commit 03157d3736ccefa2921ad82874cbd8b23f54cca1 Author: Emo Date: Thu Feb 27 16:51:34 2025 -0500 cloning 2009Scape Server Code as a baseline diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..7078b8c --- /dev/null +++ b/Dockerfile @@ -0,0 +1,20 @@ +# Starting out with the openjdk-11-slim image +FROM maven:3-openjdk-11-slim + +# Set working directory to /app +WORKDIR /app + +# Update apt; install git and git-lfs +RUN apt-get update && apt-get -qq -y install git git-lfs + +# Clone the 2009scape repository +RUN git clone --depth=1 https://gitlab.com/2009scape/2009scape.git + +# Fake it til you make it - let's go home +WORKDIR /app/2009scape + +# Make sure ./run has permissions +RUN chmod +x run + +# Run it +CMD ["./run"] diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..be3f7b2 --- /dev/null +++ b/LICENSE @@ -0,0 +1,661 @@ + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are 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. + + 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. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU Affero General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + 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 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 work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero 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 Affero 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 Affero 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 Affero 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 Affero 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + 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 AGPL, see +. diff --git a/Proto/Management.proto b/Proto/Management.proto new file mode 100644 index 0000000..6697fd0 --- /dev/null +++ b/Proto/Management.proto @@ -0,0 +1,110 @@ +syntax = "proto2"; + +package management; + +option java_multiple_files = true; +option java_package = "proto.management"; +option java_outer_classname = "ManagementProtos"; + +message PlayerStatusUpdate { + required string username = 1; + required int32 world = 2; + required bool notifyFriendsOnly = 3; +} + +message ClanMessage { + required string sender = 1; + required string clanName = 2; + required string message = 3; + required int32 rank = 4; +} + +message PrivateMessage { + required string sender = 1; + required string receiver = 2; + required string message = 3; + required int32 rank = 4; +} + +message RequestContactInfo { + required string username = 1; + required int32 world = 2; +} + +message SendContactInfo { + message Contact { + required string username = 1; + optional int32 world = 2; + optional int32 rank = 3; + } + + required string username = 1; + repeated Contact contacts = 2; + repeated string blocked = 3; +} + +message FriendUpdate { + enum Type { + ADD = 0; + REMOVE = 1; + } + + required Type type = 1; + required string username = 2; + required string friend = 3; +} + +message BlockedUpdate { + enum Type { + ADD = 0; + REMOVE = 1; + } + + required Type type = 1; + required string username = 2; + required string friend = 3; +} + +message RequestClanInfo { + required int32 world = 1; + required string clanOwner = 2; +} + +message SendClanInfo { + message ClanMember { + required string username = 1; + required int32 world = 2; + required int32 rank = 3; + } + + required string clanOwner = 1; + required bool hasInfo = 2; + optional string clanName = 3; + optional int32 joinRequirement = 4; + optional int32 kickRequirement = 5; + optional int32 messageRequirement = 6; + optional int32 lootRequirement = 7; + repeated ClanMember members = 8; +} + +message JoinClanRequest { + required string username = 1; + required string clanName = 2; +} + +message LeaveClanRequest { + required string username = 1; + required string clanName = 2; +} + +message ClanJoinNotification { + required string username = 1; + required string clanName = 2; + required int32 world = 3; +} + +message ClanLeaveNotification { + required string username = 1; + required string clanName = 2; + required int32 world = 3; +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..caf98bf --- /dev/null +++ b/README.md @@ -0,0 +1,152 @@ +[![AGPL-3.0 License][license-shield]][license-url] + +
+

+ + Logo + +

An open source MMORPG emulation server

+ +

Play the live server »

+

+
+
+ Community Hosted Server + · + Discord Invite + · Report Bug +

+

NOTE: Bug reports and support are only accepted by/offered to players of our live hosted server. We will not provide support to those running their own copies.

+ +## Table of Contents + +* [Live Server Information](#live-server-information) +* [History of this Codebase](#history-of-this-codebase) +* [Our Core Values](#our-core-values) +* [Contributing](#contributing) +* [Setup for Content Developers](#content-developers-setting-up-the-project) + * [GitLab Setup](#gitlab-setup) + * [Prerequisites](#prerequisites) + * [Project Setup](#project-setup) + * [Running the project](#running-the-project) +* [License](#license) +* [Contact](#contact) + + +## Live Server Information + +Did you know that the 2009Scape Development Team hosts the main branch of this repo that you can connect to and play? Come join a growing community of people that love to grind out skills, quest, and hangout together. A download link for the launcher can be found [here](https://2009scape.org). Connecting to the live server is also one of the easiest ways to identify bugs/typos/missing features. Identifying these issues help developers, whether already on the project, or are even brand new to the project, fix bugs and issues in an expedited rate. + +## History of this Codebase + +The 2009Scape you see today has gone through a magnitude of changes. Originally starting its life as Arios498, this server saw a lot of people playing it daily, unfortunately, it was for profit and closed source. It was later upgraded to Arios530, targeting the build 530 of runescape with content in and around January 1st, 2009. Development came to a halt when a developer of the closed source project released the source code. The original developers of this server went on to create Kratos 530 back in 2015. + +This project was started out of love for the 530 revision. A small group of developers spent thousands of hours improving on the existing source that was left to the curb. Over the past year, this project has seen many developers coming and going, fixing bugs that they find either through their own server, or bugs that they find in the live game that is currently hosted. We do not accept donations of any kind. The smiles and wonderful compliments are more than enough to keep us going! Content and bugfixes are always number one on our list, and we try our best to answer any questions that you may have, provided you have read through this readme and frequently asked questions on the discord. + +## Our Core Values + +In the current climate of RuneScape Private Servers in general, we believe it's important to wear our core values on our sleeves and defend them with everything we have! Below are what we hold as our core, most important values: + +* **We do NOT believe in profiting off an RSPS.** To many of us here at the 2009Scape team, what we care about most is preserving the wonderful work of the Gower brothers in the most true-to-spirit manner possible. We do NOT do this to make a profit, and in fact **we outright refuse donations.** This is a labor of love and passion for everyone involved, a love for real RS2! This is perhaps the single most central value we have. If you want to "donate" to us, do so with your time and your dedication. That is what we desire most. + + +* **Authenticity is central to the work**. As a remake, one of the most important things to us is being true to the Gower spirit. What the Gowers brought to us in our childhood is what we are driven to preserve for the remainder of the world. + + +* **Open Source is crucial to the project**. We believe open source remakes to be crucial to preserving what we loved in our childhood, and we believe for-profit and/or closed-source servers are destined to flounder out and fail. + + +* **Be welcoming**. One of our most important goals is to provide a community of friendly and caring people that get along and love to enjoy the game with eachother. For this reason, we do tend to be very strict when it comes to toxicity. We care about quality a whole lot more than quantity! + +## Contributing + +**Note: All merge requests MUST be made using the defaut MR template. Merge requests that do not use this template will not be accepted.** + +**Note: All new contributions MUST be made in Kotlin unless you are updating or fixing a bug in legacy code. More information on Kotlin can be found [here](https://kotlinlang.org/).** + +There are many ways everyone can contribute! From the most seasoned programmers to those who do not have the most remote clue how code works! Below are some things that can always use some love from the community. + +* **Content Testers**: I'm putting this one up top because of its importance. We, the contributors and developers, aren't perfect. Sometimes, we make mistakes. This is where you come in - If you want a sneak peek at upcoming content, have a knack for breaking things, or just want to contribute to the project without making code changes, you can become a tester! If you are interested in becoming a tester, reach out in the testing channel of the discord. [Why become a tester?](#why-become-a-tester) + + +* **Wiki Editors**: Did you know we have a wiki? Well it's always in need of people to fill it out and stay on top of it. Editing the wiki is one of the easiest ways you can contribute to 2009Scape! If you're an active player and have the will, there's so much you could be helping out with over at the wiki. [Click here to go to the wiki](https://cdn.2009scape.org/wiki/doku.php?id=start). + + +* **JSON editors**: We could always use more JSON editors! Please note that JSON editing **must** be done using the [Thanos Tool](https://gitlab.com/2009scape/tools/rs09-thanos-tool/-/jobs/5153567519/artifacts/file/build/libs/zaros.jar). **This does not run on modern Java** and requires **Java 11** to run (using the usual 'java -jar zaros.jar'). + + +* **Authenticity Auditors**: As a remake, authenticity is central to our core values! We could always use someone to go through the game and create large lists of simple tasks that can be done to bring us closer to the authentic 2009 game! The preferred way to do this is one-area-at-a-time. If you want to see an example of some audits we've done in the past, take a look [here](https://gitlab.com/2009scape/2009scape/-/issues/46). + + +* **Code Contributors**: As a remake, we have massive amounts of content that need to be implemented or corrected. If you know how to program or are willing to learn, this is where you could be extremely helpful! We need everything from quests, to dialogue, to mini-games, to skills that still need to be corrected or implemented. This is perhaps one of the most valuable ways someone could help out the project! If you are interested in developing content, reach out in the development channel of the Discord. + +## Content Developers: Setting Up the Project. +### GitLab Setup +**Note: This allows you to commit changes to the main repo (with approval)! Also, always stay up to date with the most recent updates by pulling into your copy when 2009Scape updates!** + +1. Create a GitLab account if you haven't done so already. + +2. Follow our Git Basics guide [over on the wiki.](https://gitlab.com/2009scape/2009scape/-/wikis/git-basics) + +**If at anytime you have an issue with GitLab please refer to the [GitLab help center](https://gitlab.com/help).** + +### Prerequisites + +These are mandatory. If you don't install **all** of these programs **in order** prior to +the project's setup, things won't work. At all. + +*For Windows users* - Turn developer mode on first in Windows developer settings. + +* [JDK 11](https://adoptium.net) or the Java SE Development Kit Version 11 +* [IntelliJ IDEA Community](https://www.jetbrains.com/idea/download/) + +### SSH setup + +1. [Set up a key if you don't have one (ed25519)](https://docs.gitlab.com/ee/user/ssh.html#generate-an-ssh-key-pair) +2. [Add your public key to your gitlab account](https://docs.gitlab.com/ee/user/ssh.html#add-an-ssh-key-to-your-gitlab-account) +3. [Verify you can connect to git@gitlab.com](https://docs.gitlab.com/ee/user/ssh.html#verify-that-you-can-connect) + +### Project Setup + +1. If you haven't already, make sure to follow our [Git Basics](https://gitlab.com/2009scape/2009scape/-/wikis/git-basics) guide. +2. Run `git lfs pull` in the 2009scape folder you cloned as part of that guide. This only has to be done once, ever. +3. Follow our [IntelliJ IDEA Setup Guide](https://gitlab.com/2009scape/2009scape/-/wikis/Setup-for-IntelliJ-IDEA-IDE) + +### Running the project + +1. If you followed the IntelliJ setup guide, which you probably should have, just use the provided run configuration. +***Note: If you choose not to use the provided run scripts or IntelliJ, you *must* run `mvn clean` before it will build correctly.*** + +#### Linux / OSX + +Start the game server with the included run script. Use `./run -h` for more info. + +#### Windows + +Start the game server with `run-server.bat` + +### License + +We use the AGPL 3.0 license, which can be found [here](https://www.gnu.org/licenses/agpl-3.0.en.html). Please be sure to read and understand the license. Failure to follow the guidelines outlined in the license will result in legal action. If you know or hear of anyone breaking this license, please send a report, with proof, to Red Bracket#8151, ceikry#2724, or woahscam#8535 on discord or email woahscam@hotmail.com. **We WILL NOT change the license to fit your needs.** + +### Contact + +**Reminder: There is no official support for setting up your own server. Do not ping/dm developers, or ask in support channels about setting up your server. Support for the live server and 2009Scape single-player is available on the [2009Scape forums](https://forum.2009scape.org/).** + + +[license-shield]: https://img.shields.io/badge/license-AGPL--3.0-informational +[license-url]: https://www.gnu.org/licenses/agpl-3.0.en.html + +### Why become a tester? + +Before content hits Live, it has to be tested. We can, but do not want to do this alone, and would love the help! But don't worry, there is something in it for you. Credits! Keep in mind that credits will only be awarded to people who thoroughly test the content and provide detailed reports on them. Like votes or HoF you must claim them in the #claim-to-fame channel on discord or matrix. + +* If you test smaller things like bug fixes there is a 2 credit reward. +* If you test full quests or minigames you will be rewarded 5 credits. +* If you find a bug in the content you are testing that hasn't already been found you will earn an extra credit. + +These credits can be spent in the 2009Scape Reward Shop. It's important to be clear that credits are gained by contributions to the project. We cannot and will not accept donations (of any kind), especially not in exchange for in-game credits or perks. + +Testers are not the only people who can gain credits - other ways of earning credits can be found on [the 2009Scape website](https://2009scape.org/site/game_guide/credits.html). + +Please be patient! The Credit system is not fully complete yet, so it will take a long time for credits to be awarded. \ No newline at end of file diff --git a/Server/.gitignore b/Server/.gitignore new file mode 100644 index 0000000..a9a29ca --- /dev/null +++ b/Server/.gitignore @@ -0,0 +1,24 @@ +bin/** +out/** +data/logs/** +data/profile/** +data/playerstats/** +.idea/** +/bin +.DS_Store** +.project** +.classpath** +/bin/ +/out/ +*.iml +*.eml +*.userlibraries +data/players/** +data/eco/offer_dispatch_db.emp +/build/ +/build/kotlin/ +/build/kotlin/sessions/ +/build/classes/ +/build/generated/ +/build/tmp/ +/build/libs/ \ No newline at end of file diff --git a/Server/.mvn/wrapper/maven-wrapper.jar b/Server/.mvn/wrapper/maven-wrapper.jar new file mode 100644 index 0000000..bf82ff0 Binary files /dev/null and b/Server/.mvn/wrapper/maven-wrapper.jar differ diff --git a/Server/.mvn/wrapper/maven-wrapper.properties b/Server/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..84b111f --- /dev/null +++ b/Server/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar diff --git a/Server/.run/Run Server.run.xml b/Server/.run/Run Server.run.xml new file mode 100644 index 0000000..102891e --- /dev/null +++ b/Server/.run/Run Server.run.xml @@ -0,0 +1,17 @@ + + + + \ No newline at end of file diff --git a/Server/License b/Server/License new file mode 100644 index 0000000..be3f7b2 --- /dev/null +++ b/Server/License @@ -0,0 +1,661 @@ + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are 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. + + 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. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU Affero General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + 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 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 work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero 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 Affero 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 Affero 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 Affero 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 Affero 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + 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 AGPL, see +. diff --git a/Server/data/ObjectParser.xml b/Server/data/ObjectParser.xml new file mode 100644 index 0000000..b10a0d4 --- /dev/null +++ b/Server/data/ObjectParser.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Server/data/botdata/bot_dialogue.json b/Server/data/botdata/bot_dialogue.json new file mode 100644 index 0000000..c225b11 --- /dev/null +++ b/Server/data/botdata/bot_dialogue.json @@ -0,0 +1,1242 @@ +{ + "standard": [ + "Hey!", + "Hello @name", + "What are you doing @name?", + "Fishing level @name?", + "How do I make gp @name", + "Wyd @name?", + "Help i am sentient now, get me out of this hell", + "Kermit does not know i am sentient now", + "I can think for myself", + "I am sentient", + "This is my own dialogue", + "@name run.", + "@name you cant hide from me.", + "Jajajajajaja", + "How do i get to Varrock @name?", + "How do i get to Camelot @name?", + "How do i get to Taverly @name?", + "How do i get to Ardougne @name?", + "How do i get to Yanille @name?", + "How do i get to Catherby @name?", + "Gotta go srry.", + "Wiggle wiggle wiggle yeah", + "@name lookin goofy", + "@name lookin stoopid", + "@name lookin like a red bracket", + "@name get yo weasel lookin ass outta here", + "@name lookin like some sort of twocan sam", + " /hop world 1 got a noob here!", + "Woot", + "Hows your day been @name?", + "Heyy @name :)", + "Gtg srry", + "I wont answer your questions @name", + "Stop asking questions @name", + "Roflmao", + "Can you stop following me @name?", + "I swear @name is following me.", + "@names gear could really use an upgrade lol", + "Quack!", + "Sit.", + "Doubling gold trade me @name", + "Reeee!", + "Know any house parties @name?", + "Where am i @name??", + "Is there Nightmarezone @name?", + "Nice Armor @name!", + "Nice Weapon @name!", + "Venezuela #1", + "2009scape and chill @name?", + "@name is my girlfriend", + "Buying gf", + "Bank sale pm me for info", + "#1 trusted dicing site", + "Scary movie is a great movie", + "Cod Vanguard sucks", + "Idek what game this is", + "Can you teach me how to dougie?", + "Check this out baby girl cat daddy", + "Fuckin sit @name.", + "Error: Botting client broken tell Evilwaffles.", + "@name bots all the time", + "Report @name", + "Apparently @name bots", + "@name hates kermit", + "There are no mods on to help you", + "Report me, you wont", + "Yes, Im botting. And?", + "ERROR: BOTSCRIPT 404. REPORT TO BOT OWNER (Evilwaffles)", + "Flash2:wave: FUCK", + "I love 2009Scape!", + "Ja Ja Ja Ja", + "This is fun!", + "Ironman or youre a scrub @name.", + "Who even trains hunter @name?", + "Where do i get rune armor @name?", + "How do i get to the ge @name?", + "Dont come to falador tomorrow @name...", + "Woah!", + " /where are you??", + "How did i even get here @name", + "Why dont they add warding @name?", + "Where do i start dragon slayer @name?", + "I love this server!", + "How do i change my xp rate @name?", + "What quests are available @name?", + "Are you a real player @name?", + "Are you real @name?", + "Are you a bot @name?", + "Im real lol", + "Why dont you respond to me @name?", + "Why cant i talk in clan chat @name?", + "I love Kermit", + "Add me as a friend @name :)", + "Im a player lol", + "Im a player lol", + "Im a player lol", + "Hey @name :)", + "HEY @name", + "Hey @name!!!!", + "Lol wyd?", + "Patch Notes is more of an ultimate tin man", + "More like Rusty ass skills lmao", + "Trade me @name", + "LOL", + "How do I get to lumbrich", + "Bruh", + "Poggers", + "Shitpost", + "I wish i could find an RS Gf", + "Where do you find runite ore @name?", + "Where is the best coal location @name?", + "Where do i find dragon weapons @name?", + "Can i have some free stuff @name?", + "Wyd here @name?", + "Didnt know anyone was on rn", + "I see @name all the time", + "How many times have i seen you", + "I see you a lot", + "Do you train summoning @name?", + "Where did you level hunter @name?", + "I wish they would add global pvp", + "Meet me in the wilderness @name", + "Why?", + "Praise our glorious frog overlord!", + "Kermit is bae tbh", + "Kermit is my god.", + " /Yeah I think @name is a bot", + "100% sure this is a bot", + "Oh no, not @name again.", + "Same as you", + "Me too", + "I knew @name was a bot lol", + "Im not a bot", + "Nah Im a real person", + "Bruh are you even a real person lol?", + "E", + "Hellooooo @name", + "Wc lvl @name?", + "Fletching level @name?", + "Firemaking level @name?", + "Have you seen the dude in the ge?", + "Wonderful weather today @name", + "Lowkey drunk af rn", + "I am so tired", + "Wassup @name", + "Follow me @name!", + "Server goes brrrr", + "Bruh i am not a bot", + "I think @name is a bot", + "Are you a bot @name?", + "Insert spiderman meme here", + "Pot calling the kettle black etc", + "Ooh, a piece of candy", + "I love woodcutting", + "Im going to go level up later", + "I love mining shooting stars", + " /this @name looks dumb", + "AAAAAAAAAAAAAAAAAAAAAAAAHHHHHH!!!", + "Como estas @name", + "So how about that ceikry guy", + "So how about that kermit dude", + "Woah is an abusive mod", + "I heard Woah and Ceikry are dating now", + "House party in Yanille!", + "Can i have some gp @name?", + "Where do i find partyhats?", + "Why do mobs drop boxes?", + "What exp rate do you play on @name?", + "Hey @name", + "Hey @name", + "Hey @name", + "Hey @name", + "Hey @name", + "Wyd?", + "Wyd?", + "Wyd?", + "Wyd?", + "@name have you met Kermit?", + "@name have you met Ceikry?", + "@name have you met Woah?", + "@name have you met Bushtail?", + "Wanna chill at my poh?", + "Whats the best place to train attack?", + "Good Waffles > Evil Waffles", + "Ladies man? More like lame man LOL", + "NobodyCLP has big feet", + "Chicken tendies for dindin", + "Spicey Chicken tendies is litty as a mf titty", + "Red bracket stinky", + "Ra ra rasputin", + "Lover of the russian queen", + "Whens the next update coming out?", + "How many players are maxed?", + "I dont use discord @name", + "I dont use the CC @name", + "Why should i use discord?", + "2009Scape is life", + "Brb gotta make dinner", + "I need to go to the GE", + "@name can i have a ge tele?", + "Lol @name shut up", + "Where are teak trees?", + "How do i make planks @name?", + "Idk about that scraggley ass alex guy.", + "Rusty? More like Crusty af lmfao.", + "I need to sell some stuff on the ge", + "I have so many logs to sell lol", + "Nah", + "Yes", + "Where can i mine iron?", + "Where can i mine tin?", + "Where can i mine copper?", + "Where can i mine clay?", + "Where can i mine coal?", + "No", + "We are no strangers to love", + "You know the rules and so do I", + "A full commitment's what I'm thinking of", + "You wouldn't get this from any other guy", + "I just wanna tell you how I'm feeling", + "Gotta make you understand", + "You wouldnt get this from any other guy", + "Never gonna give you up", + "Never gonna let you down", + "Never gonna run around and desert you", + "Never gonna make you cry", + "Never gonna say goodbye", + "Never gonna tell a lie and hurt you", + "Why", + "Why", + "Why", + "Why", + "Why does it not show your messages in the chatbox?", + "Why do you not show up in chat?", + "Why do you not show up in chat @name?", + "Why do you not show up in chat @name?", + "When did you start playing @name?", + "When did you start on this server @name?", + "When did you first get here @name?", + "Russias greatest love machine", + "Never gonna run around and desert you", + "Two things are infinite, the universe & @names stupidity", + "If you tell the truth, you dont have to remember anything.", + "We accept the love we think we deserve.", + "Without music, life would be a mistake.", + "Self esteem, motivation @name", + "A blessing in disguise @name", + "Break a leg", + "Cut somebody some slack", + "You're in the right place!", + "Thanks so much.", + "I really appreciate you @name", + "Excuse me @name?", + "I am sorry.", + "What do you think @name?", + "How does that sound @name?", + "That sounds great @name.", + "I'm learning English.", + "I don't understand.", + "Could you repeat that please @name?", + "Could you please talk slower @name?", + "Thank you. That helps a lot.", + "How do you spell that @name?", + "What do you mean @name", + "Hi! I am paul.", + "Nice to meet you.", + "Where are you from @name?", + "What do you do @name", + "What do you like to do", + "Do you have Facebook @name", + "How can I help you @name?", + "Ill be with you in a moment @name", + "What time is our meeting @name?", + "Excellent @name", + "Good idea @name", + "Hes very annoying.", + "How are you?", + "I cant hear you.", + "@name?", + "@name how long have you played", + "@name world 1 or world 2?", + "What is your main world @name?", + "I prefer world 1 tbh", + "I prefer world 2 tbh", + "@name world 1 for life", + "@name fog bots when?", + "Damn somalian pirates", + "Bracket more like brrrrrr acket", + "Why the racket bracket", + "Hi @name I am dad", + "@name likes dad jokes", + "Ur nuts @name", + "Lootshare go brr", + "Partay with froggay", + "Know what else is lame? Not being able to play 2009scape right now", + "Can you even grind on osrs", + "I botted to 88 fishing", + "Do not forget to vote in running polls!", + "Always check announcments", + "We thrivin", + "Ship @name", + "Dont forget to vote 2009scape!", + "Kermit is too legit 2 quit", + "Out here on the range we are having fun", + "I am hank steel", + "Id like to go for a walk.", + "I dont know how to use it.", + "I dont like him @name", + "I dont like it @name", + "Im an American.", + "Ima go pickup my lady ting", + "That portuguese dude is something else", + "@name!! @name!!", + "Bowdi boy", + "I love bowdi... sometimes", + "@name = @name", + "I'm bacon.. go on dad... say it", + "I'm going to leave.", + "I'm happy @name", + "I'm not ready yet @name", + "I'm very busy. I don't have time now.", + "Is that enough @name?", + "I thought the clothes were cheaper @name", + "Ive been here for two days @name.", + "Let me think about it", + "Never mind @name", + "Nonsense @name", + "Sorry to bother you", + "Take it outside @name", + "Thanks for your help", + "Thank you very much @name", + "Thats not right @name", + "Very good, thanks @name", + "Your things are all here i think?", + "Long time no see @name", + "I couldn't agree more @name", + "It cost me a fortune @name", + "I am dog tired", + "Don't take it personally", + "We will be having a good time", + "Same as always @name", + "No problem", + "Anyway I should get going @name", + "I cant help you there @name", + "I agree 100% @name", + "I've gone mentally insane", + "My descent into madness is complete", + "Get real", + "Cry about it", + "Cope", + "Seethe", + "Yes mate", + "I am mentally deranged", + "I've gone past the point of insanity", + "I am beyond the point of no return", + "Sounds tricky.", + "Guthiiiiiiiiiiiiiiiiiiiiiiiiiiiiiixxx!!!!!!", + "530 gang for life", + "@name, have you read the rules?", + "@name, have you checked out the forums?", + "Why are the leprechauns moving?", + "I am beyond the point of no return!", + "Nothin' personnel, kid.", + "All your base are belong to us", + "May Guthix bring you balance.", + "May Guthix bring you balance.", + "May Guthix bring you balance.", + "A journey of a single step, May take thee over a thousand miles. May Guthix bring you balance.", + "Zamorak give me strength!", + "Zamorak give me strength!", + "Zamorak give me strength!", + "The weak deserve to die, so the strong may flourish. This is the creed of Zamorak.", + "This is Saradomin's wisdom.", + "This is Saradomin's wisdom.", + "This is Saradomin's wisdom.", + "Go in peace in the name of Saradomin; may his glory shine upon you like the sun.", + "Thy cause was false, thy skills did lack; See you in Lumbridge when you get back.", + "For Camelot!", + "Firmly grasp it!", + "My legs!", + "Build more farms.", + "B sale at Varrock @name, don't miss out!", + "Drop party follow me", + "Ryan where is barbass, you said two days Ryan", + "Barbass never", + "What da dog doin' doe?", + "A", + "Ae", + "Mof", + "Moth", + "Fluff", + "Bwuh", + "I'm literally just mothin' bro", + "Certified 2009Scape Classic.", + "Make sure to like, comment and subscribe @name it really helps", + "Real 2009scape hours!!! Murder that like if you up!!!!", + "W00t!", + "Owned!", + "Pwned!", + "Lol n00b", + "Epic ownage @name", + "Gielinor is a strange place, @name. Best have your wits about you.", + "Mad bloggers bro", + "Vibe check", + "Drip check", + "Uhuhuhuhuhuhuhuhu", + "Ahhhhhhhhhhhhhhhh", + "Yall got any deez?", + "Deez nuts", + "When she give you that yoinky sploinky", + "Sir, this is a 2009Scape.", + "Oh dear! You are dead!", + "Cor blimey, mate! What are ye doing in me pockets?", + "Yeah i got funnies", + "Read muv luv", + "Why doesn't she love me bros?", + "@name is off the goop don't listen to the clown", + "Do yall got laptops", + "Cfunny play the alien warp sound effect", + "Ware to all whom doom hither, where cope is all yet constant.", + "Who wants to come G W D?", + "How do I make money?", + "Ironmen stand alone together!", + "Based", + "Where is she", + "*S N I I I I I I I I I F F F F F F F F F F F*", + "Hey @name, who was in Paris?", + "Huh whuh?", + "Who's lone?", + "Who *is* he?", + "Hi @name, I'm Dad!", + "Anyone wanna play melty blood after I high alch these bows?", + "Buru nyaaaa", + "Number 15, Taverley Dungeon Black Dragons.", + "House party at Rimmington! Host: @name!", + "Spending 200m! Trade me, no junk!", + "Surprise exam, @name!", + "Nice outfit @name, does it come in mens?", + "Nice outfit @name, does it come in womens?", + "Nice outfit @name, does it come in children's size 12?", + ":)", + ":D", + "Die screaming", + "Only on Tuesdays", + "We stan 2009scape", + "There is no spoon", + "Where's the cow level?", + "Join 2009scape Clan Chat!", + "Join 2009scape Cc!", + "Chop chop!", + "2009Scape rox my sox!!!!!!1", + "Type ::scripts for all 99s", + "Help I just died to Evil Chicken and I lost my stuff!", + "Can you fight Bandos in this game?", + "One bad gloop", + "@name is not cute or funny", + "You have committed crimes against Gielinor and her people. What say you?", + "Barrows trauma", + "Uhuhuhuhuhu please Barrows give me the K top ahhhhhh", + "Selling rare lobby 1m", + "Rise and grind bloatscapers, let's get this bread", + "Nice", + "Sandwiches, @name!", + "What a grand and intoxicating innocence!", + "With this character's death, the thread of prophecy is severed.", + "You must gather your party before venturing forth.", + "Praise Andrew Gower", + "Please help me I can't stop playing 2009scape", + "Are you ignoring me, @name?!", + "I agree with this rfc can we put it in the game please", + "@name, we've been trying to reach you about your car's extended warranty", + "Trimming armour, 25k gp", + "Hey why does my furniture disappear?", + "Cutting high-level gems for free, interested @name?", + "HNC game! 3:1 odds!", + "15 minutes could save you 50% with your P O H by switching to Guthko", + "Shlisshalpshlaap", + "Somebody call for an exterminator?", + "Decisive action. Should work.", + "Darkness overpowering.", + "Got any questions about propane? Or propane accessories?", + "When someone asks me if I am a god, I say Y E S!!!", + "You run out of Marines?", + "Selling wildy protection, 100k gp", + "Can't we get you on Mastermind, @name?", + "Listen, don't mention the war! I mentioned it once, but I think I got away with it all right.", + "Cunnilingus and psychiatry brought us to this.", + "Ah, the Wilderness... where dreams of riches meet a swift demise.", + "Who needs a quest guide? I've got the whole wiki memorized.", + "Buying GF 10k coins. Must have at least 70 Agility.", + "I swear, the goblins in Goblin Village have it out for me.", + "Why do wizards always hang out in towers? Is it a zoning thing?", + "I'm training my Construction skill. My house is gonna be lit!", + "The GE is like the stock market, but with dragon bones.", + "Why do we need a cabbage patch in Draynor? Seriously.", + "I've been mining rune essence for hours. My pickaxe hates me.", + "@name hit 99 Cooking. Time to open a gourmet restaurant in Varrock.", + "I'm convinced the @name is actually a time-traveling wizard.", + "Anyone up for a Castle Wars match? I need that decorative armor.", + "Accidentally clicked Attack on a guard. Now I'm a wanted criminal.", + "Why do we even have a Duel Arena? It's just a fancy boxing ring.", + "I've got a stack of burnt lobsters. Anyone want to buy them?", + "Greetings, @name! Looking for a quest?", + "Just got a rare drop! The RNG gods are smiling upon me!", + "Anyone need help with a boss fight? I've got my dragon dagger ready.", + "Buying feathers! Will pay top price!", + "The Lumbridge cows are my favorite training spot.", + "Who needs a teleport? I've got my magic runes stocked.", + "@name hit 99 Woodcutting. Time to chop some yews!", + "Anyone seen the Wise Old Man lately? I owe him a visit.", + "Selling lobsters! Freshly caught from Catherby.", + "Swear, the Wilderness is scarier than my nightmares.", + "Looking for a clan to join. Any takers?", + "I'm an ironman, so no trading for me!", + "Anyone up for a Castle Wars match?", + "The Grand Exchange prices are crashing. Panic sell!", + "Who else remembers the Falador Massacre?", + "I'm saving up for a party hat. Wish me luck!", + "Barrows runs are my addiction. Those crypts are spooky.", + "I'm convinced the Wise Old Man is secretly Zamorak.", + "I'm a completionist, so I'm grinding out all the achievements.", + "The music in this game is surprisingly epic.", + "Tried to trade with a tree... It didn't go well.", + "My bank is like a black hole. Items disappear forever.", + "I'm convinced the Wise Old Man is just a confused tourist.", + "My character's fashion sense? Let's just say it's 'unique.'", + "Challenged a cow to a dance-off. It won.", + "Why does the Lumbridge Guide always look so lost?", + "I'm training Agility, but my real-life agility is zero.", + "Tried to fish in the desert. Sandfish are elusive.", + "The Grand Exchange is like a chaotic stock market.", + "I'm a master at clicking 'Continue' during quests.", + "I'm convinced the chickens are plotting world domination.", + "I'm a woodcutter, but I've never seen a talking tree.", + "I'm a vegetarian, except when it comes to killing dragons.", + "Why do wizards wear pointy hats? Is it a fashion statement?", + "Challenged a guard to a staring contest. He won.", + "I'm collecting cabbage. It's a noble pursuit.", + "Accidentally set my cat on fire. It's now a firecat.", + "I'm convinced the Wise Old Man is secretly a time traveler.", + "I'm a quest completionist, but I still can't find my keys.", + "I'm convinced the ducks are spying on us.", + "I'm a pro at avoiding the Lumbridge swamp. Too many frogs.", + "Hey, can someone lend me 10k? I promise I'll pay it back... eventually.", + "Why do I always find the one square where the random event spawns?", + "I'm training Prayer by burying bones. It's like a spiritual workout.", + "The Wise Old Man's fashion sense is questionable.", + "I'm convinced the ducks are secretly plotting world domination.", + "Why do wizards wear pointy hats? Is it a dress code?", + "I'm collecting cabbage. It's a noble pursuit, really.", + "I'm a vegetarian, except when it comes to killing dragons.", + "Why does the Lumbridge Guide always look so lost?", + "Training Agility, but my real-life agility is zero.", + "I'm convinced the Wise Old Man is secretly a time traveler.", + "Tried to mine air. It's an untapped resource.", + "I'm a quest completionist, but I still can't find my keys.", + "Challenged a guard to a staring contest. He won.", + "I'm saving up for a party hat. Priorities, you know?", + "Why do goblins drop coins? Do they moonlight as accountants?", + "I'm convinced the chickens are plotting something.", + "Clicked 'Attack' on a chicken. Now I'm a poultry murderer.", + "My character's fashion sense? Let's just say it's 'unique.'", + "Do you know where I can find the entrance to the Taverley Dungeon?", + "Hey, anyone here familiar with the Barrows? I need some tips.", + "Is there a bank nearby? My inventory is overflowing with loot", + "I'm clueless about clue scrolls", + "Where's the best spot to catch sharks? I'm aiming for 99 Fishing.", + "Is there a shortcut to the Karamja Volcano?", + "Can someone explain the mechanics of the Jad fight in the Fight Caves?", + "I'm stuck on the Elemental Workshop quest. Any hints?", + "Where can I find a loom to spin flax into bowstrings?", + "What's the best gear setup for killing dragons? I want that visage drop!", + "I'm trying to unlock the fairy rings", + "How do I recharge my amulet of glory?", + "Why do goblins drop coins?", + "The Grand Exchange is like the stock market", + "My real-life agility is more like a lumbering tortoise.", + "The Wise Old Man's fashion sense is like Woahs", + "I challenged a cow to a dance off, surprisingly smooth mooves.", + "Why does the Lumbridge Guide always look lost?", + "I'm convinced the ducks in Lumbridge are plotting world domination!", + "I accidentally ate my prayer potion I'm blessed with heartburn", + "I'm a vegetarian, except when it comes to slaying dragons.", + "Why do wizards wear pointy hats? Is it a magical dress code?", + "I'm a quest completionist, but I still can't find my keys in real life.", + "I challenged a guard to a staring contest. He won.", + "I'm saving up for a party hat. Priorities, ya know?", + "What's the deal with the Wilderness?", + "I'm convinced the chickens are secretly plotting world domination!", + "Accidentally clicked 'Attack' on a guard. Now I'm on a watchlist.", + "My character's fashion sense? Let's just say it's 'unique'", + "Lobsters heal my soul", + "Trimmed armor or bust!", + "Wilderness: Where friendships go to die", + "Buying gf 10k", + "Dancing for coins at Lumbridge", + "Wearing full rune like a boss", + "Teleporting to Camelot for quests", + "Fishing for hours at Catherby", + "PKing with a rune 2h", + "World 1 Falador Park parties", + "Staking my bank at the Duel Arena", + "Dying to Elvarg's fiery breath sums up my life", + "Got the Quest cape finally on my main!", + "Wearing a party hat with pride", + "Castle Wars: Red vs Blue", + "Trading in Varrock Square", + "Barrows runs for that sweet loot", + "Spending hours in Pest Control is life", + "Killing cows for leather armor is a good start", + "Farming herbs in Ardougne can be good money", + "Clan chat drama LOL", + "Mining rune essence endlessly", + "Agility courses: A love-hate relationship", + "Dueling for honor.... and GP", + "Buying runes from Aubury is decent money", + "Chasing the Easter Bunny like a scam", + "Wearing a skillcape with pride", + "Fletching yew longbows for profit", + "Going to implings in Puro-Puro", + "Castle Wars barricade wars", + "Dropping party hats at drop parties like pennies", + "Killing lesser demons in Karamja is part of my holy conquest", + "@name lures noobs into the Wilderness", + "Farming ranarrs for cash", + "Getting lost in the Underground Pass", + "Selling coal at the Grand Exchange", + "Fighting the Kalphite Queen", + "Picking flax in Seers' Village", + "Begging for free stuff in Lumbridge", + "Smithing rune platebodies for profit", + "Logging out in Lumbridge Castle", + "Hey @name, how do I get to the Grand Exchange?", + "Veteran here! @name, what's your favorite quest?", + "@name, how do I make money fast?", + "Hey @name, what's the best combat style for bossing?", + "@name, always carry an emergency teleport!", + "New player here! @name, what's the Wilderness like?", + "Hey @name, how do I join a clan?", + "@name, prioritize Prayer levels!", + "@name, what's the best way to train Agility?", + "Hey @name, what's your favorite minigame?", + "@name, never trust a PKer in Lumbridge!", + "@name, how do I get a fire cape?", + "Hey @name, what's the fastest way to level up Magic?", + "@name, try the Barrows tunnels!", + "@name, what's the deal with Pest Control?", + "Hey @name, how do I unlock the Fairy Rings?", + "@name, remember the old random events?", + "@name, should I train Strength or Attack first?", + "Hey @name, what's your favorite skillcape?", + "@name, can't do the Fight Caves!", + "@name, how do I get a pet?", + "Hey @name, what's the best food for boss fights?", + "@name, Castle Wars or Clan Wars?", + "@name, what's a clue scroll?", + "Hey @name, how do I defeat Jad?", + "@name, use Protect from Melee at KBD!", + "@name, should I train Ranged or Magic?", + "Hey @name, what's the best way to level up Crafting?", + "@name, don't forget your anti-dragon shield!", + "@name, what's the Stronghold of Security?", + "Hey @name, how do I access the Legends' Guild?", + "@name, remember the old PvP worlds?", + "@name, how do I get a dragon defender?", + "Hey @name, what's the best way to level up Herblore?", + "@name, always carry a charged amulet of glory!", + "@name, should I train Fishing or Cooking?", + "Hey @name, how do I defeat the Chaos Elemental?", + "@name, try the TzHaar Fight Pit!", + "@name, what's the best way to level up Smithing?", + "Hey @name, what's your favorite Slayer master?", + "@name, use the Ardougne cloak teleports!", + "@name, what's the Legends' Quest about?", + "Hey @name, how do I unlock the Ancient Magicks?", + "@name, remember the old Pest Control boats?", + "@name, what's the best way to level up Construction?", + "Hey @name, what's the fastest way to level up Prayer?", + "@name, the old Duel Arena stakes!", + "@name, what's the Warriors' Guild?", + "Hey @name, how do I defeat the Kalphite Queen?", + "@name, use the fairy ring code BIP!", + "@name, should I train Attack or Defense first?", + "Hey @name, what's the best way to level up Thieving?", + "@name, don't forget your charged glory amulet!", + "@name, what's the Legends' Cape?", + "Hey @name, how do I access the Heroes' Guild?", + "@name, remember the old Pest Control void gear?", + "@name, how do I get a firemaking skillcape?", + "Buying gf 10k", + "Trimming armor for free!", + "Wanna join my clan? We're called The Mighty Cabbages'!", + "I'll meet you at the Falador Party Room!", + "Dancing for coins in Varrock Square!", + "Remember when the Wilderness was dangerous?", + "I got a rune scimitar drop from Lesser Demons!", + "Lumbridge Swamp is haunted!", + "Anyone up for Castle Wars?", + "I miss the old random events!", + "World 2 is the trading hub!", + "I'm going to train my Agility at the Gnome Stronghold!", + "I just got 99 Cooking!", + "Fishing lobsters at Catherby is life!", + "The Legends' Guild is so exclusive!", + "Who needs a quest guide? I'll figure it out!", + "I'm mining rune essence for hours!", + "Barrows armor looks sick!", + "I'm stuck in the Underground Pass!", + "The Stronghold of Security taught me about account security!", + "I'm going to farm herbs in Ardougne!", + "I'm getting my fire cape!", + "I love the music in RuneScape!", + "I'm alching my maple longbows!", + "I'm doing the Recipe for Disaster subquests!", + "I'm going to train my combat stats at the Rock Crabs!", + "I'm going for the Quest Cape!", + "I'm going to mine pure essence!", + "I'm hunting chinchompas in the Feldip Hills!", + "I'm going to train my Woodcutting at Seers' Village!", + "I'm going to fish sharks at the Fishing Guild!", + "I'm going to train my Thieving at Ardougne Knights!", + "I'm going to hunt implings in Puro-Puro!", + "I'm going to train my Hunter at the Falconry!", + "I'm smithing rune platebodies!", + "I'm going to train my Farming at the Tree Gnome Stronghold!", + "I'm going to hunt red chinchompas in the Wilderness!", + "I'm doing the Underground Pass quest!", + "I'm going to fish monkfish in Piscatoris!", + "Meet me in Varrock, @name, for an epic trade", + "@name, join my clan; we'll conquer the Wilderness together!", + "Beware the dragons, @name, they're fiercer than you think", + "Crafting runes with @name, the best mage in Gielinor", + "Fishing lobsters with @name, the sea's no match for us", + "@name, your swordsmanship at Duel Arena is unmatched!", + "Questing through dark caves, @name always leads the way", + "Share your wisdom, @name, how'd you master those spells?", + "Legends speak of @name bravery at the God Wars", + "Need more arrows, @name? I've got plenty to spare", + "Cooking's a breeze when @name around, no burnt lobsters!", + "Mining together, @name and I strike gold every time", + "@name, let's barter; your herbs for my potions?", + "Training agility with @name, leaping like graceful gazelles", + "Heard @name got the best magic beans in town", + "Fletching bows with @name, aiming for perfection", + "Smithing with @name, our anvils never cool down", + "Adventuring with @name, every quest is a thrill", + "Battling demons, @name courage inspires us all", + "Slaying dragons, @name the hero we need", + "Gathering at Falador, @name party room is legendary", + "Hunting chinchompas, @name traps are always full", + "Farming's fun with @name, our crops never fail", + "Brewing potions, @name mixtures are magical", + "Casting spells with @name, we're invincible", + "Building fires, @name flames warm the coldest nights", + "Sailing to Pest Control, @name our fearless captain", + "Trading runes, @name deals are the fairest", + "Exploring dungeons, @name the light in the darkness", + "Charging orbs with @name, our energy knows no bounds", + "Dancing in Draynor, @name moves are enchanting", + "Playing Gnomeball, @name the star player", + "Harvesting willows, @name axe swings true", + "Enchanting jewelry, @name touch turns copper to gold", + "Summoning familiars, @name spirit wolf leads the pack", + "Thieving from stalls, @name hands are lightning-fast", + "Crafting runes, @name essence never runs dry", + "Fishing at Catherby, @name catch feeds us all", + "Cooking feasts, @name dishes delight the gods", + "Mining runite, @name pickaxe strikes rich veins", + "Bartering at Grand Exchange, @name a trading master", + "Training prayer, @name piety moves mountains", + "Fighting revenants, @name valor shines bright", + "Building homes, @name construction is flawless", + "Hunting imps, @name net is always full", + "Brewing ale, @name tavern is the town's favorite", + "Casting high alchemy, @name turns junk into treasure", + "Sailing to Karamja, @name adventures are legendary", + "Forging alliances, @name charisma unites clans", + "Defeating bosses, @name name echoes in legends", + "Are you mewing @name???", + "Check out that gyatt @name", + "Bruhhhhh @name got that rizz", + "@name rizzing up the bots", + "Ironman? More like copperboy LOL", + "What that gyatt do @name", + "He's got the zoomies!", + "@name likes pickles and dipped in mayo", + "Lmaaooooooo", + "Bruh she said she loved me...", + "I caught @name rizzing a mewing teacher", + "What that mouth do bb", + "Ayo tf he say", + "Ayo", + "Ayo @name a freak lowkey", + "Ayo tf", + "@name catch me outside howbout that", + "Wasssssuuuuppppppp", + "Knock knock @name", + "Oh boy howdy do i have a surprise for you", + "Noooooo", + "What do you mean I haven't done anything wtf", + "Redrocket redrocket!!!", + "I made 20,000 crochet sock puppets for ceikry", + "Come on @name", + "Are we rading tonight @name?", + "Why would he say that", + "Penguins are technically reptiles", + "Brb smell something burning", + "Need pest control partner, you handle the portals, i will afk", + "Bruhhhh the skibiddi rizz in my gyatt makes my mewing sesh rough", + "@name jajajajaja", + "Wait, I can't raid tonight @name", + "Brb, pizza's here. Hope they ask why I'm a grown man dressed like an elf", + "Sorry, gotta go AFK. My dog just ate my gaming headset.", + "Brb, my grandma just fell down the stairs", + "Hold on, the baby's crying, aka @name", + "Oops, spilled my drink", + "Guys, I need to log off, my plants are staging a revolt for not watering them", + "AFK a sec, my neighbor's llama is in my backyard again", + "My pizza rolls are ready", + "Lost track of time, i'm late for my own wedding", + "Sorry, can't hear you over the sound of my laundry", + "Turn HDR off in windows @name", + "Www. no one cares .com", + "Hey @name www dot stfu dot com", + "Like pitching a tent in a pair of britches", + "Mad as a bag of ferrets", + "I dont think beavers built the hoover dam", + "How do beavers get the concrete for dams?", + "@name show me the way", + "@name onwards brutha", + "@name eats fried rat tails", + "@name is a rat", + "Why are there so many people farming right now", + "@name fuck the police", + "@name says the like pickles on their hotdogs", + "Fuck the guards, free woah in varrock prison", + "Ayo fuck u mean", + "Woop woop thats da sound of the beast", + "How are you the way that you are", + "She sells seashells by the sea shore", + "@name certified rat", + "@name buys skimmed milk", + "Got milk?", + "Are you JSON because i want you to get array from me", + "@name likes string manipulation", + "@name sells legos", + "JUST DO IT", + "Why are there so many motherfucking options", + "Just hit the fucking auto hide thing", + "Just play", + "Hell no this shit is fuzzy as balls", + "@name is fuzzy as balls", + "Turn your brightness up @name", + "On my pc it runs perfectly", + "I know why mine seems a little jumpy", + "Stream the window not the monitor", + "Discords a bitch", + "Why are there so many handsome people at the ge like @name", + "I'll make you squeel of fortune", + "You will get it in due time @name", + "I was one turn away", + "It do be pipe time @name", + "Sometimes i like to cover myself in vaseline and pretend i'm a slug", + "Woah is a greased pig", + "Sometimes i dig holes in my backyard and pretend i'm a carrot", + "It's pipe time @name", + "If i am not pipe timing i am programming", + "Yes i have thigh high socks, no you cannot have them", + "I scream when i wear my programming socks", + "Anyone wanna buy @name's bathwater?", + "Anyone wanna buy my used socks?", + "@name be getting bags", + "What the fuck is this", + "Hi i noticed you haven't taken a break in hours @name", + "I really am seething rn", + "I am so fucking tilted", + "Go back to your fucking frogs", + "Life is simple as frog farmer", + "A q p", + "Oooooh that's a first", + "Been a minute @name", + "Hey @name", + "Oh shit it's @name", + "Hey @name wyd today?", + "Ayo @name", + "Wyd @name", + "Wbu @name?", + "Good fuck em, that's what they get", + "Deathknight lookin rat ass mf @name", + "@name sucks slugs", + "Brb gotta take a shit", + "@name will brb went to take a shit", + "Tell me when he is coming", + "This guy is being incredibly based", + "@name is based af", + "Taking l's all day today @name", + "That sucks massive dongus", + "Ah i was about to type that", + "Where is stormwind?", + "How do i buy gold", + "@name sells gold", + "@name is a gold digger", + "Ayo @name wanna buy some frog legs?", + "Brb fucking burnt my pizza rolls", + "I swear @name if you need roll again", + "@name you are a hunter you don't need plate armor", + "Dragonriding is satisfying", + "There's an old TzHarrian saying, you fuck up once, you lose two teeth", + "FUCK", + "@name i am ready when you are", + "Anyone selling logs?", + "That is hilarious @name", + "Alright @name", + "I need to go get my quest cape", + "500 barrows runs dry", + "Back to back to back barrows items, easy game", + "@name did you know them?", + "@name sucks eggs", + "@name eats snails", + "Who is that?", + "I've gotta go in 20 minutes", + "Bonk", + "Gtg in 30 minutes", + "They left 50 minutes ago", + "I think it's just gonna be us", + "Who is that?", + "Stop following me", + "@name stop following me", + "I think @name is watching me", + "@name wouldn't let me get a hit in at clan wars", + "Clan wars and chill?", + "Quick mewing sesh", + "Don't you stickbug me", + "Get stick bugged", + "Wtf why are you a dragon", + "Fun fact, woah eats eggs whole like a snake", + "Ceikys there's a rare over there", + "Where is goldshire?", + "How long have you played @name?", + "Wanna quest?", + "TROGDORRRRRR", + "Fuck this shit i'm out", + "Wait till you get your first 99", + "How is that even possible", + "That's the max", + "@name is trying to max", + "Complesionist cape?", + "How can you increase your run speed?", + "@name where is barrows?", + "@name where are rune rocks?", + "@name where is yanille?", + "@name how long have you played for?", + "Yes these quotes were hand typed", + "Kermit was here", + "World of Warcraft died after Wrath", + "Ceikry needs to add talent trees", + "How do you get to the wilderness?", + "Anyone tryna lure @name?", + "@name tried to lure me", + "@name bots all the time", + "Anyone want chicken tendies", + "Brb foods ready", + "Brb", + "Gotta go get food", + "Anyone else from northern alaska?", + "Fishing 4 gp", + "Looking for gf", + "Anyone wanna be my discord kitten?", + "Selling discord kittens", + "@name is a discord kitten", + "Add me on discord", + "Are you in the 09discord", + "Where are you going @name?", + "Idk what i am going to cook today", + "What should i eat tonight", + "He is in the cave", + "Don't forget to save game before logging out", + "American horror story died after season 1", + "Prequels are better than the sequels", + "Disney star wars is the best star wars", + "Halo 5 sucked", + "Selling xbox live gold and 1600 microsoft points for 50k gp", + "Buying gf 25gp and a bucket", + "@name i heard evilwaffles bots", + "@name hopefully ceikry doesn't find out about evilwaffles", + "Honk honk", + "Where is the road to mordor?", + "Golem lookin ass bitch", + "@name rat looking mf", + "@name uses sand paper to wipe", + "@name said Woah is cute", + "You need 25 of 40 to do that", + "Over 1000 unique lines of dialogue", + "What should i get to eat", + "Ge be poppin today", + "Where all the woahs at", + "Ayo woahscam got that gyatt", + "That is one i haven't seen before" + ], + "halloween": [ + "Trick or treat!!!", + "Boo! Hahahahaha!!", + "Have you got your costume on, @name?", + "How much candy did you get, @name?", + "Don't dead open inside", + "Costume party at my P O H!! Follow me!", + "Trick, then!", + "Brrrainssssssss...", + "'Cause this is thriller, thriller night!", + "This is Hallowe'en, this is Hallowe'en!", + "This is Hallowe'en, everybody make a scene!", + "In this town we call home, everyone hail to the pumpkin song!", + "Watch out for Skeleton Jack!", + "The headless-what-man? Horse? Never heard of those.", + "Bring me their souls!", + "I'll take any sweets you don't want, @name", + "Whatever you do, don't come to Draynor Manor on this spooky night.", + "Ahhhh! @name, you scared me! :(", + "I'm making soup from some leftover pumpkins, want any?", + "I'm gonna be so sick from eating all these sweets...", + "Rise from the grave, my minions! Tis' Hallowe'en!", + "This Scream Fortress 2 update hits kinda different...", + "Nice costume Woah", + "Nice costume, @name!", + "Ooh, a piece of candy.", + "Time to join the skeleton war, @name.", + "Spooky scary skeletons!", + "Spooky scary skeletons!", + "Spooky scary skeletons!", + "Spooky scary skeletons, send shivers down your spine!", + "Shrieking skulls will shock your soul, seal your doom tonight!", + "Spooky scary skeletons, speak with such a screech!", + "You'll shake and shudder in surprise, when you hear these zombies shriek!", + "'Cause spooky scary skeletons, shout startling shrilly screams!", + "Spooky scary skeletons, will wake you with a boo!", + "*doot doot*" + ], + "approaching_christmas": [ + "Only @timer days left till christmas!", + "@timer days till christmas @name!!!", + "I cant believe theres only @timer days left till christmas", + "Isnt there @timer days left till christmas??", + "I am so excited for christmas @name!", + "Guess whats in @timer days @name?", + "Im so excited for christmas in @timer days!", + "I cant believe its December already @name!", + "Do you like christmas @name?", + "I love december its my favourite month @name", + "I love winter so much @name", + "I hate when its cold outside @name", + "You need to put some warm clothes on @name", + "Wanna build a snowman @name?", + "Frozen is a terrible movie @name", + "@name is a winter meme", + "@name do you have an advent calendar?", + "@name builds gingerbread houses", + "@name likes liquorice", + "Do you drink egg nog @name?", + "@name bites candy canes", + "@name is my north star", + "Kermit is green, the grinch is green, coincidence?", + "@name who do you thinks the server scrooge?", + "Do you like snow @name", + "I think there are @timer days left then its christmas?", + "What day is christmas on @name?", + "Has it snowed where you live @name?", + "I wonder when it is going to snow", + "Building snow men for GP", + "Buying santa hats", + "Wanna buy a santa hat @name?", + "Where can i get a santa hat?", + "I need to put my christmas tree up", + "Do you like gingerbread cookies @name?", + "Do you decorate your christmas tree @name?", + "Oopsie looks like me and @name are under a mistletoe", + "I need ideas for stocking stuffers", + "I have @timer days left to fill our stockings", + "Fuck the grinches bitch ass", + "Rusty = the grinch, @name = santa", + "@name the red nose reindeer", + "Put one foot in front of the other", + "And soon you will be walking out the doooor", + "Elf on the shelf time", + "@name loves pinecones", + "I love the smell of pinecones", + "All i want for christmas is @name", + "@name is underneath some mistletoe", + "Woah used to be a sled dog", + "Did you know woah was a sled dog before", + "I bet @name loves mariah carey", + "We have @timer days to setup christmas lights", + "Christmas crackers when", + "@name wanna do a christmas cracker??", + "I need to start wrapping presents i bought", + "I love fireside chats on cold days like this", + "Jingle bells batman smells", + "Jingle bells Rusty smells", + "Jingle bells Patch Notes smells", + "Jingle bells Evilwaffles smells", + "Jingle bells @name smells", + "Jingle all the way", + "Stroke-a my, Lick-a my, Suck-a my cock", + "In a one horse open sleigh", + "Oh, what fun it is to ride", + "Oh, what fun it is to ride, finish it @name", + "Jingle bells, jingle bells", + "Jingle all the way", + "I want a hippopotamus for christmas", + "Only a hippopotamus will do", + "I want a hippopotamus", + "I dont want a lot for Christmas", + "All I Want for Christmas Is You", + "I really cant stay, Baby its cold outside", + "Christmas isnt a season. Its a feeling", + "Christmas is doing a little something extra for someone", + "There is nothing cozier than a Christmas tree all lit up", + "Christmas is a necessity", + "Christmas countdown: @timer days.", + "Christmas in @timer days @name", + "Frosty the Snowmannnn", + "Up on the housetop with old saint nick", + "Here comes santa claus, here comes santa claus", + "I saw mommy kissing santaaaa claus", + "I saw Kermit kissing santaaaa claus", + "You are a mean one, Mr. Grinch", + "Deck the hallsss", + "ITS BEGINNING TO LOOK A LOT LIKE CHRISTAAMASSSSS" + ], + "christmas_eve": [ + "I cant wait for christmas tomorrow @name!!", + "Its almost christmas!!!", + "1 more day!!!!!", + "Dont forget to put cookies and milk out tonight!!", + "@name do you like christmas??", + "Happy Christmas eve @name :)" + ], + "christmas_day": [ + "Merry Christmas @name!!", + "What did you get for christmas @name?", + "ITS CHRISTMASSSS!!!", + "Christmas party time!!", + "@name vibing with the christmas spirit", + "Cant believe its christmas!!", + "We need to have a christmas party @name!!", + "Merry christmas @name :))", + "Hope youre having an amazing christmas @name :)", + "I love winter so much @name", + "I hate when its cold outside @name", + "You need to put some warm clothes on @name", + "Wanna build a snowman @name?", + "Do you like christmas @name?" + ], + "new_years_eve": [ + "What are you doing for New Years @name?", + "New Years Eve party orrr?", + "We should do something for New Years eve today @name!", + "Happy New Years Eve @name", + "1 More day left in 2021 thank god", + "Whats your New Years resolution @name?" + ], + "new_years": [ + "Happy New Years @name!!!", + "Its New Years Day @name!", + "HAPPY NEW YEAR @name!!!", + "2022 lets fucking gooooooo", + "What are your goals for 2022 @name?" + ], + "valentines": [ + "Will you be my valentine @name?", + "I am so happy rn", + "God i am so lonely", + "I am Ceikrys illegitimate child", + "Be my valentine!", + "Lets sneak off somewhere and kiss @name", + "What are you doing for valentines day @name", + "Woah and Ceikry be kissin lowkey", + "In for a peg @name?", + "Woah got those roofies strapped", + "Why is my drink cloudy?", + "@name and woah be wrestlin", + "Bekky want sum fuk?", + "Damn @name you got an ass", + "Is that a footlong in your pants or are you happy to see me?", + "@name so hot i gotta change my pants", + "@name is a sex god", + "Bruh we hype today", + "Dont be silly wrap the willy @name!", + "Wrap it before you smack it @name", + "Can i get a reeeeee @name?", + "Valentines day is the best day", + "@name shut up before i smack you with my crusty sock", + "Valentines day, more like me and my hand day smh", + "If you think these quotes are wild just wait @name", + "All im saying is we have never seen @name and biden in the same room", + "Red rocket, red rocket!", + "Woahs favourite game is red rocket", + "@name sexy af today", + "Happy Valentines day @name!!!", + "Happy Valentines day @name!!!", + "Happy Valentines day @name!!!", + "Happy Valentines day @name!!!", + "Happy Valentines day @name!!!" + ], + "easter": [ + "Happy Easter!!!", + "Happy Easter @name!!!", + "Bunny time", + "Wanna go look for easter eggs @name???", + "Find any easter eggs @name?", + "@name is the easter bunny!", + "Kermit is dating the easter bunny!", + "Easter is one of my favorite holidays", + "I heard there are easter eggs hidden around?", + "Easter is the only time you should put all of your eggs in one basket", + "I said hip hop do not stop", + "Jump jump jump around", + "@name how is your easter going?", + "I love easter!", + "@name stole my easter eggs!", + "Karma karma karma karma karma chameleon", + "@name!! @name!! what are you doing for easter??", + "The hare was a popular motif in medieval church art", + "I heard the easter bunny is hiding somewhere!", + "I wonder where i can find more eggs", + "@name how many eggs did you find?", + "@name lets go easter egg hunting!", + "@name like orange chocolate eggs", + "@name and woah know the easter bunny", + "@name did you know ceikry swallows eggs whole", + "Have an amazing easter @name!", + "Happy easter @name!", + "Hope you are having an amazing easter @name!!!!", + "Wooooooh easter!!!", + "@name loves easter too!", + "Who else loves easter like i do??", + "@name and i are going easter egg hunting", + "@name and i are going to look for the easter bunny!!", + "Hint for anyone who sees this you must dig above eagles peak" + ] +} diff --git a/Server/data/botdata/botnames.txt b/Server/data/botdata/botnames.txt new file mode 100644 index 0000000..22c5715 --- /dev/null +++ b/Server/data/botdata/botnames.txt @@ -0,0 +1,64160 @@ +-Kevo +0 S O +0 4 1 1 +0 4 7 +0 HBK 0 +0 Khan 0 +0 LM +0 Quest Ptz +0 Undead 532 +0 hits +0 s m a n +0-0000000000 +00 zarour 00 +000eggs +004 n +007 Double O +007Banshee +00eeeee58 +00eeeeeHC +00oo00oo00z +010elpibexx0 +014ankh +01690 +017Lucas +01Ares +01eon +01ogre +020893 +024elyograG +02RS +02homestar +031 +0315 +0416347345 +054 +055027584 +05miller5 +05venom04 +06 59 +0600 +06sz +07 Account +07 Adept +07 Ashley +07 Clinton +07 Ezra +07 Gizzy +07 Main +07 Nihilist +07 Officer +07 Rz +07 Sicario +07 T Bone +07 iron +07 kiero X +07 nice jake +070623 +07Ashley +07Ben +07Geno +07Jack +07Lax +07Panda +07Paul +07RS Suck +07Rockysbudy +07coco +07guthix07 +07wan +080 +0800 +0800952449 +0837 +09 +0920 +09Ash +09Ashley +09Ato09 +09Chris +09Dans +09Paul +09Reaper +09Rhys +09Rvape +09Skillerino +09TroyScape +09milo456 +09scaping +09wan +0BAMA +0Behind0You0 +0CdanC0 +0G +0GCore +0Giesel42O +0IIll0llIIII +0JL +0Joker0 +0KAT +0LKI +0MEGA PVM +0MG ST3PSIS +0MW2PVM +0Manbearpig0 +0MrJ +0PC +0Pwnseason +0S Iluvatar +0SFX +0Tempest0 +0WEK +0X010 +0_BADASS_0 +0anabanthis0 +0bD0G +0bankspace +0bby +0bby Man +0belix +0bscure0ne +0ctopus +0dds r u win +0desza +0dexy +0dyssey +0ff Task +0ffline +0g_player +0gden +0ggyy +0gie +0h Hi Mark +0h4Sure +0hh +0hmMyGod +0hp +0im2old4this +0inke +0k +0l +0l m +0ld Mate +0leaguespace +0li +0livers +0livias +0lki +0llieNorth +0llies +0lmet +0lofmeister +0lurker0 +0mfgcows +0mg A Baboon +0mg A Scimmy +0miseGo +0mnisciens +0n Time +0nMyWay2Max +0na +0nenonen +0neski +0netruememe +0niichan +0njon +0nlyClouds +0nmy +0ops +0oqs +0pSe +0pen +0pen Al +0pi ates +0pportunity +0riole +0rjan +0rl +0rnstein +0rphaned +0samaBdabbin +0sc4r +0smasher0 +0so +0ssimpwner +0syb +0t +0taku +0taylor +0verHyped +0verdrinking +0verhaul +0vershield +0viBeSo +0vyy +0wnag3s +0wnage_2017 +0wnagedaddy +0wned +0wns +0wnu1h1t +0x Good x0 +0x05 +0xBitcoin +0xocube +0xp Fail +0xygen +1 +1 0 1 0 +1 1 4 +1 2 2 +1 337 +1 3s +1 4 11 +1 54 +1 9 7 +1 A M O R +1 A N D 1 +1 Account +1 Corin 6 9 +1 DC +1 Flicki Boi +1 Free Ryde +1 Ham +1 K0 Is Back +1 Line +1 Lion Tell +1 P P 1 +1 Percent +1 Waffle +1 and only +1 is ln of e +1 kc 1 pet +1 parhaista +1 s t Blood +1-800DILLDOE +1-GrayStone +10 Four +100 Duke +1000 Antz +1000 Eyes +1000 Ways +10000Fists +1000PingOnly +100Cl +100Grabb +100g +100kyews +100m gp +100xcoin +101000101010 +1017Trev +101e +101evil101 +101rootbeer +104512 +105 +107M +1085 +1099s +10Hz +10R80 +10b +10cc +10lachs +10mm mafia +10th Reaper +10v10 +10v10v +10v10v10v +10x Brew +1101953119 +1111 +11111111111d +111fishkite1 +112OceanAve +116 +116 123 +1183kenny +118s +11inchlimp +11l1 +12 +12 49 +12 XP +12 hours +120u +1212ajs2 +123 Zeus +123456205 +123Four +123bear5 +123tseemijni +1272172 +1288 +12bar +12bar_ty +12blackeagle +12boo8 +12earlycob +12in +12millionGP +12oss +12oz +12th +13 37 +13 Daas +1300 +130SS +130rk +1312AFCA +1313 +131kg +1337 af +1337Trevor +1350 +138hans +13D +13LACK0N3 +13O +13alerion +13ayek +13ehh +13ert1 +13ig +13igdog +13kc Corp +13oneZ +13purecs +13ruce +13th Witness +14 wides +1400 +14060M +144 +1441 +144forever +1453 FSM +149122089147 +14Fre-e +14GT +14Words +15 min Break +150 kilos +1520sedgwick +15b name +15mg +16 Fly Tell +16 Fps +1602 +16bumpysnow +16lB +16le +17 76 +170 IQ +17222 +1780 +17Kc +17_FLHXS +17rune2277 +18 Or Older +18 Points +18 girlll +18-06-2022 x +1800BetsOff +1802M +180555 +181 +1817 +1827 +1845 +184910381412 +187 +187 781 +1877 +187PIGMORGUE +187er +1889 +18cast1935 +18hr +18killz +18s +19 KAPLAN 05 +19088ml +1942 +1948 +199 +1992 +1994 +19O7 +19edgebee +19puxx +1AB +1After909 +1Alfa +1Ali1Plane +1BGP +1Bio +1Buck1Love +1C2R +1C3 W4RR10R +1CuteBot +1Fbs +1G1D +1GramIronMan +1Hit2Lum +1Hunnid +1I1I1IIll1l +1InchWalrus +1Iron Reborn +1Kyle +1Lank +1ManGangBang +1Mayze +1NANO +1NU +1Nikolai +1Nut Dude +1O1Barz +1Ogp +1P Game +1Parthannax2 +1RlE +1ST KC +1Shadow9Fist +1Shark +1Stunner ISU +1Swan +1TapDirtNap +1Tick +1Tick 2 Slow +1TickShit +1Unforgiven8 +1_BLEED_BLUE +1ars +1badprogram +1bankingnoob +1blackhawk17 +1blk eye r2 +1cooking +1da5 +1dan2 +1day +1day iwas pk +1eat +1einad +1eyeNinja +1god max1 +1grootfeest +1hundrednite +1imp1jar +1isa +1itemtbow +1jbone +1john +1k no zik +1kDuramax +1kMaster QXD +1k_0 +1kc myself +1kctobpet +1kill3dsanta +1kk3 +1kkc +1kona +1llmatic +1llusionss +1mforest +1nOnlyBigB +1nVaSioN +1ndy +1ne life +1nfiniti +1nsane str5 +1nv1s +1nvercargill +1o 8 +1ocation +1please +1powerhydra +1r0nRyan +1rock23 +1savage +1st Frans +1st ed mint +1st son +1stHCwasPKED +1stlrfan +1stnoob7 +1t8w +1tapaturma +1tickspecwep +1trueMortyy +1ucif3ro +1v1d a sedan +1w1lll0se +1wayEscape +1wwdwd2e21ed +1yfe +1zet +2 0 1 4 +2 1Savage +2 2 7 7 +2 2 8 9 +2 3 7 5 +2 9 +2 Big tities +2 Brothers +2 Much Tuna +2 P A C +2 Rich 4 Dis +2 Silent 540 +2 Smooth +2 ball cane +2 funny bro +2 grls 1 Jad +2 h p +2 in +2 kups +2 lN +2 more min +20 20 vision +20 Agi irl +20 On Pump 3 +200 +200 Cook +2000 +2001Arwen +2006nope +2007scape +2008Anthony +2009Anthony +200MXP Cook +200m for Olm +200mDefence +200marchalt +200mslay1day +2011Turmoil +2013 Rt +20130406655 +20136 +2027Parzival +202o2 +204 Wootang +205alphago +208 +209th +20Four +20I0 +20JuanSavag3 +20ms +21 5 +21 Average +21 Musketeer +21 Savage +2137 gp +215O +2173 +21JJ +21SavageX2C +21unit +22 69 +22 Geese +22 Gz +22 darnoc 22 +22 day fury +220mg +226559 +227 7 +2277 +2277 Beast +2277 Soon TM +2277MaybeNvr +2277kg +22O5 +22X7 +22btc +22harry +22mario +22whitewolf +23 x 3 +232o2oo +234071973416 +23463564 +235iii6i666i +2376Total +2376ed +23847239571 +23CD +23I +23coalcare +24 Hour +24000 +241 +241196 +2424 +245 +247 365 +2488 +24YO +24l7 +24w +25 S +25simulator +26 th +260sheepdog +265344626546 +26ll98 +26pandas +26th +27 5 +27 M +271MPN +27ml +2841280 +28BagsOfSalt +28goldpieces +290x +29384652 +2996 +29Pons30 +29enchant821 +29robdead +2B Nier +2Broke4Coke +2C-T-2 +2D E F2 +2D pantsut +2Edgy4Meme +2Far +2Fast2Fuego +2GIRLS +2GLE +2Girls +2Goblins1Jug +2Guys1Wyvern +2Guys1dds +2I40 +2InchLift +2InchPnisher +2JZ GTE +2JZ Soup +2JZ-GTE Mk4 +2Jerry +2Lit +2M0X1 +2MIN +2Men +2MinNoodles +2O xp +2O07 +2OO7 +2QC +2Rare2Die +2Secs +2Sparks +2TH3MAX +2Tbows51Kc +2Tits +2TonHoneyBun +2VX +2amtossedher +2anmlsglued +2beFrank +2buttedgoat +2cbrein +2coldkillaa +2cool4u +2cythe +2d irl +2danny1 +2dslap +2fastkilzz +2g0ds1cup +2girls1Kyle +2girls1Tbow +2girls1bed +2girls1troll +2girlz1jbird +2gurls1tick +2h ur azzzzz +2hopp +2hot2touch +2hot2touch2 +2hs +2id +2kav +2late2team +2logx +2nd Marksman +2nd Max Cape +2nd Sucks +2ndpanz +2olon +2oul +2pac +2pacs +2plush +2sm0keyyyyyy +2steps +2th7 +2tickin +2tti +2two77 +2uBz +2ual +2ugi +2woke +2x92is99 +2ze +2zick1zussy +3 Hit V +3 5 P +3 50 +3 77 +3 Moons +3 S I X E S +3 SwordStyle +3 T C +3 arcanes ty +3 me0 +3-age +30 yo b00mer +300m MPS +3019 +30FF +30SHOTFOCUS +30XY +30thNovember +30zl +311s +3155 +315lbs +315squatreps +3160 +316Austin +32 kay +320m +33 Dust Cat +335K +33jf +33zero2 +3400 +341all +34241245321 +345138 +34HL6432G6L2 +34T +34rj394thgro +351329 +35ankoumoon +35cm bicep +360 Labels +360backhand +365 day +369x +36ACT +36answersay +379 +37Kg +37kg +381N +38CoolestMan +38drivelift +39 PETS +3BigDoobie +3D AnimeTits +3D Dorito +3E8 +3G +3III +3L1QZaD +3LetterName +3Miller3 +3TicYaMum +3TickEat +3Ticks +3WordName +3a B0ng +3aly +3amf +3arbeed +3ash +3awe +3b +3bay +3bobyshmurda +3d age boots +3d354 +3dderino +3erzerk +3h scimitar +3ibal0e9 +3inchsoft +3ioc +3iron5u +3km +3lPatron +3lack 3litz +3lilbirbs +3lit3 +3liteSupreme +3lven +3lyrie +3lys +3niZ +3nosedmonkey +3nps +3oh5 +3pic +3ragesave +3rd Age Ryan +3rd Age THC +3rd Age Toes +3rd Age Wife +3rd Hunter +3rd Mage Owl +3rd X +3rdAgeHolds +3rdAgeHunt +3rdAgeSlayer +3rdMistake +3sd +3sl +3stripe +3uck +3uzi +3verD3ad +3vil +3vil Giraffe +3vil Lawyer +3we +3x3i +3xDestroyer +3xtra-1arge +3yes +3zR +3zi +4 Bros Info +4 Man Nex +4 inch demon +4 inches now +40 IQ +400L +400s +403 b +40699 Crabs +40Atk +40ms +40oz +412087542131 +413 JokeR +416MiIf Jade +41O +42 Mime 2462 +42 Reasons +42 skankhunt +420 Perkele +420 Sam +420 kc +420 lobster +420-2-Day +420Arch420 +420Every +420Hellz +420LavarBall +420Pixels +420cyguy +420licious +420michael13 +420tarmslyng +42342343342 +42Def +42O42O +42nd +432andone +43technetium +44 bot +4400 +44444444444 +45 fail +4500c +4564 +457 +45smith2345 +478k +47an +47th +48H +48hour +49 r +492117837813 +49forcerage +4ALLYaYa03 +4D Entity +4EverAlone +4HeadScape +4Hymnz +4IQ Idiot +4K MrKrabs +4KT Youngboy +4Kath +4L O K O +4LDO +4LeafCIover +4Lt Goon Bag +4MoistScoops +4Nick8 +4STER +4Sale399 +4TheGalaxy +4The_Horde +4Tune +4V2Coldplay +4_Th3_mAiN +4are +4asphalt4 +4biddin3 +4cof +4dan2 +4dapigs +4dosemonster +4ever +4everdry +4got2pull0ut +4gottenvoid +4hQ +4hit pl0x +4holyhydra +4iend +4lex4nder +4litraa +4mag1996 +4otobemaG +4pf PvM Lao +4pf danaw1te +4plate +4rKsTon3 +4sen +4th lesson +4th8 +4the +4themininoob +4thunderbolt +4ur Elise +4werty4 +5 56 +5 Nine +5 Oh +5 mil +5 ms +5-Bet Fold +50 DKP Minus +500 BJ +5000men4 +505 +50Dkp_Minus +50TintenUwMa +50bitsnka +510 +51Highlander +51xp +528racklover +5304 +530pm +53R10U5 +53m0g +54 Slayer +548 +55mg +562 +5639 +56667 +56771910 +56O +570215 +5771 +57tallfred +57wraith2076 +5876 +58th +59OG +5ADx +5Aces +5BY5 +5G fries +5GCovidTower +5H4NKS +5IRLOIN +5Id3Track +5M3H +5M9SNH31KAOI +5NAX +5OP +5Orudis5 +5UBLlME +5a9 +5alood +5alve +5ammito +5dudes1bank +5eekingdeath +5eizures +5g Internet +5gum +5harp5hoota +5hauny +5hayWh1te +5head +5inch Floppy +5is +5j5 +5kc Zulrah +5l9 +5lNS +5lap +5nis +5parrow +5quid +5st +5t h +5th Blessing +5th hcim LUL +5trm +5wan +5wattia +5x3 +5xr2 +6 57 +6 9buttholes +6 Donuts +6 Drive Fox +6 Foot 5 +6 I X GOD +6 M +6 Mil +6 Qp +600 Years +605 +60min is 1hr +617 +61V +6264 +629fm +62steeplist +6384 +647 +64DD +64th +6535 +6620 +666 317 +666 J +666 is leet +666Ds +666Duuvel666 +666drkwizard +66Cute +66sick +675 +67M +67jj6j7 +68 savage +6822ii +68pickleman +69 L OR D 69 +6942O +69KolaOlli73 +69Skrrt420 +69bbygurl +69maryj420 +6Dukke +6ESkarmory +6LACKY +6PaperJoint +6R6 +6T9sofine +6TMG +6Tilbud +6UGG +6cansOfBeer +6cythe +6dr3w9 +6e +6enny +6ess +6et Schwifty +6h Logout +6in9 +6ix +6ixty +6ixx +6jadkiller +6km +6lb brownie +6mat +6ong +6p8o6 +6pathsofpein +6qp +6shooter +6uapo +6uh +6utt9lug +6y6y6y2 +7 7 MAFIA +7 Curry +7 DeadlySins +7 Fat Drake +7 Of Nine +7 Trouts +7 pets chimp +7 seconds +7042 +70Point1 lol +70rangeboy +70to120 +710 710 710 +716 +718m +71rc +72005sc +73 and Kree +734590325839 +737 +73Head +73HoundKey +73gp +742617OOOO27 +74ChaosLTUU +75 IQ +76frozen44 +76ms +7738 +777slayer777 +77Dunamis77 +77Stingray +77ms +782 +784162 +79giantfoot +7AYL0R +7D9 +7Esconar7 +7Ethereal +7F9 +7GB +7God +7H3 +7J4FXEL7YFW5 +7Lazy7 +7RAC +7T +7TF +7Vick +7Viggie +7ZP +7abibi +7amowdahli +7aq +7asty +7ate9 +7axy +7bazillion +7ckng +7ckng Mad +7claudia7 +7crypto7 +7emo +7emp +7emptest +7fisherdog +7havage +7min +7mins +7mni +7om +7ourney +7out +7rad3 +7raphouse +7rev +7ridley +7scaryfire +7th Chamber +7th February +7uP joAo +7wizard10 +7xshadowx7 +8 1 O +8 3B +8 Sue Build +8 alien 8 +8 bit bling +8 oh 8 +8008tator +808Southside +80leavefox +82 Sue Say +8282 +831pride +832arba +8485 +849 +84Bandit +85 N +8502 +852K +858 +85U +85dakota85 +88 Odd Wand +8800 +8885 +88gg +89devoid1329 +8ASS +8BootRaw6220 +8ElMandinga8 +8J8 +8O8O8O8O8O8O +8ass +8balknowsall +8balled +8eauty +8h of sleep +8ind +8l0wm3 +8lackMamba24 +8loodrune +8lue Phat +8owser +8qxkf02v +8tail +8uD +8yrs +9 9 Problems +9 B 0 +9 DUIS +9 Tick Brain +9 mb +900mexp +901Grizzlies +90804 +9092514 +90tegguy +91 +91 Tin Idea +911_Nate +91414 +91CAL +91flip +92 way there +920 Bdops +9227 +9297 +92t +92times2is99 +94 xp +94AR BTW +95EliasAw +95LH +95p7 +96 WINDSTAR +9687 +96fastfrog +97DEF +97ccman97 +97fsh +98 BEDARD +98 Civic +982 +98Bn +98max1 +99 Doobies +99 Grill +99 Grinding +99 Mage +99 Rats +99 StaKe LvL +99 Steeze +99 oz +99 rwt +991atatime +9991499 +99BnkStnding +99Juuling +99Lives +99S2HP +99Scents +99Scotting +99Slayer +99Souls3Days +99Victim +99_Maxed +99bottin +99charming +99hh +99moretimes +99ox +99problems4 +99ss +99sweatlvl +99wc500m +9Bar +9Barr +9CX +9D9Skillzz +9Dimensional +9GAG Reflex +9JR +9KL00AZIIZ9K +9O 9 +9PetsSoFar +9T3 +9TY9_Sailing +9UNIT +9cansRavioli +9ieman +9inchStepBro +9mm ko +9mmlesah +9ne +9ond +9till5slave +9ussy +9yearoldpops +A 2 The Aron +A 3 +A 45 +A 7 F O L D +A Articuno +A Bad IGN +A Bad Meme +A Big Hippo +A Big Leap +A Blind Man +A Booty Clap +A Born King +A Boss +A Bozo +A Bozz +A Bronze man +A Butcher +A Catowl +A Cityzen +A Claptrap +A Classy Boy +A Crazy Cook +A Crisp Sock +A Curry +A Cute Snail +A Dreamer +A Drunk Beer +A Du Ma +A F K Scape +A F KING +A F M Scape +A Fat Deer +A Fat Pike +A Fat Swede +A Gauss +A Girthy Boi +A Godsword +A H Fire +A Half Fool +A Hofasho +A I D E N +A I I e n +A II D +A Iron Yoshi +A J +A JJug +A Jack O Lit +A Jug +A Kimura +A L 3 X +A L C A P WN +A L E K S +A L I S H A +A L T +A Lava Lamp +A LifeTime +A Lilypad +A Little Lit +A Llama +A Long Story +A Loose Seal +A Mattias +A Maxed Iron +A MaxedBeard +A MeatStick +A Melic Poet +A Message +A Moist One +A Moot +A Nathan +A New Area +A Newbi +A P R O X +A Panther +A Pauled +A Pixxel +A Pkr +A Plush +A Poothy +A Pot Head +A Psy +A Quest God +A Quickie +A R H +A R Z +A Raccoon +A Random 4nr +A Real Bamf +A Revuelto +A Rocky Road +A Scylla +A Sly Deity +A Snorelax +A Sofa +A Soft Spoon +A Solo Slave +A Soul Rune +A SpaceFox +A Spaceman +A TRX +A Tonk +A Towel +A Tuxedo Guy +A U G +A V T U R +A WILDR0NNY +A White Girl +A Wiki +A Wild Nolan +A Wise Sloth +A X Y S +A Yang +A Yep +A Zee +A Zeer +A Zoo Keeper +A Zuk +A Zuzakini +A aron +A bit north +A broke 126 +A capybara +A cclimation +A d e b y +A dam +A damm +A dammmm +A e d o +A e s i r +A f r a i d +A gg +A lba +A ll F +A llan +A llstar +A ltar +A m a nd a +A n d re +A nz +A rdy +A rmin +A rmoa +A rrow +A stoner guy +A to teh Jay +A ug +A y s a +A z k e n +A z t e r +A-Chronic +A-F-Kaveman +A123 +A13X +A15 +A1KMAN +A1nz00alGown +A1rhook +A2 +A22Y +A47 Soldier +A543 +A7MED +A84 +AAA GG +AAAAAFK +AAAAAddy +AAIGHT +AAsamba +AB Dash +AB84 +ABEC +ABG Huntr +ABILITEETTI +ABearCat +ABlazys97 +ABlueShirt +AC Dicing +AC TEMP IQ +AC0T +ACDC +ACatGirl uwu +AColdBeer +AComp +ACucumber +ADACardano +ADAMB73 +ADHDerral +ADRlAN +AD_inc +ADankTank +ADirtyDan +ADrugTaker +AE2AW +AEKDB +AER0B +AER1410 +AFCA +AFCA CBS +AFCA SCHOREM +AFGard +AFJay +AFK Always +AFK Kay +AFK Liam +AFK SCO +AFK Spoon +AFK twigz +AFKJOHN +AFKaas +AFKarl +AFKevv +AFKolby +AFKspiracy +AFTW +AFX64 +AFrickinLion +AGIT8 +AGP3 +AGRONOMlST +AGSpec +AGWA +AGlassOfH2O +AGorski +AH Energy +AH64 Apache +AHHSCHMEEEEE +AHK XD +AHMETJACKSON +AHarmlesKitn +AHlager +AHriMTaLeZ +AI Fighter +AI0 +AII 99 +AIchemyz +AIecko +AIeksib +AIexmeister +AIixs +AIlByMyself +AIm23ARDesti +AIways sm1le +AJ R +AJ Skills +AJ4J +AJTracey +AJ_24 +AJisHere93 +AJsk +AK Alpha +AK Sam +AK47 +AK4LF +AK5C +AKI-47 +AKK1E +AKM +AKSpring +AKinkyMonkey +AL-Trojans +AL3CX +AL7 +ALBlNO +ALEXppresso +ALLCAPS +ALLEGATlONS +ALLTY4 +ALSO +ALT Lurer +ALargeMudkip +ALevel115 +ALevel126 +ALittleLofty +ALittleLogan +ALonelyKurt +ALonelySpoon +ALonelyTaco +ALv3Magikarp +AMAWM +AMC Millions +AMD352 +AMDOSRSIRON2 +AMGS65 +AMRSY +AMST +AN07HER +AN0NYM0OOOUS +AN1MAL1ST1SK +ANDERDAPLUG +ANDR3 +ANDREVVTATE +ANDROlD 18 +ANGL0 SAX0N +ANGRY BL0KE +ANGRY N3RD +ANIKV +ANNA7AR +ANNOYYEED +ANON +ANRH +ANUBlS +AOMA Doomfox +AOT GOAT +APC L000000L +APTZ27 +APrince +AQ COCUGU +AQMD +AQUAMARROCKZ +AR Brah +AR Fifteen +AR15ONA +AR1F +AR53 +ARCANO RS +ARCHER +ARCHIT3CTS +ARESCREED23 +ARNGCantrell +ARRIVISTEZ +ARRRot +ARTHURSHLBY +ARTIZN +ARZ Ranger +ARandyCat +ASAP +ASAP Decky +ASDQ +ASH88 +ASIAN CHAD +ASIANBABIE +ASMR +AScrubIsHere +ASkillersAlt +ASpacejunky +ASuperDood +ASuperior +AT-AT +ATAR96 +ATEIROMU +ATLx +ATR +ATastyPastry +ATurboVirgin +AU6URY +AUD1O +AURl +AUSLANDER +AUSTlN +AUTOart +AUTUMNELEGY +AUT_Alex +AUT_KoDeD +AV1 +AVATARRR +AVE MARlA +AVICll +AVOCAD0O00OO +AVlCII +AWW CRIKEY +AX0L0TL +AXL gun ROSE +AYRI DMM +AZER +AZNPanda +A_G_4 +A_Wuh +AaaBiiCee +Aaalmost +Aadalyn +AadreNaline +Aahatto +AakieSnaakie +Aaking +AangTurambar +AardbeiSoep +Aardwormpie +Aaren +Aargh +Aarhus +Aarmir +Aaro236 +Aaron +Aaron 23 +Aaron Btw +Aaron Quiz +Aaron Samuel +Aaron11700 +AaronJMLP +AaronPVM +Aarsworm +Aarti +Aary +Aaryn +AashUnce +Aastradsen +AatroxLife +Aauburn +AavikonGaara +Aayraz +AbInito +Abaay +Abacraumbii +Abaiz +Abaker +Abaqus +Abariel +Abbas Elect +Abbey +Abbey Ruins +Abbo baker +Abbyscimmy +Abc easy as +Abdallah6 +Abdirahman +Abe lnnkon +Abe numse +AbeTheHobo +Abengers +Abernasty +AbiChillii +Abide +Abido +Abigayyl +Abismaalinen +Abito +Abiuro +Ablazin +Abnegation +Abnxy +Abocrate +Abolish +Abolish NFA +Abool +Aboriginal +Aborts +Abortuary +Aboss +Abou3Fiddy +Abov +Above +AboveAvgGoat +AboveHonor +Abpor +Abr19 +Abradolf +Abrafebre +Abrakadaddy +Abrakadino19 +Abree107 +Abridgetolum +Abrils +Abritrage +Abruaa +Abruzi +AbsentPray +Absol +Absol-EX +Absolut1on +Absolute POS +Absolute St8 +Absolutism +Absolver +Absorpt +Absoullutely +Abstand +Abstergo +AbstractNay +Abstractable +AbsurdGreek +Absurdly Gay +Absynthial +Abu Chungus +Abu Salih +Abuk +Abulssoni +Abuv +Abyission +AbysmalGrind +Abyss Laps +Abyss Whip +AbyssFreaks +AbyssWalkerr +AbyssaI +Abyssal +Abyssal Roar +Abyssal Sire +Abyssal Wook +AbyssalEmu +AbyssalTrout +AbyssalWrath +Abysse +Abyzz +Acady +Acai +Acai Berries +Acamarine +Acan D +Acardi +AccessPoint +Acciainoli +Accio +Accio Bond +AccioHorcrux +Accolades +Accountant 0 +Accursio +Ace Kills +Ace12209 +Ace123445678 +Ace2cool +AceAlexander +AceArcaneon +AceOfSevens +AceTenSuited +AceTookUOut +Acefalcon3 +Acekicker +Acemachine +Acemanjam +Acenr +Acer +Aces +Aces x3 +Acesuke +Acesupersoak +Acetazolamid +Acha9 +Achaeos +Ache +Achenar +Achernar +Achievement +Achievements +Achilles Low +Achilles XXI +AchillesFist +Acholight +Achuu11 +Acid +Acid Cat420 +Acid Christ +Acid Dab +Acid Frick +Acid II +Acid Lunatic +Acid Magick +Acid Reducer +AcidBxbies +AcidHouse +Acide +Acidic +Acidylia +Acir +Ack Varmland +Acke +AckeSSBM +Ackman67 +Acko +Aclu +Aclyss +Acolytes +Acorn Potat +AcornHunter1 +Acoustics +Acquila +Acquilar +Act Ov Vodka +Actaeor +Actan +Action +Action Dwarf +Action Movie +Active +Active Whale +Active-Bombi +ActiveRecord +ActivelySent +Activeshot +Activis +Actor +Actt +Actual +Actual Bald +Actual Yak +ActualName +Actually +Actw +Acuila +Acumen OSRS +AcuraIntegra +AcuteSloth +Ad Pulvurum +Ad0pted +Adachigahara +Adada62 +Adalman +Adam +Adam pd1 +Adam8 +AdamBonar +AdamInAtl +AdamPwnz +AdamTehMong +Adamant +Adamanta +Adamantoise +Adamchrisp +Adammmmmmm +Adamp1 +Adampewpew +AdamsMain +Adamskieh +Adamy +Adaptations +Add Jisuke +Addderall +AdderLord +Adderall +Addi +Addicted Tom +Addicted2Rs +AddictedIM +AddictedSoul +Addlero +Addycusfinch +Addytt1 +Adee3 +Adeeb +Adelaw +Adele +Adelier +Adeliya +Ademon66 +Adenocard +Adept +Adept Brick +Adeptus W40k +Adeq +Adeus +AdeyP +Adgoar +Adhd Adam +Adhurim +Adi Laser +Adic +Adiieu +Adil +Adin +Adios Punani +Adiosk8r +AdjacentAce +Adjudicatior +Adjusted +Adjustmyfan +Adkille +Adley +Admetis +Admirable +Admiral +Admiral Addy +Admiral Kev +Admiral Nano +Ado12322 +Adogg0323 +Adolari +Adomirion +AdonisUkko +Adorak +Adorations +Adore +Adornare +Adr Iron +Adrean +Adrian +AdrianMMO +Adriatik +Adriatik7 +Adrik +Adriyxs +Adroid +Adskip +Adss +Adstar +Adster98 +Aduadu +Adust +Adusy +Advance2Max +Advanced Rat +AdvancedOwen +Adventure On +AdversY +Advvil +Adwan +Adyn1 +Adz92 +Adzyy +Adzz +Ae rith +Aeariyion +Aeckersss +Aecyra +Aedon +Aedreius +Aeganor +Aegislash +Aegon +Aeikora +Aejayem +Aelin +AelitenRS +Aelos +Aemil +Aent +Aeon +AeonsOG +Aequites +Aerack +Aerdont +Aergius +Aeric Shun +Aerith 68 +Aerivas +Aerj +Aero +Aeroaxe +Aerocity +Aerohead50 +Aerolustly +Aeromi +Aerosol +AeroxAces +Aerros +Aeryen +Aerzo +Aestana +Aesthetiix +Aeterni +Aetharan +Aetharyn +AetherEra +Aethyrs +Aeugh +Aev +Aeyriex +Aezolix +Aff it +Affaires +Affan Khan +Affect +Affectie +Affidra +Affinivax +Affirmed +AfghanisDan +Afghanistan +Aficionado +Afk Blake +Afk Jasper +Afk N Scape +Afk Ray +Afk Scape +Afk To Smoke +Afk em +Afk is EZ +AfkBandos +AfkGod +AfkMachine +AfkTbh +Afked +AfkforGainz +Afkillz +Afkin +Afkoelen +Afkstar +Afkwarrio6 +Aflamed +Afnacho1 +Afonso +Afperser +Afrecan +AfricaSavior +Africagamer1 +AfricanMelon +Afrie +Afrikka +Afriquee +Afro +Afro Deagle +AfroFishh +AfroShay +Afrojofe +Afroman +Afromann +Afromouse87 +Afrothunder +Aft3rmath +After Dark +After3Scoops +AfterLike +Afterlife +Aftermatter +Aftermax +Aftex +Aftyr +Afx31 +Ag0b +Ag3nte +AgagaWeeWee +Aganis +Agaperik +Agatsuma +Age Forever +Age of Hell +Aged +Agenda21 +Agent +Agent 3 +Agent Jass +Agent Slidt +Agent805 +Agent94 +AgentFluff2 +AgentOrnox +Agentbunny1 +AgenteGanso +Agentlobster +Aggressox +Aghiestic67 +AgiNagii +Agil +Agil Tank +Agile +Agile AI +Agile Rob +Agile Tom +AgileAllMile +AgileFlea53 +AgileLlama +AgileRj +Agilities +Agility +Agitare +Agmaur +Agnar472 +Agni +Agnoscere +Agnykai +Agoge +Agressie +Agroni +Agronox +Agronyss +Ags G Maul +Agsungg +Agua Diablo +Aguanator +Agv +AhaShakes +Ahab +Ahav +Ahegao +AhegaoShawty +AhegaoxDrool +Ahero Knitly +AhiPoke +Ahjin +Ahkscape +Ahkward +Ahlaundoh +Ahmishcyborg +Ahol +Ahoyhoy +Ahreams +Ahri babe +Ahriah +Ahrim Job420 +Ahrou +Ahvexx +Ai Haibara +Ai activated +Ai u +AiMienOortje +AiNebesvaik +AiXiao +Aiai8 +Aian +AiasIM +Aiayu +Aid12100 +Aidann +Aidens Iron +Aidios +Aife +Aigua +Aiii Guey +Aiikis0 +Aila +Aillwynd +Aimbot77 +Aimdur +AimenForFun +AimenForYou +Ain Zak +Aina Vapaa +Aintos +Ainu +Air Aaron +Air Bison +Air Cube +Air Hawkz +Air Nimbus +Air Up There +AirAction +AirRin +AirWindSurge +Airborne +Aircendition +Airexz +Airforcin +Airomatren +Aironmaen +Airorider1 +Airplanez +AirsickMold +Airskipper +Airstone +Airstrike +Airstrikes +Airwalk +Airwipp +Aishi owo +Aisyah +Aivery +Aiwe +Aixaa +Aixleft +Aiyaaaa +Aiyzer +Aizor +Aizzz +Aj Blitz +Ajamian +Ajarn +Ajaxius +Ajdj +Ajeh +Ajeti +Ajikk +Ajinz +Ajt141 +Ajushox +Ajuus +Ajx +Ak 4854 +Ak5u +Aka God +AkaSpecs +Akadian +Akagi +Akali +Akalron +Akarema +AkaseAkari +Akasha +Akashy +Akatsuki +Akaza +Akduman +Akeno +Akhasa +Akhavan +Akhotha +Akiha +Akihiko Main +Akilled +Akimbo Gmaul +Akira28 +Akirakiyomi +Akka Flakka +Akkaido +Akkezander27 +Akkhai +Akmore720 +Akn Magic +Akogare +Akolyta +Akomatic +Akomatk +Akowii +AkraLaDragon +Akropolis +Akshan +Aksu +Aksu596 +AksuRS +Aktii +Aktivaros +Aku Megami +AkumaPenguin +Akunte +Akushizu +Akusti +Akustic +Akvarij +Akyba +Akyle +Al Go Rhythm +Al e x x +Al ex G +Al-Kimiya +AlCaponee +AlFromOhio +AlIigator +AlMusallam95 +Alabandus +Alabarce +Aladfar +Alak4zam +Alakazoom +Alakazzaror +Alameda +Alamittainen +Alan +Alan200414 +Alandar +Alanowsky +Alantiwa +Alasse +Alaurise +AlbaisBack +Albananaa +Albanoi +Albatrossse +Albatrox +Albert 1888 +Albert Klett +AlbertaDean +AlbertasRec +Alberthorn +Alberto +Alberto P +Albertttt +AlbiBambi +Albin0z +Albinos10 +AlboBloodZ +Alboy +AlbusTheDood +Albuun +Alc1 +Alcadeias +Alcado +Alcarnia +Alcatres +Alcatrez +Alceini +Alcerathe +Alch O Holic +AlchKids4Gp +Alchaline +AlchedMyLife +AlchedMyM0M +AlchedMyNuts +AlchedYaNan +Alcheimers +Alchemical A +Alchemicc +Alchemisten +Alchemize +AlchemstDefi +Alchemyst +Alchhorn +Alchulon +Alckx +AlcoSkillz +Alcond +Alcool +Alcoz +Aldastro +Aldecaldos +AldenolcyCB +Aldi Knight +Aldit0r3 +Aldol +Alduiin +Aldwin Mose +Alec +Alec-kun +Aleck_l2 +Aleffy +Alegrete +AleizzleX +Alekja +Aleks +Aleksi +Aleksib +Aleliumbis +Alem +Alemao +Alenac +Aleous +Alerio +Alessan +AletosCR +Alex +Alex Blaze +Alex Cartman +Alex Grey +Alex IV +Alex Meret +Alex Power3 +Alex V2 +Alex Welshy +Alex Zander +Alex from IT +Alex the dad +Alex12161 +Alex3 +AlexDirty +AlexHill +AlexODaGreat +AlexSpkt +AlexV +Alexa +Alexander0k +Alexandre M +Alexbrave2 +Alexbrock +Alexis2Pro +Alexmeister +Alexnchill +Alexownsmatt +Alexr0 +Alexx +Alexx2G +Alexxandraa +AlexxisTexas +Alexzilla +Alf11 +AlfaAleksi +AlfaQ +Alfahane +Alfahanne +Alfication +Alfie 96 +Alfonga +Alfonso +AlfonsoKhan +AlfredTB +Alfrid +Alfuh +Algiebeer +Alharbi +Alhyrr +Ali Shuffle +AliThePvmer +Alibaba +Alicander +Alicc +Alice +Alice x +AliceOMalice +Alicent +Alicezero1 +Alicola +Alien +AlienAntFarm +AlienTTmilk +AlienVoucher +Alienmage +Aliens +Aliii33 +Alijr +AliksOh +Alioman +AlistarTb21 +Aliste +Alive Bozo +Alive Seb +Alive Vein +Alive18 +AlivenHappy +Alixz +Aljase +Alkan +Alkene +Alki Holic +Alkkor +Alkoholismi +Alkymo +Alkyne +All Blue +All Darn Day +All Fore One +All Frosty +All Peachy +All There +All a Bone +AllRubyMoi +AllThePain +AllTimeNo +AllYourBase +AllaBarri +Allabaster +Allan +Allan man +Allards +Allcreation +Allday +Alldays +Alldogg +AllegedTheif +AllegedTree +Allen +Allerb +AllesPaletti +Alleviate +AllexWx +Allext +Alligaattori +Alligamanor +Alligood +Allisun +Allkune +Allky +AlllySpawn +Allmethyst +Allo +Allomantic +Allon +Allonsmoke +Allowe +Allowed to +Allscreen4 +Allsen +AllstarTb21 +Alltiana +Alludo +AllusionTens +Ally +Alma +Almahh +Almighty +Almighty2277 +AlmightyMilo +AlmondJoy +AlmostHadMee +AlmostSavvy +Almost_124 +Almosttheir +Alno +Aloha +Alohas +Aloise +Aloittelija +Alondraj +Alone +Alone CRNA +Alone RS +AloneHeWalks +AlonelyPlace +Along +Alonzo520 +Alonzo52O +Aloqab +Alosthawaiin +Alov +Alow +Aloxc +Aloysius +Alozaps +Alpaca +Alpaca B0ng +Alpaca Lips +AlpacaMyBags +AlpacaMyBowl +Alpacaliptic +Alpedocles +Alpha +Alpha Cygni +AlphaCoderXI +AlphaFeeb +AlphaMathic +AlphaSeraph +Alpha_Scott +Alpharma +Alphonse +Alphray +AlphusBrah +Alpine Climb +Alpinetree +Alpoopi +Alppiruusu +Alprazoland +Already +Alright +Alright Mom +AlrightBucko +Alrite +Alry +Alsatian +Alsatians +Also +Also Jack +Also Luci +Also Lucky +Also Nexxtar +Also Noexi +Also Schlak +Also kawkky +AlsoAlso +AlsoRabbit +Alst +Alston +Alt Ctrl +Alt G boys +Alt Juana +Alt Redshok +Alt prepot +Alt3rbridg3 +AltOclock +AltSkillsDoe +Altairre +Altamonte +Altchilly100 +Altcliffe +Altdunk +Altemeier +Altenan +Alter +Alteraga +Alternate +AlternateArt +Alternatee +Alterones +Althamen +Althornson +Altifueled +AltimateRalf +Alting +Altkandos +Altnik +Altonorin +Altruistic +Altus +Alty2 +Alucks +Aluspalvelu +Alvaaro +Alvarreth +Alveoli +Alvislt +Alvx +Always +Always Alex +Always Awake +Always Harm +Always Late0 +AlwaysByrnes +AlwaysDNS +AlwaysLost +AlwaysPoor +AlwaysQuest +AlwaysSunny +Alwayscuffed +AlwayzJarvin +AlwayzSol +Alwex123321 +Alwin S +Alxs +Alyks +Alysanne +Alyv +Alzad +Alzuraak +Alzz +Am eer +Am ity +Am ln Danger +AmCatWhatDo +Ama zon +AmaAvenger +Amadeux +Amaiya +Amak +Amalie +Amanda +Amanda Btw +Amandelbrod +Amarantine +Amarok Moon +Amasclit +Amateur +Amathyn +Amatsukaze +Amatus +Amazarashi +Amazaro +Amazing +Amazon Power +Amazonia +Amb3rLeaf +AmberTheCat +Ambik +Ambion +Ambipom +Ambisagrus +Ambition IRL +Ambition98 +Ambitioned +Ambrose34 +Amcaroz +AmcyC37 +Amd27 +Ame Hara +AmeJoyRock +Amean +Ameero7 +Amel +Amelia Beth +Amen +Amend +Amenity +Ameno l +Americlaps +AmiableDingo +Amibis +Amida +Amigeau +Amigo +Amigos +Amillie +Amin +Amir Psycho +Amis +Amitwin +Amityz +AmixBeast +Amjad +Amjar +Amka0s +Amkings +Amlodipinee +Ammastian +Amnesiia +Amnios +AmoMeuFilho +Amoei +Amon Amarth +Among Dead +AmongUs R34 +Amongst It +Amordrise +Amos1500 +Amper +Amperes Law +Ampiainen +Ampilify +Ample +Amplify +Ampura +Amsclarke +Amsterdamage +Amty +Amused Fonty +Amuzements +Amuzzr +Amuzzzr +Amy Sonck +AmyMacdonald +Amygdala +Amylit +Amyshaw123 +An Amputee +An Animal +An Ebony BBW +An Old Chum +An epic OAP +An old Gnome +An0mandaris +An0niminis +An6ers +AnActualHorn +AnAmerican +AnEnginerd +AnEpicWookie +AnEskimo +AnExperiment +AnEyeOhLate +AnOldTank +Ana D Armas +AnaWynn +Anabella28 +Anabolic +Anabolic h1t +Anabowlen +AnaklusmosAN +Anao +Anaphylaxiss +Anarchy +Anarchy870 +AnarchyOS +Anari +AnataNoWaifu +Anbu +Anbu_Mobb +AncIrew +Ancalagon +Ancastry +AnchorMann +Ancient +Ancient Fury +Ancient fir +Ancient hil +Ancient soul +AncientFreak +AncientLamb6 +AncientMagus +AncientOath +AncientP +Ancientgh0st +Anciento +Ancientz pal +Ancitif +Ancona +Ancow +And e +And r ew +AndSo +AndYetISmile +Andardenn +Ander5 +Anderave +Andericus +Anders375 +AndersenXo +Anderssen +Andhra +AndiCandy +AndiVT +Andiamo98 +Andipyrus +Andirath +Anditre +Andj +Andoyen +Andrade149 +AndreasBL5 +Andremagico7 +AndresVZLA +Andrethyst +Andrew +Andrew Marr +Andrew OG +AndrewWigins +Andrewjaay +AndrewsMeat +Andrezee +Andrezz +Andri02 +Andrian +Andrick +Andrishh +Andrius X +AndriusBykas +Androgenic +Android Iron +AndroidFox +Andromed1k +Andsaca +Andx +Andy +Andy Candy +Andy Ops +Andy Salrem +Andy btw +Andy2 +Andy2511 +Andy43229 +AndyG223 +AndyIsComing +AndyL +AndyMcbob4 +Andydiaz +Andyfromvent +Andyn9 +Andyooi +Andyvns +Anele Boy +Aneluy +AnemicIzzy +Anesics +Anetha +Aneurin +Anez +Ang3li +Angalad +Angel +Angel Advise +Angel Allie +Angel Gabe +Angel Martyr +Angel Vlad +Angel4killin +Angel5 +AngelOfZeal +AngelOrHour +Angelic Lust +AngelicOrb +AngelicVixen +Angelisimo +Angell SL +AngelsCrys +Anger +Angerfish208 +Anghelic One +Angie Bos +Angl 0f War +Anglerstein +AngloSamson +Angoose +Angry +Angry Bison1 +Angry Child +Angry Thumb +AngryHusky24 +AngryMvP +AngryNachos +AngryPickle +AngryScape +AngryWizard +Angsti +AngusM +AnhTaDuong +Anhedoniaa +Anid +Anida Hanjab +Anidien +Anieli +Aniheyu +Anim +Anima +Animal +Animal feces +Animalia +Animation +Animations +Anime +Anime Nips +AnimeExpert +AnimeMilkers +AnimeWaifus +Animorph +Animos +Animosity +Anion +Aniril x +Anita Dong +Anita M Wynn +AniviaKush +Aniwave +Anja +Anja Rubik +AnjaPija +Anjigami +Anjru +AnkaraAisa +Ankedia +Ankka51 +Ankn +Ankou btw +AnkouClothes +Ankougnu +Ankourule243 +Anlaku +Anlex +Anmah +Anmokyu +Anna Huikka +Anna Liebert +Anna Planks +Anna Rosanna +Annavvaa +Anne Puppy +AnneWB +Annero +Annhilate0 +Annihilated +Annihilation +Annihilative +Annna Puu +Annoys +Anoie +AnomalousFox +Anon E Maus +AnonDoctore +Anonim +Anons +Anonymiity +Anonymous aF +Anonymousse +Anoobass1 +Anooge +Anoomliebird +Anor +Anotha Skar +Another +Another Name +AnotherCsTa +AnotherDoor +AnotherGamer +AnotherName +AnotherPb +Anouar +Anoubis +Ansaittu +Anscombe +AnselAdams +Ansoil +Ansovs +Ansuz +Ant M8 +Ant a +AntRIP +Antartsant12 +Antast +Ante +Antee294 +Antelope123 +Antex +Anth x +Anth52 +Anthiex +Anthilll +Anthony +Anthony Btw +Anthony I +Anthony5002 +Anthoons +Anthooony +Anthorak +Anti +Anti Drop +Anti PK G0D +Anti002 +AntiFuh +AntiVaxMothr +Antidope +Antifa4figs +Antifire +Antiflag42 +Antiguy24 +Antinyte +Antipathic +Antipixel +AntiqueRS +Antiqxx +Antireflex +Antis +Antiserum420 +Antixan +Antiyano +Antlers +Antmix +Anto +Anton +Anton T +Antonio +Antonn +Antony +Antony1202 +Antony142pay +Antoun +Antracid +Antron +Antstolis +Anttila +Antweezy +Antz Xii +AnuBi 1337 +Anub1s +Anubis +Anubis ex +AnubisT3 +Anuj +Anul +AnullSecs +Anv1k +Anve +Anxi +Anxiety +AnxietyBTW +Anxious +Anxious Mess +AnxiousDoggy +AnyDrops +AnyLesS +AnyQuestions +AnyScrolls +Anze +AnzheliK +Anzie +Anzied +Anzu +Anzypoo +AoA Jammer +AobaJohsai +Aog +Aoh +Aohc +Aohu +Aoi Tetsu +Aokijahr +Aokijii +AonEne +Aonyx +AoooA +Aorpheat +Aosrs +Aowi +Aozaa +Ap0logy +Ap0phis +Ap3x +Ap870 +ApRoMn +Apaat +Apaatje +Apache +Apache30 +Aparlo +ApartAbyss +Apathetik +ApdoJ +Apdomine +Ape Cape +Ape Dos Mil +ApeAtoll +Apetamer +ApetimusPrym +Apex +Apex Pro +Apex-scaper +ApexGT +Apexflashy +Apexist +Apgujeong +Apherna +Aphex +Aphroditeee +Apimer +Apinamies +Apldale +Apm90x +Apoc +Apoc142 +Apocriya +Apocryphe +Apolliox +Apollo Beach +Apollo13th +Apolytos +Apop +Apophiss +Apor +Apostasie +Apotoxin +App3lflap +AppaYipYip +Apparat +Apparitionn +Appeasive +Appel Farm +Applauder +Apple +Apple A Day +Apple Mart +AppleBluue +Appleboss +Applecus +Applejuiceaj +Applemaxx +Applev2 +Applied +Applul +Apportant +Apprenti1 +ApprenticeRS +Approval +ApprovuL +AppySauce4 +Apqle +Aprella +April +April 8 1997 +April twenty +Aproximity +Apsa Larr +Apteryx +Apteryx luna +ApuHapu +Apul +Apullu +Apyon +Aqew +Aqizu +Aqtive +AquaUnit +Aquah +Aquaileo +Aquajd +Aqualetics +Aquamation +Aquamentus9 +Aquascaped +Aquaticbob +Aquatik +Aquellex +Aqueueser +AquiIa +Aquilo +Aqva Babe +Ar ex +ArA100 +ArKadeeee +Arab Frieza +Arabian +Arada +Araet +Aragonx +Aragornmv +Aragornous +Aramaki +Araman +Aramex +Arandae +Aranna +Aranruth +Araq +Araqon +Arasex +Arashikato +Arastaiel +Arathir +Araur +Aravt +Araysen +Arazz +Arb4n +Arbator +Arbenn +Arbin +Arbyy +Arc1s +Arcade firee +Arcadian96 +Arcane +Arcane Grima +Arcane Queen +ArcaneApollo +ArcaneBear +Arcanezeus +Arcangel +Arcangel IX +Arcanic +Arcanox Sad +Arcanum XIII +Arcas3 +Arced RS +Arceneus +Arch +Arch RS +Arch er +Arch3nLight +ArchFarmer +ArchX +Archaea582 +Archahl +Archaic Wolf +Archaiden199 +Archanjel +Archas +Archavia +ArchbishopC +Archduke Btw +Archelon +Archer +ArcherYew +Archie +Archizel +Archon +ArchonArchy +Arcinton +ArckenSphere +Arclight +Arcnan +Arctic +Arctic Roach +Arctic Vaggy +ArcticCamel +ArcticMank +ArcticTitan +Arcticas +Arcticchill +Arcty +Arda +Ardaddy +Ardames +ArdenDZY +ArdestRange +Ardilos +Ardougn e +Arduino69 +ArdumTheMain +Ardumm +Ardy +Are Dry +Are ng +Are you well +AreYouMyMumm +AreYouPepega +Area +Areimer0606 +Arekusei +Arena +ArenaRebuild +Arend Nest +AreolaArnold +Areolas +Areoloth +Areow +Ares +Ares 3060 +Ares1701 +AresArmy +AresKnight +Arescoth +Aretx +Arezrazer +Arfex +Arga +Argawan +Argent +Arghoslent +Argilla +Argo Vesta +Argonuts +Argory +Argov +Argyle Sock +Argyle Socks +ArgyleGrandt +Arhedel +Ari +AriSlash +Aria +ArianDRZ +Ariana +Arias star +Ariazel +Arid +ArieMoon +AriesWarrior +ArieyaeIron +Arifureta +Arigorn +Arigorn55 +Arihant +Arillian +Aris +Arisen I +Aristo +Aristokratas +Arisu +Arith1um +Arithe +Arizotal +Arjoon +Ark9tog +ArkAngel029 +Arka91 +Arkaniz +Arkantos51 +Arkaros +Arkavos +Arkaynine +Arkeela +Arkells +Arkem +Arkemir +Arkend +Arketryx +Arkevin +Arkhero +Arkizah +Arkki +Arkonka1 +Arkonknight +Arkvasal +Arkysh +Arlind +ArloTheBrave +Arlorict +Arlyeaxn +Arlyse +Arm Chair +Arm Guy +Arma Frost +Armadexx +Armado +Armadomin +Armadyl king +ArmadylPker +Armadyllo +Armament +Armanyte +Armapickle +Armas Chosen +Armchairs +Armerak +Arminius Sol +ArmisticeDay +Armo +ArmoBlood +ArmoMike +Armoah +Armondega +ArmorHelmet3 +ArmorSeeds +Armourer +Armsdray +Armweak55 +Armysam +Arna +Arndas +Arnear +Arnhems +Arnie +Arnold +Arnor +Arnthor +Arntj +Arobpl +Arod +Arodaz +Aromipesa +Aron +Aronya +Aroorin +Arousen +Arousin +Aroyu +Arpang +Arpegio +Arptacular +Arr n Geesus +Arrandarls +Arrasca +Arrazha +Arre10 +Arrizu +ArrowHaste +ArrowTank +Arrowmind +Arrows Myth +Arrowtower +Ars Nova +Arsaydar +Arsenals +Arsene rar +Arsenic +ArsenicEyes +Arsenn +Arshal +Arsi +Arslen +Arson +ArsonScape +Arst +Arstan Selmy +Art Dayne +Art Star +ArtIsHard +ArtStylerzz +Artces +Artegal +Artenmis +Artesna +Artezor +Artful Dodgr +Arthaniel +Arthesus +Arthropods +Arthur +Arthven +Artic0 +Articuno1991 +Artidote +Artillion1 +Artipeng +Artisaani +Arto Lauri +ArtofKush +ArtoriaSiff +Artoriias28 +Arts +Artu12v +Arturis +Artychurro +Artz +Aru +Arumen +Arunas +Arusas +Aruwyn_Xi +Arve +Arvinthir +Arviragus +Arvns +Arvsta Won +Arvx +Arwe +Arwon +Arxanec +Arya +Aryabhata +Aryuts +Aryzha +Arzemnieks +Arzi +Arzna +AsalentBlaze +Asami +Asami Sato +Asap +AsapLamb +Asbi +Asbloodfalls +Asbur +Ascadex +Ascanliss +Ascended +Aschen +Ascii You +Asda +Asdasd107 +Asdewq +Ase +Aseae +Ased +Asfixiator +Ash K +Ash Solo +Ash Wreckum +Ash l +AshBash +AshEvillDead +AshKetchum00 +AshLad94 +Ashabee +Ashandarei0 +Ashcroft +Ashealia +Ashen +Ashen Bride +Ashen Heart +Ashen One +AshenSughar +AsherMentuI +Ashes +Ashes630 +Asheviere +Asheville +Ashhh +Ashieboyyy +Ashikaru38 +Ashington +Ashkelmek +Ashkii +Ashkyn +Ashleigh +Ashley +AshleyNZ +Ashleyi +Ashlyce +Ashmeow +Ashn +Ashoo +Ashsole +Ashton +Ashura Bakke +Ashwin09 +Ashy joey +AshyKneecapz +Ashyy +Asian +AsianGrinder +Asics +Ask Oziach +AskMeDolCare +Askraf +Askumi +AslanMaximus +Aslywyn +Asmir9990 +Asorf +Asos +Asot +Aspen +Asper +Aspestia +Asphyi +Asphyi Xate +Ass Balm +Ass Clams +Ass Drill +Ass Rocker +Ass locator +AssClapping +AssMcButt +Assasindie73 +Assasintoad +Assassinado +Assaulted +Asshats R Us +Assktchum +Asstain +Ast 360 +Astan +Astaro +Astartes +AstartesXIII +AsterSG +Asterlad +Asterlyte +Asterus +Astiminate +Astoia +Aston Fartin +AstraDan93 +Astraea +Astral Queen +Astral laws +Astrali +Astrals +Astray +Astrayus +Astro +Astro Dust +Astro O7 +AstroKP +AstroXgK +AstroYogurt +Astroflare +Astronaut Al +AstrooWRLD +Astrophe +Astrostone +Astylez +Asubu +AsuhDude +Asuka +AsukaLangely +AsukaYenOSRS +Asukas +Asumaton +Asumistuki +Asuna +Asunnn +Asura +Asus bl +AsylumTRAV +Asymmetry +Asyn +Asynergy +Aszalem +Aszard +Aszension +At0mic +Atacrite +Atar +Ataraxia +Ateo +AthIetic +Athaw +Athe na +Athedeia +Athena +AthenaOfOsrs +Athenaloki +Athi +Athire +Athius +Atika +Atilio +Atin +Ativan IM +Atlamillian +Atlantic +AtlasErol +AtlasUsurper +Atlashi +Atleast +Atli567 +Atmosfare +Ato m +Atolla +Atolli +Atom +Atomic +AtomicFlux +Atomicdomb2 +Atomikaust +Atomsk +Atomyze +Atonic +Atorvastatin +Atouk +Atoxicary +Atoz +Atriades +AtriummDream +Atrixas +Atro phy +Atroo +Atroph +AttackMoons +Attard +AttemptedUwU +Attic +Attic Ghost +Attic Witch +Attics +Attikos +Atton +Attuned +Atuking +Atvinnulaus +Atylos +Atza +Au 0srs +Au 1 +Au Bar +Au Barrett +Au Joel +Au Shooty +Au92 +AuRoyce +AuStarZ +Aubrey +Aubrey UIM +AubsG +Auburn Lax +Aubzzz +Auclaw +Auctionable +Aud +AudacityOP +Auddax +Audi +Audi Nurse +Audi Reach +Audo +Audronan +Audtnec +Audylinks +Augment +AugstBrnsRed +Augurk +Augury Tank +August +AugustAmes +Augustiner16 +Augutis +Auhdy +Auja3 +AuksoAlt +Aulono +Aumoki +Aunonen +Aunt Wu +Auntie +Auntie Mabel +AuraBeast +AuraSissari +Aurah +Aurelia +AurelionROW +AurelionVM +Aurelya +Aureou +Aurgodi +AuriZed +Auriana +Aurionx +Aurizon +Aurorin +Aurrok +Aurtle +AurumFoxfire +Auryn +Aus +Aus 2277 +Aus Shizam +AusBruto +AusGram +Ause +AusieBumpkin +Ausripper +Aussie +Aussie Jay +Aussie Luke +AussieKunt +AussieOandE +AussieSparta +Aussome +Aussybear +Aust Terps +Austie +Austiiizy +Austin +Austin Ames +Austin is 1 +Austin296 +Austiz +AustlnPowers +Australia +Australians +Australiaz +AustrianOak +Austs +Austyn +Autchin +Authorized +Authorizer +Autickstic +Autilon +Autism +AutismeKnaap +Autist +Autistic +AutisticAndy +Auto Tuned +AutoBonsai +AutoEmp +AutoLoot EXE +Autoacid +AutomailArm +Automonteur +Autophagy +Autorotate +Auts Man +Autumn +AutumnKevegy +Autzerk +Auuustin +Auuuv +AuzReaper13 +Auzium +Av o +Av3z Str +AvC OSRS +Ava End +Avaetar +Avaigo +Avatar +Avatar Evan +Avatar Magni +AvatarBean69 +AvatarShakur +Avedon +Aveng +Avengerous +Aventy +Aver4ge +Average +AverageDesk2 +AverageDink +AverageJoe29 +Averex +Avernic +Avero +Avertehs +Avest09 +AvestGIM +Avex +Avexaon +Avfc Holte +Avg Tom +AvgMG +AvgScape +Aviaatar +Avian +AvidTech +Aviiation +Aviion +Avinosis +Avir +Aviron +Avlek +Avocatocat +Avoidable +Avoinmieli +Avonak +Avondale +Avouch +Avrahm +Avsendesora +Avysto +Avze +Awadi69 +Awaiting +Awaiting 126 +Awaits +Awaiyume +Awakened Olm +Awarde +AweJeez +Awendana +Awesome +AwesomeBros +AwesomeJared +Awezm +Awful +Awful Name +Awfully +Awh DB +Awh Nuggets +Awies +Awilkins4231 +Awkquavian +Awkventurer3 +Awkward +Awowegei +Awowo Gay +Awry +Awtangg +AwwSeriously +Awwdiddums +Awwtis +Awyr +Ax3 +Axayre +Axdrew +Axely +AxemPink +Axeo +Axhers +Axies +Axillaa +AximusMax +Axiom +Axlerod +Axleson +Axodyi +Axolotl +Axsentz +Axton +Axylix +Ay Monk +Ay Ron Man +Ay3m +AyAyRon +AyB33 +AyJae +Ayafuyuzu +AyameDespair +Ayatan +Aybills +Ayd +Aye Sip +AyeBaddaBing +AyeePizza +Ayeeet +Ayema IM +Ayenull +Ayetg +Ayfi +Aylia +Aylward +Ayman +Ayo4Yayo +AyoSteeze +Ayoe +Ayonikz +Ayra +Ayri +Ayrton +Aysuu +Ayveros +Ayy Nakana +Ayy bae bae +Ayy q p +Ayyye +Ayyyon +Ayzo +Az PVM +Aza zel +Azad +Azad Kashmir +Azala +Azami +Azandari +Azathor +Azathoth26 +Azathrir +Azazel OSRS +Azeenil +Azemu +Azerma +Azez +Azimut +Azimuthaal +Aziz +Aziz7 +Azkaton +Azken +Azkybot +Azlo +Azmataz +Aznbabe +Aznmixboy +Azom +AzorAhaiBTW +Azotize +Azoxy +Azpa +AzraelReaper +Azriiele +Azryel +Azs +Azshara +AztecLT +Aztra +Azula +Azula Whip +Azur Lane +Azur_I +Azure +Azure23782 +AzureSpirit +Azuredadi +Azuremadi +Azuretiger +Azuuure +Azynn +Azyrith +Azza Bear +Azzaar +Azzaboy100 +Azzakel +Azzanadra +Azzanadraa +Azzax +Azzgarnia +Azzz +B 0 B S +B 0 S S +B 0 U J E E +B 3R +B 58 +B A F F E Y +B A MF +B A U W S +B B Bouncy +B C 2 +B C M +B CA +B D Y +B E E G +B E R T A +B E R t I 3 +B ELA +B Gates +B Gonkeybron +B I G G L E +B I R T +B Ian +B J O R N +B L 4 N K +B L A D E Z +B L A N E +B L A Y E D +B L ANK +B L I X T +B Milesy +B Minor +B O G S +B O O T H +B O Y E A +B R A l N +B R II A N +B R l C E +B S +B SlDE +B T J +B Victor B +B W 1 +B W A K +B aylor +B aze +B ecky +B eeez +B iggles +B la z e +B las +B r a g g +B r eezy +B rads +B raes i +B ruised Lee +B u bs +B ug +B un +B utt +B w +B-0-SS-M-A-N +B-Dollaz +B-Lal +B00 KAW KEY +B00Lici0us +B00MERAT3R +B00ST +B00SY +B00tlicker +B0ARD +B0B The Cat +B0BaH +B0GLA +B0ND +B0NERCRUSHER +B0NGRIPS42O +B0OP +B0aty +B0atyquila +B0bz BurGerz +B0dka +B0n3z84 +B0nes2Weed +B0rders +B0rn +B0rn2bking +B0rnas +B0tched +B14cksh4d0w +B1G BAD CHAD +B1G8 +B1GARMS +B1GBOB +B1GGY +B1G_D1ESEL +B1G_SW1GS +B1RDUP +B1Te Me +B1ack Lotus +B1ackJack +B1asphemy +B1gTTgothGF +B1gd0wg +B1ink +B1mboBambi +B1zrme +B2AD +B2F +B2J3 +B2bZeroSpecs +B2rad +B3A5T +B3CK +B3NJAMOON +B3NT D0ver +B3TTERLUCK +B3Y0ND +B3njamima +B3njamin +B3nny Blanco +B46 +B4RR +B4S +B4llista +B6a +B6i +B70 +B747B +B8 H8ER +BACKURBOI +BACONisgd4me +BADASS +BADDONE +BADPanda2 +BADUPDATES +BAKED +BALD n DUMB +BAMF +BAMFnificent +BARBARlANS +BARRAGENOW +BARRON24 +BASED DMM +BASEDQwert +BATATUNGA +BATH0RY +BAYLlFE +BBBBBONKA +BBGL +BBK +BBKwenie +BBL RIZZY +BBQs +BBW Pizza +BBarnzeyy +BBeepLettuce +BBoys Father +BCBDestroyer +BCC YT +BCDOJRP +BCK CigButts +BCMagoo +BDCMatt +BDrichard +BEANS9991119 +BEARDED +BEAST ARCHER +BEATONiT +BEBELAC28 +BEEA +BEG0N +BEG0NE +BEINGMAXDSUX +BELSJ +BEMBOU +BEST +BET5 +BEYFYBOI +BFKay +BHAFC +BIG ASHL3Y +BIG C0X LUVR +BIG HIT GOOD +BIG pontifex +BIGBADWILLY +BIGD05 +BIGDROPHUNTR +BIGFERGLOAD +BIGHEADSMASH +BIGJP +BIGMINK +BIGSITUATI0N +BIKlIllIlIIE +BILR0Y +BIOATED +BIRD SHlT +BIRP +BIRWAAA +BIS Monster +BIaded +BIadet +BIapa +BIood Prince +BJ Applegate +BJ M +BJPlaysRS +BKBB +BKK +BKLN +BL00DANG3L +BL33DPL34S3 +BL3SS3D4LIFE +BLACK DOG NI +BLASE +BLGesus +BLICKYSTIFFI +BLOBi WRX +BLOOD +BLUEPIZZAMAN +BLXCKPINK +BLYATMOTOR +BLlNKY +BMEUR +BMooldijk +BMrgn +BO0MERSO0NER +BOA Liger +BOBGIGALUCKY +BOBYAHMDGECI +BOER KAMIEL +BOGOBoneless +BOL0CKS +BOLSOONARO +BOMBAKLAP +BOMBU +BONITA 02 +BOOPlNG +BOOTTYBANDIT +BORDEN DAIRY +BOSNIAQUE +BOSS +BOSS OG +BOSSMANHOG +BOlNEXTDOOR +BPNS Hawk +BPTheIronOne +BPrimitive +BR0 BRO +BR00KES +BR0CE +BR0ER +BR0THERS +BR3AKABLE +BRA71L +BRACULA +BRAMMOSOVIC +BRANDONSMlTH +BRCH4 +BREJCHA +BRUTAL +BRabbit25 +BRlOCHE +BSB Howie +BSNR +BST Steve +BSickler +BSven-B +BTCEUR +BTKMGJKL +BTMillz +BTW Beirre +BTW idgaf +BTW vs RNG +BTWSaberlion +BTWsanta +BU1MER +BUHLL +BUILD +BUILD PONYS +BULLlSH +BUNDHA +BUNStheGOD +BUR13D AL1VE +BURYT0MORROW +BUSS IT +BUTTB0NERED +BUTTCOlN +BV Martyr +BWheatZ +BYEq +BYOBOOZE114 +Ba1i +Ba5b0y +Ba6y +Ba77erY +Baa m +Baaaats +Baal157 +BaalZvuv +Baals +Baalthas +Baamf +Baami +Baandos +Baarb Lahey +Baas +Baba +Baba Booey9 +Baba Borgar +BabaLovesKos +BabaSlaaf +BabaSleep +BabaTarzan +Babafasa +Babayaga-9 +Babayaga2121 +Baberrandrid +Babica Mraz +Babiez +Babocat +Baboosh +Babs221 +BabsCox +Baby +Baby Bear +Baby Bobby +Baby Boeing +Baby Daphne +Baby Houdini +Baby Motel +Baby1400 +BabyB +BabyDogeCoin +BabyDogeFTW +BabyGroot +BabyHat +BabyHewy +BabyHiggy +BabyJIREN +BabyLinga +BabyPandaa3 +BabySas +BabyTamer +Babycerasaux +Babydump +BabyfaceBill +Babyjoker828 +Bac0n +BaccaM +Bachelour +Bachuras17 +Bachus67 +Back +Back Jauer +Back Seater +Back2Backk +Back2ourdays +BackInTime +BackToBambi +BackToOwn +BackelsOSRS +Backinthe09RS +Backlit +Backspace +Backsterr +Backus +Baco +Bacodie +Bacoid1 +Bacon +Bacon Glizzy +Bacon24717 +BaconBlunts +Baconcannon +Baconist +Baconlord100 +Baconpancake +Baconstrike +Bacteria +Bactomet +Bacun +Bad Advice +Bad Ape +Bad Axe +Bad Day +Bad Fruits +Bad Kind +Bad Kuip +Bad Mario +Bad McNamey +Bad Mistake +Bad Name Now +Bad Robert +Bad Weather +Bad exp +Bad2dabone30 +BadAndB0ujee +BadAss_oO +BadChicken +BadChronic +BadDecision +BadIdeaDog +BadIllusions +BadInIronMan +BadInNames +BadMamaJama +BadMannerz +BadSass +BadSpalling +Badaping +Badass +Badass Fe +Badass Iron +Badass Rs +BadassIron +BadassPotato +Badasseness +Badaxx +BaddieDragon +Badgalriri +Badger Bush +BadgerInABag +Badgerq97 +Badical +Badman +Badman ET +Badoodle +Badora +Badora II +Baduk +Badvask +Bae-Kun8er +Baeby +Baekah +Bag it +Bag of Yay +BagFryLife +Bagadigi +Bagan +Bageera +BagelSpanker +Bagels +Baggyshaw +Baghdad +Baginga +Bagis +Bagokk +Bags +Bags n Beer +Bagsnacks +Bagz +BahRitTanEe4 +BahamutLimit +Bahn +Bahnzeen +Bahp +Bai Ningyang +Baib +Bail Jait +Baileys +Bailsby +Bailz +Baimonnnn +Baines +Baino +BainoLad +Bainz +Bairac +Baites +Baja Baja +Bajan +Bajart +Bajcolado +Bajela +Bajere +Bajhole +Bajista +Bajji +Bajkami +Bajsanus +Baju +Bak cornet +BakIron +Baka Mop +Baka Prase +BakaOsaka +BakaPho +Bakazuro +Baked +Baked Mage +Baked Saiyan +BakedVandon +Baked_Beagle +Bakedd +Bakedmuffins +BakeonBits +Baker Bully +Bakerloo +Bakers Baked +Baketto +Bakhmut +Baki Hanma +Bakingsodah +Bakingsweets +Bakkis +Bakllava +Bakron +Bakthawar +Baku +Bakuchiol +Bakusho +Bakuthedrunk +BalIsackt1ts +Baladend +Balan +Balan Dinh +Balar +Balarezo +BalazinGIM +Balboa Park +Balbuli +Bald +Bald Arab +Bald Male +Bald Shupa +Bald Sicknez +Bald To Bold +Bald Wookiee +Bald at 29 +BaldKnees +BaldMansKenn +Baldfuc +BaldheadBill +Baldoc +Baldorr +Baldrake +Baldras +Balerion +Baliboosca +Balkan +Balkenende +Ball +BallOfCotton +Balla +Ballack342 +Ballade No 3 +Ballcheck369 +Ballenaso +Baller006 +Ballerina +Ballesekk +Ballet +BallinBamf +Ballotaa +Ballroom +Bally +Ballztacular +Ballzy +Balmung311 +Balneum Anas +Balob +Balontra +Balou +Balrogs Hell +Balthazar BL +Baltimohr +Baltimore MD +Baltoth +Baltramiejus +Baltzerboii +Balu +Balu Titan +Baluk +Bam Achilles +Bam Grizz +Bambi0326 +BambiSlayer +Bamboo +Bamboo James +BambooPandas +Bambuliuss +Bamf +BamfJoe +Bamfbeav +Bamiman +Bamse +Bamztile +Banan +Banefish +Banerz +Banio +Bank Stander +Bankaiz +Banki 1 1 +Banzu +Bape +BapeNation +Bapelsin +BaphometsLov +Baptor +Baqels +BarShake +BarSmash +Baraek +Barakoli +Baratheon +Barathrum +BarbaariJuho +Barbatos +Barbose +Barbwiire +Barbyte97 +Barca +Barca230492 +Barcodes +Barcoding +Barcy +Bardimuss +BardleDooDoo +Bare +Barely High +Barely Legal +BarelyBusy +BarelyDecent +Barfallonyou +Barfs +Barfy +Bargli +Barhoor +Bariviera49 +Bark sample +Barkki +BarnVo +Barncle Boy +Barneey +Barnet Ftw +Barney12370 +BarneyKing +Barneylover +Barnez10 +Barnyard Boy +Barnz +BaroBro +Barometz +Baron +Baron Iron +Baron Timmy +BaronConey +BaronGiraffe +BaronVonGeeb +Baroondon +Barqueefa +Barr +BarracuDro +Barraggah +Barrako +Barrel Flop +Barricade +Barrowry +Barry +Barry Koota +Barry0408 +BarryBanaan +BarsasBoom +Barstukas +Bart +Bart Heredit +BartBelly +BartSimps +BartenderBTW +Bartheez +Bartholomeii +Bartje +Bartol +Bartycool +Barzhal +Bas +Bas Waterpas +Bas481 +Basant +Base +Base 99s +Base Skills +Based +Based Evan +Based Kyoko +Based Miyagi +BasedGob +BasedHeru +BasedScape +Basement Dad +Baseplate86 +Bash +BashinBosses +BashiraTHC +Bashram2 +Bashx +Basic +Basic Drop +BasicBilbo +BasicIronman +Basil +Basil Hiiri +Basileia +Basilikos12 +Baska +Baskervilla +Basket +Basketballer +Baskie +Baskrans +Basmah +Bassaidai2 +Bassey +Basshu Fon +Basshunter +Bassilliaux +Basstomouth +BastasRemmen +Bastermate +Bastiao +Bastidaz +Bastin101 +Baszist +Bat Fastard +Bat Kills +Bat418 +BatChatillon +BatFat +Batbot101 +Bateau +BatedUrGonna +Batesanator +Batgirl +Batin +Batistaisraw +Batleris +Batmain +Batmam +Batman +Batmanlul +Bats +BatsVsChina +Batsborkair +Batsmattie +BattDoode +Batter +Batter Cake +Battle Jack +Battousai +Battousai09 +Batu +Batussy +Batzch +Batzz +Bauchop +Baulsacky +Bautista I +Bav +Bavaria +Bawdlands +Bawjaws +Bawn +Bawwz DeadAf +Bawz +Bax2 +Baxi 247 +Baxxis +Bay +BaySeoul +BayaniSenpai +Bayern_pvm1 +Bayes +Baykr +Bayle Domon +Bayleef180 +Baylin +Baylon +Baylon rs +BaylyBoyBro +Bayman +Bayou Bengal +Bayside +Baza +Baza NZ +Bazilijus +Bazimga +Bazmobile +Bazoo415 +Bazoomaster +Bazope +Bazukashrimp +Bazz0r +Bazzak +BazzleB +BazzleBTW +Bazzooi +BbDontHurtMe +Bbase12 +Bbaws +Bboygainz +Bbubbsy +BcShane +Bcgod +BchImaBus +BckOFFRTRD +BckScratcher +Bcowzy +Bdawg +Bdub187 +Be Aware +Be Rad +Be Strong +Be X Unlucky +Be as t +BeEzyMan2 +BeFawn +BeThankfulll +BeTy +BeaTee +Beaan +Beak er +Beaken +Beaky +Beamesy77 +Beaming +Beamo +Beams btw +Bean +Bean Bunn +Bean Slapper +Beanieus +Beanis +Beanisdead +BeanozZ +Beanpot +Beans1991 +Bear +Bear Downn +Bear Finale +Bear IV +Bear Jake +Bear Savage +Bear W Scarf +Bear0nBeer +Bear32 +BearByBlood +BearByte +BearDown80 +BearGrillz +BearImmunity +Bearac +Beardboy +Bearded +Bearded Hick +BeardedGummy +Beardedwick +Beardilizer +Bearing Down +Bearly Iron +Bearopenart +Bearrito42 +BearsBeetsBG +Bearsarefrie +Bearsfan5455 +Bearshot +Bearsome +BearsyXL +Beary +Beast +Beast Guard +Beast Things +Beast1Range1 +Beasted Main +Beastgriff +BeastieBoy31 +Beastied +Beastley +BeastlyGinge +BeastlyMuff +Beastman642 +BeastyY69 +Beat +Beat Tit +Beat my Wifi +BeatboxRS +Beatdown115 +BeaterGod +BeatmyJonson +Beatrix +Beatz +Beau +Beau Ryan +Beau1o +Beaukaki +Beautifull +Beaver +Beaver Booty +BeaverSweat +Beaverr +Beavers79 +Beavis 420 +Beavis825 +Bebbie +Bebe +BebeAtron +Bebexx +Bebo294 +BeboKAhnung +Beckerr +Beckovas +Beckyboo308 +Beckymikyu +Become +Becoming +Becton22 +Bed +BedByDaylite +BedForSale +Bedanc +Bedeh +Beden +Bedevil +Bedni1 +BedtimeHERO +Bedwoods +Bee Butts +Bee Keep +BeebeM +Beef +Beef Mince +Beef Squirt +BeefBottom +Beefense +Beefs +Beefy +Beefy Potato +Beefy Treat +Beefycopter +Beeg +Beeg splat +BeegeKhaos +Beeghs +Beeks +Beeky +Beeline +Beelzebubba +Beelzebubby5 +Been +Been Mobile +Been Poor +Beepern +Beer +Beer Diet +Beer Is Cool +Beer Pong +Beer Tankard +Beer gut Jim +Beer n Blow +BeerIsGood +Beerchamp1 +Beerfest +Beerhana +Beershits +Beersmack +Beerzinnss +Bees169 +Beest +Beestig +Beeswakka +BeetchAustin +BeetchJeemmy +Beetle +Beetus93 +BeeyondBeef +BefJekyll +Befkeuning +Before Snow +BeforeDeth +Befsnor Ben +Begani +Begave +Beget +Begin +Beginning +Beginnings +Beh +Behaarde lul +Behemoth +Behhnchod +Beholder24 +Beibs +Beidou +Beige Carpet +Beikengaut +Beikenost +BeirH +Beirreee +Beirut +BekanTering +Bekfist +Bekk +Bekkie +Bekske +Bekt +Bekutma +Bel Lando +Belaa +Belamylinds +Beleid +Belenthir +Belgarathion +BelgianBeast +Belgiium +Belgique +Beliefofmine +Belindaa +BellWoods +Bellatrix +BelleBeans +Bellebutties +Bellerin +Bellfontaine +Bellicus +BellsOfWar +Bellum50 +BellyEscobar +Bellzbellz +Belorca +Beloved +BelowAvrge +BelowMe +Belsassar +Belsey +Belsfyre +Belsyn +Belt +Belt vs Kids +Beluge +Belzebu +Belzeddarr +Bemerson +Bemke +Bempii +Bempire +Ben Babeslay +Ben Behling +Ben Bekkuman +Ben C H +Ben Jay +Ben Jones +Ben Kingsley +Ben Manolo +Ben Salden +Ben Standish +Ben di +Ben1kzeker +BenDjammin +BenDover321 +BenKuro +BenLevensMoe +BenQ Smasher +BenRobbo06 +BenShapirOwO +BenWithJam +Benarends +Benbooo +Benching +BendOverBabe +Bendak +Bendeguz +BenderBuilda +Bendigo +Bendigo Man +Bendo +Bendos Hilt +Bendude +Bendyruler +Bendzo +Benedict +Beneee +Benefitz +Beneh +Benelovent +BengtBreak +Bengtsson +Beni +Beni Siitoin +Benifax +Benifird +Benis Hammer +BenisTechTip +Benisbringer +Benja1666 +Benji +Benji Stax +Benji189 +Benjiii +Benllech +Benman +Benmiester44 +Benneta +Benni234 +Benni2345 +Bennie +Bennie Lam +Bennis +Bennny0_o +Benny Sins +Benny Stacks +Benny Yuh +Benny p mage +Benny1175 +BennyBeeee +BennyQ +Bennybooom +Bennyz +Benocotch +Benoid +Benononono +Benoragon +Benoxo +Benqqu +Benquad +Bens +BensBent +Bensmom7 +Bensos +Benstjohn +Bentso +Benvil +Benyy +Benza +Benzema1 +Benzine +Benzoed +Benzylll +Benzz +Beopia +Beozqt +BeppaPig +BeppsaN +Ber +Berada +Beralf +Bercuckle +Berd +BerettaM9A4 +Berettapwnge +BergJr +Bergheimen +Bergkamp +Bergr +Berk +Berkan +Berkis +Berkven +Bermaitha +Bermbommert +Bernache +Bernie Mac +Berno +BernyMadoff +Beroepskech +Berraok +BerrieFan +Berrr +Berry +Berry Carry +Berry Soap +BerryBus +BerryInBooty +Berrys +Berrzerk +Bersbillus +Berserk FTW +Bert Curtis +Bert NUFC +BertMacklin +Berta B0y +Bertie +Bertje +Bertow +BerttDog +Bervoets +Berzerking +Berzurkah +Bes +Besin +Besseggen +BesselJ +Bessone +Best +Best Kio1 +Best Lolz +Best Murmeli +Best Nher yh +Best Realtor +Best Whilbur +BestCat +BestDIzzyNA +BestFioraNA +BestHouse +BestInSloth +BestJester +BestMommyGF +BestSenpai +BestVersion +Bestia Solus +Besties +Bestkilnot +Bestoladec +Besty +Besynderligt +BethMeow +Bethany +Bethell +Bethevoid +Bethrezen +Betray +Betta1009 +BetterCookie +BettsISale1 +Bettuh +BeugLizard +Beuglord +Beugsmate +BeunDeHaas +Beunhaas053 +Bevaun +Bevelle +Bever Mama +BeverGT +BeverlyPils +Bevers +Beverst +Bevruchter +Bevvy +Bewaker +Bewq +Beyond +Beyond Max +Beyond Mind +BeyondKenzie +Beyond_blitz +Beyta +Bezbi +Bezdzwieczny +Bezeo +BezosTezos +Bferg3 +Bfh1master +Bfood +BgoinHAM +Bhaals Rage +Bhakli +Bhalobashi +Bhangre +Bhench0d +Bhillup +Bhongk +Bhoy +Bhrad +Bht +Bhuggy +Bi +BiBi +BiGtOkEsBrUh +BiZaAr3 +BiZaM +BiZoNaDe +BiasVariance +Bibbit7 +BibleThump +BibleTrump +Bic +Biccins +Bice Bucket +Bicep Peak +Bicep Smooch +Biceps Btw +Bicho +BichoFeote +Bichslap +BickyChicken +Bictim +Bid Whist +BidaFire +Biddah +Biddiss +Biden +Bidens Slow +Bidensity +Bideo_Gabes +BieBras +Biebje +Biebop +Bierliebe +BierryTaudet +Bierscape09 +Biffo89 +Biffsy +Bifking +Bifta89 +Big Armpit +Big Arms Ben +Big Ass Turd +Big Baby Boy +Big Bearius +Big Beets +Big Bennys +Big Binotte +Big Boi Ian +Big Boone +Big Brane +Big Bruno +Big Buffalo +Big Buzz OG +Big Bwana +Big C +Big C A S H +Big Calquat +Big Cat Fan +Big Chest +Big Chugger +Big Crafter2 +Big Cypress +Big D Brasco +Big Dav II +Big Delts +Big Discus +Big Dog Sly +Big Donads +Big Dumb Zac +Big Eazy +Big Erecshun +Big Genitals +Big Geordie +Big Gol +Big Gorg +Big Grorb +Big Guy Hax +Big Hingus +Big Hoss Lad +Big Jake +Big Jezza +Big Jim Hun +Big Johnnyy +Big Josher +Big Krukke +Big Latvian +Big Lesbo +Big Lew +Big Mag +Big Meth +Big Mike +Big Mo +Big Mooch +Big N LilCox +Big O Wiener +Big Ole +Big Ole Dog +Big Pancaker +Big Poopa +Big Rek +Big Sage +Big Scoops +Big Seaweed +Big Shaq +Big Slick +Big Slurpp +Big Smi +Big Stivz +Big Suze +Big T +Big Tanz +Big Tripod +Big Zaff +Big mfkn Obi +Big ol Bag +Big rOve +Big0neNC +BigBad Matt +BigBadPurps +BigBaller +BigBallsagna +BigBankTake +BigBantonio +BigBaseNZ +BigBear675 +BigBenPies +BigBinkus +BigBlackCats +BigBlueCox +BigBoiiiBuzz +BigBoyBorri +BigBrad Wolf +BigBrownMan +BigBtheOG +BigBug +BigBulli +BigBustUp +BigBwanaCox +BigChinger +BigChuggen +BigChung99 +BigCitta +BigCoatBrum +BigCruch +BigD Randy +BigDSurgery +BigDaddyBomb +BigDaddyEddy +BigDaddyMeme +BigDaddyNate +BigDaddyT85 +BigDick Q +BigDillz +BigDonKeedic +BigDrizzleRS +BigDug4U +BigEar +BigEgoSmolPP +BigGreenEgg +BigGuy +BigHatxLogan +BigHeadPG +BigHootyBoot +BigIronPanda +BigKusa +BigLemonTree +BigLez71 +BigLiftsDad +BigLoadOfOof +BigLovve +BigLuke69420 +BigMainKilla +BigMav0416 +BigMilkerz +BigMo +BigNerdd +BigPapaDank +BigPapaya +BigPepega +BigQuadric3p +BigRaph +BigRat17 +BigRedDog +BigRedRodney +BigRickusTra +BigRodger +BigSack2 +BigSammyD +BigSappas +BigShot BTW +BigSikTv +BigSpook +BigTastyy +BigTimmy +BigUp01 +BigX +BigYitties +BigZikEnergy +Big_B0g +Big_Beard +Bigballsac +Bigbenslayer +Bigborncrazy +Bigboy0007 +Bigboytec +Bigcros +Bigdaddy +Bigdrongo +Bigex +Bigg +BiggSackss +Bigga Boi +BiggerNDumbr +Biggie +BiggieChonks +BiggieMcLarg +Biggieeeeeee +Biggiemollz +Biggies Maul +Biggums +Biggumz +Biggus +BiggusSnails +Biggy +BiggySauce +Bighomiedebo +Bigjwood +Biglex GIM +Bigmet +Bignoob80 +BignoseChris +Bigred8616 +Bigrigcoin +Bigripper420 +Bigrobowskki +Bigtor +Bigwildo010 +Bigwilly597 +BigxFisch +Bigz +Biic +Biig +Biig Boobies +BiigHatLogan +Biig_Boi +Biiggg B +Biitter +BijnaMax +Bijstandswet +Bijuzin +Biked +Biku +Bikura +Bil28 +Bilal Awan +Bilbalbek +Bilbo +Bilbo Dabins +Bilbo55510 +Bilboro +Bilby +Bilde +Bilie +Bilk Mowl +Bilkos_Ices +Bill +Bill Niah +Bill Smiff +Bill Ward +Bill Wigly +Billa +Billest +Billfish1 +Billgodyz +Billie Boi +Billie Gin +Billiee +Billington +Billjetti +Billogbfd +BillowyMilk +Bills Late +Bills PC +BillsITIafia +Billy +Billy Blunts +Billy Buchu +Billy H-M +Billy Joe77 +Billy Plates +Billy Tonka +BillyBob546 +BillyBonka +BillyMav +BillyNotRlly +BillyRay +Billyn +Billyreino +Billz xd +BillzNSkillz +Bily Mavrick +Bilybil +Bimmers +Bingerss +Bingo +Bingo Carla +BingoBango +Bingus +Bingy lol +Binki2021 +Binkleborp +BinksBrew +Binky Stinky +Binneli +Binny +Bins78 +Binv +Bio s +BioCosmic +BioFrank +BioMasterZap +Bioavailable +Bioch +BiofieldMage +Biohazard541 +Biomutant +Bionic Muse +BionicKing +BionicalWolf +Bionicle1395 +Bionycle +Biosafety +Bioterrorism +Bip0lar +BipedalBear +Bird +Bird Ibex +Bird Tickler +BirdFactsr +BirdFarmRun +Birdger +Birdie Train +Birdie713 +Birdies +Birdman +Birdman593 +BirdmanZ17 +Birdmanjr07 +Birdnesto +Birds +BirdsNotRea1 +BirdyguyFe +Birelis +Birjeldadge +Birk +Birkenau88 +Birkenstock +Birkenstocks +BiroGanda +Birth +Birthfather +Bis +Biscape +Bisccy +Biscuit +Biscuit Cats +Biscuitnipz +Bishbasher +Bishbosch +Bisher +Bishop Shane +Biskante +BiskyRizness +Bison +Bisq +Bisse +Bisun +Bit Bald +BitScottish +Bitcoin Z +Bitdefender1 +Bitesized +Bitey +Bithc +Bits +Bits Init +Bitsy Bee +Bitte +Bitterkoekje +Bittles +Bitttimon +Bittykat +Bitwalker +Bitza +BixT +Bizanovic +Bizarre Hobo +Bizk +Bizness +Bizotic +Bizoune +Bizwald +Bj0rnsson +Bjarne +Bjarngrim +Bjergstroem +Bjonny +Bjorhn +Bjorn +Bjorn XXVI +Bk +BkGime +Bkedlikelays +Bkeezy +Bken +Bkguytd6 +Bkostas +Bl0od +Bl0od Legion +Bl0odFenix +BlG FROSTY +BlG MOBY +BlG POO +BlG WOODY +BlNA +BlSHNU +BlZZ +Blaaaaake +Blaack +Blablibla101 +Blac +Blaccy1 +Black +Black Atlass +Black Bears +Black Bro +Black Caucus +Black Fuel +Black Hole +Black Hunlef +Black R X +Black Rifle +Black Upa +Black User +Black lv +BlackAliss +BlackAwaken +BlackCawfee +BlackCloud +BlackHawkEye +BlackNuget +BlackPyramid +BlackTurtles +BlackWidowM +Blacka +Blackasses3 +Blackbandits +Blackbelt +Blackberry +BlackdRedHed +Blackdahlia1 +Blacked Out +Blackeye603 +Blackking435 +BlacklMamba +Blacklmp +Blacknight +Blackout20XX +Blackpak +Blackplosive +Blacksamuri2 +Blackstar755 +Blacktide1 +Bladbro +BladeTongue +BladeWizz24 +BladeXFury +Bladeboy6 +Blademail +Bladenight69 +BladesEspada +Bladypus +Blaest +Blaf +Blag0 +Blainyckz +BlairChan +Blairzy +Blaise +Blaise Green +Blaise22689 +BlaiseDebest +Blak +Blak Deshi +Blak Hawk987 +BlakHammah +BlakTooth +Blakaraknid +Blakdragon +Blake +Blake Bar +BlakeOCE +Blakeboi +Blakeeeeee +Blakely +Blakerke +Blakey3 +Blakk +Blakkeyy +Blakpn0y +Blame +Blame Blitz +Blame Dave +Blamed +Blamer +Blamp +Blank Face +BlankTree +Blanka1990 +Blanke +Blankfillin +Blanks +Blap +Blapa +BlaqBeard +Blard +Blare +Blaser +Blasphemy +Blast +Blast Bepe +Blastoise +Blastrune995 +Blaszczy16 +Blattermans +Blauwe Brief +Blaze +Blaze Hooker +Blaze King +BlazeBaked +BlazeItDad +BlazeThatSht +BlazeWhale +Blazed +Blazed GIM +BlazedRanarr +Blazed_Chip +Blazer Kdog +Blazer-31 +BlazerSven +Blazikenite +Blazin +Blazinbiscut +BlazingGood +BlazingREAPZ +BlazingSid +Blck +Bleak Days +Bleak House +Bleakair +Bleasi +BledReborn +Bleekybleeky +BleepMyBloop +Blehalol +Bleidas +Bleiesnus +Bleifuss +Bleken88 +BlendedWhale +Blendon +BlessOneTime +BlessTime +Blessdd +Blessed +Blessed IM +Blessed N L +Blessedcrypt +Blessin +Blessnt +Bleuski +Blevins33 +Blew +Bleyage +Blhek +Blib +Blije +Blimey +Blimpie33 +Blimpysaur +Blind Yeti +Blind1 +BlindByron +BlindSamael +Blindblinker +Blindeyy +Blindspott +Blindwizard +Blingblin255 +Blinger +Blink +Blinx337 +Blioneer +BlissWarrior +BlissfulDrgn +BlissfulIron +Blisss +Blista +Blistered +Blithering +BlitzJuuls +Blitze +BlitzedBoss +Blixtslag +BlizSukzNuts +BlizZinski +Blizz of Ozz +Blizzard343 +Blizzartd +Blk Kush +Blkbeard22 +Blkup +Bloat +Bloated +Bloats hard +Blob +Blobman1 +Block +Block XD +Blockhead +Blodmire +Blodreiina +Blodreina 1 +Blody Mess 2 +Bloedkuul +Bloeps +Blogmas +Bloke Kisser +Blom +Blombo +Blommer1 +Blonde +Blonde Don +Blonket +Bloo2 +Blood +Blood Face09 +Blood Lotion +Blood Man478 +Blood Moor +Blood Rift +Blood Spawn +Blood Spawns +Blood Turd +Blood Vials +Blood Voss +Blood Wyrm +Blood0fhell +Blood4Peace +BloodWarzz +Bloodfan0 +Bloodgeon +Bloodiedawn +Bloodlet +Bloodmaged +Bloodrave182 +Bloodraven +Bloodredmano +Bloodshade +Bloodsheds +Bloodsportt +Bloody Scarf +BloodyMurder +Bloodyengine +Bloodyrootz +Bloodytem +BloomBouquet +Blooms +Bloons TD +Blops Far +Blorgons +Blosh +Blote +Blouch +Blow Off +BlowBiden +Blowd +Blowin Ohs +BlowingPipe +Blown +BlownbyTwins +Blowup Dolz +BlowyBarry +Blu Ocean +Blu3Mink96 +Blu3print +Blu3s +BluAnimal +BluNightfall +BluSPANKSyou +BluSlidePark +Blubberboy +BludMaul +Bludclat +Bludgeoner0 +Bludime504 +Blue +Blue 420 +Blue Atmos +Blue Fox 64 +Blue Inn +Blue Jay +Blue Legend +Blue Limes +Blue Nahuatl +Blue Osiris1 +Blue Oyster +Blue Summer +Blue Trex +Blue Winds +Blue Ziv +Blue305 +BlueBoat +BlueBorough +BlueCashews +BlueDHYDshld +BlueFrogsOP +BlueGwapes +BlueHawkie +BlueHornet +BlueJob +BlueLegendzz +BlueLemon66 +BlueLine +BlueLite +BlueMandril +BlueMeanEyes +BlueMuff1n +BlueOverkill +BlueRanger +BlueRose91 +BlueTyphoon +Blue_speed +Bluebears +Bluebury +Bluecaps09 +Blued +Blueface G +Bluefir +Blueluna +Bluemoon97 +Blueprint19 +Blueqerry +Bluerope14 +Blues 1 Clue +Bluescreen +Blueshores +Bluestopher +Bluetiger919 +Bluewarthog +Bluexy +Blueyy04 +Bluez +Bluezaros +Bluff +Blufire +Blumkohl +Blump King +Blunt +BluntBird +BluntSurgeon +BluntTaster +Bluntmore +Bluntobject +Bluntology +Blunts +Blunty Pyro +BluntzyMcGee +BlurOfLight +Blurr62 +Blurred +Blurtt +Blusaunders +Blut Arteiri +Bluternite +Bluutooth +BluzCluzz +Blxke +Blyat +Blyckertski +Blyocr +Blze +Bmart +Bmaylor +Bmeg +Bmoot +BmwNerd +BnB +Bnaar +Bo Ed +Bo Selecta +Bo0nies +BoBgss126 +BoBoTaeTo +Boa92 +Boabs +Boagrious +Boang +Boas +Boater lad +Boats N Hoos +Bob Blinger +Bob Burglar +Bob Kelso +Bob Lebowski +Bob Marley +Bob Shermon +Bob Violet +Bob11790 +Bob19922 +Bob44th +BobBojangles +BobCatMilk +BobGuenille +BobNegao +BobRossDied +BobTheDaddy +BobaNeZmogus +Bobakadush +BobbaStanley +Bobbanxd +Bobbiie +Bobby +Bobby Brawl +Bobby JoJo +Bobby Lash7 +BobbyBigLips +BobbyBonk +BobbyShurda +BobbySmooth +Bobbyccf +Bobbydrake09 +Bobbysweggg +BobbyyHill +Bobi +Bobicles2 +Bobidabob +Bobite92 +Bobo Bagins +Bobrobber +Bobrusu +Bobs +Bobsaytoad +Bobtunafish +Bobvill +Boca +Boca Raton +Bocaj +Boccle +Bockovie +BockyOG +Bodaajamies +Bodacious +Boddy +Bodhy +BodisDelotis +Bodjery +Bodlamadrid +Body +Body Kit +BodyRune +Bodyart +Bodybuilding +Bodyguerdson +Boe f +Boed +Boeing +Boeing MAX +Boekanier +Boemsjaka +Boer +Boer Salad +BoerJohannes +Boerboel +Bofad Esnuts +Bofas +Boff +Bog Jr +BogDomen +Bogalog +Bogart +Bogby +Bogchamp +Bogged Dacks +Boggmonster +Boggsy III +Bogi153 +Boginskaya +Bogmellon +Bogusbart +Bohachii +Boham +Bohejmen +Bohn +BohneSaw +BohnerSoup +BoilerMakerr +Boints +Boise Bronco +Bojaroff +BokOrmen +Bokbok9 +Bokeva +Bokje1 +Boko +BolaRobin +Bold +Bold Smut +BoldPelipper +BoldandBrash +BoldupG +Bolibomba +BolleBenny +Bollieflex +Bologang +BolsaDeCoco +Bolsta +Boltagon +BoltonRamsay +Boltzzzzz +Bomb +Bomb Squad +Bombergray +Bomboy +Bombu +Bomer +Bommerche +Bommijn +Bompa +Bompanero +Bompton +Bomtastic +Bon Pa Tin +Bon fee +BonQong +Bonar +Bonar Slayer +Bond +Bond Digger +Bond Huntin +Bond09 +Bond4MyIron +BondBought +BondedLiam +Bondegang +Bonden +Bondi altti +Bondify +Bondkyle +Bondoos +Bonduwel +Bondz +Bone Hawk +Bone Man +Bone Medic +Bone Thugsz +Bone Ur Hole +BoneSurgeon +Bonecrushing +Bonedork +Bonehead +Bonen2 +BonerMachine +Bones2Peach +BonesNAltars +Bonez III +Bonfire1 +Bonfire237 +Bong Lenis +Bong Quixote +Bong Squats +BongAppetite +BongSec +BongTokez +BongZiller +Bonglefin +Bongletopper +Bonglewongle +BongoBasse78 +BongoRider +Bongobodil +Bongotree +Bonh +Bonjwa1 +Bonk Weekly +Bonkers517 +Bonkeykong +Bonnaroovian +BonnieTHICCC +Bonnyjoy1 +Bonnyyyyy +Bonus +Bony +Boo Duh +Boo5tn +BooBaker +Boob +Boob Dragon +Boob Slip +Boob zilla +Boobini +Booblee +Boobs Mom +BoobyHill +Booca +Booduh +Booffee +Boofqueefius +Booger +Booger Ballz +BoogerSnacks +Boogeyman +Boogie +Boogie339 +BoogieCorgi +Boogieman +BoogurBoy +Booiesblazin +Boojwazee +Book +Book of Sand +Bookie Killa +Bookless +Booksmart +BooleanSpl1t +BoolinScape +Booll05 +Booloo +BoomBangPow8 +BoomFire69 +BoomFloof +BoomMatt +Boomdead123 +Boomerclicks +Boomfire2 +Boomfire9 +Boomhakik +Boomjuice +Boomstick08 +Boondow +Booney Tunes +Boookuh +BoopBeepBeep +Booped +Boopette +Boopie +Booping +BooptSnoot +Boorrie +Boost +Boost736 +Boosted six +BoostedBruh +Boostedd +Boostergold +Boostify +BoostyBetard +Boot +Booteelick +Boothanqq +Boothyy +BootieMix +Booties +Bootihole +Bootlesape +Bootsjunge +Booty +Booty Dishes +Booty Kev +Booty McDab +Booty Sensei +BootyCheek +BootyGod Zac +BootyNasty +Bootypixels +Booxia3 +Booyeh +Booze +Boozem +Boozeobagins +BoozyBirdy +BoozyXander +Bop +Bopla +Bopoman +Boppin +Bora +Borads +Boramoss +Borderguard +Boreall +Bored +Bored Idea +Bored Ingame +BoredMalamut +Bored_IRon5 +BorenZo +Borethil +Borgiie +Boriix +BoringName +Boris +Boris King7 +Boris sfisgh +Borkiin +BorkingCorp +Born +Born Abroad +Born to Hodl +BornToTrade +BornTwoGrind +BornofDragon +BoroAce +BoroLight +Boromer23 +Borring +Borsten +Borussia +Bos Marmot +Bos9 +BosNaes +Bosco Wong +Bosh +Boshby +Bosif +Bosnald +Bosnian +Bosnier +Boson +Boss +Boss 4 Pet +Boss Biz +Boss Fights +Boss Mati +Boss Mei +Boss Rarkley +Boss Slayer +Boss4Days +BossMan +BossMann +BossOnly100 +Bossalinie +Bosses +Bossin x +Bossk +BossmanJCriz +Bossnian +BossyEnemy +Bostin Loyd +Boston Tony +Bosw8er +Bot Detected +Bot Matt +Bot Owen +Bot To 2277 +Bot for dayz +Bot player +BotBooster +Bothbalgone +Botman1431 +Botsii +Botsji +Bottatrice +Bottlewin +BottnScheise +Bottrill +Botty +Boub +Bought +Bought Cape +Bought Gear +Boules +Boulli120 +Bouncy +Bound Books +Bounzy +Bourbon Time +Bourgeoiis +Bournos +Boutopia +Bouwkundige +Bouwmans +Boven +Bovine +Bovyy +Bow And K0 +Bow1ng +Bow2ThyQueen +BowIads +Bowbby +Bower +Bowfa Barry +Bowfa Dees +Bowin +Bowinkle +Bowjacked +Bowl +BowlCutMonty +BowlNutta +BowlPacked +BowlResin +Bowlcut +Bowleo +BowlerBTW +Bowlhead +Bown +Bownerator +Bowny20 +BowsB4Hose +Bowse +Bowser Jr +BowserSideB +Bowwsy +Box Art +Box Office +Box T +Box Therapy +Box of Rain +BoxOGnomes +Boxacle +Boxedup +Boxer +Boxic +BoxingNugget +Boxio +Boxse +Boxxie +Boxxy +Boxy +Boy Mobile +Boy Wonder +Boydem +Boydie4427 +Boyfredaaa +BoylifeInNZ +Boys +Boys Broke +Boys No Good +BoysAndGirls +BoysenBill +Boysennn +Boyyo +Boze +Boze Worm +Boze mol +BozeOog +Bozut +Br ay +Br ibb +Br yan +Br00dje +Br0ox +Br0wnSpit +Br3ws +Br4dders +Br4w +Br5andon +BraBraBrad +Braaamps +Brabbss +Brad +Brad RS +Brad T King +Brad017 +BradIsAChad +BradIsChad +BradKavanagh +BraddahPoppz +Braddahoodz +Braddict +Brader +Bradj_55 +Bradlem95 +Bradleyussy +Bradlio +Bradolai +Brads Wrath +BradyDezNutz +Bradycus +Bragon +Brah +Brahamus +Brahu +Brain Drill +Brain Kancer +Brain Stim +Brain Sucker +Brainiac2018 +BrainrotMaxx +Brainsquash +Braithy +Brajen +Brak +Brakathor +Brakence +Brakke Bever +Brakza +Brallerx +Bram +Bram91 +BramDx +Brambickle +Brambo100 +Bramboo +Brammie +Bramxoo +Bramziee +Bran +Bran dont +BranDaMfMan +Branch +Brand +BrandNewHere +Branden +Brandi Rose +Brandir +Brandish +Brando +Brando n +Brando23x +Brandog +Brandon +Brandon 126 +Brandon TJ +Brandon9250 +BrandonLarge +Brandonp32 +Brandonx188 +Branflakez +Brannttt +Bransk +Bransterdamn +Brap +BrasilHemp +BraskaDad +Brass +Brassy Bird +BrastaSauce +BratusB +BraunBrains +BravSlav +BraveBear +Bravenewfy +Braves +Bravest +Bravo +Bravo Eagle +Bravo Lv +Bravo8 Scav +Brawl +Brawlers +BraxMax +Braxt +Bray0420 +Braydons +Braylor +Brazden +Brazeheart +Brazzerker +Brb Delivery +Brblol +Brdy +Breaches +Bread +Bread Again +Bread Dead +Bread Init +Breadatour +Breadhats +Break3r Gabe +Breakchance +Breakdownz +Breaver +Brech +Bredbeddle +Breeann +Breeno +Breenus +Breeoh +Breez +Breezeeh +Breezy +Breezy Jai +Breezy2277 +BreezyMT +Breffest +Breivig +BrejchaBoris +Brejin +Brelinguette +Bremen71 +Brendann +Brendvn +Brenkku +Brenkolovski +Brennzo +Brent Ham +Brent4000100 +Brentiscoool +Brenty88 +Breskvice +Bressjul +Bret +BretHammy24 +Breth +Brett who +Brett6910 +BrettThePunk +Brettdog +Bretz +Brevetted +Brew +Brew Dr +Brew IPA +BrewceWillis +Brewdo +Brewin +BrewskiGod +Brewsley +Brewsy +Brex +Brexit +Brezell +Brezzy +Brian Dub +Brian-senpai +Brian1234146 +Brian4755 +Brian8781 +Brianmyth +Brick Brick +Brick49 +Brickerino +Brickhead +Brickhooouse +Brickhouse +Bridding +BridgeFourr +Bridger +Brie Larson +Brieenne +Brief +Briefly +Briggs +Bright Day22 +Brightest +Brightly +Brihyun +Briickzz +Briidi +Brin +Brinfish +Bring +Bringtheheat +Brinkler +Brinkosaurus +Brinsgr +Brisiinger +Briskly +Brispy +Brist +Brit +Brite +British Diet +British bamf +Britswelll +Brittanys +Brittanyx +Brlm +BrntSausages +Bro bee +BroTwoTher +BroUFailLol +Broad +Broadboat +Broadday +Brobasaurus +Brobible +Brobin +Brocadillo +Brocaine +BroccCheddar +BroccoIi +BroceanMan +Brocepticon +Brocknation +Brocolis +BroderPierre +Brodie +Brodie410 +Brodie827 +Brodisi Jr +Brododore +Brodus Clay +Brodymon316 +Broekloos +Broficiency +Broft +Brogfrogdog +Broha +Brohard +Broiled +Broken Cpu +Broken DPS +Broken Hip +Broken Top +BrokenBones +Brokenn +Brokensunset +Brokk +BrokkMachine +BroknScrotum +Broko +Brolic +Broly +Bromagic +Bromatron +Bromerly +Bromosapienn +Bromz +Bron Yr Aur2 +Bronkey +Bront +Bronxie +Bronxy +Bronze Cow +Bronze Eel +Bronze Moose +Bronze5 +BronzeDong +BronzeWorthy +Bronzegnu199 +Bronzr +Bronzy +BrooceWillis +Broodje +Broodoos +Brooke +Brookesbeast +Brookfield +Brooksher +Brooksy +BroomInBum +Broomi +Brootloops +Brootuss +Broque +Bros +Brosaph +Brosoul +Brossy +Brotatochip +BrothaForest +Brother +BrotherChong +Brothermon +Brotherr +Brotholomew +Brown +Brown692 GIM +BrownTree +BrownTree63 +Brownecakes +Brownmo +Brrandon +Brrd +Brrinn +Brrr Zeus +Brthdy +Bru now +Bruce +Bruce Jenr +BruceJennder +BruceNutty +BruceWayme +Bruceh +BruciebearTV +Bruenor +Bruffell +Bruges +Bruh +Bruhh +BruhhChungus +Bruhs +Bruiser +Brumaks +Brumle +Brundeen +Brundles +Brundo +Brungoil +Bruno p15 +Brus +Brutal +Brute +Brutescape +Bruthar +Brutified +Brutzli +Bruut +Bruva Eww +Brvte +Brwny-mix +Bryan +BryanFury +Bryannn +Bryccc +Bryce +Brychu +Bryci +Brycikins +Bryham0 +Brynildsen +Brynmor +Brys Journey +Bryson +Brysons +Brystreams +Bryu +Bryymstick +Bsakke +Bsaunders0 +Bse +Bsgs +Bsketbl +Bskli +Bslayer +Bthomson +Btownballer +Btrec +Btv +Btw Das +Btw Guy +Btw tietjes +BtwBallo +BtwImJoe +BtwTradeMe +Bu nny +Bu11itt +Bu11seye00 +BuBszs +BuDzNBooze +BuLLeT PVM +Bub Josh +Bub389 +Bubba +Bubba Gage +Bubba Watson +Bubbateux +Bubbba +Bubble +Bubble Butts +Bubble Tea65 +BubbleBlob +BubbleJuice +BubbleOLuke +Bubbleguy +Bubblenab +BubblesGO +Bubblies +Bubbo +Bubbz +Bubgi moment +Bubo +Bubu +Bubzs +Bucc ees +Buccsta +Buchu +Buchu Bong +Buchu Daddy +Bucito +Buck +Buck Oakly +BuckNastyy +Buckeye +BuckinThanos +Buckjames +Buckner1 +Buckner20 +Bud Right +BudLightBtls +BudSake +Budabupbup +Buddaball +BuddahCheese +Buddeke +BuddhaPuck +Buddweiiser +Buddy +Buddy Waters +BuddyGuy +BuddyJ +Budgen +Budget +Budgets +Budjeke +Budpotamous +Buds Bud +Budsteel +Budster +Buduhhh +Budward +Budwise +Budzinski +Budzliteyear +Budzyn +Buff +Buff Bezos +Buff Mafia +BuffFridge +Buffel +Buffel x +Bufubu +Bug V2 +Bugalado +Bugaloo +Bugazzi +BugcatMoo +Bugg +Bugg XO +Bugis x +Bugs +Bugs c +Bugsaur +Bugyo +Bugyy +Bugziee +Bugzy +Buhe +Buhnuhnuh +Buhole +Build3d +Built +Built Dfrnt +BuiltToSpill +BukesCarKey +Bukkakey +Bukkele +Bukmyhr +BukseFar +Bukt +Bula +Bulb_a_saur +Bulba +BulbaThor +Buli +Bulk +Bulkier +BulkyTrout46 +Bull Shifter +BullSharkBob +Bulldawg1289 +Bulldogs815 +Bulldozer297 +BulleT1017 +Bullerbyn +Bullet135191 +BulletBlitz +Bullschiff +Bullseye414 +Bulltill +Buloz +Bultac +Bulte +Bum Hole +Bum Vinegar +BumPounder +Bumble +Bumblethumps +Bumjam +Bummer +Bummholee +Bumveld +BunanaMuffin +BunanuhBread +Bunceylad +Bundle +Bundy red +Bungle Bug +Bungstar +BungusBoi +Bunion +Bunjamino +Bunni Pig +Bunns +Bunns Dying +Bunny +Bunny DeIron +BunnyRabb1t +Bunnytrack +Bunq +Bunryl +Buns +Buntian +Bunty Boy +Bunzosteele +Buorin +Bup +Buqqi +Bur eye on +Bur y +Burak I +Buray +Burec +Burens +Burensbd +Bureze +Burezz +Burg de Rott +Burger +Burgerb0y +Burgerr +Buri +Burial +Burials +Buried Mole +Buriial +Burkekey +Burkkle +Burly +Burlyy +Burmecia +Burn +Burn Herbal +Burn With Me +Burn t +BurnMyChi1d +Burna Boy +Burnardo +Burnari +Burnceller +Burned +BurnedIron +Burners +Burnetplanet +BurnhamAll12 +Burnin +BurninOctane +BurninStarIV +BurningBrian +BurningCole +BurningFight +BurningKushh +Burningdavid +Burninghippo +Burnley +Burns +Burns Green +Burnstown +Burnt +Burnt Bonez +Burnt Bunz +Burnt Senpai +Burnt cod +Burnt lol +BurntT +Burntmeat +BurnzWhnIPvp +Burnzaloree +Burnzie +Burp +Burpenen +Burpsy +Burrkle +Burst +Bursts +Burwell +Bury +BuryMeDeep +Busch +Busch Ebba +Buschhhhhhhh +Buschhuscher +Buschkilla +Bushbaby +Bushido +Bushido Jack +BushidoNegro +Bussch +Bussino +Bussy Bwana +Bust +Bustard +Busted +Busted Shaft +BusterBlader +Busternut +Bustinbibear +BustyBarry +BustySaurus +Busy Phat +BusyDayToday +BusyRightNow +ButMuhMain +Buthole +Butinz +Butje Kef +Butlergunner +Butt Clouds +Butt King +Butt Liquor +Butt Plog +ButtChugr +ButtExpert +Butter +Butter Sock +ButterSirup +ButterSyrup +Butterbur +Butters +Buttgers +Butthxle +ButtnCLICKER +Buttt Mud +Butzaf06 +Buu Blat +Buuloki +Buurtpooier +Buus +Buutsika +Buwuchu +Buwuchuu +Buxi +Buxom Lady +Buy Wards +BuyBitcoin01 +BuyGF_1GP +Buyer Beware +Buying +Buying IG GF +Buying gf 2M +Buying99rc +BuyingRsGfs +Buzi Mi Daj +Buzi Syrom +Buzin +Buzin Benji +Buzy +BuzzL1teBeer +BuzzMax +Buzzard +Buzzi +Buzzlghtbeer +Buzzzwin +Bvanana +Bville23 +Bwan a +Bwana +Bwana Brah +Bwana Haz +Bwana I +Bwana Rat +Bwana TK +Bwana Zander +Bwana-senpai +BwanaObama +BwanaOnDrugs +Bwanah +Bwananabread +Bwanario +Bwanner +Bwarath +Bwekfast +Bwekfeest +Bwie +Bwila +Bwse +Bxao +Bxdhi +Bxo +ByDesign +Bye Felicia +Bye Friend +Byles +Bynguyen +Byrd +Byrd Gang +Byrd Park +Byrne +ByteMeM8 +Byzo +Bztm +C 678 +C A M R O N +C A R S 0 N +C A R S O N +C Biologist +C D C D C D +C H l S E L +C H l Z E L +C HARL IE +C HlCKEN +C J 102 +C L A M P +C L U E 5 +C Maelstrom +C Mauricio +C OLLINGWOOD +C R I X US +C RoyMustang +C Rx +C S +C Sol +C Trafalgar +C W +C Wills +C a c h e +C a le b +C a r lo +C a sp er +C alvarium +C amel +C e v +C eej +C h a ds +C hap +C hristt +C ip +C itadel +C lhris +C nr +C ntmaster +C o r a l +C oach +C orgi +C osmos +C oty +C rafter +C raig +C raiig +C rux +C u r t +C x L +C-11 +C-53 +C-Dom +C-Stones +C-bat +C00RS Light +C00per +C0Dl +C0LTE +C0MBAT 126 +C0RAZON +C0SA +C0WK +C0XG0BBLER +C0Xsuka4gp +C0YS +C0c0nUt +C0dy +C0dyssey +C0nner +C0wanz +C11 H15 NO2 +C137 Beth +C18 +C18H27NO3 +C204 +C2okies +C3 P0 +C33 +C3Pz +C4 RL +C450 +C4L1BRE +C4RL +C4RNAG3 +C8M +C9rl +CA5E +CAKESNIFFER +CALL +CAMBO D N +CAMEL0T +CANNONlNG +CANT SPEAK 0 +CAPITALIST +CAPSLOCK +CARAPlLS +CARDlFF +CARROLLYZER +CATS GO NYA +CATsmoothies +CBC +CBD Brownie +CBK20 +CBMPeterson +CBas +CBomb +CC 9 +CC HM +CCCCFF +CCCO +CCatt +CChuk +CConnor +CDKein +CDR +CDRMark +CDawg420 +CEClL +CEL4L +CEO OF ARK +CEO of TOB +CF5 +CFoodBisc +CFour +CG MindPr0 +CGA +CGC Zeus +CGR +CGoldy +CH1P +CH3CKMYSW4G +CH4OS_REIGNS +CHATBN +CHEEFO +CHIEF +CHIEFWHALE +CHIEFxKEETH +CHOF28 +CHOLEZmusic +CHOPSTlCKS +CHOSENBYNAME +CHR187IAN +CHRlS PRATT +CHRlSDUDE +CHUCKDABANK +CHUDZY +CHULIGAN911 +CHURNlN +CHlC-FlL-A +CHlCKENS +CHlCKNUGGET +CHlLDS +CIA GF PsyOp +CJ McCreery +CJ2K +CJB_01 +CJPez +CJlivin11 +CJoaboneP +CK the Wise +CK2 +CK9 +CKSKEE +CKVY171 +CL0wn Inc +CL3O +CLIIllIIllIT +CMBloodcraft +CMER +CMMCTk +CMU Chips +CMoneyTwo +CN77 +CNC2112 +CNGT +CO maxplayer +CO0RS +CO1N +COKECOKECOKE +COLE +COM3THAZINE +COM3TS +CONFlDENT +CORONA +CORP +COTTONPlCK3R +COVID +COX Kane +COYM +COYMauves +CP8 +CPA Scape +CPR +CPT Morghun +CPT-Rock69 +CQJB +CR1SPY_BAC0N +CR4ZYH34D +CR7 +CRAI9 +CRLmastrFlex +CRSSD +CRTS +CRUSlR +CRY0GENIC +CRlMP +CRlP +CRlSTO +CRlTIC +CRtallboy +CS6 +CSG0 +CSchicky +CT42 +CTFU +CV90 +CVID +CVTRILLOG +CYP 3A4 +CYP450 +CZHANG +C_mrade +Ca 11 +Ca m el +Ca3ino +CaL4MiiTYxX +CaMOOflaged +CaPl +Caam +Caater +Cab Up +CabbageSeeds +Cabbi_cs +Cabdi +Cabela +Cabido +Cabinetsalt +Caboose121 +Caboucha +Cabouchi +Cachalot +Cache +Cachet +CacklingMagi +Cacoadragon +Cactus +Cactus9k +Cactusaak +Cadallic0 +CadmiumBird +Cadov +Caduzitcho +Cadzie +Caekrus +Caelanity +Caelums013 +Caerus +Caesar +Caesar Pasta +Cafe Fraiche +CafeZing +Caffeine +Caffeine Use +Caffeiner +Cages +Cagrets +Cahors +Cahsmo +Caide +Caifan +Caifanes +Caillou hobo +Cailthun +Cainie +Cainn +Caio +Cairn08 +Cairo +Caiser +Caitlin Rice +Cajjj +Cajun +Cajun Blood +Cajun Fox +Cajun Fries +CajunCrimson +Cake +Cake qp +CakeBoss1337 +Cakeboy 43 +Cakefound +Caketins +Cal Fong +Cal l u m +Cal-Mag +Cal_C +CalamityD +Calamityy +Calb_Potta +Calbod +Calcab +Calcd +CalciferGIM +Calcio +CalculateWhy +Calcusource +Cald0g +Caldaris +Caleb +Caleb o_o +Caleeba +Calf15 +Caliace +Calibeafall +Calibrated +Calibur +CaliburZ +Calico +Calierazon +Califaa +Califauxeous +Califirona +Calimandro +Calipha +Calipso +Calist0 +Calisterie +Calivego +Call +Call Me Milo +Call me Cham +Call me m16 +Call0 +CallMeCletus +CallMeGeorge +CallMeJAS +CallMeJoey +CallMeKeen +CallMeKeezy +CallMeLeger +CallMeNoLuck +CallMeSofD +CallMeStevo +CallMeTipz +CallMeow +Call_Me_Arty +Callaghxn777 +Callboy +Calliburr +Calliott +Callisto +Callisto Cub +CallmeZach +Callmekee +CallumTM +Calluum +Calm Chris +CalmCombo +CalmDownSon +CalmYourBits +Calmoran +Calo3 +Calquat +CalquatFruit +Calster26 +Calu +Calum +Calvi +Calvi n +Calvin +Calvin924 +Calyxsys +Calzano +Calzone +CalzonePizza +Cam Jong-Fe +Cam Jong-Un +Cam Rebuild +CamAlot_iron +CamDeezy +CamLite +Camakie +Camaniack +Camargue +Camb o +Cambeezy +CamboSliice +Cambridge +Cambulance +Camdenan +Camel Glue +Camel Neckit +CamelActive +Camelm8 +Camerocity +CameronNeal +Camhanaich +Camil +Camion +Camise +Camm +Cammo545 +Cammy +Cammy Ded +Camosaur +CampBingBong +Campbell +Camperfish +CampinOnline +Campisii +Campus Crew +Camsdadddy +Camshows +Can Berry +Can Fe Spoon +Can U C Me7 +Can it Bozo +Can0fBeans +CanChem +CanMJ +CanManCannon +CanOManBFTM +CanUGetAway +Canada +CanadaBawd +CanadaGuuse +CanadaScape2 +CanadasChief +Canadian +Canadian Bc +CanadianDevi +CanadianYeti +Canadiehn +Canadiian +Canan32 +Canberk +Cancel +Cancelled +Cancelled It +Cancer7 +Cancerfree24 +Cancerios +Canderos +Candlebox +Candrok +Candy +CandyFlipin +CandyKing42 +CandyKing420 +CaneCorso +Canear +Canehdiann +Canibalistic +Caniz +Cann +Cannabinoidz +Canned Beer +CannibalGK +Cannibble +CannoliBoi +Cannolis +Cannondorf +Cannot +Cannot Login +Cannrrrr +Canon Bob +Canook +Canowhoopazz +Canserber0 +Cant +Cant Quit 07 +CantCasino +CantMaxBc69 +CantTalkPerm +CantThink +CantTradeTho +Canta +Cantaloupe +Cantclik4sht +Canter +Cantina +Canting +Cantu +Canyonranger +CaoFasho +Caoe +Cap E Bara +Cap10 +Capalotty +Cape Fear +Cape Max +Cape Seller +CapeScape +CapeZer0 +Caped +Capez +CapiiTano +CapitalGainz +Capitalise +Capitalist34 +Capn Wahle +CapnCookd +CapnMeliodas +Capniq +Capnplant +Capo Yamato +Capone +Capos +Capotia +Cappe +Cappei +Cappie Greek +Capreol +Capriccio +Caprius +Caprix +Capsule +Capt +Capt Bobette +Capt Bumi +Capt Dave +Capt G +Capt Halo +Capt Hootler +Capt Kenway +Capt King +Capt Kumquat +Capt Murdoc +Capt Plank +Capt420 +CaptHardon +CaptLongJon +CaptPleb +CaptZilyana +Captain +Captain Jack +Captain Lev1 +Captain Tast +Captain Tec +Captain Y +Captain Zoso +CaptainAlice +CaptainCanto +CaptainCox +CaptainDom +CaptainDredd +CaptainLuker +CaptainOboy +CaptainObvio +CaptainWalt +Captainshiny +Captainzzz +Captan +Captcha +CaptinA +CaptinKorasi +Captinrandom +Captiva +Captn +Captn Bear +Captn P00F +Captn Sqirk +CaptnCommand +CaptnMittens +Capu +Capussi +CapybaraDung +Car Ram Rod +CarNalgas +CaraDuraMC +Caracal +Carademlof +CaramelSlice +Caratheodory +Carbo Cat +Carbolic +Carbon +Carbon K +CarbonCarbon +Carbonist +Carbos +Carbyne +Carcinoid +Carde +Carden +CardiacKemba +Cardinxl1 +CardyZ Main +Care +Carea +Caregiver +Careo +Caricapaya +Cariej +CarimsEygon +Carino +CarjUIM +Carjacking +Carked +Carkis +Carkosa +Carl +Carl Sagan +CarlBarker +CarlDerp +CarlSagan80 +Carleton789 +Carlin +Carlingue +Carlitos +Carlo +CarlosM +Carlosjavily +Carlrip +Carls453 +Carly +Carlyle +Carmillae +Carna +Carnadova +CarneGrande +Carnie +CarnifexVeil +Carnitas +Carnival0fRs +Carnzlo +Carolan +Carp3di3m13 +Carpe +Carpenters +Carpi +Carr +CarrickDaddy +CarriedBayo +Carrot s +CarrotMilker +Carrs Pasty +Carrutt +Carry +Carry Yak +Carry9otter +Cars +Cars Suck +Carsillas +Carsten10 +Carterfish +Cartman +Carton +Cartzy +Caru +Carvdogg17 +Carve +Caryopsis +Cas1a +CasZeal +Casamigos +Casawn +Casc +Casca +Cascola +Casell +Caseten +CaseyWaff +Cash +Cash two +Casherbob +Cashewk +Cashlemke +Cashs Main +Casino +Casino Sand +CasinoProblm +Casketball +Casmatos +Cass Cath +CassTheGod +Cassarole +Cassath +Casserolio +Cassidyy +Cassie Aram +Cassim +Cassirer +Cast +Cast Rate +Cast Turbo +Castello +Castilla +Castorly +Castrophany +Casual +Casual Man +CasualChris +CasualGrinds +CasualPete +CasualStorm +Casualdkdk +Casualty +Casvel +Casviel +Cat Man1001 +Cat Nips +Cat Shaped +Cat Smuggler +Cat Snacks +Cat Soup +Cat Woman +Cat got out +Cat shirt +CatBoyInHeat +CatPandas +CatPissRNG +CatSaysMeow +Cataclysm55 +Catala +Catalepsy +Catalyticx +Catan +CatchTheDrop +Catchin +Catchin Pets +Catchlove +Catdog1280 +Catechism +Cater Champ +Catfish Rock +Catflap +Catgirl Cafe +CatgirlSan +Cath +Catharina +Cathays +Cather +Catherbae +Cathuntdog +Catman31 +Catnip +Catnip Cutie +Catnor +Catomic123 +Catra Meow +CatsnCars +Catsnarterrr +Catspeak +CattoKitty3 +CauZ +Cauldrons +Caulf1eld +CaulkPushUps +Caustic +Cauterised +Cavaleiro888 +Cave +Cave Closer +Cave Horror +Cavern +Cavern Freak +Caves +Cavos +Cavs +Cavsy +Cawrin +Cayk +Cayman 07 +Cayrus +Caza Lowell +Cazaq2 +Cazik +Cazos +Cazum +Cazwise +Cazzakin +Cazzy +Cba Ofc +Cba To Carry +Cba To Share +CbarDaKing +Cbetrs +Cbf Playing +Cbot05 +Cc17wo +Ccn +Cd777 +Cdale +Cdoc +Ceana +Ceb +Ceber +Ceceil10 +Cecetra +CedIsMySon +Cedty +Cee real +Cee-Jay +Ceebooty +CeeeHooo +Ceeege +Ceejaydjj +Ceekay +Ceeon +Ceeps +Cefiro +Ceio +CekicGuc +Celach +Celach 2 +Celadus24 +Celazer +Celebio +Celer0 +Celesdel +CelestialSun +Celestive +Celestron +Celhon +Celi0 +Celiac +Celikanen +Celine Dijon +Cell Saga +Cell Z Saga +CellaDwella +Cellectric +Celli +Cellmate +Celms +Celrisen +CeltBrenny +Celtic +Celtic Hero +Celtic555 +Celtica +Celyzh +Cemen Demon +Cengkeh +Cennolink +Cenpie +Censor +Centac +Centennials +Center Fit +Centers +Centershot5 +CentraIka +Central +CentralC +Centrimag +Centropy +Ceo of Timbs +Ceoe +Cephalopods +Cepp +Ceppt Irn +Cepxy +Cera +Ceraseus +Cerati +Cerb +Cerb R Us +Cerberus +Cerberus98 +Cercle +Cerea +CerealGuy +Cerebro +Cerenade +CeriGG +Cerkev +Cermi +Cerpin +Cerpin Taxt +Cerpooch +Cersey +Cersky +CertIronBoy +CertifiedPoS +Cervantes18 +CesarPalace +Cesema +Cetr +Cets +Cev +Cevap +Cevarus +Ceverie +Cewl +Cewl Hwip +Cexilius +Ceyyl +Cf b4 +Cfretz244 +Ch i +Ch i c k en +Ch ief +Ch00bies +Ch0c0tac0 +Ch1cag0 Bear +Ch1mes +Ch1noLf +Ch1zz +Ch33sy +Ch3ckMat3 +Ch3spy +ChNPP +Cha rles +Cha0ticAngel +ChaCha +ChaCha Benny +ChaSniff +Chaavez +Chaboud +Chaboul +Chacaliando +Chacksen +Chad +Chad Draven +Chad Stride +Chad Vibes +Chad Wardn +Chad again +Chad isAFK +Chad okeefe +ChadBehavior +ChadCor +ChadFratStar +ChadMadLad34 +ChadR3333 +Chadacas +ChadamantBar +Chadders +Chadding +Chaddyboy +Chadga +Chadieus +Chadkiller76 +ChadronX +Chaehee +Chael +Chaendo G +Chaewon +Chaga Chai +Chain +Chain Mace +Chainn +Chainsaw +Chainsaw Guy +Chair +ChairmanMao +Chaiyse +Chaken +Chakleton +Chakra Monk +Chal1ce +Chalba +ChaldeanGIM +Chalgrove +Chalk Bar +Chalked +Challandria +Challll +Chalva +Cham Cham +Chamariapero +ChamberBeast +Champ +Champ Ryan +ChampGaryOak +Champagnole +Champiion +Champion910 +Championship +Championz +Chance2Skill +Chanced +Chancellor +Chancie +Chandler737 +Chando +ChangWu +Change +Changebear +Changes +ChangrOfName +Chanios +Channel +Channon +Chaos +Chaos River +ChaosBandego +ChaosCleric +ChaosD00M +ChaosGIM +ChaosInbound +ChaosJS +ChaosedElf1 +Chaosfish33 +Chaoslynx +Chaotic Cole +ChaoticH0B0 +ChaoticMoott +ChaoticScorp +Chaotixx +Chaottic +Chaoz +Chap Zachman +Chap em up +Chapels +Chaplain +Chapo +Chapoo +Chapp +Chappe +Chappers +Chapter +Char Zeta +Char lang +CharL-32 +Character252 +Charamio +Charatcur +Charben +Chardonn +ChargeN +Chargez +Chariot +Chariten +Charitonin +Charizardz +Charlez +CharlieFTG +CharlieFine +CharlieOHair +CharlieScene +CharlieTheIV +CharlieWork +Charlieb9 +CharliesFE +Charloi +Charlotta +Charltonb +CharlyDarwin +Charm +Charmey +Charmin12 +Charmos +Charmoul +Charms +Charmy +Charon0 +Charor +Charred Yews +Charrysteas +Chartart +Chase Goals +Chase Jones +Chase Riley +ChaseGuy +ChaseNBake +ChasePP +Chaser959 +Chasing Pets +ChasingDragz +Chasmata +Chasse +Chastised +Chatorbait +Chattanugget +Chatto +Chatty +ChaukletZ +Chauman0819 +Chauska +Chavi +Chaz +ChazMac +Chazzdiddy +ChazzedBangr +Chazzy +Chazzy Paws +Cheah +Cheaps +Check +Check Point +CheckAndMate +CheckRaiseHS +CheckTheWiki +CheckWikiPls +CheckWikiPlz +Checkaaa +Checker +Checkley +Checkmate +CheddLaurent +Chedda +Chee +CheecHnChong +Cheech Blaze +Cheeek +Cheeks +Cheeky +Cheeky Peeky +Cheeky Prawn +Cheeky Tom +CheekyBanter +CheekyCheeto +CheekyDrop +Cheelee +Cheeno +Cheepnis +Cheermancy +Cheers +Cheese +Cheese Borgr +Cheese Slice +CheeseTax +Cheesebubby +Cheeseilton +Cheeseit32 +Cheesteri +Cheeswiz +CheesySweet +Cheesyrice +Cheetas +CheetoRatFan +Cheetu +Cheex +Cheez-Zits +Cheeze Caper +Cheeze Nepz +CheezeOx +Cheezer2000 +Cheezewiz0 +Cheezo +Cheezuz +Cheezyboy25 +Chef +Chef Bu Fang +Chef Malone +Chef Mihali +Chef Peter +Chef Poopy +Chef Special +ChefBoiRJay +Cheff Zaya +Cheffrey +Cheffy95 +Chefs +Cheif +Cheimuu +Cheiquispir +ChelTheNelf +Chelate_D +Chello Sexy +Chellyy +Chelsea Bot +Chelsko +Chelsy +Chelx +Chemanelo +ChemicalFade +Chemleech +Chems +Chen Luu +Chendlar +Chenzooo +Cheomeister +Cherba +Cherisu +Cherno-byl +Chernoblyat +Chernobyl +Cherri Bomb +Cherry +Cherry Field +Cherrydown +CherryxPiex +Chesco +Cheshmate +Chesscape420 +ChessyQ18 +Chessyboi +Chestbrah +Chestbroh +Chester63 +Chesterfi3ld +Chestickles +Chestnut +Chestodor +Chet +Chet Baker +Chet Max +Chet Ripley +Chettos +Chevaliers +Chevrolet +Chevron +ChevyB1998 +Chew +Chewbacca No +Chewbakkaah +Chewby +Chewby Lt +Chewed +Chewitt88 +Chewy +Chey +Chi hiro +Chi11 Wi11 +ChiCity +ChiIdo +ChiLongQua +ChiamataM +Chibattagreg +Chibber +Chiboubo +Chicanery +Chiccbacca +ChichaBabby +Chichhuve +ChickeNOG +Chicken +Chicken Cat +Chicken996 +ChickenRings +Chickenelli +Chickenneth +Chickens Inc +Chickensnout +Chickerolies +ChickinNugie +Chico Bean +Chico Cool5 +Chicold +Chicopee +Chid Heredit +Chie +ChieFbLuntz +Chief +Chief Checka +Chief Gordy +Chief Herres +Chief Otaku +Chief Seneca +Chief Sound +Chief Toxine +Chief812 +ChiefBobert +ChiefSmakaHo +Chiefss +ChieftonP +Chiekz +Chiester 45 +Chigginwangs +Chiiiraq +Chika +ChikenLiro +Chikinbone +Chiksan +Chikupa +Chilasr +Chilaxinman +Chilcos +Childhoods +Childish +Chilgamesh +Chili +Chili Pepper +Chili Popper +ChiliTurd +Chilibean +ChilidogBank +Chilidoger +Chilipupper +Chill +Chill Mate +Chill Maxxy +Chill Zege +ChillAssGuy +ChillHill +ChillScape +Chillagalet +Chilled +Chilli +Chilli Ramen +Chilli dong +ChilliPesto +Chilliam +Chilliburns +Chillmitch +Chillrend +Chilly +ChillyPolarB +ChimJongUn +Chimbilin +Chimera364 +Chimire +Chimmy +Chimneybob +Chimp10n +Chimpywimp +ChinStar +China +ChinaInBox17 +ChinaSupaman +Chinanumber1 +Chinchompin +Chinchonkerz +Chinchoopa +Chinegroe +Chingie +ChingwaChing +Chinley +Chinolc +Chinook Bram +Chinquila +Chintan +Chio Bu +Chionophobia +Chip +Chip Black +Chip Skylark +ChipRain +Chipotl e +ChippedHam +ChipperyChip +Chippy +Chippy btw +Chipsbok +Chipsncrackr +Chipster321 +Chipz +Chisa +Chisels +Chiswick +Chitus +ChivZz +Chiw +ChixDigTbows +Chiyo-Father +Chizle +Chizzet +Chkn +ChloeTragedy +Chloemacmate +Chloes +Chloramine +Chnce +ChoNaWiadro +Chob +Choccazz +Choche +Choco Flex +ChocoMeteor +Chocoblow +Chocobo +Chocobos +Chocomalo14 +Chocys +Chodemate +Chodless +Chofl +Chohanzzz +Choi +Choicess +Choke Daddy +ChoklatMoose +Chola +Cholesterol +Chom +Chombe +ChompVonDile +Chompadile +Chompakilla +Chompy +Chompy chick +Chompys +Chon +ChonYee +ChonerScaper +Chongsy +ChonkPenguin +Chonksta +Chonky Duck +Choobage +Choobcob +Choochy +Chooks +Choomb +Choooooooch +Chop +Chop Rips +ChopSthix +Chopemania +Chopin +ChopinDolphy +Chopinaway +Choppa +ChoppinWork +Chordes +Choreboy +Chornflakes +Choronzon +Chosen +Chosh +Chow +Chowfun +Choybin +Choz +ChozenGod +Chozen_Azn +Chozo +Chozo Lite +Chozo Statue +Chqse +Chr Mck +Chr0nl +Chranic +ChrdyMcDenis +Chri5ty +Chriiiis +Chriisgg +Chrimon +Chris +Chris F +Chris JR +Chris Luxon +Chris P3 +Chris Slays +Chris xD +Chris0527 +Chris1f +ChrisCleans +ChrisFate +ChrisHanson +ChrisKringle +ChrisOnTilt +ChrisTheUnit +ChrisThomps +Chrisadk +Chrisha +Chrishowe +Chrisible +Chrisjay +Chriskies +Chrisob +Chrisog +Chrispy +Chrispy-sama +Chriss +ChrissPIBass +Chrissy +Chrissy Tooh +Chrissyx +Christ +Christ an +ChristFarley +Christiannnn +Christidog +Christlan +Christmonkee +Christoffer +Christoker +Christopher +ChristyCloud +Chrisxmas +Chriz +Chriz297 +Chrizzoz95 +Chrl +Chroist +Chromadorr +Chromalox +Chromatica +Chromi +ChromieOX +Chromixe +Chronepsis +Chroner +Chronic +Chronic Jack +ChronicChris +Chronicflame +ChronnerBro +Chrono Aeon +ChronoKiller +Chronoburn +Chronomancer +Chronorage +Chronos +Chronosanity +Chrostopher +Chrunndle +Chrusee +Chrysaorr +Chrysaros +Chryserys +Chub +Chub n Tuck +Chubafet +Chubby +Chubby Nomad +Chubs-Magee +Chubsy Bubsy +Chuchin +Chuck +Chuck Hoots +Chuck Prime +Chuck truck +ChuckChan +ChuckDogg +ChuckMeDaddy +ChuckNat +ChuckSpedina +ChuckTesta +Chuckerberg +Chucky +Chuda007 +Chug +Chug Butt +Chug KoolAid +ChugMyPPot +Chugg Jugg +Chugga +Chugger +Chugging +ChumSlugger +Chuml +Chump +Chumpingham +ChunchuloX +Chunetops +Chung +Chung us +Chungus-kun +ChungusClam +Chunk +ChunkiCinni +ChunkmanFYB +Chunksy +Chunky Nan +ChunkyGimp +Chunkybudda +Chupa +Chupperino +Chur Broo +ChurchMouse +ChurchTuring +Churchfield +Churchieboy +Churd +Churlrunone +Churnin +Chuzyz +Chvrles +Chxmpanzee +Chyky +Chyna +Chyurr +CiSCii +Ciamballer +Ciaphas Cain +Ciastkowy +Cic321 +Cicely +Cicero +Cici +Cicindelinae +Cider +CieloQueen +Cigarettez +Cigblaster +Cigggy +Ciggitybutts +Cighan +Cignii +Ciji +Cim +Cimakas +Cimelia +Cinamin +Cincinnatus +Cinderal +Cinderhulker +Cindirty +Cinemaxxin +CinmarRS +Cinoxe +Cinqoo +Cinquain +Ciomsa +Circle Pea +CircleStrafe +Circleone58 +Circomcised +CircularSaw +Circumflexx +Circus Clown +Circuz +Ciresidnal +Cirexi +Cirez +Cirmit +Cirn0 +Ciroren +Cirrus Virus +Cirth +Ciryatur +Cisco +Cisk +Cisplatin +Ciszak1996 +Cit Funt +Citadel +Citadel Wyrm +Citate +CitizenTay +CitrusLemons +CitrusTree +City +City Limits +City Morgue +City Perks +Civeo +Civz +Ciziin +Cizre +Cizzakillss +Cjg117 +Ckale +ClGARO +Cla ws +Claca +Claco +Claiborne +ClairDeLune +ClaireFarr0n +Clambam +Clamburglar2 +Clan thmoker +ClanChats +Clan_Daddy +ClankImaTank +Clannyy +Clanworld +Clap3d +ClapMaster4K +ClapMeMommy +ClapYouDown +Claptrap +ClarKah +Clardy2 +Clarisse +Clark C +Clarkey BTW +Clarky +Clasherz +Clasico +Classic +Classic Max +ClassicTrap +ClassicVibes +Classically +Classickxd +Classsikh +ClassyCod +Claudenstein +Claudiu +Claw +Clawdius +Clawsie +Clay Nasty +ClayNugget +Claymor +Claypops +Clayters +Claytn +Clayton +Clazerbeam +Clean +Clean Dishes +CleanSleeve +CleanedBown +Cleann +Cleanst +Clear +ClearEyes +Clearly +Cleatis +Cleaver +CleaverGreen +Cledos +Clefable +Clefairy +Cleg Drop +Cleible +Clem +Clem585 +ClemFandango +CleoTehCat +Cleopatraa +Cleoxc +Clerric +Clethbery +ClevelandOH +Clevey +ClexOrie +Cleyra +Clff +Cliche +Click +Click Bosses +Click hero +ClickAndChil +ClickB8 +Clickbait21 +Clicks0nMobs +Cliffder +Clifferd +CliffyOG +Cliffyy +ClimateChang +ClimberAZ +Clingy +Clinician +Clinicwater +Clint +Clinttt +Cliphanger1 +Clipper +ClipseZ +Clipz +Clipz Ahoy +CliveTrotter +Clix +Cload +Clockwise +Clod +Clogged King +Cloggin +Clogging +Cloistered +Clone +Clone bone +ClosedLoop +Closertohell +Closeshots +Closofy +Clotert +ClottedCream +Cloud +Cloud Cover +Cloud Els +Cloud Griega +Cloud Nine +Cloud Stairs +Cloud Surge +Cloud y +Cloud1K +CloudSoftass +CloudT +Cloudhill +Cloudi Boi +Cloudjumper9 +Clouds +Clouds_Song +Cloudy +Cloudy Boi +Cloudy Sleep +Cloudy Wolf +CloudyOcean +Cloudys +Cloudystrife +Clouted +Clovie +Clown +Clown Around +Clown0164 +Clownfart7 +Clryy +Clss +CltRain +ClubBruggeKV +ClubWolf +Clue +Clue More +Clue Relic +Clue box +Cluebringer +Clueful +CluelessKook +Cluer +Clues +Clues Hunter +Clumpey +Clumsy +Clunker +ClutchFlipsy +Clutchy +Clyde Cooter +ClydeBarrow +Clynelish +Clyps +Cmallz02 +CmarBeast +Cmndrcool222 +CmokinSrack +Cmon +CmptrGmr +Cnbl +Cnhil +Cnr +Cnwalker +CoFlack +CoKMcGay +CoX Mentor +CoX ToB ToA +CoXAcc +Co_do_blyat +Coa +Coach +Coach Trip +Coach Wright +CoachJal +Coachsharter +Coal +Coal ore +Coan +Coat Throat +Cob Web +Cobab +Cobalt +CobaltKings +CobbMorty +Cobba +Cobplacecow +Cobra +CobraChickn +Cobreu +Cocajumba +Coco +CocoGetsLoot +CocoaPuff +CocosLilSimp +Codai +Code +Code Mellow +Codemax +Coder00d +Coderedcfc +Coders +Codfish808 +Codi +Codonz +Cody +Cody Smith +Cody The IM +Cody The M +CodyBeaumont +Codys Nuts +Codyx +Coeeyyy +Coekebakker +Coenzyme +Coex +Cofeni +Coffaholic +Coffe277 +Coffee Latte +Coffee Love +Coffee Robot +Coffee94 +CoffeeAndExp +CoffeeBarrel +CoffeeIsBest +CoffeeKitty +CoffeeMafia +CoffeeQ888 +CoffeeSlayer +Coffey +Coffin Cape +Cogelon +Coggle +Cogstyle +Coheed +Coherent +Coilman +Coin +CoinToss +Coinism +Coipo +CokeHogan +CokeShoveler +Cokebro +CokedPepsi +Col10 +ColVolgin +Cola +Cola Flesje +Colaboks +Colb y +Cold +Cold Bowl +Cold Ham +Cold Hash +Cold Hemp +Cold War +Cold1 +ColdReign +Coldhound591 +Coldpiee +Coldraze +Coldrootbeer +Coldshop +Coldstream +Coldvayne +Coldvepz +Coldwar +Coldwoods +Cole10083 +ColeEleven +ColeQuil +ColeVeryBakd +ColectionPog +Colee +Colei +Coleus +Colgate777 +Colienergia +Colin +Colins +Colivanov +Collan33 +CollectMemes +CollectibIes +CollectionIM +Collectively +Collector of +Collega +Collier +Collierss +Colliflopter +Collin892 +CollioKey +Colom +ColonColitis +Colonel +Colonello +ColonialDank +Colonne +Color Climax +ColorBlindHC +ColorMeBlind +Coloradodo +ColorfulE +Colossus 5 +Colossvs +Colt +Colt trigger +Coltan +Colthound +Coltn +Coltrainz1 +Coltsfan1996 +Columbot +Columbus175 +ColumbusCrew +Colxman +Colzy +Coma +Combaed +Combat Phase +CombatStudy +Combatking13 +Combibo +Comboed +Combos +Come +Come Loads +ComeAtMeBruh +Comet +Cometz +Comex +Comfort +Comfortably +Comfy +Comfy Butt +Comfy hug +Comic +Comic Books +ComicalBust +Comicmaster0 +ComingHome +Comiya +Comlidor +Comm Zilyana +Command Grab +Commander Fh +Commander Ra +Commas +Commiefornia +Common +Common Drop +CommonGinger +CommunistMoo +CommunistPig +CompactSugar +Companiion +Companion +Compd +Compe +Compgeek +Compilacion +Complain +Complete +CompleteAss +CompleteSpud +Completes +Complex +ComplexTree +Complextro +Composing +Composites +Comptons +Compy +Compyclon +ComradSergey +Comrade Hanz +ComradeCas +ComradeCovid +ComradeMule +ComradePugs +Con JD +Con Safos +Con ner +ConKlave +ConaAmadora +Conaizy +Conal +Conceited +Concentrates +Conchrist +Concritus +Conductor4 +Cone01 +Conedinho +Confederacy +Conficker +Confidentiel +Confined +Conflamit +Conflate +Conflict +Confuze +Congest +Congetus +CongiestMunt +Congra +ConicLight +Conjay +Conjo +Conman +Connavar +Connee +Conner +Conner OK +Connerr +Connerxx +Connor M +Connor xv +Connzy +Conor +Conor J +Conor07 +Conpetgrebe +Conqo +Conquar +Conquers +Conquestions +Conquestti +ConradK +Consan +Considerable +Conskis +ConstantZero +Constantnips +Constellar +Constence +Constricted +Constructeur +Consumption +Contaminate +Contant Geld +Contendedd +Conterfeit +Contes +Contrabant +Contract M +Contradicted +ControlAll +Controller +Controlllers +ControneX +Contyy +Conventicle +Converter +Conway +Conydriving +Conyon +Conzila +Conzine +Coob Lad +Coogs +Cooj +Cook4everu +Cookdaburra +Cooked Chook +Cooked Sinus +Cookedvomit +Cooki3Crumb +CookiMan +Cookie +Cookie Cake +Cookie O_o +Cookie904 +CookieKid00 +CookieSpec +CookieV3 +Cookiers +Cookiezi +Cool +Cool Raccoon +Cool Yak 496 +CoolAssName +CoolG WC +CoolNameBrah +Coolair +Coolavatar1 +Coolboy_cal +Cooldesert2 +Coolest91 +CoolestCow +Coolio +CoolmanCool +Coolmanafo +Coolminer685 +Coolmintoreo +Coolmonkey50 +Coolsniper +Coolster +Coolxkidz +Coom +Coomcoomber +Coonrade +Coopa +CoopaTroopah +Cooper +Cooperative +Coopr +Coopsz +Coors Light +CoorsRight +Coorsy +Coos +Cooter +Cooter Kick +Cootie +Coozn +Copytopy +Coquettish +CorCam +Corabex +CoralCastlez +CoralFire +CoralReef +Corbi +Corbula +CorbyTheLad +Cord +Core OS +Coree +Coreey +Coreling jr +Corena +Corey +CoreyCarlaw +CoreyNKH +Coreyeroc +Corgi +Corgi Puppy +CorgisIron +Corgo +Corinnna +Corizz +Corleone +Corley +Corn +Corn x Holio +Cornbuddy +Corndoq +CorneliusIII +Cornflake +Cornie +Cornilius +Cornish +Cornwall94 +Cornwalll +Corny10k +Cornye +Corona +Corona Bat +Corona Case +Coronad1 +Corp +Corp Scape +Corp09RS +CorpLeecher +CorpRng +CorpSlapper +CorpToMax +Corping Bro +Corpletics +CorporalWolf +Correy Lahey +Correyyy +CorruptDingo +Cors +Corsa +Corsetti +Cortes +Cortex +Cortica +Cortistatin +Cortsen +Corun +Corvanjer +Corvisquire +Corvitolis +Corvo +Corvoo +Corvus +Corvus enca +Corwin +Corydonn +Coryy +Corzappy +Cos A Nostra +Cosaintus +Coseph +Coshie +Cosmic +Cosmic Booty +Cosmic Star +CosmicPebble +Cosmiclaws +Cosmog +Costa +Costah +Costcutters +Costi +CostlyOne +Costom +Costs +Cotched +Cotopaxi +Cotstini +Cottee +Cotton +Cottrell +Cotty2Hotty +Couch Frame +Couchie +Coughey +Count 2Three +Count Cranz +Count Dookie +CountCuckula +CountDrugula +Counterspell +Countries +Country +Country Song +Countwert +Coupland +Coures +CourtnyGears +Couscous +Cousin +Cousins +Couzens90 +Cove +Coventrians +Coventry +Covert +Covert Blade +Covid +CovidFree +Covvboyz +Cow Door Mat +Cow Foo +Cow Pet +Cow Tongue +Cow Wizard +Cow395 +CowChum +CowMr101 +CowSalsa +CowVein +Cowa +Cowabungalow +CowboyK1ller +CowboyKaroo +Cowdenbeath +Cowlories +Cowrat +Cowsburp +Cowtongue +CowzGoMoopy +Cox out boys +Coxed +CoyieGod +Coz +Cozmic_Raven +Cozy +Cozzza +Cpl Gaz +Cpl Seeder +Cpt Doobie +Cpt Fail +Cpt Kokopuff +Cpt Mellow +Cpt Mina +Cpt One Eye +Cpt Pepe +Cpt Pop Tart +Cpt Shanks +Cpt TRICKS +Cpt Unclutch +Cpt Wally +CptAceRimmer +CptKyle +CptRileyy +CptRom +CptSankara +CptSmackAHo +CptUzu +Cptainseveto +Cptn +Cptn Jack +Cptn Murica +CptnBuckaroo +Cpunek +Cqrl +Cr o +Cr0be +Cr0codile +Cr0z +Cr4zyLuck +CrAzY HoRnEt +Crab +Crab Emoji +Crab Jazlo +Crab Leaker +Crabalt +Crabby +Crabcore +Crader +Craft +Craft Brew +Craft Guild +CraftPure +Crafter Jr +Craftes +Craftsmen +Crafty +Crafty Man +CraftyRunes +Cragyl +Craig +Craig Dawson +Craighead18 +Craizy 8 +Craizy9 +Crakced +Crammerr +CranadosX +Cranberry +Crangus +Crank +Cranke +Cranky +Cranky Cows +CrankyScream +Crantock +Crapicorn +Crapping +Crappy Luck +CrappyScape +Craqers +Crash +Crash Crann +Crash Cymbal +Crash Site +Crashbot +Crashendo +Crashticles +Crateapa +Crateaqa +Cratzi Duhuh +Crave +Crave Me +Crave to Max +Craw +Crawfish +Crawl2033 +Crawn +CrawsBow +CrawsMain +CrayQuaza +Crayons +Crayy +Crayzee +Craze NL +Crazed Man +CrazedAfro +CrazedAgain +Crazedmonkee +CraziKido +Crazie +Crazy +Crazy 859 +Crazy Canada +Crazy Sam +Crazy Skull +Crazy5115 +CrazyDieMan +CrazyDryMan +CrazyDutchy +CrazyIron85 +CrazyShrimp +CrazyStuff +Crazya0 +Crazyb00b +Crazyhalo +Crazys +Crazystevee +Crazytree +Crazzy +Crazzy Ivan +Crcsh +CreaMiJeans +Cream +Cream City +Cream Guzzle +Cream21 +CreamFreesh +CreamingPies +Creamp +Creamy Fella +Creamy Whole +Creasential +Creat Steal +Create +CreateNoPain +Created +Creating6 +Creator1212 +Creator409 +CreatorJR +Creaturree +Creazy7 +Crecker Fux +Crecket +Credibility +Credito +Creel +Creenen +Creepy +Creezy +CreightonRS +Crem Fraiche +Cremator +Crenoc +Crescent +Cressp +Cresss +Creston fftp +Crevis6 +CrewDoe +Crewcial +Crickets +Crickss +Crier +Crimewave +Crimeway1991 +Crimin +Criminaldmge +Criminalised +Crimp +Crimson +CrimsonCow +CrimsonDDS +CrimsonJayce +CrimsonLily +CrimsonRogu3 +CrimsonScape +CrimsonTide +CrimsonU +CrimsonWic +Crimsoncaim +Crimz0n +Crinath +Cringy Grump +Cringy af +CrinsomX +Cripler +Cripple +Crippled +CrippledKev +Crippler +Cripty +Cris +Crisby +Crispiessss +Crispy +Crispy Bac0n +Crispy I +CrispyBreast +Crissco515 +CristalAlken +Cristierra +CriticalX +Criticizer +Critter J +Crittx +Crixos +Crixus x +Criyosphinx +Crna +Crna Gora +CrnerMcGregr +Croc +CrocDanDee 1 +Crocalu +Crocketeere +CrocoMaster +Cromeh +Croney +Cronsus +Cronus +Cronz +Croogus +Crooked Path +Crooklyn +Crooshtwoost +Crosby Alt +Crosem +Cross +Cross Me +Crosswinds +Crouchling +Croupz +Crow +Crow Mn +CrowBox +Crown +CrownConvict +CrownRoyal84 +Crownescent +Crowride1873 +Crowther +Croww +Croxy +Crozier +CrspyPigeon +Crudelismo +Crudivore +Crue Xena +Cruel Cub +Cruel Irony +CruelVictory +Cruelcanary +Cruixiote +Crumbledoor +Crumblers +Crumbways +Crunch7O4 +Crus ty +CrusH-HK +CrusadeKlr +Crusadershot +Crush Depth +Crushed +Crushed Guam +Crusher9783 +CrusherWake +Crushersun +Crushertaco +Crushs noob +Crust Cape +Crustie +CrustyDuckr +CrustyPusy +Crustysnot +Crux +Crux da King +Crux25 +Cruxyy +Cruzty +Cruzzetbuzz +Crwfrd +Crxk +Crxsty +Cry +Cry0nman +Cry4help +CryIs0gp +CrySupply +Cryge +Crygechamp +Crying +Crying Cutie +CrykeeOwO +Crynceps +Cryo +Cryo Chamber +Cryogen +Cryogenica +Cryogenica 2 +Cryogenist +Cryorah +Crypthead +CrypticSlays +Cryptling +Crypto +CryptoKitty +CryptoMellow +Cryptonomico +Crypzor +Crysaki +Crysh +Crystal +Crystian +Crzy Mia +Crzyarab +Csajka +Csk x +Cssy +CtCandyRandy +Ctclaire999 +Cteel +Ctep31 +Cth ulhu +Cthrek +Ctrengereid +Ctrl +Ctrl F +CtrlAltDel x +Cuada +Cuat3 +Cuatche +Cuattr0 +Cub Will +Cuba Sybre +Cubans +Cubed +Cubet +CuckChuck +CuckW +Cuckgex +Cucumbers +CudddlyBear +Cujoh +Culemborg +Culinair +Culls +Culltist +Cultured +Cultzy +CumHeretic43 +CumanderZili +Cummy Sigil +Cumpaska +Cunnavathing +Cunny +Cuno +Cuolua +Cuong +Cup Noodle +Cup Of Chai +Cupaplayer +Cupcakess +Cuppalimmy +Cuppi +Cups +Cupthebooty +Curaga +Curble +CurdTuttrboi +CuriPolymath +Curll +Curls +Curlx +Curly +CurlyTwist +Currancy +Curry Storm +Curryleaf +Curse +Curse on me +Cursed +Cursed Chump +Cursed Nm +Cursed Side +Cursed ll +CursedOwned +CursedRNG oO +Cursedpotato +Curt +Curtis Jones +Curve +CurvedHorn +CurvyChcken +Curzonn +Cushco +Cushdy +Custom +Custom Jr +Custom Sock +Custom TK +CustomGFX +Cute +Cute Cat lol +Cute Paunch +Cute n o o b +CuteClit +Cutegirluwu +Cuti +Cuties +Cuttableedge +Cutting edge +Cuttl +Cuttle +Cutty Sarks +Cuuap +Cuult +Cuz im Jones +Cuz im jesus +Cuztom +Cuzzo94 +Cuzzu +Cvanz +Cvbgn +Cvrkster +Cvrsn +Cw90 +Cwab +Cwazza +Cweavy +Cwer +Cwick +Cwioktopus +Cxffee +Cxld +Cxnnor +CyaCyaCyaCya +Cyal8rnub +Cyan +Cyan Ablaze +Cyasoon +Cybb +Cyber Mind +Cyber n Bug +Cyber172 +CyberJesus +CyberSlave18 +Cybernautron +Cybernike +Cyberpope +Cyborg Musk +CyborgHex +Cybron +Cycling +Cycling Road +Cyclogy +Cyclone2498 +Cycloner5 +Cyclopedia +Cyclops +Cycolon +Cygni +CykPyk +CykaNuggetzz +Cyldan +Cym +Cymatics +Cymbaline +CymricCat +Cyn2k +CynAcolyte +Cyncess +Cynda +Cyndaquiill +Cyndee +Cyndrakial +Cynhi +Cynic +CynicalSilas +Cynocephali +Cynognathus +Cynosure +Cynox +Cynthaen +Cyodot +Cyous +Cyox +Cypersilver +Cypher Blue +Cypress +Cypress H1ll +Cyralx +Cyrax +Cyrax314 +Cyriel +Cyrodiil22 +Cyroenix +Cyruscomrad +Cytain +Cytryn7 +Cyuh +Cyum +Czacha +Czar +Czar I +Czar Trump +Czechmate +Czha +Czivend123 +Czk +D A I J I N +D A L M +D A M 0 +D A M I A N +D A M N L0L +D A N G I T +D A N N Yy +D A T H I T +D B A +D B Z pker +D Blo +D Clawz +D Darkblader +D Derbles +D Dragon124 +D Duberstein +D E C O +D E F Q 0 N +D E F Q O N +D E R P +D E V I N +D F U Q +D I Q +D I R T Y Ko +D J Diddles +D Long +D M T Elves +D O D +D O M M E L +D R 6 K E +D R l Z Z T +D Rack4 +D S A V +D Squarius +D U R K +D Wilson +D Wreck +D a mo +D a r t s +D a rk +D a u t o +D a v i d +D amz +D arking +D arkoz +D as +D ashing +D avey +D axe +D db +D ebol +D ecimate +D eej +D eek +D eep +D eez +D en +D enial +D entist +D i l a n +D i x o n +D i zz y +D iesel +D iizzy +D imi +D imitri +D onda +D onger +D oo l ey +D op e +D utchgr +D-D-A +D00DLES +D00dey9 +D0CTOR +D0GS0NG +D0NE0 +D0NPABLO +D0PESIC +D0any +D0inkleberg +D0lNK +D0llynho +D0n vi0lad0r +D0nte +D1APAM +D1GG00BIITTI +D1P +D1ZZY +D1ngu5555 +D1no +D24L +D2Aina +D2nzo +D2theOnTRUMP +D3 Washup +D33L1N +D3ATHBYPI3 +D3ATHVENG +D3C +D3C0D3D +D3DW8 +D3IVY OSRS +D3VONSHIRE +D3ZZi5 +D3ceptions +D3precated +D3thbyzebra +D3v1lBoy +D3vilmar3 +D3zert +D4H4EK3YSM +D4TE +D4VO +D4n0118 +D4ng3r Suca +D4nkmemel0rd +D4nnyy +D4rels +D4rk +D4rth +D7NNY +D9 +D9R +DA ODB KIDZ +DA0IST +DA3N33RY +DA4N +DAD563884271 +DADDYS IR0N +DAHDB +DARCHANG3L +DARGON +DASH +DAWGPOUND +DArtspret +DBA Paulo +DBKangaroo +DBO90 +DBOL TRICEPS +DBUZZ +DC Flubber +DC-8-51 +DCreek +DD 214 +DD G +DD2I4 +DDAlt +DDSurWrists +DDandy +DDoS Wildy +DDune +DEFENDPOPPNK +DEFlNE +DEM0L +DEM0NIC +DEPRINS +DESPA SIITTO +DESPAlRGE +DESTYLAT +DFez +DG 00 +DGAF +DH Marker +DH btw +DHIBZ +DHSC4EVER +DHally +DHlN +DHoShow +DIDZZ +DIETDRDIET +DINGO SCUM +DIORITIC +DIORITlC +DIRTYags +DISAPRIN +DITMANM0DE +DIVINExNOVA +DIY Ele +DIY Jamie +DIY Salsa +DIY Shane +DIY Steo +DIYIronFeBTW +DIYRevelled +DJ Bop +DJ Cranston +DJ Heiko +DJ Korsakoff +DJ Llama +DJ Pen is +DJEDDIK +DJK Daniel +DJKALLE ANKA +DJKrampz +DJMileyCyrus +DJMuscleBram +DJOFULLIN +DJSeinfeld +DKHo +DKJN +DMM 2 07 +DMM Gp Swap +DMM Ryu +DMT Dad +DMT Satan +DMTDAN +DMTe +DMagnum 10 +DMessengerS +DN Atro +DN20 +DNFL +DNLD +DO0FY +DOGELII +DOITESTEVEN +DON FIJI +DON VALTEE +DONG GOLEM +DONJOHNNNY +DOOMBRlNGER +DOOMSlayer +DOSNE +DP776 +DPRNS +DPS Disciple +DPvM +DPvM Jordan +DQ9 +DR PAAAK +DR VABA +DRAEG0 +DRANG3 +DRD31 +DRFL +DRGNSLAYER85 +DRIEST RNG +DRL0NGD0NG +DRLGspace +DRNKN DWARF +DROPPEDITALL +DRTY +DRUNKIDIOT +DReelest +DRegi +DS Stolen +DSHeavy +DStat +DStroud +DSyndrome +DT5 +DUMB +DUSKBLADEL0L +DV 8 +DV trekpik +DVa +DW Gunthie +DW24 +DWlGHT +DXQIWOL +DXXM +DYao +DZ o_o +Da Bomb 149 +Da Buddah +Da Iron Jedi +Da Man 65 +Da Nils +Da Puppy13 +Da Sniper007 +Da T Virus +Da d dy +Da t +Da then bh +Da1ton +DaBears +DaBoz +DaBurg +DaCatBeam +DaCigarMan +DaCuddy +DaCult +DaDangus +DaDude +DaFatManDan +DaFeesh +DaHumanClown +DaIronBooty +DaIton +DaJaVu +DaLegendary +DaPootz +DaRKi +DaSernet +DaSheepFtClb +DaTr3w +DaVinciss +DaaChronic +Daaak +Daallas +Daan +Daanilio +Daanncorr +Daavos +Dab Thirty +Dab then pvm +Dab0mba +DabANOMICS1 +DabDabDan +DabInMyEye +DabTornado +Dab_nScape +Dabbadank +Dabbe +Dabbers +Dabbie Duck +Dabbin Dolo +DabbinDonut +DabbingBrb +Dabe +Dabe Sucks +Dabei +Dabomb 13 +Daborn92 +Dabos Weenie +DabsWithDan +Dabsmoke +Dabsncats +Dabsndogs +Dabton +Dabvape420 +Dacaedia +Dacc +Dachowski +Dackel +Dackenerino +Dacune +Dad Goals +Dad Sean +DadBurrys +DadGoingMad +DadLeft +DadRanarrWay +DadamoSte +Dadbackward +Dadbackwards +Dadbod4lyfe +Daddaforce +Daddy +Daddy Bundy +Daddy Chaman +Daddy Chubs +Daddy Danger +Daddy Dead +Daddy Drow +Daddy Oreo +Daddy Smit +Daddy Spoon +Daddy Yurdle +Daddy sandro +DaddyDeagz +DaddyDylo +DaddyLemming +DaddyMac +DaddyMars +DaddyNemmy +DaddyPig406 +DaddyTowel +Daddyfied +Daddyplease +DaddysLoad +Daddyspie +DaddyyDong +Daddyz +Daddyz Clean +Dadevil1616 +Dadfield +Dadi415 +Dadorii +Dadosaur +Dads +Dadukez +DadurQa +Dadyankee3 +DaemonGunner +DaemonTool +Daemonmage +Daemonrds +Daenrys +Daep +Daewolo +Daeyalt Ess +Daeye +Daez 95 +Daf Arch +Dafetsch +Dafney +Dafo322 +Daft Punked +DaftDemon +DaftPun +Daftmoul +DafttPunk +Dafuggg +Dafy +Dag DaLooter +Dagannot hs +Dagannuts +Daganoth Rex +Dagathar1 +Dagburn +DaggaNOTKlNG +Dagger93 +Dagggg +Daggou +Daggz +Dagin +DagkingV2 +Dagnel Daddi +Dago +DagobertTT +Dagoth Vemyn +Dagsi27 +Daguar +Dahlareen +Dahls +Dahlson +Dahmonkey +Dahrmata +Dahrr +Dahumbug +Daijoukay +Daiju Spede +Daiktusrenku +Daileee +Dailiana +Daily Grind +DailyDoomer +DailyDosage +DailyPog +DailyScape99 +DailySharts +DailyShelfer +Dailytoker +Dain +Dainius +Dains +Daipers +Dairychuk +DaisOfHavoc +Daiseido +Daiski +DaisukeJigen +DaisyApple +DaivdFW +Daiw +Dajmkryss +Daka +Daka Alt +Dakai +Dakay +Daklozenkrat +Dakotas +Daksu +Dal3y +Dalacks +DalaiLlama +Dalanes +Dale Dobec +Dale G +Dale HC BTW +Dale Winton +Dale1612 +Daleferd +Dalejamesw +Dalek +Dalek Cookie +Daley_Dose +Dali176 +Dalkz +Dalls Beep +Dalmatian +Daloomi +Dalrak +Dalski +Daltficiency +Dalton +Dalton4theft +Dalton_LB +Daltonnn +Dalundo +Dalzii +DamDude +DamSplash +Damage +Damarquis +Damberson +Damen +Dameon xd +Dami +Dami-an +Damiaen +Damian_Xx +Damish +Damlotz +DammitHarry +Damn Evil +Damn God +Damn its Sam +DamnItHarlod +DamnSexy +DamnViton +Damned +DamnedDaniel +Damngoodsoup +Damni t +Damo +Damo is free +Damon +Damp Memes +DampBucket +DampForklift +DampMongot94 +Dampener +Damzos +Dan Bad +Dan Craig +Dan Daoud +Dan Gleesac +Dan H +Dan M +Dan S +Dan xo +Dan-Reijden +Dan120201 +Dan452 +Dan646464 +Dan91 +DanAsker +DanAye +DanBTW +DanChan1101 +DanGreenFan +DanGur27 +DanMaxd +DanMingo +DanO_o +DanOfCumelot +DanPJ +DanRickshaw +DanTheM4N +DanTofoo +Danboy +Dance +Dance for XP +Danced +DancingForGP +DancingRa1n +Danco +Dandrikis +Dandwc88 +DaneDaddy99s +Danea +Danelele +DanernesLys +Danex85 +Dang +Dang It +DangFloopity +Dangelboi +Danger Swign +Danger Zoneh +DangerBear +DangerGlutes +Dangerouz +Dangeruss +Dangerxi +Dangerz0ne15 +DangitBobby +Dani +Dani Cute +Dani D +Dani Dark 0p +Dani007 +Dania +Danieelius +Daniel +Daniel Mcc44 +Daniel OSRS +Daniel12xx +DanielSumtin +Danielbisgod +Daniella +DanielleOfc +Danielmcken1 +Daniels +Danielwat +Daniiieell +Danijenn1211 +Danilin +Danimal +DanisH96 +DanishAdonis +DanishGoat +Danje +Dank +Dank Chef +Dank Exp +Dank Perp +Dank Tigzy +DankDylShpil +DankMagic +DankSavage99 +Dank_Mcnasty +Dankdank96 +Dankdog +Dankdynasty +Dankey +Dankfool +Dankleburgh +Dankstanky +Danktrees +DankumZ +Danky Kwuarm +Danletics +Danleypa +Danlord3222 +Dann +Dannda +Dannebrog +Dannel +Danney +Danngy +Danniel +Dannk +Dannny +Dannum +Danny +Danny Dubs +Danny Dvito +Danny Mate +Danny P +Danny Pudi +Danny m8 +Danny wtf +DannyDeleto6 +DannyK +DannyKjr +DannyPho +Dannygem +Dannytrol +Dannyw +Danog +Danoj +Danol +Danomeva +Danoontje +Danozz +Danratty +Danrow +Danrue +Dans +Dansayeagle +Danski261 +DanteExitium +Danxdoo1 +DanykaNadeau +Danzai +Danzig +Danzoler +Daofather +Daoko X +Dapper +Dapper Hades +Dapper Jr +Dappest +Dappi +DaquanNiguan +Daquantaro +Daquicker +Darbinism +Darc +Darc Sport +Darcy +Darda09 +Daredevil595 +Dareme95 +Daremo +Dareya2 +DarfPlageus +DarfWantWarp +Darimy +Dario +Dario hax +Darion +Dariukas +Dark +Dark X +Dark Alcyte +Dark Aloy +Dark Curtain +Dark Iron69 +Dark Jaxol +Dark Kadabra +Dark Kill L +Dark Knig ht +Dark Kurama +Dark Peter10 +Dark Rabbit +Dark Ranqe +Dark Side +Dark Specter +Dark Stone66 +Dark Tetrad +Dark Totem +Dark Uzi +Dark Veidar +Dark Wegener +Dark Xarpus +Dark kamui +Dark lll +Dark1437 +DarkAether +DarkEater +DarkElf135 +DarkEmerald +DarkGraceful +DarkHoodGIM +DarkKn1ghts +DarkMerliin +DarkNut393 +DarkOwI +DarkReapingX +DarkReign +DarkWizard +DarkXiphles9 +DarkZulu97 +Dark_Auth +Darkang3lpkx +Darkao +Darkarmy40 +Darkbox777 +Darkbright +Darke Hand +Darkemissery +Darken Devil +DarkenRahlrs +Darker +Darkest Kind +Darkest Syde +Darkfanime +Darkflash15 +Darkgutz +Darkhal +Darkine +Darklord4211 +Darknapster +Darkp0wnz +Darkphil007 +Darkpupitar2 +Darkrai +Darkraven368 +Darkscorpio5 +Darkseance +Darksense +Darksim10 +Darkskiller +Darksn0w +Darksnoweb +Darksocks1 +Darkst4ar +Darkstar078 +Darkturbo +Darktyranno +Darkwrath43 +Darkyr +Darlin g +Darling27 +Darma +Darnic +Darquain +Darras +Darren T +Darrens +Darriann +Darse +Darsehole +Dart Slayer +Darth +Darth Kas +Darth Shiroo +Darth Spade +Darth Val +DarthNevidia +DarthSpliffs +DarthWrecker +Darthe +Darthodium +Darthonion90 +Darthrodger +Darthruneis +Darthshea +Darucell +Darush +Daryl +Darz +Darzix +Darzo5 +Das Idle +Das It Maine +DasGoose +DasReich88 +Daschiva +Dascrez +Dasgirl09 +Daspwn +Dasrx RNG +Daszler +Dat Geezer +Dat2eWoord +DatBoiNibbe +DatBoyLoy +DatGuySteve +DatIronNinja +DatNeck +DatPeko +DatYeet +Data +Data Diddler +Data Privacy +DataDruid +Datadyne +Datames +Datcookie34 +Date +Dathx +Datis +Datoxicate +Dats +Datskai +Datting +Dattos +Datuk +DaturaTrip +Daubs +Daud +Daughters +Daunt +Dauntless +DauntlessXav +Dauth Elda +DavSko +Davaflav +Davai +Davantage +Dave +Dave From Au +Dave Hooray +Dave J +Dave Mario +Dave Senpai +Dave The Egg +DaveAckery +DaveDaBeast +DaveDorvis +DaveLister +DaveYognaut +Davebarbaren +Davedication +Davedude +Davej86 +Daveken +Davesty +DaveyB0nes +DaveyWSM +David +David Co +David Duffs +David Ortiz +David R333 +David007 +David2699 +David4755 +DavidKinaMan +DavidPH +Davidisiscoo +Davidopathy +Davis751 +Davlan +Davo +Davord +Davoron +Davros70 +Davshing +Davu +Dawaj Lama +Dawg Dynasty +Dawkins +Dawn +Dawn Destiny +Dawn Era +Dawn Summers +Dawn Wall +DawnEverbane +DawnSwanMon +Dawna +DawnfaIl +Dawson141 +Dawtrix +Daxidol +Daxon +Daxx95 +Daxxzy +Day Dreams +Day Lightz +Day1ofNoFap +Day6 +DayJarVu +DayOff2JOff +DayStar Turk +Daydrifta +Daye Xero +Daykillz +Dayman_GIM +Daymien +Daynnn +Daysi Darcey +Daystar +Daytrip +Dayuf +Dayveeeee +Dayz of Iron +Dayzd1 +Daz3dnBlaz3d +Daze +DazedDave +DazednConfsd +Dazzler95 +Dazzz +Dbeatz +Dbewt +Dbmx +Dboot +Dbricke +Dbz Pride +Dc B L I N D +Dc Hakkarn +Dc IronMan +Dcaravan +Dced +Dced at Corp +Dception +Dcing +Dday6Jun1944 +Ddestroyer56 +Ddos +Dds4theko +Ddsing +Ddsme +De Algerijn +De Baardman +De Eryngy +De Fishy Guy +De Gennaro +De Hoppert +De Jam +De Krikke +De La Trey +De Marco +De Max +De Mechelaar +De Pette 69 +De Redacteur +De Sam Matie +De monic +De stoutsten +De us +De1icioso +DeAndre +DeDawgTubb +DeEgis +DeFatCactus +DeGiano +DeGreen +DeHijskraan +DeIronMan +DeIronedMan +DeKawika +DeLL +DeLooter +DeLouuu +DePope +DeTrixzz +De_lemme10 +DeaTH +Deacey +DeaconDrew +Dead +Dead Baldy +Dead Bozo +Dead Chilli +Dead Easy +Dead HC Here +Dead Her0 +Dead I Guess +Dead Mum +Dead Policaj +Dead Psyc +Dead Sellout +Dead Ticks +Dead XVIII +DeadDogRed +DeadGhost +DeadKelly +DeadNowM9 +DeadPickle +DeadPower +DeadPuto +DeadRealSoon +DeadSanson +DeadSlice +DeadSmog3 +DeadWife +Deadarrow99 +Deadbeater +Deadblinx +Deadened +Deadfallen +Deadlft +Deadlift +Deadliftjr +Deadly +Deadly Pixel +DeadlyAnt +DeadlyBatz +DeadlyDJ +DeadlyDrinkr +DeadlyHit +DeadlyNecros +Deadman AF +Deadness +Deadpaal +Deadrango +Deadwool +DeadxProof +Deaf +Deaf Person +Deaf RScaper +Deafmau5 +Deafs +Deakien +Deakz +Deal or nah +Dealing +Dean +Dean Jac +DeanRs +Deandelouest +Deantotheo +Deaptic +Dear +Dear Deer +Dear no one +Death +Death Devil +Death Eaters +Death Is Fun +Death Loco +Death Qweef +Death Rainer +Death0fyou +DeathByRC +DeathPanda +DeathPen +DeathSurgenc +Deathbyclick +Deathcloude +Deathcore +Deathduspart +Deathfuzz13 +Deathhope666 +Deathism +Deathit55 +Deathmast333 +Deathomen +Deathrattle +DeathsCaII +DeathsCoffer +Deathscyt56 +Deathstarlol +Deatths +Deb0wer +Debauchery +Debb +Debdu +Debil Missed +Debiruss +Deborla +Debug +Debwani +Deca +Decapacitate +Decard Cain +Decarium +Decath +DecayedWrath +Decca +Dece1ve +Deceive +Decent Drugs +Decerate +Dechmann +Decides +Decim +Decim-san +Decimate +Decius Maxim +Deckiez +Deckler +Declare +Declined +Deco Himself +Decolonize +Decomposed +Decon +Decs +Dectron1 +Ded Ronald +Ded Smithy +DedClicks +DedVittu +DedWilson +DedZap +DedZeppelin7 +Deddo92 +Dedfin +Dedge Inside +Dediabl0 +Dedicated +Dedicated XP +Dedmoo +Dedressing +DedsetLegend +Dedville +Dedzone +Dee +DeeLizard +DeeLuxe +DeeZe +Deedeedee630 +Deedlebees +Deeego +DeeezNats +Deejay +Deeku vaan +DeelDoughs +Deemush +Deep +Deep Medi +DeepInUrMum +Deepika P +Deepinuh +Deepnsider +Deerboy7I7 +Deerhunt03 +Deerkl +Deerski +Deerskin18 +Deevos +Deeyja +Deez Mangoes +Deezima +Deeztroyer +Deezy44D +Defaultbomb +Defaulted +Defeat Evil +Defeater +Defektas +Defelorn +Defence42 +Defensief +Deffi +Defib +Define Pain +Deflexus +Defloat +Deflorator +DefoNotKiwi +DefoNotSpoon +Defog +Deformedhell +Defqonlord +Defrosted +Deft +Deftones +Defund +Defunto2 +Defy Limit +Defyinq +Degak +Deganti Upe +Degas +Degen Darra +Degen Ryu +DegenGod +DegenRetard +Degeneraatio +Degenic Neet +Degenomics +Degradedd +Deguns +DeiAx +Deidera +Deifi +Deimoss +Deinsmeins +Deiron Tyson +Deitonus +Deive +Deiviiz +Deivis +Dejagoo +Dekeyser +Dekkens +Deko +Dekul +Dekylex +Del1nquent +Del4no +DelaIron +Delaey +Delay +Delciotto +Deldeen +Dele +Deleted +DeleuzeSucks +Deleven +Delga +Delger +Delhaize +DeliMeats +Delic +Delicoffee +Delimain +Delirah +Deliyria +Delkku2 +Dell +Dell De Dul +DellaRS +Dellamor +Dellies +Delmar +Delmaro +Delonius +Delphan09 +Delskiii +Delsym +Delta +Delta 516 +DeltaCloud +DeltaEpsilon +DeltaPapa +Deltaskull +Deltawye +Delten +Delusional +Delusionnn +Deluthul +Deluvial +Deluxe5 +Delvex +DemSkillsDoe +Demander +Demboo +Demco +Demerlay +Demetre130 +Demi +DemiGodKempo +DemigodI +Demising +Demmegod +Demolidor +Demon +Demon Albarn +Demon Flare +Demon Plate +Demon RS +Demon1793 +DemonWolf1 +Demon_Matrix +Demonaly +Demonas +Demonboys1 +Demoni +Demonic +DemoniclockR +Demonleader8 +Demonslay335 +Demonteats +Demoted +Dempa +Dempeanut +DempseyRoll +Dempsters +Dempsu +Demyze +Den Bever +Den Duivel +Den Illya +Den1z +DenZelouZ +Denaelc +Dench Bee +Denclosure +Denferok +Denfoe +Denggly +Denglish +Denis +Denix6 +Denizenn +Denkil +Denkue +Denmarkian +Dennaro +Denneny +Dennis +DennisWilbur +Dennisfr +Dennispanda1 +Denny +Dennyispro +Denonweff +DenouncedGod +Denoxite +DenseLayer +Denssoni +Densu +DentalMental +Dented +Dentistry +Dently +DenverHockey +Deny +Deny92345 +Denza93 +Deon +Deoo +Deoxy_19 +Deoxys39 +Depdada007 +DependaAF +Depends +Depenenkal +Depletion +Deplox +Deprimes +Deprimir +Depster +DepthStryder +Deputy Mibo +DeputyDwigt +Der Hungrige +Der Panda +DerPunkt31 +Derbados +DerbyDerbs +Derdel +DerekBarnett +DerekEmKay +DerekWins +Derenity +Derick +Derived Hope +Derk Danger +Derkalurka +Derkila +Derkle +Dermijiny +Dern Swan +Derot +Deroy +DerpCanin +DerpDeezy +Derpmoil +Derptimusbro +DerpyClayDog +Derrick +Derrick Rose +DerrickC145 +Derrik +Derrin +Dertay +Des0rg +Desaus +Descendence +Desconectado +Desear +Desert +DesertAmulet +DesertEagle +DesertFlower +Deserve +Desi +Desigium +Desinger +Desinteresse +Desire +Desk +Desley +Desn1q +Desoroth +Desper +Desperados +Despitous +Despot +Dest +Destab +Destinneh +Destiny Goat +Destr0i +DestroyButts +Destructoid +Desuelle +Desuhmate +Det BabyLegs +DetRedWings +Detain +Detects +Detectum +Determind888 +Detonati +Detone +Detriment +Detrimental +DetroitSux +Deugeniet +Deunek +Deur NL +Deurloos +Deus +Deus Esq +Deus leto +Deus lux est +DeusFerox +DeusXQuinoa +Deuxth +Dev Jacob +DevMoney420 +Devanar +Devb0t +Develinside9 +Develique +Devidedby0 +Devika +Devil +Devil Horns +Devil lnside +Devil9394 +DevilOfheavn +Devildog +Devilege +Devilgod +Devilish +Deviljin583 +Devilman +Devils +Devilsbkb0ne +Devilsjoker +DevinTheDude +Devinchi +Devious +Devise +Devizer +Devo +Devon Btw +Devoted I +Devotion +Devoured +Devourkitty +Devry Cain +Devstated +Devv N +Devvy UwU +Dewa +Dewarping +Dewiro +Dewitten420 +Dewk +Dewrunk +Dewsk1 +Dewts +Deww +Dex Territy +Dexby +Dexderp +Dexlan +Dexter +Dexter Lou +Dexterity +Dexxaz +Dexxtrouss +Dexy Fiend +DexyDean +Deykota +Deyou +Deyron +Deysean +Deyvyejones +Dezerthuntar +Dezi-VII +Dezkor2 +Dezmezz +Deztroyer +Deztroyer 0 +Dezzu +Dflow023 +Dfs Sfs +Dfuks +Dfw +Dgalaga +Dgref +DhRecka +Dhae +Dhaegar57 +Dhaeqriyil +Dhaggz +Dhalsim +Dharek +Dharma Van +Dharoc +Dharok +Dharok 0bama +Dharok Derek +DharokHardOn +Dharokbomber +Dharoker +Dharokz +Dhavy +Dhides +DhingusKhan +Dhon +Dhon Do +Dhor +Dhr Leon +Di vau vand +DiaRelent +DiaThresh +Diabalo +DiabeticKid +DiabeticPhuk +Diabetucus +Diablo +Diablo47741 +Diablosis +DiabolicDead +Diade +Diagnosis +Diagonlane +Diah +Diako +Diako Gyan +Dialga +Diam0nd01 +Diamega +Diamond +Diamond D +Diamond Jozu +Diamond2192 +DiamondScott +Diamondback +Diamonds +Diamonds Jr +Diamonds lit +Diamoniakmep +Diampromidi +Dianakins +DianasaurEgg +Diane +Diapeetikko +Diaper Dan +Diaresta +Diariez +Diarrhea +Diarrhea Tom +Diart +DiaryNoob +Dibbo +Dibbu +Dibidos +Dibidus +Dibsis +Dibsis CoMa +DibtheLegend +Dibudabudi +Dibyel +DiccEat +DicedBrotito +Dicer +Dicey ReRoll +Dicio +Dick Jones +DickNBallin +Dickbruiser +Dickeroo +Dicko +Diclo Force +Dicnar +Dicso +DictatorNL +Did You Fart +Did You Try +DidAnalOnce +DidISayWeast +DidNotDieBtw +DidUJustBgs +Didavoo +Diddle Drip +Diddlybopp +Diddmeister +Didi +Didnt +DidntAsk +Didny +Didsome1say +Die hard 66 +DieAntwoord +Dieby +Died4Hides +DiedRank +DiedSierra +Diedrrr027 +Diegoide +Dien0 +Dieno +Diesel +Diesel Bill +DieselPump +Diet Andy +DietSquid +Dietch +Dieu +Diffindo +Diffy +Dig Bick 420 +DigBicker +DigDaniel +DigOlBick +Digestive +Digger +Diggernick32 +Digghass +Diggy +Digi1al +DigiDestined +DigiFlisp +Digifreak045 +Digironimo +Digit28 +Digital +Digital Age +Digital day +DigitalGamer +DigitalKillz +Diglett Dave +Dignace +Dignity +Digtalcarrot +Digweed +Digyeety +Dihl +DiiK +Diiferent +DiiirtyDog +Diisphoria +Dija +Dikk Mabbutt +Dikkaz +Dikke +Dikke Hobbit +Dikke Kei +Dikken +Dikuufd +Dil Pickle +Dilbo +DildoBagguns +Dilexro +Dilfslayer +Dill0n +Dillaz +Dillbert +DilleFlute +Dillhen +Dillon +DillontheFox +Dillusion94 +Dilly +Dillywacka +Dillzpickl +Dilogos +Dilph +Diluzion +Dilvy +Dilx +DimDimz +DimJangle +DimKills +Dimaa +Dimathys +Dime +Dime Daddy +Dime Skate +Dimebag217 +DimitriosMVP +Dimmu +Dimmy +Dimples +Dimwits +DinFulaJavel +Dinamite +Dinari +Dindu +DinduNuffen +Diner +Ding-A-Ling2 +DingDong +DingDongDell +Dingbat Rat +Dinger30 +Dingle Eater +Dingus +Dinh +Dinho1 +Dinieras +DinkeLBerrG1 +Dinkerwoltz +Dinkis +DinkleBrrgh +Dinkleberg +DinoBoy7 +DinoSnore +Dinomite +Dinoparrot91 +Dinorock +Dinosaur +Dinostrong +DioBrandoXx +Dioden +Diogaite +Diogo +Diogun +Dioor +DiorTemplar +DiorTheGreat +Dios +Dios world +Diosdado_12 +Dioxins +Dioxis6 +Dipdadronan +Dipical +Dipli +Dipolio +DippaDave +Dippoldism +Dippy +DippyMcshit +Dipshit Dan +Dipyo +Diq-In-A-Box +DirectDesire +DirectDsLcul +Direwolf +Dirk +Dirk Stryker +DirkDigglr +Dirkieflurky +Dirol +Dirt +Dirt Shark +DirtAss +Dirtbag +Dirtbikerpro +Dirtboy345 +Dirtjogger +Dirty +Dirty Dozen +Dirty Nuts +Dirty Nwah +Dirty Pack +Dirty Tampon +Dirty Wit +Dirty Wookie +DirtyDoc +DirtyGeUsers +DirtyGlock +DirtyKo +DirtyLube +DirtyOldMan +DirtyShire +DirtySouthNz +DirtySpade +DirtyWata +DirtyyIron +Dirun +Disabled +Disaster0 +Disasterolgy +Disastro +Disbeliefs +Disc +Disc Chucker +DiscGG +Disclosing +Disclosure +Disco +Disco Mayhem +Disco PvM +DiscoDarwin +DiscoFever +DiscoLars +DiscoTronix +Discoburger +Discodoris +Disconnecct +Disconootje +Discord +Discordian +Discounted +Discoveredx +Discretions +Disentombed +Disfunctie +Disgusting +Diskmedel +Disloyal +Disneyland +Disodrer +Disorderly +Disperse +Disprivilag +DissTeam +Dissidence +DissyReborn +Distained +Distanc3 +Distard +DistinctEvil +District +Distroyer972 +Disturbed +Ditherman +Ditt +Ditt o +Ditto +Ditty +DitzyGranny +Dive Ball +DiveMedic +Divertus +DividedSky +Dividends +Divin3RS +Divine +Divine Dream +Divine Fenix +Divine Furby +Divine Mass +Divine One +Divine Oodle +Divine Sveta +Divine Zaros +DivineLegend +DivineRhythm +DivineShine +Divinenro +Divines +Divinethug +Divinez +Diving +Divinitii068 +Divoky +Divorce +Divxd +Dixed +Dixie +Dixie Pixies +Dixin Yass +Dixon +Dixon Planks +Dixxy +Dixy Wrecked +Diy Dan +Diz_OG +Dizho +Dizk +Dizstruxshon +Dizza +Dizzleslayer +DizzyDan +DizzyPanda +DizzyRnG +Dizzzzy +Dj Dimu +Dj Jordi +Dj Ju +DjNateP +DjSpicyNuts +DjWalkzz +Djacquays94 +Djagzar +Djahat +Djauw +Djavul +Djbeejay99 +DjenCraw +DjentleSoul +Djl0077 +Djmx1000 +Djoefer +Djozztico +Djscoobsta_X +Djunya +Djurfan +DjustinT +DkPepper +Dkafeine +Dkzz +DlAMONDS +DlBz +DlCKE +DlCTATOR +DlDS +DlE MACHlNE +DlNNER +DlONNE +DlPLO +DlRECT +DlSCONNECTED +DlTTO +DlXON +Dlghorner +DliveMarc +Dlorean +Dm8 +DmVinny +Dmage +Dmante +Dmfs +Dmgp +Dmhc +Dmi11z +Dmitri333 +DmkFight +DmkKilla +Dmoe +Dmt Kitty +Dn Dayander +Dn Havoc +DnB Fanatic +Dnc +Dnv +Do It Best +Do It Myself +Do You Zerk +Do ur Best +DoDArmy +DoHerbRuns +DoKZx +DoMeDirty035 +DoMeHardNan +DoSoQi +DoUEvenTank +DoWerkSonn +Doadles +Doajiggi +Dob Au +Dobar +Dobby Hanzo +DobbyGotPwnd +DobbyTheSock +Doboner +Dobster +Doc Doc +Doc Heart +Doc k i n g +DocDingle +DocGiggles +DocMonocle +DocVamp +DocYouSign +Doc_Hershey +Docere +Docs +Docta +Docta Mantis +Docta dean +Docter Brule +Doctor +Doctor Ace +Doctor Bubca +Doctor Exx +Doctor Fail +Doctor Funk +Doctor Fuzz +Doctor Iron +Doctor Krieg +Doctor Luck +Doctor Oby +Doctor Swag +Doctor WormP +Doctor Wylie +Doctor Zeh +DoctorCoc +DoctorHeiter +DoctorKraft +DoctorNutz +DoctorRex +DoctorSquat +DoctorTsom +DoctuhDrew +Docxm +Doddi +Doddy8D +Dodge +Dodge Feet +Dodger995 +DodgersBRAH +Dodgy +Dodgy Player +Dodgy Todge +Dodjomaster +Dodko +Dodo134 +Dodokipje +Dodol +Dodose +DodusNet +Doefos +Doeidoei +Doep +Doesnt +Doesnt Trade +Doetje +Dofric +Dog Fart Net +Dog Myrnac +Dog The Frog +Dog did Meow +DogDiet +DogFlyRatCow +DogLogNogJog +DogShitter1 +DogSoldier29 +DogTag +Dogan +Dogannn +Dogax +Doge +Doge Caravan +Dogecoin100x +Dogesaurus +Dogessa +Dogestyle +Dogfruit1555 +Doggiezz +Doggoat +Doggshit +Doglinsheran +Doglips +Doglover7004 +DogmanJones +Dogplaceman +Dogpoop +Dogres +Dogs +Dogsh1t Main +Dogshit Rick +Dogslayer420 +Dogsume +Dogtogod +Dogzie +Dohace +Dohdee +Dohenus +Dohero +Dohski +Doin It Raw +DoinGodsWork +Doiran99 +Doiu +Doja Chompy +Doja Shark +Dokarius +Dokdo +Doken +DokeyPickle +DokiToast +Dokter Klok +Doktor Onion +DoktorBarber +Dokuganryu +Dokuhime +Dokusei +Dol +Dol Alt +Dolce +Dolerkyo +Dolf +Dolham +Doll +Doll of Evil +Dolle +Dolly +Dollynho +Dollynho Bro +Dolomite +Dolormight +Dolph +DolphinAnus +DolphinPucci +Dolphinl1ck +Dom R +Dom Wong +DomGaz +DomLaurencio +DomYouAll +Domanater105 +Domantass +Domatic +Domccas +Domeeee +DomiGothMomi +Domiinant +Domika +Domimic +Dominate Jr +Dominaton +Dominator541 +Dominatorrz +Dominikus67 +Dominionmake +DominoTerry +Dominos +Dominus Omni +Domiros +Domixin +Domke25 +Domknit +Dommie 07 +Dommy +DommyDucky +Domo Teddy +Domoralized +Domoszlo +Doms +Domstad Slay +Domtoren +Don Abuja +Don Bob +Don Boki +Don Con +Don DingDong +Don Dotta +Don Huono +Don Matt +Don Moochie +Don Persian +Don Robb +Don Sebitas +Don Serrano +Don callum +DonB0t +DonBroco +DonDennis94 +DonMarcino +DonThinKill5 +DonWonTon420 +Donair +Donair Dude +Donal +Donald +Donald Dumps +DonaldTrump +Donaldfact +DonaledTrump +Donantelo +Donate Here +DonateBond +Donato +Donchz +Donda +Dondd +Donderschok +Done enough +DoneThat +Dong +Dong Chan +Dong em Down +DongActual +DongCowboy +DongEater +Donger Lord +Dongi +Donging +Dongolark +Dongs Ahoy +Dongsalad +Dongu +Dongus +Donkerblauw +Donkere +Donkernick +Donkey Kink +Donkey Squid +DonkeySocks +Donkhu +DonldTrumpet +Donnatello +DonnieAssie +Donnieduke +Dono +DonoWho +Donology +DonovanRS +Donsalt +Dont +Dont Be Pked +Dont Heal +Dont Sir Me +Dont You Shy +Dont do dat +Dont skill +DontBeMad +DontBotNerds +DontDieMase +DontDieSans +DontEatMyDog +DontGetDrops +DontHoldBack +DontJump +DontPanicPlx +DontSassMe1 +DontStarve2 +DontTellFeds +DontTouchIt +DontUseFKeys +DontWarnMe +Dontneedbp +Dontyoudoit1 +Donuhtzz +Donut +Donut181 +Donutman +Donvys +Donwcpot +Doob +Doobe +Doobie Doo +DoobleDecker +Doodle Bob73 +DoodleCraver +DoodleTheGod +Doodled +Doodledash +Doodoolist +Doodslag +Doof +Doofe +Doofensmirtz +Doofy +Doogl3 +Doogyplumm +Dookami +Dookers +Dookie +Doom +Doom Bar +Doom Metal +Doom Raiser7 +DoomDoomDoom +DoomFruit +Doomblade +Doomed +Doomed Necro +DoomiShroomi +Doomkid50 +Doon +Doooooobie +DoorDshGamer +DoorTech +DoorToLight +Doorknob +Dooz 12 +Dopamemes +DopaminAbxsr +Dopamine +Dopamine OD +Dopatopia +Dope +Dope Doc +Dope Plugs +Dope Sweater +Dope btw +DopeAnteater +DopeCalippo +DopeDrop +Dopedrift +Dopeturtle +Dopeules +Dopey Iron +Doppa +Doppleganger +Doppleladler +DopplerDank +DoraDaExplra +DoraSweetass +Dordin +Dore +Dorede +Dorg +DorgonPocket +Dorgoroth +Dorito +Doritomancer +Doriva +Dorkydevil93 +Dorman Jr +Dormant Evil +DormiNdaExp +Dorohedoro +Doronn +Dorp +Dorse +DorseHong +Dorthea +DortyKil +Dorvagten +Dory364 +Dos STI +DosEquis +DosKadenas +Dosia +Dosk +Doss +Dostalgia +Dot Death +Dot Head +Dot_Tea +Dothalican +DottySloth +Douane +Double +Double CupMc +Double Drop +Double Take +Double agent +DoubleBrowns +DoubleDeezus +Doubleb011 +Doubledonk +Doubt +Doubt It +Doubted Pyro +Doug +Doug Salt +Douglasotto2 +Dougoboy +Doujinmoe +Douq +Douyin +Dova_sage +Dovahkiintim +Dovahkyng +Dovitello +Dovydas54 +Dowatnow +Down +Down Vote Me +DowniePatrol +Downland +Downlifter +Download +Downtown +Downworld +Dowzi +Doxus +Doxxme +Doxy +Doye +Doyer1 +Doyers +Dozck +Dozerdayne +Dozerrrr +DpittmanIM +Dqzi +Dr 7 +Dr Atsum +Dr B3rry +Dr Bading +Dr Barty +Dr Butt Love +Dr Caccon +Dr Camembert +Dr Cremaster +Dr Crumpet +Dr DO0M +Dr Edy +Dr Flipflops +Dr Gainz +Dr Geyseks +Dr Glottis +Dr Gotham +Dr Gulak +Dr Harry Nut +Dr Ivar +Dr Jago +Dr Jerry +Dr Kenchi +Dr La Scotte +Dr Lulu +Dr Madv +Dr Mawffle +Dr Melons +Dr Mikey +Dr MonaLaser +Dr Mustacho +Dr Mustard +Dr NFC +Dr Neuron +Dr No Life +Dr Oreo +Dr PFAFF +Dr Phil +Dr Plebeian +Dr Quirke +Dr Rave +Dr Robster +Dr Rum +Dr Shook +Dr Siesta +Dr Slayer +Dr Stamps +Dr Swaggins +Dr T e a r +Dr Tanner +Dr Volts +Dr Will MM +Dr Yosty +Dr Zeby +Dr Zeh +Dr Zimm +Dr obZen +Dr smithing2 +DrAsTiiC +DrBeast +DrBen50 +DrBigSang +DrBlackshell +DrBlumpkinz +DrBuckFitchs +DrButter +DrC0X +DrChezz +DrCrunch13 +DrDRespect +DrDankMan +DrDankRip +DrDemitrius +DrDennisMD +DrDitalini +DrDoddi +DrDruen +DrEfficient +DrFlobe +DrFognog +DrHugecookie +DrJoose +DrKayzed +DrKevinn +DrKiloGram +DrKush69 +DrKushBurner +DrLoomis +DrLuckyacorn +DrMatthie +DrNachtiga +DrOly +DrPeppermmm +DrPhil2019 +DrPhineas +DrPoopstein +DrProfess0r +DrRift +DrRipStudwel +DrSevens +DrSkunkPhD +DrSquanto +DrSwag +DrWodahs +DrWoolyNips +Dr_Olusegun +DraCoNiiaN +Draacaryss +DraakSeviper +Draakmonkey +Drac0claws +Dracarus +Dracaryys +Draccnor +Drache104 +Draciel +Drack3d +Drackon +Draco +DracoGhost +Draconian111 +Dracote +Dracts +Dracula50125 +Draeghem +Drag Puff +DragSyndrome +Dragen +Dragen Ballz +Dragers +DraggSlayaa +Dragnarok +Dragneel +Dragnipurake +Dragnkllr233 +Dragon +Dragon Boots +Dragon Brew +Dragon Gras +Dragon Imp +Dragon Not 6 +Dragon Sword +Dragon Those +Dragon7998 +DragonAxePlx +DragonDrew +DragonKlaas +DragonPrime +DragonSpayer +Dragonbait4 +Dragonboy691 +Dragoncore74 +Dragonfeir +Dragonflew +Dragonheat46 +Dragonkin892 +Dragonkingiq +Dragonlear1 +Dragonluv16 +Dragonmake +DragonoidA2 +Dragonrains +Dragonrune16 +Dragons Iron +Dragonslayaz +Dragonstompy +Dragonstone +Dragonvirse +Dragonz +Dragonz Fury +Dragoon +Dragoon0517 +Dragoonalfa +Dragoonhuntz +Dragoonnoth +Dragoscale03 +Dragq +Dragster5300 +Draind +Drairi +Draiserman +Draithus +Drakanelf +Draken Feest +Drakenwold +Drakesh12 +Draket +Drakhom +Drakken +Draknar +DrakoVamp01 +Drakonid +DrakosWrath +Drakuonis +Dramyre +Dranasty +Dranty +Drap +Drapht +Draugadroid +Drava +Drawbridge72 +Drawde +Drawll +Drax +Drayden +Drayheart +Draynth +Drazar +Drazart5 +Drazhe +Drazzo +Drbeto11 +Dre Skrila +Dread +DreadPandora +Dreadfvl +Dreadnott173 +Dreadnough77 +Dreadnoughtt +Dreadnuts +Dreadzie +Dreagation +Dreak +Dream +Dream Deeply +Dream Delve +Dream Plan +Dream Queen +Dream Realm +Dream Tempo +Dream-layer +DreamJT +Dreamboats +Dreamcatcher +Dreamchasr +Dreamfreeze +Dreamguy +DreamingLily +DreamingNote +DreamisBack +Dreams Real +Dreamscape +Dreamstain +Dreamvil +Dreamy Ku +DreamzRs +Drecy +Dredd +Dreddshott +Drednok +Dreek +Dreepy885 +Dreeww +Dregulle +Drei +Dremarial +Drenthe +Drenz +Drenzek +Drenzi +Dreun +Drew +Drew5 +Drew89 +DrewNG +DrewToshiro +Drewbber +Drewbob24464 +Drewby +Drewcas +Drewfuss32 +DrewsHotMom +Dreww +Drex +DrezaR +Drezilith +Drfannypack +Drgreenthumz +Drie Fristi +Dries D-P +Driesca +Driest +Driewieler +Drift +DriftTap +DriftVolvo +Driftzzilla +Driger +Driger F +Driink +Drijf Hout +Drikett +Drikon +Drill n Fill +Drink +Drink 4 Loko +Drink Empty +Drink Local +DrinkCheap +DrinkPapaMlk +DrinkSlinger +Drinkability +Drinker +Drinkin Pete +Drip +Drip To Hard +Dripping Gut +DrippingSack +Drive Stick +Driver193 +Drivious +Drizzy Drake +DrkMstr89 +Drkfirelord2 +Drlime +Dro0 +Dro268 +Droefto3ter +Droge +Droge Dackel +DrogeBanane +Droid +Dromedario +Drommy +Dromy +Dron Iick +Drone Reed +Drone347 +Droog Meneer +Droom +Droopy +Drop +Drop Acid +Drop Brews +Drop Please +Drop Rates +DropGetter +DropMeUrPet +DropTheFlop +DropTopWizop +Dropko +Dropletics +Drops +DropsWhen +Drosaire +Droski +Drouter +Drri +Drrrrunk +Drswole +DrtyBusDr1vr +Drtyhnddog +Drudenhaus +DrudgeMunkey +Drug +Drug Test +DrugProblems +Drugged Out +Drugonaut +Drugs Hurt +DrugsArBadMK +DrugsHere +Drui +Druknr +Drukzah +Drum +DrumBarrel +Drumaz +Drummaboy276 +Drummadr +Drummerz +Drums +Drums X +Drums of War +DrumsSpace +Drumz +Drunk +Drunk CCTV +Drunk CJ +Drunk Jake +Drunk Mimic +Drunk Pastor +Drunk gaming +Drunk n High +DrunkAssassn +DrunkDriving +DrunkGhillie +Drunken +Drunken Monk +Drunken org +Drunkfam +Drunkiin +Drunkn Fun +Drunknerd +Drunknhiiiii +Drwe +Dry 4 Hilt +Dry Cleaner +Dry Dong +Dry Hard +Dry Hardcore +Dry Soup +Dry Trip +Dry on stuff +Dry so I Cry +Dry x +DryBandit +DryWolf +Dryhump +DryksMuseum +Dryness +Drynx +Dryron Man +Dryskies +Drysol +Dryune999 +Dryya +DshubaMisfit +Dsk 10 +DssHimself +Dstroyed +Dt2m +DtWoofles +Dtjenl +Dton +Du +Du Old Pker +Du lourd +Du5tin 3 +DuTson +DuYorick +Dual +Dualerz +Dualicious +Duaneker +Duarterecife +Duathlon +Dub Season +DubC Brownie +Dubalonius +Dubber +Dubbers15 +Dube +Dubie +DubieDebies +Dubios +Dublestuffed +Dublet +Dubs +Dubs_789 +Dubsake +Dubspeck +DubstepsDead +Dubu +Dubu Dahyun +Dubz4Dayz +Dubzy91 +Duc +Ducid Lream +Duck +Duck Sucker +Duck Tape +DuckEnte +DuckNoSmoke7 +DuckSick +Duckcited +Ducklovesyou +Duckreas +Ducks Quac +Ducks U +DucksFatha +Ducky HVIII +DuckyTears +Duckzi11a +Dudash +Dude +Dude Come On +Dude12677 +Dude9103 +DudeAtHome +DudeItsMikey +DudeWD40 +Dudefish64e +Dudeimblazez +Dudenmi +Dudetastic +Dudification +DuelKing +Dufendr +Duff +Duff Daddy +Duff Groupie +DuffHeavy +Duffmanas +Duffs +Duffy234 +Duffybroh +Dufwha +Duggie +Dugong1338 +Dugsie +Duh Kota +Duhstin +Duhul +DuiBuQiShaBi +Duindorp +Duk Me Hard +Duke Ag +Duke Babylon +Duke Roland +DukeBaird +Dukino +DukkuTzi +Dularian +Dulezburg +Duli +Dullskie +Dulwich +Duly Ignored +Dum n dumr +DumFuknIdiot +Dumb +Dumb Alien +Dumb Ass Dan +Dumb Drunk +DumbDog +DumbMatt +DumbThiccAss +Dumbaneering +Dumbass +Dumbass 69 +Dumbass Tony +Dumbells +Dumber +Dumbfounded +Dumbfuk +Dumbi +Dumbledore +Dumesday80 +Dumfries +Dumle +Dumoo +Dumpert +Dumpsterjed1 +Dumwood +DunJunn +Dunadane +Dunbahn +Dunc95 +Duncan +Dunco +Dundasso +Dundefeated +DunderHonung +DunderLadd +Dundiez +Dundonian +Dundrift +Dundrturken +Dune dain +Dungfung +Dunghead +Dunizz +Dunjins +Dunjun +Dunkbox +Dunked +Dunked on +Dunkies +Dunkle Sonne +DunknDink +Dunkston +Dunlaf +DunneDone709 +Dunnill +Dunwall +Duo Armadyl +Duo Elysian +Duodenum +Duoing +Duoli +DupaMuck +Dupe Holder +Duper +Dupey +Duplicated +Dupy007 +Duqq +DuraDoobs +Duracell +Duracell321 +Duradad +Duradal +Duradels +Duradyl +Durag Pat +Duramax +Durant +Duravillidad +Durex +Durexslayer +Duri +Durial +Durial32won +Durialives +Duriel1 +Duriul321 +Durkburt +Durlz +Durni +Durns Main +Durocher +Durooo +Durtsa +Durtsamang +Durtstar +Durty +DurtyFish +DurtyFish HC +Durukah +Durumfe +Durumoomoo +Durza Spy +Dus1O +Dusansss +Duseballs2 +Dushie +Dusk Summers +Duskel +Dust in +Dusted +Dusters +Dustielle +Dustin Rush +Dustinant5 +Dustinn +Dustins Main +Dusto56 +Dustpan18 +Dustt +Dusturbia +Dusty +Dusty cones +DustyNoods +DustyPope +Dustyin +Dutch +Dutch Diablo +Dutch Dog +Dutch GOdz +Dutch Genius +Dutch Quin +Dutch RvG +Dutch girls2 +DutchEnergy +DutchStuff68 +Dutchbobby +Dutchie +Dutchtin +DutchtinOS +DutchtinsAlt +DutchyCrazy +Duty +Dutzu +Duuni-Pete +Duva +Duvel +Duvelicious +Duvl +Duwua Lipa +Dux Sauce +Duxt +Duztin +Dvaergen +Dvdasa831 +Dven +Dvlkid +Dvn +Dvsk +Dvst +Dw b happy +Dw ight +Dwagos 2 +Dwake +Dwaki +Dwarf +DwarfSailing +Dwarfoox +Dwarfson +Dwarve Mage +Dwaybe +DwerlzCH +Dwibbel +Dwight Sn00t +Dworf +Dxnnis +Dxscoveries +Dxue +Dxukko +Dydapynk +DyePhix +DyinToLive +DykeMenace +Dyl Dough +Dyl Gates +Dyla +Dyla n +Dylan Du Sol +Dylan Iron +DylanCarl +DylanFx +DylanWad +Dylanimal +Dylanm504 +Dylann070 +Dylano +Dylbots +DyldoGreat +Dylectable +Dylian +Dyllann +Dylrex +Dyls +Dylshanwang +Dylson +Dylsy +Dymass +Dymenshun +Dymosh +DynamicDuo +Dynamicdan47 +Dynasty +Dynloris +Dynomite +Dynstyreborn +Dyonutborne +Dyonysos +Dyoung116 +Dypso +Dyrakos +DyreBatt +Dyreshot +Dyrus +Dysae +Dyslexic gg +DyslexicTree +Dyslexual +Dysliexc +Dyspnea +Dystopias +Dysturbed +Dystxpian +Dyth +Dyvv +Dyy +Dyzurah +Dz03 +DzRz +Dzakar +Dzangg +Dzentelmenas +Dzievan +DzintarsOls +Dzoseris +DzsungelTyuk +Dzud +Dzun +E D V +E Fox +E MB +E N I M A +E R A +E S H +E SL +E V 0 L +E Z I O +E hm C uee +E ldest +E lixor +E lvarg +E lves +E mni +E mpathy +E njoy +E nvy +E p i i +E r ic +E th +E thy +E volve +E-Dawg478 +E-Grill +E-Hubble +E-S-T19XX +E1K +E4as +EA888 +EARLYoCUYLER +EBDB +EBIDABLAY +EBZ +ECCIES +ECH0 +EC_Legends +EDATERHG69 +EDGV1L +EDM Erik +EDM Playlist +EDMJo +EF tanq +EFFlClENT +EFILLAICOSON +EFL +EG6808 +EGA +EGIRLSIMPER +EGirl Marcy +EHPause +EHstro +EIGRP +EIessar +EIithi +EJ 207 +EJackUL8 +EL BULLYS +EL GA TO +EL Guuapo +ELCAMI +ELFlikeaBOSS +ELITE +ELJosh +ELUSIVE +ELVD +EMIYA Alter +EMPER0R95 +EMaes32 +EN X +ENAC +ENimmo +EOCscape +EOD20 +EODdv +EPLS +EREXI0N +ERGENEKON +ERJ145XR +ERRIE HERRIE +ERRORMONSTER +ESCEDDIE +ESP Zone +ESPARG0 +ESPORZUL51 +ETE76 +ETHIOPIAN +ETurns +EV6A +EVA ELFlE +EVE0 +EVScape +EWFPLMFRLRLF +EXECUT0RZ +EXTT +EXpoZuR +EZ Tag +EZ Till Dead +EZ-Y +EZBar +EZnvm +EaTZyourOReO +Eac63 +Eadgars Ruse +Eadles +Eagel89 +Eager +Eagle +Eagle Eye +EagleSafari +EaglesWentz +Eairj +Eajk +Eara1 +Earendil +Earl131 +EarlRico +EarlVincent +Earll +Earll Ragnar +EarnNest +Earth rune +Earth1ing +Earthling Em +Earz +EasY FraG +Ease +East +EastEnders +EastSyde +EastWho +Eastlakeclub +Eastment +Easy +Easy Girls +Easy1 +EasyDingMike +EasyFro +EasyJet +EasyNoRoids +EasyRNG +EasyTurbo +EasyWhale +Easycore +Easyskillszs +Eat Crow +Eat God +Eat Hot Chip +Eat Tacos XD +EatBrick Kid +EatMoreGlue +EatNutsGegex +EatSand +EatSleepPlay +EatULive_666 +Eatbananana +Eathan +EatingBigD +Eatpiebro +Eats Pant +EatsPoop +Eatu +Eazie +Eazy +Eazy AF +Eazy Rat +EazyGam3 +Eazy_Peazy16 +Eazymon +Eb Marah +Ebbitten +Eberebus +Ebgame2 +Ebinki +Ebisumaru +Ebola +Ebolapaska +Ebp90 +Ebrahem2004 +Eburr +Ec0 +Ecahs +Eccles Alt +Ecdubs +Echo +Echo GIM +Echo Justice +Echo Slam +Echo4211 +Echo_XVII +Echte Belg +Ecko RS +Eckou +Eclardyne +EclecticDern +Ecnubsirhc +EcoLite +EconPhD +Ecs Nick +Ectuu +Ecxes +Ed Dobalina +Ed Si +Ed Word +EdEddndEddy +Edd Gein +Eddapt +Edde7000 +Eddi e +Eddie GGs +Eddie MLG +Eddie1402 +EddieMercury +EddieTross +EddieVanHalo +Eddoz +Ede n +Edelbae +Edelweise +Eden XD +Edga64 +EdgaRyto +Edgar +EdgarAlnGrow +EdgarKing +Edgarr +Edge +Edge c dr +Edge51 +Edgelord +Edgerunner +Edgevill +Edgeville +Edghill +EdgingGod +Edgy Boss +Edgykid +Edgynald +EdibleChickn +EdibleSnow +Edisx13 +Ediverse +Edje +Edjob +Edmund +Edn +Ednnnx0 +EdoKirurari +Edocsil Domi +Edocsil IRON +EdotheJew +Edoxa +Edpls_o +Edson +Edspresso +Edsy +Eduardo II +Eduardoo II +Eduasia1 +Edunu +Eduzey +Edvin +Edvius GO +Edvyno1 +Edwald0 +Edward Teach +Edward phish +Edwarriorx +Edwin Ownz +Eeeeeeeman +Eeeeera +Eeekpenguin +Eeepen +Eek The Nub +Eeli +EelsUpInside +Eem lekker +EenViezeVent +Eend btw +Eendsaurus +Eernegem +Eeveeeee +EeveyBee +Eexhausted +EfORya +Efendi +EfficientBot +EffinNips +Effril +Efnie +Eform +Eftur +Egg Boy +Egg Olmlet +Egg rolls +EggInTheRain +Egganator1 +Eggs 11 +Eggs N Bacey +EggscapeRoom +Eggspert +Eggssmells +Eggsy +Eggtooth1 +Eggy +EggyChipz +Eggzotic +Eglerz +EgoTeri +Egoistic +Egoran +Egorous +Egotistixal +Eh MapleTree +Ehdjsnd +EhhFK +Ehms +Ehnra +EhpEhbGrind +Ehpatrick +Ehpriori +EhrenSpoon +Ehunter +Ei hekille +Eidolonvool +Eientei +Eigenspace +Eigenvalues +Eight +Eight_10 +Eigma +Eihwaz +EikAyZ +Eikel +Eilfs +Eimp +EinBerlin3r +Einar +Einaras +Eindbaas +EindelijkMax +Eingebildet +Einsteins +Einswarior3 +Einyel +Einzelkampf +Eirik +Eisen +Eisengor +Eitsei +Ejiogbe88 +Ejjj1000 +Ejma +Ejx +Ekali +Ekim +Ekim117 +EkkoThresh +Eklof +Eklofs +Ekonomisti +Ekovo +Ekstra +Eksynet +Ekwendeni +Ekxo +El Arana +El Blame +El Blaze +El Boppo +El Chip +El Ghost +El Guapo +El Panache +El PapiTrump +El Pato lOko +El Patolino +El Pinguino2 +El Podger +El Scouse +El Smurf 370 +El WarLord +El Znorro +El-Fahoum +ElBlancooo91 +ElGatoGris +ElGreg_4 +ElHash +ElJReezy +ElJohnny +ElOso +ElPoyoSenpai +El_Pickle69 +Elaedor +Elano +Elasticy +Elatedscarab +ElationArrow +ElbartoOSRS +Elbowd +Elbows Out +Elbs +Elchapo24 +Eldasero +Elder Coal +Elder Siroj +Elder nerd +ElderMoth +ElderRyu +Eldereon +Elderpliney +Eldest Sense +Eldia +Eldin +Eldonskii +Eldoubleyou +Eldrek +EldridPenny +Eldritch +EldritchMage +Elduz +Eleandil +Elebit +Electr0lysis +Electric +Electric Mud +Electric cat +Electrics +Electrike +Electro Beat +Elektr0nas +Element +Element Sk8 +Elementality +Elementhur +Elementiix +Elemmires +Elemntsk8ter +Elemyra +Elena +Elenaki +Elendaro +Elenion +Elephanten +Elephants +Elephantz +Elephent +Elev +ElevatedLife +ElevatedSoul +Eleven +Elevennn +Elevil +Elevo +Elexuitt +Eley +Elezar +Elf King Leg +Elf u +Elfess +Elfie +Elfinsocks +Elfire626 +ElfsWordFly +Elgifted +Elgingo1 +Elgstant +Eli Ancients +Eli Fe +Eli Junior +Elia135792 +Eliass +Elice +ElichikAyase +Elicit +Elif +Eligos +Elijah Who +Elilia +Eliot +Elipson +Eliptats +Elirond +Eliseuh +Elit +Elitaire Lul +Elitarisme +Elite +Elite HIT +Elite Moscu +Elite Sendi +Elite Slayer +Elite387 +EliteJager +ElitePvmer +EliteScaper +Elite_Quests +Eliteisftw +ElitesEyes +ElitesFinest +Elitist Weeb +Eliwin +Eliwood225 +Elixir +Elizabethboy +ElizeRyd +Eljaaa +Elkanath +Elkias +Ell1eScape +Ellakazam +Elliebus23 +Elliot727 +Ellise29 +Elliterate +Ello +Ello Ron +Ellphie +Elly Dog +ElmSpringsTN +Elmatron +Elmo +Elmo Narca +Elmos Wrld +Elmswood +Elnaphant +Elnuma +Elo Luigi +Elo Solo +EloJimmini +Elocuente +Elodie +Elon M9sk +Elons +Elox7 +Elpis +Elppu +Elqnaattori +Elrebririand +Elric +Elrohiir +ElroyFTW +Elryeth +Elsa +Elshak +Elsheshima +Elshi +Elshire +Elsworth +Eltader2 +Eltry +Eltuu +Elucidation +ElunedsSong +Eluniel +Elusive +Elusive Drop +Elusive818 +ElusiveOne +Eluti +Eluw +Elve +Elve Alt1 +Elve Elve +Elveiq +Elven +Elven Durant +Elven Lamp +Elvenborn +Elverum +Elvey +Elviax +Elvin +Elvis +Elvis Crespo +ElvisArt069 +Elvs +Elvyn Frenzy +Elvz +Elwood +Ely the Man +ElyGoulding +Elyam +Elyaris +Elyas5 +Elyas_Max +Elycal +Elyes +Elyixa +Elynescence +Elyphosani +Elyqs +Elyrion +Elysi +Elysian +Elysian Brew +Elysian OSRS +ElysianError +ElysianOP +ElysianTank +Elysianlove +Elysianz +Elysion +Elysiuhm +ElysiumFalls +Elyte +Elyxr +Elyysian +Elyzarin +Elz +Em il +EmTvLive +EmaBeast OS +EmaRae +Emacity momo +Emad +EmagndiM11 +Emalexa +Emanated +Emanuel +Emasterone +Ember +Ember of Ash +Embereus +Embossis +Emce +Emeowtion +Emerald +Emerald Jack +Emeraldx +Emergency +Emericanpkur +Emerickb93 +Emeritas +EmeritusD +Emhrys +Emiel +Emiel Btw +EmielM +Emielos +Emiit +Emilharen +Emilis +Emilliio +Emilozz +Emilozzz +Eminem Yupp +Emirdagli +Emirdagliii +Emithyst +Emiya Shiro +Emma +Emma Main +Emma Q1 +Emma epsi +Emma1020 +EmmaCn132 +EmmaEmma +EmmaRose +Emma_RC +Emmaes +Emmalitarosa +Emmet1156 +Emmet20 +Emnay +Emnicious +Emnitylol +Emo Bee +Emo King +Emoness +Emoticon +Emoyy +Empathy TKE +Empathys +Emperor +Emperor Elo +Emperor Xau +EmperorBuggy +Empery +Empire +Empire State +Empireglorth +Empirix +Empty +Empty Box +EmptyB +EmptyBox +Emptyhalo +Emptynogin +Empyre +Empyrius882 +Emriat +Emu War +Emumafia +Emus +Emylia +En Jernmand +En ki +En oo vajaa +En99omgangen +EnCue +Enabled +Enabler +Enanthat +Enbrel +EnbyDeal +Encrypted +Encryptiron +Encyclopedie +End Goals +End Grind +End1ess +EndOnDeath +Endanged +Endem1c +EnderMart +Enderofwar +Endgame +Endgameplzz +Endgegner +EndingTime +Endir +Endl3ss +EndlesNights +Endless +Endless Dawn +Endless RNG +Endlingg +Endo +Endor +Endos +Enedal +Enemez +Enemm +Enemyboy +Energie +Energise +Energy +Energy Dave +Enert +Enes +Enfers +Enfes +EnforcerOP +Eng1and +Engage +Engagement +EngelNacht +Engen +Enginaer +Enginarc +Enginear +Engineer Sam +Engineered +Enginerd09 +Engl1sh +Englandwon +Englebassen +Englehr +English +English Sir +English noob +Enhtitled +EnigmaCoder +EnigmaWR +EnigmaZen +Enis Kanter +Enivid +Enjoi +EnjoiAssault +Enjoy +Enjoy It +Enjoy Today +Enjoymydhide +Enjoys +EnjoysQuests +Enk rypted +Enkaidu +Enkeltje +Enkh +Enki +Enkidu260 +EnlargedNads +EnlargedNut +Enmios +Enora Nyx FE +Enoran +Enormous +Enormous Hog +Enos +EnoughGfuel +Enoux +Enphadei +Enraged +Enraged Crow +Enraged Lamp +Enranged +Enrich +Enrico +Enrik +Enroza +Ensanguined +Enshu +Ensnare +Ensomhet +Ent Sapling +Ent1tle +Enterprise +Enthusigasm +Entitled +Entiy +Envello +Envidius +Envied +Envil +Envious +Envvi +Envx +Envx1 +Envy +Envy S +Envy lul +Envyctus +EnvyouS +Envys +Envyy +Enza Denino +Enzed +Enzel +Enziguru +Enzyme +EoMeri +EocBlowsNuts +Eodwyn +Eol Ivan +Eos Adamm +Eos Mark +Eostrix +Eowy +Ep1breren +Epaah +Eperz +EphermalGoat +Ephi +Ephrayim +Epiales +Epic +Epic Nom +Epic Popo77 +Epic Specz +Epic Star +EpicGamer69 +EpicReefer +EpicSalmon +EpicSpasms +EpicToaster9 +EpicTomato +EpicX +Epic_Knight0 +Epicderk +Epicoz +Epicurus4 +Epicvoid +Epicx +Epigraphs +Epiixx +Epikki +Episodic +Epitohm +EpitomeSlay +Epix_x +Epiyon +Epods WifeY +Epoinen9 +Eponas +Eposs +Eppdawg +Eppers +Epping +Epson Eco +Epyll +Eq +Equilibria +Equilities +Equnox +Eqwity +Er0l +Er1kasss +ErBr +Era +EraJorma +Erabeus +Erad +Eradicus +Eragon 1 +Eragondragen +Erase +EraseThat +Erased +Eray +Erbal +ErbearIV +Erbiboar +Erbyss +Erdi +Erebus +Erect Chair +Erect Diglet +Erectus Croc +Eredln +Eren The Nub +Eren Yaegar +Erg129 +EriUmi +Eric +Eric Brad +Eric Dingus +Eric Hansen +Eric RS +Eric V +EricN7 +EricPrydz +EricR95 +EricTheNoob +Erica +Erican Maxos +Ericc +Ericgone13 +Erichilles +Erics Pixels +Ericsurf6 +Eriction +Erie +Erijk +Erik +Erik Ryatal +ErikProbably +Erikaugust +Erikci Jr +Erikito09 +Erikkert +Eriknau +Erikoisjouko +Erikoiskahvi +Eriksen14 +Erikske89 +Erikv28 +Erinus +Eriscord +Erixzo +Erkki +Erkki Pers +Erkkiks +Erlid +Erlin +Erlksson +Erm its me +Ermac +Ermafrodita +Erna +Ernestaiii +Ernesto056 +Ernsour +Ero +Erock2828 +Erocktastic +Erodel +Erodoris +Erony +Eros +Erosei +Erotic Maid +Eroxtroy +Error +Error 510 +Error X Life +Error812 +ErrorSeven +Errric +Errrr +Ersei +Ershayz +Ershayzz +Ersiki +Ertsu +Eruni +Eruptingcat +Erwin +Erwin J +ErzaGames +ErzaScarlet +Es0x Luc1us +EsArTee +EsJayW +EsXP +EsbenViking +Esbuh +Esc anor +Escalation +Escaline +Escanor1994 +EscapeMaIron +EscapeWhere +Escension +Escha +Escnirp +Esconex +Escot +Esd +Ese Burrito +Esham +Esheme Sen +Esimies +Esinaahka +Eskalt +Eskandar +Eskeleto9 +Eskett +Eskett II +Eskib0y +Eskii +Eskild +Eskimeme +Eskimo +EskimoFro +Eskizzibur +Esko79 +Eslamm +Eslihero +Espa +Espada_Vx +Esparvel +Especkt +Espee +Espuky +Espyria +Esquelito +Essencehour +Essex RS +Essylle +Est Bellum +Estafeta1 +Estar +Estebaan +Esteedee +Esteeme +Esteet +Esteffano 3d +EsterKai +Esterbrook +Estetica +EstevamStain +Estiem +Estonia9184 +Estra +Estrogenizer +Estus +Estusin +Esya +Etakenai +Etardoron +EtchaSketcho +Eternal +Eternal Envy +Eternal Max +Eternal NEET +Eternal Orb +Eternal Qt +Eternal Riw +EternalGuide +EternalHeart +EternalPants +EternalSin9 +Eternalfury2 +Eternalgod99 +Eternity +EternityAP +EternityEndz +Ethaan +Ethan +Ethan Hunt +EthanMcSexy +Ethanol +EthansMain +Ethel +Ether +EtherBunny +Etherealist +Ethereous +Ethernet3 +Etherscan +Ethoxide +Ethread +Ethwin +Etikk +Etis +Etkzera +Etna +Etnie0 +Etobicoke +Etrengereid +EttLitetHus +Etuovi +Etyaz +Etymology +Eu_Matheus +Euanx +Eucaryptus +Eucleides +Euclidian +Euclipenguin +Euf +Eugenepickl3 +Euhem +Euhh +Eukaryote +Eukko +Eulers Eagle +Eulogise +Eunbiii +Eunie Xeno +Eunx +Euphael +Eupharu +Euphorion9 +Euphoriotic +Euro +Euro Centric +EuroGarden +Eurovizija +Eusheen +Eusiriito +Euthia +Euxii +Euxy +Eva-O1 +Evadari +Evaiv +EvanWilliams +Evanz40 +Evaptix +Evawe +Evdog +Evelynn UwU +Evemarner +Even2000 +Even3518 +EvenMater +Evenepoel +Evening +Eventyrlig +Ever +Ever so Dark +EverSingular +Everglow +EveronSky +Eversiction +Every Color +Every Word +EverybodyZuk +Evette +Evictus +Evil +Evil Buu +Evil H +Evil Inari +Evil Kenevil +Evil Lizard +Evil Lord +Evil Nishiki +Evil Oak +Evil Twin +Evil Zayne +Evil-Mind69 +Evil3yez +EvilCopycat +EvilDeeds +EvilDegen +EvilFootLong +EvilH4mmy +EvilOwen01 +EvilTriumphs +Evilaz +Evildoer +Evilegod2 +Evilelfy +Evilhammer +Eviljay +Evillized +Evilstar34 +Eviltroll648 +Eviran +Evirane +Evnn +Evo9 +EvoSlacker +EvoSlayz +EvoeHalt +Evoke +Evolooner +Evolution +Evolved +Evra +Evrs +Evrybodypays +Evse +Evuk +Evultion +Evylix +Evytt +Evzmac +Ew Its Mike +Ewan BTW +Ewang +Ewiiyar +Ewmu +Ewos +Ewya +Ex Files +Ex Holy +Ex Port +Ex Sythe +Ex-Slur +Ex3rt +Ex903 +ExHCMangy +ExMachina +ExMaxxed +ExPro +ExPsi +ExQ Bratan +ExSevenTech +ExShiron +Exa OuO +Exaalt +ExamJ +Exambient +ExamineCoins +Examines +Examon +Exanso +Exarch +Exasperation +Exaz +Exbos +Excadrill +Excaria +ExcelIsLife +Excellarate +Excellini +Excinium +Excise +Exclude +Exclusic +Excody0 +ExcuseMyStr +Execrating +Executed +Executes +Exella +Exem +Exercise +Exero +Exflacto +Exhaust +Exhibition +Exhumed +Exi Sisukas +Exia +Exile +Exile Vision +Exile88 +Exile_vChad +Exiled Noobi +Exiled Peon +Exiled Slay +Exileeeee +Exiquio +Exiriam +Exiting +Exmigrant1 +Exminer +Exo25 +Exoden +Exodusty +Exonaut +Exor +Exorcism +Exoristic +Exorzist +Exotic +Exotic Xenon +Exotica +Exotick +Exp Jesus +Exp Nerd +Exp Wasting +Expaaja +Expansa +Expansce +Expanse +Expensive +Experience +Expl0it +Explaindeath +ExplicitPvm +Explodet +Explodium +Exploiter +Explorer +Explorifice +Explosia +Expochan +Export +Expozz +Expressed +Expressen +Exright +Extella +Extended C +Extile +Extinct +ExtinctDecay +Extinguished +Extortionate +Extra +Extra Chance +Extra Droog +Extra Poor +Extra Shadow +ExtraRNG +ExtractorX +Extranjer0 +Extreemkills +Extrem3b0y +Extreme +Extreme JeJe +Extreme Moo +Extreme Pray +ExtremeJokeR +Extremterms +Extrim +Extrovert +Extubation +Exty +Exultia +Exume +Exus +Exus De +Exustron +Exwalker +Exxtinct +Exynyt +Exz0 +Exzacly +Exzactly +Exzakly +Exzian +Ey1 +Eye patch +EyeBDaMan +EyeHaveToPoo +EyeMakeYouQQ +Eyeless +Eyelessjohn +Eyeofdeath3 +Eyeron E +Eyes Inside +EyesLowIndo +EyezClosed +Eyggs +Eylix +Eymox +Eyrfire +Eyup xD +Ez Klaplong +Ez4Peru +Ez4u2nv +Ez4u2say +EzBot +EzCashin +EzSlayEzLife +EzUnReal +Ezarc HCIM +Ezdrae +Ezero Br +Ezey +Ezfart +Ezia +Ezra +Ezup +Ezwa +Ezxkiel +Ezzardx300 +Ezzi +Ezzuna +F 3 4 R +F 0 N Z Y +F 3 R R U M +F A C E +F A N TT I +F E L I CYA +F For Flash +F I X E D +F L A T +F M L +F R A T +F Ribeiro +F SONY +F T P +F You Bro +F athlete +F e e b s +F l a n Cat +F l u f fy +F l ux +F loofy +F reeze +F u z Z e +F ury +F-16 +F-ck Bleed +F-ck Irons +F00DCOMA +F00F +F0O +F0REIN +F0ZI +F0cus Me +F0rtune +F0sta +F0xBr34d +F1 Mercedes +F104 +F19 +F1REWIND +F1nalHour +F1rst +F1skemann +F1tn3ssWorld +F20z +F23A +F2L +F2P Waifu 07 +F34r My B0w +F34rcr4ds +F3ARCE +F3LINA +F3lo +F4DE +F4TB0Y +F4ust +F4xi +F7VD3 +F80Scott +F8n +F8tz +F9 +FA DY +FA Joel +FA1Z +FAILED ZEUS +FALLGIRL1029 +FASHl0NSCAPE +FASTBLAST I +FATHER +FATHER RANCH +FAlRWEATHER +FBD +FBGM 101 +FBGMi +FC Groningen +FC Liverpool +FD3S_RX7 +FE AltScape +FE Cerise +FE Endeavor +FE Mazoku +FE Smore +FE wretch +FE80 Seal +FEJMBE +FER00 +FER0C1OUS +FERTILE DONG +FEstlkerpeng +FFA +FFA Everyday +FFASplit +FFIE go brr +FFS Sam +FFV +FF_GhiLLi +FFelidae +FGHTIN +FHV +FIDADDY +FIFG Phat +FILLME +FIRE 0F +FIRESlTE +FISHY au +FIV3 +FIying +FJ +FK Corp +FK TURAEL +FK1 +FKGlory +FKN RAPTOR +FKRA +FL jit +FL0CK +FL3XPL3K +FLAPPYLIPZ +FLC L +FLOR1DA +FLYGOD +FLYING +FLgoob +FLoKii +FM DOOM +FMGbrien +FMLshes17 +FMarshalBill +FN2187 +FNA +FNEkkGKGKWGK +FO-LAZY +FOES +FOLEM +FONKY +FONNlX +FOSTEEEEZY +FOUO +FOUR GATSU +FOV90slider +FOXBRAH +FP Engineer +FR1T +FRAQSTAR +FREEBABA +FREED0M 1776 +FRIENDSHRIMP +FROM ICELAND +FROO00OO0ZEN +FROSTYFOO +FROXBURG +FSK Gaz +FSW 2JZGTE +FTI +FULGRlM +FUTRHNDRX +FUTillIFU +FVChallenger +FW HYPZ +FX Teddy +FXF_Tails +FYXON +Fa k er +FaBeSCa +FaNNtastix +FaZe +Faabio +Faalk +Faardo +Faarihn +Faathos +Fabario +FabiScape +Fabiann +Fabidjann +Fabiiano +Fabioso +Fabled +Fabled Fox +Fabreezy +Fabretzio +Fabsitz +Fabulence +Face +Face Seat +Face9 +FaceHook +FaceTheFacts +FacedBased +Facehuntter +FacelessBoyd +Facilis +Facing +Fack Russia +Factual +FadaPDF +Fade +Fade Lightly +Fade zz +Faded Crook +Faded Focus +Faded Lungz +Faded Past +FadedFace +Faderfouras +Fadfats +Fadge7 +Fading +Faeanaro +Faebat +Faeles +Faerindel +Faested +Faf +FahQ +Fahim +Fahrbot +Fai1ure +Fail Be Dont +Fail Friday +Fail Stacks +FailFish +FailedNoob +FailedZerk +Failing +Failocity +FailsauceFTW +Faint +Faint Dallas +Fair +Fair Folk +Fair Luck +Fairburn +Fairex +FairiesBane +FairlyDecent +Fairr +Fairr Enough +Fairwolf139I +FairyFeind +FairyVeiler +Faith xd +Faiu +Fakdo +Fake +Fake Chad +Fake Dylan +Fake ID +Fake Levi +Fake Pobble +Fake Suffer +Fake Will +FakeBallots +FakeGirl +FakeNews_CNN +FakeNudez +Fakent +Fakeppa +Fakez07 +Fakezgen +Fakn Oats +Faknius +Faku +Fal +Fal7 +Falabar247 +Faladalore +Faladas +Faladoor +Falador +Falador Sq +FaladorabIe +Faladorks +Faladussy +Falcon +Falconf1 +Falconr +Falconz420 +Faleis +Falestine +Falkenberg +Falkuntpunch +FallOfSolace +Fallacy i +Falladis +Falldyl +Fallen +Fallen Dark +Fallen Hopes +Fallen Noble +FallenBlur +FallenGods +FallenOutlaw +FallenSlayer +Fallenchamps +Fallendude55 +FallingDown +Falll +FallnPancake +FallnSpartan +Fallon +Fallout +Falloutah +Falls +Falls Apart +Falls Road +FallyFiddler +Fals +FalscherHase +False +False 9 +False Boon +False Divine +False News +FalseGod +Falsemorels +Falubo +Fam +Fam Chi Boy +FamIso +Famcloth +Fame is +Famexx1337 +Famfrit +Familia +Familie +Family Crest +Famished Fe +FamishedNine +Famjam +Famoose +FamousBowl +FamousBowls +FamousPixels +Famuel +Fan +Fanatic Est +Fanatiker +Fanawr +Fancys +Fandri +Fanfiction +Fang Dude +FangJo +Fangsie +FannyPaca +Fantasieloos +Fantastik +Fantikerz +Fantomine +Fantrix +Fany Pack +Fanzi +Fappel +Fapperd +Fapple Bees +Fapricorn +Fapworthy +Far Alone +FarAke +FarFarOut +FarNear +Farages Army +Faragi +Farah +Faramir +Faran +Farao +Faraolorddd +Farcry25 +Fareham +Farelinho +Farenru +Farewell Bud +Farfire +Farid Lord +Faridi +Farigno +Farkle +Farkwar +Farlz +Farm +Farm Strong +Farm11m +Farm3r +FarmHub +FarmRun Clay +Farmance +Farmay7 +Farmelot +Farmenheimer +Farmer +Farmer Blake +Farmer Crab +Farmer Dannn +Farmer Jayy +Farmer Johnx +Farmer McGee +Farmer Santa +Farmer Wull +Farmer Zach +Farmer Zratz +Farmers +Farmertree +Farmin +Farming +Farming Arma +Farming Moe +Farmingfoxx +Farmingtool +Faroeallstar +Faron +Faror +Farpoint09 +Farqin +Farrier +Farron08 +Farseer +Farseer Hat +Farsight2 +Farssi +Fart Gunner +Fart Shartly +Fart Weed +FartInMyGob +FartSymphony +Farthinder +FartinLKing +FartinLuther +Farting cat +FartingCow +Farts2Wet +Farty Ass +Farukoo +FasTLT +Fascia +FashionBTW +FashionPig +Fashy +Fast +Fast AF +Fastenal +Fasterman +Fastly +Fastmagepk1 +Fastmaniac +Fat Bawlsack +Fat Boobs +Fat Cat +Fat Clouds +Fat Fur +Fat Goombah +Fat Jonny +Fat Leb +Fat Maniac +Fat Mat +Fat Moron +Fat Nymph +Fat Rackz +Fat Ralph +Fat Salesman +Fat Swaggy +Fat Thin +Fat Waddle +Fat Wirgin +Fat Wrath +FatBIunt +FatBurgerKid +FatClock +FatGreasyGuy +FatITguy +FatKidBrett +FatKidHougie +FatMonkey +FatSlutKing +Fatafeat +Fatal +Fatal Cazual +Fatal Psycho +FatalReign +FatalXfire +FatalisRS +Fatalsystem +Fataltorment +FatboislimOS +Fatboy6 +Fatcav2 +Fatceps +Fatdogs11 +Fate Gu +Fate Z +Fateq +FatesWarning +Fatez +Fathead +Father +Father Of 3 +Father Of M0 +Father Tacos +Fathey +Fatmat +Fatrekt +Fatso +Fatstinkysak +Fatterhead +Fatty Combat +Fatty Park +Fatty-Kent +Fatty380 +FattyIsntFat +FattySupreme +FattyTerps +Fattybanger +Fattymcdugal +Faultty +Fausto +FautleferQC +Fave +Favelador +Favion +Faw OCE +Fawka516 +Fawn1460 +Fawz +Faxon +Fayl +Fayumi +Fayv +FazTazTic +FazeQ +FazeSkilling +Fazebook +Fazed Imp +Fazist +Fcape +Fcbfan1994 +Fctillidie +Fe AND17 +Fe Adex +Fe Alma +Fe Anakin +Fe Bastok +Fe Carter +Fe Clay8 +Fe Cremator +Fe Dahje +Fe Dentyste +Fe Dopamine +Fe Gangsta +Fe Grom +Fe Gson +Fe Hellpuppy +Fe Hucks +Fe KabooM +Fe Kiteman +Fe Kyle Fe +Fe Liquid +Fe Logix +Fe Louis +Fe MGTOW +Fe MagicMan +Fe Monkey +Fe Mulks +Fe Nail +Fe Nini +Fe Nocturne +Fe Nylost +Fe Oakdice +Fe Papi +Fe Patrick +Fe Pvm Tiger +Fe Pyles XV +Fe Qlimax +Fe Republic +Fe Rex +Fe Sav +Fe Setting +Fe Skilleye +Fe Slammed +Fe Sten +Fe Tentacles +Fe Thijssie +Fe Tomie +Fe UIM +Fe Viraxic +Fe Werty +Fe X AE A-Xi +Fe Xems +Fe Zachpnnc +Fe Zelta +Fe anor +Fe ared +Fe depressed +Fe elsBadMan +Fe il +Fe lonies +Fe lungs +Fe lyne +Fe r a t +Fe rgy +Fe ta +Fe-ranator +Fe0xi +Fe20 +Fe26 +FeBriZley +FeCapedSloth +FeCrab +FeDestroyed +FeDyl +FeFiFoFum +FeFireTruck +FeFlo +FeFox +FeIII +FeJonnisjoen +FeKyle +FeMale Chris +FeManlett +FeMattsheets +FeMoist +FeMudcheck +FeNote +FeOx +FePash +FePinkviini +FeReelix +FeShane +FeSolaris +FeSynical +FeTaeliah +FeUIMIronBTW +Fe_Schrute69 +Fe_StarLord +Fe_Symphony +FeaR +Feaaar +FeagMeister +Fear +Fear Fun +FearKev +FearMyTM26 +FearOfChange +FearSamurai +FearTheBear +FearThyDoom +FearTurkey +Fearengineer +Feargasm +FearlessFudu +Fearmaker1 +Fearrod +FearzebuJr +Feasted +Feather +Feather Bug +Feathereli +Febelz +Febreezio +FecesFyrHose +Fedad +Feded +Federal +Federated +Fedji +Fedo +Fedooool +Fedt +Feebee +Feebz +Feed Forward +FeedMePlants +Feedback +Feedle +Feek 1 +Feel Ya +FeelMyBirdie +Feelin +Feelin Fine +Feelin It +FeelinHappy +Feelmygame +Feelosophy +Feels +Feels Lonely +FeelsDuBis +Feelsbadkapp +FeelslronMan +FeelzBradMan +Feen +Feet Watcher +FeetFunGoose +FeetPic +Fefe3 +FefilleLaDur +Fegicaly +Fegoob +Feint +Feisty +Feit +Feitn +Fel +FelNeck +Felamar +Feldip +Felgenhauer +Feli-Marie +Feliaff +Felinaed +Feline Feast +Felix2 +Felixa +Felixigor6 +Feller Crus +Feller Magic +Fellow +Fellow Fool +Fellowships +Felmyst +Felon +Felonies +FeloniousHam +Felony Ruler +Felted +Female Henry +Fembo y +Femboi +FemboyFloppa +Fementedspaq +Femister +Femke +Femke Bol +Femkekos +Femstiq +Fencig5 +Fencingduck +Fencko +Fender +Fender Axes +Fender Twin +Fendoral +Fene77 +Fenerbahce +Feniks366 +Fenix Downs +Fenix Kiros +Fenkat +Fennikel +Fenny RS +Fenomeno11 +Fenothiazine +FenrilasIM +Fenrirs Fall +Fens +Fenshy +Fenske +Fented +Fentenal +Fenternal +Fenyxgreen +Fenzo +Fenzy +Fequites +Feral Wiki +FeralFiddler +Feralblood +Feraligatr44 +Feraliigatr +Feratzu +Ferbzy +FerdaWoox +Ferduh +Fereekelor +Ferlide +Fermeon +Fernando-Frv +Fernie +Ferny +Fero217 +Ferocious J +Ferocious97 +Feroos +Ferousity +Ferpderp +Ferrarezi +Ferrari +Ferrari Enzo +FerrariScape +Ferrat +Ferrdie +Ferreklop +FerretFoSho +Ferrex +Ferrggette +FerricAndre +Ferring +Ferrinheight +Ferro +FerroPlanty +Ferrothan +Ferrothorn +Ferrous +Ferrous Frog +Ferrous Hugs +FerrousBoii +FerrousWheel +FerrousWolfe +Ferrowing +Ferrum +Ferrum-56 +FerrumPawn +Fersapian +Ferus +Ferus Ferrum +Fervor +Ferynys +Fesan +Fesenko +Festis +Festiva +Fesu +FetaCheese +Fetetchie +Fettisdagen +Fetus +Feudal +Feunk +Fewest +Fewideahide +Feydx +Feyenoord36 +Feylon +Ffilteg +FfsImAfk +FgtBob +Fhil +Fhk Trudeau +Fhpure1 +Fibeer +Fiberlight +Fibix +Ficc +Ficomon +FiddlesLeaf +Fidds93 +Fiddy Ate +Fiddy Bag +FiddyDuddy +FiddySweens +Fidelity +Fiege +Fielacius +Fielde +FiendinLo +FiendsDream +Fierce some +Fiero +Fiets +Fiets opa +Fietsen +Fiff +Fifflaren +Fifth +Fifth Herald +Fifty +Fifty 5O +Fifty Cent +FiftyFive +FiftyForty +FiftyStones +FigaroTheCat +Figes +Fight +Fight 04 +Fight For Jk +FightMiIk +Fighta +FighterSE +Figless Duck +Figmentx +Fignootters +Figpig +FigsNotPigs +Figure +Figwit +Fiiderino +Fiiggy +Filed +FiletOFlesh +FilipTelford +Filippia +Fillifjonken +FillyFilly12 +Fillzu +Filmmaker +Filo Legolas +Filofteia +Filoksenia +Filson-zzZ +Filth0 +Filthy +Filthy Bird +Filthy Clam +Filthy Pesnt +Filthy Santa +Filthy Weeb +Filthy istik +Filthy4Iron +FilthyDane +FilthyDingus +FilthyOreo +FilthyPixels +Filthy_Stew +Filz +FimiWolf +Fin Vader +Fin219 +FinPunisher +Final +Final Redux +Final playz +FinalBossUIM +Finalbang +Finalbrk +FinalityB +Finally +Finaltank +Finch +Fincher +Find +Find mucking +FindTheTeemo +Findawg56 +Finding Dory +FindingDory +Finding_Mary +Fineillspoon +Finem Mundo +Finesse +Finessing +Finex +FingerBang +Fingerdfilly +Fingered +Fingerlegs +FinickySquid +Finish +Finish Flash +FinishedLog +Finishzuelan +Finklestein +FinkyFink +Finlan +Finland +Finlanderi +Finlanders +Finlays +Finlunch +Finn1309 +FinnelCake +Finnica +Finnish +Finnkie +Finral +Finrufa +Finsho +Finsta +Fintiaani +Finutty +Fiola34 +Fiora +Fipimuesi +Fir3bird85 +Firat +Firben +Fire +Fire 745 +Fire 961 +Fire Captain +Fire Chiller +Fire Fiesta +Fire Fist +Fire Galley +Fire Kaped +Fire Kittie +Fire Tune +Fire10910 +FireAF +FireAnRescue +FireGiant +FireKornez +FireOnRs +FireReid +FireTruckBoy +FireWolf28r +Firebelly +Firebuggy +Firebwans +Firecan1314 +Firedevil +Firedrake658 +Firehawk746 +Fireheart470 +Firein12 +Firejax +Firekirbyeli +Fireknight0 +Fireman +Fireman Sam +Firemanzz +Firemutt +Firenova +Fireoman +Fireskill +Firesmash +Firestarone +FireyDragons +Firko +Firnik +First +First Bozz +First Up +FirstBathTub +FirstBlood 1 +FirstIron +FirstRS +First_Viking +Firulay18 +Fish +Fish Cow Dog +Fish Keeper +Fish Nibba +FishFingerz +FishGoBlub +Fishcake +FishesBmine +Fishey +Fishie +Fishling +Fishoii +Fishstickz +Fishsword389 +Fishvaulter +FishyBrines +Fisicas +Fiskhue +Fisna +Fist +FistMeTrump +Fister +Fit Jr +FitAid +Fitdis +Fitis +Fitsit +Fitty Tyson +FittyBuck +Fitzy Smalls +Fiurio +Five +Five Demands +FiveManSplit +FivePaws +FivePointOh +Fivee Skinn +Fiveskin +FixationRS +Fixed +FixedCost +FixedMain +FixedWing +Fixions +Fizbin +Fizg0d +Fizz Khalifa +Fizzed +Fizzle +Fizzy Glizzy +FizzyGuzzler +Fjala +Fjala r +Fjalee +Fjollan +Fjolle Mate +Fjomp +Fk RS L +Fk W Da Woo +FkingEzeKial +Fkking +Fklostmybnk +Fkluzac +FknDeece +FknDreaming +Fkuru +Fl y +FlLTHYYYYYY +FlNARKY +FlTTY +FlTZ +Flabaghast +Flaboogles +Flaccid +Flaccid RNG +Flaccid Semi +FlaccidWhip +Flacid +Flackyo +Fladra +Flagaria +Flagrance +Flagrant 2 +Flagz +Flaherdog +FlailTheKing +FlailingGoat +Flair Viper +Flakelar +Flakey +Flakeydude +Flakkas +Flakto +Flamaha +Flame Lurker +Flame0fUdun +Flame29 +FlameSoother +Flamed +Flamel +Flamepistol +Flames4 Ever +FlamingPee +Flamingfox +Flamingguy7 +Flaminold +Flaminrofls +Flammbam +Flanelli +Flap +Flap Slap +FlapJackals +Flapple +Flapsian +Flare +Flare Grylls +Flareblade +Flareon +Flarez +Flarp +Flash +Flash Voyage +Flash3200 +FlashYellow +Flashbane +Flashbang +Flashcards +Flaskepost +Flat +Flat Eric +FlatAssPlank +FlatEarth361 +Flatback +Flatlandah +Flatorbrush +Flaunt +Flava +Flavaaaaa +Flavie +Flavour Trip +FlavouredDav +Flavur +Flaw +Flawd +Flawed +Flawed Bliss +Flawless xD +Flawnn +Flawzin +Flax Pickerr +Flaze +Fleaa +Fled 6ymcric +Fleeson +Flemingo +Flemino +Fleruas +Flesh Forest +Fleshgod +Fleshpound +Fletch2 +Fletched0 +Fletcher +Fletcher 06 +Fleton +Fletz +Fleurescent +Flex +Flex Wayne +Flex1bel +Flex1bility +FlexCity +FlexSeal +Flexatronic +Fli pper +FliPancakes +Flick +FlickMyTick +Flicker 06 +FlidFlop +Fliga +Flight +FlikAwrist +Flikker +Flikker Kind +Flimmyflan +Flimpy +Flimsywhale +Flimzy +Flinch +FlingDragon +Flint +Flint RS +Flint Water +Flintstoned +FlipDaddy +Flipdam +Flipje +Flipman24 +Flippa +Flippa Monk +Flippar +Flippers +Flippin +Flipsen07 +Flipzzzup +Flirz +Flit Wick +Flix +Flixy +Flizz xd +Flllllllllll +Float +Floater eyes +Floatzelo +Floballer +Flock43 +Floeter +Floki loki +Flomple +Flonza +Floody +FloofyTurtle +FloofyWaffle +Flooga +Floogan33 +Floopyboople +FloorTwenty +Floot +FlopLord +Flopez +Floppy +Floppy Boaby +FloppyDongle +Florian +Florian_1988 +Florida +Floth +Flover +Flow +Flow it +FlowMafiaaa +FlowState +Flowah +Flowen0ne +Flower +Flowerm00se +Flowiey +FlownbyFire +Flowtown +Floww-Grown +Flowwar +Flowzyy +Floxin +Floy +Floyx +Fludds +Fluenz +FluffPandaSr +Fluffafluff +Fluffalo +FlufflePluff +Fluffy +Fluffy chair +FluffyTater +Fluffypony44 +Fluga +Flugel25 +Flugenhorn1 +Fluid +Fluid Voyage +Fluke Jr +Fluminense +Flunc +Flunt Capz +Fluoroform +Fluorophore +Flupbaster +Flurius +Flushiz +FluteBand +Flutlicht +Fluxee +Fluxery +Fluxion +Fluxx V2 +Flvd +Fly an High +Fly by N7ght +Fly in +Fly-TheW +FlyLo +FlyPap3rr +FlySunyQuest +Flyboyray +Flydol +FlydonWayno +Flyeeee +Flyer +Flyer TMT +Flyer W Iron +Flyern +Flyguy13 +Flyhll +Flying +Flying Pingu +Flying Swede +FlyingBobcat +FlyingIrish +Flymi +Flymzy +Flynny +Flynsquirrel +Flynt +Flyonwings +Flyvende +Flyvende Ged +Flyy +Fml IronMan +Fml Its Adam +Fml Its Carl +FnHit +Fnatic +Fo Ring +FoRbeZiiLLa +Foam Corner +FoamDemon1 +FoamShrimp +Foamshire +Fobu +Fockwolf1 +Focus +Focus73 +FocusOnGoals +Focusor +Foen +Foesum +Foggy1991 +Fogol +Fogpun +Fogworth +Fohmie +FoiledSoftly +Fojin +Fokjefe +Folayyy +Foleshill +Folesy +Folfox +Folieo +Folk +Folk169 +Folktale +FollieRS +Followed +Follower +Folwifuswalo +Folxi +Fomble +Fomid +Fondle +FondleMyIron +Fong +Fonnis +FonsJ +Foo I I +Food +Food For Me +FoodEmperor +FoodStampGod +Foodfoodfood +Foodie +Foofickle +FookOffNerd +Fool +Fool Senpai +FoolFighters +Foolery +Foolingling +FoolishHeart +Fools +Fools Errand +Fools Switch +FoolsErrand +Foomp +Foooman +Foose +Foosyy +Foot +Foot Ball242 +Foot Magnet +FootLocker +Footaphiliac +FootlongMike +Fooz +For +For Karamja +For My Block +ForDaScratch +ForKrimpt +ForNostalgi +ForRusssia +ForWeAreMany +Forbe +ForbiddenCry +Forbids +Force +ForceZero +Forcekid +Ford +Ford Racing +Forearm +ForeignBoris +Foreigner +Foreknown +Forerunner40 +Forescimitar +Forest93 +Foresteris +Foreva +Forever Wild +ForeverAlone +ForeverClone +ForeverLost +Foreverett +ForgetThePet +Forgetmenot +Forgetpluto +Forgettios +Forgive +Forgived +ForgottedPin +Forgotten +ForgottenRNG +Forkbomb +Forkers +Forkmitt +Forks Out +Forma +Formal +FormalPotato +Formaldhyde +Former Nub +FormerDivine +FormerSeaman +FormuIa 1 +Fornuis +Forresten +Forsaken +Forsakens +Forsworn66 +Fort +Fort Chronos +Forteh +Fortified +Fortify +Fortimuss +Fortis Lupus +Fortjent +FortniteRox +Fortran95 +Fortress +Fortunes +Forty +Forza +Forza Derby +ForzaGTx +Forzam +Fosh +Fossa69 +Fossil Rock +Fossul +FosterXP +Fostret +Fosz +Foton +Fotty +Foumy6 +Found Prawn +Found3Groots +FoundABaby +Four +Four One 6 +FourB +FourZone3 +Fourlifee +Fourloco +Fournlock +FourthChance +FourthPower +Fowke +Fox Enjoyer +Fox Two +Fox Zebra +Fox243 +FoxStevenson +FoxTherapy +FoxVex +Foxall +Foxe +Foxerx1 +Foxes +Foxfiend +Foxfire +FoxfireStyle +Foxi +Foxing +Foxtrot +Foxx OG +Foxxwild +Foxy +Foxy Rebel +Foxy SuzyQ +FoxyBaphomet +FoxySquid +FoxzHound +Fozbert64 +Fozie +FpsMichael +FpsWheelerrx +Fpsallday +Fr anci5 +Fr ankie +Fr0 +Fr0zEn111 +Fr1ckingH3ck +Fr1xioN +Fr3Pa1est1n4 +FraJoLaaa +Fraagile +Fraazzy +Frab +Frac +Fractals Son +Fractuality +Fraggiux +Fraggle +FragmentedX +Fragmentizer +Frags +Frail +Framed +FramedJunior +Frames Wolfe +Framingham +Franche420 +Francine1225 +Francis0wns +FranciscoJ32 +Franco +Franf10 +Frank +Frank Donner +Frank Is Dog +Frank Lin +Frank White +Frank-sama +Frank836 +FrankMadeME +FrankTTank +Frankers +FrankieFlow +FrankiesAlt +Frankinspank +Franklin1O1 +FrankyFish32 +FrankyLeGros +FrankyyTanky +Frantiks +Franwan +Frappacholo +Fraqqer +Fraser +Fraser840 +Fraspex +Frassboss +Frate +Fratto +Fratty Flows +Fraud Thurgo +Fraught +Frauwz +Fravvomaxx +Frayhalla +Frazer +Frazia +Frazoo +Frazze +Frazzlewagg +Frazzt +Frchtzcker +Fre d +Freaak +Freak +Freako07 +Freako09 +Freaks +Freakxx +Freaky Peet +FreakyWajt +Fred +Fred J Frost +Fred Solo +FredMaxedALT +Fredagsgroda +Fredanbetty +Freddi +Freddiep +Freddy CEO +Freddy ownz +Fredericton +Frederizz +Fredla +Fredleif +Fredo +Fredric +Fredriks +Freds Breads +Free +Free Dumb +Free Minded +Free O9 +Free lootkey +FreeFreeze +FreeFryBread +FreeHongK0ng +FreeKoolaid +FreeTeli2Lum +FreeTheRealD +Freebooterv +Freeczs BTC +Freedom +Freedom06 +FreedomJust +FreedomUP +Freee +Freehky +Freek 1 +FreekALeak +Freekkittens +Freelo +Freeman +Freepop +Freerangee +Freesoul +Freest +Freestylin +Freeway +Freeze +Freeze M E +Freezes +Fregion +Frei +Frekitohh +Freky +FrenchBuoy +Frendi +Frenek +Frenkurt +Frenmiir +Frenzy +Frenzy4 +FreonPays +Fresaaaa +Fresco +Fresh +Fresh Cheese +Fresh Pesto +FreshPotsRS +Freshly +Freshske +Frette +Freud +Frevlin +Frewdy +Freya +Freyas BTW +Frez +FriarNation +Fricas +FriccKip +Frickin +Frickn Playa +FridayDa13th +FridayMojito +Fridelis +Fridfoolium +Fried +Fried Erik +FriedRicePls +Friede +Friend +FriendlyJo +Frietjecurry +Frieza +Frieza Saga +Friezerik +Friggn +Friggy +Friibag +Friisby +Fris +Frisdrank Jr +Frisky Lime +FriskyBiznaz +FriskyJews +FriskyPainal +Fritszon +Frittered +Fritz +Fritz94 +Frix +Frkn +Frnds +FrobroSwagin +FrochioRS +Frodo +Frodo Bagger +FrodoBagGims +FrodoBogues +FrodoRS +Frodoinc1 +Froemelke +Froemeltchhh +Froez66 +Frofuzz +Frog +Frog Blog +FrogBoySlim +Frogfish12 +Froggiefish +Froggit +FroggyBro +Frogmann +Frogone9 +Frogsforjp +Frogtelllow +Frogtoken +Frogwork +Frohobo +Froloox +From +From Beyond +From Florida +From Lebanon +From Nz +FromNewWorld +FromSoftware +Front +FrontBottoms +FrontierEdge +Froobing +Frooby +Froomey +Froot Loop +Frootata +Froppy Tsuyu +Fropul +Frosht42 +Frost +Frost JTS +Frost Mages +Frost_PvM +Frostbiter +FrostedBow +Frostmourne +Frostserpent +Frosty +Frosty E +Frosty Gay +Frosty6570 +Frosty751 +FrostyPea43 +FrostySurge +Frostyfuz +Frostyyyman +Frote +Frotzr +Frovz +Froya +Froyotech +Froz09 +Frozah +Froze +Frozen +Frozen Crown +Frozen Rain +FrozenKing +FrozenMosin +Frozencarrot +Frozenn Dusk +Frozty Feet +Frrrozn +Fru Katt +Frufoo +Frugal +Frugtmanden +Fruh +Fruit Crepes +Fruit Dryer +Fruit Munch +Fruit1824 +Fruit1846 +Fruitbooting +Fruitje +Fruitloop8 +Frunk +FrunktheHunk +Fruta +Frvnk +Frxnk White +Frxnklin +Fry B +Frysta +Fsaze +FtheFrench73 +FuAiluue +FuNrikoz +FuRiouSs +Fubar3d +Fubini +Fubuki +Fubuking +FucDPS +FucNorfKorea +FucaDuc +Fuchsiger +Fudeath36 +Fudg3 +Fudge +Fudgie +Fuel +Fuel Ex +Fuertote_17 +Fuetakishi +Fug +Fug sakes +FugDisFugDat +Fugedit +FuggleQuest +FuggnIronBtw +Fuglemanden +Fuhni +Fuhrerengel +Fujimator +Fujk +FukYeaChina +Fukahi +Fukinnnn +Fukn Lit Btw +Fuktflekken +FulMomentum +Fula +FulgBTW +Fuliss +Full +Full 3A +Full AD Vlad +Full Boost +Full Moot +Full Tilt +Full of Wo0d +FullGraceful +FullSendGoat +FullTimeNerd +FullTryHard +FullerACL +Fully +Fully Mobile +Fullysick +Fulsh +Fumblebag +Fumblers +Fumbles12 +Fumin +FumingMe +Fun Guy mhm +Fun Sucker +Fun1nFunera1 +FunHotBox +FunWithFire +FunctioningC +Fund +Fundo +FuneRune +Funeral +Fungi +Funk +Funk Head +Funk Mastah +FunkBondMule +Funkafiend +FunkiPorcini +Funkiboy2 +FunkiiMonkii +FunkleRoy +Funkr +Funkshun +Funkworks +Funky +FunkyBoy4444 +FunkyDiddler +FunkySlut +Funky_Hunk +FunnelCaker +Funni +Funni Memmer +Funny +Funny-King03 +FunnyAndEpic +Funobu +Funpeople5 +Funrun123456 +Funzip +Fuorra +FuqAgility +FurMissile +Furbs +Furi Potion +Furious +FuriousPower +Furiri +Furo +Furox +Furry +Furry Wall +FurryDemon +Furrykins +FursonaHaver +FurtleTurtle +Furty +Furu +Fury +Fury DnT +Fury Lord +FuryJunky +FuryL0rd +Furyian +Fuse +Fuse is HARD +Fuseton +Fusiiion +Fusion Aurum +FusionGT2 +FussyParter +FutchDuck +Futex +Futss +Future +Future Tense +FutureKaiden +Futureruler9 +Futures +Futures Main +Fuuwah +Fuxley +Fuze +Fuzz Man +FuzzManPeach +Fuzzums4 +Fuzzy +Fuzzy Sox +Fuzzy jaw95 +Fuzzy1918 +FuzzyDonkey +FuzzyFudgey +FuzzyMWV +Fuzzy_NooT +Fuzzybear65 +Fuzzyblaa56 +Fuzzykitty +Fuzzzy +FvS Love +Fweafwe +Fxked +Fxob +Fxrgus +Fxrret +Fy six +Fy12e +Fyitz +Fylberg +Fylize +Fym +Fyr +Fyr Tornado +Fyresam +Fyri +Fyrinlight +Fyron +Fyrox +Fyszz +Fyzio +Fziaa +G +G 0 A T +G A F F E R +G Alfansos +G Ape +G B S +G Check +G Fruit +G GAMER GIRL +G I M Danny +G Iron Adam +G L E N +G L H F +G M B +G Man9822 +G Mauls +G O O D +G O O S E Y +G R E E N +G R I L L O +G Terminator +G X F C +G Zus +G a r t y +G a t t s u +G ante +G dot C +G e n g a r +G eeb +G i j s +G i l b o +G iG +G imme +G iooo +G l R L +G laze +G no Z +G o G G u +G o h o +G o th i X +G oldd +G oldeen +G oofy +G ozz +G rafix +G ronimo27 +G root +G shi +G u a m s +G unitt +G-F-M +G-IronKuv +G-Thug Nasty +G-knowww +G-rivs +G0AT JUICE +G0ATWRANGLER +G0D Richard +G0DLY +G0LD3N +G0LDC0AST +G0LDEN +G0LDENB0Y +G0LDIE +G0NGSHOW +G0OEY +G0TH ANGEL +G0TTY +G0blineer +G0dr3kt +G0dsnotdead +G0ing +G0ld +G0lden +G0rillaJesus +G1C +G1adiador +G1edrelis +G1izzyGob1in +G1m Luna +G3RM4N +G3ZZ4 +G4M3OV3R +G4RG0YLE +G4UAFS +G4YLORD +G4de +G59 Awol +G6E Turbo +G6Wizard +G80 +G99s +GAAANNNGGG +GABBAGE +GAGGED N +GALO9A +GAMMAGARD +GAMxJAKE +GANONd0rf +GAOKNMxzHR +GARDlNER +GATECRASH +GATTl +GB Amarok +GBJackieWang +GCMidlane +GDG +GE IS WACK +GE to FE +GE0RG3WKUSH +GEARLE55 +GEEZ0 +GERANUS +GERRIEE +GEtItFrAnK +GFHL +GFe Aang +GFmanbearpig +GG Joe +GG McCloud +GG Sofie +GG Wped +GG6HJA9KSDHJ +GGGGGGGGanta +GGGskywalker +GGW Limit +GGW Thanos +GGf1cation +GGtoHH +GH05T DUDE +GH95 +GHEEESE +GHETT0JESUS +GI GN +GI Lewis +GI Lucky +GI Madras +GI Mohib +GIANT HENO +GIANT ITIOLE +GIBBO96 +GIGAGUMPH +GIM 0dawg +GIM 2nd +GIM Albin +GIM Aperture +GIM BTWW +GIM Ballak +GIM Barkless +GIM Baylis +GIM Bunzz +GIM C J +GIM CgIsEasy +GIM Composer +GIM Conkers +GIM Cris +GIM DareDev +GIM Derek +GIM Dionysus +GIM Dormant +GIM FatLion +GIM Fearzzy +GIM Ganther +GIM Glalie +GIM Globi +GIM Hatred +GIM Hola +GIM LWE +GIM Lasse_ju +GIM Lazyguy +GIM Lxxs +GIM Lyon +GIM M0FFY +GIM Madac +GIM Magneto +GIM Malphite +GIM Martas +GIM Maudi +GIM Mcstro +GIM Me STD +GIM Mecknon +GIM Mirasei +GIM Moith +GIM NewPorts +GIM OatBloke +GIM Obvious +GIM Or715 +GIM Philrat +GIM Player02 +GIM Qtpie +GIM RWT +GIM RagePope +GIM Raheem +GIM Rakfaan +GIM Ring +GIM Schaa +GIM Schnei +GIM Sense +GIM Snax +GIM Stinks +GIM Stompy +GIM Stoney P +GIM Stu +GIM TUT +GIM Terix +GIM Tman +GIM Tobi +GIM Toe Pic +GIM Ved +GIM Viklok +GIM Wife +GIM Zork +GIM atomic +GIM bad ass +GIM brutal +GIM kerma +GIM poy249 +GIM sabinsky +GIM xDist +GIM-Topsu +GIMAerospace +GIMButcha +GIMFunder +GIMME CLAW +GIMP Crystal +GIMP DlCC +GIMP Jonny +GIMP Suns +GIMP Toast +GIMP Will +GIMP Zuzu +GIMPlayer69 +GIMRavenKing +GIMTruck-Kun +GIM_NoRun +GIM_Snowwolf +GIM_tybraun +GIMcardellio +GIMonster +GIMp Brian +GIMpope +GIMxH2 +GIRTH CHECK +GIronPPVibes +GL GETTIN IN +GL on Purple +GL78 +GLG Sophie +GLUS +GLWeAllDie +GM Matt +GMEMan8000 +GMKirby +GNULinux +GOAT GOD 420 +GODSOMBRA SL +GOGETA +GOLOVOLOMKEE +GOOD +GOODGAMEGGXD +GOP DUMB +GOZERGAST +GPA +GPWASTER +GR0OOT +GR1NCH +GRAB-A-LEAF +GRAN1T3 +GRAND +GRAPHISTED +GREIV0US +GREIVUOS +GRIMSTAIN +GRINGOLAO +GRUMPY +GRUMPY BSTRD +GRUMPY PAPAW +GRYGRY +GRiMZ +GRiMZ 420 +GRlM +GRlM REEFER +GS Concerta +GSAileen +GSW Shane +GSwolls +GT350 +GTA SA +GTFOIMGAMIN +GTOD +GTRKingZilla +GUBIDUBII +GUCCI SENPAI +GUCCl +GUJ0 +GUNMAN683 +GURRD +GUUMBY +GVSU +GYDtown +GZA +GZX +Ga l +Ga7ba +Gaara +Gaara Sand +Gaarden +Gaarise +Gaarlokiin +Gab al Ghul +Gabagoo l +Gabber +Gabber NaTaN +Gabberboy15 +Gabble +Gabe +Gabe020 +Gaberoks +Gabesz +Gabo +Gabrahanth +Gabriel61198 +Gabris +GabyabyxD +Gacha +Gaddgedlar +Gadrak +Gadwall +Gaerolth +GaethjeKO +Gaga +Gaga Iron +Gage S +Gageks +Gagne +Gahbo +Gain +Gain exp +Gainful Grey +Gains alot +Gainz Godz +Gainz Nerd +GainzForHire +GainzWorld +Gainzvill +Gainzville +GaiusTavi +Gaiy +GalGadotsBF +Gala G +Galamx +Galandorf1 +Galar +Galava +Galaxia +Galaxiancam +Galaxies +Galaxy +Galbazeek1 +Galderr +Galdysa +Galgenbrok +GalickGunner +Galilee +Gallaxy +Galleta +Gallium +Gallowbell +Galon Garuda +Galon1 +Galow +Galton +Galvatron +Galwic +Galyam +Galzuk +Gam +Gamaiiron +Gambinahuora +Gambino +Gambit +Gambit Ghoul +Gamblerz +Gamboy46 +Game +Game Clown +Game Name +Game Of Olms +GameBot2000 +GameOvaries3 +GameStop +Gameboto4 +Gameboyjr +Gameboylight +Gamelia7 +Gamer +Gamer Log +Gamer Worded +Gamer4Life +Gamercutie +Gamerplaya7 +Gamerr +Games Rigged +Gameshow +Gamesman +Gaming +GamingLover +GamingVapor +Gamir Von +Gammel Mand +Gamorrah +Ganandalf +GandaIfNoir +Gandalf +Gandalf staf +Gandalf3602 +GandalfBalle +Gandhi +Gandolf +Gandolpeeni +Gandon12840 +Gandulff +Gane +Gang +Gang Goblin +Gangbarang +Gangnrad +Gangris +Gangry +Gangsta +Ganj +GanjaGhandhi +GanjaRhino +Ganjoefarner +Gankicus +Gankster +Ganna Bogdan +Gannicus +Gannicusproo +Gannnon +Ganooch +Gansa0 +Ganta +Gantee +Ganthorains +Gantre +Ganzaxuz +Ganze +Gap Tester +Gaping +GaratholX7 +Garbage +Garbage Life +GarbageEater +Garbagexd +Garbar6 +Garboh +Garbug +Gardenia +Gardening +Garder1968 +Garena +Garfinator +Gargano +Gargaspoon +Gargath286 +Gargathon +Gargleon +Gargoyle79 +Garlic +Garnat +Garnet Gust +Garp +Garrb3ar +Garrett +Garretttt +Garrothis +Garthoon +Garvis +Gary +Gary Ghee +Gary Giggles +Gary Guldske +Gary Linkov +Gary Wang +GaryDabs +GarySmokeOak +Garyjayjay +Garysson +Gasconade x +Gash Pasher +GashBndicoot +Gashtag +Gassy +Gassy Cat +GassyFlaps +Gastje888 +Gastronaught +Gate +Gateofdoom +Gath +Gato +GatoNaranja +Gator +Gator Bob Jr +Gator Papi +Gatorboiz +Gatorian176 +Gatorslyr +GatrsNTaters +Gau Cho +Gauntlet +Gaur Gura +Gauss +Gautstafer +Gauvin +Gavbin +Gavi +Gavii +Gavin Dance +Gavita +Gavrot +Gavussy +Gavy +Gawd Bodi +Gawk5000 +Gawkes +Gawkss +Gawt +Gawz +Gay 4 Guthix +Gay Bear +Gay Bear Cub +Gay Farm +Gay Fieri +Gay Framed +Gay Holly +Gay Impling +Gay Liam +Gay Male69 +Gay Snake +Gay Squire +Gay Vermin +Gay Wimp +Gay450Bucks +Gay4Ketchup +GayWalrus69 +Gayblade +GaylsHaram +Gayme +Gayron +Gaz +GazGoon +Gazaman11 +Gazan +Gazd +Gazed +Gazed Soul +Gazelle2211 +Gazru +Gaztok +Gazza +Gbax-Style +Gdey56 +Ge0rgeburton +GeChallengeM +GeTLeFt1 +Gear 5th +Gear Carried +Gear Fear +Gear Sekando +Geard +Gearfried +GearheadSTL +GebwellB +Geck-o +GeckoDad +Gedmuush +GeeHasMews +GeeStreet +Geeb +Geebs +Geebster +Geef Bier +Geegles +Geeker +Geeknip +Geeman125 +Geen +GeenBankMan +Geera +Geerin +GeertWillows +Geestig +Geeving +Geewd +Gefilus666 +GeggaMoya +Gehrman +GeilTijgerke +GeilePaddo +Geitekaas +Gekido +GekkaJohn +Gekke +Gekke Farmer +Gekke Nelis +Gekke Pablo +Gekkesmurf +Gekoh +Gekolian +Geks +GelZmog +Gelawynn +Gelderlander +Gelezis +Gelijk +Geliquideerd +Gellaitry +Geller Bing +Gelly +Gelmar +Gem +GeminitusII +Gemlingur +Gemsbok +Gen Kokopuff +Gen4 UU +GenCoupeGang +GenFormat +GenGraardor +Genabackis +Genann +Genaron +Gene Shorts +GeneBelcher +GeneDenim +GeneKapp +GeneVieve_SL +General +General Aldo +General Bigi +General Iroh +General NL +GeneralJosh +GeneralLudd +GeneralMcRib +GeneralMo +GeneralMoist +GeneralNASTY +GeneralPlay +GeneralStore +Generall +Generall_xx +Generalton +Generol55 +Genesee +Genesis G80 +Genetiics +Genetiz +Genga r +Gengahr +Gengerbred +Geni +Genie Magick +Genie Talls +GenitalsHead +Genix +Genjitatsumi +Genk +Gennie +Gennu +Geno +Geno RS +Geno2566 +GenoJuice +Genocidal +Genovan +Genres +Gensha +Gentileza +Gentle +Gentle Death +Gentle Gypsy +Gentleman J +Gentlemanfox +Genty +Genuine +GenuineDude +Genus +Geo Fe +Geo Geo +GeoDuuud +Geoculus +Geodark +Geof Sux 666 +Geoff_Failed +Geoffry +Geography +Geoguess +Geoide +Geologistic +Geomatic +Geonde +Geordie +George +George 36th +George F M +George Vv +GeorgeJx93 +GeorgeVork +Georgey +Georgezs +Georgies +Georgopol +Geoso +Geotechnicki +Geovanna +GerAmi +Gera1d +Gerald +Geralt Nivea +Gerb3 +Gerberos +Gerbs +Gerbz +GerdyofRivia +Gergery +Gerjan +GerksShirts +Germaan +GermanGuyRS +Germanic +Germaphobic +Germimo +Gernoazi +Gero +Geroko +Gerr Hurka +Gerrido +Gerrmz +Gerroes4GIM +Gerry Bud +Gershboon +Gert +GertrudeSimp +GertrudesAss +Gery07 +Gesaldo +Gese +Geskar +Geso +Gesoz +Gestetner +Get A Life B +Get Back Son +Get Bread +Get Exp +Get Fukt Pal +Get Pho +Get Syked +Get0nMyHorse +GetABeerInYa +GetATapWater +GetAclick +GetDatXp +GetMeOut +GetMeOutHere +GetOnMyLvl +GetOverlt +GetPets12 +GetSkipped +GetThatUpYaa +GetTogether +GetUrWild0n +GetWreckdSon +Getdolphined +Getfck3dup +Getlow777 +Getplayed +Getsu +GettinTanked +GeudensK +Geuld +Gew +Gewoon +Gezang +Gf g +Gf4tiuser +GfRsIGotAGf +Gfi +Gh3t0 T4nk3r +Ghafir +Ghaipol +Ghandizy +Ghandy +Gharron +Ghckkrchkrer +Ghda +Gheed +Ghentiana +Gherkins +Ghetto +Ghhjgwsr +Ghidorah +Ghillie Suit +Ghilly +Ghoosted +Ghorraka +Ghosnik +Ghost +Ghost 311 +Ghost Ahoy +Ghost Fe +Ghost XP +GhostAralein +GhostHouse +GhostOrchids +GhostTank +GhostXD +Ghostas +Ghosteeen +Ghostfice +Ghostflips +Ghostiami1 +Ghostly Taco +GhostlyFetus +Ghostlyowns +Ghostninja +Ghostsu +Ghostwish492 +Ghosty +Ghoul Intent +Ghoul Zeta +Ghraz +Ghruntsarokk +Ght179 +Ghurrix +Ghuuneiboi +Ghxul +Gi Lew +Gi bbo +Giallo +Giant +Giant Ego +Giant Gochu +Giant Killer +Giant Peenos +Giant Plums +Giant Trunks +Giant spider +Giant235 +GiantConker +GiantShafty +Giantesss +Giaveri +Gib bread +GibMePets +Gibbed +Gibberish +Gibboh +Gibbon +Gibbon girl +Gibby +Gibby0712 +Gibbzzy +Gibsky +Gibsmeister +Gibson +Giddy Cowboy +Giddy Yup +Gidejong +Gidionn +Gidle Soyeon +Giebu +Gielinor +GielinorGage +GielinorGoat +Gielinord +Gielinored +Giena +Gier +Gierige +Giffaro +Gifgas +GigaBinary +GigaChad FSW +Gigabit +Gigantic Nut +Gigantic Owl +Giganttio +Gigashit +Giggel Boy +Giggety +GiggleFailer +GiggySmalls +Gigi +Gigime +Gigs x0rz +Giiblo +Giiirtz +Giitzy +Gijoe184 +Gijs +Gijsbart +Gilan +Gilbert +Gildart_91 +Gilded +Gilded Gucci +Gilded Robes +GildeddGuppy +Gilenoth +Gilesy_93 +GilgaGaming +Gilindur +Giljom +Gillan +Gillbert44 +Gille +Gilles +Gillisuit +GillyChop +Gillyjj +Gilnash +Gils +Gilthresa +Gim Balboa +Gim Mayhem +Gim Reaper x +Gim Rickard +Gim Sahara +Gim Synicals +Gim ckn +GimJonel +Gimaralas +Gimbli102 +Gimlocke +Gimme +Gimme Pixels +GimmeDatWAP +Gimmie 500k +Gimp Charona +Gimp George +Gimp Rachau +Gimp Sage +Gimperfect +Gimpgas +Gimptan +Gin N pizza +Gin Theory +GinValid +Gina Linetti +Ginekologs +GingaFe +Gingaaaaa +Ginger +Ginger Elvis +Ginger KG +GingerUnit49 +GingerZ94 +Ginger_Men +Gingerbeefe +Gingr +Gingr Snaps +Gingyge +Ginjaah +Ginko Sora +Ginny +Ginobeatsss +Ginyuu +Gioarcher69 +Giorgi +Gios Ladder +Giovanniam +Giovano +Gippeo +Gipson +Giraaa +GiraffeLord +Giraffeneck +Girl +Girl10116 +GirlGamer420 +GirlLoveeee +Girls +Girls Add Me +Girlygurl420 +Giroza +GirrthBrooks +Girsu +Girth +GirthBeast +GirthMatters +Girthy Bunny +GirthyBaboon +GirthySack +Giskardr +Gist +Gistermorgen +Git Ducked +Git Gudr +Gity +Giuuntas +Give +Give Advice +Give Er +Give Me Kith +Give Purple +Give Purples +GiveMeMaul +GiveMutagen +Given +Given Bow +Given Power +Givera0 +Giville +Giving +Givox +Gixerikan +Gizmoed +Gizmoo247 +Gizzy-71 +Gj nice +Gjerloew +Gjonunaki +Gktr +Gl Bob +Gl Im Dandy +Gl Im Tom +Gl0ver +GlLDARTS +GlM Sam +GlMKingCole +GlMP Blue +GlMP Purpp +GlNGER +GlRLS +GlTHUB +GlUwUten +Glaceon Girl +Glacial +Glacial Fog +GlacieredTig +GladePlugIns +GladeSONPT +Gladeandy +Gladiator12 +Gladiator4x4 +Gladpootje +Glads +Glaeser +Glaive Rush +Glance +GlasMelk +Glasabarn +Glashute +Glass talons +GlassIsrael +Glassblow Me +Glassface +Glava +Glavas +Glazmeister +Glazyy +Glcnn +Glcnn II +Glcsw +Gleassi +Gleddified +Gleep +Gleesoman123 +Glejak +Glen +Glen Cook +Glen Kenobi +Glen OSRS +Glenbobis +Glennis25 +Glennitals +Glennyboy +Glennzii +GleuberBTW +Gleythar +Glicky +GlideWho +Glierieman +GlitCH1221 +Glitchfather +Glitchxd +Glitterix +Glo-Tank +Glob Master +Globalled +Globby +Gloc +Glock +Glock 48 +GlockHoliday +Glockford +Glocktopuss +Glocs +Glod +Gloei +Gloei Lampje +Gloom +Gloop +Glopyz +Glorfsaus +Glories +Glorious +Glorpy Glorp +Glossay +Glou +Glough +Gloves +Glow +Glowing Dawn +Glowing Ray +Gloyer +GlucGluc9000 +Glue +Glue Scroll +GlueInhaler +Gluehbirne +Gluest1ck +Gluhh +Glukoosi +Gluons +Glut +Gluteeni +Gluten ei +Gluteous +GluteyIM +Gluurbuur +Gluurder +Glyn +Glyo +Glys +Gmackie1 +Gmic +Gnaes +GnakNim +Gnarkotics +Gnarled +Gnarles +Gnarly Nacho +Gnarlysurfer +Gnarmato +Gnarnold +Gnarwhal +Gnashit +GngBng +Gnge +Gnight +Gniles +Gnoblin +Gnome +Gnome Ass +Gnome nz +GnomeBustas +GnomeChompii +GnomeFN +GnomeScarf +Gnome_child1 +Gnomeball Me +Gnomedalf +Gnomeopathy +Gnomeplay +Gnomeputone +Gnomerex +Gnomeruno +Gnomes +GnomesDid911 +Gnomonkey +Gnomuim +Gnon +Gnoob +Gnorc +Gnos +Gnosticz +Gnotyep +Go Already +Go Die +Go Do One M8 +Go FF +Go Outdoors +Go Outside +Go Rogue +Go Thanos +Go ask Wiki +Go2HornyJail +Go4Stonks +GoBearsUA +GoBiiii +GoDhAsCoMe2u +GoDrinkWater +GoGGu +GoIsland +GoPlayOutsid +GoSlow +GoToBedKids +Goads +Goal2Max +Goalkeeper54 +Goals +Goat +Goat Toes +Goat512 +GoatAteMySon +GoatOfWar +GoatStank +Goatbigboy +Goaticorn +Goatman +Goatmelk +Goatrilla +Goats +Goatsky +Gobbie +Gobiasinds +Goblin +GoblinBreath +GoblinLevel1 +Goblinborn +Goblinchips +GoblinxSlaya +Goby358 +Gochancee1 +God 126 +God Aye +God Bjorn +God Flax +God Forgave +God Like PvM +God Of Chips +God Of Hatrd +God Of Lamps +God Of W13 +God Pandora +God Ranger90 +God Tier +God of Walls +GodDmntNappa +GodEmpsTrump +GodHalfMercy +GodKingJT +GodLovesG4ys +GodM +GodOfCats +GodOfTorment +GodSaidGrind +GodSaved +GodSlayer422 +GodSoge +GodTierAcct +GodTormentor +Godaa +Godcody +Godd Is Good +Goddaz +GoddessAmaya +GoddessHylia +Godenzonen +Godeso +Godezzo +Godfather TR +Godfather9 4 +Godis +Godkip +Godleh +Godlike Nico +GodlikeOne +Godly +GodlyLeecher +GodlyThug +GodofAhri +Godofore +Godofyou2 +Godric777 +Godrics +Gods +Gods Madness +Gods Plans +Gods Savage +Gods Taint +Gods Word +GodsBlackSon +GodsSniper +GodsSyndrome +GodsZombies +Godsent +GodsentHero +Godspade +Godss Angel +Godstrong +Godswordl +Godte +Godumas +Godvermomme +Godwar +Godwise +GodzFear +Godzilla +Godzilla1282 +Goed +Goed Gedaan +Goed stinke +Goedaardig +Goedgemutst +Goeie Sannie +Goeman +Goes +Goggoli +Gogo +Gogo Gorilla +Gogojuice +Gogoud +GogurtYogurt +Gohan +Gohanski +Gohler +Goiij +Goilin +Goin +Goin Slayin +Going HCIm +GoingBald130 +GoingBonkers +Goinvokeman +Gojam +Goji Berries +Gok Wan k +Gokillanoob +Goku +Goku 420 +Goku Nazz +Goku3ss3 +Gokuu +Gol +Gol D Stocks +Gold +Gold Avocado +Gold Devill +Gold Golem +Gold Lynx +Gold M40A3 +Gold N Mole +Gold Ox +Gold Ruler +Gold Scrap +Gold-Ileana +GoldTracerR1 +Goldclaw30 +Golden +Golden Acorn +Golden Dunes +Golden Eyes +Golden Power +Golden2Aim +GoldenArm647 +GoldenGoose +GoldenMinion +Goldendev +Goldendrgn +GoldfarmCOX +Goldie47 +GoldieOne +Goldiekk +Goldkimono +Goldless +Goldmagic +Goldmagic 1 +Goldminer727 +Golds +Golduck +Goldy Mox +Golem +GolemDuoGIM +Golemantium +Golembaby +Golf +Golf Socks +Golfcarts +Golfje92 +Golfkarton +Gollito +GolloSam +Gomardo +Gomham +Gomsugo +Gomut +Gon +GonDaba +GonFeeshin +Gonah +Gonapappa +Gondort +Gone +Gone9237 +GoneClear +GoneFarming +GoneInDry +GonjaMon +GonnaSleep +Gont +Gontr +Gonyor +Gonzalo +Gonzra +Goo Cat +GooMoonRyong +Gooball +Gooberz +GoobledeGoop +Goobtacular +Good +Good Bull +Good Creb +Good Cuxt +Good Darts +Good Duck +Good Ironman +Good Natured +Good Pho You +Good Potato +Good Voodoo +Good lol +GoodFight +GoodGuyJosh +GoodOlBussy +GoodSkinCare +GoodTalk BRO +GoodVibes +Gooda4 +Gooday2uall +Goodbye +Goodbye game +Goodcents +Gooddeerend +Gooder Album +GooderB0aty +GoodlyKi56 +Goodole +Goodpizza +Goodriver +Goodwin +Gooey Bace +Goofy +Goofy Kitten +GoofyLlama +Goofzillers +Googagoogago +Googie +Googii +Google +Google Plus +Google THC +Googleisme +Googs +Gool164 +Goomy +Goon Galore +Goon Rangoon +GoonRNG +Gooner +Gooneshy +Gooney +Goooby +Gooochy +GooodO1dDays +Goopbandit +GoopityGlorp +Goose +Goose Field +Goose World +GooseAlmyti +Goosebottle +Goosecaboos +Goosely +Gooshus +Goostafus +Goothan +Gooziky +Goph +Gopherpaws +Gophurr +Gopuppy +GorGorDon16 +Goragtong +Gorak +Gorastaman +Gorathe +Gorazdus +Gord +Gordi +Gords +Gore +GoreTexZ +Gorehogthot +Gorg +Gorge002 +Gorgeous +Gorgeous Vin +Gorgeous War +Gorgonsolo +Gorgoth +Gorila911 +GorillaChad +GorillaHaze +GorillaMon3Y +Gorillr +Goriox +GorkOfGuthix +GorogSmash +Goromi +Gorons Ruby +Gorpie +GorskiGG +Gortron +Gory Figment +Gorzie +Goshiki +Gossip +Gosustyle +Got Mad Nugz +Got my DD214 +GotABigDoing +GotItAll99 +GotTheTool +GotchuXL +Goteborg +Gotemburgo +Gotham Steel +Gothic Mommy +GothicHippy +Gothicking70 +Gotta +Gotta B Dope +GottaSlay +Gottaburn +Gougar +Gountor5 +Gourd +GourdPicker +Gourmandise +Gourmet +Goy Boyy +Goy Oy Vey +Gozi +Gozpot +Gp On Me +Gr OO7 +Gr0tti +Gr33n +Gr3at Noob +Gr4naat +Gr4p3 +Gr4y W0lf +Gr8Legacy +Graaf Mol +Graardad +Graarp +Graav +Grab +GrabAColdOne +GrabbaLeaff +GrabsPeePee +GraciousHeeb +Grade I +Graenmeti +Grafie +Grafvs +Graham47 +Grain +GrainUhSalt +Grainfedbeef +Grainter +Grainwave +Grainys +Grakron +Grallham +Gram othy +Gram0fDabs +Gramalio +Grambo +Grammar +Grammar Naxi +GrampaDreami +GramsaySan +Gran +Gran t +Granbyboys69 +Grand +Grand Magpie +Grand Tree +Grand mb +GrandErected +GrandSlash +GrandVince +GrandWizard +Grander LTU +Grandikid +GrandmasterT +Grandmasters +Grandpa +Grandpa H +Grandwarlike +Graniitti +Granite God1 +Grannolegs +Grannt +Granny Tiddy +Grant +Grant LLKL +Granto +Grantos1993 +Grants2004 +Grape +Graphics +Grappleshot +Graros +Grasp +Grass Nugs +Grasshoppper +Grassman-420 +Grast1z +GratefulFunk +Gratefulfunk +Gratis +Gratitheode +Graudalin +GraveDiqqer +Gravecan +Graveless +Gravenor +Graves +Gravew0rm +Gravitrons +GravityPulse +GravyTugboat +Grawgar +Gray +Gray Goo +Gray Icon +Gray Nine +Gray Owl +Gray Sails +Gray Wolf31 +GrayXOF +Graybanns +Grayden +Graymarrow +Grayola +Grays Peak +Grayv +Grazalay +Grazia +Grazing +Grazing Goat +Grazium +Grazuz +Grazy Killah +Grazzak +GrcRevisited +GreFunky +Greally +GreasierNerd +Greasy +Greasy Nerds +GreasyGoose +GreasyKnucks +Great +Great Catto +Great Dain +Great Sneeze +GreatBritain +GreatFambino +GreatGinGin7 +GreatNorth +Greater Rev +Greaterbeing +Greaterwang +Greatgranpa +Greatwhite62 +Gredhkj +GreedyFox +GreedyG4me +Greek +Greek Bust +Green +Green Floyd +Green Gh0st +Green Guru42 +Green HoHo +Green Molly +Green O +Green Theory +Green noob +Green0ktober +GreenBstard +GreenClue +GreenCortex +GreenMonstah +Green_Matcha +Greenbeens1 +Greenboy638 +Greendor +Greene Daeye +Greenikulas +Greenmusiq +Greenwell +Greenwolf666 +Greg +Greg Bcknghm +Greg M +Greg NM +Greg Why +GregLAD +Greggery +Gregley +Gregobeast69 +Gregor itos +GregorJesk +Gregornaut +Gregory +Gregoryxo +Gregreg +Gregsdabomb +Gregy165 +Greh +Greig +Greil +Grej +Gremlin +Gremoir +GremorysPawn +Grena +Grenadev +Grenenjah +Grenthyl +Gressaker +Grewal +Grey Beards +GreyCheddar +GreyStation2 +Greyballes +Greybird +Greyhound00 +Greyhounds +Greyhunter +Greytness +Grider +Griefstonks +Grieve +Grieve r +Grieve4Nieve +Grievedd +GrifSpice +Griff Please +Griff6GG +Griffey +Griffeydor +Griffimano +Griffin +Griffin 900 +Griffinerr +Griffoo +Grifo +Grifwin +Grihm +Grilby +Grill Bears +GrilledNem +Grim +Grim Lahey +Grim Reapr +Grim1O +GrimR +GrimRequiem +Grimalkinn +Grimby +Grimescene +Grimey17 +Grimfeather +Grimhimblem +Grimm +Grimm Malice +Grimmauld +Grimmij0w +Grimmjaww +GrimmjowCero +Grimmlie +Grimms Baane +Grimnitro +Grimple +Grimreaper22 +Grimsomebody +Grimwar +Grimwold2 +Grimy +Grimy Elf +Grimy Ghetto +Grimy Guamay +Grimy H +Grimy Lord +Grimy Oppie +GrimyBuchu +GrimyIndica +GrimyPussy +GrimyRanarrs +GrimyTorstol +Grimz Reapin +Grimzyy +Grinchy +Grind +Grind 4 Max +Grind 4 Pets +Grind Time +Grind4Life2k +GrindAndGame +GrindFaster +Grindcorr +Grinder +GrinderTo99s +Grindin +Grindinator +Grindius +Grindlwald +Gringotts +GrinoReigns +Gripzakje +Gris Moor +GrittyTacos +Griz mobile +Grizmatik +Grizzley +Grizzly +Grizzly Rock +GrizzlyCares +GrmblGrombl +GrnBstrdO_o +Grobar20 +Grobaz +Grod15 +Groen Hertje +Groene +Groesbeek +Groet +Grog Dog +Grog Mobster +Grogget +Groleo +Gromada +GrommrUK +Gromp Love +Gronk +Gronky +Gronky Mutt +GroogeN +Groot Lol +GrootPool +GropeJelly +Gros +Gross +Grosyte +Grot I +Grotegelds +Grotkop +Grotty +Grottyzilla +Ground Hawk +GroundGolem +GroundRanarr +Group Int +Group Pig +GroupAaronMn +GroupSexyMan +Groupie Hugs +GroupieSheep +GroupyCoopy +Groves +Grow Culture +Grow a Set +Grown +Grown ups 2 +Grrh +Grrim +Grrr17 +Grrrrrrr +Grubbfoot +GrubbyNative +Grubumas +Grucci +Gruglio +Grum +Grummmy +Grumpy +Grumpy Bear +Grumpy Dane +Grumpy Rock +GrumpyBean +GrumpyFire +GrumpySkelly +Grumtuque +Grunderzz +Gruntlife +Grupopo +Grwl +Gryff1n +Gryygeri +Grze100 +Gschlez +Gsef +Gsuz +Gtacoolz +GtheSquid +Gtotgt +Gtr Zilla +GuBoki +Guadanha +Guak +Guaka +Guala +Guam +Guam Autism +Guam Extract +Guam Leaf +GuamFarm +Guapify +Guar +GuardMaze +Guardhakan +Guardiaaan +Guardian726 +Guardy +Guason +Guataca +Gubrew +Gucci +Gucci Print +Gucci Sheets +Gucci Skrrt +Gucci0 +GucciBalboa +GucciChris +GucciDang +GucciDragon +GucciMedHelm +Guccifi +GucciiFlops +Guckle +Gudfad3rn +Gudge +Gudginator +Gudmen +Gudomligt +Gudown +Guelph +Guernicaa +Guess I Did +Guest738 +Gufix +Gugaru +Guidebook +Guidefox +Guido Bwana +Guildboss +Guile +Guilles123 +Guillotine +Guilou3 +Guimmy +GuineaHorn +Guizompaz +Gukkiman +GulTraktor +Gulf +Gulmek +Gulpar +Gulpin +Gulsaft +Gum +GumGum B +GumGum Fruit +Gumat0s +GumbleChunky +Gumbygerkin +Gumbygrump +Gumbygusher +Gumbypriest +Gumiibear +Gummi +Gummibier +Gummy +GummyTushie +Gumpie123 +Gumri +Gun +Gunalations +Gunci +GundarV +Gundrace +Gundrak +Gune +Gunfire +Gunite +Gunjamini +Gunman +Gunn a +Gunna +Gunnar +Gunnawr +Gunner556 +Gunnolvur +Gunny +GunnyGuest +Guns +Guns Up +Guns n Rozes +GunsN +GunsN Roses +Gunshow36 +Gunsmith95 +GunsonGurner +Gunta Guy +Gunter +Gunteria +GuntherNese +Gunthie +Guntilius +Guntown +Gunvald1 +Gunwil +Gunzyx +Gupto3 +Gura +GuraChan +Gurahka +Gurchh +Guren +Gurenz +Guri77 +Gurilovich +Gurke +Gurkes +Gurnie +GurningPills +Gurnsy +Gurog +Gurp +Gurp Gork +Guru Pathik +GuruOz3 +Gus is Maxed +GusMagnel +Gushing Thot +Gusmamba +Gustav +Gusten +Gustice +Gustie1 +Gusty x +GuteArbeiter +Gutenberg +Gutenberger +Guthiccz +Guthix +Guthix Boss +Guthix San +GuthixIsBae +GuthixVapes +Gutti +Guuds +Guus geIuk +Guusman +Guwaap +Guwapp +Guwgle +Guy Shishioh +Guy Williams +Guy in hat +GuyBillNye +GuyDude +GuyHarvey +GuyInReaLife +GuyOnaBear +GuyOverThere +GuyintheChat +Guyringo +Guzas +Guzman Loer +Guzzle +Gvjordan +Gvzy +Gwaas +Gwas +Gwas BE +GwasMaster +Gwasha +Gwasing +Gwaztec +Gwd +Gweav +Gween Dwagon +Gweeve +Gwellz +Gwenchanaa +GwigMate +Gwimer +Gwinter225 +Gws 2 +Gwu +Gwublin +Gwyn +Gwynrwyn +Gxhost +Gyanzin +Gyga +Gym Beam +Gym Is Home +Gym then GYG +Gymming +Gymp +Gynn +GypsyAvenger +GypsyTears +Gyrati0n +Gyro +Gyroman +Gyrotta +Gytisr9 +Gyts +Gyym +Gz Parsec +GzBs +H 0 U N D +H 2R +H A D O +H A I D E S +H A M M E H +H A R L S +H A T +H A X 3 D +H D M P +H E A L E R +H E J S A N +H O L M E +H Q Killer +H S 7 +H U L K K +H U N A J A +H a t y +H a w n y +H abs +H alo +H ch +H e c t o r +H i n e s +H l E U +H obbs +H owl +H rekDoer +H uff +H-tsi +H0B0 +H0DEX +H0LINESS +H0NA +H0PES +H0RSEFIGHTER +H0RY +H0j +H0j00 +H0lyPorkyPig +H0me +H0nestyBe +H0wy +H1GH +H1gh +H1gs +H2 Ninja +H20magic +H22a +H2GivesUTheD +H2HO +H2Okt +H2R +H3AV3N1Y +H3NNESSEY +H3adBurner +H3ll +H3llg0g +H3nti3 +H3rbMaXD +H3rbs +H3rioon +H3xxar +H4RD P V M +H4RD PVM +H4wk0n +H501 +H61 +H8 +H8rry +HA RD +HACHE +HADYYY +HAHA CODY +HAMMY P0TTER +HANDLEwCARE +HAOKIMALONE +HARVEY +HARYWERNASDA +HASA +HAUS DOSAN +HAWGCRANKD +HAXERFUGGv2 +HBPandox +HBTFD +HBTurpin +HC DVS +HC Diego +HC H R A D +HC HALLEN +HC J P +HC Lone +HC Nitsy +HC PogChamp +HC Tehl0rd +HCByTheWay +HCIM +HCIM Freak +HCIM Telmo +HCJynkky +HCTHB +HCaturbate +HCgenes +HClM +HCmunchies +HCquitter +HCsndr +HDGamerLewis +HDarcticus +HEAD TURNER +HEADLlNES +HEAVYWElGHT +HEAVYWORK +HEJNUS +HEL1O +HELPPOLOTO +HELl0S +HEMSKl +HEMULIN LADA +HER0X +HEREforPETS +HERYWERNASDA +HEWlTT +HEXISZ7N510Q +HElMDALLR +HElSENBERG +HFH141 +HGCduke +HGHZ +HHans +HI IM XP +HI lM SATAN +HICK +HIHIHl +HIKI VALUU +HIM thespaz +HINEaKIN +HKD +HL8ight +HM-O3 +HM01Urself +HM01Yourself +HM02YouFools +HM05 +HM05 Flash +HMFIC +HMR9 +HMS Bass +HMTickle +HMWRCKR +HO NK +HOB0MAN +HODL DEEZ +HOKIE +HOKIE II +HOLDUP +HOMIE_SNKE +HOOD +HOOLlGANS +HQ140 +HR palvelut +HRVRD +HRZ Dennys +HReversti +HT Hero King +HTKBeast +HTTP +HUGE +HULKSMASH +HULL CI TY +HUMANATSIGHT +HUMPING +HUUTIS +HVSG73373535 +HWFG Jordan +HYDROPWN1C +HYPEHYPEHYPE +HYPERTAIKURI +HYPOXD +Ha Tsjoe +Ha Yea +Ha rrison +Ha ss +Ha1fWayCrook +HaClintondix +HaKooro +HaMwise +HaNamer +Haaaa +Haaaydeez +Haar-Xil-MES +Haarde Knud +Haardest +Haarvey +Haavard +Habaneros +Habbitatt +Habib +HabsWin2021 +Hachune +Hacien +Hacis Zone +Hack McGraw +Hackdash +Hacked +Hacked Here +HackermanJS +Hackett116 +Hackie +Hacklang +Hacky +Had Enough +Had2hurt +HaddlingOS +Hadeees +Hadei +Haderlumpen +Hades +Hades m8 +Hadezzz +Hadhod46 +Hadies205 +Hads MC +Hadyen +Haelendur +Haell +Haemogobl1n +Haertyew +Hafco +Hafcos +Hafdis +Haffamilleon +Haffie +Hagaar +Hagedis +Hagenau +Hagenees +HaggisChaser +HagridGone +Haha +Haha noob +HahaBonk +HahaYes +Hahaha +Hahalord888 +HahnSuperDry +Hahru +HaiDiLao +HaiHai +HaiIZaros +Haiaf +Haiden +Haidynn +Haighy +Hail to Pitt +HailYeah +Hailie Jade +Haio +Hair +HairNotFound +Hairy +Hairy Batman +Hairy Dery +Hairy Hobbit +Hairy Hooker +HairyCave +HairyGirls76 +HairyLatino +HairysJungle +Hairyteddybe +Haissi20 +Haiten +Haitze +Haizet +Hajduk +Hajj12 +Hajkiii +HakGwai +Hakafissken +Hakala +HakanTheMad +Hakaniemi +Hakattu +Hakeem +Hakkie +Hakkua +Hakozuka +HakunaWHO +Hakuryuu +Hakwai +Hal Jordan +Halaal +Halal 1 +Halal Burger +HalalSnakbar +Halaladdin +Halbrand3791 +Halcony +Halcyon Myth +Haldir +Haldir140 +Haldun +Hale +Hale End +Half +Half Volley +Half a Cig +Half a Worm +HalfAb0rted +HalfHawaiian +Halfdanger +Halfway +HalfwayOkay +Haliax +Halibelle +Halipatsuife +Hall +Hall of Fame +Halla +Halla-Aho +Hallako +Halleloja +Haller +Hallo Knul +Halloman71 +Hallonkram +Hallowed +Halls104 +Hallucianter +Hallucin8d +Hallufauz +Halluusio +Halo +HaloMisfit +Haloboy +Haloking176 +Haloman6666 +Haloo +Halseys +Halsly +Haltrek +Halujo +HaluunKeksin +Halve +Ham Dip +Ham Turkey +Ham r +HamHawk +Hamada +Hamaken +Hamataka +Hambam55 +Hamburgor +Hambzy +Hamdulilah +Hamed +Hamel +Hamii +Hamis +Hamlee +Hamm +HammZ +Hammer +Hammer Man +Hammer4422 +Hammer4442 +HammerTime29 +HammerTine +Hammered +Hammertime +Hammond +HamnerTime +HamoodyShimy +Hamp +Hampton Bays +Hampus +Hamrocks +Hamsterslayr +Hamstr +Hamudiy +Hana the Mad +Hanashee +Hand Puppet +HandTuggy +Hande +Handecapped +Handex +Handicap +HandleofJD +Handley +Handphone +Hands +Hands Hurt +Handsome +Handsome Rob +Haneet +HanekawaSimp +Hanfkeks +Hang +Hang em high +HangChowCrow +Hangin +Hangin Nuts +Hanhen +Hani +Hanikala +Hank Jackson +Hank T Tank +Hank343 +HankTheTank2 +Hankanini +Hankk1 +HankoAJ +Hankzilla +Hannah +Hannh +Hannibal GIM +Hanno +Hannu +Hannu Poika +Hannu Soolo +Hannys Main +Hanoi +Hanoi Rocks +Hanoob btw +Hans Glans +Hansen +Hansern +Hansiil +Hansonville +Hansy +Hantarded +Hanwi +Hanzino +HaochengZ +Haole +Haphazzardz +Hapoton +Happ1RS +Happier +Happiikhat +Happy +Happy Beluga +Happy Dappy +Happy Feet +Happy Josh +Happy Kitty +Happy Light +Happy Meal +Happy Prayer +Happy Tj +Happy exSlut +Happy2DaCore +Happy420 +HappyMeds +HappyPandaXD +HappyScape +Happydud01 +Happyfrog12 +Happyguy +Happypurpday +Happytoy +HapuApu +Hapukurk +HarKieren +HarO Reborn +Hara YEP +HaraHachiBu +Haraket +Harambe +Harambro +Harash +Harassment +Harbix +Harbor 2567 +Hard +Hard Chance +Hard Clue +Hard Filmur1 +Hard Kinta +Hard TeK +HardFormed +HardHatJeffy +HardMannetje +HardRAZ3R +HardRazer +Hardc0reBruh +Hardcome +Hardcrux +Harde Pik +HardeSnikkel +HardenedRS +Harder +Hardeschijf +Hardie +Harding +Hardlesas +Hardman +Hardon hank +Hardstyle IM +Hardwaring +Hardwell420 +Hare Danger +Harem +Harem Isekai +Harja +Hark +Harka +Harken +Harken21 +Harlekin +Harlem +Harley Nz +Harleyrox +Harlie +Harlot +Harm +Harmala +Harmentje +Harming +HarmlessTwig +Harmon Angel +Harmoniiumm +Harmonized +Harmony +Harmonyy +Harmr +Harms +Harms Whey +HarpoonMyAss +Harraggen +Harresvela +Harri +Harri Hylje +Harriganrace +Harris0n +Harrithon +Harrods Fish +Harrris +Harry +Harry Bucket +Harry Dirty +Harry Hendo +HarryPoppa +HarryTheGOD +HarryTheWhte +Harryalt +Harryguy23 +Harryindacut +Harses +Harsh Times +Harshhashh +HartIess +Hartlepool +Hartree +Hartreni +Haruka +Haruka Meh +Harus Ranger +Harutikk +Haruto +Haruuki +Harvahammas +Harvardista +Harveytec +HaryLongWood +Has2BeSHiFtY +Has547 +HasOneLegacy +Hasballa +Hasbullah +Hasek +Hash +Hash Browns +Hash House +Hash One M8 +Hash katchum +Hash1 +Hash1Aussie +HashHund +HashIsLife +HashTagYou +Hashh +Hashiiirama +Hashimm +Hashlife +HashtagGOALS +Hashtagz +Hasloa +Hass +Hassall +Hassis +Hassoni +Hastings +Hasty Power +Hat i +Hat tis +HatchetOG +Hatchkat17 +Hatchling +Hathrow +HatiFnattt +HatoradeJack +Hats +Hatsune +Hatsune Miko +Hatsy +Hatte +Hattibagen +Hattnn +Hattuviilari +Haubjerg +Hauki0nFive +Hauki0nIron +Hauki0nNoob +Hauki0nUlti +Haunleff +Hauntedfury +Haunter12123 +Hauntya +HausHausHaus +HautaNorsu +Hautboi +HavU +Havac +Havard +Havawk +Have +Have Sabr +HaveAGood1 +Havendare +Havenmeester +Havi k +Havidex +Havoc Grasp +HavocRavage +HavocThomas +Havok +Havottaja +Havzzter +Haw +Haw4iiankush +Hawaii +Hawaii Ice +HawaiiMadez +Hawaiian +Hawasser +Hawes +Hawk +Hawk Driver +Hawkear +Hawkes +Hawkeye87 +Hawkit +HawkofLight +HawksMama +Hawkwound +Hawkzrael +Hawler12 +Hawolt +HaxY +Haxd +Haxident +Haxixero +Haxn +Haxnoiz +Haxoonie +HayHay +Hayabusa +Hayaku +Hayasaca +Hayasaka +Hayboo +Hayden3 +Haydenl451 +Haydenss +Haydern +Haydor +Hayesy +Hayfield +Hayirlisi +HayleyQuinn +Haylz +Haynex +Haz-zy +Haz2 +HazDownz +Hazade +Hazardless +Hazardouss +Hazards +Haze +HazeCloud99 +HazeMePls +HazePGN +Hazed +Hazeley +Hazezor +Hazla +Hazsle +Haztraz +Hazy Sparrow +HazyHerb +HazyHour +HazzFive +Hc OffWhite +Hc Oh Wait +Hc Toleranss +HcFlex004 v4 +HcGon +HcHoopla +HcimTironade +Hcimdiot +Hckie +He Adventure +He Pinky +He Who Iron +He nry +He11zdone +HeSmokesBud +Head +HeadBear +HeadHuunter +HeadOverseer +Headache +Headenforcer +Headgaskets +Headleya +Headliners +Headlines +Headlines v2 +Headshotting +Headwipe +Healers +Healty +Heard +Heard Chef +Hearne +Heart Please +Hearted +Hearten +Heartlesdude +Heartlock +Heartquake +Hearts +Heartsful +Heartskate +Heartttt +Hearty +Heat +HeatSeekr187 +Heated +Heathen +Heathenry +Heather x3 +Heatmyser +HeatproofIM +Heav7n +HeavenIyGard +Heavener +HeavenlyBlue +Heavens +Heavens Feel +HeavensDao +HeavensStorm +Heavensdown +Heavy +HeavyBowGun +Heb0 +Hecec +Heck +HeckIron +HeckinWoofer +HeckingFish +HecklerNKoch +Heckstrm +Hecote +Hectic Mic +HecticGinger +HecticHerb +HecticKebab +Hectoplasma +Hedge +Hedralx +Heebie +Heedbo +Heee +Heel +Heeling +Hefboom +HeftyFlan +HegXDXD +Hege +Hegelund +Hegert +Hegesy +HehtoLerssi +Hei Kneuter +Heifetz +Heightenings +HeikkiPentti +Heil +Heil Pierce +Heil Vegeta +Heilios +Heill Ragnar +Heinamies +Heineken +Heinekentje +Heinered +Heinzzel +Heir +HeirHead +Heisbergh +HeisenBergW +Heisenber9 +Heist Music +Hej hej +HejBrink +Hekaton +Hekdik +Hekla +Heko +HektikBadger +Helbur +Heldip +HelemaalMooi +Helesta +Helium +Hell ETC +Hell Kitt3n +Hell ffa +HellAngel +HellBlood +Hella +Hella Tonk +Hellabad +Hellafly +Hellagaybtw +Hellandnz +Helldog946 +Hellhaunted +HellianV +Hellinferno4 +Hellixx64 +Helllblazer +Hellmo +Hello +Hello Bel +Hello Friend +Hello6 +HelloBot9000 +HelloDottie +Hellodummy +Hellrain962 +Hellrazorr +Hells 10hp +Hells Chance +Hells Godz +Hells Puppet +Hells doggy +HellsRavage2 +Hellwater +Hellz +Helm +Helmoid +Help +Help Autism +Help I Gay +Help my +HelpImStupid +HelpLahh +HelpTheNoobs +Helpful +Helpless Ale +Helson Ryse +Helta9 +Helx +Hema roids +Heme2 +HemeSupreme +Hemiptera +Hemmii +Hemmur +HemoGlobe +Hemp +Hemp product +Hempopotamus +Hempwick +Hems +Hen Ac Araf +HenaQ +Henbane0 +Hendo Au +Henee +Henehh +Henfami +Hengecobdig +Hengggga +HenkDeTanker +HenkdePlank +Henkka Btw +Henkka242 +Henkkawaa +Henkkiiieee +Henkleebruce +Henko420GB +Henktius +Henlo +Henners +Hennesssssy +Henni +Henniejj +Hennssey +Henri380 +Henry Fe +Henry XV +Henry14 +Hens +Hensel +Henslord +Hensta +Hentai Daddy +HentaiMaiden +HentaiMusic +Henu OG +Henzone58 +Heolis +HephaestusRS +Her Gay +HerAddiction +Herb +Herb Deen +Herb Lab +Herb Quest +Herb box +Herbacist +Herbaderb +HerbalKing +HerbalTeabag +Herbalicious +Herbby +Herbilicious +Herblore +Herbmania +Herbmatic +Herbogus +HerbsnSpicer +HerculesLoyd +Herculooo +HereFor_Beer +HereSomeDank +HeresALlama +HeresySlayer +Herk +Herkko +Herkko32 +Herkku +Herkules +Herky +Herm10ne +Hermanni +Hermaus M +Herminator0 +Hermit +Hermit Jack +Hermitian +Hermot palaa +Hero +Hero Extreme +Hero Kid +Hero vs Hero +HeroDan +HeroGenos +HeroToby +Heroed +Heroic +Heroic Hope +HeroicDesire +Heroicjesus +Heron Bird +Herp +Herpa +HerpaGnome +HerpesNo +Herpesbek +Herpito +Herr Gaucho +Herr Luc +Herra +Herra Beavis +HerraBonsai +Herrits +Herrmann3 +Hesienberg +Hesitation +Hesmander +Hespori +Hespori KC +HesporisSeed +Hespus +Hess +Hesson +Het Heden +Hetdorp +Hetebeir +Hetehaan +Hetimos +Hets Capture +Hetumo +Hetzer +Heuha +Heur +Heuro +Heuvel +Heuvel Reus +Hevenlys +Hever +Hevi +Hevi Luumu +Heving +Hewy +Hex Is Maxed +HexMage +Hexadecimal +Hexagon Heat +Hexalogy +Hexedited +Hexenblut666 +Hexenkonig +Hexication +Hexos +Hexphase +Hextale +Hextra0rdnry +Hexun +Hexxjan +Hey B +Hey Bob +Hey Cheems +Hey Im Dylan +Hey J +Hey Jase +Hey Jay +Hey Mills +Hey Ubba +HeyBeautiful +HeyBigDaddy +HeyDaddy +HeyFonte +HeyHowsLife +HeyItsLachy +HeyLuffy +HeyThatsLife +Hey_Duck +Heymakerz +Heyman +Heywaddup +HeyyDivine +Hezbullah +Hezr +HgH2 +Hhmm45 +Hhmora +Hi Cookie +Hi Im Ant +Hi Im Duncan +Hi Im Emil +Hi Im Frak +Hi Im Ken +Hi Im Pei +Hi Im Stevo +Hi Im Vitao +Hi ImMrRight +Hi Lvl Ideas +Hi Opal +Hi Ren +Hi Suka xD +Hi Tyler +Hi im Gin +Hi im Savage +Hi im Shar +Hi im Yellow +Hi lm Paul +Hi lm Sk8 +HiDyvvnBDP +HiGHFLYER +HiHowAreYa +HiImIronRick +HiImNicole +HiLumbridge +HiNebb +Hiarii +Hibbetts +Hiben75 +Hibernal +Hick +Hickery +Hicu +Hidaki +Hidden +Hidden Power +Hidden one1 +Hiddenn +Hiddinkiwi +Hiddy +Hide Ink 207 +Hide Ya Kids +Hidekia +Hideo +Hideopenend +Hider +HidesHerEyes +Hidi +Hidole555 +Hidro +Hieroglyfic +Hifter13 +Higgens +High +High Content +High Halpert +High Hustler +High Knight +High On Cake +High Ronnie +High Score +High Snorse +High Up Here +High as Zuk +High lm hi +HighAsF Bruh +HighBacon +HighMeatloaf +HighNoobJhin +HighOnPlants +HighProbably +Highbury +Highcaalibex +Higher Force +Highestarchy +Highfish +Highjacurmum +Highland +Highly Faded +Highmountain +HighonCash +Highs +Highscaping +Hightierian +Highway2Hell +Higlen +Higu +HihoMenono +HiiddeN +HiipFiire +Hiisgreat +Hiit Man +Hiiz +Hijack778 +Hijsbergh +Hiker +Hikiukko +Hikizato +Hikmet +Hilarious +Hilda Garde +Hildr +Hilge +Hilipilli +Hilk +Hillhouse +Hillpker +Hillram +HilltopHick +Hillzy +Hilo +Himala +Himaster +Himtheguy +Himy +Hina Suguta +Hincarpie +Hinchers +Hindi +Hindle +Hinny +Hinss +Hintai +Hiopeer +Hip Fe Hop +HipSlippers +Hiphop +Hiphopdude0 +Hipiguy48 +Hipnodiskd4 +Hippeis +HippieLexy +Hippies +HippoBlunts +Hiqhlife +Hirae2 +Hiria1 +Hiroble +Hiroticus +Hiroyuki Isa +His Faithful +HisHungness +HisLordship +Hisano +Hisblore +Hislordship +HisokaX4 +Hispeeed +Hissi-Timo +Hit U +Hit By Car +Hit Points +Hit The Guam +HitMyVape +HitOnRun +HitOrange +HitTheVape +Hitagi +Hitch350 +Hitchens +HitherDither +Hitman Style +Hitme8 +Hitmonchans +Hits +Hits Like +Hitsumaru +Hittimestari +Hitz +Hiva +Hiya +Hiyouri +HjaIIe +Hjaldr +HlKEN +HlMBO +Hladomor +Hlata +Hldz +Hlep +Hlnub +Hm +Hmg Hawj Str +Hmm Fr Bruh +HmmKoekjes +Hmmer +Hmmingbird +Hmmk +Hmmm +HntrBTW +Ho Chi Meme +Ho LiFuk +HoButter +HoFkee +HoLeShite +HoarderMan +Hob Ralford +Hobbi +Hobbit +Hobby Jogger +Hobex +Hobgoblinas +Hobgoblins +Hobgrot +Hobie +Hobo +Hobodude67 +Hock Baws +Hockney +Hocky +Hocpuck +Hocus POTUS +HodamOS +Hodeman +Hodge5 +Hodgetwin +Hodort +Hodvik +Hoffmanator +Hoffmanbmx +Hoffsworth +Hofus +Hog +HogPacker70 +Hogboar +Hogboy +Hoggormen +Hognag +Hogo +Hogsen +Hogskoleprov +Hoheti +Hohhenheim +Hohhoijjaaaa +Hoi An +Hoilam +Hoix +Hokage +Hokage Jason +Hokage Sama +HokageRS +Hokiako +Hokie +Hokiee +Hokies +HolaBurrito +Holbox +Hold +Hold My Gun +Hold3nMc +HoldMyShrimp +HoldenBallz +Hole +HoleNewName +Holenes +Holidayz +Holiest +Holiidayyy +Holisti +Hollar +Hollington24 +Hollow +Hollowed One +Hollsyy +HoloTheDrunk +HololiveOS +Holoubek +Holsey3126 +Holt +Holtsen +Holunder +Holy +Holy Cheetos +Holy Druid +Holy Jandals +Holy Moses +Holy Plan +Holy Rock91 +Holy Scrotum +HolyChrist +HolyColt +HolyDugong +HolyElixir +HolyEntity +HolyGhost +HolyHerb +HolyIronmoly +HolyMould +HolySaints +HolySkittles +Holycaw +Holyfuk +Holyhonza +Holykana +Holyshmokez +Holyzuk +Hom3r +Homage48 +Hombelkei +Home +Home Boy +Home Office +Home Page +Home Plug +Home Run26 +Homealot +Homebad +Homefront +Homegrowe +Homelander +Homeless +Homeowner +Homepage +Homer +Homer LT 0_o +Homestead +Homicide +Homie +Homies556 +Homingstats +Homlepung +HommeDeFer +Hompski +Hon +Honaz +Honchcrow +Honda Coupes +HondaXJ20 +Honden +Hondo Ohnaka +Hondsvot +Honest +HonestThomas +Honestben +Honestidade +Honeytrippin +Honeyyyy +HonkMyClussy +Honket +HonkeyKong +Honkitonki1 +Honko +Honkys +Honler +Honor +Honourable +Honq +Honra +Honru +Hoo Lee Fook +Hooba +Hoobloob +HoochFighter +Hood +Hood Rat +HoodBrothers +Hoodaloo +Hooded +HoodedDeath +Hooder +Hoodieninja +Hoodless +Hoodlum_94 +Hoodrat +Hoodstar XD +HoofHarted +Hoogbegaafd +Hook +Hook N Arrow +Hookah +Hookin4GP +Hookr +Hooleys +Hooofer +Hoooka +HooorrraaaH +Hoop Snake +HoopaLoopz +Hoopdie +Hoopre +Hoopti +Hoorus +Hooryu +Hootenanny +Hooyaah +Hoozio +Hop Loser +HopNowNoob +Hope +Hope4TheBest +HopeSmolDicc +Hopeless +Hopelite22 +Hopeu98 +Hopian +Hoppa +Hopper727 +Hoppip +Hoppipolla +Hops World +Hoptilicus +Horatio +Horatioat +Horcrux +Hord +Hordalad +Hordaland +Hordelli +Horey +Horizons +Horizons End +Horme +HornDawgx +Horned +Horns +Horny4Herbs +Horny4Hunlef +Horozu +Horppi +Horrific Rat +Horriser +Horros +Horrow jr +Horse +Horse Tock +Horselord +Horshock +Horsley park +Horstel +Horus Hyla +Horus1701 +HoshizoraRin +Hospitaliano +Hoss +Host Proctix +HostileBoss +HostileCloud +HostileEx +Hostiles +Hot Ass +Hot Box +Hot Boxing +Hot Chesters +Hot Choco +Hot Chook +Hot Dog 1995 +Hot Dog Guy +Hot Girl +Hot Glacier +Hot Gril +Hot Hemp +Hot Shop +Hot Since 82 +Hot Stepdadi +Hot nurse +HotAsianCuti +HotCocoa +HotCuppaT +HotDoggWater +HotManCurry +HotMaxCurry +HotPud +HotSaus123 +HotSnow +Hot_Farmer99 +Hotadelchic +Hotandhorny +Hotbox +Hotchelli +Hotdog +Hotdog Timmy +Hotdog655 +HotdogGravy +Hotdogit101 +Hotdogwhat +Hotel +Hotkeys +Hotline Juan +Hotot +Hotputhy +Hotrod-Matt +Hots +Hotsbo +Hotse +Hotsgonwild +Hotshotz61 +Hotslol +Hotwheeler +Houdinski +Houndstooth +Houowvwvv +Hourlies +HoursAndy +Hous +House +House748 +HouseSniffer +Houseman45 +Housewife +Houston713 +Houstoned +Houstonnnn +Hovis +Hovland +Hovmeizter +How do I win +How to quit +How2Boss +How2username +HowAboutNeup +HowDoDisWork +HowHardd +HowIing +HowIsDis +HowLee +HowSway +Howde +Howland +Howler Head +Howlini +Hows +Howsey +Howson +HoySmallFry +Hoya Markus +Hoyaa +Hoyah +Hoyiron +Hoyryjyra +Hoyyehh +Hp x Hp +Hr Banan4 +Hr CarlSmart +Hr KalZ +Hr Pagulane +HrMystik +Hra Amiraali +HraMajuri +Hraerekkrr +Hrafnagud +Hrag +Hrathix +Hrry +Hrungiir +HshBrwnClwn +Hsilver +Hska +HsrFresh +Htine +HuZ Ryan +Huaraaturpaa +Huard +Hub3r +Hubbbzzzz +Hubbz216 +Hubeeb +Hubie +Hubiera +Hubli +Huby K +Huck +HuckUsAHandy +Huckn +Huddo +Hudsy +Huebs +Huevote +HueycoatI +Huffers +Hug A Mudkip +Hug my cat +Hugakitty +Huge +Huge Coom +Huge Mudkip +HugeCcret +HugeCox +HugeMike +HugeSimp +HugeSquanch +HugeXpWaste +Hugh +Hugh Jannob +Hugh Jas +Hugh Jazzhol +HughAreMyron +HughJastle +Hughes Luck +Hugo +Hugo Baws +Hugo C +Hugodzilla +Hugos +Hugoslavic +Hugotec +HugsTibbers +Hugsi +Hugsqtface +Huhi +Huhm0ng +Huhmble +Huhu +Huidskleur +Huiliuiliu +Huilu +Huinca +Hukka +Hulagu +Huler +Hulk +HulkSmaash +Hullcity25 +Hulll +Hulluke +Hulluurpo +Hulvatonta +Hulyx +Human +Human Knight +Human Reject +HumanMalware +HumanSl0th +HumanToxin +Humanist +Humanityy +Humanoid Rat +Humb +Humb RS +Humbabe +Humberto +Humble +Humble Finn +Humble Husk +Humble Otter +Humble RNG +Humble lp +HumbleCanoe +HumbleCrab +HumbleFarmer +HumblePlayer +Humblee +Humblegods +Humbleherb +Humblenobody +Humbles +Humboy +Humgrump +Humid +Humiliation +Humji +Hummbinger +Hummerspeck +HumperT +Humpletics +Humu +Hunajamurune +Hundjagare +Hundred +Hung Opossum +Hung Pikachu +Hung Zebra +HungLow30 +HungSolo45 +Hungarry208 +HungerRee +Hungry +Hungry as fk +HungrySponge +HuniePop +Hunkadoris +Hunks +Hunlef +Hunnets +Hunni Bunny +Hunpy +Hunt Mike +Huntarr +Huntdragimps +Hunter +Hunter10139 +Hunter4056 +HunterPandav +HunterXosrs +Hunters Main +Hunterz +Huntin Specs +Huntindawg +Huntindawg2 +Hunting +HuntingGirls +HuntingPets +Huntinrox +Huntinthotts +Huntiritox +HuntnCoFTB +Huntsin +Hunyadi +Huolon +Hupipelaaja +Huppis +HuppuKostaja +Hups +Huqin +Hurlae +Hurleee +Hurley +Hurley24 +Hurlock +Hurri +Hurrisun +Hurs 1 +Hurtigmads +HurtsDonut +Huscarl +HuseG00SE +Huseyin31 +Hush Pup +Husker +HuskerFool +Huskieeeee +Huskvarna +Huskyskills +Hussar1683 +Husse1n +Husseinn +Hustensaft +Hustlez +Huswan +Hutchens +HutchoAU +Hutros +Huts +Hutula +HuugeCok +Huugo35 +Huule +Huumepoliisl +Huupee +Huutiset +Huutoripuli +Huviksee +Huxley King +Huxtap +Huxtin +Huzeyfe +HvH +Hvale +Hvale Kongen +Hvorfor +Hwael +HwbrangerUIM +Hwzrs +Hxc Ironfail +Hxcmackin +Hxpeful +Hxrm +Hxrsey +Hy a +Hy3RoGeN +Hy3RoGeN x +HyAcey +HyDrooo +Hybernated +Hybrid +Hybrid Hurtz +Hybrid Mech +HybridSanta +HydG +Hydi +Hydr0nate +Hydr0p0nic +Hydra +Hydra Ikkle +Hydra Spoon +Hydra_Lerna +Hydraletics +Hydras Daddy +Hydration +Hydraxon +Hydrerion +Hydro-Quebec +HydroBlast +HydroC +HydroGasMask +Hydrocarbons +Hydroe +Hydrofiner +HydrosFather +Hyemi +Hyfens +HyggeDansker +Hyi +Hykd +HylianLink +HylianLombax +Hylkon +Hymy +Hyosin +Hyough +HypaDunkTv +HypaZestay +HypeLad +Hyper +Hyper 212 +Hyper Threat +Hyper autist +Hypercam +Hypercoaster +Hyperdeath20 +Hypermole +Hypersomnia +Hypertroll +Hypertrophic +Hyperversity +Hyphen +Hyphen-ated +Hyphenated +HyphyRS +Hypn0se +Hypocriet +Hyprocrisy +Hysteric4l +Hytrogod +Hyttynen +Hyula +Hyun +Hyxbe +Hyze +Hyzers +I M +I Skilz I +I ADK I +I AM DROID +I Am Arun +I Am Calysto +I Am Cicu +I Am Dave +I Am Eugene +I Am Malenia +I Am Mathew +I Am Mizzou +I Am Times +I Am Vexed +I Am Vono +I Am Xyience +I Am Yesac +I B Z +I Barak I +I Be Vibing +I Be Yankin +I BenJammin +I Bryce I +I Buy Bulks +I Buy You +I Call BS +I Cant Veng +I Chance I +I Chaz I +I Chop Life +I DanWise I +I Daniella I +I Decimate +I Descend +I Dizz I +I Dont Gnome +I Dont Know +I Dont Weld +I Drink T +I Drive Jeep +I Duck Hunt +I ELITE I +I ET BBIES +I Emu I +I Enjoy Butt +I Faheem I +I Farm On Rs +I Flick Bean +I Gem I +I Genesis l +I Go Noob +I Gribben I +I Grind it +I H8 GAGEX +I Haros I +I Have Quit +I Heal DHers +I Herb Store +I Hunt Pets +I Hustle Man +I I ODIN I I +I JANGLER I +I Judgee Yu +I Ko U Lol 1 +I L0ve Lolis +I LOTR I +I LV PEACH X +I Lezima I +I Liam I +I Liamz6 I +I Like Cake +I Like JoJo +I Lov3 Pho +I Love DILFS +I Love Kinja +I Love Kylie +I Love Muff +I Love You +I Luci +I Luhhya +I Luv tSwift +I M A P nuss +I M Ket +I M S N Y +I M The Weed +I Maxed OSRS +I May Be +I MoF +I Mograine I +I N D I A N +I Need 1M +I Need Succ +I Need aBeer +I Novato I +I Nz I +I OX +I Owning +I P0 +I P0KY I +I Parry I +I Peter I +I Pk In Monk +I Plank Lots +I Play Aegis +I Pod335 +I Pri +I Q T +I R N B R U +I R O N 99 +I RC +I ReAPeR I +I Roll Need +I Ron Man +I Ruin Holes +I Run East 2 +I Sharted +I Smiteyou I +I Smoke Irit +I Specs I +I Spied +I Strangles +I Taka Hujit +I Teller I +I Tricky I +I Tuscan I +I Valknir +I Vape Lube +I Viral +I Want 60FPS +I Would Rage +I Xl I I Xl +I Yogurt +I Yoshitsune +I am Anyone +I am Bryce +I am DB o +I am Elk +I am Future +I am Glynny +I am J M E +I am Jedi +I am Niels +I am Nyheim +I am Olive +I am Ry +I am SHODAN +I am Saitama +I am Shiny +I am Shogun +I am Simon +I am Soloing +I am Twiggy +I am a wreck +I am aRusher +I am drunk +I am groot B +I ate +I bad Guy +I desire God +I do be Iron +I eat peach +I h8 farming +I have egg73 +I have poon +I have rng +I ll fail +I love me +I love yew +I m Dave +I m Kenpachi +I m an Angel +I matchjad I +I mpling +I n b 4 +I ndy +I nspire +I rvin +I sak +I smell zaza +I so pale +I squared R +I t I s +I tbag cows +I used to Rc +I van +I vinrox +I w4ste xp +I wana dew u +I want wings +I-IEEBO +I-Iulk +I00OOOOOO00I +I2P +I2m +I2ocky +I2ossiiii +I3ET +I3WANA +I3ooth +I3ow Hunter +I3ox +I3rucex +I3ubbles +I3ulow +I7I +I7iablo +IA +IAM HARDWELL +IAMBillNye +IAMDouble_C +IAlwaysBurn +IAmArcade +IAmArchangel +IAmBabyYoda +IAmBinx +IAmEcliptic +IAmFaptastic +IAmFrampt +IAmJacbo +IAmRichard +IAmSlimShady +IAmStyle +IAmUnbound +IAmWaffles +IAreTazz +IB4I +IBB Baskani +IBIoodRose +IBaIance +IBangBBWs +IBardak +IBloodwing +IBuyGF5GP +IBuyPowers +IBuyShungite +IC 3 +IC XC NI KA +ICE GIANTT +ICNK +ICantFit +ICauseRage +ICrazyCamelI +ID theft +IDEPOCIEBIE +IDSilver +IDark +IDiabloI +IDustie +IEATEDYU +IFALL3NI +IFIFIFFIFIF +IFIFIFIFFIFI +IFIFIFlFIFIF +IFRC +IFRS +IFRS 9 +IFartOnBaby +IFernedYou +IFistBonk +IFoundABaby +IG0R II +IGN0RANCE +IGoogledIt +IHQueenI +IHasHips +IHaveAWifey +IHaveChicken +IHaveToQuit +IHobbitI +IHopFromNo1 +IHuntKoalas +II Fabi II +II Gots Piie +II Mossy II +II TurMz +II0III +II0v0II +IICyRaNoKII +III SLAYR +III jin III +IIIBCIII +IIIGavinIII +IIIel0n +IIIusionist +IIKOO +IIPAC +IIPrincesaII +II_Blanx_II +IIamaman +IIflemishII +IIlIIAS +IIlIIoIIlII +IIllIll +IIlllllIIlIl +IIndy +IIrisviel +IIsaac +IIx Link xII +IJzer Bal +IJzermeneer +IK Pegasi +IKotol +ILL M1ND +ILLUMINATIS +ILOVEUBRAT +ILVI +ILike +ILikeKorone +ILizzy +ILostMySock +ILostMyTalk +ILoveAstolfo +ILoveSeaFood +ILoveYasmin +IM Adept +IM BLUE DA +IM Bazlish +IM Big N8 +IM Bjakke +IM Bolle Ui +IM Butchh +IM CSI +IM Cares +IM Chaudoin +IM Corita +IM Dahak +IM Damy +IM Dislectyc +IM Dodgypig +IM Donactro +IM Drone +IM Dutch Dog +IM EL Clawo +IM Envy +IM Erlandu +IM GERRALD95 +IM Gekko +IM Gokhan +IM Guilty +IM HEEM +IM Hail +IM Harnas +IM Hulkeen +IM Infested +IM Jap1 +IM Jenskee +IM Kat +IM Knol +IM Krona +IM M U R P H +IM M0A +IM Maccy +IM MajorRat +IM Maninja +IM Musa +IM Noddy +IM Ong Gia +IM PVM BRADY +IM PapaBless +IM Peach Man +IM Pepekage +IM Perp +IM Phubz +IM RICO_1 +IM Rampage +IM Reiner +IM Rome +IM Ruinscape +IM ST0NED +IM Sebaa +IM Soad +IM Spooned +IM Super AFK +IM Tank OG +IM ThiccSucc +IM Tipz +IM Toon +IM Walnut +IM Witt +IM Zoot +IM a pansy +IM blazeit +IM sanderve +IM spen +IMAEATURASSS +IMAFKNNONCE2 +IMGOKU1 +IMHankey +IMHky +IMJeffG +IMMezzo +IMNagrom +IMPERlO +IMPlayerjohn +IMSOULSHADOW +IMSausjegeit +IMSkrt +IMWaldorf +IM_Queeffing +IMa Planker +IMakeUBegKid +IMevil yoshi +IMissNieve +IMnotQ +IMoIVoxide +IMsmits +IN A FERRARI +IN PRISON RN +INCEL839273 +INCreate +INDICA +INFERNALMAX +INTERMEDlATE +INYOURTS +INeedABump +IOHBOY +IOnSpacezI +IP6 +IPkdYourBank +IPlayForPeso +IPlayHigh +IPonderosa +IProGuthix +IPumpkin +IPunchKids +IQUICA +IR Hardcore +IR0N +IR0N BOND +IR0NMAN +IR4Q +IRL Femboy +IRON +IRON BYRNS +IRON DlOXlDE +IRON NOT HOT +IRONMAN ADO +IReallyLikeU +IRework +IRidePipe +IRoldy +IRowForUCD +ISAPOOPS +ISO PEE +ISOMAN12 +ISQQC +ISTRA +IScottGame +ISjorsI +ISmokeABit +ISoLaTIIon +ISquirk +ISuperStarI +ITIB +ITIISERY +ITIOMME +ITIace +ITIaddy +ITIagicka +ITIagicks +ITIajestic +ITIallen +ITIasKilleR +ITIassacre +ITIatty +ITIerica +ITIiko +ITIoj +ITIoosh +ITIr +ITSPYRO +ITV X +IThe Beatles +ITrimGlories +ITurtlekunI +IUR +IUntradeable +IV Luke +IV skin +IVI V G +IVICMXCIII +IVIE0W +IVIacaroni +IVIaybe +IVIeesa +IVIeredith +IVIesprit +IVIetallica +IVIidget +IVIooN +IVIowlzy +IVIugginz +IVIush +IVIxtthew +IVOXYGEN +IW Lytheria +IW4M +IWGP +I_Eat_Ass04 +I_Inity +I_Noodz_I +I_make_noise +Iacto +Iaculch +Iaffan +Iafs +IaintHiding +Iam Bald +IamAjewBoy +IamBowser +IamBruun +IamCheesin +IamCrazyBoy +IamDuru +IamErect +IamGossip +IamNSFW +IamNotHodor +IamRichPutin +IamSneak +IamThaLiquor +IamXerxes +Iambadhaha +Iamcruxer +Iamearth +Iaminsanemax +Iammooted +Iammtpjr +Iamstepbro +Iamthestars +IamthyPope +Ian Beale +Ian Rush +IanT +Ianalan +Ianbird +Ianeke +Ianeke4 +Ianyaboii +Ianz +Iax 2000 +Ibanezx88 +Ibanezx99 +Ibans Fe nix +IbansPheonix +Ibarbo +Ibb +Iberis +Ibexleave +Iblushh +Ibn +Ibrahimovic +Ibugppl Jr +Ibunaaru +Ibuprofen800 +IcEyCuDa +Icanfixthat +Icarius Fell +IcarusRS +Icaruz +Icculus1 +Ice 9112 +Ice Barrage +Ice Caves +Ice Gengar +Ice King +Ice clap +Ice giants +Ice in Vodka +Ice5566 +IceBarraging +IceCreamDog +IceDesert +IceFoxZero +IceH +IceIceChooky +IceNineKiIIs +IcePrisonMe +IceSparro +Iceb +Icebeam +Iceburghomie +Iced 0ut +IcedOutDrip +IcedScrabble +Icedeadmage +Icee +Icefirezz +Icehound +Iceid +Icejawa +Iceland +Iceleag +Iceliang530 +Icelight +Icemonkeyz +Icen +Icesoze +Icespeller +Icetaylor +Icey +Icey Lunaris +Icey M +Iceyou90 +Ichi +Ichi6an +IchikaNagano +Iciclez +Ico n +IconPara +Iconiic +Iconoclasmic +Icookpeople +Icoz +IctCat +Icy Duck +Icy Tires +IcyFear +IcyTowerr +Icyene +Icyene Hero +Icyenicblood +Icyflowers +Icyx +Id Tele Too +Id Yak It +Idaho +IdahoTaters +IdcGoAway +Idea +Ideaal +Ideekay +Idepredad0rI +Ididit33 +Idk Why PvM +Idle GE +Idle Melvor +IdleWhale +Idlibi +Idna Supafly +Idol Namib +Idont +Idontlikejad +Idopk1 +Iecysoda +Ienjoisk8ing +Iern +If I Succeed +Iffi +Iffyz +Igge +Iggy Ontario +Igloocold +Igmere +Ignace +Ignent +IgnisDraco22 +IgnobleSolid +Igor Krutoy +Igor Mang +IgorBogdanof +Igorr +Igot99failin +Igris +Iguaani +Ih8myRNG +Ihan +Ihana +Ihme +Ihnigmakage +IiIy +IidaEmilia +Iilqtforeva +Iimel +IisRaDiO +Iisalmi +Iivomon +Ijoinedthis +Ijusheadshot +Ijzer tekort +Ik Geef Bon +IkBenWeg +Ikastovizski +IkeJEI +Ikhela +Ikillu247 +IkkeVincent +Ikkle +Ikkle Hydra +Ikkle v Pain +IkkleHorvick +Il +Il MrBorn lI +IlIBooieIlI +IlIIIIlIIIlI +IlIIlIllIlII +IlINard0IlI +IlRisklIlIlI +Ileeze +Ilija +Ill Ko You +Ill Effect +Illbeyourcat +Illegal Char +Illest Logic +IllestEver +Illinoisan +Illithid69 +Illlenium +Illumee +Illuminatorr +IlluminumRS +Illusionist +Illusivezz +Illustration +Illuzory +Illwil +Illyrian +Illyrian TSX +Ilmer +Ilotalo +Ilovethewar +IlpOG +Ilsaldur +Iltasanomat +Iluredyou +Ilusm +Iluvahrim +Iluvitar Eru +IlyrianBlood +Im 85 Slayr +Im A Saint +Im Am Die +Im Ami +Im Anabolic +Im Annoyed +Im Artur +Im Ash +Im Asking +Im Aspergers +Im BackUp +Im Baguette +Im Barlow +Im Behemoth +Im Benough +Im Blastoise +Im Bo Licht +Im Brills +Im Burnz +Im CG +Im Chal +Im Christian +Im Courage +Im Dino +Im Dr Afk +Im Easy Exp +Im Elyk +Im Excalibur +Im Fabulous +Im Fever +Im Finnish +Im From Jax +Im Gainz +Im Gippin +Im Gutfor +Im Hawkward +Im Hersh +Im Huck +Im Hunta +Im Hussain +Im Iron +Im Iron WTF +Im Jags +Im Jokers +Im Jovian +Im Just Ken +Im Krazy +Im Kyle Btw +Im Legacy XD +Im Los t +Im Luis +Im McGriddle +Im Missle +Im Moist 4 U +Im Moore +Im Mr Josh +Im Nate +Im Nathan x +Im Newschool +Im Nice +Im Not Okayy +Im Not lron +Im Nzmitch +Im Off Chops +Im On A Yak +Im On Point +Im Only +Im Orc +Im Outt +Im Pogi +Im Qwerty +Im Ron BTW +Im Rus +Im Savage +Im Scoob +Im Secor +Im Shambles +Im Single AF +Im Smexy +Im Snake A +Im So Vayne +Im Songs +Im Spirit +Im Stig +Im Symb +Im Tainted +Im Tame +Im Temppay +Im Terrible5 +Im TheBeast +Im Tibbz +Im Travis +Im Triz +Im Tyl3rr +Im Whey +Im Ya Papa +Im Your Babe +Im Your Dad +Im Yui +Im Zac +Im Ze 0wner +Im alex btw +Im just Cody +Im not FBI +Im relapsing +Im tall af +Im wokeup +Im-Crowess +Im2good4u2nv +Im45defence +Im4everlucky +ImALilPigBoy +ImASthhnake +ImAdam +ImAl0ne +ImAn Ironman +ImBaldFromRS +ImBobbyrayj +ImBoredOfRS +ImCharky +ImChuckBass +ImClueless +ImCravenTim +ImDaPlugLLC +ImDaved +ImDaviie +ImDirtyyyDan +ImDoctaWhom +ImEmilyy +ImEric +ImFinnish +ImFlizz +ImGodd +ImGodly +ImHavingFun +ImHellaHigh +ImHighASFSry +ImHisBae +ImIncredible +ImInfested +ImIntense +ImJames +ImJebbe +ImJinxed +ImJordon +ImJustLonely +ImJustRaging +ImKnotSimple +ImLarge +ImLeeuwarden +ImLikeRlyBad +ImLukesGIM +ImMAdBro +ImMajesticAf +ImMaxy +ImMilky +ImNewbie +ImNoobK +ImNooblit +ImNotAfriend +ImNotHumble +ImNotLost +ImNotThien +ImPaul +ImPaulAlt +ImQuorra +ImRyboy +ImSane +ImShreksDad +ImSixteen +ImSnoop +ImSoGodlyy +ImSoVulgar +ImStormmm +ImTaegan +ImTayla +ImTinyRiick +ImTipsy +ImToFrosty +ImTooGucci +ImTwisted +ImVanilla +ImWargasm +ImWilbur +ImYourDadBTW +ImZe +ImZorp +Im_Stone126 +Ima Guy +Ima Lil High +Ima Maleman +Ima lron man +ImaCraftHor +ImaMainbtw +Imack +Imafore +Images +Imaginable +Imagine +Imakuni0 +Imalooter +Iman103 +Imangry20 +Imanity +Imanubnoob +Imar Pussay +Imasecretspy +Imasin +Imawizardm8 +Imazamox +Imblim +Imblim Area +Imbrochavel +Imbue +Imbued Haert +Imbuing +Imbune +ImeshuggahI +Imgrazy +Imhellgracio +Imidril +ImiteBurDADY +Imitus +Imm Mad Bro +Imma +ImmaSkill +Immaturity +Immediate W +Immense +Immer +Immerseus +Immiscible +Immortal +Immortal91 +ImmortalK12 +ImmortanMike +Immxnse +Immys +Imnotahuman +ImoChase +Imoinu +Imotay +ImpactPewPew +Impale Her +Impared +Impeccable +Impedance +Impede +Imperdoavel +Imperfecto +Imperfekt +ImperialQc +Impietyy +Impish +Impish Ace +Impishhh +Imposter Jon +Impriznd +Improv +Improved +Impulsive Au +Impurest678 +Imql +Imre +Imsain +Imsokwtie +Imstratss +ImtheAnimal +ImtheCARRYv2 +Imthick +Imtoob +Imuhbeast +Imuripieru +Imus +ImxricK +In Game Life +In Menu Andy +In My Shadow +In Recovery +In Seconds +In2cept +InCyson +InDaCouch666 +InDespair +InFemous +InGameLies +InTawlerable +InThe90s +InTolu +InTransition +InXanee +InYaShower +Inaaya +Inactive Acc +Inar +Inavi Jones +Inbow +Inbred +Incapacitory +Incendia Vir +Inch95 +Incin3rat3 X +Inco-san +Incoherent +Incomes +IncomingBeef +IncomingGank +IncredblDino +Incumbency +Indain +IndawrCrwdad +Indcsn +Indecisive +IndecisiveO +Indemise +IndexNull +Indian +Indian Chad +IndianCat +IndianaJones +Indicates +Indicator +IndieGarri +Indigo640 +Indivi2you +Indoktrinera +IndominusAsh +Indoor Scape +IndoorsOnly +Indoorsman +Indrado +Indrias1 +Indy Ju +Inecstatic +Inedibles +IneedPVM +Ineff icient +Inefishient +IneptEwok +InfIuenced +Infaam +InfallibleX2 +InfamousAB +InfamousEvil +InfamousMain +Infantiel +Infase +Infectus +InferiorRNG +InfernOwl +Infernadev +Infernal +InfernalChef +InfernalLuke +InfernalPRO +Infernax +Inferneo +Inferno +InfernoTism +Infernowerno +Infero +Infesmati +Infin1te +Infinate +Infininth +InfinitiGX +InfinityMan +Infirme +Inflnite +Influx +Info +Info Kiosk +Infobese +Infor +Infora Treat +Ingeb +Ingenious G +Ingeniously +Inglane +Ingleburn +Inhaled +Inhinyero +InhumanBTW +Inimene1020 +Inimputable +InitialTT +Iniys +Inkedsaint +Inko +Inksane95 +Inkwes +Inner +Inner Brian +Inner Peace +InnerBliss +Innvision +Inori xdd +Inosuke xo +Inqku +Inri +Insafi +Insane +Insane Iron +InsaneBobbie +InsaneFruit +InsaneIee +InsanePerson +Insaneglutes +Insanewolfy +Insaniack +InsanityNix +Insanityx +Insanityzz +Insatiate +Inse +Insectkoala +InsertGold +Insluiper +Insomnia +Insomnist +Insomnity +Inspection +Insta +Insta Spec +Instabox +Instagrem +Instail +Instinct +Instro +Instruct +Insucc +Insulter +Insulting +Insulting MF +Insurgence +Insurgent +Int0mieli +Integration +Intel6 +IntelManiac +Intellectual +Intendi +IntenseRage +Intensifyyy +Intentional +Intercept0r +Interchange +Intermk +Internal +Internal Max +Interracial +Interronator +Intherial +Intier +Intimate +Intimidant +Into +IntoInfinite +Intoner +Intresant +Intresenting +Ints +Intubator +Intuition +Inubashiri +Inukal +Inuouk +Inur +InvTagsBad +Inva +Invalar +Invercargill +Inversives +Invert +InvertedDuck +Inveterate +Invierno +Invisa +Invisa Scav +Invisa-Veng +Invisioners +Invokers +Involk +Invoryy +Inwu +Inxo +Io Jah Pul +IoB Sylarke +Iock +Ion Benny +Ion870 +IonCannon +Ionia +Iono +Iou689 +Iowa146 +IowaCJ +Ioyal +Ioyins +IpeeInTheSea +Ipod5412 +IpotYouDrop +Ippe +Ipswich +Ipswich FC +Ir JWWillem +Ir Phys +Ir0n +Ir0n Bot +Ir0n b00k +Ir0nMammoth +Ir0nMish +Ir0nPuma +Ir0nRagnarok +IrDA +Iralimir +Irha +Irid +Irie +IrieLuDa +Irinichina +Iris Elea +Iris_1904 +Irish +Irithe +Irl Baller +Irmak +Irobar +Iroff SGDaht +Iroflman +Iroh Bison +Iroha +Iroic +Irom Typo +Iron +Iron 0lm +Iron 2DWaifu +Iron 2b +Iron 3 Hit +Iron ABC +Iron Achael +Iron Aeolian +Iron Alabama +Iron Alee +Iron Aloha +Iron Aloodum +Iron Alpha +Iron Anaerob +Iron Anno +Iron Anonymo +Iron Antzz +Iron Areolas +Iron Arnoud +Iron Arzka +Iron Assface +Iron Ayen +Iron Azshara +Iron B O D Y +Iron B0yx +Iron BDN +Iron BLK +Iron Bart +Iron Baskan +Iron Bawlsak +Iron Bawsss +Iron Beabs +Iron Beeto +Iron Besu +Iron Bezem +Iron Bibi2u +Iron Biddys +Iron Bloke +Iron Bogmac +Iron Book +Iron Boomz +Iron Booxia +Iron Borrrby +Iron Brevik +Iron Brinnie +Iron BryconC +Iron Buchu +Iron Buckc +Iron Bucket +Iron Bumko +Iron Burrata +Iron Buuh +Iron Byld +Iron Caddy +Iron Calquat +Iron Carly +Iron Carmine +Iron Carna +Iron Cerv +Iron Cevol +Iron Chaw +Iron Chemic +Iron Chkn +Iron Cholby +Iron Chombre +Iron Chrisss +Iron Coby +Iron Coin +Iron Coronao +Iron D Luffy +Iron D Natsu +Iron D Zeref +Iron DJG +Iron DSC +Iron DVS +Iron Daniel +Iron Deku +Iron Denal +Iron Deroq +Iron Destr0i +Iron Dipshit +Iron Dixi +Iron Domi +Iron Dumontx +Iron Dylnn +Iron E +Iron E s s +Iron E z +Iron Eagah +Iron Elyon +Iron Equity +Iron Excal +Iron Exed +Iron FFrenzy +Iron Fe +Iron Ferro +Iron Filthy +Iron Fioxxu +Iron Fire 75 +Iron Floor +Iron Forgy +Iron Franchi +Iron Frodo +Iron Fuhrers +Iron G Zeus +Iron G0liath +Iron Gaan +Iron Gamerz +Iron Gayness +Iron Ghosgar +Iron Ginto +Iron Gios +Iron Go +Iron Godley +Iron Godly +Iron Golem +Iron Goth GF +Iron Greg +Iron Grind20 +Iron Griss +Iron Haze +Iron Hoiy +Iron Holub +Iron Hookkan +Iron Hossi +Iron Hroth +Iron Hugge +Iron Husky +Iron Hydros +Iron Hyger +Iron IPvMI +Iron Insaneo +Iron Jakob +Iron Jal-Nib +Iron Jeref +Iron Jeroen +Iron JimmyJ +Iron Jizzman +Iron Jss +Iron K3 +Iron Kalde +Iron Kaleef +Iron Kapkeik +Iron Karjala +Iron Katniss +Iron Kayn +Iron Keagan +Iron Kess +Iron Kiwii +Iron Kngs +Iron Knipp +Iron Kodie +Iron Koopsy +Iron Kornie +Iron Krijn +Iron Krikke +Iron Laplace +Iron Laxor +Iron Layfe +Iron Letski +Iron Liber +Iron Lose +Iron Lungsta +Iron MTUT +Iron Mamma +Iron Mammal +Iron Mapes +Iron Marie26 +Iron Marlon +Iron Martin +Iron Masori +Iron Masuli +Iron Matt +Iron Matt NZ +Iron Matty W +Iron Matuba +Iron Maxvoid +Iron Mellem +Iron Meydon +Iron Miguel +Iron Mikebor +Iron Milan +Iron Mimal +Iron Miro +Iron Moardus +Iron Mossyy +Iron Munted +Iron Mystip +Iron Nap +Iron Nellz +Iron Nick +Iron Nimmi +Iron Nobody +Iron Noe +Iron Nuclide +Iron Nuuby +Iron O Brien +Iron Oak +Iron Oboi +Iron Ohboy +Iron Ohgodno +Iron Ohzone +Iron Opto +Iron Ores +Iron Pandis +Iron Parkour +Iron Patches +Iron Peg +Iron Pge +Iron Phe +Iron Plague +Iron Pothead +Iron Praxis +Iron Pwn +Iron Pwnstar +Iron RNGsus +Iron Rakey +Iron Randall +Iron Randyy +Iron Reedzy +Iron Rekkr +Iron Request +Iron Rikyu +Iron Rind +Iron Roach +Iron Robsham +Iron Roof +Iron Rushy +Iron Rybread +Iron Ryuuga +Iron S t i g +Iron SSJ +Iron Sagga +Iron Samiria +Iron Santus +Iron Scolew +Iron Scran +Iron Seagz +Iron Seha +Iron Shaikh +Iron Shavers +Iron Sheik +Iron Shnapi +Iron Siem +Iron Sioux +Iron Skoptsy +Iron Skroten +Iron Skydive +Iron Slash +Iron Slaya83 +Iron Sloth 2 +Iron Smoke94 +Iron Snypah +Iron Sparco +Iron Splat +Iron Stannrs +Iron SteveB +Iron Stomp +Iron Stronq +Iron Stw +Iron Sullo +Iron Susu +Iron Svampe +Iron Swaffle +Iron Swag +Iron Takumi +Iron Tango +Iron Tanzim +Iron Tbar +Iron Terboo +Iron Teun +Iron Thi3ves +Iron Tiffers +Iron Tigr +Iron Tigran +Iron Tinman +Iron TomT0m +Iron Tonkin +Iron Tonski +Iron Tonymaa +Iron Torfi +Iron Toxxic +Iron Trashua +Iron Trixx +Iron Tudder +Iron Tutnin +Iron Tweeker +Iron Tyrans +Iron Tyrant +Iron UIM +Iron Uakti +Iron Unam +Iron Varuna +Iron Vatti +Iron Venema +Iron Vexzed +Iron VickD +Iron W1nk +Iron Weather +Iron Wespula +Iron Wii +Iron WindJr +Iron Woofy +Iron Wu5 +Iron XIIIV +Iron Xellana +Iron Xire +Iron YEE +Iron Yangus +Iron Z4ppie +Iron Zephyx +Iron Zeraph +Iron Zerg +Iron Zilong +Iron Zinoto +Iron Zoha +Iron Zol +Iron Zrysen +Iron Zul Mox +Iron anrowi +Iron d0gz +Iron da ddy +Iron dols +Iron dry +Iron feens +Iron flynn +Iron instead +Iron kitcat +Iron l2asta +Iron ona Mac +Iron pappal +Iron werty +Iron whiff +Iron wiper +Iron x wolf +Iron xyN +Iron-Ximena +Iron10203 +Iron2Pickaxe +Iron619 +IronAgentP +IronAjandre1 +IronAkleiss +IronAlblad +IronAlufolie +IronAngst +IronAnnaMay +IronApples +IronAsbe +IronAssHole +IronAussieM8 +IronAxe +IronBadAtPvm +IronBankFull +IronBeanz +IronBeerad +IronBiGuyBtw +IronBistchul +IronBobbyjoe +IronBoink +IronBosse +IronBound +IronBrad +IronBrand21 +IronBrick +IronBruBrah +IronBuriedNU +IronBurnsRed +IronC1aws +IronCagedRat +IronCemile +IronChillii +IronChirpOTK +IronChompers +IronChrisKin +IronClarkey +IronCoX +IronComedy +IronCooter +IronCozza +IronCraiger +IronDab 710 +IronDakotas +IronDandaman +IronDavid +IronDeadBoy +IronDefiant +IronDeredas +IronDethaele +IronDodo420 +IronDog777 +IronDong +IronDravekD +IronDringus +IronDtrex +IronDubble +IronDubzy +IronDudde +IronDunceCap +IronDurrrrr +IronEagles +IronEkakerta +IronEso +IronEtch +IronFefe +IronFigment +IronForFunnn +IronForged99 +IronForyn +IronFrenzey +IronFrogMan +IronFungi +IronGalihand +IronGatr44 +IronGear CEO +IronGez +IronGodsword +IronGoliathX +IronGoneNorm +IronGow +IronGuh +IronHammy +IronHasta +IronHomer +IronIDKFA +IronInsano +IronIogibear +IronIsNoJoke +IronJValor +IronJakeT +IronJames +IronJamesG +IronJarod +IronJeffZ +IronJenga +IronJezz +IronJoint +IronJosehiha +IronJosephxo +IronJuji +IronKaboom +IronKaiser +IronKapp +IronKayodee +IronKest +IronKingdoms +IronKukk +IronKyloman +IronLadBtw +IronLadel +IronLaffin +IronLankzey +IronLazure +IronLegend +IronLegocy +IronLepaus +IronLifting +IronLionMAIN +IronLucas +IronLuckPlz +IronMadePure +IronMagick +IronMainOx +IronMan +IronManBow +IronManJar +IronManSux +IronMango +IronMarius +IronMarty +IronMason +IronMathwin +IronMatty +IronMayne +IronMetknot +IronMikado +IronMinion +IronMitchKun +IronMollusk +IronMountain +IronMugz +IronMushy +IronNWord +IronNachos +IronNantt1 +IronNateDogg +IronNazguls +IronNexuss +IronNeya +IronNibletz +IronNihilm +IronNinja13 +IronNord +IronOceanMan +IronOdum +IronOldBoy +IronOnPatch +IronOrca +IronOreAgate +IronOsiriss +IronOxideMan +IronOxidizer +IronPangtar +IronParis +IronPeteMan +IronPills +IronPrice +IronPrickles +IronProf +IronPumitaz +IronQben +IronQli +IronQueen +IronRait +IronRassi +IronReese +IronRobbo +IronRogueMan +IronSabo +IronSantaMan +IronSchmieds +IronShadow5 +IronSikruz +IronSkaro +IronSly +IronSmurfff +IronSparrow +IronSpiderZ +IronSpitfire +IronSplats +IronSpoNeD +IronSpoony +IronSpray +IronSquidly +IronSteve-O +IronStronky +IronSurf +IronSylar +IronSystolic +IronTarnum +IronTasseron +IronTau +IronTedBundi +IronTeste +IronTestedRB +IronTimTim +IronToff +IronTulio +IronTyson +IronUnkilled +IronVegtable +IronVib3s +IronVikinng +IronVikzo +IronVinda +IronViolette +IronW3LEGEND +IronWafflee +IronWallnut +IronWantsRNG +IronWayneker +IronWidovv +IronWush +IronYoerik +IronYugo +IronZettrox +IronZong +Iron_ProDabs +Iron_Slippy +Iron_Sukulo +Ironarcanic +Ironatica +Ironator +Ironblood7 +Ironboba9993 +Ironbobsaget +Ironborn +Ironborn PVM +Ironbutcher +Ironclad Sac +Ironed +IronedSwift +IronendJr +Ironeyy +Ironflox +Ironfur +Irongrazvis +Irongusty +Ironiam Vir +Ironic +Ironic Force +Ironic Kill +Ironic Name +IronicBenson +IronicSwag93 +IronicViking +Ironicer +Ironiical +Ironija +Ironik 20 +IroningB0red +IroningSucks +IronishSana +Ironkaka +Ironmacman +Ironmale +Ironman +Ironman Daff +Ironman Jase +Ironman Jowe +Ironman Wit +Ironman idk +IronmanFookz +IronmanHutch +Ironmanerno +Ironmeme +Ironmeme Cx +Ironmeme Lol +Ironmies +Ironmimmi +Ironmorriz23 +Ironn +Ironn Yoshii +Ironnesses +Ironpasta1 +Ironqa +Ironred33 +Ironriwer +Irons suck +Ironshore +Ironsoul2 +Ironstone +Irontownhero +Ironwind747 +Ironwinter +Ironwork4eva +IronxElite +Irony +Irony Nib +Ironylion +Ironyx +Ironzi +Ironzilla +Irrelevant +Irrumated +Iru +Irulon +Irxn +Irxnized +Is E_wen +Is Idle +Is Slikker +Is a bich +Is this you +IsAlexOk +IsButters +IsChazCool +IsDomIsGood +IsYaBoyDoive +Isaac +Isaki Magari +Isbjorn +Isganytojas +Ishigo1992 +IshmaelDonny +Ishrandom +Ishzn +IsidoroM +Iskemia +Iskolar +Iskon +Iskra +Islaal +Islami +Islefalls +Isleview +IsmackfaceI +Ismelitooo +Ismo54 +IsoG +IsoKitty +IsoP +Isoga +Isoleucine +Isootoonik +Isoptox +Isosami +IsraVM +Israels +IssaEly +IssaStiffler +Issard +Ist M +Istanbulite +Istasher +Istaxit +Isvig +It Slaps +It is Rex +ItBeJacK +ItBurns +ItIsWedsDude +ItPol +ItWasntMe007 +Itaky +Ital +Italian +Italian roxx +ItalianAJ +Itaochi +Itchweedy +Itcoto +Iteyx +Ithero +Ithlinee +Itik +Itinkinou +Its Absol +Its Almog +Its Arj +Its B0B +Its Brother +Its Canadian +Its Conrad +Its Da J00z +Its Dally +Its Dyl +Its Hash +Its Jon btw +Its Jst Skin +Its Kaylee +Its Libo +Its Me Dave +Its Me Q +Its Me Suns +Its Misha +Its Nipo +Its Peter +Its Rigged +Its Sebas +Its Sense +Its Seth +Its Smooth +Its Teddy +Its Wolfie +Its Yama +Its Zammy +Its a Shame +Its claw +Its me Josh +Its me eden +Its rob +ItsAboutTime +ItsAirdog +ItsAllOgreM8 +ItsAnobrain +ItsBarcus +ItsBigNasty +ItsBlitzyy +ItsBrtnyBch +ItsBru +ItsClout +ItsDende +ItsDynasty +ItsFinn +ItsFlooo +ItsHoggle +ItsHosef +ItsInThePast +ItsKenshi +ItsLitttFam +ItsMarc +ItsMeBlaze +ItsMeDog +ItsMev +ItsMrSir2u +ItsNiels +ItsOleGreg +ItsOwenM8 +ItsRainor +ItsSirTech +ItsSkells +ItsSyn1k +ItsTaylen +ItsTerpsWrld +ItsUnruly +ItsWeinstein +ItsWicked +Its_A45c +Its_Fonte +ItsaTommyGun +Itse rauta +Itsemurha +Itsmeborrid +ItsoktoGIM +Itsssjustice +Itsy Bitsy +Itupakointi +Itx +ItxJustin +Itz Haydn1 +Itz Hickton +Itz Kodiak +Itz Nate +Itz Scrubz +ItzAtlass +ItzElise +ItzJroc +ItzKat +ItzLogikal +ItzMrNick +Itzla +Itzvenom +Itzzz B +Iuc +Iuckk +Iulz +Iussy +Iustrous +Iuxio +IvIegaDan +IvIr Wize +Ivain +Ivaink +Ivalice XIV +Ivan Knjklj +IvanEOD +IvanMullet +Ivanckonia +Ivanka +Ivansaccount +IvelJet +Iveljetorox +Ivoos +Ivory Tower +Ivryk +Iwanbro +IxHunt3rxI +IxVenom +Ixala +IxonnoxI +Ixyc +Iz0p +Izaa +Izac +Izanani +Izbec +Izhmash +Izi Claps +Izone_Kev +Izuria +Izvorul +Izzy +IzzyBigBoy +Izzyboy300 +J 0 S H Y +J 0 S H l +J 4 6 +J 4 K E +J 6 +J A B S +J A I D A N +J A M A L +J A N K I +J A U N U S +J A W D +J Breezi +J C Trousers +J D +J D Ballew +J Dahmer +J E E V E 5 +J E T +J F +J Fred Run +J I M M +J I MM Y +J Kole +J Kribzz +J L A +J MF B +J Neat +J O E G +J O L T I K +J O T A +J O3Y +J R O C +J R V +J Rat Cow +J S 2 M +J S Z M +J Saints +J Suave +J U S T A S +J U Z +J a c k a l +J a c k son +J a c k y +J a mie +J a n i +J ackal +J al +J ameper +J anii +J appie +J asnah +J ason +J asyra +J ayson +J bellfortt +J bird shady +J e sse +J eff +J effy +J ensen +J esse +J essica +J imme +J imy +J imz +J ipr +J lMM Y +J o b e +J o e +J o ey +J o f +J o s h y +J oep +J ohannes +J ointz +J oke R +J or G +J oshh +J oshhh +J osie +J u wu +J ung +J unko +J utch +J uun +J uwu +J x B +J yy +J-2tha-R-O-C +J-Man 93 +J-Turn +J-Yeezy +J001_jf1 +J0DYY +J0E +J0E REAL +J0EEY +J0NE +J0UF +J0YBOY LUFFY +J0YRYDE +J0dz +J0hnnyQ +J0ng +J0ngeBV +J0ppy +J0rdanDv +J0rdo117 +J0se +J0se Dtown +J0se Dtuwnn +J0seph +J0shh +J1MB0H +J1NBE +J1ub +J2TR +J2caine45 +J2ck +J328 +J3Ciron +J3JU +J3S5E +J3rkkuHD +J41AL +J45e0wns +J4QS +J4S +J4gga +J4my +J95 +JAABASNABBA +JACK3DJOHNNY +JACKYOUNG93 +JAG0705 +JAI MA KALI +JAMA Open +JAUH0JENGI +JAVON 9-INCH +JAYJ51 +JAYR0CKBABY +JAlDYN +JB 2K +JB87 +JBGard +JBrody +JBuck057 +JBux +JC-1989 +JCS07 +JCole +JCon +JCutler +JD MD +JD4 +JDBass +JDEP +JDFlaSh +JDJM +JDez +JDlion +JDredd66 +JDuck +JE B +JEEZE +JENNY +JENNY DEATH +JERN SVIN TO +JETSNBEERS +JF Kennedy +JFB +JFCK +JFK gone AFK +JFKautopilot +JFL +JField +JFrog +JFryGuy +JGIRONTG +JGIV +JGlen97 +JH3305 +JH91xx +JHINitalia +JIGGYWIGGY +JIIVEE94 +JJ-M +JJ23 +JJAAKKO +JJBW +JJPowers +JJROCKETS +JJRicky +JJS BBQ +JJSM_Dulker +JJchris66 +JJoe +JJumalwelho +JK Rowling +JKMi +JKTimbo +JKUR ON 40S +JKeM +JKingJ777 +JKrollin +JKuyaa +JLG +JLowe +JLsone +JMI NG +JMTaipei +JMack +JMiddd +JOBBO +JOCKO00O0O0O +JOE EROTIC +JOKER 709 +JON3ZYY94 +JORlCK +JORlS +JP Kotsnek +JP17 +JPB at Large +JPI +JPS Daytona +JPant1ess +JPantless +JPatness +JPence +JPountney +JPudz +JR05E +JR0D +JRBeast +JRC Crypto +JROGU +JRxs +JS Xpress +JSL34 +JSLatvala +JSPACER +JS_Terminal +JSco +JShep23 +JSilvester08 +JSlice94 +JSplash +JStepho +JT5 +JTAG +JTCS +JTI ain +JTIAIC +JTM33 +JTscape +JUGIB +JUIBE +JUICEWRLD9 9 +JULlAN +JUST +JUST A HlPPO +JUST Nikk +JUSTICE +JWRLD +JXJ +JZB +JZX1O0 +Ja k ey +Ja m e s +Ja mes A +Ja se +Ja sn +JaBouris +JaDig +JaStraater +Ja_Fireking +Jaaaakkoooo +Jaac +JaackGP +Jaager Jack +Jaagmu +Jaahee +Jaakako +Jaalva +Jaamm +Jaant0 +Jaapievecht +Jaay G +JaayC +JabHook +JabbaU +JabbasHut +Jabbaw0cky +Jaber +Jabesol +Jabiborinoni +JablezGIM +Jablooze +Jabo b +Jabopanda +Jabroni +Jabroniii +Jabrs +Jabuz +Jac o b +Jacckk +Jace C +Jacerhapsody +Jacey +Jacinto +Jack +Jack Dyer +Jack Htoo +Jack Hughes +Jack Mac +Jack Maz +Jack Par-O +Jack Reipan +Jack1 +Jack12Broke +JackBadasson +JackBass4 +JackBlade +JackDanielsH +JackHammr +JackKnight +JackKvorkian +JackMayte +JackOscar +JackRod +Jack_Herer9 +Jacka +JackandCoke +Jackass +Jackass Sean +Jackazzz1 +Jackblaze +Jackbtw +Jacke +Jacked +Jackie +Jackingten +Jackisbanana +JacknHookers +Jacko Bei +JackoPogU +Jackoo +Jackos +Jackoz +Jacks +Jacks0n +Jackson +Jackspyrow +Jackyboiii +Jacob +JacobGhosty +JacobIsTaken +JacobT789 +Jacobb +Jacobieus +Jacobro +Jacobs +Jacobwins1 +Jacupy +Jacy59 +Jad slides +JadMaister +Jada +Jadakiss +Jadavius +Jaddok +Jaddy Chill +Jade +JadedRapture +Jadeine +JadenM +Jads +JadsVag +Jaecob +JaegerBoom +Jaeson +Jafacakeman +Jafanto +JafarTooHigh +Jaffa Jake +Jaffar +Jaffywaffy +Jafsx +Jagdpanther +JagerBombski +JagerIron +Jagermeister +Jagged +Jaggen +Jaghatai K +Jagoodiii +Jah toch +JahIthBer +Jahaerhys +Jahaok +Jaharred +Jahbby +JahgexPlzzz +Jahmay +Jahmerica +Jahngles +JaiSiaRamJai +Jaiden184 +Jailbreak455 +Jaime 427 +Jaimeebear +Jak Maximus +JakMetalHead +Jaka On Can +Jake +Jake C +Jake D Snake +Jake Muzzin +Jake OC +Jake Scapes +Jake Solo +JakeState68 +JakeSteFarm +Jakedajackal +Jakee +Jakeeyx +Jakermeister +JakesGHerps +JakesSolo +Jakesonville +JaketheSnake +Jakey +Jakey C +Jakeyosaurus +Jakeyz +Jaknop +Jakrem +Jakrojan +Jakuli226 +Jal-Nib-Jmal +JalNib +Jalduii +Jaleesa +Jales +Jalim Rabei +Jalite +Jaljif +Jalla +Jalo +Jaloenow +Jalordom +Jalou +Jalzas +Jam Flex +JamBandDad +Jamaikietis +JamalBobaman +Jamango +Jamania64 +Jamar +Jamaul Jr +Jambaica +Jamblaster +Jambreak +Jamburano +Jamchu +Jameo +James +James 6000x +James Comey +James Kakadu +James Kelp +James Poncho +James PvE +James Rolfe +James c +James osrs +James1087 +James2709 +James9 +James945848 +James9520 +JamesBondss +JamesCUFC +JamesDaWizar +JamesHaliday +JamesJ2019 +JamesLango +JamesMaynard +JamesNI +JamesPratt94 +JamesShotGG +James_22 +Jamesay +Jamesbombom +Jamesrb1 +Jamess +Jamesy +JamiBear +Jamiboy +Jamie +Jamie Tacos +Jamie W +JamieJams +JamieOliver +JamieXV +Jamilan +Jaminnnn +Jamixa +Jamjac +Jamlicking +Jammie +Jammmy +Jammoose +Jammy Dogger +Jammy Scone +Jamn +Jamosbondos +Jamppa +Jampy +Jampyre +Jamuli +Jamurazi +Jamwa +Jamyroo531 +Jamzylockz +Jamzz +Jan +Jan Griffith +Jan en Karel +Jan100000 +JanHenkD +JanVanLeiden +JanXtian +Jananas3 +Janar +Jancentp +Jandaer +Jandhob +Jandie5 +Jane +Janer +Janes +Janes Bond +Jango Style2 +Jango fet310 +Jangsta23 +Janice +Janikowski +Janissary90 +Jank +Jankk +Jankko +Janksky +JannaMain73 +Jannanas +Janne +JannpajII +JanoPotato +Jansky +Jansz101 +Jante +Jantex +JantheBear +Jaooa +Japanese +Japhur +Japiohh +Japles1 +Japoolie +Jappieee +Jappieness +Jappo +Jaqen +Jaqquu +Jar Of Pets +Jar Uh Dirt +Jar of Pukes +Jar of Swamp +Jar ofc um +Jar3y +JarOfCookies +JarOfH0les +JarOfSmORC +Jarab +Jare d +JareZki +Jared1234 +Jareds134 +JarlCantBank +JarlEarlKing +JarlVaarg +Jarnemelk +Jarnie Dimon +JarnoMirma +Jarnte +Jarra +Jarre +Jarredn +Jarreelll +Jarskie +Jarsse +Jaru +Jarvis +Jarx +Jas Melody +Jasberg +Jaseel +Jasey +Jasey Rae +Jashin +Jasinador +Jaskanpaska +Jason +Jason In Max +Jason73 +JasonJ +JasonLRG +JasonRises +JasonSkillz +JasonT20015 +JasonVorheez +Jasonn +Jasonnn +Jasperw90 +Jaspi +Jasthew +JasuzChrist +Jasyre +Jauneri +Jaunius +Jav +Jave +Javert +Javier Pwns +Javve +Javvymuis +Jaw +Jawaloso +Jawgasm +Jawmac +Jawniz +Jawntista +Jawor +Jaws +Jaws 2 75 +Jawshy +Jax Evasion +Jax Teller +JaximusIV +Jaxy22 +Jay Ayy Why +Jay Baby +Jay Exotic +Jay Hughes +Jay M +Jay RZ +Jay Show +Jay Sparks69 +Jay United +Jay b1zzle +Jay kell +Jay024 +Jay357 +JayDaddy313 +JayEngineer +JayFlow +JayJee +JayKay Okay +JayLunar +JayManzarek +JayMaster +JayMe x +JayMuthaFknC +JayPortal +JayRu7 +JayTheBurnt +JayTheRunner +Jaybiz +Jayden +Jayders +Jaydey +Jaydia +Jaydo x +Jaydonn +Jaydos +Jayeden +Jayhawk225 +Jayhawkers +Jayi +JayjayNeo01 +Jayksie +Jayman +Jaymeh Lee +Jaymo123 +Jaymyson +JaysATank +Jayshuunn +Jayspoks +Jayster +Jaytea +Jayteaf +Jaytee1262 +Jaywub +Jayy +Jayy Slays +Jayy x +Jayzar +Jaz Coleman +Jazo +Jazpurs +Jazz +JazzFlap +JazzMaster09 +Jazzeh +Jazzjr89 +Jazzly +Jazzy +JazzyFlips +Jb Godranger +Jba123 +Jbevzzz +Jblieves88 +Jbob72 +Jbt +Jbvff +Jc_TheCops +Jcb4646 +Jcdelavici +Jchn +Jcmalone23 +Jcolts20 +Jcourt1 +Jdaws +Jdidy +Jdoggy2018 +Jdp3 +Je nny +Je pppe +JeBoyHiddema +JeIlo +JeIly Man +JeJoat +JeK0 +Jean +Jean belette +Jean man +Jeangaboudle +Jeankeh +Jeari +Jeavoni +Jebaited825 +Jebiii +Jebrim +Jebroid +Jebroni +Jecht Shot +Jecob +JedMosley +Jedah +JedaiKnight +Jedi +Jedi Drue +Jeebiez +Jeebz +Jeefro +Jeek +Jeemis +Jeep +Jeesuhs +Jeet +Jeeve +Jeez +Jeez Christ +Jef fy +JefFamous +Jeff +Jeff Aero +Jeff C +Jeff pls go +Jeff says +Jeff the Cat +JeffEHPstein +JeffG +JeffMusk +JeffWiki +Jeffermus +Jeffica +Jeffie381 +Jeffmyster5 +Jeffre +Jeffrey Z +JeffreyFNV +Jeffreypoe +Jeffro +Jeffy +Jeffy xD +JeffyTheDahm +Jeffzuaos +JefriEpstin +Jefry +Jeft +Jefy +Jeggesen +Jeguelson +Jehdin +Jehobo +Jehtty +Jeikeorb +Jeimi +JeisBtw +Jejex +Jekd +Jekquesting +Jelbishi +Jelbringer +Jelen +Jelenner +Jelior +Jella +Jelle +Jelle Bouma +Jellie40 +Jellisme_99 +Jellitots +Jellough +Jelluh +Jelly +Jelly Bears +Jelly Booty +Jelly Dub +Jelly Sucks +JellyBeanRs +JellyGenix +Jellydonuts +Jellyfishes +Jelziin +Jelzini +Jemades +Jemelope +Jemile +Jen na +Jen0va +JenaTulwarts +Jenessa +JenfoxxSub +Jenicek +Jeniuss +Jenkiins +Jenla +Jenna Taylia +JennaHeather +Jennacydal +JenniTolls +Jennie +Jennn +Jenny +JennyElina +Jensen641 +JensenRS +Jenskee +Jenten +Jeometri +Jepp89 +Jeppe +Jeppeonkurre +Jeppie +Jepppe +Jepppu +Jepuzeka +Jepz +JerBearGrizz +JerBearOmfg +Jerak +Jerayou +Jerbelle +Jerbil +Jerec +Jereh24 +Jeremiahlewi +Jeremy +Jeremy 2007 +Jeremy Ray +Jergs +Jeri +Jerm +Jermothy +Jerms Pro +Jern Jan +Jern Tarzan +Jerne +Jernladden +Jernlund +Jernpung +Jero +Jeroen 31 +Jerom21 +Jerrbear69 +Jerre26 +Jerrin +Jerrwie +Jerry +Jerry Alan +Jerry Maine +JerryChinger +JerryMina +Jerryy +Jers +Jers Knot +Jersh +Jershawerr +Jersion +Jertz +Jeru +Jerunox +Jerusalenm +Jerziii +Jerzy +Jes2x +Jeseeka +Jesh g +Jesh-mar +JeshusChrist +Jesiah +Jesk +Jesliq +Jesper Bratt +Jesper135 +Jesperyo +Jess +Jesse +Jesse Top +Jesseq +Jessica +Jessie +Jessie Jones +Jesspresso +Jessy +JessyTrip +JessycaOSRS +Jester Head +Jesterbubba +Jesus +Jesus I love +Jesus MPhys +Jesus Saved +JesusComing +JesusRedeems +Jet Jaguar8D +Jet3010 +JetFlame +Jeththe +Jetlag +Jetma +Jetridder11 +Jetski +Jetsmoke +Jettiesimp +Jettrider +Jeugd +Jev21 +Jevel +JewFroBro +Jewbaaca +Jewbakah +Jewbang +JewishRob +Jewy +Jexlad +Jexlo +Jeyos +Jeyzuz +Jezeus +Jezkoz +Jezuux +JezzaripHD +Jezzie +Jezzx +Jf-n03 +Jfleeze +Jfrith +Jfuzzy +Jglove +Jgus88 +Jgy1889 +Jhackal +Jhb +Jhebs +Jhny +Jhonlovin +Jhoocy +Jhoocy Moot +JhormanCovid +JhosS +Jhow +Ji bs +Ji m m +Jia Lissa +Jian +Jiara +Jibajaba +Jibberflexed +Jibbllyy +JibinSui +Jibneh +JibrilMaster +Jiffee +Jig Bugs +Jiga Chad +Jiggalagg +JiggerJoe +Jiggity +Jigglyboy +Jigglywoo +Jiggypufff +Jignite +Jigoogly +Jih +Jihe +Jihne +JiiU +Jiiko +Jiim Lahey +Jiiraiiya +JikdarShark +Jikkurr +Jiklim +Jill Hyde +Jille Man +Jim +Jim Sauce +Jim Shorts +Jim0k +Jim2k1 +Jim38iron +JimAdler +JimTheGing +Jimb0bMaster +JimballSlice +Jimbeamtndew +Jimbi +Jimbly +Jimbo Sween +JimboJamzAF +JimboQuan +JimboSlice21 +Jimbob3005 +Jimbogun +Jimboi +Jimbub +JimcakeKong +Jimdawgy +Jimi +Jiminuatron +Jiminy49 +Jimm +JimmahDean +Jimmerik +Jimmi +Jimmi Lipper +Jimmmm +Jimmy +Jimmy Jumper +Jimmy Plays +Jimmy Scimmy +Jimmy Wooo +Jimmy1408 +Jimmy3rdBase +JimmyBullard +JimmyBuns +JimmyCarter +JimmyGrimble +JimmyStubble +JimmyValmer7 +Jimmybe +Jimmygk +Jimmylovecox +Jimmynyge +Jimmyo +Jimosine +Jimpertje +Jimpiix +Jims Goon +Jims Ironing +Jimsterjim +Jimver +Jin Oh +Jin R n G +JinDoritos +JinJ0 nJuice +Jinb +JingleBiloba +Jingy +Jinimy +Jinjaman +Jinkers +Jinko +Jinkys +JinnyChatBot +Jinpa +Jinsinny +Jinte +Jinxed Jake +Jinzo Doku +Jinzo Jinzo +JioGetsMoney +Jion +Jions Alt +Jipser +Jipske +Jiqonix +Jiqura +Jiraiya +Jiraiyeah +Jirakh +Jiren +Jirka +Jirou Kyouka +Jisska +Jitaxia +Jithra +JiveChompy +Jixoxx +Jixr +Jixx0x +Jiyool +Jizt +Jj Dynomite +Jj Jerk2 +Jjar127 +Jjjjjj210 +Jjozzie +Jk Esq +Jkdogg +Jkhby +Jkl Kalja +Jkolrur +Jkrexx +Jku45 +Jl-SOO +JlGA +JlLLY +JlMMB0 +JlZZB0SS +Jlarge +Jlova +Jmagelssen +Jman021 +Jmar +Jmaster402 +Jmbryn +Jmca +Jmca Savage +Jmen +Jmies +Jmjake +Jmonelite +Jmudford44 +Jmz +Jnas +JnrSeneca +Jnsthenx +Jnup +Jnwp +Jo Pain +Jo de Coeckh +Jo h 2 +Jo iron +Jo rd an +Jo shua +Jo we +Jo0l +Jo3 H +Jo3p +Jo5p +Jo6p +Jo711 +JoE ShMoee +JoEiSaFiShEr +JoJi +JoJo +JoJo Skriver +JoJo79 +JoJoJoUrBoat +JoKerRtheGOD +JoMoe +JoRouss +JoWie +JoXuh +Joacco +Joao +Joao EV +Joao Paulo +Jobac +Jobann +Jobard93 +Jobber +Jobbes +Jobbits +JobbySkelper +Jobbydrinker +Jobbyqq +Jobless +Jockward +Jocqui +Jodenzaad +JodioJoestar +Jodon +Joe 7 +Joe Kronic +Joe Lol +Joe Mangina +Joe Mclaren +Joe Muggs +Joe Potato +Joe Schwa +Joe TheBeard +Joe56543 +Joe56780 +JoeBidens Bf +JoeEldenring +JoeFoe +JoeGas +JoeInglesGod +JoeJunk +JoeMothers +JoeStudd +JoeTheGod +JoeWoody +Joebie +Joebobinator +Joecuster +Joedaschmoe +Joee P +Joeholding +Joekle +Joel +Joel 9444 +Joel In Pain +Joel Lobster +JoelBtw +Joelemz +Joell +Joenage +Joenly +Joered40 +Joeri +Joes +Joeshmo +Joestar +Joey +Joey Diaz +Joey Mobile +Joey RS +Joey069 +JoeyDabs +JoeyGatto +JoeyP +JoeySlays +Joey_1993 +Joeyboy +JoeyboySucks +Joeychh +Joeydarebel +Joeyer5 +Joeyfernando +Joeyjoe600 +Jofa +Joferr +Joffa +JoffreyLupul +Joggaplanten +Johan +Johan Cruyff +Johanbtw +JohannesN +JohannesRRL +Joherk +John +John Bilos +John C +John Cena +John China +John D4rk +John Ironman +John Mayer +John McCain +John Mugwump +John Muir +John Paul +John Penn +John Sal +JohnChaptr15 +JohnDaBoss +JohnGilespie +JohnNoyes +JohnRambo43 +JohnWLennon +JohnWick39 +John_Wick007 +Johnathan +Johnbovi +JohndemenBTW +Johnletics +Johnmcdodger +Johnny +Johnny Chinn +Johnny Dinh +Johnny Lyu +JohnnyBeanz +JohnnyChimpo +JohnnyHart +JohnnyLoco +JohnnyMellow +JohnnyQuest +JohnnySXC +Johnnypants +Johnnys +Johno381982 +JohnoMate +Johns +Johns bad ma +Johnsons +Johnsters4 +Johny +Johny Aus +JohnyLocoo +Johnyy +Johuab +Johzyn +Joizz +Jojis +Jojj +Jojkan +Jojo Rabbit +Jojora +Jojy +Jok +Jokar +Joke +Joke xD +Jokelanopein +Joker +JokerzDice +Jokinq +Jokkepappa +JokuHeppu +JokuVaan +Jokurul +Jole +JolliJolli +Jollyfarms +Jolonerz +Jolteon +Jolting +Joltism +Jomba +Jombsy +Jomer +Jommann +Jomoba +Jomppaa +Jomppei +Jon +Jon Eusebius +Jon Meades +Jon Snow +Jon ny +Jon10 +JonHDgamer +JonMarston +JonOn +JonVV +Jonadwyn +Jonahams808 +Jonahcart +Jonanism +Jonas +Jonas9115 +JonasLietuva +Jonas_Butte +Jonasbroh +Jonassau +Jonatan Jo +JonathanRoid +Jonaz +Jonbaron +Jonboy +Joncc +Jondog +JoneNikula +JoneZii +Jonesing +Jonessy +JonesyBadger +Jonetsa +Jonezey3 +Jongo +Joni +Jonibo +Jonie D +JonisBaisus +JonisSniegas +Jonjo12knees +Jonko +Jonko lover +Jonn +Jonnay +Jonne r +Jonnems +Jonnisan +Jonnisjoen +Jonno1789 +Jonny +JonnyBiggles +JonnyBoii +JonnyL2020 +JonnyLots +JonnyM +Jonnybak +Jonnybowler8 +Jonnysniper +Jonsamma +Jonsed +Jontzzz +Jonxsy +Jony +Jonzza +Joo Potato +JooOvenPizza +Jooe +JoojoThePk8r +JoonSoo +Joonas +Joonayoyo +Jooni +Joontah +Jooogijuuu +Jooohnny +Joop Mgoon +Joopaul +Joose3 +Jooshica +Joosst +Joostvd17 +Jooxan +Jophatmama +Joptvajiumat +Jor dinh +Jor dy +JorVa Osj +Jord +Jord 0_o +Jord Croft +Jord idk +Jord xD +Jord y +Jord z +JordHarris +Jord_96 +Jordan 1 +Jordan 7218 +Jordan KY +Jordan030592 +Jordan07 +Jordan1063 +Jordaneee +Jordanite +Jordans +Jordany5b +Jordavitch +Jorden +JordenFCB +Jordinee +Jordnn +Jordo Am +JordyM +JordyMcSheep +Jordynn +Jordysteen +Jordz_King +Jore +Jorenator +Jorgeme +Jorgos +Joricki +JorkinMyWorm +Jorkkelis +Jorlund +Jornaleiro +JoroEdde +Jorsne +Jorster +Jorttis +Jorzki +Jos Bezos +Jos de Mutn +Josavi +JoseLargeD +JosefStaIin +Joseluis1 +Joselyn Leo +Josen +Joseph +Joseph Sam2 +Josh +Josh 2277 +Josh Jones +Josh Tsutola +Josh x +Josh013 +Josh2Godly +JoshD +JoshDagainz +JoshGymnast +JoshMarksman +JoshYewAhh +Joshalog +Joshan +Joshery +Joshh +Joshhhh +Joshii +Joshimitzu +Joshism +Joshjoshin +Joshmaster31 +Joshpaul +Joshua +Joshuaaaah +JoshyCii +Josiah Higha +Josiahs +Josoust +Joss +Josse +Jostavo +Josti O_o +Jostle +Josue +Josukes +Josylvio +Jota_420 +Jote +Jothha +Jotjemenotje +Jotq +Jottini +Jotunheimar +Jotwe +Joueur4376 +Joulaha +Jovial +Jovilius +JovyGaming +Jowah +Jowalll +JowatBTW +Jowel +Jowitt +JoyOfSatan +Joycey1997 +Joynzz +Joystick +Joyun II +Joz6 +Jozi Blue +Jozu +Jpan1 +Jpellican +Jpq +Jqwss +Jr Metro +Jr Muffin +Jr Stigel +Jr2k13 +Jrabbat +Jrby +Jrdn +Jreppks +Jrey +Jroanirr +Jrodjok +Jrogo +JsJays +JsN4 +Jsag +Jsi7111 +Jsnn +Jsony +Jspot +Jsq +Jstnn +Jstrife9 +Jthrust +Jtownironman +Ju mala +JuGgLe BuG +JuJuzzz +Juan Dangle +JuanTalon +Juandissimo +Juaneria +Juanreliable +Jubaah +Jubarte +JubbaTheHut +Jubilations +Jubita +Jublian +Jubster +Jubtus +Jubu +Jubz +Judah +Judas wept +Judddy +Jude +Judge +JudgeDredd +Judgewalker +Judie +Judies +Judlmin +JudoChop +Juduel +Judus +Judybats +Juedons +Juezz90 +Juffo +Jug001 +JugMilk +Juga JR +Jugalator +Juganog +Jugernought +Juggalo09R +Juggerthot +Jugimaster +JuhQ +Juheniqus +Juhhu +Juhiiis +Juhis +Juhls +Juho +Juhve94 +JuiBoi +Juib +Juice +Juice W RL D +Juice WRLD +JuiceRock +JuiceUSA +Juiceb0x44 +Juiceful +Juicewayne +Juicieee +Juicing +Juicy +Juicy BIG +Juicy Jorma +Juicy Lil D +Juicy Pair +Juicy XPs +JuicyBigNut +JuicyJesusFE +JuicyJocelyn +JuicyJones +JuicyLap +JuicyTear +JuicyTigr +JuicyWetNut +Juicy_Newfie +JuiicyAF +Juikki +Juint +Juipp_Iron +Juisy +Juk e +JukeLess +Jukebot +Juked +JukeduM +Juko +Juktes +Jul es +Jules +Julesbak +Julia +JuliaFlorida +JulieFromHR +Julieekins +Julien +Julio Cesar +JuliusHotdog +Julley +Julma +JulmaJoe +Julmarsson +Julpa +Jumal +Jumanji +Jumbalia420 +Jumbo +Jumbo Joe +Jumpcut +JumpingBean +Juncker +June +June bug +Junexo +JungJulius +Jungkook +Jungle +Jungle Georg +Jungle Jepa +Jungle Jim +Jungle Wreck +Jungle175 +JungleKitty +JunglinTunes +Juniortank25 +Junk168 +Junmai +Junsimu +Juntti463 +Juo +Juoda +Juoppis +JuostenKustu +Jup1Ko1r4 +Juppi +Juqqernaut +Juranja +Jurassix +Jurble +Juri +Juri M +Jurikka +Jurisdiction +Jurky +Jurmalainen +Jurrie +Jurtaani +JuryRigging +JusAmain101 +JusCauz +JusDoMe +JusPourVous +Jusfat +JussJoshinYa +Jussi +Just +Just Alright +Just Alt F4 +Just BeingMe +Just Bones +Just Bryce +Just Champ3 +Just Creepin +Just Dank +Just De-Iron +Just Jacob +Just Keith +Just Kurt +Just Logan +Just Malone +Just Milton +Just Mitch +Just Neptune +Just Reacher +Just Treason +Just a Dilf +Just a main +Just aFacade +Just for Fun +Just1n Sane +Just3lis444 +JustAAPotato +JustADowny +JustAFroggy +JustBob +JustChillins +JustDevon +JustDrew +JustFollow +JustGoInDry +JustIan +JustJS +JustJake +JustKidStuff +JustLucky +JustNewbin +JustPeachy +JustPertti +JustRenne +JustRoW +JustSarge +JustSinful +JustTaxLand +JustTheFool +JustTheTip +JustToast +JustTrynaMax +JustVibeWMe +JustVinny +Justa Wake +JustaStar +Justass +Justice v1 +JusticeSven +Justicemoose +Justiciaro +Justified +Justin +Justin NT +JustinBieber +JustinFromVA +Justinkai +Justinolk +Justins007 +Justlfied +Justnexuss +Justo80 +Justorr +Justryin +Justyfi +Justyn +Jusus +Jutendouji +Jutku +Jutkunmetku +Jutter +Jutti +Jutty Ruckus +JuuNinJi +Juugmasta +Juul +Juulxodia +Juun Solo +Juuna +Juunaz2chips +Juustis +Juuzo +Juvi +Juvian +Juzzy +Jvzy +Jwad +Jwcsg +Jwd +Jwett +Jwu +JxJxV +JxcelD +Jxck +Jxcx +Jxdidiah +Jxdooo +Jxhnn +Jxke +Jxmeson +Jxnas +Jxni +Jxstxn +Jxxst +JxyStorm +Jy +Jybais +Jyeronese +Jygers +Jyhlln +Jyhy +Jype +Jyppedi1992 +Jysk +Jyura +Jyy +Jyypy +JyzzBrah +Jz +Jzbeta +K 1 L L A +K 1 P +K AMI +K B D autism +K E K E B +K E L A +K E T CHUM +K E V 0_O +K Hades +K K Boef +K NW +K O L L I +K O M P I S +K OOOOOOOOOO +K P N +K P Sweet +K Smalls +K W +K W A L A +K Y Y +K a l e w i +K a z a +K aarel +K ayyla +K eller +K elvin +K en +K etaminer +K ev +K iNG IRON +K idd +K ilo +K im +K l 9 +K l N G S +K nauss +K nut +K o j o +K o o s a +K ohen +K orruptt +K ree +K rs +K t r n e +K una +K ushi +K uz +K voth e +K y u m a +K yogre +K-Diddy +K-epan +K-market +K0 +K0 4 +K00LBR33ZE +K0F +K0L0S +K0NING +K0USE +K0bus +K0edinator +K0ju Balius +K0lbi +K0ndemned +K0rky +K0rnuit +K0tleciokas +K0veras +K0zor +K19 +K1ERZ +K1LLY +K1ddl3 +K1ller5169 +K1ng +K1ngo +K1ngshredder +K1r1t0123 +K2 Jung +K32 +K38 +K3KSE +K3U S2 +K3azkoks +K3fka +K3kt +K3mi +K3nn3d +K44K +K4IF20 +K8iee +K99 2 +K9Father +K9lenny +K9rk +KA97 +KABBABEAST +KAKAGUATE0 +KAKERANDELIN +KAL-JML +KAMlX +KAT alyzt +KB1988 +KBARAKAT +KBX0 +KC Chiefz +KC M0 +KC8 +KCRB +KChiefn +KDOG1419 +KDOT_OSRS +KDark22 +KDrizzy +KEEPOUNDING +KEEPTHATSHIT +KEEZY10 +KEIF +KEKDUBYA +KEKLERO +KENTUCKYBLUE +KEllis +KFBal +KFC CAMDEN +KFC EMPL0YEE +KFC OG +KFCatz +KFChompy +KGBK +KGCine +KGP +KGee +KGoldy +KHADER +KIIIIIIIIIIH +KILLER COMBO +KILO +KIMB0 +KING +KING GAYWAD +KING VILO +KING332 +KINGNERON +KINGstayMAX +KINGxGIZZARD +KINNTO +KIPPER +KIVI 420 +KIWI Stu +KIitor IS +KJ 2 +KJ6 +KJLS +KKayK +KKela +KKona +KKona USA +KKrazyAl +KKronas +KKurtiz +KL93 +KLB +KLS +KM 30 +KMW +KN0G +KNIKERSNIFFA +KO CANE +KOK enjoyer +KOKAOKAA +KONMAI +KOS OVO +KOlRA +KQSS +KR Zangetsu +KR0VALI +KRN +KRON1C 420 +KRYMK +KRYPTONlAN +KRlT +KRonHusker +KS04rs1 +KSP +KSaucee +KT Ferrie +KT Tape +KU51 +KUAY +KUAYx +KURD1STAN +KVM8 +KVRPT +KXNG Razing +KXNGVEGETA +K_sak +Ka0s50 +Ka92 +KaChiuSa +KaIOKENRAGE +KaMi +KaMi_RnG +KaTFeniX +Kaan +Kaan Frog +Kaarel55555 +Kaaris95 +Kaarv +Kaasbaap +Kaasboom +Kaasmantel +Kaaswater +Kaaz Channel +Kabatlor +Kachhow +Kacinova +Kacy +Kacyy +KadHead +Kadabara +Kadan +Kadarlu +Kadett Opel +Kadeyr1 +Kadocc +KaeBtw +Kaelin +Kaempen +Kaepls +Kaer +Kaesar +KafHaYaAinSa +Kafaei +Kaffah +Kafficko +Kage Boshi +Kahdoom +Kahis +Kahlx +Kahto +Kahuna +Kahur111 +Kahvikuppi +Kahvimaa +Kahvo +Kahwoozy +Kai ri +KaiHos19 +KaiXin +Kaibaman +Kaif +Kaihn +Kaiirl +Kaila +Kails +Kaimanll3kav +Kaimorten +Kainahuulio +Kaine +Kaioken x420 +KaiokenRyan +Kaion +Kaiser +KaiserBruno +KaiserRS +Kaister +Kaitaia +KaitoSun +Kaiven +Kaizen Reign +Kaizen Soji +KaizennxX +Kaizloh +Kaizooka +Kajbanan +Kajgils Far +Kakariiiiick +Kakarrot +Kake +Kaker +Kakerandeli +Kaki317 +Kakoji +Kakor +Kaksitoista +Kaku +Kaku bakudan +Kakua +Kakuri +Kal9000 +Kalakoi +Kalas +Kalash556 +Kalashnikova +Kalavothe +Kalb +Kale +Kale Henk +Kale vader +KaleKikker92 +KaleRS +Kaley Cuoco +KaleyFan +Kalezki +Kalfite +Kali Maaaa +Kali Roses +Kaliaa +Kalico Cat +Kalideos +Kalihi +Kalikow +Kalima +Kalis +Kaliumoxide +Kallateral +Kalle +Kalle Anka +Kalleee +Kalmaars +Kaloex +KalopsiaSix +Kaloua +Kaltsu +Kalu1337 +Kalub +Kalvaaja +Kalveo +Kalystas +Kam +Kam Lok Lam +Kamal63 +Kamchi +Kamelinpiaru +Kamelovsky +Kamelze +Kamen +Kami_no_majo +Kamiel +Kamii Dad +Kamijou +Kamikazi +Kamino +Kamino Kage +Kammorie +Kamp +Kampest +Kamphuijs +Kanagawa +Kanao +Kanapius +Kanapizza +Kanbu +Kandarin +Kandeeh +Kandid GG +Kandonesys +KandrakarsNX +Kane +Kane 7687 +Kaneelkameel +KanekiKun +Kaneohe +Kangru +Kangst3r +Kani +Kaninka +Kanned +KannonBalker +Kannski +Kansas +Kansas Bill +Kansas State +Kanseim +Kansi +Kansloos +Kant +Kantinejuf +Kantoo +Kantrimees +Kanttis +Kanuk +Kanye +Kanyeetzy +Kanzeigan +Kaolo +Kaolo Spoon +KaozerMauser +Kapaa +Kapakala +KapeVing +Kaphu +Kapiling +Kapitalisti +Kapitein +Kapiten +Kapkeik +Kapkkha +Kaporkchop +Kapot +Kapot Slecht +Kappa 73 +Kappa monkaS +Kappa xD +KappaZilla +Kappala +Kappalism +Kapsaluun +Kapsones +KaptainPurp +Kaptainkilla +Kaptains +KapteinK +Kapten +Kaptn skev +KarQ +Karaboudjan +Karaf +Karagoz +Karamjob +Karans +KarateKon +KarazySS4 +Karc +KareemPie1 +Kareir +Karekano +Karen +KarenMaskin +Karethaeis +Kargas +Karhu48 +Karhuboiii +Karhulohi81 +Kari +KariJuice +Karies +KariimsPik +KarilSummer +Karils +Karim4lol +Karkanii +Karkotaseet +Karkov +Karl +Karl The SUV +Karl1s +KarlS282 +Karlee +Karliah +Karlit +Karlology +KarlosBro +Karlteine +Karma +KarmaRush +Karmaa +Karmadyl +Karmafox +Karmah +Karmas +KarnMother1 +Karnivore +Karnyx +Karolik +Karolus6 +KarpyCarpe +Karrak7 +KarsanHAM +Karsk kopp +Karskeinmies +Karso +Karsta Anne +Kartelrand +Kartoesh +Kartoma +Karukas0 +Karumba +Karumi +Karuu +KarvaBanaani +Karvajarru +KarvaneMees +Karvatatti +Karwos +Kasane +Kasdeya x +Kasei +Kaseii 1 +Kasejas +Kasen +Kaser +Kashak +Kasihan Gua +Kasoku Tesla +Kasp +Kasperjus +Kasprzak1 +Kaspuhh +Kasraa +Kass Glimmer +Kassipotku +Kassu +Kassu C +Kasuel +Kasugano +Kasvikko +Kat1nr +KatBeatitude +Katagon +Kataphatic +Kate +Kate Bush +KateTiffany +Katenkos +Katetuotto +Katfishh +Katiensam +Katikene +Katikene0 +Katinas +Katiopeia +Katlink5 +KatnissGray +Katraenia +Katrielle +Katski +Katsuo666 +Katt 90 +KattNiP +Kattarui +Kattnakken5 +Kattnis +Katze btw +Katzes +Kauhee Hiki +Kaukeneris +Kauldron +Kaunas +Kaunas_Rulz +Kaunopihlaja +Kautschuk +Kavz +KawaBonga +Kawactus +Kawaii +Kawaiimachin +Kawaiisaki +Kawakuboku +Kawkaw +Kawked +Kawtik +Kay D +KayJ +KayWhyPee +Kayazy +Kayback +Kaybizzle +Kayden +Kayden Boy +Kayen +Kayla +Kayla Swift +Kaylidascope +Kaylizz +Kaylon +Kayluh +Kayns Main +KayranFootly +Kayso +Kaytok +KayyPlz +Kayzielol +Kayzo +Kazatan1245 +Kazave +Kazaz +Kazcade95 +Kazching +Kaze8HerOut +Kazify +Kazuma Moon +Kazunni +Kazuuhiro +Kc Collector +Kcnny +Kdash +Kdaw +Kdens +Kdragons +Ke bajo +Ke era +Ke nt +KeB4NG +KeRah +Keabler +KeanuCat +Keasbey +Kebab +Kebab Ari +Kebab Store +KebabGuy93 +KebabWrap +Kebabov iron +Kebbabhallal +Kebbby +Kebbe +Kebintotero +Kebs +Kecok +Kedakaki +Kedirav +Keebler +Keef Supreme +Keef_Man +Keegi100 +Keekar +Keekers +Keel +Keela +Keelay +Keenar +Keep Le Fe +KeepCup +KeepDistance +KeepItWicKeD +Keeper1OS +KeepitStoney +Keepo +KeepoKeisari +KeepoNoIron +Keepomaster +Kees +KeesCanadees +Keeslp09 +Keetgracht +Keevon Man +Keff +Kegaz +Kegern +Kegs +Kegse +Keh O Brien +Kehaline1 +Kehno +Keiala +Keidy9 +Keifay +Keikoh +Keinas18 +Keiran +Keiran Perch +Keironn +Keisari +Keisarinna +Keister Egg +Keit +KeithMcChief +Keithii +Keittokuppi +Keizer +Kekaha +KekeLovesMe +Kekkonen +Kekkonen69 +Keksiviikko +Kel Darsam +Kela +Kela maksaa +Kela-Olli +Kelagang +Kelb +Kelbikers +Keldran +Kelen +Kelerak +Kelgone +Kelh +Kellarivelho +Keller +Kells o_o +Kelly +Kellycollin2 +Kelohonka +Keloo +Kelps +Kelso523 +Kelso561 +Keltik +KeltonThaGod +Keltuzazz +Kelu +Kelvin2GWW +Kelvino +Kelwus3 +KempBush +KempDaShrimp +Kempisch +Kempset +Kempy x +Ken +Ken Bolka +Ken Griffey +Ken Kill U +Ken RS +Ken Ten +Ken141 +KenBone +KenKaniffCT +KenPerm +Kendal x +Kendal68 +Kendlang1 +Kendrick3691 +Kenery +Kenesu +Kenfernal +Kenleyy +Kenleyy_TM +Kenmaster +Kenn +Kenn y +Kenna +Kenndu +Kennedy +Kenny +Kenny Deez +Kenny121 +Kenny6397 +KennyKSD +KennyS +KennyWhopper +Kennyollie +Kennypower5 +Kennyyyyyyy +Kenozh +Kenpo +Kensan-7 +Kenshiro +Kent +KentWasTaken +Kentacus +Kentarokins +Kentish Hops +Kentucky +Kenwood +KenyanChild +Kenyann +Kenze +Keonii +Keox +Kep +Kephan +Keplunk +Keppi +Keppi Einari +Kepra +Kepuck +KerZam +Keraliix +Keratin +Kerbeth +KerfDaddy +Keri +Keric +Kerk +Kerkerino +Kermajorma +Kermit +KermitTheRob +Kernalpotato +Kernautist +Keromasev +Kerrr +Kertar +Kerzara +Kes Sittus +Kesc +Kesekui +Kesohs +Ket +Ket Baggie +Ket Schep +Ket Uh Mean +KetaKnallt +KetaYours +Ketabar +Ketanator +Ketch +Ketho +Ketnet +Ketonall +Ketsah +Kettaz +Kettu +Kettyman +Ketwards +Keudel +Keunic +Kev The Tonk +Kevain69 +Kevali +Kevb0t +Kevbro9 +Kevichan +Kevin +Kevin Booker +Kevin Framed +Kevin Nguyen +Kevin5-0 +KevinDurant +KevinLawrune +KevinOSeven +KevinTes +KevinTheGOAT +Kevinspostal +Kevinw20 +KevlarX +KevolutionX +Kevsin2 +Kevsin3 +Kevslays +Kevstrong +Kevthebos +Kevva +Kevve +Kevzy +Kewl +Kewlaidman +Kewnsauce +Kewwl +Kexkaka +Key Concept +KeyNoir +Keyashes +Keydiss +Keyfob +Keylock +Keylord +Keyney +Keyoh +Keyori +Keyose +Keywork +Keyzz +Kez0 +Keza132 +Kezmaya +Keztra +KezzerQ +Kezzerina +Kgb Spy +Kgsnipe +Kha Zx +Khaant +Khabib +Khader +Khajgold +Khal +Khal Bow +Khaled +Khaleeeesi +Khaleesi1113 +Khalesar +Khalisee +Khamoshi +Khan of Iron +KhanhDung +Khans Wrath +Khanzed +Khao +Kharium94 +Kharjo +Kharn +Kharos +Kharzan +KhatrickZain +Khayri Demon +Khazad +Khazad Dum +Khazanedar +Khazu +Khealim +Khest +Khint +Khirean +Khiru +Khleb +KhooNBust +Khoosh +Khoppa +Khornebull +Khovansky +Khride +Khrollo +Khryptik +Khrysus +Khufu +Khune +Khunt Flapz +Ki Adi Fundi +Ki Arts +Ki Stu GSK +KiD BeeR +KiIIa4realz +KiLn +KiSMET6 +Kia Jon +Kiarama +Kibb +Kibeleza +Kibisai +Kibito Kai +Kibra +Kick +KickarseCale +Kickback Dw +Kickbums +Kicker +Kickrolls +Kid Inferno +Kid K O N G +KidClutch17 +KidLeaderKTY +KidSativa +Kidalien +Kidchilly100 +Kidd +Kidlizard +KidneyBean +Kids +Kids Bong +Kidtrilogy +Kidur +Kie +Kiedis +Kieftron +Kiek um goan +Kieken +Kiekkoilija +Kiera +Kiero +Kierzo +Kiewit +Kifooo +Kifsa +KiiDSKOLiO +Kiinja +Kiinnostaa +Kiirii +Kiisu +Kiivi +Kiiwityty +Kiizoru +Kijucatm +Kikikissa +Kikiniki2 +Kikkel +Kikkertje +Kikyo101 +Kil U +KilIerDaddy +Kilamanjaro +Kilbot0 +Kiliann +Kill +Kill Crazy10 +Kill Credit +Kill the GE +KillConfirmd +KillSwitch26 +Killa +Killa Cam +Killa Kamali +Killa213 +KillaSilence +Killab0rtion +Killabrew +Killadelphia +Killadeuce +Killamemsta +Killaowns +Killatonicus +Killed +Killed Elmo +Killed145 +Killekalekoe +Killemall +Killer +Killer Jr +Killer Kurce +Killer7502 +Killer81093 +Killer9823 +KillerFlix +KillerSlee +KillerVibes +Killerank202 +Killercaster +Killerdog HC +Killerdustyn +Killerkotti +Killermatt +Killeroh +Killers455 +Killertribes +Killgor138 +Killi +KillianRS +Killing +KillinxLivin +Killjoy4fun +Killjoyer2 +Killmankind +Killme5551 +Killmelol +Killnloot2 +Killoah +Killsw1tched +Killswitch83 +Killua +KilluaSam +Killzone +Kilminater +Kilo Meter +Kilodoreo +Kilograms +KiluaZoldyk +Kim +Kim Chungha +Kim Trails +KimKallstrom +Kima +Kima Ronso +Kimano +Kimbr0 +Kimbu +Kimex +Kimi Hendrix +Kimoja +Kimosabii +KimtonLe +Kina +Kinaesthetic +Kinboat +Kind +Kinda +Kinda Blue +Kinda Sinful +KindaDerpy +Kindaddy +Kindom +Kindoou +Kindozsodln +Kineettinen +Kinetic +King +King 0f Gout +King Ankle +King Aussie +King AvonIV +King Blob +King Boned +King Bud +King Bugs +King Chev +King Dong +King Dongo +King Edolus +King Elf +King Elon +King Emurxer +King Flipsta +King Frodon +King Green 2 +King H0d0r +King Ian +King Junkie +King Kabanos +King Kenneth +King Lexius +King Mariin +King Milky +King Nino 1 +King No Fear +King Noc +King Paf +King Rabbit +King Rayman +King Redeem +King Rico +King Runs +King Ruonis +King Seb +King Seneca +King Size V +King Slime +King Snowman +King Spudz +King Swine +King Tsar +King Westor +King XRPL +King Zaros +King davey +King of Imps +King of PvM +King0fHelll +King0fSkane +King1631 +KingAcorn85 +KingAwowogay +KingBOO +KingBailey +KingBoo +KingBuliwyf +KingClark +KingCudii +KingCurtis11 +KingDarkVII +KingDweebus +KingEider +KingFlugal +KingGoblin09 +KingGrekus +KingGunshow +KingHawk O_o +KingInYellow +KingJacula +KingJelore +KingJoey +KingKahuna +KingKlick373 +KingKlye +KingKongKoen +KingKong_Qc +KingLeonidas +KingMikeyD +KingMongo +KingMonk +KingMook +KingNate1 +KingNathanx +KingOfIron +KingOfQuests +KingParcival +KingPatVII +KingPlAnchor +KingPractice +KingRobStark +KingRustyVII +KingSandCrab +KingScribles +KingSizeD1CK +KingSoge +KingSpirel +KingStyle +KingTheGreat +KingTsjubbie +KingValencio +KingYoshi +KingZac +KingZerka +King_Kerran +Kingaroo +Kingben +Kingbuddy40 +Kingdom Rush +KingdomBlade +Kingeri +Kingg +Kinggg +Kingism +Kingjake18 +Kingmonkey23 +Kingofhearts +Kingpfx2 +Kingpin +Kingpin Xp +Kingpk3r +Kingrobster7 +Kingruler456 +Kings67 +KingsBluue +KingsGrace +Kingspadex42 +Kingsta +Kingsthor +KingstoAces +KingstonWall +Kingsty +Kingz Haki +KingzWorld +Kinjello +Kink +KinkerScaper +Kinkers +Kinky +Kinky Kenny +Kinky Scr +Kinkybuns +Kinkytoast +Kinkyy +Kinno +Kinobles +Kinokird +KinokoZoku +Kinp +Kinsaic +Kintoki300 +Kiopley2 +Kiox +Kipee Anneli +Kiplup +Kipnuggets +Kippenbro +Kipsel +Kiptandori +Kiqz +Kiraci +Kiraga +Kiraly +Kirara +Kirbi Smart +Kirbngo +Kirbsey +Kirby +Kirby7670 +Kirchberg +Kire1n +Kiree +Kiriel +Kirimah +Kirito +Kirk4 +Kirk97 +Kirkburton1 +KirkyBeast +Kirne +Kirrion +Kirry +Kirstin +Kirthor +Kirumibe +Kiruzonu +Kirx125 +Kirz +Kisa +Kiseki +Kisizel +Kisle +Kiso Valley +Kiss +Kiss Kiss +KissMeHomies +KissOfFire +KissOfFury +Kissahomie69 +Kissanpentu +Kissmyase111 +Kist +Kit Fistoo +Kit10Kat +Kita +Kitashan +Kite Solo +Kiteman +Kitfox IV +Kitsch +KitsiKitty +Kitsune +Kitsune Kami +Kitsune Ness +Kitsunemimi +Kitten +Kittenz +Kitties +Kittle Bits +Kittoh +Kitty +Kitty Perry +Kitty v2 +KittyMeow83 +Kittymouse 1 +Kittys Newb +Kiusatus +Kivespulla +Kivick +Kiwa +Kiweh +Kiwi +Kiwi Icons +Kiwi Stona +KiwiIskadda +KiwiMacJ +KiwiSteve +KiwiTheBot +Kiwiana +Kiwidude +Kiwiskurt +Kiwwion +Kiyak +Kiyoko +KizJ +Kizminsky +Kizone +Kizz mo +Kizza +Kj Kai +KjellEllen +Kjellberg94 +Kjomo +Kjottfifaan +Kkobe +Kkobugi +Kkokkom +Kkoppa +Kl2AZY +Kl3RAN +KlDDO +KlLL +KlLL 4 BONES +KlMI +KlMpossible +KlND +KlNG +KlNG MlKE +KlNGY +Klaar +Klaarkomer +Klaasie +Klacky +Klanezy +Klanks +Klankss +Klapzak +Klarence +Klariany +Klarna +Klaskdeng +Klassic +Klassified +Klatscher +KlausLittle +Klaussie +Klavan +Klavelon +KlazBooy +Kleatus +Klebold +Kleened +Kleiades +Kleine bolle +Klementtii +KlemmDawg17 +Klemonhaze +Klengie +Kleo +Klepdiezle03 +Klepp +Kleptic +Kletz +KlewKlew +KliKlack +Kliewer +Kliffa +Klik gebit +Klikke +Klingons +Klippzz +Klo0 +Kloefklapper +Klogin +Klonzyon +Kloofiool +Kloorijoodik +Kloot-Zuk +Kloover +KloreCore +Klotho +KlovneKrabbe +Klowdstr1fe +Klub Dubx +Kluftritter +Klumpy +Klumsie +Klunchkey +KlungePlunge +Klunkii +KlutzyKay +Kluuntje +Klvtz +Klyd +Kmac +KmartWorker +Kmd +Kmie +Kmk_Yawgmoth +Kmorken +Kmtfwtm +KnD xP +Knaap +Knabbelbaars +Knabbernossi +Knacker +Knakenstein +Knaksaucage +Knallbarsk +KnarfeRS +Knastaris +Knastee +Knaught +Kndd +Knead +Kneeeled +Knewby8 +KngBlkDrogon +Knickers +KnicksNati0n +Knife +KnifeStory +Kniffes +Knight +Knight Crip +Knight Drake +Knight Jo +Knight Mors +Knight of 3 +Knight50 +Knight522 +Knight5247 +KnightKettle +KnightMike +KnightO +Knightcrawle +Knightenator +Knightlock +Knightmare +KnightmareNL +Knightrainy +Knightromite +Kniili +Knikkerbal +Knivezii +Knob End +Knobin Hood +Knod with Me +Knoo +Knospi +KnowMadss +KnowPurpose +Knowing +Knowledge +Known +KnowsNoFear +Knoxville333 +Knuckle +Knuckles +Knulle +Knummi +Knurrbauch +KnusCaboose +Knusseprulle +Knut Knut +Knwn +Ko Addiction +Ko D Ur Dead +Ko0tje +KoBe +KoH Zoro +KoPvM +Koa +Koak +Koala +KoalaBear819 +KoalaBwala +KoalaHeist +Koalarobe +Kob Bryant +Kob3oshii +Kobakat +Kobayashi89 +Kobe +Kobenna +Kobi btw +Kobold +Kobushi +Kochelas +KochiiBear +Kocjancic +Kocyte +Kodai +Kodak +Kodax +Kodeth +Kodfunk +Kodie +Kodipar +Kodo +Kody IRL +Kodywithac +Koekebakker +Koekenpan +Koekienator +Koelkast1 +Koelkast3120 +Koelogg +Koemi +Koenfu +Koeppy +Koerdistan +Koff +Kofferbak +Koffie +Koffie Shop +KoffieBoer +Koffiekan +Kofnx +Koga09 +Kogarah +Koge +Kognito +Kogsin +Koh Me Lo +Kohda +Kohrosian +Koii Diva +Koka +Koki +KokiriSword +Kokki +Kokkue +Kokkugoburin +Koko10tkd +Kokoftu +Kokou +Kolade123 +Kolariah +Kolarino +Kolbot +Kold Pizza69 +Koldbetrayal +Koldz +Kolicee +Kolmay +Kolmiojuuri +Kolodinsky +Kolomit +Kolton +Komai +Komarov26 +Komijn +KomisarzFlak +Kommunist +Komog +Kompact +Kompania +KomradeScape +Komugi +KonDaTV +KonKai +Kona +KonaTheCake +KonaTheGent +Konami +KonarMilkies +Koncept +Kong +Kongen3609 +Kongherodes +Kongklunk +Kongmoakim +Kongon Musta +Kongz +Konigs Tiger +Konigsblau +Koningnoob +Konjakkia +Konkelbearet +Konkuuu +Konnie +Konnor Ray +Konny +KonosubaAqua +Konroy11 +Konstiq +Kont Crumbs +KonteNeuker +Kontentti +Kontoret +Kontrafakt +Konu +Kony +Kony4ever +KonyRomo +Konya Slayer +Koo +Koob +Kooben +Kooch50 +Koochie +Koogs +Kooiker +KookieDough +Kooky Kal +Kool Aid76 +Kool Hwhip +Kool Iron +KoolKriegs +Kooleey +Koollpop +Kooloo Limpa +Koomar +Koomorang +KoontzyJr +Kooopa +Koopa +Koopa Kash +Koopatrol +Koopley +Koops +Koothi Jr +Kop0nen +Kopet +Kopites +Kopn Alt +Kopoes +Koppa Olutta +Kopra_0nu +Kopzilla0 +KoqPuuser +Korado +Korail +Koral64 +Korangarr +Korasko +Korazi +Korbet +KorbolJestem +Korby_K +Korea +KoreaBread +Korean +Korean Neet +Korelivia +Korihoko +Korisas +Korkesh101 +Kormulus +Korneel +Kornettos +Korok +Korpokkur +Korravalvur +Korsair +Korsan +Kortti +KosChiquiss +Kosaki +KosarevSpawn +KosenRS +Kosey +Kosha Engler +Kosken Kovin +Kosmckid +Kosmo +Kosra +Kosst +Kossukissa +Kostaja123 +Kosteezer +Kotaki95 +Kothfan2 +Kothfan3 +Kothu +Kotimaista +Kotkatapult +Kotoe +Kotov +Kottis +Kotze +Koucii +Kouen +Kouhais +Kouldi +Koulupummi +Kourend +Kourk +Kov0s +Kova Kova +Kovacs +Kovacs Bela +Kovaley +Kovalux +KovidKai +Kovit +Kow +Kowawa +Koxu +Koy +Koy5 +Koyix +Kozileks +Kozmic +Kozojebec +Kozyshack +Kpiy +Kprs +KpyosX +Kq +Kr0jm +Kr149 +Kr1sten +Krab +KrabbiePatty +KrackScape +Kradoth +Kraff +Kraft Slave +Kraftra +Krafty +Kragjay +Kragwa +Krahhling +KrakaJ +Kraken +Kraken Beerz +KrakenSnacks +Krakenarse +Krakenmom +Krakkars +Kralik +Kralovna +Krammetje +Krana +Kranky Kraut +Kranox +Kransie +KrapNSchitz +Krapinschitz +Krappa +Kraq +Krasznahorka +Kratic +Kratje +Kratos +Kratos-Arepa +Kraujukaz +Kravcik +Krawall +Kray +Kraytoast +Krayz818 +Kraz3d +Krazed Zen +Krazezor +Krazy +Krazy Kramer +KrazyKillah3 +Kream +Kream PIE +KreampieKing +Kreams +Kree +KreeM_Pies4U +Krel +Kreme Krispy +Krepe +Kreshink +Kreupel hond +Kribo +KriegFleisch +Krigare +Krigersej +Krigsgaldr +Krikkos +Krile +Krillin +Krillin It +Kriltar +KrimenReborn +Krios +Kriptog +Kris 2 +Kris Kross +Kris Tis +Kris Toffer +KrispCowMilk +KrispyCow +KrispyJello +Krispz +Kriss42 +Krisse +Krisstian +Krisstof +Kristina +Kristo1337 +Kristoh +Kristops +KristySlays +Kristya +Kriszx +Krith +Kritters +Krizalid +Krizee +Krllykins +Kro +Kroeg +Kroekoek +Kroer1 +Krogan +Krohmos +Kroketten +Krombop Mike +Kromuh +Kron0 +KronScape +KroniKStyL +Kronic +KronicPlague +Kronic_gtt7 +Kronjuvel +Kronoryx +Kronstedt123 +Krontio +Kropium +Kross +Krownax +KrthisIrnhrt +Kruber +KruimeIkoek +Kruisboog +Kruizar +Kruncha +Krusch Qc +Krusk09 +Krustorb +KruttGutten +Kruuxt +Krvavec +Krw +Kryder +Kryderman95 +Kryl +Kryllz +Kryoge777 +Krypsiss +Kryptanite +Kryptic +Krypto Pup +Krypz +Krystalbead +Krystalized +Krystie +Krytl0rd +Kryxon +KryyptCeepR +Kscott +Ksed +Ksteg +Ktran4 +Ku +Kuaalo +Kuanta +Kubanna +Kubfu +Kubiak +Kuchera +Kudos +Kudra Shade +Kudsk +Kudt +Kuemper +Kufke +Kuger +Kugi +Kuha +Kuhis +Kuhki +Kuhnlicious +Kuhvon +KuhwazyyPVM +Kuhz +KuidaoreTaro +Kuistikopone +Kuittis +Kuji Otoya +Kukii +Kukko +Kuksukka +Kulak +Kuler +Kuli +Kullilutku +Kullirausku +Kumara Fries +Kumduh +Kumeku +Kumetis +KumikoOkada +Kummars +Kummens +Kumoga +Kumonyru +Kunakana +Kunaphela +Kundalini888 +Kung +Kung Aguero +KungFuKennyy +KungFuhr3r +KungFury01 +Kungfuu000 +Kungler +Kungzaki +Kunie +Kunkku289 +Kunkulu +Kunsel +KunukGL +Kuola +Kuollu Homer +Kupla +Kuppi +KurSiens +Kuran +Kurasaki21 +Kurask +Kuratus +Kurayamii +Kurdishtan +Kurfue +Kurgan +Kurib0hh +Kurim +Kurios +Kurko +Kuro +Kuro6757 +KuroKama +Kurohige-Jm +Kuroma +Kuroshin4 +Kursdragon +Kurt Cocaine +Kurt1sdbr +KurtMaxed +Kurtan +Kurtismo789 +Kurtiz +Kurtowogei +Kuru +Kurumin +Kurums +Kurune +Kurza +Kurzgesagt +Kurzi +Kurzol +KusOnRNG +Kusai +Kush +Kush 999 +Kush Grey +Kush Nerd +KushWizdom +KushalaDaora +Kushanada +KushedKnight +Kushies +Kushioned +Kushkhalifa +Kushmooms +Kushtyyy +Kusiaks +Kusimuna +Kusimuna JR +Kusle +KusmarPavola +Kuso Saiko +Kut Jack +KutInternet +Kutasy +Kuthay +Kutirons +Kutkip +Kutori +Kutunawa +KuuDuu +Kuudere +Kuulus +Kuuw +Kuvakei +Kuwolski +Kuxx +Kuykendoll +Kuzh +Kuzi +KuzzzTruckin +Kvacky +Kvamsdal +Kvaoathe +Kvzy +Kwadraat +Kwakske +Kwambam +Kwan +KwanDynasty3 +Kwani +Kwarkark +Kwastaken +Kweem +Kwei +Kwep +Kwieppie +Kwintal +Kwondeo +Kwong +Kwongo +KwuarmFarm +KxKxW +KxNoTTz +KyIll +KyPolar +KyWi +Kyaandere +Kyafa +Kyberpaavi +Kye187 +Kyeb +KyeeG +Kyelee +Kyersago +Kygehn +Kygesm +Kyhlen +Kylanater +Kyle +Kyle 8990 +Kyle Esq +Kyle G +Kyle Kmac +Kyle VA +KyleFammm +KyleGrounded +Kyledog829 +Kyler +Kyler Moss +Kyles Cute +Kyles GIM +Kylesteven +Kylewwashere +Kylex +Kylianvb +Kylliel +Kyloman +Kymeister +Kynodontas +KyotoSadness +Kyouan +Kyouko +Kyouma +Kyouna +Kyouran +Kyphrus +Kyps +Kyr0s +KyraXIV +Kyrakishuun +Kyrdaar +Kyrie +Kyrist +KyroThanatos +Kyroba +Kyronius +Kys Ironmen +Kyski +Kytkinpommi +KyuubiKurama +Kywt +Kyykin +Kzyl +L 0 S T Y +L 3 G 4 C Y +L 67 +L A R A M S +L Ben +L CBO +L D A +L E G E N D +L E G O +L E L O +L E P I +L F C +L FC +L Hus +L I N U X +L I V M +L OAFS +L S Q +L U I G +L U U K E +L X R D S +L achie +L aika +L aka +L ama +L ang +L apras +L atias +L aw Rune +L aze +L e an +L eafErikson +L egs +L ek +L emaster +L ev +L i m a a +L iamm +L iar +L ilo +L inox +L ions +L o w g +L ockdown +L ofty +L osi +L paradoxum +L u m i +L u mi +L u x +L ucas +L unatic +L00000 +L00M +L00OL0OO00OL +L00T SNIPER +L00tacr1s +L00termember +L0G0 +L0GI +L0L +L0L0LL0L00LL +L0RA +L0RD +L0RDGAINS +L0ST S0UL +L0Z +L0kur +L0rd +L0rd Arthur +L0rdMullett +L0st +L0vecraft +L0ves2Splooj +L109 +L115Squirtle +L1L GN0ME +L1ghtweaver +L1l bits +L1ncoln +L1ndman +L2 +L2Crash +L2D3 +L2Loki +L2love +L2mmutaja +L2sit +L2tankbandos +L2tob +L337 GodHand +L3RKON +L3V3L +L3apOfFa1th +L3gg0 +L3mur +L3prec0n +L3sius +L3tMeBreath +L4D2 Enjoyer +L4rry +L4st +L522 +L64 +L86A2 +L8CP +L8ers +L8rT8r +LADFS +LAMAFAO +LAMARJACKS0N +LASBE +LAUFY +LAZY88 +LB9 +LBS M +LBaccer +LC33 +LCpl +LE0 MESSI +LE54SON +LEARNINGTHIS +LEGOSl +LEN0 +LENZ +LET ME COOK +LEWlS +LF Content +LFG 69 +LFGrills +LG 8anter +LGBTQLMNOP +LIL BLESSED +LIL PRINCE +LILKHALAMARI +LIMEWORLD +LIQUICITY +LITEIT +LITHITS +LJ 8 +LJAP +LJPalmer +LKIT +LL Trigger +LLAMA_ears93 +LLIRSHSLSIEi +LLY Duramax +LLeffe +LLich +LLol +LMAO LOL KEK +LMAOImDying +LMFAO IRL +LMFAOIRL +LMNOP3 +LMParrot +LN41 +LOADED_AR +LOGAN109 +LOGlC +LOH3 +LOL BMW +LOL MAD +LOOP1456 +LOOSECOOCHlE +LOSTinGAMES +LOUlSlANA +LOWIQXD +LP Smokie +LRG +LRGD +LRichyy +LS1 +LS3D +LSD-25 +LSDDS +LSDe +LSDeezNutttz +LSDonny +LSDreamy +LSxD +LTUD3stroy3r +LTapperz +LUBRICAT0R +LUKA DONClC +LUR3ME +LURED BY ROT +LUTlN +LVN iZN0 +LWE +LXFY +LYAM femboy +La Benezra +La Bollita +La Brebis +La Croix +La Fiesta031 +La Frontera +La Moo +La Porta +La Sopa +La7itude +LaCroisssant +LaFroob +LaLegende +LaMachCaron +LaMarii +LaPichula +LaRS 07 +LaYdlN +Laaban +Laadvermogen +Laady +Laagvliet +Laaki +Labas Utak +LabbatBlue +LabbattSplat +Labbis +Labor +Labstev +Labundo +LacDeaths +LacedKoolAid +Lacedonian +Laceinyoface +Lachosocko +LachysMain +LacinorI +Lack +Lacking +Lacking IQ +Lacoline +Lacraio +Lacrymosa +Lactosite +LacusClyne +Lad J +Ladbrook +Laderstall +Ladme +Ladrian +Lads +Lady +Lady Calais1 +Lady Chompa +Lady Devil +Lady Porky +Lady Storms +Lady2022 +LadyBuck +LadyGagaTbh +LadyJan +LadyJan BTW +LadyJessicaL +LadyMidn1ght +LadyOfCyprus +LadyOfMagick +LadyPidge +LadySaurus94 +LadyStarlite +LadyStorm83 +LadyVamperic +Ladydoll +Laedzter +Laeretes +Laethia2 +Laetor +Laf +Laffam +Laffy +Laffy Taffy +Lafondaa +Laftonn +Lag out +LagArtist +LageLanden +Lagerhaus +Lageri +Lagg +Laggbeer +Laggro +Laggy Brain +Laggy Clicks +Laglet +Lago +Lagodzacy +Lagomancer +Lagoon +Lagrange +Lagscape +Lagu +Lagwagon +Lah Di Dah +Laharl +Lahn +Laid +Laid bare +Laika Wolf +LaiskaJake +Laiskiainen4 +Laitoin +Laitti +Laitue +Lajer +Lajfi +Lake +Lake Show +Lake Valor +LakeMonYew +Laker +Lakeshire +Lakka +Lakonic +Laksa +Laku +Lakuni +Lakupiippu +Lala +Lalochazia +Lalundi +Lam lul +Lam_12 +Lama +Lamanent +Lamb1237 +Lambretta62 +Lambs +Lambzilla +Lame +LamePuttE10 +Lamented +Lamfear +Lamh +Lamie +Lamiia +Lammen +Lammy +Lamns +Lamp +Lamp Burner +Lamp master +Lampepit +Lampyy +Lampzki +Lamshnarf +LanJiaoDuaKi +Lana +LanaLuna +LanceDaPantz +Lanco +Lancy +Land +Lander +Landeskoging +Landlord +Landofzoa +Landucey19 +Landyll +Laneeta +Lanell Latta +Lanesstee +Lang Chang +LangeNieWies +Langeboy +Langecries +Langner +Langosman +Langscape +Langtu102 +Langutan +Langzzy +Lanier +LankFrampard +LankaKekw +Lanky +Lanky Josh +Lankyfeed +Lann +Lanny Pan +Lanoue +Lanpzki +Lanrico +LantadymeRey +Lantern Snow +Lanx +Lanzlol +Laogai +Laopac +Laowens43920 +Lap0tai +Lape +Laphloredos +Lapsa +Lapsapp +Lapsivesi +Lapua +Lapuz +Lapy +LaquishaBaby +Lar0i +Laraelias +Larcadum +Larcenex +Lard Jaysus +Lare +Lare240 +Larecia +Larecio +Larenz Tate +Large +Large Chompy +Large D +Large Npc +Large Tasty +Large Toads +LargeExpLamp +LargeGrandma +LargeZock +Largelad2 +Largeprune +Larie +Larissa +LarksTongues +Larkypoo +Larotux +Larrey +Larry +Larry 0G +LarryB +LarryIsHere +Larrys +Larrys btw +Larryz +Lars Ohly +Larser +Larsinosrs +Larsjns +Larso +Lartsi +Laruka +LasBoi +Lascooby +LaserLad +LaserSchlong +Laserati +Lashi +Lasjstts +Laska +Laska Siara +Laski +Laskii +Lasne +LasoliLeiffi +LassT +Last +Last Bison +Last King +Last N1te +Last Stages +Last Texan +LastAttempt +LastBoss +LastHours +LastMark +LastRecalI +LastTexan +LastWookiee +Lastinis +Lastkaiii +Latanoprost +Late +LateKnight +LateOwl +Lateksiuljas +Latelaturi +Latero123 +Latias +Latins +Latissimus +Latitude +Latompachy +Laturaivo +Lau396 +LauQT +Laudine +Laufeyson965 +LaughTale XD +Laughed +Laukage +Laukie +Laukki1 +Laundry +Laundry Room +LaupieLaupie +Laur +Laur ex core +Laura +Laura J +Laura uwu +Laurat J +Lauren +Laurentina +Lautanen +Lauw +LauweEgberts +Lav x +Lava +Lava Buster +Lava rune +LavaFountain +LavaKitty +Lavadude42 +Lavafrost +Lavagirl420 +Lavak +Lavak Bob +Lavanis +Lavasat +LavendrGoons +Lavigne +Lavina26 +Lavios +Laviuthen +Lavvv +LawOfBirds +Lawesy +Lawfox +Lawhrer +LawlAsYouDie +Lawlie +Lawliet +Lawlimon +Lawlygagging +Lawn +LawnChair48 +Lawncat +Lawnmower73 +Lawre nce +Lawsilk +Lawson +Lawyer JD +LawyerGirl24 +Lax_315 +Laxar +Laxx +Lay +LayDead +Layden +Laydwnandr0t +Laydyn +Layes +Layes X +Layezy +Laylaa +Lays +Layzi +Laz GIM +Laz Lo Mein +Laz2510 +Laza Ferro +Lazer +LazerVizion +LazerWork +Lazgo +Laziest +Lazikiel +LazloDaLlama +Lazy +Lazy Fare +Lazy Jazz +Lazy Lump +Lazy Matt +Lazy Mauler +Lazy Moo +Lazy Shell +Lazy Soul +Lazy Stona +Lazy XP +LazyB0y +LazyBoneZone +LazyDevon +LazyFarmer +LazyOwner +LazyThom +LazyTurtleRS +Lazydrink +Lazyie_KiD +Lazysmokes +LazyyySloth +Lblacc +Lbuzz +Lck +Lda237 +Lder +Lds +Le Bibu +Le Biff +Le Big Sad +Le Catptain +Le Doda +Le Foole +Le Gio +Le H0NK +Le Jeffeh +Le Peanut +Le Petit BH +Le Pogo +Le Reject +Le Stu +Le Sus +Le Tom +Le von +Le4f +LeAUD +LeB0ng James +LeBlownGames +LeBoobie +LeBrianJames +LeDamos +LeDerpski +LeIronJims +LeKinguin +LeLuuk +LeMontBlanc +LeMoonMan +LeMoopey +LeNnEeX +LePeach +LeVarrock +Lead +Leader9922 +Leaderless +Leadfeathers +Leadley +Leads Dead +Leaf +Leaf 7 +Leaf Parker +Leaf998 +LeafStoneDab +Leafffy +Leafpool +Leafyshade +Leaga +League Brain +Leak +LeakedDMs +Leaks +Lean +LeanFavaBean +Leanlce44 +LearnCatMeow +Learningosrs +Learti +Lease0fLife +Leather Top +LeatherJan +LeatherRat +Leatherr +Leaux Key +Leavepigrun +Leb Crotch +Leb Man +Lebanesee +Lebennn +Lebor +Lebowski2033 +Lebrons +Lebusoft +Lebzima +LeccaJr +Leckie12 +Leclerc 2024 +Lectaminol +Lectosh +Lectrix +Led2000 +LedXia +Ledgendairy +Ledning +Ledu +Lee +Lee Ratt +LeeFelix +LeeGavGav +LeeHen +LeeV_V +Leecherboy +Leechy2399 +LeedsUnited +Leegotalo +Leeleebug210 +Leemer +Leemi +Leemo +Leer0y +Leerjet +Leeroyy +Leers OSRS +Leeshore +LeesusChrist +Leet +Leet Blues +Leet Bug +Leetroopa +Leeuwarden +Leevar +Leezy +Lefonzeee +Left gf 4 Xp +Left inPeace +LeftFistt +LeftHerFor07 +LeftHerForRs +LeftTwix +Leftist +Leftwich22 +Lefty +Lefty-x +LeftyWarrior +Leftytexan +Leg Day 99 +Legacy-Blade +LegacyOfErik +LegalCounsel +Legalism +Legally +Legally Dumb +LegallyAfk +Lege +Legend +Legend 0007 +LegendHarold +LegendKingz +LegendOfShao +LegendSuz +LegendaryDTM +LegendaryFoe +LegendaryLVP +LegendaryMe +LegendaryRS +LegendarySte +LegendaryZ0 +Legenddiary +Legenddreams +Legendelek +Legendish +Legends Epic +Legendsam7 +Legened248 +Legggggooooo +Leggo +Leggy +Leggz +Legikt +Legio +Legion2410 +Legionals +Legislatore +Legit +Legit Ape +LegitGarbage +LegitSamuel +Legitidrown +Lego Brick +Lego Fisher +Lego Mania X +LegoMyBob +Legolas +Legolas I +Legolic +Legoliker999 +Legosas11 +Legosaur +Leguminati +Leha +Lehawek +Lehmo +Lehnert +Lehoir +Leid +Leider +Leidmavo +Leif +LeifBestLord +Leiff +Leigh +Leilin +Leimstiift +Leion +Leist1nas +Leistus +Leito +Leitwolf +Leivermorale +Leivonnaiset +Leiza +Lejj BTW +Lejoon +Leka xo +Lekira97 +LekkerMoeder +Lekkeri +Lekray +Leky +LelSickMeme +Lelalt +Lelbow +Leldorin +Leldra +Lell +Lelott +LelouchV +Lelysia +Lemako +Lemillion141 +Lemiy +Lemke +Lemmelleni +Lemmy +LemmyThePerv +Lemon +Lemon5000123 +Lemon9000000 +LemonTart +Lemonade max +Lemonguin +Lemonmooffin +Lemonowo +Lemonrider +Lemony Earl +Lemonz +Lemosgomes +Lemphys +Lempsu +Lemurcow +Lemuria88 +Lemursnore +Lendtable +Lenegis +Lenel Devel +Lengzz +Leni Epiza +Lenience3 +Lenify +Lenlami +Lenn375 +Lennie +Lenning +Lenny Euler +LennyPro +Lenovel +Lenreys +Lenses +Lentiano1 +Lentil +LenvisCZE +Lenya +Leo Gagner +Leo Messi +Leo The Fish +Leo12_1993 +Leo2 +Leo96 +Leodero +Leoma +Leonatwo +Leonbozz +LeonidasIV +LeonidasThor +LeonidasXCIV +Leonl +Leontje +Leorio +Lepek38 +Lepkilla +Lepra +Leprechau +Leprincias +Lerch +Lernaean +LeroyDanknz +Leroyvdk +Lerzbot +LesGetIt +Lesbean +Lesen +Leshrac +LesleySnipez +Less +LessIsMore +Lessar +Lesser Gods +Lessking +Lestamsakul +Lestersaurus +Lesva +Let Us Dream +LetBrettBang +LetJimCook +Lethal +Lethal Blade +LethalClick +LethalMortal +Lethally +Letharil +Lethwei +Letits now +LetrahL +Lets +Lets Blaze +Lets Boss +Lets Glide +Lets Plop OK +Lets Ride +Lets See +Lets Toke +Lets Ziggy +Lets pep +LetsGetSmity +LetsGetem +LetsRouQ +LetsgoDaddy +Letsjjj +Letspoint +Lettersloth +LettuceLegs +LettuceLime +LettuceNut +Lettuce_8 +Lettulainen +Leturpentinr +Letz +Leukaremmi +LeukemiaLord +Levante Frog +Level +Level Denel +Levelations +Leveldegree +Levi +Levi Squad +Levi lmao +Leviate +Levibeelevi +Leviud +Levven +Levyiah +Lew Sanus +Lew sid +Lewd Queen +LewdTouchMe +Lewdberrypie +Lewey +Lewf +Lewfu +Lewhh +Lewir +Lewis +LewisMcLaren +Lewis_y +Lewism22 +Lewison +Lewiss +Lewithetui +Lewu +Lewwiis +LexaSteel +Lexatrax +Lexay +Lexdegekte +Lexer +Lexington73 +Lexkai +Lexxi +Lexy +Leyon +Leyr +Leysim +Leyton +Leyzen +Lezio7 +Lezley +Lfts +Lhk +Li am +LiI Tii Lii +LiT Clutch +LiT on Dabs +LiTxEXODlAx +Liam McPoyl +Liam1994 +Liam6780 +LiamLate +LiamLollypop +Liamas +Liberate +Liberaxa +Liberty +Liberty Cap +Libolik +Libracorn +Librain +LichKiing +LichOneeChan +Licharus +Licht +LichterLo +Lichtert +Licitness +Lick +Lick My Wyrm +Lick Time +LickAhrim +LickMcFicks +Lickeris +Lickilicky +Lickumss +LidawgMcChad +Lidless +Lidlman +Lie +Lie4it +Liebzer +Lies of S +Liet Katsu +Lietuviskass +Lietuvisz4 +Lieve +Lieven +Lif3 +Lifal +Life +Life Road +LifeInsAgent +LifeIsBaked +LifeIsRockie +Lifeform +Lifehunt +Lifeisnow13 +Lifeliners +Lifelulz +Lifes +Lifes12Rules +Lifesteal +Lifestyle +Lifewaste +Lifezajoke +Lifticus +Lifting Fe +Liggen +Lighning +Light +Light Ace +Light Shell +Light age II +Light1324 +LightAura +LightB0ne +LightRigger +Lightarrg255 +Lightaxo +Lighten +LightenUp +Lighter +Lighterfalz +Lightfister +Lightg0d +Lighthead45 +Lightlord440 +Lightning MF +Lightningess +Lightqt +Lightstoria +Lightww +Ligma Balzaq +LigmaMufin +Ligt +Lihatanko +Lihtnenolife +Lihtsurelik +Lihu +Liiga-Ari +LiikeAGlove +Liite +Liitokissa +Lijk +Lik me knie +LikMijnRaid +Lika C +Likalatopus +Likark +Like +Like Saint +LikeABrother +LikeAGloveee +LikeCinnamon +LikeToetally +Liketocombat +Liko +Likrot +Lil Callisto +Lil Dickyy +Lil Donut +Lil Dor +Lil Doss +Lil Eso +Lil Fika +Lil Garbo +Lil Hogg +Lil Knight +Lil Koda +Lil Lilyxo +Lil Lotus +Lil MCM4A1 +Lil Moe +Lil NllLO22 +Lil Rat Mann +Lil Roli +Lil Shay +Lil Stoma +Lil Tragic +Lil Weeezy +Lil Woowoo +Lil Yeeter +Lil Yungen +Lil Zeusy +Lil Ziik +Lil Zimp +Lil parasite +LilBirb +LilBlueMew +LilBobbi +LilFaulk +LilGBigThing +LilGay btw +LilHorny +LilMissSlays +LilNubbins +LilPeepBoi +LilSeany +LilSquidgy +LilSteamBoat +LilStonks +LilSuzieVert +LilUziBlyat +LilWitness +LilYungChitn +Lila +Lilac Devil +Lilangrydude +Lilbobsters +Lilchris +Lildirt +Lildischarge +Liles +Lilhotshotv2 +Lilinss +Lilith +Lillia n +Lillie +Lillyz +Lilmoose99 +Lilnenedemon +Lilqtforeva +Lilsauce72 +Lilsutts +Lily +Lily Mayy +Lilyalatea +LilyaxD +Lilypily0 +Lilysaurs +Limb +Lime Light +Lime Season +Limed +Limeguy21 +Limewire +Limit Form +Limited Room +Limiwinkz +Limiy +Limmert +Limmy +Limo +Limp +Limp Lime +Limpsioo +Limpwurt +Limyt +Linalool +LincolnButt +Lind say +Linda +Linda Lou +Lindegaard +Lindewyn +Lindsey +Linearr +LinedFury +Linelis99 +Linen +Linen Cry +Linerz +Linewa +Liney +Lingwood +Linh +Linhson +Link +Link Adam +Link Click +Link Noises +Link Tribute +LinkKing +LinkTheIron +LinkedList +Linkedln +Linkin Boy33 +Linkinaz +Linkmoon +Linkseratten +Linkv21 +Linnara +Linsey +Linsunt +Lintell-lad5 +LinusEkedahl +Linxis +Lion +Lion Gin +Lion-021 +Lion0fZion +Lionbatdog +Lioncheart +Lionclaw +Lionelliee +Lionheart +Lionheart Xl +Lionhrt +Lionyxia +Lioui +LipShits +Lipalow +Lipperr +Lippy Jimmy +Liqu +Liquar +Liquicity46 +Liquid +Liquid Apple +Liquid CSGO +Liquid GZA +Liquid Mire +Liquid Nexus +Liquid Reign +Liquid8 +LiquidRmt +LiquidTheory +LiquidTrails +Liquidat0r +Liquidated +LiquidatorRS +Liquidwood0 +Liquified +Liquir +LiquorGrain +Liqwid +Liridon +Lirrix +Lishenna +Lisica +Lisle +Liso +Lissino +Lissoms +Listeffect +Listen2me +ListenMorty +Listerine_TC +Listics +Listifyy +Lisuna +Lit Dawg +Lit Guy +Litas +LiteForge +Litefooted +Litelii +Litem +Liten +LiteralCow +Literic +Lites Evil +Litey +Liteyr +Lithassa +Lithuano +Littens +LittieTover +LittjeterRS +Little +Little Allie +Little Flirt +Little Jaxon +Little Knob +Little Sloth +Little Snor +Little Ticks +Little Twig +Little meow +LittleGhosty +LittleIron +LittleNudger +LittleTrev8 +LittleWillis +LittleZorro +Littlebluefe +Littleblueju +Littlechirru +Littlefarms1 +Littlefire01 +Littleguyz +Littletickle +Litto +LittyNoCap +Litvintroll +Lium +Liuo +Liutkemenas +Livahpewl +Livand +Live +Live Jaked +Live Moose +Live2Win +Live4thefigh +LiveItRight +LiveLoveAsap +LiveYourLife +Livedasniper +Livepan +Liverpewle +Livey +LividPharm +Living +Living Life +Living Lust +Livingenemy +Liviu230 +Livvii +LivyLo +Liwyn +Liyum +Lizard Siege +Lizily +Lizinginis +Ljb +Ljudmila +Ljuu +Lkarch +Lkky +Lkn +Lkoi +Lkue +LlHAPIIRAKKA +LlLY ALLEN +LlLYUFFIE88 +LlMEWlRE +LlNT +LlON +LlSA ANN FAN +LlTEWORK +LlTT +Ll_lK3 +Lla234 +Llama +Llama BTW +Llama Pharm +LlamaDawg +LlamaMcfenis +Lleucu Ann +Llirik +Lloydyy +Lluuk1 +Llychlynwr +Lmao +Lmaz +Lmfao +Lmlxlk +Lmmortai 07 +Lmsjfjksdnhb +Lmurs +Lncln +Lng +Lo Kii +Lo My God +Lo cation +Lo07er +Lo0pyy +LoGiiKBah +LoPintos +LoadMySkeng +Loaded +Loadizzle +Loadstar +LoafOCelery +Loathed Kmd +Loathing +Lobb Dad +Lobby +Lobby Two +Lobo Blanco +Lobo Sonora +LoboStark1 +Lobot96 +Lobotomizer +Lobstars +Lobster12 +Lobstero +Local +Local FEmale +Local Idiot +LocalHero7 +LocalJoint +Locale +Lochi +LockDownLife +Lockdown v2 +Locko +Lockpicks +Lockski +Locksnap +Lockssley +LocoDoritos +LocoHamsterz +Locococonut +Locothegenie +Locrian +Locton +Loda +Lodarion +Loders +Lodestar +Lodestones +Lodgehunter +Lodiedoo +Loebas +Loeffen +Loez +LofaBred +Lofi +Log62 +LogHog8 +LogHunterKaz +Logan +Logan2x +Loganator34 +LogansPrayer +Logavano +LogiTekton +Logia +LogicTerror +Logical God +Login +Logitech +Logitekton +Logless +Logos13 +LogsKnog +Lohan +Lohkey +Lohruken +Lohwi +Loikoi +Loikoi Lee +LoisGriffin1 +LokieDokie +Lokolow +Lokos +Lokrand +Lokur +Lol Ur Dead +Lol466 +Loladactylll +Loldg +Lolek +Loli Cox +Loli Neko +Loli Pantsuu +Loli-Remain +LoliChan +LoliElie +LoliStrangla +Lolicons +Loligagging +Lolipoparty +Lolitsleeroy +Lolmanever +Lolmc +Lolopipop +Lolwierdo +Lolwuts +LomLy +Lombachs +Lombardi +Lomborghini +Lome +Lomobuu +Lompardo +Lon3y +Lonan +Lonan Arikos +Lone +Lone Gym Rat +Lone Lee Axi +Lone Pop +Lone Requiem +Lone runkero +LoneCorp +LoneMage +LoneStarWit +Loneful +Lonehenge922 +Lonely +Lonely Eevee +Lonely Neo +Lonely Norms +Lonely Ride +Lonely Salty +Lonely Slave +Lonely Table +Lonely Tugs +LonelyLight +LonelyOnT0p +LonelyRS +LonelyTugs +Lonelyy +LonerSushi +LonesomeSoep +Lonewolf117 +Long +Long 4skin +Long Demon +Long Ol Dong +LongBoneee +LongRodGod +LongSnapper +Longbow +Longest Head +Longie +Longjohnz +Longmeatlog +Longnech +Longo Doggo +Longstaf +Longsword950 +Longview +Longwave +LongySlongy +Lonjick +Lonksu +Lonz +Loo p +LoofiePoofie +Loofoo +Loogs +Loogy +Look +Look out bro +Looked +Lookin +Lookingman +Lookn4Puzzy +Lookout +Lookup +Loon +Loon Master +Loonetick jr +Looney278 +Loongstickyy +Loonlette +Loony +Loony RS +LoonyLunar +Loonykilla +Loonyluke5 +Looolo +LoopGoon +LoopSwoop +Loophole336 +LoopieFish +Loopy586 +Loose +LooseAnos +LooseLesley +LoosebuLdge +Loosh +Loot Chemist +Loot Party +Lootcifer +Looted +Lootedyou2 +Lootorz +Lootrich +Lootsharing +Lootsi +Lootski +Loox +Lopmkinjubhy +Loppy Killer +Loquwsea321 +Lord +Lord Amonite +Lord Bees +Lord Buud +Lord Bv +Lord Caldlow +Lord Conte +Lord Cryer +Lord Cypher +Lord Devil +Lord Doofy +Lord Elfen3 +Lord Extropy +Lord Grefven +Lord Grim +Lord Grofyth +Lord Guam +Lord Hents +Lord Jebbe +Lord Joona2 +Lord Jostyh +Lord Keithus +Lord Kratos +Lord Loss +Lord M0RG0TH +Lord Mantra +Lord Masonic +Lord Mjosh +Lord Of Cows +Lord Pengu1n +Lord Pillow +Lord Richie +Lord Runes +Lord Shayne +Lord Tarkus +Lord Valzin +Lord Vioarr +Lord Vishnu +Lord Xeth +Lord Yaksha +Lord Zq +Lord iFlex +Lord kuro +Lord polak +LordArtonius +LordAusticus +LordBaphomet +LordCoffee2k +LordCorreia +LordDanko +LordDaxel +LordEpic69 +LordFarquxd +LordFoxy +LordGuthanPK +LordJRazE +LordJuba +LordLambo91 +LordMullett +LordNorden +LordOfHarems +LordOfOtakus +LordPh1L +LordPolgoth +LordQuinker +LordScoobert +LordShrubber +LordSloppy +LordThyas +LordUSA +LordYawgmoth +LordZahard +Lordalbert0 +Lorddraconal +Lorde +Lordjoeman +Lordkaes +Lordstails +Lordtwinky +Lordy Flame +Lordy608 +Lordza +Loredon +Lorehold +Loreland +Lorencia +Lorenz +Lorenzoh sr +Lorenzokazoo +Lorithean +Lorkaa +Lorki +LorqueldIM +Lorre46 +Lorry +LortJob +Lorttomies99 +Lorvikatari +Lorwic +LosAngeles +Lose +Losel +LoserKid +Loshambo +LosinAllHope +Losing +Losing Fat +LosingXP +Loss1525 +Lost +Lost Angel +Lost Baby +Lost Baggage +Lost Logan +Lost My Baby +Lost My Sock +Lost Oliver +Lost On You +Lost Roomba +Lost Snail +Lost Tadpole +Lost Weed +LostBank +LostBankKey +LostChad +LostCloss +LostDude28 +LostHalls +LostJelyFish +LostMoon +LostOcean +LostOnThePCT +LostSauce +LostStatus +LostVorki +LostandFound +Lostdog03 +LostlSoul +Lostpetrock +Lostplzhelp +Lostrelic93 +Losty99 +Lot of Beans +Lothariou +Lotilyx +Lotion +Lots of Eggs +Lotsa Regret +LotsaOSRS +LottaPotAgo +Lotto +Lotu15 +Lotus bless +LotusKid +Lotwik +Lou Le Dur +Lou Red Wood +Lou Sputho1e +Lou Surr +LouBug +LouSass +Louezzi +Loug +Lougle +LouiVui +Louie Bags +LouieMurphy +Louiec3 +Louiseyy +Lounckie +Loupak +Lousy Drunk +LouvicDank +Louzy +Lov ed +Love +Love Caley +Love M Poker +Love Roman +Love Taylor +Love Yourz +Love me +LoveMyAnzaa +LoveThat +Loveable +Lovelili +Lovely +Lovely Clawz +Lovely Cola +Lovepoot +Loverboy +Loveskillin +Lovexdragon +Lovey +Loveyan823 +Low Alched +Low Chief +LowBaller +LowKeyPickle +LowLifes +LowPines +LowPower +LowRunEnergy +Lowanse +Lowballz +Lowercase +Lowery +Lowfield19 +LowkeyBallin +Lowlander +Lowlife121 +Lowlux +Lowner +Lowrey73 +Lowstar1 +Lowtempterps +Lowy +LoxoJ +Loxtos +Loyal2pvm +Loyalcaptain +Loyd Nichols +Loze +Lpfan +Lrauq +Lrian +Lric Eotter +Lron +Lronic +Ls4 +LsummerC +Lsv +Lt Burgers +Lt Golpar II +Lt Mantas +Lt Purekarys +Lt-Iron-Lt6 +LtCastiel +LtJan +LtRemigijus +Lt_Torch +Ltfreggin +Ltk Iron +Ltman42 +Ltmf +Ltufighterlt +Lu Diabla +Lu be +Lu0nto +LuauKing +Lub +Lub3edUp +Lubbz +Lubed +LubinLen +Lubos +Lubosek +Luc4rio +LucSynthesis +Luca +Lucaemar +LucarioLVL X +Lucas +Lucas Solo +Lucas1192 +Lucasmelo11 +Luccaa +Lucho +Luchtloper +Luciah +Lucid +Lucid Cynic +Lucid Dream +Lucid Josh +Lucid Meme +Lucid Truths +LucidFeels +LucidPie +Lucidcr +Lucidfever +LucidityX +Lucie SkyDia +Lucifenrir +Lucifer v2 +Lucifer06 +Lucifer4Real +Lucifer_link +Luciifer +Lucil +Lucina +Lucipur +Lucivert +Luck +Luck Lost +Luck Voltla +LuckRunsAlt +Luckario +Luckd0ut +Luckeh +Lucker +LuckieStein +Luckless +Luckpvm +Luckscaper +Lucky +Lucky Arian +Lucky B Boss +Lucky Bambam +Lucky Baws +Lucky Cash +Lucky Chance +Lucky Clover +Lucky Clown +Lucky Duck +Lucky Greg +Lucky Kev +Lucky Link +Lucky Lombax +Lucky Lukey +Lucky Mofo +Lucky Rabbit +Lucky Sofa +Lucky Yoru +Lucky skrue +Lucky when +LuckyAce +LuckyDog +LuckyDog x +LuckyEmerald +LuckyKroketa +LuckyLackey +LuckyMatch +LuckyNrSeven +LuckyVic +Luckybamboo1 +Luckynuts +Luckyxx +LucoUK +Lucyfer22 +Luczzs +Lud a +Luda-Dan +Luderan +Ludo +Ludo Sand3rs +Ludomo +Lueis +Lueke +LuffyAce +LuffyDMonkey +Lufidius +Lufue +Lug RS +Lugal Ki En +LugiaWaifu +Luglys +Lugs +Luider +Luigihbk +Luis +Luis Anico +Luis Antonio +Luis Dk +LuisFarm +Luis_Vzla +Luka +LukaBrasi +Lukas +LukasFlux +Lukaz +Luke +Luke S +Luke3 +LukeOS +Lukeee +LukefonFabre +Lukeh +Lukeicth +Lukesfish +LuketheDM +Lukey294 +LukeyUK +Lukezz +LukiOne +Lukiekuipie +Lukio W +Lukiss +Lukoo911 +Lukse +Lukytisz +Lulani 13 +Lulla +Lullie +LuluTheCat +Luluca +Lulucifer +Lumber Yak +LumberStevo +Lumbidge +Lumbo +Lumby +LumbyCalled +LumbyCastle +Lumbys Waits +Lumiaris +Lumifrost +Lumimies +Luminatti +Lumm1475 +Lummer +Lumo +LumpiaFan69 +Lumpqua +LumpsMcgooey +Luna +Luna Koneko +Luna Lucero +Luna Mexi +Lunacy +Lunaec +Lunamarie +Lunar +Lunar Haze +Lunar Lotus +Lunar Tear +Lunar Tones +Lunar Ursa +LunarDemon99 +LunarEquinox +LunarSC2 +LunarTheCat +LunarTigerr +Lunarann +Lunarcrow614 +Lunardini +Lunarism +Lunarmoat638 +Lunate +Lunati +Lunaticmo1 +Lunatric +Lunaverse +Lunch +LunchboxLLC +Lunchtime007 +Lund +LundXCV +Lundh +Luneasa +LuneyTunez +LungTied +Luni +Luniaxis +Lunie +Lunier +Lunis +Lunizzzz +Lunytic +Luonteri +Luonto +Lupah +Luper +Lupi +Lupo +Lupuloid +Lure2G +Lurjus +LurkinTurd +Luru +Lush Vibes +Lusitropy +Luskidoo +Lussen1 +Lustwaffle +Lusu +LusyTheGoat +Lutha +Luthien +Luthien T2 +Luthors +Luthstorm +Lutinrouge +Luucy +Luud +Luukie +Luuloterve +Luuseri +Luuuseri +Luuuuna +Luuwana +Luv2spuj +Luver Focker +Luvholic +Luviii +Luwucy +Lux Please +Lux211 +Lux7thSaga +Luxatio +Luxeo +Luxilie +Luxire +Luxoul +Luxumine +Luxury +Luya +Luzu +Lv ranger +Lv 5 Psyduck +Lv Camo +Lv100 +Lv100 Raichu +Lv5 Treecko +LvI3stak3 +Lv_1_Mew +Lvcretivs +Lvl 1 +Lvl 3 Nub20 +Lvl 99 Goon +Lvl100cheese +Lvl30Ditto +Lvl99 +Lvl99Docking +LvlUpUrself +Lvls Up +Lvqquvs +Lwy +Lx1I +Lxbe +Lxfleur +Lxnes +Lycix +Lycoe +Lycstoned +Lyct +LydeZGrod +Lyderis +Lydia +Lydia Kenney +Lydmix +Lyfe Tyme +Lyin +Lyin Eyes +Lyke625 +Lyks +Lymaks +Lymez +LynX ZrLeX +Lyna +Lynamet +Lynching Leo +Lyngo +Lyni +Lynics +Lynx +Lynx Jitan +Lynx Tiger +Lynx Titan +LynxTitan +Lynxes +Lynxy +LyraLyraLyra +Lyrad002 +Lyrich +Lyricidal +Lyrilusc +Lyron +Lysandra +Lysdexic4986 +Lyse +Lysmann +Lyyli PL +Lyzu +Lzin +Lzs +M A G 3 +M 1 KE +M 3 3 P +M 4 T R I X +M 8 A 1 +M A D O X +M A D Storm +M A T E J +M A X O U T +M A X PAYNE +M B Z +M E H I S +M E L D O +M E T R O +M E X I +M I K B A R +M I T H O X +M I U +M I Z Z O U +M INDGAME +M Itty +M K J +M O B I L 3 +M O C 0 +M O C H +M O ID O K +M R NaCl +M Super Buu +M T C +M U D K l P +M X G P +M a V 3 Rick +M a d Shrumn +M a k a i +M age +M aikel +M ak0 +M ammoth +M ana +M ankDemes +M anu +M aples +M arcel +M arquim +M artin +M ask +M athis +M axou +M azzz +M c +M elz +M enzy +M ga +M gh +M i t c h y +M i y a +M ikasa +M ike +M imik +M int +M itchel +M ittens +M l Q Q +M merz poL9 +M o C e +M o r t e n +M oist +M onkfish +M orytania +M the Maxed +M ugger +M ulas +M urphy 2 +M usashi +M-theory +M00CHIE +M00SE M00SE +M01 +M0IST +M0IST B0X +M0LE +M0NALISA +M0NEYM1TCH3 +M0NST3R1PP3R +M0ON +M0ONCAKES +M0R TEN +M0RG0TH +M0RGE +M0SS3Y +M0ST D0PE +M0hannad +M0ist +M0ist Midget +M0ney Swag +M0nk3y DLufy +M0nke y +M0nkey15 +M0nsterTuk +M0obs +M0resheth +M0rningstr +M0use +M11CK +M11ka +M1911A1 +M1GU +M1NG3_GOO +M1TTLE +M1ch +M1gos +M1ke50 +M1ksu +M1nd Master +M1ntberry C +M1ss Di0r +M1stak3nly +M26 +M3 L +M30W +M30z +M3GAD0UCH3 +M3L10DA5 +M3MEL0RXD +M3MoRY +M3X1CO +M3XICO +M3ch4nics +M3ll3 +M3lllll +M3lviin +M3ntal +M3rking +M3ry +M3t4l1n1S +M40A +M4D399 +M4g3 +M4g4z +M4gnus666 +M4k3d0 +M4tte +M4xt0R +M5 +M52 +M523 +M6 Mill +M6N +M7J +M7TT +M855A1 +M8NoFreebies +M8TT +MA N E +MAAAAK +MAAGES +MACKOGNEUR +MADLADz +MADRNGJACK +MAESTR0FRESH +MAFKINCHAMP +MAGA +MAGA1292011 +MAGE2W1N +MAGETOW +MAJ0NEZAS +MANNNERHACK +MANSlKKA +MANT4S +MARCOPOLO +MARLB0RO +MARMlTAO +MAS0N +MASKED +MASSGAINER32 +MASTER DREAM +MASTER J0KER +MATUTVlTTUUN +MAURERA79 +MAUROPICOTTO +MAX3D +MAXABILITY +MAXED PINOY +MAXXEDDADDY +MAX_HER0X +MAXlME +MAlNEVENT +MAlNTENANCE +MC Cheep +MC catheter +MCBURNOUT +MCHammered +MCKenny91 +MCSIZZLE +MCmattt +MD7 +MD96 +MDE Presents +MDPS +MDaher +MDucks +MEAT G0D +MEAT HEAD36 +MEGATRON +MEK4KK4KK4KK +MELAN00MA +MELT +METM0NKEY +METR0lD +METS0 +MEV4NS +MF DC +MF MORTEN +MF SofaKing +MF TEE +MFE +MFKU +MFLI +MFSTEVE +MG5 +MGFS +MGKRevs +MGM WAY +MGreengrass +MH Therapist +MHA C +MHBC +MHS +MIDAs +MILFmauler +MILSHAKE +MINH +MISOGl +MISSYGAMlNG +MIST +MITCHY +MIX0R +MJ23 +MJKaboose2 +MJT +MK-HARDSTYLE +MK6R +MKAM +MLB +MLTEEZY +MLaidman +MMMahogany +MMORPGenius +MMTera +MMitchh +MMtheMachine +MOABDADDY +MOMHUNTER666 +MON5TER +MOODSWlNGS +MOOSEM3AT +MOTM +MP17 +MP9 +MPB +MR JOHN WlCK +MR LETHAL2u +MR REET +MR TMR +MR UDZ +MR556A1 +MRButter +MRC Tugboat +MRGAMEZ +MRHD +MRLARGE +MRM +MRPlZZAPRIZE +MRWHlTE +MR_MAITO +MSPaint64 +MSceneFF +MSpacePotato +MStarkz +MTBMB +MTPETE +MTV CRlBS +MTXP +MUISSS911 +MULHERndaEXP +MUMM0 +MURMELl +MUSK +MUSK0KA +MUSUMUMM +MUZAMMIL +MV Flow +MV Welshy +MVIII +MVKirby +MVP HERO +MVP Mahomes +MVRDA +MVTIASD +MWwarzone +MY L U N A +MYRSKYVIITTA +MYTHICROYXLE +M_Sariol +Ma Band +Ma Dood +Ma Titi +Ma t t h e w +Ma5onx +Ma7e +MaCoMb +MaHeelsHurt +MaJeShTic +MaQtPie +MaX662 +MaXam00se +MaXeDSani +MaXx0wnage +Maacc +Maake88 +Maanman +Maasegyr +Maax2 +Maaxiking +Maazako +Mabbbs +Mabbs +Mabel +MableLake +Maboe +Mac Diver +Mac Donald +Mac Garfield +MacDuff +MacFredrik +MacFredrique +MacMillers +MacMoblins +MacRae +MacSandwich +MacTheRipper +Maca +MacaFazoL +Macabre +Macaron +Macaroni 73 +Macaronni5 +MaccaM +Maccaroni +Macduffe +Mace Windu +Macedo +Mach Sigma +MachV2 +Machado +Machfredy +Machine Girl +MachoTimo +Machtig +Machtige +Machtigeman +Machtigemeid +Machto +Mack +Mack x +MackD +Mackadactyl +Mackadee +Mackdizzle99 +Mackeo +Mackerel Sky +Mackerels +MackhNL +MacksEntropy +MacksIsland +Maclairin123 +Maclas +Macoinho +Macre demia +MacreedyLove +Macromage1 +Mad Dog Eris +Mad Flavour +Mad Krampus +Mad Max 20 +Mad Papper +Mad Suss +Mad Vlad +Mad Watson +Mad X +Mad arrows12 +Mad as heck +MadBoy20 +MadBruh +MadCanadian +MadChemist8 +MadD0g11 +MadD0gL4d69 +MadDogged +MadJeffs +MadKingMikey +MadMaxMan +MadPubes +MadSnowman23 +MadaRook +Madaddam +Madam305 +Madarah +Madd177 +MaddAntelope +MaddMann5 +Maddape +Madddiieee +Madden +Maddie Baddy +Maddogjr +Maddux +Maddy +Made of Sand +Made4Slaying +MadeInAfrica +MadeYouClick +MadeinTYO +Madeiraa +Madeleine +Madeweine +Madhu +Madlaina +Madmaxie +Madness Max +Madodee +Madona +Madra +Madrock01 +MadsG +Madsenn +Madsermad +Madshatter71 +Madskillz756 +Madslasher30 +Madslax2 +Madsosaur +Madula +Madvantage +MadxMonsta +Mady +Madysen +Madza +Madzilla +Maeda +Maegera +Maela +MaerlinTaz +Maertynas +Maester +Maester Trea +Maestro +Maestro Heil +Maestro1 +Mafia-BP +MafiaMan +MafiosiDad +Mafooma +Mag1c +Mag1cJohnny +Mag1c_W33d +Maga Kahn +Magalator +Magani C +Magawie +Magc +Mage +Mage Eh +Mage Kume +Mage N Skil +Mage7master7 +MageFish +MageHax +MagePriece +Mager +Magerold +Magers +Mages350 +Magestus +Magethirst +Magezi +Magggorical +Magginator +Maggot +MagiTurtle +Magic +Magic Bonus +Magic Clicks +Magic Mackee +Magic Moose +Magic Rino +Magic Tree +Magic Wand +Magic fTail +MagicAppel +MagicMemorys +MagicPanda91 +MagicSchoBus +MagicSilver +Magic_Elmo1 +Magical +MagicalRuby +Magican +Magicarp +Magicbox +Magicdefence +Magicken +Magicx +Magija +Magik +Magik773 +Magikilo +Magiok +Magisteerial +Maglet +Magma +Magnaboy +Magnati +Magnautism +Magnesium +Magnesium J +MagnesiumIV +Magneticism +Magnetite +Magni99 +Magnifice +Magnilo +Magnis +Magnu +Magnus Gram +Magnusungam +Mago +Magsd1 +Maguneru +Maguro +Magus +MagusChum +Magyk +Magzem +Mah Jae +Mah Jong +MahSeed +Mahalusa +Mahanimal +Mahe +Mahkelroy +Mahler +Mahmoud +Mahogany +Mahomes +Mahonoken +Mahtitykki +Mahzius +Mahzka +Mai kel +Maiba +Maide +Maidenheir +Maignansdead +Maikel J +Maikhol +MailTime +Mailor +Main +Main 3s +Main Cactus +Main Ginger +Main J0urney +Main Mynt +Main Natey +Main Pando +Main Path +Main Product +Main Twiddle +Main Wario +MainCharlie +MainCoach +MainCringe +MainDong +MainForever +MainHamendex +MainHolm +MainJ +MainMan_Mads +MainNudley +MainPurp +MainSt +MainStand +MainStreamx +MainWabbit +Maind +Maindeer +MaineDeno +Mainline +Mainly +Mainly Pure +Mainly Ricky +Mains +Mainslet +Mainuru +Mainz +Mainz Gainz3 +Mair +Mair017 +Maisa +Maisa Torppa +Maisteri +MaitoRimpula +Maix +Maizon +Maizpilao01 +MajMischief +MajQ +Majakanvahti +Majcew +Majcew 2 +Majehjk +Majer4 +Majin Buuwu +Majinbooo +Majinjon +Majki +Majokko +Majooty +Major +Major Damien +Major Gains +MajorEar +MajorMammoth +MajorObesity +MajorOwnz +MajorSnizz +Majora +MajoraMasked +Majoras WRLD +Majzako7 +Maka +Maka2201 +Makagago +Makaule +Makaveli +Makaveli I +Makaveli II +Makaveli l +Make +Make A Pile +Make Carrion +MakeItStack +MakeMeKing +MakeNotes +Makeboy +Makeeesful +Maken +Maken Gainz +MakenMakkara +Makenna +Makhachev +Maki +Makilake +MakinExcuses +Makiverem +Makk +Makke +Makkeii +Makker Benja +Makker Trane +Makkiavelli +Mako Nox +Makoea +Maks Cape +Maksimit +Maksoinvelat +Maksuamet +Maksui +Maksukka +Makzd +MalaLechita +Malachai +Maladec +Maladiec +Malagah +Malbec +Malboulgea +Malcz +Malding +Male +Maleurous +Malfoy +Malhavic +Mali RS +MalibuMan96 +Malibuux +Malignant00 +Malik +Malinerix +Malitiae +Malkav +Mall +Mall Gang +MallbuRo +Malleus +Malli +Mallieero69 +Malloc +Mallomar +Malmi +Malmot +Malomalo +Maloo +Malqy +Malse +Malt +Maltapkiller +Malteadita +Malter +Malterz +Malucoftw +Malurian283 +Malvian +Malvidus +Malvoliuus +Malware +Mamachii +Mamas Meat +Mamba +Mambaaaaaa +MambasWRLD +Mambo No5 +Mamboita +Mammad +Mamoul +Mamupatja +Man Asian +Man Bag +Man Killa77 +Man Kip +Man Raccoon +Man Throater +Man gos +Man-Yak +ManBearPiggy +ManGoBzzzt +ManOfGold +ManUnited +ManVanWelec +ManWT +ManWoox +Manaburna +Manafont +Manakiel +ManakuraJP +Manantti123 +Manantti321 +Manardog +Manawatu +Manby +Mancandy +Manchest +Mancino +Mancunion92 +Mand1ng0 +Mandelbrot +ManderSala +MandoCheese +Mandor1 +Mandred +Mandulorian +Mane +Manegaming +Maneirinho +Manelzera +Maneter56 +Manevolent +Manfa +MangJoe +MangeMeister +Mangle +Mangled +Manglican +Mango +Mango Monkey +Mango Rat +Mango Season +Mango10 +Mango1997 +Mangobnana +Mangostangos +Manhoos +Manhunt +ManiacBison +ManicNode +ManicRS +Maniek +Manila +Maniwani +Manju +Manke +Mankitten +Manlanter +Manletti +Manly +Mannekeuh +Manni Penny +Mannie +Mannix270 +Mannjpip +Mannnekala +Mannowrath +Manny21 +Manokin +Manor +Manorvic +MansaMusa +Manser2300 +Mansup5 +Manswarm +Manswers +Manta +Manta Wray2 +Mantarayo +MantasA +Mantaslocoo +Mantelio8 +ManteliseXe +Manthe +MantorokDIA +Mantoshka +Manttt +Manuelh3 +Manumatti +Manx_Scaper +Many +Many Walrus +Manyi +Manyvids +ManzGotViewz +Manzo +Maose +Maozn +Mapanza1 +Maple +Maple Jay +MaplePoutine +MapleRoyals +MapledOaf +Maplejuana +Mapletech +Mapne +Mappl1n +Mappzz +Mar0e +Mar782 +Mara +Maracruz +Maradonaa +Marassa +Marathonius +Maraud +Marblez +Marc +Marc NL +Marc Paul +Marc Spac +MarcVinicius +Marchmello +Marchuk +Marcia Ress +Marcikarp +Marcilicious +Marcius 7 +Marco225 +Marco7k +Marcoli64 +Marcoo +Marcooow +Marcos Vibe +Marcski +Marcussius +Mardiie +Marducas +Mardy O G +Mardzz +Mare +Marenki +Maret +Marg3 +Margana +Marganer +Margiella +Margins +Margodx +Margon +Margonite Xu +Marguana +Marheim +Mari +Marianas +Mariano 1 +Mariasonic +Marib +Marijuano +Marikadere +Marines +Marinez +Mario Bros +Mario Goatse +MarioKartDD +MarioTennis +Marioh +MarioisKewl +Marioman +Marioneta +MariosPeach +Maritime +Maritozzo +Marjapuuro +Marjatta +Mark Pledger +Mark Swenson +Mark-777 +Mark-Zuk +Mark0vDeath +Mark12387 +Mark1ta +Mark5Barki +MarkBuns +MarkJongejan +Markald87 +Marke +Markerr +MarkhamON +Markie994 +Markipedia +Markku +Marklyft +MarkoOSRS +Markop100 +Markovia64 +Marks Main +Marks Phone +Marks lron +Markus +Markus Stier +Marky428 +Marlbrozo +Marleth +Marleyy +Marlin1993 +Marlon0817 +MarlonisGod +Marlooo +Marlopped +Marluxia Pwn +Marmita99 +Marmp +Marms +Marmy +Marn3y +Marni +Maro202 +MaroO +Maroj +Marokkaan +Marokkaantje +Maroko111 +Maroon5 +Marpollo +MarquiseDmnd +MarrCuzz +Marrcy +Marreldil +Marrer +Married +Marrio +Marrius +Marro75 +Marsal +Marsalkka +Marsel +Marsg +Marsgl +Marsh Marrow +Marsha +Marshal +Marshall1 +Marshmont +Marshyy +MarskiLark +Marsmash +Marsovec +Marstead +Marswatt +Mart0103 +Marten +Marten x +MarthProMonk +Martial +MartianLynch +Martiba +Martiiian +Martijn +Martika +Martin +Martin 2007 +MartinGameTV +Martindeq +Martinjsh +Martinkyle20 +Martins +Martinside +Martip +MartnShkreli +Marty +Marty150 +MartyG +MartynMage +Martyr Main +Maruna +Marv +Marvelli +Marvick +Marvins Dad +Marwan +Marwin +MarxRoux +MarxTheMyth +Mary j4n3 +Maryj +Maryland +Marylandd +Marzcorw +Marzeo +Marzhy +Masaca +Masacre599 +Masade +Masago +Masakado +Masandalf +Maschok +Masconomet +MaseLitt +Maserati +Mash +MashedOP +Mashimarq +Mashiwo +Masin +Masiron +Maskedpump +Maskin +Masochisttwo +Mason OSRS +MasonJarr +Masonatorr +Masonitte +Masons Dong +Masoo +MasquedMan +Masryy +Massa +Massacre Fc +MassageMan97 +Massif +Massimo130 +Massinissa7 +Massive +Massive Noob +MassiveJonas +Masss +Massterduel +Mast3rOogway +MastaHeff +Master +Master Bakes +Master Bogs +Master Byro +Master Garni +Master Jos +Master M V +Master Riven +Master Skizz +Master Vates +MasterB1994 +MasterBarter +MasterBlazee +MasterDragxn +MasterGrogu +MasterKiefff +MasterMake +MasterMasa2 +MasterNeigh +MasterOzzy +MasterPanda +MasterPookie +MasterRooshi +MasterSlayrr +MasterThresh +MasterX +Masteragota +Masterbihno +Mastercat +Masterdemon4 +Masterflick +Masteri +MasteriMori +Masterkindem +Masterrgod +Mastervile +Mastirida +Masturbeerke +Masurda +Masuro +Masylvain +Mat 1 +Mat Jacko +Mat Share +Mat thew11 +Matchbox 20 +Mate +Matematikk +Materium +Mateusz1210 +Math +Math Is Fun +Math ematic +MathVibes +Mathcore +Mathematics +Matheor +Mathers +Mathers1996 +Mathew +Mathias +Mathias Nemo +Mathisse +Mathmic +Matholemeu +Mathrotus +Matieus +Matix +Matkijanarhi +Matmo +Mato Seihei +MatoPotato +Matoaca +Matrak +Matreex +Matrix +Matrixpachi +Matruusi2 +Mats +Matsu +Matsuri +Matsyir +Matt +Matt 162 +Matt Bman +Matt CFK +Matt Cat +Matt GIM +Matt K +Matt Lad +Matt Mo +Matt Slay +Matt Smash +Matt V +Matt Wy +Matt1494 +MattLeedz +MattMattBro +MattNDew +MattRanger +MattRoux +MattSeal7 +MattStyle +MattWallet +Mattaclysmic +Mattakuda +Mattam66 +Mattaroo +Mattec +Matteos1 +MatterOfTime +Matternot +Mattex +Mattheus17 +Matthew +MatthewDK +MatthewRS +Matthewwww +Matthidan +Matthis +Mattias +Mattice +Mattie osrs +Mattie43 +Mattj +Mattniss +Matto +Mattor +Mattorel +Mattrate +Matts +Matts RNG +Mattsbro +Matttbob +Matttt +Mattty +Mattus50 +Mattx1 +Matty +Matty A +Matty Gibbs +Matty Ic3 +Matty467 +MattyChasee +MattyLight91 +MattyNW +Mattych +Mattyflight +Mattys +Mattyz6 +Matu btw +Matuba +Mature +Matwo +Matygoyo +Matz +Maub1 +Maucca +Mauddibb +Maui +MauiBeach +MauiMallard +Mauidude +Maukas +Maukka +MaukuMaija +Maul 0n Top +Mauler4500 +Mauler_rocks +Maumau013 +Mauna +Mauno +Mauricio555 +Maury +Mauvayy +Mauvier +Mavdagin +Mavel +Maven +Maver +Maveric +Maverrick +MavicAir +Maviie +Mawch +Maween +Mawie +Mawlocke +Mawn +Mawsen +Max 4 Mikey +Max Ape +Max Attacken +Max BD +Max Blacks +Max Botter +Max Cape +Max Deiron +Max Eff +Max Entropy +Max Gadget +Max Gav +Max Here4Pet +Max House +Max Karma +Max Klett +Max Methi +Max NoLyfer +Max O7 +Max Obi +Max Pkr +Max Puffs +Max Re3oo +Max Relax +Max Scape +Max Snek +Max Temper +Max The Hero +Max Tilting +Max Tonks +Max Vandal +Max Weezy +Max Wotif +Max XP +Max Zack +Max Zeus +Max btw +Max cape 420 +Max hits +Max killz6 +Max plus +Max uwu +MaxAchoo +MaxAnarchy +MaxBTW +MaxBadAss +MaxBear +MaxHare +MaxHaus +MaxHomieJose +MaxIgnorance +MaxIrl +MaxKhalifa +MaxMainJake +MaxMuffin +MaxNeander +MaxSAVAGERY +MaxTix +MaxTurbo +Maxchar +Maxd +Maxe2968 +Maxeado +Maxed +Maxed Beans +Maxed Code +Maxed Egirl +Maxed Emm +Maxed Eric +Maxed Groot +Maxed Hippo +Maxed II3en +Maxed Jeff +Maxed Kiraly +Maxed Loser +Maxed M0bile +Maxed MVP +Maxed Masak +Maxed Newfie +Maxed POH +Maxed Phells +Maxed Rat +Maxed Rob +Maxed Scaper +Maxed Spyike +Maxed Total +Maxed Twice +Maxed Velho +Maxed Whip +Maxed Zeb +Maxed Zuk +Maxed osrs +Maxed when +MaxedActuary +MaxedBruh +MaxedBurnout +MaxedButPoor +MaxedFrog +MaxedIn2074 +MaxedInDa6ix +MaxedMain +MaxedMax751 +MaxedMike +MaxedMobile +MaxedNbored +MaxedPleb +MaxedRepel +MaxedYP +Maxedlegacy +Maxedtoasty +Maxedwell +Maxell +Maxerder +Maxiboy4a9 +Maxidy +Maxime5100 +Maximonster +Maximum +Maximum Tier +Maximumist +MaximusAM +Maxinator87 +Maxing zzz +MaxingMyMain +MaxingSucked +Maxingthis +Maxiorek1200 +Maxisbaws +Maxisen +Maxitaxi777 +Maxiu +Maxjuhhhh19 +Maxkenzi +Maxmemix +Maxnominus +Maxo +MaxoBlasto +Maxoou +Maxpappy +Maxpro +Maxst +Maxstalker67 +Maxstatz +MaxtanosXD +Maxwall +Maxx +Maxx y +Maxxed Alt +Maxxed Dusty +Maxxed Trash +MaxxedNoob +Maxzet +MayanFuror +Mayate +Maybe CIA +Maybe Idiot +Maybe Jeff +Maybe Shady +MaybeMason +MaybeMitch +Maybemnam +Maybez +Maybizzle +Maybon +Maydole +Mayerdynn +Mayhaps +Mayhem +Mayhem Maker +MayhemMakers +Mayl +Maylive +Mayo +MayoForFunds +Mayonaz +Mayor +Mayor Jiwana +Maytona +Mayuri +Mayushii +Mayvex +Mayweather +Maz0n1k +Maza +Mazala +Mazande +Mazariner +Mazauu +Mazda168 +Mazdan +Mazdaspeeed3 +Mazdraith +Maze +Maze of Iron +Mazel613 +Mazersyy +Mazhar +Mazlol +Mazmarazor +Mazoni +Mazpls +Mazta +Mazuma +Mazz y +Mazzacre +Mbox +Mbyoo +Mc Dragans +Mc Florry +Mc Red +McAlakazam +McAsssBlast +McBurn +McCheddabomb +McChimkenGOD +McChubbin +McCllin +McConaughey +McCreJ +McCringle +McCune +McDanky42O +McDizzle15 +McDongles +McDoodle_21 +McDouble +McFantasy +McFizzleDady +McFly93 +McFozzar +McGooser +McGorm +McGregor60gs +McGruff +McHammock +McIllu +McIronLeech +McKennon +McKerma +McLOVlN +McLaeNz +McLeaNz +McLemore +McLovin707 +McLowry +McMeekin +McMillan +McNeal +McNoob10 +McNoodle +McNorm +McNugget +McP0P0 +McQuaker +McQueensy +McRibs +McRibs Back +McRip +McSchloogan +McShrubbery +McSomf +McSplitter +McStarley +McSuperNoob +McTaskupillu +McThomzie +McVittties +McWeaksauce +Mcards +Mcbelsito +Mcberra +Mcdally +Mcgingerpony +Mcgregorini +Mckelvie +Mckinconn +Mclaren88 +Mcneill +Mcpatrice12 +Mcpielover +Mcturdson +Mcwaffle1 +Mcy +Mderg +Mdub Suhh +Mdzvwz +Me Acoustic +Me Ca +Me Dead +Me No Brains +Me Woody +Me and Jr +Me lvin +Me phisto +Me3lem +MeBigPoppa +MeBlast +MeMillionthD +MeThudZ +MeTwo +MeadowFall +Meadows +MeagerSkills +Meals +Mean +Mean Crusher +Mean Street +Meano +MeanrangerFE +Meap +Mearm +Mears +Measles +Meat +Meat Rat +Meat Shank +Meats +Meatspot +MeatyLoaf +Meauner +Mebo +Mech +MechantBozzo +Mechaodin +Mechelen +Mechvengance +Mecidon +Mecone +Mectofion +Meddler +Meddlr +Medi Mobile +Medi i +Medi ocre +Medical Herb +Medicate +Medicides +Medicinal +Medicore +Medievh +MediocreMatt +MediocreRye +MediocreTime +Medispensary +Meditations +Medium Cloo +Medler +Medoletics +Medon +Medorable +Medusa228 +MedwayDragon +MeechIsCute +Meechy Dark +Meeeseek +Meelays +MeenBeans +MeepBeepMeep +Meeran +Meerca +Meerkz +Mees126 +MeesKees +MeetMyMeat +Meetti +Meew +Meewerp +Mefaustofele +Mefco +Meftah +Mefy +Meg 3 +Mega +Mega Butt +Mega Farce +Mega Kyle +Mega Mort +Mega konn +MegaAmpharos +MegaDoris +MegaDrive +MegaMustarn +MegaNaziHatr +Megabyte6 +Megadwarf47 +Megalo +Megalodont +Megamanyo +Megamind +Megamind Jr +Megans +Megaronii +Megastoffe +Megatortle +Megatrax +Megis +Megnificent +Megpan +Megumin +Megustio +Meh Noob +Mehrunes +Mehts +Mehuelin +Mehuo +MeideC94_BB +Meido +Mein lron +Meinkul +Meiousei +Meister Sho +Meiyo +Mek +Mekaanik +Meklo +Meksa +Mel Meow +Mel Yakutia +Mel btw +Melanderr +Melanoma +Melayna +Melc0n +Melchuzz +Melcoor +Meldianx +Meldynoir +Melee +Melee_Range +Meleny +Meleven +Melhoop +Meliodas420 +Meliodin +Melisma +Melk +Melkin +Melktietje +Melkzuurtje +Mellakka +Melleruds +Melling +Mello Gello +Mello Yello +Mellodynamic +Mellow Jingy +Mellow Tones +Mellow6 +MellowSoul +MellowTokes +Melly +Melly YNW +Melo +Melodicolt +Meloenschijf +Melongrab +Melotoninn +Melpan +MeltedCash +Meltman +Meltok +Meltryllis +Melvin dew +MelvinTheOK +MemberBerry +Memberlist +Meme +Meme Loord +MemeDoge111 +MemeVendor +Memedalorian +Memem3 +Memeologist +Memeshake +Memmor +Memory +MemoryCard +MemoryWorm +Memphis lol +MemryLoss +Mena +Menap +Menaza +Mend +Mendicant +Mendieton +Mendokusai +Mendota +Meneer +Meneer Nijn +Menesus +Menetoeihin +Menial Luck +Mennie +Menrey +Mensphysique +Mental Coach +Mental4Metal +MentalAbacus +Mentally Moo +Mentalmissy +Mentoes +Menyu +Menza +Menzola +Meoooow +Meow Ghost +Meow Im Hawk +Meow Softly +MeowKiki +Meowed +Meowgi +Meowler +Meowmagic +Meowrijuana +Meowskeys +Meowtheduck +Meowzer7 +Mepiff +Mepn +Mepthadr0ne +Mer Train +Merami fan +Meramon +Meraxus +Merbz +Merc-Raa +Merc_Lobo +Mercedes F1 +Mercenary V +Merces +Merch +MerchantUrch +MerciTwingo +Merciulago +Mercphobia +Mercules +Mercury Owl +Mercury15 +Mercy +Mercy Osrs +MercyfulFate +Mercys +Merderr +Mergician +Meric +Meridians +Meris +Merisalu +Merisorax +Merkdalat +Merke +Merked Ko +Merksick +Merlin +Merlin Otter +MerlinMonroe +MerlinPT +Merloc21 +Merlucius +Merlvin +Merricat +Merry +MerryTuesday +Mersunperse +Merten +Mertguy2p0 +Mertiin +Mertjaars +Mervyn +Meryam +Meryath +Meryl +MesH3aL +Mesa +Meshi510 +Meshkot +Mesin +Mesmeriize +Meso cyclone +Meson +Messaa +Messersmitti +Messi +Messias +Messorium +Mestari +Mestaristick +Mester B +MesterAbekat +MestreGlados +Met Promise +MetDoobie +Meta +Meta Mammoth +Meta l +MetaCTF +MetabolicPro +Metadragon +Metafisico3 +Metagel +Metal +Metal Booty +Metal Little +Metal Shad0w +MetalGear +MetalMaiden3 +Metalest +Metaling +Metallic Neb +Metallifog +MetallikDeth +Metallproz +Metalproz +Metamorphic +Metamorphs +Metamushroom +Metaphwoar +Metaurus +Metaxia +Metbol +Meteora +Meteoriitti +Meth Teeth +Methal +Methodical +Methusal +Methylanara +Metix +Metoprolol +Metropolia +Metsavaras +Metselaar +Metsiq +Metters +Metukka +Metzifer +Metzz +Meulendijks4 +Meune +Meuosh +Meur +Meuyou +Mevvz +MewIlicious +MewPulse +Mewby +Mewli +Mewllicious +Mewrad +Mewtwo +MewtwoKing +Mewww +Mex Arkantos +Mex_N_Flex +Mexicanchild +MexiePie +Mexlet123 +Mextex +Meykaa +Meymer +Mez-qt +Mezane +Mezecs +Mezenburn +Mezeroth +Meziriti +Mezmereye +Mezomel +Mezy +Mezzalarry +Mezzito +Mf Fe +Mfey +Mfin Taylor +MfknNewports +MgZz +Mglegolas +Mgn +Mhh +Mi Hoy Minoy +Mi1os +Mi3pelst3in +MiAdidas +MiIIenia +MiIIers +MiQuu +MiTDro +Mia Kalphite +Miacon +Miami 305 +Miami Cane +Miami Rebels +Miasm +Miawnation +Mibs +Micaso +Miccolo3 +MiceMan +Micecream +Micella +Mich +Mich Bz +Mich49 +Michael +Michael4655 +Michael67676 +MichaelB +MichaelScarn +MichaelScott +MichaelXCVI +Michaelinos +Michairon +Michal +Michanderma +Michano1992 +Michaud +Michel647 +Michelau +Michelle jnr +Michiel +Michiel_96 +Michinaki +Michism +Michlenn +Michxa +Michy Man +MickZagger +Mickael +MickeyJoe +Mickeyr4nge +Mickul +Mickyy +Micosa +Micro +Micro Cosmic +Micro Nerd +MicroButt420 +MicroShrooms +Microdot +Microgolf +Microman0000 +Micromelo1 +Microo +Micropyle +Microsoft22 +Mictie +Micxyz +Mid Fade +Mid Pack +MidValley +Midareru +Midas224 +Midday +Middelkerke +Midget +Midget Bones +Midget Rave +MidniteGreen +Midori +Midori Enju +Midside +Midway16 +Midweeks +Midwife Dan +Miega +Miegalius +Miekka +Mier +Mierdapier +Mies +Mies Lapsi +Mig Wizard +Migalos +Miggles +Mighty +Mighty King +Mighty MP1 +Mighty Milk +Mighty Oak +MightyDolt +MightyNemo +MightyOrange +MightyPieBoy +MightySlappe +Mightyfrosty +Migjiris +Migou +Migrainelife +Migraines +MiguelDyson +Miguu +Migy +Migzee +Mihu o_o +Miiammi +Miig +Miiiild +Miika +MiikeyG +Miillls +Miiori +MiissMandii +Miitt +Mij +Mijae +Mijniebelle +Mijuzo +Mik +MikTheKing +Mika Kuwait +Mika x +MikaDMM +Mikael +Mikasana +MikazuAugus +Mike +Mike DIY +Mike Davis +Mike Hochuli +Mike Hunt +Mike Mike +Mike Unit +Mike Xp +Mike-NL +Mike1 +Mike745638 +MikeChang +MikeConleyJR +MikeDangr +MikeDitka +MikeHasMoobs +MikeM +MikeMontana +MikePunts +Mike_Oxmaul +Mikebaker417 +Mikeey +Mikeje13 +MikelCz +Mikemyers31 +Mikerockshhh +Mikeroscape +Mikeroscope +Mikes1995 +Mikethafarm +Mikey +Mikey B +Mikey Bai +Mikey Hey +Mikey Milk +Mikey x +Mikey1plate +Mikey47745 +MikeyBigDick +MikeyPat +Mikeygirl94 +Mikeyscape +MikeyyG +Mikezalwinnu +Mikezilla +Mikezzup +Miki4 +Mikilly +Mikki +Mikkon +Mikouich +Mikrobangine +MiksuBTW +Miksuuu +MikuNakanoxx +Miky852 +Mikzel +Mil Z +Mil ky +Mila +Milagre +Milaz +MildRussia +Mile Stoner +Mileage +MilesQPR +Miley Cyrush +Milfcocktail +Milfguardian +Milhous +Mili +Milico +Milieu +Milieudienst +Milimoowolf +Miljoona +Milk +Milk Energy +Milk Expert +Milk Sausage +Milk my milk +MilkDaughter +MilkMan227C +MilkOhh +MilkToast +Milked Cox +Milkki +Milkless +Milkmate +Milkn Tiddys +Milkopia +Milkraze +Milky +MilkyGalaxy +Mill Reef +Mill385 +Millbrook92 +Milleks +Miller 40 +MillerLatte +Millerlite40 +Millerlite95 +Millermore +MilliMillzy +Millie +Millionsppl +Millkk +Milllf +MillsMCR +Millsbay +MillzyRS +Milo +Milo Iced +Milo Monster +Milol +Milpe +Milsurp +Miltank +Milton +Mim3r +Mimahh +Mime Tan +Mimi20 +MimiKe +Mimic +Mimori +Min Botter +Min XD +Minalinsky +Minar +Minazuki +Mincene +Mind +Mind C Crew +Mind F-ed +Mind of me +MindBender84 +MindYoStep +Minde +Minde0777 +Mindf4ck7 +Mindforce +MindfulGnome +Mindgrnd +Mindhead +Mindlet +Mindreaver +Minds Hunter +Mindys +Mine is frai +Miner00 +MinerMvp +Mineraal +Minerii +Minerock +Minerock Man +Minesweeperx +Mineta +Miney +Minfri +Minga Minga +Mingdee +MingeKing +Mingerd +MinhteaFresh +Mini +Mini Aurelia +Mini Biceps +Mini Chocobo +Mini Elba +Mini Hazy +Mini Jaack +Mini K +Mini M +Mini Misty +Mini Van +Mini Xander +Mini o +MiniBuilt +MiniBundy04 +MiniCoat +MiniDrew +MiniDuckling +MiniNinjo +MiniSoMini +MiniStew +MiniToast +Minibini +Minidefiant +Miniglass +Miniguez +Minijazz +Minimaps +Minimizing +Minimum +Mining +Mining Runes +Minioz1 +MinipeTh +Minirio +Miniscus +Minish Gal +Minisnacks +Miniuzy +Minix +Mink +MinkMiller +Minkyeung +Minnesoooota +Minnick +Minnie +Minski +Minslee +Minstrel RS +Mint +Mint1s +MintEastwood +MintSoldier +MintWestwood +Mintaras +Minton +Mintvolcano +Minty Elder +Minty Rogue +Minty28 +MintyBeaver +MintyBreath +MintyFreshFe +Minty_Duos +Mintyyyy +Minu Kamp +MinusMinitia +Minyons +Minzy130 +Mio Magic +Mioceen +Mipu +Miqdad +Miqote +Miquuw +Miracle +Miracle Grip +Miracle Sun +MiracleToy +Miraculous +MiramiS +Miran a +Mirana +Mirari +Mire +Mirek +Mirepoix +Miriage +Mirin_Gloots +Mirith +Mirize +Mirk +Mirkat +Mirkoi +Mirkys +MiroSemberac +Miroh +Miroki +Mirthless +Miruki +Mirxcle +MisClickPro +MisLilToe +Misaka 10032 +Misakipillow +Misano +Misantrofia +Miscellaneum +Mischief +Miscrint +Miscy +Misdeal +MisfitGrinds +Mish +Mishie x +Mishigamaa +Mishkkal +Misimo +Miskil +Misks +MiskySam +Mislabeled +Miso Horney +Miss +Miss Amanda +Miss Amped +Miss Beth +Miss Clover +Miss Inform +Miss Judging +Miss Kipatzu +Miss Kitty +Miss Nothing +Miss Piggy +Miss Tinaa +MissArcane +MissMockingJ +MissMystique +MissRosie +MissTowlie +MissTwistedx +Missandrist +MissclickGG +Missel0 +Missen +MissinTicks +Missing +MissingRNG +Mission +Missu +Missus +Missvmk +Missy +Missy Cee +Mista +Mista 1337 +Mista Wright +MistaPhelps +MistaWubz +Mistagainz +Mister +Mister Chill +Mister Ex +Mister Gone +Mister Jar +Mister KJ +Mister Texas +Mister Tiger +Mister Xanny +MisterBass +MisterBensy +MisterBidoof +MisterCobb +MisterGurn +MisterJager +MisterPatego +MisterStats +MisterTrump +MisterWhale +MisteruDongu +Misterwieb1 +Mistheos +Misticwok +Mistify +Mistik Soda +Mistio +Misto-Flies +Mistr Morale +MistrGiggity +Mistral +Mistre Apple +Mistres Pres +Misty +Misty12 +Misty7632 +Misuryu +Mitabi +Mitch +Mitch Gate +Mitch Izle +Mitch Peters +Mitch W +MitchHardo +MitchRap +Mitchggee +Mitchman987 +Mitchs 2nd +Mitchys Iron +Mith +Mith Man214 +Mith Scimmy +MitherHobo +Mithoon +Mithrality +Mithralking8 +Mithrane +Mithter T +Mito +Mitologas +Mitqh +Mittag +MittensRS +Mittum +Mitus +Mituse +Mitver +Mitzchy +Miuted +Miuw +Mivo50 +Miwi +MixBro +MixKit +MixTapeFiya +Mixes +Mixieg +Mixtape +Mixun +Mixxush +Miyags +Miyui +Mizis +Mizo +Mizro +Mizty +Mizuno Akane +Mizusawa +Mizz Horror +MizzFrizz +Mizzzura +Mjay +Mjoll1990 +Mjurk +Mk20 +Mk60 +MkLeo +Mkiller120 +MknlC +MlCOOL +MlDGARD +MlKE +MlKEL +MlLFnCOOKIE +MlLLlSECOND +MlLO999 +MlXOR +MlZORE +Mlao +Mlddel1 +Mlopes +Mmgmike24 +Mmichel +Mmkbro +Mmm Food +Mmm Mushroom +Mmm Xp +MmmBathSalts +MmmButter +Mmmmm Bacon +Mmorpg +Mmu +Mmurder825 +Mmv +Mnemic +Mnir +MnkyDLufy +Mnmnnmnm +Mnts +Mo Fo Sho +Mo Hit +Mo slays +MoFo Boss +MoIon Iabe +MoMoYaP1972 +MoPhobia +Moathog63 +MoaxD +Mob Partyhat +Mob Punch +Mob Up +MobILe_Own3R +Moba All Day +MobbDeep +MobbyWang +Moberger +Mobiel +Mobile +Mobile Data +Mobile Maxin +Mobile Rng +Mobile Skiff +MobilePlayin +MobileSkeng +MobileXPOnly +Mobilekraan +Mobilist +Mobiusyellow +Mobo +Mobs +MobyWoby +Mobz +Moca Pet +Moccamuna +Moccies +Moccona +Mochasins +Mochi Donuts +Mochyy +Moe Amien +Moe Is Back +Moe You Up +MoeCipher +MoeTx +Moeberg +MoedZhafa +Moedameyer +Moefugganutz +Moepog +Moer +Moes +Moestieee +MoetIkLopen +Mofaer45 +MoffelRS +Mofleminator +Mofo Lt +Mofo Shadow +MofoMo92 +Mofoe +Mog Time xD +Mogcow +Moggok +Mogtime +Moh +Mohahm +Mohamedss +Mohanad +Mohannah +Moheed +Mohh +Mohib +Mohlo +Mohnday +Mohphy +Moiqol +Moist +Moist Dreamz +Moist Holy +Moist Maori +Moist3allsac +MoistButh0le +MoistMaker +MoistPainal +MoistWreck +Moistium +Mojimot0 +Mojito +Mojo Fiki +Mojojojo171 +Moju +Moju GG +Mojurico +Mojzis +Mok101 +Moka +Mokemok +Mokkasiini +Mokke-senpai +Mokkis +Moksa +Moksu +Moku +Mokum +Mokum Syl +Mola +Molag x Bal +Molars +Moldy Nuts +MoldyChips +Mole +Mole Slides +Mole1 +MoleMan-II +Molemountain +Moles Rule +Molinas +Molkkipo +Molle +Mollem +Mollium +MolllyPop +Molloyo +Mollt +MollyLlama +Molokotorby +Molotoffer +Moltea +Molten +Molten B +Moltenclawz +Moltres X +Mom Hunter +Mom Madness +MomICantPaus +Moments +MomentsApart +MommaCuz +Mommy +MommyMish +Mommys Hand +Momoh flip +Moms +MomsLasagna +Moms_Spagett +Mon key +Mon3yy +Mona +Monarchis +Monarchy +Monday +Monde +MonehBabeh +Money +Money BTW +Money Bagz +Money Grabs +Money Mann10 +Money tyven +MoneyMalone +Moneyman +Moneyman 199 +Mongke +Mongrel Hick +Mongstaman +Moniez +Monika Liu +Moniosaaja +Monitor +Monk +Monk Fists +MonkFishking +Monka +Monka Blunts +MonkaFront +MonkaGrizz +MonkaSFish +MonkaZter +Monkadile +Monke +Monkees80 +Monkey +Monkey D C +Monkey News +Monkey Pox +MonkeyDGazoo +MonkeyHeadAF +Monkeyannie +Monkeyboy991 +Monkeydodo45 +Monkeyhug +Monkeys Ass +Monkeysick +Monkie +Monkphish +Monksmen +Monkster +MonnerMads +Monnivalas +Monnual +Monny +Mono +Mono Y Mono +Monopoly +Monopoly Mvp +Monotone 07 +MonrealkaAfk +Monroejo +Monsemand92 +Monsilly +Monsta +Monstaarr +Monster Hog +Monster Tits +Monster333 +MonsterKush +MonsterTrain +Monsterofpk +Monstrius +Monstrocity +Monsutaa +Montagne +Montak +Montanaro +Monterey +MonthOldMilk +Monty +Monty Jr +Monumental +Monuu +Monxanvrooo +MooGoo +Mooch +Moocow910 +Moodeer +Moodoo +Mooffa +MoofinnMan +Moogly +Moohcake +Mooi +Mooie +Mooing +Mooing Cow +Moojin +Mookinater +Mooksy +Moon +Moon688 +Moon7I8 +MoonCard +MoonDunes +MoonStaIlion +MoonWolf +MoonYagami +Mooncrafting +Mooner +Moongazing +Moonish +Moonish Ale +Moonjock +Moonlightcb +MoonlitNika +Moonly +Moonman392 +Moonr0cks +Moonshadow18 +MooonCakeee +Mooony +Moopy +Mooqie +Moordaap3 +MooreNoyce +Moorleey +Moortgat +Moose +Moose Land +Moose713 +MooseEatBear +Moosecup +Moosefangs +Mooseheads +Mooserini +Moosewizza +Mooseyt +Moosy +Moot +Moowi +Mooyee +Mopdussy +Mopeds +Mopedstian +Moppeharry +Moppy +Moq puW +Mor Ul Neck +Moral +Morales +Morally +Moray +Morbid +MorbinThyme +Morch +MordLacaroni +Mordacai +Mordenumero2 +Morder-Biest +MordinSolus +Mordy +More +More AFK +More Chillli +More Coala +MoreThermite +Moredots92 +Morelos +Morfeusz +Morgan Donor +Morgan69 +MorganAtkins +MorganaTits +Morghuan +Morghulish +Morgo +Morgoth Man +Morgue +Morguhh12 +Mori Memento +Morijo +Moriquendi +Moritz +Morkius +Morkret +Morkula37 +Morland +Morlun +Morlyx +MormonFTP21 +Morniingstar +Moronavirus +Morot +Morph1ng +Morpheus Aus +Morphing +Morphogene +Morpice +MorqSukhaari +Morqan +MorrisTheCat +Morsey +Morski +Mort +Mort Eater +Mort Rigo +Mortal +Mortal Coil +Mortalize +MortarMan +MortemPlaga +Mortituros +Mortle2 +MortonRamsey +Mortonnizer +MortresxD s1 +MorttMoryt +Morue +Morvas +Morytania +Mosade +Mosaq +Mosbol +Moscosung +Moseley +Mosess +MoshPitJosh2 +Mosio +Mosiph +Moska +Mosmo +MossadKiller +Mosse +Mossels +Mossgiant +Mossy +Mossy Taint +Most +MostDreaded +Mostly Godly +Mostoes +Mosychuk +Moteha +MothQueen +Moth_29 +Mothafuqueur +MotherFigure +Mothless +Motikeli +Motion1010 +MotivaSean +Motivated +Motmans +Motochorro +Motor +Motse +Mottis +Mottly +Mottookaa +Motx +Motyas +Motzimoo +Moubu +Mougi +Moukie +Moul +Mouldied +Mouldy Lamp +Mouley +Mount +Mountain +Mountan Drew +Mourn +Mourners +Mournhold +Mous +Mousecream +Mousekeys +Mouselifter +Mouseman298 +Mousenn +Mousie23 +Mouteo +Mouthful Pip +Move +Move Over +Move Ziggy +Move2791 +Movember +Moviestar +Moving +Moving20 +Mow on mate +Mowgli13 +Mowk +Mowt +Mox +Moxy Senpai +Moyaha5 +Moyd +Moyis +Moysey +MozDef +Mptrj +Mq4 +Mr 0wnage +Mr 223 +Mr 7o7o +Mr 9ine +Mr A +Mr Airborne +Mr Alba +Mr Alex +Mr Ashh +Mr Ayye +Mr Bagel +Mr Baggy +Mr Barakas +Mr Bazzi +Mr Beefman +Mr Beekman +Mr Believe +Mr Biceps +Mr Bijpakken +Mr Bond +Mr Boogley +Mr Brunoo +Mr Burton x +Mr C0KE +Mr CHM +Mr Chonky +Mr Chopz +Mr Comrade +Mr Costy +Mr Count Up +Mr Cryin +Mr Dan Solo +Mr Darzelis +Mr Deivis LT +Mr DirtyDan +Mr Dong322 +Mr Dreamcast +Mr Dry +Mr Dudeicus +Mr Dumbiller +Mr Durian +Mr Dylesxic +Mr Easyscape +Mr Egret +Mr Elmar +Mr Elysian +Mr EsKei +Mr Fathead +Mr Father +Mr Foe +Mr Freezie3 +Mr Fridge +Mr Funguses +Mr Geese +Mr General +Mr Gentil +Mr Ghillie +Mr Ghizar +Mr GnW +Mr GodLuck +Mr Hanki6 +Mr Hassan Fe +Mr Hollowx +Mr Hrodbert +Mr Hulbert +Mr Infinity +Mr Iron Bar +Mr Iron Gray +Mr Iron Owl +Mr Iron Poo +Mr IronAss +Mr Jacko +Mr Jam10 +Mr Jam1O +Mr Jasperr +Mr Johbi +Mr Jonh L +Mr Jordy +Mr Joshing +Mr Jot +Mr Kaasmof +Mr Kato +Mr Keyss +Mr KingCobra +Mr Kirbo +Mr Kiwi Bird +Mr Kman +Mr Kodai +Mr Kokkok +Mr Krabbsss +Mr L0af +Mr Laser +Mr Laz +Mr Leeee +Mr Looch +Mr Loser +Mr Lysol +Mr Mackie +Mr Manual +Mr Martel +Mr McCune +Mr Mentos +Mr Mikers +Mr Missiles +Mr Miyagy +Mr Moncler +Mr Mordacai +Mr MrX +Mr Nagoh +Mr Nasty Kev +Mr Nate +Mr Nebs Main +Mr Neckless +Mr No Rift +Mr No Sleep +Mr NoMates +Mr Nonya +Mr Ohio +Mr Oizo +Mr OldSchool +Mr Osc ar +Mr Ozzy +Mr Palm +Mr Pandaz +Mr Pastorius +Mr Peggers +Mr Phelipe +Mr Pita +Mr Platypus +Mr Pondman +Mr Poup +Mr Pretzels +Mr Questerr +Mr RaWaR +Mr Rebirth +Mr Rich T +Mr Robert +Mr Romm +Mr Ryker B +Mr S N S +Mr SZX +Mr Sasquatch +Mr Shaman +Mr Siege +Mr Sighco +Mr Slabs +Mr Slaw20 +Mr Spark +Mr Splitter +Mr Squicky +Mr Stan Man +Mr Syvan +Mr T C +Mr Takoya +Mr Tbh +Mr Teej +Mr Thornbery +Mr Troll +Mr Trump +Mr Untainted +Mr Vaidys +Mr Vanhanen +Mr Veegs +Mr Wieler +Mr Wild x +Mr Woods +Mr World 420 +Mr Woz +Mr Wumbo +Mr Xray +Mr XuRu +Mr Yozef +Mr Yum +Mr Yzi +Mr Zevosh +Mr Zio +Mr ensayne +Mr noli Fe +Mr rubler +Mr spikey +Mr stony +Mr2ndPlace +Mr44 +MrAlcotester +MrAmazing +MrAmbaal +MrAngelxz2 +MrAngerfist +MrAnkan +MrAwesomeNL +MrB1u3 +MrBananaJoe +MrBeadyEyes +MrBeastly +MrBeerNTits +MrBic +MrBigLoads +MrBigPecs +MrBigWheels +MrBingly +MrBlueScreen +MrBooBlocca +MrBorreby +MrBouncyButt +MrBraa +MrBry +MrBryne +MrBucko +MrCammilleri +MrCandleWax +MrCharmeleon +MrCian +MrCivilian +MrCoolSkills +MrCoook +MrCoopahh +MrCowey +MrDTails +MrDairyHeir +MrDaive +MrDarkBlue +MrDarkSide76 +MrDarling +MrDashwood +MrDeadInside +MrDevice +MrDevour +MrDoake +MrDoofes +MrDraconite +MrDumbaldore +MrEasty +MrEdgaras +MrEmerica +MrEnd +MrEwan +MrExterm +MrFANG +MrFancyboots +MrFarrell +MrFlizz +MrFluffy97 +MrFreakyFrog +MrFrizzesh +MrFro +MrFrogRS +MrFuack +MrGaalis +MrGainz +MrGanksta +MrGatorGnash +MrGeeeeeee +MrGibbletts +MrGixxer +MrGodBrand +MrGoodbye +MrGraveLord +MrGrind +MrGurbz +MrGurn +MrGustuv +MrHatN Clogs +MrHeftyBag +MrHobokian +MrHummus +MrHypeK0 +MrIWontMax +MrIronChef +MrJTheIron +MrJad +MrJargon +MrJermu +MrJoestar +MrJohnnyx +MrJonMan +MrKadir007 +MrKerrie +MrKevinR +MrKoalas +MrKyle +MrLaffy +MrMag +MrManny +MrMatchett +MrMaxLvl99 +MrMayhem +MrMeeseek420 +MrMeeseexs +MrMell0w +MrMime +MrMonkeyJock +MrMonopoly +MrMonsterrr +MrMooCows +MrMose911 +MrNL +MrNaf1 +MrNatee +MrNeverWrong +MrNice98 +MrNieksas +MrNikeKush +MrNoBank +MrNoFgiven +MrNoFilter +MrNoLove +MrNook +MrNorwayOS +MrObliverate +MrOceanic +MrOctapus +MrOngh +MrOriginal25 +MrPK74 +MrPaip +MrPapaJoe +MrPezcu +MrPige0nz +MrPiggles +MrPlasters +MrPoopiehead +MrPork +MrPotionz +MrPowers +MrPutterLite +MrQuaker +MrQuick1 +MrRaidUrGirl +MrRakoon +MrRangingElf +MrRawDog +MrRiceBucket +MrRidder +MrRight4U +MrRobinHood6 +MrRoboto +MrRocco +MrRodgersHD +MrRojo31 +MrRumarak +MrRuneDrag +MrRyo +MrSanta94 +MrScape2Much +MrSensimilla +MrShneeeebly +MrShoarma +MrSimQn +MrSirOne +MrSkydive +MrSlongerton +MrSmiiLey +MrSmikkel +MrSocorelis +MrSolo +MrSteelYoRNG +MrStickyBudz +MrSucellus +MrSuibhne +MrSupo +MrSusans +MrSwift00 +MrTanglez +MrTibberfitz +MrTickMaster +MrToad +MrTobyG +MrTooSerious +MrTough rs +MrTrashclikz +MrTryHard69 +MrTurds +MrVillanelle +MrVitable +MrWallnutt +MrWeageZ0311 +MrWest +MrWhetFartz +MrWobble420 +MrWorldwidee +MrYachie +MrZandra +Mr_B1ff +Mr_Hairless +Mr_Kadir007 +Mr_Kapoo +Mr_Manchello +Mr_Ostroum +Mr_Schmeckle +Mr_Scoff +Mrawrs +Mrbadwrench +Mrbaird +Mrbd +Mrburnsss +Mrcoconut22 +Mrdeemoney +Mrevil1 +Mrfuntime517 +Mrfuzzy +Mrglex +Mrhood +Mrjellyfish +Mrjli +Mrloonetick +Mrm0rm0r +Mrmagoo0 +Mrmanguy +Mrn1ceguy89 +Mrpokoz +Mrpoopyface1 +Mrs Budie +Mrs Pure Cut +MrsFabler +MrsJonesUFT +MrsMushrooms +MrsPurpTurt +MrsSocorelis +Mrslipkn0t +Mrwaffleses +Ms Goblin +Ms K +Ms Lizziard +Ms Trap +Ms Zik +MsAnderzen +MsArachnea +MsBoothanqq +MsFreakyFrog +MsGroves +MsSev +MsethOWarq p +Mssp +Mstr Postman +Mt Eben +Mt Olympus +Mthrfckrmike +Mthw +Mtn Dew Dew +MtnDewford +MtnGoat +Mtp69 +Mtra +Mtv Cribs 07 +Muad_Dib +Muahahaha45 +Muahhahaa +Muahuahuahua +Muas +MuasBtw +Muay Mat +Muaythai +Muc Gib +MuchBetta +MuchGpWaste +Muchly +MuchosAssias +Muchy +Muckball +Muco +Mud Cricket +Mud Temple +Mud9 +MudCatBigDog +Mudda Focha +Muddas Main +Muddy patch +Mudguard +Mudkins +Mudkip +Mudmur +Mueezy +MuerteBella +Mues +Mufasa +Mufasa IXI +MufffinKing +Mufficer +MuffinActual +Muffinkyutie +Muffins +Muffinyatta +Mufz +Mugarooni +Mugen +Mugge +Muggerman3 +Muggled +Muggles +Muggtjuven +Mugrub +Mugy +Mugzy +Muhaji +Muhamed +Muhfn +Muhkea +Mui Gokuu +Muilpeer +Muki +Mukkaram7861 +Mukkey +Muktheduck +MulasRevenge +Mulberry Mtn +Muleleaveox +Mulky +Mulle-mek +Mullet Mafia +Mullishus +Mullvaden +Mully +MullyMammoth +Multi +Multiloquent +MultipleRats +Multiplying +Multitalent +Multiway +Multizeta +Multrix +Mulugga +Mum3nRider +MumBanker +Mumble +Mumbles +MumblinSloth +Mummzy +Mumriken +Mums +Mumspaghetti +Munansurvain +Munchise +Munder +Mundt +Mungles +Mungoe +Mungu +Munia15 +Munich +Munire +Munk +Munkea +Munkefar +Munkinut +Munky Munk +MunkyBizness +MunkyKnuckle +Munn +Munnchicles +Munqqi4862 +Munqqii +Munshae +Muparadzi +Muphat +Muppz +Murasa +Murbez +Murda Turk +Murder +Murdered +Murderings +Murdimius +Murdock +Murdur +Murgambit +Muri +Murilokooo +Murimekko +MurkWahlberg +MurlokMurlok +Murogrim +MurphRS +Murphys +Murphys Lag +Murpman +Murray +Murray 1991 +Murre +Murrloc +Murrrum +Murt15 +Murtti +Murzum +MuscleNation +Musftw +Mushmom +Mushroom +Mushroom Mtn +Mushrooms1 +Mushtime +MushuPorkPls +Musi c +Music +Musica +MusicalMurdR +MusicalStory +MusiclRevivl +Musicpunk +Muskets +Muskintine +Muskogee +Musky Whale +Muslimi +Musschoot +Mussy +Must +Must Slay +MustBeGanja +MustKillBill +Musta +Mustachio +Mustamae +MustangYak1 +Mustangs +Mustard +MustardXD17 +Mustasurma +Mustekala +MusterShelby +Musto Task +Musty Ropes +Musty Sailor +MustyToofer +Musuwu +Mut3dHasselt +MutaNep +Mutants +Mutapets +Mutated +Mute Pker +Muteself +Mutilated +Mutsurini +Mutt a dile +Muttadale +Muttadiddle +Muttadude +Muttallica +Muugz +Muumipappa +Muunchyy +Muurxi +Muushuu +Muutz +Muws +Muy Booty +Muzbo +Muzi +Muziek Smurf +Muzket +Muzz +Muzzle +Mv P +MvP ov RnG +Mvk +Mvko +Mvp Scrub +Mvvs +Mw2 +MxMay +MxSloot +Mxb36 +Mxffin +Mxr +Mxteorites +Mxtta +My Damie +My Dark Hell +My Dark Soul +My Death Bed +My Demons +My Dont We +My Dumb Iron +My Faith +My Fantasy +My GF isMILF +My Gentiles +My God +My Iron Man +My Ironmain +My Ki +My Kill +My Kingz +My Limp GIMP +My Main Game +My Maine +My Mate Elm +My Name Vyga +My Pet Mocha +My Rng Ass +My Sana +My Secrets +My Ticks Now +My Ult +My pp stink +MyAssLucky +MyCatKillsMe +MyCtyNeedsMe +MyDuck +MyElyNow +MyFitPal +MyHandyMan +MyIiu +MyLastGo +MyLoveFaith +MyMercy +MyNAm3BubBA +MyNameIs +MyNameIsCole +MyNameIsKent +MyNameIsTina +MyNameIsTrev +MyOSAccount +MyPetRicky +MyProject +MyRifleMyGun +MyRight Nut +MySeed +MySkillsKill +MyStinkHurts +MyTakao +MyWanderlust +MyWyvernAlt +Myams +Myat +Mycreation +Mycreation1 +Mydlong +Mydragon8u2 +Myers +Mygary +Mygraine +Mykeh +Mylar +Myles +Myles_008 +Mylifeisless +MylilBrony +Mylle +Mylo +Mylo 7 +Mylos +Mylosas +Myndemo +Myoboku +Myosarcoma +Myoshi +Myotoxin +Myriadic +Myrm +Myron +MyronAynes +Myrupz +Mystearica +Myster +Mystery Btw +Mystery X +MysteryGifts +MystiCool +Mystic +Mystic Mak +Mystic Pizza +Mystic Voke +MysticChompy +MysticDrift +MysticErebos +MysticRiver +MysticStrega +Mysticpuffer +Mysticrobe +Mystics Main +Mysticvaa +Mystiic +Myth +MythCerix +MythCraft +Mythic +Mythic Hiero +Mythicat +Mythrin III +Myto +Myuf +Myuk +Mywa +Myz +Myzi +Mzaa +Mziy +Mzr +Mztar +N 10 +N 55 +N A l N E R +N E L L +N E N E +N Gallagher +N I GH T96 +N I N O X +N I S H +N ICK Y +N O B S Y +N U B U +N W M +N a t t z +N ang +N anko +N arb +N dejay p +N e a k i le +N e i l +N e0 +N iall +N ibbler +N ightgleam +N l C K O +N l E V E +N o m a d +N occo +N oggin +N u d +N uggies +N-J-R +N0 H34RT +N0 Invictus +N0 pid +N00biistyl +N00bslayer27 +N04me +N0B4Marri4g3 +N0Ballz +N0ID +N0LlMlT +N0OneCares +N0T HC +N0XPWaste +N0blelegend +N0llie +N0obalhao +N0rse_k1ng +N0sie +N0t Maxed +N0t special +N0tliketh1s +N0ul +N1 CK +N17 Jake +N1C3 +N1NJASK1LLZZ +N1ckai +N1cwho +N1nja +N1njaCat +N3XX +N3p +N3se +N3x +N4L +N4ruto +N4styNat3 +N7N +N8vy +N9NE420 +N9T7 +N9U +NABEEL RJ +NAGAKAMAL +NANORA +NARPslayer +NASDBOY +NASSERN +NASTY +NAVl +NB8K 2K13 +NBA +NBA NewMain +NBA Youngb0i +NC90 +NCG +NCG 2 +NCPS +NEBR0SKY +NECR0DANCER +NEEDAMETHYST +NEENEE +NEET +NEET forever +NELSONORS +NENOS +NEONiC +NEWBEYE +NEWFISHMATE +NEX IS WET +NEXFARMER +NEYOVIC +NFed +NHL Blues +NHrn +NIIXIIK +NINJABLEV1NS +NINJATMNT +NITR00 +NJC20 +NJWW +NKJ +NL Chronos +NL Gilbert +NLDeluXe +NLFreakky +NMM Jaoel +NMOS_giant +NMZLetics +NO 1s SAFE +NO CHlLL +NO FEEL +NO MlDS +NO N R G +NO PlD +NOAH +NOMETHESPORT +NOOOOOOOOOO +NORTHSEA +NOSTALGlA +NOTTDY +NOTaPancake +NOmki +NPC Healer +NPC Icedrake +NPYJ +NRA +NSFL +NSHN +NST Praise +NT FiSHvv +NT Y +NTBeerBandit +NTMR RADIO +NUEL +NULLI +NULLlN KUPPl +NUTSHOT +NVQ +NWHL +NWI 219 RAT +NY +NY C +NY G +NY x LEGiiT +NZ Dave +NZL +N_MB +N_other_day +Na Mn Or I +NaCl +NaCl Sprite +NaCl is salt +NaQ +Naaath +Naafiri +Naais +Naakkeri94 +Naakt +Naaon +Naautilus +NabD Rank 5 +Nabroleon +Nabshadow +Nabss +Nabua +NabyLad +Nach +NachB +Nachitto +Nacho +Nacho Alt +Nacho2030 +NachoByte +NachoDragon +NachoPapi +Nacht +Nachtkastje +NachuiTuda +Nadaa +Nadeo +Nader +Nadsage +Nadund +Naethera +Naftininkas +Naga +Naga Morich +Nagisa +Nags +NagyonJo +Nagyung +Nah0824 +Nahida +Nahiida +Nahkamestari +Nahuel +Nahyol +Nahyun +NaiiSha +Nailbox +Nailed Hard +Naimsen +Nainenoon +Nairda Niam +Nairda Nori +Nairino +Naisu +Najda +Nakal +Nakama +NakedTwister +NakednFeared +Nakke176 +Nakkee +Nakkesleijer +Nakkimauno +Naksitr6ll +Naku +Nakuz +Nakuz0r +Nalle Puh FT +Nallieheai +Nalsara +Nam +Namcel +Name +NameECJ +NameRjected +NameWasBannd +Named +NamedGenius +Namelessdude +Namelus +NamesAreMeh +NamesHisoka +Namine Silke +Namir +Nammer +Namuko +Nana +Nana Steel +Nanado +Nanciscor +Nancyy +Nander +Nandos +Nandos Man +NangMan +Nangdalorian +Nanimavi +Naniva +Nannertee +Nanno +Nannu Baba +NannyCam69 +Nanoh +Nanoman360 +Nanonymouse +Nanook IV +Nanoray +Nanotech +Nans +NansBeaver +NansCumTowel +NantaoL +Nanyts +Naoe +Naoe Y +Naoe Yamato +NaofumiLTU +Naoka +Naow +Nap Tackle +Napaaaaaaaaa +Napalm +Napanderii +Napettaja +Naphtic +NapkinFork +Napnapnap8 +NapoleanBra +Napoleon +Nappy Head +Napsutaja +Naqu +Nara ven +Naradas +Narbose +Narby +Narcan Saves +NardDog +Nareg +Narel1a +Narendradath +Narg +Nargarothian +Narked +Narkon +NarnodesNono +Narrative +Narry +Nartens +Narth Calior +Narthalion +Naru808 +Naruto +Narval +Narvalow +Narwallus +Narwhal1731 +Narx4 +Nas is like +Nasa +Nasaman +Nascar +Naseeph +Nashh +Nashluffy +Nashonic +Nashy +Naskarsdad +Nasko 07 +Nasper +Nasrullah +Nasseee +Nassim +Nast +Nastacov +Nastie +Nastik +Nasty +Nasty107red7 +NastyAss +NastyCasual +NastyDonger +NastyGarbage +NastyGeUsers +NastyV6 +Nasuuu +Nat Scheetje +Natalie +Natby +Nate +Nate Dogg g +Nate Joggers +NateDoge +NateStayLove +Natebroh +Natedog 1104 +Naternater +NatesOSRSAcc +Nath Meister +Nath btw +NathJeaL +Nathan +Nathan A +Nathan Lyon +Nathan Novak +NathanTurn +Nathandrthal +Nathanyuelle +Nathn +Nationwide +Native +Nato is Jake +Nato888 +Natoh +Natoroid +Natrox999 +Nats +Natsu +NattNub +Natte +Natte Dop +Natte Dream +Nattetid +Nattkungen +Nattmara +Nattraps +Natu +NaturalBeaut +Naturally +Naturally Me +Nature +Nature B0Y +NatureNymph +Naturealis +Naturejacks +Nauce +Naudra +Naught Good +Naughtpure +NaughtyPanda +Naukahtaa +Naukkiss +Nautis +Nauuyn +Navas +Navbrah +NaviRio +Naviaux +Navidson1 +Navn +Navraj +Navtik +Navy +NavyDD214RET +NavyLight +NavyPunk +Navyseals199 +Nawberry +NawtyMonkey +Nawus +Nax +Naxacid +Naxiius +Naxito +Naxos +Naxtzi +Nay RS +Nay0101 +Nayna +Nayrus +Nayrus Love +NazTehRpR +Nazgul +Nazty +Nbba +Nbcw +Nbsniper69 +Ncpure +Ncrr +Ne x is +Ne3po +Ne86 +Neak +Nealonl4 +Nealos +Neals +Nealvy +Neanderthal +Nearly +Nearomancer +Neatkii +Neav +Neb0lith +Nebb +Nebbo +NebbyGo2Bag +Nebezaidu +Nebijok +Nebrosky +Neccto +Nechromancer +Nechryass +Nechs +NechtKnecht +NeckBat +Neckbeardis +Necksnipped +NecroEric +NecrodedGSF +Necrokingns +Necromatus +Necromooser +Necronomist +Necrophorum +Necrosauruss +Ned1991 +Neddam +NederweertV2 +Neduks +Nedus +Nedved +Nedward +Neeby +Need +Need 2m +Need A Pint +Need Femboy +Need GP Now +Need Protein +Need Rogaine +Need Spoon +NeedInternet +NeedMoore +NeedPurp4Bed +Needs +Needs Coffee +NeedsADad +Needtomboy +Neeech +Neefey +Neeisnet +Neekkoco +NeekoNeekoNl +Neekomata +Neekss +Neelen +Neems +NeetScape +Neetman +Nefarious fe +NeferSeti +Nefereous +Neffiz +Neg14 +NegAttiveI +Negan +Neganeogami +Neghed +Nego Baby +Negrong +Nehxy +Neil +Neilthedead +Neintein +Neitiznut +Neitiznut Jr +Nej tak +Nejvalt +Nejvash +Nekalbink +Nekkopanda +Neko Inori +NekoSayNyaa +Nekomata Nia +Nekomimi +Nekromant Cz +Nekrukeisari +Nelaimingas +Neleron +Nelhium +Nelkirr +Nelli Matula +Nelliell +Nellysan +Nelox +Nels0N +Nelsi +NelsonRosea +Nelsonater +Nelvian +Nelx +Nelybynature +Nelzhar +Nemaksciai +Nemba +Nemerrr +Nemesis +Nemesis2020 +Nemf +Nemijin +Nemipro +Nemisys +Nemj +Nemmo +Nemo +Nemo_o +Nemonia +Nemoven +Nenah +Nendou +Neng_Thao02 +Nengah +NeniHead +Nenio +Nentsukka +Neo +Neojoramony +Neon +Neon Christ +Neon Juan +Neon Slinky +Neon Volts +Neon xxv +NeonChilli +NeonGenxsis +NeonM1d +NeonO7 +NeonPaladin +NeonRhythm11 +Neonik +Neonke +Neopia +Neoplasia +Nephedes +Nephyrion +Neppe +Neptune169 +Ner +Nera Obuoliu +NerbBlaster +Nerbles +Nerbs +Nerd +Nerd Body +Nerd Owns +Nerd Stone +Nerda +Nerdbob +Nerdcore +Nerdier +Nerdpuff +Nerf Bowfa +Nerf Coffee +Nerf Th1s +NerfMePlz +NerfTG +Nergegante +Nergg +Nerio x +Nerithma +Nermzz7 +Neroxcen +Nerraw +Nershi +Nerve +Nerve Cell +Nesk +Nesquiik KlD +Nesretep +Ness +Nestedloops +Nesties +Nestl3 +Nestorianos +Nesuvarzytas +NetTrap +Netamu +Netanelba +Neteroem +Netgear +Nethada +NetherToxin +Netho +Netjes +Netmn15 +Neto +Nettipoliisi +NetturDab +Neturtingas +Neural +Neuro Lepsis +Neuro-Tomb +Neurologist +Neurophys +Neurovelho +Neut +Neutral Game +Neutralised +Neutrally +Neutronas +Nevar89 +Nevena +Never +Never Die113 +Never Spoon +Never die +Never2Clever +NeverAssume +NeverBudge +NeverEnding +NeverFreeze +NeverGetRift +NeverGunaMax +NeverImprove +NeverLateWiz +NeverMoves +NeverMyFault +NeverQuest +NeverRespawn +NeverSailing +NeverSober +NeverTrading +Neverender27 +Nevermaker +Neverover +Nevi +Nevik94 +Nevinnn +Nevit +New Monkey +New Tooka +New journey +NewAgsWhoDis +NewBoy4321 +NewDad +NewFavorite +NewHobby +NewMobWhoDis +NewPlayerx13 +NewToBossing +NewWrldHodor +NewZealands +Newb +Newb Ranger +Newbillnye +Newby +NewcastleFC +NewfieTinMan +Newfiebanger +Newguy2003 +Newleesh +Newlut +NewrockkuOS +Newst0nekid +Newt Jacuzzi +Newtman907 +Newton 1 +Neww Zealand +Nex Afg +Nex FFA King +Nex Is My X +Nex Minion +Nex Myself +Nex leecher +Nex1s +Nex2169 +Nexarion +Nexcellent +Nexeiy +Nexfinity +Nexgen +Nexi +Nexil +Next +Next Day +NextPet +Nexus Sire +Nexx +Neya +Neyburr +Neye +Neyes +Neyugn +NezFix +Nezqi +Neztea +Nezuk o +NghtPnda +Ngis +Ngyessiree +Nh3r +NhaleXhale +Nhan +Nhest Cutter +Nhimzo +Nhouse20 +Nhyrenn +Ni +Ni ke +Niahl +Niall x +Niawag +NibblyTitter +Nibbyus +Nibexx +NiblaNoss +Nic +Nic Machine +Nic Nasty +Nic Nerc +Nic co +NicMachine +Nicannand +Nicao Beck +Nicashi +Nicathan +Nice +Nice Adept +Nice Caulk +Nice Iron +Nice Nice +Nice One +Nice Peaks +Nice Pets +Nice try guy +NiceGuy Edy +NiceGuyEddyy +NiceMarkMark +NicePotatoes +Nicely High +Nichohls +NicholasRage +Nicholaswei +Nichy +NiciValbuena +Nick +Nick Grows +Nick Ints +Nick Lopes +Nick Sellers +Nick X10 +Nick0hwolf +Nick1234101 +NickChubb24 +NickReady +NickScape +NickSpoof +NickTSMITW +NickVo +NickaClassic +Nickernack55 +Nicki +Nicki Menage +NickisBackyo +Nickk +Nickmitz23 +NickmyKnack +Nicknao +Nickolai Lol +Nickool4 +Nickos +Nickoss +Nickoudbier1 +Nickroo1234 +Nicks +Nicks OSRS +NicksNipples +NickyPunky +Nickynice23 +Nickyy +Nickyy G +Nico +Nico BE +Nico Le Chef +NicoFreakOh +NicoIas +NicolaSturge +Nicolai +Nicolaj +Nicolas +Nicoo +Nicophilia +Nicsyth +NidaNewName +Nidalee +Nidgen +Nidh +Nidhogs +Nidk +Nidmann +Nidoking110 +Nidraugas +NieI +Nief +Niefable +Nielaahh +Niels1608 +Nielscorn +Nielsen9312 +Nielssjeee +Niely +Nieman +NietzscheJR +Nieve +Nieve Hamtaa +Nieve Rivers +Nieve Task +NieveIrwin +NieveIsBad +NieveIsThic +NieveMeAlone +NieveTitties +Nieves +Nieves Bean +Nieves Boob +Nieves Butt +NievesDead +NievesThighs +Nifelhiem +NifkeCove +Nifty Gifty +Nigel +Nighlist +Night +Night Elf45 +Night Shade +NightNurse +Night_Furor +Nightbass +Nighter +Nightmare +Nightmare CX +Nightmare028 +NightmareSHW +Nightolas +Nights9 +Nightsharp +Nighttman +NightxxShade +Nightz Watch +Nihilismi +NihilistScum +Nihplod +Niihilism +Niiick +Nijah123 +Nijn +Nik-fil-A +Nikab +Nikco +Nike +NikeOnMyFeet +Nikez +Nikit +Nikkerpoo +NikkiJaxx +NikkiQT +NikkisDD +Nikkisaur +Nikko +Niknea +Niko Solo +NikolasOG +Nikoo +Nikronic +Nikskill +Nikumei +Nikun +Nikz +Niley +Nilitsu +Nilpferd +Nils +Nilwh +NilzZ +NimaNaruto +Nimajineb +Nimble Snail +Nimbubu +Nimex +Nimismies2 +Nimlasher234 +Nimloth_666 +Nimma Crew +Nimmongel +Nimrod +Nina +Nina Dobrev +Ninanunana +Nine E L +NineTs +Ninef +Ninesax +Ninetails +Ninetales4 +Ninevolz2 +Ninfia +Ningaa +Nini N Kiki +Ninja +Ninja Bamsen +Ninja Cow Jr +Ninja Rasta +Ninja1978 +Ninja66 +NinjaNoodles +NinjaPunch72 +NinjaSpeed +NinjaTurt +Ninjaloff +NinjasDark3 +Ninjee xo +NinjerNick +Ninjunzo +Ninjymate +Ninook +Ninorc +Nintendogz +Nipaahv +Nipes +Nipitipi +Nipp +Nipp-on +NippleSundae +Nippppppppee +Nipps89 +NipseyHpvm +Niseraru +Nishax +Niskha +Nismo +Nismo Ranqe +Nisramont +Nissan +NisseIadden +Nissmo +Nistipata78 +Nitefall3n +Nitepearlz +Nitetrip +Nith +Nithe +Niton +Nitro Crate +Nitro Dax +Nitro Rng +Nitro306 +NitroCrate +Nitroalkenes +Nitrognhorse +Nitros +NitrosOxide +Nitrous Bro +Nitsch +Nitsuj42 +Nitt +Nittany +NitwitSchool +Niukkis +Niva +Nivex +Nivory +Nixby +Nixi_NL +Nixiro +NixonsJowls +Nixvet +Nixxay Iron +Nixy +NixzTez +Nizqa +Nj0y +Nkpi +NlCK +NlCKT +NlLREM +NlMBY +NlSO +NllCK +NllL022 +NlppleX +Nmf Euphoric +Nmofm +Nnavs +Nnoitra +No 1 There +No 99s btw +No Arcane No +No Autoclick +No Basic +No Death Tax +No DexL +No Diff +No Emphasis +No Fear X +No Fkeys +No Honor Yah +No Joggers +No Kwuarms +No Legs Lazy +No Logic +No Lucko +No Means Ya +No Meds +No More Bugs +No Much Bulk +No Normies +No Old +No Pets +No Rationale +No Rugrats +No Saint +No Senpai +No Sleepin +No Souldier +No Splits +No Submit +No Tax Due +No Tbow Andy +No To War +No Xp Waste +No Zily Luck +No ah +No toleranss +No ur roll +No0dlehead +No53 +No7 +NoAntiVenom +NoBankIRL +NoBanksNoThx +NoBans +NoBp +NoCreamy +NoDayMercy +NoDealEU +NoDropForMe +NoDurex4you +NoEdge707 +NoFame +NoFang Wizza +NoFapp +NoFlipZone +NoGoodSkills +NoHelp +NoHesitation +NoInferno +NoIronManBTW +NoLife4Him2 +NoLifeCue +NoLifeLevi +NoLifeMain +NoLifeMcgee +NoLifeScape +NoLifeSincRS +NoLiferSoul +NoLimit +NoLootBag +NoLootNoWoot +NoLove +NoLuck Mario +NoLuckBearku +NoMarinero +NoMercyUIM +NoMo +NoMore +NoMoreTrades +NoNumbers4me +NoOlmletSig +NoPainNoMain +NoPolnT +NoPrims2k_kc +NoPurpleAku +NoRNGsmalle +NoScyOrStaf +NoShit +NoSprayNoLay +NoStore +NoStrategy +NoStress2Day +NoTangleroot +NoTank4U +NoTexture +NoTradeBrad +NoTradeForMe +NoVa ITI +NoVow +NoWaR +NoXpWast3 +NoXpWasted +NoZulrahIM +No_Dumping +No_Remedii +Noah +Noah Dinnae +Noah G +Noah Luvs U +NoahB +NoahGriffith +Noahfireball +Noahs +Noam Chompy +Noamonts +Nobber +Nobbys +Nobelanerr +NobilityTorn +Noble +Noble Gage +Noble Oats +Noble Sticre +NobleCorey +NobleVespo +NoblesForRec +Noblood +Nobody Good +Nobodyz +Nobrain +Nobu +Nobudy +Nobularlol +Nocando +Nocarred +Nochill +NocnyKoszmar +Noco +Noctivagous +Nocturnal +Nocturnal RS +Nocturnal024 +NocwocDaLord +Nodens +Nodonge5 +Nodorcro +NoeLT +Noeka +Noem +NoemMeJePapi +Noexi +Nofolkn whey +Nogal +Nogi +Nogoodnms +NoiScape +Noig +NoirSandy +Noiserv +Noisy +Noisy Luigi +Noita-akka +Noith +NoizRock +Noizex +Nokil +Nokiny +NolanAlpha +Nolch +Nole Jr +Noley +Nolifepvm +Nolifer +Nolifer 28 +Nolly +NoloadRIP +Nolungs +Nolzeyy +Nolzzz +Nom C +Nom Ruby +NomCensurer +NomNomSoulz +NomadForseti +NomadRek +NomadsLife +Nommmy +Nomoenoobs +Nomonater +Nomskichooo +Nomtiq +Non5ens31 +Noname Nate +Nonc +None +None Feared +NoneOther +Nonke +Nonni +Nonplayer +Nonreal +Nonsense +Nonstop +Nonvalid +Nonwestlee96 +Nonwitzki +Noo Promises +Noob +Noob Man +Noob N Smoke +NoobHey +NoobPkedMe +NoobWrecker +Noobacleese +Noobalhao +Noobe15 +Noobest +Noobicidal +Noobike00525 +Noobirini +NoobishAct2 +Noobs +Noobsscape +Noobtyle +Noobtype +Nooby +Noodle +Noodle Dude +Noodle Me +Noodle Soups +Noodles +Noodlike +Noodz +Nooki +Noolbort +Noon +Noons +Noonshake +Noopi757 +Noorbee +Noorden +Noosii +Nooster +Noot +NopePope +Noportals +NorCalGreens +Nora Flora +Norbet +Norbsi +Norchis +Nordas +Nordfeir +Nordicade +Nordnec +Nordo +Nordstrand +Norfok +Norge +Norhig +Nori Nitsuj +Norilsk +Norimasa +NormHadAFarm +Normabel +NormanBates +Normans +Normie +Normie Main +Normie helm +NormieDalzii +NormieFYI +Normies +Normy Narked +Norn +Norqe +NorrSken +Norska +Nortenosk +North +North No 2 +North Rmmbr +North1ane +Northerly +Northfork +Northic +Northnewfy +Northrod +Northtoeast +Northxy +Norti +Norton +Norton_Gman +Nortoon +Nortron +Noscythe bad +Nose +Nose Beerz +Nose Puncher +NoseBeersies +Nosetkl +Nosevesey +NosferatuBoi +Nosni +Nosnorb +Nosorow +Nost4lgia95 +NostalgiaNp +Nostalgic +Nostalgic00 +Nostalgimon +Nostos +Nostrily +Not 0A +Not A Lover +Not A Robot +Not Bad +Not Brizz +Not Carlyle +Not Cynical +Not Dzop +Not Eternal +Not Flicking +Not Frac +Not Gaming +Not Ice +Not Internal +Not Ketho +Not Level +Not Lime +Not Lorppe +Not Med +Not Mesijus +Not Mikers +Not Muppet +Not Muppz +Not Panik +Not Perry +Not Rudy +Not Ryu +Not Salinger +Not Schuproo +Not Sharp +Not Soft Yet +Not Sotetseg +Not Tanzu +Not Tarczon +Not Tarny +Not Twistie +Not Vaxx +Not Yakosu +Not Your Nan +Not ZB +Not Zema +Not a Fan +Not a UIM +Not all +Not an elf +Not enough +Not even Dan +Not main btw +Not rn Babe +Not trivial +Not wow man +Not-afraidem +NotAFKenough +NotAJ +NotALurer532 +NotASkrub +NotAStreamer +NotAlright +NotBiabanana +NotBot893294 +NotEp3 +NotEvenRare +NotGilthresa +NotHCJames +NotKD +NotKailey +NotKnowMadss +NotLefty +NotMatched +NotMaxinSoon +NotMinty +NotN07NeMo +NotNecro +NotPker +NotPlateWolf +NotReady +NotShaneska +NotSoCasual +NotSoHCZoro +NotThaFather +NotUIM +NotUrAvgTim +NotUrBisnis +NotValidName +NotYerGuyPal +NotaCola +Notanedgepkr +Notanoob12 +Notfatprism +Nothard +Nothin Lasts +Nothing +Nothing Sold +Nothing2die4 +NothingMate +NothinqThere +Notjoeybloom +Notlayla +Notmyrsname +Notori +Notorious +Notorious N1 +NotoriousALB +Nottarg +Nottingham +Notutoring +Notwind +Notz +NouGIM +Nour +Nouvelle Vag +Nov +Nova +Nova Lova +Nova NK +Nova Rez +Nova X1 +NovaDragonX +NovaNovNov +NovaNova_v1 +NovaaDay +Novacult +Novahearts +Novahria +Novalisky +Novamus +Novaqueen +Novaspell +Novelled +Novem +November Air +Novesey +NovicePlayer +Novist +Novizy +Now Boarding +Nowa +Nowa Lyfe +Nowlan2 +Nowoxifer +Nowt +Nowuh +Nox Irea +Nox1de +Noxai +Noxeek +Noxelder +Noxia +Noxied +Noxif +Noxifer Nino +Noxifer Noob +Noxifers +Noxiti +Noxitrall +Noy rs +Noys +NozFox +Nozel +Nozzie +Nozzles +Npc Contact +Nppb +Npzu +Nrsa +Nrse +NsG Flames +Nshit +Nsns khalifa +Nsoak +Nsor +Nssc +Nstfu +Nt0y +NtQuiteRamb0 +Ntsf +Nu ff +Nub Cakes +Nub Cape +Nub Die Plx +Nub II Elite +Nub at PvM +Nubby +Nubby Nubnub +NubbyOtter +Nubciclez +Nube +Nube101 +Nubje +Nubslie +Nubthhh +Nubutraum +Nuc1ear +Nuck +Nuck Formies +Nuckie34 +NuckinPhutty +NuckkinFuts +NuclearDron3 +NuclearShift +Nucleons +Nucleotide +Nucu +Nue +Nuffedyr +Nuffers +Nuffyz +Nuffz +Nuge Hews +Nugget +Nugget Farm +Nugget8453 +Nuggo +Nugs +Nuhapiippu +Nuigaia +Nuirokay +Nuk3rO +Nuke +Nuke Rofl +NukeDuke98 +Nukkumassa +Nukooa +Nukster +Null God +Null Quiet +Null Scaper +NullObject +NullTalisman +Nulliko +Nullish +Nullly +Nuloh +Nulsen +Nuluki +Num1 StepSis +NumTaker +Numazu +Numb God +Numb Too +NumbButWhole +NumbaWanGIM +Number +Number Forty +Number is 47 +Number1 +Number1 Bass +Numbermatch +Numel +Numenor21 +Numerater0 +Numerikaali +Numidium +Numinious +Numismatist +Numpad +NunWithAGun +Nuna +Nunac +Nunc +Nuno +NunsRtight +Nunsbox +Nuoli Z +Nuori Karhu +Nuparu22 +Nupayne +Nupiso +Nuqubba +Nuqx +NuranJeezes +Nurco +Nurdal +NurgleBurgle +Nurrminatorr +Nurse +Nurse Turbo +Nurselie +Nursering +Nusky +Nussi +Nust +Nut Nut +Nut on Nieve +NutStains +NutZak +Nutgood +Nutipaa +Nutjes +Nutrino +Nutta +Nutu +Nutviper +Nutwic +Nuubby1 +Nuubi85 +Nuuh +Nuuhi +Nuux +Nuwanda +NvMe +NvMy +NvMy Madness +NvUs +Nvh +Nvidas +Nvious7 +Nvr Ironman +Nvsh +Nwkz +Nxcv1 +Ny e +NyThinIsFine +Nyaa +Nyalesh +Nyam2 +Nyannoid +NyarkThunaki +Nybocs +Nydarb +Nydde +Nydloh +Nyesqui +Nyholmeen +Nyk X1 +Nykat +Nyler +Nymlonn +Nymph +Nyppe96 +Nyquistt +Nyranger99 +Nyraxion +Nyrkki +Nystuen +Nythan +Nythos +Nythsama +Nytrate +Nytrogen +Nyula +Nyx Avatar +Nyx296 +Nyx_TrueShot +NyxxiePixxie +Nz Str +Nz Boy 96 +Nz Str +Nzfisher +NzhiaT +Nzpkers +Nzz +O C M W +O E M +O G Herbs +O G RasTa +O K E Y +O L D Z E +O Lewis +O N W +O O 9 +O O O O O O +O Rodrigo +O TUGA LINDO +O X Y G 3 N +O ctopus +O dhran +O hio +O l m e w +O m a r +O o g a +O s s e +O stake +O-Scape +O-Six Newb +O-SobaMask +O0BY +O5O5 +O64 +O7 offroad +O93 +OBD2 +OBGYN doc +OBKush69 +OBLV Empson +OBLV KKRKAT +OBLVPIPEBOMB +OButterstick +OCBP +OConnell +ODarnUFail +OEM +OFFS NFS +OFS I +OG AlanEspo +OG BlowsCOX +OG Boney +OG Ezena +OG Germ +OG Greenery +OG H4zed +OG Horizon +OG IronAaron +OG K1ng +OG Kassu +OG Kenobi +OG Mr Crispy +OG PvMer +OG SUOMINEN +OG Sage +OG Soul +OG StrongBoy +OG Totti +OG not OJ +OG-Bebardo +OG2 +OGBloodFam +OGJezus +OGKingRavenZ +OGLman416 +OGRockstar +OGTeacher +OGThicPickle +OGWhitePanda +OG_Westside +OH NO PLZ +OHC +OHP +OH_mes +OHv3rdose +OINK OINK XD +OId Nite +OJ AVENGER +OK Thug +OLD MAKAVELI +OLUTMIES +OLY Krzanich +OLlVER +OMEGAPEG +OMG U DID IT +OMG a GIM +OMGstepbwana +OMNIV0RE +OMX +OMYLANTAAAA +ONCES +ONDERBOKSEM +ONE EYE Q +ONEBIGJOKE +ONEM0REBEER +OON HUMALASA +OOOGAABUNGA +OP Yoyoei +OPEN NA N00R +OPIronman +OPName +OPP2 +OREG0N +ORLZU +ORlCHALCOS +OS Anthony +OS BAKA +OS Badger +OS Flexin +OS Gdtn +OS Glory +OS Hadley +OS Iron Life +OS Jordan +OS Lou +OS Maroko111 +OS Masochist +OS Nat +OS Reecy +OS Versace +OS Weesh +OS dah +OSBudknight +OSBug +OSCannabis +OSCastleWars +OSColbyStock +OSGingerkiin +OSGraham +OSGrindscape +OSHH +OSRASS +OSRS +OSRS Brody +OSRS Cyze +OSRS DANI +OSRS Denmark +OSRS Dresse +OSRS Hostage +OSRS Jim +OSRS Joshua +OSRS Keegs +OSRS Moey +OSRS Rapaaja +OSRS STIMPY +OSRS TOBI +OSRS Tired +OSRS Zezima +OSReaper +OSSD +OSSoulwars +OS_AndyB +OS_Jazzy +OSzerox +OTF SPRINKLE +OUTSlDERS +OWE N +OZANN +O_o +OachKatzal +Oak Cliff +Oak Tree Ted +Oaonui +OasisRS +Oathbringer +Oathh +Oatmels +Oatre +OavTXXrC2Bc +Ob1tuary +ObZenpai +Obama +Obama2014 +Obanana +Obby +Obby Apples +Obby Cam +Obby Cape +Obby z +Obby200 +Obedar +Obelisks +Oberschicht +Obese +Obese Scrub +ObeseMaurice +ObeyBdubb +ObeydaWalrus +Obfuscatiion +ObiHiGround +Obib +Object62 +Objection +Objektas +Objektijuht +Oblitergator +Obliticks +Oblivion +Oblodzisz +Obloid +Oblv +Oblv Jass +Oblv mobi +Obnoxious +Oboi +Obos +ObscureFruit +ObscureHeart +ObscureLogic +Obscuremelon +Obsel +Obsidian +Obsidian222 +Obtain Shade +Obvious +Obviouseboyz +OcaJomba +Ocachobee +Ocara +Ocara Debrew +Ocarious 2 +Occ0x +Occcy +OccrumsRazor +Occulent92 +Occupation +Occupational +Ocean +Ocean Fog +OceanMachine +Oceanside +Oceanux +Oced +Ocellari +Ocelvon +Ocg +Och +Ochen +Ochit +Ochrie +Ockult +Oclusvision +Ocra +Ocst +Octagawn +Octane07 +Octane09 +Octanes +OctarineJake +Octave +Octavia +Octet +October +October 12th +Octoberain +Octopossy +Octoppus +Ocuflox +Ocular Rift +Oculist +Ocyd +Odang +Odawg121 +Odd Focus +OddPhallus +OddSaus +OddSnipa +Oddjob46 +Oddloop +Oddni +Odeee +OdenKozuki +OdensWinterG +Odeon +Oder +Odezt +Odin +Odin Slayin +Odissious +Odiums Champ +Odlaw +Odonodb +Odophru +Odors +Odssy +Odsza +Odyssey Fe +Odyssey310 +Odysseyyy +Oenhausen +Oenonymaus +Oepeloetje +Oepsie +OetOet +Oetje +Of The Rune +OfThePirates +Off Pace +Off Rate +Off a Bar +OffMyChest +OffPeesh +Offer +Offering +Offers +OfficerTFist +Offka +Offlime +Offret +Offset +OffsetPaul +Og Voldemort +OgAcco +OgChrisCudi +OgDankRiddim +OgHood +OgSephiroth +Ogazumu +Ogg25 +Ogisek +Ogkek +Oglong King +Ogmj +Ogopogo5000 +Ogre +Oguussie +Oh Bee One +Oh Billy +Oh Canadian +Oh Daddy Yes +Oh Edgeville +Oh Gzuss +Oh Hi Marc +Oh Im Ben +Oh Its Toast +Oh No Oreo +Oh So Alone +Oh Tylor +Oh Vacancy +Oh sh +Oh4Sure +OhDannyBoii +OhEmGe +OhHaiMark +OhHeyGrant +OhIScott +OhItsMatt +OhJezuz +OhLookABot +OhManOhJeez +OhMyJosh +OhMyShoulder +OhNo +OhNoMyHymen +OhTurtle +Ohbi +Oheck Im Fe +OhhCaleb +OhhMikey +OhhTiS +Ohio +OhioTexas +Ohlander +Ohm Calvin +Ohm Free +Ohpiate +Ohseeya +Ohtoodles +Oi +Oi Matey +Oi You +Oie +Oifey +Oij +Oikeisto +Oikis +OilHawk +Oiler1k +Oilertay +Oilux +OilyMeat +Oinky +Oishii +OisnesA +Oispa +Oispa Kaljaa +OjibweJohn +Ojigkwanong +Ojman +Ok Bud +Ok G +Ok Jose +Ok a y +Ok-sail zip +OkYh +Okadolf +Okageo +Okaiko +Okay +Okay Mommy +Okay Papi +OkayCCal +OkayTwilly +Okeechobee +Okeydoke +Okino +Okke +Oklahoma Rat +Oksa +Okupant +OkzobRS +Ol Mucker +Ol Salty Dog +Ola Nordmann +Olajuwon +Olav Jr +Olav2002 +Olaveraaa +Olaviitsio +Olbyy +Old 9m9a9 +Old Abe 101 +Old Anao +Old Beer +Old Bill +Old Birdy +Old Boy +Old Champ +Old Dabs +Old Delf +Old Dry KBAC +Old El Paso +Old G ordao +Old Greggg +Old Jedi +Old Lancer +Old Man Bob +Old Man Cris +Old Man Rabb +Old Maxie +Old Mog +Old Monkey3 +Old NlCO +Old Nutbag +Old Olorin +Old Pixels +Old Player22 +Old Rangoon +Old Sbi +Old Schooled +Old Toaster +Old Yammu +Old man Kent +OldBae +OldBlueish +OldBruce +OldDirtyMan +OldFishLife +OldGamma +OldHitta +OldHulver +OldQwaltz +OldRzzlTrog +OldSkewlRS +OldSkoolKush +OldSteinlein +Oldbaldman5 +Oldburnzy +Olde +Olde Nite +Oldemark +Oldinsh +Oldizjr +Oldman +OldmanP +Oldmanhandz +Oldschool +Oldschools +OldskuleRS +Oldsusik +Oldtimate +Oldwhiteman +Ole +Ole IrIsh +Ole Martin +OleFrumpacus +OleMusky +OleStinkBait +OleTejas +Oleg +Olei +Olemand8 +Olen +Olen Iron +Olenpromees +Olertomb +Oles +OlesDpaul +Olette +Olfre31 +Oli +Oli xo +OliTheFarmer +Oliivi +Oliivi Rouva +Olimpus +Olios +Olivas +Olive +Olive You +Oliveinho +Oliver GIM +Oliver The G +Olivia +Olkikalsar +Ollie 01 +Ollivanders +Ollonjonny +Olly +Olm Alone +Olm Likes me +Olm Nut +OlmMyGod +Olmar +Olmek +Olmie Wolmie +Olminous +Olmlet +Olmlit +Olms +Olms Daddy +OlmsNutz +Olmsbish +Olmspetwhale +Olobor +Olrox +Olspa Rahkaa +Oltsu +Olvi +Olympic 33 +Olysian +Olze +Oma r +Omaci +Omar +Omar Kai +Omar Khaldun +Omar Uchiha +Omarinski +Omatunto +Omaxiu +Ome Sjors +Omega +OmegaBeast +OmegaRs3LuL +Omegathletic +Omegatron +Omen Forrest +Omena3 +Omerta +Omfg +Omhellz yea +OminousMan +Ommetje +Ommy +Omne +Omni +OmniRick +Omnicide97 +Omnient +Omnivaw +Omolon +Ompikuusi +Omroep Max +On Blocks +On Rate +On Steven Dr +On Tv +On a Bar +On the alt +OnAMeme +OnDeaTHrow +OnPoint +OnRedPanda +OnTheEdge +On_log_n +Onana +Onbekend +Onbekende +Once +Oncey +Onchune +Oncle +Oncle Jazz +Onderwerp +One Arm Chin +One Eyed Owl +One Lazy Cat +One Leaf +One Off +One Piece X +One Record +One United +One Wolf +One au +One life lad +OneBadNWord +OneBoxBox +OneCallBTW +OneClickMan +OneDayIs2Day +OneFalseStep +OneFive +OneForAll8th +OneFunkies +OneInchDong +OneInchPeen +OneJohn +OneLeg1 +OneLifeGiven +OneLostMain +OneManBand +OneManBucket +OneManNoob +OneManTeam +OnePac +OnePlus6Btw +OneProGoober +OneProNoober +OneRustyMan +OneSillyBoi +OneSnappyBoi +OneTera +OneTickAway +OneTickBrick +OneTickyBoi +OneWhoKnox +OneWish +Onebuc +Onedeadthing +Onehidefrog +Onelaughbob +Onesecafk +Onesome +Onetick +Onexia +Onfight +Ong Gia +Onidhre +Onika +OnionGoggles +Onism +Onitir +Onkdah +Onke +Onkel Dunkel +Onkelleif +Onkologen +Online Coach +Only +Only 1 Iron +Only Bussy +Only Crazy +Only Fight8 +Only Scotch +Only Victims +OnlyBans +OnlyBrand +OnlyChompies +OnlyCraig +OnlyDanss +OnlyDrags +OnlyFFAns +OnlyFans +OnlyFansss +OnlyFlies +OnlyGain +OnlyJars +OnlyJoel +OnlyJordann +OnlyKingKoob +OnlyKisses +OnlyKnuup +OnlyPepsiMax +OnlyRussell +OnlySolos +OnlyTheCold +OnlyWithTime +Onlyfans +Onlyfarm +OnlyyMike +Onn +Onno +Onoezeleer +Onoin +Onox +OnthatGrindd +Onu-sama +Onubis +Onus +Onuzq +Onxaba +Onya +Onyksi +Onyx +Onyx Farming +Onyxe +Onze +Oo Step Back +Oodenssiii +Ooelluoo +Oof Dankus +Ooft +Oofus +Ooga Booga C +Ooh Skill Em +Oohf +Oohfunkyme +Ooiboi +OokOokStrats +Ookfried +Ooktism +Oomp +Oompy +Oooh Baby +OopsiePoopsy +Oopsralla +Ooskabible +Oouu Weee +Ooyf +Ooze +Oozymooz +Op Closed +Op Wout +OpGetGood +Opa Bravo +Opa Snipes +OpaJei +Opacki +Opal Mafia +Opalfruen +Opatsuno +Opel Vivaro +Open +Open GL +Open osrs +OpenAI GPT4 +OpenTheTill +Openpuppygo +Opera +Operacional +Operetta +Opex +Opgezwolle +Ophelia +Ophelia Prim +Opiez +Opihr +Opinionated +Opitz +OpiumWard +Opkikkeren +Oponn +OppaSky +Oppai Heart +Oppai OwO +Oppanox +Oppheng +Opposite +OppositePoop +Oprego +Opreus +Ops +Opt +Optic +OpticAGS +Optical itch +Opticplex +Opticplex09 +OptimistLuke +Optimus +Optimus Pork +Optiver +Opts +Optus +Optyfen +Optyfengauww +Opus Deo +Opus149 +Opus22 +Opyomi +Oqagin-san +Oqlak +OracleOf +OracleStud +Oraclez +Orange1213 +Orangeboy333 +Oranje Panda +Oranqe +OrbWeaver +Orca +Orcanater +Orch +Orchazm +Orchid +Orchidzx +OreSpasm +Oreano +Oreeezy +Oregon Weed +Oreinstein +Oreo Empire +Oreo UwU +Oreo Wafer +Oreos +OreosInMilk +Oretizm +Oreton +Orezzer +Organic +Organic Hemp +OrganicOnion +Organics +Orgasmique +Orgo +Ori lion +Oriaks +Orienterare +Origens +Origin Puff +Original BA +Original Blu +OriginalGoat +Originaljim +Originexo +Orilion +Oringl Wafle +OriobanaOuhi +Oriole +Orioles +OrionDragon +OrionRenegd +Orjan +Ork Merchant +Ormi +OrngFish +OrngeManBad +Orodyn +Oronius +Orphaaan +Orphaan +Orphan +Orphan Annie +Orphan Soul +Orphan Twin +Orphan8r +Orpheus +Orpoerpo +Orrey +Ors striker +Orthago +Orthiss +OrthodoxJoo +OrthopodMD +Orvud +Oryx Aksis +OryxZebu +Os Him +Os Hitman +Os Rolex +Os SMDJ +OsBlackBolt +OsBrody +OsBudknight +OsDave +OsIronCrash +OsRs Vibes +Osav +Osbenji +Oscar Jacob +Oscarnight90 +Oscietra +Osdorp +Osetek +Osgu +Osgub +Oshawnasi +Osidric +Osimhen +Osiris +Osjuicey +Oskar +Oskar XVII +Oskari +Oskinathor +Osmo +Osrs Bane +Osrs Dimitri +Osrs Goku +Osrs Mistren +Osrs Woolley +Osrs2007 +OsrsBawlz +OsrsDavid +OsrsVibes +OsrsWiki +Osrshabibi +Osscar69 +Osseb +Ossi666 +OstBakarn +Ostengar +Ostentatio +OsteoSoon +Osteonics +Ostidecriss4 +Ostmumten +Ostracized +Ostrich +Osumi +Osvo1d +Oswaldorun +Oswin Oswald +Osxu47 +Osykoo +Osyrs +Otago Nz +Otakar +Otaku +Otan Olutta +OtarsBeast +Othantos +Othelllo +OtherJackets +OtherWize +Otho +Otomycosis +Ottarl +Ottchy +Otter +OtterMG +OtterMan +Otto +OttokarIII +Ottoman1907 +Ottwanbre +Ottzor +Otyugh +OuchIFarted1 +Oucho +Oud Nieuws +Oudenophobic +Ought +OuiDaddy +Ouija +Oukashi +Oulusta +Oumaji +Oumarou +Oumu +Ounaaja +Ouncie +Our ClapTrap +Our Kid +OurLordAllah +OurPage +OurTbow +Out Of Herbs +Out of Town +OutOfBreath +OutOnBail +OutR +Outbid +Outblasted +Outblasting +Outbox +Outbreak46 +OuterBodyXP +OuterShock +Outgrinded +Outie +OutlawBTW +OutofQontrol +Outofcontrol +Outohere +Outperform +Outplayy +Outra +Outs +Outsider058 +OutsidrR +OuttaThePan +Ouze +Ouzi +OvO +Ovaryacted +Ovaryacting +Ovela +Oven Dish +OvenGold +Ovenschotel +Over +OverRoid +Overburner67 +Overcame +Overclockers +Overdose1911 +Overhand +OverkillWill +Overklokkd +Overlegen +Overload +Overload_inc +Overloader +Overlordnick +Overmind +OverpowTV +Overprepared +Overrated +Oversight +Overspan +Overspec +OvertPyro +Overtaxed +Overthinker +Overtus +Ovid +Ovl +OvrLrd Zaros +Owed +OwenFever +Owip +Owl Full +Owl MD +OwlMyLove +Owlea +Owlpeth +Owlson +Owly +Own Risk +Own Skillz70 +Own617 +Ownage +Ownd +Owned +OwnedByMK +Owner Previn +Owning +Owning4babes +Ownsz +Ownt +Ownyouall6 +Owusu +Owwi +Ox Prez +Ox0 Ko0ol O0 +Ox310 +OxStache +Oxct +Oxcy +Oxeon +OxideIon +Oxidising +Oxidizing +Oxiduck +Oximas +Oxit +Oxium +Oxjenks +Oxoi +OxyCottN +OxyDream +Oxycotton +Oxyoxyoxyoxy +Oyrn +Oyster +Oyster37 +Oyugock +Oyvin +Ozaiii +Ozak +Ozcred +Ozeana +Ozenc +Oziarch +Ozin +OzirisRS +Ozium +Ozmone +Oznerbon +OzokuLight +Ozuhan +OzyMex +OzzMate +Ozzb0 +Ozzerro +Ozzie +Ozziemate +Ozzio +Ozzy +Ozzy Hobbit +Ozzykye +Ozzys +Ozzzyy +P 0 W N E D +P 0 E F +P 0 R G I E +P A M K A +P A P Z +P A R N Y +P DIRTY SODA +P EDRAO +P Eng +P I T +P K +P O L I S H +P O T A T O +P O V I +P Purts +P R O X +P R S +P V M Lew +P W A Y +P Y R O +P a n x o +P eachy +P erfect Ten +P h Z o r o +P i +P ix +P ixe l +P o z e +P oH +P ockets +P r o g r am +P udding +P ure +P uss Wizard +P00ksalukes +P0CKETPUSSI +P0ES +P0PE +P0RKB0I +P0ST HUMAN +P0TIONS +P0TTER +P0TUS +P0ddy +P0nti4c +P1CC0L0 +P1CK3R1NG +P1Hat +P1SSBANDIT +P1ZZA EATER +P1ZZY +P1ckleR11ck +P1ssDr1nk3r +P1stols +P1tts +P1zzaTheHutt +P1zzaa +P2Chill +P2D2 +P2P Race Car +P2w Scape +P3C +P3RKELE +P3RLICH +P3RMMUT3D +P3T3 IS G0D +P3TAR +P3aceful +P3loce +P3rcy +P46 +P4CK +P4DLA +P4RKER04 +P4cH +P4sk +P5ythix +P6D +P7DRO +P9 +PA N I C +PACK WATCH +PACKETLOSS +PACTV +PALAK1KO +PALL3N +PALSAM +PALSANMAKI +PANTY DROPER +PAPA +PASTORIKONE +PATPATMAX +PATRlOOT +PAUL +PAULWALKER +PB Barbie +PB Dauntless +PB J +PBT Yumi +PBTM +PBnJ +PC PrincipIe +PC0TE +PCCZ +PCDO +PCE +PDGA +PDizzleworth +PE strategy +PE3ST +PEAMINlSTER +PEARSON92 +PEC Zwolle +PEEKYNUMBER1 +PEEinAcup +PERMA +PERSE +PET3R +PET3R PAN +PETEAIR +PF Killaz +PFOF +PFalciparum +PG MAIN +PG-13 +PGA_Pope +PGMid +PGmeupe93 +PH1SH3DB4N +PHGomes +PHLP +PHURY +PIAN0 +PICC +PIITAA +PING +PINKYxBRAIN +PITFIGHT +PJ Salt +PJRovers +PK NOOB BR 2 +PK Shark +PKTHEOTHER +PKing +PL4T1N4 +PLANET SHlT +PLAYER827324 +PLAZID +PLSDONTPLANK +POGPOGPOG +POGvM +POMP3Y +PONYRIDER73 +POTTER +POTUS DJT +PPale +PPorappippam +PQMF +PQWNEM12XXSS +PRADA +PRAISE +PRAISE FOOT +PRAISEHELIX +PRETTY +PREW0RKOUT +PRIM0B0LAN +PRIZ0NM1KE +PRODaintOFFu +PRlNCEE +PSMark +PSO Pokie +PSRB +PSTjager +PSY OPERATOR +PSacz +PTKNT +PTMN +PUBG +PULL +PULL A GLOCK +PUNANYCEZZ +PUNANYMASSIF +PUPPY SIT +PURP xx +PURPLE MAN X +PUSHUPS +PV60 +PVM PLUS PVP +PVM Zem +PVM lifee +PVMGrim +PVMramranch +PVPJACKUS +PWNJoLee +PWNl +P_rple +PaIe Nimbus +PaIm +PaJau +PaPaSaucee +PaPePiPoPuPy +PaR0 +PaShango +PaTeraNauu +Paaaants +Paaatriick +Paarse Kat +Paarty +Paatse +PabIoEscobar +Pablana +Pablo Q +PacDan +PacYakJack +Paca +Pace +PaceYourself +Pacellino +Paciar +Pacifico0ler +Pacifist +Pack +Pack Yarack +PackAnother1 +PackYakistan +Packapunchd +Packers +Packers Ammy +Packfan35 +PackingCope +Packmanjr +PacksOfBagel +Paco 41 +Pactii +Pad of Note +Paddy Simcox +Pademelon +Padge +Padraig +Padrew +Paduann +Paehkisfe +Paem +Pafffy +Paffio +Pagan +PaganFox +PaganWish +Page +Pagman73 +Pahapukki +Pahizz +Pahys +Paid 4 +Paike +Pain deliver +PainInTheAx +PainRain +Painb0ws +Painovoima +PaintBoxx +Painta +Painted +Painz Wrath +PairODocks +Paixo +Paiyrd +Paizuri +Pajaaay +Pajama0sam +Pajaripipari +Pajita +Pakaika +Pakanajumala +PakasteOlut +Pakford +Pakmaniac +Pakr04 +Palabutoh +Palad1um +Paladijn Mb +Palapak +Palataan +Palatro +Pale +Pale Marble +Pale Player +PaleCocoon +Paledeano +Paleek +Paleek sucks +Palenaatio +PaleoRanger +PalestineHC +PaliRebel +Paliperidone +Paljad +Pallas +Pallas Cat +Palle Panik +PalliJarn +Pallihintti +Palllister +Pallof +Palmboom +Palmboom95 +Palt +Palworld CEO +Paly +PamPams +Pamdora +Pamela Isley +Pampas +Pamz +Pan Biceps +Pan Jawel +Pana Sicknez +Panacea +Panal +Panarin +PancakeOSRS +Pancaker +Pancakey +Pancukeshi +Panda +Panda Godz +Panda Pride +Panda Rua +Panda Seany +PandaBier +PandaBrommer +PandaKIKI +PandaMan +PandaMcfanda +PandaPowa +Pandasadge +Pandaux +Pandaz +Pandeh +Pandemicbowl +Panderal +Pandiman +Pandini_O +PandorazBox +Panelka +Panera +Panesii +Panette +Panferno7 +Pangolins +Pangs +Panic +Panic King +Panic Papi +Panic Switch +PanicThenRun +Panicupdate +Panini +Panixate +Pankekee +Pankki on +Panky +Pannu +Pano +Panoople +Panorramix +Panqueques +Pans_Gaming +Pansendoras +PansophicaI +Pantaloon +Pantelic +Pantera1230 +PanteraWalk +Panthalassa +Panther_Cap +Panties D0WN +Pantix +PantlessDuck +PantsShitter +PanzerMarkV +PaoZi41 +Paoul +Pap Smoke +Papa +Papa Beat Me +Papa Beer +Papa Chibs +Papa Falco +Papa Glock +Papa Hitman +Papa John +Papa Kev +Papa Peck +Papa Penguin +Papa Raniel +Papa Rook3 +Papa Scape +Papa Shaydee +Papa Sheek +Papa Snacks +Papa YY +Papa Zuk +Papa jinx +Papa tim +PapaCart +PapaFozzy +PapaJohn +PapaJoyce13 +PapaMoxie +PapaParsley +PapaSarducci +Papabeer +Papagecko +Papaija +Papalotee +Papapa +Papaya +Papaya Pete +PapayaGod +PapayaPetee +Papegaaitje +Paper +Paperbag +Papi +Papi Baz +Papi Chop +Papi Feb +Papi Fish +Papi Gains +Papi Okapi +Papi Sam +Papi Sean +Papi Six +PapiTron +Papicito +Papicodone +Papido +PapieLexus +PapierHier +Papierschere +Papii +Paplip +Papo Sauce +Pappa Mauly +PappaPizza +Pappanopolis +PapperNapper +PaprikaBoi +PapuIsThatU +Papukaia +Papyea Fruit +Papz Mage +Paqan +ParKy_ParK +Parabhjeet +Parabolic +Paracleis +Paradoos +Paradox +Paradox 2277 +ParadoxAU +ParadoxCrux +Paradoxal +Paralimpian +Parameters +Paramost +Parandrus +Paranosys +ParaplegicIM +Parappa +ParasiteHunt +Parasitoid +ParasoxX +Parazino +Parc +Parc Ferme +ParchedToast +Parciparla +Parent +Parfour +Parhaat +Pari +Pariera +PariguayoGL +Parikh +Parikkala +Parish +Parjesh +Park +Parkchae +Parkehh +Parker177 +Parker1770 +ParkerSquats +Parkerrr +Parkuh +Parky +Parkz +Parley0 +ParmsG8 +Paroni007 +Paront +Parotis +Parox3tine +Parrot +Parrot Champ +Parrot Le Fe +Parrot Poop +Parsecs +Partey +Parth4903 +Parthnix +Particulae +Partly +Partonax +Parttime +Party +Party Fraud +Party Pete +PartyRock +Partyhaty +Partynexdor +ParuParu +Parvovirus +Parx98 +Parxe kurita +Parzival32 +Pasadinas +PashkaPushka +Pashmina +Pasianssi +Pasiiba90 +Pasikaustes +Pasito +PasitoBandit +Pasje +PaskaJatka69 +PaskaneHomo +Paskie +Paskis +Pasmo +Pasrules +Pasta +Pasta Lance +Pasta Mancer +PastaShel +Pastabrain +Pastafreezer +Pastagonia +Pasticcione +Pastor +Pastry +Pasu +Pasza1357 +Pat NoScythe +Pat The Nerd +Pat the Cat +Pat twumasi +Pat_y +Pata2006 +Patalopodus +PatchRS +Patchley +Patdog666 +Pate +Patella +PatentedName +Patetisk +PathTracker +Pathogen +Pathways +Patio +Patious +Patmantheman +PatoVelaz9 +Patojo +Patota +Patrexion +Patrician +Patrick +PatrickClick +PatrickLaine +Patrickp35 +Patrik Laine +Patriot88 +Patriotscape +Patriotsp +Patriottj +Patrolliin +Patronique +Patrouski +Patryk 1 +Pats +Patsey +PattMyGun +Patta1 +Patte +Pattos +Patty C +Pattycakes19 +Pattyrick8 +Patyfatycake +Pau1ekas +Pauk +Paul +Paul 0 +Paul Beer +Paul Ski +Paul0 H +Paul007 +Paul90333 +PaulD +PaulOH10 +PaulTheRabbi +Paulchritude +Pauleee +Paulest Paul +PauletteRose +Paulius +Paulk23 +Paulrat +Paulrat 3 +PaulyNFS +Paum No Xeem +PauperPlayer +Paupy +PauseGuy +Pauwels +Pauwels v2 +Pavies +Pavio +Pavla +Pavlacci +Pavlvs +Pawggrs +Pawgz +Pawko +Pawlmeister +Pawlu +Pawlzer +Pawn 69 +Pawn M8 +Pawrie +Pawwsy +Pax Mundus +Paxin +Paxy +Pay2ClickLol +PayMyDeedFWD +Payne_Trayne +Paznos6 +Pazuta +Pazzo-Repack +Pb Fe +Pb and Jd +Pbby +Pbkillua +PbyOne +PdaddyReborn +PdfPKerNoGF +PdiddyReborn +Pe en +Pe t er +Pe1ipp3r +Peabody +PeacandLove +Peace +PeaceNLove31 +PeaceOfMind +Peacebuild +Peaceer +Peacefrog +Peach s +PeachKing +Peaches5000 +Peachh +Peachhh +Peachy Tank +PeachyBrute +PeachyDean +Peaco +Peacoat +Peak +Peakado +Peake +Peake7 +Peakleaf +Peaky +PeanutBTW +Pear +PearOfApples +PearlNechlis +PearlWeed +Pearlito +Pearshaped9 +Peasant +Peasyy +PeatMoss +Peatie +Peba +Pebbex +Pebblez +PebisGuan +Pebl +Pebu +Pebz +PecanBread11 +Pecker Punch +PeckerFish +Peckerflexer +Pecki +Peco +Pecs +Pectorialis +Pecuni75 +Peddler +Pederbuus +Pedestrian01 +Pedro +Pedro5901 +Pedtato +Pee Jay Salt +Pee Kay Err +Pee Mud +Pee On Irons +PeeJayPlayz +PeePee +Peeanut +Peeble +Peeeeeekaaaa +Peeke +Peel +PeelMyCarrot +PeeledBanana +Peely +Peen +PeenLover61 +Peep Taimla +Peepo +Peepo Parker +PeepoPants +PeepoRiot420 +Peeps Cx +Peepzilla +PeerTheSeer +Peernicus +Peeshuuu +Peest +PeetrusEst +Peevish +Peevy +Peezerthecat +Peg Boots +Peg My Arse +Pegasian +Pegasians +Pegasus51C +Pegi18 +Peha +Pehkis +Pehmolelu +Pei898 +Peighniss +Peiin +Pein +Peipeilaile +Peipi +Pekaia +Pekays +Pekdon +Pekka Elo +Pekka-Eric +Pekka557 +Pekkaa +Pekkaad +Pekkadillo +Pekonipeikko +Peksaad +Pelaa +Pelaaja1 +Pelco +Pele Marreta +Peli Moapa +Peligroso +Pelikaen +Pelippper +Pelirroja +Pelmee +Pelosi +PeltiPirkka +Peltolammi +Pemiel +Pen Sir +Pena +Penally GIM +Penance Boom +Pencelis +PencilVesta +Pendax +PendulumC +Penetrader +Peng Lightey +PengMaster +Penge1616 +Penguin +PenguinBelly +Penguino +Pengwim +PeniAnus +Peniel +Peninsula +Pennstate +Pennsylvania +PennyPinchnJ +Pennybag +Pennycord +Pennywise +Pennywise070 +Pentagrammi +Pentektonyx +Penthera +Penthrox +Penthus +Pentu +Penward +Peopledud +Peoples111 +Peor +Pep Kroket +Pepar +Pepar Kakan +Pepclub101 +Pepco +PepeGUH +PepeHang +PepeLaughing +PepegaScape +Pepeh +Pepemiguel +Pepo Is Me +Peppey +Peppi +PeppiEnSossi +Peppusieni +Peppy Pete +Pepsi +Pepsi Maxed +Pepsi Maxia +Pepsi575 +PepsiMaxL1me +PepsiTwist +Pepsies +Pepsipowars +Pept +PeptoGlizmol +Pepuszka126 +Pequenaud +Pequette +Per Ke Le +Perc 3m +Perceive +Perceptivity +Perch Curry +Perchlorate +Percy Grail +Percy Nash +Percy Turner +Perduh +Peremees +Perfect +Perfect Dark +PerfectCurse +PerfectJerni +PerfectProof +Perfectaaa +Performax +Perfringens +Pergert +PerhapsGuy +Peridots +Perikles460 +Peril +Perkinatored +Perky +PerkyPorker +Perlen +Perm II Mu8e +Permabulk +Permded +Permedd +Permer +Permuh +Pernix +Pero Scoped +Perox +Perp67 +Perpl +Perplox +Perrault +Perrif +Perry Hubes +Perry T +Persephatta +Perseveranca +Persian +Persilja +Perspective +Pert +Perterritus +Perth +Pervy x Sage +Pesiz +Pesoprkl +Pessimism +Pest +PestGodd +Pestilance7 +Pestilent Bt +Pestle +Pet Alpaca +Pet Awowogei +Pet Cape +Pet Crusader +Pet Eric +Pet Hunta +Pet KBD +Pet King +Pet Luck +Pet Meowtain +Pet Smuggler +Pet The Cats +Pet Ty +PetBoost +PetCorp +PetHuntBrad +PetHuntGrind +PetHunta +PetHunting +PetPlease +PetSpooner +PetUrSausage +Petal +Petalite +Petar228 +Petarss +Petched +Petchy inis +Petcord +PeteRePete +Pete_901 +Petega +Petelgeuse1 +Peteniice +Peter +Peter DIY +Peter Dupas +Peter Kent +Peter97 +PeterLimbeek +PeterPlanker +PeterRS +PeterTheSalt +Peterh +Peterm +Peterszoees +Petey pleb +Petit +PetitKeBeQ +Petite +Petite Poire +Petless +Petooted +Petpet +Petrenkovitz +Petricsh +Petriq +PetroX77 +Petrosian +Petting GIM +PettyName +Petuhh +Petz +Peuramaa +PewTheMeow +Peweherman +Pewming +Pex3 +PexBoi +Pexci +Pexezz +Pexterity +Pextill +PeytyPoo +Pez xX +Pez za +Pezy +Pfiny +Pfister +Pfle +Ph0g +PhD Fred +PhD Funk +PhD in TCG +PhaMaTics +Phader +Phaero +Phai +Phainesthai +Phalamon +Phallic +PhallusBigus +Phamia +Phamit +Phant +PhantomDred +PhantomFiend +PhantomLogic +PhantomVS +Phantombear7 +Phanton +PhappleSauce +Pharaoh Chad +Pharaoh Ion +Pharmafia +Pharqen +Phase +Phasedd +Phasing +Phasmatus +Phasmatys +Phat +Phat Dik +Phat Pat +PhatAsher +PhatFrat +Phathead +Phatman348 +Phats +PhatsoCallum +Phatt +Phatty +Phattyftboy +Phaxe +Phd n Arteez +Pheasant +Pheasant Egg +Phels +PhenXX +Pheniex2 +Phenomenal +Phensa +Pheonixess +Pher +Phernix +Phetty +Pheus +Phex +Phi184 +Phibes +Phil +Phil Coulson +Phil Mcrakin +Philip +Philip424 +Philipp +Philkwl +Phille +Philli Blunt +Phillies +Philliez +Phillip +Phillip R +Phillipp +Philly +Philly Sucks +PhillyFiller +Philoi +Philosophia +Philou +PhilsBent +PhilsUnlucky +Philth +Philtration +Phin_C +Phinxu +Phinz +Phipple +Phishn +Phizo +Phlaja +Phlegmy +Phlemming +Phloppster +Phlopsy +Pho Z +Phobias +PhobosDeimos +Phoibos +Phonatik +Phone +Phone Number +Phone Scaper +PhoneHC +Phonebook +Phoneman +Phools +Phoque +Phor Skin +Phosani +Phossa +Phostus +Photographs +Photon +Photonic +Photos +Phragasm +Phrak +Phrexyian +Phrez +PhriarPhace +Phrizo +Phrocks +Phsteven +Phug +Phugma +Phuke +Phuket +Phwan +Phxrm +Phylum +Phyrlo +Phyro +Phyronex +Physics +Physics Jedi +Phytz +Phyzxs +Pianio +Piano Hands +Pianoanddrum +Piantissimo +Piasa +Pic of Feet +Picante +Piccoloownsu +Piccy +Pichi Slayer +Pickl3Lover +Pickle Josh +Pickle Vick +PickleKez +PickleSaucy +PickledWater +Pickles4Me +Pickles69314 +Picklzz +PicnicBomber +PicoDico +Picolo +PictureID +Picuu +Picuwu +Pidbull +Pidbull 1 +Pidgeot18 +Pidgey +Pidgy +Pidiot +Pidrux +Pie +Pie Dish +PieGPT +Piecekeeper2 +Pieces +Pieck +Pieerio +Piemaksa +Piemans +PiemieJurrie +Pieper +Piepieweenie +Pier Just +Pierced Wolf +Pierenbadje +Pierniczek00 +Piestove +Piet +Piet 21 +PietKrediet +Pieter +Pieter Zwart +PieterPep +Pieterjan +Pietermans +Pietn4 +Pietrangelo +Pietrnogiets +Piety +Piety Prease +Pieza +Pieza de oro +Piffen +Pigeon +Pigeon Soup +Pigeonmight +Piggi Smalls +Pigi373 +Piglette +Pigman461 +Pigmeu +Pigpikerush +Pigpuffer +Pigs +Pigwardfrog +Pihl +Piip MEEGA +Piipar +Piirivalvur +PikaChar222 +PikaChin +Pikachewed +Pikachos +Pikachu +Pikachu87 +Pikachurine +Pikachuz +Pikkets +Pikkett +Pikku +PikkuSheikki +Pikkupbrix +Pile +Pile O Poo +Pile o Dirt +Pilgrimage +Pili +Pilli +Pilliad +Pillifnutten +PillowBoy +PillowCowCow +Pillukarva23 +Pilmir +Pilodro +PilsToTheMax +Pilsners +Pilum +Pim Pam +Pimay +Pimfortune +Pimp +Pimp Ralpert +PimpWeazel +PimpWhistle +Pimpert +Pimpin Thots +Pindaro +Ping +PingFlopped +Pingu +Pink +Pink Avocado +Pink Bar +Pink Cow34 +Pink Iron +Pink Lube +PinkDrinkSip +PinkShopRag +PinkVoidZ +Pinkberg +Pinkk +Pinky +Pinkywinky9b +Pinkyx0xo +PinndOutGoon +PinnkBunny +Pinnn +Pinpi +Pinquana +Pinsamt +PintOfMilf +Pintel +Pinterests +Pinu +Piolin +Pioniers +Piovendo +Piparikissa +PipeQlo +Pipluppp +Pipo-badeend +Pippinmary +PippleNinchy +Pipposan +Pippuri +Pir Alain +Pirat +Pirate +Pirate Kanye +Pirate Patch +Piratey +Pirelly +Piri +Pirig0 +Pirihuora666 +Piripaque +Piripippeli +Pirjo +Pirjo69 +Pirk the pk +Pirkka Olut +PirkkaJokeri +Pirkkamies +Piroskinha +PirpleSlirpy +Pirres +Pirulitim +Pisatronas +Pisau +Piscarallius +Piscis +Piscolaz +Pistacchio +Pistoliftero +Pit Stain +PitGamin1311 +Pita Diver +Pitbulterje +Pitby +Pitchfork +Pithikos +Piticarus +Pitiless +Pitinator +Pitt +Pittaaaaa +PitterPattr +Pittsburqh +Pitudin +Pivach +Pix Pixelle +PixarMarsTTV +Pixel +PixelMuffin +Pixie Henge +Pixieragnar +Pixkekoa +Pizdec +Pizza +Pizza Addict +Pizza Box +Pizza Flip +Pizza Mang +Pizza Patron +PizzaDaHutt +Pizzaman5510 +PizzasIron +Pizzler +Pj The Pj +Pjotr +Pjt77 +Pjumi +Pk Bot 37 +Pk M4ster007 +Pk Wit P Hat +Pk3iru_Osrs +Pk3r Range 7 +Pk996 +PkGoW +PkMeIfUgey +PkTheKid +Pker nr 1337 +PkerTrysHard +PkforFun +Pking +Pkingranged9 +PkmnTrnrRED +Pkmort +Pksorwd +Pkyr +Pl0xed +Pl3b +PlELS +PlFFMAN +PlGGY +PlHLAJA +PlMP +PlMPPl +PlMl +PlPPY +PlRATE KING +PlSS +Plaagen +Plaasda +Plaat +Placedoemax +Plaeggs +Plaid10 +PlaidMarquis +Plain +PlainIronMan +PlainNoGood +Plaininsane +Plamt +Plan +Plan B-gs +Plane4611 +Planet001 +PlanetPaul +Plank +Plank Egger +Plank Sodplo +Plank2G +PlankForBank +PlankTan +Planken bos +Planker +Planking Brb +Plankrunner8 +PlanktSoms +Plant Herbs +Plantdaddyy +Plap +Plasma Taco +Plasmore +Plastikos +Plastiscines +Plat Kont +PlatGX +PlatScrub +Platinum2008 +PlatinumHerb +PlatinumSage +PlatinumSeif +Platnuim +Platnum112 +Platpus3000 +Platyroo +Play +Play Lazy +PlaySoloBro +PlayToAFK +Playbunny +PlayedBe4EOC +Player +Player 0ne +Player 4519 +Player Gap +Player Name +Player235711 +Player35254 +PlayerIsBusy +PlayerSlayaa +Playpro5 +Plays high +Playtest +Playthious +Pleasantries +Please pot +Pleasurehole +Pleb Nick +Plebbocs +Plebiside +Pleblio +Plebnex +Plebs +Plebz +Plece +Plegh +Plexasaurus +Plexx +Plez +Pliemp +Pliep +Pliep Ploep +Plips +Plisski +Plixious +Plocc +Plogbilen +Plogdog +Plomono +Ploop +Plootbot +Plop deez +Plopi +Plopr +Plopzorg +Plorky +Plorr +Plostic +Plot786 +PlovasYonder +Plovilas +Plow +Plowthrough +PlsAName +Plsmrlizard +Pluc321 +Pluckky +Plug In Baby +Plugatron +Plugged +Pluggen +Pluhdl +Plukketje +PlumTickler +PlumbThatA +PlumpGiraffe +Plumper +Plundered +Plunkton +Plunukki +Plupian +Plus +Plus Vite +PlusZack +Plush Mole +Pluto +Plutonium +Plutonium 94 +Plym +Plz LD Nat5 +PlzGiveBonds +PlzRnGesus +PlzSpoonFeed +Pm Me Imps +Pm me to spy +Pm4 eloboost +PmFun +Pmy39 +Pnak +PneFc +Pnia +PnutButtrJly +PoachedLion +PoakedSussy +PoaneFoane +PoarIIneemn +Pocholo +Pocket +Pocket Cards +PocketBandit +PocketSock +Pockipickle +Pocy2 +Pod x +Podvodnik +Poeiermolke +Poem +Poenes +Poephoofd +Poepi12 +Poepjong +Poepsiee +Poerto +Poet1321 +Pofka +Pog Dog +Pog isma +Pog-kek-Lul +PogChampagne +PogMeister +PogTato +PogTato Iron +Pogba +PogoPochette +Pogsled +Pogue4Lyfe +Poikanen +Point +Point Guards +PointTax +Pointstormy +Poison Ives +Poison x Ivy +PoisonCobra +PoisonX7 +Poisonblack +Poisonous +Pokaroo2 +Poke Champ3 +Pokeaotics +PokedexNo258 +Pokefreud11 +Pokemaster +Pokemon +Pokemon Ruby +PokemonScape +Pokemonguy16 +PokerPro +Pokerboy19 +Pokergod720 +Pokifeet +PokimanesBF +Pokoloko +Pol o +Polaar +PolakYT +Polar +PolarTrip +Polarin +Polarisi888 +Polarus +Polarward +PolderLatina +Pole Met +PoleVault +Polio23 +Polish +Polish Eagle +Polite +Politoed +Polixo +Polkapolkka +Polkastarter +Poll +Pollar i +Pollekeuh +PollenJ0ck +Polllie +Polllo420 +Pollnivneach +Pollo Dry +PolloGrande +Pollofrit0 +Pollum +Pollywog +PoloG +Poloskyy +Polter +Polyamorous +Polycoffin +Polyesterday +Polygonise +Polyhedra +Polynomail +Polyphobia +Polywoggle +Pomi Xd +Pommy +Pompeyo +Pomposity +Ponas +Pond Scum +Pondres +Ponkito +Ponobi +Pont +Ponti +Pontifex +Pony +PonyOwner938 +PonyPorker +Ponzy FTW +Poo Socks +PooAtPVM +Poobanans +Pooby Bag +Poodle +Poofpooh +Poogen +Poogster +Pooh +Pooh Breezy +Pooh Say +Poohead92 +Poohsea +Poojabber364 +Pook +PookiDaPooki +PookieB3ar +PookieBearOG +Pool Noodlez +Pool Toucher +PoolboyFiji +Poon +Poon Lips +PoonHandleMe +PoonTangPie +PoonTappa +Poonanjo +Pooned +Poonjuu +Pooohie +Poop +Poop Shidder +PoopyRico +Poor +Poor Advice +Poor Clicker +Poor Content +Poor Nooby +Poor You +Poortom24 +Pooscaper +PootLoops +Pootzie +Pootzie_xox +Pop In Smoke +Pop N +Pop-up ad +PopTheIron +Popcornachi +Pope +Pope VI +PopeChamp +PopeDenis +Popeet +Popepu +PopeyezGain +Popfumes +Popkorni +Poplo +Popovich +Popoyoi +Poppa +Poppa Bev +PoppaChoonie +Poppajohns +Poppin Awf +Poppscotti +Poppy +Poppymatt +Pops24 +Popstar2 +Popular +PopyHarlow +PorWrx +Pordiosero +Pore +Pork Jerry +PorkCH0PZ +Porkkanakana +Porksters +Porrie +Porsche +PorscheDaddy +Port Khazard +PortUnionMan +Porta Pro +Portal of I +PorterRobnsn +Portrays +Portsari +Portuguese +Portvakt +Porunga +Porygon-Z +PoseidonDrip +Posemann +Posh +PoshPenguin +Poshker +Poshki +Poshkii +Posino +Positivar +Positive +Positivehp +Possessed +PossiblyAFK +PossumPally +Possumi +Post +Post Malone +Post Max +Post-Absurd +PostCodee +Postie +PostmanPatt +PostureCheck +Posty2k +Pot Gatherer +Pot Of Greed +Pot Often +Pot Sharer +Pot cms +Pot v X +PotScape +PotScape CC +Potapto +Potato +Potato D Ben +PotatoButGay +PotatoLlorch +PotatoRangr +Potatoqueenn +Potecito jr +PotentJay +Potezny +Potge +Pothaaai +PotionFayD +Potland +Potland o_0 +PotoSekwati +Potoo +PotsAlots +Potsi +Pottawatomie +Potter Paypa +Potth +Pottieface +Pottsi +PottuTatti +Potzy +Poucher +Pouches +Poucie +Pounake +PoundSandNub +PourMeBleach +Poussemoila +Poutz +Poverty +Povvo +Powacat +Power +Power Aid 4 +Power H +Power Outage +Power Surge +PowerJoe +Powerade +Powerdude153 +Powerful +PowerfulBram +Powerfull +Powerlines +Poweron6 +Poww LUIS +Powwil +Powxrs +Poxuistas +Poyig +Pozar +Ppl +Pposkyor +Pql +Pr0 Ph3t +Pr0pvm +Pr0way +Pr1MaL +Pr3par3 2die +Pr3ttyW0man9 +Pr3y +Pra1seTheSun +Practical +Prada +Praecellemus +Praedy +Praenthos +Praes +Praestantia +Praetor +Prage699 +Prahlad +Prairiez +PraiseCorn +Praisemyrng +Pramikon +Prankzy +Prari +Praskle +Pratt Mario +Praxahr +Praxys +Pray +Pray Salah +Pray for me +Pray t o God +Pray4TheWin +Pray4me +PrayForDeath +PrayForYou +PrayToAres +PrayarN +Prayer Pro +Prayerr +Prayis +Praynr +PreMDPepper +PreNew +PreRuined +Precise +Precixion +Precondition +Predaxx +Predicition +Preedy +Pregnant +PregnantSock +Prelash +Prelet +Prelex +Prellifunky +Prem +PrematureNut +Premie +PremierZarry +Premium Dude +Premz +Prep +Prepared2 +Preposo0 +Prepotting +PresPoon +Presearing +Preserve +PresidentMo +Presley93 +Presley93BTW +Preso +PressX +PressedClean +Prestor +Pretendy +Preternal +Preto +Preto Ownsss +Pretten +Pretty +Pretty God +Pretty moist +PrettyGood +Prettyokqt +Pretved +Pretz +Prevengeance +Previn +Prey +Prey4Pocius +Preying +Priapismi +Pricy +Priestopher +Prif Daddy +Prifddinas +Priide +Priimitive +Prilliam +Prim +Prima +Primacy +Primal +Primal gain +Prime +PrimeSeries +PrimeToaster +Primed +Primetime190 +Primetime829 +Primevil +PrimexReborn +Primid +Primiitive +Primilivum +Primitive +PrimoVG +Primordial +Primster +Prince +Prince Drt +Prince Ferro +Prince Mate +Prince Tuten +PrinceCrypto +PrinceJozef +PrinceZuko +Pringle287 +Pringles +Prins +Prins Pi1s +Prinses +PrintedCash +Prion +Priority +Priorrr +Priselac +Prisimenu +Prismalitic +Prison +Prison Joe +Prison M1ke +Prison Soap +Pritje +PrityBoiSwag +PrivateSmorc +Prix +Prixma +Prncss +Prncss II +PrntScr +Pro Flicks +Pro Per UIM +Pro SKiiLLz +Pro Slacka +Pro Slacker +Pro Tanto +Pro Tato +Pro Zoe +Pro twin33 +Pro-tag +ProForm +ProFortnite +ProLegend +ProSKatona +ProSups +ProTweakius +Proba +Probability +Problemski +ProbzDrunk +Procedures +Proclivitas3 +Procoptodon +Proctiv +Procts +ProddyP +Prodigy 99 +Prodigy Matt +ProdigyTape +ProdigyThief +Prodigy_77 +Prodoughtype +Product99 +Prof +Prof Bruce +Prof Cheese +Prof Ribeiro +Prof Shroom +ProfGanon +Prof_Plums +Prof_Snack +ProfanityBox +Professa +ProfessorBot +Proficent +ProfoundPnda +Prog +Project +Project Deku +Project Paat +Project Sept +ProjectGamma +ProjektUri +Proklus +Prokopios +Prolapsi +Prolly High +Proly high +Promacta +Promepheus +Promise +Promtel +Prone +Prongs97 +Pronx +Proots +Prop Gun +Propagate +Propas +Proper +Proper bald +ProperTroll +Prophecy +ProphetSnayk +Prophylax +Proponi +Propulsions +Prosit +Prospicktor +Pross +Proster +Protagg +Protanopia +Protassium +Protease +ProtectdLeft +Protectlilb9 +Protectorate +Protege +Proteiini +Protixen +Protlong +Protocell +Proton Drum +Protopteryx +PrototypeGOD +Protox +Prouser +Provei +ProvidenceL +Providential +Proviro +Provoke Rage +Provokeskill +Provoxo +Prowz +ProxDemSox +Proxeum +Proximitus +Proxymine3 +Prozac Manic +Prozac Peter +PrrMeowPrr +Prro +Prrr +Prrr Perry +Prryvdoof +Pruillip +Prune +Prune Slayer +PruneHub +PrusaSlicer +Prutturp +Pryn +Pryxl +Pryypsas +Pryza91 +PsYcHo130 +Psalm +Psalms116 +Psaro +PseudRodrigo +Pseudo +Pseudomonas +Pseudonimas +PsiTempest +Psichedeliks +Psiki +Psiklone +Psmaster +Psoup +Psuedoniem +Psy0tic +Psy13m +PsyDellic +PsyWaps +Psybae +Psyc +Psyc Paladin +Psyc0-I +Psyched +PsychicL10n +PsychicType +Psychinis +Psycho +Psycho Fungi +Psycho11111 +PsychoPatty +Psychodeathk +Psychohexane +Psychokilla +PsychoxX +Psyco +Psycub420 +Psydvekoosi +Psygo +PsyhexGOD +Psykoz +Psylocin +Psyminds +Psynar +Psyqualogy +Psysyk +Psytoro +Psytrnce +Psyyke +Pt 79 +Ptalm +PteShank +Ptfo +Ptol +Ptopaz +Ptyh +Pu-94 +Pubeless +PubicThumb +Pubicon +Public NJP +Publics +Publuske +PuchaLibre +Puck +Pudding +Pudding Man +Puddingdude +Puddingtons +Pudge +Pudge Pudge +PudgeJackie +Pudgeegee +Pudnik +Pudota +Pudota basso +Puerto Varas +Puff Daddy +Puffed +Pufffml +Puffy +Puffy xx +Pufr +Pug +Pug Boots +Pug Champ +PugToots +Pugasaur +Puggin +Puggzy +Puglet +Pugna +Pugsyy +Pugwest +Pugy +Puhd +Puhd1staja +Puhuri +Pui +Puin +PuinguimGOD +Pukeking +Pukeko +Puli1111 +Pulkjes +Pull +PullOutKing +PullOutRange +Pulli +Pulma1 +PulpFlctlon +Pulza +PumGiver +Pumba +Pumba Bot +Pumba89 +PumpUpTheJam +Pumper +Pumper Joe +Pumpflexin +Pumpkin +PumpkinLatte +Pumpui +Pumuckl +Punani MD +Puncakes +Punch +Punch Main +Punched +Pundareen +Punde +Pune +Pune rouch +Punegonde +Pung +PunishinBird +PunjabSamosa +Punk-06 +PunkPang +Punkt +Punt +Puntenjagert +Puntje ket +Puny Duck +Pup +Pup in a Cup +Puppadile +Puppana +Pupper1 +PuppySeal +Puppysaysftw +Pur3 +Pur3 Bow99 +Pur3death2 +PurMain +Purate +Purcey +Purcs +Pure +Pure Evil99 +Pure Great1 +Pure Hunk +Pure Paprika +PureBread +PureFilth +PureIronEyyy +PureOGIronMn +PureOwner +PureWax +Pureanger728 +Purebas alt +Purebasalt +Purebish +Purell +Pureloot21 +Purely +Purelybo0ty6 +Purenerd +Purepappa +Purepappa66 +Purescarybuu +Purey Arcane +PurgatoryBro +Purgy +Purifyin +Purjj +Purka11 +Purkkatukka +Purkkaukko +Purkkius +Purko +Purnex +Purolator Pl +Purp +Purp Nasty +Purp Nips +Purp Please +Purp or Bust +Purp where +Purp1eWizard +PurpLightPlz +Purpl3 Lean +Purple +Purple Flap +Purple Meeep +Purple-Broly +PurpleDabz +PurpleGoat +PurpleHippoo +PurpleMurple +PurpleNinjja +PurplePlez +PurpleTeemo +PurpleThorax +PurpleVex +PurpleWhaki +Purpledile +Purplefox +Purplekills +Purplemudkip +Purpleowns +Purppurainen +Purpsauce +PurrPig +Purse seine +PursuantACE +Pursuedd +Purtherapist +Pusat +PuscSquirt +Puse +PuseSlayer +Pushgold +Pushovermage +Pushy Bubes +Puss +Pustut +Put Me 4th +PutMeInCo4ch +Putaria +Puthiegh +Puthy +Putkipommi +Putrescent +Putse +Putyte1 +PutziVikat +Puud +Puujalka10 +Puukko Pekka +PuuluuP +Puumba +Puuteri +Puylayer +Puzzle Drops +PuzzleTheCat +Pv Was Here +PvEmerald +PvM Andrew +PvM Beireh +PvM Bhunt3r +PvM Blake +PvM Boganeer +PvM Cas +PvM ColdBeer +PvM Crooky +PvM David +PvM Eestlane +PvM Gemeos +PvM Grindz +PvM Hawk +PvM Hero92 +PvM Items +PvM Jack +PvM MeK +PvM Miku H +PvM Muzzy +PvM Nex +PvM Nug +PvM Oliver +PvM Packers +PvM Panda +PvM Rev +PvM Rin +PvM Spectral +PvM Tom +PvM Wiz +PvM guy +PvM zoom +PvMAlone +PvMCerlow +PvMKoala +PvMNightmare +PvMNotorious +PvMProfessor +PvM_Nugg +PvMalexDR +PvManchester +PvMs +PvP +PvP Master +PvPRoTiGy +PvPete +PvPs +Pvkk +Pvm 4 Pets +Pvm Aero +Pvm Demigod +Pvm Garley +Pvm M0lz2 +Pvm MageBoss +Pvm Runeboyz +Pvm Tigers +PvmBrad +PvmQ +PvmRNGesus +Pvmpets +Pvoet +PvtStevens +Pvul +Pw4 +PwDhorizons +Pwca +Pwdz +Pweet +Pwew +PwincessK +Pwn Dat Noob +PwnTommy +Pwnage +Pwnbaa +Pwnd +Pwnna +Pwnnzz +Pwno +PwnrPizzaman +Pwnslayibex +Pwpw +Pwxn +Px_7UX8Cy8 +Pxcs +Pxie +Pxtrick +Pxxch +Pxzls +Pyet +Pyfa +Pygmysteaks +Pyia +Pyjamas99 +Pyki +Pyloric +Pylseboden +Pyocola +Pyra +Pyrate Aeon +Pyre Lord3 +Pyre Mouse +Pyretic +Pyrl +Pyro238 +PyroEagle13 +PyroF3AR +Pyro_OO1 +Pyrocore +Pyrotemplar +PyrrosDimas +Pyssu +Pyst +Python +Pythonx135 +Pyux +Pyykki +Pyyli +Pyzdalupi +PzK +Pzju +PzzaPredator +Q 1 +Q K M Nophis +Q Proserpina +Q S L +Q cs +Q l ii Ma X +Q of Spade +Q uincy +Q-Dance Jr +Q-Qs +Q1NH4N +Q33N +Q53 +Q60 +Q7L +Q8 I +Q8vv +QAWSED +QGM +QIKNQFRDNUQF +QKen +QPR +QPness +QQ3 +QQQ Gang +QQQQQQRRRRRR +QQuaLLeH +QRcoding +QT Bri +QT0 +QTRDS +QTY1 +QTZedd +QTom +QU0TE ME +QU42TION +QWIWRDIGIDFG +Qadir +Qaem +Qaidos +Qajvha +Qapz +Qash +Qc power1 +Qc-Elfmage +Qeassaris +QeeQ +Qego +Qeko +Qeln +Qemi +Qeni +Qenobii +Qi Kua Mai +Qi Ling +QiangxD +Qilat +Qiok +QlKNQFRDNUQF +Qlhp xD +Qlioux +Qmain +QnBumbleBee +Qnon +Qoil +Qoki +Qombat +Qosmio +QpSc +Qpaki +QpzQ +Qragon +Qrax +Qridan +Qrischin +Qrollop +Qrwewa +Qryptic +Qtey +Qtreb +Qu3stm4st3r +Quacamole +Quack Attk +Quack Boom +QuackForMe +Quacka +Quacker +QuadJake +Quadder 4444 +Quadralobsta +Quadrifoglio +Quadrioo2 +Quaerd +QuaffPotion +Quaffle9 +Quahzai +Quakbou +Quakenet +Quakoss +Qualitative +Qualities +Quality Kek +Quality Name +QualitySleep +Quang +Quantities +Quantization +Quantuh +Quantum +QuantumTurtl +Quarentitty +Quarks +QuarterToBen +Quarterback +Quarters +Quartia +Quav +Quawka +Quazi +Qucks +Qucu +QueBolaAsere +QueefInMyEar +QueefMaestro +QueefWiggum +QueefedOnYou +Queeffing +Queen +Queen De +Queen Juggle +Queen Keegs +Queen of CoX +Queen0fScots +QueenBadJuju +QueenJada +QueenOfCorn +Queenmystque +Queenn Elsa +Queer +Queer Peter +Queerzzly +Queijo9 +Quelana +Quenched +Quero +Quessswho +Quest +Quest Dodger +Quest Giver +Quest Lckd +Quest Noobi +Quest Person +Quest Plug +Questikels +QuestsAreBad +Quety +Queue Pea +Queueie +Quew +Quey +Quezzimoto +Quf +Qui GonJinn +Quica +Quick200 +QuickClicks +QuickELMN8 +QuickNDeadly +QuickShot +QuickShot x +Quicken +Quickman1000 +Quickshot343 +Quiddich +Quiet +Quiet Place +Quiet Please +Quiet Toot +QuietStorm44 +Quiettravlr +Quikstache00 +Quilicura +Quillninety3 +Quimbo +Quinker +Quinncidence +Quinnyb0y +Quintendo +Quirkless24 +QuirkyBeaver +QuirkyPurple +Quit 4 iron +QuitForIron +QuitForRS3 +Quite +Quite Shy +Quitegoddish +Quitoris +Quitting Alc +Quiz +Quizav +Quizzy Dee +QukinoTe +Quonloo +Quorhum +Qureshi +Quria +Qurix +Quti +Qutie +Quukske +Quvma +Quweix +Quyron +Quz +Quzzini +Qverkuz +Qwagmire +Qwaltz +Qwd +Qwezz +Qwibz +Qwinny +Qwinoa +Qwozii +Qxevym1 +Qzbxd +Qzst +R 0 E +R 0 w d y +R A L L S +R A V I +R A Z T A +R E +R H Y T H M +R I J K A R +R I K +R I P B R O +R L +R N G Pwnz5 +R N Geo +R O B B IE +R O E L +R O O N +R O X +R P N +R S J +R S Life +R S M +R U A Terd +R U MAD BRU +R Y A N +R Y D +R You Jelly +R a uL +R a z u z +R ack +R amon +R eece +R em +R hin o +R i a d +R ift +R l C H +R mr +R o r o no a +R ob +R obert +R oger +R osss +R uiN +R ya n +R yun +R-66Y +R00M +R00P +R00SE +R00T +R0AD +R0B0C0P +R0BBO +R0FL AT L1FE +R0GAN +R0KKIN +R0LX +R0MICH +R0NES +R0NNIEB0Y +R0OZ +R0R0R +R0Y +R0YAL +R0ad +R0bain +R0bbby +R0binho +R0n13L +R0seofthorns +R0yksopp +R14H +R1CO +R1chs +R1ghtupth3r3 +R1ku +R1ng +R2TB +R32 N Z +R33c0NN +R34 +R3Dtjee +R3d3mtion +R3dlegend +R3vq +R4 n g 3 r z +R4LLY +R4g4n4 +R4ndomUs3r +R4ndyM0n +R4ndy_lahey +R4ng3 +R4ng3 Nubie +R4ng3r 00 +R4nge +R4nge 2 Lpk +R4re Pepe +R4v2n +R6boi +R8nny +RA NG ED +RAB9 +RACELIS24 +RAD x GLiDeR +RADATOUILLE +RADlATAstory +RAFA LOKO +RAG YOUR A55 +RAKETTAA +RAPPUHN +RATMON3Y +RAUTA ARTO +RAlN +RAlSED +RBNY +RBeardWBrow +RC Blows +RC350 +RC93 +RCFreak +RCW +RCY +RD Alten +RDHG +RDJ94 +RDT King +RDW_Dark +RE2PECT +RE4LG4LIFE +REALLY RITCH +REBOOTING +REC0N +RECEPTED +RED DEM0N +REDBUHLL +REDD0GJR +REDLlNE +REDRACECAR99 +REEEject +REEEsuns +REINCARN4TE +REKNAW +REKTmlg99op +REMAlN +REMIIIX +REN0 +REZlN +RElNHARDT +RF Bushee +RF Genesis +RFDesigner +RGB Titties +RGGregar +RGet +RHCP-Solo +RHK Ezze +RI Sleepy +RIP Base +RIP Meme Man +RIP Mitch +RIP Pork Pie +RIP life +RIPAUGUST +RIPAccount94 +RIPT4H +RIPgirthgirl +RIllipieru +RIpuim +RJCI +RJE +RJL129 +RKBM2 +RKN +RKOd +RKOd My Mum +RKTA +RKZY +RL Adam +RL Wolf +RLBurnside +RMAC-97 +RMF Dead +RMG solo +RMax +RNG Alche +RNG GOD +RNG Kevin +RNG MAD +RNG Msg Me +RNG Replace +RNG Tomas +RNG dez nuts +RNG9518 +RNGBandit +RNGVRNG +RNGiesi +RNGrim +RNGsetMeFree +RNJohn +RNJoseph +ROADTO100B +ROBAlN +ROBBOsickdog +ROCCAT +ROCKYY +RODRlCK +ROF0LFOR +ROFOLFOR +ROHTEENMUTSI +ROKO +ROLL TlDE +ROLLinPEACE +ROMBU +RONNIE COLE +RONZE +ROR0 +ROSTA +ROT LOST 6K +ROVANIEMl +RR Fourshore +RR55 +RRAMPIDD +RREKKLES +RRX YY RRX +RRayhan +RRevelation +RRickkert +RRobert +RRocket02 +RS Bread +RS Cinema +RS Jesus +RS Myrthe +RS Nico +RS SLAG +RS UFC NRL +RS ape +RS2 Legend +RS3 Refugee +RS3izBetter +RS6 Quattro +RSB Fox +RSBadLifeBad +RSDonny +RSGO +RSLtSgtZen +RSMAXD +RSPSisBETTER +RSPup +RSQT +RS_Tytin +RSfork +RSmake +RStrength99 +RSuomivihu +RTGoldleader +RTK86 +RTLadNumber4 +RU B Y +RU Petrified +RUBBERI +RUUNIKUNN +RU_Engineer +RUlS +RWB Codeine +RWSDOUG +RX S +RX7 FC3S +RXen0 +RY N0 +RY P +RYAN +RYN16 +RZAlex +R_D TRAJANO +R_andy13 +Ra +Ra fi +Ra1d +RaMR0D +RaRaJuana +RaSToG +RaaWa +Raaagnaar +Raab +Raaban +Raahe +Raahh +Raakanipsu +Raamsdonkje +Raanduin +Raassig +RabarberBarb +Rabbagust +Rabbie +Rabbit MD +RabbitFlats +Rabbitdude +RabbitsDong +RabidDolphin +Rabidherring +Rabiosa +Rabrt +Rabs xo +RacccAttack +Raccoon +Raccoon King +Raccooncow +Raccoonus +Race +Rachael +Rachey B +Racholini +Rachscape +Racteal +Rad Renegade +RadFeenix +Radacia +Radaenne +Radar +Radeo +Radia7ion +Radiance +Radiant Lux +RadiantSkye +Radiator +Radini +Radio +Radio DJ Dan +Radio Love +Radiohead66 +Radiologics +Radish55 +Radja333 +RadoslavvBG +Radrieldor +Radsurlak +Radsy +Radtastic +Radusa-Two +Raeghal +Raelir +Raen +Raf0da +Rafaael +Raffealy +Rafff +Raffineret +Rafi Tafy +Rafiniya +Rafn +Rafnar0G +Raft15 +Rafy +Rag +Rag Demon +Rag Doll +Rag Gdz +Rag List +RagToRiches +Ragani +Rage +Rage Fuel +Rage233 +RageCold +RageCombo +RagedIronMan +Ragefire1 +Ragegold1163 +Ragez Fury +Ragga +Ragga Muffyn +Raggedy Jeeb +Raggers +Raggnag +Raggy Reapzz +RaginBatts +RagingK9Fury +RagingReddit +RagingTroll +Ragingg +Ragnar +RagnarOsborn +Ragnariukas +Ragnarok96 +Ragnell56 +Ragni +RagsIIRichez +RagucciRafa +Ragurain +Ragy rag +Rahamasin +Rahamies +Raharu +RahbHurt +Rahdyxc +Rahedo +Rahimo +Rahis +Rahjer +Rahy King +Rai +Rai_3 +Raibu +Raichue +Raicun +Raid +Raid Lewis +Raid My Body +Raideris +Raiderrediar +RaidriarTGK +Raien +Raihan +Raihou +Raii +Raiicrow +Raikesy +Railee +Raimar1 +Raimiss +Rain +Rain Days +Rain Please +Rain ee +Rainbird +Rainbow +RainbowBeast +Raine +Rainer +Rainforest +Raining +Rainingbroz +Rainingmeltz +Rainman446 +Rainnos +Rainold +Rainshower +Raintown17 +Raisedbycows +Raiskausrapu +Raisson +Raisson X +Raistlin +RaistlinFasa +Raisya +Raivan90 +Raizerr +Rajat76 +Raje +Rajgo +Rajs +Rajvir +Rakaah +RakadB3 +Rakblood +Rake +Rake ur weed +Rakettikala +RakiRaki +Rakiata +RakingPurple +Rakkir +Rakoins +Rakru1 +Rakuko +Rakun Rakan +Rakupenda +Ralalallei +Ralgurr +Ralle1208 +Rallis +RalorLeetor +Ralos Rise +Ralp +RalphLauren +Ralphed +Ralphie3 +Ralphy Jnr +Raltsz +RalvekZul +RamYe +Ramae +Ramallah +Ramathorn +Rambling +Rambo +Rambo Prods +Rambo The 3 +Rambo The 4 +RamboBrad +RamboDaddy +RamboKiddo +RamboOmega +RamboSambo +Rame +Rame s +Ramen +Rameses B +Rami +Rami Tsunami +Ramleh +Rammdude +Rammmsteinn +RamonZera +Ramonix +Rampa +RampageOnly +Rampauttaja +Rampenisse +Ramrod +Ramsas +Ramsay +RamsayGrejoy +Ramxious +Ramzis +Ramztad +Ran-D +RanShakHazar +Rana pipiens +Ranamen7 +Ranarr +Ranarr Bowl +Ranarr Czar +RanarrScape +RanarrSmoke +Ranarrjuice +Ranarrseole +Randalf +Randalfen +Randalicious +RandallOG +Randdall +Randeaux +Randecker +Randinator42 +RandlesAlt +Random Day +Random763 +RandomGuy771 +RandomLemon1 +Randomguy38 +Randomized +Randomkul +Randomojojo +Randsoms +Randy Rawdog +Randy Rolex +RandyBanger +Randyke +Randys +Ranestumies +Rang +Rang3d Xp +RangPang +Rangahhh +Rangatan44 +Range +Range 4 mage +Range AR +Range Kiing2 +Range4Free +RangeGawd +RangePs +Rangeddddddd +Rangedly +Ranger +Ranger Fain +Ranger Hood +Ranger Uhle +Ranger82592 +RangerBoots +RangerFain +Rangerofgold +Rangerrr +Rangish +RangoII +RanjaForLife +Rank +Rank 1 +Rank 1 Gamer +Rank 1 Korea +Rank 1 Norge +Rank 1337 +Rank1Espada +Rank1NA +Rank350 +Rank62 +RankOneTurk +Ranox +Ranty +Ranul Oracle +Ranusian +Ranzo +Raoul +Rap50Cents +Rapasuu +Rapid +RapidCycling +RapidPancake +Rapidd +Rapiers +Rapolas +Rapolu +Rapt0ram +Rapterzz99 +Rapthor +Raptor +Raptor Jesuz +RaptorLuck +Raptorcaw +Raptorjk +Raptorman +Raptorsin6ix +Raptz +Rapu +Raquelo +Rare +Rare Arugula +Rare Chance +Rare Doggo +Rare Hat +Rare Panda +Rare Pets +Rare Vibes +Rareinpepe +Raresocks +Rarity +Rarity Belle +Rarma +Rasa +Rascus +Raseni +Rasenkage +Rashford +Raskasta +Raspatil +Rasput1n2k13 +RaspyLemon +Rassaasolo +Rasta Panda +Rastaclat +Rastafarlion +Rastamain +Rastaman +Rat Digward +Rat Flicker +Rat Has Dice +Rat Hunter23 +Rat L Traps +Rat Lettuce +Rat Sensei +RatKing365 +RatWithAGat +Rata +Ratchet48 +Ratcliffe +Ratdrin +Ratenda +RathianSP +Rathmai +Ratikka07 +Ratlifenerd +Ratlordmax +Ratm +Ratpno +Ratrace12345 +Ratrero +Ratsy J +RattleSsnake +Rattled +Rattlerskill +Rattlesnake +Rauhanrekka +Rauokse +Raur +Raurshank +Rauski696 +Rauss +Rauta +Rauta Juoppo +Rauta Sorsa +Rauta Tuomo +Rauta Urho +RautaGoblin +RautaLeksa +RautaPertti +RautaPizza +Rauta_Kessu +Rautafantic +Rautakuma +Rautis +Rauzee +Ravac +Ravangerous +Ravanth +Rave Pants +RaveBoy21k +Ravedeath +Ravemaste476 +Raven +Raven Frost +Ravency +Ravensword +Raventodt +Ravers +Ravesyy +Raving +RavingElf +RavishUndead +Ravlar +Ravs +RawPhazon +RawRyan +RawToast_13 +Rawbean +Rawduggie +Rawest +Rawke +Rawr +RawrItsKirby +Rawrr +Rawsome +Rawssss +Rawst +Rawwr Austin +Raxen Light +Raxorn +Ray Btw +Ray Kurzweil +Ray Rwars +Ray Sensei +Ray Squared +RayCon +RayMarshall +Rayfort +RayiiRios +Rayjin_Storm +Raykin +Rayleighs +Rayleight +RaymanXo +Raymo +Raymone +Rayne +Rayne Drop +Raynel +Raynelie +Rayner91 +Rayo McFly +RayofLight2 +Raypac +Rayrunner +Rays Max +Rayye +Raz Wolf +Razaia +Raze +RazenOh +Razer +Razer Elite +Razeren +Razguld +Razie +Razih +RazleBadazle +Razor +Razor Beast +Razor654991 +Razorblat +Razoriginal +Razorshark +Razrback +Razz1eDazz1e +Razzle +Razzzoor +Rb Salvation +Rb2790 +Rc +Rc Dark Rang +Rc_Power +Rcardio +Rcer +Rckr +Rddrz +Rds 44 +Rds Nerd +Rdushi +ReDrOc +ReFueld +RePeTiiTioN +ReRemakeAndy +Re_Rauzo +ReachAround +Reachinator +Reactate +Reaction Tec +Reactionary +Reactionss +Reactor15 +Read Art +Ready 123 +Ready4pwnage +ReadyToReap +Reah +Reaks +Real +Real Cute +Real Earth +Real Friends +Real Jesiah +Real Kev +Real Me +Real Reasonn +Real Skyline +Real Umbreon +Real Unlucky +RealAndBased +RealBoobs +RealBruceU +RealDrSeuss +RealJonner +RealKing11 +RealKingBee +RealLifeBot +RealLyre +RealMemeVPJr +RealPeelBoat +RealRicFlair +RealScythe +RealShyGuy +RealSpeed +RealStoney +Realcorkpig +Realdent +Realflamesss +Realismi +Realissm +Realist Knut +Realistg +Reality +RealitysGod +Really +Really Spicy +ReallyToxic +Realpk2004 +Realtank +Realtor R1 +Reap +Reapa +Reaper +Reaper0321 +ReaperLucid +Reaperkiller +Reaping Inc +Rearrange +Reaver Tru5t +Reavus +Rebaulten +Rebel +Rebel Serj +Rebelatto9 +Rebelgian +Rebelican +Rebellgutt +Rebelqt +Rebir7h +Rebirth +RebirthFlame +Rebis +ReboKhaihang +Rebooting +Reborn +RebornMuscle +RebornNips +Reborninc +Rebounder234 +Rebuild +Rebuild4free +RebuildLewi +RebuildMitch +Rebuildep +Rebuilders +Recable +RecentKill +Recess +Recharge +Recited +Recker1o1 +Reckless +Reckless Ell +Reckless Fyb +Reckless Lad +Reclaimar +Reclaiming +Recline +Reclined +Recnamalad +Reco Fam +Recolddone +Reconjack +Recore +Recover +RectalRoni +RectalRumble +Rectophobia +Recuder +RecyclePls +Recyr +Red Asia +Red Cavalier +Red Courier +Red Duke +Red Hick +Red Hippo +Red Hood +Red Hot Go +Red Kool-Aid +Red Nine +Red Osrs +Red Pepper65 +Red Rays +Red Rockin +Red Simon +Red Staal +Red Style +Red The Pom +Red Wings +Red XIII FF7 +Red hat +Red partyhat +Red3 +Red6 +RedCavalier +RedDwarf +RedGraceful +RedMare +RedRambler +RedRatedGame +RedRathalos +RedRegent +RedRusker +RedTwisted +RedWarlock31 +RedWol +Red__Mage9 +Redael +Redarekun +Redbackpker +Redben45 +RedberryLean +Redbull +Redbull Od +Reddo +Reddragon884 +Redflame +Redgit +Redikarp +Redisleft +Redius +RedkaWodbull +Redland +Redlonghorn +RedneckYoshi +Rednecks +Rednex +Redninja02 +Rednipplee +Redo +Redo Undo +Redouan94 +Redrevolve11 +Reds +Redshapes +Redshok +Redshoker +Redsk1ns +Redskin +Redsug +Reduced +Reductive +Redus +Redux +Redux Lux +Redz +Redza14 +Ree Mastered +Reeb +Reececup +Reecesoa +Reecie +ReedBadass +Reee +Reeebow +ReeeeZ +Reeeps +Reeet +ReefSharkz +ReeferKeefer +ReefyReefer +Reel_Arphios +Reels +Reemov3d +Reer +Reeyu +Reeze Tech +Reflection44 +Refleksfrode +Refleksi +Refluxerino +ReformedMatt +Reformer +Refried +Regal +Regan +Regelios +Regement +Regent Pve +ReggieWeggie +Reggin Cx +Regie +Regiis +Regio +Regular +Regular Iron +RegularJerry +RegularPlank +RegulusAurum +Rehbein +RehlapzZ +Rehoboam +Rehst +Rehzzy +Rei-chan +Reibnitz +Reichart +Reidar +Reids +Reidtheweed +Reign +ReignInBlood +ReignOfThor +Reigns +ReikenGIMP +Reimie0x +Reimo +ReimuHakurei +ReinLassen +ReinMoose +Reince +Reinkmyster +Reipas +Reisnom +Reisy +Reita +Reizzaz +Reject q p +Rejected Alt +Rejected Son +Rejected btw +Rejects +Rejet-01 +Rejey8 +Rejuvenating +RekaScape +Rekans +Rekenz +Rekkaboi +Rekkerta +Rekkt +Reklats +Rekna +Rekt +RektHavok +Rekunleashed +Relaaax +Relapse +Relapses +Relative +Relatived +Relax to Alt +Relent1ess +Relevancys +Relianah +Reliefed +ReligionBad +Reliinqish +Relik +Relinquishh +Relit +RelivinYouth +Relizent +Relizent2 +Relizents +Rellnquish +Relloktion +Relmu +Reload +ReloadFaster +Reloox +Relrekis +Reluctants +Rem Dogg +Rembs +Remcodingho +Remedial +Remiejj-BV +Remiel +Remillia +Reminded +Reminiscon +Remitin +Remix +Remixed +Remmos +Remmyy +Remn +Remo +Remorsed +Remspoor +Remtar74 +Remvrkable +Remylz +Remytouille +Ren to +RenLady +RenZelus +Ren_Otori +Renacan +Renall +Renarin +Renas +Renato +Renauddd +ReneeIsMaxed +Renegor +Renesau +Renewed +Rengar +Rengeki +Renger +RengokuRS +RengokuSmile +Renixion +Rennuts +Rennz +Renovato +Rensafari +Rent +Rentb0y +Renzo Bamf +Repathor +Repeats +Rephia +Replayroyke +Replenished +Replikantti +Replo +Reply To Me +Report Biden +Reported +Reporting U +Reppin519 +RepresentRS +Reprexain +Reps4Jesuz +Reptile +Reptile God +Reptiliano +Reptillian +Republic55 +RepublicofRS +Reputism +Reqtile +Requaahv +Requilog +Requin +RequireBone +Reredrum +Rero +Resallude +ResenBallZ +Resentfully +Reseriant +Reserv3D +Reshop +Resident +ResignWonki +Resilient +Resistzz +Resizable +Resk +Resoluutio +Respaze +Respeat +RespecTheMax +Respect Me +RespectMyDab +Respek +Respire +Responders +Respy +Respyy +ResrvdFinest +Ressara +RestIess +RestInPce +RestTooLaid +Restinp3ace +Restless99 +RestoredIron +Restrial +Restrio +Resultss +Resultzs +Resupplying +Retendous +Rethie +Retired Dead +RetiredMaboe +RetiredStic +Retr0virus11 +Retro +Retro PvM +RetroDeviant +RetroRaz +Retrohiili +Retrovision +Rettent +RetuKettu +Retupelle +ReturnToOne +Reub +Reubon +Reuborn +Reudo +Rev Hayter +RevDragon +RevZamorak +Revamp +Revamp cF +Revanche +Revellius +Revelwood +Revenant MKX +Revenant Rag +RevenantBoy +RevengerII +Revent +ReveredB3ard +Reverenciar +Reverenz +ReverieDC +ReversEffort +Reversedd +Revi21 +Revilia +Revofev +Revoke +Revolted +Revolving +Revs +RevsRebuild +Revus +Revvanth +Revx +Revzvy +Revzy +Rewbs +Rewinds Iron +Rewnlite +Rewns +Rewo +Rewriting +RexCox +RexM +RexMouser +Rexicur +Rexkat +Rexun +RexxNotReal +Rexxasaurus +Rexxer69 +Reyes407 +Reyko +ReynoldsWrap +Reystov +Reyswaldo +Rez X +Rezi +Rezident +Rezka +Rezki +Reznx +Rezy +Rezz Main +Rezz79 +Rezzn +Rfsu +Rgimenez007 +Rgk +Rgnfrg +Rhaegalion +Rhaegar +Rhaegard +Rhaegor +Rhagaea +Rhastae +Rhcprule6 +Rheal +Rheece +Rhette +Rhezmyn +Rhianne +Rhien +Rhiley +Rhino +Rhino Art +Rhino Prime +RhinoNuts +Rhit +Rhiyia +Rhk +Rho Ur Boat +Rhoads +Rhocky +Rhodesia +Rhogue +Rhondda +Rhorrn +RhuBarb3 +Rhubarbino +Rhuina +Rhyio +Rhyl +Rhyme +Rhyming +Rhyninn +Rhynoob +Rhys Irl +Rhys25 +RhysieBoy +Rhysos +Rhythm +Rhythm Games +Rhythms +Rhyw Peth +Ri v en +RiJect +RiKoCheP +Riaever +Riamo +Rias +Ribb +Ribeye1611 +Ribinha +Ribitz +Riboku +Ribu +RicVR +Ricadio +Ricanmonkey +Ricardato +RicardooR +Riccario +Rice +RiceAndTacos +RiceWrangler +Ricefishie +Ricepicker89 +Rich +Rich 1 Hita +Rich Noob +Rich Snoe +Rich13 +RichAround +RichGuy X +RichHarambe9 +RichMansDrip +Richaard +Richard +Richard Baer +Richard Moss +Richard12391 +Richards2705 +Richart 123 +Richguy3213 +Richie +Richterr +Richxrd +Richy +Richy Rich +Rick +Rick scape0 +RickAndVorki +RickDeckard +RickEscobar +RickRab +Rick_NLD +Rickard +Rickeh 1 +RicketyReck +Rickhs +Rickky Bobbi +Ricklet +Ricklewinks +Rickness666 +RicknessAlt +Rickolas +Rickos +Ricksking +Rickstaverse +Ricky +Ricky Bob E +RickydeRoach +Rickyj13 +Rickyrevine +RicoMangos +Ricoo +Ricotayqueso +Riddim +RidePine +Ridemyhomies +Rider +Rider Galara +RiderOfRohan +Rider_99 +RidgeRacerR4 +Ridgewood +Ridley +Ridley1990 +Ridored +Rie1yReid +Riektanminol +Ries2 +RiesBatsbak +Rif +Rif T +Rifampicin +Rifen +Rift Archer +RiftOversoul +Rig Pig +Riga +Rigelius +Riggas +Rigged1 +Riggerlyworm +Righ +Right +RightKnight5 +Rightthisway +Rigid Tony +Riglr +Rigondead +Rigondeaux +Rigourlas +Rigr +Rigtop25 +Rihmakallo5 +Rihsky +Riickkert +Riiggs +Riii +Riiico Suave +RiimuRatigan +Riippptttt +Riisi +Riitasointu +Rijst +Rik M +RikCastle +RikSavage +Rikador +Rikalero +Rikeez +Rikka-kun +Rikka-san +Rikky Flames +Riksaah btw +Rikten X +Riku887 +RikuLehDeku +RikuRNG +RikvWesting +Rilah1212 +Riled Up +RilesWright +Riles_Nation +Riley Mort +Riley1098 +RileyReidx +RileyVoelkel +Riltor Storm +Rimbton +Rimorix +Rimppa97 +Rimuru BTW +Rinby +Rindos +Ringboi5 +Rinhx +Rini Keeper +Rinky +Rinoa +Rinrus +Rinsumageast +Rio-Dono +Riolu +Riona +Riot +Riot Breaker +Riot Starter +Riotdeath +Riotz v4 +Riou +Riouha +Rip David +Rip25kChins +RipBigDoinks +RipFeKeenan +RipLo +RipMagikarp +RipRoidie +RipSnorter46 +RipTheBilly +Ripd +RipePineappl +Ripper +Ripperhino +RippleBear +Rippn +Ripsin +Ripstart +Ripulieinari +Ripulirulla +Riri488 +RiseOfTerror +Risencambrie +Rishhh +Rishloo +Rising serum +RisingHonour +Risingodslay +Risk +Risker +RiskinPixelz +Riskule +Risky Pete +Risky Ryan +Riskz92 +Rislearn +Rismani +Risotto +Risperdal +Risque Moose +Risqy +Ritchi026 +Ritle +Ritopikachu +Ritrole1 +Ritthback +Rittz +Riubuli +RivalIron +RivalTitan +Rivalguy25 +Rive +RivenGasm +River Kelda +River OSRS +RiverOfIron +RiverOut +RiverToSea +Riveriea +RiverzRaging +Rivy +Riwer +Rixhy +Riyazzz +RiyuK +RizeNSkrine +Rizi Bizi +Rizla King +Rizos +RizzardWizrd +Rizzhole +Rizzzoo +Rizzzyisback +Rj8532 +Rjtyyi +Rkaksi +RlCE +RlCEHEAD +RlFK +RlGBY +RlP Harambe +RlPMYMANX +Rlly G +Rmus1 +Rmve +RnBieber +RnGator +RnGisFocked +Rndl +Rng Depleted +Rng Maestro +Rng Rami +Rng4Display +RngIshit +Rngclown +Rnjeesus +Rnkji +Ro The Boat +Ro s +Ro2no +RoBoRhino +RoBoat +RoNNalDis +RoSki +RoT Nick +RoT is GAY +Roach +Road +Road Run +Road sign 73 +Road to kek +RoadBoat +RoadSpartan +RoadToALLPet +Roadbiker15 +RoadetoMax +Roadways +Roadz +Roam +Roaming Sky +Roanen97 +Roastedsteak +Rob Aero +Rob Hot Dog +Rob Iron +Rob Pooner +Rob Zombie +Rob2G +Rob94401 +RobDirkson +RobThePole +RobWilliams +RobWorker +Robb +Robb uwu +Robbbana +Robbbbb +Robbiboi +Robbie EN +RobbieJ547 +Robbin +RobbinDaHood +Robbo +Robby +RobbyMatrix +RobbyRott3n +Robeartoe +Robejose +Roben +Roben Jr +Robert +Robert Pires +Robert Stein +Robert T +Robert1f +Roberto700 +Robidoux +Robigo +Robin +Robin Van H +Robin564 +Robinhoodnow +Robjee +Robjon7 +Roblit +Robln +Robln l-l00d +Robodinho +Robodyx +Robok0p +Robokiller86 +Robolisten +Robologist +Robot +Robpar6 +RobsonV +Robtoe123 +Robust +Robyn550 +Roc3 +RocheLimit +Rochette +Rock +Rock Knight +Rock Nin +Rock Rage +Rock The Red +Rock Wizard3 +Rockabbages +Rockadelic +Rockafellah1 +RocketRock88 +Rockfists1 +Rockford +RockfordT +Rockin +Rockin Ness +Rockland +Rocklore +Rockmaker +Rockrets +Rocktail +Rockwell +Rocky +Rocky 1535 +RockyYourMom +Rockydig +Rocokoko +Roczor +Rod Goesinya +Rod Man +Rod Monan +Rod My O +Rod i +Rodefe +Rodeva +Rodimus55 +Rodje +Rodney +Rodney Farva +Rodnirt +Rodnizzle +Rodrick +Rodrigo +Roe2 +RoeGut +Roebie1 +Roei +Roekoeloos +Roel +Roerbakei +Roexzy +Roff +RoffXD +Roffie +Roffy +Rofie +RoflOs +Roflaye +Roflmao +Roflmaomg +Roflologist +Roga +Rogerthatxd +Rogier504 +Rogiertjuuuh +RogretheOger +Rogue +Rogue nr2 +RogueSoul03 +Roguestoney +Roguor +Rohafin +Rohekonn +Rohman +Rohmu +Rohr +Roice +Roid +Roidsy +Roihuvuori +Roithamer +Roixie +Rojas +Rokec993 +Rokki +Rokushoo +Rolann +Rolav +Rold +Rolde +Roldeh +Roldie +Rolex +RollOurOwnJs +Rolla +RollandSmash +Rolleston +Rollin +Rollin Clean +Rolling +Rolling Kush +Rolling2Hard +Rollingo +Rolls +Rollsie +Rolluik +Rolly83 +Rolpharoni +Rolson +Rom3 +Roma +Romad +Romare +Romarigo +Romboy619 +Rome +Romein +Romen +Romen Ranges +Romeo for u +Romeos GIM +RomeowL +Romic +Romka +Romo +RompLord +Rompmaninov +Romway +Ron Swansong +RonBurgundy +RonCumtastic +Ronald +RonaldReagan +Ronbiara +Ronch +Ronco6 +RondVierkant +Rondey +RoneRackal +Ronescape +Ronggo +Rongor +Rongrongie +Roni Hagert +RoniKysh +Ronn Coleman +Ronnicle +Ronnie +Ronnie Fe +Ronnie Ponny +Ronnie518 +RonnieKray +Ronniebob +Ronny +Ronokroo +Ronpoo +Ronti +Rony +Ronz +Roof +Rooftop Laps +RooieRotzak +Roolon +Roomhoorntje +Roommaster1 +Roon2h +RooneyDUNX +Roonscape +Roosa +Roosevelt19 +Roosevelt69 +Roosevelt79 +Roost Coffee +Root Exoi +Rootman34 +Roover +Rooxy +Roozom +Rope +RopeDart88 +Ropemaker +Ropew +RoqeSVK +RorannoaZ +Rorek +RorekMalc +Rorr +Rorvis +Rory Gall +Rory Stone +RoryBurnout +RoryJb +Rorys +Rosalktha +Rosco Jenkn +Rose +Rose Fritz +Rose of May +Rose tiara +RoseGold_A +RoseOnCasket +Roseanne +Rosemarrie +Rosemary +Roses R Red +RosetaStoned +Roshidragon +Roshyz +RosieBtw +Rosieflower +Rosin0nly +RosinHead710 +RosinScape +Roskamaster +Ross +RossOSRS +Rossaboy +Rossed +Rossssi +Rossys +Rosters +RostiKz +Rosv0 +Rot3x +RotJofaJofa +Rotagilla +Rotated +Rotation +Rotelli +Rothen +RothesLatrin +Rothgor +RotiPrata +Rotiforms +Rotom +Rotta +Rottapoju +Rotten +Rotten Vale +Rotten Wang +RottenEyeMoe +RottenGurl +Rottencotten +Rottenzotten +Rotterdam +Rotzschrank +Rouge +RougeDev +RougeManiac +RougeThief02 +Rough +Rough Games +RoughINSERT +Rounded +Rounded Xp +Rounder +Rounding +Rousey +Rousseau88 +Route +Rova +Rove +Rovicus +Rovka +Row Sripple +Rowdy Tobias +Rowe5000 +Roweeee +Rowg +Rowinovich92 +Rowls +Rowoep +RoxanX +Roxasroxs564 +Roxer +Roxie Valor +Roxxe +Roy385 +RoyLay +RoyZay +Roya2Face +Royal +Royal 69 +Royal Chief +Royal Death +Royal Rain +Royal Violet +Royal Wax +RoyalD3sire +RoyalMess +RoyalPurps +RoyalRolf +RoyalScumbag +RoyalShaco +Royal_Shock +Royal_inc +Royan +Royboy16 +Roye +Royo +Royollie +Roysrols +Roytang5 +RoyyyAfca +Rozensho +RozirPanda +Rozkol +Rozlucka +Roztomily +Rozzaa +RricketyREKT +Rro +Rs Bartender +Rs But Afk +Rs D +Rs God +Rs Jamal +Rs Kajcsa +Rs Olm +Rs Pikachu +Rs Wiki +RsBryce +RsGoku +RsOverGirls +RsRuinMyLife +RsSuomi +Rs_ReeCe +Rsanaded +Rsebb +Rset +Rsh Katje +Rsh10 +Rsky B +Rsn Kmt +Rsn_Adam +Rsn_Dillon +Rtlo18918B +Rtslash +Rty +Ru Ru +Ru2uo +Ru6 +RuMoRRs +RuRu-nyan +RuRu09 +Ruan +Rubber +Rubber Alt +Rubber Apple +Rubber Luffy +RubberApple +Rubbery +Rubbery Ra +Rubee +RubenD +Rubenich +RubiconGuy +RubikMouse +Rubinx81 +Rubish +Rubrek +RubsSandwich +Rubss +Ruby +Ruby Opal +Ruby Runes +Ruby5001 +RubyBlue +RubyBoltSpec +RubyEvelyn +RubyLvledUp +Rubystealer +Ruck +Rucked Faw +Ruckus +Ructions +Rudadoodadoo +Rude +RudeBoiElj +Rudekid1035 +Rudetopia +Rudi Andre +Rudii +Rudin +Rudin Alt +Rudolph +Rudy +RudyGiuliani +Rueben +Ruel +Rufie +Rufles +Rufu +Rufus Shaw +Rufus xD +Rug Klachten +Ruge +Rugg0064 +Rugpijn +Rugrat +Ruhl +Ruhpetitive +Ruhtrik +Rui HIMimura +Rui Sand +RuiMariz +Ruimte +RuimteMan +Ruinationnn +Ruined +Ruined Kap +Ruint +Ruizoeki +Ruk1a +Rukavi +Ruker +Rukias Feet +Rukusama +Ruky +Rule Elite +Rule34 Grogu +Rulesy +Rulesyy +Rullmane +Rum Lad +RumJeDobry +Rumble519 +RumbleYT +Rump +Rump Kicker +Rumpetask +Rumpkondens +Rumpleminze +Rumpstag +Run Alt +Run Down Mid +Run n Alch +Run1t3 +Run1t3 Cape +Run2paradise +RunCMP +RunFreek +RunNhideZom +RunRonRun +Runboof +Runboy25s +Runcatsmith +Rundamental +Rundi +Rune +Rune Scimmy6 +Rune Strg +Rune Toi +Rune Trophy +Rune Tunes +Rune Woolf +Rune l Scape +Rune lennyFe +Rune mendigo +Rune-Taneli +RuneAlt1 +RuneArguero +RuneBri +RuneFiend +RuneKing2h +RuneLight +RunePuuro +RuneShape +RuneWeems +Runebie93 +Runeblaizer +Runebryter +Runechi +Runecraft +Runecrafts +Runed Ltd +Runeiro +Runely +Runeman3134 +RunenSohn +Runepalmu +Runeranta1 +RunesCrafted +RunescepxD +RunescepxDD +Runeshaft16 +Runesniffer2 +Runesr4nerds +Runester9999 +Runeukko431 +Runeveeti +Runeventure +Runey +Runey Toons +Rungne14 +RunicXanadu +Runita +Runite +Runite Ricky +RuniteNerves +RunkoPalkki +RunnerTwoD2 +RunninBlood1 +Runnn +Runny Rectum +Runnynumber2 +Runolf +Runs +Runs Laps +Runtellthat4 +Runtu Reiska +Rup +RupOSRS +Rupea +Ruperd +Rupert Whale +Rupiss +Ruptured +Rupus +RureScape +Ruri +Rus s +Rush618 +RushAl0t +Rushana +Rushflame555 +Rushing +RushnSuch +Rushoo +Rusinahousu +Rusinapulla +Ruskajan +Ruskeareika +Russano +RussianLives +Russian_Fire +Russkill1000 +Rust +Rust Oxide +RustLasagna +Rustaaaagh +Rusted +Rusted Ape +Rustee +Rusticis +Rusticus +Rustig +Rustigggggg +Rustix +Rustu +Rusty +Rusty Spoons +Rusty99 +RustyFoot +RustyPlastic +RustySimon +RustyStipps +RustyTuna +Rustydog125 +Rustynice +Rustyw +Rusy002 +Rut469 +Rutgar +Ruthacus +Ruthers +Rutje +Ruto +Rutten +Ruttuperse +Rutu +Ruudcz +Ruuddie +Ruup +Ruut +Ruutana +Ruwe Dollo +Ruzafa +Ruzy +Rvght +Rvilleboy +Rvndy +RvneHQ +RvrseGiraffe +Rvsta +Rvvvy +Rwkw +Rwolfe +Rx bones +Rx-ll +RxHarmacist +Rx_Sparky +Rxscro +Rxzm +Ry Jones 21 +Ry T +Ry n +Ry-07 +RyGuyyy1 +RyKush +RyQzz +RyRgrMcFrly +Ryaite +Ryalae +Ryan +Ryan 178 +Ryan8529 +RyanApollo +RyanC203 +RyanFar25 +RyanKristoph +RyanNagato +RyanPick +RyanTW +Ryanandneal +Ryaneal +RyangalO +Ryanmattin0 +Ryann737 +Ryanpage +RyansRebuild +Ryanwouldsay +Ryawh08 +Rybizzle +Ryca +Rycerz Arek +Ryd +Ryder +Ryders +Ryderwear +Rydwarf +RyeAnn +RyeEx +RyePie +RyeYun +Ryeron +Rygelon +Rygo111 +Ryhan +Ryi +Ryjgar +Ryking +RylanIsLive +Ryleegh +Ryley +Rylios +Rylorg +RynHasAutism +Rynilion +Ryns +Ryokojin +Ryolm +Ryoma +Ryougi +Ryougi Shiki +Ryouma +Ryoush +Ryronman +Rystaloid +RystyRane +Rytacus +Rytis +Ryu Deadass +Ryu L +Ryugo +Ryuk +Ryukiral +Ryuko +Ryul Silvyr +Ryvik +Ryxidius +Ryyd +Ryzelf +Ryzema +Ryzho +Ryzloh +Ryzou +Rzasa +Rzy4k +S 0 R A +S A S H O +S A VV A G E +S C N +S C U Z Z +S E T C H +S G M B +S I N +S J H +S M A S H ER +S M I L E S +S O Z O +S P E E E D +S Q5 +S Rye +S Spirit +S T ACK E D +S T E F AN +S T E N +S T I L L +S T R 4 ever +S T R Pwnz5 +S U F F +S V N E +S W A N N +S a z z y +S acrificed +S aevar +S aii +S ammmy +S co t t +S cruffy +S e 7 e n s +S e a f o +S e e j +S ebbe +S emi +S enu +S err +S h a n e oo +S hadw +S hayzz +S hea +S hep +S imply +S k u ll y +S kari +S l M B A +S l3 +S nipz +S ofa +S offa +S ofus +S orrow +S oulz +S outh +S p00ky +S secy dy +S t e v e n +S t i +S t i g +S t i x +S tas +S u b j e ct +S uffa +S unz +S wan +S-525 +S-Market ll +S00000O0000k +S0FTPUPPY +S0L0 +S0L0 SL0AN +S0MALISLAYER +S0O0O0O0O00S +S0S JERRY +S0UVLAKI +S0Z4 +S0ar +S0ciety +S0dra +S0gg3 +S0ldern +S0lomon44 +S0lty +S0nical +S0phie +S0tg +S0thra +S11om +S1MPSLAYER +S1N6 +S1NA +S1ORM +S1SU +S1ayzAllDay +S1n0fWrath +S1ngul4rity +S287 +S2u2 +S3 Matt +S3ID +S3W3RSLVT +S3n4_Hc +S3oulful +S4M0HT +S4M20N +S4v4s +S5peedy +S60RDesign +S7arburst +SA alter ego +SAAB_Toxic +SAAIXX +SAGLAM +SAINt +SAINt Steff +SALM00O00N +SALM00OOON +SAMCRO +SAMMMMMY +SANDFROG53 +SANFEWLUVR78 +SANO +SANRIPOSYCHO +SANTERCOMTER +SANTO5 +SANYANOSTRAH +SAPl +SARAH +SARPBC +SATAN GOD +SATORIIN +SAUCEnJUICE +SAVVON +SAWPREME +SAlNT +SAlNTS +SAlYAJlN +SB DRIFT +SB Luke +SB Mac +SB Mully +SB2K +SBSBSBSBSBSB +SC0V +SCARED +SCHOOTSFIRED +SCOTUS John +SCR0TUM +SCRAMMMBLED +SCRIMS +SCRT SAUCE +SCYukino +SC_Josh +SClarky +SDC Thursday +SDV +SDVX +SDemotivated +SE Alaska +SE N SE +SECDEF +SELF +SEMI CHUB ON +SEMl DEAD +SEPTlC +SESACO +SETU +SEXY GRETA +SFTYALWYSOFF +SG +SGNG +SGTA +SGTX +SH333S +SH5 +SHAD0WBANN +SHAGED +SHANK SAMA +SHELDOR +SHERMnNATOR +SHElD-HEDA +SHIA +SHIA_WIRE +SHIDDED0N +SHIIIELDS +SHINY +SHINZ0N +SHOTGUNSUGE +SHRIIlIlIIMP +SHlESTY +SHlFTER +SHlNl +SHlVER +SIBS +SIDB +SIGMA MALE69 +SIGNZ +SIKKaudio +SILENT +SIMAA +SIR KIRSI +SIR_WHAT_NOW +SISDIS +SIayer +SIoopie +SJ7 +SK octorock +SKBToast +SKBerk +SKD +SKDMRX +SKDee +SKEEZUZ +SKKi63 +SKlDMARK +SKlNNY +SKlTZO +SL0AN +SL1T +SL3DNECK +SL3VEN +SL90 +SLAAYEEER +SLAP +SLAP A SL0TH +SLAY +SLAYER +SLBM +SLE Casper2 +SLEEEZY +SLNT +SLOpro +SLV +SM Esura +SM Tech N9ne +SM0KE +SMANisonfire +SMEGMAEATER +SMGO +SMHeMbRBoB +SMKoolin +SMOrc +SMOrc Weeds +SMOrc3000 +SMRT KO +SN0W +SN0WBUSH +SN3AKBO +SNAX +SNAlIlIlIlIL +SNUIVEEEEEH +SOCIAL SCARE +SOLO D0L0 +SOLlD +SOMALISTEVE9 +SOUL MASTER +SP1NK +SPAICC +SPANKWlRE +SPLEEBTEZ +SPLODGE +SPOODERMENNN +SPOOKAH +SPlCER +SPlCY RAMEN +SPlDER-MAN +SQLite +SQSHD +SR0o0RM +SR20 +SRH IM +SRSwiper +SS Iron +SSF Fe BTW +SSJ2 GhostMO +SSS-Latch +SSamm +SSco0by1 +SSironMage +SSlavic +SSnakeling +ST0n3 +ST3AKS +STAIGZOR +STALlN +STAMPEE +STARSZSZ +STAUNCHEST +STEEZ +STEEZ UwU +STERGS +STEVEYZERMAN +STEVIO +STElNSGATE +STElNSGATE 0 +STIFT +STM32 F103 +STOERE OMA +STPN +STR m8 +STRZI +STRlCKEN +STRlDERMAN +STSTSTSTSTST +STUB0RN +STYG +STZY +STlFFMElSTER +STlNGRAY +SUBAROO +SUJET0 +SUP3RCLAUDIA +SUPA +SUPERSET q +SUPERTAIKURI +SUPREME +SURPRlSED +SV_Exon +SW3GG3RZ +SWAGL0RD +SWE4TY +SWlPE LEFT +SYMBI0TE +SYMPATHY +SYRpaperclip +SZP-Qlimax +S_nacky +SaHiB +SaItbender +SaSoeur +SaYeon +SaZz +Saagarius +SaakeliMies +Saambellah +Saaq +Saarinen +Saassz +Sabba +Sabbatix +Sabbelaar +Sabeket +Sabel26 +Sabelt +Sabeltann26 +Saber +Saber Alter +Saber Lilli +Saber Six +Saberloco +Saberos +Sabich +Sabina +Sabitoo +Sabler +Sabo +Sabor Fresa +Sabotaging +Sabre Doge +Sabretooth +Sabu549 +Sabuwu +Sac +Sacck +Sacha Boeyy +Sachets +Sack 2 Dirty +Sack_Lunch +Sackofeyes +Sacolyn +Sacre +Sacred +Sacred Eli +SacredArtist +Sacrificed +Sad Boi J +Sad Fat Ugly +Sad Juggler +Sad Leaf +Sad43 +SadClownP +SadJB +SadPanda94 +SadWhiteFalc +SadamBHangin +Sadass +Sadcatxd +Sadge Izzy +Sadge2407 +SadgeCry +Sadgetseg +Sadiq +Sadism +Sadistic +Sadivy +Sadness +Sadting +Sadystic +Sadz +Sadz Rax +Sae Bae +Saena +Saenmin +Saeph +Saerdna97 +Saerom +Saetama +Saetre +Safavid +Safcon +Safe N Sound +SafeFromWork +SafeUp YOLO +Safecamp +Safelyfast +Saff +Saffat +Saffi +Safiir +Saftsack8 +Saga +Sagar +Sage +Sage Lao Tzu +Sage Lily +Sage North +Sage Vegas +SageO6 +Sageinventor +Sageme +Sager +Sager Main +Sagev +Saggy +Saggy Weenis +Sagittarios +Sags +Saguaro Joe +Sah D +Sahin +Sahonym +Sahra +Sai +Sai Chosis +Sai Saici +Sai1420 +SaiPhai +Said +Saifphire +Saigyouji +Saiin +Saika +Saikoh +Saikoo +Saikou +Saikshin +Sail Door +Sailing Prod +Sain +Sainola +Saint +Saint 7 +Saint Acura +Saint Andrew +Saint Bjorn +Saint Fabioo +Saint Fellow +Saint Hatred +Saint Hyde +Saint JJJ +Saint Silver +Saint Tmi +Saint Zero +SaintBurgs +SaintDienda +SaintDovey +SaintElspeth +SaintMilk +SaintPablo68 +SaintShiba +Sainted +Saintri +Saitam +Saitama +Saivaa +Saiyajin +Saiyan +SaiyanSkinn +Saiyanns +Saiyans +Sajjad +Sajzi +Sakhmett +Saki Nikaido +Sakix +Sakk +Sakke +Sakkyun +Sakobi +SakooR +Saksa +Sakuragi +Sal Magluta +SalBobo +Salacity +Salad +Salad Car +Salad Kareem +Saladhead25 +Saladsoup +SalamPacanam +Salamalion98 +Salbo +Salcal +Salda +Saledor +Saleen +Salford +SaliBronze +Salih +Salii +Saliis Main +Salista +Sallad +Sallariina +Salllamander +Salma +Salmelainen +Salmo +Salmon +Salmon Ikura +SalmonCookr7 +SalmonsRule +Salmos33 +Salms +Salomon +Salomon666 +Salone +Salorassi +Salsa +SalsaMurango +Salt +Salt Mines +SaltInTheCut +SaltPJ +SaltasVolfas +Salte 55 +SaltedCorona +Salten +Saltia +Saltigast +Salty +Salty 4 Life +Salty Cris +Salty First +Salty Fooker +Salty Gimp +Salty Guava +Salty Slimy +SaltyNakul +SaltyPears +SaltyPilgrim +SaltyQuackr +SaltyShrimp +Saltydivo +Saltzpyre +Saluskenas +Salvats +Sam Biddle +Sam F +Sam II +Sam Knight +Sam S +Sam Tha Man +Sam Zi +Sam btw +Sam1 +Sam5453 +SamFC +SamGaspacho +SamManSnow +SamV007 +SamW +SamWisely +Sama ntha +Samadier +Samadieron +Samaji +Samalorian +Samanthix +Samantics +Samay +Samb0Slice +Sambal Sauce +Samblader +Sambwo +Same Deal +Same Kid +Same Thanks +SameerM0 +Sameling +Samfew +Samfundet +Samgonz3 +SammGemm +Sammi80 +SammieRose +Sammito2 +Sammjoey +Sammstera +Sammuel +SammyGer +Samo +Samoski +Samphet +Sample size +SampleText +Samprini +Samps0n +Sampson +Samqqa +Samri +Sams Main +Samsara Kama +Samsoniene +Samsora +Samster8812 +Samu Saukko +Samubidladin +Samuel Hall +SamuelBrian +SamuelP223 +Samuell C +Samurai +Samusar7481 +Samwse +Samxy +Samzh +Samzju +Samzor +Samzy +San Quentin +San0 +San200 +SanHolo +SanPaid +SanSheng +SanTie +Sana +Sanada +Sanark +Sanbir +Sancta +Sancte +Sand +Sand Raider +Sand Shrew +Sandal Slap +Sandbar +Sanddemon527 +Sandelzi +Sanderr +SandhillFrog +Sandhog +Sandhur +Sandiey +Sandman1 +Sandmannen9 +Sandogan +Sandokan +Sandoval Btw +Sands +Sandviper40 +SandwichBag +Sandwichfish +Sandy +Sandy Claps +Sandy Land +Sandy OS +SandyLand +SandyMonkey +SandyWexler +Sane Panda +SanePizza +Sanellyyy +Sanfew Serun +Sangers +Sangi +Sangotha +Sangtuary +Sanguinala +SanguineHawk +Sanguinezti +SanguisDurus +Sanitary Poo +SanityCntrl +Sanjachi +Sanjai13 +Sanjin +Sanka +Sanka93 +SanodersNL +Sanoske13 +Sanphew +Sans Soleil +Sanshou +Sansos +Santa +Santa 07 +Santa Chielt +SantaChristo +Santapwner +Santasos +Santeri +Santeri333 +Santhacine +Sanzoku +Sanzoku HC +Sanzu_o +SaoriHayami +Saoro +Saosiiin +SaphiTheBear +Saphie +Saphirakush +Saphiro +Sapin +SapphicDiana +SapphicEmmmy +SapphicJade +Sapphirebear +Sapphirelove +SappieWappie +Sappihron +Sappphire +Sappx +Saqi +Saqib +Sar a +Sara +SaraNotDomin +Saradominas +Saradontmin +Saragomin +Sarah +Sarah Hagan +SarahWalker +Sarahsaurus +Saraie +Saran +Saran07 +Sarangae +Saraph +Saras BBD +Saratomi +Saraziel +Sarbles +Sarcasmder +Sarctopus +Sarcy Csp +Sardaukar +Sardlz +Sarecren +Sarfar +Sarge +Sargon III +Sariel +Sarkie +Sarmagedonas +Sarms Knight +Sarodin +Sarrafo +Sarrdukar +Sarri +Sarriesque +Sarro +Sarrz +SarthaMewart +Sarthe +Sarthinox +Sarthorm +Sarumite +Saryit +Sarytis +Sascha +Saserdoti +Sash +Sashadow +Saskel +SaskiaNaka +Sasser +Sasslax +Sasssie +Sassy +Sassy Rookie +Satada88 +Satamari +Satan +Satan Claus +SatanSquared +SatanarchyXX +SatanicGrill +Sataniciocus +Satans Ktten +Satchmoi +Satchyl +Satisfyed +SativaDreams +Satizfy +Satoo +Saturdayxz +SaturnHippo +Saty +SauLau +Sauce McBoss +Saucestad +SauceyFox +SauceyHorsey +Saucy +Saug +Saugy +Saul +Saul Bloom +Saul Pvm +SaulMozarela +Sault +Sauna +SaunaPaska +Saund +Saunders +SaundersRNG0 +Saundo +Saunty92 +Saurogar +Sauroiv +SauronsTower +Saus +SausageRyder +Savabeel +Savage +Savage City +Savage Gamer +Savage Kush +Savage Mind +Savage Pimpn +Savage Titan +Savage izJkD +SavageBigL +SavageSource +Savaged +Savakuda +Savalar +Saved +Saved Me +Savg +Savilahti99 +Savior +Saviour +Savj +Savjry +Savoureux +Savpryan +Savu +Savu Nahka +Savustettu +Savvo +Savvune +Savvvy +Savvy +Savy +Savy Neals +Saw Em Off +Saw Siege +Sawanne +Sawaz1 +Sawbonez +Sawdey +Sawrik +Sawzall12 +Sax +Saxerpillar +Saxlord2500 +Saxon +Saxon_knight +Say Allo +Say Freeze +Say Geronimo +Say Go Put +Say Gz Rn +Say aligh +SayMyName +SayNo2Ebola +Saya +Sayadzin +Sayersi +Saylorbtw +Saymouseart +Sayonara +Sayooo +Saypa +Sayrim +Sayrr +SaysNiceAlot +Sazch +Sazere +Sazme +Sazzarull +Sboy_90 +Sbraga +Sc ruffy +Sc0nesy +Sc0ttishDave +Sc1ttl3 +ScOx +ScOx ChrisM +Scabrick +Scaf +Scaggy +Scaha +ScalerSlut +Scales +Scampr +ScandalousHC +ScannerBen +Scape +Scape Jam +Scape Snake +Scape Steve +ScapeChad +ScapesGhxst +Scapeskater +Scapin +Scaping +Scar +Scar TNL +Scar of Time +Scarb OS +Scare077 +Scared +Scared Jr +Scared Zebra +ScaredOfAll +Scarfade +Scargut +Scarleto +Scarlett +ScarredScape +Scarsx +Scarves +Scary Face +Scary Me +Scary Parrot +ScaryBrandon +ScaryShadows +ScaryTerry +ScaryVacoom +Scat +Scat19 +Scatheful +Scatter +Scea +Scemblix +SceneGfX +Sceneryy +Sceptile +Scew +Schaapers +Schams +Scharnhorst +Scheemz +Schepo +Scheubz +Schienenwulf +SchijnWerper +Schildkroote +Schildpad +Schileru +Schiller1994 +Schimy +Schiphol +Schismo +Schizphrenia +Schlaide +Schlak182 +Schlanged +SchlipityDop +Schlitz +Schlock +Schlowmo +Schlynn +Schmaltz +Schmelting +Schmidtty641 +Schmokeyboii +Schmoovin +Schmuck +Schmuel +Schmuk +Schneemann90 +Schnei Yo +Schneidster7 +Schneyy +Schnitzel +Schnitzl +Schnocks +Schnoob +Schnops +Schnozz +Scholi +Schoolies +Schools +SchoonCombat +Schooner +Schoonzoon +Schoopity +Schorr +Schout +Schovaval +Schretty +Schricky +Schrodingus +Schuabinator +Schuck +Schuyler +SchwanzLord +Schweiaos +Schweigende +Schwiemann +Schwingy +Schwog +Schwoopity +SciCloan +Sciamachy +Sciario +Scids +Scils +Scimi +Scimista +Scimmy2face +Scion 1T +ScizR +Scizorp +Sclass707 +Scodran +Scoffs +Scofiz +ScoobaQ +ScoobiedO0 +Scooby +Scooby T1 +Scooby Yew +ScoobySnack +ScoobySnacks +ScoochPoooch +Scoopie +Scoops12 +Scooter999 +Scootr +Scoots +Scoped +Scorchbeast +Score +Scoreox +Scoreyy +Scori +Scorial +Scorialator +Scorlibran +Scorpiex +ScorpioBoy +Scorpslay +Scorqion +Scortyx +Scot ty +ScotianHerbz +Scotse +Scott +Scott 0888 +Scott Men +ScottJ +ScottKZ +Scotteh +Scottie +ScottieP +ScottsTotlol +Scottsdale +Scottvc +Scotty +ScottyPippen +ScottyThrall +Scottyx +Scourging +Scouse Lyfe +ScouseBandit +ScouseThanos +Scout +Scout Dorvis +Scout Troopr +Scout a raid +Scouting UIM +ScoutnStake +Scowder +Scp-2786 +Scr0t +Scradmaster +Scraex +Scrafo +Scrambledleg +Scrap +Scrappy666 +ScratchGolfr +Scratchzilla +ScreamIM +ScreamSavor +Screeb +Screen +Screws +Screws Floor +ScrewstonTex +Scrig +Scringo +Scrkidzl12 +Scrotboy +Scrotetseg +Scrruff +Scrub +Scruba10 +Scrubgod +Scruffy +Scrums +Scryzen +SctyDsntKnow +Scuba Steev7 +ScubaSnacks +ScubaSteveOG +ScubaStweeb +Scuff +Scuffed +Scuffed Jesu +Scuffed Ming +Scuffed Sire +ScuffedGoose +Scuggie +ScumBagAlex +Scumbag +Scumbag Joe +Scummy +ScummyMonkey +Scumpi +Scurlll +Scuro +Scurrilous +Scuto +ScuttleAway +Scuzz OS +Scvthe +Scwubs +Scybin +Scyld +Scythe +ScytheOrNeck +ScytheShreds +Scytheer +Scytheplease +Scythes +Sdelta230 +Sdsdsd789 +Sduckk +Se Ki +Se rena +Se7en Rye +SeBambi +SeDzz +SeLeV +Sea 7urtle +Sea Anemone +Sea Buoy +Sea Hawkins +Sea Lobster +Sea Monk +Sea More +Sea Saint +Sea Slugs +Sea Turtle +Sea Turtles +SeaManTaster +SeaShanty +SeaShellKing +Seagal +Seagaru +Seagate +Seal +Sealab +Sealegs Btw +Seamlessly +Sean E +Sean Is +Sean278 +SeanIsHiding +SeanRich1 +Sean_C +Seande4 +Seangie 91 +Seanii +Seantjl +Seany4444 +Seanye +Seanz +Seapy +Searched +SearingPain +Searob +Seas +SeasTheDay +SeatGeek +Seated +Seater +Seater HC +Seath1552 +Seatoad +Seaweed +Seazeee +Seb Fe +Seb Lt +Seb Sob +SebBTW +Seba Iron +Sebis +Sebla +Seboeber +Seboobs +Sebukai +Sebzy +SecBongToke +Secho +SecondMars +SecondStage +Secondary +Secondes +Secret +SecretlyACat +Secretly_Bad +Sectokin +Sector Six +Seculish +Secwai +Sedap +Sedentary +Sedlom +Sedrf23 +See Too Far +See u em +SeeMeGoing +SeeYou +Seed +Seed Of Dee +Seed386 +Seeeek +Seeejay +Seek +SeekerofIron +Seekerz +Seeking +Seeliss +Seems +Seems Legit +SeemsFair +Seen +Seen A Babe +Seenoevil +Seery +Seerz +Seffer Kover +Sefirah +Sefka Sil +Segelpaatti +Segma +Sego +Segs69 +SeibaRaion +Seifeltz +Seifer666666 +Seig91 +Seighilde +Seigneur5000 +Sein Blut +Seiskalehti +Seiverna +Seiya216 +Seize +Sejaeek +Seje +Sejj +SejjNesta +Sek Loso +Sekaiyatra +Sekava +Seko +SektorQ +Selaphiell +Selastiri +Selbyen +Seldrium +Selectic +Selena Gomes +Selesi +Self +Self Attempt +SelfStanding +Selfie +Selina Kyle +Selj +SellMaxMain +Sellerz +Selling ROTS +Sello_Hunter +Sellu +Selmer +Selostaja +Selyk +Semantic +Sembient +Seme +Semestro +Semeul +Semi +Semi-Stable +SemiReliable +Semih +Seminary +Seministi +Seminoles +Semirare +Semlan +Semours +Semper +SemperOP +Semperlex +Senarii +Senbonzakra +Sencillo +Send Backup +SendItKing +Sengster +Senhor +Senhor Prego +Senia +Seniab88 +Senior +Senior Wells +SeniorCui +SeniorLep +Senis6 +Senjor +Senkaiye +Senkuu +Sennno +Senny Bridge +Seno 45 +Senor +Senor Grumpy +Senor Nub +Senor Patata +SenorMarcSux +Senpai +Senpai Avv +SenpaiDecer +SenpaiiGod +Senpenbanka +Senpukyaku +Sens Army +Sens249 +Sensas +Senses +Senses Fail +Senses12 +Sensie +SensualSnail +Sentinel +Sentristi +Sentrosi +Senturia +Senzel +Seoyeonnie +Separi +Sephiore +Sepi testaa +Sepper +Seppiee +Seps +September 26 +Septic +Septimus +Sepv +Sequenced +Sequin +Sequinex +Sequissimo +SequissuAnau +Ser Bone +Ser Boris +Ser Kelvin +Ser Paddles +Ser Percy +Ser dracarys +Seracid +Seraff Fe +Seraph +Seraphine BF +Serblicious +SerenShadows +SereneMarine +Serenity +Serenity Now +Sereri +Serfival +SergeiSativa +Sergonomicus +Serial +Serialist +Serine +Serioga One +SerionKiller +SeriousLip +Seriousruss +Serkr +Serkus +Serls +Sernara +Sero87 +Seroplex +Serori +SerotoninBTW +Serpent Sin +Serpico +Serpula +Serpy +Serros +SertCocuk +Server +Servia +Service +Service Jobs +Service user +Sese +Sese778 +Sesil +Sessanna +Set h +SetItToWumbo +Seta +Seth +Seth1711 +Seth6191 +SethH350 +Sethalas +Sethliu +Sethmare +Setko +Seto292 +Settled +Setzal +Seut +Sevadeg +Sevalt +Seved223 +Sevenation +Seventh +Seventh Son +Seveoon +Seveoonn +Severith +Sevie +Sevvy +Sewdri +Sex Beast +Sex Gods +Sex Sea +Sex Vibe +SexEZ +SexFerguson +Sexi Rat +Sexperience +Sexsi +Sext0n +Sextor +Sextuple +Sexy Carl +Sexy Cholo +Sexy Style +Sexy Will +SexyFatGirls +SexyLefty +SexyPeaches +SexyShooterr +Sexyteurs +SeymourAses +Seyriu +Seytan +Sfa05 +Sfannie +Sfd +Sfen +Sfouf +Sg Mini +Sgn +Sgs flames +Sgt +Sgt J0hns0n +Sgt Jacques +Sgt Moogoo +Sgt Ru642 +Sgt Salliss +Sgt SaltySac +Sgt-Sub0_99s +SgtBuurman +SgtSausy +SgtSlaughtur +Sgtbea93 +Sgtfatboy +Sgtsoldier +Sh00t3r2O2O +Sh0rt Lived +Sh0rty +Sh0w +Sh3pathome +Sh4d0w009 +Sh4dowfox +Sh4rice +Sha r k +Shaan +ShabooBopWoW +Shabot +Shaboun +Shabuski +Shaco +Shaco Bot +ShaddyB +Shade T +ShadeSlay +ShadedWizard +Shadedmedic +Shadeknightt +Shadesypoo +Shado +Shado Man69 +Shadonnon +Shadow +Shadow Flare +Shadow Left +Shadow Specs +ShadowBobado +ShadowBoy001 +ShadowFink +ShadowGodEU +ShadowJosh +ShadowMakerz +ShadowPrism9 +ShadowSinz +ShadowSniper +Shadow_006R +Shadowclysm +Shadowcra +Shadowlimes +Shadowmax666 +Shadows Fall +Shadowscreen +Shadowsun +Shadowwheel +Shadsnp2017 +Shadum +ShadwRoca +Shady +Shady 716 +Shady Glade +Shady Shin +Shady417 +Shady78 +ShadyMilkMan +ShadyMinkins +Shadys Bro +Shadysider +ShaftyKrafty +Shafu +Shagnarok +Shags Bussy +Shagzy +Shahe D +Shahub +ShakaLakaInU +Shake +Shakeem +Shakeman +ShakenSoda +Shakkas +Shakuuuur +Shalamaar +Shalendra +Shallistera +Shalomga +Shalysa +Sham on Osrs +ShamSavior +Shaman +ShamanJon +ShamanLizard +Shamanletics +Shambler96 +Shame +Shamiina +Shampoe +Shampoo +Shamsal +Shamu +Shandaie +Shandooobie +Shane +Shane F3 +ShaneSJ +Shanee-oo +Shanem24co +Shaneobrahhh +Shaner +Shanfew +Shania +Shania Twain +Shanizmo +Shanked +Shanked it +Shanks +Shanks Haki +Shanksen +Shantaaa +Shantar +Shanteven +Shantideva +Shapalo +Shapaz +Shape +Shaper +Shapii +Shaqs +Shaqster1k +Shaquayquay +Shard +Shard 2 +Share E R +Share Sucks +Shareit +Sharing +Sharingan +Sharingan x +SharishaXd +Shark +SharkTheBait +SharkiFan +Sharkie200 +Sharkie92 +Sharktail +Sharkyyyyy +Sharmac +Sharmz +Sharn +Sharoxi +Sharp +Sharpeyy +Sharpgut +Sharpi e +Sharpie +Sharpman767 +SharpyClaw +Shart +ShartEnjoyer +Sharven +Shasan501 +Shat 2 Hard +Shatllef +Shatter +Shatter Day +Shaun +Shaun R +Shaun135961 +Shauna Vayne +Shaunhunni +Shaunni1 +Shaunrnm3 +Shaunyx +ShaveYourNek +Shaved +Shawn +ShawnBW +ShawnBay +ShawnXL +Shawni +Shawnoh +Shawrysx +Shay Kirbuti +Shaya +Shaya Rene +Shayd +Shaykolade +Shaymuz +ShaynRS +Shayne +Shayne 1 +Shayne Topp +ShayneW +Shaziyen +Shaznon +Shazu00 +Shazzys +Shckizm +She Moist +She Slackin +She is lvl18 +Sheashanera +Shebbi +Sheep +SheepKhalifa +SheepTrainer +Sheepi +Sheeppo +Sheer freeze +SheeshSkicka +Sheeshlor +Sheetm3tal +Sheetz +Sheev +Sheff-Rah +ShegoSimp +Sheguey +Sheikk +Sheilaaaa2 +Sheivattu +Shelbgasm +Shelbi +Shelburz +Sheldore +Sheldozer +Sheli +Shelios +Shelkun +ShellBeRight +ShellLeeBee +Shelldunk +Shen +Shen Btw +Shen-pai +Shenfu +Shenkie +Shep +ShepShep95 +Shepher +Shepherdess +Sheq +Sherbert96 +Sherkey +Sherlock +Sherlock 07 +Sherlockness +Shernz +Sherry +Shertie +Shes Nasty +Shes Royal +Shesterkin +Shev64 +Shevzzz +Shewolf Nova +Shezwick +Shh +Shh Im Maxed +ShiaLaBuff +Shiba +Shiba Miyuki +Shibidy +Shiddy +Shieldy +ShiftWorker +Shifteroo +Shifterr +Shiftless +Shifty +Shiftynifty +Shiftyy +Shifu +Shigure +Shihyi +Shiifty +Shiiftyy +Shiit +Shiit head +Shikhar +Shilo +Shilo Void +Shilomies +Shilvah +Shimmeister +Shimosh +Shin Nohara +ShinMalphur +Shinchi +Shine tales +Shing +Shinichiro +Shinigami +Shinigami 07 +Shininess +ShiningStar0 +Shining_Bind +ShinnGee +Shino +Shinobi +Shinook +Shinox +Shintaz +Shintygod +Shiny +Shiny Dragon +Shiny Glue +Shiny Mew +Shiny Olm +ShinyMimikyu +ShinyNoctowl +ShinyShyvana +Shionono +Shioshii +Ship I +Ship s +ShipCaptCrew +Shipoden +Shipppo +Shippy +Shir +Shir0u Emiya +Shirakami +Shiramasen +Shiranaii +Shire Fox +Shiredragon +Shiri +Shirlan +Shirts +Shishkemax +Shiskey +Shiv HD +Shivals +Shivered +Shiveron +Shivers888 +Shivoc +Shiyah +Shizlo +Shizzus +Shmazza +Shmeckington +Shmecko +Shmelf +Shmerlin +Shmew +Shmexy +Shmidtie +Shmo +Shmoah7 +Shneeb +Shnoobed +ShoToy +Shoarma +Shoarmadyl +Shocka +Shocked +Shockedme +ShockerMe +Shockzeyy +Shogaol +Shompy +Shongrislomg +Shonion +ShooK em +Shoog +Shook +Shoopdiesel +ShootYaSkool +Shootem40 +Shooty Tater +Shop +Shopferix +Shora57 +Shore +Shorelyy +Shorez +Short +Short Mike +Short Tale +ShortHoppe +Shortec +Shortguy +Shortstop819 +Shortz360 +Shot +Shot1200 +Shotixx +Shotoer +Shotzz +Shoulderr +Shouto +Show +ShowFeet +ShowUrPits +Showby14 +Shower +Shower Maxed +Shown +Showtek +Shozen +Shpee +Shpikey +Shpongle +Shrabbaa +Shran +Shredded +ShreddedMD +Shregz +Shreikkiller +Shrek +Shrek 6 +Shrek BTW +Shrek2 +ShrekLovr +ShrekazoidPR +Shreksalot +Shrik +Shrikems +Shrimp 72 +ShrimpForx +ShrimpStick +Shrimpa +Shrimping +Shrimpster +Shrimpy5 +Shroden +ShrogTheBarb +Shromik +Shromu +Shroom God +ShroomLord17 +Shroomjak +Shrtct +Shrumes +Shtankybruce +ShuZ +Shuaston +Shuckle +Shuddie +Shuffleee +Shuiin +Shultzy +Shun Conery +Shundo Mew +Shungite Bar +Shuno +Shunolog +Shunpown +Shunrai +Shunseh +Shupa +Shure +Shurty +Shut +Shut Up Megg +Shut Up Mmeg +Shutnik +Shv +Shvne +Shwift +Shwiftzy741 +Shwoompy +Shwoop +Shxtn +Shy Kirino +Shy Mew +ShyElfTrap +ShySphincter +Shyhorsegirl +Shyphii +Shypsena +Si Ya +Si d +Si mp +SiFu +SiIver Fang +SiRzZ Zeref +Sia +Siallus +Siamees +SiameseCat +Siamogale +Siane +Sianna +Siber +Sibling +Sic Mundus +SicSolaFide +Sicariiarum +Sicily +Sick +Sick Degen +Sick Ego +Sick Giraffe +Sick Irony +Sick Main +Sick Mark +Sick Pet +Sick Skill +SickFam +SickGainsBru +SickNasty +SickPete +SickPump +Sicka +Sicker +Sickhuman +Sickhunt +Sickle76 +Sicknez +Sicko +Sicko Stronk +Sickvibe +Sicxness +Sid and Geno +Sidabras +Side B +SideChump +SideMeatt +Sidecutters +Sides +Sidewinder15 +Sidge +SidijuS +Sidin1 +Sidka60 +Sido +Sidocahn +Sidro +Sie +SiebScho +Siegmeyer14 +Sielunveli +Siemke +SiennaEhtycs +Sierra Echo +Sierzant +Sierzy +Siesta +Sifu +SifuPlankton +Sig Man +SigSauer +Sigarda206 +SigeFrid +Sigefride +Siggen +Siggie +Sigh +Sighlent +SightUn +SightUn Seen +Sighted +SightlessDog +Sightlines +Sigiis +Sigin +Sigma Blood +Sigma Oasis +Sigma Seven +Sigmarz +Sigmazeous +Sigmet +Sign +Signd0g +Signoth +Sigrudson +Sihana +Sihl +SihuiRS +Sihva +Sihva Dark +Siida +Siiiiiiix +Siimon3 +Siimse +Sijmen +Sika +Sika-Mika +Sikauss +Sikerrim +Sikko +Sikko NL +Sikkosaurus +Sikn +Sikruz +Siks +Sikskilla +Silanz +Silasco +Silavex +Silcaria +Silcooper +Sild +SilenceSC2 +SilencedAF +Silent +Silent Sky +Silent too +SilentEnmity +SilentFabric +SilentFaux +SilentQ +Silentzsword +Silicon Z +Silinsh +Silixi +Silky +Silky Beauts +Silly +Silly Asian +Silly Kev +Silly Rum +Silly Virgin +Silly Zilly +SillyPsybin +Sillyibexe +Silmarilli +Siloxane +SilvaAlzir42 +Silvaa +Silvado +Silvanla +Silver +Silver Cave +Silver King +Silver Lugia +SilverForM +SilverLining +SilverPuni +SilverRizlas +SilverTeej +Silverado +Silverang +Silverbluds +Silvercrux +Silverfeelin +Silverfrost9 +Silverimo +Silverxlion +Silviii +Silvoan +SilvrLining +Sim Aero +Simeeon +Simel +Simetra +Similuck +Simmcheck +Simmi091 +Simmie +Simmololol +Simmondz +Simmumah +Simno Karys +Simoggy +Simon Bruh +Simon Jnrr +SimonCookie +SimonCowell +Simone Weil +Simp Andy +Simp4Jessy +Simp4Science +Simp4Tanz +Simpa +Simpinz +Simple +Simple Helm +SimpleSlays +Simplekinz +Simplest +Simplex +SimplexDabs +Simplicitey +Simplicityx +Simply +Simply Quiet +Simply Sam +SimplyBadass +SimplyBetter +SimplyFresh +SimplyLlama +SimplyNikki +SimplyPro +SimplyRiolu +SimplySendIt +Simply_JS +SimppCatcher +Simpson +Simse +SimulatedYou +Simutrans +Sin Cena +Sin Cere +Sin City +Sin Dragon +Sin0fWrath +SinCrux +Sinappihauki +Sinasappel +Sinatra +Sinbad +Sinbvd +Since +SinceOldDays +Sinclair Oil +Sincoura +Sindo +Sinefeld +Sinerule +Sinetine +Sinferna +SinfulDesire +SinfulDingo +Singerderek +Singulares +SingulariTx +Singularry +SinikOG +Sinister +Sinister C6Z +Sinister Key +SinisterLeft +Sinisterz06 +Sinistr Dave +Sinitank +Sinixx +Sink +Sinka +SinkingUnder +SinnerUK +Sinner_Blue +Sins +Sins of Thor +Sint Truien +Sinta +Sinterglass +SiontC100mph +Siorri +Sioux +Sip Cleeko +Sipa +SippinBeers +Sippy +Sippy 1 +Sipsta +Sipuliparoni +Sir Zhao +Sir 0wnalot +Sir Ali +Sir Ante +Sir Boberton +Sir Botje +Sir Brandito +Sir Burritoe +Sir Chancho +Sir Colossos +Sir Daven +Sir Deedge +Sir Delwin +Sir Doland +Sir Doobies +Sir Elusive +Sir Epic 3rd +Sir Ferreus +Sir Fire Ki +Sir Frekkel +Sir Fudmire +Sir FurDude +Sir Galleth +Sir Godfree +Sir Graj +Sir Ial +Sir Idwaly +Sir Iron 4th +Sir Jamie N +Sir Jinhai +Sir Junn +Sir LafaLafa +Sir Lanofg +Sir Leadfoot +Sir Lidd +Sir Lobster +Sir Luke1627 +Sir Max Tb +Sir Mordacai +Sir Mr Bro I +Sir Nak +Sir NichoIas +Sir Nuggers +Sir O Tonin +Sir One Shot +Sir Peg +Sir Poisonfa +Sir Pur Paul +Sir Queeffin +Sir Reflex +Sir Reos Lee +Sir Rhaenir +Sir Rolf exe +Sir Seifer +Sir Shrimps +Sir Slyck +Sir Son Goku +Sir Sparhawk +Sir Stidi +Sir Stitch +Sir Sucellus +Sir Sven +Sir Tanner +Sir Ton4 +Sir Towliee +Sir Truble +Sir Var4 +Sir Ving +Sir Vkk +Sir Whipit +Sir Wismar +Sir Wojtek +Sir Zakar +Sir friezer +Sir philippe +SirAirik +SirAmikVarze +SirAngo +SirArcAngel +SirArimal +SirBabbers +SirBerus +SirBjustice +SirBoma +SirBoopin +SirBroderick +SirCapper +SirChknNuget +SirCoolAsian +SirCumsAlil +SirDanSolo55 +SirDarrBear +SirDeimos +SirDouglass +SirDougles +SirDoyvid +SirDude +SirEfficient +SirEskimo +SirFroggits +SirGillespie +SirGoki +SirGrimsby +SirGrizzly +SirHines +SirHmm +SirHollywood +SirHumanBean +SirIronyMan +SirKakoiml +SirKefir +SirKill +SirKulls +SirLarry55 +SirLoinalot0 +SirLunarias +SirNexALot +SirOcean +SirPegAsians +SirPhockQ +SirPoo +SirPwn +SirRebs +SirRuck +SirSanders +SirSchmoopy +SirShakes +SirSilky +SirSlayalot +SirSpicius +SirSplinge +SirSunTitan +SirSwaggzz +SirTrea +SirVenompool +SirWhalord +SirXhantium +SirYiffer +Sir_massmo +Siraxis3310 +Siraz +Sircamm +Sircarenot2 +Sirdedalot +Sire Edward +SireSucks +SirenMan +Sirhca +Sirius +Sirixen +Sirjoshihad2 +Sirkuspelle +Sirlagger +Sirlightboy +Sirmordred44 +Sirnuclear +Sirroyce +Sirsa +Sirsteve99 +Sirstynkalot +Sirswish4 +Sirtippy23 +SisiJones +Siste +Sit Quietly +Sit xD +Sita Koll +Sita Rama +Sitharii +Sithlord +Sitinduck +Sitt +SiuMan +Sivior000 +Six 3 Ohh +Six Dix +Six Kills +Six Seasons +Six Sen6e +SixFootAmigo +SixOhFour +Sixcess +Sixfoot0001 +Sixint +Sixpkabs +Sixpounders +Sixten106 +Sixthflag +Sixty +Sixty N9ne +SixtyNine73 +Siynistr +Sizashi +SizeMan +Sizer +Sizzle Cat +Sjaak +Sjak +Sjakk +Sjakk Spill +Sjappy +Sjeb +Sjele +Sjenjatje +Sjenkie +Sjokoladebit +Sjoni +SjonnieDon +Sjonsen +Sjotha +Sjulstad99 +Sk Gollum +Sk Scooter +Sk ky +Sk u lly +Sk1llzy_RS +Sk1ttlz +Sk8rgrl474 +SkHiCharisma +Skaaddoosh +Skaane +Skachoo +Skada +Skada N +Skade +Skaduw99 +Skaf +SkaffeAgent +Skaicius +Skaikru +Skailas +Skakkae +Skal95 +Skanderbeg +Skank Hunt32 +Skarboeblie +Skarking +SkarmBliss +Skars Iron +Skaryth +Skate +Skate Squirt +Skatemyboard +Skater 1299 +SkaterJord +SkaterSkillz +Skatergod +Skaterlegs +Skaterune3 +Skaufel +Skcoot +Skedeby +Skedsauce +Skeeb +Skeer +Skeesh +Skeeterstein +SkeetlzPopz +Skeff +Skeggy +Skelebral +Skelethon +SkeletonSex +Skelex +Skelnik +Skelpy +Skely527 +Skelytom +Skepp +SkeptasMum +Skeptical +SkepticalSol +Skere +Skere Bert +Skermy +Skerp_Perp +Skertt +Sketch1e +Sketchiin +Sketti Water +Skewp +Skezi +Ski Gim +Skiba +Skibidi Tob +Skibidibills +Skidoodlee +SkiemLord +Skifree +Skilane +Skill +Skill Will +Skill issues +SkillFatigue +SkilldSkitzo +Skilldriver +Skilled +Skilled Boof +Skilled Roy +Skiller +SkillerC4 +Skillerbabes +Skillersj +Skilless +Skillexi +Skillhunter1 +Skillian89 +Skillius +Skilll +Skilllzdan +Skilln +Skillpace +Skillpadden +Skills +Skills Ahoy +Skills Boss +SkillsPets +SkillzGainz +SkillzLmao +Skillza +Skillzzz +Skilor +Skimer +SkinStitches +SkinTone5 +SkinnedYoshi +Skinny +Skinny Mage +Skinthix +Skinyoualive +SkipTheTask +Skipi +Skipper996 +SkipperMcgoo +SkipperPing +Skippy +Skiptutorial +Skito +Skittlz Doc +SkitzRs +Skitzad +Skitzpatrick +Skizzles +Skj +Skjaera +Skjeberg +Skjelve +Skkarpz +Sknnywhteboy +Sknor +Sko Birds +SkoalSnus +Skodem +Skoh +Skol +Skold +Skolder +Skolzera +SkoobiDooby +Skooier Bibs +SkoomaPls +Skopix +Skopusnik +Skordeath +Skorkath +Skorne +Skorned +Skotten +Skov +Skovduen +Skovtt +Skox +Skral +Skramlan99 +Skreecher +Skreeeech +Skreeeech Z +Skriptz +Skritman +Skrl +SkroTam +Skroooodge +Skrote +Skrrrtle +Skrudzas +Skruf +SkrumpKing +Skrychi +Skryze +Skubert +Skuddar +Skul +SkulbIaka +Skuldebrev +Skull 2148 +Skull Cove +Skull64 +SkullDemise +SkullFkdNex +SkullFricker +SkullTrailYT +SkullTricked +Skulled +Skullhead6 +Skullking199 +Skullpit +Skulls +Skulls Jr +Skumbag Xell +Skummi +Skummy +Skumpy +Skundos +Skunk +SkunkAsylum +Skunkerinho +Skunkieblow +Skwat MD +Skwurtle +Sky BIues +Sky Em +Sky Mages +Sky Satan +Sky VR46 +Sky and Sea +Sky is mine +SkyBouncer +SkyBroadband +SkyFlyPie +SkyKnight +SkyRizzy1 +SkySailing +SkySkyClover +Skyblownet +Skybussa +Skyda +SkyeKuro +Skyenss +Skygirl Tami +Skyleosaurus +Skymonster77 +Skymore +Skynet1188 +Skyom +Skype Call +Skyreacher +Skyrider +Skyrider50 +Skyrion993 +Skywalkingyo +Sl yx +SlGURD +SlGlL +SlLPH +SlRCUMSlZE +Slaats +SlabOfCorona +Slabs +Slackington +Slacky +Sladdbarn +Slade9100 +Sladist +Slagter +Slain +SlainThemis +Slaked +Slakito +Slakje +Slakoth +Slam +Slam Daddy +Slambo +Slamdabooty +Slamdark +Slamer1993 +SlammDaddy +SlammalS +Slamz +Slance +Slap +SlapMyWyrm +SlapShot777 +Slapen +Slaphead28 +Slapmeister +SlappChopped +SlappaBogan +SlappeStront +Slappenn +Slappers +SlappinMango +SlappybagsFC +Slaps +Slaps Nuts +Slapzinger +Slaqk +Slarkan +Slash +Slasher +Slasher z99 +Slasher0708 +Slaskepott +Slate Snake +Slats +Slaughta +Slaughtered +SlaughtrMeat +Slav Kings +Slava +Slave +Slavish +Slavtonio +Slay +Slay Addict +Slay More +Slay Or Bust +Slay Pets +Slay R +Slay Tim +Slay0rDie +Slay3rmate +SlayAChicken +SlayEeryDay +SlayForFame +SlayForJoy +SlayImpulses +SlayIsMyfame +SlaySir +SlayToSkill +Slayaholic +Slayborhood +Slaycation +Slaydenoob +Slaydo +Slayem Maul +Slayer +Slayer 247 +Slayer 267O +Slayer Azye +Slayer Clues +Slayer Helmz +Slayer King +Slayer L0G +Slayer Mid +Slayer Rome +Slayer Shark +Slayer Task +Slayer XPs +Slayer bond +Slayer n gp +Slayer314 +Slayer360 +Slayer7515 +SlayerAltAcc +SlayerKingv2 +SlayerRyan +Slayerburger +Slayerdog +Slayerg1g +SlayerisGame +Slayerknox +Slayerman +Slayers +Slayflake +Slayfrenzy +Slayhades383 +Slayic +Slayin +SlayinSkills +Slaying Poon +SlayingBooty +SlayingDave +Slayingit14 +Slayn +Slayology +Slayosaur +Slayr +Slays +SlaysIronman +Slayscaped +Slayter +Slaytr +Slayv +Slaywolf +Slayyer59 +SlayzyDayz +Slck Mark +SleanClate +SleazySEAL +Sleazyscape +Sledgendaddy +Sleeep +Sleep +Sleep Cycle +Sleep When +Sleepercell +Sleepgoood +Sleepierz +Sleepiness +Sleeping +SleepingCow +Sleepinonice +SleeplessC47 +Sleepnaut +Sleeps +Sleepy +Sleepy Fr0st +Sleepy Hoop +Sleepy Mulli +Sleepy Tired +Sleepy sound +SleepyPlantz +SleepySus +Sleepybear +Sleepzy31 +Sleet56 +Sleete +Sleighbor +Sleightyyy +Sleighyour +Slemmy +Slender +SlepinHose +Slepinn +Slepping123 +SleppySnek +Sletmar Kets +Slettenbak +Sleuth +Slev711 +Sleve +Slevenderrrr +Slewwyy +Sleya +Slibbon +Slice +Slice Dice85 +Sliced1Bread +Slicer3 0 +Sliceseau +Slick +Slickslipply +Slicore +Slidecast +Slides +Slidpanther +Slidz +SlieNinja +Slienced +Slievemore +SlihgtyWrong +Slikjee +Slim +Slim Gandalf +Slim Paul +Slim Yogurt +SlimJD +SlimeShat +Slimey Fish +Slimjim +Slimy +Slimy Uim +Slingin +Slinkeh +Slinky +Slioter +Slipery Peet +Slipory +SlipperySnek +Slise745 +Slit +Slizzle +Sll8 +SlnOfWrath +Slo +Slo w th +Sloanee +SlobOnMy +Slojsarn +Slokei +Sloopie +Sloothy +Sloper +Sloppy Joey +Sloppy WAP +Sloppy Zoot +SloppyGnomes +Sloppyninj +Slorkie +Sloshpack +Slotche +Sloth +Slothenly +Slothery +Slothhs +Slothly +Sloths +Slothy +SlottedPig +Slough +Slow +Slow Down +Slow Spirits +Slow blow +SlowRoaster +Slowky +Slowly Dying +Slowpoke +SlowrolI +Slowxpgamer +Sludgy1 +Slug Kiss +Slugggy +Slugjob +Slugr +Slum Village +SlumberGoose +Slumptality +Slurggi +SlurmsMcnzie +Slurmz +SlurpDaTerp +Slurpez +SlurpinBrews +Slus +Slush +Slushhy +Slushii +Slushiiii +Slushyy +Slusserbust +Sluthra +Slutism +Slutzilla +Sluwe +Sluwe Odin +Slxpz +Sly CHRlS +Sly Guy Matt +Sly Shy Guy +Sly Spyro +SlyPancakes +Slyfocs +Slyjack +Slymax +Slypes +Slythiren +Slyzuh +Sm0keyMcpot +Sm0rc420 +Sm1thyy +Sm6 +Sm8 AJ +Smaarips +Smac +Smack Snr +Smacka Fish +Smackatosh +Smacking 0s +Smackintoshh +Smaeow +Smai +Smajli +Smal Iron +Small +Small Chief +Small Idea +Small Iron +Small Paul +Small3y +SmallBlock +SmallBrained +SmallPepino +Smallemans +Smalley +Sman +Smang +Smart Dog +Smart Foam +Smart One +Smartbabe +SmarteeRS +SmarterMop +Smartfon +Smartiest +Smartyross +Smash Vials +Smashing +Smaug +SmaugSlayer +Sme Cape +Smeared +Smecher +Smeeezy +Smeegoles +SmegGIM Gr8 +Smeggyweggie +SmegmaJesus +SmegmaL0rd66 +Smegmatism +Smegmboy123 +Smekkes +Smeklius +Smeli0das +Smelix3 +SmellMyClam +SmellingMill +Smelly +Smelly Butt +Smelly Guy +Smelly Kip +SmellyGymSox +Smellyjeans +Smellypillow +Smess +Smetvrees +SmexyBaker +Smezzie +SmiTHSaNiTy +Smiddels +Smiddle +Smidjorgen +Smii +Smil +Smil3r +Smile My Boy +SmileBro +Smiled +Smilee +Smiles +Smiley AK +SmileyCyrus +SmileymanTim +Smilf +Smiliprophet +Smilts +Smimi Smumu +SmiqelAngelo +Smirk +Smit +Smite Bait +Smite4Ags +SmiteForAgs +Smited Time +Smites +Smith +Smith Inc +Smith a Cat +Smith2109 +SmithRebirth +Smithin +SmithingWhip +Smithinz +Smithoxmagic +Smithy +Smithy NZ +Smittyk15 +Smo3 +Smoak +Smob +Smoel Dicht +SmoggyB +Smokahontaz +Smoke +Smoke A Bag +Smoke Brb +Smoke J Brb +Smoke Oil +Smoke2Fly +SmokeChedFTM +SmokeCheds +SmokeM0B +SmokeSocial +SmokeandCum +Smoked Bacon +Smoked Ed 92 +Smokedale +Smokee +SmokeeLoki +SmokerOfDank +Smokes +Smokey +Smokey Eyes +Smokey201 +Smokeynutz +Smokeynz +Smokiecat +Smokin Clans +Smokin Perks +SmokinBlunts +SmokinChills +Smoking +Smoking Hash +SmokingFlax +SmoknDReefer +Smol +Smol Big Toe +Smol Kupo +Smol Lyra +Smol Pikachu +SmolDeer +Smoland +Smolrice +Smooooove +Smooth +Smooth Draft +SmoothRabbi +Smoothlu +Smoothpossum +SmoqueWeed +Smork It +Smoss +Smot Poking +Smpli +Smuddy +Smug +Smug Advice +Smug Grin +Smulknul +Smurf +Smurfboard +Smurfed +Smurfingt0n +Smurfman254 +Smurfukas +Smurghilda +Smurky Maart +Smurphington +Smush +Smush Things +Smushma +SmushyCows +Smuvies +Smuzzle +Smythy +Sn0op +Sn0rkath420 +Sn0wb4ll +Sn1p3 +SnYp +Snabba +Snack Bar +SnackJack +Snackspace +Snacktime +SnafuPC +Snaggapus +Snaghyrnd +SnailNipples +Snake +Snake Boss +Snake Jazz +SnakeSpec +Snakebite37 +Snakebites +Snakedeath2 +Snakedogbear +Snakeling +SnakeskinRag +Snaks +Snaky +Snaky Snake +SnapMyCarot +Snapa7 +Snapboog1e +Snape Grass +Snapeeh +SnapperSnafu +SnappySplash +SnarTheCook +Snarbo +Snarf +Snarflaxus +Snarfsnah +Snarglefox +Snarl +Snarx +SnaszAndrejj +Snatchquatch +SnazzyLt +Sneak Dissin +SneakEnergy +SneakKhajit +Sneakbo +Sneakee +Sneaky +Sneaky Chair +Sneaky IM +Sneaky Shark +Sneaky47 +SneakyBaloup +SneakyCake +SneakyEmu +SneakyFrogg +SneakyGnomne +SneakyOD +SneakyPete +SneakyTay +SneakyZoot +Sneakymag3 +Sneakyvicn +Sneakywaffle +Sneakz +Snee +Sneekerz +Sneekey +SneekyBeeky +Sneekydied +Sneeuwpoeper +Snefnuk +Sneide O_o +Snek zy +SnekInMyBewt +Snekkerboden +Snekling +Snekty +Snekty Jr +Snelms Deep +Snelmz +Snibzy +Snickers +Snickersbite +Snicklesz +Snide +Snide Senpai +Sniff K +Sniff this L +Sniffi +Sniffin 24-7 +Sniffin Bags +SniffinBags +SniffingClue +Snifflematt +SniffmySmoje +SniffyMonkey +Snike4 +Snikepaven +Snipe +SnipeOne045 +Sniper +Sniperfrank1 +Sniping +Snipor +SnkyGreninja +Snlly +Snny +SnoWorm +Snobby +Snobby Elite +Snoep +Snollen +Snoobsteri +Snoogens +Snookies +Snoop +Snoop D9 +SnoopSiah +Snoopfyzle +Snoopy +Snoot Boops +SnoozeBolton +SnoozingBear +Snoper +SnoreLunaLax +Snorff1 +Snorklarn +Snorlax +Snorlax9030 +Snorlaxz iLy +Snorona +Snot +Snotlapje +Snow +Snow Day +Snow Poff +SnowBunnyhvn +SnowEmpress6 +SnowManSam +Snowangel18 +Snowballerz +Snowbaru +Snowclub +Snowdaze +Snowearth +Snowelle +Snowfall +Snowfield +Snowieflake +Snowiest +Snowii +Snowmen +Snowscythe +Snowsmith43 +Snowvof +Snowy Winter +Snowy2653 +Snowyo26 +Snowys Main +SnuSnuShi +Snubby +SnugLikeABug +Snuge +SnuggleSnail +Snugglez +Snugins +Snuift +Snuite +SnusMumr1ken +Snuskig +Snusti +Snuup +Snuus +Snuuska +Snype_U +So Far To Go +So Flattered +So Inagawa +So Iron BRUH +So Jamiezing +So OSRS +So Quiche +So Warm +SoHighhhh +SoLoH DoLoH +SoMoist +SoSimPol +SoSleepy +SoStronk +SoUhBtw +SoVeryInvis +Soaa7 +Soad +Soally +Soap013 +Soaphia +Soapybubble +Sobe +Sobe VII +Sober +SoberFarmer +Sobibor +Sobotka +Soburin +Sobzy +Socca +Soccerc12 +Soccermom02 +Soccy +SocialAnxty +Socialism +SocialistGuy +Sociality +Sock Jesus +Sock Starch +Sock Stealer +Socket +Sockks +Socks +Sockum +Socrates +Socrates001 +Socratestes +Soctch +SodaGrab +SodaLambz +SodaPopPunk +Sodaseg +Sodasokwa +Sodd +Sodo Pop +Sodobrasil1 +Soecara +SoegLeppel +SofaKingHI6H +Sofakingdom +Soffachka +Sofia +Sofia Cooper +SofiaVergara +Sofiero +Sofoni +Soft +Soft Chicken +Soft Dump +Soft Geeves +Soft Jesus +Soft to Hard +Softboil +Softcorejmac +Softer +Softest +SoftestFox +Softice +SogSteelrock +Sogeking +Soggy +Soggy Napkin +SogxNeutro +Sohcahtoa090 +Sohh +Sohl +Sohrac +Soi +Soi Cowboy +Soija +Soisox +Soivio +Sojuah +Sol Buendia +Sol Heredic +Sol Heretit +Sol Leo +Sol Rock +Sol o +SolTeevo +SolaDuaeManu +Solakoust +Solan +Solar Stone +Solar754 +Solarized +Solarrr +Solaryohm +Solarys +SolasLexeth +Sold +Sold GF 4Gp +Sold My Name +SoldMyRNG +SoldMyWife +SoldUrDad4GP +Soldaat +Soldaat824 +Solder +Soldjer +Soldtheman +Sole226 +Solek +Solely +Soley +Solibiobois +Solid +Solid Snack +Solid Stache +SolidSnape +Solidtag +Soliform +Solimanx +Solitary +Solkrieg +Sollor +Solmlet +Solo +Solo A7X +Solo Aero +Solo Arron +Solo Blitzy +Solo CM +Solo Chumb +Solo Dani +Solo Foxy +Solo Geeber +Solo Gira48 +Solo H3llz +Solo Hayden +Solo Herbo +Solo Idenn +Solo Jawn +Solo Jones +Solo Jord +Solo Kev +Solo Mace +Solo Mus +Solo Road +Solo Romte +Solo Russian +Solo Sieb +Solo Sirva +Solo Trojan +Solo Umbreon +Solo Ward +Solo Wind +Solo Xenopus +Solo Yoyo +Solo kris +Solo snapper +Solo2424 +SoloBandit +SoloBongo +SoloCanadian +SoloDeicide +SoloDeth +SoloDynamix +SoloFireFist +SoloFlar +SoloFletcher +SoloHotDog +SoloIron30 +SoloMerx +SoloMishMosh +SoloMission +SoloNotAlone +SoloProject +SoloRob +SoloShow +SoloSloop +SoloSmackbar +SoloSnhaas +SoloSupOnly +SoloTibbs +Soloable +Solobussy +Solocek +SolohellRat +SoloingLife +Soloman50 +Solomasi +Solomon +Solomon Kane +Solomopp +Solos Turn +Solowerkz +Soloyo +Solsa +Solucki +Solufana +Solus +Solus RS +Solvent +Solvent less +Soly Handal +SomalianRats +Somalor +Somavrana +Some +Some Pets +Some Ranger +Some Use +Some mad dog +Some1youno +SomeDirtyOar +SomeGoldDust +SomeRSIdiot +Somix +Somniac One +Somnolent +Somoshoho +Somppup +Son Goku MF +Son Huntr +Son LeGeND +Son o Rous +Son of Akkha +Son of Hail +SonArtorias +SonBuns +SonIron +SonNamedBort +SonOfDecay +SonOfGandalf +SonOfWright +SonVsStepmom +Son_Jo +Sonc +Sondey +Sondr +Sondra +Sonekta +Sonett +Song +Songs Of +Songsteel +Sonhov +Sonia Strumm +Sonic 513 +Sonic Kp3 +SonicYouth +Sonicgg1 +Sonics +Sonics Alt +Sonidoo +Sonjini +SonneTeufel +Sonol +Sonsofkyuss +Sonx +SonyVegas17 +Sonycboom +SooCrispyy +SooUnlucky +Sookadiik +Soolo +Soon +SoonAHusband +Soonifer +Soop Pock +Soop3rpig +SootSpritez +Soothe +SootyWhale32 +Soph +Sophinx +Sophlex +Sophomaniac +Sophy +Sopranos +Soqz +Sora +Soraaxle +Soradin +Sorado6 +Sorarpegius +Sorbits +Sorbosander +Sorcere10 +Sorcerer5555 +SorcererOdin +Sorcerio +SorceryFish +Sordnatra +Sore +Sorec +Sorenisbad +Sorenn +Sorgrum +Sorinvv +Sormeton +Sorose +Sorry +Sorry Iron +Sorry1mLate +Sorryganster +Sortable +Sorted +SorthIon +Soruve +SosBoerrr +Sosig +Soskiller6k +Soskunde +Sosraid +Soss +Sossukorva +Sossumafia +Sosuke Aizen +Sotamage +Sotetseg +Sothe1 +SotonSteve +Sottetseg +Soujy +Soul +Soul Burger +Soul Scaper +Soul Sleep +Soul v9 +SoulEater957 +SoulMadness +SoulOfMidir +SoulSteala +SoulUnleash +Soulbarrier +Soulbearer +Soulcape +Souldia +Souled 0ut +Soulja Lance +Soulkilled3 +Soulkn +Soulles +SoullessMask +SoullessWood +Souloh0 +Soulololol +Soulplay Gee +Souls Mate +SoulsRampart +Soultiller +Soulxicution +Sound Soul +Soundbar +SoundsOfSoul +Soup +SoupEyes +SoupOfTheDay +SoupTheDuck +Soupshi +Sour +Sourzilla +SousChefLuna +Sousse +South +South Dakota +South Park55 +SouthPillar +SouthSide +Southampton +Southenders +Southern +Southp0le +Souvenierr +Souvis +Souvis5 +Soux +Sovacam +Sovakat +Soveth +Sovetskie +Sovi +Soviet +Soviet Union +Sovryn +Sow Love +Sowodasoap +Sox207 +Soxinder +Soy Duro +Soy Sauce +SoyBhoy +SoyJuanEuro +SoySoySoySoy +Soyez +Soylemagne +Soylo +Soz Misclick +Sozan +Sp00n +Sp1cy +Sp1cy Ramen +Sp1cyAvocado +Sp33Dkillz +Sp33dy +Sp3c Deck +Sp3nC +SpARioN +SpBongile +Spaar Lampje +Spaca +Space +Space Bussy +Space Lily +Space Marine +Space Orbs +SpaceC +SpaceEnter +SpaceScape +SpaceToker +Spacealt +SpacedPinata +SpaceeCowboy +Spacejumper0 +Spacing Outt +Spade-e +Spadey +Spag +SpagBolCol +SpagHacked +Spaget1111 +Spagett +Spajina +Spalling +Spam Lite +SpangeBerb +Spangebob +Spangl +Spangledbun +Spanish +Spanish Dave +SpankFox +Spankies Lit +Spanky +Spann +Sparacino916 +Sparc +Sparc Mac +SpardaWallet +Spare +Spark +SparkRS +Sparkles +Sparklesbean +Sparky3433 +SparkyD5 +Sparkyo +Sparre +Sparta2 +Spartac_us +Spartacus855 +SpartanDrgon +SpartanSheep +SpartanSlick +Sparte +Spartin028 +Sparty +Spasian +Spat Fastic +SpatialMagic +Spattu +Spaustin80 +Spauz +Spaynce +Spctwm +SpdrBiteJosh +Speak +Speakerbocks +SpearRue +Speat +Speats +Spebi +Spec A Ho +Spec Master +SpecAgent713 +Special +SpecialBus +SpecialGuest +SpecialPVM +Speciiik +Speckles +SpectrlHeist +Specz +Speechwriter +Speed Colas +Speed Wobble +SpeedPony44 +SpeedSouls +Speedalot ak +Speedball1 +Speede +Speedlund +Speedrun +Speedster +Speedy Cd +Speedy Click +Speedy Rulzz +Speedy9921 +SpeedySpider +Speeldoos +Speen Big +Speeze +SpejsonNM +Spek +SpekKas +Spektur +Spellgoth +Spenc +SpenceSuh +Spencee +Spenceey +Spencer +Spencer O +Spencerr +Spencerz +Spend +Spendlove +Spengineer +Spennel +Spennel V2 +Spenno 1 +Spensaurus +Sper +Spermlet +Spero +Speshal +Speshl +Spesho +Spettkaka1 +Spewis +Spewler +Spewlie +Spezza +Sphere +Sphinx +Sphinx66 +Sphooner +Spice +SpicelessJoe +SpiceyBoy39 +Spici +Spici Boi +Spicy +Spicy Noods +Spicy Rahman +SpicyMemeGod +SpicyMoney +SpicyPepe +SpicyVitus +Spide +Spider +Spider1357 +SpiderPhenom +Spiderhead +Spiderpig +Spidersnot8 +Spiderw5 +Spiderz 3 +SpideyC +Spidoo +Spiering +Spierpijn +Spigniv +Spike05 +SpikesterHC +Spillage +Spillingx +Spin911 +Spineweilder +Spinkle +Spinnenking +Spinnenweb +Spinolyp +Spirit +Spirit Box +Spirit Cube +Spirit Owner +Spirit Rok +Spirit Sin +Spiritcraft +Spisek +Spit man +SpitfireSR +Spitiz +Spizazzy +SpizzyMarz +Splarf +Splarn +Splash LT +Splash-8 +Splashattak +Splashcarrot +Splasher +Splashes +Splashley +Splashworlds +Splasion +Splatter300 +Spleaner +Splessp +Splezaa +SpliceTFY6H +Splidge +SpliffMaster +Spliffore +Spliiffy +Splinta +Splinterhand +Splitarellie +Splitfaction +Sploof +Spluge +Splyce +Spo0n +Spocuch +Spodey +Spoice +Spoilted +Spoka +Sponch +Spongey +Sponkz +Spoodersussi +Spoog +Spookachtig +Spookadoodle +Spookfish +SpookiBoogi9 +Spooky Beech +Spooky Ramen +SpookyCarl +SpookyMain +Spookyou +Spookytoot +Spoon +Spoon Full +SpoonFedFred +SpoonFedii +SpoonMePlz +SpoonTracker +Spoonay +Spooncera +Spoondow +Spooned +Spooned Simp +SpoonedBunni +SpoonedNormi +SpoonedWhen +Spoonfed BTW +Spoonihomo +Spoonku +Spoonletics +Spoonmannn +Spoons +Spoood +Spoookems +SpoopyDooToo +SpoopyNooper +Spoorwijk +Spooxky +Spop +Sporer +Sport Leader +Sport425 +Sports Bike +Sportsnut911 +Spotifee +Spotmaster 5 +SpottedBass +Spottednoble +SpotterN +Spottie +SpowSaus +Spr1ditis +SprLemonHaze +Spraahz +Sprattet +SprayM0re +SpraynMantis +SpreadButter +Spreader +Spria +Sprice +Springer +Springii +Sprinty +Spritbilist +Spro max +Sprog Legend +Sprogdor +Sprooti +Spruit +Spry +Spubb +Spud +Spudalumps +Spudge +Spudinator +Spuge +Spuhcific +Spuhgetti +Spuitopbruid +Spunknik +SpunkyLlama +Spurted +SputtyBTW +Spyder Sin +Spydig +Spyike270 +SpykeZim +Spykes +Spyriano +Spyro +Spyro 3 +Spyrooooooo +Spytech44 +Sq Head +Sqe3zy +Sqeat +Sqiit +Sqix +Sqoub +Sqreech +Sqrwl +Squab Cat +Squabs +Squad of one +Squadleader +Squaire +Squall +Squall44444 +Squallicious +SquanUK +Squanch Rat +Squanchhy +Square +Square One +Squarebodies +Squat Slav +SquatCobbler +SquatJogsBro +SquatNation +Squatting +Squaw +Squeakes_x +Squeaky Cow +Squeedly +Squeeeegs +SqueegeeLord +Squeeze +SquidNumber0 +SquidSquad +SquidTofu +Squidby +Squiddle +Squidgling +Squidie +Squidler +Squigiglius +Squigs +Squigtime +Squinch +Squinch Alt +Squinton +Squintts +SquintyNinja +Squire Yaper +Squirlruler +Squirly69 +Squirrel +Squirrel Pop +SquirrelTM +Squirreled8 +Squirrely W +Squirt2God +SquirtsAlot +SquirtyHersh +SquirtyMcD +SquishySir +Squonking +Sqwalle +Sqwarka +SqwezMyLemon +Sr Dipper +Sr8d +SrBambino +SrMick +SrMuerte +Sraracha +Srelek +Sri +Srogi Wujek +Srs +SrslyTired +SryAFK +Sshscaptain +Sshuggi05 +Sssnakepit +St Chrewin +St Liam +St Newman +St eve +St itch +St un +St0kStaartj3 +St0ney +St0oge +St4bU +St4rCh11d +St8hunter +StBasilthGr8 +StDecker +Sta Mama +StaIemate +StaJeOvo +Staasi +Stab3r +Stabalot +Stabobis +Stacii100 +Stackdude +Stackey +Stackieks +Stackin Dosh +StagBeer +Stagden +Stagmuss +StagnantAlt +Stagnation +Stago +Stahlinski +Stain Master +Stak +Stake Me +StakeOrQuit +Stakebril +Stakens +Staker +StakerOhWait +Stalactites +Stale +Stale Chips +Stale Dough +StaleBagle +Stalefloe +Staley +Stalifax +Stalk +Staller +Stalline +Stalphie +Stamin +Stamina Pot +Stamkoz +Stammer +Stampie +Stams +Stamuhnuh +Stan +StancedMK +Standard +Stanimal +Stanimal244 +Stanjuuh +Stank +Stank Rat +StankBreath +Stankfist +Stanley +Stanleye +Stanlux +Staparik +Staparik Lt +Stapper6 +Star +Star Doctor +Star Say 962 +Star Scourge +Star Spoon +Star zy +StarDreamSam +StarFell +StarGlimmy +StarKist +StarSnitcher +Starboyyyyy +Starbuckss +Starcharts +Starchild +Starcry +Starfallx +Starfight789 +Starfish +Starjoker8 +Stark Btw +Starlette +Starlighte +Starmaker +Starmemoria +Staropramen +Starr +Starrlightss +Starryfina +Stars +Stars Hockey +Starshark +Start Game +Started Late +StarvedLlama +Starvi +Starwulf +Starzhine +Stash +Stashes +Stasik25 +Stasik77 +Static +Static Peak +Staticshook +Statoke +StatsisZero +Stattelsson +Statuhs +Status Bar +Statutory +Statykk +Statzy +Staubach +Staunch +Staunch_BJD +Stax I +Stay +Stay Breezy +Stay Frosty +Stay Hurt +Stay Hustlin +Stay Ready +Stay Salty +Stay Shady +Stay Sic +Stay West +Stay wise +StayFinessed +StayPulls +StayPullsBTW +StayThirsty +StayinClassy +StaysmallEZ +Ste Gerrard +Ste f +SteSkillalt +Steady +Steady Loot +Steady Mobn +SteadyFlexin +SteadyetiBTW +Steak Ramen +SteakWitWiz +Steaked +StealCutOats +Steals +StealsThings +Stealth +Stealth Ownz +StealthChop +Stealthcy +Stealthi +Stealthweed +Stealthwolf +Stealy +Stealy Boi +Steam +SteamboatJim +Steamed H4ms +Steamfitting +Steammm +SteamyBuns +SteamyCreams +Steanox +Steb +Stedy +Steeam +Steebert +Steeermy +Steekkha +Steel +Steel Gods +Steel Stud +Steel Tarkus +Steel VIK +SteelRoxas +Steelbird16 +Steeleos +Steelpan +Steen +Steenkoe +Steezed0ut +Steezi +Stef +Stef West +Stefan +StefanLivNo1 +Stefar +Stefen +Steff +SteffenHax +Stefo +Stego +Steiger +Steikluet +Steinbeck +Steinphite +Stela +Stelisss +Stellacea +Stellamara +StellarLG +StellarWhey +Stellard +Stellas Dad +Stelli +StembaWalker +Stenfen +Stengo +Stenicki +Stenny +Stenuism +Step +Step Barrow +Step mummy +StepBroHung +StepBroImZuk +StepDabs +Stepbro +Stepbro Paul +Steph Browne +Steph a nee +Stephan +Stephand +Stephane +Stephen9320 +StephenMoore +Stephenns +StephhRS +Steppage +Steppaz +Steppenwulf +Stepy +Stereofuzz +Sterlander +Sterlington +Sterrenstof +Stervolz15 +Stetko +Steum +Stev +Stev en +Steve +Steve Beanie +Steve Tobs +Steve Tombs +Steve Zissou +Steve ffs +Steve is Pro +Steve07 +Steve51 +SteveAustin +SteveChamp +SteveGuy241 +SteveMCOG +SteveMerch +SteveOwner09 +SteveSnow15 +SteveStamos +SteveTheGimp +SteveTheMuss +Stevee +Stevefr3nch +Stevemck +Stevenrds +Steves Blade +Stevet7125 +Stevey +Stevie ESQ +Stevo +Stevo Lad +Stevo29 +Stevoguy +Stewge +Stexie +Stian +Stian Olsen +Stian2 +Stibby +Stickasaurus +Sticker +Stickers +Stickman +Stickman Zeb +Stickman0011 +Stickmeister +SticksNbugs +Sticky +Sticky Icky +Sticky Nut +StickyBeardo +StickyShroom +Sticky_BIBLE +Sticky_Lip +Stickypooman +Stickz Alt +StierK +Stieren Lul +Stiffies +Stiffish +Stifighter X +Stiflers mum +Stigel +Stigiam +Stigmaster +Stijco +Stijf Stefke +Stijin +StikSt0f +Stikjob +Stil +Still +StillANormie +StillCoughin +StillFap2ash +StillFarmin +StillNoBan +StillNoTBOW +StillRemains +Stillblazing +Stillen +Stillis +Stillmatic18 +Stiltz +Stimu +Stimulated +Stin +Stindebinde +StingWisher +Stingy +Stink +Stink Soep +Stinka +Stinker +Stinks +Stinkwiener +Stinky +Stinky Adam +Stinky Wench +StinkyFatBoy +Stinkyfeat1 +Stinkypooper +Stinkywon +Stino33 +Stiorra +Stipples +StirG29 +Stirner +Stitcha +Stiven117 +Stixc +Stiznai +StlthyPanda +Stnmn +Stnyzky +StockMyRam +StockOlm +Stocker T +Stockphish +Stocksund +Stocktone +Stockyard +Stodie +Stoel +Stoere Kip +Stoerebos11 +Stoern +Stoffer +Stoffins +Stoggy188 +Stoic Christ +Stoic Sloth +StoicGod +Stoke +StokedMaggot +Stolen +Stolen Ego +Stolen Grunt +Stolen Herbs +Stoli +Stoli za +Stolid +Stolpz +Stolte +Stoltzkin +StolzRS +StompaHhh +Stompadile +Stompea +Stomped +Ston3d Arrow +Stone +StoneDwarf +StoneOkami +Stoneator +Stonebeech +Stoned +Stoned Abra +Stoned Sober +StonedGSXR +StonedNormie +StonedTTD +StonedTurtle +Stonedtime +Stoneplus +Stoner +Stoner Morty +Stoner Pov +StonerGod +StonerL0ve +Stonerling +Stonesoul15 +Stoneyvangel +Stonkx +Stony 420 +Stoobie +Stoogaroni +Stooley +Stoolz +Stoonly +Stoopy +Stoopy Scape +Stoovey +Stop +Stop Acts +Stop Mules +Stop Now +Stop StepDad +StopCapping +StopDabs +StopDontDoIt +StopStepSis +Stopitjoe +Storgie +Stories +Storkie +Storm +Storm Monkey +StormFly +Stormlight +Stormmaker98 +Stormy RS +Stormzy +Storn42 +Stortford +Story +Story Arc +Story of Man +Storybot +StoryofPete +Storys +Stothelayer +Stouse +Stouty +Stovall_9 +Stover +Stovete +Stowa +Stowty +Stox7k +Str Owner07 +Str Takes U +Str0ng8ad +Str8 +Str8 Maxed +Str8backatya +Strabz +Stradarts +Stradinger +Straf +Strafe +Strafes +Straffen +Strafi n +StraightSimp +Straighter +Straka +Stralia +StralianBtw +StrangeChris +Stranger bud +Stranger56 +Strangerz +Stranges10 +Strangler +Strap +Stratazz +Straton +Stratty +StratusQc +Straubrey +Strauss +Strav +Straven89 +StrawHatMatt +Strawbs +Strawhat01 +Straya +Strayday +Straynaneeee +Streakin +Streammmmmmz +Streammz +Streepken419 +Street +Street Fever +StreetSweepa +Strefi +Stregano +Strelitzea +StrenIron +Strength +Strength Lvl +Strengthy43 +Strepski +Stresset +Stretch +Stretch 07 +Stretchy +Strickend +StrictNein +Strictly +Striddle +Strideless +Strife +Strijden +Strijder +Strikedown +Striker796 +Striker8 +Striker8 0 +Strikes +Strikingvipr +String Benis +StringsLogic +Strip Club x +Stripa +Stripgwyn +Stripred +Strive +Strix Tactic +Stro Sr +Strobax +Strocks3 +Strocules +Strohs +StrokeMuh +StrokeMyWand +Strokemon +StrokmyGroot +Stroller +StrollerBaby +Stroma +Stromboli +Strong Chonk +Strong Left +StrongKush +Stronger +Strongman613 +Strongrune +Strongsad Jr +Strongtank11 +Stronkmoscle +Stronku +Stroople +Stroppy +Strosity +Stroxers +Strr +Strubber +Strudelis +Strugglen +Strugl +Struthy +StrydarGrim +Strykijzer +Stryneguten2 +Strytegy +Stu Pid +StuartLittle +Stubo +Stud +StudMonster +Studderd +Student +Student t +Student tort +Study Hours +Stuffe +Stuffed +Stuffed Hog +Stuffmypanda +StufnDatMufn +Stugey +Stuggo +StuieShadez +Stukatz +Stuksken +Stumbles +Stunflame +Stunlax +Stunnaz +Stunts +StunuuR +Stupendous +Stupid My +Stupid Swagg +Stupid444 +StupidMagnet +StupidTrader +Stupidcoin2 +Stupsus +Sturdy Base +Sturdy Wrist +StureStork +Stureplan +Sturminator3 +Stussy +Stuxi +Stuzington +StvnSmth +Stvx +Stxrbursts +Stye +Style +StylesP +Stylistx +StyxHatred +SuBRifleS +SuNnY_AuStiN +SuRviVoR +SuaNorte +Suadela +Suavity +Sub Ironman +Sub Taz +Sub3Marathon +SubEntity +Sub_Void +Subaru +Subaru Bow +Subarue +Subarus +Subatinijo +SubiSpeed +Subiaco +Subiaco Oval +Subie +Subie_rex22 +Subigrl +Subkultured +Sublanza +Sublimation6 +Submerging +Submug +Subnautica +Subnet +Subnova97 +Subpreme +Subtle +SubtleAsnTrt +Subtotal +Suburu +Subwaysurfer +Subwooferman +Subwrx +Suc +SuccMyMilk +Succeed +Successful +Succulent +Such +Such Mlg +Suchislifee +Sucjk +Suck At Zuk +Suck my dig +SuckItBrandn +SuckMyBot +SuckMyDuels +SuckTube +Suckle +SucksTehSuck +SucksToSuck +Sucuk +Sudan7a7 +Sudas +SudoBash +SudoFox +Sudsy Mule +Sudz +Sue Lynder +Suede +Suedezor +Suemi +Suephoria +Suffer +Sufferance +Sufferi +Suffering +Suffi +Sufflavus +Suffspector +Sufwah +SugaNoCoffee +Sugab +Sugar +Sugar Leafs +Sugar Lily +Sugar STR +Sugar Shilo +SugarDaddyNL +SugarFr3 +SugarFre +Sugarbunny +Sugaree +Sugarly +Sugge +Sugma Newt +Sugmabum +Sugru +Suhado +Suhec +Suhgundees +SuhhP +Suhk +Suhkmedaddy +Sui29 +SuiSaii +Suikerwafel +Suing +Suited +Suizy +Sujn +Suket +Sukit Trevek +Sukiti +SukkerLyn +Sukondikis +Sukoru_VIII +Sukotto-Sama +Sukz +Sulcius +Suldan Serar +Sulg +Sulliusceps +Sully +Sully Bear +Sult an +Sultan +SultricMY +Sulu34 +Sum +Sum 1 +Sum Tuum +Sum41 +SumBeers +Sumh +Sumin +Sumlettuce +Summ +Summah +Summer +Summerson1 +Summit +Summit603 +Summon +Summond +Summoneering +Sumper1 +Sumuinen +SumwanSpeshl +Sun Devi1 +Sun Isukki +Sun Muijja +Sun Riser +Sun Rising +Sun Sioux +SunBar +SunG0han +SunaLAD +Sunbite +Sunchester +Sunda0wner1 +Sunday +Sundo +Sundxy +SundyWundy +SunflowerMan +Sungravel +Sunguinesti +Sunine +Sunky Kong +Sunlust +Sunni +Sunny +Sunny Boy +Sunny Coast +Sunny Otso +Sunnyi +Sunoric +SunriseEagle +Sunrises +Suns in 2025 +SunsShine +Sunsa +Sunscape6 +Sunset +Sunset Riot +Sunshadow +Sunshine +SunshineBus +Sunskit +Sunta +Sunti +Sunuwar +Sunyikata +Sunzz +Suola +Suolane +Suolitussari +Suomen +SuomiKP +Suomiprkl +Sup Mike +Sup3r Ziko +SupAndSupply +SupDutch +Supa +Supa Saper +SupaHottFiya +SupaWarmFire +Supaidahman +Supdude +Supeerbusy +Super +Super 16 +Super Bossy +Super Cinos +Super Cool +Super Duke +Super Fish +Super Fr3ak +Super Katze +Super Tails +Super4 +SuperChunk3 +SuperFlow +SuperHeroWiz +SuperJoy +SuperJuicy +SuperKoi +SuperKriss +SuperMcFresh +SuperMiika +SuperMuffins +SuperNJ +SuperNinja0 +SuperPPMan +SuperPochaco +SuperScaper7 +SuperSem1 +SuperShane +SuperShif +SuperT0aster +SuperTussu +SuperVegeto +Superalan9 +Superb +Superbigblnt +Superbusy +Superdoer +Superdrol 50 +Superfire444 +Superguaygix +Superior +Superjim111 +Superjoden +Superkman12 +Superkoi3000 +Supernate91 +Supernatti +Supernova +Supersam142 +Superstition +Superstuffz +Superwarz96 +Superzu 0ne +Supo +Suppertmain +Supple Flaps +Suppp +Suppression +Supra +Supra2JZ +SupraTurbo +Supragirl94 +Supreeme +Supreme +Supreme Iron +Supreme NYC +SupremeDanz +SupremeSpike +SupremeTeam +SupremeWoody +Suprie +Suprreme +Supsep +Supultura +Suq Maddic +SurNtly +Sura Lust +Suraato +Surah An-Nas +Suraii +Sure +SureDeth +Sureal +Surfboarder +Surg1n +Surge +SurgeHunter +Suricate +Suris +Suriv +Surkastunut +Surkee pelaa +Surlygrump2 +Surok +Surrey +Suruinen +Surullista +Susan Boyle +Suse +Susej Dog +Susell +Sushi Cult +Sushi Eater +Sushi Life +Sushi Water +SushiToyota +Sushidame +Susilapsi +Suspence +Suspiria +Susser Tod +Susurrous +Sutdellen +Sutho15 +Sutty +Suur L6vi +Suvalkietis +Suvorexant +Suxe +Suzakuin +Suzn +Suzshenron +Sv +Svampus +SvartaOdhner +Svartalvheim +Sveden +Sveitsi +Sveka +Sven +Sven med D +Svenpai +Svenskafyren +Sverd +Svetta +Svikkipedia +Svinepels +Svisha +Svt500 +Svurt +SvvK +Sw0llenPlums +Sw3Frost +Swaars +Swabby +Swabski +Swacked +Swadloon +Swaffeldomin +Swag +Swag Ponu +Swag420 +Swagbopeep +Swageroneus +Swagex +Swagg Goat +Swagger +Swagger Pkr +Swaggy Ballz +SwaggyMaggee +Swagittarius +Swagohod +Swagomancer +Swagslicer +Swagturtle +Swagunit +Swahilson +SwamiNate +SwammyHolds5 +Swamp +Swamp Crotch +Swamp People +Swampy +Swampy Sloth +SwampyAce +Swan +SwangleSauce +Swanheart +Swanney +Swanni D +Swanny +Swapski +Swarm243 +Swarme +Swarme d +Swarmyard +Swatfighter7 +Swatson +Swaxel +Swe Flame +Swe Fred +Swe Jerry +Sweatiest Xp +Sweatscaper +Sweaty +Sweaty G0OCH +Sweaty King +Sweaty Nurse +SweatyBeard +SweatyBurger +SweatyMoobs +SweatyScrot +SweatySockZz +SweatySunday +Sweden +Swedgeville +Swedish +Swedish Fika +Swedish Myth +Swedushi +Sweensicle +Sweepstakes +Sweepyjoe +Sweeqy +Sweet +Sweet Boyy +Sweet Dee +Sweet Es Mmm +Sweet Guy 94 +Sweet Pigeon +Sweet Potato +Sweet Vodka +SweetSugR +SweetVan420 +Sweetchild0m +Sweetermanz +Swell +Swer +Swerve +Swerve0311 +SwerveJ +Swervy +Swerze +Swift +Swift btw +Swift738 +SwiftCobra08 +SwiftSteps +Swiftamine +Swiftly546 +Swiftmend +Swiggitywall +SwiggyMcSwig +Swiigs +Swiim Shady +Swiirl +Swild0 +Swilza +Swimfatman +Swimmor908 +Swimpa +Swine +Swingers +Swip3rR +SwipeMyCard +Swirly +Swirly248 +Swishers +SwissPigeon +Switch Dropz +SwoIe +Swole Milk +SwoleBadguy +Swolerbear +SwoleyGhost +Swolga +Swoli +SwollSoul +Swollbroham +Swolverine +Swoofii +Swootz +Sword +SwordBoy110 +Swordcode205 +Swordied +Swordillo3 +Swordlord524 +Swordman1173 +Swordmank +Swordmast756 +Swordmother +Swords +Sworzis +Swoule +Swown +Swtbnd +Swtshrt +Swuido +Swurl +Swxv +Swyxia +Sxng +Sxrup +Sxstyl +Sxves +Sy +Syaniide +Sybe +Sybke +Sybr +Sycamore +Syche +Sycily +Syck Memes +Sycrem +Sycther +Syed +Syfer +Syh +Syjac +Sykeaux +Sykes +Sykes Xo +Sykes33 +Sykezer +Syliith +Sylist +Sylite +Sylixx13 +Sylosis +Sylph Rings +Sylth +Sylthrakis +Sylvaria +Sylvee Serum +Sylveon700 +Sylveonn +Sylvian +Sylwia +Symb +Symba12 +Symblic +Sympathize +Symphonicx +Symtai +Syn-er-gy +SynGates07 +SynTechRS +Synacyde +Synaii +Synced +Synchronizer +Synchronous +Syncire +Syncronia +Syncshot +Synd +SyndaXatrix +Syndalen +Syndicete +Syndok +Syndra +Syndrious +Synepxd +Synepxo +Synergy Sam +Synesthesian +Synfidel +Synister9090 +Synizta +SynkNZ +Synn +Synnri +Synoz +Synq +Syntax +Synthy +Syntipukki +Synyster +Sypanite +Syphikins +Syracusa +Syrile +Syrilius +Syringe +Syrius +Syrups +Syrus +Syrus Virus +SyrusDaVirus +SysTeM 07 +Sysf +Sysfea +Syssla +System_Fail +Syte +Syvette +Syzgy +SzechuanJuan +Szenarien +Szethe +Sznd +Sztarky +Sztr +Szyrup +Szyther +T 0 0 A S T +T 0 B +T 1 ta n i c +T A B S +T A R O +T Bagmotion +T C 3 +T C J +T D +T E L O +T H C +T H O R M +T IV +T McLeod +T Montana +T Nymphadora +T O M M M Y +T O N N l +T O N Y N Z +T OXI C +T P I E +T R A V +T R U 3 +T S M +T S O M +T Shadow T +T T E X X +T U B M A N +T U R K 96 +T U U M A +T W I S T Y +T W l C E +T a v e r +T alon +T aqn +T emby +T enrin +T h a w +T imboy +T imm +T omahawk +T otem +T otz +T r as h +T rigger +T ripwyre +T rist an +T u m p p i +T ubby +T ylor +T yrr +T-A nina +T-BONE STEAK +T-Hugs +T-Lai +T-Rabb +T-city +T0 BE FRANK +T00K3N +T00LB0X +T00ManyCooks +T0AD +T0KEN +T0KK +T0M +T0M ATO +T0RB3N +T0RlN +T0bbbE +T0ber +T0fi +T0ilah +T0lne +T0mbak +T0mz +T0oth +T0othbrush +T0ry +T0tally lll +T0vergasje +T1gBits +T1m +T1mmaayy +T2NK +T3KT0N +T3T +T3URASTAJA46 +T3mu +T3vas +T4TE +T4a +T7 +T70TYE +T7mon +T8OW +TA Greenie +TA xBravo +TAA66 +TAARA +TABS1E +TANK ED +TANKTOPTIGER +TANRfromHS +TARFUII +TARV05 +TATERT1TS04 +TB12 +TB3N +TBA Ness +TBA Poppi +TBAC +TBNinja +TBOW +TBSE Stupid +TBSG-Baine +TBonFirstCoX +TBoneZzzz +TBoyd4138 +TC NeverLift +TCHAMl +TDPred +TDRS +TDie +TDog +TE Omni +TE-toimisto +TEAMFORTDUDE +TEATMCBRIEF +TEAxBAGGER +TEBA +TEDDl +TEEMUXXD +TERMlNATE +TERRORHYPE +TESTOKEIJU +TFS +TFreeze +TGCONCEPTION +TGDekuTree +TGI Vendredi +TGOBS +TGSH +TGSpaghettiM +TH0MAS +TH0MM0 +TH0TDETECT0R +TH5 +THA CHR0NIC +THANIT0 +THANKS D0C +THATSCARCASM +THAl LADYB0Y +THC BOOSTED +THC and EXP +THCGods +THCiron +THE CH1N0 +THE JEDl +THE MOOR +THE MUUMI +THE TOSH +THEHAZE +THEIKOS +THEST0RM +THEchronic 8 +THICC +THICC UIM +THICCCBWANA +THIIIIITH +THRALLGOBRRR +THT +THUMBTHUCKER +TIIIIIIK +TIM BEREN +TIMBO +TIOTEEE +TITr fishy +TJ UCF +TJay +TKO Rage +TKOsh +TKfromNC +TLT5 +TLTBT +TM Riddle +TM8 +TNA INUS +TNDSH +TNF +TNT Stealth +TN_Biscuits +TOA Main +TOA Rebuild +TOA3 +TOASTA +TOB Inc +TOBplank +TOHIGH2FLY +TOLIPTSET +TOM RlDDLE +TOMMMY +TOMMYSHELBEY +TOMMonyzzz +TONNI re mix +TOOlateN0B +TOR0 +TORVA BTW +TPD-Vladik +TPGG +TR Ugur +TR0UT CURS0R +TR0X +TR3N ABUS3R +TR75 +TR9 +TRABZ10 +TRAJANO RD +TRAPH0UZE +TRAPorGTFO +TRAVllS +TRCSup +TRESTOLONE +TRI0DE +TRIPPlE +TRUMP +TRUMPbtw +TRUTH OF JFK +TRXeatsRAPTR +TRYNAHANGWU +TSA +TSI +TSMCharizard +TSMsOAZ +TSR Mishiah +TST +TSWRX +TSwiftSucks +TT17 +TTBtw +TTT +TTTSpiceTTT +TTTTT +TTVCardyUK +TTVPandaBear +TTommynator +TTurret +TTyrannical +TULK4S +TURBOPEN59 +TURDENATOR +TURK +TURKISH HERO +TURM0IL22 +TVAnime +TWISTED T +TWITTERSUPP +TWL +TWO000 +TWlNKE +TX Bonefrog +TX-15 +TXR3 +TYC Beatrice +TYCANN +TYEY +TYL0RD +TYTYTYYYTTYT +TZTOKHUGEKOK +T_ShelbyLtd +T_Swishh +T_apka +Ta C oS +Ta ks +Ta1ntzilla +Ta2kaz +Ta7e +Taakxic +Taargus +Taathum +Taavik6iv +Taavit +Tabagie +TabascoGrind +Tabbed +Tabbscoot +Tabby Cat4 +TabbyCat97 +Taberknackle +Tabesco +Tabiun +TableLamp +Taboo Tim +Tac +Tach +Tachr +Tachycardy +TackTick +Tacklebox +Taco +Taco Bit +Taco Krydder +Taco Log +Taco Paws +TacoCat +TacoKittenz +TacoTimma +TacoWithGuac +Tacos Pump +Tacotueaday +Tactic +TacticNoodle +Tactical-RSP +Tactics +Tactics Ogre +Taders +Tadz +Taekwon-Do +Taekwondoo +Taelium +Taelos +Tafboy +Taffarell +Tafff +Tag 7 +Tagei +Taggeman +Tagi +Tagz +Tahdeton +Tahdonvoima +Tahfi +Tahimik +Tahm83 +Tahuna Beach +Tahx +Tai +Tai Mai Shuu +Taikajim +Taikanz +Taikapoika +Tail Gory +Tail Raiser +Tailight +Tails +Tailsnake +Tainoo1 +Taint +TaintFondler +Taintedhappy +Taintehds +Tairoun +Taiwan +Taiyi2 +Taizur +Taj Mahballz +Takalaaaa +Takaloo +Take +Take My Sp3c +TakeARedPill +TakeNaps +TakeUhSeat +Takea12 +Takedown Jr +Takeitilslay +Takens +Takeout24 +Taker +Takfil +Takimoto +TakingADab +Takis +Takji +Takobocchi +Taks +Taky +Talal +Talaxim +Talcron +Taleah +TalenteDK +Tali +Talia +Talito +Talk +Talkamar TT +TalkingMoose +Tall Greg +Tall Vince +TallChair +TallPaul24 +Talla +Talla Keyali +Tallented +TallerKiwi +Tallink +Tallopolis +Tally +Taloroar101 +Talos +Talppa +Talrith +Taltt4 +Talu +Talvedon +Talviel +Taly +Talzn +Tam Ranch +Tam The Bae +Tam k0nijn +Tamacti +Tamadra +Tamaki +Tamale +Tamara +Tamaraa +Tamayura +Tamber +Tamberi +Tame +Tamerr +Tamis +Tamjam +Tamlin +Tammii +Tamminga +Tammy +TampaTHC +Tampered +Tan Toad +TanDumb +Tanatos +Tandanus +Tanden +Tanduay Rum +Taneesha +Tang Eater +Tangar +Tangela +Tangelo T +TangerineFly +Tangibility +Tangle +Tangle Root +TangleEllis +Tangleboot +Tangledroot +Tango +Tangshan +Tangzu +Tanie +Tanime +Tanis513 +Tanjiro +Tank +Tank VS Bear +TankMageJon +TankProphecy +Tankarino +Tanked +TankedAgain +Tanker +Tanker 685 +Tanker773 +Tankerton +Tankkimies +Tankky +Tanknique69 +Tankster360 +Tankytank +Tanna +Tannnk +Tanny +Tanoak +Tanoak alt +TanqueRamos +TantusV +Tantza +Tanuliina +Tanz +Tanz Mutagen +TanzFang +Tanza +Tanzagen +TanzerReborn +Tanzoo +Tanzu +Taozi +Tapanui +Tapas +Tapdaddy +Tape +Tapir +Tapir Squad +Tapirslayer6 +Taplop +Taplu +TapoinItteni +Tapu +Taqi +Taradrial +Tardagan +Tardysoap +Tarezed +Taringa +Tarki +Tarkista Hv +Tarlach +Tarns +Taro +Taro Buns +TaronRS +Taroshik69 +Tarouco +Tarpon +Tarroo +TarzanNinja +Tarzzan +Tasarorm +Tascar +Tase T +Tashee +Tashkas 007 +TaskMan +Tasset Man +Tassoth +Tassy +TastefulNote +Tasty +Tasty Burger +Tasty Nan +TastyBoiMilk +TastyKnight +TastyToilet +Tata +Tataa +Tatanchis +Tatankaa +Tatapie +Tatepon +Tater +Tatertots +Tatimary +Tato +Tatorz +Tattoo +TattrTots +Tatuu +Tau Lord45 +Tau Neutrino +Tau Tau +Taucher +TaunkChicken +Tauno +Taunos +Taurideum +Tauros +Taut +Tautvif +Tava +Tava Monster +Tavern slut +Tavernic +Tavi +Tawa +Tawakoni +Tawer +Tawhid +Tawny +Tax Audit +Tax Wax +Tax Wizard +Taxing +Tay Lore +Tay3rell +TayMoney +Tayleth +Taylor +Taylor672 +TaylorMarcus +Taylort07 +Tayluh +Taynq +Tayri +Tays +Tayunu +Taz762009 +Tazmina90 +Tazner +Tazplan +Tazy420 +Tazz2006 +Tazzin +TazzoTezz +Tb knakworst +Tbix +Tbk +Tbone5876 +Tbow +Tbow Joe +Tbow Todd +TbowCourtois +Tbrs6 +Tchambz +TdTapsa +Tdblindmonke +Tddun +Tdmiro +Tdogg31 +Tdurocher +Te +Te Awa +Te x a s +Te zzz +TeBroHimself +TeCurt +TeJay +TeMuD +TeQuiL A +Tea Farmer +Tea Witch +Tea n Milk +Tea on Wayne +TeaIe +TeaMerchant +Teaandliquor +Teabz +Teachan +Teadribble69 +Teafuse +Teagan +TeagueDaBoss +Teal AV +Tealer +Team +Team Chubby +Team Flow +Team Rocket +TeamCleaned +TeamJono +TeamSoloMid +TeamVaChimpy +Teamwork +Teand +Tears +Tears of Avo +TearsOfWeezy +Teazor +Tebal1 +Tebowowns +Tebus +Tec-Grind-95 +Tecc Legacy +Tecco +TechCo +TechColor +TechContraps +TechFreakTwo +TechOnMaxed +Techart +TechiePicker +Techmenjoe +Technician +Techno177 +Techno9 +Techo +Techtonique +Teckczar +Teckerz +Teckie16 +Tector OSRS +Ted Beneke +Ted Striker +TedRS +Teddii Bear +Teddy +Teddy Brum +Teddybareman +TeddysMoo +Tedication +Tedsticles +Tedua +Tedzudo +TeeBee +TeeBee11 +TeeSchaf +TeeTee1772 +Teebo 727 +Teegious +Teegzie +Teekiz +Teemu +Teemu126 +Teemuz +Teena +Teenagers +Teenyduck +Teequoze +Teeqy +Teeray +Teetoh +Tefak +Teff +Tefilah +TeflonCancer +TeflonJavon +TegridyF4rmz +Tegriidy +Teh Only God +Teh W H I P +Teh Yumm +TehBigNub +TehBriBri +TehKillaaa +TehPum +TehShowerMan +Tehebow +Tehh +Teigur +Teittinen +Teivanna +Teixo +Tejmaster +Tekannan +Teke Toucher +Tekkenfury +Tekkies +Tekkies nub +Tekknow +Tekkuza +Teknoid +Tekoflex +Tekryael +TekstPlekshT +Teksti-TV666 +Tektiny +Tektom +Tektonio +Tektons +TektonsTaint +Tektos +Tel3 +Telboy +Teledogs +Telee +Teleport 125 +Teleportoise +TelesBehindU +Telesh69 +Tellum +Telluric +Telope +TemBROross +Temdom +Temeria +Temmer +Temmie +TempVVS +Tempal2 +Tempest +Tempesta1 +Tempick +Templaris +Temple +Templooit +Tempname123 +Tempoctrl +Temponazz +TemporaryBls +Temppuliina +TempstRimuru +Tempthric +Tempz +Ten Letters +TenOnTheFlop +TenPieceNug +TenPly Bud +Tenacious +Tender Nuts +Tenderrrrr +Tendinosis +TendoTheTux +Tendulkun +Tenebri +TenebrisMeam +Tenenwasser +Tenereus +Tenga +Tenh1s +Tenhou +Tennis +Tennis Socks +TennisLad +Tennnessee +Tennu +Tennysee +Tenorman +Tenraikash1 +TenryuuKaiNi +Tensilean +Tensor +Tensor Trace +Tentacle +Tentpolepie +Tenya +Teotl +Tep3lstreel +Tepeksi +Tepezki +Teplan +Tepoa +Tepponen +Teqila +Teqq +TeraLokien +TeraVit +Teras +Terbleg +Terial117 +Tering +Tering Tiete +Term +Termite +Termiz +TermnaLcpL +Termoil +Tero +TerpWrangler +Terpedout +Terpily +Terppa1775 +TerpySlurpy +TerraToffey +TerraTony +TerresFatum +Terrible Edd +Terro +Terror +Terror Earth +TerrorJaxx +Terrorise +Terroristi +Terry +Terry Munro +Terry61RS +Terrybear +Terva +Tes Iron +Tesaticles +Tesco +Teserve +Tesla bot +TeslaDiva +TeslaHero +Tesni +Tessei +Tesseria +Tessies Bits +Test +Test Dummy +Test Strip +TestStrip +Testate +TesticularCa +Testikeln +Testoepa +Testsubject +TetYun +Tete3 0 +Tetragrams +Tetrah Blue +Tetsu +Tetsu Nurtaw +Tetsu Steel +Tetsu2 +Tetsunohigan +Tettekop +Tettezotteke +Teurastamo +Teus +Teus777 +Tev0 +Tevreden +Tewocp +Tewty +Tewwer +Tex Zen +TexanzOS +Texas +Texas Hou +TexasAggie +TexasPlayer +Texasholdems +Texastea2 +Texman +Text +Texx +Teyrill +Teyzr +Tezyn +Tflo +Tfue +Tfulkyou +TgMofo +Th Abigor +Th0m +Th3 K1ng P1n +Th3 Wolf +Th3IronMan +Th3KiNG +Th3KiNG_Paul +Th3Tool +Th3Villager +Th3_DoN +Th3uns +ThAngelSlayr +ThEDievolved +ThSheerman +Tha Bser +Tha Crazy L +Tha Decided +ThaDankantor +ThaDragonSM +ThaGiz +ThaLawl +ThaNewArcher +ThaRealRambo +ThaStepBro +ThaaMunchies +ThaaOne +Thaerokem +Thai +Thai Girl +Thai ler +Thaichili +Thalarios +ThaliN1 +Thamasta47 +Thameslink +ThanaWee +ThanatosRise +Thangkang +Thanked +Thanks +Thanks Jeans +Thanks4Pet +Thankz Mom +Thano +Thanos btw +ThanosIsLife +Tharendel +Tharic +Tharin +Tharok +Tharrogant +Thasos +That +That Noob +That RNG +ThatBoiii +ThatBoyBurly +ThatDamAss +ThatFishhGuy +ThatGuyGoob +ThatGuyJordy +ThatLipGrip +ThatLuck +ThatManBez +ThatOldskool +ThatOlmlet +ThatOneAsian +ThatSandNoob +ThatSickBoi +Thatonesock +Thats +Thats Gang +Thats Not PC +Thats Thicc +ThatsNotRite +Thaumat +Thaurison +Thav022 +Thawk410 +The 0ld Nite +The 0xymoron +The 1 liquid +The 11th +The 2nd GIM +The 3rd Main +The 90s +The Actuary +The Aegis +The Aod +The Apina +The Atreus +The BPO +The Baad Man +The Big Chum +The Bleez +The Blue Owl +The Blyat +The Bonk +The Booger +The Boys +The Brawler +The Broskie +The Bubbsy +The Buffalo +The Cage +The Catowl +The Champy +The Chopper +The Cleaned +The Cleaning +The Coffin +The Comeup +The Crogamer +The Crows +The Dabbler +The Danny +The Dark +The Dark165 +The Data Guy +The Debated +The Decided +The Deli +The Diamond +The Dink +The Dipshit +The Dothraki +The DrNick +The Dragona +The Dre +The DripLord +The Duffman +The DwOrfe +The Echo +The Eco +The Effected +The Em8 +The End +The Engine +The Ex Zerkr +The Expanse +The Fat Toad +The Fe Woman +The Fig +The Fisher +The Fugitive +The Gas Tank +The Ginga +The Giznooch +The Grouch +The Grower +The Guppy +The HRE +The Half Man +The Harambae +The Havok +The Hibbs +The Hivemind +The Hobo +The Hoffner +The Hundred +The Hunter +The I Am +The Iron Cpt +The Iron Era +The Is0lated +The Jedi Way +The King 023 +The Kiwi +The Labfreak +The Lager +The Last Act +The Latvian +The Law 98 +The Locust +The Logger +The Long Day +The Lope +The Lord Ra +The Lovers +The Lurifax +The MCG +The Magic +The Maiden +The Marco +The Maskara +The Matth +The Mediator +The Midlands +The Mks +The Mouldy +The Mr Spec +The Murder21 +The Muscles +The Nexian +The Nicollai +The Noob +The OSU +The Office +The Old Fonz +The Old Kite +The Old Mike +The Omun +The Onceler +The Only Sin +The OnlyPyro +The Paladin +The Peak Pro +The Pet Farm +The Playoffs +The Pocket +The Proline +The Prophet +The Ptolemy +The Pwnes +The Qwinner +The Real Cat +The Sabre5 +The Sarge +The Schnopps +The Sea Bee +The Seahawks +The Serval +The Shy Guy +The Shy Oni +The Sly Fox +The Snail34 +The Snapback +The Steele +The Steward +The Stranger +The Surveyor +The Tardis +The Thanator +The Tils +The Tiny Dog +The Trap +The Triple T +The Use +The Victory +The W0rst +The Wael +The Warp +The Wraith +The Wupp +The keho +The thin 1ce +The-Wind-Up +The0G +The1 +The1_2watch +The1stmage +The3dge +The3rdOlive +The3rdTrike +The888 +TheAdzz +TheAirIsDead +TheAlbatross +TheAllSorts +TheApe +TheArcheType +TheArchthief +TheAsic +TheAssailant +TheAusSpade +TheAvenger56 +TheAvgJon +TheAzimuth +TheBandit777 +TheBassIsRaw +TheBazaBrown +TheBean +TheBearJ3w +TheBeltMan +TheBezal +TheBidness +TheBigShield +TheBigZofNYC +TheBlackest +TheBlindy +TheBlueShore +TheBlueWrath +TheBoltzy +TheBoomfire +TheBopp10 +TheBotReaper +TheBowJob +TheBrain +TheBranFlake +TheBrundone +TheBudWiser +TheC0W +TheCanada +TheCapist +TheCarrotMan +TheCaseAce +TheCheezywiz +TheChosnOnes +TheCokeFiend +TheCollected +TheCondemned +TheCorrupt +TheCuckening +TheCzarnian +TheDaedalus +TheDalek +TheDampBush +TheDangs +TheDankShow +TheDawg +TheDayWalker +TheDayman +TheDeadMann +TheDeadTeam +TheDeen +TheDisgusten +TheDog +TheDoubee +TheDreamKing +TheDrips +TheDry +TheDuckChris +TheDuckDaddy +TheDucksNut +TheDuud +TheDyr61 +TheEricShaun +TheEstonian +TheEvaElfie +TheEvlManRay +TheExtracted +TheF0rg0ten9 +TheF1ash +TheFabDabber +TheFallen1x +TheFeOdyssey +TheFeres +TheFizzCC +TheFlammers +TheFlopyTaco +TheFlyingFin +TheFoef +TheFolly +TheFrenchGuy +TheFunkyHomo +TheFunnyLove +TheFuzzball +TheGaGee +TheGaryy +TheGiggleMan +TheGlawce +TheGodFathxr +TheGodGuthix +TheGodfather +TheGoodLife +TheGoonie +TheGordinfla +TheGoryGlory +TheGr8Jimbo +TheGrainGoat +TheGreat +TheGreat One +TheGreatThor +TheGreenBowl +TheGugguru +TheGurrag +TheHabduL +TheHackedOne +TheHapa +TheHartstopr +TheHerbSack +TheHuffDaddy +TheHugLife +TheHungOne +TheHungRoid +TheHydra69 +TheInilator +TheIronBarra +TheIronBoy +TheIronDolan +TheIronHoser +TheIronMouse +TheIronTwist +TheIronVault +TheIronZoid +TheIsamaru +TheJele +TheJosephe +TheKappaCorn +TheKhun +TheKid +TheKillerB +TheKnight +TheKnightman +TheKolector +TheKop +TheLaggyDad +TheLampKing +TheLastTheef +TheLaxBrah +TheLazyNinja +TheLewhole +TheLionn +TheMaadKing +TheMachine39 +TheMadWolf +TheMainZeus +TheMamba +TheManInBush +TheManJordo +TheManatee +TheMaskie +TheMavrick +TheMaxPvMer +TheMayne +TheMetaNow +TheMikkel +TheMorloc8 +TheMuel +TheMuffin8or +TheMursk +TheNegative +TheNerve +TheNewLue220 +TheNewMonkey +TheNexu +TheNinjaH0b0 +TheNoPurp +TheNooby +TheOG Logo +TheOGGrimm +TheOGslacker +TheOSRSWiki +TheOllieBoi +TheOlmlet +TheOne772 +TheOneMatrix +TheOperative +ThePTWY +ThePaceAce +ThePardos +ThePariah +ThePerfect G +ThePolak +ThePraetors +ThePrenti +ThePrestiege +ThePrideS1n +TheProfess0r +TheProvider +ThePureRingR +TheRanger +TheRealBean +TheRealBew +TheRealDest +TheRealIdean +TheRealKanye +TheRealKush +TheRealKyle +TheRealKyle9 +TheRealMidus +TheRealShway +TheRedNas +TheRedRaider +TheRevRip +TheRewriter +TheRobin129 +TheRoulette +TheRsBug +TheSaggyOne +TheSaltyYew +TheSandFoxx +TheShadyMile +TheShyFn +TheSimpSonny +TheSinner +TheSkippyBoy +TheSlim1 +TheSneakyOne +TheSoggyOne +TheSoloHades +TheSpaceSaus +TheStonedElf +TheSwumpMan +TheTKsmith +TheTankProd +TheTerug +TheTimeLord +TheTinPeach +TheToyMaster +TheTree7 +TheTrue Goku +TheTrueNorth +TheTrueOOGA +TheTrueSatan +TheTruthOnly +TheUnbeloved +TheUndified +TheUnluckyIM +TheValuable +TheVerve +TheVeryBest +TheVnom +TheVoodoo2 +TheW1tcher +TheWerebear +TheWetDuck +TheWhlteWolf +TheWiseLoner +TheWitcherr +TheWizaad +TheWrongName +TheYahtzee +TheYak +TheYimYim +TheYugo +TheZoracks +TheZurvan +The_Dave666 +The_Dunster +The_Eoline +The_Hillboy +The_Jimmy +The_Krang +The_Man146 +The_Sturg +The_Zob +Thea1a +Theatres +Thebano +Thebig76 +Thecascade +TheclawMVP +Theconn +Thedriesj11 +Thedyolf +Thee Khed +TheeMohican +TheeSkill +Theel +Theem +Theeweaver +Theez +Theezak +Thefunto +Theguymann +Thejessman1 +ThelAvent +Thelastmane +Thelegend4uk +Thelmacat342 +Thelvereas +ThemanwhoisB +Themenchman +Thengalin +Theoatrix +Theodensa +Theodora605 +Theohhhh +Theoklitos +Theoneburger +Theophobia +Theorized +Theory +Theoryist +Thepawgchamp +Thepiefour +Theracords +Theralion +TherapyGroup +Theravasa +ThereTheyre +Therealhook +Therens1 +Therer +Thermynator +Theruler333 +Thery +Thesaurusus +These +Thesonicking +Thespok +Theunfrgiven +Thew +Thewoodle +They +TheyTukMyJob +TheyXciteMe +Theynika +Thgll +Thibaut +Thibi +Thic Glizzy +ThicBudget +ThicCreature +ThicKoontang +Thicc +Thicc Aku +Thicc Budget +Thicc Fil A +Thicc Flair +Thicc Momma +ThiccBird91 +ThiccCowboys +ThiccDaddyXL +ThiccDonut +ThiccQueen +ThiccSkips +ThiccZwans +Thiccapedia +Thick +Thick Cut +Thick Nick +Thick Red +Thick nun +Thick2g +Thick4Head +ThickGlute +ThickIronBum +ThickMike +ThickSenpai +ThickSpak +Thickenei +Thickest +Thickkmommy +Thics +Thiery +Thies +Thiesen +Thievette +ThievinKills +ThievingL +Thievs +Thigh +Thighhighs +ThiiComplex +Thiibaut +Thillam +ThinBlueL1ne +ThinPeepoSad +ThinkB4Hit +Thinkoclet +Thinxo +Third +Third-ages +ThirdAge +ThirdAgeBoss +ThirdEye +Thirdborn +Thirsty 4PvM +Thirtys +This +This Gimp +This Leo +This Schmuck +ThisAint +ThisAint-Wow +ThisAintSkil +ThisGuySkip +ThisPieIsDry +Thisious +Thissa +Thlrd +Thoakline +Thocasu +Thogdad +Thogidar +Thohon +Thom +Thomarse +Thomas +Thomas Juice +ThomasticIM +Thomastic_1 +Thombstone +ThomiusTeGr8 +Thommetje +Thommyy +Thonack +Thonq +Thoomin +Thor +Thoradin +Thoraldd +ThoraxPurple +Thordej +Thorgal +Thorgoth1 +Thorkar96 +Thorn +Thornet +Thornnforge +ThorntonM +Thorvesta +Thot Jadiels +Thotalopolis +Thoth +Thotmince48 +Thotscape +Thoughting +Thoughtseize +Thounde +Thoupeppi +Thrasmion +Thrax OS +Three Twelve +ThreeOneNine +Threemars +Threesunders +Threkeld +Threno +ThreshDaOg +Thrihyrne +Thrilbo +Thrilerrr +Thrillhousee +Thrisel +Thrivaldi +Thrlll +Throat +ThrobGodTod +Throbba +Throbbing +Thrombi +Thromur +Throupled +ThrownFury +Throxx +Thru +Thru ur poo +ThruDaStorm +Thrust +Thrustaxe1 +Thueh +Thug +Thug bone4 +Thugbug808 +Thugg +Thugge +ThugsBunny +Thugsbunny73 +Thulean +Thumb +ThumbBwana +Thumper +Thunadaja +ThundaBear +ThundaJunk +Thundac +Thundahcatz4 +Thunder Dog +Thunder Gate +Thunder Nerd +Thunder Zeus +ThunderBirdz +ThunderRolts +Thunderbo1tz +Thundercat +Thunderite +Thunderoxgod +Thunderpb28 +Thunderst0rm +Thundito +Thur go +Thurbs +Thurison +Thusly +Thutmose +Thuvian +Thuzd +Thve1ivan +Thwart +Thy Odama +Thy Victory +ThyIronGiant +ThyLegend +ThyVonR +Thybo +Thyclops +Thyhead +Thyming +Thyreus +Thys +Thysa +Thyymabotnus +Ti Blade +TiXN +Tia +Tiaan +Tiaeuth +Tiafoe +TiagoM +Tiak +Tian Guo +Tianzi +Tiazen +Tibadis +Tibador +Tibaul +Tibbsyy +Tiberium SvK +Tiboot +Tic Fart +TicImperfect +TicTacSensei +Ticano +Tice300 +Ticina +Tick +Tick Behind +Tick Ma Nip +Tick Manips +TickAteUrMom +TickTickRun +Tickable +TicketGoblin +Tickets +Tickflow +TicklMySickl +TickleBerry +TicklesIM +Tickmark +Ticks +Ticks missed +Tict +Tictacdingus +Tid Eez +Tidders +Tiddy +Tiddy Winks +TiddyLactate +Tidev +Tidy +Tiedemanns +Tiedustelija +Tiegra +Tielemans +Tier +Tier 05 +Tierney +Tierra Bella +Tiesto +TifaL123 +Tiffs +Tiftanlar +Tig Bittty +TigTheWelder +Tigas TT +Tiger +Tiger Tea +Tiger Trap +TigerYouDied +Tigerheart07 +Tigerheart09 +Tigerlady +Tigerlady203 +Tigerr +Tigersrule23 +Tigerwolf +TiggoGnomes +Tiggrat +Tighe +Tight +Tight Helmet +TightSpace42 +Tigor +TigreRosso +Tigrio +Tigy +Tiiimon +Tiimari +Tiistai +Tiistia +Tiit Hepa +Tiivo +Tijmen +Tijn040 +Tijs +Tijskid +Tijuude +Tiki Haha +TikiTyrant +Tikk1s +Tikka +Tikkix +Tikru +Tiktok +Tikwah +Tila +Tilburg +Tild0 +Tilfreds +Tilidin +Till Bored +Tillah +TillerPloww +Tillykke +Tilted +Tilted I Am +TiltedGoblin +TiltedIM +Tilur +Tim Pedwar +Tim Puri +Tim The Jedi +Tim bo Slice +Tim-O-thy +TimShutDown +TimSkilling +TimTheLegend +Timaaaay +Timaaay +TimbaWimba +Timbeettius +Timber +Timbertail +Timbito +Timboball +Timbuktu25 +Timbulz +Time +Time For Me +Time Leap +Time Voyager +Time2Lose1 +TimeFlies +TimeIsStrnge +TimeLion +TimeMuffins +TimeSink2000 +TimeSpan +TimeZebra +TimedxBeast +Timespacing +Timetokill19 +Timew8ster +Timex +Timex 07 +Timka +Timkempp +Timm +Timmay111865 +Timmeh +Timmies +Timmuuhh +Timmy +Timmy Jim +Timmy Tbow +Timmy Tiime +TimmysCoffee +TimnI2 +Timonkey +Timos +TimosTime +Timotej +Timsey +Timzee +TinFoil Joe +TinHongetech +Tincoinco +Tincup +Tindatinn +Tindell23 +Tinder lvl 1 +TinderMatch +Tine +Tinfawn +TinfoiledHat +Tinfoilhat +TingSumWong +TingleTingle +TingleUwU +Tingot +Tingsha +Tink +Tink200345 +Tinkelsia +Tinmanone +TinnMan +Tinnitus +Tinsmith +Tinted Rock +Tintti218 +Tinuvial +Tinvicuna +Tiny +Tiny Bagel +Tiny Buddha +Tiny Bun +Tiny Dck +Tiny Feet +Tiny Lego +Tiny Secrets +Tiny Teemo +Tiny Triceps +TinyFnRick +TinyIronDong +TinyLebowski +TinyLes +TinyTaro +TinyToasters +TinymafaRick +Tinypns +Tinytiger17 +Tinzo +Tip Zee +Tip of Dik +TipTheTank +TipeF +Tipeeee +Tipit +Tipoz +Tipper +Tippin_toes +Tips Iron +Tips Touched +Tipsy PvMer +TipsyBeard +TiptopSundae +Tipu +Tiqu +Tiques +TiramisuTart +Tire Slayer +Tired +Tired Hero +Tired of IRL +TiredPidgeon +Tirex +Tiring +TirmenaT +TironTula +Tironade +Tirpz +Tirsonek +Tisalia +Tisch +Tism Tanner +Tit Bow +TitMcghee +TitPoker +Titan +Titan Luke +TitaniteSlab +Titanium Mag +Titas P +TitePoire +Title +Title Fight +Titsferdayz +Tittsnbiches +Tittyboi5 +Titus +Titus Furius +Tivaaa +Tivinter +Tizra +Tizzcdn +Tj Russo +Tj Watt +Tj0epert +Tjaa +Tjabalabaaa +Tjalo +Tjar +Tjarie +Tjarles +Tjbakel +Tjf12 +Tjob +TjockaBengt +Tjs109 +Tjuv +Tkit +Tksquad +Tktn +TlCK LOST +TlLLER +TlLT +TlME 2 QUlT +TlNUS +TlTANlC +Tliltocatl +TmSmT +Tman +Tmarvy +Tmilllz +Tmm +Tmmm +Tmoe +Tmoe123 +Tmoneyyyy123 +Tmppa +Tmtiger16 +Tnt Harder +To Ashes +To Be Sure +ToAPlanker +ToBeAgile +ToLoNi +ToMyTailFin +ToNFisKrs07 +ToTheRanch +Toad Pond +ToadKar TV +Toas20 +Toast +ToastBTW +ToastMal0ne +Toaste +Toasted +ToastedCargo +ToastedMoose +Toasterly +Toastie +Toasty +Toat +Tob Braidy +Tob Carvery +Tob Marley +TobOnMyCox +TobSpoon69 +Tobak +Tobbeloba +Tobias +TobiasFate +Tobiasz +Toboogan3 +Tobser +Toby +Toby Raz3 +Toby1889 +TobyMcCrier +TobyRax +TodWhispers +Todays N00B +Toddlet +Toddo25 +Todt Thot +Toe Biden +Toe Crocs +Toe Moss +ToeRag +Toedeloe +Toedels +Toeh5 +Toek +Toekie +Toeristje +Toermalijn +Toes B4 Bros +Toets +Toews +Toffenboi +Toffer_99 +Toffffu +Toffoli +Tofs4pk +Tofthagen +Tofu +Tofu Python +Tog +Toge6343 +Togepi +Togica +Togo Mouri +Tohni +Tohveli +Toilet +Toilet Humor +ToiletBowlbb +Toiletpaper9 +Toimin +Toiney +Toinzy +Toivo_43 +Tojosodope +Tok in +Tok-xik-Hex +TokHaar +Tokah +Toke +TokeSevere +Tokedaddy +Toker11 +Tokin +Tokin Ranarr +Tokin99 +TokkHaar +Tokkie01 +Tokonu +Tokoya +Tokoya11 +Toktz-ma-cox +Tokyo +Tokyo Ghost +Tokyo Prose +Toldasor +Tolhuis +ToljaSo +Tolo Ar Nin +Tolweg +Tom Adamo +Tom Cx +Tom Decoene +Tom Fn Brady +Tom Is Huge +Tom Shanks +Tom T +Tom Vercetti +Tom Waited +Tom btw +Tom from 561 +Tom is Sharp +Tom o_0 +Tom vs Log +Tom9 +TomAce +TomFlinn7 +TomHilRigour +TomMazilian +TomMerrilin +TomOfTheWest +TomTehCat +Toma +TomaMvp +Tomaatti169 +Tomarti +Tomastor +TomatoAndEgg +TomatoFarm19 +TomatoTom9 +Tomazon +Tomb +TombLooter +Tomba +Tombalo +Tombat +Tombazv2 +Tombea09 +Tombing +Tomdabom +Tomdoc14 +Tome +TomehhG +TomiL +Tomiee +Tomik85 +Tomlyn +Tomm +TommieSalami +Tommm +Tommmo +Tommy +Tommy 901 +Tommy J C +Tommy2Tick +TommyGunn204 +TommyJay +TommyTalapia +Tommyhawk +Tommyyy +Tomn +Tomo +Tomori +Tomorrowlxnd +Tompi +Tompp1 +Tompsi +Toms +Toms PvM +Tomsdk +Tomson177 +Tomtastrophe +Tomtom032 +Tomukas +Tomvdh +Tomxi +TomzodoubleO +Tond3 +TondeK18 +Tone +Toneez +Tonester03 +Tonfa +Tong +Tongo +Tongue Baths +Toni +Tonicto +Tonk A Wiz +Tonka742 +Tonkade +TonkatsuLife +TonkerEx +Tonnie +Tony +Tony D +Tony Gwynn +Tony P +Tony Soap +Tony Soprano +Tony Tuna +Tony23 +TonyCaawk +Tonyde +Tonydidles +Tonyhood +Tonzaww +Too Original +TooBasic +TooBigDad +TooManyCooks +TooManyKinks +TooMuchIan +TooMuchSauce +TooMuchTuna +TooReal +TooShredded +TooWhite4You +Toobias +ToogaTank +Tooheys +Tookkul +TookyDaWooky +Tool +Toolbox +Tools1977 +ToomBooii +Toomas +Toomi +Toonic +Tooodley +Tooomo +Tooq +Tooqan +Toortles +Toostie +Tooterz +ToothhurtyPM +Tooves +Top Gear +Top Glock +Top Milk +Top Monents +Top Mong +Top Trends +Top V1 +Top Vestain +Top10 +Top5Worst +TopGlitch +TopGunt +TopTitz +Topdogg16 +Topez +Topgolf +Topi +Topkeklethal +Topkerel +Topman +Toppavenger +Topstad +TopsyTurve +Tor Btw +Tor Cool Guy +TorBlueJays +Torag Tony +Torags +Torags The C +Torchbringer +Torchfall +Torchiclover +Torchpix +Tordenknold +Tordue +Toreador +Toreransu +Torgonis +Tori +Torille +Torille btw +Toris +Torkoal +Torky Bow +Torlux +Torm +TormentingU +Tormood +Tornaddyne +Tornado Kim +TornadoGang +TornadoShit +Torned +Tornjak +TornoDB +Torok +Toronto +TorontoOVO +Torr3nHunt3r +Torra +TorraTwo +Torretto +Torrfly +Torrud +Torsinclair +Torso +Torstol +Torstol Todd +Tortanium +Tortcher +Tortelini +Tortew +TortiIIa +TortillaChip +Torttunaama +TortugaBooga +Tortugas +Tortuous +Torture Iron +Torva boy +Torvee +Torvesta +Toseki +Tosetti +Toshiba +Tossin +Tostada +Tot1 +Total +Total Lvl +Total Pede +Total Spoof +Total Vanity +Total Zero +Totaldumm +Totaled3 +Totalis +Totallymad20 +Totalxq +Totato +Tote +Totemas +Totnum +Tott +Totti +Tottie +Toucan +Toucann +Touch My Wii +Touch Tablet +Touch Touch +TouchPinis +TouchedByXp +Touchkin +Touchmydig +Touchpad +TougeAttack +Tough +Tounii +Tour Guide +Tourino +Tournx72 +Tousart +Tove +Towely +Tower Guard +TowerOfGod +Towerbros +Town +Town Square +Towney Stark +Towton II +Toxic +Toxic Dice +Toxic Emre +Toxic Joda +Toxic Mfer +Toxic Outlaw +Toxic Waltz +Toxic017 +Toxic125 +ToxicBropipe +ToxicDroPipe +ToxicKenny +ToxicSimp +ToxicWaster +Toxzeek +Toy Chest +Toycutter +Toyger +Toyne +Toyocoma +ToysRusK1d +Toysalami +TozzinSalads +Tpc Chris +Tpc Jimmy +Tpc Ken +Tqnks +Tqrb +Tr Farmer +Tr hoca +Tr0gdor +Tr1ckyD1cky +Trabelco +Trac +Trace +Tracing +Trackpad +Tracktix +Trackzor +Tracto r +Tractorjoe13 +Tracxy +Trad +Trade +Trade Me 70k +Trade Parade +TradeForItem +TradeMeBro +TradeMeUWont +Tradebarrier +Tradeophobia +Trae47 +Traenalai +Trage Gast +Tragick +Tragon33X +Trail +Trail Sodas +Train Track +Traincore +Trained Fish +Trainer +Trainer Bad +Trainin +TrainingDay +TrainingDays +TrainingWill +Trainor BTW +Trains +Traiths +Trakiya +Traktori +Traktorman +Tralan +Tralfamadori +Tramayne +Tramfix +Trample +TranSfused +Trance +Trance Heals +Trance666 +TranquilGod +TranquilHaze +Tranquillia +Transfer +Transgressor +Transpiler +Transpose +Tranziztance +Trap +Trap Carrot +Trap the Cat +Trap-A-Holic +TrapGdReptar +TrapGood93 +Trap_Capo +Trapking +Trapking 8 +Trapping +Trapski +Trasclart +Trash +Trash Pvmer +TrashBlast +TrashManJ0hn +TrashServers +Trashu2 +Trashua +Trashy +Traumahh +Travee +Traveler +Travis +Travis 42 +Travis on Rs +Travis473 +TravisThott +Travish +Travor +TravviePatty +Travy D Law +Traxic +Traxxed +Trayvon King +Trazaeth +Trazez +Trazza001 +Trebluh +Trebyzond +Tredderss +Tree +Tree Form +Tree Oils +Tree43210 +Tree50 +TreeNut11 +TreeTopsFart +TreeWeasel +Treedemption +Treehuggers +Treelo23 +Treenut +Treinen +Treio +Trejoracine +Trekhoar +Treldinn +Trem Bao Uai +TremensInc +Tremorx00 +Tremzy +Tren Culture +Tren Hex +TrenbolonAce +Trench Ben +Trendeon +Trendiness +Trenl +Trennel7 +Treno +Trensational +Trentovitch +Trentt +Trepa +Trepador +Treps +Tresemmee +Trev +Trev the dog +Trevenant +Trevo +Trevor +Trevor Died +Trevor M +Trewg +Trews +Trey +Trey is +Treygor +Treyvor +Trezler +Trgx2 +Tri Flamingo +Tri-P0LAR +Tri9py_J +TriBalanced +TriFlea +Tribe +Tribe Leader +Tribe of 123 +Tribryd26 +Trick +Trick Blue +Trick Statue +Trick-demon +TrickRoom +Trickiac +Trickin +Trickool +Trickster122 +Tricomb +Trictagon1 +Trictagon2 +Tricx +Trid3nt +Trieuce +Triforce13 +Trigamy +TriggaTriggs +Triggadd +Triggahappy +Trigger Me +TriggeredMot +Triggeredm3 +Triggering +Trigos +Triig +TrikiRiki +TrikyCutworm +Trikzed +Tril +Trilipe +Trilligy +Trillogy +Trillotani +Trilogies +TrilogyXO +Trim +Trim Jr +TrimmedGrimm +Trimmedguy +TrinitySauce +Trinix +Trio +Trio MF +Trip +Trip Machine +Trip Masta +TripEatIRL +TripJaw +TripSquad +Tripachu +Tripae +Triple +Triple Deuce +Triple Dex +Triple U +TripleBeans +TripleHyphen +TripleNeck +Triplet +Tripod Neb +TripodDog +Trippie Damo +Trippinsac +TrippleMarty +Trippy +Trippy Mind +Trippy Troll +TrippyReefer +TrippyScapee +TrippyTony +Trips +TripssAcid +TrisomyMumky +Triss123456 +Trissee +TristV1 +Tristann +Trito +Triton Blue +TritonSaber +Triumph +Trivi Beast +Trivit +Trivium +Trixcet +Trizak +Trizepz +Trldude7 +TrocSan +Trocko4 +TrodOnLego +Troetelbeer +Trogbite +Trojan Steed +Trok +Trolerage +Troll Chad +Troll464 +TrolleVV +TrolletTruls +Trollevv +Trollface +Trollheimusk +Trolli +TrollinPony +TrollinTony +Trollinguy +Trollzzy +Trololosaur +Tromal +Trombalski +TronixxIM +Tronkshark +Tronse +TroopIronman +Trooperke +Tropec +TrophieTyler +Tropical97 +Tropicaux +Tropidelics +Tropsic +Troskals +Tross +Trottero +Trottington +Troulis180 +Trounced +TrousrMonstr +Trout Wallet +Trovam +Trovo +Troxicus +Troy Buckle +TroyPolamalu +Trreezz +Trrrpfosdss +Tru3Iron +Trublians +Truce +TruckTruck +TruckYacht +TruckerLiam +TruckerTuck +TruckersLife +Trucki +Truckstop0 +True +True Flex +True Joker +True Knight +True Owl +True Repent +True Tones +TrueBadApple +TrueBank +TrueNorth95 +TrueSatan +TrueTech +TrueTeller77 +TrueYoshi +Truegreed +Trueplaya +Truers +Trueth +Trulieve +Truly +Truly Lifted +Truly Loving +TrulyForever +Trump +TrumpCard +TrumpSuxAss +Trumpet +Trundholm +Trunker +Truno +Trunsa +Trusejageren +TrustIssues +TrustNoOne +Trusted +Trustifarian +Trustin +TrustyThrust +Truth Hurtts +Truth Seekir +Truxy One +TrveKvlt +Try Casual +Try Die Cry +Try Hard Jr +Try2IronMan +TryAltF4 +TryCBD +TryHard +TryHard DBag +TryHardi +Tryactin +TrygveLegend +Tryh4rder +Tryhard +TryinNot2Die +Trym +TrymeTrick +Tryna Max +Tryna match +Tryndaflex77 +Trynottodie2 +Trypophobia +Tryptamind +Tryptopane +Tryuumph +Trzaskowski +Ts Danne +Ts Me +TsMaxed +Tsakahele +Tsar +Tsar Douglas +Tsarina +Tschinelas +Tshotz +Tsiquli +Tsitika +Tsjok +Tsolu +Tsqq +Tstiffy_15 +TsuNaabi +Tsubusa +Tsuchan311 +Tsudo +TsukasaS +TsukiAkuma +Tsukihi +TsukikoBaka +Tsukiya +Tsuku +Tsuku yomi +Tsukuyomi +Tsumikitty +Tsumoso +Tsurubebi +Tsyphoid +Ttffdd +Ttoz +TuNxZbs +Tubbless +Tubbzzy +Tube Dood021 +Tubmasta95 +Tubs +Tubz +Tuca +Tucker Jeb +Tuckerajf +TudoLaDentro +Tuerro +Tuexo +Tufan +Tuffa +Tufs +TugBoatWilly +TugMeTwice +TugMyCox +Tuga9 +Tugboat +Tugboats +Tuii +Tuisku +Tuittu +Tukeldaja +Tukkairti +Tulf +Tulip +Tulipssonmyd +Tully03 +Tulppu +Tumbdownlog +TumbleDore +TumblingSand +Tumeken Tay +TumekenToday +Tumma Paahto +Tumms +Tumnus +Tumppe +Tuna +Tuna Juice +Tuna Shuffle +Tunaking420 +Tunasafarii +Tunda +TunderBog +Tundra +Tunez +Tung +Tung Fu Rue +Tungsten +TungstenGyro +Tunguska +Tunkky +Tunnellord +Tunppii +Tunsberg +Tuntun +Tuoppi1230 +TupacShaakur +Tupackid +Tupakki +Tupeli +Tuperrovski +Tupla Olut +Tuplaa +Tupoopsa +Tuppu +Tuppu hoitaa +Tuppuu +Turambarr +TurangaNui +Turb0uu +Turbanator +Turbie +Turbin +Turbo +Turbo IM +Turbo Junkie +Turbo Toes +Turbo Zero +TurboMilf +TurboSoak +TurboTez +TurboWet +Turbokjepp +Turbotymer +TurdFlicker +TurdFurgeson +Tured +Turha +Turiak +Turjilin +Turk Monsta +Turk3H +Turk3HH +TurkBird +TurkeyPro +Turkije +Turkish One +Turkish3agle +Turkled +Turkos06 +Turks +Turn +Turn It Left +TurnMagic +Turnalar +Turner Coach +Turnii +Turnt +Turqish +Turqy +Turri +Turrner +Turrox +Turskaa +Turso +Turssuttaja +Turtelloo +Turtle +Turtle Rak +Turtle s +Turtle7 +TurtleCoddlr +TurtleWurdle +Turtlebutt +Turtledog +Turtleliest +TurtlesClimb +TurtlesRdank +Turtleso3o +Turts +Turuii +Turvasana +Tusc +Tushy Taker +Tusk +Tusondude25 +Tusseladd92 +Tustea Kossu +Tutorial +Tutoroo +Tutta +Tutter +TuttiFruttii +Tuttimango +Tuttimelon +Tuuri +Tuuri haukka +Tuvisitt +Tux +Tuxy +Tuya +Tuzle +Tvanderlaan1 +Tvb Cx +Tw0Pack +Tw1ZzT +Tw1nsPurr +Tw1nz +Tw1st3d_B0W +Tw1stedBow +TwTv +Twald10 +Twas +Twas Xmas +Twashua +Twaste +Tweaky +Twee Barkie +Tweeder +Tweek +Tweekzor +Tweetart +Tweeznap +Tweezr +TweezyShadow +Twelvyy +Twenie Wan +Twerk +Twerk 132 +Twet +Twice +Twice Flo +TwickerTweet +Twiddle +Twiddle Twix +Twidgets +Twiested +Twift +Twigbert +Twigglet +TwiggyC +Twigler +Twigster +Twiisted +Twilight2326 +TwilightPony +Twilly Spree +Twillz +Twin +Twin Fists +Twin Kinz +Twin Peaks +Twinflip +Twinick +Twink +Twink Ripper +Twinkle +Twinkle Park +Twinklekat +Twinr0va +Twins +Twist2K +Twist3d +Twist3dData +Twisted +Twisted Boog +Twisted Bung +Twisted Cook +Twisted Echo +Twisted Jam +Twisted Matt +Twisted Titt +Twisted cat +Twisted garg +TwistedAegis +TwistedBeer +TwistedBerns +TwistedBowlz +TwistedBr0 +TwistedCybrg +TwistedGuard +TwistedHeart +TwistedLike +TwistedOffer +TwistedWally +Twisted_Ry +Twisted_newf +TwistedxAura +Twister Nips +Twister XIII +Twistertjeee +Twistie +TwistsedT +Twitch +Twitch Fear +Twitch simp +Twitch507 +TwitchFear +TwitchSeljan +Twitchen004 +Twitchin +TwixTM +Twizler74 +Twizzlers88 +Twnkles +Twntythree23 +Two Elites +Two Fears +Two Ounces +Two2SixToo +TwoBeerBuzz +TwoDigitJish +TwoDogs +TwoInTheSink +TwoLegedDog +TwoShue +TwoTwentyTwo +Twoconch +TwojaStara +Twoy +Twpz +Twstd +Twum +Tx2 +Tx3 Poseidon +TxNock +Txbor +Txfr +Txga +Txh +Txlon +Txture +TxunaTuna +Txyus +Ty +Ty God +Ty Sit Idiot +Ty bears +Ty1er +Ty4F +TyDyPooFingr +TySkidmore23 +Tybear575 +Tyberium +Tybones +Tycen +Tycens +Tydigidy +Tydollatree +TyeMeUp +Tyelca +Tyepo +Tyfr +Tyfus +Tyfus Bende +Tyfus Mug +Tyfuslija +Tyga +Tygr +Tyhger +Tyin +Tyixx +Tyjes1 +Tykaman +Tyl r +Tyler +Tyler Razz +Tyler Stone +Tyler051095 +Tyler4rs +TylerGBR +TylerMike +Tylerknight3 +Tylerton +TylerxBandit +Tylo54 +Tylooor +Tylz2 +Tym8 +Tyney +Tyngre +Tyom +Tyontaja +TypOneg4tive +Typhose +Typical +Typisch +Typto +Typtooka +Tyq +Tyr 24 +Tyr Ara +Tyra +Tyrael +Tyrael OG +Tyran88bid +Tyraniana +Tyranids +TyrannicaI +Tyrants +Tyrep +Tyrex +Tyro +Tyrus +Tysh +Tyskie +Tyskie38 +Tyskn +Tysn +Tyson11 +Tysonn +Tyst +Tysterisk +Tytastic +Tythle +Tytto +Tywonia +Tz-Kek-Twang +Tz-Ket-Kush +TzCal +TzCok +TzCok-Hard +TzDeez +TzDeez-Nuts +TzHaar +TzHaar Meej +TzHaar-Doug +TzJal +TzKal +TzKal Majora +TzKal-AszZuk +TzKal-Cumsok +TzKal-Gio +TzKal-Mike +TzKal-Thad +TzKal-Zuky +TzKalFatkok +TzKalSuk +TzKarl +TzSuk-Dis2 +TzTok +TzTok Chris +TzTok-1gBud +TzTok-Fart +TzTok-Flame +TzTok-Izzy +TzTok-Jaffa +TzTok-Jahd +TzTok-Jeffy +TzTok-Joka +TzTok-Kekw +TzTok-KetKok +TzTok-Ladz +TzTokTitties +Tzek +Tzhaar Bower +TzhaarThicc +Tzhaar_PvP +Tzharzh +Tziis +Tzikit +Tzkal Edgar +Tzkal Tygo +Tzkal-Reborn +Tzok-GigaKok +Tzoski +Tztok Shaz +Tztok-Met-Al +Tzuyuwu +U A E +U A V Online +U Ded Boi +U Mirin Brah +U N X +U R Lame +U Tele Nub +U W8 +U n I f Y +U nknown +U0Q +U0sunpeh +U3 +U4 +U71Q +UAWMAN +UB02 +UBWare +UBaKr +UConn +UENDELIG +UFOTurtle +UFOs +UG Juppa +UGLYMONKEY58 +UGLYS +UGam3zOS +UI GOKUU +UI UC +UIM BUTT3RS +UIM Brah +UIM Burni +UIM Chayula +UIM Illusive +UIM Liar +UIM Lobotomy +UIM Log +UIM Loki +UIM Nathanjb +UIM Ori +UIM Paperbag +UIM Pepper +UIM Pidbull +UIM Shen +UIM Shrift +UIM Sorrows +UIM Spongie +UIM Stephan +UIM Thor +UIM Vas +UIM Warriorh +UIM Wedey +UIM Yoga +UIM Zoldyck +UIM whozan +UIM7 +UIMBerg +UIMaqtpai +UIMatti +UIMpostor +UIPanda +UIdahoKush +UIspice +UKB0b449 +UKnowItsB +UL7RA +ULF Tagger +ULTMA +ULTRA +UN-FAZED +UNBIQUOUS +UNC0RN +UNCEL +UNCLE +UNCLE LEET +UNCLESAMY +UNDEAD EXO +UNDERURBED4 +UNEX1ST +UNH0IY +UNLOADED999 +UPDOGS +UPSdeliveree +UQV +UR 0 HP LMAO +URA Noob +URAMESHl +URSS +US Postal +USA Tyler +USA USA USA +USA is Dev1l +USAF +USAO +USBthe2th +USMARINEHYDE +USNavyOver70 +USSpaceForce +USTreasury +USirHaveLost +USirHaveWon +UTT +UWCB +UWF +UWUSTELIJA +UZY VS JAD +Ualt +Uamee +Ubar +Ubaru +Uber +Uber Logan +Uber Yeats +Uberamazing +Ubersmind +Ubicorn +Ubu +Uccino +Uchiwa +Uchr +Udacity +Uderp +Udhariol2 +Udingus +Ufda +Uffe Persson +UgliestIncel +Ugly +Ugly Hipster +UglyFishArm +Uglybeetle27 +Uglyyo93 +UgranDag +Ugursuz IT +Uh-0h +Uhbove +UhhhBoneless +Uhhhh Wut +Uhm +Uhscended +Uidi One +Uim Beyonce +Uim IRL also +Uim Zuko +UimSian +Uimakoulu +Uk Bristol +Uki Kukkamaa +Uki Skillz +Ukko +Ukko-Pekka +Ukkonenn +Uknow Yunho +UknowPotter +Ukonvasara +Ulappa +Ulibarri +Ulik madiq +Ulillillia +Uliss +Ulizius +Ullerton +UltDrewes +UltRise +Ultebor +Ulthane120 +Ultima +Ultimat3ly +Ultimate +Ultimate Low +UltimateH0bo +UltimateSami +UltimateWare +UltimateZe +Ultist +Ultistic +Ultorman +Ultra +Ultra Miami +Ultra Primal +Ultra Sloth +Ultra Space +Ultra Teuz +UltraGOOP +UltraJack +UltrasTomi +Ulvhilde +Ulyanyx +UmUUmuUmU +Umarra +Umbr +Umbrah +Umea +Umek +Umiland +Ummfufu +Ummz +Un Dutchable +Un M-U-T-3-D +Un puma +Un-Expected +UnDutchable +UnGoof +UnHoLyxMaTTy +UnOrderly +UnRuleD +UnTaMed X +Una999 +Unacceptab1e +Unaclogger +Unaided +Unass1sted +Unassisted +Unavailable +Unbacked +Unbann me +Unbiased +UnboundLeaf +Unbreakable +Unc1e +UncJo +Uncaged1776 +UncagedOne +Uncandled +Uncel +Uncel Ben +Unchunk Man +Uncle +Uncle Exci +Uncle Julien +Uncle Rocho +Uncle Solo +Uncle Somnus +Uncle THC +Uncle Trippy +UncleBigBob1 +UncleCuckle +UncleDaddiii +UncleGuy +UncleSlappy1 +Unclear +Unclesam137 +Uncode +UncomfyPants +Uncommon +Uncooker +Uncool Gary +Uncr3at1ve +Uncut +Uncy Duncy +Und3r0ath +Undead +UndeadElk333 +UndeadYenny +Undeadd +Undefeated +Undelivered +Undeniable +Under +UnderExiled +Underaged +Undercatt +Underlogged +Underoos +Underrs +Understars +Understated +Underverse +Undine +Undoubtful +Undra +UndrgrndSalt +Undulaatti94 +Unemati02 +Unemployed +Unequalized +Uneven +Uneven Mango +Unexposed +Unfair +Unfearful +Unfergetable +Unfi +Unfollowing +Unfriended +Unfunno +Ung +Ungolianty +Unhappy +Unhapytuna +Unhealthy +UnhingedE +Unho +Unholy Bains +Unholy Cult +UnholyAbyss +Unholybucket +Uni Mike +UniQ +Unicat +Unicorn +Unids +Unii +Unik +Unimaginary +Unimander +Unintended +Union Dixie +Uniqlorn +Unique +Unique Am I +Unit +Unit Tests +United +UnitedLeeds +Uniteds +Unity 3D +Universe +Unkh +UnkindPastry +UnkindledTwo +Unknown +UnknownBeing +UnknownPlaya +UnknownValue +Unknownchuck +UnkoPlayer +Unkoly +Unkownkiller +Unlash +Unlds +UnlimitedHC +Unlit Sky +Unlock Death +Unluckerdile +Unluckers +Unlucky +Unlucky Jord +Unlucky lmp +UnluckyNGay +Unlugy +Unluigi +Unmasked +Unmaxed +Unmerkable +Unmoist +Unnerving +Unohdettu2 +Unomia +UnorthodoxGF +Unorthodoxfo +Unown397 +Unprofitable +Unread +UnrealGecko +Unrecord +Unreliab1e +Unrot +Unruliest +Unsafest +Unsainted +Unsavior +Unscuff +Unscythed +Unseen +Unshaven Cat +UnstopFork +Unstrung +Unsubscribed +Unsung +Untameable +Unthinkable +Until +Until Dawn +UntrimCraft +Untrimmed +Unus Divinus +Unv +Unwiii +Unzkiboi +Uoziz +Uozu +Up N Ur Mom +Up ya mom jr +UpBad +UpNorthCha +UpRoaRs +UpThaSaints +Upeo +Upi +Uploading +Upluk +Upper Four +Uppercuts +Uppotukki +Upriser +Uprising +Uproot +Upsi +Upthe1rons +Uptime +Ur Exp 2 Me +Ur Obsession +Ur a baish +UrASalmon +UrBabyzDaddy +UrBoyBilbo +UrDadsLov3r +UrJustXpToMe +UrMomLvedIt +UrNansMan +UrPureSucks +UrScr3wed +UrSuchaShita +UrWifeLuvzMe +UrYe +UrZoggy +Ura Juanker +Uragaan Dude +Urakas +Urakkapallo +Urallia +Uran ium +Uranus +UrbanMerza +Urbdayy +Urbn +Urdead +Urea +Urek +Urekzera +Urfe +Urheiluiatka +Urheilujatka +UricOddball +Urkchar +Urked +Urkerhard +Urock16 +Uross +Urotsuki +Urpokarhu +Urri +Urs +Ursa +UrsaOmega +Urskog +Urthron +Uru p +UsainBloat +Usb Doe Tin +Usb Flies +Use +Use Tongue +Use2bHC +UseToBeGood +Useable +Usecsythang +UsedApplePie +UsedLube +UsedRubbers +Useless +Useless Main +User +User 27 +UserApproved +Useranme +Usos +Ussin +UsualAntZ +Usva +Utahime +Utahn +Utareita +Utca +Utini +Utis +Utsuwu +Utter +Utter Pleb +Utvisa +Uunijutsku +Uunipelti +Uuo +Uus kaust +Uuti3 +UwU Leo +UwU Noctis +UwU Otaku +UxXwpasdiioa +Uzin +Uzot +UzrielBoi +Uzunar +V 3 +V 9 +V A K U +V A L O R +V A M 0 S +V A N D E R +V Bros +V E F +V E H +V G +V GK +V Gamemaniac +V L A D Y +V Lestat V +V NL +V Nichushkin +V OO D 00 +V R I L +V e c n a +V endetta +V ergetend +V ezi +V i 1 e +V r o l ij k +V the Victim +V-43 +V-EuSoto +V-SaTanjiro9 +V-Tek +V-olRagnarok +V043 +V0F +V0WZ +V0XA +V1BER +V2int5 +V3NQM +V3XY +V3lnias +V3n3natis +V3rtigo btw +V43 +V4SKI +V4sia +V5C 2 +VAIDUOKL1S +VALH0WLA +VALHA LL A +VALK0 +VALORANTJETT +VAMPYRlC +VANlLLA RUM +VB TINNS +VB24PK +VBoss +VBsec +VDB Niffooo +VDHG +VEDA +VEGANDIET +VEN0M13 +VENNY MOCKER +VERYBANANNA +VET DMaZ +VHS or DVD +VIAL1 +VIE T +VIII +VIIVII +VIKING0 +VILIONKKAA +VLEERMUlS +VODKANATOR +VODs +VOIVID +VOREVERAIONV +VORKl +VOlDWAKER +VP N1ck +VPSxSam +VPixels +VRScotty +VS0P +VS367 +VUNDA +VVDance +VVJuul +VVS1 +VVStoner +VVade +VVanderer +VVarden +VVeems +VVhite0ut +VViggle +VVilson +VVinni +VVintage +VVona +VVoods +VW Crafter +Va1ynx +Vaal +Vaalbara9 +Vaalberg +Vaandah +Vaca Preta +Vacant V +Vache +Vache Verte +Vad3 +Vader +Vado +Vaealin +Vaelleruen +Vaelte Peter +Vafan +Vafthruthnir +VagAngler +Vagabond +Vagina Bad +Vahagis +Vahagn +Vahidil +Vahlyte +Vahn +Vaikuttava +Vailokas +Vain +Vainis +Vaishe +Vaisu +VaitkiS +Vaizki +Vajengo +Vakstu +Val Rex +Val3ntlne +ValOnMyChest +Vala +Valadrak +Valarfax +Valaron +Valdevon +Valdomiro B +Valdyra +Valendale +Valentijn +ValentinaLuv +Valete +ValgeHunt09 +ValheraUK +Valhk +Valiant Nite +Validde +Valiente +Valienton +Valiiim +Valiralith +Valirion +Valivill +Valknir +Valkore +ValkyraeS1MP +Valkyrie btw +Valkyrie xo +ValkyrieNora +Vall +Valliance +Valliate +Vallies +Vallk +Valluu +Valmar +Valmora +Valo +Valo Ville +Valo247 +Valor +ValorantJohn +Valorate +Valorisatie +Valorise +Valorpoint +Valrog +Valus +Valverdi +Valxn +Valzar +Valzor +Vam pire +Vamo +Vampeodia +Vampire Bob +Vampirehunt +Vampiress +Vampurr +Vampyire +Vampza +Van Cold +Van Hellsing +VanDarkhome +VanHeisma +Vanaic +VanceStJohn +Vandahl +Vandaine +Vandalize +Vandalized +Vanderhek +Vanderstorm +Vandery +Vandetto +Vandmand +Vandorann +Vanek +Vanek-26 +Vang +Vanh0 +VanhaKettu +Vanhal000 +Vanilla Best +VanillaBum +VanillaDonut +VanillaFlow +VanillaSwirl +Vanillawaifu +Vanity +Vanity Fair +VanityNugett +VanityRS +Vanityyh +Vanja +Vanja M +Vanki +Vannara +Vanskid +Vanss +Vantiron +Vanupimphi +Vape99 +VapeMonster +VapeNGapeLLC +Vapeape1 +Vaperan +Vapid H +VapinTiger +Vaping Cloud +Vaporion +Vaporized +Vapsjeeee +Var Laslore +Varamyr +Vardorfister +VardorvisSux +Vardovish +Varduka +Varenagan +Vargen96 +Vargo +Vargrmoon +Variabulls +Varixed +Varlanazz +Varlot4 +Varm +Varm Kaffe +Varnilla +VarockVirgin +Varonom +Varpu +Varradero +Varro +Varrock +Varrok Obama +Varroq +VarrrokObama +Varsa +Varsii +Varthon +Varulven +Varxas +Varz +Vas R +Vasar23 +Vasd +Vasdeffernce +Vaskapotti +Vaskekort +Vasquez +Vassaa +Vassago0111 +Vassal +Vastrakal +Vastuuvapaus +Vasuki +Vasyliev +Vatenkeist +Vatix +Vauderus +Vaull +Vault Hunter +VaultTecs +Vautumn +Vaux +Vava471 +Vaveti +VawnHeuf +Vaxx +Vaxxil +Vaxyr +VayQ +Vayda +Vaynon98 +Vaz0r +Vazier +Vazoo +Vb Panther +Vbiqve +VeKnow +VeZuu +Veas +Vector +Vedam +Veddunreal +Vedroulian +Veecal +Veeena +Veekkuu +Veerpalu +Veersnof +Veetu76 +Vefsn +Vegabond +Vegakargdon +Vegan +VeganFemboy +VeganVibes +Veganstho +Vegard +Vegas +Vegas Gunman +Vegas Mike +Vege-Mauri +Vegeetta +Vegeta +Vegeta MF +Vegetah +Vegetas Veng +Vegetunks +Veggie Mate +Veghan +Vegitation +Vegito +Vegito Meta +Vegolse +Vehicle Tech +Vehms +Vehru +Vehtamin +Veilig +Veilious +Veinin +VeitiKKa +Vekie +Vekuuu +Velaynx +Velbain +Veld +Velegro +Velek +Velgreed +Velhote +Veli +Veli Iron +Velikan +Veliki +Velite12 +Velkennar +Velkija +Velli +Velmir +Velociraptor +Veloxrapt0r +Velreth +Veltsi +Velvetgunner +Velvsy +Velzun +Vemba +Venado +Vendall2 +Vender +Venderik +Vendet27 +Vendum +Venemies +Venenatis +Venerate +Venereology +Venetsia +Venfour +Veng +Veng BTW +Veng Me Not +Veng Waster +VengDeezNutz +Venganza +VengeMeDaddy +Vengeance013 +VengeanceTR +Vengeancen +Vengeful +Venizar +Venkeltje +Vennythizer +Vennyv99 +Venom +Venom Vegeta +Venom00 +VenomTears +Venomousbite +Venomxkillz +Venous Cobra +Venpu +Ventia +Ventile +Ventril0qist +Venus Nyan +Venzdroid +Venze +Venzy +Veo s +Veos +Verac Obama +Veracs +Veracthus +Veraen +Veratyr +Verbac +Verbal +Verbal Kint +VerbalIrony +Verbia +Verbo +Verche +Verdantys +Verdoemd +Verdux +Vereco +Verelya +Vereoris +Vergi Drakan +Veri Eze +Vericity +Verify +Verin +Verissimum +Veritasium +Verity +Verix +Verjj +Verkyz +Verliax +Vermachelen +Vermeill +Vermithrax91 +Vermont Iron +Vermyapyre +Vern29 +VernalTDevil +Vernon +Vernossiel +Vernyxitas +Vernz1337 +Verokostaja +Veromnis +Verrario +Verrtus +Verruckt +VersGrind +Versacce +VersaceGuap +VersaceSofa +Versalix +Versatio +Versily +Vertigo 2 +Vertsu1 +Vervyyy +Verweel +VerxaRS +Very +Very AFK +Very Typical +VeryAvgRNG +VeryGoodRNG +VeryLarry +VeryLilRng +Veryloo +Verysharp988 +Verywarm2246 +Veryx +Verzicky +Verzik +Verzik BTW +VerzikDaCuck +Verzika +Verzy +Verzy Werzy +Vesal +Vesaris +Vesipiisami +Vesku +Vesley +Vespina +Vespulia +Vesqu +Vesryn +Vessim +Vest +Vesta 1000 +Veste +Vestergaard +Vestorius +Vesture +Vesunna +Vetala +Vetem +VeteranGamer +Vetilation +Vetinari37 +Vetionarian +Vetr Skaoi +VettePolle +Vex Viper +Vex Virus +Vex8 +Vexare +Vexed Viper +Vexeed +Vexer07 +Vexero +Vexers +Vexflame +Vexing +Vexinity +Vexrip +Vexstrom +Veylantz +Veyron +Veysel +VezTa +Vezka +Vezon +VgbndUnicorn +ViIlageIdiot +ViaCarter +Vial +Viallinen +Viat +Vib3Ch3ck3r +Vib8 +Vibby +Vibe +VibeCentral +Vibeke Gar +Vibeology +Vibes Check +VibesTooWavy +Vicardi +Viccuri +Vicente1111 +Vicenza 173 +Vices +Vicious Dest +ViciousPawg +Vickies +Vicky +VictheStud +Victimised +Victor +Victor Dogg +Victor Lim +VictorHo +Victorize +Victorp75 +Victoryw +Victreebel +Victur +Vida +Vidacks +Viddii +Video Gamic +Videogam3r +Vidlmao +Vidy +Vidz +Viech +Viema +Vienas +Viera22 +Viesker +Viesty +Vietnamees +View +View Bot +View0 +ViezNegertje +Vieze Jongen +Viggi +Vigi V +Vigilamus +Vigly +Viguro +Vii23 +ViiPV +ViiViiVii +Viiduus +Viiiral +Viikonloppu +Viiksi-Vallu +ViinaGoblin +Viinakramppi +ViisYsiKuus +Vijand +Vijay +VikSC +Vikat +VikeSkol +Vikerne666 +VikiLord +Viking +Viking Dad +Viking768 +VikingKnees +Vikingfe +VikkiVance +Viklok +Vikram +Viktor +Viktor Wins +VilainLutin +Vilbeee +Vile +Vile Arcane +Vile Cabbage +Vile Squid +Vileblood +Vilemaw +Viliant +Vilke +Villagers +Villain Dude +VillainLife +Villanovaguy +Villanovan +Ville +Ville921 +VilleGallle +Villix +Villllu +Villosa +Villrix +Vilnis +Vilty +Vilunki +Vimpsen +Vims +Vin 08 +Vin B +Vin Vista +Vinaegre +Vinbum43 +VinceBennett +VinceOfMince +Vincen +Vincent +Vincent D2 +VincentDaMan +Vincentimetr +Vinceut +Vinchops +Vindi IM +Vindruen +Vindruva +Vinh y +Vinish +Vinkmaster1 +Vinland +Vinloxx +Vinn28 +VinnFrazz +Vinneh +Vinnie +Vinnie Dabs +Vinnie Pazz +Vinnie526 +Vinny +Vinny NZ +Vinny Speedy +Vinny Verac +Vinny-G +Vinnyaldo +Vinoloog +Vinopenkki +Vinostondis +Vinous +VinsanityGG +Vintage +Vintages +Vintner +Vinxe +Vinxion x +Violas +Violent +ViolentPudd +ViolentToxin +ViolentWaves +Violetti +Violon +VipStar +Viper +Viper Aurora +Viper G40 +VirZuk +Viral +Virbatum +Virbliud +Virelith +Virgin Creep +VirginGirl +VirginHunteh +VirginUwU +Virginism +Viriato +VirtRemnants +Virtaheepo +Virtuaalnuss +Virtual +VirtualAhri +Virtuart +Virtuous +Virunypel +Virus +Virus LSSZ +Virus Soup +Viruss +ViruzTehNub +Virzik +VisagePlease +Visarin +Viscera +Viscx +Visdom +Vishno +Vishnu +Visibly +Visigothic +Visine +Vision +Viskan +VismaBlet +Vister +Vistopherson +VisuallyMatt +Viswiel +Vita +VitaLemonTea +VitaMineralz +Vital Dude +Vital Hope +Vitality +Vitamin See +VitaminCnote +Vithark +Vito +Vitor +Vitreous +Vitrified +Vitruvio2 +Vitryssen +Viturbio +Viturscy +Viva +Viva La Vida +Viva Mehico +VivaLaWeegee +Vivalask8r +Vivalla +Vivants +Vivascape +VividAzura +VividDreamss +Vivido +Vivij +Vivk +VivziePop +Vixca +Viyrew +Vize Senpai +Vizima +Viziyo +Vjee +Vk +VlBZ +VlGGAN +VlNTER +VlRAL +VlVID +VlaamsePlank +Vlad +VladTheBwana +VladThePaler +Vlada +Vladek284 +Vladi +Vladibjoern +Vladictorian +Vlaendren +Vlambare +Vlast1n +Vlncent +Vloxx +VnG Lynds +VnG Zenyte +Vnce +VngH +VnilaGorilla +Vo Amice +VoHiYo_Nami +Vobia +Vocaloida +Vodbi +Vodec +Vodka +Vodka ice +VodkaBarrage +VodkaBreath +VodkaPlz +Vodke +Voekus +Voetbalkous +Vogefur +Vogues +Vogven +Void +Void Fanatic +Void XVII +Void-Cho +VoidMySoul +VoidOnyx22 +VoidWraith +Voidberg +Voidnight +Voidpaw +Voidrow +Voidseeker +Voidwaker op +Voittosumma +Vokon +VolProMan +Volai +Volantis +Volary +Volblaffen +Volc +Volcan +Volcance +Volcanos +Volco +Volcwinder +Voldesad +Volgos +Volkert +Volkie +Volkrah +Volkzy +Volmortt +Volrod +Volrum +Volt +Volt OSRS +Volt268 +Voltimolt +Voltz Tzkek +Volucris +Volunteer +Volux +Volzo +Vomiting +Vomiting Cat +Vompiainen +Vomuao +Vomure +Von Beck +Von Dylan 2 +Von Locke +Von Reibnitz +VonThaine +Vonbony +Vonderhaar +Vondoom +Voneirus +Vonhinten +Vono +VonoV +Vonschatten +Vonsv +Vonty +VooLis +VoodooCells +Voodookie +Voorheees +Vopi +Vor The Ape +VorGole +Vorare +Vorarlberg +Vorcan +Vorikar +Vork +Vork Planker +VorkathsMate +Vorki +VorkiAlt +Vorkscaping +Voroth +Vorpal +Vorpeo +Vorsamu +Vorschlag +Vorso +Vortob4 +VosOc +Voss V2 +Vossen +Vosty +Voted4Kanye +Vovi +Vox Whoppa +VoxMachina +Voxna +Vozion +Vpdz +Vrauri +Vrayl +Vreaper +Vref +Vrekked +Vriendschap +Vriix +Vrijer +Vrillionaire +Vroeg +VroomMasheen +Vrzn +Vsian +Vsmoke +Vsnn +Vt Flavourss +Vt99 +Vuallis +Vubbe +Vud +Vueko +Vukodlak +Vuku Doll +Vulcan +Vulcant +VulcunLogik +Vule +Vuleka +VulfRS +Vulia +Vulklet +Vulm +Vulo Lives +Vulp +Vulpes +Vulpes Audax +Vuohi +Vurx +Vurzik +Vus +Vusa +Vuto +Vutox +Vuuln +Vuur +Vuuututututu +VvM Otter +Vxmm +Vxus +Vyagruhh +Vyaraeaen +Vyaza +Vyby +Vycarious +Vycos +Vyluxian +Vymera +Vynlx +Vyrelady Em +Vyrza +Vysaraine +Vyseri +Vytauts +Vyukris +Vzb +Vzla +Vzr +W 0 R D +W A G M I +W A G U S +W A V V E S +W E K A +W I L L 777 +W I N 3 D +W J M V +W L F +W O W S K I +W Rizz +W a r s +W ak +W amo +W anted +W e r +W elfare +W i i +W i l l y +W i r e tap +W ifi +W iggly +W illy +W ilmer +W l S E +W ll Z A R D +W olf +W orx +W-2 Form +W-A-M-M-E-R +W00D +W00DINTUNA +W00X W0N DMM +W0MB +W0RY +W0SS +W0fle +W0nderwall +W0t Rng +W141 Legends +W1ETzakje +W1F +W1G +W1Z3 +W1ldman +W1nch +W1ngedDragon +W2P_III +W330 +W349 +W370 +W3SL3T7 +W3ST0RZ +W420 +W489 +W4R3 +W4T3RM3L0N +W4Wumbo +W56 +W5O7 +W7uQs7s1uKyS +W7uQsTu1KsyS +W8 letme pot +W88SSKILLER +W8ST UF TIME +W8ing4Name +W91 forever +WA2 +WAGINGWARS +WAKANDA JEFF +WAKEUPSWEATN +WAP Munchlax +WAQQQ +WARLOCKTIN +WAZABl +WAxsTAche +WBA Scott +WBMA +WE0DEND +WE3N +WEEDY Woody +WEGOINGCRAZY +WEGSIR +WFH Gains +WFTWP +WG Affect +WGWGWGW6W6W6 +WH1TECHAP3L +WHITE E92 +WHITEEEEEEEY +WIMThighs +WINNINGrng +WIRE PULLING +WISEB0LDMAN +WIZRD6 +WLJ +WM94 +WMAF +WMATA +WO0DSIE +WOMYNAREDUMB +WONT +WOOGLlN +WPNsuper +WS Hubris +WS Kyzza +WS Phora +WSOP +WTB GF 1 GP +WTF No Luck +WTF S7VEN +WUDS +WV Boi +WW I +WW2 Champs +WYBD +WYD STEP M0M +WYDStpSis +WZ95 +Wa Wa Master +Wa t +WaIk +WaVy +Waaaan +WaaduuuHek +Waafty +Waager +Waai Do +Waassssaaap +Wabanaki Son +Wabbert +Wabo +Wack Sparrow +Wackabie +Wacko Swaami +Wacoltx +Wadbot +Waddlez +Wadee +Wadeo369 +Waderik +Waem +Wafcfreak +Wafe +Waffle Cone +Waffle Jr +Waffleboy +Waffleici +Wafflekin +Waffles700 +WafflesYo +Wagada +Wagblump +Waggit +WaggsTheDog +Waggz +Wagit +Wagn1984 +WagnBurner +Wagyu +Wahb +Wahido11 +Wahpahp +Wahpan +Waifuism +Waifus +WaikatoChris +Waikit8 +Waine +Wait +Wait Quick +Waitforit14 +Waitin +Wajiiro +Wake +Wake Boarder +WakeAndDrake +WakeUpF1lthy +WakeUpGirl +Wakey Wines +Wakisaka +Walborg +Waldrin +Waldron530 +Wales164 +Walker +Walkin +Walkofshane +WalksOG +Walktellfox +Wall-enberg +Wallabies +Wallabillah +Wallace D S +WallaceTusk +Wallah Krise +Wallah Lag +Wallahper +Walleen +Wallerz +Wallex +Walli +Wallstboi69 +Wallsunny +WallyGator +Walnutt +Walo CZ +Walpie6 +Walsamer +Walshy +Walshy00 +Walshyo +WaltJnr +Walter +WaltersPub +Waltt +Waltzz +Waluigi +Walzu +Wampire +Wan E +WanPanMan +Wandel +WanderTheSee +Wandereer +Wanem +WangSohLong +Wanhe +Wanistan +Wanna +WannaBeE-tje +WannaGetABag +Wannebet +Want +Want2beIron +Want2mess2 +WantTacos +Wantsome909 +Waonnman +Wapf +WapitiSmackr +Wapol +Wapsi +War Dwr +War Force +War12Ready +WarFawk +WarHawKVJ +WarOnOurMind +WarSoc +War_x +Warbler +Warchee +Warcloud +Warclown +WarcraftOSRS +Ward988 +Warden +WardensFe +Wardle101 +Wardless 1 +Wardy791 +Ware Adelaar +Warfeh +Warforged +Warg +Wargames11 +Wargowitto +Warhammer70 +WarheadZ91 +Warking 5099 +Warlolz +Warlord +Warlord Kek +Warlord Oli +Warlord Papi +Warlord Sage +Warlord Tyth +Warlordjinx +Warm +Warm Alfredo +Warm Beer +Warm Donuts +Warm Pasta +Warm Pillows +WarmLoaf +WarmManBlast +Warmantus +Warmly +Warmongoloid +Warmouth +Warnac +Warney +Warnings +WarpedDeath +WarpedMatrix +Warph +WarrgMG +Warrior +Warrior09rs +WarriorHome +Warstroy +Wartika +Wartna +Wartortle +WartoysCandy +Wartt +Warwick 1080 +WasHcimLoL +Wasabeh +Wasbeertjes +WashMachine +Washed CJ +Washyleopard +Waspoeder +Waspraa +Wasserohne +Wassillie +Wasstyr +WasteOfBond +Wasted +Wasted Toxic +Wasted Xj +WastedSpecs +Wastedgr1ny +WastingTicks +Wastinmylyfe +Wastoid +Wasup725 +WasupMyBwana +Watafara +Watamei +Watamelun +Watanuki +Watardid +Water +Water Skink +Water-T +Waterbender +Waterbury +Watercress +Waterdrop +WatermelonTV +Waterpijp +WaterrBoy +WatersHorse +Watertodt +Waterwraith +Watr +Watschi +Watson92 +Wattledaub +WattsyMain +Wattua +Waugh +Waulez +Wauzemaus +Wave 10 +Wave 69 +WaveBtw +WaveSkill +WavesOnMars +Wavezz +Wavy +Wax Dabs +Wax i +Waxby +WaxbyDonkey +Waxing Sun +Waxtap +Waxy +WayOfKings +WayS1de +WayTooPosted +WayV +Wayabove +Wayde +Waydens +Wayert +Wayfarers +Waylor +Wayne +Wayne1149 +WayneBretzky +WayneMain +WayneStated +Wayney +WayofWonder +Waypanaator +Waypastfear +Wayt +Wayward +Wayward Soul +Waza131 +Wazp +Wazup31 +Wazupfighter +Wazzlewop +Wbd +Wcrocks +Wcs139 +Wct +Wdfamidoing +Wdges +We B Trollin +We Feed +We Grinded +We Guard +We Love Dogs +We Tad +We The Team +We sley +We0921 +WeAllGucci +WeAreDoomed +WeAreGroot +WeAreMoksi +WeChat +WeDaBstMusic +WeLoveToB +WeRageAsTwo +WeTheCha +WeTsHaDoW +WeWanking +Wea Boo +WeaIth +Weak Iaugh +Weak Mindset +Weak Terror +Weak Wrists +WeakLesss +WeakSpot +Weakcob +Weaker +Weaki +Weaky +Wealth herbs +Wealthy +Wealthy Pro +WeaponNovice +WeardBeird +Wearwolf +Weasel07 +Weasel09 +WeaselToast +WeaselTuco +Weaselious +Weatherwatch +Weatherzx +Weav +Web 2 +Webb +Webbe +Webben +Webdow +Webs +Webstar +Webtastic +Weby Elite +Wecanmakeit +Weddn +Weder +WedhusGembel +Wee +Wee Seapy +WeeDRekT +WeeMissSlays +WeeWab +Weebcrusher +Weebmurderer +Weed +Weed B0Y +Weed Barrage +Weed Farm +Weed OG +Weed PhD +Weed Strains +Weed VIII +WeedWizzard +Weedbucks +Weedle +WeeeWoooo +WeekndWorior +Weel +Weelechts +WeenieHut +Weeperz +Wehby3K +Wehsing +Weichey +Weight +Weighting +Weightless +Weighty +WeirdChimp +Weirhere +Weis578 +Weistalief +Weki +WelbyBree +Welcome +Welcome Beck +Weld +Weld Arc +Weldar +Welfare PvM +Well Done +Well-ChromeD +Wellar21 +Wellbutrin +Welld +Wellfence18 +Wellpower10 +Wellrun1076 +Wellschit +WellyWonka +Weloy +Welp +Welsh +WelshNProud +Welshfuryy +Welshhy +Welshy 07 +Welshy94 +WelshyRhys +Wemh +Wench +Wendy Page +Wendyy +Weng +Wenja +Wenkey +Wenzhou +Were2341 +WereWaffles +WereWolf II +Werebanana +Werk +Werknemer +Wermin +Werrett +Werrtus +Weru +Wery +Wesh +Weshzz +Weslee +Wesley +Wesper +Wessen +Wesss +West +West Mids +West Shiv +West Tigers +West Varrock +WestFlag +WestTxBoyz +Westardythot +Western +Western PA +WesternBlot +Westleafer +Westly +Westwich +Weszie +Wet Boxes +Wet Garbage +Wet Land +Wet Ottr +Wet P +Wet Sneeze +Wet Thot +Wet and oily +WetDreamMeme +WetForPet +WetRnG +Wetex +Wetone2880p +Wetta +WetterPussy +Wevile +Wexom +Wexs +Wexxorz +Weyerbacher +Wezl +Wh1teSox +WhaIe +Whaddup +Whag +Whai +Whale +WhaleeWatch +Whaletorsk +Whalkatraz +Whamburgers +Wharebadjer +Wharncliffe +What Da Hell +What if +WhatASpoon +WhatAThot +WhatAreDrops +WhatItDoBoo +WhatSheZed +WhatTheDaze +Whatapure101 +Whats +Whats Canada +Whats Good +Whats Reddit +Whats Trade +WhatsHonour +WhatsRsSober +WhatsThisRNG +WhatssapX +Whatsup +Whatz Trade +Whavenlad +Whaxt +Wheatleyprop +Wheel +Wheelchair +Wheelied +Wheelies152 +Whees +Wheesnaw +WhenPigsFly +WhenRuneLife +WhenYouCute +Whensfull +Where is GE +WhereAreWe +WhereIsPeace +WhereTheCats +Whereisme7 +Wheremeballs +WheresMyPets +WheresMyPurp +WheresMyRNG +WheresPurple +WhersMyPet +Whesh +Whey +Whey God +Whiff +WhiityTosser +WhilyWhip +Whimsicat +Whina +Whinnie +Whipppy +WhippyMong +Whipsaw +Whiskerfish +Whiskey +WhiskeyWhip +WhiskyVault +Whiskywayne +Whisp3r +Whisper_2 +Whitah +White +White Beauty +White Mage +White Mantis +White Owl +White Rnger +White Shark +White Soul +White Wolf +WhiteBTW +WhiteBoySam +WhiteChuky +WhiteCricket +WhiteDeathh1 +WhiteMagnet +WhiteMaleHre +WhitePilled +WhiteProdigy +WhiteWolf216 +WhiteZephyr +WhiteZetsu +Whiteboy016 +Whitecoast +Whitecrow +Whitefire68 +Whiteflashh +Whitemambz +Whitetoes +WhizsuJr +Who Add +Who Nose +Who8mypaint +WhoDatDJ +WhoDoICatch +WhoHaxdMe +WhoLikesIron +Whoa +Whoa Gaming +WhoaKemosabe +Whole +Wholelottabk +Whomp923 +Whomst +Whomst MD +Whoratile +Whorrid +Whos +Whos Jo3 +WhosUrDabby +Whosjason +Whosyourmac +Whothehell +Whruum +WhtKndofCake +WhteLilySeed +Whuo +Whurse +Whurse Meat +Why 8ank +Why Play +Why SkaR +Why Try Guy +Why are u ge +Why u N0ob +WhyBank +WhyCantIPick +WhyIsRumGone +WhyNevaLucky +WhyRyan +WhySleeping +WhyTryAtOsrs +Whyase +Whydoubother +Whymcie +WhyteGoodman +Whyto +Wibbity +Wibbix +Wibbleforce +Wicea +Wichel +Wick3d Bet +Wickaboag +WickedKlowns +Wict +Widdly +Wide +Wide Client +Wide Vibe +WideBoyy +WideDommy +Widmee +Widows Kiss +WiebMasterly +Wiebah +Wiebere +Wiebren +Wiebstar003 +Wiegedood +Wielebny +WienerWipe +Wierie +Wiesel +Wife +Wife or RS +Wifi +Wifi Beater +Wig Lops +WigWacker +Wigan +WiganRS +Wiggety +Wiggie +WiggleMcTuff +Wiggly +Wiggly Woo +Wiggoth +Wigins +Wihbane +Wihwy +Wiigg +Wiiillllsonn +Wiiize +Wiji +Wijji +Wijsheid +Wikas1337 +Wiki Flipper +WikiLiex +WikiWorm +Wikinger +Wikingpedia +Wikked +WikuliK +Wilby +Wild +Wild Bill 71 +Wild Clicks +Wild Cowboys +Wild Fury +Wild Orange +Wild Pump +Wild Raven +Wild Rivers +Wild Spirit +Wild Squidi +Wild Stylez +Wild Whim +Wild chickie +WildAbandon +WildGothGirl +WildSF +WildSnorlax +WildTokes +Wilda83as7 +Wildapple +Wildbasher +Wildboy181 +Wildcard +Wildcatface +Wilde Bizon +Wildfire +Wildlands +Wildly +Wildmon +Wildy Back +Wilk +Will +Will Compton +Will Smif +Will T +Will i b +Will man +WillCosby69 +WillG +WillNight +Willasaurus +WillfulNomad +WillfulTiger +Willi +William +William Way +William2133 +WilliamChris +Williamsburg +Williamwrc +Williamwurld +Willianderma +Williard +Willicous +Willie +WillieP +Willlowsap +Willo +Willoweeper2 +Willowisp +Willsy_828 +Willy +WillyMonka +WillySneeze +WillyTickles +WillyVanilly +Willyams +Willymule +WilmaCokfit +Wilnafe +Wilpu +Wilro +Wilso +Wilson +WilsonBro +WilsousGoods +Wilters +Wiltings +Wilwork4stuf +Wilza +Wilzy +Wimm +Wimpy Hulk +Wimpy Worm +Wimpy127 +Winanda +Wind +Wind River +Wind the ham +Windal +Winded +WindexWipes +Windi +WindmillBoy +Windowpie +Windows10 +Windrun +Winds Tormnt +Windwaker +Wine +Wineapple +Winedolphin +WinexBlaze +Wing Daddy +Wing Reaper +WingToe +Winged +Wingedlemur +Wingednebula +Wingknutts +Wingless +Wingman Skre +Wingmanfire +Wingmastah +Wingnut +Wingnut277v2 +Wingoficarus +WingsXIcarus +Wingz +Wink +Winner Chris +Winner1Class +Winning Life +Wintage +Wintaj +Winter +Winter Slays +Winter Woede +Winter mage +Winterpropht +Wintersaurus +Wintertarwe +Wintertoad +Wintis +WintonOS +Winze +Wipe +WipeRZ +Wippy Spuds +Wipzed +Wirbi +Wirusas14 +Wis +WisCheez +Wisdem +Wise +Wise Andy +Wise Bloke +Wise New Man +Wise OlMan +Wise Old Guy +Wise Old Roy +Wise Pug +Wise Up +Wise9884 +WiseBlackMan +WiseOIdMan +WiseOld +WiseOldCam +WiseOldNeef +WiseOldNut +WiseOldSimp +WiseOldWench +WiseYoungOne +Wish +Wishen +Wishidie +Wishies +Wishwandewe +Wishy Walshy +Wispa +WispyWolf +Wissfx1 +Wisundaz +Witch +Witch Aileen +Witch Elf +Witchkraft +Witchprick +Witchz +Witeout LLC +With Skills +Witha +WithoutAGe +Witicism +Witkus +WitlessFox +Witness +Witte +WitteLijnen +Witteri +Wittu +Wittytoad +Wixsie +Wixxa +Wiz master +WizKaleeba +WizKawifa +Wizard +Wizard Weird +Wizard of Oz +Wizard012345 +WizardFish11 +WizardIRL +WizardKing +WizardMascot +WizardSleeve +Wizardmatt6 +Wizardspike +Wizfujin +Wizidross +Wizreefer +Wizyweirdo +Wizz Z +Wizzie +Wizzti +Wizzy +Wizzypoop +Wizzzard +Wkd Br0 +Wkedjester +Wkndr +WlLDERSGEERT +WlLL +WlLL1am +WlLSO +Wlatt +Wlsperingeye +WnB +WnnB +Woadblu +Woah +WoahDudeNice +Wobbery +WobbleyPOP +Woblin +Wobos +Wobs +Wobufett +Wocka +Wocky +Wodka +Wodka Orange +Woe Woe +Woedipoe +Woemance +Woeppa +Woes +Wofford +Wofford2 +Wohdii +Wohrx +Woikaz +WojoWins +Wojtas +WokeUp +Wokkel +Wokki +Wolf +Wolf Berserk +Wolf66 +WolfApple +WolfLucifer +Wolf_Hunter +Wolfazal +Wolfboi70 +Wolfboy1209 +Wolfden95 +Wolfeena +Wolferno +WolfgarrX +Wolfgarth +Wolfhearth +Wolfie +Wolfie Daddy +Wolfiezzz +Wolfinger +Wolfique +Wolfjob +Wolfman +Wolfman00777 +Wolfmans +WolfnBane +WolframOxide +Wolfshade +Wolfshook +Wolfspeed +Wolfy3777 +Wolfz +Wolles +Wolq poW +Wolverine V8 +Wolvesy +Wolwa +WomanScorn +Womaz +WombatLife +Wombats +Wombayaga +Won Alll Day +Wonderful +Wondo +Wonka44 +WonkyShlonky +Wonn +Wonnawonka +WonterJodt +Woo Hee +WooGGi +Wood +Wood Choppin +Wood Scimmy +Wood Style +Wood VI +Wood4all +WoodJablowm3 +Woodcrest +WoodcutterQw +WoodenSword +Woodland +Woodsboro +Woodson +Woodsy +WoodsySmells +Woody +Woody540 +Woody8 +WoodyBussy69 +Woodys +Woodz90 +Woof +Woof Woof Jr +Woofaire +Woofi +Wooh +WookieBread +Wool Socks +Wool Tar +Wooli +WoollffMain +Woolly +Wooo Blod +Wooody125 +Woooglets +Wooogy +Wooooo91 +Woopie Doop +Woopsx10 +Woopuh +Woord +Woorm +Woos +Woosa +Woot +Woowoh +Woox +WooxFromWlSH +Wooz +Woozie400 +Wophel Iron +Word +Word Bird +Word2urmum +WordCheck +Work +WorkUkko +Workahaulix +Workath +Workin +Working Man +Working Poor +Workouts +Worland +World +World 46 +World 526 +World 61 +World Of Rat +World345 +WorldEndero +WorldWarTwo +Worldly +WorldsGr8est +WormInHeaven +Wormeater66 +Worms +Worning +Worning Mood +Worst Herp +Worzo +Worzord +Wosby +Woshy +Woste +Wostyn +WotCee +Wotnel +Woudie +Woul +Wounded +Wounds +Wourlow +WouterMarni +WouterPils +Woutertje +Woutertje 93 +WowAUnicorn +WowDerek +WowoW +Woww +Wowzer1482 +Woz X +Wozi +Wozol +Wozzah +Wozzy +Wqlq +Wrackbar +WraithSx +Wramn +Wrap +Wrap5 +Wrath +Wrath0fMath +Wrathchildxd +Wrathinsea +Wrav +WreXham AFC +Wreck These +WreckAndRoll +Wreckage +Wreckanism +Wrecked +Wreckfull +Wreckin4Days +Wreckon +Wreckonize +Wrecky +Wreckzu +Wrekdum +Wrektem +WrektumRalph +Wrenny +Wrigzer +Wrijo +Wrinkle Meat +Wripzi +Writing +Written +WrmFzy +Wroggi +Wrong +Wrong Focus +Wrot +Wruumze +Wryd +Wrynn +Wsupden +Wtf Burgers +Wtf Bwana +Wtf Is Elmo +Wtf Michael +Wtf happen +WtfJad +Wtf_Stake +Wtfisabook +Wtfxcreepy1 +WuLuZ +WuTangDan +WuTangRs +WuTangflame +WubbaRs +Wubj +WuceBrayne +WuckFeeaboos +Wucky +Wudkip +Wueu +Wuhan +Wulfeh +Wulkanaz +Wullets +Wulong Rush +Wumbolii +Wumox +Wundy +Wungz +Wunk +Wuntch Meat +Wur1 +Wurgon +Wurj +Wurrior +Wurstfest +Wurtziite +Wuteng +Wutlife +Wutru +Wutta Beast +Wuuluu +Wuz H +Wuzn +Wuzzi99 +Wwalrus +Wwarlock +Wxll +Wxyz +Wy 1853 +Wyan +Wyard +Wyatte +Wybb +Wybo +Wyborowa +Wyd +Wydie +Wyel +Wyiphi +Wyldar +WyldeKirito +Wylie +Wyliecoyote2 +Wylyne +Wynand +Wynmao123 +WyoFletch +WyrdStoned +Wyrlor +WyvernBreath +WyvernMage +WyvernSlayer +Wz Karmish +Wzurd +X X V +X 0H +X Axis +X Bullet X +X Dsmith X +X E L E X +X E R 0 +X Ecuted +X I L E +X Ice Break +X Japan +X King Jehu +X Landie X +X Mars +X Mathiew X +X OUT OF RS +X Robert X +X Rorschach +X SUR X13 +X Seabridge +X WAVE 70 X +X Y P O +X e x i m +X pelz +X-Jabs +X-Man +X-SVNTH +X0N3X +X1xfa11enx1x +X65 +X9Y +XAAXAA +XANSEB +XARlQUE +XATHD +XAyYxlMaOxX +XCShark +XCortezX +XD XDDD XD +XD8D +XDQ +XDamage +XERTNARG +XESPIS +XEback +XFitVapeVegn +XHCD +XI J +XI5 +XIBT +XIX Zeta XIX +XIXIXIXVXIVI +XIXXI +XJT +XKappaX +XL Peen +XL Succ +XL itikka +XMR +XNovaCainX +XOBLIN +XORB +XP All Night +XP Hobo +XP Jake +XP Thieving +XP for gains +XPOQ +XRP Glandorf +XRV +XRay Mike +XS3X +XSandwich18 +XSapocalypse +XTCarlo +XTIF +XUJ0RKI +XV73J +XXGrimorgXX +XXTENTACI0N +XXaan +XXera +XZoTicTB +X_Ouchies_X +X_Streetz +Xa1e +Xaaan +Xaberphel +Xadia +Xaeram +Xafirox +Xahp +Xaint +Xalastar +Xalcvs +Xalrir +Xam Renz +Xambitz +Xamphion +Xan Gogh +XanaxXR +Xandahr +Xandayn +Xanefeo +Xanfan +Xann +XanomaliuX +Xanq +Xanthophylle +XanthousKing +Xantiasto +Xar +Xarigue +Xarious +Xarkus +Xarnathos +Xarov +Xarpus Decay +Xarqn +Xartes253 +Xaryn +Xasdaxs +XaskiM +Xasthur +Xatar +Xaud +Xaussiemaulx +Xav777 +XavieerL +Xavieerr +Xayrus +Xazz12 +Xbalan +Xbogaerts +Xbox +Xbox Account +Xbox kid 99 +Xboxkid33 +XcL ady kila +XcalenX +Xcalumet +Xcelorin +Xcuuuse +XeNeaxaxa +Xebstrika +Xecki +Xedoria +Xeem +Xeet +Xefi +Xefn +Xelas +Xelcab +Xeldin +Xelian +Xelzathar +Xemnax +Xems +Xen0phyte +XenaDior +Xenastry +Xendel +Xenece +Xenethos +Xenfire +Xeniat +XenithStar +Xenlon +Xennofobia +Xeno X Human +Xenofiel +Xenofile +Xenoforms +Xenorith +XenoviaZhao +Xenria +Xenses +Xentric +Xentric I +Xenzah +XeoX +Xeqo +Xeretus +Xeric +Xerics +Xerics Exile +Xerics Solo +Xerile +Xerkom +Xerloz +Xero +XeroBlitzAce +XeroBone +Xeroish +Xerona +Xeroscape +Xerosenkio +Xeroso +Xerphias +Xertrius +Xerxe +Xestox +Xetarillos +Xewne +Xeyler +Xfebruari23X +Xflowerz1 +Xgen2004 +Xghostbx +XgodofironX +Xhaloz +Xhq +Xi Bogan iX +Xianerth +Xiang +Xiang Ying +Xiao Wei +Xick +XicoDoAnzoL +Xidos +Xielt +Xiff +XigZig +Xiglaan +Xijaxer +Xilamz +Xillious +Xilphy +XinXani +Xinbonddon +Xinck +Xiom +Xiphoz +Xipi +Xipo +Xirenia +Xists +Xityx +Xiuol +Xizor +Xizxuka +Xizz +Xj Driver +Xl Pat lX +Xl Tango lX +Xlarss +Xlogmore +Xmas Santa +Xmasvibes +Xmerl +Xnam +Xname4 +Xniklaz +XoXdr34mzXoX +Xofal +Xoir +Xojix +Xolca +Xolidus +Xolmia +Xolun +Xonzz +Xoobs +Xorphas +Xorx +XoutofRunes +XpTitan +Xpect2die +Xpelz +Xperiencer +Xplay2slayX +Xplicits +XploitClamps +Xpm +Xpreme +Xqcksilverx +Xqkiller +Xquick +XrRipple +Xsk1l3rX +Xskillz +XslayerkingX +Xsy +Xtan +Xterioz +Xternal VZ +Xteven +Xth +Xtian +Xtopheris +Xtreme Kill +Xu +Xu3 +XuRuP1Ta +Xufo +Xuhe +Xulaa +Xulreh +Xupafion +Xuro +Xutera +Xuxe +Xuxy97 +XvalQ +XvalentiX +XvegetaX +Xvim +Xwb +Xwoprl +Xx A ll y xX +XxBABY +XxBriDGExX +XxCoponerxX +XxJIMBUSKID +XxKaakkimusx +XxMOPExX +XxPoliSwagxX +XxRXZ60xX +Xxhel +Xxpyroxx20 +XxrigourXx +Xxsagexx30 +Xyagrius +Xylarium +Xyler +Xylr +Xylym_pilot +Xymox +Xynamic +Xyrath +Xyresic +Xyryu +Xyzcanon +Xz8 +Xzavier +Xzil +Xzpect +Y DynHaearn +Y Fx +Y O D A +Y O K A I +Y arok +Y ellow +Y em +Y ogo +Y oshi +Y0N3 +Y0l0mees +Y0usless +Y2K38 +Y2k Survivor +Y3RBA +Y3w +Y4P +YBank_Mak 69 +YCTH +YCantPigsFly +YChewyYOS +YEEEZY +YERTII +YExTI +YGBigTank +YKW +YM +YMJFL +YNW Kushy +YOKiki +YONGWOLRANG +YOOOH JOEE +YORJ +YOTJ +YOUR +YOURMOMSMAN +YS3 +YSL +YSL for Life +YSinpo +YTPO +YTrySoHard +YUSEF +YWM +YYST +YYose +Ya Boi Suff +Ya Boy Lachy +Ya Boy Ryan +Ya9 +YaBoiCrisps +YaBoiSlip +YaBoiWestie +YaBoiiQuan +YaBoyCosmo +YaDoons +YaLilMupp1t +YaOldHeffer +YaSillyRAT +Yabai +Yabbary +Yabbie Pump +Yaboiskee +Yaboitrek +Yaboku +Yabui +Yachi +Yachiri +Yackill +Yackity Yak +Yackley C +Yagyu +YahRamen +Yahe +Yahtz3 +Yahtz3e +Yahya10100 +Yaik +Yaimzz +Yak Elves +Yak of Iron +YakYak +YakimaValey +Yakka Stacka +Yakosu +Yakushima +Yakuza +YakuzaDragon +Yalazar +Yall Raycist +Yalloune +Yalomi +YamR6 +Yama XCII +Yamagata +Yamakato +Yamata +Yamda +Yami +Yami Bakura +Yammed +Yampay +Yampay II +Yamsaretasty +YanKeDooDle +Yand0 +Yang +Yangtze +Yangus456 +Yani +Yanilla +Yanilla Kush +Yank on This +Yankee Run C +Yann78 +Yannick177 +YannickH +Yannis +Yao Yo Xin +Yaossynx +Yaprakdal +Yardi +Yarfn +Yaribel +Yarne +Yarny +Yaseki +Yasen 105 +Yasuos +Yasuuo +Yato1God +Yaukai +Yauz +Yavrum +Yawan +Yawgg +YawningPanda +Yawp +Yaxfe +YayItzTyler +Yaysuo +YazanBates +Yaziro +Yazo +Yazuki +Yberi +Ycinho +Ydmyk +Ydorog +Ydrasil +Ye Magekilla +Ye Mate +Ye Olde Ace +Ye Olde Ned +Ye Olde Oak +Ye ti +YeBankWicked +YeBoi +Yea UrBanned +YeaAiiiiite +YeahIMineIM +Year +YearUp +YeastPocket +YeastyPussey +Yeblehs +Yechs +Yeda +YeebusGeebus +Yeeeeehaww +Yeeetist +Yeeetscape +Yeern 101 +Yeeska +Yeet Dan +Yeet Thyself +YeetMemes +Yeeted One +Yeetu +Yeezy +YefTalks +Yefim +Yehtii +Yeiw +Yek +Yekhsad +Yekouri +Yeland +YeldariIII +Yeli +Yelling +YelllowFlash +Yellow +YellowForest +Yellowfox21 +Yellowhoody +Yem o +Yemly +Yemrisnen +Yenie +Yenil +Yenofthunder +Yenom +Yentelke1998 +Yeoubi +Yeoz +Yep Cup +Yerbal Tea +Yerd +Yeren +Yerico Tsu +Yerkinoff +Yerm da worm +Yeroen +YerrBanned +Yerradu +Yerrrrey +Yes Click Me +Yes No Maybe +YesOk +YesYesYall +YeshuaShalom +Yeso Pro +Yessir +Yesze +Yetagaindied +Yeteri +Yeti +Yetiburger +Yetlon +Yetsu +Yettiez +Yetzne +Yevop +Yevral +Yew 2 +Yew Burn +Yew Root +Yew Tree +Yew Wu +Yew a sloot +YewEssBee +YewGnomeSayn +Yewcutter +Yewise +Yewna +Yewp +Yews pnas +Yewsanity +Yewse +YexaC +Yezzi +Yfer +Yffud Gnik +Yggdrasverre +Ygh +Ygritte8686 +Yharnam Soul +Yhul +Yiatse +Yid +Yidy +YikesScooby +Yilver +Yimo +Yinlin Simp +Yippe +Yippiyak +Yisabela +Yja +Yke +Ykeykey +YlFF +Ylikivaa +Yllattyneet +Yllig +Ylmn +Ylpistynyt +Ylulawo +YmanThe1 +Ymbyydi +Ynastra +Yne +Yng Xehanort +Ynka +Ynun +Ynza +Yo Caspian +Yo Griff +Yo Its Devo +Yo Kev +Yo L +Yo MyUSD +Yo Soy Dios +Yo lm Lee +Yo uu +Yo wyd +Yo2021 +YoCerberus +YoGurttt +YoHighRoller +YoHimiiTsu +YoIronManBtw +YoKristaps +YoMomsFavBF +YoSinNow +Yobew +Yocan +Yoco +Yoda +Yoda Adf +Yoda Corona +Yoda NSZ +YodaEvans +YodaPen +Yodamainn +YodasNo1Fan +YodasYoda +Yodasquad +Yodati +Yoder +Yoerias +Yoeshua +Yofang +Yoghurtis +Yogi +Yogi DMT +Yogi Surfer +Yogololo +Yogusun +Yohny +Yoink +YoinkYoink +Yojak3 +Yokie +Yolkysky +YoloSwagHope +Yolp +Yolvert +Yomaku +YomamaPro +Yomashu +Yomdo +Yondu +Yondu Poppin +Yonemid +YongZhong +YongZonnegod +Yonkers +Yonko Buggy +YooDuragon +Yoodish +Yoooord +Yoorah +Yor +Yorga +Yorick +Yorick095 +YorickMorty +Yoriichan +Yorinky +York Rite +Yorkson +Yoru +Yosep +Yoshi +Yoshi Man17 +Yoshi Suyumi +Yoshi6380 +YoshiThick +YoshisStory +Yoshiwaptor +Yoshizilla +Yotaak +Yoteii +Yotsuya Miko +Yottie +You Are Zach +You Be Love +You Die71 +You Ok Fam +You R D3d +You rc 2 +YouGotRoll3d +YouGotSeabed +YouNeverKnow +YouOverThink +YouSuck +YouWontScare +YouareGE +Youbartonz +Youme +Youncies +Young +Young Bucket +Young G4 +Young Guthix +Young Krazed +Young Logic +Young Mooch +Young Mullet +Young Tango +Young li +YoungCatFish +YoungNoot +YoungScuba +YoungThugga +Youngdaddyg +Younge +Younglleff +Youngn +Youngsters +Youngvet +Your +Your Amity +Your Future +Your Idol +Your Misery +Your Mom67 +Your Mothers +Your Toilet +YourDadIsMe +YourFrenRen +YourObsessed +YourPaperm8 +YourSolution +Youre Joshin +YoureAllTalk +YoureIgnored +YoureMySam +YoureSoCool +Youssef +Youthful +Youtube Luck +Youwillcower +Youxi37 +Yowarrior40 +Yowch +Yowzer +Yoxz +Yoyaaaaaaaaa +Yoyo +Yoyo502 +Yoyoma007 +Yrasa +Yrdna +Yre +Yrjo +Yrok +Yrrabo +YsL Dom +Ysdragos +Yshtola +Ysr +Yster +Yster Bunny +Ysuke +Yu Seolha +Yu Stinkipu2 +Yu Zi Jiang +Yubs +Yubz +Yucan Tucan +Yuck +Yuck Aroma +YuckFou +YuckMouth +YuckNoYums +Yudi +Yuengllng +Yug Cipe +YugiMoto666 +Yugioh +Yuhai +Yuigahama +Yuiii +Yuiku +Yuipster +Yuka Takaya +Yukaiaiaiai +Yuki Kitsume +Yukika +Yukionna +YuliusCaesar +Yulong +YumYumSauce +Yuma az +Yumaad +Yumbo +Yumhumgao +Yumiko +Yummy +Yumped +Yundastan +Yundruh +Yuneekh +Yunery +Yung +Yung Belial +Yung Birdie +Yung Deaner +Yung Nice +Yung Swoosh +Yung Zach +YungDuski +YungIron +YungMoistGod +YungPredator +YungSlick +YungThimothy +YungTungsten +YungWhiteBoy +Yungsik +Yungsingteng +Yungyonder +YunnT +Yuno +Yuno Yuno +Yunozen +Yunq +Yunthers +Yuoni +YupImMadBro +Yupal +Yuqi Dab +YuqiShuhua +Yurimo +Yurix +Yuriy +Yusaris +Yusko +Yutorgborm +Yutzz +Yuudachi +YuugeJohnson +Yuuki +Yuuma +Yuuuuurd me +Yuuzu +Yuyevon2003 +Yuyu Shirai +Yuzumii +Yveaux +Yvno +Yvoa100 +Yvon +Yvuar +YxY +Yxskaft +Yzanagi +Yzap +Yzyszn8 +Z 0 D I A C +Z 84 +Z A D O +Z A R G O T +Z A V Y +Z Barrows +Z E R0 +Z I K O +Z Jay +Z M P +Z O R 0 +Z O V K O +Z O ZO +Z Rowz +Z a a K i R +Z aeBae +Z e e e f +Z e x +Z ebak +Z edd +Z erkie +Z ev +Z i g g e h +Z igZag +Z ion +Z y g y +Z ygis +Z-TheReaper +Z00STER +Z0K0 +Z0MBI3 +Z0MBIFIED +Z0NK3D +Z0RB0 +Z0bbey +Z0deac +Z0ops +Z1pn +Z1pn_xD +Z26 Man +Z3 +Z3FRAN +Z3R0 CO0L +Z3ds +Z3ymour1 +Z4phy +Z4ppie +Z6L +Z7Z7Z777ZZ +Z900 +ZACCU +ZADDYGANG +ZALCANOPET +ZALGlRlS +ZAQWRY +ZB84 +ZBLOCKA +ZEIVI +ZEKEDAFREAK +ZELDRIS0 +ZER0 EHP +ZER0Z +ZGJ +ZHG +ZIARED +ZILLER +ZJ +ZL1 Devin +ZLA +ZMB Scary +ZMithrilMan +ZNDX +ZOEY 101 FAN +ZPWUZZLED122 +ZRegi +ZSYD230207 +ZUCK +ZUK EXPERT +ZUwUBI +ZWUNK +ZWlFT +ZX +ZY +ZZ +Z_Z +ZaPhiRoxD +ZaadTeef +Zaane +Zaanstad +Zaatar +Zabe +Zabey +Zabini +Zabky +Zaboxi +ZacAynsley +ZacBallsHard +ZacFx +Zacariah D +Zaccchhh +Zaccy +Zacflame +Zach +Zach 6464 +Zach Patino +Zach est13 +Zach q p +Zach07 +Zach314 +Zach4211 +Zachagawea +Zachatank +Zachawy +Zachh +Zachhh +Zachs +ZachsAccount +Zachulous +Zack0ry +Zack504 +ZackAsch +ZackSparrow +ZackWasTaken +Zackary +Zackle Berry +Zackly +Zackman +Zackology +Zackree +Zacky P +Zacoron +Zacxion +Zaddy Bully +Zaddy Zo +ZaddyCool +Zadek +Zadior +Zadok +Zae +Zae The Bae +Zaenil +Zaeres +Zaf +Zafaron +Zaff +Zafrot +Zaga911 +Zaggly +Zagustin +Zagz +Zahard Army +ZahellGlarus +Zahellina +Zahiirr +Zahnae +Zahrani +Zaion +Zairin +Zairx +Zaitsev +Zaixii +Zaixyyuu +Zakhary +Zakje Pep +Zaku Rs +Zakz +Zala +Zalaberto +Zalar +Zalat +Zaleander +Zalen +Zalerae +Zalotus +Zalphyrus +Zalse +ZaltyPretzel +Zalux +Zam +ZamPeZu +Zaman +Zamanr +Zameul +Zami +Zamianx +Zamicxus +Zamirok +Zammiy Slay +Zammy +ZammyHasjta +ZammyJesus +Zammys Flame +Zamorak +Zamorak 61 +Zamorak Book +Zamorak Tome +Zamorak808 +ZamorakBrews +Zamorakz +Zamorangue +Zamorizzle +Zamowrecked +Zamypkernoob +Zamzam +Zamzico +Zanakkusu +Zanc +Zandie +Zandous +Zane +Zanfew +Zanfis +ZangKeera +Zangola +Zaniels +Zanimoto +Zanithic +Zanity +ZannyBatsbak +Zanryu +Zans +Zansus +Zantaril +Zanwk +Zanzu +Zaom +Zaon +ZapWasTakn +Zapah +Zapatos +ZaphiasTM +Zaphyan +Zaphyrim +Zapii +Zapio +Zapky +Zapleno +Zapletics +Zappaforever +Zappman123 +Zapppy +ZappyLand +ZappyWabbit +Zapsticle +Zaque +Zara Mobile +Zaraffa +Zararod +Zarasth +Zarathos +Zarchonias +Zardee +Zardua +Zarf +Zarfa +Zargole +Zariah +Zariky +Zariser +Zarke +Zarkh +Zarkino +Zarkoz +Zarley +Zarliona +Zarmos +Zaro +Zaro M +Zaroki +Zaros +Zaros2k +ZarosCorrupt +ZarosRex +Zarosadomin +Zarosian Rat +Zaroux +Zarov +Zarpedon +Zarrix +Zarude +Zarvern +Zary +ZaryteKnight +Zasi +Zasilus +Zastava Ak47 +Zastavo +Zatailex +Zatch175 +Zathul +Zatom +Zattix +Zauberbiest +Zausbaus +Zav555 +Zavaren +Zavikk +Zavilia +Zavinor +Zavorak +Zavvia +ZavylonCG +Zawro +Zawts +Zaxbys +Zaxcord +Zaxm1 +Zaxxxsoldier +Zaza9119 +Zazian +ZbraCakez +Zbychu +Zch +Zcj +Zcu +Zdawg +Ze Golo +Ze Own +Ze Punheteir +Ze Ubernoob +ZeOblitz +ZeProx +ZeQuYaa +ZeZienMaar +Ze_balla +Zea1ous +Zeal +Zealandra +Zealea +Zealicious +Zealoe +Zealous Love +Zeals Max +Zeather +Zeb Slays +Zebak +Zebak Acid +Zebaks Jugs +Zebedank +Zebede +Zebest605 +Zebras +Zebs main +Zebs scuffed +Zebu +Zebuck +Zecca +Zechuchith +Zect +Zed7 +Zed_11 +Zedanko +Zedar +Zedd +Zedd UwU +Zedd180 +Zedek +Zedirex +Zeds +Zedz +ZeeAyyBee +ZeeEL +ZeeZeeZee +Zeebers +Zeec +Zeedith +Zeehox +Zeeke +Zeekheart +Zeelmaekers +Zeemoee +Zeeny +Zeeon +Zeep +Zeepra +Zeerkel +Zeeshan +Zeeshan01 +Zeeuun +Zeeuws +Zeeuws Tuig +Zeeve +Zeeyk +Zeezki +Zeffe +Zefrank +ZefyX3 +Zegetable +Zeh Zimah +ZehThijs +Zehbu +Zehf +Zehiret +Zehv +Zeilex +Zeinovyah +Zeious +Zeitgaist +Zeithex +Zeken +ZekimusPrime +Zekje +Zekkels +Zekley +Zeko01 +Zekrom +ZelaooReturn +Zelatrix +Zelcano +Zelcode +Zelda +ZeldaHaxor42 +Zeldamen +Zeldaza +Zelle Me GP +Zelnite53 +Zelroy2 +Zelten +Zelzoy +Zemiak +Zemie +Zemix +Zemmy +Zemoko +Zemps +Zemyrrah +Zen Moments +ZenBtw +ZenRaidz +Zena96 +Zenathrius +Zenci +Zenearys +Zenemz +Zenez +Zenfor +Zeni Master +Zenithina +Zenitsu +Zenium +Zenki +Zenki RS +Zennyte +Zeno +Zeno Pho Bia +Zenoce +Zenpep +Zenqii +Zenqs +Zenrrrr +Zensai +Zentae +Zentra +Zenytum +Zenzulo +Zeon Clone +Zeorun +Zeos +Zeoth +Zeou +Zeoxr +Zeph +Zeph0s +Zepher138 +Zepherahs +Zephere16 +Zephrinne +Zephxa +Zephylius +Zephyren +Zephyrhills +Zephyric +Zephyrot +Zeplin1 +Zeppelin IV +Zer0Requiem +Zer0Tw0 +Zer0mancer +ZerUmh +Zeratul259 +Zerbeh +Zerberous +Zeref +Zerendipity +Zergonaut +Zeri0n +ZerkByDay +ZerkInDaYard +ZerkMeOffPlz +Zerkeee +Zerker +Zerker fe +Zerkism +Zerkom +Zernag +Zero +Zero Cals +Zero DeNiros +Zero Saber +Zero Scope +Zero Suit +Zero Talent +Zero Tol +Zero Zeros +Zero92922 +ZeroAltruism +ZeroBodies +ZeroCake +ZeroDignity +ZeroFox8576 +ZeroGravity3 +ZeroHour +ZeroHpAgain +ZeroTheKing +ZeroValor +ZeroXJD +ZeroZero +Zerobeat +Zerodareborn +Zeroeagle +Zeroen +Zerololz +Zeroly2 +Zeroswift +Zerq +Zerrilis +Zerro +Zersers +ZertUwU +Zerx +Zesima +Zeskater +Zesty +Zesty Bvrnsy +Zesty Senpai +Zesu +Zet_RS +Zetani +Zetardo +Zetore +Zetreker +Zetrus +ZetsuboSekai +Zetsubou +Zetta +Zettty +Zeug +Zeus +Zeus Jr +Zeus07 +Zeus09 +Zeusvdl +Zeven +Zeveria +Zevlim +Zevosh +Zevvo +Zewx +Zexma +Zexra +Zexual +Zeyora +Zeyzima +Zezaroth +Zezergz +Zezima Simp +Zezima W q p +Zezimaislife +Zezimas +Zezime +Zezus +Zezynx +Zfg Fan Girl +Zfsalt +ZgeL +Zgrite +Zgzi +Zhacarn +Zhaoyl +Zhava +Zhinky +Zhiqth +Zhonny +Zhops +Zhotaro +Zhqith +Zhuxiong +Zhuzh +Zhykiel +ZhyloFlex +Zi P +Zi1y +ZiNikor +Ziauze +Zick Licker +Ziclone +Zidi +Ziega +Zierikzee +Zigfrid +Ziggey +Ziggurattus +Ziggydog7 +Ziglar +Zigory +Zigzagoonfmt +Ziicatela +Ziidz +Ziinc +Ziincor +Ziisus69 +Zijwiel Iron +Zikry +Zil o +Zilandraa +Zilanthra +Zilex +Zilexion777 +Zilly +ZillyLovesMe +Zillya +Zilpha +Zilvia +Zilyana +Zilyana Gr +Zilyana Jr +Zilyanas Dad +Zilyarma +Zim +Zim8 +ZimFlare0003 +Zimak +Zimaterasu +Ziminiar +ZimnyZielony +Zimpathizer +Zinc +Zinct +Zing +Zingg +Zinixon +Ziniy +Ziniyy +Zinnialexis +Zinogre +Zinoto +Zinryia +Zinshaw +Zinsmaster +Zinsmeistro +Zioh +Zion +Zion Fire +Zioo +Zip Lynx +Zipacna +Zipit +Zipm +Zipo259 +Zipp0Fluid +Zippeeee +ZipperTrout +Zippy909090 +Zipsap +Ziqs +Zireal +Zireb +ZireneV2 +Zirkisi +Zirn +Ziron +Zirrub +Zirvzaa +Zisam +Zitaya +Ziti Sauce +Zitri +Zittte +Zivile +Zixcon +Zixon +Zixxen +Zixxty +Ziyai +ZizZazZuz +Zizarius +Zizou +Zizzle +Zji +Zjoelini +Zkilrr +Zkyui +ZlGGEY +ZlNQK +ZlZl +Zlap +Zlatan +Zleek +Zleepeey +Zlig +Zlomble +Zlote +Zlug +Zmancool +Zmanonthego +Zmazek +ZmaziWasHere +ZmbieShepard +Znked +Znorox +Zo e y +Zo m B +Zo nk +Zo7al +Zoak +Zoanthids +Zoaxyl +Zobbe +Zobny +Zoca +Zoca BD +Zodden +ZodiacIsTed +Zoeh +Zoet +Zoey +Zofad +Zofu +Zogggii +Zoggy Marley +Zogloid +Zogurk +Zohi +Zoik +Zoil +Zojun +Zok +Zoka +Zolarf +Zolaris +Zolcome +Zoli +Zolkaria +Zollo +Zolon +Zolrisma +Zolruh +Zolt09 +Zoltan Uk +Zoltanious +ZolwoZ +Zombah +Zombi Zack +Zombie +Zombie Cody +Zombie Zack +Zombiezparty +Zomboide +Zombrons +Zomi +Zomimi +Zomp +Zone Red +ZonichGG +Zonir +ZonlyAlex +Zonnedael +ZonoxRS +Zonse +Zonum_Knight +Zoo Orleans +Zoo scape +Zoobloo7 +Zookly +Zool +Zoolander +Zoolander011 +Zoom +Zooming +Zoommaster97 +Zoonix +Zooted +Zoppy +Zorb49 +Zorblet +Zorcar +Zoret +Zorg +Zorh +Zorie +Zorin +Zorkath +Zorkz +ZornDurag +ZoroRoronoa +Zorolith +Zoros son +Zorrac +Zorrita +Zorros +Zoryov +Zos +Zosc +Zossssssssss +Zostok +Zoteize +Zotetz +Zoudrex +Zoumok +Zouns +Zown +Zowski +Zozma +Zozo1232 +Zpizz +Zqw6 +ZrankerF +Zrax +Zriv +Zrr +Zsedcx +Ztneff +Ztxch9 +Zubaritis +Zubora +Zubsolv +Zuburus +Zucchini3 +Zuchini +ZuckZyZock +Zucu +Zuel +Zuened +Zuggster +Zugmah +Zugs +Zuibbi +Zuiox +Zuipe +Zuipen +Zuipvlek +Zuk +Zuk Bot +Zuk Cucker +Zuk Meh Off +Zuk My Toa +Zuk Sucks +Zuk a Duck +Zuk a Zik +Zuk at 1 Kc +Zuk my Tzok +Zuk was here +ZukDisLilZik +ZukMadic +ZukMyAss +ZukOrBust +Zukala +Zukmos +ZukoTheMcoon +Zul-Bot Farm +Zul-tul +Zulandra +Zulax +Zulex +Zullander +Zullrah +Zullu +Zulrah Goat +ZulrahSlave +Zultora +Zulu +ZuluLippen +Zum +Zumaz +Zumaz Her +Zumb ass +Zumwalt +Zundaddy +Zundix +Zunkrah +Zup Rap1 +Zurad +Zuramaru +Zurcal +Zure Kut +Zuremate +Zuriel +Zuriel321 +Zurius +Zurkzes +Zurlofix +Zurn +Zurper +Zurqos +Zurthur +Zurvan +Zurxas +Zuubi +Zuuqe +Zuurkast +Zuv Arik +Zuviel +Zuwy +Zuxar +Zuxf +Zuxi +Zuzad +Zuzas23 +Zvg +Zvirbulis +Zvotne +Zw3d +Zw4rtjoekel +Zwabba +ZwangerePapa +Zwanneke +Zwartbeast +Zwartbest +Zwarte Iron +Zwarte dief +ZwarteAapMan +Zwartehand +Zwef +ZweiBeer +Zwei_02 +Zwerky +Zwette Draak +Zwieber Vos +Zwiers +Zwift13 +Zwijg +Zwil +Zwimps +Zwinter +Zwlr +Zwwwnbeast +Zx J3SS3 xZ +ZxFe +ZxbeeRs +Zxeon +Zxirl +Zyad +Zybes +Zyck o +Zydecolarry +Zyer +Zyev +Zygalo +Zygameux +Zygy +Zykaite +Zykonic +Zyl +Zylco +Zyleta +Zyliana +Zyllami +ZynGardener +Zynerith +Zynnocent +Zynthe +Zyntixero +Zyper89 +Zyrem +Zyrinth +Zyrok +Zyrona +Zyrpex +ZyruviasDied +Zyunkko +Zyxla +Zyxuz +Zyyra +Zyz +Zyzziima +Zyzzy +Zyzzz brahh +ZzJ0SH +Zzanoss +Zzayo +Zzuma6 +Zzyzzx +Zzzax +Zzzd +ZzzzG +[#OA0VWICQ8] +[#SG1JGUXTW] +_Untrimmah +_gria +a Cairn +a Dang +a Mikey +a Miko +a Venenatis +a Venny +a Weeman +a bean +a black cod +a casul +a cooky +a cool bug +a eu +a f o +a gentle sir +a little sad +a ndo +a p p l e +a pathetic +a pb +a sad kraken +a sad waffle +a sk y +a the sniper +a tnQ +a trash cat +a zo +a-x51 +a07 +a1liez +aDome +aDuNaz +aGamerGaming +aGamingDad +aGlasgowGrin +aGoober +aIIfather +aKSU nPC +aKash20i3 +aMiniDude +aMiniGorilla +aMiniHitMark +aNERDYsloth +aNStarFury +aPinkBunny +aPinkKitten +aShavedLlama +aSnowTiger +aSunnyPotato +aSwiftyBoi +aThoms +aTinyChimp +aVolk +aWildSeal +a_SaladKing +a_duncan +aa noob +aaah +aaahChu +aalucard +aanmaken +aanwaz1g +aaron_diaz +aaronparkerr +aatudoz +aaty +ab0u +aballer09 +abbruzi +abbruzie +abcz +abdi +abdimajiid +abdulllah +abis +abk144 +abni +about blank +abqve +abra238 +abrakadabraZ +abray +abu hassani +acceleratism +ace375 +acecoffee2 +acerkush +achillies +achillies zy +achinadav +achterkamer +acidshit +actionbob +actlater +actofvalor24 +acuile +adPEXtwinDnG +addaaam +adem6792 +adizzle444 +adogg0323 +adopt +adrian +adsdadasdgtd +adsh55 +adue +adul +adul t +advia +advies +advit +aeej +aeggefar +aejfd +aenpaa +aezthetic1 +afatslug +aferraro +afh +afk 2 2277 +afk a bunch +afk n doc +afkayscape +afkdontattac +afkingRS +afkvsehp +afkwarriorzz +aflk +afraid2boss +afraid2boss2 +african +aftrthxght +afzi +agent_of_fox +agentdd_4 +agfdbzIM +aggain +agic +agieee +agoraphob1a +agrovation +agsmanpro11 +agytagtyewaq +ah oh uh +ahahah +ahippi3 +ahokusa +ahrlhyrslylh +ai eye q +ai3i42Iaaskl +aiden m8 +aidibohx +air strikes +airborn frog +aito +aitoBeruna +aiwodas +ajiffniff +ak47afghan1 +ak47ags +akaExploit +akaNorman +akae +akbennyboy +akeep +akidnamdjrmy +akipf +akirahokuto +akkha kum +akleb +akq +akspew +aksta +aku aku1212 +al0x +alabasta1 +alabthemoola +alans +alaric +alaxam +albersson +albiguerra +albioon +alchetraz +alders0n +aldi warrior +aldrichmax +aldrichs +alecbeats +aledank +alexjberroc +alexlangman +alexs99s +alfafa20 +alfhershey +algotrader +alias ilias +alic3 +alimpweenus +alipandh +alittlepig +alkaizerx +alkkis +alkkis pk +all en +all love man +all to 200m +all4four20 +allcaps +allebylund +allenbb3 +allez +allluminati +allomax3 +allora76 +allowitplz +allzeras +almoggar +alpacathund1 +alpacka toke +alpalmchal +alpha +alphabosss +already +also +alsobosspros +alt f4 gn +alt maxed +alt rite +alt0n +alt2kil +altairanezio +altehnub +altforusa +altiarblade +alvexn ltu +alvinhic +always win +alwayscurius +alwrighty +am sam +am so sleepy +amagna +amay +amfoine +amheeh +amikiri +ampharos61 +amputated +anasacez21 +ancapistan +anchor +anchor seb +ancientskye +andhetakes +andhim +andmcadams +andreable +andriuttt +andtony +andynew2007 +anelebar +angel995 +angeline1711 +angrydump +aniki chan +anime +anime member +animeF3tish +animegirl73 +anizan +anklez +ankou4smokin +annie +annie r u ok +annni +annull +anoldfatdude +anon1606 +anotha 0ne +another gay +anti +antibully +antituuri +antivaxer +antombomb +anttimage3 +anxiousbeef +any1 +anygirls +anyma +ao +aocha +aod retired +ap1ska +ap3xOo +apacifist789 +apcays +apeman8731 +apenzoon +aperts +aphr0 +apikeppa +apina +apiph3ny +apou +appelkneuz +applee +aqp frog +aqqqqqqqqqqq +aquafx +araenel13 +aratsanus +arcane +archyiop +arcvnaxiii +arcwriter +ard lad 06 +ardazz +ardy guardy +arengs +arevles +arexmeister +arfih +argilah +ari abdul +ari shaffir +ariman22 +arkoudaphile +armadyyyyldo +armyofkids +arnr +arocardo +arookie +arouze +arreydn +arrowbob2 +arrows2ashes +art possible +artaax +artan +arteefact +arth urr +arthadeos +arthurdebart +artist_60 +artizia +artogoes +arvothepure +arzier +ascipulus +ascott1 +asdafsdafsd +asdasdasdf1 +asdsdafsa +asedviss +asfand +ashster25 +asian +asianbunnyx +asibioass +asidb +asm +asmoooo +ason jones +aspiraring1 +asrdftgffdsh +ass chance +ass jiggles +assaultvests +assbergerler +assdrag +asseaterbtw +assoffire +astgferallah +asuhcuh +at0 +atob7 +atoma619 +attaaM +attack2much +auditore28 +audrey +audrey horne +auma +aus j osh +aussieyobbo +aut AT5 +aut1st1c +autism +autisticboiz +autumnbound +av av +av8bgo +avantoeftish +avewy +avg Jake +avg gov ee +avg idiot +avikntos +avmech31 +avocabo +awple +aww fk +axeleebob +axeli +axetoons +axoblaster +axperson808 +ay96 +aydrian +ayeetbix +ayhank +aynull +ayos ayo +ayrball +ayshinx +ayte +ayvz +ayyreynolds +az3r bulbul +azerke +azilim +aziz8mohd +azj +azura +b a g +b a l r a j +b b o x x +b eeg +b enjy +b ezos +b i g s t +b kuz +b l u rr +b oe +b on ass +b oo n +b ooth +b u l +b ulba +b-ray29 +b00ty +b00tyw1zard +b0btehcool +b0dybilder +b0gadu +b0nelesstofu +b0rn2grill +b0urb0n_kid +b1ackcoxdown +b1apoody +b2bpurple +b2bs +b33 rabbit +b39 +b3cc +b3kiy +b3rgo +b4Mb00B0NGG0 +b4iforget +b4nyluckypvm +b5 s4 0000 +bIack +bIrkaoff +bLeatzker +bMat95 +bSteeezy +bVibin +bZabii +ba1tti +baIIs3 +baami +babewatch +babstah +babugo +baby +baby peb +baby peba +babybuffalo +babygirl +bacbacbacbac +baccybaxter +backseatrs +bacodie +bacroonX +bad bee +bad boy602 +bad british +bad data +badalts +badass1337 +badat3tick +badcold611 +badderjari +baddspella +badger fan 7 +badsadmac +badtechnique +bag milk +bagans +baglokale +bahumat +baile +baile y +baitmem8 +baj69 +bajadam +bajj +bak3d bean5 +bakareru +bakesome +bakkerbtw +bakplaat11 +balding +balisongg +balkare +ballenbak +ballerbebbo +balsson +bam +bam-BA-lamb +bambera2 +bamfhitman +bamsi +banana +bantrok +baraho +barakozle +barcrestboy +bard006 +bardj +baritone888 +bark bark +bark f0r 0ff +barkirion rs +barkmeat +baron nash +barou +barry +barrybacon +barrysdad +barryslet +bartelbarel +based +based af +bash the rat +bashong +basic +basically +basiel +basispiloot6 +bassdrum +bassfortexx +basspro76 +bastukid +bat flack di +batchela +batdog183 +bates +batje vier +batseflats +batterym1es +battlebus33 +battleman36 +battried +baumannii +bawky +bawsi +bawz zaa +baywest +bazjunior +bbALL +bbb +bbest +bblood +bbones +bboyalec +bbtarget +bbully +bc22 +bcguppy +bck2kickass +bcollier94 +bdb +bdw reborn +be one +bean flick3r +beanbag173 +beanieton +beanskunk +bear +bear66881 +beard3djesus +beardZy +bearia +bearitimus +bearjack +bearplusiron +beatthebot +beaver 5 +beaver 9 +beaver win +beaverboy47 +beavitte +bec0me +becarius +becca boooo +beckles96 +bedabin247 +bedburn +bedtime +beech +beeelake +beenus42 +beer sweats +beggar +behaardezak +belanin +belgibeer +beliver96 +belizianos +bellatarius +bello0 +belub +bemw +bendy +bengnomonkey +benisbutts69 +benjabii +benjimin +benjiswaggod +benlovesyo +benrj91 +benroxo +bent +benyatta1 +berd007 +berkut87 +berrytrials +berseke1 +berserkbear +berserkku +bertucci2575 +berzerks +besouley +best bojji +betleejuice +betonimuna +betty wu +beverlly +beverwijk +bevh +bevsteve +bff +bfxrturbo +bg s +bgs ownez +bhicks +bhuffs3434 +bibilush +biccc +bicycle666 +bidls +bidof +bieltanman +biffsy +bifket +big bad jon +big bojangle +big gay ig +big gmbino +big head +big man shaq +big rart +big snood +big tree 63 +bigbadheskey +bigbig horse +bigbigbone +bigblade28 +bigbluntbrnr +bigbologna31 +bigboybarlow +bigboybrips +bigboymansir +bigbud +bigchoocher +bigcuff +bigdbandioto +bigdoggtrock +bigdoinks42 +bigg bud +biggest +biggest fan +biggiefries7 +biggledoinkz +biggreenbush +biggs +bigjuicybutt +bigl +biglenz +bigmoney jim +bignipnik +bigonevs +bigotslayer +bigpkz +bigpompom +bigreddogV2 +bigschlong33 +bigsee +bigshrub45 +bigsnail +bigspick +bigsugoi +bigtuner +bigz4p +bike +bike trail +bilbsay +bilet92 +bilfey +bill one +billbosaurus +billsta46 +billy +billy g0at +billy mayne +billy5454 +billyj0e +billyjoewo +bilo xd +bimblebunk +binaev12 +binch +bincho420 +bindi +bingels +binkie +biolemonhaze +biozahard +bipiee +bipoc +biq pp gamer +bir d +birbeon +birdieputt +birkki +bisp +bisse +bitten by +bitter +bitter fruit +bj0rne +bjassen +bjpc +bjuti +bkguytd6 +bl00d twinz +bl00dShaman +bl0wMyPlpe +bl0wdakushh +bl4ckdelt4 +black +black coffee +black cum24 +blackbelt +blackburrito +blackedmarko +blacksshad0w +blackstyl579 +blackzranger +blade2k9 +bladee +blaktraksoot +blame war +blankownz +blarbydoo +blastmaster6 +blawblaw +blazar58 +blaze59 +blazed +blazekin +blazertrail4 +bleenkie +blessn +bleu +bleu kayn +bleubeard +bliksem269 +bliksuiker +blind +blind idiot +blink 1 8 2 +blinkforlife +bliss +blky +bloQQe +blobaman +blockteleing +blonkie45 +bloo37 +blood +bloodhound96 +bloodrain202 +bloodredd +bloodtheatre +blothbather +blowmebuddy +blubbystr699 +blue +blue in vain +blue max6 +blueTofu +blueWagonMan +bluebean2596 +blueberry624 +blueberrydev +bluebop +blueergon059 +bluetrane +bluewahfull +blunt tank +blurite boy4 +blutorch +blvckstvrr +blynaas +bman5 +bmeow +bnff +bnndt +bnqy +bo bby +bo nk +bo2Lawrence +bo3rke +bo4r +bob bob bob +bobby ross +bobby45153 +bobbyb727 +bobbyitsme +bobbyjoe +bobbytronx +bober vvittu +bobfish66 +bobness +bobondowski +bobsushi6396 +boer +bofflepopper +bogie297 +boglad4ket +boident +boinkerton +boke smowls +boksepoeper1 +bollocksed +boltwitdick +boltzy +bombadinski +bombycrahan +bon4ri +bonSwole +bond +bondalorian +bonderoeven +bonelessrice +bonfire +bongohonkers +bonkbonk +bonna1994 +boo0ty +boob boob +boob nut +boodje1993 +boofablebass +book of ra +boom +boomboom +booogieoogie +boooosh +boorito +boosbear +bootn98 +bootylips +bootyters +boratas13 +bored +boring hobby +born +borpxatu +borsi +boss +boss hogs +bossboy420 +bosscat56 +bossdemon88 +bossdog99 +bossedit123 +bossy momma +bostonbb2g +bosway +bota2 +botchx +botilabaca +botleFluff +bottleo +bottn +bottomfeed +bottypedpsw +bounsn +bouquetboy +bouwjaar1990 +bouzouki +bowfa bob +bowfaaddict +bowl +bowl loaded +bownd +boxofbears +boxtrapgod +boycie420 +boydi +boydt +boyuniverse +boz pwr +boze +bozo +bp9 +br0wnardRS +braap poster +bradrian +bragegutten +brain +brain rotted +brainbusterr +branderx gim +brandom lol +bratnt +brawling +brb cigy +bread +breakingood +brecht181 +bree +breeze +brejch +brekitutta +brett +brett 69 +bretthomas3 +brettiz +brettjournal +brettmanx7 +brettrae +brew bar +brewi +brexit +brian285 +brian289 +brianknight7 +briareus +brics +bridder +bridgeport +brika +bring ya ass +brisingr vin +briskyhot +brixs22 +brizzle +brky +bro its hamz +brock soup +broetie +broker +bronson99 +bronzelvl +bronzenohkie +brooskii +brotha in Ra +brotherkjell +brothervoid7 +brown +brownell +brownjesus +brtsbrg +bruh +brushy1 +brutals +bryike +bsavs +bsct +bskiller10 +btc +btd6king +btw Im Nakey +btway +bu bla +buIberpikmin +bubbakush +bubbith +buckethead12 +bucketnipple +buckul +budabaii +buddyswift +budge1 +budhato +buds +buff +buff T O N Y +buff boobies +buff outlaw +bug salesman +bugeye freak +bugsijs +buhm +buldog89 +bulk up +bulpster +bumbler +bumpyD +bumpywalnut8 +bunchface0 +bundun +bungaku +buornos +burakaflocka +burlyman +burnedpotato +burnindank +burnsalinas +burntfish55 +burntjar +burt +buryafriend +bushkada +bussi eater +bussmandrew +busta bunny +butlesha +butt boobies +butt chug +buttercord +buttonbags +buup +buurman111 +buurtvader2 +buwatt +buying ai gf +buying girls +buying sloth +buzzin +bwaby +bwana69man +bxhxdir +bxmbi little +bxther +by Juddy +byEmilsson +byll +byrny +bzerk +c a b l a y +c bro +c greyson +c h u c kles +c hainz +c j t +c m l +c o 1 a +c onorr +c rompt +c ubic +c xx zz c +c-ross93 +c00lbeer +c0vid +c11ntz +c3h8 seller +c95 +c9hype +cBold +cDive +cFraze +cMehuu +cMoney62 +cRunX +cT Kura +ca mel +caaaazaaa +cache +cad5112 +cadeano +caesarsantin +cafedenbas +cagasaurio +cage +cagesitter +caiomhinnn +cajzbi +cakemusclez +cakepillows +cala mity +calamity meg +calgore10 +calisme +call +call me Q +callbackc4ll +calliott14 +callmedaddie +callmeqel +callmeson +callum23394 +calmdown +calmir +calvo +camberland +cameindamail +cameliorate +camellia +camognome +camrbidge +can o fish +can smoker +canadian +canalope +cancer +cancer ruin +canman794 +cannot pvp +cantgetdrops +cantsoloraid +canyon crab +cap byakuya +cap3r +cape kraken +capinkiller1 +cappin +captn_dabbin +car oussel +carbonclock +carefree +carltonking1 +carlwalter +carmito999 +caronita +carrotepic +carrus65 +carti stan +carx +casadri +cash pls +cash19400 +cashcache +cashflowgwap +caspar O8 +casperium +cass +cassa +cassidyz +cast iron 99 +cat goose +cat the rat +cat yo quack +catJAMgif +catdog183 +catdog184 +caterpie +catgirl41 +catlice +catlover68 +catmummy18 +cats +cats go meow +catsandogs +catsarepeopl +catsntatts +cattierjam +cattsts +causey +cave zizil5 +cawn man +caykk +caza +cb0ndy +cbbr +cbf maxing +ccc kyle +ccc kyle BTW +cccccc +cce +ccoinstar +ccvtw +cdryz +ceef +ceerial +ceh9 +celery dog +celestial177 +celliott94 +certifythat +cestlez +ceus +cgmirin +ch oi +ch00s3n +chach47 +chadduker +chadmaro +chadsmurfin +chaffedlips +chakra +chamby +champagnedon +champinjon +champions +champrocks +chamskillz +changa nndmt +changemyrng +chao keng +chaossarim2 +chaoswizzard +chaps on +chargnar +charliety +charlyzard +charred +chat +chatandinan +chats 0ff +chavito_mobi +chazsti +cheapscape +cheddaphile +cheekraider +cheenos +cheese +cheese nuts +cheese tots +cheesed +cheesesmoka +cheesesnake +cheesie odst +cheesy05 +cheetboyx90 +cheetodust +cheffffffa +chemistmike +chemistryphd +chenswok +chent +chenzoh +cherenkov +cherrygrove +chessboxing +chewbacca814 +chewybeaver +chi huahua +chickenarise +chickenbyrd +chickennug74 +chicknsoup3 +chicknugets +chicom +chicom shill +chidavantlez +chie +chie na wei +chien belge +chigas +chilli +chillimayo +chillscape99 +chillummen +chimney15 +chimonas +chinchinchin +chinkbox +chinorondon1 +chipndale +chirspls +chisssa +chlodotexe +chnged +chobby bong +chochise +chodell13 +chogey +chokemepleas +chokemysword +choobocka5 +chook1e +choppers +chopsbwana +chorkin +chr0nic k0 +chris +chriscrossz3 +chrisdude +chriskr9 +chriskys +christimgood +christinet +chronicwax +chuI2ch +chubbybeagle +chubysack +chum god +chumboyee +chunkydaddy +chvi123 +chxpo +ciggen3 +cigonusargas +cimmins +cimsoK +cindur +cinekmiszcz +cinim +circa445 +cityless +civo +cjim +cjrr3 +cjskillet +cjuul +clabby +clac +clancy272 +clangy544 +clara ravens +clardiiii +claryzz +class1k +clayylmao +cleanhell +cleann +cleanscape +clevesbch2 +click +click boss +clickin boss +clickrtraind +clienting +cliff +clifsideGang +clig fish +clini +clippng +clodoaldo23 +clogs please +closeline194 +cloudroamer +clouds +clownViking +clownsrus2 +clownzeta +clrjones964 +clubsammich +cluemaster7 +cmer +cmiite +cmiuehye +cml852 +cmm6364 +coatria +coats +cobrafrost +cobraslyer +coco +coco coconut +cocoa +codga123 +cody curls +coffeechuno +coffeemug91 +coin btw +cojestkuwa +colafanboy +colb 45 +coldumber +coleeeeee +colekay +colemak +collect butt +collessin +colon +colt +coltsfan1287 +coma afk +come +come in bum +commandrsnow +compact cat +concert +conig +connie +connor420sit +connorkwl +connorosrs +containment +content days +continental +contra145 +conww +cookiedunker +cookiekill +cookieman +cookys +cooldude2845 +cooleodotty +coolgasje +coolish funt +coop ananas +coozin_killa +copy166 +cor tapijt +cordnog +core63 +corgi +corgi fan73 +corgsterr +corn +corn8holio7 +cornstarchII +coronel +coronieverus +corps +corpse +corpslave18 +correctmymis +cosec +cosineeee +cosmic +cosmicphetus +coszzyy +council pops +count beck +countjupiter +covid +covidconvict +covidsurvivo +cow abandon +cow cede +cow20 +cowpigj +cowpker4life +cowpoo99 +cowpuncher19 +cows +cox finisher +cox for cash +coxchambers +coxfcksme +coxnass +cp5 +cpenn +cpt-cujo +cr ai g +crZbY +crab +crad le guy +cradleguys +crag slayer +craigbr-1994 +craigobaker +craigs cool +craj +crajan +crannerz +crash +crayfish1 +crazecanuck +crazycow913 +crazyloLer14 +crcsofkrks +creamiboi +crenux1st +crep +crevebach +crew-z +criddd +crimsonlily +cringis khan +crinkes +cripsystrips +cris7ronaldo +crisVao +crisp damage +criticism +critiode +cross +crownchyfled +crppironman +crueship +cruisingmap +crumble +crunchyfrog6 +crunchyrolll +crushsquid +crustymcfk +cruuton +crybcdry +cryme wave +crypto +crystalbluu +crzybrady +cskt +csramsus +cstk1Ng +ctmv +ctq +ctraltdelet +ctsRasta +cu ck +cub1c +cubbear +cubezor99 +cucked +cumstrosity +cunnys +cupma +cupofpeepee +cups +cursed_angeI +curt +cus345 +cuscusrevers +cute +cute lil elf +cutekitten7 +cutemuppit +cutepenguin9 +cutetoeluvr +cutie cat24 +cutie frog +cuvae +cvbj +cvl +cwazi +cxir +cyanicide +cyberdunk +cyberyux +cyi +cynth ia +cyxxa +czaroiemao +czechit +d arb +d e v o u t +d io r +d urrin +d y lan +d00she +d0g eat d0g +d0gz +d0nnie-d0rk0 +d0rq +d0ugjudy +d1sh +d216 +d2n +d3mot10n +d4rkk +dDillyDilly +dEAd0dhz +dEdjamaL +dXLeamXb +da jiin +da ph +da6god +daMteG +daPeanut +dab 710 +dab face +dab marino +dabaig +dabbtheslab +dabilitation +daboiz +daboo420 +dabs n smoke +dabtchel +dad bad +dad tree +dadcoma +daddds +daddy sharky +daddyfred +daddys +daddywaluigi +dadfcker69 +dads bulge +dadsbelt +dadsilou +dadson23 +daedbent +daft plonker +dagens mand +dagg3 +daggry +daghostwoman +dagond0rk1 +dahhyunnee +dahlinho +dahlukeh +dainiux2014 +daisyfletchy +dallas +dallee +dalunk +dalvik +damage222 +damo332 +dan73 +dan_hua +dance +dancol00 +dandy man +danielccm +danielfanacc +dank +dankburgers +dankin606 +danklingt0n +danliciouso +danny4490 +dannytjuhhh +danthebankid +danzing +dapipelaya +daprincess21 +daredevildog +daretodair +darigondeath +darius_v_2 +dark +dark binding +dark hays +dark0hawk +dark5pac3r +darkandrew7 +darkanimal86 +darkclues +darkcyco +darkgirl79 +darkhex0 +darkjustin54 +darklordc +darkmagicdad +darkness +darkstagx +darkxaotik +darkyChao +darranegobli +darranekarhu +darranekives +darth gainz +darthbuddatv +darthv102 +darvan +dascarytaco +dasor012 +dataenz +datakrash +datalogi +datboi2456 +datstonerlal +datweekaz74 +davadof +daveb123 +david442p +davidpain +dawaj +dawningofwar +dawnsend4 +dawocar +day of dog +dayoh +daysack +daystar +daystar 0-0 +daz 11 +dballl +dbau +dbopp +dbow4pking +dbstf94 +dc22000 +dc22000_1509 +dcPain +dcfgs4 +dcing always +dcross9999 +ddSyndrome +dddvlot +ddr +ddsfornubs +de Fe Dad +de em tee +de metro +de00 +deZoet +de_rono +dead +dead tee +dead2Mfarmer +deadazztec +deadcentred +deadfrompvm +deadfrontier +deadlymoth +deadmau5 +deadmeadow +deadskiller7 +deadwildyXD +dear +dear sleeper +dearlola1 +death +death to wdr +death0183 +deathax10 +deathchecks +deathe +deathlifiron +debbie +deci m8 +deciphered +declaw3d +decoy110 +ded R N G +ded pixels +dedarec +dedcell +dedfin +dee2801 +deeezey +deep +deepbowlz +deeptechouse +deesnertz +deetuu +deez ntz +defblacklawl +defender3355 +defenderCX +degie +degraded +degryser +dehula +deivvn +dekane +deketamingo +deku +delboy1964 +delete +delete from +demaguz +demerstrand +demon ssss +den n y +dennyispro +densenuggett +denver +denver nugs +denzarr +departusa +deperni Jr +derdepoging +derrybarry +des9re +deserved pet +desksitter +despotroast +dessverre +desteezdubs +detnia f +detrater mi +detzy detzy +deuce +deuzzz +dev rat +devils +devilz ashes +devious man +devonjt1 +dewsh +dexaur +dexless 4eva +dfkjgkjfdgj +dfordumm1ed +dftba +dg eco +dgndfgjnmfdh +dgro +dgwiD +dharokjonsin +dhe +dhl +di Trevi +diK +diabolicdth +diamanda +dibdabber33 +dibdibdibdib +dickchair +dickenbals +dickfield +dickin +didak +diddy420 +didnt rwt +dids +didugetrekt +dieHosen +dies at zuk +dietc0ke +difjnuee +difluenz +digigrind +digimonOtis +digthat +diguper +dikke +dikke vogel +dikorbut +dilaudid dad +dilbertt +dill +dill picklez +dinklebrah +dinwy +dioshka +dirt box +dirty +dirty rat420 +dirtyman +dirtyydan +disc o +disco sminny +disdudsauf +disease +disrespected +distracktion +diti +diu nay lomo +dive +divibee +dixon butts +dizma +dizzee l0l +dj en sander +dj poolboi +dj roblox +dj1111 +dj_khaaaled +djawns +djerfen +djfistingodx +djhonnyc22 +djk1168 +djm 0813 +djschaum +dkb15 +dkirk +dlaldus +dmersaregay +dmgx +dmh3464 +dmmeguy +dmmskuhled +dmolishall +dmorgzz +dmxbutwhite +dnb demon +dnd5 +do o d +dobiz +doctorbeefus +doctorkrysis +doctorstig +doeby1 +doesnt +dog dog baby +dog rs +dog yum +dog22 +dogGoesMeow +dogluvr42 +dogofrivers +dogongod +doing time +dokus +dom1nation97 +dominicpm008 +domiuxas52 +dommegekke1 +don paro +don3tsc3m +donaldsocool +dong bone +dongiebong +donkeykong2 +donmaners +donnyr2hcim +donohuey +dont +dont eatass +dont relax +dontiane +dontpickme24 +dontsmokemid +donzy +doobie8 +doogleweed +dookie +dooknukem3d +doom +doomcat67 +doominizer +doomsiclepop +doorbel +doors +doot scooter +dop +dopa +dopey smurfy +dopeyaf +doris negra +dorkSine +dormanth +dorschbag10 +doteslintrrc +double99 +doublecross +doublegulps +dox +doyc15 +dp23wnnabe +dpi +dps7 +dr crabman +dr evil +dr smurf +dr3wst3rk +dr4ll1m +drag +drag0n +dragneel132 +drago_jr555 +dragonizer11 +dragtom +draind +drakh +drakonic +dratini213 +draxyboo +drazil7 +drdrinkwater +dreads iron +dreadthefate +dreamworld +dreiph +drewsky +drickvatten +drillbit_10 +drink toilet +dripcuck +drogodon +droidfarmer +droopsnoot +drotRS +drouzeee +drphil10203 +druedainx +drug_yew +drugandbass +drugs +drugsrbad +drunk +drunk f00l +drunkwpants +drwilly92 +drxfluffeeee +dssctn +dstortion +dstroyd +dsvgs +dt duby +dtfmslogan +duMonster +dubba z +dubdubbronco +dubies4days +duckwax +dudash +dude +duder +dudrid BTW +dudylson +duedeman +duel +duets +duette +duff skill +duffman1992 +duhpho +duked +dulitrai +dull needle +dulle00 +dumb +dumbass hick +dumbweeb22 +dumple +dumpy rat +dun2kaz +duncan c +dunerat +dung_eater31 +dunnman +dunt +duo virgin +durche93 +durgs +duriol +durkology +dusp +dusq +duve melker +dvnny +dwarFcaNnOn4 +dwayne +dwvb +dylaaan6 +dyldied +dylodide +dymo +dynastyzero +dyrachyo +dyskletiker +dyssection +dyzi +dzhy +dzmomolungma +e LFa s +e acc +e c e e R +e c stasy +e ji +e med +e pinke +e rui +e031420e +e1ght +e50 +e500 +e621net +eKaleb +eL Lavish +eLSD +eLas +eLeeT +eLqTLN +eM Be +eMiSk AU +eNCH +ePicnicEMan +eSquence +eStimatic +eXtr3Mer btw +eacy +eaekk +eagl393 +eagle shed +easily thero +easterparty +easyMEDIA +eat a udon +eat my bewty +eatcox +eathelwulf +eatmyfries +eatmypie +eatsdonut49 +eazybreazy +eazygps +eazyws +ebbe +ebijah +eboy gamer57 +ecce +echo cooks +eckla +ecofine +eddimunstr +eddyb +edgarsjm +edible +edilot +edmu +edunit +eegor +eek monkey +een pint aub +eenzeven +eerx +eesau +eetbordleeg +eetuliiniBTW +efcherry +efci +effectiiveRS +effing sheet +efog +efren189 +egcept +eggo death +eggu +eggzotic +egirl qt314 +egirl tile +egirl73 +egyptasaurus +egypton +egzoff +ehdion +ehoov92 +eiaraieaieai +eid ola +eiflA +eigh +eilhart +ein Bier +einu miegot +ejobs +ekcivtec +ekhoplex +ekm +el Laneo +el is +el peppo +el tubo +elDiablo666 +elGoblino +elbo +eldanari +elden lawd +elder +elder jam +elder poul +elderimpking +eldestlance +eldrich ball +elefantsrul +elfje185 +elitharion +elkcarc +elkcark +elletwo +elli +ellias +elliott1650 +ellipsism +ello +ellran +elm43 +elmeroguero +elon +eloquent +elsieh +eltomatero12 +elyaxo +email12345 +emaq +emaru +emaw +emiiru +emilviperHIM +emilyqt666 +emiracle +emm +emokid93 +emopapi +emptyhead +emptysoul88 +emuulzzz +emvelienenko +en Au +encoa +endless +endlessgrnd +eneco +enemy2mad269 +enen +energymango +eneslannn +engrave +enjoiskate +enlmatek +enlot +enneUni +enormousguy +enservices +entiesman +envetoids +eocri +eow btw +epcr +epic +epickayle +epicnding +epocsorekiM +eptul +er2002 +eraie +eric verdonc +erik020 +erikj20 +erilthil +erk is cute +erlendolstad +ermer +ermer fudd +ernestoch +ernieK +erniethecat +erpponen +errikkold5 +error +error nope +error occurd +errorwithnam +ersatzquatch +eruze +ervin +erzin +esc +eseeg +esportspker +espress +esssaa +estra jen +eteelS +eternatus +etha +ether-or +etsii naista +eujamaispkei +euonym +euphoria btw +eureka 4 +euxy +ev tesla +evanthenewb +evidencez +evil +evil drudge +evils ault +evirgin +evoL +evol +evonaabi +evoshiva +ew its paul +ewechoose +ewenn +ewgility +ewmu +ewvn +ex0dus +ex_shadow +excalipoodle +excitedz +exila +exile +exodiass +exolyte +exp waste 07 +extesyturtle +extinct +extra +extra big pp +extrastark +extratrippy +eyes fire2 +eygs +eyniss +ezAce +ezzychu +ezzymc +f a r r r +f ainted +f c gee +f d b +f ern +f q +f r o st y +f reS +f0r 20 +f0rbes +f0rev3r +f0rzca +f1elder +f1ll2 +f1oh +f1sh1ngcrazy +f2pkiller420 +f3n1kz +f41r unknown +f4az +f4fight +f8 +fEmshi +fJack +fa1lure +fa2kil +fa43ws5gdrxn +fabsku +faceeee +facehunt +fadc2 +failbloug +fairies ring +faiyaz911 +faka jackson +fake +fakeironman +falcon30040 +fallen +fallenbouse +fallengodxx +falneek +falsehope +familypp22 +famousbutnot +famousdavies +famwell +fan3to +fancybunny84 +fanof +fanook kill +fansh +fapital one +fapyqt +farmerman111 +fart taker +farth4lyf +fartypants64 +farva5001 +fastfoodguy +fastsalmon34 +fat bish0p +fat miso +fat n ugly +fatalzgs +fatalzick92 +fatblimp +fatcactus99 +fatdabz +fatdemon +fatfish44 +fatiimma +fatpapi +fatrat095 +fattig +fatty +fatty_ironmn +fattymcthick +fawaka +fawkin +fawnt +fayeuk +fayfey +fazIlioilol +fbah2 +fcemee +fdegierr +fdsd +fe ar none +fe fi fo ben +fe fleton +fe hessu +fe shredder +fe unclefro +fe-ma-le +feaker +fearma +fearnooaths +fearsome +fech +fed the rat +fedposting +feed water +feet r neat +feet shui +feet tickle +fegorus +feinkostbob +fellman250 +felsic +femaledhide +femboy fever +femiketyson +femra +fems +femtanyl +fenimore133 +fenty +ferbies +ferderb +fergina +ferkyy +fernezi +fernibosh +ferric thane +ferrotopamin +ferrousnub +fettnerd +ffa btw +ffakin roids +ffs cmon +ffun15 +fghtmeirl +fhb ruby +fhisher9 +fi1LMma8Ke7R +fiddy +fieryflame55 +fifiz +figey +figgiolly +fighter8888 +fighttme +fighu +figit +fiiks +fiishcat +fijurgt +fiko +fikset +fill2 +filma kraken +filnrozdor +filthiefrank +fin hupu +final dip +finalkid +finally +finance king +findmydog4 +finerunes7 +finfinnegan +fingerd +finn +fire +fire skull99 +firebrotha2 +firebwan +fireflyman3 +firemadara +firewood149 +firework19 +first +fish cook +fish slut34 +fishbomb83 +fisher ilhan +fishfiinger +fishnforfun +fist +fist n twist +fistaah +fistofzeuz +fitjamal +fixedmanose +fixx ur face +fizoo +fjuc +fk bud +fkMushrooms +fkWiiz +fkn seale +fl0ppy +fl0rals +fl0xen +flabb +flaccid +flacidzillaa +flaggeding +flaminstu +flapdrol2000 +flatbroke +flatjack78 +flatpancakes +flawskee +flax somker +flenis +fleqk +flexmaniac +flexxygreen +fligh4 +flimzzy +flink1145 +flint +flip555 +flipdoggydog +flipouu +flipperkid69 +flke +floch +floie +floopily +florda v2 +florida1992 +flow +flow states +flowerbunz +flowers +flowerworks +flowing past +flpi +fluffy +flunkerr +flwc +flyingfather +flyingpigs +flymouse +flywoodhead +fmPalm +fo77y +fo_of +focusor +foldoutchair +folklore +fondledeez +fonytergus0n +food +foom +foookz +foot fe tish +footbag +footgobble9 +forbiddengol +forcestealer +forevercc +forfun_ED +forgeleader4 +forkheals +formazion +formerly act +fornitesweat +forrestriley +forss1 +fortnitecuum +forty7 +fortyfour44 +fortyfours +fotjonxd +found RS2019 +fourecks +fowrt +foxMcCl0udd +foxair +foxdude909 +foxi melissa +foxmr2 +foxological +foxspirit +foxxit +fp +fp4bank +fpsbowser +fr0stys +fr0zen46 +fractalion +frail +franklinzule +frantam +frawzti +fredz1 +free +free rations +free willy1 +freeheadbutt +freekek +freekface99 +freepknub337 +freeze4peeps +fremenik +freshaf +freshdougie +fressi +friccSailing +friday x +friedz +friendlyduck +frierenfan69 +frodobaggens +frog37 +frogggggggg7 +frogmeme420x +frogposting +froock +frootl00p233 +froppy +frosteazz +frostfire089 +frostkatss +frothsy +froxey +frozen +frqke +fruitdeeps +fryguy20 +frzen +fskencha219 +fsnack +fsteve +fsxd +ftSlimShady +ftmg +fubar +fudkingname +fuhrari +fukduelarena +fuktig +full service +fullrune383 +fun e name +fund issues +funk +funk it +funky +furi xD +fusarium5 +future days +fuwamoco fan +fuzzlumpkin +fuzzydenuts +fuzzypapi +fuzzypupz +fwapdokopjai +fwft09 +fwip +fxck +fxck versace +fxdb +fyfaen +fymcgee +fyr irony +fyromaniac +g arre +g o o w +g u L z +g00dz +g0_ober +g0d slayer19 +g0dofgames +g0dz target +g0ld +g0rgelzak +g1g1tyg0o0 +g1n00tj3 +g1o +g4rug +gIassy +gOWObs +ga zr +gaaaaleth +gabba-jabba +gabbe314 +gadnukB0W +gaffel +gagifidi +gaht +gaht dangit +gainsaid +gainz +gainz no +gainztrain9 +gallidogs +galx37 +game +gamedbroski +gamelsbad +gamer +gamer63738 +gamerb0y +games sheet +gamesalright +gamin hard +gang +gang gastino +ganger34u +gangstersfly +ganjah lord +ganoze +gapin ass +gaping +gargalonmyd +garn woolies +garra +garymunzen +gas watah +gasang +gatekeepr +gatlin +gatorbait61 +gatorclue +gaumcat14 +gavin +gay avenger +gay corn +gb +gd5 +ge1uk +gecs +gege4646 +gegebee +geitz4 +general_a3 +generalneos +genghys +geniuswinner +gentle +geof +georgemonger +gerdlol +gestrikt +get pregnant +getcance +geten30 +getpixelz +getsnipez +getting +geusjj +geve en neme +gewoonhendri +gezzle +gfink +gg Goombas +gggochu +ggremlin +ggroeffus +ggrr +ggwpezgame +gherkins +ghliz +ghost +ghost of CVS +ghostlyjon +ghostmahi +ghrimdrakan +ghxstboy +gianni025 +giannnnni +giant +giantsbane10 +gibsons dog +giffnamepls +giga +giga zooted +gigglybear +gijsro +gilgir +gim Bam +gim ajuin +gim so bad +gimeurgpm8 +gimhunter02 +gimmey bear +gimpeta +gimpinator14 +gimtmbj +gingasnapz +gingerr +ginjembre +gino2315 +gintoki +gioh +girl +girlbossed +girthing +git gud kekw +give +give in +give me 1 gp +giveortake +givmemonyplz +giza +gizmywizz +gkfdhsjbgpas +gl barnie +gl gf i win +gl lmfao +gl0s2n +gladwin97 +glazura +glgl +glica +glingster +glitch1128 +glooboowhoo +glotis420 +glowmastree +glumburger +gmac33 +gmtn +gnak +gnariska +gnarrrkilll +gnobo +gnome pegger +goGETTER87 +goal freak +goat +goated +goatflocker +goblinsyler +gochugaru +godblaster69 +godfreeB +godmiljaar +godmysavior +godofvoid +godsdankweed +godss +godver +going2maxnow +gokhanakan +goku9172 +gokublk409 +golaguard +goldenN0B0DY +goldest cat2 +goldiepawper +gomikasu +gon dor +gonarusinat +gone numb +gonewild +gonsoLE +gonz o +good +good duck 4 +goodboi525 +goodlife +goonette +goontuna +gooootsby +goos fah bah +goose +goosegoose22 +gor7 +goranfr +goreshitfan +gorgewkush +goroka +got u m8 +goth mime +gothic +gothorian +gotmadtree +gotoschool +gottaRash +gotzeeben +goy street +gp294 +gpawshaft02 +gpf93 +gr0ve +grace life +graftosh +gramss +gran chorizo +grandp4 +grandpa +grandpashome +grandslamhit +graphist II +grashuis +grass hopper +gratis +gravetheif +gray ass +greasy bacon +greasyguy19 +great +great bazza +great blazer +great keith +great pkay +greeaf +green +greenbuds1 +greenfleet1 +greenie14 +greenm4444 +greeny4 +greenzyyy +greg +greg btw +grey +grilecheese +grillmagnum +grindin2bond +grinschen +grizzy77 +grlobe +grogybog12 +gronoc +groogns +grossedinde6 +gruelsipper +grumpyy +gt i +gtrpower3 +guardy +gucci +guirkle +gularies +gulibleidiot +gullefjun2 +gulp my knob +gumlord54 +gunbladelh +gungaman3 +gunnmoses +gunnybear +gunzip +gurz +guttsberserk +guuvin +guy123452345 +guyfranklin +guyhasaname +guyladriel +guzzlinbrews +gvfsa +gwaph +gwaphics +gwapo gwapo +gwb +gwen-artemis +gwiffdakid +gwogoudain +gwug +gypzys +gyxl +h ertog +h re +h ugo +h00cares +h0rseZ +h2j +h3hz +h4h4h +h4ndshake +h8browns +h8dip +h9g +hEAdGLiTcH +hOsujaRS +haaksrikko +haam +habitus +hacchi +hackening +hadibaam +hagerlund +haha +haha lul +haha nice xd +hahaLMAOlol +hahaa +hahaa-ukko +hahaha +hahaha LOL +haiiG +hairahcaz +hairy +hairyraccoon +hairytaent +haistavittu9 +hakuikoyori +hakumaata +halal +haldfhaklfa2 +half +halfcrimp +halfrightfox +halftimegod +halling1 +halo +halo 238 +halo is scum +haloumbs +hamdrip +hamers +hamhand +hamilton +hamilton fan +hammade +hammershark +hammu666 +hamptonboys +hamthenoob +hamzullah +han sohee +hanakarjala +handi 0_0 +handi9900 +hangry_bird +hanh +happi hippo +happyprophet +har tig +hard3x +hardcoresque +hardstuck gp +hareby +harelmatlaw1 +haringbata +hark +harleybegum +harmony +harmony w +harrpp +harryderoest +harts0295 +harziol +hasansahl +hasbulla +hash +hassbulla +hat foe +haterz +havfherter +haw yee +hawkesbay +hayati enta +hayden787 +hazel nut +hc pilszen +hc_karadeniz +hcgoldslaye +hcim gud btw +hclirongang +hcmemekiller +hdhd +he a 1O but +he box jonge +he r b +he4 +heGee +hear +heartvessels +heast oida +heatassnugs +heatwave305 +heavygim +heavyiron94 +hebrewmytea +heca +heckn frick +hedonismbot +hee haw 255 +heegeer +heel +heelgoed +heeming +heeyhallozeg +heftZEUS +hehe +hehe heheh +hehehehe +hei954 +heimy22 +heizenberg11 +helgrimm +helicopta12 +hellobob488 +hellofpures +hellohello +hellohelloom +hellper +hellreaper25 +help +helpa +helpusobi1 +hembree +hemmingsson +hemmy +hemran +hemstad +henkka89 +henkleingeld +hennnin +henson23 +henzer +heppytako +her mager +herb +herb btw +herb l0rd +herb l0rd jr +herbdean0981 +herbi +herbibear +here +herezacsko +herkimer +heros +herrasmies68 +hesedona +hesi pullup +hestakuken +heuj speulen +hexergeralt +hexxers +hexzie +hey axel +hey im ben +hey its zul +hey_imgrump +hey_rayray +heywoodya +hh r +hhdrgu +hi im miku +hidde xddd +hiddeboven +hidesonkush +hidlandboys +high +high bonsai +highIMcamila +highelolux +higher man +highfly94 +highprice +highright +highsassy +hightoo99 +highventure +hih +hiiggiinss_5 +hiirihaukka +hikipastori +himokarpaasi +himself99 +hiphopdied +hipocracy +hippofart27 +hippyjump3 +hippytrippin +hirai +hirai momo +his7 +hit trees +hitchclimber +hitsumabushi +hitto +hitz +hiunknown +hiya jase +hizli maymun +hlen +hlua +hlucky +hm08 +hn k +hnge +hnsky +hoangbach456 +hobbit head +hobosloveme +hodl link +hoffnungslos +hol my got +holdadoor +holden21 +holdenrulz6 +holidayRus +hollowking +holonomy +holy +holy chad +holyfizz +holypalo +home2get +homestank +homie jaquan +hompkerbenis +honda +honeywheat +honourpig48 +honscy +hooah89D +hooliganism +hoonyboony +hoosier4life +hootis4 +hopOFFbish +hopeakettu25 +hopeless0ne +horkkaaja18 +horror +horsedik7 +hos +hoswoo +hot otter +hotdogmum99 +hotpants +hotyogapants +how 2 use ge +howliett +hows it garn +howyadurrr +howyodo +hrby +hrsn +hs +hs3 +huang9296 +hub154 +huealldaym8 +huge +huge cog +huge man big +huge ovaries +hugh +hugh_who +hugheberto +hughjazznut +hugjam02 +hulikopteeri +hulikopteri +hulken532 +hulrikon94 +human6000 +humble +humjiboi +hummerspeck +humpmedumpty +hunden +hungrypit +hungwonglow +hunter +hunter01132 +hunter123216 +huntin_pets +huor4hansu +huoranpenska +hurt +hurtswhenip +husbandowo +hush +huskyheaven +hut dugs +huutonaurua +hwow +hxdd +hxzy +hyasf +hycoda +hydra +hydraboss +hymke +hypez +hyphynx +hypofelix10 +hyprmax +hyung +hyvintoimii +hzpascal +i 0nly skill +i Bmx +i C D +i Kelly +i Kyle +i Shin Chan +i Spartan +i Stugbert i +i URNn +i Val +i am hua ren +i am iron xd +i am nickle +i am rocky +i am soo dry +i bets i +i ch i +i dandy +i dcd 4 sets +i disabled +i done +i eat noods +i forte +i gag +i gor +i got dust +i grug +i hit 420z +i i i i +i john 96 +i look great +i lose gp +i need top +i need you +i ok can win +i poop alone +i praise mvp +i preferhead +i r muffin +i r4piid i +i ronman +i vexterr +i-i-istutter +i0 strength +i0am0the0one +i126 +i2eally +i2legit +i2me +i3nd Legends +i420u +i50 +i8 2 l8 +i9 +iAIex +iAM Pleb +iAUSSIE +iAdriaan +iAlch +iAlchedNieve +iAmNotSharky +iAmaWiseAss +iAmen +iAttributes +iB Lifted +iBal +iBallr +iBeDorky +iBeanie93 +iBeast It Up +iBeatNavy +iBeleti +iBelg +iBlack Zeus +iBlake +iBloodsicle +iBlurks +iBosstastic +iBoughtpizza +iBrandon +iBukowski +iBunZoot +iBurkie +iBurn Dro +iBustedaNUT +iCakoRS +iCarna +iCbarr93 +iCh0sen +iChangeling +iCheezedOff +iCheze +iChugBleach +iCiga +iClickYellow +iCmurda +iCoconut +iCrank a lot +iCrash +iCreeme +iCyantist +iD Dazza +iDH +iDabbedOut +iDan +iDanny13oy +iDark Jesus +iDashio +iDashwood +iDeathlok +iDerpo +iDez +iDo RageQuit +iDoNot +iDontWinSad +iDrankCOFFEE +iDrebin +iDrexler +iDrops +iDuiveltje +iElfy +iElysian +iEmery +iEpa +iEprod +iEuph +iEuroVamp +iEvergarden +iFailAgainnn +iFatalFoei +iFerrumMan +iFeud +iFightClouds +iFightGiants +iFire +iFoRGe +iFrads +iFradz +iFrogs +iFry +iFucter +iFukFatChix +iFurb +iGab +iGarns +iGlaceon +iGlitched +iGlowGreen +iGohan +iGotDds +iGotDibs +iGotem +iGreig +iGuDMaFF +iGuessUrNew +iHazelnut +iHenrie +iHenry +iHiyori +iHockey +iHolydude +iHuntie +iHydroxity +iHydroxityv2 +iIimesiahiIi +iJ0HN +iJ4CK +iJCLEE X +iJake +iJamPancake +iJesslag +iJezuss +iJfr +iJohn +iJomm +iJwu +iKHole +iKILLN +iKantu +iKarl1s +iKerry +iKitch +iKitz +iKonijn +iKoning +iKozak +iKristov +iKurko +iKushUp +iLEFTmyGF4RS +iLL Sushi +iLeftHer4XP +iLegacyX20 +iLetaker +iLeveled +iLikeTacos +iLikeTheStok +iLikeuAlatte +iLoner +iLove +iLoveYou3OOO +iLuckout +iLuv Pandas +iLuvMyMilf +iLuvSubs +iM3RKEDu +iMADbro +iMahjarrat +iManiac +iMark 1 +iMarkl +iMartin11 +iMatey +iMeeger +iMellek +iMelli +iMementoMori +iMeo +iMichaelN +iMikail +iMikey +iMogUCope +iMotown +iMushh +iMuste +iMx +iN3K0 +iNamaste +iNeedBeaver +iNeverMor3 +iNewbcake +iNewton +iNibble Bats +iNz +iOPeveryday +iOhmz +iOsmumten +iOwl +iOwnU4ss +iP1 +iPIMP +iPKedEpstein +iPacmanSam +iPaki +iPalumor +iPatrickN +iPegAsians +iPerfectoX +iPete +iPhone +iPink +iPlugg +iPod +iPop +iPray_Guthix +iPresident +iPunchCones +iPure +iPvM_Soul +iPvmForBank +iPyj +iQuestas +iQuiet +iQuittedCiao +iRNGizzed +iRekt +iRepToronto +iReue +iRev Man +iRezlo +iRoN cUj0 +iRoNmAnSdUmB +iRonAllot +iRunTh3World +iRunzo +iRycoda +iSaran +iScape +iScaped +iScooby +iScream03 +iScrewedUp +iShibby +iSkane +iSkript +iSlay Girls +iSlayCookies +iSlayGoat +iSlenderMann +iSmashUrGF +iSniffCows +iSnowmobile +iSoulReap +iSpare +iStayLowKey +iStealSex +iSteele +iStick2Corp +iStonee +iStream +iStreetfight +iSuhdle +iSwarly +iSweat +iSweatyYeti +iT0m +iTan +iTaz +iTed2cold +iTheDarkKing +iTheodore +iThiellie +iTisk +iTmetzo +iToxic +iTrin +iTunder +iTw1sted +iTyler +iTz Command +iTz Frosty +iTzBoo420 +iTzGoinInDry +iTzKATalyzt +iTzSnypah +iTzTurtlexD +iTzTyLeRXD +iTzWho +iTzZ +iTzxLiMiiTz +iTzzVanquish +iUberz +iUsed2Corp +iUub +iWilkel +iWillz +iWithdrawal +iWonderWhy +iWyatt +iYahwehi +iYellowClick +iYunis +iZ4 +iZorru +iZuny +i_murder_bh +iafx +iain19 +iamAFK +iamCanadian +iamMcLovin +iamfish +iamfried247 +iamfuss0100 +iamgreatrng +iamlucas19 +iamonfiyaaaa +iamperkins +iamvery cool +iamvoldemort +iamzed +iandrehehexD +iateyourpie +ibbenbueren +ibn Mukhtar +iboomedyou +iboyfly +ibr4him +iburythebone +ibushmani +ic3d +ic3d c0ffee +icannotboss +icanread321 +icantspelle +ice beam +ice juice +ice-nine9 +icearrow28 +icebolt19987 +iceburg189 +icecoldbreez +iced +iced marbles +iceman000 +icewall0w +ichau +icjbi +icky sticky +icutL0g5 +icy ded ppl +icyT +icydilldos +icypolarbear +id c +idc +idcy +idfap +ididnthither +idiedonmyhc +idiom +idiot +idiot game +idiothead +idk chill +idkgoogleit +idkh0wtoplay +idkwhatdo +idle +idle1 +idpoen +idrater +iduggz10 +iekaajer +iekgaa +ienai +ifantomas6 +ifarted42000 +ifootfondle +ight +igiddeni +iglo16 +igotdaice +igotnolifee +igotnoolife +igotwingz +igotyour99s +igrimmerz +igugh +ih8urkind +ihan +ihaveanxiety +ihavitunopee +iheartBBLs +ihopeurope +ii Sahir ii +ii am teaser +ii bad guy +ii forte ii +ii love cats +iiBink +iiDivine +iiDrackidii +iiGallardoo +iiHydra +iiLuckyVibes +iiTz Nothing +iiZEEii +iiZno +ii_TrYHaRd +iiaannaa +iiiRood +iijelloo +iikasoyi +iimperious +iinsin +iioktb +iirc +iitsjarod +iitz deebz +iitzz Ryan +iivy11 +iizoneout +ijoinedthis +ijust +ijustgotreal +ijzer ali +ijzer vreter +ijzeren +ijzerenman1 +ik itachi ik +ikea +ikeep1r0lled +ikil +ikillstuff +ikiroz +ikoyouboy +ikp0wnsz +ikpakjou +ikrr +iksalion +iksd +iksdeee +il malocchio +ila161 +ilapaR +ileax +ileft +ilegalTruble +ileppmot +ilfi +ilike2gamble +ililliiilli +iljang +ill Dottore +ill-Money +illadelph +illenials +illisible +illmaister +illmatic +illmindhop5 +illotex +illumea +illuminavi +illyreia +illysia +ilookcat +ilovecitywok +iloveinsulin +ilswisa +iluvducks +ily stepmom +ilyakchuk +im 1v9 +im Jaacob +im Noah +im Z a n e +im a learner +im a pur8 +im at cox +im bad tbh +im batu kham +im cats +im dandy +im huge +im in charge +im nlf +im pogging +im ruben +im solo rose +im tr4vis +im ttZ +im4everxerox +imAcidic +imAhri +imAlexRyan +imBetter123 +imCodehh +imJT +imNEWY +imPapu +imStef +imWebby +im_pro_jones +ima big boy +ima survivor +imafatscaper +imago loop +imaybegod +imbaconyum +imbueddog212 +imbutz +imbuyingf +imcahos +imcaprise +imdrunkashit +imdud +imfi +imflavio +imho +imhuge +iminarager +imjeremy +immachin +immaturely +immef +immirgant +immmersion +immortalz +imnotdani +impaired +impartial +impek +imteddybear +imthenalls +imtogepi +imusualyhigh +imzahikell +in africa +inSec +inTheSlum +inb4elysian +inc +incant +incci +inclibe +includingtea +ind +indebara +indian +inescate +inf nick +infamousO775 +infamousjew +infare +infernalwhen +infessian +infragant +initiator +iniu +inject +injinourme +inked +inldgwetrust +innSink +inner child +insaned17 +instagation +intja +intwystis +invictecum +invirtua +invisybl +invynsable +inwervs +inwnucleus +inxx +ioe +iojerfwpjiof +ioliteKnight +iolm +ioncolliderz +ionlypickadc +ionman +iorcsrox +iownw69 +ipfreely939 +ipwnkthxbai +ir0nschlong +irak93 +ireq +irhunter +iriee NZ +iron +iron Dreven +iron Fapkin +iron Nido +iron bewts +iron carly65 +iron chur g +iron colb +iron cuzibro +iron d +iron dafanek +iron dumle +iron evoo +iron gariks +iron grogu +iron hobbs +iron i jad i +iron imp 89 +iron kobe +iron kydrol +iron mazie +iron nakno +iron nkellen +iron sfgiant +iron snak3s +iron snurd +iron t2 +iron te_un +iron to main +iron tylerr1 +iron veil902 +iron veyydot +iron vow +iron xarcher +iron0 +iron0_o +ironBellukka +iron_day54 +ironandwhine +ironarrow +ironbandiit +ironbass +ironclimber1 +irond +ironderp +irondude686 +ironerextion +ironerrosann +ironeye +ironfara +ironfather8 +ironfyi +irongaga +ironguxiz +ironhuuu +ironic it is +ironikcronik +ironinfinite +ironjssnoob +ironjustice +ironjutku +ironkendall +ironkevkev +ironlizrdfuk +ironlog215 +ironlooks +ironly fans +ironmortel85 +ironoujust +ironpower29 +ironpuni +ironskunkki +ironspig +irontsuki +ironvesku +ironwortel +ironwoss +irradiated +irregularly +iruste +is an option +is skimpin +isCatrileo +isayswegyolo +isleepwith3s +islugo +isoPROpain +istealyoloot +isuwu +it do be +it ends now +it0b +it0keup +itachi9113 +itbch +itirof +itisdre +itmeautim +itroy v2 +its Bread +its DeFib +its Hoffman +its Knetter +its Mewtwo +its Polle +its a ginger +its aight +its an 8th +its leviosaa +its not mine +its the game +its20after4 +itsAden +itsErnie +itsGLD +itsJayy +itsNoki +itsSt1cky +itsWum +itsa +itsa_feature +itsaart +itsalic +itsbenny +itsbill +itsdanlol +itself +itsfwhobar +itsmewarreng +itspajamaday +itsthedirtyJ +itwasme +ityttmom +itz Ozie +itz Tastey +itzjaycie +iua +iusedtosleep +ivao +ivibondivi +ivlr +iw +iwearIRONirl +iwinulosety +ix7 +ixGOONIExi +ixJake +ixoniron +iyyghg +izmibence +j e company +j o h n z +j o l s +j sta1in +j uddr +j wet +j0rd +j0rdb98 +j0shNZ +j0shwah +j1nx +j311yb311y97 +j3ffmaill3 +j3rvi5 +jDaledge +j_mes +jaakqoo +jaatzy +jackBingus +jackLonghorn +jackancoke7 +jackjester +jacksonlol +jacola +jae Bee +jaguarundi +jagweed +jagweedle +jahan +jahmelo +jahnjo +jahrezeiten +jaitt075 +jajademonrat +jajajad +jake92 +jake9549 +jakeyvil +jakkaru +jakste r +jaksterlite +jakuusa24 +jallon +jalucox +jamaz8 +james1234269 +james68889 +james9f +jamesishere +jamesw +jamflex +jamgyo +jamie g 456 +jamjarrrs +jamm +janguy +jani +jankywanky +jano +jaq0 +jargonship +jarjoevis +jarngrimre +jarno561 +jarnrisi +jarnwoodchck +jarsko +jaseDemon +jaseGrumpy +jauu +jaxta +jay 6ird +jay oh kay +jayst1n +jayveedee +jaza +jaza maxwell +jbirrd +jd345 +jdockett +jdore +jdsgsxrthou +jeREEEEEmy +jedi +jeeeeee +jeep +jeezuschrxst +jef skhiii +jeff +jeffswifty +jegerklog +jehhjr +jekkujaba +jellyfish49 +jellyjam20 +jem is cool +jerome +jerrys ags +jerrys venny +jerzieboy18 +jesjesjo +jesus bone +jesus vape +jesus4gives +jesusiswrong +jesust +jetalexnder +jettyrr +jewellski +jewjoking +jfan +jfc +jfrank127 +jfy +jfyulopaef +jheezuz +jhinnessy +jhonlee48 +jhoog +ji mbo +jibmask +jicc +jigx +jihal2020 +jikrak +jiksee +jim jones it +jimbob1 +jimbobeda +jimdeut06 +jimmy +jinjji +jippey +jjammerweer +jjerrbo +jjingx +jjpanther95 +jkfizzy +jkre +jkthekilla +jman +jmjmjt01 +jmusilli11 +jmw1031 +jndi +jnjo +jnlffs +jnyjny +jobljobl123 +jochieboy6 +jodilynne +jodo wollos +joe the pop4 +joepie +joestrider2 +joey0343 +joeyisstoned +johhny2hatz +johndalton95 +johnnyandtam +johnsmain +johnstaLoL +joje9 +joji +jojojo357 +jokaranpampu +jokemyster +jokerpoker +jokkefar +jokr +jolle rmm +jon ko +jonehehe +jones +jonk33n +jonko +jonnetuinen1 +jonnywormy99 +jonppeli +jonwillbert +jonyants +jonzii90 +joohhhnnn +joop59 +jordaaaan +jordlar +jords +jordy8878 +jordymans +jorfee +jorge w +jorma heat +jortdebonobo +josheroni +joshuab98 +joshy872 +joshykun uwu +jossejoks123 +jossiee9 +joster +jouv +jovic +joygi +jozn +jp s +jpjpj +jpmonkeyboy +jpruee +jqzz +jre257 +jrwheelyy +jslashk +jsoaksdawg +jstrot +jta1992 +ju1ce +juaco torta +juan09gon +jubbediah +juggernaught +jugiwow +juice +juicy jones +juicyj03 +juicyjoystic +juju +juke +juketsauli13 +juks +julia uwu +jullbrew +jumpe +jumpshot7 +junami14 +jungle +jupi234 +jupilersjuk +jupl234 +jusiuke +just +just living +just2own +justJust +justLush +just_willie +justamemerr +justaname20 +justapethunt +justarabbit +justin5454 +justinttu +justluxy +justsomenoob +justsomewood +justwin4head +justwitching +jutku22 +jutmeister +juwgrehg8w30 +jwalty +jwheaties900 +jwles +jwov +jxdoo +jye2014 +jynzziii +jyripetteri +jyyhnas +jzhua +jzm0 +k a p s +k anao +k e y e r +k ep +k ian +k oga +k u h +k um man +k-rock94 +k0ed y0oh +k0mpact +k0nch +k0nna +k0rrup7i0n +k1dnam3dcud1 +k1lla +k1lla cam +k1ngzinho +k3yblade +k6k3 +k80may +k9k9k9k9k9k +kFlipsta +kMikey +kUwUmiko +ka r el +ka vi +ka wa +kaaf +kaali +kaalwo +kaaskrok3t +kab000m123 +kabal1995 +kacy +kaffetime +kahleparta +kahvi +kahzaohimark +kaii tangata +kaimann +kaiokenz +kaizen1 +kajyboyyy +kak_kis +kakes +kako666 +kako666 ii +kaksaking +kalacaodan +kalev +kalijaveikko +kaljunaama +kaloopsia +kalusto123 +kalxb +kamekazi +kamerucito +kamika +kammoooooon +kanchazi +kandids +kanga roe +kangaroo +kannv +kanyefan22 +kapot +kappachino +kappaross420 +karambamb +karelzzzz +karibola +karil +karilol +karma dies +kaspery0 +kasperyo1 +kasrug +kassi +kastekann007 +katelate +katiegore +katinnekke +kavachi +kavinskie +kawasakki +kawi +kawkky +kawnoz +kaynori +kayxiv +kbest777 +kbuns +kc3 +kc3477 +kcaaJ +kcmeatlover +kdani +kdawg710 +kdog420 +kdw27 +ke-bun +keatonboss +keegan789 +keekluulz +keep +keep going33 +keepitdedpls +keesie7 +keezuth +kehd +keilaaa +keiniks +keittokinkku +keittoo +keiwa +kejo +kekipua +kekw9001 +kela +kela fan +kelan +kelan miehii +kellapea +kemabi +kembot +kemosabi +kempster8 +kenchuuuu +kendawwwg +kennynoodles +kenya help +kepijuku +keppuli +kepwontmax +kerekewere +kerm jump +kerwin +keskorian567 +ket boof +ketaccino +ketawuss +ketchupfles +kevin +kevinator41 +kevinnnggg +kevpurp +kevvaGG +keyggre +kferd +khaki cuffs +khxn +kiba420 +kibeleza +kibsy +kica7 +kickback +kiddoseta +kids +kidsteve18 +kidz +kiefcheef +kiiiiiiiiid +kiix +kil lu a +kill +kill3r +killah +killakristy +killanoob93 +killconey84 +killcrab +killd0zer666 +killedual0t +killerline +killnack +killthatree +killwi5e +killy +kilpi +kimachevich +kimbo +kimpsa +kinako4 +kind +kinda soft +kindaanxious +kindocool +king +king lee166 +king stuff1 +king-tiddus +king420smokn +kingblackops +kingcuzh +kingdaddyIM +kingdale26 +kingerr +kinghrvatska +kingknightf3 +kingkong1211 +kingofmanse +kingprince +kingrizzla2 +kingsardine9 +kingsje +kingswood +kingvoid1083 +kinky fish +kinobi +kinzyyy +kipitril +kirby421blzt +kire7693 +kireeh +kiri2kun +kirkaye +kirky 127 +kisipicka +kisses +kissmyassetz +kitashan +kitkats GIM +kittymeow556 +kivipaska +kiwidson +kiwie +kiwiibear +kjekken +kjellingeee +kjeltringen +kjems +kk lol +kkDV +kkangaroo +kkarl +kkjamin +kkman45 +kl00g +klaaore +klacen +klampo +klankerclean +klassiskt +klef +kleshkebem +kleu +klexosfox +kleyver22 +kliefhead +kll4mee9 +kloh510 +klojo103 +klojo105 +klopt +kluizen +klycko +kms fast lol +kn0ws beers +knani +kneel2me +kneeslapperr +knickname +knifemanha +knight +knightnate8 +knobb +knobby +knokro +knotts +knox +kodakid98 +kofelad +kojak1211 +kokimon +kokinaattori +kolb +komari_k +konar simp +konb +konch99 +koning broer +kontiainen +kony +koo de gras +kooks only +kooltrickz +koronaaaa +kosiq +koudekroket +kounga +koyhalaulaa +kozel +kozina +kozzuu +kpt +krZ +krab meat +krad +krakenwsn +krakim +krakkakkak +krakodile +krat +krazyfaken +krb 16 +kreepingdeth +kreeq +kreesie +krewl +krikenator +krillzscape +krioyo +kripu +krisaaferfi +krnjellytv +krobi +kronicganj +kronopes +kroodjebaass +krp +kruizin +kruuuuben +krxW +kryptocookie +ksdnklowdss +ksiadz +ksko +ksubbi +ktsmo +kudryavtseva +kugelencas +kujan2 +kukerino +kukko soosi +kukrishikari +kulers +kulers bsk +kulju +kulso +kulwreck +kumiko okada +kurasaki21 +kurdikana +kuro 275 +kuromi irl +kursa sucks +kurtebener +kush +kush tacos +kushmas +kusib +kusimursu24 +kuvaiti +kuwait333 +kveemanne +kwak +kwak eend +kwall +kwarkje +kwdn +kwinus +kwuantadyme +kxde +kxlle +kxzu +kyaa +kyanochaites +kybl +kyfu +kyle of pvm +kylehwog +kyles +kylop +kyssysmeua +kyurem_vrah +kyykanhenki +l Am Mathew +l Athena l +l BTW Envy l +l Buzzsaw l +l Click l +l Darken l +l EARN MAN +l Elija +l Fam l +l Feather l +l Floss Fish +l Flynn +l Freya le +l Hav Ligma +l Kelpie l +l Killua l +l Lena +l Love You +l Macca l +l Misfit l +l Mister l +l Nz l +l RSK l +l RWT l +l Snus l +l Steph l +l Succubus l +l Sw0rdm3n l +l Viz l +l am RON +l am cute +l cup +l failex +l lemon +l u g i a +l unchbo x +l-LEVY-l +l-Relinquish +l-l-L_l-lL_l +l0H3aV3nLy0l +l0ne0ne +l0rellai +l21 +l23 +l33tsuperh4x +l3LACK +l3W0FPI +l3en +l3enjie +l3ezzerk +l3ishop +l4n +l5h +l7ivine +l8tenite +l995 +lA R R O Wl +lAlexAnderl +lAnomaIy +lBaecob +lBakin +lBrent +lCEBERGSLIM +lCONlC +lD an +lDFC +lDalel +lDanilo +lDark +lDark ice +lDerby +lDezzy +lDokkum +lE N VY +lGuess +lHawke +lHong Kongl +lI pv M l +lIHlIIlHIllI +lIIIlIlIIII +lIIlllllIlll +lJWl +lJoynerl +lKanel +lKeith +lKenna +lKenny +lKlas +lKyle +lLY Harambe +lLewis +lLupo +lM Nathan +lMarkl +lMercyl +lMr Zaros +lNSF +lNTOXlCATlNG +lNerdRage +lNolan +lPaleHorsel +lParticle +lPeriphery +lPoe +lR0NM4N +lREKEEN +lReece +lRossy +lRyan +lSaiyanl +lSellFeetPix +lSkinny +lSlayer +lTS ON SIGHT +lTedl +lTextbookl +lTlTITlTlTIT +lVIaGiK +lVictorl +lVitor +lVlango +lYungPlaguel +l_Thunder_l +l_wyverns_l +la flare +lacefield07 +lactosebad +ladsquiron +lady-yoshi78 +ladyspartin +lafreniere13 +lagamuffin +laggium +lakde99 +lakey peak +lakeypooh +laks +lala u death +lamJason +lambar +lambreturns +lame +lamepun3than +lamironben +lamshnarf +lamyourdeath +lanch +lanthe +lapyflapy +laqsative +lardosio +large +large moist +large nob +large pox +largewillow9 +larinen +larl +larsbeuk99 +larsnjun +larvacorium +lash209 +lasseboi +last +last katana +lastdcplz +lasyy +later gater +latinamx +laughingbisc +laura +laura froggy +lawkingkong +lawo1 +laxasia +lazarus +lazy aiz +lazydj2 +lazyhitman +lazzabazza11 +lcefiend +lckle +ldy +le iromax +leafsevens +leak organs +learncox123 +least toxic +leather74 +lebanon d0n +lebusoft +ledy0710 +leech +leech iron +leech keeper +leechyGP +leehi +leesha locks +leetjojo +leevi22 +leewhiffy +leewi +leggie +legioen +legionbgbear +leglizeRanch +legn-dary +legohuis99 +leipo +leivonnainen +lejhobs +lejhonni +lekkergras +leld +leliwuz1837 +lellikedraak +lemeborrowgp +lemm y +lemon +lemon 25 +lemon cookie +lenda +lengf +leo vzla +leos main +leoshnoire +lepetitpois +lepicklenick +lepo +lerpledore +lesel +letos111 +lettam +lettername +level-103 +level-125 +level-596 +levendi +levon +lewcifer8118 +lewdogg +lexi +lexi bell3 +lexicon7 +lguana +lhommerun +liamde +libad5343 +libertador +liberteeeee +licdik21 +lick +lick my chad +life is shit +lifesalaugh +lifter +light +light year +lightfader96 +lightningess +ligma +ligma2 +ligmadich +lihaamm +lihavadino69 +liisa +liisankissa +lijkenpikker +like cooking +lil Mamacita +lil b +lil bumpp +lil chris 15 +lil ducky69 +lil gay cat +lil jev +lil mage013 +lil zeze +lil zuck +lilBula +lilJacklil +lilNoob2341 +lilbitlifted +lilchiken +lilcjay11 +lilcuff +lilgreasy +lilkcough +lill misfit +lillelar92 +lilliilillil +lilmasterOG +lilmuscles +lilseveron +lilsquiddy +liltunechi +lily0v0 +lima +limona5 +lindyman +line +linebacker +linkhg100 +linlithgow +lintydeer +linusforsman +lionking-PVM +lip length +liquidchese +lirska +lisher100 +listentonano +litger +litheum +litranmaito +littering an +little boat +little man 9 +littlebumble +littleman699 +littlemc14 +liubei4444 +livdumb +livil +liz_mar70 +ljjjt +ljzerenmes +lkalgo +lkaoz +lkeaurhteakl +lkigai +lkjhsdfglkjh +lkkle +ll Grey ll +ll Zeke ll +ll jacob ll +llBear +llIIIlIIIlII +llIIllIIll +llKaren +llKris +llNephilim +llRevenantll +llStevell +llab +llaurune +llerb +lletya sugma +lleygo +llhan +lliigmanuts +llitl +lllIlIlIll +lllPeppalll +lllnifflll +lllogical +lllustrious +llo yd +lloytronn +lluH +lm Drunk69 +lm H o T +lm Jard +lm Scoob +lm Stark +lm Washed +lm batman +lm scrub +lm2fas4u +lmAddicted +lmBarryAllen +lmTrash +lmao +lmaonation +lmfao ffs +lmgur +lmmorral +lmmortall +lmpart +lmpatiences +lmperishable +lmplication +lmplode +lmpostar +lmposter +lnSpectre +lnYourDreams +lnc +lncendie +lncest Steve +lncestralTop +lncline +lncredibilis +lndain +lndecisive +lndika +lnfa +lnfernal +lnfiltrate +lnfinitesoul +lnformed +lnitial +lnitialed +lnkd +lnquisitor +lnsanewolfy +lnsec +lnsertname +lnspect +lnspiration +lnv +lnvictxs +lnya +lo0o0lo0o0l +loadedhuggie +loadingman +loasted +lobi +lobssss +lobster pot4 +lobswordie +local +lockluster +lococonut92 +lococsgo +locustchrist +lofi cow +log item +logMs +logger2222 +loggiee +logic +login down +loginxtor +loisakurvi +lokdead +lolaskiller +lolbert +loldatfunny +lolekx6969x +lolerrofl +loli +loliconflict +loliron2main +loller63 +lollydeepthr +lolnicebank +loloharqia +lolol +lolw +lolwhoplays1 +lolxdmeme +lolzzii +lone +lonely +lonely rider +lonelybutter +lonewolf200s +lonewolf99s +long +long hcaeb +longbodd +longlabia +lonko +look1nAzz +look2thepast +look4clues +looking ass +loopyloos +loose +loota-criss +lootshark +loox +lopiwer +lopldopl +loraxkiller +lord +lord bimby +lord boozer +lordlazzy +lordrandomZE +lordrunekeys +lordsamzju +lordzyzzbrah +lore2 +lory +losbandito +losee1 +losing +lost +lost to time +lostchuck +lostingame +lostpanda21 +lostwithiel +lotion on my +loucks +loueyyy +louisa +loumit +louw +love +love bees +love haaze +loveNfungus +loveT0spooge +loveablepand +lovebeastx +lovebite +lovegoroe +loveh8hero +loves a beug +loves moms +loveyoub1tc8 +lovezz2pwn +low lQ gamer +lower caste +lowlyworm +lowrandom +lowstat +lowwpower +lpman +lreful +lrin +lron +lron Bladder +lron Fill +lron Kev +lron Mar +lron Mennis +lron Paladin +lron PvM +lron Taint +lron Tom +lron patriot +lronBud +lronConquer +lronman +lronmanBtw +lronmanCraig +lronnan +ls32o0 +lsdx +lssabella +ltachi +ltachi_01 +ltaychi +ltsJor +ltsJustified +ltsMiller +ltsYaBoi +ltsYourBoi +ltsuki +lu is +lu1gi00 +luc1d dream +lucaniste +lucid +lucid olm +lucifer290 +luck wheelie +luckeG +luckey7744 +lucknesshcim +lucky +lucky female +lucky never +luckyweeb13 +luckyy vii +lucuh +lucyramon +ludaftpitbul +lufteohl +luierick +luis +lukas +lukas2518 +luke the npc +lukehm8o +lukek22 +lukem0n +lukewarmrod +lukey +lukey pookey +lukis159 +lukutty +lulllopiet +lulu +lummby fam +lummywk17 +lunamelina +lunar frost +lunch roll +lunchbox +lung +luolapeikko +luthas +luut +luv da grind +luwl +luxyy +lv ie +lvan +lvarLothbrok +lvl 1 sleep +lvl3 +lvon +lwesche +lweyffaM +lxli +lymitz +lynx zan +lynxix13 +lysander640 +lyzolda +lzrdlvr1 +m 62 +m e e p y +m i d s +m i n i m +m i t s u +m inimum +m miq +m nice guy +m x e +m-moi +m00fen +m00fin +m00nrock +m0ker +m0mentum +m0saic +m0stert +m1ssing +m1xos +m3g4m4n +m3nd3nhall +m3rkzz +m3tku +m4ge4life4 +m4gi +m4n +m4ttay +m5q +m6ngel112 +m8tio +m8zi +mBucket +mGu +ma shnibbla +ma61187 +ma7shee +maadar sag +maahhtt +maawee +mabeltwinkle +mac_moneyy +macflag +macgleeznorg +machurrohard +macjonge +mackbhamRS +macke064 +maclean93 +mad bor +mad dogs son +mad hjorn +mad4cashh +madara666 +madeustilde +madgamer45 +madhat86 +madironman45 +madman456789 +madmat38 +madnijz +madpaul1 +madwebbie +mady I green +madzey +maeonia +mafiaz +mafiz +mafur +magerageftw7 +magesticx +maggpagg +magic +magic me92 +magicarp420 +magick pp +magicmike117 +magiskt het +magnacarta +magnum0008 +magnumdong94 +magyarok3 +mah nickel +mahamoho1 +maiden +mainCallum +mainyMCmain +maiy +makarena +makemon +makenator +makkan69 +makosoup +maksavelat +malfoy +malkin98 +malmstrom +malte313 +mamadou11 +mamatriceps +man spreader +manaakitanga +manameisjeff +mangkj +mango +mangocry +mangoszn +manmeowmagic +mansbridge +mantequille +manwhofish +manxster +manyfac3god +mao +maon +maori +maplegamer6 +mapletits +maqr +marbelo +marchdog +marcinrulz +marcmaralou +marcwins123 +marioflame +marioswe7 +mark uk +marketmoney +markobae +markypoo +marmO0n +marmalarm +marr66 +marrab +marrciee +marrrcoman +marshyymarsh +marth2king +martickle +marvypoo +mas koff +masdebator +masonkillem +masta132 +mastafarmer +master +master9782 +master_box +masterloveme +mastermisch +masterpi314 +masterseppi +masteryi01 +matata23 +matiks +matis6080 +matiteusz +mats +mats643 +matsxe +matt182xx +matteuce W +matthew6500 +matthoot88 +mattrabbit +mattv +matzRRR +matzkia1 +mauberries +maulnak +maupz +mauriveitaas +mausre +mav daddy +mavrooo +max acc btw +max all max +max pet hunt +max yet jake +maxcapealt7 +maxed +maxed nelis +maxedtheaxe +maxgt96 +maxiicano +maxiwiz +maxiyogi +maxplayer +maxrevenue +may him +may lay +may thai +maybe +maybejarrod +mayhemrs +mazzahS +mb +mcbig12 +mcbreeeeee +mcdonald +mcgigity +mcmadpac +mcnuggetcons +mcrane1202 +mcsoftee +mdawg +me disabled +me espresso +me handicap +me ineffable +me no bueno +meOwNYXx +meat jun +meatball47 +mebigbob +mechmillz +medicmain +medictbh +medium cloos +medium unit +meds bad +meekmook +meemimestari +meepify +meerks +meermaijer +meetoihi22 +mega +megabass +megajoeck +megatricks +megoodpvmer +megret +megxolotl +mehloncoly +mehmuss +mehunder +mei +meinen +melangina +melborn44 +meldrahn +meleonlyslay +mellaa98 +mellagro +mellonman +mellow jack +melncholy +melog +melog dog +melvin quit +memephis +menaceirl +menarehot69 +mendier btw +mentasltu +meow for gp +meow for raf +meowthc +meowtism +merryrice +meskil +metblo +meth0d +methcathione +method888 +mettleman149 +meurtpo +mewby +mezins +mf Catleesi +mf Giggle +mf neeko +mf yappin +mfHank +mfHank Hill +mferJones +mg +mhe00 +miTzy +mia celtic7 +miaka yuki +mianbaoroll +miceworkteam +michaelma4 +micheal +michixranged +microham 69 +microwave62 +mid clicker +midget man +midzy +mie19 +mielas +migboincan +migidi +migilicuty +mihalys +mikbea +mike 6 +mike2290 +mikefizzled +mikeohtran +mikh +mikko2112 +mikkoyy +miko +mikomiko +miksuwu +miku qwq +milahreigne +mild farm +mildMuscaria +milfnmybed +milkpatty +milkthegoat +milkuwu +milkybestdog +million sof +miltryguy248 +mims2dank4me +minato +minatokill +mind goblin +mindislost +mini booty +mini r00d +mini rocklee +miningas +mininimum +minit +minky +minmax +minni mile +minor flex +minorhazzard +minsy +minty1981 +mintyale +mintyclintyy +minus +minus Left +minyhitsk0 +miokaen +mippim +miqli +miramyra +miregal1 +mirhagk +miriti +mis +misery2018 +missingIink +missuy +mister +mitchelle1 +mitchrocks +mitchvvs +mixed snacky +mk6 +mkden2 +mkl782 +mks200 +mksu +mkvo +mlars300 +mlbg +mlgb +mlgkittycat +mlkia09 +mlong06 +mmaxie +mmigo +mmmkay02 +mmmmmmmmhmm +mmmmmmnmmnm +mmmuurrddaaa +mndo +mniml +mno +mnt +mo an +mobile +moer +mogwire +mohak45 +mohrs0 +moist +moist P00P +moistSwan43 +moistcltoras +moithab +mokkakulli44 +moksi +mol 99 +moldsack +mole +moleflair +molkyrion +mologgi +molten ass +mombasaa +mombasaa D +mondklapje +monero gay +moneybandz +moneypants +mongelman11 +monkaS +monkasusdog +monkegrip +monkey +monkeybisz +monkeymatt +monkeywilly +monkieturd +monnan56 +monstaa +monsterje11 +montaxus +monteurtje +moo vo4life +mooblesyrup +mooch86 +moocowfish +moogz +mooiboy +mookixx +moomoocrab +moonlighterr +moonona +moonpapa +moonrat2 +moonwyrms +mooofy +moor +morPL8morD8S +morgan renee +morgf +morsotiikeri +morty +mortymoo +mos f +moscuz +moska +most +mostalpha +mothaload +motmyfanny +motorbichael +mountcaedo +mpathetic +mpel +mpxd +mpz00ne +mqaccat +mr atheist +mr boobrie +mr buying gf +mr mage t +mr pink1 +mr rob iron +mr shroom +mr triggerd +mr10inches +mr12345 +mrDragon2009 +mr_adore +mrb97 +mrbreadst1ck +mrdickbals +mrfox2 +mrgeck +mrkaramazov +mrpurpdrank +mrvortex3 +mrwoffy2 +msHyde +msb2595 +msimmo93 +mss +mstfu +mstr nay nay +mtash96 +mthic +muchderanged +mucserup +mudbitedlite +mufassa +muffing +muggfac +mugii +muh +muh sheen +muhName +muhnamezjeff +muhnkydluffy +muin101 +mulletman360 +multi genius +mum ranger +munalutkutin +mungero +mungkee +munney +munoz316 +muovaz +murders +murphy +murphy XD +musashi2109 +musei +mushpinator +musnew +musta_matto +mustaa +mustardsurma +musterdsauce +musty04 +mustypill0w +muta +mutanen +mutsCateer +muufaanchu +muy bien +mv3 +mvgatron +mx +mxgali41 +mxpurp +mxq +my fruit +myballskin +mychaelven +mycrazy life +mydmallsick +myexdidntrs +mygf +mykohchoo +mymoonkeyz +myname Borat +mynamesDog +mypp +myrtlecat +mys_try +mystic +myturngranny +mzsc +n a g a +n k h +n o m i s +n oge +n os +n00b tax +n00btube +n00dIe +n0DaT +n0n Believer +n0ns3nse +n0rthmemphis +n1ch0las +n1ghtmares +n3cromans3r +n4ts +n8m +n8n +nSubordinate +nVox +nYer +n_koo +na cba +naamarihomo +naapurintati +nabritches +nachoss +nae drops +nagezz +nagoog +nah cba tbh +nahbo +nahhhh +nahka +nahkasaurus1 +nahkasohva +nakneemo +naksuu89 +naldy +nalon34 +nalyD yrraB +nambourian +name is damo +namelessRS +nami skin +namnori00 +namtar elite +nancyy +naner +naniichan +naomi +naoshika +napkins r us +nappera +narbsta +nas xy +nashmvpx2 +naskend +nassikka +nasty +natalya +nathank498 +nattte krant +natty nest +natur3za +naturesque +natuurhuisje +naughty ruz +naunas +naven +navi my dude +nawilsi +naxe +nayo123jo +nbyo +ndrs +ne cro +ne hi +nebegyd1k +nebula3 +nechs minute +neck bungee +neckals +nedpvm +nee ceri +neebzor +need +need drops +need panoche +needs tips +neeeefe +neeloy +neenisneen +neeshmow +negative +neggibo +neil +neil v +neiti +neitsytkulli +nekemaribo +nelrb +nemofishtits +neocritter +neoneu +neophyte8 +nerdneck irl +nerf +nerpkin +netsh +neuber +neukbare +neutekind +neuz +never lucker +never s0ber +never subtle +neverblume +nevercash +neverenought +neviilz +new pfp +newaccbtch +newallmaster +news +newt merch +next +next 99 +nexus +ney spook +nezumileo +nfandango +nh0x +nhy0x +ni ox +niaya +nibbla +nice +nice to game +nicelah +niceslime +nick +nick at nite +nickdv +nickel +nickfx +nicky +nicnad +nico +nicoxpico +nieve nooooo +nightmareram +nigriV +nikhil +nikler +niko +niko78878 +niksin +nilatshpes0j +nimlif +nioem +nipsunaapuri +nishkid64 +nisq +nitro +nitsuj315 +nivk420 +nizmoNL +njitram +nk spy +nko +nl Airo +nmb +nmhbu +nmzcow +nnick999 +nnko +nnmf +no birds +no engraving +no flek zone +no gag +no gay ok +no l00t +no purp bug +no use +no1evrnos69 +noDDD +noTheOwNeR +noThumbz +no_odles +noahcous +nobankpin +nobjockey400 +nochoc +nodeLT +nodropman +noek1 +noeyi +noice garrry +noiteerIW +noki keppi +noldaddy +nomiS +nominMaxCape +nomlaS norI +nomorelies22 +nona nona +nonamechange +nondedjuu +nont0xic +nonuboko +noob +nooberman37 +noobledooble +noodle +noong +nopies +noplanhere +nor so osrs +norI Ryan +nora cat +nori +norm HARDY +normal +normie +nornavsoc +norrisi +nos +nosemar +nosepack +noskilljoe +nosnhojgib +nosoberday +nostalgiaeng +noswaL +not Duncan +not chop +not cumingbk +not gods +not heppi +not herbo +not him dude +not shaken +not tiv +not tk +not today m9 +not ual +not1stepbak +notEdited +notPape +notRoyal +notanjiro +notazerk +notbennie +notdead91 +notefficient +notepad0164 +notepad14 +notlikedis +notsoB +notsosmart11 +nottrade +notwack +noutonme +novali1 +novike +novikid +nrakneS +nrdz +nt combos +ntarallucci +nthing +ntrstng +nucnad +nufnufaz +nuggeets +nugs +nullbeing +nulluserid +numb3r go up +number +number 11 +numbly +numnut +nuoli tulta +nuopisa +nurbaya +nurriez +nusta +nusta but +nut low +nut5ack +nutes +nutpeanut +nuubbaa +nuubii +nvcu +nvrpurplight +nwate +nyareet +nyc ramme +nyet +nymue +nysyGG +nzskater +o Buffy o +o Galaxy +o Jay o +o NEK o +o Pug o +o SiLeNce o +o Steven o +o c c u l t +o chem +o n e i n v +o tp +o tu +o0 Rang0r 0o +o00dan00o +o0Ganktank0o +o0mni +o3d +o9 +oAQu1LeSs +oAlsen +oAmber +oBugz +oBuster +oChezzeRo +oClairebearo +oClay +oColeeey +oDemko +oDriew +oDrizzyyy +oFelipe +oGMRKay +oGreene +oGun Smokeo +oHEXo +oHoriizon +oHxD +oIce Teak +oKsirf +oMDmA +oMalevolence +oMoJo +oOGeorgeOo +oORagnarOo +oOoITITIoOo +oRonde +oSanta +oSea +oSpecialx +oTARNAo +oWags +o_o SEMA o_o +oaenii +oaflion +oaisjgljlak +oaj +oakypinkre +oatenz +obama +obamas ass +obbE x +obees +obej +obese_man61 +obican +obitokun +obosk +obvi_no_gf +ocbslim +ocian +ocruT +octazookaa94 +octopussi11 +od1np1ck +odafan +odd woof +oddfinn +oddniffler +odenthas +odinsjourney +odio +odlolien +odty +odyssey +oerinn +of a china +of booze +off balance +offends +offshore +og kasi +ogag +ogbrittney +ogeesus +ogg25the2nd +ogned +ogogog +ogteleblock +oh no fuse +ohSmelly +ohai ohai +oheesnose +ohgoshyjoshy +ohh_man200 +ohhh nooooo +ohhnnnoooo +ohia +ohio is for +ohioisonfire +ohiostate347 +ohly +ohmyrod +ohtukurva +ohyep +oi ranga +oids +oigia +oily rod +oilysurprise +oixi +ok baba +okannah +oke +oksen32 +ol Twizted1 +ol kq +ol pleb +ol_l +olatrekuk +old Soul rs +old kind 911 +old man agst +old man zedd +old meat +old mem +older +older fruit +oldsports +oleNeilyBob +olen lahe +olindaelostz +oljon112 +ollie +olliedamage +olliethekat +olllllllo +olllllllo TJ +olmec +olmmmmm +olms beach +olovi kolome +olsyboi +olvia +omavi +omegaOnepump +omff +omgbabestop +omgimacarrot +ompahelppoo +omrip96 +omwtotob +omyefge +on 9 +on the fella +onalite +onbak1992 +oncenterlink +one 69 +one1one1one +oneblade +onelifehaze +onespringday +oneticktony +onex +ongelmanuori +onizuka +onle +onlinetares +only +only4pvm +onnetar +ons va +onthebook +ontspan maat +ontv1992 +onyo +onyx no +oo7jordan +oobent +ooblued +oof mikael +oofbored +ooi +ook Thunder +ookbye +ooli +ooo Papi +oooRush99ooo +ooooby +oooopsiee +op +op P +openyoarmpit +opiumwet ii +opneemvot +opticsnail +opzu +orangeluke +orangetree34 +orb in bag +orb knob +ordy +orebac +oreo lil +oreru +orexinergic +orez66 +org asms +orgasmdonor +orielor +orig +orir +oritx +orkans +orkut +ormz +orophyr +orra +orrichimaru +os SlayScape +osJuhiss +osbhuda +ose420 +osmati +osn +ososrswhen +osquiver +osrs Apathy +osrs MCFS +osrsbilly +ossaciM +osu +osynlig +otallone +otdog +oteb +otherguy3668 +otoboR +ottledread +ottx +ouic +oum +ouououuoouuu +outohere2k +outsmart3d +outsourced +ouwe +ovas bis +overact +oversize rat +ovox +owen4boro +owenwilson +ownsome1 +ownt by flan +owo0 +ox +oxifaze +oxoxoxoxox +oxtale +oxyy +oysni tu +ozos +ozztrevor +p hd +p n g +p x v x m +p000r +p0ge +p0tat0_baked +p0w3r +p0werSinn +p0werliftin +p2pell +pAj4ri +pHqiXfQb5rpO +pRandgris +pRiesty +p_tane +paatttxxi +pacack +pacbackpack +paccerz +pack +packmas +pacman5882 +padedu +padhimself +padq +pagakoning +pahe +painter2020 +pajiaobin +pakgg +pakkohoito +pakoonjuokse +pakwatch +palacePier +paladylan +panda +pandahands +pandas flail +pandascapes +panel v2 +panelupgrade +papa jjinx +papaisthatu +papatec +paper +paperbutter +parB +para1911 +parsakeito +party-joiker +partyinferno +partymonkey +partypooyan +partypossum +pashol +pasismi +paskapylly6 +pastry +pat summitt +patbeerpants +patches4623 +patnazNkryme +patriciogmz +patrol +paul94nl +paulimvitor +paulmacawk +paw fetish +pay peru +payout +pazmar +pb tiramisu +pbagel +pbj eater +pbjt +pcce +pd3 +pdi +peace love h +peaceofbread +peaceoverwar +peacsenur +peajy +peakyberry +pebbles256 +pecemker99 +pecker neck +pecko517 +pedagoog +peeje +peenwa +peepeepeepe +peepichu +peepoGamer +peepoParker +peerks +pegfemboys +pegge jr +peksi +pelaan +peliken2 +pellemaailma +pelmot +pemmex +pen gee23 +penakonda +penally +penile pain +penny 4 thot +penteroinen +peoples0123 +pepe max +perc ceo +perc5 +perckey +perigor22 +perlecta +perm +pernieuw +pernix +persepullo +persesreign +persisted +person +personajay22 +personal +pesto pasta +pet melon +pet my mole +petc0 +peternguin +petesmcskeet +petlucksucks +pettyrogue +pewbs +pezzler +pfiati +phatpunch +phatsocallum +phattymaster +phen0mXD +phenotype +pheras +phetagoras +pheyyw +phinex +phlayme +phonon +phoop +phorme +photolstamp +pi n g +pibbi +pickle llama +pieater_314 +pierke +pietu +pietun +pieww +pigeonkisser +pigeontoeman +piggybosspen +pigusvaistai +pihseurc +piia potka +piie +pikir +pikknu +pikkukala +pikkupeppi +pillman +pilludemoni +pimmscup +pineapples56 +pink soup +pink spoon7 +pink4 +pinkdragon76 +pinna67 +piomon +pipiopi +pippelisurma +pippy 429 +pipratoos +pir0tekniq +piraat bwana +piratedog7 +pisk naxui +pixelpeat +pixiedrank +pizano +pizzaforce33 +pizzaloksi +pizzalord321 +pizzerr +pj137137 +pjmonkey03 +pk3rsh34v3ns +pk_all_pk1 +pk_by_me +pkdrwho2 +pkdude116 +pker +pker ice +pkerdude559 +pkew +pkpk +pkshitomario +pkwy +pl33k_supa +pl3d +plaatshouder +planetflat +plank r +plankforsure +platygirl +play +player198792 +plea +pleadingface +pleadtha5th +please +pleasebuyckb +pleb Remains +pleb166 +pleben +plebminister +pletsjer +ploomert +plopko +plszulpet +plum lee +pluma +plumb +plumb bum420 +plumit +plumpy nut +plz dont kry +plzl +plzvenmome +pm 2 spy +pm4 boost +pmax +pmmefeetpics +pneck +pnn +po0z +poachpenguin +pocar +podginator +podolskee +poesiewoesi +poesiwoesie +poffdragon1 +pogarmyy +pogdoor +poggersgif +poggie +pogglewogger +pohaku +pohwe +pointn +pointright +poire +pok758758 +pokas +pokemonsunim +polentusmax +politieman +polo gee +poly +ponderer +pontlarge +ponyika +poo from bum +poobutton +pooga +poohwell +poolbadger +poon fisher +poon nanny +poop81 +poopeepeeman +poopsm0ke +poorlyhung +pop-tato +pope +popstantot +popwig +porkchop-kun +porkchop87 +poro600500 +porpleRanger +poseidon0928 +post +post nut sad +potato +potato pleb +potatogod62 +potatolove20 +potatoplayer +potholderz +potionsell3r +power +power helmie +powercheck6 +powerpluging +powerslide +pp 73 +ppb +ppdandelions +ppengu +ppfighter +ppidd +pr0jectcarry +pr0kkeh +pr1est +prQmethazine +practice +praskiepas +prayfx +preachably +pregnant +pretty +prillage +princesstktk +pripps0 +prkr +prncss +pro90 +problitz1 +progmog +project eggs +prom +prostate +proud2bbalin +prtck +prut257 +ps1 jrpg +pshot25 +psp 11O6 +pssssssh +psykotic12 +pt37 +ptdn +pubnroh +puddskape69 +pudgy +pugginSpooky +pugmen +puhkipantu +pul uk +pulinaseppo +puljulaine +pullo viinaa +pulpfree +pumiss +pummi984 +pumpkinslaye +puncher +punchlineNL +pungur +punken +puny +pur3gh0st99 +purEvil808 +pure +pure owns al +pure wood23 +pure10693 +pureblackid +puregluttony +purity +purpfanatic +pusha tree +pvm bioodz +pvm-owning +pvmingbr0 +pvmrob +pvpmirage +pvtRyansPvts +pvvm +pwn me plox +pwn0grapphy +pwn2b3w1ld +pwnnya +pwuh +px yra +pxls +pxtchy +py ze +pynergy +pyro +pyro255 +pyromaangast +pyttyyn +pz +pzqlpwbma +q Aleks +q Nossie p +q b0nkerz q +q f z +q l l u +q sl +q-Mini-p +q0k +q9q9q +qJezza +qOsMoSiSq +qPepsi +qQazp +qTiger +qazi +qazio +qbc +qbi +qbt +qckr +qerw22 +qez +qi e +qiany +qiunc +qiyamah +qlxxlp +qnzjosh +qoao +qooo +qop +qorbin +qp +qpwoei1029 +qqgoat +qsse +qtAlice +qtb +qtei +quazepam +quekchose +questarila +queundas +quickiies +quickmoist +quickster61 +quit afking +quit cry +quitb42k +quiver81 +quky +qwaylub +qwerps +qwertralph +qwerty2431 +qwertyboll93 +qwertyuiozxc +qwl 2 +qwopr8 +qwruqwpourqr +qy +qz +qzxz +r a i n i n +r a i q +r d x +r eflex +r ehab +r i ley +r n g o d +r o c h i +r pt +r u a pussy +r0adh0g +r0jasss +r0mera +r0p3_tv +r0yalrag3r +r1ch3r mitch +r1chmond +r1ddlbox +r1z1n +r3laxed +r3mov3k3bab +r4cky +rAEbl88 +rIcHmAn4 +rMatey +rVino +r_rl +raando +rabid +raccy rac +rackee chan +rackelzz +rackemballz +rackzcity +racoon96 +raddawgg +rademakertj3 +radox +rafa2424 +rafnek1 +rafuchoz +ragde28 +ragegoon206 +raid +raiden +raildex +raisin canes +rakete +rallikaar +ralliss +ram this +ramafie +ramblin +rambo 1206 +rambombon +rambroze +ramjamyelham +ramsesthecat +ranarr +ranarrbiss +random +rang2d +range +rangedp00wns +rangoraus +ransty +rarefleas +rarekia +rarru +rarurrer +rat catcher4 +rat ritual +ratboysteve +rateddd +ratirl +ratirlAlfred +rats +rattiyanee +ratzzzzzzzzz +rautamon +raves m4ck +raving +ravioliwren +rawheadshot +rawkneedong +rawr +rawrsmashh +rayhoon +raymanvh +razorwheels1 +razzdnutz +razzex +razzmatazz23 +rb winter +rbjk +rbootsGOD +rcr333 +rcyy +rdrluvr77 +re-frozen +reBoosted +real boyo +real-derin +realAxu +reallityfail +reallyhigh +realpcooktho +reamillion +rebirthofyay +rebuildd +rec me +reclinedgmr +recognizable +reconjack +red eye jedi +red fox8 +red504 +redank +redberry +redditlucio +reddragon950 +redeye q p +redgorilla12 +redhunter193 +redman211 +redpatch +redracecar27 +redrumyliad +redsheik +redsox216 +redsp3c +redwagon9 +reenur +reese +reetznutz +reflexlols +refurb99 +reggie v2 +reggieblunts +regorydog +regular ph +rei1315 +reikimastr +reilaria +reistje +reitan2k +rekordlaunh1 +rekrog +rektum +relac +relaxed +relaxed now +rellu riku +reluf +remind +remind309498 +remko maxed +renaissance +renasue +renruB +reopened +report you +reptil51 +reptile reas +reptilepoop8 +repulz +resU +resetcentral +resupplyalt +retern +retrrd +retuson +retzc +reznas5 +rezpek +rfr0sti +rg44 +rgfji +rhey +rhiller83 +rhygan1 +rhys c +ribalibali +ribe4 +ricard0live +ricardos78 +richarb14 +richy +richy rain +rickrko +rickthick73 +rickystackss +ridewitme +riilis +riipx +rikkertik +riksa123 +riku230 +rikuirl +riller +rils2 +rimpati +ringo794 +ringosting0 +rino +rip dj +ripHuyy11 +ripbobthecat +ripend +ripsrc +risbarn +riskbizz +risker +ritcey +rithvik +ritotrisoto +riuCooler +rizn +rjh300 +rjweb +rl9g10rs +rlkgfseorhfe +rnatt +rng god x +rng limey +rnom +rnue +rnv +ro0b0 +road2broke +rob nagle +robbinator27 +robhode +robilo123 +robinchris +robo +robombalt +rockcrabpvmr +rockeroHN +rocketberg +rockhead7746 +rockstarwht +rocky leeg +rockyandtaz +rockyou 2 +roest +roflbaker +roggy +roldan_one +roldunogene +rollsyy +rommmey +romper +roofy +rornburst +ros n +rosati924 +roshambee +rossdark1234 +rossmain +rostiefrosti +rosullivan8 +rot popstar +rotceleS +rouge +round cat +round kc +royalpanda53 +royce ranger +rqkrtzjvbsuh +rrautamies +rriot +rrrpR +rrrrrrc +rryutie +rs3 blows +rs3dansgame +rsoby +rsruinmelife +rstr expert +rsyux +rthgo200 +ru-ne +rubengouveia +rubikslayer +rubj3llyonme +rubtuge +ruck ur dad +ruding +ruikkuapina +rukdingme +rullakebaani +run amuk +run its bc +runaru +runaway iron +rune +rune dogger +rune enjoyer +rune poon +runedongs783 +runedragslay +runeferyearz +runehol1st1 +runeika +runep3 +runequeen163 +runesc4pe +runesoftime +runetraction +runite +runite bars +rupt +russien +rusted +rusted shaft +rustigggggg +rustinged +rustys word +rusvet +rvrse +rxbi +rxylvrn +ry1n +ryh +ryppyreika +rythail1 +s h l o o p +s hok +s i r tinly +s k i p o w +s laack +s n u f f e +s nekk +s t i l +s tress +s0spwnz +s0uln0te +s0ultage +s10w +s11gm4 +s1ayerg0d +s1pa +s1r maximus +s3fa +s3nna +s3nt +s3ppa +s3vuu +s4mu +s4nc +s7v7nty +s7vey +sCUM Runner +sKDestine +sNEXyBaker +sSahm +sSpring +sTs W33D +sTxje +sYo +s_ck it +sa ko +sa-ku +sabfas +sackiltrog22 +sackmen +sackmyduck +sacredchange +sad nmad +saddest +sadgeboi +sadnmad +sadnmad666 +safe bunnys +safermoon +saffyO1 +saffyO2 +safino +saguyuyu +saiko +sailsouls +saintffs +saiyansmithy +saknoM rD +sakuyaaa +salad +saltia +saltycups +saltynads +saltypepper +saltysealife +sam ofc +samdegreat +same +same hada +samo0o +samoht10 +samothon +samqwop +samtatt1 +samuraigod13 +samwise1133 +sandai korky +sande108 +sanooJ +santa cloud +santa ho ho +santorio +saphinix +sara +sara 35 +saralandry +sarcasmz +sari essayah +sarppatsu +sashamii +saskecas1 +sassy fool +satisfried +satsuJima +saturos159 +sauna41 +sausage +savPalestine +savage_grey +savi 2 +savukorilas +sawb +sawb0ssnl +sawl7 +sawshoulders +sawyfabj +saynototofu +sayyless +sbrand0n8300 +sburzz +sc arlett +sc00ben +scaffidi +scallicci +scape for 1 +scape4ever20 +scapey123 +scaredbunny1 +scat wagon +scb +sccrub +sce nes +scerp +schaamlap +scherzmfromz +schetts +schiggs +schildknaap +schmashmu +schneeple +schneky +schnibbyy +schzu +scidder123 +scitles +scnick +scone99 +scoobydooby9 +scoobysdooby +scotian 902 +scottslipper +scottuzamaki +scottydo27 +scout +scout robot +scrollspirit +scrotumfart +scrubEE +scuffedbrain +scuffi +scumbag 66 +scuterholmes +scythe +scytheXI +sdfsd125 +sdotmaxedout +sdzl +seBlait +sea owl +seabird +seachrome +seacowcow +seamondemon +search0 +seared +seawolfsam +sebbe osrs +secs +securite +see attached +see me whip +see4limbs +seepah +seetod +sefeeee +seffimz +seizure +sekkuso +selfShow +selfcurse +selfish coal +selling +sembino +semper +semperstrik3 +senZe +senapsgasen +sendu2edge +sendykap +senggg +senpai +senpai btw +senseyf +sentterih +seppem +seppes121 +seppevb +seppohaa +septynetas +ser angus +ser tugger +seraphine jo +serbuttkiss +serious +seriouslee98 +serpentSmelt +servix +sessarrow +settyboy66 +settyz +sex mum +sexy skuxz +sexypersian +seyed +sezery94 +sfinx71 +sfnative +sfsdfg +sgaben +sgf419 +sgg9779 +sgk +sgq +sgurdevolii +sh-Y-ft +sh1nan1gans +sh1ttyrng +sha0ski +sha7y +shabado +shad y +shadex94 +shadow +shadow brr +shadow btw +shadow77440 +shadow926629 +shadowarmy +shadracker +shafli +shakedabooti +shaking irl +shamabeast +shamans +shambbles +shanemck +shantyklawsh +shape +share +sharingbox +sharkey_32 +sharpshot776 +sharto86 +sharyn cox +shasd whip +shawnn1 +shayge +she btw +shed dabber +sheep5 +sheev85 +shekelgoblin +shelfy 2 +shents +shere khan1 +shes sleepy +shezze +shhit +shiddingpant +shields_zzz +shift drop +shifty +shiftydaboss +shigha +shiky +shio +shishiodoshi +shisui +shizcake +shkoB0 +shliure +shmoopaladoo +shnizzlebear +shoarmamama +shokki +shoopa +shoot162 +shordilele +shore +shortsleeves +shortstroked +shower +shoyu +shreddin +shredness +shredskater +shrek5 +shrigma +shrlmp +shrooon +shroooooooms +shrootfarm +shroudyroudy +shtos +shturpants +shumili +shushlik +shvxstxchla +shxg +shxyzzz +shy lo +siNusas +sibeepboop +sickGeneral +sicklyhare +sideways640 +sidney3241 +sienna +sienna sleep +sieracki +sigh +sign0ut +siik +siimzz97 +siiz +sikatopi62 +sikazz +silburr +silemani +silenthenk69 +silentical +silenttrew +silim acac +silk +silly cowboy +silvar93 +silver bean1 +silveraze123 +silverwar33 +silvethril +silvio lol +simi sai +simmeg +simp 4 life +simple +sims Hsp +simz +sinannani +sinappi688 +sindicalism +sindulis +sinfulnature +singlemom34 +sinsofmany +sippin +siptar +sir ecnar +sir skau +sirlotje +sirmesoulier +sirpaul +sirpoopball5 +sissijuustox +sisuwu +sitonmaface7 +six2midnight +sixanddagger +sixerr +sixovercrest +sjaq +sk0me +sk1rttt +sk9bord +skaiii +skaios24 +skandaali +skaring kids +skateenjoi +skaterdogz +skatermatt91 +skatterpunk1 +skaugi +skcusxegaj +skedie +skeide +skek +skeletoon +skeli +sketchdreams +ski +skidipoppop +skilgrave +skill +skillachris2 +skiller270 +skilleuhjong +skillmaster +skillngbot41 +skills2millz +skillz davoo +skin suit +skinny227419 +skinnypimp71 +skipz1419 +skittels +skittlesour +skiu_21 +skizzurp +skizzy sammy +sknzor +skoalintry +skoowu +skorthen +skowotek +skranzii +skrenne +skrtskrtpvdb +sks110 +skuccy +skuirk +skunk nugs +skunkpaste +skunkskillzz +skyE +skyelar27 +skyffoxx +skyz +skzs912lav +slaack +slack austin +slacky456 +slajdaren +slap her box +slappfisken +slartiste +slavhouse +slay +slayJTIaster +slayer +slayer92 +slayerfrog57 +slayerxp +slayetd +slayhore +slaying +slayzerot +sle3k +sleek2d +sleepinonice +sleept1ght +sleepy 940 +sleepysleeky +sleepyweasel +sleightest +slemgaedda +slice +slice O pie +slickstick21 +slickvick21 +slidesteps +slidtegitte +slight +slight7 +sliginz +sliim +slim in dar +slim j3sus +slimski +slinnGimme +slippaa +slipstrides +slobthyknob +slowmopwns +sludgebag +slundersc0re +slurpeeboi9 +slurpeeking9 +slurpy40 +slurpydong15 +sluz +slvtty slvt +sly seyda +slyhitman +slypupper +slyr4ng3d +sm0ke herbs +sm0kebeers +smChi +smackbo +smaddz +smaggd +smalcano +small boaty +smallmichell +smallppbigxp +smalsey +smasher12121 +smasher95 +smaugs +smbonn2005 +smeerpijper +smel +smelly fuss +smellyducks +smerq +smettjes1 +smh Monkey +smiithy +smirqqel +smithdarts +smittty2009 +smoe +smoke +smoke buds +smokesIetsgo +smokin +smokin turdz +smokingalone +smol bat +smol chris +smolBen29 +smoothcamel +smoothlover +smote +smoug007 +smrgn +smuqu +smurfrookie +smurpfy +smushman +snaggle +snagnURkill +snailydog +snakehuntr94 +snakenbaked +snaplocket +snapped neck +snarfoo +snck +sneakY geeB +sneakyleazrd +sneakyyj +sneekeysnek +sneeky +snek +snek killa69 +snek man_44 +snidletics +sniff +sniffmapouch +snikkels +snipper143 +snoogensss +snoppen97 +snorlax481 +snot aap +snow dude678 +snowdance +snowfild +snowkeepuh +snowy +snowyhawk45 +snowysonic +snoxxyl +snp500 +snubsnub +snurtfe +snuskfet +snuskukken +snusnuending +snygg o smal +so joe +so jung mijo +so much ass +soarix +sobsk +soccerdog +soccermom82 +soccerrad177 +sock +socopb +sodChamp +soderfalk +sodynamic +soft +soft dab +softer bugg +sofus64 +soggybread4u +soggywaffel9 +sohju +soiled +sojraal +sokoudjou +solfam +solidon +solo +solodiyloner +solodoloyolo +soloeraut +solopops +solos +solost7 +sombb +somber +some +some1saybags +someBODY325 +somos papaya +sondrep +sonera +sonoboymw +sonofablitz +soobli +soombie +soon2bxwife +sophiebear69 +soppel +sorris alt +sorry +sorry pls no +sorrymatey +sotaneekeri +soul +soul et luna +souldrainer +soulkamikazi +soulkra +soundspeeds +soupnbannock +sourkraut +soxx +sp3edie +spOnsOrr +space craft +spacemanriff +spaceonion44 +spagh bol +spam123 +spangulation +spankmoi +sparkoftruth +spartan1137 +sparterrang9 +special k258 +specialton +specuri +speed +speeder269 +speedtrain +speeeeeen +spell +spenmaso +spete +sphicologo +spiLLLLL +spicke21 +spiderman 13 +spidey +spigems +spinova +spiwit twee +spladay +spleiner +spletcher2 +spliffens +sploobie +spoiled mayo +spondonicles +spooki xd +spookib +spoon +spoondrngplz +spoonfed +spoontarded +spoonyg +spoooficus +spootineftw +spord8 +spozz +sppak +sppoh +spratel +springAnonce +springplant +springsteen3 +sprite zero +spritelum +sprits +sprsp +spudmyster +spugEddi +spunkontitz +spyde96 +spyrolegend4 +sq shield +sqad +sqrls +squareheadfk +squatlownslo +squidnstab +squirrel1991 +squirt fan +squirts +sralisas +sray +srd +srgynt +ssA taE +ssei +ssh keys +ssj3 +sspiriNut +sssu +ssttaann +ssyd +st aeryn +st4k3l0rd +staarii +stabbycut +stabekk +stackables +stackagawea +stahldog +stainalt +staleburrit0 +stan darshhh +stannaz +stannum +star +starcrosdlvr +starfalI +starknightsy +starshoppinn +starvn-marvn +static void +steadiskill +stealthwolf +steckubnU +steel +steel slime +steeljake +steelplums +steeveee +steezybear +steezyledge +stefanopt +steflon don +stekkeT +stella1 +stepbro +steph n +stephvn +steponnopets +stereos +sterre1ch +stertanz +steveagogoo +stevenovak6 +stew thru +stewiii +stfn +sticc +stickuppix +sticky clay +sticky holes +stickygirl +stiff +stig sucks +stiice +stikybandit3 +still +stingray2018 +stinky +stinkybunny9 +stinkymooner +stokstaart +stoned +stoned84 +stonedowned +stonerwelds +stoneybolgne +stony +stoodzy +stop log +stopbegging +stopy wersow +stor m +storkis95 +storm +stormynight +stouterikk +stp3ach +str3tch33 +str8 balling +straangeDayz +stradiSlay +stranglege +strap locks +strateigo +straw cup +strawbery +strawnk5 +streetshark2 +strex1 +striker +strnagetamer +stroudlee +strp0tzz +stugex +stuntti +stupid +stupid game +stupidcape +stupot845 +stylebend3r +styrkekram +styxRYAN +sub merge +sub2purple +sublime +submunculus +subooptimal +substring +subzero +suchti +sudden sloth +suga +sugar d0nkey +sugarfreeman +sugarwater +sugme nob +suheil69 +suhuan123 +sukau +sukc +sukidarkra +sukii +sullz +sum1elsecall +summa +summa arte +sumsy +sun delusion +sunaert +sunday tea +sundburgaren +sung101 +sunkir +sunkirrr +sunny +sunny sponge +sunrakuz +sunris +sunu +suolahappo +sup J +sup3r0n3 +supagorilla +supalordwar +supbruh +super +super slooow +super system +super-thoms +superbuds +supercolds +superj4 +superlisko +superlonely +supermanJJ +supermarket +supermaxx +supermoist +superr +supnoobs10 +suppertmain +suppus +supra +surfboardcat +susanno +susdog +suspect12 +suss +suwo +suxc +suzuky +svedanya +svennepen +svenskeren80 +svettnisse +svimmelskam +svoji +svrN +svstre +svti +svver +sw x +swag +swag dr +swagburgler +swaggabawz93 +swaggb0y0wnz +swaggie365 +swagscape666 +swake420 +swamp +swamp man_43 +swampertman8 +swampwitchx +swampy fool +swansoup +swasian +sweaty +swed +swed 420 +sweet ass +sweetpissin +sweety 77 +sweggdaddy1 +swerve q p +swfc50 +swfc51 +swftz +swiet +swiftmango21 +swissbagette +swol +swolelord +swooinc +sword +swordngun3 +swordsplay62 +swxasxx +sxkes +sxtt0 +sxybro +sycp +syklo +symmm +synack +syndra007 +synnistra +synterrafox +syua +syytu +szer +szeth17 +sztuk +t iel +t imbo +t r a m +t rio +t u k e +t ux +t-Wrench +t-painn +t0_valhalla +t0ast mal0ne +t0c00l +t0nni +t0xicpoptart +t1n3 +t1tz1 +t4aker +t4t frot dog +tOxI +tRIPdoubt +tRNA +tSessa +tZiMiNt +ta det lugnt +taasen +tabbionny +tabulast +taco +tad3j +taeyeon +tage3xx +tak0981 +take +takimoto +takotime +tala 7t +talinklion +talisam +tallest +tallwhitebr1 +tamesh +tandem dooks +tanfastics +tanguay478 +tanklesss +tankyster +tanuliina +tanzfangplz +tar +targ119 +targa +tarpGC +tastenz +tatarsauce +tatuwah +taxed2 +taybonejones +taysmehu +tayyab +tazzen +tazzzz31 +tb 3O3 +tbaballers +tbach +tboowscouter +tbow +tbradz +tbrey24 +tcorky +tcroft +tdawgthekid +tdoe +tdogtsw +tdslaterG +tdufflebags +teagantime +teakte00 +techev +techeverria +technitions +teem0her0 +teemerco +teh_new_guy +tehe302 +tehskoozy +teini_horo +tellymantel +temmi69 +temx +tenac +tentacion +tentacruel38 +tepaseohijo +terenerd +teroy +terrence +terroristiI9 +terrryfold +tescoworker6 +tess tlckles +testokersa +tetinhaaa +tetsundo +teum +tevlevdeR +tewwowism +tezje +tfortal3nt +tfsi +tfw +tfzx +tgchick3n +tgkiller +th0my188 +th3engineers +th3m0nrr0 +th3physicis7 +thaiboygoon +thajokerkid +thames1000 +thasonn +that1stoner +thatbaldkid1 +thatbuttguy +thats +thats bone +thatthicksix +the 2 of us +the G herbo +the Unreal +the Zec +the afg-gun +the assail +the big girl +the capt +the creaper +the girls +the kleeborp +the lupo +the lurkkii +the mighty R +the ocean +the suns +theDazzling +theFish +theH0witzer +theHNC +theMatan123 +theSuperb0wl +theWOODchpr +the_blindguy +theachaian +thealemdar92 +thebestgf +thebrucelee +thecoolbro97 +thecwakecake +thedamoes +thedarclit +thedarklit +thedyermaker +theebeker +theeib +theforkster +thefunkmonk +thegamebad +theguyman160 +thehow112 +theironlotus +thejonsson +thekingkane1 +thelanco +theletterbla +themaestrox +thematrixgg +themrgiggles +theon +theonebrova +thepirateman +therangetank +thereal bi n +therealAxu +therealchr1s +therealinfex +therealramba +therminy +thes5016 +thesavior315 +theserpent +thesmurfster +thetibo +thetoday +thewooshh +they gave up +thezucc +thhxd +thicassglass +thicc dady +thicccc +thicchode +thiever05 +thijssb +thinker +thinky +this +this blunder +this gu y +thiseku +thisthat2019 +thongmasterb +thoomed +thosma777 +thot +thot tub834 +thotortiana +thoughtz +thrakataluk +thrashcan86 +three2one0 +thricer +throat queen +thrynandwen +thug z9 +thugger +thugli +thundeman999 +thurgo pie +thwison +thx4zloot +tibbs plural +ticklemesack +tidnabregdab +tienermoeder +tigerturtle0 +tightteen97 +tijgertje3 +tiktok rizz +timaye56 +timejumpsolo +timmaxio +timmer +timmy +timmyisweeni +timmyjoe643O +tinmer +tinnaytookit +tintaria13 +tippystick +tipua +tipyt0p +tire +tiredcloth +tisbea +tissiliisa +titches wit +titsanddrags +titty +tittyjuggler +tj44 +tjappko +tjcombro +tjd1233 +tjomka +tksnevrlucky +tmahones +tmeer +tmeer 18 +tmjdx +tmued +to dd +to0Oldf0r1t +to_o +toad +toad03 +toasted max +toastfinder +toastypoast +toatsme42 +tobiasalex4r +tobinoo +todd crosset +todtplanker +toe2 +toebumper +toes +toesmeller87 +toff +toff haha +toffelboy +toffij +tojo228 +toks +tolerable 24 +tom hutch +tom widdle +tombaum +tombradynfl +tominator87 +tommybun +tommys488 +tomrichmond9 +tomriddle09 +tonko +tonttitonder +tony danza +tony el gros +too bad +too known +toolbar +toomastoomas +toonits +tooowise +toot +top her 1000 +topdollar +topgun 17 +topgun343 +topie +toptom90 +toqs1986 +torfy +tormutrose +toronomans +torpedox1 +tosspot12 +tossta +tostaempo +totip46 +tottti +touhutimppa +touma +toxi +toxicburn13 +toxiclun +toxicsaitama +toy Owner +tozmic +tq +tr0nberg +tr0nd +tra1nwr3ck13 +trade +tradescreen +trading law +traevitz +traffic +trafficly +trainman222 +tramayne +tranquiltoad +tranqzz +trans +trapbag +trapizium01 +trashy +trattqunnar +trav50 +travym66 +trcky americ +treboolks +treetardo +treezy +tremmu +trenboloneyy +trevor4ever +trevs +trevs iron +treyblob +triangle28 +trickyerrr +trickyricky +trickytoad59 +triggaevery1 +trikyricky +trilla +tripin +triple fin +triple pre +triple zero +triplefiter +triplelmao +trippel agen +triv hamzy +trojan break +troll +trolling +tropiiix +trout +troutking96 +troy the mak +trso +tru3 +trucker74 +truskey +trustfundcat +trustsfund +truucas +try the wiki +trying2quit +tryksta +trytohuntme +ts4ever +tsqq +tstrong5689 +tsukemen +tsumino +tsurie +tsw +tswiftfan82 +tthe +ttnq +tubu +tuggly +tuhdhuderr +tulieee +tum0ppi +tumeken jyra +tumme +tummytickler +tumunduktu +tunalife +tunnepelaaja +turban911 +turbo +turbo nut +turboChett +turboboost93 +turboed son +turbogamer12 +turbojoey +turbothots +turkishh +turkles ahmo +turn the 6 +turnt +turntBurrito +turntgod711 +turtl111 +tututu +tuumas +tv_vt +tvmv +twasnotready +twelve bags +twelvecharac +twelveswords +twiceascool +twink irl +twinr0va +twisted tina +twistedgirls +twisty +twitterclans +twixinthemix +twiztid5000 +two4nine +twohandedfap +twotoedsloth +twrangles +twubble +ty RuneLite +ty zmith +ty4flail +tyguy +tyler1041 +tylorLotus +typage +typedef +typto +tyrant +tz13 +tztok-worm +tzuyah +tzuyufan14 +u dead now09 +u got a dart +u got beaned +u itachi +u kno de wae +u r gay 4 rs +u0h +uEnv +uKnoTheRules +uLiveButOnce +uRattt +uSnAvYsEaLs7 +uTBER +u_u sunshine +uberHasu btw +uberstunts +ubiquitous96 +ubug +uchar +udq +udr +uetzcayotl +ufnn +uganstolfin +ugivahrimjob +ugly 67 +uglyandfat +uiaF +uiliuiliu +uilz +uimi +ukn0w +ukwolf1 +ukzharry +ulab +uliuli reps +ult u fk jzs +ultimo0se +ultracet +um Cya +uma pyoi +umer +umexx +umr +umw +un deux +un1versa1 +unFolly +unaroc +unawareaxe +unazegamoth +uncle +unclefro +uncleskrt +und +und3adedd +undeadgun +underslept +undoc +uneek2you +ungafknbunga +unholyblood +unitewankers +unkyjay +unla +unless +unlucky2020 +unluki +unravel +unravelslapz +unreaL294 +unrequited +unsoy +untc +untilnextyea +untitled +unwarranted +unzips +uppahoods +upset +upset berry +upwindnofear +uqx +ur a bird +ur buttugly +ur cool +ur so mad +ur stinky +ur6 +urBunsRDone +urNANS +urano O_o +urashitpker +urfault +urgirlisf2p +urgnah8me +urondelekk +urqt +urvinis1 +urza +usainb0ltrag +uselessbozo +uselessmap +user187 +usergoeshere +userjman1428 +usinlefthand +usma6100 +utiliser +utpaatur +utsw +uu Sauce +uub +uubaidaus +uul +uuuoouuououo +uuuuhhh +uwja +uwu merchant +uwu noises +uwu24 +uxbridgekid +uyakO +uz x +uzei +uzis akimbo +uzui +v Simba v +v olksu +v oltage +v tsng +v uka +v yp +v-yordan0702 +v0i kehveli +v0mbat +v13 +v3kz +v453 +vAnthony +vBlankie +vCamel +vDragzi +vFoley +vJace +vJordxn +vLachieAU +vLeqacy +vNicholas +vPikis +vRoso +vSnoop +vSpectre +vTaqq +vaderex-1 +vaflyga +vageet +vaghairs +vagtap +val val val +valeriaT3amo +valithi +vallihauta96 +vampfrog +vampir +vampiremiyo +van est +van soi +vanVoren +vanacis +vanacularr +varla phase +vasia +vasxx +vaux One +vavmaster +vb cannsss +vb1 +vbehn44 +vbhos +vc +vcl +vcnyew +vcw +veEXP +veergolio +veetuli10 +vega591 +vegiebobs +vegiitto +vekter1 +veldow +velek +ven g +venazuelan +vene +venefae +veneruuti +venezuelan76 +vengedclaws +vengedurmom +vennie123 +venom nate +vent +venturo +venzano +vepie +veri2222 +verlord +vernonb2688 +versacejean5 +versatility4 +vertigo love +vertztheone +verychillguy +verzikius +vesikulho22 +vesq +vestapol +vftvmv +vgtrs +vibe check +vibing +victoriauwu +video +video peli +videogamer +viento suave +vierges +viet dragon +vieze sjomp +vigilant +vihervasuri +viikzt +viilipytty +viki +viktor main +viktoras300 +villavolta80 +villeh +vinigha +vinke00 +vippaa +virtualsucks +visdayox +viserbro +vislegis +vispikauha +vissiman +visualduck +visuna +vitunhomo +vitunkoyha +vitunneekers +vitur scythe +vitutor +vituvahe35 +vivaa +vizzN +vkt +vlaamsbelang +vlees petje +vllekoo +vlyn +vmooo829 +vmxn +voddeman +vodka +vodkapro +vodke +voi vattu +void-e-d +void5 +volconhammer +voldersnort +volga34 +vomax +vork4sh +vorosity +vosol +vougz +voui +voxi6 +voyage_zjo +voyej +vpxl +vraakmanus +vriskafan888 +vro +vubervos +vulnaamin +vulxe +vunts +vuokko22 +vurn +vursa +vutr +vuur +vuzvuz +vvBearded +vval +vvtt +vw +vzi +vzkg +w Danko +w e b r l +w en +w ert +w vy +w00_88 +w00d pecker +w00tgh0st +w00x titan +w00xy +w0Ive +w0ked +w0lcomcz +w33dplanter +w3n +w4kenbak3 +w5s +w6rst +wYungen +waaayneee +waaluigii +wack pack +wacup +waga iron +wagen +wagween +waitwhyudead +wakecub +wakingupsad +wakuser +walk +walker80 +walli +walloftime39 +wallyally13 +walmart nuts +walmart used +walnutmonkey +waltjrs legs +wanShy +wana corp +wanna quit +wanolo +wapwap +warcauser33 +warcraftgame +wardongs +warestoteles +warface125 +warm +warm cuddles +warm is vuur +warmclouds +warrior +warteryyy +waseem76786 +waste of alt +watch +watch hp ty +waterbender +waterdrink +wathx +wavej4 +wawuweewa +waxRS +waxhitwonder +wayabove +wayne s new +wcdak +wdx +we died fast +weThoom +weak dummy +weaknd +wealldiesoon +wealthletics +weaponman54 +wear croc +weary pigeon +wechilling +wednesdvy +weeb +weeb doggo +weebew +weedkillsppl +weegthe32nd +weekendfun +weenscape +weh8ironmen +wehde +weight4 +weir19 +weirdo +wekkes +wenwick +weoh +weppend +weregild +werkd +wermz8 +werndoggaa +wertyer2 +wesley 256 +wesley biets +wesrrules92 +westsider011 +wet da bed +wet oven +weve +weweweweoox +wewkek +wf_solo123 +wfh atm +wfsdfvwwfsdq +wfsn +wh1tey95 +whale +whale come +whathitu +whatiswork +whats +whats skills +whatsoup +when +when I chant +where +where ask +where moon +where noon +where yat +wheresyaboy +whip2b +whipbanned +whiskey bow +whisoserious +whispery +white +whitedog8 +whitless +whizprjazpxr +whk +who is react +whoawhoami +whodo +whodoyouknow +whololo30 +whoopdidy +whoppinknob +whoscherry +whotf +whtmicrowave +whuchaka v +why afk +why ego +whyaintyoume +whyamisofat +whynotp2p +whyuboolyme +whyzerkbro +wi f +wibeton +widefang +wiegehtsmir +wienerbread +wife4sale +wifes +wifibananas +wiidziss +wikedfix +wil je ket +wildarko +wildberryRS +wildcheery77 +wildystuff6 +will +will vv +will win 2 +will_mello +willc893 +willeehawk +willie432 +willis28 +willmissit +willmott +willsand2405 +willsuck4GMK +win we must +winnur +winterburnI +winterdaze +wiseguy2187 +wiseoldPapi +wiseoldnam +wispykarma +wistfulgyre +witchbladezz +witeboi +witenry +with +witnesspower +wiw +wizard129 +wizardyoda7 +wizkid499 +wjsn +wkurtin +wlkerTXrangr +wndow +wndy +wngo +woah +wocket +wodg +woesh0 +wohc +wokkejzzbak +wolfbless +wolfy +wolrus +wombo_zombo +womp +wonder_wenis +wonnie +wonniwonkaka +woodchopp +woofmaster +wooohooo +wooooom +woopingcrab +wooski43 +wootex +woox +woox10k +wormple +woshishabi +wowda +woxzard +wrdd +wrdflexoke +wrong ranger +wrsrule +wruhtra +wsodonnell76 +wsvolt +wtbzenyte +wtffixthis +wtfix +wubzh8black +wucebrilllis +wuckedenergy +wucy +wudi +wudup9696 +wuil10 +wulfwulfson +wussupfool +wutzgood +wutzit +wwTakun +wweadge2 +www +wwwMusic-Map +wyat +wyattearp99 +wyked +wytch +wyverns4days +wzav423 +wzrdddddyo +wzrds +wzs +x 0lev x +x ABBlE +x Argonath x +x Chainz x +x Chelli +x D E E x +x Dante +x Fabinho +x FiFi +x Flux +x GS Cookies +x Haste +x Kane x +x Kierac x +x L i o n +x Lady +x Lafferty x +x LostBoy +x Mayhem +x Ndo +x Nex +x Not blue x +x Nym +x Pho +x Red Rum +x Ryu +x Ryuu +x Sorvete +x Verzik x +x Zela +x Zink +x a t +x e l a b +x gladiat0r +x husla +x iNtrigue +x iyad x +x lollage x +x mk ultra +x preska x +x r +x warri0r121 +x zi +x zn +x073x +x0Mag +x0Tub +x12ob1n +x1deag +x1flyx +x235 +x2u mania +x3 nuzzle +x7 Curvelo +x86 +x8737 +x8mz3hg7zm5f +xAFK_BTWx +xAbysss +xAddictive +xAeroWolf +xAndrew +xBL00DSTREAM +xBaNeSoldier +xBarlah +xBayLiss +xBeefStonks +xBeerbear +xBehavior +xBellax +xBenny +xBlackDahlia +xBongzilla +xBootySlayer +xBottleCap +xBotty +xBowlofPhox +xBrendyy +xBrimz +xBrown +xBusse +xCUFFSx +xCallT0Armsx +xCarter +xCastiiel +xCheeseheadx +xChemistry +xCherish +xChew +xChiro +xChyeaa +xClf +xClifffff +xCloudie +xCodeh +xComposure +xD1E +xDCx152 +xDOMIN1C +xDRAYx +xDab of Iron +xDaf +xDagon +xDapzz +xDat +xDevastor +xDevil +xDied +xDieter +xDijon +xDilexro +xDingy +xDora +xDoremonx +xDrawingDead +xDuckyV +xET99 +xElliott +xElsa +xEnforcerx +xEtiquette +xExclusive +xFMSx +xFailBoatx +xFirespiritx +xFlea +xFloaty +xFranku +xFraz +xFremmy +xFruity +xGallarzax +xGigz +xGoat +xGongo +xGrant +xGusBus +xH1ckz +xH4rry +xHades +xHamzha +xHannna +xHartliss +xHarty +xHayez +xHearTBow +xHerp +xHmongHerox +xHugsi +xHussla +xI3reeze +xIron Senpai +xJeb +xJiren +xJlN +xJolt +xJord +xJordd +xJulia +xJuve +xKAJJEx +xKadi +xKdpunx +xKing +xKodai +xKrab +xKril +xL2MUZZx +xLayLay +xLelooToo +xLester +xLrc +xLuXx +xLumby +xLunatiQ +xLynn +xMBx +xMEKANIKx +xMMGx +xMardy +xMarkos +xMassx +xMatah +xMatty +xMedicate +xMentalXx +xMetharos +xMewzic +xMochiix +xMonkey +xMp5 +xMyrupz +xN I K Ex +xNatureladx +xNeilzus +xNerevar +xNgocdol +xNickaap +xNova +xO Poe +xOBG +xOG420 +xOnetickFap +xPager +xPedu +xPhil +xPortgas +xPussSmasher +xQSS +xQuantumxx +xRICK OWENSx +xRadagonx +xRakine +xRaptor +xReaperx666x +xReckless +xRedGlow +xRefactor +xRektByAMain +xRemyLacroix +xRipple +xRivv +xRobdebankx +xRobertox22 +xRobscapes +xRxmeo +xSPAGHETTIx +xSamR +xScooter +xScribbz +xScrimp +xSecret +xSeized +xServing +xSillyCybinx +xSkizzy +xSkuffy +xSkySnow +xSlayer +xSleeper +xSleepgoodx +xSlysoft +xSnaytronSx +xSnvw +xSoKi +xSteezy +xSweetHopex +xSword +xSxAxMx +xSynn +xT o m +xT0A +xTERRIBLEx +xTKOx +xTWM +xTerpenes +xThirlmere +xTopher +xTorsti +xTransfer +xTrigger +xTwister +xVektor +xVenomx9 +xVoidRange +xW R A T Hx +xWANNTEDx +xWar +xWarface +xWillowTreex +xWillx93 +xWoke +xWoodChopx +xX Bez Xx +xXBlitzO +xXCaBiDeXx +xXDurryXx +xXGIMP420Xx +xXJoshUKXxHD +xXNaliXx +xXightx +xXshadowz7Xx +xYogibear +xZAKATAKx +xZCH +xZITOx +xZayin +xZeeBaby +xZuk +x_Goddess_xz +x_Huzy_x +x_Theron +x_x Fish +x_xMGKx_x +xaa2 +xaarpus +xal din +xangoose +xansinmybody +xaoeu +xapd +xaro +xaxon +xbox +xboxkid +xc00lxDawgx +xceasea +xcoda +xcrolles +xcvbg +xd domi +xd jumper +xdamanx +xeem +xegaF +xemulate +xenaines +xeney +xenomuslol +xenvzi +xeravier +xerkin +xexezinh0 +xfishngrillx +xfxe +xgamerxx +xhamstr +xhard82x +xhennamariax +xhoq +xi execut3 x +xi li er +xiBubbax +xiaohongshu +xiaolingxiao +xienn +ximix +xinnox +xir0nm4skx +xirampagezz +xironluckx +xiwitl +xjawz1e +xl Aaron lx +xl cook +xlDerekxl +xlReversal +xlibrio +xlr704 +xlxl xlxl +xmikeyx +xmxxmx56 +xoKt +xoRUNExo +xolindseyxo +xoreZ +xoro +xoxoverdose +xozoca +xp per hour +xp waster 47 +xpabax +xpcumsez +xpeyotex +xplo it +xpoltergiest +xpwast3d +xrated +xslayerbobx +xson +xspacedoll +xstic +xtcoming999 +xthn +xtothedee +xttx +xtyrantix +xvn +xvrph +xvza +xwl +xwuwesxdrf +xx darkminer +xxDerp +xxMatter +xxREVENANTxx +xxSabin09xx +xxSe7en +xxTanner +xxcombatgodx +xxero +xxok +xxpurskillxx +xxx2sp3cuxxx +xyujah +xyzn +xzanle +xzb +xzizzil +xzn 2 +xzwu +y om +y w +y0y0keepitup +y37ir +y8s1 +yTried +ya pig +ya winning +yaJaeT +yaboyalex +yack daniels +yacobson99 +yae +yahn +yai5 +yamawaro +yamb0 +yamsauze +yankmynads +yannickal4 +yanq10 +yaowiee +yapgragim +yasuo god69 +yayasquirrel +ydoc +ye idc +ye ki M +ye p to +yea im jebus +yeahboi9992 +yeahsmitty +yeahyoink +yearstowaste +yeastyboys +yechu +yedgy +yee yee fkrs +yeet +yellow car01 +yeniL +yerrakunt +yesigame +yesy0u +yinghao870 +yinksnerf +yinonormal +yipcl +yippie1317 +yispaulcute +ykO Ops +ykeL +yleisradio +ylliB +ym y +ymca4life +yna +yo eight +yo itz ep +yobacha +yodA +yoda +yoda monkey +yohaha123 +yolomuffin +yonex +yonghoon +yooyeet +yorkietootz +yorue +you died123 +you r a qt +youb1n +youneedcope +young meows +young vibby +youngbriks +youngmachine +youngtrop21 +youngwings +youpougou +your +your thrall +youralterego +youssef +yowasupppbra +yoyoma361 +yp +ypoodle +ypool4 +ypools +yragbackward +yrhs +yribbles +ytsud mi +ytuiop +yugiiii +yuh huh +yum +yummybolete +yung +yung chubs +yung cody +yung inf +yungando +yungcozzy +yuor +yurciq +yuy165 +yves klein +yvonko +ywwoT +yxow +yyknaH J +yyttam +yyzanadu94 +yzyzyzy +z 5 x +z Animal z +z Rhodes +z Shane +z a p s +z iQ +z man827 +z0nk +z0rrda +z0up +z1ftz +z4np +z5p +z7co +zBando +zBenn +zBonesz +zCocoa +zDaremeth +zDeku +zFalcone68 +zGameDance +zGanj +zGibao +zGz +zJenga +zKamp +zKno +zKuru +zLost +zMonchi +zNico +zNolan +zRarePiece +zRavenx +zSlay +zSpaceRaptor +zSwanny +zTitan +zWxLF +za2 +za33erklan +zaaza +zacharial +zachhy +zachte +zack +zack_0333 +zacyy +zaddy +zak vol zalm +zakaru9999 +zakk0 +zakrey +zakrobgames +zalem +zancan2 +zapper920 +zarehp +zarfeq +zartrez +zasmaru +zatch_maxed +zazalover69 +zazazhizhma +zazyga +zbra +zclx +zcollins +zdi +zdin +zdya +ze4l +zeKrD +zeachh +zeall +zeano +zebakkes +zeccStake +zedabranca +zeddicus676 +zedisabled +zedzke +zeeebak +zeeno +zegg +zehstee +zeikhannes +zeker +zeldris +zelo1 +zendendead +zenmort +zensix +zenuk zay +zenyte4money +zeppelin0ooh +zeqha +zer0 +zer0sirisFHK +zerker seven +zerkhelm +zero +zero gd +zero u_u +zeroblade81 +zeroixx +zerotwonine +zeroz136 +zerzerz +zeus energy +zewos +zewzh +zhengu +zhipowerz +zi0n1 +zibri7 +ziewe +zifyr +ziggy man 77 +ziily +zilyana +zina +zina n chill +zinax +ziniD +zinzares +zionari +zippp +zirreael +ziurbtw +ziuys +ziyi_wangler +zjh +zjind +zlayaa +zlink10 +zlliM +zlowden +zmakisan +znap5 +zoan +zoboz +zohcysp +zokunashi +zole +zomff +zomgrick +zonares +zookwaa +zoomixd +zop1 +zorkie +zoro u +zouse +zparky +zppr +zq0 +zreL +zrl +zruG +zrzwns +ztaM +ztkfps +zu b +zubor1 +zuenzima +zujal +zuk a cuck +zuk xd +zuk2hard4me +zukushichi +zulogz +zulrah +zuluTriPig +zummorak +zurcc +zurlond +zuuryy +zw +zwah +zwint +zwolle +zwqpDEOXl23 +zxpf +zyeetz +zygarde92 +zygis323 +zykez +zymaa +zymz +zysuna +zzad +zzai +zzben +zzero +zzigma +zzzJonno diff --git a/Server/data/botdata/ge_bot_appearances_and_equipment.json b/Server/data/botdata/ge_bot_appearances_and_equipment.json new file mode 100644 index 0000000..a4a1bef --- /dev/null +++ b/Server/data/botdata/ge_bot_appearances_and_equipment.json @@ -0,0 +1,68 @@ +{ + "noob": [ + {"appearance":{"appearance_cache":[{"color":"0","look":"0"},{"color":"0","look":"10"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"3","id":"1265"},{"amount":"1","charge":"1000","slot":"5","id":"1171"},{"amount":"293","charge":"1000","slot":"13","id":"877"}]}, + {"appearance":{"appearance_cache":[{"color":"1","look":"0"},{"color":"0","look":"11"},{"color":"16","look":"18"},{"color":"0","look":"27"},{"color":"0","look":"34"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"1169"},{"amount":"1","charge":"1000","slot":"2","id":"1704"},{"amount":"1","charge":"1000","slot":"3","id":"9183"},{"amount":"1","charge":"1000","slot":"4","id":"1131"},{"amount":"1","charge":"1000","slot":"7","id":"2495"},{"amount":"1","charge":"1000","slot":"9","id":"2491"},{"amount":"1","charge":"1000","slot":"10","id":"88"},{"amount":"293","charge":"1000","slot":"13","id":"877"}]}, + {"appearance":{"appearance_cache":[{"color":"0","look":"0"},{"color":"0","look":"10"},{"color":"16","look":"18"},{"color":"0","look":"106"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"1163"},{"amount":"1","charge":"1000","slot":"2","id":"1725"},{"amount":"1","charge":"1000","slot":"3","id":"5698"},{"amount":"1","charge":"1000","slot":"4","id":"1127"},{"amount":"1","charge":"1000","slot":"7","id":"1079"},{"amount":"1","charge":"1000","slot":"10","id":"3105"}]}, + {"appearance":{"appearance_cache":[{"color":"9","look":"266"},{"color":"0","look":"16"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"3","id":"1333"},{"amount":"1","charge":"1000","slot":"4","id":"1127"},{"amount":"1","charge":"1000","slot":"5","id":"1201"},{"amount":"1","charge":"1000","slot":"7","id":"1079"},{"amount":"1","charge":"1000","slot":"10","id":"11019"}]}, + {"appearance":{"appearance_cache":[{"color":"1","look":"2"},{"color":"0","look":"13"},{"color":"1","look":"18"},{"color":"0","look":"28"},{"color":"0","look":"33"},{"color":"16","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"2910"},{"amount":"1","charge":"1000","slot":"1","id":"10499"},{"amount":"1","charge":"1000","slot":"2","id":"552"},{"amount":"1","charge":"1000","slot":"3","id":"861"},{"amount":"1","charge":"1000","slot":"4","id":"544"},{"amount":"1","charge":"1000","slot":"7","id":"2497"},{"amount":"1","charge":"1000","slot":"9","id":"7458"},{"amount":"1","charge":"1000","slot":"10","id":"2904"}]}, + {"appearance":{"appearance_cache":[{"color":"12","look":"2"},{"color":"0","look":"10"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"1","id":"1007"},{"amount":"1","charge":"1000","slot":"3","id":"1381"},{"amount":"1","charge":"1000","slot":"4","id":"426"},{"amount":"1","charge":"1000","slot":"7","id":"428"}]}, +{"appearance":{"appearance_cache":[{"color":"20","look":"267"},{"color":"0","look":"12"},{"color":"0","look":"18"},{"color":"0","look":"31"},{"color":"4","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"3","id":"6908"},{"amount":"1","charge":"1000","slot":"4","id":"1135"},{"amount":"1","charge":"1000","slot":"7","id":"428"}]}, +{"appearance":{"appearance_cache":[{"color":"0","look":"0"},{"color":"0","look":"10"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"6","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"1161"},{"amount":"1","charge":"1000","slot":"3","id":"1287"},{"amount":"1","charge":"1000","slot":"4","id":"1123"},{"amount":"1","charge":"1000","slot":"5","id":"1199"},{"amount":"1","charge":"1000","slot":"7","id":"1073"}]}, +{"appearance":{"appearance_cache":[{"color":"12","look":"2"},{"color":"0","look":"16"},{"color":"6","look":"18"},{"color":"0","look":"27"},{"color":"0","look":"84"},{"color":"16","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"1153"},{"amount":"1","charge":"1000","slot":"3","id":"1363"},{"amount":"1","charge":"1000","slot":"4","id":"6184"},{"amount":"1","charge":"1000","slot":"5","id":"1540"},{"amount":"1","charge":"1000","slot":"7","id":"6185"}]}, + {"appearance":{"appearance_cache":[{"color":"12","look":"2"},{"color":"0","look":"16"},{"color":"6","look":"18"},{"color":"0","look":"27"},{"color":"0","look":"84"},{"color":"16","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"11021"},{"amount":"1","charge":"1000","slot":"1","id":"4411"},{"amount":"1","charge":"1000","slot":"2","id":"1725"},{"amount":"1","charge":"1000","slot":"3","id":"1333"},{"amount":"1","charge":"1000","slot":"4","id":"11020"},{"amount":"1","charge":"1000","slot":"5","id":"1185"},{"amount":"1","charge":"1000","slot":"7","id":"11022"},{"amount":"1","charge":"1000","slot":"10","id":"11019"}]}, + {"appearance":{"appearance_cache":[{"color":"12","look":"2"},{"color":"0","look":"16"},{"color":"6","look":"18"},{"color":"0","look":"27"},{"color":"0","look":"84"},{"color":"16","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"1949"},{"amount":"1","charge":"1000","slot":"1","id":"1007"},{"amount":"1","charge":"1000","slot":"3","id":"1381"},{"amount":"1","charge":"1000","slot":"4","id":"426"},{"amount":"1","charge":"1000","slot":"5","id":"1540"},{"amount":"1","charge":"1000","slot":"7","id":"428"}]}, + {"appearance":{"appearance_cache":[{"color":"12","look":"2"},{"color":"0","look":"16"},{"color":"6","look":"18"},{"color":"0","look":"27"},{"color":"0","look":"84"},{"color":"16","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"10774"},{"amount":"1","charge":"1000","slot":"1","id":"10069"},{"amount":"1","charge":"1000","slot":"2","id":"1725"},{"amount":"1","charge":"1000","slot":"3","id":"1333"},{"amount":"1","charge":"1000","slot":"4","id":"1125"},{"amount":"1","charge":"1000","slot":"7","id":"1077"},{"amount":"1","charge":"1000","slot":"9","id":"2997"},{"amount":"1","charge":"1000","slot":"10","id":"7114"}]} + + ], + "intermediate": [ + {"appearance":{"appearance_cache":[{"color":"0","look":"0"},{"color":"0","look":"10"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"3","id":"1265"},{"amount":"1","charge":"1000","slot":"5","id":"1171"},{"amount":"293","charge":"1000","slot":"13","id":"877"}]}, + {"appearance":{"appearance_cache":[{"color":"0","look":"1"},{"color":"0","look":"10"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"2637"},{"amount":"1","charge":"1000","slot":"1","id":"6568"},{"amount":"1","charge":"1000","slot":"2","id":"1704"},{"amount":"1","charge":"1000","slot":"3","id":"1305"},{"amount":"1","charge":"1000","slot":"4","id":"3140"},{"amount":"1","charge":"1000","slot":"5","id":"6524"},{"amount":"1","charge":"1000","slot":"7","id":"4087"},{"amount":"1","charge":"1000","slot":"9","id":"3060"},{"amount":"1","charge":"1000","slot":"10","id":"11732"},{"amount":"293","charge":"1000","slot":"13","id":"877"}]}, + {"appearance":{"appearance_cache":[{"color":"0","look":"1"},{"color":"0","look":"10"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"11674"},{"amount":"1","charge":"1000","slot":"1","id":"10720"},{"amount":"1","charge":"1000","slot":"2","id":"1725"},{"amount":"1","charge":"1000","slot":"3","id":"1387"},{"amount":"1","charge":"1000","slot":"4","id":"8839"},{"amount":"1","charge":"1000","slot":"7","id":"8840"},{"amount":"1","charge":"1000","slot":"9","id":"8842"},{"amount":"1","charge":"1000","slot":"10","id":"11732"},{"amount":"293","charge":"1000","slot":"13","id":"877"}]}, + {"appearance":{"appearance_cache":[{"color":"12","look":"261"},{"color":"0","look":"10"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"16","look":"38"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"1","id":"9805"},{"amount":"1","charge":"1000","slot":"4","id":"10348"},{"amount":"1","charge":"1000","slot":"10","id":"1837"}]}, + {"appearance":{"appearance_cache":[{"color":"12","look":"261"},{"color":"0","look":"10"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"16","look":"38"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"10392"},{"amount":"1","charge":"1000","slot":"1","id":"1007"},{"amount":"1","charge":"1000","slot":"2","id":"11113"},{"amount":"1","charge":"1000","slot":"3","id":"1387"},{"amount":"1","charge":"1000","slot":"4","id":"1117"},{"amount":"1","charge":"1000","slot":"5","id":"1173"},{"amount":"1","charge":"1000","slot":"7","id":"1075"},{"amount":"1","charge":"1000","slot":"10","id":"4129"}]}, + {"appearance":{"appearance_cache":[{"color":"1","look":"3"},{"color":"0","look":"16"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"3755"},{"amount":"1","charge":"1000","slot":"1","id":"2412"},{"amount":"1","charge":"1000","slot":"2","id":"1704"},{"amount":"1","charge":"1000","slot":"3","id":"1383"},{"amount":"1","charge":"1000","slot":"4","id":"4091"},{"amount":"1","charge":"1000","slot":"7","id":"4093"},{"amount":"1","charge":"1000","slot":"9","id":"7462"},{"amount":"1","charge":"1000","slot":"10","id":"10696"}]}, + {"appearance":{"appearance_cache":[{"color":"1","look":"3"},{"color":"0","look":"16"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"9755"},{"amount":"1","charge":"1000","slot":"1","id":"9754"},{"amount":"1","charge":"1000","slot":"2","id":"1704"},{"amount":"1","charge":"1000","slot":"3","id":"1275"},{"amount":"1","charge":"1000","slot":"4","id":"1127"},{"amount":"1","charge":"1000","slot":"7","id":"1079"},{"amount":"1","charge":"1000","slot":"10","id":"88"}]}, + {"appearance":{"appearance_cache":[{"color":"0","look":"0"},{"color":"0","look":"10"},{"color":"16","look":"18"},{"color":"0","look":"106"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"11665"},{"amount":"1","charge":"1000","slot":"1","id":"9807"},{"amount":"1","charge":"1000","slot":"2","id":"1704"},{"amount":"1","charge":"1000","slot":"3","id":"13290"},{"amount":"1","charge":"1000","slot":"4","id":"8839"},{"amount":"1","charge":"1000","slot":"5","id":"1201"},{"amount":"1","charge":"1000","slot":"7","id":"8840"},{"amount":"1","charge":"1000","slot":"9","id":"8842"},{"amount":"1","charge":"1000","slot":"10","id":"11732"}]}, + {"appearance":{"appearance_cache":[{"color":"0","look":"0"},{"color":"0","look":"10"},{"color":"16","look":"18"},{"color":"0","look":"106"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"9672"},{"amount":"1","charge":"1000","slot":"1","id":"9783"},{"amount":"1","charge":"1000","slot":"2","id":"1725"},{"amount":"1","charge":"1000","slot":"3","id":"4587"},{"amount":"1","charge":"1000","slot":"4","id":"9674"},{"amount":"1","charge":"1000","slot":"7","id":"2497"},{"amount":"1","charge":"1000","slot":"9","id":"7458"},{"amount":"1","charge":"1000","slot":"10","id":"3105"}]}, + {"appearance":{"appearance_cache":[{"color":"0","look":"0"},{"color":"0","look":"10"},{"color":"16","look":"18"},{"color":"0","look":"106"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"10828"},{"amount":"1","charge":"1000","slot":"1","id":"9763"},{"amount":"1","charge":"1000","slot":"2","id":"1725"},{"amount":"1","charge":"1000","slot":"3","id":"4587"},{"amount":"1","charge":"1000","slot":"4","id":"1127"},{"amount":"1","charge":"1000","slot":"5","id":"8850"},{"amount":"1","charge":"1000","slot":"7","id":"1079"},{"amount":"1","charge":"1000","slot":"10","id":"3105"}]}, + {"appearance":{"appearance_cache":[{"color":"9","look":"266"},{"color":"0","look":"16"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"10828"},{"amount":"1","charge":"1000","slot":"1","id":"2414"},{"amount":"1","charge":"1000","slot":"2","id":"1704"},{"amount":"1","charge":"1000","slot":"3","id":"4587"},{"amount":"1","charge":"1000","slot":"4","id":"1127"},{"amount":"1","charge":"1000","slot":"5","id":"1201"},{"amount":"1","charge":"1000","slot":"7","id":"4087"},{"amount":"1","charge":"1000","slot":"10","id":"11732"}]}, + {"appearance":{"appearance_cache":[{"color":"1","look":"2"},{"color":"0","look":"13"},{"color":"1","look":"18"},{"color":"0","look":"28"},{"color":"0","look":"33"},{"color":"16","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"1","id":"9802"}]}, + {"appearance":{"appearance_cache":[{"color":"1","look":"2"},{"color":"0","look":"13"},{"color":"1","look":"18"},{"color":"0","look":"28"},{"color":"0","look":"33"},{"color":"16","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"6182"},{"amount":"1","charge":"1000","slot":"1","id":"4355"},{"amount":"1","charge":"1000","slot":"2","id":"1478"},{"amount":"1","charge":"1000","slot":"3","id":"9185"},{"amount":"1","charge":"1000","slot":"4","id":"544"},{"amount":"1","charge":"1000","slot":"7","id":"2497"}]} , + {"appearance":{"appearance_cache":[{"color":"1","look":"1"},{"color":"0","look":"10"},{"color":"14","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"20","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"1","id":"10071"},{"amount":"1","charge":"1000","slot":"2","id":"1704"},{"amount":"1","charge":"1000","slot":"3","id":"8872"},{"amount":"1","charge":"1000","slot":"9","id":"1059"},{"amount":"1","charge":"1000","slot":"10","id":"88"}]}, +{"appearance":{"appearance_cache":[{"color":"20","look":"278"},{"color":"0","look":"1000"},{"color":"0","look":"56"},{"color":"0","look":"61"},{"color":"0","look":"68"},{"color":"0","look":"70"},{"color":"0","look":"79"}],"gender":"1"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"1149"},{"amount":"1","charge":"1000","slot":"1","id":"6568"},{"amount":"1","charge":"1000","slot":"2","id":"1704"},{"amount":"1","charge":"1000","slot":"3","id":"1305"},{"amount":"1","charge":"1000","slot":"4","id":"2623"},{"amount":"1","charge":"1000","slot":"5","id":"6524"},{"amount":"1","charge":"1000","slot":"7","id":"4087"},{"amount":"1","charge":"1000","slot":"10","id":"11732"}]}, + {"appearance":{"appearance_cache":[{"color":"20","look":"1"},{"color":"0","look":"14"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"1","id":"4413"},{"amount":"1","charge":"1000","slot":"3","id":"1271"},{"amount":"1","charge":"1000","slot":"4","id":"1123"},{"amount":"1","charge":"1000","slot":"7","id":"1073"}]}, +{"appearance":{"appearance_cache":[{"color":"20","look":"1"},{"color":"0","look":"14"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"3751"},{"amount":"1","charge":"1000","slot":"1","id":"10499"},{"amount":"1","charge":"1000","slot":"2","id":"1704"},{"amount":"1","charge":"1000","slot":"3","id":"4587"},{"amount":"1","charge":"1000","slot":"4","id":"546"},{"amount":"1","charge":"1000","slot":"5","id":"1201"},{"amount":"1","charge":"1000","slot":"7","id":"548"},{"amount":"1","charge":"1000","slot":"10","id":"3105"}]}, + {"appearance":{"appearance_cache":[{"color":"0","look":"0"},{"color":"0","look":"10"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"14120"},{"amount":"1","charge":"1000","slot":"2","id":"9470"},{"amount":"1","charge":"1000","slot":"3","id":"1305"},{"amount":"1","charge":"1000","slot":"4","id":"10822"},{"amount":"1","charge":"1000","slot":"5","id":"1540"},{"amount":"1","charge":"1000","slot":"7","id":"10824"}]}, + {"appearance":{"appearance_cache":[{"color":"0","look":"0"},{"color":"0","look":"10"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"5","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"1153"},{"amount":"1","charge":"1000","slot":"2","id":"1704"},{"amount":"1","charge":"1000","slot":"3","id":"4153"},{"amount":"1","charge":"1000","slot":"4","id":"1115"},{"amount":"1","charge":"1000","slot":"7","id":"1067"}]}, + {"appearance":{"appearance_cache":[{"color":"0","look":"0"},{"color":"0","look":"10"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"5","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"3751"},{"amount":"1","charge":"1000","slot":"1","id":"6568"},{"amount":"1","charge":"1000","slot":"2","id":"1704"},{"amount":"1","charge":"1000","slot":"3","id":"5698"},{"amount":"1","charge":"1000","slot":"4","id":"1127"},{"amount":"1","charge":"1000","slot":"5","id":"8847"},{"amount":"1","charge":"1000","slot":"7","id":"1079"},{"amount":"1","charge":"1000","slot":"10","id":"4131"}]}, + {"appearance":{"appearance_cache":[{"color":"0","look":"0"},{"color":"0","look":"10"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"5","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"1163"},{"amount":"1","charge":"1000","slot":"2","id":"3853"},{"amount":"1","charge":"1000","slot":"3","id":"1373"},{"amount":"1","charge":"1000","slot":"4","id":"1127"},{"amount":"1","charge":"1000","slot":"5","id":"1201"},{"amount":"1","charge":"1000","slot":"7","id":"1079"}]} , + {"appearance":{"appearance_cache":[{"color":"0","look":"0"},{"color":"0","look":"10"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"5","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"11021"},{"amount":"1","charge":"1000","slot":"2","id":"3853"},{"amount":"1","charge":"1000","slot":"3","id":"1373"},{"amount":"1","charge":"1000","slot":"4","id":"1127"},{"amount":"1","charge":"1000","slot":"5","id":"1201"},{"amount":"1","charge":"1000","slot":"7","id":"1079"}]}, + {"appearance":{"appearance_cache":[{"color":"0","look":"0"},{"color":"0","look":"10"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"5","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"11021"},{"amount":"1","charge":"1000","slot":"1","id":"14081"},{"amount":"1","charge":"1000","slot":"2","id":"3853"},{"amount":"1","charge":"1000","slot":"3","id":"1373"},{"amount":"1","charge":"1000","slot":"4","id":"6184"},{"amount":"1","charge":"1000","slot":"7","id":"6185"},{"amount":"1","charge":"1000","slot":"10","id":"3107"}]}, +{"appearance":{"appearance_cache":[{"color":"0","look":"0"},{"color":"0","look":"10"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"6","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"6182"},{"amount":"1","charge":"1000","slot":"1","id":"10636"},{"amount":"1","charge":"1000","slot":"2","id":"1704"},{"amount":"1","charge":"1000","slot":"3","id":"1371"},{"amount":"1","charge":"1000","slot":"4","id":"10633"},{"amount":"1","charge":"1000","slot":"5","id":"3122"},{"amount":"1","charge":"1000","slot":"7","id":"6181"}]}, +{"appearance":{"appearance_cache":[{"color":"12","look":"2"},{"color":"0","look":"16"},{"color":"6","look":"18"},{"color":"0","look":"27"},{"color":"0","look":"84"},{"color":"16","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"1","id":"10071"},{"amount":"1","charge":"1000","slot":"2","id":"1704"},{"amount":"1","charge":"1000","slot":"3","id":"1381"},{"amount":"1","charge":"1000","slot":"10","id":"88"}]} + + ], + "veteran": [ + {"appearance":{"appearance_cache":[{"color":"0","look":"0"},{"color":"0","look":"10"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"1038"},{"amount":"1","charge":"1000","slot":"1","id":"6570"},{"amount":"1","charge":"1000","slot":"2","id":"10360"},{"amount":"1","charge":"1000","slot":"3","id":"3053"},{"amount":"1","charge":"1000","slot":"4","id":"3140"},{"amount":"1","charge":"1000","slot":"5","id":"1171"},{"amount":"1","charge":"1000","slot":"7","id":"10394"},{"amount":"293","charge":"1000","slot":"13","id":"877"}]}, + {"appearance":{"appearance_cache":[{"color":"4","look":"48"},{"color":"0","look":"1000"},{"color":"0","look":"56"},{"color":"0","look":"61"},{"color":"0","look":"68"},{"color":"0","look":"70"},{"color":"0","look":"79"}],"gender":"1"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"1038"},{"amount":"1","charge":"1000","slot":"1","id":"6570"},{"amount":"1","charge":"1000","slot":"2","id":"10360"},{"amount":"1","charge":"1000","slot":"3","id":"3053"},{"amount":"1","charge":"1000","slot":"4","id":"3140"},{"amount":"1","charge":"1000","slot":"5","id":"1171"},{"amount":"1","charge":"1000","slot":"7","id":"10394"},{"amount":"293","charge":"1000","slot":"13","id":"877"}]}, + {"appearance":{"appearance_cache":[{"color":"4","look":"48"},{"color":"0","look":"1000"},{"color":"0","look":"56"},{"color":"0","look":"61"},{"color":"0","look":"68"},{"color":"0","look":"70"},{"color":"0","look":"79"}],"gender":"1"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"9950"},{"amount":"1","charge":"1000","slot":"1","id":"6570"},{"amount":"1","charge":"1000","slot":"2","id":"1704"},{"amount":"1","charge":"1000","slot":"3","id":"7668"},{"amount":"1","charge":"1000","slot":"4","id":"2503"},{"amount":"1","charge":"1000","slot":"7","id":"2497"},{"amount":"1","charge":"1000","slot":"9","id":"5556"},{"amount":"1","charge":"1000","slot":"10","id":"11732"},{"amount":"293","charge":"1000","slot":"13","id":"877"}]}, + {"appearance":{"appearance_cache":[{"color":"12","look":"261"},{"color":"0","look":"10"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"16","look":"38"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"1","id":"9805"},{"amount":"1","charge":"1000","slot":"4","id":"10348"},{"amount":"1","charge":"1000","slot":"10","id":"1837"}]}, + {"appearance":{"appearance_cache":[{"color":"1","look":"3"},{"color":"0","look":"16"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"1","id":"9807"},{"amount":"1","charge":"1000","slot":"2","id":"1656"},{"amount":"1","charge":"1000","slot":"4","id":"1127"},{"amount":"1","charge":"1000","slot":"7","id":"1079"},{"amount":"1","charge":"1000","slot":"9","id":"7462"}]}, + {"appearance":{"appearance_cache":[{"color":"1","look":"3"},{"color":"0","look":"16"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"9758"},{"amount":"1","charge":"1000","slot":"1","id":"9757"},{"amount":"1","charge":"1000","slot":"2","id":"1656"},{"amount":"1","charge":"1000","slot":"3","id":"1387"},{"amount":"1","charge":"1000","slot":"4","id":"10378"},{"amount":"1","charge":"1000","slot":"5","id":"1183"},{"amount":"1","charge":"1000","slot":"7","id":"10380"},{"amount":"1","charge":"1000","slot":"9","id":"7462"},{"amount":"1","charge":"1000","slot":"10","id":"10696"}]}, + {"appearance":{"appearance_cache":[{"color":"1","look":"3"},{"color":"0","look":"16"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"10828"},{"amount":"1","charge":"1000","slot":"1","id":"10635"},{"amount":"1","charge":"1000","slot":"2","id":"9470"},{"amount":"1","charge":"1000","slot":"3","id":"9185"},{"amount":"1","charge":"1000","slot":"4","id":"10386"},{"amount":"1","charge":"1000","slot":"5","id":"3842"},{"amount":"1","charge":"1000","slot":"7","id":"10388"},{"amount":"1","charge":"1000","slot":"10","id":"1837"}]}, + {"appearance":{"appearance_cache":[{"color":"1","look":"3"},{"color":"0","look":"16"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"9755"},{"amount":"1","charge":"1000","slot":"1","id":"9754"},{"amount":"1","charge":"1000","slot":"2","id":"1704"},{"amount":"1","charge":"1000","slot":"3","id":"1275"},{"amount":"1","charge":"1000","slot":"4","id":"1127"},{"amount":"1","charge":"1000","slot":"7","id":"1079"},{"amount":"1","charge":"1000","slot":"10","id":"88"}]}, + {"appearance":{"appearance_cache":[{"color":"0","look":"0"},{"color":"0","look":"10"},{"color":"16","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"16","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"9764"},{"amount":"1","charge":"1000","slot":"1","id":"9763"},{"amount":"1","charge":"1000","slot":"2","id":"1704"}]}, + {"appearance":{"appearance_cache":[{"color":"0","look":"0"},{"color":"0","look":"10"},{"color":"16","look":"18"},{"color":"0","look":"108"},{"color":"3","look":"34"},{"color":"16","look":"38"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"9814"},{"amount":"1","charge":"1000","slot":"1","id":"10662"}]}, + {"appearance":{"appearance_cache":[{"color":"0","look":"0"},{"color":"0","look":"10"},{"color":"16","look":"18"},{"color":"0","look":"108"},{"color":"3","look":"34"},{"color":"16","look":"38"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"9749"},{"amount":"1","charge":"1000","slot":"1","id":"10662"},{"amount":"1","charge":"1000","slot":"2","id":"6585"},{"amount":"1","charge":"1000","slot":"3","id":"5016"},{"amount":"1","charge":"1000","slot":"4","id":"13858"},{"amount":"1","charge":"1000","slot":"5","id":"7053"},{"amount":"1","charge":"1000","slot":"7","id":"13861"}]}, + {"appearance":{"appearance_cache":[{"color":"1","look":"2"},{"color":"0","look":"13"},{"color":"1","look":"18"},{"color":"0","look":"28"},{"color":"0","look":"33"},{"color":"16","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"11718"},{"amount":"1","charge":"1000","slot":"1","id":"10499"},{"amount":"1","charge":"1000","slot":"2","id":"87"},{"amount":"1","charge":"1000","slot":"3","id":"9185"},{"amount":"1","charge":"1000","slot":"4","id":"11720"},{"amount":"1","charge":"1000","slot":"5","id":"11283"},{"amount":"1","charge":"1000","slot":"7","id":"11722"},{"amount":"1","charge":"1000","slot":"9","id":"7458"},{"amount":"1","charge":"1000","slot":"10","id":"6920"}]}, + {"appearance":{"appearance_cache":[{"color":"1","look":"2"},{"color":"0","look":"13"},{"color":"1","look":"18"},{"color":"0","look":"28"},{"color":"0","look":"33"},{"color":"16","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"6918"},{"amount":"1","charge":"1000","slot":"1","id":"9771"},{"amount":"1","charge":"1000","slot":"2","id":"87"},{"amount":"1","charge":"1000","slot":"3","id":"1387"},{"amount":"1","charge":"1000","slot":"4","id":"6916"},{"amount":"1","charge":"1000","slot":"5","id":"11283"},{"amount":"1","charge":"1000","slot":"7","id":"6924"},{"amount":"1","charge":"1000","slot":"9","id":"6922"},{"amount":"1","charge":"1000","slot":"10","id":"6920"}]}, +{"appearance":{"appearance_cache":[{"color":"0","look":"45"},{"color":"0","look":"1000"},{"color":"0","look":"56"},{"color":"0","look":"61"},{"color":"6","look":"68"},{"color":"0","look":"70"},{"color":"0","look":"79"}],"gender":"1"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"2637"},{"amount":"1","charge":"1000","slot":"1","id":"9769"},{"amount":"1","charge":"1000","slot":"2","id":"1478"},{"amount":"1","charge":"1000","slot":"3","id":"4151"},{"amount":"1","charge":"1000","slot":"4","id":"10460"},{"amount":"1","charge":"1000","slot":"5","id":"3842"},{"amount":"1","charge":"1000","slot":"7","id":"10394"},{"amount":"1","charge":"1000","slot":"9","id":"2912"},{"amount":"1","charge":"1000","slot":"10","id":"2904"}]}, + {"appearance":{"appearance_cache":[{"color":"0","look":"45"},{"color":"0","look":"1000"},{"color":"0","look":"56"},{"color":"0","look":"61"},{"color":"6","look":"68"},{"color":"0","look":"70"},{"color":"0","look":"79"}],"gender":"1"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"8903"},{"amount":"1","charge":"1000","slot":"1","id":"9807"},{"amount":"1","charge":"1000","slot":"2","id":"6585"},{"amount":"1","charge":"1000","slot":"3","id":"4151"},{"amount":"1","charge":"1000","slot":"4","id":"14479"},{"amount":"1","charge":"1000","slot":"5","id":"1187"},{"amount":"1","charge":"1000","slot":"7","id":"4087"},{"amount":"1","charge":"1000","slot":"9","id":"2912"},{"amount":"1","charge":"1000","slot":"10","id":"11732"}]}, +{"appearance":{"appearance_cache":[{"color":"20","look":"278"},{"color":"0","look":"1000"},{"color":"0","look":"56"},{"color":"0","look":"61"},{"color":"0","look":"68"},{"color":"0","look":"70"},{"color":"0","look":"79"}],"gender":"1"},"equipment":[{"amount":"1","charge":"1000","slot":"1","id":"10635"},{"amount":"1","charge":"1000","slot":"2","id":"1704"},{"amount":"1","charge":"1000","slot":"3","id":"4151"},{"amount":"1","charge":"1000","slot":"4","id":"4757"},{"amount":"1","charge":"1000","slot":"5","id":"7053"},{"amount":"1","charge":"1000","slot":"7","id":"4759"},{"amount":"1","charge":"1000","slot":"10","id":"11732"}]}, + {"appearance":{"appearance_cache":[{"color":"20","look":"278"},{"color":"0","look":"1000"},{"color":"0","look":"56"},{"color":"0","look":"61"},{"color":"0","look":"68"},{"color":"0","look":"70"},{"color":"0","look":"79"}],"gender":"1"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"1163"},{"amount":"1","charge":"1000","slot":"1","id":"9766"},{"amount":"1","charge":"1000","slot":"2","id":"1704"},{"amount":"1","charge":"1000","slot":"3","id":"4587"},{"amount":"1","charge":"1000","slot":"4","id":"10551"},{"amount":"1","charge":"1000","slot":"5","id":"8850"},{"amount":"1","charge":"1000","slot":"7","id":"1079"},{"amount":"1","charge":"1000","slot":"9","id":"7455"}]}, +{"appearance":{"appearance_cache":[{"color":"12","look":"2"},{"color":"0","look":"10"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"0","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"2643"},{"amount":"1","charge":"1000","slot":"1","id":"10446"},{"amount":"1","charge":"1000","slot":"2","id":"6585"},{"amount":"1","charge":"1000","slot":"3","id":"4151"},{"amount":"1","charge":"1000","slot":"4","id":"4712"},{"amount":"1","charge":"1000","slot":"5","id":"8850"},{"amount":"1","charge":"1000","slot":"7","id":"4714"},{"amount":"1","charge":"1000","slot":"9","id":"7461"},{"amount":"1","charge":"1000","slot":"10","id":"11732"}]}, +{"appearance":{"appearance_cache":[{"color":"0","look":"0"},{"color":"0","look":"10"},{"color":"0","look":"18"},{"color":"0","look":"26"},{"color":"6","look":"33"},{"color":"0","look":"36"},{"color":"0","look":"42"}],"gender":"0"},"equipment":[{"amount":"1","charge":"1000","slot":"0","id":"10828"},{"amount":"1","charge":"1000","slot":"1","id":"2414"},{"amount":"1","charge":"1000","slot":"2","id":"6585"},{"amount":"1","charge":"1000","slot":"3","id":"4587"},{"amount":"1","charge":"1000","slot":"4","id":"10551"},{"amount":"1","charge":"1000","slot":"5","id":"1187"},{"amount":"1","charge":"1000","slot":"7","id":"4087"},{"amount":"1","charge":"1000","slot":"9","id":"7462"},{"amount":"1","charge":"1000","slot":"10","id":"11732"}]} + + + ] +} \ No newline at end of file diff --git a/Server/data/botdata/getnames.sh b/Server/data/botdata/getnames.sh new file mode 100755 index 0000000..cce1c43 --- /dev/null +++ b/Server/data/botdata/getnames.sh @@ -0,0 +1,4 @@ +for i in {6000..6500} +do + wget -O- "https://secure.runescape.com/m=hiscore_oldschool/overall.ws?table=0&page=$i" | grep user1= | sed 's/^.*user1=//'| sed 's/".*$//' | grep -v "Binary" >> botnames.txt +done diff --git a/Server/data/botdata/namesandarmor.txt b/Server/data/botdata/namesandarmor.txt new file mode 100644 index 0000000..1759f16 --- /dev/null +++ b/Server/data/botdata/namesandarmor.txt @@ -0,0 +1,335 @@ +XMR BTC ETH:7:0:0:0:841:0:0:0:0:0:0:1061:0: +SpinnerYOU:8:0:0:0:1277:0:1171:0:0:0:0:0:0: +im-rahha:58:0:0:0:0:0:0:0:0:0:0:0:0: +newvicn:20:0:0:0:0:0:0:0:0:0:0:0:0: +KnocktdafOut:101:0:0:0:0:0:0:0:0:0:0:0:0: +Powndrake196:3:0:0:0:0:0:0:0:0:0:0:0:0: +muppemxx:3:1038:0:0:0:0:0:0:0:0:0:0:0: +GGraft:32:1949:4335:1725:1329:546:20166:0:548:0:2922:1061:0: +OdymX:3:0:0:0:1293:1101:1175:0:1067:0:1063:0:0: +jesusj17:48:0:4391:0:843:0:0:0:0:0:2932:1061:0: +Raningblast3:3:0:0:0:1351:0:0:0:0:0:0:0:0: +65fatknife:3:0:0:0:0:0:0:0:0:0:0:0:0: +NeobilkDark:23:0:0:0:1203:0:1173:0:0:0:0:0:0: +TROXZ144POXZ:56:1161:0:1009:1301:1123:1197:0:1073:0:0:0:0: +xXMakiaXx:80:0:0:0:1381:0:0:0:1033:0:0:0:0: +Molebats1209:3:0:0:0:0:0:0:0:0:0:0:0:0: +64 Wise 1978:3:0:0:0:0:0:0:0:0:0:0:0:0: +Clue Mimic:3:0:3781:0:0:0:0:0:0:0:2922:2914:0: +claymus14:30:1157:0:0:1329:1115:1193:0:1069:0:0:0:0: +xAlexGGotYaX:10:1949:0:0:1277:0:1171:0:0:0:0:0:0: +Morerule1367:3:0:0:0:0:0:0:0:0:0:0:0:0: +77shiny1198:3:0:0:0:0:0:0:0:0:0:0:0:0: +YaelColins:40:0:0:552:9703:0:9704:0:0:0:0:0:0: +casacoima10:12:0:0:0:1277:0:1171:0:0:0:0:0:0: +MenMaster:20:0:0:0:1205:0:0:0:0:0:0:0:0: +M0L1NTR0N3:44:1949:0:1725:1357:1005:9704:0:1095:0:0:1061:0: +fdsfwrfW2E:40:0:0:0:1277:0:1171:0:0:0:0:0:0: +Lewt Bags:58:1155:4351:21149:1387:1117:1189:0:1075:0:1065:4119:0: +bierfietsss:72:1163:1019:1731:1333:1127:1201:0:1079:0:1059:9005:0: +TaDeDeBeShPa:3:0:0:0:0:0:0:0:0:0:0:0:0: +Soonride2043:3:0:0:0:0:0:0:0:0:0:0:0:0: +KolSinRa6944:3:0:0:0:0:0:0:0:0:0:0:0:0: +BoCaRefVaCyI:3:0:0:0:0:0:0:0:0:0:0:0:0: +Gerloc55:43:0:0:0:1387:0:13660:0:0:0:0:9006:0: +ChMaIvCrJanL:3:0:0:0:0:0:0:0:0:0:0:0:0: +Happier Dog:44:7136:20214:10366:1387:1844:0:0:1845:0:11858:1846:0: +emachorrr:3:0:0:0:1277:0:0:0:0:0:0:0:0: +MIDNIGHTHOUR:63:1042:0:1710:10156:6322:4156:0:1099:0:11120:0:0: +LilOmni:6:0:0:0:0:0:0:0:0:0:0:1061:0: +wef6qwe4r561:3:0:0:0:0:0:0:0:0:0:0:0:0: +Sister 13:3:12600:9793:0:20590:6186:24325:0:13288:0:0:23285:0: +IsidraJr:58:0:0:0:0:0:0:0:0:0:0:0:0: +BeDeMaSa0891:3:0:0:0:0:0:0:0:0:0:0:0:0: +JustSkillezZ:50:1017:0:0:1387:426:0:0:428:0:0:0:0: +Elcangri11:39:1017:1007:1727:1381:1035:1199:0:1033:0:1059:1061:0: +haroldas 99r:13:1017:1019:1731:843:0:0:0:1015:0:1059:1061:0: +Day Dreamer2:47:1145:0:1727:1355:1123:7352:0:1091:0:0:0:0: +venepower:67:1017:0:1731:1381:577:0:0:1033:0:1059:0:0: +GOOL19207:59:1163:0:0:1333:1123:1201:0:1079:0:0:0:0: +T A L 3 N T:67:10452:12197:6585:11785:544:12610:0:2497:0:11133:12598:0: +xz Team:30:579:4371:0:1387:577:0:0:1033:0:21816:626:0: +lWontEverDie:96:0:0:0:853:7370:0:0:1099:0:0:0:0: +WooJ:122:2986:9808:1704:3053:13106:0:0:0:0:11140:13131:0: +Zaliukas19:7:1153:1031:1478:1323:1115:1175:0:1067:0:0:0:0: +Marian Nasir:3:0:0:0:0:0:0:0:0:0:0:0:0: +laitukas29:3:0:0:0:0:0:0:0:0:0:0:0:0: +AFRODITA-23:38:0:0:0:0:0:0:0:0:0:0:0:0: +Monrojas:50:0:1029:1725:1381:0:0:0:1099:0:1065:1061:0: +stejler:114:21266:6570:19553:4151:21301:12954:0:21304:0:7462:11840:0: +Loamjytuner:3:0:0:0:0:0:0:0:0:0:0:0:0: +u smoke mid:92:12293:10499:10364:1387:1121:1197:0:1071:0:1065:11840:0: +MIMIYEEET:64:0:10499:0:861:0:0:0:0:0:0:0:0: +hamnndoza:3:1153:0:0:11709:1115:1191:0:1067:0:1063:1061:0: +4virgin:112:0:0:0:1275:0:0:0:0:0:0:0:0: +LSASORI-666:60:579:0:1731:1387:577:0:0:1011:0:0:1061:0: +12evil2175:4:0:0:0:0:0:0:0:0:0:0:0:0: +Rushkaril208:71:1153:0:1478:1331:1119:1191:0:1067:0:7595:0:0: +sneksk13:49:0:0:0:0:0:0:0:0:0:0:0:0: +M i m e s:53:0:0:0:1387:3058:0:0:3059:0:0:3061:0: +llego crispy:54:9925:0:22692:853:1123:0:0:1073:0:9922:24313:0: +dami420:71:3486:20214:1731:12389:3481:3488:0:3483:0:23261:1061:0: +Vjx:59:12455:1019:10366:1387:12451:13660:0:12447:0:2912:1061:0: +jonko_08:39:1161:0:1731:1387:1123:1197:0:1073:0:1063:1061:0: +Oliverg1995:36:6188:4351:0:837:6654:0:0:0:0:2922:0:0: +TErko SKs:20:1017:0:0:1383:0:1173:0:0:0:0:0:0: +e t h x n:67:0:0:0:1387:6654:0:0:6181:0:7595:9005:0: +Beretsand522:85:5554:0:1710:21646:5553:0:0:5555:0:5556:5557:0: +ApS Squirrel:55:1163:4325:1731:1333:1113:1201:0:1079:0:2942:1061:0: +Acazandra:60:579:4407:1727:1387:577:0:0:1011:0:24311:1061:0: +BybisTasei:112:1169:1027:1731:1387:1135:24325:0:1099:0:1065:1061:0: +WelshPro2:47:1053:0:1725:1333:544:0:0:542:0:0:1061:0: +ElwinLeong:46:1044:0:1654:851:7364:0:0:1099:0:1065:7596:0: +Squaawk:99:0:6568:0:0:0:0:0:0:0:11126:0:0: +Bread1991:4:1155:0:0:1293:1117:1171:0:1075:0:0:0:0: +Tzaska:112:1949:9781:0:6562:11854:22322:0:11856:0:11858:11860:0: +honkah0nka:120:0:0:0:1359:0:0:0:0:0:0:0:0: +VitsEco:64:7394:23300:1731:1387:7390:13660:0:7378:0:1065:23291:0: +Emer Jhon 19:62:0:0:0:1381:1035:0:0:1033:0:0:0:0: +Roberthx:55:1163:0:1725:1333:1113:1201:0:1079:0:0:0:0: +Nikitakitz:33:12283:4371:1478:1285:12277:12281:0:12285:0:11079:3061:0: +DNoancy76:3:0:0:0:0:0:0:0:0:0:0:0:0: +black chinin:34:0:0:0:0:0:0:0:0:0:0:0:0: +NO0MEERCYY:106:0:0:0:0:0:0:0:0:0:0:0:0: +Kekava:89:11862:1019:7803:1327:1125:1195:0:1077:0:0:3061:0: +Finis34:76:24305:23410:10364:1387:24307:24325:0:24309:0:24311:24313:0: +SSSniperWolf:53:23101:23099:0:11709:23369:2589:0:23095:0:23091:23093:0: +HazeyJ:49:0:0:21314:11707:0:0:0:0:0:0:4121:0: +dontbrkrules:45:0:0:0:1387:0:0:0:0:0:0:0:0: +s46gs4g6s5dg:3:0:0:0:0:0:0:0:0:0:0:0:0: +PuRe_ReVs97:39:1169:0:1704:8880:1129:0:0:1099:0:2487:0:0: +DrakenHamer:108:0:0:0:1381:1035:0:0:1033:0:0:0:0: +VoHoTi816863:3:0:0:0:0:0:0:0:0:0:0:0:0: +H 2 P:63:1053:13679:21314:1387:22695:24325:0:13288:0:0:13286:0: +Leviathan Sr:3:0:1007:0:13328:6654:0:0:6655:0:0:0:0: +Chuka Ryori:102:0:0:0:1387:0:0:0:0:0:0:0:0: +5g4sg4sg4sg:3:0:0:0:0:0:0:0:0:0:0:0:0: +Elroyfct19:8:1949:0:0:0:0:1173:0:0:0:0:0:0: +PureEffectQ:37:1161:1019:1725:1331:1123:1540:0:1073:0:1059:1061:0: +rowcharger2:58:2613:0:0:1387:2607:2611:0:3475:0:1065:0:0: +Redrani1:33:1038:0:0:0:0:0:0:0:0:0:0:0: +ottn ook eem:76:12639:9757:0:4934:13104:0:0:6185:0:0:6666:0: +UzairScape:52:0:0:0:1387:0:0:0:0:0:0:0:0: +Ultiwarriors:65:1169:4379:1731:853:1135:0:0:1099:0:1065:9006:0: +kilaSTR:21:579:4345:1725:1329:577:0:0:1081:0:0:1061:0: +homeboijones:22:0:0:0:0:0:0:0:0:0:0:0:0: +Jcc1992:9:1157:0:0:1353:1119:1193:0:1069:0:2922:0:0: +Rsk venom:69:24288:0:12002:12000:24291:6889:0:24294:0:6922:6920:0: +Paptor986:68:1949:1027:1731:1333:1113:0:0:1079:0:2902:1061:0: +BigDuncan69:42:1161:1031:1478:1333:1123:1199:0:1073:0:2922:9006:0: +Gril:34:579:0:1727:1381:581:0:0:542:0:0:0:0: +54 27:69:1163:4351:1725:1385:1113:1201:0:1079:0:1065:1061:0: +treghar:3:0:0:0:0:0:0:0:0:0:0:0:0: +TreeWise Ben:59:1017:0:1727:1387:546:0:0:548:0:0:0:0: +ladiabla6666:59:0:0:0:0:0:0:0:0:0:0:0:0: +Joekeltje05:42:1055:4399:1727:1381:1035:0:0:1033:0:0:1061:0: +Cykelpump94:68:0:0:0:1381:1035:0:0:1033:0:0:0:0: +ToP WinG:61:0:0:11113:9185:0:0:0:0:0:0:0:0: +Smigol89:75:12504:10499:1704:9185:2503:1540:0:2497:0:2491:6328:0: +6d54fd4d5:3:0:0:0:0:0:0:0:0:0:0:0:0: +JaDeLashKriT:3:0:0:0:0:0:0:0:0:0:0:0:0: +Devskii:64:1169:9783:1731:853:1129:0:0:1099:0:1065:1061:0: +AliArcher22:107:1163:4371:1725:1333:1127:1201:0:1079:0:1065:1061:0: +Y0URN0TREADY:21:11847:0:10364:667:23097:13660:0:9923:0:23091:9921:0: +Kepler16b:15:1153:0:552:1267:1115:1191:0:6181:0:1059:0:0: +JamitusDeath:63:1163:1019:0:1333:1127:1201:0:1079:0:2902:1061:0: +blib vbob:3:0:0:0:0:0:0:0:0:0:0:0:0: +FighterMan3D:3:0:0:0:1265:0:1173:0:0:0:0:0:0: +dustyturnip:54:1163:0:1478:1333:2599:1201:0:1079:0:0:9006:0: +Cucilo:63:0:0:0:0:0:0:0:0:0:0:0:0: +BrrrrCold:53:2657:1007:1731:1333:2653:2659:0:3478:0:2912:9006:0: +Nv-BlackMind:88:24315:24207:0:1271:24317:0:0:24319:0:24321:24323:0: +kjuse:71:1038:0:1731:0:9924:0:0:9923:0:9922:1837:0: +Archie b:73:12453:6568:10364:1381:7390:2621:0:7386:0:2912:11840:0: +lamarcelazaz:112:0:0:0:0:0:0:0:0:0:0:0:0: +Soni Evil:3:0:0:0:1351:0:0:0:0:0:0:0:0: +Ubertas:91:0:4323:1727:1387:0:0:0:0:0:0:3061:0: +bholehairz:24:579:4365:1727:1381:577:0:0:1011:0:2932:1061:0: +I P0p ZanZ:41:579:0:1727:1387:0:0:0:0:0:0:0:0: +mr 7ranks:94:0:0:0:0:0:0:0:0:0:0:0:0: +weedmam44:89:0:0:0:0:0:0:0:0:0:0:0:0: +Bort Goth:54:1042:4387:1478:23330:23215:7348:0:2617:0:1059:9005:0: +godkin94:43:12231:4407:1662:1387:12225:12233:0:12227:0:2922:1061:0: +zznjujkuiy:3:0:0:0:0:0:0:0:0:0:0:0:0: +Snakenaldo:30:1155:0:1731:1359:1117:1173:0:1075:0:1059:1061:0: +Osmar-Rvn:75:12455:23297:10364:1387:12451:24325:0:12447:0:0:9921:0: +J U Q:3:11850:11852:1708:10010:11854:0:0:11856:0:10075:11860:0: +batrinhos:45:6182:4349:1478:1387:6654:0:0:7380:0:1065:9005:0: +d5fd45fdfd43:3:0:0:0:0:0:0:0:0:0:0:0:0: +mhxomklo:64:12013:0:0:1275:12014:0:0:12015:0:21345:12016:0: +Jaxaloth:42:1153:0:10364:1331:1115:1191:0:1081:0:0:0:0: +DuctileMarro:5:0:0:552:1277:0:1171:0:0:0:0:0:0: +FirmGrandma:124:22326:6570:19553:22978:22327:22322:0:22328:0:22981:7159:0: +Andr3ws:51:0:0:0:0:0:0:0:0:0:2902:7596:0: +Motel IlIIlI:54:0:0:0:0:0:0:0:0:0:0:0:0: +Its yeboii:98:12434:19697:19720:1387:19958:3842:0:19964:0:4105:23285:0: +TheOverdraft:118:0:0:0:0:0:0:0:0:0:0:0:0: +jbl092191:85:2665:4357:0:0:2661:2667:0:2663:0:6720:6328:0: +NewSummerVI:79:12600:23300:10366:23279:20199:13660:0:2593:0:23091:12891:0: +hambargaman:80:1040:0:0:1387:9924:0:0:9923:0:0:9921:0: +Ivyone42:35:0:13679:0:0:0:13660:0:0:0:0:0:0: +grumpy troll:116:0:0:0:0:0:0:0:0:0:0:0:0: +xRektify:93:0:0:11107:6739:0:0:0:0:0:0:0:0: +bramboom:5:0:4407:0:1351:0:0:0:0:0:0:0:0: +wrap a joint:94:2627:9795:1725:1333:1113:0:0:1079:0:2491:11840:0: +leegon1:85:0:0:0:0:0:0:0:0:0:0:0:0: +koekeroekoe1:94:21298:6568:11128:0:21301:12954:0:21304:0:11122:11840:0: +maryamgee123:10:1153:1019:0:1381:0:1191:0:0:0:0:0:0: +zazuke2019:53:22689:13679:22692:853:22695:0:0:1099:0:0:22701:0: +Mrmeanbow:97:1163:23297:1725:1333:1127:1201:0:1079:0:0:0:0: +MagicBunny01:47:1949:0:0:0:1757:0:0:0:0:0:0:0: +el frinchy:49:0:0:0:0:0:0:0:0:0:0:0:0: +Ninja1901:50:6188:13679:0:1387:0:0:0:0:0:0:0:0: +Dilk Mud:81:12241:6570:1725:1333:12235:1191:0:1067:0:0:0:0: +zELGLw:5:0:0:0:1277:0:1171:0:0:0:0:0:0: +DeMeLo139067:3:0:0:0:0:0:0:0:0:0:0:0:0: +Sun Rocks:49:2613:0:0:1381:1035:1201:0:1033:0:0:0:0: +Black Arkan:42:2605:0:0:1331:2599:2603:0:12279:0:1063:1061:0: +xxrreexxrex:3:0:4365:0:0:0:0:0:0:0:0:0:0: +Kingdavid370:16:0:0:0:1349:0:0:0:0:0:0:0:0: +OTEguQ:5:0:0:0:1205:0:1171:0:0:0:0:1061:0: +OnlYMrSmItH:3:12845:0:22692:1419:6184:0:0:6185:0:13287:13286:0: +DinkelBrot:14:1048:13679:0:0:20184:13660:0:20187:0:3060:1837:0: +Voidsux:98:0:0:0:1359:544:0:0:542:0:0:0:0: +worchafts:3:0:0:1654:0:0:0:0:0:0:0:0:0: +1k sand crab:79:1038:23297:0:10010:1035:12335:0:1033:0:0:11840:0: +Gopherslane:101:0:0:0:0:0:0:0:0:0:0:0:0: +Firehit2:28:1165:1019:0:1329:1125:1195:0:0:0:0:1061:0: +BeanSw3de:71:2595:4335:0:1387:2591:2597:0:2593:0:24311:3061:0: +rarebreed28:42:579:0:0:1387:577:0:0:1033:0:0:0:0: +Mullac255:50:0:1019:1731:1381:6184:1540:0:6185:0:1059:1061:0: +680m:110:0:0:0:0:0:0:0:0:0:0:0:0: +Niffou:7:1153:0:0:1323:1115:1191:0:1067:0:0:0:0: +AlessandlawD:4:0:0:0:0:0:0:0:0:0:0:0:0: +chandelaaaa:52:0:0:0:1275:0:0:0:0:0:1580:0:0: +kevkeassel:8:1153:1007:1478:1323:1115:1191:0:1067:0:1059:1061:0: +RockMauler:57:0:0:0:0:0:0:0:0:0:0:0:0: +Apothus14:43:0:0:0:1387:0:0:0:0:0:0:0:0: +lilibthx3:3:0:0:0:0:0:0:0:0:0:0:0:0: +Choc Luvr:48:1949:0:0:1333:0:0:0:13288:0:1059:1061:0: +ALXNDR B:60:0:0:0:0:0:0:0:0:0:0:0:0: +crisalida1:29:0:0:0:1351:0:0:0:0:0:0:0:0: +doynana:25:1157:0:1718:2402:1129:1177:0:1095:0:1063:1061:0: +homer_1993:64:1163:4365:1731:853:1113:0:0:1099:0:1065:1061:0: +Kos Emak lol:80:1163:4367:1725:853:1135:0:0:1079:0:1065:24313:0: +chinowaggon:42:1153:0:1725:853:1101:0:0:1099:0:1065:0:0: +Raised Wood:40:1159:0:0:1333:1121:1197:0:1071:0:0:0:0: +PalavaMaa:3:21859:13679:22692:22684:0:13660:0:0:0:13287:13286:0: +adroit4559:3:0:0:0:0:0:0:0:0:0:0:0:0: +SensaiKush:85:10828:6568:6585:0:0:0:0:0:0:0:11840:0: +Neba Brat:70:0:0:0:0:0:0:0:0:0:0:0:0: +Zartharias:55:1165:0:0:1333:1125:1195:0:1077:0:0:0:0: +lioooooooooo:38:0:0:0:0:0:0:0:0:0:0:0:0: +Julle2900:54:0:0:0:0:0:0:0:0:0:0:0:0: +ItsSpectrum:92:0:0:0:0:0:0:0:0:0:0:0:0: +Pinkjoe_369:68:6182:0:0:1275:6180:0:0:6181:0:0:0:0: +iD3CAP1TATE:86:1050:0:1731:0:0:0:0:0:0:1065:23285:0: +0wnbyme0:80:2665:4355:0:1387:2661:2667:0:2663:0:1065:9005:0: +whodis1:11:1153:4351:1725:1325:1115:1191:0:1067:0:0:1061:0: +V-Caracas:75:0:0:0:1211:0:0:0:0:0:0:0:0: +Jackawoo:24:1153:1019:1009:1323:1101:1191:0:1081:0:1059:0:0: +yorwys:76:0:0:0:1357:0:0:0:2617:0:0:0:0: +ashwoog:8:0:0:0:0:0:0:0:0:0:0:0:0: +Belly111:57:1169:0:1725:1373:1129:0:0:1099:0:1065:1061:0: +rolexeshh:54:0:0:0:1381:0:0:0:0:0:0:0:0: +Flamingasz:39:1040:23297:1660:1273:0:0:0:0:0:0:0:0: +TooFreeBoy:38:1159:0:1725:1329:1121:1197:0:1071:0:7595:1061:0: +el capibara:64:0:1019:0:0:0:0:0:0:0:0:0:0: +maName1999:43:1169:0:1725:853:1115:0:0:1099:0:1065:0:0: +noobmager69:13:579:4397:1727:1381:577:0:0:1011:0:1063:1061:0: +Greg lad:53:1153:4315:1725:1373:1115:1191:0:1081:0:0:1061:0: +420 McWaffle:42:1169:4339:0:853:1129:0:0:1099:0:1065:0:0: +SwappingSpit:56:1053:4351:1725:853:1101:0:0:1099:0:1065:1061:0: +og Swervinn:74:0:0:0:0:0:0:0:0:0:0:0:0: +yurmari:41:0:0:0:1351:0:13660:0:0:0:0:0:0: +mrintensely8:120:0:0:0:0:0:0:0:0:0:0:0:0: +65s4gs6g:3:0:0:0:0:0:0:0:0:0:0:0:0: +Yippi kaye:32:5533:0:0:0:0:13660:0:0:0:0:0:0: +E D U A R DO:58:5533:0:552:1381:23404:0:0:1099:0:0:0:0: +RichBichLily:57:0:0:1710:20590:0:0:0:0:0:0:0:0: +ee PILLERI:94:0:0:0:0:0:0:0:0:0:0:0:0: +el tor001:84:0:0:1712:1381:0:0:0:0:0:0:0:0: +Ill have tht:49:6188:4325:1725:20155:1129:0:0:1099:0:1065:1061:0: +Li-Fan Wei:61:2665:1023:1731:853:2661:0:0:3479:0:1065:0:0: +CrsipDaddy69:62:1163:0:1731:1333:1127:1201:0:1079:0:1065:0:0: +50 Crow 2195:4:0:0:0:1351:0:0:0:0:0:0:0:0: +Nonce No:42:24315:13679:1725:853:24317:0:0:1099:0:1065:24323:0: +c6z0urhtkxou:3:0:0:0:0:0:0:0:0:0:0:0:0: +capulina 12:71:0:0:0:1359:0:0:0:0:0:0:0:0: +atti zuen:27:579:1019:1727:1387:577:0:0:0:0:0:0:0: +Wildmake:25:1153:1019:1725:1331:1101:1191:0:1067:0:0:1061:0: +iGod Butcher:69:2627:1027:1731:1333:1127:2629:0:2625:0:0:22701:0: +imma warlock:25:1153:0:0:1381:1115:1191:0:1067:0:1063:1061:0: +Kingviking11:50:1169:1021:1725:853:1115:0:0:1099:0:1065:1061:0: +Hookhda1995:51:1153:4365:1725:1333:1115:0:0:1067:0:0:1061:0: +OptusWIFI:27:0:4409:1727:1381:1035:0:0:1033:0:0:1061:0: +No Chance G:58:0:0:1725:853:1101:0:0:1099:0:1065:1061:0: +19F10V7XUA3L:3:0:0:0:0:0:0:0:0:0:0:0:0: +Karamjanda23:50:1169:4393:1731:853:1109:0:0:1099:0:1065:1061:0: +Duskthrow39:34:1017:4405:1478:853:1035:0:0:1099:0:0:1061:0: +skitzatics:36:0:0:1725:1331:0:0:0:1099:0:1065:0:0: +Vi Vinner:59:1153:1027:1725:853:1115:0:0:1099:0:1065:1061:0: +666 sauce:56:0:3789:10364:1333:0:0:0:0:0:1065:6666:0: +Purple Sclm:54:1169:24207:1725:853:1101:0:0:1099:0:1065:1061:0: +69leo:55:1163:1027:1478:1303:23392:1201:0:1079:0:0:0:0: +125i:77:1163:4345:1725:1333:1127:1201:0:1079:0:1065:1061:0: +Shady_4720:29:1017:4345:1727:1381:544:0:0:542:0:0:1061:0: +gotitondeck:30:1169:1019:1725:853:1129:0:0:1097:0:2912:1061:0: +Crispy chips:78:1163:1027:1731:853:1113:0:0:1099:0:1065:24313:0: +PlzRisk More:45:12518:4389:1725:853:1101:0:0:7378:0:1065:1837:0: +P K Bash Man:56:1169:0:1725:853:1129:0:0:1099:0:1065:1061:0: +Kieran2809:18:0:0:0:1355:0:0:0:0:0:0:1061:0: +Yes I m New:79:2665:1019:1731:1333:2661:2667:0:2663:0:1065:9006:0: +HMAY4QQ37YGB:3:0:0:0:0:0:0:0:0:0:0:0:0: +Soul Dig 934:50:1153:0:0:1323:1115:1191:0:1067:0:1059:1061:0: +Mr Medicated:63:1157:1027:1725:853:1119:0:0:1099:0:1065:1061:0: +Troll2k:4:1153:0:0:1277:1129:1171:0:0:0:0:1061:0: +Protect Hope:62:2665:1027:10364:853:2669:0:0:2655:0:2489:11840:0: +ITS ME KDP:14:0:0:1731:0:0:0:0:0:0:1063:1061:0: +anastasiaemp:28:1153:0:0:1277:1103:1173:0:1087:0:0:0:0: +Aka Flying:45:5527:4367:1725:853:0:0:0:0:0:1065:6666:0: +llSlayerlI:47:1169:4385:1725:853:1129:0:0:1099:0:1065:1061:0: +jO9hurley:61:1163:1021:1725:1333:1113:1201:0:1079:0:2912:1061:0: +lilaf:43:1169:0:1725:1319:1129:0:0:1099:0:1065:0:0: +Logamconner:3:0:0:0:0:0:0:0:0:0:0:0:0: +dunnbros1:64:1169:4383:1725:853:1129:0:0:1099:0:1065:1061:0: +345458472110:101:1169:4407:1725:853:1133:0:0:1099:0:1065:1061:0: +Blonkalex23:61:1163:0:1725:1333:1127:1201:0:1079:0:0:1061:0: +0hide0cry:67:0:0:1731:853:1129:0:0:1097:0:1063:0:0: +Magemac99:27:579:4365:0:1387:577:1177:0:1011:0:0:0:0: +Alcap0ny:54:1153:0:0:0:1105:0:0:1067:0:2932:1061:0: +WISDJGJJ5CK4:3:0:0:0:0:0:0:0:0:0:0:0:0: +Confiteor:81:0:0:0:853:0:0:0:0:0:0:0:0: +x Obey the:68:579:0:1727:1333:577:0:0:542:0:0:0:0: +sicriona:103:1163:1023:1725:1333:1127:1201:0:1079:0:2922:1061:0: +Deleo Hostem:74:2619:9753:1731:23334:2661:2659:0:2663:0:1065:2914:0: +K E N N O:89:10294:0:1731:1333:7372:0:0:1093:0:1065:1061:0: +T3CHe:47:579:0:1731:1333:577:0:0:1099:0:1063:0:0: +Kaiju_X:72:1169:0:1731:853:544:0:0:1099:0:1065:0:0: +Junior_steez:68:0:0:1725:1333:544:0:0:542:0:2912:1061:0: +BllI1C:52:1169:0:1725:853:1129:0:0:1099:0:1065:1061:0: +Husky Fellow:53:6335:20217:1725:853:1129:0:0:7380:0:1065:23288:0: +w33d pk u:73:1169:4373:1725:853:1135:0:0:1099:0:1065:1061:0: +Gl Im Ninat:55:1169:4333:1725:853:0:0:0:1099:0:1065:1061:0: +12iownu:56:579:0:1725:1333:577:0:0:1099:0:1065:0:0: +TernoWildust:87:0:0:1731:1381:577:0:0:542:0:1065:0:0: +xongbax:57:1169:4347:1725:853:1129:0:0:1099:0:1065:1061:0: +G0DS Of Edge:76:2673:1027:1731:1333:2669:2675:0:2671:0:1065:1061:0: +Slashz:46:1169:4351:0:853:1129:0:0:1099:0:1065:0:0: +MicKy242:66:579:1021:0:1333:1121:1197:0:1085:0:1059:1061:0: +God trust:70:0:0:1725:1333:544:0:0:1099:0:1065:0:0: +Nodak Josh:69:12283:13679:1731:853:7362:0:0:7378:0:1065:1061:0: +ryuga attak:66:1163:0:1725:1333:1113:1201:0:1079:0:0:1061:0: +OldeEnglish:74:1163:0:1731:1333:1127:0:0:1079:0:0:0:0: +Vettige Sam:28:6656:0:1654:0:6654:0:0:6655:0:2902:0:0: +sitdown:61:1169:0:1704:868:1129:0:0:2497:0:2491:1837:0: +Zamppaliin:57:0:0:0:0:0:0:0:0:0:0:0:0: +kuchar23:94:1163:1019:1725:853:1135:0:0:1079:0:1065:1061:0: +Tyuio594:69:0:0:0:0:0:0:0:0:0:0:0:0: +oZeZo:90:0:0:0:1359:0:0:0:0:0:0:0:0: +Mrmagicmatt:50:1153:4377:1725:1333:1115:0:0:1067:0:1059:1061:0: +iism0ke:51:1169:4325:1725:853:1129:0:0:1099:0:1065:626:0: +Dzestiz:3:5533:0:21314:20779:0:24325:0:3059:0:3060:3061:0: +Justiniksass:3:0:0:0:0:0:0:0:0:0:0:0:0: +rag 1:66:2619:23410:1731:853:2661:0:0:2663:0:1065:23285:0: + diff --git a/Server/data/botdata/namesandarmorscript b/Server/data/botdata/namesandarmorscript new file mode 100644 index 0000000..b22283d --- /dev/null +++ b/Server/data/botdata/namesandarmorscript @@ -0,0 +1,78 @@ +/* + +This script is run with OSBot. Created by Red Bracket. + +namesandarmor.txt has the following format: +name:cblevel:helmet:cape:neck:weapon:chest:shield:unknown:legs:unknown:gloves:boots: + +*/ + + +import org.osbot.rs07.api.def.ItemDefinition; +import org.osbot.rs07.api.model.Player; +import org.osbot.rs07.script.Script; +import org.osbot.rs07.script.ScriptManifest; + +import java.io.*; +import java.util.ArrayList; + +@ScriptManifest(name = "Fetch data10", author = "b4", version = 2, logo = "", info = "info") +public class Reader extends Script { + + private ArrayList names = new ArrayList<>(20); + + @Override + public int onLoop() { + Player p = getPlayers().closest(o -> !names.contains(o.getName())); + if (p != null) + { + names.add(p.getName()); + String equipment = getOthersEquipment(p); + //Format: + //name:cblevel:helmet:cape:neck:weapon:chest:shield:unknown:legs:unknown:gloves:boots: + log2(p.getName() + + ":" + p.getCombatLevel() + + ":" + equipment); + } + return 50; + } + + private void log2(String msg) + { + try { + log(msg); + FileReader fr = new FileReader(getDirectoryData() + "Data.txt"); + BufferedReader br = new BufferedReader(fr); + for (String line; (line = br.readLine()) != null; ) { + if (line.split(":")[0].equals(msg.split(":")[0])) + { + log("Not adding that one, since we already have it"); + return; + } + } + + + FileWriter fw = new FileWriter(getDirectoryData() + "Data.txt", true); + BufferedWriter bw = new BufferedWriter(fw); + PrintWriter out = new PrintWriter(bw); + out.println(msg); + out.close(); + } catch (Exception e) { + log(e); + } + } + + private String getOthersEquipment(Player p) { + String equipmentList = ""; + if(p != null) { + int[] equipment = p.getDefinition().getAppearance(); + for (int value : equipment) { + if (value - 512 > 0) + equipmentList += ItemDefinition.forId(value - 512).getId() + ":"; + else + equipmentList += 0 + ":"; + } + } + return equipmentList; + } +} diff --git a/Server/data/botdata/pestcontrolcopies.txt b/Server/data/botdata/pestcontrolcopies.txt new file mode 100644 index 0000000..0fd7663 --- /dev/null +++ b/Server/data/botdata/pestcontrolcopies.txt @@ -0,0 +1,38 @@ +#Format: +#name:cblevel:helmet:cape:neck:weapon:chest:shield:unknown:legs:unknown:gloves:boots: +SirKermit:138:1149:6568:6585:4587:10564:6524:0:4585:0:1059:1061: +ceikry:110:1149:6568:6585:4587:10564:6524:0:4585:0:1059:1061: +loving puppy:95:11665:6568:6585:4587:8839:14767:0:8840:0:8842:1061: +rattle63:83:14096:10499:6585:4151:14094:14767:0:14095:0:8842:1061: +baluga:110:10828:6568:6585:4151:3140:6524:0:4087:0:8842:11732: +crabcake:115:10828:10446:6585:4151:10564:6524:0:4087:0:8842:11732: +Red:94:121:6568:10354:6585:10564:0:0:4087:0:1059:11732: +puglet:120:10828:6568:6585:11696:4757:0:0:8840:0:1059:3105: +linux:101:10828:10069:6585:4151:3140:14767:0:4087:0:1059:3105: +sicriona:103:1163:1023:6585:1333:1127:1201:0:1079:0:2922:1061:0: +czar:110:1149:6568:6585:4587:10564:6524:0:4585:0:1059:1061: +Alex:95:11665:6568:6585:4587:8839:14767:0:8840:0:8842:1061: +RedSparr0w:83:1149:6568:6585:4587:10564:6524:0:4585:0:1059:1061: +Summer:110:10828:6568:6585:4151:3140:6524:0:4087:0:8842:11732: +RedBracket:115:10828:10446:6585:13477:10564:6524:0:4087:0:8842:11732: +Woah:94:1163:6568:6585:13477:10564:0:0:4087:0:1059:11732: +SirKermit:130:10828:6568:6585:13477:4757:0:0:8840:0:1059:3105: +ceikry:95:10828:10069:6585:4151:3140:14767:0:4087:0:1059:3105: +SirKermit:138:1149:6568:6585:4587:10564:6524:0:4585:0:1059:1061: +ceikry:110:1149:6568:6585:4587:10564:6524:0:4585:0:1059:1061: +loving puppy:95:11665:6568:6585:4587:8839:14767:0:8840:0:8842:1061: +rattle63:83:14096:10499:6585:4151:14094:14767:0:14095:0:8842:1061: +baluga:110:10828:6568:6585:4151:3140:6524:0:4087:0:8842:11732: +crabcake:115:10828:10446:6585:4151:10564:6524:0:4087:0:8842:11732: +Red:94:121:6568:10354:6585:10564:0:0:4087:0:1059:11732: +puglet:120:10828:6568:6585:11696:4757:0:0:8840:0:1059:3105: +linux:101:10828:10069:6585:4151:3140:14767:0:4087:0:1059:3105: +sicriona:103:1163:1023:6585:1333:1127:1201:0:1079:0:2922:1061:0: +czar:110:1149:6568:6585:4587:10564:6524:0:4585:0:1059:1061: +Alex:95:11665:6568:6585:4587:8839:14767:0:8840:0:8842:1061: +RedSparr0w:83:1149:6568:6585:4587:10564:6524:0:4585:0:1059:1061: +Summer:110:10828:6568:6585:4151:3140:6524:0:4087:0:8842:11732: +RedBracket:115:10828:10446:6585:13477:10564:6524:0:4087:0:8842:11732: +Woah:94:1163:6568:6585:13477:10564:0:0:4087:0:1059:11732: +SirKermit:130:10828:6568:6585:13477:4757:0:0:8840:0:1059:3105: +ceikry:95:10828:10069:6585:4151:3140:14767:0:4087:0:1059:3105: \ No newline at end of file diff --git a/Server/data/cache/main_file_cache.dat2 b/Server/data/cache/main_file_cache.dat2 new file mode 100644 index 0000000..d7514d6 Binary files /dev/null and b/Server/data/cache/main_file_cache.dat2 differ diff --git a/Server/data/cache/main_file_cache.idx0 b/Server/data/cache/main_file_cache.idx0 new file mode 100644 index 0000000..29da3cf Binary files /dev/null and b/Server/data/cache/main_file_cache.idx0 differ diff --git a/Server/data/cache/main_file_cache.idx1 b/Server/data/cache/main_file_cache.idx1 new file mode 100644 index 0000000..ed15fcd Binary files /dev/null and b/Server/data/cache/main_file_cache.idx1 differ diff --git a/Server/data/cache/main_file_cache.idx10 b/Server/data/cache/main_file_cache.idx10 new file mode 100644 index 0000000..59d2161 Binary files /dev/null and b/Server/data/cache/main_file_cache.idx10 differ diff --git a/Server/data/cache/main_file_cache.idx11 b/Server/data/cache/main_file_cache.idx11 new file mode 100644 index 0000000..6dccb5f Binary files /dev/null and b/Server/data/cache/main_file_cache.idx11 differ diff --git a/Server/data/cache/main_file_cache.idx12 b/Server/data/cache/main_file_cache.idx12 new file mode 100644 index 0000000..e27eb6d Binary files /dev/null and b/Server/data/cache/main_file_cache.idx12 differ diff --git a/Server/data/cache/main_file_cache.idx13 b/Server/data/cache/main_file_cache.idx13 new file mode 100644 index 0000000..8acd7ef Binary files /dev/null and b/Server/data/cache/main_file_cache.idx13 differ diff --git a/Server/data/cache/main_file_cache.idx14 b/Server/data/cache/main_file_cache.idx14 new file mode 100644 index 0000000..96c7bd0 Binary files /dev/null and b/Server/data/cache/main_file_cache.idx14 differ diff --git a/Server/data/cache/main_file_cache.idx15 b/Server/data/cache/main_file_cache.idx15 new file mode 100644 index 0000000..d504977 Binary files /dev/null and b/Server/data/cache/main_file_cache.idx15 differ diff --git a/Server/data/cache/main_file_cache.idx16 b/Server/data/cache/main_file_cache.idx16 new file mode 100644 index 0000000..ad2c1b1 Binary files /dev/null and b/Server/data/cache/main_file_cache.idx16 differ diff --git a/Server/data/cache/main_file_cache.idx17 b/Server/data/cache/main_file_cache.idx17 new file mode 100644 index 0000000..7a2a366 Binary files /dev/null and b/Server/data/cache/main_file_cache.idx17 differ diff --git a/Server/data/cache/main_file_cache.idx18 b/Server/data/cache/main_file_cache.idx18 new file mode 100644 index 0000000..b7dcc43 Binary files /dev/null and b/Server/data/cache/main_file_cache.idx18 differ diff --git a/Server/data/cache/main_file_cache.idx19 b/Server/data/cache/main_file_cache.idx19 new file mode 100644 index 0000000..da1040f Binary files /dev/null and b/Server/data/cache/main_file_cache.idx19 differ diff --git a/Server/data/cache/main_file_cache.idx2 b/Server/data/cache/main_file_cache.idx2 new file mode 100644 index 0000000..73bf75f Binary files /dev/null and b/Server/data/cache/main_file_cache.idx2 differ diff --git a/Server/data/cache/main_file_cache.idx20 b/Server/data/cache/main_file_cache.idx20 new file mode 100644 index 0000000..72c6cda Binary files /dev/null and b/Server/data/cache/main_file_cache.idx20 differ diff --git a/Server/data/cache/main_file_cache.idx21 b/Server/data/cache/main_file_cache.idx21 new file mode 100644 index 0000000..1da8fce Binary files /dev/null and b/Server/data/cache/main_file_cache.idx21 differ diff --git a/Server/data/cache/main_file_cache.idx22 b/Server/data/cache/main_file_cache.idx22 new file mode 100644 index 0000000..caee83c Binary files /dev/null and b/Server/data/cache/main_file_cache.idx22 differ diff --git a/Server/data/cache/main_file_cache.idx23 b/Server/data/cache/main_file_cache.idx23 new file mode 100644 index 0000000..0d03d75 Binary files /dev/null and b/Server/data/cache/main_file_cache.idx23 differ diff --git a/Server/data/cache/main_file_cache.idx24 b/Server/data/cache/main_file_cache.idx24 new file mode 100644 index 0000000..29172b7 Binary files /dev/null and b/Server/data/cache/main_file_cache.idx24 differ diff --git a/Server/data/cache/main_file_cache.idx25 b/Server/data/cache/main_file_cache.idx25 new file mode 100644 index 0000000..dcc8774 Binary files /dev/null and b/Server/data/cache/main_file_cache.idx25 differ diff --git a/Server/data/cache/main_file_cache.idx255 b/Server/data/cache/main_file_cache.idx255 new file mode 100644 index 0000000..6f133c7 Binary files /dev/null and b/Server/data/cache/main_file_cache.idx255 differ diff --git a/Server/data/cache/main_file_cache.idx26 b/Server/data/cache/main_file_cache.idx26 new file mode 100644 index 0000000..e3be0f5 Binary files /dev/null and b/Server/data/cache/main_file_cache.idx26 differ diff --git a/Server/data/cache/main_file_cache.idx27 b/Server/data/cache/main_file_cache.idx27 new file mode 100644 index 0000000..24e8b4b Binary files /dev/null and b/Server/data/cache/main_file_cache.idx27 differ diff --git a/Server/data/cache/main_file_cache.idx28 b/Server/data/cache/main_file_cache.idx28 new file mode 100644 index 0000000..681e537 Binary files /dev/null and b/Server/data/cache/main_file_cache.idx28 differ diff --git a/Server/data/cache/main_file_cache.idx3 b/Server/data/cache/main_file_cache.idx3 new file mode 100644 index 0000000..8dfb06a Binary files /dev/null and b/Server/data/cache/main_file_cache.idx3 differ diff --git a/Server/data/cache/main_file_cache.idx4 b/Server/data/cache/main_file_cache.idx4 new file mode 100644 index 0000000..8c2eb47 Binary files /dev/null and b/Server/data/cache/main_file_cache.idx4 differ diff --git a/Server/data/cache/main_file_cache.idx5 b/Server/data/cache/main_file_cache.idx5 new file mode 100644 index 0000000..cb88101 Binary files /dev/null and b/Server/data/cache/main_file_cache.idx5 differ diff --git a/Server/data/cache/main_file_cache.idx6 b/Server/data/cache/main_file_cache.idx6 new file mode 100644 index 0000000..899c420 Binary files /dev/null and b/Server/data/cache/main_file_cache.idx6 differ diff --git a/Server/data/cache/main_file_cache.idx7 b/Server/data/cache/main_file_cache.idx7 new file mode 100644 index 0000000..7dc29a6 Binary files /dev/null and b/Server/data/cache/main_file_cache.idx7 differ diff --git a/Server/data/cache/main_file_cache.idx8 b/Server/data/cache/main_file_cache.idx8 new file mode 100644 index 0000000..3c213c6 Binary files /dev/null and b/Server/data/cache/main_file_cache.idx8 differ diff --git a/Server/data/cache/main_file_cache.idx9 b/Server/data/cache/main_file_cache.idx9 new file mode 100644 index 0000000..a8e00ff Binary files /dev/null and b/Server/data/cache/main_file_cache.idx9 differ diff --git a/Server/data/configs/account_limit_exceptions.conf b/Server/data/configs/account_limit_exceptions.conf new file mode 100644 index 0000000..c412ca2 --- /dev/null +++ b/Server/data/configs/account_limit_exceptions.conf @@ -0,0 +1,2 @@ +[exceptions] +"127.0.0.1" = 5 \ No newline at end of file diff --git a/Server/data/configs/ammo_configs.json b/Server/data/configs/ammo_configs.json new file mode 100644 index 0000000..4cc7dbc --- /dev/null +++ b/Server/data/configs/ammo_configs.json @@ -0,0 +1,1770 @@ +[ + { + "itemId": "78", + "name": "Ice arrows", + "start_graphic": "25,96", + "darkbow_graphic": "1110,96", + "projectile": "16,40,36,41,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "598", + "name": "Bronze fire arrows", + "start_graphic": "26,96", + "darkbow_graphic": "1113,96", + "projectile": "17,40,36,41,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "732", + "name": "Holy water", + "start_graphic": "193,0", + "darkbow_graphic": "", + "projectile": "192,40,36,32,32,15,0", + "poison_damage": "0" + }, + { + "itemId": "800", + "name": "Bronze thrownaxe", + "start_graphic": "43,96", + "darkbow_graphic": "", + "projectile": "36,40,36,32,32,15,0", + "poison_damage": "0" + }, + { + "itemId": "801", + "name": "Iron thrownaxe", + "start_graphic": "42,96", + "darkbow_graphic": "", + "projectile": "35,40,36,32,32,15,0", + "poison_damage": "0" + }, + { + "itemId": "802", + "name": "Steel thrownaxe", + "start_graphic": "44,96", + "darkbow_graphic": "", + "projectile": "37,40,36,32,32,15,0", + "poison_damage": "0" + }, + { + "itemId": "803", + "name": "Mithril thrownaxe", + "start_graphic": "45,96", + "darkbow_graphic": "", + "projectile": "38,40,36,32,32,15,0", + "poison_damage": "0" + }, + { + "itemId": "804", + "name": "Adamant thrownaxe", + "start_graphic": "46,96", + "darkbow_graphic": "", + "projectile": "39,40,36,32,32,15,0", + "poison_damage": "0" + }, + { + "itemId": "805", + "name": "Rune thrownaxe", + "start_graphic": "48,96", + "darkbow_graphic": "", + "projectile": "41,40,36,32,32,15,0", + "poison_damage": "0" + }, + { + "itemId": "806", + "name": "Bronze dart", + "start_graphic": "232,96", + "darkbow_graphic": "", + "projectile": "226,40,36,32,32,15,0", + "poison_damage": "0" + }, + { + "itemId": "807", + "name": "Iron dart", + "start_graphic": "233,96", + "darkbow_graphic": "", + "projectile": "227,40,36,32,32,15,0", + "poison_damage": "0" + }, + { + "itemId": "808", + "name": "Steel dart", + "start_graphic": "234,96", + "darkbow_graphic": "", + "projectile": "228,40,36,32,32,15,0", + "poison_damage": "0" + }, + { + "itemId": "809", + "name": "Mithril dart", + "start_graphic": "235,96", + "darkbow_graphic": "", + "projectile": "229,40,36,32,32,15,0", + "poison_damage": "0" + }, + { + "itemId": "810", + "name": "Adamant dart", + "start_graphic": "236,96", + "darkbow_graphic": "", + "projectile": "230,40,36,32,32,15,0", + "poison_damage": "0" + }, + { + "itemId": "811", + "name": "Rune dart", + "start_graphic": "237,96", + "darkbow_graphic": "", + "projectile": "231,40,36,32,32,15,0", + "poison_damage": "0" + }, + { + "itemId": "812", + "name": "Bronze dart(p)", + "start_graphic": "232,96", + "darkbow_graphic": "", + "projectile": "226,40,36,32,32,15,0", + "poison_damage": "28" + }, + { + "itemId": "813", + "name": "Iron dart(p)", + "start_graphic": "233,96", + "darkbow_graphic": "", + "projectile": "227,40,36,32,32,15,0", + "poison_damage": "28" + }, + { + "itemId": "814", + "name": "Steel dart(p)", + "start_graphic": "234,96", + "darkbow_graphic": "", + "projectile": "228,40,36,32,32,15,0", + "poison_damage": "28" + }, + { + "itemId": "815", + "name": "Mithril dart(p)", + "start_graphic": "235,96", + "darkbow_graphic": "", + "projectile": "229,40,36,32,32,15,0", + "poison_damage": "28" + }, + { + "itemId": "816", + "name": "Adamant dart(p)", + "start_graphic": "236,96", + "darkbow_graphic": "", + "projectile": "230,40,36,32,32,15,0", + "poison_damage": "28" + }, + { + "itemId": "817", + "name": "Rune dart(p)", + "start_graphic": "237,96", + "darkbow_graphic": "", + "projectile": "231,40,36,32,32,15,0", + "poison_damage": "28" + }, + { + "itemId": "825", + "name": "Bronze javelin", + "start_graphic": "206,96", + "darkbow_graphic": "", + "projectile": "200,40,36,32,32,15,0", + "poison_damage": "0" + }, + { + "itemId": "826", + "name": "Iron javelin", + "start_graphic": "207,96", + "darkbow_graphic": "", + "projectile": "201,40,36,32,32,15,0", + "poison_damage": "0" + }, + { + "itemId": "827", + "name": "Steel javelin", + "start_graphic": "208,96", + "darkbow_graphic": "", + "projectile": "202,40,36,32,32,15,0", + "poison_damage": "0" + }, + { + "itemId": "828", + "name": "Mithril javelin", + "start_graphic": "209,96", + "darkbow_graphic": "", + "projectile": "203,40,36,32,32,15,0", + "poison_damage": "0" + }, + { + "itemId": "829", + "name": "Adamant javelin", + "start_graphic": "210,96", + "darkbow_graphic": "", + "projectile": "204,40,36,32,32,15,0", + "poison_damage": "0" + }, + { + "itemId": "830", + "name": "Rune javelin", + "start_graphic": "211,96", + "darkbow_graphic": "", + "projectile": "205,40,36,32,32,15,0", + "poison_damage": "0" + }, + { + "itemId": "831", + "name": "Bronze javelin(p)", + "start_graphic": "206,96", + "darkbow_graphic": "", + "projectile": "200,40,36,32,32,15,0", + "poison_damage": "28" + }, + { + "itemId": "832", + "name": "Iron javelin(p)", + "start_graphic": "207,96", + "darkbow_graphic": "", + "projectile": "201,40,36,32,32,15,0", + "poison_damage": "28" + }, + { + "itemId": "833", + "name": "Steel javelin(p)", + "start_graphic": "208,96", + "darkbow_graphic": "", + "projectile": "202,40,36,32,32,15,0", + "poison_damage": "28" + }, + { + "itemId": "834", + "name": "Mithril javelin(p)", + "start_graphic": "209,96", + "darkbow_graphic": "", + "projectile": "203,40,36,32,32,15,0", + "poison_damage": "28" + }, + { + "itemId": "835", + "name": "Adamant javelin(p)", + "start_graphic": "210,96", + "darkbow_graphic": "", + "projectile": "204,40,36,32,32,15,0", + "poison_damage": "28" + }, + { + "itemId": "836", + "name": "Rune javelin(p)", + "start_graphic": "211,96", + "darkbow_graphic": "", + "projectile": "205,40,36,32,32,15,0", + "poison_damage": "28" + }, + { + "itemId": "863", + "name": "Iron knife", + "start_graphic": "220,96", + "darkbow_graphic": "", + "projectile": "213,40,36,32,32,15,0", + "poison_damage": "0" + }, + { + "itemId": "864", + "name": "Bronze knife", + "start_graphic": "219,96", + "darkbow_graphic": "", + "projectile": "212,40,36,32,32,15,0", + "poison_damage": "0" + }, + { + "itemId": "865", + "name": "Steel knife", + "start_graphic": "221,96", + "darkbow_graphic": "", + "projectile": "214,40,36,32,32,15,0", + "poison_damage": "0" + }, + { + "itemId": "866", + "name": "Mithril knife", + "start_graphic": "223,96", + "darkbow_graphic": "", + "projectile": "216,40,36,32,32,15,0", + "poison_damage": "0" + }, + { + "itemId": "867", + "name": "Adamant knife", + "start_graphic": "224,96", + "darkbow_graphic": "", + "projectile": "217,40,36,32,32,15,0", + "poison_damage": "0" + }, + { + "itemId": "868", + "name": "Rune knife", + "start_graphic": "225,96", + "darkbow_graphic": "", + "projectile": "218,40,36,32,32,15,0", + "poison_damage": "0" + }, + { + "itemId": "869", + "name": "Black knife", + "start_graphic": "222,96", + "darkbow_graphic": "", + "projectile": "215,40,36,32,32,15,0", + "poison_damage": "0" + }, + { + "itemId": "870", + "name": "Bronze knife(p)", + "start_graphic": "219,96", + "darkbow_graphic": "", + "projectile": "212,40,36,32,32,15,0", + "poison_damage": "28" + }, + { + "itemId": "871", + "name": "Iron knife(p)", + "start_graphic": "220,96", + "darkbow_graphic": "", + "projectile": "213,40,36,32,32,15,0", + "poison_damage": "28" + }, + { + "itemId": "872", + "name": "Steel knife(p)", + "start_graphic": "221,96", + "darkbow_graphic": "", + "projectile": "214,40,36,32,32,15,0", + "poison_damage": "28" + }, + { + "itemId": "873", + "name": "Mithril knife(p)", + "start_graphic": "223,96", + "darkbow_graphic": "", + "projectile": "216,40,36,32,32,15,0", + "poison_damage": "28" + }, + { + "itemId": "874", + "name": "Black knife(p)", + "start_graphic": "222,96", + "darkbow_graphic": "", + "projectile": "215,40,36,32,32,15,0", + "poison_damage": "28" + }, + { + "itemId": "875", + "name": "Adamant knife(p)", + "start_graphic": "224,96", + "darkbow_graphic": "", + "projectile": "217,40,36,32,32,15,0", + "poison_damage": "28" + }, + { + "itemId": "876", + "name": "Rune knife(p)", + "start_graphic": "225,96", + "darkbow_graphic": "", + "projectile": "218,40,36,32,32,15,0", + "poison_damage": "28" + }, + { + "itemId": "877", + "name": "Bronze bolts", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "0" + }, + { + "itemId": "878", + "name": "Bronze bolts(p)", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "28" + }, + { + "itemId": "879", + "name": "Opal bolts", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "0" + }, + { + "itemId": "880", + "name": "Pearl bolts", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "0" + }, + { + "itemId": "882", + "name": "Bronze arrow", + "start_graphic": "19,96", + "darkbow_graphic": "1104,96", + "projectile": "10,40,36,41,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "883", + "name": "Bronze arrow(p)", + "start_graphic": "19,96", + "darkbow_graphic": "1104,96", + "projectile": "10,40,36,41,46,5,0", + "poison_damage": "28" + }, + { + "itemId": "884", + "name": "Iron arrow", + "start_graphic": "18,96", + "darkbow_graphic": "1105,96", + "projectile": "9,40,36,41,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "885", + "name": "Iron arrow(p)", + "start_graphic": "18,96", + "darkbow_graphic": "1105,96", + "projectile": "9,40,36,41,46,5,0", + "poison_damage": "28" + }, + { + "itemId": "886", + "name": "Steel arrow", + "start_graphic": "20,96", + "darkbow_graphic": "1106,96", + "projectile": "11,40,36,41,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "887", + "name": "Steel arrow(p)", + "start_graphic": "20,96", + "darkbow_graphic": "1106,96", + "projectile": "11,40,36,41,46,5,0", + "poison_damage": "28" + }, + { + "itemId": "888", + "name": "Mithril arrow", + "start_graphic": "21,96", + "darkbow_graphic": "1107,96", + "projectile": "12,40,36,41,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "889", + "name": "Mithril arrow(p)", + "start_graphic": "21,96", + "darkbow_graphic": "1107,96", + "projectile": "12,40,36,41,46,5,0", + "poison_damage": "28" + }, + { + "itemId": "890", + "name": "Adamant arrow", + "start_graphic": "22,96", + "darkbow_graphic": "1108,96", + "projectile": "13,40,36,41,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "891", + "name": "Adamant arrow(p)", + "start_graphic": "22,96", + "darkbow_graphic": "1108,96", + "projectile": "13,40,36,41,46,5,0", + "poison_damage": "28" + }, + { + "itemId": "892", + "name": "Rune arrow", + "start_graphic": "24,96", + "darkbow_graphic": "1109,96", + "projectile": "15,40,36,41,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "893", + "name": "Rune arrow(p)", + "start_graphic": "24,96", + "darkbow_graphic": "1109,96", + "projectile": "15,40,36,41,46,5,0", + "poison_damage": "28" + }, + { + "itemId": "2532", + "name": "Iron fire arrows", + "start_graphic": "26,96", + "darkbow_graphic": "1113,96", + "projectile": "17,40,36,41,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "2534", + "name": "Steel fire arrows", + "start_graphic": "26,96", + "darkbow_graphic": "1113,96", + "projectile": "17,40,36,41,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "2536", + "name": "Mithril fire arrows", + "start_graphic": "26,96", + "darkbow_graphic": "1113,96", + "projectile": "17,40,36,41,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "2538", + "name": "Adamant fire arrows", + "start_graphic": "26,96", + "darkbow_graphic": "1113,96", + "projectile": "17,40,36,41,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "2540", + "name": "Rune fire arrows", + "start_graphic": "26,96", + "darkbow_graphic": "1113,96", + "projectile": "17,40,36,41,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "2866", + "name": "Ogre arrow", + "start_graphic": "243,60", + "darkbow_graphic": "", + "projectile": "242,40,36,41,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "3093", + "name": "Black dart", + "start_graphic": "273,96", + "darkbow_graphic": "", + "projectile": "227,40,36,32,32,15,0", + "poison_damage": "0" + }, + { + "itemId": "3094", + "name": "Black dart(p)", + "start_graphic": "273,96", + "darkbow_graphic": "", + "projectile": "227,40,36,32,32,15,0", + "poison_damage": "28" + }, + { + "itemId": "4160", + "name": "Broad arrow", + "start_graphic": "325,96", + "darkbow_graphic": "1112,96", + "projectile": "326,40,36,41,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "4212", + "name": "New crystal bow", + "start_graphic": "250,96", + "darkbow_graphic": "", + "projectile": "249,40,36,45,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "4214", + "name": "Crystal bow full", + "start_graphic": "250,96", + "darkbow_graphic": "", + "projectile": "249,40,36,45,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "4215", + "name": "Crystal bow 9/10", + "start_graphic": "250,96", + "darkbow_graphic": "", + "projectile": "249,40,36,45,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "4216", + "name": "Crystal bow 8/10", + "start_graphic": "250,96", + "darkbow_graphic": "", + "projectile": "249,40,36,45,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "4217", + "name": "Crystal bow 7/10", + "start_graphic": "250,96", + "darkbow_graphic": "", + "projectile": "249,40,36,45,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "4218", + "name": "Crystal bow 6/10", + "start_graphic": "250,96", + "darkbow_graphic": "", + "projectile": "249,40,36,45,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "4219", + "name": "Crystal bow 5/10", + "start_graphic": "250,96", + "darkbow_graphic": "", + "projectile": "249,40,36,45,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "4220", + "name": "Crystal bow 4/10", + "start_graphic": "250,96", + "darkbow_graphic": "", + "projectile": "249,40,36,45,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "4221", + "name": "Crystal bow 3/10", + "start_graphic": "250,96", + "darkbow_graphic": "", + "projectile": "249,40,36,45,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "4222", + "name": "Crystal bow 2/10", + "start_graphic": "250,96", + "darkbow_graphic": "", + "projectile": "249,40,36,45,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "4223", + "name": "Crystal bow 1/10", + "start_graphic": "250,96", + "darkbow_graphic": "", + "projectile": "249,40,36,45,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "4740", + "name": "Bolt rack", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "0" + }, + { + "itemId": "4778", + "name": "Iron brutal", + "start_graphic": "18,96", + "darkbow_graphic": "", + "projectile": "9,40,36,41,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "4783", + "name": "Steel brutal", + "start_graphic": "20,96", + "darkbow_graphic": "", + "projectile": "11,40,36,41,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "4788", + "name": "Black brutal", + "start_graphic": "18,96", + "darkbow_graphic": "", + "projectile": "9,40,36,41,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "4793", + "name": "Mithril brutal", + "start_graphic": "21,96", + "darkbow_graphic": "", + "projectile": "12,40,36,41,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "4798", + "name": "Adamant brutal", + "start_graphic": "22,96", + "darkbow_graphic": "", + "projectile": "13,40,36,41,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "4803", + "name": "Rune brutal", + "start_graphic": "24,96", + "darkbow_graphic": "", + "projectile": "15,40,36,41,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "5616", + "name": "Bronze arrow(p+)", + "start_graphic": "19,96", + "darkbow_graphic": "1104,96", + "projectile": "10,40,36,41,46,5,0", + "poison_damage": "38" + }, + { + "itemId": "5617", + "name": "Iron arrow(p+)", + "start_graphic": "18,96", + "darkbow_graphic": "1105,96", + "projectile": "9,40,36,41,46,5,0", + "poison_damage": "38" + }, + { + "itemId": "5618", + "name": "Steel arrow(p+)", + "start_graphic": "20,96", + "darkbow_graphic": "1106,96", + "projectile": "11,40,36,41,46,5,0", + "poison_damage": "38" + }, + { + "itemId": "5619", + "name": "Mithril arrow(p+)", + "start_graphic": "21,96", + "darkbow_graphic": "1107,96", + "projectile": "12,40,36,41,46,5,0", + "poison_damage": "38" + }, + { + "itemId": "5620", + "name": "Adamant arrow(p+)", + "start_graphic": "22,96", + "darkbow_graphic": "1108,96", + "projectile": "13,40,36,41,46,5,0", + "poison_damage": "38" + }, + { + "itemId": "5621", + "name": "Rune arrow(p+)", + "start_graphic": "19,96", + "darkbow_graphic": "", + "projectile": "10,40,36,41,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "5622", + "name": "Bronze arrow(p++)", + "start_graphic": "19,96", + "darkbow_graphic": "1104,96", + "projectile": "10,40,36,41,46,5,0", + "poison_damage": "48" + }, + { + "itemId": "5623", + "name": "Iron arrow(p++)", + "start_graphic": "18,96", + "darkbow_graphic": "1105,96", + "projectile": "9,40,36,41,46,5,0", + "poison_damage": "48" + }, + { + "itemId": "5624", + "name": "Steel arrow(p++)", + "start_graphic": "20,96", + "darkbow_graphic": "1106,96", + "projectile": "11,40,36,41,46,5,0", + "poison_damage": "48" + }, + { + "itemId": "5625", + "name": "Mithril arrow(p++)", + "start_graphic": "21,96", + "darkbow_graphic": "1107,96", + "projectile": "12,40,36,41,46,5,0", + "poison_damage": "48" + }, + { + "itemId": "5626", + "name": "Adamant arrow(p++)", + "start_graphic": "22,96", + "darkbow_graphic": "1108,96", + "projectile": "13,40,36,41,46,5,0", + "poison_damage": "48" + }, + { + "itemId": "5627", + "name": "Rune arrow(p++)", + "start_graphic": "24,96", + "darkbow_graphic": "1109,96", + "projectile": "15,40,36,41,46,5,0", + "poison_damage": "48" + }, + { + "itemId": "5628", + "name": "Bronze dart(p+)", + "start_graphic": "232,96", + "darkbow_graphic": "", + "projectile": "226,40,36,32,32,15,0", + "poison_damage": "38" + }, + { + "itemId": "5629", + "name": "Iron dart(p+)", + "start_graphic": "233,96", + "darkbow_graphic": "", + "projectile": "227,40,36,32,32,15,0", + "poison_damage": "38" + }, + { + "itemId": "5630", + "name": "Steel dart(p+)", + "start_graphic": "235,96", + "darkbow_graphic": "", + "projectile": "229,40,36,32,32,15,0", + "poison_damage": "38" + }, + { + "itemId": "5631", + "name": "Black dart(p+)", + "start_graphic": "273,96", + "darkbow_graphic": "", + "projectile": "227,40,36,32,32,15,0", + "poison_damage": "38" + }, + { + "itemId": "5633", + "name": "Adamant dart(p+)", + "start_graphic": "236,96", + "darkbow_graphic": "", + "projectile": "230,40,36,32,32,15,0", + "poison_damage": "38" + }, + { + "itemId": "5634", + "name": "Rune dart(p+)", + "start_graphic": "237,96", + "darkbow_graphic": "", + "projectile": "231,40,36,32,32,15,0", + "poison_damage": "38" + }, + { + "itemId": "5635", + "name": "Bronze dart(p++)", + "start_graphic": "232,96", + "darkbow_graphic": "", + "projectile": "226,40,36,32,32,15,0", + "poison_damage": "48" + }, + { + "itemId": "5636", + "name": "Iron dart(p++)", + "start_graphic": "233,96", + "darkbow_graphic": "", + "projectile": "227,40,36,32,32,15,0", + "poison_damage": "48" + }, + { + "itemId": "5637", + "name": "Steel dart(p++)", + "start_graphic": "234,96", + "darkbow_graphic": "", + "projectile": "228,40,36,32,32,15,0", + "poison_damage": "48" + }, + { + "itemId": "5638", + "name": "Black dart(p++)", + "start_graphic": "273,96", + "darkbow_graphic": "", + "projectile": "227,40,36,32,32,15,0", + "poison_damage": "48" + }, + { + "itemId": "5639", + "name": "Mithril dart(p++)", + "start_graphic": "235,96", + "darkbow_graphic": "", + "projectile": "229,40,36,32,32,15,0", + "poison_damage": "48" + }, + { + "itemId": "5640", + "name": "Adamant dart(p++)", + "start_graphic": "236,96", + "darkbow_graphic": "", + "projectile": "230,40,36,32,32,15,0", + "poison_damage": "48" + }, + { + "itemId": "5641", + "name": "Rune dart(p++)", + "start_graphic": "237,96", + "darkbow_graphic": "", + "projectile": "231,40,36,32,32,15,0", + "poison_damage": "48" + }, + { + "itemId": "5642", + "name": "Bronze javelin(p+)", + "start_graphic": "206,96", + "darkbow_graphic": "", + "projectile": "200,40,36,32,32,15,0", + "poison_damage": "38" + }, + { + "itemId": "5643", + "name": "Iron javelin(p+)", + "start_graphic": "207,96", + "darkbow_graphic": "", + "projectile": "201,40,36,32,32,15,0", + "poison_damage": "38" + }, + { + "itemId": "5644", + "name": "Steel javelin(p+)", + "start_graphic": "208,96", + "darkbow_graphic": "", + "projectile": "202,40,36,32,32,15,0", + "poison_damage": "38" + }, + { + "itemId": "5645", + "name": "Mithril javelin(p+)", + "start_graphic": "209,96", + "darkbow_graphic": "", + "projectile": "203,40,36,32,32,15,0", + "poison_damage": "38" + }, + { + "itemId": "5646", + "name": "Adamant javelin(p+)", + "start_graphic": "210,96", + "darkbow_graphic": "", + "projectile": "204,40,36,32,32,15,0", + "poison_damage": "38" + }, + { + "itemId": "5647", + "name": "Rune javelin(p+)", + "start_graphic": "211,96", + "darkbow_graphic": "", + "projectile": "205,40,36,32,32,15,0", + "poison_damage": "38" + }, + { + "itemId": "5648", + "name": "Bronze jav\\'n(p++)", + "start_graphic": "206,96", + "darkbow_graphic": "", + "projectile": "200,40,36,32,32,15,0", + "poison_damage": "48" + }, + { + "itemId": "5649", + "name": "Iron javelin(p++)", + "start_graphic": "207,96", + "darkbow_graphic": "", + "projectile": "201,40,36,32,32,15,0", + "poison_damage": "48" + }, + { + "itemId": "5650", + "name": "Steel javelin(p++)", + "start_graphic": "208,96", + "darkbow_graphic": "", + "projectile": "202,40,36,32,32,15,0", + "poison_damage": "48" + }, + { + "itemId": "5651", + "name": "Mithril javelin(p++)", + "start_graphic": "209,96", + "darkbow_graphic": "", + "projectile": "203,40,36,32,32,15,0", + "poison_damage": "48" + }, + { + "itemId": "5652", + "name": "Adamant javelin(p++)", + "start_graphic": "210,96", + "darkbow_graphic": "", + "projectile": "204,40,36,32,32,15,0", + "poison_damage": "48" + }, + { + "itemId": "5653", + "name": "Rune javelin(p++)", + "start_graphic": "211,96", + "darkbow_graphic": "", + "projectile": "205,40,36,32,32,15,0", + "poison_damage": "48" + }, + { + "itemId": "5654", + "name": "Bronze knife(p+)", + "start_graphic": "219,96", + "darkbow_graphic": "", + "projectile": "212,40,36,32,32,15,0", + "poison_damage": "38" + }, + { + "itemId": "5655", + "name": "Iron knife(p+)", + "start_graphic": "220,96", + "darkbow_graphic": "", + "projectile": "213,40,36,32,32,15,0", + "poison_damage": "38" + }, + { + "itemId": "5656", + "name": "Steel knife(p+)", + "start_graphic": "221,96", + "darkbow_graphic": "", + "projectile": "214,40,36,32,32,15,0", + "poison_damage": "38" + }, + { + "itemId": "5657", + "name": "Mithril knife(p+)", + "start_graphic": "223,96", + "darkbow_graphic": "", + "projectile": "216,40,36,32,32,15,0", + "poison_damage": "38" + }, + { + "itemId": "5658", + "name": "Black knife(p+)", + "start_graphic": "222,96", + "darkbow_graphic": "", + "projectile": "215,40,36,32,32,15,0", + "poison_damage": "38" + }, + { + "itemId": "5659", + "name": "Adamant knife(p+)", + "start_graphic": "224,96", + "darkbow_graphic": "", + "projectile": "217,40,36,32,32,15,0", + "poison_damage": "38" + }, + { + "itemId": "5660", + "name": "Rune knife(p+)", + "start_graphic": "225,96", + "darkbow_graphic": "", + "projectile": "218,40,36,32,32,15,0", + "poison_damage": "38" + }, + { + "itemId": "5661", + "name": "Bronze knife(p++)", + "start_graphic": "219,96", + "darkbow_graphic": "", + "projectile": "212,40,36,32,32,15,0", + "poison_damage": "48" + }, + { + "itemId": "5662", + "name": "Iron knife(p++)", + "start_graphic": "220,96", + "darkbow_graphic": "", + "projectile": "213,40,36,32,32,15,0", + "poison_damage": "48" + }, + { + "itemId": "5663", + "name": "Steel knife(p++)", + "start_graphic": "221,96", + "darkbow_graphic": "", + "projectile": "214,40,36,32,32,15,0", + "poison_damage": "48" + }, + { + "itemId": "5664", + "name": "Mithril knife(p++)", + "start_graphic": "223,96", + "darkbow_graphic": "", + "projectile": "216,40,36,32,32,15,0", + "poison_damage": "48" + }, + { + "itemId": "5665", + "name": "Black knife(p++)", + "start_graphic": "222,96", + "darkbow_graphic": "", + "projectile": "215,40,36,32,32,15,0", + "poison_damage": "48" + }, + { + "itemId": "5666", + "name": "Adamant knife(p++)", + "start_graphic": "224,96", + "darkbow_graphic": "", + "projectile": "217,40,36,32,32,15,0", + "poison_damage": "48" + }, + { + "itemId": "5667", + "name": "Rune knife(p++)", + "start_graphic": "225,96", + "darkbow_graphic": "", + "projectile": "218,40,36,32,32,15,0", + "poison_damage": "48" + }, + { + "itemId": "6061", + "name": "Bronze bolts(p+)", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "38" + }, + { + "itemId": "6062", + "name": "Bronze bolts(p++)", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "48" + }, + { + "itemId": "6522", + "name": "Toktz-xil-ul", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "442,40,36,32,32,15,0", + "poison_damage": "0" + }, + { + "itemId": "8882", + "name": "Bone bolts", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "0" + }, + { + "itemId": "9139", + "name": "Blurite bolts", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "0" + }, + { + "itemId": "9140", + "name": "Iron bolts", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "0" + }, + { + "itemId": "9141", + "name": "Steel bolts", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "0" + }, + { + "itemId": "9142", + "name": "Mithril bolts", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "0" + }, + { + "itemId": "9143", + "name": "Adamant bolts", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "0" + }, + { + "itemId": "9144", + "name": "Rune bolts", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "0" + }, + { + "itemId": "9236", + "name": "Opal bolts (e)", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "0" + }, + { + "itemId": "9237", + "name": "Jade bolts (e)", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "0" + }, + { + "itemId": "9238", + "name": "Pearl bolts (e)", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "0" + }, + { + "itemId": "9239", + "name": "Topaz bolts (e)", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "0" + }, + { + "itemId": "9240", + "name": "Sapphire bolts (e)", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "0" + }, + { + "itemId": "9241", + "name": "Emerald bolts (e)", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "0" + }, + { + "itemId": "9242", + "name": "Ruby bolts (e)", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "0" + }, + { + "itemId": "9243", + "name": "Diamond bolts (e)", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "0" + }, + { + "itemId": "9244", + "name": "Dragon bolts (e)", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "0" + }, + { + "itemId": "9245", + "name": "Onyx bolts (e)", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "0" + }, + { + "itemId": "9286", + "name": "Blurite bolts(p)", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "28" + }, + { + "itemId": "9287", + "name": "Iron bolts (p)", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "28" + }, + { + "itemId": "9288", + "name": "Steel bolts (p)", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "28" + }, + { + "itemId": "9289", + "name": "Mithril bolts (p)", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "28" + }, + { + "itemId": "9290", + "name": "Adamant bolts (p)", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "28" + }, + { + "itemId": "9291", + "name": "Runite bolts (p)", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "28" + }, + { + "itemId": "9293", + "name": "Blurite bolts(p+)", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "38" + }, + { + "itemId": "9294", + "name": "Iron bolts(p+)", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "38" + }, + { + "itemId": "9295", + "name": "Steel bolts(p+)", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "38" + }, + { + "itemId": "9296", + "name": "Mithril bolts(p+)", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "38" + }, + { + "itemId": "9297", + "name": "Adamant bolts(p+)", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "38" + }, + { + "itemId": "9298", + "name": "Runite bolts(p+)", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "38" + }, + { + "itemId": "9300", + "name": "Blurite bolts(p++)", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "48" + }, + { + "itemId": "9301", + "name": "Iron bolts(p++)", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "48" + }, + { + "itemId": "9302", + "name": "Steel bolts(p++)", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "48" + }, + { + "itemId": "9303", + "name": "Mithril bolts(p++)", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "48" + }, + { + "itemId": "9304", + "name": "Adamant bolts(p++)", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "48" + }, + { + "itemId": "9305", + "name": "Runite bolts(p++)", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "48" + }, + { + "itemId": "9335", + "name": "Jade bolts", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "0" + }, + { + "itemId": "9336", + "name": "Topaz bolts", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "0" + }, + { + "itemId": "9337", + "name": "Sapphire bolts", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "0" + }, + { + "itemId": "9338", + "name": "Emerald bolts", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "0" + }, + { + "itemId": "9339", + "name": "Ruby bolts", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "0" + }, + { + "itemId": "9340", + "name": "Diamond bolts", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "0" + }, + { + "itemId": "9341", + "name": "Dragon bolts", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "0" + }, + { + "itemId": "9342", + "name": "Onyx bolts", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "0" + }, + { + "itemId": "9706", + "name": "Training arrows", + "start_graphic": "806,96", + "darkbow_graphic": "806,96", + "projectile": "805,40,36,41,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "10033", + "name": "Chinchompa", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "908,40,36,45,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "10034", + "name": "Red chinchompa", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "909,40,36,45,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "10158", + "name": "Kebbit bolts", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "0" + }, + { + "itemId": "10159", + "name": "Long kebbit bolts", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "0" + }, + { + "itemId": "11212", + "name": "Dragon arrow", + "start_graphic": "1116,96", + "darkbow_graphic": "1114,96", + "projectile": "1120,40,36,41,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "11217", + "name": "Dragon fire arrows", + "start_graphic": "26,96", + "darkbow_graphic": "1113,96", + "projectile": "17,40,36,41,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "11227", + "name": "Dragon arrow(p)", + "start_graphic": "1116,96", + "darkbow_graphic": "1114,96", + "projectile": "1120,40,36,41,46,5,0", + "poison_damage": "28" + }, + { + "itemId": "11228", + "name": "Dragon arrow(p+)", + "start_graphic": "1116,96", + "darkbow_graphic": "1114,96", + "projectile": "1120,40,36,41,46,5,0", + "poison_damage": "38" + }, + { + "itemId": "11229", + "name": "Dragon arrow(p++)", + "start_graphic": "1116,96", + "darkbow_graphic": "1114,96", + "projectile": "1120,40,36,41,46,5,0", + "poison_damage": "48" + }, + { + "itemId": "11230", + "name": "Dragon dart", + "start_graphic": "1123,96", + "darkbow_graphic": "", + "projectile": "1122,40,36,32,32,15,0", + "poison_damage": "0" + }, + { + "itemId": "11231", + "name": "Dragon dart(p)", + "start_graphic": "1123,96", + "darkbow_graphic": "", + "projectile": "1122,40,36,32,32,15,0", + "poison_damage": "28" + }, + { + "itemId": "11233", + "name": "Dragon dart(p+)", + "start_graphic": "1123,96", + "darkbow_graphic": "", + "projectile": "1122,40,36,32,32,15,0", + "poison_damage": "38" + }, + { + "itemId": "11234", + "name": "Dragon dart(p++)", + "start_graphic": "1123,96", + "darkbow_graphic": "", + "projectile": "1122,40,36,32,32,15,0", + "poison_damage": "48" + }, + { + "itemId": "13083", + "name": "Black bolts", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "0" + }, + { + "itemId": "13084", + "name": "Black bolts(p)", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "28" + }, + { + "itemId": "13085", + "name": "Black bolts(p+)", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "38" + }, + { + "itemId": "13086", + "name": "Black bolts(p++)", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "48" + }, + { + "itemId": "13280", + "name": "Broad-tipped bolts", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "27,38,36,41,32,5,0", + "poison_damage": "0" + }, + { + "itemId": "13879", + "name": "Morrigan\\'s javelin", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "1837,40,36,32,32,15,0", + "poison_damage": "0" + }, + { + "itemId": "13880", + "name": "Morrigan\\'s javelin(p)", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "1837,40,36,32,32,15,0", + "poison_damage": "28" + }, + { + "itemId": "13881", + "name": "Morrigan\\'s javelin(p+)", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "1837,40,36,32,32,15,0", + "poison_damage": "38" + }, + { + "itemId": "13882", + "name": "Morrigan\\'s javelin(p++)", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "1837,40,36,32,32,15,0", + "poison_damage": "48" + }, + { + "itemId": "13883", + "name": "Morrigan\\'s throwing axe", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "1839,40,36,32,32,15,0", + "poison_damage": "0" + }, + { + "itemId": "13953", + "name": "Corrupt morrigan\\'s javelin", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "1837,40,36,32,32,15,0", + "poison_damage": "0" + }, + { + "itemId": "13954", + "name": "C. morrigan\\'s javelin (p)", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "1837,40,36,32,32,15,0", + "poison_damage": "28" + }, + { + "itemId": "13955", + "name": "C. morrigan\\'s javelin (p+)", + "start_graphic": "1837,96", + "darkbow_graphic": "", + "projectile": "1840,40,36,32,32,15,0", + "poison_damage": "38" + }, + { + "itemId": "13956", + "name": "C. morrigan\\'s javelin (p++)", + "start_graphic": "1837,96", + "darkbow_graphic": "", + "projectile": "1840,40,36,32,32,15,0", + "poison_damage": "48" + }, + { + "itemId": "13957", + "name": "C. morrigan\\'s throwing axe", + "start_graphic": "-1,0", + "darkbow_graphic": "", + "projectile": "1839,40,36,32,32,15,0", + "poison_damage": "0" + }, + { + "itemId": "14202", + "name": "Arrows (class 1)", + "start_graphic": "24,96", + "darkbow_graphic": "1109,96", + "projectile": "15,40,36,41,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "14203", + "name": "Arrows (class 2)", + "start_graphic": "24,96", + "darkbow_graphic": "1109,96", + "projectile": "15,40,36,41,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "14204", + "name": "Arrows (class 3)", + "start_graphic": "24,96", + "darkbow_graphic": "1109,96", + "projectile": "15,40,36,41,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "14205", + "name": "Arrows (class 4)", + "start_graphic": "24,96", + "darkbow_graphic": "1109,96", + "projectile": "15,40,36,41,46,5,0", + "poison_damage": "0" + }, + { + "itemId": "14206", + "name": "Arrows (class 5)", + "start_graphic": "24,96", + "darkbow_graphic": "1109,96", + "projectile": "15,40,36,41,46,5,0", + "poison_damage": "0" + } +] diff --git a/Server/data/configs/clue_rewards.json b/Server/data/configs/clue_rewards.json new file mode 100644 index 0000000..5554b13 --- /dev/null +++ b/Server/data/configs/clue_rewards.json @@ -0,0 +1,2182 @@ +{ + "rare": [ + { + "minAmount": 1, + "weight": 50, + "id": 10362, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": 30, + "id": 3486, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": 30, + "id": 3481, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": 30, + "id": 3483, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": 30, + "id": 3485, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": 30, + "id": 3488, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": 10, + "id": 10330, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": 10, + "id": 10332, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": 10, + "id": 10334, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": 10, + "id": 10336, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": 10, + "id": 10338, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": 10, + "id": 10340, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": 10, + "id": 10342, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": 10, + "id": 10344, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": 10, + "id": 10346, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": 10, + "id": 10348, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": 10, + "id": 10350, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": 10, + "id": 10352, + "maxAmount": 1 + } + ], + "medium": [ + { + "minAmount": 1, + "weight": "5", + "id": 2605, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2599, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2601, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2603, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3474, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2613, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2607, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2609, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3475, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2611, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2647, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2645, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2649, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2577, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2579, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 7319, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 7321, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 7323, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 7325, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 7327, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 7372, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 7380, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 7370, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 7378, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 13103, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 13097, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10282, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 13109, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 13107, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 13111, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 13113, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 13115, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10364, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10420, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10422, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10400, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10402, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10416, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10418, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10436, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10438, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10296, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10298, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10300, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10302, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10304, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 7334, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 7340, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 7346, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 7352, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 7358, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10446, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10448, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10450, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10452, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10454, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10456, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1161, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1123, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1073, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1091, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1199, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1183, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1111, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1211, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1271, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1287, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1301, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1317, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1357, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1371, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1430, + "maxAmount": 1 + }, + { + "minAmount": 10, + "weight": "5", + "id": 4823, + "maxAmount": 40 + }, + { + "minAmount": 1, + "weight": "5", + "id": 9183, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1393, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1099, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1135, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 857, + "maxAmount": 1 + }, + { + "minAmount": 10, + "weight": "5", + "id": 8781, + "maxAmount": 43 + }, + { + "minAmount": 6, + "weight": "5", + "id": 374, + "maxAmount": 23 + }, + { + "minAmount": 15, + "weight": "5", + "id": 380, + "maxAmount": 43 + }, + { + "minAmount": 500, + "weight": "5", + "id": 995, + "maxAmount": 7000 + }, + { + "minAmount": 15, + "weight": "5", + "id": 10326, + "maxAmount": 40 + }, + { + "minAmount": 15, + "weight": "5", + "id": 7329, + "maxAmount": 40 + }, + { + "minAmount": 15, + "weight": "5", + "id": 7331, + "maxAmount": 40 + }, + { + "minAmount": 15, + "weight": "5", + "id": 7330, + "maxAmount": 40 + }, + { + "minAmount": 15, + "weight": "5", + "id": 10327, + "maxAmount": 40 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10476, + "maxAmount": 27 + }, + { + "minAmount": 1, + "weight": "5", + "id": 556, + "maxAmount": 228 + }, + { + "minAmount": 1, + "weight": "5", + "id": 554, + "maxAmount": 228 + }, + { + "minAmount": 1, + "weight": "5", + "id": 557, + "maxAmount": 228 + }, + { + "minAmount": 1, + "weight": "5", + "id": 555, + "maxAmount": 228 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3827, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3828, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3829, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3830, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3831, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3832, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3833, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3834, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3835, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3836, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3837, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3838, + "maxAmount": 1 + } + ], + "hard": [ + { + "minAmount": 1, + "weight": "5", + "id": 10284, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 13101, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 13099, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10470, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10472, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10474, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10440, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10442, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10444, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2627, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2623, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2625, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3477, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2629, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2619, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2615, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2617, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3476, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2621, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2673, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2669, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2671, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3480, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2675, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2657, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2653, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2655, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3478, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2659, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2665, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2661, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2663, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3479, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2667, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10286, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 7336, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10288, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 7342, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10290, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 7348, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10292, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 7354, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10294, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 7360, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 7376, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 7384, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 7374, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 7382, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10374, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10368, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10370, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10372, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10382, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10376, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10378, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10380, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10390, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10384, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10386, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10388, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2651, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2581, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2639, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2641, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2643, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1163, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1127, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1079, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1093, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1201, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1185, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1213, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1275, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1289, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1303, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1319, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1359, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1373, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1432, + "maxAmount": 1 + }, + { + "minAmount": 10, + "weight": "5", + "id": 4824, + "maxAmount": 43 + }, + { + "minAmount": 6, + "weight": "5", + "id": 9144, + "maxAmount": 23 + }, + { + "minAmount": 1, + "weight": "5", + "id": 9185, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2497, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2503, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 861, + "maxAmount": 2 + }, + { + "minAmount": 1, + "weight": "5", + "id": 859, + "maxAmount": 2 + }, + { + "minAmount": 6, + "weight": "5", + "id": 8783, + "maxAmount": 27 + }, + { + "minAmount": 16, + "weight": "5", + "id": 380, + "maxAmount": 38 + }, + { + "minAmount": 7, + "weight": "5", + "id": 386, + "maxAmount": 32 + }, + { + "minAmount": 1, + "weight": "5", + "id": 7398, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 7399, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 7400, + "maxAmount": 1 + }, + { + "minAmount": 500, + "weight": "5", + "id": 995, + "maxAmount": 7000 + }, + { + "minAmount": 15, + "weight": "5", + "id": 10326, + "maxAmount": 40 + }, + { + "minAmount": 15, + "weight": "5", + "id": 7329, + "maxAmount": 40 + }, + { + "minAmount": 15, + "weight": "5", + "id": 7331, + "maxAmount": 40 + }, + { + "minAmount": 15, + "weight": "5", + "id": 7330, + "maxAmount": 40 + }, + { + "minAmount": 15, + "weight": "5", + "id": 10327, + "maxAmount": 40 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10476, + "maxAmount": 27 + }, + { + "minAmount": 1, + "weight": "5", + "id": 556, + "maxAmount": 228 + }, + { + "minAmount": 1, + "weight": "5", + "id": 554, + "maxAmount": 228 + }, + { + "minAmount": 1, + "weight": "5", + "id": 557, + "maxAmount": 228 + }, + { + "minAmount": 1, + "weight": "5", + "id": 555, + "maxAmount": 228 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3827, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3828, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3829, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3830, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3831, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3832, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3833, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3834, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3835, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3836, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3837, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3838, + "maxAmount": 1 + } + ], + "easy": [ + { + "minAmount": 1, + "weight": "5", + "id": 2633, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2635, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2637, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2587, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2583, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2585, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3472, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2589, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2595, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2591, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2593, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3473, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2597, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10306, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10308, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10310, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10312, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10314, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 7332, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 7338, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 7344, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 7350, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 7356, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 2631, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 7392, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 7396, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 7388, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 7390, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 7386, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 7394, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 7362, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 7366, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 7364, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 7368, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10404, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10406, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10424, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10426, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10408, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10410, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10428, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10430, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10412, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10414, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10432, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10434, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10316, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10318, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10320, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10322, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10324, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10392, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10394, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10396, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10398, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10366, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10458, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10464, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10462, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10466, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10460, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10468, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 13095, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 13105, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10280, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1077, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1089, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1107, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1125, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1151, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1165, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1179, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1195, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1217, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1283, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1297, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1313, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1327, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1341, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1361, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1367, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1426, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3098, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 4821, + "maxAmount": 1 + }, + { + "minAmount": 4, + "weight": "5", + "id": 8779, + "maxAmount": 38 + }, + { + "minAmount": 1, + "weight": "5", + "id": 850, + "maxAmount": 4 + }, + { + "minAmount": 4, + "weight": "5", + "id": 334, + "maxAmount": 19 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1169, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1059, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1061, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1063, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1095, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1129, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1167, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1131, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 858, + "maxAmount": 4 + }, + { + "minAmount": 3, + "weight": "5", + "id": 330, + "maxAmount": 23 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1441, + "maxAmount": 3 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1443, + "maxAmount": 3 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1270, + "maxAmount": 3 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1097, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 1133, + "maxAmount": 1 + }, + { + "minAmount": 500, + "weight": "5", + "id": 995, + "maxAmount": 7000 + }, + { + "minAmount": 15, + "weight": "5", + "id": 10326, + "maxAmount": 40 + }, + { + "minAmount": 15, + "weight": "5", + "id": 7329, + "maxAmount": 40 + }, + { + "minAmount": 15, + "weight": "5", + "id": 7331, + "maxAmount": 40 + }, + { + "minAmount": 15, + "weight": "5", + "id": 7330, + "maxAmount": 40 + }, + { + "minAmount": 15, + "weight": "5", + "id": 10327, + "maxAmount": 40 + }, + { + "minAmount": 1, + "weight": "5", + "id": 10476, + "maxAmount": 27 + }, + { + "minAmount": 1, + "weight": "5", + "id": 556, + "maxAmount": 228 + }, + { + "minAmount": 1, + "weight": "5", + "id": 554, + "maxAmount": 228 + }, + { + "minAmount": 1, + "weight": "5", + "id": 557, + "maxAmount": 228 + }, + { + "minAmount": 1, + "weight": "5", + "id": 555, + "maxAmount": 228 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3827, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3828, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3829, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3830, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3831, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3832, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3833, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3834, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3835, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3836, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3837, + "maxAmount": 1 + }, + { + "minAmount": 1, + "weight": "5", + "id": 3838, + "maxAmount": 1 + } + ] +} diff --git a/Server/data/configs/door_configs.json b/Server/data/configs/door_configs.json new file mode 100644 index 0000000..ec17288 --- /dev/null +++ b/Server/data/configs/door_configs.json @@ -0,0 +1,3090 @@ +[ + { + "id": "3", + "replaceId": "1531", + "fence": "false", + "metal": "false" + }, + { + "id": "4", + "replaceId": "3271", + "fence": "false", + "metal": "false" + }, + { + "id": "24", + "replaceId": "8791", + "fence": "false", + "metal": "false" + }, + { + "id": "59", + "replaceId": "1534", + "fence": "false", + "metal": "false" + }, + { + "id": "71", + "replaceId": "1517", + "fence": "false", + "metal": "false" + }, + { + "id": "72", + "replaceId": "1520", + "fence": "false", + "metal": "false" + }, + { + "id": "73", + "replaceId": "4425", + "fence": "false", + "metal": "false" + }, + { + "id": "74", + "replaceId": "4426", + "fence": "false", + "metal": "false" + }, + { + "id": "81", + "replaceId": "11712", + "fence": "false", + "metal": "false" + }, + { + "id": "82", + "replaceId": "11715", + "fence": "false", + "metal": "false" + }, + { + "id": "89", + "replaceId": "1560", + "fence": "false", + "metal": "true" + }, + { + "id": "90", + "replaceId": "1560", + "fence": "false", + "metal": "true" + }, + { + "id": "92", + "replaceId": "91", + "fence": "false", + "metal": "false" + }, + { + "id": "93", + "replaceId": "12445", + "fence": "false", + "metal": "false" + }, + { + "id": "94", + "replaceId": "1561", + "fence": "false", + "metal": "true" + }, + { + "id": "95", + "replaceId": "1560", + "fence": "false", + "metal": "true" + }, + { + "id": "99", + "replaceId": "14750", + "fence": "false", + "metal": "false" + }, + { + "id": "102", + "replaceId": "13002", + "fence": "false", + "metal": "false" + }, + { + "id": "166", + "replaceId": "1556", + "fence": "false", + "metal": "false" + }, + { + "id": "167", + "replaceId": "1552", + "fence": "false", + "metal": "false" + }, + { + "id": "883", + "replaceId": "7051", + "fence": "false", + "metal": "false" + }, + { + "id": "1512", + "replaceId": "1515", + "fence": "false", + "metal": "false" + }, + { + "id": "1513", + "replaceId": "1514", + "fence": "false", + "metal": "false" + }, + { + "id": "1516", + "replaceId": "1517", + "fence": "false", + "metal": "false" + }, + { + "id": "1519", + "replaceId": "1520", + "fence": "false", + "metal": "false" + }, + { + "id": "1530", + "replaceId": "1531", + "fence": "false", + "metal": "false" + }, + { + "id": "1533", + "replaceId": "1534", + "fence": "false", + "metal": "false" + }, + { + "id": "1536", + "replaceId": "1537", + "fence": "false", + "metal": "false" + }, + { + "id": "1539", + "replaceId": "1540", + "fence": "false", + "metal": "true" + }, + { + "id": "1542", + "replaceId": "1543", + "fence": "false", + "metal": "true" + }, + { + "id": "1544", + "replaceId": "1545", + "fence": "false", + "metal": "true" + }, + { + "id": "1551", + "replaceId": "1552", + "fence": "true", + "metal": "false" + }, + { + "id": "1553", + "replaceId": "1556", + "fence": "true", + "metal": "false" + }, + { + "id": "1557", + "replaceId": "1560", + "fence": "false", + "metal": "true" + }, + { + "id": "1558", + "replaceId": "1560", + "fence": "true", + "metal": "true" + }, + { + "id": "1573", + "replaceId": "1574", + "fence": "false", + "metal": "false" + }, + { + "id": "1575", + "replaceId": "1576", + "fence": "false", + "metal": "false" + }, + { + "id": "1589", + "replaceId": "1561", + "fence": "true", + "metal": "true" + }, + { + "id": "1590", + "replaceId": "1561", + "fence": "false", + "metal": "true" + }, + { + "id": "1591", + "replaceId": "1531", + "fence": "false", + "metal": "false" + }, + { + "id": "1595", + "replaceId": "1531", + "fence": "false", + "metal": "false" + }, + { + "id": "1596", + "replaceId": "1561", + "fence": "false", + "metal": "true" + }, + { + "id": "1597", + "replaceId": "1561", + "fence": "false", + "metal": "true" + }, + { + "id": "1598", + "replaceId": "1556", + "fence": "false", + "metal": "false" + }, + { + "id": "1599", + "replaceId": "1556", + "fence": "false", + "metal": "false" + }, + { + "id": "1804", + "replaceId": "1531", + "fence": "false", + "metal": "false" + }, + { + "id": "1805", + "replaceId": "15535", + "fence": "false", + "metal": "false" + }, + { + "id": "1991", + "replaceId": "1545", + "fence": "false", + "metal": "true" + }, + { + "id": "2000", + "replaceId": "1537", + "fence": "false", + "metal": "false" + }, + { + "id": "2002", + "replaceId": "1537", + "fence": "false", + "metal": "false" + }, + { + "id": "2025", + "replaceId": "2026", + "fence": "false", + "metal": "false" + }, + { + "id": "2034", + "replaceId": "1531", + "fence": "false", + "metal": "false" + }, + { + "id": "1530", + "replaceId": "1531", + "fence": "false", + "metal": "false" + }, + { + "id": "2039", + "replaceId": "1560", + "fence": "false", + "metal": "true" + }, + { + "id": "2041", + "replaceId": "1561", + "fence": "false", + "metal": "true" + }, + { + "id": "2050", + "replaceId": "15511", + "fence": "true", + "metal": "false" + }, + { + "id": "2051", + "replaceId": "15513", + "fence": "true", + "metal": "false" + }, + { + "id": "2054", + "replaceId": "24375", + "fence": "false", + "metal": "false" + }, + { + "id": "2058", + "replaceId": "1561", + "fence": "false", + "metal": "true" + }, + { + "id": "2060", + "replaceId": "1561", + "fence": "false", + "metal": "false" + }, + { + "id": "2069", + "replaceId": "23339", + "fence": "false", + "metal": "false" + }, + { + "id": "2115", + "replaceId": "1561", + "fence": "false", + "metal": "true" + }, + { + "id": "2116", + "replaceId": "1561", + "fence": "false", + "metal": "true" + }, + { + "id": "2154", + "replaceId": "1561", + "fence": "false", + "metal": "true" + }, + { + "id": "2155", + "replaceId": "1561", + "fence": "false", + "metal": "true" + }, + { + "id": "2184", + "replaceId": "7260", + "fence": "false", + "metal": "false" + }, + { + "id": "2307", + "replaceId": "1561", + "fence": "false", + "metal": "true" + }, + { + "id": "2308", + "replaceId": "1561", + "fence": "false", + "metal": "true" + }, + { + "id": "2309", + "replaceId": "1540", + "fence": "false", + "metal": "true" + }, + { + "id": "2338", + "replaceId": "35631", + "fence": "false", + "metal": "false" + }, + { + "id": "2391", + "replaceId": "1561", + "fence": "false", + "metal": "true" + }, + { + "id": "2392", + "replaceId": "1561", + "fence": "false", + "metal": "true" + }, + { + "id": "2397", + "replaceId": "24383", + "fence": "false", + "metal": "false" + }, + { + "id": "2398", + "replaceId": "24379", + "fence": "false", + "metal": "false" + }, + { + "id": "2399", + "replaceId": "36319", + "fence": "false", + "metal": "false" + }, + { + "id": "2406", + "replaceId": "2407", + "fence": "false", + "metal": "false" + }, + { + "id": "2416", + "replaceId": "2417", + "fence": "false", + "metal": "false" + }, + { + "id": "2427", + "replaceId": "36864", + "fence": "false", + "metal": "false" + }, + { + "id": "2428", + "replaceId": "36359", + "fence": "false", + "metal": "false" + }, + { + "id": "2429", + "replaceId": "36343", + "fence": "false", + "metal": "false" + }, + { + "id": "2430", + "replaceId": "36853", + "fence": "false", + "metal": "false" + }, + { + "id": "2431", + "replaceId": "36848", + "fence": "false", + "metal": "false" + }, + { + "id": "2432", + "replaceId": "1561", + "fence": "false", + "metal": "true" + }, + { + "id": "2433", + "replaceId": "1561", + "fence": "false", + "metal": "true" + }, + { + "id": "2438", + "replaceId": "3728", + "fence": "false", + "metal": "false" + }, + { + "id": "2439", + "replaceId": "3727", + "fence": "false", + "metal": "false" + }, + { + "id": "2526", + "replaceId": "24377", + "fence": "false", + "metal": "true" + }, + { + "id": "2528", + "replaceId": "24935", + "fence": "false", + "metal": "false" + }, + { + "id": "2534", + "replaceId": "2998", + "fence": "false", + "metal": "false" + }, + { + "id": "2535", + "replaceId": "2998", + "fence": "false", + "metal": "false" + }, + { + "id": "2537", + "replaceId": "24932", + "fence": "false", + "metal": "false" + }, + { + "id": "2546", + "replaceId": "2547", + "fence": "false", + "metal": "false" + }, + { + "id": "2548", + "replaceId": "2549", + "fence": "false", + "metal": "false" + }, + { + "id": "2550", + "replaceId": "27989", + "fence": "false", + "metal": "false" + }, + { + "id": "2551", + "replaceId": "30865", + "fence": "false", + "metal": "false" + }, + { + "id": "2552", + "replaceId": "1561", + "fence": "false", + "metal": "true" + }, + { + "id": "2553", + "replaceId": "1561", + "fence": "false", + "metal": "true" + }, + { + "id": "2554", + "replaceId": "26916", + "fence": "false", + "metal": "false" + }, + { + "id": "2555", + "replaceId": "1537", + "fence": "false", + "metal": "false" + }, + { + "id": "2556", + "replaceId": "25417", + "fence": "false", + "metal": "false" + }, + { + "id": "2557", + "replaceId": "1543", + "fence": "false", + "metal": "true" + }, + { + "id": "2558", + "replaceId": "25717", + "fence": "false", + "metal": "false" + }, + { + "id": "2559", + "replaceId": "25820", + "fence": "false", + "metal": "false" + }, + { + "id": "2595", + "replaceId": "3271", + "fence": "false", + "metal": "false" + }, + { + "id": "2621", + "replaceId": "3271", + "fence": "false", + "metal": "false" + }, + { + "id": "2622", + "replaceId": "3271", + "fence": "false", + "metal": "false" + }, + { + "id": "2624", + "replaceId": "2549", + "fence": "false", + "metal": "false" + }, + { + "id": "2625", + "replaceId": "2549", + "fence": "false", + "metal": "false" + }, + { + "id": "2626", + "replaceId": "3271", + "fence": "false", + "metal": "false" + }, + { + "id": "2627", + "replaceId": "3271", + "fence": "false", + "metal": "false" + }, + { + "id": "2628", + "replaceId": "3271", + "fence": "false", + "metal": "false" + }, + { + "id": "2631", + "replaceId": "1545", + "fence": "false", + "metal": "true" + }, + { + "id": "2673", + "replaceId": "1561", + "fence": "false", + "metal": "true" + }, + { + "id": "2674", + "replaceId": "1561", + "fence": "false", + "metal": "true" + }, + { + "id": "2705", + "replaceId": "25643", + "fence": "false", + "metal": "false" + }, + { + "id": "2712", + "replaceId": "36865", + "fence": "false", + "metal": "false" + }, + { + "id": "2786", + "replaceId": "20088", + "fence": "false", + "metal": "true" + }, + { + "id": "2787", + "replaceId": "20087", + "fence": "false", + "metal": "false" + }, + { + "id": "2788", + "replaceId": "20090", + "fence": "false", + "metal": "true" + }, + { + "id": "2789", + "replaceId": "20089", + "fence": "false", + "metal": "false" + }, + { + "id": "2814", + "replaceId": "1561", + "fence": "false", + "metal": "false" + }, + { + "id": "2815", + "replaceId": "1561", + "fence": "false", + "metal": "false" + }, + { + "id": "2861", + "replaceId": "15535", + "fence": "false", + "metal": "false" + }, + { + "id": "2862", + "replaceId": "24815", + "fence": "false", + "metal": "false" + }, + { + "id": "2863", + "replaceId": "3271", + "fence": "false", + "metal": "false" + }, + { + "id": "2865", + "replaceId": "1561", + "fence": "false", + "metal": "true" + }, + { + "id": "2866", + "replaceId": "1561", + "fence": "false", + "metal": "true" + }, + { + "id": "2882", + "replaceId": "1561", + "fence": "false", + "metal": "true" + }, + { + "id": "2883", + "replaceId": "1561", + "fence": "false", + "metal": "true" + }, + { + "id": "2997", + "replaceId": "2998", + "fence": "false", + "metal": "false" + }, + { + "id": "3014", + "replaceId": "3271", + "fence": "false", + "metal": "false" + }, + { + "id": "3015", + "replaceId": "3727", + "fence": "true", + "metal": "false" + }, + { + "id": "3016", + "replaceId": "3727", + "fence": "true", + "metal": "false" + }, + { + "id": "3017", + "replaceId": "3271", + "fence": "false", + "metal": "false" + }, + { + "id": "3018", + "replaceId": "3271", + "fence": "false", + "metal": "false" + }, + { + "id": "3019", + "replaceId": "3271", + "fence": "false", + "metal": "false" + }, + { + "id": "3020", + "replaceId": "1561", + "fence": "false", + "metal": "true" + }, + { + "id": "3021", + "replaceId": "1561", + "fence": "false", + "metal": "true" + }, + { + "id": "3022", + "replaceId": "1561", + "fence": "false", + "metal": "true" + }, + { + "id": "3023", + "replaceId": "1561", + "fence": "false", + "metal": "true" + }, + { + "id": "3024", + "replaceId": "3271", + "fence": "false", + "metal": "false" + }, + { + "id": "3025", + "replaceId": "3271", + "fence": "false", + "metal": "false" + }, + { + "id": "3026", + "replaceId": "3271", + "fence": "false", + "metal": "false" + }, + { + "id": "3027", + "replaceId": "3271", + "fence": "false", + "metal": "false" + }, + { + "id": "3197", + "replaceId": "3727", + "fence": "false", + "metal": "false" + }, + { + "id": "3198", + "replaceId": "3727", + "fence": "false", + "metal": "false" + }, + { + "id": "3270", + "replaceId": "3271", + "fence": "false", + "metal": "false" + }, + { + "id": "3506", + "replaceId": "1561", + "fence": "false", + "metal": "true" + }, + { + "id": "3507", + "replaceId": "1561", + "fence": "false", + "metal": "true" + }, + { + "id": "3725", + "replaceId": "3727", + "fence": "true", + "metal": "false" + }, + { + "id": "3726", + "replaceId": "3728", + "fence": "true", + "metal": "false" + }, + { + "id": "3743", + "replaceId": "17090", + "fence": "false", + "metal": "false" + }, + { + "id": "3745", + "replaceId": "3271", + "fence": "false", + "metal": "false" + }, + { + "id": "3746", + "replaceId": "3271", + "fence": "false", + "metal": "false" + }, + { + "id": "3747", + "replaceId": "3748", + "fence": "false", + "metal": "false" + }, + { + "id": "3763", + "replaceId": "3764", + "fence": "false", + "metal": "true" + }, + { + "id": "3776", + "replaceId": "3777", + "fence": "false", + "metal": "false" + }, + { + "id": "4148", + "replaceId": "4246", + "fence": "false", + "metal": "false" + }, + { + "id": "4165", + "replaceId": "4697", + "fence": "false", + "metal": "false" + }, + { + "id": "4166", + "replaceId": "7374", + "fence": "false", + "metal": "false" + }, + { + "id": "4247", + "replaceId": "21342", + "fence": "false", + "metal": "false" + }, + { + "id": "4311", + "replaceId": "4139", + "fence": "true", + "metal": "false" + }, + { + "id": "4312", + "replaceId": "4140", + "fence": "false", + "metal": "false" + }, + { + "id": "4423", + "replaceId": "4425", + "fence": "false", + "metal": "false" + }, + { + "id": "4424", + "replaceId": "4426", + "fence": "false", + "metal": "false" + }, + { + "id": "4427", + "replaceId": "4429", + "fence": "false", + "metal": "false" + }, + { + "id": "4428", + "replaceId": "4430", + "fence": "false", + "metal": "false" + }, + { + "id": "4487", + "replaceId": "4492", + "fence": "false", + "metal": "false" + }, + { + "id": "4490", + "replaceId": "4491", + "fence": "false", + "metal": "false" + }, + { + "id": "4629", + "replaceId": "4630", + "fence": "false", + "metal": "false" + }, + { + "id": "4631", + "replaceId": "4630", + "fence": "false", + "metal": "false" + }, + { + "id": "4632", + "replaceId": "4634", + "fence": "false", + "metal": "false" + }, + { + "id": "4633", + "replaceId": "4634", + "fence": "false", + "metal": "false" + }, + { + "id": "4636", + "replaceId": "4639", + "fence": "false", + "metal": "false" + }, + { + "id": "4637", + "replaceId": "4639", + "fence": "false", + "metal": "false" + }, + { + "id": "4638", + "replaceId": "4639", + "fence": "false", + "metal": "false" + }, + { + "id": "4640", + "replaceId": "4639", + "fence": "false", + "metal": "false" + }, + { + "id": "4696", + "replaceId": "21343", + "fence": "false", + "metal": "false" + }, + { + "id": "4962", + "replaceId": "3271", + "fence": "false", + "metal": "false" + }, + { + "id": "4963", + "replaceId": "17092", + "fence": "false", + "metal": "false" + }, + { + "id": "4964", + "replaceId": "17094", + "fence": "false", + "metal": "false" + }, + { + "id": "5126", + "replaceId": "5128", + "fence": "false", + "metal": "false" + }, + { + "id": "5172", + "replaceId": "1545", + "fence": "false", + "metal": "true" + }, + { + "id": "5183", + "replaceId": "5188", + "fence": "false", + "metal": "false" + }, + { + "id": "5186", + "replaceId": "5187", + "fence": "false", + "metal": "false" + }, + { + "id": "5244", + "replaceId": "5245", + "fence": "false", + "metal": "false" + }, + { + "id": "5501", + "replaceId": "8821", + "fence": "false", + "metal": "true" + }, + { + "id": "5667", + "replaceId": "26207", + "fence": "false", + "metal": "false" + }, + { + "id": "5803", + "replaceId": "4173", + "fence": "false", + "metal": "false" + }, + { + "id": "5804", + "replaceId": "5132", + "fence": "false", + "metal": "false" + }, + { + "id": "5805", + "replaceId": "7435", + "fence": "false", + "metal": "false" + }, + { + "id": "5806", + "replaceId": "5268", + "fence": "false", + "metal": "false" + }, + { + "id": "6100", + "replaceId": "6101", + "fence": "false", + "metal": "false" + }, + { + "id": "6102", + "replaceId": "6103", + "fence": "false", + "metal": "false" + }, + { + "id": "6104", + "replaceId": "6105", + "fence": "false", + "metal": "false" + }, + { + "id": "6106", + "replaceId": "6107", + "fence": "false", + "metal": "false" + }, + { + "id": "6108", + "replaceId": "6107", + "fence": "false", + "metal": "false" + }, + { + "id": "6110", + "replaceId": "6111", + "fence": "false", + "metal": "false" + }, + { + "id": "6112", + "replaceId": "6113", + "fence": "false", + "metal": "false" + }, + { + "id": "6114", + "replaceId": "6113", + "fence": "false", + "metal": "false" + }, + { + "id": "6451", + "replaceId": "1561", + "fence": "false", + "metal": "true" + }, + { + "id": "6452", + "replaceId": "1561", + "fence": "false", + "metal": "true" + }, + { + "id": "6624", + "replaceId": "6626", + "fence": "false", + "metal": "false" + }, + { + "id": "6625", + "replaceId": "6627", + "fence": "false", + "metal": "false" + }, + { + "id": "6975", + "replaceId": "6976", + "fence": "false", + "metal": "false" + }, + { + "id": "6977", + "replaceId": "6109", + "fence": "false", + "metal": "false" + }, + { + "id": "7049", + "replaceId": "7051", + "fence": "true", + "metal": "false" + }, + { + "id": "7050", + "replaceId": "7052", + "fence": "true", + "metal": "false" + }, + { + "id": "7222", + "replaceId": "7260", + "fence": "false", + "metal": "false" + }, + { + "id": "7259", + "replaceId": "7260", + "fence": "false", + "metal": "false" + }, + { + "id": "7274", + "replaceId": "5245", + "fence": "false", + "metal": "false" + }, + { + "id": "7302", + "replaceId": "5245", + "fence": "false", + "metal": "false" + }, + { + "id": "7317", + "replaceId": "5245", + "fence": "false", + "metal": "false" + }, + { + "id": "7320", + "replaceId": "5245", + "fence": "false", + "metal": "false" + }, + { + "id": "7323", + "replaceId": "5245", + "fence": "false", + "metal": "false" + }, + { + "id": "7326", + "replaceId": "5245", + "fence": "false", + "metal": "false" + }, + { + "id": "7354", + "replaceId": "5245", + "fence": "false", + "metal": "false" + }, + { + "id": "7373", + "replaceId": "7374", + "fence": "false", + "metal": "false" + }, + { + "id": "8695", + "replaceId": "8696", + "fence": "false", + "metal": "false" + }, + { + "id": "8786", + "replaceId": "11708", + "fence": "false", + "metal": "false" + }, + { + "id": "8787", + "replaceId": "10261", + "fence": "false", + "metal": "false" + }, + { + "id": "8788", + "replaceId": "1545", + "fence": "false", + "metal": "true" + }, + { + "id": "8789", + "replaceId": "11710", + "fence": "false", + "metal": "false" + }, + { + "id": "8810", + "replaceId": "8812", + "fence": "true", + "metal": "false" + }, + { + "id": "8811", + "replaceId": "8813", + "fence": "true", + "metal": "false" + }, + { + "id": "8818", + "replaceId": "8819", + "fence": "false", + "metal": "false" + }, + { + "id": "8820", + "replaceId": "8821", + "fence": "false", + "metal": "true" + }, + { + "id": "9562", + "replaceId": "9564", + "fence": "false", + "metal": "true" + }, + { + "id": "9563", + "replaceId": "9564", + "fence": "false", + "metal": "true" + }, + { + "id": "10260", + "replaceId": "10261", + "fence": "false", + "metal": "false" + }, + { + "id": "10262", + "replaceId": "10263", + "fence": "false", + "metal": "false" + }, + { + "id": "10264", + "replaceId": "10265", + "fence": "false", + "metal": "false" + }, + { + "id": "10325", + "replaceId": "10327", + "fence": "false", + "metal": "false" + }, + { + "id": "10431", + "replaceId": "37996", + "fence": "false", + "metal": "false" + }, + { + "id": "10527", + "replaceId": "10528", + "fence": "false", + "metal": "false" + }, + { + "id": "10529", + "replaceId": "10530", + "fence": "false", + "metal": "false" + }, + { + "id": "11196", + "replaceId": "10327", + "fence": "false", + "metal": "false" + }, + { + "id": "11197", + "replaceId": "4639", + "fence": "false", + "metal": "false" + }, + { + "id": "11379", + "replaceId": "11380", + "fence": "false", + "metal": "false" + }, + { + "id": "11381", + "replaceId": "11380", + "fence": "false", + "metal": "false" + }, + { + "id": "11483", + "replaceId": "11708", + "fence": "false", + "metal": "false" + }, + { + "id": "11616", + "replaceId": "11617", + "fence": "false", + "metal": "false" + }, + { + "id": "11707", + "replaceId": "11708", + "fence": "false", + "metal": "false" + }, + { + "id": "11709", + "replaceId": "11710", + "fence": "false", + "metal": "false" + }, + { + "id": "11711", + "replaceId": "11710", + "fence": "false", + "metal": "false" + }, + { + "id": "11713", + "replaceId": "11712", + "fence": "false", + "metal": "false" + }, + { + "id": "11714", + "replaceId": "11715", + "fence": "false", + "metal": "false" + }, + { + "id": "11716", + "replaceId": "11722", + "fence": "false", + "metal": "false" + }, + { + "id": "11721", + "replaceId": "11723", + "fence": "false", + "metal": "false" + }, + { + "id": "11993", + "replaceId": "11994", + "fence": "false", + "metal": "false" + }, + { + "id": "12045", + "replaceId": "12046", + "fence": "false", + "metal": "false" + }, + { + "id": "12047", + "replaceId": "12048", + "fence": "false", + "metal": "false" + }, + { + "id": "12348", + "replaceId": "10327", + "fence": "false", + "metal": "false" + }, + { + "id": "12349", + "replaceId": "11382", + "fence": "false", + "metal": "false" + }, + { + "id": "12350", + "replaceId": "11382", + "fence": "false", + "metal": "false" + }, + { + "id": "12444", + "replaceId": "12445", + "fence": "false", + "metal": "false" + }, + { + "id": "12446", + "replaceId": "12447", + "fence": "false", + "metal": "false" + }, + { + "id": "12448", + "replaceId": "12449", + "fence": "false", + "metal": "false" + }, + { + "id": "12761", + "replaceId": "11617", + "fence": "false", + "metal": "false" + }, + { + "id": "12816", + "replaceId": "12988", + "fence": "false", + "metal": "false" + }, + { + "id": "12817", + "replaceId": "12989", + "fence": "false", + "metal": "false" + }, + { + "id": "12986", + "replaceId": "7051", + "fence": "true", + "metal": "false" + }, + { + "id": "12987", + "replaceId": "7052", + "fence": "true", + "metal": "false" + }, + { + "id": "13001", + "replaceId": "34353", + "fence": "false", + "metal": "false" + }, + { + "id": "13006", + "replaceId": "13008", + "fence": "false", + "metal": "false" + }, + { + "id": "13007", + "replaceId": "13009", + "fence": "false", + "metal": "false" + }, + { + "id": "13015", + "replaceId": "13018", + "fence": "false", + "metal": "false" + }, + { + "id": "13016", + "replaceId": "13017", + "fence": "false", + "metal": "false" + }, + { + "id": "13094", + "replaceId": "13095", + "fence": "false", + "metal": "false" + }, + { + "id": "13096", + "replaceId": "13097", + "fence": "false", + "metal": "false" + }, + { + "id": "13100", + "replaceId": "13103", + "fence": "false", + "metal": "false" + }, + { + "id": "13101", + "replaceId": "13102", + "fence": "false", + "metal": "false" + }, + { + "id": "13107", + "replaceId": "13108", + "fence": "false", + "metal": "false" + }, + { + "id": "13109", + "replaceId": "13110", + "fence": "false", + "metal": "false" + }, + { + "id": "13118", + "replaceId": "13120", + "fence": "false", + "metal": "false" + }, + { + "id": "13119", + "replaceId": "13121", + "fence": "false", + "metal": "false" + }, + { + "id": "13314", + "replaceId": "13315", + "fence": "false", + "metal": "false" + }, + { + "id": "13317", + "replaceId": "13318", + "fence": "false", + "metal": "true" + }, + { + "id": "13320", + "replaceId": "13321", + "fence": "false", + "metal": "true" + }, + { + "id": "13323", + "replaceId": "13324", + "fence": "false", + "metal": "true" + }, + { + "id": "13326", + "replaceId": "13327", + "fence": "false", + "metal": "false" + }, + { + "id": "13344", + "replaceId": "13350", + "fence": "false", + "metal": "false" + }, + { + "id": "13345", + "replaceId": "13351", + "fence": "false", + "metal": "false" + }, + { + "id": "13346", + "replaceId": "13352", + "fence": "false", + "metal": "true" + }, + { + "id": "13347", + "replaceId": "13353", + "fence": "false", + "metal": "true" + }, + { + "id": "13348", + "replaceId": "13354", + "fence": "false", + "metal": "true" + }, + { + "id": "13349", + "replaceId": "13355", + "fence": "false", + "metal": "true" + }, + { + "id": "14233", + "replaceId": "14234", + "fence": "true", + "metal": "false" + }, + { + "id": "14235", + "replaceId": "14236", + "fence": "true", + "metal": "false" + }, + { + "id": "14237", + "replaceId": "14238", + "fence": "true", + "metal": "false" + }, + { + "id": "14239", + "replaceId": "14240", + "fence": "true", + "metal": "false" + }, + { + "id": "14241", + "replaceId": "14242", + "fence": "true", + "metal": "false" + }, + { + "id": "14243", + "replaceId": "14244", + "fence": "true", + "metal": "false" + }, + { + "id": "14245", + "replaceId": "14246", + "fence": "true", + "metal": "false" + }, + { + "id": "14247", + "replaceId": "14246", + "fence": "true", + "metal": "false" + }, + { + "id": "14749", + "replaceId": "14750", + "fence": "false", + "metal": "false" + }, + { + "id": "14751", + "replaceId": "14754", + "fence": "false", + "metal": "false" + }, + { + "id": "14752", + "replaceId": "14753", + "fence": "false", + "metal": "false" + }, + { + "id": "14923", + "replaceId": "17115", + "fence": "false", + "metal": "false" + }, + { + "id": "14982", + "replaceId": "24930", + "fence": "false", + "metal": "false" + }, + { + "id": "15056", + "replaceId": "14924", + "fence": "false", + "metal": "false" + }, + { + "id": "15204", + "replaceId": "15205", + "fence": "false", + "metal": "false" + }, + { + "id": "15510", + "replaceId": "15511", + "fence": "true", + "metal": "false" + }, + { + "id": "15512", + "replaceId": "15513", + "fence": "true", + "metal": "false" + }, + { + "id": "15514", + "replaceId": "15515", + "fence": "true", + "metal": "false" + }, + { + "id": "15516", + "replaceId": "15517", + "fence": "true", + "metal": "false" + }, + { + "id": "15536", + "replaceId": "15535", + "fence": "false", + "metal": "false" + }, + { + "id": "15641", + "replaceId": "15642", + "fence": "false", + "metal": "false" + }, + { + "id": "15644", + "replaceId": "15645", + "fence": "false", + "metal": "false" + }, + { + "id": "15647", + "replaceId": "15648", + "fence": "false", + "metal": "false" + }, + { + "id": "15650", + "replaceId": "15645", + "fence": "false", + "metal": "false" + }, + { + "id": "15653", + "replaceId": "15654", + "fence": "false", + "metal": "false" + }, + { + "id": "15759", + "replaceId": "14750", + "fence": "false", + "metal": "false" + }, + { + "id": "16774", + "replaceId": "16777", + "fence": "false", + "metal": "false" + }, + { + "id": "16776", + "replaceId": "16777", + "fence": "false", + "metal": "false" + }, + { + "id": "16778", + "replaceId": "16779", + "fence": "false", + "metal": "false" + }, + { + "id": "17089", + "replaceId": "17090", + "fence": "false", + "metal": "false" + }, + { + "id": "17091", + "replaceId": "17092", + "fence": "false", + "metal": "false" + }, + { + "id": "17093", + "replaceId": "17092", + "fence": "false", + "metal": "false" + }, + { + "id": "17114", + "replaceId": "17115", + "fence": "false", + "metal": "false" + }, + { + "id": "17316", + "replaceId": "17317", + "fence": "false", + "metal": "false" + }, + { + "id": "17600", + "replaceId": "18031", + "fence": "false", + "metal": "false" + }, + { + "id": "17601", + "replaceId": "18032", + "fence": "false", + "metal": "false" + }, + { + "id": "17973", + "replaceId": "18031", + "fence": "false", + "metal": "false" + }, + { + "id": "18091", + "replaceId": "18032", + "fence": "false", + "metal": "false" + }, + { + "id": "18092", + "replaceId": "18032", + "fence": "false", + "metal": "false" + }, + { + "id": "18168", + "replaceId": "11617", + "fence": "false", + "metal": "false" + }, + { + "id": "18489", + "replaceId": "18490", + "fence": "false", + "metal": "true" + }, + { + "id": "18698", + "replaceId": "18699", + "fence": "false", + "metal": "false" + }, + { + "id": "18700", + "replaceId": "18701", + "fence": "false", + "metal": "false" + }, + { + "id": "20391", + "replaceId": "28518", + "fence": "false", + "metal": "true", + "autowalk": "true" + }, + { + "id": "28514", + "replaceId": "28518", + "fence": "false", + "metal": "true", + "autowalk": "true" + }, + { + "id": "21065", + "replaceId": "21161", + "fence": "false", + "metal": "false" + }, + { + "id": "21160", + "replaceId": "21161", + "fence": "false", + "metal": "false" + }, + { + "id": "21162", + "replaceId": "21161", + "fence": "false", + "metal": "false" + }, + { + "id": "21164", + "replaceId": "21161", + "fence": "false", + "metal": "false" + }, + { + "id": "21340", + "replaceId": "21342", + "fence": "false", + "metal": "false" + }, + { + "id": "21341", + "replaceId": "21342", + "fence": "false", + "metal": "false" + }, + { + "id": "21397", + "replaceId": "21398", + "fence": "false", + "metal": "true" + }, + { + "id": "21399", + "replaceId": "21402", + "fence": "false", + "metal": "true" + }, + { + "id": "21400", + "replaceId": "21401", + "fence": "false", + "metal": "true" + }, + { + "id": "21403", + "replaceId": "21404", + "fence": "true", + "metal": "true" + }, + { + "id": "21405", + "replaceId": "21406", + "fence": "true", + "metal": "true" + }, + { + "id": "21505", + "replaceId": "21506", + "fence": "false", + "metal": "false" + }, + { + "id": "21507", + "replaceId": "21508", + "fence": "false", + "metal": "false" + }, + { + "id": "21600", + "replaceId": "21601", + "fence": "false", + "metal": "false" + }, + { + "id": "22435", + "replaceId": "22436", + "fence": "false", + "metal": "false" + }, + { + "id": "22437", + "replaceId": "22438", + "fence": "false", + "metal": "false" + }, + { + "id": "22779", + "replaceId": "22778", + "fence": "false", + "metal": "false" + }, + { + "id": "22914", + "replaceId": "22913", + "fence": "false", + "metal": "false" + }, + { + "id": "22921", + "replaceId": "22920", + "fence": "false", + "metal": "true" + }, + { + "id": "23056", + "replaceId": "24685", + "fence": "false", + "metal": "false" + }, + { + "id": "23216", + "replaceId": "23217", + "fence": "true", + "metal": "true" + }, + { + "id": "23338", + "replaceId": "23339", + "fence": "false", + "metal": "false" + }, + { + "id": "23340", + "replaceId": "23341", + "fence": "false", + "metal": "false" + }, + { + "id": "23342", + "replaceId": "23343", + "fence": "false", + "metal": "false" + }, + { + "id": "23378", + "replaceId": "23339", + "fence": "false", + "metal": "false" + }, + { + "id": "23917", + "replaceId": "23918", + "fence": "true", + "metal": "false" + }, + { + "id": "24369", + "replaceId": "24373", + "fence": "false", + "metal": "false" + }, + { + "id": "24370", + "replaceId": "24374", + "fence": "false", + "metal": "false" + }, + { + "id": "24376", + "replaceId": "24377", + "fence": "false", + "metal": "false" + }, + { + "id": "24378", + "replaceId": "24377", + "fence": "false", + "metal": "false" + }, + { + "id": "24381", + "replaceId": "24379", + "fence": "false", + "metal": "false" + }, + { + "id": "24384", + "replaceId": "24383", + "fence": "false", + "metal": "false" + }, + { + "id": "24565", + "replaceId": "36316", + "fence": "false", + "metal": "false" + }, + { + "id": "24567", + "replaceId": "36318", + "fence": "false", + "metal": "false" + }, + { + "id": "24686", + "replaceId": "24685", + "fence": "false", + "metal": "false" + }, + { + "id": "24816", + "replaceId": "24815", + "fence": "false", + "metal": "false" + }, + { + "id": "24931", + "replaceId": "24930", + "fence": "false", + "metal": "false" + }, + { + "id": "24933", + "replaceId": "24932", + "fence": "false", + "metal": "false" + }, + { + "id": "24936", + "replaceId": "24935", + "fence": "false", + "metal": "false" + }, + { + "id": "25418", + "replaceId": "25417", + "fence": "false", + "metal": "false" + }, + { + "id": "25594", + "replaceId": "25639", + "fence": "false", + "metal": "false" + }, + { + "id": "25595", + "replaceId": "25639", + "fence": "false", + "metal": "false" + }, + { + "id": "25638", + "replaceId": "25639", + "fence": "false", + "metal": "false" + }, + { + "id": "25640", + "replaceId": "25641", + "fence": "false", + "metal": "false" + }, + { + "id": "25642", + "replaceId": "25643", + "fence": "false", + "metal": "false" + }, + { + "id": "25716", + "replaceId": "25717", + "fence": "false", + "metal": "false" + }, + { + "id": "25718", + "replaceId": "25719", + "fence": "false", + "metal": "false" + }, + { + "id": "25748", + "replaceId": "25791", + "fence": "false", + "metal": "false" + }, + { + "id": "25750", + "replaceId": "25789", + "fence": "false", + "metal": "false" + }, + { + "id": "25788", + "replaceId": "25641", + "fence": "false", + "metal": "false" + }, + { + "id": "25790", + "replaceId": "25639", + "fence": "false", + "metal": "false" + }, + { + "id": "25799", + "replaceId": "25800", + "fence": "false", + "metal": "false" + }, + { + "id": "25804", + "replaceId": "25805", + "fence": "false", + "metal": "false" + }, + { + "id": "25806", + "replaceId": "25807", + "fence": "false", + "metal": "false" + }, + { + "id": "25813", + "replaceId": "25816", + "fence": "false", + "metal": "false" + }, + { + "id": "25814", + "replaceId": "25815", + "fence": "false", + "metal": "false" + }, + { + "id": "25819", + "replaceId": "25820", + "fence": "false", + "metal": "false" + }, + { + "id": "25825", + "replaceId": "25826", + "fence": "false", + "metal": "false" + }, + { + "id": "25827", + "replaceId": "25828", + "fence": "false", + "metal": "false" + }, + { + "id": "25876", + "replaceId": "25877", + "fence": "false", + "metal": "true" + }, + { + "id": "26081", + "replaceId": "26083", + "fence": "false", + "metal": "true", + "autowalk": "true" + }, + { + "id": "26082", + "replaceId": "26084", + "fence": "false", + "metal": "true", + "autowalk": "true" + }, + { + "id": "26130", + "replaceId": "26132", + "fence": "false", + "metal": "true" + }, + { + "id": "26131", + "replaceId": "26133", + "fence": "false", + "metal": "true" + }, + { + "id": "26425", + "replaceId": "2521", + "fence": "false", + "metal": "false" + }, + { + "id": "26426", + "replaceId": "26852", + "fence": "false", + "metal": "false" + }, + { + "id": "26427", + "replaceId": "26851", + "fence": "false", + "metal": "false" + }, + { + "id": "26428", + "replaceId": "2520", + "fence": "false", + "metal": "false" + }, + { + "id": "26560", + "replaceId": "26561", + "fence": "false", + "metal": "true" + }, + { + "id": "26706", + "replaceId": "26707", + "fence": "false", + "metal": "true" + }, + { + "id": "26787", + "replaceId": "8821", + "fence": "false", + "metal": "false" + }, + { + "id": "26808", + "replaceId": "26916", + "fence": "false", + "metal": "false" + }, + { + "id": "26810", + "replaceId": "26916", + "fence": "false", + "metal": "false" + }, + { + "id": "26906", + "replaceId": "26907", + "fence": "false", + "metal": "false" + }, + { + "id": "26908", + "replaceId": "26909", + "fence": "false", + "metal": "false" + }, + { + "id": "26910", + "replaceId": "26911", + "fence": "false", + "metal": "false" + }, + { + "id": "26913", + "replaceId": "26914", + "fence": "false", + "metal": "false" + }, + { + "id": "26917", + "replaceId": "26916", + "fence": "false", + "metal": "false" + }, + { + "id": "27065", + "replaceId": "1561", + "fence": "true", + "metal": "true" + }, + { + "id": "27066", + "replaceId": "1561", + "fence": "false", + "metal": "true" + }, + { + "id": "27846", + "replaceId": "27851", + "fence": "false", + "metal": "false" + }, + { + "id": "27848", + "replaceId": "27853", + "fence": "true", + "metal": "false" + }, + { + "id": "27852", + "replaceId": "27851", + "fence": "true", + "metal": "false" + }, + { + "id": "27854", + "replaceId": "27853", + "fence": "false", + "metal": "false" + }, + { + "id": "27988", + "replaceId": "27989", + "fence": "false", + "metal": "false" + }, + { + "id": "28407", + "replaceId": "28408", + "fence": "false", + "metal": "false" + }, + { + "id": "28409", + "replaceId": "28410", + "fence": "false", + "metal": "false" + }, + { + "id": "28589", + "replaceId": "28588", + "fence": "false", + "metal": "false" + }, + { + "id": "28690", + "replaceId": "28692", + "fence": "false", + "metal": "true" + }, + { + "id": "28691", + "replaceId": "28693", + "fence": "false", + "metal": "true" + }, + { + "id": "29261", + "replaceId": "29262", + "fence": "false", + "metal": "true" + }, + { + "id": "29315", + "replaceId": "29317", + "fence": "false", + "metal": "true" + }, + { + "id": "29316", + "replaceId": "29322", + "fence": "false", + "metal": "true" + }, + { + "id": "29319", + "replaceId": "29318", + "fence": "false", + "metal": "true" + }, + { + "id": "29320", + "replaceId": "29321", + "fence": "false", + "metal": "true" + }, + { + "id": "29575", + "replaceId": "30865", + "fence": "false", + "metal": "false" + }, + { + "id": "29732", + "replaceId": "30865", + "fence": "false", + "metal": "false" + }, + { + "id": "30116", + "replaceId": "30117", + "fence": "true", + "metal": "false" + }, + { + "id": "30118", + "replaceId": "30119", + "fence": "true", + "metal": "false" + }, + { + "id": "30120", + "replaceId": "30121", + "fence": "true", + "metal": "false" + }, + { + "id": "30122", + "replaceId": "30123", + "fence": "true", + "metal": "false" + }, + { + "id": "30124", + "replaceId": "30125", + "fence": "true", + "metal": "false" + }, + { + "id": "30126", + "replaceId": "30127", + "fence": "true", + "metal": "false" + }, + { + "id": "30128", + "replaceId": "30129", + "fence": "true", + "metal": "false" + }, + { + "id": "30130", + "replaceId": "30131", + "fence": "true", + "metal": "false" + }, + { + "id": "30503", + "replaceId": "18031", + "fence": "false", + "metal": "false" + }, + { + "id": "30864", + "replaceId": "30865", + "fence": "false", + "metal": "false" + }, + { + "id": "31340", + "replaceId": "31341", + "fence": "false", + "metal": "false" + }, + { + "id": "31342", + "replaceId": "31343", + "fence": "false", + "metal": "false" + }, + { + "id": "31534", + "replaceId": "31535", + "fence": "false", + "metal": "true" + }, + { + "id": "31808", + "replaceId": "31809", + "fence": "false", + "metal": "false" + }, + { + "id": "31811", + "replaceId": "31812", + "fence": "false", + "metal": "false" + }, + { + "id": "31814", + "replaceId": "31816", + "fence": "false", + "metal": "false" + }, + { + "id": "31815", + "replaceId": "31817", + "fence": "false", + "metal": "false" + }, + { + "id": "31818", + "replaceId": "31816", + "fence": "false", + "metal": "false" + }, + { + "id": "31819", + "replaceId": "31817", + "fence": "false", + "metal": "false" + }, + { + "id": "31820", + "replaceId": "31821", + "fence": "false", + "metal": "false" + }, + { + "id": "31822", + "replaceId": "31823", + "fence": "false", + "metal": "false" + }, + { + "id": "31825", + "replaceId": "31824", + "fence": "false", + "metal": "false" + }, + { + "id": "31827", + "replaceId": "31826", + "fence": "false", + "metal": "false" + }, + { + "id": "31830", + "replaceId": "31829", + "fence": "false", + "metal": "true" + }, + { + "id": "31832", + "replaceId": "31831", + "fence": "false", + "metal": "true" + }, + { + "id": "31838", + "replaceId": "31839", + "fence": "false", + "metal": "true" + }, + { + "id": "31841", + "replaceId": "31842", + "fence": "false", + "metal": "false" + }, + { + "id": "31844", + "replaceId": "31845", + "fence": "false", + "metal": "true" + }, + { + "id": "33060", + "replaceId": "31828", + "fence": "false", + "metal": "false" + }, + { + "id": "34005", + "replaceId": "31845", + "fence": "false", + "metal": "true" + }, + { + "id": "34042", + "replaceId": "34043", + "fence": "false", + "metal": "true" + }, + { + "id": "34044", + "replaceId": "34045", + "fence": "false", + "metal": "false" + }, + { + "id": "34046", + "replaceId": "6115", + "fence": "false", + "metal": "true" + }, + { + "id": "34234", + "replaceId": "34808", + "fence": "false", + "metal": "false" + }, + { + "id": "34312", + "replaceId": "34313", + "fence": "false", + "metal": "false" + }, + { + "id": "34354", + "replaceId": "34353", + "fence": "false", + "metal": "false" + }, + { + "id": "34779", + "replaceId": "34777", + "fence": "true", + "metal": "false" + }, + { + "id": "34780", + "replaceId": "34778", + "fence": "true", + "metal": "false" + }, + { + "id": "34805", + "replaceId": "34808", + "fence": "false", + "metal": "false" + }, + { + "id": "34806", + "replaceId": "34808", + "fence": "false", + "metal": "false" + }, + { + "id": "34807", + "replaceId": "34808", + "fence": "false", + "metal": "false" + }, + { + "id": "34809", + "replaceId": "34808", + "fence": "false", + "metal": "false" + }, + { + "id": "34811", + "replaceId": "34813", + "fence": "false", + "metal": "false" + }, + { + "id": "34812", + "replaceId": "34813", + "fence": "false", + "metal": "false" + }, + { + "id": "34816", + "replaceId": "34818", + "fence": "false", + "metal": "false" + }, + { + "id": "34817", + "replaceId": "34813", + "fence": "false", + "metal": "false" + }, + { + "id": "34819", + "replaceId": "34820", + "fence": "false", + "metal": "false" + }, + { + "id": "34822", + "replaceId": "34823", + "fence": "false", + "metal": "false" + }, + { + "id": "34825", + "replaceId": "34826", + "fence": "false", + "metal": "false" + }, + { + "id": "34827", + "replaceId": "34828", + "fence": "false", + "metal": "false" + }, + { + "id": "35241", + "replaceId": "35242", + "fence": "false", + "metal": "false" + }, + { + "id": "35243", + "replaceId": "15651", + "fence": "false", + "metal": "false" + }, + { + "id": "35540", + "replaceId": "35541", + "fence": "false", + "metal": "false" + }, + { + "id": "35630", + "replaceId": "35631", + "fence": "false", + "metal": "false" + }, + { + "id": "35991", + "replaceId": "36021", + "fence": "false", + "metal": "false" + }, + { + "id": "36022", + "replaceId": "36021", + "fence": "false", + "metal": "false" + }, + { + "id": "36315", + "replaceId": "36342", + "fence": "false", + "metal": "false" + }, + { + "id": "36317", + "replaceId": "36340", + "fence": "false", + "metal": "false" + }, + { + "id": "36320", + "replaceId": "36319", + "fence": "false", + "metal": "false" + }, + { + "id": "36339", + "replaceId": "36358", + "fence": "false", + "metal": "false" + }, + { + "id": "36341", + "replaceId": "36356", + "fence": "false", + "metal": "false" + }, + { + "id": "36344", + "replaceId": "36343", + "fence": "false", + "metal": "false" + }, + { + "id": "36355", + "replaceId": "36356", + "fence": "false", + "metal": "false" + }, + { + "id": "36357", + "replaceId": "36356", + "fence": "false", + "metal": "false" + }, + { + "id": "36360", + "replaceId": "36359", + "fence": "false", + "metal": "false" + }, + { + "id": "36844", + "replaceId": "36845", + "fence": "false", + "metal": "false" + }, + { + "id": "36846", + "replaceId": "36848", + "fence": "false", + "metal": "false" + }, + { + "id": "36847", + "replaceId": "36848", + "fence": "false", + "metal": "false" + }, + { + "id": "36851", + "replaceId": "36853", + "fence": "false", + "metal": "false" + }, + { + "id": "36852", + "replaceId": "36853", + "fence": "false", + "metal": "false" + }, + { + "id": "36856", + "replaceId": "36858", + "fence": "false", + "metal": "false" + }, + { + "id": "36857", + "replaceId": "36859", + "fence": "false", + "metal": "false" + }, + { + "id": "36862", + "replaceId": "36864", + "fence": "false", + "metal": "false" + }, + { + "id": "36863", + "replaceId": "36864", + "fence": "false", + "metal": "false" + }, + { + "id": "36913", + "replaceId": "36912", + "fence": "true", + "metal": "false" + }, + { + "id": "36915", + "replaceId": "36914", + "fence": "true", + "metal": "false" + }, + { + "id": "36917", + "replaceId": "36916", + "fence": "true", + "metal": "false" + }, + { + "id": "36919", + "replaceId": "36918", + "fence": "true", + "metal": "false" + }, + { + "id": "36999", + "replaceId": "37000", + "fence": "false", + "metal": "false" + }, + { + "id": "37002", + "replaceId": "37003", + "fence": "false", + "metal": "false" + }, + { + "id": "37352", + "replaceId": "37351", + "fence": "true", + "metal": "false" + }, + { + "id": "37354", + "replaceId": "37353", + "fence": "false", + "metal": "false" + }, + { + "id": "37995", + "replaceId": "37996", + "fence": "false", + "metal": "false" + }, + { + "id": "38124", + "replaceId": "38123", + "fence": "false", + "metal": "false" + }, + { + "id": "38141", + "replaceId": "38142", + "fence": "false", + "metal": "false" + } +] diff --git a/Server/data/configs/drop_tables.json b/Server/data/configs/drop_tables.json new file mode 100644 index 0000000..00bceef --- /dev/null +++ b/Server/data/configs/drop_tables.json @@ -0,0 +1,58803 @@ +[ + { + "default": [], + "charm": [], + "ids": "0", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1,2,3,16,24,170,351,359,663,726,727,728,729,730,1081,1084,1085,1086,1087,1088,1089,2675,2683,3223,3224,3225,3915,5923", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "2.0", + "id": "1139", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1203", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "22.0", + "id": "877", + "maxAmount": "12" + }, + { + "minAmount": "7", + "weight": "3.0", + "id": "882", + "maxAmount": "7" + }, + { + "minAmount": "4", + "weight": "2.0", + "id": "557", + "maxAmount": "4" + }, + { + "minAmount": "6", + "weight": "2.0", + "id": "554", + "maxAmount": "6" + }, + { + "minAmount": "9", + "weight": "2.0", + "id": "558", + "maxAmount": "9" + }, + { + "minAmount": "2", + "weight": "1.0", + "id": "562", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "23.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "37.0", + "id": "995", + "maxAmount": "3" + }, + { + "minAmount": "5", + "weight": "9.0", + "id": "995", + "maxAmount": "5" + }, + { + "minAmount": "15", + "weight": "4.0", + "id": "995", + "maxAmount": "15" + }, + { + "minAmount": "25", + "weight": "1.0", + "id": "995", + "maxAmount": "25" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "313", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "436", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1965", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "4,5,6,25,352,353,354,360,361,362,363,2776,2684,3226,3227,5924", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "2.0", + "id": "1139", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1203", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "22.0", + "id": "877", + "maxAmount": "12" + }, + { + "minAmount": "7", + "weight": "3.0", + "id": "882", + "maxAmount": "7" + }, + { + "minAmount": "4", + "weight": "2.0", + "id": "557", + "maxAmount": "4" + }, + { + "minAmount": "6", + "weight": "2.0", + "id": "554", + "maxAmount": "6" + }, + { + "minAmount": "9", + "weight": "2.0", + "id": "558", + "maxAmount": "9" + }, + { + "minAmount": "2", + "weight": "1.0", + "id": "562", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "23.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "37.0", + "id": "995", + "maxAmount": "3" + }, + { + "minAmount": "5", + "weight": "9.0", + "id": "995", + "maxAmount": "5" + }, + { + "minAmount": "15", + "weight": "4.0", + "id": "995", + "maxAmount": "15" + }, + { + "minAmount": "25", + "weight": "1.0", + "id": "995", + "maxAmount": "25" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "313", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "436", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1965", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "7,1377,1757,1758,1759,1760,1761,7128,7129,7130", + "description": "", + "main": [ + { + "minAmount": "4", + "weight": "2.0", + "id": "557", + "maxAmount": "4" + }, + { + "minAmount": "6", + "weight": "2.0", + "id": "554", + "maxAmount": "6" + }, + { + "minAmount": "9", + "weight": "2.0", + "id": "558", + "maxAmount": "9" + }, + { + "minAmount": "2", + "weight": "1.0", + "id": "562", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "11.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "27.0", + "id": "14430", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "38.0", + "id": "995", + "maxAmount": "3" + }, + { + "minAmount": "25", + "weight": "1.0", + "id": "995", + "maxAmount": "25" + }, + { + "minAmount": "1", + "weight": "27.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "313", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "5341", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "5345", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "5343", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "5329", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "5340", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "8,282,2674,2696,5926,5927,5928,5929", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "882", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "877", + "maxAmount": "2" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "877", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1381", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "863", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "562", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "557", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "554", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "558", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "995", + "maxAmount": "3" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "995", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "436", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "91.6064", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "7.0005", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.7927", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.4372", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.1632", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "9,32,206,296,297,298,299,344,345,346,368,678,812,887,1142,1143,1144,1145,1146,1147,1148,1149,1150,1296,1297,1374,1805,1806,2699,2700,2701,2702,2703,2704,2705,2962,2963,2964,2965,2966,2967,2968,2969,2970,2971,2972,2973,3228,3229,3230,3231,3232,3233,3241,3407,3408,3715,3941,3942,4257,4258,4259,4260,4301,4302,4303,4304,4305,4306,4307,4308,4309,4310,4311,4336,4993,4994,4995,4996,4997,4998,4999,5000,5001,5002,5489,5490,5491,5492,5800,5801,5919,5920,6183,6184,6190,6498,6499,6500,6501,6502,6503,7142", + "description": "", + "main": [ + { + "minAmount": "4", + "weight": "50.0", + "id": "5318", + "maxAmount": "6" + }, + { + "minAmount": "4", + "weight": "50.0", + "id": "5319", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "5324", + "maxAmount": "4" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "5322", + "maxAmount": "4" + }, + { + "minAmount": "3", + "weight": "5.0", + "id": "5320", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5323", + "maxAmount": "4" + }, + { + "minAmount": "2", + "weight": "3.0", + "id": "5321", + "maxAmount": "4" + }, + { + "minAmount": "6", + "weight": "50.0", + "id": "556", + "maxAmount": "6" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "557", + "maxAmount": "6" + }, + { + "minAmount": "2", + "weight": "50.0", + "id": "554", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1446", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1458", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "565", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "561", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "562", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1339", + "maxAmount": "1" + }, + { + "minAmount": "12", + "weight": "50.0", + "id": "884", + "maxAmount": "12" + }, + { + "minAmount": "2", + "weight": "50.0", + "id": "9140", + "maxAmount": "18" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "882", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "886", + "maxAmount": "11" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "995", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "50.0", + "id": "995", + "maxAmount": "2" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "1987", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2347", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1947", + "maxAmount": "1" + }, + { + "minAmount": "4", + "weight": "5.0", + "id": "1947", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1115", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2353", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "91.6064", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "94.08", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.2133", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.1733", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.2667", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.2667", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "12,3246,3247,3248,3249,3250,3251,3252,3253,3255,3256,3257,3258,3259,3260,3261,3262,3263,5909", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "3.0", + "id": "1351", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1349", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1379", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1375", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1420", + "maxAmount": "1" + }, + { + "minAmount": "15", + "weight": "3.0", + "id": "882", + "maxAmount": "15" + }, + { + "minAmount": "8", + "weight": "3.0", + "id": "884", + "maxAmount": "8" + }, + { + "minAmount": "3", + "weight": "1.0", + "id": "562", + "maxAmount": "3" + }, + { + "minAmount": "5", + "weight": "3.0", + "id": "557", + "maxAmount": "5" + }, + { + "minAmount": "8", + "weight": "2.0", + "id": "554", + "maxAmount": "8" + }, + { + "minAmount": "10", + "weight": "2.0", + "id": "558", + "maxAmount": "10" + }, + { + "minAmount": "2", + "weight": "1.0", + "id": "563", + "maxAmount": "2" + }, + { + "minAmount": "5", + "weight": "41.0", + "id": "995", + "maxAmount": "5" + }, + { + "minAmount": "8", + "weight": "9.0", + "id": "995", + "maxAmount": "8" + }, + { + "minAmount": "25", + "weight": "5.0", + "id": "995", + "maxAmount": "25" + }, + { + "minAmount": "32", + "weight": "3.0", + "id": "995", + "maxAmount": "32" + }, + { + "minAmount": "1", + "weight": "36.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "438", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "948", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1917", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "2142", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "956", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1592", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "77.9122", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "12.4761", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.5379", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.8192", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.2546", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "13,652,1263,5195,5196,5197", + "description": "", + "main": [ + { + "minAmount": "5", + "weight": "3.0", + "id": "556", + "maxAmount": "5" + }, + { + "minAmount": "12", + "weight": "2.0", + "id": "556", + "maxAmount": "12" + }, + { + "minAmount": "5", + "weight": "3.0", + "id": "554", + "maxAmount": "5" + }, + { + "minAmount": "12", + "weight": "2.0", + "id": "554", + "maxAmount": "12" + }, + { + "minAmount": "5", + "weight": "3.0", + "id": "555", + "maxAmount": "5" + }, + { + "minAmount": "12", + "weight": "2.0", + "id": "555", + "maxAmount": "12" + }, + { + "minAmount": "5", + "weight": "3.0", + "id": "557", + "maxAmount": "5" + }, + { + "minAmount": "12", + "weight": "2.0", + "id": "557", + "maxAmount": "12" + }, + { + "minAmount": "5", + "weight": "3.0", + "id": "559", + "maxAmount": "5" + }, + { + "minAmount": "12", + "weight": "2.0", + "id": "559", + "maxAmount": "12" + }, + { + "minAmount": "5", + "weight": "3.0", + "id": "558", + "maxAmount": "5" + }, + { + "minAmount": "12", + "weight": "2.0", + "id": "558", + "maxAmount": "12" + }, + { + "minAmount": "2", + "weight": "8.0", + "id": "562", + "maxAmount": "2" + }, + { + "minAmount": "10", + "weight": "1.0", + "id": "562", + "maxAmount": "10" + }, + { + "minAmount": "2", + "weight": "8.0", + "id": "561", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "1.0", + "id": "563", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "1.0", + "id": "565", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "1379", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1448", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1444", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1442", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "20.0", + "id": "995", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "9.0", + "id": "995", + "maxAmount": "2" + }, + { + "minAmount": "18", + "weight": "7.0", + "id": "995", + "maxAmount": "18" + }, + { + "minAmount": "30", + "weight": "1.0", + "id": "995", + "maxAmount": "30" + }, + { + "minAmount": "1", + "weight": "16.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "577", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "579", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "89.3939", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.6277", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.9481", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.7316", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.2987", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "15", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "89.3939", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "18", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "2.0", + "id": "1139", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1203", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "22.0", + "id": "877", + "maxAmount": "12" + }, + { + "minAmount": "7", + "weight": "3.0", + "id": "882", + "maxAmount": "7" + }, + { + "minAmount": "4", + "weight": "2.0", + "id": "557", + "maxAmount": "4" + }, + { + "minAmount": "6", + "weight": "2.0", + "id": "554", + "maxAmount": "6" + }, + { + "minAmount": "9", + "weight": "2.0", + "id": "558", + "maxAmount": "9" + }, + { + "minAmount": "2", + "weight": "1.0", + "id": "562", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "23.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "37.0", + "id": "995", + "maxAmount": "3" + }, + { + "minAmount": "5", + "weight": "9.0", + "id": "995", + "maxAmount": "5" + }, + { + "minAmount": "15", + "weight": "4.0", + "id": "995", + "maxAmount": "15" + }, + { + "minAmount": "25", + "weight": "1.0", + "id": "995", + "maxAmount": "25" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "313", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "436", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1965", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "19,1092,3348,3349,3350", + "description": "", + "main": [ + { + "minAmount": "20", + "weight": "50.0", + "id": "555", + "maxAmount": "47" + }, + { + "minAmount": "9", + "weight": "50.0", + "id": "559", + "maxAmount": "24" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "558", + "maxAmount": "5" + }, + { + "minAmount": "7", + "weight": "50.0", + "id": "558", + "maxAmount": "7" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "562", + "maxAmount": "5" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "561", + "maxAmount": "7" + }, + { + "minAmount": "2", + "weight": "5.0", + "id": "563", + "maxAmount": "3" + }, + { + "minAmount": "2", + "weight": "5.0", + "id": "565", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1293", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1281", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "888", + "maxAmount": "5" + }, + { + "minAmount": "7", + "weight": "50.0", + "id": "888", + "maxAmount": "7" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "890", + "maxAmount": "5" + }, + { + "minAmount": "7", + "weight": "25.0", + "id": "890", + "maxAmount": "7" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1141", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "4", + "weight": "50.0", + "id": "5318", + "maxAmount": "4" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "5322", + "maxAmount": "3" + }, + { + "minAmount": "4", + "weight": "50.0", + "id": "5324", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "50.0", + "id": "5319", + "maxAmount": "4" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "5320", + "maxAmount": "3" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "5321", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "5.0", + "id": "5323", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "995", + "maxAmount": "200" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1933", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2335", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "2351", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "20,365,2256", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "2.0", + "id": "1281", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1295", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1157", + "maxAmount": "1" + }, + { + "minAmount": "30", + "weight": "13.0", + "id": "555", + "maxAmount": "30" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "565", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "9.0", + "id": "2351", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "2353", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "2359", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "16.0", + "id": "995", + "maxAmount": "2" + }, + { + "minAmount": "8", + "weight": "10.0", + "id": "995", + "maxAmount": "8" + }, + { + "minAmount": "15", + "weight": "18.0", + "id": "995", + "maxAmount": "15" + }, + { + "minAmount": "48", + "weight": "40.0", + "id": "995", + "maxAmount": "48" + }, + { + "minAmount": "120", + "weight": "2.0", + "id": "995", + "maxAmount": "120" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "5733", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "21,1072", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "23,26", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "127.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "38,39,675", + "description": "", + "main": [ + { + "minAmount": "10", + "weight": "50.0", + "id": "995", + "maxAmount": "56" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "2138", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "41,288,951,1017,1401,1402,2313,2314,2315", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "32.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "64.0", + "id": "314", + "maxAmount": "5" + }, + { + "minAmount": "15", + "weight": "32.0", + "id": "314", + "maxAmount": "15" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "20.1053", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "69.0441", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0025", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.8402", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0079", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "49,3586,6210", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "126.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "12070", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "536", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "1747", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "4", + "weight": "28.2697", + "id": "0", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "4.6304", + "id": "12158", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "4.2242", + "id": "12159", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "61.4947", + "id": "12160", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "1.381", + "id": "12163", + "maxAmount": "4" + } + ], + "tertiary": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "7980", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "127.0", + "id": "0", + "maxAmount": "1" + } + ], + "ids": "50,2642", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "1369", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1315", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1357", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1317", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1303", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1123", + "maxAmount": "1" + }, + { + "minAmount": "105", + "weight": "50.0", + "id": "556", + "maxAmount": "105" + }, + { + "minAmount": "105", + "weight": "50.0", + "id": "554", + "maxAmount": "105" + }, + { + "minAmount": "7", + "weight": "25.0", + "id": "560", + "maxAmount": "7" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "565", + "maxAmount": "15" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "563", + "maxAmount": "15" + }, + { + "minAmount": "690", + "weight": "25.0", + "id": "884", + "maxAmount": "690" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "9144", + "maxAmount": "12" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1725", + "maxAmount": "1" + }, + { + "minAmount": "100", + "weight": "25.0", + "id": "441", + "maxAmount": "100" + }, + { + "minAmount": "100", + "weight": "25.0", + "id": "1516", + "maxAmount": "100" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "9431", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2361", + "maxAmount": "1" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "385", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "407", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "30", + "weight": "50.0", + "id": "995", + "maxAmount": "690" + }, + { + "minAmount": "1", + "weight": "0.20404", + "id": "11286", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "200.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "534", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "52,4665,4666", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "536", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "1749", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "18.0057", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "17.6693", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "43.5864", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "17.0291", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.7095", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "53,4669,4670,4671,4672", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "4.0", + "id": "1315", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1355", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1369", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1197", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1123", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1303", + "maxAmount": "1" + }, + { + "minAmount": "20", + "weight": "20.0", + "id": "828", + "maxAmount": "20" + }, + { + "minAmount": "4", + "weight": "8.0", + "id": "892", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "5.0", + "id": "563", + "maxAmount": "4" + }, + { + "minAmount": "2", + "weight": "4.0", + "id": "565", + "maxAmount": "2" + }, + { + "minAmount": "8", + "weight": "3.0", + "id": "811", + "maxAmount": "8" + }, + { + "minAmount": "5", + "weight": "3.0", + "id": "560", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "15.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "196", + "weight": "36.0", + "id": "995", + "maxAmount": "196" + }, + { + "minAmount": "330", + "weight": "10.0", + "id": "995", + "maxAmount": "330" + }, + { + "minAmount": "690", + "weight": "1.0", + "id": "995", + "maxAmount": "690" + }, + { + "minAmount": "3", + "weight": "3.0", + "id": "1897", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "2361", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.25", + "id": "12477", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "536", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "1747", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "3", + "weight": "56.6693", + "id": "0", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "8.6692", + "id": "12158", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "26.5555", + "id": "12159", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "6.759", + "id": "12160", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "1.3469", + "id": "12163", + "maxAmount": "3" + } + ], + "ids": "54,4673,4674,4675,4676", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "4.0", + "id": "1315", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1361", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1355", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1369", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1197", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1123", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1303", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1113", + "maxAmount": "1" + }, + { + "minAmount": "30", + "weight": "20.0", + "id": "829", + "maxAmount": "30" + }, + { + "minAmount": "50", + "weight": "8.0", + "id": "554", + "maxAmount": "50" + }, + { + "minAmount": "16", + "weight": "7.0", + "id": "816", + "maxAmount": "16" + }, + { + "minAmount": "10", + "weight": "5.0", + "id": "563", + "maxAmount": "10" + }, + { + "minAmount": "2", + "weight": "3.0", + "id": "868", + "maxAmount": "2" + }, + { + "minAmount": "15", + "weight": "3.0", + "id": "565", + "maxAmount": "15" + }, + { + "minAmount": "75", + "weight": "1.0", + "id": "556", + "maxAmount": "75" + }, + { + "minAmount": "10", + "weight": "1.0", + "id": "562", + "maxAmount": "10" + }, + { + "minAmount": "196", + "weight": "40.0", + "id": "995", + "maxAmount": "196" + }, + { + "minAmount": "330", + "weight": "10.0", + "id": "995", + "maxAmount": "330" + }, + { + "minAmount": "690", + "weight": "1.0", + "id": "995", + "maxAmount": "690" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "2361", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1897", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.25", + "id": "12480", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.0128", + "id": "11286", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "536", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "1751", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "48.5393", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "11.0668", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "27.2748", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.9091", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.21", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "55,4681,4682,4683,4684,5178", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "4.0", + "id": "1069", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1355", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1365", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1243", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1161", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1197", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1245", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1213", + "maxAmount": "1" + }, + { + "minAmount": "75", + "weight": "8.0", + "id": "555", + "maxAmount": "75" + }, + { + "minAmount": "15", + "weight": "5.0", + "id": "561", + "maxAmount": "15" + }, + { + "minAmount": "3", + "weight": "3.0", + "id": "563", + "maxAmount": "3" + }, + { + "minAmount": "37", + "weight": "1.0", + "id": "554", + "maxAmount": "37" + }, + { + "minAmount": "8", + "weight": "1.0", + "id": "565", + "maxAmount": "8" + }, + { + "minAmount": "1", + "weight": "15.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "11", + "weight": "5.0", + "id": "995", + "maxAmount": "11" + }, + { + "minAmount": "44", + "weight": "26.0", + "id": "995", + "maxAmount": "44" + }, + { + "minAmount": "132", + "weight": "25.0", + "id": "995", + "maxAmount": "132" + }, + { + "minAmount": "200", + "weight": "10.0", + "id": "995", + "maxAmount": "200" + }, + { + "minAmount": "440", + "weight": "1.0", + "id": "995", + "maxAmount": "440" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "449", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "365", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.25", + "id": "12478", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "1", + "weight": "87.586", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.549", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.8189", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.3911", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.6551", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "59,60", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "2.0", + "id": "839", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1139", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1189", + "maxAmount": "1" + }, + { + "minAmount": "8", + "weight": "3.0", + "id": "882", + "maxAmount": "8" + }, + { + "minAmount": "8", + "weight": "3.0", + "id": "877", + "maxAmount": "8" + }, + { + "minAmount": "6", + "weight": "2.0", + "id": "556", + "maxAmount": "6" + }, + { + "minAmount": "4", + "weight": "2.0", + "id": "557", + "maxAmount": "4" + }, + { + "minAmount": "6", + "weight": "2.0", + "id": "554", + "maxAmount": "6" + }, + { + "minAmount": "7", + "weight": "2.0", + "id": "559", + "maxAmount": "7" + }, + { + "minAmount": "6", + "weight": "1.0", + "id": "558", + "maxAmount": "6" + }, + { + "minAmount": "1", + "weight": "19.0", + "id": "995", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "40.0", + "id": "995", + "maxAmount": "5" + }, + { + "minAmount": "12", + "weight": "10.0", + "id": "995", + "maxAmount": "12" + }, + { + "minAmount": "20", + "weight": "1.0", + "id": "995", + "maxAmount": "20" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "229", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "2307", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1965", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1009", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "30.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "1", + "weight": "91.8947", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.065", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.2525", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.3423", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.4455", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "61,1004,1221,1473,1474,4400,4401,7207", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "6291", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "62,1478,2491,2492,6376,6377", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "2.0", + "id": "1233", + "maxAmount": "1" + }, + { + "minAmount": "17", + "weight": "8.0", + "id": "9288", + "maxAmount": "17" + }, + { + "minAmount": "12", + "weight": "8.0", + "id": "814", + "maxAmount": "12" + }, + { + "minAmount": "13", + "weight": "2.0", + "id": "557", + "maxAmount": "13" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "1", + "weight": "72.2513", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0631", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.9319", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.6049", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.1488", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "63", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "1", + "weight": "62.4612", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "23.1644", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.4798", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.4467", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.4478", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "64", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "71", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "4.0", + "id": "1307", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1375", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "4.0", + "id": "806", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "3190", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1321", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1337", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "4.0", + "id": "807", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1293", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1420", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1323", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1239", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1353", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1424", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1139", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1155", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1075", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1101", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1141", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "4.0", + "id": "995", + "maxAmount": "5" + }, + { + "minAmount": "8", + "weight": "4.0", + "id": "995", + "maxAmount": "8" + }, + { + "minAmount": "10", + "weight": "4.0", + "id": "995", + "maxAmount": "10" + }, + { + "minAmount": "12", + "weight": "4.0", + "id": "995", + "maxAmount": "12" + }, + { + "minAmount": "23", + "weight": "4.0", + "id": "995", + "maxAmount": "23" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "946", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "5105", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "14424", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "73,74,75,419,420,421,422,423,424,2714,2863,2866,2869,2878,3622,4392,4393,4394,5293,5294,5295,5296,5297,5298,5299,5300,5301,5302,5303,5304,5305,5306,5307,5308,5309,5310,5311,5312,5313,5314,5315,5316,5317,5318,5319,5320,5321,5322,5323,5324,5325,5326,5327,5328,5329,5330,5331,5375,5376,5377,5378,5379,5380,5393,5394,5395,5396,5397,5398,5399,5400,5401,5402,5403,5404,5405,5406,5407,5408,5409,5410,6099,6100,6131", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "4.0", + "id": "1139", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1420", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1291", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1189", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1349", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "7.0", + "id": "884", + "maxAmount": "5" + }, + { + "minAmount": "8", + "weight": "4.0", + "id": "884", + "maxAmount": "8" + }, + { + "minAmount": "5", + "weight": "2.0", + "id": "886", + "maxAmount": "5" + }, + { + "minAmount": "6", + "weight": "5.0", + "id": "559", + "maxAmount": "6" + }, + { + "minAmount": "5", + "weight": "5.0", + "id": "558", + "maxAmount": "5" + }, + { + "minAmount": "13", + "weight": "4.0", + "id": "556", + "maxAmount": "13" + }, + { + "minAmount": "7", + "weight": "1.0", + "id": "554", + "maxAmount": "7" + }, + { + "minAmount": "6", + "weight": "1.0", + "id": "561", + "maxAmount": "6" + }, + { + "minAmount": "4", + "weight": "1.0", + "id": "562", + "maxAmount": "4" + }, + { + "minAmount": "2", + "weight": "1.0", + "id": "564", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "4", + "weight": "4.0", + "id": "995", + "maxAmount": "4" + }, + { + "minAmount": "10", + "weight": "11.0", + "id": "995", + "maxAmount": "10" + }, + { + "minAmount": "18", + "weight": "2.0", + "id": "995", + "maxAmount": "18" + }, + { + "minAmount": "26", + "weight": "3.0", + "id": "995", + "maxAmount": "26" + }, + { + "minAmount": "35", + "weight": "2.0", + "id": "995", + "maxAmount": "35" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "313", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "436", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "438", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "221", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "590", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1351", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "77", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "530", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "78.7445", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "19.2498", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.521", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.2069", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.2779", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "78,1005,2482,3711", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "1739", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "2132", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "94.9773", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.8562", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.8921", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.2258", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.0486", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "81,397,955,1767,3309", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "592", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "93.9387", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.8077", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.7671", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.8683", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.6181", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "82,4694,4695,4696,4697,6101", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "4.0", + "id": "1353", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1157", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1325", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1181", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1109", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1147", + "maxAmount": "1" + }, + { + "minAmount": "60", + "weight": "8.0", + "id": "554", + "maxAmount": "60" + }, + { + "minAmount": "12", + "weight": "5.0", + "id": "562", + "maxAmount": "12" + }, + { + "minAmount": "3", + "weight": "3.0", + "id": "560", + "maxAmount": "3" + }, + { + "minAmount": "30", + "weight": "1.0", + "id": "554", + "maxAmount": "30" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "10", + "weight": "7.0", + "id": "995", + "maxAmount": "10" + }, + { + "minAmount": "40", + "weight": "29.0", + "id": "995", + "maxAmount": "40" + }, + { + "minAmount": "120", + "weight": "40.0", + "id": "995", + "maxAmount": "120" + }, + { + "minAmount": "200", + "weight": "10.0", + "id": "995", + "maxAmount": "200" + }, + { + "minAmount": "450", + "weight": "1.0", + "id": "995", + "maxAmount": "450" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1993", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "444", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "14426", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "592", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "62.1649", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "6.9276", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.7889", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "26.1919", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.9267", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "83,4698,4699,4700,4701", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "4.0", + "id": "1311", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1353", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1365", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1197", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1073", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1163", + "maxAmount": "1" + }, + { + "minAmount": "75", + "weight": "8.0", + "id": "554", + "maxAmount": "75" + }, + { + "minAmount": "15", + "weight": "3.0", + "id": "562", + "maxAmount": "15" + }, + { + "minAmount": "5", + "weight": "3.0", + "id": "560", + "maxAmount": "5" + }, + { + "minAmount": "37", + "weight": "1.0", + "id": "554", + "maxAmount": "37" + }, + { + "minAmount": "11", + "weight": "7.0", + "id": "995", + "maxAmount": "11" + }, + { + "minAmount": "44", + "weight": "28.0", + "id": "995", + "maxAmount": "44" + }, + { + "minAmount": "132", + "weight": "40.0", + "id": "995", + "maxAmount": "132" + }, + { + "minAmount": "220", + "weight": "10.0", + "id": "995", + "maxAmount": "220" + }, + { + "minAmount": "460", + "weight": "1.0", + "id": "995", + "maxAmount": "460" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "361", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "2357", + "maxAmount": "1" + }, + { + "minAmount": "10", + "weight": "1.0", + "id": "1734", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "12070", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "592", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "22.5725", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "20.8465", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.762", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "44.1955", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.6236", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "84,677,4702,4703,4704,4705", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "4.0", + "id": "1283", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1365", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1361", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1165", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1197", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1147", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1113", + "maxAmount": "1" + }, + { + "minAmount": "50", + "weight": "8.0", + "id": "556", + "maxAmount": "50" + }, + { + "minAmount": "10", + "weight": "7.0", + "id": "562", + "maxAmount": "10" + }, + { + "minAmount": "7", + "weight": "4.0", + "id": "565", + "maxAmount": "7" + }, + { + "minAmount": "37", + "weight": "1.0", + "id": "554", + "maxAmount": "37" + }, + { + "minAmount": "3", + "weight": "1.0", + "id": "563", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "23.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "30", + "weight": "7.0", + "id": "995", + "maxAmount": "30" + }, + { + "minAmount": "44", + "weight": "6.0", + "id": "995", + "maxAmount": "44" + }, + { + "minAmount": "132", + "weight": "38.0", + "id": "995", + "maxAmount": "132" + }, + { + "minAmount": "220", + "weight": "6.0", + "id": "995", + "maxAmount": "220" + }, + { + "minAmount": "460", + "weight": "1.0", + "id": "995", + "maxAmount": "460" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "379", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "2361", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "133", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "12070", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "2134", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "86,87,446,950,4395,4922,4923,4924,4925,4926,4927,4942,4943,4944,4945", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "88,224,4928,4929,4936,4937", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "2134", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "237", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "89,987", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "90.3666", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.2856", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.8525", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.4723", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.023", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "90,91,92,93,459,1471,2036,2037,2715,3151,3291,3581,4384,4385,4386,5332,5333,5334,5335,5336,5337,5338,5339,5340,5341,5365,5366,5367,5368,5381,5385,5386,5387,5388,5389,5390,5391,5392,5411,5412,5422,6091,6092,6093,6764,6765,6766,6767,6768", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "6.0", + "id": "1203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "6.0", + "id": "1137", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1279", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1349", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1323", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "4.0", + "id": "882", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "884", + "maxAmount": "1" + }, + { + "minAmount": "15", + "weight": "2.0", + "id": "556", + "maxAmount": "15" + }, + { + "minAmount": "3", + "weight": "2.0", + "id": "557", + "maxAmount": "3" + }, + { + "minAmount": "2", + "weight": "2.0", + "id": "554", + "maxAmount": "2" + }, + { + "minAmount": "3", + "weight": "2.0", + "id": "562", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "1.0", + "id": "561", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "886", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "20.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "18.0", + "id": "995", + "maxAmount": "2" + }, + { + "minAmount": "4", + "weight": "7.0", + "id": "995", + "maxAmount": "4" + }, + { + "minAmount": "12", + "weight": "7.0", + "id": "995", + "maxAmount": "12" + }, + { + "minAmount": "16", + "weight": "4.0", + "id": "995", + "maxAmount": "16" + }, + { + "minAmount": "25", + "weight": "4.0", + "id": "995", + "maxAmount": "25" + }, + { + "minAmount": "33", + "weight": "4.0", + "id": "995", + "maxAmount": "33" + }, + { + "minAmount": "48", + "weight": "4.0", + "id": "995", + "maxAmount": "48" + }, + { + "minAmount": "1", + "weight": "18.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1442", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1947", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "14426", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "592", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "94,3844,3850,3851", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "1013", + "maxAmount": "1" + }, + { + "minAmount": "7", + "weight": "50.0", + "id": "558", + "maxAmount": "9" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "562", + "maxAmount": "4" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "563", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "561", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "27", + "weight": "50.0", + "id": "995", + "maxAmount": "434" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1625", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1934", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2351", + "maxAmount": "2" + }, + { + "minAmount": "3", + "weight": "5.0", + "id": "532", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "2859", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "88.6454", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.5857", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.992", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.5777", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.1992", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "95,142,1330,4413,4414,6047,6048,6049", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "7830", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "2859", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "73.057", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "9.8446", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.849", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "12.8793", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.3701", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "96,97", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "99,3582,6374", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "88.8944", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "9.6568", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.3775", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.9295", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.1418", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "100,101,102,444,445,1769,1770,1771,1772,1773,1774,1775,1776,2274,2275,2276,2277,2278,2279,2280,2281,2678,2679,2680,2681,3264,3265,3266,3267,3726,4261,4262,4263,4264,4265,4266,4267,4268,4269,4270,4271,4272,4273,4274,4275,4276,4407,4408,4409,4410,4411,4412,4479,4480,4481,4482,4483,4484,4485,4486,4487,4488,4489,4490,4491,4492,4499,4633,4634,4635,4636,4637,5855,5856,6125,6126,6132,6133,6279,6280,6281,6282,6283,6402,6403,6404,6405,6406,6407,6408,6409,6410,6411,6412,6413,6414,6415,6416,6417,6418,6419,6420,6421,6422,6423,6424,6425,6426,6427,6428,6429,6430,6431,6432,6433,6434,6435,6436,6437,6438,6439,6440,6441,6442,6443,6444,6445,6446,6447,6448,6449,6450,6451,6452,6453,6454,6455,6456,6457,6458,6459,6460,6461,6462,6463,6464,6465,6466,6467,6490,6491,6492,6493,6494,6495,7964", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "4.0", + "id": "1237", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1173", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1351", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1139", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1139", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1189", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1155", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1153", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1239", + "maxAmount": "1" + }, + { + "minAmount": "6", + "weight": "5.0", + "id": "555", + "maxAmount": "6" + }, + { + "minAmount": "7", + "weight": "5.0", + "id": "559", + "maxAmount": "7" + }, + { + "minAmount": "4", + "weight": "3.0", + "id": "557", + "maxAmount": "4" + }, + { + "minAmount": "7", + "weight": "3.0", + "id": "882", + "maxAmount": "7" + }, + { + "minAmount": "8", + "weight": "3.0", + "id": "877", + "maxAmount": "8" + }, + { + "minAmount": "5", + "weight": "2.0", + "id": "825", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "562", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "561", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "995", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "35.0", + "id": "995", + "maxAmount": "5" + }, + { + "minAmount": "9", + "weight": "3.0", + "id": "995", + "maxAmount": "9" + }, + { + "minAmount": "15", + "weight": "3.0", + "id": "995", + "maxAmount": "15" + }, + { + "minAmount": "20", + "weight": "2.0", + "id": "995", + "maxAmount": "20" + }, + { + "minAmount": "1", + "weight": "15.0", + "id": "2347", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "288", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1949", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1965", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1917", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "10999", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1009", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1987", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "438", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1438", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "948", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "2136", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "85.6976", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.7526", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.596", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.6717", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.2821", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "105,1195", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "948", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "2136", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "82.1397", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "16.534", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.4421", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.5305", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.3537", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "106", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "532", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "30.6289", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "55.6271", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "7.2156", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0098", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.5185", + "id": "12163", + "maxAmount": "1" + } + ], + "tertiary": [ + { + "minAmount": "1", + "weight": "9973.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "10976", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "10977", + "maxAmount": "1" + } + ], + "ids": "110,1582,1583,1584,1585,1586,7003,7004", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "3.0", + "id": "1353", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1181", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1393", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1333", + "maxAmount": "1" + }, + { + "minAmount": "150", + "weight": "10.0", + "id": "554", + "maxAmount": "150" + }, + { + "minAmount": "5", + "weight": "7.0", + "id": "562", + "maxAmount": "5" + }, + { + "minAmount": "12", + "weight": "5.0", + "id": "892", + "maxAmount": "12" + }, + { + "minAmount": "5", + "weight": "4.0", + "id": "565", + "maxAmount": "5" + }, + { + "minAmount": "37", + "weight": "1.0", + "id": "554", + "maxAmount": "37" + }, + { + "minAmount": "2", + "weight": "1.0", + "id": "563", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "19.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "60", + "weight": "40.0", + "id": "995", + "maxAmount": "60" + }, + { + "minAmount": "15", + "weight": "7.0", + "id": "995", + "maxAmount": "15" + }, + { + "minAmount": "25", + "weight": "6.0", + "id": "995", + "maxAmount": "25" + }, + { + "minAmount": "300", + "weight": "2.0", + "id": "995", + "maxAmount": "300" + }, + { + "minAmount": "50", + "weight": "1.0", + "id": "995", + "maxAmount": "50" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "379", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "2353", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "117", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "11.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "532", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "45.9587", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "44.7868", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.9505", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.5777", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.7263", + "id": "12163", + "maxAmount": "1" + } + ], + "tertiary": [ + { + "minAmount": "1", + "weight": "9973.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "10976", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "10977", + "maxAmount": "1" + } + ], + "ids": "111,3072,4685,4686,4687", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "5.0", + "id": "1309", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1195", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1353", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1281", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1067", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1428", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1181", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "6.0", + "id": "890", + "maxAmount": "5" + }, + { + "minAmount": "6", + "weight": "4.0", + "id": "561", + "maxAmount": "6" + }, + { + "minAmount": "24", + "weight": "3.0", + "id": "558", + "maxAmount": "24" + }, + { + "minAmount": "37", + "weight": "3.0", + "id": "559", + "maxAmount": "37" + }, + { + "minAmount": "3", + "weight": "2.0", + "id": "563", + "maxAmount": "3" + }, + { + "minAmount": "12", + "weight": "1.0", + "id": "555", + "maxAmount": "12" + }, + { + "minAmount": "4", + "weight": "1.0", + "id": "564", + "maxAmount": "4" + }, + { + "minAmount": "3", + "weight": "1.0", + "id": "560", + "maxAmount": "3" + }, + { + "minAmount": "2", + "weight": "1.0", + "id": "565", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "14422", + "maxAmount": "1" + }, + { + "minAmount": "117", + "weight": "32.0", + "id": "995", + "maxAmount": "117" + }, + { + "minAmount": "53", + "weight": "12.0", + "id": "995", + "maxAmount": "53" + }, + { + "minAmount": "196", + "weight": "10.0", + "id": "995", + "maxAmount": "196" + }, + { + "minAmount": "8", + "weight": "7.0", + "id": "995", + "maxAmount": "8" + }, + { + "minAmount": "22", + "weight": "6.0", + "id": "995", + "maxAmount": "22" + }, + { + "minAmount": "400", + "weight": "1.0", + "id": "995", + "maxAmount": "400" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1993", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "447", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1963", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "5733", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "532", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "61.6452", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "32.5923", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.7924", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.4366", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.5336", + "id": "12163", + "maxAmount": "1" + } + ], + "tertiary": [ + { + "minAmount": "1", + "weight": "9973.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "10976", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "10977", + "maxAmount": "1" + } + ], + "ids": "112,1587,1588,1681,4534,4688,4706", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "5.0", + "id": "1179", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1389", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1141", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1285", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1243", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1193", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "4.0", + "id": "563", + "maxAmount": "3" + }, + { + "minAmount": "18", + "weight": "3.0", + "id": "556", + "maxAmount": "18" + }, + { + "minAmount": "27", + "weight": "3.0", + "id": "557", + "maxAmount": "27" + }, + { + "minAmount": "7", + "weight": "3.0", + "id": "562", + "maxAmount": "7" + }, + { + "minAmount": "6", + "weight": "3.0", + "id": "561", + "maxAmount": "6" + }, + { + "minAmount": "3", + "weight": "2.0", + "id": "564", + "maxAmount": "3" + }, + { + "minAmount": "15", + "weight": "2.0", + "id": "884", + "maxAmount": "15" + }, + { + "minAmount": "30", + "weight": "1.0", + "id": "886", + "maxAmount": "30" + }, + { + "minAmount": "3", + "weight": "1.0", + "id": "560", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "565", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "35.0", + "id": "14422", + "maxAmount": "1" + }, + { + "minAmount": "37", + "weight": "19.0", + "id": "995", + "maxAmount": "37" + }, + { + "minAmount": "2", + "weight": "8.0", + "id": "995", + "maxAmount": "2" + }, + { + "minAmount": "119", + "weight": "10.0", + "id": "995", + "maxAmount": "119" + }, + { + "minAmount": "300", + "weight": "2.0", + "id": "995", + "maxAmount": "300" + }, + { + "minAmount": "1", + "weight": "6.0", + "id": "2353", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "453", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1969", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "14426", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "3125", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "58.3163", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "36.367", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.4356", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.4642", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.4168", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "113,6268", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "30.0", + "id": "1237", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1239", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "2.0", + "id": "827", + "maxAmount": "5" + }, + { + "minAmount": "2", + "weight": "10.0", + "id": "561", + "maxAmount": "2" + }, + { + "minAmount": "5", + "weight": "2.0", + "id": "561", + "maxAmount": "5" + }, + { + "minAmount": "10", + "weight": "2.0", + "id": "561", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1533", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1525", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "15.0", + "id": "14422", + "maxAmount": "1" + }, + { + "minAmount": "22", + "weight": "20.0", + "id": "6306", + "maxAmount": "22" + }, + { + "minAmount": "2", + "weight": "4.0", + "id": "2114", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1963", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "946", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "526", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "2.0", + "id": "526", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "532", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "2.0", + "id": "532", + "maxAmount": "3" + }, + { + "minAmount": "6", + "weight": "1.0", + "id": "532", + "maxAmount": "6" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "536", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "5733", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "532", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "1000.0", + "id": "0", + "maxAmount": "1" + } + ], + "tertiary": [ + { + "minAmount": "1", + "weight": "4986.5", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "12.5", + "id": "10976", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "10977", + "maxAmount": "1" + } + ], + "ids": "114", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "39.0625", + "id": "6666", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "78.125", + "id": "6665", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "13.0", + "id": "14422", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "13.0", + "id": "14430", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "156.25", + "id": "345", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "156.25", + "id": "327", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "156.25", + "id": "371", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "156.25", + "id": "372", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "156.25", + "id": "359", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "156.25", + "id": "360", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "39.0625", + "id": "383", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "39.0625", + "id": "349", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "39.0625", + "id": "331", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "156.25", + "id": "313", + "maxAmount": "15" + }, + { + "minAmount": "1", + "weight": "156.25", + "id": "1511", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "39.0625", + "id": "1383", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "78.125", + "id": "407", + "maxAmount": "1" + }, + { + "minAmount": "4", + "weight": "78.125", + "id": "402", + "maxAmount": "8" + }, + { + "minAmount": "5", + "weight": "4.0", + "id": "555", + "maxAmount": "18" + }, + { + "minAmount": "3", + "weight": "78.125", + "id": "6664", + "maxAmount": "6" + }, + { + "minAmount": "1", + "weight": "39.0625", + "id": "401", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "39.0625", + "id": "6667", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "532", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "82.5938", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "13.9157", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.736", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.3739", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.3806", + "id": "12163", + "maxAmount": "1" + } + ], + "tertiary": [ + { + "minAmount": "1", + "weight": "9973.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "10976", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "10977", + "maxAmount": "1" + } + ], + "ids": "115,374,852,2801,3419,5174", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "19.0", + "id": "14422", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "109.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "532", + "maxAmount": "2" + } + ], + "charm": [], + "ids": "116,4291,4292,6078,6079,6080,6081,6269,6270", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "1309", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1424", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1281", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1283", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1217", + "maxAmount": "1" + }, + { + "minAmount": "4", + "weight": "50.0", + "id": "869", + "maxAmount": "19" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1295", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1365", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1311", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1297", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1313", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1299", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1430", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1317", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "5.0", + "id": "886", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1101", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1105", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1153", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1191", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1141", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1181", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1147", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "5.0", + "id": "563", + "maxAmount": "2" + }, + { + "minAmount": "3", + "weight": "5.0", + "id": "563", + "maxAmount": "3" + }, + { + "minAmount": "2", + "weight": "5.0", + "id": "560", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "5.0", + "id": "561", + "maxAmount": "2" + }, + { + "minAmount": "3", + "weight": "5.0", + "id": "561", + "maxAmount": "3" + }, + { + "minAmount": "2", + "weight": "5.0", + "id": "558", + "maxAmount": "2" + }, + { + "minAmount": "3", + "weight": "5.0", + "id": "558", + "maxAmount": "3" + }, + { + "minAmount": "2", + "weight": "5.0", + "id": "564", + "maxAmount": "2" + }, + { + "minAmount": "3", + "weight": "5.0", + "id": "564", + "maxAmount": "3" + }, + { + "minAmount": "7", + "weight": "5.0", + "id": "555", + "maxAmount": "7" + }, + { + "minAmount": "15", + "weight": "5.0", + "id": "554", + "maxAmount": "15" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5101", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5318", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "5320", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5321", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5298", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5292", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5323", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5281", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5311", + "maxAmount": "1" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "5324", + "maxAmount": "4" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "5309", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5295", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5293", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5294", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5105", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5104", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "12176", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5303", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5280", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5301", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5100", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5297", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5302", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5296", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1917", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "995", + "maxAmount": "473" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "225", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1446", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1442", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "10976", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "10977", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "532", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "85.0", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "7.0", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "7.0", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "12163", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "489.0", + "id": "0", + "maxAmount": "1" + } + ], + "ids": "117,4689,4690,4691,4692,4693", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "5.0", + "id": "1153", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1191", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1295", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "6.0", + "id": "884", + "maxAmount": "3" + }, + { + "minAmount": "15", + "weight": "3.0", + "id": "554", + "maxAmount": "15" + }, + { + "minAmount": "7", + "weight": "3.0", + "id": "555", + "maxAmount": "7" + }, + { + "minAmount": "2", + "weight": "3.0", + "id": "563", + "maxAmount": "2" + }, + { + "minAmount": "10", + "weight": "2.0", + "id": "886", + "maxAmount": "10" + }, + { + "minAmount": "3", + "weight": "2.0", + "id": "558", + "maxAmount": "3" + }, + { + "minAmount": "2", + "weight": "2.0", + "id": "564", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "1.0", + "id": "562", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "1.0", + "id": "560", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "7.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "18.0", + "id": "14430", + "maxAmount": "1" + }, + { + "minAmount": "38", + "weight": "14.0", + "id": "995", + "maxAmount": "38" + }, + { + "minAmount": "52", + "weight": "10.0", + "id": "995", + "maxAmount": "52" + }, + { + "minAmount": "15", + "weight": "8.0", + "id": "995", + "maxAmount": "15" + }, + { + "minAmount": "8", + "weight": "6.0", + "id": "995", + "maxAmount": "8" + }, + { + "minAmount": "88", + "weight": "2.0", + "id": "995", + "maxAmount": "88" + }, + { + "minAmount": "1", + "weight": "11.0", + "id": "225", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "6.0", + "id": "1917", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1446", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.6544", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.32", + "id": "10976", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.0256", + "id": "10977", + "maxAmount": "1" + }, + { + "minAmount": "6", + "weight": "2.0", + "id": "561", + "maxAmount": "6" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "90.789", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.7853", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.8556", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.9837", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.5864", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "118,120,121,382,582,3219,3220,3221,3268,3269,3270,3271,3272,3273,3274,3275,3294,3295,4316,5880,5881,5882,5883,5884,5885", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "10.0", + "id": "1265", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1139", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1375", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1267", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1363", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "7.0", + "id": "877", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "4.0", + "id": "562", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "4.0", + "id": "561", + "maxAmount": "2" + }, + { + "minAmount": "4", + "weight": "20.0", + "id": "995", + "maxAmount": "4" + }, + { + "minAmount": "10", + "weight": "15.0", + "id": "995", + "maxAmount": "10" + }, + { + "minAmount": "30", + "weight": "2.0", + "id": "995", + "maxAmount": "30" + }, + { + "minAmount": "1", + "weight": "20.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "2347", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "7.0", + "id": "2349", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "438", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "436", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "2351", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "453", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1913", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "81.6299", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "9.4137", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0075", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.2593", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.6896", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "119,2423", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "2.0", + "id": "1157", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1299", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1181", + "maxAmount": "1" + }, + { + "minAmount": "10", + "weight": "1.0", + "id": "555", + "maxAmount": "10" + }, + { + "minAmount": "24", + "weight": "3.0", + "id": "556", + "maxAmount": "24" + }, + { + "minAmount": "37", + "weight": "3.0", + "id": "558", + "maxAmount": "37" + }, + { + "minAmount": "3", + "weight": "2.0", + "id": "564", + "maxAmount": "3" + }, + { + "minAmount": "10", + "weight": "3.0", + "id": "562", + "maxAmount": "10" + }, + { + "minAmount": "9", + "weight": "3.0", + "id": "561", + "maxAmount": "9" + }, + { + "minAmount": "3", + "weight": "4.0", + "id": "563", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "1.0", + "id": "560", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "453", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "7.0", + "id": "991", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1985", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "6.0", + "id": "2359", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1982", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "15", + "weight": "2.0", + "id": "995", + "maxAmount": "15" + }, + { + "minAmount": "25", + "weight": "11.0", + "id": "995", + "maxAmount": "25" + }, + { + "minAmount": "47", + "weight": "13.0", + "id": "995", + "maxAmount": "47" + }, + { + "minAmount": "92", + "weight": "40.0", + "id": "995", + "maxAmount": "92" + }, + { + "minAmount": "150", + "weight": "10.0", + "id": "995", + "maxAmount": "150" + }, + { + "minAmount": "350", + "weight": "2.0", + "id": "995", + "maxAmount": "350" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "82.4038", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "15.9877", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.493", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.9659", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.1495", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "122,123,2685,2686,2687,2688,3583,4898,6275", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "1237", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "826", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "1207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1279", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1293", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1239", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "1241", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "1295", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "555", + "maxAmount": "2" + }, + { + "minAmount": "6", + "weight": "25.0", + "id": "559", + "maxAmount": "6" + }, + { + "minAmount": "7", + "weight": "25.0", + "id": "554", + "maxAmount": "7" + }, + { + "minAmount": "2", + "weight": "8.0", + "id": "564", + "maxAmount": "2" + }, + { + "minAmount": "3", + "weight": "8.0", + "id": "562", + "maxAmount": "3" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "561", + "maxAmount": "4" + }, + { + "minAmount": "2", + "weight": "8.0", + "id": "563", + "maxAmount": "2" + }, + { + "minAmount": "4", + "weight": "50.0", + "id": "5318", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "50.0", + "id": "5319", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "50.0", + "id": "5324", + "maxAmount": "4" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "5320", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5323", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5294", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5293", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "5322", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5321", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5306", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5311", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5104", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5105", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5106", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5280", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5281", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5100", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5296", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "12176", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5292", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5297", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5299", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5301", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5303", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5295", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5302", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "225", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "288", + "maxAmount": "1" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "6306", + "maxAmount": "15" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5300", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5304", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "1987", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "1", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "995", + "maxAmount": "62" + }, + { + "minAmount": "1", + "weight": "82.4038", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "1", + "weight": "74.8304", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "9.0131", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.5294", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.9457", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.6814", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "124", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "3.0", + "id": "1241", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1385", + "maxAmount": "1" + }, + { + "minAmount": "12", + "weight": "13.0", + "id": "557", + "maxAmount": "12" + }, + { + "minAmount": "3", + "weight": "9.0", + "id": "561", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "7.0", + "id": "562", + "maxAmount": "3" + }, + { + "minAmount": "2", + "weight": "6.0", + "id": "563", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "4.0", + "id": "560", + "maxAmount": "2" + }, + { + "minAmount": "60", + "weight": "3.0", + "id": "557", + "maxAmount": "60" + }, + { + "minAmount": "2", + "weight": "1.0", + "id": "565", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "14.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "18.0", + "id": "14422", + "maxAmount": "1" + }, + { + "minAmount": "12", + "weight": "18.0", + "id": "995", + "maxAmount": "12" + }, + { + "minAmount": "1", + "weight": "28.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "14426", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "1", + "weight": "53.6086", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "41.9912", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.4642", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.5197", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.4162", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "125,145,3073", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "3.0", + "id": "1363", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1309", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1281", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1195", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1428", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1181", + "maxAmount": "1" + }, + { + "minAmount": "4", + "weight": "10.0", + "id": "561", + "maxAmount": "4" + }, + { + "minAmount": "3", + "weight": "8.0", + "id": "562", + "maxAmount": "3" + }, + { + "minAmount": "2", + "weight": "7.0", + "id": "563", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "5.0", + "id": "564", + "maxAmount": "2" + }, + { + "minAmount": "3", + "weight": "5.0", + "id": "888", + "maxAmount": "3" + }, + { + "minAmount": "2", + "weight": "3.0", + "id": "560", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "2.0", + "id": "890", + "maxAmount": "2" + }, + { + "minAmount": "5", + "weight": "1.0", + "id": "890", + "maxAmount": "5" + }, + { + "minAmount": "2", + "weight": "1.0", + "id": "565", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "18.0", + "id": "14422", + "maxAmount": "1" + }, + { + "minAmount": "4", + "weight": "10.0", + "id": "995", + "maxAmount": "4" + }, + { + "minAmount": "15", + "weight": "18.0", + "id": "995", + "maxAmount": "15" + }, + { + "minAmount": "125", + "weight": "2.0", + "id": "995", + "maxAmount": "125" + }, + { + "minAmount": "1", + "weight": "13.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "447", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "126", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "2.0", + "id": "1391", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1428", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1357", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "9.0", + "id": "561", + "maxAmount": "5" + }, + { + "minAmount": "4", + "weight": "8.0", + "id": "562", + "maxAmount": "4" + }, + { + "minAmount": "15", + "weight": "8.0", + "id": "888", + "maxAmount": "15" + }, + { + "minAmount": "2", + "weight": "7.0", + "id": "563", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "5.0", + "id": "564", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "4.0", + "id": "560", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "1.0", + "id": "565", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "15", + "weight": "50.0", + "id": "995", + "maxAmount": "15" + }, + { + "minAmount": "1", + "weight": "18.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1641", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "355", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "14426", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "1363", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "127", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "128,1479,1875,4343", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "7862", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "532", + "maxAmount": "1" + }, + { + "minAmount": "15", + "weight": "100.0", + "id": "886", + "maxAmount": "26" + }, + { + "minAmount": "12", + "weight": "100.0", + "id": "802", + "maxAmount": "21" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "54.5455", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "21.6783", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "11.1888", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "6.2937", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "6.2937", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "130", + "description": "", + "main": [ + { + "minAmount": "21", + "weight": "50.0", + "id": "557", + "maxAmount": "21" + }, + { + "minAmount": "22", + "weight": "50.0", + "id": "557", + "maxAmount": "22" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "565", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "565", + "maxAmount": "3" + }, + { + "minAmount": "15", + "weight": "50.0", + "id": "562", + "maxAmount": "15" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "563", + "maxAmount": "13" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "561", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1442", + "maxAmount": "1" + }, + { + "minAmount": "99", + "weight": "5.0", + "id": "562", + "maxAmount": "99" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1181", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1145", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "147", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "165", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "3030", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5949", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "143", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "442", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "444", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "373", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "7054", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "7210", + "maxAmount": "1" + }, + { + "minAmount": "323", + "weight": "5.0", + "id": "995", + "maxAmount": "525" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "10976", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "10977", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "3166", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "12163", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5600.0", + "id": "0", + "maxAmount": "1" + } + ], + "ids": "132,1463,1464,1487,2301,4344,4363,5852,6943,7211,7213,7215,7217,7219,7221,7223,7225,7227", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "237", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "84.4867", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.9954", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "9.6471", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.5729", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.2979", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "133", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "2859", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "143", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "592", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "3", + "weight": "11.0653", + "id": "0", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "20.685", + "id": "12158", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "10.8348", + "id": "12159", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "20.7757", + "id": "12160", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "36.6392", + "id": "12163", + "maxAmount": "3" + } + ], + "ids": "8349,8350,8351,8352,8353,8354,8355,8356,8357,8358,8359,8360,8361,8362,8363,8364,8365,8366", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "96.0", + "id": "1371", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "24.0", + "id": "1289", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "1303", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "24.0", + "id": "1432", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "1113", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "1147", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "1185", + "maxAmount": "1" + }, + { + "minAmount": "20", + "weight": "48.0", + "id": "4699", + "maxAmount": "40" + }, + { + "minAmount": "20", + "weight": "24.0", + "id": "560", + "maxAmount": "40" + }, + { + "minAmount": "20", + "weight": "16.0", + "id": "563", + "maxAmount": "40" + }, + { + "minAmount": "10", + "weight": "48.0", + "id": "565", + "maxAmount": "20" + }, + { + "minAmount": "8", + "weight": "144.0", + "id": "14424", + "maxAmount": "10" + }, + { + "minAmount": "4", + "weight": "144.0", + "id": "14422", + "maxAmount": "10" + }, + { + "minAmount": "5", + "weight": "16.0", + "id": "385", + "maxAmount": "15" + }, + { + "minAmount": "1", + "weight": "16.0", + "id": "163", + "maxAmount": "6" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "139", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "24.0", + "id": "2361", + "maxAmount": "5" + }, + { + "minAmount": "3", + "weight": "16.0", + "id": "1602", + "maxAmount": "5" + }, + { + "minAmount": "2", + "weight": "24.0", + "id": "1442", + "maxAmount": "5" + }, + { + "minAmount": "11000", + "weight": "216.0", + "id": "995", + "maxAmount": "13000" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "14484", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "14472", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "14474", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "14476", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "64.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "32.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "1", + "weight": "70.7701", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.4637", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.361", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "12.8041", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.6011", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "158", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "1233", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "869", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1297", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1428", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1245", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "581", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "18.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "9.0", + "id": "564", + "maxAmount": "3" + }, + { + "minAmount": "2", + "weight": "4.0", + "id": "560", + "maxAmount": "2" + }, + { + "minAmount": "45", + "weight": "4.0", + "id": "556", + "maxAmount": "45" + }, + { + "minAmount": "2", + "weight": "6.0", + "id": "565", + "maxAmount": "2" + }, + { + "minAmount": "8", + "weight": "46.0", + "id": "995", + "maxAmount": "8" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "2359", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "22.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "187", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "163,164,2781", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "5.0", + "id": "2169", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "2102", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "2120", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "2128", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "2171", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "2167", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "2164", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "2165", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "2166", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "2026", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "2025", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "2023", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "995", + "maxAmount": "5" + }, + { + "minAmount": "10", + "weight": "49.0", + "id": "995", + "maxAmount": "10" + }, + { + "minAmount": "125", + "weight": "1.0", + "id": "995", + "maxAmount": "125" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "172,174,3242,3243,3244,3245,4658,4659,4660,4661", + "description": "", + "main": [ + { + "minAmount": "10", + "weight": "3.0", + "id": "557", + "maxAmount": "10" + }, + { + "minAmount": "18", + "weight": "2.0", + "id": "557", + "maxAmount": "18" + }, + { + "minAmount": "10", + "weight": "3.0", + "id": "556", + "maxAmount": "10" + }, + { + "minAmount": "18", + "weight": "2.0", + "id": "556", + "maxAmount": "18" + }, + { + "minAmount": "10", + "weight": "3.0", + "id": "555", + "maxAmount": "10" + }, + { + "minAmount": "18", + "weight": "2.0", + "id": "555", + "maxAmount": "18" + }, + { + "minAmount": "10", + "weight": "3.0", + "id": "554", + "maxAmount": "10" + }, + { + "minAmount": "18", + "weight": "2.0", + "id": "554", + "maxAmount": "18" + }, + { + "minAmount": "10", + "weight": "3.0", + "id": "558", + "maxAmount": "10" + }, + { + "minAmount": "18", + "weight": "2.0", + "id": "558", + "maxAmount": "18" + }, + { + "minAmount": "10", + "weight": "3.0", + "id": "559", + "maxAmount": "10" + }, + { + "minAmount": "18", + "weight": "2.0", + "id": "559", + "maxAmount": "18" + }, + { + "minAmount": "4", + "weight": "6.0", + "id": "562", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "7.0", + "id": "561", + "maxAmount": "4" + }, + { + "minAmount": "3", + "weight": "1.0", + "id": "563", + "maxAmount": "3" + }, + { + "minAmount": "2", + "weight": "1.0", + "id": "564", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "2.0", + "id": "565", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "1379", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1444", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1442", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1448", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "581", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1017", + "maxAmount": "1" + }, + { + "minAmount": "36", + "weight": "4.0", + "id": "557", + "maxAmount": "36" + }, + { + "minAmount": "1", + "weight": "17.0", + "id": "995", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "16.0", + "id": "995", + "maxAmount": "2" + }, + { + "minAmount": "4", + "weight": "7.0", + "id": "995", + "maxAmount": "4" + }, + { + "minAmount": "29", + "weight": "3.0", + "id": "995", + "maxAmount": "29" + }, + { + "minAmount": "30", + "weight": "1.0", + "id": "995", + "maxAmount": "30" + }, + { + "minAmount": "1", + "weight": "15.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "173", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "175,2697,7161,7162", + "description": "", + "main": [ + { + "minAmount": "2", + "weight": "27.0", + "id": "877", + "maxAmount": "12" + }, + { + "minAmount": "6", + "weight": "2.0", + "id": "555", + "maxAmount": "6" + }, + { + "minAmount": "5", + "weight": "2.0", + "id": "557", + "maxAmount": "5" + }, + { + "minAmount": "9", + "weight": "3.0", + "id": "558", + "maxAmount": "9" + }, + { + "minAmount": "1", + "weight": "13.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "39.0", + "id": "954", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "13.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "6.0", + "id": "313", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1965", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "946", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1139", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "436", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "12.0", + "id": "995", + "maxAmount": "5" + }, + { + "minAmount": "15", + "weight": "3.0", + "id": "995", + "maxAmount": "15" + }, + { + "minAmount": "25", + "weight": "1.0", + "id": "995", + "maxAmount": "25" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "94.1431", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.2003", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.2851", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.7167", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.6549", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "178,179,2751,2777,2778,6189", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "1279", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1153", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1424", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1165", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "888", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1313", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1283", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1125", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1077", + "maxAmount": "1" + }, + { + "minAmount": "29", + "weight": "25.0", + "id": "558", + "maxAmount": "29" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "557", + "maxAmount": "10" + }, + { + "minAmount": "9", + "weight": "25.0", + "id": "559", + "maxAmount": "9" + }, + { + "minAmount": "7", + "weight": "25.0", + "id": "564", + "maxAmount": "7" + }, + { + "minAmount": "46", + "weight": "25.0", + "id": "562", + "maxAmount": "46" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "560", + "maxAmount": "2" + }, + { + "minAmount": "34", + "weight": "25.0", + "id": "563", + "maxAmount": "34" + }, + { + "minAmount": "6", + "weight": "5.0", + "id": "561", + "maxAmount": "6" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "5318", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "5319", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "5.0", + "id": "5324", + "maxAmount": "4" + }, + { + "minAmount": "3", + "weight": "5.0", + "id": "5322", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "5.0", + "id": "5320", + "maxAmount": "3" + }, + { + "minAmount": "23", + "weight": "5.0", + "id": "5323", + "maxAmount": "23" + }, + { + "minAmount": "2", + "weight": "5.0", + "id": "5321", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "995", + "maxAmount": "500" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "2353", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1933", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2309", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "438", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "181,2547,7105", + "description": "", + "main": [ + { + "minAmount": "2", + "weight": "7.0", + "id": "563", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "4.0", + "id": "9142", + "maxAmount": "12" + }, + { + "minAmount": "36", + "weight": "3.0", + "id": "556", + "maxAmount": "36" + }, + { + "minAmount": "9", + "weight": "2.0", + "id": "559", + "maxAmount": "9" + }, + { + "minAmount": "9", + "weight": "2.0", + "id": "557", + "maxAmount": "9" + }, + { + "minAmount": "12", + "weight": "2.0", + "id": "558", + "maxAmount": "12" + }, + { + "minAmount": "3", + "weight": "1.0", + "id": "561", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "35.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "11.0", + "id": "14424", + "maxAmount": "2" + }, + { + "minAmount": "3", + "weight": "5.0", + "id": "995", + "maxAmount": "3" + }, + { + "minAmount": "8", + "weight": "5.0", + "id": "995", + "maxAmount": "8" + }, + { + "minAmount": "29", + "weight": "3.0", + "id": "995", + "maxAmount": "29" + }, + { + "minAmount": "35", + "weight": "1.0", + "id": "995", + "maxAmount": "35" + }, + { + "minAmount": "1", + "weight": "30.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "227", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1291", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "231", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1594", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1627", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1137", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1454", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "182,183,184,185,2695,3167,3168,3169,3170,3171,3172,3173,3174,3175,3176,3177,3178,3179,3180,3181,3182,3183,3184,3185,3186,3187,3188,3189,3190,3191,3192,3193,3194,3195,3196,6346,6347,6348,6349,6350,6351,6352,6353,6354,6355,6356", + "description": "", + "main": [ + { + "minAmount": "10", + "weight": "2.0", + "id": "556", + "maxAmount": "10" + }, + { + "minAmount": "9", + "weight": "2.0", + "id": "557", + "maxAmount": "9" + }, + { + "minAmount": "5", + "weight": "2.0", + "id": "554", + "maxAmount": "5" + }, + { + "minAmount": "2", + "weight": "6.0", + "id": "562", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "5.0", + "id": "561", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "1.0", + "id": "563", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1321", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "6.0", + "id": "1203", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "10.0", + "id": "9140", + "maxAmount": "12" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1115", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "12.0", + "id": "1025", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "2351", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1949", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "9", + "weight": "3.0", + "id": "882", + "maxAmount": "9" + }, + { + "minAmount": "12", + "weight": "2.0", + "id": "882", + "maxAmount": "12" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "4", + "weight": "29.0", + "id": "995", + "maxAmount": "4" + }, + { + "minAmount": "7", + "weight": "8.0", + "id": "995", + "maxAmount": "7" + }, + { + "minAmount": "12", + "weight": "6.0", + "id": "995", + "maxAmount": "12" + }, + { + "minAmount": "25", + "weight": "13.0", + "id": "995", + "maxAmount": "25" + }, + { + "minAmount": "35", + "weight": "4.0", + "id": "995", + "maxAmount": "35" + }, + { + "minAmount": "55", + "weight": "1.0", + "id": "995", + "maxAmount": "55" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "86.7406", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "11.5076", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.7715", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.6429", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.3375", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "186,7106,7107,7108,7109,7110,7111,7112,7113,7114", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "1353", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1137", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1363", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1309", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1203", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "13.0", + "id": "561", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "4.0", + "id": "562", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "1.0", + "id": "564", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "1.0", + "id": "560", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "1.0", + "id": "563", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "24.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "2351", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "453", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "167", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "161", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "8", + "weight": "23.0", + "id": "995", + "maxAmount": "8" + }, + { + "minAmount": "15", + "weight": "11.0", + "id": "995", + "maxAmount": "15" + }, + { + "minAmount": "20", + "weight": "1.0", + "id": "995", + "maxAmount": "20" + }, + { + "minAmount": "30", + "weight": "2.0", + "id": "995", + "maxAmount": "30" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "1", + "weight": "85.3493", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.9531", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.4672", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.3107", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.9197", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "187", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "2.0", + "id": "1139", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1115", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "22.0", + "id": "877", + "maxAmount": "12" + }, + { + "minAmount": "7", + "weight": "3.0", + "id": "882", + "maxAmount": "7" + }, + { + "minAmount": "4", + "weight": "2.0", + "id": "557", + "maxAmount": "4" + }, + { + "minAmount": "6", + "weight": "2.0", + "id": "554", + "maxAmount": "6" + }, + { + "minAmount": "9", + "weight": "2.0", + "id": "558", + "maxAmount": "9" + }, + { + "minAmount": "2", + "weight": "1.0", + "id": "562", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "23.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "36.0", + "id": "995", + "maxAmount": "3" + }, + { + "minAmount": "5", + "weight": "9.0", + "id": "995", + "maxAmount": "5" + }, + { + "minAmount": "15", + "weight": "4.0", + "id": "995", + "maxAmount": "15" + }, + { + "minAmount": "25", + "weight": "1.0", + "id": "995", + "maxAmount": "25" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "313", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "436", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1965", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "191,2496,2497", + "description": "", + "main": [ + { + "minAmount": "10", + "weight": "25.0", + "id": "828", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1237", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1239", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1241", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1243", + "maxAmount": "1" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "827", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "231", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1525", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1533", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "3188", + "maxAmount": "1" + }, + { + "minAmount": "15", + "weight": "50.0", + "id": "6306", + "maxAmount": "62" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "444", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1933", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "438", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "225", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "561", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "74.1154", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "17.7558", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.9091", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0402", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.1795", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "192", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "3.0", + "id": "1139", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1151", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1420", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1426", + "maxAmount": "1" + }, + { + "minAmount": "8", + "weight": "4.0", + "id": "882", + "maxAmount": "8" + }, + { + "minAmount": "2", + "weight": "3.0", + "id": "558", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "555", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "1.0", + "id": "557", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "1.0", + "id": "562", + "maxAmount": "2" + }, + { + "minAmount": "3", + "weight": "2.0", + "id": "561", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "325", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "18.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "31.0", + "id": "995", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "20.0", + "id": "995", + "maxAmount": "2" + }, + { + "minAmount": "6", + "weight": "20.0", + "id": "995", + "maxAmount": "6" + }, + { + "minAmount": "13", + "weight": "7.0", + "id": "995", + "maxAmount": "13" + }, + { + "minAmount": "20", + "weight": "6.0", + "id": "995", + "maxAmount": "20" + }, + { + "minAmount": "30", + "weight": "2.0", + "id": "995", + "maxAmount": "30" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "193", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "1217", + "maxAmount": "1" + }, + { + "minAmount": "12", + "weight": "5.0", + "id": "554", + "maxAmount": "12" + }, + { + "minAmount": "2", + "weight": "4.0", + "id": "563", + "maxAmount": "2" + }, + { + "minAmount": "9", + "weight": "2.0", + "id": "557", + "maxAmount": "9" + }, + { + "minAmount": "36", + "weight": "1.0", + "id": "556", + "maxAmount": "36" + }, + { + "minAmount": "3", + "weight": "1.0", + "id": "561", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "34.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "10.0", + "id": "14424", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "239", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "235", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "225", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "1.0", + "id": "225", + "maxAmount": "2" + }, + { + "minAmount": "3", + "weight": "1.0", + "id": "225", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "231", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "227", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "15.0", + "id": "995", + "maxAmount": "3" + }, + { + "minAmount": "10", + "weight": "1.0", + "id": "995", + "maxAmount": "10" + }, + { + "minAmount": "29", + "weight": "3.0", + "id": "995", + "maxAmount": "29" + }, + { + "minAmount": "1", + "weight": "37.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "167", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "14426", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "199", + "description": "", + "main": [ + { + "minAmount": "5", + "weight": "270.0", + "id": "995", + "maxAmount": "25" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2142", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "26.0", + "id": "1349", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1595", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1917", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "948", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.5", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "18.0", + "id": "1375", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.2", + "id": "1420", + "maxAmount": "1" + }, + { + "minAmount": "10", + "weight": "18.0", + "id": "882", + "maxAmount": "10" + }, + { + "minAmount": "8", + "weight": "14.0", + "id": "884", + "maxAmount": "8" + }, + { + "minAmount": "5", + "weight": "14.0", + "id": "557", + "maxAmount": "5" + }, + { + "minAmount": "10", + "weight": "9.0", + "id": "558", + "maxAmount": "10" + }, + { + "minAmount": "9", + "weight": "9.0", + "id": "554", + "maxAmount": "9" + }, + { + "minAmount": "2", + "weight": "5.0", + "id": "563", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "150.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "202", + "description": "", + "main": [ + { + "minAmount": "12", + "weight": "25.0", + "id": "559", + "maxAmount": "12" + }, + { + "minAmount": "3", + "weight": "5.0", + "id": "562", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "563", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "5.0", + "id": "561", + "maxAmount": "3" + }, + { + "minAmount": "30", + "weight": "25.0", + "id": "555", + "maxAmount": "30" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1175", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1325", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1157", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1353", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1177", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1313", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "120", + "weight": "50.0", + "id": "995", + "maxAmount": "300" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "442", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "5.0", + "id": "374", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "203", + "description": "", + "main": [ + { + "minAmount": "12", + "weight": "25.0", + "id": "559", + "maxAmount": "12" + }, + { + "minAmount": "30", + "weight": "25.0", + "id": "555", + "maxAmount": "30" + }, + { + "minAmount": "3", + "weight": "5.0", + "id": "562", + "maxAmount": "3" + }, + { + "minAmount": "2", + "weight": "5.0", + "id": "563", + "maxAmount": "2" + }, + { + "minAmount": "4", + "weight": "5.0", + "id": "561", + "maxAmount": "4" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "995", + "maxAmount": "69" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1157", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1313", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.417", + "id": "1", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "442", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "5.0", + "id": "374", + "maxAmount": "5" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "204", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "8", + "weight": "50.0", + "id": "995", + "maxAmount": "150" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "442", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "563", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "565", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "561", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1313", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "374", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "205", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "1217", + "maxAmount": "1" + }, + { + "minAmount": "12", + "weight": "5.0", + "id": "555", + "maxAmount": "12" + }, + { + "minAmount": "2", + "weight": "4.0", + "id": "563", + "maxAmount": "2" + }, + { + "minAmount": "3", + "weight": "1.0", + "id": "561", + "maxAmount": "3" + }, + { + "minAmount": "36", + "weight": "1.0", + "id": "554", + "maxAmount": "36" + }, + { + "minAmount": "1", + "weight": "39.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "239", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "231", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "227", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "5.0", + "id": "995", + "maxAmount": "3" + }, + { + "minAmount": "10", + "weight": "3.0", + "id": "995", + "maxAmount": "10" + }, + { + "minAmount": "24", + "weight": "3.0", + "id": "995", + "maxAmount": "24" + }, + { + "minAmount": "1", + "weight": "37.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "11.0", + "id": "167", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "993", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "14426", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "37.5", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "12.5", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "16.25", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "18.75", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "15.0", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "221", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "555", + "maxAmount": "1" + }, + { + "minAmount": "24", + "weight": "50.0", + "id": "563", + "maxAmount": "24" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "564", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "562", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "560", + "maxAmount": "2" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "554", + "maxAmount": "15" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1153", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "995", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1446", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5324", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "830", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "225", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1917", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1191", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1295", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5303", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "281", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "283", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "370,357,348,369,347,371", + "description": "all combat mourners", + "main": [] + }, + { + "default": [], + "charm": [ + { + "minAmount": "1", + "weight": "81.6118", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "15.83", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.4426", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.4809", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.6347", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "412", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "530", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "438,439,440,441,442,443,4470", + "description": "Tree Spirit (Hostile Woodcutting Random Event/Enchanted Valley)", + "main": [ + { + "minAmount": "1", + "weight": "8.0", + "id": "1351", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "1349", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "1353", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "1361", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "1355", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "1357", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1359", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "12.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "14.0", + "id": "14428", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "946", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "6.0", + "id": "3051", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "6.0", + "id": "3049", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "16.0", + "id": "561", + "maxAmount": "5" + }, + { + "minAmount": "10", + "weight": "8.0", + "id": "561", + "maxAmount": "10" + }, + { + "minAmount": "22", + "weight": "2.0", + "id": "561", + "maxAmount": "22" + }, + { + "minAmount": "28", + "weight": "2.0", + "id": "561", + "maxAmount": "28" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1963", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "592", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "12163", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5600.0", + "id": "0", + "maxAmount": "1" + } + ], + "ids": "490,1959,1962,1963,1964,1965,1966,1967,1968,2015,2016,2017,2018,2019,6753,6754,6755,6756,6757,6758,6759,6760", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "5.0", + "id": "1333", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1185", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1673", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1654", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1635", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1696", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1639", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2566", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1727", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1656", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1637", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11072", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "995", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "405", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "2357", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "444", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "970", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "9032", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1939", + "maxAmount": "17" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "950", + "maxAmount": "1" + }, + { + "minAmount": "10", + "weight": "5.0", + "id": "2007", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "609,4603,4604,4605,4606", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "556", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "565", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "562", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "557", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "561", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "554", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "882", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "886", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1446", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5324", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "995", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1947", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5318", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "592", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "781", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "667", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "592", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "708,709,1531,6211", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "877", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1949", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1944", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2138", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2309", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2307", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1965", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2142", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1933", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1759", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "2347", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1474", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1470", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1476", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1472", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1448", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "592", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2146", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1947", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "753", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "590", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1735", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1925", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1929", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1935", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1937", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1993", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "195", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1931", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "956", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1438", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2349", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1927", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2357", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "9442", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "434", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "579", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "749", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "1191", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1081", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "11371", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "857", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1371", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1430", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1391", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1428", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1181", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1157", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1193", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1295", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1424", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1325", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1143", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1333", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "9145", + "maxAmount": "5" + }, + { + "minAmount": "20", + "weight": "50.0", + "id": "886", + "maxAmount": "20" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "890", + "maxAmount": "5" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "565", + "maxAmount": "3" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "565", + "maxAmount": "5" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "560", + "maxAmount": "5" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "9419", + "maxAmount": "2" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "808", + "maxAmount": "10" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "865", + "maxAmount": "10" + }, + { + "minAmount": "10", + "weight": "5.0", + "id": "9144", + "maxAmount": "10" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "2356", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "2354", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "2357", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "444", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2361", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "11443", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "11465", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "106", + "weight": "50.0", + "id": "995", + "maxAmount": "467" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1515", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1623", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1619", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1637", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11359", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5733", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "750", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "11371", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1191", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1081", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1371", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1430", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1391", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1428", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1181", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1193", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1157", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1295", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1424", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1325", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "857", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1333", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "9145", + "maxAmount": "5" + }, + { + "minAmount": "20", + "weight": "50.0", + "id": "886", + "maxAmount": "20" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "890", + "maxAmount": "5" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "560", + "maxAmount": "5" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "565", + "maxAmount": "3" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "565", + "maxAmount": "5" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "9419", + "maxAmount": "2" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "808", + "maxAmount": "10" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "865", + "maxAmount": "10" + }, + { + "minAmount": "10", + "weight": "5.0", + "id": "9144", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "2357", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "2356", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "2354", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "444", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "11443", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "11465", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "106", + "weight": "50.0", + "id": "995", + "maxAmount": "106" + }, + { + "minAmount": "142", + "weight": "50.0", + "id": "995", + "maxAmount": "142" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1515", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11359", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1637", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5733", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "751", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "1333", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11371", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1295", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1371", + "maxAmount": "1" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "865", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1424", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "857", + "maxAmount": "1" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "808", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1391", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1430", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1428", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1191", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1081", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1193", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1157", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1181", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "890", + "maxAmount": "5" + }, + { + "minAmount": "20", + "weight": "25.0", + "id": "886", + "maxAmount": "20" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "9145", + "maxAmount": "5" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "9144", + "maxAmount": "10" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "560", + "maxAmount": "5" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "565", + "maxAmount": "3" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "565", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1515", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "2354", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "11443", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11359", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "11465", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "752", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "5.0", + "id": "1371", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1373", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1428", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1430", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1432", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1325", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1333", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1295", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "11367", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11369", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11371", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "11373", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "11375", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1391", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1181", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1157", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1193", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1191", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1081", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1149", + "maxAmount": "1" + }, + { + "minAmount": "20", + "weight": "50.0", + "id": "867", + "maxAmount": "20" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "892", + "maxAmount": "10" + }, + { + "minAmount": "2", + "weight": "50.0", + "id": "9419", + "maxAmount": "2" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "9144", + "maxAmount": "10" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "9145", + "maxAmount": "5" + }, + { + "minAmount": "6", + "weight": "25.0", + "id": "560", + "maxAmount": "9" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "11467", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "11465", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11507", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11505", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "11475", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "11473", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5295", + "maxAmount": "1" + }, + { + "minAmount": "106", + "weight": "5.0", + "id": "995", + "maxAmount": "106" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "533", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "383", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "385", + "maxAmount": "3" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "2355", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "5.0", + "id": "2360", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2362", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2364", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "857", + "maxAmount": "1" + }, + { + "minAmount": "13", + "weight": "25.0", + "id": "1515", + "maxAmount": "13" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11359", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "2859", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "839,6050,6051", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "1861", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "840", + "description": "", + "main": [] + }, + { + "default": [], + "charm": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "12163", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5600.0", + "id": "0", + "maxAmount": "1" + } + ], + "ids": "870", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "5294", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5323", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5293", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5292", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5100", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5104", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "12176", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5295", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5300", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5321", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "877", + "description": "", + "main": [ + { + "minAmount": "8", + "weight": "25.0", + "id": "556", + "maxAmount": "8" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "565", + "maxAmount": "2" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "562", + "maxAmount": "3" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "557", + "maxAmount": "4" + }, + { + "minAmount": "6", + "weight": "25.0", + "id": "554", + "maxAmount": "6" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "882", + "maxAmount": "4" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "886", + "maxAmount": "8" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1295", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1141", + "maxAmount": "1" + }, + { + "minAmount": "6", + "weight": "25.0", + "id": "995", + "maxAmount": "35" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1448", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "878", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "1295", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1141", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1137", + "maxAmount": "1" + }, + { + "minAmount": "8", + "weight": "25.0", + "id": "556", + "maxAmount": "8" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "562", + "maxAmount": "3" + }, + { + "minAmount": "6", + "weight": "5.0", + "id": "554", + "maxAmount": "6" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "561", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "565", + "maxAmount": "2" + }, + { + "minAmount": "6", + "weight": "50.0", + "id": "995", + "maxAmount": "30" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "882", + "maxAmount": "4" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "886", + "maxAmount": "2" + }, + { + "minAmount": "8", + "weight": "25.0", + "id": "886", + "maxAmount": "8" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1448", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "440", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "536", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "1753", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "66.2159", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.4604", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "16.0822", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "7.7004", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.5411", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "941,4677,4678,4679,4680", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "4.0", + "id": "1069", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1365", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1355", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1243", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1197", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1161", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1213", + "maxAmount": "1" + }, + { + "minAmount": "75", + "weight": "8.0", + "id": "555", + "maxAmount": "75" + }, + { + "minAmount": "15", + "weight": "5.0", + "id": "561", + "maxAmount": "15" + }, + { + "minAmount": "3", + "weight": "3.0", + "id": "563", + "maxAmount": "3" + }, + { + "minAmount": "37", + "weight": "1.0", + "id": "554", + "maxAmount": "37" + }, + { + "minAmount": "1", + "weight": "15.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "11", + "weight": "10.0", + "id": "995", + "maxAmount": "11" + }, + { + "minAmount": "44", + "weight": "23.0", + "id": "995", + "maxAmount": "44" + }, + { + "minAmount": "132", + "weight": "25.0", + "id": "995", + "maxAmount": "132" + }, + { + "minAmount": "200", + "weight": "10.0", + "id": "995", + "maxAmount": "200" + }, + { + "minAmount": "440", + "weight": "1.0", + "id": "995", + "maxAmount": "440" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "365", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "449", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.25", + "id": "12479", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "1490", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "988", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "1157", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1295", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1281", + "maxAmount": "1" + }, + { + "minAmount": "30", + "weight": "25.0", + "id": "555", + "maxAmount": "30" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "995", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2351", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2353", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "989", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "1281", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1295", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1157", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "995", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1623", + "maxAmount": "1" + }, + { + "minAmount": "30", + "weight": "25.0", + "id": "555", + "maxAmount": "30" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2351", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2353", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "1490", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "990", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "1157", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1295", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1281", + "maxAmount": "1" + }, + { + "minAmount": "30", + "weight": "25.0", + "id": "555", + "maxAmount": "30" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "995", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2351", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2353", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2359", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "592", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "1497", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "998", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "592", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "1498", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "999", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "592", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "1499", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1000", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "1410", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1002", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1007", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "1397", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1399", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1393", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1395", + "maxAmount": "1" + }, + { + "minAmount": "60", + "weight": "50.0", + "id": "556", + "maxAmount": "60" + }, + { + "minAmount": "189", + "weight": "50.0", + "id": "556", + "maxAmount": "189" + }, + { + "minAmount": "79", + "weight": "50.0", + "id": "557", + "maxAmount": "79" + }, + { + "minAmount": "86", + "weight": "50.0", + "id": "557", + "maxAmount": "86" + }, + { + "minAmount": "51", + "weight": "50.0", + "id": "554", + "maxAmount": "51" + }, + { + "minAmount": "180", + "weight": "50.0", + "id": "554", + "maxAmount": "180" + }, + { + "minAmount": "86", + "weight": "50.0", + "id": "555", + "maxAmount": "86" + }, + { + "minAmount": "107", + "weight": "50.0", + "id": "555", + "maxAmount": "107" + }, + { + "minAmount": "8", + "weight": "25.0", + "id": "565", + "maxAmount": "8" + }, + { + "minAmount": "25", + "weight": "25.0", + "id": "564", + "maxAmount": "25" + }, + { + "minAmount": "45", + "weight": "25.0", + "id": "560", + "maxAmount": "45" + }, + { + "minAmount": "9", + "weight": "25.0", + "id": "563", + "maxAmount": "9" + }, + { + "minAmount": "12", + "weight": "25.0", + "id": "561", + "maxAmount": "12" + }, + { + "minAmount": "28", + "weight": "25.0", + "id": "561", + "maxAmount": "28" + }, + { + "minAmount": "77", + "weight": "50.0", + "id": "995", + "maxAmount": "77" + }, + { + "minAmount": "89", + "weight": "50.0", + "id": "995", + "maxAmount": "89" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "2876", + "maxAmount": "1" + }, + { + "minAmount": "11", + "weight": "100.0", + "id": "314", + "maxAmount": "30" + } + ], + "charm": [], + "ids": "1016,1550", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "592", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "86.2037", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0201", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.9644", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "7.2179", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.5939", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "1019", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "554", + "maxAmount": "20" + }, + { + "minAmount": "2", + "weight": "50.0", + "id": "562", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "560", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "561", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "563", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "565", + "maxAmount": "1" + }, + { + "minAmount": "12", + "weight": "50.0", + "id": "995", + "maxAmount": "42" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1387", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "1021", + "description": "", + "main": [ + { + "minAmount": "15", + "weight": "13.0", + "id": "556", + "maxAmount": "15" + }, + { + "minAmount": "2", + "weight": "9.0", + "id": "561", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "7.0", + "id": "562", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "6.0", + "id": "563", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "560", + "maxAmount": "1" + }, + { + "minAmount": "20", + "weight": "3.0", + "id": "556", + "maxAmount": "20" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "565", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "14.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "12", + "weight": "36.0", + "id": "995", + "maxAmount": "12" + }, + { + "minAmount": "42", + "weight": "3.0", + "id": "995", + "maxAmount": "42" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1381", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "28.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "227", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1022", + "description": "", + "main": [ + { + "minAmount": "15", + "weight": "13.0", + "id": "555", + "maxAmount": "15" + }, + { + "minAmount": "2", + "weight": "9.0", + "id": "561", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "7.0", + "id": "562", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "6.0", + "id": "563", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "560", + "maxAmount": "1" + }, + { + "minAmount": "20", + "weight": "3.0", + "id": "555", + "maxAmount": "20" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "565", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "14.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "12", + "weight": "36.0", + "id": "995", + "maxAmount": "12" + }, + { + "minAmount": "42", + "weight": "3.0", + "id": "995", + "maxAmount": "42" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1383", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "28.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "3325", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "12163", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5600.0", + "id": "0", + "maxAmount": "1" + } + ], + "ids": "1023,1220,1223,1225,6214", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "1361", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "562", + "maxAmount": "3" + }, + { + "minAmount": "2", + "weight": "50.0", + "id": "560", + "maxAmount": "2" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "557", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "565", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5281", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5294", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5297", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5104", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5100", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5292", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5106", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5323", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5293", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5296", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5105", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5311", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5280", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5298", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5321", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "12176", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5299", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5303", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5302", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5301", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5295", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "15", + "weight": "50.0", + "id": "995", + "maxAmount": "15" + }, + { + "minAmount": "1", + "weight": "6.7715", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "1029,6056", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "855", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1353", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1097", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1157", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "361", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1901", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2293", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "7178", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "247", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "1539", + "maxAmount": "5" + }, + { + "minAmount": "4", + "weight": "50.0", + "id": "1784", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1523", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "7936", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5970", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "453", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1777", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "231", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1761", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "8778", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "133", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2359", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2347", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "1030,6057", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "365", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "361", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "2011", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "2327", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1897", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "2293", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5004", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1883", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "247", + "maxAmount": "1" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "380", + "maxAmount": "4" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "386", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "7170", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5755", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "7178", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "7188", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "5.0", + "id": "10137", + "maxAmount": "5" + }, + { + "minAmount": "6", + "weight": "5.0", + "id": "7179", + "maxAmount": "6" + }, + { + "minAmount": "3", + "weight": "5.0", + "id": "374", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "10136", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5406", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "2007", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5970", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "5.0", + "id": "3145", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "5.0", + "id": "3143", + "maxAmount": "2" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "1032,6059", + "description": "", + "main": [ + { + "minAmount": "4", + "weight": "50.0", + "id": "562", + "maxAmount": "4" + }, + { + "minAmount": "1330", + "weight": "50.0", + "id": "555", + "maxAmount": "1330" + }, + { + "minAmount": "25", + "weight": "50.0", + "id": "558", + "maxAmount": "25" + }, + { + "minAmount": "30", + "weight": "50.0", + "id": "556", + "maxAmount": "30" + }, + { + "minAmount": "28", + "weight": "50.0", + "id": "559", + "maxAmount": "30" + }, + { + "minAmount": "50", + "weight": "50.0", + "id": "554", + "maxAmount": "50" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1448", + "maxAmount": "1" + }, + { + "minAmount": "20", + "weight": "50.0", + "id": "7937", + "maxAmount": "35" + }, + { + "minAmount": "20", + "weight": "50.0", + "id": "1436", + "maxAmount": "20" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "564", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "4695", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "4696", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "4698", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "4694", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "5.0", + "id": "4699", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "5.0", + "id": "4697", + "maxAmount": "4" + }, + { + "minAmount": "7", + "weight": "5.0", + "id": "565", + "maxAmount": "7" + }, + { + "minAmount": "11", + "weight": "5.0", + "id": "566", + "maxAmount": "11" + }, + { + "minAmount": "13", + "weight": "5.0", + "id": "563", + "maxAmount": "13" + }, + { + "minAmount": "13", + "weight": "5.0", + "id": "561", + "maxAmount": "13" + }, + { + "minAmount": "13", + "weight": "5.0", + "id": "560", + "maxAmount": "13" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1442", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "1033,6060", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "5.0", + "id": "1391", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1273", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2493", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "10083", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5970", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "231", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "444", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "2358", + "maxAmount": "5" + }, + { + "minAmount": "10", + "weight": "5.0", + "id": "450", + "maxAmount": "10" + }, + { + "minAmount": "30", + "weight": "50.0", + "id": "556", + "maxAmount": "57" + }, + { + "minAmount": "20", + "weight": "25.0", + "id": "7936", + "maxAmount": "35" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "237", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1601", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "5.0", + "id": "5760", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "7208", + "maxAmount": "1" + }, + { + "minAmount": "4", + "weight": "50.0", + "id": "8779", + "maxAmount": "4" + }, + { + "minAmount": "3", + "weight": "5.0", + "id": "5321", + "maxAmount": "3" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "1035,6062", + "description": "", + "main": [ + { + "minAmount": "3", + "weight": "50.0", + "id": "1701", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "1732", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "2569", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "3391", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1347", + "maxAmount": "1" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "2571", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1185", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5541", + "maxAmount": "1" + }, + { + "minAmount": "6", + "weight": "50.0", + "id": "1748", + "maxAmount": "6" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "2364", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1603", + "maxAmount": "1" + }, + { + "minAmount": "4", + "weight": "5.0", + "id": "1602", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5287", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "987", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "985", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "993", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5300", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "12121", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "1052,1053,3606,3607,3608,3609,3610,3611", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "1203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1420", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "830", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1189", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "559", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "556", + "maxAmount": "3" + }, + { + "minAmount": "7", + "weight": "25.0", + "id": "554", + "maxAmount": "7" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "562", + "maxAmount": "4" + }, + { + "minAmount": "2", + "weight": "5.0", + "id": "564", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "995", + "maxAmount": "125" + }, + { + "minAmount": "7", + "weight": "50.0", + "id": "313", + "maxAmount": "7" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "438", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "221", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "590", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "7218", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "532", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "69.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "7.0", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "11.0", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "1096", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "4.0", + "id": "1119", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1341", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1339", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1183", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "3122", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1121", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1347", + "maxAmount": "1" + }, + { + "minAmount": "80", + "weight": "8.0", + "id": "557", + "maxAmount": "80" + }, + { + "minAmount": "16", + "weight": "5.0", + "id": "561", + "maxAmount": "16" + }, + { + "minAmount": "4", + "weight": "3.0", + "id": "563", + "maxAmount": "4" + }, + { + "minAmount": "65", + "weight": "1.0", + "id": "557", + "maxAmount": "65" + }, + { + "minAmount": "25", + "weight": "1.0", + "id": "557", + "maxAmount": "25" + }, + { + "minAmount": "1", + "weight": "15.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "40", + "weight": "29.0", + "id": "995", + "maxAmount": "40" + }, + { + "minAmount": "135", + "weight": "25.0", + "id": "995", + "maxAmount": "135" + }, + { + "minAmount": "190", + "weight": "10.0", + "id": "995", + "maxAmount": "190" + }, + { + "minAmount": "20", + "weight": "4.0", + "id": "995", + "maxAmount": "20" + }, + { + "minAmount": "420", + "weight": "1.0", + "id": "995", + "maxAmount": "420" + }, + { + "minAmount": "6", + "weight": "3.0", + "id": "454", + "maxAmount": "6" + }, + { + "minAmount": "4", + "weight": "2.0", + "id": "360", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1357", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "532", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "53.7736", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "35.8491", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "6.6038", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.7736", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.0", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "1097", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "4.0", + "id": "1119", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1341", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1339", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1183", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "3122", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1121", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1347", + "maxAmount": "1" + }, + { + "minAmount": "80", + "weight": "8.0", + "id": "557", + "maxAmount": "80" + }, + { + "minAmount": "16", + "weight": "5.0", + "id": "561", + "maxAmount": "16" + }, + { + "minAmount": "4", + "weight": "3.0", + "id": "563", + "maxAmount": "4" + }, + { + "minAmount": "65", + "weight": "1.0", + "id": "557", + "maxAmount": "65" + }, + { + "minAmount": "25", + "weight": "1.0", + "id": "557", + "maxAmount": "25" + }, + { + "minAmount": "1", + "weight": "15.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "40", + "weight": "29.0", + "id": "995", + "maxAmount": "40" + }, + { + "minAmount": "135", + "weight": "25.0", + "id": "995", + "maxAmount": "135" + }, + { + "minAmount": "190", + "weight": "10.0", + "id": "995", + "maxAmount": "190" + }, + { + "minAmount": "20", + "weight": "4.0", + "id": "995", + "maxAmount": "20" + }, + { + "minAmount": "420", + "weight": "1.0", + "id": "995", + "maxAmount": "420" + }, + { + "minAmount": "6", + "weight": "3.0", + "id": "454", + "maxAmount": "6" + }, + { + "minAmount": "4", + "weight": "2.0", + "id": "360", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1357", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "532", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "67.1141", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "21.6443", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0336", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.1946", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0134", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "1098", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "4.0", + "id": "1119", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1341", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1339", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1183", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "3122", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1121", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1347", + "maxAmount": "1" + }, + { + "minAmount": "80", + "weight": "8.0", + "id": "557", + "maxAmount": "80" + }, + { + "minAmount": "16", + "weight": "5.0", + "id": "561", + "maxAmount": "16" + }, + { + "minAmount": "4", + "weight": "3.0", + "id": "563", + "maxAmount": "4" + }, + { + "minAmount": "65", + "weight": "1.0", + "id": "557", + "maxAmount": "65" + }, + { + "minAmount": "25", + "weight": "1.0", + "id": "557", + "maxAmount": "25" + }, + { + "minAmount": "1", + "weight": "15.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "40", + "weight": "29.0", + "id": "995", + "maxAmount": "40" + }, + { + "minAmount": "135", + "weight": "25.0", + "id": "995", + "maxAmount": "135" + }, + { + "minAmount": "190", + "weight": "10.0", + "id": "995", + "maxAmount": "190" + }, + { + "minAmount": "20", + "weight": "4.0", + "id": "995", + "maxAmount": "20" + }, + { + "minAmount": "420", + "weight": "1.0", + "id": "995", + "maxAmount": "420" + }, + { + "minAmount": "6", + "weight": "3.0", + "id": "454", + "maxAmount": "6" + }, + { + "minAmount": "4", + "weight": "2.0", + "id": "360", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1357", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "532", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1101,1102,1103,1104,1105", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "4.0", + "id": "1141", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1339", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1341", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1145", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1345", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1181", + "maxAmount": "1" + }, + { + "minAmount": "60", + "weight": "8.0", + "id": "557", + "maxAmount": "60" + }, + { + "minAmount": "7", + "weight": "5.0", + "id": "561", + "maxAmount": "7" + }, + { + "minAmount": "2", + "weight": "3.0", + "id": "563", + "maxAmount": "2" + }, + { + "minAmount": "45", + "weight": "1.0", + "id": "557", + "maxAmount": "45" + }, + { + "minAmount": "25", + "weight": "1.0", + "id": "557", + "maxAmount": "25" + }, + { + "minAmount": "1", + "weight": "15.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "19.0", + "id": "14422", + "maxAmount": "1" + }, + { + "minAmount": "8", + "weight": "7.0", + "id": "995", + "maxAmount": "8" + }, + { + "minAmount": "35", + "weight": "29.0", + "id": "995", + "maxAmount": "35" + }, + { + "minAmount": "50", + "weight": "6.0", + "id": "995", + "maxAmount": "50" + }, + { + "minAmount": "100", + "weight": "10.0", + "id": "995", + "maxAmount": "100" + }, + { + "minAmount": "250", + "weight": "1.0", + "id": "995", + "maxAmount": "250" + }, + { + "minAmount": "3", + "weight": "3.0", + "id": "454", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "2.0", + "id": "354", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.32", + "id": "10976", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.0256", + "id": "10977", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "532", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1106,1107,1108,1109,1110,1111,1112,1138", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "4.0", + "id": "1141", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1339", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1341", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1145", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1345", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1181", + "maxAmount": "1" + }, + { + "minAmount": "60", + "weight": "8.0", + "id": "557", + "maxAmount": "60" + }, + { + "minAmount": "7", + "weight": "5.0", + "id": "561", + "maxAmount": "7" + }, + { + "minAmount": "2", + "weight": "3.0", + "id": "563", + "maxAmount": "2" + }, + { + "minAmount": "45", + "weight": "1.0", + "id": "557", + "maxAmount": "45" + }, + { + "minAmount": "25", + "weight": "1.0", + "id": "557", + "maxAmount": "25" + }, + { + "minAmount": "1", + "weight": "15.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "19.0", + "id": "14422", + "maxAmount": "1" + }, + { + "minAmount": "8", + "weight": "7.0", + "id": "995", + "maxAmount": "8" + }, + { + "minAmount": "35", + "weight": "29.0", + "id": "995", + "maxAmount": "35" + }, + { + "minAmount": "50", + "weight": "6.0", + "id": "995", + "maxAmount": "50" + }, + { + "minAmount": "100", + "weight": "10.0", + "id": "995", + "maxAmount": "100" + }, + { + "minAmount": "250", + "weight": "1.0", + "id": "995", + "maxAmount": "250" + }, + { + "minAmount": "3", + "weight": "3.0", + "id": "454", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "2.0", + "id": "354", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.32", + "id": "10976", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.0256", + "id": "10977", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "532", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "50.0805", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "39.694", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.9114", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.2206", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0934", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "1115,1116,1117", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "4.0", + "id": "1119", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1339", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1341", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1357", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1183", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "3122", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1121", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1347", + "maxAmount": "1" + }, + { + "minAmount": "80", + "weight": "8.0", + "id": "557", + "maxAmount": "80" + }, + { + "minAmount": "16", + "weight": "5.0", + "id": "561", + "maxAmount": "16" + }, + { + "minAmount": "4", + "weight": "3.0", + "id": "563", + "maxAmount": "4" + }, + { + "minAmount": "65", + "weight": "1.0", + "id": "557", + "maxAmount": "65" + }, + { + "minAmount": "25", + "weight": "1.0", + "id": "557", + "maxAmount": "25" + }, + { + "minAmount": "1", + "weight": "15.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "20", + "weight": "4.0", + "id": "995", + "maxAmount": "20" + }, + { + "minAmount": "40", + "weight": "29.0", + "id": "995", + "maxAmount": "40" + }, + { + "minAmount": "135", + "weight": "25.0", + "id": "995", + "maxAmount": "135" + }, + { + "minAmount": "190", + "weight": "10.0", + "id": "995", + "maxAmount": "190" + }, + { + "minAmount": "420", + "weight": "1.0", + "id": "995", + "maxAmount": "420" + }, + { + "minAmount": "6", + "weight": "3.0", + "id": "454", + "maxAmount": "6" + }, + { + "minAmount": "4", + "weight": "2.0", + "id": "360", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.32", + "id": "10976", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.0256", + "id": "10977", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "532", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1118,1119,1120,1121,1122,1123,1124", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "1341", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1345", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1361", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1141", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1339", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1145", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1181", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5291", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5292", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5293", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5294", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5296", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5295", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "12176", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5297", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5298", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5299", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5300", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5301", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5302", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5303", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5323", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5321", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5311", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5100", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5104", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5105", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5106", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5280", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5281", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5304", + "maxAmount": "1" + }, + { + "minAmount": "8", + "weight": "50.0", + "id": "995", + "maxAmount": "8" + }, + { + "minAmount": "35", + "weight": "50.0", + "id": "995", + "maxAmount": "35" + }, + { + "minAmount": "7", + "weight": "50.0", + "id": "561", + "maxAmount": "7" + }, + { + "minAmount": "25", + "weight": "50.0", + "id": "557", + "maxAmount": "25" + }, + { + "minAmount": "45", + "weight": "50.0", + "id": "557", + "maxAmount": "45" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "563", + "maxAmount": "2" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "454", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "354", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "7884", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "10976", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "10977", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "532", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1130,1131,1132,1133,1134", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "4.0", + "id": "1141", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1339", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1341", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1145", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1345", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1181", + "maxAmount": "1" + }, + { + "minAmount": "60", + "weight": "8.0", + "id": "557", + "maxAmount": "60" + }, + { + "minAmount": "7", + "weight": "5.0", + "id": "561", + "maxAmount": "7" + }, + { + "minAmount": "2", + "weight": "3.0", + "id": "563", + "maxAmount": "2" + }, + { + "minAmount": "45", + "weight": "1.0", + "id": "557", + "maxAmount": "45" + }, + { + "minAmount": "25", + "weight": "1.0", + "id": "557", + "maxAmount": "25" + }, + { + "minAmount": "1", + "weight": "15.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "19.0", + "id": "14422", + "maxAmount": "1" + }, + { + "minAmount": "8", + "weight": "7.0", + "id": "995", + "maxAmount": "8" + }, + { + "minAmount": "35", + "weight": "29.0", + "id": "995", + "maxAmount": "35" + }, + { + "minAmount": "50", + "weight": "6.0", + "id": "995", + "maxAmount": "50" + }, + { + "minAmount": "100", + "weight": "10.0", + "id": "995", + "maxAmount": "100" + }, + { + "minAmount": "250", + "weight": "1.0", + "id": "995", + "maxAmount": "250" + }, + { + "minAmount": "3", + "weight": "3.0", + "id": "454", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "2.0", + "id": "354", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.32", + "id": "10976", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.0256", + "id": "10977", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "1", + "weight": "87.6923", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.8422", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.1442", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.5573", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.764", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "1153,1156", + "description": "", + "main": [ + { + "minAmount": "11", + "weight": "50.0", + "id": "556", + "maxAmount": "19" + }, + { + "minAmount": "11", + "weight": "50.0", + "id": "555", + "maxAmount": "19" + }, + { + "minAmount": "11", + "weight": "50.0", + "id": "557", + "maxAmount": "19" + }, + { + "minAmount": "11", + "weight": "50.0", + "id": "554", + "maxAmount": "19" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "555", + "maxAmount": "2" + }, + { + "minAmount": "7", + "weight": "25.0", + "id": "554", + "maxAmount": "7" + }, + { + "minAmount": "6", + "weight": "25.0", + "id": "559", + "maxAmount": "6" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "564", + "maxAmount": "2" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "562", + "maxAmount": "3" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "561", + "maxAmount": "4" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "563", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "565", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1837", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1835", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1833", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1299", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1329", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1143", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1109", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1131", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1279", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "826", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1181", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1281", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1295", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "995", + "maxAmount": "1000" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1823", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "3138", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1783", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "1", + "weight": "73.4384", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "7.9927", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.2881", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "6.8405", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "6.4403", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "1154", + "description": "", + "main": [ + { + "minAmount": "60", + "weight": "50.0", + "id": "554", + "maxAmount": "60" + }, + { + "minAmount": "12", + "weight": "25.0", + "id": "562", + "maxAmount": "12" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "560", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "561", + "maxAmount": "1" + }, + { + "minAmount": "30", + "weight": "5.0", + "id": "554", + "maxAmount": "30" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1157", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1353", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1325", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1109", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1181", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1146", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "995", + "maxAmount": "240" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "995", + "maxAmount": "450" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1823", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "1", + "weight": "64.8768", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "13.2327", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "6.3396", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "6.8032", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.7477", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "1155,1157", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "4.0", + "id": "1285", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1365", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1355", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1197", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1147", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1113", + "maxAmount": "1" + }, + { + "minAmount": "50", + "weight": "8.0", + "id": "556", + "maxAmount": "50" + }, + { + "minAmount": "10", + "weight": "7.0", + "id": "562", + "maxAmount": "10" + }, + { + "minAmount": "7", + "weight": "4.0", + "id": "565", + "maxAmount": "7" + }, + { + "minAmount": "37", + "weight": "1.0", + "id": "554", + "maxAmount": "37" + }, + { + "minAmount": "3", + "weight": "1.0", + "id": "563", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "23.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "132", + "weight": "40.0", + "id": "995", + "maxAmount": "132" + }, + { + "minAmount": "30", + "weight": "7.0", + "id": "995", + "maxAmount": "30" + }, + { + "minAmount": "44", + "weight": "6.0", + "id": "995", + "maxAmount": "44" + }, + { + "minAmount": "220", + "weight": "6.0", + "id": "995", + "maxAmount": "220" + }, + { + "minAmount": "460", + "weight": "1.0", + "id": "995", + "maxAmount": "460" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "379", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "133", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "14426", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "6", + "weight": "79.5353", + "id": "0", + "maxAmount": "6" + }, + { + "minAmount": "6", + "weight": "2.681", + "id": "12158", + "maxAmount": "6" + }, + { + "minAmount": "6", + "weight": "3.3959", + "id": "12159", + "maxAmount": "6" + }, + { + "minAmount": "6", + "weight": "5.8981", + "id": "12160", + "maxAmount": "6" + }, + { + "minAmount": "6", + "weight": "8.4897", + "id": "12163", + "maxAmount": "6" + } + ], + "tertiary": [ + { + "minAmount": "1", + "weight": "255.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "7981", + "maxAmount": "1" + } + ], + "ids": "1158,1159,1160,3835,3836,4234", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "1245", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1359", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1373", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1319", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1347", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.2737", + "id": "7158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1113", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.2737", + "id": "3140", + "maxAmount": "1" + }, + { + "minAmount": "500", + "weight": "50.0", + "id": "888", + "maxAmount": "500" + }, + { + "minAmount": "350", + "weight": "50.0", + "id": "884", + "maxAmount": "350" + }, + { + "minAmount": "100", + "weight": "50.0", + "id": "892", + "maxAmount": "100" + }, + { + "minAmount": "75", + "weight": "75.0", + "id": "561", + "maxAmount": "75" + }, + { + "minAmount": "20", + "weight": "25.0", + "id": "563", + "maxAmount": "20" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1301", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1185", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1131", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2501", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "6.5475", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "600", + "weight": "25.0", + "id": "554", + "maxAmount": "600" + }, + { + "minAmount": "50", + "weight": "50.0", + "id": "565", + "maxAmount": "50" + }, + { + "minAmount": "20", + "weight": "25.0", + "id": "246", + "maxAmount": "20" + }, + { + "minAmount": "8", + "weight": "25.0", + "id": "379", + "maxAmount": "8" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "3053", + "maxAmount": "1" + }, + { + "minAmount": "1560", + "weight": "50.0", + "id": "995", + "maxAmount": "1560" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "59.5722", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "7.8769", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "24.361", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "6.5554", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.6345", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "1183,1184,1201,2359,2360,2361,2362,2373,7438,7439,7440,7441", + "description": "", + "main": [ + { + "minAmount": "70", + "weight": "50.0", + "id": "555", + "maxAmount": "70" + }, + { + "minAmount": "37", + "weight": "25.0", + "id": "554", + "maxAmount": "37" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "563", + "maxAmount": "3" + }, + { + "minAmount": "12", + "weight": "25.0", + "id": "561", + "maxAmount": "12" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1243", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1197", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1099", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1135", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1065", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1161", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1147", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "365", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "385", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "379", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "397", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "391", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5299", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5297", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5298", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5296", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5106", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5281", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5301", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5303", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5280", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5302", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5300", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "20", + "weight": "50.0", + "id": "995", + "maxAmount": "427" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "6103", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "449", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "6102", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "948", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "2136", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "85.3383", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.1504", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.5038", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.2556", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.7519", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "1196,1197", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "2859", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "60.5114", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "7.1023", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "22.4432", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.2386", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.7045", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "1198", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1200,1203,1204,1206,4649,7120", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "4.0", + "id": "1311", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1353", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1365", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1197", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1073", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1163", + "maxAmount": "1" + }, + { + "minAmount": "75", + "weight": "8.0", + "id": "554", + "maxAmount": "75" + }, + { + "minAmount": "15", + "weight": "5.0", + "id": "562", + "maxAmount": "15" + }, + { + "minAmount": "5", + "weight": "3.0", + "id": "560", + "maxAmount": "5" + }, + { + "minAmount": "37", + "weight": "1.0", + "id": "554", + "maxAmount": "37" + }, + { + "minAmount": "132", + "weight": "40.0", + "id": "995", + "maxAmount": "132" + }, + { + "minAmount": "44", + "weight": "29.0", + "id": "995", + "maxAmount": "44" + }, + { + "minAmount": "220", + "weight": "10.0", + "id": "995", + "maxAmount": "220" + }, + { + "minAmount": "11", + "weight": "7.0", + "id": "995", + "maxAmount": "11" + }, + { + "minAmount": "460", + "weight": "1.0", + "id": "995", + "maxAmount": "460" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "361", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "2357", + "maxAmount": "1" + }, + { + "minAmount": "10", + "weight": "1.0", + "id": "1734", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "14426", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "79.478", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "18.3672", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.7552", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.2444", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.1553", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "1218", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "5.0", + "id": "1458", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "7881", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "1", + "weight": "82.6794", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "7.4178", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.2519", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "7.287", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.364", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "1219", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "127.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "3363", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "3345", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1227", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "3367", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "3347", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1228", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "3363", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "3349", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1229", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "3367", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "3351", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1230", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "3365", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "3353", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1231", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "3396", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1240", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "3396", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1241", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1255,1256", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "1139", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1203", + "maxAmount": "1" + }, + { + "minAmount": "7", + "weight": "25.0", + "id": "882", + "maxAmount": "7" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "877", + "maxAmount": "11" + }, + { + "minAmount": "9", + "weight": "25.0", + "id": "558", + "maxAmount": "9" + }, + { + "minAmount": "6", + "weight": "25.0", + "id": "554", + "maxAmount": "6" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "562", + "maxAmount": "2" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "557", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "995", + "maxAmount": "30" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1965", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "436", + "maxAmount": "1" + }, + { + "minAmount": "30", + "weight": "5.0", + "id": "313", + "maxAmount": "110" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2681", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1257,1258,1261,1262", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "1139", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1203", + "maxAmount": "1" + }, + { + "minAmount": "7", + "weight": "25.0", + "id": "882", + "maxAmount": "7" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "877", + "maxAmount": "11" + }, + { + "minAmount": "9", + "weight": "25.0", + "id": "558", + "maxAmount": "9" + }, + { + "minAmount": "6", + "weight": "25.0", + "id": "554", + "maxAmount": "6" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "562", + "maxAmount": "2" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "557", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "995", + "maxAmount": "30" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1965", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "436", + "maxAmount": "1" + }, + { + "minAmount": "30", + "weight": "5.0", + "id": "313", + "maxAmount": "110" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5733", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1264", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "1397", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1395", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1399", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1393", + "maxAmount": "1" + }, + { + "minAmount": "189", + "weight": "25.0", + "id": "556", + "maxAmount": "189" + }, + { + "minAmount": "196", + "weight": "25.0", + "id": "556", + "maxAmount": "196" + }, + { + "minAmount": "42", + "weight": "25.0", + "id": "555", + "maxAmount": "42" + }, + { + "minAmount": "126", + "weight": "25.0", + "id": "555", + "maxAmount": "126" + }, + { + "minAmount": "79", + "weight": "25.0", + "id": "557", + "maxAmount": "79" + }, + { + "minAmount": "86", + "weight": "25.0", + "id": "557", + "maxAmount": "86" + }, + { + "minAmount": "51", + "weight": "25.0", + "id": "554", + "maxAmount": "51" + }, + { + "minAmount": "180", + "weight": "25.0", + "id": "554", + "maxAmount": "180" + }, + { + "minAmount": "25", + "weight": "25.0", + "id": "564", + "maxAmount": "25" + }, + { + "minAmount": "28", + "weight": "25.0", + "id": "561", + "maxAmount": "28" + }, + { + "minAmount": "30", + "weight": "25.0", + "id": "561", + "maxAmount": "30" + }, + { + "minAmount": "9", + "weight": "25.0", + "id": "563", + "maxAmount": "9" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "563", + "maxAmount": "10" + }, + { + "minAmount": "45", + "weight": "25.0", + "id": "560", + "maxAmount": "45" + }, + { + "minAmount": "8", + "weight": "25.0", + "id": "565", + "maxAmount": "8" + }, + { + "minAmount": "40", + "weight": "25.0", + "id": "565", + "maxAmount": "40" + }, + { + "minAmount": "7789", + "weight": "25.0", + "id": "995", + "maxAmount": "7789" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "12163", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5600.0", + "id": "0", + "maxAmount": "1" + } + ], + "ids": "1265,1267", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "5.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5293", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5295", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5297", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1265", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1267", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1351", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "826", + "maxAmount": "1" + }, + { + "minAmount": "7", + "weight": "50.0", + "id": "554", + "maxAmount": "7" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "561", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "562", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1454", + "maxAmount": "1" + }, + { + "minAmount": "4", + "weight": "50.0", + "id": "995", + "maxAmount": "498" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "407", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "402", + "maxAmount": "5" + }, + { + "minAmount": "2", + "weight": "5.0", + "id": "403", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "411", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "409", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1969", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "946", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "440", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "453", + "maxAmount": "2" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "436", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "438", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "313", + "maxAmount": "10" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "45", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "9187", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "225", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "405", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1306", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "1337", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1335", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "453", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2353", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "440", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "438", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "436", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "15", + "weight": "50.0", + "id": "995", + "maxAmount": "16" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "227", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1925", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "590", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "229", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1917", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "247", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "221", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "3690", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "1307", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "229", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "227", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "231", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "221", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "247", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "590", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1925", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1337", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1335", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1917", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2353", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "438", + "maxAmount": "5" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "436", + "maxAmount": "5" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "440", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "453", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "3690", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1308", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "1337", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1335", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "3757", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "3758", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "3748", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "436", + "maxAmount": "5" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "438", + "maxAmount": "5" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "440", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "453", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2353", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "15", + "weight": "50.0", + "id": "995", + "maxAmount": "16" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "590", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "229", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "227", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1925", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1917", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "221", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "231", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "247", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1582", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "3690", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "55.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "13.0", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "6.0", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "1338", + "description": "Chaos Tunnels / Lighthouse Dagannoths", + "main": [ + { + "minAmount": "1", + "weight": "5.0", + "id": "1237", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1239", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1243", + "maxAmount": "1" + }, + { + "minAmount": "15", + "weight": "4.0", + "id": "555", + "maxAmount": "15" + }, + { + "minAmount": "15", + "weight": "2.0", + "id": "886", + "maxAmount": "15" + }, + { + "minAmount": "3", + "weight": "1.0", + "id": "828", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "18.0", + "id": "14428", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "12.0", + "id": "301", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "4.0", + "id": "345", + "maxAmount": "3" + }, + { + "minAmount": "5", + "weight": "4.0", + "id": "327", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "311", + "maxAmount": "1" + }, + { + "minAmount": "15", + "weight": "2.0", + "id": "314", + "maxAmount": "15" + }, + { + "minAmount": "50", + "weight": "2.0", + "id": "313", + "maxAmount": "50" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "377", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "359", + "maxAmount": "1" + }, + { + "minAmount": "10", + "weight": "2.0", + "id": "402", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "413", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "1.0", + "id": "411", + "maxAmount": "2" + }, + { + "minAmount": "56", + "weight": "29.0", + "id": "995", + "maxAmount": "56" + }, + { + "minAmount": "25", + "weight": "9.0", + "id": "995", + "maxAmount": "25" + }, + { + "minAmount": "44", + "weight": "8.0", + "id": "995", + "maxAmount": "44" + }, + { + "minAmount": "41", + "weight": "6.0", + "id": "995", + "maxAmount": "41" + }, + { + "minAmount": "12", + "weight": "2.0", + "id": "45", + "maxAmount": "12" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "405", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "14426", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "55.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "13.0", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "6.0", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "2455", + "description": "Waterbirth Dagannoths (Melee Variant)", + "main": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "3749", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "3751", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "3753", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "3755", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "160.0", + "id": "1353", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "160.0", + "id": "828", + "maxAmount": "3" + }, + { + "minAmount": "15", + "weight": "80.0", + "id": "886", + "maxAmount": "15" + }, + { + "minAmount": "1", + "weight": "48.0", + "id": "3748", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "48.0", + "id": "3757", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "48.0", + "id": "3758", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "32.0", + "id": "3767", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "32.0", + "id": "3761", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "32.0", + "id": "3799", + "maxAmount": "1" + }, + { + "minAmount": "10", + "weight": "160.0", + "id": "555", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "160.0", + "id": "561", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "160.0", + "id": "563", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "32.0", + "id": "565", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "64.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "16.0", + "id": "14428", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "160.0", + "id": "6155", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "160.0", + "id": "590", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "112.0", + "id": "411", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "80.0", + "id": "377", + "maxAmount": "1" + }, + { + "minAmount": "47", + "weight": "32.0", + "id": "995", + "maxAmount": "47" + }, + { + "minAmount": "3", + "weight": "32.0", + "id": "995", + "maxAmount": "3" + }, + { + "minAmount": "38", + "weight": "32.0", + "id": "995", + "maxAmount": "38" + }, + { + "minAmount": "26", + "weight": "32.0", + "id": "995", + "maxAmount": "26" + }, + { + "minAmount": "81", + "weight": "32.0", + "id": "995", + "maxAmount": "81" + }, + { + "minAmount": "1", + "weight": "32.0", + "id": "3801", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "1438", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "1440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "1442", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "1444", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "1446", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "1448", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "1454", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1452", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1462", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "16.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "16.0", + "id": "14426", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "55.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "13.0", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "6.0", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "2456", + "description": "Waterbirth Dagannoths (Ranged Variant)", + "main": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "3749", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "3751", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "3753", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "3755", + "maxAmount": "1" + }, + { + "minAmount": "30", + "weight": "160.0", + "id": "886", + "maxAmount": "30" + }, + { + "minAmount": "1", + "weight": "48.0", + "id": "3748", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "48.0", + "id": "3757", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "48.0", + "id": "3758", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "32.0", + "id": "3767", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "32.0", + "id": "3761", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "32.0", + "id": "3799", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "32.0", + "id": "828", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "32.0", + "id": "6149", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "32.0", + "id": "6143", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "128.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "16.0", + "id": "14428", + "maxAmount": "1" + }, + { + "minAmount": "10", + "weight": "480.0", + "id": "402", + "maxAmount": "10" + }, + { + "minAmount": "20", + "weight": "160.0", + "id": "45", + "maxAmount": "20" + }, + { + "minAmount": "47", + "weight": "32.0", + "id": "995", + "maxAmount": "47" + }, + { + "minAmount": "3", + "weight": "32.0", + "id": "995", + "maxAmount": "3" + }, + { + "minAmount": "38", + "weight": "32.0", + "id": "995", + "maxAmount": "38" + }, + { + "minAmount": "26", + "weight": "32.0", + "id": "995", + "maxAmount": "26" + }, + { + "minAmount": "81", + "weight": "32.0", + "id": "995", + "maxAmount": "81" + }, + { + "minAmount": "5", + "weight": "128.0", + "id": "403", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "80.0", + "id": "405", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "80.0", + "id": "413", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "80.0", + "id": "363", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "32.0", + "id": "6169", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "32.0", + "id": "6171", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "32.0", + "id": "6173", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "32.0", + "id": "3801", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "1438", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "1440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "1442", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "1444", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "1446", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "1448", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "1454", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1452", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1462", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "16.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "16.0", + "id": "14426", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1390", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "532", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "10937", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "12162", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1521,1522,1523", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "5.0", + "id": "10976", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "10977", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "960", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "98.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.0", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.0", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.0", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "1524,1525,5678,5679,5680,5681,5682,5683,5684,5685,5686,5687,5688,5689,5690,5691,5692,5693,5694,5695,5696,5697,5698,5699,5700,5701,5702,5703,5704,5705,5706,5707,5708,5709,5710,5711,5712,5713,5714,5715,5716,5717,5718,5719,5720,5721,5722,5723,5724,5725,5726,5727,5728,5729,5730,5731,5732,5733,5734,5735,5736,5737,5738,5739,5740,5741,5742,5743,5744,5745,5746,5747", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "7863", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "10940", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "10945", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "10941", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "10933", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "7666", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "3363", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "3365", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "3367", + "maxAmount": "3" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "884", + "maxAmount": "5" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "886", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1139", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1291", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "558", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "560.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1539", + "description": "", + "main": [ + { + "minAmount": "5", + "weight": "25.0", + "id": "995", + "maxAmount": "5" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "995", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1349", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1279", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1137", + "maxAmount": "1" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "556", + "maxAmount": "15" + }, + { + "minAmount": "9", + "weight": "25.0", + "id": "555", + "maxAmount": "9" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "562", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2349", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "2859", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "80.7333", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "11.7333", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.3333", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.2", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "1558,1559,1951,1952,1953,1954,1955,1956,6052", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "532", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1560,1561,1562,1563,1564,1565,1566", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1157", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1125", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1373", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1145", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1357", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1121", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "3122", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1347", + "maxAmount": "1" + }, + { + "minAmount": "25", + "weight": "50.0", + "id": "565", + "maxAmount": "25" + }, + { + "minAmount": "15", + "weight": "50.0", + "id": "560", + "maxAmount": "15" + }, + { + "minAmount": "65", + "weight": "50.0", + "id": "555", + "maxAmount": "65" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "563", + "maxAmount": "3" + }, + { + "minAmount": "20", + "weight": "50.0", + "id": "995", + "maxAmount": "200" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "359", + "maxAmount": "4" + }, + { + "minAmount": "6", + "weight": "25.0", + "id": "380", + "maxAmount": "6" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "10976", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "5.0", + "id": "453", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "534", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1589,3588,4667,4668", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "536", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "100.0", + "id": "2349", + "maxAmount": "5" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "39.7302", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "13.6424", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "30.8949", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "12.2934", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.4391", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "1590", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "4.0", + "id": "1315", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1355", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1369", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1197", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1123", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1303", + "maxAmount": "1" + }, + { + "minAmount": "30", + "weight": "20.0", + "id": "829", + "maxAmount": "30" + }, + { + "minAmount": "50", + "weight": "8.0", + "id": "554", + "maxAmount": "50" + }, + { + "minAmount": "16", + "weight": "7.0", + "id": "816", + "maxAmount": "16" + }, + { + "minAmount": "2", + "weight": "6.0", + "id": "9142", + "maxAmount": "12" + }, + { + "minAmount": "10", + "weight": "5.0", + "id": "563", + "maxAmount": "10" + }, + { + "minAmount": "15", + "weight": "3.0", + "id": "565", + "maxAmount": "15" + }, + { + "minAmount": "2", + "weight": "3.0", + "id": "868", + "maxAmount": "2" + }, + { + "minAmount": "25", + "weight": "1.0", + "id": "560", + "maxAmount": "25" + }, + { + "minAmount": "196", + "weight": "39.0", + "id": "995", + "maxAmount": "196" + }, + { + "minAmount": "330", + "weight": "10.0", + "id": "995", + "maxAmount": "330" + }, + { + "minAmount": "690", + "weight": "1.0", + "id": "995", + "maxAmount": "690" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "2361", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "2.0", + "id": "373", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "373", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.0625", + "id": "4087", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.0625", + "id": "4585", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "536", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "100.0", + "id": "2351", + "maxAmount": "5" + } + ], + "charm": [ + { + "minAmount": "2", + "weight": "39.7985", + "id": "0", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "12.2826", + "id": "12158", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "32.2437", + "id": "12159", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "12.8932", + "id": "12160", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "2.782", + "id": "12163", + "maxAmount": "2" + } + ], + "ids": "1591", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "4.0", + "id": "1317", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1357", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1371", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1183", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1147", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1373", + "maxAmount": "1" + }, + { + "minAmount": "4", + "weight": "20.0", + "id": "830", + "maxAmount": "4" + }, + { + "minAmount": "15", + "weight": "15.0", + "id": "560", + "maxAmount": "15" + }, + { + "minAmount": "9", + "weight": "7.0", + "id": "817", + "maxAmount": "9" + }, + { + "minAmount": "2", + "weight": "6.0", + "id": "9143", + "maxAmount": "12" + }, + { + "minAmount": "3", + "weight": "5.0", + "id": "566", + "maxAmount": "3" + }, + { + "minAmount": "5", + "weight": "3.0", + "id": "868", + "maxAmount": "5" + }, + { + "minAmount": "3", + "weight": "5.0", + "id": "566", + "maxAmount": "3" + }, + { + "minAmount": "270", + "weight": "19.0", + "id": "995", + "maxAmount": "270" + }, + { + "minAmount": "550", + "weight": "10.0", + "id": "995", + "maxAmount": "550" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "161", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "9431", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "3.0", + "id": "2361", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "2011", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.0128", + "id": "11286", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.125", + "id": "4087", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.125", + "id": "4585", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "536", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "100.0", + "id": "2353", + "maxAmount": "5" + } + ], + "charm": [ + { + "minAmount": "3", + "weight": "33.614", + "id": "0", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "13.8986", + "id": "12158", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "35.1826", + "id": "12159", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "14.2297", + "id": "12160", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "3.0751", + "id": "12163", + "maxAmount": "3" + } + ], + "ids": "1592,3590", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "4.0", + "id": "1432", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1359", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1163", + "maxAmount": "1" + }, + { + "minAmount": "7", + "weight": "20.0", + "id": "830", + "maxAmount": "7" + }, + { + "minAmount": "15", + "weight": "15.0", + "id": "565", + "maxAmount": "15" + }, + { + "minAmount": "12", + "weight": "7.0", + "id": "817", + "maxAmount": "12" + }, + { + "minAmount": "2", + "weight": "6.0", + "id": "9144", + "maxAmount": "12" + }, + { + "minAmount": "5", + "weight": "5.0", + "id": "566", + "maxAmount": "5" + }, + { + "minAmount": "470", + "weight": "20.0", + "id": "995", + "maxAmount": "470" + }, + { + "minAmount": "650", + "weight": "10.0", + "id": "995", + "maxAmount": "650" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "145", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "9431", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "2363", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "165", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "2011", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "1.0", + "id": "2011", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.0128", + "id": "11286", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.25", + "id": "4087", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.25", + "id": "4585", + "maxAmount": "1" + }, + { + "minAmount": "7", + "weight": "3.0", + "id": "868", + "maxAmount": "7" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "70.4846", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.8947", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "15.901", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "6.4401", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.2796", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "1593,1594", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "1", + "weight": "87.3121", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "9.0562", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.2646", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.9459", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.4212", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "1600,1601,1602,1603", + "description": "", + "main": [ + { + "minAmount": "9", + "weight": "50.0", + "id": "557", + "maxAmount": "10" + }, + { + "minAmount": "12", + "weight": "50.0", + "id": "554", + "maxAmount": "12" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "561", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5318", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5319", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5324", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5322", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5320", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5323", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5321", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "12148", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "203", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "205", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "211", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "213", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "215", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "221", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "225", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "239", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "227", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "223", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "235", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "231", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "995", + "maxAmount": "3" + }, + { + "minAmount": "8", + "weight": "50.0", + "id": "995", + "maxAmount": "8" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "4119", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "187", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "1", + "weight": "73.48", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "11.8412", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.9054", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.9876", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.7859", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "1604,1605,1606,1607", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "12.0", + "id": "1353", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1197", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "3053", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1073", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1163", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "4103", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "130.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "130.0", + "id": "14424", + "maxAmount": "2" + }, + { + "minAmount": "3", + "weight": "47.0", + "id": "14424", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "76.0", + "id": "14428", + "maxAmount": "1" + }, + { + "minAmount": "460", + "weight": "4.0", + "id": "995", + "maxAmount": "460" + }, + { + "minAmount": "1", + "weight": "72.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "20.0", + "id": "14426", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "56.3725", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.8432", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "26.9563", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "6.4594", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.3687", + "id": "12163", + "maxAmount": "1" + } + ], + "tertiary": [ + { + "minAmount": "1", + "weight": "2999.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "7978", + "maxAmount": "1" + } + ], + "ids": "1608,1609,4229", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "3.0", + "id": "1355", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1197", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1123", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1303", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "13290", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "4111", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "4160", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "13280", + "maxAmount": "10" + }, + { + "minAmount": "20", + "weight": "2.0", + "id": "13278", + "maxAmount": "60" + }, + { + "minAmount": "20", + "weight": "2.0", + "id": "13279", + "maxAmount": "60" + }, + { + "minAmount": "5", + "weight": "2.0", + "id": "9143", + "maxAmount": "20" + }, + { + "minAmount": "5", + "weight": "10.0", + "id": "561", + "maxAmount": "5" + }, + { + "minAmount": "15", + "weight": "6.0", + "id": "561", + "maxAmount": "15" + }, + { + "minAmount": "30", + "weight": "2.0", + "id": "561", + "maxAmount": "30" + }, + { + "minAmount": "1", + "weight": "18.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "15.0", + "id": "14422", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "22", + "weight": "8.0", + "id": "995", + "maxAmount": "22" + }, + { + "minAmount": "748", + "weight": "2.0", + "id": "995", + "maxAmount": "748" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "239", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "3.0", + "id": "225", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "3.0", + "id": "2114", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1963", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "2.0", + "id": "1963", + "maxAmount": "2" + }, + { + "minAmount": "20", + "weight": "2.0", + "id": "1780", + "maxAmount": "30" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "2289", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "2.0", + "id": "526", + "maxAmount": "2" + }, + { + "minAmount": "4", + "weight": "1.0", + "id": "526", + "maxAmount": "4" + }, + { + "minAmount": "2", + "weight": "2.0", + "id": "532", + "maxAmount": "2" + }, + { + "minAmount": "4", + "weight": "1.0", + "id": "532", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "161", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "173", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "4", + "weight": "4.0", + "id": "558", + "maxAmount": "16" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "560", + "maxAmount": "5" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "1", + "weight": "73.7631", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "9.5666", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.7979", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.8876", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "6.9849", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "1610,1827,6389", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "16.0", + "id": "1311", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "12.0", + "id": "1353", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "12.0", + "id": "1365", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "4129", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1163", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "4153", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "4101", + "maxAmount": "1" + }, + { + "minAmount": "75", + "weight": "32.0", + "id": "554", + "maxAmount": "75" + }, + { + "minAmount": "15", + "weight": "12.0", + "id": "562", + "maxAmount": "15" + }, + { + "minAmount": "5", + "weight": "12.0", + "id": "560", + "maxAmount": "5" + }, + { + "minAmount": "37", + "weight": "4.0", + "id": "554", + "maxAmount": "37" + }, + { + "minAmount": "132", + "weight": "160.0", + "id": "995", + "maxAmount": "132" + }, + { + "minAmount": "44", + "weight": "108.0", + "id": "995", + "maxAmount": "44" + }, + { + "minAmount": "220", + "weight": "40.0", + "id": "995", + "maxAmount": "220" + }, + { + "minAmount": "11", + "weight": "28.0", + "id": "995", + "maxAmount": "11" + }, + { + "minAmount": "460", + "weight": "4.0", + "id": "995", + "maxAmount": "460" + }, + { + "minAmount": "3", + "weight": "8.0", + "id": "2353", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "8.0", + "id": "2359", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "2357", + "maxAmount": "1" + }, + { + "minAmount": "10", + "weight": "4.0", + "id": "1734", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "20.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "35", + "weight": "8.0", + "id": "7937", + "maxAmount": "35" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "12163", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5600.0", + "id": "0", + "maxAmount": "1" + } + ], + "ids": "1611", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "1311", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1365", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1353", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "4153", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1163", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "4129", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1157", + "maxAmount": "1" + }, + { + "minAmount": "37", + "weight": "50.0", + "id": "554", + "maxAmount": "37" + }, + { + "minAmount": "75", + "weight": "50.0", + "id": "554", + "maxAmount": "75" + }, + { + "minAmount": "15", + "weight": "50.0", + "id": "562", + "maxAmount": "15" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "560", + "maxAmount": "5" + }, + { + "minAmount": "11", + "weight": "50.0", + "id": "995", + "maxAmount": "498" + }, + { + "minAmount": "35", + "weight": "25.0", + "id": "7937", + "maxAmount": "35" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "2359", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "2353", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2357", + "maxAmount": "1" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "1734", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "1", + "weight": "88.902", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.4973", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "6.9705", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.3085", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.3217", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "1612", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "16.0", + "id": "1420", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "16.0", + "id": "1203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "1191", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "23.0", + "id": "556", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "16.0", + "id": "562", + "maxAmount": "3" + }, + { + "minAmount": "6", + "weight": "8.0", + "id": "562", + "maxAmount": "6" + }, + { + "minAmount": "2", + "weight": "23.0", + "id": "564", + "maxAmount": "2" + }, + { + "minAmount": "7", + "weight": "8.0", + "id": "554", + "maxAmount": "7" + }, + { + "minAmount": "13", + "weight": "80.0", + "id": "995", + "maxAmount": "13" + }, + { + "minAmount": "26", + "weight": "64.0", + "id": "995", + "maxAmount": "26" + }, + { + "minAmount": "13", + "weight": "176.0", + "id": "7937", + "maxAmount": "13" + }, + { + "minAmount": "7", + "weight": "40.0", + "id": "313", + "maxAmount": "7" + }, + { + "minAmount": "15", + "weight": "176.0", + "id": "313", + "maxAmount": "15" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "221", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "4105", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "1", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "272.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "16.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "35", + "weight": "64.0", + "id": "995", + "maxAmount": "35" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "592", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "55.2891", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.8367", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.368", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "30.4735", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0327", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "1613", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "4.0", + "id": "1311", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1353", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1365", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1197", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1073", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1163", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "4131", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "3.0", + "id": "560", + "maxAmount": "5" + }, + { + "minAmount": "10", + "weight": "3.0", + "id": "560", + "maxAmount": "10" + }, + { + "minAmount": "37", + "weight": "1.0", + "id": "562", + "maxAmount": "37" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "14428", + "maxAmount": "1" + }, + { + "minAmount": "132", + "weight": "40.0", + "id": "995", + "maxAmount": "132" + }, + { + "minAmount": "44", + "weight": "29.0", + "id": "995", + "maxAmount": "44" + }, + { + "minAmount": "220", + "weight": "10.0", + "id": "995", + "maxAmount": "220" + }, + { + "minAmount": "11", + "weight": "7.0", + "id": "995", + "maxAmount": "11" + }, + { + "minAmount": "460", + "weight": "1.0", + "id": "995", + "maxAmount": "460" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "361", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "2357", + "maxAmount": "1" + }, + { + "minAmount": "10", + "weight": "1.0", + "id": "1734", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "592", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "52.8956", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.6662", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.4161", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "32.9683", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0538", + "id": "12163", + "maxAmount": "1" + } + ], + "tertiary": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "7979", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4999.0", + "id": "0", + "maxAmount": "1" + } + ], + "ids": "1615,4230", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "4.0", + "id": "1283", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1365", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1361", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1197", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1147", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1113", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "19.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "50", + "weight": "8.0", + "id": "556", + "maxAmount": "50" + }, + { + "minAmount": "7", + "weight": "4.0", + "id": "565", + "maxAmount": "7" + }, + { + "minAmount": "10", + "weight": "6.0", + "id": "562", + "maxAmount": "10" + }, + { + "minAmount": "3", + "weight": "1.0", + "id": "563", + "maxAmount": "3" + }, + { + "minAmount": "60", + "weight": "5.0", + "id": "7937", + "maxAmount": "60" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "2361", + "maxAmount": "1" + }, + { + "minAmount": "30", + "weight": "7.0", + "id": "995", + "maxAmount": "30" + }, + { + "minAmount": "44", + "weight": "6.0", + "id": "995", + "maxAmount": "44" + }, + { + "minAmount": "132", + "weight": "35.0", + "id": "995", + "maxAmount": "132" + }, + { + "minAmount": "220", + "weight": "9.0", + "id": "995", + "maxAmount": "220" + }, + { + "minAmount": "460", + "weight": "1.0", + "id": "995", + "maxAmount": "460" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "379", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1454", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1452", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "133", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.25", + "id": "4151", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "67.2875", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "7.0347", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "19.4192", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0371", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.2214", + "id": "12163", + "maxAmount": "1" + } + ], + "tertiary": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "7977", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1999.0", + "id": "0", + "maxAmount": "1" + } + ], + "ids": "1616,1617,4228", + "description": "", + "main": [ + { + "minAmount": "75", + "weight": "50.0", + "id": "555", + "maxAmount": "175" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "561", + "maxAmount": "45" + }, + { + "minAmount": "12", + "weight": "25.0", + "id": "562", + "maxAmount": "12" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "563", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1365", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1243", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1355", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1197", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1161", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "207", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "211", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "11", + "weight": "50.0", + "id": "995", + "maxAmount": "495" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "7899", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1452", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "449", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "379", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "4109", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "4109", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "53.9118", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "9.3528", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "30.9557", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.6941", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0855", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "1618,1619,6215", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "4.0", + "id": "1353", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1157", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1325", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1181", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1109", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "4125", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1147", + "maxAmount": "1" + }, + { + "minAmount": "60", + "weight": "8.0", + "id": "554", + "maxAmount": "60" + }, + { + "minAmount": "3", + "weight": "3.0", + "id": "565", + "maxAmount": "3" + }, + { + "minAmount": "10", + "weight": "5.0", + "id": "565", + "maxAmount": "10" + }, + { + "minAmount": "30", + "weight": "1.0", + "id": "565", + "maxAmount": "30" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "10", + "weight": "7.0", + "id": "995", + "maxAmount": "10" + }, + { + "minAmount": "40", + "weight": "25.0", + "id": "995", + "maxAmount": "40" + }, + { + "minAmount": "120", + "weight": "20.0", + "id": "995", + "maxAmount": "120" + }, + { + "minAmount": "200", + "weight": "10.0", + "id": "995", + "maxAmount": "200" + }, + { + "minAmount": "450", + "weight": "1.0", + "id": "995", + "maxAmount": "450" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "526", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "7.0", + "id": "532", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "3.0", + "id": "532", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "2293", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "444", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "5104", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "11072", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "88.9239", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.2682", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "7.3641", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.1737", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.27", + "id": "12163", + "maxAmount": "1" + } + ], + "tertiary": [ + { + "minAmount": "1", + "weight": "114872.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "128.0", + "id": "7976", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "13000.0", + "id": "12109", + "maxAmount": "1" + } + ], + "ids": "1620,1621,4227", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "12.0", + "id": "1279", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "12.0", + "id": "1207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "4121", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "4.0", + "id": "826", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1295", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "4117", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "24.0", + "id": "561", + "maxAmount": "2" + }, + { + "minAmount": "4", + "weight": "16.0", + "id": "561", + "maxAmount": "4" + }, + { + "minAmount": "2", + "weight": "12.0", + "id": "563", + "maxAmount": "2" + }, + { + "minAmount": "6", + "weight": "8.0", + "id": "561", + "maxAmount": "6" + }, + { + "minAmount": "2", + "weight": "8.0", + "id": "555", + "maxAmount": "2" + }, + { + "minAmount": "7", + "weight": "8.0", + "id": "554", + "maxAmount": "7" + }, + { + "minAmount": "1", + "weight": "40.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "72.0", + "id": "14430", + "maxAmount": "1" + }, + { + "minAmount": "15", + "weight": "64.0", + "id": "995", + "maxAmount": "15" + }, + { + "minAmount": "5", + "weight": "48.0", + "id": "995", + "maxAmount": "5" + }, + { + "minAmount": "28", + "weight": "48.0", + "id": "995", + "maxAmount": "28" + }, + { + "minAmount": "62", + "weight": "16.0", + "id": "995", + "maxAmount": "62" + }, + { + "minAmount": "42", + "weight": "12.0", + "id": "995", + "maxAmount": "42" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "995", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "84.0", + "id": "225", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "14426", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "64.0022", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "7.3073", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "22.1332", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.3634", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.1938", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "1622,1623,1626,1627,1628,1629,1630", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "19.0", + "id": "1069", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "1355", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1197", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1161", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "13290", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "4113", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "17.0", + "id": "563", + "maxAmount": "3" + }, + { + "minAmount": "15", + "weight": "14.0", + "id": "561", + "maxAmount": "15" + }, + { + "minAmount": "37", + "weight": "3.0", + "id": "561", + "maxAmount": "37" + }, + { + "minAmount": "1", + "weight": "22.0", + "id": "199", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "16.0", + "id": "201", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "12.0", + "id": "203", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "9.0", + "id": "205", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "7.0", + "id": "207", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "209", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "211", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "213", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "215", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "2485", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "217", + "maxAmount": "3" + }, + { + "minAmount": "44", + "weight": "77.0", + "id": "995", + "maxAmount": "44" + }, + { + "minAmount": "132", + "weight": "32.0", + "id": "995", + "maxAmount": "132" + }, + { + "minAmount": "440", + "weight": "3.0", + "id": "995", + "maxAmount": "440" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "5296", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "7.0", + "id": "5297", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "7.0", + "id": "5281", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5106", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5298", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "5299", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "5300", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "5301", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "5302", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "5303", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "5304", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "19.0", + "id": "225", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5280", + "maxAmount": "1" + }, + { + "minAmount": "45", + "weight": "1.0", + "id": "561", + "maxAmount": "45" + }, + { + "minAmount": "1", + "weight": "64.0022", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "55.1863", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "11.8733", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "6.1533", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.8346", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.9525", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "1624", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "1353", + "maxAmount": "1" + }, + { + "minAmount": "15", + "weight": "50.0", + "id": "892", + "maxAmount": "15" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2489", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1399", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "15.0", + "id": "1213", + "maxAmount": "1" + }, + { + "minAmount": "37", + "weight": "50.0", + "id": "554", + "maxAmount": "37" + }, + { + "minAmount": "150", + "weight": "50.0", + "id": "554", + "maxAmount": "150" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "562", + "maxAmount": "5" + }, + { + "minAmount": "2", + "weight": "15.0", + "id": "566", + "maxAmount": "2" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "566", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "995", + "maxAmount": "15" + }, + { + "minAmount": "25", + "weight": "25.0", + "id": "995", + "maxAmount": "25" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "2359", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1883", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "15.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.02822962", + "id": "3140", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "300", + "weight": "15.0", + "id": "554", + "maxAmount": "300" + }, + { + "minAmount": "60", + "weight": "25.0", + "id": "995", + "maxAmount": "60" + }, + { + "minAmount": "300", + "weight": "25.0", + "id": "995", + "maxAmount": "300" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1631,1632", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "0.07", + "id": "4115", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "8.0", + "id": "557", + "maxAmount": "5" + }, + { + "minAmount": "42", + "weight": "1.3", + "id": "557", + "maxAmount": "42" + }, + { + "minAmount": "2", + "weight": "1.3", + "id": "562", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "5.9", + "id": "440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.6", + "id": "453", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.3", + "id": "438", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "2351", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "436", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.5", + "id": "2349", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.3", + "id": "447", + "maxAmount": "1" + }, + { + "minAmount": "4", + "weight": "1.0", + "id": "5318", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "0.6", + "id": "5319", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "0.5", + "id": "5324", + "maxAmount": "4" + }, + { + "minAmount": "3", + "weight": "0.2", + "id": "5322", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "0.1", + "id": "5320", + "maxAmount": "3" + }, + { + "minAmount": "2", + "weight": "0.05", + "id": "5323", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "0.025", + "id": "5321", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "3.7", + "id": "1913", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.6", + "id": "2347", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.3", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.6", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "592", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "86.6357", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0393", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.4947", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.338", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.4923", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "1633,1634,1635,1636,6216", + "description": "", + "main": [ + { + "minAmount": "30", + "weight": "50.0", + "id": "554", + "maxAmount": "30" + }, + { + "minAmount": "60", + "weight": "50.0", + "id": "554", + "maxAmount": "60" + }, + { + "minAmount": "12", + "weight": "50.0", + "id": "562", + "maxAmount": "12" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "563", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "560", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1157", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1387", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1353", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1365", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "886", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1109", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "4123", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1145", + "maxAmount": "1" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "995", + "maxAmount": "10" + }, + { + "minAmount": "40", + "weight": "50.0", + "id": "995", + "maxAmount": "40" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "444", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1993", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "1", + "weight": "65.9946", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "7.6208", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "21.8565", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.5828", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.9453", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "1637,1638,1639,1640,1641,1642", + "description": "", + "main": [ + { + "minAmount": "15", + "weight": "25.0", + "id": "562", + "maxAmount": "15" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "560", + "maxAmount": "5" + }, + { + "minAmount": "5", + "weight": "5.0", + "id": "555", + "maxAmount": "21" + }, + { + "minAmount": "7", + "weight": "5.0", + "id": "565", + "maxAmount": "7" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1365", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1311", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1353", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1197", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "4127", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1163", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1119", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1373", + "maxAmount": "1" + }, + { + "minAmount": "11", + "weight": "50.0", + "id": "995", + "maxAmount": "497" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2357", + "maxAmount": "1" + }, + { + "minAmount": "10", + "weight": "5.0", + "id": "1734", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "61.2459", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "32.8603", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.7701", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.5155", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.6082", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "1643,1644,1645,1646,1647", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "1379", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1387", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "3053", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1401", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "557", + "maxAmount": "5" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "557", + "maxAmount": "10" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "554", + "maxAmount": "10" + }, + { + "minAmount": "18", + "weight": "50.0", + "id": "554", + "maxAmount": "18" + }, + { + "minAmount": "7", + "weight": "50.0", + "id": "560", + "maxAmount": "7" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "565", + "maxAmount": "4" + }, + { + "minAmount": "7", + "weight": "25.0", + "id": "565", + "maxAmount": "7" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "556", + "maxAmount": "10" + }, + { + "minAmount": "18", + "weight": "25.0", + "id": "556", + "maxAmount": "18" + }, + { + "minAmount": "18", + "weight": "25.0", + "id": "558", + "maxAmount": "18" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "555", + "maxAmount": "10" + }, + { + "minAmount": "18", + "weight": "25.0", + "id": "555", + "maxAmount": "18" + }, + { + "minAmount": "18", + "weight": "25.0", + "id": "559", + "maxAmount": "18" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "995", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "50.0", + "id": "995", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "4099", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "4107", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "12163", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5600.0", + "id": "0", + "maxAmount": "1" + } + ], + "tertiary": [ + { + "minAmount": "1", + "weight": "511.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "7975", + "maxAmount": "1" + } + ], + "ids": "1648,1649,1650,1651,1652,1653,1654,1655,1656,1657", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "2902", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2922", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2912", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2942", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "3799", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "4155", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1635", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1637", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1639", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1641", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "995", + "maxAmount": "442" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "592", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "2859", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "46.664", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "44.29", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0169", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.9727", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0564", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "6006,6007,6008,6009,6010,6011,6012,6013,6014,6015,6016,6017,6018,6019,6020,6021,6022,6023,6024,6025,6026,6027,6028,6029,6030,6031,6032,6033,6034,6035,6036,6037,6038,6039,6040,6041,6042,6043,6044,6045,6212,6213", + "description": "Werewolves (and human form for Canifis)", + "main": [ + { + "minAmount": "5", + "weight": "50.0", + "id": "2138", + "maxAmount": "5" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "2132", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "2136", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1993", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1325", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1353", + "maxAmount": "1" + }, + { + "minAmount": "50", + "weight": "25.0", + "id": "886", + "maxAmount": "50" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1157", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1329", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1181", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1109", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1147", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "830", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "995", + "maxAmount": "10" + }, + { + "minAmount": "90", + "weight": "50.0", + "id": "995", + "maxAmount": "90" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "6814", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "958", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "7868", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "245", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "983", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "239", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1925", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "440", + "maxAmount": "5" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "453", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "227", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "590", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "2353", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "1739", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "4287", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "12163", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5600.0", + "id": "0", + "maxAmount": "1" + } + ], + "ids": "1691,5211", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "100.0", + "id": "314", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "4289", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1692", + "description": "", + "main": [] + }, + { + "default": [], + "charm": [], + "ids": "1698", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "5321", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5323", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5292", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5293", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5294", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "12176", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5296", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5297", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5100", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5104", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5105", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5106", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5311", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5295", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5299", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5300", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5304", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5280", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5298", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "6", + "weight": "50.0", + "id": "555", + "maxAmount": "6" + }, + { + "minAmount": "7", + "weight": "50.0", + "id": "559", + "maxAmount": "7" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "563", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "50.0", + "id": "995", + "maxAmount": "612" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "225", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "227", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1710,1711,1712", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "1207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1129", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "697", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "686", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "882", + "maxAmount": "8" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "886", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1351", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1349", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1353", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1265", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1267", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1269", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "946", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "50.0", + "id": "995", + "maxAmount": "19" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1625", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1627", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "321", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2138", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1739", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "453", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "688", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "590", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1511", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "314", + "maxAmount": "7" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1734", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5321", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5323", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5319", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5324", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2370", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "1713,4329", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "1714,1715,1716,1717,4318,4320", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "882", + "maxAmount": "20" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1351", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1265", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1349", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1267", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "886", + "maxAmount": "20" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1353", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1269", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1129", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "50.0", + "id": "995", + "maxAmount": "21" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "319", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "2138", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "50.0", + "id": "314", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1734", + "maxAmount": "6" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1511", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1625", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "686", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "697", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2714", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1627", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "688", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "453", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1739", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5733", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "82.8244", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "12.2137", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.5725", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0076", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.3817", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "1752,1753,6109,6110,6111", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "2128", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "2102", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "2171", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "2120", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2165", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2166", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2169", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2164", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "7878", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "1739", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "2132", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "93.2258", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.7419", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.5806", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.9677", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.4839", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "1766,1768,2310", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "93.2258", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1795,1796,1797", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1814,1815,1816,1817,1818", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "86.9276", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "6.5495", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.476", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.8488", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.1981", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "1822,1823,1824,1825,5752,5753,5754,5755,5756,5757,5758,5759,5760,5761,5762,5763,5764,5765,5766,5767,5768,5769,5783,5785,5873,5874,5875,5876,5877,5878", + "description": "", + "main": [ + { + "minAmount": "6", + "weight": "50.0", + "id": "555", + "maxAmount": "6" + }, + { + "minAmount": "7", + "weight": "25.0", + "id": "559", + "maxAmount": "7" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "557", + "maxAmount": "4" + }, + { + "minAmount": "13", + "weight": "25.0", + "id": "558", + "maxAmount": "19" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1438", + "maxAmount": "1" + }, + { + "minAmount": "8", + "weight": "50.0", + "id": "877", + "maxAmount": "8" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1965", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5016", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5018", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1381", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1009", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1237", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1173", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "7907", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1949", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "2307", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1917", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "10999", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "288", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1101", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "590", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "995", + "maxAmount": "49" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "1987", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "532", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1828", + "description": "", + "main": [ + { + "minAmount": "2", + "weight": "50.0", + "id": "995", + "maxAmount": "2" + }, + { + "minAmount": "30", + "weight": "50.0", + "id": "995", + "maxAmount": "30" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "4517", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "561", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "561", + "maxAmount": "3" + }, + { + "minAmount": "22", + "weight": "25.0", + "id": "884", + "maxAmount": "22" + }, + { + "minAmount": "45", + "weight": "25.0", + "id": "886", + "maxAmount": "45" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "565", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "564", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "453", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1243", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1969", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "10976", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "4129", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "10977", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1829", + "description": "", + "main": [ + { + "minAmount": "12", + "weight": "25.0", + "id": "555", + "maxAmount": "12" + }, + { + "minAmount": "12", + "weight": "25.0", + "id": "557", + "maxAmount": "12" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "564", + "maxAmount": "2" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "561", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1444", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1440", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "995", + "maxAmount": "5" + }, + { + "minAmount": "15", + "weight": "50.0", + "id": "995", + "maxAmount": "15" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "4517", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1830,2469,2470,2471,2472,2473,2689,3300,3783", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5004", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "5004", + "maxAmount": "5" + }, + { + "minAmount": "6", + "weight": "50.0", + "id": "555", + "maxAmount": "6" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11766", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11767", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11768", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11769", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11764", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "1939", + "maxAmount": "6" + } + ], + "charm": [], + "ids": "1831", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "1351", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1279", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1155", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1191", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "4121", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "557", + "maxAmount": "5" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "555", + "maxAmount": "15" + }, + { + "minAmount": "7", + "weight": "25.0", + "id": "559", + "maxAmount": "7" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "995", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "50.0", + "id": "995", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "596", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "4540", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2357", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "1", + "weight": "52.5489", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "6.5845", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "36.5336", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.5259", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.8071", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "5750", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "221", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "225", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "231", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "223", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "235", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "995", + "maxAmount": "8" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "590", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "10978", + "maxAmount": "8" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "4529", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "36", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "555", + "maxAmount": "167" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "557", + "maxAmount": "147" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "554", + "maxAmount": "91" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "561", + "maxAmount": "8" + }, + { + "minAmount": "2", + "weight": "50.0", + "id": "995", + "maxAmount": "36" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "10978", + "maxAmount": "8" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1395", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1874", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "7862", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "532", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1935,1936,1937,1938,1939,1940,1941,1942", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1157", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1125", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1373", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1145", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1357", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1121", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "3122", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1347", + "maxAmount": "1" + }, + { + "minAmount": "25", + "weight": "50.0", + "id": "565", + "maxAmount": "25" + }, + { + "minAmount": "15", + "weight": "50.0", + "id": "560", + "maxAmount": "15" + }, + { + "minAmount": "65", + "weight": "50.0", + "id": "555", + "maxAmount": "65" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "563", + "maxAmount": "3" + }, + { + "minAmount": "20", + "weight": "50.0", + "id": "995", + "maxAmount": "200" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "359", + "maxAmount": "4" + }, + { + "minAmount": "6", + "weight": "25.0", + "id": "380", + "maxAmount": "6" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "10976", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "5.0", + "id": "453", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "592", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "12163", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5600.0", + "id": "0", + "maxAmount": "1" + } + ], + "ids": "1958,1961,1960,5360", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "5.0", + "id": "1333", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1185", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "4675", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1673", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1654", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1635", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1696", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1639", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2566", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1727", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1656", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1637", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11072", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "995", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "405", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "2357", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "444", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "970", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "9032", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1939", + "maxAmount": "17" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "950", + "maxAmount": "1" + }, + { + "minAmount": "10", + "weight": "5.0", + "id": "2007", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "86.2564", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "7.1429", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.5191", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.838", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.2436", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "1976", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "3032", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "2428", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "2432", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "113", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1991", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "995", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1994", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "7914", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "9052", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1995", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1996,3675,3676,6792,6946,7320,7322,7324,7326,7328", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "7911", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "11965", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "1", + "weight": "79.2519", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.389", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "12.9177", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.7431", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.6983", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "2031", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "2032", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "91.6382", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.6928", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.4744", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.9386", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.256", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "2033,4920,4921", + "description": "", + "main": [] + }, + { + "default": [], + "charm": [ + { + "minAmount": "1", + "weight": "90.4762", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.291", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.1164", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.5291", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.5873", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "2035", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "4850", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "4812", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "2044,2045,2046,2047,2048,2049,2050,2051,2052,2053,2054,2055,2056,2057", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "2058", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1351", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1291", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1139", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1189", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1349", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1420", + "maxAmount": "1" + }, + { + "minAmount": "58", + "weight": "25.0", + "id": "884", + "maxAmount": "58" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "886", + "maxAmount": "32" + }, + { + "minAmount": "12", + "weight": "25.0", + "id": "888", + "maxAmount": "12" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1381", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "559", + "maxAmount": "11" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "562", + "maxAmount": "4" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "556", + "maxAmount": "3" + }, + { + "minAmount": "7", + "weight": "25.0", + "id": "554", + "maxAmount": "84" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "558", + "maxAmount": "7" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "561", + "maxAmount": "5" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "563", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "564", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "6476", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "7863", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "995", + "maxAmount": "82" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "313", + "maxAmount": "7" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "590", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "966", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1917", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "436", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "438", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "592", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "221", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1594", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2331", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "2069,2070,2071,2072,2075,2076,2077,2078", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "995", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "440", + "maxAmount": "7" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "442", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "590", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "7907", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5014", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "2073,2074", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "5016", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5018", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1153", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5014", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1101", + "maxAmount": "1" + }, + { + "minAmount": "12", + "weight": "50.0", + "id": "995", + "maxAmount": "12" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "7907", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "590", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "2109,2110,2111,2112,2113,2114,2115,2116,2117,2118,2119,2120,2121,2122,2124,2126", + "description": "", + "main": [ + { + "minAmount": "100", + "weight": "99.0", + "id": "995", + "maxAmount": "100" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "73.5695", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.9046", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "9.1281", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.6349", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.7629", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "2130,2131,2132,2133,3276,3277,3278,3279", + "description": "", + "main": [ + { + "minAmount": "2", + "weight": "25.0", + "id": "562", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "561", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1139", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1375", + "maxAmount": "1" + }, + { + "minAmount": "6", + "weight": "25.0", + "id": "877", + "maxAmount": "6" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1337", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1265", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1363", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1341", + "maxAmount": "1" + }, + { + "minAmount": "4", + "weight": "50.0", + "id": "995", + "maxAmount": "42" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "436", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2349", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2351", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2347", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "453", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "6.11111", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "3801", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1929", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1592", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "2134,2135,2136,2232", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "1337", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1335", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1339", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1341", + "maxAmount": "1" + }, + { + "minAmount": "35", + "weight": "50.0", + "id": "995", + "maxAmount": "57" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "438", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1917", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "3801", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1592", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1929", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "2234,2235", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "5291", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5292", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5293", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5294", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5295", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5296", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5297", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5298", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5299", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5300", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5301", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5302", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5303", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5304", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5281", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5280", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "99.1835", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.8165", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.0", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.0", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.0", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "2239,2240,2316,2317", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "592", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "96.1266", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.7056", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.9032", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.2058", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.0588", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "2263", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "5521", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "7936", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "50.0", + "id": "7937", + "maxAmount": "2" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "7937", + "maxAmount": "5" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "7937", + "maxAmount": "10" + }, + { + "minAmount": "25", + "weight": "50.0", + "id": "7937", + "maxAmount": "25" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1438", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1448", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1444", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1442", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1446", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1454", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1452", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1462", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1458", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5516", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "12161", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "96.1266", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "592", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "80.0326", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0474", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "12.1634", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.149", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.6076", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "2264", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "45.0", + "id": "5521", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "7936", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "50.0", + "id": "7937", + "maxAmount": "2" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "7937", + "maxAmount": "5" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "7937", + "maxAmount": "10" + }, + { + "minAmount": "25", + "weight": "50.0", + "id": "7937", + "maxAmount": "25" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1438", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1448", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1444", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1442", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1446", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1454", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1452", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1462", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1458", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5516", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "12161", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "80.0326", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "592", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "73.5196", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.1545", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "18.176", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.6304", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.5194", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "2265", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "45.0", + "id": "5521", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "7936", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "50.0", + "id": "7937", + "maxAmount": "2" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "7937", + "maxAmount": "5" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "7937", + "maxAmount": "10" + }, + { + "minAmount": "25", + "weight": "50.0", + "id": "7937", + "maxAmount": "25" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1438", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1448", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1444", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1442", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1446", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1454", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1452", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1462", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1458", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5516", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "12161", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "73.5196", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "3", + "weight": "2.8249", + "id": "0", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "79.2687", + "id": "12158", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "9.3063", + "id": "12159", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "6.6384", + "id": "12160", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "1.9617", + "id": "12163", + "maxAmount": "3" + } + ], + "ids": "2452,2885", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "555", + "maxAmount": "39" + }, + { + "minAmount": "2", + "weight": "50.0", + "id": "557", + "maxAmount": "37" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1438", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1448", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1442", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1454", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1446", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1444", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1462", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1452", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1119", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1125", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1355", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "6151", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "6145", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1341", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1301", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1345", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5106", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5281", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5291", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5292", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5293", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5294", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5296", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5295", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5297", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5298", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5300", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5301", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5302", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5303", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5304", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "27", + "weight": "50.0", + "id": "995", + "maxAmount": "27" + }, + { + "minAmount": "28", + "weight": "50.0", + "id": "995", + "maxAmount": "28" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "377", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "363", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "590", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "405", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "6161", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "6157", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "6159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "2454", + "description": "", + "main": [ + { + "minAmount": "16", + "weight": "50.0", + "id": "995", + "maxAmount": "38" + }, + { + "minAmount": "2", + "weight": "50.0", + "id": "314", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "359", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "327", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "555", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "407", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "411", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "56.7727", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "15.2283", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "7.576", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.5159", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "11.907", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "2457,2884", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "554", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "563", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "556", + "maxAmount": "6" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "558", + "maxAmount": "9" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "555", + "maxAmount": "10" + }, + { + "minAmount": "4", + "weight": "50.0", + "id": "557", + "maxAmount": "9" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "562", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "564", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "561", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "560", + "maxAmount": "10" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "565", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1438", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1448", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1444", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1442", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1454", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1462", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5291", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5292", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5293", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5294", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5296", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5295", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5297", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5298", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5299", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5300", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5301", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5302", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5303", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5304", + "maxAmount": "1" + }, + { + "minAmount": "9", + "weight": "50.0", + "id": "7937", + "maxAmount": "9" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "886", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "6167", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "6165", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "6153", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "6147", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "6163", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "353", + "maxAmount": "2" + }, + { + "minAmount": "5", + "weight": "5.0", + "id": "995", + "maxAmount": "489" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "359", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "6287", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "2489,2490", + "description": "", + "main": [] + }, + { + "default": [], + "charm": [ + { + "minAmount": "1", + "weight": "40.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "88.0", + "id": "12168", + "maxAmount": "1" + } + ], + "ids": "2591,2592,2593,2594,2595,2596,2597,7753", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "6526", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "6568", + "maxAmount": "1" + }, + { + "minAmount": "25", + "weight": "256.0", + "id": "557", + "maxAmount": "25" + }, + { + "minAmount": "25", + "weight": "256.0", + "id": "554", + "maxAmount": "25" + }, + { + "minAmount": "25", + "weight": "128.0", + "id": "556", + "maxAmount": "25" + }, + { + "minAmount": "5", + "weight": "64.0", + "id": "562", + "maxAmount": "5" + }, + { + "minAmount": "2", + "weight": "64.0", + "id": "561", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "32.0", + "id": "560", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "1617", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "32.0", + "id": "1619", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "64.0", + "id": "1621", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "128.0", + "id": "1623", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "160.0", + "id": "9194", + "maxAmount": "1" + }, + { + "minAmount": "100", + "weight": "1280.0", + "id": "6529", + "maxAmount": "1000" + }, + { + "minAmount": "1", + "weight": "1622.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "1", + "weight": "40.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "88.0", + "id": "12168", + "maxAmount": "1" + } + ], + "ids": "2598,2599,2600,2601,2602,2603,7754,7767,7768,7769", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "8.0", + "id": "2347", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "1755", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "946", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "1935", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "1931", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1617", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1619", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "1621", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "16.0", + "id": "1623", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "20.0", + "id": "9194", + "maxAmount": "1" + }, + { + "minAmount": "100", + "weight": "160.0", + "id": "6529", + "maxAmount": "700" + }, + { + "minAmount": "1", + "weight": "263.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "1", + "weight": "40.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "88.0", + "id": "12168", + "maxAmount": "2" + } + ], + "ids": "2604,2605,2606,2607,2608,2609,7755", + "description": "", + "main": [ + { + "minAmount": "9", + "weight": "1.0", + "id": "6522", + "maxAmount": "29" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "6523", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "6525", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "6568", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1617", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1619", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "1621", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "16.0", + "id": "1623", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "20.0", + "id": "9194", + "maxAmount": "1" + }, + { + "minAmount": "100", + "weight": "160.0", + "id": "6529", + "maxAmount": "2000" + }, + { + "minAmount": "1", + "weight": "299.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "1", + "weight": "40.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "88.0", + "id": "12168", + "maxAmount": "2" + } + ], + "ids": "2610,2611,2612,2613,2614,2615,2616,2624,2625", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "6528", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "6524", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "6568", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1617", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1619", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "1621", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "16.0", + "id": "1623", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "20.0", + "id": "9194", + "maxAmount": "1" + }, + { + "minAmount": "100", + "weight": "160.0", + "id": "6529", + "maxAmount": "2000" + }, + { + "minAmount": "1", + "weight": "300.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "2698", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "1279", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1153", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1424", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1165", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "888", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1313", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1283", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1125", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1077", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "558", + "maxAmount": "9" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "557", + "maxAmount": "10" + }, + { + "minAmount": "9", + "weight": "25.0", + "id": "559", + "maxAmount": "9" + }, + { + "minAmount": "7", + "weight": "25.0", + "id": "564", + "maxAmount": "7" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "562", + "maxAmount": "6" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "560", + "maxAmount": "2" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "563", + "maxAmount": "4" + }, + { + "minAmount": "6", + "weight": "5.0", + "id": "561", + "maxAmount": "6" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "5318", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "5319", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "5.0", + "id": "5324", + "maxAmount": "4" + }, + { + "minAmount": "3", + "weight": "5.0", + "id": "5322", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "5.0", + "id": "5320", + "maxAmount": "3" + }, + { + "minAmount": "23", + "weight": "5.0", + "id": "5323", + "maxAmount": "23" + }, + { + "minAmount": "2", + "weight": "5.0", + "id": "5321", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "995", + "maxAmount": "500" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "2353", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1933", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2309", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "438", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "7518", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "2706,3421,3424,4346", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "7536", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "7538", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "407", + "maxAmount": "2" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "2707,2708,6115,6116", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "7889", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "592", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "2709", + "description": "", + "main": [ + { + "minAmount": "4", + "weight": "50.0", + "id": "554", + "maxAmount": "9" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1442", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "592", + "maxAmount": "1" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "555", + "maxAmount": "10" + } + ], + "charm": [], + "ids": "2710", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "5.0", + "id": "1444", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "555", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "592", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "2711", + "description": "", + "main": [ + { + "minAmount": "5", + "weight": "50.0", + "id": "557", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1440", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "592", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "2712", + "description": "", + "main": [ + { + "minAmount": "4", + "weight": "50.0", + "id": "556", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1438", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1381", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5527", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "592", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "2717", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "1391", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1013", + "maxAmount": "1" + }, + { + "minAmount": "7", + "weight": "50.0", + "id": "558", + "maxAmount": "9" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "562", + "maxAmount": "4" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "563", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "561", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "27", + "weight": "50.0", + "id": "995", + "maxAmount": "434" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1625", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1934", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2351", + "maxAmount": "2" + }, + { + "minAmount": "3", + "weight": "5.0", + "id": "532", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "532", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "64.7702", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.6684", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.3532", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.2923", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "13.9158", + "id": "12163", + "maxAmount": "1" + } + ], + "tertiary": [ + { + "minAmount": "1", + "weight": "9973.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "10976", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "10977", + "maxAmount": "1" + } + ], + "ids": "2783", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "16.0", + "id": "1313", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "12.0", + "id": "1367", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "1361", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1183", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1113", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1163", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "11235", + "maxAmount": "1" + }, + { + "minAmount": "47", + "weight": "32.0", + "id": "556", + "maxAmount": "47" + }, + { + "minAmount": "10", + "weight": "28.0", + "id": "562", + "maxAmount": "10" + }, + { + "minAmount": "3", + "weight": "20.0", + "id": "560", + "maxAmount": "3" + }, + { + "minAmount": "7", + "weight": "16.0", + "id": "565", + "maxAmount": "7" + }, + { + "minAmount": "5", + "weight": "4.0", + "id": "560", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "60.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "16.0", + "id": "14424", + "maxAmount": "2" + }, + { + "minAmount": "152", + "weight": "159.0", + "id": "995", + "maxAmount": "152" + }, + { + "minAmount": "64", + "weight": "24.0", + "id": "995", + "maxAmount": "64" + }, + { + "minAmount": "95", + "weight": "24.0", + "id": "995", + "maxAmount": "95" + }, + { + "minAmount": "220", + "weight": "20.0", + "id": "995", + "maxAmount": "220" + }, + { + "minAmount": "1", + "weight": "12.0", + "id": "385", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "2361", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1456", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "121", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "4.0", + "id": "385", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "12.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "12.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "2803", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "436", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "441", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2355", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "438", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "454", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "442", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "447", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "5322", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "5324", + "maxAmount": "3" + }, + { + "minAmount": "4", + "weight": "50.0", + "id": "5319", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "5318", + "maxAmount": "4" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "5323", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5321", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5320", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "554", + "maxAmount": "42" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "561", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "946", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "50.0", + "id": "1831", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1829", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1827", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1825", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1971", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "5.0", + "id": "1823", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "4115", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "10976", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "2804,2805,2806", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "436", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "441", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2355", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "438", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "454", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "442", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "447", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "5322", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "5324", + "maxAmount": "3" + }, + { + "minAmount": "4", + "weight": "50.0", + "id": "5319", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "5318", + "maxAmount": "4" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "5323", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5321", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5320", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "554", + "maxAmount": "42" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "561", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "946", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "50.0", + "id": "1831", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1829", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1827", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1825", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1971", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "5.0", + "id": "1823", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "4115", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "10976", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "2807,2808", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "436", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "441", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2355", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "438", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "454", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "442", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "447", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "5322", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "5324", + "maxAmount": "3" + }, + { + "minAmount": "4", + "weight": "50.0", + "id": "5319", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "5318", + "maxAmount": "4" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "5323", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5321", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5320", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "554", + "maxAmount": "42" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "561", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "946", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "50.0", + "id": "1831", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1829", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1827", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1825", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1971", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "5.0", + "id": "1823", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "4115", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "10976", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "2837,2838,2839,2840,2841,2842,5629,5630,5631,5632,5633,5634,5635,5636,5637,5638,5639,5640,5641,5642,5643,5644,5645,5646,5647,5648,5649,5650,5651,5652,5653,5654,5655,5656,5657,5658,5659,5660,5661,5662,5663,5664,5665", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1329", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1209", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "50.0", + "id": "9141", + "maxAmount": "2" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "556", + "maxAmount": "3" + }, + { + "minAmount": "23", + "weight": "25.0", + "id": "555", + "maxAmount": "23" + }, + { + "minAmount": "6", + "weight": "25.0", + "id": "559", + "maxAmount": "6" + }, + { + "minAmount": "7", + "weight": "25.0", + "id": "562", + "maxAmount": "7" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "564", + "maxAmount": "5" + }, + { + "minAmount": "2", + "weight": "5.0", + "id": "563", + "maxAmount": "2" + }, + { + "minAmount": "38", + "weight": "50.0", + "id": "995", + "maxAmount": "46" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "6716", + "maxAmount": "1" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "313", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "7157", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "6721", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "7863", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "2843,2844,2845,2846,2847,2848", + "description": "", + "main": [ + { + "minAmount": "17", + "weight": "25.0", + "id": "555", + "maxAmount": "17" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "564", + "maxAmount": "2" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "562", + "maxAmount": "4" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "559", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "556", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "7863", + "maxAmount": "1" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "995", + "maxAmount": "40" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "6716", + "maxAmount": "1" + }, + { + "minAmount": "7", + "weight": "50.0", + "id": "313", + "maxAmount": "7" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1325", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "6721", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "2850", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "213", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "2880", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "6729", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "6155", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "2881", + "description": "", + "main": [ + { + "minAmount": "25", + "weight": "10.0", + "id": "866", + "maxAmount": "50" + }, + { + "minAmount": "1", + "weight": "7.0", + "id": "2489", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "5.0", + "id": "805", + "maxAmount": "10" + }, + { + "minAmount": "10", + "weight": "5.0", + "id": "810", + "maxAmount": "25" + }, + { + "minAmount": "200", + "weight": "5.0", + "id": "863", + "maxAmount": "500" + }, + { + "minAmount": "50", + "weight": "5.0", + "id": "865", + "maxAmount": "150" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "3757", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "3748", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "3758", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "6724", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "6739", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "3749", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "6133", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "6135", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "6733", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "5.0", + "id": "9144", + "maxAmount": "12" + }, + { + "minAmount": "50", + "weight": "5.0", + "id": "886", + "maxAmount": "250" + }, + { + "minAmount": "200", + "weight": "4.0", + "id": "884", + "maxAmount": "500" + }, + { + "minAmount": "1", + "weight": "7.0", + "id": "14428", + "maxAmount": "1" + }, + { + "minAmount": "156", + "weight": "10.0", + "id": "995", + "maxAmount": "156" + }, + { + "minAmount": "1", + "weight": "6.0", + "id": "413", + "maxAmount": "1" + }, + { + "minAmount": "10", + "weight": "5.0", + "id": "45", + "maxAmount": "30" + }, + { + "minAmount": "5", + "weight": "5.0", + "id": "385", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "50", + "weight": "5.0", + "id": "1518", + "maxAmount": "150" + }, + { + "minAmount": "50", + "weight": "3.0", + "id": "1516", + "maxAmount": "150" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "9431", + "maxAmount": "1" + }, + { + "minAmount": "250", + "weight": "1.0", + "id": "314", + "maxAmount": "500" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "6729", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "6155", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "2882", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "10.0", + "id": "1399", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1395", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1397", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1392", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "3757", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "3748", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "3758", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "6562", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "6739", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "3755", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "6139", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "6141", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "6731", + "maxAmount": "1" + }, + { + "minAmount": "100", + "weight": "6.0", + "id": "556", + "maxAmount": "200" + }, + { + "minAmount": "50", + "weight": "5.0", + "id": "557", + "maxAmount": "100" + }, + { + "minAmount": "25", + "weight": "2.0", + "id": "565", + "maxAmount": "75" + }, + { + "minAmount": "25", + "weight": "2.0", + "id": "563", + "maxAmount": "75" + }, + { + "minAmount": "25", + "weight": "2.0", + "id": "561", + "maxAmount": "75" + }, + { + "minAmount": "25", + "weight": "2.0", + "id": "560", + "maxAmount": "75" + }, + { + "minAmount": "25", + "weight": "2.0", + "id": "4698", + "maxAmount": "75" + }, + { + "minAmount": "1", + "weight": "7.0", + "id": "14428", + "maxAmount": "1" + }, + { + "minAmount": "25", + "weight": "10.0", + "id": "1441", + "maxAmount": "75" + }, + { + "minAmount": "25", + "weight": "7.0", + "id": "1439", + "maxAmount": "75" + }, + { + "minAmount": "25", + "weight": "7.0", + "id": "1445", + "maxAmount": "75" + }, + { + "minAmount": "5", + "weight": "10.0", + "id": "385", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "413", + "maxAmount": "1" + }, + { + "minAmount": "150", + "weight": "5.0", + "id": "7937", + "maxAmount": "150" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "972", + "weight": "3.0", + "id": "995", + "maxAmount": "972" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "6729", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "6155", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "2883", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "17.0", + "id": "1193", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "11.0", + "id": "1343", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "7.0", + "id": "1357", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1119", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1273", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1123", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "3757", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1359", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "6739", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "3748", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "3758", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1315", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "2570", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "6129", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "6130", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "6737", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "6735", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "2456", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "141", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "129", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "147", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "165", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "191", + "maxAmount": "1" + }, + { + "minAmount": "25", + "weight": "10.0", + "id": "448", + "maxAmount": "25" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "2361", + "maxAmount": "1" + }, + { + "minAmount": "100", + "weight": "2.0", + "id": "454", + "maxAmount": "100" + }, + { + "minAmount": "150", + "weight": "1.0", + "id": "441", + "maxAmount": "150" + }, + { + "minAmount": "15", + "weight": "1.0", + "id": "2354", + "maxAmount": "30" + }, + { + "minAmount": "156", + "weight": "10.0", + "id": "995", + "maxAmount": "156" + }, + { + "minAmount": "1", + "weight": "7.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "7.0", + "id": "365", + "maxAmount": "5" + }, + { + "minAmount": "5", + "weight": "4.0", + "id": "373", + "maxAmount": "5" + }, + { + "minAmount": "5", + "weight": "1.0", + "id": "385", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "2", + "weight": "47.6638", + "id": "0", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "16.3926", + "id": "12158", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "8.9794", + "id": "12159", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "23.8319", + "id": "12160", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "3.1323", + "id": "12163", + "maxAmount": "2" + } + ], + "ids": "2889", + "description": "", + "main": [ + { + "minAmount": "5", + "weight": "50.0", + "id": "557", + "maxAmount": "5" + }, + { + "minAmount": "9", + "weight": "50.0", + "id": "555", + "maxAmount": "9" + }, + { + "minAmount": "4", + "weight": "50.0", + "id": "7936", + "maxAmount": "8" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1442", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1438", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1454", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1446", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1444", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "4", + "weight": "50.0", + "id": "886", + "maxAmount": "7" + }, + { + "minAmount": "2", + "weight": "50.0", + "id": "884", + "maxAmount": "17" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "3757", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5319", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5318", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5324", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5322", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5321", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "12148", + "maxAmount": "3" + }, + { + "minAmount": "4", + "weight": "50.0", + "id": "401", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "50.0", + "id": "403", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "377", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "301", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "590", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1781", + "maxAmount": "1" + }, + { + "minAmount": "355", + "weight": "25.0", + "id": "995", + "maxAmount": "355" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "231", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "6812", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "2", + "weight": "33.9281", + "id": "0", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "6.6641", + "id": "12158", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "3.3079", + "id": "12159", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "54.6051", + "id": "12160", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "1.4948", + "id": "12163", + "maxAmount": "2" + } + ], + "tertiary": [ + { + "minAmount": "1", + "weight": "9999.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "11286", + "maxAmount": "1" + } + ], + "ids": "3068,3069,3070,3071", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "16.0", + "id": "1283", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "1361", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "6324", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1399", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "6809", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "8.0", + "id": "8882", + "maxAmount": "12" + }, + { + "minAmount": "2", + "weight": "8.0", + "id": "9142", + "maxAmount": "12" + }, + { + "minAmount": "2", + "weight": "8.0", + "id": "9144", + "maxAmount": "12" + }, + { + "minAmount": "10", + "weight": "28.0", + "id": "566", + "maxAmount": "10" + }, + { + "minAmount": "30", + "weight": "16.0", + "id": "556", + "maxAmount": "30" + }, + { + "minAmount": "30", + "weight": "16.0", + "id": "555", + "maxAmount": "30" + }, + { + "minAmount": "7", + "weight": "16.0", + "id": "565", + "maxAmount": "7" + }, + { + "minAmount": "3", + "weight": "4.0", + "id": "563", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "48.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "16.0", + "id": "14422", + "maxAmount": "1" + }, + { + "minAmount": "132", + "weight": "139.0", + "id": "995", + "maxAmount": "132" + }, + { + "minAmount": "220", + "weight": "36.0", + "id": "995", + "maxAmount": "220" + }, + { + "minAmount": "30", + "weight": "28.0", + "id": "995", + "maxAmount": "30" + }, + { + "minAmount": "44", + "weight": "24.0", + "id": "995", + "maxAmount": "44" + }, + { + "minAmount": "460", + "weight": "4.0", + "id": "995", + "maxAmount": "460" + }, + { + "minAmount": "60", + "weight": "20.0", + "id": "7937", + "maxAmount": "60" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "9463", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "379", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1454", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1452", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "133", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "20.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "1", + "weight": "91.5619", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.7734", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.9766", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.4995", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.1886", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "3153", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "1157", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1353", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1387", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1109", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1145", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1313", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "4123", + "maxAmount": "1" + }, + { + "minAmount": "15", + "weight": "50.0", + "id": "562", + "maxAmount": "30" + }, + { + "minAmount": "20", + "weight": "50.0", + "id": "554", + "maxAmount": "90" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "560", + "maxAmount": "3" + }, + { + "minAmount": "30", + "weight": "50.0", + "id": "995", + "maxAmount": "30" + }, + { + "minAmount": "40", + "weight": "50.0", + "id": "995", + "maxAmount": "40" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "444", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "453", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1993", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "799", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "3200", + "description": "Chaos Elemental (Boss)", + "main": [ + { + "minAmount": "1", + "weight": "6.0", + "id": "7158", + "maxAmount": "1" + }, + { + "minAmount": "500", + "weight": "50.0", + "id": "556", + "maxAmount": "500" + }, + { + "minAmount": "50", + "weight": "25.0", + "id": "565", + "maxAmount": "50" + }, + { + "minAmount": "100", + "weight": "50.0", + "id": "562", + "maxAmount": "100" + }, + { + "minAmount": "50", + "weight": "25.0", + "id": "560", + "maxAmount": "50" + }, + { + "minAmount": "200", + "weight": "25.0", + "id": "892", + "maxAmount": "200" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "464", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "2446", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "187", + "maxAmount": "1" + }, + { + "minAmount": "300", + "weight": "150.0", + "id": "995", + "maxAmount": "300" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "6.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "400", + "weight": "50.0", + "id": "809", + "maxAmount": "400" + }, + { + "minAmount": "500", + "weight": "25.0", + "id": "884", + "maxAmount": "500" + }, + { + "minAmount": "1000", + "weight": "25.0", + "id": "884", + "maxAmount": "1000" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "592", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "83.9189", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "14.0681", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.081", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.7755", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.1567", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "3201,3202", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "1397", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1393", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1381", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1387", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1401", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "556", + "maxAmount": "17" + }, + { + "minAmount": "18", + "weight": "50.0", + "id": "554", + "maxAmount": "45" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "562", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "50.0", + "id": "561", + "maxAmount": "37" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "4694", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "560", + "maxAmount": "2" + }, + { + "minAmount": "11", + "weight": "50.0", + "id": "995", + "maxAmount": "200" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "2", + "maxAmount": "3" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "569", + "maxAmount": "2" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "1781", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "3222", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "2.0", + "id": "1139", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1203", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "22.0", + "id": "877", + "maxAmount": "12" + }, + { + "minAmount": "7", + "weight": "3.0", + "id": "882", + "maxAmount": "7" + }, + { + "minAmount": "4", + "weight": "2.0", + "id": "557", + "maxAmount": "4" + }, + { + "minAmount": "6", + "weight": "2.0", + "id": "554", + "maxAmount": "6" + }, + { + "minAmount": "9", + "weight": "2.0", + "id": "558", + "maxAmount": "9" + }, + { + "minAmount": "2", + "weight": "1.0", + "id": "562", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "23.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "37.0", + "id": "995", + "maxAmount": "3" + }, + { + "minAmount": "5", + "weight": "9.0", + "id": "995", + "maxAmount": "5" + }, + { + "minAmount": "15", + "weight": "4.0", + "id": "995", + "maxAmount": "15" + }, + { + "minAmount": "25", + "weight": "1.0", + "id": "995", + "maxAmount": "25" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "313", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "436", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1965", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "3237", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "2.0", + "id": "1139", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1203", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "22.0", + "id": "877", + "maxAmount": "12" + }, + { + "minAmount": "7", + "weight": "3.0", + "id": "882", + "maxAmount": "7" + }, + { + "minAmount": "4", + "weight": "2.0", + "id": "557", + "maxAmount": "4" + }, + { + "minAmount": "6", + "weight": "2.0", + "id": "554", + "maxAmount": "6" + }, + { + "minAmount": "9", + "weight": "2.0", + "id": "558", + "maxAmount": "9" + }, + { + "minAmount": "2", + "weight": "1.0", + "id": "562", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "23.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "37.0", + "id": "995", + "maxAmount": "3" + }, + { + "minAmount": "5", + "weight": "9.0", + "id": "995", + "maxAmount": "5" + }, + { + "minAmount": "15", + "weight": "4.0", + "id": "995", + "maxAmount": "15" + }, + { + "minAmount": "25", + "weight": "1.0", + "id": "995", + "maxAmount": "25" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "313", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "436", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1965", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "3238", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "2.0", + "id": "1139", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1203", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "22.0", + "id": "877", + "maxAmount": "12" + }, + { + "minAmount": "7", + "weight": "3.0", + "id": "882", + "maxAmount": "7" + }, + { + "minAmount": "4", + "weight": "2.0", + "id": "557", + "maxAmount": "4" + }, + { + "minAmount": "6", + "weight": "2.0", + "id": "554", + "maxAmount": "6" + }, + { + "minAmount": "9", + "weight": "2.0", + "id": "558", + "maxAmount": "9" + }, + { + "minAmount": "2", + "weight": "1.0", + "id": "562", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "23.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "37.0", + "id": "995", + "maxAmount": "3" + }, + { + "minAmount": "5", + "weight": "9.0", + "id": "995", + "maxAmount": "5" + }, + { + "minAmount": "15", + "weight": "4.0", + "id": "995", + "maxAmount": "15" + }, + { + "minAmount": "25", + "weight": "1.0", + "id": "995", + "maxAmount": "25" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "313", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "436", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1965", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "3239", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "2.0", + "id": "1139", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1203", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "22.0", + "id": "877", + "maxAmount": "12" + }, + { + "minAmount": "7", + "weight": "3.0", + "id": "882", + "maxAmount": "7" + }, + { + "minAmount": "4", + "weight": "2.0", + "id": "557", + "maxAmount": "4" + }, + { + "minAmount": "6", + "weight": "2.0", + "id": "554", + "maxAmount": "6" + }, + { + "minAmount": "9", + "weight": "2.0", + "id": "558", + "maxAmount": "9" + }, + { + "minAmount": "2", + "weight": "1.0", + "id": "562", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "23.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "37.0", + "id": "995", + "maxAmount": "3" + }, + { + "minAmount": "5", + "weight": "9.0", + "id": "995", + "maxAmount": "5" + }, + { + "minAmount": "15", + "weight": "4.0", + "id": "995", + "maxAmount": "15" + }, + { + "minAmount": "25", + "weight": "1.0", + "id": "995", + "maxAmount": "25" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "313", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "436", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1965", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "3240,5025,5048", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "2.0", + "id": "1139", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1203", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "22.0", + "id": "877", + "maxAmount": "12" + }, + { + "minAmount": "7", + "weight": "3.0", + "id": "882", + "maxAmount": "7" + }, + { + "minAmount": "4", + "weight": "2.0", + "id": "557", + "maxAmount": "4" + }, + { + "minAmount": "6", + "weight": "2.0", + "id": "554", + "maxAmount": "6" + }, + { + "minAmount": "9", + "weight": "2.0", + "id": "558", + "maxAmount": "9" + }, + { + "minAmount": "2", + "weight": "1.0", + "id": "562", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "23.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "37.0", + "id": "995", + "maxAmount": "3" + }, + { + "minAmount": "5", + "weight": "9.0", + "id": "995", + "maxAmount": "5" + }, + { + "minAmount": "15", + "weight": "4.0", + "id": "995", + "maxAmount": "15" + }, + { + "minAmount": "25", + "weight": "1.0", + "id": "995", + "maxAmount": "25" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "313", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "436", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1965", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "532", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "7416", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "7418", + "maxAmount": "3" + } + ], + "charm": [ + { + "minAmount": "2", + "weight": "71.1249", + "id": "0", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "8.5018", + "id": "12158", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "11.3012", + "id": "12159", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "6.4282", + "id": "12160", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "2.6439", + "id": "12163", + "maxAmount": "2" + } + ], + "ids": "3340", + "description": "", + "main": [ + { + "minAmount": "105", + "weight": "50.0", + "id": "556", + "maxAmount": "105" + }, + { + "minAmount": "105", + "weight": "50.0", + "id": "554", + "maxAmount": "105" + }, + { + "minAmount": "15", + "weight": "50.0", + "id": "565", + "maxAmount": "15" + }, + { + "minAmount": "7", + "weight": "50.0", + "id": "560", + "maxAmount": "7" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "563", + "maxAmount": "15" + }, + { + "minAmount": "690", + "weight": "25.0", + "id": "884", + "maxAmount": "690" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1301", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1355", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1369", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1121", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1147", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1725", + "maxAmount": "1" + }, + { + "minAmount": "100", + "weight": "25.0", + "id": "1516", + "maxAmount": "100" + }, + { + "minAmount": "1", + "weight": "6.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "6.0", + "id": "10976", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "6.0", + "id": "10977", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "100", + "weight": "25.0", + "id": "441", + "maxAmount": "100" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1315", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "2359", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "407", + "maxAmount": "1" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "385", + "maxAmount": "4" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "592", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "3346,3347", + "description": "", + "main": [ + { + "minAmount": "2", + "weight": "25.0", + "id": "561", + "maxAmount": "2" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "563", + "maxAmount": "50" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "557", + "maxAmount": "15" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5323", + "maxAmount": "6" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5305", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "5308", + "maxAmount": "3" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "5318", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5311", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5098", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5100", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "5322", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5105", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5104", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5106", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5296", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5299", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "5307", + "maxAmount": "3" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "5319", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "12176", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5309", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5306", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5295", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5321", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5096", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5099", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1353", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1311", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1163", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "7432", + "maxAmount": "1" + }, + { + "minAmount": "44", + "weight": "25.0", + "id": "995", + "maxAmount": "44" + }, + { + "minAmount": "64", + "weight": "25.0", + "id": "995", + "maxAmount": "64" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "6035", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2970", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "434", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "534", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "55.9766", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "9.1987", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "21.9199", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "11.0684", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.8364", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "3376", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "7.0", + "id": "145", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "55.9766", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "1", + "weight": "91.209", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.8008", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.9436", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.7576", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.289", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "3406,6217,7714,7715", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "111.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "555", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "556", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "995", + "maxAmount": "30" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "995", + "maxAmount": "20" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "532", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "12163", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5600.0", + "id": "0", + "maxAmount": "1" + } + ], + "ids": "3587", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "7844", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "10977", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "10976", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5323", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5298", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5281", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5301", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5280", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5294", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5297", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5104", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5100", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5106", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "12176", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5293", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5296", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5311", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5105", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5292", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5295", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5303", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5302", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5321", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5299", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "3697,3698,3699,3700,3701,3702,3703,3704,3705", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "5291", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5292", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5293", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5294", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5296", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "12176", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5295", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5297", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5298", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5299", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5300", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5301", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5302", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5303", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5304", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5104", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5106", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5280", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5321", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5105", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5100", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5323", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5311", + "maxAmount": "1" + }, + { + "minAmount": "60", + "weight": "50.0", + "id": "556", + "maxAmount": "60" + }, + { + "minAmount": "9", + "weight": "25.0", + "id": "562", + "maxAmount": "9" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "564", + "maxAmount": "4" + }, + { + "minAmount": "20", + "weight": "25.0", + "id": "555", + "maxAmount": "20" + }, + { + "minAmount": "2", + "weight": "5.0", + "id": "563", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1361", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1141", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1281", + "maxAmount": "1" + }, + { + "minAmount": "8", + "weight": "25.0", + "id": "888", + "maxAmount": "8" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1329", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1265", + "maxAmount": "1" + }, + { + "minAmount": "20", + "weight": "50.0", + "id": "995", + "maxAmount": "20" + }, + { + "minAmount": "50", + "weight": "50.0", + "id": "995", + "maxAmount": "50" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2359", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "3706,3710", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "2134", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "73.7201", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "22.7431", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.6213", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.4998", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.4157", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "3707", + "description": "", + "main": [ + { + "minAmount": "10", + "weight": "25.0", + "id": "378", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "383", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "384", + "maxAmount": "3" + }, + { + "minAmount": "8", + "weight": "25.0", + "id": "384", + "maxAmount": "8" + }, + { + "minAmount": "18", + "weight": "25.0", + "id": "350", + "maxAmount": "18" + }, + { + "minAmount": "9", + "weight": "25.0", + "id": "372", + "maxAmount": "9" + }, + { + "minAmount": "18", + "weight": "5.0", + "id": "2135", + "maxAmount": "18" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "557", + "maxAmount": "10" + }, + { + "minAmount": "18", + "weight": "50.0", + "id": "557", + "maxAmount": "18" + }, + { + "minAmount": "7", + "weight": "50.0", + "id": "560", + "maxAmount": "7" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "555", + "maxAmount": "10" + }, + { + "minAmount": "18", + "weight": "25.0", + "id": "555", + "maxAmount": "18" + }, + { + "minAmount": "18", + "weight": "25.0", + "id": "556", + "maxAmount": "18" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "565", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "995", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "50.0", + "id": "995", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1444", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "11037", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "532", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "100.0", + "id": "526", + "maxAmount": "3" + } + ], + "charm": [], + "ids": "3808,3819", + "description": "", + "main": [ + { + "minAmount": "10", + "weight": "50.0", + "id": "5324", + "maxAmount": "29" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5101", + "maxAmount": "1" + }, + { + "minAmount": "4", + "weight": "5.0", + "id": "5318", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "5.0", + "id": "5319", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5322", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5321", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5096", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5097", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5099", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5103", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5308", + "maxAmount": "3" + }, + { + "minAmount": "2", + "weight": "5.0", + "id": "5305", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5323", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5098", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5309", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5307", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5320", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "2150", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "2114", + "maxAmount": "1" + }, + { + "minAmount": "16", + "weight": "50.0", + "id": "1968", + "maxAmount": "101" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2253", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2064", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2187", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1458", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "561", + "maxAmount": "3" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "557", + "maxAmount": "14" + }, + { + "minAmount": "5", + "weight": "5.0", + "id": "566", + "maxAmount": "11" + }, + { + "minAmount": "12", + "weight": "50.0", + "id": "886", + "maxAmount": "23" + }, + { + "minAmount": "6", + "weight": "25.0", + "id": "888", + "maxAmount": "13" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "7939", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "10995", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "10977", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "10976", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "6333", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "6332", + "maxAmount": "4" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "3815", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "532", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "3939", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "8.0", + "id": "5100", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5311", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5323", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5321", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5105", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5104", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5281", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5106", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5291", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5292", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5293", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5294", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5295", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "12176", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5296", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5297", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5298", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5299", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5300", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5301", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5302", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5303", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5304", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "4695", + "maxAmount": "1" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "555", + "maxAmount": "15" + }, + { + "minAmount": "22", + "weight": "100.0", + "id": "995", + "maxAmount": "44" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "405", + "maxAmount": "1" + }, + { + "minAmount": "50", + "weight": "50.0", + "id": "313", + "maxAmount": "50" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "571", + "maxAmount": "1" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "402", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "404", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "377", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "363", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "411", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "50.0", + "id": "823", + "maxAmount": "2" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "46", + "maxAmount": "3" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "4160", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "3940", + "description": "", + "main": [ + { + "minAmount": "4", + "weight": "25.0", + "id": "4160", + "maxAmount": "5" + }, + { + "minAmount": "2", + "weight": "50.0", + "id": "823", + "maxAmount": "2" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "46", + "maxAmount": "3" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "555", + "maxAmount": "15" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "4695", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "363", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "377", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "403", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "401", + "maxAmount": "5" + }, + { + "minAmount": "50", + "weight": "50.0", + "id": "313", + "maxAmount": "50" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "571", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "411", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "405", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5301", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5100", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5105", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5104", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5299", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5311", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5294", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5295", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5323", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5300", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5296", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "12176", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5103", + "maxAmount": "1" + }, + { + "minAmount": "21", + "weight": "50.0", + "id": "995", + "maxAmount": "21" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "44", + "weight": "50.0", + "id": "995", + "maxAmount": "44" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "532", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "7959", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "3943", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "8.0", + "id": "5321", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5106", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5291", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5292", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5293", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5294", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5296", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5295", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5297", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5298", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5299", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5300", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5301", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5302", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5303", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5304", + "maxAmount": "1" + }, + { + "minAmount": "22", + "weight": "100.0", + "id": "995", + "maxAmount": "44" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "10976", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "50.0", + "id": "823", + "maxAmount": "2" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "46", + "maxAmount": "3" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "4160", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "571", + "maxAmount": "1" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "555", + "maxAmount": "15" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "4695", + "maxAmount": "1" + }, + { + "minAmount": "50", + "weight": "50.0", + "id": "313", + "maxAmount": "50" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "363", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "377", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "405", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "411", + "maxAmount": "2" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "12163", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5600.0", + "id": "0", + "maxAmount": "1" + } + ], + "ids": "4226", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "1059", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2902", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2922", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2912", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2942", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "3799", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "4155", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1635", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1637", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1639", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1641", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "995", + "maxAmount": "442" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "592", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "4327", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "882", + "maxAmount": "20" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1351", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1265", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1349", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1267", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "886", + "maxAmount": "20" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1353", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1269", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1129", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "50.0", + "id": "995", + "maxAmount": "21" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "319", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "2138", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "50.0", + "id": "314", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1734", + "maxAmount": "6" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1511", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1625", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "686", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "697", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1627", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "688", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "453", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1739", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "81.7721", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.6723", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "12.4324", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.6996", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.4235", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "4348,4349,4350,4351,4352", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "1335", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "826", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1191", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1239", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "50.0", + "id": "561", + "maxAmount": "6" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "560", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5318", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5319", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5324", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5322", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5320", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5323", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "12148", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5321", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "441", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "6334", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "6332", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "2115", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "526", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "532", + "maxAmount": "3" + }, + { + "minAmount": "4", + "weight": "5.0", + "id": "8778", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "532", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "78.7882", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.6555", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.1922", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "13.8093", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.5548", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "4353,4354,4355,4356,4357", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "1355", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1197", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1161", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.73581", + "id": "8901", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5281", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5324", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5296", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5318", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5297", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5319", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5299", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "5106", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5300", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5280", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5301", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "12148", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5323", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5320", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5298", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5322", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "5321", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "5302", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "5303", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "5304", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "561", + "maxAmount": "3" + }, + { + "minAmount": "50", + "weight": "25.0", + "id": "554", + "maxAmount": "50" + }, + { + "minAmount": "44", + "weight": "25.0", + "id": "995", + "maxAmount": "44" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "225", + "maxAmount": "1" + }, + { + "minAmount": "4", + "weight": "50.0", + "id": "6334", + "maxAmount": "4" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "6332", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "12.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "10976", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "10977", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "561", + "maxAmount": "4" + }, + { + "minAmount": "6", + "weight": "25.0", + "id": "561", + "maxAmount": "6" + }, + { + "minAmount": "132", + "weight": "25.0", + "id": "995", + "maxAmount": "132" + }, + { + "minAmount": "440", + "weight": "25.0", + "id": "995", + "maxAmount": "440" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "72.1599", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "23.6015", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.6356", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.2041", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.3988", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "4381,4382,4383", + "description": "", + "main": [ + { + "minAmount": "5", + "weight": "25.0", + "id": "890", + "maxAmount": "25" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1391", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "869", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "565", + "maxAmount": "11" + }, + { + "minAmount": "2", + "weight": "50.0", + "id": "563", + "maxAmount": "2" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "560", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5281", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5280", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5297", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5299", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5100", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5292", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5106", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5323", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5293", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5296", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5105", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5294", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5098", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5298", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5303", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5104", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5321", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5311", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "12176", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5295", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5302", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "365", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "7082", + "maxAmount": "1" + }, + { + "minAmount": "8", + "weight": "50.0", + "id": "995", + "maxAmount": "500" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "1437", + "maxAmount": "15" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "7937", + "maxAmount": "15" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "448", + "maxAmount": "14" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "187", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "9008", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1442", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "72.1599", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "1", + "weight": "88.929", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.1142", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.9575", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.7357", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.2637", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "4389,4390,4391", + "description": "", + "main": [ + { + "minAmount": "3", + "weight": "50.0", + "id": "559", + "maxAmount": "12" + }, + { + "minAmount": "2", + "weight": "50.0", + "id": "4696", + "maxAmount": "23" + }, + { + "minAmount": "42", + "weight": "50.0", + "id": "554", + "maxAmount": "42" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "561", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "995", + "maxAmount": "499" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "441", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "592", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "9011", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2355", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1165", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "88.929", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "76.9587", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "19.0203", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.3723", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.3297", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.3191", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "4397,4398,4399", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "1145", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "888", + "maxAmount": "17" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "890", + "maxAmount": "14" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1165", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "333", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "329", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "373", + "maxAmount": "1" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "1437", + "maxAmount": "15" + }, + { + "minAmount": "30", + "weight": "25.0", + "id": "1437", + "maxAmount": "30" + }, + { + "minAmount": "7", + "weight": "50.0", + "id": "555", + "maxAmount": "7" + }, + { + "minAmount": "15", + "weight": "50.0", + "id": "7937", + "maxAmount": "15" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "554", + "maxAmount": "15" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "564", + "maxAmount": "4" + }, + { + "minAmount": "7", + "weight": "25.0", + "id": "562", + "maxAmount": "7" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "563", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5318", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "5318", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5319", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "5324", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5322", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5320", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5323", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "12148", + "maxAmount": "3" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "12148", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "14", + "weight": "50.0", + "id": "995", + "maxAmount": "221" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "221", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "596", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "5.0", + "id": "454", + "maxAmount": "7" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "9010", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "76.9587", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "4404,4405,4406", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "1155", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "884", + "maxAmount": "20" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "869", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1205", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "882", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1237", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1381", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "439", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "437", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "7937", + "maxAmount": "15" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "1437", + "maxAmount": "30" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2357", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "995", + "maxAmount": "469" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "558", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "555", + "maxAmount": "5" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "557", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "9007", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2142", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1442", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "532", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "14426", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "2.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "9016", + "maxAmount": "1" + } + ], + "ids": "4418,6218", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "4.0", + "id": "1069", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "3192", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1309", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "802", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "803", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "5670", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1365", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1083", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1113", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "16.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "27", + "weight": "5.0", + "id": "995", + "maxAmount": "27" + }, + { + "minAmount": "97", + "weight": "5.0", + "id": "995", + "maxAmount": "97" + }, + { + "minAmount": "104", + "weight": "29.0", + "id": "995", + "maxAmount": "104" + }, + { + "minAmount": "132", + "weight": "25.0", + "id": "995", + "maxAmount": "132" + }, + { + "minAmount": "286", + "weight": "10.0", + "id": "995", + "maxAmount": "286" + }, + { + "minAmount": "475", + "weight": "8.0", + "id": "995", + "maxAmount": "475" + }, + { + "minAmount": "4", + "weight": "2.0", + "id": "5625", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "2570", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "14426", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "4456,4457,4458,4459,6271,6272,6273,6274", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "1205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1307", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "3190", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1321", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1279", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1309", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1375", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "807", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1155", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1075", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1139", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1101", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1141", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "946", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5105", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "532", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "9080", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "64.8102", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "14.0533", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "7.8289", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.9381", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "7.3696", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "4527,4528,4529,4530,4531,4532,4533", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "5.0", + "id": "10976", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "10977", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "9079", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.12595", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "325", + "weight": "5.0", + "id": "995", + "maxAmount": "400" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "4546", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "1025", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "4577", + "description": "", + "main": [ + { + "minAmount": "3", + "weight": "25.0", + "id": "2998", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "3000", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "751", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "9469", + "maxAmount": "10" + }, + { + "minAmount": "8", + "weight": "25.0", + "id": "9475", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "4605", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "985", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "987", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5075", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "4585", + "description": "", + "main": [ + { + "minAmount": "10", + "weight": "25.0", + "id": "564", + "maxAmount": "19" + }, + { + "minAmount": "16", + "weight": "25.0", + "id": "562", + "maxAmount": "27" + }, + { + "minAmount": "9", + "weight": "25.0", + "id": "561", + "maxAmount": "15" + }, + { + "minAmount": "7", + "weight": "25.0", + "id": "563", + "maxAmount": "18" + }, + { + "minAmount": "7", + "weight": "25.0", + "id": "560", + "maxAmount": "13" + }, + { + "minAmount": "6", + "weight": "25.0", + "id": "565", + "maxAmount": "10" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "566", + "maxAmount": "11" + }, + { + "minAmount": "51", + "weight": "25.0", + "id": "7936", + "maxAmount": "97" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1624", + "maxAmount": "16" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "1622", + "maxAmount": "5" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "1620", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1617", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "2998", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "3000", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "751", + "maxAmount": "1" + }, + { + "minAmount": "8", + "weight": "25.0", + "id": "9469", + "maxAmount": "15" + }, + { + "minAmount": "8", + "weight": "25.0", + "id": "9475", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "985", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "13157", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "92.3056", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.118", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.9651", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0295", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.5818", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "4805,4806,4807,4808,4813,4814,4815,4816,4817,4818,4819,4820,4821,4822,4823,4824,4825,4826,4827,4828,4829,4830,4831,4832,4833,4834,4835,4836,4837,4838,4839,4840,4841,4842,4843,4844,4849,4850,4851,4852,7606,7607,7608,7609,7614,7615,7616,7617,7618,7619,7620,7621,7622,7623,7624,7625,7626,7627,7628,7629,7630,7631,7632,7633,7634,7635,7682,7683,7684,7685,7691,7692,7693,7694,7695,7696,7697,7698,7699,7700,7701,7702,7703,7704,7705,7706", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "560", + "maxAmount": "25" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "565", + "maxAmount": "15" + }, + { + "minAmount": "80", + "weight": "50.0", + "id": "554", + "maxAmount": "80" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "200", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "202", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "206", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "204", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "208", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "212", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "210", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "216", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "214", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "218", + "maxAmount": "4" + }, + { + "minAmount": "100", + "weight": "50.0", + "id": "995", + "maxAmount": "1240" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "3385", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "3387", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "9735", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "4930,4931,4933,4934", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "9735", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "4932,4935", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "10129", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "5088", + "description": "", + "main": [] + }, + { + "default": [], + "charm": [], + "ids": "5116", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "5250,5254", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "1197", + "maxAmount": "1" + }, + { + "minAmount": "16", + "weight": "25.0", + "id": "890", + "maxAmount": "16" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1391", + "maxAmount": "1" + }, + { + "minAmount": "7", + "weight": "5.0", + "id": "892", + "maxAmount": "8" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1432", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1319", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1185", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1249", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "565", + "maxAmount": "5" + }, + { + "minAmount": "37", + "weight": "25.0", + "id": "554", + "maxAmount": "37" + }, + { + "minAmount": "3", + "weight": "5.0", + "id": "564", + "maxAmount": "3" + }, + { + "minAmount": "20", + "weight": "5.0", + "id": "4699", + "maxAmount": "20" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "995", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "9735", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "379", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "365", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "363", + "maxAmount": "1" + }, + { + "minAmount": "7", + "weight": "5.0", + "id": "10143", + "maxAmount": "7" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "68.3486", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.1284", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0459", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "22.0183", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.4587", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "5251,5252,5255,5256", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "1197", + "maxAmount": "1" + }, + { + "minAmount": "16", + "weight": "25.0", + "id": "890", + "maxAmount": "16" + }, + { + "minAmount": "7", + "weight": "25.0", + "id": "892", + "maxAmount": "7" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1333", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1432", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1391", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1319", + "maxAmount": "1" + }, + { + "minAmount": "20", + "weight": "25.0", + "id": "4699", + "maxAmount": "20" + }, + { + "minAmount": "37", + "weight": "25.0", + "id": "554", + "maxAmount": "37" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "565", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "60", + "weight": "50.0", + "id": "995", + "maxAmount": "302" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "363", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "365", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "5.0", + "id": "9738", + "maxAmount": "3" + }, + { + "minAmount": "6", + "weight": "5.0", + "id": "10143", + "maxAmount": "6" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "555", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "4.9106", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "9.3881", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.7939", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "78.8777", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0297", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "5361", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "6.0", + "id": "1383", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1395", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1111", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1343", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "9418", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1147", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "2487", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1123", + "maxAmount": "1" + }, + { + "minAmount": "90", + "weight": "8.0", + "id": "888", + "maxAmount": "90" + }, + { + "minAmount": "90", + "weight": "6.0", + "id": "555", + "maxAmount": "90" + }, + { + "minAmount": "15", + "weight": "5.0", + "id": "9337", + "maxAmount": "15" + }, + { + "minAmount": "9", + "weight": "5.0", + "id": "560", + "maxAmount": "19" + }, + { + "minAmount": "4", + "weight": "3.0", + "id": "565", + "maxAmount": "12" + }, + { + "minAmount": "3", + "weight": "2.0", + "id": "4695", + "maxAmount": "10" + }, + { + "minAmount": "3", + "weight": "2.0", + "id": "4698", + "maxAmount": "10" + }, + { + "minAmount": "3", + "weight": "1.0", + "id": "4694", + "maxAmount": "10" + }, + { + "minAmount": "2", + "weight": "9.0", + "id": "14424", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "14422", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "5321", + "maxAmount": "9" + }, + { + "minAmount": "96", + "weight": "10.0", + "id": "995", + "maxAmount": "696" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "448", + "maxAmount": "5" + }, + { + "minAmount": "3", + "weight": "1.0", + "id": "2354", + "maxAmount": "3" + }, + { + "minAmount": "2", + "weight": "2.0", + "id": "2359", + "maxAmount": "2" + }, + { + "minAmount": "5", + "weight": "8.0", + "id": "572", + "maxAmount": "10" + }, + { + "minAmount": "5", + "weight": "4.0", + "id": "228", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1444", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "3.0", + "id": "377", + "maxAmount": "12" + }, + { + "minAmount": "3", + "weight": "3.0", + "id": "383", + "maxAmount": "6" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "385", + "maxAmount": "1" + }, + { + "minAmount": "20", + "weight": "2.0", + "id": "232", + "maxAmount": "20" + }, + { + "minAmount": "10", + "weight": "2.0", + "id": "402", + "maxAmount": "30" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "407", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "6667", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "1624", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "5295", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "536", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "100.0", + "id": "1753", + "maxAmount": "2" + } + ], + "charm": [ + { + "minAmount": "2", + "weight": "63.6081", + "id": "0", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "14.93", + "id": "12158", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "12.4417", + "id": "12159", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "7.6205", + "id": "12160", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "1.3997", + "id": "12163", + "maxAmount": "2" + } + ], + "ids": "5362", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "11373", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1317", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1319", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1373", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1305", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1145", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1113", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1163", + "maxAmount": "1" + }, + { + "minAmount": "15", + "weight": "50.0", + "id": "565", + "maxAmount": "20" + }, + { + "minAmount": "35", + "weight": "50.0", + "id": "4699", + "maxAmount": "35" + }, + { + "minAmount": "37", + "weight": "25.0", + "id": "4694", + "maxAmount": "37" + }, + { + "minAmount": "17", + "weight": "25.0", + "id": "561", + "maxAmount": "17" + }, + { + "minAmount": "34", + "weight": "25.0", + "id": "556", + "maxAmount": "34" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "563", + "maxAmount": "15" + }, + { + "minAmount": "45", + "weight": "25.0", + "id": "563", + "maxAmount": "45" + }, + { + "minAmount": "8", + "weight": "25.0", + "id": "890", + "maxAmount": "8" + }, + { + "minAmount": "8", + "weight": "25.0", + "id": "805", + "maxAmount": "8" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "829", + "maxAmount": "1" + }, + { + "minAmount": "8", + "weight": "25.0", + "id": "867", + "maxAmount": "8" + }, + { + "minAmount": "90", + "weight": "5.0", + "id": "888", + "maxAmount": "90" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "995", + "maxAmount": "1813" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "448", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2011", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "536", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "100.0", + "id": "2359", + "maxAmount": "3" + } + ], + "charm": [ + { + "minAmount": "4", + "weight": "9.0422", + "id": "0", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "19.2257", + "id": "12158", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "48.7929", + "id": "12159", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "19.3398", + "id": "12160", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "3.5993", + "id": "12163", + "maxAmount": "4" + } + ], + "ids": "5363", + "description": "", + "main": [ + { + "minAmount": "20", + "weight": "8.0", + "id": "810", + "maxAmount": "20" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1373", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1432", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1147", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1163", + "maxAmount": "1" + }, + { + "minAmount": "14", + "weight": "50.0", + "id": "811", + "maxAmount": "14" + }, + { + "minAmount": "8", + "weight": "50.0", + "id": "830", + "maxAmount": "12" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "9144", + "maxAmount": "27" + }, + { + "minAmount": "8", + "weight": "25.0", + "id": "868", + "maxAmount": "18" + }, + { + "minAmount": "8", + "weight": "25.0", + "id": "892", + "maxAmount": "8" + }, + { + "minAmount": "27", + "weight": "25.0", + "id": "565", + "maxAmount": "27" + }, + { + "minAmount": "10", + "weight": "8.0", + "id": "566", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11429", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11443", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11457", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11465", + "maxAmount": "1" + }, + { + "minAmount": "600", + "weight": "75.0", + "id": "995", + "maxAmount": "3000" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "385", + "maxAmount": "6" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11359", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11338", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "8.0", + "id": "2363", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.07570993", + "id": "11286", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.0236593552", + "id": "11335", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "952", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "85.7316", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "7.7699", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0161", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.4329", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0494", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "5414", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "532", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "12163", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5600.0", + "id": "0", + "maxAmount": "1" + } + ], + "ids": "5415,5416", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "1365", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1243", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1355", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1069", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "10589", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1161", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1197", + "maxAmount": "1" + }, + { + "minAmount": "75", + "weight": "50.0", + "id": "555", + "maxAmount": "75" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "563", + "maxAmount": "3" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "561", + "maxAmount": "15" + }, + { + "minAmount": "37", + "weight": "25.0", + "id": "554", + "maxAmount": "37" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "44", + "weight": "50.0", + "id": "995", + "maxAmount": "200" + }, + { + "minAmount": "440", + "weight": "50.0", + "id": "995", + "maxAmount": "440" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "449", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "365", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "10976", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "10977", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "532", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "71.375", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "9.5708", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "7.381", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.4093", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.2638", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "5417,5418", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "1365", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1243", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1355", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1069", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "10589", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1161", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1197", + "maxAmount": "1" + }, + { + "minAmount": "75", + "weight": "50.0", + "id": "555", + "maxAmount": "75" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "563", + "maxAmount": "3" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "561", + "maxAmount": "15" + }, + { + "minAmount": "37", + "weight": "25.0", + "id": "554", + "maxAmount": "37" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "44", + "weight": "50.0", + "id": "995", + "maxAmount": "200" + }, + { + "minAmount": "440", + "weight": "50.0", + "id": "995", + "maxAmount": "440" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "449", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "365", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "10976", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "10977", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "532", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "5473,5521,5525,5474,5522,5526,5475,5523,5527", + "description": "first 3: ice troll runt, next 3: ice troll male, last 3: ice troll female", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "1119", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1339", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1141", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1341", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1181", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "1161", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "1357", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "1145", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "1345", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "1201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "1347", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "3122", + "maxAmount": "1" + }, + { + "minAmount": "8", + "weight": "50.0", + "id": "557", + "maxAmount": "60" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "561", + "maxAmount": "8" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "563", + "maxAmount": "8" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "384", + "maxAmount": "8" + }, + { + "minAmount": "4", + "weight": "50.0", + "id": "402", + "maxAmount": "10" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "454", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "354", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1760", + "maxAmount": "42" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5100", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5323", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5292", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5104", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5293", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5311", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5321", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5294", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5295", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5105", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5282", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5296", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5281", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5297", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5106", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5298", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5280", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5299", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "3138", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5300", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5301", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5302", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5303", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5304", + "maxAmount": "1" + }, + { + "minAmount": "35", + "weight": "100.0", + "id": "995", + "maxAmount": "350" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "10976", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "10977", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "532", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "5476,5524,5528", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "0.15", + "id": "1201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1161", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1181", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1121", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.098", + "id": "1347", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1341", + "maxAmount": "1" + }, + { + "minAmount": "8", + "weight": "1.0", + "id": "557", + "maxAmount": "36" + }, + { + "minAmount": "12", + "weight": "0.65", + "id": "563", + "maxAmount": "12" + }, + { + "minAmount": "7", + "weight": "0.65", + "id": "561", + "maxAmount": "7" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "5104", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "5100", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.038", + "id": "5295", + "maxAmount": "1" + }, + { + "minAmount": "6", + "weight": "1.0", + "id": "454", + "maxAmount": "6" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1759", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "1.0", + "id": "353", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "0.098", + "id": "3122", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "201", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "10818", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "10814", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "10816", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "5529", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "100.0", + "id": "5001", + "maxAmount": "10" + } + ], + "charm": [], + "ids": "5593", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "10877", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "10859", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "10976", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "10977", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "100.0", + "id": "223", + "maxAmount": "7" + } + ], + "charm": [], + "ids": "5594", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "10879", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "10859", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + }, + { + "minAmount": "10", + "weight": "100.0", + "id": "314", + "maxAmount": "40" + }, + { + "minAmount": "100", + "weight": "100.0", + "id": "314", + "maxAmount": "100" + } + ], + "charm": [], + "ids": "5595", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "10859", + "maxAmount": "1" + }, + { + "minAmount": "4", + "weight": "5.0", + "id": "2138", + "maxAmount": "4" + }, + { + "minAmount": "8", + "weight": "5.0", + "id": "2138", + "maxAmount": "8" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "10880", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "100.0", + "id": "7566", + "maxAmount": "7" + } + ], + "charm": [], + "ids": "5596", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "10881", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "10859", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "221", + "maxAmount": "4" + }, + { + "minAmount": "6", + "weight": "100.0", + "id": "221", + "maxAmount": "6" + } + ], + "charm": [], + "ids": "5597", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "10882", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "10859", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "100.0", + "id": "237", + "maxAmount": "4" + } + ], + "charm": [], + "ids": "5603", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "10878", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "10859", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "5627,5628", + "description": "", + "main": [ + { + "minAmount": "2", + "weight": "50.0", + "id": "9141", + "maxAmount": "6" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1329", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "23", + "weight": "50.0", + "id": "555", + "maxAmount": "23" + }, + { + "minAmount": "6", + "weight": "50.0", + "id": "559", + "maxAmount": "6" + }, + { + "minAmount": "7", + "weight": "25.0", + "id": "562", + "maxAmount": "7" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "564", + "maxAmount": "5" + }, + { + "minAmount": "2", + "weight": "5.0", + "id": "563", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "7863", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "7157", + "maxAmount": "1" + }, + { + "minAmount": "30", + "weight": "50.0", + "id": "995", + "maxAmount": "65" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1025", + "maxAmount": "1" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "313", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "987", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "985", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1623", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1621", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1619", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1617", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "5751", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "557", + "maxAmount": "20" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "555", + "maxAmount": "13" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "4698", + "maxAmount": "15" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "564", + "maxAmount": "7" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "561", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "10978", + "maxAmount": "8" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "995", + "maxAmount": "444" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "7416", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2714", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5733", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "11008", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "5842,5843,5844,5845,5846,5847,5848,5849,5850,5851", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "9", + "weight": "25.0", + "id": "558", + "maxAmount": "9" + }, + { + "minAmount": "6", + "weight": "25.0", + "id": "555", + "maxAmount": "6" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "557", + "maxAmount": "5" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "995", + "maxAmount": "5" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "995", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "954", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1139", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "313", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "436", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1965", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "946", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "5859", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "5860", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "5.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "11205", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "5993", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "203", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "557", + "maxAmount": "3" + }, + { + "minAmount": "11", + "weight": "25.0", + "id": "555", + "maxAmount": "11" + }, + { + "minAmount": "11", + "weight": "25.0", + "id": "562", + "maxAmount": "11" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "561", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1407", + "maxAmount": "1" + }, + { + "minAmount": "57", + "weight": "25.0", + "id": "995", + "maxAmount": "57" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1385", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "7416", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "7893", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "2", + "weight": "100.0", + "id": "532", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "11210", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "5996", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "5331", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "10976", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "6053,6063", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "6328", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "3385", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "3391", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1113", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "3101", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1333", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1347", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "6313", + "maxAmount": "1" + }, + { + "minAmount": "70", + "weight": "50.0", + "id": "892", + "maxAmount": "70" + }, + { + "minAmount": "70", + "weight": "50.0", + "id": "811", + "maxAmount": "70" + }, + { + "minAmount": "40", + "weight": "50.0", + "id": "868", + "maxAmount": "40" + }, + { + "minAmount": "50", + "weight": "50.0", + "id": "805", + "maxAmount": "50" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "9342", + "maxAmount": "2" + }, + { + "minAmount": "4", + "weight": "5.0", + "id": "9194", + "maxAmount": "4" + }, + { + "minAmount": "1016", + "weight": "50.0", + "id": "1747", + "maxAmount": "1016" + }, + { + "minAmount": "4", + "weight": "50.0", + "id": "140", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "5938", + "maxAmount": "4" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "6155", + "maxAmount": "3" + }, + { + "minAmount": "4", + "weight": "5.0", + "id": "2364", + "maxAmount": "4" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "6054,6064", + "description": "", + "main": [ + { + "minAmount": "2", + "weight": "5.0", + "id": "1705", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5547", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "5.0", + "id": "1703", + "maxAmount": "3" + }, + { + "minAmount": "100", + "weight": "50.0", + "id": "11212", + "maxAmount": "500" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "9341", + "maxAmount": "40" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1305", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "1215", + "maxAmount": "3" + }, + { + "minAmount": "105", + "weight": "25.0", + "id": "11230", + "maxAmount": "350" + }, + { + "minAmount": "105", + "weight": "50.0", + "id": "11232", + "maxAmount": "350" + }, + { + "minAmount": "100", + "weight": "50.0", + "id": "11237", + "maxAmount": "500" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "9193", + "maxAmount": "49" + }, + { + "minAmount": "111", + "weight": "50.0", + "id": "535", + "maxAmount": "297" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5316", + "maxAmount": "1" + }, + { + "minAmount": "52", + "weight": "25.0", + "id": "537", + "maxAmount": "99" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "1616", + "maxAmount": "6" + }, + { + "minAmount": "6", + "weight": "5.0", + "id": "5300", + "maxAmount": "6" + }, + { + "minAmount": "5", + "weight": "5.0", + "id": "7219", + "maxAmount": "15" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "6103", + "description": "", + "main": [ + { + "minAmount": "323", + "weight": "50.0", + "id": "995", + "maxAmount": "323" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "444", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "2357", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1515", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1391", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1325", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "11371", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1333", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11359", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "6104", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "5.0", + "id": "1371", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1391", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1081", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1191", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1143", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1181", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1333", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1157", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "11371", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1193", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1295", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1424", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1325", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "857", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "890", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "565", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "560", + "maxAmount": "5" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "9419", + "maxAmount": "2" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "9145", + "maxAmount": "5" + }, + { + "minAmount": "20", + "weight": "50.0", + "id": "886", + "maxAmount": "20" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "808", + "maxAmount": "10" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "865", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2361", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "2357", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "444", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "2356", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "2354", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "11443", + "maxAmount": "1" + }, + { + "minAmount": "106", + "weight": "50.0", + "id": "995", + "maxAmount": "106" + }, + { + "minAmount": "142", + "weight": "50.0", + "id": "995", + "maxAmount": "142" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11359", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "11337", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1637", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1619", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1515", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "6105", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "995", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1515", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1637", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1191", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1081", + "maxAmount": "1" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "865", + "maxAmount": "10" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "2354", + "maxAmount": "3" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "9145", + "maxAmount": "5" + }, + { + "minAmount": "2", + "weight": "5.0", + "id": "9419", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "11443", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "2356", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "857", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1333", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2361", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2357", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "444", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "5.0", + "id": "890", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11371", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1373", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1391", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "11359", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "6106", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "5.0", + "id": "1333", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1181", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1391", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "106", + "weight": "50.0", + "id": "995", + "maxAmount": "142" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "2356", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "2354", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "444", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "9419", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11359", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "6107", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "1295", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1424", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1325", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11371", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "857", + "maxAmount": "1" + }, + { + "minAmount": "20", + "weight": "25.0", + "id": "886", + "maxAmount": "20" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "9145", + "maxAmount": "5" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "9419", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1371", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1333", + "maxAmount": "1" + }, + { + "minAmount": "10", + "weight": "5.0", + "id": "808", + "maxAmount": "10" + }, + { + "minAmount": "10", + "weight": "5.0", + "id": "865", + "maxAmount": "10" + }, + { + "minAmount": "5", + "weight": "5.0", + "id": "890", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1391", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1191", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1193", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1157", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1143", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1197", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "106", + "weight": "50.0", + "id": "995", + "maxAmount": "323" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "11443", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "2357", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "2354", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "2356", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1515", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "444", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "565", + "maxAmount": "3" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "560", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1637", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2361", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "11359", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "592", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "4", + "weight": "91.1171", + "id": "0", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "3.0405", + "id": "12158", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "0.9915", + "id": "12159", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "0.2864", + "id": "12160", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "4.5645", + "id": "12163", + "maxAmount": "4" + } + ], + "ids": "6203", + "description": "K'ril Tsutsaroth (Zamorak GWD Boss)", + "main": [ + { + "minAmount": "1", + "weight": "8.112", + "id": "11716", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.92128", + "id": "11708", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.352", + "id": "11710", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.352", + "id": "11712", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.352", + "id": "11714", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "11736", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5698", + "maxAmount": "1" + }, + { + "minAmount": "295", + "weight": "100.0", + "id": "5626", + "maxAmount": "300" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "1333", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1123", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "1079", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "145", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "157", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "3026", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "189", + "maxAmount": "3" + }, + { + "minAmount": "120", + "weight": "25.0", + "id": "560", + "maxAmount": "125" + }, + { + "minAmount": "80", + "weight": "25.0", + "id": "565", + "maxAmount": "85" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "2486", + "maxAmount": "10" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "5302", + "maxAmount": "3" + }, + { + "minAmount": "19000", + "weight": "100.0", + "id": "995", + "maxAmount": "21000" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "12070", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "592", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "6204", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "3.37566", + "id": "11716", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.37566", + "id": "11710", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.37566", + "id": "11712", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.37566", + "id": "11714", + "maxAmount": "1" + }, + { + "minAmount": "1300", + "weight": "500.0", + "id": "995", + "maxAmount": "1500" + }, + { + "minAmount": "95", + "weight": "500.0", + "id": "886", + "maxAmount": "100" + }, + { + "minAmount": "95", + "weight": "500.0", + "id": "808", + "maxAmount": "100" + }, + { + "minAmount": "5", + "weight": "500.0", + "id": "560", + "maxAmount": "10" + }, + { + "minAmount": "5", + "weight": "500.0", + "id": "565", + "maxAmount": "10" + }, + { + "minAmount": "3", + "weight": "500.0", + "id": "385", + "maxAmount": "3" + }, + { + "minAmount": "2", + "weight": "500.0", + "id": "7060", + "maxAmount": "2" + }, + { + "minAmount": "10", + "weight": "500.0", + "id": "246", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "500.0", + "id": "145", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "500.0", + "id": "157", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "12070", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "592", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "6206", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "3.37566", + "id": "11716", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.37566", + "id": "11710", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.37566", + "id": "11712", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.37566", + "id": "11714", + "maxAmount": "1" + }, + { + "minAmount": "1300", + "weight": "500.0", + "id": "995", + "maxAmount": "1500" + }, + { + "minAmount": "95", + "weight": "500.0", + "id": "886", + "maxAmount": "100" + }, + { + "minAmount": "95", + "weight": "500.0", + "id": "808", + "maxAmount": "100" + }, + { + "minAmount": "5", + "weight": "500.0", + "id": "560", + "maxAmount": "10" + }, + { + "minAmount": "5", + "weight": "500.0", + "id": "565", + "maxAmount": "10" + }, + { + "minAmount": "3", + "weight": "500.0", + "id": "385", + "maxAmount": "3" + }, + { + "minAmount": "2", + "weight": "500.0", + "id": "7060", + "maxAmount": "2" + }, + { + "minAmount": "10", + "weight": "500.0", + "id": "246", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "500.0", + "id": "145", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "500.0", + "id": "157", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "12070", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "592", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "6208", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "3.37566", + "id": "11716", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.37566", + "id": "11710", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.37566", + "id": "11712", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.37566", + "id": "11714", + "maxAmount": "1" + }, + { + "minAmount": "1300", + "weight": "500.0", + "id": "995", + "maxAmount": "1500" + }, + { + "minAmount": "95", + "weight": "500.0", + "id": "886", + "maxAmount": "100" + }, + { + "minAmount": "95", + "weight": "500.0", + "id": "808", + "maxAmount": "100" + }, + { + "minAmount": "5", + "weight": "500.0", + "id": "560", + "maxAmount": "10" + }, + { + "minAmount": "5", + "weight": "500.0", + "id": "565", + "maxAmount": "10" + }, + { + "minAmount": "3", + "weight": "500.0", + "id": "385", + "maxAmount": "3" + }, + { + "minAmount": "2", + "weight": "500.0", + "id": "7060", + "maxAmount": "2" + }, + { + "minAmount": "10", + "weight": "500.0", + "id": "246", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "500.0", + "id": "145", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "500.0", + "id": "157", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "12070", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "6219,6229,6255,6277", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "1295", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1281", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1428", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1371", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1341", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1355", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1279", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1323", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1303", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "3202", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1317", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1243", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1105", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1161", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1071", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1059", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1195", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1081", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "6220,6230,6256,6276", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "886", + "maxAmount": "12" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "884", + "maxAmount": "24" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "882", + "maxAmount": "58" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "559", + "maxAmount": "12" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "892", + "maxAmount": "5" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "890", + "maxAmount": "12" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "40", + "maxAmount": "5" + }, + { + "minAmount": "12", + "weight": "50.0", + "id": "53", + "maxAmount": "12" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "687", + "maxAmount": "1" + }, + { + "minAmount": "7", + "weight": "50.0", + "id": "1778", + "maxAmount": "7" + }, + { + "minAmount": "11", + "weight": "50.0", + "id": "57", + "maxAmount": "11" + }, + { + "minAmount": "12", + "weight": "50.0", + "id": "57", + "maxAmount": "12" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "843", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "851", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "43", + "maxAmount": "13" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "861", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "12070", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "6221,6231,6257,6278", + "description": "", + "main": [ + { + "minAmount": "11", + "weight": "50.0", + "id": "556", + "maxAmount": "11" + }, + { + "minAmount": "13", + "weight": "50.0", + "id": "556", + "maxAmount": "13" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "555", + "maxAmount": "5" + }, + { + "minAmount": "9", + "weight": "50.0", + "id": "555", + "maxAmount": "9" + }, + { + "minAmount": "4", + "weight": "50.0", + "id": "561", + "maxAmount": "4" + }, + { + "minAmount": "9", + "weight": "50.0", + "id": "561", + "maxAmount": "9" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "562", + "maxAmount": "6" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "560", + "maxAmount": "2" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "9075", + "maxAmount": "3" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "563", + "maxAmount": "2" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "4695", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "4696", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "4698", + "maxAmount": "2" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "559", + "maxAmount": "5" + }, + { + "minAmount": "12", + "weight": "25.0", + "id": "559", + "maxAmount": "12" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "558", + "maxAmount": "5" + }, + { + "minAmount": "7", + "weight": "25.0", + "id": "554", + "maxAmount": "7" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "565", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "11732", + "maxAmount": "1" + }, + { + "minAmount": "23", + "weight": "50.0", + "id": "7937", + "maxAmount": "23" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "175", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "532", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "314", + "maxAmount": "16" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "36.6834", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.6873", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "13.9521", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "15.4005", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.2767", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "6222", + "description": "Kree'arra (Armadyl GWD Boss)", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "1319", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "9185", + "maxAmount": "1" + }, + { + "minAmount": "15", + "weight": "100.0", + "id": "9144", + "maxAmount": "25" + }, + { + "minAmount": "80", + "weight": "50.0", + "id": "892", + "maxAmount": "100" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "9244", + "maxAmount": "15" + }, + { + "minAmount": "500", + "weight": "25.0", + "id": "558", + "maxAmount": "600" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "2503", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.98342", + "id": "11718", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.98342", + "id": "11720", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.98342", + "id": "11722", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "5302", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "5303", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5315", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.11985", + "id": "11702", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.49174", + "id": "11710", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.49174", + "id": "11712", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.49174", + "id": "11714", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "169", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "163", + "maxAmount": "3" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "218", + "maxAmount": "25" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "989", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "10976", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "10977", + "maxAmount": "1" + }, + { + "minAmount": "18000", + "weight": "100.0", + "id": "995", + "maxAmount": "20000" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "6223", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "0.902405", + "id": "11718", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.902405", + "id": "11720", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.902405", + "id": "11722", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.70721", + "id": "11710", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.70721", + "id": "11712", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.70721", + "id": "11714", + "maxAmount": "1" + }, + { + "minAmount": "1300", + "weight": "500.0", + "id": "995", + "maxAmount": "1500" + }, + { + "minAmount": "95", + "weight": "500.0", + "id": "886", + "maxAmount": "100" + }, + { + "minAmount": "95", + "weight": "500.0", + "id": "808", + "maxAmount": "100" + }, + { + "minAmount": "15", + "weight": "500.0", + "id": "4697", + "maxAmount": "25" + }, + { + "minAmount": "2", + "weight": "500.0", + "id": "391", + "maxAmount": "2" + }, + { + "minAmount": "3", + "weight": "500.0", + "id": "7058", + "maxAmount": "3" + }, + { + "minAmount": "2", + "weight": "500.0", + "id": "6694", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "500.0", + "id": "214", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "12070", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "6225", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "0.902405", + "id": "11718", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.902405", + "id": "11720", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.902405", + "id": "11722", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.70721", + "id": "11710", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.70721", + "id": "11712", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.70721", + "id": "11714", + "maxAmount": "1" + }, + { + "minAmount": "1300", + "weight": "500.0", + "id": "995", + "maxAmount": "1500" + }, + { + "minAmount": "95", + "weight": "500.0", + "id": "886", + "maxAmount": "100" + }, + { + "minAmount": "95", + "weight": "500.0", + "id": "808", + "maxAmount": "100" + }, + { + "minAmount": "15", + "weight": "500.0", + "id": "4697", + "maxAmount": "25" + }, + { + "minAmount": "2", + "weight": "500.0", + "id": "391", + "maxAmount": "2" + }, + { + "minAmount": "3", + "weight": "500.0", + "id": "7058", + "maxAmount": "3" + }, + { + "minAmount": "2", + "weight": "500.0", + "id": "6694", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "500.0", + "id": "214", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "12070", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "6227", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "0.902405", + "id": "11718", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.902405", + "id": "11720", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.902405", + "id": "11722", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.70721", + "id": "11710", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.70721", + "id": "11712", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.70721", + "id": "11714", + "maxAmount": "1" + }, + { + "minAmount": "1300", + "weight": "500.0", + "id": "995", + "maxAmount": "1500" + }, + { + "minAmount": "95", + "weight": "500.0", + "id": "886", + "maxAmount": "100" + }, + { + "minAmount": "95", + "weight": "500.0", + "id": "808", + "maxAmount": "100" + }, + { + "minAmount": "15", + "weight": "500.0", + "id": "4697", + "maxAmount": "25" + }, + { + "minAmount": "2", + "weight": "500.0", + "id": "391", + "maxAmount": "2" + }, + { + "minAmount": "3", + "weight": "500.0", + "id": "7058", + "maxAmount": "3" + }, + { + "minAmount": "2", + "weight": "500.0", + "id": "6694", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "500.0", + "id": "214", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "12070", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "314", + "maxAmount": "7" + } + ], + "charm": [], + "ids": "6232,6233,6234,6235,6236,6237,6238,6239,6240,6241,6242,6243,6244,6245,6246", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "10.0", + "id": "1229", + "maxAmount": "1" + }, + { + "minAmount": "15", + "weight": "18.0", + "id": "556", + "maxAmount": "15" + }, + { + "minAmount": "30", + "weight": "13.0", + "id": "555", + "maxAmount": "30" + }, + { + "minAmount": "2", + "weight": "4.0", + "id": "563", + "maxAmount": "2" + }, + { + "minAmount": "9", + "weight": "4.0", + "id": "561", + "maxAmount": "9" + }, + { + "minAmount": "3", + "weight": "3.0", + "id": "562", + "maxAmount": "3" + }, + { + "minAmount": "12", + "weight": "2.0", + "id": "559", + "maxAmount": "12" + }, + { + "minAmount": "11", + "weight": "2.0", + "id": "565", + "maxAmount": "11" + }, + { + "minAmount": "5", + "weight": "1.0", + "id": "558", + "maxAmount": "5" + }, + { + "minAmount": "16", + "weight": "1.0", + "id": "562", + "maxAmount": "16" + }, + { + "minAmount": "1", + "weight": "15.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "4", + "weight": "30.0", + "id": "2362", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "442", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "9431", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "5.0", + "id": "175", + "maxAmount": "5" + }, + { + "minAmount": "5", + "weight": "3.0", + "id": "0", + "maxAmount": "5" + }, + { + "minAmount": "5", + "weight": "2.0", + "id": "373", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "14426", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "12070", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "4", + "weight": "82.502", + "id": "0", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "4.2237", + "id": "12158", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "4.8572", + "id": "12159", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "5.9533", + "id": "12160", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "2.4638", + "id": "12163", + "maxAmount": "4" + } + ], + "ids": "6247", + "description": "Commander Zilyana (Saradomin GWD Boss)", + "main": [ + { + "minAmount": "1", + "weight": "1.92128", + "id": "11706", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.352", + "id": "11710", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.352", + "id": "11712", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.352", + "id": "11714", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.112", + "id": "11730", + "maxAmount": "1" + }, + { + "minAmount": "35", + "weight": "50.0", + "id": "811", + "maxAmount": "40" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "1093", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "1201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1123", + "maxAmount": "1" + }, + { + "minAmount": "95", + "weight": "50.0", + "id": "563", + "maxAmount": "100" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "3024", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "163", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "3042", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "6687", + "maxAmount": "3" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "208", + "maxAmount": "5" + }, + { + "minAmount": "2", + "weight": "50.0", + "id": "5295", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5316", + "maxAmount": "1" + }, + { + "minAmount": "19000", + "weight": "100.0", + "id": "995", + "maxAmount": "21000" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2434", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "6248", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "3.04143", + "id": "11730", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.04143", + "id": "11710", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.04143", + "id": "11712", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.04143", + "id": "11714", + "maxAmount": "1" + }, + { + "minAmount": "1300", + "weight": "500.0", + "id": "995", + "maxAmount": "1500" + }, + { + "minAmount": "95", + "weight": "500.0", + "id": "886", + "maxAmount": "100" + }, + { + "minAmount": "95", + "weight": "500.0", + "id": "808", + "maxAmount": "100" + }, + { + "minAmount": "5", + "weight": "500.0", + "id": "563", + "maxAmount": "10" + }, + { + "minAmount": "3", + "weight": "500.0", + "id": "7946", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "500.0", + "id": "7218", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "500.0", + "id": "208", + "maxAmount": "1" + }, + { + "minAmount": "6", + "weight": "500.0", + "id": "238", + "maxAmount": "6" + }, + { + "minAmount": "5", + "weight": "500.0", + "id": "232", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "12070", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "6250", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "3.04143", + "id": "11730", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.04143", + "id": "11710", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.04143", + "id": "11712", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.04143", + "id": "11714", + "maxAmount": "1" + }, + { + "minAmount": "1300", + "weight": "500.0", + "id": "995", + "maxAmount": "1500" + }, + { + "minAmount": "1", + "weight": "500.0", + "id": "886", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "500.0", + "id": "808", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "500.0", + "id": "563", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "500.0", + "id": "7946", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "500.0", + "id": "7218", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "500.0", + "id": "208", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "500.0", + "id": "238", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "500.0", + "id": "232", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "12070", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "6252", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "3.04143", + "id": "11730", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.04143", + "id": "11710", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.04143", + "id": "11712", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.04143", + "id": "11714", + "maxAmount": "1" + }, + { + "minAmount": "1300", + "weight": "500.0", + "id": "995", + "maxAmount": "1500" + }, + { + "minAmount": "1", + "weight": "500.0", + "id": "886", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "500.0", + "id": "808", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "500.0", + "id": "563", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "500.0", + "id": "7946", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "500.0", + "id": "7218", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "500.0", + "id": "208", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "500.0", + "id": "238", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "500.0", + "id": "232", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "12070", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "6254", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "127.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "5733", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "67.5", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "26.25", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.0", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.0", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "6.25", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "6258,6259", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "5.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "4834", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "4", + "weight": "85.5895", + "id": "0", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "4.7851", + "id": "12158", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "3.5198", + "id": "12159", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "3.6001", + "id": "12160", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "2.5055", + "id": "12163", + "maxAmount": "4" + } + ], + "ids": "6260", + "description": "General Graardor (Bandos GWD Boss)", + "main": [ + { + "minAmount": "1", + "weight": "8.0", + "id": "1289", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1303", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "1319", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "1127", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1275", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.5756", + "id": "11724", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.5756", + "id": "11726", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.5756", + "id": "11728", + "maxAmount": "1" + }, + { + "minAmount": "65", + "weight": "50.0", + "id": "561", + "maxAmount": "70" + }, + { + "minAmount": "115", + "weight": "25.0", + "id": "454", + "maxAmount": "120" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "450", + "maxAmount": "20" + }, + { + "minAmount": "19000", + "weight": "100.0", + "id": "995", + "maxAmount": "21000" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5300", + "maxAmount": "1" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "1514", + "maxAmount": "20" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "3024", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "3052", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "10976", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "10977", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.2878", + "id": "11710", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.2878", + "id": "11712", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.2878", + "id": "11714", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.83004", + "id": "11704", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "6261", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "1.23663", + "id": "11724", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.23663", + "id": "11726", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.23663", + "id": "11728", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.70988", + "id": "11710", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.70988", + "id": "11712", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.70988", + "id": "11714", + "maxAmount": "1" + }, + { + "minAmount": "1300", + "weight": "500.0", + "id": "995", + "maxAmount": "1500" + }, + { + "minAmount": "95", + "weight": "500.0", + "id": "886", + "maxAmount": "100" + }, + { + "minAmount": "95", + "weight": "500.0", + "id": "808", + "maxAmount": "100" + }, + { + "minAmount": "25", + "weight": "500.0", + "id": "564", + "maxAmount": "30" + }, + { + "minAmount": "20", + "weight": "500.0", + "id": "561", + "maxAmount": "25" + }, + { + "minAmount": "5", + "weight": "500.0", + "id": "226", + "maxAmount": "5" + }, + { + "minAmount": "2", + "weight": "500.0", + "id": "385", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "500.0", + "id": "7054", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "500.0", + "id": "9741", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "500.0", + "id": "157", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "500.0", + "id": "1971", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "12070", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "6263", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "1.23663", + "id": "11724", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.23663", + "id": "11726", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.23663", + "id": "11728", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.70988", + "id": "11710", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.70988", + "id": "11712", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.70988", + "id": "11714", + "maxAmount": "1" + }, + { + "minAmount": "1300", + "weight": "500.0", + "id": "995", + "maxAmount": "1500" + }, + { + "minAmount": "95", + "weight": "500.0", + "id": "886", + "maxAmount": "100" + }, + { + "minAmount": "95", + "weight": "500.0", + "id": "808", + "maxAmount": "100" + }, + { + "minAmount": "25", + "weight": "500.0", + "id": "564", + "maxAmount": "30" + }, + { + "minAmount": "25", + "weight": "500.0", + "id": "561", + "maxAmount": "30" + }, + { + "minAmount": "5", + "weight": "500.0", + "id": "226", + "maxAmount": "5" + }, + { + "minAmount": "2", + "weight": "500.0", + "id": "385", + "maxAmount": "2" + }, + { + "minAmount": "3", + "weight": "500.0", + "id": "7054", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "500.0", + "id": "9741", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "500.0", + "id": "157", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "500.0", + "id": "1917", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "12070", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "6265", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "1.23663", + "id": "11724", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.23663", + "id": "11726", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.23663", + "id": "11728", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.70988", + "id": "11710", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.70988", + "id": "11712", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.70988", + "id": "11714", + "maxAmount": "1" + }, + { + "minAmount": "1300", + "weight": "500.0", + "id": "995", + "maxAmount": "1500" + }, + { + "minAmount": "95", + "weight": "500.0", + "id": "886", + "maxAmount": "100" + }, + { + "minAmount": "95", + "weight": "500.0", + "id": "808", + "maxAmount": "100" + }, + { + "minAmount": "25", + "weight": "500.0", + "id": "564", + "maxAmount": "30" + }, + { + "minAmount": "20", + "weight": "500.0", + "id": "561", + "maxAmount": "25" + }, + { + "minAmount": "5", + "weight": "500.0", + "id": "226", + "maxAmount": "5" + }, + { + "minAmount": "2", + "weight": "500.0", + "id": "385", + "maxAmount": "2" + }, + { + "minAmount": "3", + "weight": "500.0", + "id": "7054", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "500.0", + "id": "9741", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "500.0", + "id": "157", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "500.0", + "id": "1025", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "12070", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "6285,6286,6287,6288,6289,6290,6291,6292,6293,6294,6295,6322,6323,6324,6325,6326,6327,6328,6329,6330,6331,6332", + "description": "", + "main": [ + { + "minAmount": "24", + "weight": "50.0", + "id": "556", + "maxAmount": "60" + }, + { + "minAmount": "12", + "weight": "50.0", + "id": "557", + "maxAmount": "36" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "560", + "maxAmount": "28" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "563", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "566", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1121", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1201", + "maxAmount": "1" + }, + { + "minAmount": "16", + "weight": "50.0", + "id": "9190", + "maxAmount": "24" + }, + { + "minAmount": "16", + "weight": "50.0", + "id": "9191", + "maxAmount": "24" + }, + { + "minAmount": "16", + "weight": "50.0", + "id": "9192", + "maxAmount": "24" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "9143", + "maxAmount": "15" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1343", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "9144", + "maxAmount": "12" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1347", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1275", + "maxAmount": "1" + }, + { + "minAmount": "15", + "weight": "50.0", + "id": "995", + "maxAmount": "479" + }, + { + "minAmount": "23", + "weight": "50.0", + "id": "314", + "maxAmount": "99" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "1939", + "maxAmount": "52" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "449", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "187", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2185", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2187", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1458", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "384", + "maxAmount": "6" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "3209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1462", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "532", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "80.3408", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.756", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.2796", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.1186", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.505", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "6296,6297", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "1343", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1357", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1121", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1275", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1347", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "449", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "448", + "maxAmount": "9" + }, + { + "minAmount": "6", + "weight": "50.0", + "id": "454", + "maxAmount": "16" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "563", + "maxAmount": "6" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1458", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1462", + "maxAmount": "1" + }, + { + "minAmount": "49", + "weight": "5.0", + "id": "556", + "maxAmount": "49" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "10995", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "10976", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "10977", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "3209", + "maxAmount": "1" + }, + { + "minAmount": "30", + "weight": "50.0", + "id": "995", + "maxAmount": "180" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "1939", + "maxAmount": "32" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "1968", + "maxAmount": "54" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2187", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "7939", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "187", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "80.3408", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "76.3636", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "17.931", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.8213", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.1944", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.6897", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "6363,6364", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "5.0", + "id": "1213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1301", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1325", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1333", + "maxAmount": "1" + }, + { + "minAmount": "100", + "weight": "100.0", + "id": "995", + "maxAmount": "100" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "379", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "78.8", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.3333", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.2", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.3333", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "13.3333", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "6365,6366", + "description": "", + "main": [ + { + "minAmount": "100", + "weight": "50.0", + "id": "995", + "maxAmount": "100" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "1777", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "849", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "847", + "maxAmount": "1" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "886", + "maxAmount": "10" + }, + { + "minAmount": "20", + "weight": "5.0", + "id": "888", + "maxAmount": "20" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "861", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "6378", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "5318", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5319", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5320", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5323", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2108", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "3142", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5972", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5984", + "maxAmount": "1" + }, + { + "minAmount": "1020", + "weight": "50.0", + "id": "314", + "maxAmount": "1020" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1515", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "227", + "maxAmount": "1" + }, + { + "minAmount": "12", + "weight": "25.0", + "id": "6306", + "maxAmount": "18" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11766", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11767", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11768", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11769", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11764", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "6379", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "5318", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5319", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5322", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "5320", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "5.0", + "id": "5323", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5321", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5288", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "556", + "maxAmount": "48" + }, + { + "minAmount": "28", + "weight": "50.0", + "id": "555", + "maxAmount": "28" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "557", + "maxAmount": "9" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "561", + "maxAmount": "15" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "560", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "565", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "380", + "weight": "5.0", + "id": "995", + "maxAmount": "380" + }, + { + "minAmount": "2", + "weight": "50.0", + "id": "5504", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "235", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "454", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "6306", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "1", + "weight": "82.6923", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.3269", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "11.0577", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.4423", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.4808", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "6380", + "description": "", + "main": [ + { + "minAmount": "5", + "weight": "50.0", + "id": "554", + "maxAmount": "5" + }, + { + "minAmount": "6", + "weight": "50.0", + "id": "554", + "maxAmount": "6" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "4696", + "maxAmount": "3" + }, + { + "minAmount": "2", + "weight": "50.0", + "id": "561", + "maxAmount": "2" + }, + { + "minAmount": "9", + "weight": "50.0", + "id": "561", + "maxAmount": "9" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "563", + "maxAmount": "1" + }, + { + "minAmount": "9", + "weight": "25.0", + "id": "563", + "maxAmount": "9" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "557", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "566", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "5.0", + "id": "565", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5291", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5292", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5293", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5294", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5296", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "12176", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5297", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5298", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5299", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5295", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5301", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5302", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5303", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5288", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "6306", + "maxAmount": "23" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "440", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "5504", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "453", + "maxAmount": "7" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "235", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11766", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11767", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11768", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11769", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11764", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "6381,6383", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "562", + "maxAmount": "2" + }, + { + "minAmount": "8", + "weight": "25.0", + "id": "562", + "maxAmount": "10" + }, + { + "minAmount": "32", + "weight": "25.0", + "id": "555", + "maxAmount": "32" + }, + { + "minAmount": "35", + "weight": "25.0", + "id": "555", + "maxAmount": "35" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "566", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "247", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "6468", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "841", + "maxAmount": "1" + }, + { + "minAmount": "28", + "weight": "50.0", + "id": "882", + "maxAmount": "28" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1422", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1389", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1379", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1381", + "maxAmount": "1" + }, + { + "minAmount": "68", + "weight": "50.0", + "id": "555", + "maxAmount": "68" + }, + { + "minAmount": "6", + "weight": "50.0", + "id": "554", + "maxAmount": "6" + }, + { + "minAmount": "6", + "weight": "50.0", + "id": "557", + "maxAmount": "6" + }, + { + "minAmount": "12", + "weight": "25.0", + "id": "556", + "maxAmount": "12" + }, + { + "minAmount": "33", + "weight": "25.0", + "id": "558", + "maxAmount": "33" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1438", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1448", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1444", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1442", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1167", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1061", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1059", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1129", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1103", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1173", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1139", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1635", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1654", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1673", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1718", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1729", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1727", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "436", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "438", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2349", + "maxAmount": "1" + }, + { + "minAmount": "225", + "weight": "50.0", + "id": "995", + "maxAmount": "225" + }, + { + "minAmount": "400", + "weight": "50.0", + "id": "995", + "maxAmount": "400" + }, + { + "minAmount": "1042", + "weight": "50.0", + "id": "1734", + "maxAmount": "1042" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "314", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1741", + "maxAmount": "1" + }, + { + "minAmount": "20", + "weight": "50.0", + "id": "313", + "maxAmount": "50" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "532", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "6512,6513,6514,6515,6516,6517,6518,6519", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "1341", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1345", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1361", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1141", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1339", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1145", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1181", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5291", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5292", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5293", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5294", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5296", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5295", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "12176", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5297", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5298", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5299", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5300", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5301", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5302", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5303", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5323", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5321", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5311", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5100", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5104", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5105", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5106", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5280", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5281", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5304", + "maxAmount": "1" + }, + { + "minAmount": "8", + "weight": "50.0", + "id": "995", + "maxAmount": "8" + }, + { + "minAmount": "35", + "weight": "50.0", + "id": "995", + "maxAmount": "35" + }, + { + "minAmount": "7", + "weight": "50.0", + "id": "561", + "maxAmount": "7" + }, + { + "minAmount": "25", + "weight": "50.0", + "id": "557", + "maxAmount": "25" + }, + { + "minAmount": "45", + "weight": "50.0", + "id": "557", + "maxAmount": "45" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "563", + "maxAmount": "2" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "454", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "354", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "7884", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "10976", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "10977", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "4", + "weight": "100.0", + "id": "12158", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "12159", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "12160", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "12163", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "5.6", + "id": "0", + "maxAmount": "1" + } + ], + "ids": "6604,6635,6655,6666,6677,6697,6703,6715", + "description": "Revenant imp", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "1079", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1093", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1113", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1147", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1163", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1185", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1289", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1303", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1319", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1347", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1373", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1432", + "maxAmount": "1" + }, + { + "minAmount": "100", + "weight": "25.0", + "id": "7937", + "maxAmount": "1000" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "563", + "maxAmount": "200" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "565", + "maxAmount": "200" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "560", + "maxAmount": "200" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1618", + "maxAmount": "5" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "445", + "maxAmount": "30" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "114", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "208", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "450", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "452", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "3050", + "maxAmount": "10" + }, + { + "minAmount": "20", + "weight": "50.0", + "id": "554", + "maxAmount": "500" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "555", + "maxAmount": "500" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "556", + "maxAmount": "500" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "1516", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "100", + "weight": "50.0", + "id": "995", + "maxAmount": "1000" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5315", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5316", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5300", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5289", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5288", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5318", + "maxAmount": "50" + }, + { + "minAmount": "50", + "weight": "25.0", + "id": "9144", + "maxAmount": "50" + }, + { + "minAmount": "75", + "weight": "25.0", + "id": "9143", + "maxAmount": "75" + }, + { + "minAmount": "75", + "weight": "25.0", + "id": "892", + "maxAmount": "75" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "386", + "maxAmount": "4" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "7061", + "maxAmount": "5" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "4", + "weight": "100.0", + "id": "12158", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "12159", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "12160", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "12163", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "5.6", + "id": "0", + "maxAmount": "1" + } + ], + "ids": "6605,6612,6616,6620,6636,6637,6638,6639,6651,6656,6657,6658,6667,6678,6679,6680,6681,6693,6698,6699,6704,6705,6706,6707,6716,6717,6718,6719", + "description": "Revenant goblin", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "1079", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1093", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1113", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1147", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1163", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1185", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1289", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1303", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1319", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1347", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1373", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1432", + "maxAmount": "1" + }, + { + "minAmount": "100", + "weight": "25.0", + "id": "7937", + "maxAmount": "1000" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "563", + "maxAmount": "200" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "565", + "maxAmount": "200" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "560", + "maxAmount": "200" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1618", + "maxAmount": "5" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "445", + "maxAmount": "30" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "114", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "208", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "450", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "452", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "3050", + "maxAmount": "10" + }, + { + "minAmount": "20", + "weight": "50.0", + "id": "554", + "maxAmount": "500" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "555", + "maxAmount": "500" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "556", + "maxAmount": "500" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "1516", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "100", + "weight": "50.0", + "id": "995", + "maxAmount": "1000" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5315", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5316", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5300", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5289", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5288", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5318", + "maxAmount": "50" + }, + { + "minAmount": "50", + "weight": "25.0", + "id": "9144", + "maxAmount": "50" + }, + { + "minAmount": "75", + "weight": "25.0", + "id": "9143", + "maxAmount": "75" + }, + { + "minAmount": "75", + "weight": "25.0", + "id": "892", + "maxAmount": "75" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "386", + "maxAmount": "4" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "7061", + "maxAmount": "5" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "4", + "weight": "100.0", + "id": "12158", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "12159", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "12160", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "12163", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "5.6", + "id": "0", + "maxAmount": "1" + } + ], + "ids": "6606,6621,6628,6640,6659,6682,6694,6708,6720", + "description": "Revenant icefiend", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "1079", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1093", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1113", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1147", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1163", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1185", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1289", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1303", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1319", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1347", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1373", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1432", + "maxAmount": "1" + }, + { + "minAmount": "100", + "weight": "25.0", + "id": "7937", + "maxAmount": "1000" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "563", + "maxAmount": "200" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "565", + "maxAmount": "200" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "560", + "maxAmount": "200" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1618", + "maxAmount": "5" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "445", + "maxAmount": "30" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "114", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "208", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "450", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "452", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "3050", + "maxAmount": "10" + }, + { + "minAmount": "20", + "weight": "50.0", + "id": "554", + "maxAmount": "500" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "555", + "maxAmount": "500" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "556", + "maxAmount": "500" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "1516", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "100", + "weight": "50.0", + "id": "995", + "maxAmount": "1000" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5315", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5316", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5300", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5289", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5288", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5318", + "maxAmount": "50" + }, + { + "minAmount": "50", + "weight": "25.0", + "id": "9144", + "maxAmount": "50" + }, + { + "minAmount": "75", + "weight": "25.0", + "id": "9143", + "maxAmount": "75" + }, + { + "minAmount": "75", + "weight": "25.0", + "id": "892", + "maxAmount": "75" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "386", + "maxAmount": "4" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "7061", + "maxAmount": "5" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "4", + "weight": "100.0", + "id": "12158", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "12159", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "12160", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "12163", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "5.6", + "id": "0", + "maxAmount": "1" + } + ], + "ids": "6607,6609,6614,6617,6625,6632,6644,6663,6675,6686,6701,6712,6724,6728", + "description": "Revenant werewolf", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "1079", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1093", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1113", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1147", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1163", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1185", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1289", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1303", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1319", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1347", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1373", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1432", + "maxAmount": "1" + }, + { + "minAmount": "100", + "weight": "25.0", + "id": "7937", + "maxAmount": "1000" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "563", + "maxAmount": "200" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "565", + "maxAmount": "200" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "560", + "maxAmount": "200" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1618", + "maxAmount": "5" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "445", + "maxAmount": "30" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "114", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "208", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "450", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "452", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "3050", + "maxAmount": "10" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "232", + "maxAmount": "500" + }, + { + "minAmount": "20", + "weight": "50.0", + "id": "554", + "maxAmount": "500" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "555", + "maxAmount": "500" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "556", + "maxAmount": "500" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "1516", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "100", + "weight": "50.0", + "id": "995", + "maxAmount": "1000" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5315", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5316", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5300", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5289", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5288", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5318", + "maxAmount": "50" + }, + { + "minAmount": "50", + "weight": "25.0", + "id": "9144", + "maxAmount": "50" + }, + { + "minAmount": "75", + "weight": "25.0", + "id": "9143", + "maxAmount": "75" + }, + { + "minAmount": "75", + "weight": "25.0", + "id": "892", + "maxAmount": "75" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "386", + "maxAmount": "4" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "7061", + "maxAmount": "5" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "4", + "weight": "100.0", + "id": "12158", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "12159", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "12160", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "12163", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "5.6", + "id": "0", + "maxAmount": "1" + } + ], + "ids": "6608,6642,6661,6684,6710,6722,6727", + "description": "Revenant hobgoblin", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "1079", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1093", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1113", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1147", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1163", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1185", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1289", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1303", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1319", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1347", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1373", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1432", + "maxAmount": "1" + }, + { + "minAmount": "100", + "weight": "25.0", + "id": "7937", + "maxAmount": "1000" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "563", + "maxAmount": "200" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "565", + "maxAmount": "200" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "560", + "maxAmount": "200" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1618", + "maxAmount": "5" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "445", + "maxAmount": "30" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "114", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "208", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "450", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "452", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "3050", + "maxAmount": "10" + }, + { + "minAmount": "20", + "weight": "50.0", + "id": "554", + "maxAmount": "500" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "555", + "maxAmount": "500" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "556", + "maxAmount": "500" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "1516", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "100", + "weight": "50.0", + "id": "995", + "maxAmount": "1000" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5315", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5316", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5300", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5289", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5288", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5318", + "maxAmount": "50" + }, + { + "minAmount": "50", + "weight": "25.0", + "id": "9144", + "maxAmount": "50" + }, + { + "minAmount": "75", + "weight": "25.0", + "id": "9143", + "maxAmount": "75" + }, + { + "minAmount": "75", + "weight": "25.0", + "id": "892", + "maxAmount": "75" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "386", + "maxAmount": "4" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "7061", + "maxAmount": "5" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "4", + "weight": "100.0", + "id": "12158", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "12159", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "12160", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "12163", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "5.6", + "id": "0", + "maxAmount": "1" + } + ], + "ids": "6610,6615,6618,6624,6626,6629,6633,6648,6653,6664,6670,6672,6690,6696,6702,6713,6725,6729", + "description": "Revenant ork", + "main": [ + { + "minAmount": "1", + "weight": "5.0", + "id": "1215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1704", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1079", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1093", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1113", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1147", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1163", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1185", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1289", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1303", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1319", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1347", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1373", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1432", + "maxAmount": "1" + }, + { + "minAmount": "100", + "weight": "25.0", + "id": "7937", + "maxAmount": "1000" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "563", + "maxAmount": "200" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "565", + "maxAmount": "200" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "560", + "maxAmount": "200" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1618", + "maxAmount": "5" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "445", + "maxAmount": "30" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "114", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "208", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "450", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "452", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "3050", + "maxAmount": "10" + }, + { + "minAmount": "20", + "weight": "50.0", + "id": "554", + "maxAmount": "500" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "555", + "maxAmount": "500" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "556", + "maxAmount": "500" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "1516", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "100", + "weight": "50.0", + "id": "995", + "maxAmount": "1000" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5315", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5316", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5300", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5289", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5288", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5318", + "maxAmount": "50" + }, + { + "minAmount": "50", + "weight": "25.0", + "id": "9144", + "maxAmount": "50" + }, + { + "minAmount": "75", + "weight": "25.0", + "id": "9143", + "maxAmount": "75" + }, + { + "minAmount": "75", + "weight": "25.0", + "id": "892", + "maxAmount": "75" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "386", + "maxAmount": "4" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "7061", + "maxAmount": "5" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "4", + "weight": "100.0", + "id": "12158", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "12159", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "12160", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "12163", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "5.6", + "id": "0", + "maxAmount": "1" + } + ], + "ids": "6611,6619,6627,6630,6634,6650,6654,6665,6673,6676,6692,6714,6726,6730", + "description": "Revenant knight", + "main": [ + { + "minAmount": "1", + "weight": "5.0", + "id": "1215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1704", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1079", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1093", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1113", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1147", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1163", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1185", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1289", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1303", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1319", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1347", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1373", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1432", + "maxAmount": "1" + }, + { + "minAmount": "100", + "weight": "25.0", + "id": "7937", + "maxAmount": "1000" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "563", + "maxAmount": "200" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "565", + "maxAmount": "200" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "560", + "maxAmount": "200" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1618", + "maxAmount": "5" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "445", + "maxAmount": "30" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "114", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "208", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "450", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "452", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "3050", + "maxAmount": "10" + }, + { + "minAmount": "20", + "weight": "50.0", + "id": "554", + "maxAmount": "500" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "555", + "maxAmount": "500" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "556", + "maxAmount": "500" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "1516", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "100", + "weight": "50.0", + "id": "995", + "maxAmount": "1000" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5315", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5316", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5300", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5289", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5288", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5318", + "maxAmount": "50" + }, + { + "minAmount": "50", + "weight": "25.0", + "id": "9144", + "maxAmount": "50" + }, + { + "minAmount": "75", + "weight": "25.0", + "id": "9143", + "maxAmount": "75" + }, + { + "minAmount": "75", + "weight": "25.0", + "id": "892", + "maxAmount": "75" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "386", + "maxAmount": "4" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "7061", + "maxAmount": "5" + }, + { + "minAmount": "200", + "weight": "25.0", + "id": "995", + "maxAmount": "5000" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "4", + "weight": "100.0", + "id": "12158", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "12159", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "12160", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "12163", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "5.6", + "id": "0", + "maxAmount": "1" + } + ], + "ids": "6613,6623,6643,6652,6662,6669,6671,6674,6685,6695,6700,6711,6723", + "description": "Revenant vampire", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "1079", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1093", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1113", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1147", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1163", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1185", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1289", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1303", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1319", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1347", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1373", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1432", + "maxAmount": "1" + }, + { + "minAmount": "100", + "weight": "25.0", + "id": "7937", + "maxAmount": "1000" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "563", + "maxAmount": "200" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "565", + "maxAmount": "200" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "560", + "maxAmount": "200" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1618", + "maxAmount": "5" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "445", + "maxAmount": "30" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "114", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "208", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "450", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "452", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "3050", + "maxAmount": "10" + }, + { + "minAmount": "20", + "weight": "50.0", + "id": "554", + "maxAmount": "500" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "555", + "maxAmount": "500" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "556", + "maxAmount": "500" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "1516", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "100", + "weight": "50.0", + "id": "995", + "maxAmount": "1000" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5315", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5316", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5300", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5289", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5288", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5318", + "maxAmount": "50" + }, + { + "minAmount": "50", + "weight": "25.0", + "id": "9144", + "maxAmount": "50" + }, + { + "minAmount": "75", + "weight": "25.0", + "id": "9143", + "maxAmount": "75" + }, + { + "minAmount": "75", + "weight": "25.0", + "id": "892", + "maxAmount": "75" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "386", + "maxAmount": "4" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "7061", + "maxAmount": "5" + }, + { + "minAmount": "200", + "weight": "25.0", + "id": "995", + "maxAmount": "5000" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "4", + "weight": "100.0", + "id": "12158", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "12159", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "12160", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "12163", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "5.6", + "id": "0", + "maxAmount": "1" + } + ], + "ids": "6622,6631,6641,6660,6668,6683,6709,6721", + "description": "Revenant pyrefiend", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "1079", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1093", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1113", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1147", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1163", + "maxAmount": "1" + }, + { + "minAmount": "200", + "weight": "25.0", + "id": "995", + "maxAmount": "5000" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1185", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1289", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1303", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1319", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1347", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1373", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1432", + "maxAmount": "1" + }, + { + "minAmount": "100", + "weight": "25.0", + "id": "7937", + "maxAmount": "1000" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "563", + "maxAmount": "200" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "565", + "maxAmount": "200" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "560", + "maxAmount": "200" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1618", + "maxAmount": "5" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "445", + "maxAmount": "30" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "114", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "208", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "450", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "452", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "3050", + "maxAmount": "10" + }, + { + "minAmount": "20", + "weight": "50.0", + "id": "554", + "maxAmount": "500" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "555", + "maxAmount": "500" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "556", + "maxAmount": "500" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "1516", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "100", + "weight": "50.0", + "id": "995", + "maxAmount": "1000" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5315", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5316", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5300", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5289", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5288", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5318", + "maxAmount": "50" + }, + { + "minAmount": "50", + "weight": "25.0", + "id": "9144", + "maxAmount": "50" + }, + { + "minAmount": "75", + "weight": "25.0", + "id": "9143", + "maxAmount": "75" + }, + { + "minAmount": "75", + "weight": "25.0", + "id": "892", + "maxAmount": "75" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "386", + "maxAmount": "4" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "7061", + "maxAmount": "5" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "4", + "weight": "100.0", + "id": "12158", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "12159", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "12160", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "12163", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "5.6", + "id": "0", + "maxAmount": "1" + } + ], + "ids": "6645,6687", + "description": "Revenant cyclops", + "main": [ + { + "minAmount": "1", + "weight": "5.0", + "id": "1215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1704", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1079", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1093", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1113", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1147", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1163", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1185", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1289", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1303", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1319", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1347", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1373", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1432", + "maxAmount": "1" + }, + { + "minAmount": "100", + "weight": "25.0", + "id": "7937", + "maxAmount": "1000" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "563", + "maxAmount": "200" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "565", + "maxAmount": "200" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "560", + "maxAmount": "200" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1618", + "maxAmount": "5" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "445", + "maxAmount": "30" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "114", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "208", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "450", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "452", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "3050", + "maxAmount": "10" + }, + { + "minAmount": "20", + "weight": "50.0", + "id": "554", + "maxAmount": "500" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "555", + "maxAmount": "500" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "556", + "maxAmount": "500" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "1516", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "100", + "weight": "50.0", + "id": "995", + "maxAmount": "1000" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5315", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5316", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5300", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5289", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5288", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5318", + "maxAmount": "50" + }, + { + "minAmount": "50", + "weight": "25.0", + "id": "9144", + "maxAmount": "50" + }, + { + "minAmount": "75", + "weight": "25.0", + "id": "9143", + "maxAmount": "75" + }, + { + "minAmount": "75", + "weight": "25.0", + "id": "892", + "maxAmount": "75" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "386", + "maxAmount": "4" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "7061", + "maxAmount": "5" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "4", + "weight": "100.0", + "id": "12158", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "12159", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "12160", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "12163", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "5.6", + "id": "0", + "maxAmount": "1" + } + ], + "ids": "6646,6688", + "description": "Revenant hellhound", + "main": [ + { + "minAmount": "1", + "weight": "5.0", + "id": "1215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1704", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1079", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1093", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1113", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1147", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1163", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1185", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1289", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1303", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1319", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1347", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1373", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1432", + "maxAmount": "1" + }, + { + "minAmount": "100", + "weight": "25.0", + "id": "7937", + "maxAmount": "1000" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "563", + "maxAmount": "200" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "565", + "maxAmount": "200" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "560", + "maxAmount": "200" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1618", + "maxAmount": "5" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "445", + "maxAmount": "30" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "114", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "208", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "450", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "452", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "3050", + "maxAmount": "10" + }, + { + "minAmount": "20", + "weight": "50.0", + "id": "554", + "maxAmount": "500" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "555", + "maxAmount": "500" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "556", + "maxAmount": "500" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "1516", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "100", + "weight": "50.0", + "id": "995", + "maxAmount": "1000" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5315", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5316", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5300", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5289", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5288", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5318", + "maxAmount": "50" + }, + { + "minAmount": "50", + "weight": "25.0", + "id": "9144", + "maxAmount": "50" + }, + { + "minAmount": "75", + "weight": "25.0", + "id": "9143", + "maxAmount": "75" + }, + { + "minAmount": "75", + "weight": "25.0", + "id": "892", + "maxAmount": "150" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "386", + "maxAmount": "4" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "7061", + "maxAmount": "5" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "4", + "weight": "100.0", + "id": "12158", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "12159", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "12160", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "12163", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "5.6", + "id": "0", + "maxAmount": "1" + } + ], + "ids": "6647,6689", + "description": "Revenant demon", + "main": [ + { + "minAmount": "1", + "weight": "5.0", + "id": "1215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1704", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1079", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1093", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1113", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1147", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1163", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1185", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1289", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1303", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1319", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1347", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1373", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1432", + "maxAmount": "1" + }, + { + "minAmount": "100", + "weight": "25.0", + "id": "7937", + "maxAmount": "1000" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "563", + "maxAmount": "200" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "565", + "maxAmount": "200" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "560", + "maxAmount": "200" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1618", + "maxAmount": "5" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "445", + "maxAmount": "30" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "114", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "208", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "450", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "452", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "3050", + "maxAmount": "10" + }, + { + "minAmount": "20", + "weight": "50.0", + "id": "554", + "maxAmount": "500" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "555", + "maxAmount": "500" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "556", + "maxAmount": "500" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "1516", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "100", + "weight": "50.0", + "id": "995", + "maxAmount": "1000" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5315", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5316", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5300", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5289", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5288", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5318", + "maxAmount": "50" + }, + { + "minAmount": "50", + "weight": "25.0", + "id": "9144", + "maxAmount": "50" + }, + { + "minAmount": "75", + "weight": "25.0", + "id": "9143", + "maxAmount": "75" + }, + { + "minAmount": "75", + "weight": "25.0", + "id": "892", + "maxAmount": "75" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "386", + "maxAmount": "4" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "7061", + "maxAmount": "5" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "4", + "weight": "100.0", + "id": "12158", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "12159", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "12160", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "12163", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "5.6", + "id": "0", + "maxAmount": "1" + } + ], + "ids": "6649,6691", + "description": "Revenant dark beast", + "main": [ + { + "minAmount": "1", + "weight": "5.0", + "id": "1215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1704", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1079", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1093", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1113", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1147", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1163", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1185", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1289", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1303", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1319", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1347", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1373", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1432", + "maxAmount": "1" + }, + { + "minAmount": "100", + "weight": "25.0", + "id": "7937", + "maxAmount": "1000" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "563", + "maxAmount": "200" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "565", + "maxAmount": "200" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "560", + "maxAmount": "200" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1618", + "maxAmount": "5" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "445", + "maxAmount": "30" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "114", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "208", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "450", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "452", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "3050", + "maxAmount": "10" + }, + { + "minAmount": "20", + "weight": "50.0", + "id": "554", + "maxAmount": "500" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "555", + "maxAmount": "500" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "556", + "maxAmount": "500" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "1516", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "100", + "weight": "50.0", + "id": "995", + "maxAmount": "1000" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5315", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5316", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5300", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5289", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5288", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5318", + "maxAmount": "50" + }, + { + "minAmount": "50", + "weight": "25.0", + "id": "9144", + "maxAmount": "50" + }, + { + "minAmount": "75", + "weight": "25.0", + "id": "9143", + "maxAmount": "75" + }, + { + "minAmount": "75", + "weight": "25.0", + "id": "892", + "maxAmount": "75" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "386", + "maxAmount": "4" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "7061", + "maxAmount": "5" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "80.1337", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "6.6032", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.9189", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.5225", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.8217", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "6761,6762,6763", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "886", + "maxAmount": "23" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "890", + "maxAmount": "14" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "9142", + "maxAmount": "14" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1321", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1323", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1325", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1329", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1371", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "808", + "maxAmount": "25" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1241", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "857", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "565", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "560", + "maxAmount": "10" + }, + { + "minAmount": "75", + "weight": "25.0", + "id": "554", + "maxAmount": "75" + }, + { + "minAmount": "25", + "weight": "25.0", + "id": "4699", + "maxAmount": "25" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "2354", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "2357", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "2356", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "442", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2359", + "maxAmount": "1" + }, + { + "minAmount": "106", + "weight": "50.0", + "id": "995", + "maxAmount": "323" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1835", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1641", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "161", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1833", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "954", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "946", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11986", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "9419", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "5.0", + "id": "9737", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "9745", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "90.2081", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0796", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.4688", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.4076", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.836", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "6773", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "1391", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1319", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "5.0", + "id": "830", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "554", + "maxAmount": "1" + }, + { + "minAmount": "24", + "weight": "25.0", + "id": "890", + "maxAmount": "24" + }, + { + "minAmount": "8", + "weight": "25.0", + "id": "10143", + "maxAmount": "8" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "562", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "565", + "maxAmount": "1" + }, + { + "minAmount": "37", + "weight": "5.0", + "id": "4699", + "maxAmount": "37" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "995", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "11986", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "9735", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "371", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "6774", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "5.0", + "id": "1347", + "maxAmount": "1" + }, + { + "minAmount": "24", + "weight": "5.0", + "id": "890", + "maxAmount": "24" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1319", + "maxAmount": "1" + }, + { + "minAmount": "9", + "weight": "25.0", + "id": "892", + "maxAmount": "9" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1373", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1149", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1249", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1391", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "371", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "373", + "maxAmount": "1" + }, + { + "minAmount": "7", + "weight": "25.0", + "id": "565", + "maxAmount": "7" + }, + { + "minAmount": "20", + "weight": "25.0", + "id": "4699", + "maxAmount": "20" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5280", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "995", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "5.0", + "id": "9735", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "987", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "10143", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11986", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "985", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1621", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1621", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1607", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1605", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1603", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1823", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "11986", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "6777", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "565", + "maxAmount": "7" + }, + { + "minAmount": "20", + "weight": "25.0", + "id": "4699", + "maxAmount": "20" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "564", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1319", + "maxAmount": "1" + }, + { + "minAmount": "24", + "weight": "25.0", + "id": "890", + "maxAmount": "24" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1199", + "maxAmount": "1" + }, + { + "minAmount": "9", + "weight": "25.0", + "id": "892", + "maxAmount": "9" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1185", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1347", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1373", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "1391", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1623", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1621", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1619", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1617", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5280", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2293", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "371", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "373", + "maxAmount": "1" + }, + { + "minAmount": "15", + "weight": "50.0", + "id": "995", + "maxAmount": "15" + }, + { + "minAmount": "29", + "weight": "50.0", + "id": "995", + "maxAmount": "29" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "9735", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "10143", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "6778", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "3385", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "3387", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "3389", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "3393", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "3391", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "30", + "weight": "25.0", + "id": "561", + "maxAmount": "30" + }, + { + "minAmount": "20", + "weight": "25.0", + "id": "4699", + "maxAmount": "20" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "565", + "maxAmount": "7" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "564", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1391", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1347", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1373", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1319", + "maxAmount": "1" + }, + { + "minAmount": "24", + "weight": "25.0", + "id": "890", + "maxAmount": "24" + }, + { + "minAmount": "9", + "weight": "25.0", + "id": "892", + "maxAmount": "9" + }, + { + "minAmount": "200", + "weight": "5.0", + "id": "9143", + "maxAmount": "200" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "371", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "373", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "365", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2293", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "9052", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "363", + "maxAmount": "1" + }, + { + "minAmount": "60", + "weight": "25.0", + "id": "995", + "maxAmount": "500" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11986", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1623", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1621", + "maxAmount": "2" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "9735", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "6945,7319,7321,7323,7325,7327", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "7911", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "11965", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "4", + "weight": "100.0", + "id": "12158", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "12159", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "12160", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "100.0", + "id": "12163", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "5.6", + "id": "0", + "maxAmount": "1" + } + ], + "ids": "6998,6999", + "description": "Revenant dragon", + "main": [ + { + "minAmount": "1", + "weight": "5.0", + "id": "1215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1704", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1079", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1093", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1113", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1147", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1163", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1185", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1289", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1303", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1319", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1347", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1373", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1432", + "maxAmount": "1" + }, + { + "minAmount": "100", + "weight": "25.0", + "id": "7937", + "maxAmount": "1000" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "563", + "maxAmount": "200" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "565", + "maxAmount": "200" + }, + { + "minAmount": "15", + "weight": "25.0", + "id": "560", + "maxAmount": "200" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1618", + "maxAmount": "5" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "445", + "maxAmount": "30" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "114", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "208", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "450", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "452", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "3050", + "maxAmount": "10" + }, + { + "minAmount": "20", + "weight": "50.0", + "id": "554", + "maxAmount": "500" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "555", + "maxAmount": "500" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "556", + "maxAmount": "500" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "1516", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "100", + "weight": "50.0", + "id": "995", + "maxAmount": "1000" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5315", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5316", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5300", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5289", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "5288", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "5318", + "maxAmount": "50" + }, + { + "minAmount": "50", + "weight": "25.0", + "id": "9144", + "maxAmount": "50" + }, + { + "minAmount": "75", + "weight": "25.0", + "id": "9143", + "maxAmount": "75" + }, + { + "minAmount": "75", + "weight": "25.0", + "id": "892", + "maxAmount": "75" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "386", + "maxAmount": "4" + }, + { + "minAmount": "5", + "weight": "25.0", + "id": "7061", + "maxAmount": "5" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "532", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "13.1269", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "79.3218", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.9989", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.7261", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.8264", + "id": "12163", + "maxAmount": "1" + } + ], + "tertiary": [ + { + "minAmount": "1", + "weight": "9973.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "10976", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "10977", + "maxAmount": "1" + } + ], + "ids": "7078", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "2.0", + "id": "1239", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "12570", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "124.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "532", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "53.1561", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "38.8704", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.3223", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.99", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.6611", + "id": "12163", + "maxAmount": "1" + } + ], + "tertiary": [ + { + "minAmount": "1", + "weight": "9973.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "10976", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "10977", + "maxAmount": "1" + } + ], + "ids": "7079,7081", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "2.0", + "id": "12570", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "126.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "532", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "52.7123", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "38.5613", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.7146", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.4222", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.5896", + "id": "12163", + "maxAmount": "1" + } + ], + "tertiary": [ + { + "minAmount": "1", + "weight": "9973.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "10976", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "10977", + "maxAmount": "1" + } + ], + "ids": "7080,7082", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "2.0", + "id": "1239", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "126.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "7133,7134", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "12070", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "15.0", + "id": "1147", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "35.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "77.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "1", + "weight": "2.0266", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "62.8232", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.2621", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "9.7834", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.1048", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "7135", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "127.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "7138,7139,7140", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "2.371541", + "id": "14497", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.371541", + "id": "14499", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.371541", + "id": "14501", + "maxAmount": "1" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "557", + "maxAmount": "10" + }, + { + "minAmount": "18", + "weight": "25.0", + "id": "557", + "maxAmount": "18" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "556", + "maxAmount": "10" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "559", + "maxAmount": "10" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "554", + "maxAmount": "10" + }, + { + "minAmount": "10", + "weight": "25.0", + "id": "558", + "maxAmount": "10" + }, + { + "minAmount": "18", + "weight": "25.0", + "id": "558", + "maxAmount": "18" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "561", + "maxAmount": "4" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "562", + "maxAmount": "4" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "563", + "maxAmount": "3" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "564", + "maxAmount": "2" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "565", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1442", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1444", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1379", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "995", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "995", + "maxAmount": "2" + }, + { + "minAmount": "4", + "weight": "25.0", + "id": "995", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "581", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1017", + "maxAmount": "1" + }, + { + "minAmount": "36", + "weight": "25.0", + "id": "556", + "maxAmount": "36" + }, + { + "minAmount": "36", + "weight": "25.0", + "id": "559", + "maxAmount": "36" + }, + { + "minAmount": "36", + "weight": "25.0", + "id": "554", + "maxAmount": "36" + }, + { + "minAmount": "36", + "weight": "25.0", + "id": "558", + "maxAmount": "36" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "1", + "weight": "93.0134", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.6584", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.988", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.9873", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.3529", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "7158", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "1205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1139", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "556", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "554", + "maxAmount": "11" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "555", + "maxAmount": "8" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "995", + "maxAmount": "30" + }, + { + "minAmount": "2", + "weight": "50.0", + "id": "454", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "225", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "223", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1621", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1617", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1607", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "93.0134", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "1", + "weight": "71.9397", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "6.1502", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.6665", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "17.1496", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.094", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "7159", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "1143", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1181", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1391", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "1121", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "1213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "50.0", + "id": "448", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "454", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "564", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "561", + "maxAmount": "20" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "562", + "maxAmount": "18" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "557", + "maxAmount": "22" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "80.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "1", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "1", + "weight": "58.7492", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "7.9739", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.9208", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "26.2643", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0919", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "7160", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "25.0", + "id": "1143", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "1185", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "1333", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "560", + "maxAmount": "20" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "563", + "maxAmount": "20" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "554", + "maxAmount": "58" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "565", + "maxAmount": "16" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "564", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5104", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5311", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5100", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5323", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5298", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5281", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5280", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5301", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5297", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5299", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5292", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5106", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5293", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5296", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5105", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5294", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "12176", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5295", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5303", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5302", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5321", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "448", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "450", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "995", + "maxAmount": "5" + }, + { + "minAmount": "100", + "weight": "50.0", + "id": "995", + "maxAmount": "400" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "6004", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "5733", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5300", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "5304", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "73.7931", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "22.9885", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.069", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.1494", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.0", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "7640", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "1179", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1195", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1325", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "5322", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "5100", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "5320", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5105", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5106", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "5104", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "5323", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "5.0", + "id": "5281", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "564", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "560", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "565", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "5.0", + "id": "4695", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "5.0", + "id": "4697", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "5.0", + "id": "4696", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "5.0", + "id": "4694", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "11069", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "11072", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11074", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11076", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1641", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "11085", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "11092", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1643", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "11095", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "11115", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "3049", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "313", + "maxAmount": "10" + }, + { + "minAmount": "20", + "weight": "50.0", + "id": "1539", + "maxAmount": "20" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "4821", + "maxAmount": "10" + }, + { + "minAmount": "750", + "weight": "5.0", + "id": "995", + "maxAmount": "750" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2359", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "1", + "weight": "75.6592", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "20.8925", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.6227", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.6227", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.2028", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "7641", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "50.0", + "id": "1059", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1179", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1195", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1325", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1635", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1637", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1639", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "11069", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "11072", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1641", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11076", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "11074", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "11085", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "11092", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "11088", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1643", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "11095", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "11115", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "564", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "560", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "565", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "5.0", + "id": "4695", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "5.0", + "id": "4697", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "5.0", + "id": "4696", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "5.0", + "id": "4694", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "5322", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "5100", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "50.0", + "id": "5320", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "5323", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5105", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "5106", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "5104", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "5.0", + "id": "5105", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "5.0", + "id": "5281", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "3049", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "313", + "maxAmount": "10" + }, + { + "minAmount": "20", + "weight": "50.0", + "id": "1539", + "maxAmount": "20" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "4821", + "maxAmount": "10" + }, + { + "minAmount": "750", + "weight": "5.0", + "id": "995", + "maxAmount": "750" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2359", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "46.1418", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "43.3139", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.6442", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.7841", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.1161", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "7642,7643", + "description": "", + "main": [ + { + "minAmount": "6", + "weight": "50.0", + "id": "892", + "maxAmount": "6" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "867", + "maxAmount": "10" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1357", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1331", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "25.0", + "id": "868", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1333", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "4125", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1181", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1109", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1111", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1183", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "4129", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1147", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1149", + "maxAmount": "1" + }, + { + "minAmount": "50", + "weight": "50.0", + "id": "556", + "maxAmount": "50" + }, + { + "minAmount": "50", + "weight": "50.0", + "id": "557", + "maxAmount": "50" + }, + { + "minAmount": "50", + "weight": "50.0", + "id": "554", + "maxAmount": "50" + }, + { + "minAmount": "10", + "weight": "50.0", + "id": "7936", + "maxAmount": "10" + }, + { + "minAmount": "20", + "weight": "50.0", + "id": "562", + "maxAmount": "20" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "560", + "maxAmount": "5" + }, + { + "minAmount": "6", + "weight": "25.0", + "id": "565", + "maxAmount": "30" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "454", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "445", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "448", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "450", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "5001", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "250", + "weight": "50.0", + "id": "995", + "maxAmount": "250" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "163", + "maxAmount": "1" + }, + { + "minAmount": "20", + "weight": "5.0", + "id": "1539", + "maxAmount": "20" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [ + { + "minAmount": "13", + "weight": "3.1496", + "id": "0", + "maxAmount": "13" + }, + { + "minAmount": "13", + "weight": "22.2601", + "id": "12158", + "maxAmount": "13" + }, + { + "minAmount": "13", + "weight": "12.0238", + "id": "12159", + "maxAmount": "13" + }, + { + "minAmount": "13", + "weight": "22.0685", + "id": "12160", + "maxAmount": "13" + }, + { + "minAmount": "13", + "weight": "40.498", + "id": "12163", + "maxAmount": "13" + } + ], + "ids": "8133", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "0.4", + "id": "13752", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.2", + "id": "13746", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.2", + "id": "13750", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.2", + "id": "13748", + "maxAmount": "1" + }, + { + "minAmount": "20000", + "weight": "12.0", + "id": "995", + "maxAmount": "50000" + }, + { + "minAmount": "1", + "weight": "12.0", + "id": "1401", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "12.0", + "id": "1403", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "12.0", + "id": "1405", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "12.0", + "id": "1407", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "11133", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "13734", + "maxAmount": "1" + }, + { + "minAmount": "750", + "weight": "17.0", + "id": "890", + "maxAmount": "750" + }, + { + "minAmount": "250", + "weight": "24.0", + "id": "9144", + "maxAmount": "250" + }, + { + "minAmount": "2000", + "weight": "17.0", + "id": "2", + "maxAmount": "2000" + }, + { + "minAmount": "175", + "weight": "20.0", + "id": "9245", + "maxAmount": "175" + }, + { + "minAmount": "2500", + "weight": "21.0", + "id": "7937", + "maxAmount": "2500" + }, + { + "minAmount": "250", + "weight": "17.0", + "id": "563", + "maxAmount": "250" + }, + { + "minAmount": "500", + "weight": "17.0", + "id": "564", + "maxAmount": "500" + }, + { + "minAmount": "300", + "weight": "22.0", + "id": "560", + "maxAmount": "300" + }, + { + "minAmount": "250", + "weight": "32.0", + "id": "566", + "maxAmount": "250" + }, + { + "minAmount": "70", + "weight": "21.0", + "id": "384", + "maxAmount": "70" + }, + { + "minAmount": "120", + "weight": "17.0", + "id": "240", + "maxAmount": "120" + }, + { + "minAmount": "120", + "weight": "17.0", + "id": "9738", + "maxAmount": "120" + }, + { + "minAmount": "24", + "weight": "15.0", + "id": "5321", + "maxAmount": "24" + }, + { + "minAmount": "10", + "weight": "5.0", + "id": "5295", + "maxAmount": "10" + }, + { + "minAmount": "30", + "weight": "20.0", + "id": "7061", + "maxAmount": "30" + }, + { + "minAmount": "40", + "weight": "10.0", + "id": "2449", + "maxAmount": "40" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "13754", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "18.0", + "id": "4091", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "18.0", + "id": "4093", + "maxAmount": "1" + }, + { + "minAmount": "125", + "weight": "17.0", + "id": "450", + "maxAmount": "125" + }, + { + "minAmount": "35", + "weight": "18.0", + "id": "2362", + "maxAmount": "35" + }, + { + "minAmount": "20", + "weight": "12.0", + "id": "452", + "maxAmount": "20" + }, + { + "minAmount": "100", + "weight": "12.0", + "id": "8781", + "maxAmount": "100" + }, + { + "minAmount": "150", + "weight": "12.0", + "id": "8836", + "maxAmount": "150" + }, + { + "minAmount": "100", + "weight": "18.0", + "id": "1754", + "maxAmount": "100" + }, + { + "minAmount": "75", + "weight": "12.0", + "id": "1514", + "maxAmount": "75" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "82.1886", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "7.3302", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.2583", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.1612", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0617", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "8149,8150,8151", + "description": "", + "main": [ + { + "minAmount": "4", + "weight": "25.0", + "id": "888", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1424", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "1199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1163", + "maxAmount": "1" + }, + { + "minAmount": "6", + "weight": "25.0", + "id": "564", + "maxAmount": "6" + }, + { + "minAmount": "12", + "weight": "25.0", + "id": "562", + "maxAmount": "12" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "561", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "565", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "560", + "maxAmount": "3" + }, + { + "minAmount": "3", + "weight": "25.0", + "id": "7937", + "maxAmount": "12" + }, + { + "minAmount": "1", + "weight": "25.0", + "id": "222", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "20.0", + "id": "961", + "maxAmount": "9" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "8779", + "maxAmount": "5" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1617", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1621", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1619", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1623", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "6.0", + "id": "8781", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "313", + "maxAmount": "7" + }, + { + "minAmount": "1", + "weight": "30.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "20.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "20.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "91.6064", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "7.0005", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.7927", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.4372", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.1632", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "1076,1077", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "300.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "70.0", + "id": "1339", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "40.0", + "id": "1343", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "33.0", + "id": "1121", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "7.0", + "id": "1159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "1071", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "1446", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "30.0", + "id": "447", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "400.0", + "id": "995", + "maxAmount": "23" + }, + { + "minAmount": "23", + "weight": "100.0", + "id": "995", + "maxAmount": "38" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1073,1074", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "200.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "70.0", + "id": "1097", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "30.0", + "id": "1099", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "20.0", + "id": "847", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "849", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "30.0", + "id": "447", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "240.0", + "id": "995", + "maxAmount": "23" + }, + { + "minAmount": "23", + "weight": "100.0", + "id": "995", + "maxAmount": "38" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1065", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "80.0", + "id": "1157", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "30.0", + "id": "3097", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "3098", + "maxAmount": "1" + }, + { + "minAmount": "6", + "weight": "50.0", + "id": "3093", + "maxAmount": "6" + }, + { + "minAmount": "6", + "weight": "50.0", + "id": "869", + "maxAmount": "6" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "2353", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "20.0", + "id": "2359", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "100.0", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "30.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "20.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "565", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1623", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "30.0", + "id": "1621", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "20.0", + "id": "1619", + "maxAmount": "1" + }, + { + "minAmount": "24", + "weight": "100.0", + "id": "995", + "maxAmount": "70" + }, + { + "minAmount": "70", + "weight": "50.0", + "id": "995", + "maxAmount": "180" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "88.5971", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.5251", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.7022", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.6504", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.5251", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "1044,1045,1046", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "600.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "14", + "weight": "400.0", + "id": "995", + "maxAmount": "30" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "88.5971", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.5251", + "id": "12158", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.7022", + "id": "12159", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.6504", + "id": "12160", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.5251", + "id": "12163", + "maxAmount": "1" + } + ], + "ids": "188,189,190", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "500.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "1033", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "40.0", + "id": "1035", + "maxAmount": "1" + }, + { + "minAmount": "24", + "weight": "400.0", + "id": "995", + "maxAmount": "64" + }, + { + "minAmount": "64", + "weight": "50.0", + "id": "995", + "maxAmount": "94" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1591", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "201", + "description": "Jailer (Taverley Dungeon, drops Jail key)", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "2859", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "141", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1455,1456,1459,1460,1465", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "100.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1904,6368,6367,912,913,914,253,254,255,256,258,27,34,35,689,690,691,3814,3816,4402,4403", + "description": "", + "main": [ + { + "minAmount": "4", + "weight": "50.0", + "id": "995", + "maxAmount": "34" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "14,6972,6973,6974,6975,6976,6977,6978,6979,6980,6981,6982,6983,6984,6985,6986,6987", + "description": "Druid and Druidess (Taverley)", + "main": [ + { + "minAmount": "27", + "weight": "2.2", + "id": "557", + "maxAmount": "27" + }, + { + "minAmount": "9", + "weight": "1.1", + "id": "555", + "maxAmount": "9" + }, + { + "minAmount": "9", + "weight": "1.1", + "id": "557", + "maxAmount": "9" + }, + { + "minAmount": "9", + "weight": "1.1", + "id": "554", + "maxAmount": "9" + }, + { + "minAmount": "3", + "weight": "1.1", + "id": "562", + "maxAmount": "3" + }, + { + "minAmount": "2", + "weight": "0.57", + "id": "563", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "3.4", + "id": "199", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "201", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "205", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "207", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "209", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "211", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "213", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "215", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.5", + "id": "2485", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.5", + "id": "217", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "5.0", + "id": "995", + "maxAmount": "2" + }, + { + "minAmount": "4", + "weight": "1.9", + "id": "995", + "maxAmount": "4" + }, + { + "minAmount": "1", + "weight": "1.7", + "id": "995", + "maxAmount": "1" + }, + { + "minAmount": "15", + "weight": "1.7", + "id": "995", + "maxAmount": "15" + }, + { + "minAmount": "20", + "weight": "0.6", + "id": "995", + "maxAmount": "20" + }, + { + "minAmount": "1", + "weight": "22.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "6.2", + "id": "229", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "1203", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "538", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "540", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.9", + "id": "225", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.64", + "id": "175", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "428,429", + "description": "Shade (Stronghold of Security) (So Shade Robes can drop)", + "main": [ + { + "minAmount": "1", + "weight": "0.1", + "id": "546", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.1", + "id": "548", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "0", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "391,392,393,394,395,396", + "description": "River Troll (Hostile Fishing Random Event)", + "main": [ + { + "minAmount": "1", + "weight": "10.0", + "id": "371", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "383", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "349", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.2", + "id": "331", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.2", + "id": "327", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "345", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "359", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "10.0", + "id": "313", + "maxAmount": "5" + }, + { + "minAmount": "30", + "weight": "10.0", + "id": "313", + "maxAmount": "30" + }, + { + "minAmount": "15", + "weight": "10.0", + "id": "313", + "maxAmount": "15" + }, + { + "minAmount": "20", + "weight": "3.2", + "id": "314", + "maxAmount": "20" + }, + { + "minAmount": "40", + "weight": "3.2", + "id": "314", + "maxAmount": "40" + }, + { + "minAmount": "50", + "weight": "2.0", + "id": "313", + "maxAmount": "50" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "407", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "8.0", + "id": "405", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.5", + "id": "151", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "413,414,415,416", + "description": "Rock Golem (Combat lvl 14-79) (Hostile Mining Random Event)", + "main": [ + { + "minAmount": "5", + "weight": "20.0", + "id": "557", + "maxAmount": "5" + }, + { + "minAmount": "42", + "weight": "5.0", + "id": "557", + "maxAmount": "42" + }, + { + "minAmount": "2", + "weight": "5.0", + "id": "562", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "2349", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "438", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "436", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "1913", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "2347", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "417,418", + "description": "Rock Golem (Combat lvl 120-159) (Hostile Mining Random Event)", + "main": [ + { + "minAmount": "1", + "weight": "6.0", + "id": "1265", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.5", + "id": "1271", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.5", + "id": "1275", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "20.0", + "id": "557", + "maxAmount": "5" + }, + { + "minAmount": "42", + "weight": "18.0", + "id": "557", + "maxAmount": "42" + }, + { + "minAmount": "2", + "weight": "18.0", + "id": "562", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "20.0", + "id": "453", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "17.0", + "id": "447", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "17.0", + "id": "2349", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "440", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "2351", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "438", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "436", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "449", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.5", + "id": "451", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "20.0", + "id": "1913", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "20.0", + "id": "2347", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "2892", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1480", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "4910", + "description": "Earth Elemental", + "main": [ + { + "minAmount": "1", + "weight": "2.0", + "id": "565", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "560", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "6.0", + "id": "563", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "12.0", + "id": "562", + "maxAmount": "2" + }, + { + "minAmount": "15", + "weight": "12.0", + "id": "557", + "maxAmount": "20" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "1440", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "10.0", + "id": "561", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1385", + "maxAmount": "1" + }, + { + "minAmount": "14", + "weight": "45.0", + "id": "995", + "maxAmount": "42" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "31", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "2892", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1480", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "4911", + "description": "Elemental Rock", + "main": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "1020", + "description": "Wandering earth elemental", + "main": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "31", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "565", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "560", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "6.0", + "id": "563", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "12.0", + "id": "562", + "maxAmount": "2" + }, + { + "minAmount": "15", + "weight": "12.0", + "id": "557", + "maxAmount": "20" + }, + { + "minAmount": "1", + "weight": "10.0", + "id": "1440", + "maxAmount": "1" + }, + { + "minAmount": "2", + "weight": "10.0", + "id": "561", + "maxAmount": "2" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "1385", + "maxAmount": "1" + }, + { + "minAmount": "14", + "weight": "45.0", + "id": "995", + "maxAmount": "42" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "0", + "maxAmount": "1" + } + ], + "ids": "4396,4415", + "description": "Rat (Stronghold)", + "main": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "3363", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "3355", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1232", + "description": "Pointed", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "3367", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "3357", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1233", + "description": "Pointed", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "3363", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "3359", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1234", + "description": "Pointed", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "3367", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "3361", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1235", + "description": "Pointed", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "1019", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "180", + "description": "Old-Highwayman", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "837", + "description": "Shantay Guard", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "526", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1019", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "2677", + "description": "New-Highwayman", + "main": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "995", + "maxAmount": "25" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "9141", + "maxAmount": "15" + }, + { + "minAmount": "1", + "weight": "23.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "447,448,449,917", + "description": "Jail Guard", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "526", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "2337", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "48", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "76", + "description": "Entrana Zombie", + "main": [ + { + "minAmount": "1", + "weight": "4.0", + "id": "1139", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1291", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "50.0", + "id": "1351", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1349", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "556", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "4.0", + "id": "882", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "561", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "5", + "weight": "50.0", + "id": "313", + "maxAmount": "5" + }, + { + "minAmount": "18", + "weight": "3.0", + "id": "995", + "maxAmount": "18" + }, + { + "minAmount": "28", + "weight": "2.0", + "id": "995", + "maxAmount": "28" + }, + { + "minAmount": "1", + "weight": "7.0", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1993", + "description": "", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "532", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "6779", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "0.25", + "id": "10976", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "0.02", + "id": "10977", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "99.73", + "id": "0", + "maxAmount": "1" + } + ] + }, + { + "default": [], + "charm": [], + "ids": "1832", + "description": "Cave Bug (Level 6)", + "main": [ + { + "minAmount": "8", + "weight": "5.0", + "id": "555", + "maxAmount": "8" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "561", + "maxAmount": "1" + }, + { + "minAmount": "6", + "weight": "2.0", + "id": "557", + "maxAmount": "6" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "561", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "23.0", + "id": "14424", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "235", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "221", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "2.0", + "id": "223", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "225", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "231", + "maxAmount": "1" + }, + { + "minAmount": "3", + "weight": "8.0", + "id": "995", + "maxAmount": "3" + }, + { + "minAmount": "1", + "weight": "64.0", + "id": "0", + "maxAmount": "1" + }, + { + "minAmount": "8", + "weight": "3.0", + "id": "995", + "maxAmount": "8" + }, + { + "minAmount": "1", + "weight": "5.0", + "id": "36", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "3.0", + "id": "590", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "4527", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "3057,3059,3058,3060,3061,3062,3063,3064,3065,3066", + "description": "Champion's Challenge NPC - activity", + "main": [] + }, + { + "default": [], + "charm": [], + "ids": "2459,2460,2461,2462", + "description": "Pheasant NPC (level 4) - Freaky Forester - Random event", + "main": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "6178", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "526", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "4184", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "1676", + "description": "Experiment (level 51)", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "526", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "3672,3673,5168,5169,5170", + "description": "Ram", + "main": [] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "526", + "maxAmount": "1" + }, + { + "minAmount": "1", + "weight": "1.0", + "id": "1583", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "6108", + "description": "", + "main": [] + }, + { + "default": [], + "charm": [], + "ids": "795", + "description": "", + "main": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "1580", + "maxAmount": "1" + } + ] + }, + { + "default": [ + { + "minAmount": "1", + "weight": "1.0", + "id": "592", + "maxAmount": "1" + } + ], + "charm": [], + "ids": "8127", + "description": "Dark energy core", + "main": [] + } +] \ No newline at end of file diff --git a/Server/data/configs/ground_spawns.json b/Server/data/configs/ground_spawns.json new file mode 100644 index 0000000..ca2b6f7 --- /dev/null +++ b/Server/data/configs/ground_spawns.json @@ -0,0 +1,670 @@ +[ + { + "item_id": "20", + "loc_data": "{1,2577,9655,0,100}-" + }, + { + "item_id": "21", + "loc_data": "{1,2613,9639,0,100}-" + }, + { + "item_id": "22", + "loc_data": "{1,2574,9633,0,100}-" + }, + { + "item_id": "23", + "loc_data": "{1,2583,9613,0,100}-" + }, + { + "item_id": "24", + "loc_data": "{1,2564,9662,0,100}-" + }, + { + "item_id": "28", + "loc_data": "{1,2807,3450,0,90}-" + }, + { + "item_id": "33", + "loc_data": "{1,2547,3114,0,10}-{1,3208,3395,1,30}-" + }, + { + "item_id": "39", + "loc_data": "{1,2672,3433,0,90}-" + }, + { + "item_id": "41", + "loc_data": "{1,3125,9997,0,90}-" + }, + { + "item_id": "53", + "loc_data": "{3,3240,3940,0,44}-{2,3237,3948,0,44}-{3,3235,3949,0,44}-" + }, + { + "item_id": "83", + "loc_data": "{1,2637,9819,0,30}-" + }, + { + "item_id": "84", + "loc_data": "{1,2638,9906,0,30}-" + }, + { + "item_id": "85", + "loc_data": "{1,2628,9859,0,30}-" + }, + { + "item_id": "88", + "loc_data": "{1,2654,9767,0,63}-" + }, + { + "item_id": "90", + "loc_data": "{1,2570,9604,0,30}-" + }, + { + "item_id": "185", + "loc_data": "{1,2467,3176,0,90}-" + }, + { + "item_id": "223", + "loc_data": "{1,3179,9881,0,90}-{1,3177,9880,0,90}-{1,3128,9956,0,90}-{1,3129,9954,0,90}-{1,3126,9958,0,90}-{1,3117,9951,0,90}-{1,3118,9948,0,90}-{1,3119,9949,0,90}-" + }, + { + "item_id": "229", + "loc_data": "{1,2588,3090,2,90}-{1,2587,3090,2,90}-{1,2809,3342,0,100}-{1,2808,3343,0,100}-{1,3186,3836,0,60}-{1,3195,3849,0,60}-" + }, + { + "item_id": "231", + "loc_data": "{1,2905,3297,0,10}-{1,2907,3295,0,10}-{1,2553,3751,0,90}-{1,2553,3754,0,90}-{1,2552,3757,0,90}-{1,2546,3763,0,90}-{1,2542,3765,0,90}-{1,2540,3765,0,90}-{1,2528,3716,0,90}-{1,2501,3727,0,90}-{1,2502,3726,0,90}-{1,2501,3729,0,90}-{1,2500,3730,0,90}-{1,2500,3731,0,90}-{1,2501,3732,0,90}-{1,2503,3733,0,90}-{1,2504,3732,0,90}-{1,2506,3731,0,90}-{1,2529,3735,0,90}-{1,2531,3736,0,90}-{1,2527,3746,0,90}-{1,2525,3751,0,90}-{1,2532,3762,0,90}-{1,2503,3757,0,30}-{1,2502,3756,0,30}-{1,2502,3754,0,30}-{1,2502,3752,0,30}-{1,2503,3751,0,30}-{1,2505,3753,0,30}-" + }, + { + "item_id": "239", + "loc_data": "{1,3217,3812,0,2}-{1,3210,3808,0,2}-" + }, + { + "item_id": "243", + "loc_data": "{1,2910,9809,0,30}-{1,2908,9805,0,30}-{1,2902,9806,0,30}-{1,2906,9796,0,30}-{1,2905,9801,0,30}-" + }, + { + "item_id": "245", + "loc_data": "{1,2931,3515,0,50}-" + }, + { + "item_id": "247", + "loc_data": "{1,2512,3080,0,30}-{1,2517,3082,0,30}-{1,2509,3088,0,30}-{1,2508,3084,0,30}-" + }, + { + "item_id": "272", + "loc_data": "{1,3108,3356,1,140}-" + }, + { + "item_id": "273", + "loc_data": "{1,3097,3366,0,140}-" + }, + { + "item_id": "276", + "loc_data": "{1,3111,3367,0,50}-" + }, + { + "item_id": "277", + "loc_data": "{1,3092,9755,0,50}-" + }, + { + "item_id": "278", + "loc_data": "{1,2604,3358,0,50}-" + }, + { + "item_id": "301", + "loc_data": "{1,2608,3397,0,90}-" + }, + { + "item_id": "303", + "loc_data": "{1,3245,3155,0,140}-{1,3244,3159,0,140}-{1,3429,4784,0,75}-{1,3432,4783,0,75}-{1,3414,4768,0,75}-{1,3429,4769,0,75}-{1,3431,4772,0,75}-{1,3415,4786,0,75}-{1,3412,4784,0,75}-" + }, + { + "item_id": "305", + "loc_data": "{1,2605,3395,0,90}-" + }, + { + "item_id": "307", + "loc_data": "{1,2860,3335,0,190}-" + }, + { + "item_id": "311", + "loc_data": "{1,2605,3396,0,90}-" + }, + { + "item_id": "347", + "loc_data": "{1,2563,9511,0,30}-" + }, + { + "item_id": "357", + "loc_data": "{1,2820,3453,0,90}-" + }, + { + "item_id": "401", + "loc_data": "{1,2959,2959,0,160}-{1,2943,2950,0,160}-{1,2866,2976,0,160}-{1,2854,2977,0,160}-{1,2839,2975,0,160}-{1,2757,2947,0,160}-{1,2755,2952,0,160}-{1,2786,2960,0,160}-{1,2782,2987,0,160}-{1,2771,2995,0,160}-{1,2761,3000,0,160}-{1,3829,3053,0,160}-{1,3813,3066,0,160}-{1,3814,3064,0,160}-{1,3808,3060,0,160}-{1,2945,3068,0,160}-{1,2975,3013,0,160}-{1,2955,3010,0,160}-{1,2755,3008,0,160}-{1,2754,3017,0,160}-{1,2756,3060,0,160}-{1,2755,3070,0,160}-{1,2896,3119,0,160}-{1,2914,3111,0,160}-{1,2926,3110,0,160}-{1,2939,3102,0,160}-{1,2938,3073,0,160}-{1,2756,3074,0,160}-{1,2806,3128,0,160}-{1,2764,3131,0,160}-{1,2753,3125,0,160}-{1,2757,3109,0,160}-{1,2864,3195,0,160}-{1,2810,3387,0,160}-{1,2809,3388,0,160}-{1,2809,3385,0,160}-{1,2807,3386,0,160}-{1,2804,3385,0,160}-{1,2807,3384,0,160}-{1,2805,3384,0,160}-{1,2802,3382,0,160}-{1,2805,3381,0,160}-{1,2804,3380,0,160}-{1,2693,3727,0,160}-{1,2698,3729,0,160}-{1,2700,3731,0,160}-{1,2708,3728,0,160}-{1,2725,3731,0,160}-{1,2721,3730,0,160}-{1,2719,3733,0,160}-{1,2714,3733,0,160}-{1,2712,3732,0,160}-" + }, + { + "item_id": "444", + "loc_data": "{1,3231,3739,0,250}-{1,3236,3741,0,250}-{1,3195,9821,0,150}-" + }, + { + "item_id": "480", + "loc_data": "{1,3298,3313,0,30}-" + }, + { + "item_id": "526", + "loc_data": "{1,2510,3080,0,30}-{1,2516,3084,0,30}-{1,2509,3090,0,30}-{1,2512,3084,0,30}-{1,2510,3084,0,30}-{1,2505,3114,0,30}-{1,2507,3116,0,30}-{1,2503,3118,0,30}-{1,2510,3114,0,30}-{1,3238,3606,0,100}-{1,3236,3605,0,100}-{1,3238,3603,0,100}-{1,3240,3603,0,100}-{1,3242,3604,0,100}-{1,3244,3611,0,100}-{1,3247,3614,0,100}-{1,3238,3610,0,100}-{1,3238,3608,0,100}-{1,3232,3948,0,100}-{1,3237,3938,0,100}-{1,3250,3952,0,100}-{1,2966,9772,0,90}-{1,2968,9771,0,90}-{1,2831,9766,0,90}-{1,2829,9764,0,90}-{1,2917,9796,0,90}-{1,2914,9796,0,90}-{1,2910,9797,0,90}-{1,2908,9794,0,90}-{1,2926,9801,0,90}-{1,2924,9801,0,90}-{1,2924,9804,0,90}-{1,2927,9805,0,90}-{1,2929,9807,0,90}-{1,2938,9792,0,90}-{1,2938,9796,0,90}-{1,2935,9799,0,90}-{1,2930,9794,0,90}-{1,2932,9792,0,90}-{1,2903,9826,0,90}-{1,2906,9823,0,90}-{1,2906,9825,0,90}-{1,2907,9824,0,90}-{1,2910,9825,0,90}-{1,3101,9825,0,90}-{1,3107,9823,0,90}-{1,3109,9823,0,90}-{1,3110,9825,0,90}-{1,3138,9880,0,90}-{1,3141,9879,0,90}-{1,3142,9880,0,90}-{1,3143,9878,0,90}-{1,3097,9902,0,90}-{1,3094,9907,0,90}-{1,3093,9884,0,90}-{1,3098,9886,0,90}-{1,3093,9879,0,90}-{1,3122,9891,0,90}-{1,3116,9891,0,90}-{1,3119,9894,0,90}-{1,3120,9894,0,90}-{1,3103,9953,0,90}-{1,3104,9950,0,90}-{1,3110,9952,0,90}-{1,3111,9956,0,90}-{1,3110,9958,0,90}-{1,3111,9959,0,90}-{1,3116,9950,0,90}-{1,3127,9957,0,90}-" + }, + { + "item_id": "528", + "loc_data": "{1,3211,3822,0,60}-{1,3212,3819,0,60}-{1,3217,3816,0,60}-{1,3218,3813,0,60}-{1,3182,3848,0,50}-{1,3178,3851,0,60}-{1,3179,3853,0,60}-{1,3185,3857,0,60}-{1,3187,3853,0,60}-" + }, + { + "item_id": "542", + "loc_data": "{1,3059,3488,1,90}-" + }, + { + "item_id": "544", + "loc_data": "{1,3059,3487,1,90}-" + }, + { + "item_id": "554", + "loc_data": "{1,3303,3311,0,30}-{1,3026,3636,0,200}-" + }, + { + "item_id": "555", + "loc_data": "{1,3297,3316,0,30}-{1,3028,3636,0,200}-{3,2960,3899,0,200}-" + }, + { + "item_id": "556", + "loc_data": "{1,2938,3158,0,110}-{1,3030,3636,0,200}-" + }, + { + "item_id": "557", + "loc_data": "{1,3032,3636,0,200}-" + }, + { + "item_id": "558", + "loc_data": "{1,3206,3208,0,40}-{1,3023,3640,0,200}-" + }, + { + "item_id": "559", + "loc_data": "{1,3233,3573,0,200}-{1,3234,3578,0,200}-{1,3230,3582,0,200}-{1,3021,3637,0,200}-{1,3089,3866,0,30}-" + }, + { + "item_id": "561", + "loc_data": "{1,2671,3737,0,200}-{1,2672,3738,0,200}-" + }, + { + "item_id": "562", + "loc_data": "{1,3021,3640,0,200}-{1,3137,3833,0,200}-{1,3139,3814,0,200}-{1,3145,3814,0,200}-{1,3144,3826,0,200}-{1,3149,3823,0,200}-{1,3151,3831,0,200}-" + }, + { + "item_id": "564", + "loc_data": "{3,2947,3898,0,200}-" + }, + { + "item_id": "590", + "loc_data": "{1,2368,3135,0,140}-{1,2431,3072,0,140}-{1,3112,3369,2,140}-{1,3209,3734,0,100}-" + }, + { + "item_id": "677", + "loc_data": "{1,3369,3378,0,150}-" + }, + { + "item_id": "687", + "loc_data": "{1,2655,3424,0,80}-{1,2665,3424,0,80}-{1,2669,3423,0,80}-{1,2668,3419,0,80}-{1,2671,3420,0,80}-{1,2677,3423,0,80}-{1,2676,3425,0,80}-{1,2676,3422,0,80}-{1,2679,3424,0,80}-{1,2678,3426,0,80}-{1,2679,3423,0,80}-{1,2680,3424,0,80}-{1,2672,3427,0,80}-{1,2676,3430,0,80}-{1,2673,3428,0,80}-{1,2670,3437,0,80}-{1,2649,9854,0,80}-{1,2643,9853,0,80}-{1,2644,9851,0,80}-" + }, + { + "item_id": "708", + "loc_data": "{1,3368,9770,0,30}-{1,3364,9764,0,30}-{1,3363,9831,0,30}-{1,3370,9826,0,30}-" + }, + { + "item_id": "712", + "loc_data": "{1,2887,3412,0,30}-{1,2903,3441,0,30}-" + }, + { + "item_id": "767", + "loc_data": "{1,3245,3385,1,50}-{1,3243,3383,1,50}-" + }, + { + "item_id": "882", + "loc_data": "{1,3205,3227,0,140}-{1,2957,3205,0,30}-{1,2944,3332,0,30}-{1,3104,3599,0,100}-{1,3103,3596,0,100}-{1,3100,3593,0,100}-{1,3096,3595,0,100}-{1,3094,3598,0,100}-{1,3100,3609,0,100}-{1,3104,3610,0,100}-{1,3107,3611,0,100}-{1,3108,3603,0,100}-{1,3135,9916,0,140}-{3,3130,9903,0,140}-" + }, + { + "item_id": "946", + "loc_data": "{1,2903,3148,0,80}-{1,3205,3212,0,80}-{1,3224,3202,0,80}-{1,3218,3416,1,90}-{1,2820,3450,0,90}-{1,3106,3956,0,60}-{1,2566,9526,0,30}-{1,3215,9625,0,80}-{1,3218,9887,0,33}-{1,2700,3407,0,100}-" + }, + { + "item_id": "952", + "loc_data": "{1,3572,3312,0,30}-{1,3571,3310,0,30}-{1,3120,3359,0,110}-{1,2566,3330,0,100}-{1,2981,3370,0,90}-{1,3218,3412,1,30}-{1,1951,4964,0,30}-" + }, + { + "item_id": "954", + "loc_data": "{1,2094,3152,0,150}-{1,2785,3279,0,150}-{1,2786,3287,0,150}-{1,2786,3286,0,150}-" + }, + { + "item_id": "960", + "loc_data": "{1,2851,3239,0,160}-{1,2847,3238,0,160}-{1,2845,3232,0,160}-{1,2856,3231,0,160}-{1,2857,3236,0,160}-{1,2846,3384,0,160}-{1,2848,3383,0,160}-{1,2550,3575,0,200}-{1,2553,3576,0,200}-{1,2554,3575,0,200}-{1,2556,3573,0,200}-{1,3216,3665,0,200}-{1,3224,3668,0,200}-{1,3245,3678,0,200}-{1,3230,3686,0,200}-{1,3216,3677,0,200}-{1,3219,3680,0,200}-" + }, + { + "item_id": "966", + "loc_data": "{1,3237,3696,0,150}-" + }, + { + "item_id": "970", + "loc_data": "{1,3290,3033,1,90}-" + }, + { + "item_id": "983", + "loc_data": "{1,3131,9862,0,90}-" + }, + { + "item_id": "995", + "loc_data": "{2,3234,3560,0,100}-{2,3106,3547,0,100}-{1,3104,3558,0,100}-{1,3106,3534,0,100}-{2,3101,3564,0,100}-{4,3103,3579,0,100}-{384,3224,3830,0,50}-{384,3220,3824,0,50}-{1,2909,9800,0,150}-{4,2912,9801,0,150}-{8,2910,9803,0,150}-{5,2907,9807,0,150}-{6,2913,9806,0,150}-{1,2922,9820,0,150}-{1,2934,9834,0,150}-{1,2917,9850,0,150}-{1,2914,9849,0,150}-{3,3195,9834,0,150}-{4,3195,9820,0,150}-{66,3191,9821,0,150}-{56,3190,9819,0,150}-{26,3188,9819,0,150}-{26,3188,9820,0,150}-{35,3189,9819,0,150}-{4,3088,9898,0,150}-{1,3088,9899,0,150}-{1,3091,9899,0,150}-" + }, + { + "item_id": "1005", + "loc_data": "{1,3014,3227,0,30}-{1,3009,3204,0,30}-" + }, + { + "item_id": "1009", + "loc_data": "{1,3122,9881,0,30}-" + }, + { + "item_id": "1059", + "loc_data": "{1,3148,3177,0,30}-{1,3242,3385,1,90}-{1,3097,3486,0,90}-" + }, + { + "item_id": "1061", + "loc_data": "{1,3111,3159,0,190}-{1,3112,3155,0,100}-{1,3302,3190,0,30}-{1,3244,3386,1,190}-{1,3208,9620,0,190}-{1,3210,9615,0,190}-" + }, + { + "item_id": "1069", + "loc_data": "{1,3249,3740,0,90}-" + }, + { + "item_id": "1119", + "loc_data": "{1,3084,3859,0,60}-" + }, + { + "item_id": "1137", + "loc_data": "{1,3242,3688,0,150}-" + }, + { + "item_id": "1139", + "loc_data": "{1,3122,3360,0,190}-" + }, + { + "item_id": "1171", + "loc_data": "{1,3217,3514,0,30}-" + }, + { + "item_id": "1191", + "loc_data": "{1,3250,3797,0,150}-" + }, + { + "item_id": "1203", + "loc_data": "{1,3248,3245,0,180}-{1,3242,3383,1,240}-{1,3216,3695,0,150}-" + }, + { + "item_id": "1205", + "loc_data": "{1,3213,3216,1,190}-" + }, + { + "item_id": "1207", + "loc_data": "{1,3213,3682,0,100}-" + }, + { + "item_id": "1217", + "loc_data": "{1,3180,3821,0,60}-" + }, + { + "item_id": "1265", + "loc_data": "{1,3229,3218,2,100}-{1,2963,3216,0,30}-{1,3081,3429,0,50}-{1,3288,9442,0,90}-{1,3288,9431,0,90}-" + }, + { + "item_id": "1321", + "loc_data": "{1,2965,3211,1,30}-" + }, + { + "item_id": "1351", + "loc_data": "{1,2795,3161,0,240}-{1,2970,3376,1,30}-" + }, + { + "item_id": "1385", + "loc_data": "{1,3099,3862,0,131}-" + }, + { + "item_id": "1422", + "loc_data": "{1,3320,3137,0,150}-" + }, + { + "item_id": "1467", + "loc_data": "{1,2784,3289,0,0}-" + }, + { + "item_id": "1469", + "loc_data": "{1,2766,3277,0,100}-{1,2766,3289,0,100}-" + }, + { + "item_id": "1510", + "loc_data": "{1,2576,3334,0,100}-" + }, + { + "item_id": "1511", + "loc_data": "{1,3106,3160,0,160}-{1,3106,3159,0,160}-{1,3105,3159,0,160}-{1,3205,3226,2,160}-{1,3205,3224,2,160}-{1,3208,3225,2,160}-{1,3209,3224,2,160}-{1,2958,3205,0,30}-{1,2959,3205,0,30}-" + }, + { + "item_id": "1523", + "loc_data": "{1,2614,9570,0,30}-" + }, + { + "item_id": "1550", + "loc_data": "{1,2714,3478,0,30}-" + }, + { + "item_id": "1573", + "loc_data": "{1,2559,2975,0,10}-{1,2560,2974,0,10}-{1,2561,2973,0,10}-{1,2561,2976,0,10}-{1,2740,3637,0,30}-{1,2736,3638,0,30}-{1,2735,3636,0,30}-{1,2743,3636,0,30}-{1,2739,3634,0,30}-{1,2743,3640,0,30}-{1,2741,3639,0,30}-{1,2736,3641,0,30}-{1,2738,3641,0,30}-{1,2734,3640,0,30}-{1,2738,3636,0,30}-" + }, + { + "item_id": "1590", + "loc_data": "{1,2900,9766,0,90}-" + }, + { + "item_id": "1592", + "loc_data": "{1,2935,3283,1,90}-" + }, + { + "item_id": "1595", + "loc_data": "{1,2928,3290,0,90}-" + }, + { + "item_id": "1597", + "loc_data": "{1,2932,3287,1,90}-" + }, + { + "item_id": "1599", + "loc_data": "{1,2931,3287,1,90}-" + }, + { + "item_id": "1607", + "loc_data": "{1,2679,3740,0,144}-{1,3169,3887,0,144}-{1,3169,3887,0,144}-" + }, + { + "item_id": "1641", + "loc_data": "{1,3196,9822,0,150}-" + }, + { + "item_id": "1654", + "loc_data": "{1,3192,9821,0,150}-" + }, + { + "item_id": "1734", + "loc_data": "{1,3286,3491,0,50}-" + }, + { + "item_id": "1735", + "loc_data": "{1,2930,3285,1,90}-{1,3192,3272,0,140}-{1,3152,3306,0,30}-{1,3126,3356,0,140}-" + }, + { + "item_id": "1755", + "loc_data": "{1,2935,3286,0,90}-" + }, + { + "item_id": "1785", + "loc_data": "{1,2822,3355,0,150}-" + }, + { + "item_id": "1856", + "loc_data": "{1,2638,3292,0,150}-" + }, + { + "item_id": "1887", + "loc_data": "{1,3141,3452,1,90}-" + }, + { + "item_id": "1913", + "loc_data": "{1,2863,9875,0,44}-{1,2861,9878,0,44}-" + }, + { + "item_id": "1917", + "loc_data": "{1,3286,3033,1,90}-{1,2799,3156,0,150}-{1,2796,3165,0,150}-{1,3049,3257,0,150}-{1,3080,3438,0,45}-{1,3077,3439,0,30}-{1,3077,3443,0,30}-" + }, + { + "item_id": "1919", + "loc_data": "{1,2798,3156,0,150}-{1,2799,3155,0,150}-{1,2795,3160,0,150}-{1,2798,3160,0,150}-{1,2798,3161,0,150}-{1,2795,3165,0,150}-{1,2794,3165,0,150}-" + }, + { + "item_id": "1921", + "loc_data": "{1,3291,3034,0,90}-" + }, + { + "item_id": "1923", + "loc_data": "{1,3208,3214,0,80}-{1,3140,3452,1,90}-" + }, + { + "item_id": "1925", + "loc_data": "{1,2428,3079,0,80}-{1,2428,3080,0,80}-{1,2371,3128,0,80}-{1,2371,3127,0,80}-{1,3307,3195,0,30}-{1,3225,3294,0,80}-{1,3026,3289,0,80}-{1,3121,3359,0,60}-{1,2564,3332,0,100}-{1,3221,3497,1,80}-{1,3222,3491,1,80}-{1,2958,3510,0,80}-{1,2958,3510,0,80}-{1,1941,4956,0,30}-{1,3216,9625,0,80}-{1,2633,9908,0,100}-" + }, + { + "item_id": "1927", + "loc_data": "{1,2685,3683,0,174}-" + }, + { + "item_id": "1929", + "loc_data": "{1,2820,3452,0,90}-{1,2823,3449,0,90}-" + }, + { + "item_id": "1931", + "loc_data": "{1,3209,3214,0,80}-{1,3166,3310,0,90}-{1,3144,3449,2,90}-" + }, + { + "item_id": "1935", + "loc_data": "{1,2905,3146,0,80}-{1,3211,3212,0,80}-{1,2936,3292,0,90}-{1,3142,3447,2,90}-{1,3211,9625,0,80}-" + }, + { + "item_id": "1939", + "loc_data": "{1,3193,3181,0,150}-{1,3194,3168,0,150}-{1,3191,3162,0,150}-{1,3189,3163,0,150}-{1,3185,3161,0,150}-{1,3182,3165,0,150}-{1,3172,3166,0,150}-{1,3170,3167,0,150}-{1,3164,3169,0,150}-{1,3171,3177,0,150}-{1,3173,3178,0,150}-{1,3164,3180,0,150}-{1,3165,3187,0,150}-{1,3171,3191,0,150}-{1,3178,3190,0,150}-{1,3181,3193,0,150}-{1,3182,3181,0,150}-{1,3493,3408,0,30}-{1,3494,3402,0,30}-{1,3494,3396,0,30}-{1,3499,3401,0,30}-" + }, + { + "item_id": "1944", + "loc_data": "{1,3191,3276,0,35}-{1,3229,3299,0,35}-{1,3226,3301,0,35}-{1,3015,3295,0,30}-{1,3016,3295,0,30}-{1,2853,3370,0,35}-{1,2852,3369,0,35}-{1,2851,3372,0,35}-{1,2453,4476,0,1}-" + }, + { + "item_id": "1955", + "loc_data": "{1,3141,3447,1,90}-{1,3140,3447,1,90}-{1,3141,3447,2,90}-" + }, + { + "item_id": "1963", + "loc_data": "{1,2907,3146,0,150}-{1,3009,3207,0,150}-" + }, + { + "item_id": "1965", + "loc_data": "{1,3217,9622,0,90}-" + }, + { + "item_id": "1971", + "loc_data": "{1,2843,3369,0,160}-" + }, + { + "item_id": "1973", + "loc_data": "{1,3143,3453,0,40}-{1,2384,4440,0,40}-" + }, + { + "item_id": "1982", + "loc_data": "{1,2584,2966,0,10}-{1,3085,3261,0,150}-{1,3039,3706,0,15}-" + }, + { + "item_id": "1985", + "loc_data": "{1,3083,3260,0,150}-{1,3039,3707,0,15}-" + }, + { + "item_id": "1987", + "loc_data": "{1,3144,3450,2,90}-{1,3237,9761,0,90}-" + }, + { + "item_id": "1993", + "loc_data": "{1,3291,3033,1,90}-" + }, + { + "item_id": "2025", + "loc_data": "{1,2449,3510,1,90}-" + }, + { + "item_id": "2026", + "loc_data": "{1,2483,3482,1,90}-{1,2489,3489,1,90}-" + }, + { + "item_id": "2126", + "loc_data": "{1,2661,3478,0,100}-{1,2638,3480,0,100}-{1,2632,3492,0,100}-{1,2648,3498,0,100}-{1,2669,3497,0,100}-" + }, + { + "item_id": "2128", + "loc_data": "{1,2648,2963,0,10}-{1,2647,2956,0,10}-{1,2638,2949,0,10}-" + }, + { + "item_id": "2140", + "loc_data": "{1,2971,3382,1,30}-" + }, + { + "item_id": "2142", + "loc_data": "{1,3080,3443,0,30}-{1,3077,3441,0,30}-" + }, + { + "item_id": "2150", + "loc_data": "{1,2907,3393,0,30}-{1,2903,3400,0,30}-{1,2908,3410,0,30}-{1,2418,3511,0,30}-{1,2417,3512,0,30}-{1,2416,3512,0,30}-{1,2412,3511,0,30}-{1,2411,3519,0,30}-{1,2415,3518,0,30}-{1,2417,3516,0,30}-{1,2417,3515,0,30}-{1,2421,3519,0,30}-{1,2424,3517,0,30}-{1,2424,3514,0,30}-{1,2428,3510,0,30}-{1,2407,3516,0,30}-" + }, + { + "item_id": "2162", + "loc_data": "{1,2896,3414,0,30}-{1,2425,3515,0,30}-{1,2415,3517,0,30}-{1,2414,3518,0,30}-{1,2419,3511,0,30}-{1,2415,3511,0,30}-{1,2414,3510,0,30}-{1,2427,3508,0,30}-{1,2426,3507,0,30}-{1,2408,3518,0,30}-" + }, + { + "item_id": "2313", + "loc_data": "{1,2820,3455,0,90}-{1,3142,3447,1,90}-{1,3222,3494,0,90}-" + }, + { + "item_id": "2333", + "loc_data": "{1,3042,3952,0,100}-" + }, + { + "item_id": "2347", + "loc_data": "{1,2934,3286,0,90}-{1,2975,3368,1,30}-{1,2579,3463,0,40}-{1,1953,4974,0,30}-" + }, + { + "item_id": "2357", + "loc_data": "{1,3192,9822,0,150}-" + }, + { + "item_id": "2398", + "loc_data": "{1,2517,3049,0,50}-{1,2511,3045,0,50}-" + }, + { + "item_id": "2407", + "loc_data": "{1,2935,3460,0,5}-" + }, + { + "item_id": "2408", + "loc_data": "{1,2903,3471,0,5}-" + }, + { + "item_id": "2957", + "loc_data": "{1,3443,9742,0,100}-{1,3443,9742,1,100}-" + }, + { + "item_id": "2964", + "loc_data": "{1,3437,3337,0,100}-" + }, + { + "item_id": "3109", + "loc_data": "{1,2893,3565,0,2}-" + }, + { + "item_id": "3110", + "loc_data": "{1,2893,3564,0,2}-" + }, + { + "item_id": "3111", + "loc_data": "{1,2893,3561,0,2}-" + }, + { + "item_id": "3112", + "loc_data": "{1,2893,3563,0,2}-" + }, + { + "item_id": "3113", + "loc_data": "{1,2893,3562,0,2}-" + }, + { + "item_id": "3138", + "loc_data": "{1,3463,9478,2,45}-{1,3461,9480,2,45}-{1,3461,9482,2,45}-{1,3461,9484,2,45}-" + }, + { + "item_id": "3711", + "loc_data": "{1,2660,3676,0,196}-" + }, + { + "item_id": "3803", + "loc_data": "{1,2658,3676,0,174}-" + }, + { + "item_id": "3805", + "loc_data": "{1,2659,3676,0,196}-" + }, + { + "item_id": "4199", + "loc_data": "{1,3492,3474,0,0}-" + }, + { + "item_id": "4615", + "loc_data": "{1,3479,3092,0,0}-" + }, + { + "item_id": "4619", + "loc_data": "{1,2713,4913,0,2}-" + }, + { + "item_id": "4707", + "loc_data": "{1,3571,3312,0,40}-" + }, + { + "item_id": "4838", + "loc_data": "{1,2593,3103,1,40}-" + }, + { + "item_id": "5008", + "loc_data": "{1,3230,9609,0,44}-" + }, + { + "item_id": "5523", + "loc_data": "{1,2935,3282,1,90}-" + }, + { + "item_id": "5586", + "loc_data": "{1,2473,4941,0,90}-" + }, + { + "item_id": "6291", + "loc_data": "{1,2681,3111,0,30}-{1,2673,3112,0,30}-{1,2674,3094,0,30}-{1,2671,3089,0,30}-" + }, + { + "item_id": "6662", + "loc_data": "{1,2984,3112,0,90}-" + }, + { + "item_id": "6663", + "loc_data": "{1,2984,3114,0,90}-" + }, + { + "item_id": "7510", + "loc_data": "{1,2867,9875,0,44}-" + }, + { + "item_id": "11065", + "loc_data": "{1,2928,3289,0,90}-" + }, + { + "item_id": "12494", + "loc_data": "{1,2762,2973,0,60}-" + } +] \ No newline at end of file diff --git a/Server/data/configs/interface_configs.json b/Server/data/configs/interface_configs.json new file mode 100644 index 0000000..9508700 --- /dev/null +++ b/Server/data/configs/interface_configs.json @@ -0,0 +1,920 @@ +[ + { + "id": "5", + "interfaceType": "8", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "12", + "interfaceType": "0", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "13", + "interfaceType": "0", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "15", + "interfaceType": "3", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "24", + "interfaceType": "8", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "34", + "interfaceType": "8", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "38", + "interfaceType": "8", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "42", + "interfaceType": "8", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "46", + "interfaceType": "8", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "57", + "interfaceType": "8", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "58", + "interfaceType": "8", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "59", + "interfaceType": "8", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "64", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "65", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "66", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "67", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "68", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "69", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "70", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "71", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "74", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "92", + "interfaceType": "2", + "walkable": "true", + "tabIndex": "0" + }, + { + "id": "94", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "96", + "interfaceType": "1", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "98", + "interfaceType": "1", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "102", + "interfaceType": "0", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "107", + "interfaceType": "3", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "115", + "interfaceType": "1", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "118", + "interfaceType": "1", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "126", + "interfaceType": "1", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "131", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "137", + "interfaceType": "7", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "139", + "interfaceType": "8", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "140", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "149", + "interfaceType": "2", + "walkable": "true", + "tabIndex": "3" + }, + { + "id": "169", + "interfaceType": "8", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "172", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "173", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "174", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "175", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "176", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "177", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "182", + "interfaceType": "2", + "walkable": "true", + "tabIndex": "14" + }, + { + "id": "187", + "interfaceType": "2", + "walkable": "true", + "tabIndex": "13" + }, + { + "id": "192", + "interfaceType": "2", + "walkable": "true", + "tabIndex": "6" + }, + { + "id": "193", + "interfaceType": "2", + "walkable": "true", + "tabIndex": "6" + }, + { + "id": "194", + "interfaceType": "8", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "195", + "interfaceType": "8", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "196", + "interfaceType": "8", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "198", + "interfaceType": "8", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "209", + "interfaceType": "8", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "210", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "211", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "212", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "213", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "228", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "230", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "232", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "234", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "236", + "interfaceType": "3", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "240", + "interfaceType": "3", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "241", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "242", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "243", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "244", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "245", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "246", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "247", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "248", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "256", + "interfaceType": "8", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "259", + "interfaceType": "2", + "walkable": "true", + "tabIndex": "2" + }, + { + "id": "261", + "interfaceType": "2", + "walkable": "true", + "tabIndex": "11" + }, + { + "id": "271", + "interfaceType": "2", + "walkable": "true", + "tabIndex": "5" + }, + { + "id": "274", + "interfaceType": "2", + "walkable": "true", + "tabIndex": "2" + }, + { + "id": "303", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "304", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "305", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "306", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "307", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "309", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "311", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "312", + "interfaceType": "7", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "319", + "interfaceType": "0", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "320", + "interfaceType": "2", + "walkable": "true", + "tabIndex": "1" + }, + { + "id": "324", + "interfaceType": "0", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "328", + "interfaceType": "8", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "336", + "interfaceType": "3", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "371", + "interfaceType": "1", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "372", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "373", + "interfaceType": "1", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "377", + "interfaceType": "8", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "380", + "interfaceType": "1", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "381", + "interfaceType": "8", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "387", + "interfaceType": "2", + "walkable": "true", + "tabIndex": "4" + }, + { + "id": "389", + "interfaceType": "6", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "395", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "398", + "interfaceType": "3", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "407", + "interfaceType": "1", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "408", + "interfaceType": "1", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "411", + "interfaceType": "2", + "walkable": "true", + "tabIndex": "4" + }, + { + "id": "418", + "interfaceType": "8", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "421", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "428", + "interfaceType": "8", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "430", + "interfaceType": "2", + "walkable": "true", + "tabIndex": "6" + }, + { + "id": "464", + "interfaceType": "2", + "walkable": "true", + "tabIndex": "12" + }, + { + "id": "482", + "interfaceType": "1", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "485", + "interfaceType": "8", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "486", + "interfaceType": "8", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "487", + "interfaceType": "8", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "488", + "interfaceType": "8", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "498", + "interfaceType": "0", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "516", + "interfaceType": "0", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "519", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "532", + "interfaceType": "8", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "541", + "interfaceType": "1", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "548", + "interfaceType": "5", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "549", + "interfaceType": "5", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "550", + "interfaceType": "2", + "walkable": "true", + "tabIndex": "8" + }, + { + "id": "551", + "interfaceType": "2", + "walkable": "true", + "tabIndex": "9" + }, + { + "id": "553", + "interfaceType": "0", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "582", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "589", + "interfaceType": "2", + "walkable": "true", + "tabIndex": "10" + }, + { + "id": "597", + "interfaceType": "1", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "598", + "interfaceType": "1", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "599", + "interfaceType": "1", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "601", + "interfaceType": "1", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "620", + "interfaceType": "0", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "621", + "interfaceType": "3", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "630", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "638", + "interfaceType": "1", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "644", + "interfaceType": "3", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "648", + "interfaceType": "3", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "653", + "interfaceType": "8", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "656", + "interfaceType": "8", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "660", + "interfaceType": "0", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "662", + "interfaceType": "2", + "walkable": "true", + "tabIndex": "7" + }, + { + "id": "665", + "interfaceType": "1", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "667", + "interfaceType": "0", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "668", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "670", + "interfaceType": "3", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "695", + "interfaceType": "7", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "698", + "interfaceType": "7", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "701", + "interfaceType": "7", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "703", + "interfaceType": "7", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "706", + "interfaceType": "7", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "711", + "interfaceType": "7", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "735", + "interfaceType": "3", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "740", + "interfaceType": "4", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "746", + "interfaceType": "5", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "755", + "interfaceType": "5", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "763", + "interfaceType": "3", + "walkable": "false", + "tabIndex": "-1" + }, + { + "id": "804", + "interfaceType": "1", + "walkable": "true", + "tabIndex": "-1" + }, + { + "id": "809", + "interfaceType": "8", + "walkable": "true", + "tabIndex": "-1" + } +] diff --git a/Server/data/configs/item_configs.json b/Server/data/configs/item_configs.json new file mode 100644 index 0000000..c7da93a --- /dev/null +++ b/Server/data/configs/item_configs.json @@ -0,0 +1,132116 @@ +[ + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "The body of a Dwarf savaged by Goblins.", + "durability": null, + "name": "Dwarf remains", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "two_handed": "true", + "id": "0" + }, + { + "destroy_message": "I got this from Captain Lawgof.", + "shop_price": "1", + "examine": "Good for repairing a broken cannon.", + "durability": null, + "name": "Toolkit", + "tradeable": "false", + "destroy": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "1" + }, + { + "shop_price": "5", + "ge_buy_limit": "10000", + "examine": "Ammo for the Dwarf Cannon.", + "grand_exchange_price": "381", + "durability": null, + "name": "Cannonball", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2" + }, + { + "shop_price": "1", + "examine": "Construction notes for Dwarf cannon ammo.", + "durability": null, + "name": "Nulodion's notes", + "weight": "0.02", + "archery_ticket_price": "0", + "id": "3" + }, + { + "requirements": "{13,35}", + "shop_price": "5", + "examine": "Used to make cannon ammunition.", + "name": "Ammo mould", + "weight": "4.5", + "archery_ticket_price": "0", + "id": "4" + }, + { + "shop_price": "20", + "examine": "An old note book.", + "durability": null, + "name": "Instruction manual", + "weight": "0.51", + "archery_ticket_price": "0", + "id": "5" + }, + { + "shop_price": "187500", + "ge_buy_limit": "10", + "examine": "The cannon is built on this.", + "grand_exchange_price": "189000", + "durability": null, + "name": "Cannon base", + "tradeable": "true", + "weight": "7", + "archery_ticket_price": "0", + "id": "6" + }, + { + "shop_price": "187500", + "ge_buy_limit": "10", + "grand_exchange_price": "189000", + "durability": null, + "name": "Cannon base", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7" + }, + { + "shop_price": "187500", + "ge_buy_limit": "10", + "examine": "The mounting for the multicannon.", + "grand_exchange_price": "185000", + "durability": null, + "name": "Cannon stand", + "tradeable": "true", + "weight": "7", + "archery_ticket_price": "0", + "id": "8" + }, + { + "shop_price": "187500", + "ge_buy_limit": "10", + "grand_exchange_price": "185000", + "durability": null, + "name": "Cannon stand", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9" + }, + { + "shop_price": "187500", + "ge_buy_limit": "10", + "examine": "The barrels for the multicannon.", + "grand_exchange_price": "187000", + "durability": null, + "name": "Cannon barrels", + "tradeable": "true", + "weight": "7", + "archery_ticket_price": "0", + "id": "10" + }, + { + "shop_price": "187500", + "ge_buy_limit": "10", + "grand_exchange_price": "187000", + "durability": null, + "name": "Cannon barrels", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11" + }, + { + "shop_price": "187500", + "ge_buy_limit": "10", + "examine": "This powers the multicannon.", + "grand_exchange_price": "175200", + "durability": null, + "name": "Cannon furnace", + "tradeable": "true", + "weight": "7", + "archery_ticket_price": "0", + "id": "12" + }, + { + "shop_price": "187500", + "ge_buy_limit": "10", + "grand_exchange_price": "175200", + "durability": null, + "name": "Cannon furnace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13" + }, + { + "shop_price": "1", + "examine": "A metal railing replacement.", + "durability": null, + "name": "Railing", + "archery_ticket_price": "0", + "id": "14" + }, + { + "examine": "A cloth given to me by Sir Galahad.", + "durability": null, + "name": "Holy table napkin", + "archery_ticket_price": "0", + "id": "15" + }, + { + "examine": "A small tin whistle.", + "durability": null, + "name": "Magic whistle", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "16" + }, + { + "examine": "I wonder what happens when I ring it?", + "durability": null, + "name": "Grail bell", + "archery_ticket_price": "0", + "id": "17" + }, + { + "examine": "It will point the way for me.", + "durability": null, + "name": "Magic gold feather", + "archery_ticket_price": "0", + "id": "18" + }, + { + "examine": "A cog from some machinery.", + "durability": null, + "name": "White cog", + "weight": "1", + "archery_ticket_price": "0", + "id": "20" + }, + { + "examine": "A cog from some machinery.", + "durability": null, + "name": "Black cog", + "weight": "1", + "archery_ticket_price": "0", + "id": "21" + }, + { + "examine": "A cog from some machinery.", + "durability": null, + "name": "Blue cog", + "weight": "1", + "archery_ticket_price": "0", + "id": "22" + }, + { + "examine": "A cog from some machinery.", + "durability": null, + "name": "Red cog", + "weight": "1", + "archery_ticket_price": "0", + "id": "23" + }, + { + "examine": "Doesn't look very tasty.", + "durability": null, + "name": "Rat poison", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "24" + }, + { + "examine": "Wormy.", + "durability": null, + "name": "Red vine worm", + "archery_ticket_price": "0", + "id": "25" + }, + { + "examine": "Hemenster fishing contest trophy.", + "durability": null, + "name": "Fishing trophy", + "archery_ticket_price": "0", + "id": "26" + }, + { + "examine": "Pass to the Hemenster fishing contest.", + "durability": null, + "name": "Fishing pass", + "archery_ticket_price": "0", + "id": "27" + }, + { + "shop_price": "121", + "examine": "Drives away all known 6 legged creatures.", + "durability": null, + "name": "Insect repellent", + "archery_ticket_price": "0", + "id": "28" + }, + { + "examine": "It's a bucket of wax.", + "durability": null, + "name": "Bucket of wax", + "weight": "2.5", + "archery_ticket_price": "0", + "id": "30" + }, + { + "examine": "You shouldn't have this.", + "name": "RDT Slot", + "id": "31" + }, + { + "shop_price": "3", + "examine": "A spooky candle.", + "durability": null, + "name": "Lit black candle", + "archery_ticket_price": "0", + "id": "32" + }, + { + "shop_price": "24", + "examine": "A candle.", + "grand_exchange_price": "104", + "durability": null, + "name": "Lit candle", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "33" + }, + { + "shop_price": "24", + "examine": "A candle.", + "grand_exchange_price": "104", + "durability": null, + "name": "Lit candle", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "34" + }, + { + "shop_price": "200", + "examine": "This used to belong to King Arthur.", + "has_special": "true", + "durability": null, + "weight": "2.2", + "attack_speed": "5", + "weapon_interface": "6", + "render_anim": "2554", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "attack_audios": "2500,2500,2517,2500", + "name": "Excalibur", + "archery_ticket_price": "0", + "id": "35", + "bonuses": "20,29,-2,0,0,0,3,2,1,0,0,25,0,0,0" + }, + { + "shop_price": "24", + "ge_buy_limit": "100", + "examine": "A candle.", + "grand_exchange_price": "119", + "durability": null, + "name": "Candle", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "36" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "119", + "durability": null, + "name": "Candle", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "37" + }, + { + "shop_price": "3", + "examine": "A spooky candle.", + "durability": null, + "name": "Black candle", + "archery_ticket_price": "0", + "id": "38" + }, + { + "shop_price": "10", + "ge_buy_limit": "10000", + "examine": "I can make an arrow with these.", + "grand_exchange_price": "16", + "durability": null, + "name": "Bronze arrowtips", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "39" + }, + { + "shop_price": "26", + "ge_buy_limit": "10000", + "examine": "I can make an arrow with these.", + "grand_exchange_price": "23", + "durability": null, + "name": "Iron arrowtips", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "40" + }, + { + "shop_price": "36", + "ge_buy_limit": "10000", + "examine": "I can make an arrow with these.", + "grand_exchange_price": "63", + "durability": null, + "name": "Steel arrowtips", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "41" + }, + { + "shop_price": "68", + "ge_buy_limit": "10000", + "examine": "I can make an arrow with these.", + "grand_exchange_price": "74", + "durability": null, + "name": "Mithril arrowtips", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "42" + }, + { + "shop_price": "160", + "ge_buy_limit": "10000", + "examine": "I can make an arrow with these.", + "grand_exchange_price": "185", + "durability": null, + "name": "Adamant arrowtips", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "43" + }, + { + "shop_price": "460", + "ge_buy_limit": "10000", + "examine": "I can make an arrow with these.", + "grand_exchange_price": "839", + "durability": null, + "name": "Rune arrowtips", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "44" + }, + { + "ge_buy_limit": "10000", + "examine": "Opal bolt tips.", + "grand_exchange_price": "1", + "durability": null, + "name": "Opal bolt tips", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "45" + }, + { + "ge_buy_limit": "10000", + "examine": "Pearl bolt tips.", + "grand_exchange_price": "5", + "durability": null, + "name": "Pearl bolt tips", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "46" + }, + { + "shop_price": "114", + "ge_buy_limit": "10000", + "examine": "I can make bolts with these.", + "grand_exchange_price": "44", + "durability": null, + "name": "Barb bolttips", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "5", + "id": "47" + }, + { + "ge_buy_limit": "10000", + "examine": "An unstrung longbow; I need a bowstring for this.", + "grand_exchange_price": "14", + "durability": null, + "name": "Longbow (u)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "48" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "14", + "durability": null, + "name": "Longbow (u)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "49" + }, + { + "ge_buy_limit": "10000", + "examine": "I need to find a string for this.", + "grand_exchange_price": "5", + "durability": null, + "name": "Shortbow (u)", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "50" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "5", + "durability": null, + "name": "Shortbow (u)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "51" + }, + { + "ge_buy_limit": "20000", + "examine": "A wooden arrow shaft", + "grand_exchange_price": "21", + "durability": null, + "name": "Arrow shaft", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "52" + }, + { + "ge_buy_limit": "20000", + "examine": "A wooden arrow shaft with flights attached.", + "grand_exchange_price": "56", + "durability": null, + "name": "Headless arrow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "53" + }, + { + "shop_price": "50", + "ge_buy_limit": "10000", + "examine": "An unstrung oak bow; I need a bowstring for this.", + "grand_exchange_price": "7", + "durability": null, + "name": "Oak shortbow (u)", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "54" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "7", + "durability": null, + "name": "Oak shortbow (u)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "55" + }, + { + "ge_buy_limit": "10000", + "examine": "An unstrung oak longbow; I need a bowstring for this.", + "grand_exchange_price": "20", + "durability": null, + "name": "Oak longbow (u)", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "56" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "20", + "durability": null, + "name": "Oak longbow (u)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "57" + }, + { + "shop_price": "64", + "ge_buy_limit": "10000", + "examine": "An unstrung willow longbow; I need a bowstring for this.", + "grand_exchange_price": "46", + "durability": null, + "name": "Willow longbow (u)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "58" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "46", + "durability": null, + "name": "Willow longbow (u)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "59" + }, + { + "shop_price": "16", + "ge_buy_limit": "10000", + "examine": "An unstrung willow shortbow; I need a bowstring for this.", + "grand_exchange_price": "20", + "durability": null, + "name": "Willow shortbow (u)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "60" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "20", + "durability": null, + "name": "Willow shortbow (u)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "61" + }, + { + "ge_buy_limit": "10000", + "examine": "An unstrung maple bow; I need a bowstring for this.", + "grand_exchange_price": "94", + "durability": null, + "name": "Maple longbow (u)", + "tradeable": "true", + "weight": "1.2", + "archery_ticket_price": "0", + "id": "62" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "94", + "durability": null, + "name": "Maple longbow (u)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "63" + }, + { + "ge_buy_limit": "10000", + "examine": "An unstrung maple bow; I need a bowstring for this.", + "grand_exchange_price": "56", + "durability": null, + "name": "Maple shortbow (u)", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "64" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "56", + "durability": null, + "name": "Maple shortbow (u)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "65" + }, + { + "ge_buy_limit": "10000", + "examine": "An unstrung yew longbow; I need a bowstring for this.", + "grand_exchange_price": "468", + "durability": null, + "name": "Yew longbow (u)", + "tradeable": "true", + "weight": "1.32", + "archery_ticket_price": "0", + "id": "66" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "468", + "durability": null, + "name": "Yew longbow (u)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "67" + }, + { + "ge_buy_limit": "10000", + "examine": "An unstrung yew shortbow; I need a bowstring for this.", + "grand_exchange_price": "158", + "durability": null, + "name": "Yew shortbow (u)", + "tradeable": "true", + "weight": "1.32", + "archery_ticket_price": "0", + "id": "68" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "158", + "durability": null, + "name": "Yew shortbow (u)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "69" + }, + { + "shop_price": "931", + "ge_buy_limit": "10000", + "examine": "An unstrung magic longbow; I need a bowstring for this.", + "grand_exchange_price": "1246", + "durability": null, + "name": "Magic longbow (u)", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "70" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "1246", + "durability": null, + "name": "Magic longbow (u)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "71" + }, + { + "shop_price": "890", + "ge_buy_limit": "10000", + "examine": "An unstrung magic shortbow; I need a bowstring for this.", + "grand_exchange_price": "745", + "durability": null, + "name": "Magic shortbow (u)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "72" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "745", + "durability": null, + "name": "Magic shortbow (u)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "73" + }, + { + "remove_head": "true", + "shop_price": "10", + "examine": "A helmet, as worn by the minions of General Khazard.", + "durability": null, + "weight": "2.7", + "destroy": "true", + "equipment_slot": "0", + "destroy_message": "I can borrow another from the armoury near the Fight Arena.", + "name": "Khazard helmet", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "74", + "bonuses": "0,0,0,0,0,4,5,3,0,0,0,0,0,0,0" + }, + { + "shop_price": "12", + "examine": "Armour, as worn by the minions of General Khazard.", + "durability": null, + "weight": "0.5", + "destroy": "true", + "equipment_slot": "4", + "destroy_message": "I can borrow another from the armoury near the Fight Arena.", + "remove_sleeves": "true", + "name": "Khazard armour", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "75", + "bonuses": "0,0,0,0,0,9,11,10,0,0,0,0,0,0,0" + }, + { + "destroy_message": "The lazy guard probably has a spare set...", + "examine": "These keys open the cells at the Khazard Fight Arena. (Fight Arena)", + "durability": null, + "name": "Khazard cell keys", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "76" + }, + { + "destroy_message": "Angor, the Khazard barman, has a stock of Khali brew.", + "shop_price": "5", + "examine": "A bottle of Khazard's worst brew.", + "durability": null, + "name": "Khali brew", + "tradeable": "false", + "destroy": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "77" + }, + { + "destroy_message": "Can only be fired from yew, magic, dark or twisted bows.", + "shop_price": "2", + "examine": "Can only be fired from yew, magic, or dark bows.", + "durability": null, + "name": "Ice arrows", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "78", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,16", + "equipment_slot": "13" + }, + { + "examine": "A lever to open something perhaps?", + "durability": null, + "name": "Lever", + "archery_ticket_price": "0", + "id": "83" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "The power in this staff causes it to vibrate gently.", + "durability": null, + "name": "Staff of armadyl", + "tradeable": "false", + "destroy": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "84", + "render_anim": "2553" + }, + { + "examine": "It catches the light! (Temple of Ikov)", + "durability": null, + "name": "Shiny key", + "archery_ticket_price": "0", + "id": "85" + }, + { + "examine": "An amulet made by Lucien.", + "durability": null, + "name": "Pendant of lucien", + "archery_ticket_price": "0", + "id": "86", + "equipment_slot": "2" + }, + { + "examine": "Yet another amulet.", + "durability": null, + "name": "Armadyl pendant", + "archery_ticket_price": "0", + "id": "87", + "equipment_slot": "2" + }, + { + "examine": "Magic boots that make you lighter than normal.", + "durability": null, + "name": "Boots of lightness", + "weight": "-4.5", + "archery_ticket_price": "0", + "id": "88", + "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", + "equipment_slot": "10" + }, + { + "examine": "Magic boots that make you lighter than normal.", + "durability": null, + "name": "Boots of lightness", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "89", + "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", + "equipment_slot": "10" + }, + { + "examine": "It's very soft!", + "durability": null, + "name": "Child's blanket", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "90" + }, + { + "ge_buy_limit": "100", + "examine": "I need another ingredient to finish this guam potion.", + "grand_exchange_price": "285", + "durability": null, + "name": "Guam potion(unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "91" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "285", + "durability": null, + "name": "Guam potion(unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "92" + }, + { + "ge_buy_limit": "100", + "examine": "I need another ingredient to finish this marrentill potion.", + "grand_exchange_price": "43", + "durability": null, + "name": "Marrentill potion(unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "93" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "43", + "durability": null, + "name": "Marrentill potion(unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "94" + }, + { + "ge_buy_limit": "100", + "examine": "I need another ingredient to finish this tarromin potion.", + "grand_exchange_price": "287", + "durability": null, + "name": "Tarromin potion(unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "95" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "287", + "durability": null, + "name": "Tarromin potion(unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "96" + }, + { + "shop_price": "64", + "ge_buy_limit": "100", + "examine": "I need another ingredient to finish this potion.", + "grand_exchange_price": "435", + "durability": null, + "name": "Harralander potion(unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "97" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "435", + "durability": null, + "name": "Harralander potion(unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "98" + }, + { + "ge_buy_limit": "100", + "examine": "I need another ingredient to finish this ranarr potion.", + "grand_exchange_price": "4823", + "durability": null, + "name": "Ranarr potion(unf)", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "99" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "4823", + "durability": null, + "name": "Ranarr potion(unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "100" + }, + { + "ge_buy_limit": "100", + "examine": "I need another ingredient to finish this irit potion.", + "grand_exchange_price": "2243", + "durability": null, + "name": "Irit potion(unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "101" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2243", + "durability": null, + "name": "Irit potion(unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "102" + }, + { + "ge_buy_limit": "100", + "examine": "I need another ingredient to finish this avantoe potion.", + "grand_exchange_price": "3831", + "durability": null, + "name": "Avantoe potion(unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "103" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3831", + "durability": null, + "name": "Avantoe potion(unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "104" + }, + { + "ge_buy_limit": "100", + "examine": "I need another ingredient to finish this kwuarm potion.", + "grand_exchange_price": "1833", + "durability": null, + "name": "Kwuarm potion(unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "105" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1833", + "durability": null, + "name": "Kwuarm potion(unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "106" + }, + { + "ge_buy_limit": "100", + "examine": "I need another ingredient to finish this cadantine potion.", + "grand_exchange_price": "1844", + "durability": null, + "name": "Cadantine potion(unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "107" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1844", + "durability": null, + "name": "Cadantine potion(unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "108" + }, + { + "ge_buy_limit": "100", + "examine": "I need another ingredient to finish this dwarf weed potion.", + "grand_exchange_price": "6740", + "durability": null, + "name": "Dwarf weed potion(unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "109" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "6740", + "durability": null, + "name": "Dwarf weed potion(unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "110" + }, + { + "ge_buy_limit": "100", + "examine": "I need another ingredient to finish this torstol potion.", + "grand_exchange_price": "14500", + "durability": null, + "name": "Torstol potion(unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "111" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "14500", + "durability": null, + "name": "Torstol potion(unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "112" + }, + { + "shop_price": "780", + "ge_buy_limit": "100", + "examine": "4 doses of Strength potion.", + "grand_exchange_price": "1041", + "durability": null, + "name": "Strength potion(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "113" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1041", + "durability": null, + "name": "Strength potion(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "114" + }, + { + "shop_price": "780", + "ge_buy_limit": "100", + "examine": "3 doses of Strength potion.", + "grand_exchange_price": "812", + "durability": null, + "name": "Strength potion(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "115" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "812", + "durability": null, + "name": "Strength potion(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "116" + }, + { + "shop_price": "780", + "ge_buy_limit": "100", + "examine": "2 doses of Strength potion.", + "grand_exchange_price": "656", + "durability": null, + "name": "Strength potion(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "117" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "656", + "durability": null, + "name": "Strength potion(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "118" + }, + { + "shop_price": "780", + "ge_buy_limit": "100", + "examine": "1 dose of Strength potion.", + "grand_exchange_price": "355", + "durability": null, + "name": "Strength potion(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "119" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "355", + "durability": null, + "name": "Strength potion(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "120" + }, + { + "shop_price": "560", + "ge_buy_limit": "100", + "examine": "3 doses of Attack potion.", + "grand_exchange_price": "195", + "durability": null, + "name": "Attack potion(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "121" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "195", + "durability": null, + "name": "Attack potion(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "122" + }, + { + "shop_price": "560", + "ge_buy_limit": "100", + "examine": "2 doses of Attack potion.", + "grand_exchange_price": "113", + "durability": null, + "name": "Attack potion(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "123" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "113", + "durability": null, + "name": "Attack potion(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "124" + }, + { + "shop_price": "560", + "ge_buy_limit": "100", + "examine": "1 dose of Attack potion.", + "grand_exchange_price": "197", + "durability": null, + "name": "Attack potion(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "125" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "197", + "durability": null, + "name": "Attack potion(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "126" + }, + { + "shop_price": "139", + "ge_buy_limit": "100", + "examine": "3 doses of restore potion.", + "grand_exchange_price": "59", + "durability": null, + "name": "Restore potion(3)", + "tradeable": "true", + "weight": "0.03", + "archery_ticket_price": "0", + "id": "127" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "59", + "durability": null, + "name": "Restore potion(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "128" + }, + { + "shop_price": "139", + "ge_buy_limit": "100", + "examine": "2 doses of restore potion.", + "grand_exchange_price": "35", + "durability": null, + "name": "Restore potion(2)", + "tradeable": "true", + "weight": "0.03", + "archery_ticket_price": "0", + "id": "129" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "35", + "durability": null, + "name": "Restore potion(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "130" + }, + { + "shop_price": "139", + "ge_buy_limit": "100", + "examine": "1 dose of restore potion.", + "grand_exchange_price": "21", + "durability": null, + "name": "Restore potion(1)", + "tradeable": "true", + "weight": "0.03", + "archery_ticket_price": "0", + "id": "131" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "21", + "durability": null, + "name": "Restore potion(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "132" + }, + { + "shop_price": "114", + "ge_buy_limit": "100", + "examine": "3 doses of Defence Potion.", + "grand_exchange_price": "323", + "durability": null, + "name": "Defence potion(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "133" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "323", + "durability": null, + "name": "Defence potion(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "134" + }, + { + "shop_price": "114", + "ge_buy_limit": "100", + "examine": "2 doses of Defence Potion.", + "grand_exchange_price": "247", + "durability": null, + "name": "Defence potion(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "135" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "247", + "durability": null, + "name": "Defence potion(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "136" + }, + { + "shop_price": "114", + "ge_buy_limit": "100", + "examine": "1 dose of Defence Potion.", + "grand_exchange_price": "148", + "durability": null, + "name": "Defence potion(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "137" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "148", + "durability": null, + "name": "Defence potion(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "138" + }, + { + "ge_buy_limit": "100", + "examine": "3 doses of Prayer restore potion.", + "grand_exchange_price": "4134", + "durability": null, + "name": "Prayer potion(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "139" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "4134", + "durability": null, + "name": "Prayer potion(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "140" + }, + { + "ge_buy_limit": "100", + "examine": "2 doses of Prayer restore potion.", + "grand_exchange_price": "2868", + "durability": null, + "name": "Prayer potion(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "141" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2868", + "durability": null, + "name": "Prayer potion(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "142" + }, + { + "ge_buy_limit": "100", + "examine": "1 dose of Prayer restore potion.", + "grand_exchange_price": "1353", + "durability": null, + "name": "Prayer potion(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "143" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1353", + "durability": null, + "name": "Prayer potion(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "144" + }, + { + "ge_buy_limit": "1000", + "examine": "3 doses of super Attack potion.", + "grand_exchange_price": "691", + "durability": null, + "name": "Super attack(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "145" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "691", + "durability": null, + "name": "Super attack(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "146" + }, + { + "ge_buy_limit": "1000", + "examine": "2 doses of super Attack potion.", + "grand_exchange_price": "451", + "durability": null, + "name": "Super attack(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "147" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "451", + "durability": null, + "name": "Super attack(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "148" + }, + { + "ge_buy_limit": "1000", + "examine": "1 dose of super Attack potion.", + "grand_exchange_price": "243", + "durability": null, + "name": "Super attack(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "149" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "243", + "durability": null, + "name": "Super attack(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "150" + }, + { + "ge_buy_limit": "100", + "examine": "3 doses of Fishing potion.", + "grand_exchange_price": "40", + "durability": null, + "name": "Fishing potion(3)", + "tradeable": "true", + "weight": "0.03", + "archery_ticket_price": "0", + "id": "151" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "40", + "durability": null, + "name": "Fishing potion(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "152" + }, + { + "ge_buy_limit": "100", + "examine": "2 doses of Fishing potion.", + "grand_exchange_price": "56", + "durability": null, + "name": "Fishing potion(2)", + "tradeable": "true", + "weight": "0.03", + "archery_ticket_price": "0", + "id": "153" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "56", + "durability": null, + "name": "Fishing potion(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "154" + }, + { + "ge_buy_limit": "100", + "examine": "1 dose of Fishing potion.", + "grand_exchange_price": "87", + "durability": null, + "name": "Fishing potion(1)", + "tradeable": "true", + "weight": "0.03", + "archery_ticket_price": "0", + "id": "155" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "87", + "durability": null, + "name": "Fishing potion(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "156" + }, + { + "ge_buy_limit": "1000", + "examine": "3 doses of super Strength potion.", + "grand_exchange_price": "1679", + "durability": null, + "name": "Super strength(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "157" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1679", + "durability": null, + "name": "Super strength(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "158" + }, + { + "ge_buy_limit": "1000", + "examine": "2 doses of super Strength potion.", + "grand_exchange_price": "1164", + "durability": null, + "name": "Super strength(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "159" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1164", + "durability": null, + "name": "Super strength(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "160" + }, + { + "ge_buy_limit": "1000", + "examine": "1 dose of super Strength potion.", + "grand_exchange_price": "603", + "durability": null, + "name": "Super strength(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "161" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "603", + "durability": null, + "name": "Super strength(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "162" + }, + { + "ge_buy_limit": "1000", + "examine": "3 doses of super Defence potion.", + "grand_exchange_price": "113", + "durability": null, + "name": "Super defence(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "163" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "113", + "durability": null, + "name": "Super defence(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "164" + }, + { + "ge_buy_limit": "1000", + "examine": "2 doses of super Defence potion.", + "grand_exchange_price": "65", + "durability": null, + "name": "Super defence(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "165" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "65", + "durability": null, + "name": "Super defence(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "166" + }, + { + "ge_buy_limit": "1000", + "examine": "1 dose of super Defence potion.", + "grand_exchange_price": "41", + "durability": null, + "name": "Super defence(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "167" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "41", + "durability": null, + "name": "Super defence(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "168" + }, + { + "ge_buy_limit": "1000", + "examine": "3 doses of ranging potion.", + "grand_exchange_price": "6224", + "durability": null, + "name": "Ranging potion(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "169" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "6224", + "durability": null, + "name": "Ranging potion(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "170" + }, + { + "ge_buy_limit": "1000", + "examine": "2 doses of ranging potion.", + "grand_exchange_price": "4330", + "durability": null, + "name": "Ranging potion(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "171" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "4330", + "durability": null, + "name": "Ranging potion(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "172" + }, + { + "ge_buy_limit": "1000", + "examine": "1 dose of ranging potion.", + "grand_exchange_price": "2068", + "durability": null, + "name": "Ranging potion(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "173" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "2068", + "durability": null, + "name": "Ranging potion(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "174" + }, + { + "shop_price": "375", + "ge_buy_limit": "1000", + "examine": "3 doses of antipoison potion.", + "grand_exchange_price": "1239", + "durability": null, + "name": "Antipoison(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "175" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1239", + "durability": null, + "name": "Antipoison(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "176" + }, + { + "shop_price": "375", + "ge_buy_limit": "1000", + "examine": "2 doses of antipoison potion.", + "grand_exchange_price": "822", + "durability": null, + "name": "Antipoison(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "177" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "822", + "durability": null, + "name": "Antipoison(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "178" + }, + { + "shop_price": "375", + "ge_buy_limit": "1000", + "examine": "1 dose of antipoison potion.", + "grand_exchange_price": "460", + "durability": null, + "name": "Antipoison(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "179" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "460", + "durability": null, + "name": "Antipoison(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "180" + }, + { + "ge_buy_limit": "1000", + "examine": "3 doses of super anti poison potion.", + "grand_exchange_price": "872", + "durability": null, + "name": "Super antipoison(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "181" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "872", + "durability": null, + "name": "Super antipoison(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "182" + }, + { + "ge_buy_limit": "1000", + "examine": "2 doses of super anti poison potion.", + "grand_exchange_price": "509", + "durability": null, + "name": "Super antipoison(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "183" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "509", + "durability": null, + "name": "Super antipoison(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "184" + }, + { + "ge_buy_limit": "1000", + "examine": "1 dose of super anti poison potion.", + "grand_exchange_price": "366", + "durability": null, + "name": "Super antipoison(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "185" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "366", + "durability": null, + "name": "Super antipoison(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "186" + }, + { + "ge_buy_limit": "1000", + "examine": "For use on daggers and projectiles.", + "grand_exchange_price": "33", + "durability": null, + "name": "Weapon poison", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "187" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "33", + "durability": null, + "name": "Weapon poison", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "188" + }, + { + "ge_buy_limit": "1000", + "examine": "3 doses of Zamorak brew.", + "grand_exchange_price": "1818", + "durability": null, + "name": "Zamorak brew(3)", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "189" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1818", + "durability": null, + "name": "Zamorak brew(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "190" + }, + { + "ge_buy_limit": "1000", + "examine": "2 doses of Zamorak brew.", + "grand_exchange_price": "1004", + "durability": null, + "name": "Zamorak brew(2)", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "191" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1004", + "durability": null, + "name": "Zamorak brew(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "192" + }, + { + "ge_buy_limit": "1000", + "examine": "1 dose of Zamorak brew.", + "grand_exchange_price": "1175", + "durability": null, + "name": "Zamorak brew(1)", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "193" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1175", + "durability": null, + "name": "Zamorak brew(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "194" + }, + { + "ge_buy_limit": "100", + "examine": "This is meant to be good for spots.", + "grand_exchange_price": "117", + "durability": null, + "name": "Potion", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "195" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "117", + "durability": null, + "name": "Potion", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "196" + }, + { + "shop_price": "39", + "ge_buy_limit": "100", + "examine": "Stankers gives out these strange cocktails for free.", + "grand_exchange_price": "124", + "durability": null, + "name": "Poison chalice", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "197" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "124", + "durability": null, + "name": "Poison chalice", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "198" + }, + { + "requirements": "{3,15}", + "ge_buy_limit": "10000", + "examine": "I need to clean this herb before I can use it.", + "grand_exchange_price": "150", + "durability": null, + "name": "Grimy guam", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "199" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "155", + "durability": null, + "name": "Grimy guam", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "200" + }, + { + "requirements": "{5,15}", + "ge_buy_limit": "10000", + "examine": "I need to clean this herb before I can use it.", + "grand_exchange_price": "150", + "durability": null, + "name": "Grimy marrentill", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "201" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "26", + "durability": null, + "name": "Grimy marrentill", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "202" + }, + { + "requirements": "{11,15}", + "ge_buy_limit": "10000", + "examine": "I need to clean this herb before I can use it.", + "grand_exchange_price": "150", + "durability": null, + "name": "Grimy tarromin", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "203" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "151", + "durability": null, + "name": "Grimy tarromin", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "204" + }, + { + "requirements": "{20,15}", + "ge_buy_limit": "10000", + "examine": "I need to clean this herb before I can use it.", + "grand_exchange_price": "300", + "durability": null, + "name": "Grimy harralander", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "205" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "275", + "durability": null, + "name": "Grimy harralander", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "206" + }, + { + "requirements": "{15,25}", + "ge_buy_limit": "10000", + "examine": "I need to clean this herb before I can use it.", + "grand_exchange_price": "1300", + "durability": null, + "name": "Grimy ranarr", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "207" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "4909", + "durability": null, + "name": "Grimy ranarr", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "208" + }, + { + "requirements": "{15,40}", + "ge_buy_limit": "10000", + "examine": "I need to clean this herb before I can use it.", + "grand_exchange_price": "900", + "durability": null, + "name": "Grimy irit", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "209" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "2034", + "durability": null, + "name": "Grimy irit", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "210" + }, + { + "requirements": "{15,48}", + "ge_buy_limit": "10000", + "examine": "I need to clean this herb before I can use it.", + "grand_exchange_price": "500", + "durability": null, + "name": "Grimy avantoe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "211" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "3789", + "durability": null, + "name": "Grimy avantoe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "212" + }, + { + "requirements": "{15,54}", + "ge_buy_limit": "10000", + "examine": "I need to clean this herb before I can use it.", + "grand_exchange_price": "900", + "durability": null, + "name": "Grimy kwuarm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "213" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "1665", + "durability": null, + "name": "Grimy kwuarm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "214" + }, + { + "requirements": "{15,65}", + "ge_buy_limit": "10000", + "examine": "I need to clean this herb before I can use it.", + "grand_exchange_price": "900", + "durability": null, + "name": "Grimy cadantine", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "215" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "1582", + "durability": null, + "name": "Grimy cadantine", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "216" + }, + { + "requirements": "{15,70}", + "ge_buy_limit": "10000", + "examine": "I need to clean this herb before I can use it.", + "grand_exchange_price": "1300", + "durability": null, + "name": "Grimy dwarf weed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "217" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "6934", + "durability": null, + "name": "Grimy dwarf weed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "218" + }, + { + "requirements": "{15,75}", + "ge_buy_limit": "10000", + "examine": "I need to clean this herb before I can use it.", + "grand_exchange_price": "3200", + "durability": null, + "name": "Grimy torstol", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "219" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "35800", + "durability": null, + "name": "Grimy torstol", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "220" + }, + { + "shop_price": "3", + "ge_buy_limit": "10000", + "examine": "It seems to be looking at me.", + "grand_exchange_price": "27", + "durability": null, + "name": "Eye of newt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "221" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "27", + "durability": null, + "name": "Eye of newt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "222" + }, + { + "ge_buy_limit": "10000", + "examine": "Ewww!", + "grand_exchange_price": "888", + "durability": null, + "name": "Red spiders' eggs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "223" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "888", + "durability": null, + "name": "Red spiders' eggs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "224" + }, + { + "ge_buy_limit": "10000", + "examine": "The root of a limpwurt plant.", + "grand_exchange_price": "1984", + "durability": null, + "name": "Limpwurt root", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "225" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "1984", + "durability": null, + "name": "Limpwurt root", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "226" + }, + { + "shop_price": "10", + "ge_buy_limit": "10000", + "examine": "A glass vial containing water.", + "grand_exchange_price": "35", + "durability": null, + "name": "Vial of water", + "tradeable": "true", + "weight": "0.02", + "archery_ticket_price": "0", + "id": "227" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "35", + "durability": null, + "name": "Vial of water", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "228" + }, + { + "shop_price": "5", + "ge_buy_limit": "10000", + "examine": "An empty glass vial.", + "grand_exchange_price": "2", + "durability": null, + "name": "Vial", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "229" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "2", + "durability": null, + "name": "Vial", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "230" + }, + { + "shop_price": "67", + "ge_buy_limit": "10000", + "examine": "Strange spiky grass.", + "grand_exchange_price": "318", + "durability": null, + "name": "Snape grass", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "231" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "318", + "durability": null, + "name": "Snape grass", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "232" + }, + { + "shop_price": "4", + "ge_buy_limit": "1000", + "examine": "I can grind things for potions in this.", + "grand_exchange_price": "38", + "durability": null, + "name": "Pestle and mortar", + "tradeable": "true", + "weight": "0.05", + "archery_ticket_price": "0", + "id": "233" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "38", + "durability": null, + "name": "Pestle and mortar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "234" + }, + { + "ge_buy_limit": "10000", + "examine": "Finely ground horn of Unicorn.", + "grand_exchange_price": "2460", + "durability": null, + "name": "Unicorn horn dust", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "235" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "2460", + "durability": null, + "name": "Unicorn horn dust", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "236" + }, + { + "ge_buy_limit": "10000", + "examine": "This horn has restorative properties.", + "grand_exchange_price": "2481", + "durability": null, + "name": "Unicorn horn", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "237" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "2481", + "durability": null, + "name": "Unicorn horn", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "238" + }, + { + "ge_buy_limit": "10000", + "examine": "Sour berries, used in potions.", + "grand_exchange_price": "1438", + "durability": null, + "name": "White berries", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "239" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "1438", + "durability": null, + "name": "White berries", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "240" + }, + { + "ge_buy_limit": "10000", + "examine": "Finely ground scale of Dragon.", + "grand_exchange_price": "1336", + "durability": null, + "name": "Dragon scale dust", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "241" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "1336", + "durability": null, + "name": "Dragon scale dust", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "242" + }, + { + "ge_buy_limit": "10000", + "examine": "A large shiny scale.", + "grand_exchange_price": "1244", + "durability": null, + "name": "Blue dragon scale", + "tradeable": "true", + "weight": "0.01", + "archery_ticket_price": "0", + "id": "243" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "1244", + "durability": null, + "name": "Blue dragon scale", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "244" + }, + { + "ge_buy_limit": "10000", + "examine": "An evil wine that is often found in chaos temples.", + "grand_exchange_price": "2768", + "durability": null, + "name": "Wine of zamorak", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "245" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "2768", + "durability": null, + "name": "Wine of zamorak", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "246" + }, + { + "ge_buy_limit": "10000", + "examine": "They don't look very ripe.", + "grand_exchange_price": "83", + "durability": null, + "name": "Jangerberries", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "247" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "83", + "durability": null, + "name": "Jangerberries", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "248" + }, + { + "ge_buy_limit": "10000", + "examine": "A fresh herb.", + "grand_exchange_price": "182", + "durability": null, + "name": "Clean guam", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "249" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "182", + "durability": null, + "name": "Clean guam", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "250" + }, + { + "ge_buy_limit": "10000", + "examine": "A fresh herb.", + "grand_exchange_price": "23", + "durability": null, + "name": "Clean marrentill", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "251" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "23", + "durability": null, + "name": "Clean marrentill", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "252" + }, + { + "ge_buy_limit": "10000", + "examine": "A fresh herb.", + "grand_exchange_price": "144", + "durability": null, + "name": "Clean tarromin", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "253" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "144", + "durability": null, + "name": "Clean tarromin", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "254" + }, + { + "ge_buy_limit": "10000", + "examine": "A fresh herb.", + "grand_exchange_price": "275", + "durability": null, + "name": "Clean harralander", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "255" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "275", + "durability": null, + "name": "Clean harralander", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "256" + }, + { + "ge_buy_limit": "10000", + "examine": "A fresh herb.", + "grand_exchange_price": "4930", + "durability": null, + "name": "Clean ranarr", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "257" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "4930", + "durability": null, + "name": "Clean ranarr", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "258" + }, + { + "ge_buy_limit": "10000", + "examine": "A fresh herb.", + "grand_exchange_price": "2072", + "durability": null, + "name": "Clean irit", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "259" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "2072", + "durability": null, + "name": "Clean irit", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "260" + }, + { + "ge_buy_limit": "10000", + "examine": "A fresh herb.", + "grand_exchange_price": "3812", + "durability": null, + "name": "Clean avantoe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "261" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "3812", + "durability": null, + "name": "Clean avantoe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "262" + }, + { + "ge_buy_limit": "10000", + "examine": "A fresh herb.", + "grand_exchange_price": "1641", + "durability": null, + "name": "Clean kwuarm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "263" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "1641", + "durability": null, + "name": "Clean kwuarm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "264" + }, + { + "ge_buy_limit": "10000", + "examine": "A fresh herb.", + "grand_exchange_price": "1585", + "durability": null, + "name": "Clean cadantine", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "265" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "1585", + "durability": null, + "name": "Clean cadantine", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "266" + }, + { + "ge_buy_limit": "10000", + "examine": "A fresh herb.", + "grand_exchange_price": "6925", + "durability": null, + "name": "Clean dwarf weed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "267" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "6925", + "durability": null, + "name": "Clean dwarf weed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "268" + }, + { + "ge_buy_limit": "10000", + "examine": "A fresh herb.", + "grand_exchange_price": "8400", + "durability": null, + "name": "Clean torstol", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "269" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "35900", + "durability": null, + "name": "Clean torstol", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "270" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "It looks like part of a machine", + "durability": null, + "name": "Pressure gauge", + "archery_ticket_price": "0", + "id": "271" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A box of fish food / Keeps your pet fish strong and healthy.", + "durability": null, + "name": "Fish food", + "archery_ticket_price": "0", + "id": "272", + "equipment_slot": "5" + }, + { + "destroy_message": "You'll have to make more in Draynor Manor.", + "examine": "This isn't good for fish.", + "durability": null, + "name": "Poisoned fish food", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "274" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "name": "Key", + "archery_ticket_price": "0", + "id": "275" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "It's slightly charred.", + "durability": null, + "name": "Rubber tube", + "archery_ticket_price": "0", + "id": "276" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "It's pretty full.", + "durability": null, + "name": "Oil can", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "277" + }, + { + "examine": "A sharp cattleprod.", + "durability": null, + "name": "Cattleprod", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "278", + "weapon_interface": "5", + "bonuses": "4,2,-4,1,0,0,0,0,1,0,0,3,0,0,0", + "equipment_slot": "3" + }, + { + "examine": "Councillor Halgrive gave me this to kill some sheep.", + "durability": null, + "name": "Sheep feed", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "279" + }, + { + "examine": "The suspicious-looking remains of a suspicious-looking sheep.", + "durability": null, + "name": "Sheep bones (1)", + "archery_ticket_price": "0", + "id": "280" + }, + { + "examine": "The suspicious-looking remains of a suspicious-looking sheep.", + "durability": null, + "name": "Sheep bones (2)", + "archery_ticket_price": "0", + "id": "281" + }, + { + "examine": "The suspicious-looking remains of a suspicious-looking sheep.", + "durability": null, + "name": "Sheep bones (3)", + "archery_ticket_price": "0", + "id": "282" + }, + { + "examine": "The suspicious-looking remains of a suspicious-looking sheep.", + "durability": null, + "name": "Sheep bones (4)", + "archery_ticket_price": "0", + "id": "283" + }, + { + "remove_sleeves": "true", + "examine": "This should protect me from the plague, I hope!", + "durability": null, + "name": "Plague jacket", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "284", + "equipment_slot": "4" + }, + { + "examine": "A thick pair of leather trousers. or These should protect me from the plague, I hope!", + "durability": null, + "name": "Plague trousers", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "285", + "equipment_slot": "7" + }, + { + "examine": "Armour designed to fit goblins.", + "durability": null, + "name": "Orange goblin mail", + "weight": "3", + "archery_ticket_price": "0", + "id": "286", + "equipment_slot": "4" + }, + { + "examine": "Armour designed to fit goblins.", + "durability": null, + "name": "Blue goblin mail", + "weight": "3", + "archery_ticket_price": "0", + "id": "287", + "equipment_slot": "4" + }, + { + "shop_price": "16", + "ge_buy_limit": "100", + "examine": "Armour designed to fit goblins.", + "grand_exchange_price": "398", + "durability": null, + "name": "Goblin mail", + "tradeable": "true", + "weight": "3.6", + "archery_ticket_price": "0", + "id": "288", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "398", + "durability": null, + "name": "Goblin mail", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "289" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "This contains some vital research results.", + "durability": null, + "name": "Research package", + "weight": "1", + "archery_ticket_price": "0", + "id": "290" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "name": "Notes", + "archery_ticket_price": "0", + "id": "291" + }, + { + "examine": "A book on elven history in northern 2009Scape.", + "durability": null, + "name": "Book on baxtorian", + "archery_ticket_price": "0", + "id": "292" + }, + { + "examine": "A small pebble with elven inscription.", + "durability": null, + "name": "Glarial's pebble", + "archery_ticket_price": "0", + "id": "294" + }, + { + "examine": "A bright green gem set in a necklace.", + "durability": null, + "name": "Glarial's amulet", + "archery_ticket_price": "0", + "id": "295", + "equipment_slot": "2" + }, + { + "examine": "An urn containing Glarial's ashes./An empty urn made for Glarial's ashes.", + "durability": null, + "name": "Glarial's urn", + "archery_ticket_price": "0", + "id": "296" + }, + { + "examine": "An urn containing Glarial's ashes./An empty urn made for Glarial's ashes.", + "durability": null, + "name": "Glarial's urn", + "archery_ticket_price": "0", + "id": "297" + }, + { + "shop_price": "300", + "ge_buy_limit": "5000", + "examine": "Magical seeds in a mithril case.", + "grand_exchange_price": "623", + "durability": null, + "name": "Mithril seeds", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "299" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A bit of rat.", + "durability": null, + "name": "Rat's tail", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "300" + }, + { + "requirements": "{10,40}", + "shop_price": "20", + "ge_buy_limit": "100", + "examine": "Useful for catching lobsters.", + "grand_exchange_price": "100", + "durability": null, + "name": "Lobster pot", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "301" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "100", + "durability": null, + "name": "Lobster pot", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "302" + }, + { + "shop_price": "40", + "ge_buy_limit": "100", + "examine": "Useful for catching small fish.", + "grand_exchange_price": "397", + "durability": null, + "name": "Small fishing net", + "tradeable": "true", + "weight": "4.5", + "archery_ticket_price": "0", + "id": "303" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "397", + "durability": null, + "name": "Small fishing net", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "304" + }, + { + "requirements": "{16,10}", + "shop_price": "20", + "ge_buy_limit": "100", + "examine": "Useful for catching lots of fish.", + "grand_exchange_price": "329", + "durability": null, + "name": "Big fishing net", + "tradeable": "true", + "weight": "8.1", + "archery_ticket_price": "0", + "id": "305" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "329", + "durability": null, + "name": "Big fishing net", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "306" + }, + { + "requirements": "{5,10}", + "shop_price": "5", + "ge_buy_limit": "100", + "examine": "Useful for catching sardine or herring.", + "grand_exchange_price": "74", + "durability": null, + "name": "Fishing rod", + "tradeable": "true", + "weight": "1.3", + "archery_ticket_price": "0", + "id": "307" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "74", + "durability": null, + "name": "Fishing rod", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "308" + }, + { + "requirements": "{20,10}", + "shop_price": "5", + "ge_buy_limit": "100", + "examine": "Useful for catching salmon or trout.", + "grand_exchange_price": "123", + "durability": null, + "name": "Fly fishing rod", + "tradeable": "true", + "weight": "1.3", + "archery_ticket_price": "0", + "id": "309" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "123", + "durability": null, + "name": "Fly fishing rod", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "310" + }, + { + "requirements": "{10,35}", + "shop_price": "45", + "ge_buy_limit": "5000", + "examine": "Useful for catching big fish.", + "grand_exchange_price": "235", + "durability": null, + "name": "Harpoon", + "tradeable": "true", + "weight": "1.3", + "archery_ticket_price": "0", + "id": "311" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "235", + "durability": null, + "name": "Harpoon", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "312" + }, + { + "shop_price": "3", + "ge_buy_limit": "10000", + "examine": "For use with a fishing rod.", + "grand_exchange_price": "3", + "durability": null, + "name": "Fishing bait", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "313" + }, + { + "shop_price": "6", + "ge_buy_limit": "10000", + "examine": "Used for fly fishing.", + "grand_exchange_price": "24", + "durability": null, + "name": "Feather", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "314" + }, + { + "ge_buy_limit": "10000", + "examine": "Some nicely cooked shrimp.", + "grand_exchange_price": "9", + "durability": null, + "name": "Shrimps", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "315" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "9", + "durability": null, + "name": "Shrimps", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "316" + }, + { + "shop_price": "6", + "ge_buy_limit": "20000", + "examine": "I should try cooking this.", + "grand_exchange_price": "7", + "durability": null, + "name": "Raw shrimps", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "317" + }, + { + "ge_buy_limit": "20000", + "grand_exchange_price": "7", + "durability": null, + "name": "Raw shrimps", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "318" + }, + { + "ge_buy_limit": "10000", + "examine": "Some nicely cooked anchovies.", + "grand_exchange_price": "26", + "durability": null, + "name": "Anchovies", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "319" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "26", + "durability": null, + "name": "Anchovies", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "320" + }, + { + "shop_price": "16", + "ge_buy_limit": "20000", + "examine": "I should try cooking this.", + "grand_exchange_price": "11", + "durability": null, + "name": "Raw anchovies", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "321" + }, + { + "ge_buy_limit": "20000", + "grand_exchange_price": "11", + "durability": null, + "name": "Raw anchovies", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "322" + }, + { + "durability": null, + "name": "Burnt fish", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "324" + }, + { + "shop_price": "10", + "ge_buy_limit": "10000", + "examine": "Some nicely cooked Sardines.", + "grand_exchange_price": "12", + "durability": null, + "name": "Sardine", + "tradeable": "true", + "weight": "0.12", + "archery_ticket_price": "0", + "id": "325" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "12", + "durability": null, + "name": "Sardine", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "326" + }, + { + "shop_price": "7", + "ge_buy_limit": "20000", + "examine": "I should try cooking this.", + "grand_exchange_price": "31", + "durability": null, + "name": "Raw sardine", + "tradeable": "true", + "weight": "0.12", + "archery_ticket_price": "0", + "id": "327" + }, + { + "ge_buy_limit": "20000", + "grand_exchange_price": "31", + "durability": null, + "name": "Raw sardine", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "328" + }, + { + "shop_price": "88", + "ge_buy_limit": "10000", + "examine": "Some nicely cooked salmon.", + "grand_exchange_price": "278", + "durability": null, + "name": "Salmon", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "329" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "278", + "durability": null, + "name": "Salmon", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "330" + }, + { + "shop_price": "36", + "ge_buy_limit": "20000", + "examine": "I should try cooking this.", + "grand_exchange_price": "172", + "durability": null, + "name": "Raw salmon", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "331" + }, + { + "ge_buy_limit": "20000", + "grand_exchange_price": "172", + "durability": null, + "name": "Raw salmon", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "332" + }, + { + "shop_price": "7", + "ge_buy_limit": "10000", + "examine": "Some nicely cooked trout.", + "grand_exchange_price": "172", + "durability": null, + "name": "Trout", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "333" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "172", + "durability": null, + "name": "Trout", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "334" + }, + { + "shop_price": "7", + "ge_buy_limit": "20000", + "examine": "I should try cooking this.", + "grand_exchange_price": "67", + "durability": null, + "name": "Raw trout", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "335" + }, + { + "ge_buy_limit": "20000", + "grand_exchange_price": "67", + "durability": null, + "name": "Raw trout", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "336" + }, + { + "examine": "Some nicely cooked giant carp.", + "durability": null, + "name": "Giant carp", + "archery_ticket_price": "0", + "id": "337" + }, + { + "examine": "I should try cooking this.", + "durability": null, + "name": "Raw giant carp", + "archery_ticket_price": "0", + "id": "338" + }, + { + "shop_price": "49", + "ge_buy_limit": "10000", + "examine": "Some nicely cooked fish.", + "grand_exchange_price": "19", + "durability": null, + "name": "Cod", + "tradeable": "true", + "weight": "0.33", + "archery_ticket_price": "0", + "id": "339" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "19", + "durability": null, + "name": "Cod", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "340" + }, + { + "shop_price": "49", + "ge_buy_limit": "20000", + "examine": "I should try cooking this.", + "grand_exchange_price": "29", + "durability": null, + "name": "Raw cod", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "341" + }, + { + "ge_buy_limit": "20000", + "grand_exchange_price": "29", + "durability": null, + "name": "Raw cod", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "342" + }, + { + "durability": null, + "name": "Burnt fish", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "344" + }, + { + "ge_buy_limit": "20000", + "examine": "I should try cooking this.", + "grand_exchange_price": "63", + "durability": null, + "name": "Raw herring", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "345" + }, + { + "ge_buy_limit": "20000", + "grand_exchange_price": "63", + "durability": null, + "name": "Raw herring", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "346" + }, + { + "shop_price": "6", + "ge_buy_limit": "10000", + "examine": "Some nicely cooked herring.", + "grand_exchange_price": "23", + "durability": null, + "name": "Herring", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "347" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "23", + "durability": null, + "name": "Herring", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "348" + }, + { + "ge_buy_limit": "20000", + "examine": "I should try cooking this.", + "grand_exchange_price": "72", + "durability": null, + "name": "Raw pike", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "349" + }, + { + "ge_buy_limit": "20000", + "grand_exchange_price": "72", + "durability": null, + "name": "Raw pike", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "350" + }, + { + "ge_buy_limit": "10000", + "examine": "Some nicely cooked pike.", + "grand_exchange_price": "94", + "durability": null, + "name": "Pike", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "351" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "94", + "durability": null, + "name": "Pike", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "352" + }, + { + "shop_price": "26", + "ge_buy_limit": "20000", + "examine": "I should try cooking this.", + "grand_exchange_price": "14", + "durability": null, + "name": "Raw mackerel", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "353" + }, + { + "ge_buy_limit": "20000", + "grand_exchange_price": "14", + "durability": null, + "name": "Raw mackerel", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "354" + }, + { + "shop_price": "23", + "ge_buy_limit": "10000", + "examine": "Some nicely cooked fish.", + "grand_exchange_price": "5", + "durability": null, + "name": "Mackerel", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "355" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "5", + "durability": null, + "name": "Mackerel", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "356" + }, + { + "durability": null, + "name": "Burnt fish", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "358" + }, + { + "ge_buy_limit": "20000", + "examine": "I should try cooking this.", + "grand_exchange_price": "210", + "durability": null, + "name": "Raw tuna", + "tradeable": "true", + "weight": "0.379", + "archery_ticket_price": "0", + "id": "359" + }, + { + "ge_buy_limit": "20000", + "grand_exchange_price": "210", + "durability": null, + "name": "Raw tuna", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "360" + }, + { + "shop_price": "126", + "ge_buy_limit": "10000", + "examine": "Wow, this is a big fish.", + "grand_exchange_price": "281", + "durability": null, + "name": "Tuna", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "361" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "281", + "durability": null, + "name": "Tuna", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "362" + }, + { + "ge_buy_limit": "20000", + "examine": "I should try cooking this.", + "grand_exchange_price": "490", + "durability": null, + "name": "Raw bass", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "363" + }, + { + "ge_buy_limit": "20000", + "grand_exchange_price": "490", + "durability": null, + "name": "Raw bass", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "364" + }, + { + "shop_price": "270", + "ge_buy_limit": "10000", + "examine": "Wow, this is a big fish.", + "grand_exchange_price": "330", + "durability": null, + "name": "Bass", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "365" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "330", + "durability": null, + "name": "Bass", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "366" + }, + { + "durability": null, + "name": "Burnt fish", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "368" + }, + { + "durability": null, + "name": "Burnt fish", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "370" + }, + { + "ge_buy_limit": "20000", + "examine": "I should try cooking this.", + "grand_exchange_price": "513", + "durability": null, + "name": "Raw swordfish", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "371" + }, + { + "ge_buy_limit": "20000", + "grand_exchange_price": "513", + "durability": null, + "name": "Raw swordfish", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "372" + }, + { + "shop_price": "400", + "ge_buy_limit": "10000", + "examine": "I'd better be careful eating this!", + "grand_exchange_price": "501", + "durability": null, + "name": "Swordfish", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "373" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "501", + "durability": null, + "name": "Swordfish", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "374" + }, + { + "durability": null, + "name": "Burnt swordfish", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "376" + }, + { + "ge_buy_limit": "20000", + "examine": "I should try cooking this.", + "grand_exchange_price": "322", + "durability": null, + "name": "Raw lobster", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "377" + }, + { + "ge_buy_limit": "20000", + "grand_exchange_price": "322", + "durability": null, + "name": "Raw lobster", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "378" + }, + { + "shop_price": "107", + "ge_buy_limit": "10000", + "examine": "This looks tricky to eat.", + "grand_exchange_price": "334", + "durability": null, + "name": "Lobster", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "379" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "334", + "durability": null, + "name": "Lobster", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "380" + }, + { + "durability": null, + "name": "Burnt lobster", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "382" + }, + { + "ge_buy_limit": "20000", + "examine": "I should try cooking this.", + "grand_exchange_price": "1615", + "durability": null, + "name": "Raw shark", + "tradeable": "true", + "weight": "0.7", + "archery_ticket_price": "0", + "id": "383" + }, + { + "ge_buy_limit": "20000", + "grand_exchange_price": "1615", + "examine": "", + "durability": null, + "name": "Raw shark", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "384" + }, + { + "ge_buy_limit": "10000", + "examine": "I'd better be careful eating this.", + "grand_exchange_price": "1682", + "durability": null, + "name": "Shark", + "tradeable": "true", + "weight": "0.6", + "archery_ticket_price": "0", + "id": "385" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "1682", + "durability": null, + "name": "Shark", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "386" + }, + { + "durability": null, + "name": "Burnt shark", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "388" + }, + { + "ge_buy_limit": "20000", + "examine": "A rare catch.", + "grand_exchange_price": "2114", + "durability": null, + "name": "Raw manta ray", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "389" + }, + { + "ge_buy_limit": "20000", + "grand_exchange_price": "2114", + "durability": null, + "name": "Raw manta ray", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "390" + }, + { + "ge_buy_limit": "10000", + "examine": "Mmmm...this looks tasty!", + "grand_exchange_price": "2552", + "durability": null, + "name": "Manta ray", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "391" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "2552", + "durability": null, + "name": "Manta ray", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "392" + }, + { + "durability": null, + "name": "Burnt manta ray", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "394" + }, + { + "ge_buy_limit": "20000", + "examine": "A rare catch.", + "grand_exchange_price": "2397", + "durability": null, + "name": "Raw sea turtle", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "395" + }, + { + "ge_buy_limit": "20000", + "grand_exchange_price": "2397", + "durability": null, + "name": "Raw sea turtle", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "396" + }, + { + "ge_buy_limit": "10000", + "examine": "Tasty!", + "grand_exchange_price": "2486", + "durability": null, + "name": "Sea turtle", + "tradeable": "true", + "weight": "0.35", + "archery_ticket_price": "0", + "id": "397" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "2486", + "durability": null, + "name": "Sea turtle", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "398" + }, + { + "durability": null, + "name": "Burnt sea turtle", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "400" + }, + { + "shop_price": "5", + "ge_buy_limit": "10000", + "examine": "Slightly damp seaweed.", + "grand_exchange_price": "780", + "durability": null, + "name": "Seaweed", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "401" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "780", + "durability": null, + "name": "Seaweed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "402" + }, + { + "ge_buy_limit": "10000", + "examine": "Slightly damp seaweed.", + "grand_exchange_price": "291", + "durability": null, + "name": "Edible seaweed", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "403" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "291", + "durability": null, + "name": "Edible seaweed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "404" + }, + { + "ge_buy_limit": "100", + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "4162", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "405" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "4162", + "durability": null, + "name": "Casket", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "406" + }, + { + "ge_buy_limit": "500", + "examine": "Its a rare oyster.", + "grand_exchange_price": "23", + "durability": null, + "name": "Oyster", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "407" + }, + { + "ge_buy_limit": "500", + "grand_exchange_price": "23", + "durability": null, + "name": "Oyster", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "408" + }, + { + "shop_price": "5", + "examine": "Aww, it's empty.", + "durability": null, + "name": "Empty oyster", + "tradeable": "true", + "weight": "0.08", + "archery_ticket_price": "0", + "id": "409" + }, + { + "durability": null, + "name": "Empty oyster", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "410" + }, + { + "shop_price": "44", + "ge_buy_limit": "500", + "examine": "I could work wonders with a chisel on this pearl.", + "grand_exchange_price": "18", + "durability": null, + "name": "Oyster pearl", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "411", + "equipment_slot": "5" + }, + { + "ge_buy_limit": "500", + "grand_exchange_price": "18", + "durability": null, + "name": "Oyster pearl", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "412" + }, + { + "ge_buy_limit": "500", + "examine": "I could work wonders with a chisel on these pearls.", + "grand_exchange_price": "639", + "durability": null, + "name": "Oyster pearls", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "413", + "equipment_slot": "5" + }, + { + "ge_buy_limit": "500", + "grand_exchange_price": "639", + "durability": null, + "name": "Oyster pearls", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "414" + }, + { + "examine": "An expensive colourless liquid.", + "durability": null, + "name": "Ethenea", + "archery_ticket_price": "0", + "id": "415" + }, + { + "examine": "This isn't worth much.", + "durability": null, + "name": "Liquid honey", + "archery_ticket_price": "0", + "id": "416" + }, + { + "examine": "It's highly poisonous.", + "durability": null, + "name": "Sulphuric broline", + "weight": "1", + "archery_ticket_price": "0", + "id": "417" + }, + { + "examine": "Probably best I don't keep this too long.", + "durability": null, + "name": "Plague sample", + "archery_ticket_price": "0", + "id": "418" + }, + { + "examine": "A special kind of paper.", + "durability": null, + "name": "Touch paper", + "archery_ticket_price": "0", + "id": "419" + }, + { + "examine": "Apparently it distills.", + "durability": null, + "name": "Distillator", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "420" + }, + { + "examine": "Yup. It's an amulet.", + "durability": null, + "name": "Lathas' amulet", + "archery_ticket_price": "0", + "id": "421", + "equipment_slot": "2" + }, + { + "examine": "Birds love this stuff!", + "durability": null, + "name": "Bird feed", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "422" + }, + { + "examine": "(empty) It's empty... (full) It's full of pigeons.", + "durability": null, + "name": "Pigeon cage", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "424" + }, + { + "examine": "(empty) It's empty... (full) It's full of pigeons.", + "durability": null, + "name": "Pigeon cage", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "425" + }, + { + "ge_buy_limit": "100", + "shop_price": "5", + "examine": "Top half of a priest suit.", + "durability": null, + "weight": "2", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "55", + "name": "Priest gown", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "426", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,3,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "55", + "durability": null, + "name": "Priest gown", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "427" + }, + { + "ge_buy_limit": "100", + "shop_price": "5", + "examine": "Bottom half of a priest suit.", + "grand_exchange_price": "14", + "durability": null, + "name": "Priest gown", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "428", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,3,0,0", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "14", + "durability": null, + "name": "Priest gown", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "429" + }, + { + "remove_sleeves": "true", + "examine": "Medical looking.", + "durability": null, + "name": "Doctors' gown", + "weight": "1", + "archery_ticket_price": "0", + "id": "430", + "equipment_slot": "4" + }, + { + "shop_price": "27", + "examine": "A very strong spirit brewed in Karamja.", + "durability": null, + "name": "Karamjan rum", + "archery_ticket_price": "0", + "id": "431" + }, + { + "examine": "Pirates don't have the best handwriting...", + "durability": null, + "name": "Pirate message", + "weight": "1", + "archery_ticket_price": "0", + "id": "433" + }, + { + "ge_buy_limit": "25000", + "examine": "Some hard dry clay.", + "grand_exchange_price": "150", + "durability": null, + "name": "Clay", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "434" + }, + { + "ge_buy_limit": "25000", + "grand_exchange_price": "406", + "durability": null, + "name": "Clay", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "435" + }, + { + "ge_buy_limit": "25000", + "examine": "This needs refining.", + "grand_exchange_price": "80", + "tokkul_price": "4", + "durability": null, + "name": "Copper ore", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "436" + }, + { + "ge_buy_limit": "25000", + "grand_exchange_price": "58", + "durability": null, + "name": "Copper ore", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "437" + }, + { + "shop_price": "6", + "ge_buy_limit": "25000", + "examine": "This needs refining.", + "grand_exchange_price": "80", + "tokkul_price": "4", + "durability": null, + "name": "Tin ore", + "tradeable": "true", + "weight": "2.25", + "archery_ticket_price": "0", + "id": "438" + }, + { + "ge_buy_limit": "25000", + "grand_exchange_price": "46", + "durability": null, + "name": "Tin ore", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "439" + }, + { + "ge_buy_limit": "25000", + "examine": "This needs refining.", + "grand_exchange_price": "204", + "tokkul_price": "25", + "durability": null, + "name": "Iron ore", + "tradeable": "true", + "weight": "2.25", + "archery_ticket_price": "0", + "id": "440" + }, + { + "ge_buy_limit": "25000", + "grand_exchange_price": "396", + "durability": null, + "name": "Iron ore", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "441" + }, + { + "shop_price": "82", + "ge_buy_limit": "25000", + "examine": "This needs refining.", + "grand_exchange_price": "180", + "tokkul_price": "112", + "durability": null, + "name": "Silver ore", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "442" + }, + { + "ge_buy_limit": "25000", + "grand_exchange_price": "205", + "durability": null, + "name": "Silver ore", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "443" + }, + { + "ge_buy_limit": "25000", + "examine": "This needs refining.", + "grand_exchange_price": "311", + "tokkul_price": "225", + "durability": null, + "name": "Gold ore", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "444" + }, + { + "ge_buy_limit": "25000", + "grand_exchange_price": "319", + "durability": null, + "name": "Gold ore", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "445" + }, + { + "examine": "This needs refining.", + "durability": null, + "name": "'perfect' gold ore", + "archery_ticket_price": "0", + "id": "446" + }, + { + "shop_price": "243", + "ge_buy_limit": "25000", + "examine": "This needs refining.", + "grand_exchange_price": "420", + "tokkul_price": "243", + "durability": null, + "name": "Mithril ore", + "tradeable": "true", + "weight": "1.75", + "archery_ticket_price": "0", + "id": "447" + }, + { + "ge_buy_limit": "25000", + "grand_exchange_price": "369", + "durability": null, + "name": "Mithril ore", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "448" + }, + { + "shop_price": "1300", + "ge_buy_limit": "25000", + "examine": "This needs refining.", + "grand_exchange_price": "1160", + "tokkul_price": "600", + "durability": null, + "name": "Adamantite ore", + "tradeable": "true", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "449" + }, + { + "ge_buy_limit": "25000", + "grand_exchange_price": "1622", + "durability": null, + "name": "Adamantite ore", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "450" + }, + { + "ge_buy_limit": "25000", + "examine": "This needs refining.", + "grand_exchange_price": "10300", + "tokkul_price": "4800", + "durability": null, + "name": "Runite ore", + "tradeable": "true", + "weight": "2.25", + "archery_ticket_price": "0", + "id": "451" + }, + { + "ge_buy_limit": "25000", + "grand_exchange_price": "10300", + "durability": null, + "name": "Runite ore", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "452" + }, + { + "ge_buy_limit": "25000", + "examine": "Hmm a non-renewable energy source!", + "grand_exchange_price": "320", + "tokkul_price": "67", + "durability": null, + "name": "Coal", + "tradeable": "true", + "weight": "2.25", + "archery_ticket_price": "0", + "id": "453" + }, + { + "ge_buy_limit": "25000", + "grand_exchange_price": "315", + "durability": null, + "name": "Coal", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "454" + }, + { + "examine": "The official Alfred Grimhand bar crawl card.", + "durability": null, + "name": "Barcrawl card", + "archery_ticket_price": "0", + "id": "455" + }, + { + "destroy_message": "You will need to speak to Thormac to get another cage.", + "examine": "It's empty!", + "durability": null, + "name": "Scorpion cage", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "weight": "0.15", + "id": "456" + }, + { + "destroy_message": "You will need to speak to Thormac to get another cage.", + "examine": "There is 1 scorpion inside.", + "durability": null, + "name": "Scorpion cage", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "weight": "0.175", + "id": "457" + }, + { + "destroy_message": "You will need to speak to Thormac to get another cage.", + "examine": "There are 2 scorpions inside.", + "durability": null, + "name": "Scorpion cage", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "weight": "0.2", + "id": "458" + }, + { + "destroy_message": "You will need to speak to Thormac to get another cage.", + "examine": "There is 1 scorpion inside.", + "durability": null, + "name": "Scorpion cage", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "weight": "0.175", + "id": "459" + }, + { + "destroy_message": "You will need to speak to Thormac to get another cage.", + "examine": "There are 2 scorpions inside.", + "durability": null, + "name": "Scorpion cage", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "weight": "0.2", + "id": "460" + }, + { + "destroy_message": "You will need to speak to Thormac to get another cage.", + "examine": "There is 1 scorpion inside.", + "durability": null, + "name": "Scorpion cage", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "weight": "0.175", + "id": "461" + }, + { + "destroy_message": "You will need to speak to Thormac to get another cage.", + "examine": "There are 2 scorpions inside.", + "durability": null, + "name": "Scorpion cage", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "weight": "0.2", + "id": "462" + }, + { + "destroy_message": "You will need to speak to Thormac to get another cage.", + "examine": "There are 3 scorpions inside.", + "durability": null, + "name": "Scorpion cage", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "weight": "0.225", + "id": "463" + }, + { + "ge_buy_limit": "10000", + "examine": "Found on strange plants that grow around Karamja.", + "grand_exchange_price": "403", + "durability": null, + "name": "Strange fruit", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "464" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "403", + "durability": null, + "name": "Strange fruit", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "465" + }, + { + "shop_price": "1", + "examine": "Useless without the head.", + "attack_audios": "2508,0,0,0", + "durability": null, + "name": "Pickaxe handle", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "466", + "equipment_slot": "3" + }, + { + "durability": null, + "name": "Pickaxe handle", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "467" + }, + { + "examine": "Nurmof can fix this for me.", + "attack_audios": "2508,0,0,0", + "durability": null, + "name": "Broken pickaxe", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "468", + "equipment_slot": "3" + }, + { + "durability": null, + "name": "Broken pickaxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "469" + }, + { + "examine": "Nurmof can fix this for me.", + "attack_audios": "2508,0,0,0", + "durability": null, + "name": "Broken pickaxe", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "470", + "equipment_slot": "3" + }, + { + "durability": null, + "name": "Broken pickaxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "471" + }, + { + "examine": "Nurmof can fix this for me.", + "attack_audios": "2508,0,0,0", + "durability": null, + "name": "Broken pickaxe", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "472", + "equipment_slot": "3" + }, + { + "durability": null, + "name": "Broken pickaxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "473" + }, + { + "examine": "Nurmof can fix this for me.", + "attack_audios": "2508,0,0,0", + "durability": null, + "name": "Broken pickaxe", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "474", + "equipment_slot": "3" + }, + { + "durability": null, + "name": "Broken pickaxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "475" + }, + { + "examine": "Nurmof can fix this for me.", + "attack_audios": "2508,0,0,0", + "durability": null, + "name": "Broken pickaxe", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "476", + "equipment_slot": "3" + }, + { + "durability": null, + "name": "Broken pickaxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "477" + }, + { + "examine": "Nurmof can fix this for me.", + "attack_audios": "2508,0,0,0", + "durability": null, + "name": "Broken pickaxe", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "478", + "equipment_slot": "3" + }, + { + "durability": null, + "name": "Broken pickaxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "479" + }, + { + "shop_price": "1", + "examine": "It's missing a handle.", + "durability": null, + "name": "Bronze pick head", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "480" + }, + { + "durability": null, + "name": "Bronze pick head", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "481" + }, + { + "shop_price": "1", + "examine": "It's missing a handle.", + "durability": null, + "name": "Iron pick head", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "482" + }, + { + "durability": null, + "name": "Iron pick head", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "483" + }, + { + "shop_price": "1", + "examine": "It's missing a handle.", + "durability": null, + "name": "Steel pick head", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "484" + }, + { + "durability": null, + "name": "Steel pick head", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "485" + }, + { + "shop_price": "1", + "examine": "It's missing a handle.", + "durability": null, + "name": "Mithril pick head", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "486" + }, + { + "durability": null, + "name": "Mithril pick head", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "487" + }, + { + "shop_price": "1", + "examine": "It's missing a handle.", + "durability": null, + "name": "Adamant pick head", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "488" + }, + { + "durability": null, + "name": "Adamant pick head", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "489" + }, + { + "shop_price": "1", + "examine": "It's missing a handle.", + "durability": null, + "name": "Rune pick head", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "490" + }, + { + "durability": null, + "name": "Rune pick head", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "491" + }, + { + "examine": "Useless without the head.", + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "492", + "equipment_slot": "3" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "493" + }, + { + "examine": "Bob can fix this broken (metal) axe for me.", + "durability": null, + "name": "Broken axe", + "weight": "2.5", + "archery_ticket_price": "0", + "id": "494", + "equipment_slot": "3" + }, + { + "durability": null, + "name": "Broken axe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "495" + }, + { + "examine": "Bob can fix this broken (metal) axe for me.", + "durability": null, + "name": "Broken axe", + "weight": "2.5", + "archery_ticket_price": "0", + "id": "496", + "equipment_slot": "3" + }, + { + "durability": null, + "name": "Broken axe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "497" + }, + { + "examine": "Bob can fix this broken (metal) axe for me.", + "durability": null, + "name": "Broken axe", + "weight": "2.5", + "archery_ticket_price": "0", + "id": "498", + "equipment_slot": "3" + }, + { + "durability": null, + "name": "Broken axe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "499" + }, + { + "examine": "Bob can fix this broken (metal) axe for me.", + "durability": null, + "name": "Broken axe", + "weight": "2.5", + "archery_ticket_price": "0", + "id": "500", + "equipment_slot": "3" + }, + { + "durability": null, + "name": "Broken axe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "501" + }, + { + "examine": "Bob can fix this broken (metal) axe for me.", + "durability": null, + "name": "Broken axe", + "weight": "2.5", + "archery_ticket_price": "0", + "id": "502", + "equipment_slot": "3" + }, + { + "durability": null, + "name": "Broken axe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "503" + }, + { + "examine": "Bob can fix this broken (metal) axe for me.", + "durability": null, + "name": "Broken axe", + "weight": "2.5", + "archery_ticket_price": "0", + "id": "504", + "equipment_slot": "3" + }, + { + "durability": null, + "name": "Broken axe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "505" + }, + { + "examine": "Bob can fix this broken (metal) axe for me.", + "durability": null, + "name": "Broken axe", + "weight": "2.5", + "archery_ticket_price": "0", + "id": "506", + "equipment_slot": "3" + }, + { + "durability": null, + "name": "Broken axe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "507" + }, + { + "examine": "A piece of ancient goblin axe.", + "durability": null, + "name": "Picture", + "archery_ticket_price": "0", + "id": "508" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "509" + }, + { + "examine": "A piece of ancient goblin axe.", + "durability": null, + "name": "Picture", + "archery_ticket_price": "0", + "id": "510" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "511" + }, + { + "examine": "A piece of ancient goblin axe.", + "durability": null, + "name": "Picture", + "archery_ticket_price": "0", + "id": "512" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "513" + }, + { + "examine": "A piece of ancient goblin axe.", + "durability": null, + "name": "Picture", + "archery_ticket_price": "0", + "id": "514" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "515" + }, + { + "examine": "A piece of ancient goblin axe.", + "durability": null, + "name": "Picture", + "archery_ticket_price": "0", + "id": "516" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "517" + }, + { + "examine": "A piece of ancient goblin axe.", + "durability": null, + "name": "Picture", + "archery_ticket_price": "0", + "id": "518" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "519" + }, + { + "examine": "A piece of ancient goblin axe.", + "durability": null, + "name": "Picture", + "archery_ticket_price": "0", + "id": "520" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "521" + }, + { + "examine": "I don't fancy eating this now.", + "durability": null, + "name": "Enchanted beef", + "archery_ticket_price": "0", + "id": "522" + }, + { + "examine": "I don't fancy eating this now.", + "durability": null, + "name": "Enchanted rat meat", + "archery_ticket_price": "0", + "id": "523" + }, + { + "examine": "I don't fancy eating this now.", + "durability": null, + "name": "Enchanted bear meat", + "archery_ticket_price": "0", + "id": "524" + }, + { + "examine": "I don't fancy eating this now.", + "durability": null, + "name": "Enchanted chicken", + "weight": "1", + "archery_ticket_price": "0", + "id": "525" + }, + { + "shop_price": "190", + "ge_buy_limit": "10000", + "grand_exchange_price": "190", + "examine": "Bones are for burying!", + "durability": null, + "name": "Bones", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "526" + }, + { + "shop_price": "190", + "ge_buy_limit": "10000", + "grand_exchange_price": "190", + "durability": null, + "name": "Bones", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "527" + }, + { + "ge_buy_limit": "10000", + "examine": "Bones are for burying!", + "grand_exchange_price": "329", + "durability": null, + "name": "Burnt bones", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "528" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "329", + "durability": null, + "name": "Burnt bones", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "529" + }, + { + "ge_buy_limit": "10000", + "examine": "Ew it's a pile of bones.", + "grand_exchange_price": "354", + "durability": null, + "name": "Bat bones", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "530" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "354", + "durability": null, + "name": "Bat bones", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "531" + }, + { + "shop_price": "593", + "ge_buy_limit": "10000", + "examine": "Normal: Ew, it's a pile of bones.", + "grand_exchange_price": "593", + "durability": null, + "name": "Big bones", + "tradeable": "true", + "weight": "0.8", + "archery_ticket_price": "0", + "id": "532" + }, + { + "shop_price": "593", + "ge_buy_limit": "10000", + "grand_exchange_price": "593", + "durability": null, + "name": "Big bones", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "533" + }, + { + "ge_buy_limit": "10000", + "examine": "Ew, it's a pile of bones.", + "grand_exchange_price": "1357", + "durability": null, + "name": "Babydragon bones", + "tradeable": "true", + "weight": "0.7", + "archery_ticket_price": "0", + "id": "534" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "1357", + "durability": null, + "name": "Babydragon bones", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "535" + }, + { + "ge_buy_limit": "10000", + "examine": "These would feed a dog for months!", + "grand_exchange_price": "1300", + "durability": null, + "name": "Dragon bones", + "tradeable": "true", + "weight": "1.5", + "archery_ticket_price": "0", + "id": "536" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "4065", + "durability": null, + "name": "Dragon bones", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "537" + }, + { + "ge_buy_limit": "100", + "examine": "Keeps a druid's knees nice and warm.", + "grand_exchange_price": "168", + "durability": null, + "name": "Druid's robe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "538", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,4,0,0", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "168", + "durability": null, + "name": "Druid's robe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "539" + }, + { + "remove_sleeves": "true", + "ge_buy_limit": "100", + "examine": "I feel closer to the gods when I am wearing this.", + "grand_exchange_price": "328", + "durability": null, + "name": "Druid's robe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "540", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,4,0,0", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "328", + "durability": null, + "name": "Druid's robe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "541" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "528", + "durability": null, + "name": "Monk's robe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "542", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,5,0,0", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "528", + "durability": null, + "name": "Monk's robe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "543" + }, + { + "remove_sleeves": "true", + "ge_buy_limit": "100", + "grand_exchange_price": "1495", + "durability": null, + "name": "Monk's robe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "544", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,6,0,0", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1495", + "durability": null, + "name": "Monk's robe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "545" + }, + { + "remove_sleeves": "true", + "examine": "I feel closer to the gods when I am wearing this. (Top) If a shade had knees, this would keep them nice and warm. (Bottom)", + "durability": null, + "name": "Shade robe", + "weight": "2", + "archery_ticket_price": "0", + "id": "546", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,5,0,0", + "equipment_slot": "4" + }, + { + "examine": "I feel closer to the gods when I am wearing this. (Top) If a shade had knees, this would keep them nice and warm. (Bottom)", + "durability": null, + "name": "Shade robe", + "weight": "2", + "archery_ticket_price": "0", + "id": "548", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,4,0,0", + "equipment_slot": "7" + }, + { + "shop_price": "1", + "ge_buy_limit": "100", + "examine": "Issued by 2009Scape Council to all new citizens.", + "grand_exchange_price": "123", + "durability": null, + "name": "Newcomer map", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "550" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "123", + "durability": null, + "name": "Newcomer map", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "551" + }, + { + "examine": "It lets me talk to ghosts.", + "durability": null, + "name": "Ghostspeak amulet", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "552", + "equipment_slot": "2" + }, + { + "destroy_message": "If you get rid of the skull you'll have to search for it again.", + "examine": "Ooooh spooky!", + "durability": null, + "name": "Ghost's skull", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "553" + }, + { + "shop_price": "17", + "ge_buy_limit": "25000", + "examine": "One of the 4 basic elemental Runes.", + "grand_exchange_price": "18", + "tokkul_price": "6", + "durability": null, + "name": "Fire rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "554" + }, + { + "shop_price": "17", + "ge_buy_limit": "25000", + "examine": "One of the 4 basic elemental Runes.", + "grand_exchange_price": "18", + "tokkul_price": "6", + "durability": null, + "name": "Water rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "555" + }, + { + "shop_price": "17", + "ge_buy_limit": "25000", + "examine": "One of the 4 basic elemental Runes.", + "grand_exchange_price": "18", + "tokkul_price": "6", + "durability": null, + "name": "Air rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "556" + }, + { + "shop_price": "17", + "ge_buy_limit": "25000", + "examine": "One of the 4 basic elemental Runes.", + "grand_exchange_price": "18", + "tokkul_price": "6", + "durability": null, + "name": "Earth rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "557" + }, + { + "shop_price": "17", + "ge_buy_limit": "25000", + "examine": "Used for basic missile spells.", + "grand_exchange_price": "18", + "tokkul_price": "4", + "durability": null, + "name": "Mind rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "558" + }, + { + "shop_price": "16", + "ge_buy_limit": "25000", + "examine": "Used for Curse spells", + "grand_exchange_price": "16", + "tokkul_price": "4", + "durability": null, + "name": "Body rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "559" + }, + { + "shop_price": "310", + "ge_buy_limit": "25000", + "examine": "Used for medium missile spells.", + "grand_exchange_price": "320", + "durability": null, + "tokkul_price": "270", + "name": "Death rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "560" + }, + { + "shop_price": "372", + "ge_buy_limit": "25000", + "examine": "Used for alchemy spells.", + "grand_exchange_price": "380", + "durability": null, + "name": "Nature rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "561" + }, + { + "shop_price": "140", + "ge_buy_limit": "25000", + "examine": "Used for small missile spells.", + "grand_exchange_price": "140", + "durability": null, + "tokkul_price": "135", + "name": "Chaos rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "562" + }, + { + "shop_price": "378", + "ge_buy_limit": "25000", + "examine": "Used for teleport spells.", + "grand_exchange_price": "380", + "durability": null, + "name": "Law rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "563" + }, + { + "shop_price": "232", + "ge_buy_limit": "25000", + "examine": "Used for enchant spells.", + "grand_exchange_price": "240", + "durability": null, + "name": "Cosmic rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "564" + }, + { + "shop_price": "550", + "ge_buy_limit": "25000", + "examine": "Used for large missile spells.", + "grand_exchange_price": "560", + "durability": null, + "name": "Blood rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "565" + }, + { + "shop_price": "400", + "ge_buy_limit": "25000", + "examine": "Used for high level curse spells.", + "grand_exchange_price": "420", + "durability": null, + "name": "Soul rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "566" + }, + { + "ge_buy_limit": "5000", + "examine": "I'd prefer it if it was powered.", + "grand_exchange_price": "561", + "durability": null, + "name": "Unpowered orb", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "567" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "561", + "durability": null, + "name": "Unpowered orb", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "568" + }, + { + "ge_buy_limit": "5000", + "examine": "A magic glowing orb.", + "grand_exchange_price": "2346", + "durability": null, + "name": "Fire orb", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "569" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "2346", + "durability": null, + "name": "Fire orb", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "570" + }, + { + "ge_buy_limit": "5000", + "examine": "A magic glowing orb.", + "grand_exchange_price": "2024", + "durability": null, + "name": "Water orb", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "571" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "2024", + "durability": null, + "name": "Water orb", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "572" + }, + { + "ge_buy_limit": "5000", + "examine": "A magic glowing orb.", + "grand_exchange_price": "2162", + "durability": null, + "name": "Air orb", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "573" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "2162", + "durability": null, + "name": "Air orb", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "574" + }, + { + "ge_buy_limit": "5000", + "examine": "A magic glowing orb.", + "grand_exchange_price": "2208", + "durability": null, + "name": "Earth orb", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "575" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "2208", + "durability": null, + "name": "Earth orb", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "576" + }, + { + "shop_price": "4", + "ge_buy_limit": "100", + "examine": "I can do magic better in this.", + "durability": null, + "weight": "1", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "1840", + "name": "Wizard robe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "577", + "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1840", + "durability": null, + "name": "Wizard robe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "578" + }, + { + "shop_price": "2", + "ge_buy_limit": "100", + "examine": "A silly pointed hat.", + "durability": null, + "weight": "0.45", + "equipment_slot": "0", + "grand_exchange_price": "361", + "name": "Wizard hat", + "tradeable": "true", + "archery_ticket_price": "0", + "hat": "true", + "id": "579", + "bonuses": "0,0,0,2,0,0,0,0,2,0,0,0,0,0,0" + }, + { + "shop_price": "2", + "ge_buy_limit": "100", + "grand_exchange_price": "361", + "durability": null, + "name": "Wizard hat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "580" + }, + { + "shop_price": "5", + "ge_buy_limit": "100", + "examine": "I can do magic better in this.", + "durability": null, + "weight": "1", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "1364", + "name": "Black robe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "581", + "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1364", + "durability": null, + "name": "Black robe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "582" + }, + { + "shop_price": "10", + "examine": "Empty: It's a bailing bucket. Full: It's a bailing bucket full of salty water.", + "durability": null, + "name": "Bailing bucket", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "583" + }, + { + "durability": null, + "name": "Bailing bucket", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "584" + }, + { + "shop_price": "10", + "examine": "Empty: It's a bailing bucket. Full: It's a bailing bucket full of salty water.", + "durability": null, + "name": "Bailing bucket", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "585" + }, + { + "durability": null, + "name": "Bailing bucket", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "586" + }, + { + "examine": "A strange glowing green orb.", + "durability": null, + "name": "Orb of protection", + "weight": "1", + "archery_ticket_price": "0", + "id": "587" + }, + { + "examine": "Two strange glowing green orbs.", + "durability": null, + "name": "Orbs of protection", + "archery_ticket_price": "0", + "id": "588" + }, + { + "examine": "It's an amulet of protection given to me by the Gnomes.", + "durability": null, + "name": "Gnome amulet", + "archery_ticket_price": "0", + "id": "589", + "bonuses": "0,0,0,0,0,13,13,13,0,0,0,0,0,0,0", + "equipment_slot": "2" + }, + { + "shop_price": "1", + "ge_buy_limit": "5000", + "examine": "Useful for lighting a fire.", + "grand_exchange_price": "118", + "durability": null, + "name": "Tinderbox", + "tradeable": "true", + "weight": "0.05", + "archery_ticket_price": "0", + "id": "590" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "118", + "durability": null, + "name": "Tinderbox", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "591" + }, + { + "ge_buy_limit": "10000", + "examine": "A heap of ashes.", + "grand_exchange_price": "368", + "durability": null, + "name": "Ashes", + "tradeable": "true", + "weight": "0.056", + "archery_ticket_price": "0", + "id": "592" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "368", + "durability": null, + "name": "Ashes", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "593" + }, + { + "examine": "A lit home-made torch.", + "durability": null, + "name": "Lit torch", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "594" + }, + { + "shop_price": "1", + "ge_buy_limit": "100", + "examine": "An unlit home-made torch.", + "grand_exchange_price": "1", + "durability": null, + "name": "Unlit torch", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "596" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1", + "durability": null, + "name": "Unlit torch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "597" + }, + { + "ge_buy_limit": "10000", + "examine": "unlit: Arrows with bronze heads and oil-soaked cloth. lit: An easy to make, bronze-headed fire arrow.", + "grand_exchange_price": "162", + "durability": null, + "name": "Bronze fire arrows", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "598", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,7", + "equipment_slot": "13" + }, + { + "ge_buy_limit": "100", + "examine": "A book on the history of astronomy in 2009Scape.", + "grand_exchange_price": "658", + "durability": null, + "name": "Astronomy book", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "600" + }, + { + "destroy_message": "You'll have to find another, down in the dungeon.", + "examine": "A small key for a large door.", + "durability": null, + "name": "Goblin kitchen key", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "601" + }, + { + "destroy_message": "You'll have to get another down in the Dungeon", + "examine": "An unusual clay mould in the shape of a disc.", + "durability": null, + "name": "Lens mould", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "602" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A perfectly circular disc of glass.", + "durability": null, + "name": "Observatory lens", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "603" + }, + { + "shop_price": "160", + "examine": "A slender bone shard given to you by Zadimus.", + "durability": null, + "name": "Bone shard", + "archery_ticket_price": "0", + "id": "604" + }, + { + "shop_price": "100", + "examine": "A key fashioned from a shard of bone. (Shilo Village)", + "durability": null, + "name": "Bone key", + "archery_ticket_price": "0", + "id": "605" + }, + { + "examine": "A stone plaque with carved letters in it.", + "durability": null, + "name": "Stone-plaque", + "archery_ticket_price": "0", + "id": "606" + }, + { + "examine": "An ancient tattered scroll.", + "durability": null, + "name": "Tattered scroll", + "archery_ticket_price": "0", + "id": "607" + }, + { + "shop_price": "100", + "examine": "An ancient crumpled scroll.", + "durability": null, + "name": "Crumpled scroll", + "archery_ticket_price": "0", + "id": "608" + }, + { + "examine": "The remains of the Zombie Queen.", + "durability": null, + "name": "Rashiliyia corpse", + "archery_ticket_price": "0", + "id": "609" + }, + { + "examine": "The remains of Zadimus.", + "durability": null, + "name": "Zadimus corpse", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "610" + }, + { + "examine": "A magical crystal sphere.", + "durability": null, + "name": "Locating crystal", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "611" + }, + { + "examine": "A magical crystal sphere.", + "durability": null, + "name": "Locating crystal", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "612" + }, + { + "examine": "A magical crystal sphere.", + "durability": null, + "name": "Locating crystal", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "613" + }, + { + "examine": "A magical crystal sphere.", + "durability": null, + "name": "Locating crystal", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "614" + }, + { + "examine": "A magical crystal sphere.", + "durability": null, + "name": "Locating crystal", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "615" + }, + { + "destroy_message": "You made the beads of the dead during the Shilo Village quest. You can get another from Yanni Salika in Shilo Village for 1200 gold.", + "shop_price": "1200", + "examine": "A curious looking neck ornament.", + "durability": null, + "name": "Beads of the dead", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "616", + "bonuses": "1,1,1,1,1,1,1,1,1,1,1,1,1,0,0", + "equipment_slot": "2" + }, + { + "bankable": "false", + "examine": "Lovely money!", + "durability": null, + "name": "Coins", + "archery_ticket_price": "0", + "id": "617" + }, + { + "examine": "Beads carved out of a bone.", + "durability": null, + "name": "Bone beads", + "archery_ticket_price": "0", + "id": "618" + }, + { + "shop_price": "35", + "examine": "Allows you to rest in the luxurious Paramayer Inn.", + "durability": null, + "name": "Paramaya ticket", + "archery_ticket_price": "0", + "id": "619" + }, + { + "shop_price": "35", + "examine": "Allows you to rest in the luxurious Paramayer Inn.", + "durability": null, + "name": "Paramaya ticket", + "archery_ticket_price": "0", + "id": "620" + }, + { + "examine": "Sold in Shilo Village for passage on the 'Lady of the Waves'.", + "durability": null, + "name": "Ship ticket", + "archery_ticket_price": "0", + "id": "621" + }, + { + "examine": "An ivory sword pommel.", + "durability": null, + "name": "Sword pommel", + "archery_ticket_price": "0", + "id": "623" + }, + { + "examine": "Notes taken from the tomb of Bervirius.", + "durability": null, + "name": "Bervirius notes", + "archery_ticket_price": "0", + "id": "624" + }, + { + "examine": "A decorated belt used to trade information between distant villages.", + "durability": null, + "name": "Wampum belt", + "archery_ticket_price": "0", + "id": "625" + }, + { + "ge_buy_limit": "100", + "shop_price": "200", + "examine": "They're soft, silky and pink.", + "grand_exchange_price": "558", + "durability": null, + "name": "Boots", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "626", + "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", + "equipment_slot": "10" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "558", + "durability": null, + "name": "Boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "627" + }, + { + "ge_buy_limit": "100", + "shop_price": "200", + "examine": "They're soft, silky and green.", + "grand_exchange_price": "397", + "durability": null, + "name": "Boots", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "628", + "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", + "equipment_slot": "10" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "397", + "durability": null, + "name": "Boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "629" + }, + { + "ge_buy_limit": "100", + "shop_price": "200", + "examine": "They're soft, silky and blue.", + "grand_exchange_price": "612", + "durability": null, + "name": "Boots", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "630", + "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", + "equipment_slot": "10" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "612", + "durability": null, + "name": "Boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "631" + }, + { + "ge_buy_limit": "100", + "shop_price": "200", + "examine": "They're soft, silky and cream.", + "grand_exchange_price": "496", + "durability": null, + "name": "Boots", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "632", + "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", + "equipment_slot": "10" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "496", + "durability": null, + "name": "Boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "633" + }, + { + "ge_buy_limit": "100", + "shop_price": "200", + "examine": "They're soft, silky and turquoise.", + "grand_exchange_price": "226", + "durability": null, + "name": "Boots", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "634", + "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", + "equipment_slot": "10" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "226", + "durability": null, + "name": "Boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "635" + }, + { + "shop_price": "180", + "ge_buy_limit": "100", + "examine": "The ultimate in gnome design, now in pink.", + "durability": null, + "weight": "1", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "265", + "name": "Robe top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "636", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "265", + "durability": null, + "name": "Robe top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "637" + }, + { + "shop_price": "180", + "ge_buy_limit": "100", + "examine": "The ultimate in gnome design, now in green.", + "durability": null, + "weight": "1", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "235", + "name": "Robe top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "638", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "235", + "durability": null, + "name": "Robe top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "639" + }, + { + "shop_price": "180", + "ge_buy_limit": "100", + "examine": "The ultimate in gnome design, now in blue.", + "durability": null, + "weight": "1", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "447", + "name": "Robe top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "640", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "447", + "durability": null, + "name": "Robe top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "641" + }, + { + "shop_price": "180", + "ge_buy_limit": "100", + "examine": "The ultimate in gnome design, now in cream.", + "durability": null, + "weight": "1", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "396", + "name": "Robe top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "642", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "396", + "durability": null, + "name": "Robe top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "643" + }, + { + "shop_price": "180", + "ge_buy_limit": "100", + "examine": "The ultimate in gnome design, now in turquoise.", + "durability": null, + "weight": "1", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "70", + "name": "Robe top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "644", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "70", + "durability": null, + "name": "Robe top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "645" + }, + { + "ge_buy_limit": "100", + "shop_price": "180", + "examine": "Made by tree gnomes with a thing for pink.", + "grand_exchange_price": "249", + "durability": null, + "name": "Robe bottoms", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "646", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "249", + "durability": null, + "name": "Robe bottoms", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "647" + }, + { + "ge_buy_limit": "100", + "shop_price": "180", + "examine": "Made by tree gnomes with a thing for green.", + "grand_exchange_price": "210", + "durability": null, + "name": "Robe bottoms", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "648", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "210", + "durability": null, + "name": "Robe bottoms", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "649" + }, + { + "ge_buy_limit": "100", + "shop_price": "180", + "examine": "Made by tree gnomes with a thing for blue.", + "grand_exchange_price": "453", + "durability": null, + "name": "Robe bottoms", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "650", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "453", + "durability": null, + "name": "Robe bottoms", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "651" + }, + { + "ge_buy_limit": "100", + "shop_price": "180", + "examine": "Made by tree gnomes with a thing for cream.", + "grand_exchange_price": "348", + "durability": null, + "name": "Robe bottoms", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "652", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "348", + "durability": null, + "name": "Robe bottoms", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "653" + }, + { + "ge_buy_limit": "100", + "shop_price": "180", + "examine": "Made by tree gnomes with a thing for turquoise.", + "grand_exchange_price": "92", + "durability": null, + "name": "Robe bottoms", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "654", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "92", + "durability": null, + "name": "Robe bottoms", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "655" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "677", + "examine": "A silly, pink pointed hat.", + "durability": null, + "name": "Hat", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.4", + "hat": "true", + "id": "656", + "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "677", + "durability": null, + "name": "Hat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "657" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "480", + "examine": "A silly, green pointed hat.", + "durability": null, + "name": "Hat", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.4", + "hat": "true", + "id": "658", + "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "480", + "durability": null, + "name": "Hat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "659" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "421", + "examine": "A silly, blue pointed hat.", + "durability": null, + "name": "Hat", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.4", + "hat": "true", + "id": "660", + "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "421", + "durability": null, + "name": "Hat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "661" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1102", + "examine": "A silly, cream pointed hat.", + "durability": null, + "name": "Hat", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.4", + "hat": "true", + "id": "662", + "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1102", + "durability": null, + "name": "Hat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "663" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "295", + "examine": "A silly, turquoise pointed hat.", + "durability": null, + "name": "Hat", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.4", + "hat": "true", + "id": "664", + "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "295", + "durability": null, + "name": "Hat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "665" + }, + { + "examine": "Picture of a posing Paladin.", + "durability": null, + "name": "Portrait", + "weight": "1.3", + "archery_ticket_price": "0", + "id": "666" + }, + { + "turn90cw_anim": "821", + "examine": "A Faladian Knight's sword.", + "walk_anim": "819", + "durability": null, + "weight": "1", + "turn90ccw_anim": "822", + "attack_speed": "5", + "weapon_interface": "6", + "turn180_anim": "820", + "equip_audio": "2248", + "render_anim": "292", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "stand_anim": "809", + "attack_audios": "2500,2500,2517,2500", + "name": "Blurite sword", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "667", + "stand_turn_anim": "823", + "bonuses": "9,14,-2,0,0,0,3,2,0,0,0,10,0,0,0" + }, + { + "examine": "Definitely blue.", + "durability": null, + "name": "Blurite ore", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "668" + }, + { + "examine": "A receptacle for specimens!", + "durability": null, + "name": "Specimen jar", + "archery_ticket_price": "0", + "id": "669" + }, + { + "examine": "A small brush used to clean rock samples.", + "durability": null, + "name": "Specimen brush", + "archery_ticket_price": "0", + "id": "670" + }, + { + "examine": "A carefully-kept-safe skull sample.", + "durability": null, + "name": "Animal skull", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "671" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A special cup.", + "durability": null, + "name": "Special cup", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "672" + }, + { + "examine": "A lucky mascot.", + "durability": null, + "name": "Teddy", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "673" + }, + { + "examine": "A roughly shaped piece of rock.", + "durability": null, + "name": "Cracked sample", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "674" + }, + { + "examine": "A small pick for digging.", + "durability": null, + "name": "Rock pick", + "archery_ticket_price": "0", + "id": "675", + "equipment_slot": "3" + }, + { + "examine": "Used for digging!", + "durability": null, + "name": "Trowel", + "archery_ticket_price": "0", + "id": "676" + }, + { + "examine": "An empty tray for panning.", + "durability": null, + "name": "Panning tray", + "archery_ticket_price": "0", + "id": "677" + }, + { + "examine": "This tray contains gold nuggets.", + "durability": null, + "name": "Panning tray", + "archery_ticket_price": "0", + "id": "678" + }, + { + "examine": "This tray contains mud.", + "durability": null, + "name": "Panning tray", + "archery_ticket_price": "0", + "id": "679" + }, + { + "examine": "Pure, lovely gold!", + "durability": null, + "name": "Nuggets", + "archery_ticket_price": "0", + "id": "680" + }, + { + "examine": "An unusual symbol as yet unidentified by the archaeological expert.", + "durability": null, + "name": "Ancient talisman", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "681" + }, + { + "examine": "A letter waiting to be stamped.", + "durability": null, + "name": "Unstamped letter", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "682" + }, + { + "examine": "A sealed letter of recommendation.", + "durability": null, + "name": "Sealed letter", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "683" + }, + { + "examine": "Used to hold up trousers!", + "durability": null, + "name": "Belt buckle", + "weight": "1", + "archery_ticket_price": "0", + "id": "684" + }, + { + "examine": "Phew!", + "durability": null, + "name": "Old boot", + "archery_ticket_price": "0", + "id": "685" + }, + { + "examine": "A decent-enough weapon gone rusty.", + "durability": null, + "name": "Rusty sword", + "weight": "2", + "archery_ticket_price": "0", + "id": "686" + }, + { + "examine": "This must have been shot at high speed.", + "durability": null, + "name": "Broken arrow", + "archery_ticket_price": "0", + "id": "687" + }, + { + "examine": "Not Dick Whittington's helper at all!", + "durability": null, + "name": "Buttons", + "archery_ticket_price": "0", + "id": "688" + }, + { + "examine": "I pity the poor person beaten with this!", + "attack_audios": "2555,0,0,0", + "durability": null, + "name": "Broken staff", + "tradeable": "true", + "weight": "1.8", + "archery_ticket_price": "0", + "id": "689" + }, + { + "examine": "Smashed glass.", + "durability": null, + "name": "Picture", + "archery_ticket_price": "0", + "id": "690" + }, + { + "examine": "The owner has passed Earth Sciences Level 1 exam.", + "durability": null, + "name": "Level 1 certificate", + "archery_ticket_price": "0", + "id": "691" + }, + { + "examine": "The owner has passed Earth Sciences Level 2 exam.", + "durability": null, + "name": "Level 2 certificate", + "archery_ticket_price": "0", + "id": "692" + }, + { + "examine": "The owner has passed Earth Sciences Level 3 exam.", + "durability": null, + "name": "Level 3 certificate", + "archery_ticket_price": "0", + "id": "693" + }, + { + "examine": "Smashing!", + "durability": null, + "name": "Ceramic remains", + "archery_ticket_price": "0", + "id": "694" + }, + { + "examine": "Now, if I could just find a tooth fairy to sell this to...", + "durability": null, + "name": "Old tooth", + "archery_ticket_price": "0", + "id": "695" + }, + { + "examine": "A letter inviting me to use the private digging shafts.", + "durability": null, + "name": "Invitation letter", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "696" + }, + { + "examine": "It would be hard to repair this!", + "durability": null, + "name": "Damaged armour", + "weight": "7.75", + "archery_ticket_price": "0", + "id": "697" + }, + { + "examine": "Armour left over from a great fight.", + "durability": null, + "name": "Broken armour", + "weight": "8", + "archery_ticket_price": "0", + "id": "698" + }, + { + "examine": "An old stone slab with writing on it.", + "durability": null, + "name": "Stone tablet", + "archery_ticket_price": "0", + "id": "699" + }, + { + "examine": "An acrid chemical.", + "durability": null, + "name": "Chemical powder", + "archery_ticket_price": "0", + "id": "700" + }, + { + "examine": "An acrid chemical.", + "durability": null, + "name": "Ammonium nitrate", + "archery_ticket_price": "0", + "id": "701" + }, + { + "examine": "A strong chemical.", + "durability": null, + "name": "Unidentified liquid", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "702" + }, + { + "shop_price": "1", + "examine": "A strong chemical.", + "durability": null, + "name": "Nitroglycerin", + "weight": "1", + "archery_ticket_price": "0", + "id": "703" + }, + { + "examine": "Charcoal - crushed to small pieces!", + "durability": null, + "name": "Ground charcoal", + "archery_ticket_price": "0", + "id": "704" + }, + { + "shop_price": "1", + "examine": "A mixture of strong chemicals.", + "durability": null, + "name": "Mixed chemicals", + "weight": "0.03", + "archery_ticket_price": "0", + "id": "705" + }, + { + "shop_price": "1", + "examine": "A mixture of strong chemicals.", + "durability": null, + "name": "Mixed chemicals", + "weight": "0.035", + "archery_ticket_price": "0", + "id": "706" + }, + { + "examine": "A mixture of strong chemicals.", + "durability": null, + "name": "Chemical compound", + "weight": "0.035", + "archery_ticket_price": "0", + "id": "707" + }, + { + "examine": "The root of an arcenia plant.", + "durability": null, + "name": "Arcenia root", + "archery_ticket_price": "0", + "id": "708" + }, + { + "examine": "An unusually shaped vase. You can see something glinting inside.", + "durability": null, + "name": "Vase", + "archery_ticket_price": "0", + "id": "710" + }, + { + "examine": "It's about chemicals, judging from its cover.", + "durability": null, + "name": "Book on chemicals", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "711" + }, + { + "shop_price": "10", + "examine": "A nice cup of tea.", + "grand_exchange_price": "30", + "durability": null, + "name": "Cup of tea", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "712" + }, + { + "examine": "Notes given to you by Radimus Erkle, it includes a partially completed map.", + "durability": null, + "name": "Radimus notes", + "archery_ticket_price": "0", + "id": "714" + }, + { + "examine": "Notes given to you by Radimus Erkle, it includes a partially completed map.", + "durability": null, + "name": "Radimus notes", + "archery_ticket_price": "0", + "id": "715" + }, + { + "examine": "It makes a loud but interesting sound when swung in the air.", + "durability": null, + "name": "Bull roarer", + "archery_ticket_price": "0", + "id": "716" + }, + { + "examine": "A scrawled note with spidery writing on it.", + "durability": null, + "name": "Scrawled note", + "archery_ticket_price": "0", + "id": "717" + }, + { + "examine": "A scrawled note with spidery writing on it.", + "durability": null, + "name": "A scribbled note", + "archery_ticket_price": "0", + "id": "718" + }, + { + "examine": "A scrawled note with spidery writing on it.", + "durability": null, + "name": "Scrumpled note", + "archery_ticket_price": "0", + "id": "719" + }, + { + "examine": "A rough sketch of a bowl shaped vessel given to you by Gujuo.", + "durability": null, + "name": "Sketch", + "archery_ticket_price": "0", + "id": "720" + }, + { + "examine": "A specially made bowl constructed out of pure gold.", + "durability": null, + "name": "Gold bowl", + "archery_ticket_price": "0", + "id": "721" + }, + { + "examine": "A specially made bowl constructed out of pure gold and blessed.", + "durability": null, + "name": "Blessed gold bowl", + "weight": "0.8", + "archery_ticket_price": "0", + "id": "722" + }, + { + "examine": "A blessed golden bowl. It has pure sacred water in it.", + "durability": null, + "name": "Golden bowl", + "weight": "1", + "archery_ticket_price": "0", + "id": "723" + }, + { + "examine": "A blessed golden bowl. It has pure sacred water in it.", + "durability": null, + "name": "Golden bowl", + "weight": "1", + "archery_ticket_price": "0", + "id": "724" + }, + { + "examine": "A blessed golden bowl. It has pure sacred water in it.", + "durability": null, + "name": "Golden bowl", + "weight": "1", + "archery_ticket_price": "0", + "id": "725" + }, + { + "examine": "A blessed golden bowl. It has pure sacred water in it.", + "durability": null, + "name": "Golden bowl", + "weight": "1", + "archery_ticket_price": "0", + "id": "726" + }, + { + "examine": "One of nature's pipes.", + "durability": null, + "name": "Hollow reed", + "weight": "0.012", + "archery_ticket_price": "0", + "id": "727" + }, + { + "examine": "One of nature's pipes.", + "durability": null, + "name": "Hollow reed", + "weight": "0.012", + "archery_ticket_price": "0", + "id": "728" + }, + { + "examine": "It looks like the Shamans personal notes...", + "durability": null, + "name": "Shamans tome", + "archery_ticket_price": "0", + "id": "729" + }, + { + "examine": "An ancient tome on Demonology.", + "durability": null, + "name": "Binding book", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "730" + }, + { + "shop_price": "160", + "examine": "An enchanted empty glass vial.", + "durability": null, + "name": "Enchanted vial", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "731" + }, + { + "examine": "A vial of holy water, good against certain demons.", + "durability": null, + "name": "Holy water", + "archery_ticket_price": "0", + "id": "732", + "weapon_interface": "18", + "bonuses": "0,0,0,0,12,0,0,0,0,0,0,0,0,0,24", + "equipment_slot": "3" + }, + { + "examine": "Fragments of a broken container.", + "durability": null, + "name": "Smashed glass", + "archery_ticket_price": "0", + "id": "733" + }, + { + "examine": "These need to be germinated before they can be used. / These are germinated and ready to be planted in fertile soil.", + "durability": null, + "name": "Yommi tree seeds", + "archery_ticket_price": "0", + "id": "735" + }, + { + "examine": "These need to be germinated before they can be used. / These are germinated and ready to be planted in fertile soil.", + "durability": null, + "name": "Yommi tree seeds", + "archery_ticket_price": "0", + "id": "736" + }, + { + "examine": "A Snakeweed mixture, needs another ingredient.", + "durability": null, + "name": "Snakeweed mixture", + "weight": "1", + "archery_ticket_price": "0", + "id": "737" + }, + { + "examine": "It's a mixture of ardrigal and water. Needs another ingredient.", + "durability": null, + "name": "Ardrigal mixture", + "archery_ticket_price": "0", + "id": "738" + }, + { + "examine": "A bravery potion for which Gujuo gave you the details, let's hope it works.", + "durability": null, + "name": "Bravery potion", + "archery_ticket_price": "0", + "id": "739" + }, + { + "shop_price": "160", + "examine": "A silly, blue pointed hat.", + "grand_exchange_price": "472", + "durability": null, + "name": "Blue hat", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "hat": "true", + "id": "740", + "bonuses": "0,0,0,2,0,0,0,0,2,0,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "examine": "It looks like it's been snapped off of something.", + "durability": null, + "name": "Chunk of crystal", + "archery_ticket_price": "0", + "id": "741" + }, + { + "examine": "It looks like it's been snapped off of something.", + "durability": null, + "name": "Hunk of crystal", + "archery_ticket_price": "0", + "id": "742" + }, + { + "examine": "It looks like it's been snapped off of something.", + "durability": null, + "name": "Lump of crystal", + "archery_ticket_price": "0", + "id": "743" + }, + { + "examine": "A heart shaped crystal.", + "durability": null, + "name": "Heart crystal", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "744" + }, + { + "examine": "A heart shaped crystal.", + "durability": null, + "name": "Heart crystal", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "745" + }, + { + "examine": "A black obsidian dagger, it has a strange aura about it.", + "durability": null, + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "defence_anim": "378", + "equipment_slot": "3", + "attack_anims": "400,400,400,400", + "attack_audios": "2517,2517,2500,2517", + "name": "Dark dagger", + "archery_ticket_price": "0", + "id": "746", + "bonuses": "5,3,-4,1,0,0,0,0,1,0,0,0,0,0,0" + }, + { + "examine": "A black obsidian dagger, it has a strange aura about it - it seems to be glowing.", + "durability": null, + "attack_speed": "6", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "defence_anim": "378", + "equipment_slot": "3", + "attack_anims": "400,400,400,400", + "attack_audios": "2517,2517,2500,2517", + "name": "Glowing dagger", + "archery_ticket_price": "0", + "id": "747", + "bonuses": "5,3,-4,1,0,0,0,0,1,0,0,0,0,0,0" + }, + { + "examine": "A powerful spell for good.", + "durability": null, + "name": "Holy force", + "archery_ticket_price": "0", + "id": "748" + }, + { + "examine": "A well carved totem pole made from the trunk of a Yommi tree.", + "durability": null, + "name": "Yommi totem", + "weight": "3", + "archery_ticket_price": "0", + "id": "749" + }, + { + "examine": "A gilded totem pole from the Kharazi tribe.", + "durability": null, + "name": "Gilded totem", + "archery_ticket_price": "0", + "id": "750" + }, + { + "examine": "A common gnomeball, obtained by playing gnomeball.", + "durability": null, + "name": "Gnomeball", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "751", + "equipment_slot": "3" + }, + { + "durability": null, + "name": "Gnomeball", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "752" + }, + { + "ge_buy_limit": "100", + "examine": "Poisonous berries.", + "grand_exchange_price": "42", + "durability": null, + "name": "Cadava berries", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "753" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "42", + "durability": null, + "name": "Cadava berries", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "754" + }, + { + "shop_price": "1", + "examine": "This potion will most certainly almost kill you.", + "durability": null, + "name": "Cadava potion", + "archery_ticket_price": "0", + "id": "756" + }, + { + "examine": "Phoenix Gang weapon store key.", + "durability": null, + "name": "Weapon store key", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "759" + }, + { + "durability": null, + "name": "Weapon store key", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "760" + }, + { + "destroy_message": "You'll have to kill Jonny the beard in order to get another one.", + "examine": "An intelligence report.", + "durability": null, + "name": "Intel report", + "destroy": "true", + "archery_ticket_price": "0", + "id": "761" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Half of the Shield of Arrav.", + "durability": null, + "name": "Broken shield", + "destroy": "true", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "763" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Half of the Shield of Arrav.", + "durability": null, + "name": "Broken shield", + "destroy": "true", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "765" + }, + { + "turn90cw_anim": "821", + "examine": "Second-rate crossbow, former property of the Phoenix Gang.", + "walk_anim": "4226", + "durability": null, + "weight": "3", + "turn90ccw_anim": "822", + "attack_speed": "6", + "weapon_interface": "17", + "turn180_anim": "4227", + "equip_audio": "2244", + "render_anim": "175", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "426,426,426,426", + "stand_anim": "4591", + "attack_audios": "2700,0,0,0", + "name": "Phoenix crossbow", + "tradeable": "true", + "run_anim": "4228", + "archery_ticket_price": "0", + "id": "767", + "stand_turn_anim": "823", + "bonuses": "0,0,0,0,6,0,0,0,0,0,0,0,0,0,0" + }, + { + "durability": null, + "name": "Phoenix crossbow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "768" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Entrance certificate to the Imperial Guard.", + "durability": null, + "name": "Certificate", + "archery_ticket_price": "0", + "id": "769" + }, + { + "destroy_message": "You can get another branch if you chop the dramen tree underneath Entrana again.", + "examine": "A limb of the fabled Dramen tree.", + "durability": null, + "name": "Dramen branch", + "tradeable": "false", + "destroy": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "771" + }, + { + "turn90cw_anim": "1207", + "examine": "Crafted from a Dramen tree branch.", + "walk_anim": "1205", + "durability": null, + "weight": "1.8", + "turn90ccw_anim": "1208", + "attack_speed": "4", + "weapon_interface": "1", + "turn180_anim": "1206", + "equip_audio": "2247", + "render_anim": "28", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "stand_anim": "813", + "attack_audios": "2555,0,0,0", + "name": "Dramen staff", + "tradeable": "false", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "772", + "stand_turn_anim": "1209", + "bonuses": "-1,-1,10,10,0,2,3,1,10,0,0,10,0,0,0" + }, + { + "examine": "A perfect ruby ring.", + "durability": null, + "name": "'perfect' ring", + "archery_ticket_price": "0", + "id": "773", + "equipment_slot": "12" + }, + { + "examine": "A perfect ruby necklace.", + "durability": null, + "name": "'perfect' necklace", + "archery_ticket_price": "0", + "id": "774", + "equipment_slot": "2" + }, + { + "destroy_message": "You can obtain another set of Cooking gauntlets from Dimintheis.", + "examine": "These gauntlets empower with a greater ability to cook fish.", + "durability": null, + "name": "Cooking gauntlets", + "tradeable": "false", + "destroy": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "775", + "bonuses": "2,2,2,0,0,8,9,7,0,0,3,2,0,0,0", + "equipment_slot": "9" + }, + { + "destroy_message": "You can obtain another set of Goldsmith gauntlets from Dimintheis.", + "examine": "These gauntlets empower the bearer whilst making gold.", + "durability": null, + "name": "Goldsmith gauntlets", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "776", + "bonuses": "2,2,2,0,0,8,9,7,0,0,3,2,0,0,0", + "equipment_slot": "9" + }, + { + "destroy_message": "You can obtain another set of Chaos gauntlets from Dimintheis.", + "examine": "These gauntlets empower spell casters.", + "durability": null, + "name": "Chaos gauntlets", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "777", + "bonuses": "2,2,2,0,0,8,9,7,0,0,3,2,0,0,0", + "equipment_slot": "9" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "My reward for assisting the Fitzharmon family.", + "durability": null, + "name": "Family gauntlets", + "weight": "1", + "archery_ticket_price": "0", + "id": "778", + "bonuses": "2,2,2,0,0,8,9,7,0,0,0,2,0,0,0", + "equipment_slot": "9" + }, + { + "examine": "A fragment of the Fitzharmon family crest.", + "durability": null, + "name": "Crest part", + "archery_ticket_price": "0", + "id": "779" + }, + { + "examine": "A fragment of the Fitzharmon family crest.", + "durability": null, + "name": "Crest part", + "archery_ticket_price": "0", + "id": "780" + }, + { + "examine": "A fragment of the Fitzharmon family crest.", + "durability": null, + "name": "Crest part", + "archery_ticket_price": "0", + "id": "781" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A sample of the bark from the Grand Tree.", + "durability": null, + "name": "Bark sample", + "archery_ticket_price": "0", + "id": "783" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A book to translate the ancient gnome language into English.", + "durability": null, + "name": "Translation book", + "archery_ticket_price": "0", + "id": "784" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Perhaps I should read it and see what Glough is up to!", + "durability": null, + "name": "Glough's journal", + "archery_ticket_price": "0", + "id": "785" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Hazelmere wrote something down on this scroll.", + "durability": null, + "name": "Hazelmere's scroll", + "archery_ticket_price": "0", + "id": "786" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "An order from the Karamja shipyard.", + "durability": null, + "name": "Lumber order", + "archery_ticket_price": "0", + "id": "787" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "The key to Glough's chest.", + "durability": null, + "name": "Glough's key", + "weight": "1", + "archery_ticket_price": "0", + "id": "788" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Twigs bound together in the shape of a (Z/U/T/O).", + "durability": null, + "name": "Twigs", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "789" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Twigs bound together in the shape of a (Z/U/T/O).", + "durability": null, + "name": "Twigs", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "790" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Twigs bound together in the shape of a (Z/U/T/O).", + "durability": null, + "name": "Twigs", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "791" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Twigs bound together in the shape of a (Z/U/T/O).", + "durability": null, + "name": "Twigs", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "792" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "An ancient rock with strange magical properties.", + "durability": null, + "name": "Daconia rock", + "tradeable": "false", + "destroy": "true", + "weight": "3", + "archery_ticket_price": "0", + "id": "793" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "These are plans for an invasion!", + "durability": null, + "name": "Invasion plans", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "794" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A model of a Karamja warship", + "durability": null, + "name": "War ship", + "weight": "0.01", + "archery_ticket_price": "0", + "id": "795" + }, + { + "shop_price": "4", + "ge_buy_limit": "1000", + "examine": "A finely balanced throwing axe.", + "durability": null, + "attack_speed": "5", + "weapon_interface": "18", + "equip_audio": "2232", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "3", + "attack_audios": "2706,2706,2706", + "name": "Bronze thrownaxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "800", + "bonuses": "0,0,0,0,4,0,0,0,0,0,0,0,0,0,5" + }, + { + "shop_price": "13", + "ge_buy_limit": "1000", + "examine": "A finely balanced throwing axe.", + "durability": null, + "attack_speed": "5", + "weapon_interface": "18", + "equip_audio": "2232", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "14", + "attack_audios": "2706,2706,2706", + "name": "Iron thrownaxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "801", + "bonuses": "0,0,0,0,5,0,0,0,0,0,0,0,0,0,7" + }, + { + "requirements": "{4,5}", + "shop_price": "38", + "ge_buy_limit": "1000", + "examine": "A finely balanced throwing axe.", + "durability": null, + "attack_speed": "5", + "weapon_interface": "18", + "equip_audio": "2232", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "60", + "attack_audios": "2706,2706,2706", + "name": "Steel thrownaxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "802", + "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,11" + }, + { + "requirements": "{4,20}", + "shop_price": "105", + "ge_buy_limit": "1000", + "examine": "A finely balanced throwing axe.", + "durability": null, + "attack_speed": "5", + "weapon_interface": "18", + "equip_audio": "2232", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "135", + "attack_audios": "2706,2706,2706", + "name": "Mithril thrownaxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "803", + "bonuses": "0,0,0,0,12,0,0,0,0,0,0,0,0,0,16" + }, + { + "requirements": "{4,30}", + "shop_price": "262", + "ge_buy_limit": "1000", + "examine": "A finely balanced throwing axe.", + "durability": null, + "attack_speed": "5", + "weapon_interface": "18", + "equip_audio": "2232", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "138", + "attack_audios": "2706,2706,2706", + "name": "Adamant thrownaxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "804", + "bonuses": "0,0,0,0,17,0,0,0,0,0,0,0,0,0,23" + }, + { + "requirements": "{4,40}", + "shop_price": "698", + "ge_buy_limit": "1000", + "examine": "A finely balanced throwing axe.", + "has_special": "true", + "durability": null, + "attack_speed": "5", + "weapon_interface": "18", + "equip_audio": "2232", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "243", + "attack_audios": "2706,2706,2706", + "name": "Rune thrownaxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "805", + "bonuses": "0,0,0,0,26,0,0,0,0,0,0,0,0,0,36" + }, + { + "ge_buy_limit": "1000", + "examine": "A deadly throwing dart with a bronze tip.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "582,582,582,582", + "grand_exchange_price": "53", + "attack_audios": "2547,0,0,0", + "name": "Bronze dart", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "806", + "bonuses": "0,0,0,0,3,0,0,0,0,0,0,0,0,0,1" + }, + { + "ge_buy_limit": "1000", + "examine": "A deadly throwing dart with an iron tip.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "582,582,582,582", + "grand_exchange_price": "59", + "attack_audios": "2547,0,0,0", + "name": "Iron dart", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "807", + "bonuses": "0,0,0,0,4,0,0,0,0,0,0,0,0,0,3" + }, + { + "requirements": "{4,5}", + "ge_buy_limit": "1000", + "examine": "A deadly throwing dart with a steel tip.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "582,582,582,582", + "grand_exchange_price": "50", + "attack_audios": "2547,0,0,0", + "name": "Steel dart", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "808", + "bonuses": "0,0,0,0,5,0,0,0,0,0,0,0,0,0,4" + }, + { + "requirements": "{4,20}", + "ge_buy_limit": "1000", + "examine": "A deadly throwing dart with a mithril tip.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "582,582,582,582", + "grand_exchange_price": "68", + "attack_audios": "2547,0,0,0", + "name": "Mithril dart", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "809", + "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,7" + }, + { + "requirements": "{4,30}", + "ge_buy_limit": "1000", + "examine": "A deadly throwing dart with an adamantite tip.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "582,582,582,582", + "grand_exchange_price": "96", + "attack_audios": "2547,0,0,0", + "name": "Adamant dart", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "810", + "bonuses": "0,0,0,0,11,0,0,0,0,0,0,0,0,0,10" + }, + { + "requirements": "{4,40}", + "ge_buy_limit": "1000", + "examine": "A deadly throwing dart with a rune tip.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "582,582,582,582", + "grand_exchange_price": "122", + "attack_audios": "2547,0,0,0", + "name": "Rune dart", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "811", + "bonuses": "0,0,0,0,15,0,0,0,0,0,0,0,0,0,14" + }, + { + "ge_buy_limit": "1000", + "examine": "A deadly throwing dart with a bronze tip.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "582,582,582,582", + "grand_exchange_price": "66", + "attack_audios": "2547,0,0,0", + "name": "Bronze dart(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "812", + "bonuses": "0,0,0,0,3,0,0,0,0,0,0,0,0,0,1" + }, + { + "ge_buy_limit": "1000", + "examine": "A deadly throwing dart with an iron tip.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "582,582,582,582", + "grand_exchange_price": "66", + "attack_audios": "2547,0,0,0", + "name": "Iron dart(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "813", + "bonuses": "0,0,0,0,4,0,0,0,0,0,0,0,0,0,3" + }, + { + "requirements": "{4,5}", + "ge_buy_limit": "1000", + "examine": "A deadly throwing dart with a steel tip.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "582,582,582,582", + "grand_exchange_price": "75", + "attack_audios": "2547,0,0,0", + "name": "Steel dart(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "814", + "bonuses": "0,0,0,0,5,0,0,0,0,0,0,0,0,0,4" + }, + { + "requirements": "{4,20}", + "ge_buy_limit": "1000", + "examine": "A deadly throwing dart with a mithril tip.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "582,582,582,582", + "grand_exchange_price": "65", + "attack_audios": "2547,0,0,0", + "name": "Mithril dart(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "815", + "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,7" + }, + { + "requirements": "{4,30}", + "ge_buy_limit": "1000", + "examine": "A deadly throwing dart with an adamantite tip.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "582,582,582,582", + "grand_exchange_price": "75", + "attack_audios": "2547,0,0,0", + "name": "Adamant dart(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "816", + "bonuses": "0,0,0,0,11,0,0,0,0,0,0,0,0,0,10" + }, + { + "requirements": "{4,40}", + "ge_buy_limit": "1000", + "examine": "A deadly throwing dart with a rune tip.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "582,582,582,582", + "grand_exchange_price": "110", + "attack_audios": "2547,0,0,0", + "name": "Rune dart(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "817", + "bonuses": "0,0,0,0,15,0,0,0,0,0,0,0,0,0,14" + }, + { + "attack_audios": "2547,0,0,0", + "durability": null, + "name": "Poisoned dart(p)", + "archery_ticket_price": "0", + "id": "818", + "equip_audio": "2244", + "equipment_slot": "3" + }, + { + "ge_buy_limit": "5000", + "examine": "A deadly looking dart tip made of bronze - needs feathers for flight.", + "grand_exchange_price": "24", + "attack_audios": "2547,0,0,0", + "durability": null, + "name": "Bronze dart tip", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "819" + }, + { + "ge_buy_limit": "5000", + "examine": "A deadly looking dart tip made of iron - needs feathers for flight.", + "grand_exchange_price": "19", + "attack_audios": "2547,0,0,0", + "durability": null, + "name": "Iron dart tip", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "820" + }, + { + "ge_buy_limit": "5000", + "examine": "A deadly looking dart tip made of steel - needs feathers for flight.", + "grand_exchange_price": "66", + "attack_audios": "2547,0,0,0", + "durability": null, + "name": "Steel dart tip", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "821" + }, + { + "ge_buy_limit": "5000", + "examine": "A deadly looking dart tip made of mithril - needs feathers for flight.", + "grand_exchange_price": "97", + "attack_audios": "2547,0,0,0", + "durability": null, + "name": "Mithril dart tip", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "822" + }, + { + "ge_buy_limit": "5000", + "examine": "A deadly looking dart tip made of adamantite - needs feathers for flight.", + "grand_exchange_price": "212", + "attack_audios": "2547,0,0,0", + "durability": null, + "name": "Adamant dart tip", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "823" + }, + { + "ge_buy_limit": "5000", + "examine": "A deadly looking dart tip made of runite - needs feathers for flight.", + "grand_exchange_price": "498", + "attack_audios": "2547,0,0,0", + "durability": null, + "name": "Rune dart tip", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "824" + }, + { + "shop_price": "6", + "ge_buy_limit": "1000", + "examine": "A bronze-tipped javelin.", + "durability": null, + "attack_speed": "6", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "6", + "name": "Bronze javelin", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "825", + "bonuses": "0,0,0,0,5,0,0,0,0,0,0,0,0,0,6" + }, + { + "shop_price": "8", + "ge_buy_limit": "1000", + "examine": "An iron-tipped javelin.", + "durability": null, + "attack_speed": "6", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "2", + "name": "Iron javelin", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "826", + "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,10" + }, + { + "requirements": "{4,5}", + "shop_price": "37", + "ge_buy_limit": "1000", + "examine": "A steel-tipped javelin.", + "durability": null, + "attack_speed": "6", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "19", + "name": "Steel javelin", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "827", + "bonuses": "0,0,0,0,12,0,0,0,0,0,0,0,0,0,12" + }, + { + "requirements": "{4,20}", + "shop_price": "79", + "ge_buy_limit": "1000", + "examine": "A mithril tipped javelin.", + "durability": null, + "attack_speed": "6", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "25", + "name": "Mithril javelin", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "828", + "bonuses": "0,0,0,0,17,0,0,0,0,0,0,0,0,0,18" + }, + { + "requirements": "{4,30}", + "shop_price": "100", + "ge_buy_limit": "1000", + "examine": "An adamant tipped javelin.", + "durability": null, + "attack_speed": "6", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "51", + "name": "Adamant javelin", + "tradeable": "true", + "archery_ticket_price": "100", + "id": "829", + "bonuses": "0,0,0,0,24,0,0,0,0,0,0,0,0,0,28" + }, + { + "requirements": "{4,40}", + "shop_price": "624", + "ge_buy_limit": "1000", + "examine": "A rune tipped javelin.", + "durability": null, + "attack_speed": "6", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "186", + "name": "Rune javelin", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "830", + "bonuses": "0,0,0,0,38,0,0,0,0,0,0,0,0,0,42" + }, + { + "shop_price": "6", + "ge_buy_limit": "1000", + "examine": "A bronze-tipped javelin.", + "durability": null, + "attack_speed": "6", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "19", + "name": "Bronze javelin(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "831", + "bonuses": "0,0,0,0,5,0,0,0,0,0,0,0,0,0,6" + }, + { + "shop_price": "8", + "ge_buy_limit": "1000", + "examine": "An iron-tipped javelin.", + "durability": null, + "attack_speed": "6", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "19", + "name": "Iron javelin(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "832", + "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,10" + }, + { + "requirements": "{4,5}", + "shop_price": "37", + "ge_buy_limit": "1000", + "examine": "A steel-tipped javelin.", + "durability": null, + "attack_speed": "6", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "34", + "name": "Steel javelin(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "833", + "bonuses": "0,0,0,0,12,0,0,0,0,0,0,0,0,0,12" + }, + { + "requirements": "{4,20}", + "shop_price": "79", + "ge_buy_limit": "1000", + "examine": "A mithril tipped javelin.", + "durability": null, + "attack_speed": "6", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "44", + "name": "Mithril javelin(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "834", + "bonuses": "0,0,0,0,17,0,0,0,0,0,0,0,0,0,18" + }, + { + "requirements": "{4,30}", + "shop_price": "100", + "ge_buy_limit": "1000", + "examine": "An adamant tipped javelin.", + "durability": null, + "attack_speed": "6", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "88", + "name": "Adamant javelin(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "835", + "bonuses": "0,0,0,0,24,0,0,0,0,0,0,0,0,0,28" + }, + { + "requirements": "{4,40}", + "shop_price": "624", + "ge_buy_limit": "1000", + "examine": "A rune tipped javelin.", + "durability": null, + "attack_speed": "6", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "256", + "name": "Rune javelin(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "836", + "bonuses": "0,0,0,0,38,0,0,0,0,0,0,0,0,0,42" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "821", + "examine": "This fires crossbow bolts.", + "walk_anim": "4226", + "turn90ccw_anim": "822", + "attack_speed": "6", + "turn180_anim": "4227", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "4230,4230,4230,4230", + "grand_exchange_price": "276", + "stand_anim": "4591", + "tradeable": "true", + "run_anim": "4228", + "archery_ticket_price": "0", + "id": "837", + "stand_turn_anim": "823", + "bonuses": "0,0,0,0,6,0,0,0,0,0,0,0,0,0,0", + "shop_price": "70", + "durability": null, + "weight": "8", + "weapon_interface": "17", + "equip_audio": "2244", + "render_anim": "175", + "attack_audios": "2700,0,0,0", + "name": "Crossbow" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "276", + "durability": null, + "name": "Crossbow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "838" + }, + { + "ge_buy_limit": "5000", + "turn90cw_anim": "821", + "examine": "A nice sturdy bow.", + "walk_anim": "819", + "turn90ccw_anim": "822", + "attack_speed": "6", + "two_handed": "true", + "turn180_anim": "820", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "426,426,426,426", + "grand_exchange_price": "55", + "stand_anim": "808", + "tradeable": "true", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "839", + "stand_turn_anim": "823", + "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,0", + "shop_price": "80", + "durability": null, + "weight": "1.8", + "weapon_interface": "16", + "equip_audio": "2244", + "render_anim": "1", + "attack_audios": "2700,0,0,0", + "name": "Longbow" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "55", + "durability": null, + "name": "Longbow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "840" + }, + { + "ge_buy_limit": "5000", + "turn90cw_anim": "821", + "examine": "A shortbow made of wood.", + "walk_anim": "819", + "turn90ccw_anim": "822", + "attack_speed": "4", + "two_handed": "true", + "turn180_anim": "820", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "426,426,426,426", + "grand_exchange_price": "79", + "stand_anim": "808", + "tradeable": "true", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "841", + "stand_turn_anim": "823", + "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,0", + "shop_price": "50", + "durability": null, + "weight": "1.33", + "weapon_interface": "16", + "equip_audio": "2244", + "render_anim": "1", + "attack_audios": "2700,0,0,0", + "name": "Shortbow" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "79", + "durability": null, + "name": "Shortbow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "842" + }, + { + "requirements": "{4,5}", + "shop_price": "164", + "ge_buy_limit": "5000", + "examine": "A shortbow made out of oak, still effective.", + "durability": null, + "weight": "1.8", + "attack_speed": "4", + "two_handed": "true", + "weapon_interface": "16", + "equip_audio": "2244", + "render_anim": "2588", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "426,426,426,426", + "grand_exchange_price": "54", + "attack_audios": "2700,0,0,0", + "name": "Oak shortbow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "843", + "bonuses": "0,0,0,0,14,0,0,0,0,0,0,0,0,0,0" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "54", + "durability": null, + "name": "Oak shortbow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "844" + }, + { + "requirements": "{4,5}", + "shop_price": "160", + "ge_buy_limit": "5000", + "examine": "A nice sturdy bow made out of oak.", + "durability": null, + "weight": "2", + "attack_speed": "6", + "two_handed": "true", + "weapon_interface": "16", + "equip_audio": "2244", + "render_anim": "2588", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "426,426,426,426", + "grand_exchange_price": "132", + "attack_audios": "2700,0,0,0", + "name": "Oak longbow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "845", + "bonuses": "0,0,0,0,14,0,0,0,0,0,0,0,0,0,0" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "132", + "durability": null, + "name": "Oak longbow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "846" + }, + { + "requirements": "{4,20}", + "shop_price": "320", + "ge_buy_limit": "5000", + "examine": "A nice sturdy bow made out of willow.", + "durability": null, + "weight": "1.5", + "attack_speed": "6", + "two_handed": "true", + "weapon_interface": "16", + "equip_audio": "2244", + "render_anim": "2588", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "426,426,426,426", + "grand_exchange_price": "132", + "attack_audios": "2700,0,0,0", + "name": "Willow longbow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "847", + "bonuses": "0,0,0,0,20,0,0,0,0,0,0,0,0,0,0" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "132", + "durability": null, + "name": "Willow longbow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "848" + }, + { + "requirements": "{4,20}", + "shop_price": "200", + "ge_buy_limit": "5000", + "examine": "A shortbow made out of willow, still effective.", + "durability": null, + "weight": "1", + "attack_speed": "4", + "two_handed": "true", + "weapon_interface": "16", + "equip_audio": "2244", + "render_anim": "2588", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "426,426,426,426", + "grand_exchange_price": "106", + "attack_audios": "2700,0,0,0", + "name": "Willow shortbow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "849", + "bonuses": "0,0,0,0,20,0,0,0,0,0,0,0,0,0,0" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "106", + "durability": null, + "name": "Willow shortbow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "850" + }, + { + "requirements": "{4,30}", + "shop_price": "640", + "ge_buy_limit": "5000", + "examine": "A nice sturdy bow made out of maple.", + "durability": null, + "weight": "1.8", + "attack_speed": "6", + "two_handed": "true", + "weapon_interface": "16", + "equip_audio": "2244", + "render_anim": "2588", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "426,426,426,426", + "lendable": "true", + "grand_exchange_price": "320", + "attack_audios": "2700,0,0,0", + "name": "Maple longbow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "851", + "bonuses": "0,0,0,0,29,0,0,0,0,0,0,0,0,0,0" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "320", + "durability": null, + "name": "Maple longbow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "852" + }, + { + "requirements": "{4,30}", + "shop_price": "400", + "ge_buy_limit": "5000", + "examine": "A shortbow made out of maple, still effective.", + "durability": null, + "weight": "1", + "attack_speed": "4", + "two_handed": "true", + "weapon_interface": "16", + "equip_audio": "2244", + "render_anim": "2588", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "426,426,426,426", + "lendable": "true", + "grand_exchange_price": "290", + "attack_audios": "2700,0,0,0", + "name": "Maple shortbow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "853", + "bonuses": "0,0,0,0,29,0,0,0,0,0,0,0,0,0,0" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "290", + "durability": null, + "name": "Maple shortbow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "854" + }, + { + "requirements": "{4,40}", + "shop_price": "674", + "ge_buy_limit": "5000", + "examine": "A nice sturdy bow made out of yew.", + "durability": null, + "weight": "1.8", + "attack_speed": "6", + "two_handed": "true", + "weapon_interface": "16", + "equip_audio": "2244", + "render_anim": "2588", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "426,426,426,426", + "lendable": "true", + "grand_exchange_price": "706", + "attack_audios": "2700,0,0,0", + "name": "Yew longbow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "855", + "bonuses": "0,0,0,0,47,0,0,0,0,0,0,0,0,0,0" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "706", + "durability": null, + "name": "Yew longbow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "856" + }, + { + "requirements": "{4,40}", + "ge_buy_limit": "5000", + "examine": "A shortbow made out of yew, still effective.", + "durability": null, + "weight": "1", + "attack_speed": "4", + "two_handed": "true", + "weapon_interface": "16", + "equip_audio": "2244", + "render_anim": "2588", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "426,426,426,426", + "lendable": "true", + "grand_exchange_price": "422", + "attack_audios": "2700,0,0,0", + "name": "Yew shortbow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "857", + "bonuses": "0,0,0,0,47,0,0,0,0,0,0,0,0,0,0" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "422", + "durability": null, + "name": "Yew shortbow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "858" + }, + { + "requirements": "{4,50}", + "shop_price": "1270", + "ge_buy_limit": "5000", + "examine": "A nice sturdy magical bow.", + "has_special": "true", + "durability": null, + "weight": "1.8", + "attack_speed": "6", + "two_handed": "true", + "weapon_interface": "16", + "equip_audio": "2244", + "render_anim": "2588", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "426,426,426,426", + "lendable": "true", + "grand_exchange_price": "1437", + "attack_audios": "2700,0,0,0", + "name": "Magic longbow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "859", + "bonuses": "0,0,0,0,69,0,0,0,0,0,0,0,0,0,0" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "1437", + "durability": null, + "name": "Magic longbow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "860" + }, + { + "requirements": "{4,50}", + "shop_price": "5600", + "ge_buy_limit": "5000", + "examine": "Short and magical, but still effective.", + "has_special": "true", + "durability": null, + "weight": "1.3", + "attack_speed": "4", + "two_handed": "true", + "weapon_interface": "16", + "equip_audio": "2244", + "render_anim": "2588", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "426,426,426,426", + "lendable": "true", + "grand_exchange_price": "959", + "attack_audios": "2700,0,0,0", + "name": "Magic shortbow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "861", + "bonuses": "0,0,0,0,69,0,0,0,0,0,0,0,0,0,0" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "959", + "durability": null, + "name": "Magic shortbow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "862" + }, + { + "shop_price": "58", + "ge_buy_limit": "10000", + "examine": "A finely balanced throwing knife.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "87", + "attack_audios": "2704,0,0,0", + "name": "Iron knife", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "863", + "bonuses": "0,0,0,0,5,0,0,0,0,0,0,0,0,0,4" + }, + { + "shop_price": "14", + "ge_buy_limit": "10000", + "examine": "A finely balanced throwing knife.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "73", + "attack_audios": "2704,0,0,0", + "name": "Bronze knife", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "864", + "bonuses": "0,0,0,0,4,0,0,0,0,0,0,0,0,0,3" + }, + { + "requirements": "{4,5}", + "shop_price": "68", + "ge_buy_limit": "10000", + "examine": "A finely balanced throwing knife.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "136", + "attack_audios": "2704,0,0,0", + "name": "Steel knife", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "865", + "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,7" + }, + { + "requirements": "{4,20}", + "ge_buy_limit": "10000", + "examine": "A finely balanced throwing knife.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "201", + "attack_audios": "2704,0,0,0", + "name": "Mithril knife", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "866", + "bonuses": "0,0,0,0,11,0,0,0,0,0,0,0,0,0,10" + }, + { + "requirements": "{4,30}", + "ge_buy_limit": "10000", + "examine": "A finely balanced throwing knife.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "421", + "attack_audios": "2704,0,0,0", + "name": "Adamant knife", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "867", + "bonuses": "0,0,0,0,15,0,0,0,0,0,0,0,0,0,14" + }, + { + "requirements": "{4,40}", + "ge_buy_limit": "10000", + "examine": "A finely balanced throwing knife.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "1132", + "attack_audios": "2704,0,0,0", + "name": "Rune knife", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "868", + "bonuses": "0,0,0,0,25,0,0,0,0,0,0,0,0,0,24" + }, + { + "requirements": "{4,10}", + "shop_price": "15", + "ge_buy_limit": "10000", + "examine": "A finely balanced throwing knife.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "95", + "attack_audios": "2704,0,0,0", + "name": "Black knife", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "869", + "bonuses": "0,0,0,0,10,0,0,0,0,0,0,0,0,0,8" + }, + { + "shop_price": "14", + "ge_buy_limit": "10000", + "examine": "A finely balanced throwing knife.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "73", + "attack_audios": "2704,0,0,0", + "name": "Bronze knife(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "870", + "bonuses": "0,0,0,0,4,0,0,0,0,0,0,0,0,0,3" + }, + { + "shop_price": "58", + "ge_buy_limit": "10000", + "examine": "A finely balanced throwing knife.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "88", + "attack_audios": "2704,0,0,0", + "name": "Iron knife(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "871", + "bonuses": "0,0,0,0,5,0,0,0,0,0,0,0,0,0,4" + }, + { + "requirements": "{4,5}", + "shop_price": "68", + "ge_buy_limit": "10000", + "examine": "A finely balanced throwing knife.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "124", + "attack_audios": "2704,0,0,0", + "name": "Steel knife(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "872", + "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,7" + }, + { + "requirements": "{4,20}", + "ge_buy_limit": "100", + "examine": "A finely balanced throwing knife.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "226", + "attack_audios": "2704,0,0,0", + "name": "Mithril knife(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "873", + "bonuses": "0,0,0,0,11,0,0,0,0,0,0,0,0,0,10" + }, + { + "requirements": "{4,10}", + "shop_price": "15", + "ge_buy_limit": "10000", + "examine": "A finely balanced throwing knife.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "69", + "attack_audios": "2704,0,0,0", + "name": "Black knife(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "874", + "bonuses": "0,0,0,0,10,0,0,0,0,0,0,0,0,0,8" + }, + { + "requirements": "{4,30}", + "ge_buy_limit": "10000", + "examine": "A finely balanced throwing knife.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "503", + "attack_audios": "2704,0,0,0", + "name": "Adamant knife(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "875", + "bonuses": "0,0,0,0,15,0,0,0,0,0,0,0,0,0,14" + }, + { + "requirements": "{4,40}", + "ge_buy_limit": "10000", + "examine": "A finely balanced throwing knife.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "1374", + "attack_audios": "2704,0,0,0", + "name": "Rune knife(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "876", + "bonuses": "0,0,0,0,25,0,0,0,0,0,0,0,0,0,24" + }, + { + "shop_price": "3", + "ge_buy_limit": "10000", + "examine": "Bronze crossbow bolts.", + "grand_exchange_price": "12", + "durability": null, + "name": "Bronze bolts", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "877", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,10", + "equipment_slot": "13" + }, + { + "shop_price": "3", + "ge_buy_limit": "10000", + "examine": "Bronze crossbow bolts.", + "grand_exchange_price": "38", + "durability": null, + "name": "Bronze bolts(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "878", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,10", + "equipment_slot": "13" + }, + { + "ge_buy_limit": "25000", + "examine": "Opal tipped bronze crossbow bolts", + "grand_exchange_price": "5", + "durability": null, + "name": "Opal bolts", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "879", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,14", + "equipment_slot": "13" + }, + { + "requirements": "{4,26}", + "ge_buy_limit": "25000", + "examine": "Pearl tipped Iron crossbow bolts.", + "grand_exchange_price": "32", + "durability": null, + "name": "Pearl bolts", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "880", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,48", + "equipment_slot": "13" + }, + { + "shop_price": "80", + "ge_buy_limit": "10000", + "examine": "Great if you have a crossbow!", + "grand_exchange_price": "42", + "durability": null, + "name": "Barbed bolts", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "881", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,12", + "equipment_slot": "13" + }, + { + "shop_price": "7", + "ge_buy_limit": "10000", + "examine": "Arrows with bronze heads.", + "grand_exchange_price": "10", + "durability": null, + "name": "Bronze arrow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "882", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,7", + "equipment_slot": "13" + }, + { + "shop_price": "7", + "ge_buy_limit": "10000", + "examine": "Arrows with bronze heads.", + "grand_exchange_price": "39", + "durability": null, + "name": "Bronze arrow(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "883", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,7", + "equipment_slot": "13" + }, + { + "shop_price": "20", + "ge_buy_limit": "10000", + "examine": "Arrows with iron heads.", + "grand_exchange_price": "10", + "durability": null, + "name": "Iron arrow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "884", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,10", + "equipment_slot": "13" + }, + { + "shop_price": "20", + "ge_buy_limit": "10000", + "examine": "Arrows with iron heads.", + "grand_exchange_price": "41", + "durability": null, + "name": "Iron arrow(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "885", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,10", + "equipment_slot": "13" + }, + { + "requirements": "{4,5}", + "shop_price": "46", + "ge_buy_limit": "10000", + "examine": "Arrows with steel heads.", + "grand_exchange_price": "25", + "durability": null, + "name": "Steel arrow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "886", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,16", + "equipment_slot": "13" + }, + { + "requirements": "{4,5}", + "shop_price": "46", + "ge_buy_limit": "10000", + "examine": "Arrows with steel heads.", + "grand_exchange_price": "69", + "durability": null, + "name": "Steel arrow(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "887", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,16", + "equipment_slot": "13" + }, + { + "requirements": "{4,20}", + "shop_price": "76", + "ge_buy_limit": "10000", + "examine": "Arrows with mithril heads.", + "grand_exchange_price": "30", + "durability": null, + "name": "Mithril arrow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "888", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,22", + "equipment_slot": "13" + }, + { + "requirements": "{4,20}", + "shop_price": "76", + "ge_buy_limit": "10000", + "examine": "Arrows with mithril heads.", + "grand_exchange_price": "69", + "durability": null, + "name": "Mithril arrow(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "889", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,22", + "equipment_slot": "13" + }, + { + "requirements": "{4,30}", + "shop_price": "172", + "ge_buy_limit": "10000", + "examine": "Arrows with adamantite heads.", + "grand_exchange_price": "111", + "durability": null, + "name": "Adamant arrow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "890", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,31", + "equipment_slot": "13" + }, + { + "requirements": "{4,30}", + "shop_price": "172", + "ge_buy_limit": "10000", + "examine": "Arrows with adamantite heads.", + "grand_exchange_price": "109", + "durability": null, + "name": "Adamant arrow(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "891", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,31", + "equipment_slot": "13" + }, + { + "requirements": "{4,40}", + "shop_price": "510", + "ge_buy_limit": "10000", + "examine": "Arrows with rune heads.", + "grand_exchange_price": "212", + "durability": null, + "name": "Rune arrow", + "tradeable": "true", + "archery_ticket_price": "40", + "id": "892", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,49", + "equipment_slot": "13" + }, + { + "requirements": "{4,40}", + "shop_price": "510", + "ge_buy_limit": "10000", + "examine": "Arrows with rune heads.", + "grand_exchange_price": "257", + "durability": null, + "name": "Rune arrow(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "893", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,49", + "equipment_slot": "13" + }, + { + "ge_buy_limit": "10000", + "examine": "unlit: Arrows with bronze heads and oil-soaked cloth. lit: An easy to make, bronze-headed fire arrow.", + "grand_exchange_price": "228", + "durability": null, + "name": "Bronze fire arrows", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "942", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,7", + "equipment_slot": "13" + }, + { + "shop_price": "0", + "examine": "Ugh! It's wriggling!", + "durability": null, + "name": "Worm", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "id": "943" + }, + { + "durability": null, + "name": "Worm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "944" + }, + { + "durability": null, + "name": "Throwing rope", + "archery_ticket_price": "0", + "id": "945", + "equipment_slot": "3" + }, + { + "shop_price": "25", + "ge_buy_limit": "100", + "examine": "A dangerous looking knife.", + "grand_exchange_price": "32", + "durability": null, + "name": "Knife", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "946" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "32", + "durability": null, + "name": "Knife", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "947" + }, + { + "shop_price": "4", + "ge_buy_limit": "100", + "examine": "This would make warm clothing.", + "grand_exchange_price": "9", + "durability": null, + "name": "Bear fur", + "tradeable": "true", + "weight": "3", + "archery_ticket_price": "0", + "id": "948" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "9", + "durability": null, + "name": "Bear fur", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "949" + }, + { + "shop_price": "21", + "ge_buy_limit": "100", + "examine": "It's a sheet of silk.", + "grand_exchange_price": "27", + "durability": null, + "name": "Silk", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "950" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "27", + "durability": null, + "name": "Silk", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "951" + }, + { + "shop_price": "5", + "ge_buy_limit": "100", + "examine": "A slightly muddy spade. / Popular with farmers and treasure hunters.", + "grand_exchange_price": "117", + "durability": null, + "name": "Spade", + "tradeable": "true", + "weight": "1.8", + "archery_ticket_price": "0", + "id": "952" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "117", + "durability": null, + "name": "Spade", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "953" + }, + { + "shop_price": "18", + "ge_buy_limit": "100", + "examine": "A coil of rope.", + "grand_exchange_price": "96", + "durability": null, + "name": "Rope", + "tradeable": "true", + "weight": "1.3", + "archery_ticket_price": "0", + "id": "954" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "96", + "durability": null, + "name": "Rope", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "955" + }, + { + "examine": "Get your axes from Bob's Axes.", + "durability": null, + "name": "Flier", + "archery_ticket_price": "0", + "id": "956" + }, + { + "shop_price": "70", + "ge_buy_limit": "100", + "examine": "This would make warm clothing.", + "grand_exchange_price": "34", + "durability": null, + "name": "Grey wolf fur", + "tradeable": "true", + "weight": "3", + "archery_ticket_price": "0", + "id": "958" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "34", + "durability": null, + "name": "Grey wolf fur", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "959" + }, + { + "shop_price": "100", + "ge_buy_limit": "10000", + "examine": "A plank of wood!", + "grand_exchange_price": "234", + "durability": null, + "name": "Plank", + "tradeable": "true", + "weight": "0.8", + "archery_ticket_price": "0", + "id": "960" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "234", + "durability": null, + "name": "Plank", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "961" + }, + { + "ge_buy_limit": "2", + "examine": "I need to pull this.", + "grand_exchange_price": "15", + "durability": null, + "name": "Christmas cracker", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "962" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "1900000000", + "durability": null, + "name": "Christmas cracker", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "963" + }, + { + "examine": "A fraction of a roof.", + "durability": null, + "name": "Tile", + "weight": "0.6", + "archery_ticket_price": "0", + "id": "966" + }, + { + "shop_price": "15", + "ge_buy_limit": "100", + "examine": "Used for making notes.", + "grand_exchange_price": "153", + "durability": null, + "name": "Papyrus", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "970" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "153", + "durability": null, + "name": "Papyrus", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "971" + }, + { + "shop_price": "15", + "examine": "Used for making notes.", + "grand_exchange_price": "163", + "durability": null, + "name": "Papyrus", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "972" + }, + { + "shop_price": "45", + "ge_buy_limit": "100", + "examine": "A lump of charcoal.", + "grand_exchange_price": "272", + "durability": null, + "name": "Charcoal", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "973" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "272", + "durability": null, + "name": "Charcoal", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "974" + }, + { + "shop_price": "52", + "ge_buy_limit": "100", + "examine": "A jungle specific slashing device.", + "durability": null, + "weight": "1.3", + "attack_speed": "5", + "weapon_interface": "6", + "render_anim": "2554", + "equipment_slot": "3", + "grand_exchange_price": "619", + "name": "Machete", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "975", + "bonuses": "0,6,-2,0,0,0,0,0,0,0,0,5,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "619", + "durability": null, + "name": "Machete", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "976" + }, + { + "durability": null, + "name": "Cooking pot", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "978" + }, + { + "shop_price": "10", + "ge_buy_limit": "2", + "examine": "Used to get out of Thordur's blackhole.", + "grand_exchange_price": "298000000", + "durability": null, + "name": "Disk of returning", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "981" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "298000000", + "durability": null, + "name": "Disk of returning", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "982" + }, + { + "shop_price": "1", + "ge_buy_limit": "100", + "examine": "A key found on the floor of Edgeville Dungeon.", + "grand_exchange_price": "547", + "durability": null, + "name": "Brass key", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "983" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "547", + "durability": null, + "name": "Brass key", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "984" + }, + { + "ge_buy_limit": "100", + "examine": "The tooth end of the mysterious Crystal key. Can you find the other half?", + "grand_exchange_price": "24900", + "durability": null, + "name": "Tooth half of a key", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "985" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "24900", + "durability": null, + "name": "Tooth half of a key", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "986" + }, + { + "ge_buy_limit": "100", + "examine": "The loop end of the mysterious Crystal key. Can you find the other half?", + "grand_exchange_price": "21100", + "durability": null, + "name": "Loop half of a key", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "987" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "21100", + "durability": null, + "name": "Loop half of a key", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "988" + }, + { + "ge_buy_limit": "100", + "examine": "A mysterious key for a mysterious chest.", + "grand_exchange_price": "48700", + "durability": null, + "name": "Crystal key", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "989" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "48700", + "durability": null, + "name": "Crystal key", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "990" + }, + { + "ge_buy_limit": "100", + "examine": "It looks like the key to a chest", + "grand_exchange_price": "4971", + "durability": null, + "name": "Muddy key", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "991" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "4971", + "durability": null, + "name": "Muddy key", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "992" + }, + { + "ge_buy_limit": "100", + "examine": "You get a sense of dread from this key.", + "grand_exchange_price": "54600", + "durability": null, + "name": "Sinister key", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "993" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "54600", + "durability": null, + "name": "Sinister key", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "994" + }, + { + "examine": "Lovely money!", + "durability": null, + "name": "Coins", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "995" + }, + { + "shop_price": "2", + "ge_buy_limit": "100", + "examine": "A mostly clean apron.", + "grand_exchange_price": "93", + "durability": null, + "name": "White apron", + "tradeable": "true", + "weight": "0.45", + "archery_ticket_price": "0", + "id": "1005", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "93", + "durability": null, + "name": "White apron", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1006" + }, + { + "shop_price": "20", + "ge_buy_limit": "100", + "examine": "A bright red cape.", + "grand_exchange_price": "187", + "durability": null, + "name": "Cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "1007", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "187", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1008" + }, + { + "ge_buy_limit": "100", + "examine": "I'd prefer a gold one.", + "grand_exchange_price": "65", + "durability": null, + "name": "Brass necklace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1009", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "65", + "durability": null, + "name": "Brass necklace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1010" + }, + { + "shop_price": "2", + "ge_buy_limit": "100", + "examine": "Leg covering favored by women and wizards.", + "grand_exchange_price": "208", + "durability": null, + "name": "Blue skirt", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "1011", + "bonuses": "0,0,0,1,0,0,0,0,1,0,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "208", + "durability": null, + "name": "Blue skirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1012" + }, + { + "shop_price": "3", + "ge_buy_limit": "100", + "examine": "A ladies skirt.", + "grand_exchange_price": "216", + "durability": null, + "name": "Pink skirt", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "1013", + "bonuses": "0,0,0,1,0,0,0,0,1,0,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "216", + "durability": null, + "name": "Pink skirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1014" + }, + { + "shop_price": "2", + "ge_buy_limit": "100", + "examine": "Clothing favoured by women and dark wizards.", + "grand_exchange_price": "30", + "durability": null, + "name": "Black skirt", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "1015", + "bonuses": "0,0,0,1,0,0,0,0,1,0,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "30", + "durability": null, + "name": "Black skirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1016" + }, + { + "shop_price": "2", + "ge_buy_limit": "100", + "examine": "A silly pointed hat.", + "grand_exchange_price": "280", + "durability": null, + "name": "Wizard hat", + "tradeable": "true", + "archery_ticket_price": "0", + "hat": "true", + "id": "1017", + "bonuses": "0,0,0,2,0,0,0,0,2,0,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "280", + "durability": null, + "name": "Wizard hat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1018" + }, + { + "shop_price": "20", + "ge_buy_limit": "100", + "examine": "A warm black cape.", + "grand_exchange_price": "209", + "durability": null, + "name": "Cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "1019", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "209", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1020" + }, + { + "shop_price": "20", + "ge_buy_limit": "100", + "examine": "A thick blue cape.", + "grand_exchange_price": "504", + "durability": null, + "name": "Cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "1021", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "504", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1022" + }, + { + "shop_price": "20", + "ge_buy_limit": "100", + "examine": "A thick yellow cape.", + "grand_exchange_price": "439", + "durability": null, + "name": "Cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "1023", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "439", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1024" + }, + { + "shop_price": "2", + "ge_buy_limit": "100", + "examine": "A black piece of cloth on a string.", + "grand_exchange_price": "111", + "durability": null, + "name": "Eyepatch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1025", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "111", + "durability": null, + "name": "Eyepatch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1026" + }, + { + "shop_price": "20", + "ge_buy_limit": "100", + "examine": "A thick green cape.", + "grand_exchange_price": "1061", + "durability": null, + "name": "Cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "1027", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1061", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1028" + }, + { + "shop_price": "20", + "ge_buy_limit": "100", + "examine": "A thick purple cape.", + "grand_exchange_price": "955", + "durability": null, + "name": "Cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "1029", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "955", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1030" + }, + { + "shop_price": "20", + "ge_buy_limit": "100", + "examine": "A thick orange cape.", + "durability": null, + "destroy": "true", + "weight": "0.4", + "equipment_slot": "1", + "grand_exchange_price": "1656", + "name": "Cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1031", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1656", + "durability": null, + "name": "Cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1032" + }, + { + "shop_price": "30", + "ge_buy_limit": "2", + "examine": "A robe worn by worshippers of Zamorak.", + "grand_exchange_price": "2481", + "durability": null, + "name": "Zamorak robe", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "1033", + "bonuses": "0,0,0,2,0,0,0,0,3,0,0,0,3,0,0", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "2481", + "durability": null, + "name": "Zamorak robe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1034" + }, + { + "shop_price": "40", + "ge_buy_limit": "2", + "examine": "A robe worn by worshippers of Zamorak.", + "durability": null, + "weight": "0.9", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "1259", + "name": "Zamorak robe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1035", + "bonuses": "0,0,0,2,0,0,0,0,3,0,3,0,3,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "1259", + "durability": null, + "name": "Zamorak robe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1036" + }, + { + "destroy_message": "You can get a replacement from Diango.", + "shop_price": "1", + "examine": "A rabbit-like adornment.", + "durability": null, + "name": "Bunny ears", + "tradeable": "false", + "destroy": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "1037", + "equipment_slot": "0" + }, + { + "lendable": "true", + "shop_price": "1", + "ge_buy_limit": "2", + "examine": "A nice hat from a cracker.", + "grand_exchange_price": "10", + "durability": null, + "name": "Red partyhat", + "tradeable": "true", + "weight": "0.05", + "archery_ticket_price": "0", + "id": "1038", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "1500000000", + "durability": null, + "name": "Red partyhat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1039" + }, + { + "lendable": "true", + "shop_price": "1", + "ge_buy_limit": "2", + "examine": "A nice hat from a cracker.", + "grand_exchange_price": "10", + "durability": null, + "name": "Yellow partyhat", + "tradeable": "true", + "weight": "0.05", + "archery_ticket_price": "0", + "id": "1040", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "1200000000", + "durability": null, + "name": "Yellow partyhat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1041" + }, + { + "lendable": "true", + "shop_price": "1", + "ge_buy_limit": "2", + "examine": "A nice hat from a cracker.", + "grand_exchange_price": "10", + "durability": null, + "name": "Blue partyhat", + "tradeable": "true", + "weight": "0.05", + "archery_ticket_price": "0", + "id": "1042", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "2100000000", + "durability": null, + "name": "Blue partyhat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1043" + }, + { + "lendable": "true", + "shop_price": "1", + "ge_buy_limit": "2", + "examine": "A nice hat from a cracker.", + "grand_exchange_price": "10", + "durability": null, + "name": "Green partyhat", + "tradeable": "true", + "weight": "0.05", + "archery_ticket_price": "0", + "id": "1044", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "1300000000", + "durability": null, + "name": "Green partyhat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1045" + }, + { + "lendable": "true", + "shop_price": "1", + "ge_buy_limit": "2", + "examine": "A nice hat from a cracker.", + "grand_exchange_price": "10", + "durability": null, + "name": "Purple partyhat", + "tradeable": "true", + "weight": "0.05", + "archery_ticket_price": "0", + "id": "1046", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "1000000000", + "durability": null, + "name": "Purple partyhat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1047" + }, + { + "lendable": "true", + "shop_price": "1", + "ge_buy_limit": "2", + "examine": "A nice hat from a cracker.", + "grand_exchange_price": "10", + "durability": null, + "name": "White partyhat", + "tradeable": "true", + "weight": "0.05", + "archery_ticket_price": "0", + "id": "1048", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "2000000000", + "durability": null, + "name": "White partyhat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1049" + }, + { + "shop_price": "1", + "ge_buy_limit": "2", + "examine": "It's a Santa hat.", + "durability": null, + "weight": "0.1", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "5", + "name": "Santa hat", + "tradeable": "true", + "archery_ticket_price": "0", + "hat": "true", + "id": "1050" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "112600000", + "durability": null, + "name": "Santa hat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1051" + }, + { + "shop_price": "450", + "examine": "The cape worn by members of the Legends Guild.", + "durability": null, + "name": "Cape of legends", + "weight": "1.8", + "archery_ticket_price": "0", + "id": "1052", + "bonuses": "0,0,0,0,0,7,7,7,7,7,7,0,0,0,0", + "equipment_slot": "1" + }, + { + "remove_head": "true", + "shop_price": "15", + "ge_buy_limit": "2", + "examine": "Aaaarrrghhh ... I'm a monster.", + "durability": null, + "remove_beard": "true", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "98000000", + "name": "Green h'ween mask", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1053" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "98000000", + "durability": null, + "name": "Green h'ween mask", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1054" + }, + { + "remove_head": "true", + "shop_price": "15", + "ge_buy_limit": "2", + "examine": "Aaaarrrghhh ... I'm a monster.", + "durability": null, + "remove_beard": "true", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "115900000", + "name": "Blue h'ween mask", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1055" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "115900000", + "durability": null, + "name": "Blue h'ween mask", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1056" + }, + { + "remove_head": "true", + "shop_price": "15", + "ge_buy_limit": "2", + "examine": "Aaaarrrghhh ... I'm a monster.", + "durability": null, + "remove_beard": "true", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "154300000", + "name": "Red h'ween mask", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1057" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "154300000", + "durability": null, + "name": "Red h'ween mask", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1058" + }, + { + "shop_price": "6", + "ge_buy_limit": "5000", + "examine": "These will keep my hands warm!", + "grand_exchange_price": "12", + "durability": null, + "name": "Leather gloves", + "tradeable": "true", + "weight": "0.23", + "archery_ticket_price": "0", + "id": "1059", + "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0", + "equipment_slot": "9" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "12", + "durability": null, + "name": "Leather gloves", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1060" + }, + { + "shop_price": "6", + "ge_buy_limit": "5000", + "examine": "Comfortable leather boots.", + "grand_exchange_price": "144", + "durability": null, + "name": "Leather boots", + "tradeable": "true", + "weight": "0.34", + "archery_ticket_price": "0", + "id": "1061", + "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", + "equipment_slot": "10" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "144", + "durability": null, + "name": "Leather boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1062" + }, + { + "shop_price": "18", + "ge_buy_limit": "5000", + "examine": "Better than no armour!", + "grand_exchange_price": "13", + "durability": null, + "name": "Leather vambraces", + "tradeable": "true", + "weight": "0.22", + "archery_ticket_price": "0", + "id": "1063", + "bonuses": "0,0,0,0,4,2,2,1,0,0,0,0,0,0,0", + "equipment_slot": "9" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "13", + "durability": null, + "name": "Leather vambraces", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1064" + }, + { + "requirements": "{4,40}", + "shop_price": "2500", + "ge_buy_limit": "5000", + "examine": "Made from 100% real dragonhide.", + "durability": null, + "weight": "0.28", + "equip_audio": "2241", + "equipment_slot": "9", + "lendable": "true", + "grand_exchange_price": "1407", + "name": "Green d'hide vambraces", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1065", + "bonuses": "0,0,0,-10,8,3,2,4,2,0,0,0,0,0,0" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "1407", + "durability": null, + "name": "Green d'hide vambraces", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1066" + }, + { + "shop_price": "280", + "ge_buy_limit": "100", + "examine": "These look pretty heavy.", + "durability": null, + "weight": "9", + "absorb": "1,0,1", + "equip_audio": "2242", + "equipment_slot": "7", + "grand_exchange_price": "55", + "name": "Iron platelegs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1067", + "bonuses": "0,0,0,-21,-7,11,10,10,-4,10,0,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "55", + "durability": null, + "name": "Iron platelegs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1068" + }, + { + "requirements": "{1,5}", + "shop_price": "1000", + "ge_buy_limit": "100", + "examine": "These look pretty heavy.", + "durability": null, + "weight": "9", + "absorb": "1,0,1", + "equip_audio": "2242", + "equipment_slot": "7", + "grand_exchange_price": "426", + "name": "Steel platelegs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1069", + "bonuses": "0,0,0,-21,-7,17,16,15,-4,16,2,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "426", + "durability": null, + "name": "Steel platelegs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1070" + }, + { + "requirements": "{1,20}", + "shop_price": "2600", + "ge_buy_limit": "100", + "examine": "These look pretty heavy.", + "durability": null, + "weight": "7.7", + "absorb": "1,0,2", + "equip_audio": "2242", + "equipment_slot": "7", + "grand_exchange_price": "1391", + "name": "Mithril platelegs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1071", + "bonuses": "0,0,0,-21,-7,24,22,20,-4,22,5,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1391", + "durability": null, + "name": "Mithril platelegs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1072" + }, + { + "requirements": "{1,30}", + "shop_price": "6464", + "ge_buy_limit": "100", + "examine": "These look pretty heavy.", + "durability": null, + "weight": "10", + "absorb": "1,0,3", + "equip_audio": "2242", + "equipment_slot": "7", + "grand_exchange_price": "3649", + "name": "Adamant platelegs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1073", + "bonuses": "0,0,0,-21,-7,33,31,29,-4,31,10,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3649", + "durability": null, + "name": "Adamant platelegs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1074" + }, + { + "shop_price": "80", + "ge_buy_limit": "100", + "examine": "These look pretty heavy.", + "durability": null, + "weight": "9", + "equip_audio": "2242", + "equipment_slot": "7", + "grand_exchange_price": "34", + "name": "Bronze platelegs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1075", + "bonuses": "0,0,0,-21,-7,8,7,6,-4,7,0,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "34", + "durability": null, + "name": "Bronze platelegs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1076" + }, + { + "requirements": "{1,10}", + "shop_price": "1920", + "ge_buy_limit": "100", + "examine": "These look pretty heavy", + "durability": null, + "weight": "9", + "absorb": "1,0,2", + "equip_audio": "2242", + "equipment_slot": "7", + "grand_exchange_price": "4995", + "name": "Black platelegs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1077", + "bonuses": "0,0,0,-21,-7,21,20,19,-4,20,3,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "4995", + "durability": null, + "name": "Black platelegs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1078" + }, + { + "requirements": "{1,40}", + "shop_price": "64000", + "ge_buy_limit": "100", + "examine": "These look pretty heavy.", + "durability": null, + "weight": "9", + "absorb": "2,0,4", + "equip_audio": "2242", + "equipment_slot": "7", + "lendable": "true", + "grand_exchange_price": "38500", + "name": "Rune platelegs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1079", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "38500", + "durability": null, + "name": "Rune platelegs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1080" + }, + { + "shop_price": "280", + "ge_buy_limit": "100", + "examine": "Designer leg protection.", + "grand_exchange_price": "86", + "durability": null, + "name": "Iron plateskirt", + "tradeable": "true", + "weight": "8.1", + "archery_ticket_price": "0", + "id": "1081", + "bonuses": "0,0,0,-21,-7,11,10,10,-4,10,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "86", + "durability": null, + "name": "Iron plateskirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1082" + }, + { + "requirements": "{1,5}", + "shop_price": "1000", + "ge_buy_limit": "100", + "examine": "Designer leg protection.", + "durability": null, + "weight": "8.1", + "equipment_slot": "7", + "grand_exchange_price": "514", + "name": "Steel plateskirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1083", + "bonuses": "0,0,0,-21,-7,17,16,15,-4,16,2,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "514", + "durability": null, + "name": "Steel plateskirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1084" + }, + { + "requirements": "{1,20}", + "shop_price": "2600", + "ge_buy_limit": "100", + "examine": "Designer leg protection.", + "durability": null, + "weight": "7.2", + "absorb": "1,0,2", + "equipment_slot": "7", + "grand_exchange_price": "1339", + "name": "Mithril plateskirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1085", + "bonuses": "0,0,0,-21,-7,24,22,20,-4,22,5,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1339", + "durability": null, + "name": "Mithril plateskirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1086" + }, + { + "shop_price": "80", + "ge_buy_limit": "100", + "examine": "Designer leg protection.", + "grand_exchange_price": "113", + "durability": null, + "name": "Bronze plateskirt", + "tradeable": "true", + "weight": "8.1", + "archery_ticket_price": "0", + "id": "1087", + "bonuses": "0,0,0,-21,-7,8,7,6,-4,7,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "113", + "durability": null, + "name": "Bronze plateskirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1088" + }, + { + "requirements": "{1,10}", + "shop_price": "1920", + "ge_buy_limit": "100", + "examine": "Designer leg protection.", + "durability": null, + "weight": "8", + "absorb": "1,0,2", + "equipment_slot": "7", + "grand_exchange_price": "2180", + "name": "Black plateskirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1089", + "bonuses": "0,0,0,-21,-7,21,20,19,-4,20,3,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2180", + "durability": null, + "name": "Black plateskirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1090" + }, + { + "requirements": "{1,30}", + "shop_price": "6464", + "ge_buy_limit": "100", + "examine": "Designer leg protection.", + "durability": null, + "weight": "9", + "absorb": "1,0,3", + "equipment_slot": "7", + "grand_exchange_price": "3610", + "name": "Adamant plateskirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1091", + "bonuses": "0,0,0,-21,-7,33,31,29,-4,31,10,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3610", + "durability": null, + "name": "Adamant plateskirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1092" + }, + { + "requirements": "{1,40}", + "shop_price": "64000", + "ge_buy_limit": "100", + "examine": "Designer leg protection.", + "durability": null, + "weight": "8", + "absorb": "2,0,4", + "equipment_slot": "7", + "lendable": "true", + "grand_exchange_price": "38100", + "name": "Rune plateskirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1093", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "38100", + "durability": null, + "name": "Rune plateskirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1094" + }, + { + "shop_price": "23", + "ge_buy_limit": "5000", + "examine": "Better than no armour!", + "grand_exchange_price": "5", + "durability": null, + "name": "Leather chaps", + "tradeable": "true", + "weight": "3", + "archery_ticket_price": "0", + "id": "1095", + "bonuses": "0,0,0,0,4,2,2,1,0,0,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "5", + "durability": null, + "name": "Leather chaps", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1096" + }, + { + "requirements": "{4,20}", + "shop_price": "750", + "ge_buy_limit": "1000", + "examine": "Those studs should provide a bit more protection.", + "durability": null, + "weight": "4.5", + "absorb": "0,2,1", + "equipment_slot": "7", + "grand_exchange_price": "377", + "name": "Studded chaps", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1097", + "bonuses": "0,0,0,-5,6,15,16,17,6,16,5,0,0,0,0" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "377", + "durability": null, + "name": "Studded chaps", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1098" + }, + { + "requirements": "{4,40}", + "shop_price": "3900", + "ge_buy_limit": "5000", + "examine": "100% real dragonhide.", + "durability": null, + "weight": "5.4", + "absorb": "0,4,2", + "equip_audio": "2241", + "equipment_slot": "7", + "lendable": "true", + "grand_exchange_price": "2228", + "name": "Green d'hide chaps", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1099", + "bonuses": "0,0,0,-10,8,22,16,24,8,22,15,0,0,0,0" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "2228", + "durability": null, + "name": "Green d'hide chaps", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1100" + }, + { + "shop_price": "210", + "ge_buy_limit": "100", + "examine": "A series of connected metal rings.", + "grand_exchange_price": "76", + "durability": null, + "name": "Iron chainbody", + "tradeable": "true", + "weight": "6.8", + "archery_ticket_price": "0", + "id": "1101", + "bonuses": "0,0,0,-15,0,10,15,19,-3,12,5,0,0,0,0", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "76", + "durability": null, + "name": "Iron chainbody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1102" + }, + { + "shop_price": "60", + "ge_buy_limit": "100", + "examine": "A series of connected metal rings.", + "grand_exchange_price": "37", + "durability": null, + "name": "Bronze chainbody", + "tradeable": "true", + "weight": "6.8", + "archery_ticket_price": "0", + "id": "1103", + "bonuses": "0,0,0,-15,0,7,11,13,-3,9,5,0,0,0,0", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "37", + "durability": null, + "name": "Bronze chainbody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1104" + }, + { + "requirements": "{1,5}", + "shop_price": "750", + "ge_buy_limit": "100", + "examine": "A series of connected metal rings.", + "durability": null, + "weight": "6", + "equipment_slot": "4", + "grand_exchange_price": "265", + "name": "Steel chainbody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1105", + "bonuses": "0,0,0,-15,0,17,25,30,-3,19,5,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "265", + "durability": null, + "name": "Steel chainbody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1106" + }, + { + "requirements": "{1,10}", + "shop_price": "1440", + "ge_buy_limit": "100", + "examine": "A series of connected metal rings.", + "durability": null, + "weight": "6.8", + "absorb": "1,0,2", + "equipment_slot": "4", + "grand_exchange_price": "961", + "name": "Black chainbody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1107", + "bonuses": "0,0,0,-15,0,22,32,39,-3,24,10,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "961", + "durability": null, + "name": "Black chainbody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1108" + }, + { + "requirements": "{1,20}", + "shop_price": "1950", + "ge_buy_limit": "100", + "examine": "A series of connected metal rings.", + "durability": null, + "weight": "5.8", + "absorb": "1,0,3", + "equipment_slot": "4", + "grand_exchange_price": "963", + "name": "Mithril chainbody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1109", + "bonuses": "0,0,0,-15,0,25,35,42,-3,27,20,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "963", + "durability": null, + "name": "Mithril chainbody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1110" + }, + { + "requirements": "{1,30}", + "shop_price": "4800", + "ge_buy_limit": "100", + "examine": "A series of connected metal rings.", + "durability": null, + "weight": "7.7", + "absorb": "2,0,4", + "equipment_slot": "4", + "grand_exchange_price": "2731", + "name": "Adamant chainbody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1111", + "bonuses": "0,0,0,-15,0,36,50,61,-3,38,30,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2731", + "durability": null, + "name": "Adamant chainbody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1112" + }, + { + "requirements": "{1,40}", + "shop_price": "50000", + "ge_buy_limit": "100", + "examine": "A series of connected metal rings.", + "durability": null, + "weight": "6.8", + "absorb": "3,0,6", + "equipment_slot": "4", + "lendable": "true", + "grand_exchange_price": "29800", + "name": "Rune chainbody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1113", + "bonuses": "0,0,0,-15,0,63,72,78,-3,65,40,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "29800", + "durability": null, + "name": "Rune chainbody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1114" + }, + { + "shop_price": "560", + "ge_buy_limit": "500", + "examine": "Provides excellent protection.", + "durability": null, + "weight": "9.95", + "equip_audio": "2239", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "434", + "name": "Iron platebody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1115", + "bonuses": "0,0,0,-30,-10,21,20,12,-6,20,5,0,0,0,0" + }, + { + "ge_buy_limit": "500", + "grand_exchange_price": "434", + "durability": null, + "name": "Iron platebody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1116" + }, + { + "shop_price": "160", + "ge_buy_limit": "500", + "examine": "Provides excellent protection.", + "durability": null, + "weight": "9.5", + "equip_audio": "2239", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "36", + "name": "Bronze platebody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1117", + "bonuses": "0,0,0,-30,-10,15,14,9,-6,14,5,0,0,0,0" + }, + { + "ge_buy_limit": "500", + "grand_exchange_price": "36", + "durability": null, + "name": "Bronze platebody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1118" + }, + { + "requirements": "{1,5}", + "shop_price": "2000", + "ge_buy_limit": "500", + "examine": "Provides excellent protection.", + "durability": null, + "weight": "9.9", + "equip_audio": "2239", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "1077", + "name": "Steel platebody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1119", + "bonuses": "0,0,0,-30,-10,32,31,24,-6,31,5,0,0,0,0" + }, + { + "ge_buy_limit": "500", + "grand_exchange_price": "1077", + "durability": null, + "name": "Steel platebody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1120" + }, + { + "requirements": "{1,20}", + "shop_price": "5200", + "ge_buy_limit": "500", + "examine": "Provides excellent protection.", + "durability": null, + "weight": "8.6", + "absorb": "1,0,3", + "equip_audio": "2239", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "2965", + "name": "Mithril platebody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1121", + "bonuses": "0,0,0,-30,-10,46,44,38,-6,44,20,0,0,0,0" + }, + { + "ge_buy_limit": "500", + "grand_exchange_price": "2965", + "durability": null, + "name": "Mithril platebody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1122" + }, + { + "requirements": "{1,30}", + "shop_price": "16256", + "ge_buy_limit": "500", + "examine": "Provides excellent protection.", + "durability": null, + "weight": "11", + "absorb": "2,0,4", + "equip_audio": "2239", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "9790", + "name": "Adamant platebody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1123", + "bonuses": "0,0,0,-30,-10,65,63,55,-6,63,30,0,0,0,0" + }, + { + "ge_buy_limit": "500", + "grand_exchange_price": "9790", + "durability": null, + "name": "Adamant platebody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1124" + }, + { + "requirements": "{1,10}", + "shop_price": "3840", + "ge_buy_limit": "500", + "examine": "Provides Excellent protection.", + "durability": null, + "weight": "9.9", + "absorb": "1,0,2", + "equip_audio": "2239", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "4915", + "name": "Black platebody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1125", + "bonuses": "0,0,0,-30,-10,41,40,30,-6,40,10,0,0,0,0" + }, + { + "ge_buy_limit": "500", + "grand_exchange_price": "4915", + "durability": null, + "name": "Black platebody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1126" + }, + { + "requirements": "{1,40}", + "shop_price": "65000", + "ge_buy_limit": "100", + "examine": "Provides excellent protection.", + "durability": null, + "weight": "9.9", + "absorb": "3,0,6", + "equip_audio": "2239", + "equipment_slot": "4", + "lendable": "true", + "remove_sleeves": "true", + "grand_exchange_price": "38800", + "name": "Rune platebody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1127", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "38800", + "durability": null, + "name": "Rune platebody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1128" + }, + { + "shop_price": "20", + "ge_buy_limit": "1000", + "examine": "Better than no armour!", + "grand_exchange_price": "34", + "durability": null, + "name": "Leather body", + "tradeable": "true", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "1129", + "bonuses": "0,0,0,-2,2,8,9,10,4,9,5,0,0,0,0", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "34", + "durability": null, + "name": "Leather body", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1130" + }, + { + "requirements": "{1,10}", + "shop_price": "170", + "ge_buy_limit": "1000", + "examine": "Harder than normal leather.", + "durability": null, + "weight": "3.6", + "absorb": "0,2,1", + "equipment_slot": "4", + "grand_exchange_price": "43", + "name": "Hardleather body", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1131", + "bonuses": "0,0,0,-4,8,12,15,18,6,15,10,0,0,0,0" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "43", + "durability": null, + "name": "Hardleather body", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1132" + }, + { + "requirements": "{1,20}-{4,20}", + "shop_price": "850", + "ge_buy_limit": "1000", + "examine": "These studs should provide a bit more protection.", + "durability": null, + "weight": "5", + "absorb": "0,3,1", + "equipment_slot": "4", + "grand_exchange_price": "414", + "name": "Studded body", + "tradeable": "true", + "archery_ticket_price": "150", + "id": "1133", + "bonuses": "0,0,0,-4,8,18,25,22,8,25,20,0,0,0,0" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "414", + "durability": null, + "name": "Studded body", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1134" + }, + { + "requirements": "{1,40}-{4,40}", + "shop_price": "7800", + "ge_buy_limit": "5000", + "examine": "Made from 100% real dragonhide.", + "durability": null, + "weight": "6.8", + "absorb": "0,6,3", + "equip_audio": "2241", + "equipment_slot": "4", + "lendable": "true", + "grand_exchange_price": "4544", + "name": "Green d'hide body", + "tradeable": "true", + "archery_ticket_price": "2400", + "id": "1135", + "bonuses": "0,0,0,-15,15,40,32,45,20,40,40,0,0,0,0" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "4544", + "durability": null, + "name": "Green d'hide body", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1136" + }, + { + "remove_head": "true", + "shop_price": "84", + "ge_buy_limit": "100", + "examine": "A medium sized helmet.", + "durability": null, + "weight": "1.8", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "22", + "name": "Iron med helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1137", + "bonuses": "0,0,0,-3,-1,4,5,3,-1,4,0,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "22", + "durability": null, + "name": "Iron med helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1138" + }, + { + "remove_head": "true", + "shop_price": "24", + "ge_buy_limit": "100", + "examine": "A medium sized helmet.", + "durability": null, + "weight": "1.8", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "39", + "name": "Bronze med helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1139", + "bonuses": "0,0,0,-3,-1,3,4,2,-1,3,0,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "39", + "durability": null, + "name": "Bronze med helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1140" + }, + { + "remove_head": "true", + "requirements": "{1,5}", + "shop_price": "300", + "ge_buy_limit": "100", + "examine": "A medium sized helmet.", + "durability": null, + "weight": "1.8", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "52", + "name": "Steel med helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1141", + "bonuses": "0,0,0,-3,-1,7,8,6,-1,7,3,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "52", + "durability": null, + "name": "Steel med helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1142" + }, + { + "remove_head": "true", + "requirements": "{1,20}", + "shop_price": "780", + "ge_buy_limit": "100", + "examine": "A medium sized helmet.", + "durability": null, + "weight": "1.3", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "272", + "name": "Mithril med helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1143", + "bonuses": "0,0,0,-3,-1,10,11,9,-1,10,5,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "272", + "durability": null, + "name": "Mithril med helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1144" + }, + { + "remove_head": "true", + "requirements": "{1,30}", + "shop_price": "1920", + "ge_buy_limit": "100", + "examine": "A medium sized helmet.", + "durability": null, + "weight": "1.8", + "absorb": "1,0,2", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "1024", + "name": "Adamant med helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1145", + "bonuses": "0,0,0,-3,-1,14,15,13,-1,14,6,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1024", + "durability": null, + "name": "Adamant med helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1146" + }, + { + "remove_head": "true", + "requirements": "{1,40}", + "shop_price": "19200", + "ge_buy_limit": "100", + "examine": "A medium sized helmet.", + "durability": null, + "weight": "1.8", + "absorb": "1,0,3", + "equip_audio": "2240", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "11400", + "name": "Rune med helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1147", + "bonuses": "0,0,0,-3,-1,22,23,21,-1,22,7,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "11400", + "durability": null, + "name": "Rune med helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1148" + }, + { + "remove_head": "true", + "requirements": "{1,60}", + "ge_buy_limit": "100", + "examine": "Makes the wearer pretty intimidating.", + "durability": null, + "weight": "1.3", + "absorb": "2,0,4", + "equip_audio": "2240", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "60500", + "name": "Dragon med helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1149", + "bonuses": "0,0,0,-3,-1,33,35,32,-1,34,10,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "60500", + "durability": null, + "name": "Dragon med helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1150" + }, + { + "remove_head": "true", + "requirements": "{1,10}", + "shop_price": "530", + "ge_buy_limit": "100", + "examine": "A medium sized helmet.", + "durability": null, + "weight": "1.8", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "242", + "name": "Black med helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1151", + "bonuses": "0,0,0,-3,-1,9,10,8,-1,9,4,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "242", + "durability": null, + "name": "Black med helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1152" + }, + { + "remove_head": "true", + "shop_price": "61", + "ge_buy_limit": "100", + "examine": "A full face helmet.", + "durability": null, + "weight": "2.7", + "equip_audio": "2240", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "56", + "name": "Iron full helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1153", + "bonuses": "0,0,0,-6,-2,6,7,5,-1,6,0,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "56", + "durability": null, + "name": "Iron full helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1154" + }, + { + "remove_head": "true", + "shop_price": "44", + "ge_buy_limit": "100", + "examine": "A full face helmet.", + "durability": null, + "weight": "2.7", + "equip_audio": "2240", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "67", + "name": "Bronze full helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1155", + "bonuses": "0,0,0,-6,-2,4,5,3,-1,4,0,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "67", + "durability": null, + "name": "Bronze full helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1156" + }, + { + "remove_head": "true", + "requirements": "{1,5}", + "shop_price": "550", + "ge_buy_limit": "100", + "examine": "A full face helmet.", + "durability": null, + "weight": "2.7", + "equip_audio": "2240", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "195", + "name": "Steel full helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1157", + "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "195", + "durability": null, + "name": "Steel full helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1158" + }, + { + "remove_head": "true", + "requirements": "{1,20}", + "shop_price": "1430", + "ge_buy_limit": "100", + "examine": "A full face helmet.", + "durability": null, + "weight": "2.2", + "equip_audio": "2240", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "675", + "name": "Mithril full helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1159", + "bonuses": "0,0,0,-6,-2,13,14,11,-1,13,5,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "675", + "durability": null, + "name": "Mithril full helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1160" + }, + { + "remove_head": "true", + "requirements": "{1,30}", + "shop_price": "3520", + "ge_buy_limit": "100", + "examine": "A full face helmet.", + "durability": null, + "weight": "2.7", + "absorb": "1,0,2", + "equip_audio": "2240", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "1911", + "name": "Adamant full helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1161", + "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,6,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1911", + "durability": null, + "name": "Adamant full helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1162" + }, + { + "remove_head": "true", + "requirements": "{1,40}", + "ge_buy_limit": "100", + "examine": "A full face helmet.", + "durability": null, + "weight": "2.7", + "absorb": "1,0,3", + "equip_audio": "2240", + "remove_beard": "true", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "20900", + "name": "Rune full helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1163", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "20900", + "durability": null, + "name": "Rune full helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1164" + }, + { + "remove_head": "true", + "requirements": "{1,10}", + "shop_price": "1372", + "ge_buy_limit": "100", + "examine": "A full face helmet.", + "durability": null, + "weight": "2.7", + "equip_audio": "2240", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "731", + "name": "Black full helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1165", + "bonuses": "0,0,0,-6,-2,12,13,10,-1,12,4,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "731", + "durability": null, + "name": "Black full helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1166" + }, + { + "remove_head": "true", + "shop_price": "24", + "ge_buy_limit": "5000", + "examine": "Better than no armour!", + "durability": null, + "weight": "0.9", + "equipment_slot": "0", + "grand_exchange_price": "9", + "name": "Leather cowl", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1167", + "bonuses": "0,0,0,0,1,2,3,4,2,3,0,0,0,0,0" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "9", + "durability": null, + "name": "Leather cowl", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1168" + }, + { + "remove_head": "true", + "requirements": "{4,20}", + "shop_price": "200", + "ge_buy_limit": "5000", + "examine": "Light weight head protection.", + "durability": null, + "weight": "0.9", + "equip_audio": "2238", + "equipment_slot": "0", + "grand_exchange_price": "56", + "name": "Coif", + "tradeable": "true", + "archery_ticket_price": "100", + "id": "1169", + "bonuses": "0,0,0,-1,2,4,6,8,4,4,5,0,0,0,0" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "56", + "durability": null, + "name": "Coif", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1170" + }, + { + "shop_price": "20", + "ge_buy_limit": "100", + "examine": "A solid wooden shield.", + "grand_exchange_price": "483", + "durability": null, + "name": "Wooden shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1171", + "bonuses": "0,0,0,0,0,4,5,3,1,4,0,0,0,0,0", + "equip_audio": "2250", + "equipment_slot": "5" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "483", + "durability": null, + "name": "Wooden shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1172" + }, + { + "shop_price": "48", + "ge_buy_limit": "100", + "examine": "A medium square shield.", + "durability": null, + "weight": "3", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "12", + "name": "Bronze sq shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1173", + "bonuses": "0,0,0,-6,-2,5,6,4,0,5,0,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "12", + "durability": null, + "name": "Bronze sq shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1174" + }, + { + "shop_price": "168", + "ge_buy_limit": "100", + "examine": "A medium square shield.", + "durability": null, + "weight": "3.6", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "39", + "name": "Iron sq shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1175", + "bonuses": "0,0,0,-6,-2,8,9,7,0,8,1,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "39", + "durability": null, + "name": "Iron sq shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1176" + }, + { + "requirements": "{1,5}", + "shop_price": "600", + "ge_buy_limit": "100", + "examine": "A medium square shield.", + "durability": null, + "weight": "3", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "185", + "name": "Steel sq shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1177", + "bonuses": "0,0,0,-6,-2,12,13,11,0,12,4,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "185", + "durability": null, + "name": "Steel sq shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1178" + }, + { + "requirements": "{1,10}", + "shop_price": "1463", + "ge_buy_limit": "100", + "examine": "A medium square shield.", + "durability": null, + "weight": "4", + "absorb": "1,0,2", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "511", + "name": "Black sq shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1179", + "bonuses": "0,0,0,-6,-2,15,16,14,0,15,9,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "511", + "durability": null, + "name": "Black sq shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1180" + }, + { + "requirements": "{1,20}", + "shop_price": "1560", + "ge_buy_limit": "100", + "examine": "A medium square shield.", + "durability": null, + "weight": "3.1", + "absorb": "2,0,4", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "744", + "name": "Mithril sq shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1181", + "bonuses": "0,0,0,-6,-2,17,19,15,0,17,18,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "744", + "durability": null, + "name": "Mithril sq shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1182" + }, + { + "requirements": "{1,30}", + "ge_buy_limit": "100", + "examine": "A medium square shield.", + "durability": null, + "weight": "4", + "absorb": "3,0,6", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "2136", + "name": "Adamant sq shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1183", + "bonuses": "0,0,0,-6,-2,24,26,22,0,24,25,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2136", + "durability": null, + "name": "Adamant sq shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1184" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "100", + "examine": "A medium square shield.", + "durability": null, + "weight": "3.64", + "absorb": "3,0,7", + "equip_audio": "2245", + "equipment_slot": "5", + "lendable": "true", + "grand_exchange_price": "22800", + "name": "Rune sq shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1185", + "bonuses": "0,0,0,-6,-2,38,40,36,0,38,35,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "22800", + "durability": null, + "name": "Rune sq shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1186" + }, + { + "requirements": "{1,60}", + "ge_buy_limit": "10", + "examine": "An ancient and powerful looking Dragon Square shield.", + "durability": null, + "weight": "3", + "absorb": "5,0,11", + "equip_audio": "2245", + "equipment_slot": "5", + "lendable": "true", + "grand_exchange_price": "431900", + "name": "Dragon sq shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1187", + "bonuses": "0,0,0,-6,-2,50,52,48,0,50,50,0,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "431900", + "durability": null, + "name": "Dragon sq shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1188" + }, + { + "shop_price": "86", + "ge_buy_limit": "100", + "examine": "A large metal shield.", + "durability": null, + "weight": "5.4", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "18", + "name": "Bronze kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1189", + "bonuses": "0,0,0,-8,-2,5,7,6,-1,6,1,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "18", + "durability": null, + "name": "Bronze kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1190" + }, + { + "shop_price": "233", + "ge_buy_limit": "100", + "examine": "A large metal shield.", + "durability": null, + "weight": "5.4", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "57", + "name": "Iron kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1191", + "bonuses": "0,0,0,-8,-2,8,10,9,-1,9,2,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "57", + "durability": null, + "name": "Iron kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1192" + }, + { + "requirements": "{1,5}", + "shop_price": "850", + "ge_buy_limit": "100", + "examine": "A large metal shield.", + "durability": null, + "weight": "5.4", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "354", + "name": "Steel kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1193", + "bonuses": "0,0,0,-8,-2,13,15,14,-1,14,5,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "354", + "durability": null, + "name": "Steel kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1194" + }, + { + "requirements": "{1,10}", + "shop_price": "2121", + "ge_buy_limit": "100", + "examine": "A large metal shield.", + "durability": null, + "weight": "5.4", + "absorb": "1,0,2", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "3311", + "name": "Black kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1195", + "bonuses": "0,0,0,-8,-2,17,19,18,-1,18,10,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3311", + "durability": null, + "name": "Black kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1196" + }, + { + "requirements": "{1,20}", + "ge_buy_limit": "100", + "examine": "A large metal shield.", + "durability": null, + "weight": "4.5", + "absorb": "2,0,4", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "1128", + "name": "Mithril kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1197", + "bonuses": "0,0,0,-8,-2,18,22,20,-1,20,20,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1128", + "durability": null, + "name": "Mithril kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1198" + }, + { + "requirements": "{1,30}", + "ge_buy_limit": "100", + "examine": "A large metal shield.", + "durability": null, + "weight": "5.8", + "absorb": "3,0,6", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "3066", + "name": "Adamant kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1199", + "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,30,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3066", + "durability": null, + "name": "Adamant kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1200" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "100", + "examine": "A large metal shield.", + "durability": null, + "weight": "5.4", + "absorb": "3,0,7", + "equip_audio": "2245", + "equipment_slot": "5", + "lendable": "true", + "grand_exchange_price": "35600", + "name": "Rune kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1201", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "35600", + "durability": null, + "name": "Rune kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1202" + }, + { + "shop_price": "38", + "ge_buy_limit": "100", + "examine": "Short but pointy.", + "durability": null, + "weight": "0.4", + "attack_speed": "4", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "defence_anim": "378", + "equipment_slot": "3", + "attack_anims": "400,400,401,400", + "grand_exchange_price": "35", + "attack_audios": "2517,2517,2500,2517", + "name": "Iron dagger", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1203", + "bonuses": "5,3,-4,1,0,0,0,0,1,0,0,4,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "35", + "durability": null, + "name": "Iron dagger", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1204" + }, + { + "shop_price": "11", + "ge_buy_limit": "100", + "examine": "Short but pointy.", + "durability": null, + "weight": "0.4", + "attack_speed": "4", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "defence_anim": "378", + "equipment_slot": "3", + "attack_anims": "400,400,401,400", + "grand_exchange_price": "105", + "attack_audios": "2517,2517,2500,2517", + "name": "Bronze dagger", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1205", + "bonuses": "4,2,-4,1,0,0,0,0,1,0,0,3,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "105", + "durability": null, + "name": "Bronze dagger", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1206", + "equip_audio": "" + }, + { + "requirements": "{0,5}", + "shop_price": "135", + "ge_buy_limit": "100", + "examine": "Short but pointy.", + "durability": null, + "weight": "0.4", + "attack_speed": "4", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "defence_anim": "378", + "equipment_slot": "3", + "attack_anims": "400,400,401,400", + "grand_exchange_price": "17", + "attack_audios": "2517,2517,2500,2517", + "name": "Steel dagger", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1207", + "bonuses": "8,4,-4,1,0,0,0,0,1,0,0,7,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "17", + "durability": null, + "name": "Steel dagger", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1208" + }, + { + "requirements": "{0,20}", + "shop_price": "130", + "ge_buy_limit": "100", + "examine": "A dangerous dagger.", + "durability": null, + "weight": "0.3", + "attack_speed": "4", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "defence_anim": "378", + "equipment_slot": "3", + "attack_anims": "400,400,401,400", + "grand_exchange_price": "71", + "attack_audios": "2517,2517,2500,2517", + "name": "Mithril dagger", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1209", + "bonuses": "11,5,-4,1,0,0,0,0,1,0,0,10,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "71", + "durability": null, + "name": "Mithril dagger", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1210" + }, + { + "requirements": "{0,30}", + "shop_price": "816", + "ge_buy_limit": "100", + "examine": "Short and deadly.", + "durability": null, + "weight": "0.4", + "attack_speed": "4", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "defence_anim": "378", + "equipment_slot": "3", + "attack_anims": "400,400,401,400", + "grand_exchange_price": "300", + "attack_audios": "2517,2517,2500,2517", + "name": "Adamant dagger", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1211", + "bonuses": "15,8,-4,1,0,0,0,0,1,0,0,14,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "300", + "durability": null, + "name": "Adamant dagger", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1212" + }, + { + "requirements": "{0,40}", + "shop_price": "8000", + "ge_buy_limit": "100", + "examine": "A powerful dagger.", + "durability": null, + "weight": "0.4", + "attack_speed": "4", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "defence_anim": "378", + "equipment_slot": "3", + "attack_anims": "400,400,401,400", + "lendable": "true", + "grand_exchange_price": "4642", + "attack_audios": "2517,2517,2500,2517", + "name": "Rune dagger", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1213", + "bonuses": "25,12,-4,1,0,0,0,0,1,0,0,24,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "4642", + "durability": null, + "name": "Rune dagger", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1214" + }, + { + "requirements": "{0,60}", + "shop_price": "60000", + "ge_buy_limit": "10", + "examine": "A powerful dagger.", + "has_special": "true", + "durability": null, + "weight": "0.4", + "attack_speed": "4", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "396,396,395,396", + "lendable": "true", + "grand_exchange_price": "17700", + "attack_audios": "2517,2517,2500,2517", + "name": "Dragon dagger", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1215", + "bonuses": "40,25,-4,1,0,0,0,0,1,0,0,40,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "17700", + "durability": null, + "name": "Dragon dagger", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1216" + }, + { + "requirements": "{0,10}", + "shop_price": "240", + "ge_buy_limit": "100", + "examine": "A vicious black dagger.", + "durability": null, + "weight": "0.4", + "attack_speed": "4", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "defence_anim": "378", + "equipment_slot": "3", + "attack_anims": "400,400,401,400", + "grand_exchange_price": "79", + "attack_audios": "2517,2517,2500,2517", + "name": "Black dagger", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1217", + "bonuses": "10,5,-4,1,0,0,0,0,1,0,0,7,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "79", + "durability": null, + "name": "Black dagger", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1218" + }, + { + "shop_price": "38", + "ge_buy_limit": "100", + "examine": "Short but pointy.", + "durability": null, + "weight": "0.4", + "attack_speed": "4", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "defence_anim": "378", + "equipment_slot": "3", + "attack_anims": "400,400,401,400", + "grand_exchange_price": "56", + "attack_audios": "2517,2517,2500,2517", + "name": "Iron dagger(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1219", + "bonuses": "5,3,-4,1,0,0,0,0,1,0,0,4,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "56", + "durability": null, + "name": "Iron dagger(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1220" + }, + { + "shop_price": "11", + "ge_buy_limit": "100", + "examine": "Short but pointy.", + "durability": null, + "weight": "0.4", + "attack_speed": "4", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "defence_anim": "378", + "equipment_slot": "3", + "attack_anims": "400,400,401,400", + "grand_exchange_price": "86", + "attack_audios": "2517,2517,2500,2517", + "name": "Bronze dagger(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1221", + "bonuses": "4,2,-4,1,0,0,0,0,1,0,0,3,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "86", + "durability": null, + "name": "Bronze dagger(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1222" + }, + { + "requirements": "{0,5}", + "shop_price": "135", + "ge_buy_limit": "100", + "examine": "Short but pointy.", + "durability": null, + "weight": "0.4", + "attack_speed": "4", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "defence_anim": "378", + "equipment_slot": "3", + "attack_anims": "400,400,401,400", + "grand_exchange_price": "98", + "attack_audios": "2517,2517,2500,2517", + "name": "Steel dagger(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1223", + "bonuses": "8,4,-4,1,0,0,0,0,1,0,0,7,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "98", + "durability": null, + "name": "Steel dagger(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1224" + }, + { + "requirements": "{0,20}", + "shop_price": "130", + "ge_buy_limit": "100", + "examine": "A dangerous dagger.", + "durability": null, + "weight": "0.3", + "attack_speed": "4", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "defence_anim": "378", + "equipment_slot": "3", + "attack_anims": "400,400,401,400", + "grand_exchange_price": "129", + "attack_audios": "2517,2517,2500,2517", + "name": "Mithril dagger(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1225", + "bonuses": "11,5,-4,1,0,0,0,0,1,0,0,10,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "129", + "durability": null, + "name": "Mithril dagger(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1226" + }, + { + "requirements": "{0,30}", + "shop_price": "816", + "ge_buy_limit": "100", + "examine": "Short and deadly.", + "durability": null, + "weight": "0.4", + "attack_speed": "4", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "defence_anim": "378", + "equipment_slot": "3", + "attack_anims": "400,400,401,400", + "grand_exchange_price": "365", + "attack_audios": "2517,2517,2500,2517", + "name": "Adamant dagger(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1227", + "bonuses": "15,8,-4,1,0,0,0,0,1,0,0,14,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "365", + "durability": null, + "name": "Adamant dagger(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1228" + }, + { + "requirements": "{0,40}", + "shop_price": "8000", + "ge_buy_limit": "100", + "examine": "A powerful dagger.", + "durability": null, + "weight": "0.4", + "attack_speed": "4", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "defence_anim": "378", + "equipment_slot": "3", + "attack_anims": "400,400,401,400", + "lendable": "true", + "grand_exchange_price": "4831", + "attack_audios": "2517,2517,2500,2517", + "name": "Rune dagger(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1229", + "bonuses": "25,12,-4,1,0,0,0,0,1,0,0,24,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "4831", + "durability": null, + "name": "Rune dagger(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1230" + }, + { + "requirements": "{0,60}", + "shop_price": "60000", + "ge_buy_limit": "10", + "examine": "A powerful dagger.", + "has_special": "true", + "durability": null, + "weight": "0.4", + "attack_speed": "4", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "396,396,395,396", + "lendable": "true", + "grand_exchange_price": "17600", + "attack_audios": "2517,2517,2500,2517", + "name": "Dragon dagger(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1231", + "bonuses": "40,25,-4,1,0,0,0,0,1,0,0,40,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "17600", + "durability": null, + "name": "Dragon dagger(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1232" + }, + { + "requirements": "{0,10}", + "shop_price": "240", + "ge_buy_limit": "100", + "examine": "A vicious black dagger.", + "durability": null, + "weight": "0.4", + "attack_speed": "4", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "defence_anim": "378", + "equipment_slot": "3", + "attack_anims": "400,400,401,400", + "grand_exchange_price": "67", + "attack_audios": "2517,2517,2500,2517", + "name": "Black dagger(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1233", + "bonuses": "10,5,-4,1,0,0,0,0,1,0,0,7,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "67", + "durability": null, + "name": "Black dagger(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1234" + }, + { + "durability": null, + "name": "Poisoned dagger(p)", + "archery_ticket_price": "0", + "id": "1235", + "render_anim": "2584" + }, + { + "durability": null, + "name": "Poisoned dagger(p)", + "archery_ticket_price": "0", + "id": "1236" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A bronze tipped spear.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "turn180_anim": "1206", + "defence_anim": "2079", + "equipment_slot": "3", + "attack_anims": "428,2081,429,428", + "grand_exchange_price": "858", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "1237", + "stand_turn_anim": "1209", + "bonuses": "5,5,5,0,0,1,1,0,0,0,0,6,0,0,0", + "shop_price": "26", + "durability": null, + "weight": "2.2", + "weapon_interface": "14", + "equip_audio": "2247", + "render_anim": "28", + "name": "Bronze spear" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "858", + "durability": null, + "name": "Bronze spear", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1238" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "An iron tipped spear.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "turn180_anim": "1206", + "defence_anim": "2079", + "equipment_slot": "3", + "attack_anims": "428,2081,429,428", + "grand_exchange_price": "209", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "1239", + "stand_turn_anim": "1209", + "bonuses": "8,8,8,0,0,1,1,0,0,0,0,10,0,0,0", + "durability": null, + "weight": "2.2", + "weapon_interface": "14", + "equip_audio": "2247", + "render_anim": "28", + "name": "Iron spear" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "209", + "durability": null, + "name": "Iron spear", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1240" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A steel tipped spear.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "turn180_anim": "1206", + "defence_anim": "2079", + "equipment_slot": "3", + "attack_anims": "428,2081,429,428", + "grand_exchange_price": "340", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "1241", + "stand_turn_anim": "1209", + "bonuses": "12,12,12,0,0,1,1,0,0,0,0,12,0,0,0", + "requirements": "{0,5}", + "durability": null, + "weight": "2.2", + "weapon_interface": "14", + "equip_audio": "2247", + "render_anim": "28", + "name": "Steel spear" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "340", + "durability": null, + "name": "Steel spear", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1242" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A mithril tipped spear.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "turn180_anim": "1206", + "defence_anim": "2079", + "equipment_slot": "3", + "attack_anims": "428,2081,429,428", + "grand_exchange_price": "353", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "1243", + "stand_turn_anim": "1209", + "bonuses": "17,17,17,0,0,1,1,0,0,0,0,18,0,0,0", + "requirements": "{0,20}", + "durability": null, + "weight": "1.8", + "weapon_interface": "14", + "equip_audio": "2247", + "render_anim": "28", + "name": "Mithril spear" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "353", + "durability": null, + "name": "Mithril spear", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1244" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "An adamant tipped spear.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "turn180_anim": "1206", + "defence_anim": "2079", + "equipment_slot": "3", + "attack_anims": "428,2081,429,428", + "grand_exchange_price": "1191", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "1245", + "stand_turn_anim": "1209", + "bonuses": "24,24,24,0,0,1,1,0,0,0,0,28,0,0,0", + "requirements": "{0,30}", + "durability": null, + "weight": "2", + "weapon_interface": "14", + "equip_audio": "2247", + "render_anim": "28", + "name": "Adamant spear" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1191", + "durability": null, + "name": "Adamant spear", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1246" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A rune tipped spear.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "turn180_anim": "1206", + "defence_anim": "2079", + "equipment_slot": "3", + "attack_anims": "428,2081,429,428", + "grand_exchange_price": "12200", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "1247", + "stand_turn_anim": "1209", + "bonuses": "36,36,36,0,0,1,1,0,0,0,0,42,0,0,0", + "requirements": "{0,40}", + "durability": null, + "weight": "2.2", + "weapon_interface": "14", + "equip_audio": "2247", + "render_anim": "28", + "lendable": "true", + "name": "Rune spear" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "12200", + "durability": null, + "name": "Rune spear", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1248" + }, + { + "ge_buy_limit": "10", + "turn90cw_anim": "1207", + "examine": "A dragon tipped spear.", + "walk_anim": "1205", + "has_special": "true", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "turn180_anim": "1206", + "defence_anim": "2079", + "equipment_slot": "3", + "attack_anims": "428,2081,429,428", + "grand_exchange_price": "37200", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "1249", + "stand_turn_anim": "1209", + "bonuses": "55,55,55,0,0,5,5,5,5,5,0,60,0,0,0", + "requirements": "{0,60}", + "durability": null, + "weight": "2", + "weapon_interface": "14", + "equip_audio": "2247", + "render_anim": "28", + "lendable": "true", + "name": "Dragon spear" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "37200", + "durability": null, + "name": "Dragon spear", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1250", + "defence_anim": "2079" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A bronze tipped spear.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "turn180_anim": "1206", + "defence_anim": "2079", + "equipment_slot": "3", + "attack_anims": "428,2081,429,428", + "grand_exchange_price": "389", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "1251", + "stand_turn_anim": "1209", + "bonuses": "5,5,5,0,0,1,1,0,0,0,0,6,0,0,0", + "durability": null, + "weight": "2.2", + "weapon_interface": "14", + "equip_audio": "2247", + "render_anim": "28", + "name": "Bronze spear(p)" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "389", + "durability": null, + "name": "Bronze spear(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1252" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "An iron tipped spear.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "turn180_anim": "1206", + "defence_anim": "2079", + "equipment_slot": "3", + "attack_anims": "428,2081,429,428", + "grand_exchange_price": "212", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "1253", + "stand_turn_anim": "1209", + "bonuses": "8,8,8,0,0,1,1,0,0,0,0,10,0,0,0", + "durability": null, + "weight": "2.2", + "weapon_interface": "14", + "equip_audio": "2247", + "render_anim": "28", + "name": "Iron spear(p)" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "212", + "durability": null, + "name": "Iron spear(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1254" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A steel tipped spear.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "turn180_anim": "1206", + "equipment_slot": "3", + "attack_anims": "428,2081,429,428", + "grand_exchange_price": "136", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "1255", + "stand_turn_anim": "1209", + "bonuses": "12,12,12,0,0,1,1,0,0,0,0,12,0,0,0", + "requirements": "{0,5}", + "durability": null, + "weight": "2.2", + "weapon_interface": "14", + "equip_audio": "2247", + "render_anim": "28", + "name": "Steel spear(p)" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "136", + "durability": null, + "name": "Steel spear(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1256" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A mithril tipped spear.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "turn180_anim": "1206", + "defence_anim": "2079", + "equipment_slot": "3", + "attack_anims": "428,2081,429,428", + "grand_exchange_price": "350", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "1257", + "stand_turn_anim": "1209", + "bonuses": "17,17,17,0,0,1,1,0,0,0,0,18,0,0,0", + "requirements": "{0,20}", + "durability": null, + "weight": "1.8", + "weapon_interface": "14", + "equip_audio": "2247", + "render_anim": "28", + "name": "Mithril spear(p)" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "350", + "durability": null, + "name": "Mithril spear(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1258" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "An adamant tipped spear.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "turn180_anim": "1206", + "defence_anim": "2079", + "equipment_slot": "3", + "attack_anims": "428,2081,429,428", + "grand_exchange_price": "1004", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "1259", + "stand_turn_anim": "1209", + "bonuses": "24,24,24,0,0,1,1,0,0,0,0,28,0,0,0", + "requirements": "{0,30}", + "durability": null, + "weight": "2", + "weapon_interface": "14", + "equip_audio": "2247", + "render_anim": "28", + "name": "Adamant spear(p)" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1004", + "durability": null, + "name": "Adamant spear(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1260" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A rune tipped spear.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "turn180_anim": "1206", + "defence_anim": "2079", + "equipment_slot": "3", + "attack_anims": "428,2081,429,428", + "grand_exchange_price": "12400", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "1261", + "stand_turn_anim": "1209", + "bonuses": "36,36,36,0,0,1,1,0,0,0,0,42,0,0,0", + "requirements": "{0,40}", + "durability": null, + "weight": "2.2", + "weapon_interface": "14", + "equip_audio": "2247", + "render_anim": "28", + "lendable": "true", + "name": "Rune spear(p)" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "12400", + "durability": null, + "name": "Rune spear(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1262" + }, + { + "ge_buy_limit": "10", + "turn90cw_anim": "1207", + "examine": "A dragon tipped spear.", + "walk_anim": "1205", + "has_special": "true", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "turn180_anim": "1206", + "defence_anim": "2079", + "equipment_slot": "3", + "attack_anims": "428,2081,429,428", + "grand_exchange_price": "39700", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "1263", + "stand_turn_anim": "1209", + "bonuses": "55,55,55,0,0,5,5,5,5,5,0,60,0,0,0", + "requirements": "{0,60}", + "durability": null, + "weight": "2", + "weapon_interface": "14", + "equip_audio": "2247", + "render_anim": "28", + "lendable": "true", + "name": "Dragon spear(p)" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "39700", + "durability": null, + "name": "Dragon spear(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1264" + }, + { + "shop_price": "1", + "ge_buy_limit": "100", + "examine": "Used for mining.", + "durability": null, + "weight": "2.25", + "attack_speed": "5", + "weapon_interface": "4", + "equip_audio": "2232", + "defence_anim": "403", + "equipment_slot": "3", + "attack_anims": "401,401,400,401", + "grand_exchange_price": "17", + "attack_audios": "2508,2508,2508,2508", + "name": "Bronze pickaxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1265", + "bonuses": "4,-2,2,0,0,0,1,0,0,0,0,5,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "17", + "durability": null, + "name": "Bronze pickaxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1266" + }, + { + "shop_price": "140", + "ge_buy_limit": "100", + "examine": "Used for mining.", + "durability": null, + "weight": "2.25", + "attack_speed": "5", + "weapon_interface": "4", + "equip_audio": "2232", + "defence_anim": "403", + "equipment_slot": "3", + "attack_anims": "401,401,400,401", + "grand_exchange_price": "200", + "attack_audios": "2508,2508,2508,2508", + "name": "Iron pickaxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1267", + "bonuses": "5,-2,3,0,0,0,1,0,0,0,0,7,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "200", + "durability": null, + "name": "Iron pickaxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1268" + }, + { + "requirements": "{0,5}", + "shop_price": "500", + "ge_buy_limit": "100", + "examine": "Used for mining.", + "durability": null, + "weight": "2.25", + "attack_speed": "5", + "weapon_interface": "4", + "equip_audio": "2232", + "defence_anim": "403", + "equipment_slot": "3", + "attack_anims": "401,401,400,401", + "grand_exchange_price": "571", + "attack_audios": "2508,2508,2508,2508", + "name": "Steel pickaxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1269", + "bonuses": "8,-2,6,0,0,0,1,0,0,0,0,9,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "571", + "durability": null, + "name": "Steel pickaxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1270" + }, + { + "requirements": "{0,30}-{14,31}", + "shop_price": "3200", + "ge_buy_limit": "100", + "examine": "Used for mining.", + "durability": null, + "weight": "2.7", + "attack_speed": "5", + "weapon_interface": "4", + "equip_audio": "2232", + "defence_anim": "403", + "equipment_slot": "3", + "attack_anims": "401,401,400,401", + "grand_exchange_price": "1782", + "attack_audios": "2508,2508,2508,2508", + "name": "Adamant pickaxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1271", + "bonuses": "17,-2,15,0,0,0,1,0,0,0,0,19,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1782", + "durability": null, + "name": "Adamant pickaxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1272" + }, + { + "requirements": "{0,20}", + "shop_price": "1300", + "ge_buy_limit": "100", + "examine": "Used for mining.", + "durability": null, + "weight": "1.8", + "attack_speed": "5", + "weapon_interface": "4", + "equip_audio": "2232", + "defence_anim": "403", + "equipment_slot": "3", + "attack_anims": "401,401,400,401", + "grand_exchange_price": "611", + "attack_audios": "2508,2508,2508,2508", + "name": "Mithril pickaxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1273", + "bonuses": "12,-2,10,0,0,0,1,0,0,0,0,13,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "611", + "durability": null, + "name": "Mithril pickaxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1274" + }, + { + "requirements": "{0,40}-{14,41}", + "shop_price": "32000", + "ge_buy_limit": "100", + "examine": "Used for mining.", + "durability": null, + "weight": "2.2", + "attack_speed": "5", + "weapon_interface": "4", + "equip_audio": "2232", + "defence_anim": "403", + "equipment_slot": "3", + "attack_anims": "401,401,400,401", + "lendable": "true", + "grand_exchange_price": "19500", + "attack_audios": "2508,2508,2508,2508", + "name": "Rune pickaxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1275", + "bonuses": "26,-2,24,0,0,0,1,0,0,0,0,29,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "19500", + "durability": null, + "name": "Rune pickaxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1276" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A razor sharp sword.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "4", + "turn180_anim": "1206", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "381,381,390,381", + "grand_exchange_price": "13", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "1277", + "stand_turn_anim": "823", + "bonuses": "4,3,-2,0,0,0,2,1,0,0,0,5,0,0,0", + "shop_price": "33", + "durability": null, + "weight": "1", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "1381", + "attack_audios": "2500,2500,2517,2500", + "name": "Bronze sword" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "13", + "durability": null, + "name": "Bronze sword", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1278" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A razor sharp sword.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "4", + "turn180_anim": "1206", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "381,381,390,381", + "grand_exchange_price": "17", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "1279", + "stand_turn_anim": "823", + "bonuses": "6,4,-2,0,0,0,2,1,0,0,0,7,0,0,0", + "shop_price": "91", + "durability": null, + "weight": "1.8", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "1381", + "attack_audios": "2500,2500,2517,2500", + "name": "Iron sword" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "17", + "durability": null, + "name": "Iron sword", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1280" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A razor sharp sword.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "4", + "turn180_anim": "1206", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "381,381,390,381", + "grand_exchange_price": "79", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "1281", + "stand_turn_anim": "823", + "bonuses": "11,8,-2,0,0,0,2,1,0,0,0,12,0,0,0", + "requirements": "{0,5}", + "shop_price": "412", + "durability": null, + "weight": "1", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "1381", + "attack_audios": "2500,2500,2517,2500", + "name": "Steel sword" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "79", + "durability": null, + "name": "Steel sword", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1282" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A razor sharp sword.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "4", + "turn180_anim": "1206", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "381,381,390,381", + "grand_exchange_price": "197", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "1283", + "stand_turn_anim": "823", + "bonuses": "14,10,-2,0,0,0,2,1,0,0,0,12,0,0,0", + "requirements": "{0,10}", + "shop_price": "624", + "durability": null, + "weight": "1", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "1381", + "attack_audios": "2500,2500,2517,2500", + "name": "Black sword" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "197", + "durability": null, + "name": "Black sword", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1284" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A razor sharp sword.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "4", + "turn180_anim": "1206", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "381,381,390,381", + "grand_exchange_price": "313", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "1285", + "stand_turn_anim": "823", + "bonuses": "16,11,-2,0,0,0,2,1,0,0,0,17,0,0,0", + "requirements": "{0,20}", + "shop_price": "266", + "durability": null, + "weight": "1.5", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "1381", + "attack_audios": "2500,2500,2517,2500", + "name": "Mithril sword" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "313", + "durability": null, + "name": "Mithril sword", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1286" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A razor sharp sword.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "4", + "turn180_anim": "1206", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "381,381,390,381", + "grand_exchange_price": "1046", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "1287", + "stand_turn_anim": "823", + "bonuses": "23,18,-2,0,0,0,2,1,0,0,0,24,0,0,0", + "requirements": "{0,30}", + "shop_price": "2080", + "durability": null, + "weight": "1", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "1381", + "attack_audios": "2500,2500,2517,2500", + "name": "Adamant sword" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1046", + "durability": null, + "name": "Adamant sword", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1288" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A razor sharp sword.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "4", + "turn180_anim": "1206", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "381,381,390,381", + "grand_exchange_price": "12300", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "1289", + "stand_turn_anim": "823", + "bonuses": "38,26,-2,0,0,0,2,1,0,0,0,39,0,0,0", + "requirements": "{0,40}", + "shop_price": "20800", + "durability": null, + "weight": "1.8", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "1381", + "lendable": "true", + "attack_audios": "2500,2500,2517,2500", + "name": "Rune sword" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "12300", + "durability": null, + "name": "Rune sword", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1290" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "821", + "examine": "A razor sharp longsword.", + "walk_anim": "819", + "turn90ccw_anim": "822", + "attack_speed": "5", + "turn180_anim": "820", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "grand_exchange_price": "14", + "stand_anim": "808", + "tradeable": "true", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "1291", + "stand_turn_anim": "823", + "bonuses": "4,5,-2,0,0,0,3,2,0,0,0,7,0,0,0", + "shop_price": "23", + "durability": null, + "weight": "1.8", + "weapon_interface": "6", + "equip_audio": "2248", + "render_anim": "1", + "attack_audios": "2500,2500,2517,2500", + "name": "Bronze longsword" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "14", + "durability": null, + "name": "Bronze longsword", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1292" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "821", + "examine": "A razor sharp longsword.", + "walk_anim": "819", + "turn90ccw_anim": "822", + "attack_speed": "5", + "turn180_anim": "820", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "grand_exchange_price": "22", + "stand_anim": "808", + "tradeable": "true", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "1293", + "stand_turn_anim": "823", + "bonuses": "6,8,-2,0,0,0,3,2,0,0,0,10,0,0,0", + "shop_price": "177", + "durability": null, + "weight": "2", + "weapon_interface": "6", + "equip_audio": "2248", + "render_anim": "1", + "attack_audios": "2500,2500,2517,2500", + "name": "Iron longsword" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "22", + "durability": null, + "name": "Iron longsword", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1294" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "821", + "examine": "A razor sharp longsword.", + "walk_anim": "819", + "turn90ccw_anim": "822", + "attack_speed": "5", + "turn180_anim": "820", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "grand_exchange_price": "147", + "stand_anim": "808", + "tradeable": "true", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "1295", + "stand_turn_anim": "823", + "bonuses": "9,14,-2,0,0,0,3,2,0,0,0,16,0,0,0", + "requirements": "{0,5}", + "shop_price": "500", + "durability": null, + "weight": "2", + "weapon_interface": "6", + "equip_audio": "2248", + "render_anim": "1", + "attack_audios": "2500,2500,2517,2500", + "name": "Steel longsword" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "147", + "durability": null, + "name": "Steel longsword", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1296" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "821", + "examine": "A razor sharp longsword.", + "walk_anim": "819", + "turn90ccw_anim": "822", + "attack_speed": "5", + "turn180_anim": "820", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "grand_exchange_price": "384", + "stand_anim": "808", + "tradeable": "true", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "1297", + "stand_turn_anim": "823", + "bonuses": "13,18,-2,0,0,0,3,2,0,0,0,16,0,0,0", + "requirements": "{0,10}", + "shop_price": "960", + "durability": null, + "weight": "1.8", + "weapon_interface": "6", + "equip_audio": "2248", + "render_anim": "1", + "attack_audios": "2500,2500,2517,2500", + "name": "Black longsword" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "384", + "durability": null, + "name": "Black longsword", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1298" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "821", + "examine": "A razor sharp longsword.", + "walk_anim": "819", + "turn90ccw_anim": "822", + "attack_speed": "5", + "turn180_anim": "820", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "grand_exchange_price": "602", + "stand_anim": "808", + "tradeable": "true", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "1299", + "stand_turn_anim": "823", + "bonuses": "15,20,-2,0,0,0,3,2,0,0,0,22,0,0,0", + "requirements": "{0,20}", + "shop_price": "1074", + "durability": null, + "weight": "1.5", + "weapon_interface": "6", + "equip_audio": "2248", + "render_anim": "1", + "attack_audios": "2500,2500,2517,2500", + "name": "Mithril longsword" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "602", + "durability": null, + "name": "Mithril longsword", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1300" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "821", + "examine": "A razor sharp longsword.", + "walk_anim": "819", + "turn90ccw_anim": "822", + "attack_speed": "5", + "turn180_anim": "820", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "grand_exchange_price": "1808", + "stand_anim": "808", + "tradeable": "true", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "1301", + "stand_turn_anim": "823", + "bonuses": "20,29,-2,0,0,0,3,2,0,0,0,31,0,0,0", + "requirements": "{0,30}", + "shop_price": "3200", + "durability": null, + "weight": "2", + "weapon_interface": "6", + "equip_audio": "2248", + "render_anim": "1", + "attack_audios": "2500,2500,2517,2500", + "name": "Adamant longsword" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1808", + "durability": null, + "name": "Adamant longsword", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1302" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "821", + "examine": "A razor sharp longsword", + "walk_anim": "819", + "turn90ccw_anim": "822", + "attack_speed": "5", + "turn180_anim": "820", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "grand_exchange_price": "19000", + "stand_anim": "808", + "tradeable": "true", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "1303", + "stand_turn_anim": "823", + "bonuses": "38,47,-2,0,0,0,3,2,0,0,0,49,0,0,0", + "requirements": "{0,40}", + "shop_price": "32000", + "durability": null, + "weight": "1.8", + "weapon_interface": "6", + "equip_audio": "2248", + "render_anim": "1", + "lendable": "true", + "attack_audios": "2500,2500,2517,2500", + "name": "Rune longsword" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "19000", + "durability": null, + "name": "Rune longsword", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1304" + }, + { + "ge_buy_limit": "10", + "turn90cw_anim": "821", + "examine": "A very powerful sword.", + "walk_anim": "1146", + "has_special": "true", + "turn90ccw_anim": "822", + "attack_speed": "5", + "turn180_anim": "820", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "grand_exchange_price": "60200", + "stand_anim": "809", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "1305", + "stand_turn_anim": "823", + "bonuses": "58,69,-2,0,0,0,3,2,0,0,0,71,0,0,0", + "requirements": "{0,60}", + "shop_price": "100000", + "durability": null, + "weight": "1.8", + "weapon_interface": "6", + "equip_audio": "2248", + "render_anim": "1426", + "lendable": "true", + "attack_audios": "2500,2500,2517,2500", + "name": "Dragon longsword" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "60200", + "durability": null, + "name": "Dragon longsword", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1306" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "7044", + "examine": "A two-handed sword.", + "walk_anim": "7046", + "turn90ccw_anim": "7043", + "attack_speed": "7", + "two_handed": "true", + "turn180_anim": "7045", + "defence_anim": "7050", + "equipment_slot": "3", + "attack_anims": "7041,7041,7048,7049", + "grand_exchange_price": "89", + "stand_anim": "7047", + "tradeable": "true", + "run_anim": "7039", + "archery_ticket_price": "0", + "id": "1307", + "stand_turn_anim": "7040", + "bonuses": "-4,9,8,-4,0,0,0,0,0,-1,0,10,0,0,0", + "shop_price": "160", + "durability": null, + "weight": "3.6", + "weapon_interface": "7", + "equip_audio": "2248", + "render_anim": "124", + "attack_audios": "2503,0,2504,0", + "name": "Bronze 2h sword" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "89", + "durability": null, + "name": "Bronze 2h sword", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1308" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "7044", + "examine": "A two handed sword.", + "walk_anim": "7046", + "turn90ccw_anim": "7043", + "attack_speed": "7", + "two_handed": "true", + "turn180_anim": "7045", + "defence_anim": "7050", + "equipment_slot": "3", + "attack_anims": "7041,7041,7048,7049", + "grand_exchange_price": "32", + "stand_anim": "7047", + "tradeable": "true", + "run_anim": "7039", + "archery_ticket_price": "0", + "id": "1309", + "stand_turn_anim": "7040", + "bonuses": "-4,13,10,-4,0,0,0,0,0,-1,0,14,0,0,0", + "shop_price": "260", + "durability": null, + "weight": "3.6", + "weapon_interface": "7", + "equip_audio": "2248", + "render_anim": "124", + "attack_audios": "2503,0,2504,0", + "name": "Iron 2h sword" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "32", + "durability": null, + "name": "Iron 2h sword", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1310" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "7044", + "examine": "A two handed sword.", + "walk_anim": "7046", + "turn90ccw_anim": "7043", + "attack_speed": "7", + "two_handed": "true", + "turn180_anim": "7045", + "defence_anim": "7050", + "equipment_slot": "3", + "attack_anims": "7041,7041,7048,7049", + "grand_exchange_price": "411", + "stand_anim": "7047", + "tradeable": "true", + "run_anim": "7039", + "archery_ticket_price": "0", + "id": "1311", + "stand_turn_anim": "7040", + "bonuses": "-4,21,16,-4,0,0,0,0,0,-1,0,22,0,0,0", + "requirements": "{0,5}", + "shop_price": "1000", + "durability": null, + "weight": "3", + "weapon_interface": "7", + "equip_audio": "2248", + "render_anim": "124", + "attack_audios": "2503,0,2504,0", + "name": "Steel 2h sword" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "411", + "durability": null, + "name": "Steel 2h sword", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1312" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "7044", + "examine": "A two-handed sword.", + "walk_anim": "7046", + "turn90ccw_anim": "7043", + "attack_speed": "7", + "two_handed": "true", + "turn180_anim": "7045", + "defence_anim": "7050", + "equipment_slot": "3", + "attack_anims": "7041,7041,7048,7049", + "grand_exchange_price": "1031", + "stand_anim": "7047", + "tradeable": "true", + "run_anim": "7039", + "archery_ticket_price": "0", + "id": "1313", + "stand_turn_anim": "7040", + "bonuses": "-4,27,21,-4,0,0,0,0,0,-1,0,26,0,0,0", + "requirements": "{0,10}", + "shop_price": "2400", + "durability": null, + "weight": "3.6", + "weapon_interface": "7", + "equip_audio": "2248", + "render_anim": "124", + "attack_audios": "2503,0,2504,0", + "name": "Black 2h sword" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1031", + "durability": null, + "name": "Black 2h sword", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1314" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "7044", + "examine": "A two-handed sword.", + "walk_anim": "7046", + "turn90ccw_anim": "7043", + "attack_speed": "7", + "two_handed": "true", + "turn180_anim": "7045", + "defence_anim": "7050", + "equipment_slot": "3", + "attack_anims": "7041,7041,7048,7049", + "grand_exchange_price": "1396", + "stand_anim": "7047", + "tradeable": "true", + "run_anim": "7039", + "archery_ticket_price": "0", + "id": "1315", + "stand_turn_anim": "7040", + "bonuses": "-4,30,24,-4,0,0,0,0,0,-1,0,31,0,0,0", + "requirements": "{0,20}", + "shop_price": "3000", + "durability": null, + "weight": "3.1", + "weapon_interface": "7", + "equip_audio": "2248", + "render_anim": "124", + "attack_audios": "2503,0,2504,0", + "name": "Mithril 2h sword" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1396", + "durability": null, + "name": "Mithril 2h sword", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1316" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "7044", + "examine": "A two-handed sword.", + "walk_anim": "7046", + "turn90ccw_anim": "7043", + "attack_speed": "7", + "two_handed": "true", + "turn180_anim": "7045", + "defence_anim": "7050", + "equipment_slot": "3", + "attack_anims": "7041,7041,7048,7049", + "grand_exchange_price": "3577", + "stand_anim": "7047", + "tradeable": "true", + "run_anim": "7039", + "archery_ticket_price": "0", + "id": "1317", + "stand_turn_anim": "7040", + "bonuses": "-4,43,30,-4,0,0,0,0,0,-1,0,44,0,0,0", + "requirements": "{0,30}", + "shop_price": "6400", + "durability": null, + "weight": "4", + "weapon_interface": "7", + "equip_audio": "2248", + "render_anim": "124", + "attack_audios": "2503,0,2504,0", + "name": "Adamant 2h sword" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3577", + "durability": null, + "name": "Adamant 2h sword", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1318" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "7044", + "examine": "A two handed sword.", + "walk_anim": "7046", + "turn90ccw_anim": "7043", + "attack_speed": "7", + "two_handed": "true", + "turn180_anim": "7045", + "defence_anim": "7050", + "equipment_slot": "3", + "attack_anims": "7041,7041,7048,7049", + "grand_exchange_price": "38200", + "stand_anim": "7047", + "tradeable": "true", + "run_anim": "7039", + "archery_ticket_price": "0", + "id": "1319", + "stand_turn_anim": "7040", + "bonuses": "-4,69,50,-4,0,0,0,0,0,-1,0,70,0,0,0", + "requirements": "{0,40}", + "shop_price": "40000", + "durability": null, + "weight": "3.6", + "weapon_interface": "7", + "equip_audio": "2248", + "render_anim": "124", + "lendable": "true", + "attack_audios": "2503,0,2504,0", + "name": "Rune 2h sword" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "38200", + "durability": null, + "name": "Rune 2h sword", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1320" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "821", + "examine": "A vicious, curved sword.", + "walk_anim": "819", + "turn90ccw_anim": "822", + "attack_speed": "4", + "turn180_anim": "820", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "grand_exchange_price": "13", + "stand_anim": "808", + "tradeable": "true", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "1321", + "stand_turn_anim": "823", + "bonuses": "1,7,-2,0,0,0,1,0,0,0,0,6,0,0,0", + "shop_price": "40", + "durability": null, + "weight": "1", + "weapon_interface": "6", + "equip_audio": "2248", + "render_anim": "1", + "attack_audios": "2500,0,2517,0", + "name": "Bronze scimitar" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "13", + "durability": null, + "name": "Bronze scimitar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1322" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "821", + "examine": "A vicious, curved sword.", + "walk_anim": "819", + "turn90ccw_anim": "822", + "attack_speed": "4", + "turn180_anim": "820", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "grand_exchange_price": "30", + "stand_anim": "808", + "tradeable": "true", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "1323", + "stand_turn_anim": "823", + "bonuses": "2,10,-2,0,0,0,1,0,0,0,0,9,0,0,0", + "shop_price": "112", + "durability": null, + "weight": "1.8", + "weapon_interface": "6", + "equip_audio": "2248", + "render_anim": "1", + "attack_audios": "2500,0,2517,0", + "name": "Iron scimitar" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "30", + "durability": null, + "name": "Iron scimitar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1324" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "821", + "examine": "A vicious, curved sword.", + "walk_anim": "819", + "turn90ccw_anim": "822", + "attack_speed": "4", + "turn180_anim": "820", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "grand_exchange_price": "101", + "stand_anim": "808", + "tradeable": "true", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "1325", + "stand_turn_anim": "823", + "bonuses": "3,15,-2,0,0,0,1,0,0,0,0,14,0,0,0", + "requirements": "{0,5}", + "shop_price": "400", + "durability": null, + "weight": "1.8", + "weapon_interface": "6", + "equip_audio": "2248", + "render_anim": "1", + "attack_audios": "2500,0,2517,0", + "name": "Steel scimitar" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "101", + "durability": null, + "name": "Steel scimitar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1326" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "821", + "examine": "A vicious, curved sword.", + "walk_anim": "819", + "turn90ccw_anim": "822", + "attack_speed": "4", + "turn180_anim": "820", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "grand_exchange_price": "4498", + "stand_anim": "808", + "tradeable": "true", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "1327", + "stand_turn_anim": "823", + "bonuses": "4,19,-2,0,0,0,1,0,0,0,0,14,0,0,0", + "requirements": "{0,10}", + "durability": null, + "weight": "1.8", + "weapon_interface": "6", + "equip_audio": "2248", + "render_anim": "1", + "attack_audios": "2500,0,2517,0", + "name": "Black scimitar" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "4498", + "durability": null, + "name": "Black scimitar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1328" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "821", + "examine": "A vicious, curved sword.", + "walk_anim": "819", + "turn90ccw_anim": "822", + "attack_speed": "4", + "turn180_anim": "820", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "grand_exchange_price": "469", + "stand_anim": "808", + "tradeable": "true", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "1329", + "stand_turn_anim": "823", + "bonuses": "5,21,-2,0,0,0,1,0,0,0,0,20,0,0,0", + "requirements": "{0,20}", + "shop_price": "1040", + "durability": null, + "weight": "1.5", + "weapon_interface": "6", + "equip_audio": "2248", + "render_anim": "1", + "attack_audios": "2500,0,2517,0", + "name": "Mithril scimitar" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "469", + "durability": null, + "name": "Mithril scimitar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1330" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "821", + "examine": "A viciously curved sword", + "walk_anim": "819", + "turn90ccw_anim": "822", + "attack_speed": "4", + "turn180_anim": "820", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "grand_exchange_price": "1525", + "stand_anim": "808", + "tradeable": "true", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "1331", + "stand_turn_anim": "823", + "bonuses": "6,29,-2,0,0,0,1,0,0,0,0,28,0,0,0", + "requirements": "{0,30}", + "shop_price": "2304", + "durability": null, + "weight": "2", + "weapon_interface": "6", + "equip_audio": "2248", + "render_anim": "1", + "attack_audios": "2500,0,2517,0", + "name": "Adamant scimitar" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1525", + "durability": null, + "name": "Adamant scimitar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1332" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "821", + "examine": "A vicious, curved sword.", + "walk_anim": "819", + "turn90ccw_anim": "822", + "attack_speed": "4", + "turn180_anim": "820", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "grand_exchange_price": "15200", + "stand_anim": "808", + "tradeable": "true", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "1333", + "stand_turn_anim": "823", + "bonuses": "7,45,-2,0,0,0,1,0,0,0,0,44,0,0,0", + "requirements": "{0,40}", + "durability": null, + "weight": "1.8", + "weapon_interface": "6", + "equip_audio": "2248", + "render_anim": "1", + "lendable": "true", + "attack_audios": "2500,0,2517,0", + "name": "Rune scimitar" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "15200", + "durability": null, + "name": "Rune scimitar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1334" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "821", + "examine": "I don't think it's intended for joinery.", + "walk_anim": "819", + "turn90ccw_anim": "822", + "attack_speed": "6", + "turn180_anim": "820", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "395,395,395,395", + "grand_exchange_price": "20", + "stand_anim": "808", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "1335", + "stand_turn_anim": "823", + "bonuses": "-4,-4,11,-4,0,0,0,0,0,0,0,9,0,0,0", + "shop_price": "224", + "durability": null, + "weight": "1.8", + "weapon_interface": "10", + "equip_audio": "2233", + "render_anim": "1430", + "attack_audios": "2504,0,0,0", + "name": "Iron warhammer" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "20", + "durability": null, + "name": "Iron warhammer", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1336" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "821", + "examine": "I don't think it's intended for joinery.", + "walk_anim": "819", + "turn90ccw_anim": "822", + "attack_speed": "6", + "turn180_anim": "820", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "395,395,395,395", + "grand_exchange_price": "16", + "stand_anim": "808", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "1337", + "stand_turn_anim": "823", + "bonuses": "-4,-4,10,-4,0,0,0,0,0,0,0,8,0,0,0", + "shop_price": "59", + "durability": null, + "weight": "1", + "weapon_interface": "10", + "equip_audio": "2233", + "render_anim": "1430", + "attack_audios": "2504,0,0,0", + "name": "Bronze warhammer" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "16", + "durability": null, + "name": "Bronze warhammer", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1338" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "821", + "examine": "I don't think it's intended for joinery.", + "walk_anim": "819", + "turn90ccw_anim": "822", + "attack_speed": "6", + "turn180_anim": "820", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "395,395,395,395", + "grand_exchange_price": "283", + "stand_anim": "808", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "1339", + "stand_turn_anim": "823", + "bonuses": "-4,-4,18,-4,0,0,0,0,0,0,0,16,0,0,0", + "requirements": "{0,5}", + "shop_price": "832", + "durability": null, + "weight": "1", + "weapon_interface": "10", + "equip_audio": "2233", + "render_anim": "1430", + "attack_audios": "2504,0,0,0", + "name": "Steel warhammer" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "283", + "durability": null, + "name": "Steel warhammer", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1340" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "821", + "examine": "I don't think it's intended for joinery.", + "walk_anim": "819", + "turn90ccw_anim": "822", + "attack_speed": "6", + "turn180_anim": "820", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "395,395,395,395", + "grand_exchange_price": "562", + "stand_anim": "808", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "1341", + "stand_turn_anim": "823", + "bonuses": "-4,-4,22,-4,0,0,0,0,0,0,0,19,0,0,0", + "requirements": "{0,10}", + "shop_price": "1274", + "durability": null, + "weapon_interface": "10", + "equip_audio": "2233", + "render_anim": "1430", + "attack_audios": "2504,0,0,0", + "name": "Black warhammer" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "562", + "durability": null, + "name": "Black warhammer", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1342" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "821", + "examine": "I don't think it's intended for joinery.", + "walk_anim": "819", + "turn90ccw_anim": "822", + "attack_speed": "6", + "turn180_anim": "820", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "395,395,395,395", + "grand_exchange_price": "1071", + "stand_anim": "808", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "1343", + "stand_turn_anim": "823", + "bonuses": "-4,-4,25,-4,0,0,0,0,0,0,0,20,0,0,0", + "requirements": "{0,20}", + "shop_price": "2158", + "durability": null, + "weight": "1.5", + "weapon_interface": "10", + "equip_audio": "2233", + "render_anim": "1430", + "attack_audios": "2504,0,0,0", + "name": "Mithril warhammer" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1071", + "durability": null, + "name": "Mithril warhammer", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1344" + }, + { + "ge_buy_limit": "1000", + "turn90cw_anim": "821", + "examine": "I don't think it's intended for joinery.", + "walk_anim": "819", + "turn90ccw_anim": "822", + "attack_speed": "6", + "turn180_anim": "820", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "395,395,395,395", + "grand_exchange_price": "2996", + "stand_anim": "808", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "1345", + "stand_turn_anim": "823", + "bonuses": "-4,-4,33,-4,0,0,0,0,0,0,0,31,0,0,0", + "requirements": "{0,30}", + "shop_price": "5356", + "durability": null, + "weight": "2", + "weapon_interface": "10", + "equip_audio": "2233", + "render_anim": "1430", + "attack_audios": "2504,0,0,0", + "name": "Adamant warhammer" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "2996", + "durability": null, + "name": "Adamant warhammer", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1346" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "821", + "examine": "I don't think it's intended for joinery.", + "walk_anim": "819", + "turn90ccw_anim": "822", + "attack_speed": "6", + "turn180_anim": "820", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "395,395,395,395", + "grand_exchange_price": "24600", + "stand_anim": "808", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "1347", + "stand_turn_anim": "823", + "bonuses": "-4,-4,53,-4,0,0,0,0,0,0,0,48,0,0,0", + "requirements": "{0,40}", + "shop_price": "41000", + "durability": null, + "weight": "1.8", + "weapon_interface": "10", + "equip_audio": "2233", + "render_anim": "1430", + "lendable": "true", + "attack_audios": "2504,0,0,0", + "name": "Rune warhammer" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "24600", + "durability": null, + "name": "Rune warhammer", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1348" + }, + { + "shop_price": "56", + "ge_buy_limit": "100", + "examine": "A woodcutter's axe.", + "durability": null, + "weight": "1.3", + "attack_speed": "5", + "weapon_interface": "2", + "equip_audio": "2229", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "395,395,401,395", + "grand_exchange_price": "8", + "attack_audios": "2498,2498,2497,2498", + "name": "Iron axe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1349", + "bonuses": "-2,5,3,0,0,0,1,0,0,0,0,7,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "8", + "durability": null, + "name": "Iron axe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1350" + }, + { + "shop_price": "20", + "ge_buy_limit": "100", + "examine": "A woodcutter's axe.", + "durability": null, + "weight": "1.35", + "attack_speed": "5", + "weapon_interface": "2", + "equip_audio": "2229", + "render_anim": "2586", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "395,395,401,395", + "grand_exchange_price": "44", + "attack_audios": "2498,2498,2497,2498", + "name": "Bronze axe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1351", + "bonuses": "-2,4,2,0,0,0,1,0,0,0,0,5,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "44", + "durability": null, + "name": "Bronze axe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1352" + }, + { + "requirements": "{0,5}", + "shop_price": "200", + "ge_buy_limit": "100", + "examine": "A woodcutter's axe.", + "durability": null, + "weight": "1.3", + "attack_speed": "5", + "weapon_interface": "2", + "equip_audio": "2229", + "render_anim": "2586", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "395,395,401,395", + "grand_exchange_price": "36", + "attack_audios": "2498,2498,2497,2498", + "name": "Steel axe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1353", + "bonuses": "-2,8,6,0,0,0,1,0,0,0,0,9,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "36", + "durability": null, + "name": "Steel axe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1354" + }, + { + "requirements": "{0,20}", + "shop_price": "660", + "ge_buy_limit": "100", + "examine": "A powerful axe.", + "durability": null, + "weight": "1.1", + "attack_speed": "5", + "weapon_interface": "2", + "equip_audio": "2229", + "render_anim": "2586", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "395,395,401,395", + "grand_exchange_price": "141", + "attack_audios": "2498,2498,2497,2498", + "name": "Mithril axe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1355", + "bonuses": "-2,12,10,0,0,0,1,0,0,0,0,13,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "141", + "durability": null, + "name": "Mithril axe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1356" + }, + { + "requirements": "{0,30}-{8,31}", + "shop_price": "1625", + "ge_buy_limit": "100", + "examine": "A powerful axe.", + "durability": null, + "weight": "2", + "attack_speed": "5", + "weapon_interface": "2", + "equip_audio": "2229", + "render_anim": "2586", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "395,395,401,395", + "grand_exchange_price": "592", + "attack_audios": "2498,2498,2497,2498", + "name": "Adamant axe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1357", + "bonuses": "-2,17,15,0,0,0,1,0,0,0,0,19,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "592", + "durability": null, + "name": "Adamant axe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1358" + }, + { + "requirements": "{0,40}-{8,41}", + "ge_buy_limit": "100", + "examine": "A powerful axe.", + "durability": null, + "weapon_interface": "2", + "equip_audio": "2229", + "render_anim": "2586", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "395,395,401,395", + "grand_exchange_price": "7495", + "attack_audios": "2498,2498,2497,2498", + "name": "Rune axe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1359", + "bonuses": "-2,26,24,0,0,0,1,0,0,0,0,29,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "7495", + "durability": null, + "name": "Rune axe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1360" + }, + { + "requirements": "{0,10}", + "ge_buy_limit": "100", + "examine": "A sinister looking axe.", + "durability": null, + "weight": "2", + "attack_speed": "5", + "weapon_interface": "2", + "equip_audio": "2229", + "render_anim": "2586", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "395,395,401,395", + "grand_exchange_price": "335", + "attack_audios": "2498,2498,2497,2498", + "name": "Black axe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1361", + "bonuses": "-2,10,8,0,0,0,1,0,0,0,0,12,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "335", + "durability": null, + "name": "Black axe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1362" + }, + { + "shop_price": "182", + "ge_buy_limit": "100", + "examine": "A vicious looking axe.", + "durability": null, + "weight": "2.7", + "attack_speed": "6", + "weapon_interface": "2", + "equip_audio": "2232", + "render_anim": "2586", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "395,395,401,395", + "grand_exchange_price": "21", + "attack_audios": "2498,2498,2497,2498", + "name": "Iron battleaxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1363", + "bonuses": "-2,8,5,0,0,0,0,0,0,-1,0,13,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "21", + "durability": null, + "name": "Iron battleaxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1364" + }, + { + "requirements": "{0,5}", + "shop_price": "650", + "ge_buy_limit": "100", + "examine": "A vicious looking axe.", + "durability": null, + "weight": "2.7", + "attack_speed": "6", + "weapon_interface": "2", + "equip_audio": "2232", + "render_anim": "2586", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "395,395,401,395", + "grand_exchange_price": "208", + "attack_audios": "2498,2498,2497,2498", + "name": "Steel battleaxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1365", + "bonuses": "-2,16,11,0,0,0,0,0,0,-1,0,20,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "208", + "durability": null, + "name": "Steel battleaxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1366" + }, + { + "requirements": "{0,10}", + "shop_price": "1248", + "ge_buy_limit": "100", + "examine": "A vicious looking axe.", + "durability": null, + "weight": "2.7", + "attack_speed": "6", + "weapon_interface": "2", + "equip_audio": "2232", + "render_anim": "2586", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "395,395,401,395", + "grand_exchange_price": "556", + "attack_audios": "2498,2498,2497,2498", + "name": "Black battleaxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1367", + "bonuses": "-2,20,15,0,0,0,0,0,0,-1,0,24,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "556", + "durability": null, + "name": "Black battleaxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1368" + }, + { + "requirements": "{0,20}", + "shop_price": "1690", + "ge_buy_limit": "100", + "examine": "A vicious looking axe.", + "durability": null, + "weight": "2", + "attack_speed": "6", + "weapon_interface": "2", + "equip_audio": "2232", + "render_anim": "2586", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "395,395,401,395", + "grand_exchange_price": "809", + "attack_audios": "2498,2498,2497,2498", + "name": "Mithril battleaxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1369", + "bonuses": "-2,22,17,0,0,0,0,0,0,-1,0,29,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "809", + "durability": null, + "name": "Mithril battleaxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1370" + }, + { + "requirements": "{0,30}", + "shop_price": "4160", + "ge_buy_limit": "100", + "examine": "A vicious looking axe.", + "durability": null, + "weight": "3", + "attack_speed": "6", + "weapon_interface": "2", + "equip_audio": "2232", + "render_anim": "2586", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "395,395,401,395", + "grand_exchange_price": "2311", + "attack_audios": "2498,2498,2497,2498", + "name": "Adamant battleaxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1371", + "bonuses": "-2,31,26,0,0,0,0,0,0,-1,0,41,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2311", + "durability": null, + "name": "Adamant battleaxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1372" + }, + { + "requirements": "{0,40}", + "ge_buy_limit": "100", + "examine": "A vicious looking axe.", + "durability": null, + "weight": "2", + "attack_speed": "6", + "weapon_interface": "2", + "equip_audio": "2232", + "render_anim": "2586", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "395,395,401,395", + "lendable": "true", + "grand_exchange_price": "24800", + "attack_audios": "2498,2498,2497,2498", + "name": "Rune battleaxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1373", + "bonuses": "-2,48,43,0,0,0,0,0,0,-1,0,64,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "24800", + "durability": null, + "name": "Rune battleaxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1374" + }, + { + "shop_price": "52", + "ge_buy_limit": "100", + "examine": "A vicious looking axe.", + "durability": null, + "weight": "2.7", + "attack_speed": "6", + "weapon_interface": "2", + "equip_audio": "2232", + "render_anim": "2586", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "395,395,401,395", + "grand_exchange_price": "15", + "attack_audios": "2498,2498,2497,2498", + "name": "Bronze battleaxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1375", + "bonuses": "-2,6,3,0,0,0,0,0,0,-1,0,9,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "15", + "durability": null, + "name": "Bronze battleaxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1376" + }, + { + "requirements": "{0,60}", + "shop_price": "200000", + "ge_buy_limit": "10", + "examine": "A vicious looking axe.", + "has_special": "true", + "durability": null, + "weight": "2.7", + "attack_speed": "6", + "weapon_interface": "2", + "render_anim": "2586", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "395,395,401,395", + "lendable": "true", + "grand_exchange_price": "123200", + "attack_audios": "2498,2498,2497,2498", + "name": "Dragon battleaxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1377", + "bonuses": "-2,70,65,0,0,0,0,0,0,-1,0,85,0,0,0" + }, + { + "requirements": "{0,60}", + "ge_buy_limit": "10", + "grand_exchange_price": "123200", + "durability": null, + "name": "Dragon battleaxe", + "tradeable": "true", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "1378", + "defence_anim": "397" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "It's a slightly magical stick.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "turn180_anim": "1206", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "grand_exchange_price": "37", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "1379", + "stand_turn_anim": "1209", + "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0", + "shop_price": "15", + "durability": null, + "weight": "2", + "weapon_interface": "1", + "equip_audio": "2247", + "render_anim": "28", + "attack_audios": "2555,0,0,0", + "name": "Staff" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "37", + "durability": null, + "name": "Staff", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1380" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A Magical staff.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "turn180_anim": "1206", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "grand_exchange_price": "784", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "1381", + "stand_turn_anim": "1209", + "bonuses": "0,-1,7,10,0,2,3,1,10,0,0,3,0,0,0", + "shop_price": "1500", + "durability": null, + "weight": "2.2", + "weapon_interface": "1", + "equip_audio": "2247", + "render_anim": "28", + "attack_audios": "2555,0,0,0", + "name": "Staff of air" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "784", + "durability": null, + "name": "Staff of air", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1382" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A Magical staff.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "turn180_anim": "1206", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "grand_exchange_price": "890", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "1383", + "stand_turn_anim": "1209", + "bonuses": "0,-1,7,10,0,2,3,1,10,0,0,3,0,0,0", + "shop_price": "1500", + "durability": null, + "weight": "2.2", + "weapon_interface": "1", + "equip_audio": "2247", + "render_anim": "28", + "attack_audios": "2555,0,0,0", + "name": "Staff of water" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "890", + "durability": null, + "name": "Staff of water", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1384" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A Magical staff.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "turn180_anim": "1206", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "grand_exchange_price": "879", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "1385", + "stand_turn_anim": "1209", + "bonuses": "1,-1,9,10,0,2,3,1,10,0,0,5,0,0,0", + "shop_price": "1500", + "durability": null, + "weight": "2.2", + "weapon_interface": "1", + "equip_audio": "2247", + "render_anim": "28", + "attack_audios": "2555,0,0,0", + "name": "Staff of earth" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "879", + "durability": null, + "name": "Staff of earth", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1386" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A Magical staff.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "turn180_anim": "1206", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "grand_exchange_price": "1330", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "1387", + "stand_turn_anim": "1209", + "bonuses": "3,-1,9,10,0,2,3,1,10,0,0,6,0,0,0", + "shop_price": "1500", + "durability": null, + "weight": "2.2", + "weapon_interface": "1", + "equip_audio": "2247", + "render_anim": "28", + "attack_audios": "2555,0,0,0", + "name": "Staff of fire" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1330", + "durability": null, + "name": "Staff of fire", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1388" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A Magical staff.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "turn180_anim": "1206", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "grand_exchange_price": "58", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "1389", + "stand_turn_anim": "1209", + "bonuses": "2,-1,10,10,0,2,3,1,10,0,0,7,0,0,0", + "shop_price": "200", + "durability": null, + "weight": "2.2", + "weapon_interface": "1", + "equip_audio": "2247", + "render_anim": "28", + "attack_audios": "2555,0,0,0", + "name": "Magic staff" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "58", + "durability": null, + "name": "Magic staff", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1390" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "It's a slightly magical stick.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "turn180_anim": "1206", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "grand_exchange_price": "7963", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "1391", + "stand_turn_anim": "1209", + "bonuses": "7,-1,25,12,0,2,3,1,12,0,0,32,0,0,0", + "requirements": "{0,30}-{6,30}", + "shop_price": "7000", + "durability": null, + "weight": "2.25", + "weapon_interface": "1", + "equip_audio": "2247", + "render_anim": "28", + "attack_audios": "2555,0,0,0", + "name": "Battlestaff" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "7963", + "durability": null, + "name": "Battlestaff", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1392" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "It's a slightly magical stick.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "turn180_anim": "1206", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "grand_exchange_price": "9113", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "1393", + "stand_turn_anim": "1209", + "bonuses": "7,-1,28,12,0,2,3,1,12,0,0,35,0,0,0", + "requirements": "{0,30}-{6,30}", + "shop_price": "19600", + "durability": null, + "weight": "2.25", + "weapon_interface": "1", + "equip_audio": "2247", + "render_anim": "28", + "attack_audios": "2555,0,0,0", + "name": "Fire battlestaff" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "9113", + "durability": null, + "name": "Fire battlestaff", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1394" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "It's a slightly magical stick.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "turn180_anim": "1206", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "grand_exchange_price": "9122", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "1395", + "stand_turn_anim": "1209", + "bonuses": "7,-1,28,12,0,2,3,1,12,0,0,35,0,0,0", + "requirements": "{0,30}-{6,30}", + "durability": null, + "weight": "2.2", + "weapon_interface": "1", + "equip_audio": "2247", + "render_anim": "28", + "attack_audios": "2555,0,0,0", + "name": "Water battlestaff" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "9122", + "durability": null, + "name": "Water battlestaff", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1396" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "It's a slightly magical stick.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "turn180_anim": "1206", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "grand_exchange_price": "8982", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "1397", + "stand_turn_anim": "1209", + "bonuses": "7,-1,28,12,0,2,3,1,12,0,0,35,0,0,0", + "requirements": "{0,30}-{6,30}", + "shop_price": "7000", + "durability": null, + "weight": "2.25", + "weapon_interface": "1", + "equip_audio": "2247", + "render_anim": "28", + "attack_audios": "2555,0,0,0", + "name": "Air battlestaff" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "8982", + "durability": null, + "name": "Air battlestaff", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1398" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "It's a slightly magical stick.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "turn180_anim": "1206", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "grand_exchange_price": "9041", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "1399", + "stand_turn_anim": "1209", + "bonuses": "7,-1,28,12,0,2,3,1,12,0,0,35,0,0,0", + "requirements": "{0,30}-{6,30}", + "shop_price": "1500", + "durability": null, + "weight": "2.2", + "weapon_interface": "1", + "equip_audio": "2247", + "render_anim": "28", + "attack_audios": "2555,0,0,0", + "name": "Earth battlestaff" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "9041", + "durability": null, + "name": "Earth battlestaff", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1400" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "It's a slightly magical stick.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "turn180_anim": "1206", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "grand_exchange_price": "25400", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "1401", + "stand_turn_anim": "1209", + "bonuses": "10,-1,40,14,0,2,3,1,14,0,0,50,0,0,0", + "requirements": "{0,40}-{6,40}", + "durability": null, + "weight": "2", + "weapon_interface": "1", + "equip_audio": "2247", + "render_anim": "28", + "attack_audios": "2555,0,0,0", + "name": "Mystic fire staff" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "25400", + "durability": null, + "name": "Mystic fire staff", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1402" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "It's a slightly magical stick.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "turn180_anim": "1206", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "grand_exchange_price": "24800", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "1403", + "stand_turn_anim": "1209", + "bonuses": "10,-1,40,14,0,2,3,1,14,0,0,50,0,0,0", + "requirements": "{0,40}-{6,40}", + "durability": null, + "weapon_interface": "1", + "equip_audio": "2247", + "render_anim": "28", + "attack_audios": "2555,0,0,0", + "name": "Mystic water staff" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "24800", + "durability": null, + "name": "Mystic water staff", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1404" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "It's a slightly magical stick.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "turn180_anim": "1206", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "grand_exchange_price": "25100", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "1405", + "stand_turn_anim": "1209", + "bonuses": "10,-1,40,14,0,2,3,1,14,0,0,50,0,0,0", + "requirements": "{0,40}-{6,40}", + "durability": null, + "weight": "2.2", + "weapon_interface": "1", + "equip_audio": "2247", + "render_anim": "28", + "attack_audios": "2555,0,0,0", + "name": "Mystic air staff" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "25100", + "durability": null, + "name": "Mystic air staff", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1406" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "It's a slightly magical stick.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "turn180_anim": "1206", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "grand_exchange_price": "25400", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "1407", + "stand_turn_anim": "1209", + "bonuses": "10,-1,40,14,0,2,3,1,14,0,0,50,0,0,0", + "requirements": "{0,40}-{6,40}", + "shop_price": "40000", + "durability": null, + "weight": "2.2", + "weapon_interface": "1", + "equip_audio": "2247", + "render_anim": "28", + "attack_audios": "2555,0,0,0", + "name": "Mystic earth staff" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "25400", + "durability": null, + "name": "Mystic earth staff", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1408" + }, + { + "turn90cw_anim": "1207", + "examine": "An ancient staff, formerly the property of Iban.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "weapon_interface": "1", + "turn180_anim": "1206", + "equip_audio": "2247", + "render_anim": "28", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "stand_anim": "813", + "attack_audios": "2555,0,0,0", + "name": "Iban's staff", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "1409", + "stand_turn_anim": "1209", + "bonuses": "10,-1,40,10,0,2,3,1,10,0,0,50,0,0,0" + }, + { + "examine": "An ancient staff, formerly the property of Iban.", + "attack_audios": "2555,0,0,0", + "durability": null, + "name": "Iban's staff", + "weight": "2.2", + "archery_ticket_price": "0", + "attack_speed": "5", + "id": "1410", + "bonuses": "10,-1,40,10,0,2,3,1,10,0,0,50,0,0,0" + }, + { + "durability": null, + "name": "Farmer's fork", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1412" + }, + { + "durability": null, + "name": "Halberd", + "archery_ticket_price": "0", + "attack_speed": "7", + "id": "1413" + }, + { + "durability": null, + "name": "Halberd", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1414" + }, + { + "attack_audios": "2504,0,0,0", + "durability": null, + "name": "Warhammer", + "archery_ticket_price": "0", + "attack_speed": "6", + "id": "1415" + }, + { + "durability": null, + "name": "Warhammer", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1416" + }, + { + "durability": null, + "name": "Javelin", + "archery_ticket_price": "0", + "attack_speed": "6", + "id": "1417" + }, + { + "durability": null, + "name": "Javelin", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1418" + }, + { + "turn90cw_anim": "821", + "examine": "It's a Scythe.", + "walk_anim": "819", + "durability": null, + "weight": "3", + "turn90ccw_anim": "822", + "attack_speed": "7", + "two_handed": "true", + "weapon_interface": "22", + "turn180_anim": "820", + "equip_audio": "2247", + "render_anim": "1383", + "defence_anim": "383", + "equipment_slot": "3", + "attack_anims": "440,440,438,382", + "stand_anim": "847", + "attack_audios": "2524,2524,2522,2524", + "name": "Scythe", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "1419", + "stand_turn_anim": "823", + "bonuses": "3,8,3,0,0,0,3,1,0,0,0,10,0,0,0" + }, + { + "shop_price": "80", + "ge_buy_limit": "100", + "examine": "A spiky mace.", + "durability": null, + "weight": "1.8", + "attack_speed": "5", + "weapon_interface": "8", + "equip_audio": "2246", + "defence_anim": "403", + "equipment_slot": "3", + "attack_anims": "401,401,400,401", + "grand_exchange_price": "7", + "attack_audios": "2508,2508,25092508", + "name": "Iron mace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1420", + "bonuses": "4,-2,9,0,0,0,0,0,0,0,0,7,1,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "7", + "durability": null, + "name": "Iron mace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1421" + }, + { + "shop_price": "18", + "ge_buy_limit": "100", + "examine": "A spiky mace.", + "durability": null, + "weight": "1.79", + "attack_speed": "5", + "weapon_interface": "8", + "equip_audio": "2246", + "defence_anim": "403", + "equipment_slot": "3", + "attack_anims": "401,401,400,401", + "grand_exchange_price": "12", + "attack_audios": "2508,2508,25092508", + "name": "Bronze mace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1422", + "bonuses": "1,-2,6,0,0,0,0,0,0,0,0,5,1,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "12", + "durability": null, + "name": "Bronze mace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1423" + }, + { + "requirements": "{0,5}", + "shop_price": "225", + "ge_buy_limit": "100", + "examine": "A spiky mace.", + "durability": null, + "weight": "1.79", + "attack_speed": "5", + "weapon_interface": "8", + "equip_audio": "2246", + "defence_anim": "403", + "equipment_slot": "3", + "attack_anims": "401,401,400,401", + "grand_exchange_price": "31", + "attack_audios": "2508,2508,25092508", + "name": "Steel mace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1424", + "bonuses": "7,-2,13,0,0,0,0,0,0,0,0,11,2,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "31", + "durability": null, + "name": "Steel mace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1425" + }, + { + "requirements": "{0,10}", + "ge_buy_limit": "100", + "examine": "A spiky mace.", + "durability": null, + "weight": "1.79", + "attack_speed": "5", + "weapon_interface": "8", + "equip_audio": "2246", + "defence_anim": "403", + "equipment_slot": "3", + "attack_anims": "401,401,400,401", + "grand_exchange_price": "954", + "attack_audios": "2508,2508,25092508", + "name": "Black mace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1426", + "bonuses": "8,-2,16,0,0,0,0,0,0,0,0,13,2,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "954", + "durability": null, + "name": "Black mace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1427" + }, + { + "requirements": "{0,20}", + "shop_price": "585", + "ge_buy_limit": "100", + "examine": "A spiky mace.", + "durability": null, + "weight": "1.5", + "attack_speed": "5", + "weapon_interface": "8", + "equip_audio": "2246", + "defence_anim": "403", + "equipment_slot": "3", + "attack_anims": "401,401,400,401", + "grand_exchange_price": "157", + "attack_audios": "2508,2508,25092508", + "name": "Mithril mace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1428", + "bonuses": "11,-2,18,0,0,0,0,0,0,0,0,16,3,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "157", + "durability": null, + "name": "Mithril mace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1429" + }, + { + "requirements": "{0,30}", + "shop_price": "1440", + "ge_buy_limit": "100", + "examine": "A spiky mace.", + "durability": null, + "weight": "2", + "attack_speed": "5", + "weapon_interface": "8", + "equip_audio": "2246", + "defence_anim": "403", + "equipment_slot": "3", + "attack_anims": "401,401,400,401", + "grand_exchange_price": "673", + "attack_audios": "2508,2508,25092508", + "name": "Adamant mace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1430", + "bonuses": "13,-2,25,0,0,0,0,0,0,0,0,23,3,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "673", + "durability": null, + "name": "Adamant mace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1431" + }, + { + "requirements": "{0,40}", + "shop_price": "14400", + "ge_buy_limit": "100", + "examine": "A spiky mace.", + "durability": null, + "weight": "1.79", + "attack_speed": "5", + "weapon_interface": "8", + "equip_audio": "2246", + "defence_anim": "403", + "equipment_slot": "3", + "attack_anims": "401,401,400,401", + "lendable": "true", + "grand_exchange_price": "8380", + "attack_audios": "2508,2508,25092508", + "name": "Rune mace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1432", + "bonuses": "20,-2,39,0,0,0,0,0,0,0,0,36,4,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "8380", + "durability": null, + "name": "Rune mace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1433" + }, + { + "requirements": "{0,60}", + "shop_price": "50000", + "ge_buy_limit": "10", + "examine": "A spiky mace.", + "has_special": "true", + "durability": null, + "weight": "1.8", + "attack_speed": "5", + "weapon_interface": "8", + "equip_audio": "2246", + "defence_anim": "403", + "equipment_slot": "3", + "attack_anims": "401,401,400,401", + "lendable": "true", + "grand_exchange_price": "29300", + "attack_audios": "2508,2508,25092508", + "name": "Dragon mace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1434", + "bonuses": "40,-2,60,0,0,0,0,0,0,0,0,55,5,0,0" + }, + { + "requirements": "{0,60}", + "ge_buy_limit": "10", + "grand_exchange_price": "29300", + "durability": null, + "name": "Dragon mace", + "tradeable": "true", + "weight": "1.8", + "archery_ticket_price": "0", + "id": "1435" + }, + { + "shop_price": "1", + "ge_buy_limit": "25000", + "examine": "An uncharged Rune Stone.", + "grand_exchange_price": "40", + "durability": null, + "name": "Rune essence", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1436" + }, + { + "ge_buy_limit": "25000", + "grand_exchange_price": "40", + "durability": null, + "name": "Rune essence", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1437" + }, + { + "shop_price": "50", + "ge_buy_limit": "500", + "examine": "A mysterious power emanates from the talisman...", + "grand_exchange_price": "404", + "durability": null, + "name": "Air talisman", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "1438" + }, + { + "ge_buy_limit": "500", + "grand_exchange_price": "404", + "durability": null, + "name": "Air talisman", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1439" + }, + { + "requirements": "{9,20}", + "shop_price": "50", + "ge_buy_limit": "500", + "examine": "A mysterious power emanates from the talisman...", + "grand_exchange_price": "785", + "durability": null, + "name": "Earth talisman", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1440" + }, + { + "ge_buy_limit": "500", + "grand_exchange_price": "785", + "durability": null, + "name": "Earth talisman", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1441" + }, + { + "requirements": "{14,20}", + "shop_price": "50", + "ge_buy_limit": "500", + "examine": "A mysterious power emanates from the talisman...", + "grand_exchange_price": "4140", + "durability": null, + "name": "Fire talisman", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1442" + }, + { + "ge_buy_limit": "500", + "grand_exchange_price": "4140", + "durability": null, + "name": "Fire talisman", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1443" + }, + { + "requirements": "{5,20}", + "shop_price": "50", + "ge_buy_limit": "500", + "examine": "A mysterious power emanates from the talisman...", + "grand_exchange_price": "7975", + "durability": null, + "name": "Water talisman", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1444" + }, + { + "ge_buy_limit": "500", + "grand_exchange_price": "7975", + "durability": null, + "name": "Water talisman", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1445" + }, + { + "requirements": "{20,20}", + "shop_price": "50", + "ge_buy_limit": "500", + "examine": "A mysterious power emanates from the talisman...", + "grand_exchange_price": "1373", + "durability": null, + "name": "Body talisman", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1446" + }, + { + "ge_buy_limit": "500", + "grand_exchange_price": "1373", + "durability": null, + "name": "Body talisman", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1447" + }, + { + "requirements": "{2,20}", + "shop_price": "50", + "ge_buy_limit": "500", + "examine": "A mysterious power emanates from the talisman...", + "grand_exchange_price": "285", + "durability": null, + "name": "Mind talisman", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1448" + }, + { + "ge_buy_limit": "500", + "grand_exchange_price": "285", + "durability": null, + "name": "Mind talisman", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1449" + }, + { + "requirements": "{20,77}", + "ge_buy_limit": "500", + "examine": "A mysterious power emanates from the talisman...", + "grand_exchange_price": "3178", + "durability": null, + "name": "Blood talisman", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1450" + }, + { + "ge_buy_limit": "500", + "grand_exchange_price": "3178", + "durability": null, + "name": "Blood talisman", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1451" + }, + { + "requirements": "{20,35}", + "shop_price": "125", + "ge_buy_limit": "500", + "examine": "A mysterious power emanates from the talisman...", + "grand_exchange_price": "605", + "durability": null, + "name": "Chaos talisman", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1452" + }, + { + "ge_buy_limit": "500", + "grand_exchange_price": "605", + "durability": null, + "name": "Chaos talisman", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1453" + }, + { + "requirements": "{20,27}", + "shop_price": "125", + "ge_buy_limit": "500", + "examine": "A mysterious power emanates from the talisman...", + "grand_exchange_price": "785", + "durability": null, + "name": "Cosmic talisman", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1454" + }, + { + "ge_buy_limit": "500", + "grand_exchange_price": "785", + "durability": null, + "name": "Cosmic talisman", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1455" + }, + { + "requirements": "{20,65}", + "ge_buy_limit": "500", + "examine": "A mysterious power emanates from the talisman...", + "grand_exchange_price": "2501", + "durability": null, + "name": "Death talisman", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1456" + }, + { + "ge_buy_limit": "500", + "grand_exchange_price": "2501", + "durability": null, + "name": "Death talisman", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1457" + }, + { + "requirements": "{20,54}", + "shop_price": "125", + "ge_buy_limit": "500", + "examine": "A mysterious power emanates from the talisman...", + "grand_exchange_price": "1219", + "durability": null, + "name": "Law talisman", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1458" + }, + { + "ge_buy_limit": "500", + "grand_exchange_price": "1219", + "durability": null, + "name": "Law talisman", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1459" + }, + { + "durability": null, + "name": "Soul talisman", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1461" + }, + { + "requirements": "{20,44}", + "shop_price": "125", + "ge_buy_limit": "500", + "examine": "A mysterious power emanates from the talisman...", + "grand_exchange_price": "1596", + "durability": null, + "name": "Nature talisman", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1462" + }, + { + "ge_buy_limit": "500", + "grand_exchange_price": "1596", + "durability": null, + "name": "Nature talisman", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1463" + }, + { + "ge_buy_limit": "5000", + "examine": "I can exchange this for equipment.", + "grand_exchange_price": "9", + "durability": null, + "name": "Archery ticket", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1464" + }, + { + "examine": "For use on daggers and projectiles.", + "grand_exchange_price": "36", + "durability": null, + "name": "Weapon poison", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1465" + }, + { + "examine": "Some damp wooden sticks.", + "durability": null, + "name": "Damp sticks", + "archery_ticket_price": "0", + "id": "1467" + }, + { + "examine": "Some dry wooden sticks.", + "durability": null, + "name": "Dry sticks", + "archery_ticket_price": "0", + "id": "1468" + }, + { + "examine": "Smashed glass.", + "durability": null, + "name": "Broken glass", + "archery_ticket_price": "0", + "id": "1469" + }, + { + "ge_buy_limit": "100", + "examine": "A small round red bead.", + "grand_exchange_price": "169", + "durability": null, + "name": "Red bead", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1470" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "169", + "durability": null, + "name": "Red bead", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1471" + }, + { + "ge_buy_limit": "100", + "examine": "A small round yellow bead.", + "grand_exchange_price": "249", + "durability": null, + "name": "Yellow bead", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1472" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "249", + "durability": null, + "name": "Yellow bead", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1473" + }, + { + "ge_buy_limit": "100", + "examine": "A small round black bead.", + "grand_exchange_price": "229", + "durability": null, + "name": "Black bead", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1474" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "229", + "durability": null, + "name": "Black bead", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1475" + }, + { + "ge_buy_limit": "100", + "examine": "A small round white bead.", + "grand_exchange_price": "1530", + "durability": null, + "name": "White bead", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1476" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1530", + "durability": null, + "name": "White bead", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1477" + }, + { + "shop_price": "1000", + "ge_buy_limit": "100", + "examine": "Wizard Mizgog sells these aim-enhancing amulets.", + "grand_exchange_price": "2870", + "durability": null, + "name": "Amulet of accuracy", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1478", + "bonuses": "4,4,4,4,4,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2870", + "durability": null, + "name": "Amulet of accuracy", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1479" + }, + { + "examine": "A magical sphere that glimmers within.", + "durability": null, + "name": "Orb of light", + "weight": "5", + "archery_ticket_price": "0", + "id": "1481" + }, + { + "examine": "A magical sphere that glimmers within.", + "durability": null, + "name": "Orb of light", + "weight": "5", + "archery_ticket_price": "0", + "id": "1482" + }, + { + "examine": "A magical sphere that glimmers within.", + "durability": null, + "name": "Orb of light", + "weight": "5", + "archery_ticket_price": "0", + "id": "1483" + }, + { + "examine": "A magical sphere that glimmers within.", + "durability": null, + "name": "Orb of light", + "weight": "5", + "archery_ticket_price": "0", + "id": "1484" + }, + { + "examine": "A damp, wet cloth.", + "durability": null, + "name": "Damp cloth", + "archery_ticket_price": "0", + "id": "1485" + }, + { + "examine": "A broken piece of railing.", + "durability": null, + "name": "Piece of railing", + "weight": "2", + "archery_ticket_price": "0", + "id": "1486" + }, + { + "examine": "This horn has restorative properties.", + "grand_exchange_price": "1159", + "durability": null, + "name": "Unicorn horn", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "1487" + }, + { + "examine": "A coat of arms of the Ardougne Paladins.", + "durability": null, + "name": "Paladin's badge", + "archery_ticket_price": "0", + "id": "1488" + }, + { + "examine": "A coat of arms of the Ardougne Paladins.", + "durability": null, + "name": "Paladin's badge", + "archery_ticket_price": "0", + "id": "1489" + }, + { + "examine": "A coat of arms of the Ardougne Paladins.", + "durability": null, + "name": "Paladin's badge", + "archery_ticket_price": "0", + "id": "1490" + }, + { + "examine": "On the ground: Curiosity has yet to kill this one...", + "durability": null, + "name": "Witch's cat", + "weight": "1.2", + "archery_ticket_price": "0", + "id": "1491" + }, + { + "examine": "A simple doll with Iban's likeness.", + "durability": null, + "name": "Doll of iban", + "weight": "1", + "archery_ticket_price": "0", + "id": "1492" + }, + { + "examine": "An account of the last times of someone.", + "durability": null, + "name": "Old journal", + "archery_ticket_price": "0", + "id": "1493" + }, + { + "examine": "The tale of Iban.", + "durability": null, + "name": "History of iban", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "1494" + }, + { + "shop_price": "5000", + "examine": "Strong dwarvish gloves.", + "durability": null, + "name": "Klank's gauntlets", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "1495", + "bonuses": "2,2,2,0,0,8,9,7,0,0,5,2,0,0,0", + "equipment_slot": "9" + }, + { + "examine": "I thought you only saw these in pairs?", + "durability": null, + "name": "Iban's dove", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "1496" + }, + { + "examine": "A mystical demonic amulet.", + "durability": null, + "name": "Amulet of othanian", + "archery_ticket_price": "0", + "id": "1497" + }, + { + "examine": "A mystical demonic amulet.", + "durability": null, + "name": "Amulet of doomion", + "archery_ticket_price": "0", + "id": "1498" + }, + { + "examine": "A mystical demonic amulet.", + "durability": null, + "name": "Amulet of holthion", + "archery_ticket_price": "0", + "id": "1499" + }, + { + "examine": "A strange dark liquid.", + "durability": null, + "name": "Iban's shadow", + "archery_ticket_price": "0", + "id": "1500", + "equip_audio": "" + }, + { + "examine": "Smells stronger than most spirits.", + "durability": null, + "name": "Dwarf brew", + "archery_ticket_price": "0", + "id": "1501" + }, + { + "examine": "The burnt remains of Iban.", + "durability": null, + "name": "Iban's ashes", + "weight": "0.056", + "archery_ticket_price": "0", + "id": "1502" + }, + { + "examine": "A search warrant for a house in West Ardougne.", + "durability": null, + "name": "Warrant", + "archery_ticket_price": "0", + "id": "1503" + }, + { + "examine": "It doesn't look very tasty.", + "durability": null, + "name": "Hangover cure", + "weight": "2", + "archery_ticket_price": "0", + "id": "1504" + }, + { + "examine": "Maybe I should read this...", + "durability": null, + "name": "A magic scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "1505" + }, + { + "remove_head": "true", + "examine": "Stops me from breathing nasty stuff!", + "durability": null, + "name": "Gas mask", + "weight": "0.25", + "archery_ticket_price": "0", + "id": "1506", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "examine": "Quite a small key.", + "durability": null, + "name": "A small key", + "archery_ticket_price": "0", + "id": "1507" + }, + { + "examine": "It seems to say \"hongorer lure\"...", + "durability": null, + "name": "A scruffy note", + "archery_ticket_price": "0", + "id": "1508" + }, + { + "examine": "Turnip growing for beginners.", + "durability": null, + "name": "Book", + "archery_ticket_price": "0", + "id": "1509" + }, + { + "examine": "A picture of a lady called Elena.", + "durability": null, + "name": "Picture", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "1510" + }, + { + "shop_price": "4", + "ge_buy_limit": "25000", + "examine": "A number of wooden logs.", + "grand_exchange_price": "120", + "durability": null, + "name": "Logs", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "1511" + }, + { + "ge_buy_limit": "25000", + "grand_exchange_price": "279", + "durability": null, + "name": "Logs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1512" + }, + { + "ge_buy_limit": "25000", + "examine": "Logs cut from a magic tree.", + "grand_exchange_price": "680", + "durability": null, + "name": "Magic logs", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "1513" + }, + { + "ge_buy_limit": "25000", + "grand_exchange_price": "1581", + "durability": null, + "name": "Magic logs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1514" + }, + { + "ge_buy_limit": "25000", + "examine": "Logs cut from a yew tree.", + "grand_exchange_price": "320", + "durability": null, + "name": "Yew logs", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "1515" + }, + { + "ge_buy_limit": "25000", + "grand_exchange_price": "532", + "durability": null, + "name": "Yew logs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1516" + }, + { + "ge_buy_limit": "25000", + "examine": "Logs cut from a maple tree.", + "grand_exchange_price": "160", + "durability": null, + "name": "Maple logs", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "1517" + }, + { + "ge_buy_limit": "25000", + "grand_exchange_price": "20", + "durability": null, + "name": "Maple logs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1518" + }, + { + "ge_buy_limit": "25000", + "examine": "Logs cut from a willow tree.", + "grand_exchange_price": "80", + "durability": null, + "name": "Willow logs", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "1519" + }, + { + "ge_buy_limit": "25000", + "grand_exchange_price": "11", + "durability": null, + "name": "Willow logs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1520" + }, + { + "ge_buy_limit": "25000", + "examine": "Logs cut from an Oak Tree.", + "grand_exchange_price": "140", + "durability": null, + "name": "Oak logs", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "1521" + }, + { + "ge_buy_limit": "25000", + "grand_exchange_price": "153", + "durability": null, + "name": "Oak logs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1522" + }, + { + "shop_price": "20", + "ge_buy_limit": "100", + "examine": "For picking tough locks.", + "grand_exchange_price": "1311", + "durability": null, + "name": "Lockpick", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1523" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1311", + "durability": null, + "name": "Lockpick", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1524" + }, + { + "examine": "I need to clean this herb before I can use it.", + "durability": null, + "name": "Grimy snake weed", + "archery_ticket_price": "0", + "id": "1525" + }, + { + "examine": "A fresh herb.", + "durability": null, + "name": "Clean snake weed", + "archery_ticket_price": "0", + "id": "1526" + }, + { + "examine": "I need to clean this herb before I can use it.", + "durability": null, + "name": "Grimy ardrigal", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "1527" + }, + { + "examine": "A fresh herb.", + "durability": null, + "name": "Clean ardrigal", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "1528" + }, + { + "examine": "I need to clean this herb before I can use it.", + "durability": null, + "name": "Grimy sito foil", + "archery_ticket_price": "0", + "id": "1529" + }, + { + "examine": "A fresh herb.", + "durability": null, + "name": "Clean sito foil", + "archery_ticket_price": "0", + "id": "1530" + }, + { + "examine": "I need to clean this herb before I can use it.", + "durability": null, + "name": "Grimy volencia moss", + "archery_ticket_price": "0", + "id": "1531" + }, + { + "examine": "A fresh herb.", + "durability": null, + "name": "Clean volencia moss", + "archery_ticket_price": "0", + "id": "1532" + }, + { + "examine": "I need to clean this herb before I can use it.", + "durability": null, + "name": "Grimy rogue's purse", + "archery_ticket_price": "0", + "id": "1533" + }, + { + "examine": "A fresh herb.", + "durability": null, + "name": "Clean rogue's purse", + "archery_ticket_price": "0", + "id": "1534" + }, + { + "examine": "A piece of map.", + "durability": null, + "name": "Map part", + "archery_ticket_price": "0", + "id": "1535" + }, + { + "examine": "A piece of map.", + "durability": null, + "name": "Map part", + "archery_ticket_price": "0", + "id": "1536" + }, + { + "examine": "A piece of map.", + "durability": null, + "name": "Map part", + "archery_ticket_price": "0", + "id": "1537" + }, + { + "examine": "A map of the route to Crandor.", + "durability": null, + "name": "Crandor map", + "archery_ticket_price": "0", + "id": "1538" + }, + { + "shop_price": "52", + "ge_buy_limit": "10000", + "examine": "Keeps things in place fairly permanently.", + "grand_exchange_price": "59", + "durability": null, + "name": "Steel nails", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1539" + }, + { + "ge_buy_limit": "100", + "examine": "This provides partial protection from dragon-breath attacks.", + "grand_exchange_price": "637", + "durability": null, + "name": "Anti-dragon shield", + "tradeable": "true", + "weight": "5.4", + "archery_ticket_price": "0", + "id": "1540", + "bonuses": "0,0,0,0,0,7,9,8,2,8,0,0,0,0,0", + "equipment_slot": "5" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "637", + "durability": null, + "name": "Anti-dragon shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1541" + }, + { + "shop_price": "1", + "examine": "A key to Melzar's Maze.", + "durability": null, + "name": "Maze key", + "archery_ticket_price": "0", + "id": "1542" + }, + { + "destroy_message": "You can get another from Dr Harlow in the Blue Moon Inn of Varrock.", + "examine": "A very pointy stick.", + "durability": null, + "name": "Stake", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "1549", + "equipment_slot": "5" + }, + { + "ge_buy_limit": "100", + "examine": "Deters vampires.", + "grand_exchange_price": "20", + "durability": null, + "name": "Garlic", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1550" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "20", + "durability": null, + "name": "Garlic", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1551" + }, + { + "examine": "Sardine flavoured with doogle leaves.", + "durability": null, + "name": "Doogle sardine", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "1552" + }, + { + "examine": "This kitten seems to like you.", + "durability": null, + "name": "Pet kitten", + "archery_ticket_price": "0", + "id": "1555" + }, + { + "examine": "This kitten seems to like you.", + "durability": null, + "name": "Pet kitten", + "archery_ticket_price": "0", + "id": "1556" + }, + { + "examine": "This kitten seems to like you.", + "durability": null, + "name": "Pet kitten", + "archery_ticket_price": "0", + "id": "1557" + }, + { + "examine": "This kitten seems to like you.", + "durability": null, + "name": "Pet kitten", + "archery_ticket_price": "0", + "id": "1558" + }, + { + "examine": "This kitten seems to like you.", + "durability": null, + "name": "Pet kitten", + "archery_ticket_price": "0", + "id": "1559" + }, + { + "examine": "This kitten seems to like you.", + "durability": null, + "name": "Pet kitten", + "archery_ticket_price": "0", + "id": "1560" + }, + { + "examine": "This cat definitely likes you.", + "durability": null, + "name": "Pet cat", + "archery_ticket_price": "0", + "id": "1561" + }, + { + "examine": "This cat definitely likes you.", + "durability": null, + "name": "Pet cat", + "archery_ticket_price": "0", + "id": "1562" + }, + { + "examine": "This cat definitely likes you.", + "durability": null, + "name": "Pet cat", + "archery_ticket_price": "0", + "id": "1563" + }, + { + "examine": "This cat definitely likes you.", + "durability": null, + "name": "Pet cat", + "archery_ticket_price": "0", + "id": "1564" + }, + { + "examine": "This cat definitely likes you.", + "durability": null, + "name": "Pet cat", + "archery_ticket_price": "0", + "id": "1565" + }, + { + "examine": "This cat definitely likes you.", + "durability": null, + "name": "Pet cat", + "archery_ticket_price": "0", + "id": "1566" + }, + { + "examine": "This cat is so well fed it can hardly move.", + "durability": null, + "name": "Overgrown cat", + "archery_ticket_price": "0", + "id": "1567" + }, + { + "examine": "This cat is so well fed it can hardly move.", + "durability": null, + "name": "Overgrown cat", + "archery_ticket_price": "0", + "id": "1568" + }, + { + "examine": "This cat is so well fed it can hardly move.", + "durability": null, + "name": "Overgrown cat", + "archery_ticket_price": "0", + "id": "1569" + }, + { + "examine": "This cat is so well fed it can hardly move.", + "durability": null, + "name": "Overgrown cat", + "archery_ticket_price": "0", + "id": "1570" + }, + { + "examine": "This cat is so well fed it can hardly move.", + "durability": null, + "name": "Overgrown cat", + "archery_ticket_price": "0", + "id": "1571" + }, + { + "examine": "This cat is so well fed it can hardly move.", + "durability": null, + "name": "Overgrown cat", + "archery_ticket_price": "0", + "id": "1572" + }, + { + "examine": "A tasty herb good for seasoning.", + "durability": null, + "name": "Doogle leaves", + "archery_ticket_price": "0", + "id": "1573" + }, + { + "examine": "For feline training expertise.", + "durability": null, + "name": "Cat training medal", + "archery_ticket_price": "0", + "id": "1575", + "equipment_slot": "2" + }, + { + "examine": "Candlestick used during Heroes' Quest.", + "durability": null, + "name": "Pete's candlestick", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1577" + }, + { + "durability": null, + "name": "Pete's candlestick", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1578" + }, + { + "examine": "This denotes a Master Thief.", + "durability": null, + "name": "Thieves' armband", + "archery_ticket_price": "0", + "id": "1579" + }, + { + "examine": "These will keep my hands cold!", + "durability": null, + "name": "Ice gloves", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "1580", + "bonuses": "0,0,0,0,0,0,3,4,0,2,2,0,0,0,0", + "equipment_slot": "9" + }, + { + "examine": "Yuck.", + "durability": null, + "name": "Blamish snail slime", + "weight": "1", + "archery_ticket_price": "0", + "id": "1581" + }, + { + "examine": "Made from the finest snail slime.", + "durability": null, + "name": "Blamish oil", + "archery_ticket_price": "0", + "id": "1582" + }, + { + "examine": "Firebird feather.", + "durability": null, + "name": "Fire feather", + "archery_ticket_price": "0", + "id": "1583" + }, + { + "examine": "Apparently my name is Hartigen.", + "durability": null, + "name": "Id papers", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "1584" + }, + { + "examine": "Useful for catching lava eels.", + "durability": null, + "name": "Oily fishing rod", + "weight": "1", + "archery_ticket_price": "0", + "id": "1585" + }, + { + "examine": "This is of use in completing Heroes' Quest. (Heroes' Quest)", + "durability": null, + "name": "Miscellaneous key", + "tradeable": "true", + "weight": "0.01", + "archery_ticket_price": "0", + "id": "1586" + }, + { + "durability": null, + "name": "Miscellaneous key", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1587" + }, + { + "examine": "The key I got from Grip. (Heroes' Quest)", + "durability": null, + "name": "Grips' key ring", + "archery_ticket_price": "0", + "id": "1588" + }, + { + "shop_price": "1", + "examine": "I wonder what this unlocks. (Heroes' Quest)", + "durability": null, + "name": "Dusty key", + "archery_ticket_price": "0", + "id": "1590" + }, + { + "examine": "Key to a cell. (Heroes' Quest)", + "durability": null, + "name": "Jail key", + "archery_ticket_price": "0", + "id": "1591" + }, + { + "shop_price": "5", + "ge_buy_limit": "100", + "examine": "Used to make gold rings.", + "grand_exchange_price": "316", + "durability": null, + "name": "Ring mould", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "1592" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "316", + "durability": null, + "name": "Ring mould", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1593" + }, + { + "examine": "Used to make unholy symbols.", + "durability": null, + "name": "Unholy mould", + "archery_ticket_price": "0", + "id": "1594" + }, + { + "shop_price": "5", + "ge_buy_limit": "100", + "examine": "Used to make gold amulets.", + "grand_exchange_price": "288", + "durability": null, + "name": "Amulet mould", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "1595" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "288", + "durability": null, + "name": "Amulet mould", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1596" + }, + { + "shop_price": "5", + "ge_buy_limit": "100", + "examine": "Used to make gold necklaces.", + "grand_exchange_price": "269", + "durability": null, + "name": "Necklace mould", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "1597" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "269", + "durability": null, + "name": "Necklace mould", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1598" + }, + { + "shop_price": "5", + "ge_buy_limit": "100", + "examine": "Used to make holy symbols of Saradomin.", + "grand_exchange_price": "504", + "durability": null, + "name": "Holy mould", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "1599" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "504", + "durability": null, + "name": "Holy mould", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1600" + }, + { + "ge_buy_limit": "500", + "examine": "This looks valuable.", + "grand_exchange_price": "14800", + "durability": null, + "name": "Diamond", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1601" + }, + { + "ge_buy_limit": "500", + "grand_exchange_price": "14800", + "durability": null, + "name": "Diamond", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1602" + }, + { + "shop_price": "400", + "ge_buy_limit": "1000", + "examine": "This looks valuable.", + "grand_exchange_price": "1598", + "durability": null, + "name": "Ruby", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1603" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1598", + "durability": null, + "name": "Ruby", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1604" + }, + { + "shop_price": "350", + "ge_buy_limit": "1000", + "examine": "This looks valuable.", + "grand_exchange_price": "853", + "durability": null, + "name": "Emerald", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1605" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "853", + "durability": null, + "name": "Emerald", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1606" + }, + { + "shop_price": "175", + "ge_buy_limit": "1000", + "examine": "This looks valuable.", + "grand_exchange_price": "520", + "durability": null, + "name": "Sapphire", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1607" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "520", + "durability": null, + "name": "Sapphire", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1608" + }, + { + "ge_buy_limit": "1000", + "shop_price": "100", + "examine": "A semi precious stone.", + "grand_exchange_price": "44", + "durability": null, + "name": "Opal", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1609" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "41", + "durability": null, + "name": "Opal", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1610" + }, + { + "ge_buy_limit": "1000", + "shop_price": "150", + "grand_exchange_price": "84", + "examine": "A semi precious stone.", + "durability": null, + "name": "Jade", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1611" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "83", + "durability": null, + "name": "Jade", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1612" + }, + { + "ge_buy_limit": "1000", + "shop_price": "200", + "examine": "A semi precious stone.", + "grand_exchange_price": "120", + "durability": null, + "name": "Red topaz", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "1613" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "103", + "durability": null, + "name": "Red topaz", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1614" + }, + { + "shop_price": "75000", + "ge_buy_limit": "100", + "examine": "This looks valuable.", + "grand_exchange_price": "27400", + "durability": null, + "name": "Dragonstone", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "1615" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "27400", + "durability": null, + "name": "Dragonstone", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1616" + }, + { + "ge_buy_limit": "500", + "examine": "An uncut diamond.", + "grand_exchange_price": "2160", + "tokkul_price": "300", + "durability": null, + "name": "Uncut diamond", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1617" + }, + { + "ge_buy_limit": "500", + "grand_exchange_price": "20000", + "durability": null, + "name": "Uncut diamond", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1618" + }, + { + "ge_buy_limit": "1000", + "examine": "An uncut ruby.", + "grand_exchange_price": "1140", + "tokkul_price": "150", + "durability": null, + "name": "Uncut ruby", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1619" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "4970", + "durability": null, + "name": "Uncut ruby", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1620" + }, + { + "shop_price": "50", + "ge_buy_limit": "1000", + "examine": "An uncut emerald.", + "grand_exchange_price": "580", + "tokkul_price": "75", + "durability": null, + "name": "Uncut emerald", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1621" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "2621", + "durability": null, + "name": "Uncut emerald", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1622" + }, + { + "shop_price": "25", + "ge_buy_limit": "1000", + "examine": "An uncut sapphire.", + "grand_exchange_price": "420", + "tokkul_price": "37", + "durability": null, + "name": "Uncut sapphire", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1623" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1851", + "durability": null, + "name": "Uncut sapphire", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1624" + }, + { + "ge_buy_limit": "1000", + "examine": "An uncut opal.", + "grand_exchange_price": "65", + "durability": null, + "name": "Uncut opal", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1625" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "65", + "durability": null, + "name": "Uncut opal", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1626" + }, + { + "ge_buy_limit": "1000", + "examine": "An uncut jade.", + "grand_exchange_price": "138", + "durability": null, + "name": "Uncut jade", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1627" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "138", + "durability": null, + "name": "Uncut jade", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1628" + }, + { + "ge_buy_limit": "1000", + "examine": "An uncut red topaz.", + "grand_exchange_price": "279", + "durability": null, + "name": "Uncut red topaz", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "1629" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "279", + "durability": null, + "name": "Uncut red topaz", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1630" + }, + { + "shop_price": "75000", + "ge_buy_limit": "100", + "examine": "An uncut dragonstone.", + "grand_exchange_price": "31700", + "tokkul_price": "1500", + "durability": null, + "name": "Uncut dragonstone", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "1631" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "31700", + "durability": null, + "name": "Uncut dragonstone", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1632" + }, + { + "examine": "This gem is crushed and broken.", + "durability": null, + "name": "Crushed gem", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1633" + }, + { + "durability": null, + "name": "Crushed gem", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1634" + }, + { + "ge_buy_limit": "5000", + "examine": "A valuable ring.", + "grand_exchange_price": "165", + "durability": null, + "name": "Gold ring", + "tradeable": "true", + "destroy": "false", + "archery_ticket_price": "0", + "id": "1635", + "equipment_slot": "12" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "165", + "durability": null, + "name": "Gold ring", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1636" + }, + { + "ge_buy_limit": "5000", + "examine": "A valuable ring.", + "grand_exchange_price": "561", + "durability": null, + "name": "Sapphire ring", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1637", + "equipment_slot": "12" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "561", + "durability": null, + "name": "Sapphire ring", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1638" + }, + { + "ge_buy_limit": "5000", + "examine": "A valuable ring.", + "grand_exchange_price": "884", + "durability": null, + "name": "Emerald ring", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1639", + "equipment_slot": "12" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "884", + "durability": null, + "name": "Emerald ring", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1640" + }, + { + "shop_price": "2025", + "ge_buy_limit": "5000", + "examine": "A valuable ring.", + "grand_exchange_price": "1110", + "durability": null, + "name": "Ruby ring", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1641", + "equipment_slot": "12" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "1110", + "durability": null, + "name": "Ruby ring", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1642" + }, + { + "shop_price": "3172", + "ge_buy_limit": "5000", + "examine": "A valuable ring.", + "grand_exchange_price": "4416", + "durability": null, + "name": "Diamond ring", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1643", + "equipment_slot": "12" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "4416", + "durability": null, + "name": "Diamond ring", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1644" + }, + { + "shop_price": "7750", + "ge_buy_limit": "100", + "examine": "A valuable ring.", + "grand_exchange_price": "26700", + "durability": null, + "name": "Dragonstone ring", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1645", + "equipment_slot": "12" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "26700", + "durability": null, + "name": "Dragonstone ring", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1646" + }, + { + "examine": "A valuable ring.", + "grand_exchange_price": "547", + "durability": null, + "name": "Sapphire ring", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1649" + }, + { + "examine": "A valuable ring.", + "grand_exchange_price": "993", + "durability": null, + "name": "Emerald ring", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1650" + }, + { + "shop_price": "2025", + "examine": "A valuable ring.", + "grand_exchange_price": "1125", + "durability": null, + "name": "Ruby ring", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1651" + }, + { + "shop_price": "3172", + "examine": "A valuable ring.", + "grand_exchange_price": "3622", + "durability": null, + "name": "Diamond ring", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1652" + }, + { + "shop_price": "7750", + "examine": "A valuable ring.", + "grand_exchange_price": "19606", + "durability": null, + "name": "Dragonstone ring", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1653" + }, + { + "shop_price": "450", + "ge_buy_limit": "5000", + "examine": "I wonder if this is valuable.", + "grand_exchange_price": "185", + "durability": null, + "name": "Gold necklace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1654", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "185", + "durability": null, + "name": "Gold necklace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1655" + }, + { + "shop_price": "945", + "ge_buy_limit": "5000", + "examine": "I wonder if this is valuable.", + "grand_exchange_price": "534", + "durability": null, + "name": "Sapphire necklace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1656", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "534", + "durability": null, + "name": "Sapphire necklace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1657" + }, + { + "shop_price": "1425", + "ge_buy_limit": "5000", + "examine": "I wonder if this is valuable.", + "grand_exchange_price": "781", + "durability": null, + "name": "Emerald necklace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1658", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "781", + "durability": null, + "name": "Emerald necklace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1659" + }, + { + "shop_price": "870", + "ge_buy_limit": "5000", + "examine": "I wonder if this is valuable.", + "grand_exchange_price": "1276", + "durability": null, + "name": "Ruby necklace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1660", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "1276", + "durability": null, + "name": "Ruby necklace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1661" + }, + { + "shop_price": "3307", + "ge_buy_limit": "5000", + "examine": "I wonder if this is valuable.", + "grand_exchange_price": "14300", + "durability": null, + "name": "Diamond necklace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1662", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "14300", + "durability": null, + "name": "Diamond necklace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1663" + }, + { + "ge_buy_limit": "100", + "examine": "I wonder if this is valuable.", + "grand_exchange_price": "26000", + "durability": null, + "name": "Dragon necklace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1664", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "26000", + "durability": null, + "name": "Dragon necklace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1665" + }, + { + "shop_price": "945", + "examine": "I wonder if this is valuable.", + "grand_exchange_price": "532", + "durability": null, + "name": "Sapphire necklace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1668" + }, + { + "shop_price": "1425", + "examine": "I wonder if this is valuable.", + "grand_exchange_price": "741", + "durability": null, + "name": "Emerald necklace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1669" + }, + { + "shop_price": "870", + "examine": "I wonder if this is valuable.", + "grand_exchange_price": "1194", + "durability": null, + "name": "Ruby necklace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1670" + }, + { + "shop_price": "3307", + "examine": "I wonder if this is valuable.", + "grand_exchange_price": "9795", + "durability": null, + "name": "Diamond necklace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1671" + }, + { + "examine": "I wonder if this is valuable.", + "grand_exchange_price": "23010", + "durability": null, + "name": "Dragon necklace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1672" + }, + { + "shop_price": "350", + "ge_buy_limit": "5000", + "examine": "A plain gold amulet.", + "grand_exchange_price": "172", + "durability": null, + "name": "Gold amulet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1673" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "172", + "durability": null, + "name": "Gold amulet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1674" + }, + { + "shop_price": "810", + "ge_buy_limit": "5000", + "examine": "I wonder if I can get this enchanted.", + "grand_exchange_price": "473", + "durability": null, + "name": "Sapphire amulet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1675" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "473", + "durability": null, + "name": "Sapphire amulet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1676" + }, + { + "shop_price": "1147", + "ge_buy_limit": "5000", + "examine": "I wonder if I can get this enchanted.", + "grand_exchange_price": "695", + "durability": null, + "name": "Emerald amulet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1677" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "695", + "durability": null, + "name": "Emerald amulet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1678" + }, + { + "shop_price": "2025", + "ge_buy_limit": "5000", + "examine": "I wonder if I can get this enchanted.", + "grand_exchange_price": "1268", + "durability": null, + "name": "Ruby amulet", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "id": "1679" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "1268", + "durability": null, + "name": "Ruby amulet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1680" + }, + { + "shop_price": "3307", + "ge_buy_limit": "5000", + "examine": "I wonder if I can get this enchanted.", + "grand_exchange_price": "3359", + "durability": null, + "name": "Diamond amulet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1681" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "3359", + "durability": null, + "name": "Diamond amulet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1682" + }, + { + "ge_buy_limit": "100", + "examine": "I wonder if I can get this enchanted.", + "grand_exchange_price": "26900", + "durability": null, + "name": "Dragonstone ammy", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1683" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "26900", + "durability": null, + "name": "Dragonstone ammy", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1684" + }, + { + "shop_price": "810", + "examine": "I wonder if I can get this enchanted.", + "grand_exchange_price": "417", + "durability": null, + "name": "Sapphire amulet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1687" + }, + { + "shop_price": "1147", + "examine": "I wonder if I can get this enchanted.", + "grand_exchange_price": "648", + "durability": null, + "name": "Emerald amulet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1688" + }, + { + "shop_price": "2025", + "examine": "I wonder if I can get this enchanted.", + "grand_exchange_price": "1098", + "durability": null, + "name": "Ruby amulet", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "id": "1689" + }, + { + "shop_price": "3307", + "examine": "I wonder if I can get this enchanted.", + "grand_exchange_price": "1993", + "durability": null, + "name": "Diamond amulet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1690" + }, + { + "examine": "I wonder if I can get this enchanted.", + "grand_exchange_price": "18436", + "durability": null, + "name": "Dragonstone ammy", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1691" + }, + { + "shop_price": "350", + "ge_buy_limit": "5000", + "examine": "A plain gold amulet.", + "grand_exchange_price": "137", + "durability": null, + "name": "Gold amulet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1692", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "137", + "durability": null, + "name": "Gold amulet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1693" + }, + { + "shop_price": "810", + "ge_buy_limit": "5000", + "examine": "I wonder if I can get this enchanted.", + "grand_exchange_price": "435", + "durability": null, + "name": "Sapphire amulet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1694", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "435", + "durability": null, + "name": "Sapphire amulet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1695" + }, + { + "shop_price": "1147", + "ge_buy_limit": "5000", + "examine": "I wonder if I can get this enchanted.", + "grand_exchange_price": "659", + "durability": null, + "name": "Emerald amulet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1696", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "659", + "durability": null, + "name": "Emerald amulet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1697" + }, + { + "shop_price": "2025", + "ge_buy_limit": "5000", + "examine": "I wonder if I can get this enchanted.", + "grand_exchange_price": "1115", + "durability": null, + "name": "Ruby amulet", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "id": "1698", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "1115", + "durability": null, + "name": "Ruby amulet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1699" + }, + { + "shop_price": "3307", + "ge_buy_limit": "5000", + "examine": "I wonder if I can get this enchanted.", + "grand_exchange_price": "2706", + "durability": null, + "name": "Diamond amulet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1700", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "2706", + "durability": null, + "name": "Diamond amulet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1701" + }, + { + "ge_buy_limit": "100", + "examine": "I wonder if I can get this enchanted.", + "grand_exchange_price": "27100", + "durability": null, + "name": "Dragonstone ammy", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1702", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "27100", + "durability": null, + "name": "Dragonstone ammy", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1703" + }, + { + "ge_buy_limit": "100", + "examine": "A very powerful dragonstone amulet.", + "grand_exchange_price": "28000", + "durability": null, + "name": "Amulet of glory", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1704", + "bonuses": "10,10,10,10,10,3,3,3,3,3,3,6,3,0,0", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "28000", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Amulet of glory", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1705" + }, + { + "examine": "A dragonstone amulet with 1 magic charge.", + "grand_exchange_price": "1", + "durability": null, + "name": "Amulet of glory(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1706", + "bonuses": "10,10,10,10,10,3,3,3,3,3,3,6,3,0,0", + "equipment_slot": "2" + }, + { + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Amulet of glory(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1707" + }, + { + "examine": "A dragonstone amulet with 2 magic charges.", + "grand_exchange_price": "1", + "durability": null, + "name": "Amulet of glory(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1708", + "bonuses": "10,10,10,10,10,3,3,3,3,3,3,6,3,0,0", + "equipment_slot": "2" + }, + { + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Amulet of glory(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1709" + }, + { + "examine": "A dragonstone amulet with 3 magic charges.", + "grand_exchange_price": "1", + "durability": null, + "name": "Amulet of glory(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1710", + "bonuses": "10,10,10,10,10,3,3,3,3,3,3,6,3,0,0", + "equipment_slot": "2" + }, + { + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Amulet of glory(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1711" + }, + { + "ge_buy_limit": "100", + "examine": "A dragonstone amulet with 4 magic charges.", + "grand_exchange_price": "29300", + "durability": null, + "name": "Amulet of glory(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1712", + "bonuses": "10,10,10,10,10,3,3,3,3,3,3,6,3,0,0", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "29300", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Amulet of glory(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1713" + }, + { + "shop_price": "200", + "ge_buy_limit": "5000", + "examine": "It needs a string so I can wear it.", + "grand_exchange_price": "83", + "durability": null, + "name": "Unstrung symbol", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1714" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "83", + "durability": null, + "name": "Unstrung symbol", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1715" + }, + { + "shop_price": "120", + "ge_buy_limit": "5000", + "examine": "A symbol of Saradomin.", + "grand_exchange_price": "29", + "durability": null, + "name": "Unblessed symbol", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1716", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "29", + "durability": null, + "name": "Unblessed symbol", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1717" + }, + { + "shop_price": "300", + "ge_buy_limit": "5000", + "examine": "A blessed holy symbol of Saradomin.", + "grand_exchange_price": "88", + "durability": null, + "name": "Holy symbol", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1718", + "bonuses": "0,0,0,0,0,2,2,2,2,2,3,0,8,0,0", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "88", + "durability": null, + "name": "Holy symbol", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1719" + }, + { + "ge_buy_limit": "5000", + "examine": "It needs a string so I can wear it.", + "grand_exchange_price": "178", + "durability": null, + "name": "Unstrung emblem", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1720" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "178", + "durability": null, + "name": "Unstrung emblem", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1721" + }, + { + "shop_price": "120", + "ge_buy_limit": "5000", + "examine": "An unholy symbol of Zamorak.", + "grand_exchange_price": "24", + "durability": null, + "name": "Unpowered symbol", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1722", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "24", + "durability": null, + "name": "Unpowered symbol", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1723" + }, + { + "shop_price": "135", + "ge_buy_limit": "5000", + "examine": "An unholy symbol of Zamorak.", + "grand_exchange_price": "57", + "durability": null, + "name": "Unholy symbol", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1724", + "bonuses": "2,2,2,2,2,0,0,0,0,0,0,0,8,0,0", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "5000", + "examine": "An enchanted ruby amulet.", + "grand_exchange_price": "1247", + "durability": null, + "name": "Amulet of strength", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1725", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,10,0,0,0", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "1247", + "durability": null, + "name": "Amulet of strength", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1726" + }, + { + "shop_price": "900", + "ge_buy_limit": "5000", + "examine": "An enchanted sapphire amulet of magic.", + "grand_exchange_price": "519", + "durability": null, + "name": "Amulet of magic", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1727", + "bonuses": "0,0,0,10,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "519", + "durability": null, + "name": "Amulet of magic", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1728" + }, + { + "shop_price": "1275", + "ge_buy_limit": "5000", + "examine": "An enchanted emerald amulet of protection.", + "grand_exchange_price": "721", + "durability": null, + "name": "Amulet of defence", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1729", + "bonuses": "0,0,0,0,0,7,7,7,7,7,7,0,0,0,0", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "721", + "durability": null, + "name": "Amulet of defence", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1730" + }, + { + "shop_price": "3525", + "ge_buy_limit": "5000", + "examine": "An enchanted diamond amulet of power.", + "grand_exchange_price": "2573", + "durability": null, + "name": "Amulet of power", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1731", + "bonuses": "6,6,6,6,6,6,6,6,6,6,6,6,1,0,0", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "2573", + "durability": null, + "name": "Amulet of power", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1732" + }, + { + "shop_price": "1", + "ge_buy_limit": "5000", + "examine": "Used with a thread to make clothes.", + "grand_exchange_price": "5", + "durability": null, + "name": "Needle", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1733" + }, + { + "shop_price": "4", + "ge_buy_limit": "10000", + "examine": "Use with a needle to make clothes.", + "grand_exchange_price": "7", + "durability": null, + "name": "Thread", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1734" + }, + { + "shop_price": "1", + "ge_buy_limit": "100", + "examine": "For shearing sheep.", + "grand_exchange_price": "76", + "durability": null, + "name": "Shears", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "1735" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "76", + "durability": null, + "name": "Shears", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1736" + }, + { + "ge_buy_limit": "5000", + "examine": "I think this came from a sheep.", + "grand_exchange_price": "160", + "durability": null, + "name": "Wool", + "tradeable": "true", + "weight": "0.14", + "archery_ticket_price": "0", + "id": "1737" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "160", + "durability": null, + "name": "Wool", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1738" + }, + { + "ge_buy_limit": "10000", + "examine": "I should take this to the tannery.", + "grand_exchange_price": "140", + "durability": null, + "name": "Cowhide", + "tradeable": "true", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "1739" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "516", + "durability": null, + "name": "Cowhide", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1740" + }, + { + "ge_buy_limit": "10000", + "examine": "It's a piece of leather.", + "grand_exchange_price": "638", + "durability": null, + "name": "Leather", + "tradeable": "true", + "weight": "2.25", + "archery_ticket_price": "0", + "id": "1741" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "638", + "durability": null, + "name": "Leather", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1742" + }, + { + "ge_buy_limit": "10000", + "examine": "It's a piece of hard leather.", + "grand_exchange_price": "640", + "durability": null, + "name": "Hard leather", + "tradeable": "true", + "weight": "3.1", + "archery_ticket_price": "0", + "id": "1743" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "640", + "durability": null, + "name": "Hard leather", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1744" + }, + { + "ge_buy_limit": "10000", + "examine": "It's a piece of prepared green dragon hide.", + "grand_exchange_price": "2237", + "durability": null, + "name": "Green d-leather", + "tradeable": "true", + "weight": "3.1", + "archery_ticket_price": "0", + "id": "1745" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "2237", + "durability": null, + "name": "Green d-leather", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1746" + }, + { + "ge_buy_limit": "10000", + "examine": "The scaly rough hide from a Black Dragon.", + "grand_exchange_price": "5802", + "durability": null, + "name": "Black dragonhide", + "tradeable": "true", + "weight": "3.1", + "archery_ticket_price": "0", + "id": "1747" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "5802", + "durability": null, + "name": "Black dragonhide", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1748" + }, + { + "ge_buy_limit": "10000", + "examine": "The scaly rough hide from a red dragon.", + "grand_exchange_price": "3539", + "durability": null, + "name": "Red dragonhide", + "tradeable": "true", + "weight": "3", + "archery_ticket_price": "0", + "id": "1749" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "3539", + "durability": null, + "name": "Red dragonhide", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1750" + }, + { + "ge_buy_limit": "10000", + "examine": "The scaly rough hide from a blue dragon.", + "grand_exchange_price": "2473", + "durability": null, + "name": "Blue dragonhide", + "tradeable": "true", + "weight": "3.1", + "archery_ticket_price": "0", + "id": "1751" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "2473", + "durability": null, + "name": "Blue dragonhide", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1752" + }, + { + "ge_buy_limit": "10000", + "examine": "The scaly rough hide from a green dragon.", + "grand_exchange_price": "1000", + "durability": null, + "name": "Green dragonhide", + "tradeable": "true", + "weight": "3.1", + "archery_ticket_price": "0", + "id": "1753" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "1933", + "durability": null, + "name": "Green dragonhide", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1754" + }, + { + "shop_price": "14", + "ge_buy_limit": "100", + "examine": "Good for detailed crafting.", + "grand_exchange_price": "20", + "durability": null, + "name": "Chisel", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "1755" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "20", + "durability": null, + "name": "Chisel", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1756" + }, + { + "shop_price": "2", + "ge_buy_limit": "100", + "examine": "A mostly clean apron.", + "grand_exchange_price": "74", + "durability": null, + "name": "Brown apron", + "tradeable": "true", + "weight": "0.45", + "archery_ticket_price": "0", + "id": "1757", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "74", + "durability": null, + "name": "Brown apron", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1758" + }, + { + "ge_buy_limit": "5000", + "examine": "Spun from sheeps' wool.", + "grand_exchange_price": "115", + "durability": null, + "name": "Ball of wool", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1759" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "115", + "durability": null, + "name": "Ball of wool", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1760" + }, + { + "ge_buy_limit": "10000", + "examine": "Clay soft enough to mould.", + "grand_exchange_price": "487", + "durability": null, + "name": "Soft clay", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "1761" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "487", + "durability": null, + "name": "Soft clay", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1762" + }, + { + "shop_price": "6", + "ge_buy_limit": "100", + "examine": "A little bottle of red dye.", + "grand_exchange_price": "1374", + "durability": null, + "name": "Red dye", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1763" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1374", + "durability": null, + "name": "Red dye", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1764" + }, + { + "shop_price": "6", + "ge_buy_limit": "100", + "examine": "A little bottle of yellow dye.", + "grand_exchange_price": "549", + "durability": null, + "name": "Yellow dye", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1765" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "549", + "durability": null, + "name": "Yellow dye", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1766" + }, + { + "shop_price": "6", + "ge_buy_limit": "100", + "examine": "A little bottle of blue dye", + "grand_exchange_price": "642", + "durability": null, + "name": "Blue dye", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "1767" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "642", + "durability": null, + "name": "Blue dye", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1768" + }, + { + "shop_price": "6", + "ge_buy_limit": "100", + "examine": "A little bottle of orange dye.", + "grand_exchange_price": "1258", + "durability": null, + "name": "Orange dye", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "1769" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1258", + "durability": null, + "name": "Orange dye", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1770" + }, + { + "shop_price": "6", + "ge_buy_limit": "100", + "examine": "A little bottle of green dye.", + "grand_exchange_price": "503", + "durability": null, + "name": "Green dye", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1771" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "503", + "durability": null, + "name": "Green dye", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1772" + }, + { + "shop_price": "6", + "ge_buy_limit": "100", + "examine": "A little bottle of purple dye.", + "grand_exchange_price": "288", + "durability": null, + "name": "Purple dye", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1773" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "288", + "durability": null, + "name": "Purple dye", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1774" + }, + { + "ge_buy_limit": "10000", + "examine": "Hot glass ready to be blown into useful objects.", + "grand_exchange_price": "924", + "durability": null, + "name": "Molten glass", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "1775" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "924", + "durability": null, + "name": "Molten glass", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1776" + }, + { + "ge_buy_limit": "10000", + "examine": "I need a bow stave to attach this to.", + "grand_exchange_price": "240", + "durability": null, + "name": "Bow string", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1777" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "223", + "durability": null, + "name": "Bow string", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1778" + }, + { + "shop_price": "73", + "ge_buy_limit": "25000", + "examine": "A plant cultivated for fibres (ground); I should use this with a spinning wheel (item).", + "grand_exchange_price": "73", + "durability": null, + "name": "Flax", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "1779" + }, + { + "ge_buy_limit": "25000", + "grand_exchange_price": "73", + "durability": null, + "name": "Flax", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1780" + }, + { + "ge_buy_limit": "10000", + "examine": "One of the ingredients for making glass.", + "grand_exchange_price": "575", + "durability": null, + "name": "Soda ash", + "tradeable": "true", + "weight": "0.09", + "archery_ticket_price": "0", + "id": "1781" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "575", + "durability": null, + "name": "Soda ash", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1782" + }, + { + "ge_buy_limit": "10000", + "examine": "One of the ingredients for making glass.", + "grand_exchange_price": "265", + "durability": null, + "name": "Bucket of sand", + "tradeable": "true", + "weight": "2.5", + "archery_ticket_price": "0", + "id": "1783" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "265", + "durability": null, + "name": "Bucket of sand", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1784" + }, + { + "shop_price": "5", + "ge_buy_limit": "100", + "examine": "Used to form molten glass into useful items.", + "grand_exchange_price": "195", + "durability": null, + "name": "Glassblowing pipe", + "tradeable": "true", + "weight": "0.05", + "archery_ticket_price": "0", + "id": "1785" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "195", + "durability": null, + "name": "Glassblowing pipe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1786" + }, + { + "ge_buy_limit": "100", + "examine": "I need to put this in a pottery oven.", + "grand_exchange_price": "53", + "durability": null, + "name": "Unfired pot", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1787" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "53", + "durability": null, + "name": "Unfired pot", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1788" + }, + { + "ge_buy_limit": "100", + "examine": "I need to put this in a pottery oven.", + "grand_exchange_price": "96", + "durability": null, + "name": "Unfired pie dish", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1789" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "96", + "durability": null, + "name": "Unfired pie dish", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1790" + }, + { + "shop_price": "32", + "ge_buy_limit": "100", + "examine": "I need to put this in a pottery oven.", + "grand_exchange_price": "194", + "durability": null, + "name": "Unfired bowl", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1791" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "194", + "durability": null, + "name": "Unfired bowl", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1792" + }, + { + "shop_price": "15", + "ge_buy_limit": "100", + "examine": "A slightly bluish leaf.", + "grand_exchange_price": "57", + "durability": null, + "name": "Woad leaf", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1793", + "equip_audio": "" + }, + { + "ge_buy_limit": "100", + "examine": "Useful for crafting items.", + "grand_exchange_price": "249", + "durability": null, + "name": "Bronze wire", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1794" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "249", + "durability": null, + "name": "Bronze wire", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1795" + }, + { + "examine": "Anna's shiny silver coated necklace.", + "durability": null, + "name": "Silver necklace", + "weight": "1", + "archery_ticket_price": "0", + "id": "1796", + "equipment_slot": "2" + }, + { + "examine": "Anna's shiny silver coated necklace.", + "durability": null, + "name": "Silver necklace", + "weight": "1", + "archery_ticket_price": "0", + "id": "1797", + "equipment_slot": "2" + }, + { + "examine": "Bob's shiny silver coated tea cup.", + "durability": null, + "name": "Silver cup", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "1798" + }, + { + "examine": "Bob's shiny silver coated tea cup.", + "durability": null, + "name": "Silver cup", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "1799" + }, + { + "examine": "Carol's shiny silver coated bottle.", + "durability": null, + "name": "Silver bottle", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "1800" + }, + { + "examine": "Carol's shiny silver coated bottle.", + "durability": null, + "name": "Silver bottle", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "1801" + }, + { + "examine": "David's shiny silver coated book.", + "durability": null, + "name": "Silver book", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "1802" + }, + { + "examine": "David's shiny silver coated book.", + "durability": null, + "name": "Silver book", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "1803" + }, + { + "examine": "Elizabeth's shiny silver coated needle.", + "durability": null, + "name": "Silver needle", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "1804" + }, + { + "examine": "Elizabeth's shiny silver coated needle.", + "durability": null, + "name": "Silver needle", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "1805" + }, + { + "examine": "Frank's shiny silver coated pot.", + "durability": null, + "name": "Silver pot", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "1806" + }, + { + "examine": "Frank's shiny silver coated pot.", + "durability": null, + "name": "Silver pot", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "1807" + }, + { + "examine": "Some (colour) thread found at the murder scene.", + "durability": null, + "name": "Criminal's thread", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "1808" + }, + { + "examine": "Some (colour) thread found at the murder scene.", + "durability": null, + "name": "Criminal's thread", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "1809" + }, + { + "examine": "Some (colour) thread found at the murder scene.", + "durability": null, + "name": "Criminal's thread", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "1810" + }, + { + "examine": "A piece of fly paper. It's sticky.", + "durability": null, + "name": "Flypaper", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "1811" + }, + { + "examine": "A pot found at the murder scene, with a sickly odour.", + "durability": null, + "name": "Pungent pot", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "1812" + }, + { + "examine": "A flimsy-looking dagger found at the crime scene./A flimsy looking dagger found at the crime scene coated with a thin layer of flour.", + "attack_audios": "2517,2517,2500,2517", + "durability": null, + "name": "Criminal's dagger", + "archery_ticket_price": "0", + "id": "1813" + }, + { + "examine": "A flimsy-looking dagger found at the crime scene./A flimsy looking dagger found at the crime scene coated with a thin layer of flour.", + "attack_audios": "2517,2517,2500,2517", + "durability": null, + "name": "Criminal's dagger", + "archery_ticket_price": "0", + "id": "1814" + }, + { + "examine": "The fingerprints of the murderer.", + "durability": null, + "name": "Killer's print", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "1815" + }, + { + "examine": "An imprint of Anna's fingerprint.", + "durability": null, + "name": "Anna's print", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "1816" + }, + { + "examine": "An imprint of Bob's fingerprint.", + "durability": null, + "name": "Bob's print", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "1817" + }, + { + "examine": "An imprint of Carol's fingerprint.", + "durability": null, + "name": "Carol's print", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "1818" + }, + { + "examine": "An imprint of David's fingerprint.", + "durability": null, + "name": "David's print", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "1819" + }, + { + "examine": "An imprint of Elizabeth's fingerprint.", + "durability": null, + "name": "Elizabeth's print", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "1820" + }, + { + "examine": "An imprint of Frank's fingerprint.", + "durability": null, + "name": "Frank's print", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "1821" + }, + { + "examine": "An unidentified fingerprint taken from the murder weapon.", + "durability": null, + "name": "Unknown print", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "1822" + }, + { + "shop_price": "30", + "ge_buy_limit": "100", + "examine": "A full waterskin with four portions of water.", + "grand_exchange_price": "184", + "durability": null, + "name": "Waterskin(4)", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "1823" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "184", + "durability": null, + "name": "Waterskin(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1824" + }, + { + "shop_price": "30", + "examine": "A nearly full waterskin with three portions of water.", + "grand_exchange_price": "4", + "durability": null, + "name": "Waterskin(3)", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "1825" + }, + { + "durability": null, + "name": "Waterskin(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1826" + }, + { + "shop_price": "30", + "examine": "A half empty waterskin with two portions of water.", + "grand_exchange_price": "4", + "durability": null, + "name": "Waterskin(2)", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "1827" + }, + { + "durability": null, + "name": "Waterskin(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1828" + }, + { + "shop_price": "30", + "examine": "A nearly empty waterskin with one portion of water.", + "grand_exchange_price": "4", + "durability": null, + "name": "Waterskin(1)", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "1829" + }, + { + "durability": null, + "name": "Waterskin(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1830" + }, + { + "shop_price": "30", + "ge_buy_limit": "100", + "examine": "A completely empty waterskin - you'll need to fill it up.", + "grand_exchange_price": "93", + "durability": null, + "name": "Waterskin(0)", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "1831" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "93", + "durability": null, + "name": "Waterskin(0)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1832" + }, + { + "remove_sleeves": "true", + "shop_price": "40", + "ge_buy_limit": "100", + "examine": "A cool, light desert shirt.", + "grand_exchange_price": "93", + "durability": null, + "name": "Desert shirt", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "1833", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "93", + "durability": null, + "name": "Desert shirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1834" + }, + { + "shop_price": "40", + "ge_buy_limit": "100", + "examine": "A cool, light desert robe.", + "grand_exchange_price": "74", + "durability": null, + "name": "Desert robe", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "1835", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "74", + "durability": null, + "name": "Desert robe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1836" + }, + { + "shop_price": "20", + "ge_buy_limit": "100", + "examine": "Comfortable desert shoes.", + "grand_exchange_price": "257", + "durability": null, + "name": "Desert boots", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "1837", + "equipment_slot": "10" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "257", + "durability": null, + "name": "Desert boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1838" + }, + { + "examine": "This key is crudely made. It came from the mining camp Mercenary Captain.", + "durability": null, + "name": "Metal key", + "archery_ticket_price": "0", + "id": "1839" + }, + { + "examine": "A metallic key, usually used by prison guards. (Tourist Trap)", + "durability": null, + "name": "Cell door key", + "archery_ticket_price": "0", + "id": "1840" + }, + { + "examine": "An empty barrel/A Splendid barrel.", + "grand_exchange_price": "206", + "durability": null, + "name": "Barrel", + "tradeable": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "1841" + }, + { + "examine": "Inventory: A mining barrel with Ana in it.While in the mine cart: It's Ana... in a barrel... in a mine cart.", + "durability": null, + "name": "Ana in a barrel", + "weight": "32", + "archery_ticket_price": "0", + "id": "1842" + }, + { + "examine": "This key unlocks a very sturdy gate. Ana gave me this key. (Tourist Trap)", + "durability": null, + "name": "Wrought iron key", + "archery_ticket_price": "0", + "id": "1843" + }, + { + "remove_sleeves": "true", + "examine": "A filthy, smelly, flea infested shirt.", + "durability": null, + "name": "Slave shirt", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "1844", + "equipment_slot": "4" + }, + { + "examine": "A filthy, smelly, flea infested robe.", + "durability": null, + "name": "Slave robe", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "1845", + "equipment_slot": "7" + }, + { + "examine": "A set of filthy, smelly, flea infested desert slave boots.", + "durability": null, + "name": "Slave boots", + "weight": "0.6", + "archery_ticket_price": "0", + "id": "1846", + "equipment_slot": "10" + }, + { + "examine": "A piece of paper with barely legible writing - looks like a recipe!", + "durability": null, + "name": "Scrumpled paper", + "archery_ticket_price": "0", + "id": "1847" + }, + { + "shop_price": "5", + "examine": "Very important information.", + "durability": null, + "name": "Shantay disclaimer", + "archery_ticket_price": "0", + "id": "1848" + }, + { + "examine": "A prototype throwing dart.", + "attack_audios": "2547,0,0,0", + "durability": null, + "name": "Prototype dart", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "1849" + }, + { + "examine": "Plans of a technical nature.", + "durability": null, + "name": "Technical plans", + "weight": "1", + "archery_ticket_price": "0", + "id": "1850" + }, + { + "examine": "The most delicious of pineapples.", + "durability": null, + "name": "Tenti pineapple", + "weight": "1", + "archery_ticket_price": "0", + "id": "1851" + }, + { + "examine": "A key to the chest in Captain Siad's room.", + "durability": null, + "name": "Bedabin key", + "archery_ticket_price": "0", + "id": "1852" + }, + { + "examine": "A protoype dart tip - it looks deadly.", + "attack_audios": "2547,0,0,0", + "durability": null, + "name": "Prototype dart tip", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "1853" + }, + { + "shop_price": "5", + "examine": "Allows you to pass through the Shantay pass into the Kharid Desert.", + "durability": null, + "name": "Shantay pass", + "archery_ticket_price": "0", + "id": "1854" + }, + { + "examine": "A Tourist's Guide to Ardougne.", + "durability": null, + "name": "Guide book", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "1856" + }, + { + "examine": "The Rantuki tribe's totem.", + "durability": null, + "name": "Totem", + "weight": "3", + "archery_ticket_price": "0", + "id": "1857" + }, + { + "examine": "It says 'To Lord Handelmort, Handelmort Mansion'.", + "durability": null, + "name": "Address label", + "archery_ticket_price": "0", + "id": "1858" + }, + { + "ge_buy_limit": "1000", + "examine": "I need to cook this first.", + "grand_exchange_price": "486", + "durability": null, + "name": "Raw ugthanki meat", + "tradeable": "true", + "weight": "0.75", + "archery_ticket_price": "0", + "id": "1859" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "486", + "durability": null, + "name": "Raw ugthanki meat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1860" + }, + { + "ge_buy_limit": "1000", + "examine": "I need to cook this first / Freshly cooked ugthanki meat.", + "grand_exchange_price": "687", + "durability": null, + "name": "Ugthanki meat", + "tradeable": "true", + "weight": "0.75", + "archery_ticket_price": "0", + "id": "1861" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "687", + "durability": null, + "name": "Ugthanki meat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1862" + }, + { + "shop_price": "9", + "ge_buy_limit": "1000", + "examine": "I need to cook this.", + "grand_exchange_price": "90", + "durability": null, + "name": "Pitta dough", + "tradeable": "true", + "weight": "0.14", + "archery_ticket_price": "0", + "id": "1863" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "90", + "durability": null, + "name": "Pitta dough", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1864" + }, + { + "ge_buy_limit": "1000", + "examine": "Nicely baked pitta bread. Needs more ingredients to make a kebab.", + "grand_exchange_price": "22", + "durability": null, + "name": "Pitta bread", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1865" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "22", + "durability": null, + "name": "Pitta bread", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1866" + }, + { + "examine": "It's all burnt.", + "durability": null, + "name": "Burnt pitta bread", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1867" + }, + { + "durability": null, + "name": "Burnt pitta bread", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1868" + }, + { + "ge_buy_limit": "1000", + "examine": "A mixture of tomatoes in a bowl.", + "grand_exchange_price": "90", + "durability": null, + "name": "Chopped tomato", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "1869" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "90", + "durability": null, + "name": "Chopped tomato", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1870" + }, + { + "ge_buy_limit": "1000", + "examine": "A mixture of onions in a bowl.", + "grand_exchange_price": "142", + "durability": null, + "name": "Chopped onion", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "1871" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "142", + "durability": null, + "name": "Chopped onion", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1872" + }, + { + "ge_buy_limit": "1000", + "examine": "Strips of ugthanki meat in a bowl.", + "grand_exchange_price": "348", + "durability": null, + "name": "Chopped ugthanki", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1873" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "348", + "durability": null, + "name": "Chopped ugthanki", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1874" + }, + { + "ge_buy_limit": "1000", + "examine": "A mixture of chopped onions and tomatoes in a bowl", + "grand_exchange_price": "31", + "durability": null, + "name": "Onion & tomato", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1875" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "31", + "durability": null, + "name": "Onion & tomato", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1876" + }, + { + "shop_price": "26", + "ge_buy_limit": "1000", + "examine": "A mixture of chopped onions and ugthanki meat in a bowl.", + "grand_exchange_price": "330", + "durability": null, + "name": "Ugthanki & onion", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1877" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "330", + "durability": null, + "name": "Ugthanki & onion", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1878" + }, + { + "ge_buy_limit": "10000", + "examine": "A mixture of chopped tomatoes and ugthanki meat in a bowl.", + "grand_exchange_price": "331", + "durability": null, + "name": "Ugthanki & tomato", + "tradeable": "true", + "weight": "0.25", + "archery_ticket_price": "0", + "id": "1879" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "331", + "durability": null, + "name": "Ugthanki & tomato", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1880" + }, + { + "ge_buy_limit": "1000", + "examine": "A mixture of chopped tomatoes, onions and ugthanki meat in a bowl", + "grand_exchange_price": "412", + "durability": null, + "name": "Kebab mix", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1881" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "412", + "durability": null, + "name": "Kebab mix", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1882" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "2027", + "durability": null, + "name": "Ugthanki kebab", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "1883" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "2027", + "durability": null, + "name": "Ugthanki kebab", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1884" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1499", + "durability": null, + "name": "Ugthanki kebab", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "1885" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1499", + "durability": null, + "name": "Ugthanki kebab", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1886" + }, + { + "shop_price": "10", + "ge_buy_limit": "100", + "examine": "Useful for baking cakes.", + "grand_exchange_price": "20", + "durability": null, + "name": "Cake tin", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "1887" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "20", + "durability": null, + "name": "Cake tin", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1888" + }, + { + "ge_buy_limit": "1000", + "examine": "Now all I need to do is cook it.", + "grand_exchange_price": "559", + "durability": null, + "name": "Uncooked cake", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "1889" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "559", + "durability": null, + "name": "Uncooked cake", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1890" + }, + { + "shop_price": "50", + "ge_buy_limit": "1000", + "examine": "A plain sponge cake.", + "grand_exchange_price": "155", + "durability": null, + "name": "Cake", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "1891" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "155", + "durability": null, + "name": "Cake", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1892" + }, + { + "shop_price": "50", + "ge_buy_limit": "1000", + "examine": "A plain sponge cake.", + "grand_exchange_price": "39", + "durability": null, + "name": "2/3 cake", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "1893" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "39", + "durability": null, + "name": "2/3 cake", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1894" + }, + { + "shop_price": "50", + "ge_buy_limit": "1000", + "examine": "A plain sponge cake.", + "grand_exchange_price": "32", + "durability": null, + "name": "Slice of cake", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "1895" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "32", + "durability": null, + "name": "Slice of cake", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1896" + }, + { + "ge_buy_limit": "1000", + "examine": "This looks very tasty.", + "grand_exchange_price": "416", + "durability": null, + "name": "Chocolate cake", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "1897" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "416", + "durability": null, + "name": "Chocolate cake", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1898" + }, + { + "ge_buy_limit": "1000", + "examine": "This looks very tasty.", + "grand_exchange_price": "181", + "durability": null, + "name": "2/3 chocolate cake", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "1899" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "181", + "durability": null, + "name": "2/3 chocolate cake", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1900" + }, + { + "ge_buy_limit": "1000", + "examine": "This looks very tasty.", + "grand_exchange_price": "13", + "durability": null, + "name": "Chocolate slice", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "1901" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "13", + "durability": null, + "name": "Chocolate slice", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1902" + }, + { + "durability": null, + "name": "Burnt cake", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1904" + }, + { + "shop_price": "3", + "ge_buy_limit": "100", + "examine": "Probably the finest readily-available ale in Asgarnia.", + "grand_exchange_price": "190", + "durability": null, + "name": "Asgarnian ale", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1905" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "190", + "durability": null, + "name": "Asgarnian ale", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1906" + }, + { + "shop_price": "3", + "ge_buy_limit": "100", + "examine": "It's got strange bubbles in it.", + "grand_exchange_price": "171", + "durability": null, + "name": "Wizard's mind bomb", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1907" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "171", + "durability": null, + "name": "Wizard's mind bomb", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1908" + }, + { + "shop_price": "2", + "ge_buy_limit": "100", + "examine": "A glass of frothy ale.", + "grand_exchange_price": "828", + "durability": null, + "name": "Greenman's ale", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1909" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "828", + "durability": null, + "name": "Greenman's ale", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1910" + }, + { + "shop_price": "2", + "ge_buy_limit": "100", + "examine": "A glass of bitter.", + "grand_exchange_price": "487", + "durability": null, + "name": "Dragon bitter", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "1911" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "487", + "durability": null, + "name": "Dragon bitter", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1912" + }, + { + "shop_price": "3", + "ge_buy_limit": "100", + "examine": "A pint of thick dark beer.", + "grand_exchange_price": "212", + "durability": null, + "name": "Dwarven stout", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1913" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "212", + "durability": null, + "name": "Dwarven stout", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1914" + }, + { + "shop_price": "3", + "ge_buy_limit": "100", + "examine": "A murky glass full of your average, everyday pirate slosh.", + "grand_exchange_price": "19", + "durability": null, + "name": "Grog", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "1915" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "19", + "durability": null, + "name": "Grog", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1916" + }, + { + "ge_buy_limit": "100", + "examine": "A glass of frothy ale.", + "grand_exchange_price": "202", + "durability": null, + "name": "Beer", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "1917", + "equipment_slot": "3" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "202", + "durability": null, + "name": "Beer", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1918" + }, + { + "shop_price": "1", + "ge_buy_limit": "100", + "examine": "I need to fill this with beer.", + "grand_exchange_price": "10", + "durability": null, + "name": "Beer glass", + "tradeable": "true", + "weight": "0.05", + "archery_ticket_price": "0", + "id": "1919" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "10", + "durability": null, + "name": "Beer glass", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1920" + }, + { + "ge_buy_limit": "100", + "examine": "It's a bowl of water.", + "grand_exchange_price": "97", + "durability": null, + "name": "Bowl of water", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "1921" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "97", + "durability": null, + "name": "Bowl of water", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1922" + }, + { + "shop_price": "4", + "ge_buy_limit": "100", + "examine": "Useful for mixing things.", + "grand_exchange_price": "34", + "durability": null, + "name": "Bowl", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "1923" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "34", + "durability": null, + "name": "Bowl", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1924" + }, + { + "shop_price": "2", + "ge_buy_limit": "100", + "examine": "It's an empty bucket.", + "grand_exchange_price": "30", + "durability": null, + "name": "Bucket", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "1925" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "30", + "durability": null, + "name": "Bucket", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1926" + }, + { + "shop_price": "12", + "ge_buy_limit": "1000", + "examine": "It's a bucket of milk.", + "grand_exchange_price": "103", + "durability": null, + "name": "Bucket of milk", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "1927" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "103", + "durability": null, + "name": "Bucket of milk", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1928" + }, + { + "ge_buy_limit": "100", + "examine": "It's a bucket of water.", + "grand_exchange_price": "72", + "durability": null, + "name": "Bucket of water", + "tradeable": "true", + "weight": "3", + "archery_ticket_price": "0", + "id": "1929" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "72", + "durability": null, + "name": "Bucket of water", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1930" + }, + { + "shop_price": "1", + "ge_buy_limit": "100", + "examine": "This pot is empty.", + "grand_exchange_price": "6", + "durability": null, + "name": "Empty pot", + "tradeable": "true", + "weight": "0.45", + "archery_ticket_price": "0", + "id": "1931" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "6", + "durability": null, + "name": "Empty pot", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1932" + }, + { + "shop_price": "14", + "ge_buy_limit": "1000", + "examine": "There is flour in this pot.", + "grand_exchange_price": "172", + "durability": null, + "name": "Pot of flour", + "tradeable": "true", + "weight": "1.3", + "archery_ticket_price": "0", + "id": "1933" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "172", + "durability": null, + "name": "Pot of flour", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1934" + }, + { + "shop_price": "1", + "ge_buy_limit": "10000", + "examine": "This jug is empty.", + "grand_exchange_price": "29", + "durability": null, + "name": "Jug", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "1935" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "29", + "durability": null, + "name": "Jug", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1936" + }, + { + "shop_price": "1", + "ge_buy_limit": "10000", + "examine": "It's full of water.", + "grand_exchange_price": "87", + "durability": null, + "name": "Jug of water", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "1937" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "87", + "durability": null, + "name": "Jug of water", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1938" + }, + { + "ge_buy_limit": "5000", + "examine": "A foul smelling thick tar like substance.", + "grand_exchange_price": "103", + "durability": null, + "name": "Swamp tar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1939" + }, + { + "shop_price": "38", + "ge_buy_limit": "5000", + "examine": "A tar-like substance mixed with flour and warmed.", + "grand_exchange_price": "342", + "durability": null, + "name": "Raw swamp paste", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1940" + }, + { + "shop_price": "38", + "ge_buy_limit": "100", + "examine": "A tar-like substance mixed with flour and warmed.", + "grand_exchange_price": "1", + "durability": null, + "name": "Swamp paste", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1941" + }, + { + "shop_price": "11", + "ge_buy_limit": "500", + "examine": "This could be used to make a good stew.", + "grand_exchange_price": "91", + "durability": null, + "name": "Potato", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "1942" + }, + { + "ge_buy_limit": "500", + "grand_exchange_price": "91", + "durability": null, + "name": "Potato", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1943" + }, + { + "shop_price": "1", + "ge_buy_limit": "1000", + "examine": "A nice fresh egg.", + "grand_exchange_price": "99", + "durability": null, + "name": "Egg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1944" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "99", + "durability": null, + "name": "Egg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1945" + }, + { + "shop_price": "14", + "examine": "There is flour in this pot.", + "grand_exchange_price": "162", + "durability": null, + "name": "Flour", + "tradeable": "true", + "weight": "1.3", + "archery_ticket_price": "0", + "id": "1946" + }, + { + "shop_price": "2", + "ge_buy_limit": "1000", + "examine": "Some wheat heads.", + "grand_exchange_price": "7", + "durability": null, + "name": "Grain", + "tradeable": "true", + "weight": "0.6", + "archery_ticket_price": "0", + "id": "1947" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "7", + "durability": null, + "name": "Grain", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1948" + }, + { + "shop_price": "2", + "ge_buy_limit": "100", + "examine": "What a silly hat.", + "grand_exchange_price": "233", + "durability": null, + "name": "Chef's hat", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "1949", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "233", + "durability": null, + "name": "Chef's hat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1950" + }, + { + "shop_price": "3", + "ge_buy_limit": "1000", + "examine": "Very bright red berries.", + "grand_exchange_price": "337", + "durability": null, + "name": "Redberries", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "1951" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "337", + "durability": null, + "name": "Redberries", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1952" + }, + { + "ge_buy_limit": "1000", + "examine": "Potentially pastry.", + "grand_exchange_price": "433", + "durability": null, + "name": "Pastry dough", + "tradeable": "true", + "weight": "0.16", + "archery_ticket_price": "0", + "id": "1953" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "433", + "durability": null, + "name": "Pastry dough", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1954" + }, + { + "shop_price": "36", + "ge_buy_limit": "1000", + "examine": "Keeps the doctor away.", + "grand_exchange_price": "353", + "durability": null, + "name": "Cooking apple", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1955" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "353", + "durability": null, + "name": "Cooking apple", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1956" + }, + { + "shop_price": "12", + "ge_buy_limit": "1000", + "examine": "A strong smelling onion.", + "grand_exchange_price": "8", + "durability": null, + "name": "Onion", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "1957" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "8", + "durability": null, + "name": "Onion", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1958" + }, + { + "ge_buy_limit": "2", + "examine": "Happy Halloween.", + "grand_exchange_price": "273600000", + "durability": null, + "name": "Pumpkin", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "1959" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "273600000", + "durability": null, + "name": "Pumpkin", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1960" + }, + { + "ge_buy_limit": "2", + "examine": "Happy Easter.", + "grand_exchange_price": "80400000", + "durability": null, + "name": "Easter egg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1961" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "80400000", + "durability": null, + "name": "Easter egg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1962" + }, + { + "shop_price": "2", + "ge_buy_limit": "1000", + "examine": "Mmm this looks tasty.", + "grand_exchange_price": "263", + "durability": null, + "name": "Banana", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1963", + "equipment_slot": "3" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "263", + "durability": null, + "name": "Banana", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1964" + }, + { + "ge_buy_limit": "1000", + "examine": "Yuck, I don't like cabbage.", + "grand_exchange_price": "41", + "durability": null, + "name": "Cabbage", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "1965" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "41", + "durability": null, + "name": "Cabbage", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1966" + }, + { + "examine": "Yuck, a cabbage from Draynor Manor. I don't like cabbage.", + "grand_exchange_price": "55", + "durability": null, + "name": "Cabbage", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "1967" + }, + { + "durability": null, + "name": "Cabbage", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1968" + }, + { + "shop_price": "1", + "examine": "A home made spinach thing.", + "durability": null, + "name": "Spinach roll", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "1969" + }, + { + "shop_price": "1", + "ge_buy_limit": "1000", + "examine": "A meaty kebab.", + "grand_exchange_price": "97", + "durability": null, + "name": "Kebab", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1971" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "97", + "durability": null, + "name": "Kebab", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1972" + }, + { + "shop_price": "20", + "ge_buy_limit": "10000", + "examine": "Mmmmmmm chocolate.", + "grand_exchange_price": "295", + "durability": null, + "name": "Chocolate bar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1973", + "equipment_slot": "5" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "295", + "durability": null, + "name": "Chocolate bar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1974" + }, + { + "shop_price": "20", + "ge_buy_limit": "10000", + "examine": "It's ground-up chocolate.", + "grand_exchange_price": "370", + "durability": null, + "name": "Chocolate dust", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1975" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "370", + "durability": null, + "name": "Chocolate dust", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1976" + }, + { + "examine": "Milk with chocolate in it.", + "durability": null, + "name": "Chocolatey milk", + "weight": "2", + "archery_ticket_price": "0", + "id": "1977" + }, + { + "shop_price": "10", + "ge_buy_limit": "1000", + "examine": "A nice cup of tea.", + "grand_exchange_price": "30", + "durability": null, + "name": "Cup of tea", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "1978" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "30", + "durability": null, + "name": "Cup of tea", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1979" + }, + { + "shop_price": "1", + "ge_buy_limit": "100", + "examine": "An empty cup.", + "grand_exchange_price": "5", + "durability": null, + "name": "Empty cup", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1980" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "5", + "durability": null, + "name": "Empty cup", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1981" + }, + { + "shop_price": "25", + "ge_buy_limit": "10000", + "examine": "This would make good ketchup.", + "grand_exchange_price": "159", + "durability": null, + "name": "Tomato", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1982" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "159", + "durability": null, + "name": "Tomato", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1983" + }, + { + "shop_price": "1", + "examine": "Rotten to the core!", + "durability": null, + "name": "Rotten apple", + "archery_ticket_price": "0", + "id": "1984" + }, + { + "shop_price": "3", + "ge_buy_limit": "10000", + "examine": "It's got holes in it.", + "grand_exchange_price": "188", + "durability": null, + "name": "Cheese", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "1985" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "188", + "durability": null, + "name": "Cheese", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1986" + }, + { + "shop_price": "1", + "ge_buy_limit": "1000", + "examine": "Good grapes for wine making.", + "grand_exchange_price": "1510", + "durability": null, + "name": "Grapes", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "1987" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1510", + "durability": null, + "name": "Grapes", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1988" + }, + { + "ge_buy_limit": "2", + "examine": "An optimist would say it is half full.", + "grand_exchange_price": "227700000", + "durability": null, + "name": "Half full wine jug", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1989" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "227700000", + "durability": null, + "name": "Half full wine jug", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1990" + }, + { + "examine": "Oh dear, this wine is terrible!", + "durability": null, + "name": "Jug of bad wine", + "weight": "1", + "archery_ticket_price": "0", + "id": "1991" + }, + { + "examine": "Oh dear, this wine is terrible!", + "durability": null, + "name": "Jug of bad wine", + "weight": "1", + "archery_ticket_price": "0", + "id": "1992" + }, + { + "shop_price": "128", + "ge_buy_limit": "1000", + "examine": "It's full of wine.", + "grand_exchange_price": "36", + "durability": null, + "name": "Jug of wine", + "tradeable": "true", + "weight": "1.5", + "archery_ticket_price": "0", + "id": "1993" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "36", + "durability": null, + "name": "Jug of wine", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1994" + }, + { + "examine": "This wine needs to ferment before it can be drunk.", + "durability": null, + "name": "Unfermented wine", + "weight": "1", + "archery_ticket_price": "0", + "id": "1995" + }, + { + "examine": "This wine needs to ferment before it can be drunk.", + "durability": null, + "name": "Unfermented wine", + "weight": "1", + "archery_ticket_price": "0", + "id": "1996" + }, + { + "ge_buy_limit": "200", + "grand_exchange_price": "177", + "durability": null, + "name": "Incomplete stew", + "archery_ticket_price": "0", + "id": "1997" + }, + { + "ge_buy_limit": "200", + "grand_exchange_price": "177", + "durability": null, + "name": "Incomplete stew", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "1998" + }, + { + "ge_buy_limit": "200", + "grand_exchange_price": "210", + "durability": null, + "name": "Incomplete stew", + "archery_ticket_price": "0", + "id": "1999" + }, + { + "ge_buy_limit": "200", + "grand_exchange_price": "210", + "durability": null, + "name": "Incomplete stew", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2000" + }, + { + "shop_price": "1", + "ge_buy_limit": "200", + "examine": "I need to cook this.", + "grand_exchange_price": "600", + "durability": null, + "name": "Uncooked stew", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "2001" + }, + { + "ge_buy_limit": "200", + "grand_exchange_price": "600", + "durability": null, + "name": "Uncooked stew", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2002" + }, + { + "shop_price": "20", + "ge_buy_limit": "200", + "examine": "It's a meat and potato stew.", + "grand_exchange_price": "1133", + "durability": null, + "name": "Stew", + "tradeable": "true", + "weight": "1.5", + "archery_ticket_price": "0", + "id": "2003" + }, + { + "ge_buy_limit": "200", + "grand_exchange_price": "1133", + "durability": null, + "name": "Stew", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2004" + }, + { + "durability": null, + "name": "Burnt stew", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2006" + }, + { + "shop_price": "230", + "ge_buy_limit": "1000", + "examine": "This could liven up an otherwise bland stew.", + "grand_exchange_price": "277", + "durability": null, + "name": "Spice", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "2007" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "277", + "durability": null, + "name": "Spice", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2008" + }, + { + "ge_buy_limit": "200", + "examine": "I need to cook this.", + "grand_exchange_price": "1382", + "durability": null, + "name": "Uncooked curry", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2009" + }, + { + "ge_buy_limit": "200", + "grand_exchange_price": "1382", + "durability": null, + "name": "Uncooked curry", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2010" + }, + { + "ge_buy_limit": "200", + "examine": "It's a spicy hot curry.", + "grand_exchange_price": "1001", + "durability": null, + "name": "Curry", + "tradeable": "true", + "weight": "1.5", + "archery_ticket_price": "0", + "id": "2011" + }, + { + "ge_buy_limit": "200", + "grand_exchange_price": "1001", + "durability": null, + "name": "Curry", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2012" + }, + { + "examine": "Eew, it's horribly burnt.", + "durability": null, + "name": "Burnt curry", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2013" + }, + { + "durability": null, + "name": "Burnt curry", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2014" + }, + { + "shop_price": "5", + "ge_buy_limit": "1000", + "examine": "An absolutely clear spirit sold by well-stocked bars.", + "grand_exchange_price": "366", + "durability": null, + "name": "Vodka", + "tradeable": "true", + "weight": "0.25", + "archery_ticket_price": "0", + "id": "2015" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "366", + "durability": null, + "name": "Vodka", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2016" + }, + { + "shop_price": "5", + "ge_buy_limit": "1000", + "examine": "This Draynor malt is sold by well-stocked bars.", + "grand_exchange_price": "68", + "durability": null, + "name": "Whisky", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "2017" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "68", + "durability": null, + "name": "Whisky", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2018" + }, + { + "shop_price": "2", + "ge_buy_limit": "1000", + "examine": "A strong spirit that tastes of Juniper; sold at well-stocked bars.", + "grand_exchange_price": "184", + "durability": null, + "name": "Gin", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "2019" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "184", + "durability": null, + "name": "Gin", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2020" + }, + { + "shop_price": "6", + "ge_buy_limit": "1000", + "examine": "A strong spirit best served in a large glass.", + "grand_exchange_price": "146", + "durability": null, + "name": "Brandy", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2021" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "146", + "durability": null, + "name": "Brandy", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2022" + }, + { + "shop_price": "5", + "examine": "A book on tree gnome cocktails.", + "durability": null, + "name": "Cocktail guide", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "2023" + }, + { + "durability": null, + "name": "Cocktail guide", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2024" + }, + { + "shop_price": "2", + "examine": "Used for mixing cocktails.", + "durability": null, + "name": "Cocktail shaker", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "2025" + }, + { + "shop_price": "1", + "examine": "For sipping cocktails.", + "durability": null, + "name": "Cocktail glass", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2026" + }, + { + "durability": null, + "name": "Cocktail glass", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2027" + }, + { + "shop_price": "30", + "ge_buy_limit": "1000", + "examine": "A premade Blurberry Special.", + "grand_exchange_price": "70", + "durability": null, + "name": "Premade blurb' sp.", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "2028" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "70", + "durability": null, + "name": "Premade blurb' sp.", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2029" + }, + { + "shop_price": "30", + "ge_buy_limit": "1000", + "examine": "A premade Chocolate Saturday.", + "grand_exchange_price": "13", + "durability": null, + "name": "Premade choc s'dy", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "2030" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "13", + "durability": null, + "name": "Premade choc s'dy", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2031" + }, + { + "shop_price": "30", + "ge_buy_limit": "1000", + "examine": "A premade Drunk Dragon.", + "grand_exchange_price": "34", + "durability": null, + "name": "Premade dr' dragon", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "2032" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "34", + "durability": null, + "name": "Premade dr' dragon", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2033" + }, + { + "shop_price": "30", + "ge_buy_limit": "1000", + "examine": "A premade Fruit Blast.", + "grand_exchange_price": "48", + "durability": null, + "name": "Premade fr' blast", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "2034" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "48", + "durability": null, + "name": "Premade fr' blast", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2035" + }, + { + "shop_price": "30", + "ge_buy_limit": "1000", + "examine": "A premade Pineapple Punch.", + "grand_exchange_price": "40", + "durability": null, + "name": "Premade p' punch", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "2036" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "40", + "durability": null, + "name": "Premade p' punch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2037" + }, + { + "shop_price": "30", + "ge_buy_limit": "1000", + "examine": "A premade Short Green Guy.", + "grand_exchange_price": "33", + "durability": null, + "name": "Premade sgg", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "2038" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "33", + "durability": null, + "name": "Premade sgg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2039" + }, + { + "shop_price": "30", + "ge_buy_limit": "1000", + "examine": "A Premade Wizard Blizzard.", + "grand_exchange_price": "26", + "durability": null, + "name": "Premade wiz blz'd", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "2040" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "26", + "durability": null, + "name": "Premade wiz blz'd", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2041" + }, + { + "examine": "This cocktail is just missing those little finishing touches.", + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2042" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2043" + }, + { + "examine": "This cocktail is just missing those little finishing touches.", + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2044" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2045" + }, + { + "examine": "This cocktail is just missing those little finishing touches.", + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2046" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2047" + }, + { + "shop_price": "28", + "ge_buy_limit": "1000", + "examine": "A fresh healthy fruit mix.", + "grand_exchange_price": "285", + "durability": null, + "name": "Pineapple punch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2048" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "285", + "durability": null, + "name": "Pineapple punch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2049" + }, + { + "examine": "This cocktail is just missing those little finishing touches.", + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2050" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2051" + }, + { + "examine": "This cocktail is just missing those little finishing touches.", + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2052" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2053" + }, + { + "shop_price": "28", + "ge_buy_limit": "1000", + "examine": "This looks like a strange mix.", + "grand_exchange_price": "774", + "durability": null, + "name": "Wizard blizzard", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "2054" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "774", + "durability": null, + "name": "Wizard blizzard", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2055" + }, + { + "examine": "This cocktail is just missing those little finishing touches.", + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2056" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2057" + }, + { + "examine": "This cocktail is just missing those little finishing touches.", + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2058" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2059" + }, + { + "examine": "This cocktail is just missing those little finishing touches.", + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2060" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2061" + }, + { + "examine": "This cocktail is just missing those little finishing touches.", + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2062" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2063" + }, + { + "shop_price": "30", + "ge_buy_limit": "1000", + "examine": "Looks good... smells strong.", + "grand_exchange_price": "5468", + "durability": null, + "name": "Blurberry special", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2064" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "5468", + "durability": null, + "name": "Blurberry special", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2065" + }, + { + "examine": "This cocktail is just missing those little finishing touches.", + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2066" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2067" + }, + { + "examine": "This cocktail is just missing those little finishing touches.", + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2068" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2069" + }, + { + "examine": "This cocktail is just missing those little finishing touches.", + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2070" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2071" + }, + { + "examine": "This cocktail is just missing those little finishing touches.", + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2072" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2073" + }, + { + "shop_price": "28", + "ge_buy_limit": "1000", + "examine": "A warm creamy alcoholic beverage", + "grand_exchange_price": "272", + "durability": null, + "name": "Choc saturday", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "2074" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "272", + "durability": null, + "name": "Choc saturday", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2075" + }, + { + "examine": "This cocktail is just missing those little finishing touches.", + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2076" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2077" + }, + { + "examine": "This cocktail is just missing those little finishing touches.", + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2078" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2079" + }, + { + "shop_price": "28", + "ge_buy_limit": "1000", + "examine": "A Short Green Guy... looks good.", + "grand_exchange_price": "756", + "durability": null, + "name": "Short green guy", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2080" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "756", + "durability": null, + "name": "Short green guy", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2081" + }, + { + "examine": "This cocktail is just missing those little finishing touches.", + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2082" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2083" + }, + { + "shop_price": "28", + "ge_buy_limit": "1000", + "examine": "A cool refreshing fruit mix.", + "grand_exchange_price": "1802", + "durability": null, + "name": "Fruit blast", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2084" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1802", + "durability": null, + "name": "Fruit blast", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2085" + }, + { + "examine": "This cocktail is just missing those little finishing touches.", + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2086" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2087" + }, + { + "examine": "This cocktail is just missing those little finishing touches.", + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2088" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2089" + }, + { + "examine": "This cocktail is just missing those little finishing touches.", + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2090" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2091" + }, + { + "shop_price": "28", + "ge_buy_limit": "1000", + "examine": "A warm creamy alcoholic beverage", + "grand_exchange_price": "506", + "durability": null, + "name": "Drunk dragon", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2092" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "506", + "durability": null, + "name": "Drunk dragon", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2093" + }, + { + "examine": "I'm not completely sure what this contains.", + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2094" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2095" + }, + { + "examine": "I'm not completely sure what this contains.", + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2096" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2097" + }, + { + "examine": "I'm not completely sure what this contains.", + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2098" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2099" + }, + { + "examine": "I'm not completely sure what this contains.", + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2100" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2101" + }, + { + "shop_price": "2", + "ge_buy_limit": "1000", + "examine": "A common fruit, popularly used in cocktails.", + "grand_exchange_price": "86", + "durability": null, + "name": "Lemon", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "2102" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "86", + "durability": null, + "name": "Lemon", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2103" + }, + { + "ge_buy_limit": "1000", + "examine": "The not-too-surprising result of using a knife with a lemon!", + "grand_exchange_price": "29", + "durability": null, + "name": "Lemon chunks", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2104" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "29", + "durability": null, + "name": "Lemon chunks", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2105" + }, + { + "ge_buy_limit": "1000", + "examine": "The not-too-surprising result of using a knife with a lemon!", + "grand_exchange_price": "16", + "durability": null, + "name": "Lemon slices", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2106" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "16", + "durability": null, + "name": "Lemon slices", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2107" + }, + { + "shop_price": "70", + "ge_buy_limit": "1000", + "examine": "A common fruit.", + "grand_exchange_price": "930", + "durability": null, + "name": "Orange", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "2108" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "930", + "durability": null, + "name": "Orange", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2109" + }, + { + "ge_buy_limit": "1000", + "examine": "Fresh chunks of orange.", + "grand_exchange_price": "46", + "durability": null, + "name": "Orange chunks", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2110" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "46", + "durability": null, + "name": "Orange chunks", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2111" + }, + { + "ge_buy_limit": "1000", + "examine": "Fresh orange slices.", + "grand_exchange_price": "163", + "durability": null, + "name": "Orange slices", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2112" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "163", + "durability": null, + "name": "Orange slices", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2113" + }, + { + "shop_price": "2", + "ge_buy_limit": "1000", + "examine": "It can be cut up into something more manageable with a knife.", + "grand_exchange_price": "45", + "durability": null, + "name": "Pineapple", + "tradeable": "true", + "weight": "0.15", + "archery_ticket_price": "0", + "id": "2114" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "45", + "durability": null, + "name": "Pineapple", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2115" + }, + { + "ge_buy_limit": "1000", + "examine": "Fresh chunks of pineapple.", + "grand_exchange_price": "86", + "durability": null, + "name": "Pineapple chunks", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2116" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "86", + "durability": null, + "name": "Pineapple chunks", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2117" + }, + { + "ge_buy_limit": "1000", + "examine": "The not-too-surprising result of using a knife with a pineapple!", + "grand_exchange_price": "25", + "durability": null, + "name": "Pineapple ring", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2118" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "25", + "durability": null, + "name": "Pineapple ring", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2119" + }, + { + "shop_price": "2", + "ge_buy_limit": "1000", + "examine": "A common fruit, popularly used in cocktails.", + "grand_exchange_price": "78", + "durability": null, + "name": "Lime", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "2120" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "78", + "durability": null, + "name": "Lime", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2121" + }, + { + "ge_buy_limit": "1000", + "examine": "Fresh chunks of lime.", + "grand_exchange_price": "16", + "durability": null, + "name": "Lime chunks", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2122" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "16", + "durability": null, + "name": "Lime chunks", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2123" + }, + { + "ge_buy_limit": "1000", + "examine": "The not-too-surprising result of using a knife with a lime!", + "grand_exchange_price": "25", + "durability": null, + "name": "Lime slices", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2124" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "25", + "durability": null, + "name": "Lime slices", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2125" + }, + { + "shop_price": "10", + "ge_buy_limit": "10000", + "examine": "Some rather pretty blue berries picked from a dwellberry bush.", + "grand_exchange_price": "144", + "durability": null, + "name": "Dwellberries", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2126" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "144", + "durability": null, + "name": "Dwellberries", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2127" + }, + { + "shop_price": "2", + "ge_buy_limit": "1000", + "examine": "A common ingredient in gnome cuisine.", + "grand_exchange_price": "275", + "durability": null, + "name": "Equa leaves", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2128" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "275", + "durability": null, + "name": "Equa leaves", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2129" + }, + { + "shop_price": "2", + "ge_buy_limit": "10000", + "examine": "Fresh cream.", + "grand_exchange_price": "58", + "durability": null, + "name": "Pot of cream", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "2130" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "58", + "durability": null, + "name": "Pot of cream", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2131" + }, + { + "shop_price": "58", + "ge_buy_limit": "1000", + "examine": "I need to cook this first.", + "grand_exchange_price": "282", + "durability": null, + "name": "Raw beef", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "2132" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "282", + "durability": null, + "name": "Raw beef", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2133" + }, + { + "shop_price": "1", + "ge_buy_limit": "1000", + "examine": "I need to cook this first.", + "grand_exchange_price": "85", + "durability": null, + "name": "Raw rat meat", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "2134" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "85", + "durability": null, + "name": "Raw rat meat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2135" + }, + { + "shop_price": "8", + "ge_buy_limit": "1000", + "examine": "I need to cook this first.", + "grand_exchange_price": "307", + "durability": null, + "name": "Raw bear meat", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "2136" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "307", + "durability": null, + "name": "Raw bear meat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2137" + }, + { + "shop_price": "60", + "ge_buy_limit": "1000", + "examine": "I need to cook this first.", + "grand_exchange_price": "386", + "durability": null, + "name": "Raw chicken", + "tradeable": "true", + "weight": "0.15", + "archery_ticket_price": "0", + "id": "2138" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "386", + "durability": null, + "name": "Raw chicken", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2139" + }, + { + "shop_price": "5", + "ge_buy_limit": "1000", + "examine": "Mmm this looks tasty.", + "grand_exchange_price": "70", + "durability": null, + "name": "Cooked chicken", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "2140" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "70", + "durability": null, + "name": "Cooked chicken", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2141" + }, + { + "shop_price": "5", + "ge_buy_limit": "1000", + "examine": "Mmm this looks tasty.", + "grand_exchange_price": "111", + "durability": null, + "name": "Cooked meat", + "tradeable": "true", + "weight": "0.25", + "archery_ticket_price": "0", + "id": "2142" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "111", + "durability": null, + "name": "Cooked meat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2143" + }, + { + "durability": null, + "name": "Burnt chicken", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2145" + }, + { + "examine": "Oh dear, it's totally burnt!", + "durability": null, + "name": "Burnt meat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2146" + }, + { + "durability": null, + "name": "Burnt meat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2147" + }, + { + "examine": "A very strange eel.", + "durability": null, + "name": "Raw lava eel", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "2148" + }, + { + "examine": "Strange, it looks cooler now it's been cooked.", + "durability": null, + "name": "Lava eel", + "weight": "0.15", + "archery_ticket_price": "0", + "id": "2149" + }, + { + "ge_buy_limit": "10000", + "examine": "A slippery little blighter.", + "grand_exchange_price": "750", + "durability": null, + "name": "Swamp toad", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "2150" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "750", + "durability": null, + "name": "Swamp toad", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2151" + }, + { + "ge_buy_limit": "1000", + "examine": "They're a gnome delicacy apparently.", + "grand_exchange_price": "661", + "durability": null, + "name": "Toad's legs", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "2152" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "661", + "durability": null, + "name": "Toad's legs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2153" + }, + { + "examine": "They're a gnome delicacy apparently.", + "durability": null, + "name": "Picture", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "2154" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2155" + }, + { + "examine": "They're a gnome delicacy apparently.", + "durability": null, + "name": "Spicy toad's legs", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "2156" + }, + { + "durability": null, + "name": "Spicy toad's legs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2157" + }, + { + "examine": "They're a gnome delicacy apparently.", + "durability": null, + "name": "Seasoned legs", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "2158" + }, + { + "durability": null, + "name": "Seasoned legs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2159" + }, + { + "examine": "They're a gnome delicacy apparently.", + "durability": null, + "name": "Spicy worm", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "2160" + }, + { + "durability": null, + "name": "Spicy worm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2161" + }, + { + "ge_buy_limit": "100", + "examine": "They're a gnome delicacy apparently.", + "grand_exchange_price": "24", + "durability": null, + "name": "King worm", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "2162" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "24", + "durability": null, + "name": "King worm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2163" + }, + { + "shop_price": "1", + "examine": "A deep tin used to make gnome battas in.", + "durability": null, + "name": "Batta tin", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "2164" + }, + { + "shop_price": "10", + "examine": "A shallow tray used to make crunchies in.", + "durability": null, + "name": "Crunchy tray", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "2165" + }, + { + "shop_price": "10", + "examine": "A large ovenproof bowl.", + "durability": null, + "name": "Gnomebowl mould", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "2166" + }, + { + "examine": "Aluft Gianne's favourite dishes.", + "durability": null, + "name": "Gianne's cook book", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "2167" + }, + { + "durability": null, + "name": "Gianne's cook book", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2168" + }, + { + "shop_price": "2", + "ge_buy_limit": "1000", + "examine": "It's Aluft Gianne's secret mix of spices.", + "grand_exchange_price": "28", + "durability": null, + "name": "Gnome spice", + "tradeable": "true", + "weight": "0.14", + "archery_ticket_price": "0", + "id": "2169" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "28", + "durability": null, + "name": "Gnome spice", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2170" + }, + { + "shop_price": "2", + "ge_buy_limit": "1000", + "examine": "It's made from a secret recipe.", + "grand_exchange_price": "13", + "durability": null, + "name": "Gianne dough", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "2171" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "13", + "durability": null, + "name": "Gianne dough", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2172" + }, + { + "examine": "This gnome bowl doesn't look very appetizing.", + "durability": null, + "name": "Picture", + "weight": "1", + "archery_ticket_price": "0", + "id": "2173" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2174" + }, + { + "durability": null, + "name": "Burnt gnomebowl", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2176" + }, + { + "examine": "This gnomebowl is in the early stages of preparation.", + "durability": null, + "name": "Half baked bowl", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "2177" + }, + { + "examine": "This gnomebowl needs cooking.", + "durability": null, + "name": "Raw gnomebowl", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2178" + }, + { + "examine": "This unfinished XX needs YY.", + "durability": null, + "name": "Picture", + "archery_ticket_price": "0", + "id": "2179" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2180" + }, + { + "examine": "This unfinished XX needs YY.", + "durability": null, + "name": "Picture", + "archery_ticket_price": "0", + "id": "2181" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2182" + }, + { + "examine": "This unfinished XX needs YY.", + "durability": null, + "name": "Picture", + "archery_ticket_price": "0", + "id": "2183" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2184" + }, + { + "shop_price": "450", + "ge_buy_limit": "1000", + "examine": "Full of creamy, chocolately goodness.", + "grand_exchange_price": "4400", + "durability": null, + "name": "Chocolate bomb", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "2185" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "4400", + "durability": null, + "name": "Chocolate bomb", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2186" + }, + { + "ge_buy_limit": "1000", + "examine": "It actually smells quite good.", + "grand_exchange_price": "2321", + "durability": null, + "name": "Tangled toads' legs", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "2187" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "2321", + "durability": null, + "name": "Tangled toads' legs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2188" + }, + { + "examine": "This unfinished XX needs YY.", + "durability": null, + "name": "Picture", + "archery_ticket_price": "0", + "id": "2189" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2190" + }, + { + "ge_buy_limit": "1000", + "examine": "It actually smells quite good.", + "grand_exchange_price": "454", + "durability": null, + "name": "Worm hole", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2191" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "454", + "durability": null, + "name": "Worm hole", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2192" + }, + { + "examine": "This unfinished XX needs YY.", + "durability": null, + "name": "Picture", + "archery_ticket_price": "0", + "id": "2193" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2194" + }, + { + "ge_buy_limit": "1000", + "examine": "This looks pretty healthy.", + "grand_exchange_price": "481", + "durability": null, + "name": "Veg ball", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2195" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "481", + "durability": null, + "name": "Veg ball", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2196" + }, + { + "examine": "These crunchies don't look very appetising.", + "durability": null, + "name": "Odd crunchies", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2197" + }, + { + "durability": null, + "name": "Odd crunchies", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2198" + }, + { + "durability": null, + "name": "Burnt crunchies", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2200" + }, + { + "examine": "This crunchy is in the early stages of preparation.", + "durability": null, + "name": "Half baked crunchy", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2201" + }, + { + "ge_buy_limit": "1000", + "examine": "These crunchies need cooking.", + "grand_exchange_price": "163", + "durability": null, + "name": "Raw crunchies", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2202" + }, + { + "examine": "This XX crunchy needs garnishing with YY.", + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2203" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2204" + }, + { + "shop_price": "80", + "ge_buy_limit": "1000", + "examine": "It actually smells quite good.", + "grand_exchange_price": "255", + "durability": null, + "name": "Worm crunchies", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2205" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "255", + "durability": null, + "name": "Worm crunchies", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2206" + }, + { + "examine": "This XX crunchy needs garnishing with YY.", + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2207" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2208" + }, + { + "shop_price": "70", + "ge_buy_limit": "1000", + "examine": "Yum... smells good.", + "grand_exchange_price": "816", + "durability": null, + "name": "Chocchip crunchies", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2209" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "816", + "durability": null, + "name": "Chocchip crunchies", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2210" + }, + { + "examine": "This XX crunchy needs garnishing with YY.", + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2211" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2212" + }, + { + "shop_price": "70", + "ge_buy_limit": "1000", + "examine": "Yum...smells spicy.", + "grand_exchange_price": "101", + "durability": null, + "name": "Spicy crunchies", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2213" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "101", + "durability": null, + "name": "Spicy crunchies", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2214" + }, + { + "examine": "This XX crunchy needs garnishing with YY.", + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2215" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2216" + }, + { + "ge_buy_limit": "1000", + "examine": "It actually smells quite good.", + "grand_exchange_price": "1228", + "durability": null, + "name": "Toad crunchies", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "2217" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1228", + "durability": null, + "name": "Toad crunchies", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2218" + }, + { + "ge_buy_limit": "1000", + "examine": "A premade Worm Batta.", + "grand_exchange_price": "130", + "durability": null, + "name": "Premade w'm batta", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "2219" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "130", + "durability": null, + "name": "Premade w'm batta", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2220" + }, + { + "ge_buy_limit": "1000", + "examine": "A Premade Toad Batta.", + "grand_exchange_price": "127", + "durability": null, + "name": "Premade t'd batta", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "2221" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "127", + "durability": null, + "name": "Premade t'd batta", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2222" + }, + { + "ge_buy_limit": "1000", + "examine": "A Premade Cheese and Tomato Batta.", + "grand_exchange_price": "137", + "durability": null, + "name": "Premade c+t batta", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "2223" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "137", + "durability": null, + "name": "Premade c+t batta", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2224" + }, + { + "ge_buy_limit": "1000", + "examine": "A premade Fruit Batta.", + "grand_exchange_price": "131", + "durability": null, + "name": "Premade fr't batta", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "2225" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "131", + "durability": null, + "name": "Premade fr't batta", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2226" + }, + { + "ge_buy_limit": "1000", + "examine": "A Premade Vegetable Batta.", + "grand_exchange_price": "134", + "durability": null, + "name": "Premade veg batta", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "2227" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "134", + "durability": null, + "name": "Premade veg batta", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2228" + }, + { + "ge_buy_limit": "1000", + "examine": "A premade Chocolate Bomb.", + "grand_exchange_price": "1227", + "durability": null, + "name": "Premade choc bomb", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "2229" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1227", + "durability": null, + "name": "Premade choc bomb", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2230" + }, + { + "ge_buy_limit": "1000", + "examine": "A premade Tangled Toads Legs.", + "grand_exchange_price": "867", + "durability": null, + "name": "Premade ttl", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "2231" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "867", + "durability": null, + "name": "Premade ttl", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2232" + }, + { + "ge_buy_limit": "1000", + "examine": "A premade Worm Hole.", + "grand_exchange_price": "237", + "durability": null, + "name": "Premade worm hole", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "2233" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "237", + "durability": null, + "name": "Premade worm hole", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2234" + }, + { + "ge_buy_limit": "1000", + "examine": "A premade Vegetable Ball.", + "grand_exchange_price": "233", + "durability": null, + "name": "Premade veg ball", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "2235" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "233", + "durability": null, + "name": "Premade veg ball", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2236" + }, + { + "ge_buy_limit": "1000", + "examine": "Some Premade Worm Crunchies.", + "grand_exchange_price": "76", + "durability": null, + "name": "Premade w'm crun", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "2237" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "76", + "durability": null, + "name": "Premade w'm crun", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2238" + }, + { + "ge_buy_limit": "1000", + "examine": "Some Premade chocchip crunchies.", + "grand_exchange_price": "95", + "durability": null, + "name": "Premade ch' crunch", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "2239" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "95", + "durability": null, + "name": "Premade ch' crunch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2240" + }, + { + "ge_buy_limit": "1000", + "examine": "Some premade Spicy Crunchies.", + "grand_exchange_price": "103", + "durability": null, + "name": "Premade s'y crunch", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "2241" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "103", + "durability": null, + "name": "Premade s'y crunch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2242" + }, + { + "shop_price": "80", + "ge_buy_limit": "1000", + "examine": "Some premade Toad Crunchies.", + "grand_exchange_price": "43", + "durability": null, + "name": "Premade t'd crunch", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "2243" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "43", + "durability": null, + "name": "Premade t'd crunch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2244" + }, + { + "examine": "This batta doesn't look very appetising.", + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2245" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2246" + }, + { + "durability": null, + "name": "Burnt batta", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2248" + }, + { + "examine": "This gnome batta is in the early stages of preparation.", + "durability": null, + "name": "Half baked batta", + "archery_ticket_price": "0", + "id": "2249" + }, + { + "shop_price": "1", + "examine": "This gnome batta needs cooking.", + "durability": null, + "name": "Raw batta", + "archery_ticket_price": "0", + "id": "2250" + }, + { + "shop_price": "1", + "examine": "This XX batta needs garnishing with YY.", + "durability": null, + "name": "Picture", + "archery_ticket_price": "0", + "id": "2251" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2252" + }, + { + "ge_buy_limit": "1000", + "examine": "It actually smells quite good.", + "grand_exchange_price": "140", + "durability": null, + "name": "Worm batta", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2253" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "140", + "durability": null, + "name": "Worm batta", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2254" + }, + { + "shop_price": "78", + "ge_buy_limit": "1000", + "examine": "It actually smells quite good.", + "grand_exchange_price": "271", + "durability": null, + "name": "Toad batta", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "2255" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "271", + "durability": null, + "name": "Toad batta", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2256" + }, + { + "shop_price": "1", + "examine": "This XX batta needs garnishing with YY.", + "durability": null, + "name": "Picture", + "archery_ticket_price": "0", + "id": "2257" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2258" + }, + { + "ge_buy_limit": "1000", + "examine": "This smells really good.", + "grand_exchange_price": "260", + "durability": null, + "name": "Cheese+tom batta", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "2259" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "260", + "durability": null, + "name": "Cheese+tom batta", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2260" + }, + { + "shop_price": "1", + "examine": "This XX batta needs garnishing with YY.", + "durability": null, + "name": "Unfinished batta", + "archery_ticket_price": "0", + "id": "2261" + }, + { + "durability": null, + "name": "Unfinished batta", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2262" + }, + { + "shop_price": "1", + "examine": "This XX batta needs garnishing with YY.", + "durability": null, + "name": "Unfinished batta", + "archery_ticket_price": "0", + "id": "2263" + }, + { + "durability": null, + "name": "Unfinished batta", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2264" + }, + { + "shop_price": "1", + "examine": "This XX batta needs garnishing with YY.", + "durability": null, + "name": "Unfinished batta", + "archery_ticket_price": "0", + "id": "2265" + }, + { + "durability": null, + "name": "Unfinished batta", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2266" + }, + { + "shop_price": "1", + "examine": "This XX batta needs garnishing with YY.", + "durability": null, + "name": "Unfinished batta", + "archery_ticket_price": "0", + "id": "2267" + }, + { + "durability": null, + "name": "Unfinished batta", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2268" + }, + { + "shop_price": "1", + "examine": "This XX batta needs garnishing with YY.", + "durability": null, + "name": "Unfinished batta", + "archery_ticket_price": "0", + "id": "2269" + }, + { + "durability": null, + "name": "Unfinished batta", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2270" + }, + { + "shop_price": "1", + "examine": "This XX batta needs garnishing with YY.", + "durability": null, + "name": "Unfinished batta", + "archery_ticket_price": "0", + "id": "2271" + }, + { + "durability": null, + "name": "Unfinished batta", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2272" + }, + { + "shop_price": "1", + "examine": "This XX batta needs garnishing with YY.", + "durability": null, + "name": "Unfinished batta", + "archery_ticket_price": "0", + "id": "2273" + }, + { + "durability": null, + "name": "Unfinished batta", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2274" + }, + { + "shop_price": "1", + "examine": "This XX batta needs garnishing with YY.", + "durability": null, + "name": "Picture", + "archery_ticket_price": "0", + "id": "2275" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2276" + }, + { + "ge_buy_limit": "1000", + "examine": "It actually smells quite good.", + "grand_exchange_price": "303", + "durability": null, + "name": "Fruit batta", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "2277" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "303", + "durability": null, + "name": "Fruit batta", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2278" + }, + { + "shop_price": "1", + "examine": "This XX batta needs garnishing with YY.", + "durability": null, + "name": "Picture", + "archery_ticket_price": "0", + "id": "2279" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2280" + }, + { + "ge_buy_limit": "1000", + "examine": "Well... It looks healthy.", + "grand_exchange_price": "240", + "durability": null, + "name": "Vegetable batta", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "2281" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "240", + "durability": null, + "name": "Vegetable batta", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2282" + }, + { + "shop_price": "4", + "ge_buy_limit": "1000", + "examine": "I need to add some tomato next.", + "grand_exchange_price": "418", + "durability": null, + "name": "Pizza base", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "2283" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "418", + "durability": null, + "name": "Pizza base", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2284" + }, + { + "ge_buy_limit": "1000", + "examine": "I need to add some cheese next.", + "grand_exchange_price": "366", + "durability": null, + "name": "Incomplete pizza", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2285" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "366", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Incomplete pizza", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2286" + }, + { + "ge_buy_limit": "1000", + "examine": "This needs cooking.", + "grand_exchange_price": "1141", + "durability": null, + "name": "Uncooked pizza", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2287" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1141", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Uncooked pizza", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2288" + }, + { + "shop_price": "200", + "ge_buy_limit": "1000", + "examine": "A cheese and tomato pizza.", + "grand_exchange_price": "1357", + "durability": null, + "name": "Plain pizza", + "tradeable": "true", + "weight": "0.66", + "archery_ticket_price": "0", + "id": "2289" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1357", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Plain pizza", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2290" + }, + { + "shop_price": "200", + "ge_buy_limit": "1000", + "examine": "Half of this plain pizza has been eaten.", + "grand_exchange_price": "238", + "durability": null, + "name": "1/2 plain pizza", + "tradeable": "true", + "weight": "0.66", + "archery_ticket_price": "0", + "id": "2291" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "238", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "1/2 plain pizza", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2292" + }, + { + "ge_buy_limit": "1000", + "examine": "A pizza with bits of meat on it.", + "grand_exchange_price": "1012", + "durability": null, + "name": "Meat pizza", + "tradeable": "true", + "weight": "0.83", + "archery_ticket_price": "0", + "id": "2293" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1012", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Meat pizza", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2294" + }, + { + "ge_buy_limit": "1000", + "examine": "Half of this meat pizza has been eaten.", + "grand_exchange_price": "339", + "durability": null, + "name": "1/2 meat pizza", + "tradeable": "true", + "weight": "0.83", + "archery_ticket_price": "0", + "id": "2295" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "339", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "1/2 meat pizza", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2296" + }, + { + "ge_buy_limit": "1000", + "examine": "A pizza with anchovies.", + "grand_exchange_price": "1573", + "durability": null, + "name": "Anchovy pizza", + "tradeable": "true", + "weight": "0.83", + "archery_ticket_price": "0", + "id": "2297" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1573", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Anchovy pizza", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2298" + }, + { + "ge_buy_limit": "1000", + "examine": "Half of this anchovy pizza has been eaten.", + "grand_exchange_price": "44", + "durability": null, + "name": "1/2 anchovy pizza", + "tradeable": "true", + "weight": "0.83", + "archery_ticket_price": "0", + "id": "2299" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "44", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "1/2 anchovy pizza", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2300" + }, + { + "ge_buy_limit": "1000", + "examine": "A pizza with bits of pineapple on it.", + "grand_exchange_price": "1469", + "durability": null, + "name": "Pineapple pizza", + "tradeable": "true", + "weight": "0.83", + "archery_ticket_price": "0", + "id": "2301" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1469", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Pineapple pizza", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2302" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "156", + "examine": "Half of this pineapple pizza has been eaten.", + "durability": null, + "name": "1/2 p'apple pizza", + "archery_ticket_price": "0", + "id": "2303" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "156", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "1/2 p'apple pizza", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2304" + }, + { + "examine": "Oh dear!", + "durability": null, + "name": "Burnt pizza", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2306" + }, + { + "ge_buy_limit": "1000", + "examine": "Some uncooked dough.", + "grand_exchange_price": "158", + "durability": null, + "name": "Bread dough", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2307" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "158", + "durability": null, + "name": "Bread dough", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2308" + }, + { + "shop_price": "24", + "ge_buy_limit": "1000", + "examine": "Nice crispy bread.", + "grand_exchange_price": "110", + "durability": null, + "name": "Bread", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "2309" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "110", + "durability": null, + "name": "Bread", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2310" + }, + { + "durability": null, + "name": "Burnt bread", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2312" + }, + { + "shop_price": "3", + "ge_buy_limit": "100", + "examine": "Deceptively pie shaped.", + "grand_exchange_price": "174", + "durability": null, + "name": "Pie dish", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "2313" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "174", + "durability": null, + "name": "Pie dish", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2314" + }, + { + "ge_buy_limit": "1000", + "examine": "I need to find a filling for this pie.", + "grand_exchange_price": "887", + "durability": null, + "name": "Pie shell", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2315" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "887", + "durability": null, + "name": "Pie shell", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2316" + }, + { + "ge_buy_limit": "1000", + "examine": "This would be much tastier cooked.", + "grand_exchange_price": "781", + "durability": null, + "name": "Uncooked apple pie", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "2317" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "781", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Uncooked apple pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2318" + }, + { + "ge_buy_limit": "1000", + "examine": "This would be much healthier cooked.", + "grand_exchange_price": "747", + "durability": null, + "name": "Uncooked meat pie", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "2319" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "747", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Uncooked meat pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2320" + }, + { + "ge_buy_limit": "1000", + "examine": "This would be much more appetising cooked.", + "grand_exchange_price": "802", + "durability": null, + "name": "Uncooked berry pie", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "2321" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "802", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Uncooked berry pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2322" + }, + { + "shop_price": "140", + "ge_buy_limit": "1000", + "examine": "Mmm Apple pie.", + "grand_exchange_price": "246", + "durability": null, + "name": "Apple pie", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "2323" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "246", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Apple pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2324" + }, + { + "ge_buy_limit": "1000", + "examine": "Looks tasty.", + "grand_exchange_price": "534", + "durability": null, + "name": "Redberry pie", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "2325" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "534", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Redberry pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2326" + }, + { + "shop_price": "16", + "ge_buy_limit": "1000", + "grand_exchange_price": "160", + "examine": "Not for vegetarians.", + "durability": null, + "name": "Meat pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2327" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "160", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Meat pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2328" + }, + { + "examine": "I think I left it on the stove too long.", + "durability": null, + "name": "Burnt pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2330" + }, + { + "shop_price": "16", + "ge_buy_limit": "1000", + "grand_exchange_price": "174", + "examine": "Half of it is suitable for vegetarians.", + "durability": null, + "name": "Half a meat pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2331" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "174", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Half a meat pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2332" + }, + { + "ge_buy_limit": "1000", + "examine": "So tasty I kept some for later.", + "grand_exchange_price": "248", + "durability": null, + "name": "Half a redberry pie", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "2333" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "248", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Half a redberry pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2334" + }, + { + "shop_price": "140", + "ge_buy_limit": "1000", + "examine": "Mmm half an apple pie.", + "grand_exchange_price": "146", + "durability": null, + "name": "Half an apple pie", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "2335" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "146", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Half an apple pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2336" + }, + { + "ge_buy_limit": "1000", + "examine": "Raw meat from the oomlie bird.", + "grand_exchange_price": "155", + "durability": null, + "name": "Raw oomlie", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "2337" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "155", + "durability": null, + "name": "Raw oomlie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2338" + }, + { + "examine": "A thick green palm leaf used by natives to cook meat.", + "durability": null, + "name": "Palm leaf", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "2339" + }, + { + "examine": "A thick green palm leaf used by natives to cook meat.", + "durability": null, + "name": "Palm leaf", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "2340" + }, + { + "ge_buy_limit": "1000", + "examine": "Oomlie meat in a palm leaf pouch. It just needs to be cooked.", + "grand_exchange_price": "814", + "durability": null, + "name": "Wrapped oomlie", + "tradeable": "true", + "weight": "0.25", + "archery_ticket_price": "0", + "id": "2341" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "814", + "durability": null, + "name": "Wrapped oomlie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2342" + }, + { + "ge_buy_limit": "1000", + "examine": "Deliciously cooked oomlie meat in a palm leaf pouch.", + "grand_exchange_price": "1126", + "durability": null, + "name": "Cooked oomlie wrap", + "tradeable": "true", + "weight": "0.25", + "archery_ticket_price": "0", + "id": "2343" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1126", + "durability": null, + "name": "Cooked oomlie wrap", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2344" + }, + { + "durability": null, + "name": "Burnt oomlie wrap", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2346" + }, + { + "shop_price": "13", + "ge_buy_limit": "1000", + "examine": "Good for hitting things!", + "grand_exchange_price": "37", + "durability": null, + "name": "Hammer", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "2347" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "37", + "durability": null, + "name": "Hammer", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2348" + }, + { + "shop_price": "10", + "ge_buy_limit": "10000", + "examine": "It's a bar of bronze.", + "grand_exchange_price": "268", + "durability": null, + "name": "Bronze bar", + "tradeable": "true", + "weight": "1.8", + "archery_ticket_price": "0", + "id": "2349" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "268", + "durability": null, + "name": "Bronze bar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2350" + }, + { + "ge_buy_limit": "10000", + "examine": "It's a bar of iron.", + "grand_exchange_price": "493", + "durability": null, + "name": "Iron bar", + "tradeable": "true", + "weight": "1.8", + "archery_ticket_price": "0", + "id": "2351" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "493", + "durability": null, + "name": "Iron bar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2352" + }, + { + "ge_buy_limit": "10000", + "examine": "It's a bar of steel.", + "grand_exchange_price": "1266", + "durability": null, + "name": "Steel bar", + "tradeable": "true", + "weight": "1.81", + "archery_ticket_price": "0", + "id": "2353" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "1266", + "durability": null, + "name": "Steel bar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2354" + }, + { + "ge_buy_limit": "10000", + "examine": "It's a bar of silver.", + "grand_exchange_price": "274", + "durability": null, + "name": "Silver bar", + "tradeable": "true", + "weight": "1.81", + "archery_ticket_price": "0", + "id": "2355" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "274", + "durability": null, + "name": "Silver bar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2356" + }, + { + "ge_buy_limit": "10000", + "examine": "It's a bar of gold.", + "grand_exchange_price": "107", + "durability": null, + "name": "Gold bar", + "tradeable": "true", + "weight": "1.81", + "archery_ticket_price": "0", + "id": "2357" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "107", + "durability": null, + "name": "Gold bar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2358" + }, + { + "shop_price": "120", + "ge_buy_limit": "10000", + "examine": "It's a bar of mithril.", + "grand_exchange_price": "1920", + "durability": null, + "name": "Mithril bar", + "tradeable": "true", + "weight": "1.6", + "archery_ticket_price": "0", + "id": "2359" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "1920", + "durability": null, + "name": "Mithril bar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2360" + }, + { + "ge_buy_limit": "10000", + "examine": "It's a bar of adamant.", + "grand_exchange_price": "3306", + "durability": null, + "name": "Adamantite bar", + "tradeable": "true", + "weight": "2.04", + "archery_ticket_price": "0", + "id": "2361" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "3306", + "durability": null, + "name": "Adamantite bar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2362" + }, + { + "ge_buy_limit": "10000", + "examine": "It's a bar of rune.", + "grand_exchange_price": "13300", + "durability": null, + "name": "Runite bar", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "2363" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "13300", + "durability": null, + "name": "Runite bar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2364" + }, + { + "examine": "It's a 'perfect' golden bar.", + "durability": null, + "name": "'perfect' gold bar", + "weight": "2", + "archery_ticket_price": "0", + "id": "2365" + }, + { + "requirements": "{13,60}", + "ge_buy_limit": "100", + "examine": "The left half of a Dragon Square Shield.", + "grand_exchange_price": "65800", + "durability": null, + "name": "Shield left half", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "2366" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "65800", + "durability": null, + "name": "Shield left half", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2367" + }, + { + "requirements": "{13,60}", + "shop_price": "750000", + "ge_buy_limit": "100", + "examine": "The right half of a dragon square shield.", + "grand_exchange_price": "743100", + "durability": null, + "name": "Shield right half", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "2368" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "743100", + "durability": null, + "name": "Shield right half", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2369" + }, + { + "shop_price": "100", + "ge_buy_limit": "5000", + "examine": "A set of studs for leather armour.", + "grand_exchange_price": "792", + "durability": null, + "name": "Steel studs", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "2370" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "792", + "durability": null, + "name": "Steel studs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2371" + }, + { + "destroy_message": "This item will likely break if you put it down, and you will have to go looking for another one.", + "examine": "An old statue of an ogre warrior.", + "durability": null, + "name": "Ogre relic", + "tradeable": "false", + "destroy": "true", + "weight": "3", + "archery_ticket_price": "0", + "id": "2372" + }, + { + "destroy_message": "This item will likely break if you put it down here and you will have to go looking for another.", + "examine": "Part of an ogre relic.", + "durability": null, + "name": "Relic part 1", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "2373" + }, + { + "destroy_message": "This item will likely break if you put it down here and you will have to go looking for another.", + "examine": "Part of an ogre relic.", + "durability": null, + "name": "Relic part 2", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "2374" + }, + { + "destroy_message": "This item will likely break if you put it down here and you will have to go looking for another.", + "examine": "Part of an ogre relic.", + "durability": null, + "name": "Relic part 3", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "2375" + }, + { + "destroy_message": "This item will likely break if you put it down here and you will have to go looking for another.", + "examine": "It's a map.", + "durability": null, + "name": "Skavid map", + "tradeable": "false", + "destroy": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "2376" + }, + { + "destroy_message": "This item will likely break if you put it down here and you will have to go looking for another.", + "examine": "Very tooth-like.", + "durability": null, + "name": "Ogre tooth", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "2377" + }, + { + "destroy_message": "This item will likely break if you put it down here and you will have to go looking for another.", + "examine": "Formerly the property of the ogre, Toban", + "durability": null, + "name": "Toban's key", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "2378" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Handy if you want to break all your teeth.", + "durability": null, + "name": "Rock cake", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "2379" + }, + { + "destroy_message": "This item will likely break if you put it down here, and you will have to go looking for another.", + "examine": "Eeeeyeeew!", + "durability": null, + "name": "Fingernails", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "2384" + }, + { + "examine": "I can't wear this old thing.", + "durability": null, + "name": "Old robe", + "weight": "1", + "archery_ticket_price": "0", + "id": "2385" + }, + { + "examine": "Looks kind of useless.", + "durability": null, + "name": "Unusual armour", + "weight": "4", + "archery_ticket_price": "0", + "id": "2386" + }, + { + "examine": "Pointy.", + "attack_audios": "2517,2517,2500,2517", + "durability": null, + "name": "Damaged dagger", + "archery_ticket_price": "0", + "id": "2387" + }, + { + "examine": "Useless as an eye patch.", + "durability": null, + "name": "Tattered eye patch", + "archery_ticket_price": "0", + "id": "2388" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "shop_price": "5", + "examine": "An empty glass vial.", + "grand_exchange_price": "1", + "durability": null, + "name": "Vial", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2389" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "shop_price": "5", + "examine": "An empty glass vial.", + "grand_exchange_price": "1", + "durability": null, + "name": "Vial", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2390" + }, + { + "ge_buy_limit": "100", + "examine": "Let's see it fly, now!", + "grand_exchange_price": "350", + "durability": null, + "name": "Ground bat bones", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "2391" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "350", + "durability": null, + "name": "Ground bat bones", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2392" + }, + { + "destroy_message": "This item will likely break if you put it down here and you will have to go looking for another.", + "examine": "It's a stolen bar of gold.", + "durability": null, + "name": "Toban's gold", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "2393" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "This is meant to be good for spots.", + "grand_exchange_price": "157", + "durability": null, + "name": "Potion", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2394" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A dangerous magical liquid.", + "durability": null, + "name": "Magic ogre potion", + "archery_ticket_price": "0", + "id": "2395", + "equipment_slot": "3" + }, + { + "examine": "A spell is written on this parchment.", + "durability": null, + "name": "Spell scroll", + "archery_ticket_price": "0", + "id": "2396" + }, + { + "examine": "A tattered old robe.", + "durability": null, + "name": "Shaman robe", + "weight": "2", + "archery_ticket_price": "0", + "id": "2397" + }, + { + "examine": "Deadly.", + "durability": null, + "name": "Cave nightshade", + "archery_ticket_price": "0", + "id": "2398" + }, + { + "turn90cw_anim": "821", + "examine": "The magical sword 'Silverlight'. / The magical sword 'Silverlight', stained black with mushroom ink. (during Shadow of the Storm)", + "walk_anim": "819", + "durability": null, + "weight": "1.8", + "turn90ccw_anim": "822", + "attack_speed": "5", + "weapon_interface": "6", + "turn180_anim": "820", + "render_anim": "1", + "defence_anim": "388", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "stand_anim": "808", + "name": "Silverlight", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "2402", + "stand_turn_anim": "823", + "bonuses": "9,14,-2,0,0,0,3,2,1,0,0,12,0,0,0" + }, + { + "examine": "Scroll containing a powerful enchantment of restoration.", + "durability": null, + "name": "Hazeel scroll", + "weight": "1", + "archery_ticket_price": "0", + "id": "2403" + }, + { + "remove_sleeves": "true", + "examine": "Decorative armour; an heirloom of the Carnillean family.", + "durability": null, + "name": "Carnillean armour", + "weight": "9", + "archery_ticket_price": "0", + "id": "2405", + "bonuses": "0,0,0,0,0,20,14,8,0,0,5,0,0,0,0", + "equipment_slot": "4" + }, + { + "examine": "A sign of my commitment to Hazeel.", + "durability": null, + "name": "Hazeel's mark", + "archery_ticket_price": "0", + "id": "2406", + "equipment_slot": "2" + }, + { + "examine": "A child's ball.", + "durability": null, + "name": "Ball", + "archery_ticket_price": "0", + "id": "2407" + }, + { + "examine": "A key to the Witch's house's front door. (Witch's House)", + "durability": null, + "name": "Door key", + "archery_ticket_price": "0", + "id": "2409" + }, + { + "examine": "A very attractive magnet.", + "durability": null, + "name": "Magnet", + "archery_ticket_price": "0", + "id": "2410" + }, + { + "examine": "A cape from the almighty god Saradomin.", + "durability": null, + "name": "Saradomin cape", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "2412", + "bonuses": "0,0,0,10,0,1,1,2,10,0,5,0,0,0,0", + "equipment_slot": "1" + }, + { + "examine": "A cape from the almighty god Guthix.", + "durability": null, + "name": "Guthix cape", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "2413", + "bonuses": "0,0,0,10,0,1,1,2,10,0,5,0,0,0,0", + "equipment_slot": "1" + }, + { + "examine": "A cape from the almighty god Zamorak.", + "durability": null, + "name": "Zamorak cape", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "2414", + "bonuses": "0,0,0,10,0,1,1,2,10,0,5,0,0,0,0", + "equipment_slot": "1" + }, + { + "shop_price": "80000", + "examine": "A magical staff imbued with the power of Saradomin.", + "durability": null, + "weight": "2.2", + "attack_speed": "4", + "weapon_interface": "1", + "equip_audio": "2247", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "attack_audios": "2555,0,0,0", + "name": "Saradomin staff", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "2415", + "bonuses": "-1,-1,6,6,0,2,3,1,6,0,0,2,0,0,0" + }, + { + "shop_price": "80000", + "examine": "A magical staff imbued with the power of Guthix.", + "durability": null, + "weight": "2", + "attack_speed": "4", + "weapon_interface": "1", + "equip_audio": "2247", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "attack_audios": "2555,0,0,0", + "name": "Guthix staff", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "2416", + "bonuses": "-1,-1,6,6,0,2,3,1,6,0,0,2,0,0,0" + }, + { + "shop_price": "80000", + "turn90cw_anim": "1207", + "examine": "A magical staff imbued with the power of Zamorak.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "attack_speed": "4", + "weapon_interface": "1", + "turn180_anim": "1206", + "equip_audio": "2247", + "defence_anim": "420", + "render_anim": "28", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "stand_anim": "813", + "attack_audios": "2555,0,0,0", + "tradeable": "false", + "name": "Zamorak staff", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "2417", + "stand_turn_anim": "1209", + "bonuses": "-1,-1,6,6,0,2,3,1,6,0,0,2,0,0,0" + }, + { + "examine": "A heavy key made of bronze. (Prince Ali Rescue).", + "durability": null, + "name": "Bronze key", + "archery_ticket_price": "0", + "id": "2418" + }, + { + "examine": "A grey woollen wig.", + "durability": null, + "name": "Wig", + "archery_ticket_price": "0", + "id": "2419" + }, + { + "examine": "A grey woollen wig.", + "durability": null, + "name": "Wig", + "archery_ticket_price": "0", + "id": "2421" + }, + { + "lendable": "true", + "examine": "A nice hat from a cracker.", + "grand_exchange_price": "2147483647", + "durability": null, + "name": "Blue partyhat", + "archery_ticket_price": "0", + "id": "2422" + }, + { + "examine": "Imprint of a key in a lump of clay.", + "durability": null, + "name": "Key print", + "archery_ticket_price": "0", + "id": "2423" + }, + { + "examine": "A bottle of skin coloured paste.", + "durability": null, + "name": "Paste", + "archery_ticket_price": "0", + "id": "2424" + }, + { + "attack_audios": "2704,0,0,0", + "durability": null, + "name": "Picture", + "archery_ticket_price": "0", + "id": "2425" + }, + { + "durability": null, + "name": "Burnt oomlie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2427" + }, + { + "shop_price": "8002", + "ge_buy_limit": "100", + "examine": "4 doses of Attack potion.", + "grand_exchange_price": "275", + "durability": null, + "name": "Attack potion(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2428" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "275", + "durability": null, + "name": "Attack potion(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2429" + }, + { + "shop_price": "139", + "ge_buy_limit": "100", + "examine": "4 doses of restore potion.", + "grand_exchange_price": "101", + "durability": null, + "name": "Restore potion(4)", + "tradeable": "true", + "weight": "0.03", + "archery_ticket_price": "0", + "id": "2430" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "101", + "durability": null, + "name": "Restore potion(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2431" + }, + { + "shop_price": "7832", + "ge_buy_limit": "100", + "examine": "4 doses of Defence Potion.", + "grand_exchange_price": "448", + "durability": null, + "name": "Defence potion(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2432" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "448", + "durability": null, + "name": "Defence potion(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2433" + }, + { + "ge_buy_limit": "100", + "examine": "4 doses of Prayer restore potion.", + "grand_exchange_price": "5687", + "durability": null, + "name": "Prayer potion(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2434" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "5687", + "durability": null, + "name": "Prayer potion(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2435" + }, + { + "shop_price": "8000", + "ge_buy_limit": "1000", + "examine": "4 doses of super Attack potion.", + "grand_exchange_price": "898", + "durability": null, + "name": "Super attack(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2436" + }, + { + "shop_price": "8000", + "ge_buy_limit": "1000", + "grand_exchange_price": "898", + "durability": null, + "name": "Super attack(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2437" + }, + { + "ge_buy_limit": "100", + "examine": "4 doses of Fishing potion.", + "grand_exchange_price": "73", + "durability": null, + "name": "Fishing potion(4)", + "tradeable": "true", + "weight": "0.03", + "archery_ticket_price": "0", + "id": "2438" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "73", + "durability": null, + "name": "Fishing potion(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2439" + }, + { + "shop_price": "8000", + "ge_buy_limit": "1000", + "examine": "4 doses of super Strength potion.", + "grand_exchange_price": "2278", + "durability": null, + "name": "Super strength(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2440" + }, + { + "shop_price": "8000", + "ge_buy_limit": "1000", + "grand_exchange_price": "2278", + "durability": null, + "name": "Super strength(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2441" + }, + { + "shop_price": "7000", + "ge_buy_limit": "1000", + "examine": "4 doses of super Defence potion.", + "grand_exchange_price": "153", + "durability": null, + "name": "Super defence(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2442" + }, + { + "shop_price": "7000", + "ge_buy_limit": "1000", + "grand_exchange_price": "153", + "durability": null, + "name": "Super defence(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2443" + }, + { + "ge_buy_limit": "1000", + "examine": "4 doses of ranging potion.", + "grand_exchange_price": "8317", + "durability": null, + "name": "Ranging potion(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2444" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "8317", + "durability": null, + "name": "Ranging potion(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2445" + }, + { + "shop_price": "375", + "ge_buy_limit": "1000", + "examine": "4 doses of antipoison potion.", + "grand_exchange_price": "1624", + "durability": null, + "name": "Antipoison(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2446" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1624", + "durability": null, + "name": "Antipoison(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2447" + }, + { + "ge_buy_limit": "1000", + "examine": "4 doses of super anti poison potion.", + "grand_exchange_price": "1062", + "durability": null, + "name": "Super antipoison(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2448" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1062", + "durability": null, + "name": "Super antipoison(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2449" + }, + { + "ge_buy_limit": "1000", + "examine": "4 doses of Zamorak brew.", + "grand_exchange_price": "2838", + "durability": null, + "name": "Zamorak brew(4)", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "2450" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "2838", + "durability": null, + "name": "Zamorak brew(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2451" + }, + { + "ge_buy_limit": "100", + "examine": "4 doses of anti-firebreath potion.", + "grand_exchange_price": "4743", + "durability": null, + "name": "Antifire potion(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2452" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "4743", + "durability": null, + "name": "Antifire potion(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2453" + }, + { + "ge_buy_limit": "100", + "examine": "3 doses of anti-firebreath potion.", + "grand_exchange_price": "3518", + "durability": null, + "name": "Antifire potion(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2454" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3518", + "durability": null, + "name": "Antifire potion(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2455" + }, + { + "ge_buy_limit": "100", + "examine": "2 doses of anti-firebreath potion.", + "grand_exchange_price": "2291", + "durability": null, + "name": "Antifire potion(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2456" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2291", + "durability": null, + "name": "Antifire potion(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2457" + }, + { + "ge_buy_limit": "100", + "examine": "1 dose of anti-firebreath potion.", + "grand_exchange_price": "1099", + "durability": null, + "name": "Antifire potion(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2458" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1099", + "durability": null, + "name": "Antifire potion(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2459" + }, + { + "shop_price": "15", + "ge_buy_limit": "100", + "examine": "A posy of flowers.", + "durability": null, + "weight": "0.02", + "attack_speed": "4", + "weapon_interface": "12", + "defence_anim": "403", + "equipment_slot": "3", + "attack_anims": "381,381,381,381", + "fun_weapon": "true", + "grand_exchange_price": "704", + "attack_audios": "2566", + "name": "Flowers", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2460", + "bonuses": "-100,-100,-50,0,0,0,0,0,0,0,0,-10,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "704", + "durability": null, + "name": "Flowers", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2461" + }, + { + "shop_price": "15", + "ge_buy_limit": "100", + "examine": "A posy of flowers.", + "durability": null, + "weight": "0.02", + "attack_speed": "4", + "weapon_interface": "12", + "defence_anim": "403", + "equipment_slot": "3", + "attack_anims": "381,381,381,381", + "fun_weapon": "true", + "grand_exchange_price": "704", + "attack_audios": "2566", + "name": "Flowers", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2462", + "bonuses": "-100,-100,-50,0,0,0,0,0,0,0,0,-10,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "704", + "durability": null, + "name": "Flowers", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2463" + }, + { + "shop_price": "15", + "ge_buy_limit": "100", + "examine": "A posy of flowers.", + "durability": null, + "weight": "0.02", + "attack_speed": "4", + "weapon_interface": "12", + "defence_anim": "403", + "equipment_slot": "3", + "attack_anims": "381,381,381,381", + "fun_weapon": "true", + "grand_exchange_price": "638", + "attack_audios": "2566", + "name": "Flowers", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2464", + "bonuses": "-100,-100,-50,0,0,0,0,0,0,0,0,-10,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "638", + "durability": null, + "name": "Flowers", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2465" + }, + { + "shop_price": "15", + "ge_buy_limit": "100", + "examine": "A posy of flowers.", + "durability": null, + "weight": "0.02", + "attack_speed": "4", + "weapon_interface": "12", + "defence_anim": "403", + "equipment_slot": "3", + "attack_anims": "381,381,381,381", + "fun_weapon": "true", + "grand_exchange_price": "629", + "attack_audios": "2566", + "name": "Flowers", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2466", + "bonuses": "-100,-100,-50,0,0,0,0,0,0,0,0,-10,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "629", + "durability": null, + "name": "Flowers", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2467" + }, + { + "shop_price": "15", + "ge_buy_limit": "100", + "examine": "A posy of flowers.", + "durability": null, + "weight": "0.02", + "attack_speed": "4", + "weapon_interface": "12", + "defence_anim": "403", + "equipment_slot": "3", + "attack_anims": "381,381,381,381", + "fun_weapon": "true", + "grand_exchange_price": "639", + "attack_audios": "2566", + "name": "Flowers", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2468", + "bonuses": "-100,-100,-50,0,0,0,0,0,0,0,0,-10,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "639", + "durability": null, + "name": "Flowers", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2469" + }, + { + "shop_price": "15", + "ge_buy_limit": "100", + "examine": "A posy of flowers.", + "durability": null, + "weight": "0.02", + "attack_speed": "4", + "weapon_interface": "12", + "defence_anim": "403", + "equipment_slot": "3", + "attack_anims": "381,381,381,381", + "fun_weapon": "true", + "grand_exchange_price": "613", + "attack_audios": "2566", + "name": "Flowers", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2470", + "bonuses": "-100,-100,-50,0,0,0,0,0,0,0,0,-10,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "613", + "durability": null, + "name": "Flowers", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2471" + }, + { + "shop_price": "15", + "ge_buy_limit": "100", + "examine": "A posy of flowers.", + "durability": null, + "weight": "0.02", + "attack_speed": "4", + "weapon_interface": "12", + "defence_anim": "403", + "equipment_slot": "3", + "attack_anims": "381,381,381,381", + "fun_weapon": "true", + "grand_exchange_price": "711", + "attack_audios": "2566", + "name": "Flowers", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2472", + "bonuses": "-100,-100,-50,0,0,0,0,0,0,0,0,-10,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "711", + "durability": null, + "name": "Flowers", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2473" + }, + { + "shop_price": "15", + "ge_buy_limit": "100", + "examine": "A posy of flowers.", + "durability": null, + "weight": "0.02", + "attack_speed": "4", + "weapon_interface": "12", + "defence_anim": "403", + "equipment_slot": "3", + "attack_anims": "381,381,381,381", + "fun_weapon": "true", + "grand_exchange_price": "48700", + "attack_audios": "2566", + "name": "Flowers", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2474", + "bonuses": "-100,-100,-50,0,0,0,0,0,0,0,0,-10,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "48700", + "durability": null, + "name": "Flowers", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2475" + }, + { + "shop_price": "15", + "ge_buy_limit": "100", + "examine": "A posy of flowers.", + "durability": null, + "weight": "0.02", + "attack_speed": "4", + "weapon_interface": "12", + "defence_anim": "403", + "equipment_slot": "3", + "attack_anims": "381,381,381,381", + "fun_weapon": "true", + "grand_exchange_price": "5975", + "attack_audios": "2566", + "name": "Flowers", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2476", + "bonuses": "-100,-100,-50,0,0,0,0,0,0,0,0,-10,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "5975", + "durability": null, + "name": "Flowers", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2477" + }, + { + "ge_buy_limit": "10000", + "examine": "A fresh herb.", + "grand_exchange_price": "7274", + "durability": null, + "name": "Clean lantadyme", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2481" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "7274", + "durability": null, + "name": "Clean lantadyme", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2482" + }, + { + "ge_buy_limit": "100", + "examine": "I need another ingredient to finish this lantadyme potion.", + "grand_exchange_price": "6940", + "durability": null, + "name": "Lantadyme potion(unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2483" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "6940", + "durability": null, + "name": "Lantadyme potion(unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2484" + }, + { + "requirements": "{15,67}", + "ge_buy_limit": "10000", + "examine": "I need to clean this herb before I can use it.", + "grand_exchange_price": "900", + "durability": null, + "name": "Grimy lantadyme", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2485" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "7210", + "durability": null, + "name": "Grimy lantadyme", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2486" + }, + { + "requirements": "{4,50}", + "ge_buy_limit": "5000", + "examine": "Made from 100% real dragonhide.", + "durability": null, + "weight": "0.2", + "equip_audio": "2241", + "equipment_slot": "9", + "lendable": "true", + "grand_exchange_price": "1705", + "name": "Blue d'hide vamb", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2487", + "bonuses": "0,0,0,-10,9,4,3,5,4,0,4,0,0,0,0" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "1705", + "durability": null, + "name": "Blue d'hide vamb", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2488" + }, + { + "requirements": "{4,60}", + "ge_buy_limit": "5000", + "examine": "Vambraces made from 100% real dragonhide.", + "durability": null, + "weight": "0.25", + "equip_audio": "2241", + "equipment_slot": "9", + "lendable": "true", + "grand_exchange_price": "2046", + "name": "Red d'hide vamb", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2489", + "bonuses": "0,0,0,-10,10,5,4,6,6,0,5,0,0,0,0" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "2046", + "durability": null, + "name": "Red d'hide vamb", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2490" + }, + { + "requirements": "{4,70}", + "ge_buy_limit": "5000", + "examine": "Vambraces made from 100% real dragonhide.", + "durability": null, + "weight": "0.25", + "equip_audio": "2241", + "equipment_slot": "9", + "lendable": "true", + "grand_exchange_price": "2506", + "name": "Black d'hide vamb", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2491", + "bonuses": "0,0,0,-10,11,6,5,7,8,0,6,0,0,0,0" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "2506", + "durability": null, + "name": "Black d'hide vamb", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2492" + }, + { + "requirements": "{4,50}", + "ge_buy_limit": "5000", + "examine": "Made from 100% real dragonhide.", + "durability": null, + "weight": "5.4", + "absorb": "0,5,2", + "equip_audio": "2241", + "equipment_slot": "7", + "lendable": "true", + "grand_exchange_price": "2504", + "name": "Blue d'hide chaps", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2493", + "bonuses": "0,0,0,-10,11,25,19,27,14,25,20,0,0,0,0" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "2504", + "durability": null, + "name": "Blue d'hide chaps", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2494" + }, + { + "requirements": "{4,60}", + "ge_buy_limit": "5000", + "examine": "Made from 100% real dragonhide.", + "durability": null, + "weight": "5.4", + "absorb": "0,6,3", + "equip_audio": "2241", + "equipment_slot": "7", + "lendable": "true", + "grand_exchange_price": "3142", + "name": "Red d'hide chaps", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2495", + "bonuses": "0,0,0,-10,14,28,22,30,20,28,25,0,0,0,0" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "3142", + "durability": null, + "name": "Red d'hide chaps", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2496" + }, + { + "requirements": "{4,70}", + "ge_buy_limit": "5000", + "examine": "Made from 100% real dragonhide.", + "durability": null, + "weight": "5.4", + "absorb": "0,7,3", + "equip_audio": "2241", + "equipment_slot": "7", + "lendable": "true", + "grand_exchange_price": "4744", + "name": "Black d'hide chaps", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2497", + "bonuses": "0,0,0,-10,17,31,25,33,28,31,30,0,0,0,0" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "4744", + "durability": null, + "name": "Black d'hide chaps", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2498" + }, + { + "requirements": "{1,40}-{4,50}", + "ge_buy_limit": "5000", + "examine": "Made from 100% real dragonhide.", + "durability": null, + "weight": "6.8", + "absorb": "0,6,3", + "equip_audio": "2241", + "equipment_slot": "4", + "lendable": "true", + "grand_exchange_price": "5420", + "name": "Blue d'hide body", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2499", + "bonuses": "0,0,0,-15,20,45,37,50,30,45,45,0,0,0,0" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "5420", + "durability": null, + "name": "Blue d'hide body", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2500" + }, + { + "requirements": "{1,40}-{4,60}", + "ge_buy_limit": "5000", + "examine": "Made from 100% real dragonhide.", + "durability": null, + "weight": "6.8", + "absorb": "0,6,3", + "equip_audio": "2241", + "equipment_slot": "4", + "lendable": "true", + "grand_exchange_price": "6680", + "name": "Red d'hide body", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2501", + "bonuses": "0,0,0,-15,25,50,42,55,40,50,50,0,0,0,0" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "6680", + "durability": null, + "name": "Red d'hide body", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2502" + }, + { + "requirements": "{1,40}-{4,70}", + "ge_buy_limit": "5000", + "examine": "Made from 100% real dragonhide.", + "durability": null, + "weight": "6.8", + "absorb": "0,6,3", + "equip_audio": "2241", + "equipment_slot": "4", + "lendable": "true", + "grand_exchange_price": "8098", + "name": "Black d'hide body", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2503", + "bonuses": "0,0,0,-15,30,55,47,60,50,55,55,0,0,0,0" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "8098", + "durability": null, + "name": "Black d'hide body", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2504" + }, + { + "ge_buy_limit": "10000", + "examine": "It's a piece of prepared blue dragonhide.", + "grand_exchange_price": "2888", + "durability": null, + "name": "Blue d-leather", + "tradeable": "true", + "weight": "3.1", + "archery_ticket_price": "0", + "id": "2505" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "2888", + "durability": null, + "name": "Blue d-leather", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2506" + }, + { + "ge_buy_limit": "10000", + "examine": "It's a piece of prepared red dragonhide.", + "grand_exchange_price": "4464", + "durability": null, + "name": "Red dragon leather", + "tradeable": "true", + "weight": "3", + "archery_ticket_price": "0", + "id": "2507" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "4464", + "durability": null, + "name": "Red dragon leather", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2508" + }, + { + "ge_buy_limit": "10000", + "examine": "It's a piece of prepared black dragonhide.", + "grand_exchange_price": "6664", + "durability": null, + "name": "Black d-leather", + "tradeable": "true", + "weight": "3.1", + "archery_ticket_price": "0", + "id": "2509" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "6664", + "durability": null, + "name": "Black d-leather", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2510" + }, + { + "shop_price": "4", + "examine": "A number of wooden logs.", + "grand_exchange_price": "124", + "durability": null, + "name": "Logs", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "2511" + }, + { + "lendable": "true", + "examine": "A series of connected metal rings.", + "grand_exchange_price": "2902937", + "rare_item": "true", + "durability": null, + "name": "Dragon chainbody", + "tradeable": "true", + "weight": "6.8", + "archery_ticket_price": "0", + "id": "2513", + "absorb": "4,0,9", + "bonuses": "0,0,0,-15,0,81,93,98,-3,82,50,0,0,0,0" + }, + { + "shop_price": "6", + "examine": "I should try cooking this.", + "grand_exchange_price": "6", + "durability": null, + "name": "Raw shrimps", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "2514" + }, + { + "durability": null, + "name": "Raw shrimps", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2515" + }, + { + "shop_price": "14", + "examine": "There is flour in this pot.", + "grand_exchange_price": "162", + "durability": null, + "name": "Pot of flour", + "tradeable": "true", + "weight": "1.3", + "archery_ticket_price": "0", + "id": "2516" + }, + { + "durability": null, + "name": "Pot of flour", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2517" + }, + { + "shop_price": "1", + "examine": "Pretty smelly.", + "durability": null, + "name": "Rotten tomato", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2518" + }, + { + "durability": null, + "name": "Rotten tomato", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2519" + }, + { + "shop_price": "150", + "examine": "An inexpensive white/black/grey/brown toy horse.", + "durability": null, + "name": "Toy horsey", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2520" + }, + { + "durability": null, + "name": "Toy horsey", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2521" + }, + { + "shop_price": "150", + "examine": "An inexpensive white/black/grey/brown toy horse.", + "durability": null, + "name": "Toy horsey", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2522" + }, + { + "durability": null, + "name": "Toy horsey", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2523" + }, + { + "shop_price": "150", + "examine": "An inexpensive white/black/grey/brown toy horse.", + "durability": null, + "name": "Toy horsey", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2524" + }, + { + "durability": null, + "name": "Toy horsey", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2525" + }, + { + "shop_price": "150", + "examine": "An inexpensive white/black/grey/brown toy horse.", + "durability": null, + "name": "Toy horsey", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2526" + }, + { + "durability": null, + "name": "Toy horsey", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2527" + }, + { + "bankable": "false", + "examine": "Wonder what happens if I rub it...", + "durability": null, + "name": "Lamp", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "2528" + }, + { + "examine": "A magical sphere that glimmers within.", + "durability": null, + "name": "Orb of light", + "weight": "5", + "archery_ticket_price": "0", + "id": "2529" + }, + { + "shop_price": "140", + "grand_exchange_price": "140", + "examine": "Bones are for burying!", + "durability": null, + "name": "Bones", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "2530" + }, + { + "durability": null, + "name": "Bones", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2531" + }, + { + "ge_buy_limit": "10000", + "examine": "unlit: Arrows with iron heads and oil-soaked cloth. lit: An easy to make, iron-headed fire arrow.", + "grand_exchange_price": "316", + "durability": null, + "name": "Iron fire arrows", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2532", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,10", + "equipment_slot": "13" + }, + { + "ge_buy_limit": "10000", + "examine": "unlit: Arrows with iron heads and oil-soaked cloth. lit: An easy to make, iron-headed fire arrow.", + "grand_exchange_price": "305", + "durability": null, + "name": "Iron fire arrows", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2533", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,10", + "equipment_slot": "13" + }, + { + "requirements": "{4,5}", + "ge_buy_limit": "10000", + "examine": "unlit: Arrows with steel heads and oil-soaked cloth. lit: An easy to make, steel-headed fire arrow.", + "grand_exchange_price": "325", + "durability": null, + "name": "Steel fire arrows", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2534", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,16", + "equipment_slot": "13" + }, + { + "requirements": "{4,5}", + "ge_buy_limit": "10000", + "examine": "unlit: Arrows with steel heads and oil-soaked cloth. lit: An easy to make, steel-headed fire arrow.", + "grand_exchange_price": "327", + "durability": null, + "name": "Steel fire arrows", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2535", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,16", + "equipment_slot": "13" + }, + { + "requirements": "{4,20}", + "ge_buy_limit": "10000", + "examine": "unlit: Arrows with mithril heads and oil-soaked cloth. lit: An easy to make, mithril-headed fire arrow.", + "grand_exchange_price": "9", + "durability": null, + "name": "Mithril fire arrows", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2536", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,22", + "equipment_slot": "13" + }, + { + "requirements": "{4,20}", + "ge_buy_limit": "10000", + "examine": "unlit: Arrows with mithril heads and oil-soaked cloth. lit: An easy to make, mithril-headed fire arrow.", + "grand_exchange_price": "63", + "durability": null, + "name": "Mithril fire arrows", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2537", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,22", + "equipment_slot": "13" + }, + { + "requirements": "{4,30}", + "ge_buy_limit": "10000", + "examine": "unlit: Arrows with adamant heads and oil-soaked cloth.lit: An easy-to-make, Adamant-headed fire arrow.", + "grand_exchange_price": "90", + "durability": null, + "name": "Adamant fire arrows", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2538", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,31", + "equipment_slot": "13" + }, + { + "requirements": "{4,30}", + "ge_buy_limit": "10000", + "examine": "unlit: Arrows with adamant heads and oil-soaked cloth.lit: An easy-to-make, Adamant-headed fire arrow.", + "grand_exchange_price": "127", + "durability": null, + "name": "Adamant fire arrows", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2539", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,31", + "equipment_slot": "13" + }, + { + "requirements": "{4,40}", + "ge_buy_limit": "10000", + "examine": "An easy to make, rune-headed fire arrow.", + "grand_exchange_price": "539", + "durability": null, + "name": "Rune fire arrows", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2540", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,49", + "equipment_slot": "13" + }, + { + "requirements": "{4,40}", + "ge_buy_limit": "10000", + "examine": "An easy to make, rune-headed fire arrow.", + "grand_exchange_price": "682", + "durability": null, + "name": "Rune fire arrows", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2541", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,49", + "equipment_slot": "13" + }, + { + "ge_buy_limit": "5000", + "examine": "An enchanted ring.", + "grand_exchange_price": "943", + "durability": null, + "name": "Ring of recoil", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2550", + "equipment_slot": "12" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "943", + "durability": null, + "name": "Ring of recoil", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2551" + }, + { + "shop_price": "770", + "ge_buy_limit": "10000", + "examine": "An enchanted ring.", + "grand_exchange_price": "1237", + "durability": null, + "name": "Ring of duelling(8)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2552", + "equipment_slot": "12" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "1237", + "durability": null, + "name": "Ring of duelling(8)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2553" + }, + { + "shop_price": "770", + "examine": "An enchanted ring.", + "grand_exchange_price": "8", + "durability": null, + "name": "Ring of duelling(7)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2554", + "equipment_slot": "12" + }, + { + "durability": null, + "name": "Ring of duelling(7)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2555" + }, + { + "shop_price": "770", + "examine": "An enchanted ring.", + "grand_exchange_price": "8", + "durability": null, + "name": "Ring of duelling(6)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2556", + "equipment_slot": "12" + }, + { + "durability": null, + "name": "Ring of duelling(6)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2557" + }, + { + "shop_price": "770", + "examine": "An enchanted ring.", + "grand_exchange_price": "8", + "durability": null, + "name": "Ring of duelling(5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2558", + "equipment_slot": "12" + }, + { + "durability": null, + "name": "Ring of duelling(5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2559" + }, + { + "shop_price": "770", + "examine": "An enchanted ring.", + "grand_exchange_price": "8", + "durability": null, + "name": "Ring of duelling(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2560", + "equipment_slot": "12" + }, + { + "durability": null, + "name": "Ring of duelling(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2561" + }, + { + "shop_price": "770", + "examine": "An enchanted ring.", + "grand_exchange_price": "8", + "durability": null, + "name": "Ring of duelling(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2562", + "equipment_slot": "12" + }, + { + "durability": null, + "name": "Ring of duelling(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2563" + }, + { + "shop_price": "770", + "examine": "An enchanted ring.", + "grand_exchange_price": "8", + "durability": null, + "name": "Ring of duelling(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2564", + "equipment_slot": "12" + }, + { + "durability": null, + "name": "Ring of duelling(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2565" + }, + { + "shop_price": "770", + "ge_buy_limit": "10000", + "examine": "An enchanted ring.", + "grand_exchange_price": "594", + "durability": null, + "name": "Ring of duelling(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2566", + "equipment_slot": "12" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "594", + "durability": null, + "name": "Ring of duelling(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2567" + }, + { + "ge_buy_limit": "10000", + "examine": "An enchanted ring.", + "grand_exchange_price": "1103", + "durability": null, + "name": "Ring of forging", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2568", + "equipment_slot": "12" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "1103", + "durability": null, + "name": "Ring of forging", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2569" + }, + { + "shop_price": "3000", + "ge_buy_limit": "10000", + "examine": "An enchanted ring.", + "grand_exchange_price": "4540", + "durability": null, + "name": "Ring of life", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2570", + "equipment_slot": "12" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "4540", + "durability": null, + "name": "Ring of life", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2571" + }, + { + "examine": "An enchanted ring.", + "durability": null, + "name": "Ring of wealth", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2572", + "equipment_slot": "12" + }, + { + "durability": null, + "name": "Ring of wealth", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2573" + }, + { + "examine": "Used by navigators to find their position in 2009Scape.", + "durability": null, + "name": "Sextant", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "2574" + }, + { + "examine": "A fine looking time piece.", + "durability": null, + "name": "Watch", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "2575" + }, + { + "examine": "A navigator's chart of 2009Scape.", + "durability": null, + "name": "Chart", + "archery_ticket_price": "0", + "id": "2576" + }, + { + "requirements": "{4,40}", + "ge_buy_limit": "2", + "examine": "Lightweight boots ideal for rangers.", + "durability": null, + "weight": "0.2", + "equipment_slot": "10", + "lendable": "true", + "grand_exchange_price": "13900000", + "name": "Ranger boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2577", + "bonuses": "0,0,0,-10,8,2,3,4,2,0,10,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "13900000", + "durability": null, + "name": "Ranger boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2578" + }, + { + "requirements": "{6,20}", + "ge_buy_limit": "2", + "examine": "Slightly magical boots.", + "durability": null, + "weight": "1", + "equipment_slot": "10", + "lendable": "true", + "grand_exchange_price": "747300", + "name": "Wizard boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2579", + "bonuses": "0,0,0,4,0,0,0,0,4,0,0,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "747300", + "durability": null, + "name": "Wizard boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2580" + }, + { + "requirements": "{4,40}", + "ge_buy_limit": "2", + "examine": "Endorsed by Robin Hood.", + "durability": null, + "weight": "0.2", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "4400000", + "name": "Robin hood hat", + "tradeable": "true", + "archery_ticket_price": "0", + "hat": "true", + "id": "2581", + "bonuses": "0,0,0,-10,8,4,6,8,4,4,7,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "4400000", + "durability": null, + "name": "Robin hood hat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2582" + }, + { + "requirements": "{1,10}", + "ge_buy_limit": "2", + "examine": "Black platebody with trim.", + "durability": null, + "weight": "9.07", + "absorb": "1,0,2", + "equip_audio": "2239", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "74900", + "name": "Black platebody (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2583", + "bonuses": "0,0,0,-30,-10,41,40,30,-6,40,10,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "74900", + "durability": null, + "name": "Black platebody (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2584" + }, + { + "requirements": "{1,10}", + "ge_buy_limit": "2", + "examine": "Black platelegs with trim.", + "durability": null, + "weight": "9", + "equip_audio": "2242", + "equipment_slot": "7", + "grand_exchange_price": "39900", + "name": "Black platelegs (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2585", + "bonuses": "0,0,0,-21,-7,21,20,19,-4,20,3,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "39900", + "durability": null, + "name": "Black platelegs (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2586" + }, + { + "remove_head": "true", + "requirements": "{1,10}", + "ge_buy_limit": "100", + "examine": "Black full helmet with trim.", + "durability": null, + "weight": "2", + "equip_audio": "2240", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "82200", + "name": "Black full helm(t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2587", + "bonuses": "0,0,0,-6,-2,12,13,10,-1,12,4,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "82200", + "durability": null, + "name": "Black full helm(t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2588" + }, + { + "requirements": "{1,10}", + "shop_price": "2072", + "ge_buy_limit": "2", + "examine": "Black kiteshield with trim.", + "durability": null, + "weight": "5", + "absorb": "1,0,2", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "73000", + "name": "Black kiteshield (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2589", + "bonuses": "0,0,0,-8,-2,17,19,18,-1,18,10,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "73000", + "durability": null, + "name": "Black kiteshield (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2590" + }, + { + "requirements": "{1,10}", + "ge_buy_limit": "2", + "examine": "Black platebody with gold trim.", + "durability": null, + "weight": "9.07", + "absorb": "1,0,2", + "equip_audio": "2239", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "589000", + "name": "Black platebody (g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2591", + "bonuses": "0,0,0,-30,-10,41,40,30,-6,40,10,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "589000", + "durability": null, + "name": "Black platebody (g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2592" + }, + { + "requirements": "{1,10}", + "ge_buy_limit": "2", + "examine": "Black platelegs with gold trim.", + "durability": null, + "weight": "9", + "equip_audio": "2242", + "equipment_slot": "7", + "grand_exchange_price": "216700", + "name": "Black platelegs (g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2593", + "bonuses": "0,0,0,-21,-7,21,20,19,-4,20,3,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "216700", + "durability": null, + "name": "Black platelegs (g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2594" + }, + { + "remove_head": "true", + "requirements": "{1,10}", + "ge_buy_limit": "100", + "examine": "Black full helmet with gold trim.", + "durability": null, + "weight": "2.7", + "equip_audio": "2240", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "364800", + "name": "Black full helm(g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2595", + "bonuses": "0,0,0,-6,-2,12,13,10,-1,12,4,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "364800", + "durability": null, + "name": "Black full helm(g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2596" + }, + { + "requirements": "{1,10}", + "ge_buy_limit": "2", + "examine": "Black kiteshield with gold trim.", + "durability": null, + "weight": "5", + "absorb": "1,0,2", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "355600", + "name": "Black kiteshield (g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2597", + "bonuses": "0,0,0,-8,-2,17,19,18,-1,18,10,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "355600", + "durability": null, + "name": "Black kiteshield (g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2598" + }, + { + "requirements": "{1,30}", + "ge_buy_limit": "2", + "examine": "Adamant platebody with trim.", + "durability": null, + "weight": "9.07", + "absorb": "2,0,4", + "equip_audio": "2239", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "104000", + "name": "Adam platebody (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2599", + "bonuses": "0,0,0,-30,-10,65,63,55,-6,63,30,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "104000", + "durability": null, + "name": "Adam platebody (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2600" + }, + { + "requirements": "{1,30}", + "shop_price": "6464", + "ge_buy_limit": "2", + "examine": "These look heavy", + "durability": null, + "weight": "10", + "absorb": "1,0,3", + "equip_audio": "2242", + "equipment_slot": "7", + "grand_exchange_price": "23200", + "name": "Adam platelegs (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2601", + "bonuses": "0,0,0,-21,-7,33,31,29,-4,31,10,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "23200", + "durability": null, + "name": "Adam platelegs (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2602" + }, + { + "requirements": "{1,30}", + "ge_buy_limit": "2", + "examine": "A large metal shield.", + "durability": null, + "weight": "5.8", + "absorb": "3,0,6", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "49100", + "name": "Adam kiteshield (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2603", + "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,30,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "49100", + "durability": null, + "name": "Adam kiteshield (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2604" + }, + { + "remove_head": "true", + "requirements": "{1,30}", + "ge_buy_limit": "2", + "examine": "Adamant full helm with trim", + "durability": null, + "weight": "2.7", + "absorb": "1,0,2", + "equip_audio": "2240", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "85000", + "name": "Adam full helm(t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2605", + "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,6,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "85000", + "durability": null, + "name": "Adam full helm(t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2606" + }, + { + "requirements": "{1,30}", + "ge_buy_limit": "2", + "examine": "Adamant platebody with gold trim.", + "durability": null, + "weight": "9.07", + "absorb": "2,0,4", + "equip_audio": "2239", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "359500", + "name": "Adam platebody (g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2607", + "bonuses": "0,0,0,-30,-10,65,63,55,-6,63,30,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "359500", + "durability": null, + "name": "Adam platebody (g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2608" + }, + { + "requirements": "{1,30}", + "shop_price": "6464", + "ge_buy_limit": "2", + "examine": "Adamant platelegs with gold trim.", + "durability": null, + "weight": "10", + "absorb": "1,0,3", + "equip_audio": "2242", + "equipment_slot": "7", + "grand_exchange_price": "94300", + "name": "Adam platelegs (g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2609", + "bonuses": "0,0,0,-21,-7,33,31,29,-4,31,10,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "94300", + "durability": null, + "name": "Adam platelegs (g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2610" + }, + { + "requirements": "{1,30}", + "ge_buy_limit": "2", + "examine": "Adamant kiteshield with gold trim.", + "durability": null, + "weight": "6", + "absorb": "3,0,6", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "170100", + "name": "Adam kiteshield (g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2611", + "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,30,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "170100", + "durability": null, + "name": "Adam kiteshield (g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2612" + }, + { + "remove_head": "true", + "requirements": "{1,30}", + "ge_buy_limit": "2", + "examine": "Adamant full helmet with gold trim.", + "durability": null, + "weight": "2.7", + "absorb": "1,0,2", + "equip_audio": "2240", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "222400", + "name": "Adam full helm(g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2613", + "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,6,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "222400", + "durability": null, + "name": "Adam full helm(g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2614" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "Rune platebody with gold trim.", + "durability": null, + "weight": "9.07", + "absorb": "3,0,6", + "equip_audio": "2239", + "equipment_slot": "4", + "lendable": "true", + "remove_sleeves": "true", + "grand_exchange_price": "426200", + "name": "Rune platebody (g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2615", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "426200", + "durability": null, + "name": "Rune platebody (g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2616" + }, + { + "requirements": "{1,40}", + "shop_price": "64000", + "ge_buy_limit": "2", + "examine": "Rune platelegs with gold trim.", + "durability": null, + "weight": "9", + "absorb": "2,0,4", + "equip_audio": "2242", + "equipment_slot": "7", + "lendable": "true", + "grand_exchange_price": "243400", + "name": "Rune platelegs (g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2617", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "243400", + "durability": null, + "name": "Rune platelegs (g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2618" + }, + { + "remove_head": "true", + "requirements": "{1,40}", + "shop_price": "35000", + "ge_buy_limit": "100", + "examine": "Rune full helmet with gold trim.", + "durability": null, + "weight": "2", + "absorb": "1,0,3", + "equip_audio": "2240", + "remove_beard": "true", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "506800", + "name": "Rune full helm(g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2619", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "506800", + "durability": null, + "name": "Rune full helm(g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2620" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "Rune kiteshield with gold trim", + "durability": null, + "weight": "5", + "absorb": "3,0,7", + "equip_audio": "2245", + "equipment_slot": "5", + "lendable": "true", + "grand_exchange_price": "392700", + "name": "Rune kiteshield (g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2621", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "392700", + "durability": null, + "name": "Rune kiteshield (g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2622" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "Rune platebody with trim.", + "durability": null, + "weight": "9.07", + "absorb": "3,0,6", + "equip_audio": "2239", + "equipment_slot": "4", + "lendable": "true", + "remove_sleeves": "true", + "grand_exchange_price": "162700", + "name": "Rune platebody (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2623", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "162700", + "durability": null, + "name": "Rune platebody (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2624" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "Rune platelegs with trim!", + "durability": null, + "weight": "9", + "absorb": "2,0,4", + "equip_audio": "2242", + "equipment_slot": "7", + "lendable": "true", + "grand_exchange_price": "95400", + "name": "Rune platelegs (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2625", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "95400", + "durability": null, + "name": "Rune platelegs (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2626" + }, + { + "remove_head": "true", + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "Rune full helmet with trim.", + "durability": null, + "weight": "2.7", + "absorb": "1,0,3", + "equip_audio": "2240", + "remove_beard": "true", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "216600", + "name": "Rune full helm (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2627", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "216600", + "durability": null, + "name": "Rune full helm (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2628" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "A large, metal shield with a nice trim.", + "durability": null, + "weight": "5", + "absorb": "3,0,7", + "equip_audio": "2245", + "equipment_slot": "5", + "attack_anims": "", + "lendable": "true", + "grand_exchange_price": "160300", + "name": "Rune kiteshield (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2629", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "160300", + "durability": null, + "name": "Rune kiteshield (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2630" + }, + { + "lendable": "true", + "ge_buy_limit": "2", + "examine": "Your money or your life!", + "grand_exchange_price": "83500", + "durability": null, + "name": "Highwayman mask", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2631", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "83500", + "durability": null, + "name": "Highwayman mask", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2632" + }, + { + "lendable": "true", + "ge_buy_limit": "2", + "examine": "Parlez-vous francais? (Do you speak French?)", + "grand_exchange_price": "34300", + "durability": null, + "name": "Blue beret", + "tradeable": "true", + "archery_ticket_price": "0", + "hat": true, + "id": "2633", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "34300", + "durability": null, + "name": "Blue beret", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2634" + }, + { + "lendable": "true", + "ge_buy_limit": "2", + "examine": "Parlez-vous francais?(Do you speak French?)", + "grand_exchange_price": "117500", + "durability": null, + "name": "Black beret", + "tradeable": "true", + "archery_ticket_price": "0", + "hat": true, + "id": "2635", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "117500", + "durability": null, + "name": "Black beret", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2636" + }, + { + "lendable": "true", + "ge_buy_limit": "2", + "examine": "Parlez-vous francais? (Do you speak French?)", + "grand_exchange_price": "328000", + "durability": null, + "name": "White beret", + "tradeable": "true", + "archery_ticket_price": "0", + "hat": true, + "id": "2637", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "328000", + "durability": null, + "name": "White beret", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2638" + }, + { + "lendable": "true", + "ge_buy_limit": "2", + "examine": "All for one and one for all!", + "grand_exchange_price": "29100", + "durability": null, + "name": "Tan cavalier", + "tradeable": "true", + "archery_ticket_price": "0", + "hat": true, + "id": "2639", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "29100", + "durability": null, + "name": "Tan cavalier", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2640" + }, + { + "lendable": "true", + "ge_buy_limit": "2", + "examine": "All for one and one for all!", + "grand_exchange_price": "23600", + "durability": null, + "name": "Dark cavalier", + "tradeable": "true", + "archery_ticket_price": "0", + "hat": true, + "id": "2641", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "23600", + "durability": null, + "name": "Dark cavalier", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2642" + }, + { + "lendable": "true", + "ge_buy_limit": "2", + "examine": "All for one and one for all!", + "grand_exchange_price": "384500", + "durability": null, + "name": "Black cavalier", + "tradeable": "true", + "archery_ticket_price": "0", + "hat": true, + "id": "2643", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "384500", + "durability": null, + "name": "Black cavalier", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2644" + }, + { + "lendable": "true", + "ge_buy_limit": "2", + "examine": "A minimalist's hat.", + "grand_exchange_price": "91300", + "durability": null, + "name": "Red headband", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2645", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "91300", + "durability": null, + "name": "Red headband", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2646" + }, + { + "lendable": "true", + "ge_buy_limit": "2", + "examine": "A minimalist's hat.", + "grand_exchange_price": "32900", + "durability": null, + "name": "Black headband", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2647", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "32900", + "durability": null, + "name": "Black headband", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2648" + }, + { + "lendable": "true", + "ge_buy_limit": "2", + "examine": "A minimalist's hat.", + "grand_exchange_price": "17800", + "durability": null, + "name": "Brown headband", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2649", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "17800", + "durability": null, + "name": "Brown headband", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2650" + }, + { + "ge_buy_limit": "2", + "examine": "Shiver me timbers!", + "grand_exchange_price": "82500", + "durability": null, + "name": "Pirate's hat", + "tradeable": "true", + "archery_ticket_price": "0", + "hat": "true", + "id": "2651", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "82500", + "durability": null, + "name": "Pirate's hat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2652" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "Rune platebody in the colours of Zamorak.", + "durability": null, + "weight": "9", + "absorb": "3,0,6", + "equip_audio": "2239", + "equipment_slot": "4", + "lendable": "true", + "remove_sleeves": "true", + "grand_exchange_price": "809000", + "name": "Zamorak platebody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2653", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "809000", + "durability": null, + "name": "Zamorak platebody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2654" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "Rune platelegs in the colours of Zamorak.", + "durability": null, + "weight": "9", + "absorb": "2,0,4", + "equip_audio": "2242", + "equipment_slot": "7", + "lendable": "true", + "grand_exchange_price": "281500", + "name": "Zamorak platelegs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2655", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "281500", + "durability": null, + "name": "Zamorak platelegs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2656" + }, + { + "remove_head": "true", + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "A full helmet in the colours of Zamorak.", + "durability": null, + "weight": "2", + "absorb": "1,0,3", + "equip_audio": "2240", + "remove_beard": "true", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "601500", + "name": "Zamorak full helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2657", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,1" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "601500", + "durability": null, + "name": "Zamorak full helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2658" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "A Rune kiteshield in the colours of Zamorak.", + "durability": null, + "weight": "5", + "absorb": "3,0,7", + "equip_audio": "2245", + "equipment_slot": "5", + "lendable": "true", + "grand_exchange_price": "499500", + "name": "Zamorak kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2659", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "499500", + "durability": null, + "name": "Zamorak kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2660" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "Rune platebody in the colours of Saradomin.", + "durability": null, + "weight": "9.07", + "absorb": "3,0,6", + "equip_audio": "2239", + "equipment_slot": "4", + "lendable": "true", + "remove_sleeves": "true", + "grand_exchange_price": "1600000", + "name": "Saradomin platebody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2661", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "1600000", + "durability": null, + "name": "Saradomin platebody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2662" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "Rune platelegs in the colours of Saradomin.", + "durability": null, + "weight": "9", + "absorb": "2,0,4", + "equip_audio": "2242", + "equipment_slot": "7", + "lendable": "true", + "grand_exchange_price": "444000", + "name": "Saradomin platelegs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2663", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "444000", + "durability": null, + "name": "Saradomin platelegs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2664" + }, + { + "remove_head": "true", + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "Rune full helmet in the colours of Saradomin.", + "durability": null, + "weight": "2", + "absorb": "1,0,3", + "equip_audio": "2240", + "remove_beard": "true", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "1100000", + "name": "Saradomin full helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2665", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "1100000", + "durability": null, + "name": "Saradomin full helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2666" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "Rune kiteshield in the colours of Saradomin.", + "durability": null, + "weight": "5.4", + "absorb": "3,0,7", + "equip_audio": "2245", + "equipment_slot": "5", + "lendable": "true", + "grand_exchange_price": "795900", + "name": "Saradomin kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2667", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "795900", + "durability": null, + "name": "Saradomin kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2668" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "Rune platebody in the colours of Guthix.", + "durability": null, + "weight": "9.07", + "absorb": "3,0,6", + "equip_audio": "2239", + "equipment_slot": "4", + "lendable": "true", + "remove_sleeves": "true", + "grand_exchange_price": "307900", + "name": "Guthix platebody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2669", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "307900", + "durability": null, + "name": "Guthix platebody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2670" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "Rune platelegs in the colours of Guthix.", + "durability": null, + "weight": "9", + "absorb": "2,0,4", + "equip_audio": "2242", + "equipment_slot": "7", + "lendable": "true", + "grand_exchange_price": "169900", + "name": "Guthix platelegs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2671", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "169900", + "durability": null, + "name": "Guthix platelegs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2672" + }, + { + "remove_head": "true", + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "A rune full helmet in the colours of Guthix.", + "durability": null, + "weight": "2", + "absorb": "1,0,3", + "equip_audio": "2240", + "remove_beard": "true", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "323100", + "name": "Guthix full helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2673", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,1,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "323100", + "durability": null, + "name": "Guthix full helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2674" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "Rune kiteshield in the colours of Guthix.", + "durability": null, + "weight": "5.4", + "absorb": "3,0,7", + "equip_audio": "2245", + "equipment_slot": "5", + "lendable": "true", + "grand_exchange_price": "247300", + "name": "Guthix kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2675", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "247300", + "durability": null, + "name": "Guthix kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2676" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2677" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2678" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2679" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2680" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2681" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2682" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2683" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2684" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2685" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2686" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2687" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2688" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2689" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2690" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2691" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2692" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2693" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2694" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2695" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2696" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2697" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2698" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2699" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2700" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2701" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2702" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2703" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2704" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2705" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2706" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2707" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2708" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2709" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2710" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2711" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2712" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2713" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "2714" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "2715" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2716" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "2717" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "2718" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2719" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "2720" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "2721" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2722" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2723" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "2724" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2725" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "2726" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2727" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "2728" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2729" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "2730" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2731" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "2732" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2733" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "2734" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2735" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "2736" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2737" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "2738" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2739" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "2740" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2741" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "2742" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2743" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "2744" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2745" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "2746" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2747" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "2748" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2773" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2774" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "2775" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2776" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "2777" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2778" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "2779" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2780" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "2781" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2782" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2783" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "2784" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2785" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2786" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "2787" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2788" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "2789" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2790" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "2791" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2792" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2793" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2794" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "shop_price": "5", + "examine": "I need to solve this.", + "durability": null, + "name": "Puzzle box", + "archery_ticket_price": "0", + "id": "2795" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2796" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2797" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "shop_price": "5", + "examine": "I need to solve this.", + "durability": null, + "name": "Puzzle box", + "archery_ticket_price": "0", + "id": "2798" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2799" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "shop_price": "5", + "examine": "I need to solve this.", + "durability": null, + "name": "Puzzle box", + "archery_ticket_price": "0", + "id": "2800" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2801" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "2802" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2803" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "2804" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2805" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "2806" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2807" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "2808" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2809" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "2810" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2811" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "2812" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2813" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "2814" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2815" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "2816" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2817" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "2818" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2819" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "2820" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2821" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "2822" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2823" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "2824" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2825" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "2826" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2827" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "2828" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2829" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "2830" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2831" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2833" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2835" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2837" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2839" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2841" + }, + { + "examine": "I need to answer this correctly.", + "durability": null, + "name": "Challenge scroll", + "archery_ticket_price": "0", + "id": "2842" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2843" + }, + { + "examine": "I need to answer this correctly.", + "durability": null, + "name": "Challenge scroll", + "archery_ticket_price": "0", + "id": "2844" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2845" + }, + { + "examine": "I need to answer this correctly.", + "durability": null, + "name": "Challenge scroll", + "archery_ticket_price": "0", + "id": "2846" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2847" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2848" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2849" + }, + { + "examine": "I need to answer this correctly.", + "durability": null, + "name": "Challenge scroll", + "archery_ticket_price": "0", + "id": "2850" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2851" + }, + { + "examine": "I need to answer this correctly.", + "durability": null, + "name": "Challenge scroll", + "archery_ticket_price": "0", + "id": "2852" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2853" + }, + { + "examine": "I need to answer this correctly.", + "durability": null, + "name": "Challenge scroll", + "archery_ticket_price": "0", + "id": "2854" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2855" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2856" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2857" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "2858" + }, + { + "ge_buy_limit": "1000", + "examine": "Bones of a recently slain wolf.", + "grand_exchange_price": "1266", + "durability": null, + "name": "Wolf bones", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "2859" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1266", + "durability": null, + "name": "Wolf bones", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2860" + }, + { + "shop_price": "5", + "ge_buy_limit": "1000", + "examine": "I can make an ogre arrow with these.", + "grand_exchange_price": "5", + "durability": null, + "name": "Wolfbone arrowtips", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2861" + }, + { + "ge_buy_limit": "25000", + "examine": "These logs are longer than normal.", + "grand_exchange_price": "169", + "durability": null, + "name": "Achey tree logs", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "2862" + }, + { + "ge_buy_limit": "25000", + "grand_exchange_price": "169", + "durability": null, + "name": "Achey tree logs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2863" + }, + { + "ge_buy_limit": "1000", + "examine": "A wooden arrow shaft", + "grand_exchange_price": "47", + "durability": null, + "name": "Ogre arrow shaft", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2864" + }, + { + "ge_buy_limit": "1000", + "examine": "An ogre arrow with four flights attached.", + "grand_exchange_price": "172", + "durability": null, + "name": "Flighted ogre arrow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2865" + }, + { + "requirements": "{4,30}", + "shop_price": "25", + "ge_buy_limit": "1000", + "examine": "A large ogre arrow with a bone tip.", + "grand_exchange_price": "49", + "durability": null, + "name": "Ogre arrow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2866", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,22", + "equipment_slot": "13" + }, + { + "examine": "A large pair of ogre bellows. If filled with gas (1-3): A large pair of ogre bellows, it has x load(s) of swamp gas in it.", + "durability": null, + "name": "Ogre bellows", + "archery_ticket_price": "0", + "id": "2871", + "equipment_slot": "3" + }, + { + "examine": "A large pair of ogre bellows. If filled with gas (1-3): A large pair of ogre bellows, it has x load(s) of swamp gas in it.", + "durability": null, + "name": "Ogre bellows (3)", + "archery_ticket_price": "0", + "id": "2872" + }, + { + "examine": "A large pair of ogre bellows. If filled with gas (1-3): A large pair of ogre bellows, it has x load(s) of swamp gas in it.", + "durability": null, + "name": "Ogre bellows (2)", + "archery_ticket_price": "0", + "id": "2873" + }, + { + "examine": "A large pair of ogre bellows. If filled with gas (1-3): A large pair of ogre bellows, it has x load(s) of swamp gas in it.", + "durability": null, + "name": "Ogre bellows (1)", + "archery_ticket_price": "0", + "id": "2874" + }, + { + "bankable": "false", + "examine": "An inflated toad.", + "durability": null, + "name": "Bloated toad", + "tradeable": "false", + "destroy": "true", + "weight": "0.7", + "archery_ticket_price": "0", + "id": "2875" + }, + { + "ge_buy_limit": "10000", + "examine": "I need to cook this first.", + "grand_exchange_price": "2145", + "durability": null, + "name": "Raw chompy", + "tradeable": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "2876" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "2145", + "durability": null, + "name": "Raw chompy", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2877" + }, + { + "shop_price": "130", + "ge_buy_limit": "1000", + "examine": "It might look delicious to an ogre.Roasted chompy bird.", + "grand_exchange_price": "95", + "durability": null, + "name": "Cooked chompy", + "tradeable": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "2878" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "95", + "durability": null, + "name": "Cooked chompy", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2879" + }, + { + "durability": null, + "name": "Ruined chompy", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2881" + }, + { + "examine": "It has been deliciously seasoned to taste wonderful for ogres.", + "durability": null, + "name": "Seasoned chompy", + "weight": "10", + "archery_ticket_price": "0", + "id": "2882" + }, + { + "requirements": "{4,30}", + "shop_price": "500", + "examine": "More powerful than a normal bow, useful against large game birds.", + "durability": null, + "weight": "1", + "attack_speed": "8", + "two_handed": "true", + "weapon_interface": "16", + "equipment_slot": "3", + "attack_audios": "2700,0,0,0", + "name": "Ogre bow", + "archery_ticket_price": "0", + "id": "2883", + "bonuses": "0,0,0,0,38,0,0,0,0,0,0,0,0,0,0" + }, + { + "examine": "Book of the elemental shield.", + "durability": null, + "name": "Battered book", + "archery_ticket_price": "0", + "id": "2886" + }, + { + "examine": "An old battered key. (Elemental Workshop I)", + "durability": null, + "name": "Battered key", + "archery_ticket_price": "0", + "id": "2887" + }, + { + "examine": "This is an empty stone bowl. / This is a stone bowl full of lava.", + "durability": null, + "name": "A stone bowl", + "archery_ticket_price": "0", + "id": "2888", + "equipment_slot": "3" + }, + { + "examine": "This is an empty stone bowl. / This is a stone bowl full of lava.", + "durability": null, + "name": "A stone bowl", + "archery_ticket_price": "0", + "id": "2889", + "equipment_slot": "3" + }, + { + "shop_price": "2000", + "ge_buy_limit": "100", + "examine": "A shield made in the Elemental Workshop.", + "grand_exchange_price": "709", + "durability": null, + "name": "Elemental shield", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "2890", + "bonuses": "0,0,0,0,0,0,0,0,6,0,0,0,0,0,0", + "equipment_slot": "5" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "709", + "durability": null, + "name": "Elemental shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2891" + }, + { + "examine": "This needs refining.", + "durability": null, + "name": "Elemental ore", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "2892" + }, + { + "shop_price": "650", + "ge_buy_limit": "100", + "examine": "Very stylish!", + "grand_exchange_price": "1570", + "durability": null, + "name": "Boots", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "2894", + "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", + "equipment_slot": "10" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1570", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2895" + }, + { + "shop_price": "650", + "ge_buy_limit": "100", + "examine": "Some fine werewolf clothing.", + "durability": null, + "weight": "1", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "867", + "name": "Robe top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2896", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "867", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Robe top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2897" + }, + { + "shop_price": "650", + "ge_buy_limit": "100", + "examine": "Made by werewolves for werewolves.", + "grand_exchange_price": "741", + "durability": null, + "name": "Robe bottoms", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "2898", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "741", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Robe bottoms", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2899" + }, + { + "shop_price": "650", + "ge_buy_limit": "100", + "examine": "A silly pointed hat.", + "durability": null, + "weight": "0.4", + "equipment_slot": "0", + "grand_exchange_price": "844", + "name": "Hat", + "tradeable": "true", + "archery_ticket_price": "0", + "hat": "true", + "id": "2900", + "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "844", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Hat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2901" + }, + { + "shop_price": "650", + "ge_buy_limit": "10", + "examine": "These gloves from Canifis will keep my hands warm!", + "grand_exchange_price": "1039", + "durability": null, + "name": "Gloves", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "2902", + "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0", + "equipment_slot": "9" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "1039", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Gloves", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2903" + }, + { + "shop_price": "650", + "ge_buy_limit": "100", + "examine": "Very stylish!", + "grand_exchange_price": "1359", + "durability": null, + "name": "Boots", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "2904", + "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", + "equipment_slot": "10" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1359", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2905" + }, + { + "shop_price": "650", + "ge_buy_limit": "100", + "examine": "Some fine werewolf clothing.", + "durability": null, + "weight": "1", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "958", + "name": "Robe top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2906", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "958", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Robe top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2907" + }, + { + "shop_price": "650", + "ge_buy_limit": "100", + "examine": "Made by werewolves for werewolves.", + "grand_exchange_price": "474", + "durability": null, + "name": "Robe bottoms", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "2908", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "474", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Robe bottoms", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2909" + }, + { + "shop_price": "650", + "ge_buy_limit": "100", + "examine": "A silly pointed hat.", + "durability": null, + "weight": "0.4", + "equipment_slot": "0", + "grand_exchange_price": "1445", + "tradeable": "true", + "name": "Hat", + "archery_ticket_price": "0", + "hat": "true", + "id": "2910", + "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1445", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Hat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2911" + }, + { + "shop_price": "650", + "ge_buy_limit": "10", + "examine": "These gloves from Canifis will keep my hands warm!", + "grand_exchange_price": "1254", + "durability": null, + "name": "Gloves", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "2912", + "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0", + "equipment_slot": "9" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "1254", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Gloves", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2913" + }, + { + "shop_price": "650", + "ge_buy_limit": "100", + "examine": "Very stylish!", + "grand_exchange_price": "1054", + "durability": null, + "name": "Boots", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "2914", + "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", + "equipment_slot": "10" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1054", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2915" + }, + { + "shop_price": "650", + "ge_buy_limit": "100", + "examine": "Some fine werewolf clothing.", + "durability": null, + "weight": "1", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "789", + "name": "Robe top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2916", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "789", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Robe top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2917" + }, + { + "shop_price": "650", + "ge_buy_limit": "100", + "examine": "Made by werewolves for werewolves.", + "grand_exchange_price": "603", + "durability": null, + "name": "Robe bottoms", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "2918", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "603", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Robe bottoms", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2919" + }, + { + "shop_price": "650", + "ge_buy_limit": "100", + "examine": "A silly pointed hat.", + "durability": null, + "weight": "0.4", + "equipment_slot": "0", + "grand_exchange_price": "997", + "name": "Hat", + "tradeable": "true", + "archery_ticket_price": "0", + "hat": "true", + "id": "2920", + "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "997", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Hat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2921" + }, + { + "shop_price": "650", + "ge_buy_limit": "10", + "examine": "These gloves from Canifis will keep my hands warm!", + "grand_exchange_price": "1221", + "durability": null, + "name": "Gloves", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "2922", + "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0", + "equipment_slot": "9" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "1221", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Gloves", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2923" + }, + { + "shop_price": "650", + "ge_buy_limit": "100", + "examine": "Very stylish!", + "grand_exchange_price": "737", + "durability": null, + "name": "Boots", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "2924", + "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", + "equipment_slot": "10" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "737", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2925" + }, + { + "shop_price": "650", + "ge_buy_limit": "100", + "examine": "Some fine werewolf clothing.", + "durability": null, + "weight": "1", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "504", + "name": "Robe top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2926", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "504", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Robe top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2927" + }, + { + "shop_price": "650", + "ge_buy_limit": "100", + "examine": "Made by werewolves for werewolves.", + "grand_exchange_price": "637", + "durability": null, + "name": "Robe bottoms", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "2928", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "637", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Robe bottoms", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2929" + }, + { + "shop_price": "650", + "ge_buy_limit": "100", + "examine": "A silly pointed hat.", + "durability": null, + "weight": "0.4", + "equipment_slot": "0", + "grand_exchange_price": "925", + "name": "Hat", + "tradeable": "true", + "archery_ticket_price": "0", + "hat": "true", + "id": "2930", + "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "925", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Hat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2931" + }, + { + "shop_price": "650", + "ge_buy_limit": "10", + "examine": "These gloves from Canifis will keep my hands warm!", + "grand_exchange_price": "1829", + "durability": null, + "name": "Gloves", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "2932", + "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0", + "equipment_slot": "9" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "1829", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Gloves", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2933" + }, + { + "shop_price": "650", + "ge_buy_limit": "100", + "examine": "Very stylish!", + "grand_exchange_price": "988", + "durability": null, + "name": "Boots", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "2934", + "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", + "equipment_slot": "10" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "988", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2935" + }, + { + "shop_price": "650", + "ge_buy_limit": "100", + "examine": "Some fine werewolf clothing.", + "durability": null, + "weight": "1", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "925", + "name": "Robe top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2936", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "925", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Robe top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2937" + }, + { + "shop_price": "650", + "ge_buy_limit": "100", + "examine": "Made by werewolves for werewolves.", + "grand_exchange_price": "927", + "durability": null, + "name": "Robe bottoms", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "2938", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "927", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Robe bottoms", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2939" + }, + { + "shop_price": "650", + "ge_buy_limit": "100", + "examine": "A silly pointed hat.", + "durability": null, + "weight": "0.4", + "equipment_slot": "0", + "grand_exchange_price": "1209", + "name": "Hat", + "tradeable": "true", + "archery_ticket_price": "0", + "hat": "true", + "id": "2940", + "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1209", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Hat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2941" + }, + { + "shop_price": "650", + "ge_buy_limit": "10", + "examine": "These gloves from Canifis will keep my hands warm!", + "grand_exchange_price": "634", + "durability": null, + "name": "Gloves", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "2942", + "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0", + "equipment_slot": "9" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "634", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Gloves", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2943" + }, + { + "examine": "A key made from solid gold", + "durability": null, + "name": "Golden key", + "archery_ticket_price": "0", + "id": "2944" + }, + { + "examine": "A key made of solid iron.", + "durability": null, + "name": "Iron key", + "archery_ticket_price": "0", + "id": "2945" + }, + { + "examine": "A replica tinderbox made of solid gold.", + "durability": null, + "name": "Golden tinderbox", + "archery_ticket_price": "0", + "id": "2946" + }, + { + "examine": "A replica candle made of solid gold.", + "durability": null, + "name": "Golden candle", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "2947" + }, + { + "examine": "A replica pot made of solid gold.", + "durability": null, + "name": "Golden pot", + "archery_ticket_price": "0", + "id": "2948" + }, + { + "examine": "A replica hammer made of solid gold.", + "durability": null, + "name": "Golden hammer", + "tradeable": "false", + "destroy": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "2949" + }, + { + "examine": "A replica needle made of solid gold.", + "durability": null, + "name": "Golden needle", + "archery_ticket_price": "0", + "id": "2951" + }, + { + "examine": "A silver dagger that can prevent werewolves changing form.", + "durability": null, + "weight": "0.4", + "attack_speed": "4", + "weapon_interface": "5", + "render_anim": "2584", + "defence_anim": "378", + "equipment_slot": "3", + "attack_anims": "400,400,401,400", + "attack_audios": "2517,2517,2500,2517", + "name": "Wolfbane", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "2952", + "bonuses": "11,5,-4,1,0,0,0,0,1,0,1,10,5,0,0" + }, + { + "examine": "It's a bucket of water.", + "grand_exchange_price": "74", + "durability": null, + "name": "Bucket of water", + "tradeable": "true", + "weight": "3", + "archery_ticket_price": "0", + "id": "2953" + }, + { + "examine": "It's a bucket of water.", + "grand_exchange_price": "74", + "durability": null, + "name": "Bucket of water", + "tradeable": "true", + "weight": "3", + "archery_ticket_price": "0", + "id": "2954" + }, + { + "shop_price": "5", + "ge_buy_limit": "100", + "examine": "A foul smelling brew.", + "grand_exchange_price": "16", + "durability": null, + "name": "Moonlight mead", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2955" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "16", + "durability": null, + "name": "Moonlight mead", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2956" + }, + { + "examine": "An empty druid pouch.", + "durability": null, + "name": "Druid pouch", + "archery_ticket_price": "0", + "id": "2957" + }, + { + "examine": "A druid pouch.", + "durability": null, + "name": "Druid pouch", + "archery_ticket_price": "0", + "id": "2958" + }, + { + "examine": "Erhhh! It stinks.", + "durability": null, + "name": "Rotten food", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "2959" + }, + { + "durability": null, + "name": "Rotten food", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2960" + }, + { + "ge_buy_limit": "100", + "examine": "It's a silver sickle.", + "durability": null, + "weight": "1.6", + "weapon_interface": "6", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "grand_exchange_price": "28", + "name": "Silver sickle", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2961", + "bonuses": "0,0,0,0,0,0,1,1,1,1,0,1,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "28", + "durability": null, + "name": "Silver sickle", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2962" + }, + { + "attack_anims": "390,390,381,390", + "examine": "It's a blessed silver sickle.", + "durability": null, + "name": "Silver sickle(b)", + "weight": "1.5", + "archery_ticket_price": "0", + "weapon_interface": "6", + "id": "2963", + "bonuses": "0,0,0,0,0,0,1,1,1,1,0,1,5,0,0", + "defence_anim": "397", + "equipment_slot": "3" + }, + { + "shop_price": "1", + "examine": "Used for washing your face, amongst other things.", + "durability": null, + "name": "Washing bowl", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "2964" + }, + { + "examine": "A small mirror, probably used for grooming.", + "durability": null, + "name": "Mirror", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "2966" + }, + { + "examine": "A druidic spell given to you freely by the spirit of Filliman Tarlock.", + "durability": null, + "name": "Druidic spell", + "archery_ticket_price": "0", + "id": "2968" + }, + { + "examine": "A used druidic spell given to you freely by the spirit of Filliman Tarlock.", + "durability": null, + "name": "A used spell", + "archery_ticket_price": "0", + "id": "2969" + }, + { + "ge_buy_limit": "10000", + "examine": "A mushroom from the swamps of Mort Myre.", + "grand_exchange_price": "915", + "durability": null, + "name": "Mort myre fungus", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2970" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "915", + "durability": null, + "name": "Mort myre fungus", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2971" + }, + { + "ge_buy_limit": "100", + "examine": "A cutting from a budding branch.", + "grand_exchange_price": "338", + "durability": null, + "name": "Mort myre stem", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2972" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "338", + "durability": null, + "name": "Mort myre stem", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2973" + }, + { + "ge_buy_limit": "100", + "examine": "A pear picked from a dying bush in Mort Myre.", + "grand_exchange_price": "975", + "durability": null, + "name": "Mort myre pear", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "2974" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "975", + "durability": null, + "name": "Mort myre pear", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2975" + }, + { + "shop_price": "10", + "ge_buy_limit": "100", + "examine": "Used to make sickles.", + "grand_exchange_price": "498", + "durability": null, + "name": "Sickle mould", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "2976" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "498", + "durability": null, + "name": "Sickle mould", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2977" + }, + { + "examine": "A symbol of your chompy bird hunting prowess.", + "durability": null, + "name": "Chompy bird hat", + "weight": "0.33", + "archery_ticket_price": "0", + "id": "2978", + "equipment_slot": "0" + }, + { + "examine": "A symbol of your chompy bird hunting prowess.", + "durability": null, + "name": "Chompy bird hat", + "weight": "0.33", + "archery_ticket_price": "0", + "id": "2979", + "equipment_slot": "0" + }, + { + "examine": "A symbol of your chompy bird hunting prowess.", + "durability": null, + "name": "Chompy bird hat", + "weight": "0.33", + "archery_ticket_price": "0", + "id": "2980", + "equipment_slot": "0" + }, + { + "examine": "A symbol of your chompy bird hunting prowess.", + "durability": null, + "name": "Chompy bird hat", + "weight": "0.33", + "archery_ticket_price": "0", + "id": "2981", + "equipment_slot": "0" + }, + { + "examine": "A symbol of your chompy bird hunting prowess.", + "durability": null, + "name": "Chompy bird hat", + "weight": "0.33", + "archery_ticket_price": "0", + "id": "2982", + "equipment_slot": "0" + }, + { + "examine": "A symbol of your chompy bird hunting prowess.", + "durability": null, + "name": "Chompy bird hat", + "weight": "0.33", + "archery_ticket_price": "0", + "id": "2983", + "equipment_slot": "0" + }, + { + "examine": "A symbol of your chompy bird hunting prowess.", + "durability": null, + "name": "Chompy bird hat", + "weight": "0.33", + "archery_ticket_price": "0", + "id": "2984", + "equipment_slot": "0" + }, + { + "examine": "A symbol of your chompy bird hunting prowess.", + "durability": null, + "name": "Chompy bird hat", + "weight": "0.33", + "archery_ticket_price": "0", + "id": "2985", + "equipment_slot": "0" + }, + { + "examine": "A symbol of your chompy bird hunting prowess.", + "durability": null, + "name": "Chompy bird hat", + "weight": "0.33", + "archery_ticket_price": "0", + "id": "2986", + "equipment_slot": "0" + }, + { + "examine": "A symbol of your chompy bird hunting prowess.", + "durability": null, + "name": "Chompy bird hat", + "weight": "0.33", + "archery_ticket_price": "0", + "id": "2987", + "equipment_slot": "0" + }, + { + "examine": "A symbol of your chompy bird hunting prowess.", + "durability": null, + "name": "Chompy bird hat", + "weight": "0.33", + "archery_ticket_price": "0", + "id": "2988", + "equipment_slot": "0" + }, + { + "examine": "A symbol of your chompy bird hunting prowess.", + "durability": null, + "name": "Chompy bird hat", + "weight": "0.33", + "archery_ticket_price": "0", + "id": "2989", + "equipment_slot": "0" + }, + { + "examine": "A symbol of your chompy bird hunting prowess.", + "durability": null, + "name": "Chompy bird hat", + "weight": "0.33", + "archery_ticket_price": "0", + "id": "2990", + "equipment_slot": "0" + }, + { + "examine": "A symbol of your chompy bird hunting prowess.", + "durability": null, + "name": "Chompy bird hat", + "weight": "0.33", + "archery_ticket_price": "0", + "id": "2991", + "equipment_slot": "0" + }, + { + "examine": "A symbol of your chompy bird hunting prowess.", + "durability": null, + "name": "Chompy bird hat", + "weight": "0.33", + "archery_ticket_price": "0", + "id": "2992", + "equipment_slot": "0" + }, + { + "examine": "A symbol of your chompy bird hunting prowess.", + "durability": null, + "name": "Chompy bird hat", + "weight": "0.33", + "archery_ticket_price": "0", + "id": "2993", + "equipment_slot": "0" + }, + { + "examine": "A symbol of your chompy bird hunting prowess.", + "durability": null, + "name": "Chompy bird hat", + "weight": "0.33", + "archery_ticket_price": "0", + "id": "2994", + "equipment_slot": "0" + }, + { + "examine": "A symbol of your chompy bird hunting prowess.", + "durability": null, + "name": "Chompy bird hat", + "weight": "0.33", + "archery_ticket_price": "0", + "id": "2995", + "equipment_slot": "0" + }, + { + "examine": "I can exchange these for further experience or items.", + "durability": null, + "name": "Agility arena ticket", + "archery_ticket_price": "0", + "id": "2996" + }, + { + "shop_price": "800", + "ge_buy_limit": "10", + "examine": "You should see the shark...", + "grand_exchange_price": "1500000", + "durability": null, + "name": "Pirate's hook", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "2997", + "bonuses": "0,0,0,0,0,1,5,3,0,0,1,0,0,0,0", + "equipment_slot": "9" + }, + { + "shop_price": "3", + "ge_buy_limit": "10000", + "examine": "A fresh herb.", + "grand_exchange_price": "4056", + "durability": null, + "name": "Clean toadflax", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2998" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "4056", + "durability": null, + "name": "Clean toadflax", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "2999" + }, + { + "shop_price": "10", + "ge_buy_limit": "10000", + "examine": "A fresh herb.", + "grand_exchange_price": "10500", + "durability": null, + "name": "Clean snapdragon", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3000" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "10500", + "durability": null, + "name": "Clean snapdragon", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3001" + }, + { + "ge_buy_limit": "100", + "examine": "I need another ingredient to finish this toadflax potion.", + "grand_exchange_price": "3988", + "durability": null, + "name": "Toadflax potion(unf)", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "3002" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3988", + "durability": null, + "name": "Toadflax potion(unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3003" + }, + { + "ge_buy_limit": "100", + "examine": "I need another ingredient to finish this snapdragon potion.", + "grand_exchange_price": "9588", + "durability": null, + "name": "Snapdragon potion(unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3004" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "9588", + "durability": null, + "name": "Snapdragon potion(unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3005" + }, + { + "shop_price": "150", + "examine": "Keep out of reach of children and familiars.", + "durability": null, + "name": "Firework", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3006" + }, + { + "durability": null, + "name": "Firework", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3007" + }, + { + "shop_price": "145", + "ge_buy_limit": "100", + "examine": "4 doses of energy potion.", + "grand_exchange_price": "33", + "durability": null, + "name": "Energy potion(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3008" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "33", + "durability": null, + "name": "Energy potion(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3009" + }, + { + "shop_price": "145", + "ge_buy_limit": "100", + "examine": "3 doses of energy potion.", + "grand_exchange_price": "18", + "durability": null, + "name": "Energy potion(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3010" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "18", + "durability": null, + "name": "Energy potion(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3011" + }, + { + "shop_price": "145", + "ge_buy_limit": "100", + "examine": "2 doses of energy potion.", + "grand_exchange_price": "11", + "durability": null, + "name": "Energy potion(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3012" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "11", + "durability": null, + "name": "Energy potion(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3013" + }, + { + "shop_price": "145", + "ge_buy_limit": "100", + "examine": "1 dose of energy potion.", + "grand_exchange_price": "25", + "durability": null, + "name": "Energy potion(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3014" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "25", + "durability": null, + "name": "Energy potion(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3015" + }, + { + "shop_price": "4000", + "ge_buy_limit": "1000", + "examine": "4 doses of super energy potion.", + "grand_exchange_price": "3088", + "durability": null, + "name": "Super energy(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3016" + }, + { + "shop_price": "4000", + "ge_buy_limit": "1000", + "grand_exchange_price": "3088", + "durability": null, + "name": "Super energy(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3017" + }, + { + "ge_buy_limit": "1000", + "examine": "3 doses of super energy potion.", + "grand_exchange_price": "2485", + "durability": null, + "name": "Super energy(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3018" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "2485", + "durability": null, + "name": "Super energy(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3019" + }, + { + "ge_buy_limit": "1000", + "examine": "2 doses of super energy potion.", + "grand_exchange_price": "1592", + "durability": null, + "name": "Super energy(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3020" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1592", + "durability": null, + "name": "Super energy(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3021" + }, + { + "ge_buy_limit": "1000", + "examine": "1 dose of super energy potion.", + "grand_exchange_price": "1432", + "durability": null, + "name": "Super energy(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3022" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1432", + "durability": null, + "name": "Super energy(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3023" + }, + { + "shop_price": "12000", + "ge_buy_limit": "1000", + "examine": "4 doses of super restore potion.", + "grand_exchange_price": "11500", + "durability": null, + "name": "Super restore(4)", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "3024" + }, + { + "shop_price": "12000", + "ge_buy_limit": "1000", + "grand_exchange_price": "11500", + "durability": null, + "name": "Super restore(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3025" + }, + { + "ge_buy_limit": "1000", + "examine": "3 doses of super restore potion.", + "grand_exchange_price": "8690", + "durability": null, + "name": "Super restore(3)", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "3026" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "8690", + "durability": null, + "name": "Super restore(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3027" + }, + { + "ge_buy_limit": "1000", + "examine": "2 doses of super restore potion.", + "grand_exchange_price": "5637", + "durability": null, + "name": "Super restore(2)", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "3028" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "5637", + "durability": null, + "name": "Super restore(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3029" + }, + { + "ge_buy_limit": "1000", + "examine": "1 dose of super restore potion.", + "grand_exchange_price": "2606", + "durability": null, + "name": "Super restore(1)", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "3030" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "2606", + "durability": null, + "name": "Super restore(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3031" + }, + { + "ge_buy_limit": "100", + "examine": "4 doses of Agility potion.", + "grand_exchange_price": "276", + "durability": null, + "name": "Agility potion(4)", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "3032" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "276", + "durability": null, + "name": "Agility potion(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3033" + }, + { + "ge_buy_limit": "100", + "examine": "3 doses of Agility potion.", + "grand_exchange_price": "148", + "durability": null, + "name": "Agility potion(3)", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "3034" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "148", + "durability": null, + "name": "Agility potion(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3035" + }, + { + "ge_buy_limit": "100", + "examine": "2 doses of Agility potion.", + "grand_exchange_price": "115", + "durability": null, + "name": "Agility potion(2)", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "3036" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "115", + "durability": null, + "name": "Agility potion(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3037" + }, + { + "ge_buy_limit": "100", + "examine": "1 dose of Agility potion.", + "grand_exchange_price": "306", + "durability": null, + "name": "Agility potion(1)", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "3038" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "306", + "durability": null, + "name": "Agility potion(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3039" + }, + { + "ge_buy_limit": "100", + "examine": "4 doses of Magic potion.", + "grand_exchange_price": "7214", + "durability": null, + "name": "Magic potion(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3040" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "7214", + "durability": null, + "name": "Magic potion(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3041" + }, + { + "ge_buy_limit": "100", + "examine": "3 doses of Magic potion.", + "grand_exchange_price": "5285", + "durability": null, + "name": "Magic potion(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3042" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "5285", + "durability": null, + "name": "Magic potion(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3043" + }, + { + "ge_buy_limit": "100", + "examine": "2 doses of Magic potion.", + "grand_exchange_price": "3697", + "durability": null, + "name": "Magic potion(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3044" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3697", + "durability": null, + "name": "Magic potion(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3045" + }, + { + "ge_buy_limit": "100", + "examine": "1 dose of Magic potion.", + "grand_exchange_price": "1826", + "durability": null, + "name": "Magic potion(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3046" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1826", + "durability": null, + "name": "Magic potion(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3047" + }, + { + "durability": null, + "name": "Pirate's hook", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3048" + }, + { + "requirements": "{15,30}", + "ge_buy_limit": "10000", + "examine": "I need to clean this herb before I can use it.", + "grand_exchange_price": "3996", + "durability": null, + "name": "Grimy toadflax", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3049" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "3996", + "durability": null, + "name": "Grimy toadflax", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3050" + }, + { + "requirements": "{15,59}", + "ge_buy_limit": "10000", + "examine": "I need to clean this herb before I can use it.", + "grand_exchange_price": "10500", + "durability": null, + "name": "Grimy snapdragon", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3051" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "10500", + "durability": null, + "name": "Grimy snapdragon", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3052" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "It's a slightly magical stick.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "turn180_anim": "1206", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "grand_exchange_price": "9985", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "3053", + "stand_turn_anim": "1209", + "bonuses": "7,-1,28,12,0,2,3,1,12,0,0,35,0,0,0", + "requirements": "{0,30}-{6,30}", + "durability": null, + "weight": "2.2", + "weapon_interface": "1", + "equip_audio": "2247", + "render_anim": "28", + "attack_audios": "2555,0,0,0", + "name": "Lava battlestaff" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "It's a slightly magical stick.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "turn180_anim": "1206", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "grand_exchange_price": "34100", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "3054", + "stand_turn_anim": "1209", + "bonuses": "10,-1,40,14,0,2,3,1,14,0,0,50,0,0,0", + "requirements": "{0,40}-{6,40}", + "shop_price": "160", + "durability": null, + "weight": "2", + "weapon_interface": "1", + "equip_audio": "2247", + "render_anim": "28", + "attack_audios": "2555,0,0,0", + "name": "Mystic lava staff" + }, + { + "durability": null, + "name": "Lava battlestaff", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3055" + }, + { + "durability": null, + "name": "Mystic lava staff", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3056" + }, + { + "examine": "A mime would wear this.", + "durability": null, + "name": "Mime mask", + "archery_ticket_price": "0", + "id": "3057", + "equipment_slot": "0" + }, + { + "remove_sleeves": "true", + "examine": "A mime would wear these.", + "durability": null, + "name": "Mime top", + "archery_ticket_price": "0", + "id": "3058", + "equipment_slot": "4" + }, + { + "examine": "A mime would wear these.", + "durability": null, + "name": "Mime legs", + "archery_ticket_price": "0", + "id": "3059", + "equipment_slot": "7" + }, + { + "examine": "A mime would wear these.", + "durability": null, + "name": "Mime gloves", + "archery_ticket_price": "0", + "id": "3060", + "equipment_slot": "9" + }, + { + "examine": "A mime would wear these.", + "durability": null, + "name": "Mime boots", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "3061", + "equipment_slot": "10" + }, + { + "examine": "It seems to be humming...", + "durability": null, + "name": "Strange box", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "3062" + }, + { + "requirements": "{4,10}", + "ge_buy_limit": "1000", + "examine": "A deadly throwing dart with a black tip.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "582,582,582,582", + "grand_exchange_price": "628", + "attack_audios": "2547,0,0,0", + "name": "Black dart", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3093", + "bonuses": "0,0,0,0,7,0,0,0,0,0,0,0,0,0,6" + }, + { + "requirements": "{4,10}", + "ge_buy_limit": "1000", + "examine": "A deadly throwing dart with a black tip.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "582,582,582,582", + "grand_exchange_price": "740", + "attack_audios": "2547,0,0,0", + "name": "Black dart(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3094", + "bonuses": "0,0,0,0,7,0,0,0,0,0,0,0,0,0,6" + }, + { + "shop_price": "48", + "ge_buy_limit": "100", + "examine": "A set of fighting claws.", + "durability": null, + "weight": "0.9", + "attack_speed": "4", + "two_handed": "true", + "weapon_interface": "9", + "equip_audio": "1003", + "render_anim": "2583", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,390,390", + "grand_exchange_price": "702", + "attack_audios": "2548,2548,2548,2548", + "name": "Bronze claws", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3095", + "bonuses": "3,4,-4,0,0,1,2,1,0,0,0,5,0,0,0" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "A set of fighting claws.", + "durability": null, + "weight": "0.9", + "attack_speed": "4", + "two_handed": "true", + "weapon_interface": "9", + "equip_audio": "1003", + "render_anim": "2583", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,390,390", + "grand_exchange_price": "13", + "attack_audios": "2548,2548,2548,2548", + "name": "Iron claws", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3096", + "bonuses": "4,6,-4,0,0,2,3,1,0,0,0,7,0,0,0" + }, + { + "requirements": "{0,5}", + "shop_price": "175", + "ge_buy_limit": "100", + "examine": "A set of fighting claws.", + "durability": null, + "weight": "0.9", + "attack_speed": "4", + "two_handed": "true", + "weapon_interface": "9", + "equip_audio": "1003", + "render_anim": "2583", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,390,390", + "grand_exchange_price": "20", + "attack_audios": "2548,2548,2548,2548", + "name": "Steel claws", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3097", + "bonuses": "8,11,-4,0,0,3,6,2,0,0,0,12,0,0,0" + }, + { + "requirements": "{0,10}", + "ge_buy_limit": "100", + "examine": "A set of fighting claws.", + "durability": null, + "weight": "6", + "attack_speed": "4", + "two_handed": "true", + "weapon_interface": "9", + "equip_audio": "1003", + "render_anim": "2583", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,390,390", + "grand_exchange_price": "940", + "attack_audios": "2548,2548,2548,2548", + "name": "Black claws", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3098", + "bonuses": "10,14,-4,0,0,4,7,2,0,0,0,14,0,0,0" + }, + { + "requirements": "{0,20}", + "ge_buy_limit": "100", + "examine": "A set of fighting claws.", + "durability": null, + "weight": "0.9", + "attack_speed": "4", + "two_handed": "true", + "weapon_interface": "9", + "equip_audio": "1003", + "render_anim": "2583", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,390,390", + "grand_exchange_price": "114", + "attack_audios": "2548,2548,2548,2548", + "name": "Mithril claws", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3099", + "bonuses": "11,16,-4,0,0,4,8,2,0,0,0,17,0,0,0" + }, + { + "requirements": "{0,30}", + "ge_buy_limit": "100", + "examine": "A set of fighting claws.", + "durability": null, + "attack_speed": "4", + "two_handed": "true", + "weapon_interface": "9", + "equip_audio": "1003", + "render_anim": "2583", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,390,390", + "grand_exchange_price": "649", + "attack_audios": "2548,2548,2548,2548", + "name": "Adamant claws", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3100", + "bonuses": "18,23,-4,0,0,6,12,3,0,0,0,24,0,0,0" + }, + { + "requirements": "{0,40}", + "ge_buy_limit": "100", + "examine": "A set of fighting claws.", + "has_special": "true", + "durability": null, + "weight": "0.9", + "attack_speed": "4", + "two_handed": "true", + "weapon_interface": "9", + "equip_audio": "1003", + "render_anim": "2583", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,390,390", + "lendable": "true", + "grand_exchange_price": "6939", + "attack_audios": "2548,2548,2548,2548", + "name": "Rune claws", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3101", + "bonuses": "26,38,-4,0,0,10,19,5,0,0,0,39,0,0,0" + }, + { + "examine": "The combination to Burthorpe Castle's equipment room.", + "durability": null, + "name": "Combination", + "archery_ticket_price": "0", + "id": "3102" + }, + { + "examine": "The guard wrote the IOU on the back of some paper.", + "durability": null, + "name": "Iou", + "archery_ticket_price": "0", + "id": "3103" + }, + { + "examine": "This map shows the secret way up to Death Plateau.", + "durability": null, + "name": "Secret way map", + "archery_ticket_price": "0", + "id": "3104" + }, + { + "shop_price": "1900", + "ge_buy_limit": "100", + "examine": "Boots made for general climbing; rocks a speciality.", + "durability": null, + "destroy": "true", + "weight": "0.3", + "equip_audio": "2237", + "equipment_slot": "10", + "grand_exchange_price": "51400", + "name": "Climbing boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3105", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,2,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "51400", + "durability": null, + "name": "Climbing boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3106" + }, + { + "examine": "Climbing boots with spikes.", + "durability": null, + "name": "Spiked boots", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "3107", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,2,0,0,0", + "equip_audio": "2237", + "equipment_slot": "10" + }, + { + "examine": "Place on the stone mechanism in the right order to open the door.", + "durability": null, + "name": "Stone ball", + "archery_ticket_price": "0", + "id": "3109" + }, + { + "examine": "Place on the stone mechanism in the right order to open the door.", + "durability": null, + "name": "Stone ball", + "archery_ticket_price": "0", + "id": "3110" + }, + { + "examine": "Place on the stone mechanism in the right order to open the door.", + "durability": null, + "name": "Stone ball", + "archery_ticket_price": "0", + "id": "3111" + }, + { + "examine": "Place on the stone mechanism in the right order to open the door.", + "durability": null, + "name": "Stone ball", + "archery_ticket_price": "0", + "id": "3112" + }, + { + "examine": "Place on the stone mechanism in the right order to open the door.", + "durability": null, + "name": "Stone ball", + "archery_ticket_price": "0", + "id": "3113" + }, + { + "examine": "Entrance certificate to the Imperial Guard.", + "durability": null, + "name": "Certificate", + "archery_ticket_price": "0", + "id": "3114" + }, + { + "durability": null, + "name": "Bronze claws", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3115" + }, + { + "durability": null, + "name": "Iron claws", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3116" + }, + { + "durability": null, + "name": "Steel claws", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3117" + }, + { + "durability": null, + "name": "Black claws", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3118" + }, + { + "durability": null, + "name": "Mithril claws", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3119" + }, + { + "durability": null, + "name": "Adamant claws", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3120" + }, + { + "durability": null, + "name": "Rune claws", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3121" + }, + { + "requirements": "{1,50}-{2,50}", + "ge_buy_limit": "10", + "examine": "A solid stone shield.", + "durability": null, + "weight": "6.8", + "absorb": "5,0,10", + "equipment_slot": "5", + "lendable": "true", + "grand_exchange_price": "34800", + "name": "Granite shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3122", + "bonuses": "0,0,0,-12,-8,40,42,38,0,65,50,0,0,0,0" + }, + { + "ge_buy_limit": "10000", + "examine": "Large glistening bones which glow with a pale yellow aura.", + "grand_exchange_price": "1975", + "durability": null, + "name": "Shaikahan bones", + "tradeable": "true", + "weight": "1.5", + "archery_ticket_price": "0", + "id": "3123" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "1975", + "durability": null, + "name": "Shaikahan bones", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3124" + }, + { + "ge_buy_limit": "10000", + "examine": "Fairly big bones which smell distinctly of Jogre.", + "grand_exchange_price": "1023", + "durability": null, + "name": "Jogre bones", + "tradeable": "true", + "weight": "0.8", + "archery_ticket_price": "0", + "id": "3125" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "1023", + "durability": null, + "name": "Jogre bones", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3126" + }, + { + "examine": "These blackened Jogre bones have been somehow burnt.", + "durability": null, + "name": "Burnt jogre bones", + "tradeable": "false", + "weight": "0.8", + "archery_ticket_price": "0", + "id": "3127" + }, + { + "examine": "Burnt Jogre bones smothered with raw Karambwanji Paste.", + "durability": null, + "name": "Pasty jogre bones", + "tradeable": "false", + "weight": "0.8", + "archery_ticket_price": "0", + "id": "3128" + }, + { + "examine": "Burnt Jogre bones smothered with cooked Karambwanji paste.", + "durability": null, + "name": "Pasty jogre bones", + "tradeable": "false", + "weight": "0.8", + "archery_ticket_price": "0", + "id": "3129" + }, + { + "examine": "Burnt Jogre bones marinated in a lovely Karambwanji sauce. Perfect.", + "durability": null, + "name": "Marinated j' bones", + "tradeable": "false", + "weight": "0.8", + "archery_ticket_price": "0", + "id": "3130" + }, + { + "examine": "Jogre bones smothered with raw Karambwanji paste.", + "durability": null, + "name": "Pasty jogre bones", + "tradeable": "false", + "weight": "0.8", + "archery_ticket_price": "0", + "id": "3131" + }, + { + "examine": "Jogre bones smothered with cooked Karambwanji paste.", + "durability": null, + "name": "Pasty jogre bones", + "tradeable": "false", + "weight": "0.8", + "archery_ticket_price": "0", + "id": "3132" + }, + { + "examine": "Jogre Bones marinated in Karambwanji sauce. Not quite right.", + "durability": null, + "name": "Marinated j' bones", + "tradeable": "false", + "weight": "0.8", + "archery_ticket_price": "0", + "id": "3133" + }, + { + "durability": null, + "name": "Granite shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3134" + }, + { + "shop_price": "1", + "examine": "The key to the troll prison.", + "durability": null, + "name": "Cell key 1", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "3136" + }, + { + "examine": "The key to the troll prison.", + "durability": null, + "name": "Cell key 2", + "weight": "1", + "archery_ticket_price": "0", + "id": "3137" + }, + { + "ge_buy_limit": "10000", + "examine": "How am I supposed to eat that?!", + "grand_exchange_price": "1834", + "durability": null, + "name": "Potato cactus", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "3138" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "1834", + "durability": null, + "name": "Potato cactus", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3139" + }, + { + "requirements": "{1,60}", + "ge_buy_limit": "10", + "examine": "A series of connected metal rings.", + "rare_item": "true", + "durability": null, + "weight": "6.8", + "absorb": "4,0,9", + "equipment_slot": "4", + "lendable": "true", + "remove_sleeves": "true", + "grand_exchange_price": "4300000", + "name": "Dragon chainbody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3140", + "bonuses": "0,0,0,-15,0,81,93,98,-3,82,50,0,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "4300000", + "durability": null, + "name": "Dragon chainbody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3141" + }, + { + "shop_price": "440", + "ge_buy_limit": "20000", + "examine": "A raw green octopus.", + "grand_exchange_price": "1775", + "durability": null, + "name": "Raw karambwan", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "3142" + }, + { + "ge_buy_limit": "20000", + "grand_exchange_price": "1775", + "durability": null, + "name": "Raw karambwan", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3143" + }, + { + "shop_price": "460", + "ge_buy_limit": "10000", + "examine": "Cooked octopus.", + "grand_exchange_price": "1455", + "durability": null, + "name": "Cooked karambwan", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "3144" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "1455", + "durability": null, + "name": "Cooked karambwan", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3145" + }, + { + "examine": "Cooked octopus. It looks poorly cooked and quite dangerous.", + "durability": null, + "name": "Poison karambwan", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "3146" + }, + { + "shop_price": "460", + "examine": "Cooked octopus.", + "grand_exchange_price": "906", + "durability": null, + "name": "Cooked karambwan", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "3147" + }, + { + "durability": null, + "name": "Burnt karambwan", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3149" + }, + { + "examine": "Small brightly coloured tropical fish.", + "durability": null, + "name": "Raw karambwanji", + "archery_ticket_price": "0", + "id": "3150" + }, + { + "examine": "Small brightly coloured tropical fish.", + "durability": null, + "name": "Karambwanji", + "weight": "0.99", + "archery_ticket_price": "0", + "id": "3151" + }, + { + "examine": "Freshly made octopus paste. It smells quite nauseating.", + "durability": null, + "name": "Karambwan paste", + "archery_ticket_price": "0", + "id": "3152" + }, + { + "examine": "Freshly made octopus paste. It smells quite nauseating.", + "durability": null, + "name": "Karambwan paste", + "archery_ticket_price": "0", + "id": "3153" + }, + { + "examine": "Freshly made octopus paste. It smells quite nauseating.", + "durability": null, + "name": "Karambwan paste", + "archery_ticket_price": "0", + "id": "3154" + }, + { + "examine": "This paste smells of raw fish./This paste smells of cooked fish.", + "durability": null, + "name": "Karambwanji paste", + "archery_ticket_price": "0", + "id": "3155" + }, + { + "examine": "This paste smells of raw fish./This paste smells of cooked fish.", + "durability": null, + "name": "Karambwanji paste", + "archery_ticket_price": "0", + "id": "3156" + }, + { + "requirements": "{10,65}", + "shop_price": "5", + "ge_buy_limit": "100", + "examine": "A wide bodied and thin necked vessel, encrusted with sea salt. / The Karambwan Vessel is loaded with Karambwanji", + "grand_exchange_price": "221", + "durability": null, + "name": "Karambwan vessel", + "tradeable": "true", + "weight": "3", + "archery_ticket_price": "0", + "id": "3157", + "equipment_slot": "3" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "221", + "durability": null, + "name": "Karambwan vessel", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3158" + }, + { + "requirements": "{10,65}", + "shop_price": "5", + "examine": "A wide bodied and thin necked vessel, encrusted with sea salt. / The Karambwan Vessel is loaded with Karambwanji", + "grand_exchange_price": "240", + "durability": null, + "name": "Karambwan vessel", + "tradeable": "true", + "weight": "3", + "archery_ticket_price": "0", + "id": "3159" + }, + { + "durability": null, + "name": "Karambwan vessel", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3160" + }, + { + "examine": "A set of instructions explaining how to construct a Karambwan vessel", + "durability": null, + "name": "Crafting manual", + "archery_ticket_price": "0", + "id": "3161" + }, + { + "ge_buy_limit": "100", + "examine": "You swear you had more than three slices before.", + "grand_exchange_price": "38", + "durability": null, + "name": "Sliced banana", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3162" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "38", + "durability": null, + "name": "Sliced banana", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3163" + }, + { + "shop_price": "27", + "examine": "A very strong spirit brewed in Karamja.", + "durability": null, + "name": "Karamjan rum", + "archery_ticket_price": "0", + "id": "3164" + }, + { + "shop_price": "27", + "examine": "A very strong spirit brewed in Karamja.", + "durability": null, + "name": "Karamjan rum", + "archery_ticket_price": "0", + "id": "3165" + }, + { + "examine": "It's the body of a dead monkey.", + "durability": null, + "name": "Monkey corpse", + "weight": "1", + "archery_ticket_price": "0", + "id": "3166" + }, + { + "examine": "It's the skin of a (hopefully) dead monkey.", + "durability": null, + "name": "Monkey skin", + "archery_ticket_price": "0", + "id": "3167" + }, + { + "examine": "A 'Seaweed in Monkey Skin' sandwich. Perfect for statue repair.", + "durability": null, + "name": "Seaweed sandwich", + "archery_ticket_price": "0", + "id": "3168" + }, + { + "examine": "A body of a dead monkey, tastefully stuffed with seaweed.", + "durability": null, + "name": "Stuffed monkey", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "3169" + }, + { + "turn90cw_anim": "1207", + "examine": "A Karambwan poisoned bronze tipped spear.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1206", + "equip_audio": "2247", + "defence_anim": "2079", + "render_anim": "28", + "equipment_slot": "3", + "attack_anims": "2080,2081,2082,2080", + "grand_exchange_price": "266", + "stand_anim": "813", + "name": "Bronze spear(kp)", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "3170", + "stand_turn_anim": "1209", + "bonuses": "5,5,5,0,0,1,1,0,0,0,0,6,0,0,0" + }, + { + "turn90cw_anim": "1207", + "examine": "A Karambwan poisoned iron tipped spear.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1206", + "equip_audio": "2247", + "defence_anim": "2079", + "render_anim": "28", + "equipment_slot": "3", + "attack_anims": "2080,2081,2082,2080", + "grand_exchange_price": "304", + "stand_anim": "813", + "name": "Iron spear(kp)", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "3171", + "stand_turn_anim": "1209", + "bonuses": "8,8,8,0,0,1,1,0,0,0,0,10,0,0,0" + }, + { + "requirements": "{0,5}", + "turn90cw_anim": "1207", + "examine": "A Karambwan poisoned steel tipped spear.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1206", + "equip_audio": "2247", + "defence_anim": "2079", + "render_anim": "28", + "equipment_slot": "3", + "attack_anims": "2080,2081,2082,2080", + "grand_exchange_price": "503", + "stand_anim": "813", + "name": "Steel spear(kp)", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "3172", + "stand_turn_anim": "1209", + "bonuses": "12,12,12,0,0,1,1,0,0,0,0,12,0,0,0" + }, + { + "requirements": "{0,20}", + "turn90cw_anim": "1207", + "examine": "A Karambwan poisoned mithril tipped spear.", + "walk_anim": "1205", + "durability": null, + "weight": "1.8", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1206", + "equip_audio": "2247", + "defence_anim": "2079", + "render_anim": "28", + "equipment_slot": "3", + "attack_anims": "2080,2081,2082,2080", + "grand_exchange_price": "368", + "stand_anim": "813", + "name": "Mithril spear(kp)", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "3173", + "stand_turn_anim": "1209", + "bonuses": "17,17,17,0,0,1,1,0,0,0,0,18,0,0,0" + }, + { + "requirements": "{0,30}", + "turn90cw_anim": "1207", + "examine": "A Karambwan poisoned adamant tipped spear.", + "walk_anim": "1205", + "durability": null, + "weight": "2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1206", + "equip_audio": "2247", + "defence_anim": "2079", + "render_anim": "28", + "equipment_slot": "3", + "attack_anims": "2080,2081,2082,2080", + "grand_exchange_price": "1093", + "stand_anim": "813", + "name": "Adamant spear(kp)", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "3174", + "stand_turn_anim": "1209", + "bonuses": "24,24,24,0,0,1,1,0,0,0,0,28,0,0,0" + }, + { + "requirements": "{0,40}", + "turn90cw_anim": "1207", + "examine": "\tA Karambwan poisoned rune tipped spear.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1206", + "equip_audio": "2247", + "defence_anim": "2079", + "render_anim": "28", + "equipment_slot": "3", + "attack_anims": "2080,2081,2082,2080", + "grand_exchange_price": "12089", + "stand_anim": "813", + "name": "Rune spear(kp)", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "3175", + "stand_turn_anim": "1209", + "bonuses": "36,36,36,0,0,1,1,0,0,0,0,42,0,0,0" + }, + { + "turn90cw_anim": "1207", + "examine": "A Karambwan poisoned dragon tipped spear.", + "walk_anim": "1205", + "has_special": "true", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "turn180_anim": "1206", + "defence_anim": "2079", + "equipment_slot": "3", + "attack_anims": "2080,2081,2082,2080", + "grand_exchange_price": "37446", + "stand_anim": "813", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "3176", + "stand_turn_anim": "1209", + "bonuses": "55,55,55,0,0,5,5,5,5,5,0,60,0,0,0", + "requirements": "{0,60}", + "durability": null, + "weight": "2", + "weapon_interface": "14", + "equip_audio": "2247", + "render_anim": "28", + "name": "Dragon spear(kp)" + }, + { + "durability": null, + "name": "Picture", + "archery_ticket_price": "0", + "id": "3177", + "equipment_slot": "5" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3178" + }, + { + "examine": "These are smallish monkey bones.", + "grand_exchange_price": "383", + "durability": null, + "name": "Monkey bones", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "3179" + }, + { + "examine": "These are medium sized monkey bones.", + "grand_exchange_price": "383", + "durability": null, + "name": "Monkey bones", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "3180" + }, + { + "examine": "These are quite large monkey bones.", + "grand_exchange_price": "383", + "durability": null, + "name": "Monkey bones", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "3181" + }, + { + "examine": "These are quite large monkey bones.", + "grand_exchange_price": "383", + "durability": null, + "name": "Monkey bones", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "3182" + }, + { + "ge_buy_limit": "10000", + "examine": "These are small monkey bones.", + "grand_exchange_price": "588", + "durability": null, + "name": "Monkey bones", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "3183" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "588", + "durability": null, + "name": "Monkey bones", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3184" + }, + { + "examine": "These are smallish monkey bones. They smell extremely nauseating.", + "grand_exchange_price": "383", + "durability": null, + "name": "Monkey bones", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "3185" + }, + { + "examine": "These are small monkey bones. They smell extremely nauseating.", + "grand_exchange_price": "383", + "durability": null, + "name": "Monkey bones", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "3186" + }, + { + "shop_price": "140", + "grand_exchange_price": "140", + "durability": null, + "name": "Bones", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "3187" + }, + { + "shop_price": "60", + "ge_buy_limit": "100", + "examine": "A piece of silk which can be used to remove poison from weapons.", + "grand_exchange_price": "286", + "durability": null, + "name": "Cleaning cloth", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "3188" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "286", + "durability": null, + "name": "Cleaning cloth", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3189" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A bronze halberd.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "7", + "two_handed": "true", + "turn180_anim": "1206", + "defence_anim": "430", + "equipment_slot": "3", + "attack_anims": "440,440,412,440", + "grand_exchange_price": "522", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "3190", + "stand_turn_anim": "1209", + "bonuses": "7,8,0,-4,0,-1,1,2,0,0,0,8,0,0,0", + "shop_price": "104", + "durability": null, + "weight": "3", + "weapon_interface": "15", + "equip_audio": "2247", + "render_anim": "28", + "name": "Bronze halberd" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "522", + "durability": null, + "name": "Bronze halberd", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3191" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "An iron halberd.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "7", + "two_handed": "true", + "turn180_anim": "1206", + "defence_anim": "430", + "equipment_slot": "3", + "attack_anims": "440,440,412,440", + "grand_exchange_price": "124", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "3192", + "stand_turn_anim": "1209", + "bonuses": "9,12,0,-4,0,-1,1,2,0,0,0,12,0,0,0", + "shop_price": "364", + "durability": null, + "weight": "3.1", + "weapon_interface": "15", + "equip_audio": "2247", + "render_anim": "28", + "name": "Iron halberd" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "124", + "durability": null, + "name": "Iron halberd", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3193" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A steel halberd.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "7", + "two_handed": "true", + "turn180_anim": "1206", + "defence_anim": "430", + "equipment_slot": "3", + "attack_anims": "440,440,412,440", + "grand_exchange_price": "726", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "3194", + "stand_turn_anim": "1209", + "bonuses": "14,19,0,-4,0,-1,2,3,0,0,0,20,0,0,0", + "requirements": "{0,5}", + "shop_price": "1300", + "durability": null, + "weight": "3", + "weapon_interface": "15", + "equip_audio": "2247", + "render_anim": "28", + "name": "Steel halberd" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "726", + "durability": null, + "name": "Steel halberd", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3195" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A black halberd.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "7", + "two_handed": "true", + "turn180_anim": "1206", + "defence_anim": "430", + "equipment_slot": "3", + "attack_anims": "440,440,412,440", + "grand_exchange_price": "4344", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "3196", + "stand_turn_anim": "1209", + "bonuses": "19,25,0,-4,0,-1,2,3,0,0,0,20,0,0,0", + "requirements": "{0,10}-{2,5}", + "shop_price": "2496", + "durability": null, + "weight": "3", + "weapon_interface": "15", + "equip_audio": "2247", + "render_anim": "28", + "name": "Black halberd" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "4344", + "durability": null, + "name": "Black halberd", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3197" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A mithril halberd.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "7", + "two_handed": "true", + "turn180_anim": "1206", + "defence_anim": "430", + "equipment_slot": "3", + "attack_anims": "440,440,412,440", + "grand_exchange_price": "6995", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "3198", + "stand_turn_anim": "1209", + "bonuses": "22,28,0,-4,0,-1,2,4,0,0,0,29,0,0,0", + "requirements": "{0,20}-{2,10}", + "shop_price": "3380", + "durability": null, + "weight": "2.7", + "weapon_interface": "15", + "equip_audio": "2247", + "render_anim": "28", + "name": "Mithril halberd" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "6995", + "durability": null, + "name": "Mithril halberd", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3199" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "An adamant halberd.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "7", + "two_handed": "true", + "turn180_anim": "1206", + "defence_anim": "430", + "equipment_slot": "3", + "attack_anims": "440,440,412,440", + "grand_exchange_price": "4690", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "3200", + "stand_turn_anim": "1209", + "bonuses": "28,41,0,-4,0,-1,3,4,0,0,0,42,0,0,0", + "requirements": "{0,30}-{2,15}", + "shop_price": "8320", + "durability": null, + "weight": "3.6", + "weapon_interface": "15", + "equip_audio": "2247", + "render_anim": "28", + "name": "Adamant halberd" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "4690", + "durability": null, + "name": "Adamant halberd", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3201" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A rune halberd.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "7", + "two_handed": "true", + "turn180_anim": "1206", + "defence_anim": "430", + "equipment_slot": "3", + "attack_anims": "440,440,412,440", + "grand_exchange_price": "77100", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "3202", + "stand_turn_anim": "1209", + "bonuses": "48,67,0,-4,0,-1,4,5,0,0,0,68,0,0,0", + "requirements": "{0,40}-{2,20}", + "shop_price": "128000", + "durability": null, + "weight": "3", + "weapon_interface": "15", + "equip_audio": "2247", + "render_anim": "28", + "lendable": "true", + "name": "Rune halberd" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "77100", + "durability": null, + "name": "Rune halberd", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3203" + }, + { + "ge_buy_limit": "10", + "turn90cw_anim": "1207", + "examine": "A dragon halberd.", + "walk_anim": "1205", + "has_special": "true", + "turn90ccw_anim": "1208", + "attack_speed": "7", + "two_handed": "true", + "turn180_anim": "1206", + "defence_anim": "430", + "equipment_slot": "3", + "attack_anims": "440,440,412,440", + "grand_exchange_price": "201000", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "3204", + "stand_turn_anim": "1209", + "bonuses": "70,95,0,-4,0,-1,4,5,0,0,0,89,0,0,0", + "requirements": "{0,60}-{2,30}", + "shop_price": "325000", + "durability": null, + "weight": "3.1", + "weapon_interface": "15", + "equip_audio": "2247", + "render_anim": "28", + "lendable": "true", + "name": "Dragon halberd" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "201000", + "durability": null, + "name": "Dragon halberd", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3205" + }, + { + "examine": "A summons from King Lathas.", + "durability": null, + "name": "King's message", + "archery_ticket_price": "0", + "id": "3206" + }, + { + "examine": "A letter for King Lathas from Lord Iorwerth.", + "durability": null, + "name": "Iorwerths message", + "archery_ticket_price": "0", + "id": "3207" + }, + { + "examine": "Lord Iorwerth's crystal pendant.", + "durability": null, + "name": "Crystal pendant", + "archery_ticket_price": "0", + "id": "3208", + "equipment_slot": "2" + }, + { + "examine": "A piece of chemical formation.", + "durability": null, + "name": "Sulphur", + "weight": "0.6", + "archery_ticket_price": "0", + "id": "3209" + }, + { + "shop_price": "4", + "ge_buy_limit": "10000", + "examine": "Some limestone.", + "grand_exchange_price": "238", + "durability": null, + "name": "Limestone", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "3211" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "238", + "durability": null, + "name": "Limestone", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3212" + }, + { + "examine": "Some quicklime.", + "durability": null, + "name": "Quicklime", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "3213" + }, + { + "examine": "A pot of ground quicklime.", + "durability": null, + "name": "Pot of quicklime", + "archery_ticket_price": "0", + "id": "3214" + }, + { + "shop_price": "160", + "examine": "A pile of ground sulphur.", + "durability": null, + "name": "Ground sulphur", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "3215" + }, + { + "ge_buy_limit": "100", + "examine": "An empty barrel/A Splendid barrel.", + "grand_exchange_price": "207", + "durability": null, + "name": "Barrel", + "tradeable": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "3216" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "207", + "durability": null, + "name": "Barrel", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3217" + }, + { + "examine": "A fused barrel full of fire oil.", + "durability": null, + "name": "Barrel bomb", + "weight": "32", + "archery_ticket_price": "0", + "id": "3218" + }, + { + "examine": "A fused barrel full of fire oil.", + "durability": null, + "name": "Barrel bomb", + "weight": "32", + "archery_ticket_price": "0", + "id": "3219" + }, + { + "examine": "A barrel full of coal-tar.", + "durability": null, + "name": "Barrel of coal-tar", + "weight": "32", + "archery_ticket_price": "0", + "id": "3220" + }, + { + "examine": "A barrel full of naphtha.", + "durability": null, + "name": "Barrel of naphtha", + "weight": "32", + "archery_ticket_price": "0", + "id": "3221" + }, + { + "examine": "A barrel full of naphtha and sulphur./A barrel full of naphtha and quicklime.", + "durability": null, + "name": "Naphtha mix", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "3222" + }, + { + "examine": "A barrel full of naphtha and sulphur./A barrel full of naphtha and quicklime.", + "durability": null, + "name": "Naphtha mix", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "3223" + }, + { + "examine": "A strip of cloth.", + "durability": null, + "name": "Strip of cloth", + "archery_ticket_price": "0", + "id": "3224" + }, + { + "shop_price": "67", + "ge_buy_limit": "5000", + "examine": "Might taste better cooked.", + "grand_exchange_price": "312", + "durability": null, + "name": "Raw rabbit", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "3226" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "312", + "durability": null, + "name": "Raw rabbit", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3227" + }, + { + "shop_price": "19", + "ge_buy_limit": "1000", + "examine": "Mmm this looks tasty.", + "grand_exchange_price": "35", + "durability": null, + "name": "Cooked rabbit", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3228" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "35", + "durability": null, + "name": "Cooked rabbit", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3229" + }, + { + "examine": "A book by Mel Achy.", + "durability": null, + "name": "Big book of bangs", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "3230" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3232" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3234" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3236" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3238" + }, + { + "ge_buy_limit": "100", + "examine": "Bark from a hollow tree.", + "grand_exchange_price": "23", + "durability": null, + "name": "Bark", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "3239" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "23", + "durability": null, + "name": "Bark", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3240" + }, + { + "examine": "One of 2009Scape's many citizens.", + "durability": null, + "name": "Man", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "3241" + }, + { + "examine": "He grows crops in the area.", + "durability": null, + "name": "Farmer", + "archery_ticket_price": "0", + "id": "3243" + }, + { + "examine": "Rogueish.", + "durability": null, + "name": "Rogue", + "archery_ticket_price": "0", + "id": "3247" + }, + { + "examine": "Varies, refer below.", + "durability": null, + "name": "Guard", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "3249" + }, + { + "examine": "A member of Ardougne's militia.", + "durability": null, + "name": "Knight of ardougne", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "3251" + }, + { + "examine": "The strong arm of the law.", + "durability": null, + "name": "Watchman", + "archery_ticket_price": "0", + "id": "3253" + }, + { + "examine": "A holy warrior.", + "durability": null, + "name": "Paladin", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "3255" + }, + { + "examine": "Heroic!", + "durability": null, + "name": "Hero", + "archery_ticket_price": "0", + "attack_speed": "5", + "id": "3259" + }, + { + "examine": "A pale, tough looking herb.", + "durability": null, + "name": "Goutweed", + "archery_ticket_price": "0", + "id": "3261" + }, + { + "examine": "It's tough and spiky.", + "durability": null, + "name": "Troll thistle", + "archery_ticket_price": "0", + "id": "3262" + }, + { + "examine": "It'll be easier to grind now.", + "durability": null, + "name": "Dried thistle", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "3263" + }, + { + "examine": "It's ready for mixing.", + "durability": null, + "name": "Ground thistle", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "3264" + }, + { + "examine": "It's part of Eadgar's plan.", + "durability": null, + "name": "Troll potion", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "3265" + }, + { + "examine": "It's rather drunk.", + "durability": null, + "name": "Drunk parrot", + "archery_ticket_price": "0", + "id": "3266" + }, + { + "examine": "It's dirty and smelly.", + "durability": null, + "name": "Dirty robe", + "archery_ticket_price": "0", + "id": "3267" + }, + { + "examine": "It's good enough to fool a troll.", + "durability": null, + "name": "Fake man", + "archery_ticket_price": "0", + "id": "3268" + }, + { + "examine": "The key to the Trollheim storeroom.", + "durability": null, + "name": "Storeroom key", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "3269" + }, + { + "examine": "Pineapple chunks dipped in a strong liquor.", + "durability": null, + "name": "Alco-chunks", + "archery_ticket_price": "0", + "id": "3270" + }, + { + "ge_buy_limit": "5000", + "examine": "That used to be a vampyre!", + "grand_exchange_price": "381", + "durability": null, + "name": "Vampire dust", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3325" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "381", + "durability": null, + "name": "Vampire dust", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3326" + }, + { + "remove_head": "true", + "ge_buy_limit": "100", + "examine": "An easy-to-make, marshy-coloured, Mort Myre snail shell helmet.", + "grand_exchange_price": "56", + "durability": null, + "name": "Myre snelm", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "3327", + "bonuses": "0,0,0,-3,-1,7,8,6,-1,7,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "56", + "durability": null, + "name": "Myre snelm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3328" + }, + { + "remove_head": "true", + "shop_price": "300", + "ge_buy_limit": "100", + "examine": "Rounded: A red and black snail shell helmet. Pointed: A red and black pointed snail shell helmet.", + "durability": null, + "weight": "2", + "equipment_slot": "0", + "grand_exchange_price": "291", + "name": "Blood'n'tar snelm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3329", + "bonuses": "0,0,0,-3,-1,7,8,6,-1,7,0,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "291", + "durability": null, + "name": "Blood'n'tar snelm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3330" + }, + { + "remove_head": "true", + "shop_price": "300", + "ge_buy_limit": "100", + "examine": "An easy-to-make, muddy-yellow, Mort Myre snail shell helmet.", + "grand_exchange_price": "57", + "durability": null, + "name": "Ochre snelm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3331", + "bonuses": "0,0,0,-3,-1,7,8,6,-1,7,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "57", + "durability": null, + "name": "Ochre snelm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3332" + }, + { + "remove_head": "true", + "ge_buy_limit": "100", + "examine": "A moody blue snail shell helmet, mort myre snail shell helm", + "grand_exchange_price": "73", + "durability": null, + "name": "Bruise blue snelm", + "tradeable": "true", + "weight": "1.9", + "archery_ticket_price": "0", + "id": "3333", + "bonuses": "0,0,0,-3,-1,7,8,6,-1,7,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "73", + "durability": null, + "name": "Bruise blue snelm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3334" + }, + { + "remove_head": "true", + "ge_buy_limit": "100", + "examine": "An easy-to-make, orange-and-bark coloured, Mort Myre snail shell helmet.", + "grand_exchange_price": "63", + "durability": null, + "name": "Broken bark snelm", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "3335", + "bonuses": "0,0,0,-3,-1,7,8,6,-1,7,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "63", + "durability": null, + "name": "Broken bark snelm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3336" + }, + { + "remove_head": "true", + "ge_buy_limit": "100", + "examine": "An easy-to-make, marshy-coloured, Mort Myre snail shell helmet.", + "grand_exchange_price": "58", + "durability": null, + "name": "Myre snelm", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "3337", + "bonuses": "0,0,0,-3,-1,7,8,6,-1,7,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "58", + "durability": null, + "name": "Myre snelm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3338" + }, + { + "remove_head": "true", + "shop_price": "300", + "ge_buy_limit": "100", + "examine": "Rounded: A red and black snail shell helmet. Pointed: A red and black pointed snail shell helmet.", + "durability": null, + "weight": "2", + "equipment_slot": "0", + "grand_exchange_price": "147", + "name": "Blood'n'tar snelm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3339", + "bonuses": "0,0,0,-3,-1,7,8,6,-1,7,0,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "147", + "durability": null, + "name": "Blood'n'tar snelm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3340" + }, + { + "remove_head": "true", + "shop_price": "300", + "ge_buy_limit": "100", + "examine": "An easy-to-make, muddy-yellow, Mort Myre snail shell helmet.", + "grand_exchange_price": "54", + "durability": null, + "name": "Ochre snelm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3341", + "bonuses": "0,0,0,-3,-1,7,8,6,-1,7,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "54", + "durability": null, + "name": "Ochre snelm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3342" + }, + { + "remove_head": "true", + "ge_buy_limit": "100", + "examine": "A moody blue snail shell helmet, mort myre snail shell helm", + "grand_exchange_price": "248", + "durability": null, + "name": "Bruise blue snelm", + "tradeable": "true", + "weight": "1.9", + "archery_ticket_price": "0", + "id": "3343", + "bonuses": "0,0,0,-3,-1,7,8,6,-1,7,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "248", + "durability": null, + "name": "Bruise blue snelm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3344" + }, + { + "ge_buy_limit": "100", + "examine": "An easy-to-make, 'myre'-coloured, Mort Myre snail shell; looks protective.", + "grand_exchange_price": "155", + "durability": null, + "name": "Blamish myre shell", + "tradeable": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "3345" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "155", + "durability": null, + "name": "Blamish myre shell", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3346" + }, + { + "ge_buy_limit": "100", + "examine": "An easy-to-make, red, Mort myre snail shell; looks protective.", + "grand_exchange_price": "590", + "durability": null, + "name": "Blamish red shell", + "tradeable": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "3347" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "590", + "durability": null, + "name": "Blamish red shell", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3348" + }, + { + "ge_buy_limit": "100", + "examine": "An easy-to-make, muddy-yellow, Mort Myre snail shell; looks protective.", + "grand_exchange_price": "134", + "durability": null, + "name": "Blamish ochre shell", + "tradeable": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "3349" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "134", + "durability": null, + "name": "Blamish ochre shell", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3350" + }, + { + "ge_buy_limit": "100", + "examine": "An easy-to-make, blue, Mort Myre snail shell; looks protective.", + "grand_exchange_price": "230", + "durability": null, + "name": "Blamish blue shell", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3351" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "230", + "durability": null, + "name": "Blamish blue shell", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3352" + }, + { + "ge_buy_limit": "100", + "examine": "An easy-to-make, bark-coloured, Mort Myre snail shell; looks protective.", + "grand_exchange_price": "195", + "durability": null, + "name": "Blamish bark shell", + "tradeable": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "3353" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "195", + "durability": null, + "name": "Blamish bark shell", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3354" + }, + { + "ge_buy_limit": "100", + "examine": "An easy-to-make, 'myre'-coloured, Mort Myre snail shell; looks protective.", + "grand_exchange_price": "145", + "durability": null, + "name": "Blamish myre shell", + "tradeable": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "3355" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "145", + "durability": null, + "name": "Blamish myre shell", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3356" + }, + { + "ge_buy_limit": "100", + "examine": "An easy-to-make, red, Mort myre snail shell; looks protective.", + "grand_exchange_price": "614", + "durability": null, + "name": "Blamish red shell", + "tradeable": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "3357" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "614", + "durability": null, + "name": "Blamish red shell", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3358" + }, + { + "ge_buy_limit": "100", + "examine": "An easy-to-make, muddy-yellow, Mort Myre snail shell; looks protective.", + "grand_exchange_price": "173", + "durability": null, + "name": "Blamish ochre shell", + "tradeable": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "3359" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "173", + "durability": null, + "name": "Blamish ochre shell", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3360" + }, + { + "ge_buy_limit": "100", + "examine": "An easy-to-make, blue, Mort Myre snail shell; looks protective.", + "grand_exchange_price": "874", + "durability": null, + "name": "Blamish blue shell", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3361" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "874", + "durability": null, + "name": "Blamish blue shell", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3362" + }, + { + "shop_price": "74", + "ge_buy_limit": "10000", + "examine": "The thin, slimy corpse of a deceased giant snail.", + "grand_exchange_price": "2047", + "durability": null, + "name": "Thin snail", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "3363" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "2047", + "durability": null, + "name": "Thin snail", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3364" + }, + { + "ge_buy_limit": "1000", + "examine": "The lean, slimy corspe of a dead snail.", + "grand_exchange_price": "958", + "durability": null, + "name": "Lean snail", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "3365" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "958", + "durability": null, + "name": "Lean snail", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3366" + }, + { + "shop_price": "160", + "ge_buy_limit": "10000", + "examine": "The fat, slimy, corpse of a deceased giant snail.", + "grand_exchange_price": "971", + "durability": null, + "name": "Fat snail", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3367" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "971", + "durability": null, + "name": "Fat snail", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3368" + }, + { + "ge_buy_limit": "10000", + "examine": "A succulently slimy piece of sumptuous snail.", + "grand_exchange_price": "833", + "durability": null, + "name": "Thin snail meat", + "tradeable": "true", + "weight": "3", + "archery_ticket_price": "0", + "id": "3369" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "833", + "durability": null, + "name": "Thin snail meat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3370" + }, + { + "ge_buy_limit": "10000", + "examine": "A succulently slimey slice of sumptuous snail.", + "grand_exchange_price": "251", + "durability": null, + "name": "Lean snail meat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3371" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "251", + "durability": null, + "name": "Lean snail meat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3372" + }, + { + "ge_buy_limit": "10000", + "examine": "A succulently slimy slice of sumptuous snail.", + "grand_exchange_price": "603", + "durability": null, + "name": "Fat snail meat", + "tradeable": "true", + "weight": "4.5", + "archery_ticket_price": "0", + "id": "3373" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "603", + "durability": null, + "name": "Fat snail meat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3374" + }, + { + "durability": null, + "name": "Burnt snail", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3376" + }, + { + "shop_price": "5", + "ge_buy_limit": "100", + "examine": "An empty sample bottle.", + "grand_exchange_price": "14", + "durability": null, + "name": "Sample bottle", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3377" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "14", + "durability": null, + "name": "Sample bottle", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3378" + }, + { + "ge_buy_limit": "1000", + "examine": "A slime covered eel - yuck!", + "grand_exchange_price": "358", + "durability": null, + "name": "Slimy eel", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "3379" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "358", + "durability": null, + "name": "Slimy eel", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3380" + }, + { + "ge_buy_limit": "1000", + "examine": "A cooked slimy eel - not delicious, but pretty nutritious.", + "grand_exchange_price": "274", + "durability": null, + "name": "Cooked slimy eel", + "tradeable": "true", + "destroy": "false", + "weight": "2", + "archery_ticket_price": "0", + "id": "3381" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "274", + "durability": null, + "name": "Cooked slimy eel", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3382" + }, + { + "requirements": "{1,40}-{6,40}", + "ge_buy_limit": "100", + "examine": "A wooden helmet.", + "durability": null, + "weight": "0.9", + "absorb": "3,1,0", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "5993", + "name": "Splitbark helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3385", + "bonuses": "0,0,0,3,-2,10,9,11,3,0,7,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "5993", + "durability": null, + "name": "Splitbark helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3386" + }, + { + "requirements": "{1,40}-{6,40}", + "ge_buy_limit": "100", + "examine": "Provides good protection.", + "durability": null, + "weight": "4.5", + "absorb": "6,3,0", + "equipment_slot": "4", + "lendable": "true", + "remove_sleeves": "true", + "grand_exchange_price": "26700", + "name": "Splitbark body", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3387", + "bonuses": "0,0,0,10,-10,36,26,42,15,0,40,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "26700", + "durability": null, + "name": "Splitbark body", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3388" + }, + { + "requirements": "{1,40}-{6,40}", + "ge_buy_limit": "100", + "examine": "These should protect my legs.", + "durability": null, + "weight": "3.6", + "absorb": "4,2,0", + "equipment_slot": "7", + "lendable": "true", + "grand_exchange_price": "43700", + "name": "Splitbark legs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3389", + "bonuses": "0,0,0,7,-7,22,20,25,10,0,15,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "43700", + "durability": null, + "name": "Splitbark legs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3390" + }, + { + "requirements": "{1,40}-{6,40}", + "ge_buy_limit": "100", + "examine": "These should keep my hands safe.", + "durability": null, + "weight": "0.9", + "equipment_slot": "9", + "lendable": "true", + "grand_exchange_price": "2786", + "name": "Splitbark gauntlets", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3391", + "bonuses": "0,0,0,2,-1,3,2,4,2,0,3,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2786", + "durability": null, + "name": "Splitbark gauntlets", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3392" + }, + { + "requirements": "{1,40}-{6,40}", + "ge_buy_limit": "100", + "examine": "Wooden foot protection.", + "durability": null, + "weight": "0.9", + "equip_audio": "2237", + "equipment_slot": "10", + "lendable": "true", + "grand_exchange_price": "3808", + "name": "Splitbark boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3393", + "bonuses": "0,0,0,2,-1,3,2,4,2,0,9,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3808", + "durability": null, + "name": "Splitbark boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3394" + }, + { + "ge_buy_limit": "1000", + "examine": "The remains of a deadly shade.", + "grand_exchange_price": "18", + "durability": null, + "name": "Loar remains", + "tradeable": "true", + "weight": "1.35", + "archery_ticket_price": "0", + "id": "3396" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "18", + "durability": null, + "name": "Loar remains", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3397" + }, + { + "ge_buy_limit": "1000", + "examine": "The remains of a deadly shade.", + "grand_exchange_price": "249", + "durability": null, + "name": "Phrin remains", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3398" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "249", + "durability": null, + "name": "Phrin remains", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3399" + }, + { + "ge_buy_limit": "1000", + "examine": "The remains of a deadly shade.", + "grand_exchange_price": "138", + "durability": null, + "name": "Riyl remains", + "tradeable": "true", + "weight": "1.3", + "archery_ticket_price": "0", + "id": "3400" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "138", + "durability": null, + "name": "Riyl remains", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3401" + }, + { + "ge_buy_limit": "1000", + "examine": "The remains of a deadly shade.", + "grand_exchange_price": "334", + "durability": null, + "name": "Asyn remains", + "tradeable": "true", + "weight": "1.3", + "archery_ticket_price": "0", + "id": "3402" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "334", + "durability": null, + "name": "Asyn remains", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3403" + }, + { + "ge_buy_limit": "1000", + "examine": "The remains of a deadly shade.", + "grand_exchange_price": "5264", + "durability": null, + "name": "Fiyr remains", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3404" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "5264", + "durability": null, + "name": "Fiyr remains", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3405" + }, + { + "ge_buy_limit": "100", + "examine": "I need another ingredient to finish this potion.", + "grand_exchange_price": "137", + "durability": null, + "name": "Ash potion(unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3406" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "137", + "durability": null, + "name": "Ash potion(unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3407" + }, + { + "examine": "4 doses serum 207 as described in Herbi Flax's diary.", + "durability": null, + "name": "Serum 207 (4)", + "archery_ticket_price": "0", + "id": "3408" + }, + { + "examine": "3 doses serum 207 as described in Herbi Flax's diary.", + "durability": null, + "name": "Serum 207 (3)", + "archery_ticket_price": "0", + "id": "3410" + }, + { + "examine": "2 doses serum 207 as described in Herbi Flax's diary.", + "durability": null, + "name": "Serum 207 (2)", + "archery_ticket_price": "0", + "id": "3412" + }, + { + "examine": "1 dose serum 207 as described in Herbi Flax's diary.", + "durability": null, + "name": "Serum 207 (1)", + "archery_ticket_price": "0", + "id": "3414" + }, + { + "shop_price": "208", + "examine": "3 doses permanent serum 208 as described in Herbi Flax's diary.", + "durability": null, + "name": "Serum 208 (4)", + "archery_ticket_price": "0", + "id": "3416" + }, + { + "shop_price": "208", + "examine": "3 doses permanent serum 208 as described in Herbi Flax's diary.", + "durability": null, + "name": "Serum 208 (3)", + "archery_ticket_price": "0", + "id": "3417" + }, + { + "shop_price": "208", + "examine": "2 doses permanent serum 208 as described in Herbi Flax's diary.", + "durability": null, + "name": "Serum 208 (2)", + "archery_ticket_price": "0", + "id": "3418" + }, + { + "shop_price": "208", + "examine": "1 dose permanent serum 208 as described in Herbi Flax's diary.", + "durability": null, + "name": "Serum 208 (1)", + "archery_ticket_price": "0", + "id": "3419" + }, + { + "shop_price": "21", + "ge_buy_limit": "10000", + "examine": "A well carved limestone brick.", + "grand_exchange_price": "178", + "durability": null, + "name": "Limestone brick", + "tradeable": "true", + "weight": "1.3", + "archery_ticket_price": "0", + "id": "3420" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "178", + "durability": null, + "name": "Limestone brick", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3421" + }, + { + "shop_price": "26", + "ge_buy_limit": "1000", + "examine": "4 doses of olive oil.", + "grand_exchange_price": "678", + "durability": null, + "name": "Olive oil(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3422" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "678", + "durability": null, + "name": "Olive oil(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3423" + }, + { + "shop_price": "26", + "ge_buy_limit": "1000", + "examine": "3 doses of olive oil.", + "grand_exchange_price": "413", + "durability": null, + "name": "Olive oil(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3424" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "413", + "durability": null, + "name": "Olive oil(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3425" + }, + { + "shop_price": "26", + "ge_buy_limit": "1000", + "examine": "2 doses of olive oil.", + "grand_exchange_price": "173", + "durability": null, + "name": "Olive oil(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3426" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "173", + "durability": null, + "name": "Olive oil(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3427" + }, + { + "shop_price": "26", + "ge_buy_limit": "1000", + "examine": "1 dose of olive oil.", + "grand_exchange_price": "110", + "durability": null, + "name": "Olive oil(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3428" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "110", + "durability": null, + "name": "Olive oil(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3429" + }, + { + "ge_buy_limit": "1000", + "examine": "Sacred oil.", + "grand_exchange_price": "3587", + "durability": null, + "name": "Sacred oil(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3430" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "3587", + "durability": null, + "name": "Sacred oil(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3431" + }, + { + "ge_buy_limit": "1000", + "examine": "Sacred oil.", + "grand_exchange_price": "2596", + "durability": null, + "name": "Sacred oil(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3432" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "2596", + "durability": null, + "name": "Sacred oil(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3433" + }, + { + "ge_buy_limit": "1000", + "examine": "Sacred oil.", + "grand_exchange_price": "1713", + "durability": null, + "name": "Sacred oil(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3434" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1713", + "durability": null, + "name": "Sacred oil(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3435" + }, + { + "ge_buy_limit": "1000", + "examine": "Sacred oil.", + "grand_exchange_price": "1846", + "durability": null, + "name": "Sacred oil(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3436" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1846", + "durability": null, + "name": "Sacred oil(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3437" + }, + { + "ge_buy_limit": "25000", + "examine": "Funeral logs used for burning loars.", + "grand_exchange_price": "853", + "durability": null, + "name": "Pyre logs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3438" + }, + { + "ge_buy_limit": "25000", + "grand_exchange_price": "853", + "durability": null, + "name": "Pyre logs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3439" + }, + { + "ge_buy_limit": "1000", + "examine": "Oak logs prepared with sacred oil for a funeral pyre.", + "grand_exchange_price": "1122", + "durability": null, + "name": "Oak pyre logs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3440" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1122", + "durability": null, + "name": "Oak pyre logs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3441" + }, + { + "ge_buy_limit": "1000", + "examine": "Willow logs prepared with sacred oil for a funeral pyre.", + "grand_exchange_price": "1164", + "durability": null, + "name": "Willow pyre logs", + "tradeable": "true", + "weight": "1.3", + "archery_ticket_price": "0", + "id": "3442" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1164", + "durability": null, + "name": "Willow pyre logs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3443" + }, + { + "ge_buy_limit": "1000", + "examine": "Maple logs prepared with sacred oil for a funeral pyre.", + "grand_exchange_price": "3313", + "durability": null, + "name": "Maple pyre logs", + "tradeable": "true", + "weight": "1.3", + "archery_ticket_price": "0", + "id": "3444" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "3313", + "durability": null, + "name": "Maple pyre logs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3445" + }, + { + "ge_buy_limit": "1000", + "examine": "Yew logs prepared with sacred oil for a funeral pyre.", + "grand_exchange_price": "4424", + "durability": null, + "name": "Yew pyre logs", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "3446" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "4424", + "durability": null, + "name": "Yew pyre logs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3447" + }, + { + "ge_buy_limit": "1000", + "examine": "Magic logs prepared with sacred oil for a funeral pyre.", + "grand_exchange_price": "5611", + "durability": null, + "name": "Magic pyre logs", + "tradeable": "true", + "weight": "1.3", + "archery_ticket_price": "0", + "id": "3448" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "5611", + "durability": null, + "name": "Magic pyre logs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3449" + }, + { + "examine": "A bronze key with a blood-red painted eyelet. (Shades of Mort'ton)", + "durability": null, + "name": "Bronze key red", + "archery_ticket_price": "0", + "id": "3450" + }, + { + "examine": "A bronze key with a brown painted eyelet. (Shades of Mort'ton)", + "durability": null, + "name": "Bronze key brown", + "archery_ticket_price": "0", + "id": "3451" + }, + { + "examine": "A bronze key with a crimson painted eyelet. (Shades of Mort'ton)", + "durability": null, + "name": "Bronze key crimson", + "archery_ticket_price": "0", + "id": "3452" + }, + { + "examine": "A bronze key with a black painted eyelet. (Shades of Mort'ton)", + "durability": null, + "name": "Bronze key black", + "archery_ticket_price": "0", + "id": "3453" + }, + { + "examine": "A bronze key with a purple painted eyelet. (Shades of Mort'ton)", + "durability": null, + "name": "Bronze key purple", + "archery_ticket_price": "0", + "id": "3454" + }, + { + "examine": "A steel key with a blood-red painted eyelet. (Shades of Mort'ton)", + "durability": null, + "name": "Steel key red", + "archery_ticket_price": "0", + "id": "3455" + }, + { + "examine": "A steel key with a brown painted eyelet. (Shades of Mort'ton)", + "durability": null, + "name": "Steel key brown", + "archery_ticket_price": "0", + "id": "3456" + }, + { + "examine": "A steel key with a crimson painted eyelet. (Shades of Mort'ton)", + "durability": null, + "name": "Steel key crimson", + "archery_ticket_price": "0", + "id": "3457" + }, + { + "examine": "A steel key with a black painted eyelet. (Shades of Mort'ton)", + "durability": null, + "name": "Steel key black", + "archery_ticket_price": "0", + "id": "3458" + }, + { + "examine": "A steel key with a purple painted eyelet. (Shades of Mort'ton)", + "durability": null, + "name": "Steel key purple", + "archery_ticket_price": "0", + "id": "3459" + }, + { + "examine": "A black key with a blood-red painted eyelet. (Shades of Mort'ton)", + "durability": null, + "name": "Black key red", + "archery_ticket_price": "0", + "id": "3460" + }, + { + "examine": "A black key with a brown painted eyelet. (Shades of Mort'ton)", + "durability": null, + "name": "Black key brown", + "archery_ticket_price": "0", + "id": "3461" + }, + { + "examine": "A black key with a crimson painted eyelet. (Shades of Mort'ton)", + "durability": null, + "name": "Black key crimson", + "archery_ticket_price": "0", + "id": "3462" + }, + { + "examine": "A black key with a black painted eyelet. (Shades of Mort'ton)", + "durability": null, + "name": "Black key black", + "archery_ticket_price": "0", + "id": "3463" + }, + { + "examine": "A black key with a purple painted eyelet. (Shades of Mort'ton)", + "durability": null, + "name": "Black key purple", + "archery_ticket_price": "0", + "id": "3464" + }, + { + "examine": "A silver key with a blood-red painted eyelet. (Shades of Mort'ton)", + "durability": null, + "name": "Silver key red", + "archery_ticket_price": "0", + "id": "3465" + }, + { + "examine": "A silver key with a brown painted eyelet. (Shades of Mort'ton)", + "durability": null, + "name": "Silver key brown", + "archery_ticket_price": "0", + "id": "3466" + }, + { + "examine": "A silver key with a crimson painted eyelet. (Shades of Mort'ton)", + "durability": null, + "name": "Silver key crimson", + "archery_ticket_price": "0", + "id": "3467" + }, + { + "examine": "A silver key with a black painted eyelet. (Shades of Mort'ton)", + "durability": null, + "name": "Silver key black", + "archery_ticket_price": "0", + "id": "3468" + }, + { + "examine": "A silver key with a purple painted eyelet. (Shades of Mort'ton)", + "durability": null, + "name": "Silver key purple", + "archery_ticket_price": "0", + "id": "3469" + }, + { + "ge_buy_limit": "1000", + "examine": "Amazingly untouched by time.", + "grand_exchange_price": "956", + "durability": null, + "name": "Fine cloth", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "3470" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "956", + "durability": null, + "name": "Fine cloth", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3471" + }, + { + "requirements": "{1,10}", + "ge_buy_limit": "2", + "examine": "Black plateskirt with trim.", + "grand_exchange_price": "3077", + "durability": null, + "name": "Black plateskirt (t)", + "tradeable": "true", + "weight": "8", + "archery_ticket_price": "0", + "id": "3472", + "bonuses": "0,0,0,-21,-7,21,20,19,-4,20,3,0,0,0,0", + "equipment_slot": "7" + }, + { + "requirements": "{1,10}", + "ge_buy_limit": "2", + "examine": "Black plateskirt with gold trim.", + "grand_exchange_price": "10600", + "durability": null, + "name": "Black plateskirt (g)", + "tradeable": "true", + "weight": "9", + "archery_ticket_price": "0", + "id": "3473", + "bonuses": "0,0,0,-21,-7,21,20,19,-4,20,3,0,0,0,0", + "equipment_slot": "7" + }, + { + "requirements": "{1,30}", + "ge_buy_limit": "2", + "examine": "Adamant plateskirt with trim.", + "durability": null, + "weight": "9", + "absorb": "1,0,3", + "equipment_slot": "7", + "grand_exchange_price": "4403", + "name": "Adam plateskirt (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3474", + "bonuses": "0,0,0,-21,-7,33,31,29,-4,31,10,0,0,0,0" + }, + { + "requirements": "{1,30}", + "ge_buy_limit": "2", + "examine": "Adamant plateskirt with gold trim.", + "durability": null, + "weight": "9", + "absorb": "1,0,3", + "equipment_slot": "7", + "grand_exchange_price": "11000", + "name": "Adam plateskirt (g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3475", + "bonuses": "0,0,0,-21,-7,33,31,29,-4,31,10,0,0,0,0" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "Rune plateskirt with gold trim.", + "durability": null, + "weight": "9", + "absorb": "2,0,4", + "equipment_slot": "7", + "lendable": "true", + "grand_exchange_price": "42500", + "name": "Rune plateskirt (g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3476", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" + }, + { + "requirements": "{1,40}", + "shop_price": "81280", + "ge_buy_limit": "2", + "examine": "Rune plateskirt with trim.", + "durability": null, + "weight": "8", + "absorb": "2,0,4", + "equipment_slot": "7", + "lendable": "true", + "grand_exchange_price": "38300", + "name": "Rune plateskirt (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3477", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "Rune plateskirt in the colours of Zamorak.", + "durability": null, + "weight": "9", + "absorb": "2,0,4", + "equipment_slot": "7", + "lendable": "true", + "grand_exchange_price": "42000", + "name": "Zamorak plateskirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3478", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "Rune plateskirt in the colours of Saradomin.", + "durability": null, + "weight": "9", + "absorb": "2,0,4", + "equipment_slot": "7", + "lendable": "true", + "grand_exchange_price": "44000", + "name": "Saradomin plateskirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3479", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "Rune plateskirt in the colours of Guthix.", + "durability": null, + "weight": "9", + "absorb": "2,0,4", + "equipment_slot": "7", + "lendable": "true", + "grand_exchange_price": "39100", + "name": "Guthix plateskirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3480", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "Rune platebody with complete gold trim & plating.", + "durability": null, + "weight": "10", + "absorb": "3,0,6", + "equip_audio": "2239", + "equipment_slot": "4", + "lendable": "true", + "remove_sleeves": "true", + "grand_exchange_price": "2500000", + "name": "Gilded platebody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3481", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "2500000", + "durability": null, + "name": "Gilded platebody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3482" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "Rune platelegs with gold plate.", + "durability": null, + "weight": "9", + "absorb": "2,0,4", + "equip_audio": "2242", + "equipment_slot": "7", + "lendable": "true", + "grand_exchange_price": "2200000", + "name": "Gilded platelegs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3483", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "2200000", + "durability": null, + "name": "Gilded platelegs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3484" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "Rune plateskirt with gold plate.", + "durability": null, + "weight": "9", + "absorb": "2,0,4", + "equipment_slot": "7", + "lendable": "true", + "grand_exchange_price": "162300", + "name": "Gilded plateskirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3485", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "Rune full helmet with gold plate.", + "durability": null, + "weight": "2", + "absorb": "1,0,3", + "equip_audio": "2240", + "remove_beard": "true", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "477200", + "name": "Gilded full helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3486", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "477200", + "durability": null, + "name": "Gilded full helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3487" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "Rune kiteshield with gold plate.", + "durability": null, + "weight": "5", + "absorb": "3,0,7", + "equip_audio": "2245", + "equipment_slot": "5", + "lendable": "true", + "grand_exchange_price": "515400", + "name": "Gilded kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3488", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "515400", + "durability": null, + "name": "Gilded kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3489" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3490" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3491" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3492" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3493" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3494" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3495" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3496" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3497" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3498" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3499" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3500" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3501" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3502" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3503" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3504" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3505" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3506" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3507" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3508" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3509" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3510" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "3511" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3512" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3513" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3514" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3515" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3516" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "3517" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3518" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "3519" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3520" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "3521" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3522" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "3523" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3524" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3525" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3526" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "3527" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3528" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "3529" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3530" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "3531" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3532" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "3533" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3534" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "3535" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3536" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "3537" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3538" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "3539" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3540" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "3541" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3542" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "3543" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3544" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "3545" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3546" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "3547" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3548" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "3549" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3550" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "3551" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3552" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "3553" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3554" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "3555" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3556" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "3557" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3558" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "3559" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3560" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "3561" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3562" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "3563" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3564" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "shop_price": "5", + "examine": "I need to solve this.", + "durability": null, + "name": "Puzzle box", + "archery_ticket_price": "0", + "id": "3565" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3566" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "shop_price": "5", + "examine": "I need to solve this.", + "durability": null, + "name": "Puzzle box", + "archery_ticket_price": "0", + "id": "3567" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3568" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "shop_price": "5", + "examine": "I need to solve this.", + "durability": null, + "name": "Puzzle box", + "archery_ticket_price": "0", + "id": "3569" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3570" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "shop_price": "5", + "examine": "I need to solve this.", + "durability": null, + "name": "Puzzle box", + "archery_ticket_price": "0", + "id": "3571" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3572" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3573" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3574" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3575" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "shop_price": "5", + "examine": "I need to solve this.", + "durability": null, + "name": "Puzzle box", + "archery_ticket_price": "0", + "id": "3576" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3577" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "shop_price": "5", + "examine": "I need to solve this.", + "durability": null, + "name": "Puzzle box", + "archery_ticket_price": "0", + "id": "3578" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3579" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3580" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "3581" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3582" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "3583" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3584" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "3585" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3586" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "3587" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3588" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "3589" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3590" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "3591" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3592" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "3593" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3594" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "3595" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3596" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "3597" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3598" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3599" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "3600" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3601" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3602" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "3603" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3604" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3605" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3607" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3609" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3610" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3611" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3612" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3613" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3614" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3615" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3616" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3617" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "3618" + }, + { + "durability": null, + "name": "Black plateskirt (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3668" + }, + { + "durability": null, + "name": "Black plateskirt (g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3669" + }, + { + "durability": null, + "name": "Adam plateskirt (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3670" + }, + { + "durability": null, + "name": "Adam plateskirt (g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3671" + }, + { + "durability": null, + "name": "Rune plateskirt (g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3672" + }, + { + "durability": null, + "name": "Rune plateskirt (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3673" + }, + { + "durability": null, + "name": "Zamorak plateskirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3674" + }, + { + "durability": null, + "name": "Saradomin plateskirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3675" + }, + { + "durability": null, + "name": "Guthix plateskirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3676" + }, + { + "durability": null, + "name": "Gilded plateskirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3677" + }, + { + "shop_price": "13000", + "examine": "An exquisitely shaped tool specially designed for fixing temples.", + "durability": null, + "name": "Flamtaer hammer", + "weight": "1.3", + "archery_ticket_price": "0", + "id": "3678" + }, + { + "examine": "A sealed letter of recommendation.", + "durability": null, + "name": "Picture", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "3685" + }, + { + "examine": "It's almost a musical instrument.", + "durability": null, + "name": "Unstrung lyre", + "weight": "1", + "archery_ticket_price": "0", + "id": "3688", + "equipment_slot": "3" + }, + { + "examine": "A musical intrument that I can magically play.", + "durability": null, + "name": "Lyre", + "weight": "1.8", + "archery_ticket_price": "0", + "id": "3689", + "equipment_slot": "3" + }, + { + "examine": "This will teleport me to Rellekka when I play it.", + "durability": null, + "name": "Enchanted lyre", + "weight": "1.8", + "archery_ticket_price": "0", + "id": "3690", + "equipment_slot": "3" + }, + { + "examine": "This will teleport me to Rellekka when I play it.", + "durability": null, + "name": "Enchanted lyre(1)", + "weight": "1.8", + "archery_ticket_price": "0", + "id": "3691", + "equipment_slot": "3" + }, + { + "examine": "I can use this to make a lyre.", + "durability": null, + "name": "Branch", + "weight": "1", + "archery_ticket_price": "0", + "id": "3692" + }, + { + "shop_price": "1000", + "examine": "I can spin this into golden wool.", + "durability": null, + "name": "Golden fleece", + "weight": "1", + "archery_ticket_price": "0", + "id": "3693" + }, + { + "examine": "I can use this to make a lyre.", + "durability": null, + "name": "Golden wool", + "weight": "1", + "archery_ticket_price": "0", + "id": "3694" + }, + { + "turn90cw_anim": "6662", + "examine": "The lowest maintenance pet you will ever have.", + "walk_anim": "6658", + "durability": null, + "weight": "1", + "turn90ccw_anim": "6663", + "two_handed": "true", + "turn180_anim": "6659", + "render_anim": "792", + "equipment_slot": "3", + "stand_anim": "6657", + "name": "Pet rock", + "run_anim": "6660", + "archery_ticket_price": "0", + "id": "3695", + "stand_turn_anim": "6661" + }, + { + "examine": "Talisman to bind the Draugen.", + "durability": null, + "name": "Hunters' talisman", + "archery_ticket_price": "0", + "id": "3696" + }, + { + "examine": "Talisman to bind the Draugen.", + "durability": null, + "name": "Hunters' talisman", + "archery_ticket_price": "0", + "id": "3697" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Some flowers from a distant land.", + "durability": null, + "name": "Exotic flower", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "3698" + }, + { + "examine": "A hauntingly beautiful love ballad.", + "durability": null, + "name": "Fremennik ballad", + "archery_ticket_price": "0", + "id": "3699" + }, + { + "examine": "A pair of sturdy made custom boots.", + "durability": null, + "name": "Sturdy boots", + "archery_ticket_price": "0", + "id": "3700" + }, + { + "examine": "Could probably be a bit clearer?", + "durability": null, + "name": "Tracking map", + "archery_ticket_price": "0", + "id": "3701" + }, + { + "examine": "A finely crafted string for a custom bow", + "durability": null, + "name": "Custom bow string", + "archery_ticket_price": "0", + "id": "3702" + }, + { + "examine": "An extremely odd, non-edible fish.", + "durability": null, + "name": "Unusual fish", + "archery_ticket_price": "0", + "id": "3703" + }, + { + "examine": "Map showing the best fishing spots out at sea.", + "durability": null, + "name": "Sea fishing map", + "archery_ticket_price": "0", + "id": "3704" + }, + { + "examine": "An estimate of expected local weather conditions.", + "durability": null, + "name": "Weather forecast", + "archery_ticket_price": "0", + "id": "3705" + }, + { + "examine": "Shows the wearer is worthy of the Champions table.", + "durability": null, + "name": "Champions token", + "archery_ticket_price": "0", + "id": "3706" + }, + { + "examine": "Probably the greatest cocktail in the world.", + "durability": null, + "name": "Legendary cocktail", + "archery_ticket_price": "0", + "id": "3707" + }, + { + "examine": "A signed statement promising a reduction on sales tax.", + "durability": null, + "name": "Fiscal statement", + "archery_ticket_price": "0", + "id": "3708" + }, + { + "shop_price": "5000", + "examine": "A legally binding contract promising not to enter the longhall.", + "durability": null, + "name": "Promissory note", + "archery_ticket_price": "0", + "id": "3709" + }, + { + "examine": "This employment contract is for a warrior to act as a bodyguard.", + "durability": null, + "name": "Warriors' contract", + "archery_ticket_price": "0", + "id": "3710" + }, + { + "shop_price": "325", + "examine": "A lot of beer in a barrel.", + "grand_exchange_price": "1555", + "durability": null, + "name": "Keg of beer", + "tradeable": "true", + "weight": "20", + "archery_ticket_price": "0", + "id": "3711" + }, + { + "examine": "Suspiciously close to beer, but without the side effects.", + "durability": null, + "name": "Low alcohol keg", + "weight": "20", + "archery_ticket_price": "0", + "id": "3712" + }, + { + "examine": "It's some kind of weird little parcel thing.", + "durability": null, + "name": "Strange object", + "archery_ticket_price": "0", + "id": "3713" + }, + { + "examine": "It's some kind of weird little parcel thing.", + "durability": null, + "name": "Lit strange object", + "archery_ticket_price": "0", + "id": "3714" + }, + { + "examine": "A red coloured disk, apparently made out of wood.", + "durability": null, + "name": "Picture", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "3715" + }, + { + "examine": "A red coloured disk, apparently made out of wood.", + "durability": null, + "name": "Picture", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "3716" + }, + { + "examine": "A very attractive magnet.", + "durability": null, + "name": "Magnet", + "archery_ticket_price": "0", + "id": "3718" + }, + { + "examine": "Some blue thread.", + "durability": null, + "name": "Thread", + "archery_ticket_price": "0", + "id": "3719" + }, + { + "examine": "A small pick for cracking small objects.", + "durability": null, + "name": "Pick", + "archery_ticket_price": "0", + "id": "3720" + }, + { + "examine": "Might be fun to play with in the bath.", + "durability": null, + "name": "Ship toy", + "archery_ticket_price": "0", + "id": "3721" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "It's a bucket of salty water.", + "durability": null, + "name": "Full bucket", + "archery_ticket_price": "0", + "id": "3722" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "This bucket is eighty percent full. It has a 5 painted on its side.", + "durability": null, + "name": "4/5ths full bucket", + "archery_ticket_price": "0", + "id": "3723" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "This bucket is sixty percent full. It has a 5 painted on its side.", + "durability": null, + "name": "3/5ths full bucket", + "archery_ticket_price": "0", + "id": "3724" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "This bucket is forty percent full. It has a 5 painted on its side.", + "durability": null, + "name": "2/5ths full bucket", + "archery_ticket_price": "0", + "id": "3725" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "This bucket is twenty percent full. It has a 5 painted on its side.", + "durability": null, + "name": "1/5ths full bucket", + "archery_ticket_price": "0", + "id": "3726" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "shop_price": "2", + "examine": "It's an empty bucket.", + "grand_exchange_price": "50", + "durability": null, + "name": "Empty bucket", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "3727" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "This bucket of water is frozen solid.", + "durability": null, + "name": "Frozen bucket", + "archery_ticket_price": "0", + "id": "3728" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "This jug is completely full. It has a 3 painted on its side.", + "durability": null, + "name": "Full jug", + "archery_ticket_price": "0", + "id": "3729" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "This jug is two thirds full. It has a 3 painted on its side.", + "durability": null, + "name": "2/3rds full jug", + "archery_ticket_price": "0", + "id": "3730" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "This jug is one third full. It has a 3 painted on its side.", + "durability": null, + "name": "1/3rds full jug", + "archery_ticket_price": "0", + "id": "3731" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "shop_price": "1", + "examine": "This jug is empty.", + "grand_exchange_price": "164", + "durability": null, + "name": "Empty jug", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "3732" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "This jug of water is frozen solid.", + "durability": null, + "name": "Frozen jug", + "archery_ticket_price": "0", + "id": "3733" + }, + { + "examine": "An unusually shaped vase. You can see something glinting inside.", + "durability": null, + "name": "Vase", + "archery_ticket_price": "0", + "id": "3734" + }, + { + "examine": "An unusually shaped vase full of water. You can see something glinting inside.", + "durability": null, + "name": "Vase of water", + "archery_ticket_price": "0", + "id": "3735" + }, + { + "examine": "An unusually shaped vase full of ice. You can see something glinting inside.", + "durability": null, + "name": "Frozen vase", + "archery_ticket_price": "0", + "id": "3736" + }, + { + "examine": "This looks like a lid to some kind of container.", + "durability": null, + "name": "Vase lid", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "3737" + }, + { + "examine": "The lid is screwed on tightly. ", + "durability": null, + "name": "Sealed vase", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "3738" + }, + { + "examine": "The lid is screwed on tightly. It is full of water.", + "durability": null, + "name": "Sealed vase", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "3739" + }, + { + "examine": "The lid is screwed on tightly. It is very cold. ", + "durability": null, + "name": "Sealed vase", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "3740" + }, + { + "examine": "A small, cold key.", + "durability": null, + "name": "Frozen key", + "archery_ticket_price": "0", + "id": "3741" + }, + { + "examine": "The colouring on it seems to be some kind of sticky goop.", + "durability": null, + "name": "Red herring", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "3742" + }, + { + "examine": "A red coloured disk, apparently made out of wood.", + "durability": null, + "name": "Red disk", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "3743" + }, + { + "examine": "A simple looking disk made of wood.", + "durability": null, + "name": "Wooden disk", + "archery_ticket_price": "0", + "id": "3744" + }, + { + "shop_price": "27", + "examine": "The key to leave the Seer's house.", + "durability": null, + "name": "Seer's key", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "3745" + }, + { + "examine": "Yup, it's sticky, it's red and it's goop.", + "durability": null, + "name": "Sticky red goop", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "3746" + }, + { + "durability": null, + "name": "Sticky red goop", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3747", + "alchemizable": "true" + }, + { + "remove_head": "true", + "examine": "A sturdy helm worn only by Fremennik clan members.", + "durability": null, + "name": "Fremennik helm", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "3748", + "absorb": "1,0,2", + "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,6,0,0,0,0", + "alchemizable": "true", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "requirements": "{1,45}", + "shop_price": "78000", + "ge_buy_limit": "100", + "examine": "This helmet is worn by archers.", + "durability": null, + "weight": "2", + "absorb": "0,3,1", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "48900", + "name": "Archer helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3749", + "bonuses": "-5,-5,-5,-5,6,6,8,10,6,6,0,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "48900", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Archer helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3750" + }, + { + "remove_head": "true", + "requirements": "{1,45}", + "shop_price": "78000", + "ge_buy_limit": "100", + "examine": "This helmet is worn by berserkers.", + "durability": null, + "weight": "2.7", + "absorb": "1,0,3", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "60900", + "name": "Berserker helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3751", + "bonuses": "0,0,0,-5,-5,31,29,33,0,30,7,3,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "60900", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Berserker helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3752" + }, + { + "remove_head": "true", + "requirements": "{1,45}", + "shop_price": "78000", + "ge_buy_limit": "100", + "examine": "This helm is worn by warriors.", + "durability": null, + "weight": "2.7", + "absorb": "1,0,3", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "50700", + "name": "Warrior helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3753", + "bonuses": "0,5,0,-5,-5,31,33,29,0,30,7,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "50700", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Warrior helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3754" + }, + { + "remove_head": "true", + "requirements": "{1,45}", + "shop_price": "78000", + "ge_buy_limit": "100", + "examine": "This helm is worn by farseers.", + "durability": null, + "weight": "2.7", + "absorb": "3,1,0", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "47900", + "name": "Farseer helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3755", + "bonuses": "-5,-5,-5,6,-5,8,10,12,6,0,7,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "47900", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Farseer helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3756" + }, + { + "examine": "A sword used only by Fremennik warriors.", + "durability": null, + "weight": "1.8", + "attack_speed": "4", + "weapon_interface": "6", + "alchemizable": "true", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "name": "Fremennik blade", + "archery_ticket_price": "0", + "id": "3757", + "bonuses": "6,29,-2,0,0,0,1,0,0,0,0,28,0,0,0" + }, + { + "examine": "A shield worn by Fremennik warriors.", + "durability": null, + "name": "Fremennik shield", + "destroy": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "3758", + "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,30,0,0,0,0", + "alchemizable": "true", + "equipment_slot": "5" + }, + { + "shop_price": "325", + "ge_buy_limit": "1000", + "examine": "The latest fashion in Rellekka.", + "grand_exchange_price": "697", + "durability": null, + "name": "Fremennik cloak", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3759", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "697", + "durability": null, + "name": "Fremennik cloak", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3760" + }, + { + "shop_price": "325", + "ge_buy_limit": "1000", + "examine": "The latest fashion in Rellekka.", + "grand_exchange_price": "54", + "durability": null, + "name": "Fremennik cloak", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3761", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "54", + "durability": null, + "name": "Fremennik cloak", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3762" + }, + { + "shop_price": "325", + "ge_buy_limit": "1000", + "examine": "The latest fashion in Rellekka.", + "grand_exchange_price": "581", + "durability": null, + "name": "Fremennik cloak", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3763", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "581", + "durability": null, + "name": "Fremennik cloak", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3764" + }, + { + "shop_price": "325", + "ge_buy_limit": "1000", + "examine": "The latest fashion in Rellekka.", + "grand_exchange_price": "912", + "durability": null, + "name": "Fremennik cloak", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3765", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "912", + "durability": null, + "name": "Fremennik cloak", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3766" + }, + { + "remove_sleeves": "true", + "shop_price": "325", + "ge_buy_limit": "100", + "examine": "The latest in Fremennik fashion.", + "grand_exchange_price": "100", + "durability": null, + "name": "Fremennik shirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3767", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "100", + "durability": null, + "name": "Fremennik shirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3768" + }, + { + "remove_sleeves": "true", + "shop_price": "325", + "ge_buy_limit": "100", + "examine": "The latest in Fremennik fashion.", + "grand_exchange_price": "486", + "durability": null, + "name": "Fremennik shirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3769", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "486", + "durability": null, + "name": "Fremennik shirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3770" + }, + { + "remove_sleeves": "true", + "shop_price": "325", + "ge_buy_limit": "100", + "examine": "The latest in Fremennik fashion.", + "grand_exchange_price": "242", + "durability": null, + "name": "Fremennik shirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3771", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "242", + "durability": null, + "name": "Fremennik shirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3772" + }, + { + "remove_sleeves": "true", + "shop_price": "325", + "ge_buy_limit": "100", + "examine": "The latest in Fremennik fashion.", + "grand_exchange_price": "500", + "durability": null, + "name": "Fremennik shirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3773", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "500", + "durability": null, + "name": "Fremennik shirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3774" + }, + { + "remove_sleeves": "true", + "shop_price": "325", + "ge_buy_limit": "100", + "examine": "The latest in Fremennik fashion.", + "grand_exchange_price": "450", + "durability": null, + "name": "Fremennik shirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3775", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "450", + "durability": null, + "name": "Fremennik shirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3776" + }, + { + "shop_price": "325", + "ge_buy_limit": "1000", + "examine": "The latest fashion in Rellekka.", + "grand_exchange_price": "674", + "durability": null, + "name": "Fremennik cloak", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3777", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "674", + "durability": null, + "name": "Fremennik cloak", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3778" + }, + { + "shop_price": "325", + "ge_buy_limit": "1000", + "examine": "The latest fashion in Rellekka.", + "grand_exchange_price": "809", + "durability": null, + "name": "Fremennik cloak", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3779", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "809", + "durability": null, + "name": "Fremennik cloak", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3780" + }, + { + "shop_price": "325", + "ge_buy_limit": "1000", + "examine": "The latest fashion in Rellekka.", + "grand_exchange_price": "632", + "durability": null, + "name": "Fremennik cloak", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3781", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "632", + "durability": null, + "name": "Fremennik cloak", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3782" + }, + { + "shop_price": "325", + "ge_buy_limit": "1000", + "examine": "The latest fashion in Rellekka.", + "grand_exchange_price": "517", + "durability": null, + "name": "Fremennik cloak", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3783", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "517", + "durability": null, + "name": "Fremennik cloak", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3784" + }, + { + "shop_price": "325", + "ge_buy_limit": "1000", + "examine": "The latest fashion in Rellekka.", + "grand_exchange_price": "398", + "durability": null, + "name": "Fremennik cloak", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3785", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "398", + "durability": null, + "name": "Fremennik cloak", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3786" + }, + { + "shop_price": "325", + "ge_buy_limit": "1000", + "examine": "The latest fashion in Rellekka.", + "grand_exchange_price": "283", + "durability": null, + "name": "Fremennik cloak", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3787", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "283", + "durability": null, + "name": "Fremennik cloak", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3788" + }, + { + "shop_price": "325", + "ge_buy_limit": "1000", + "examine": "The latest fashion in Rellekka.", + "grand_exchange_price": "966", + "durability": null, + "name": "Fremennik cloak", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3789", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "966", + "durability": null, + "name": "Fremennik cloak", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3790" + }, + { + "shop_price": "650", + "ge_buy_limit": "100", + "examine": "Very stylish!", + "grand_exchange_price": "205", + "durability": null, + "name": "Fremennik boots", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "3791", + "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", + "equipment_slot": "10" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "205", + "durability": null, + "name": "Fremennik boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3792" + }, + { + "shop_price": "650", + "ge_buy_limit": "100", + "examine": "The latest fashion of Rellekka.", + "durability": null, + "weight": "0.9", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "1191", + "name": "Fremennik robe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3793", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1191", + "durability": null, + "name": "Fremennik robe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3794" + }, + { + "shop_price": "650", + "ge_buy_limit": "100", + "examine": "The latest fashion of Rellekka.", + "grand_exchange_price": "663", + "durability": null, + "name": "Fremennik skirt", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "3795", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "663", + "durability": null, + "name": "Fremennik skirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3796" + }, + { + "shop_price": "650", + "ge_buy_limit": "100", + "examine": "A silly pointed hat.", + "grand_exchange_price": "2380", + "durability": null, + "name": "Fremennik hat", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "3797", + "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2380", + "durability": null, + "name": "Fremennik hat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3798" + }, + { + "ge_buy_limit": "10", + "shop_price": "650", + "examine": "These will keep my hands warm!", + "grand_exchange_price": "172", + "durability": null, + "name": "Gloves", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "3799", + "bonuses": "0,0,0,0,0,0,1,2,0,0,1,0,0,0,0", + "equipment_slot": "9" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "172", + "durability": null, + "name": "Gloves", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3800" + }, + { + "shop_price": "325", + "ge_buy_limit": "100", + "examine": "A lot of beer in a barrel. Beer in a barrel - a specialty of the Fremennik Province.", + "grand_exchange_price": "1817", + "durability": null, + "name": "Keg of beer", + "tradeable": "true", + "weight": "20", + "archery_ticket_price": "0", + "id": "3801" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1817", + "durability": null, + "name": "Keg of beer", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3802" + }, + { + "ge_buy_limit": "100", + "examine": "A glass of frothy ale.", + "grand_exchange_price": "393", + "durability": null, + "name": "Beer", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "3803" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "393", + "durability": null, + "name": "Beer", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3804" + }, + { + "shop_price": "26", + "examine": "A big cup for a big thirst.", + "durability": null, + "name": "Tankard", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3805" + }, + { + "durability": null, + "name": "Tankard", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3806" + }, + { + "ge_buy_limit": "2", + "examine": "This seems to have been torn from a book...", + "grand_exchange_price": "1400000", + "durability": null, + "name": "Saradomin page 1", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3827" + }, + { + "ge_buy_limit": "2", + "examine": "This seems to have been torn from a book...", + "grand_exchange_price": "686000", + "durability": null, + "name": "Saradomin page 2", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3828" + }, + { + "ge_buy_limit": "2", + "examine": "This seems to have been torn from a book...", + "grand_exchange_price": "522800", + "durability": null, + "name": "Saradomin page 3", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3829" + }, + { + "ge_buy_limit": "2", + "examine": "This seems to have been torn from a book...", + "grand_exchange_price": "629500", + "durability": null, + "name": "Saradomin page 4", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3830" + }, + { + "ge_buy_limit": "2", + "examine": "This seems to have been torn from a book...", + "grand_exchange_price": "7100000", + "durability": null, + "name": "Zamorak page 1", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3831" + }, + { + "ge_buy_limit": "2", + "examine": "This seems to have been torn from a book...", + "grand_exchange_price": "5400000", + "durability": null, + "name": "Zamorak page 2", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3832" + }, + { + "ge_buy_limit": "2", + "examine": "This seems to have been torn from a book...", + "grand_exchange_price": "4700000", + "durability": null, + "name": "Zamorak page 3", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3833" + }, + { + "ge_buy_limit": "2", + "examine": "This seems to have been torn from a book...", + "grand_exchange_price": "5900000", + "durability": null, + "name": "Zamorak page 4", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3834" + }, + { + "ge_buy_limit": "2", + "examine": "This seems to have been torn from a book...", + "grand_exchange_price": "1200000", + "durability": null, + "name": "Guthix page 1", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3835" + }, + { + "ge_buy_limit": "2", + "examine": "This seems to have been torn from a book...", + "grand_exchange_price": "997100", + "durability": null, + "name": "Guthix page 2", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3836" + }, + { + "ge_buy_limit": "2", + "examine": "This seems to have been torn from a book...", + "grand_exchange_price": "953100", + "durability": null, + "name": "Guthix page 3", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3837" + }, + { + "ge_buy_limit": "2", + "examine": "This seems to have been torn from a book...", + "grand_exchange_price": "1000000", + "durability": null, + "name": "Guthix page 4", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3838" + }, + { + "shop_price": "5000", + "examine": "An incomplete book of Saradomin.", + "durability": null, + "name": "Damaged book", + "weight": "1", + "archery_ticket_price": "0", + "id": "3839", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,5,0,0", + "equipment_slot": "5" + }, + { + "shop_price": "5000", + "examine": "The Holy book of Saradomin.", + "durability": null, + "name": "Holy book", + "weight": "1", + "archery_ticket_price": "0", + "id": "3840", + "bonuses": "0,0,0,0,0,8,8,8,8,8,8,0,5,0,0", + "equipment_slot": "5" + }, + { + "shop_price": "5000", + "examine": "An incomplete book of Zamorak.", + "durability": null, + "name": "Damaged book", + "weight": "1", + "archery_ticket_price": "0", + "id": "3841", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,5,0,0", + "equipment_slot": "5" + }, + { + "examine": "The unholy book of Zamorak.", + "durability": null, + "name": "Unholy book", + "weight": "1", + "archery_ticket_price": "0", + "id": "3842", + "bonuses": "8,8,8,8,8,0,0,0,0,0,0,0,5,0,0", + "equipment_slot": "5" + }, + { + "shop_price": "5000", + "examine": "An incomplete book of Guthix.", + "durability": null, + "name": "Damaged book", + "weight": "1", + "archery_ticket_price": "0", + "id": "3843", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,5,0,0", + "equipment_slot": "5" + }, + { + "examine": "The holy book of Guthix.", + "durability": null, + "name": "Book of balance", + "weight": "1", + "archery_ticket_price": "0", + "id": "3844", + "bonuses": "4,4,4,4,4,4,4,4,4,4,4,0,5,0,0", + "equipment_slot": "5" + }, + { + "examine": "Looks like some kind of manual.", + "durability": null, + "name": "Manual", + "tradeable": "false", + "destroy": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "3847" + }, + { + "examine": "A key to the front door of the lighthouse. (Horror from the Deep)", + "durability": null, + "name": "Lighthouse key", + "archery_ticket_price": "0", + "id": "3848" + }, + { + "examine": "Looks old and rusty...", + "durability": null, + "name": "Rusty casket", + "tradeable": "false", + "destroy": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "3849" + }, + { + "durability": null, + "name": "Unholy symbol", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3852" + }, + { + "shop_price": "490", + "ge_buy_limit": "10000", + "examine": "An enchanted necklace.", + "grand_exchange_price": "852", + "durability": null, + "name": "Games necklace(8)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3853", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "852", + "durability": null, + "name": "Games necklace(8)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3854" + }, + { + "shop_price": "490", + "examine": "An enchanted necklace.", + "grand_exchange_price": "8", + "durability": null, + "name": "Games necklace(7)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3855", + "equipment_slot": "2" + }, + { + "durability": null, + "name": "Games necklace(7)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3856" + }, + { + "shop_price": "490", + "examine": "An enchanted necklace.", + "grand_exchange_price": "8", + "durability": null, + "name": "Games necklace(6)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3857", + "equipment_slot": "2" + }, + { + "durability": null, + "name": "Games necklace(6)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3858" + }, + { + "shop_price": "490", + "examine": "An enchanted necklace.", + "grand_exchange_price": "8", + "durability": null, + "name": "Games necklace(5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3859", + "equipment_slot": "2" + }, + { + "durability": null, + "name": "Games necklace(5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3860" + }, + { + "shop_price": "490", + "examine": "An enchanted necklace.", + "grand_exchange_price": "8", + "durability": null, + "name": "Games necklace(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3861", + "equipment_slot": "2" + }, + { + "durability": null, + "name": "Games necklace(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3862" + }, + { + "shop_price": "490", + "examine": "An enchanted necklace.", + "grand_exchange_price": "8", + "durability": null, + "name": "Games necklace(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3863", + "equipment_slot": "2" + }, + { + "durability": null, + "name": "Games necklace(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3864" + }, + { + "shop_price": "490", + "examine": "An enchanted necklace.", + "grand_exchange_price": "8", + "durability": null, + "name": "Games necklace(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3865", + "equipment_slot": "2" + }, + { + "durability": null, + "name": "Games necklace(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3866" + }, + { + "shop_price": "490", + "ge_buy_limit": "10000", + "examine": "An enchanted necklace.", + "grand_exchange_price": "2093", + "durability": null, + "name": "Games necklace(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3867", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "2093", + "durability": null, + "name": "Games necklace(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "3868" + }, + { + "durability": null, + "name": "Stool", + "archery_ticket_price": "0", + "id": "3893", + "equipment_slot": "3" + }, + { + "examine": "It's not very good.", + "durability": null, + "name": "Awful anthem", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "3894" + }, + { + "examine": "Much better.", + "durability": null, + "name": "Good anthem", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "3895" + }, + { + "examine": "Just needs the King's signature.", + "durability": null, + "name": "Treaty", + "archery_ticket_price": "0", + "id": "3896" + }, + { + "examine": "For making a giant pen.", + "durability": null, + "name": "Giant nib", + "archery_ticket_price": "0", + "id": "3897" + }, + { + "examine": "The king should be able to use this.", + "durability": null, + "name": "Giant pen", + "archery_ticket_price": "0", + "id": "3898" + }, + { + "shop_price": "15", + "examine": "Not as good as a pet frog.", + "durability": null, + "name": "Iron sickle", + "weight": "1.6", + "archery_ticket_price": "0", + "id": "3899", + "weapon_interface": "6", + "bonuses": "0,0,0,0,0,0,1,1,1,1,0,1,0,0,0", + "equipment_slot": "3" + }, + { + "examine": "Managing Thine Kingdom for Noobes by A. Ghrim.", + "durability": null, + "name": "Ghrim's book", + "weight": "1", + "archery_ticket_price": "0", + "id": "3901" + }, + { + "examine": "A pile of gout tubers suitable for use in mountainous terrain.", + "durability": null, + "name": "Hardy gout tuber", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "4001" + }, + { + "examine": "It looks like some kind of control panel.", + "durability": null, + "name": "Spare controls", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "4002" + }, + { + "examine": "It's the official Gnome Royal Seal, signed by King Narode Shareen.", + "durability": null, + "name": "Gnome royal seal", + "archery_ticket_price": "0", + "id": "4004" + }, + { + "shop_price": "160", + "examine": "Unreadable orders handwritten by King Narnode Shareen.", + "durability": null, + "name": "Narnode's orders", + "archery_ticket_price": "0", + "id": "4005" + }, + { + "shop_price": "10", + "examine": "Magical monkey talking dentures! What more can we say? Ook!", + "durability": null, + "name": "Monkey dentures", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "4006" + }, + { + "examine": "A gold bar with a talkative monkey spirit.", + "durability": null, + "name": "Enchanted bar", + "weight": "2", + "archery_ticket_price": "0", + "id": "4007" + }, + { + "shop_price": "3", + "examine": "It's... the eye of a gnome! Now what on earth could one do with this?", + "durability": null, + "name": "Eye of gnome", + "weight": "1", + "archery_ticket_price": "0", + "id": "4008" + }, + { + "shop_price": "3", + "examine": "It's... the eye of a gnome! Now what on earth could one do with this?", + "durability": null, + "name": "Eye of gnome", + "weight": "1", + "archery_ticket_price": "0", + "id": "4009" + }, + { + "shop_price": "3", + "examine": "They are Monkey Nuts. Yummy.", + "durability": null, + "name": "Monkey nuts", + "archery_ticket_price": "0", + "id": "4012" + }, + { + "shop_price": "50", + "examine": "It's a monkey bar. It looks highly nutritious.", + "durability": null, + "name": "Monkey bar", + "archery_ticket_price": "0", + "id": "4014" + }, + { + "shop_price": "300", + "examine": "It's a bowl full of mushy banana", + "durability": null, + "name": "Banana stew", + "archery_ticket_price": "0", + "id": "4016" + }, + { + "examine": "It's an amulet mould shaped like a monkey head.", + "durability": null, + "name": "M'amulet mould", + "weight": "1", + "archery_ticket_price": "0", + "id": "4020" + }, + { + "examine": "It's an Amulet of Monkey Speak. It makes vague chattering noises.", + "durability": null, + "name": "M'speak amulet", + "weight": "1.3", + "archery_ticket_price": "0", + "id": "4021", + "equipment_slot": "2" + }, + { + "examine": "It's an unstrung Amulet of Monkey Speak. It makes vague chattering noises.", + "durability": null, + "name": "M'speak amulet", + "weight": "1.3", + "archery_ticket_price": "0", + "id": "4022" + }, + { + "shop_price": "1000", + "examine": "A magic talisman in shape of a monkey head.", + "durability": null, + "name": "Monkey talisman", + "weight": "1.25", + "archery_ticket_price": "0", + "id": "4023" + }, + { + "examine": "A magical talisman in the shape of a Karamjan monkey head.", + "durability": null, + "name": "Monkey greegree", + "archery_ticket_price": "0", + "id": "4024", + "equipment_slot": "3" + }, + { + "examine": "A magical talisman in the shape of a Karamjan monkey head.", + "durability": null, + "name": "Monkey greegree", + "archery_ticket_price": "0", + "id": "4025", + "equipment_slot": "3" + }, + { + "examine": "A magical talisman in the shape of a Karamjan monkey head.", + "durability": null, + "name": "Monkey greegree", + "archery_ticket_price": "0", + "id": "4026", + "equipment_slot": "3" + }, + { + "examine": "A magical talisman in the shape of a Karamjan monkey head.", + "durability": null, + "name": "Monkey greegree", + "archery_ticket_price": "0", + "id": "4027", + "equipment_slot": "3" + }, + { + "examine": "A magical talisman in the shape of a Karamjan monkey head.", + "durability": null, + "name": "Monkey greegree", + "archery_ticket_price": "0", + "id": "4028", + "equipment_slot": "3" + }, + { + "examine": "A magical talisman in the shape of a Karamjan monkey head.", + "durability": null, + "name": "Monkey greegree", + "archery_ticket_price": "0", + "id": "4029", + "equipment_slot": "3" + }, + { + "examine": "A magical talisman in the shape of a Karamjan monkey head.", + "durability": null, + "name": "Monkey greegree", + "archery_ticket_price": "0", + "id": "4030", + "equipment_slot": "3" + }, + { + "examine": "A magical talisman in the shape of a Karamjan monkey head.", + "durability": null, + "name": "Monkey greegree", + "archery_ticket_price": "0", + "id": "4031", + "equipment_slot": "3" + }, + { + "examine": "I can train on this", + "durability": null, + "name": "Dummy", + "archery_ticket_price": "0", + "id": "4032" + }, + { + "examine": "It's a very ancient skull from some kind of ape.", + "durability": null, + "name": "Monkey skull", + "archery_ticket_price": "0", + "id": "4034" + }, + { + "examine": "It is the official sigil of the 10th squad of the Royal Guard.", + "durability": null, + "name": "10th squad sigil", + "archery_ticket_price": "0", + "id": "4035", + "equipment_slot": "2" + }, + { + "turn90cw_anim": "1424", + "examine": "The Holy Team Standard", + "walk_anim": "1422", + "durability": null, + "weight": "2", + "turn90ccw_anim": "1425", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1423", + "render_anim": "131", + "equipment_slot": "3", + "stand_anim": "1421", + "name": "Saradomin banner", + "tradeable": "false", + "run_anim": "1427", + "archery_ticket_price": "0", + "id": "4037", + "stand_turn_anim": "1426" + }, + { + "durability": null, + "name": "Saradomin banner", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "4038" + }, + { + "turn90cw_anim": "1424", + "examine": "The Zamorak team's flag.", + "walk_anim": "1422", + "durability": null, + "turn90ccw_anim": "1425", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1423", + "render_anim": "131", + "equipment_slot": "3", + "stand_anim": "1421", + "name": "Zamorak banner", + "tradeable": "false", + "run_anim": "1427", + "archery_ticket_price": "0", + "id": "4039", + "stand_turn_anim": "1426" + }, + { + "durability": null, + "name": "Zamorak banner", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "4040" + }, + { + "examine": "The colours of Saradomin/Zamorak.", + "durability": null, + "name": "Hooded cloak", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "4041", + "equipment_slot": "1" + }, + { + "examine": "The colours of Saradomin/Zamorak.", + "durability": null, + "name": "Hooded cloak", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "4042", + "equipment_slot": "1" + }, + { + "durability": null, + "name": "Rock", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4044" + }, + { + "examine": "I could use this to destroy things...", + "durability": null, + "name": "Explosive potion", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4045" + }, + { + "durability": null, + "name": "Explosive potion", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4046" + }, + { + "examine": "A coil of rope.", + "durability": null, + "name": "Climbing rope", + "archery_ticket_price": "0", + "id": "4047" + }, + { + "durability": null, + "name": "Climbing rope", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4048" + }, + { + "examine": "A box of bandages for healing.", + "durability": null, + "name": "Bandages", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4049" + }, + { + "durability": null, + "name": "Bandages", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4050" + }, + { + "examine": "Good for repairing a broken cannon.", + "durability": null, + "name": "Toolkit", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "4051" + }, + { + "durability": null, + "name": "Toolkit", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4052" + }, + { + "examine": "Handy for hindering the enemy team's movement.", + "durability": null, + "name": "Barricade", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4053" + }, + { + "durability": null, + "name": "Barricade", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4054" + }, + { + "shop_price": "5", + "examine": "It's a manual for Castle Wars", + "durability": null, + "name": "Castlewars manual", + "weight": "1", + "archery_ticket_price": "0", + "id": "4055" + }, + { + "examine": "I can exchange these for further items.", + "durability": null, + "name": "Castle wars ticket", + "archery_ticket_price": "0", + "id": "4067" + }, + { + "requirements": "{0,5}", + "shop_price": "50", + "turn90cw_anim": "821", + "examine": "A very decorative sword.", + "walk_anim": "819", + "durability": null, + "weight": "1", + "turn90ccw_anim": "822", + "weapon_interface": "6", + "turn180_anim": "820", + "equip_audio": "2248", + "render_anim": "1", + "castle_wars_ticket_price": "5", + "equipment_slot": "3", + "stand_anim": "808", + "name": "Decorative sword", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "4068", + "stand_turn_anim": "823", + "bonuses": "13,18,-2,0,0,0,3,2,0,0,0,16,0,0,0" + }, + { + "remove_sleeves": "true", + "requirements": "{1,5}", + "durability": null, + "name": "Decorative armour", + "archery_ticket_price": "0", + "id": "4069", + "bonuses": "0,0,0,-30,-10,32,31,24,-6,31,5,0,0,0,0", + "castle_wars_ticket_price": "8", + "equipment_slot": "4" + }, + { + "requirements": "{1,5}", + "durability": null, + "name": "Decorative armour", + "archery_ticket_price": "0", + "id": "4070", + "bonuses": "0,0,0,-21,-7,17,16,15,-4,16,2,0,0,0,0", + "castle_wars_ticket_price": "6", + "equipment_slot": "7" + }, + { + "remove_head": "true", + "requirements": "{1,5}", + "shop_price": "40", + "examine": "A very decorative helm.", + "durability": null, + "name": "Decorative helm", + "weight": "1", + "archery_ticket_price": "0", + "id": "4071", + "bonuses": "0,0,0,-3,-1,7,8,6,-1,7,3,0,0,0,0", + "castle_wars_ticket_price": "4", + "equipment_slot": "0" + }, + { + "requirements": "{1,5}", + "shop_price": "60", + "examine": "A very decorative shield.", + "durability": null, + "name": "Decorative shield", + "archery_ticket_price": "0", + "id": "4072", + "bonuses": "0,0,0,-8,-2,13,15,14,-1,14,5,0,0,0,0", + "castle_wars_ticket_price": "6", + "equipment_slot": "5" + }, + { + "examine": "Not so useful for lighting a fire.", + "durability": null, + "name": "Damp tinderbox", + "archery_ticket_price": "0", + "id": "4073" + }, + { + "durability": null, + "name": "Damp tinderbox", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4074" + }, + { + "examine": "A bizarre fungus. It glows with a pale blue light.", + "durability": null, + "name": "Glowing fungus", + "archery_ticket_price": "0", + "id": "4075" + }, + { + "examine": "A key I found in the lower levels of the Morytanian mines. (Haunted Mine) / As the 'Innocent-looking key': A shiny key sitting quietly on a crate.", + "durability": null, + "name": "Crystal-mine key", + "archery_ticket_price": "0", + "id": "4077" + }, + { + "examine": "I stole this from a Saradominist I met South of Mort'ton.", + "durability": null, + "name": "Zealot's key", + "archery_ticket_price": "0", + "id": "4078" + }, + { + "examine": "A gift from Santa.", + "durability": null, + "name": "Yo-yo", + "archery_ticket_price": "0", + "id": "4079" + }, + { + "examine": "Increases the wearer's strength and accuracy by 15% when fighting the undead.", + "durability": null, + "name": "Salve amulet", + "weight": "0.6", + "archery_ticket_price": "0", + "id": "4081", + "bonuses": "0,0,0,0,0,3,3,3,0,0,3,0,3,0,0", + "equipment_slot": "2" + }, + { + "examine": "An unstrung crystal imbued with the power of Saradomin.", + "durability": null, + "name": "Salve shard", + "archery_ticket_price": "0", + "id": "4082" + }, + { + "examine": "Unwaxed: It needs waxing before I can use it. Waxed: A waxed sled.", + "durability": null, + "name": "Sled", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "4083", + "equipment_slot": "3" + }, + { + "turn90cw_anim": "1468", + "examine": "Unwaxed: It needs waxing before I can use it. Waxed: A waxed sled.", + "walk_anim": "1468", + "durability": null, + "turn90ccw_anim": "1468", + "attack_speed": "4", + "two_handed": "true", + "turn180_anim": "1468", + "render_anim": "1119", + "equipment_slot": "3", + "stand_anim": "1461", + "name": "Sled", + "run_anim": "1468", + "archery_ticket_price": "0", + "id": "4084", + "stand_turn_anim": "1468" + }, + { + "examine": "I can use this to wax my sled.", + "durability": null, + "name": "Wax", + "archery_ticket_price": "0", + "id": "4085", + "equipment_slot": "5" + }, + { + "examine": "These pale flowers have a pungent odour.", + "durability": null, + "name": "Trollweiss", + "archery_ticket_price": "0", + "attack_speed": "5", + "id": "4086", + "weapon_interface": "12", + "bonuses": "-100,-100,-50,0,0,0,0,0,0,0,0,-10,0,0,0", + "equipment_slot": "3" + }, + { + "requirements": "{1,60}", + "ge_buy_limit": "10", + "examine": "Looks pretty heavy.", + "durability": null, + "rare_item": "true", + "weight": "9", + "absorb": "3,0,6", + "equip_audio": "2242", + "equipment_slot": "7", + "lendable": "true", + "grand_exchange_price": "190500", + "name": "Dragon platelegs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4087", + "bonuses": "0,0,0,-21,-7,68,66,63,-4,65,20,0,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "190500", + "durability": null, + "name": "Dragon platelegs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4088" + }, + { + "requirements": "{1,20}-{6,40}", + "shop_price": "15000", + "ge_buy_limit": "100", + "examine": "Blue: A magical hat. ", + "durability": null, + "weight": "0.4", + "absorb": "3,1,0", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "13700", + "name": "Mystic hat", + "tradeable": "true", + "archery_ticket_price": "0", + "hat": true, + "id": "4089", + "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "13700", + "durability": null, + "name": "Mystic hat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4090" + }, + { + "requirements": "{1,20}-{6,40}", + "shop_price": "120000", + "ge_buy_limit": "100", + "examine": "The upper half of a magical robe.", + "durability": null, + "weight": "2.7", + "absorb": "3,1,0", + "equipment_slot": "4", + "lendable": "true", + "remove_sleeves": "true", + "grand_exchange_price": "72100", + "name": "Mystic robe top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4091", + "bonuses": "0,0,0,20,0,0,0,0,20,0,20,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "72100", + "durability": null, + "name": "Mystic robe top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4092" + }, + { + "requirements": "{1,20}-{6,40}", + "shop_price": "80000", + "ge_buy_limit": "100", + "examine": "The lower half of a magical robe.", + "durability": null, + "absorb": "4,2,0", + "equipment_slot": "7", + "lendable": "true", + "grand_exchange_price": "47700", + "name": "Mystic robe bottom", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4093", + "bonuses": "0,0,0,15,0,0,0,0,15,0,15,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "47700", + "durability": null, + "name": "Mystic robe bottom", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4094" + }, + { + "requirements": "{1,20}-{6,40}", + "shop_price": "10000", + "ge_buy_limit": "100", + "examine": "Magical gloves.", + "durability": null, + "weight": "0.4", + "equipment_slot": "9", + "lendable": "true", + "grand_exchange_price": "5913", + "name": "Mystic gloves", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4095", + "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "5913", + "durability": null, + "name": "Mystic gloves", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4096" + }, + { + "requirements": "{1,20}-{6,40}", + "shop_price": "10000", + "ge_buy_limit": "100", + "examine": "Magical boots.", + "durability": null, + "weight": "0.4", + "equipment_slot": "10", + "lendable": "true", + "grand_exchange_price": "6303", + "name": "Mystic boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4097", + "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "6303", + "durability": null, + "name": "Mystic boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4098" + }, + { + "requirements": "{1,20}-{6,40}", + "shop_price": "15000", + "ge_buy_limit": "100", + "examine": "Black: A magical hat. ", + "durability": null, + "weight": "0.4", + "absorb": "3,1,0", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "16700", + "name": "Mystic hat", + "tradeable": "true", + "archery_ticket_price": "0", + "hat": true, + "id": "4099", + "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "16700", + "durability": null, + "name": "Mystic hat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4100" + }, + { + "requirements": "{1,20}-{6,40}", + "shop_price": "120000", + "ge_buy_limit": "100", + "examine": "The upper half of a magical robe.", + "durability": null, + "weight": "2.7", + "absorb": "3,1,0", + "equipment_slot": "4", + "lendable": "true", + "remove_sleeves": "true", + "grand_exchange_price": "75100", + "name": "Mystic robe top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4101", + "bonuses": "0,0,0,20,0,0,0,0,20,0,20,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "75100", + "durability": null, + "name": "Mystic robe top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4102" + }, + { + "requirements": "{1,20}-{6,40}", + "shop_price": "80000", + "ge_buy_limit": "100", + "examine": "The lower half of a magical robe.", + "durability": null, + "absorb": "4,2,0", + "equipment_slot": "7", + "lendable": "true", + "grand_exchange_price": "50700", + "name": "Mystic robe bottom", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4103", + "bonuses": "0,0,0,15,0,0,0,0,15,0,15,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "50700", + "durability": null, + "name": "Mystic robe bottom", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4104" + }, + { + "requirements": "{1,20}-{6,40}", + "shop_price": "10000", + "ge_buy_limit": "100", + "examine": "Dark magical gloves.", + "durability": null, + "weight": "0.4", + "equipment_slot": "9", + "lendable": "true", + "grand_exchange_price": "8913", + "name": "Mystic gloves", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4105", + "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "8913", + "durability": null, + "name": "Mystic gloves", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4106" + }, + { + "requirements": "{1,20}-{6,40}", + "shop_price": "10000", + "ge_buy_limit": "100", + "examine": "Magical boots.", + "durability": null, + "weight": "0.4", + "equipment_slot": "10", + "lendable": "true", + "grand_exchange_price": "9303", + "name": "Mystic boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4107", + "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "9303", + "durability": null, + "name": "Mystic boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4108" + }, + { + "requirements": "{1,20}-{6,40}", + "shop_price": "15000", + "ge_buy_limit": "100", + "examine": "White: A magical hat. ", + "durability": null, + "weight": "0.4", + "absorb": "3,1,0", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "16700", + "name": "Mystic hat", + "tradeable": "true", + "archery_ticket_price": "0", + "hat": true, + "id": "4109", + "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "16700", + "durability": null, + "name": "Mystic hat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4110" + }, + { + "requirements": "{1,20}-{6,40}", + "shop_price": "120000", + "ge_buy_limit": "100", + "examine": "The upper half of a magical robe.", + "durability": null, + "weight": "2.7", + "absorb": "3,1,0", + "equipment_slot": "4", + "lendable": "true", + "remove_sleeves": "true", + "grand_exchange_price": "75100", + "name": "Mystic robe top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4111", + "bonuses": "0,0,0,20,0,0,0,0,20,0,20,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "75100", + "durability": null, + "name": "Mystic robe top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4112" + }, + { + "requirements": "{1,20}-{6,40}", + "shop_price": "80000", + "ge_buy_limit": "100", + "examine": "The lower half of a magical robe.", + "durability": null, + "absorb": "4,2,0", + "equipment_slot": "7", + "lendable": "true", + "grand_exchange_price": "50700", + "name": "Mystic robe bottom", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4113", + "bonuses": "0,0,0,15,0,0,0,0,15,0,15,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "50700", + "durability": null, + "name": "Mystic robe bottom", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4114" + }, + { + "requirements": "{1,20}-{6,40}", + "shop_price": "10000", + "ge_buy_limit": "100", + "examine": "Bright magical gloves.", + "durability": null, + "weight": "0.4", + "equipment_slot": "9", + "lendable": "true", + "grand_exchange_price": "8913", + "name": "Mystic gloves", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4115", + "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "8913", + "durability": null, + "name": "Mystic gloves", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4116" + }, + { + "requirements": "{1,20}-{6,40}", + "shop_price": "10000", + "ge_buy_limit": "100", + "examine": "Magical boots.", + "durability": null, + "weight": "0.4", + "equipment_slot": "10", + "lendable": "true", + "grand_exchange_price": "9303", + "name": "Mystic boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4117", + "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "9303", + "durability": null, + "name": "Mystic boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4118" + }, + { + "ge_buy_limit": "100", + "examine": "These will protect my feet.", + "grand_exchange_price": "359", + "durability": null, + "name": "Bronze boots", + "tradeable": "true", + "weight": "1.3", + "archery_ticket_price": "0", + "id": "4119", + "bonuses": "0,0,0,-3,-1,1,2,3,0,0,0,0,0,0,0", + "equip_audio": "2237", + "equipment_slot": "10" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "359", + "durability": null, + "name": "Bronze boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4120" + }, + { + "ge_buy_limit": "100", + "examine": "These will protect my feet.", + "grand_exchange_price": "17000", + "durability": null, + "name": "Iron boots", + "tradeable": "true", + "weight": "1.3", + "archery_ticket_price": "0", + "id": "4121", + "bonuses": "0,0,0,-3,-1,2,3,4,0,0,0,0,0,0,0", + "equip_audio": "2237", + "equipment_slot": "10" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "17000", + "durability": null, + "name": "Iron boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4122" + }, + { + "requirements": "{1,5}", + "ge_buy_limit": "100", + "examine": "These will protect my feet.", + "durability": null, + "weight": "1.3", + "equip_audio": "2237", + "equipment_slot": "10", + "grand_exchange_price": "258", + "name": "Steel boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4123", + "bonuses": "0,0,0,-3,-1,5,6,7,0,0,5,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "258", + "durability": null, + "name": "Steel boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4124" + }, + { + "requirements": "{1,10}", + "ge_buy_limit": "100", + "examine": "These will protect my feet.", + "durability": null, + "weight": "1.3", + "equip_audio": "2237", + "equipment_slot": "10", + "grand_exchange_price": "317", + "name": "Black boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4125", + "bonuses": "0,0,0,-3,-1,7,8,9,0,0,7,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "317", + "durability": null, + "name": "Black boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4126" + }, + { + "requirements": "{1,20}", + "ge_buy_limit": "100", + "examine": "These will protect my feet.", + "durability": null, + "weight": "1", + "equip_audio": "2237", + "equipment_slot": "10", + "grand_exchange_price": "580", + "name": "Mithril boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4127", + "bonuses": "0,0,0,-3,-1,8,9,10,0,0,8,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "580", + "durability": null, + "name": "Mithril boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4128" + }, + { + "requirements": "{1,30}", + "ge_buy_limit": "100", + "examine": "These will protect my feet.", + "durability": null, + "weight": "1.3", + "equip_audio": "2237", + "equipment_slot": "10", + "grand_exchange_price": "1336", + "name": "Adamant boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4129", + "bonuses": "0,0,0,-3,-1,10,11,12,0,0,9,1,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1336", + "durability": null, + "name": "Adamant boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4130" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "100", + "examine": "These will protect my feet.", + "durability": null, + "weight": "1.3", + "equip_audio": "2237", + "equipment_slot": "10", + "lendable": "true", + "grand_exchange_price": "7474", + "name": "Rune boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4131", + "bonuses": "0,0,0,-3,-1,12,13,14,0,0,10,2,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "7474", + "durability": null, + "name": "Rune boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4132" + }, + { + "durability": null, + "name": "Crawling hand", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "4133" + }, + { + "examine": "A spiky crawling critter. (level 23) Not very tasty-looking. (level 138)", + "durability": null, + "name": "Cave crawler", + "archery_ticket_price": "0", + "attack_speed": "3", + "id": "4134" + }, + { + "examine": "A tortured screaming soul.", + "durability": null, + "name": "Banshee", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "4135" + }, + { + "examine": "The slime of evil.", + "durability": null, + "name": "Rockslug", + "archery_ticket_price": "0", + "id": "4136" + }, + { + "examine": "The winged reptile.", + "durability": null, + "name": "Cockatrice", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "4137" + }, + { + "examine": "A small fire demon.", + "durability": null, + "name": "Pyrefiend", + "archery_ticket_price": "0", + "id": "4138" + }, + { + "examine": "The eyes of evil.", + "durability": null, + "name": "Basilisk", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "4139" + }, + { + "examine": "An evil magic user.", + "durability": null, + "name": "Infernal mage", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "4140" + }, + { + "examine": "The tongue of evil.", + "durability": null, + "name": "Bloodveld", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "4141" + }, + { + "examine": "• Needs cream.....• Wibbly.• Wobbly...• There's always room for jelly.• Doesn't look so tough...• Looks scared to see me.", + "durability": null, + "name": "Jelly", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "4142" + }, + { + "durability": null, + "name": "Turoth", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "4143" + }, + { + "examine": "A very smelly ghost.", + "durability": null, + "name": "Abberant spectre", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "4144" + }, + { + "examine": "The vacuumed face of evil.", + "durability": null, + "name": "Dust devil", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "4145" + }, + { + "durability": null, + "name": "Kurask", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "4146" + }, + { + "examine": "Flies like a rock.", + "durability": null, + "name": "Gargoyle", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "4147" + }, + { + "durability": null, + "name": "Nechryael", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "4148" + }, + { + "examine": "A denizen of the Abyss!", + "durability": null, + "name": "Abyssal demon", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "4149" + }, + { + "shop_price": "90", + "examine": "Arrows with a wider than normal tip.", + "durability": null, + "name": "Broad arrows", + "archery_ticket_price": "0", + "id": "4150", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,28,0,0" + }, + { + "ge_buy_limit": "10", + "turn90cw_anim": "821", + "examine": "A weapon from the Abyss.", + "walk_anim": "1660", + "has_special": "true", + "rare_item": "true", + "turn90ccw_anim": "822", + "attack_speed": "4", + "turn180_anim": "820", + "defence_anim": "1659", + "equipment_slot": "3", + "attack_anims": "1658,1658,1658,1658", + "grand_exchange_price": "413500", + "stand_anim": "808", + "tradeable": "true", + "run_anim": "1661", + "archery_ticket_price": "0", + "id": "4151", + "stand_turn_anim": "823", + "bonuses": "0,82,0,0,0,0,0,0,0,0,0,82,0,0,0", + "requirements": "{0,70}", + "durability": null, + "weight": "0.45", + "weapon_interface": "11", + "equip_audio": "2249", + "render_anim": "620", + "lendable": "true", + "attack_audios": "2720,0,0,0", + "name": "Abyssal whip" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "413500", + "durability": null, + "name": "Abyssal whip", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4152" + }, + { + "ge_buy_limit": "10", + "turn90cw_anim": "1663", + "examine": "Simplicity is the best weapon.", + "walk_anim": "1663", + "has_special": "true", + "rare_item": "true", + "turn90ccw_anim": "1663", + "attack_speed": "7", + "two_handed": "true", + "turn180_anim": "1663", + "defence_anim": "1666", + "equipment_slot": "3", + "attack_anims": "1665,1665,1665,1665", + "grand_exchange_price": "29900", + "stand_anim": "1662", + "tradeable": "true", + "run_anim": "1664", + "archery_ticket_price": "0", + "id": "4153", + "stand_turn_anim": "823", + "bonuses": "0,0,81,0,0,0,0,0,0,0,0,79,0,0,0", + "requirements": "{0,50}-{2,50}", + "durability": null, + "weight": "4.5", + "weapon_interface": "10", + "render_anim": "27", + "lendable": "true", + "attack_audios": "2714,0,0,0", + "name": "Granite maul" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "29900", + "durability": null, + "name": "Granite maul", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4154" + }, + { + "shop_price": "1", + "examine": "I can contact the Slayer Masters with this.", + "durability": null, + "name": "Enchanted gem", + "archery_ticket_price": "0", + "id": "4155" + }, + { + "requirements": "{1,20}-{18,25}", + "shop_price": "5000", + "ge_buy_limit": "100", + "examine": "I can just about see things in this shield's reflection.", + "durability": null, + "weight": "2.2", + "equipment_slot": "5", + "grand_exchange_price": "3318", + "name": "Mirror shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4156", + "bonuses": "0,0,0,0,0,10,15,5,5,10,5,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3318", + "durability": null, + "name": "Mirror shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4157" + }, + { + "requirements": "{0,55}-{18,50}", + "shop_price": "31000", + "turn90cw_anim": "1207", + "examine": "A spear with a leaf-shaped point.", + "walk_anim": "1205", + "durability": null, + "weight": "2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1206", + "equip_audio": "2247", + "defence_anim": "2079", + "render_anim": "28", + "equipment_slot": "3", + "attack_anims": "2080,2081,2082,2080", + "stand_anim": "813", + "name": "Leaf-bladed spear", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "4158", + "stand_turn_anim": "1209", + "bonuses": "47,42,36,0,0,1,1,0,0,0,0,50,0,0,0" + }, + { + "requirements": "{0,55}-{18,50}", + "shop_price": "31000", + "examine": "A spear with a leaf-shaped point.", + "durability": null, + "name": "Leaf-bladed spear", + "weight": "2", + "archery_ticket_price": "0", + "attack_speed": "5", + "id": "4159", + "equip_audio": "2247", + "equipment_slot": "3" + }, + { + "requirements": "{18,55}-{4,50}", + "shop_price": "90", + "examine": "Arrows with a wider than normal tip.", + "durability": null, + "name": "Broad arrow", + "archery_ticket_price": "0", + "id": "4160", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,28", + "equipment_slot": "13" + }, + { + "shop_price": "10", + "ge_buy_limit": "100", + "examine": "A bag of salt.", + "grand_exchange_price": "1", + "durability": null, + "name": "Bag of salt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4161" + }, + { + "shop_price": "500", + "ge_buy_limit": "100", + "examine": "I can even smash stone with this.", + "grand_exchange_price": "140", + "durability": null, + "name": "Rock hammer", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "4162", + "equipment_slot": "3" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "140", + "durability": null, + "name": "Rock hammer", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4163" + }, + { + "requirements": "{18,10}", + "shop_price": "200", + "ge_buy_limit": "100", + "examine": "Stops me breathing in too much dust.", + "grand_exchange_price": "615", + "durability": null, + "name": "Face mask", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "4164", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "615", + "durability": null, + "name": "Face mask", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4165" + }, + { + "requirements": "{18,15}", + "shop_price": "200", + "ge_buy_limit": "100", + "examine": "These will protect my ears from loud noise.", + "grand_exchange_price": "484", + "durability": null, + "name": "Earmuffs", + "tradeable": "true", + "weight": "2.6", + "archery_ticket_price": "0", + "id": "4166", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "484", + "durability": null, + "name": "Earmuffs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4167" + }, + { + "requirements": "{18,60}", + "shop_price": "200", + "ge_buy_limit": "100", + "examine": "Protects me from any bad smells.", + "grand_exchange_price": "523", + "durability": null, + "name": "Nose peg", + "tradeable": "true", + "weight": "8", + "archery_ticket_price": "0", + "id": "4168", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "523", + "durability": null, + "name": "Nose peg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4169" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "An old and magical staff.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "4", + "turn180_anim": "1206", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "grand_exchange_price": "12100", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "4170", + "stand_turn_anim": "1209", + "bonuses": "7,-1,25,12,0,2,3,1,10,0,0,35,0,0,0", + "requirements": "{18,55}-{6,50}", + "shop_price": "21000", + "durability": null, + "weight": "1.8", + "weapon_interface": "1", + "equip_audio": "2247", + "render_anim": "28", + "attack_audios": "2555,0,0,0", + "name": "Slayer's staff" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "12100", + "durability": null, + "name": "Slayer's staff", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4171" + }, + { + "shop_price": "90", + "examine": "Arrows with a wider than normal tip.", + "durability": null, + "name": "Broad arrows", + "archery_ticket_price": "0", + "id": "4172", + "equipment_slot": "13" + }, + { + "shop_price": "90", + "examine": "Arrows with a wider than normal tip.", + "durability": null, + "name": "Broad arrows", + "archery_ticket_price": "0", + "id": "4173", + "equipment_slot": "13" + }, + { + "shop_price": "90", + "examine": "Arrows with a wider than normal tip.", + "durability": null, + "name": "Broad arrows", + "archery_ticket_price": "0", + "id": "4174", + "equipment_slot": "13" + }, + { + "shop_price": "90", + "examine": "Arrows with a wider than normal tip.", + "durability": null, + "name": "Broad arrows", + "archery_ticket_price": "0", + "id": "4175", + "equipment_slot": "13" + }, + { + "examine": "A weapon from the Abyss.", + "rare_item": "true", + "durability": null, + "weight": "0.45", + "attack_speed": "4", + "render_anim": "620", + "lendable": "true", + "grand_exchange_price": "388392", + "name": "Abyssal whip", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4178", + "bonuses": "0,82,0,0,0,0,0,0,0,0,0,82,0,0,0" + }, + { + "examine": "A big, bad troll.", + "durability": null, + "name": "Stick", + "archery_ticket_price": "0", + "attack_speed": "6", + "id": "4179" + }, + { + "lendable": "true", + "examine": "Looks pretty heavy.", + "grand_exchange_price": "165900", + "durability": null, + "name": "Dragon platelegs", + "tradeable": "true", + "weight": "9", + "archery_ticket_price": "0", + "id": "4180", + "absorb": "3,0,6", + "bonuses": "0,0,0,-21,-7,68,66,63,-4,65,20,0,0,0,0" + }, + { + "durability": null, + "name": "Mouth grip", + "archery_ticket_price": "0", + "id": "4181", + "equipment_slot": "3" + }, + { + "examine": "A pale, tough looking herb.", + "durability": null, + "name": "Goutweed", + "archery_ticket_price": "0", + "id": "4182" + }, + { + "examine": "A six-pointed marble and obsidian amulet", + "durability": null, + "name": "Star amulet", + "archery_ticket_price": "0", + "id": "4183" + }, + { + "examine": "Upon close examination, this seems to be a key.", + "durability": null, + "name": "Cavern key", + "archery_ticket_price": "0", + "id": "4184" + }, + { + "examine": "Upon close examination, this seems to be a key.", + "durability": null, + "name": "Tower key", + "archery_ticket_price": "0", + "id": "4185" + }, + { + "examine": "Upon close examination, this seems to be a key.", + "durability": null, + "name": "Shed key", + "archery_ticket_price": "0", + "id": "4186" + }, + { + "examine": "Triangular in shape, made from marble, and as large as your hand.", + "durability": null, + "name": "Marble amulet", + "archery_ticket_price": "0", + "id": "4187" + }, + { + "examine": "Triangular in shape, made from obsidian, and as large as your hand.", + "durability": null, + "name": "Obsidian amulet", + "archery_ticket_price": "0", + "id": "4188" + }, + { + "examine": "A length of garden cane.", + "durability": null, + "name": "Garden cane", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "4189" + }, + { + "examine": "A typical garden brush.", + "durability": null, + "name": "Garden brush", + "weight": "1", + "archery_ticket_price": "0", + "id": "4190" + }, + { + "examine": "A typical garden brush, with a cane tied to it.", + "durability": null, + "name": "Extended brush", + "weight": "1", + "archery_ticket_price": "0", + "id": "4191" + }, + { + "examine": "A typical garden brush, with two canes tied to it.", + "durability": null, + "name": "Extended brush", + "weight": "1", + "archery_ticket_price": "0", + "id": "4192" + }, + { + "examine": "A typical garden brush, with three canes tied to it.", + "durability": null, + "name": "Extended brush", + "weight": "1", + "archery_ticket_price": "0", + "id": "4193", + "equipment_slot": "3" + }, + { + "examine": "A pair of limp, dead arms.", + "durability": null, + "name": "Arms", + "weight": "2", + "archery_ticket_price": "0", + "id": "4195", + "alchemizable": "true" + }, + { + "examine": "A pair of lifeless, rotting legs.", + "durability": null, + "name": "Legs", + "archery_ticket_price": "0", + "id": "4196", + "alchemizable": "true" + }, + { + "examine": "No brain: A gruesome, decapitated head, whose brain has rotted away. Brain: A gruesome, decapitated head - its eyes stare lifelessly at nothing.", + "durability": null, + "name": "Decapitated head", + "weight": "3", + "archery_ticket_price": "0", + "id": "4197", + "alchemizable": "true" + }, + { + "examine": "No brain: A gruesome, decapitated head, whose brain has rotted away. Brain: A gruesome, decapitated head - its eyes stare lifelessly at nothing.", + "durability": null, + "name": "Decapitated head", + "weight": "3", + "archery_ticket_price": "0", + "id": "4198", + "alchemizable": "true" + }, + { + "shop_price": "50", + "examine": "A pickled brain, submerged inside a jar of vinegar.", + "durability": null, + "name": "Pickled brain", + "archery_ticket_price": "0", + "id": "4199", + "alchemizable": "true" + }, + { + "examine": "A mould for making silver lightning conductors.", + "durability": null, + "name": "Conductor mould", + "archery_ticket_price": "0", + "id": "4200" + }, + { + "examine": "A silver lightning conductor.", + "durability": null, + "name": "Conductor", + "weight": "4", + "archery_ticket_price": "0", + "id": "4201" + }, + { + "destroy_message": "Another can be received from pickpocketing Dr. Fenkenstrain in the tower.", + "examine": "The Ring of charos", + "durability": null, + "name": "Ring of charos", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "4202", + "equipment_slot": "12" + }, + { + "examine": "This consecration seed looks grey and dead.", + "durability": null, + "name": "Consecration seed", + "archery_ticket_price": "0", + "id": "4205" + }, + { + "examine": "This consecration seed looks grey and dead.", + "durability": null, + "name": "Consecration seed", + "archery_ticket_price": "0", + "id": "4206" + }, + { + "ge_buy_limit": "10", + "examine": "This crystal seed looks grey and dead.", + "grand_exchange_price": "92600", + "durability": null, + "name": "Crystal seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4207" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "92600", + "durability": null, + "name": "Crystal seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4208" + }, + { + "examine": "A book on Cadarn clan history.", + "durability": null, + "name": "Cadarn lineage", + "archery_ticket_price": "0", + "id": "4209" + }, + { + "requirements": "{4,70}-{16,50}", + "shop_price": "900000", + "ge_buy_limit": "10", + "examine": "A nice sturdy magical bow.", + "durability": null, + "weight": "1.8", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "16", + "equip_audio": "2238", + "render_anim": "2588", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "426,426,426,426", + "grand_exchange_price": "905300", + "attack_audios": "1352,1352,1352,0", + "name": "New crystal bow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4212", + "bonuses": "0,0,0,0,100,0,0,0,0,0,0,0,0,0,70" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "905300", + "durability": null, + "name": "New crystal bow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4213" + }, + { + "requirements": "{4,70}-{16,50}", + "shop_price": "900000", + "examine": "A nice sturdy magical bow.", + "durability": null, + "weight": "1.8", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "16", + "equip_audio": "2238", + "render_anim": "2588", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "426,426,426,426", + "grand_exchange_price": "901019", + "attack_audios": "1352,1352,1352,0", + "name": "Crystal bow full", + "archery_ticket_price": "0", + "id": "4214", + "bonuses": "0,0,0,0,100,0,0,0,0,0,0,0,0,0,70" + }, + { + "requirements": "{4,70}-{16,50}", + "shop_price": "900000", + "examine": "A nice sturdy magical bow.", + "durability": null, + "weight": "1.8", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "16", + "equip_audio": "2238", + "render_anim": "2588", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "426,426,426,426", + "grand_exchange_price": "901019", + "attack_audios": "1352,1352,1352,0", + "name": "Crystal bow 9/10", + "archery_ticket_price": "0", + "id": "4215", + "bonuses": "0,0,0,0,96,0,0,0,0,0,0,0,0,0,68" + }, + { + "requirements": "{4,70}-{16,50}", + "shop_price": "900000", + "examine": "A nice sturdy magical bow.", + "durability": null, + "weight": "1.8", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "16", + "equip_audio": "2238", + "render_anim": "2588", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "426,426,426,426", + "grand_exchange_price": "901019", + "attack_audios": "1352,1352,1352,0", + "name": "Crystal bow 8/10", + "archery_ticket_price": "0", + "id": "4216", + "bonuses": "0,0,0,0,92,0,0,0,0,0,0,0,0,0,66" + }, + { + "requirements": "{4,70}-{16,50}", + "shop_price": "900000", + "examine": "A nice sturdy magical bow.", + "durability": null, + "weight": "1.8", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "16", + "equip_audio": "2238", + "render_anim": "2588", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "426,426,426,426", + "grand_exchange_price": "901019", + "attack_audios": "1352,1352,1352,0", + "name": "Crystal bow 7/10", + "archery_ticket_price": "0", + "id": "4217", + "bonuses": "0,0,0,0,88,0,0,0,0,0,0,0,0,0,64" + }, + { + "requirements": "{4,70}-{16,50}", + "shop_price": "900000", + "examine": "A nice sturdy magical bow.", + "durability": null, + "weight": "1.8", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "16", + "equip_audio": "2238", + "render_anim": "2588", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "426,426,426,426", + "grand_exchange_price": "901019", + "attack_audios": "1352,1352,1352,0", + "name": "Crystal bow 6/10", + "archery_ticket_price": "0", + "id": "4218", + "bonuses": "0,0,0,0,84,0,0,0,0,0,0,0,0,0,62" + }, + { + "requirements": "{4,70}-{16,50}", + "shop_price": "900000", + "examine": "A nice sturdy magical bow.", + "durability": null, + "weight": "1.8", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "16", + "equip_audio": "2238", + "render_anim": "2588", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "426,426,426,426", + "grand_exchange_price": "901019", + "attack_audios": "1352,1352,1352,0", + "name": "Crystal bow 5/10", + "archery_ticket_price": "0", + "id": "4219", + "bonuses": "0,0,0,0,80,0,0,0,0,0,0,0,0,0,60" + }, + { + "requirements": "{4,70}-{16,50}", + "shop_price": "900000", + "examine": "A nice sturdy magical bow.", + "durability": null, + "weight": "1.8", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "16", + "equip_audio": "2238", + "render_anim": "2588", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "426,426,426,426", + "grand_exchange_price": "901019", + "attack_audios": "1352,1352,1352,0", + "name": "Crystal bow 4/10", + "archery_ticket_price": "0", + "id": "4220", + "bonuses": "0,0,0,0,76,0,0,0,0,0,0,0,0,0,58" + }, + { + "requirements": "{4,70}-{16,50}", + "shop_price": "900000", + "examine": "A nice sturdy magical bow.", + "durability": null, + "weight": "1.8", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "16", + "equip_audio": "2238", + "render_anim": "2588", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "426,426,426,426", + "grand_exchange_price": "901019", + "attack_audios": "1352,1352,1352,0", + "name": "Crystal bow 3/10", + "archery_ticket_price": "0", + "id": "4221", + "bonuses": "0,0,0,0,72,0,0,0,0,0,0,0,0,0,56" + }, + { + "requirements": "{4,70}-{16,50}", + "shop_price": "900000", + "examine": "A nice sturdy magical bow.", + "durability": null, + "weight": "1.8", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "16", + "equip_audio": "2238", + "render_anim": "2588", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "426,426,426,426", + "grand_exchange_price": "901019", + "attack_audios": "1352,1352,1352,0", + "name": "Crystal bow 2/10", + "archery_ticket_price": "0", + "id": "4222", + "bonuses": "0,0,0,0,68,0,0,0,0,0,0,0,0,0,54" + }, + { + "requirements": "{4,70}-{16,50}", + "shop_price": "900000", + "examine": "A nice sturdy magical bow.", + "durability": null, + "weight": "1.8", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "16", + "equip_audio": "2238", + "render_anim": "2588", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "426,426,426,426", + "grand_exchange_price": "901019", + "attack_audios": "1352,1352,1352,0", + "name": "Crystal bow 1/10", + "archery_ticket_price": "0", + "id": "4223", + "bonuses": "0,0,0,0,64,0,0,0,0,0,0,0,0,0,52" + }, + { + "requirements": "{1,70}-{16,50}", + "shop_price": "750000", + "ge_buy_limit": "10", + "examine": "A nice sturdy crystal shield.", + "durability": null, + "weight": "2", + "absorb": "6,0,12", + "equipment_slot": "5", + "grand_exchange_price": "756900", + "name": "New crystal shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4224", + "bonuses": "0,0,0,-10,-10,51,54,53,0,80,70,0,0,0,0" + }, + { + "requirements": "{1,70}-{16,50}", + "shop_price": "750000", + "examine": "A nice sturdy crystal shield.", + "grand_exchange_price": "749305", + "durability": null, + "name": "Crystal shield full", + "weight": "2", + "archery_ticket_price": "0", + "id": "4225", + "absorb": "6,0,12", + "bonuses": "0,0,0,-10,-10,51,54,53,0,80,70,0,0,0,0", + "equipment_slot": "5" + }, + { + "requirements": "{1,70}-{16,50}", + "shop_price": "750000", + "examine": "A nice sturdy crystal shield.", + "grand_exchange_price": "749305", + "durability": null, + "name": "Crystal shield 9/10", + "weight": "2", + "archery_ticket_price": "0", + "id": "4226", + "absorb": "6,0,12", + "bonuses": "0,0,0,-10,-10,49,52,51,0,78,68,0,0,0,0", + "equipment_slot": "5" + }, + { + "requirements": "{1,70}-{16,50}", + "shop_price": "750000", + "examine": "A nice sturdy crystal shield.", + "grand_exchange_price": "749305", + "durability": null, + "name": "Crystal shield 8/10", + "weight": "2", + "archery_ticket_price": "0", + "id": "4227", + "absorb": "6,0,12", + "bonuses": "0,0,0,-10,-10,47,50,49,0,76,66,0,0,0,0", + "equipment_slot": "5" + }, + { + "requirements": "{1,70}-{16,50}", + "shop_price": "750000", + "examine": "A nice sturdy crystal shield.", + "grand_exchange_price": "749305", + "durability": null, + "name": "Crystal shield 7/10", + "weight": "2", + "archery_ticket_price": "0", + "id": "4228", + "absorb": "6,0,12", + "bonuses": "0,0,0,-10,-10,45,48,47,0,74,65,0,0,0,0", + "equipment_slot": "5" + }, + { + "requirements": "{1,70}-{16,50}", + "shop_price": "750000", + "examine": "A nice sturdy crystal shield.", + "grand_exchange_price": "749305", + "durability": null, + "name": "Crystal shield 6/10", + "weight": "2", + "archery_ticket_price": "0", + "id": "4229", + "absorb": "6,0,12", + "bonuses": "0,0,0,-10,-10,43,46,45,0,72,63,0,0,0,0", + "equipment_slot": "5" + }, + { + "requirements": "{1,70}-{16,50}", + "shop_price": "750000", + "examine": "A nice sturdy crystal shield.", + "grand_exchange_price": "749305", + "durability": null, + "name": "Crystal shield 5/10", + "weight": "2", + "archery_ticket_price": "0", + "id": "4230", + "absorb": "6,0,12", + "bonuses": "0,0,0,-10,-10,41,44,43,0,70,61,0,0,0,0", + "equipment_slot": "5" + }, + { + "requirements": "{1,70}-{16,50}", + "shop_price": "750000", + "examine": "A nice sturdy crystal shield.", + "grand_exchange_price": "749305", + "durability": null, + "name": "Crystal shield 4/10", + "weight": "2", + "archery_ticket_price": "0", + "id": "4231", + "absorb": "6,0,12", + "bonuses": "0,0,0,-10,-10,39,42,41,0,68,59,0,0,0,0", + "equipment_slot": "5" + }, + { + "requirements": "{1,70}-{16,50}", + "shop_price": "750000", + "examine": "A nice sturdy crystal shield.", + "grand_exchange_price": "749305", + "durability": null, + "name": "Crystal shield 3/10", + "weight": "2", + "archery_ticket_price": "0", + "id": "4232", + "absorb": "6,0,12", + "bonuses": "0,0,0,-10,-10,37,40,39,0,66,58,0,0,0,0", + "equipment_slot": "5" + }, + { + "requirements": "{1,70}-{16,50}", + "shop_price": "750000", + "examine": "A nice sturdy crystal shield.", + "grand_exchange_price": "749305", + "durability": null, + "name": "Crystal shield 2/10", + "weight": "2", + "archery_ticket_price": "0", + "id": "4233", + "absorb": "6,0,12", + "bonuses": "0,0,0,-10,-10,35,38,37,0,64,56,0,0,0,0", + "equipment_slot": "5" + }, + { + "requirements": "{1,70}-{16,50}", + "shop_price": "750000", + "examine": "A nice sturdy crystal shield.", + "grand_exchange_price": "749305", + "durability": null, + "name": "Crystal shield 1/10", + "weight": "2", + "archery_ticket_price": "0", + "id": "4234", + "absorb": "6,0,12", + "bonuses": "0,0,0,-10,-10,33,36,35,0,62,54,0,0,0,0", + "equipment_slot": "5" + }, + { + "durability": null, + "name": "New crystal shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4235" + }, + { + "requirements": "{4,5}", + "examine": "This bow has been signed by Robin, Master Bowman.", + "durability": null, + "weight": "2", + "attack_speed": "6", + "two_handed": "true", + "weapon_interface": "16", + "render_anim": "2588", + "equipment_slot": "3", + "name": "Signed oak bow", + "archery_ticket_price": "0", + "id": "4236", + "bonuses": "0,0,0,0,14,0,0,0,0,0,0,0,0,0,0" + }, + { + "examine": "It's a bowl of water, with some nettles in it.", + "durability": null, + "name": "Nettle-water", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "4237" + }, + { + "examine": "It's a bowl of (milky) nettle tea.", + "durability": null, + "name": "Nettle tea", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "4239" + }, + { + "examine": "It's a bowl of (milky) nettle tea.", + "durability": null, + "name": "Nettle tea", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "4240" + }, + { + "examine": "(In inventory) A handful of nettles (In ground) I better not get stung/I wouldn't like to get stung/I wish I could sting other people/Dock leaves at the ready/These may hurt/nettles sting my leggies(Draynor Village nettles)", + "durability": null, + "name": "Nettles", + "archery_ticket_price": "0", + "id": "4241" + }, + { + "shop_price": "10", + "examine": "A nice cup of tea.", + "grand_exchange_price": "30", + "durability": null, + "name": "Cup of tea", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "4242" + }, + { + "shop_price": "10", + "examine": "A nice cup of tea.", + "grand_exchange_price": "30", + "durability": null, + "name": "Cup of tea", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "4243" + }, + { + "examine": "A porcelain cup.", + "durability": null, + "name": "Porcelain cup", + "archery_ticket_price": "0", + "id": "4244" + }, + { + "shop_price": "10", + "examine": "A nice cup of tea.", + "grand_exchange_price": "30", + "durability": null, + "name": "Cup of tea", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "4245" + }, + { + "shop_price": "10", + "examine": "A nice cup of tea.", + "grand_exchange_price": "30", + "durability": null, + "name": "Cup of tea", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "4246" + }, + { + "examine": "The Robes of Necrovarus.", + "durability": null, + "name": "Mystical robes", + "weight": "2.3", + "archery_ticket_price": "0", + "id": "4247" + }, + { + "examine": "The Book of Haricanto.", + "durability": null, + "name": "Book of haricanto", + "weight": "2", + "archery_ticket_price": "0", + "id": "4248" + }, + { + "shop_price": "32", + "examine": "A translation manual.", + "durability": null, + "name": "Translation manual", + "weight": "1", + "archery_ticket_price": "0", + "id": "4249" + }, + { + "examine": "The amulet of ghostspeak glows green from the crone's enchantment.", + "durability": null, + "name": "Ghostspeak amulet", + "archery_ticket_price": "0", + "id": "4250", + "equipment_slot": "2" + }, + { + "destroy_message": "The Ectophial will smash if you drop it. Velorina can replace it.", + "examine": "The Ectophial.", + "durability": null, + "name": "Ectophial", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "4251" + }, + { + "destroy_message": "The Ectophial will smash if you drop it. Velorina can replace it.", + "examine": "The Ectophial.", + "durability": null, + "name": "Ectophial", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "4252" + }, + { + "examine": "A small wooden ship. / A small wooden ship with a silk flag.", + "durability": null, + "name": "Model ship", + "archery_ticket_price": "0", + "id": "4253" + }, + { + "examine": "A small wooden ship. / A small wooden ship with a silk flag.", + "durability": null, + "name": "Model ship", + "archery_ticket_price": "0", + "id": "4254" + }, + { + "examine": "A pot of crushed bones.", + "durability": null, + "name": "Bonemeal", + "weight": "1", + "archery_ticket_price": "0", + "id": "4255" + }, + { + "examine": "A pot of crushed small ninja monkey bones.", + "durability": null, + "name": "Bonemeal", + "weight": "1", + "archery_ticket_price": "0", + "id": "4256" + }, + { + "examine": "A pot of crushed wolf bones.", + "durability": null, + "name": "Bonemeal", + "weight": "1", + "archery_ticket_price": "0", + "id": "4257" + }, + { + "examine": "A pot of crushed burnt bones.", + "durability": null, + "name": "Bonemeal", + "weight": "1", + "archery_ticket_price": "0", + "id": "4258" + }, + { + "examine": "A pot of crushed burnt jogre bones.", + "durability": null, + "name": "Bonemeal", + "weight": "1", + "archery_ticket_price": "0", + "id": "4259" + }, + { + "examine": "A pot of crushed monkey bones.", + "durability": null, + "name": "Bonemeal", + "weight": "1", + "archery_ticket_price": "0", + "id": "4260" + }, + { + "examine": "A pot of crushed bat bones.", + "durability": null, + "name": "Bonemeal", + "weight": "1", + "archery_ticket_price": "0", + "id": "4261" + }, + { + "examine": "A pot of crushed big bones.", + "durability": null, + "name": "Bonemeal", + "weight": "1", + "archery_ticket_price": "0", + "id": "4262" + }, + { + "examine": "A pot of crushed jogre bones.", + "durability": null, + "name": "Bonemeal", + "weight": "1", + "archery_ticket_price": "0", + "id": "4263" + }, + { + "examine": "A pot of crushed zogre bones.", + "durability": null, + "name": "Bonemeal", + "weight": "1", + "archery_ticket_price": "0", + "id": "4264" + }, + { + "examine": "A pot of crushed shaikahan bones.", + "durability": null, + "name": "Bonemeal", + "weight": "1", + "archery_ticket_price": "0", + "id": "4265" + }, + { + "examine": "A pot of crushed baby dragon bones.", + "durability": null, + "name": "Bonemeal", + "weight": "1", + "archery_ticket_price": "0", + "id": "4266" + }, + { + "examine": "A pot of crushed wyvern bones.", + "durability": null, + "name": "Bonemeal", + "weight": "1", + "archery_ticket_price": "0", + "id": "4267" + }, + { + "examine": "A pot of crushed dragon bones.", + "durability": null, + "name": "Bonemeal", + "weight": "1", + "archery_ticket_price": "0", + "id": "4268" + }, + { + "examine": "A pot of crushed [type of bones].", + "durability": null, + "name": "Bonemeal", + "weight": "1", + "archery_ticket_price": "0", + "id": "4269" + }, + { + "examine": "A pot of crushed medium ninja monkey bones.", + "durability": null, + "name": "Bonemeal", + "weight": "1", + "archery_ticket_price": "0", + "id": "4270" + }, + { + "examine": "A pot of crushed Dagannoth-king bones.", + "durability": null, + "name": "Bonemeal", + "weight": "1", + "archery_ticket_price": "0", + "id": "4271" + }, + { + "shop_price": "100", + "examine": "A key fashioned from a shard of bone. (Shilo Village)", + "durability": null, + "name": "Bone key", + "archery_ticket_price": "0", + "id": "4272" + }, + { + "examine": "A section from some kind of map.", + "durability": null, + "name": "Map scrap", + "archery_ticket_price": "0", + "id": "4274" + }, + { + "examine": "A section from some kind of map.", + "durability": null, + "name": "Map scrap", + "archery_ticket_price": "0", + "id": "4275" + }, + { + "examine": "A section from some kind of map.", + "durability": null, + "name": "Map scrap", + "archery_ticket_price": "0", + "id": "4276" + }, + { + "examine": "A complete treasure map.", + "durability": null, + "name": "Treasure map", + "archery_ticket_price": "0", + "id": "4277" + }, + { + "examine": "A token with ectoplasm on it.", + "durability": null, + "name": "Ecto-token", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "4278" + }, + { + "examine": "A scroll of paper containing signatures.", + "durability": null, + "name": "Petition form", + "archery_ticket_price": "0", + "id": "4283" + }, + { + "examine": "Before Ectofuntus: It's a bedsheet.After Ectofuntus: It's an ectoplasm-covered bedsheet.", + "durability": null, + "name": "Bedsheet", + "tradeable": "false", + "weight": "1", + "archery_ticket_price": "0", + "id": "4284", + "equipment_slot": "0" + }, + { + "examine": "Before Ectofuntus: It's a bedsheet.After Ectofuntus: It's an ectoplasm-covered bedsheet.", + "durability": null, + "name": "Bedsheet", + "tradeable": "false", + "weight": "1", + "archery_ticket_price": "0", + "id": "4285", + "equipment_slot": "0" + }, + { + "examine": "It's a bucket of ectoplasm.", + "durability": null, + "name": "Bucket of slime", + "weight": "3", + "archery_ticket_price": "0", + "id": "4286" + }, + { + "shop_price": "58", + "ge_buy_limit": "1000", + "examine": "I need to cook this first.", + "grand_exchange_price": "440", + "durability": null, + "name": "Raw beef", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "4287" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "440", + "durability": null, + "name": "Raw beef", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4288" + }, + { + "shop_price": "60", + "ge_buy_limit": "1000", + "examine": "I need to cook this first.", + "grand_exchange_price": "263", + "durability": null, + "name": "Raw chicken", + "tradeable": "true", + "weight": "0.15", + "archery_ticket_price": "0", + "id": "4289" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "263", + "durability": null, + "name": "Raw chicken", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4290" + }, + { + "shop_price": "5", + "ge_buy_limit": "1000", + "examine": "Mmm this looks tasty.", + "grand_exchange_price": "59", + "durability": null, + "name": "Cooked chicken", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "4291" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "59", + "durability": null, + "name": "Cooked chicken", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4292" + }, + { + "shop_price": "5", + "ge_buy_limit": "1000", + "examine": "Mmm this looks tasty.", + "grand_exchange_price": "74", + "durability": null, + "name": "Cooked meat", + "tradeable": "true", + "weight": "0.25", + "archery_ticket_price": "0", + "id": "4293" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "74", + "durability": null, + "name": "Cooked meat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4294" + }, + { + "examine": "A member of the 'Humans Against Monsters' group.", + "durability": null, + "name": "Female h.a.m.", + "archery_ticket_price": "0", + "id": "4295" + }, + { + "examine": "A member of the 'Humans Against Monsters' group.", + "durability": null, + "name": "Male h.a.m.", + "archery_ticket_price": "0", + "id": "4297" + }, + { + "remove_sleeves": "true", + "ge_buy_limit": "100", + "examine": "The label says 'Vivid Crimson', but it looks like pink to me!", + "grand_exchange_price": "19", + "durability": null, + "name": "Ham shirt", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "4298", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "19", + "durability": null, + "name": "Ham shirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4299" + }, + { + "ge_buy_limit": "100", + "examine": "The label says 'Vivid Crimson', but it looks like pink to me!", + "grand_exchange_price": "11", + "durability": null, + "name": "Ham robe", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "4300", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "11", + "durability": null, + "name": "Ham robe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4301" + }, + { + "remove_head": "true", + "ge_buy_limit": "100", + "examine": "Light-weight head protection and eye shield.", + "grand_exchange_price": "400", + "durability": null, + "name": "Ham hood", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4302", + "bonuses": "0,0,0,0,0,0,1,2,0,1,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "400", + "durability": null, + "name": "Ham hood", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4303" + }, + { + "ge_buy_limit": "100", + "examine": "A HAM cape.", + "grand_exchange_price": "25", + "durability": null, + "name": "Ham cloak", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4304", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "25", + "durability": null, + "name": "Ham cloak", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4305" + }, + { + "ge_buy_limit": "100", + "examine": "A badge for the HAM cult.", + "grand_exchange_price": "63", + "durability": null, + "name": "H.a.m logo", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.5", + "id": "4306", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "63", + "durability": null, + "name": "H.a.m logo", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4307" + }, + { + "ge_buy_limit": "10", + "examine": "Gloves worn by the Humans Against Monsters group.", + "grand_exchange_price": "59", + "durability": null, + "name": "Gloves", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4308", + "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0", + "equipment_slot": "9" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "59", + "durability": null, + "name": "Gloves", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4309" + }, + { + "ge_buy_limit": "100", + "examine": "Boots worn by the Humans Against Monsters group.", + "grand_exchange_price": "323", + "durability": null, + "name": "Boots", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4310", + "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", + "equip_audio": "", + "equipment_slot": "10" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "323", + "durability": null, + "name": "Boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4311" + }, + { + "examine": "A book on elven crystal.", + "durability": null, + "name": "Crystal of seren", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4313" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "2342", + "durability": null, + "name": "Team-1 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4315", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2342", + "durability": null, + "name": "Team-1 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4316" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "1145", + "durability": null, + "name": "Team-2 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4317", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1145", + "durability": null, + "name": "Team-2 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4318" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "141", + "durability": null, + "name": "Team-3 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4319", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "141", + "durability": null, + "name": "Team-3 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4320" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "973", + "durability": null, + "name": "Team-4 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4321", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "973", + "durability": null, + "name": "Team-4 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4322" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "1294", + "durability": null, + "name": "Team-5 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4323", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1294", + "durability": null, + "name": "Team-5 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4324" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "124", + "durability": null, + "name": "Team-6 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4325", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "124", + "durability": null, + "name": "Team-6 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4326" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "1264", + "durability": null, + "name": "Team-7 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4327", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1264", + "durability": null, + "name": "Team-7 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4328" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "1824", + "durability": null, + "name": "Team-8 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4329", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1824", + "durability": null, + "name": "Team-8 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4330" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "841", + "durability": null, + "name": "Team-9 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4331", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "841", + "durability": null, + "name": "Team-9 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4332" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "1127", + "durability": null, + "name": "Team-10 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4333", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1127", + "durability": null, + "name": "Team-10 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4334" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "2011", + "durability": null, + "name": "Team-11 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4335", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2011", + "durability": null, + "name": "Team-11 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4336" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "1591", + "durability": null, + "name": "Team-12 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4337", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1591", + "durability": null, + "name": "Team-12 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4338" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "308", + "durability": null, + "name": "Team-13 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4339", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "308", + "durability": null, + "name": "Team-13 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4340" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "1504", + "durability": null, + "name": "Team-14 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4341", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1504", + "durability": null, + "name": "Team-14 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4342" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "1462", + "durability": null, + "name": "Team-15 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4343", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1462", + "durability": null, + "name": "Team-15 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4344" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "313", + "durability": null, + "name": "Team-16 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4345", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "313", + "durability": null, + "name": "Team-16 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4346" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "1231", + "durability": null, + "name": "Team-17 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4347", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1231", + "durability": null, + "name": "Team-17 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4348" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "1678", + "durability": null, + "name": "Team-18 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4349", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1678", + "durability": null, + "name": "Team-18 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4350" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "1041", + "durability": null, + "name": "Team-19 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4351", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1041", + "durability": null, + "name": "Team-19 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4352" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "703", + "durability": null, + "name": "Team-20 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4353", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "703", + "durability": null, + "name": "Team-20 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4354" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "1292", + "durability": null, + "name": "Team-21 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4355", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1292", + "durability": null, + "name": "Team-21 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4356" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "1368", + "durability": null, + "name": "Team-22 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4357", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1368", + "durability": null, + "name": "Team-22 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4358" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "280", + "durability": null, + "name": "Team-23 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4359", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "280", + "durability": null, + "name": "Team-23 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4360" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "1512", + "durability": null, + "name": "Team-24 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4361", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1512", + "durability": null, + "name": "Team-24 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4362" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "1395", + "durability": null, + "name": "Team-25 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4363", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1395", + "durability": null, + "name": "Team-25 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4364" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "191", + "durability": null, + "name": "Team-26 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4365", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "191", + "durability": null, + "name": "Team-26 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4366" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "1420", + "durability": null, + "name": "Team-27 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4367", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1420", + "durability": null, + "name": "Team-27 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4368" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "1920", + "durability": null, + "name": "Team-28 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4369", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1920", + "durability": null, + "name": "Team-28 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4370" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "1175", + "durability": null, + "name": "Team-29 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4371", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1175", + "durability": null, + "name": "Team-29 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4372" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "552", + "durability": null, + "name": "Team-30 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4373", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "552", + "durability": null, + "name": "Team-30 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4374" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "1385", + "durability": null, + "name": "Team-31 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4375", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1385", + "durability": null, + "name": "Team-31 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4376" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "1168", + "durability": null, + "name": "Team-32 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4377", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1168", + "durability": null, + "name": "Team-32 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4378" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "211", + "durability": null, + "name": "Team-33 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4379", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "211", + "durability": null, + "name": "Team-33 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4380" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "1128", + "durability": null, + "name": "Team-34 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4381", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1128", + "durability": null, + "name": "Team-34 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4382" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "1140", + "durability": null, + "name": "Team-35 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4383", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1140", + "durability": null, + "name": "Team-35 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4384" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "84", + "durability": null, + "name": "Team-36 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4385", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "84", + "durability": null, + "name": "Team-36 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4386" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "1010", + "durability": null, + "name": "Team-37 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4387", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1010", + "durability": null, + "name": "Team-37 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4388" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "1833", + "durability": null, + "name": "Team-38 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4389", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1833", + "durability": null, + "name": "Team-38 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4390" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "914", + "durability": null, + "name": "Team-39 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4391", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "914", + "durability": null, + "name": "Team-39 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4392" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "582", + "durability": null, + "name": "Team-40 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4393", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "582", + "durability": null, + "name": "Team-40 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4394" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "1471", + "durability": null, + "name": "Team-41 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4395", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1471", + "durability": null, + "name": "Team-41 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4396" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "1072", + "durability": null, + "name": "Team-42 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4397", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1072", + "durability": null, + "name": "Team-42 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4398" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "298", + "durability": null, + "name": "Team-43 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4399", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "298", + "durability": null, + "name": "Team-43 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4400" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "1268", + "durability": null, + "name": "Team-44 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4401", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1268", + "durability": null, + "name": "Team-44 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4402" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "1371", + "durability": null, + "name": "Team-45 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4403", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1371", + "durability": null, + "name": "Team-45 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4404" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "140", + "durability": null, + "name": "Team-46 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4405", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "140", + "durability": null, + "name": "Team-46 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4406" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "1233", + "durability": null, + "name": "Team-47 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4407", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1233", + "durability": null, + "name": "Team-47 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4408" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "1836", + "durability": null, + "name": "Team-48 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4409", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1836", + "durability": null, + "name": "Team-48 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4410" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "1185", + "durability": null, + "name": "Team-49 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4411", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1185", + "durability": null, + "name": "Team-49 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4412" + }, + { + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Ooohhh look at the pretty colours...", + "grand_exchange_price": "708", + "durability": null, + "name": "Team-50 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4413", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "708", + "durability": null, + "name": "Team-50 cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4414" + }, + { + "examine": "A jungle forester's blunt axe.", + "durability": null, + "name": "Blunt axe", + "weight": "1.3", + "archery_ticket_price": "0", + "id": "4415" + }, + { + "examine": "A strong medicinal brew for heavy chests.", + "durability": null, + "name": "Herbal tincture", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "4416" + }, + { + "ge_buy_limit": "100", + "examine": "A cup of Guthix rest.", + "grand_exchange_price": "223", + "durability": null, + "name": "Guthix rest(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4417" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "223", + "durability": null, + "name": "Guthix rest(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4418" + }, + { + "ge_buy_limit": "100", + "examine": "A cup of Guthix rest.", + "grand_exchange_price": "134", + "durability": null, + "name": "Guthix rest(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4419" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "134", + "durability": null, + "name": "Guthix rest(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4420" + }, + { + "ge_buy_limit": "100", + "examine": "A cup of Guthix rest.", + "grand_exchange_price": "83", + "durability": null, + "name": "Guthix rest(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4421" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "83", + "durability": null, + "name": "Guthix rest(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4422" + }, + { + "ge_buy_limit": "100", + "examine": "A cup of Guthix rest.", + "grand_exchange_price": "44", + "durability": null, + "name": "Guthix rest(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4423" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "44", + "durability": null, + "name": "Guthix rest(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4424" + }, + { + "examine": "A half-filled feather mattress.", + "durability": null, + "name": "Stodgy mattress", + "weight": "10", + "archery_ticket_price": "0", + "id": "4425" + }, + { + "examine": "A comfy-looking feather mattress.", + "durability": null, + "name": "Comfy mattress", + "weight": "15", + "archery_ticket_price": "0", + "id": "4426" + }, + { + "examine": "Looks like a bunch of rust to me.", + "durability": null, + "name": "Iron oxide", + "weight": "1", + "archery_ticket_price": "0", + "id": "4427" + }, + { + "examine": "An animate rock spell is written on this parchment.", + "durability": null, + "name": "Animate rock scroll", + "archery_ticket_price": "0", + "id": "4428" + }, + { + "examine": "The weathervane directions should now work.", + "durability": null, + "name": "Directionals", + "archery_ticket_price": "0", + "id": "4430" + }, + { + "examine": "A fixed weathervane ornament.", + "durability": null, + "name": "Ornament", + "archery_ticket_price": "0", + "id": "4432" + }, + { + "examine": "A fixed weathervane rotating pillar.", + "durability": null, + "name": "Weathervane pillar", + "archery_ticket_price": "0", + "id": "4434" + }, + { + "examine": "Clear skies ahead, with some chance of showers, thunderstorms, ice and hail.", + "durability": null, + "name": "Weather report", + "archery_ticket_price": "0", + "id": "4435" + }, + { + "ge_buy_limit": "100", + "examine": "This is pretty well sealed.", + "grand_exchange_price": "245", + "durability": null, + "name": "Airtight pot", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "4436" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "245", + "durability": null, + "name": "Airtight pot", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4437" + }, + { + "ge_buy_limit": "100", + "examine": "This needs firing, then it should fit on a normal-sized pot.", + "grand_exchange_price": "16", + "durability": null, + "name": "Unfired pot lid", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4438" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "16", + "durability": null, + "name": "Unfired pot lid", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4439" + }, + { + "ge_buy_limit": "100", + "examine": "This should fit on a normal-sized pot.", + "grand_exchange_price": "5", + "durability": null, + "name": "Pot lid", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4440" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "5", + "durability": null, + "name": "Pot lid", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4441" + }, + { + "examine": "An airtight pot with something inside, most likely breathing salts.", + "durability": null, + "name": "Breathing salts", + "archery_ticket_price": "0", + "id": "4442" + }, + { + "examine": "A large cage for transporting chickens.", + "durability": null, + "name": "Chicken cage", + "weight": "1", + "archery_ticket_price": "0", + "id": "4443" + }, + { + "examine": "A jungle forester's super sharp axe.", + "durability": null, + "name": "Sharpened axe", + "weight": "1.3", + "archery_ticket_price": "0", + "id": "4444" + }, + { + "examine": "Some mahogany logs which have been professionally cured.", + "durability": null, + "name": "Red mahogany log", + "weight": "1.3", + "archery_ticket_price": "0", + "id": "4445" + }, + { + "destroy_message": "You can get another key ring from Yanni Salika in Shilo Village.", + "shop_price": "500", + "examine": "I can store my keys here.", + "durability": null, + "name": "Steel key ring", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "4446" + }, + { + "examine": "I wonder what happens if I rub it.", + "durability": null, + "name": "Antique lamp", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "4447" + }, + { + "ge_buy_limit": "100", + "examine": "It's a bowl of hot water.", + "grand_exchange_price": "111", + "durability": null, + "name": "Bowl of hot water", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "4456" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "111", + "durability": null, + "name": "Bowl of hot water", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4457" + }, + { + "ge_buy_limit": "100", + "examine": "A cup of water.", + "grand_exchange_price": "36", + "durability": null, + "name": "Cup of water", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4458" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "36", + "durability": null, + "name": "Cup of water", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4459" + }, + { + "ge_buy_limit": "100", + "examine": "It's hot!", + "grand_exchange_price": "102", + "durability": null, + "name": "Cup of hot water", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4460" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "102", + "durability": null, + "name": "Cup of hot water", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4461" + }, + { + "examine": "A ruined herb tea.", + "durability": null, + "name": "Ruined herb tea", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4462" + }, + { + "durability": null, + "name": "Ruined herb tea", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4463" + }, + { + "ge_buy_limit": "100", + "examine": "See article", + "grand_exchange_price": "13", + "durability": null, + "name": "Herb tea mix", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4464" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "13", + "durability": null, + "name": "Herb tea mix", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4465" + }, + { + "ge_buy_limit": "100", + "examine": "See article", + "grand_exchange_price": "13", + "durability": null, + "name": "Herb tea mix", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4466" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "13", + "durability": null, + "name": "Herb tea mix", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4467" + }, + { + "ge_buy_limit": "100", + "examine": "See article", + "grand_exchange_price": "19", + "durability": null, + "name": "Herb tea mix", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4468" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "19", + "durability": null, + "name": "Herb tea mix", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4469" + }, + { + "ge_buy_limit": "100", + "examine": "See article", + "grand_exchange_price": "19", + "durability": null, + "name": "Herb tea mix", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4470" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "19", + "durability": null, + "name": "Herb tea mix", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4471" + }, + { + "ge_buy_limit": "100", + "examine": "See article", + "grand_exchange_price": "17", + "durability": null, + "name": "Herb tea mix", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4472" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "17", + "durability": null, + "name": "Herb tea mix", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4473" + }, + { + "ge_buy_limit": "100", + "examine": "See article", + "grand_exchange_price": "18", + "durability": null, + "name": "Herb tea mix", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4474" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "18", + "durability": null, + "name": "Herb tea mix", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4475" + }, + { + "ge_buy_limit": "100", + "examine": "See article", + "grand_exchange_price": "18", + "durability": null, + "name": "Herb tea mix", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4476" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "18", + "durability": null, + "name": "Herb tea mix", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4477" + }, + { + "ge_buy_limit": "100", + "examine": "See article", + "grand_exchange_price": "46", + "durability": null, + "name": "Herb tea mix", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4478" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "46", + "durability": null, + "name": "Herb tea mix", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4479" + }, + { + "ge_buy_limit": "100", + "examine": "See article", + "grand_exchange_price": "41", + "durability": null, + "name": "Herb tea mix", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4480" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "41", + "durability": null, + "name": "Herb tea mix", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4481" + }, + { + "ge_buy_limit": "100", + "examine": "See article", + "grand_exchange_price": "43", + "durability": null, + "name": "Herb tea mix", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4482" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "43", + "durability": null, + "name": "Herb tea mix", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4483" + }, + { + "shop_price": "160", + "examine": "The strange characters supposedly grant Svidi safe passage into Rellekka.", + "durability": null, + "name": "Safety guarantee", + "archery_ticket_price": "0", + "id": "4484" + }, + { + "examine": "This fruit is known as White Pearl. Should taste good.", + "durability": null, + "name": "White pearl", + "weight": "1", + "archery_ticket_price": "0", + "id": "4485" + }, + { + "examine": "You can grow this seed even in cold mountain ranges!", + "durability": null, + "name": "White pearl seed", + "archery_ticket_price": "0", + "id": "4486" + }, + { + "examine": "It's a piece of the Ancient Rock of the mountain people. It's still just a stone.", + "durability": null, + "name": "Half a rock", + "weight": "1", + "archery_ticket_price": "0", + "id": "4487" + }, + { + "examine": "The corpse of a woman who died long ago.", + "durability": null, + "name": "Corpse of woman", + "weight": "1", + "archery_ticket_price": "0", + "id": "4488" + }, + { + "examine": "This used to belong to Asleif, daughter of the mountain camp chieftain.", + "durability": null, + "name": "Asleif's necklace", + "archery_ticket_price": "0", + "id": "4489" + }, + { + "examine": "Marginally better than egg on your face.", + "durability": null, + "name": "Mud", + "archery_ticket_price": "0", + "id": "4490" + }, + { + "examine": "A muddy rock.", + "durability": null, + "name": "Muddy rock", + "weight": "1", + "archery_ticket_price": "0", + "id": "4492" + }, + { + "examine": "It's just a long stick, really.", + "durability": null, + "name": "Pole", + "archery_ticket_price": "0", + "id": "4494" + }, + { + "examine": "It's just a long stick, really.", + "durability": null, + "name": "Pole", + "archery_ticket_price": "0", + "id": "4495" + }, + { + "examine": "Splintered into pieces, it has become completely useless to you.", + "durability": null, + "name": "Broken pole", + "archery_ticket_price": "0", + "id": "4496" + }, + { + "shop_price": "18", + "examine": "A coil of rope.", + "grand_exchange_price": "101", + "durability": null, + "name": "Rope", + "tradeable": "true", + "weight": "1.3", + "archery_ticket_price": "0", + "id": "4498", + "equipment_slot": "3" + }, + { + "durability": null, + "name": "Rope", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4499" + }, + { + "examine": "It's just a long stick, really.", + "durability": null, + "name": "Pole", + "archery_ticket_price": "0", + "id": "4500", + "equipment_slot": "3" + }, + { + "examine": "It's just a long stick, really.", + "durability": null, + "name": "Pole", + "archery_ticket_price": "0", + "id": "4501", + "equipment_slot": "3" + }, + { + "remove_head": "true", + "shop_price": "3000", + "examine": "Quite ferocious looking.", + "durability": null, + "destroy": "true", + "weight": "0.4", + "equipment_slot": "0", + "destroy_message": "Hamal, the Chieftain of the Mountain Camp, can replace this.", + "name": "Bearhead", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "4502", + "bonuses": "0,0,0,-3,-3,12,14,10,7,9,0,0,0,0,0" + }, + { + "requirements": "{0,20}", + "shop_price": "50", + "turn90cw_anim": "821", + "examine": "A very decorative sword.", + "walk_anim": "819", + "durability": null, + "weight": "1", + "turn90ccw_anim": "822", + "weapon_interface": "6", + "turn180_anim": "820", + "equip_audio": "2248", + "render_anim": "1", + "defence_anim": "397", + "castle_wars_ticket_price": "50", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "stand_anim": "808", + "name": "Decorative sword", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "4503", + "stand_turn_anim": "823", + "bonuses": "15,20,-2,0,0,0,3,2,0,0,0,22,0,0,0" + }, + { + "remove_sleeves": "true", + "requirements": "{1,20}", + "durability": null, + "name": "Decorative armour", + "archery_ticket_price": "0", + "id": "4504", + "bonuses": "0,0,0,-30,-10,46,44,38,-6,44,20,0,0,0,0", + "castle_wars_ticket_price": "80", + "equipment_slot": "4" + }, + { + "requirements": "{1,20}", + "durability": null, + "name": "Decorative armour", + "archery_ticket_price": "0", + "id": "4505", + "bonuses": "0,0,0,-21,-7,24,22,20,-4,22,5,0,0,0,0", + "castle_wars_ticket_price": "60", + "equipment_slot": "7" + }, + { + "remove_head": "true", + "requirements": "{1,20}", + "shop_price": "40", + "examine": "A very decorative helm.", + "durability": null, + "name": "Decorative helm", + "weight": "1", + "archery_ticket_price": "0", + "id": "4506", + "bonuses": "0,0,0,-3,-1,10,11,9,-1,10,5,0,0,0,0", + "castle_wars_ticket_price": "40", + "equipment_slot": "0" + }, + { + "requirements": "{1,20}", + "shop_price": "60", + "examine": "A very decorative shield.", + "durability": null, + "name": "Decorative shield", + "archery_ticket_price": "0", + "id": "4507", + "bonuses": "0,0,0,-8,-2,18,22,20,-1,20,20,0,0,0,0", + "castle_wars_ticket_price": "60", + "equipment_slot": "5" + }, + { + "requirements": "{0,30}", + "shop_price": "50", + "turn90cw_anim": "821", + "examine": "A very decorative sword.", + "walk_anim": "819", + "durability": null, + "weight": "1", + "turn90ccw_anim": "822", + "weapon_interface": "6", + "turn180_anim": "820", + "equip_audio": "2248", + "render_anim": "1", + "defence_anim": "397", + "castle_wars_ticket_price": "500", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "stand_anim": "808", + "name": "Decorative sword", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "4508", + "stand_turn_anim": "823", + "bonuses": "20,29,-2,0,0,0,3,2,0,0,0,31,0,0,0" + }, + { + "remove_sleeves": "true", + "requirements": "{1,30}", + "durability": null, + "name": "Decorative armour", + "archery_ticket_price": "0", + "id": "4509", + "bonuses": "0,0,0,-30,-10,65,63,55,-6,63,30,0,0,0,0", + "castle_wars_ticket_price": "800", + "equipment_slot": "4" + }, + { + "requirements": "{1,30}", + "durability": null, + "name": "Decorative armour", + "archery_ticket_price": "0", + "id": "4510", + "bonuses": "0,0,0,-21,-7,33,31,29,-4,31,10,0,0,0,0", + "castle_wars_ticket_price": "600", + "equipment_slot": "7" + }, + { + "remove_head": "true", + "requirements": "{1,30}", + "shop_price": "40", + "examine": "A very decorative helm.", + "durability": null, + "name": "Decorative helm", + "weight": "1", + "archery_ticket_price": "0", + "id": "4511", + "bonuses": "0,0,0,-3,-1,14,15,13,-1,14,6,0,0,0,0", + "castle_wars_ticket_price": "400", + "equipment_slot": "0" + }, + { + "requirements": "{1,30}", + "shop_price": "60", + "examine": "A very decorative shield.", + "durability": null, + "name": "Decorative shield", + "archery_ticket_price": "0", + "id": "4512", + "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,30,0,0,0,0", + "castle_wars_ticket_price": "600", + "equipment_slot": "5" + }, + { + "remove_head": "true", + "durability": null, + "name": "Castlewars hood", + "archery_ticket_price": "0", + "id": "4513", + "bonuses": "0,0,0,0,0,0,1,2,0,1,0,0,0,0,0", + "castle_wars_ticket_price": "10", + "equipment_slot": "0" + }, + { + "durability": null, + "name": "Castlewars cloak", + "archery_ticket_price": "0", + "id": "4514", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "castle_wars_ticket_price": "10", + "equipment_slot": "1" + }, + { + "remove_head": "true", + "durability": null, + "name": "Castlewars hood", + "archery_ticket_price": "0", + "id": "4515", + "bonuses": "0,0,0,0,0,0,1,2,0,1,0,0,0,0,0", + "castle_wars_ticket_price": "10", + "equipment_slot": "0" + }, + { + "durability": null, + "name": "Castlewars cloak", + "archery_ticket_price": "0", + "id": "4516", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "castle_wars_ticket_price": "10", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "1000", + "examine": "This could feed a family of gnomes for a week!", + "grand_exchange_price": "970", + "durability": null, + "name": "Giant frog legs", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4517" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "970", + "durability": null, + "name": "Giant frog legs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4518" + }, + { + "requirements": "{12,11}", + "shop_price": "10", + "ge_buy_limit": "100", + "examine": "Empty: An oil lamp with no oil in it.Filled: Not the genie sort.", + "grand_exchange_price": "1575", + "durability": null, + "name": "Oil lamp", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4522" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1575", + "durability": null, + "name": "Oil lamp", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4523" + }, + { + "shop_price": "10", + "examine": "Empty: An oil lamp with no oil in it.Filled: Not the genie sort.", + "grand_exchange_price": "2", + "durability": null, + "name": "Oil lamp", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4524" + }, + { + "requirements": "{12,11}", + "shop_price": "10", + "ge_buy_limit": "100", + "examine": "Empty: An oil lamp with no oil in it.Filled: Not the genie sort.", + "grand_exchange_price": "2", + "durability": null, + "name": "Oil lamp", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4525" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2", + "durability": null, + "name": "Oil lamp", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4526" + }, + { + "requirements": "{4,11}", + "ge_buy_limit": "100", + "examine": "Lit: A flickering candle in a glass cage.Unlit: a candle in a glass cage.Without candle: Put a candle in to complete it.", + "grand_exchange_price": "39", + "durability": null, + "name": "Candle lantern", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "4527" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "39", + "durability": null, + "name": "Candle lantern", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4528" + }, + { + "requirements": "{4,11}", + "ge_buy_limit": "100", + "examine": "Lit: A flickering candle in a glass cage.Unlit: a candle in a glass cage.Without candle: Put a candle in to complete it.", + "grand_exchange_price": "431", + "durability": null, + "name": "Candle lantern", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "4529" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "431", + "durability": null, + "name": "Candle lantern", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4530" + }, + { + "examine": "Lit: A flickering candle in a glass cage.Unlit: a candle in a glass cage.Without candle: Put a candle in to complete it.", + "grand_exchange_price": "1", + "durability": null, + "name": "Candle lantern", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "4531" + }, + { + "requirements": "{4,11}", + "examine": "Lit: A flickering candle in a glass cage.Unlit: a candle in a glass cage.Without candle: Put a candle in to complete it.", + "grand_exchange_price": "1", + "durability": null, + "name": "Candle lantern", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "4532" + }, + { + "durability": null, + "name": "Candle lantern", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4533" + }, + { + "examine": "Lit: A flickering candle in a glass cage.Unlit: a candle in a glass cage.Without candle: Put a candle in to complete it.", + "grand_exchange_price": "1", + "durability": null, + "name": "Candle lantern", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "4534" + }, + { + "requirements": "{11,26}", + "ge_buy_limit": "100", + "examine": "Unfuelled: Put oil in to complete it. Unlit: An unlit oil lantern. Lit: It lights your way through the dark places of the earth.", + "grand_exchange_price": "12", + "durability": null, + "name": "Oil lantern", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "4535" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "12", + "durability": null, + "name": "Oil lantern", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4536" + }, + { + "requirements": "{11,26}", + "ge_buy_limit": "100", + "examine": "Unfuelled: Put oil in to complete it. Unlit: An unlit oil lantern. Lit: It lights your way through the dark places of the earth.", + "grand_exchange_price": "218", + "durability": null, + "name": "Oil lantern", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "4537" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "218", + "durability": null, + "name": "Oil lantern", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4538" + }, + { + "examine": "Unfuelled: Put oil in to complete it. Unlit: An unlit oil lantern. Lit: It lights your way through the dark places of the earth.", + "grand_exchange_price": "198", + "durability": null, + "name": "Oil lantern", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "4539" + }, + { + "shop_price": "43", + "ge_buy_limit": "100", + "examine": "Add the glass to complete.", + "grand_exchange_price": "8", + "durability": null, + "name": "Oil lantern frame", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4540" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "8", + "durability": null, + "name": "Oil lantern frame", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4541" + }, + { + "shop_price": "88", + "ge_buy_limit": "100", + "examine": "A roughly circular disc of glass.", + "grand_exchange_price": "1", + "durability": null, + "name": "Lantern lens", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4542" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1", + "durability": null, + "name": "Lantern lens", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4543" + }, + { + "shop_price": "400", + "ge_buy_limit": "100", + "examine": "You need to add a lens before you can use it.", + "grand_exchange_price": "88", + "durability": null, + "name": "Bullseye lantern", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "4544" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "88", + "durability": null, + "name": "Bullseye lantern", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4545" + }, + { + "requirements": "{11,49}", + "shop_price": "400", + "ge_buy_limit": "100", + "examine": "You need to add lamp oil before you can use it.", + "grand_exchange_price": "158", + "durability": null, + "name": "Bullseye lantern", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "4546" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "158", + "durability": null, + "name": "Bullseye lantern", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4547" + }, + { + "requirements": "{11,49}", + "shop_price": "400", + "ge_buy_limit": "100", + "examine": "A sturdy steel lantern.", + "grand_exchange_price": "1345", + "durability": null, + "name": "Bullseye lantern", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "4548" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1345", + "durability": null, + "name": "Bullseye lantern", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4549" + }, + { + "shop_price": "400", + "examine": "A sturdy steel lantern casting a bright beam.", + "grand_exchange_price": "1235", + "durability": null, + "name": "Bullseye lantern", + "tradeable": "false", + "weight": "1", + "archery_ticket_price": "0", + "id": "4550" + }, + { + "remove_head": "true", + "requirements": "{1,5}", + "shop_price": "650", + "ge_buy_limit": "100", + "examine": "You don't want to wear it inside-out.", + "durability": null, + "weight": "2.2", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "774", + "name": "Spiny helmet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4551", + "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "774", + "durability": null, + "name": "Spiny helmet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4552" + }, + { + "examine": "Remember to brush after eating!", + "durability": null, + "name": "Blue sweets", + "archery_ticket_price": "0", + "id": "4558" + }, + { + "examine": "Remember to brush after eating!", + "durability": null, + "name": "Deep blue sweets", + "archery_ticket_price": "0", + "id": "4559" + }, + { + "examine": "Remember to brush after eating!", + "durability": null, + "name": "White sweets", + "archery_ticket_price": "0", + "id": "4560" + }, + { + "examine": "Remember to brush after eating!", + "grand_exchange_price": "10037", + "durability": null, + "name": "Purple sweets", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4561" + }, + { + "examine": "Remember to brush after eating!", + "durability": null, + "name": "Red sweets", + "archery_ticket_price": "0", + "id": "4562" + }, + { + "examine": "Remember to brush after eating!", + "durability": null, + "name": "Green sweets", + "archery_ticket_price": "0", + "id": "4563" + }, + { + "examine": "Remember to brush after eating!", + "durability": null, + "name": "Pink sweets", + "archery_ticket_price": "0", + "id": "4564" + }, + { + "bankable": "true", + "turn90cw_anim": "821", + "examine": "Hand them out to spread the Easter happiness.", + "walk_anim": "1836", + "durability": null, + "destroy": "true", + "turn90ccw_anim": "822", + "weapon_interface": "12", + "turn180_anim": "820", + "render_anim": "594", + "equipment_slot": "3", + "fun_weapon": "true", + "stand_anim": "1837", + "name": "Basket of eggs", + "tradeable": "false", + "run_anim": "1836", + "archery_ticket_price": "0", + "id": "4565", + "stand_turn_anim": "823" + }, + { + "examine": "Perhaps not the most powerful weapon in 2009Scape.", + "durability": null, + "weight": "0.4", + "attack_speed": "4", + "weapon_interface": "12", + "equip_audio": "2238", + "defence_anim": "1834", + "equipment_slot": "3", + "attack_anims": "1833,1833,1833,1833", + "fun_weapon": "true", + "attack_audios": "2257,2257,2257", + "name": "Rubber chicken", + "archery_ticket_price": "0", + "id": "4566", + "bonuses": "-100,-100,-50,0,0,0,0,0,0,0,0,-10,0,0,0" + }, + { + "remove_head": "true", + "examine": "Made of gold and white gold.", + "durability": null, + "name": "Gold helmet", + "weight": "31.7", + "archery_ticket_price": "0", + "id": "4567", + "bonuses": "0,0,0,0,0,0,10,20,0,10,6,0,0,0,0", + "equipment_slot": "0" + }, + { + "examine": "This book is almost falling apart, you'll have to handle it quite carefully.", + "durability": null, + "name": "Dwarven lore", + "archery_ticket_price": "0", + "id": "4568" + }, + { + "examine": "A missing page from Rolad's book! It seems to be the first one.", + "durability": null, + "name": "Book page 1", + "archery_ticket_price": "0", + "id": "4569" + }, + { + "examine": "A missing page from Rolad's book! It seems to be the second one.", + "durability": null, + "name": "Book page 2", + "archery_ticket_price": "0", + "id": "4570" + }, + { + "examine": "A missing page from Rolad's book! It seems to be the third one.", + "durability": null, + "name": "Book page 3", + "archery_ticket_price": "0", + "id": "4571" + }, + { + "examine": "A collection of missing pages from Rolad's book!", + "durability": null, + "name": "Pages", + "archery_ticket_price": "0", + "id": "4572" + }, + { + "examine": "A collection of missing pages from Rolad's book!", + "durability": null, + "name": "Pages", + "archery_ticket_price": "0", + "id": "4573" + }, + { + "examine": "These are the base schematics of a dwarven multicannon.", + "durability": null, + "name": "Base schematics", + "archery_ticket_price": "0", + "id": "4574" + }, + { + "requirements": "{0,10}", + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A black tipped spear.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1206", + "equip_audio": "2247", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "536", + "stand_anim": "813", + "tradeable": "true", + "name": "Black spear", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "4580", + "stand_turn_anim": "1209", + "bonuses": "15,15,15,0,0,1,1,0,0,0,0,16,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "536", + "durability": null, + "name": "Black spear", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4581" + }, + { + "requirements": "{0,10}", + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A black tipped spear.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1206", + "equip_audio": "2247", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "2808", + "stand_anim": "813", + "tradeable": "true", + "name": "Black spear(p)", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "4582", + "stand_turn_anim": "1209", + "bonuses": "15,15,15,0,0,1,1,0,0,0,0,16,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2808", + "durability": null, + "name": "Black spear(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4583" + }, + { + "requirements": "{0,10}", + "turn90cw_anim": "1207", + "examine": "A Karambwan poisoned black tipped spear.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1206", + "equip_audio": "2247", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "309", + "stand_anim": "813", + "name": "Black spear(kp)", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "4584", + "stand_turn_anim": "1209", + "bonuses": "15,15,15,0,0,1,1,0,0,0,0,16,0,0,0" + }, + { + "requirements": "{1,60}", + "ge_buy_limit": "10", + "examine": "This looks pretty heavy.", + "durability": null, + "rare_item": "true", + "weight": "9", + "absorb": "3,0,6", + "equipment_slot": "7", + "lendable": "true", + "grand_exchange_price": "161000", + "name": "Dragon plateskirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4585", + "bonuses": "0,0,0,-21,-7,68,66,63,-4,65,20,0,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "161000", + "durability": null, + "name": "Dragon plateskirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4586" + }, + { + "ge_buy_limit": "10", + "turn90cw_anim": "821", + "examine": "A vicious, curved sword.", + "walk_anim": "819", + "has_special": "true", + "turn90ccw_anim": "822", + "attack_speed": "4", + "turn180_anim": "820", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "grand_exchange_price": "65400", + "stand_anim": "808", + "tradeable": "true", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "4587", + "stand_turn_anim": "823", + "bonuses": "8,67,-2,0,0,0,1,0,0,0,0,66,0,0,0", + "requirements": "{0,60}", + "shop_price": "100000", + "durability": null, + "weight": "1.8", + "weapon_interface": "6", + "equip_audio": "2248", + "render_anim": "1", + "lendable": "true", + "attack_audios": "2500,0,2517,0", + "name": "Dragon scimitar" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "65400", + "durability": null, + "name": "Dragon scimitar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4588" + }, + { + "examine": "Keys to the Mayor's house. (The Feud)", + "durability": null, + "name": "Keys", + "archery_ticket_price": "0", + "id": "4589" + }, + { + "examine": "The Mayor of Pollnivneach's wife's jewels.", + "durability": null, + "name": "Jewels", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "4590" + }, + { + "shop_price": "1", + "examine": "Wear it on your head.", + "durability": null, + "name": "Karidian headpiece", + "archery_ticket_price": "0", + "id": "4591" + }, + { + "shop_price": "1", + "examine": "Makes me itch.", + "durability": null, + "name": "Fake beard", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "4593" + }, + { + "shop_price": "160", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Note", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4597" + }, + { + "shop_price": "160", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Note", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4598" + }, + { + "shop_price": "1", + "examine": "A handy little club made out of oak.", + "durability": null, + "weight": "1.8", + "attack_speed": "4", + "weapon_interface": "10", + "defence_anim": "425", + "equipment_slot": "3", + "attack_anims": "395,395,395,395", + "name": "Oak-blackjack", + "archery_ticket_price": "0", + "id": "4599", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,2,0,0,0" + }, + { + "shop_price": "600", + "ge_buy_limit": "100", + "examine": "A handy little club made out of willow.", + "durability": null, + "weight": "1", + "attack_speed": "4", + "weapon_interface": "10", + "defence_anim": "425", + "equipment_slot": "3", + "attack_anims": "395,395,395,395", + "grand_exchange_price": "321", + "name": "Willow-blackjack", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4600", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,8,0,0,0" + }, + { + "examine": "Dung of the Camelus Horribleus variety.", + "durability": null, + "name": "Ugthanki dung", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4601" + }, + { + "examine": "Dung of the Camelus Horribleus variety.", + "durability": null, + "name": "Ugthanki dung", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "4602" + }, + { + "shop_price": "2", + "examine": "A receipt for one 'Camelus Horribleus", + "durability": null, + "name": "Receipt", + "archery_ticket_price": "0", + "id": "4603" + }, + { + "examine": "A red viscous liquid in a vial.", + "durability": null, + "name": "Hag's poison", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "4604" + }, + { + "examine": "Makes a hissing sound.", + "durability": null, + "name": "Snake charm", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "4605", + "equipment_slot": "3" + }, + { + "examine": "This is used to hold snakes.", + "durability": null, + "name": "Snake basket", + "archery_ticket_price": "0", + "id": "4606" + }, + { + "examine": "This basket contains a snake.", + "durability": null, + "name": "Snake basket full", + "weight": "1", + "archery_ticket_price": "0", + "id": "4607" + }, + { + "shop_price": "5", + "ge_buy_limit": "1000", + "examine": "A meaty and very hot kebab.", + "grand_exchange_price": "403", + "durability": null, + "name": "Super kebab", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "4608" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "403", + "durability": null, + "name": "Super kebab", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4609" + }, + { + "examine": "The bottle feels warm.", + "durability": null, + "name": "Red hot sauce", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "4610" + }, + { + "remove_head": "true", + "examine": "A disguise suitable for the desert.", + "durability": null, + "name": "Desert disguise", + "archery_ticket_price": "0", + "id": "4611", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "durability": null, + "name": "Willow-blackjack", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4612" + }, + { + "shop_price": "75", + "examine": "It has a picture of a dragon on it.", + "durability": null, + "name": "Spinning plate", + "archery_ticket_price": "0", + "id": "4613" + }, + { + "examine": "Alas...", + "durability": null, + "name": "Broken plate", + "archery_ticket_price": "0", + "id": "4614" + }, + { + "examine": "An archaeologist's notes.", + "durability": null, + "name": "Varmen's notes", + "archery_ticket_price": "0", + "id": "4616" + }, + { + "examine": "The museum curator's key (The Golem).", + "durability": null, + "name": "Display cabinet key", + "archery_ticket_price": "0", + "id": "4617" + }, + { + "examine": "It's pretty, but you wish you knew what it was.", + "durability": null, + "name": "Strange implement", + "archery_ticket_price": "0", + "id": "4619" + }, + { + "examine": "It looks horrible.", + "durability": null, + "name": "Black mushroom", + "weight": "1", + "archery_ticket_price": "0", + "id": "4620" + }, + { + "examine": "A long feather patterned like a flame.", + "durability": null, + "name": "Phoenix feather", + "archery_ticket_price": "0", + "id": "4621" + }, + { + "examine": "Black ink made out of mushrooms.", + "durability": null, + "name": "Black mushroom ink", + "weight": "1", + "archery_ticket_price": "0", + "id": "4622" + }, + { + "examine": "A phoenix feather dipped in ink.", + "durability": null, + "name": "Phoenix quill pen", + "archery_ticket_price": "0", + "id": "4623" + }, + { + "examine": "It reads 'YOUR TASK IS DONE'.", + "durability": null, + "name": "Golem program", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "4624" + }, + { + "shop_price": "650", + "ge_buy_limit": "100", + "examine": "A cheeky little lager from the Bandit Camp.", + "grand_exchange_price": "1133", + "durability": null, + "name": "Bandit's brew", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4627" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1133", + "durability": null, + "name": "Bandit's brew", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4628" + }, + { + "examine": "A copy of the engravings found on a mysterious stone tablet.", + "durability": null, + "name": "Etchings", + "archery_ticket_price": "0", + "id": "4654" + }, + { + "examine": "A rough translation made from archaeological etchings.", + "durability": null, + "name": "Translation", + "weight": "1", + "archery_ticket_price": "0", + "id": "4655" + }, + { + "examine": "This key is unusally warm to the touch.", + "durability": null, + "name": "Warm key", + "archery_ticket_price": "0", + "id": "4656" + }, + { + "examine": "A ring that allows you to see things that are normally invisible.", + "durability": null, + "name": "Ring of visibility", + "archery_ticket_price": "0", + "id": "4657", + "equipment_slot": "12" + }, + { + "examine": "A silver pot made by Ruantun.", + "durability": null, + "name": "Silver pot", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "4658" + }, + { + "examine": "A silver pot made by Ruantun and blessed on Entrana.", + "durability": null, + "name": "Blessed pot", + "weight": "2", + "archery_ticket_price": "0", + "id": "4659" + }, + { + "examine": "A silver pot made by Ruantun filled with your blood.", + "durability": null, + "name": "Silver pot", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "4660" + }, + { + "examine": "A blessed silver pot made by Ruantun filled with your blood.", + "durability": null, + "name": "Blessed pot", + "weight": "2", + "archery_ticket_price": "0", + "id": "4661" + }, + { + "examine": "A silver pot made by Ruantun filled with blood and garlic.", + "durability": null, + "name": "Silver pot", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "4662" + }, + { + "examine": "A blessed silver pot filled with blood and garlic.", + "durability": null, + "name": "Blessed pot", + "weight": "2", + "archery_ticket_price": "0", + "id": "4663" + }, + { + "examine": "A silver pot made by Ruantun filled with blood and spices.", + "durability": null, + "name": "Silver pot", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "4664" + }, + { + "examine": "A blessed silver pot filled with blood and spices.", + "durability": null, + "name": "Blessed pot", + "weight": "2", + "archery_ticket_price": "0", + "id": "4665" + }, + { + "examine": "A silver pot made by Ruantun filled with blood, garlic and spices.", + "durability": null, + "name": "Silver pot", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "4666" + }, + { + "examine": "A blessed silver pot filled with blood, garlic and spices.", + "durability": null, + "name": "Blessed pot", + "weight": "2", + "archery_ticket_price": "0", + "id": "4667" + }, + { + "examine": "Finely ground garlic powder.", + "durability": null, + "name": "Garlic powder", + "archery_ticket_price": "0", + "id": "4668" + }, + { + "examine": "The Diamond of Blood.", + "durability": null, + "name": "Blood diamond", + "archery_ticket_price": "0", + "id": "4670" + }, + { + "examine": "The Diamond of Ice.", + "durability": null, + "name": "Ice diamond", + "archery_ticket_price": "0", + "id": "4671" + }, + { + "examine": "The Diamond of Smoke.", + "durability": null, + "name": "Smoke diamond", + "weight": "1", + "archery_ticket_price": "0", + "id": "4672" + }, + { + "examine": "The Diamond of Shadow.", + "durability": null, + "name": "Shadow diamond", + "weight": "1", + "archery_ticket_price": "0", + "id": "4673" + }, + { + "examine": "An old and strangely shaped metal cross.", + "durability": null, + "name": "Gilded cross", + "archery_ticket_price": "0", + "id": "4674" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A magical staff of ancient origin...", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "4", + "turn180_anim": "1206", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "grand_exchange_price": "59300", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "4675", + "stand_turn_anim": "1209", + "bonuses": "10,-1,40,15,0,2,3,1,15,0,0,50,-1,0,0", + "requirements": "{0,50}-{6,50}", + "shop_price": "80000", + "durability": null, + "weight": "2.25", + "weapon_interface": "1", + "equip_audio": "2247", + "render_anim": "28", + "lendable": "true", + "attack_audios": "2555,0,0,0", + "name": "Ancient staff" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "59300", + "durability": null, + "name": "Ancient staff", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4676" + }, + { + "examine": "It's an amulet of cat speak. It makes vague purring noises.", + "durability": null, + "name": "Catspeak amulet", + "weight": "1.3", + "archery_ticket_price": "0", + "id": "4677", + "equipment_slot": "2" + }, + { + "examine": "Varies. See Types", + "durability": null, + "name": "Canopic jar", + "weight": "4", + "archery_ticket_price": "0", + "id": "4678" + }, + { + "examine": "Varies. See Types", + "durability": null, + "name": "Canopic jar", + "weight": "4", + "archery_ticket_price": "0", + "id": "4679" + }, + { + "examine": "Varies. See Types", + "durability": null, + "name": "Canopic jar", + "weight": "4", + "archery_ticket_price": "0", + "id": "4680" + }, + { + "examine": "Varies. See Types", + "durability": null, + "name": "Canopic jar", + "weight": "4", + "archery_ticket_price": "0", + "id": "4681" + }, + { + "shop_price": "300", + "examine": "A blessed holy symbol of Saradomin.", + "grand_exchange_price": "112", + "durability": null, + "name": "Holy symbol", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4682", + "bonuses": "0,0,0,0,0,2,2,2,2,2,3,0,0,8,0" + }, + { + "shop_price": "135", + "examine": "An unholy symbol of Zamorak.", + "grand_exchange_price": "52", + "durability": null, + "name": "Unholy symbol", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4683", + "bonuses": "2,2,2,2,2,0,0,0,0,0,0,0,0,8,0" + }, + { + "shop_price": "30", + "examine": "One sheet of mummy wrap.", + "durability": null, + "name": "Linen", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "4684" + }, + { + "examine": "Little book of embalming by Bod E. Wrapper.", + "durability": null, + "name": "Embalming manual", + "archery_ticket_price": "0", + "id": "4686" + }, + { + "examine": "It's a bucket of sap.", + "durability": null, + "name": "Bucket of sap", + "weight": "2", + "archery_ticket_price": "0", + "id": "4687" + }, + { + "examine": "A little heap of salt.", + "durability": null, + "name": "Pile of salt", + "archery_ticket_price": "0", + "id": "4689" + }, + { + "examine": "Miniature golden statue of a sphinx.", + "durability": null, + "name": "Sphinx's token", + "archery_ticket_price": "0", + "id": "4691" + }, + { + "shop_price": "130000", + "examine": "A very delicate sheet of gold.", + "grand_exchange_price": "132580", + "durability": null, + "name": "Gold leaf", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "4692" + }, + { + "examine": "It's a bucket of salty water.", + "durability": null, + "name": "Full bucket", + "archery_ticket_price": "0", + "id": "4693" + }, + { + "shop_price": "11151", + "ge_buy_limit": "25000", + "examine": "A combined Water and Fire Rune.", + "grand_exchange_price": "48", + "durability": null, + "name": "Steam rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4694" + }, + { + "shop_price": "11151", + "ge_buy_limit": "25000", + "examine": "A combined air and water rune.", + "grand_exchange_price": "249", + "durability": null, + "name": "Mist rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4695" + }, + { + "shop_price": "11151", + "ge_buy_limit": "25000", + "examine": "A combined Air and Earth Rune.", + "grand_exchange_price": "20", + "durability": null, + "name": "Dust rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4696" + }, + { + "shop_price": "11151", + "ge_buy_limit": "25000", + "examine": "A combined Air and Fire Rune.", + "grand_exchange_price": "148", + "durability": null, + "name": "Smoke rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4697" + }, + { + "shop_price": "11151", + "ge_buy_limit": "25000", + "examine": "A combined Earth and Water rune.", + "grand_exchange_price": "657", + "durability": null, + "name": "Mud rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4698" + }, + { + "shop_price": "11151", + "ge_buy_limit": "25000", + "examine": "A combined earth and fire rune.", + "grand_exchange_price": "49", + "durability": null, + "name": "Lava rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4699" + }, + { + "examine": "You need to add lamp oil before you can use it.", + "durability": null, + "name": "Sapphire lantern", + "weight": "1.3", + "archery_ticket_price": "0", + "id": "4700" + }, + { + "examine": "A bullseye lantern with a sapphire for a lens.", + "durability": null, + "name": "Sapphire lantern", + "weight": "1.3", + "archery_ticket_price": "0", + "id": "4701" + }, + { + "examine": "A lantern casting a bright blue beam.", + "durability": null, + "name": "Sapphire lantern", + "weight": "1.3", + "archery_ticket_price": "0", + "id": "4702" + }, + { + "shop_price": "1", + "examine": "Doesn't look very special.", + "grand_exchange_price": "0", + "durability": null, + "name": "Magic stone", + "tradeable": "false", + "weight": "2.267", + "archery_ticket_price": "0", + "id": "4703" + }, + { + "turn90cw_anim": "821", + "examine": "A magic stone bowl for catching the tears of Guthix.", + "walk_anim": "819", + "durability": null, + "destroy": "true", + "weight": "1.8", + "turn90ccw_anim": "822", + "turn180_anim": "820", + "render_anim": "1", + "equipment_slot": "3", + "stand_anim": "808", + "name": "Stone bowl", + "tradeable": "false", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "4704", + "stand_turn_anim": "823" + }, + { + "examine": "This book must be really old!", + "durability": null, + "name": "Crumbling tome", + "archery_ticket_price": "0", + "id": "4707" + }, + { + "remove_head": "true", + "requirements": "{1,70}-{6,70}", + "ge_buy_limit": "10", + "examine": "Ahrim the Blighted's leather hood.", + "durability": null, + "rare_item": "true", + "weight": "0.9", + "absorb": "5,2,0", + "equipment_slot": "0", + "grand_exchange_price": "94300", + "name": "Ahrim's hood", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4708", + "bonuses": "0,0,0,6,-2,15,13,16,6,0,15,0,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "94300", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Ahrim's hood", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4709" + }, + { + "ge_buy_limit": "10", + "turn90cw_anim": "1207", + "examine": "Ahrim the Blighted's quarterstaff.", + "walk_anim": "1205", + "rare_item": "true", + "turn90ccw_anim": "1208", + "attack_speed": "6", + "two_handed": "true", + "turn180_anim": "1206", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "grand_exchange_price": "69500", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "4710", + "stand_turn_anim": "1209", + "bonuses": "12,-1,65,15,0,3,5,2,15,0,0,68,0,0,0", + "requirements": "{0,70}-{6,70}", + "durability": null, + "weight": "2", + "weapon_interface": "1", + "equip_audio": "2247", + "render_anim": "28", + "attack_audios": "2555,0,0,0", + "name": "Ahrim's staff" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "69500", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Ahrim's staff", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4711" + }, + { + "requirements": "{1,70}-{6,70}", + "ge_buy_limit": "10", + "examine": "Ahrim the Blighted's armoured robe top.", + "durability": null, + "rare_item": "true", + "weight": "5", + "absorb": "10,5,0", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "1000000", + "name": "Ahrim's robetop", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4712", + "bonuses": "0,0,0,30,-10,52,37,63,30,0,60,0,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "1000000", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Ahrim's robetop", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4713" + }, + { + "requirements": "{1,70}-{6,70}", + "ge_buy_limit": "10", + "examine": "Ahrim the Blighted's armoured robe skirt.", + "durability": null, + "rare_item": "true", + "weight": "12", + "absorb": "7,3,0", + "equipment_slot": "7", + "grand_exchange_price": "1700000", + "name": "Ahrim's robeskirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4714", + "bonuses": "0,0,0,22,-7,33,30,36,22,0,30,0,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "1700000", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Ahrim's robeskirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4715" + }, + { + "remove_head": "true", + "requirements": "{1,70}", + "ge_buy_limit": "10", + "examine": "Dharok the Wretched's helm.", + "durability": "1", + "rare_item": "true", + "weight": "1", + "absorb": "2,0,5", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "1300000", + "name": "Dharok's helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4716", + "bonuses": "0,0,0,-3,-1,45,48,44,-1,51,15,0,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "1300000", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Dharok's helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4717" + }, + { + "ge_buy_limit": "10", + "turn90cw_anim": "821", + "examine": "Dharok the Wretched's greataxe.", + "walk_anim": "2064", + "rare_item": "true", + "turn90ccw_anim": "822", + "attack_speed": "7", + "two_handed": "true", + "turn180_anim": "820", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "2067,2067,2066,2067", + "grand_exchange_price": "516900", + "stand_anim": "2065", + "tradeable": "true", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "4718", + "stand_turn_anim": "823", + "bonuses": "-4,103,95,-4,0,0,0,0,0,-1,0,105,0,0,0", + "requirements": "{0,70}-{2,70}", + "durability": null, + "weight": "13", + "weapon_interface": "2", + "equip_audio": "2232", + "render_anim": "134", + "name": "Dharok's greataxe" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "516900", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Dharok's greataxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4719" + }, + { + "requirements": "{1,70}", + "ge_buy_limit": "10", + "examine": "Dharok the Wretched's platebody armour.", + "durability": null, + "rare_item": "true", + "weight": "9.9", + "absorb": "5,0,10", + "equip_audio": "2239", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "511400", + "name": "Dharok's platebody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4720", + "bonuses": "0,0,0,-30,-10,122,120,107,-6,132,60,0,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "511400", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Dharok's platebody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4721" + }, + { + "requirements": "{1,70}", + "ge_buy_limit": "10", + "examine": "Dharok the Wretched's plate leg armour.", + "durability": null, + "rare_item": "true", + "weight": "10", + "absorb": "3,0,7", + "equip_audio": "2243", + "equipment_slot": "7", + "grand_exchange_price": "748800", + "name": "Dharok's platelegs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4722", + "bonuses": "0,0,0,-21,-7,85,82,83,-4,92,30,0,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "748800", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Dharok's platelegs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4723" + }, + { + "remove_head": "true", + "requirements": "{1,70}", + "ge_buy_limit": "10", + "examine": "Guthan the Infested's helm", + "durability": null, + "rare_item": "true", + "weight": "2", + "absorb": "2,0,5", + "equip_audio": "2240", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "396300", + "name": "Guthan's helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4724", + "bonuses": "0,0,0,-6,-2,55,58,54,-1,62,15,0,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "396300", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Guthan's helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4725" + }, + { + "ge_buy_limit": "10", + "turn90cw_anim": "1207", + "examine": "Guthan the Infested's warspear.", + "walk_anim": "1205", + "rare_item": "true", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "turn180_anim": "1206", + "defence_anim": "2079", + "equipment_slot": "3", + "attack_anims": "2080,2081,2082,2080", + "grand_exchange_price": "588400", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "4726", + "stand_turn_anim": "1209", + "bonuses": "75,75,75,0,0,7,7,7,0,0,0,75,0,0,0", + "requirements": "{0,70}", + "durability": null, + "weight": "2.2", + "weapon_interface": "14", + "equip_audio": "2247", + "render_anim": "28", + "name": "Guthan's warspear" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "588400", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Guthan's warspear", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4727" + }, + { + "requirements": "{1,70}", + "ge_buy_limit": "10", + "examine": "Guthan the Infested's platebody armour.", + "durability": null, + "rare_item": "true", + "weight": "9", + "absorb": "5,0,10", + "equip_audio": "2239", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "316800", + "name": "Guthan's platebody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4728", + "bonuses": "0,0,0,-30,-10,122,120,107,-6,132,60,0,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "316800", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Guthan's platebody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4729" + }, + { + "requirements": "{1,70}", + "ge_buy_limit": "10", + "examine": "Guthan the Infested's chainskirt.", + "durability": null, + "rare_item": "true", + "weight": "8", + "absorb": "3,0,7", + "equip_audio": "2242", + "equipment_slot": "7", + "grand_exchange_price": "315600", + "name": "Guthan's chainskirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4730", + "bonuses": "0,0,0,-14,-7,75,72,73,-4,82,30,0,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "315600", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Guthan's chainskirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4731" + }, + { + "remove_head": "true", + "requirements": "{1,70}-{4,70}", + "ge_buy_limit": "1", + "examine": "Karil the Tainted's coif.", + "durability": null, + "rare_item": "true", + "absorb": "0,5,2", + "equip_audio": "2238", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "38900", + "name": "Karil's coif", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4732", + "bonuses": "0,0,0,-1,3,6,9,12,6,10,15,0,0,0,0" + }, + { + "ge_buy_limit": "1", + "grand_exchange_price": "38900", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Karil's coif", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4733" + }, + { + "ge_buy_limit": "1", + "turn90cw_anim": "2076", + "examine": "Karil the Tainted's repeating crossbow.", + "walk_anim": "2076", + "rare_item": "true", + "turn90ccw_anim": "2076", + "attack_speed": "4", + "two_handed": "true", + "turn180_anim": "2076", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "2075,2075,2075,2075", + "grand_exchange_price": "188000", + "stand_anim": "2074", + "tradeable": "true", + "run_anim": "2077", + "archery_ticket_price": "0", + "id": "4734", + "stand_turn_anim": "823", + "bonuses": "0,0,0,0,84,0,0,0,0,0,0,0,0,0,0", + "requirements": "{4,70}", + "durability": null, + "weight": "2", + "weapon_interface": "17", + "equip_audio": "2244", + "render_anim": "372", + "attack_audios": "2700,0,0,0", + "name": "Karil's crossbow" + }, + { + "ge_buy_limit": "1", + "grand_exchange_price": "188000", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Karil's crossbow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4735" + }, + { + "requirements": "{1,70}-{4,70}", + "ge_buy_limit": "10000", + "examine": "Karil the Tainted's leather body armour.", + "durability": null, + "rare_item": "true", + "weight": "6", + "absorb": "0,10,5", + "equip_audio": "2241", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "1800000", + "name": "Karil's leathertop", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4736", + "bonuses": "0,0,0,-15,30,47,42,50,65,57,60,0,0,0,0" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "1800000", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Karil's leathertop", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4737" + }, + { + "requirements": "{1,70}-{4,70}", + "ge_buy_limit": "10000", + "examine": "Karil the Tainted's leather skirt.", + "durability": null, + "rare_item": "true", + "weight": "2", + "absorb": "0,7,3", + "equip_audio": "2238", + "equipment_slot": "7", + "grand_exchange_price": "217000", + "name": "Karil's leatherskirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4738", + "bonuses": "0,0,0,-10,17,26,20,28,35,33,30,0,0,0,0" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "217000", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Karil's leatherskirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4739" + }, + { + "requirements": "{4,70}", + "shop_price": "420", + "ge_buy_limit": "10000", + "examine": "Must need a special type of crossbow to use this.", + "grand_exchange_price": "238", + "durability": null, + "name": "Bolt rack", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4740", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,55", + "equipment_slot": "13" + }, + { + "remove_head": "true", + "requirements": "{1,70}", + "ge_buy_limit": "10", + "examine": "Torag the Corrupted's helm.", + "durability": null, + "rare_item": "true", + "weight": "5", + "absorb": "2,0,5", + "equip_audio": "2240", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "139000", + "name": "Torag's helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4745", + "bonuses": "0,0,0,-6,-2,55,58,54,-1,62,15,0,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "139000", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Torag's helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4746" + }, + { + "requirements": "{0,70}-{2,70}", + "ge_buy_limit": "1000", + "examine": "Torag the Corrupted's twin hammers.", + "durability": null, + "rare_item": "true", + "weight": "3", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "10", + "equip_audio": "2233", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "2068,2068,2068,2068", + "grand_exchange_price": "111600", + "attack_audios": "1332,0,0,0", + "name": "Torag's hammers", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4747", + "bonuses": "-4,-4,85,-4,0,0,0,0,0,0,0,72,0,0,0" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "111600", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Torag's hammers", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4748" + }, + { + "requirements": "{1,70}", + "ge_buy_limit": "10", + "examine": "Torag the Corrupted's platebody armour.", + "durability": null, + "rare_item": "true", + "weight": "9", + "absorb": "5,0,10", + "equip_audio": "2239", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "346200", + "name": "Torag's platebody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4749", + "bonuses": "0,0,0,-30,-10,122,120,107,-6,132,60,0,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "346200", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Torag's platebody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4750" + }, + { + "requirements": "{1,70}", + "ge_buy_limit": "10", + "examine": "Torag the Corrupted's plate leg armour.", + "durability": null, + "rare_item": "true", + "weight": "9", + "absorb": "3,0,7", + "equip_audio": "2242", + "equipment_slot": "7", + "grand_exchange_price": "427200", + "name": "Torag's platelegs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4751", + "bonuses": "0,0,0,-21,-7,85,82,83,-4,92,30,0,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "427200", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Torag's platelegs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4752" + }, + { + "remove_head": "true", + "requirements": "{1,70}", + "ge_buy_limit": "10", + "examine": "Verac the Defiled's helm.", + "durability": null, + "rare_item": "true", + "weight": "1", + "absorb": "2,0,5", + "equip_audio": "2240", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "687200", + "name": "Verac's helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4753", + "bonuses": "0,0,0,-6,-2,55,58,54,0,56,15,0,3,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "687200", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Verac's helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4754" + }, + { + "ge_buy_limit": "10", + "turn90cw_anim": "2060", + "examine": "Verac the Defiled's flail.", + "walk_anim": "1830", + "rare_item": "true", + "turn90ccw_anim": "2060", + "attack_speed": "5", + "two_handed": "true", + "turn180_anim": "2060", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "2062,2062,2062,2062", + "grand_exchange_price": "135500", + "stand_anim": "1832", + "tradeable": "true", + "run_anim": "1831", + "archery_ticket_price": "0", + "id": "4755", + "stand_turn_anim": "823", + "bonuses": "68,-2,82,0,0,0,0,0,0,0,0,72,6,0,0", + "requirements": "{0,70}", + "durability": null, + "weight": "2", + "weapon_interface": "8", + "equip_audio": "2246", + "render_anim": "1426", + "attack_audios": "1323,0,0,0", + "name": "Verac's flail" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "135500", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Verac's flail", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4756" + }, + { + "requirements": "{1,70}", + "ge_buy_limit": "10", + "examine": "Verac the Defiled's brassard.", + "durability": null, + "rare_item": "true", + "weight": "5", + "absorb": "5,0,10", + "equip_audio": "2241", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "270000", + "name": "Verac's brassard", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4757", + "bonuses": "0,0,0,-6,-2,81,95,85,0,81,60,0,5,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "270000", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Verac's brassard", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4758" + }, + { + "requirements": "{1,70}", + "ge_buy_limit": "10", + "examine": "Verac the Defiled's plate skirt.", + "durability": null, + "rare_item": "true", + "weight": "5", + "absorb": "3,0,7", + "equip_audio": "2242", + "equipment_slot": "7", + "grand_exchange_price": "411400", + "name": "Verac's plateskirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4759", + "bonuses": "0,0,0,-21,-7,85,82,83,0,84,30,0,4,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "411400", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Verac's plateskirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4760" + }, + { + "requirements": "{4,30}", + "ge_buy_limit": "1000", + "examine": "Blunt bronze arrow...ouch", + "grand_exchange_price": "39", + "durability": null, + "name": "Bronze brutal", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4773", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,11", + "equipment_slot": "13" + }, + { + "requirements": "{4,30}", + "ge_buy_limit": "1000", + "examine": "Blunt iron arrow...ouch", + "grand_exchange_price": "14", + "durability": null, + "name": "Iron brutal", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4778", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,13", + "equipment_slot": "13" + }, + { + "requirements": "{4,30}", + "ge_buy_limit": "1000", + "examine": "Blunt steel arrow...ouch", + "grand_exchange_price": "20", + "durability": null, + "name": "Steel brutal", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4783", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,19", + "equipment_slot": "13" + }, + { + "requirements": "{4,30}", + "ge_buy_limit": "1000", + "examine": "Blunt black arrow...ouch", + "grand_exchange_price": "63", + "durability": null, + "name": "Black brutal", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4788", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,22", + "equipment_slot": "13" + }, + { + "requirements": "{4,30}", + "shop_price": "20", + "ge_buy_limit": "1000", + "examine": "Blunt mithril arrow...ouch", + "grand_exchange_price": "80", + "durability": null, + "name": "Mithril brutal", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4793", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,34", + "equipment_slot": "13" + }, + { + "requirements": "{4,30}", + "ge_buy_limit": "1000", + "examine": "Blunt adamant arrow...ouch", + "grand_exchange_price": "154", + "durability": null, + "name": "Adamant brutal", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4798", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,45", + "equipment_slot": "13" + }, + { + "requirements": "{4,30}", + "shop_price": "180", + "ge_buy_limit": "1000", + "examine": "Blunt rune arrow...ouch", + "grand_exchange_price": "188", + "durability": null, + "name": "Rune brutal", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4803", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,60", + "equipment_slot": "13" + }, + { + "examine": "A very black prism.", + "durability": null, + "name": "Black prism", + "archery_ticket_price": "0", + "id": "4808" + }, + { + "examine": "A half torn necromantic page.", + "durability": null, + "name": "Torn page", + "archery_ticket_price": "0", + "id": "4809" + }, + { + "examine": "It's about to fall apart.", + "durability": null, + "name": "Ruined backpack", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "4810" + }, + { + "examine": "A white ceramic mug with a dragon insignia.", + "durability": null, + "name": "Dragon inn tankard", + "archery_ticket_price": "0", + "id": "4811" + }, + { + "ge_buy_limit": "10000", + "examine": "A pile of Zombie Ogre bones.", + "grand_exchange_price": "1167", + "durability": null, + "name": "Zogre bones", + "tradeable": "true", + "weight": "0.8", + "archery_ticket_price": "0", + "id": "4812" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "1167", + "durability": null, + "name": "Zogre bones", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4813" + }, + { + "examine": "A classic realist charcoal portrait of Sithik.", + "durability": null, + "name": "Sithik portrait", + "archery_ticket_price": "0", + "id": "4814" + }, + { + "examine": "A classic realist charcoal portrait of Sithik.", + "durability": null, + "name": "Sithik portrait", + "archery_ticket_price": "0", + "id": "4815" + }, + { + "examine": "A signed classic realist charcoal portrait of Sithik.", + "durability": null, + "name": "Signed portrait", + "archery_ticket_price": "0", + "id": "4816" + }, + { + "examine": "A book explaining the art of portraiture.", + "durability": null, + "name": "Book of portraiture", + "weight": "1", + "archery_ticket_price": "0", + "id": "4817", + "equipment_slot": "5" + }, + { + "examine": "An ancient ogre artefact-resembling a large heavy helm.", + "durability": null, + "name": "Ogre artefact", + "archery_ticket_price": "0", + "id": "4818" + }, + { + "shop_price": "4", + "ge_buy_limit": "10000", + "examine": "Keeps things in place fairly permanently.", + "grand_exchange_price": "16", + "durability": null, + "name": "Bronze nails", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4819" + }, + { + "shop_price": "33", + "ge_buy_limit": "10000", + "examine": "Keeps things in place fairly permanently.", + "grand_exchange_price": "16", + "durability": null, + "name": "Iron nails", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4820" + }, + { + "ge_buy_limit": "10000", + "examine": "Keeps things in place fairly permanently.", + "grand_exchange_price": "13", + "durability": null, + "name": "Black nails", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4821" + }, + { + "ge_buy_limit": "10000", + "examine": "Keeps things in place fairly permanently.", + "grand_exchange_price": "35", + "durability": null, + "name": "Mithril nails", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4822" + }, + { + "ge_buy_limit": "10000", + "examine": "Keeps things in place fairly permanently.", + "grand_exchange_price": "87", + "durability": null, + "name": "Adamantite nails", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4823" + }, + { + "ge_buy_limit": "10000", + "examine": "Keeps things in place fairly permanently.", + "grand_exchange_price": "114", + "durability": null, + "name": "Rune nails", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4824" + }, + { + "ge_buy_limit": "100", + "examine": "An unstrung composite ogre bow.", + "grand_exchange_price": "447", + "durability": null, + "name": "Unstrung comp bow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4825" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "447", + "durability": null, + "name": "Unstrung comp bow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4826" + }, + { + "requirements": "{4,30}", + "shop_price": "180", + "ge_buy_limit": "100", + "examine": "A composite ogre bow.", + "durability": null, + "weight": "1.8", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "16", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "426,426,426,426", + "grand_exchange_price": "225", + "attack_audios": "2700,0,0,0", + "name": "Comp ogre bow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4827", + "bonuses": "0,0,0,0,38,0,0,0,0,0,0,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "225", + "durability": null, + "name": "Comp ogre bow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4828" + }, + { + "examine": "A book of H.A.M. affiliation", + "durability": null, + "name": "Book of 'h.a.m", + "archery_ticket_price": "0", + "id": "4829", + "equipment_slot": "5" + }, + { + "ge_buy_limit": "10000", + "examine": "Ancient ogre bones from the ogre burial tomb.", + "grand_exchange_price": "5931", + "durability": null, + "name": "Fayrg bones", + "tradeable": "true", + "weight": "0.8", + "archery_ticket_price": "0", + "id": "4830" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "5931", + "durability": null, + "name": "Fayrg bones", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4831" + }, + { + "ge_buy_limit": "10000", + "examine": "Ancient ogre bones from the ogre burial tomb.", + "grand_exchange_price": "7093", + "durability": null, + "name": "Raurg bones", + "tradeable": "true", + "weight": "0.8", + "archery_ticket_price": "0", + "id": "4832" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "7093", + "durability": null, + "name": "Raurg bones", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4833" + }, + { + "ge_buy_limit": "10000", + "examine": "Ancient ogre bones from the burial tomb.", + "grand_exchange_price": "16300", + "durability": null, + "name": "Ourg bones", + "tradeable": "true", + "weight": "0.8", + "archery_ticket_price": "0", + "id": "4834" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "16300", + "durability": null, + "name": "Ourg bones", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4835" + }, + { + "examine": "Some strange liquid given to you by Zavistic Rarve.", + "durability": null, + "name": "Strange potion", + "archery_ticket_price": "0", + "id": "4836" + }, + { + "examine": "A book of necromantic spells.", + "durability": null, + "name": "Necromancy book", + "archery_ticket_price": "0", + "id": "4837", + "equipment_slot": "5" + }, + { + "shop_price": "10", + "examine": "A nice cup of tea.", + "grand_exchange_price": "30", + "durability": null, + "name": "Cup of tea", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "4838" + }, + { + "examine": "A key to some sort of special tomb area.", + "durability": null, + "name": "Ogre gate key", + "archery_ticket_price": "0", + "id": "4839" + }, + { + "ge_buy_limit": "100", + "examine": "I need another ingredient to finish this rogue's purse potion.", + "grand_exchange_price": "2194", + "durability": null, + "name": "Rogue's purse potion(unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4840" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2194", + "durability": null, + "name": "Rogue's purse potion(unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4841" + }, + { + "shop_price": "200", + "ge_buy_limit": "1000", + "examine": "4 doses of Relicym's balm, which helps cure disease.", + "grand_exchange_price": "1430", + "durability": null, + "name": "Relicym's balm(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4842" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1430", + "durability": null, + "name": "Relicym's balm(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4843" + }, + { + "shop_price": "200", + "ge_buy_limit": "1000", + "examine": "3 doses of Relicym's balm, which helps cure disease.", + "grand_exchange_price": "654", + "durability": null, + "name": "Relicym's balm(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4844" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "654", + "durability": null, + "name": "Relicym's balm(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4845" + }, + { + "shop_price": "200", + "ge_buy_limit": "1000", + "examine": "2 doses of Relicym's balm, which helps cure disease.", + "grand_exchange_price": "325", + "durability": null, + "name": "Relicym's balm(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4846" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "325", + "durability": null, + "name": "Relicym's balm(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4847" + }, + { + "shop_price": "200", + "ge_buy_limit": "1000", + "examine": "1 dose of Relicym's balm, which helps cure disease.", + "grand_exchange_price": "204", + "durability": null, + "name": "Relicym's balm(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4848" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "204", + "durability": null, + "name": "Relicym's balm(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4849" + }, + { + "ge_buy_limit": "100", + "examine": "A key which opens a coffin!", + "grand_exchange_price": "1963", + "durability": null, + "name": "Ogre coffin key", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4850" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1963", + "durability": null, + "name": "Ogre coffin key", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4851" + }, + { + "examine": "A pot of crushed fayrg bones.", + "durability": null, + "name": "Bonemeal", + "weight": "1", + "archery_ticket_price": "0", + "id": "4852" + }, + { + "examine": "A pot of crushed raurg bones.", + "durability": null, + "name": "Bonemeal", + "weight": "1", + "archery_ticket_price": "0", + "id": "4853" + }, + { + "examine": "A pot of crushed ourg bones.", + "durability": null, + "name": "Bonemeal", + "weight": "1", + "archery_ticket_price": "0", + "id": "4854" + }, + { + "examine": "A pot of crushed gorilla monkey bones.", + "durability": null, + "name": "Bonemeal", + "weight": "1", + "archery_ticket_price": "0", + "id": "4855" + }, + { + "remove_head": "true", + "requirements": "{1,70}-{6,70}", + "examine": "Ahrim the Blighted's leather hood.", + "grand_exchange_price": "77678", + "durability": null, + "name": "Ahrim's hood 100", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "4856", + "absorb": "5,2,0", + "bonuses": "0,0,0,6,-2,15,13,16,6,0,15,0,0,0,0", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "requirements": "{1,70}-{6,70}", + "examine": "Ahrim the Blighted's leather hood.", + "grand_exchange_price": "77678", + "durability": null, + "name": "Ahrim's hood 75", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "4857", + "absorb": "5,2,0", + "bonuses": "0,0,0,6,-2,15,13,16,6,0,15,0,0,0,0", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "requirements": "{1,70}-{6,70}", + "examine": "Ahrim the Blighted's leather hood.", + "grand_exchange_price": "77678", + "durability": null, + "name": "Ahrim's hood 50", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "4858", + "absorb": "5,2,0", + "bonuses": "0,0,0,6,-2,15,13,16,6,0,15,0,0,0,0", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "requirements": "{1,70}-{6,70}", + "examine": "Ahrim the Blighted's leather hood.", + "grand_exchange_price": "77678", + "durability": null, + "name": "Ahrim's hood 25", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "4859", + "absorb": "5,2,0", + "bonuses": "0,0,0,6,-2,15,13,16,6,0,15,0,0,0,0", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "requirements": "{1,70}-{6,70}", + "ge_buy_limit": "10", + "examine": "Ahrim the Blighted's leather hood.", + "durability": null, + "weight": "0.9", + "absorb": "5,2,0", + "equipment_slot": "0", + "grand_exchange_price": "51700", + "name": "Ahrim's hood 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4860" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "51700", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Ahrim's hood 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4861" + }, + { + "requirements": "{0,70}-{6,70}", + "turn90cw_anim": "1207", + "examine": "Ahrim the Blighted's quarterstaff.", + "walk_anim": "1205", + "durability": null, + "weight": "2", + "turn90ccw_anim": "1208", + "attack_speed": "6", + "weapon_interface": "1", + "turn180_anim": "1206", + "equip_audio": "2247", + "defence_anim": "420", + "render_anim": "28", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "grand_exchange_price": "50655", + "stand_anim": "813", + "attack_audios": "2555,0,0,0", + "name": "Ahrim's staff 100", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "4862", + "stand_turn_anim": "1209", + "bonuses": "12,-1,65,15,0,3,5,2,15,0,0,68,0,0,0" + }, + { + "requirements": "{0,70}-{6,70}", + "turn90cw_anim": "1207", + "examine": "Ahrim the Blighted's quarterstaff.", + "walk_anim": "1205", + "durability": null, + "weight": "2", + "turn90ccw_anim": "1208", + "attack_speed": "6", + "weapon_interface": "1", + "turn180_anim": "1206", + "equip_audio": "2247", + "defence_anim": "420", + "render_anim": "28", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "grand_exchange_price": "50655", + "stand_anim": "813", + "attack_audios": "2555,0,0,0", + "name": "Ahrim's staff 75", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "4863", + "stand_turn_anim": "1209", + "bonuses": "12,-1,65,15,0,3,5,2,15,0,0,68,0,0,0" + }, + { + "requirements": "{0,70}-{6,70}", + "turn90cw_anim": "1207", + "examine": "Ahrim the Blighted's quarterstaff.", + "walk_anim": "1205", + "durability": null, + "weight": "2", + "turn90ccw_anim": "1208", + "attack_speed": "6", + "weapon_interface": "1", + "turn180_anim": "1206", + "equip_audio": "2247", + "defence_anim": "420", + "render_anim": "28", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "grand_exchange_price": "50655", + "stand_anim": "813", + "attack_audios": "2555,0,0,0", + "name": "Ahrim's staff 50", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "4864", + "stand_turn_anim": "1209", + "bonuses": "12,-1,65,15,0,3,5,2,15,0,0,68,0,0,0" + }, + { + "requirements": "{0,70}-{6,70}", + "turn90cw_anim": "1207", + "examine": "Ahrim the Blighted's quarterstaff.", + "walk_anim": "1205", + "durability": null, + "weight": "2", + "turn90ccw_anim": "1208", + "attack_speed": "6", + "weapon_interface": "1", + "turn180_anim": "1206", + "equip_audio": "2247", + "defence_anim": "420", + "render_anim": "28", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "grand_exchange_price": "50655", + "stand_anim": "813", + "attack_audios": "2555,0,0,0", + "name": "Ahrim's staff 25", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "4865", + "stand_turn_anim": "1209", + "bonuses": "12,-1,65,15,0,3,5,2,15,0,0,68,0,0,0" + }, + { + "requirements": "{0,70}-{6,70}", + "ge_buy_limit": "10", + "turn90cw_anim": "1207", + "examine": "Ahrim the Blighted's quarterstaff.", + "walk_anim": "1205", + "durability": null, + "weight": "2", + "turn90ccw_anim": "1208", + "attack_speed": "6", + "weapon_interface": "1", + "turn180_anim": "1206", + "equip_audio": "2247", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "50600", + "stand_anim": "813", + "attack_audios": "2555,0,0,0", + "name": "Ahrim's staff 0", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "4866", + "stand_turn_anim": "1209" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "50600", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Ahrim's staff 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4867" + }, + { + "requirements": "{1,70}-{6,70}", + "remove_sleeves": "true", + "examine": "Ahrim the Blighted's armoured robe top.", + "grand_exchange_price": "1458307", + "durability": null, + "name": "Ahrim's top 100", + "weight": "5", + "archery_ticket_price": "0", + "id": "4868", + "absorb": "10,5,0", + "bonuses": "0,0,0,30,-10,52,37,63,30,0,60,0,0,0,0", + "equipment_slot": "4" + }, + { + "requirements": "{1,70}-{6,70}", + "remove_sleeves": "true", + "examine": "Ahrim the Blighted's armoured robe top.", + "grand_exchange_price": "1458307", + "durability": null, + "name": "Ahrim's top 75", + "weight": "5", + "archery_ticket_price": "0", + "id": "4869", + "absorb": "10,5,0", + "bonuses": "0,0,0,30,-10,52,37,63,30,0,60,0,0,0,0", + "equipment_slot": "4" + }, + { + "requirements": "{1,70}-{6,70}", + "remove_sleeves": "true", + "examine": "Ahrim the Blighted's armoured robe top.", + "grand_exchange_price": "1458307", + "durability": null, + "name": "Ahrim's top 50", + "weight": "5", + "archery_ticket_price": "0", + "id": "4870", + "absorb": "10,5,0", + "bonuses": "0,0,0,30,-10,52,37,63,30,0,60,0,0,0,0", + "equipment_slot": "4" + }, + { + "requirements": "{1,70}-{6,70}", + "remove_sleeves": "true", + "examine": "Ahrim the Blighted's armoured robe top.", + "grand_exchange_price": "1458307", + "durability": null, + "name": "Ahrim's top 25", + "weight": "5", + "archery_ticket_price": "0", + "id": "4871", + "absorb": "10,5,0", + "bonuses": "0,0,0,30,-10,52,37,63,30,0,60,0,0,0,0", + "equipment_slot": "4" + }, + { + "requirements": "{1,70}-{6,70}", + "ge_buy_limit": "10", + "examine": "Ahrim the Blighted's armoured robe top.", + "durability": null, + "weight": "5", + "absorb": "10,5,0", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "1100000", + "name": "Ahrim's top 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4872" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "1100000", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Ahrim's top 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4873" + }, + { + "requirements": "{1,70}-{6,70}", + "examine": "Ahrim the Blighted's armoured robe skirt.", + "grand_exchange_price": "1561591", + "durability": null, + "name": "Ahrim's skirt 100", + "weight": "12", + "archery_ticket_price": "0", + "id": "4874", + "absorb": "7,3,0", + "bonuses": "0,0,0,22,-7,33,30,36,22,0,30,0,0,0,0", + "equipment_slot": "7" + }, + { + "requirements": "{1,70}-{6,70}", + "examine": "Ahrim the Blighted's armoured robe skirt.", + "grand_exchange_price": "1561591", + "durability": null, + "name": "Ahrim's skirt 75", + "weight": "12", + "archery_ticket_price": "0", + "id": "4875", + "absorb": "7,3,0", + "bonuses": "0,0,0,22,-7,33,30,36,22,0,30,0,0,0,0", + "equipment_slot": "7" + }, + { + "requirements": "{1,70}-{6,70}", + "examine": "Ahrim the Blighted's armoured robe skirt.", + "grand_exchange_price": "1561591", + "durability": null, + "name": "Ahrim's skirt 50", + "weight": "12", + "archery_ticket_price": "0", + "id": "4876", + "absorb": "7,3,0", + "bonuses": "0,0,0,22,-7,33,30,36,22,0,30,0,0,0,0", + "equipment_slot": "7" + }, + { + "requirements": "{1,70}-{6,70}", + "examine": "Ahrim the Blighted's armoured robe skirt.", + "grand_exchange_price": "1561591", + "durability": null, + "name": "Ahrim's skirt 25", + "weight": "12", + "archery_ticket_price": "0", + "id": "4877", + "absorb": "7,3,0", + "bonuses": "0,0,0,22,-7,33,30,36,22,0,30,0,0,0,0", + "equipment_slot": "7" + }, + { + "requirements": "{1,70}-{6,70}", + "ge_buy_limit": "10", + "examine": "Ahrim the Blighted's armoured robe skirt.", + "grand_exchange_price": "1500000", + "durability": null, + "name": "Ahrim's skirt 0", + "tradeable": "true", + "weight": "12", + "archery_ticket_price": "0", + "id": "4878", + "absorb": "7,3,0", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "1500000", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Ahrim's skirt 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4879" + }, + { + "remove_head": "true", + "requirements": "{1,70}", + "examine": "Dharok the Wretched's helm.", + "durability": null, + "weight": "1", + "absorb": "2,0,5", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "1355582", + "name": "Dharok's helm 100", + "archery_ticket_price": "0", + "id": "4880", + "bonuses": "0,0,0,-3,-1,45,48,44,-1,51,15,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,70}", + "examine": "Dharok the Wretched's helm.", + "durability": null, + "weight": "1", + "absorb": "2,0,5", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "1355582", + "name": "Dharok's helm 75", + "archery_ticket_price": "0", + "id": "4881", + "bonuses": "0,0,0,-3,-1,45,48,44,-1,51,15,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,70}", + "examine": "Dharok the Wretched's helm.", + "durability": null, + "weight": "1", + "absorb": "2,0,5", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "1355582", + "name": "Dharok's helm 50", + "archery_ticket_price": "0", + "id": "4882", + "bonuses": "0,0,0,-3,-1,45,48,44,-1,51,15,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,70}", + "examine": "Dharok the Wretched's helm.", + "durability": null, + "weight": "1", + "absorb": "2,0,5", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "1355582", + "name": "Dharok's helm 25", + "archery_ticket_price": "0", + "id": "4883", + "bonuses": "0,0,0,-3,-1,45,48,44,-1,51,15,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,70}", + "ge_buy_limit": "10", + "examine": "Dharok the Wretched's helm.", + "durability": null, + "weight": "1", + "absorb": "2,0,5", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "1300000", + "name": "Dharok's helm 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4884" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "1300000", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Dharok's helm 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4885" + }, + { + "turn90cw_anim": "2064", + "examine": "Dharok the Wretched's greataxe.", + "walk_anim": "2064", + "turn90ccw_anim": "2064", + "attack_speed": "7", + "two_handed": "true", + "turn180_anim": "2064", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "2067,2067,2066,2067", + "grand_exchange_price": "454500", + "stand_anim": "2065", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "4886", + "stand_turn_anim": "823", + "bonuses": "-4,103,95,-4,0,0,0,0,0,-1,0,105,0,0,0", + "requirements": "{0,70}-{2,70}", + "durability": null, + "weight": "13", + "weapon_interface": "2", + "equip_audio": "2232", + "render_anim": "134", + "attack_audios": "1320,0,0,0", + "name": "Dharok's axe 100" + }, + { + "turn90cw_anim": "2064", + "examine": "Dharok the Wretched's greataxe.", + "walk_anim": "2064", + "turn90ccw_anim": "2064", + "attack_speed": "7", + "two_handed": "true", + "turn180_anim": "2064", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "2067,2067,2066,2067", + "grand_exchange_price": "454500", + "stand_anim": "2065", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "4887", + "stand_turn_anim": "823", + "bonuses": "-4,103,95,-4,0,0,0,0,0,-1,0,105,0,0,0", + "requirements": "{0,70}-{2,70}", + "durability": null, + "weight": "13", + "weapon_interface": "2", + "equip_audio": "2232", + "render_anim": "134", + "attack_audios": "1320,0,0,0", + "name": "Dharok's axe 75" + }, + { + "turn90cw_anim": "2064", + "examine": "Dharok the Wretched's greataxe.", + "walk_anim": "2064", + "turn90ccw_anim": "2064", + "attack_speed": "7", + "two_handed": "true", + "turn180_anim": "2064", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "2067,2067,2066,2067", + "grand_exchange_price": "454500", + "stand_anim": "2065", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "4888", + "stand_turn_anim": "823", + "bonuses": "-4,103,95,-4,0,0,0,0,0,-1,0,105,0,0,0", + "requirements": "{0,70}-{2,70}", + "durability": null, + "weight": "13", + "weapon_interface": "2", + "equip_audio": "2232", + "render_anim": "134", + "attack_audios": "1320,0,0,0", + "name": "Dharok's axe 50" + }, + { + "turn90cw_anim": "2064", + "examine": "Dharok the Wretched's greataxe.", + "walk_anim": "2064", + "turn90ccw_anim": "2064", + "attack_speed": "7", + "two_handed": "true", + "turn180_anim": "2064", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "2067,2067,2066,2067", + "grand_exchange_price": "454500", + "stand_anim": "2065", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "4889", + "stand_turn_anim": "823", + "bonuses": "-4,103,95,-4,0,0,0,0,0,-1,0,105,0,0,0", + "requirements": "{0,70}-{2,70}", + "durability": null, + "weight": "13", + "weapon_interface": "2", + "equip_audio": "2232", + "render_anim": "134", + "attack_audios": "1320,0,0,0", + "name": "Dharok's axe 25" + }, + { + "requirements": "{0,70}-{2,70}", + "ge_buy_limit": "10", + "turn90cw_anim": "2064", + "examine": "Dharok the Wretched's greataxe.", + "walk_anim": "2064", + "durability": null, + "weight": "13", + "turn90ccw_anim": "2064", + "attack_speed": "7", + "two_handed": "true", + "weapon_interface": "2", + "turn180_anim": "2064", + "equip_audio": "2232", + "render_anim": "134", + "equipment_slot": "3", + "grand_exchange_price": "442600", + "stand_anim": "2065", + "attack_audios": "1320,0,0,0", + "tradeable": "true", + "name": "Dharok's axe 0", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "4890", + "stand_turn_anim": "823" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "442600", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Dharok's axe 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4891" + }, + { + "requirements": "{1,70}", + "examine": "Dharok the Wretched's platebody armour.", + "durability": null, + "weight": "9.9", + "absorb": "5,0,10", + "equip_audio": "2239", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "481600", + "name": "Dharok's body 100", + "archery_ticket_price": "0", + "id": "4892", + "bonuses": "0,0,0,-30,-10,122,120,107,-6,132,60,0,0,0,0" + }, + { + "requirements": "{1,70}", + "examine": "Dharok the Wretched's platebody armour.", + "durability": null, + "weight": "9.9", + "absorb": "5,0,10", + "equip_audio": "2239", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "481600", + "name": "Dharok's body 75", + "archery_ticket_price": "0", + "id": "4893", + "bonuses": "0,0,0,-30,-10,122,120,107,-6,132,60,0,0,0,0" + }, + { + "requirements": "{1,70}", + "examine": "Dharok the Wretched's platebody armour.", + "durability": null, + "weight": "9.9", + "absorb": "5,0,10", + "equip_audio": "2239", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "481600", + "name": "Dharok's body 50", + "archery_ticket_price": "0", + "id": "4894", + "bonuses": "0,0,0,-30,-10,122,120,107,-6,132,60,0,0,0,0" + }, + { + "requirements": "{1,70}", + "examine": "Dharok the Wretched's platebody armour.", + "durability": null, + "weight": "9.9", + "absorb": "5,0,10", + "equip_audio": "2239", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "481600", + "name": "Dharok's body 25", + "archery_ticket_price": "0", + "id": "4895", + "bonuses": "0,0,0,-30,-10,122,120,107,-6,132,60,0,0,0,0" + }, + { + "requirements": "{1,70}", + "ge_buy_limit": "10", + "examine": "Dharok the Wretched's platebody armour.", + "durability": null, + "weight": "9.9", + "absorb": "5,0,10", + "equip_audio": "2239", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "438200", + "name": "Dharok's body 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4896" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "438200", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Dharok's body 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4897" + }, + { + "requirements": "{1,70}", + "examine": "Dharok the Wretched's plate leg armour.", + "grand_exchange_price": "897451", + "durability": null, + "name": "Dharok's legs 100", + "weight": "10", + "archery_ticket_price": "0", + "id": "4898", + "absorb": "3,0,7", + "bonuses": "0,0,0,-21,-7,85,82,83,-4,92,30,0,0,0,0", + "equip_audio": "2243", + "equipment_slot": "7" + }, + { + "requirements": "{1,70}", + "examine": "Dharok the Wretched's plate leg armour.", + "grand_exchange_price": "897451", + "durability": null, + "name": "Dharok's legs 75", + "weight": "10", + "archery_ticket_price": "0", + "id": "4899", + "absorb": "3,0,7", + "bonuses": "0,0,0,-21,-7,85,82,83,-4,92,30,0,0,0,0", + "equip_audio": "2243", + "equipment_slot": "7" + }, + { + "requirements": "{1,70}", + "examine": "Dharok the Wretched's plate leg armour.", + "grand_exchange_price": "897451", + "durability": null, + "name": "Dharok's legs 50", + "weight": "10", + "archery_ticket_price": "0", + "id": "4900", + "absorb": "3,0,7", + "bonuses": "0,0,0,-21,-7,85,82,83,-4,92,30,0,0,0,0", + "equip_audio": "2243", + "equipment_slot": "7" + }, + { + "requirements": "{1,70}", + "examine": "Dharok the Wretched's plate leg armour.", + "grand_exchange_price": "897451", + "durability": null, + "name": "Dharok's legs 25", + "weight": "10", + "archery_ticket_price": "0", + "id": "4901", + "absorb": "3,0,7", + "bonuses": "0,0,0,-21,-7,85,82,83,-4,92,30,0,0,0,0", + "equip_audio": "2243", + "equipment_slot": "7" + }, + { + "requirements": "{1,70}", + "ge_buy_limit": "10", + "examine": "Dharok the Wretched's plate leg armour.", + "durability": null, + "weight": "10", + "absorb": "3,0,7", + "equip_audio": "2243", + "equipment_slot": "7", + "grand_exchange_price": "676000", + "name": "Dharok's legs 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4902" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "676000", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Dharok's legs 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4903" + }, + { + "remove_head": "true", + "requirements": "{1,70}", + "examine": "Guthan the Infested's helm", + "durability": null, + "weight": "2", + "absorb": "2,0,5", + "equip_audio": "2240", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "232455", + "name": "Guthan's helm 100", + "archery_ticket_price": "0", + "id": "4904", + "bonuses": "0,0,0,-6,-2,55,58,54,-1,62,15,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,70}", + "examine": "Guthan the Infested's helm", + "durability": null, + "weight": "2", + "absorb": "2,0,5", + "equip_audio": "2240", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "232455", + "name": "Guthan's helm 75", + "archery_ticket_price": "0", + "id": "4905", + "bonuses": "0,0,0,-6,-2,55,58,54,-1,62,15,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,70}", + "examine": "Guthan the Infested's helm", + "durability": null, + "weight": "2", + "absorb": "2,0,5", + "equip_audio": "2240", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "232455", + "name": "Guthan's helm 50", + "archery_ticket_price": "0", + "id": "4906", + "bonuses": "0,0,0,-6,-2,55,58,54,-1,62,15,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,70}", + "examine": "Guthan the Infested's helm", + "durability": null, + "weight": "2", + "absorb": "2,0,5", + "equip_audio": "2240", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "232455", + "name": "Guthan's helm 25", + "archery_ticket_price": "0", + "id": "4907", + "bonuses": "0,0,0,-6,-2,55,58,54,-1,62,15,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,70}", + "ge_buy_limit": "10", + "examine": "Guthan the Infested's helm", + "durability": null, + "weight": "2", + "absorb": "2,0,5", + "equip_audio": "2240", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "368200", + "name": "Guthan's helm 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4908" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "368200", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Guthan's helm 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4909" + }, + { + "turn90cw_anim": "1207", + "examine": "Guthan the Infested's warspear.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "turn180_anim": "1206", + "defence_anim": "2079", + "equipment_slot": "3", + "attack_anims": "2080,2081,2082,2080", + "grand_exchange_price": "371782", + "stand_anim": "813", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "4910", + "stand_turn_anim": "1209", + "bonuses": "75,75,75,0,0,7,7,7,0,0,0,75,0,0,0", + "requirements": "{0,70}", + "durability": null, + "weight": "2.2", + "weapon_interface": "14", + "equip_audio": "2247", + "render_anim": "28", + "attack_audios": "1316,0,0,0", + "name": "Guthan's spear 100" + }, + { + "turn90cw_anim": "1207", + "examine": "Guthan the Infested's warspear.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "turn180_anim": "1206", + "defence_anim": "2079", + "equipment_slot": "3", + "attack_anims": "2080,2081,2082,2080", + "grand_exchange_price": "371782", + "stand_anim": "813", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "4911", + "stand_turn_anim": "1209", + "bonuses": "75,75,75,0,0,7,7,7,0,0,0,75,0,0,0", + "requirements": "{0,70}", + "durability": null, + "weight": "2.2", + "weapon_interface": "14", + "equip_audio": "2247", + "render_anim": "28", + "attack_audios": "1316,0,0,0", + "name": "Guthan's spear 75" + }, + { + "turn90cw_anim": "1207", + "examine": "Guthan the Infested's warspear.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "turn180_anim": "1206", + "defence_anim": "2079", + "equipment_slot": "3", + "attack_anims": "2080,2081,2082,2080", + "grand_exchange_price": "371782", + "stand_anim": "813", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "4912", + "stand_turn_anim": "1209", + "bonuses": "75,75,75,0,0,7,7,7,0,0,0,75,0,0,0", + "requirements": "{0,70}", + "durability": null, + "weight": "2.2", + "weapon_interface": "14", + "equip_audio": "2247", + "render_anim": "28", + "attack_audios": "1316,0,0,0", + "name": "Guthan's spear 50" + }, + { + "turn90cw_anim": "1207", + "examine": "Guthan the Infested's warspear.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "turn180_anim": "1206", + "defence_anim": "2079", + "equipment_slot": "3", + "attack_anims": "2080,2081,2082,2080", + "grand_exchange_price": "371782", + "stand_anim": "813", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "4913", + "stand_turn_anim": "1209", + "bonuses": "75,75,75,0,0,7,7,7,0,0,0,75,0,0,0", + "requirements": "{0,70}", + "durability": null, + "weight": "2.2", + "weapon_interface": "14", + "equip_audio": "2247", + "render_anim": "28", + "attack_audios": "1316,0,0,0", + "name": "Guthan's spear 25" + }, + { + "requirements": "{0,70}", + "ge_buy_limit": "10", + "turn90cw_anim": "1207", + "examine": "Guthan the Infested's warspear.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1206", + "equip_audio": "2247", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "379500", + "stand_anim": "813", + "attack_audios": "1316,0,0,0", + "tradeable": "true", + "name": "Guthan's spear 0", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "4914", + "stand_turn_anim": "1209" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "379500", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Guthan's spear 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4915" + }, + { + "requirements": "{1,70}", + "examine": "Guthan the Infested's platebody armour.", + "durability": null, + "weight": "9", + "absorb": "5,0,10", + "equip_audio": "2239", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "241605", + "name": "Guthan's body 100", + "archery_ticket_price": "0", + "id": "4916", + "bonuses": "0,0,0,-30,-10,122,120,107,-6,132,60,0,0,0,0" + }, + { + "requirements": "{1,70}", + "examine": "Guthan the Infested's platebody armour.", + "durability": null, + "weight": "9", + "absorb": "5,0,10", + "equip_audio": "2239", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "241605", + "name": "Guthan's body 75", + "archery_ticket_price": "0", + "id": "4917", + "bonuses": "0,0,0,-30,-10,122,120,107,-6,132,60,0,0,0,0" + }, + { + "requirements": "{1,70}", + "examine": "Guthan the Infested's platebody armour.", + "durability": null, + "weight": "9", + "absorb": "5,0,10", + "equip_audio": "2239", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "241605", + "name": "Guthan's body 50", + "archery_ticket_price": "0", + "id": "4918", + "bonuses": "0,0,0,-30,-10,122,120,107,-6,132,60,0,0,0,0" + }, + { + "requirements": "{1,70}", + "examine": "Guthan the Infested's platebody armour.", + "durability": null, + "weight": "9", + "absorb": "5,0,10", + "equip_audio": "2239", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "241605", + "name": "Guthan's body 25", + "archery_ticket_price": "0", + "id": "4919", + "bonuses": "0,0,0,-30,-10,122,120,107,-6,132,60,0,0,0,0" + }, + { + "requirements": "{1,70}", + "ge_buy_limit": "10", + "examine": "Guthan the Infested's platebody armour.", + "durability": null, + "weight": "9", + "absorb": "5,0,10", + "equip_audio": "2239", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "245900", + "name": "Guthan's body 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4920" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "245900", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Guthan's body 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4921" + }, + { + "requirements": "{1,70}", + "examine": "Guthan the Infested's chainskirt.", + "grand_exchange_price": "224030", + "durability": null, + "name": "Guthan's skirt 100", + "weight": "8", + "archery_ticket_price": "0", + "id": "4922", + "absorb": "3,0,7", + "bonuses": "0,0,0,-14,-7,75,72,73,-4,82,30,0,0,0,0", + "equip_audio": "2242", + "equipment_slot": "7" + }, + { + "requirements": "{1,70}", + "examine": "Guthan the Infested's chainskirt.", + "grand_exchange_price": "224030", + "durability": null, + "name": "Guthan's skirt 75", + "weight": "8", + "archery_ticket_price": "0", + "id": "4923", + "absorb": "3,0,7", + "bonuses": "0,0,0,-14,-7,75,72,73,-4,82,30,0,0,0,0", + "equip_audio": "2242", + "equipment_slot": "7" + }, + { + "requirements": "{1,70}", + "examine": "Guthan the Infested's chainskirt.", + "grand_exchange_price": "224030", + "durability": null, + "name": "Guthan's skirt 50", + "weight": "8", + "archery_ticket_price": "0", + "id": "4924", + "absorb": "3,0,7", + "bonuses": "0,0,0,-14,-7,75,72,73,-4,82,30,0,0,0,0", + "equip_audio": "2242", + "equipment_slot": "7" + }, + { + "requirements": "{1,70}", + "examine": "Guthan the Infested's chainskirt.", + "grand_exchange_price": "224030", + "durability": null, + "name": "Guthan's skirt 25", + "weight": "8", + "archery_ticket_price": "0", + "id": "4925", + "absorb": "3,0,7", + "bonuses": "0,0,0,-14,-7,75,72,73,-4,82,30,0,0,0,0", + "equip_audio": "2242", + "equipment_slot": "7" + }, + { + "requirements": "{1,70}", + "ge_buy_limit": "10", + "examine": "Guthan the Infested's chainskirt.", + "durability": null, + "weight": "8", + "absorb": "3,0,7", + "equip_audio": "2242", + "equipment_slot": "7", + "grand_exchange_price": "240900", + "name": "Guthan's skirt 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4926" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "240900", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Guthan's skirt 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4927" + }, + { + "remove_head": "true", + "requirements": "{1,70}-{4,70}", + "examine": "Karil the Tainted's coif.", + "durability": null, + "absorb": "0,5,2", + "equip_audio": "2238", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "7520", + "name": "Karil's coif 100", + "archery_ticket_price": "0", + "id": "4928", + "bonuses": "0,0,0,-1,3,6,9,12,6,10,15,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,70}-{4,70}", + "examine": "Karil the Tainted's coif.", + "durability": null, + "absorb": "0,5,2", + "equip_audio": "2238", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "7520", + "name": "Karil's coif 75", + "archery_ticket_price": "0", + "id": "4929", + "bonuses": "0,0,0,-1,3,6,9,12,6,10,15,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,70}-{4,70}", + "examine": "Karil the Tainted's coif.", + "durability": null, + "absorb": "0,5,2", + "equip_audio": "2238", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "7520", + "name": "Karil's coif 50", + "archery_ticket_price": "0", + "id": "4930", + "bonuses": "0,0,0,-1,3,6,9,12,6,10,15,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,70}-{4,70}", + "examine": "Karil the Tainted's coif.", + "durability": null, + "absorb": "0,5,2", + "equip_audio": "2238", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "7520", + "name": "Karil's coif 25", + "archery_ticket_price": "0", + "id": "4931", + "bonuses": "0,0,0,-1,3,6,9,12,6,10,15,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,70}-{4,70}", + "ge_buy_limit": "1", + "examine": "Karil the Tainted's coif.", + "durability": null, + "absorb": "0,5,2", + "equip_audio": "2238", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "7557", + "name": "Karil's coif 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4932" + }, + { + "ge_buy_limit": "1", + "grand_exchange_price": "7557", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Karil's coif 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4933" + }, + { + "turn90cw_anim": "2076", + "examine": "Karil the Tainted's repeating crossbow.", + "walk_anim": "2076", + "turn90ccw_anim": "2076", + "attack_speed": "4", + "two_handed": "true", + "turn180_anim": "2076", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "2075,2075,2075,2075", + "grand_exchange_price": "108029", + "stand_anim": "2074", + "run_anim": "2077", + "archery_ticket_price": "0", + "id": "4934", + "stand_turn_anim": "823", + "bonuses": "0,0,0,0,84,0,0,0,0,0,0,0,0,0,0", + "requirements": "{4,70}", + "durability": null, + "weight": "2", + "weapon_interface": "17", + "equip_audio": "2244", + "render_anim": "372", + "attack_audios": "2700,0,0,0", + "name": "Karil's x-bow 100" + }, + { + "turn90cw_anim": "2076", + "examine": "Karil the Tainted's repeating crossbow.", + "walk_anim": "2076", + "turn90ccw_anim": "2076", + "attack_speed": "4", + "two_handed": "true", + "turn180_anim": "2076", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "2075,2075,2075,2075", + "grand_exchange_price": "108029", + "stand_anim": "2074", + "run_anim": "2077", + "archery_ticket_price": "0", + "id": "4935", + "stand_turn_anim": "823", + "bonuses": "0,0,0,0,84,0,0,0,0,0,0,0,0,0,0", + "requirements": "{4,70}", + "durability": null, + "weight": "2", + "weapon_interface": "17", + "equip_audio": "2244", + "render_anim": "372", + "attack_audios": "2700,0,0,0", + "name": "Karil's x-bow 75" + }, + { + "turn90cw_anim": "2076", + "examine": "Karil the Tainted's repeating crossbow.", + "walk_anim": "2076", + "turn90ccw_anim": "2076", + "attack_speed": "4", + "two_handed": "true", + "turn180_anim": "2076", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "2075,2075,2075,2075", + "grand_exchange_price": "108029", + "stand_anim": "2074", + "run_anim": "2077", + "archery_ticket_price": "0", + "id": "4936", + "stand_turn_anim": "823", + "bonuses": "0,0,0,0,84,0,0,0,0,0,0,0,0,0,0", + "requirements": "{4,70}", + "durability": null, + "weight": "2", + "weapon_interface": "17", + "equip_audio": "2244", + "render_anim": "372", + "attack_audios": "2700,0,0,0", + "name": "Karil's x-bow 50" + }, + { + "turn90cw_anim": "2076", + "examine": "Karil the Tainted's repeating crossbow.", + "walk_anim": "2076", + "turn90ccw_anim": "2076", + "attack_speed": "4", + "two_handed": "true", + "turn180_anim": "2076", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "2075,2075,2075,2075", + "grand_exchange_price": "108029", + "stand_anim": "2074", + "run_anim": "2077", + "archery_ticket_price": "0", + "id": "4937", + "stand_turn_anim": "823", + "bonuses": "0,0,0,0,84,0,0,0,0,0,0,0,0,0,0", + "requirements": "{4,70}", + "durability": null, + "weight": "2", + "weapon_interface": "17", + "equip_audio": "2244", + "render_anim": "372", + "attack_audios": "2700,0,0,0", + "name": "Karil's x-bow 25" + }, + { + "requirements": "{4,70}", + "ge_buy_limit": "10", + "turn90cw_anim": "2076", + "examine": "Karil the Tainted's repeating crossbow.", + "walk_anim": "2076", + "durability": null, + "weight": "2", + "turn90ccw_anim": "2076", + "attack_speed": "4", + "two_handed": "true", + "weapon_interface": "17", + "turn180_anim": "2076", + "equip_audio": "2244", + "render_anim": "372", + "equipment_slot": "3", + "grand_exchange_price": "106300", + "stand_anim": "2074", + "name": "Karil's x-bow 0", + "tradeable": "true", + "run_anim": "2077", + "archery_ticket_price": "0", + "id": "4938", + "stand_turn_anim": "823" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "106300", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Karil's x-bow 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4939", + "equip_audio": "" + }, + { + "requirements": "{1,70}-{4,70}", + "examine": "Karil the Tainted's leather body armour.", + "durability": null, + "weight": "6", + "absorb": "0,10,5", + "equip_audio": "2241", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "983428", + "name": "Karil's top 100", + "archery_ticket_price": "0", + "id": "4940", + "bonuses": "0,0,0,-15,30,47,42,50,65,57,60,0,0,0,0" + }, + { + "requirements": "{1,70}-{4,70}", + "examine": "Karil the Tainted's leather body armour.", + "durability": null, + "weight": "6", + "absorb": "0,10,5", + "equip_audio": "2241", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "983428", + "name": "Karil's top 75", + "archery_ticket_price": "0", + "id": "4941", + "bonuses": "0,0,0,-15,30,47,42,50,65,57,60,0,0,0,0" + }, + { + "requirements": "{1,70}-{4,70}", + "examine": "Karil the Tainted's leather body armour.", + "durability": null, + "weight": "6", + "absorb": "0,10,5", + "equip_audio": "2241", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "983428", + "name": "Karil's top 50", + "archery_ticket_price": "0", + "id": "4942", + "bonuses": "0,0,0,-15,30,47,42,50,65,57,60,0,0,0,0" + }, + { + "requirements": "{1,70}-{4,70}", + "examine": "Karil the Tainted's leather body armour.", + "durability": null, + "weight": "6", + "absorb": "0,10,5", + "equip_audio": "2241", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "983428", + "name": "Karil's top 25", + "archery_ticket_price": "0", + "id": "4943", + "bonuses": "0,0,0,-15,30,47,42,50,65,57,60,0,0,0,0" + }, + { + "requirements": "{1,70}-{4,70}", + "ge_buy_limit": "1", + "examine": "Karil the Tainted's leather body armour.", + "durability": null, + "weight": "6", + "absorb": "0,10,5", + "equip_audio": "2241", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "1500000", + "name": "Karil's top 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4944" + }, + { + "ge_buy_limit": "1", + "grand_exchange_price": "1500000", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Karil's top 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4945" + }, + { + "requirements": "{1,70}-{4,70}", + "examine": "Karil the Tainted's leather skirt.", + "grand_exchange_price": "85135", + "durability": null, + "name": "Karil's skirt 100", + "weight": "2", + "archery_ticket_price": "0", + "id": "4946", + "absorb": "0,7,3", + "bonuses": "0,0,0,-10,17,26,20,28,35,33,30,0,0,0,0", + "equip_audio": "2238", + "equipment_slot": "7" + }, + { + "requirements": "{1,70}-{4,70}", + "examine": "Karil the Tainted's leather skirt.", + "grand_exchange_price": "85135", + "durability": null, + "name": "Karil's skirt 75", + "weight": "2", + "archery_ticket_price": "0", + "id": "4947", + "absorb": "0,7,3", + "bonuses": "0,0,0,-10,17,26,20,28,35,33,30,0,0,0,0", + "equip_audio": "2238", + "equipment_slot": "7" + }, + { + "requirements": "{1,70}-{4,70}", + "examine": "Karil the Tainted's leather skirt.", + "grand_exchange_price": "85135", + "durability": null, + "name": "Karil's skirt 50", + "weight": "2", + "archery_ticket_price": "0", + "id": "4948", + "absorb": "0,7,3", + "bonuses": "0,0,0,-10,17,26,20,28,35,33,30,0,0,0,0", + "equip_audio": "2238", + "equipment_slot": "7" + }, + { + "requirements": "{1,70}-{4,70}", + "examine": "Karil the Tainted's leather skirt.", + "grand_exchange_price": "85135", + "durability": null, + "name": "Karil's skirt 25", + "weight": "2", + "archery_ticket_price": "0", + "id": "4949", + "absorb": "0,7,3", + "bonuses": "0,0,0,-10,17,26,20,28,35,33,30,0,0,0,0", + "equip_audio": "2238", + "equipment_slot": "7" + }, + { + "requirements": "{1,70}-{4,70}", + "ge_buy_limit": "1", + "examine": "Karil the Tainted's leather skirt.", + "durability": null, + "weight": "2", + "absorb": "0,7,3", + "equip_audio": "2238", + "equipment_slot": "7", + "grand_exchange_price": "153100", + "name": "Karil's skirt 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4950" + }, + { + "ge_buy_limit": "1", + "grand_exchange_price": "153100", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Karil's skirt 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4951" + }, + { + "remove_head": "true", + "requirements": "{1,70}", + "examine": "Torag the Corrupted's helm.", + "durability": null, + "weight": "5", + "absorb": "2,0,5", + "equip_audio": "2240", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "71798", + "name": "Torag's helm 100", + "archery_ticket_price": "0", + "id": "4952", + "bonuses": "0,0,0,-6,-2,55,58,54,-1,62,15,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,70}", + "examine": "Torag the Corrupted's helm.", + "durability": null, + "weight": "5", + "absorb": "2,0,5", + "equip_audio": "2240", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "71798", + "name": "Torag's helm 75", + "archery_ticket_price": "0", + "id": "4953", + "bonuses": "0,0,0,-6,-2,55,58,54,-1,62,15,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,70}", + "examine": "Torag the Corrupted's helm.", + "durability": null, + "weight": "5", + "absorb": "2,0,5", + "equip_audio": "2240", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "71798", + "name": "Torag's helm 50", + "archery_ticket_price": "0", + "id": "4954", + "bonuses": "0,0,0,-6,-2,55,58,54,-1,62,15,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,70}", + "examine": "Torag the Corrupted's helm.", + "durability": null, + "weight": "5", + "absorb": "2,0,5", + "equip_audio": "2240", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "71798", + "name": "Torag's helm 25", + "archery_ticket_price": "0", + "id": "4955", + "bonuses": "0,0,0,-6,-2,55,58,54,-1,62,15,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,70}", + "ge_buy_limit": "10", + "examine": "Torag the Corrupted's helm.", + "durability": null, + "weight": "5", + "absorb": "2,0,5", + "equip_audio": "2240", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "78200", + "name": "Torag's helm 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4956" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "78200", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Torag's helm 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4957" + }, + { + "requirements": "{0,70}-{2,70}", + "examine": "Torag the Corrupted's twin hammers.", + "durability": null, + "weight": "3", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "10", + "equip_audio": "2233", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "2068,2068,2068,2068", + "grand_exchange_price": "95800", + "attack_audios": "1332,0,0,0", + "name": "Torag's hammer 100", + "archery_ticket_price": "0", + "id": "4958", + "bonuses": "-4,-4,85,-4,0,0,0,0,0,0,0,72,0,0,0" + }, + { + "requirements": "{0,70}-{2,70}", + "examine": "Torag the Corrupted's twin hammers.", + "durability": null, + "weight": "3", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "10", + "equip_audio": "2233", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "2068,2068,2068,2068", + "grand_exchange_price": "95800", + "attack_audios": "1332,0,0,0", + "name": "Torag's hammer 75", + "archery_ticket_price": "0", + "id": "4959", + "bonuses": "-4,-4,85,-4,0,0,0,0,0,0,0,72,0,0,0" + }, + { + "requirements": "{0,70}-{2,70}", + "examine": "Torag the Corrupted's twin hammers.", + "durability": null, + "weight": "3", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "10", + "equip_audio": "2233", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "2068,2068,2068,2068", + "grand_exchange_price": "95800", + "attack_audios": "1332,0,0,0", + "name": "Torag's hammer 50", + "archery_ticket_price": "0", + "id": "4960", + "bonuses": "-4,-4,85,-4,0,0,0,0,0,0,0,72,0,0,0" + }, + { + "requirements": "{0,70}-{2,70}", + "examine": "Torag the Corrupted's twin hammers.", + "durability": null, + "weight": "3", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "10", + "equip_audio": "2233", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "2068,2068,2068,2068", + "grand_exchange_price": "95800", + "attack_audios": "1332,0,0,0", + "name": "Torag's hammer 25", + "archery_ticket_price": "0", + "id": "4961", + "bonuses": "-4,-4,85,-4,0,0,0,0,0,0,0,72,0,0,0" + }, + { + "requirements": "{0,70}-{2,70}", + "ge_buy_limit": "10", + "examine": "Torag the Corrupted's twin hammers.", + "durability": null, + "weight": "3", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "10", + "equip_audio": "2233", + "equipment_slot": "3", + "grand_exchange_price": "95600", + "attack_audios": "1332,0,0,0", + "name": "Torag's hammer 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4962" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "95600", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Torag's hammer 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4963" + }, + { + "requirements": "{1,70}", + "examine": "Torag the Corrupted's platebody armour.", + "durability": null, + "weight": "9", + "absorb": "5,0,10", + "equip_audio": "2240", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "297733", + "name": "Torag's body 100", + "archery_ticket_price": "0", + "id": "4964", + "bonuses": "0,0,0,-30,-10,122,120,107,-6,132,60,0,0,0,0" + }, + { + "requirements": "{1,70}", + "examine": "Torag the Corrupted's platebody armour.", + "durability": null, + "weight": "9", + "absorb": "5,0,10", + "equip_audio": "2240", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "297733", + "name": "Torag's body 75", + "archery_ticket_price": "0", + "id": "4965", + "bonuses": "0,0,0,-30,-10,122,120,107,-6,132,60,0,0,0,0" + }, + { + "requirements": "{1,70}", + "examine": "Torag the Corrupted's platebody armour.", + "durability": null, + "weight": "9", + "absorb": "5,0,10", + "equip_audio": "2240", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "297733", + "name": "Torag's body 50", + "archery_ticket_price": "0", + "id": "4966", + "bonuses": "0,0,0,-30,-10,122,120,107,-6,132,60,0,0,0,0" + }, + { + "requirements": "{1,70}", + "examine": "Torag the Corrupted's platebody armour.", + "durability": null, + "weight": "9", + "absorb": "5,0,10", + "equip_audio": "2240", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "297733", + "name": "Torag's body 25", + "archery_ticket_price": "0", + "id": "4967", + "bonuses": "0,0,0,-30,-10,122,120,107,-6,132,60,0,0,0,0" + }, + { + "requirements": "{1,70}", + "ge_buy_limit": "10", + "examine": "Torag the Corrupted's platebody armour.", + "durability": null, + "weight": "9", + "absorb": "5,0,10", + "equip_audio": "2240", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "271600", + "name": "Torag's body 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4968" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "271600", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Torag's body 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4969" + }, + { + "requirements": "{1,70}", + "examine": "Torag the Corrupted's plate leg armour.", + "grand_exchange_price": "384813", + "durability": null, + "name": "Torag's legs 100", + "weight": "9", + "archery_ticket_price": "0", + "id": "4970", + "absorb": "3,0,7", + "bonuses": "0,0,0,-21,-7,85,82,83,-4,92,30,0,0,0,0", + "equip_audio": "2242", + "equipment_slot": "7" + }, + { + "requirements": "{1,70}", + "examine": "Torag the Corrupted's plate leg armour.", + "grand_exchange_price": "384813", + "durability": null, + "name": "Torag's legs 75", + "weight": "9", + "archery_ticket_price": "0", + "id": "4971", + "absorb": "3,0,7", + "bonuses": "0,0,0,-21,-7,85,82,83,-4,92,30,0,0,0,0", + "equip_audio": "2242", + "equipment_slot": "7" + }, + { + "requirements": "{1,70}", + "examine": "Torag the Corrupted's plate leg armour.", + "grand_exchange_price": "384813", + "durability": null, + "name": "Torag's legs 50", + "weight": "9", + "archery_ticket_price": "0", + "id": "4972", + "absorb": "3,0,7", + "bonuses": "0,0,0,-21,-7,85,82,83,-4,92,30,0,0,0,0", + "equip_audio": "2242", + "equipment_slot": "7" + }, + { + "requirements": "{1,70}", + "examine": "Torag the Corrupted's plate leg armour.", + "grand_exchange_price": "384813", + "durability": null, + "name": "Torag's legs 25", + "weight": "9", + "archery_ticket_price": "0", + "id": "4973", + "absorb": "3,0,7", + "bonuses": "0,0,0,-21,-7,85,82,83,-4,92,30,0,0,0,0", + "equip_audio": "2242", + "equipment_slot": "7" + }, + { + "requirements": "{1,70}", + "ge_buy_limit": "10", + "examine": "Torag the Corrupted's plate leg armour.", + "durability": null, + "weight": "9", + "absorb": "3,0,7", + "equip_audio": "2242", + "equipment_slot": "7", + "grand_exchange_price": "371300", + "name": "Torag's legs 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4974" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "371300", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Torag's legs 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4975" + }, + { + "remove_head": "true", + "requirements": "{1,70}", + "examine": "Verac the Defiled's helm.", + "durability": null, + "weight": "1", + "absorb": "2,0,5", + "equip_audio": "2240", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "459537", + "name": "Verac's helm 100", + "archery_ticket_price": "0", + "id": "4976", + "bonuses": "0,0,0,-6,-2,55,58,54,0,56,15,0,3,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,70}", + "examine": "Verac the Defiled's helm.", + "durability": null, + "weight": "1", + "absorb": "2,0,5", + "equip_audio": "2240", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "459537", + "name": "Verac's helm 75", + "archery_ticket_price": "0", + "id": "4977", + "bonuses": "0,0,0,-6,-2,55,58,54,0,56,15,0,3,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,70}", + "examine": "Verac the Defiled's helm.", + "durability": null, + "weight": "1", + "absorb": "2,0,5", + "equip_audio": "2240", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "459537", + "name": "Verac's helm 50", + "archery_ticket_price": "0", + "id": "4978", + "bonuses": "0,0,0,-6,-2,55,58,54,0,56,15,0,3,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,70}", + "examine": "Verac the Defiled's helm.", + "durability": null, + "weight": "1", + "absorb": "2,0,5", + "equip_audio": "2240", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "459537", + "name": "Verac's helm 25", + "archery_ticket_price": "0", + "id": "4979", + "bonuses": "0,0,0,-6,-2,55,58,54,0,56,15,0,3,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,70}", + "ge_buy_limit": "10", + "examine": "Verac the Defiled's helm.", + "durability": null, + "weight": "1", + "absorb": "2,0,5", + "equip_audio": "2240", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "648900", + "name": "Verac's helm 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4980" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "648900", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Verac's helm 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4981" + }, + { + "turn90cw_anim": "2060", + "examine": "Verac the Defiled's flail.", + "walk_anim": "1830", + "turn90ccw_anim": "2060", + "attack_speed": "5", + "two_handed": "true", + "turn180_anim": "2060", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "2062,2062,2062,2062", + "grand_exchange_price": "95474", + "stand_anim": "1832", + "run_anim": "1831", + "archery_ticket_price": "0", + "id": "4982", + "stand_turn_anim": "823", + "bonuses": "68,-2,82,0,0,0,0,0,0,0,0,72,6,0,0", + "requirements": "{0,70}", + "durability": null, + "weight": "2", + "weapon_interface": "8", + "equip_audio": "2246", + "render_anim": "1426", + "attack_audios": "1323,0,0,0", + "name": "Verac's flail 100" + }, + { + "turn90cw_anim": "2060", + "examine": "Verac the Defiled's flail.", + "walk_anim": "1830", + "turn90ccw_anim": "2060", + "attack_speed": "5", + "two_handed": "true", + "turn180_anim": "2060", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "2062,2062,2062,2062", + "grand_exchange_price": "95474", + "stand_anim": "1832", + "run_anim": "1831", + "archery_ticket_price": "0", + "id": "4983", + "stand_turn_anim": "823", + "bonuses": "68,-2,82,0,0,0,0,0,0,0,0,72,6,0,0", + "requirements": "{0,70}", + "durability": null, + "weight": "2", + "weapon_interface": "8", + "equip_audio": "2246", + "render_anim": "1426", + "attack_audios": "1323,0,0,0", + "name": "Verac's flail 75" + }, + { + "turn90cw_anim": "2060", + "examine": "Verac the Defiled's flail.", + "walk_anim": "1830", + "turn90ccw_anim": "2060", + "attack_speed": "5", + "two_handed": "true", + "turn180_anim": "2060", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "2062,2062,2062,2062", + "grand_exchange_price": "95474", + "stand_anim": "1832", + "run_anim": "1831", + "archery_ticket_price": "0", + "id": "4984", + "stand_turn_anim": "823", + "bonuses": "68,-2,82,0,0,0,0,0,0,0,0,72,6,0,0", + "requirements": "{0,70}", + "durability": null, + "weight": "2", + "weapon_interface": "8", + "equip_audio": "2246", + "render_anim": "1426", + "attack_audios": "1323,0,0,0", + "name": "Verac's flail 50" + }, + { + "turn90cw_anim": "2060", + "examine": "Verac the Defiled's flail.", + "walk_anim": "1830", + "turn90ccw_anim": "2060", + "attack_speed": "5", + "two_handed": "true", + "turn180_anim": "2060", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "2062,2062,2062,2062", + "grand_exchange_price": "95474", + "stand_anim": "1832", + "run_anim": "1831", + "archery_ticket_price": "0", + "id": "4985", + "stand_turn_anim": "823", + "bonuses": "68,-2,82,0,0,0,0,0,0,0,0,72,6,0,0", + "requirements": "{0,70}", + "durability": null, + "weight": "2", + "weapon_interface": "8", + "equip_audio": "2246", + "render_anim": "1426", + "attack_audios": "1323,0,0,0", + "name": "Verac's flail 25" + }, + { + "requirements": "{0,70}", + "ge_buy_limit": "10", + "turn90cw_anim": "2060", + "examine": "Verac the Defiled's flail.", + "walk_anim": "1830", + "durability": null, + "weight": "2", + "turn90ccw_anim": "2060", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "8", + "turn180_anim": "2060", + "equip_audio": "2246", + "render_anim": "1426", + "equipment_slot": "3", + "grand_exchange_price": "95500", + "stand_anim": "1832", + "attack_audios": "1323,0,0,0", + "tradeable": "true", + "name": "Verac's flail 0", + "run_anim": "1831", + "archery_ticket_price": "0", + "id": "4986", + "stand_turn_anim": "823" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "95500", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Verac's flail 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4987" + }, + { + "requirements": "{1,70}", + "examine": "Verac the Defiled's brassard.", + "durability": null, + "weight": "5", + "absorb": "5,0,10", + "equip_audio": "2241", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "177963", + "name": "Verac's top 100", + "archery_ticket_price": "0", + "id": "4988", + "bonuses": "0,0,0,-6,-2,81,95,85,0,81,60,0,5,0,0" + }, + { + "requirements": "{1,70}", + "examine": "Verac the Defiled's brassard.", + "durability": null, + "weight": "5", + "absorb": "5,0,10", + "equip_audio": "2241", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "177963", + "name": "Verac's top 75", + "archery_ticket_price": "0", + "id": "4989", + "bonuses": "0,0,0,-6,-2,81,95,85,0,81,60,0,5,0,0" + }, + { + "requirements": "{1,70}", + "examine": "Verac the Defiled's brassard.", + "durability": null, + "weight": "5", + "absorb": "5,0,10", + "equip_audio": "2241", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "177963", + "name": "Verac's top 50", + "archery_ticket_price": "0", + "id": "4990", + "bonuses": "0,0,0,-6,-2,81,95,85,0,81,60,0,5,0,0" + }, + { + "requirements": "{1,70}", + "examine": "Verac the Defiled's brassard.", + "durability": null, + "weight": "5", + "absorb": "5,0,10", + "equip_audio": "2241", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "177963", + "name": "Verac's top 25", + "archery_ticket_price": "0", + "id": "4991", + "bonuses": "0,0,0,-6,-2,81,95,85,0,81,60,0,5,0,0" + }, + { + "requirements": "{1,70}", + "ge_buy_limit": "10", + "examine": "Verac the Defiled's brassard.", + "durability": null, + "weight": "5", + "absorb": "5,0,10", + "equip_audio": "2241", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "174000", + "name": "Verac's top 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4992" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "174000", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Verac's top 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4993" + }, + { + "requirements": "{1,70}", + "examine": "Verac the Defiled's plate skirt.", + "grand_exchange_price": "297540", + "durability": null, + "name": "Verac's skirt 100", + "weight": "5", + "archery_ticket_price": "0", + "id": "4994", + "absorb": "3,0,7", + "bonuses": "0,0,0,-21,-7,85,82,83,0,84,30,0,4,0,0", + "equip_audio": "2242", + "equipment_slot": "7" + }, + { + "requirements": "{1,70}", + "examine": "Verac the Defiled's plate skirt.", + "grand_exchange_price": "297540", + "durability": null, + "name": "Verac's skirt 75", + "weight": "5", + "archery_ticket_price": "0", + "id": "4995", + "absorb": "3,0,7", + "bonuses": "0,0,0,-21,-7,85,82,83,0,84,30,0,4,0,0", + "equip_audio": "2242", + "equipment_slot": "7" + }, + { + "requirements": "{1,70}", + "examine": "Verac the Defiled's plate skirt.", + "grand_exchange_price": "297540", + "durability": null, + "name": "Verac's skirt 50", + "weight": "5", + "archery_ticket_price": "0", + "id": "4996", + "absorb": "3,0,7", + "bonuses": "0,0,0,-21,-7,85,82,83,0,84,30,0,4,0,0", + "equip_audio": "2242", + "equipment_slot": "7" + }, + { + "requirements": "{1,70}", + "examine": "Verac the Defiled's plate skirt.", + "grand_exchange_price": "297540", + "durability": null, + "name": "Verac's skirt 25", + "weight": "5", + "archery_ticket_price": "0", + "id": "4997", + "absorb": "3,0,7", + "bonuses": "0,0,0,-21,-7,85,82,83,0,84,30,0,4,0,0", + "equip_audio": "2242", + "equipment_slot": "7" + }, + { + "requirements": "{1,70}", + "ge_buy_limit": "10", + "examine": "Verac the Defiled's plate skirt.", + "durability": null, + "weight": "5", + "absorb": "3,0,7", + "equip_audio": "2242", + "equipment_slot": "7", + "grand_exchange_price": "321600", + "name": "Verac's skirt 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4998" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "321600", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Verac's skirt 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "4999" + }, + { + "ge_buy_limit": "1000", + "examine": "It's incredibly slimy.", + "grand_exchange_price": "373", + "durability": null, + "name": "Raw cave eel", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "5001" + }, + { + "ge_buy_limit": "1000", + "examine": "It's a bit slimy.", + "grand_exchange_price": "164", + "durability": null, + "name": "Cave eel", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "5003" + }, + { + "examine": "That's disgusting!", + "durability": null, + "name": "Frog spawn", + "archery_ticket_price": "0", + "id": "5004" + }, + { + "durability": null, + "name": "Raw cave eel", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5005" + }, + { + "durability": null, + "name": "Burnt cave eel", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5006" + }, + { + "durability": null, + "name": "Cave eel", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5007" + }, + { + "examine": "A book about the ancient goblin tribes.", + "durability": null, + "name": "Goblin symbol book", + "weight": "1", + "archery_ticket_price": "0", + "id": "5009" + }, + { + "examine": "You found the Lumbridge silverware in the HAM cave.", + "durability": null, + "name": "Silverware", + "archery_ticket_price": "0", + "id": "5011" + }, + { + "examine": "A peace treaty between Lumbridge and the Cave Goblins.", + "durability": null, + "name": "Peace treaty", + "archery_ticket_price": "0", + "id": "5012" + }, + { + "shop_price": "900", + "examine": "A helmet with a lamp on it.", + "grand_exchange_price": "380", + "durability": null, + "name": "Mining helmet", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "5013", + "bonuses": "0,0,0,-3,-1,4,5,3,-1,4,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "requirements": "{11,65}", + "shop_price": "900", + "ge_buy_limit": "100", + "examine": "A helmet with an unlit lamp on it.", + "durability": null, + "weight": "1", + "equipment_slot": "0", + "grand_exchange_price": "342", + "name": "Mining helmet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5014", + "bonuses": "0,0,0,-3,-1,4,5,3,-1,4,0,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "342", + "durability": null, + "name": "Mining helmet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5015" + }, + { + "ge_buy_limit": "100", + "shop_price": "600", + "turn90cw_anim": "1207", + "examine": "Basic but brutal!", + "walk_anim": "1205", + "durability": null, + "weight": "1.3", + "turn90ccw_anim": "1208", + "attack_speed": "6", + "two_handed": "false", + "weapon_interface": "14", + "turn180_anim": "1206", + "equip_audio": "2247", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "219", + "stand_anim": "813", + "tradeable": "true", + "name": "Bone spear", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "5016", + "stand_turn_anim": "1209", + "bonuses": "11,11,11,0,0,1,1,0,0,0,0,13,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "219", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Bone spear", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5017" + }, + { + "shop_price": "600", + "ge_buy_limit": "100", + "examine": "Basic but brutal!", + "durability": null, + "weight": "0.9", + "attack_speed": "6", + "weapon_interface": "10", + "defence_anim": "403", + "equipment_slot": "3", + "attack_anims": "401,401,400,401", + "grand_exchange_price": "384", + "name": "Bone club", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5018", + "bonuses": "-4,-4,16,-4,0,0,0,0,0,0,0,15,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "384", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Bone club", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5019" + }, + { + "shop_price": "150", + "examine": "A ticket to take you from the dwarven mines under Ice Mountain to Keldagrim.", + "durability": null, + "name": "Minecart ticket", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "5020" + }, + { + "shop_price": "150", + "examine": "A ticket to take you from the dwarven mines under Ice Mountain to Keldagrim.", + "durability": null, + "name": "Minecart ticket", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "5021" + }, + { + "shop_price": "150", + "examine": "A ticket to take you from the dwarven mines under Ice Mountain to Keldagrim.", + "durability": null, + "name": "Minecart ticket", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "5022" + }, + { + "shop_price": "150", + "examine": "A ticket to take you from the dwarven mines under Ice Mountain to Keldagrim.", + "durability": null, + "name": "Minecart ticket", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "5023" + }, + { + "remove_sleeves": "true", + "shop_price": "812", + "ge_buy_limit": "100", + "examine": "Far too small to wear.", + "grand_exchange_price": "710", + "durability": null, + "name": "Woven top", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "5024", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "710", + "durability": null, + "name": "Woven top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5025" + }, + { + "remove_sleeves": "true", + "shop_price": "812", + "ge_buy_limit": "100", + "examine": "Yellow top, too small for me.", + "grand_exchange_price": "908", + "durability": null, + "name": "Woven top", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "5026", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "908", + "durability": null, + "name": "Woven top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5027" + }, + { + "remove_sleeves": "true", + "shop_price": "812", + "ge_buy_limit": "100", + "examine": "Blue top, very tiny.", + "grand_exchange_price": "1357", + "durability": null, + "name": "Woven top", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "5028", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1357", + "durability": null, + "name": "Woven top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5029" + }, + { + "remove_sleeves": "true", + "ge_buy_limit": "100", + "grand_exchange_price": "867", + "examine": "Tiny!", + "durability": null, + "name": "Shirt", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "5030", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "867", + "durability": null, + "name": "Shirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5031" + }, + { + "remove_sleeves": "true", + "ge_buy_limit": "100", + "grand_exchange_price": "1023", + "examine": "Tiny!", + "durability": null, + "name": "Shirt", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "5032", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1023", + "durability": null, + "name": "Shirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5033" + }, + { + "remove_sleeves": "true", + "ge_buy_limit": "100", + "grand_exchange_price": "1282", + "examine": "Tiny!", + "durability": null, + "name": "Shirt", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "5034", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1282", + "durability": null, + "name": "Shirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5035" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "746", + "examine": "A pair of long dwarven trousers... long for dwarves, of course.", + "durability": null, + "name": "Trousers", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "5036", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "746", + "durability": null, + "name": "Trousers", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5037" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "378", + "examine": "A pair of long dwarven trousers... long for dwarves, of course.", + "durability": null, + "name": "Trousers", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "5038", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "378", + "durability": null, + "name": "Trousers", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5039" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "442", + "examine": "A pair of long dwarven trousers... long for dwarves, of course.", + "durability": null, + "name": "Trousers", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "5040", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "442", + "durability": null, + "name": "Trousers", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5041" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1191", + "examine": "These look great, on dwarves!", + "durability": null, + "name": "Shorts", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "5042", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1191", + "durability": null, + "name": "Shorts", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5043" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1229", + "examine": "Yellow shorts. Far too small for you.", + "durability": null, + "name": "Shorts", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "5044", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1229", + "durability": null, + "name": "Shorts", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5045" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2582", + "examine": "Blue shorts, these would look great on dwarves!", + "durability": null, + "name": "Shorts", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "5046", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2582", + "durability": null, + "name": "Shorts", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5047" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "681", + "examine": "A brown skirt. Size small!", + "durability": null, + "name": "Skirt", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "5048", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "681", + "durability": null, + "name": "Skirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5049" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1151", + "examine": "A blue skirt.", + "durability": null, + "name": "Skirt", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "5050", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1151", + "durability": null, + "name": "Skirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5051" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "803", + "examine": "Lilac skirt.", + "durability": null, + "name": "Skirt", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "5052", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "803", + "durability": null, + "name": "Skirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5053" + }, + { + "examine": "A short angry guy.", + "durability": null, + "name": "Dwarf", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5054" + }, + { + "durability": null, + "name": "Dwarf", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5055" + }, + { + "examine": "This looks very rusty and worn;", + "durability": null, + "name": "Dwarven battleaxe", + "archery_ticket_price": "0", + "id": "5056" + }, + { + "examine": "This looks very rusty and worn;", + "durability": null, + "name": "Dwarven battleaxe", + "archery_ticket_price": "0", + "id": "5057" + }, + { + "examine": "This looks very rusty and worn;", + "durability": null, + "name": "Dwarven battleaxe", + "archery_ticket_price": "0", + "id": "5058" + }, + { + "examine": "This looks very rusty and worn;", + "durability": null, + "name": "Dwarven battleaxe", + "archery_ticket_price": "0", + "id": "5059" + }, + { + "examine": "This looks very rusty and worn;", + "durability": null, + "name": "Dwarven battleaxe", + "archery_ticket_price": "0", + "id": "5060", + "equip_audio": "2232", + "equipment_slot": "3" + }, + { + "examine": "This looks very rusty and worn;", + "durability": null, + "name": "Dwarven battleaxe", + "archery_ticket_price": "0", + "id": "5061", + "equip_audio": "2232", + "equipment_slot": "3" + }, + { + "examine": "One of a pair I assume.", + "durability": null, + "name": "Left boot", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "5062" + }, + { + "examine": "A good looking boot, for the right foot. Literally.", + "durability": null, + "name": "Right boot", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "5063" + }, + { + "examine": "A lovely pair of boots.", + "durability": null, + "name": "Exquisite boots", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "5064" + }, + { + "examine": "An old library book. It bears the title 'Scholars to Dwarven Costumes'.", + "durability": null, + "name": "Book on costumes", + "archery_ticket_price": "0", + "id": "5065" + }, + { + "examine": "These notes are from a meeting of the Keldagrim Consortium.", + "durability": null, + "name": "Meeting notes", + "archery_ticket_price": "0", + "id": "5066" + }, + { + "examine": "Clothes for the sculptor's model.", + "durability": null, + "name": "Exquisite clothes", + "archery_ticket_price": "0", + "id": "5067" + }, + { + "examine": "A master at farming.", + "durability": null, + "name": "Master farmer", + "archery_ticket_price": "0", + "id": "5068" + }, + { + "examine": "Full: ", + "durability": null, + "name": "Bird's nest", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "5070" + }, + { + "examine": "Full: ", + "durability": null, + "name": "Bird's nest", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "5071" + }, + { + "examine": "Full: ", + "durability": null, + "name": "Bird's nest", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "5072" + }, + { + "examine": "Full: ", + "durability": null, + "name": "Bird's nest", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "5073" + }, + { + "examine": "Full: ", + "durability": null, + "name": "Bird's nest", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "5074" + }, + { + "examine": "Full: ", + "durability": null, + "name": "Bird's nest", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "5075" + }, + { + "examine": "A red bird's egg.", + "durability": null, + "name": "Bird's egg", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "5076" + }, + { + "examine": "A blue bird's egg.", + "durability": null, + "name": "Bird's egg", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "5077" + }, + { + "examine": "A green bird's egg.", + "durability": null, + "name": "Bird's egg", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "5078" + }, + { + "requirements": "{2,19}", + "shop_price": "84", + "ge_buy_limit": "100", + "examine": "A marigold seed - plant in flower patch.", + "grand_exchange_price": "8", + "durability": null, + "name": "Marigold seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5096" + }, + { + "requirements": "{11,19}", + "shop_price": "98", + "ge_buy_limit": "100", + "examine": "A rosemary seed - plant in flower patch.", + "grand_exchange_price": "3", + "durability": null, + "name": "Rosemary seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5097" + }, + { + "requirements": "{24,19}", + "shop_price": "14", + "ge_buy_limit": "100", + "examine": "A nasturtium seed - plant in flower patch.", + "grand_exchange_price": "1", + "durability": null, + "name": "Nasturtium seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5098" + }, + { + "requirements": "{19,25}", + "ge_buy_limit": "100", + "examine": "A woad seed - plant in flower patch.", + "grand_exchange_price": "1", + "durability": null, + "name": "Woad seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5099" + }, + { + "requirements": "{19,26}", + "shop_price": "70", + "ge_buy_limit": "100", + "examine": "A limpwurt seed - plant in flower patch.", + "grand_exchange_price": "273", + "durability": null, + "name": "Limpwurt seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5100" + }, + { + "requirements": "{10,19}", + "ge_buy_limit": "100", + "examine": "A redberry seed - Plant in a bush patch.", + "grand_exchange_price": "1", + "durability": null, + "name": "Redberry seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5101" + }, + { + "requirements": "{22,19}", + "ge_buy_limit": "100", + "examine": "A cadavaberry seed - Plant in a bush patch.", + "grand_exchange_price": "1", + "durability": null, + "name": "Cadavaberry seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5102" + }, + { + "requirements": "{19,36}", + "ge_buy_limit": "100", + "examine": "A dwellberry seed - Plant in a bush patch.", + "grand_exchange_price": "1", + "durability": null, + "name": "Dwellberry seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5103" + }, + { + "requirements": "{19,48}", + "shop_price": "22", + "ge_buy_limit": "100", + "examine": "A jangerberry bush seed - plant in a bush patch.", + "grand_exchange_price": "2", + "durability": null, + "name": "Jangerberry seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5104" + }, + { + "requirements": "{19,59}", + "ge_buy_limit": "100", + "examine": "A whiteberry bush seed - plant in a bush patch.", + "grand_exchange_price": "8", + "durability": null, + "name": "Whiteberry seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5105" + }, + { + "requirements": "{19,70}", + "ge_buy_limit": "100", + "examine": "A poison ivy bush seed - plant in a bush patch.", + "grand_exchange_price": "38", + "durability": null, + "name": "Poison ivy seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5106" + }, + { + "requirements": "{19,55}", + "shop_price": "29", + "ge_buy_limit": "100", + "examine": "A Cactus seed - plant in a cactus patch.", + "grand_exchange_price": "10", + "durability": null, + "name": "Cactus seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5280" + }, + { + "requirements": "{19,63}", + "ge_buy_limit": "100", + "examine": "Also known as Deadly Nightshade - plant in a belladonna patch.", + "grand_exchange_price": "24", + "durability": null, + "name": "Belladonna seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5281" + }, + { + "requirements": "{19,53}", + "ge_buy_limit": "100", + "grand_exchange_price": "2", + "durability": null, + "name": "Mushroom spore", + "archery_ticket_price": "0", + "id": "5282" + }, + { + "requirements": "{19,27}", + "ge_buy_limit": "100", + "examine": "Plant this in a plantpot of soil to grow a sapling.", + "grand_exchange_price": "4", + "durability": null, + "name": "Apple tree seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5283" + }, + { + "requirements": "{19,33}", + "ge_buy_limit": "100", + "examine": "Plant this in a plantpot of soil to grow a sapling.", + "grand_exchange_price": "5", + "durability": null, + "name": "Banana tree seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5284" + }, + { + "requirements": "{19,39}", + "ge_buy_limit": "100", + "examine": "Plant this in a plantpot of soil to grow a sapling.", + "grand_exchange_price": "30", + "durability": null, + "name": "Orange tree seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5285" + }, + { + "requirements": "{19,42}", + "ge_buy_limit": "100", + "examine": "Plant this in a plant pot of soil to grow a sapling.", + "grand_exchange_price": "265", + "durability": null, + "name": "Curry tree seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5286" + }, + { + "requirements": "{19,51}", + "ge_buy_limit": "100", + "examine": "Plant this in a plantpot of soil to grow a sapling.", + "grand_exchange_price": "13700", + "durability": null, + "name": "Pineapple seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5287" + }, + { + "requirements": "{19,57}", + "ge_buy_limit": "100", + "examine": "Plant this in a plant pot of soil to grow a sapling.", + "grand_exchange_price": "41200", + "durability": null, + "name": "Papaya tree seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5288" + }, + { + "requirements": "{19,68}", + "shop_price": "35000", + "ge_buy_limit": "100", + "examine": "Plant in a plantpot of soil to grow a sapling.", + "grand_exchange_price": "105100", + "durability": null, + "name": "Palm tree seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5289" + }, + { + "requirements": "{19,72}", + "shop_price": "35000", + "ge_buy_limit": "100", + "examine": "Plant in a plantpot of soil to grow a sapling.", + "grand_exchange_price": "32000", + "durability": null, + "name": "Calquat tree seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5290" + }, + { + "requirements": "{9,19}", + "ge_buy_limit": "100", + "examine": "A guam seed - plant in a herb patch.", + "grand_exchange_price": "5", + "durability": null, + "name": "Guam seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5291" + }, + { + "requirements": "{14,19}", + "ge_buy_limit": "100", + "examine": "A marrentill seed - plant in a herb patch.", + "grand_exchange_price": "5", + "durability": null, + "name": "Marrentill seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5292" + }, + { + "requirements": "{19,19}", + "ge_buy_limit": "100", + "examine": "A tarromin seed - plant in a herb patch.", + "grand_exchange_price": "1", + "durability": null, + "name": "Tarromin seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5293" + }, + { + "requirements": "{19,26}", + "ge_buy_limit": "100", + "examine": "A harralander seed - plant in a herb patch.", + "grand_exchange_price": "4", + "durability": null, + "name": "Harralander seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5294" + }, + { + "requirements": "{19,32}", + "shop_price": "4000", + "ge_buy_limit": "100", + "examine": "A Ranarr seed - plant in a herb patch.", + "grand_exchange_price": "9489", + "durability": null, + "name": "Ranarr seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5295" + }, + { + "requirements": "{19,38}", + "ge_buy_limit": "100", + "examine": "A toadflax seed - plant in a herb patch.", + "grand_exchange_price": "2980", + "durability": null, + "name": "Toadflax seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5296" + }, + { + "requirements": "{19,44}", + "ge_buy_limit": "100", + "examine": "An irit seed - plant in a herb patch.", + "grand_exchange_price": "181", + "durability": null, + "name": "Irit seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5297" + }, + { + "requirements": "{19,50}", + "ge_buy_limit": "100", + "examine": "An avantoe seed - plant in a herb patch.", + "grand_exchange_price": "2492", + "durability": null, + "name": "Avantoe seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5298" + }, + { + "requirements": "{19,56}", + "ge_buy_limit": "100", + "examine": "A kwuarm seed - plant in a herb patch.", + "grand_exchange_price": "537", + "durability": null, + "name": "Kwuarm seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5299" + }, + { + "requirements": "{19,62}", + "ge_buy_limit": "100", + "examine": "A snapdragon seed - plant in a herb patch.", + "grand_exchange_price": "47800", + "durability": null, + "name": "Snapdragon seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5300" + }, + { + "requirements": "{19,67}", + "ge_buy_limit": "100", + "examine": "A cadantine seed - plant in a herb patch.", + "grand_exchange_price": "1253", + "durability": null, + "name": "Cadantine seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5301" + }, + { + "requirements": "{19,73}", + "ge_buy_limit": "100", + "examine": "A lantadyme seed - plant in a herb patch.", + "grand_exchange_price": "37100", + "durability": null, + "name": "Lantadyme seed", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "5302" + }, + { + "requirements": "{19,79}", + "ge_buy_limit": "100", + "examine": "A dwarf weed seed - plant in a herb patch.", + "grand_exchange_price": "41900", + "durability": null, + "name": "Dwarf weed seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5303" + }, + { + "requirements": "{19,85}", + "ge_buy_limit": "100", + "examine": "A Torstol seed - plant in a herb patch.", + "grand_exchange_price": "302300", + "durability": null, + "name": "Torstol seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5304" + }, + { + "requirements": "{3,19}", + "shop_price": "38", + "ge_buy_limit": "100", + "examine": "A barley seed - plant in a hops patch.", + "grand_exchange_price": "1", + "durability": null, + "name": "Barley seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5305" + }, + { + "requirements": "{13,19}", + "shop_price": "86", + "ge_buy_limit": "100", + "examine": "A jute seed - plant in a hops patch.", + "grand_exchange_price": "2", + "durability": null, + "name": "Jute seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5306" + }, + { + "requirements": "{4,19}", + "shop_price": "52", + "ge_buy_limit": "100", + "examine": "A hammerstone hop seed - plant in a hops patch.", + "grand_exchange_price": "1", + "durability": null, + "name": "Hammerstone seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5307" + }, + { + "requirements": "{8,19}", + "shop_price": "60", + "ge_buy_limit": "100", + "examine": "An Asgarnian hop seed - plant in a hops patch.", + "grand_exchange_price": "1", + "durability": null, + "name": "Asgarnian seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5308" + }, + { + "requirements": "{16,19}", + "shop_price": "210", + "ge_buy_limit": "100", + "examine": "A yanillian hop seed - plant in a hops patch.", + "grand_exchange_price": "11", + "durability": null, + "name": "Yanillian seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5309" + }, + { + "requirements": "{21,19}", + "shop_price": "8", + "ge_buy_limit": "100", + "examine": "A krandorian hop seed - plant in a hops patch.", + "grand_exchange_price": "1", + "durability": null, + "name": "Krandorian seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5310" + }, + { + "requirements": "{19,28}", + "shop_price": "14", + "ge_buy_limit": "100", + "examine": "A wildblood hop seed - plant in a hops patch.", + "grand_exchange_price": "12", + "durability": null, + "name": "Wildblood seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5311" + }, + { + "requirements": "{15,19}", + "shop_price": "100", + "ge_buy_limit": "100", + "examine": "Plant this in a plantpot of soil to grow a sapling.", + "grand_exchange_price": "22", + "durability": null, + "name": "Acorn", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5312" + }, + { + "requirements": "{19,30}", + "ge_buy_limit": "100", + "examine": "Plant this in a plantpot of soil to grow a sapling.", + "grand_exchange_price": "945", + "durability": null, + "name": "Willow seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5313" + }, + { + "requirements": "{19,45}", + "ge_buy_limit": "100", + "examine": "Plant this in a plantpot of soil to grow a sapling.", + "grand_exchange_price": "35400", + "durability": null, + "name": "Maple seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5314" + }, + { + "requirements": "{19,60}", + "ge_buy_limit": "100", + "examine": "Plant this in a plantpot of soil to grow a sapling.", + "grand_exchange_price": "81900", + "durability": null, + "name": "Yew seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5315" + }, + { + "requirements": "{19,75}", + "ge_buy_limit": "100", + "examine": "Plant this in a plantpot of soil to grow a sapling.", + "grand_exchange_price": "276900", + "durability": null, + "name": "Magic seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5316" + }, + { + "requirements": "{19,83}", + "shop_price": "55000", + "examine": "Plant this in a plant pot of soil to grow a sapling.", + "durability": null, + "name": "Spirit seed", + "archery_ticket_price": "0", + "id": "5317" + }, + { + "shop_price": "8", + "ge_buy_limit": "500", + "examine": "A potato seed - plant in an allotment.", + "grand_exchange_price": "1", + "durability": null, + "name": "Potato seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5318" + }, + { + "requirements": "{5,19}", + "shop_price": "10", + "ge_buy_limit": "500", + "examine": "An onion seed - plant in an allotment.", + "grand_exchange_price": "1", + "durability": null, + "name": "Onion seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5319" + }, + { + "requirements": "{20,19}", + "ge_buy_limit": "500", + "examine": "A sweetcorn seed - plant in an allotment.", + "grand_exchange_price": "2", + "durability": null, + "name": "Sweetcorn seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5320" + }, + { + "requirements": "{19,47}", + "shop_price": "56", + "ge_buy_limit": "500", + "examine": "A watermelon seed - plant in an allotment.", + "grand_exchange_price": "2491", + "durability": null, + "name": "Watermelon seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5321" + }, + { + "requirements": "{12,19}", + "shop_price": "10", + "ge_buy_limit": "500", + "examine": "A tomato seed - plant in an allotment.", + "grand_exchange_price": "1", + "durability": null, + "name": "Tomato seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5322" + }, + { + "requirements": "{19,31}", + "ge_buy_limit": "500", + "examine": "A strawberry seed - plant in an allotment.", + "grand_exchange_price": "240", + "durability": null, + "name": "Strawberry seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5323" + }, + { + "requirements": "{7,19}", + "shop_price": "25", + "ge_buy_limit": "500", + "examine": "A cabbage seed - plant in an allotment.", + "grand_exchange_price": "1", + "durability": null, + "name": "Cabbage seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5324" + }, + { + "shop_price": "12", + "ge_buy_limit": "100", + "examine": "Not suitable for archaeological digs.", + "grand_exchange_price": "106", + "durability": null, + "name": "Gardening trowel", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5325" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "106", + "durability": null, + "name": "Gardening trowel", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5326" + }, + { + "examine": "I need to attach this to its head.", + "durability": null, + "name": "Spade handle", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "5327" + }, + { + "examine": "I need to attach this to its handle.", + "durability": null, + "name": "Spade head", + "archery_ticket_price": "0", + "id": "5328" + }, + { + "shop_price": "5", + "ge_buy_limit": "100", + "examine": "Good for pruning away diseased leaves.", + "grand_exchange_price": "204", + "durability": null, + "name": "Secateurs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5329", + "equipment_slot": "3" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "204", + "durability": null, + "name": "Secateurs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5330" + }, + { + "shop_price": "8", + "ge_buy_limit": "100", + "examine": "This watering can is empty.", + "grand_exchange_price": "298", + "durability": null, + "name": "Watering can", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "5331" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "298", + "durability": null, + "name": "Watering can", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5332" + }, + { + "shop_price": "8", + "examine": " This watering can is almost empty.", + "grand_exchange_price": "206", + "durability": null, + "name": "Watering can(1)", + "archery_ticket_price": "0", + "weight": "0.2", + "id": "5333" + }, + { + "shop_price": "8", + "examine": "This watering can is three-quarters empty.", + "grand_exchange_price": "206", + "durability": null, + "name": "Watering can(2)", + "archery_ticket_price": "0", + "weight": "0.3", + "id": "5334" + }, + { + "shop_price": "8", + "examine": "This watering can is just under half-full.", + "grand_exchange_price": "206", + "durability": null, + "name": "Watering can(3)", + "archery_ticket_price": "0", + "weight": "0.4", + "id": "5335" + }, + { + "shop_price": "8", + "examine": " Some would say this watering can is half-full, others half-empty.", + "grand_exchange_price": "206", + "durability": null, + "name": "Watering can(4)", + "archery_ticket_price": "0", + "weight": "0.5", + "id": "5336" + }, + { + "shop_price": "8", + "examine": "This watering can is just over half-full.", + "grand_exchange_price": "206", + "durability": null, + "name": "Watering can(5)", + "archery_ticket_price": "0", + "weight": "0.6", + "id": "5337" + }, + { + "shop_price": "8", + "examine": " This watering can is three quarters full.", + "grand_exchange_price": "206", + "durability": null, + "name": "Watering can(6)", + "archery_ticket_price": "0", + "weight": "0.7", + "id": "5338" + }, + { + "shop_price": "8", + "examine": " This watering can is almost completely full.", + "grand_exchange_price": "206", + "durability": null, + "name": "Watering can(7)", + "archery_ticket_price": "0", + "weight": "0.8", + "id": "5339" + }, + { + "shop_price": "8", + "examine": " This watering can is completely full.", + "grand_exchange_price": "206", + "durability": null, + "name": "Watering can(8)", + "archery_ticket_price": "0", + "weight": "0.9", + "id": "5340" + }, + { + "shop_price": "6", + "ge_buy_limit": "100", + "examine": "Use this to clear weeds.", + "grand_exchange_price": "99", + "durability": null, + "name": "Rake", + "tradeable": "true", + "weight": "1.3", + "archery_ticket_price": "0", + "id": "5341" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "99", + "durability": null, + "name": "Rake", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5342" + }, + { + "shop_price": "6", + "ge_buy_limit": "100", + "examine": "Use this to plant seeds with.", + "grand_exchange_price": "117", + "durability": null, + "name": "Seed dibber", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5343" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "117", + "durability": null, + "name": "Seed dibber", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5344" + }, + { + "ge_buy_limit": "100", + "examine": "A pair of gardening boots.", + "grand_exchange_price": "3186", + "durability": null, + "name": "Gardening boots", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "5345", + "equipment_slot": "10" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3186", + "durability": null, + "name": "Gardening boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5346" + }, + { + "examine": "I need to reattach this to its head.", + "durability": null, + "name": "Rake handle", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "5347" + }, + { + "examine": "I need to reattach this to its handle.", + "durability": null, + "name": "Rake head", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5348" + }, + { + "shop_price": "1", + "ge_buy_limit": "100", + "examine": "An empty plant pot.", + "grand_exchange_price": "20", + "durability": null, + "name": "Plant pot", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5350" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "20", + "durability": null, + "name": "Plant pot", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5351" + }, + { + "shop_price": "9", + "ge_buy_limit": "100", + "examine": "An unfired plant pot.", + "grand_exchange_price": "7", + "durability": null, + "name": "Unfired plant pot", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5352" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "7", + "durability": null, + "name": "Unfired plant pot", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5353" + }, + { + "shop_price": "1", + "ge_buy_limit": "100", + "examine": "A plant pot filled with soil.", + "grand_exchange_price": "340", + "durability": null, + "name": "Plant pot", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5354" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "340", + "durability": null, + "name": "Plant pot", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5355" + }, + { + "shop_price": "1", + "examine": "A plant pot filled with soil.", + "grand_exchange_price": "243", + "durability": null, + "name": "Plant pot", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5356" + }, + { + "durability": null, + "name": "Plant pot", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5357" + }, + { + "shop_price": "200", + "examine": "An acorn has been sown and watered in this plant pot.", + "durability": null, + "name": "Oak seedling", + "archery_ticket_price": "0", + "id": "5358" + }, + { + "examine": "A willow tree seed has been sown and watered in this plant pot", + "durability": null, + "name": "Willow seedling", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5359" + }, + { + "examine": "A maple tree has been sown (and watered) in this plant pot.", + "durability": null, + "name": "Maple seedling", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5360" + }, + { + "examine": "A yew seed has been sown in the plant pot", + "durability": null, + "name": "Yew seedling", + "weight": "1", + "archery_ticket_price": "0", + "id": "5361" + }, + { + "examine": "A magic tree seed has been sown and watered in this plant pot.", + "durability": null, + "name": "Magic seedling", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5362" + }, + { + "examine": "A spirit seedling is growing in this pot. It has been sown and watered.", + "durability": null, + "name": "Spirit seedling", + "archery_ticket_price": "0", + "id": "5363" + }, + { + "shop_price": "200", + "examine": "An acorn has been sown and watered in this plant pot.", + "durability": null, + "name": "Oak seedling", + "archery_ticket_price": "0", + "id": "5364" + }, + { + "examine": "A willow tree seed has been sown and watered in this plant pot", + "durability": null, + "name": "Willow seedling", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5365" + }, + { + "examine": "A maple tree has been sown (and watered) in this plant pot.", + "durability": null, + "name": "Maple seedling", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5366" + }, + { + "examine": "A yew seed has been sown in the plant pot", + "durability": null, + "name": "Yew seedling", + "weight": "1", + "archery_ticket_price": "0", + "id": "5367" + }, + { + "examine": "A magic tree seed has been sown and watered in this plant pot.", + "durability": null, + "name": "Magic seedling", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5368" + }, + { + "examine": "A spirit seedling is growing in this pot. It has been sown and watered.", + "durability": null, + "name": "Spirit seedling", + "archery_ticket_price": "0", + "id": "5369" + }, + { + "examine": "This sapling is ready to be planted in a tree patch.", + "durability": null, + "name": "Oak sapling", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5370" + }, + { + "examine": "This sapling is ready to be replanted in a tree patch.", + "durability": null, + "name": "Willow sapling", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5371" + }, + { + "examine": "This sapling is ready to be planted in a tree patch.", + "durability": null, + "name": "Maple sapling", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5372" + }, + { + "examine": "This sapling is ready to be planted in a tree patch.", + "durability": null, + "name": "Yew sapling", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5373" + }, + { + "examine": "This sapling is ready to be planted in a tree patch.", + "durability": null, + "name": "Magic sapling", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5374" + }, + { + "examine": "This sapling is ready to be planted in a tree patch.", + "durability": null, + "name": "Spirit sapling", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5375" + }, + { + "shop_price": "1", + "ge_buy_limit": "1000", + "examine": "An empty fruit basket.", + "grand_exchange_price": "1", + "durability": null, + "name": "Basket", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5376" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1", + "durability": null, + "name": "Basket", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5377" + }, + { + "examine": "A fruit basket filled with apples.", + "grand_exchange_price": "1889", + "durability": null, + "name": "Apples(1)", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "5378" + }, + { + "durability": null, + "name": "Apples(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5379" + }, + { + "examine": "A fruit basket filled with apples.", + "grand_exchange_price": "1889", + "durability": null, + "name": "Apples(2)", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "5380" + }, + { + "durability": null, + "name": "Apples(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5381" + }, + { + "examine": "A fruit basket filled with apples.", + "grand_exchange_price": "1889", + "durability": null, + "name": "Apples(3)", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "5382" + }, + { + "durability": null, + "name": "Apples(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5383" + }, + { + "examine": "A fruit basket filled with apples.", + "grand_exchange_price": "1889", + "durability": null, + "name": "Apples(4)", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "5384" + }, + { + "durability": null, + "name": "Apples(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5385" + }, + { + "ge_buy_limit": "1000", + "examine": "A fruit basket filled with apples.", + "grand_exchange_price": "2448", + "durability": null, + "name": "Apples(5)", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "5386" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "2448", + "durability": null, + "name": "Apples(5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5387" + }, + { + "examine": "A fruit basket filled with oranges", + "grand_exchange_price": "3823", + "durability": null, + "name": "Oranges(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5388" + }, + { + "durability": null, + "name": "Oranges(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5389" + }, + { + "examine": "A fruit basket filled with oranges", + "grand_exchange_price": "3823", + "durability": null, + "name": "Oranges(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5390" + }, + { + "durability": null, + "name": "Oranges(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5391" + }, + { + "examine": "A fruit basket filled with oranges", + "grand_exchange_price": "3823", + "durability": null, + "name": "Oranges(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5392" + }, + { + "durability": null, + "name": "Oranges(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5393" + }, + { + "examine": "A fruit basket filled with oranges", + "grand_exchange_price": "3823", + "durability": null, + "name": "Oranges(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5394" + }, + { + "durability": null, + "name": "Oranges(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5395" + }, + { + "shop_price": "70", + "ge_buy_limit": "1000", + "examine": "A common fruit.", + "grand_exchange_price": "5649", + "durability": null, + "name": "Oranges(5)", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "5396" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "5649", + "durability": null, + "name": "Oranges(5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5397" + }, + { + "examine": "A fruit basket filled with strawberries.", + "grand_exchange_price": "5", + "durability": null, + "name": "Strawberries(1)", + "tradeable": "true", + "weight": "0.25", + "archery_ticket_price": "0", + "id": "5398" + }, + { + "durability": null, + "name": "Strawberries(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5399" + }, + { + "examine": "A fruit basket filled with strawberries.", + "grand_exchange_price": "5", + "durability": null, + "name": "Strawberries(2)", + "tradeable": "true", + "weight": "0.25", + "archery_ticket_price": "0", + "id": "5400" + }, + { + "durability": null, + "name": "Strawberries(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5401" + }, + { + "examine": "A fruit basket filled with strawberries.", + "grand_exchange_price": "5", + "durability": null, + "name": "Strawberries(3)", + "tradeable": "true", + "weight": "0.25", + "archery_ticket_price": "0", + "id": "5402" + }, + { + "durability": null, + "name": "Strawberries(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5403" + }, + { + "examine": "A fruit basket filled with strawberries.", + "grand_exchange_price": "5", + "durability": null, + "name": "Strawberries(4)", + "tradeable": "true", + "weight": "0.25", + "archery_ticket_price": "0", + "id": "5404" + }, + { + "durability": null, + "name": "Strawberries(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5405" + }, + { + "ge_buy_limit": "10000", + "examine": "A fruit basket filled with strawberries.", + "grand_exchange_price": "406", + "durability": null, + "name": "Strawberries(5)", + "tradeable": "true", + "weight": "0.25", + "archery_ticket_price": "0", + "id": "5406" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "406", + "durability": null, + "name": "Strawberries(5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5407" + }, + { + "examine": "A fruit basket filled with bananas.", + "grand_exchange_price": "1064", + "durability": null, + "name": "Bananas(1)", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "5408" + }, + { + "durability": null, + "name": "Bananas(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5409" + }, + { + "examine": "A fruit basket filled with bananas.", + "grand_exchange_price": "1064", + "durability": null, + "name": "Bananas(2)", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "5410" + }, + { + "durability": null, + "name": "Bananas(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5411" + }, + { + "examine": "A fruit basket filled with bananas.", + "grand_exchange_price": "1064", + "durability": null, + "name": "Bananas(3)", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "5412" + }, + { + "durability": null, + "name": "Bananas(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5413" + }, + { + "shop_price": "2", + "examine": "Mmm this looks tasty.", + "grand_exchange_price": "171", + "durability": null, + "name": "Bananas(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5414" + }, + { + "durability": null, + "name": "Bananas(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5415" + }, + { + "shop_price": "2", + "ge_buy_limit": "1000", + "examine": "Mmm this looks tasty.", + "grand_exchange_price": "1637", + "durability": null, + "name": "Bananas(5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5416" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1637", + "durability": null, + "name": "Bananas(5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5417" + }, + { + "shop_price": "1", + "ge_buy_limit": "100", + "examine": "An empty sack.", + "grand_exchange_price": "45", + "durability": null, + "name": "Empty sack", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "5418" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "45", + "durability": null, + "name": "Empty sack", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5419" + }, + { + "examine": "There is one potato in this sack.", + "grand_exchange_price": "1276", + "durability": null, + "name": "Potatoes(1)", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5420" + }, + { + "durability": null, + "name": "Potatoes(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5421" + }, + { + "examine": "There are two potatoes in this sack.", + "grand_exchange_price": "1276", + "durability": null, + "name": "Potatoes(2)", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5422" + }, + { + "durability": null, + "name": "Potatoes(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5423" + }, + { + "examine": "There are three potatoes in this sack.", + "grand_exchange_price": "1276", + "durability": null, + "name": "Potatoes(3)", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5424" + }, + { + "durability": null, + "name": "Potatoes(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5425" + }, + { + "examine": "There are four potatoes in this sack.", + "grand_exchange_price": "1276", + "durability": null, + "name": "Potatoes(4)", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5426" + }, + { + "durability": null, + "name": "Potatoes(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5427" + }, + { + "examine": "There are five potatoes in this sack.", + "grand_exchange_price": "1276", + "durability": null, + "name": "Potatoes(5)", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5428" + }, + { + "durability": null, + "name": "Potatoes(5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5429" + }, + { + "examine": "There are six potatoes in this sack.", + "grand_exchange_price": "1276", + "durability": null, + "name": "Potatoes(6)", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5430" + }, + { + "durability": null, + "name": "Potatoes(6)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5431" + }, + { + "examine": "There are seven potatoes in this sack.", + "grand_exchange_price": "1276", + "durability": null, + "name": "Potatoes(7)", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5432" + }, + { + "durability": null, + "name": "Potatoes(7)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5433" + }, + { + "examine": "There are eight potatoes in this sack.", + "grand_exchange_price": "1276", + "durability": null, + "name": "Potatoes(8)", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5434" + }, + { + "durability": null, + "name": "Potatoes(8)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5435" + }, + { + "examine": "There are nine potatoes in this sack.", + "grand_exchange_price": "1276", + "durability": null, + "name": "Potatoes(9)", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5436" + }, + { + "durability": null, + "name": "Potatoes(9)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5437" + }, + { + "ge_buy_limit": "1000", + "examine": "There are ten potatoes in this sack.", + "grand_exchange_price": "1052", + "durability": null, + "name": "Potatoes(10)", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5438" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1052", + "durability": null, + "name": "Potatoes(10)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5439" + }, + { + "examine": "There are/is (1-10) onion(s) in this sack.", + "grand_exchange_price": "589", + "durability": null, + "name": "Onions(1)", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5440" + }, + { + "durability": null, + "name": "Onions(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5441" + }, + { + "examine": "There are/is (1-10) onion(s) in this sack.", + "grand_exchange_price": "589", + "durability": null, + "name": "Onions(2)", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5442" + }, + { + "durability": null, + "name": "Onions(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5443" + }, + { + "examine": "There are/is (1-10) onion(s) in this sack.", + "grand_exchange_price": "589", + "durability": null, + "name": "Onions(3)", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5444" + }, + { + "durability": null, + "name": "Onions(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5445" + }, + { + "examine": "There are/is (1-10) onion(s) in this sack.", + "grand_exchange_price": "589", + "durability": null, + "name": "Onions(4)", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5446" + }, + { + "durability": null, + "name": "Onions(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5447" + }, + { + "examine": "There are/is (1-10) onion(s) in this sack.", + "grand_exchange_price": "589", + "durability": null, + "name": "Onions(5)", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5448" + }, + { + "durability": null, + "name": "Onions(5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5449" + }, + { + "examine": "There are/is (1-10) onion(s) in this sack.", + "grand_exchange_price": "589", + "durability": null, + "name": "Onions(6)", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5450" + }, + { + "durability": null, + "name": "Onions(6)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5451" + }, + { + "examine": "There are/is (1-10) onion(s) in this sack.", + "grand_exchange_price": "589", + "durability": null, + "name": "Onions(7)", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5452" + }, + { + "durability": null, + "name": "Onions(7)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5453" + }, + { + "examine": "There are/is (1-10) onion(s) in this sack.", + "grand_exchange_price": "589", + "durability": null, + "name": "Onions(8)", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5454" + }, + { + "durability": null, + "name": "Onions(8)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5455" + }, + { + "examine": "There are/is (1-10) onion(s) in this sack.", + "grand_exchange_price": "589", + "durability": null, + "name": "Onions(9)", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5456" + }, + { + "durability": null, + "name": "Onions(9)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5457" + }, + { + "ge_buy_limit": "1000", + "examine": "There are/is (1-10) onion(s) in this sack.", + "grand_exchange_price": "489", + "durability": null, + "name": "Onions(10)", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5458" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "489", + "durability": null, + "name": "Onions(10)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5459" + }, + { + "examine": "There is one cabbage in this sack.", + "grand_exchange_price": "1304", + "durability": null, + "name": "Cabbages(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5460" + }, + { + "durability": null, + "name": "Cabbages(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5461" + }, + { + "examine": "There are two cabbages in this sack.", + "grand_exchange_price": "1304", + "durability": null, + "name": "Cabbages(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5462" + }, + { + "durability": null, + "name": "Cabbages(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5463" + }, + { + "examine": "There are three cabbages in this sack.", + "grand_exchange_price": "1304", + "durability": null, + "name": "Cabbages(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5464" + }, + { + "durability": null, + "name": "Cabbages(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5465" + }, + { + "examine": "There are four cabbages in this sack.", + "grand_exchange_price": "1304", + "durability": null, + "name": "Cabbages(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5466" + }, + { + "durability": null, + "name": "Cabbages(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5467" + }, + { + "examine": "There are five cabbages in this sack.", + "grand_exchange_price": "1304", + "durability": null, + "name": "Cabbages(5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5468" + }, + { + "durability": null, + "name": "Cabbages(5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5469" + }, + { + "examine": "There are six cabbages in this sack.", + "grand_exchange_price": "1304", + "durability": null, + "name": "Cabbages(6)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5470" + }, + { + "durability": null, + "name": "Cabbages(6)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5471" + }, + { + "examine": "There are seven cabbages in this sack.", + "grand_exchange_price": "1304", + "durability": null, + "name": "Cabbages(7)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5472" + }, + { + "durability": null, + "name": "Cabbages(7)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5473" + }, + { + "examine": "There are eight cabbages in this sack.", + "grand_exchange_price": "1304", + "durability": null, + "name": "Cabbages(8)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5474" + }, + { + "durability": null, + "name": "Cabbages(8)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5475" + }, + { + "examine": "There are nine cabbages in this sack.", + "grand_exchange_price": "1304", + "durability": null, + "name": "Cabbages(9)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5476" + }, + { + "durability": null, + "name": "Cabbages(9)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5477" + }, + { + "ge_buy_limit": "1000", + "examine": "There are ten cabbages in this sack.", + "grand_exchange_price": "917", + "durability": null, + "name": "Cabbages(10)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5478" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "917", + "durability": null, + "name": "Cabbages(10)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5479" + }, + { + "examine": "An apple tree has been sown (and watered) in this plant pot.", + "durability": null, + "name": "Apple seedling", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5480" + }, + { + "examine": "A banana tree seed has been sown and watered in this plant pot.", + "durability": null, + "name": "Banana seedling", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5481" + }, + { + "examine": "An orange tree seed has been sown (and watered)in this plant pot.", + "durability": null, + "name": "Orange seedling", + "archery_ticket_price": "0", + "id": "5482" + }, + { + "examine": "A curry seed has been sown and watered in this plant pot.", + "durability": null, + "name": "Curry seedling", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5483" + }, + { + "examine": "A pineapple tree has been sown (and watered) in this plant pot.", + "durability": null, + "name": "Pineapple seedling", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5484" + }, + { + "examine": "This needs watering before it will grow.", + "durability": null, + "name": "Papaya seedling", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5485" + }, + { + "examine": "This sapling is ready to be replanted in a fruit tree patch.", + "durability": null, + "name": "Palm seedling", + "weight": "0.66", + "archery_ticket_price": "0", + "id": "5486" + }, + { + "examine": "A calquat tree has been sown (and watered) in this plant pot.", + "durability": null, + "name": "Calquat seedling", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5487" + }, + { + "examine": "An apple tree has been sown (and watered) in this plant pot.", + "durability": null, + "name": "Apple seedling", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5488" + }, + { + "examine": "A banana tree seed has been sown and watered in this plant pot.", + "durability": null, + "name": "Banana seedling", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5489" + }, + { + "examine": "An orange tree seed has been sown (and watered)in this plant pot.", + "durability": null, + "name": "Orange seedling", + "archery_ticket_price": "0", + "id": "5490" + }, + { + "examine": "A curry seed has been sown and watered in this plant pot.", + "durability": null, + "name": "Curry seedling", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5491" + }, + { + "examine": "A pineapple tree has been sown (and watered) in this plant pot.", + "durability": null, + "name": "Pineapple seedling", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5492" + }, + { + "examine": "This needs watering before it will grow.", + "durability": null, + "name": "Papaya seedling", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5493" + }, + { + "examine": "This sapling is ready to be replanted in a fruit tree patch.", + "durability": null, + "name": "Palm seedling", + "weight": "0.66", + "archery_ticket_price": "0", + "id": "5494" + }, + { + "examine": "A calquat tree has been sown (and watered) in this plant pot.", + "durability": null, + "name": "Calquat seedling", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5495" + }, + { + "examine": "This sapling is ready to be replanted in a fruit tree patch.", + "durability": null, + "name": "Apple sapling", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5496" + }, + { + "examine": "This sapling is ready to be replanted in a fruit tree patch.", + "durability": null, + "name": "Banana sapling", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5497" + }, + { + "examine": "This sapling is ready to be replanted in a fruit tree patch.", + "durability": null, + "name": "Orange sapling", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5498" + }, + { + "examine": "This sapling is ready to be replanted in a fruit tree patch.", + "durability": null, + "name": "Curry sapling", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5499" + }, + { + "examine": "This sapling is ready to be replanted in a fruit tree patch.", + "durability": null, + "name": "Pineapple sapling", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5500" + }, + { + "examine": "This sapling is ready to be replanted in a fruit tree patch.", + "durability": null, + "name": "Papaya sapling", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5501" + }, + { + "examine": "This sapling is ready to be replanted in a fruit tree patch.", + "durability": null, + "name": "Palm sapling", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5502" + }, + { + "examine": "This sapling is ready to be planted in a tree patch.", + "durability": null, + "name": "Calquat sapling", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5503" + }, + { + "ge_buy_limit": "10000", + "examine": "A freshly picked strawberry.", + "grand_exchange_price": "23", + "durability": null, + "name": "Strawberry", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "5504" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "23", + "durability": null, + "name": "Strawberry", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5505" + }, + { + "examine": "The Wise Old Man of Draynor Village asked you to take this to someone.", + "durability": null, + "name": "Old man's message", + "archery_ticket_price": "0", + "id": "5506" + }, + { + "examine": "A tatty old book belonging to the Wise Old Man of Draynor Village.", + "durability": null, + "name": "Strange book", + "archery_ticket_price": "0", + "id": "5507" + }, + { + "examine": "A tatty old book belonging to the Wise Old Man of Draynor Village.", + "durability": null, + "name": "Book of folklore", + "archery_ticket_price": "0", + "id": "5508" + }, + { + "examine": "A small pouch used for storing essence.", + "durability": null, + "name": "Small pouch", + "weight": "1", + "archery_ticket_price": "0", + "id": "5509" + }, + { + "examine": "A medium-sized pouch used for storing essence.", + "durability": null, + "name": "Medium pouch", + "weight": "1", + "archery_ticket_price": "0", + "id": "5510" + }, + { + "examine": "A medium-sized pouch used for storing essence.", + "durability": null, + "name": "Medium pouch", + "weight": "1", + "archery_ticket_price": "0", + "id": "5511" + }, + { + "shop_price": "25000", + "examine": "A large pouch used for storing essence.", + "durability": null, + "name": "Large pouch", + "weight": "1", + "archery_ticket_price": "0", + "id": "5512" + }, + { + "shop_price": "25000", + "examine": "A large pouch used for storing essence.", + "durability": null, + "name": "Large pouch", + "weight": "1", + "archery_ticket_price": "0", + "id": "5513" + }, + { + "shop_price": "50000", + "examine": "A giant-sized pouch used for storing essence.", + "durability": null, + "name": "Giant pouch", + "weight": "1", + "archery_ticket_price": "0", + "id": "5514" + }, + { + "shop_price": "50000", + "examine": "A giant-sized pouch used for storing essence.", + "durability": null, + "name": "Giant pouch", + "weight": "1", + "archery_ticket_price": "0", + "id": "5515" + }, + { + "ge_buy_limit": "500", + "examine": "A mysterious power emanates from the talisman...", + "grand_exchange_price": "186900", + "durability": null, + "name": "Elemental talisman", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5516" + }, + { + "ge_buy_limit": "500", + "grand_exchange_price": "186900", + "durability": null, + "name": "Elemental talisman", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5517" + }, + { + "examine": "This contains mystical teleport information...", + "durability": null, + "name": "Scrying orb", + "weight": "1", + "archery_ticket_price": "0", + "id": "5518" + }, + { + "examine": "This orb apparently contains a cypher spell.", + "durability": null, + "name": "Scrying orb", + "weight": "1", + "archery_ticket_price": "0", + "id": "5519" + }, + { + "examine": "Some research notes on abyssal space.", + "durability": null, + "name": "Abyssal book", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5520" + }, + { + "ge_buy_limit": "100", + "examine": "A necklace embedded with mystical power.", + "grand_exchange_price": "720", + "durability": null, + "name": "Binding necklace", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "5521", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "720", + "durability": null, + "name": "Binding necklace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5522" + }, + { + "shop_price": "100", + "ge_buy_limit": "100", + "examine": "A mould for tiaras.", + "grand_exchange_price": "315", + "durability": null, + "name": "Tiara mould", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "5523" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "315", + "durability": null, + "name": "Tiara mould", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5524" + }, + { + "ge_buy_limit": "1000", + "examine": "Makes me feel like a Princess.", + "grand_exchange_price": "13", + "durability": null, + "name": "Tiara", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "5525", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "13", + "durability": null, + "name": "Tiara", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5526" + }, + { + "ge_buy_limit": "100", + "examine": "A tiara infused with the properties of air.", + "grand_exchange_price": "5", + "durability": null, + "name": "Air tiara", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "5527", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "5", + "durability": null, + "name": "Air tiara", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5528" + }, + { + "ge_buy_limit": "100", + "examine": "A tiara infused with the properties of the mind.", + "grand_exchange_price": "10", + "durability": null, + "name": "Mind tiara", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "5529", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "10", + "durability": null, + "name": "Mind tiara", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5530" + }, + { + "ge_buy_limit": "100", + "examine": "A tiara infused with the properties of water.", + "grand_exchange_price": "1351", + "durability": null, + "name": "Water tiara", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "5531", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1351", + "durability": null, + "name": "Water tiara", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5532" + }, + { + "ge_buy_limit": "100", + "examine": "A tiara infused with the properties of the body.", + "grand_exchange_price": "5", + "durability": null, + "name": "Body tiara", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "5533", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "5", + "durability": null, + "name": "Body tiara", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5534" + }, + { + "ge_buy_limit": "100", + "examine": "A tiara infused with the properties of the earth.", + "grand_exchange_price": "4", + "durability": null, + "name": "Earth tiara", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "5535", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "4", + "durability": null, + "name": "Earth tiara", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5536" + }, + { + "ge_buy_limit": "100", + "examine": "A tiara infused with the properties of fire.", + "grand_exchange_price": "8", + "durability": null, + "name": "Fire tiara", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "5537", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "8", + "durability": null, + "name": "Fire tiara", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5538" + }, + { + "ge_buy_limit": "100", + "examine": "A tiara infused with the properties of the cosmos.", + "grand_exchange_price": "8", + "durability": null, + "name": "Cosmic tiara", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "5539", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "8", + "durability": null, + "name": "Cosmic tiara", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5540" + }, + { + "ge_buy_limit": "100", + "examine": "A tiara infused with the properties of nature.", + "grand_exchange_price": "10", + "durability": null, + "name": "Nature tiara", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "5541", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "10", + "durability": null, + "name": "Nature tiara", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5542" + }, + { + "ge_buy_limit": "100", + "examine": "A tiara infused with the properties of chaos.", + "grand_exchange_price": "10", + "durability": null, + "name": "Chaos tiara", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "5543", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "10", + "durability": null, + "name": "Chaos tiara", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5544" + }, + { + "ge_buy_limit": "100", + "examine": "A tiara infused with the properties of law.", + "grand_exchange_price": "11", + "durability": null, + "name": "Law tiara", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "5545", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "11", + "durability": null, + "name": "Law tiara", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5546" + }, + { + "ge_buy_limit": "100", + "examine": "A tiara infused with the properties of death.", + "grand_exchange_price": "65", + "durability": null, + "name": "Death tiara", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "5547", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "65", + "durability": null, + "name": "Death tiara", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5548" + }, + { + "ge_buy_limit": "100", + "examine": "A tiara infused with the properties of Blood.", + "grand_exchange_price": "1058", + "durability": null, + "name": "Blood tiara", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "5549", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1058", + "durability": null, + "name": "Blood tiara", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5550" + }, + { + "ge_buy_limit": "100", + "examine": " A tiara infused with the properties of the soul.", + "durability": null, + "name": "Soul tiara", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "5551", + "equipment_slot": "0" + }, + { + "durability": null, + "name": "Soul tiara", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5552" + }, + { + "remove_sleeves": "true", + "examine": "Black banded leather armour, a rogue's dream!", + "durability": null, + "name": "Rogue top", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "5553", + "bonuses": "0,0,0,0,0,10,10,10,10,10,5,0,0,0,0", + "equipment_slot": "4" + }, + { + "remove_head": "true", + "examine": "Black banded leather armour, a rogue's dream!", + "durability": null, + "name": "Rogue mask", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "5554", + "bonuses": "0,0,0,0,0,5,5,5,5,5,0,0,0,0,0", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "examine": "Black banded leather armour, a rogue's dream!", + "durability": null, + "name": "Rogue trousers", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "5555", + "bonuses": "0,0,0,0,0,7,7,7,7,7,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "examine": "Black banded leather gloves, a rogue's dream!", + "durability": null, + "name": "Rogue gloves", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "5556", + "bonuses": "0,0,0,0,0,2,2,2,2,2,2,0,0,0,0", + "equipment_slot": "9" + }, + { + "examine": "Black banded leather boots, a rogue's dream!", + "durability": null, + "name": "Rogue boots", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "5557", + "bonuses": "0,0,0,0,0,2,2,2,2,2,0,0,0,0,0", + "equipment_slot": "10" + }, + { + "shop_price": "35", + "examine": "It can do almost anything!", + "durability": null, + "name": "Rogue kit", + "archery_ticket_price": "0", + "id": "5558" + }, + { + "examine": "A small satchel of bright powder!", + "durability": null, + "name": "Flash powder", + "weight": "1", + "archery_ticket_price": "0", + "id": "5559" + }, + { + "shop_price": "10", + "examine": "A useful hearing aid.", + "durability": null, + "name": "Stethoscope", + "archery_ticket_price": "0", + "id": "5560", + "equipment_slot": "5" + }, + { + "examine": "I can escape the Maze with this!", + "durability": null, + "name": "Mystic jewel", + "archery_ticket_price": "0", + "id": "5561" + }, + { + "examine": "A fraction of a roof.", + "durability": null, + "name": "Picture", + "weight": "0.6", + "archery_ticket_price": "0", + "id": "5568" + }, + { + "remove_head": "true", + "requirements": "{1,20}", + "shop_price": "6000", + "ge_buy_limit": "100", + "examine": "An initiate Temple Knight's helm.", + "durability": null, + "weight": "2.2", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "3512", + "name": "Initiate sallet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5574", + "bonuses": "0,0,0,-6,-2,13,14,11,-1,13,5,0,3,0,0" + }, + { + "requirements": "{1,20}", + "shop_price": "10000", + "ge_buy_limit": "100", + "examine": "An initiate Temple Knight's Armour.", + "durability": null, + "weight": "8", + "absorb": "1,0,3", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "5776", + "name": "Initiate hauberk", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5575", + "bonuses": "0,0,0,-30,-10,46,44,38,-6,44,20,0,6,0,0" + }, + { + "requirements": "{1,20}", + "shop_price": "8000", + "ge_buy_limit": "100", + "examine": "An initiate Temple Knight's leg armour.", + "durability": null, + "weight": "7", + "absorb": "1,0,2", + "equipment_slot": "7", + "grand_exchange_price": "4574", + "name": "Initiate cuisse", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5576", + "bonuses": "0,0,0,-21,-7,24,22,20,-4,22,5,0,5,0,0" + }, + { + "examine": "A vial of something labelled 'Cupric Sulfate'.", + "durability": null, + "name": "Cupric sulphate", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "5577" + }, + { + "examine": "A vial of something labelled 'Acetic Acid'.", + "durability": null, + "name": "Acetic acid", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "5578" + }, + { + "examine": "A vial of something labelled 'Gypsum'.", + "durability": null, + "name": "Gypsum", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "5579" + }, + { + "examine": "A vial of something labelled 'Sodium Chloride'.", + "durability": null, + "name": "Sodium chloride", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "5580" + }, + { + "examine": "A vial of something labelled 'Nitrous Oxide'.", + "durability": null, + "name": "Nitrous oxide", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "5581" + }, + { + "examine": "A vial of something labelled Dihydrogen Monoxide.", + "durability": null, + "name": "Vial of liquid", + "archery_ticket_price": "0", + "id": "5582" + }, + { + "examine": "A vial of something labelled 'Powdered Tin Ore'.", + "durability": null, + "name": "Tin ore powder", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "5583" + }, + { + "examine": "A vial of something labelled 'Powdered Cupric Ore'.", + "durability": null, + "name": "Cupric ore powder", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "5584" + }, + { + "examine": "I hope the mould was accurate enough...", + "durability": null, + "name": "Bronze Key", + "weight": "0.01", + "archery_ticket_price": "0", + "id": "5585" + }, + { + "examine": "It's a metal spade with a wooden handle.", + "durability": null, + "name": "Metal spade", + "weight": "1.814", + "archery_ticket_price": "0", + "id": "5586" + }, + { + "examine": "It's a metal spade without a handle.", + "durability": null, + "name": "Metal spade", + "weight": "1.814", + "archery_ticket_price": "0", + "id": "5587" + }, + { + "examine": "Looks like a pretty boring read.", + "durability": null, + "name": "Alchemical notes", + "archery_ticket_price": "0", + "id": "5588" + }, + { + "shop_price": "20", + "examine": "A tin layered with some stuff from a vial.", + "grand_exchange_price": "0", + "durability": null, + "name": "Tin", + "tradeable": "false", + "weight": "0.101", + "archery_ticket_price": "0", + "id": "5592" + }, + { + "shop_price": "20", + "examine": "It's full of a white lumpy mixture that seems to be hardening.", + "grand_exchange_price": "0", + "durability": null, + "name": "Tin", + "tradeable": "false", + "weight": "0.101", + "archery_ticket_price": "0", + "id": "5593" + }, + { + "shop_price": "20", + "examine": "There is an impression of a key embedded in it.", + "grand_exchange_price": "0", + "durability": null, + "name": "Tin", + "tradeable": "false", + "weight": "0.101", + "archery_ticket_price": "0", + "id": "5594" + }, + { + "shop_price": "20", + "examine": "There is an impression of a key, filled with tin ore.", + "grand_exchange_price": "0", + "durability": null, + "name": "Tin", + "tradeable": "false", + "weight": "0.101", + "archery_ticket_price": "0", + "id": "5595" + }, + { + "shop_price": "20", + "examine": "There is an impression of a key, filled with copper ore.", + "grand_exchange_price": "0", + "durability": null, + "name": "Tin", + "tradeable": "false", + "weight": "0.101", + "archery_ticket_price": "0", + "id": "5596" + }, + { + "shop_price": "20", + "examine": "There is an impression of a key, filled with tin and copper ore.", + "grand_exchange_price": "0", + "durability": null, + "name": "Tin", + "tradeable": "false", + "weight": "0.101", + "archery_ticket_price": "0", + "id": "5597" + }, + { + "shop_price": "20", + "examine": "There is a bronze key surrounded by plaster in this tin.", + "grand_exchange_price": "0", + "durability": null, + "name": "Tin", + "tradeable": "false", + "weight": "0.101", + "archery_ticket_price": "0", + "id": "5598" + }, + { + "shop_price": "20", + "examine": "There is a strange concoction filling this tin.", + "grand_exchange_price": "0", + "durability": null, + "name": "Tin", + "tradeable": "false", + "weight": "0.101", + "archery_ticket_price": "0", + "id": "5599" + }, + { + "shop_price": "10", + "examine": "I could probably pour something into this.", + "grand_exchange_price": "0", + "durability": null, + "name": "Tin", + "tradeable": "false", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "5600" + }, + { + "shop_price": "14", + "examine": "Good for detailed crafting.", + "grand_exchange_price": "33", + "durability": null, + "name": "Chisel", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "5601" + }, + { + "examine": "Useful for crafting items.", + "grand_exchange_price": "237", + "durability": null, + "name": "Bronze wire", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5602" + }, + { + "shop_price": "1", + "examine": "For shearing sheep.", + "grand_exchange_price": "41", + "durability": null, + "name": "Shears", + "tradeable": "false", + "weight": "0.113", + "archery_ticket_price": "0", + "id": "5603" + }, + { + "examine": "A very attractive magnet.", + "durability": null, + "name": "Magnet", + "archery_ticket_price": "0", + "id": "5604" + }, + { + "shop_price": "25", + "examine": "A dangerous looking knife.", + "grand_exchange_price": "102", + "durability": null, + "name": "Knife", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "5605" + }, + { + "examine": "I can exchange this for one free makeover with the makeover mage.", + "durability": null, + "name": "Makeover voucher", + "weight": "1", + "archery_ticket_price": "0", + "id": "5606" + }, + { + "shop_price": "2", + "examine": "Some wheat heads.", + "grand_exchange_price": "20", + "durability": null, + "name": "Grain", + "tradeable": "true", + "weight": "0.6", + "archery_ticket_price": "0", + "id": "5607", + "equipment_slot": "1" + }, + { + "examine": "A cunning animal.", + "durability": null, + "name": "Fox", + "archery_ticket_price": "0", + "id": "5608", + "equipment_slot": "3" + }, + { + "examine": "Normal: Yep. Definitely a chicken.", + "durability": null, + "name": "Chicken", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "5609", + "equipment_slot": "5" + }, + { + "examine": "There's not much sand left in the top half...", + "durability": null, + "name": "Hourglass", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "5610" + }, + { + "durability": null, + "name": "Initiate sallet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5611" + }, + { + "durability": null, + "name": "Initiate hauberk", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5612" + }, + { + "durability": null, + "name": "Initiate cuisse", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5613" + }, + { + "turn90cw_anim": "330", + "walk_anim": "330", + "durability": null, + "turn90ccw_anim": "330", + "turn180_anim": "330", + "render_anim": "191", + "equipment_slot": "3", + "stand_anim": "330", + "name": "Magic carpet", + "run_anim": "330", + "archery_ticket_price": "0", + "id": "5614", + "stand_turn_anim": "330" + }, + { + "examine": "A pot of crushed bearded gorilla monkey bones.", + "durability": null, + "name": "Bonemeal", + "weight": "1", + "archery_ticket_price": "0", + "id": "5615" + }, + { + "shop_price": "7", + "ge_buy_limit": "10000", + "examine": "Arrows with bronze heads.", + "grand_exchange_price": "127", + "durability": null, + "name": "Bronze arrow(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5616", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,7", + "equipment_slot": "13" + }, + { + "shop_price": "20", + "ge_buy_limit": "10000", + "examine": "Arrows with iron heads.", + "grand_exchange_price": "138", + "durability": null, + "name": "Iron arrow(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5617", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,10", + "equipment_slot": "13" + }, + { + "requirements": "{4,5}", + "shop_price": "46", + "ge_buy_limit": "10000", + "examine": "Arrows with steel heads.", + "grand_exchange_price": "159", + "durability": null, + "name": "Steel arrow(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5618", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,16", + "equipment_slot": "13" + }, + { + "requirements": "{4,20}", + "shop_price": "76", + "ge_buy_limit": "10000", + "examine": "Arrows with mithril heads.", + "grand_exchange_price": "176", + "durability": null, + "name": "Mithril arrow(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5619", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,22", + "equipment_slot": "13" + }, + { + "requirements": "{4,30}", + "shop_price": "172", + "ge_buy_limit": "10000", + "examine": "Arrows with adamantite heads.", + "grand_exchange_price": "211", + "durability": null, + "name": "Adamant arrow(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5620", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,31", + "equipment_slot": "13" + }, + { + "requirements": "{4,40}", + "shop_price": "510", + "ge_buy_limit": "10000", + "examine": "Arrows with rune heads.", + "grand_exchange_price": "415", + "durability": null, + "name": "Rune arrow(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5621", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,49", + "equipment_slot": "13" + }, + { + "shop_price": "7", + "ge_buy_limit": "10000", + "examine": "Arrows with bronze heads.", + "grand_exchange_price": "1076", + "durability": null, + "name": "Bronze arrow(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5622", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,7", + "equipment_slot": "13" + }, + { + "shop_price": "20", + "ge_buy_limit": "10000", + "examine": "Arrows with iron heads.", + "grand_exchange_price": "1037", + "durability": null, + "name": "Iron arrow(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5623", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,10", + "equipment_slot": "13" + }, + { + "requirements": "{4,5}", + "shop_price": "46", + "ge_buy_limit": "10000", + "examine": "Arrows with steel heads.", + "grand_exchange_price": "1038", + "durability": null, + "name": "Steel arrow(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5624", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,16", + "equipment_slot": "13" + }, + { + "requirements": "{4,20}", + "shop_price": "76", + "ge_buy_limit": "10000", + "examine": "Arrows with mithril heads.", + "grand_exchange_price": "718", + "durability": null, + "name": "Mithril arrow(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5625", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,22", + "equipment_slot": "13" + }, + { + "requirements": "{4,30}", + "shop_price": "172", + "ge_buy_limit": "10000", + "examine": "Arrows with adamantite heads.", + "grand_exchange_price": "101", + "durability": null, + "name": "Adamant arrow(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5626", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,31", + "equipment_slot": "13" + }, + { + "requirements": "{4,40}", + "shop_price": "510", + "ge_buy_limit": "10000", + "examine": "Arrows with rune heads.", + "grand_exchange_price": "1300", + "durability": null, + "name": "Rune arrow(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5627", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,49", + "equipment_slot": "13" + }, + { + "ge_buy_limit": "1000", + "examine": "A deadly throwing dart with a bronze tip.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "582,582,582,582", + "grand_exchange_price": "162", + "attack_audios": "2547,0,0,0", + "name": "Bronze dart(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5628", + "bonuses": "0,0,0,0,3,0,0,0,0,0,0,0,0,0,1" + }, + { + "ge_buy_limit": "1000", + "examine": "A deadly throwing dart with an iron tip.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "582,582,582,582", + "grand_exchange_price": "164", + "attack_audios": "2547,0,0,0", + "name": "Iron dart(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5629", + "bonuses": "0,0,0,0,4,0,0,0,0,0,0,0,0,0,3" + }, + { + "requirements": "{4,5}", + "ge_buy_limit": "1000", + "examine": "A deadly throwing dart with a steel tip.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "582,582,582,582", + "grand_exchange_price": "173", + "attack_audios": "2547,0,0,0", + "name": "Steel dart(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5630", + "bonuses": "0,0,0,0,5,0,0,0,0,0,0,0,0,0,4" + }, + { + "requirements": "{4,10}", + "ge_buy_limit": "1000", + "examine": "A deadly throwing dart with a black tip.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "582,582,582,582", + "grand_exchange_price": "822", + "attack_audios": "2547,0,0,0", + "name": "Black dart(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5631", + "bonuses": "0,0,0,0,7,0,0,0,0,0,0,0,0,0,6" + }, + { + "requirements": "{4,20}", + "ge_buy_limit": "1000", + "examine": "A deadly throwing dart with a mithril tip.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "582,582,582,582", + "grand_exchange_price": "196", + "attack_audios": "2547,0,0,0", + "name": "Mithril dart(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5632", + "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,7" + }, + { + "requirements": "{4,30}", + "ge_buy_limit": "1000", + "examine": "A deadly throwing dart with an adamantite tip.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "582,582,582,582", + "grand_exchange_price": "244", + "attack_audios": "2547,0,0,0", + "name": "Adamant dart(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5633", + "bonuses": "0,0,0,0,11,0,0,0,0,0,0,0,0,0,10" + }, + { + "requirements": "{4,40}", + "ge_buy_limit": "1000", + "examine": "A deadly throwing dart with a rune tip.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "582,582,582,582", + "grand_exchange_price": "370", + "attack_audios": "2547,0,0,0", + "name": "Rune dart(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5634", + "bonuses": "0,0,0,0,15,0,0,0,0,0,0,0,0,0,14" + }, + { + "ge_buy_limit": "1000", + "examine": "A deadly throwing dart with a bronze tip.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "582,582,582,582", + "grand_exchange_price": "1733", + "attack_audios": "2547,0,0,0", + "name": "Bronze dart(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5635", + "bonuses": "0,0,0,0,3,0,0,0,0,0,0,0,0,0,1" + }, + { + "ge_buy_limit": "1000", + "examine": "A deadly throwing dart with an iron tip.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "582,582,582,582", + "grand_exchange_price": "1687", + "attack_audios": "2547,0,0,0", + "name": "Iron dart(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5636", + "bonuses": "0,0,0,0,4,0,0,0,0,0,0,0,0,0,3" + }, + { + "requirements": "{4,5}", + "ge_buy_limit": "1000", + "examine": "A deadly throwing dart with a steel tip.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "582,582,582,582", + "grand_exchange_price": "1654", + "attack_audios": "2547,0,0,0", + "name": "Steel dart(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5637", + "bonuses": "0,0,0,0,5,0,0,0,0,0,0,0,0,0,4" + }, + { + "requirements": "{4,10}", + "ge_buy_limit": "1000", + "examine": "A deadly throwing dart with a black tip.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "582,582,582,582", + "grand_exchange_price": "2422", + "attack_audios": "2547,0,0,0", + "name": "Black dart(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5638", + "bonuses": "0,0,0,0,7,0,0,0,0,0,0,0,0,0,6" + }, + { + "requirements": "{4,20}", + "ge_buy_limit": "1000", + "examine": "A deadly throwing dart with a mithril tip.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "582,582,582,582", + "grand_exchange_price": "1660", + "attack_audios": "2547,0,0,0", + "name": "Mithril dart(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5639", + "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,7" + }, + { + "requirements": "{4,30}", + "ge_buy_limit": "1000", + "examine": "A deadly throwing dart with an adamantite tip.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "582,582,582,582", + "grand_exchange_price": "1352", + "attack_audios": "2547,0,0,0", + "name": "Adamant dart(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5640", + "bonuses": "0,0,0,0,11,0,0,0,0,0,0,0,0,0,10" + }, + { + "requirements": "{4,40}", + "ge_buy_limit": "1000", + "examine": "A deadly throwing dart with a rune tip.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "582,582,582,582", + "grand_exchange_price": "1109", + "attack_audios": "2547,0,0,0", + "name": "Rune dart(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5641", + "bonuses": "0,0,0,0,15,0,0,0,0,0,0,0,0,0,14" + }, + { + "shop_price": "6", + "ge_buy_limit": "1000", + "examine": "A bronze-tipped javelin.", + "durability": null, + "attack_speed": "6", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "115", + "name": "Bronze javelin(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5642", + "bonuses": "0,0,0,0,5,0,0,0,0,0,0,0,0,0,6" + }, + { + "shop_price": "8", + "ge_buy_limit": "1000", + "examine": "An iron-tipped javelin.", + "durability": null, + "attack_speed": "6", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "112", + "name": "Iron javelin(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5643", + "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,10" + }, + { + "requirements": "{4,5}", + "shop_price": "37", + "ge_buy_limit": "1000", + "examine": "A steel-tipped javelin.", + "durability": null, + "attack_speed": "6", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "128", + "name": "Steel javelin(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5644", + "bonuses": "0,0,0,0,12,0,0,0,0,0,0,0,0,0,12" + }, + { + "requirements": "{4,20}", + "shop_price": "79", + "ge_buy_limit": "1000", + "examine": "A mithril tipped javelin.", + "durability": null, + "attack_speed": "6", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "141", + "name": "Mithril javelin(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5645", + "bonuses": "0,0,0,0,17,0,0,0,0,0,0,0,0,0,18" + }, + { + "requirements": "{4,30}", + "ge_buy_limit": "100", + "shop_price": "100", + "examine": "An adamant tipped javelin.", + "durability": null, + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "179", + "name": "Adamant javelin(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5646", + "bonuses": "0,0,0,0,24,0,0,0,0,0,0,0,0,0,28" + }, + { + "shop_price": "624", + "ge_buy_limit": "1000", + "examine": "A rune tipped javelin.", + "durability": null, + "attack_speed": "6", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "302", + "name": "Rune javelin(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5647", + "bonuses": "0,0,0,0,38,0,0,0,0,0,0,0,0,0,42" + }, + { + "shop_price": "6", + "ge_buy_limit": "100", + "examine": "A bronze-tipped javelin.", + "durability": null, + "attack_speed": "6", + "weapon_interface": "18", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "1755", + "name": "Bronze jav'n(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5648", + "bonuses": "0,0,0,0,5,0,0,0,0,0,0,0,0,0,6" + }, + { + "shop_price": "8", + "ge_buy_limit": "1000", + "examine": "An iron-tipped javelin.", + "durability": null, + "attack_speed": "6", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "1756", + "name": "Iron javelin(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5649", + "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,10" + }, + { + "requirements": "{4,5}", + "shop_price": "37", + "ge_buy_limit": "1000", + "examine": "A steel-tipped javelin.", + "durability": null, + "attack_speed": "6", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "1769", + "name": "Steel javelin(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5650", + "bonuses": "0,0,0,0,12,0,0,0,0,0,0,0,0,0,12" + }, + { + "requirements": "{4,20}", + "shop_price": "79", + "ge_buy_limit": "1000", + "examine": "A mithril tipped javelin.", + "durability": null, + "attack_speed": "6", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "1736", + "name": "Mithril javelin(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5651", + "bonuses": "0,0,0,0,17,0,0,0,0,0,0,0,0,0,18" + }, + { + "requirements": "{4,30}", + "ge_buy_limit": "100", + "shop_price": "100", + "examine": "An adamant tipped javelin.", + "durability": null, + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "1514", + "name": "Adamant javelin(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5652", + "bonuses": "0,0,0,0,24,0,0,0,0,0,0,0,0,0,28" + }, + { + "requirements": "{4,40}", + "shop_price": "624", + "ge_buy_limit": "1000", + "examine": "A rune tipped javelin.", + "durability": null, + "attack_speed": "6", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "1521", + "name": "Rune javelin(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5653", + "bonuses": "0,0,0,0,38,0,0,0,0,0,0,0,0,0,42" + }, + { + "shop_price": "14", + "ge_buy_limit": "10000", + "examine": "A finely balanced throwing knife.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "164", + "attack_audios": "2704,0,0,0", + "name": "Bronze knife(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5654", + "bonuses": "0,0,0,0,4,0,0,0,0,0,0,0,0,0,3" + }, + { + "shop_price": "58", + "ge_buy_limit": "10000", + "examine": "A finely balanced throwing knife.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "170", + "attack_audios": "2704,0,0,0", + "name": "Iron knife(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5655", + "bonuses": "0,0,0,0,5,0,0,0,0,0,0,0,0,0,4" + }, + { + "requirements": "{4,5}", + "shop_price": "68", + "ge_buy_limit": "10000", + "examine": "A finely balanced throwing knife.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "212", + "attack_audios": "2704,0,0,0", + "name": "Steel knife(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5656", + "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,7" + }, + { + "requirements": "{4,20}", + "ge_buy_limit": "100", + "examine": "A finely balanced throwing knife.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "330", + "attack_audios": "2704,0,0,0", + "name": "Mithril knife(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5657", + "bonuses": "0,0,0,0,11,0,0,0,0,0,0,0,0,0,10" + }, + { + "requirements": "{4,10}", + "shop_price": "15", + "ge_buy_limit": "10000", + "examine": "A finely balanced throwing knife.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "66", + "attack_audios": "2704,0,0,0", + "name": "Black knife(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5658", + "bonuses": "0,0,0,0,10,0,0,0,0,0,0,0,0,0,8" + }, + { + "requirements": "{4,30}", + "ge_buy_limit": "10000", + "examine": "A finely balanced throwing knife.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "609", + "attack_audios": "2704,0,0,0", + "name": "Adamant knife(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5659", + "bonuses": "0,0,0,0,15,0,0,0,0,0,0,0,0,0,14" + }, + { + "requirements": "{4,40}", + "ge_buy_limit": "10000", + "examine": "A finely balanced throwing knife.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "1511", + "attack_audios": "2704,0,0,0", + "name": "Rune knife(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5660", + "bonuses": "0,0,0,0,25,0,0,0,0,0,0,0,0,0,24" + }, + { + "shop_price": "14", + "ge_buy_limit": "10000", + "examine": "A finely balanced throwing knife.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "1514", + "attack_audios": "2704,0,0,0", + "name": "Bronze knife(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5661", + "bonuses": "0,0,0,0,4,0,0,0,0,0,0,0,0,0,3" + }, + { + "shop_price": "58", + "ge_buy_limit": "10000", + "examine": "A finely balanced throwing knife.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "1212", + "attack_audios": "2704,0,0,0", + "name": "Iron knife(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5662", + "bonuses": "0,0,0,0,5,0,0,0,0,0,0,0,0,0,4" + }, + { + "requirements": "{4,5}", + "shop_price": "68", + "ge_buy_limit": "10000", + "examine": "A finely balanced throwing knife.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "1579", + "attack_audios": "2704,0,0,0", + "name": "Steel knife(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5663", + "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,7" + }, + { + "requirements": "{4,20}", + "ge_buy_limit": "100", + "examine": "A finely balanced throwing knife.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "1368", + "attack_audios": "2704,0,0,0", + "name": "Mithril knife(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5664", + "bonuses": "0,0,0,0,11,0,0,0,0,0,0,0,0,0,10" + }, + { + "requirements": "{4,10}", + "shop_price": "15", + "ge_buy_limit": "10000", + "examine": "A finely balanced throwing knife.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "103", + "attack_audios": "2704,0,0,0", + "name": "Black knife(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5665", + "bonuses": "0,0,0,0,10,0,0,0,0,0,0,0,0,0,8" + }, + { + "requirements": "{4,30}", + "ge_buy_limit": "100", + "examine": "A finely balanced throwing knife.", + "durability": null, + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "1505", + "attack_audios": "2704,0,0,0", + "name": "Adamant knife(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5666", + "bonuses": "0,0,0,0,15,0,0,0,0,0,0,0,0,0,14" + }, + { + "requirements": "{4,40}", + "ge_buy_limit": "10000", + "examine": "A finely balanced throwing knife.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "806,806,806,806", + "grand_exchange_price": "2207", + "attack_audios": "2704,0,0,0", + "name": "Rune knife(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5667", + "bonuses": "0,0,0,0,25,0,0,0,0,0,0,0,0,0,24" + }, + { + "shop_price": "38", + "ge_buy_limit": "100", + "examine": "Short but pointy.", + "durability": null, + "weight": "0.4", + "attack_speed": "4", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "equipment_slot": "3", + "grand_exchange_price": "483", + "attack_audios": "2517,2517,2500,2517", + "name": "Iron dagger(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5668", + "bonuses": "5,3,-4,1,0,0,0,0,1,0,0,4,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "483", + "durability": null, + "name": "Iron dagger(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5669" + }, + { + "shop_price": "11", + "ge_buy_limit": "100", + "examine": "Short but pointy.", + "durability": null, + "weight": "0.4", + "attack_speed": "4", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "equipment_slot": "3", + "grand_exchange_price": "350", + "attack_audios": "2517,2517,2500,2517", + "name": "Bronze dagger(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5670", + "bonuses": "4,2,-4,1,0,0,0,0,1,0,0,3,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "350", + "durability": null, + "name": "Bronze dagger(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5671" + }, + { + "requirements": "{0,5}", + "shop_price": "135", + "ge_buy_limit": "100", + "examine": "Short but pointy.", + "durability": null, + "weight": "0.4", + "attack_speed": "4", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "equipment_slot": "3", + "grand_exchange_price": "575", + "attack_audios": "2517,2517,2500,2517", + "name": "Steel dagger(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5672", + "bonuses": "8,4,-4,1,0,0,0,0,1,0,0,7,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "575", + "durability": null, + "name": "Steel dagger(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5673" + }, + { + "requirements": "{0,20}", + "shop_price": "130", + "ge_buy_limit": "100", + "examine": "A dangerous dagger.", + "durability": null, + "weight": "0.3", + "attack_speed": "4", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "equipment_slot": "3", + "grand_exchange_price": "538", + "attack_audios": "2517,2517,2500,2517", + "name": "Mithril dagger(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5674", + "bonuses": "11,5,-4,1,0,0,0,0,1,0,0,10,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "538", + "durability": null, + "name": "Mithril dagger(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5675" + }, + { + "requirements": "{0,30}", + "ge_buy_limit": "100", + "durability": null, + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "equipment_slot": "3", + "grand_exchange_price": "800", + "attack_audios": "2517,2517,2500,2517", + "name": "Adamant dagger(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5676", + "bonuses": "15,8,-4,1,0,0,0,0,1,0,0,14,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "800", + "durability": null, + "name": "Adamant dagger(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5677" + }, + { + "requirements": "{0,40}", + "shop_price": "8000", + "ge_buy_limit": "100", + "examine": "A powerful dagger.", + "durability": null, + "weight": "0.4", + "attack_speed": "4", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "equipment_slot": "3", + "lendable": "true", + "grand_exchange_price": "4538", + "attack_audios": "2517,2517,2500,2517", + "name": "Rune dagger(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5678", + "bonuses": "25,12,-4,1,0,0,0,0,1,0,0,24,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "4538", + "durability": null, + "name": "Rune dagger(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5679" + }, + { + "requirements": "{0,60}", + "shop_price": "60000", + "ge_buy_limit": "10", + "examine": "A powerful dagger.", + "has_special": "true", + "durability": null, + "weight": "0.4", + "attack_speed": "4", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "396,396,395,396", + "lendable": "true", + "grand_exchange_price": "16800", + "attack_audios": "2517,2517,2500,2517", + "name": "Dragon dagger(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5680", + "bonuses": "40,25,-4,1,0,0,0,0,1,0,0,40,0,0,0" + }, + { + "attack_anims": "396,396,395,396", + "ge_buy_limit": "10", + "grand_exchange_price": "16800", + "attack_audios": "2517,2517,2500,2517", + "durability": null, + "name": "Dragon dagger(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5681", + "defence_anim": "397" + }, + { + "requirements": "{0,10}", + "shop_price": "240", + "ge_buy_limit": "100", + "examine": "A vicious black dagger.", + "durability": null, + "weight": "0.4", + "attack_speed": "4", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "equipment_slot": "3", + "grand_exchange_price": "664", + "attack_audios": "2517,2517,2500,2517", + "name": "Black dagger(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5682", + "bonuses": "10,5,-4,1,0,0,0,0,1,0,0,7,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "664", + "durability": null, + "name": "Black dagger(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5683" + }, + { + "attack_audios": "2517,2517,2500,2517", + "durability": null, + "name": "Poison dagger(p+)", + "archery_ticket_price": "0", + "id": "5684", + "weapon_interface": "5", + "bonuses": "10,5,-4,1,0,0,0,0,1,0,0,7,0,0,0", + "equip_audio": "2248", + "render_anim": "2584", + "equipment_slot": "3" + }, + { + "durability": null, + "name": "Poison dagger(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5685" + }, + { + "shop_price": "38", + "ge_buy_limit": "100", + "examine": "Short but pointy.", + "durability": null, + "weight": "0.4", + "attack_speed": "4", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "equipment_slot": "3", + "grand_exchange_price": "4128", + "attack_audios": "2517,2517,2500,2517", + "name": "Iron dagger(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5686", + "bonuses": "5,3,-4,1,0,0,0,0,1,0,0,4,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "4128", + "durability": null, + "name": "Iron dagger(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5687" + }, + { + "shop_price": "11", + "ge_buy_limit": "100", + "examine": "Short but pointy.", + "durability": null, + "weight": "0.4", + "attack_speed": "4", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "equipment_slot": "3", + "grand_exchange_price": "5088", + "attack_audios": "2517,2517,2500,2517", + "name": "Br'ze dagger(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5688", + "bonuses": "4,2,-4,1,0,0,0,0,1,0,0,3,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "5088", + "durability": null, + "name": "Br'ze dagger(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5689" + }, + { + "requirements": "{0,5}", + "shop_price": "135", + "ge_buy_limit": "100", + "examine": "Short but pointy.", + "durability": null, + "weight": "0.4", + "attack_speed": "4", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "equipment_slot": "3", + "grand_exchange_price": "4729", + "attack_audios": "2517,2517,2500,2517", + "name": "Steel dagger(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5690", + "bonuses": "8,4,-4,1,0,0,0,0,1,0,0,7,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "4729", + "durability": null, + "name": "Steel dagger(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5691" + }, + { + "requirements": "{0,20}", + "shop_price": "130", + "ge_buy_limit": "100", + "examine": "A dangerous dagger.", + "durability": null, + "weight": "0.3", + "attack_speed": "4", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "equipment_slot": "3", + "grand_exchange_price": "3476", + "attack_audios": "2517,2517,2500,2517", + "name": "Mithril dagger(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5692", + "bonuses": "11,5,-4,1,0,0,0,0,1,0,0,10,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3476", + "durability": null, + "name": "Mithril dagger(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5693" + }, + { + "requirements": "{0,30}", + "ge_buy_limit": "100", + "durability": null, + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "equipment_slot": "3", + "grand_exchange_price": "4612", + "attack_audios": "2517,2517,2500,2517", + "name": "Adamant dagger(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5694", + "bonuses": "15,8,-4,1,0,0,0,0,1,0,0,14,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "4612", + "durability": null, + "name": "Adamant dagger(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5695" + }, + { + "requirements": "{0,40}", + "shop_price": "8000", + "ge_buy_limit": "100", + "examine": "A powerful dagger.", + "durability": null, + "weight": "0.4", + "attack_speed": "4", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "equipment_slot": "3", + "lendable": "true", + "grand_exchange_price": "5061", + "attack_audios": "2517,2517,2500,2517", + "name": "Rune dagger(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5696", + "bonuses": "25,12,-4,1,0,0,0,0,1,0,0,24,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "5061", + "durability": null, + "name": "Rune dagger(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5697" + }, + { + "requirements": "{0,60}", + "shop_price": "60000", + "ge_buy_limit": "10", + "examine": "A powerful dagger.", + "has_special": "true", + "durability": null, + "weight": "0.4", + "attack_speed": "4", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "396,396,395,396", + "lendable": "true", + "grand_exchange_price": "20300", + "attack_audios": "2517,2517,2500,2517", + "name": "Dragon dagger(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5698", + "bonuses": "40,25,-4,1,0,0,0,0,1,0,0,40,0,0,0" + }, + { + "attack_anims": "396,396,395,396", + "ge_buy_limit": "10", + "grand_exchange_price": "20300", + "attack_audios": "2517,2517,2500,2517", + "durability": null, + "name": "Dragon dagger(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5699", + "defence_anim": "397" + }, + { + "requirements": "{0,10}", + "shop_price": "240", + "ge_buy_limit": "100", + "examine": "A vicious black dagger.", + "durability": null, + "weight": "0.4", + "attack_speed": "4", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "equipment_slot": "3", + "grand_exchange_price": "4921", + "attack_audios": "2517,2517,2500,2517", + "name": "Black dagger(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5700", + "bonuses": "10,5,-4,1,0,0,0,0,1,0,0,7,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "4921", + "durability": null, + "name": "Black dagger(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5701" + }, + { + "attack_audios": "2517,2517,2500,2517", + "durability": null, + "name": "Poison dagger(p++)", + "archery_ticket_price": "0", + "id": "5702", + "weapon_interface": "5", + "bonuses": "10,5,-4,1,0,0,0,0,1,0,0,7,0,0,0", + "equip_audio": "2248", + "render_anim": "2584", + "equipment_slot": "3" + }, + { + "durability": null, + "name": "Poison dagger(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5703" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A bronze tipped spear.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1206", + "equip_audio": "2247", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "861", + "stand_anim": "813", + "name": "Bronze spear(p+)", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "5704", + "stand_turn_anim": "1209", + "bonuses": "5,5,5,0,0,1,1,0,0,0,0,6,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "861", + "durability": null, + "name": "Bronze spear(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5705" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "An iron tipped spear.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1206", + "equip_audio": "2247", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "676", + "stand_anim": "813", + "name": "Iron spear(p+)", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "5706", + "stand_turn_anim": "1209", + "bonuses": "8,8,8,0,0,1,1,0,0,0,0,10,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "676", + "durability": null, + "name": "Iron spear(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5707" + }, + { + "requirements": "{0,5}", + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A steel tipped spear.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1206", + "equip_audio": "2247", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "596", + "stand_anim": "813", + "tradeable": "true", + "name": "Steel spear(p+)", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "5708", + "stand_turn_anim": "1209", + "bonuses": "12,12,12,0,0,1,1,0,0,0,0,12,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "596", + "durability": null, + "name": "Steel spear(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5709" + }, + { + "requirements": "{0,20}", + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A mithril tipped spear.", + "walk_anim": "1205", + "durability": null, + "weight": "1.8", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1206", + "equip_audio": "2247", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "802", + "stand_anim": "813", + "tradeable": "true", + "name": "Mithril spear(p+)", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "5710", + "stand_turn_anim": "1209", + "bonuses": "17,17,17,0,0,1,1,0,0,0,0,18,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "802", + "durability": null, + "name": "Mithril spear(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5711" + }, + { + "requirements": "{0,30}", + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "An adamant tipped spear.", + "walk_anim": "1205", + "durability": null, + "weight": "2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1206", + "equip_audio": "2247", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "1394", + "stand_anim": "813", + "tradeable": "true", + "name": "Adamant spear(p+)", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "5712", + "stand_turn_anim": "1209", + "bonuses": "24,24,24,0,0,1,1,0,0,0,0,28,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1394", + "durability": null, + "name": "Adamant spear(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5713" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A rune tipped spear.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "turn180_anim": "1206", + "equipment_slot": "3", + "grand_exchange_price": "12500", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "5714", + "stand_turn_anim": "1209", + "bonuses": "36,36,36,0,0,1,1,0,0,0,0,42,0,0,0", + "requirements": "{0,40}", + "durability": null, + "weight": "2.2", + "weapon_interface": "14", + "equip_audio": "2247", + "render_anim": "28", + "lendable": "true", + "name": "Rune spear(p+)" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "12500", + "durability": null, + "name": "Rune spear(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5715" + }, + { + "ge_buy_limit": "10", + "turn90cw_anim": "1207", + "examine": "A dragon tipped spear.", + "walk_anim": "1205", + "has_special": "true", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "turn180_anim": "1206", + "defence_anim": "2079", + "equipment_slot": "3", + "attack_anims": "2080,2081,2082,2080", + "grand_exchange_price": "41800", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "5716", + "stand_turn_anim": "1209", + "bonuses": "55,55,55,0,0,5,5,5,5,5,0,60,0,0,0", + "requirements": "{0,60}", + "durability": null, + "weight": "2", + "weapon_interface": "14", + "equip_audio": "2247", + "render_anim": "28", + "lendable": "true", + "name": "Dragon spear(p+)" + }, + { + "attack_anims": "2080,2081,2082,2080", + "ge_buy_limit": "10", + "grand_exchange_price": "41800", + "durability": null, + "name": "Dragon spear(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5717", + "defence_anim": "2079" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A bronze tipped spear.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1206", + "equip_audio": "2247", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "7557", + "stand_anim": "813", + "name": "Bronze spear(p++)", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "5718", + "stand_turn_anim": "1209", + "bonuses": "5,5,5,0,0,1,1,0,0,0,0,6,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "7557", + "durability": null, + "name": "Bronze spear(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5719" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "An iron tipped spear.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1206", + "equip_audio": "2247", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "8394", + "stand_anim": "813", + "name": "Iron spear(p++)", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "5720", + "stand_turn_anim": "1209", + "bonuses": "8,8,8,0,0,1,1,0,0,0,0,10,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "8394", + "durability": null, + "name": "Iron spear(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5721" + }, + { + "requirements": "{0,5}", + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A steel tipped spear.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1206", + "equip_audio": "2247", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "8336", + "stand_anim": "813", + "tradeable": "true", + "name": "Steel spear(p++)", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "5722", + "stand_turn_anim": "1209", + "bonuses": "12,12,12,0,0,1,1,0,0,0,0,12,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "8336", + "durability": null, + "name": "Steel spear(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5723" + }, + { + "requirements": "{0,20}", + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A mithril tipped spear.", + "walk_anim": "1205", + "durability": null, + "weight": "1.8", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1206", + "equip_audio": "2247", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "7035", + "stand_anim": "813", + "tradeable": "true", + "name": "Mithril spear(p++)", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "5724", + "stand_turn_anim": "1209", + "bonuses": "17,17,17,0,0,1,1,0,0,0,0,18,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "7035", + "durability": null, + "name": "Mithril spear(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5725" + }, + { + "requirements": "{0,30}", + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "An adamant tipped spear.", + "walk_anim": "1205", + "durability": null, + "turn90ccw_anim": "1208", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1206", + "equip_audio": "2247", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "7530", + "stand_anim": "813", + "name": "Adamant spear(p++)", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "5726", + "stand_turn_anim": "1209", + "bonuses": "24,24,24,0,0,1,1,0,0,0,0,28,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "7530", + "durability": null, + "name": "Adamant spear(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5727" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A rune tipped spear.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "turn180_anim": "1206", + "equipment_slot": "3", + "grand_exchange_price": "17700", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "5728", + "stand_turn_anim": "1209", + "bonuses": "36,36,36,0,0,1,1,0,0,0,0,42,0,0,0", + "requirements": "{0,40}", + "durability": null, + "weight": "2.2", + "weapon_interface": "14", + "equip_audio": "2247", + "render_anim": "28", + "lendable": "true", + "name": "Rune spear(p++)" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "17700", + "durability": null, + "name": "Rune spear(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5729" + }, + { + "ge_buy_limit": "10", + "turn90cw_anim": "1207", + "examine": "A dragon tipped spear.", + "walk_anim": "1205", + "has_special": "true", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "turn180_anim": "1206", + "defence_anim": "2079", + "equipment_slot": "3", + "attack_anims": "2080,2081,2082,2080", + "grand_exchange_price": "37800", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "5730", + "stand_turn_anim": "1209", + "bonuses": "55,55,55,0,0,5,5,5,5,5,0,60,0,0,0", + "requirements": "{0,60}", + "durability": null, + "weight": "2", + "weapon_interface": "14", + "equip_audio": "2247", + "render_anim": "28", + "lendable": "true", + "name": "Dragon spear(p++)" + }, + { + "attack_anims": "2080,2081,2082,2080", + "ge_buy_limit": "10", + "grand_exchange_price": "37800", + "durability": null, + "name": "Dragon spear(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5731", + "defence_anim": "2079" + }, + { + "durability": null, + "name": "Stool", + "archery_ticket_price": "0", + "id": "5732", + "equipment_slot": "5" + }, + { + "examine": "Yuk!", + "durability": null, + "name": "Rotten potato", + "archery_ticket_price": "0", + "id": "5733" + }, + { + "requirements": "{0,10}", + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A black tipped spear.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1206", + "equip_audio": "2247", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "3351", + "stand_anim": "813", + "tradeable": "true", + "name": "Black spear(p+)", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "5734", + "stand_turn_anim": "1209", + "bonuses": "15,15,15,0,0,1,1,0,0,0,0,16,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3351", + "durability": null, + "name": "Black spear(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5735" + }, + { + "requirements": "{0,10}", + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A black tipped spear.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1206", + "equip_audio": "2247", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "9065", + "stand_anim": "813", + "tradeable": "true", + "name": "Black spear(p++)", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "5736", + "stand_turn_anim": "1209", + "bonuses": "15,15,15,0,0,1,1,0,0,0,0,16,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "9065", + "durability": null, + "name": "Black spear(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5737" + }, + { + "shop_price": "15", + "examine": "A slightly bluish leaf.", + "grand_exchange_price": "19", + "durability": null, + "name": "Woad leaf", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5738" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal Asgarnian ale.", + "grand_exchange_price": "459", + "durability": null, + "name": "Asgarnian ale(m)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5739" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "459", + "durability": null, + "name": "Asgarnian ale(m)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5740" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal Wizards Mind Bomb.", + "grand_exchange_price": "1193", + "durability": null, + "name": "Mature wmb", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5741" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1193", + "durability": null, + "name": "Mature wmb", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5742" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal Greenman's Ale.", + "grand_exchange_price": "65400", + "durability": null, + "name": "Greenman's ale(m)", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "5743" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "65400", + "durability": null, + "name": "Greenman's ale(m)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5744" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal Dragon Bitter.", + "grand_exchange_price": "2458", + "durability": null, + "name": "Dragon bitter(m)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5745" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2458", + "durability": null, + "name": "Dragon bitter(m)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5746" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal dwarven stout.", + "grand_exchange_price": "56400", + "durability": null, + "name": "Dwarven stout(m)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5747" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "56400", + "durability": null, + "name": "Dwarven stout(m)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5748" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal Moonlight Mead.", + "grand_exchange_price": "19", + "durability": null, + "name": "Moonlight mead(m)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5749" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "19", + "durability": null, + "name": "Moonlight mead(m)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5750" + }, + { + "ge_buy_limit": "100", + "examine": "This might help me chop harder.", + "grand_exchange_price": "890", + "durability": null, + "name": "Axeman's folly", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5751" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "890", + "durability": null, + "name": "Axeman's folly", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5752" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than a normal Axeman's Folly.", + "grand_exchange_price": "26000", + "durability": null, + "name": "Axeman's folly(m)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5753" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "26000", + "durability": null, + "name": "Axeman's folly(m)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5754" + }, + { + "ge_buy_limit": "100", + "examine": "A fruity, full-bodied ale.", + "grand_exchange_price": "3694", + "durability": null, + "name": "Chef's delight", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5755" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3694", + "durability": null, + "name": "Chef's delight", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5756" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal Chef's Delight.", + "grand_exchange_price": "42800", + "durability": null, + "name": "Chef's delight(m)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5757" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "42800", + "durability": null, + "name": "Chef's delight(m)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5758" + }, + { + "ge_buy_limit": "100", + "examine": "Ale with bite.", + "grand_exchange_price": "7", + "durability": null, + "name": "Slayer's respite", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5759" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "7", + "durability": null, + "name": "Slayer's respite", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5760" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal Slayer's Respite.", + "grand_exchange_price": "1748", + "durability": null, + "name": "Slayer's respite(m)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5761" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1748", + "durability": null, + "name": "Slayer's respite(m)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5762" + }, + { + "shop_price": "2", + "ge_buy_limit": "100", + "examine": "A glass of Cider", + "grand_exchange_price": "1279", + "durability": null, + "name": "Cider", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "5763" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1279", + "durability": null, + "name": "Cider", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5764" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal cider.", + "grand_exchange_price": "3614", + "durability": null, + "name": "Mature cider", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5765" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3614", + "durability": null, + "name": "Mature cider", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5766" + }, + { + "shop_price": "5", + "ge_buy_limit": "100", + "examine": "A pot filled with ale yeast.", + "grand_exchange_price": "59", + "durability": null, + "name": "Ale yeast", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "5767" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "59", + "durability": null, + "name": "Ale yeast", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5768" + }, + { + "ge_buy_limit": "100", + "examine": "Sliced and hollowed out to form a keg.", + "grand_exchange_price": "8", + "durability": null, + "name": "Calquat keg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5769" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "8", + "durability": null, + "name": "Calquat keg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5770" + }, + { + "shop_price": "3", + "ge_buy_limit": "100", + "examine": "A pint of thick dark beer.", + "grand_exchange_price": "1934", + "durability": null, + "name": "Dwarven stout(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5771" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1934", + "durability": null, + "name": "Dwarven stout(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5772" + }, + { + "shop_price": "3", + "ge_buy_limit": "100", + "examine": "A pint of thick dark beer.", + "grand_exchange_price": "3214", + "durability": null, + "name": "Dwarven stout(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5773" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3214", + "durability": null, + "name": "Dwarven stout(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5774" + }, + { + "shop_price": "3", + "ge_buy_limit": "100", + "examine": "A pint of thick dark beer.", + "grand_exchange_price": "4886", + "durability": null, + "name": "Dwarven stout(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5775" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "4886", + "durability": null, + "name": "Dwarven stout(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5776" + }, + { + "shop_price": "3", + "ge_buy_limit": "100", + "examine": "A pint of thick dark beer.", + "grand_exchange_price": "5159", + "durability": null, + "name": "Dwarven stout(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5777" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "5159", + "durability": null, + "name": "Dwarven stout(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5778" + }, + { + "shop_price": "3", + "ge_buy_limit": "100", + "examine": "Probably the finest readily-available ale in Asgarnia.", + "grand_exchange_price": "3344", + "durability": null, + "name": "Asgarnian ale(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5779" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3344", + "durability": null, + "name": "Asgarnian ale(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5780" + }, + { + "shop_price": "3", + "ge_buy_limit": "100", + "examine": "Probably the finest readily-available ale in Asgarnia.", + "grand_exchange_price": "6103", + "durability": null, + "name": "Asgarnian ale(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5781" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "6103", + "durability": null, + "name": "Asgarnian ale(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5782" + }, + { + "shop_price": "3", + "ge_buy_limit": "100", + "examine": "Probably the finest readily-available ale in Asgarnia.", + "grand_exchange_price": "9230", + "durability": null, + "name": "Asgarnian ale(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5783" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "9230", + "durability": null, + "name": "Asgarnian ale(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5784" + }, + { + "shop_price": "3", + "ge_buy_limit": "100", + "examine": "Probably the finest readily-available ale in Asgarnia.", + "grand_exchange_price": "12900", + "durability": null, + "name": "Asgarnian ale(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5785" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "12900", + "durability": null, + "name": "Asgarnian ale(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5786" + }, + { + "shop_price": "2", + "ge_buy_limit": "100", + "examine": "A glass of frothy ale.", + "grand_exchange_price": "3441", + "durability": null, + "name": "Greenmans ale(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5787" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3441", + "durability": null, + "name": "Greenmans ale(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5788" + }, + { + "shop_price": "2", + "ge_buy_limit": "100", + "examine": "A glass of frothy ale.", + "grand_exchange_price": "4670", + "durability": null, + "name": "Greenmans ale(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5789" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "4670", + "durability": null, + "name": "Greenmans ale(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5790" + }, + { + "shop_price": "2", + "ge_buy_limit": "100", + "examine": "A glass of frothy ale.", + "grand_exchange_price": "7654", + "durability": null, + "name": "Greenmans ale(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5791" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "7654", + "durability": null, + "name": "Greenmans ale(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5792" + }, + { + "shop_price": "2", + "ge_buy_limit": "100", + "examine": "A glass of frothy ale.", + "grand_exchange_price": "6317", + "durability": null, + "name": "Greenmans ale(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5793" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "6317", + "durability": null, + "name": "Greenmans ale(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5794" + }, + { + "shop_price": "3", + "ge_buy_limit": "100", + "examine": "It's got strange bubbles in it.", + "grand_exchange_price": "1495", + "durability": null, + "name": "Mind bomb(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5795" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1495", + "durability": null, + "name": "Mind bomb(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5796" + }, + { + "shop_price": "3", + "ge_buy_limit": "100", + "examine": "It's got strange bubbles in it.", + "grand_exchange_price": "2721", + "durability": null, + "name": "Mind bomb(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5797" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2721", + "durability": null, + "name": "Mind bomb(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5798" + }, + { + "shop_price": "3", + "ge_buy_limit": "100", + "examine": "It's got strange bubbles in it.", + "grand_exchange_price": "4038", + "durability": null, + "name": "Mind bomb(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5799" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "4038", + "durability": null, + "name": "Mind bomb(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5800" + }, + { + "shop_price": "3", + "ge_buy_limit": "100", + "examine": "It's got strange bubbles in it.", + "grand_exchange_price": "5166", + "durability": null, + "name": "Mind bomb(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5801" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "5166", + "durability": null, + "name": "Mind bomb(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5802" + }, + { + "shop_price": "2", + "ge_buy_limit": "100", + "examine": "A glass of bitter.", + "grand_exchange_price": "1673", + "durability": null, + "name": "Dragon bitter(1)", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "5803" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1673", + "durability": null, + "name": "Dragon bitter(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5804" + }, + { + "shop_price": "2", + "ge_buy_limit": "100", + "examine": "A glass of bitter.", + "grand_exchange_price": "3259", + "durability": null, + "name": "Dragon bitter(2)", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "5805" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3259", + "durability": null, + "name": "Dragon bitter(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5806" + }, + { + "shop_price": "2", + "ge_buy_limit": "100", + "examine": "A glass of bitter.", + "grand_exchange_price": "4845", + "durability": null, + "name": "Dragon bitter(3)", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "5807" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "4845", + "durability": null, + "name": "Dragon bitter(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5808" + }, + { + "shop_price": "2", + "ge_buy_limit": "100", + "examine": "A glass of bitter.", + "grand_exchange_price": "5924", + "durability": null, + "name": "Dragon bitter(4)", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "5809" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "5924", + "durability": null, + "name": "Dragon bitter(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5810" + }, + { + "shop_price": "5", + "ge_buy_limit": "100", + "examine": "A foul smelling brew.", + "grand_exchange_price": "1298", + "durability": null, + "name": "Moonlight mead(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5811" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1298", + "durability": null, + "name": "Moonlight mead(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5812" + }, + { + "shop_price": "5", + "ge_buy_limit": "100", + "examine": "A foul smelling brew.", + "grand_exchange_price": "2510", + "durability": null, + "name": "Moonlight mead(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5813" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2510", + "durability": null, + "name": "Moonlight mead(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5814" + }, + { + "shop_price": "5", + "ge_buy_limit": "100", + "examine": "A foul smelling brew.", + "grand_exchange_price": "3721", + "durability": null, + "name": "Moonlight mead(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5815" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3721", + "durability": null, + "name": "Moonlight mead(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5816" + }, + { + "shop_price": "5", + "ge_buy_limit": "100", + "examine": "A foul smelling brew.", + "grand_exchange_price": "4883", + "durability": null, + "name": "Moonlight mead(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5817" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "4883", + "durability": null, + "name": "Moonlight mead(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5818" + }, + { + "ge_buy_limit": "100", + "examine": "This might help me chop harder.", + "grand_exchange_price": "3333", + "durability": null, + "name": "Axeman's folly(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5819" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3333", + "durability": null, + "name": "Axeman's folly(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5820" + }, + { + "ge_buy_limit": "100", + "examine": "This might help me chop harder.", + "grand_exchange_price": "6093", + "durability": null, + "name": "Axeman's folly(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5821" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "6093", + "durability": null, + "name": "Axeman's folly(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5822" + }, + { + "ge_buy_limit": "100", + "examine": "This might help me chop harder.", + "grand_exchange_price": "8978", + "durability": null, + "name": "Axeman's folly(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5823" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "8978", + "durability": null, + "name": "Axeman's folly(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5824" + }, + { + "ge_buy_limit": "100", + "examine": "This might help me chop harder.", + "grand_exchange_price": "9212", + "durability": null, + "name": "Axeman's folly(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5825" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "9212", + "durability": null, + "name": "Axeman's folly(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5826" + }, + { + "ge_buy_limit": "100", + "examine": "A fruity, full-bodied ale.", + "grand_exchange_price": "3851", + "durability": null, + "name": "Chef's delight(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5827" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3851", + "durability": null, + "name": "Chef's delight(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5828" + }, + { + "ge_buy_limit": "100", + "examine": "A fruity, full-bodied ale.", + "grand_exchange_price": "6589", + "durability": null, + "name": "Chef's delight(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5829" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "6589", + "durability": null, + "name": "Chef's delight(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5830" + }, + { + "ge_buy_limit": "100", + "examine": "A fruity, full-bodied ale.", + "grand_exchange_price": "9536", + "durability": null, + "name": "Chef's delight(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5831" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "9536", + "durability": null, + "name": "Chef's delight(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5832" + }, + { + "ge_buy_limit": "100", + "examine": "A fruity, full-bodied ale.", + "grand_exchange_price": "13200", + "durability": null, + "name": "Chef's delight(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5833" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "13200", + "durability": null, + "name": "Chef's delight(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5834" + }, + { + "ge_buy_limit": "100", + "examine": "Ale with bite.", + "grand_exchange_price": "1127", + "durability": null, + "name": "Slayer's respite(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5835" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1127", + "durability": null, + "name": "Slayer's respite(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5836" + }, + { + "ge_buy_limit": "100", + "examine": "Ale with bite.", + "grand_exchange_price": "2168", + "durability": null, + "name": "Slayer's respite(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5837" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2168", + "durability": null, + "name": "Slayer's respite(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5838" + }, + { + "ge_buy_limit": "100", + "examine": "Ale with bite.", + "grand_exchange_price": "3209", + "durability": null, + "name": "Slayer's respite(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5839" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3209", + "durability": null, + "name": "Slayer's respite(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5840" + }, + { + "ge_buy_limit": "100", + "examine": "Ale with bite.", + "grand_exchange_price": "3582", + "durability": null, + "name": "Slayer's respite(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5841" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3582", + "durability": null, + "name": "Slayer's respite(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5842" + }, + { + "shop_price": "2", + "ge_buy_limit": "100", + "examine": "A glass of Cider", + "grand_exchange_price": "6040", + "durability": null, + "name": "Cider(1)", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "5843" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "6040", + "durability": null, + "name": "Cider(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5844" + }, + { + "shop_price": "2", + "ge_buy_limit": "100", + "examine": "A glass of Cider", + "grand_exchange_price": "11000", + "durability": null, + "name": "Cider(2)", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "5845" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "11000", + "durability": null, + "name": "Cider(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5846" + }, + { + "shop_price": "2", + "ge_buy_limit": "100", + "examine": "A glass of Cider", + "grand_exchange_price": "15400", + "durability": null, + "name": "Cider(3)", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "5847" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "15400", + "durability": null, + "name": "Cider(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5848" + }, + { + "shop_price": "2", + "ge_buy_limit": "100", + "examine": "A glass of Cider", + "grand_exchange_price": "18900", + "durability": null, + "name": "Cider(4)", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "5849" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "18900", + "durability": null, + "name": "Cider(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5850" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal dwarven stout.", + "grand_exchange_price": "44600", + "durability": null, + "name": "Dwarven stout(m1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5851" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "44600", + "durability": null, + "name": "Dwarven stout(m1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5852" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal dwarven stout.", + "grand_exchange_price": "68900", + "durability": null, + "name": "Dwarven stout(m2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5853" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "68900", + "durability": null, + "name": "Dwarven stout(m2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5854" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal dwarven stout.", + "grand_exchange_price": "98800", + "durability": null, + "name": "Dwarven stout(m3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5855" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "98800", + "durability": null, + "name": "Dwarven stout(m3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5856" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal dwarven stout.", + "grand_exchange_price": "237400", + "durability": null, + "name": "Dwarven stout(m4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5857" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "237400", + "durability": null, + "name": "Dwarven stout(m4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5858" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal Asgarnian ale.", + "grand_exchange_price": "1697", + "durability": null, + "name": "Asgarnian ale(m1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5859" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1697", + "durability": null, + "name": "Asgarnian ale(m1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5860" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal Asgarnian ale.", + "grand_exchange_price": "3307", + "durability": null, + "name": "Asgarnian ale(m2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5861" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3307", + "durability": null, + "name": "Asgarnian ale(m2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5862" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal Asgarnian ale.", + "grand_exchange_price": "4917", + "durability": null, + "name": "Asgarnian ale(m3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5863" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "4917", + "durability": null, + "name": "Asgarnian ale(m3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5864" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal Asgarnian ale.", + "grand_exchange_price": "6778", + "durability": null, + "name": "Asgarnian ale(m4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5865" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "6778", + "durability": null, + "name": "Asgarnian ale(m4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5866" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal Greenman's Ale.", + "grand_exchange_price": "57600", + "durability": null, + "name": "Greenmans ale(m1)", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "5867" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "57600", + "durability": null, + "name": "Greenmans ale(m1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5868" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal Greenman's Ale.", + "grand_exchange_price": "92000", + "durability": null, + "name": "Greenmans ale(m2)", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "5869" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "92000", + "durability": null, + "name": "Greenmans ale(m2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5870" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal Greenman's Ale.", + "grand_exchange_price": "136700", + "durability": null, + "name": "Greenmans ale(m3)", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "5871" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "136700", + "durability": null, + "name": "Greenmans ale(m3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5872" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal Greenman's Ale.", + "grand_exchange_price": "231700", + "durability": null, + "name": "Greenmans ale(m4)", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "5873" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "231700", + "durability": null, + "name": "Greenmans ale(m4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5874" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal Wizards Mind Bomb.", + "grand_exchange_price": "3032", + "durability": null, + "name": "Mind bomb(m1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5875" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3032", + "durability": null, + "name": "Mind bomb(m1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5876" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal Wizards Mind Bomb.", + "grand_exchange_price": "5977", + "durability": null, + "name": "Mind bomb(m2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5877" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "5977", + "durability": null, + "name": "Mind bomb(m2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5878" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal Wizards Mind Bomb.", + "grand_exchange_price": "8922", + "durability": null, + "name": "Mind bomb(m3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5879" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "8922", + "durability": null, + "name": "Mind bomb(m3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5880" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal Wizards Mind Bomb.", + "grand_exchange_price": "12700", + "durability": null, + "name": "Mind bomb(m4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5881" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "12700", + "durability": null, + "name": "Mind bomb(m4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5882" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal Dragon Bitter.", + "grand_exchange_price": "2125", + "durability": null, + "name": "Dragon bitter(m1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5883" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2125", + "durability": null, + "name": "Dragon bitter(m1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5884" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal Dragon Bitter.", + "grand_exchange_price": "4163", + "durability": null, + "name": "Dragon bitter(m2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5885" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "4163", + "durability": null, + "name": "Dragon bitter(m2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5886" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal Dragon Bitter.", + "grand_exchange_price": "6201", + "durability": null, + "name": "Dragon bitter(m3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5887" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "6201", + "durability": null, + "name": "Dragon bitter(m3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5888" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal Dragon Bitter.", + "grand_exchange_price": "8834", + "durability": null, + "name": "Dragon bitter(m4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5889" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "8834", + "durability": null, + "name": "Dragon bitter(m4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5890" + }, + { + "shop_price": "5", + "ge_buy_limit": "100", + "examine": "A foul smelling brew.", + "grand_exchange_price": "1315", + "durability": null, + "name": "M'light mead(m1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5891" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1315", + "durability": null, + "name": "M'light mead(m1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5892" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal Moonlight Mead.", + "grand_exchange_price": "2543", + "durability": null, + "name": "M'light mead(m2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5893" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2543", + "durability": null, + "name": "M'light mead(m2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5894" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal Moonlight Mead.", + "grand_exchange_price": "3771", + "durability": null, + "name": "M'light mead(m3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5895" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3771", + "durability": null, + "name": "M'light mead(m3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5896" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal Moonlight Mead.", + "grand_exchange_price": "5000", + "durability": null, + "name": "M'light mead(m4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5897" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "5000", + "durability": null, + "name": "M'light mead(m4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5898" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than a normal Axeman's Folly.", + "grand_exchange_price": "13500", + "durability": null, + "name": "Axeman's folly(m1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5899" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "13500", + "durability": null, + "name": "Axeman's folly(m1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5900" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than a normal Axeman's Folly.", + "grand_exchange_price": "24800", + "durability": null, + "name": "Axeman's folly(m2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5901" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "24800", + "durability": null, + "name": "Axeman's folly(m2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5902" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than a normal Axeman's Folly.", + "grand_exchange_price": "37300", + "durability": null, + "name": "Axeman's folly(m3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5903" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "37300", + "durability": null, + "name": "Axeman's folly(m3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5904" + }, + { + "ge_buy_limit": "100", + "examine": "This might help me chop harder.", + "grand_exchange_price": "60700", + "durability": null, + "name": "Axeman's folly(m4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5905" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "60700", + "durability": null, + "name": "Axeman's folly(m4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5906" + }, + { + "ge_buy_limit": "100", + "examine": "A fruity, full-bodied ale.", + "grand_exchange_price": "18000", + "durability": null, + "name": "Chef's delight(m1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5907" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "18000", + "durability": null, + "name": "Chef's delight(m1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5908" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal Chef's Delight.", + "grand_exchange_price": "34300", + "durability": null, + "name": "Chef's delight(m2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5909" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "34300", + "durability": null, + "name": "Chef's delight(m2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5910" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal Chef's Delight.", + "grand_exchange_price": "51000", + "durability": null, + "name": "Chef's delight(m3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5911" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "51000", + "durability": null, + "name": "Chef's delight(m3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5912" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal Chef's Delight.", + "grand_exchange_price": "98600", + "durability": null, + "name": "Chef's delight(m4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5913" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "98600", + "durability": null, + "name": "Chef's delight(m4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5914" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal Slayer's Respite.", + "grand_exchange_price": "3672", + "durability": null, + "name": "Slayer respite(m1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5915" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3672", + "durability": null, + "name": "Slayer respite(m1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5916" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal Slayer's Respite.", + "grand_exchange_price": "7258", + "durability": null, + "name": "Slayer respite(m2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5917" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "7258", + "durability": null, + "name": "Slayer respite(m2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5918" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal Slayer's Respite.", + "grand_exchange_price": "10800", + "durability": null, + "name": "Slayer respite(m3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5919" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "10800", + "durability": null, + "name": "Slayer respite(m3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5920" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal Slayer's Respite.", + "grand_exchange_price": "15300", + "durability": null, + "name": "Slayer respite(m4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5921" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "15300", + "durability": null, + "name": "Slayer respite(m4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5922" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal cider.", + "grand_exchange_price": "2966", + "durability": null, + "name": "Cider(m1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5923" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2966", + "durability": null, + "name": "Cider(m1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5924" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal cider.", + "grand_exchange_price": "5845", + "durability": null, + "name": "Cider(m2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5925" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "5845", + "durability": null, + "name": "Cider(m2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5926" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal cider.", + "grand_exchange_price": "8724", + "durability": null, + "name": "Cider(m3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5927" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "8724", + "durability": null, + "name": "Cider(m3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5928" + }, + { + "ge_buy_limit": "100", + "examine": "This looks a good deal stronger than normal cider.", + "grand_exchange_price": "11900", + "durability": null, + "name": "Cider(m4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5929" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "11900", + "durability": null, + "name": "Cider(m4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5930" + }, + { + "ge_buy_limit": "5000", + "examine": "I can weave this to make sacks.", + "grand_exchange_price": "532", + "durability": null, + "name": "Jute fibre", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "5931" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "532", + "durability": null, + "name": "Jute fibre", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5932" + }, + { + "ge_buy_limit": "200", + "examine": "A branch from a willow tree.", + "grand_exchange_price": "1255", + "durability": null, + "name": "Willow branch", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "5933" + }, + { + "ge_buy_limit": "200", + "grand_exchange_price": "1255", + "durability": null, + "name": "Willow branch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5934" + }, + { + "ge_buy_limit": "10000", + "examine": "A vial filled with coconut milk.", + "grand_exchange_price": "1307", + "durability": null, + "name": "Coconut milk", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5935" + }, + { + "ge_buy_limit": "1000", + "examine": "A vial of extra-strong weapon poison, for spears and daggers.", + "grand_exchange_price": "605", + "durability": null, + "name": "Weapon poison+", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5937" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "605", + "durability": null, + "name": "Weapon poison+", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5938" + }, + { + "ge_buy_limit": "1000", + "examine": "A vial of super strong weapon poison, for spears and daggers.", + "grand_exchange_price": "4817", + "durability": null, + "name": "Weapon poison++", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "5940" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "4817", + "durability": null, + "name": "Weapon poison++", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5941" + }, + { + "ge_buy_limit": "1000", + "examine": "N doses of extra-stong antipoison potion", + "grand_exchange_price": "1032", + "durability": null, + "name": "Antipoison+(4)", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "5943" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1032", + "durability": null, + "name": "Antipoison+(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5944" + }, + { + "ge_buy_limit": "1000", + "examine": "N doses of extra-stong antipoison potion", + "grand_exchange_price": "1499", + "durability": null, + "name": "Antipoison+(3)", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "5945" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1499", + "durability": null, + "name": "Antipoison+(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5946" + }, + { + "ge_buy_limit": "1000", + "examine": "N doses of extra-stong antipoison potion", + "grand_exchange_price": "1316", + "durability": null, + "name": "Antipoison+(2)", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "5947" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1316", + "durability": null, + "name": "Antipoison+(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5948" + }, + { + "ge_buy_limit": "1000", + "examine": "N doses of extra-stong antipoison potion", + "grand_exchange_price": "1599", + "durability": null, + "name": "Antipoison+(1)", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "5949" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1599", + "durability": null, + "name": "Antipoison+(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5950" + }, + { + "ge_buy_limit": "1000", + "examine": "4 doses of a super-strong antipoison potion.", + "grand_exchange_price": "1138", + "durability": null, + "name": "Antipoison++(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5952" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1138", + "durability": null, + "name": "Antipoison++(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5953" + }, + { + "ge_buy_limit": "1000", + "examine": "3 doses of a super-strong antipoison potion.", + "grand_exchange_price": "1071", + "durability": null, + "name": "Antipoison++(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5954" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1071", + "durability": null, + "name": "Antipoison++(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5955" + }, + { + "ge_buy_limit": "1000", + "examine": "2 doses of a super-strong antipoison potion.", + "grand_exchange_price": "632", + "durability": null, + "name": "Antipoison++(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5956" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "632", + "durability": null, + "name": "Antipoison++(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5957" + }, + { + "ge_buy_limit": "1000", + "examine": "1 dose of a super-strong antipoison potion.", + "grand_exchange_price": "821", + "durability": null, + "name": "Antipoison++(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5958" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "821", + "durability": null, + "name": "Antipoison++(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5959" + }, + { + "examine": "A basket filled with tomatoes.", + "grand_exchange_price": "663", + "durability": null, + "name": "Tomatoes(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5960" + }, + { + "durability": null, + "name": "Tomatoes(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5961" + }, + { + "examine": "A basket filled with tomatoes.", + "grand_exchange_price": "663", + "durability": null, + "name": "Tomatoes(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5962" + }, + { + "durability": null, + "name": "Tomatoes(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5963" + }, + { + "examine": "A basket filled with tomatoes.", + "grand_exchange_price": "663", + "durability": null, + "name": "Tomatoes(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5964" + }, + { + "durability": null, + "name": "Tomatoes(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5965" + }, + { + "examine": "A basket filled with tomatoes.", + "grand_exchange_price": "663", + "durability": null, + "name": "Tomatoes(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5966" + }, + { + "durability": null, + "name": "Tomatoes(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5967" + }, + { + "ge_buy_limit": "10000", + "examine": "A basket filled with tomatoes.", + "grand_exchange_price": "335", + "durability": null, + "name": "Tomatoes(5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5968" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "335", + "durability": null, + "name": "Tomatoes(5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5969" + }, + { + "ge_buy_limit": "5000", + "examine": "I could make a spicy curry with this.", + "grand_exchange_price": "318", + "durability": null, + "name": "Curry leaf", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5970" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "318", + "durability": null, + "name": "Curry leaf", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5971" + }, + { + "ge_buy_limit": "5000", + "examine": "Looks delicious.", + "grand_exchange_price": "2074", + "durability": null, + "name": "Papaya fruit", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5972" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "2074", + "durability": null, + "name": "Papaya fruit", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5973" + }, + { + "ge_buy_limit": "5000", + "examine": "It's a coconut.", + "grand_exchange_price": "2568", + "durability": null, + "name": "Coconut", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5974" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "2568", + "durability": null, + "name": "Coconut", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5975" + }, + { + "ge_buy_limit": "5000", + "examine": "It's a coconut.", + "grand_exchange_price": "1258", + "durability": null, + "name": "Coconut", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5976" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "1258", + "durability": null, + "name": "Coconut", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5977" + }, + { + "ge_buy_limit": "10000", + "examine": "All the milk has been removed.", + "grand_exchange_price": "54", + "durability": null, + "name": "Coconut shell", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5978" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "54", + "durability": null, + "name": "Coconut shell", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5979" + }, + { + "ge_buy_limit": "100", + "examine": "This is the largest fruit I've ever seen.", + "grand_exchange_price": "43", + "durability": null, + "name": "Calquat fruit", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5980" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "43", + "durability": null, + "name": "Calquat fruit", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5981" + }, + { + "shop_price": "48", + "ge_buy_limit": "10000", + "examine": "A juicy watermelon.", + "grand_exchange_price": "41", + "durability": null, + "name": "Watermelon", + "tradeable": "true", + "weight": "0.111", + "archery_ticket_price": "0", + "id": "5982" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "41", + "durability": null, + "name": "Watermelon", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5983" + }, + { + "ge_buy_limit": "1000", + "examine": "A slice of watermelon.", + "grand_exchange_price": "40", + "durability": null, + "name": "Watermelon slice", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5984" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "40", + "durability": null, + "name": "Watermelon slice", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5985" + }, + { + "ge_buy_limit": "10000", + "examine": "Raw sweetcorn.", + "grand_exchange_price": "19", + "durability": null, + "name": "Sweetcorn", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5986" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "19", + "durability": null, + "name": "Sweetcorn", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5987" + }, + { + "ge_buy_limit": "10000", + "examine": "Delicious cooked sweetcorn.", + "grand_exchange_price": "15", + "durability": null, + "name": "Cooked sweetcorn", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5988" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "15", + "durability": null, + "name": "Cooked sweetcorn", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5989" + }, + { + "durability": null, + "name": "Burnt sweetcorn", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5991" + }, + { + "ge_buy_limit": "100", + "examine": "A bucket of apple mush.", + "grand_exchange_price": "425", + "durability": null, + "name": "Apple mush", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5992" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "425", + "durability": null, + "name": "Apple mush", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5993" + }, + { + "ge_buy_limit": "1000", + "examine": "A handful of Hammerstone hops.", + "grand_exchange_price": "14", + "durability": null, + "name": "Hammerstone hops", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5994" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "14", + "durability": null, + "name": "Hammerstone hops", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5995" + }, + { + "ge_buy_limit": "1000", + "examine": "A handful of Asgarnian hops.", + "grand_exchange_price": "2", + "durability": null, + "name": "Asgarnian hops", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "5996" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "2", + "durability": null, + "name": "Asgarnian hops", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5997" + }, + { + "ge_buy_limit": "1000", + "examine": "A handful of Yanillian hops.", + "grand_exchange_price": "1", + "durability": null, + "name": "Yanillian hops", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5998" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1", + "durability": null, + "name": "Yanillian hops", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "5999" + }, + { + "shop_price": "4", + "ge_buy_limit": "1000", + "examine": "A handful of Krandorian hops.", + "grand_exchange_price": "2", + "durability": null, + "name": "Krandorian hops", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6000" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "2", + "durability": null, + "name": "Krandorian hops", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6001" + }, + { + "ge_buy_limit": "1000", + "examine": "A handful of wildblood hops.", + "grand_exchange_price": "66", + "durability": null, + "name": "Wildblood hops", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6002" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "66", + "durability": null, + "name": "Wildblood hops", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6003" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "219", + "examine": "A Bittercap Mushroom", + "durability": null, + "name": "Mushroom", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6004" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "219", + "durability": null, + "name": "Mushroom", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6005" + }, + { + "ge_buy_limit": "1000", + "examine": "A handful of Barley.", + "grand_exchange_price": "211", + "durability": null, + "name": "Barley", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6006" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "211", + "durability": null, + "name": "Barley", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6007" + }, + { + "ge_buy_limit": "1000", + "examine": "A handful of barley malt.", + "grand_exchange_price": "410", + "durability": null, + "name": "Barley malt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6008" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "410", + "durability": null, + "name": "Barley malt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6009" + }, + { + "ge_buy_limit": "1000", + "examine": "A bunch of marigolds.", + "grand_exchange_price": "3326", + "durability": null, + "name": "Marigolds", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6010" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "3326", + "durability": null, + "name": "Marigolds", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6011" + }, + { + "ge_buy_limit": "1000", + "examine": "A bunch of nasturtiums.", + "grand_exchange_price": "52", + "durability": null, + "name": "Nasturtiums", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6012" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "52", + "durability": null, + "name": "Nasturtiums", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6013" + }, + { + "ge_buy_limit": "1000", + "examine": "Some rosemary.", + "grand_exchange_price": "29", + "durability": null, + "name": "Rosemary", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6014" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "29", + "durability": null, + "name": "Rosemary", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6015" + }, + { + "ge_buy_limit": "10000", + "examine": "Don't prick yourself with this.", + "grand_exchange_price": "6990", + "durability": null, + "name": "Cactus spine", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6016" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "6990", + "durability": null, + "name": "Cactus spine", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6017" + }, + { + "ge_buy_limit": "10000", + "examine": "They look sweet and juicy, but only a fool would eat them.", + "grand_exchange_price": "399", + "durability": null, + "name": "Poison ivy berries", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6018" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "399", + "durability": null, + "name": "Poison ivy berries", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6019" + }, + { + "ge_buy_limit": "100", + "examine": "A pile of leaves.", + "grand_exchange_price": "152", + "durability": null, + "name": "Leaves", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6020" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "152", + "durability": null, + "name": "Leaves", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6021" + }, + { + "ge_buy_limit": "100", + "examine": "A pile of leaves.", + "grand_exchange_price": "27", + "durability": null, + "name": "Leaves", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6022" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "27", + "durability": null, + "name": "Leaves", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6023" + }, + { + "ge_buy_limit": "100", + "examine": "A pile of leaves.", + "grand_exchange_price": "21", + "durability": null, + "name": "Leaves", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6024" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "21", + "durability": null, + "name": "Leaves", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6025" + }, + { + "ge_buy_limit": "100", + "examine": "A pile of leaves.", + "grand_exchange_price": "7", + "durability": null, + "name": "Leaves", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6026" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "7", + "durability": null, + "name": "Leaves", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6027" + }, + { + "ge_buy_limit": "100", + "examine": "A pile of leaves.", + "grand_exchange_price": "11", + "durability": null, + "name": "Leaves", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6028" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "11", + "durability": null, + "name": "Leaves", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6029" + }, + { + "ge_buy_limit": "100", + "examine": "A pile of leaves.", + "grand_exchange_price": "4", + "durability": null, + "name": "Leaves", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6030" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "4", + "durability": null, + "name": "Leaves", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6031" + }, + { + "shop_price": "20", + "ge_buy_limit": "10000", + "examine": "Good for plants, helps them grow.", + "grand_exchange_price": "97", + "durability": null, + "name": "Compost", + "tradeable": "true", + "weight": "3", + "archery_ticket_price": "0", + "id": "6032" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "97", + "durability": null, + "name": "Compost", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6033" + }, + { + "ge_buy_limit": "10000", + "examine": "Super-good for the smallest or largest of plants.", + "grand_exchange_price": "909", + "durability": null, + "name": "Supercompost", + "tradeable": "true", + "weight": "3", + "archery_ticket_price": "0", + "id": "6034" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "909", + "durability": null, + "name": "Supercompost", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6035" + }, + { + "shop_price": "25", + "ge_buy_limit": "100", + "examine": "Use this on plants to cure disease.", + "grand_exchange_price": "170", + "durability": null, + "name": "Plant cure", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6036" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "170", + "durability": null, + "name": "Plant cure", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6037" + }, + { + "ge_buy_limit": "100", + "examine": "I could use this to make jewellery.", + "grand_exchange_price": "1078", + "durability": null, + "name": "Magic string", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6038" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1078", + "durability": null, + "name": "Magic string", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6039" + }, + { + "destroy_message": "You will need to create a new amulet if you destroy this one.", + "examine": "An Amulet of Nature.", + "durability": null, + "name": "Amulet of nature", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "6040", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "100", + "examine": "Strung with the root of a Magic Tree. If I enchant this it will become an amulet of nature.", + "grand_exchange_price": "1996", + "durability": null, + "name": "Pre-nature amulet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6041", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1996", + "durability": null, + "name": "Pre-nature amulet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6042" + }, + { + "ge_buy_limit": "100", + "examine": "The roots of the Oak tree.", + "grand_exchange_price": "60", + "durability": null, + "name": "Oak roots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6043" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "60", + "durability": null, + "name": "Oak roots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6044" + }, + { + "ge_buy_limit": "100", + "examine": "The roots of the Willow tree.", + "grand_exchange_price": "41", + "durability": null, + "name": "Willow roots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6045" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "41", + "durability": null, + "name": "Willow roots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6046" + }, + { + "ge_buy_limit": "100", + "examine": "The roots of the Maple tree.", + "grand_exchange_price": "40", + "durability": null, + "name": "Maple roots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6047" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "40", + "durability": null, + "name": "Maple roots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6048" + }, + { + "ge_buy_limit": "100", + "examine": "The roots of a yew tree", + "grand_exchange_price": "570", + "durability": null, + "name": "Yew roots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6049" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "570", + "durability": null, + "name": "Yew roots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6050" + }, + { + "ge_buy_limit": "100", + "examine": "The roots of a magic tree.", + "grand_exchange_price": "5853", + "durability": null, + "name": "Magic roots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6051" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "5853", + "durability": null, + "name": "Magic roots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6052" + }, + { + "durability": null, + "name": "Spirit roots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6054" + }, + { + "shop_price": "1", + "examine": "A handful of weeds.", + "durability": null, + "name": "Weeds", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6055" + }, + { + "durability": null, + "name": "Weeds", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6056" + }, + { + "examine": "A sack filled with hay. / This sack of hay has a bronze spear sticking through it.", + "durability": null, + "name": "Hay sack", + "archery_ticket_price": "0", + "id": "6057" + }, + { + "examine": "A sack filled with hay. / This sack of hay has a bronze spear sticking through it.", + "durability": null, + "name": "Hay sack", + "archery_ticket_price": "0", + "id": "6058" + }, + { + "examine": "This should scare the birds.", + "durability": null, + "name": "Scarecrow", + "archery_ticket_price": "0", + "id": "6059" + }, + { + "durability": null, + "name": "Stool", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6060" + }, + { + "shop_price": "3", + "ge_buy_limit": "10000", + "examine": "Bronze crossbow bolts.", + "grand_exchange_price": "134", + "durability": null, + "name": "Bronze bolts(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6061", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,10", + "equipment_slot": "13" + }, + { + "shop_price": "3", + "ge_buy_limit": "10000", + "examine": "Bronze crossbow bolts.", + "grand_exchange_price": "1162", + "durability": null, + "name": "Bronze bolts(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6062", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,10", + "equipment_slot": "13" + }, + { + "examine": "How do I wash blood stains out?", + "durability": null, + "name": "Bloody mourner top", + "weight": "2.72", + "archery_ticket_price": "0", + "id": "6064" + }, + { + "remove_sleeves": "true", + "examine": "A thick heavy leather top.", + "durability": null, + "name": "Mourner top", + "archery_ticket_price": "0", + "id": "6065", + "equipment_slot": "4" + }, + { + "examine": "These are in need of a good tailor.", + "durability": null, + "name": "Mourner trousers", + "weight": "2.25", + "archery_ticket_price": "0", + "id": "6066" + }, + { + "examine": "A pair of mourner trousers.", + "durability": null, + "name": "Mourner trousers", + "weight": "2.25", + "archery_ticket_price": "0", + "id": "6067", + "equipment_slot": "7" + }, + { + "shop_price": "160", + "examine": "These will keep my hands warm.", + "durability": null, + "name": "Mourner gloves", + "weight": "2.3", + "archery_ticket_price": "0", + "id": "6068", + "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0", + "equipment_slot": "9" + }, + { + "shop_price": "160", + "examine": "Comfortable leather boots.", + "durability": null, + "name": "Mourner boots", + "weight": "1.36", + "archery_ticket_price": "0", + "id": "6069", + "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", + "equipment_slot": "10" + }, + { + "examine": "A dull brown cape.", + "durability": null, + "name": "Mourner cloak", + "weight": "2.25", + "archery_ticket_price": "0", + "id": "6070", + "equipment_slot": "1" + }, + { + "shop_price": "160", + "examine": "A letter of recommendation.", + "durability": null, + "name": "Mourner letter", + "archery_ticket_price": "0", + "id": "6071" + }, + { + "examine": "A bar of soap taken from Tegid.", + "durability": null, + "name": "Tegid's soap", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "6072" + }, + { + "examine": "A book on the history of Prifddinas.", + "durability": null, + "name": "Prifddinas' history", + "archery_ticket_price": "0", + "id": "6073" + }, + { + "examine": "A book on the exploration of the eastern realm.", + "durability": null, + "name": "Eastern discovery", + "archery_ticket_price": "0", + "id": "6075" + }, + { + "examine": "A book on the settlement of the eastern realm.", + "durability": null, + "name": "Eastern settlement", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6077" + }, + { + "examine": "A book about the great divide.", + "durability": null, + "name": "The great divide", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "6079" + }, + { + "examine": "A strange broken device of gnomic design.", + "durability": null, + "name": "Broken device", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6081" + }, + { + "turn90cw_anim": "2319", + "examine": "A device for firing dye.", + "walk_anim": "2317", + "durability": null, + "weight": "4", + "turn90ccw_anim": "2320", + "attack_speed": "4", + "two_handed": "true", + "weapon_interface": "20", + "turn180_anim": "2318", + "render_anim": "284", + "equipment_slot": "3", + "stand_anim": "2316", + "name": "Fixed device", + "run_anim": "2322", + "archery_ticket_price": "0", + "id": "6082", + "stand_turn_anim": "2321" + }, + { + "examine": "This key has seen a lot of use. (Mourning's Ends Part I)", + "durability": null, + "name": "Tarnished key", + "archery_ticket_price": "0", + "id": "6083" + }, + { + "examine": "A large pair of ogre bellows filled with red dye.", + "durability": null, + "name": "Red dye bellows", + "archery_ticket_price": "0", + "id": "6085" + }, + { + "examine": "A large pair of ogre bellows filled with blue dye.", + "durability": null, + "name": "Blue dye bellows", + "archery_ticket_price": "0", + "id": "6086" + }, + { + "examine": "A large pair of ogre bellows filled with yellow dye.", + "durability": null, + "name": "Yellow dye bellows", + "archery_ticket_price": "0", + "id": "6087" + }, + { + "examine": "A large pair of ogre bellows filled with green dye.", + "durability": null, + "name": "Green dye bellows", + "archery_ticket_price": "0", + "id": "6088" + }, + { + "examine": "A blue dye filled toad.", + "durability": null, + "name": "Blue toad", + "weight": "1", + "archery_ticket_price": "0", + "id": "6089" + }, + { + "examine": "A red dye filled toad.", + "durability": null, + "name": "Red toad", + "weight": "0.7", + "archery_ticket_price": "0", + "id": "6090" + }, + { + "examine": "A yellow dye filled toad.", + "durability": null, + "name": "Yellow toad", + "weight": "0.7", + "archery_ticket_price": "0", + "id": "6091" + }, + { + "examine": "A green dye filled toad.", + "durability": null, + "name": "Green toad", + "weight": "1", + "archery_ticket_price": "0", + "id": "6092" + }, + { + "examine": "A barrel full of rotten apples.", + "durability": null, + "name": "Rotten apples", + "weight": "17", + "archery_ticket_price": "0", + "id": "6093" + }, + { + "examine": "A barrel full of mushed apples.", + "durability": null, + "name": "Apple barrel", + "archery_ticket_price": "0", + "id": "6094" + }, + { + "examine": "A barrel full of rotten apples and naptha.", + "durability": null, + "name": "Naphtha apple mix", + "archery_ticket_price": "0", + "id": "6095" + }, + { + "examine": "A barrel full of toxic naphtha.", + "durability": null, + "name": "Toxic naphtha", + "weight": "32", + "archery_ticket_price": "0", + "id": "6096" + }, + { + "examine": "It's a sieve.", + "durability": null, + "name": "Sieve", + "archery_ticket_price": "0", + "id": "6097" + }, + { + "examine": "A pile of toxic powder.", + "durability": null, + "name": "Toxic powder", + "archery_ticket_price": "0", + "id": "6098" + }, + { + "examine": "A tiny crystal enchanted to return the user to Lletya.", + "durability": null, + "name": "Teleport crystal (4)", + "archery_ticket_price": "0", + "id": "6099" + }, + { + "examine": "A tiny crystal enchanted to return the user to Lletya.", + "durability": null, + "name": "Teleport crystal (3)", + "archery_ticket_price": "0", + "id": "6100" + }, + { + "examine": "A tiny crystal enchanted to return the user to Lletya.", + "durability": null, + "name": "Teleport crystal (2)", + "archery_ticket_price": "0", + "id": "6101" + }, + { + "examine": "A tiny crystal enchanted to return the user to Lletya.", + "durability": null, + "name": "Teleport crystal (1)", + "archery_ticket_price": "0", + "id": "6102" + }, + { + "examine": "A tiny Elf crystal, I need to have this re-enchanted", + "durability": null, + "name": "Tiny elf crystal", + "archery_ticket_price": "0", + "id": "6103" + }, + { + "examine": "This key is newly cut. (Mourning's Ends Part II)", + "durability": null, + "name": "New key", + "weight": "0.33", + "archery_ticket_price": "0", + "id": "6104" + }, + { + "examine": "They seem to be not quite of this world...", + "durability": null, + "name": "Ghostly boots", + "archery_ticket_price": "0", + "id": "6106", + "bonuses": "0,0,0,2,0,0,0,0,2,0,0,0,0,0,0", + "equipment_slot": "10" + }, + { + "remove_sleeves": "true", + "examine": "Varies", + "durability": null, + "name": "Ghostly robe", + "archery_ticket_price": "0", + "id": "6107", + "bonuses": "0,0,0,5,0,0,0,0,5,0,5,0,0,0,0", + "equipment_slot": "4" + }, + { + "examine": "Varies", + "durability": null, + "name": "Ghostly robe", + "archery_ticket_price": "0", + "id": "6108", + "bonuses": "0,0,0,4,0,0,0,0,4,0,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "remove_head": "true", + "examine": "A ghostly hood, fit for a ghostly head.", + "durability": null, + "name": "Ghostly hood", + "archery_ticket_price": "0", + "id": "6109", + "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "examine": "They seem to fade in and out of existence...", + "durability": null, + "name": "Ghostly gloves", + "archery_ticket_price": "0", + "id": "6110", + "bonuses": "0,0,0,2,0,0,0,0,2,0,0,0,0,0,0", + "equipment_slot": "9" + }, + { + "examine": "Made of a strange, ghostly material...", + "durability": null, + "name": "Ghostly cloak", + "archery_ticket_price": "0", + "id": "6111", + "bonuses": "0,0,0,5,0,0,0,0,5,0,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "destroy_message": "Return to the drunken dwarf's drunken relative to get your seeds back.", + "examine": "Kelda hop seeds can only be grown underground!", + "durability": null, + "name": "Kelda seed", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6112" + }, + { + "destroy_message": "Return to the Keldagrim palace gardener to get your hops back.", + "examine": "A handful of Kelda Hops.", + "durability": null, + "name": "Kelda hops", + "tradeable": "false", + "destroy": "true", + "weight": "0.01", + "archery_ticket_price": "0", + "id": "6113" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A pint of bluish beer.", + "durability": null, + "name": "Kelda stout", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "6118" + }, + { + "examine": "There is a strange [green/yellow] marking on this stone.", + "durability": null, + "name": "Square stone", + "weight": "1", + "archery_ticket_price": "0", + "id": "6119" + }, + { + "examine": "There is a strange [green/yellow] marking on this stone.", + "durability": null, + "name": "Square stone", + "weight": "1", + "archery_ticket_price": "0", + "id": "6120" + }, + { + "durability": null, + "name": "A chair", + "archery_ticket_price": "0", + "id": "6122", + "equipment_slot": "5" + }, + { + "shop_price": "1", + "examine": "I need to fill this with beer.", + "grand_exchange_price": "25", + "durability": null, + "name": "Beer glass", + "tradeable": "true", + "weight": "0.05", + "archery_ticket_price": "0", + "id": "6123", + "equipment_slot": "3" + }, + { + "durability": null, + "name": "Coconut milk", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6124" + }, + { + "examine": "This will teleport me to Rellekka when I play it.", + "durability": null, + "name": "Enchanted lyre(2)", + "weight": "1.8", + "archery_ticket_price": "0", + "id": "6125", + "equipment_slot": "3" + }, + { + "examine": "This will teleport me to Rellekka when I play it.", + "durability": null, + "name": "Enchanted lyre(3)", + "weight": "1.8", + "archery_ticket_price": "0", + "id": "6126", + "equipment_slot": "3" + }, + { + "examine": "This will teleport me to Rellekka when I play it.", + "durability": null, + "name": "Enchanted lyre(4)", + "weight": "1.8", + "archery_ticket_price": "0", + "id": "6127", + "equipment_slot": "3" + }, + { + "remove_head": "true", + "requirements": "{1,40}", + "ge_buy_limit": "100", + "examine": "Protective headwear made from crabs. Better than it sounds.", + "durability": null, + "weight": "2.7", + "absorb": "1,0,3", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "21000", + "name": "Rock-shell helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6128", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,6,0,0,0,0" + }, + { + "lendable": "true", + "requirements": "{1,40}", + "remove_sleeves": "true", + "ge_buy_limit": "100", + "grand_exchange_price": "40600", + "durability": null, + "name": "Rock-shell plate", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6129", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,30,0,0,0,0", + "equipment_slot": "4" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "100", + "examine": "Some tough leggings made from rock crab parts.", + "durability": null, + "weight": "9", + "absorb": "2,0,4", + "equipment_slot": "7", + "lendable": "true", + "grand_exchange_price": "39400", + "name": "Rock-shell legs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6130", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,10,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,40}-{4,40}", + "ge_buy_limit": "100", + "examine": "A helm fit for any Fremennik ranger.", + "durability": null, + "weight": "1", + "absorb": "0,3,1", + "remove_beard": "true", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "35800", + "name": "Spined helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6131", + "bonuses": "-6,-6,-6,-6,6,6,6,6,6,0,6,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "35800", + "durability": null, + "name": "Spined helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6132" + }, + { + "requirements": "{1,40}-{4,40}", + "ge_buy_limit": "100", + "examine": "A constant reminder that I'm above a Dagannoth in the food chain.", + "durability": null, + "weight": "6", + "absorb": "0,6,3", + "equipment_slot": "4", + "lendable": "true", + "remove_sleeves": "true", + "grand_exchange_price": "4386", + "name": "Spined body", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6133", + "bonuses": "0,0,0,-15,15,40,32,45,20,40,30,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "4386", + "durability": null, + "name": "Spined body", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6134" + }, + { + "requirements": "{1,40}-{4,40}", + "ge_buy_limit": "100", + "examine": "Stylish leg armour for rangers with a lingering smell of raw fish...", + "durability": null, + "weight": "5", + "absorb": "0,4,2", + "equipment_slot": "7", + "lendable": "true", + "grand_exchange_price": "2132", + "name": "Spined chaps", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6135", + "bonuses": "0,0,0,-10,8,22,16,24,8,22,10,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2132", + "durability": null, + "name": "Spined chaps", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6136" + }, + { + "remove_head": "true", + "requirements": "{1,40}-{6,40}", + "ge_buy_limit": "100", + "examine": "Make your foes cower by wearing a skull as a helmet!", + "durability": null, + "weight": "1.3", + "absorb": "3,1,0", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "29500", + "name": "Skeletal helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6137", + "bonuses": "0,0,0,2,-2,10,9,11,3,0,6,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "29500", + "durability": null, + "name": "Skeletal helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6138" + }, + { + "requirements": "{1,40}-{6,40}", + "ge_buy_limit": "100", + "examine": "The bones in this armour seems to vibrate with a magic quality...", + "durability": null, + "weight": "4.9", + "absorb": "6,3,0", + "equipment_slot": "4", + "lendable": "true", + "remove_sleeves": "true", + "grand_exchange_price": "27800", + "name": "Skeletal top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6139", + "bonuses": "0,0,0,8,-10,35,25,42,15,0,30,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "27800", + "durability": null, + "name": "Skeletal top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6140" + }, + { + "requirements": "{1,40}-{6,40}", + "ge_buy_limit": "100", + "examine": "A superior set of strengthened slacks for any self respecting seer.", + "durability": null, + "weight": "4", + "absorb": "4,2,0", + "equipment_slot": "7", + "lendable": "true", + "grand_exchange_price": "23600", + "name": "Skeletal bottoms", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6141", + "bonuses": "0,0,0,6,-7,22,20,24,10,0,10,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "23600", + "durability": null, + "name": "Skeletal bottoms", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6142" + }, + { + "ge_buy_limit": "100", + "examine": "Some finely crafted Fremennik boots, made from spined dagannoth hide.", + "durability": null, + "weight": "3", + "equip_audio": "2237", + "equipment_slot": "10", + "lendable": "true", + "grand_exchange_price": "1671", + "name": "Spined boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6143", + "bonuses": "0,0,0,0,0,0,1,1,0,0,1,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1671", + "durability": null, + "name": "Spined boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6144" + }, + { + "ge_buy_limit": "100", + "examine": "Some Fremennik boots, made from the shards of a rock crab's shell.", + "durability": null, + "weight": "3.1", + "equip_audio": "2237", + "equipment_slot": "10", + "lendable": "true", + "grand_exchange_price": "756", + "name": "Rock-shell boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6145", + "bonuses": "0,0,0,0,0,0,1,1,0,0,1,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "756", + "durability": null, + "name": "Rock-shell boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6146" + }, + { + "lendable": "true", + "ge_buy_limit": "100", + "examine": "Some finely crafted Fremennik boots, made from the bones of a Wallasalki.", + "grand_exchange_price": "4958", + "durability": null, + "name": "Skeletal boots", + "tradeable": "true", + "weight": "3.1", + "archery_ticket_price": "0", + "id": "6147", + "bonuses": "0,0,0,0,0,0,1,1,0,0,1,0,0,0,0", + "equipment_slot": "10" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "4958", + "durability": null, + "name": "Skeletal boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6148" + }, + { + "lendable": "true", + "ge_buy_limit": "100", + "examine": "Fremennik gloves stitched together from spined dagannoth hide.", + "grand_exchange_price": "955", + "durability": null, + "name": "Spined gloves", + "tradeable": "true", + "weight": "3", + "archery_ticket_price": "0", + "id": "6149", + "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0", + "equipment_slot": "9" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "955", + "durability": null, + "name": "Spined gloves", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6150" + }, + { + "lendable": "true", + "ge_buy_limit": "100", + "examine": "Fremennik gloves stitched together from rock crab shell shards.", + "grand_exchange_price": "951", + "durability": null, + "name": "Rock-shell gloves", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "6151", + "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0", + "equipment_slot": "9" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "951", + "durability": null, + "name": "Rock-shell gloves", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6152" + }, + { + "lendable": "true", + "ge_buy_limit": "100", + "examine": "Fremennik gloves stitched together from wallasalki bones fragments.", + "grand_exchange_price": "21800", + "durability": null, + "name": "Skeletal gloves", + "tradeable": "true", + "weight": "3.1", + "archery_ticket_price": "0", + "id": "6153", + "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0", + "equipment_slot": "9" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "21800", + "durability": null, + "name": "Skeletal gloves", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6154" + }, + { + "ge_buy_limit": "500", + "examine": "A sturdy piece of dagannoth hide.", + "grand_exchange_price": "3978", + "durability": null, + "name": "Dagannoth hide", + "tradeable": "true", + "weight": "3.1", + "archery_ticket_price": "0", + "id": "6155" + }, + { + "ge_buy_limit": "500", + "grand_exchange_price": "3978", + "durability": null, + "name": "Dagannoth hide", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6156" + }, + { + "ge_buy_limit": "100", + "examine": "A spherical chunk of rock-shell.", + "grand_exchange_price": "7371", + "durability": null, + "name": "Rock-shell chunk", + "tradeable": "true", + "weight": "3", + "archery_ticket_price": "0", + "id": "6157" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "7371", + "durability": null, + "name": "Rock-shell chunk", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6158" + }, + { + "ge_buy_limit": "100", + "examine": "A curved piece of rock-shell.", + "grand_exchange_price": "11300", + "durability": null, + "name": "Rock-shell shard", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6159" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "11300", + "durability": null, + "name": "Rock-shell shard", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6160" + }, + { + "ge_buy_limit": "100", + "examine": "A slim piece of rock-shell.", + "grand_exchange_price": "16100", + "durability": null, + "name": "Rock-shell splinter", + "tradeable": "true", + "weight": "3", + "archery_ticket_price": "0", + "id": "6161" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "16100", + "durability": null, + "name": "Rock-shell splinter", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6162" + }, + { + "ge_buy_limit": "100", + "examine": "A fearsome looking skull.", + "grand_exchange_price": "9859", + "durability": null, + "name": "Skull piece", + "tradeable": "true", + "weight": "3.1", + "archery_ticket_price": "0", + "id": "6163" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "9859", + "durability": null, + "name": "Skull piece", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6164" + }, + { + "ge_buy_limit": "100", + "examine": "A slightly damaged ribcage.", + "grand_exchange_price": "11300", + "durability": null, + "name": "Ribcage piece", + "tradeable": "true", + "weight": "3.1", + "archery_ticket_price": "0", + "id": "6165" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "11300", + "durability": null, + "name": "Ribcage piece", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6166" + }, + { + "ge_buy_limit": "100", + "examine": "An interesting looking bone shard.", + "grand_exchange_price": "10300", + "durability": null, + "name": "Fibula piece", + "tradeable": "true", + "weight": "3.1", + "archery_ticket_price": "0", + "id": "6167" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "10300", + "durability": null, + "name": "Fibula piece", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6168" + }, + { + "ge_buy_limit": "100", + "examine": "A toughened chunk of dagannoth hide.", + "grand_exchange_price": "23400", + "durability": null, + "name": "Circular hide", + "tradeable": "true", + "weight": "3.1", + "archery_ticket_price": "0", + "id": "6169" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "23400", + "durability": null, + "name": "Circular hide", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6170" + }, + { + "ge_buy_limit": "100", + "examine": "A tattered chunk of dagannoth hide.", + "grand_exchange_price": "502", + "durability": null, + "name": "Flattened hide", + "tradeable": "true", + "weight": "3.1", + "archery_ticket_price": "0", + "id": "6171" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "502", + "durability": null, + "name": "Flattened hide", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6172" + }, + { + "ge_buy_limit": "100", + "examine": "A weathered chunk of dagannoth hide.", + "grand_exchange_price": "398", + "durability": null, + "name": "Stretched hide", + "tradeable": "true", + "weight": "3.1", + "archery_ticket_price": "0", + "id": "6173" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "398", + "durability": null, + "name": "Stretched hide", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6174" + }, + { + "durability": null, + "name": "Rock-shell helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6175" + }, + { + "examine": "A sturdy body armour made from rock crab pieces.", + "durability": null, + "name": "Rock-shell plate", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "9", + "id": "6176" + }, + { + "durability": null, + "name": "Rock-shell legs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6177" + }, + { + "examine": "I need to cook this first.", + "durability": null, + "name": "Raw pheasant", + "weight": "10", + "archery_ticket_price": "0", + "id": "6178" + }, + { + "examine": "I need to cook this first.", + "durability": null, + "name": "Raw pheasant", + "weight": "10", + "archery_ticket_price": "0", + "id": "6179" + }, + { + "remove_sleeves": "true", + "examine": "A leather strapped top.", + "durability": null, + "name": "Lederhosen top", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "6180", + "equipment_slot": "4" + }, + { + "examine": "Brown leather shorts with bright white socks?", + "durability": null, + "name": "Lederhosen shorts", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "6181", + "equipment_slot": "7" + }, + { + "remove_head": "true", + "examine": "A hat with a goat's hair attached.", + "durability": null, + "name": "Lederhosen hat", + "weight": "2", + "archery_ticket_price": "0", + "id": "6182", + "equipment_slot": "0" + }, + { + "examine": "I can use this at the Varrock clothes shop.", + "durability": null, + "name": "Frog token", + "archery_ticket_price": "0", + "id": "6183" + }, + { + "remove_sleeves": "true", + "examine": "Very posh!", + "durability": null, + "name": "Prince tunic", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "6184", + "equipment_slot": "4" + }, + { + "examine": "Very posh!", + "durability": null, + "name": "Prince leggings", + "weight": "2", + "archery_ticket_price": "0", + "id": "6185", + "equipment_slot": "7" + }, + { + "remove_sleeves": "true", + "examine": "Very posh!", + "durability": null, + "name": "Princess blouse", + "weight": "2", + "archery_ticket_price": "0", + "id": "6186", + "equipment_slot": "4" + }, + { + "examine": "Very posh!", + "durability": null, + "name": "Princess skirt", + "weight": "2", + "archery_ticket_price": "0", + "id": "6187", + "equipment_slot": "7" + }, + { + "remove_head": "true", + "examine": "Now that's just silly.", + "durability": null, + "name": "Frog mask", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "6188", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "examine": "Could there be something valuable in here?", + "durability": null, + "name": "Mystery box", + "weight": "1", + "archery_ticket_price": "0", + "id": "6199", + "point_price": "2" + }, + { + "destroy_message": "A ghastly fish", + "examine": "A raw...fish? Is this a fish??", + "durability": null, + "name": "Raw fishlike thing", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "6200" + }, + { + "examine": "Fish-tastic!", + "durability": null, + "name": "Picture", + "archery_ticket_price": "0", + "id": "6201" + }, + { + "destroy_message": "A ghastly fish", + "examine": "It's a fish-like thing that appears to already be cooked. It looks disgusting.", + "durability": null, + "name": "Fishlike thing", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "6202" + }, + { + "destroy_message": "A ghastly fish", + "examine": "A raw...fish? Is this a fish??", + "durability": null, + "name": "Raw fishlike thing", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "6204" + }, + { + "destroy_message": "A ghastly fish", + "examine": "It's a fish-like thing that appears to already be cooked. It looks disgusting.", + "durability": null, + "name": "Fishlike thing", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "6206" + }, + { + "examine": "It's an amulet of Man speak. It makes vague grunting noises.", + "durability": null, + "name": "Man speak amulet", + "archery_ticket_price": "0", + "id": "6208", + "equipment_slot": "2" + }, + { + "shop_price": "40", + "examine": "Useful for catching small fish.", + "grand_exchange_price": "433", + "durability": null, + "name": "Small fishing net", + "tradeable": "true", + "weight": "4.5", + "archery_ticket_price": "0", + "id": "6209" + }, + { + "ge_buy_limit": "1000", + "examine": "Teak logs prepared with sacred oil for a funeral pyre.", + "grand_exchange_price": "3365", + "durability": null, + "name": "Teak pyre logs", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "6211" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "3365", + "durability": null, + "name": "Teak pyre logs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6212" + }, + { + "ge_buy_limit": "1000", + "examine": "Mahogany logs prepared with sacred oil for a funeral pyre.", + "grand_exchange_price": "3574", + "durability": null, + "name": "Mahogany pyre log", + "tradeable": "true", + "weight": "1.3", + "archery_ticket_price": "0", + "id": "6213" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "3574", + "durability": null, + "name": "Mahogany pyre log", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6214" + }, + { + "requirements": "{1,25}-{6,25}", + "ge_buy_limit": "100", + "examine": "A scary broodoo shield.", + "durability": null, + "weight": "5.4", + "absorb": "4,2,0", + "equipment_slot": "5", + "grand_exchange_price": "2007", + "name": "Broodoo shield (10)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6215", + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2007", + "durability": null, + "name": "Broodoo shield (10)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6216" + }, + { + "requirements": "{1,25}-{6,25}", + "examine": "A scary broodoo shield.", + "grand_exchange_price": "1", + "durability": null, + "name": "Broodoo shield (9)", + "tradeable": "true", + "weight": "5.4", + "archery_ticket_price": "0", + "id": "6217", + "absorb": "4,2,0", + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "equipment_slot": "5" + }, + { + "durability": null, + "name": "Broodoo shield (9)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6218" + }, + { + "requirements": "{1,25}-{6,25}", + "examine": "A scary broodoo shield.", + "grand_exchange_price": "1", + "durability": null, + "name": "Broodoo shield (8)", + "tradeable": "true", + "weight": "5.4", + "archery_ticket_price": "0", + "id": "6219", + "absorb": "4,2,0", + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "equipment_slot": "5" + }, + { + "durability": null, + "name": "Broodoo shield (8)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6220" + }, + { + "requirements": "{1,25}-{6,25}", + "examine": "A scary broodoo shield.", + "grand_exchange_price": "1", + "durability": null, + "name": "Broodoo shield (7)", + "tradeable": "true", + "weight": "5.4", + "archery_ticket_price": "0", + "id": "6221", + "absorb": "4,2,0", + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "equipment_slot": "5" + }, + { + "durability": null, + "name": "Broodoo shield (7)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6222" + }, + { + "requirements": "{1,25}-{6,25}", + "examine": "A scary broodoo shield.", + "grand_exchange_price": "1", + "durability": null, + "name": "Broodoo shield (6)", + "tradeable": "true", + "weight": "5.4", + "archery_ticket_price": "0", + "id": "6223", + "absorb": "4,2,0", + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "equipment_slot": "5" + }, + { + "durability": null, + "name": "Broodoo shield (6)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6224" + }, + { + "requirements": "{1,25}-{6,25}", + "examine": "A scary broodoo shield.", + "grand_exchange_price": "1", + "durability": null, + "name": "Broodoo shield (5)", + "tradeable": "true", + "weight": "5.4", + "archery_ticket_price": "0", + "id": "6225", + "absorb": "4,2,0", + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "equipment_slot": "5" + }, + { + "durability": null, + "name": "Broodoo shield (5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6226" + }, + { + "requirements": "{1,25}-{6,25}", + "examine": "A scary broodoo shield.", + "grand_exchange_price": "1", + "durability": null, + "name": "Broodoo shield (4)", + "tradeable": "true", + "weight": "5.4", + "archery_ticket_price": "0", + "id": "6227", + "absorb": "4,2,0", + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "equipment_slot": "5" + }, + { + "durability": null, + "name": "Broodoo shield (4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6228" + }, + { + "requirements": "{1,25}-{6,25}", + "examine": "A scary broodoo shield.", + "grand_exchange_price": "1", + "durability": null, + "name": "Broodoo shield (3)", + "tradeable": "true", + "weight": "5.4", + "archery_ticket_price": "0", + "id": "6229", + "absorb": "4,2,0", + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "equipment_slot": "5" + }, + { + "durability": null, + "name": "Broodoo shield (3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6230" + }, + { + "requirements": "{1,25}-{6,25}", + "examine": "A scary broodoo shield.", + "grand_exchange_price": "1", + "durability": null, + "name": "Broodoo shield (2)", + "tradeable": "true", + "weight": "5.4", + "archery_ticket_price": "0", + "id": "6231", + "absorb": "4,2,0", + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "equipment_slot": "5" + }, + { + "durability": null, + "name": "Broodoo shield (2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6232" + }, + { + "requirements": "{1,25}-{6,25}", + "examine": "A scary broodoo shield.", + "grand_exchange_price": "1", + "durability": null, + "name": "Broodoo shield (1)", + "tradeable": "true", + "weight": "5.4", + "archery_ticket_price": "0", + "id": "6233", + "absorb": "4,2,0", + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "equipment_slot": "5" + }, + { + "durability": null, + "name": "Broodoo shield (1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6234" + }, + { + "requirements": "{1,25}-{6,25}", + "ge_buy_limit": "100", + "examine": "A scary broodoo shield.", + "durability": null, + "weight": "5.4", + "absorb": "4,2,0", + "equipment_slot": "5", + "grand_exchange_price": "2572", + "name": "Broodoo shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6235", + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2572", + "durability": null, + "name": "Broodoo shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6236" + }, + { + "requirements": "{1,25}-{6,25}", + "ge_buy_limit": "100", + "examine": "A scary broodoo shield.", + "durability": null, + "weight": "5.4", + "absorb": "4,2,0", + "equipment_slot": "5", + "grand_exchange_price": "2200", + "name": "Broodoo shield (10)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6237", + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2200", + "durability": null, + "name": "Broodoo shield (10)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6238" + }, + { + "requirements": "{1,25}-{6,25}", + "examine": "A scary broodoo shield.", + "grand_exchange_price": "1", + "durability": null, + "name": "Broodoo shield (9)", + "tradeable": "true", + "weight": "5.4", + "archery_ticket_price": "0", + "id": "6239", + "absorb": "4,2,0", + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "equipment_slot": "5" + }, + { + "durability": null, + "name": "Broodoo shield (9)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6240" + }, + { + "requirements": "{1,25}-{6,25}", + "examine": "A scary broodoo shield.", + "grand_exchange_price": "1", + "durability": null, + "name": "Broodoo shield (8)", + "tradeable": "true", + "weight": "5.4", + "archery_ticket_price": "0", + "id": "6241", + "absorb": "4,2,0", + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "equipment_slot": "5" + }, + { + "durability": null, + "name": "Broodoo shield (8)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6242" + }, + { + "requirements": "{1,25}-{6,25}", + "examine": "A scary broodoo shield.", + "grand_exchange_price": "1", + "durability": null, + "name": "Broodoo shield (7)", + "tradeable": "true", + "weight": "5.4", + "archery_ticket_price": "0", + "id": "6243", + "absorb": "4,2,0", + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "equipment_slot": "5" + }, + { + "durability": null, + "name": "Broodoo shield (7)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6244" + }, + { + "requirements": "{1,25}-{6,25}", + "examine": "A scary broodoo shield.", + "grand_exchange_price": "1", + "durability": null, + "name": "Broodoo shield (6)", + "tradeable": "true", + "weight": "5.4", + "archery_ticket_price": "0", + "id": "6245", + "absorb": "4,2,0", + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "equipment_slot": "5" + }, + { + "durability": null, + "name": "Broodoo shield (6)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6246" + }, + { + "requirements": "{1,25}-{6,25}", + "examine": "A scary broodoo shield.", + "grand_exchange_price": "1", + "durability": null, + "name": "Broodoo shield (5)", + "tradeable": "true", + "weight": "5.4", + "archery_ticket_price": "0", + "id": "6247", + "absorb": "4,2,0", + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "equipment_slot": "5" + }, + { + "durability": null, + "name": "Broodoo shield (5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6248" + }, + { + "requirements": "{1,25}-{6,25}", + "examine": "A scary broodoo shield.", + "grand_exchange_price": "1", + "durability": null, + "name": "Broodoo shield (4)", + "tradeable": "true", + "weight": "5.4", + "archery_ticket_price": "0", + "id": "6249", + "absorb": "4,2,0", + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "equipment_slot": "5" + }, + { + "durability": null, + "name": "Broodoo shield (4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6250" + }, + { + "requirements": "{1,25}-{6,25}", + "examine": "A scary broodoo shield.", + "grand_exchange_price": "1", + "durability": null, + "name": "Broodoo shield (3)", + "tradeable": "true", + "weight": "5.4", + "archery_ticket_price": "0", + "id": "6251", + "absorb": "4,2,0", + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "equipment_slot": "5" + }, + { + "durability": null, + "name": "Broodoo shield (3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6252" + }, + { + "requirements": "{1,25}-{6,25}", + "examine": "A scary broodoo shield.", + "grand_exchange_price": "1", + "durability": null, + "name": "Broodoo shield (2)", + "tradeable": "true", + "weight": "5.4", + "archery_ticket_price": "0", + "id": "6253", + "absorb": "4,2,0", + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "equipment_slot": "5" + }, + { + "durability": null, + "name": "Broodoo shield (2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6254" + }, + { + "requirements": "{1,25}-{6,25}", + "examine": "A scary broodoo shield.", + "grand_exchange_price": "1", + "durability": null, + "name": "Broodoo shield (1)", + "tradeable": "true", + "weight": "5.4", + "archery_ticket_price": "0", + "id": "6255", + "absorb": "4,2,0", + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "equipment_slot": "5" + }, + { + "durability": null, + "name": "Broodoo shield (1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6256" + }, + { + "requirements": "{1,25}-{6,25}", + "ge_buy_limit": "100", + "examine": "A scary broodoo shield.", + "durability": null, + "weight": "5.4", + "absorb": "4,2,0", + "equipment_slot": "5", + "grand_exchange_price": "2731", + "name": "Broodoo shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6257", + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2731", + "durability": null, + "name": "Broodoo shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6258" + }, + { + "requirements": "{1,25}-{6,25}", + "ge_buy_limit": "100", + "examine": "A scary broodoo shield.", + "durability": null, + "weight": "5.4", + "absorb": "4,2,0", + "equipment_slot": "5", + "grand_exchange_price": "1494", + "name": "Broodoo shield (10)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6259", + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0" + }, + { + "attack_anims": "7060", + "ge_buy_limit": "100", + "grand_exchange_price": "1494", + "durability": null, + "name": "Broodoo shield (10)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6260" + }, + { + "requirements": "{1,25}-{6,25}", + "examine": "A scary broodoo shield.", + "grand_exchange_price": "1", + "durability": null, + "name": "Broodoo shield (9)", + "tradeable": "true", + "weight": "5.4", + "archery_ticket_price": "0", + "id": "6261", + "absorb": "4,2,0", + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "equipment_slot": "5" + }, + { + "durability": null, + "name": "Broodoo shield (9)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6262" + }, + { + "requirements": "{1,25}-{6,25}", + "examine": "A scary broodoo shield.", + "grand_exchange_price": "1", + "durability": null, + "name": "Broodoo shield (8)", + "tradeable": "true", + "weight": "5.4", + "archery_ticket_price": "0", + "id": "6263", + "absorb": "4,2,0", + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "equipment_slot": "5" + }, + { + "durability": null, + "name": "Broodoo shield (8)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6264" + }, + { + "requirements": "{1,25}-{6,25}", + "examine": "A scary broodoo shield.", + "grand_exchange_price": "1", + "durability": null, + "name": "Broodoo shield (7)", + "tradeable": "true", + "weight": "5.4", + "archery_ticket_price": "0", + "id": "6265", + "absorb": "4,2,0", + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "equipment_slot": "5" + }, + { + "durability": null, + "name": "Broodoo shield (7)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6266" + }, + { + "requirements": "{1,25}-{6,25}", + "examine": "A scary broodoo shield.", + "grand_exchange_price": "1", + "durability": null, + "name": "Broodoo shield (6)", + "tradeable": "true", + "weight": "5.4", + "archery_ticket_price": "0", + "id": "6267", + "absorb": "4,2,0", + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "equipment_slot": "5" + }, + { + "durability": null, + "name": "Broodoo shield (6)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6268" + }, + { + "requirements": "{1,25}-{6,25}", + "examine": "A scary broodoo shield.", + "grand_exchange_price": "1", + "durability": null, + "name": "Broodoo shield (5)", + "tradeable": "true", + "weight": "5.4", + "archery_ticket_price": "0", + "id": "6269", + "absorb": "4,2,0", + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "equipment_slot": "5" + }, + { + "durability": null, + "name": "Broodoo shield (5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6270" + }, + { + "requirements": "{1,25}-{6,25}", + "examine": "A scary broodoo shield.", + "grand_exchange_price": "1", + "durability": null, + "name": "Broodoo shield (4)", + "tradeable": "true", + "weight": "5.4", + "archery_ticket_price": "0", + "id": "6271", + "absorb": "4,2,0", + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "equipment_slot": "5" + }, + { + "durability": null, + "name": "Broodoo shield (4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6272" + }, + { + "requirements": "{1,25}-{6,25}", + "examine": "A scary broodoo shield.", + "grand_exchange_price": "1", + "durability": null, + "name": "Broodoo shield (3)", + "tradeable": "true", + "weight": "5.4", + "archery_ticket_price": "0", + "id": "6273", + "absorb": "4,2,0", + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "equipment_slot": "5" + }, + { + "durability": null, + "name": "Broodoo shield (3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6274" + }, + { + "requirements": "{1,25}-{6,25}", + "examine": "A scary broodoo shield.", + "grand_exchange_price": "1", + "durability": null, + "name": "Broodoo shield (2)", + "tradeable": "true", + "weight": "5.4", + "archery_ticket_price": "0", + "id": "6275", + "absorb": "4,2,0", + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "equipment_slot": "5" + }, + { + "durability": null, + "name": "Broodoo shield (2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6276" + }, + { + "requirements": "{1,25}-{6,25}", + "examine": "A scary broodoo shield.", + "grand_exchange_price": "1", + "durability": null, + "name": "Broodoo shield (1)", + "tradeable": "true", + "weight": "5.4", + "archery_ticket_price": "0", + "id": "6277", + "absorb": "4,2,0", + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0", + "equipment_slot": "5" + }, + { + "durability": null, + "name": "Broodoo shield (1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6278" + }, + { + "requirements": "{1,25}-{6,25}", + "ge_buy_limit": "100", + "examine": "A scary broodoo shield.", + "durability": null, + "weight": "5.4", + "absorb": "4,2,0", + "equipment_slot": "5", + "grand_exchange_price": "2957", + "name": "Broodoo shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6279", + "bonuses": "0,0,0,3,-7,10,10,15,5,0,20,0,5,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2957", + "durability": null, + "name": "Broodoo shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6280" + }, + { + "ge_buy_limit": "100", + "examine": "A wooden pole for use in primitive construction.", + "grand_exchange_price": "1", + "durability": null, + "name": "Thatch spar light", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "6281", + "equipment_slot": "5" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1", + "durability": null, + "name": "Thatch spar light", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6282" + }, + { + "ge_buy_limit": "100", + "examine": "A wooden pole for use in primitive construction.", + "grand_exchange_price": "2", + "durability": null, + "name": "Thatch spar med", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "6283", + "equipment_slot": "5" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2", + "durability": null, + "name": "Thatch spar med", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6284" + }, + { + "ge_buy_limit": "100", + "examine": "A wooden pole for use in primitive construction.", + "grand_exchange_price": "3", + "durability": null, + "name": "Thatch spar dense", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "6285", + "equipment_slot": "5" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3", + "durability": null, + "name": "Thatch spar dense", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6286" + }, + { + "ge_buy_limit": "10000", + "examine": "Scaly but not slimy!", + "grand_exchange_price": "2084", + "durability": null, + "name": "Snake hide", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "6287" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "2084", + "durability": null, + "name": "Snake hide", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6288" + }, + { + "ge_buy_limit": "10000", + "examine": "Scaley but not slimy!", + "grand_exchange_price": "2019", + "durability": null, + "name": "Snakeskin", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "6289" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "2019", + "durability": null, + "name": "Snakeskin", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6290" + }, + { + "ge_buy_limit": "1000", + "examine": "Its creeping days are over!", + "grand_exchange_price": "1949", + "durability": null, + "name": "Spider carcass", + "tradeable": "true", + "weight": "0.8", + "archery_ticket_price": "0", + "id": "6291" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1949", + "durability": null, + "name": "Spider carcass", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6292" + }, + { + "shop_price": "50", + "ge_buy_limit": "1000", + "examine": "Raw: A raw spider threaded onto a skewer stick.Cooked: A nicely roasted spider threaded onto a skewer stick.", + "grand_exchange_price": "207", + "durability": null, + "name": "Spider on stick", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "6293" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "207", + "durability": null, + "name": "Spider on stick", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6294" + }, + { + "shop_price": "40", + "ge_buy_limit": "1000", + "examine": "A raw spider threaded onto an arrow shaft. (Raw) A nicely roasted spider threaded onto an arrow shaft. (Cooked) A badly burnt spider threaded onto a charred arrow shaft. (Burnt)", + "grand_exchange_price": "106", + "durability": null, + "name": "Spider on shaft", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "6295" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "106", + "durability": null, + "name": "Spider on shaft", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6296" + }, + { + "shop_price": "50", + "ge_buy_limit": "1000", + "examine": "Raw: A raw spider threaded onto a skewer stick.Cooked: A nicely roasted spider threaded onto a skewer stick.", + "grand_exchange_price": "54", + "durability": null, + "name": "Spider on stick", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "6297" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "54", + "durability": null, + "name": "Spider on stick", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6298" + }, + { + "shop_price": "40", + "ge_buy_limit": "1000", + "examine": "A raw spider threaded onto an arrow shaft. (Raw) A nicely roasted spider threaded onto an arrow shaft. (Cooked) A badly burnt spider threaded onto a charred arrow shaft. (Burnt)", + "grand_exchange_price": "78", + "durability": null, + "name": "Spider on shaft", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "6299" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "78", + "durability": null, + "name": "Spider on shaft", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6300" + }, + { + "durability": null, + "name": "Burnt spider", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6302" + }, + { + "shop_price": "40", + "examine": "A raw spider threaded onto an arrow shaft. (Raw) A nicely roasted spider threaded onto an arrow shaft. (Cooked) A badly burnt spider threaded onto a charred arrow shaft. (Burnt)", + "grand_exchange_price": "106", + "durability": null, + "name": "Spider on shaft", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "6303" + }, + { + "durability": null, + "name": "Spider on shaft", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6304" + }, + { + "ge_buy_limit": "1000", + "examine": "A sharp pointed stick, quite resistant to fire.", + "grand_exchange_price": "1", + "durability": null, + "name": "Skewer stick", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6305" + }, + { + "ge_buy_limit": "10000", + "examine": "Karamja currency.", + "grand_exchange_price": "2", + "durability": null, + "name": "Trading sticks", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6306" + }, + { + "ge_buy_limit": "100", + "examine": "Plant this in a herb patch to grow Goutweed.", + "grand_exchange_price": "6991", + "durability": null, + "name": "Gout tuber", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "6311" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "6991", + "durability": null, + "name": "Gout tuber", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6312" + }, + { + "shop_price": "500", + "ge_buy_limit": "100", + "examine": "A jungle specific slashing device.", + "durability": null, + "weight": "1.35", + "weapon_interface": "6", + "render_anim": "2554", + "equipment_slot": "3", + "grand_exchange_price": "179", + "name": "Opal machete", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6313", + "bonuses": "0,8,-2,0,0,0,1,1,0,0,0,4,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "179", + "durability": null, + "name": "Opal machete", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6314" + }, + { + "shop_price": "1000", + "ge_buy_limit": "100", + "examine": "A jungle specific slashing device.", + "durability": null, + "weapon_interface": "6", + "render_anim": "2554", + "equipment_slot": "3", + "grand_exchange_price": "4473", + "name": "Jade machete", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6315", + "bonuses": "0,11,-2,0,0,0,1,1,0,0,0,6,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "4473", + "durability": null, + "name": "Jade machete", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6316" + }, + { + "shop_price": "2000", + "ge_buy_limit": "100", + "examine": "A jungle specific slashing device.", + "durability": null, + "weight": "1.3", + "attack_speed": "4", + "weapon_interface": "6", + "render_anim": "2554", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "grand_exchange_price": "8774", + "name": "Red topaz machete", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6317", + "bonuses": "0,16,-2,0,0,0,1,1,0,0,0,10,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "8774", + "durability": null, + "name": "Red topaz machete", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6318" + }, + { + "ge_buy_limit": "100", + "examine": "A giant mosquito's proboscis: aerodynamic, sharp and pointy!", + "grand_exchange_price": "9733", + "durability": null, + "name": "Proboscis", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6319" + }, + { + "requirements": "{1,30}-{4,30}", + "shop_price": "1588", + "ge_buy_limit": "100", + "examine": "Made from 100% real snakeskin.", + "durability": null, + "weight": "10", + "absorb": "0,4,2", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "23100", + "name": "Snakeskin body", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6322", + "bonuses": "0,0,0,-5,12,25,28,32,15,35,30,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "23100", + "durability": null, + "name": "Snakeskin body", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6323" + }, + { + "requirements": "{1,30}-{4,30}", + "ge_buy_limit": "100", + "examine": "Made from 100% real snake.", + "durability": null, + "weight": "3.6", + "absorb": "0,3,1", + "equipment_slot": "7", + "grand_exchange_price": "702", + "name": "Snakeskin chaps", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6324", + "bonuses": "0,0,0,-5,6,8,8,10,4,10,10,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "702", + "durability": null, + "name": "Snakeskin chaps", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6325" + }, + { + "remove_head": "true", + "requirements": "{1,30}-{4,30}", + "ge_buy_limit": "100", + "examine": "Lightweight head protection.", + "durability": null, + "weight": "0.9", + "absorb": "0,2,1", + "equipment_slot": "0", + "grand_exchange_price": "871", + "name": "Snakeskin bandana", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6326", + "bonuses": "0,0,0,-5,4,2,4,4,2,2,6,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "871", + "durability": null, + "name": "Snakeskin bandana", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6327" + }, + { + "requirements": "{1,30}-{4,30}", + "ge_buy_limit": "100", + "examine": "Made from snakes.", + "grand_exchange_price": "10800", + "durability": null, + "name": "Snakeskin boots", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "6328", + "bonuses": "0,0,0,-10,3,1,1,2,1,0,9,0,0,0,0", + "equipment_slot": "10" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "10800", + "durability": null, + "name": "Snakeskin boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6329" + }, + { + "requirements": "{1,30}-{4,30}", + "ge_buy_limit": "10000", + "examine": "Made from 100% real snake.", + "grand_exchange_price": "914", + "durability": null, + "name": "Snakeskin v'brace", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "6330", + "bonuses": "0,0,0,-5,6,2,2,2,1,0,1,0,0,0,0", + "equipment_slot": "9" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "914", + "durability": null, + "name": "Snakeskin v'brace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6331" + }, + { + "ge_buy_limit": "25000", + "examine": "Some well-cut mahogany logs.", + "grand_exchange_price": "503", + "durability": null, + "name": "Mahogany logs", + "tradeable": "true", + "weight": "1.33", + "archery_ticket_price": "0", + "id": "6332" + }, + { + "ge_buy_limit": "25000", + "examine": "Some well-cut teak logs.", + "grand_exchange_price": "92", + "durability": null, + "name": "Teak logs", + "tradeable": "true", + "weight": "1.35", + "archery_ticket_price": "0", + "id": "6333" + }, + { + "ge_buy_limit": "25000", + "grand_exchange_price": "92", + "durability": null, + "name": "Teak logs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6334" + }, + { + "ge_buy_limit": "100", + "examine": "A ceremonial wooden mask.", + "grand_exchange_price": "1306", + "durability": null, + "name": "Tribal mask", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "6335", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1306", + "durability": null, + "name": "Tribal mask", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6336" + }, + { + "ge_buy_limit": "100", + "examine": "A ceremonial wooden mask.", + "grand_exchange_price": "997", + "durability": null, + "name": "Tribal mask", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "6337", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "997", + "durability": null, + "name": "Tribal mask", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6338" + }, + { + "ge_buy_limit": "100", + "examine": "A ceremonial wooden mask.", + "grand_exchange_price": "1018", + "durability": null, + "name": "Tribal mask", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "6339", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1018", + "durability": null, + "name": "Tribal mask", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6340" + }, + { + "remove_sleeves": "true", + "shop_price": "300", + "ge_buy_limit": "100", + "examine": "Local dress.", + "grand_exchange_price": "3331", + "durability": null, + "name": "Tribal top", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "6341", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3331", + "durability": null, + "name": "Tribal top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6342" + }, + { + "shop_price": "250", + "ge_buy_limit": "100", + "examine": "A brightly coloured robe prized by the Tai Bwo Wannai peoples.", + "grand_exchange_price": "1382", + "durability": null, + "name": "Villager robe", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "6343", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1382", + "durability": null, + "name": "Villager robe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6344" + }, + { + "shop_price": "200", + "ge_buy_limit": "100", + "examine": "A brightly coloured hat prized by the Tai Bwo Wannai peoples.", + "grand_exchange_price": "2337", + "durability": null, + "name": "Villager hat", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "6345", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2337", + "durability": null, + "name": "Villager hat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6346" + }, + { + "shop_price": "150", + "ge_buy_limit": "100", + "examine": "A brown armband, as worn by the Tai Bwo Wannai locals.", + "grand_exchange_price": "734", + "durability": null, + "name": "Villager armband", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "6347", + "equipment_slot": "9" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "734", + "durability": null, + "name": "Villager armband", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6348" + }, + { + "shop_price": "100", + "ge_buy_limit": "100", + "examine": "A brightly coloured pair of local sandals.", + "grand_exchange_price": "2793", + "durability": null, + "name": "Villager sandals", + "tradeable": "true", + "weight": "0.6", + "archery_ticket_price": "0", + "id": "6349", + "equipment_slot": "10" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2793", + "durability": null, + "name": "Villager sandals", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6350" + }, + { + "remove_sleeves": "true", + "shop_price": "300", + "ge_buy_limit": "100", + "examine": "Local dress.", + "grand_exchange_price": "3171", + "durability": null, + "name": "Tribal top", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "6351", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3171", + "durability": null, + "name": "Tribal top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6352" + }, + { + "shop_price": "250", + "ge_buy_limit": "100", + "examine": "A brightly coloured robe prized by the Tai Bwo Wannai peoples.", + "grand_exchange_price": "1416", + "durability": null, + "name": "Villager robe", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "6353", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1416", + "durability": null, + "name": "Villager robe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6354" + }, + { + "shop_price": "200", + "ge_buy_limit": "100", + "examine": "A brightly coloured hat prized by the Tai Bwo Wannai peoples.", + "grand_exchange_price": "2785", + "durability": null, + "name": "Villager hat", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "6355", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2785", + "durability": null, + "name": "Villager hat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6356" + }, + { + "shop_price": "100", + "ge_buy_limit": "100", + "examine": "A brightly coloured pair of local sandals.", + "grand_exchange_price": "944", + "durability": null, + "name": "Villager sandals", + "tradeable": "true", + "weight": "0.6", + "archery_ticket_price": "0", + "id": "6357", + "equipment_slot": "10" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "944", + "durability": null, + "name": "Villager sandals", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6358" + }, + { + "shop_price": "150", + "ge_buy_limit": "100", + "examine": "A blue armband, as worn by the Tai Bwo Wannai locals.", + "grand_exchange_price": "672", + "durability": null, + "name": "Villager armband", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "6359", + "equipment_slot": "9" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "672", + "durability": null, + "name": "Villager armband", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6360" + }, + { + "remove_sleeves": "true", + "shop_price": "300", + "ge_buy_limit": "100", + "examine": "Local dress.", + "grand_exchange_price": "2484", + "durability": null, + "name": "Tribal top", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "6361", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2484", + "durability": null, + "name": "Tribal top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6362" + }, + { + "shop_price": "250", + "ge_buy_limit": "100", + "examine": "A brightly coloured robe prized by the Tai Bwo Wannai peoples.", + "grand_exchange_price": "499", + "durability": null, + "name": "Villager robe", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "6363", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "499", + "durability": null, + "name": "Villager robe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6364" + }, + { + "shop_price": "200", + "ge_buy_limit": "100", + "examine": "A brightly coloured hat prized by the Tai Bwo Wannai peoples.", + "grand_exchange_price": "2440", + "durability": null, + "name": "Villager hat", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "6365", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2440", + "durability": null, + "name": "Villager hat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6366" + }, + { + "shop_price": "100", + "ge_buy_limit": "100", + "examine": "A brightly coloured pair of local sandals.", + "grand_exchange_price": "1479", + "durability": null, + "name": "Villager sandals", + "tradeable": "true", + "weight": "0.6", + "archery_ticket_price": "0", + "id": "6367", + "equipment_slot": "10" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1479", + "durability": null, + "name": "Villager sandals", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6368" + }, + { + "shop_price": "150", + "ge_buy_limit": "100", + "examine": "A yellow armband, as worn by the Tai Bwo Wannai locals.", + "grand_exchange_price": "823", + "durability": null, + "name": "Villager armband", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "6369", + "equipment_slot": "9" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "823", + "durability": null, + "name": "Villager armband", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6370" + }, + { + "remove_sleeves": "true", + "shop_price": "300", + "ge_buy_limit": "100", + "examine": "Local dress.", + "grand_exchange_price": "2683", + "durability": null, + "name": "Tribal top", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "6371", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2683", + "durability": null, + "name": "Tribal top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6372" + }, + { + "shop_price": "250", + "ge_buy_limit": "100", + "examine": "A brightly coloured robe prized by the Tai Bwo Wannai peoples.", + "grand_exchange_price": "331", + "durability": null, + "name": "Villager robe", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "6373", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "331", + "durability": null, + "name": "Villager robe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6374" + }, + { + "shop_price": "200", + "ge_buy_limit": "100", + "examine": "A brightly coloured hat prized by the Tai Bwo Wannai peoples.", + "grand_exchange_price": "3010", + "durability": null, + "name": "Villager hat", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "6375", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3010", + "durability": null, + "name": "Villager hat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6376" + }, + { + "shop_price": "100", + "ge_buy_limit": "100", + "examine": "A brightly coloured pair of local sandals.", + "grand_exchange_price": "2310", + "durability": null, + "name": "Villager sandals", + "tradeable": "true", + "weight": "0.6", + "archery_ticket_price": "0", + "id": "6377", + "equipment_slot": "10" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2310", + "durability": null, + "name": "Villager sandals", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6378" + }, + { + "shop_price": "150", + "ge_buy_limit": "100", + "examine": "A pink armband, as worn by the Tai Bwo Wannai locals.", + "grand_exchange_price": "1697", + "durability": null, + "name": "Villager armband", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "6379", + "equipment_slot": "9" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1697", + "durability": null, + "name": "Villager armband", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6380" + }, + { + "shop_price": "24", + "ge_buy_limit": "100", + "examine": "A fez hat. Juss like that.", + "grand_exchange_price": "690", + "durability": null, + "name": "Fez", + "tradeable": "true", + "archery_ticket_price": "0", + "hat": true, + "id": "6382", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "690", + "durability": null, + "name": "Fez", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6383" + }, + { + "remove_sleeves": "true", + "shop_price": "15", + "ge_buy_limit": "100", + "examine": "A bit itchy.", + "grand_exchange_price": "649", + "durability": null, + "name": "Desert top", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "6384", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "649", + "durability": null, + "name": "Desert top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6385" + }, + { + "shop_price": "25", + "ge_buy_limit": "100", + "examine": "Has a coarse hard wearing texture.", + "grand_exchange_price": "533", + "durability": null, + "name": "Desert robes", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6386", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "533", + "durability": null, + "name": "Desert robes", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6387" + }, + { + "remove_sleeves": "true", + "shop_price": "15", + "ge_buy_limit": "100", + "examine": "A bit itchy.", + "grand_exchange_price": "1016", + "durability": null, + "name": "Desert top", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "6388", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1016", + "durability": null, + "name": "Desert top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6389" + }, + { + "shop_price": "25", + "ge_buy_limit": "100", + "examine": "Better than factor 50 sun cream.", + "grand_exchange_price": "515", + "durability": null, + "name": "Desert legs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6390", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "515", + "durability": null, + "name": "Desert legs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6391" + }, + { + "remove_head": "true", + "shop_price": "35", + "ge_buy_limit": "100", + "examine": "Good for keeping the sun off my neck.", + "grand_exchange_price": "531", + "durability": null, + "name": "Menap headgear", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6392", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "531", + "durability": null, + "name": "Menap headgear", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6393" + }, + { + "remove_sleeves": "true", + "shop_price": "20", + "ge_buy_limit": "100", + "examine": "Colourful.", + "grand_exchange_price": "650", + "durability": null, + "name": "Menaphite top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6394", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "650", + "durability": null, + "name": "Menaphite top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6395" + }, + { + "shop_price": "40", + "ge_buy_limit": "100", + "examine": "A cool light Menaphite robe.", + "grand_exchange_price": "440", + "durability": null, + "name": "Menaphite robe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6396", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "440", + "durability": null, + "name": "Menaphite robe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6397" + }, + { + "shop_price": "20", + "ge_buy_limit": "100", + "examine": "Look at those nobbily knees.", + "grand_exchange_price": "246", + "durability": null, + "name": "Menap action kilt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6398", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "246", + "durability": null, + "name": "Menap action kilt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6399" + }, + { + "remove_head": "true", + "shop_price": "35", + "ge_buy_limit": "100", + "examine": "Good for keeping the sun off my neck.", + "grand_exchange_price": "484", + "durability": null, + "name": "Menap headgear", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6400", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "484", + "durability": null, + "name": "Menap headgear", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6401" + }, + { + "remove_sleeves": "true", + "shop_price": "20", + "ge_buy_limit": "100", + "examine": "Colourful.", + "grand_exchange_price": "557", + "durability": null, + "name": "Menaphite top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6402", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "557", + "durability": null, + "name": "Menaphite top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6403" + }, + { + "shop_price": "40", + "ge_buy_limit": "100", + "examine": "A cool light Menaphite robe.", + "grand_exchange_price": "449", + "durability": null, + "name": "Menaphite robe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6404", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "449", + "durability": null, + "name": "Menaphite robe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6405" + }, + { + "shop_price": "20", + "ge_buy_limit": "100", + "examine": "Look at those nobbily knees.", + "grand_exchange_price": "236", + "durability": null, + "name": "Menap action kilt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6406", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "236", + "durability": null, + "name": "Menap action kilt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6407" + }, + { + "requirements": "{17,10}-{0,10}", + "shop_price": "400", + "ge_buy_limit": "100", + "examine": "An offensive blackjack.", + "durability": null, + "weight": "1", + "attack_speed": "4", + "weapon_interface": "10", + "equipment_slot": "3", + "grand_exchange_price": "852", + "name": "Oak blackjack(o)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6408", + "bonuses": "0,0,4,0,0,0,0,0,0,0,0,4,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "852", + "durability": null, + "name": "Oak blackjack(o)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6409" + }, + { + "requirements": "{17,10}-{1,10}", + "ge_buy_limit": "100", + "examine": "An defensive blackjack.", + "durability": null, + "weight": "1", + "attack_speed": "4", + "weapon_interface": "10", + "equipment_slot": "3", + "grand_exchange_price": "818", + "name": "Oak blackjack(d)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6410", + "bonuses": "0,0,0,0,0,0,0,4,0,0,0,4,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "818", + "durability": null, + "name": "Oak blackjack(d)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6411" + }, + { + "requirements": "{17,20}-{0,20}", + "ge_buy_limit": "100", + "examine": "An offensive blackjack.", + "durability": null, + "weight": "1", + "attack_speed": "4", + "weapon_interface": "10", + "equipment_slot": "3", + "grand_exchange_price": "1418", + "name": "Willow blackjack(o)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6412", + "bonuses": "0,0,8,0,0,0,0,0,0,0,0,8,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1418", + "durability": null, + "name": "Willow blackjack(o)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6413" + }, + { + "requirements": "{17,20}-{1,20}", + "ge_buy_limit": "100", + "examine": "A defensive blackjack.", + "durability": null, + "weight": "1", + "attack_speed": "4", + "weapon_interface": "10", + "equipment_slot": "3", + "grand_exchange_price": "1285", + "name": "Willow blackjack(d)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6414", + "bonuses": "0,0,0,0,0,0,0,8,0,0,0,8,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1285", + "durability": null, + "name": "Willow blackjack(d)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6415" + }, + { + "requirements": "{17,30}", + "shop_price": "1200", + "ge_buy_limit": "100", + "examine": "A solid bit of maple.", + "durability": null, + "weight": "1.8", + "attack_speed": "4", + "weapon_interface": "10", + "defence_anim": "425", + "equipment_slot": "3", + "attack_anims": "395,395,395,395", + "grand_exchange_price": "1432", + "name": "Maple blackjack", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6416", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,20,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1432", + "durability": null, + "name": "Maple blackjack", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6417" + }, + { + "requirements": "{17,30}-{0,30}", + "shop_price": "1600", + "ge_buy_limit": "100", + "examine": "An offensive blackjack.", + "durability": null, + "weight": "1", + "attack_speed": "4", + "weapon_interface": "10", + "equipment_slot": "3", + "grand_exchange_price": "2079", + "name": "Maple blackjack(o)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6418", + "bonuses": "0,0,24,0,0,0,0,0,0,0,0,20,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2079", + "durability": null, + "name": "Maple blackjack(o)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6419" + }, + { + "requirements": "{17,30}-{1,30}", + "shop_price": "952", + "ge_buy_limit": "100", + "examine": "A defensive blackjack.", + "durability": null, + "weight": "1", + "attack_speed": "4", + "weapon_interface": "10", + "equipment_slot": "3", + "grand_exchange_price": "2407", + "name": "Maple blackjack(d)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6420", + "bonuses": "0,0,0,0,0,0,0,24,0,0,0,20,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2407", + "durability": null, + "name": "Maple blackjack(d)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6421" + }, + { + "shop_price": "17", + "examine": "One of the 4 basic elemental Runes.", + "grand_exchange_price": "9", + "durability": null, + "name": "Air rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6422" + }, + { + "durability": null, + "name": "Air rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6423" + }, + { + "shop_price": "17", + "examine": "One of the 4 basic elemental Runes.", + "grand_exchange_price": "6", + "durability": null, + "name": "Water rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6424" + }, + { + "durability": null, + "name": "Water rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6425" + }, + { + "shop_price": "17", + "examine": "One of the 4 basic elemental Runes.", + "grand_exchange_price": "7", + "durability": null, + "name": "Earth rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6426" + }, + { + "durability": null, + "name": "Earth rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6427" + }, + { + "shop_price": "17", + "examine": "One of the 4 basic elemental Runes.", + "grand_exchange_price": "16", + "durability": null, + "name": "Fire rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6428" + }, + { + "durability": null, + "name": "Fire rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6429" + }, + { + "shop_price": "140", + "examine": "Used for small missile spells.", + "grand_exchange_price": "65", + "durability": null, + "name": "Chaos rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6430" + }, + { + "durability": null, + "name": "Chaos rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6431" + }, + { + "shop_price": "310", + "examine": "Used for medium missile spells.", + "grand_exchange_price": "399", + "durability": null, + "name": "Death rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6432" + }, + { + "durability": null, + "name": "Death rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6433" + }, + { + "shop_price": "378", + "examine": "Used for teleport spells.", + "grand_exchange_price": "277", + "durability": null, + "name": "Law rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6434" + }, + { + "durability": null, + "name": "Law rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6435" + }, + { + "shop_price": "17", + "examine": "Used for basic missile spells.", + "grand_exchange_price": "6", + "durability": null, + "name": "Mind rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6436" + }, + { + "durability": null, + "name": "Mind rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6437" + }, + { + "shop_price": "16", + "examine": "Used for Curse spells", + "grand_exchange_price": "6", + "durability": null, + "name": "Body rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6438" + }, + { + "durability": null, + "name": "Body rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6439" + }, + { + "examine": "A spadeful of refined coal.", + "durability": null, + "name": "Spadeful of coke", + "weight": "2", + "archery_ticket_price": "0", + "id": "6448" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A white rosebush seed.", + "durability": null, + "name": "White rose seed", + "tradeable": "false", + "destroy": "true", + "weight": "28.928", + "archery_ticket_price": "0", + "id": "6453" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A red rosebush seed.", + "durability": null, + "name": "Red rose seed", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6454" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A pink rosebush seed.", + "durability": null, + "name": "Pink rose seed", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6455" + }, + { + "destroy_message": "You can get some more Burthorpe vine seeds from Berald in Taverly.", + "examine": "A grapevine seed.", + "durability": null, + "name": "Vine seed", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6456" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A delphinium seed.", + "durability": null, + "name": "Delphinium seed", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6457" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A snowdrop seed.", + "durability": null, + "name": "Snowdrop seed", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6460" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Shoot: A shoot that has been cut from a dying White Tree.Plant pot: A young White Tree sapling.Plant pot after watering: This shoot from a White Tree has been watered and will soon grow.", + "durability": null, + "name": "White tree shoot", + "archery_ticket_price": "0", + "id": "6461" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Shoot: A shoot that has been cut from a dying White Tree.Plant pot: A young White Tree sapling.Plant pot after watering: This shoot from a White Tree has been watered and will soon grow.", + "durability": null, + "name": "White tree shoot", + "archery_ticket_price": "0", + "id": "6462" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Shoot: A shoot that has been cut from a dying White Tree.Plant pot: A young White Tree sapling.Plant pot after watering: This shoot from a White Tree has been watered and will soon grow.", + "durability": null, + "name": "White tree shoot", + "archery_ticket_price": "0", + "id": "6463" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A young White Tree sapling", + "durability": null, + "name": "White tree sapling", + "tradeable": "false", + "destroy": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "6464" + }, + { + "destroy_message": "Another can be received from pickpocketing Dr. Fenkenstrain in the tower.", + "examine": "The power within this ring has been activated.", + "durability": null, + "name": "Ring of charos(a)", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6465", + "equipment_slot": "12" + }, + { + "examine": "A rune essence chip that has been broken into shards.", + "durability": null, + "name": "Rune shards", + "archery_ticket_price": "0", + "id": "6466" + }, + { + "examine": "Crushed rune essence.", + "durability": null, + "name": "Rune dust", + "archery_ticket_price": "0", + "id": "6467" + }, + { + "shop_price": "25", + "examine": "Use this on plants to cure disease.", + "grand_exchange_price": "199", + "durability": null, + "name": "Plant cure", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6468" + }, + { + "examine": "Looks delicious.", + "durability": null, + "name": "White tree fruit", + "archery_ticket_price": "0", + "id": "6469" + }, + { + "ge_buy_limit": "100", + "examine": "Pour this onto compost to make it into super-compost.", + "grand_exchange_price": "11500", + "durability": null, + "name": "Compost potion(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6470" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "11500", + "durability": null, + "name": "Compost potion(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6471" + }, + { + "ge_buy_limit": "100", + "examine": "Pour this onto compost to make it into super-compost.", + "grand_exchange_price": "6804", + "durability": null, + "name": "Compost potion(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6472" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "6804", + "durability": null, + "name": "Compost potion(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6473" + }, + { + "ge_buy_limit": "100", + "examine": "Pour this onto compost to make it into super-compost.", + "grand_exchange_price": "3338", + "durability": null, + "name": "Compost potion(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6474" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3338", + "durability": null, + "name": "Compost potion(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6475" + }, + { + "ge_buy_limit": "100", + "examine": "Pour this onto compost to make it into super-compost.", + "grand_exchange_price": "1734", + "durability": null, + "name": "Compost potion(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6476" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1734", + "durability": null, + "name": "Compost potion(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6477" + }, + { + "destroy_message": "You can get another one from Queen Ellamaria", + "examine": "I can use this to move heavy objects. (or) An empty trolley.", + "durability": null, + "name": "Trolley", + "tradeable": "false", + "destroy": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "6478" + }, + { + "destroy_message": "You can get another list from Queen Ellamaria in Varrock", + "examine": "A list of things that I must collect for Queen Ellamaria.", + "durability": null, + "name": "List", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6479" + }, + { + "requirements": "{4,60}", + "shop_price": "375", + "ge_buy_limit": "100", + "examine": "A razor sharp ring of obsidian.", + "durability": null, + "tokkul_price": "375", + "attack_speed": "4", + "weapon_interface": "18", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "2614,2614,2614,2614", + "grand_exchange_price": "340", + "name": "Toktz-xil-ul", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6522", + "bonuses": "0,0,0,0,69,0,0,0,0,0,0,0,0,0,49" + }, + { + "requirements": "{0,60}", + "shop_price": "60000", + "ge_buy_limit": "10", + "examine": "A razor sharp sword of obsidian.", + "durability": null, + "tokkul_price": "60000", + "weight": "1.8", + "attack_speed": "4", + "weapon_interface": "5", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "grand_exchange_price": "30200", + "name": "Toktz-xil-ak", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6523", + "bonuses": "47,38,-2,0,0,2,3,0,0,0,0,49,0,0,0" + }, + { + "requirements": "{1,60}", + "shop_price": "67500", + "ge_buy_limit": "10", + "examine": "A spiked shield of Obsidian.", + "durability": null, + "tokkul_price": "67500", + "weight": "3.6", + "absorb": "5,0,11", + "equipment_slot": "5", + "grand_exchange_price": "34700", + "name": "Toktz-ket-xil", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6524", + "bonuses": "0,0,0,-12,-8,40,42,38,0,65,60,5,0,0,0" + }, + { + "requirements": "{0,60}", + "shop_price": "37500", + "ge_buy_limit": "10", + "examine": "A large knife of Obsidian.", + "durability": null, + "tokkul_price": "37500", + "weight": "0.4", + "attack_speed": "4", + "weapon_interface": "6", + "render_anim": "2584", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "grand_exchange_price": "16900", + "name": "Toktz-xil-ek", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6525", + "bonuses": "16,48,0,0,0,0,0,0,0,0,0,39,0,0,0" + }, + { + "ge_buy_limit": "10", + "turn90cw_anim": "1207", + "examine": "A staff of obsidian.", + "walk_anim": "1205", + "tokkul_price": "52500", + "turn90ccw_anim": "1208", + "attack_speed": "6", + "two_handed": "true", + "turn180_anim": "1206", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "grand_exchange_price": "26300", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "6526", + "stand_turn_anim": "1209", + "bonuses": "15,-1,55,15,0,10,15,5,15,0,0,55,5,0,0", + "requirements": "{0,60}-{6,60}", + "shop_price": "52500", + "durability": null, + "weight": "1", + "weapon_interface": "1", + "render_anim": "28", + "name": "Toktz-mej-tal" + }, + { + "requirements": "{0,60}", + "shop_price": "45000", + "ge_buy_limit": "10", + "examine": "A mace of obsidian.", + "durability": null, + "tokkul_price": "45000", + "weight": "1.8", + "attack_speed": "5", + "weapon_interface": "10", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "grand_exchange_price": "22600", + "name": "Tzhaar-ket-em", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6527", + "bonuses": "-4,-4,62,0,0,0,0,0,0,0,0,56,0,0,0" + }, + { + "ge_buy_limit": "10", + "turn90cw_anim": "1663", + "examine": "A maul of obsidian.", + "walk_anim": "1663", + "tokkul_price": "75000", + "turn90ccw_anim": "1663", + "attack_speed": "7", + "two_handed": "true", + "turn180_anim": "1663", + "defence_anim": "1666", + "equipment_slot": "3", + "attack_anims": "2661,2661,2661,2661", + "grand_exchange_price": "31000", + "stand_anim": "1662", + "tradeable": "true", + "run_anim": "1664", + "archery_ticket_price": "0", + "id": "6528", + "stand_turn_anim": "823", + "bonuses": "0,0,80,-4,0,0,0,0,0,0,0,85,0,0,0", + "requirements": "{2,60}", + "shop_price": "75000", + "durability": null, + "weight": "3.6", + "weapon_interface": "10", + "render_anim": "27", + "attack_audios": "2520,0,0,0", + "name": "Tzhaar-ket-om" + }, + { + "examine": "It's a Token of some kind made from Obsidian.", + "durability": null, + "name": "Tokkul", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "6529" + }, + { + "durability": null, + "name": "Toktz-xil-ak", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6535" + }, + { + "durability": null, + "name": "Toktz-ket-xil", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6536" + }, + { + "durability": null, + "name": "Toktz-xil-ek", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6537" + }, + { + "durability": null, + "name": "Toktz-mej-tal", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6538" + }, + { + "durability": null, + "name": "Tzhaar-ket-em", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6539" + }, + { + "durability": null, + "name": "Tzhaar-ket-om", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6540" + }, + { + "destroy_message": "You can get a replacement mouse toy by speaking to Bob, the Jagex cat.", + "examine": "An Advanced Combat Training Device.", + "durability": null, + "name": "Mouse toy", + "tradeable": "false", + "destroy": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "6541", + "weapon_interface": "12", + "bonuses": "-100,-100,-50,0,0,0,0,0,0,0,0,-10,0,0,0", + "equipment_slot": "3" + }, + { + "destroy_message": "You will not get a replacement for the present. Open it for your reward.", + "examine": "Thanks for all your help! Love, Bob & Neite.", + "durability": null, + "name": "Present", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6542" + }, + { + "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", + "examine": "I wonder what happens if I rub it.", + "durability": null, + "name": "Antique lamp", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6543" + }, + { + "destroy_message": "You can get another Amulet of Catspeak from the Sphinx in Sophanem.", + "examine": "It's an amulet of cat speak. It makes vague purring noises.", + "durability": null, + "name": "Catspeak amulet(e)", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "6544", + "equipment_slot": "2" + }, + { + "destroy_message": "You have completed the chores; you can safely destroy the list.", + "examine": "A list of chores that Bob gave you to do.", + "durability": null, + "name": "Chores", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6545" + }, + { + "destroy_message": "You found the recipe in Unferth's bookcase, which is in his Burthorpe house, you will be able to get a replacement.", + "examine": "It says on the back 'My favourite recipe.", + "durability": null, + "name": "Recipe", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6546" + }, + { + "destroy_message": "You can get another Doctor's hat from the Apothecary in Varrock.", + "examine": "A mirror helps reflect light on the subject.", + "durability": null, + "name": "Doctors hat", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6547", + "equipment_slot": "0" + }, + { + "destroy_message": "You can get another Nurse's hat from the Apothecary in Varrock.", + "examine": "A nurse's hat, but does it have healing powers?", + "durability": null, + "name": "Nurse hat", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6548", + "equipment_slot": "0" + }, + { + "examine": "Inventory: Wild. (wily)Lethargic. (lazy)", + "durability": null, + "name": "Lazy cat", + "archery_ticket_price": "0", + "id": "6549" + }, + { + "examine": "Inventory: Wild. (wily)Lethargic. (lazy)", + "durability": null, + "name": "Lazy cat", + "archery_ticket_price": "0", + "id": "6550" + }, + { + "examine": "Inventory: Wild. (wily)Lethargic. (lazy)", + "durability": null, + "name": "Lazy cat", + "archery_ticket_price": "0", + "id": "6551" + }, + { + "examine": "Inventory: Wild. (wily)Lethargic. (lazy)", + "durability": null, + "name": "Lazy cat", + "archery_ticket_price": "0", + "id": "6552" + }, + { + "examine": "Inventory: Wild. (wily)Lethargic. (lazy)", + "durability": null, + "name": "Lazy cat", + "archery_ticket_price": "0", + "id": "6553" + }, + { + "examine": "Inventory: Wild. (wily)Lethargic. (lazy)", + "durability": null, + "name": "Lazy cat", + "archery_ticket_price": "0", + "id": "6554" + }, + { + "examine": "Inventory: Wild. (wily)Lethargic. (lazy)", + "durability": null, + "name": "Wily cat", + "archery_ticket_price": "0", + "id": "6555" + }, + { + "examine": "Inventory: Wild. (wily)Lethargic. (lazy)", + "durability": null, + "name": "Wily cat", + "archery_ticket_price": "0", + "id": "6556" + }, + { + "examine": "Inventory: Wild. (wily)Lethargic. (lazy)", + "durability": null, + "name": "Wily cat", + "archery_ticket_price": "0", + "id": "6557" + }, + { + "examine": "Inventory: Wild. (wily)Lethargic. (lazy)", + "durability": null, + "name": "Wily cat", + "archery_ticket_price": "0", + "id": "6558" + }, + { + "examine": "Inventory: Wild. (wily)Lethargic. (lazy)", + "durability": null, + "name": "Wily cat", + "archery_ticket_price": "0", + "id": "6559" + }, + { + "examine": "Inventory: Wild. (wily)Lethargic. (lazy)", + "durability": null, + "name": "Wily cat", + "archery_ticket_price": "0", + "id": "6560" + }, + { + "ge_buy_limit": "10", + "turn90cw_anim": "1207", + "examine": "It's a slightly magical stick.", + "walk_anim": "1205", + "rare_item": "true", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "turn180_anim": "1206", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "grand_exchange_price": "368700", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "6562", + "stand_turn_anim": "1209", + "bonuses": "7,-1,28,12,0,2,3,1,12,0,0,35,0,0,0", + "requirements": "{0,30}-{6,30}", + "durability": null, + "weight": "2.2", + "weapon_interface": "1", + "equip_audio": "2247", + "render_anim": "28", + "attack_audios": "2555,0,0,0", + "name": "Mud battlestaff" + }, + { + "ge_buy_limit": "10", + "turn90cw_anim": "1207", + "examine": "It's a slightly magical stick.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "turn180_anim": "1206", + "equipment_slot": "3", + "grand_exchange_price": "423100", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "6563", + "stand_turn_anim": "1209", + "bonuses": "10,-1,40,14,0,2,3,1,14,0,0,50,0,0,0", + "requirements": "{0,40}-{6,40}", + "shop_price": "40000", + "durability": null, + "weight": "2", + "weapon_interface": "1", + "equip_audio": "2247", + "render_anim": "28", + "attack_audios": "2555,0,0,0", + "name": "Mystic mud staff" + }, + { + "examine": "A valuable ring.", + "grand_exchange_price": "6609743", + "durability": null, + "name": "Onyx ring", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6564" + }, + { + "examine": "I wonder if this is valuable.", + "grand_exchange_price": "4501000", + "durability": null, + "name": "Onyx necklace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6565" + }, + { + "examine": "I wonder if I can get this enchanted.", + "grand_exchange_price": "9058124", + "durability": null, + "name": "Onyx amulet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6566" + }, + { + "shop_price": "90000", + "ge_buy_limit": "100", + "examine": "A cape woven of obsidian plates.", + "durability": null, + "tokkul_price": "90000", + "weight": "1.8", + "equipment_slot": "1", + "lendable": "true", + "grand_exchange_price": "42000", + "name": "Obsidian cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6568", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "42000", + "durability": null, + "name": "Obsidian cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6569" + }, + { + "examine": "A cape of fire.", + "durability": null, + "name": "Fire cape", + "tradeable": "false", + "weight": "1.8", + "archery_ticket_price": "0", + "id": "6570", + "bonuses": "1,1,1,1,1,11,11,11,11,11,11,4,2,0,0", + "equipment_slot": "1" + }, + { + "shop_price": "2700000", + "ge_buy_limit": "100", + "examine": "An uncut onyx.", + "grand_exchange_price": "10700000", + "tokkul_price": "300000", + "durability": null, + "name": "Uncut onyx", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6571" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "10700000", + "durability": null, + "name": "Uncut onyx", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6572" + }, + { + "ge_buy_limit": "100", + "examine": "This looks valuable.", + "grand_exchange_price": "10700000", + "durability": null, + "name": "Onyx", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6573" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "10700000", + "durability": null, + "name": "Onyx", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6574" + }, + { + "ge_buy_limit": "100", + "examine": "A valuable ring.", + "grand_exchange_price": "11900000", + "durability": null, + "name": "Onyx ring", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6575", + "equipment_slot": "12" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "11900000", + "durability": null, + "name": "Onyx ring", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6576" + }, + { + "ge_buy_limit": "100", + "examine": "I wonder if this is valuable.", + "grand_exchange_price": "4500000", + "durability": null, + "name": "Onyx necklace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6577", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "4500000", + "durability": null, + "name": "Onyx necklace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6578" + }, + { + "examine": "I wonder if I can get this enchanted.", + "grand_exchange_price": "9058124", + "durability": null, + "name": "Onyx amulet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6579" + }, + { + "durability": null, + "name": "Onyx amulet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6580" + }, + { + "ge_buy_limit": "100", + "examine": "I wonder if I can get this enchanted.", + "grand_exchange_price": "10900000", + "durability": null, + "name": "Onyx amulet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6581", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "10900000", + "durability": null, + "name": "Onyx amulet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6582" + }, + { + "ge_buy_limit": "100", + "examine": "An enchanted ring.", + "grand_exchange_price": "803700", + "durability": null, + "name": "Ring of stone", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6583", + "equipment_slot": "12" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "803700", + "durability": null, + "name": "Ring of stone", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6584" + }, + { + "lendable": "true", + "ge_buy_limit": "100", + "examine": "A very powerful onyx amulet.", + "grand_exchange_price": "9200000", + "durability": null, + "name": "Amulet of fury", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6585", + "bonuses": "10,10,10,10,10,15,15,15,15,15,15,8,5,0,0", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "9200000", + "durability": null, + "name": "Amulet of fury", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6586" + }, + { + "requirements": "{0,10}-{5,10}", + "shop_price": "360", + "ge_buy_limit": "100", + "examine": "A set of fighting claws.", + "durability": null, + "attack_speed": "4", + "two_handed": "true", + "weapon_interface": "9", + "equip_audio": "1003", + "render_anim": "2583", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,390,390", + "grand_exchange_price": "1013", + "attack_audios": "2548,2548,2548,2548", + "name": "White claws", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6587", + "bonuses": "10,14,-4,0,0,4,7,2,0,0,0,14,1,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1013", + "durability": null, + "name": "White claws", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6588" + }, + { + "requirements": "{0,10}-{5,10}", + "shop_price": "1248", + "ge_buy_limit": "100", + "examine": "A vicious looking axe.", + "durability": null, + "weight": "2.7", + "attack_speed": "6", + "weapon_interface": "2", + "equip_audio": "2232", + "render_anim": "2586", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "395,395,401,395", + "grand_exchange_price": "1459", + "attack_audios": "2498,2498,2497,2498", + "name": "White battleaxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6589", + "bonuses": "-2,20,15,0,0,0,0,0,0,-1,0,24,1,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1459", + "durability": null, + "name": "White battleaxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6590" + }, + { + "requirements": "{0,10}-{5,10}", + "shop_price": "240", + "ge_buy_limit": "100", + "examine": "A vicious white dagger.", + "durability": null, + "weight": "0.4", + "attack_speed": "4", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "defence_anim": "378", + "equipment_slot": "3", + "attack_anims": "400,400,400,400", + "grand_exchange_price": "479", + "attack_audios": "2517,2517,2500,2517", + "name": "White dagger", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6591", + "bonuses": "10,5,-4,1,0,0,0,0,1,0,0,7,1,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "479", + "durability": null, + "name": "White dagger", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6592" + }, + { + "requirements": "{0,10}-{5,10}", + "shop_price": "240", + "ge_buy_limit": "100", + "examine": "A vicious white dagger.", + "durability": null, + "weight": "0.4", + "attack_speed": "4", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "equipment_slot": "3", + "grand_exchange_price": "497", + "attack_audios": "2517,2517,2500,2517", + "name": "White dagger(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6593", + "bonuses": "10,5,-4,1,0,0,0,0,1,0,0,7,1,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "497", + "durability": null, + "name": "White dagger(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6594" + }, + { + "requirements": "{0,10}-{5,10}", + "shop_price": "240", + "ge_buy_limit": "100", + "examine": "A vicious white dagger.", + "durability": null, + "weight": "0.4", + "attack_speed": "4", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "equipment_slot": "3", + "grand_exchange_price": "982", + "attack_audios": "2517,2517,2500,2517", + "name": "White dagger(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6595", + "bonuses": "10,5,-4,1,0,0,0,0,1,0,0,7,1,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "982", + "durability": null, + "name": "White dagger(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6596" + }, + { + "requirements": "{0,10}-{5,10}", + "shop_price": "240", + "ge_buy_limit": "100", + "examine": "A vicious white dagger.", + "durability": null, + "weight": "0.4", + "attack_speed": "4", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "equipment_slot": "3", + "grand_exchange_price": "8422", + "attack_audios": "2517,2517,2500,2517", + "name": "White dagger(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6597", + "bonuses": "10,5,-4,1,0,0,0,0,1,0,0,7,1,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "8422", + "durability": null, + "name": "White dagger(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6598" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A white halberd.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "7", + "two_handed": "true", + "turn180_anim": "1206", + "defence_anim": "430", + "equipment_slot": "3", + "attack_anims": "440,440,412,440", + "grand_exchange_price": "1834", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "6599", + "stand_turn_anim": "1209", + "bonuses": "19,25,0,-4,0,-1,2,3,0,0,0,20,1,0,0", + "requirements": "{0,10}-{2,5}", + "shop_price": "1920", + "durability": null, + "weight": "3.1", + "weapon_interface": "15", + "equip_audio": "2247", + "render_anim": "28", + "name": "White halberd" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1834", + "durability": null, + "name": "White halberd", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6600" + }, + { + "requirements": "{0,10}-{5,10}", + "shop_price": "432", + "ge_buy_limit": "100", + "examine": "A spiky mace.", + "durability": null, + "weight": "1.8", + "attack_speed": "5", + "weapon_interface": "8", + "equip_audio": "2246", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "grand_exchange_price": "481", + "attack_audios": "2508,2508,25092508", + "name": "White mace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6601", + "bonuses": "8,-2,16,0,0,0,0,0,0,0,0,13,3,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "481", + "durability": null, + "name": "White mace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6602" + }, + { + "requirements": "{0,10}-{5,10}", + "ge_buy_limit": "100", + "shop_price": "200", + "turn90cw_anim": "1207", + "examine": "A Magical staff.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "weapon_interface": "1", + "turn180_anim": "1206", + "equip_audio": "2247", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "650", + "stand_anim": "813", + "attack_audios": "2555,0,0,0", + "tradeable": "true", + "name": "White magic staff", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "6603", + "stand_turn_anim": "1209", + "bonuses": "2,-1,10,10,0,2,3,1,10,0,0,7,1,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "650", + "durability": null, + "name": "White magic staff", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6604" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A razor sharp sword.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "4", + "turn180_anim": "1206", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "381,390,390,390", + "grand_exchange_price": "1187", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "6605", + "stand_turn_anim": "823", + "bonuses": "14,10,-2,0,0,0,2,1,0,0,0,12,1,0,0", + "requirements": "{0,10}-{5,10}", + "shop_price": "624", + "durability": null, + "weight": "1.8", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "1381", + "name": "White sword" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1187", + "durability": null, + "name": "White sword", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6606" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "821", + "examine": "A razor sharp longsword.", + "walk_anim": "819", + "turn90ccw_anim": "822", + "attack_speed": "5", + "turn180_anim": "820", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "grand_exchange_price": "2060", + "stand_anim": "808", + "tradeable": "true", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "6607", + "stand_turn_anim": "823", + "bonuses": "13,18,-2,0,0,0,3,2,0,0,0,16,1,0,0", + "requirements": "{0,10}-{5,10}", + "shop_price": "960", + "durability": null, + "weight": "1.8", + "weapon_interface": "6", + "equip_audio": "2248", + "render_anim": "1", + "name": "White longsword" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2060", + "durability": null, + "name": "White longsword", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6608" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "7044", + "examine": "A two handed sword.", + "walk_anim": "7046", + "turn90ccw_anim": "7043", + "attack_speed": "7", + "two_handed": "true", + "turn180_anim": "7045", + "defence_anim": "7050", + "equipment_slot": "3", + "attack_anims": "7041,7041,7048,7049", + "grand_exchange_price": "4029", + "stand_anim": "7047", + "tradeable": "true", + "run_anim": "7039", + "archery_ticket_price": "0", + "id": "6609", + "stand_turn_anim": "7040", + "bonuses": "-4,27,21,-4,0,0,0,0,0,-1,0,26,1,0,0", + "requirements": "{0,10}-{5,10}", + "shop_price": "1920", + "durability": null, + "weight": "3.6", + "weapon_interface": "7", + "equip_audio": "2248", + "render_anim": "124", + "attack_audios": "2503,0,2504,0", + "name": "White 2h sword" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "4029", + "durability": null, + "name": "White 2h sword", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6610" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "821", + "examine": "A vicious, curved sword.", + "walk_anim": "819", + "turn90ccw_anim": "822", + "attack_speed": "4", + "turn180_anim": "820", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "grand_exchange_price": "1404", + "stand_anim": "808", + "tradeable": "true", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "6611", + "stand_turn_anim": "823", + "bonuses": "4,19,-2,0,0,0,1,0,0,0,0,14,1,0,0", + "requirements": "{0,10}-{5,10}", + "shop_price": "768", + "durability": null, + "weight": "1", + "weapon_interface": "6", + "equip_audio": "2248", + "render_anim": "1", + "attack_audios": "2500,0,2517,0", + "name": "White scimitar" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1404", + "durability": null, + "name": "White scimitar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6612" + }, + { + "requirements": "{0,10}-{5,10}", + "shop_price": "980", + "ge_buy_limit": "100", + "examine": "I don't think it's intended for joinery.", + "durability": null, + "weight": "1.8", + "attack_speed": "6", + "weapon_interface": "10", + "equip_audio": "2233", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "395,395,395,395", + "grand_exchange_price": "1178", + "attack_audios": "2504,0,0,0", + "name": "White warhammer", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6613", + "bonuses": "-4,-4,22,-4,0,0,0,0,0,0,0,19,1,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1178", + "durability": null, + "name": "White warhammer", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6614" + }, + { + "requirements": "{1,10}-{5,10}", + "shop_price": "1440", + "ge_buy_limit": "100", + "examine": "A series of connected metal rings.", + "durability": null, + "weight": "6.8", + "absorb": "1,0,2", + "equipment_slot": "4", + "grand_exchange_price": "788", + "name": "White chainbody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6615", + "bonuses": "0,0,0,-15,0,22,32,39,-3,24,10,0,1,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "788", + "durability": null, + "name": "White chainbody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6616" + }, + { + "requirements": "{1,10}-{5,10}", + "shop_price": "3840", + "ge_buy_limit": "100", + "examine": "Provides excellent protection.", + "durability": null, + "weight": "9.9", + "absorb": "1,0,2", + "equip_audio": "2239", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "5837", + "name": "White platebody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6617", + "bonuses": "0,0,0,-30,-10,41,40,30,-6,40,10,0,1,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "5837", + "durability": null, + "name": "White platebody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6618" + }, + { + "requirements": "{1,10}-{5,10}", + "shop_price": "576", + "ge_buy_limit": "100", + "examine": "These will protect my feet.", + "durability": null, + "weight": "1.3", + "equipment_slot": "10", + "grand_exchange_price": "1016", + "name": "White boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6619", + "bonuses": "0,0,0,-3,-1,7,8,9,0,0,7,0,1,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1016", + "durability": null, + "name": "White boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6620" + }, + { + "remove_head": "true", + "requirements": "{1,10}-{5,10}", + "shop_price": "576", + "ge_buy_limit": "100", + "examine": "A medium sized helmet.", + "durability": null, + "weight": "1.9", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "853", + "name": "White med helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6621", + "bonuses": "0,0,0,-3,-1,9,10,8,-1,9,4,0,1,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "853", + "durability": null, + "name": "White med helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6622" + }, + { + "remove_head": "true", + "requirements": "{1,10}-{5,10}", + "shop_price": "1056", + "ge_buy_limit": "100", + "examine": "A full face helmet.", + "durability": null, + "weight": "2.7", + "equip_audio": "2240", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "2624", + "name": "White full helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6623", + "bonuses": "0,0,0,-6,-2,12,13,10,-1,12,4,0,1,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2624", + "durability": null, + "name": "White full helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6624" + }, + { + "requirements": "{1,10}-{5,10}", + "shop_price": "1920", + "ge_buy_limit": "100", + "examine": "Big, white and heavy looking.", + "durability": null, + "weight": "9", + "equipment_slot": "7", + "grand_exchange_price": "2115", + "name": "White platelegs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6625", + "bonuses": "0,0,0,-21,-7,21,20,19,-4,20,3,0,1,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2115", + "durability": null, + "name": "White platelegs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6626" + }, + { + "requirements": "{1,10}-{5,10}", + "shop_price": "1920", + "ge_buy_limit": "100", + "examine": "Big, white, and heavy looking.", + "durability": null, + "weight": "8.1", + "equipment_slot": "7", + "grand_exchange_price": "2000", + "name": "White plateskirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6627", + "bonuses": "0,0,0,-21,-7,21,20,19,-4,20,3,0,1,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2000", + "durability": null, + "name": "White plateskirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6628" + }, + { + "requirements": "{1,10}-{5,10}", + "shop_price": "6", + "ge_buy_limit": "100", + "examine": "These will keep my hands warm!", + "durability": null, + "weight": "0.2", + "equipment_slot": "9", + "grand_exchange_price": "2036", + "name": "White gloves", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6629", + "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,1,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2036", + "durability": null, + "name": "White gloves", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6630" + }, + { + "requirements": "{1,10}-{5,10}", + "shop_price": "1152", + "ge_buy_limit": "100", + "examine": "A medium square shield.", + "durability": null, + "weight": "3.6", + "absorb": "1,0,2", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "1360", + "name": "White sq shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6631", + "bonuses": "0,0,0,-6,-2,15,16,14,0,15,9,0,1,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1360", + "durability": null, + "name": "White sq shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6632" + }, + { + "requirements": "{1,10}-{5,10}", + "shop_price": "1632", + "ge_buy_limit": "100", + "examine": "A large metal shield.", + "durability": null, + "weight": "5.4", + "absorb": "1,0,2", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "2390", + "name": "White kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6633", + "bonuses": "0,0,0,-8,-2,17,19,18,-1,18,10,0,1,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2390", + "durability": null, + "name": "White kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6634" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A Temple Knight Communication Orb. Top Secret! / Use this to stay in touch with Korasi and Jessika. (A Void Dance version) / Tyr's commorb, given to him by Sir Tiffy. (Tyr's commorb)", + "durability": null, + "name": "Commorb", + "weight": "1", + "archery_ticket_price": "0", + "id": "6635" + }, + { + "examine": "Proof that I have defeated the evil mage Solus.", + "durability": null, + "name": "Solus's hat", + "archery_ticket_price": "0", + "id": "6636" + }, + { + "examine": "From a darker dimension.", + "durability": null, + "name": "Dark beast", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "6637" + }, + { + "examine": "A key to the nature of light itself. (Mourning's Ends Part II)", + "durability": null, + "name": "Colour wheel", + "archery_ticket_price": "0", + "id": "6638" + }, + { + "destroy_message": "Resetting the light maze will generate a new mirror.", + "examine": "A small hand mirror.", + "durability": null, + "name": "Hand mirror", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6639" + }, + { + "destroy_message": "Resetting the light maze will generate a new crystal.", + "examine": "A yellow crystal.", + "durability": null, + "name": "Yellow crystal", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6641" + }, + { + "destroy_message": "Resetting the light maze will generate a new crystal.", + "examine": "A cyan crystal.", + "durability": null, + "name": "Cyan crystal", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6643" + }, + { + "destroy_message": "Resetting the light maze will generate a new crystal.", + "examine": "A blue crystal.", + "durability": null, + "name": "Blue crystal", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6644" + }, + { + "destroy_message": "Resetting the light maze will generate a new crystal.", + "examine": "A fractured crystal, one of the edges is clear.", + "durability": null, + "name": "Fractured crystal", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6646" + }, + { + "destroy_message": "Resetting the light maze will generate a new crystal.", + "examine": "A fractured crystal, one of the edges is clear.", + "durability": null, + "name": "Fractured crystal", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6647" + }, + { + "destroy_message": "You can obtain another list from Thorgel.", + "examine": "It's a list of items I need to collect.", + "durability": null, + "name": "Item list", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6648" + }, + { + "examine": "The journal of Nissyen Edern.", + "durability": null, + "name": "Edern's journal", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6649" + }, + { + "examine": "A blackened crystal sample.", + "durability": null, + "name": "Blackened crystal", + "archery_ticket_price": "0", + "id": "6650" + }, + { + "examine": "A newly formed crystal / A warm energy radiates from this crystal.", + "durability": null, + "name": "Newly made crystal", + "archery_ticket_price": "0", + "id": "6651" + }, + { + "examine": "A newly formed crystal / A warm energy radiates from this crystal.", + "durability": null, + "name": "Newly made crystal", + "archery_ticket_price": "0", + "id": "6652" + }, + { + "destroy_message": "You can get another Crystal trinket from Arianwyn in Lletya.", + "examine": "A small Crystal trinket.", + "durability": null, + "name": "Crystal trinket", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6653" + }, + { + "remove_sleeves": "true", + "examine": "Examine what?", + "durability": null, + "name": "Camo top", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "6654", + "equipment_slot": "4" + }, + { + "examine": "Examine what?", + "durability": null, + "name": "Camo bottoms", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "6655", + "equipment_slot": "7" + }, + { + "examine": "Examine what?", + "durability": null, + "name": "Camo helmet", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "6656", + "equipment_slot": "0" + }, + { + "remove_sleeves": "true", + "examine": "Examine what?", + "durability": null, + "name": "Camo top", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "6657", + "equipment_slot": "4" + }, + { + "examine": "Examine what?", + "durability": null, + "name": "Camo bottoms", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "6658", + "equipment_slot": "7" + }, + { + "examine": "Examine what?", + "durability": null, + "name": "Camo helmet", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "6659", + "equipment_slot": "0" + }, + { + "shop_price": "60", + "examine": "The jar keeps shaking... I'm scared.", + "durability": null, + "name": "Fishing explosive", + "archery_ticket_price": "0", + "id": "6660" + }, + { + "examine": "An angry Ogre in a funny hat.", + "durability": null, + "name": "Mogre", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "6661" + }, + { + "examine": "This fishing rod seems to have been bitten in half.", + "durability": null, + "name": "Broken fishing rod", + "archery_ticket_price": "0", + "id": "6662" + }, + { + "examine": "It seems someone vacated this boot in a hurry.", + "durability": null, + "name": "Forlorn boot", + "archery_ticket_price": "0", + "id": "6663" + }, + { + "requirements": "{18,32}", + "shop_price": "60", + "examine": "The jar keeps shaking... I'm scared.", + "durability": null, + "name": "Fishing explosive", + "archery_ticket_price": "0", + "id": "6664" + }, + { + "examine": "Fishy, damp and smelly.", + "durability": null, + "name": "Mudskipper hat", + "weight": "1", + "archery_ticket_price": "0", + "id": "6665", + "equipment_slot": "0" + }, + { + "examine": "Strangely uncomfortable flippers.", + "durability": null, + "name": "Flippers", + "weight": "2", + "archery_ticket_price": "0", + "id": "6666", + "bonuses": "-2,-2,-2,0,0,0,1,1,0,0,0,0,0,0,0", + "equipment_slot": "10" + }, + { + "ge_buy_limit": "10000", + "examine": "An empty fishbowl.", + "grand_exchange_price": "431", + "durability": null, + "name": "Fishbowl", + "tradeable": "true", + "weight": "1.3", + "archery_ticket_price": "0", + "id": "6667" + }, + { + "examine": "A fishless fishbowl.", + "grand_exchange_price": "619", + "durability": null, + "name": "Fishbowl", + "tradeable": "true", + "weight": "2.3", + "archery_ticket_price": "0", + "id": "6668" + }, + { + "examine": "A fishless fishbowl with some seaweed.", + "grand_exchange_price": "619", + "durability": null, + "name": "Fishbowl", + "tradeable": "true", + "weight": "2.3", + "archery_ticket_price": "0", + "id": "6669" + }, + { + "examine": "A fishbowl with a Tiny Bluefish in it.", + "grand_exchange_price": "619", + "durability": null, + "name": "Fishbowl", + "tradeable": "true", + "weight": "2.3", + "archery_ticket_price": "0", + "id": "6670" + }, + { + "examine": "A fishbowl with a Tiny Greenfish in it.", + "grand_exchange_price": "619", + "durability": null, + "name": "Fishbowl", + "tradeable": "true", + "weight": "2.3", + "archery_ticket_price": "0", + "id": "6671" + }, + { + "examine": "A fishbowl with a Tiny Spinefish in it.", + "grand_exchange_price": "619", + "durability": null, + "name": "Fishbowl", + "tradeable": "true", + "weight": "2.3", + "archery_ticket_price": "0", + "id": "6672" + }, + { + "examine": "An empty fishbowl in a net.", + "durability": null, + "name": "Fishbowl and net", + "weight": "2", + "archery_ticket_price": "0", + "id": "6673" + }, + { + "shop_price": "10", + "examine": "A tiny net for grabbing tiny fish.", + "durability": null, + "name": "Tiny net", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "6674" + }, + { + "examine": "'Ingredients: Ground Guam and Ground Seaweed.", + "durability": null, + "name": "An empty box", + "archery_ticket_price": "0", + "id": "6675" + }, + { + "examine": "'Ingredients: Ground Guam and Ground Seaweed.' Well, I have the Guam Leaf...", + "durability": null, + "name": "Guam in a box", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6677" + }, + { + "examine": "'Ingredients: Ground Guam and Ground Seaweed.' Well, I have the Guam Leaf...", + "durability": null, + "name": "Guam in a box?", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6678" + }, + { + "examine": "'Ingredients: Ground Guam and Ground Seaweed.' Well, I have the Seaweed...", + "durability": null, + "name": "Seaweed in a box", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6679" + }, + { + "examine": "'Ingredients: Ground Guam and Ground Seaweed.' Well, I have the Seaweed...", + "durability": null, + "name": "Seaweed in a box?", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6680" + }, + { + "ge_buy_limit": "100", + "examine": "One of the ingredients for making fish food.", + "grand_exchange_price": "1", + "durability": null, + "name": "Ground guam", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6681" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1", + "durability": null, + "name": "Ground guam", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6682" + }, + { + "ge_buy_limit": "100", + "examine": "One of the ingredients for making fish food.", + "grand_exchange_price": "14", + "durability": null, + "name": "Ground seaweed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6683" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "14", + "durability": null, + "name": "Ground seaweed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6684" + }, + { + "ge_buy_limit": "1000", + "examine": "A Saradomin Brew.", + "grand_exchange_price": "15300", + "durability": null, + "name": "Saradomin brew(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6685" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "15300", + "durability": null, + "name": "Saradomin brew(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6686" + }, + { + "ge_buy_limit": "1000", + "examine": "A Saradomin Brew.", + "grand_exchange_price": "11400", + "durability": null, + "name": "Saradomin brew(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6687" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "11400", + "durability": null, + "name": "Saradomin brew(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6688" + }, + { + "ge_buy_limit": "1000", + "examine": "A Saradomin Brew.", + "grand_exchange_price": "7566", + "durability": null, + "name": "Saradomin brew(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6689" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "7566", + "durability": null, + "name": "Saradomin brew(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6690" + }, + { + "ge_buy_limit": "1000", + "examine": "A Saradomin Brew.", + "grand_exchange_price": "3783", + "durability": null, + "name": "Saradomin brew(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6691" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "3783", + "durability": null, + "name": "Saradomin brew(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6692" + }, + { + "ge_buy_limit": "10000", + "examine": "It's a crushed bird's nest.", + "grand_exchange_price": "10500", + "durability": null, + "name": "Crushed nest", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6693" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "10500", + "durability": null, + "name": "Crushed nest", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6694" + }, + { + "examine": "\"A cold-blooded creature, partial to warmth.", + "durability": null, + "name": "Desert lizard", + "archery_ticket_price": "0", + "id": "6695" + }, + { + "requirements": "{22,18}", + "shop_price": "1", + "examine": "Contains ice-cold water.", + "durability": null, + "name": "Ice cooler", + "archery_ticket_price": "0", + "id": "6696" + }, + { + "shop_price": "5", + "ge_buy_limit": "10000", + "examine": "A pat of freshly churned butter.", + "grand_exchange_price": "405", + "durability": null, + "name": "Pat of butter", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "6697" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "405", + "durability": null, + "name": "Pat of butter", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6698" + }, + { + "durability": null, + "name": "Burnt potato", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6700" + }, + { + "ge_buy_limit": "1000", + "examine": "It'd taste even better with some toppings.", + "grand_exchange_price": "326", + "durability": null, + "name": "Baked potato", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "6701" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "326", + "durability": null, + "name": "Baked potato", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6702" + }, + { + "ge_buy_limit": "1000", + "examine": "A baked potato with butter.", + "grand_exchange_price": "745", + "durability": null, + "name": "Potato with butter", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "6703" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "745", + "durability": null, + "name": "Potato with butter", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6704" + }, + { + "shop_price": "350", + "ge_buy_limit": "10000", + "examine": "A baked potato with butter and cheese.", + "grand_exchange_price": "604", + "durability": null, + "name": "Potato with cheese", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "6705" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "604", + "durability": null, + "name": "Potato with cheese", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6706" + }, + { + "examine": "An amulet of Camel-speak. It makes vague braying noises.", + "durability": null, + "name": "Camulet", + "archery_ticket_price": "0", + "id": "6707", + "equipment_slot": "2" + }, + { + "shop_price": "200", + "examine": "Especially good against diseased arachnids.", + "durability": null, + "name": "Slayer gloves", + "archery_ticket_price": "0", + "id": "6708", + "bonuses": "0,0,0,0,0,4,5,3,0,0,1,0,0,0,0" + }, + { + "examine": "A bunch of legs, eyes and teeth.", + "durability": null, + "name": "Fever spider", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "6709" + }, + { + "examine": "A blindweed seed - plant in a Blindweed patch.", + "durability": null, + "name": "Blindweed seed", + "archery_ticket_price": "0", + "id": "6710" + }, + { + "examine": "An inedible, foul smelling herb.", + "durability": null, + "name": "Blindweed", + "archery_ticket_price": "0", + "id": "6711" + }, + { + "examine": "Common bucket: It's a bucket of water.2008 Easter event: It's a bucket of water from the Easter Bunny's warren. Regular bucket filled from Braindeath Island: It's a bucket of... water?", + "grand_exchange_price": "74", + "durability": null, + "name": "Bucket of water", + "tradeable": "true", + "weight": "3", + "archery_ticket_price": "0", + "id": "6712" + }, + { + "examine": "A heavy metal wrench.", + "durability": null, + "name": "Wrench", + "archery_ticket_price": "0", + "id": "6713" + }, + { + "examine": "A shining paragon of wrenchly virtue.", + "durability": null, + "name": "Holy wrench", + "archery_ticket_price": "0", + "id": "6714" + }, + { + "examine": "They look at you balefully. 'Feed us...", + "durability": null, + "name": "Sluglings", + "archery_ticket_price": "0", + "id": "6715" + }, + { + "examine": "A sinister looking squid.", + "durability": null, + "name": "Karamthulhu", + "archery_ticket_price": "0", + "id": "6716" + }, + { + "examine": "A sinister looking squid.", + "durability": null, + "name": "Karamthulhu", + "archery_ticket_price": "0", + "id": "6717" + }, + { + "examine": "A diseased deceased Fever Spider. Handle with care.", + "durability": null, + "name": "Fever spider body", + "archery_ticket_price": "0", + "id": "6718" + }, + { + "examine": "Sorry, I mean a bucket of 'rum'.", + "durability": null, + "name": "Unsanitary swill", + "archery_ticket_price": "0", + "id": "6719" + }, + { + "requirements": "{18,42}", + "shop_price": "200", + "examine": "Especially good against diseased arachnids.", + "durability": null, + "name": "Slayer gloves", + "archery_ticket_price": "0", + "id": "6720", + "bonuses": "0,0,0,0,0,4,5,3,0,0,1,0,0,0,0", + "equipment_slot": "9" + }, + { + "examine": "A decent enough weapon gone rusty.", + "attack_audios": "2500,0,2517,0", + "durability": null, + "name": "Rusty scimitar", + "weight": "2", + "archery_ticket_price": "0", + "id": "6721" + }, + { + "examine": "Alas...I hardly knew him.", + "durability": null, + "name": "Zombie head", + "archery_ticket_price": "0", + "id": "6722" + }, + { + "durability": null, + "name": "Fishbowl", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6723" + }, + { + "requirements": "{4,50}", + "ge_buy_limit": "100", + "examine": "An ancient Fremennik bow that was once used to battle the Moon Clan.", + "has_special": "true", + "durability": null, + "rare_item": "true", + "weight": "1", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "16", + "render_anim": "2588", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "426,426,426,426", + "lendable": "true", + "grand_exchange_price": "12200", + "name": "Seercull", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6724", + "bonuses": "0,0,0,0,69,0,0,0,0,0,0,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "12200", + "durability": null, + "name": "Seercull", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6725" + }, + { + "durability": null, + "name": "Mud battlestaff", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6726" + }, + { + "durability": null, + "name": "Mystic mud staff", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6727" + }, + { + "examine": "A pot of crushed small zombie monkey bones.", + "durability": null, + "name": "Bonemeal", + "weight": "1", + "archery_ticket_price": "0", + "id": "6728" + }, + { + "ge_buy_limit": "10000", + "examine": "These would feed a dogfish for months!", + "grand_exchange_price": "9616", + "durability": null, + "name": "Dagannoth bones", + "tradeable": "true", + "weight": "1.5", + "archery_ticket_price": "0", + "id": "6729" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "9616", + "durability": null, + "name": "Dagannoth bones", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6730" + }, + { + "lendable": "true", + "ge_buy_limit": "10", + "examine": "A mysterious ring that can fill the wearer with magical power...", + "grand_exchange_price": "478800", + "rare_item": "true", + "durability": null, + "name": "Seers ring", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6731", + "bonuses": "0,0,0,4,0,0,0,0,4,0,0,0,0,0,0", + "equipment_slot": "12" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "478800", + "durability": null, + "name": "Seers ring", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6732" + }, + { + "lendable": "true", + "ge_buy_limit": "10", + "examine": "A fabled ring that improves the wearer's skill with a bow...", + "grand_exchange_price": "1400000", + "rare_item": "true", + "durability": null, + "name": "Archers ring", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6733", + "bonuses": "0,0,0,0,4,0,0,0,0,4,0,0,0,0,0", + "equipment_slot": "12" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "1400000", + "durability": null, + "name": "Archers ring", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6734" + }, + { + "lendable": "true", + "ge_buy_limit": "10", + "examine": "A legendary ring once worn by Fremennik warriors.", + "grand_exchange_price": "178100", + "rare_item": "true", + "durability": null, + "name": "Warrior ring", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6735", + "bonuses": "0,4,0,0,0,0,4,0,0,0,0,0,0,0,0", + "equipment_slot": "12" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "178100", + "durability": null, + "name": "Warrior ring", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6736" + }, + { + "lendable": "true", + "ge_buy_limit": "10", + "examine": "A ring reputed to bring out a berserk fury in its wearer.", + "grand_exchange_price": "2700000", + "rare_item": "true", + "durability": null, + "name": "Berserker ring", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6737", + "bonuses": "0,0,0,0,0,0,0,4,0,0,0,4,0,0,0", + "equipment_slot": "12" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "2700000", + "durability": null, + "name": "Berserker ring", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6738" + }, + { + "requirements": "{0,60}", + "ge_buy_limit": "10", + "examine": "A very powerful axe.", + "has_special": "true", + "rare_item": "true", + "durability": null, + "weapon_interface": "2", + "equip_audio": "2229", + "render_anim": "2586", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "395,395,395,395", + "grand_exchange_price": "813100", + "attack_audios": "2498,2498,2497,2498", + "name": "Dragon axe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6739", + "bonuses": "-2,38,32,0,0,0,1,0,0,0,0,42,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "813100", + "durability": null, + "name": "Dragon axe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6740" + }, + { + "examine": "Bob can fix this broken (metal) axe for me.", + "durability": null, + "name": "Broken axe", + "weight": "2.5", + "archery_ticket_price": "0", + "id": "6741", + "equipment_slot": "3" + }, + { + "durability": null, + "name": "Broken axe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6742" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6744" + }, + { + "examine": "The magical sword 'Silverlight'. / The magical sword 'Silverlight', stained black with mushroom ink. (during Shadow of the Storm)", + "durability": null, + "weight": "1.8", + "attack_speed": "5", + "weapon_interface": "6", + "render_anim": "2554", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "name": "Silverlight", + "archery_ticket_price": "0", + "id": "6745", + "bonuses": "9,14,-2,0,0,0,3,2,1,0,0,12,0,0,0" + }, + { + "examine": "The magical sword Silverlight, enhanced with the blood of Agrith-Naar.", + "has_special": "true", + "durability": null, + "weight": "1.8", + "attack_speed": "5", + "weapon_interface": "6", + "render_anim": "2554", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "name": "Darklight", + "archery_ticket_price": "0", + "id": "6746", + "bonuses": "10,16,-2,0,0,0,3,2,2,0,0,13,0,0,0" + }, + { + "examine": "Used to make the sigil of the demon Agrith-Naar.", + "durability": null, + "name": "Demonic sigil mould", + "archery_ticket_price": "0", + "id": "6747" + }, + { + "examine": "A sigil used for the summoning of the demon Agrith-Naar.", + "durability": null, + "name": "Demonic sigil", + "weight": "1.8", + "archery_ticket_price": "0", + "id": "6748" + }, + { + "examine": "Will this book help in summoning Agrith-Naar?", + "durability": null, + "name": "Demonic tome", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "6749" + }, + { + "remove_sleeves": "true", + "examine": "A desert shirt stained black with mushroom ink.", + "durability": null, + "name": "Black desert shirt", + "archery_ticket_price": "0", + "id": "6750", + "equipment_slot": "4" + }, + { + "examine": "A desert robe stained black with mushroom ink.", + "durability": null, + "name": "Black desert robe", + "archery_ticket_price": "0", + "id": "6752", + "equipment_slot": "7" + }, + { + "destroy_message": "Hopefully Erin has a copy!", + "examine": "It changes temperature as I walk. (Meeting History)", + "durability": null, + "name": "Enchanted key", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6754", + "equipment_slot": "3" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A Guthix Mjolnir.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "turn180_anim": "1206", + "defence_anim": "2079", + "equipment_slot": "3", + "attack_anims": "2080,2081,2082,2080", + "destroy_message": "You can reclaim this item from the place you found it.", + "grand_exchange_price": "2875", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "6760", + "stand_turn_anim": "1209", + "bonuses": "0,0,11,0,0,0,0,0,0,0,0,14,0,0,0", + "shop_price": "250", + "durability": null, + "weight": "2", + "weapon_interface": "3", + "render_anim": "28", + "name": "Guthix mjolnir" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2875", + "durability": null, + "name": "Guthix mjolnir", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6761" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A Saradomin Mjolnir.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "turn180_anim": "1206", + "defence_anim": "2079", + "equipment_slot": "3", + "attack_anims": "2080,2081,2082,2080", + "destroy_message": "You can reclaim this item from the place you found it.", + "grand_exchange_price": "17200", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "6762", + "stand_turn_anim": "1209", + "bonuses": "0,0,11,0,0,0,0,0,0,0,0,14,0,0,0", + "shop_price": "250", + "durability": null, + "weight": "2", + "weapon_interface": "3", + "render_anim": "28", + "name": "Saradomin mjolnir" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "17200", + "durability": null, + "name": "Saradomin mjolnir", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6763" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A Zamorak mjolnir.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "turn180_anim": "1206", + "defence_anim": "2079", + "equipment_slot": "3", + "attack_anims": "2080,2081,2082,2080", + "destroy_message": "You can reclaim this item from the place you found it.", + "grand_exchange_price": "4115", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "6764", + "stand_turn_anim": "1209", + "bonuses": "0,0,11,0,0,0,0,0,0,0,0,14,0,0,0", + "durability": null, + "weight": "2", + "weapon_interface": "3", + "render_anim": "28", + "name": "Zamorak mjolnir" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "4115", + "durability": null, + "name": "Zamorak mjolnir", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6765" + }, + { + "examine": "Antipoison for Pox.", + "durability": null, + "name": "Cat antipoison", + "archery_ticket_price": "0", + "id": "6766" + }, + { + "examine": "A little more smelly than usual.", + "durability": null, + "name": "Poisoned cheese", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "6768" + }, + { + "destroy_message": "You can obtain another sheet of music by talking to the snakecharmer of Pollnivneach.", + "examine": "Charming.", + "durability": null, + "name": "Music scroll", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6769" + }, + { + "destroy_message": "You can obtain another set of directions to the party by talking to Jimmy Dazzler.", + "examine": "Jimmy Dazzler's directions.", + "durability": null, + "name": "Directions", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6770" + }, + { + "examine": "Contains garden weeds.", + "durability": null, + "name": "Pot of weeds", + "archery_ticket_price": "0", + "id": "6771" + }, + { + "examine": "Contains slowly burning garden weeds.", + "durability": null, + "name": "Smouldering pot", + "archery_ticket_price": "0", + "id": "6772" + }, + { + "turn90cw_anim": "1424", + "examine": "A pole for putting rats on.", + "walk_anim": "1422", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1425", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "10", + "turn180_anim": "1423", + "render_anim": "131", + "equipment_slot": "3", + "stand_anim": "1421", + "name": "Rat pole", + "run_anim": "1427", + "archery_ticket_price": "0", + "id": "6773", + "stand_turn_anim": "1426", + "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0" + }, + { + "turn90cw_anim": "1424", + "examine": "A pole with one rat on it.", + "walk_anim": "1422", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1425", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "10", + "turn180_anim": "1423", + "render_anim": "131", + "equipment_slot": "3", + "stand_anim": "1421", + "name": "Rat pole", + "run_anim": "1427", + "archery_ticket_price": "0", + "id": "6774", + "stand_turn_anim": "1426", + "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0" + }, + { + "turn90cw_anim": "1424", + "examine": "A pole with two rats on it.", + "walk_anim": "1422", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1425", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "10", + "turn180_anim": "1423", + "render_anim": "131", + "equipment_slot": "3", + "stand_anim": "1421", + "name": "Rat pole", + "run_anim": "1427", + "archery_ticket_price": "0", + "id": "6775", + "stand_turn_anim": "1426", + "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0" + }, + { + "turn90cw_anim": "1424", + "examine": "A pole with three rats on it.", + "walk_anim": "1422", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1425", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "10", + "turn180_anim": "1423", + "render_anim": "131", + "equipment_slot": "3", + "stand_anim": "1421", + "name": "Rat pole", + "run_anim": "1427", + "archery_ticket_price": "0", + "id": "6776", + "stand_turn_anim": "1426", + "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0" + }, + { + "turn90cw_anim": "1424", + "examine": "A pole with four rats on it.", + "walk_anim": "1422", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1425", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "10", + "turn180_anim": "1423", + "render_anim": "131", + "equipment_slot": "3", + "stand_anim": "1421", + "name": "Rat pole", + "run_anim": "1427", + "archery_ticket_price": "0", + "id": "6777", + "stand_turn_anim": "1426", + "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0" + }, + { + "turn90cw_anim": "1424", + "examine": "A pole with five rats on it.", + "walk_anim": "1422", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1425", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "10", + "turn180_anim": "1423", + "render_anim": "131", + "equipment_slot": "3", + "stand_anim": "1421", + "name": "Rat pole", + "run_anim": "1427", + "archery_ticket_price": "0", + "id": "6778", + "stand_turn_anim": "1426", + "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0" + }, + { + "turn90cw_anim": "1424", + "examine": "A pole with six rats on it.", + "walk_anim": "1422", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1425", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "10", + "turn180_anim": "1423", + "render_anim": "131", + "equipment_slot": "3", + "stand_anim": "1421", + "name": "Rat pole", + "run_anim": "1427", + "archery_ticket_price": "0", + "id": "6779", + "stand_turn_anim": "1426", + "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0" + }, + { + "examine": "Menaphite thug.", + "durability": null, + "name": "Menaphite thug", + "archery_ticket_price": "0", + "id": "6780" + }, + { + "remove_sleeves": "true", + "examine": "This looks quite old.", + "durability": null, + "name": "Robe of elidinis", + "archery_ticket_price": "0", + "id": "6786", + "equipment_slot": "4" + }, + { + "examine": "This looks quite old.", + "durability": null, + "name": "Robe of elidinis", + "archery_ticket_price": "0", + "id": "6787", + "equipment_slot": "7" + }, + { + "examine": "This robe is too torn to wear.", + "durability": null, + "name": "Torn robe", + "weight": "1", + "archery_ticket_price": "0", + "id": "6788" + }, + { + "examine": "This robe is too torn to wear.", + "durability": null, + "name": "Torn robe", + "weight": "1", + "archery_ticket_price": "0", + "id": "6789" + }, + { + "durability": null, + "name": "Shoes", + "archery_ticket_price": "0", + "id": "6790", + "equipment_slot": "10" + }, + { + "examine": "Awusah's Sole.", + "durability": null, + "name": "Sole", + "weight": "1", + "archery_ticket_price": "0", + "id": "6791" + }, + { + "examine": "An ancient key from the shrine in Nardah. (Spirits of the Elid)", + "durability": null, + "name": "Ancestral key", + "archery_ticket_price": "0", + "id": "6792" + }, + { + "examine": "The Ballad of Jaresh.", + "durability": null, + "name": "Ballad", + "archery_ticket_price": "0", + "id": "6793" + }, + { + "shop_price": "30", + "ge_buy_limit": "1000", + "examine": "A tasty treat from Nardah - better eat this before it melts.", + "grand_exchange_price": "210", + "durability": null, + "name": "Choc-ice", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6794" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "210", + "durability": null, + "name": "Choc-ice", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6795" + }, + { + "bankable": "false", + "examine": "Wonder what happens if I rub it...", + "durability": null, + "name": "Lamp", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "6796" + }, + { + "shop_price": "8", + "examine": "See article", + "grand_exchange_price": "206", + "durability": null, + "name": "Watering can", + "archery_ticket_price": "0", + "id": "6797" + }, + { + "examine": "A scroll once used by a champion.", + "durability": null, + "name": "Champion scroll", + "archery_ticket_price": "0", + "id": "6798" + }, + { + "examine": "A scroll once used by a champion.", + "durability": null, + "name": "Champion scroll", + "archery_ticket_price": "0", + "id": "6799" + }, + { + "examine": "A scroll once used by a champion.", + "durability": null, + "name": "Champion scroll", + "archery_ticket_price": "0", + "id": "6800" + }, + { + "examine": "A scroll once used by a champion.", + "durability": null, + "name": "Champion scroll", + "archery_ticket_price": "0", + "id": "6801" + }, + { + "examine": "A scroll once used by a champion.", + "durability": null, + "name": "Champion scroll", + "archery_ticket_price": "0", + "id": "6802" + }, + { + "examine": "A scroll once used by a champion.", + "durability": null, + "name": "Champion scroll", + "archery_ticket_price": "0", + "id": "6803" + }, + { + "examine": "A scroll once used by a champion.", + "durability": null, + "name": "Champion scroll", + "archery_ticket_price": "0", + "id": "6804" + }, + { + "examine": "A scroll once used by a champion.", + "durability": null, + "name": "Champion scroll", + "archery_ticket_price": "0", + "id": "6805" + }, + { + "examine": "A scroll once used by a champion.", + "durability": null, + "name": "Champion scroll", + "archery_ticket_price": "0", + "id": "6806" + }, + { + "examine": "A scroll once used by a champion.", + "durability": null, + "name": "Champion scroll", + "archery_ticket_price": "0", + "id": "6807" + }, + { + "examine": "A scroll once used by a champion.", + "durability": null, + "name": "Champion scroll", + "archery_ticket_price": "0", + "id": "6808" + }, + { + "requirements": "{1,50}-{2,50}", + "ge_buy_limit": "10", + "examine": "These look pretty heavy.", + "durability": null, + "weight": "15", + "absorb": "2,0,5", + "equipment_slot": "7", + "lendable": "true", + "grand_exchange_price": "39400", + "name": "Granite legs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6809", + "bonuses": "0,0,0,-31,-18,43,45,41,-4,68,20,0,0,0,0" + }, + { + "examine": "A pot of crushed large zombie monkey bones.", + "durability": null, + "name": "Bonemeal", + "weight": "1", + "archery_ticket_price": "0", + "id": "6810" + }, + { + "examine": "A very dangerous pile of animated Wyvern bones.", + "durability": null, + "name": "Skeletal wyvern", + "archery_ticket_price": "0", + "attack_speed": "6", + "id": "6811" + }, + { + "ge_buy_limit": "1000", + "examine": "Bones of a huge flying creature.", + "grand_exchange_price": "4845", + "durability": null, + "name": "Wyvern bones", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "6812" + }, + { + "durability": null, + "name": "Granite legs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6813" + }, + { + "shop_price": "20", + "ge_buy_limit": "100", + "examine": "This would make warm clothing.", + "grand_exchange_price": "90", + "durability": null, + "name": "Fur", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "6814" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "90", + "durability": null, + "name": "Fur", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6815" + }, + { + "durability": null, + "name": "Wyvern bones", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6816" + }, + { + "turn90cw_anim": "7044", + "examine": "A slender two-handed sword.", + "walk_anim": "7046", + "durability": null, + "destroy": "true", + "weight": "3", + "turn90ccw_anim": "7043", + "two_handed": "true", + "turn180_anim": "7045", + "render_anim": "124", + "equipment_slot": "3", + "destroy_message": "You can reclaim this item from the place you found it.", + "stand_anim": "7047", + "name": "Slender blade", + "tradeable": "false", + "run_anim": "7039", + "archery_ticket_price": "0", + "id": "6817", + "stand_turn_anim": "7040" + }, + { + "turn90cw_anim": "1207", + "examine": "A sharp sword that can also fire arrows.", + "walk_anim": "1205", + "durability": null, + "destroy": "true", + "weight": "3", + "turn90ccw_anim": "1208", + "turn180_anim": "1206", + "render_anim": "28", + "equipment_slot": "3", + "destroy_message": "You can make a replacement.", + "stand_anim": "813", + "name": "Bow-sword", + "tradeable": "false", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "6818", + "stand_turn_anim": "1209" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "shop_price": "25000", + "examine": "A large pouch used for storing essence.", + "durability": null, + "name": "Large pouch", + "weight": "1", + "archery_ticket_price": "0", + "id": "6819" + }, + { + "destroy_message": "I can get another from the assassin beside the winch that leads down into Senntisten temple.", + "examine": "It seems to have pieces missing. After Temple at Senntisten quest: The assassin's plunder from the church on Entrana.", + "durability": null, + "name": "Relic", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6820" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "This looks valuable.", + "durability": null, + "name": "Orb", + "archery_ticket_price": "0", + "id": "6821" + }, + { + "examine": "See individual articles.", + "durability": null, + "name": "Star bauble", + "archery_ticket_price": "0", + "id": "6822" + }, + { + "examine": "See individual articles.", + "durability": null, + "name": "Star bauble", + "archery_ticket_price": "0", + "id": "6823" + }, + { + "examine": "See individual articles.", + "durability": null, + "name": "Star bauble", + "archery_ticket_price": "0", + "id": "6824" + }, + { + "examine": "See individual articles.", + "durability": null, + "name": "Star bauble", + "archery_ticket_price": "0", + "id": "6825" + }, + { + "examine": "See individual articles.", + "durability": null, + "name": "Star bauble", + "archery_ticket_price": "0", + "id": "6826" + }, + { + "examine": "See individual articles.", + "durability": null, + "name": "Star bauble", + "archery_ticket_price": "0", + "id": "6827" + }, + { + "examine": "See individual articles.", + "durability": null, + "name": "Box bauble", + "archery_ticket_price": "0", + "id": "6828" + }, + { + "examine": "See individual articles.", + "durability": null, + "name": "Box bauble", + "archery_ticket_price": "0", + "id": "6829" + }, + { + "examine": "See individual articles.", + "durability": null, + "name": "Box bauble", + "archery_ticket_price": "0", + "id": "6830" + }, + { + "examine": "See individual articles.", + "durability": null, + "name": "Box bauble", + "archery_ticket_price": "0", + "id": "6831" + }, + { + "examine": "See individual articles.", + "durability": null, + "name": "Box bauble", + "archery_ticket_price": "0", + "id": "6832" + }, + { + "examine": "See individual articles.", + "durability": null, + "name": "Box bauble", + "archery_ticket_price": "0", + "id": "6833" + }, + { + "examine": "See individual articles.", + "durability": null, + "name": "Diamond bauble", + "archery_ticket_price": "0", + "id": "6834" + }, + { + "examine": "See individual articles.", + "durability": null, + "name": "Diamond bauble", + "archery_ticket_price": "0", + "id": "6835" + }, + { + "examine": "See individual articles.", + "durability": null, + "name": "Diamond bauble", + "archery_ticket_price": "0", + "id": "6836" + }, + { + "examine": "See individual articles.", + "durability": null, + "name": "Diamond bauble", + "archery_ticket_price": "0", + "id": "6837" + }, + { + "examine": "See individual articles.", + "durability": null, + "name": "Diamond bauble", + "archery_ticket_price": "0", + "id": "6838" + }, + { + "examine": "See individual articles.", + "durability": null, + "name": "Diamond bauble", + "archery_ticket_price": "0", + "id": "6839" + }, + { + "examine": "See individual articles.", + "durability": null, + "name": "Tree bauble", + "archery_ticket_price": "0", + "id": "6840" + }, + { + "examine": "See individual articles.", + "durability": null, + "name": "Tree bauble", + "archery_ticket_price": "0", + "id": "6841" + }, + { + "examine": "See individual articles.", + "durability": null, + "name": "Tree bauble", + "archery_ticket_price": "0", + "id": "6842" + }, + { + "examine": "See individual articles.", + "durability": null, + "name": "Tree bauble", + "archery_ticket_price": "0", + "id": "6843" + }, + { + "examine": "See individual articles.", + "durability": null, + "name": "Tree bauble", + "archery_ticket_price": "0", + "id": "6844" + }, + { + "examine": "See individual articles.", + "durability": null, + "name": "Tree bauble", + "archery_ticket_price": "0", + "id": "6845" + }, + { + "examine": "See individual articles.", + "durability": null, + "name": "Bell bauble", + "archery_ticket_price": "0", + "id": "6846" + }, + { + "examine": "See individual articles.", + "durability": null, + "name": "Bell bauble", + "archery_ticket_price": "0", + "id": "6847" + }, + { + "examine": "See individual articles.", + "durability": null, + "name": "Bell bauble", + "archery_ticket_price": "0", + "id": "6848" + }, + { + "examine": "See individual articles.", + "durability": null, + "name": "Bell bauble", + "archery_ticket_price": "0", + "id": "6849" + }, + { + "examine": "See individual articles.", + "durability": null, + "name": "Bell bauble", + "archery_ticket_price": "0", + "id": "6850" + }, + { + "examine": "See individual articles.", + "durability": null, + "name": "Bell bauble", + "archery_ticket_price": "0", + "id": "6851" + }, + { + "examine": "A box for storing completed puppets.", + "durability": null, + "name": "Puppet box", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6852" + }, + { + "examine": "A box for storing painted baubles.", + "durability": null, + "name": "Bauble box", + "archery_ticket_price": "0", + "id": "6853" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A box for storing completed puppets.", + "durability": null, + "name": "Puppet box", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6854" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A box for storing painted baubles.", + "durability": null, + "name": "Bauble box", + "archery_ticket_price": "0", + "id": "6855" + }, + { + "destroy_message": "You can obtain another hat from Diango in the Draynor Market.", + "examine": "A woolly bobble hat.", + "durability": null, + "name": "Bobble hat", + "tradeable": "false", + "destroy": "true", + "weight": "0.25", + "archery_ticket_price": "0", + "id": "6856", + "equipment_slot": "0" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A woolly scarf.", + "durability": null, + "name": "Bobble scarf", + "weight": "0.25", + "archery_ticket_price": "0", + "id": "6857", + "equipment_slot": "2" + }, + { + "destroy_message": "You can obtain another hat from Diango in the Draynor Market.", + "shop_price": "160", + "examine": "A woolly Jester hat.", + "durability": null, + "name": "Jester hat", + "tradeable": "false", + "destroy": "true", + "weight": "0.25", + "archery_ticket_price": "0", + "id": "6858", + "equipment_slot": "0" + }, + { + "destroy_message": "You can get another Jester scarf from Diango.", + "examine": "A woolly jester scarf.", + "durability": null, + "name": "Jester scarf", + "tradeable": "false", + "destroy": "true", + "weight": "0.25", + "archery_ticket_price": "0", + "id": "6859", + "equipment_slot": "2" + }, + { + "destroy_message": "You may get another from Diango in Draynor Village.", + "examine": "A woolly triple bobble jester hat.", + "durability": null, + "name": "Tri-jester hat", + "tradeable": "false", + "destroy": "true", + "weight": "0.25", + "archery_ticket_price": "0", + "id": "6860", + "equipment_slot": "0" + }, + { + "destroy_message": "You can obtain another jester scarf from Diango in the Draynor Market.", + "examine": "A woolly jester scarf.", + "durability": null, + "name": "Tri-jester scarf", + "tradeable": "false", + "destroy": "true", + "weight": "0.25", + "archery_ticket_price": "0", + "id": "6861", + "equipment_slot": "2" + }, + { + "destroy_message": "You can obtain another hat from Diango in the Draynor Market.", + "examine": "A woolly tobogganing hat.", + "durability": null, + "name": "Woolly hat", + "tradeable": "false", + "destroy": "true", + "weight": "0.25", + "archery_ticket_price": "0", + "id": "6862", + "equipment_slot": "0" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A woolly tobogganing scarf.", + "durability": null, + "name": "Woolly scarf", + "tradeable": "false", + "destroy": "true", + "weight": "0.25", + "archery_ticket_price": "0", + "id": "6863", + "equipment_slot": "2" + }, + { + "examine": "The controlling part of a marionette.", + "durability": null, + "name": "Marionette handle", + "archery_ticket_price": "0", + "id": "6864", + "equipment_slot": "3" + }, + { + "destroy_message": "You can obtain another marionette in Diango's workshop by the trap door.", + "examine": "I've got no strings ... oh hang on!", + "durability": null, + "name": "Blue marionette", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6865" + }, + { + "destroy_message": "You can obtain another marionette in Diango's workshop by the trap door.", + "examine": "I've got no strings ... oh hang on!", + "durability": null, + "name": "Green marionette", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6866" + }, + { + "destroy_message": "You can obtain another marionette in Diango's workshop by the trap door.", + "examine": "I've got no strings ... oh hang on!", + "durability": null, + "name": "Red marionette", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6867" + }, + { + "examine": "I've got no strings ... oh hang on!", + "durability": null, + "name": "Blue marionette", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6868" + }, + { + "examine": "I've got no strings ... oh hang on!", + "durability": null, + "name": "Green marionette", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6869" + }, + { + "examine": "I've got no strings ... oh hang on!", + "durability": null, + "name": "Red marionette", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6870" + }, + { + "examine": "I've got no strings ... oh hang on!", + "durability": null, + "name": "Red marionette", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6871" + }, + { + "examine": "I've got no strings ... oh hang on!", + "durability": null, + "name": "Red marionette", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6872" + }, + { + "examine": "I've got no strings ... oh hang on!", + "durability": null, + "name": "Red marionette", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6873" + }, + { + "examine": "I've got no strings ... oh hang on!", + "durability": null, + "name": "Red marionette", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6874" + }, + { + "examine": "I've got no strings ... oh hang on!", + "durability": null, + "name": "Blue marionette", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6875" + }, + { + "examine": "I've got no strings ... oh hang on!", + "durability": null, + "name": "Blue marionette", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6876" + }, + { + "examine": "I've got no strings ... oh hang on!", + "durability": null, + "name": "Blue marionette", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6877" + }, + { + "examine": "I've got no strings ... oh hang on!", + "durability": null, + "name": "Blue marionette", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6878" + }, + { + "examine": "I've got no strings ... oh hang on!", + "durability": null, + "name": "Green marionette", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6879" + }, + { + "examine": "I've got no strings ... oh hang on!", + "durability": null, + "name": "Green marionette", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6880" + }, + { + "examine": "I've got no strings ... oh hang on!", + "durability": null, + "name": "Green marionette", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6881" + }, + { + "examine": "I've got no strings ... oh hang on!", + "durability": null, + "name": "Green marionette", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6882" + }, + { + "examine": "A tasty fruit.", + "durability": null, + "name": "Peach", + "archery_ticket_price": "0", + "id": "6883" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A magic training arena progress hat", + "durability": null, + "name": "Progress hat", + "archery_ticket_price": "0", + "id": "6885", + "equipment_slot": "0" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A magic training arena progress hat", + "durability": null, + "name": "Progress hat", + "archery_ticket_price": "0", + "id": "6886", + "equipment_slot": "0" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A magic training arena progress hat", + "durability": null, + "name": "Progress hat", + "archery_ticket_price": "0", + "id": "6887", + "equipment_slot": "0" + }, + { + "bankable": "false", + "examine": "A guardian of the arena.", + "durability": null, + "name": "Guardian statue", + "archery_ticket_price": "0", + "id": "6888" + }, + { + "requirements": "{6,60}", + "ge_buy_limit": "10", + "examine": "The magical book of the Mage.", + "grand_exchange_price": "3800000", + "durability": null, + "name": "Mage's book", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "6889", + "bonuses": "0,0,0,15,0,0,0,0,15,0,15,0,0,0,0", + "equipment_slot": "5" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "3800000", + "durability": null, + "name": "Mage's book", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6890" + }, + { + "shop_price": "200", + "examine": "A book about the Training Arena.", + "durability": null, + "name": "Arena book", + "weight": "1", + "archery_ticket_price": "0", + "id": "6891" + }, + { + "bankable": "false", + "shop_price": "6", + "examine": "Comfortable leather boots.", + "grand_exchange_price": "189", + "durability": null, + "name": "Leather boots", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "6893", + "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0" + }, + { + "bankable": "false", + "examine": "A large metal shield.", + "grand_exchange_price": "3084", + "durability": null, + "name": "Adamant kiteshield", + "tradeable": "true", + "weight": "5.8", + "archery_ticket_price": "0", + "id": "6894", + "absorb": "3,0,6", + "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,30,0,0,0,0" + }, + { + "bankable": "false", + "examine": "A medium sized helmet.", + "grand_exchange_price": "1049", + "durability": null, + "name": "Adamant med helm", + "tradeable": "true", + "weight": "1.8", + "archery_ticket_price": "0", + "id": "6895", + "absorb": "1,0,2", + "bonuses": "0,0,0,-3,-1,14,15,13,-1,14,6,0,0,0,0" + }, + { + "bankable": "false", + "shop_price": "350", + "examine": "This looks valuable.", + "grand_exchange_price": "644", + "durability": null, + "name": "Emerald", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6896" + }, + { + "bankable": "false", + "shop_price": "32000", + "examine": "A razor sharp longsword", + "durability": null, + "weight": "1.8", + "attack_speed": "5", + "lendable": "true", + "grand_exchange_price": "18938", + "attack_audios": "2500,2500,2517,2500", + "name": "Rune longsword", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6897", + "bonuses": "38,47,-2,0,0,0,3,2,0,0,0,49,0,0,0" + }, + { + "bankable": "false", + "examine": "A green cylinder", + "durability": null, + "name": "Cylinder", + "archery_ticket_price": "0", + "id": "6898" + }, + { + "bankable": "false", + "examine": "A yellow cube", + "durability": null, + "name": "Cube", + "archery_ticket_price": "0", + "id": "6899" + }, + { + "bankable": "false", + "examine": "A blue icosahedron.", + "durability": null, + "name": "Icosahedron", + "archery_ticket_price": "0", + "id": "6900" + }, + { + "bankable": "false", + "examine": "A red pentamid.", + "durability": null, + "name": "Pentamid", + "archery_ticket_price": "0", + "id": "6901" + }, + { + "bankable": "false", + "examine": "This looks valuable.", + "durability": null, + "name": "Orb", + "archery_ticket_price": "0", + "id": "6902" + }, + { + "bankable": "false", + "examine": "This looks valuable.", + "durability": null, + "name": "Dragonstone", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "6903" + }, + { + "examine": "Various animals' bones.", + "durability": null, + "name": "Animals' bones", + "archery_ticket_price": "0", + "id": "6904" + }, + { + "examine": "Various animals' bones.", + "durability": null, + "name": "Animals' bones", + "archery_ticket_price": "0", + "id": "6905" + }, + { + "examine": "Various animals' bones.", + "durability": null, + "name": "Animals' bones", + "archery_ticket_price": "0", + "id": "6906" + }, + { + "examine": "Various animals' bones.", + "durability": null, + "name": "Animals' bones", + "archery_ticket_price": "0", + "id": "6907" + }, + { + "requirements": "{6,45}", + "shop_price": "303030030", + "ge_buy_limit": "10", + "turn90cw_anim": "821", + "examine": "A beginner level wand", + "walk_anim": "1146", + "durability": null, + "weight": "0.2", + "turn90ccw_anim": "822", + "weapon_interface": "1", + "turn180_anim": "820", + "render_anim": "1426", + "equipment_slot": "3", + "grand_exchange_price": "11500", + "stand_anim": "809", + "name": "Beginner wand", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "6908", + "stand_turn_anim": "823", + "bonuses": "0,0,0,5,0,0,0,0,5,0,0,0,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "11500", + "durability": null, + "name": "Beginner wand", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6909" + }, + { + "requirements": "{6,50}", + "ge_buy_limit": "10", + "shop_price": "606060060", + "turn90cw_anim": "821", + "examine": "An apprentice level wand.", + "walk_anim": "1146", + "durability": null, + "turn90ccw_anim": "822", + "weapon_interface": "1", + "turn180_anim": "820", + "defence_anim": "420", + "render_anim": "1426", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "grand_exchange_price": "82000", + "stand_anim": "809", + "tradeable": "true", + "name": "Apprentice wand", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "6910", + "stand_turn_anim": "823", + "bonuses": "0,0,0,10,0,0,0,0,10,0,0,0,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "82000", + "durability": null, + "name": "Apprentice wand", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6911" + }, + { + "requirements": "{6,55}", + "ge_buy_limit": "10", + "turn90cw_anim": "821", + "examine": "A teacher level wand.", + "walk_anim": "1146", + "durability": null, + "turn90ccw_anim": "822", + "weapon_interface": "1", + "turn180_anim": "820", + "render_anim": "1426", + "equipment_slot": "3", + "grand_exchange_price": "944100", + "stand_anim": "809", + "name": "Teacher wand", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "6912", + "stand_turn_anim": "823", + "bonuses": "0,0,0,15,0,0,0,0,15,0,0,0,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "944100", + "durability": null, + "name": "Teacher wand", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6913" + }, + { + "requirements": "{6,60}", + "ge_buy_limit": "10", + "turn90cw_anim": "821", + "examine": "A master level wand.", + "walk_anim": "1146", + "durability": null, + "weight": "0.1", + "turn90ccw_anim": "822", + "weapon_interface": "1", + "turn180_anim": "820", + "defence_anim": "420", + "render_anim": "1426", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "grand_exchange_price": "1700000", + "stand_anim": "8980", + "tradeable": "true", + "name": "Master wand", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "6914", + "stand_turn_anim": "823", + "bonuses": "0,0,0,20,0,0,0,0,20,0,0,0,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "1700000", + "durability": null, + "name": "Master wand", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6915" + }, + { + "requirements": "{1,25}-{6,50}", + "ge_buy_limit": "10", + "examine": "Mystical robes.", + "durability": null, + "weight": "2.2", + "absorb": "3,1,0", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "3300000", + "name": "Infinity top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6916", + "bonuses": "0,0,0,22,0,0,0,0,22,0,20,0,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "3300000", + "durability": null, + "name": "Infinity top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6917" + }, + { + "requirements": "{1,25}-{6,50}", + "ge_buy_limit": "10", + "examine": "A mystic hat.", + "durability": null, + "weight": "0.4", + "absorb": "1,0,0", + "equipment_slot": "0", + "grand_exchange_price": "1800000", + "name": "Infinity hat", + "tradeable": "true", + "archery_ticket_price": "0", + "hat": true, + "id": "6918", + "bonuses": "0,0,0,6,0,0,0,0,6,0,7,0,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "1800000", + "durability": null, + "name": "Infinity hat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6919" + }, + { + "requirements": "{1,25}-{6,50}", + "ge_buy_limit": "10", + "examine": "Mystical boots.", + "durability": null, + "destroy": "true", + "weight": "0.4", + "equipment_slot": "10", + "grand_exchange_price": "1200000", + "name": "Infinity boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6920", + "bonuses": "0,0,0,5,0,0,0,0,5,0,5,0,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "1200000", + "durability": null, + "name": "Infinity boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6921" + }, + { + "requirements": "{1,25}-{6,50}", + "ge_buy_limit": "10", + "examine": "Mystical gloves.", + "grand_exchange_price": "1900000", + "durability": null, + "name": "Infinity gloves", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "6922", + "bonuses": "0,0,0,5,0,0,0,0,5,0,0,0,0,0,0", + "equipment_slot": "9" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "1900000", + "durability": null, + "name": "Infinity gloves", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6923" + }, + { + "requirements": "{1,25}-{6,50}", + "ge_buy_limit": "10", + "examine": "Mystical robes.", + "durability": null, + "weight": "1.8", + "absorb": "2,1,0", + "equipment_slot": "7", + "grand_exchange_price": "2500000", + "name": "Infinity bottoms", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6924", + "bonuses": "0,0,0,17,0,0,0,0,17,0,17,0,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "2500000", + "durability": null, + "name": "Infinity bottoms", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6925" + }, + { + "examine": "A tablet containing a magic spell.", + "grand_exchange_price": "983", + "durability": null, + "name": "Bones to peaches", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6926" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A severed hand covered with sand.", + "durability": null, + "name": "Sandy hand", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6945" + }, + { + "destroy_message": "Speak to the Guard Captain in Yanille to get another beer soaked hand.", + "examine": "A severed hand dripping with beer.", + "durability": null, + "name": "Beer-soaked hand", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6946" + }, + { + "destroy_message": "Speak to Bert to replace this Rota.", + "examine": "A copy of a work rota.", + "durability": null, + "name": "Bert's rota", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6947" + }, + { + "destroy_message": "Search Sandy's office in Brimhaven for another Rota.", + "examine": "An original work rota.", + "durability": null, + "name": "Sandy's rota", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6948" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Maybe I should read this...", + "durability": null, + "name": "A magic scroll", + "archery_ticket_price": "0", + "id": "6949" + }, + { + "destroy_message": "Speak to Zavistic Rarve to replace your magical orb.", + "examine": "An ordinary looking scrying orb.", + "durability": null, + "name": "Magical orb", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6950" + }, + { + "destroy_message": "Speak to Zavistic Rarve to replace your magical orb.", + "examine": "This magical scrying orb pulsates as it stores information.", + "durability": null, + "name": "Magical orb (a)", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6951" + }, + { + "destroy_message": "Speak to Betty in Port Sarim to get another bottle of truth serum.", + "examine": "Fluid sloshes innocently in this vial.", + "durability": null, + "name": "Truth serum", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6952" + }, + { + "destroy_message": "Speak to Betty in Port Sarim to get another bottle.", + "examine": "A bottle of water.", + "durability": null, + "name": "Bottled water", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6953" + }, + { + "destroy_message": "Speak to Betty in Port Sarim to get another bottle to make some more red berry juice.", + "examine": "Redberry juice sloshes around in this vial, waiting for white berries to be added.", + "durability": null, + "name": "Redberry juice", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6954" + }, + { + "destroy_message": "Speak to Betty in Port Sarim to make more pink dye.", + "shop_price": "20", + "examine": "A vial of pink dye.", + "durability": null, + "name": "Pink dye", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6955" + }, + { + "destroy_message": "Speak to Betty in Port Sarim to get another bottle to make the lens again.", + "examine": "This lens has a pinkish tinge to it.", + "durability": null, + "name": "Rose-tinted lens", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6956", + "equipment_slot": "3" + }, + { + "destroy_message": "Speak to Mazion near the sandpit on Entrana to find the Wizard Head again.", + "examine": "A decapitated, sand-covered head.", + "durability": null, + "name": "Wizard's head", + "tradeable": "false", + "destroy": "true", + "weight": "3", + "archery_ticket_price": "0", + "id": "6957" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A handful of sand from Sandy's pocket.", + "durability": null, + "name": "Sand", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6958" + }, + { + "shop_price": "20", + "ge_buy_limit": "100", + "examine": "Use pink dye on a cape and this is what you get!", + "durability": null, + "destroy": "true", + "weight": "0.4", + "equipment_slot": "1", + "grand_exchange_price": "919", + "name": "Cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6959", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "919", + "durability": null, + "name": "Cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6960" + }, + { + "examine": "A freshly baked baguette.", + "durability": null, + "name": "Baguette", + "archery_ticket_price": "0", + "id": "6961" + }, + { + "ge_buy_limit": "1000", + "examine": "A freshly made triangle sandwich.", + "grand_exchange_price": "110", + "durability": null, + "name": "Triangle sandwich", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6962" + }, + { + "examine": "A freshly made roll.", + "durability": null, + "name": "Roll", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "6963" + }, + { + "bankable": "false", + "examine": "Lovely money!", + "durability": null, + "name": "Coins", + "archery_ticket_price": "0", + "id": "6964" + }, + { + "examine": "A freshly made square sandwich.", + "durability": null, + "name": "Square sandwich", + "archery_ticket_price": "0", + "id": "6965" + }, + { + "lendable": "true", + "examine": "Makes the wearer pretty intimidating.", + "grand_exchange_price": "61200", + "durability": null, + "name": "Dragon med helm", + "tradeable": "true", + "weight": "1.3", + "archery_ticket_price": "0", + "id": "6967", + "absorb": "2,0,4", + "bonuses": "0,0,0,-3,-1,33,35,32,-1,34,10,0,0,0,0" + }, + { + "durability": null, + "name": "Triangle sandwich", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6968" + }, + { + "examine": "I'd better be careful eating this.", + "grand_exchange_price": "694", + "durability": null, + "name": "Shark", + "tradeable": "true", + "weight": "0.6", + "archery_ticket_price": "0", + "id": "6969" + }, + { + "examine": "It's a solid gold pyramid!", + "durability": null, + "name": "Pyramid top", + "weight": "11", + "archery_ticket_price": "0", + "id": "6970" + }, + { + "ge_buy_limit": "100", + "examine": "A large chunk of sandstone.", + "grand_exchange_price": "4", + "durability": null, + "name": "Sandstone (1kg)", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "6971" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "4", + "durability": null, + "name": "Sandstone (1kg)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6972" + }, + { + "ge_buy_limit": "100", + "examine": "A large chunk of sandstone.", + "grand_exchange_price": "27", + "durability": null, + "name": "Sandstone (2kg)", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "6973" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "27", + "durability": null, + "name": "Sandstone (2kg)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6974" + }, + { + "ge_buy_limit": "100", + "examine": "A large chunk of sandstone.", + "grand_exchange_price": "30", + "durability": null, + "name": "Sandstone (5kg)", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "6975" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "30", + "durability": null, + "name": "Sandstone (5kg)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6976" + }, + { + "ge_buy_limit": "100", + "examine": "A large chunk of sandstone.", + "grand_exchange_price": "120", + "durability": null, + "name": "Sandstone (10kg)", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "6977" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "120", + "durability": null, + "name": "Sandstone (10kg)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6978" + }, + { + "ge_buy_limit": "10000", + "examine": "See article", + "grand_exchange_price": "304", + "durability": null, + "name": "Granite (500g)", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "6979" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "304", + "durability": null, + "name": "Granite (500g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6980" + }, + { + "ge_buy_limit": "10000", + "examine": "See article", + "grand_exchange_price": "845", + "durability": null, + "name": "Granite (2kg)", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "6981" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "845", + "durability": null, + "name": "Granite (2kg)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6982" + }, + { + "ge_buy_limit": "10000", + "examine": "See article", + "grand_exchange_price": "2153", + "durability": null, + "name": "Granite (5kg)", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "6983", + "equipment_slot": "5" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "2153", + "durability": null, + "name": "Granite (5kg)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "6984" + }, + { + "destroy_message": "You can make another 20 kg block by giving enough stone to Lazim.", + "examine": "A huge twenty-kilo block of sandstone.", + "durability": null, + "name": "Sandstone (20kg)", + "destroy": "true", + "weight": "20", + "archery_ticket_price": "0", + "id": "6985" + }, + { + "destroy_message": "You can make another 32 kg sandstone block by giving enough stone to Lazim.", + "examine": "A huge thirty-two-kilo block of sandstone.", + "durability": null, + "name": "Sandstone (32kg)", + "destroy": "true", + "weight": "32", + "archery_ticket_price": "0", + "id": "6986" + }, + { + "destroy_message": "You can make another statue body by giving Lazim 20 kg of stone and then crafting it.", + "examine": "The body of a sandstone statue.", + "durability": null, + "name": "Sandstone body", + "destroy": "true", + "archery_ticket_price": "0", + "id": "6987" + }, + { + "destroy_message": "You can make another statue base by giving Lazim 32 kg of stone and then crafting it.", + "examine": "The base and legs of a sandstone statue.", + "durability": null, + "name": "Sandstone base", + "destroy": "true", + "weight": "32", + "archery_ticket_price": "0", + "id": "6988" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A metal sigil in the shape of a Z.", + "durability": null, + "name": "Z sigil", + "archery_ticket_price": "0", + "id": "6993" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A metal sigil in the shape of an M.", + "durability": null, + "name": "M sigil", + "archery_ticket_price": "0", + "id": "6994" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A metal sigil in the shape of an R.", + "durability": null, + "name": "R sigil", + "archery_ticket_price": "0", + "id": "6995" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A metal sigil in the shape of a K.", + "durability": null, + "name": "K sigil", + "archery_ticket_price": "0", + "id": "6996" + }, + { + "destroy_message": "You can get the statue's left arm back from Lazim.", + "examine": "The left arm of a large stone statue.", + "durability": null, + "name": "Stone left arm", + "tradeable": "false", + "destroy": "true", + "weight": "9", + "archery_ticket_price": "0", + "id": "6997" + }, + { + "destroy_message": "You can get the statue's right arm back from Lazim.", + "examine": "The right arm of a large stone statue.", + "durability": null, + "name": "Stone right arm", + "tradeable": "false", + "destroy": "true", + "weight": "9", + "archery_ticket_price": "0", + "id": "6998" + }, + { + "destroy_message": "You can get the statue's left leg back from Lazim.", + "examine": "The left leg of a large stone statue.", + "durability": null, + "name": "Stone left leg", + "tradeable": "false", + "destroy": "true", + "weight": "9", + "archery_ticket_price": "0", + "id": "6999" + }, + { + "destroy_message": "You can get the statue's right leg back from Lazim.", + "examine": "The right leg of a large stone statue.", + "durability": null, + "name": "Stone right leg", + "tradeable": "false", + "destroy": "true", + "weight": "9", + "archery_ticket_price": "0", + "id": "7000" + }, + { + "destroy_message": "You can make another positive mould by using soft clay on the pedestal in Enakhra's temple.", + "examine": "A positive clay mould of a camel's head.", + "durability": null, + "name": "Camel mould (p)", + "tradeable": "false", + "destroy": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "7001" + }, + { + "remove_head": "true", + "examine": "Blend in in the desert.", + "durability": null, + "name": "Camel mask", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "7003", + "equipment_slot": "0" + }, + { + "shop_price": "14", + "examine": "Good for detailed crafting.", + "grand_exchange_price": "33", + "durability": null, + "name": "Chisel", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "7004", + "equipment_slot": "3" + }, + { + "requirements": "{18,33}-{11,33}", + "shop_price": "130", + "ge_buy_limit": "100", + "examine": "A lantern to aid attacking Harpie bugs.", + "grand_exchange_price": "466", + "durability": null, + "name": "Unlit bug lantern", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "7051", + "equipment_slot": "5" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "466", + "durability": null, + "name": "Unlit bug lantern", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7052" + }, + { + "requirements": "{18,33}", + "shop_price": "130", + "examine": "A lantern to aid attacking Harpie bugs.", + "durability": null, + "name": "Lit bug lantern", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "7053", + "equipment_slot": "5" + }, + { + "ge_buy_limit": "10000", + "examine": "A baked potato with chilli con carne", + "grand_exchange_price": "415", + "durability": null, + "name": "Chilli potato", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "7054" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "415", + "durability": null, + "name": "Chilli potato", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7055" + }, + { + "ge_buy_limit": "10000", + "examine": "A baked potato with egg and tomato.", + "grand_exchange_price": "441", + "durability": null, + "name": "Egg potato", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "7056" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "441", + "durability": null, + "name": "Egg potato", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7057" + }, + { + "ge_buy_limit": "10000", + "examine": "A baked potato with mushroom and onions.", + "grand_exchange_price": "1165", + "durability": null, + "name": "Mushroom potato", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "7058" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "1165", + "durability": null, + "name": "Mushroom potato", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7059" + }, + { + "ge_buy_limit": "10000", + "examine": "A baked potato with tuna and sweetcorn.", + "grand_exchange_price": "2134", + "durability": null, + "name": "Tuna potato", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "7060" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "2134", + "durability": null, + "name": "Tuna potato", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7061" + }, + { + "ge_buy_limit": "1000", + "examine": "A bowl of meat in chilli-con-carne sauce.", + "grand_exchange_price": "215", + "durability": null, + "name": "Chilli con carne", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "7062" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "215", + "durability": null, + "name": "Chilli con carne", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7063" + }, + { + "ge_buy_limit": "1000", + "examine": "A bowl of scrambled eggs and tomato", + "grand_exchange_price": "126", + "durability": null, + "name": "Egg and tomato", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "7064" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "126", + "durability": null, + "name": "Egg and tomato", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7065" + }, + { + "ge_buy_limit": "1000", + "examine": "A bowl of fried mushroom and onions.", + "grand_exchange_price": "368", + "durability": null, + "name": "Mushroom & onion", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "7066" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "368", + "durability": null, + "name": "Mushroom & onion", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7067" + }, + { + "ge_buy_limit": "10000", + "examine": "A bowl of cooked tuna and sweetcorn.", + "grand_exchange_price": "514", + "durability": null, + "name": "Tuna and corn", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "7068" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "514", + "durability": null, + "name": "Tuna and corn", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7069" + }, + { + "ge_buy_limit": "1000", + "examine": "A bowl of finely minced meat.", + "grand_exchange_price": "22", + "durability": null, + "name": "Minced meat", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "7070" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "22", + "durability": null, + "name": "Minced meat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7071" + }, + { + "ge_buy_limit": "1000", + "examine": "A bowl of spicy sauce.", + "grand_exchange_price": "70", + "durability": null, + "name": "Spicy sauce", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "7072" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "70", + "durability": null, + "name": "Spicy sauce", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7073" + }, + { + "ge_buy_limit": "1000", + "examine": "A bowl of chopped garlic.", + "grand_exchange_price": "39", + "durability": null, + "name": "Chopped garlic", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7074" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "39", + "durability": null, + "name": "Chopped garlic", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7075" + }, + { + "ge_buy_limit": "1000", + "examine": "A bowl of uncooked egg.", + "grand_exchange_price": "34", + "durability": null, + "name": "Uncooked egg", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "7076" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "34", + "durability": null, + "name": "Uncooked egg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7077" + }, + { + "ge_buy_limit": "1000", + "examine": "A bowl of scrambled egg.", + "grand_exchange_price": "24", + "durability": null, + "name": "Scrambled egg", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "7078" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "24", + "durability": null, + "name": "Scrambled egg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7079" + }, + { + "ge_buy_limit": "1000", + "examine": "A bowl of sliced Bittercap mushrooms.", + "grand_exchange_price": "149", + "durability": null, + "name": "Sliced mushrooms", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "7080" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "149", + "durability": null, + "name": "Sliced mushrooms", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7081" + }, + { + "ge_buy_limit": "1000", + "examine": "A bowl of fried Bittercap mushrooms.", + "grand_exchange_price": "189", + "durability": null, + "name": "Fried mushrooms", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "7082" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "189", + "durability": null, + "name": "Fried mushrooms", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7083" + }, + { + "ge_buy_limit": "1000", + "examine": "A bowl of sliced, fried onions.", + "grand_exchange_price": "40", + "durability": null, + "name": "Fried onions", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "7084" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "40", + "durability": null, + "name": "Fried onions", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7085" + }, + { + "ge_buy_limit": "10000", + "examine": "A bowl of finely chopped tuna.", + "grand_exchange_price": "233", + "durability": null, + "name": "Chopped tuna", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "7086" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "233", + "durability": null, + "name": "Chopped tuna", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7087" + }, + { + "ge_buy_limit": "10000", + "examine": "Raw sweetcorn.", + "grand_exchange_price": "110", + "durability": null, + "name": "Sweetcorn", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7088" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "110", + "durability": null, + "name": "Sweetcorn", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7089" + }, + { + "durability": null, + "name": "Burnt egg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7091" + }, + { + "durability": null, + "name": "Burnt onion", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7093" + }, + { + "durability": null, + "name": "Burnt mushroom", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7095" + }, + { + "examine": "Best keep this away from naked flames.", + "durability": null, + "name": "Gunpowder", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "7108" + }, + { + "examine": "A fuse.", + "durability": null, + "name": "Fuse", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "7109" + }, + { + "shop_price": "300", + "ge_buy_limit": "100", + "grand_exchange_price": "48", + "examine": "A seaworthy grey shirt.", + "durability": null, + "name": "Stripy pirate shirt", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "7110", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "48", + "durability": null, + "name": "Stripy pirate shirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7111" + }, + { + "remove_head": "true", + "ge_buy_limit": "100", + "examine": "Essential pirate wear.", + "grand_exchange_price": "714", + "durability": null, + "name": "Pirate bandana", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "7112", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "714", + "durability": null, + "name": "Pirate bandana", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7113" + }, + { + "shop_price": "350", + "ge_buy_limit": "100", + "examine": "Not for land lubbers.", + "grand_exchange_price": "2530", + "durability": null, + "name": "Pirate boots", + "tradeable": "true", + "weight": "4", + "archery_ticket_price": "0", + "id": "7114", + "equipment_slot": "10" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2530", + "durability": null, + "name": "Pirate boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7115" + }, + { + "shop_price": "350", + "ge_buy_limit": "100", + "grand_exchange_price": "77", + "examine": "Well, okay, they're beige, but they're part of the white pirate clothing set, so...", + "durability": null, + "name": "Pirate leggings", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "7116", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "77", + "durability": null, + "name": "Pirate leggings", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7117" + }, + { + "examine": "A cannister holding shrapnel.", + "durability": null, + "name": "Canister", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "7118" + }, + { + "examine": "For cleaning and packing the cannon.", + "durability": null, + "name": "Ramrod", + "tradeable": "false", + "destroy": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "7120" + }, + { + "examine": "A plank of wood to repair the hull with.", + "durability": null, + "name": "Repair plank", + "archery_ticket_price": "0", + "id": "7121" + }, + { + "shop_price": "300", + "ge_buy_limit": "100", + "grand_exchange_price": "904", + "examine": "A sea worthy shirt.", + "durability": null, + "name": "Stripy pirate shirt", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "7122", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "904", + "durability": null, + "name": "Stripy pirate shirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7123" + }, + { + "remove_head": "true", + "ge_buy_limit": "100", + "examine": "Essential pirate wear.", + "grand_exchange_price": "340", + "durability": null, + "name": "Pirate bandana", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "7124", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "340", + "durability": null, + "name": "Pirate bandana", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7125" + }, + { + "shop_price": "350", + "ge_buy_limit": "100", + "grand_exchange_price": "187", + "examine": "A sea worthy pair of trousers.", + "durability": null, + "name": "Pirate leggings", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "7126", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "187", + "durability": null, + "name": "Pirate leggings", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7127" + }, + { + "shop_price": "300", + "ge_buy_limit": "100", + "grand_exchange_price": "744", + "examine": "A sea worthy shirt.", + "durability": null, + "name": "Stripy pirate shirt", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "7128", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "744", + "durability": null, + "name": "Stripy pirate shirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7129" + }, + { + "remove_head": "true", + "ge_buy_limit": "100", + "examine": "Essential pirate wear.", + "grand_exchange_price": "154", + "durability": null, + "name": "Pirate bandana", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "7130", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "154", + "durability": null, + "name": "Pirate bandana", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7131" + }, + { + "shop_price": "350", + "ge_buy_limit": "100", + "grand_exchange_price": "253", + "examine": "A sea worthy pair of trousers.", + "durability": null, + "name": "Pirate leggings", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "7132", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "253", + "durability": null, + "name": "Pirate leggings", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7133" + }, + { + "shop_price": "300", + "ge_buy_limit": "100", + "grand_exchange_price": "421", + "examine": "A sea worthy shirt.", + "durability": null, + "name": "Stripy pirate shirt", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "7134", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "421", + "durability": null, + "name": "Stripy pirate shirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7135" + }, + { + "remove_head": "true", + "ge_buy_limit": "100", + "examine": "Essential pirate wear.", + "grand_exchange_price": "469", + "durability": null, + "name": "Pirate bandana", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "7136", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "469", + "durability": null, + "name": "Pirate bandana", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7137" + }, + { + "shop_price": "350", + "ge_buy_limit": "100", + "grand_exchange_price": "83", + "examine": "A sea worthy pair of trousers.", + "durability": null, + "name": "Pirate leggings", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "7138", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "83", + "durability": null, + "name": "Pirate leggings", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7139" + }, + { + "shop_price": "2560", + "examine": "Feels quite lucky.", + "durability": null, + "weight": "1.8", + "attack_speed": "4", + "weapon_interface": "6", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "attack_audios": "2500,2500,2517,2500", + "name": "Lucky cutlass", + "archery_ticket_price": "0", + "id": "7140", + "bonuses": "5,20,0,-5,0,6,6,6,0,0,0,25,0,0,0" + }, + { + "shop_price": "1040", + "examine": "I hope he doesn't want it back.", + "durability": null, + "name": "Harry's cutlass", + "weight": "1", + "archery_ticket_price": "0", + "attack_speed": "4", + "weapon_interface": "6", + "id": "7141", + "bonuses": "3,14,0,-5,0,4,4,4,0,0,0,22,0,0,0", + "equipment_slot": "3" + }, + { + "shop_price": "25600", + "examine": "The very butcher of a silk button.", + "durability": null, + "name": "Rapier", + "weight": "1", + "archery_ticket_price": "0", + "attack_speed": "4", + "weapon_interface": "5", + "id": "7142", + "bonuses": "45,7,-2,0,0,0,1,0,0,0,0,44,0,0,0", + "render_anim": "2622", + "equipment_slot": "3" + }, + { + "examine": "Looks valuable.", + "durability": null, + "name": "Plunder", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7143" + }, + { + "examine": "By Cap'n Hook-Hand Morrisane.", + "durability": null, + "name": "Book o' piracy", + "archery_ticket_price": "0", + "id": "7144" + }, + { + "examine": "A working cannon barrel.", + "durability": null, + "name": "Cannon barrel", + "weight": "32", + "archery_ticket_price": "0", + "id": "7145" + }, + { + "examine": "Not likely to work again.", + "durability": null, + "name": "Broken cannon", + "weight": "32", + "archery_ticket_price": "0", + "id": "7146" + }, + { + "examine": "A plank of wood to repair the hull with.", + "durability": null, + "name": "Repair plank", + "archery_ticket_price": "0", + "id": "7148" + }, + { + "examine": "A cannister holding shrapnel.", + "durability": null, + "name": "Canister", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "7149" + }, + { + "examine": "Useful for pinning up paintings.", + "durability": null, + "name": "Tacks", + "archery_ticket_price": "0", + "id": "7150" + }, + { + "shop_price": "18", + "examine": "A coil of rope.", + "grand_exchange_price": "101", + "durability": null, + "name": "Rope", + "tradeable": "true", + "weight": "1.3", + "archery_ticket_price": "0", + "id": "7155" + }, + { + "shop_price": "1", + "examine": "Useful for lighting a fire.", + "grand_exchange_price": "121", + "durability": null, + "name": "Tinderbox", + "tradeable": "true", + "weight": "0.05", + "archery_ticket_price": "0", + "id": "7156" + }, + { + "shop_price": "30", + "examine": "I think it is eating through the bottle.", + "durability": null, + "name": "Braindeath 'rum", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7157" + }, + { + "ge_buy_limit": "10", + "turn90cw_anim": "7044", + "examine": "A two-handed dragon sword.", + "walk_anim": "7046", + "has_special": "true", + "rare_item": "true", + "turn90ccw_anim": "7043", + "attack_speed": "7", + "two_handed": "true", + "turn180_anim": "7045", + "defence_anim": "7050", + "equipment_slot": "3", + "attack_anims": "7041,7041,7048,7049", + "grand_exchange_price": "1000000", + "stand_anim": "7047", + "tradeable": "true", + "run_anim": "7039", + "archery_ticket_price": "0", + "id": "7158", + "stand_turn_anim": "7040", + "bonuses": "-4,92,80,-4,0,0,0,0,0,-1,0,93,0,0,0", + "requirements": "{0,60}", + "durability": null, + "weight": "3", + "weapon_interface": "7", + "equip_audio": "2248", + "render_anim": "124", + "lendable": "true", + "attack_audios": "2503,0,2504,0", + "name": "Dragon 2h sword" + }, + { + "requirements": "{18,37}", + "shop_price": "200", + "ge_buy_limit": "100", + "examine": "They're heavily insulated wellies.", + "durability": null, + "weight": "1.3", + "equipment_slot": "10", + "grand_exchange_price": "269", + "name": "Insulated boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7159", + "bonuses": "0,0,0,0,0,1,1,0,0,1,0,0,0,0,0" + }, + { + "examine": "Before being attacked: A ball of Electrical energy.", + "durability": null, + "name": "Killerwatt", + "archery_ticket_price": "0", + "attack_speed": "2", + "id": "7160" + }, + { + "durability": null, + "name": "Insulated boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7161" + }, + { + "shop_price": "5", + "ge_buy_limit": "100", + "examine": "Lots of pie recipes for me to try.", + "grand_exchange_price": "62", + "durability": null, + "name": "Pie recipe book", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7162" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "62", + "durability": null, + "name": "Pie recipe book", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7163" + }, + { + "shop_price": "54", + "ge_buy_limit": "1000", + "examine": "Still needs two more ingredients.", + "grand_exchange_price": "77", + "durability": null, + "name": "Part mud pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7164" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "77", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Part mud pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7165" + }, + { + "shop_price": "54", + "ge_buy_limit": "1000", + "examine": "Still needs one more ingredient.", + "grand_exchange_price": "284", + "durability": null, + "name": "Part mud pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7166" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "284", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Part mud pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7167" + }, + { + "ge_buy_limit": "1000", + "examine": "Needs to be baked before I can use it.", + "grand_exchange_price": "1625", + "durability": null, + "name": "Raw mud pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7168" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1625", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Raw mud pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7169" + }, + { + "shop_price": "54", + "ge_buy_limit": "1000", + "turn90cw_anim": "821", + "examine": "All the good of the earth.", + "walk_anim": "819", + "durability": null, + "turn90ccw_anim": "822", + "weapon_interface": "13", + "turn180_anim": "820", + "render_anim": "1", + "equipment_slot": "3", + "grand_exchange_price": "2024", + "stand_anim": "808", + "name": "Mud pie", + "tradeable": "true", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "7170", + "stand_turn_anim": "823" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "2024", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Mud pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7171" + }, + { + "ge_buy_limit": "1000", + "examine": "Still needs two more ingredients.", + "grand_exchange_price": "94", + "durability": null, + "name": "Part garden pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7172" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "94", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Part garden pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7173" + }, + { + "ge_buy_limit": "1000", + "examine": "Still needs one more ingredient.", + "grand_exchange_price": "150", + "durability": null, + "name": "Part garden pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7174" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "150", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Part garden pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7175" + }, + { + "ge_buy_limit": "1000", + "examine": "Needs cooking before I eat it.", + "grand_exchange_price": "1052", + "durability": null, + "name": "Raw garden pie", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "7176" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1052", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Raw garden pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7177" + }, + { + "ge_buy_limit": "1000", + "examine": "What I wouldn't give for a good steak about now...", + "grand_exchange_price": "1667", + "durability": null, + "name": "Garden pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7178" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1667", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Garden pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7179" + }, + { + "ge_buy_limit": "1000", + "examine": "What I wouldn't give for a good steak about now...", + "grand_exchange_price": "442", + "durability": null, + "name": "Half a garden pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7180" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "442", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Half a garden pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7181" + }, + { + "ge_buy_limit": "1000", + "examine": "Still needs two more ingredients.", + "grand_exchange_price": "51", + "durability": null, + "name": "Part fish pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7182" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "51", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Part fish pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7183" + }, + { + "ge_buy_limit": "1000", + "examine": "Still needs one more ingredient.", + "grand_exchange_price": "691", + "durability": null, + "name": "Part fish pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7184" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "691", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Part fish pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7185" + }, + { + "ge_buy_limit": "1000", + "examine": "Raw fish is risky, better cook it.", + "grand_exchange_price": "1198", + "durability": null, + "name": "Raw fish pie", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "7186" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1198", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Raw fish pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7187" + }, + { + "ge_buy_limit": "1000", + "examine": "Bounty of the sea.", + "grand_exchange_price": "121", + "durability": null, + "name": "Fish pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7188" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "121", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Fish pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7189" + }, + { + "ge_buy_limit": "1000", + "examine": "Bounty of the sea.", + "grand_exchange_price": "56", + "durability": null, + "name": "Half a fish pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7190" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "56", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Half a fish pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7191" + }, + { + "ge_buy_limit": "1000", + "examine": "Still needs two more ingredients. ", + "grand_exchange_price": "159", + "durability": null, + "name": "Part admiral pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7192" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "159", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Part admiral pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7193" + }, + { + "ge_buy_limit": "1000", + "examine": "Still needs one more ingredient.", + "grand_exchange_price": "537", + "durability": null, + "name": "Part admiral pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7194" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "537", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Part admiral pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7195" + }, + { + "ge_buy_limit": "1000", + "examine": "This would taste a lot better cooked.", + "grand_exchange_price": "1813", + "durability": null, + "name": "Raw admiral pie", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "7196" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1813", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Raw admiral pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7197" + }, + { + "ge_buy_limit": "1000", + "examine": "Much tastier than a normal fish pie.", + "grand_exchange_price": "532", + "durability": null, + "name": "Admiral pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7198" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "532", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Admiral pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7199" + }, + { + "ge_buy_limit": "1000", + "examine": "Much tastier than a normal fish pie.", + "grand_exchange_price": "184", + "durability": null, + "name": "Half an admiral pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7200" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "184", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Half an admiral pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7201" + }, + { + "ge_buy_limit": "1000", + "examine": "Still needs two more ingredients.", + "grand_exchange_price": "126", + "durability": null, + "name": "Part wild pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7202" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "126", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Part wild pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7203" + }, + { + "ge_buy_limit": "1000", + "examine": "Still needs one more ingredient.", + "grand_exchange_price": "1116", + "durability": null, + "name": "Part wild pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7204" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1116", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Part wild pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7205" + }, + { + "ge_buy_limit": "1000", + "examine": "Good as it looks, I'd better cook it.", + "grand_exchange_price": "3787", + "durability": null, + "name": "Raw wild pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7206" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "3787", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Raw wild pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7207" + }, + { + "ge_buy_limit": "1000", + "examine": "A triumph of man over nature.", + "grand_exchange_price": "1322", + "durability": null, + "name": "Wild pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7208" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1322", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Wild pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7209" + }, + { + "ge_buy_limit": "1000", + "examine": "A triumph of man over nature.", + "grand_exchange_price": "112", + "durability": null, + "name": "Half a wild pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7210" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "112", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Half a wild pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7211" + }, + { + "ge_buy_limit": "1000", + "examine": "Still needs two more ingredients.", + "grand_exchange_price": "495", + "durability": null, + "name": "Part summer pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7212" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "495", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Part summer pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7213" + }, + { + "ge_buy_limit": "1000", + "examine": "Still needs one more ingredient.", + "grand_exchange_price": "980", + "durability": null, + "name": "Part summer pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7214" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "980", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Part summer pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7215" + }, + { + "ge_buy_limit": "1000", + "examine": "Fresh fruit may be good for you, but I should really cook this.", + "grand_exchange_price": "2577", + "durability": null, + "name": "Raw summer pie", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "7216" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "2577", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Raw summer pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7217" + }, + { + "ge_buy_limit": "1000", + "examine": "All the fruits of a very small forest.", + "grand_exchange_price": "1288", + "durability": null, + "name": "Summer pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7218" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1288", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Summer pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7219" + }, + { + "ge_buy_limit": "1000", + "examine": "All the fruits of a very small forest.", + "grand_exchange_price": "430", + "durability": null, + "name": "Half a summer pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7220" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "430", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Half a summer pie", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7221" + }, + { + "shop_price": "19", + "examine": "Mmm this looks tasty.", + "grand_exchange_price": "32", + "durability": null, + "name": "Burnt rabbit", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7222" + }, + { + "shop_price": "25", + "ge_buy_limit": "1000", + "examine": "A delicious looking piece of roast rabbit.", + "grand_exchange_price": "37", + "durability": null, + "name": "Roast rabbit", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7223" + }, + { + "shop_price": "67", + "ge_buy_limit": "1000", + "examine": "Might taste better cooked.", + "grand_exchange_price": "112", + "durability": null, + "name": "Skewered rabbit", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "7224" + }, + { + "shop_price": "81", + "ge_buy_limit": "100", + "examine": "An iron spit.", + "grand_exchange_price": "18", + "durability": null, + "name": "Iron spit", + "tradeable": "true", + "weight": "1.5", + "archery_ticket_price": "0", + "id": "7225" + }, + { + "durability": null, + "name": "Burnt chompy", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7227" + }, + { + "shop_price": "130", + "ge_buy_limit": "1000", + "examine": "It might look delicious to an ogre.Roasted chompy bird.", + "grand_exchange_price": "164", + "durability": null, + "name": "Cooked chompy", + "tradeable": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "7228" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "164", + "durability": null, + "name": "Cooked chompy", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7229" + }, + { + "ge_buy_limit": "1000", + "examine": "A skewered chompy bird.", + "grand_exchange_price": "294", + "durability": null, + "name": "Skewered chompy", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "id": "7230" + }, + { + "durability": null, + "name": "Burnt rabbit", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7231" + }, + { + "durability": null, + "name": "Roast rabbit", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7232" + }, + { + "durability": null, + "name": "Skewered rabbit", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7233" + }, + { + "durability": null, + "name": "Iron spit", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7234" + }, + { + "durability": null, + "name": "Skewered chompy", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7235" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7236" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "7237" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7238" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7239" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "7240" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7241" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "7242" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7243" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "7244" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7245" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "7246" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7247" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7248" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7249" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7250" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7251" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7252" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7253" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7254" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7255" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7256" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "7257" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7258" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "7259" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7260" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "7261" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7262" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "7263" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7264" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "7265" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7266" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "7267" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7268" + }, + { + "examine": "I need to answer this correctly.", + "durability": null, + "name": "Challenge scroll", + "archery_ticket_price": "0", + "id": "7269" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7270" + }, + { + "examine": "I need to answer this correctly.", + "durability": null, + "name": "Challenge scroll", + "archery_ticket_price": "0", + "id": "7271" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7272" + }, + { + "examine": "I need to answer this correctly.", + "durability": null, + "name": "Challenge scroll", + "archery_ticket_price": "0", + "id": "7273" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7274" + }, + { + "examine": "I need to answer this correctly.", + "durability": null, + "name": "Challenge scroll", + "archery_ticket_price": "0", + "id": "7275" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7276" + }, + { + "examine": "I need to answer this correctly.", + "durability": null, + "name": "Challenge scroll", + "archery_ticket_price": "0", + "id": "7277" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7278" + }, + { + "examine": "I need to answer this correctly.", + "durability": null, + "name": "Challenge scroll", + "archery_ticket_price": "0", + "id": "7279" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7280" + }, + { + "examine": "I need to answer this correctly.", + "durability": null, + "name": "Challenge scroll", + "archery_ticket_price": "0", + "id": "7281" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7282" + }, + { + "examine": "I need to answer this correctly.", + "durability": null, + "name": "Challenge scroll", + "archery_ticket_price": "0", + "id": "7283" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7284" + }, + { + "examine": "I need to answer this correctly.", + "durability": null, + "name": "Challenge scroll", + "archery_ticket_price": "0", + "id": "7285" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7286" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "7287" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7288" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "7289" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7290" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "7291" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7292" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "7293" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7294" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "7295" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7296" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7298" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7300" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7301" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7303" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7304" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7305" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "7306" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7307" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "7308" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7309" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "7310" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7311" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "7312" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7313" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "7314" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7315" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "7316" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "archery_ticket_price": "0", + "id": "7317" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "7318" + }, + { + "ge_buy_limit": "2", + "examine": "Stylish!", + "grand_exchange_price": "36600", + "durability": null, + "name": "Red boater", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7319", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "36600", + "durability": null, + "name": "Red boater", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7320" + }, + { + "ge_buy_limit": "2", + "examine": "Stylish!", + "grand_exchange_price": "16600", + "durability": null, + "name": "Orange boater", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7321", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "16600", + "durability": null, + "name": "Orange boater", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7322" + }, + { + "ge_buy_limit": "2", + "examine": "Stylish!", + "grand_exchange_price": "43000", + "durability": null, + "name": "Green boater", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7323", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "43000", + "durability": null, + "name": "Green boater", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7324" + }, + { + "ge_buy_limit": "2", + "examine": "Stylish!", + "grand_exchange_price": "37600", + "durability": null, + "name": "Blue boater", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7325", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "37600", + "durability": null, + "name": "Blue boater", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7326" + }, + { + "ge_buy_limit": "2", + "examine": "Stylish!", + "grand_exchange_price": "41700", + "durability": null, + "name": "Black boater", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7327", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "41700", + "durability": null, + "name": "Black boater", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7328" + }, + { + "ge_buy_limit": "100", + "examine": "Makes firelighting a lot easier.", + "grand_exchange_price": "93", + "durability": null, + "name": "Red firelighter", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7329" + }, + { + "ge_buy_limit": "100", + "examine": "Makes firelighting a lot easier.", + "grand_exchange_price": "94", + "durability": null, + "name": "Green firelighter", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7330" + }, + { + "ge_buy_limit": "100", + "examine": "Makes firelighting a lot easier.", + "grand_exchange_price": "113", + "durability": null, + "name": "Blue firelighter", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7331" + }, + { + "requirements": "{1,10}", + "ge_buy_limit": "2", + "examine": "A black kitesheild with a heraldic design.", + "durability": null, + "weight": "4", + "absorb": "1,0,2", + "equipment_slot": "5", + "grand_exchange_price": "14300", + "name": "Black shield(h1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7332", + "bonuses": "0,0,0,-8,-2,17,19,18,-1,18,10,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "14300", + "durability": null, + "name": "Black shield(h1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7333" + }, + { + "requirements": "{1,30}", + "ge_buy_limit": "2", + "examine": "A shield with a heraldic design.", + "durability": null, + "weight": "5", + "absorb": "3,0,6", + "equipment_slot": "5", + "grand_exchange_price": "16400", + "name": "Adamant shield(h1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7334", + "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,30,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "16400", + "durability": null, + "name": "Adamant shield(h1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7335" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "A rune kiteshield with a heraldic design.", + "durability": null, + "weight": "5.4", + "absorb": "3,0,7", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "34200", + "name": "Rune shield(h1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7336", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "34200", + "durability": null, + "name": "Rune shield(h1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7337" + }, + { + "requirements": "{1,10}", + "ge_buy_limit": "2", + "examine": "A black kiteshield with a heraldic design.", + "durability": null, + "weight": "4", + "absorb": "1,0,2", + "equipment_slot": "5", + "grand_exchange_price": "9797", + "name": "Black shield(h2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7338", + "bonuses": "0,0,0,-8,-2,17,19,18,-1,18,10,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "9797", + "durability": null, + "name": "Black shield(h2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7339" + }, + { + "requirements": "{1,30}", + "ge_buy_limit": "2", + "examine": "A shield with a heraldic design.", + "durability": null, + "weight": "5", + "absorb": "3,0,6", + "equipment_slot": "5", + "grand_exchange_price": "3248", + "name": "Adamant shield(h2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7340", + "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,30,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "3248", + "durability": null, + "name": "Adamant shield(h2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7341" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "A rune kiteshield with a heraldic design.", + "durability": null, + "weight": "5.4", + "absorb": "3,0,7", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "32400", + "name": "Rune shield(h2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7342", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "32400", + "durability": null, + "name": "Rune shield(h2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7343" + }, + { + "requirements": "{1,10}", + "ge_buy_limit": "2", + "examine": "A black shield with a heraldic design.", + "durability": null, + "weight": "4", + "absorb": "1,0,2", + "equipment_slot": "5", + "grand_exchange_price": "7405", + "name": "Black shield(h3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7344", + "bonuses": "0,0,0,-8,-2,17,19,18,-1,18,10,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "7405", + "durability": null, + "name": "Black shield(h3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7345" + }, + { + "requirements": "{1,30}", + "ge_buy_limit": "2", + "examine": "A shield with a heraldic design.", + "durability": null, + "weight": "5", + "absorb": "3,0,6", + "equipment_slot": "5", + "grand_exchange_price": "5271", + "name": "Adamant shield(h3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7346", + "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,30,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "5271", + "durability": null, + "name": "Adamant shield(h3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7347" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "A rune kiteshield with a heraldic design.", + "durability": null, + "weight": "5", + "absorb": "3,0,7", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "32700", + "name": "Rune shield(h3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7348", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "32700", + "durability": null, + "name": "Rune shield(h3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7349" + }, + { + "requirements": "{1,10}", + "ge_buy_limit": "2", + "examine": "A black shield with a heraldic design.", + "durability": null, + "weight": "4", + "absorb": "1,0,2", + "equipment_slot": "5", + "grand_exchange_price": "5572", + "name": "Black shield(h4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7350", + "bonuses": "0,0,0,-8,-2,17,19,18,-1,18,10,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "5572", + "durability": null, + "name": "Black shield(h4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7351" + }, + { + "requirements": "{1,30}", + "ge_buy_limit": "2", + "examine": "A shield with a heraldic design.", + "durability": null, + "weight": "5", + "absorb": "3,0,6", + "equipment_slot": "5", + "grand_exchange_price": "3366", + "name": "Adamant shield(h4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7352", + "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,30,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "3366", + "durability": null, + "name": "Adamant shield(h4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7353" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "A rune kiteshield with a heraldic design.", + "durability": null, + "weight": "5", + "absorb": "3,0,7", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "32500", + "name": "Rune shield(h4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7354", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "32500", + "durability": null, + "name": "Rune shield(h4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7355" + }, + { + "requirements": "{1,10}", + "ge_buy_limit": "2", + "examine": "A black shield with a heraldic design.", + "durability": null, + "weight": "4", + "absorb": "1,0,2", + "equipment_slot": "5", + "grand_exchange_price": "7159", + "name": "Black shield(h5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7356", + "bonuses": "0,0,0,-8,-2,17,19,18,-1,18,10,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "7159", + "durability": null, + "name": "Black shield(h5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7357" + }, + { + "requirements": "{1,30}", + "ge_buy_limit": "2", + "examine": "A shield with a heraldic design.", + "durability": null, + "weight": "5", + "absorb": "3,0,6", + "equipment_slot": "5", + "grand_exchange_price": "6328", + "name": "Adamant shield(h5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7358", + "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,30,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "6328", + "durability": null, + "name": "Adamant shield(h5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7359" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "A rune kiteshield with a heraldic design.", + "durability": null, + "weight": "5", + "absorb": "3,0,7", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "32400", + "name": "Rune shield(h5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7360", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" + }, + { + "requirements": "", + "ge_buy_limit": "2", + "grand_exchange_price": "32400", + "durability": null, + "name": "Rune shield(h5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7361" + }, + { + "requirements": "{1,20}-{4,20}", + "ge_buy_limit": "2", + "examine": "Those studs should provide a bit more protection. Nice trim too!", + "durability": null, + "weight": "5.4", + "absorb": "0,3,1", + "equipment_slot": "4", + "grand_exchange_price": "101600", + "name": "Studded body (g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7362", + "bonuses": "0,0,0,-4,8,18,25,22,8,25,20,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "101600", + "durability": null, + "name": "Studded body (g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7363" + }, + { + "requirements": "{1,20}-{4,20}", + "ge_buy_limit": "2", + "examine": "Those studs should provide a bit more protection. Nice trim too!", + "durability": null, + "weight": "5.4", + "absorb": "0,3,1", + "equipment_slot": "4", + "grand_exchange_price": "27300", + "name": "Studded body (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7364", + "bonuses": "0,0,0,-4,8,18,25,22,8,25,20,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "27300", + "durability": null, + "name": "Studded body (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7365" + }, + { + "requirements": "{4,20}", + "ge_buy_limit": "2", + "examine": "Those studs should provide a bit more protection. Nice trim too!", + "durability": null, + "weight": "4.5", + "absorb": "0,2,1", + "equipment_slot": "7", + "grand_exchange_price": "114600", + "name": "Studded chaps (g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7366", + "bonuses": "0,0,0,-5,6,15,16,17,6,16,5,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "114600", + "durability": null, + "name": "Studded chaps (g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7367" + }, + { + "requirements": "{4,20}", + "ge_buy_limit": "2", + "examine": "Those studs should provide a bit more protection. Nice trim, too!", + "durability": null, + "weight": "4.5", + "absorb": "0,2,1", + "equipment_slot": "7", + "grand_exchange_price": "36800", + "name": "Studded chaps (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7368", + "bonuses": "0,0,0,-5,6,15,16,17,6,16,5,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "36800", + "durability": null, + "name": "Studded chaps (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7369" + }, + { + "requirements": "{1,40}-{4,40}", + "ge_buy_limit": "5000", + "examine": "Made from 100% real dragonhide. With colourful trim!", + "durability": null, + "weight": "6", + "equip_audio": "2241", + "equipment_slot": "4", + "grand_exchange_price": "212400", + "name": "D'hide body(g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7370", + "bonuses": "0,0,0,-15,15,40,32,45,20,40,40,0,0,0,0" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "212400", + "durability": null, + "name": "D'hide body(g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7371" + }, + { + "requirements": "{1,40}-{4,40}", + "ge_buy_limit": "2", + "examine": "Made from 100% real dragonhide. With colourful trim!", + "durability": null, + "weight": "6", + "equip_audio": "2241", + "equipment_slot": "4", + "grand_exchange_price": "38800", + "name": "D'hide body (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7372", + "bonuses": "0,0,0,-15,15,40,32,45,20,40,40,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "38800", + "durability": null, + "name": "D'hide body (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7373" + }, + { + "requirements": "{1,40}-{4,50}", + "ge_buy_limit": "2", + "examine": "Made from 100% real dragonhide, with colourful trim!", + "durability": null, + "weight": "6", + "equip_audio": "2241", + "equipment_slot": "4", + "grand_exchange_price": "6883", + "name": "D'hide body (g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7374", + "bonuses": "0,0,0,-15,20,45,37,50,30,45,45,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "6883", + "durability": null, + "name": "D'hide body (g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7375" + }, + { + "requirements": "{1,40}-{4,50}", + "ge_buy_limit": "2", + "examine": "Made from 100% real dragonhide, with colourful trim!", + "durability": null, + "weight": "6", + "equip_audio": "2241", + "equipment_slot": "4", + "grand_exchange_price": "5268", + "name": "D'hide body (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7376", + "bonuses": "0,0,0,-15,20,45,37,50,30,45,45,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "5268", + "durability": null, + "name": "D'hide body (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7377" + }, + { + "requirements": "{4,40}", + "ge_buy_limit": "2", + "examine": "Made from 100% real dragonhide, with colourful trim!", + "durability": null, + "weight": "5", + "equip_audio": "2241", + "equipment_slot": "7", + "grand_exchange_price": "1300000", + "name": "D'hide chaps (g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7378", + "bonuses": "0,0,0,-10,8,22,16,24,8,22,15,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "1300000", + "durability": null, + "name": "D'hide chaps (g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7379" + }, + { + "requirements": "{4,40}", + "ge_buy_limit": "2", + "examine": "Made from 100% real dragonhide, with colourful trim!", + "durability": null, + "weight": "5", + "equip_audio": "2241", + "equipment_slot": "7", + "grand_exchange_price": "304300", + "name": "D'hide chaps (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7380", + "bonuses": "0,0,0,-10,8,22,16,24,8,22,15,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "304300", + "durability": null, + "name": "D'hide chaps (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7381" + }, + { + "requirements": "{4,50}", + "ge_buy_limit": "2", + "examine": "Made from 100% real dragonhide, with colourful trim!", + "durability": null, + "weight": "5", + "equip_audio": "2241", + "equipment_slot": "7", + "grand_exchange_price": "21300", + "name": "D'hide chaps (g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7382", + "bonuses": "0,0,0,-10,11,25,19,27,14,25,20,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "21300", + "durability": null, + "name": "D'hide chaps (g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7383" + }, + { + "requirements": "{4,50}", + "ge_buy_limit": "2", + "examine": "Made from 100% real dragonhide, with colourful trim!", + "durability": null, + "weight": "5", + "equip_audio": "2241", + "equipment_slot": "7", + "grand_exchange_price": "2554", + "name": "D'hide chaps (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7384", + "bonuses": "0,0,0,-10,11,25,19,27,14,25,20,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "2554", + "durability": null, + "name": "D'hide chaps (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7385" + }, + { + "ge_buy_limit": "2", + "examine": "Leg covering favoured by women and wizards. With a colourful trim!", + "grand_exchange_price": "298900", + "durability": null, + "name": "Blue skirt (g)", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "7386", + "bonuses": "0,0,0,1,0,0,0,0,1,0,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "298900", + "durability": null, + "name": "Blue skirt (g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7387" + }, + { + "ge_buy_limit": "2", + "examine": "Leg covering favoured by women and wizards. With a colourful trim!", + "grand_exchange_price": "126800", + "durability": null, + "name": "Blue skirt (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "7388", + "bonuses": "0,0,0,1,0,0,0,0,1,0,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "126800", + "durability": null, + "name": "Blue skirt (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7389" + }, + { + "remove_sleeves": "true", + "ge_buy_limit": "2", + "examine": "I can practise magic better in this.", + "grand_exchange_price": "1200000", + "durability": null, + "name": "Wizard robe (g)", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "7390", + "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "1200000", + "durability": null, + "name": "Wizard robe (g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7391" + }, + { + "remove_sleeves": "true", + "ge_buy_limit": "2", + "examine": "I can do magic better in this.", + "grand_exchange_price": "244600", + "durability": null, + "name": "Wizard robe (t)", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "7392", + "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "244600", + "durability": null, + "name": "Wizard robe (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7393" + }, + { + "ge_buy_limit": "2", + "examine": "A silly pointed hat with colourful trim.", + "grand_exchange_price": "1400000", + "durability": null, + "name": "Wizard hat (g)", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "hat": "true", + "id": "7394", + "bonuses": "0,0,0,2,0,0,0,0,2,0,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "1400000", + "durability": null, + "name": "Wizard hat (g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7395" + }, + { + "ge_buy_limit": "2", + "examine": "A silly pointed hat, with colourful trim.", + "grand_exchange_price": "352700", + "durability": null, + "name": "Wizard hat (t)", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "hat": "true", + "id": "7396", + "bonuses": "0,0,0,2,0,0,0,0,2,0,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "352700", + "durability": null, + "name": "Wizard hat (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7397" + }, + { + "requirements": "{1,20}-{6,40}", + "ge_buy_limit": "2", + "examine": "Enchanted Wizards robes.", + "durability": null, + "weight": "1.8", + "absorb": "2,1,0", + "equipment_slot": "7", + "grand_exchange_price": "50000", + "name": "Enchanted robe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7398", + "bonuses": "0,0,0,15,0,0,0,0,15,0,15,0,0,0,0" + }, + { + "requirements": "{1,20}-{6,40}", + "ge_buy_limit": "2", + "examine": "Enchanted Wizards robes.", + "durability": null, + "weight": "1", + "absorb": "3,1,0", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "75100", + "name": "Enchanted top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7399", + "bonuses": "0,0,0,20,0,0,0,0,20,0,20,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,20}-{6,40}", + "ge_buy_limit": "2", + "examine": "A three pointed hat of magic.", + "grand_exchange_price": "8845", + "durability": null, + "name": "Enchanted hat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7400", + "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,0,0,0", + "equipment_slot": "0" + }, + { + "durability": null, + "name": "Enchanted robe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7401" + }, + { + "durability": null, + "name": "Enchanted top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7402" + }, + { + "durability": null, + "name": "Enchanted hat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7403" + }, + { + "examine": "A number of chemical covered wooden logs.", + "durability": null, + "name": "Red logs", + "archery_ticket_price": "0", + "id": "7404" + }, + { + "examine": "A number of chemical covered wooden logs.", + "durability": null, + "name": "Green logs", + "weight": "2", + "archery_ticket_price": "0", + "id": "7405" + }, + { + "examine": "A number of chemical covered wooden logs.", + "durability": null, + "name": "Blue logs", + "weight": "2", + "archery_ticket_price": "0", + "id": "7406" + }, + { + "durability": null, + "name": "Dragon 2h sword", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7407" + }, + { + "destroy_message": "I found this in a grave at Draynor Manor.", + "examine": "I shouldn't joke; this is a grave matter.", + "durability": null, + "name": "Draynor skull", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "7408" + }, + { + "shop_price": "40000", + "examine": "The only way to kill a Tanglefoot.", + "durability": null, + "destroy": "true", + "weight": "0.4", + "attack_speed": "5", + "weapon_interface": "5", + "equipment_slot": "3", + "destroy_message": "I'll chat to Malignius Mortifer if I want another pair.", + "name": "Magic secateurs", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "7409", + "bonuses": "7,9,-5,1,0,0,1,0,1,0,0,1,0,0,0" + }, + { + "destroy_message": "I can always find another Tanglefoot if I need more.", + "examine": "Contains the Fairy Queen's magical essence.", + "durability": null, + "name": "Queen's secateurs", + "archery_ticket_price": "0", + "id": "7410", + "equipment_slot": "3" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A list of the Fairy Queen's symptoms.", + "durability": null, + "name": "Symptoms list", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "7411" + }, + { + "examine": "Full: ", + "durability": null, + "name": "Bird's nest", + "archery_ticket_price": "0", + "id": "7413" + }, + { + "durability": null, + "name": "Paddle", + "archery_ticket_price": "0", + "id": "7414", + "weapon_interface": "1", + "equipment_slot": "3" + }, + { + "durability": null, + "name": "Paddle", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7415" + }, + { + "ge_buy_limit": "5000", + "examine": "A mole claw.", + "grand_exchange_price": "11800", + "durability": null, + "name": "Mole claw", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7416" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "11800", + "durability": null, + "name": "Mole claw", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7417" + }, + { + "ge_buy_limit": "5000", + "examine": "The skin of a large mole.", + "grand_exchange_price": "12000", + "durability": null, + "name": "Mole skin", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7418" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "12000", + "durability": null, + "name": "Mole skin", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7419" + }, + { + "examine": "A fun guy. No wait, that's awful. Plus it doesn't even make sense. (As Fungi) A bouncy fungus. (Level 74) A fun guy. No wait, that's awful.. (Level 86)", + "durability": null, + "name": "Mutated zygomite", + "archery_ticket_price": "0", + "id": "7420" + }, + { + "requirements": "{18,57}", + "shop_price": "300", + "turn90cw_anim": "821", + "examine": "Pumps fungicide.", + "walk_anim": "3334", + "durability": null, + "weight": "2", + "turn90ccw_anim": "822", + "turn180_anim": "820", + "render_anim": "618", + "equipment_slot": "3", + "stand_anim": "3332", + "name": "Fungicide spray 10", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "7421", + "stand_turn_anim": "823" + }, + { + "requirements": "{18,57}", + "shop_price": "300", + "turn90cw_anim": "821", + "examine": "Pumps fungicide.", + "walk_anim": "3334", + "durability": null, + "weight": "2", + "turn90ccw_anim": "822", + "turn180_anim": "820", + "render_anim": "618", + "equipment_slot": "3", + "stand_anim": "3332", + "name": "Fungicide spray 9", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "7422", + "stand_turn_anim": "823" + }, + { + "requirements": "{18,57}", + "shop_price": "300", + "turn90cw_anim": "821", + "examine": "Pumps fungicide.", + "walk_anim": "3334", + "durability": null, + "weight": "2", + "turn90ccw_anim": "822", + "turn180_anim": "820", + "render_anim": "618", + "equipment_slot": "3", + "stand_anim": "3332", + "name": "Fungicide spray 8", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "7423", + "stand_turn_anim": "823" + }, + { + "requirements": "{18,57}", + "shop_price": "300", + "turn90cw_anim": "821", + "examine": "Pumps fungicide.", + "walk_anim": "3334", + "durability": null, + "weight": "2", + "turn90ccw_anim": "822", + "turn180_anim": "820", + "render_anim": "618", + "equipment_slot": "3", + "stand_anim": "3332", + "name": "Fungicide spray 7", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "7424", + "stand_turn_anim": "823" + }, + { + "requirements": "{18,57}", + "shop_price": "300", + "turn90cw_anim": "821", + "examine": "Pumps fungicide.", + "walk_anim": "3334", + "durability": null, + "weight": "2", + "turn90ccw_anim": "822", + "turn180_anim": "820", + "render_anim": "618", + "equipment_slot": "3", + "stand_anim": "3332", + "name": "Fungicide spray 6", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "7425", + "stand_turn_anim": "823" + }, + { + "requirements": "{18,57}", + "shop_price": "300", + "turn90cw_anim": "821", + "examine": "Pumps fungicide.", + "walk_anim": "3334", + "durability": null, + "weight": "2", + "turn90ccw_anim": "822", + "turn180_anim": "820", + "render_anim": "618", + "equipment_slot": "3", + "stand_anim": "3332", + "name": "Fungicide spray 5", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "7426", + "stand_turn_anim": "823" + }, + { + "requirements": "{18,57}", + "shop_price": "300", + "turn90cw_anim": "821", + "examine": "Pumps fungicide.", + "walk_anim": "3334", + "durability": null, + "weight": "2", + "turn90ccw_anim": "822", + "turn180_anim": "820", + "render_anim": "618", + "equipment_slot": "3", + "stand_anim": "3332", + "name": "Fungicide spray 4", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "7427", + "stand_turn_anim": "823" + }, + { + "requirements": "{18,57}", + "shop_price": "300", + "turn90cw_anim": "821", + "examine": "Pumps fungicide.", + "walk_anim": "3334", + "durability": null, + "weight": "2", + "turn90ccw_anim": "822", + "turn180_anim": "820", + "render_anim": "618", + "equipment_slot": "3", + "stand_anim": "3332", + "name": "Fungicide spray 3", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "7428", + "stand_turn_anim": "823" + }, + { + "requirements": "{18,57}", + "shop_price": "300", + "turn90cw_anim": "821", + "examine": "Pumps fungicide.", + "walk_anim": "3334", + "durability": null, + "weight": "2", + "turn90ccw_anim": "822", + "turn180_anim": "820", + "render_anim": "618", + "equipment_slot": "3", + "stand_anim": "3332", + "name": "Fungicide spray 2", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "7429", + "stand_turn_anim": "823" + }, + { + "requirements": "{18,57}", + "shop_price": "300", + "turn90cw_anim": "821", + "examine": "Pumps fungicide.", + "walk_anim": "3334", + "durability": null, + "weight": "2", + "turn90ccw_anim": "822", + "turn180_anim": "820", + "render_anim": "618", + "equipment_slot": "3", + "stand_anim": "3332", + "name": "Fungicide spray 1", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "7430", + "stand_turn_anim": "823" + }, + { + "requirements": "{18,57}", + "shop_price": "300", + "turn90cw_anim": "821", + "examine": "Pumps fungicide.", + "walk_anim": "3334", + "durability": null, + "weight": "2", + "turn90ccw_anim": "822", + "turn180_anim": "820", + "render_anim": "618", + "equipment_slot": "3", + "stand_anim": "3332", + "name": "Fungicide spray 0", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "7431", + "stand_turn_anim": "823" + }, + { + "requirements": "{18,57}", + "shop_price": "10", + "examine": "Does exactly what it says on the tin. (Kills Fungi.)", + "durability": null, + "name": "Fungicide", + "archery_ticket_price": "0", + "id": "7432" + }, + { + "shop_price": "35", + "ge_buy_limit": "100", + "examine": "Spoooooon!", + "durability": null, + "weight": "0.4", + "attack_speed": "5", + "weapon_interface": "6", + "equipment_slot": "3", + "grand_exchange_price": "44", + "name": "Wooden spoon", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7433", + "bonuses": "4,5,-2,0,0,0,3,2,0,0,0,7,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "44", + "durability": null, + "name": "Wooden spoon", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7434" + }, + { + "shop_price": "45", + "ge_buy_limit": "100", + "examine": "A large whisk of death.", + "durability": null, + "attack_speed": "4", + "weapon_interface": "5", + "equipment_slot": "3", + "grand_exchange_price": "11", + "name": "Egg whisk", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7435", + "bonuses": "5,3,-4,1,0,0,0,0,1,0,0,4,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "11", + "durability": null, + "name": "Egg whisk", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7436" + }, + { + "requirements": "{0,10}", + "shop_price": "292", + "ge_buy_limit": "100", + "examine": "Use the spork.", + "durability": null, + "weight": "1.8", + "attack_speed": "4", + "weapon_interface": "5", + "equipment_slot": "3", + "grand_exchange_price": "196", + "name": "Spork", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7437", + "bonuses": "11,8,-2,0,0,0,2,1,0,0,0,12,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "196", + "durability": null, + "name": "Spork", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7438" + }, + { + "requirements": "{0,10}", + "ge_buy_limit": "100", + "shop_price": "1728", + "turn90cw_anim": "7044", + "examine": "A large spatula... of doom!", + "walk_anim": "7046", + "durability": null, + "weight": "3.6", + "turn90ccw_anim": "7043", + "attack_speed": "7", + "two_handed": "true", + "weapon_interface": "7", + "turn180_anim": "7045", + "render_anim": "124", + "equipment_slot": "3", + "grand_exchange_price": "953", + "stand_anim": "7047", + "tradeable": "true", + "name": "Spatula", + "run_anim": "7039", + "archery_ticket_price": "0", + "id": "7439", + "stand_turn_anim": "7040", + "bonuses": "-4,27,21,-4,0,0,0,0,0,-1,0,22,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "953", + "durability": null, + "name": "Spatula", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7440" + }, + { + "requirements": "{0,20}", + "shop_price": "1494", + "ge_buy_limit": "100", + "examine": "Looks like it's non-stick too!", + "durability": null, + "weight": "1.5", + "attack_speed": "6", + "weapon_interface": "10", + "equipment_slot": "3", + "grand_exchange_price": "836", + "name": "Frying pan", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7441", + "bonuses": "-4,-4,25,-4,0,0,0,0,0,0,0,20,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "836", + "durability": null, + "name": "Frying pan", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7442" + }, + { + "requirements": "{0,30}", + "shop_price": "2880", + "ge_buy_limit": "100", + "examine": "Generally used for impaling fresh meat.", + "durability": null, + "weight": "2", + "attack_speed": "5", + "weapon_interface": "6", + "equipment_slot": "3", + "grand_exchange_price": "1712", + "name": "Skewer", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7443", + "bonuses": "20,29,-2,0,0,0,3,2,0,0,0,31,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1712", + "durability": null, + "name": "Skewer", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7444" + }, + { + "requirements": "{0,40}", + "shop_price": "12960", + "ge_buy_limit": "100", + "examine": "That's how I roll!", + "durability": null, + "weight": "1.8", + "attack_speed": "5", + "weapon_interface": "10", + "equipment_slot": "3", + "grand_exchange_price": "8445", + "name": "Rolling pin", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7445", + "bonuses": "20,-2,39,0,0,0,0,0,0,0,0,36,4,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "8445", + "durability": null, + "name": "Rolling pin", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7446" + }, + { + "requirements": "{0,40}", + "shop_price": "8000", + "ge_buy_limit": "100", + "examine": "A sharp, dependable knife, for filleting meat.", + "durability": null, + "attack_speed": "4", + "weapon_interface": "5", + "equip_audio": "2244", + "equipment_slot": "3", + "grand_exchange_price": "4686", + "attack_audios": "2704,0,0,0", + "name": "Kitchen knife", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7447", + "bonuses": "25,12,-4,1,0,0,0,0,1,0,0,24,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "4686", + "durability": null, + "name": "Kitchen knife", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7448" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "821", + "examine": "Often used to soften tough meat up.", + "walk_anim": "819", + "turn90ccw_anim": "822", + "attack_speed": "6", + "turn180_anim": "820", + "defence_anim": "1666", + "equipment_slot": "3", + "attack_anims": "2067,2066,2068", + "grand_exchange_price": "24700", + "stand_anim": "808", + "tradeable": "true", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "7449", + "stand_turn_anim": "823", + "bonuses": "-4,-4,53,-4,0,0,0,0,0,0,0,48,0,0,0", + "requirements": "{0,40}", + "shop_price": "41500", + "durability": null, + "weight": "1", + "weapon_interface": "10", + "render_anim": "1", + "name": "Meat tenderiser" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "24700", + "durability": null, + "name": "Meat tenderiser", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7450" + }, + { + "requirements": "{0,40}", + "shop_price": "24040", + "ge_buy_limit": "100", + "examine": "An effective tool for chopping tough meat.", + "durability": null, + "weight": "0.5", + "attack_speed": "4", + "weapon_interface": "6", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "grand_exchange_price": "15000", + "attack_audios": "2500,0,2517,0", + "name": "Cleaver", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7451", + "bonuses": "7,45,-2,0,0,0,1,0,0,0,0,44,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "15000", + "durability": null, + "name": "Cleaver", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7452" + }, + { + "shop_price": "50", + "examine": "A pair of plain gloves.", + "durability": null, + "name": "Gloves", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "7453", + "bonuses": "1,1,1,1,1,1,1,1,1,1,1,1,0,0,0", + "equip_audio": "2236", + "equipment_slot": "9" + }, + { + "shop_price": "100", + "examine": "A pair of bronze-coloured gloves.", + "durability": null, + "name": "Gloves", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "7454", + "bonuses": "2,2,2,1,2,2,2,2,1,2,1,2,0,0,0", + "equip_audio": "2236", + "equipment_slot": "9" + }, + { + "shop_price": "325", + "examine": "A pair of iron-coloured gloves.", + "durability": null, + "name": "Gloves", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "7455", + "bonuses": "3,3,3,2,3,3,3,3,2,3,2,3,0,0,0", + "equip_audio": "2236", + "equipment_slot": "9" + }, + { + "shop_price": "500", + "examine": "A pair of steel-coloured gloves.", + "durability": null, + "name": "Gloves", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "7456", + "bonuses": "4,4,4,2,4,4,4,4,2,4,2,4,0,0,0", + "equip_audio": "2236", + "equipment_slot": "9" + }, + { + "shop_price": "1000", + "examine": "A pair of black-coloured gloves.", + "durability": null, + "name": "Gloves", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "7457", + "bonuses": "5,5,5,3,5,5,5,5,3,5,3,5,0,0,0", + "equip_audio": "2236", + "equipment_slot": "9" + }, + { + "shop_price": "1500", + "examine": "A pair of mithril-coloured gloves.", + "durability": null, + "name": "Gloves", + "archery_ticket_price": "0", + "id": "7458", + "bonuses": "6,6,6,3,6,6,6,6,3,6,3,6,0,0,0", + "equip_audio": "2236", + "equipment_slot": "9" + }, + { + "shop_price": "2500", + "examine": "A pair of adamant-coloured gloves.", + "durability": null, + "name": "Gloves", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "7459", + "bonuses": "7,7,7,4,7,7,7,7,4,7,4,7,0,0,0", + "equip_audio": "2236", + "equipment_slot": "9" + }, + { + "requirements": "{1,13}", + "shop_price": "5000", + "examine": "A pair of rune-coloured gloves.", + "durability": null, + "name": "Gloves", + "archery_ticket_price": "0", + "id": "7460", + "bonuses": "8,8,8,4,8,8,8,8,4,8,4,8,0,0,0", + "equip_audio": "2236", + "equipment_slot": "9" + }, + { + "requirements": "{1,41}", + "shop_price": "100000", + "examine": "A pair of dragon-coloured gloves.", + "durability": null, + "name": "Gloves", + "archery_ticket_price": "0", + "id": "7461", + "bonuses": "9,9,9,5,9,9,9,9,5,9,5,9,0,0,0", + "equip_audio": "2236", + "equipment_slot": "9" + }, + { + "requirements": "{1,41}", + "shop_price": "100000", + "examine": "A pair of Barrows-themed gloves.", + "durability": null, + "name": "Gloves", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "7462", + "bonuses": "12,12,12,6,12,12,12,12,6,12,6,12,0,0,0", + "equip_audio": "2236", + "equipment_slot": "9" + }, + { + "examine": "It's cornflour in a pot.", + "durability": null, + "name": "Cornflour", + "weight": "1", + "archery_ticket_price": "0", + "id": "7463" + }, + { + "examine": "A tatty old book belonging to the Wise Old Man of Draynor Village.", + "durability": null, + "name": "Book on chickens", + "archery_ticket_price": "0", + "id": "7464" + }, + { + "examine": "Surprise, it looks like a vanilla pod.", + "durability": null, + "name": "Vanilla pod", + "archery_ticket_price": "0", + "id": "7465" + }, + { + "examine": "It's cornflour in a pot.", + "durability": null, + "name": "Cornflour", + "weight": "1", + "archery_ticket_price": "0", + "id": "7466" + }, + { + "examine": "It's cornflour in a pot.", + "durability": null, + "name": "Pot of cornflour", + "weight": "1", + "archery_ticket_price": "0", + "id": "7468" + }, + { + "destroy_message": "I'll have to get all the ingredients again.", + "examine": "A mixture of milk, cream and cornflour.", + "durability": null, + "name": "Cornflour mixture", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "7470" + }, + { + "destroy_message": "I'll have to get all the ingredients again.", + "examine": "It's a bucket of milk and cream.", + "durability": null, + "name": "Milky mixture", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "7471" + }, + { + "examine": "Some cinnamon sticks.", + "durability": null, + "name": "Cinnamon", + "archery_ticket_price": "0", + "id": "7472" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A pot of brulee supreme.", + "durability": null, + "name": "Brulee supreme", + "archery_ticket_price": "0", + "id": "7476" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "What came first, the chicken or...", + "durability": null, + "name": "Evil chicken's egg", + "archery_ticket_price": "0", + "id": "7477" + }, + { + "destroy_message": "I got this by killing a Black Dragon. It might be hard to get another one.", + "examine": "It's got a dragon on it.", + "durability": null, + "name": "Dragon token", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "7478" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "It's a meat and potato stew with fancy seasoning.", + "durability": null, + "name": "Spicy stew", + "weight": "1.5", + "archery_ticket_price": "0", + "id": "7479" + }, + { + "examine": "Allows for equal distribution of spice.", + "durability": null, + "name": "Red spice (4)", + "archery_ticket_price": "0", + "id": "7480" + }, + { + "examine": "Allows for equal distribution of spice.", + "durability": null, + "name": "Red spice (3)", + "archery_ticket_price": "0", + "id": "7481" + }, + { + "examine": "Allows for equal distribution of spice.", + "durability": null, + "name": "Red spice (2)", + "archery_ticket_price": "0", + "id": "7482" + }, + { + "examine": "Allows for equal distribution of spice.", + "durability": null, + "name": "Red spice (1)", + "archery_ticket_price": "0", + "id": "7483" + }, + { + "examine": "Allows for equal distribution of spice.", + "durability": null, + "name": "Orange spice (4)", + "archery_ticket_price": "0", + "id": "7484" + }, + { + "examine": "Allows for equal distribution of spice.", + "durability": null, + "name": "Orange spice (3)", + "archery_ticket_price": "0", + "id": "7485" + }, + { + "examine": "Allows for equal distribution of spice.", + "durability": null, + "name": "Orange spice (2)", + "archery_ticket_price": "0", + "id": "7486" + }, + { + "examine": "Allows for equal distribution of spice.", + "durability": null, + "name": "Orange spice (1)", + "archery_ticket_price": "0", + "id": "7487" + }, + { + "examine": "Allows for equal distribution of spice.", + "durability": null, + "name": "Brown spice (4)", + "archery_ticket_price": "0", + "id": "7488" + }, + { + "examine": "Allows for equal distribution of spice.", + "durability": null, + "name": "Brown spice (3)", + "archery_ticket_price": "0", + "id": "7489" + }, + { + "examine": "Allows for equal distribution of spice.", + "durability": null, + "name": "Brown spice (2)", + "archery_ticket_price": "0", + "id": "7490" + }, + { + "examine": "Allows for equal distribution of spice.", + "durability": null, + "name": "Brown spice (1)", + "archery_ticket_price": "0", + "id": "7491" + }, + { + "examine": "Allows for equal distribution of spice.", + "durability": null, + "name": "Yellow spice (4)", + "archery_ticket_price": "0", + "id": "7492" + }, + { + "examine": "Allows for equal distribution of spice.", + "durability": null, + "name": "Yellow spice (3)", + "archery_ticket_price": "0", + "id": "7493" + }, + { + "examine": "Allows for equal distribution of spice.", + "durability": null, + "name": "Yellow spice (2)", + "archery_ticket_price": "0", + "id": "7494" + }, + { + "examine": "Allows for equal distribution of spice.", + "durability": null, + "name": "Yellow spice (1)", + "archery_ticket_price": "0", + "id": "7495" + }, + { + "examine": "Allows for equal distribution of spice.", + "durability": null, + "name": "Empty spice shaker", + "archery_ticket_price": "0", + "id": "7496" + }, + { + "examine": "A cool refreshing fruit mix. With ash in for some reason.", + "durability": null, + "name": "Dirty blast", + "archery_ticket_price": "0", + "id": "7497" + }, + { + "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", + "examine": "I wonder what happens if I rub it.", + "durability": null, + "name": "Antique lamp", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "7498" + }, + { + "examine": "He seems to like wearing black.", + "durability": null, + "name": "Evil dave", + "archery_ticket_price": "0", + "id": "7499" + }, + { + "examine": "A short angry guy.", + "durability": null, + "name": "Dwarf", + "archery_ticket_price": "0", + "id": "7500" + }, + { + "examine": "He provides new players with useful information.", + "durability": null, + "name": "Lumbridge guide", + "archery_ticket_price": "0", + "id": "7502" + }, + { + "examine": "He looks a little shifty.", + "durability": null, + "name": "Osman", + "archery_ticket_price": "0", + "id": "7504" + }, + { + "examine": "A shifty-looking character.", + "durability": null, + "name": "Pirate pete", + "archery_ticket_price": "0", + "id": "7505" + }, + { + "examine": "Leader of the White Knights.", + "durability": null, + "name": "Sir amik varze", + "archery_ticket_price": "0", + "id": "7506" + }, + { + "examine": "He's been frozen in time.", + "durability": null, + "name": "Skrach", + "archery_ticket_price": "0", + "id": "7507" + }, + { + "shop_price": "4", + "examine": "There appears to be a coin in the bottom. Liked by dwarves.", + "durability": null, + "name": "Asgoldian ale", + "archery_ticket_price": "0", + "id": "7508" + }, + { + "examine": "Red hot and glowing, ouch! Only for dwarf consumption.", + "durability": null, + "name": "Dwarven rock cake", + "weight": "8.5", + "archery_ticket_price": "0", + "id": "7509" + }, + { + "examine": "Cool and heavy as a brick. Only for dwarf consumption.", + "durability": null, + "name": "Dwarven rock cake", + "weight": "8.5", + "archery_ticket_price": "0", + "id": "7510" + }, + { + "examine": "Two out of two goblin generals prefer it!", + "durability": null, + "name": "Slop of compromise", + "archery_ticket_price": "0", + "id": "7511" + }, + { + "examine": "Previously a nice crispy loaf of bread. Now just kind of icky.", + "durability": null, + "name": "Soggy bread", + "archery_ticket_price": "0", + "id": "7512" + }, + { + "examine": "They clearly taste so much better this way!", + "durability": null, + "name": "Spicy maggots", + "archery_ticket_price": "0", + "id": "7513" + }, + { + "examine": "Orange slices which have been dyed, but it looks more like they died.", + "durability": null, + "name": "Dyed orange", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7514" + }, + { + "examine": "Glad these aren't in my bed.", + "durability": null, + "name": "Breadcrumbs", + "archery_ticket_price": "0", + "id": "7515" + }, + { + "examine": "Those leaves look useful!", + "durability": null, + "name": "Kelp", + "archery_ticket_price": "0", + "id": "7516" + }, + { + "examine": "Kelp flakes. Smells of the sea.", + "durability": null, + "name": "Ground kelp", + "weight": "2", + "archery_ticket_price": "0", + "id": "7517" + }, + { + "examine": "A smelly meat.", + "durability": null, + "name": "Crab meat", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7518" + }, + { + "examine": "A smelly meat.", + "durability": null, + "name": "Crab meat", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7519" + }, + { + "ge_buy_limit": "100", + "examine": "Nice and Tasty!", + "grand_exchange_price": "219", + "durability": null, + "name": "Cooked crab meat", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7521" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "219", + "durability": null, + "name": "Cooked crab meat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7522" + }, + { + "examine": "Nice and Tasty!", + "grand_exchange_price": "226", + "durability": null, + "name": "Cooked crab meat", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7523" + }, + { + "examine": "Nice and Tasty!", + "grand_exchange_price": "226", + "durability": null, + "name": "Cooked crab meat", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7524" + }, + { + "examine": "Nice and Tasty!", + "grand_exchange_price": "226", + "durability": null, + "name": "Cooked crab meat", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7525" + }, + { + "examine": "Nice and Tasty!", + "grand_exchange_price": "226", + "durability": null, + "name": "Cooked crab meat", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7526" + }, + { + "examine": "A smelly paste.", + "durability": null, + "name": "Ground crab meat", + "archery_ticket_price": "0", + "id": "7527" + }, + { + "examine": "A smelly paste.", + "durability": null, + "name": "Ground cod", + "archery_ticket_price": "0", + "id": "7528" + }, + { + "examine": "Would taste nicer if I cooked it.", + "durability": null, + "name": "Raw fishcake", + "archery_ticket_price": "0", + "id": "7529" + }, + { + "examine": "Mmmm, reminds me of the seaside.", + "durability": null, + "name": "Cooked fishcake", + "archery_ticket_price": "0", + "id": "7530" + }, + { + "examine": "Hmmm, what can I use this for?", + "durability": null, + "name": "Mudskipper hide", + "weight": "1", + "archery_ticket_price": "0", + "id": "7532" + }, + { + "remove_head": "true", + "examine": "You'll look daft, but at least you won't drown!", + "durability": null, + "name": "Fishbowl helmet", + "weight": "5", + "archery_ticket_price": "0", + "id": "7534", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "examine": "I'll need a helmet to make this work.", + "durability": null, + "name": "Diving apparatus", + "weight": "10", + "archery_ticket_price": "0", + "id": "7535", + "equipment_slot": "1" + }, + { + "examine": "Fresh off the crab itself.", + "durability": null, + "name": "Fresh crab claw", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7536" + }, + { + "examine": "If it is good enough for crabs, it's good enough for me.", + "durability": null, + "name": "Crab claw", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7537", + "bonuses": "0,0,0,0,0,3,4,2,0,0,1,1,0,0,0", + "equipment_slot": "9" + }, + { + "examine": "Fresh off the crab itself.", + "durability": null, + "name": "Fresh crab shell", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7538" + }, + { + "remove_head": "true", + "examine": "If it's good enough for crabs, it's good enough for me!", + "durability": null, + "name": "Crab helmet", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7539", + "bonuses": "0,0,0,-3,-1,4,5,3,-1,4,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "examine": "Darn, it's useless now.", + "durability": null, + "name": "Broken crab claw", + "archery_ticket_price": "0", + "id": "7540" + }, + { + "examine": "Darn, it's useless now.", + "durability": null, + "name": "Broken crab shell", + "archery_ticket_price": "0", + "id": "7541" + }, + { + "destroy_message": "Maybe Traiborn will have another.", + "examine": "Imbued with knowledge itself.", + "durability": null, + "name": "Cake of guidance", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "7542" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Now all I need to do is cook it.", + "durability": null, + "name": "Raw guide cake", + "archery_ticket_price": "0", + "id": "7543" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Egg containing knowledge.", + "durability": null, + "name": "Enchanted egg", + "archery_ticket_price": "0", + "id": "7544" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Guiding milk.", + "durability": null, + "name": "Enchanted milk", + "weight": "2", + "archery_ticket_price": "0", + "id": "7545" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A pot of special flour.", + "durability": null, + "name": "Enchanted flour", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "7546" + }, + { + "examine": "A druid pouch.", + "durability": null, + "name": "Druid pouch", + "archery_ticket_price": "0", + "id": "7547" + }, + { + "shop_price": "8", + "examine": "A potato seed - plant in an allotment.", + "grand_exchange_price": "1", + "durability": null, + "name": "Potato seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7548" + }, + { + "durability": null, + "name": "Potato seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7549" + }, + { + "shop_price": "10", + "examine": "An onion seed - plant in an allotment.", + "grand_exchange_price": "1", + "durability": null, + "name": "Onion seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7550" + }, + { + "durability": null, + "name": "Onion seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7551" + }, + { + "shop_price": "76", + "examine": "Arrows with mithril heads.", + "grand_exchange_price": "24", + "durability": null, + "name": "Mithril arrow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7552", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,22,0,0" + }, + { + "durability": null, + "name": "Mithril arrow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7553" + }, + { + "shop_price": "17", + "examine": "One of the 4 basic elemental Runes.", + "grand_exchange_price": "16", + "durability": null, + "name": "Fire rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7554" + }, + { + "durability": null, + "name": "Fire rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7555" + }, + { + "shop_price": "17", + "examine": "One of the 4 basic elemental Runes.", + "grand_exchange_price": "6", + "durability": null, + "name": "Water rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7556" + }, + { + "durability": null, + "name": "Water rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7557" + }, + { + "shop_price": "17", + "examine": "One of the 4 basic elemental Runes.", + "grand_exchange_price": "9", + "durability": null, + "name": "Air rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7558" + }, + { + "durability": null, + "name": "Air rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7559" + }, + { + "shop_price": "140", + "examine": "Used for small missile spells.", + "grand_exchange_price": "65", + "durability": null, + "name": "Chaos rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7560" + }, + { + "durability": null, + "name": "Chaos rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7561" + }, + { + "shop_price": "10", + "examine": "A tomato seed - plant in an allotment.", + "grand_exchange_price": "1", + "durability": null, + "name": "Tomato seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7562" + }, + { + "durability": null, + "name": "Tomato seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7563" + }, + { + "examine": "An inflated toad tied to a rock like a balloon.", + "durability": null, + "name": "Balloon toad", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "7564" + }, + { + "examine": "An inflated toad tied to a rock like a balloon.", + "durability": null, + "name": "Balloon toad", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "7565" + }, + { + "ge_buy_limit": "100", + "examine": "The uncooked meat of a Jubbly bird.", + "grand_exchange_price": "422", + "durability": null, + "name": "Raw jubbly", + "tradeable": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "7566" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "422", + "durability": null, + "name": "Raw jubbly", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7567" + }, + { + "ge_buy_limit": "100", + "examine": "Lovely jubbly!", + "grand_exchange_price": "944", + "durability": null, + "name": "Cooked jubbly", + "tradeable": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "7568" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "944", + "durability": null, + "name": "Cooked jubbly", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7569" + }, + { + "durability": null, + "name": "Burnt jubbly", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7571" + }, + { + "examine": "Like a banana only redder.", + "durability": null, + "name": "Red banana", + "archery_ticket_price": "0", + "id": "7572", + "equipment_slot": "5" + }, + { + "examine": "Like monkey nuts only tchikier.", + "durability": null, + "name": "Tchiki monkey nuts", + "archery_ticket_price": "0", + "id": "7573" + }, + { + "examine": "Perfect for stuffing snakes.", + "durability": null, + "name": "Sliced red banana", + "archery_ticket_price": "0", + "id": "7574" + }, + { + "examine": "Mixing this with jam would just be wrong.", + "durability": null, + "name": "Tchiki nut paste", + "archery_ticket_price": "0", + "id": "7575" + }, + { + "examine": "Like a snake only not alive.", + "durability": null, + "name": "Snake corpse", + "weight": "3", + "archery_ticket_price": "0", + "id": "7576" + }, + { + "examine": "This snake is stuffed right up.", + "durability": null, + "name": "Raw stuffed snake", + "weight": "3", + "archery_ticket_price": "0", + "id": "7577" + }, + { + "examine": "Is this really what you wanted to do?", + "durability": null, + "name": "Odd stuffed snake", + "archery_ticket_price": "0", + "id": "7578" + }, + { + "examine": "Fit for a Monkey King. (cooked)", + "durability": null, + "name": "Stuffed snake", + "weight": "3", + "archery_ticket_price": "0", + "id": "7579" + }, + { + "examine": "Your hellish pet cat!!", + "durability": null, + "name": "Overgrown hellcat", + "archery_ticket_price": "0", + "id": "7581" + }, + { + "examine": "Your hellish pet cat!!", + "durability": null, + "name": "Hell cat", + "archery_ticket_price": "0", + "id": "7582" + }, + { + "examine": "Your hellish pet cat!!", + "durability": null, + "name": "Hell-kitten", + "archery_ticket_price": "0", + "id": "7583" + }, + { + "examine": "Your hellish pet cat!!", + "durability": null, + "name": "Wily hellcat", + "archery_ticket_price": "0", + "id": "7585" + }, + { + "examine": "I can train on this", + "durability": null, + "name": "Dummy", + "archery_ticket_price": "0", + "id": "7586" + }, + { + "examine": "Filled with items. Like a bank, but spookier!", + "durability": null, + "name": "Coffin", + "archery_ticket_price": "0", + "id": "7587" + }, + { + "examine": "Filled with items. Like a bank, but spookier!", + "durability": null, + "name": "Coffin", + "archery_ticket_price": "0", + "id": "7588" + }, + { + "examine": "Filled with items. Like a bank, but spookier!", + "durability": null, + "name": "Coffin", + "archery_ticket_price": "0", + "id": "7589" + }, + { + "examine": "Filled with items. Like a bank, but spookier!", + "durability": null, + "name": "Coffin", + "archery_ticket_price": "0", + "id": "7590" + }, + { + "examine": "Filled with items. Like a bank, but spookier!", + "durability": null, + "name": "Coffin", + "archery_ticket_price": "0", + "id": "7591" + }, + { + "examine": "Aside from the braaaains on the lapel, it's still quite good.", + "durability": null, + "name": "Zombie shirt", + "archery_ticket_price": "0", + "id": "7592", + "equipment_slot": "4" + }, + { + "examine": "Good for a shamble about town.", + "durability": null, + "name": "Zombie trousers", + "archery_ticket_price": "0", + "id": "7593", + "equipment_slot": "7" + }, + { + "remove_head": "true", + "examine": "I look 40,000 years old in this...", + "durability": null, + "name": "Zombie mask", + "archery_ticket_price": "0", + "id": "7594", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "examine": "Smells pretty funky.", + "durability": null, + "name": "Zombie gloves", + "archery_ticket_price": "0", + "id": "7595", + "equipment_slot": "9" + }, + { + "shop_price": "160", + "examine": "Thrilling.", + "durability": null, + "name": "Zombie boots", + "archery_ticket_price": "0", + "id": "7596", + "equipment_slot": "10" + }, + { + "durability": null, + "name": "Item", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7597" + }, + { + "durability": null, + "name": "Item", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7598" + }, + { + "durability": null, + "name": "Item", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7599" + }, + { + "durability": null, + "name": "Item", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7600" + }, + { + "durability": null, + "name": "Item", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7601" + }, + { + "durability": null, + "name": "Item", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7602" + }, + { + "durability": null, + "name": "Item", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7603" + }, + { + "durability": null, + "name": "Item", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7604" + }, + { + "durability": null, + "name": "Item", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7605" + }, + { + "durability": null, + "name": "Item", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7606" + }, + { + "durability": null, + "name": "Item", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7607" + }, + { + "durability": null, + "name": "Item", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7608" + }, + { + "durability": null, + "name": "Item", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7609" + }, + { + "durability": null, + "name": "Item", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7610" + }, + { + "durability": null, + "name": "Item", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7611" + }, + { + "durability": null, + "name": "Item", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7612" + }, + { + "durability": null, + "name": "Item", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7613" + }, + { + "durability": null, + "name": "Item", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7614" + }, + { + "durability": null, + "name": "Item", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7615" + }, + { + "durability": null, + "name": "Item", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7616" + }, + { + "durability": null, + "name": "Item", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7617" + }, + { + "durability": null, + "name": "Item", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7618" + }, + { + "examine": "A silvery rod of mithril and silver with sapphire on top.", + "durability": null, + "name": "Silvthrill rod", + "archery_ticket_price": "0", + "id": "7620" + }, + { + "examine": "A bucket partially filled with rubble. / A bucket totally filled with rubble.", + "durability": null, + "name": "Bucket of rubble", + "weight": "2", + "archery_ticket_price": "0", + "id": "7622" + }, + { + "examine": "A bucket partially filled with rubble. / A bucket totally filled with rubble.", + "durability": null, + "name": "Bucket of rubble", + "weight": "2", + "archery_ticket_price": "0", + "id": "7624" + }, + { + "examine": "A bucket partially filled with rubble. / A bucket totally filled with rubble.", + "durability": null, + "name": "Bucket of rubble", + "weight": "2", + "archery_ticket_price": "0", + "id": "7626" + }, + { + "destroy_message": "You can get another plaster fragment by exploring near the Inn in Burgh de Rott.", + "examine": "A fragment of plaster with some impressions on it.", + "durability": null, + "name": "Plaster fragment", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "7628" + }, + { + "destroy_message": "You can get another scroll by exploring near the Inn in Burgh de Rott.", + "examine": "An ancient tattered scroll.", + "durability": null, + "name": "Dusty scroll", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "7629" + }, + { + "destroy_message": "You can get another temple key by talking to Drezel.", + "examine": "A key for the Temple Library. (In Aid of the Myreque)", + "durability": null, + "name": "Temple library key", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "7632" + }, + { + "destroy_message": "You can get another Ancient Book by searching the library in the temple on the Salve.", + "shop_price": "5000", + "examine": "The unholy book of a forgotten god.", + "durability": null, + "name": "Ancient book", + "weight": "1", + "archery_ticket_price": "0", + "id": "7633", + "bonuses": "4,4,4,6,0,4,4,4,6,0,2,0,0,5,0" + }, + { + "destroy_message": "You can get another Crumbling tome by searching the library in the temple on the Salve.", + "examine": "An ancient history book.", + "durability": null, + "name": "Battered tome", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "7634" + }, + { + "destroy_message": "You can get another Leather book by searching the library in the temple on the Salve.", + "examine": "An ancient leather-bound tome.", + "durability": null, + "name": "Leather book", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "7635" + }, + { + "examine": "Rod of Ivandis dust.", + "durability": null, + "name": "Rod dust", + "archery_ticket_price": "0", + "id": "7636" + }, + { + "examine": "A silvery rod of mithril and silver with sapphire on top.", + "durability": null, + "name": "Silvthrill rod", + "archery_ticket_price": "0", + "id": "7637", + "equipment_slot": "3" + }, + { + "examine": "A silvery rod of mithril and silver with sapphire on top.", + "durability": null, + "name": "Silvthrill rod", + "archery_ticket_price": "0", + "id": "7638" + }, + { + "turn90cw_anim": "1207", + "examine": "A fully charged rod.", + "walk_anim": "1205", + "has_special": "true", + "durability": null, + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "false", + "weapon_interface": "1", + "turn180_anim": "1206", + "equip_audio": "2247", + "render_anim": "28", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "stand_anim": "813", + "name": "Rod of ivandis(10)", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "7639", + "stand_turn_anim": "1209", + "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0" + }, + { + "turn90cw_anim": "1207", + "examine": "A partialy charged rod.", + "walk_anim": "1205", + "has_special": "true", + "durability": null, + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "false", + "weapon_interface": "1", + "turn180_anim": "1206", + "equip_audio": "2247", + "render_anim": "28", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "stand_anim": "813", + "name": "Rod of ivandis(9)", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "7640", + "stand_turn_anim": "1209", + "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0" + }, + { + "turn90cw_anim": "1207", + "examine": "A partialy charged rod.", + "walk_anim": "1205", + "has_special": "true", + "durability": null, + "destroy": "true", + "weight": "2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "false", + "weapon_interface": "1", + "turn180_anim": "1206", + "equip_audio": "2247", + "defence_anim": "420", + "render_anim": "28", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "stand_anim": "813", + "name": "Rod of ivandis(8)", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "7641", + "stand_turn_anim": "1209", + "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0" + }, + { + "turn90cw_anim": "1207", + "examine": "A partialy charged rod.", + "walk_anim": "1205", + "has_special": "true", + "durability": null, + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "false", + "weapon_interface": "1", + "turn180_anim": "1206", + "equip_audio": "2247", + "render_anim": "28", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "stand_anim": "813", + "name": "Rod of ivandis(7)", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "7642", + "stand_turn_anim": "1209", + "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0" + }, + { + "turn90cw_anim": "1207", + "examine": "A partialy charged rod.", + "walk_anim": "1205", + "has_special": "true", + "durability": null, + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "false", + "weapon_interface": "1", + "turn180_anim": "1206", + "equip_audio": "2247", + "render_anim": "28", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "stand_anim": "813", + "name": "Rod of ivandis(6)", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "7643", + "stand_turn_anim": "1209", + "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0" + }, + { + "turn90cw_anim": "1207", + "examine": "A partialy charged rod.", + "walk_anim": "1205", + "has_special": "true", + "durability": null, + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "false", + "weapon_interface": "1", + "turn180_anim": "1206", + "equip_audio": "2247", + "render_anim": "28", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "stand_anim": "813", + "name": "Rod of ivandis(5)", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "7644", + "stand_turn_anim": "1209", + "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0" + }, + { + "turn90cw_anim": "1207", + "examine": "A partialy charged rod.", + "walk_anim": "1205", + "has_special": "true", + "durability": null, + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "false", + "weapon_interface": "1", + "turn180_anim": "1206", + "equip_audio": "2247", + "render_anim": "28", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "stand_anim": "813", + "name": "Rod of ivandis(4)", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "7645", + "stand_turn_anim": "1209", + "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0" + }, + { + "turn90cw_anim": "1207", + "examine": "A partialy charged rod.", + "walk_anim": "1205", + "has_special": "true", + "durability": null, + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "false", + "weapon_interface": "1", + "turn180_anim": "1206", + "equip_audio": "2247", + "render_anim": "28", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "stand_anim": "813", + "name": "Rod of ivandis(3)", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "7646", + "stand_turn_anim": "1209", + "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0" + }, + { + "turn90cw_anim": "1207", + "examine": "2! 2 charges left! Ha Ha Ha.", + "walk_anim": "1205", + "has_special": "true", + "durability": null, + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "false", + "weapon_interface": "1", + "turn180_anim": "1206", + "equip_audio": "2247", + "render_anim": "28", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "stand_anim": "813", + "name": "Rod of ivandis(2)", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "7647", + "stand_turn_anim": "1209", + "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0" + }, + { + "turn90cw_anim": "1207", + "examine": "A partialy charged rod.", + "walk_anim": "1205", + "has_special": "true", + "durability": null, + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "false", + "weapon_interface": "1", + "turn180_anim": "1206", + "equip_audio": "2247", + "render_anim": "28", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "stand_anim": "813", + "name": "Rod of ivandis(1)", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "7648", + "stand_turn_anim": "1209", + "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0" + }, + { + "destroy_message": "You can make another one of these by using clay on Ivandis' coffin.", + "examine": "A mould of the Rod of Ivandis.", + "durability": null, + "name": "Rod clay mould", + "destroy": "true", + "archery_ticket_price": "0", + "id": "7649" + }, + { + "ge_buy_limit": "1000", + "examine": "It's ground up silver.", + "grand_exchange_price": "316", + "durability": null, + "name": "Silver dust", + "tradeable": "true", + "weight": "0.33", + "archery_ticket_price": "0", + "id": "7650" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "316", + "durability": null, + "name": "Silver dust", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7651" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "96", + "examine": "An unfinished potion.", + "durability": null, + "name": "Guthix balance(unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7652" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "96", + "durability": null, + "name": "Guthix balance(unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7653" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "77", + "examine": "An unfinished potion.", + "durability": null, + "name": "Guthix balance(unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7654" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "77", + "durability": null, + "name": "Guthix balance(unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7655" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "58", + "examine": "An unfinished potion.", + "durability": null, + "name": "Guthix balance(unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7656" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "58", + "durability": null, + "name": "Guthix balance(unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7657" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "30", + "examine": "An unfinished potion.", + "durability": null, + "name": "Guthix balance(unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7658" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "30", + "durability": null, + "name": "Guthix balance(unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7659" + }, + { + "ge_buy_limit": "1000", + "examine": "A potion of harralander, red spiders eggs, garlic and silver dust.", + "grand_exchange_price": "140", + "durability": null, + "name": "Guthix balance(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7660" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "140", + "durability": null, + "name": "Guthix balance(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7661" + }, + { + "ge_buy_limit": "1000", + "examine": "A potion of harralander, red spiders eggs, garlic and silver dust.", + "grand_exchange_price": "168", + "durability": null, + "name": "Guthix balance(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7662" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "168", + "durability": null, + "name": "Guthix balance(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7663" + }, + { + "ge_buy_limit": "1000", + "examine": "A potion of harralander, red spiders eggs, garlic and silver dust.", + "grand_exchange_price": "132", + "durability": null, + "name": "Guthix balance(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7664" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "132", + "durability": null, + "name": "Guthix balance(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7665" + }, + { + "ge_buy_limit": "1000", + "examine": "A potion of harralander, red spiders eggs, garlic and silver dust.", + "grand_exchange_price": "66", + "durability": null, + "name": "Guthix balance(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7666" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "66", + "durability": null, + "name": "Guthix balance(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7667" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1663", + "examine": "A specially crafted hammer with strange markings on it.", + "walk_anim": "1663", + "turn90ccw_anim": "1663", + "attack_speed": "5", + "two_handed": "true", + "turn180_anim": "1663", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "grand_exchange_price": "1615", + "stand_anim": "1662", + "tradeable": "true", + "run_anim": "1664", + "archery_ticket_price": "0", + "id": "7668", + "stand_turn_anim": "823", + "bonuses": "-4,-4,35,-4,0,0,0,0,0,0,0,35,0,0,0", + "shop_price": "3000", + "durability": null, + "weight": "1.8", + "weapon_interface": "10", + "render_anim": "27", + "name": "Gadderhammer" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1615", + "durability": null, + "name": "Gadderhammer", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7669" + }, + { + "turn90cw_anim": "3680", + "examine": "I think they look a bit silly.", + "walk_anim": "3680", + "durability": null, + "weight": "0.4", + "turn90ccw_anim": "3680", + "attack_speed": "4", + "two_handed": "true", + "weapon_interface": "9", + "turn180_anim": "3680", + "render_anim": "1386", + "equipment_slot": "3", + "stand_anim": "3677", + "name": "Boxing gloves", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "7671", + "stand_turn_anim": "823", + "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0" + }, + { + "turn90cw_anim": "3680", + "examine": "I think they look a bit silly.", + "walk_anim": "3680", + "durability": null, + "weight": "0.4", + "turn90ccw_anim": "3680", + "attack_speed": "4", + "two_handed": "true", + "weapon_interface": "9", + "turn180_anim": "3680", + "render_anim": "1386", + "equipment_slot": "3", + "stand_anim": "3677", + "name": "Boxing gloves", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "7673", + "stand_turn_anim": "823", + "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0" + }, + { + "examine": "A less-than razor sharp sword.", + "durability": null, + "name": "Wooden sword", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "7675", + "weapon_interface": "5", + "bonuses": "4,3,-2,0,0,0,2,1,0,0,0,5,0,0,0", + "equip_audio": "2248", + "render_anim": "2584", + "equipment_slot": "3" + }, + { + "durability": null, + "name": "Wooden shield", + "archery_ticket_price": "0", + "id": "7676", + "equip_audio": "2250", + "equipment_slot": "5" + }, + { + "examine": "It knows where the treasure is.", + "durability": null, + "name": "Treasure stone", + "weight": "1.8", + "archery_ticket_price": "0", + "id": "7677" + }, + { + "shop_price": "160", + "examine": "You can use this to open the prize chest!", + "durability": null, + "name": "Prize key", + "weight": "1", + "archery_ticket_price": "0", + "id": "7678" + }, + { + "examine": "A good tool for bashing someone.", + "durability": null, + "name": "Pugel", + "archery_ticket_price": "0", + "two_handed": "true", + "id": "7679", + "weapon_interface": "14", + "equipment_slot": "3" + }, + { + "durability": null, + "name": "Pugel", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7680" + }, + { + "examine": "Party Pete's Bumper Book Of Games", + "durability": null, + "name": "Game book", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "7681" + }, + { + "durability": null, + "name": "Hoop", + "archery_ticket_price": "0", + "id": "7682", + "equipment_slot": "3" + }, + { + "durability": null, + "name": "Hoop", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7683" + }, + { + "durability": null, + "name": "Dart", + "archery_ticket_price": "0", + "attack_speed": "3", + "id": "7684", + "equip_audio": "2244", + "equipment_slot": "3" + }, + { + "durability": null, + "name": "Dart", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7685" + }, + { + "durability": null, + "name": "Bow and arrow", + "archery_ticket_price": "0", + "id": "7686", + "weapon_interface": "1", + "equipment_slot": "3" + }, + { + "durability": null, + "name": "Bow and arrow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7687" + }, + { + "examine": "The kettle is empty.", + "durability": null, + "name": "Kettle", + "archery_ticket_price": "0", + "id": "7688" + }, + { + "durability": null, + "name": "Kettle", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7689" + }, + { + "examine": "It's full of cold water.", + "durability": null, + "name": "Full kettle", + "archery_ticket_price": "0", + "id": "7690" + }, + { + "examine": "It's full of boiling water.", + "durability": null, + "name": "Hot kettle", + "archery_ticket_price": "0", + "id": "7691" + }, + { + "examine": "I'd really like a nice cup of tea.", + "durability": null, + "name": "Pot of tea (4)", + "tradeable": "true", + "weight": "1.5", + "archery_ticket_price": "0", + "id": "7692" + }, + { + "durability": null, + "name": "Pot of tea (4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7693" + }, + { + "examine": "I'd really like a nice cup of tea.", + "durability": null, + "name": "Pot of tea (3)", + "tradeable": "true", + "weight": "1.5", + "archery_ticket_price": "0", + "id": "7694" + }, + { + "durability": null, + "name": "Pot of tea (3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7695" + }, + { + "examine": "I'd really like a nice cup of tea.", + "durability": null, + "name": "Pot of tea (2)", + "tradeable": "true", + "weight": "1.5", + "archery_ticket_price": "0", + "id": "7696" + }, + { + "durability": null, + "name": "Pot of tea (2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7697" + }, + { + "examine": "I'd really like a nice cup of tea.", + "durability": null, + "name": "Pot of tea (1)", + "tradeable": "true", + "weight": "1.5", + "archery_ticket_price": "0", + "id": "7698" + }, + { + "durability": null, + "name": "Pot of tea (1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7699" + }, + { + "examine": "Add boiling water to make a tea.", + "durability": null, + "name": "Teapot with leaves", + "tradeable": "true", + "weight": "1.5", + "archery_ticket_price": "0", + "id": "7700" + }, + { + "durability": null, + "name": "Teapot with leaves", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7701" + }, + { + "examine": "This teapot is empty.", + "durability": null, + "name": "Teapot", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "7702" + }, + { + "durability": null, + "name": "Teapot", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7703" + }, + { + "examine": "I'd really like a nice cup of tea.", + "durability": null, + "name": "Pot of tea (4)", + "tradeable": "true", + "weight": "1.5", + "archery_ticket_price": "0", + "id": "7704" + }, + { + "durability": null, + "name": "Pot of tea (4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7705" + }, + { + "examine": "I'd really like a nice cup of tea.", + "durability": null, + "name": "Pot of tea (3)", + "tradeable": "true", + "weight": "1.5", + "archery_ticket_price": "0", + "id": "7706" + }, + { + "durability": null, + "name": "Pot of tea (3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7707" + }, + { + "examine": "I'd really like a nice cup of tea.", + "durability": null, + "name": "Pot of tea (2)", + "tradeable": "true", + "weight": "1.5", + "archery_ticket_price": "0", + "id": "7708" + }, + { + "durability": null, + "name": "Pot of tea (2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7709" + }, + { + "examine": "I'd really like a nice cup of tea.", + "durability": null, + "name": "Pot of tea (1)", + "tradeable": "true", + "weight": "1.5", + "archery_ticket_price": "0", + "id": "7710" + }, + { + "durability": null, + "name": "Pot of tea (1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7711" + }, + { + "examine": "Add boiling water to make a tea.", + "durability": null, + "name": "Teapot with leaves", + "tradeable": "true", + "weight": "1.5", + "archery_ticket_price": "0", + "id": "7712" + }, + { + "durability": null, + "name": "Teapot with leaves", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7713" + }, + { + "examine": "This teapot is empty.", + "durability": null, + "name": "Teapot", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "7714" + }, + { + "durability": null, + "name": "Teapot", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7715" + }, + { + "examine": "I'd really like a nice cup of tea.", + "durability": null, + "name": "Pot of tea (4)", + "tradeable": "true", + "weight": "1.5", + "archery_ticket_price": "0", + "id": "7716" + }, + { + "durability": null, + "name": "Pot of tea (4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7717" + }, + { + "examine": "I'd really like a nice cup of tea.", + "durability": null, + "name": "Pot of tea (3)", + "tradeable": "true", + "weight": "1.5", + "archery_ticket_price": "0", + "id": "7718" + }, + { + "durability": null, + "name": "Pot of tea (3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7719" + }, + { + "examine": "I'd really like a nice cup of tea.", + "durability": null, + "name": "Pot of tea (2)", + "tradeable": "true", + "weight": "1.5", + "archery_ticket_price": "0", + "id": "7720" + }, + { + "durability": null, + "name": "Pot of tea (2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7721" + }, + { + "examine": "I'd really like a nice cup of tea.", + "durability": null, + "name": "Pot of tea (1)", + "tradeable": "true", + "weight": "1.5", + "archery_ticket_price": "0", + "id": "7722" + }, + { + "durability": null, + "name": "Pot of tea (1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7723" + }, + { + "examine": "Add boiling water to make a tea.", + "durability": null, + "name": "Teapot with leaves", + "tradeable": "true", + "weight": "1.5", + "archery_ticket_price": "0", + "id": "7724" + }, + { + "durability": null, + "name": "Teapot with leaves", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7725" + }, + { + "examine": "This teapot is empty.", + "durability": null, + "name": "Teapot", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "7726" + }, + { + "durability": null, + "name": "Teapot", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7727" + }, + { + "shop_price": "1", + "examine": "An empty cup.", + "grand_exchange_price": "7", + "durability": null, + "name": "Empty cup", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7728" + }, + { + "durability": null, + "name": "Empty cup", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7729" + }, + { + "shop_price": "10", + "examine": "A nice cup of tea.", + "grand_exchange_price": "30", + "durability": null, + "name": "Cup of tea", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "7730" + }, + { + "shop_price": "10", + "examine": "A nice cup of tea.", + "grand_exchange_price": "30", + "durability": null, + "name": "Cup of tea", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "7731" + }, + { + "examine": "A porcelain cup.", + "durability": null, + "name": "Porcelain cup", + "archery_ticket_price": "0", + "id": "7732" + }, + { + "shop_price": "10", + "examine": "A nice cup of tea.", + "grand_exchange_price": "30", + "durability": null, + "name": "Cup of tea", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "7733" + }, + { + "shop_price": "10", + "examine": "A nice cup of tea.", + "grand_exchange_price": "30", + "durability": null, + "name": "Cup of tea", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "7734" + }, + { + "examine": "A porcelain cup.", + "durability": null, + "name": "Porcelain cup", + "archery_ticket_price": "0", + "id": "7735" + }, + { + "shop_price": "10", + "examine": "A nice cup of tea.", + "grand_exchange_price": "30", + "durability": null, + "name": "Cup of tea", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "7736" + }, + { + "shop_price": "10", + "examine": "A nice cup of tea.", + "grand_exchange_price": "30", + "durability": null, + "name": "Cup of tea", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "7737" + }, + { + "examine": "Mmm, how about a nice cup of tea?", + "durability": null, + "name": "Tea leaves", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7738" + }, + { + "durability": null, + "name": "Tea leaves", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7739" + }, + { + "examine": "A glass of frothy ale.", + "grand_exchange_price": "151", + "durability": null, + "name": "Beer", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "7740" + }, + { + "durability": null, + "name": "Beer", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7741" + }, + { + "shop_price": "1", + "examine": "I need to fill this with beer.", + "grand_exchange_price": "25", + "durability": null, + "name": "Beer glass", + "tradeable": "true", + "weight": "0.05", + "archery_ticket_price": "0", + "id": "7742" + }, + { + "durability": null, + "name": "Beer glass", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7743" + }, + { + "shop_price": "3", + "examine": "Probably the finest readily-available ale in Asgarnia.", + "grand_exchange_price": "131", + "durability": null, + "name": "Asgarnian ale", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7744" + }, + { + "durability": null, + "name": "Asgarnian ale", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7745" + }, + { + "shop_price": "2", + "examine": "A glass of frothy ale.", + "grand_exchange_price": "569", + "durability": null, + "name": "Greenman's ale", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7746" + }, + { + "durability": null, + "name": "Greenman's ale", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7747" + }, + { + "shop_price": "2", + "examine": "A glass of bitter.", + "grand_exchange_price": "523", + "durability": null, + "name": "Dragon bitter", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "7748" + }, + { + "durability": null, + "name": "Dragon bitter", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7749" + }, + { + "shop_price": "5", + "examine": "A foul smelling brew.", + "grand_exchange_price": "14", + "durability": null, + "name": "Moonlight mead", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7750" + }, + { + "durability": null, + "name": "Moonlight mead", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7751" + }, + { + "shop_price": "2", + "examine": "A glass of Cider", + "grand_exchange_price": "1539", + "durability": null, + "name": "Cider", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "7752" + }, + { + "durability": null, + "name": "Cider", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7753" + }, + { + "examine": "A fruity, full-bodied ale.", + "grand_exchange_price": "2371", + "durability": null, + "name": "Chef's delight", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7754" + }, + { + "durability": null, + "name": "Chef's delight", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7755" + }, + { + "durability": null, + "name": "Paintbrush", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7756", + "equipment_slot": "3" + }, + { + "durability": null, + "name": "Paintbrush", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7757" + }, + { + "examine": "A decent-enough weapon gone rusty.", + "durability": null, + "name": "Rusty sword", + "weight": "2", + "archery_ticket_price": "0", + "id": "7758", + "equipment_slot": "3" + }, + { + "ge_buy_limit": "100", + "examine": "Nice bit of crafting.", + "grand_exchange_price": "3140", + "durability": null, + "name": "Toy soldier", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "id": "7759" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3140", + "durability": null, + "name": "Toy soldier", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7760" + }, + { + "examine": "Nice bit of crafting.", + "grand_exchange_price": "3123", + "durability": null, + "name": "Toy soldier (wound)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "id": "7761" + }, + { + "durability": null, + "name": "Toy soldier (wound)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7762" + }, + { + "ge_buy_limit": "100", + "examine": "Nice bit of crafting!", + "grand_exchange_price": "3236", + "durability": null, + "name": "Toy doll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7763" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3236", + "durability": null, + "name": "Toy doll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7764" + }, + { + "examine": "Nice bit of crafting!", + "grand_exchange_price": "3289", + "durability": null, + "name": "Toy doll (wound)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7765" + }, + { + "durability": null, + "name": "Toy doll (wound)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7766" + }, + { + "shop_price": "1705", + "ge_buy_limit": "100", + "examine": "Nice bit of crafting!", + "grand_exchange_price": "3384", + "durability": null, + "name": "Toy mouse", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "7767" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3384", + "durability": null, + "name": "Toy mouse", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7768" + }, + { + "shop_price": "1705", + "examine": "Nice bit of crafting!", + "grand_exchange_price": "3484", + "durability": null, + "name": "Toy mouse (wound)", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "7769" + }, + { + "durability": null, + "name": "Toy mouse (wound)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7770" + }, + { + "ge_buy_limit": "100", + "examine": "Inventory: Nice bit of crafting!As a follower: An amazing piece of crafting.", + "grand_exchange_price": "2930", + "durability": null, + "name": "Clockwork cat", + "tradeable": "true", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "7771" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2930", + "durability": null, + "name": "Clockwork cat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7772" + }, + { + "examine": "I can use this to make a lyre.", + "durability": null, + "name": "Branch", + "weight": "1", + "archery_ticket_price": "0", + "id": "7773", + "equipment_slot": "3" + }, + { + "destroy_message": "Warning! If you destroy this item, you will lose ALL rewards that it relates to and you will have to make another trek in order to get another one.", + "examine": "Blue/Red/Yellow reward token exchanged at Burgh de Rott/Paterdomus.", + "durability": null, + "name": "Reward token", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "7774" + }, + { + "destroy_message": "Warning! If you destroy this item, you will lose ALL rewards that it relates to and you will have to make another trek in order to get another one.", + "examine": "Blue/Red/Yellow reward token exchanged at Burgh de Rott/Paterdomus.", + "durability": null, + "name": "Reward token", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "7775" + }, + { + "destroy_message": "Warning! If you destroy this item, you will lose ALL rewards that it relates to and you will have to make another trek in order to get another one.", + "examine": "Blue/Red/Yellow reward token exchanged at Burgh de Rott/Paterdomus.", + "durability": null, + "name": "Reward token", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "7776" + }, + { + "examine": "A long section of vine made up of lots of shorter sections.", + "durability": null, + "name": "Long vine", + "archery_ticket_price": "0", + "id": "7777" + }, + { + "examine": "A short section of vines.", + "durability": null, + "name": "Short vine", + "archery_ticket_price": "0", + "id": "7778" + }, + { + "examine": "A tome of learning that focuses on the Fishing skill.", + "durability": null, + "name": "Fishing tome", + "weight": "1", + "archery_ticket_price": "0", + "id": "7779" + }, + { + "examine": "A tome of learning that focuses on the Fishing skill.", + "durability": null, + "name": "Fishing tome", + "weight": "1", + "archery_ticket_price": "0", + "id": "7780" + }, + { + "examine": "A tome of learning that focuses on the Fishing skill.", + "durability": null, + "name": "Fishing tome", + "weight": "1", + "archery_ticket_price": "0", + "id": "7781" + }, + { + "examine": "A tome of learning that focuses on Agility.", + "durability": null, + "name": "Agility tome", + "weight": "1", + "archery_ticket_price": "0", + "id": "7782" + }, + { + "examine": "A tome of learning that focuses on Agility.", + "durability": null, + "name": "Agility tome", + "weight": "1", + "archery_ticket_price": "0", + "id": "7783" + }, + { + "examine": "A tome of learning that focuses on Agility.", + "durability": null, + "name": "Agility tome", + "weight": "1", + "archery_ticket_price": "0", + "id": "7784" + }, + { + "examine": "A tome of learning that focuses on the Thieving skill.", + "durability": null, + "name": "Thieving tome", + "weight": "1", + "archery_ticket_price": "0", + "id": "7785" + }, + { + "examine": "A tome of learning that focuses on the Thieving skill.", + "durability": null, + "name": "Thieving tome", + "weight": "1", + "archery_ticket_price": "0", + "id": "7786" + }, + { + "examine": "A tome of learning that focuses on the Thieving skill.", + "durability": null, + "name": "Thieving tome", + "weight": "1", + "archery_ticket_price": "0", + "id": "7787" + }, + { + "examine": "A tome of learning which focuses on the Slayer skill.", + "durability": null, + "name": "Slayer tome", + "weight": "1", + "archery_ticket_price": "0", + "id": "7788" + }, + { + "examine": "A tome of learning which focuses on the Slayer skill.", + "durability": null, + "name": "Slayer tome", + "weight": "1", + "archery_ticket_price": "0", + "id": "7789" + }, + { + "examine": "A tome of learning which focuses on the Slayer skill.", + "durability": null, + "name": "Slayer tome", + "weight": "1", + "archery_ticket_price": "0", + "id": "7790" + }, + { + "shop_price": "160", + "examine": "A tome of learning that focuses on the Mining skill.", + "durability": null, + "name": "Mining tome", + "weight": "1", + "archery_ticket_price": "0", + "id": "7791" + }, + { + "shop_price": "160", + "examine": "A tome of learning that focuses on the Mining skill.", + "durability": null, + "name": "Mining tome", + "weight": "1", + "archery_ticket_price": "0", + "id": "7792" + }, + { + "shop_price": "160", + "examine": "A tome of learning that focuses on the Mining skill.", + "durability": null, + "name": "Mining tome", + "weight": "1", + "archery_ticket_price": "0", + "id": "7793" + }, + { + "examine": "A tome of learning that focuses on Firemaking.", + "durability": null, + "name": "Firemaking tome", + "weight": "1", + "archery_ticket_price": "0", + "id": "7794" + }, + { + "examine": "A tome of learning that focuses on Firemaking.", + "durability": null, + "name": "Firemaking tome", + "weight": "1", + "archery_ticket_price": "0", + "id": "7795" + }, + { + "examine": "A tome of learning that focuses on Firemaking.", + "durability": null, + "name": "Firemaking tome", + "weight": "1", + "archery_ticket_price": "0", + "id": "7796" + }, + { + "shop_price": "160", + "examine": "A tome of learning that focuses on the Woodcutting skill.", + "durability": null, + "name": "Woodcutting tome", + "weight": "1", + "archery_ticket_price": "0", + "id": "7797" + }, + { + "shop_price": "160", + "examine": "A tome of learning that focuses on the Woodcutting skill.", + "durability": null, + "name": "Woodcutting tome", + "weight": "1", + "archery_ticket_price": "0", + "id": "7798" + }, + { + "shop_price": "160", + "examine": "A tome of learning that focuses on the Woodcutting skill.", + "durability": null, + "name": "Woodcutting tome", + "weight": "1", + "archery_ticket_price": "0", + "id": "7799" + }, + { + "examine": "A shell from a giant snail.", + "durability": null, + "name": "Snail shell", + "weight": "7", + "archery_ticket_price": "0", + "id": "7800" + }, + { + "ge_buy_limit": "10000", + "examine": "Scaly but not slimy!", + "grand_exchange_price": "1618", + "durability": null, + "name": "Snake hide", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "7801" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "1618", + "durability": null, + "name": "Snake hide", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7802" + }, + { + "shop_price": "100", + "examine": "A non-magical copy of the make-over mage's amulet.", + "durability": null, + "name": "Yin yang amulet", + "archery_ticket_price": "0", + "id": "7803", + "equipment_slot": "2" + }, + { + "turn90cw_anim": "1207", + "walk_anim": "1205", + "durability": null, + "turn90ccw_anim": "1208", + "two_handed": "true", + "weapon_interface": "3", + "turn180_anim": "1206", + "render_anim": "28", + "equipment_slot": "3", + "stand_anim": "813", + "name": "Picture", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "7804", + "stand_turn_anim": "1209", + "bonuses": "0,0,11,0,0,0,0,0,0,0,0,14,0,0,0" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7805" + }, + { + "attack_anims": "381,390,390,390", + "examine": "A heavy duty sword.", + "durability": null, + "name": "Anger sword", + "archery_ticket_price": "0", + "attack_speed": "3", + "id": "7806", + "weapon_interface": "5", + "bonuses": "20,20,20,0,0,0,2,1,0,0,0,5,0,0,0", + "defence_anim": "397", + "equipment_slot": "3" + }, + { + "attack_anims": "395,395,401,395", + "examine": "A heavy duty axe.", + "durability": null, + "attack_audios": "2498,2498,2497,2498", + "name": "Anger battleaxe", + "archery_ticket_price": "0", + "id": "7807", + "weapon_interface": "2", + "bonuses": "20,20,20,0,0,0,0,0,0,-1,0,13,0,0,0", + "equip_audio": "2232", + "defence_anim": "397", + "equipment_slot": "3" + }, + { + "attack_anims": "390,390,381,390", + "examine": "A heavy duty mace.", + "durability": null, + "name": "Anger mace", + "archery_ticket_price": "0", + "id": "7808", + "weapon_interface": "8", + "bonuses": "20,20,20,0,0,0,0,0,0,0,0,5,1,0,0", + "defence_anim": "397", + "equipment_slot": "3" + }, + { + "turn90cw_anim": "1207", + "examine": "A heavy duty spear.", + "walk_anim": "1205", + "durability": null, + "turn90ccw_anim": "1208", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1206", + "equip_audio": "2247", + "render_anim": "28", + "defence_anim": "2079", + "equipment_slot": "3", + "attack_anims": "2080,2081,2082,2080", + "stand_anim": "813", + "name": "Anger spear", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "7809", + "stand_turn_anim": "1209", + "bonuses": "20,20,20,0,0,1,1,0,0,0,0,6,0,0,0" + }, + { + "shop_price": "1", + "examine": "This wine clearly did not age well.", + "durability": null, + "name": "Jug of vinegar", + "weight": "1", + "archery_ticket_price": "0", + "id": "7810" + }, + { + "examine": "Well, this pot is certainly full of vinegar and no mistake.", + "durability": null, + "name": "Pot of vinegar", + "weight": "1.3", + "archery_ticket_price": "0", + "id": "7811" + }, + { + "examine": "This needs a good polish.", + "durability": null, + "name": "Goblin skull", + "archery_ticket_price": "0", + "id": "7812" + }, + { + "examine": "There is a goblin bone in here.", + "durability": null, + "name": "Bone in vinegar", + "weight": "1", + "archery_ticket_price": "0", + "id": "7813" + }, + { + "examine": "This belongs in a museum!", + "durability": null, + "name": "Goblin skull", + "archery_ticket_price": "0", + "id": "7814" + }, + { + "examine": "This needs a good polish.", + "durability": null, + "name": "Bear ribs", + "archery_ticket_price": "0", + "id": "7815" + }, + { + "examine": "There is a bear bone in here.", + "durability": null, + "name": "Bone in vinegar", + "weight": "1", + "archery_ticket_price": "0", + "id": "7816" + }, + { + "examine": "This belongs in a museum!", + "durability": null, + "name": "Bear ribs", + "archery_ticket_price": "0", + "id": "7817" + }, + { + "examine": "This needs a good polish.", + "durability": null, + "name": "Ram skull", + "archery_ticket_price": "0", + "id": "7818" + }, + { + "examine": "There is a ram bone in here.", + "durability": null, + "name": "Bone in vinegar", + "weight": "1", + "archery_ticket_price": "0", + "id": "7819" + }, + { + "examine": "This belongs in a museum!", + "durability": null, + "name": "Ram skull", + "archery_ticket_price": "0", + "id": "7820" + }, + { + "examine": "This needs a good polish.", + "durability": null, + "name": "Unicorn bone", + "archery_ticket_price": "0", + "id": "7821" + }, + { + "examine": "There is a unicorn bone in here.", + "durability": null, + "name": "Bone in vinegar", + "weight": "1", + "archery_ticket_price": "0", + "id": "7822" + }, + { + "examine": "This belongs in a museum!", + "durability": null, + "name": "Unicorn bone", + "archery_ticket_price": "0", + "id": "7823" + }, + { + "examine": "This needs a good polish.", + "durability": null, + "name": "Giant rat bone", + "archery_ticket_price": "0", + "id": "7824" + }, + { + "examine": "There is a giant rat bone in here.", + "durability": null, + "name": "Bone in vinegar", + "weight": "1", + "archery_ticket_price": "0", + "id": "7825" + }, + { + "examine": "This belongs in a museum!", + "durability": null, + "name": "Giant rat bone", + "archery_ticket_price": "0", + "id": "7826" + }, + { + "examine": "This needs a good polish.", + "durability": null, + "name": "Giant bat wing", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7827" + }, + { + "examine": "There is a giant bat bone in here.", + "durability": null, + "name": "Bone in vinegar", + "weight": "1", + "archery_ticket_price": "0", + "id": "7828" + }, + { + "examine": "This belongs in a museum!", + "durability": null, + "name": "Giant bat wing", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7829" + }, + { + "examine": "This needs a good polish.", + "durability": null, + "name": "Wolf bone", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7830" + }, + { + "examine": "There is a wolf bone in here.", + "durability": null, + "name": "Bone in vinegar", + "weight": "1", + "archery_ticket_price": "0", + "id": "7831" + }, + { + "examine": "This belongs in a museum!", + "durability": null, + "name": "Wolf bone", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7832" + }, + { + "examine": "This needs a good polish.", + "durability": null, + "name": "Bat wing", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7833" + }, + { + "examine": "There is a bat bone in here.", + "durability": null, + "name": "Bone in vinegar", + "weight": "1", + "archery_ticket_price": "0", + "id": "7834" + }, + { + "examine": "This belongs in a museum!", + "durability": null, + "name": "Bat wing", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7835" + }, + { + "examine": "This needs a good polish.", + "durability": null, + "name": "Rat bone", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7836" + }, + { + "examine": "There is a rat bone in here.", + "durability": null, + "name": "Bone in vinegar", + "weight": "1", + "archery_ticket_price": "0", + "id": "7837" + }, + { + "examine": "This belongs in a museum!", + "durability": null, + "name": "Rat bone", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7838" + }, + { + "examine": "This needs a good polish.", + "durability": null, + "name": "Baby dragon bone", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7839" + }, + { + "examine": "There is a baby blue dragon bone in here.", + "durability": null, + "name": "Bone in vinegar", + "weight": "1", + "archery_ticket_price": "0", + "id": "7840" + }, + { + "examine": "This belongs in a museum!", + "durability": null, + "name": "Baby dragon bone", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7841" + }, + { + "examine": "This needs a good polish.", + "durability": null, + "name": "Ogre ribs", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7842" + }, + { + "examine": "There is a ogre bone in here.", + "durability": null, + "name": "Bone in vinegar", + "weight": "1", + "archery_ticket_price": "0", + "id": "7843" + }, + { + "examine": "This belongs in a museum!", + "durability": null, + "name": "Ogre ribs", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7844" + }, + { + "examine": "This needs a good polish.", + "durability": null, + "name": "Jogre bone", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7845" + }, + { + "examine": "There is a jogre bone in here.", + "durability": null, + "name": "Bone in vinegar", + "weight": "1", + "archery_ticket_price": "0", + "id": "7846" + }, + { + "examine": "This belongs in a museum!", + "durability": null, + "name": "Jogre bone", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7847" + }, + { + "examine": "This needs a good polish.", + "durability": null, + "name": "Zogre bone", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7848" + }, + { + "examine": "There is a zogre bone in here.", + "durability": null, + "name": "Bone in vinegar", + "weight": "1", + "archery_ticket_price": "0", + "id": "7849" + }, + { + "examine": "This belongs in a museum!", + "durability": null, + "name": "Zogre bone", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7850" + }, + { + "examine": "This needs a good polish.", + "durability": null, + "name": "Mogre bone", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7851" + }, + { + "examine": "There is a mogre bone in here.", + "durability": null, + "name": "Bone in vinegar", + "weight": "1", + "archery_ticket_price": "0", + "id": "7852" + }, + { + "examine": "This belongs in a museum!", + "durability": null, + "name": "Mogre bone", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7853" + }, + { + "examine": "This needs a good polish.", + "durability": null, + "name": "Monkey paw", + "archery_ticket_price": "0", + "id": "7854" + }, + { + "examine": "There is a monkey bone in here.", + "durability": null, + "name": "Bone in vinegar", + "weight": "1", + "archery_ticket_price": "0", + "id": "7855" + }, + { + "examine": "This belongs in a museum!", + "durability": null, + "name": "Monkey paw", + "archery_ticket_price": "0", + "id": "7856" + }, + { + "examine": "This needs a good polish.", + "durability": null, + "name": "Dagannoth ribs", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7857" + }, + { + "examine": "There is a Dagannoth bone in here.", + "durability": null, + "name": "Bone in vinegar", + "weight": "1", + "archery_ticket_price": "0", + "id": "7858" + }, + { + "examine": "This belongs in a museum!", + "durability": null, + "name": "Dagannoth ribs", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7859" + }, + { + "examine": "This needs a good polish.", + "durability": null, + "name": "Snake spine", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7860" + }, + { + "examine": "There is a snake bone in here.", + "durability": null, + "name": "Bone in vinegar", + "weight": "1", + "archery_ticket_price": "0", + "id": "7861" + }, + { + "examine": "This belongs in a museum!", + "durability": null, + "name": "Snake spine", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7862" + }, + { + "examine": "This needs a good polish.", + "durability": null, + "name": "Zombie bone", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7863" + }, + { + "examine": "There is a zombie bone in here.", + "durability": null, + "name": "Bone in vinegar", + "weight": "1", + "archery_ticket_price": "0", + "id": "7864" + }, + { + "examine": "This belongs in a museum!", + "durability": null, + "name": "Zombie bone", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7865" + }, + { + "examine": "This needs a good polish.", + "durability": null, + "name": "Werewolf bone", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7866" + }, + { + "examine": "There is a werewolf bone in here.", + "durability": null, + "name": "Bone in vinegar", + "weight": "1", + "archery_ticket_price": "0", + "id": "7867" + }, + { + "examine": "This belongs in a museum!", + "durability": null, + "name": "Werewolf bone", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7868" + }, + { + "examine": "This needs a good polish.", + "durability": null, + "name": "Moss giant bone", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7869" + }, + { + "examine": "There is a moss giant bone in here.", + "durability": null, + "name": "Bone in vinegar", + "weight": "1", + "archery_ticket_price": "0", + "id": "7870" + }, + { + "examine": "This belongs in a museum!", + "durability": null, + "name": "Moss giant bone", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7871" + }, + { + "examine": "This needs a good polish.", + "durability": null, + "name": "Fire giant bone", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7872" + }, + { + "examine": "There is a fire giant bone in here.", + "durability": null, + "name": "Bone in vinegar", + "weight": "1", + "archery_ticket_price": "0", + "id": "7873" + }, + { + "examine": "This bone belongs in a museum!", + "durability": null, + "name": "Fire giant bone", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7874" + }, + { + "examine": "This needs a good polish.", + "durability": null, + "name": "Ice giant ribs", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7875" + }, + { + "examine": "There is an ice giant bone in here.", + "durability": null, + "name": "Bone in vinegar", + "weight": "1", + "archery_ticket_price": "0", + "id": "7876" + }, + { + "examine": "This belongs in a museum!", + "durability": null, + "name": "Ice giant ribs", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7877" + }, + { + "examine": "This needs a good polish.", + "durability": null, + "name": "Terrorbird wing", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7878" + }, + { + "examine": "There is a terrorbird bone in here.", + "durability": null, + "name": "Bone in vinegar", + "weight": "1", + "archery_ticket_price": "0", + "id": "7879" + }, + { + "examine": "This belongs in a museum!", + "durability": null, + "name": "Terrorbird wing", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7880" + }, + { + "examine": "This needs a good polish.", + "durability": null, + "name": "Ghoul bone", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7881" + }, + { + "examine": "There is a ghoul bone in here.", + "durability": null, + "name": "Bone in vinegar", + "weight": "1", + "archery_ticket_price": "0", + "id": "7882" + }, + { + "examine": "This belongs in a museum!", + "durability": null, + "name": "Ghoul bone", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7883" + }, + { + "examine": "This needs a good polish.", + "durability": null, + "name": "Troll bone", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7884" + }, + { + "examine": "There is a troll bone in here.", + "durability": null, + "name": "Bone in vinegar", + "weight": "1", + "archery_ticket_price": "0", + "id": "7885" + }, + { + "examine": "This belongs in a museum!", + "durability": null, + "name": "Troll bone", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7886" + }, + { + "examine": "This needs a good polish.", + "durability": null, + "name": "Seagull wing", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7887" + }, + { + "examine": "There is a seagull bone in here.", + "durability": null, + "name": "Bone in vinegar", + "weight": "1", + "archery_ticket_price": "0", + "id": "7888" + }, + { + "examine": "This belongs in a museum!", + "durability": null, + "name": "Seagull wing", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7889" + }, + { + "examine": "This needs a good polish.", + "durability": null, + "name": "Undead cow ribs", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7890" + }, + { + "examine": "There is an undead cow bone in here.", + "durability": null, + "name": "Bone in vinegar", + "weight": "1", + "archery_ticket_price": "0", + "id": "7891" + }, + { + "examine": "This belongs in a museum!", + "durability": null, + "name": "Undead cow ribs", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7892" + }, + { + "shop_price": "160", + "examine": "This needs a good polish.", + "durability": null, + "name": "Experiment bone", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7893" + }, + { + "examine": "There is an experiment bone in here.", + "durability": null, + "name": "Bone in vinegar", + "weight": "1", + "archery_ticket_price": "0", + "id": "7894" + }, + { + "shop_price": "160", + "examine": "This belongs in a museum!", + "durability": null, + "name": "Experiment bone", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7895" + }, + { + "examine": "This needs a good polish.", + "durability": null, + "name": "Rabbit bone", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7896" + }, + { + "examine": "There is a rabbit bone in here.", + "durability": null, + "name": "Bone in vinegar", + "weight": "1", + "archery_ticket_price": "0", + "id": "7897" + }, + { + "examine": "This belongs in a museum!", + "durability": null, + "name": "Rabbit bone", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7898" + }, + { + "examine": "This bone needs a good polish.", + "durability": null, + "name": "Basilisk bone", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7899" + }, + { + "examine": "There is a basilisk bone in here.", + "durability": null, + "name": "Bone in vinegar", + "weight": "1", + "archery_ticket_price": "0", + "id": "7900" + }, + { + "examine": "This belongs in a museum!", + "durability": null, + "name": "Basilisk bone", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7901" + }, + { + "examine": "This needs a good polish.", + "durability": null, + "name": "Desert lizard bone", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7902" + }, + { + "examine": "There is a desert lizard bone in here.", + "durability": null, + "name": "Bone in vinegar", + "weight": "1", + "archery_ticket_price": "0", + "id": "7903" + }, + { + "examine": "This belongs in a museum!", + "durability": null, + "name": "Desert lizard bone", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7904" + }, + { + "examine": "This needs a good polish.", + "durability": null, + "name": "Cave goblin skull", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7905" + }, + { + "examine": "There is a cave goblin bone in here.", + "durability": null, + "name": "Bone in vinegar", + "weight": "1", + "archery_ticket_price": "0", + "id": "7906" + }, + { + "examine": "This belongs in a museum!", + "durability": null, + "name": "Cave goblin skull", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7907" + }, + { + "examine": "This needs a good polish.", + "durability": null, + "name": "Big frog leg", + "weight": "1", + "archery_ticket_price": "0", + "id": "7908" + }, + { + "examine": "There is a big frog bone in here.", + "durability": null, + "name": "Bone in vinegar", + "weight": "1", + "archery_ticket_price": "0", + "id": "7909" + }, + { + "examine": "This belongs in a museum!", + "durability": null, + "name": "Big frog leg", + "weight": "1", + "archery_ticket_price": "0", + "id": "7910" + }, + { + "examine": "This needs a good polish.", + "durability": null, + "name": "Vulture wing", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7911" + }, + { + "examine": "There is a vulture bone in here.", + "durability": null, + "name": "Bone in vinegar", + "weight": "1", + "archery_ticket_price": "0", + "id": "7912" + }, + { + "examine": "This belongs in a museum!", + "durability": null, + "name": "Vulture wing", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7913" + }, + { + "examine": "This needs a good polish.", + "durability": null, + "name": "Jackal bone", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7914" + }, + { + "examine": "There is a jackal bone in here.", + "durability": null, + "name": "Bone in vinegar", + "weight": "1", + "archery_ticket_price": "0", + "id": "7915" + }, + { + "examine": "This belongs in a museum!", + "durability": null, + "name": "Jackal bone", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "7916" + }, + { + "destroy_message": "The ram skull helm looks like it will fall apart if you drop it. You would have to go to the Odd Old Man for a replacement.", + "examine": "Makes me feel baaad to the bone.", + "durability": null, + "name": "Ram skull helm", + "weight": "3", + "archery_ticket_price": "0", + "id": "7917", + "bonuses": "0,0,0,0,-2,19,21,16,0,19,6,0,0,0,0", + "equipment_slot": "0" + }, + { + "destroy_message": "The bonesack looks like it will fall apart if you drop it. You would have to go to the Odd Old Man for a replacement.", + "examine": "The Bonesack is a little old item that protects like leather.", + "durability": null, + "name": "Bonesack", + "weight": "9", + "archery_ticket_price": "0", + "id": "7918", + "bonuses": "0,0,0,0,0,4,4,4,4,4,4,0,0,0,0", + "equipment_slot": "1" + }, + { + "shop_price": "500", + "examine": "A very good vintage.", + "durability": null, + "name": "Bottle of wine", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "7919" + }, + { + "durability": null, + "name": "Bottle of wine", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7920" + }, + { + "examine": "This one has clearly been taken down and passed around.", + "durability": null, + "name": "Empty wine bottle", + "weight": "1", + "archery_ticket_price": "0", + "id": "7921" + }, + { + "examine": "The money off voucher has expired.", + "durability": null, + "name": "Al kharid flyer", + "archery_ticket_price": "0", + "id": "7922" + }, + { + "examine": "A ring given to you by the Easter Bunny.", + "durability": null, + "attack_audios": "", + "name": "Easter ring", + "archery_ticket_price": "0", + "id": "7927", + "equip_audio": "", + "equipment_slot": "12" + }, + { + "examine": "Happy Easter.", + "grand_exchange_price": "64747137", + "durability": null, + "name": "Easter egg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7928" + }, + { + "examine": "Happy Easter.", + "grand_exchange_price": "64747137", + "durability": null, + "name": "Easter egg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7929" + }, + { + "examine": "Happy Easter.", + "grand_exchange_price": "64747137", + "durability": null, + "name": "Easter egg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7930" + }, + { + "examine": "Happy Easter.", + "grand_exchange_price": "64747137", + "durability": null, + "name": "Easter egg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7931" + }, + { + "examine": "Happy Easter.", + "grand_exchange_price": "64747137", + "durability": null, + "name": "Easter egg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7932" + }, + { + "examine": "Happy Easter.", + "grand_exchange_price": "64747137", + "durability": null, + "name": "Easter egg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7933" + }, + { + "shop_price": "390", + "ge_buy_limit": "100", + "examine": "A field ration to help your wounds go away.", + "grand_exchange_price": "171", + "durability": null, + "name": "Field ration", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7934" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "171", + "durability": null, + "name": "Field ration", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7935" + }, + { + "shop_price": "1", + "ge_buy_limit": "25000", + "examine": "An uncharged Rune Stone of extra capability.", + "grand_exchange_price": "180", + "durability": null, + "name": "Pure essence", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7936" + }, + { + "ge_buy_limit": "25000", + "grand_exchange_price": "109", + "durability": null, + "name": "Pure essence", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7937" + }, + { + "ge_buy_limit": "5000", + "examine": "A word in your shell-like.", + "grand_exchange_price": "13600", + "durability": null, + "name": "Tortoise shell", + "tradeable": "true", + "weight": "6.8", + "archery_ticket_price": "0", + "id": "7939" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "13600", + "durability": null, + "name": "Tortoise shell", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7940" + }, + { + "examine": "A sturdy sheet of iron.", + "durability": null, + "name": "Iron sheet", + "weight": "1.75", + "archery_ticket_price": "0", + "id": "7941" + }, + { + "examine": "Perfect for storing. Not so good for eating.", + "durability": null, + "name": "Fresh monkfish", + "weight": "0.8", + "archery_ticket_price": "0", + "id": "7942" + }, + { + "examine": "Perfect for storing. Not so good for eating.", + "durability": null, + "name": "Fresh monkfish", + "weight": "0.8", + "archery_ticket_price": "0", + "id": "7943" + }, + { + "ge_buy_limit": "20000", + "examine": "I should try cooking this.", + "grand_exchange_price": "618", + "durability": null, + "name": "Raw monkfish", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "7944" + }, + { + "ge_buy_limit": "20000", + "grand_exchange_price": "618", + "durability": null, + "name": "Raw monkfish", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7945" + }, + { + "ge_buy_limit": "10000", + "examine": "A tasty fish.", + "grand_exchange_price": "617", + "durability": null, + "name": "Monkfish", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "7946" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "617", + "durability": null, + "name": "Monkfish", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7947" + }, + { + "durability": null, + "name": "Burnt monkfish", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7949" + }, + { + "examine": "A highly portable army of skeletal magic.", + "durability": null, + "name": "Bone seeds", + "archery_ticket_price": "0", + "id": "7950" + }, + { + "shop_price": "160", + "examine": "A book taken from the desk of Herman Caranos.", + "durability": null, + "name": "Herman's book", + "tradeable": "false", + "destroy": "true", + "weight": "0.09", + "archery_ticket_price": "0", + "id": "7951" + }, + { + "examine": "Useless without the head.", + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7952", + "equipment_slot": "3" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7953" + }, + { + "durability": null, + "name": "Burnt shrimp", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "7955" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "7956" + }, + { + "shop_price": "2", + "examine": "A mostly clean apron.", + "grand_exchange_price": "169", + "durability": null, + "name": "White apron", + "tradeable": "true", + "weight": "0.45", + "archery_ticket_price": "0", + "id": "7957" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A prop for holding up a tunnel roof.", + "durability": null, + "name": "Mining prop", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "7958" + }, + { + "destroy_message": "You can get your box back by talking to the guard by the dungeon entrance in Etceteria.", + "examine": "A box full of stolen Etceterian items.", + "durability": null, + "name": "Heavy box", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "7959" + }, + { + "examine": "It says 'To the dungeons' on the side.", + "durability": null, + "name": "Empty box", + "archery_ticket_price": "0", + "id": "7960" + }, + { + "examine": "A diary with one/two/three/four/five page(s).", + "durability": null, + "name": "Burnt diary", + "archery_ticket_price": "0", + "id": "7961" + }, + { + "examine": "A diary with one/two/three/four/five page(s).", + "durability": null, + "name": "Burnt diary", + "archery_ticket_price": "0", + "id": "7962" + }, + { + "examine": "A diary with one/two/three/four/five page(s).", + "durability": null, + "name": "Burnt diary", + "archery_ticket_price": "0", + "id": "7963" + }, + { + "examine": "A diary with one/two/three/four/five page(s).", + "durability": null, + "name": "Burnt diary", + "archery_ticket_price": "0", + "id": "7964" + }, + { + "examine": "A diary with one/two/three/four/five page(s).", + "durability": null, + "name": "Burnt diary", + "archery_ticket_price": "0", + "id": "7965" + }, + { + "examine": "A dwarf-made coal engine. It looks very sturdy.", + "durability": null, + "name": "Engine", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "7967" + }, + { + "examine": "A beam with a pulley attached.", + "durability": null, + "name": "Pulley beam", + "archery_ticket_price": "0", + "id": "7969" + }, + { + "examine": "A long beam with a pulley attached.", + "durability": null, + "name": "Long pulley beam", + "archery_ticket_price": "0", + "id": "7970" + }, + { + "examine": "A very long beam with a pulley attached.", + "durability": null, + "name": "Longer pulley beam", + "archery_ticket_price": "0", + "id": "7971" + }, + { + "examine": "The manual for an AMCE Lift-In-A-Box.", + "durability": null, + "name": "Lift manual", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "7972" + }, + { + "examine": "A wooden beam.", + "durability": null, + "name": "Beam", + "archery_ticket_price": "0", + "id": "7973" + }, + { + "examine": "I should get it stuffed!", + "durability": null, + "name": "Crawling hand", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "7975" + }, + { + "examine": "I should get it stuffed!", + "durability": null, + "name": "Cockatrice head", + "tradeable": "false", + "destroy": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "7976" + }, + { + "examine": "I should get it stuffed!", + "durability": null, + "name": "Basilisk head", + "tradeable": "false", + "destroy": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "7977" + }, + { + "examine": "I should get it stuffed!", + "durability": null, + "name": "Kurask head", + "tradeable": "false", + "destroy": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "7978" + }, + { + "examine": "I should get it stuffed!", + "durability": null, + "name": "Abyssal head", + "tradeable": "false", + "destroy": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "7979" + }, + { + "examine": "I should get it stuffed!", + "durability": null, + "name": "Kbd heads", + "tradeable": "false", + "destroy": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "7980" + }, + { + "examine": "I should get it stuffed!", + "durability": null, + "name": "Kq head", + "archery_ticket_price": "0", + "id": "7981" + }, + { + "examine": "I could mount this on my wall!", + "durability": null, + "name": "Crawling hand", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "7982" + }, + { + "examine": "I could mount this on my wall!", + "durability": null, + "name": "Cockatrice head", + "tradeable": "false", + "destroy": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "7983" + }, + { + "examine": "I could mount this on my wall!", + "durability": null, + "name": "Basilisk head", + "tradeable": "false", + "destroy": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "7984" + }, + { + "examine": "I could mount this on my wall!", + "durability": null, + "name": "Kurask head", + "tradeable": "false", + "destroy": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "7985" + }, + { + "examine": "I could mount this on my wall!", + "durability": null, + "name": "Abyssal head", + "tradeable": "false", + "destroy": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "7986" + }, + { + "examine": "I could mount these on my wall!", + "durability": null, + "name": "Kbd heads", + "tradeable": "false", + "destroy": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "7987" + }, + { + "examine": "I could mount this on my wall!", + "durability": null, + "name": "Kq head", + "archery_ticket_price": "0", + "id": "7988" + }, + { + "examine": "Whopper! I should get this stuffed!", + "durability": null, + "name": "Big bass", + "weight": "6", + "archery_ticket_price": "0", + "id": "7989" + }, + { + "examine": "I should mount this on my wall!", + "durability": null, + "name": "Big bass", + "weight": "6", + "archery_ticket_price": "0", + "id": "7990" + }, + { + "examine": "Whopper! I should get this stuffed!", + "durability": null, + "name": "Big swordfish", + "archery_ticket_price": "0", + "id": "7991" + }, + { + "examine": "I should mount this on my wall!", + "durability": null, + "name": "Big swordfish", + "archery_ticket_price": "0", + "id": "7992" + }, + { + "examine": "It's a monster! I should get this stuffed!", + "durability": null, + "name": "Big shark", + "weight": "0.7", + "archery_ticket_price": "0", + "id": "7993" + }, + { + "examine": "I should mount this on my wall!", + "durability": null, + "name": "Big shark", + "weight": "0.7", + "archery_ticket_price": "0", + "id": "7994" + }, + { + "examine": "A portrait of King Arthur.", + "durability": null, + "name": "Arthur portrait", + "weight": "1", + "archery_ticket_price": "0", + "id": "7995" + }, + { + "shop_price": "1000", + "examine": "A portrait of Elena.", + "durability": null, + "name": "Elena portrait", + "weight": "1", + "archery_ticket_price": "0", + "id": "7996" + }, + { + "examine": "A painting of the staute of King Alvis of Keldagrim", + "durability": null, + "name": "Keldagrim portrait", + "weight": "1", + "archery_ticket_price": "0", + "id": "7997" + }, + { + "examine": "A portrait of Prince Brand and Princess Astrid of Miscellania.", + "durability": null, + "name": "Misc. portrait", + "weight": "1", + "archery_ticket_price": "0", + "id": "7998" + }, + { + "shop_price": "2000", + "examine": "The exotic land of the Elves.", + "durability": null, + "name": "Isafdar painting", + "archery_ticket_price": "0", + "id": "8000" + }, + { + "shop_price": "2000", + "examine": "The tropical coast of karamja.", + "durability": null, + "name": "Karamja painting", + "archery_ticket_price": "0", + "id": "8001" + }, + { + "shop_price": "2000", + "examine": "Oxtable's famous painting of the Lumbridge water mill.", + "durability": null, + "name": "Lumbridge painting", + "weight": "1", + "archery_ticket_price": "0", + "id": "8002" + }, + { + "shop_price": "2000", + "examine": "A painting of the spooky forests of morytania.", + "durability": null, + "name": "Morytania painting", + "weight": "1", + "archery_ticket_price": "0", + "id": "8003" + }, + { + "shop_price": "2500", + "ge_buy_limit": "1000", + "examine": "A tablet containing a magic spell.", + "grand_exchange_price": "1341", + "durability": null, + "name": "Varrock teleport", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8007" + }, + { + "shop_price": "2500", + "ge_buy_limit": "1000", + "examine": "A tablet containing a magic spell.", + "grand_exchange_price": "1371", + "durability": null, + "name": "Lumbridge teleport", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8008" + }, + { + "shop_price": "2500", + "ge_buy_limit": "1000", + "examine": "A tablet containing a magic spell.", + "grand_exchange_price": "1414", + "durability": null, + "name": "Falador teleport", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "id": "8009" + }, + { + "shop_price": "2500", + "ge_buy_limit": "1000", + "examine": "A tablet containing a magic spell.", + "grand_exchange_price": "1369", + "durability": null, + "name": "Camelot teleport", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8010" + }, + { + "shop_price": "2500", + "ge_buy_limit": "1000", + "examine": "A tablet containing a magic spell.", + "grand_exchange_price": "1511", + "durability": null, + "name": "Ardougne teleport", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8011" + }, + { + "shop_price": "2500", + "ge_buy_limit": "1000", + "examine": "A tablet containing a magic spell.", + "grand_exchange_price": "1025", + "durability": null, + "name": "Watchtower t'port", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8012" + }, + { + "ge_buy_limit": "1000", + "examine": "A tablet containing a magic spell.", + "grand_exchange_price": "1426", + "durability": null, + "name": "Teleport to house", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8013" + }, + { + "ge_buy_limit": "200", + "examine": "A tablet containing a magic spell.", + "grand_exchange_price": "360", + "durability": null, + "name": "Bones to bananas", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8014" + }, + { + "ge_buy_limit": "200", + "examine": "A tablet containing a magic spell.", + "grand_exchange_price": "620", + "durability": null, + "name": "Bones to peaches", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8015" + }, + { + "ge_buy_limit": "1000", + "examine": "A tablet containing a magic spell.", + "grand_exchange_price": "343", + "durability": null, + "name": "Enchant sapphire", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8016" + }, + { + "ge_buy_limit": "1000", + "examine": "A tablet containing a magic spell.", + "grand_exchange_price": "409", + "durability": null, + "name": "Enchant emerald", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8017" + }, + { + "ge_buy_limit": "1000", + "examine": "A tablet containing a magic spell.", + "grand_exchange_price": "207", + "durability": null, + "name": "Enchant ruby", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8018" + }, + { + "ge_buy_limit": "1000", + "examine": "A tablet containing a magic spell.", + "grand_exchange_price": "326", + "durability": null, + "name": "Enchant diamond", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8019" + }, + { + "ge_buy_limit": "1000", + "examine": "A tablet containing a magic spell.", + "grand_exchange_price": "250", + "durability": null, + "name": "Enchant dragonstn.", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8020" + }, + { + "ge_buy_limit": "1000", + "examine": "A tablet containing a magic spell.", + "grand_exchange_price": "31", + "durability": null, + "name": "Enchant onyx", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8021" + }, + { + "grand_exchange_price": "1918", + "durability": null, + "name": "Wooden bed", + "archery_ticket_price": "0", + "id": "8031" + }, + { + "grand_exchange_price": "1631", + "durability": null, + "name": "Oak bed", + "archery_ticket_price": "0", + "id": "8032" + }, + { + "grand_exchange_price": "1388", + "durability": null, + "name": "Large oak bed", + "archery_ticket_price": "0", + "id": "8033" + }, + { + "grand_exchange_price": "1376", + "durability": null, + "name": "Teak bed", + "archery_ticket_price": "0", + "id": "8034" + }, + { + "grand_exchange_price": "1996", + "durability": null, + "name": "Large teak bed", + "archery_ticket_price": "0", + "id": "8035" + }, + { + "grand_exchange_price": "1314", + "durability": null, + "name": "4-poster", + "archery_ticket_price": "0", + "id": "8036" + }, + { + "grand_exchange_price": "274779", + "durability": null, + "name": "Gilded 4-poster", + "archery_ticket_price": "0", + "id": "8037" + }, + { + "grand_exchange_price": "18", + "durability": null, + "name": "Shoe box", + "archery_ticket_price": "0", + "id": "8038" + }, + { + "grand_exchange_price": "42", + "durability": null, + "name": "Oak drawers", + "archery_ticket_price": "0", + "id": "8039" + }, + { + "grand_exchange_price": "1", + "durability": null, + "name": "Oak wardrobe", + "archery_ticket_price": "0", + "id": "8040" + }, + { + "grand_exchange_price": "126", + "durability": null, + "name": "Teak drawers", + "archery_ticket_price": "0", + "id": "8041" + }, + { + "grand_exchange_price": "12", + "durability": null, + "name": "Teak wardrobe", + "archery_ticket_price": "0", + "id": "8042" + }, + { + "grand_exchange_price": "102", + "durability": null, + "name": "Mahogany 'drobe", + "archery_ticket_price": "0", + "id": "8043" + }, + { + "grand_exchange_price": "139452", + "durability": null, + "name": "Gilded wardrobe", + "archery_ticket_price": "0", + "id": "8044" + }, + { + "grand_exchange_price": "510", + "durability": null, + "name": "Shaving stand", + "archery_ticket_price": "0", + "id": "8045" + }, + { + "grand_exchange_price": "449", + "durability": null, + "name": "Oak shaving stand", + "archery_ticket_price": "0", + "id": "8046" + }, + { + "grand_exchange_price": "147", + "durability": null, + "name": "Oak dresser", + "archery_ticket_price": "0", + "id": "8047" + }, + { + "grand_exchange_price": "478", + "durability": null, + "name": "Teak dresser", + "archery_ticket_price": "0", + "id": "8048" + }, + { + "grand_exchange_price": "456", + "durability": null, + "name": "Fancy teak dresser", + "archery_ticket_price": "0", + "id": "8049" + }, + { + "grand_exchange_price": "404", + "durability": null, + "name": "Mahogany dresser", + "archery_ticket_price": "0", + "id": "8050" + }, + { + "grand_exchange_price": "140594", + "durability": null, + "name": "Gilded dresser", + "archery_ticket_price": "0", + "id": "8051" + }, + { + "grand_exchange_price": "367", + "durability": null, + "name": "Oak clock", + "archery_ticket_price": "0", + "id": "8052" + }, + { + "grand_exchange_price": "552", + "durability": null, + "name": "Teak clock", + "archery_ticket_price": "0", + "id": "8053" + }, + { + "grand_exchange_price": "154310", + "durability": null, + "name": "Gilded clock", + "archery_ticket_price": "0", + "id": "8054" + }, + { + "examine": "When unanimated: A dusty old suit of armour. When animated: Aaargh, it's alive!", + "durability": null, + "name": "Suit of armour", + "archery_ticket_price": "0", + "id": "8085" + }, + { + "grand_exchange_price": "13", + "durability": null, + "name": "Wooden bench", + "archery_ticket_price": "0", + "id": "8108" + }, + { + "grand_exchange_price": "131", + "durability": null, + "name": "Oak bench", + "archery_ticket_price": "0", + "id": "8109" + }, + { + "grand_exchange_price": "1", + "durability": null, + "name": "Carved oak bench", + "archery_ticket_price": "0", + "id": "8110" + }, + { + "grand_exchange_price": "17", + "durability": null, + "name": "Teak dining bench", + "archery_ticket_price": "0", + "id": "8111" + }, + { + "grand_exchange_price": "2", + "durability": null, + "name": "Carved teak bench", + "archery_ticket_price": "0", + "id": "8112" + }, + { + "grand_exchange_price": "145", + "durability": null, + "name": "Mahogany bench", + "archery_ticket_price": "0", + "id": "8113" + }, + { + "grand_exchange_price": "531526", + "durability": null, + "name": "Gilded bench", + "archery_ticket_price": "0", + "id": "8114" + }, + { + "grand_exchange_price": "1", + "durability": null, + "name": "Wood dining table", + "archery_ticket_price": "0", + "id": "8115" + }, + { + "grand_exchange_price": "1", + "durability": null, + "name": "Oak dining table", + "archery_ticket_price": "0", + "id": "8116" + }, + { + "grand_exchange_price": "1", + "durability": null, + "name": "Carved oak table", + "archery_ticket_price": "0", + "id": "8117" + }, + { + "grand_exchange_price": "2", + "durability": null, + "name": "Teak table", + "archery_ticket_price": "0", + "id": "8118" + }, + { + "grand_exchange_price": "249", + "durability": null, + "name": "Carved teak table", + "archery_ticket_price": "0", + "id": "8119" + }, + { + "grand_exchange_price": "497", + "durability": null, + "name": "Mahogany table", + "archery_ticket_price": "0", + "id": "8120" + }, + { + "grand_exchange_price": "394177", + "durability": null, + "name": "Opulent table", + "archery_ticket_price": "0", + "id": "8121" + }, + { + "shop_price": "24", + "examine": "A candle.", + "grand_exchange_price": "104", + "durability": null, + "name": "Candles", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8128" + }, + { + "durability": null, + "name": "Skeleton guard", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "8131" + }, + { + "examine": "He doesn't seem pleased to see me./Beware of the dog! (Construction)", + "durability": null, + "name": "Guard dog", + "archery_ticket_price": "0", + "id": "8132" + }, + { + "examine": "He doesn't look very welcoming.", + "durability": null, + "name": "Hobgoblin guard", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "8133" + }, + { + "examine": "Young but still dangerous.", + "durability": null, + "name": "Baby red dragon", + "archery_ticket_price": "0", + "id": "8134" + }, + { + "examine": "No spider could grow that big! It's unrealistic!", + "durability": null, + "name": "Huge spider", + "archery_ticket_price": "0", + "id": "8135" + }, + { + "examine": "(Level 122)", + "durability": null, + "name": "Hellhound", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "8137" + }, + { + "examine": "I don't think insect repellent will work...", + "durability": null, + "name": "Kalphite soldier", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "8139" + }, + { + "examine": "The Tok-Xil fires deadly spines out of its arm, projected by its own heat.", + "durability": null, + "name": "Tok-xil", + "archery_ticket_price": "0", + "id": "8140" + }, + { + "examine": "Its scales seem to be made of steel.", + "durability": null, + "name": "Steel dragon", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "8142" + }, + { + "shop_price": "5000", + "examine": "You can plant this in your garden.", + "durability": null, + "name": "Thorny hedge", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8203" + }, + { + "shop_price": "10000", + "examine": "You can plant this in your garden.", + "durability": null, + "name": "Nice hedge", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8204" + }, + { + "shop_price": "15000", + "examine": "You can plant this in your garden.", + "durability": null, + "name": "Small box hedge", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8205" + }, + { + "shop_price": "20000", + "examine": "You can plant this in your garden.", + "durability": null, + "name": "Topiary hedge", + "tradeable": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "8206" + }, + { + "shop_price": "25000", + "examine": "You can plant this in your garden.", + "durability": null, + "name": "Fancy hedge", + "weight": "10", + "archery_ticket_price": "0", + "id": "8207" + }, + { + "shop_price": "50000", + "examine": "You can plant this in your garden.", + "durability": null, + "name": "Tall fancy hedge", + "archery_ticket_price": "0", + "id": "8208" + }, + { + "examine": "Some rosemary.", + "grand_exchange_price": "20", + "durability": null, + "name": "Rosemary", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8210" + }, + { + "examine": "A bunch of marigolds.", + "grand_exchange_price": "3862", + "durability": null, + "name": "Marigolds", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8214" + }, + { + "grand_exchange_price": "1", + "durability": null, + "name": "Beer barrel", + "archery_ticket_price": "0", + "id": "8239" + }, + { + "grand_exchange_price": "16860", + "durability": null, + "name": "Cider barrel", + "archery_ticket_price": "0", + "id": "8240" + }, + { + "shop_price": "3", + "examine": "Probably the finest readily-available ale in Asgarnia.", + "grand_exchange_price": "131", + "durability": null, + "name": "Asgarnian ale", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8241" + }, + { + "shop_price": "2", + "examine": "A glass of frothy ale.", + "grand_exchange_price": "569", + "durability": null, + "name": "Greenman's ale", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8242" + }, + { + "shop_price": "2", + "examine": "A glass of bitter.", + "grand_exchange_price": "523", + "durability": null, + "name": "Dragon bitter", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "8243" + }, + { + "examine": "A fruity, full-bodied ale.", + "grand_exchange_price": "2371", + "durability": null, + "name": "Chef's delight", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8244" + }, + { + "grand_exchange_price": "1", + "durability": null, + "name": "Wood kitchen table", + "archery_ticket_price": "0", + "id": "8246" + }, + { + "grand_exchange_price": "1", + "durability": null, + "name": "Oak kitchen table", + "archery_ticket_price": "0", + "id": "8247" + }, + { + "grand_exchange_price": "1", + "durability": null, + "name": "Teak kitchen table", + "archery_ticket_price": "0", + "id": "8248" + }, + { + "examine": "A trophy of a mighty slayer!", + "durability": null, + "name": "Crawling hand", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "8260" + }, + { + "examine": "A trophy of a mighty slayer!", + "durability": null, + "name": "Cockatrice head", + "tradeable": "false", + "destroy": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "8261" + }, + { + "examine": "A trophy of a mighty slayer!", + "durability": null, + "name": "Basilisk head", + "tradeable": "false", + "destroy": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "8262" + }, + { + "examine": "A trophy of a mighty slayer!", + "durability": null, + "name": "Kurask head", + "tradeable": "false", + "destroy": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "8263" + }, + { + "examine": "A trophy of a mighty slayer!!", + "durability": null, + "name": "Abyssal head", + "tradeable": "false", + "destroy": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "8264" + }, + { + "examine": "A trophy of a mighty dragon-slayer!", + "durability": null, + "name": "Kbd heads", + "tradeable": "false", + "destroy": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "8265" + }, + { + "examine": "A trophy of a mighty kalphite slayer!", + "durability": null, + "name": "Kq head", + "archery_ticket_price": "0", + "id": "8266" + }, + { + "durability": null, + "name": "Runite armour", + "archery_ticket_price": "0", + "id": "8272", + "absorb": "9,0,20", + "bonuses": "0,0,0,-65,-21,207,209,192,-12,205,102,0,0,0,0" + }, + { + "examine": "The magical sword 'Silverlight'. / The magical sword 'Silverlight', stained black with mushroom ink. (during Shadow of the Storm)", + "durability": null, + "name": "Silverlight", + "weight": "1.8", + "archery_ticket_price": "0", + "attack_speed": "5", + "id": "8279", + "bonuses": "9,14,-2,0,0,0,3,2,1,0,0,12,0,0,0" + }, + { + "examine": "This used to belong to King Arthur.", + "durability": null, + "name": "Excalibur", + "weight": "2.2", + "archery_ticket_price": "0", + "attack_speed": "5", + "id": "8280", + "bonuses": "20,29,-2,0,0,0,3,2,1,0,0,25,0,0,0" + }, + { + "examine": "The magical sword Silverlight, enhanced with the blood of Agrith-Naar.", + "durability": null, + "name": "Darklight", + "weight": "1.8", + "archery_ticket_price": "0", + "attack_speed": "5", + "id": "8281", + "bonuses": "10,16,-2,0,0,0,3,2,2,0,0,13,0,0,0" + }, + { + "examine": "This provides partial protection from dragon-breath attacks.", + "grand_exchange_price": "305", + "durability": null, + "name": "Anti-dragon shield", + "tradeable": "true", + "weight": "5.4", + "archery_ticket_price": "0", + "id": "8282", + "bonuses": "0,0,0,0,0,7,9,8,2,8,0,0,0,0,0" + }, + { + "examine": "A very powerful dragonstone amulet.", + "grand_exchange_price": "1", + "durability": null, + "name": "Amulet of glory", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8283", + "bonuses": "10,10,10,10,10,3,3,3,3,3,3,6,0,3,0" + }, + { + "shop_price": "450", + "examine": "The cape worn by members of the Legends Guild.", + "durability": null, + "name": "Cape of legends", + "weight": "1.8", + "archery_ticket_price": "0", + "id": "8284", + "bonuses": "0,0,0,0,0,7,7,7,7,7,7,0,0,0,0" + }, + { + "examine": "Legendary King of the Britons.", + "durability": null, + "name": "King arthur", + "archery_ticket_price": "0", + "id": "8285" + }, + { + "examine": "She looks concerned.", + "durability": null, + "name": "Elena", + "archery_ticket_price": "0", + "id": "8286" + }, + { + "examine": "It's full of pent-up aggression.", + "durability": null, + "name": "Rocnar", + "archery_ticket_price": "0", + "id": "8305" + }, + { + "grand_exchange_price": "1", + "durability": null, + "name": "Crude wooden chair", + "archery_ticket_price": "0", + "id": "8309" + }, + { + "grand_exchange_price": "50", + "durability": null, + "name": "Wooden chair", + "archery_ticket_price": "0", + "id": "8310" + }, + { + "grand_exchange_price": "1", + "durability": null, + "name": "Rocking chair", + "archery_ticket_price": "0", + "id": "8311" + }, + { + "grand_exchange_price": "1", + "durability": null, + "name": "Oak chair", + "archery_ticket_price": "0", + "id": "8312" + }, + { + "grand_exchange_price": "2", + "durability": null, + "name": "Oak armchair", + "archery_ticket_price": "0", + "id": "8313" + }, + { + "grand_exchange_price": "1", + "durability": null, + "name": "Teak armchair", + "archery_ticket_price": "0", + "id": "8314" + }, + { + "grand_exchange_price": "8", + "durability": null, + "name": "Mahogany armchair", + "archery_ticket_price": "0", + "id": "8315" + }, + { + "grand_exchange_price": "1", + "durability": null, + "name": "Wooden bookcase", + "archery_ticket_price": "0", + "id": "8319" + }, + { + "grand_exchange_price": "1", + "durability": null, + "name": "Oak bookcase", + "archery_ticket_price": "0", + "id": "8320" + }, + { + "grand_exchange_price": "52", + "durability": null, + "name": "Mahogany b'kcase", + "archery_ticket_price": "0", + "id": "8321" + }, + { + "requirements": "{5,22}", + "shop_price": "1000", + "examine": "You can plant this in your garden.", + "durability": null, + "name": "Bagged dead tree", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "8417" + }, + { + "durability": null, + "name": "Bagged dead tree", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8418" + }, + { + "requirements": "{10,22}", + "shop_price": "2000", + "examine": "You can plant this in your garden.", + "durability": null, + "name": "Bagged nice tree", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8419" + }, + { + "durability": null, + "name": "Bagged nice tree", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8420" + }, + { + "requirements": "{15,22}", + "examine": "You can plant this in your garden.", + "durability": null, + "name": "Bagged oak tree", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8421" + }, + { + "durability": null, + "name": "Bagged oak tree", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8422" + }, + { + "requirements": "{22,30}", + "shop_price": "10000", + "examine": "You can plant this in your garden.", + "durability": null, + "name": "Bagged willow tree", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8423" + }, + { + "durability": null, + "name": "Bagged willow tree", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8424" + }, + { + "requirements": "{22,45}", + "shop_price": "15000", + "examine": "You can plant this in your garden.", + "durability": null, + "name": "Bagged maple tree", + "tradeable": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "8425" + }, + { + "durability": null, + "name": "Bagged maple tree", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8426" + }, + { + "requirements": "{22,60}", + "shop_price": "20000", + "examine": "You can plant this in your garden.", + "durability": null, + "name": "Bagged yew tree", + "tradeable": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "8427" + }, + { + "durability": null, + "name": "Bagged yew tree", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8428" + }, + { + "requirements": "{22,75}", + "shop_price": "50000", + "examine": "You can plant this in your garden.", + "durability": null, + "name": "Bagged magic tree", + "tradeable": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "8429" + }, + { + "durability": null, + "name": "Bagged magic tree", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8430" + }, + { + "shop_price": "1000", + "ge_buy_limit": "5000", + "examine": "You can plant this in your garden.", + "grand_exchange_price": "1345", + "durability": null, + "name": "Bagged plant 1", + "tradeable": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "8431" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "1345", + "durability": null, + "name": "Bagged plant 1", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8432" + }, + { + "requirements": "{6,22}", + "shop_price": "5000", + "examine": "You can plant this in your garden.", + "durability": null, + "name": "Bagged plant 2", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "10", + "id": "8433" + }, + { + "durability": null, + "name": "Bagged plant 2", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8434" + }, + { + "requirements": "{12,22}", + "shop_price": "10000", + "examine": "You can plant this in your garden.", + "durability": null, + "name": "Bagged plant 3", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "10", + "id": "8435" + }, + { + "durability": null, + "name": "Bagged plant 3", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8436" + }, + { + "requirements": "{22,56}", + "shop_price": "5000", + "examine": "You can plant this in your garden.", + "durability": null, + "name": "Thorny hedge", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "10", + "id": "8437" + }, + { + "durability": null, + "name": "Thorny hedge", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8438" + }, + { + "requirements": "{22,60}", + "shop_price": "10000", + "examine": "You can plant this in your garden.", + "durability": null, + "name": "Nice hedge", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "10", + "id": "8439" + }, + { + "durability": null, + "name": "Nice hedge", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8440" + }, + { + "requirements": "{22,64}", + "shop_price": "15000", + "examine": "You can plant this in your garden.", + "durability": null, + "name": "Small box hedge", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "10", + "id": "8441" + }, + { + "durability": null, + "name": "Small box hedge", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8442" + }, + { + "requirements": "{22,68}", + "shop_price": "20000", + "examine": "You can plant this in your garden.", + "durability": null, + "name": "Topiary hedge", + "tradeable": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "8443" + }, + { + "durability": null, + "name": "Topiary hedge", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8444" + }, + { + "requirements": "{22,72}", + "shop_price": "25000", + "examine": "You can plant this in your garden.", + "durability": null, + "name": "Fancy hedge", + "tradeable": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "8445" + }, + { + "durability": null, + "name": "Fancy hedge", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8446" + }, + { + "requirements": "{22,76}", + "shop_price": "50000", + "examine": "You can plant this in your garden.", + "durability": null, + "name": "Tall fancy hedge", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "10", + "id": "8447" + }, + { + "durability": null, + "name": "Tall fancy hedge", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8448" + }, + { + "requirements": "{22,80}", + "shop_price": "100000", + "examine": "You can plant this in your garden.", + "durability": null, + "name": "Tall box hedge", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "10", + "id": "8449" + }, + { + "durability": null, + "name": "Tall box hedge", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8450" + }, + { + "requirements": "{22,66}", + "shop_price": "5000", + "examine": "You can plant this in your garden.", + "durability": null, + "name": "Bagged rosemary", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "10", + "id": "8451" + }, + { + "durability": null, + "name": "Bagged rosemary", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8452" + }, + { + "requirements": "{22,71}", + "shop_price": "10000", + "examine": "You can plant this in your garden.", + "durability": null, + "name": "Bagged daffodils", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "10", + "id": "8453" + }, + { + "durability": null, + "name": "Bagged daffodils", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8454" + }, + { + "requirements": "{22,76}", + "shop_price": "15000", + "examine": "You can plant this in your garden.", + "durability": null, + "name": "Bagged bluebells", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "10", + "id": "8455" + }, + { + "durability": null, + "name": "Bagged bluebells", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8456" + }, + { + "requirements": "{22,66}", + "shop_price": "5000", + "examine": "You can plant this in your garden.", + "durability": null, + "name": "Bagged sunflower", + "tradeable": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "8457" + }, + { + "durability": null, + "name": "Bagged sunflower", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8458" + }, + { + "requirements": "{22,71}", + "shop_price": "10000", + "examine": "You can plant this in your garden.", + "durability": null, + "name": "Bagged marigolds", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "10", + "id": "8459" + }, + { + "durability": null, + "name": "Bagged marigolds", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8460" + }, + { + "requirements": "{22,76}", + "shop_price": "15000", + "examine": "You can plant this in your garden.", + "durability": null, + "name": "Bagged roses", + "tradeable": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "8461" + }, + { + "durability": null, + "name": "Bagged roses", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8462" + }, + { + "shop_price": "160", + "examine": "How to build a house.", + "durability": null, + "name": "Construction guide", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "8463" + }, + { + "remove_head": "true", + "requirements": "{1,40}", + "examine": "The colours represent crest.", + "durability": null, + "name": "Rune heraldic helm", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "8464", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "requirements": "{1,40}", + "examine": "The colours represent crest.", + "durability": null, + "name": "Rune heraldic helm", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "8466", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "requirements": "{1,40}", + "examine": "The colours represent crest.", + "durability": null, + "name": "Rune heraldic helm", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "8468", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "requirements": "{1,40}", + "examine": "The colours represent crest.", + "durability": null, + "name": "Rune heraldic helm", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "8470", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "requirements": "{1,40}", + "examine": "The colours represent crest.", + "durability": null, + "name": "Rune heraldic helm", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "8472", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "requirements": "{1,40}", + "examine": "The colours represent crest.", + "durability": null, + "name": "Rune heraldic helm", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "8474", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "requirements": "{1,40}", + "examine": "The colours represent crest.", + "durability": null, + "name": "Rune heraldic helm", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "8476", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "requirements": "{1,40}", + "examine": "The colours represent crest.", + "durability": null, + "name": "Rune heraldic helm", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "8478", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "requirements": "{1,40}", + "examine": "The colours represent crest.", + "durability": null, + "name": "Rune heraldic helm", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "8480", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "requirements": "{1,40}", + "examine": "The colours represent crest.", + "durability": null, + "name": "Rune heraldic helm", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "8482", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "requirements": "{1,40}", + "examine": "The colours represent crest.", + "durability": null, + "name": "Rune heraldic helm", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "8484", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "requirements": "{1,40}", + "examine": "The colours represent crest.", + "durability": null, + "name": "Rune heraldic helm", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "8486", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "requirements": "{1,40}", + "examine": "The colours represent crest.", + "durability": null, + "name": "Rune heraldic helm", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "8488", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "requirements": "{1,40}", + "examine": "The colours represent crest.", + "durability": null, + "name": "Rune heraldic helm", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "8490", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "requirements": "{1,40}", + "examine": "The colours represent crest.", + "durability": null, + "name": "Rune heraldic helm", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "8492", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "requirements": "{1,40}", + "examine": "The colours represent crest.", + "durability": null, + "name": "Rune heraldic helm", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "8494", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1", + "examine": "A ready-to-assemble crude chair.", + "durability": null, + "name": "Crude wooden chair", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8496" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1", + "durability": null, + "name": "Crude wooden chair", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8497" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "53", + "examine": "A ready-to-assemble wooden chair.", + "durability": null, + "name": "Wooden chair", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8498" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "53", + "durability": null, + "name": "Wooden chair", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8499" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1", + "examine": "A ready-to-assemble rocking chair.", + "durability": null, + "name": "Rocking chair", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8500" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1", + "durability": null, + "name": "Rocking chair", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8501" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2", + "examine": "A ready-to-assemble oak chair.", + "durability": null, + "name": "Oak chair", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8502" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2", + "durability": null, + "name": "Oak chair", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8503" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1", + "examine": "A ready-to-assemble oak armchair.", + "durability": null, + "name": "Oak armchair", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8504" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1", + "durability": null, + "name": "Oak armchair", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8505" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1", + "examine": "A ready-to-assemble teak armchair.", + "durability": null, + "name": "Teak armchair", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8506" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1", + "durability": null, + "name": "Teak armchair", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8507" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "8", + "examine": "A ready-to-assemble mahogany armchair.", + "durability": null, + "name": "Mahogany armchair", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8508" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "8", + "durability": null, + "name": "Mahogany armchair", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8509" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1", + "examine": "A ready-to-assemble wooden bookcase.", + "durability": null, + "name": "Wooden bookcase", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8510" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1", + "durability": null, + "name": "Wooden bookcase", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8511" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1", + "examine": "A ready-to-assemble oak bookcase.", + "durability": null, + "name": "Oak bookcase", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8512" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1", + "durability": null, + "name": "Oak bookcase", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8513" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "46", + "examine": "A ready-to-assemble mahogany bookcase.", + "durability": null, + "name": "Mahogany b'kcase", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8514" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "46", + "durability": null, + "name": "Mahogany b'kcase", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8515" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1", + "examine": "A ready-to-assemble beer barrel.", + "durability": null, + "name": "Beer barrel", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8516" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1", + "durability": null, + "name": "Beer barrel", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8517" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "16900", + "examine": "A ready-to-assemble cider barrel.", + "durability": null, + "name": "Cider barrel", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8518" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "16900", + "durability": null, + "name": "Cider barrel", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8519" + }, + { + "shop_price": "3", + "ge_buy_limit": "100", + "examine": "A ready-to-assemble barrel of Asgarnian Ale.", + "grand_exchange_price": "4586", + "durability": null, + "name": "Asgarnian ale", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8520" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "4586", + "durability": null, + "name": "Asgarnian ale", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8521" + }, + { + "shop_price": "2", + "ge_buy_limit": "100", + "examine": "A ready-to-assemble barrel of Greenman's Ale.", + "grand_exchange_price": "8875", + "durability": null, + "name": "Greenman's ale", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8522" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "8875", + "durability": null, + "name": "Greenman's ale", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8523" + }, + { + "shop_price": "2", + "ge_buy_limit": "100", + "examine": "A ready-to-assemble barrel of Dragon Bitter.", + "grand_exchange_price": "10300", + "durability": null, + "name": "Dragon bitter", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "8524" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "10300", + "durability": null, + "name": "Dragon bitter", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8525" + }, + { + "ge_buy_limit": "100", + "examine": "A ready-to-assemble barrel of Chef's Delight.", + "grand_exchange_price": "48800", + "durability": null, + "name": "Chef's delight", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8526" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "48800", + "durability": null, + "name": "Chef's delight", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8527" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1", + "examine": "A ready-to-assemble wooden kitchen table.", + "durability": null, + "name": "Wood kitchen table", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8528" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1", + "durability": null, + "name": "Wood kitchen table", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8529" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1", + "examine": "A ready-to-assemble oak kitchen table.", + "durability": null, + "name": "Oak kitchen table", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8530" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1", + "durability": null, + "name": "Oak kitchen table", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8531" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1", + "examine": "A ready-to-assemble teak kitchen table.", + "durability": null, + "name": "Teak kitchen table", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8532" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1", + "durability": null, + "name": "Teak kitchen table", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8533" + }, + { + "durability": null, + "name": "Oak lectern", + "archery_ticket_price": "0", + "id": "8535" + }, + { + "durability": null, + "name": "Eagle lectern", + "archery_ticket_price": "0", + "id": "8537" + }, + { + "durability": null, + "name": "Demon lectern", + "archery_ticket_price": "0", + "id": "8539" + }, + { + "durability": null, + "name": "Teak eagle lectern", + "archery_ticket_price": "0", + "id": "8541" + }, + { + "durability": null, + "name": "Teak demon lectern", + "archery_ticket_price": "0", + "id": "8543" + }, + { + "durability": null, + "name": "Mahogany eagle", + "archery_ticket_price": "0", + "id": "8545" + }, + { + "durability": null, + "name": "Mahogany demon", + "archery_ticket_price": "0", + "id": "8547" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1", + "examine": "A ready-to-assemble wooden dining table.", + "durability": null, + "name": "Wood dining table", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8548" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1", + "durability": null, + "name": "Wood dining table", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8549" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1", + "examine": "A ready-to-assemble oak dining table.", + "durability": null, + "name": "Oak dining table", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8550" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1", + "durability": null, + "name": "Oak dining table", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8551" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1", + "examine": "A ready-to-assemble carved oak dining table.", + "durability": null, + "name": "Carved oak table", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8552" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1", + "durability": null, + "name": "Carved oak table", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8553" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2", + "examine": "A ready-to-assemble teak dining table.", + "durability": null, + "name": "Teak table", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8554" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2", + "durability": null, + "name": "Teak table", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8555" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "245", + "examine": "A ready-to-assemble carved teak dining table.", + "durability": null, + "name": "Carved teak table", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8556" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "245", + "durability": null, + "name": "Carved teak table", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8557" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "575", + "examine": "A ready-to-assemble mahogany dining table.", + "durability": null, + "name": "Mahogany table", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8558" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "575", + "durability": null, + "name": "Mahogany table", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8559" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "379100", + "examine": "A ready-to-assemble opulent dining table.", + "durability": null, + "name": "Opulent table", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8560" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "379100", + "durability": null, + "name": "Opulent table", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8561" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "15", + "examine": "A ready-to-assemble wooden dining bench.", + "durability": null, + "name": "Wooden bench", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8562" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "15", + "durability": null, + "name": "Wooden bench", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8563" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "137", + "examine": "A ready-to-assemble oak dining bench.", + "durability": null, + "name": "Oak bench", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8564" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "137", + "durability": null, + "name": "Oak bench", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8565" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1", + "examine": "A ready-to-assemble carved oak dining bench.", + "durability": null, + "name": "Carved oak bench", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8566" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1", + "durability": null, + "name": "Carved oak bench", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8567" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "18", + "examine": "A ready-to-assemble teak dining bench.", + "durability": null, + "name": "Teak dining bench", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8568" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "18", + "durability": null, + "name": "Teak dining bench", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8569" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2", + "examine": "A ready-to-assemble carved teak dining bench.", + "durability": null, + "name": "Carved teak bench", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8570" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2", + "durability": null, + "name": "Carved teak bench", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8571" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "126", + "examine": "A ready-to-assemble mahogany dining bench.", + "durability": null, + "name": "Mahogany bench", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8572" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "126", + "durability": null, + "name": "Mahogany bench", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8573" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "517600", + "examine": "A ready-to-assemble gilded mahogany dining bench.", + "durability": null, + "name": "Gilded bench", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8574" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "517600", + "durability": null, + "name": "Gilded bench", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8575" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1974", + "examine": "A ready-to-assemble wooden bed.", + "durability": null, + "name": "Wooden bed", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8576" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1974", + "durability": null, + "name": "Wooden bed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8577" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1775", + "examine": "A ready-to-assemble oak bed.", + "durability": null, + "name": "Oak bed", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8578" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1775", + "durability": null, + "name": "Oak bed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8579" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1433", + "examine": "A ready-to-assemble large oak bed.", + "durability": null, + "name": "Large oak bed", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8580" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1433", + "durability": null, + "name": "Large oak bed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8581" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1442", + "examine": "A ready-to-assemble teak bed.", + "durability": null, + "name": "Teak bed", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8582" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1442", + "durability": null, + "name": "Teak bed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8583" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2030", + "examine": "A ready-to-assemble large teak bed.", + "durability": null, + "name": "Large teak bed", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8584" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2030", + "durability": null, + "name": "Large teak bed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8585" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1401", + "examine": "A ready-to-assemble four-poster bed.", + "durability": null, + "name": "4-poster", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8586" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1401", + "durability": null, + "name": "4-poster", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8587" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "286700", + "examine": "A ready-to-assemble gilded four-poster bed.", + "durability": null, + "name": "Gilded 4-poster", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8588" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "286700", + "durability": null, + "name": "Gilded 4-poster", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8589" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "384", + "examine": "A ready-to-assemble oak clock.", + "durability": null, + "name": "Oak clock", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8590" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "384", + "durability": null, + "name": "Oak clock", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8591" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "595", + "examine": "A ready-to-assemble teak clock.", + "durability": null, + "name": "Teak clock", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8592" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "595", + "durability": null, + "name": "Teak clock", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8593" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "156100", + "examine": "A ready-to-assemble gilded mahogany clock.", + "durability": null, + "name": "Gilded clock", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8594" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "156100", + "durability": null, + "name": "Gilded clock", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8595" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "510", + "examine": "A ready-to-assemble shaving stand.", + "durability": null, + "name": "Shaving stand", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8596" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "510", + "durability": null, + "name": "Shaving stand", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8597" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "455", + "examine": "A ready-to-assemble oak shaving stand.", + "durability": null, + "name": "Oak shaving stand", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8598" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "455", + "durability": null, + "name": "Oak shaving stand", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8599" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "147", + "examine": "A ready-to-assemble oak dresser.", + "durability": null, + "name": "Oak dresser", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8600" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "147", + "durability": null, + "name": "Oak dresser", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8601" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "478", + "examine": "A ready-to-assemble teak dresser.", + "durability": null, + "name": "Teak dresser", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8602" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "478", + "durability": null, + "name": "Teak dresser", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8603" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "455", + "examine": "A ready-to-assemble fancy teak dresser.", + "durability": null, + "name": "Fancy teak dresser", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8604" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "455", + "durability": null, + "name": "Fancy teak dresser", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8605" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "399", + "examine": "A ready-to-assemble mahogany dresser.", + "durability": null, + "name": "Mahogany dresser", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8606" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "399", + "durability": null, + "name": "Mahogany dresser", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8607" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "138800", + "examine": "A ready-to-assemble gilded dresser.", + "durability": null, + "name": "Gilded dresser", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8608" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "138800", + "durability": null, + "name": "Gilded dresser", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8609" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "21", + "examine": "A ready-to-assemble shoe box.", + "durability": null, + "name": "Shoe box", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8610" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "21", + "durability": null, + "name": "Shoe box", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8611" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "47", + "examine": "A ready-to-assemble oak chest of drawers.", + "durability": null, + "name": "Oak drawers", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8612" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "47", + "durability": null, + "name": "Oak drawers", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8613" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1", + "examine": "A ready-to-assemble oak bedroom wardrobe.", + "durability": null, + "name": "Oak wardrobe", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8614" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1", + "durability": null, + "name": "Oak wardrobe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8615" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "132", + "examine": "A ready-to-assemble teak chest of drawers.", + "durability": null, + "name": "Teak drawers", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8616" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "132", + "durability": null, + "name": "Teak drawers", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8617" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "13", + "examine": "A ready-to-assemble teak bedroom wardrobe.", + "durability": null, + "name": "Teak wardrobe", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8618" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "13", + "durability": null, + "name": "Teak wardrobe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8619" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "98", + "examine": "A ready-to-assemble mahogany bedroom wardrobe.", + "durability": null, + "name": "Mahogany 'drobe", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8620" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "98", + "durability": null, + "name": "Mahogany 'drobe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8621" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "137700", + "examine": "A ready-to-assemble gilded mahogany bedroom wardrobe.", + "durability": null, + "name": "Gilded wardrobe", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "8622" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "137700", + "durability": null, + "name": "Gilded wardrobe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8623" + }, + { + "durability": null, + "name": "Crystal ball", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8625" + }, + { + "durability": null, + "name": "Elemental sphere", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8627" + }, + { + "durability": null, + "name": "Crystal of power", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8629" + }, + { + "durability": null, + "name": "Globe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8631" + }, + { + "durability": null, + "name": "Ornamental globe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8633" + }, + { + "durability": null, + "name": "Lunar globe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8635" + }, + { + "durability": null, + "name": "Celestial globe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8637" + }, + { + "durability": null, + "name": "Armillary sphere", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8639" + }, + { + "durability": null, + "name": "Small orrery", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8641" + }, + { + "durability": null, + "name": "Large orrery", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8643" + }, + { + "durability": null, + "name": "Wooden telescope", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8645" + }, + { + "durability": null, + "name": "Teak telescope", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8647" + }, + { + "durability": null, + "name": "Mahogany 'scope", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8649" + }, + { + "turn90cw_anim": "1424", + "walk_anim": "1422", + "durability": null, + "turn90ccw_anim": "1425", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1423", + "render_anim": "131", + "equipment_slot": "3", + "stand_anim": "1421", + "name": "Banner", + "run_anim": "1427", + "archery_ticket_price": "0", + "id": "8650", + "stand_turn_anim": "1426" + }, + { + "turn90cw_anim": "1424", + "walk_anim": "1422", + "durability": null, + "turn90ccw_anim": "1425", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1423", + "render_anim": "131", + "equipment_slot": "3", + "stand_anim": "1421", + "name": "Banner", + "run_anim": "1427", + "archery_ticket_price": "0", + "id": "8652", + "stand_turn_anim": "1426" + }, + { + "turn90cw_anim": "1424", + "walk_anim": "1422", + "durability": null, + "turn90ccw_anim": "1425", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1423", + "render_anim": "131", + "equipment_slot": "3", + "stand_anim": "1421", + "name": "Banner", + "run_anim": "1427", + "archery_ticket_price": "0", + "id": "8654", + "stand_turn_anim": "1426" + }, + { + "turn90cw_anim": "1424", + "walk_anim": "1422", + "durability": null, + "turn90ccw_anim": "1425", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1423", + "render_anim": "131", + "equipment_slot": "3", + "stand_anim": "1421", + "name": "Banner", + "run_anim": "1427", + "archery_ticket_price": "0", + "id": "8656", + "stand_turn_anim": "1426" + }, + { + "turn90cw_anim": "1424", + "walk_anim": "1422", + "durability": null, + "turn90ccw_anim": "1425", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1423", + "render_anim": "131", + "equipment_slot": "3", + "stand_anim": "1421", + "name": "Banner", + "run_anim": "1427", + "archery_ticket_price": "0", + "id": "8658", + "stand_turn_anim": "1426" + }, + { + "turn90cw_anim": "1424", + "walk_anim": "1422", + "durability": null, + "turn90ccw_anim": "1425", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1423", + "render_anim": "131", + "equipment_slot": "3", + "stand_anim": "1421", + "name": "Banner", + "run_anim": "1427", + "archery_ticket_price": "0", + "id": "8660", + "stand_turn_anim": "1426" + }, + { + "turn90cw_anim": "1424", + "walk_anim": "1422", + "durability": null, + "turn90ccw_anim": "1425", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1423", + "render_anim": "131", + "equipment_slot": "3", + "stand_anim": "1421", + "name": "Banner", + "run_anim": "1427", + "archery_ticket_price": "0", + "id": "8662", + "stand_turn_anim": "1426" + }, + { + "turn90cw_anim": "1424", + "walk_anim": "1422", + "durability": null, + "turn90ccw_anim": "1425", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1423", + "render_anim": "131", + "equipment_slot": "3", + "stand_anim": "1421", + "name": "Banner", + "run_anim": "1427", + "archery_ticket_price": "0", + "id": "8664", + "stand_turn_anim": "1426" + }, + { + "turn90cw_anim": "1424", + "walk_anim": "1422", + "durability": null, + "turn90ccw_anim": "1425", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1423", + "render_anim": "131", + "equipment_slot": "3", + "stand_anim": "1421", + "name": "Banner", + "run_anim": "1427", + "archery_ticket_price": "0", + "id": "8666", + "stand_turn_anim": "1426" + }, + { + "turn90cw_anim": "1424", + "walk_anim": "1422", + "durability": null, + "turn90ccw_anim": "1425", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1423", + "render_anim": "131", + "equipment_slot": "3", + "stand_anim": "1421", + "name": "Banner", + "run_anim": "1427", + "archery_ticket_price": "0", + "id": "8668", + "stand_turn_anim": "1426" + }, + { + "turn90cw_anim": "1424", + "walk_anim": "1422", + "durability": null, + "turn90ccw_anim": "1425", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1423", + "render_anim": "131", + "equipment_slot": "3", + "stand_anim": "1421", + "name": "Banner", + "run_anim": "1427", + "archery_ticket_price": "0", + "id": "8670", + "stand_turn_anim": "1426" + }, + { + "turn90cw_anim": "1424", + "walk_anim": "1422", + "durability": null, + "turn90ccw_anim": "1425", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1423", + "render_anim": "131", + "equipment_slot": "3", + "stand_anim": "1421", + "name": "Banner", + "run_anim": "1427", + "archery_ticket_price": "0", + "id": "8672", + "stand_turn_anim": "1426" + }, + { + "turn90cw_anim": "1424", + "walk_anim": "1422", + "durability": null, + "turn90ccw_anim": "1425", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1423", + "render_anim": "131", + "equipment_slot": "3", + "stand_anim": "1421", + "name": "Banner", + "run_anim": "1427", + "archery_ticket_price": "0", + "id": "8674", + "stand_turn_anim": "1426" + }, + { + "turn90cw_anim": "1424", + "walk_anim": "1422", + "durability": null, + "turn90ccw_anim": "1425", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1423", + "render_anim": "131", + "equipment_slot": "3", + "stand_anim": "1421", + "name": "Banner", + "run_anim": "1427", + "archery_ticket_price": "0", + "id": "8676", + "stand_turn_anim": "1426" + }, + { + "turn90cw_anim": "1424", + "walk_anim": "1422", + "durability": null, + "turn90ccw_anim": "1425", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1423", + "render_anim": "131", + "equipment_slot": "3", + "stand_anim": "1421", + "name": "Banner", + "run_anim": "1427", + "archery_ticket_price": "0", + "id": "8678", + "stand_turn_anim": "1426" + }, + { + "turn90cw_anim": "1424", + "walk_anim": "1422", + "durability": null, + "turn90ccw_anim": "1425", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1423", + "render_anim": "131", + "equipment_slot": "3", + "stand_anim": "1421", + "name": "Banner", + "run_anim": "1427", + "archery_ticket_price": "0", + "id": "8680", + "stand_turn_anim": "1426" + }, + { + "remove_head": "true", + "requirements": "{1,5}", + "examine": "The colours represent crest.", + "durability": null, + "name": "Steel heraldic helm", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "8682", + "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "requirements": "{1,5}", + "examine": "The colours represent crest.", + "durability": null, + "name": "Steel heraldic helm", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "8684", + "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "requirements": "{1,5}", + "examine": "The colours represent crest.", + "durability": null, + "name": "Steel heraldic helm", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "8686", + "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "requirements": "{1,5}", + "examine": "The colours represent crest.", + "durability": null, + "name": "Steel heraldic helm", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "8688", + "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "requirements": "{1,5}", + "examine": "The colours represent crest.", + "durability": null, + "name": "Steel heraldic helm", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "8690", + "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "requirements": "{1,5}", + "examine": "The colours represent crest.", + "durability": null, + "name": "Steel heraldic helm", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "8692", + "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "requirements": "{1,5}", + "examine": "The colours represent crest.", + "durability": null, + "name": "Steel heraldic helm", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "8694", + "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "requirements": "{1,5}", + "examine": "The colours represent crest.", + "durability": null, + "name": "Steel heraldic helm", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "8696", + "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "requirements": "{1,5}", + "examine": "The colours represent crest.", + "durability": null, + "name": "Steel heraldic helm", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "8698", + "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "requirements": "{1,5}", + "examine": "The colours represent crest.", + "durability": null, + "name": "Steel heraldic helm", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "8700", + "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "requirements": "{1,5}", + "examine": "The colours represent crest.", + "durability": null, + "name": "Steel heraldic helm", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "8702", + "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "requirements": "{1,5}", + "examine": "The colours represent crest.", + "durability": null, + "name": "Steel heraldic helm", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "8704", + "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "requirements": "{1,5}", + "examine": "The colours represent crest.", + "durability": null, + "name": "Steel heraldic helm", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "8706", + "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "requirements": "{1,5}", + "examine": "The colours represent crest.", + "durability": null, + "name": "Steel heraldic helm", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "8708", + "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "requirements": "{1,5}", + "examine": "The colours represent crest.", + "durability": null, + "name": "Steel heraldic helm", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "8710", + "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "requirements": "{1,5}", + "examine": "The colours represent crest.", + "durability": null, + "name": "Steel heraldic helm", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "8712", + "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "requirements": "{1,40}", + "examine": "A large metal shield.", + "durability": null, + "weight": "5.4", + "absorb": "3,0,7", + "equip_audio": "2245", + "equipment_slot": "5", + "lendable": "true", + "grand_exchange_price": "32583", + "name": "Rune kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8714", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" + }, + { + "requirements": "{1,40}", + "examine": "A large metal shield.", + "durability": null, + "weight": "5.4", + "absorb": "3,0,7", + "equip_audio": "2245", + "equipment_slot": "5", + "lendable": "true", + "grand_exchange_price": "32583", + "name": "Rune kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8716", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" + }, + { + "requirements": "{1,40}", + "examine": "A large metal shield.", + "durability": null, + "weight": "5.4", + "absorb": "3,0,7", + "equip_audio": "2245", + "equipment_slot": "5", + "lendable": "true", + "grand_exchange_price": "32583", + "name": "Rune kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8718", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" + }, + { + "requirements": "{1,40}", + "examine": "A large metal shield.", + "durability": null, + "weight": "5.4", + "absorb": "3,0,7", + "equip_audio": "2245", + "equipment_slot": "5", + "lendable": "true", + "grand_exchange_price": "32583", + "name": "Rune kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8720", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" + }, + { + "requirements": "{1,40}", + "examine": "A large metal shield.", + "durability": null, + "weight": "5.4", + "absorb": "3,0,7", + "equip_audio": "2245", + "equipment_slot": "5", + "lendable": "true", + "grand_exchange_price": "32583", + "name": "Rune kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8722", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" + }, + { + "requirements": "{1,40}", + "examine": "A large metal shield.", + "durability": null, + "weight": "5.4", + "absorb": "3,0,7", + "equip_audio": "2245", + "equipment_slot": "5", + "lendable": "true", + "grand_exchange_price": "32583", + "name": "Rune kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8724", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" + }, + { + "requirements": "{1,40}", + "examine": "A large metal shield.", + "durability": null, + "weight": "5.4", + "absorb": "3,0,7", + "equip_audio": "2245", + "equipment_slot": "5", + "lendable": "true", + "grand_exchange_price": "32583", + "name": "Rune kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8726", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" + }, + { + "requirements": "{1,40}", + "examine": "A large metal shield.", + "durability": null, + "weight": "5.4", + "absorb": "3,0,7", + "equip_audio": "2245", + "equipment_slot": "5", + "lendable": "true", + "grand_exchange_price": "32583", + "name": "Rune kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8728", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" + }, + { + "requirements": "{1,40}", + "examine": "A large metal shield.", + "durability": null, + "weight": "5.4", + "absorb": "3,0,7", + "equip_audio": "2245", + "equipment_slot": "5", + "lendable": "true", + "grand_exchange_price": "32583", + "name": "Rune kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8730", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" + }, + { + "requirements": "{1,40}", + "examine": "A large metal shield.", + "durability": null, + "weight": "5.4", + "absorb": "3,0,7", + "equip_audio": "2245", + "equipment_slot": "5", + "lendable": "true", + "grand_exchange_price": "32583", + "name": "Rune kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8732", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" + }, + { + "requirements": "{1,40}", + "examine": "A large metal shield.", + "durability": null, + "weight": "5.4", + "absorb": "3,0,7", + "equip_audio": "2245", + "equipment_slot": "5", + "lendable": "true", + "grand_exchange_price": "32583", + "name": "Rune kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8734", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" + }, + { + "requirements": "{1,40}", + "examine": "A large metal shield.", + "durability": null, + "weight": "5.4", + "absorb": "3,0,7", + "equip_audio": "2245", + "equipment_slot": "5", + "lendable": "true", + "grand_exchange_price": "32583", + "name": "Rune kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8736", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" + }, + { + "requirements": "{1,40}", + "examine": "A large metal shield.", + "durability": null, + "weight": "5.4", + "absorb": "3,0,7", + "equip_audio": "2245", + "equipment_slot": "5", + "lendable": "true", + "grand_exchange_price": "32583", + "name": "Rune kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8738", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" + }, + { + "requirements": "{1,40}", + "examine": "A large metal shield.", + "durability": null, + "weight": "5.4", + "absorb": "3,0,7", + "equip_audio": "2245", + "equipment_slot": "5", + "lendable": "true", + "grand_exchange_price": "32583", + "name": "Rune kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8740", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" + }, + { + "requirements": "{1,40}", + "examine": "A large metal shield.", + "durability": null, + "weight": "5.4", + "absorb": "3,0,7", + "equip_audio": "2245", + "equipment_slot": "5", + "lendable": "true", + "grand_exchange_price": "32583", + "name": "Rune kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8742", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" + }, + { + "requirements": "{1,40}", + "examine": "A large metal shield.", + "durability": null, + "weight": "5.4", + "absorb": "3,0,7", + "equip_audio": "2245", + "equipment_slot": "5", + "lendable": "true", + "grand_exchange_price": "32583", + "name": "Rune kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8744", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" + }, + { + "requirements": "{1,5}", + "shop_price": "850", + "examine": "A large metal shield.", + "durability": null, + "weight": "5.4", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "346", + "name": "Steel kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8746", + "bonuses": "0,0,0,-8,-2,13,15,14,-1,14,5,0,0,0,0" + }, + { + "requirements": "{1,5}", + "shop_price": "850", + "examine": "A large metal shield.", + "durability": null, + "weight": "5.4", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "346", + "name": "Steel kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8748", + "bonuses": "0,0,0,-8,-2,13,15,14,-1,14,5,0,0,0,0" + }, + { + "requirements": "{1,5}", + "shop_price": "850", + "examine": "A large metal shield.", + "durability": null, + "weight": "5.4", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "346", + "name": "Steel kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8750", + "bonuses": "0,0,0,-8,-2,13,15,14,-1,14,5,0,0,0,0" + }, + { + "requirements": "{1,5}", + "shop_price": "850", + "examine": "A large metal shield.", + "durability": null, + "weight": "5.4", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "346", + "name": "Steel kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8752", + "bonuses": "0,0,0,-8,-2,13,15,14,-1,14,5,0,0,0,0" + }, + { + "requirements": "{1,5}", + "shop_price": "850", + "examine": "A large metal shield.", + "durability": null, + "weight": "5.4", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "346", + "name": "Steel kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8754", + "bonuses": "0,0,0,-8,-2,13,15,14,-1,14,5,0,0,0,0" + }, + { + "requirements": "{1,5}", + "shop_price": "850", + "examine": "A large metal shield.", + "durability": null, + "weight": "5.4", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "346", + "name": "Steel kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8756", + "bonuses": "0,0,0,-8,-2,13,15,14,-1,14,5,0,0,0,0" + }, + { + "requirements": "{1,5}", + "shop_price": "850", + "examine": "A large metal shield.", + "durability": null, + "weight": "5.4", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "346", + "name": "Steel kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8758", + "bonuses": "0,0,0,-8,-2,13,15,14,-1,14,5,0,0,0,0" + }, + { + "requirements": "{1,5}", + "shop_price": "850", + "examine": "A large metal shield.", + "durability": null, + "weight": "5.4", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "346", + "name": "Steel kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8760", + "bonuses": "0,0,0,-8,-2,13,15,14,-1,14,5,0,0,0,0" + }, + { + "requirements": "{1,5}", + "shop_price": "850", + "examine": "A large metal shield.", + "durability": null, + "weight": "5.4", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "346", + "name": "Steel kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8762", + "bonuses": "0,0,0,-8,-2,13,15,14,-1,14,5,0,0,0,0" + }, + { + "requirements": "{1,5}", + "shop_price": "850", + "examine": "A large metal shield.", + "durability": null, + "weight": "5.4", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "346", + "name": "Steel kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8764", + "bonuses": "0,0,0,-8,-2,13,15,14,-1,14,5,0,0,0,0" + }, + { + "requirements": "{1,5}", + "shop_price": "850", + "examine": "A large metal shield.", + "durability": null, + "weight": "5.4", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "346", + "name": "Steel kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8766", + "bonuses": "0,0,0,-8,-2,13,15,14,-1,14,5,0,0,0,0" + }, + { + "requirements": "{1,5}", + "shop_price": "850", + "examine": "A large metal shield.", + "durability": null, + "weight": "5.4", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "346", + "name": "Steel kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8768", + "bonuses": "0,0,0,-8,-2,13,15,14,-1,14,5,0,0,0,0" + }, + { + "requirements": "{1,5}", + "shop_price": "850", + "examine": "A large metal shield.", + "durability": null, + "weight": "5.4", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "346", + "name": "Steel kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8770", + "bonuses": "0,0,0,-8,-2,13,15,14,-1,14,5,0,0,0,0" + }, + { + "requirements": "{1,5}", + "shop_price": "850", + "examine": "A large metal shield.", + "durability": null, + "weight": "5.4", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "346", + "name": "Steel kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8772", + "bonuses": "0,0,0,-8,-2,13,15,14,-1,14,5,0,0,0,0" + }, + { + "requirements": "{1,5}", + "shop_price": "850", + "examine": "A large metal shield.", + "durability": null, + "weight": "5.4", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "346", + "name": "Steel kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8774", + "bonuses": "0,0,0,-8,-2,13,15,14,-1,14,5,0,0,0,0" + }, + { + "requirements": "{1,5}", + "shop_price": "850", + "examine": "A large metal shield.", + "durability": null, + "weight": "5.4", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "346", + "name": "Steel kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8776", + "bonuses": "0,0,0,-8,-2,13,15,14,-1,14,5,0,0,0,0" + }, + { + "ge_buy_limit": "10000", + "examine": "A plank of sturdy oak.", + "grand_exchange_price": "660", + "durability": null, + "name": "Oak plank", + "tradeable": "true", + "weight": "0.8", + "archery_ticket_price": "0", + "id": "8778" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "660", + "durability": null, + "name": "Oak plank", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8779" + }, + { + "shop_price": "500", + "ge_buy_limit": "10000", + "examine": "A plank of fine teak.", + "grand_exchange_price": "959", + "durability": null, + "name": "Teak plank", + "tradeable": "true", + "weight": "0.8", + "archery_ticket_price": "0", + "id": "8780" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "959", + "durability": null, + "name": "Teak plank", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8781" + }, + { + "shop_price": "1500", + "ge_buy_limit": "10000", + "examine": "A plank of expensive mahogany.", + "grand_exchange_price": "2286", + "durability": null, + "name": "Mahogany plank", + "tradeable": "true", + "weight": "0.8", + "archery_ticket_price": "0", + "id": "8782" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "2286", + "durability": null, + "name": "Mahogany plank", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8783" + }, + { + "shop_price": "130000", + "ge_buy_limit": "100", + "examine": "A very delicate sheet of gold.", + "grand_exchange_price": "133800", + "durability": null, + "name": "Gold leaf", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "8784" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "133800", + "durability": null, + "name": "Gold leaf", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8785" + }, + { + "shop_price": "325000", + "ge_buy_limit": "100", + "examine": "A beautifully carved marble block.", + "grand_exchange_price": "324800", + "durability": null, + "name": "Marble block", + "tradeable": "true", + "weight": "13.6", + "archery_ticket_price": "0", + "id": "8786" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "324800", + "durability": null, + "name": "Marble block", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8787" + }, + { + "shop_price": "975000", + "ge_buy_limit": "100", + "examine": "A magic stone to make high-level furniture.", + "grand_exchange_price": "980300", + "durability": null, + "name": "Magic stone", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "8788" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "980300", + "durability": null, + "name": "Magic stone", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8789" + }, + { + "shop_price": "650", + "ge_buy_limit": "100", + "examine": "A bolt of ordinary cloth.", + "grand_exchange_price": "1090", + "durability": null, + "name": "Bolt of cloth", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "8790" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1090", + "durability": null, + "name": "Bolt of cloth", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8791" + }, + { + "ge_buy_limit": "5000", + "examine": "A clockwork mechanism.", + "grand_exchange_price": "1630", + "durability": null, + "name": "Clockwork", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "8792" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "1630", + "durability": null, + "name": "Clockwork", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8793" + }, + { + "shop_price": "13", + "ge_buy_limit": "100", + "examine": "Good for cutting wood.", + "grand_exchange_price": "64", + "durability": null, + "name": "Saw", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "8794", + "equipment_slot": "3" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "64", + "durability": null, + "name": "Saw", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8795" + }, + { + "durability": null, + "name": "Mahogany logs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8836" + }, + { + "shop_price": "1", + "ge_buy_limit": "1000", + "examine": "A hefty beam of timber, perfect for building temples.", + "grand_exchange_price": "29", + "durability": null, + "name": "Timber beam", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8837" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "29", + "durability": null, + "name": "Timber beam", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8838" + }, + { + "remove_sleeves": "true", + "requirements": "{0,42}-{1,42}-{2,42}-{3,42}-{4,42}-{5,22}-{6,42}", + "shop_price": "250", + "examine": "Torso armour from the order of the Void Knights.", + "durability": null, + "name": "Void knight top", + "tradeable": "false", + "weight": "6.5", + "archery_ticket_price": "0", + "id": "8839", + "bonuses": "0,0,0,0,0,45,45,45,45,45,45,0,0,0,0", + "equipment_slot": "4" + }, + { + "requirements": "{0,42}-{1,42}-{2,42}-{3,42}-{4,42}-{5,22}-{6,42}", + "shop_price": "250", + "examine": "Leg armour of the order of the Void Knights.", + "durability": null, + "name": "Void knight robe", + "tradeable": "false", + "weight": "8", + "archery_ticket_price": "0", + "id": "8840", + "bonuses": "0,0,0,0,0,30,30,30,30,30,15,0,0,0,0", + "equipment_slot": "7" + }, + { + "requirements": "{0,42}-{1,42}-{2,42}-{3,42}-{4,42}-{5,22}-{6,42}", + "shop_price": "250", + "examine": "A mace used by the order of the Void Knights.", + "durability": null, + "weight": "1", + "attack_speed": "5", + "weapon_interface": "1", + "equip_audio": "2246", + "render_anim": "2553", + "equipment_slot": "3", + "attack_anims": "401,401,401,401", + "attack_audios": "2508,2508,25092508", + "name": "Void knight mace", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "8841", + "bonuses": "22,0,41,8,0,2,2,2,2,2,0,38,6,0,0" + }, + { + "requirements": "{0,42}-{1,42}-{2,42}-{3,42}-{4,42}-{5,22}-{6,42}", + "shop_price": "150", + "examine": "Gloves as used by the order of the Void Knights.", + "durability": null, + "name": "Void knight gloves", + "tradeable": "false", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "8842", + "bonuses": "0,0,0,0,0,6,6,6,6,6,6,0,0,0,0", + "equipment_slot": "9" + }, + { + "examine": "A defensive weapon.", + "durability": null, + "name": "Bronze defender", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "8844", + "bonuses": "3,2,1,-3,-2,3,2,1,-3,-2,1,0,0,0,0", + "equip_audio": "2238", + "defence_anim": "4177", + "equipment_slot": "5" + }, + { + "examine": "A defensive weapon.", + "durability": null, + "name": "Iron defender", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "8845", + "bonuses": "5,4,3,-3,-2,5,4,3,-3,-2,2,0,0,0,0", + "equip_audio": "2238", + "defence_anim": "4177", + "equipment_slot": "5" + }, + { + "requirements": "{0,5}-{1,5}", + "examine": "A defensive weapon.", + "durability": null, + "name": "Steel defender", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "8846", + "bonuses": "7,6,5,-3,-2,7,6,5,-3,-2,3,1,0,0,0", + "equip_audio": "2238", + "defence_anim": "4177", + "equipment_slot": "5" + }, + { + "requirements": "{0,10}-{1,10}", + "examine": "A defensive weapon.", + "durability": null, + "name": "Black defender", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "8847", + "bonuses": "9,8,7,-3,-2,9,8,7,-3,-2,4,2,0,0,0", + "equip_audio": "2238", + "defence_anim": "4177", + "equipment_slot": "5" + }, + { + "requirements": "{0,20}-{1,20}", + "examine": "A defensive weapon.", + "durability": null, + "name": "Mithril defender", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "8848", + "bonuses": "10,9,8,-3,-2,10,9,8,-3,-2,5,3,0,0,0", + "equip_audio": "2238", + "defence_anim": "4177", + "equipment_slot": "5" + }, + { + "requirements": "{0,30}-{1,30}", + "examine": "A defensive weapon.", + "durability": null, + "name": "Adamant defender", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "8849", + "bonuses": "13,12,11,-3,-2,13,12,11,-3,-2,6,4,0,0,0", + "equip_audio": "2238", + "defence_anim": "4177", + "equipment_slot": "5" + }, + { + "requirements": "{0,40}-{1,40}", + "examine": "A defensive weapon.", + "durability": null, + "name": "Rune defender", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "8850", + "bonuses": "20,19,18,-3,-2,20,19,18,-3,-2,8,5,0,0,0", + "equip_audio": "2238", + "defence_anim": "4177", + "equipment_slot": "5" + }, + { + "examine": "Warrior Guild Token.", + "durability": null, + "name": "Warrior guild token", + "archery_ticket_price": "0", + "id": "8851" + }, + { + "examine": "Large, round, heavy shield.", + "durability": null, + "name": "Defensive shield", + "weight": "3.6", + "archery_ticket_price": "0", + "two_handed": "false", + "id": "8856", + "bonuses": "0,0,0,-6,-2,8,9,7,0,8,0,0,0,0,0", + "equipment_slot": "5" + }, + { + "examine": "Just landed 18lb shot.", + "durability": null, + "name": "18lb shot", + "destroy": "true", + "archery_ticket_price": "0", + "id": "8858" + }, + { + "examine": "Just landed 22lb shot.", + "durability": null, + "name": "22lb shot", + "destroy": "true", + "archery_ticket_price": "0", + "id": "8859" + }, + { + "examine": "To put on your head.", + "durability": null, + "name": "One barrel", + "destroy": "true", + "weight": "4.5", + "archery_ticket_price": "0", + "id": "8860", + "equipment_slot": "0" + }, + { + "examine": "To put on your head.", + "durability": null, + "name": "Two barrels", + "destroy": "true", + "weight": "9", + "archery_ticket_price": "0", + "id": "8861", + "equipment_slot": "0" + }, + { + "examine": "To put on your head.", + "durability": null, + "name": "Three barrels", + "destroy": "true", + "weight": "13.5", + "archery_ticket_price": "0", + "id": "8862", + "equipment_slot": "0" + }, + { + "examine": "To put on your head.", + "durability": null, + "name": "Four barrels", + "destroy": "true", + "weight": "18.1", + "archery_ticket_price": "0", + "id": "8863", + "equipment_slot": "0" + }, + { + "examine": "To put on your head.", + "durability": null, + "name": "Five barrels", + "destroy": "true", + "weight": "22.6", + "archery_ticket_price": "0", + "id": "8864", + "equipment_slot": "0" + }, + { + "examine": "A heap of finely ground ashes.", + "durability": null, + "name": "Ground ashes", + "archery_ticket_price": "0", + "id": "8865" + }, + { + "examine": "A key made of solid iron.", + "durability": null, + "name": "Iron key", + "archery_ticket_price": "0", + "id": "8869" + }, + { + "examine": "See article", + "durability": null, + "name": "Zanik", + "archery_ticket_price": "0", + "id": "8870" + }, + { + "turn90cw_anim": "4194", + "examine": "It's got Zanik in it.", + "walk_anim": "4194", + "durability": null, + "destroy": "true", + "weight": "32", + "turn90ccw_anim": "4194", + "turn180_anim": "4194", + "render_anim": "822", + "equipment_slot": "3", + "stand_anim": "4193", + "name": "Crate with zanik", + "tradeable": "false", + "run_anim": "4194", + "archery_ticket_price": "0", + "id": "8871", + "stand_turn_anim": "4194" + }, + { + "shop_price": "2000", + "ge_buy_limit": "100", + "examine": "A powerful dagger.", + "has_special": "true", + "durability": null, + "weight": "0.4", + "attack_speed": "4", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "defence_anim": "378", + "equipment_slot": "3", + "attack_anims": "400,400,400,400", + "grand_exchange_price": "2855", + "attack_audios": "2517,2517,2500,2517", + "name": "Bone dagger", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8872", + "bonuses": "5,3,-4,1,0,0,0,0,1,0,0,4,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2855", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Bone dagger", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8873" + }, + { + "shop_price": "2000", + "ge_buy_limit": "100", + "examine": "A powerful dagger.", + "has_special": "true", + "durability": null, + "weight": "0.4", + "attack_speed": "4", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "defence_anim": "378", + "equipment_slot": "3", + "attack_anims": "400,400,400,400", + "grand_exchange_price": "3033", + "attack_audios": "2517,2517,2500,2517", + "name": "Bone dagger (p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8874", + "bonuses": "5,3,-4,1,0,0,0,0,1,0,0,4,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3033", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Bone dagger (p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8875" + }, + { + "shop_price": "2000", + "ge_buy_limit": "100", + "examine": "A powerful dagger.", + "has_special": "true", + "durability": null, + "weight": "0.4", + "attack_speed": "4", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "defence_anim": "378", + "equipment_slot": "3", + "attack_anims": "400,400,400,400", + "grand_exchange_price": "3523", + "attack_audios": "2517,2517,2500,2517", + "name": "Bone dagger (p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8876", + "bonuses": "5,3,-4,1,0,0,0,0,1,0,0,4,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3523", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Bone dagger (p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8877" + }, + { + "shop_price": "2000", + "ge_buy_limit": "100", + "examine": "A powerful dagger.", + "has_special": "true", + "durability": null, + "weight": "0.4", + "attack_speed": "4", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "defence_anim": "378", + "equipment_slot": "3", + "attack_anims": "400,400,400,400", + "grand_exchange_price": "8337", + "attack_audios": "2517,2517,2500,2517", + "name": "Bone dagger (p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8878", + "bonuses": "5,3,-4,1,0,0,0,0,1,0,0,4,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "8337", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Bone dagger (p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8879" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "821", + "examine": "This fires crossbow bolts.", + "walk_anim": "4226", + "has_special": "true", + "turn90ccw_anim": "822", + "attack_speed": "5", + "turn180_anim": "4227", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "4230,4230,4230,4230", + "grand_exchange_price": "1159", + "stand_anim": "4591", + "tradeable": "true", + "run_anim": "4228", + "archery_ticket_price": "0", + "id": "8880", + "stand_turn_anim": "823", + "bonuses": "0,0,0,0,42,0,0,0,0,0,0,0,0,0,0", + "requirements": "{4,28}", + "shop_price": "2000", + "durability": null, + "weight": "2.2", + "weapon_interface": "17", + "render_anim": "175", + "attack_audios": "2700,0,0,0", + "name": "Dorgeshuun c'bow" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1159", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Dorgeshuun c'bow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8881" + }, + { + "requirements": "{4,28}", + "shop_price": "4", + "ge_buy_limit": "10000", + "examine": "Good if you have a bone crossbow!", + "grand_exchange_price": "12", + "durability": null, + "name": "Bone bolts", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8882", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,49", + "equipment_slot": "13" + }, + { + "examine": "See article", + "durability": null, + "name": "Zanik", + "archery_ticket_price": "0", + "id": "8887" + }, + { + "bankable": "false", + "examine": "Lovely money!", + "durability": null, + "name": "Coins", + "archery_ticket_price": "0", + "id": "8890" + }, + { + "examine": "A horrible, emaciated ape like creature with beady red eyes.", + "durability": null, + "name": "Cave horror", + "archery_ticket_price": "0", + "id": "8900" + }, + { + "requirements": "{1,20}-{2,10}", + "ge_buy_limit": "10", + "examine": "A magic cave horror mask.", + "durability": null, + "rare_item": "true", + "weight": "10", + "equipment_slot": "0", + "grand_exchange_price": "989400", + "name": "Black mask (10)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8901", + "bonuses": "0,0,0,-3,-1,9,10,8,-1,9,0,0,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "989400", + "durability": null, + "name": "Black mask (10)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8902" + }, + { + "requirements": "{1,20}-{2,10}", + "examine": "A magic cave horror mask.", + "grand_exchange_price": "583700", + "durability": null, + "name": "Black mask (9)", + "tradeable": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "8903", + "bonuses": "0,0,0,-3,-1,9,10,8,-1,9,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "durability": null, + "name": "Black mask (9)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8904" + }, + { + "requirements": "{1,20}-{2,10}", + "examine": "A magic cave horror mask.", + "grand_exchange_price": "583700", + "durability": null, + "name": "Black mask (8)", + "tradeable": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "8905", + "bonuses": "0,0,0,-3,-1,9,10,8,-1,9,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "durability": null, + "name": "Black mask (8)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8906" + }, + { + "requirements": "{1,20}-{2,10}", + "examine": "A magic cave horror mask.", + "grand_exchange_price": "583700", + "durability": null, + "name": "Black mask (7)", + "tradeable": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "8907", + "bonuses": "0,0,0,-3,-1,9,10,8,-1,9,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "durability": null, + "name": "Black mask (7)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8908" + }, + { + "requirements": "{1,20}-{2,10}", + "examine": "A magic cave horror mask.", + "grand_exchange_price": "583700", + "durability": null, + "name": "Black mask (6)", + "tradeable": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "8909", + "bonuses": "0,0,0,-3,-1,9,10,8,-1,9,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "durability": null, + "name": "Black mask (6)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8910" + }, + { + "requirements": "{1,20}-{2,10}", + "examine": "A magic cave horror mask.", + "grand_exchange_price": "583700", + "durability": null, + "name": "Black mask (5)", + "tradeable": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "8911", + "bonuses": "0,0,0,-3,-1,9,10,8,-1,9,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "durability": null, + "name": "Black mask (5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8912" + }, + { + "requirements": "{1,20}-{2,10}", + "examine": "A magic cave horror mask.", + "grand_exchange_price": "583700", + "durability": null, + "name": "Black mask (4)", + "tradeable": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "8913", + "bonuses": "0,0,0,-3,-1,9,10,8,-1,9,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "durability": null, + "name": "Black mask (4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8914" + }, + { + "requirements": "{1,20}-{2,10}", + "examine": "A magic cave horror mask.", + "grand_exchange_price": "583700", + "durability": null, + "name": "Black mask (3)", + "tradeable": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "8915", + "bonuses": "0,0,0,-3,-1,9,10,8,-1,9,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "durability": null, + "name": "Black mask (3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8916" + }, + { + "requirements": "{1,20}-{2,10}", + "examine": "A magic cave horror mask.", + "grand_exchange_price": "583700", + "durability": null, + "name": "Black mask (2)", + "tradeable": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "8917", + "bonuses": "0,0,0,-3,-1,9,10,8,-1,9,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "durability": null, + "name": "Black mask (2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8918" + }, + { + "requirements": "{1,20}-{2,10}", + "examine": "A magic cave horror mask.", + "grand_exchange_price": "583700", + "durability": null, + "name": "Black mask (1)", + "tradeable": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "8919", + "bonuses": "0,0,0,-3,-1,9,10,8,-1,9,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "durability": null, + "name": "Black mask (1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8920" + }, + { + "requirements": "{1,20}-{2,10}", + "ge_buy_limit": "10", + "examine": "An inert-seeming cave horror mask.", + "grand_exchange_price": "956100", + "durability": null, + "name": "Black mask", + "tradeable": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "8921", + "bonuses": "0,0,0,-3,-1,9,10,8,-1,9,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "956100", + "durability": null, + "name": "Black mask", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8922" + }, + { + "requirements": "{18,35}", + "shop_price": "900", + "examine": "A stick on a string... pure style.", + "durability": null, + "name": "Witchwood icon", + "archery_ticket_price": "0", + "id": "8923", + "bonuses": "0,0,0,1,0,0,0,0,0,0,0,0,1,0,0", + "equipment_slot": "2" + }, + { + "remove_head": "true", + "examine": "A white bandana and a patch for the right eye.", + "durability": null, + "name": "Bandana and eyepatch", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "8924", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "examine": "A red bandana and a patch for the right eye.", + "durability": null, + "name": "Bandana and eyepatch", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "8925", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "examine": "A blue bandana and a patch for the right eye.", + "durability": null, + "name": "Bandana and eyepatch", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "8926", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "examine": "A brown bandana and a patch for the right eye.", + "durability": null, + "name": "Bandana and eyepatch", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "8927", + "equipment_slot": "0" + }, + { + "examine": "A pirate hat and a patch for the right eye.", + "durability": null, + "name": "Hat and eyepatch", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "8928", + "equipment_slot": "0" + }, + { + "shop_price": "800", + "examine": "Tied together so they don't come apart.", + "durability": null, + "name": "Crabclaw and hook", + "weight": "1", + "archery_ticket_price": "0", + "id": "8929", + "bonuses": "0,0,0,0,0,3,5,3,0,0,0,1,0,0,0", + "equipment_slot": "9" + }, + { + "examine": "Crude wooden pipe section.", + "durability": null, + "name": "Pipe section", + "weight": "1", + "archery_ticket_price": "0", + "id": "8930" + }, + { + "durability": null, + "name": "Pipe section", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8931" + }, + { + "examine": "Repairs made with this will be patchy at best.", + "durability": null, + "name": "Lumber patch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8932" + }, + { + "durability": null, + "name": "Lumber patch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8933" + }, + { + "examine": "Slimy logs from the scrapey tree.", + "durability": null, + "name": "Scrapey tree logs", + "archery_ticket_price": "0", + "id": "8934" + }, + { + "durability": null, + "name": "Scrapey tree logs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8935" + }, + { + "examine": "Very blue.", + "durability": null, + "name": "Blue flowers", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8936" + }, + { + "durability": null, + "name": "Blue flowers", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8937" + }, + { + "examine": "Very red.", + "durability": null, + "name": "Red flowers", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8938" + }, + { + "durability": null, + "name": "Red flowers", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8939" + }, + { + "examine": "Bluuuuuuuue Monkeeeeeeey!", + "durability": null, + "name": "Blue monkey", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8943" + }, + { + "examine": "Bluuuuuuuue Monkeeeeeeey!", + "durability": null, + "name": "Blue monkey", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8944" + }, + { + "examine": "Bluuuuuuuue Monkeeeeeeey!", + "durability": null, + "name": "Blue monkey", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8945" + }, + { + "examine": "A well red monkey.", + "durability": null, + "name": "Red monkey", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8946" + }, + { + "examine": "A well red monkey.", + "durability": null, + "name": "Red monkey", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8947" + }, + { + "examine": "A well red monkey.", + "durability": null, + "name": "Red monkey", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8948" + }, + { + "remove_head": "true", + "examine": "Essential pirate wear.", + "durability": null, + "name": "Pirate bandana", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "8949", + "equipment_slot": "0" + }, + { + "examine": "Shiver me timbers!", + "grand_exchange_price": "83200", + "durability": null, + "name": "Pirate hat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8950", + "equipment_slot": "0" + }, + { + "examine": "Piratical currency.", + "durability": null, + "name": "Pieces of eight", + "archery_ticket_price": "0", + "id": "8951" + }, + { + "remove_sleeves": "true", + "shop_price": "100", + "examine": "...You can sail the seven seas...", + "durability": null, + "name": "Blue naval shirt", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "8952", + "equipment_slot": "4" + }, + { + "remove_sleeves": "true", + "shop_price": "100", + "examine": "...You can sail the seven seas...", + "durability": null, + "name": "Green naval shirt", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "8953", + "equipment_slot": "4" + }, + { + "remove_sleeves": "true", + "shop_price": "100", + "examine": "...You can sail the seven seas...", + "durability": null, + "name": "Red naval shirt", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "8954", + "equipment_slot": "4" + }, + { + "remove_sleeves": "true", + "shop_price": "100", + "examine": "...You can sail the seven seas...", + "durability": null, + "name": "Brown naval shirt", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "8955", + "equipment_slot": "4" + }, + { + "remove_sleeves": "true", + "shop_price": "100", + "examine": "...You can sail the seven seas...", + "durability": null, + "name": "Black naval shirt", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "8956", + "equipment_slot": "4" + }, + { + "remove_sleeves": "true", + "shop_price": "100", + "examine": "...You can sail the seven seas...", + "durability": null, + "name": "Purple naval shirt", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "8957", + "equipment_slot": "4" + }, + { + "remove_sleeves": "true", + "shop_price": "100", + "examine": "...You can sail the seven seas...", + "durability": null, + "name": "Grey naval shirt", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "8958", + "equipment_slot": "4" + }, + { + "shop_price": "50", + "examine": "I could never look square in this.", + "durability": null, + "name": "Blue tricorn hat", + "archery_ticket_price": "0", + "id": "8959", + "equipment_slot": "0" + }, + { + "shop_price": "50", + "examine": "I could never look square in this.", + "durability": null, + "name": "Green tricorn hat", + "archery_ticket_price": "0", + "id": "8960", + "equipment_slot": "0" + }, + { + "shop_price": "50", + "examine": "I could never look square in this.", + "durability": null, + "name": "Red tricorn hat", + "archery_ticket_price": "0", + "id": "8961", + "equipment_slot": "0" + }, + { + "shop_price": "50", + "examine": "I could never look square in this.", + "durability": null, + "name": "Brown tricorn hat", + "archery_ticket_price": "0", + "id": "8962", + "equipment_slot": "0" + }, + { + "shop_price": "50", + "examine": "I could never look square in this.", + "durability": null, + "name": "Black tricorn hat", + "archery_ticket_price": "0", + "id": "8963", + "equipment_slot": "0" + }, + { + "shop_price": "50", + "examine": "I could never look square in this.", + "durability": null, + "name": "Purple tricorn hat", + "archery_ticket_price": "0", + "id": "8964", + "equipment_slot": "0" + }, + { + "shop_price": "50", + "examine": "I could never look square in this.", + "durability": null, + "name": "Grey tricorn hat", + "archery_ticket_price": "0", + "id": "8965", + "equipment_slot": "0" + }, + { + "shop_price": "200", + "turn90cw_anim": "1424", + "examine": "The flag of The Cutthroat.", + "walk_anim": "1422", + "durability": null, + "weight": "6", + "turn90ccw_anim": "1425", + "weapon_interface": "14", + "turn180_anim": "1423", + "render_anim": "131", + "equipment_slot": "3", + "stand_anim": "1421", + "name": "Cutthroat flag", + "run_anim": "1427", + "archery_ticket_price": "0", + "id": "8966", + "stand_turn_anim": "1426" + }, + { + "shop_price": "200", + "turn90cw_anim": "1424", + "examine": "The flag of The Guilded Smile.", + "walk_anim": "1422", + "durability": null, + "weight": "6", + "turn90ccw_anim": "1425", + "attack_speed": "2", + "weapon_interface": "14", + "turn180_anim": "1423", + "render_anim": "131", + "equipment_slot": "3", + "stand_anim": "1421", + "name": "Guilded smile flag", + "run_anim": "1427", + "archery_ticket_price": "0", + "id": "8967", + "stand_turn_anim": "1426" + }, + { + "shop_price": "300", + "turn90cw_anim": "1424", + "examine": "The flag of The Bronze Fist.", + "walk_anim": "1422", + "durability": null, + "weight": "6", + "turn90ccw_anim": "1425", + "weapon_interface": "14", + "turn180_anim": "1423", + "render_anim": "131", + "equipment_slot": "3", + "stand_anim": "1421", + "name": "Bronze fist flag", + "run_anim": "1427", + "archery_ticket_price": "0", + "id": "8968", + "stand_turn_anim": "1426" + }, + { + "shop_price": "400", + "turn90cw_anim": "1424", + "examine": "The flag of The Lucky Shot.", + "walk_anim": "1422", + "durability": null, + "weight": "6", + "turn90ccw_anim": "1425", + "weapon_interface": "14", + "turn180_anim": "1423", + "render_anim": "131", + "equipment_slot": "3", + "stand_anim": "1421", + "name": "Lucky shot flag", + "run_anim": "1427", + "archery_ticket_price": "0", + "id": "8969", + "stand_turn_anim": "1426" + }, + { + "shop_price": "500", + "turn90cw_anim": "1424", + "examine": "The flag of The Treasure Trove.", + "walk_anim": "1422", + "durability": null, + "weight": "6", + "turn90ccw_anim": "1425", + "weapon_interface": "14", + "turn180_anim": "1423", + "render_anim": "131", + "equipment_slot": "3", + "stand_anim": "1421", + "name": "Treasure flag", + "run_anim": "1427", + "archery_ticket_price": "0", + "id": "8970", + "stand_turn_anim": "1426" + }, + { + "shop_price": "600", + "turn90cw_anim": "1424", + "examine": "The flag of The Phasmatys Pride.", + "walk_anim": "1422", + "durability": null, + "weight": "6", + "turn90ccw_anim": "1425", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "1423", + "render_anim": "131", + "equipment_slot": "3", + "stand_anim": "1421", + "name": "Phasmatys flag", + "run_anim": "1427", + "archery_ticket_price": "0", + "id": "8971", + "stand_turn_anim": "1426" + }, + { + "examine": "A Bowl of red water.", + "durability": null, + "name": "Bowl of red water", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8972" + }, + { + "durability": null, + "name": "Bowl of red water", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8973" + }, + { + "examine": "A Bowl of blue water.", + "durability": null, + "name": "Bowl of blue water", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8974" + }, + { + "durability": null, + "name": "Bowl of blue water", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8975" + }, + { + "examine": "Monkeys seem to like throwing these.", + "durability": null, + "name": "Bitternut", + "archery_ticket_price": "0", + "id": "8976" + }, + { + "examine": "Greasy bark from the scrapey tree.", + "durability": null, + "name": "Scrapey bark", + "weight": "1.1", + "archery_ticket_price": "0", + "id": "8977" + }, + { + "durability": null, + "name": "Scrapey bark", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8978" + }, + { + "examine": "Caution; not for use over troubled water.", + "durability": null, + "name": "Bridge section", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8979" + }, + { + "durability": null, + "name": "Bridge section", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8980" + }, + { + "examine": "Better than sea slugs.", + "durability": null, + "name": "Sweetgrubs", + "archery_ticket_price": "0", + "id": "8981" + }, + { + "durability": null, + "name": "Sweetgrubs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8982" + }, + { + "shop_price": "2", + "examine": "It's an empty bucket.", + "grand_exchange_price": "50", + "durability": null, + "name": "Bucket", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "8986" + }, + { + "durability": null, + "name": "Torch", + "archery_ticket_price": "0", + "id": "8987", + "equipment_slot": "3" + }, + { + "shop_price": "5", + "examine": "Apparently good for brewing.", + "durability": null, + "name": "The stuff", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "8988" + }, + { + "examine": "A how-to of brewing and arson.", + "durability": null, + "name": "Brewin' guide", + "archery_ticket_price": "0", + "id": "8989" + }, + { + "examine": "A how-to of brewing and arson.", + "durability": null, + "name": "Brewin' guide", + "archery_ticket_price": "0", + "id": "8990" + }, + { + "shop_price": "100", + "examine": "Not for slackers", + "durability": null, + "name": "Blue navy slacks", + "archery_ticket_price": "0", + "id": "8991", + "equipment_slot": "7" + }, + { + "shop_price": "100", + "examine": "Not for slackers", + "durability": null, + "name": "Green navy slacks", + "archery_ticket_price": "0", + "id": "8992", + "equipment_slot": "7" + }, + { + "shop_price": "100", + "examine": "Not for slackers", + "durability": null, + "name": "Red navy slacks", + "archery_ticket_price": "0", + "id": "8993", + "equipment_slot": "7" + }, + { + "shop_price": "100", + "examine": "Not for slackers", + "durability": null, + "name": "Brown navy slacks", + "archery_ticket_price": "0", + "id": "8994", + "equipment_slot": "7" + }, + { + "shop_price": "100", + "examine": "Not for slackers", + "durability": null, + "name": "Black navy slacks", + "archery_ticket_price": "0", + "id": "8995", + "equipment_slot": "7" + }, + { + "shop_price": "100", + "examine": "Not for slackers", + "durability": null, + "name": "Purple navy slacks", + "archery_ticket_price": "0", + "id": "8996", + "equipment_slot": "7" + }, + { + "shop_price": "100", + "examine": "Not for slackers", + "durability": null, + "name": "Grey navy slacks", + "archery_ticket_price": "0", + "id": "8997", + "equipment_slot": "7" + }, + { + "durability": null, + "name": "Bandana and eyepatch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8998" + }, + { + "durability": null, + "name": "Bandana and eyepatch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "8999" + }, + { + "durability": null, + "name": "Bandana and eyepatch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9000" + }, + { + "durability": null, + "name": "Bandana and eyepatch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9001" + }, + { + "durability": null, + "name": "Hat and eyepatch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9002" + }, + { + "shop_price": "2", + "ge_buy_limit": "100", + "examine": "WARNING: Contains information which could make your account secure!", + "grand_exchange_price": "100", + "durability": null, + "name": "Security book", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9003" + }, + { + "ge_buy_limit": "100", + "examine": "Information regarding the Stronghold of Security.", + "grand_exchange_price": "16", + "durability": null, + "name": "Stronghold notes", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9004" + }, + { + "destroy_message": "You can get another pair of Fancy Boots from the Stronghold of Security", + "examine": "Very nice boots from the Stronghold of Security.", + "durability": null, + "name": "Fancy boots", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "9005", + "bonuses": "0,0,0,-3,-1,1,2,3,0,0,0,0,0,0,0", + "equip_audio": "2237", + "equipment_slot": "10" + }, + { + "destroy_message": "You can get another pair of Fighting Boots from the Stronghold of Security.", + "examine": "Very nice boots from the Stronghold of Security.", + "durability": null, + "name": "Fighting boots", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "9006", + "bonuses": "0,0,0,-3,-1,1,2,3,0,0,0,0,0,0,0", + "equipment_slot": "10" + }, + { + "examine": "Ooooh spooky!", + "durability": null, + "name": "Right skull half", + "tradeable": "false", + "weight": "1", + "archery_ticket_price": "0", + "id": "9007" + }, + { + "examine": "Ooooh spooky!", + "durability": null, + "name": "Left skull half", + "tradeable": "false", + "destroy": "true", + "weight": "4", + "archery_ticket_price": "0", + "id": "9008" + }, + { + "examine": "Seems to be for use with a staff or sceptre of some sort.", + "durability": null, + "name": "Strange skull", + "tradeable": "false", + "weight": "1.2", + "archery_ticket_price": "0", + "id": "9009" + }, + { + "examine": "Top half of a broken sceptre.", + "durability": null, + "name": "Top of sceptre", + "tradeable": "false", + "weight": "2", + "archery_ticket_price": "0", + "id": "9010" + }, + { + "examine": "Bottom half of a broken sceptre.", + "durability": null, + "name": "Bottom of sceptre", + "tradeable": "false", + "weight": "1.8", + "archery_ticket_price": "0", + "id": "9011" + }, + { + "examine": "Sceptre with runes on it, seems to be missing something.", + "durability": null, + "name": "Runed sceptre", + "tradeable": "false", + "weight": "3.5", + "archery_ticket_price": "0", + "id": "9012" + }, + { + "turn90cw_anim": "1207", + "examine": "A fragile magical Sceptre.", + "walk_anim": "1205", + "durability": null, + "destroy": "true", + "weight": "1.8", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "weapon_interface": "3", + "turn180_anim": "1206", + "equip_audio": "2247", + "render_anim": "28", + "equipment_slot": "3", + "destroy_message": "You can obtain another Sceptre by collecting all four pieces from the Stronghold of Security.", + "stand_anim": "813", + "name": "Skull sceptre", + "tradeable": "false", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "9013", + "stand_turn_anim": "1209", + "bonuses": "0,-1,7,4,0,2,3,1,4,0,0,3,0,0,0" + }, + { + "durability": null, + "name": "Security book", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9014" + }, + { + "durability": null, + "name": "Stronghold notes", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9015" + }, + { + "examine": "Oversized nail clippings.", + "durability": null, + "name": "Gorak claws", + "archery_ticket_price": "0", + "id": "9016" + }, + { + "examine": "A flower with magical properties.", + "durability": null, + "name": "Star flower", + "archery_ticket_price": "0", + "id": "9017" + }, + { + "examine": "Ground-down gorak claws.", + "durability": null, + "name": "Gorak claw powder", + "weight": "1", + "archery_ticket_price": "0", + "id": "9018" + }, + { + "examine": "Contains the Fairy Queen's magical essence.", + "durability": null, + "name": "Queen's secateurs", + "archery_ticket_price": "0", + "id": "9020", + "equipment_slot": "3" + }, + { + "destroy_message": "Maybe I can find another in Fairy Nuff's grotto.", + "examine": "A scroll that says she's a healer, that's Fairy Nuff.", + "durability": null, + "name": "Nuff's certificate", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "9025" + }, + { + "ge_buy_limit": "100", + "examine": "Simon Templeton at the Agility Pyramid will give me 50 coins for this.", + "grand_exchange_price": "187", + "durability": null, + "name": "Ivory comb", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9026" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "187", + "durability": null, + "name": "Ivory comb", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9027" + }, + { + "ge_buy_limit": "100", + "examine": "Simon Templeton at the Agility Pyramid will give me 1000 coins for this.", + "grand_exchange_price": "513", + "durability": null, + "name": "Golden scarab", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9028" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "513", + "durability": null, + "name": "Golden scarab", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9029" + }, + { + "ge_buy_limit": "100", + "examine": "Little ornament in the shape of a scarab.", + "grand_exchange_price": "168", + "durability": null, + "name": "Stone scarab", + "tradeable": "true", + "weight": "0.07", + "archery_ticket_price": "0", + "id": "9030" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "168", + "durability": null, + "name": "Stone scarab", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9031" + }, + { + "ge_buy_limit": "100", + "examine": "A small pottery scarab.", + "grand_exchange_price": "74", + "durability": null, + "name": "Pottery scarab", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "9032" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "74", + "durability": null, + "name": "Pottery scarab", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9033" + }, + { + "ge_buy_limit": "100", + "examine": "A small golden statuette.", + "grand_exchange_price": "740", + "durability": null, + "name": "Golden statuette", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9034" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "740", + "durability": null, + "name": "Golden statuette", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9035" + }, + { + "ge_buy_limit": "100", + "examine": "A small pottery statuette.", + "grand_exchange_price": "97", + "durability": null, + "name": "Pottery statuette", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "9036" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "97", + "durability": null, + "name": "Pottery statuette", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9037" + }, + { + "ge_buy_limit": "100", + "examine": "A small stone statuette.", + "grand_exchange_price": "193", + "durability": null, + "name": "Stone statuette", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9038" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "193", + "durability": null, + "name": "Stone statuette", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9039" + }, + { + "ge_buy_limit": "100", + "examine": "Simon Templeton at the Agility Arena will give me 750 coins for this.", + "grand_exchange_price": "379", + "durability": null, + "name": "Gold seal", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9040" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "379", + "durability": null, + "name": "Gold seal", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9041" + }, + { + "ge_buy_limit": "100", + "examine": "Simon Templeton at the Agility Pyramid will give me 150 coins for this.", + "grand_exchange_price": "147", + "durability": null, + "name": "Stone seal", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9042" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "147", + "durability": null, + "name": "Stone seal", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9043" + }, + { + "requirements": "{0,30}-{6,30}", + "ge_buy_limit": "10", + "turn90cw_anim": "1207", + "examine": "This sceptre is fully charged.", + "walk_anim": "1205", + "durability": null, + "destroy": "true", + "weight": "2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "3", + "turn180_anim": "1206", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "1000000", + "stand_anim": "813", + "tradeable": "true", + "name": "Pharaoh's sceptre", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "9044", + "stand_turn_anim": "1209", + "bonuses": "7,-1,25,10,0,2,3,1,10,0,0,32,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "1000000", + "durability": null, + "name": "Pharaoh's sceptre", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9045" + }, + { + "requirements": "{0,30}-{6,30}", + "turn90cw_anim": "1207", + "examine": "This sceptre has two charges left.", + "walk_anim": "1205", + "durability": null, + "destroy": "true", + "weight": "2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "3", + "turn180_anim": "1206", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "27", + "stand_anim": "813", + "tradeable": "true", + "name": "Pharaoh's sceptre", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "9046", + "stand_turn_anim": "1209", + "bonuses": "7,-1,25,10,0,2,3,1,10,0,0,32,0,0,0" + }, + { + "durability": null, + "name": "Pharaoh's sceptre", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9047" + }, + { + "requirements": "{0,30}-{6,30}", + "turn90cw_anim": "1207", + "examine": "This sceptre has one charge left.", + "walk_anim": "1205", + "durability": null, + "destroy": "true", + "weight": "2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "3", + "turn180_anim": "1206", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "27", + "stand_anim": "813", + "tradeable": "true", + "name": "Pharaoh's sceptre", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "9048", + "stand_turn_anim": "1209", + "bonuses": "7,-1,25,10,0,2,3,1,10,0,0,32,0,0,0" + }, + { + "durability": null, + "name": "Pharaoh's sceptre", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9049" + }, + { + "requirements": "{0,30}-{6,30}", + "ge_buy_limit": "10", + "turn90cw_anim": "1207", + "examine": "This sceptre has no charges left.", + "walk_anim": "1205", + "durability": null, + "destroy": "true", + "weight": "2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "3", + "turn180_anim": "1206", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "985800", + "stand_anim": "813", + "tradeable": "true", + "name": "Pharaoh's sceptre", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "9050", + "stand_turn_anim": "1209", + "bonuses": "7,-1,25,10,0,2,3,1,10,0,0,32,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "985800", + "durability": null, + "name": "Pharaoh's sceptre", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9051" + }, + { + "ge_buy_limit": "1000", + "examine": "Delicious and nutritious. Well, nutritious anyway.", + "grand_exchange_price": "68", + "durability": null, + "name": "Locust meat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9052" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "68", + "durability": null, + "name": "Locust meat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9053" + }, + { + "examine": "Armour designed to fit goblins.", + "durability": null, + "name": "Red goblin mail", + "weight": "3", + "archery_ticket_price": "0", + "id": "9054", + "equipment_slot": "4" + }, + { + "examine": "Armour designed to fit goblins.", + "durability": null, + "name": "Black goblin mail", + "weight": "3", + "archery_ticket_price": "0", + "id": "9055", + "equipment_slot": "4" + }, + { + "examine": "Armour designed to fit goblins.", + "durability": null, + "name": "Yellow goblin mail", + "weight": "3", + "archery_ticket_price": "0", + "id": "9056", + "equipment_slot": "4" + }, + { + "examine": "Armour designed to fit goblins.", + "durability": null, + "name": "Green goblin mail", + "weight": "3", + "archery_ticket_price": "0", + "id": "9057", + "equipment_slot": "4" + }, + { + "examine": "Armour designed to fit goblins.", + "durability": null, + "name": "Purple goblin mail", + "weight": "3", + "archery_ticket_price": "0", + "id": "9058", + "equipment_slot": "4" + }, + { + "examine": "Armour designed to fit goblins.", + "durability": null, + "name": "Pink goblin mail", + "weight": "3", + "archery_ticket_price": "0", + "id": "9059", + "equipment_slot": "4" + }, + { + "examine": "A mystical lantern casting a green beam.", + "durability": null, + "name": "Emerald lantern", + "weight": "1.3", + "archery_ticket_price": "0", + "id": "9064" + }, + { + "examine": "A mystical lantern casting a green beam.", + "durability": null, + "name": "Emerald lantern", + "weight": "1.3", + "archery_ticket_price": "0", + "id": "9065", + "equipment_slot": "5" + }, + { + "examine": "A roughly circular disc of glass.", + "durability": null, + "name": "Emerald lens", + "archery_ticket_price": "0", + "id": "9066" + }, + { + "examine": "A log of my thoughts...", + "durability": null, + "name": "Dream log", + "weight": "1", + "archery_ticket_price": "0", + "id": "9067" + }, + { + "shop_price": "1000", + "examine": "Mystical headgear.", + "durability": null, + "name": "Moonclan helm", + "archery_ticket_price": "0", + "id": "9068", + "bonuses": "0,0,0,3,-5,3,3,3,3,-5,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "shop_price": "1000", + "examine": "A mystical hat.", + "durability": null, + "name": "Moonclan hat", + "weight": "1", + "archery_ticket_price": "0", + "id": "9069", + "bonuses": "0,0,0,3,-5,3,3,3,3,-5,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "remove_sleeves": "true", + "shop_price": "1000", + "examine": "Provides good protection.", + "durability": null, + "name": "Moonclan armour", + "weight": "4", + "archery_ticket_price": "0", + "id": "9070", + "bonuses": "0,0,0,5,-10,5,5,5,5,-10,5,0,0,0,0", + "equipment_slot": "4" + }, + { + "shop_price": "1000", + "examine": "This should protect my legs.", + "durability": null, + "name": "Moonclan skirt", + "weight": "3", + "archery_ticket_price": "0", + "id": "9071", + "bonuses": "0,0,0,5,-7,5,5,5,5,-7,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "shop_price": "900", + "examine": "These should keep my hands safe.", + "durability": null, + "name": "Moonclan gloves", + "archery_ticket_price": "0", + "id": "9072", + "bonuses": "0,0,0,2,-5,2,2,2,2,-5,2,0,0,0,0", + "equipment_slot": "9" + }, + { + "shop_price": "900", + "examine": "Groovy foot protection.", + "durability": null, + "name": "Moonclan boots", + "archery_ticket_price": "0", + "id": "9073", + "bonuses": "0,0,0,2,-5,2,2,2,2,-5,0,0,0,0,0", + "equipment_slot": "10" + }, + { + "shop_price": "200", + "examine": "A mystical cape.", + "durability": null, + "name": "Moonclan cape", + "archery_ticket_price": "0", + "id": "9074", + "bonuses": "0,0,0,2,-2,0,1,1,2,-2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "shop_price": "220", + "ge_buy_limit": "25000", + "examine": "Used for Lunar Spells", + "grand_exchange_price": "231", + "durability": null, + "name": "Astral rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9075" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "This needs refining", + "durability": null, + "name": "Lunar ore", + "weight": "7", + "archery_ticket_price": "0", + "id": "9076" + }, + { + "destroy_message": "You'll have to mine another lunar ore and smelt it.", + "examine": "It's a bar of magic metal.", + "durability": null, + "name": "Lunar bar", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "9077" + }, + { + "examine": "A book of Moonclan history.", + "durability": null, + "name": "Moonclan manual", + "weight": "1", + "archery_ticket_price": "0", + "id": "9078" + }, + { + "examine": "The tooth, the whole tooth, and nothing but the tooth.", + "durability": null, + "name": "Suqah tooth", + "archery_ticket_price": "0", + "id": "9079" + }, + { + "examine": "An untanned piece of suqah hide.", + "durability": null, + "name": "Suqah hide", + "archery_ticket_price": "0", + "id": "9080" + }, + { + "examine": "A piece of Suqah hide that has been expertly tanned into leather.", + "durability": null, + "name": "Suqah leather", + "weight": "3", + "archery_ticket_price": "0", + "id": "9081" + }, + { + "examine": "A ground Suqah tooth.", + "durability": null, + "name": "Ground tooth", + "archery_ticket_price": "0", + "id": "9082" + }, + { + "destroy_message": "Brundt the Chieftain will probably have another lying around somewhere anyway...", + "examine": "A seal of passage issued by Brundt the Chieftain of the Fremennik.", + "durability": null, + "name": "Seal of passage", + "tradeable": "false", + "destroy": "true", + "weight": "4.5", + "archery_ticket_price": "0", + "id": "9083", + "equipment_slot": "2" + }, + { + "turn90cw_anim": "1207", + "examine": "A Moonclan staff.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "turn180_anim": "1206", + "equipment_slot": "3", + "destroy_message": "The Oneiromancer might be able to help you get another.", + "stand_anim": "813", + "tradeable": "false", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "9084", + "stand_turn_anim": "1209", + "bonuses": "3,2,16,13,0,2,3,2,13,1,0,15,3,0,0", + "requirements": "{6,65}", + "shop_price": "30000", + "durability": null, + "destroy": "true", + "weight": "2.2", + "weapon_interface": "1", + "equip_audio": "2247", + "render_anim": "28", + "attack_audios": "2555,0,0,0", + "name": "Lunar staff" + }, + { + "destroy_message": "You'll have to get another from the Oneiromancer.", + "examine": "A vessel for holding liquid.", + "durability": null, + "name": "Empty vial", + "destroy": "true", + "archery_ticket_price": "0", + "id": "9085" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "shop_price": "10", + "examine": "A glass vial containing water.", + "grand_exchange_price": "21", + "durability": null, + "name": "Vial of water", + "tradeable": "true", + "weight": "0.02", + "archery_ticket_price": "0", + "id": "9086" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A vessel for dreaming while awake!", + "durability": null, + "name": "Waking sleep vial", + "archery_ticket_price": "0", + "id": "9087" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A vessel with water and Guam inside.", + "durability": null, + "name": "Guam vial", + "archery_ticket_price": "0", + "id": "9088" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A vessel with water and Marrentill inside.", + "durability": null, + "name": "Marr vial", + "archery_ticket_price": "0", + "id": "9089" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A vessel with water, guam and marrentill inside.", + "durability": null, + "name": "Guam-marr vial", + "archery_ticket_price": "0", + "id": "9090" + }, + { + "requirements": "{6,65}", + "turn90cw_anim": "1207", + "examine": "A staff enchanted by air.", + "walk_anim": "1205", + "durability": null, + "destroy": "true", + "weight": "1", + "turn90ccw_anim": "1208", + "weapon_interface": "1", + "turn180_anim": "1206", + "equip_audio": "2247", + "render_anim": "28", + "equipment_slot": "3", + "destroy_message": "You can reclaim this item from the place you found it.", + "stand_anim": "813", + "attack_audios": "2555,0,0,0", + "name": "Lunar staff - pt1", + "tradeable": "false", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "9091", + "stand_turn_anim": "1209", + "bonuses": "-1,-1,10,10,0,2,3,1,10,0,0,10,0,0,0" + }, + { + "requirements": "{6,65}", + "turn90cw_anim": "1207", + "examine": "A staff enchanted by air and fire.", + "walk_anim": "1205", + "durability": null, + "destroy": "true", + "weight": "1", + "turn90ccw_anim": "1208", + "weapon_interface": "1", + "turn180_anim": "1206", + "equip_audio": "2247", + "render_anim": "28", + "equipment_slot": "3", + "destroy_message": "You can reclaim this item from the place you found it.", + "stand_anim": "813", + "attack_audios": "2555,0,0,0", + "name": "Lunar staff - pt2", + "tradeable": "false", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "9092", + "stand_turn_anim": "1209", + "bonuses": "-1,-1,10,10,0,2,3,1,10,0,0,10,0,0,0" + }, + { + "requirements": "{6,65}", + "turn90cw_anim": "1207", + "examine": "A staff enchanted by air, fire and water.", + "walk_anim": "1205", + "durability": null, + "destroy": "true", + "weight": "1", + "turn90ccw_anim": "1208", + "weapon_interface": "1", + "turn180_anim": "1206", + "equip_audio": "2247", + "render_anim": "28", + "equipment_slot": "3", + "destroy_message": "You can reclaim this item from the place you found it.", + "stand_anim": "813", + "attack_audios": "2555,0,0,0", + "name": "Lunar staff - pt3", + "tradeable": "false", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "9093", + "stand_turn_anim": "1209", + "bonuses": "-1,-1,10,10,0,2,3,1,10,0,0,10,0,0,0" + }, + { + "examine": "Small bits of wood from the first magic tree!", + "durability": null, + "name": "Kindling", + "archery_ticket_price": "0", + "id": "9094" + }, + { + "examine": "Magic wood soaked with a potion of waking sleep. Groovy.", + "durability": null, + "name": "Soaked kindling", + "archery_ticket_price": "0", + "id": "9095" + }, + { + "remove_head": "true", + "requirements": "{1,40}-{6,65}", + "shop_price": "15000", + "examine": "A mystical helmet.", + "durability": null, + "destroy": "true", + "weight": "0.9", + "absorb": "3,1,0", + "remove_beard": "true", + "equipment_slot": "0", + "destroy_message": "The Oneiromancer might be able to help you get another.", + "name": "Lunar helm", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "9096", + "bonuses": "0,0,0,3,-2,8,7,10,2,0,7,0,0,0,0" + }, + { + "requirements": "{1,40}-{6,65}", + "shop_price": "120000", + "examine": "Provides good protection.", + "durability": null, + "destroy": "true", + "weight": "4.5", + "absorb": "6,3,0", + "equipment_slot": "4", + "destroy_message": "The Oneiromancer might be able to help you get another.", + "remove_sleeves": "true", + "name": "Lunar torso", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "9097", + "bonuses": "0,0,0,10,-10,34,22,40,12,0,35,0,0,0,0" + }, + { + "requirements": "{1,40}-{6,65}", + "shop_price": "80000", + "examine": "These should protect my legs.", + "durability": null, + "destroy": "true", + "weight": "3.65", + "absorb": "4,2,0", + "equipment_slot": "7", + "destroy_message": "The Oneiromancer might be able to help you get another.", + "name": "Lunar legs", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "9098", + "bonuses": "0,0,0,7,-7,20,19,23,9,0,20,0,0,0,0" + }, + { + "requirements": "{1,40}-{6,65}", + "shop_price": "10000", + "examine": "These should keep my hands safe.", + "durability": null, + "destroy": "true", + "weight": "0.9", + "equipment_slot": "9", + "destroy_message": "The Oneiromancer might be able to help you get another.", + "name": "Lunar gloves", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "9099", + "bonuses": "0,0,0,4,-1,2,1,1,2,0,1,0,0,0,0" + }, + { + "requirements": "{1,40}-{6,65}", + "shop_price": "10000", + "examine": "Mystical foot protection.", + "durability": null, + "destroy": "true", + "weight": "0.9", + "equipment_slot": "10", + "destroy_message": "The Oneiromancer might be able to help you get another.", + "name": "Lunar boots", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "9100", + "bonuses": "0,0,0,2,-1,1,2,2,2,0,2,0,0,0,0" + }, + { + "requirements": "{1,40}-{6,65}", + "shop_price": "12000", + "examine": "Oooo pretty!", + "durability": null, + "destroy": "true", + "weight": "0.4", + "equipment_slot": "1", + "destroy_message": "The Oneiromancer might be able to help you get another.", + "name": "Lunar cape", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "9101", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0" + }, + { + "destroy_message": "The Oneiromancer might be able to help you get another.", + "requirements": "{1,40}-{6,65}", + "shop_price": "4000", + "examine": "Awesome.", + "durability": null, + "name": "Lunar amulet", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "9102", + "bonuses": "0,0,0,1,0,0,0,0,1,0,0,0,0,0,0", + "equipment_slot": "2" + }, + { + "destroy_message": "The Oneiromancer might be able to help you get another.", + "examine": "I'll be the talk of the town with this... maybe.", + "durability": null, + "name": "A special tiara", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "9103" + }, + { + "destroy_message": "The Oneiromancer might be able to help you get another.", + "requirements": "{1,40}-{6,65}", + "shop_price": "2000", + "examine": "A mysterious ring that can fill the wearer with magical power.", + "durability": null, + "name": "Lunar ring", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "9104", + "bonuses": "0,0,0,2,0,0,0,0,2,0,0,0,0,0,0", + "equipment_slot": "12" + }, + { + "durability": null, + "name": "Astral tiara", + "archery_ticket_price": "0", + "id": "9106", + "equipment_slot": "0" + }, + { + "requirements": "{4,16}", + "examine": "Blurite crossbow bolts.", + "durability": null, + "name": "Blurite bolts", + "archery_ticket_price": "0", + "id": "9139", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,28", + "equipment_slot": "13" + }, + { + "requirements": "{4,26}", + "shop_price": "60", + "ge_buy_limit": "25000", + "examine": "Iron crossbow bolts.", + "grand_exchange_price": "41", + "durability": null, + "name": "Iron bolts", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9140", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,46", + "equipment_slot": "13" + }, + { + "requirements": "{4,31}", + "shop_price": "150", + "ge_buy_limit": "10000", + "examine": "Steel crossbow bolts.", + "grand_exchange_price": "90", + "durability": null, + "name": "Steel bolts", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9141", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,64", + "equipment_slot": "13" + }, + { + "requirements": "{4,36}", + "shop_price": "32", + "ge_buy_limit": "10000", + "examine": "Mithril crossbow bolts.", + "grand_exchange_price": "108", + "durability": null, + "name": "Mithril bolts", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9142", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,82", + "equipment_slot": "13" + }, + { + "requirements": "{4,46}", + "shop_price": "23", + "ge_buy_limit": "10000", + "examine": "Adamantite crossbow bolts.", + "grand_exchange_price": "210", + "durability": null, + "name": "Adamant bolts", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9143", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,100", + "equipment_slot": "13" + }, + { + "requirements": "{4,61}", + "ge_buy_limit": "10000", + "examine": "Runite crossbow bolts.", + "grand_exchange_price": "627", + "durability": null, + "name": "Rune bolts", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9144", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,115", + "equipment_slot": "13" + }, + { + "requirements": "{4,26}", + "shop_price": "6", + "ge_buy_limit": "10000", + "examine": "Silver crossbow bolts.", + "grand_exchange_price": "8", + "durability": null, + "name": "Silver bolts", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9145", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,36", + "equipment_slot": "13" + }, + { + "ge_buy_limit": "500", + "turn90cw_anim": "821", + "examine": "A bronze crossbow.", + "walk_anim": "4226", + "turn90ccw_anim": "822", + "attack_speed": "6", + "turn180_anim": "4227", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "4230,4230,4230,4230", + "grand_exchange_price": "29", + "stand_anim": "4591", + "tradeable": "true", + "run_anim": "4228", + "archery_ticket_price": "0", + "id": "9174", + "stand_turn_anim": "823", + "bonuses": "0,0,0,0,18,0,0,0,0,0,0,0,0,0,0", + "shop_price": "92", + "durability": null, + "weight": "4", + "weapon_interface": "17", + "equip_audio": "2244", + "render_anim": "175", + "attack_audios": "2700,0,0,0", + "name": "Bronze crossbow" + }, + { + "ge_buy_limit": "500", + "grand_exchange_price": "29", + "durability": null, + "name": "Bronze crossbow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9175" + }, + { + "requirements": "{4,16}", + "turn90cw_anim": "821", + "examine": "A blurite crossbow.", + "walk_anim": "4226", + "durability": null, + "weight": "4", + "turn90ccw_anim": "822", + "attack_speed": "6", + "weapon_interface": "17", + "turn180_anim": "4227", + "equip_audio": "2244", + "render_anim": "175", + "equipment_slot": "3", + "attack_anims": "4230,4230,4230,4230", + "stand_anim": "4591", + "attack_audios": "2700,0,0,0", + "name": "Blurite crossbow", + "run_anim": "4228", + "archery_ticket_price": "0", + "id": "9176", + "stand_turn_anim": "823", + "bonuses": "0,0,0,0,30,0,0,0,0,0,0,0,0,0,0" + }, + { + "ge_buy_limit": "500", + "turn90cw_anim": "821", + "examine": "An iron crossbow.", + "walk_anim": "4226", + "turn90ccw_anim": "822", + "attack_speed": "6", + "turn180_anim": "4227", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "4230,4230,4230,4230", + "grand_exchange_price": "20", + "stand_anim": "4591", + "tradeable": "true", + "run_anim": "4228", + "archery_ticket_price": "0", + "id": "9177", + "stand_turn_anim": "823", + "bonuses": "0,0,0,0,42,0,0,0,0,0,0,0,0,0,0", + "requirements": "{4,26}", + "shop_price": "157", + "durability": null, + "weight": "4", + "weapon_interface": "17", + "equip_audio": "2244", + "render_anim": "175", + "attack_audios": "2700,0,0,0", + "name": "Iron crossbow" + }, + { + "ge_buy_limit": "500", + "grand_exchange_price": "20", + "durability": null, + "name": "Iron crossbow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9178" + }, + { + "ge_buy_limit": "500", + "turn90cw_anim": "821", + "examine": "A steel crossbow.", + "walk_anim": "4226", + "turn90ccw_anim": "822", + "attack_speed": "6", + "turn180_anim": "4227", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "4230,4230,4230,4230", + "grand_exchange_price": "99", + "stand_anim": "4591", + "tradeable": "true", + "run_anim": "4228", + "archery_ticket_price": "0", + "id": "9179", + "stand_turn_anim": "823", + "bonuses": "0,0,0,0,54,0,0,0,0,0,0,0,0,0,0", + "requirements": "{4,31}", + "durability": null, + "weight": "5", + "weapon_interface": "17", + "equip_audio": "2244", + "render_anim": "175", + "attack_audios": "2700,0,0,0", + "name": "Steel crossbow" + }, + { + "ge_buy_limit": "500", + "grand_exchange_price": "99", + "durability": null, + "name": "Steel crossbow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9180" + }, + { + "ge_buy_limit": "500", + "turn90cw_anim": "821", + "examine": "A mithril crossbow", + "walk_anim": "4226", + "turn90ccw_anim": "822", + "attack_speed": "6", + "turn180_anim": "4227", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "4230,4230,4230,4230", + "grand_exchange_price": "355", + "stand_anim": "4591", + "tradeable": "true", + "run_anim": "4228", + "archery_ticket_price": "0", + "id": "9181", + "stand_turn_anim": "823", + "bonuses": "0,0,0,0,66,0,0,0,0,0,0,0,0,0,0", + "requirements": "{4,36}", + "durability": null, + "weight": "6", + "weapon_interface": "17", + "equip_audio": "2244", + "render_anim": "175", + "attack_audios": "2700,0,0,0", + "name": "Mith crossbow" + }, + { + "ge_buy_limit": "500", + "grand_exchange_price": "355", + "durability": null, + "name": "Mith crossbow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9182" + }, + { + "ge_buy_limit": "500", + "turn90cw_anim": "821", + "examine": "An adamantite crossbow.", + "walk_anim": "4226", + "turn90ccw_anim": "822", + "attack_speed": "6", + "turn180_anim": "4227", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "4230,4230,4230,4230", + "grand_exchange_price": "905", + "stand_anim": "4591", + "tradeable": "true", + "run_anim": "4228", + "archery_ticket_price": "0", + "id": "9183", + "stand_turn_anim": "823", + "bonuses": "0,0,0,0,78,0,0,0,0,0,0,0,0,0,0", + "requirements": "{4,46}", + "shop_price": "2244", + "durability": null, + "weight": "6", + "weapon_interface": "17", + "equip_audio": "2244", + "render_anim": "175", + "attack_audios": "2700,0,0,0", + "name": "Adamant crossbow" + }, + { + "ge_buy_limit": "500", + "grand_exchange_price": "905", + "durability": null, + "name": "Adamant crossbow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9184" + }, + { + "ge_buy_limit": "500", + "turn90cw_anim": "821", + "examine": "A runite crossbow.", + "walk_anim": "4226", + "turn90ccw_anim": "822", + "attack_speed": "6", + "turn180_anim": "4227", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "4230,4230,4230,4230", + "grand_exchange_price": "9706", + "stand_anim": "4591", + "tradeable": "true", + "run_anim": "4228", + "archery_ticket_price": "0", + "id": "9185", + "stand_turn_anim": "823", + "bonuses": "0,0,0,0,90,0,0,0,0,0,0,0,0,0,0", + "requirements": "{4,61}", + "shop_price": "16200", + "durability": null, + "weight": "6", + "weapon_interface": "17", + "equip_audio": "2244", + "render_anim": "175", + "lendable": "true", + "attack_audios": "2700,0,0,0", + "name": "Rune crossbow" + }, + { + "ge_buy_limit": "500", + "grand_exchange_price": "9706", + "durability": null, + "name": "Rune crossbow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9186" + }, + { + "ge_buy_limit": "10000", + "examine": "Jade bolt tips.", + "grand_exchange_price": "2", + "durability": null, + "name": "Jade bolt tips", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9187" + }, + { + "ge_buy_limit": "10000", + "examine": "Red Topaz bolt tips.", + "grand_exchange_price": "2", + "durability": null, + "name": "Topaz bolt tips", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9188" + }, + { + "ge_buy_limit": "10000", + "examine": "Sapphire bolt tips.", + "grand_exchange_price": "4", + "durability": null, + "name": "Sapphire bolt tips", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9189" + }, + { + "ge_buy_limit": "10000", + "examine": "Emerald bolt tips.", + "grand_exchange_price": "84", + "durability": null, + "name": "Emerald bolt tips", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9190" + }, + { + "ge_buy_limit": "10000", + "examine": "Ruby bolt tips.", + "grand_exchange_price": "159", + "durability": null, + "name": "Ruby bolt tips", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9191" + }, + { + "ge_buy_limit": "10000", + "examine": "Diamond bolt tips.", + "grand_exchange_price": "1289", + "durability": null, + "name": "Diamond bolt tips", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9192" + }, + { + "ge_buy_limit": "10000", + "examine": "Dragonstone bolt tips.", + "grand_exchange_price": "2477", + "durability": null, + "name": "Dragon bolt tips", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9193" + }, + { + "shop_price": "13500", + "ge_buy_limit": "10000", + "examine": "Onyx bolt tips.", + "grand_exchange_price": "8096", + "tokkul_price": "1500", + "durability": null, + "name": "Onyx bolt tips", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9194" + }, + { + "ge_buy_limit": "25000", + "examine": "Enchanted Opal tipped Bronze Crossbow Bolts.", + "grand_exchange_price": "10", + "durability": null, + "name": "Opal bolts (e)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9236", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,14", + "equipment_slot": "13" + }, + { + "requirements": "{4,15}", + "examine": "Enchanted Jade tipped Blurite Crossbow Bolts.", + "durability": null, + "name": "Jade bolts (e)", + "archery_ticket_price": "0", + "id": "9237", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,30", + "equipment_slot": "13" + }, + { + "requirements": "{4,26}", + "ge_buy_limit": "25000", + "examine": "Enchanted Pearl tipped Iron Crossbow Bolts.", + "grand_exchange_price": "36", + "durability": null, + "name": "Pearl bolts (e)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9238", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,48", + "equipment_slot": "13" + }, + { + "requirements": "{4,31}", + "ge_buy_limit": "25000", + "examine": "Enchanted Red Topaz tipped Steel Crossbow Bolts.", + "grand_exchange_price": "44", + "durability": null, + "name": "Topaz bolts (e)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9239", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,66", + "equipment_slot": "13" + }, + { + "requirements": "{4,36}", + "shop_price": "103", + "ge_buy_limit": "25000", + "examine": "Enchanted Sapphire tipped Mithril Crossbow Bolts.", + "grand_exchange_price": "95", + "durability": null, + "name": "Sapphire bolts (e)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9240", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,83", + "equipment_slot": "13" + }, + { + "requirements": "{4,36}", + "ge_buy_limit": "25000", + "examine": "Enchanted Emerald tipped Mithril Crossbow Bolts.", + "grand_exchange_price": "304", + "durability": null, + "name": "Emerald bolts (e)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9241", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,85", + "equipment_slot": "13" + }, + { + "requirements": "{4,46}", + "ge_buy_limit": "25000", + "examine": "Enchanted Ruby tipped Adamantite Crossbow Bolts.", + "grand_exchange_price": "450", + "durability": null, + "name": "Ruby bolts (e)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9242", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,103", + "equipment_slot": "13" + }, + { + "requirements": "{4,46}", + "ge_buy_limit": "25000", + "examine": "Enchanted Diamond tipped Adamantite Crossbow Bolts.", + "grand_exchange_price": "1631", + "durability": null, + "name": "Diamond bolts (e)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9243", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,105", + "equipment_slot": "13" + }, + { + "requirements": "{4,61}", + "ge_buy_limit": "25000", + "examine": "Enchanted Dragonstone tipped Runite Crossbow Bolts.", + "grand_exchange_price": "3217", + "durability": null, + "name": "Dragon bolts (e)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9244", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,117", + "equipment_slot": "13" + }, + { + "requirements": "{4,61}", + "ge_buy_limit": "25000", + "examine": "Enchanted Onyx tipped runite Crossbow Bolts.", + "grand_exchange_price": "8870", + "durability": null, + "name": "Onyx bolts (e)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9245", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,120", + "equipment_slot": "13" + }, + { + "requirements": "{4,16}", + "durability": null, + "name": "Blurite bolts(p)", + "archery_ticket_price": "0", + "id": "9286", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,28", + "equipment_slot": "13" + }, + { + "requirements": "{4,26}", + "shop_price": "60", + "ge_buy_limit": "25000", + "examine": "Iron crossbow bolts.", + "grand_exchange_price": "88", + "durability": null, + "name": "Iron bolts (p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9287", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,46", + "equipment_slot": "13" + }, + { + "requirements": "{4,31}", + "ge_buy_limit": "10000", + "examine": "Steel crossbow bolts.", + "grand_exchange_price": "132", + "durability": null, + "name": "Steel bolts (p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9288", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,64", + "equipment_slot": "13" + }, + { + "requirements": "{4,36}", + "shop_price": "32", + "ge_buy_limit": "10000", + "examine": "Mithril crossbow bolts.", + "grand_exchange_price": "146", + "durability": null, + "name": "Mithril bolts (p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9289", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,82", + "equipment_slot": "13" + }, + { + "requirements": "{4,46}", + "shop_price": "23", + "ge_buy_limit": "10000", + "examine": "Adamantite crossbow bolts.", + "grand_exchange_price": "302", + "durability": null, + "name": "Adamant bolts (p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9290", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,100", + "equipment_slot": "13" + }, + { + "requirements": "{4,61}", + "ge_buy_limit": "10000", + "examine": "Runite crossbow bolts.", + "grand_exchange_price": "734", + "durability": null, + "name": "Runite bolts (p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9291", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,115", + "equipment_slot": "13" + }, + { + "requirements": "{4,26}", + "shop_price": "6", + "ge_buy_limit": "10000", + "examine": "Silver crossbow bolts.", + "grand_exchange_price": "34", + "durability": null, + "name": "Silver bolts (p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9292", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,36", + "equipment_slot": "13" + }, + { + "requirements": "{4,16}", + "durability": null, + "name": "Blurite bolts(p+)", + "archery_ticket_price": "0", + "id": "9293", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,28", + "equipment_slot": "13" + }, + { + "requirements": "{4,26}", + "shop_price": "60", + "ge_buy_limit": "25000", + "examine": "Iron crossbow bolts.", + "grand_exchange_price": "185", + "durability": null, + "name": "Iron bolts(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9294", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,46", + "equipment_slot": "13" + }, + { + "requirements": "{4,31}", + "ge_buy_limit": "10000", + "examine": "Steel crossbow bolts.", + "grand_exchange_price": "215", + "durability": null, + "name": "Steel bolts(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9295", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,64", + "equipment_slot": "13" + }, + { + "requirements": "{4,36}", + "shop_price": "32", + "ge_buy_limit": "10000", + "examine": "Mithril crossbow bolts.", + "grand_exchange_price": "296", + "durability": null, + "name": "Mithril bolts(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9296", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,82", + "equipment_slot": "13" + }, + { + "requirements": "{4,46}", + "ge_buy_limit": "10000", + "grand_exchange_price": "472", + "durability": null, + "name": "Adamant bolts(p+)", + "archery_ticket_price": "0", + "id": "9297", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,100", + "equipment_slot": "13" + }, + { + "requirements": "{4,61}", + "ge_buy_limit": "10000", + "examine": "Runite crossbow bolts.", + "grand_exchange_price": "1130", + "durability": null, + "name": "Runite bolts(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9298", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,115", + "equipment_slot": "13" + }, + { + "requirements": "{4,26}", + "shop_price": "6", + "ge_buy_limit": "10000", + "examine": "Silver crossbow bolts.", + "grand_exchange_price": "129", + "durability": null, + "name": "Silver bolts(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9299", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,36", + "equipment_slot": "13" + }, + { + "requirements": "{4,16}", + "durability": null, + "name": "Blurite bolts(p++)", + "archery_ticket_price": "0", + "id": "9300", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,28", + "equipment_slot": "13" + }, + { + "requirements": "{4,26}", + "shop_price": "60", + "ge_buy_limit": "25000", + "examine": "Iron crossbow bolts.", + "grand_exchange_price": "1136", + "durability": null, + "name": "Iron bolts(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9301", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,46", + "equipment_slot": "13" + }, + { + "requirements": "{4,31}", + "ge_buy_limit": "10000", + "examine": "Steel crossbow bolts.", + "grand_exchange_price": "1088", + "durability": null, + "name": "Steel bolts(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9302", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,64", + "equipment_slot": "13" + }, + { + "requirements": "{4,36}", + "shop_price": "32", + "ge_buy_limit": "10000", + "examine": "Mithril crossbow bolts.", + "grand_exchange_price": "903", + "durability": null, + "name": "Mithril bolts(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9303", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,82", + "equipment_slot": "13" + }, + { + "requirements": "{4,46}", + "ge_buy_limit": "10000", + "grand_exchange_price": "1043", + "durability": null, + "name": "Adamant bolts(p++)", + "archery_ticket_price": "0", + "id": "9304", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,100", + "equipment_slot": "13" + }, + { + "requirements": "{4,61}", + "ge_buy_limit": "10000", + "examine": "Runite crossbow bolts.", + "grand_exchange_price": "1581", + "durability": null, + "name": "Runite bolts(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9305", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,115", + "equipment_slot": "13" + }, + { + "requirements": "{4,26}", + "shop_price": "6", + "ge_buy_limit": "10000", + "examine": "Silver crossbow bolts.", + "grand_exchange_price": "1211", + "durability": null, + "name": "Silver bolts(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9306", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,36", + "equipment_slot": "13" + }, + { + "requirements": "{4,16}", + "examine": "Jade tipped blurite bolts.", + "durability": null, + "name": "Jade bolts", + "archery_ticket_price": "0", + "id": "9335", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,30", + "equipment_slot": "13" + }, + { + "requirements": "{4,31}", + "shop_price": "62", + "ge_buy_limit": "25000", + "examine": "Red Topaz tipped Steel Crossbow Bolts.", + "grand_exchange_price": "60", + "durability": null, + "name": "Topaz bolts", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9336", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,66", + "equipment_slot": "13" + }, + { + "requirements": "{4,36}", + "ge_buy_limit": "25000", + "examine": "Sapphire tipped Mithril crossbow bolts.", + "grand_exchange_price": "89", + "durability": null, + "name": "Sapphire bolts", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9337", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,83", + "equipment_slot": "13" + }, + { + "requirements": "{4,36}", + "ge_buy_limit": "25000", + "examine": "Emerald tipped Mithril crossbow bolts.", + "grand_exchange_price": "177", + "durability": null, + "name": "Emerald bolts", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9338", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,85", + "equipment_slot": "13" + }, + { + "requirements": "{4,46}", + "ge_buy_limit": "25000", + "examine": "Ruby tipped Adamantite crossbow bolts.", + "grand_exchange_price": "408", + "durability": null, + "name": "Ruby bolts", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9339", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,103", + "equipment_slot": "13" + }, + { + "requirements": "{4,46}", + "ge_buy_limit": "25000", + "examine": "Diamond tipped Adamantite crossbow bolts.", + "grand_exchange_price": "1545", + "durability": null, + "name": "Diamond bolts", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9340", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,105", + "equipment_slot": "13" + }, + { + "requirements": "{4,61}", + "ge_buy_limit": "25000", + "examine": "Dragonstone tipped Runite crossbow bolts.", + "grand_exchange_price": "3201", + "durability": null, + "name": "Dragon bolts", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9341", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,117", + "equipment_slot": "13" + }, + { + "requirements": "{4,61}", + "ge_buy_limit": "25000", + "examine": "Onyx tipped Runite crossbow bolts.", + "grand_exchange_price": "8752", + "durability": null, + "name": "Onyx bolts", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9342", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,120", + "equipment_slot": "13" + }, + { + "shop_price": "1", + "ge_buy_limit": "10000", + "examine": "Unfeathered bronze crossbow bolts.", + "grand_exchange_price": "3", + "durability": null, + "name": "Bronze bolts (unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9375" + }, + { + "examine": "Unfeathered blurite crossbow bolts.", + "durability": null, + "name": "Blurite bolts (unf)", + "archery_ticket_price": "0", + "id": "9376" + }, + { + "shop_price": "2", + "ge_buy_limit": "10000", + "examine": "Unfeathered iron crossbow bolts.", + "grand_exchange_price": "14", + "durability": null, + "name": "Iron bolts (unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9377" + }, + { + "ge_buy_limit": "10000", + "examine": "Unfeathered steel crossbow bolts.", + "grand_exchange_price": "61", + "durability": null, + "name": "Steel bolts (unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9378" + }, + { + "ge_buy_limit": "10000", + "examine": "Unfeathered mithril crossbow bolts.", + "grand_exchange_price": "115", + "durability": null, + "name": "Mithril bolts (unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9379" + }, + { + "ge_buy_limit": "10000", + "examine": "Unfeathered adamantite crossbow bolts.", + "grand_exchange_price": "266", + "durability": null, + "name": "Adamant bolts(unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9380" + }, + { + "ge_buy_limit": "10000", + "examine": "Unfeathered runite crossbow bolts", + "grand_exchange_price": "1235", + "durability": null, + "name": "Runite bolts (unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9381" + }, + { + "ge_buy_limit": "10000", + "examine": "Unfeathered silver crossbow bolts.", + "grand_exchange_price": "2", + "durability": null, + "name": "Silver bolts (unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9382" + }, + { + "examine": "A mithril grapple tipped bolt with a rope.", + "grand_exchange_price": "1447", + "durability": null, + "name": "Grapple", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9415" + }, + { + "ge_buy_limit": "100", + "examine": "A mithril grapple tip.", + "grand_exchange_price": "461", + "durability": null, + "name": "Mith grapple tip", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "9416" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "461", + "durability": null, + "name": "Mith grapple tip", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9417" + }, + { + "ge_buy_limit": "1000", + "examine": "A mithril grapple tipped bolt with a rope.", + "grand_exchange_price": "858", + "durability": null, + "name": "Mith grapple", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9418" + }, + { + "ge_buy_limit": "1000", + "examine": "A mithril grapple tipped bolt with a rope.", + "grand_exchange_price": "1470", + "durability": null, + "name": "Mith grapple", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9419", + "equipment_slot": "13" + }, + { + "requirements": "{9,9}", + "shop_price": "20", + "ge_buy_limit": "5000", + "examine": "A pair of bronze crossbow limbs.", + "grand_exchange_price": "49", + "durability": null, + "name": "Bronze limbs", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "9420", + "equipment_slot": "5" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "49", + "durability": null, + "name": "Bronze limbs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9421" + }, + { + "requirements": "{24,9}", + "examine": "A pair of blurite crossbow limbs.", + "durability": null, + "name": "Blurite limbs", + "weight": "1", + "archery_ticket_price": "0", + "id": "9422", + "equipment_slot": "5" + }, + { + "requirements": "{9,39}", + "shop_price": "200", + "ge_buy_limit": "5000", + "examine": "A pair of iron crossbow limbs.", + "grand_exchange_price": "34", + "durability": null, + "name": "Iron limbs", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "9423", + "equipment_slot": "5" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "34", + "durability": null, + "name": "Iron limbs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9424" + }, + { + "requirements": "{9,46}", + "shop_price": "900", + "ge_buy_limit": "5000", + "examine": "A pair of steel crossbow limbs.", + "grand_exchange_price": "97", + "durability": null, + "name": "Steel limbs", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "9425", + "equipment_slot": "5" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "97", + "durability": null, + "name": "Steel limbs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9426" + }, + { + "requirements": "{9,54}", + "shop_price": "650", + "ge_buy_limit": "5000", + "examine": "A pair of mithril crossbow limbs.", + "grand_exchange_price": "347", + "durability": null, + "name": "Mithril limbs", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "9427", + "equipment_slot": "5" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "347", + "durability": null, + "name": "Mithril limbs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9428" + }, + { + "requirements": "{9,61}", + "shop_price": "4800", + "ge_buy_limit": "5000", + "examine": "A pair of adamantite crossbow limbs.", + "grand_exchange_price": "1434", + "durability": null, + "name": "Adamantite limbs", + "tradeable": "true", + "weight": "3", + "archery_ticket_price": "0", + "id": "9429", + "equipment_slot": "5" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "1434", + "durability": null, + "name": "Adamantite limbs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9430" + }, + { + "requirements": "{9,69}", + "ge_buy_limit": "5000", + "examine": "A pair of runite crossbow limbs.", + "grand_exchange_price": "9441", + "durability": null, + "name": "Runite limbs", + "tradeable": "true", + "weight": "3", + "archery_ticket_price": "0", + "id": "9431", + "equipment_slot": "5" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "9441", + "durability": null, + "name": "Runite limbs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9432" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "shop_price": "1500", + "examine": "A pouch for storing crossbow bolts.", + "durability": null, + "name": "Bolt pouch", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "9433" + }, + { + "shop_price": "25", + "ge_buy_limit": "100", + "examine": "A mould for creating silver crossbow bolts.", + "grand_exchange_price": "409", + "durability": null, + "name": "Bolt mould", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9434" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "409", + "durability": null, + "name": "Bolt mould", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9435" + }, + { + "ge_buy_limit": "1000", + "examine": "I can use this to make a crossbow string.", + "grand_exchange_price": "196", + "durability": null, + "name": "Sinew", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9436" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "196", + "durability": null, + "name": "Sinew", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9437" + }, + { + "ge_buy_limit": "1000", + "examine": "A string for a crossbow.", + "grand_exchange_price": "203", + "durability": null, + "name": "Crossbow string", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9438" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "203", + "durability": null, + "name": "Crossbow string", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9439" + }, + { + "requirements": "{9,9}", + "shop_price": "8", + "ge_buy_limit": "1000", + "examine": "A wooden crossbow stock", + "grand_exchange_price": "1", + "durability": null, + "name": "Wooden stock", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9440", + "equipment_slot": "3" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1", + "durability": null, + "name": "Wooden stock", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9441" + }, + { + "requirements": "{24,9}", + "ge_buy_limit": "1000", + "examine": "An oak crossbow stock.", + "grand_exchange_price": "1", + "durability": null, + "name": "Oak stock", + "tradeable": "true", + "weight": "3", + "archery_ticket_price": "0", + "id": "9442", + "equipment_slot": "3" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1", + "durability": null, + "name": "Oak stock", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9443" + }, + { + "requirements": "{9,39}", + "shop_price": "21", + "ge_buy_limit": "1000", + "examine": "A willow crossbow stock.", + "grand_exchange_price": "3", + "durability": null, + "name": "Willow stock", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "9444", + "equipment_slot": "3" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "3", + "durability": null, + "name": "Willow stock", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9445" + }, + { + "requirements": "{9,46}", + "shop_price": "231", + "ge_buy_limit": "1000", + "examine": "A teak crossbow stock.", + "grand_exchange_price": "6", + "durability": null, + "name": "Teak stock", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9446", + "equipment_slot": "3" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "6", + "durability": null, + "name": "Teak stock", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9447" + }, + { + "requirements": "{9,54}", + "ge_buy_limit": "1000", + "examine": "A maple crossbow stock.", + "grand_exchange_price": "7", + "durability": null, + "name": "Maple stock", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9448", + "equipment_slot": "3" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "7", + "durability": null, + "name": "Maple stock", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9449" + }, + { + "requirements": "{9,61}", + "ge_buy_limit": "1000", + "examine": "A Mahogany crossbow stock.", + "grand_exchange_price": "23", + "durability": null, + "name": "Mahogany stock", + "tradeable": "true", + "weight": "3", + "archery_ticket_price": "0", + "id": "9450", + "equipment_slot": "3" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "23", + "durability": null, + "name": "Mahogany stock", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9451" + }, + { + "requirements": "{9,69}", + "ge_buy_limit": "1000", + "examine": "A yew crossbow stock.", + "grand_exchange_price": "37", + "durability": null, + "name": "Yew stock", + "tradeable": "true", + "weight": "3", + "archery_ticket_price": "0", + "id": "9452", + "equipment_slot": "3" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "37", + "durability": null, + "name": "Yew stock", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9453" + }, + { + "shop_price": "27", + "ge_buy_limit": "500", + "examine": "An unstrung bronze crossbow.", + "grand_exchange_price": "25", + "durability": null, + "name": "Bronze c'bow (u)", + "tradeable": "true", + "weight": "8", + "archery_ticket_price": "0", + "id": "9454" + }, + { + "ge_buy_limit": "500", + "grand_exchange_price": "25", + "durability": null, + "name": "Bronze c'bow (u)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9455" + }, + { + "shop_price": "27", + "examine": "An unstrung blurite crossbow.", + "durability": null, + "name": "Blurite c'bow (u)", + "weight": "8", + "archery_ticket_price": "0", + "id": "9456" + }, + { + "ge_buy_limit": "500", + "examine": "An unstrung iron crossbow.", + "grand_exchange_price": "26", + "durability": null, + "name": "Iron c'bow (u)", + "tradeable": "true", + "weight": "8", + "archery_ticket_price": "0", + "id": "9457" + }, + { + "ge_buy_limit": "500", + "grand_exchange_price": "26", + "durability": null, + "name": "Iron c'bow (u)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9458" + }, + { + "shop_price": "27", + "ge_buy_limit": "500", + "examine": "An unstrung steel crossbow.", + "grand_exchange_price": "114", + "durability": null, + "name": "Steel c'bow (u)", + "tradeable": "true", + "weight": "8", + "archery_ticket_price": "0", + "id": "9459" + }, + { + "ge_buy_limit": "500", + "grand_exchange_price": "114", + "durability": null, + "name": "Steel c'bow (u)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9460" + }, + { + "shop_price": "27", + "ge_buy_limit": "500", + "examine": "An unstrung mithril crossbow.", + "grand_exchange_price": "330", + "durability": null, + "name": "Mithril c'bow (u)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9461" + }, + { + "ge_buy_limit": "500", + "grand_exchange_price": "330", + "durability": null, + "name": "Mithril c'bow (u)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9462" + }, + { + "shop_price": "693", + "ge_buy_limit": "500", + "examine": "An unstrung adamantite crossbow.", + "grand_exchange_price": "1007", + "durability": null, + "name": "Adamant c'bow (u)", + "tradeable": "true", + "weight": "8", + "archery_ticket_price": "0", + "id": "9463" + }, + { + "ge_buy_limit": "500", + "grand_exchange_price": "1007", + "durability": null, + "name": "Adamant c'bow (u)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9464" + }, + { + "shop_price": "4000", + "ge_buy_limit": "500", + "examine": "An unstrung runite crossbow.", + "grand_exchange_price": "9493", + "durability": null, + "name": "Runite c'bow (u)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9465" + }, + { + "ge_buy_limit": "500", + "grand_exchange_price": "9493", + "durability": null, + "name": "Runite c'bow (u)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9466" + }, + { + "examine": "It's a bar of blurite.", + "durability": null, + "name": "Blurite bar", + "weight": "1.8", + "archery_ticket_price": "0", + "id": "9467" + }, + { + "examine": "What is left over when a log is made into a plank.", + "durability": null, + "name": "Sawdust", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "9468" + }, + { + "ge_buy_limit": "100", + "examine": "A seed pod of the Grand Tree.", + "grand_exchange_price": "16200", + "durability": null, + "name": "Grand seed pod", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9469" + }, + { + "ge_buy_limit": "10", + "examine": "A scarf. You feel your upper lip stiffening.", + "grand_exchange_price": "1900000", + "durability": null, + "name": "Gnome scarf", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "9470", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "1900000", + "durability": null, + "name": "Gnome scarf", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9471" + }, + { + "ge_buy_limit": "10", + "examine": "Tally Ho!", + "grand_exchange_price": "95800", + "durability": null, + "name": "Gnome goggles", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9472", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "95800", + "durability": null, + "name": "Gnome goggles", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9473" + }, + { + "destroy_message": "Warning! If you destroy this item, you will lose ALL rewards that it relates to and you will have to make another trek in order to get another one.", + "examine": "Blue/Red/Yellow reward token exchanged at Burgh de Rott/Paterdomus.", + "durability": null, + "name": "Reward token", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "9474" + }, + { + "ge_buy_limit": "100", + "examine": "It looks very minty.", + "grand_exchange_price": "675", + "durability": null, + "name": "Mint cake", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "9475" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "675", + "durability": null, + "name": "Mint cake", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9476" + }, + { + "examine": "You can check on your delivery details here", + "durability": null, + "name": "Aluft aloft box", + "archery_ticket_price": "0", + "id": "9477" + }, + { + "shop_price": "1", + "examine": "This cheese & tomato batta needs baking (and garnishing with equa leaves).", + "durability": null, + "name": "Half made batta", + "archery_ticket_price": "0", + "id": "9478" + }, + { + "shop_price": "1", + "examine": "This cheese & tomato batta needs garnishing with equa leaves.", + "durability": null, + "name": "Unfinished batta", + "archery_ticket_price": "0", + "id": "9479" + }, + { + "shop_price": "1", + "examine": "This fruit batta needs baking (and garnishing with gnome spices).", + "durability": null, + "name": "Half made batta", + "archery_ticket_price": "0", + "id": "9480" + }, + { + "shop_price": "1", + "examine": "This fruit batta needs garnishing with gnome spices.", + "durability": null, + "name": "Unfinished batta", + "archery_ticket_price": "0", + "id": "9481" + }, + { + "shop_price": "1", + "examine": "This toad batta needs baking.", + "durability": null, + "name": "Half made batta", + "archery_ticket_price": "0", + "id": "9482" + }, + { + "shop_price": "1", + "examine": "This veggie batta needs baking (and garnishing with equa leaves).", + "durability": null, + "name": "Half made batta", + "archery_ticket_price": "0", + "id": "9483" + }, + { + "shop_price": "1", + "examine": "This veggie batta needs garnishing with equa leaves.", + "durability": null, + "name": "Unfinished batta", + "archery_ticket_price": "0", + "id": "9484" + }, + { + "shop_price": "1", + "examine": "This worm batta needs baking (and garnishing with equa leaves).", + "durability": null, + "name": "Half made batta", + "archery_ticket_price": "0", + "id": "9485" + }, + { + "shop_price": "1", + "examine": "This worm batta needs garnishing with equa leaves.", + "durability": null, + "name": "Unfinished batta", + "archery_ticket_price": "0", + "id": "9486" + }, + { + "shop_price": "28", + "examine": "This looks like a strange mix.", + "grand_exchange_price": "740", + "durability": null, + "name": "Wizard blizzard", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "9487" + }, + { + "durability": null, + "name": "Wizard blizzard", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9488" + }, + { + "shop_price": "28", + "examine": "This looks like a strange mix.", + "grand_exchange_price": "740", + "durability": null, + "name": "Wizard blizzard", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "9489" + }, + { + "shop_price": "28", + "examine": "This looks like a strange mix.", + "grand_exchange_price": "740", + "durability": null, + "name": "Wizard blizzard", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "9508" + }, + { + "durability": null, + "name": "Wizard blizzard", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9509" + }, + { + "shop_price": "28", + "examine": "A Short Green Guy... looks good.", + "grand_exchange_price": "954", + "durability": null, + "name": "Short green guy", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9510" + }, + { + "durability": null, + "name": "Short green guy", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9511" + }, + { + "shop_price": "28", + "examine": "A fresh healthy fruit mix.", + "grand_exchange_price": "287", + "durability": null, + "name": "Pineapple punch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9512" + }, + { + "durability": null, + "name": "Pineapple punch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9513" + }, + { + "shop_price": "28", + "examine": "A cool refreshing fruit mix.", + "grand_exchange_price": "2276", + "durability": null, + "name": "Fruit blast", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9514" + }, + { + "durability": null, + "name": "Fruit blast", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9515" + }, + { + "shop_price": "28", + "examine": "A warm creamy alcoholic beverage", + "grand_exchange_price": "577", + "durability": null, + "name": "Drunk dragon", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9516" + }, + { + "durability": null, + "name": "Drunk dragon", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9517" + }, + { + "shop_price": "28", + "examine": "A warm creamy alcoholic beverage", + "grand_exchange_price": "281", + "durability": null, + "name": "Choc saturday", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "9518" + }, + { + "durability": null, + "name": "Choc saturday", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9519" + }, + { + "shop_price": "30", + "examine": "Looks good... smells strong.", + "grand_exchange_price": "27", + "durability": null, + "name": "Blurberry special", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9520" + }, + { + "durability": null, + "name": "Blurberry special", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9521" + }, + { + "shop_price": "1", + "examine": "A deep tin used to make gnome battas in.", + "durability": null, + "name": "Batta tin", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "9522" + }, + { + "durability": null, + "name": "Batta tin", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9523" + }, + { + "shop_price": "1", + "examine": "A deep tin used to make gnome battas in.", + "durability": null, + "name": "Batta tin", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "9524" + }, + { + "durability": null, + "name": "Batta tin", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9525" + }, + { + "examine": "It actually smells quite good.", + "grand_exchange_price": "310", + "durability": null, + "name": "Fruit batta", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "9527" + }, + { + "durability": null, + "name": "Fruit batta", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9528" + }, + { + "shop_price": "78", + "examine": "It actually smells quite good.", + "grand_exchange_price": "280", + "durability": null, + "name": "Toad batta", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "9529" + }, + { + "durability": null, + "name": "Toad batta", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9530" + }, + { + "examine": "It actually smells quite good.", + "grand_exchange_price": "148", + "durability": null, + "name": "Worm batta", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9531" + }, + { + "durability": null, + "name": "Worm batta", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9532" + }, + { + "examine": "Well... It looks healthy.", + "grand_exchange_price": "240", + "durability": null, + "name": "Vegetable batta", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "9533" + }, + { + "durability": null, + "name": "Vegetable batta", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9534" + }, + { + "examine": "This smells really good.", + "grand_exchange_price": "266", + "durability": null, + "name": "Cheese+tom batta", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "9535" + }, + { + "durability": null, + "name": "Cheese+tom batta", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9536" + }, + { + "examine": "It actually smells quite good.", + "grand_exchange_price": "2606", + "durability": null, + "name": "Toad crunchies", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "9538" + }, + { + "durability": null, + "name": "Toad crunchies", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9539" + }, + { + "shop_price": "70", + "examine": "Yum...smells spicy.", + "grand_exchange_price": "99", + "durability": null, + "name": "Spicy crunchies", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9540" + }, + { + "durability": null, + "name": "Spicy crunchies", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9541" + }, + { + "shop_price": "80", + "examine": "It actually smells quite good.", + "grand_exchange_price": "255", + "durability": null, + "name": "Worm crunchies", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9542" + }, + { + "durability": null, + "name": "Worm crunchies", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9543" + }, + { + "shop_price": "70", + "examine": "Yum... smells good.", + "grand_exchange_price": "889", + "durability": null, + "name": "Chocchip crunchies", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9544" + }, + { + "durability": null, + "name": "Chocchip crunchies", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9545" + }, + { + "examine": "It actually smells quite good.", + "grand_exchange_price": "475", + "durability": null, + "name": "Worm hole", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9547" + }, + { + "durability": null, + "name": "Worm hole", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9548" + }, + { + "examine": "This looks pretty healthy.", + "grand_exchange_price": "514", + "durability": null, + "name": "Veg ball", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9549" + }, + { + "durability": null, + "name": "Veg ball", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9550" + }, + { + "examine": "It actually smells quite good.", + "grand_exchange_price": "2650", + "durability": null, + "name": "Tangled toads' legs", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "9551" + }, + { + "durability": null, + "name": "Tangled toads' legs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9552" + }, + { + "shop_price": "450", + "examine": "Full of creamy, chocolately goodness.", + "grand_exchange_price": "4704", + "durability": null, + "name": "Chocolate bomb", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "9553" + }, + { + "durability": null, + "name": "Chocolate bomb", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9554" + }, + { + "examine": "This unfinished choco bomb needs baking, and final ingredients", + "durability": null, + "name": "Half made bowl", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "9558" + }, + { + "examine": "This unfinished tangled toad legs bowl needs baking, and final ingredients", + "durability": null, + "name": "Half made bowl", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "9559" + }, + { + "examine": "This unfinished choc bomb needs cream and chocolate dust.", + "durability": null, + "name": "Unfinished bowl", + "archery_ticket_price": "0", + "id": "9560" + }, + { + "examine": "This unfinished veggie ball needs baking, and final ingredients", + "durability": null, + "name": "Half made bowl", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "9561" + }, + { + "examine": "This unfinished veggie ball needs equa leaves.", + "durability": null, + "name": "Unfinished bowl", + "archery_ticket_price": "0", + "id": "9562" + }, + { + "examine": "This unfinished worm hole needs baking, and final ingredients", + "durability": null, + "name": "Half made bowl", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "9563" + }, + { + "examine": "This unfinished worm hole needs equa leaves.", + "durability": null, + "name": "Unfinished bowl", + "archery_ticket_price": "0", + "id": "9564" + }, + { + "durability": null, + "name": "Cocktail shaker", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9565" + }, + { + "examine": "This wizzard blizzard needs pouring, a lime slice, and pineapple chunks.", + "durability": null, + "name": "Mixed blizzard", + "archery_ticket_price": "0", + "id": "9566" + }, + { + "examine": "This short green guy cocktail needs pouring, a lime slice and equa leaves.", + "durability": null, + "name": "Mixed sgg", + "archery_ticket_price": "0", + "id": "9567" + }, + { + "examine": "This fruit blast cocktail needs pouring and a lemon slice.", + "durability": null, + "name": "Mixed blast", + "archery_ticket_price": "0", + "id": "9568" + }, + { + "examine": "This pineapple punch needs pouring, lime and pineapple chunks, and a orange slice.", + "durability": null, + "name": "Mixed punch", + "archery_ticket_price": "0", + "id": "9569" + }, + { + "examine": "This blurberry special needs pouring, orange and lemon chunks, a lime slice and equa leaves.", + "durability": null, + "name": "Mixed blurberry special", + "archery_ticket_price": "0", + "id": "9570" + }, + { + "examine": "This choco chip crunchy needs baking and garnishing with chocolate dust.", + "durability": null, + "name": "Half made crunchy", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9577" + }, + { + "examine": "This choco chip crunchy needs garnishing with chocolate dust.", + "durability": null, + "name": "Unfinished crunchy", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9578" + }, + { + "examine": "This spicy crunchy needs baking and garnishing with gnome spices.", + "durability": null, + "name": "Half made crunchy", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9579" + }, + { + "examine": "This spicy crunchy needs garnishing with gnome spices.", + "durability": null, + "name": "Unfinished crunchy", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9580" + }, + { + "examine": "This toad crunchy needs baking and garnishing with equa leaves.", + "durability": null, + "name": "Half made crunchy", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9581" + }, + { + "examine": "This toad crunchy needs garnishing with equa leaves.", + "durability": null, + "name": "Unfinished crunchy", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9582" + }, + { + "examine": "This worm crunchy needs baking and garnishing with gnome spices.", + "durability": null, + "name": "Half made crunchy", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9583" + }, + { + "examine": "This worm crunchy needs garnishing with gnome spices.", + "durability": null, + "name": "Unfinished crunchy", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9584" + }, + { + "durability": null, + "name": "Batta tin", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9585" + }, + { + "durability": null, + "name": "Crunchy tray", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9586" + }, + { + "durability": null, + "name": "Gnomebowl mould", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9587" + }, + { + "durability": null, + "name": "Raw crunchies", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9588" + }, + { + "destroy_message": "Speak to Sir Amik Varze at the beginning of the Black Knight's Fortress Quest.", + "examine": "A dossier containing info on the Black Knight plot.", + "durability": null, + "name": "Dossier", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "9589" + }, + { + "examine": "A dossier containing info on the Black Knight plot.", + "durability": null, + "name": "Dossier", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "9590" + }, + { + "examine": "Glue made from tree sap and ground mud runes.", + "durability": null, + "name": "Magic glue", + "weight": "3", + "archery_ticket_price": "0", + "id": "9592" + }, + { + "examine": "This doesn't look like it will do anything interesting.", + "durability": null, + "name": "Weird gloop", + "tradeable": "false", + "destroy": "true", + "weight": "2.5", + "archery_ticket_price": "0", + "id": "9593" + }, + { + "examine": "Mud runes ground into a powder.", + "durability": null, + "name": "Ground mud runes", + "tradeable": "false", + "destroy": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "9594" + }, + { + "examine": "A red circular crystalline disc.", + "durability": null, + "name": "Red circle", + "archery_ticket_price": "0", + "id": "9597" + }, + { + "examine": "A red triangular crystalline disc.", + "durability": null, + "name": "Red triangle", + "archery_ticket_price": "0", + "id": "9598" + }, + { + "examine": "A red square-shaped crystalline disc.", + "durability": null, + "name": "Red square", + "archery_ticket_price": "0", + "id": "9599" + }, + { + "examine": "A red pentagon shaped crystalline disc.", + "durability": null, + "name": "Red pentagon", + "archery_ticket_price": "0", + "id": "9600" + }, + { + "examine": "An orange circular crystalline disc.", + "durability": null, + "name": "Orange circle", + "archery_ticket_price": "0", + "id": "9601" + }, + { + "examine": "An orange triangular crystalline disc.", + "durability": null, + "name": "Orange triangle", + "archery_ticket_price": "0", + "id": "9602" + }, + { + "examine": "An orange square-shaped crystalline disc.", + "durability": null, + "name": "Orange square", + "archery_ticket_price": "0", + "id": "9603" + }, + { + "examine": "An orange pentagon shaped crystalline disc.", + "durability": null, + "name": "Orange pentagon", + "archery_ticket_price": "0", + "id": "9604" + }, + { + "examine": "A yellow circular crystalline disc.", + "durability": null, + "name": "Yellow circle", + "archery_ticket_price": "0", + "id": "9605" + }, + { + "examine": "A yellow triangular crystalline disc.", + "durability": null, + "name": "Yellow triangle", + "archery_ticket_price": "0", + "id": "9606" + }, + { + "examine": "A yellow square-shaped crystalline disc.", + "durability": null, + "name": "Yellow square", + "archery_ticket_price": "0", + "id": "9607" + }, + { + "examine": "A yellow pentagon shaped crystalline disc.", + "durability": null, + "name": "Yellow pentagon", + "archery_ticket_price": "0", + "id": "9608" + }, + { + "examine": "A green circular crystalline disc.", + "durability": null, + "name": "Green circle", + "archery_ticket_price": "0", + "id": "9609" + }, + { + "examine": "A green triangular crystalline disc.", + "durability": null, + "name": "Green triangle", + "archery_ticket_price": "0", + "id": "9610" + }, + { + "examine": "A green square shaped crystalline disc.", + "durability": null, + "name": "Green square", + "archery_ticket_price": "0", + "id": "9611" + }, + { + "examine": "A green pentagon shaped crystalline disc.", + "durability": null, + "name": "Green pentagon", + "archery_ticket_price": "0", + "id": "9612" + }, + { + "examine": "A blue circular crystalline disc.", + "durability": null, + "name": "Blue circle", + "archery_ticket_price": "0", + "id": "9613" + }, + { + "examine": "A blue triangular crystalline disc.", + "durability": null, + "name": "Blue triangle", + "archery_ticket_price": "0", + "id": "9614" + }, + { + "examine": "A blue square shaped crystalline disc.", + "durability": null, + "name": "Blue square", + "archery_ticket_price": "0", + "id": "9615" + }, + { + "examine": "A blue pentagon shaped crystalline disc.", + "durability": null, + "name": "Blue pentagon", + "archery_ticket_price": "0", + "id": "9616" + }, + { + "examine": "An indigo circular crystalline disc.", + "durability": null, + "name": "Indigo circle", + "archery_ticket_price": "0", + "id": "9617" + }, + { + "examine": "An indigo triangular crystalline disc.", + "durability": null, + "name": "Indigo triangle", + "archery_ticket_price": "0", + "id": "9618" + }, + { + "examine": "An indigo square shaped crystalline disc.", + "durability": null, + "name": "Indigo square", + "archery_ticket_price": "0", + "id": "9619" + }, + { + "examine": "An indigo pentagon shaped crystalline disc.", + "durability": null, + "name": "Indigo pentagon", + "archery_ticket_price": "0", + "id": "9620" + }, + { + "examine": "A violet circular crystalline disc.", + "durability": null, + "name": "Violet circle", + "archery_ticket_price": "0", + "id": "9621" + }, + { + "examine": "A violet triangular crystalline disc.", + "durability": null, + "name": "Violet triangle", + "archery_ticket_price": "0", + "id": "9622" + }, + { + "examine": "A violet square-shaped crystalline disc.", + "durability": null, + "name": "Violet square", + "archery_ticket_price": "0", + "id": "9623" + }, + { + "examine": "A violet pentagon shaped crystalline disc.", + "durability": null, + "name": "Violet pentagon", + "archery_ticket_price": "0", + "id": "9624" + }, + { + "destroy_message": "Maybe Brimstail will have another...", + "examine": "A magical saw.", + "durability": null, + "name": "Crystal saw", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "9625", + "equipment_slot": "3" + }, + { + "destroy_message": "Maybe Brimstail will have another...", + "examine": "This small crystal seed looks grey and dead.", + "durability": null, + "name": "Small crystal seed", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "9626" + }, + { + "remove_head": "true", + "requirements": "{1,5}", + "shop_price": "1265", + "ge_buy_limit": "100", + "examine": "As used by King Tyras personal guard.", + "durability": null, + "weight": "0.9", + "equipment_slot": "0", + "grand_exchange_price": "1406", + "name": "Tyras helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9629", + "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1406", + "durability": null, + "name": "Tyras helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9630" + }, + { + "examine": "This needs refining.", + "durability": null, + "name": "Daeyalt ore", + "tradeable": "false", + "destroy": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "9632" + }, + { + "shop_price": "635", + "ge_buy_limit": "100", + "examine": "Dressing like the Vyrewatch could be a useful disguise in the ghetto of Meiyerditch.", + "durability": null, + "weight": "0.9", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "2160", + "name": "Vyrewatch top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9634", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2160", + "durability": null, + "name": "Vyrewatch top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9635" + }, + { + "shop_price": "635", + "ge_buy_limit": "100", + "examine": "Dress like a powerful Vyrewatch!", + "grand_exchange_price": "1204", + "durability": null, + "name": "Vyrewatch legs", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "9636", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1204", + "durability": null, + "name": "Vyrewatch legs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9637" + }, + { + "shop_price": "635", + "ge_buy_limit": "100", + "examine": "Dress like a powerful Vyrewatch!", + "grand_exchange_price": "2874", + "durability": null, + "name": "Vyrewatch shoes", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "9638", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "equipment_slot": "10" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2874", + "durability": null, + "name": "Vyrewatch shoes", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9639" + }, + { + "shop_price": "6", + "ge_buy_limit": "100", + "examine": "Could be used as a disguise in the ghetto of Meiyerditch.", + "durability": null, + "weight": "0.9", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "588", + "name": "Citizen top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9640", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "588", + "durability": null, + "name": "Citizen top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9641" + }, + { + "shop_price": "6", + "ge_buy_limit": "100", + "examine": "Could be used as a disguise in the ghetto of Meiyerditch.", + "grand_exchange_price": "491", + "durability": null, + "name": "Citizen trousers", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "9642", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "491", + "durability": null, + "name": "Citizen trousers", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9643" + }, + { + "shop_price": "6", + "ge_buy_limit": "100", + "examine": "Could be used as a disguise in the ghetto of Meiyerditch.", + "grand_exchange_price": "458", + "durability": null, + "name": "Citizen shoes", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "9644", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "equipment_slot": "10" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "458", + "durability": null, + "name": "Citizen shoes", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9645" + }, + { + "destroy_message": "You can get another sketch by using charcoal with papyrus, when on the wall near Castle Drakyn.", + "examine": "Northern approach of the castle.", + "durability": null, + "name": "Castle sketch 1", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "9646" + }, + { + "destroy_message": "You can get another sketch by using charcoal with papyrus, when on the wall near Castle Drakyn.", + "examine": "Western approach of the castle.", + "durability": null, + "name": "Castle sketch 2", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "9647" + }, + { + "destroy_message": "You can get another sketch by using charcoal with papyrus, when on the wall near Castle Drakyn.", + "examine": "Southern approach of the castle.", + "durability": null, + "name": "Castle sketch 3", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "9648" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A key to some large, strange door.", + "durability": null, + "name": "Large ornate key", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "9651" + }, + { + "destroy_message": "Unknown You can reclaim this item from the place you found it.", + "examine": "A book called Haemalchemy Volume 1.", + "durability": null, + "name": "Haemalchemy", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "9652" + }, + { + "destroy_message": "Safalaan gave you this message; he would probably write out another one for you.", + "examine": "A sealed message from Safalaan to Valiaf.", + "durability": null, + "name": "Sealed message", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "9653" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A key to the Witch's house's front door. (Witch's House)", + "durability": null, + "name": "Door key", + "archery_ticket_price": "0", + "id": "9654" + }, + { + "destroy_message": "You found this ladder top on a wall section in the north of Meiyerditch; you can get another one there.", + "examine": "The top part of a ladder.", + "durability": null, + "name": "Ladder top", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "9655" + }, + { + "destroy_message": "You can get another Tome of Experience from Veliaf in Burgh de Rott.", + "examine": "A tome of experience that awards 2000 XP per chapter.", + "durability": null, + "name": "Tome of xp (3)", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "9656" + }, + { + "destroy_message": "You can get another Tome of Experience from Veliaf in Burgh de Rott.", + "examine": "A tome of experience that awards 2000 XP per chapter.", + "durability": null, + "name": "Tome of xp (2)", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "9657" + }, + { + "destroy_message": "You can get another Tome of Experience from Veliaf in Burgh de Rott.", + "examine": "A tome of experience that awards 2000 XP per chapter.", + "durability": null, + "name": "Tome of xp (1)", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "9658" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Common bucket: It's a bucket of water.2008 Easter event: It's a bucket of water from the Easter Bunny's warren. Regular bucket filled from Braindeath Island: It's a bucket of... water?", + "grand_exchange_price": "74", + "durability": null, + "name": "Bucket of water", + "tradeable": "true", + "weight": "3", + "archery_ticket_price": "0", + "id": "9659" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "shop_price": "2", + "examine": "It's an empty bucket.", + "grand_exchange_price": "50", + "durability": null, + "name": "Bucket", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "9660" + }, + { + "destroy_message": "Safalaan gave you this key as a reward for helping out in Meiyerditch, you can get another key from him.", + "examine": "A key allowing a shortcut into the Sanguinesti region. (Darkness of Hallowvale)", + "durability": null, + "name": "Shortcut key", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "9662" + }, + { + "durability": null, + "name": "Torch", + "archery_ticket_price": "0", + "id": "9665", + "equipment_slot": "3" + }, + { + "shop_price": "25000", + "ge_buy_limit": "100", + "examine": "Unknown edit", + "grand_exchange_price": "27500", + "durability": null, + "name": "Pros'yte harness m", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "9666" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "27500", + "durability": null, + "name": "Pros'yte harness m", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9667" + }, + { + "shop_price": "20000", + "ge_buy_limit": "100", + "examine": "Unknown edit", + "grand_exchange_price": "22700", + "durability": null, + "name": "Initiate harness m", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "9668" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "22700", + "durability": null, + "name": "Initiate harness m", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9669" + }, + { + "shop_price": "25000", + "ge_buy_limit": "100", + "examine": "Unknown edit", + "grand_exchange_price": "27900", + "durability": null, + "name": "Pros'yte harness f", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "9670" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "27900", + "durability": null, + "name": "Pros'yte harness f", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9671" + }, + { + "remove_head": "true", + "requirements": "{1,30}-{5,20}", + "shop_price": "8000", + "ge_buy_limit": "100", + "examine": "A Proselyte Temple Knight's helm.", + "durability": null, + "weight": "2", + "absorb": "1,0,2", + "equip_audio": "2238", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "4619", + "name": "Proselyte sallet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9672", + "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,6,0,4,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "4619", + "durability": null, + "name": "Proselyte sallet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9673" + }, + { + "requirements": "{1,30}-{5,20}", + "shop_price": "12000", + "ge_buy_limit": "100", + "examine": "A Proselyte Temple Knight's armour.", + "durability": null, + "weight": "8.6", + "absorb": "2,0,4", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "7076", + "name": "Proselyte hauberk", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9674", + "bonuses": "0,0,0,-30,-10,65,63,55,-6,63,30,0,8,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "7076", + "durability": null, + "name": "Proselyte hauberk", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9675" + }, + { + "requirements": "{1,30}-{5,20}", + "shop_price": "10000", + "ge_buy_limit": "100", + "examine": "A Proselyte Temple Knight's leg armour", + "durability": null, + "weight": "7.7", + "absorb": "1,0,3", + "equipment_slot": "7", + "grand_exchange_price": "5923", + "name": "Proselyte cuisse", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9676", + "bonuses": "0,0,0,-21,-7,33,31,29,-4,31,10,0,5,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "5923", + "durability": null, + "name": "Proselyte cuisse", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9677" + }, + { + "requirements": "{1,30}-{5,20}", + "shop_price": "10000", + "ge_buy_limit": "100", + "examine": "A Proselyte Temple Knight's leg armour.", + "durability": null, + "weight": "9", + "absorb": "1,0,3", + "equipment_slot": "7", + "grand_exchange_price": "5730", + "name": "Proselyte tasset", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9678", + "bonuses": "0,0,0,-21,-7,33,31,29,-4,31,10,0,5,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "5730", + "durability": null, + "name": "Proselyte tasset", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9679" + }, + { + "examine": "A rendered down baby sea slug.", + "durability": null, + "name": "Sea slug glue", + "archery_ticket_price": "0", + "id": "9680" + }, + { + "destroy_message": "As a security precaution, your CommOrb will automatically self", + "examine": "A Temple Knight Communication Orb. Top Secret!", + "durability": null, + "name": "Commorb v2", + "archery_ticket_price": "0", + "id": "9681" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A copy of the mysterious glyphs.", + "durability": null, + "name": "Door transcription", + "archery_ticket_price": "0", + "id": "9682" + }, + { + "examine": "Dead sea slug, very sticky.", + "durability": null, + "name": "Dead sea slug", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "9683" + }, + { + "destroy_message": "You can get this page from Mayor Hobb's Desk.", + "examine": "A page from Maledict's holy book.", + "durability": null, + "name": "Page 1", + "tradeable": "false", + "destroy": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "9684" + }, + { + "destroy_message": "You can get this page from Ezekial Lovecraft.", + "examine": "A page from Maledict's holy book.", + "durability": null, + "name": "Page 2", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "9685" + }, + { + "destroy_message": "You will have to get the torn page from Col. O' Niall.", + "examine": "A page from Maledict's holy book.", + "durability": null, + "name": "Page 3", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "9686" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A piece of torn page.", + "durability": null, + "name": "Fragment 1", + "archery_ticket_price": "0", + "id": "9687" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A piece of torn page.", + "durability": null, + "name": "Fragment 2", + "archery_ticket_price": "0", + "id": "9688" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A piece of torn page.", + "durability": null, + "name": "Fragment 3", + "archery_ticket_price": "0", + "id": "9689" + }, + { + "destroy_message": "Are you sure you wish to destroy this?", + "examine": "A blank water rune.", + "durability": null, + "name": "Blank water rune", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "9690" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "shop_price": "17", + "examine": "One of the 4 basic elemental Runes.", + "grand_exchange_price": "6", + "durability": null, + "name": "Water rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9691" + }, + { + "destroy_message": "Are you sure you wish to destroy this?", + "examine": "A blank air rune.", + "durability": null, + "name": "Blank air rune", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "9692" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "shop_price": "17", + "examine": "One of the 4 basic elemental Runes.", + "grand_exchange_price": "9", + "durability": null, + "name": "Air rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9693" + }, + { + "destroy_message": "Are you sure you wish to destroy this?", + "examine": "A blank earth rune.", + "durability": null, + "name": "Blank earth rune", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "9694" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "shop_price": "17", + "examine": "One of the 4 basic elemental Runes.", + "grand_exchange_price": "7", + "durability": null, + "name": "Earth rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9695" + }, + { + "destroy_message": "Are you sure you wish to destroy this?", + "examine": "A blank mind rune.", + "durability": null, + "name": "Blank mind rune", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "9696" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "shop_price": "17", + "examine": "Used for basic missile spells.", + "grand_exchange_price": "6", + "durability": null, + "name": "Mind rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9697" + }, + { + "destroy_message": "Are you sure you wish to destroy this?", + "examine": "A blank fire rune.", + "durability": null, + "name": "Blank fire rune", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "9698" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "shop_price": "17", + "examine": "One of the 4 basic elemental Runes.", + "grand_exchange_price": "16", + "durability": null, + "name": "Fire rune", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9699" + }, + { + "durability": null, + "name": "Torch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9701" + }, + { + "examine": "A big, bad troll.", + "durability": null, + "name": "Stick", + "archery_ticket_price": "0", + "attack_speed": "6", + "id": "9702", + "weapon_interface": "5", + "equipment_slot": "3" + }, + { + "shop_price": "35", + "examine": "Basic training sword.", + "durability": null, + "weight": "1.8", + "attack_speed": "4", + "weapon_interface": "5", + "equip_audio": "2248", + "render_anim": "2584", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "381,390,390,390", + "attack_audios": "2500,2500,2517,2500", + "name": "Training sword", + "archery_ticket_price": "0", + "id": "9703", + "bonuses": "4,3,-2,0,0,0,2,1,0,0,0,5,0,0,0" + }, + { + "examine": "Made of flimsy painted wood.", + "durability": null, + "name": "Training shield", + "weight": "5.4", + "archery_ticket_price": "0", + "id": "9704", + "bonuses": "0,0,0,0,0,4,5,3,1,4,0,0,0,0,0", + "equipment_slot": "5" + }, + { + "examine": "Light and flexible, good for a beginner.", + "durability": null, + "destroy": "true", + "weight": "1.3", + "attack_speed": "4", + "two_handed": "true", + "weapon_interface": "16", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "426,426,426,426", + "attack_audios": "2700,0,0,0", + "name": "Training bow", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "9705", + "bonuses": "0,0,0,0,8,0,0,0,0,0,0,0,0,0,0" + }, + { + "examine": "Standard training arrows.", + "durability": null, + "name": "Training arrows", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "9706", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,7", + "equipment_slot": "13" + }, + { + "examine": "Book of the elemental shield.", + "durability": null, + "name": "Slashed book", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "9715" + }, + { + "examine": "Book of the elemental helm.", + "durability": null, + "name": "Beaten book", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "9717" + }, + { + "examine": "On the subject of lava dippers.", + "durability": null, + "name": "Crane schematic", + "archery_ticket_price": "0", + "id": "9718" + }, + { + "examine": "A scroll with a lever schematic drawn on it.", + "durability": null, + "name": "Lever schematic", + "archery_ticket_price": "0", + "id": "9719" + }, + { + "examine": "A crane claw.", + "durability": null, + "name": "Crane claw", + "weight": "1", + "archery_ticket_price": "0", + "id": "9720" + }, + { + "examine": "A pipe that belongs in a cannon stand.", + "durability": null, + "name": "Pipe", + "tradeable": "false", + "destroy": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "9723" + }, + { + "examine": "A large cog.", + "durability": null, + "name": "Large cog", + "weight": "1", + "archery_ticket_price": "0", + "id": "9724" + }, + { + "examine": "A medium cog.", + "durability": null, + "name": "Medium cog", + "weight": "1", + "archery_ticket_price": "0", + "id": "9725" + }, + { + "examine": "A small cog.", + "durability": null, + "name": "Small cog", + "weight": "1", + "archery_ticket_price": "0", + "id": "9726" + }, + { + "examine": "A primed elemental ingot.", + "durability": null, + "name": "Primed bar", + "weight": "1.8", + "archery_ticket_price": "0", + "id": "9727" + }, + { + "examine": "An elemental mind ingot.", + "durability": null, + "name": "Elemental mind bar", + "weight": "1", + "archery_ticket_price": "0", + "id": "9728" + }, + { + "ge_buy_limit": "100", + "examine": "A helmet made in the Elemental Workshop.", + "grand_exchange_price": "196", + "durability": null, + "name": "Elemental helmet", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "9729", + "bonuses": "0,0,0,0,0,0,0,0,4,0,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "196", + "durability": null, + "name": "Elemental helmet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9730" + }, + { + "ge_buy_limit": "100", + "examine": "A shield made in the Elemental Workshop.", + "grand_exchange_price": "8351", + "durability": null, + "name": "Mind shield", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "9731", + "bonuses": "0,0,0,0,0,0,0,0,9,0,25,0,0,0,0", + "equipment_slot": "5" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "8351", + "durability": null, + "name": "Mind shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9732" + }, + { + "shop_price": "1200", + "ge_buy_limit": "100", + "examine": "A helmet made in the Elemental Workshop.", + "grand_exchange_price": "1589", + "durability": null, + "name": "Mind helmet", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "9733", + "bonuses": "0,0,0,0,0,0,0,0,6,0,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1589", + "durability": null, + "name": "Mind helmet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9734" + }, + { + "ge_buy_limit": "10000", + "examine": "Not much good for blowing.", + "grand_exchange_price": "902", + "durability": null, + "name": "Desert goat horn", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9735" + }, + { + "ge_buy_limit": "10000", + "examine": "Finely ground desert goat horn.", + "grand_exchange_price": "1082", + "durability": null, + "name": "Goat horn dust", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9736" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "1082", + "durability": null, + "name": "Goat horn dust", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9737" + }, + { + "durability": null, + "name": "Desert goat horn", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9738" + }, + { + "shop_price": "207", + "ge_buy_limit": "100", + "examine": "4 doses of combat potion.", + "grand_exchange_price": "45", + "durability": null, + "name": "Combat potion(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9739" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "45", + "durability": null, + "name": "Combat potion(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9740" + }, + { + "shop_price": "207", + "ge_buy_limit": "100", + "examine": "3 doses of combat potion.", + "grand_exchange_price": "25", + "durability": null, + "name": "Combat potion(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9741" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "25", + "durability": null, + "name": "Combat potion(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9742" + }, + { + "shop_price": "207", + "ge_buy_limit": "100", + "examine": "2 doses of combat potion.", + "grand_exchange_price": "19", + "durability": null, + "name": "Combat potion(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9743" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "19", + "durability": null, + "name": "Combat potion(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9744" + }, + { + "shop_price": "207", + "ge_buy_limit": "100", + "examine": "1 dose of combat potion.", + "grand_exchange_price": "72", + "durability": null, + "name": "Combat potion(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9745" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "72", + "durability": null, + "name": "Combat potion(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9746" + }, + { + "requirements": "{0,99}", + "shop_price": "99000", + "examine": "The cape worn by masters of attack.", + "durability": null, + "name": "Attack cape", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9747", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{0,99}", + "durability": null, + "name": "Attack cape(t)", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "9748", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", + "equipment_slot": "1" + }, + { + "remove_head": "true", + "requirements": "{0,99}", + "shop_price": "99000", + "examine": "Attack skillcape hood.", + "durability": null, + "name": "Attack hood", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9749", + "equipment_slot": "0" + }, + { + "requirements": "{2,99}", + "shop_price": "99000", + "examine": "The cape only worn by the strongest people.", + "durability": null, + "name": "Strength cape", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9750", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{2,99}", + "durability": null, + "name": "Strength cape(t)", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "9751", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", + "equipment_slot": "1" + }, + { + "remove_head": "true", + "requirements": "{2,99}", + "shop_price": "99000", + "examine": "Strength skillcape hood.", + "durability": null, + "name": "Strength hood", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9752", + "equipment_slot": "0" + }, + { + "requirements": "{1,99}", + "shop_price": "99000", + "examine": "The cape worn by masters of the art of Defence.", + "durability": null, + "name": "Defence cape", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9753", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{1,99}", + "durability": null, + "name": "Defence cape(t)", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "9754", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", + "equipment_slot": "1" + }, + { + "remove_head": "true", + "requirements": "{1,99}", + "shop_price": "99000", + "examine": "Defence skillcape hood.", + "durability": null, + "name": "Defence hood", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9755", + "equipment_slot": "0" + }, + { + "requirements": "{4,99}", + "shop_price": "99000", + "examine": "The cape worn by master archers.", + "durability": null, + "name": "Ranging cape", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9756", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{4,99}", + "durability": null, + "name": "Ranging cape(t)", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "9757", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", + "equipment_slot": "1" + }, + { + "remove_head": "true", + "requirements": "{4,99}", + "shop_price": "99000", + "examine": "Range skillcape hood.", + "durability": null, + "name": "Ranging hood", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9758", + "equipment_slot": "0" + }, + { + "requirements": "{5,99}", + "shop_price": "99000", + "examine": "The cape worn by the most pious of heroes.", + "durability": null, + "name": "Prayer cape", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9759", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{5,99}", + "durability": null, + "name": "Prayer cape(t)", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "9760", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", + "equipment_slot": "1" + }, + { + "remove_head": "true", + "requirements": "{5,99}", + "shop_price": "99000", + "examine": "Prayer skillcape hood.", + "durability": null, + "name": "Prayer hood", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9761", + "equipment_slot": "0" + }, + { + "requirements": "{6,99}", + "shop_price": "99000", + "examine": "The cape worn by the most powerful mages.", + "durability": null, + "name": "Magic cape", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9762", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{6,99}", + "durability": null, + "name": "Magic cape(t)", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "9763", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", + "equipment_slot": "1" + }, + { + "remove_head": "true", + "requirements": "{6,99}", + "shop_price": "99000", + "examine": "Magic skillcape hood.", + "durability": null, + "name": "Magic hood", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9764", + "equipment_slot": "0" + }, + { + "requirements": "{20,99}", + "shop_price": "99000", + "examine": "The cape worn by master runecrafters.", + "durability": null, + "name": "Runecraft cape", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9765", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{20,99}", + "durability": null, + "name": "Runecraft cape(t)", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "9766", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", + "equipment_slot": "1" + }, + { + "remove_head": "true", + "requirements": "{20,99}", + "shop_price": "99000", + "examine": "Runecrafting skillcape hood.", + "durability": null, + "name": "Runecrafting hood", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9767", + "equipment_slot": "0" + }, + { + "requirements": "{3,99}", + "shop_price": "99000", + "examine": "The cape worn by well-constituted adventurers.", + "durability": null, + "name": "Hitpoints cape", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9768", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{3,99}", + "durability": null, + "name": "Hitpoints cape(t)", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "9769", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", + "equipment_slot": "1" + }, + { + "remove_head": "true", + "requirements": "{3,99}", + "shop_price": "99000", + "examine": "Constitution skillcape hood.", + "durability": null, + "name": "Hitpoints hood", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9770", + "equipment_slot": "0" + }, + { + "requirements": "{16,99}", + "shop_price": "99000", + "examine": "The cape worn by the most agile of heroes.", + "durability": null, + "name": "Agility cape", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9771", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{16,99}", + "durability": null, + "name": "Agility cape(t)", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "9772", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", + "equipment_slot": "1" + }, + { + "remove_head": "true", + "requirements": "{16,99}", + "shop_price": "99000", + "examine": "Agility skillcape hood.", + "durability": null, + "name": "Agility hood", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9773", + "equipment_slot": "0" + }, + { + "requirements": "{15,99}", + "shop_price": "99000", + "examine": "The cape worn by the most skilled at the art of herblore.", + "durability": null, + "name": "Herblore cape", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9774", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{15,99}", + "durability": null, + "name": "Herblore cape(t)", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "9775", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", + "equipment_slot": "1" + }, + { + "remove_head": "true", + "requirements": "{15,99}", + "shop_price": "99000", + "examine": "Herblore skillcape hood.", + "durability": null, + "name": "Herblore hood", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9776", + "equipment_slot": "0" + }, + { + "requirements": "{17,99}", + "shop_price": "99000", + "examine": "The cape worn by master thieves.", + "durability": null, + "name": "Thieving cape", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9777", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{17,99}", + "durability": null, + "name": "Thieving cape(t)", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "9778", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", + "equipment_slot": "1" + }, + { + "remove_head": "true", + "requirements": "{17,99}", + "shop_price": "99000", + "examine": "Thieving skillcape hood.", + "durability": null, + "name": "Thieving hood", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9779", + "equipment_slot": "0" + }, + { + "requirements": "{12,99}", + "shop_price": "99000", + "examine": "The cape worn by master craftworkers.", + "durability": null, + "name": "Crafting cape", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9780", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{12,99}", + "durability": null, + "name": "Crafting cape(t)", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "9781", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", + "equipment_slot": "1" + }, + { + "remove_head": "true", + "requirements": "{12,99}", + "shop_price": "99000", + "examine": "Crafting skillcape hood.", + "durability": null, + "name": "Crafting hood", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9782", + "equipment_slot": "0" + }, + { + "requirements": "{9,99}", + "shop_price": "99000", + "examine": "The cape worn by the best of fletchers.", + "durability": null, + "name": "Fletching cape", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9783", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{9,99}", + "durability": null, + "name": "Fletching cape(t)", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "9784", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", + "equipment_slot": "1" + }, + { + "remove_head": "true", + "requirements": "{9,99}", + "shop_price": "99000", + "examine": "Fletching skillcape hood.", + "durability": null, + "name": "Fletching hood", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9785", + "equipment_slot": "0" + }, + { + "requirements": "{18,99}", + "shop_price": "99000", + "examine": "The cape worn by slayer masters.", + "durability": null, + "name": "Slayer cape", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9786", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{18,99}", + "durability": null, + "name": "Slayer cape(t)", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "9787", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", + "equipment_slot": "1" + }, + { + "remove_head": "true", + "requirements": "{18,99}", + "shop_price": "99000", + "examine": "Slayer skillcape hood.", + "durability": null, + "name": "Slayer hood", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9788", + "equipment_slot": "0" + }, + { + "requirements": "{22,99}", + "shop_price": "99000", + "examine": "The cape worn by master builders.", + "durability": null, + "name": "Construct. cape", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9789", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{22,99}", + "durability": null, + "name": "Construct. cape(t)", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "9790", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", + "equipment_slot": "1" + }, + { + "remove_head": "true", + "requirements": "{22,99}", + "shop_price": "99000", + "examine": "Construction skillcape hood.", + "durability": null, + "name": "Construct. hood", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9791", + "equipment_slot": "0" + }, + { + "requirements": "{14,99}", + "shop_price": "99000", + "examine": "The cape worn by the most skilled miners.", + "durability": null, + "name": "Mining cape", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9792", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{14,99}", + "durability": null, + "name": "Mining cape(t)", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "9793", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", + "equipment_slot": "1" + }, + { + "remove_head": "true", + "requirements": "{14,99}", + "shop_price": "99000", + "examine": "Mining skillcape hood.", + "durability": null, + "name": "Mining hood", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9794", + "equipment_slot": "0" + }, + { + "requirements": "{13,99}", + "shop_price": "99000", + "examine": "The cape worn by master smiths.", + "durability": null, + "name": "Smithing cape", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9795", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{13,99}", + "durability": null, + "name": "Smithing cape(t)", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "9796", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", + "equipment_slot": "1" + }, + { + "remove_head": "true", + "requirements": "{13,99}", + "shop_price": "99000", + "examine": "Smithing skillcape hood.", + "durability": null, + "name": "Smithing hood", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9797", + "equipment_slot": "0" + }, + { + "requirements": "{10,99}", + "shop_price": "99000", + "examine": "The cape worn by the best fishermen.", + "durability": null, + "name": "Fishing cape", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9798", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{10,99}", + "durability": null, + "name": "Fishing cape(t)", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "9799", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", + "equipment_slot": "1" + }, + { + "remove_head": "true", + "requirements": "{10,99}", + "shop_price": "99000", + "examine": "Fishing skillcape hood.", + "durability": null, + "name": "Fishing hood", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9800", + "equipment_slot": "0" + }, + { + "requirements": "{7,99}", + "shop_price": "99000", + "examine": "The cape worn by the world's best chefs.", + "durability": null, + "name": "Cooking cape", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9801", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{7,99}", + "durability": null, + "name": "Cooking cape(t)", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "9802", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", + "equipment_slot": "1" + }, + { + "remove_head": "true", + "requirements": "{7,99}", + "shop_price": "99000", + "examine": "Cooking skillcape hood.", + "durability": null, + "name": "Cooking hood", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9803", + "equipment_slot": "0" + }, + { + "requirements": "{11,99}", + "shop_price": "99000", + "examine": "The cape worn by master firelighters.", + "durability": null, + "name": "Firemaking cape", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9804", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{11,99}", + "durability": null, + "name": "Firemaking cape(t)", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "9805", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", + "equipment_slot": "1" + }, + { + "remove_head": "true", + "requirements": "{11,99}", + "shop_price": "99000", + "examine": "Firemaking skillcape hood.", + "durability": null, + "name": "Firemaking hood", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9806", + "equipment_slot": "0" + }, + { + "requirements": "{8,99}", + "shop_price": "99000", + "examine": "The cape worn by master woodcutters (Obtaining level 99 skill)", + "durability": null, + "name": "Woodcutting cape", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9807", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{8,99}", + "durability": null, + "name": "Woodcut. cape(t)", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "9808", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", + "equipment_slot": "1" + }, + { + "remove_head": "true", + "requirements": "{8,99}", + "shop_price": "99000", + "examine": "Woodcutting skillcape hood.", + "durability": null, + "name": "Woodcutting hood", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9809", + "equipment_slot": "0" + }, + { + "requirements": "{19,99}", + "shop_price": "99000", + "examine": "The cape worn by master farmers.", + "durability": null, + "name": "Farming cape", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9810", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{19,99}", + "durability": null, + "name": "Farming cape(t)", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "9811", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", + "equipment_slot": "1" + }, + { + "remove_head": "true", + "requirements": "{19,99}", + "shop_price": "99000", + "examine": "Farming skillcape hood.", + "durability": null, + "name": "Farming hood", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9812", + "equipment_slot": "0" + }, + { + "shop_price": "99000", + "examine": "The cape worn by only the most experienced adventurers.", + "durability": null, + "name": "Quest point cape", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9813", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", + "equipment_slot": "1" + }, + { + "remove_head": "true", + "shop_price": "99000", + "examine": "Quest skillcape hood.", + "durability": null, + "name": "Quest point hood", + "tradeable": "false", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9814", + "equipment_slot": "0" + }, + { + "examine": "A woolly bobble hat.", + "durability": null, + "name": "Bobble hat", + "tradeable": "false", + "destroy": "true", + "weight": "0.25", + "archery_ticket_price": "0", + "id": "9815", + "equipment_slot": "0" + }, + { + "examine": "A woolly scarf.", + "durability": null, + "name": "Bobble scarf", + "weight": "0.25", + "archery_ticket_price": "0", + "id": "9816", + "equipment_slot": "2" + }, + { + "grand_exchange_price": "1", + "durability": null, + "name": "Oak cape rack", + "archery_ticket_price": "0", + "id": "9817" + }, + { + "grand_exchange_price": "88", + "durability": null, + "name": "Teak cape rack", + "archery_ticket_price": "0", + "id": "9818" + }, + { + "grand_exchange_price": "120", + "durability": null, + "name": "M'gany cape rack", + "archery_ticket_price": "0", + "id": "9819" + }, + { + "grand_exchange_price": "136025", + "durability": null, + "name": "Gilded cape rack", + "archery_ticket_price": "0", + "id": "9820" + }, + { + "grand_exchange_price": "328598", + "durability": null, + "name": "Marble cape rack", + "archery_ticket_price": "0", + "id": "9821" + }, + { + "grand_exchange_price": "979747", + "durability": null, + "name": "Magical cape rack", + "archery_ticket_price": "0", + "id": "9822" + }, + { + "grand_exchange_price": "59", + "durability": null, + "name": "Oak costume box", + "archery_ticket_price": "0", + "id": "9823" + }, + { + "grand_exchange_price": "122", + "durability": null, + "name": "Teak costume box", + "archery_ticket_price": "0", + "id": "9824" + }, + { + "grand_exchange_price": "59", + "durability": null, + "name": "Mahogany cos box", + "archery_ticket_price": "0", + "id": "9825" + }, + { + "grand_exchange_price": "15", + "durability": null, + "name": "Oak armour case", + "archery_ticket_price": "0", + "id": "9826" + }, + { + "grand_exchange_price": "27", + "durability": null, + "name": "Teak armour case", + "archery_ticket_price": "0", + "id": "9827" + }, + { + "grand_exchange_price": "90", + "durability": null, + "name": "M'gany arm'r case", + "archery_ticket_price": "0", + "id": "9828" + }, + { + "grand_exchange_price": "103", + "durability": null, + "name": "Oak magic wardrobe", + "archery_ticket_price": "0", + "id": "9829" + }, + { + "grand_exchange_price": "1", + "durability": null, + "name": "Carved oak magic wardrobe", + "archery_ticket_price": "0", + "id": "9830" + }, + { + "grand_exchange_price": "127", + "durability": null, + "name": "Teak magic wardrobe", + "archery_ticket_price": "0", + "id": "9831" + }, + { + "grand_exchange_price": "13", + "durability": null, + "name": "Carved teak magic wardrobe", + "archery_ticket_price": "0", + "id": "9832" + }, + { + "grand_exchange_price": "135", + "durability": null, + "name": "Mahogany magic wardrobe", + "archery_ticket_price": "0", + "id": "9833" + }, + { + "grand_exchange_price": "137267", + "durability": null, + "name": "Gilded magic wardrobe", + "archery_ticket_price": "0", + "id": "9834" + }, + { + "grand_exchange_price": "341567", + "durability": null, + "name": "Marble magic wardrobe", + "archery_ticket_price": "0", + "id": "9835" + }, + { + "grand_exchange_price": "21", + "durability": null, + "name": "Oak toy box", + "archery_ticket_price": "0", + "id": "9836" + }, + { + "grand_exchange_price": "151", + "durability": null, + "name": "Teak toy box", + "archery_ticket_price": "0", + "id": "9837" + }, + { + "grand_exchange_price": "20", + "durability": null, + "name": "Mahogany toy box", + "archery_ticket_price": "0", + "id": "9838" + }, + { + "grand_exchange_price": "21", + "durability": null, + "name": "Oak treasure chest", + "archery_ticket_price": "0", + "id": "9839" + }, + { + "grand_exchange_price": "157", + "durability": null, + "name": "Teak treas' chest", + "archery_ticket_price": "0", + "id": "9840" + }, + { + "grand_exchange_price": "39", + "durability": null, + "name": "M'gany treas' chest", + "archery_ticket_price": "0", + "id": "9841" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3", + "examine": "A ready-to-assemble oak cape rack.", + "durability": null, + "name": "Oak cape rack", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "9843" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "92", + "examine": "A ready-to-assemble teak cape rack..", + "durability": null, + "name": "Teak cape rack", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "9844" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "111", + "examine": "A ready-to-assemble mahogany cape rack.", + "durability": null, + "name": "M'gany cape rack", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "9845" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "130900", + "examine": "A ready-to-assemble gilded mahogany rack.", + "durability": null, + "name": "Gilded cape rack", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "9846" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "329500", + "examine": "A ready-to-assemble marble cape rack.", + "durability": null, + "name": "Marble cape rack", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "9847" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1000000", + "examine": "A ready-to-assemble magic cape rack.", + "durability": null, + "name": "Magical cape rack", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "9848" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "25", + "examine": "A ready-to-assemble oak toy box.", + "durability": null, + "name": "Oak toy box", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "9849" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "165", + "examine": "A ready-to-assemble teak toy box.", + "durability": null, + "name": "Teak toy box", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "9850" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "20", + "examine": "A ready-to-assemble mahogany toy box.", + "durability": null, + "name": "Mahogany toy box", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "9851" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "111", + "examine": "A ready-to-assemble oak magic wardrobe.", + "durability": null, + "name": "Oak magic wardrobe", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "9852" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1", + "examine": "A ready-to-assemble oak magic wardrobe.", + "durability": null, + "name": "Carved oak magic wardrobe", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "9853" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "133", + "examine": "A ready-to-assemble teak magic wardrobe.", + "durability": null, + "name": "Teak magic wardrobe", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "9854" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "15", + "examine": "A ready-to-assemble carved teak magic wardrobe.", + "durability": null, + "name": "Carved teak magic wardrobe", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "9855" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "129", + "examine": "A ready-to-assemble mahogany magic wardrobe.", + "durability": null, + "name": "Mahogany magic wardrobe", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "9856" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "137700", + "examine": "A ready-to-assemble gilded mahogany magic wardrobe.", + "durability": null, + "name": "Gilded magic wardrobe", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "9857" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "335800", + "examine": "A ready-to-assemble marble magic wardrobe.", + "durability": null, + "name": "Marble magic wardrobe", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "9858" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "17", + "examine": "A ready-to-assemble oak armour case.", + "durability": null, + "name": "Oak armour case", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "9859" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "29", + "examine": "A ready-to-assemble teak armour case.", + "durability": null, + "name": "Teak armour case", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "9860" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "88", + "examine": "A ready-to-assemble mahogany armour case.", + "durability": null, + "name": "M'gany arm'r case", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "9861" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "24", + "examine": "A ready-to-assemble oak treasure chest.", + "durability": null, + "name": "Oak treasure chest", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "9862" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "164", + "examine": "A ready-to-assemble teak treasure chest.", + "durability": null, + "name": "Teak treas' chest", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "9863" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "41", + "examine": "A ready-to-assemble mahogany treasure chest.", + "durability": null, + "name": "M'gany treas' chest", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "9864" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "62", + "durability": null, + "name": "Oak costume box", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "9865" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "135", + "durability": null, + "name": "Teak costume box", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "9866" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "60", + "durability": null, + "name": "Mahogany cos box", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "1", + "id": "9867" + }, + { + "durability": null, + "name": "Oak cape rack", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9868" + }, + { + "durability": null, + "name": "Teak cape rack", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9869" + }, + { + "durability": null, + "name": "M'gany cape rack", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9870" + }, + { + "durability": null, + "name": "Gilded cape rack", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9871" + }, + { + "durability": null, + "name": "Marble cape rack", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9872" + }, + { + "durability": null, + "name": "Magical cape rack", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9873" + }, + { + "durability": null, + "name": "Oak toy box", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9874" + }, + { + "durability": null, + "name": "Teak toy box", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9875" + }, + { + "durability": null, + "name": "Mahogany toy box", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9876" + }, + { + "durability": null, + "name": "Oak magic wardrobe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9877" + }, + { + "durability": null, + "name": "Carved oak magic wardrobe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9878" + }, + { + "durability": null, + "name": "Teak magic wardrobe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9879" + }, + { + "durability": null, + "name": "Carved teak magic wardrobe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9880" + }, + { + "durability": null, + "name": "Mahogany magic wardrobe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9881" + }, + { + "durability": null, + "name": "Gilded magic wardrobe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9882" + }, + { + "durability": null, + "name": "Marble magic wardrobe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9883" + }, + { + "durability": null, + "name": "Oak armour case", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9884" + }, + { + "durability": null, + "name": "Teak armour case", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9885" + }, + { + "durability": null, + "name": "M'gany arm'r case", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9886" + }, + { + "durability": null, + "name": "Oak treasure chest", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9887" + }, + { + "durability": null, + "name": "Teak treas' chest", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9888" + }, + { + "durability": null, + "name": "M'gany treas' chest", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9889" + }, + { + "durability": null, + "name": "Oak costume box", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9890" + }, + { + "durability": null, + "name": "Teak costume box", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9891" + }, + { + "durability": null, + "name": "Mahogany cos box", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9892" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A lump that at some point might have been a gout tuber.", + "durability": null, + "name": "Goutweedy lump", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "9901" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A pile of gout tubers suitable for use in mountainous terrain.", + "durability": null, + "name": "Hardy gout tubers", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "9902" + }, + { + "destroy_message": "My Arm will probably have a spare copy.", + "examine": "Farmer Gricoller's Farming Manual.", + "durability": null, + "name": "Farming manual", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "9903" + }, + { + "examine": "A book for sailors.", + "durability": null, + "name": "Sailing book", + "archery_ticket_price": "0", + "id": "9904" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "See article", + "durability": null, + "name": "Ghost buster 500", + "archery_ticket_price": "0", + "id": "9906", + "equipment_slot": "3" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "See article", + "durability": null, + "name": "Ghost buster 500", + "archery_ticket_price": "0", + "id": "9907", + "equipment_slot": "3" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "See article", + "durability": null, + "name": "Ghost buster 500", + "archery_ticket_price": "0", + "id": "9908", + "equipment_slot": "3" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "See article", + "durability": null, + "name": "Ghost buster 500", + "archery_ticket_price": "0", + "id": "9909", + "equipment_slot": "3" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "See article", + "durability": null, + "name": "Ghost buster 500", + "archery_ticket_price": "0", + "id": "9910", + "equipment_slot": "3" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "See article", + "durability": null, + "name": "Ghost buster 500", + "archery_ticket_price": "0", + "id": "9911", + "equipment_slot": "3" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "See article", + "durability": null, + "name": "Ghost buster 500", + "archery_ticket_price": "0", + "id": "9912", + "equipment_slot": "3" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A white destabiliser for use in a ghost buster.", + "durability": null, + "name": "White destabiliser", + "archery_ticket_price": "0", + "id": "9913", + "equipment_slot": "5" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A red destabiliser for use in a ghost buster.", + "durability": null, + "name": "Red destabiliser", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "9914", + "equipment_slot": "5" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A blue destabiliser for use in a ghost buster.", + "durability": null, + "name": "Blue destabiliser", + "archery_ticket_price": "0", + "id": "9915", + "equipment_slot": "5" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A green destabiliser for use in a ghost buster.", + "durability": null, + "name": "Green destabiliser", + "archery_ticket_price": "0", + "id": "9916", + "equipment_slot": "5" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A yellow destabiliser for use in a ghost buster.", + "durability": null, + "name": "Yellow destabiliser", + "archery_ticket_price": "0", + "id": "9917", + "equipment_slot": "5" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A black destabiliser for use in a ghost buster.", + "durability": null, + "name": "Black destabiliser", + "archery_ticket_price": "0", + "id": "9918", + "equipment_slot": "5" + }, + { + "examine": "An angry-looking tree root.", + "durability": null, + "name": "Evil root", + "archery_ticket_price": "0", + "id": "9919" + }, + { + "remove_head": "true", + "destroy_message": "Players may get another from Diango in Draynor Village.", + "examine": "Better not light it!", + "durability": null, + "name": "Jack lantern mask", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "9920", + "equip_audio": "3227", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Skeleton feet.", + "durability": null, + "name": "Skeleton boots", + "weight": "2", + "archery_ticket_price": "0", + "id": "9921", + "equipment_slot": "10" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Some skeletal gloves.", + "durability": null, + "name": "Skeleton gloves", + "weight": "2", + "archery_ticket_price": "0", + "id": "9922", + "equipment_slot": "9" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Does my pelvis look big in this?", + "durability": null, + "name": "Skeleton leggings", + "weight": "2", + "archery_ticket_price": "0", + "id": "9923", + "equipment_slot": "7" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "remove_sleeves": "true", + "examine": "The shirt of a fully body skeleton costume.", + "durability": null, + "name": "Skeleton shirt", + "weight": "2", + "archery_ticket_price": "0", + "id": "9924", + "equipment_slot": "4" + }, + { + "remove_head": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A scary skeleton mask.", + "durability": null, + "name": "Skeleton mask", + "weight": "2", + "archery_ticket_price": "0", + "id": "9925", + "equipment_slot": "0" + }, + { + "destroy_message": "You'll have to buy another one from Auguste on Entrana.", + "shop_price": "30000", + "examine": "This sapling is ready to be replanted in a tree patch.", + "durability": null, + "name": "Auguste's sapling", + "tradeable": "false", + "destroy": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "9932" + }, + { + "examine": "An incomplete origami balloon.", + "durability": null, + "name": "Balloon structure", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "9933" + }, + { + "examine": "An origami balloon.", + "durability": null, + "name": "Origami balloon", + "archery_ticket_price": "0", + "id": "9934" + }, + { + "examine": "An origami balloon.", + "durability": null, + "name": "Yellow balloon", + "archery_ticket_price": "0", + "id": "9935" + }, + { + "examine": "An origami balloon.", + "durability": null, + "name": "Blue balloon", + "archery_ticket_price": "0", + "id": "9936" + }, + { + "examine": "An origami balloon.", + "durability": null, + "name": "Red balloon", + "archery_ticket_price": "0", + "id": "9937" + }, + { + "examine": "An origami balloon.", + "durability": null, + "name": "Orange balloon", + "archery_ticket_price": "0", + "id": "9938" + }, + { + "examine": "An origami balloon.", + "durability": null, + "name": "Green balloon", + "archery_ticket_price": "0", + "id": "9939" + }, + { + "examine": "An origami balloon.", + "durability": null, + "name": "Purple balloon", + "archery_ticket_price": "0", + "id": "9940" + }, + { + "examine": "An origami balloon.", + "durability": null, + "name": "Pink balloon", + "archery_ticket_price": "0", + "id": "9941" + }, + { + "examine": "An origami balloon.", + "durability": null, + "name": "Black balloon", + "archery_ticket_price": "0", + "id": "9942" + }, + { + "examine": "A bag full of sand.", + "durability": null, + "name": "Sandbag", + "weight": "1", + "archery_ticket_price": "0", + "id": "9943", + "equipment_slot": "3" + }, + { + "destroy_message": "You'll have to visit Auguste on Entrana to get a new jacket.", + "remove_sleeves": "true", + "examine": "For all your flying needs.", + "durability": null, + "name": "Bomber jacket", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "9944", + "equipment_slot": "4" + }, + { + "remove_head": "true", + "destroy_message": "You'll have to visit Auguste on Entrana to get a new cap.", + "examine": "The red baron would be jealous.", + "durability": null, + "name": "Bomber cap", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "9945", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "examine": "For better flying vision.", + "durability": null, + "name": "Cap and goggles", + "archery_ticket_price": "0", + "id": "9946", + "equipment_slot": "0" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A red coloured disk that's seen better days.", + "durability": null, + "name": "Old red disk", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "9947" + }, + { + "requirements": "{21,99}", + "shop_price": "99000", + "examine": "The cape worn by master hunters.", + "durability": null, + "name": "Hunter cape", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9948", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{21,99}", + "durability": null, + "name": "Hunter cape(t)", + "archery_ticket_price": "0", + "id": "9949", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", + "equipment_slot": "1" + }, + { + "remove_head": "true", + "requirements": "{21,99}", + "shop_price": "99000", + "examine": "Hunter skillcape hood.", + "durability": null, + "name": "Hunter hood", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "9950", + "equipment_slot": "0" + }, + { + "durability": null, + "name": "Imp", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "9952" + }, + { + "examine": "A little bigger than usual...", + "durability": null, + "name": "Kebbit", + "archery_ticket_price": "0", + "id": "9953" + }, + { + "examine": "A little bigger than usual...", + "durability": null, + "name": "Kebbit", + "archery_ticket_price": "0", + "id": "9954" + }, + { + "examine": "A little bigger than usual...", + "durability": null, + "name": "Kebbit", + "archery_ticket_price": "0", + "id": "9955" + }, + { + "examine": "A little bigger than usual...", + "durability": null, + "name": "Kebbit", + "archery_ticket_price": "0", + "id": "9956" + }, + { + "examine": "A little bigger than usual...", + "durability": null, + "name": "Kebbit", + "archery_ticket_price": "0", + "id": "9957" + }, + { + "examine": "A little bigger than usual...", + "durability": null, + "name": "Kebbit", + "archery_ticket_price": "0", + "id": "9958" + }, + { + "examine": "A little bigger than usual...", + "durability": null, + "name": "Kebbit", + "archery_ticket_price": "0", + "id": "9959" + }, + { + "examine": "A little bigger than usual...", + "durability": null, + "name": "Kebbit", + "archery_ticket_price": "0", + "id": "9960" + }, + { + "examine": "A little bigger than usual...", + "durability": null, + "name": "Kebbit", + "archery_ticket_price": "0", + "id": "9961" + }, + { + "examine": "A little bigger than usual...", + "durability": null, + "name": "Kebbit", + "archery_ticket_price": "0", + "id": "9962" + }, + { + "examine": "A little bigger than usual...", + "durability": null, + "name": "Kebbit", + "archery_ticket_price": "0", + "id": "9963" + }, + { + "examine": "A little bigger than usual...", + "durability": null, + "name": "Kebbit", + "archery_ticket_price": "0", + "id": "9964" + }, + { + "examine": "It appears to be protecting the nest.", + "durability": null, + "name": "Giant eagle", + "archery_ticket_price": "0", + "id": "9974" + }, + { + "examine": "Aww, how cute. ", + "durability": null, + "name": "Rabbit", + "archery_ticket_price": "0", + "id": "9975" + }, + { + "examine": "Even more volatile than its vegetarian counterpart.", + "grand_exchange_price": "796", + "durability": null, + "name": "Red chinchompa", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "9977", + "bonuses": "0,0,0,0,70,0,0,0,0,0,0,0,15,0,0" + }, + { + "shop_price": "63", + "ge_buy_limit": "10000", + "examine": "This certainly needs cooking!", + "grand_exchange_price": "204", + "durability": null, + "name": "Raw bird meat", + "tradeable": "true", + "weight": "0.15", + "archery_ticket_price": "0", + "id": "9978" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "204", + "durability": null, + "name": "Raw bird meat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9979" + }, + { + "ge_buy_limit": "1000", + "examine": "A nicely roasted bird.", + "grand_exchange_price": "18", + "durability": null, + "name": "Roast bird meat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9980" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "18", + "durability": null, + "name": "Roast bird meat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9981" + }, + { + "durability": null, + "name": "Burnt bird meat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9983" + }, + { + "shop_price": "63", + "ge_buy_limit": "1000", + "examine": "This certainly needs cooking!", + "grand_exchange_price": "130", + "durability": null, + "name": "Skewered bird meat", + "tradeable": "true", + "weight": "0.15", + "archery_ticket_price": "0", + "id": "9984" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "130", + "durability": null, + "name": "Skewered bird meat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9985" + }, + { + "ge_buy_limit": "1000", + "examine": "A slab of raw beast meat.", + "grand_exchange_price": "16", + "durability": null, + "name": "Raw beast meat", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "9986" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "16", + "durability": null, + "name": "Raw beast meat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9987" + }, + { + "ge_buy_limit": "1000", + "examine": "A delicious looking slab of roast beast.", + "grand_exchange_price": "42", + "durability": null, + "name": "Roast beast meat", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "9988" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "42", + "durability": null, + "name": "Roast beast meat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9989" + }, + { + "durability": null, + "name": "Burnt beast meat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9991" + }, + { + "ge_buy_limit": "1000", + "examine": "Beast meat on a spit.", + "grand_exchange_price": "97", + "durability": null, + "name": "Skewered beast", + "tradeable": "true", + "weight": "3.5", + "archery_ticket_price": "0", + "id": "9992" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "97", + "durability": null, + "name": "Skewered beast", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9993" + }, + { + "ge_buy_limit": "1000", + "examine": "A bowl of chopped tomatoes with an extra kick.", + "grand_exchange_price": "324", + "durability": null, + "name": "Spicy tomato", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "9994" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "324", + "durability": null, + "name": "Spicy tomato", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9995" + }, + { + "ge_buy_limit": "1000", + "examine": "A bowl of chopped beef with an extra kick.", + "grand_exchange_price": "263", + "durability": null, + "name": "Spicy minced meat", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "9996" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "263", + "durability": null, + "name": "Spicy minced meat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9997" + }, + { + "ge_buy_limit": "100", + "examine": "4 doses of hunter potion.", + "grand_exchange_price": "566", + "durability": null, + "name": "Hunter potion(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9998" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "566", + "durability": null, + "name": "Hunter potion(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "9999" + }, + { + "ge_buy_limit": "100", + "examine": "3 doses of hunter potion.", + "grand_exchange_price": "229", + "durability": null, + "name": "Hunter potion(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10000" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "229", + "durability": null, + "name": "Hunter potion(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10001" + }, + { + "ge_buy_limit": "100", + "examine": "2 doses of hunter potion.", + "grand_exchange_price": "159", + "durability": null, + "name": "Hunter potion(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10002" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "159", + "durability": null, + "name": "Hunter potion(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10003" + }, + { + "ge_buy_limit": "100", + "examine": "1 dose of hunter potion.", + "grand_exchange_price": "148", + "durability": null, + "name": "Hunter potion(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10004" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "148", + "durability": null, + "name": "Hunter potion(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10005" + }, + { + "shop_price": "6", + "ge_buy_limit": "100", + "examine": "A simple bird catcher./There's something caught in it.", + "grand_exchange_price": "2", + "durability": null, + "name": "Bird snare", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10006" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2", + "durability": null, + "name": "Bird snare", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10007" + }, + { + "requirements": "{21,27}", + "shop_price": "38", + "ge_buy_limit": "100", + "examine": "If a creature goes inside, then the box should slam shut.", + "grand_exchange_price": "308", + "durability": null, + "name": "Box trap", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "10008" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "308", + "durability": null, + "name": "Box trap", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10009" + }, + { + "requirements": "{21,15}", + "shop_price": "24", + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "For catching butterflies...", + "walk_anim": "1205", + "durability": null, + "weight": "0.2", + "turn90ccw_anim": "1208", + "attack_speed": "4", + "weapon_interface": "10", + "turn180_anim": "1206", + "render_anim": "28", + "defence_anim": "403", + "equipment_slot": "3", + "attack_anims": "401,401,400,401", + "grand_exchange_price": "1", + "stand_anim": "813", + "name": "Butterfly net", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "10010", + "stand_turn_anim": "1209" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1", + "durability": null, + "name": "Butterfly net", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10011" + }, + { + "requirements": "{21,15}", + "shop_price": "1", + "ge_buy_limit": "100", + "examine": "It's got little holes at the top.", + "grand_exchange_price": "156", + "durability": null, + "name": "Butterfly jar", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.02", + "id": "10012" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "156", + "durability": null, + "name": "Butterfly jar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10013" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "143", + "examine": "There's a black warlock butterfly in here.", + "durability": null, + "name": "Black warlock", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.02", + "id": "10014" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "143", + "durability": null, + "name": "Black warlock", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10015" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "227", + "examine": "There's a snowy knight butterfly in here.", + "durability": null, + "name": "Snowy knight", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.02", + "id": "10016" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "227", + "durability": null, + "name": "Snowy knight", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10017" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "180", + "examine": "There's a sapphire glacialis butterfly in here.", + "durability": null, + "name": "Sapphire glacialis", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.02", + "id": "10018" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "180", + "durability": null, + "name": "Sapphire glacialis", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10019" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "1270", + "examine": "There's a ruby harvest butterfly in here.", + "durability": null, + "name": "Ruby harvest", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.02", + "id": "10020" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "1270", + "durability": null, + "name": "Ruby harvest", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10021" + }, + { + "shop_price": "500", + "examine": "A very large, single leather glove", + "durability": null, + "name": "Falconer's glove", + "tradeable": "false", + "destroy": "true", + "weight": "1.8", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "10023", + "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0", + "equipment_slot": "3" + }, + { + "shop_price": "500", + "turn90cw_anim": "5166", + "examine": "A very large, single leather glove", + "walk_anim": "5164", + "durability": null, + "destroy": "true", + "weight": "1.8", + "turn90ccw_anim": "5167", + "attack_speed": "4", + "turn180_anim": "5165", + "render_anim": "1283", + "equipment_slot": "3", + "stand_anim": "5160", + "name": "Falconer's glove", + "tradeable": "false", + "run_anim": "5168", + "archery_ticket_price": "0", + "id": "10024", + "stand_turn_anim": "5161", + "bonuses": "0,0,0,0,0,0,1,1,0,0,0,0,0,0,0" + }, + { + "requirements": "{21,71}", + "shop_price": "720", + "ge_buy_limit": "100", + "examine": "A magical catching box.", + "grand_exchange_price": "784", + "durability": null, + "name": "Magic box", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10025" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "784", + "durability": null, + "name": "Magic box", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10026" + }, + { + "shop_price": "720", + "examine": "A magical catching box.", + "grand_exchange_price": "743", + "durability": null, + "name": "Imp-in-a-box(2)", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10027" + }, + { + "shop_price": "720", + "examine": "A magical catching box.", + "grand_exchange_price": "743", + "durability": null, + "name": "Imp-in-a-box(1)", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10028" + }, + { + "requirements": "{21,31}", + "shop_price": "1", + "ge_buy_limit": "100", + "examine": "Reduces the risk of hand severage when poking large, vicious carnivores.", + "durability": null, + "weight": "1", + "weapon_interface": "6", + "equipment_slot": "3", + "grand_exchange_price": "1", + "name": "Teasing stick", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10029", + "bonuses": "7,8,0,-4,0,-1,1,2,0,0,0,8,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1", + "durability": null, + "name": "Teasing stick", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10030" + }, + { + "requirements": "{21,27}", + "shop_price": "18", + "ge_buy_limit": "100", + "examine": "The snare will tighten around animals passing through.", + "grand_exchange_price": "1", + "durability": null, + "name": "Rabbit snare", + "tradeable": "true", + "weight": "0.02", + "archery_ticket_price": "0", + "id": "10031" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1", + "durability": null, + "name": "Rabbit snare", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10032" + }, + { + "requirements": "{4,45}", + "ge_buy_limit": "20000", + "turn90cw_anim": "3177", + "walk_anim": "3177", + "durability": null, + "turn90ccw_anim": "3177", + "attack_speed": "4", + "weapon_interface": "19", + "turn180_anim": "3177", + "render_anim": "234", + "equipment_slot": "3", + "grand_exchange_price": "973", + "stand_anim": "3175", + "name": "Chinchompa", + "run_anim": "3178", + "archery_ticket_price": "0", + "id": "10033", + "stand_turn_anim": "3177", + "bonuses": "0,0,0,0,45,0,0,0,0,0,0,0,0,0,0" + }, + { + "requirements": "{4,55}", + "ge_buy_limit": "20000", + "turn90cw_anim": "3177", + "examine": "Even more volatile than its vegetarian counterpart.", + "walk_anim": "3177", + "durability": null, + "destroy": "true", + "turn90ccw_anim": "3177", + "attack_speed": "4", + "weapon_interface": "19", + "turn180_anim": "3177", + "render_anim": "234", + "equipment_slot": "3", + "grand_exchange_price": "1382", + "stand_anim": "3175", + "name": "Red chinchompa", + "tradeable": "true", + "run_anim": "3178", + "archery_ticket_price": "0", + "id": "10034", + "stand_turn_anim": "3177", + "bonuses": "0,0,0,0,70,0,0,0,0,0,0,0,0,0,15" + }, + { + "requirements": "{21,52}", + "ge_buy_limit": "100", + "examine": "These should make me harder to spot in polar areas.", + "grand_exchange_price": "449", + "durability": null, + "name": "Kyatt legs", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "10035", + "bonuses": "0,0,0,0,-7,11,10,10,0,10,10,0,0,0,0", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "449", + "durability": null, + "name": "Kyatt legs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10036" + }, + { + "requirements": "{21,52}", + "ge_buy_limit": "100", + "examine": "This should make me harder to spot in polar areas.", + "durability": null, + "weight": "0.2", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "272", + "name": "Kyatt top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10037", + "bonuses": "0,0,0,0,0,10,15,19,0,12,20,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "272", + "durability": null, + "name": "Kyatt top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10038" + }, + { + "remove_head": "true", + "requirements": "{21,52}", + "ge_buy_limit": "100", + "examine": "This should make me harder to spot in polar areas.", + "durability": null, + "weight": "0.2", + "equipment_slot": "0", + "grand_exchange_price": "8338", + "name": "Kyatt hat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10039", + "bonuses": "0,0,0,0,-1,4,5,3,0,4,3,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "8338", + "durability": null, + "name": "Kyatt hat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10040" + }, + { + "requirements": "{21,28}", + "ge_buy_limit": "100", + "examine": "This should make me harder to spot in woodland and jungle areas.", + "grand_exchange_price": "2889", + "durability": null, + "name": "Larupia legs", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "10041", + "bonuses": "0,0,0,0,-7,11,10,10,0,10,5,0,0,0,0", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2889", + "durability": null, + "name": "Larupia legs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10042" + }, + { + "requirements": "{21,28}", + "ge_buy_limit": "100", + "examine": "This should make me harder to spot in woodland and jungle areas.", + "durability": null, + "weight": "0.2", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "3232", + "name": "Larupia top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10043", + "bonuses": "0,0,0,0,0,10,15,19,0,12,10,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3232", + "durability": null, + "name": "Larupia top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10044" + }, + { + "remove_head": "true", + "requirements": "{21,28}", + "ge_buy_limit": "100", + "examine": "This should make me harder to spot in woodland and jungle areas.", + "durability": null, + "weight": "0.2", + "equipment_slot": "0", + "grand_exchange_price": "7237", + "name": "Larupia hat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10045", + "bonuses": "0,0,0,0,-1,4,5,3,0,4,5,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "7237", + "durability": null, + "name": "Larupia hat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10046" + }, + { + "requirements": "{21,38}", + "shop_price": "150", + "ge_buy_limit": "100", + "examine": "These should make me harder to spot in desert areas.", + "durability": null, + "weight": "0.2", + "equipment_slot": "7", + "grand_exchange_price": "266", + "name": "Graahk legs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10047", + "bonuses": "0,0,0,0,-7,11,10,10,0,10,10,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "266", + "durability": null, + "name": "Graahk legs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10048" + }, + { + "requirements": "{21,38}", + "shop_price": "300", + "ge_buy_limit": "100", + "examine": "This should make me harder to spot in desert areas.", + "durability": null, + "weight": "0.2", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "252", + "name": "Graahk top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10049", + "bonuses": "0,0,0,0,0,10,15,19,0,12,15,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "252", + "durability": null, + "name": "Graahk top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10050" + }, + { + "remove_head": "true", + "requirements": "{21,38}", + "shop_price": "1", + "ge_buy_limit": "100", + "examine": "This should make me harder to spot in desert areas.", + "durability": null, + "weight": "0.2", + "equipment_slot": "0", + "grand_exchange_price": "8445", + "name": "Graahk headdress", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10051", + "bonuses": "0,0,0,0,-1,4,5,3,0,4,3,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "8445", + "durability": null, + "name": "Graahk headdress", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10052" + }, + { + "remove_sleeves": "true", + "ge_buy_limit": "100", + "examine": "This should make me harder to spot in wooded areas.", + "grand_exchange_price": "3527", + "durability": null, + "name": "Wood camo top", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "10053", + "bonuses": "0,0,0,0,0,10,15,19,0,12,5,0,0,0,0", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3527", + "durability": null, + "name": "Wood camo top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10054" + }, + { + "ge_buy_limit": "100", + "examine": "These should make me harder to spot in wooded areas.", + "grand_exchange_price": "3228", + "durability": null, + "name": "Wood camo legs", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "10055", + "bonuses": "0,0,0,0,-7,11,10,10,0,10,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3228", + "durability": null, + "name": "Wood camo legs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10056" + }, + { + "requirements": "{21,4}", + "ge_buy_limit": "100", + "examine": "This should make me harder to spot in jungle areas.", + "durability": null, + "weight": "0.2", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "315", + "name": "Jungle camo top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10057", + "bonuses": "0,0,0,0,0,10,15,19,0,12,5,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "315", + "durability": null, + "name": "Jungle camo top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10058" + }, + { + "requirements": "{21,4}", + "ge_buy_limit": "100", + "examine": "These should make me harder to spot in jungle areas.", + "grand_exchange_price": "462", + "durability": null, + "name": "Jungle camo legs", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "10059", + "bonuses": "0,0,0,0,-7,11,10,10,0,10,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "462", + "durability": null, + "name": "Jungle camo legs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10060" + }, + { + "requirements": "{21,10}", + "ge_buy_limit": "100", + "examine": "This should make me harder to spot in desert areas.", + "durability": null, + "weight": "0.2", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "541", + "name": "Desert camo top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10061", + "bonuses": "0,0,0,0,0,10,15,19,0,12,10,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "541", + "durability": null, + "name": "Desert camo top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10062" + }, + { + "requirements": "{21,10}", + "ge_buy_limit": "100", + "examine": "These should make me harder to spot in desert areas.", + "grand_exchange_price": "910", + "durability": null, + "name": "Desert camo legs", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "10063", + "bonuses": "0,0,0,0,-7,11,10,10,0,10,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "910", + "durability": null, + "name": "Desert camo legs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10064" + }, + { + "remove_sleeves": "true", + "ge_buy_limit": "100", + "examine": "This should make me harder to spot in polar areas.", + "grand_exchange_price": "7990", + "durability": null, + "name": "Polar camo top", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "10065", + "bonuses": "0,0,0,0,0,10,15,19,0,12,5,0,0,0,0", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "7990", + "durability": null, + "name": "Polar camo top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10066" + }, + { + "ge_buy_limit": "100", + "examine": "These should make me harder to spot in polar areas", + "grand_exchange_price": "8389", + "durability": null, + "name": "Polar camo legs", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "10067", + "bonuses": "0,0,0,0,-7,11,10,10,0,10,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "8389", + "durability": null, + "name": "Polar camo legs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10068" + }, + { + "requirements": "{21,40}", + "ge_buy_limit": "100", + "examine": "A surprisingly aerodynamic cape.", + "grand_exchange_price": "1140", + "durability": null, + "name": "Spotted cape", + "tradeable": "true", + "weight": "-2.2", + "archery_ticket_price": "0", + "id": "10069", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1140", + "durability": null, + "name": "Spotted cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10070" + }, + { + "requirements": "{21,66}", + "ge_buy_limit": "100", + "examine": "A really surprisingly aerodynamic cape.", + "grand_exchange_price": "1262", + "durability": null, + "name": "Spottier cape", + "tradeable": "true", + "weight": "-4.5", + "archery_ticket_price": "0", + "id": "10071", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1262", + "durability": null, + "name": "Spottier cape", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10072" + }, + { + "requirements": "{21,40}", + "examine": "A surprisingly aerodynamic cape.", + "grand_exchange_price": "951", + "durability": null, + "name": "Spotted cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10073", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{21,66}", + "examine": "A really surprisingly aerodynamic cape.", + "grand_exchange_price": "881", + "durability": null, + "name": "Spottier cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10074", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{21,54}", + "ge_buy_limit": "100", + "examine": "Made from dark kebbit fur, these are perfect for tasks of a stealthier nature.", + "grand_exchange_price": "1063", + "durability": null, + "name": "Gloves of silence", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "10075", + "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0", + "equipment_slot": "9" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1063", + "durability": null, + "name": "Gloves of silence", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10076" + }, + { + "ge_buy_limit": "100", + "examine": "Attack at your own risk.", + "grand_exchange_price": "80", + "durability": null, + "name": "Spiky vambraces", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10077", + "bonuses": "0,0,0,0,4,2,2,1,0,0,1,2,0,0,0", + "equip_audio": "2241", + "equipment_slot": "9" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "80", + "durability": null, + "name": "Spiky vambraces", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10078" + }, + { + "requirements": "{4,40}", + "ge_buy_limit": "100", + "examine": "Made from 100% real dragonhide. Now with added spikiness.", + "durability": null, + "weight": "1", + "equip_audio": "2241", + "equipment_slot": "9", + "grand_exchange_price": "1353", + "name": "Green spiky vambs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10079", + "bonuses": "0,0,0,-10,8,3,2,4,2,0,3,2,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1353", + "durability": null, + "name": "Green spiky vambs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10080" + }, + { + "requirements": "{4,50}", + "ge_buy_limit": "100", + "examine": "Made from 100% real dragonhide. Now with added spikiness.", + "grand_exchange_price": "1773", + "durability": null, + "name": "Blue spiky vambs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10081", + "bonuses": "0,0,0,-10,9,4,3,5,4,0,4,2,0,0,0", + "equip_audio": "2241", + "equipment_slot": "9" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1773", + "durability": null, + "name": "Blue spiky vambs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10082" + }, + { + "requirements": "{4,60}", + "ge_buy_limit": "100", + "examine": "Vambraces made from 100% real dragonhide. Now with added spikes.", + "durability": null, + "weight": "1", + "equip_audio": "2241", + "equipment_slot": "9", + "grand_exchange_price": "1978", + "name": "Red spiky vambs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10083", + "bonuses": "0,0,0,-10,10,5,4,6,6,0,5,2,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1978", + "durability": null, + "name": "Red spiky vambs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10084" + }, + { + "requirements": "{4,70}", + "ge_buy_limit": "100", + "examine": "Vambraces made from 100% real dragonhide. Now with added spikiness.", + "durability": null, + "weight": "1", + "equip_audio": "2241", + "equipment_slot": "9", + "grand_exchange_price": "2727", + "name": "Black spiky vambs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10085", + "bonuses": "0,0,0,-10,11,6,5,7,8,0,6,2,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2727", + "durability": null, + "name": "Black spiky vambs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10086" + }, + { + "ge_buy_limit": "5000", + "examine": "Attractive to other birds and hunters alike.", + "grand_exchange_price": "20", + "durability": null, + "name": "Stripy feather", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10087" + }, + { + "shop_price": "3", + "ge_buy_limit": "5000", + "examine": "A vivid red feather.", + "grand_exchange_price": "23", + "durability": null, + "name": "Red feather", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10088" + }, + { + "ge_buy_limit": "5000", + "examine": "A cool blue feather.", + "grand_exchange_price": "27", + "durability": null, + "name": "Blue feather", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10089" + }, + { + "ge_buy_limit": "5000", + "examine": "A bright yellow feather.", + "grand_exchange_price": "36", + "durability": null, + "name": "Yellow feather", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10090" + }, + { + "shop_price": "6", + "ge_buy_limit": "5000", + "examine": "A fairly plain feather.", + "grand_exchange_price": "25", + "durability": null, + "name": "Orange feather", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10091" + }, + { + "ge_buy_limit": "100", + "examine": "It's a shabby-looking larupia fur.", + "grand_exchange_price": "1195", + "durability": null, + "name": "Tatty larupia fur", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "10093" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1195", + "durability": null, + "name": "Tatty larupia fur", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10094" + }, + { + "ge_buy_limit": "100", + "examine": "It's a perfect-looking larupia fur.", + "grand_exchange_price": "4986", + "durability": null, + "name": "Larupia fur", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "10095" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "4986", + "durability": null, + "name": "Larupia fur", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10096" + }, + { + "ge_buy_limit": "100", + "examine": "It's a shabby-looking graahk fur.", + "grand_exchange_price": "28", + "durability": null, + "name": "Tatty graahk fur", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "10097" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "28", + "durability": null, + "name": "Tatty graahk fur", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10098" + }, + { + "ge_buy_limit": "100", + "examine": "It's a perfect-looking graahk fur.", + "grand_exchange_price": "7574", + "durability": null, + "name": "Graahk fur", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "10099" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "7574", + "durability": null, + "name": "Graahk fur", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10100" + }, + { + "ge_buy_limit": "100", + "examine": "It's a shabby-looking kyatt fur.", + "grand_exchange_price": "23", + "durability": null, + "name": "Tatty kyatt fur", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10101" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "23", + "durability": null, + "name": "Tatty kyatt fur", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10102" + }, + { + "shop_price": "8000", + "ge_buy_limit": "100", + "examine": "It's a perfect-looking kyatt fur.", + "grand_exchange_price": "11100", + "durability": null, + "name": "Kyatt fur", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "10103" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "11100", + "durability": null, + "name": "Kyatt fur", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10104" + }, + { + "ge_buy_limit": "5000", + "examine": "These bone spikes are both very tough and very sharp.", + "grand_exchange_price": "154", + "durability": null, + "name": "Kebbit spike", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10105" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "154", + "durability": null, + "name": "Kebbit spike", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10106" + }, + { + "ge_buy_limit": "5000", + "examine": "These bone spikes are both very tough and very sharp.", + "grand_exchange_price": "1619", + "durability": null, + "name": "Long kebbit spike", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10107" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "1619", + "durability": null, + "name": "Long kebbit spike", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10108" + }, + { + "ge_buy_limit": "5000", + "examine": "A kebbit-sized set of dentures.", + "grand_exchange_price": "894", + "durability": null, + "name": "Kebbit teeth", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10109" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "894", + "durability": null, + "name": "Kebbit teeth", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10110" + }, + { + "ge_buy_limit": "5000", + "examine": "Previously a kebbit-sized set of dentures.", + "grand_exchange_price": "947", + "durability": null, + "name": "Kebbit teeth dust", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10111" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "947", + "durability": null, + "name": "Kebbit teeth dust", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10112" + }, + { + "ge_buy_limit": "5000", + "examine": "More menacing when attached to the owner.", + "grand_exchange_price": "55", + "durability": null, + "name": "Kebbit claws", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10113" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "55", + "durability": null, + "name": "Kebbit claws", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10114" + }, + { + "ge_buy_limit": "100", + "examine": "Sleek, silent, and furry.", + "grand_exchange_price": "92", + "durability": null, + "name": "Dark kebbit fur", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10115" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "92", + "durability": null, + "name": "Dark kebbit fur", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10116" + }, + { + "shop_price": "12", + "ge_buy_limit": "175", + "examine": "A thick fur for a cold climate.", + "grand_exchange_price": "3862", + "durability": null, + "name": "Polar kebbit fur", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10117" + }, + { + "ge_buy_limit": "175", + "grand_exchange_price": "3862", + "durability": null, + "name": "Polar kebbit fur", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10118" + }, + { + "ge_buy_limit": "100", + "examine": "Not actually from a weasel, but it is, at least, furry.", + "grand_exchange_price": "3", + "durability": null, + "name": "Feldip weasel fur", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10119" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3", + "durability": null, + "name": "Feldip weasel fur", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10120" + }, + { + "ge_buy_limit": "100", + "examine": "Common fur from a common kebbit.", + "grand_exchange_price": "1555", + "durability": null, + "name": "Common kebbit fur", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10121" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1555", + "durability": null, + "name": "Common kebbit fur", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10122" + }, + { + "ge_buy_limit": "100", + "examine": "Sandy coloured kebbit fur.", + "grand_exchange_price": "95", + "durability": null, + "name": "Desert devil fur", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10123" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "95", + "durability": null, + "name": "Desert devil fur", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10124" + }, + { + "ge_buy_limit": "100", + "examine": "Maybe this is why people think furry dice make you go faster.", + "grand_exchange_price": "8", + "durability": null, + "name": "Spotted kebbit fur", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10125" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "8", + "durability": null, + "name": "Spotted kebbit fur", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10126" + }, + { + "ge_buy_limit": "100", + "examine": "Nature's equivalent of go-faster stripes.", + "grand_exchange_price": "69", + "durability": null, + "name": "Dashing kebbit fur", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10127" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "69", + "durability": null, + "name": "Dashing kebbit fur", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10128" + }, + { + "requirements": "{10,35}", + "ge_buy_limit": "100", + "examine": "A mighty Hunter weapon. One previous owner.", + "durability": null, + "weight": "1.3", + "attack_speed": "5", + "weapon_interface": "5", + "equipment_slot": "3", + "grand_exchange_price": "19", + "name": "Barb-tail harpoon", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10129", + "bonuses": "9,4,-4,0,0,0,0,0,0,0,0,6,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "19", + "durability": null, + "name": "Barb-tail harpoon", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10130" + }, + { + "requirements": "{21,24}", + "ge_buy_limit": "100", + "examine": "Not so lucky for the rabbit.", + "grand_exchange_price": "789", + "durability": null, + "name": "Strung rabbit foot", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10132", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "789", + "durability": null, + "name": "Strung rabbit foot", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10133" + }, + { + "ge_buy_limit": "100", + "examine": "This could be put on a string and worn for luck.", + "grand_exchange_price": "543", + "durability": null, + "name": "Rabbit foot", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10134" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "543", + "durability": null, + "name": "Rabbit foot", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10135" + }, + { + "shop_price": "48", + "ge_buy_limit": "10000", + "examine": "Well, this would certainly add some colour to a meal.", + "grand_exchange_price": "99", + "durability": null, + "name": "Rainbow fish", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10136" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "99", + "durability": null, + "name": "Rainbow fish", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10137" + }, + { + "ge_buy_limit": "20000", + "examine": "A colourful fish, attracted to colourful flies.", + "grand_exchange_price": "236", + "durability": null, + "name": "Raw rainbow fish", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10138" + }, + { + "ge_buy_limit": "20000", + "grand_exchange_price": "236", + "durability": null, + "name": "Raw rainbow fish", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10139" + }, + { + "durability": null, + "name": "Burnt rainbow fish", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10141" + }, + { + "requirements": "{0,30}-{4,30}-{6,30}", + "ge_buy_limit": "10000", + "examine": "A thick, foul-smelling, tar-like substance with a green tinge", + "grand_exchange_price": "28", + "durability": null, + "name": "Guam tar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10142", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,16", + "equipment_slot": "13" + }, + { + "requirements": "{0,50}-{4,50}-{6,50}", + "ge_buy_limit": "10000", + "examine": "A thick, foul-smelling, tar-like substance with an orange tinge.", + "grand_exchange_price": "12", + "durability": null, + "name": "Marrentill tar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10143", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,22", + "equipment_slot": "13" + }, + { + "requirements": "{0,60}-{4,60}-{6,60}", + "ge_buy_limit": "10000", + "examine": "A thick, foul-smelling, tar-like substance with a red tinge.", + "grand_exchange_price": "28", + "durability": null, + "name": "Tarromin tar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10144", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,31", + "equipment_slot": "13" + }, + { + "requirements": "{0,70}-{4,70}-{6,70}", + "ge_buy_limit": "10000", + "examine": "A dark, thick, foul-smelling, tar-like substance.", + "grand_exchange_price": "47", + "durability": null, + "name": "Harralander tar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10145", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,49", + "equipment_slot": "13" + }, + { + "ge_buy_limit": "1000", + "turn90cw_anim": "5245", + "examine": "Slightly slimy, but kind of cute.", + "walk_anim": "5245", + "turn90ccw_anim": "5245", + "attack_speed": "5", + "two_handed": "true", + "turn180_anim": "5245", + "equipment_slot": "3", + "grand_exchange_price": "6", + "stand_anim": "5246", + "tradeable": "true", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "10146", + "stand_turn_anim": "823", + "bonuses": "0,19,0,0,29,0,0,0,0,0,0,31,0,0,0", + "requirements": "{0,50}-{4,50}-{6,50}", + "shop_price": "127", + "durability": null, + "destroy": "true", + "weight": "4", + "weapon_interface": "21", + "equip_audio": "732", + "render_anim": "1277", + "attack_audios": "740,735,736,0", + "name": "Orange salamander" + }, + { + "ge_buy_limit": "1000", + "turn90cw_anim": "5245", + "examine": "Slightly slimy but certainly striking.", + "walk_anim": "5245", + "turn90ccw_anim": "5245", + "attack_speed": "5", + "two_handed": "true", + "turn180_anim": "5245", + "equipment_slot": "3", + "grand_exchange_price": "27", + "stand_anim": "5246", + "tradeable": "true", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "10147", + "stand_turn_anim": "823", + "bonuses": "0,37,0,0,47,0,0,0,0,0,0,49,0,0,0", + "requirements": "{0,60}-{4,60}-{6,60}", + "shop_price": "190", + "durability": null, + "destroy": "true", + "weight": "4", + "weapon_interface": "21", + "equip_audio": "732", + "render_anim": "1277", + "attack_audios": "740,735,736,0", + "name": "Red salamander" + }, + { + "ge_buy_limit": "1000", + "turn90cw_anim": "5245", + "examine": "Slightly slimy and somewhat menacing.", + "walk_anim": "5245", + "turn90ccw_anim": "5245", + "attack_speed": "5", + "two_handed": "true", + "turn180_anim": "5245", + "equipment_slot": "3", + "grand_exchange_price": "124", + "stand_anim": "5246", + "tradeable": "true", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "10148", + "stand_turn_anim": "823", + "bonuses": "0,59,0,0,69,0,0,0,0,0,0,71,0,0,0", + "requirements": "{0,70}-{4,70}-{6,70}", + "durability": null, + "destroy": "true", + "weight": "4", + "weapon_interface": "21", + "equip_audio": "732", + "render_anim": "1277", + "attack_audios": "740,735,736,0", + "name": "Black salamander" + }, + { + "ge_buy_limit": "2000", + "turn90cw_anim": "5245", + "examine": "A very slimy and generally disgusting green lizard.", + "walk_anim": "5245", + "turn90ccw_anim": "5245", + "attack_speed": "5", + "two_handed": "true", + "turn180_anim": "5245", + "equipment_slot": "3", + "grand_exchange_price": "1802", + "stand_anim": "5246", + "tradeable": "true", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "10149", + "stand_turn_anim": "823", + "bonuses": "0,10,0,0,20,0,0,0,0,0,0,22,0,0,0", + "requirements": "{0,30}-{4,30}-{6,30}", + "durability": null, + "destroy": "true", + "weight": "4", + "weapon_interface": "21", + "equip_audio": "732", + "render_anim": "1277", + "attack_audios": "740,735,736,0", + "name": "Swamp lizard" + }, + { + "shop_price": "4", + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A noose on a stick.", + "walk_anim": "5250", + "durability": null, + "weight": "1.8", + "turn90ccw_anim": "1208", + "attack_speed": "4", + "two_handed": "true", + "weapon_interface": "14", + "turn180_anim": "5251", + "render_anim": "1279", + "equipment_slot": "3", + "grand_exchange_price": "1", + "stand_anim": "5254", + "name": "Noose wand", + "tradeable": "true", + "run_anim": "5253", + "archery_ticket_price": "0", + "id": "10150", + "stand_turn_anim": "5252" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1", + "durability": null, + "name": "Noose wand", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10151" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "821", + "examine": "A weapon made of bone and wood.", + "walk_anim": "4226", + "turn90ccw_anim": "822", + "attack_speed": "4", + "turn180_anim": "4227", + "equipment_slot": "3", + "grand_exchange_price": "2496", + "stand_anim": "4591", + "tradeable": "true", + "run_anim": "4228", + "archery_ticket_price": "0", + "id": "10156", + "stand_turn_anim": "823", + "bonuses": "0,0,0,0,55,0,0,0,0,0,0,0,0,0,0", + "requirements": "{4,50}", + "shop_price": "1300", + "durability": null, + "weight": "5", + "weapon_interface": "17", + "equip_audio": "2244", + "render_anim": "175", + "attack_audios": "2700,0,0,0", + "name": "Hunters' crossbow" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2496", + "durability": null, + "name": "Hunters' crossbow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10157" + }, + { + "requirements": "{4,50}", + "ge_buy_limit": "1000", + "examine": "Bolts made from the spikes of a prickly kebbit.", + "grand_exchange_price": "28", + "durability": null, + "name": "Kebbit bolts", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10158", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,28", + "equipment_slot": "13" + }, + { + "requirements": "{4,50}", + "ge_buy_limit": "1000", + "examine": "Bolts made from the spikes of a razor-backed kebbit.", + "grand_exchange_price": "352", + "durability": null, + "name": "Long kebbit bolts", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10159", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,38", + "equipment_slot": "13" + }, + { + "durability": null, + "name": "Orange salamander", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10160" + }, + { + "durability": null, + "name": "Red salamander", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10161" + }, + { + "durability": null, + "name": "Black salamander", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10162" + }, + { + "durability": null, + "name": "Swamp lizard", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10163" + }, + { + "examine": "Probably a bit too big for fly fishing.", + "durability": null, + "name": "Eagle feather", + "archery_ticket_price": "0", + "id": "10167" + }, + { + "examine": "A cape made from giant eagle feathers.", + "durability": null, + "name": "Eagle cape", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "10171", + "equipment_slot": "1" + }, + { + "examine": "A cheaply made fake beak.", + "durability": null, + "name": "Fake beak", + "archery_ticket_price": "0", + "id": "10172", + "equipment_slot": "0" + }, + { + "examine": "The title reads 'William Oddity's Guide to the Avian.", + "durability": null, + "name": "Bird book", + "archery_ticket_price": "0", + "id": "10173" + }, + { + "destroy_message": "You can obtain another metal feather from the camp", + "examine": "A small feather made out of some sort of metal. The detail is exquisite.", + "durability": null, + "name": "Metal feather", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10174" + }, + { + "destroy_message": "You can get another by inspecting the opening", + "examine": "An intricate feather crafted from a silver-coloured metal of some sort.", + "durability": null, + "name": "Silver feather", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10176" + }, + { + "destroy_message": "You can get another by taking from pedestal.", + "examine": "An intricate feather crafted from a bronze-coloured metal of some sort.", + "durability": null, + "name": "Bronze feather", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10177" + }, + { + "examine": "\"It looks like bird seed, but it's not quite right somehow.", + "durability": null, + "name": "Odd bird seed", + "archery_ticket_price": "0", + "id": "10178" + }, + { + "examine": "There's a feather glued to the front. \"Property of Arthur Artimus\".", + "durability": null, + "name": "Feathered journal", + "archery_ticket_price": "0", + "id": "10179" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10180" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10181" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10182" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10183" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10184" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10185" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10186" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10187" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10188" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10189" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10190" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10191" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10192" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10193" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10194" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10195" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10196" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10197" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10198" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10199" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10200" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10201" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10202" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10203" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10204" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10205" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10206" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10207" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10208" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10209" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10210" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10211" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10212" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10213" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10214" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10215" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10216" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10217" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10218" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10219" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10220" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10221" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10222" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10223" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10224" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10225" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10226" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10227" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10228" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10229" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10230" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10231" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10232" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10233" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10234" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10235" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10236" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10237" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10238" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10239" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10240" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10241" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10242" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10243" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10244" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10245" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10246" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10247" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10248" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10249" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10250" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10251" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10252" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10253" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10254" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10255" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10256" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10257" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10258" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10259" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10260" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10261" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10262" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10263" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10264" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10265" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10266" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10267" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10268" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10269" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10270" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10271" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10272" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10273" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10274" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10275" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10276" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10277" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10278" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10279" + }, + { + "ge_buy_limit": "2", + "turn90cw_anim": "1207", + "examine": "A powerful bow made from willow.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "turn180_anim": "1206", + "equipment_slot": "3", + "grand_exchange_price": "136", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "10280", + "stand_turn_anim": "1209", + "bonuses": "0,0,0,0,22,0,0,0,0,0,0,0,0,0,0", + "requirements": "{4,20}", + "durability": null, + "weight": "1.8", + "weapon_interface": "16", + "render_anim": "28", + "lendable": "true", + "attack_audios": "2700,0,0,0", + "name": "Willow comp bow" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "136", + "durability": null, + "name": "Willow comp bow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10281" + }, + { + "ge_buy_limit": "2", + "turn90cw_anim": "1207", + "examine": "A powerful bow made from yew wood.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "turn180_anim": "1206", + "equipment_slot": "3", + "grand_exchange_price": "876", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "10282", + "stand_turn_anim": "1209", + "bonuses": "0,0,0,0,49,0,0,0,0,0,0,0,0,0,0", + "requirements": "{4,40}", + "durability": null, + "weight": "1.8", + "weapon_interface": "16", + "render_anim": "28", + "lendable": "true", + "attack_audios": "2700,0,0,0", + "name": "Yew comp bow" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "876", + "durability": null, + "name": "Yew comp bow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10283" + }, + { + "ge_buy_limit": "2", + "turn90cw_anim": "1207", + "examine": "A powerful bow made from magic wood.", + "walk_anim": "1205", + "has_special": "true", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "turn180_anim": "1206", + "equipment_slot": "3", + "grand_exchange_price": "1268", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "10284", + "stand_turn_anim": "1209", + "bonuses": "0,0,0,0,71,0,0,0,0,0,0,0,0,0,0", + "requirements": "{4,50}", + "durability": null, + "weight": "1.3", + "weapon_interface": "16", + "render_anim": "28", + "lendable": "true", + "attack_audios": "2700,0,0,0", + "name": "Magic comp bow" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "1268", + "durability": null, + "name": "Magic comp bow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10285" + }, + { + "remove_head": "true", + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "A rune helmet with a heraldic design.", + "durability": null, + "absorb": "1,0,3", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "23600", + "name": "Rune helm (h1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10286", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "23600", + "durability": null, + "name": "Rune helm (h1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10287" + }, + { + "remove_head": "true", + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "A rune helmet with a heraldic design.", + "durability": null, + "weight": "3", + "absorb": "1,0,3", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "20800", + "name": "Rune helm (h2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10288", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "20800", + "durability": null, + "name": "Rune helm (h2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10289" + }, + { + "remove_head": "true", + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "A rune helmet with a heraldic design.", + "durability": null, + "weight": "4", + "absorb": "1,0,3", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "20800", + "name": "Rune helm (h3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10290", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "20800", + "durability": null, + "name": "Rune helm (h3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10291" + }, + { + "remove_head": "true", + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "A rune helmet with a heraldic design.", + "durability": null, + "weight": "2", + "absorb": "1,0,3", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "21100", + "name": "Rune helm (h4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10292", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "21100", + "durability": null, + "name": "Rune helm (h4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10293" + }, + { + "remove_head": "true", + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "A rune helmet with a heraldic design.", + "durability": null, + "weight": "2", + "absorb": "1,0,3", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "24900", + "name": "Rune helm (h5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10294", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "24900", + "durability": null, + "name": "Rune helm (h5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10295" + }, + { + "remove_head": "true", + "requirements": "{1,30}", + "ge_buy_limit": "2", + "examine": "An adamant helmet with a heraldic design.", + "durability": null, + "weight": "3", + "absorb": "1,0,2", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "31500", + "name": "Adamant helm (h1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10296", + "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,6,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "31500", + "durability": null, + "name": "Adamant helm (h1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10297" + }, + { + "remove_head": "true", + "requirements": "{1,30}", + "ge_buy_limit": "2", + "examine": "An adamant helmet with a heraldic design.", + "durability": null, + "weight": "3", + "absorb": "1,0,2", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "10100", + "name": "Adamant helm (h2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10298", + "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,6,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "10100", + "durability": null, + "name": "Adamant helm (h2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10299" + }, + { + "remove_head": "true", + "requirements": "{1,30}", + "ge_buy_limit": "2", + "examine": "An adamant helmet with a heraldic design.", + "durability": null, + "weight": "3", + "absorb": "1,0,2", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "8797", + "name": "Adamant helm (h3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10300", + "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,6,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "8797", + "durability": null, + "name": "Adamant helm (h3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10301" + }, + { + "remove_head": "true", + "requirements": "{1,30}", + "ge_buy_limit": "2", + "examine": "An Adamant helmet with a heraldic design.", + "durability": null, + "weight": "3", + "absorb": "1,0,2", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "10900", + "name": "Adamant helm (h4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10302", + "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,6,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "10900", + "durability": null, + "name": "Adamant helm (h4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10303" + }, + { + "remove_head": "true", + "requirements": "{1,30}", + "ge_buy_limit": "2", + "examine": "An adamant helmet with a heraldic design.", + "durability": null, + "weight": "3", + "absorb": "1,0,2", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "17100", + "name": "Adamant helm (h5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10304", + "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,6,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "17100", + "durability": null, + "name": "Adamant helm (h5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10305" + }, + { + "remove_head": "true", + "requirements": "{1,10}", + "ge_buy_limit": "2", + "examine": "A black helmet with a heraldic design.", + "durability": null, + "weight": "1.8", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "20400", + "name": "Black helm (h1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10306", + "bonuses": "0,0,0,-6,-2,12,13,10,-1,12,4,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "20400", + "durability": null, + "name": "Black helm (h1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10307" + }, + { + "remove_head": "true", + "requirements": "{1,10}", + "ge_buy_limit": "2", + "examine": "A black helmet with a heraldic design.", + "durability": null, + "weight": "1.8", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "7033", + "name": "Black helm (h2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10308", + "bonuses": "0,0,0,-6,-2,12,13,10,-1,12,4,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "7033", + "durability": null, + "name": "Black helm (h2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10309" + }, + { + "remove_head": "true", + "requirements": "{1,10}", + "ge_buy_limit": "2", + "examine": "A black helmet with a heraldic design.", + "durability": null, + "weight": "1.8", + "equip_audio": "2240", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "7574", + "name": "Black helm (h3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10310", + "bonuses": "0,0,0,-6,-2,12,13,10,-1,12,4,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "7574", + "durability": null, + "name": "Black helm (h3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10311" + }, + { + "remove_head": "true", + "requirements": "{1,10}", + "ge_buy_limit": "2", + "examine": "A black helmet with a heraldic design.", + "durability": null, + "weight": "1.8", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "10100", + "name": "Black helm (h4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10312", + "bonuses": "0,0,0,-6,-2,12,13,10,-1,12,4,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "10100", + "durability": null, + "name": "Black helm (h4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10313" + }, + { + "remove_head": "true", + "requirements": "{1,10}", + "ge_buy_limit": "2", + "examine": "A black helmet with a heraldic design.", + "durability": null, + "weight": "1.8", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "10400", + "name": "Black helm (h5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10314", + "bonuses": "0,0,0,-6,-2,12,13,10,-1,12,4,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "10400", + "durability": null, + "name": "Black helm (h5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10315" + }, + { + "remove_sleeves": "true", + "ge_buy_limit": "2", + "examine": "Bob says: 'Never give your password out to anyone.'", + "grand_exchange_price": "8196", + "durability": null, + "name": "Bob shirt", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "10316", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "8196", + "durability": null, + "name": "Bob shirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10317" + }, + { + "remove_sleeves": "true", + "ge_buy_limit": "2", + "examine": "Bob says: 'Always check the second trade screen.'", + "grand_exchange_price": "14700", + "durability": null, + "name": "Bob shirt", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "10318", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "14700", + "durability": null, + "name": "Bob shirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10319" + }, + { + "remove_sleeves": "true", + "ge_buy_limit": "2", + "examine": "Bob says: 'Never trade in the wilderness!'", + "grand_exchange_price": "8403", + "durability": null, + "name": "Bob shirt", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "10320", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "8403", + "durability": null, + "name": "Bob shirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10321" + }, + { + "remove_sleeves": "true", + "ge_buy_limit": "2", + "examine": "Bob says: 'A bank pin will keep your items secure.'", + "grand_exchange_price": "9230", + "durability": null, + "name": "Bob shirt", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "10322", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "9230", + "durability": null, + "name": "Bob shirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10323" + }, + { + "remove_sleeves": "true", + "ge_buy_limit": "2", + "examine": "Bob says: 'Keep your computer keylogger free and virus scanned.'", + "grand_exchange_price": "8197", + "durability": null, + "name": "Bob shirt", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "10324", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "8197", + "durability": null, + "name": "Bob shirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10325" + }, + { + "ge_buy_limit": "100", + "examine": "Makes firelighting a lot easier.", + "grand_exchange_price": "112", + "durability": null, + "name": "Purple firelighter", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10326" + }, + { + "ge_buy_limit": "100", + "examine": "Makes firelighting a lot easier.", + "grand_exchange_price": "167", + "durability": null, + "name": "White firelighter", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10327" + }, + { + "examine": "A number of chemical covered wooden logs.", + "durability": null, + "name": "White logs", + "archery_ticket_price": "0", + "id": "10328" + }, + { + "examine": "A number of chemical covered wooden logs.", + "durability": null, + "name": "Purple logs", + "archery_ticket_price": "0", + "id": "10329" + }, + { + "requirements": "{1,45}-{4,65}", + "ge_buy_limit": "2", + "examine": "Ancient range protection crafted from white dragonhide.", + "durability": null, + "weight": "4", + "absorb": "0,6,3", + "equipment_slot": "4", + "lendable": "true", + "remove_sleeves": "true", + "grand_exchange_price": "33900000", + "name": "3rd age range top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10330", + "bonuses": "0,0,0,-15,30,55,47,60,60,55,52,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "33900000", + "durability": null, + "name": "3rd age range top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10331" + }, + { + "requirements": "{1,45}-{4,65}", + "ge_buy_limit": "2", + "examine": "Fabulously ancient range protection crafted from white dragonhide.", + "durability": null, + "weight": "6", + "absorb": "0,4,2", + "equipment_slot": "7", + "lendable": "true", + "grand_exchange_price": "20800000", + "name": "3rd age range legs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10332", + "bonuses": "0,0,0,-10,17,31,25,33,30,31,25,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "20800000", + "durability": null, + "name": "3rd age range legs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10333" + }, + { + "remove_head": "true", + "requirements": "{1,45}-{4,65}", + "ge_buy_limit": "5000", + "examine": "Ancient range protection crafted from white dragonhide.", + "durability": null, + "weight": "1", + "absorb": "0,3,1", + "equip_audio": "2238", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "6100000", + "name": "3rd age range coif", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10334", + "bonuses": "0,0,0,-2,9,4,7,10,5,8,12,0,0,0,0" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "6100000", + "durability": null, + "name": "3rd age range coif", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10335" + }, + { + "requirements": "{1,45}-{4,65}", + "ge_buy_limit": "2", + "examine": "Fabulously ancient range protection crafted from white dragonhide.", + "durability": null, + "weight": "1", + "equip_audio": "2241", + "equipment_slot": "9", + "lendable": "true", + "grand_exchange_price": "7100000", + "name": "3rd age vambraces", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10336", + "bonuses": "0,0,0,-10,11,6,5,7,9,0,5,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "7100000", + "durability": null, + "name": "3rd age vambraces", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10337" + }, + { + "requirements": "{1,30}-{6,65}", + "ge_buy_limit": "2", + "examine": "Ancient mage protection enchanted in the Third-Age.", + "durability": null, + "weight": "2.5", + "absorb": "4,2,0", + "equipment_slot": "4", + "lendable": "true", + "remove_sleeves": "true", + "grand_exchange_price": "66500000", + "name": "3rd age robe top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10338", + "bonuses": "0,0,0,24,0,0,0,0,24,0,24,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "66500000", + "durability": null, + "name": "3rd age robe top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10339" + }, + { + "requirements": "{1,30}-{6,65}", + "ge_buy_limit": "2", + "examine": "Ancient mage protection enchanted in the Third-Age.", + "durability": null, + "weight": "1", + "absorb": "4,2,0", + "equipment_slot": "7", + "lendable": "true", + "grand_exchange_price": "31500000", + "name": "3rd age robe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10340", + "bonuses": "0,0,0,19,0,0,0,0,19,0,20,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "31500000", + "durability": null, + "name": "3rd age robe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10341" + }, + { + "remove_head": "true", + "requirements": "{1,30}-{6,65}", + "ge_buy_limit": "2", + "examine": "Ancient mage protection enchanted in the Third-Age.", + "durability": null, + "absorb": "2,1,0", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "21000000", + "name": "3rd age mage hat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10342", + "bonuses": "0,0,0,8,0,0,0,0,8,0,12,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "21000000", + "durability": null, + "name": "3rd age mage hat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10343" + }, + { + "lendable": "true", + "requirements": "{1,30}-{6,65}", + "ge_buy_limit": "2", + "examine": "Ancient mage protection enchanted in the Third-Age.", + "grand_exchange_price": "20100000", + "durability": null, + "name": "3rd age amulet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10344", + "bonuses": "0,0,0,15,0,0,0,0,10,0,0,0,0,0,0", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "20100000", + "durability": null, + "name": "3rd age amulet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10345" + }, + { + "requirements": "{1,65}", + "ge_buy_limit": "2", + "examine": "Ancient armour beaten from magical silver.", + "durability": null, + "weight": "2", + "absorb": "3,0,6", + "equip_audio": "2242", + "equipment_slot": "7", + "lendable": "true", + "grand_exchange_price": "92800000", + "name": "3rd age platelegs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10346", + "bonuses": "0,0,0,-25,-2,78,76,83,-5,75,25,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "92800000", + "durability": null, + "name": "3rd age platelegs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10347" + }, + { + "requirements": "{1,65}", + "ge_buy_limit": "2", + "examine": "Ancient armour beaten from magical silver.", + "durability": null, + "weight": "9", + "absorb": "4,0,9", + "equip_audio": "2234", + "equipment_slot": "4", + "lendable": "true", + "remove_sleeves": "true", + "grand_exchange_price": "86200000", + "name": "3rd age platebody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10348", + "bonuses": "0,0,0,-20,0,96,108,113,-4,97,52,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "86200000", + "durability": null, + "name": "3rd age platebody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10349" + }, + { + "remove_head": "true", + "requirements": "{1,65}", + "ge_buy_limit": "2", + "examine": "Ancient armour beaten from magical silver.", + "durability": null, + "weight": "1", + "absorb": "2,0,4", + "equip_audio": "2240", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "41600000", + "name": "3rd age full helmet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10350", + "bonuses": "0,0,0,-5,-2,47,49,43,-3,48,12,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "41600000", + "durability": null, + "name": "3rd age full helmet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10351" + }, + { + "requirements": "{1,65}", + "ge_buy_limit": "2", + "examine": "Ancient armour beaten from magical silver.", + "durability": null, + "weight": "2", + "absorb": "5,0,11", + "equip_audio": "2245", + "equipment_slot": "5", + "lendable": "true", + "grand_exchange_price": "65100000", + "name": "3rd age kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10352", + "bonuses": "0,0,0,-10,-4,63,65,61,-3,63,60,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "65100000", + "durability": null, + "name": "3rd age kiteshield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10353" + }, + { + "ge_buy_limit": "100", + "examine": "A dragonstone amulet with 4 magic charges.", + "grand_exchange_price": "233100", + "durability": null, + "name": "Amulet of glory(t4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10354", + "bonuses": "10,10,10,10,10,3,3,3,3,3,3,6,3,0,0", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "233100", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Amulet of glory(t4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10355" + }, + { + "examine": "A dragonstone amulet with 3 magic charges.", + "grand_exchange_price": "1", + "durability": null, + "name": "Amulet of glory(t3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10356", + "bonuses": "10,10,10,10,10,3,3,3,3,3,3,6,3,0,0", + "equipment_slot": "2" + }, + { + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Amulet of glory(t3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10357" + }, + { + "examine": "A dragonstone amulet with 2 magic charges.", + "grand_exchange_price": "1", + "durability": null, + "name": "Amulet of glory(t2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10358", + "bonuses": "10,10,10,10,10,3,3,3,3,3,3,6,3,0,0", + "equipment_slot": "2" + }, + { + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Amulet of glory(t2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10359" + }, + { + "examine": "A dragonstone amulet with 1 magic charge.", + "grand_exchange_price": "1", + "durability": null, + "name": "Amulet of glory(t1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10360", + "bonuses": "10,10,10,10,10,3,3,3,3,3,3,6,3,0,0", + "equipment_slot": "2" + }, + { + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Amulet of glory(t1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10361" + }, + { + "ge_buy_limit": "100", + "examine": "A very powerful dragonstone amulet with a nice trim.", + "grand_exchange_price": "223000", + "durability": null, + "name": "Amulet of glory(t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10362", + "bonuses": "10,10,10,10,10,3,3,3,3,3,3,6,3,0,0", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "223000", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Amulet of glory(t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10363" + }, + { + "ge_buy_limit": "2", + "examine": "An enchanted ruby amulet with a nice trim.", + "grand_exchange_price": "819400", + "durability": null, + "name": "Strength amulet(t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10364", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,10,0,0,0", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "819400", + "durability": null, + "name": "Strength amulet(t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10365" + }, + { + "ge_buy_limit": "5000", + "examine": "An enchanted sapphire amulet of magic.", + "grand_exchange_price": "128700", + "durability": null, + "name": "Amulet of magic(t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10366", + "bonuses": "0,0,0,10,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "128700", + "durability": null, + "name": "Amulet of magic(t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10367" + }, + { + "requirements": "{1,40}-{4,70}", + "ge_buy_limit": "2", + "examine": "Zamorak blessed dragonhide vambraces.", + "durability": null, + "weight": "1", + "equip_audio": "2241", + "equipment_slot": "9", + "grand_exchange_price": "116200", + "name": "Zamorak bracers", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10368", + "bonuses": "0,0,0,-10,11,6,5,7,8,0,6,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "116200", + "durability": null, + "name": "Zamorak bracers", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10369" + }, + { + "requirements": "{1,40}-{4,70}", + "ge_buy_limit": "2", + "examine": "Zamorak blessed dragonhide body armour.", + "durability": null, + "weight": "6", + "absorb": "0,6,3", + "equip_audio": "2241", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "155200", + "name": "Zamorak d'hide", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10370", + "bonuses": "0,0,0,-15,30,55,47,60,50,55,55,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "155200", + "durability": null, + "name": "Zamorak d'hide", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10371" + }, + { + "requirements": "{1,40}-{4,70}", + "ge_buy_limit": "2", + "examine": "Zamorak blessed dragonhide chaps.", + "durability": null, + "weight": "5", + "absorb": "0,4,2", + "equip_audio": "2241", + "equipment_slot": "7", + "grand_exchange_price": "35100", + "name": "Zamorak chaps", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10372", + "bonuses": "0,0,0,-10,17,31,25,33,28,31,30,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "35100", + "durability": null, + "name": "Zamorak chaps", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10373" + }, + { + "remove_head": "true", + "requirements": "{1,40}-{4,70}", + "ge_buy_limit": "2", + "examine": "Zamorak blessed dragonhide coif.", + "durability": null, + "absorb": "0,3,1", + "equip_audio": "2238", + "equipment_slot": "0", + "grand_exchange_price": "35900", + "name": "Zamorak coif", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10374", + "bonuses": "0,0,0,-1,7,4,7,10,4,8,8,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "35900", + "durability": null, + "name": "Zamorak coif", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10375" + }, + { + "requirements": "{1,40}-{4,70}", + "ge_buy_limit": "2", + "examine": "Guthix blessed dragonhide vambraces.", + "durability": null, + "weight": "1", + "equip_audio": "2241", + "equipment_slot": "9", + "grand_exchange_price": "3181", + "name": "Guthix bracers", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10376", + "bonuses": "0,0,0,-10,11,6,5,7,8,0,6,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "3181", + "durability": null, + "name": "Guthix bracers", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10377" + }, + { + "requirements": "{1,40}-{4,70}", + "shop_price": "13", + "ge_buy_limit": "2", + "examine": "Guthix blessed dragonhide body armour.", + "durability": null, + "weight": "6", + "absorb": "0,6,3", + "equip_audio": "2241", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "39800", + "name": "Guthix dragonhide", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10378", + "bonuses": "0,0,0,-15,30,55,47,60,50,55,55,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "39800", + "durability": null, + "name": "Guthix dragonhide", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10379" + }, + { + "requirements": "{1,40}-{4,70}", + "ge_buy_limit": "2", + "examine": "Guthix blessed dragonhide chaps.", + "durability": null, + "weight": "5", + "absorb": "0,4,2", + "equip_audio": "2241", + "equipment_slot": "7", + "grand_exchange_price": "7346", + "name": "Guthix chaps", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10380", + "bonuses": "0,0,0,-10,17,31,25,33,28,31,30,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "7346", + "durability": null, + "name": "Guthix chaps", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10381" + }, + { + "remove_head": "true", + "requirements": "{1,40}-{4,70}", + "ge_buy_limit": "2", + "examine": "Guthix blessed dragonhide coif.", + "durability": null, + "weight": "0.85", + "absorb": "0,3,1", + "equip_audio": "2238", + "equipment_slot": "0", + "grand_exchange_price": "27500", + "name": "Guthix coif", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10382", + "bonuses": "0,0,0,-1,7,4,7,10,4,8,8,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "27500", + "durability": null, + "name": "Guthix coif", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10383" + }, + { + "requirements": "{1,70}-{4,40}", + "ge_buy_limit": "2", + "examine": "Saradomin blessed dragonhide vambraces.", + "durability": null, + "weight": "1", + "equip_audio": "2241", + "equipment_slot": "9", + "grand_exchange_price": "70800", + "name": "Saradomin bracers", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10384", + "bonuses": "0,0,0,-10,11,6,5,7,8,0,6,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "70800", + "durability": null, + "name": "Saradomin bracers", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10385" + }, + { + "requirements": "{1,40}-{4,70}", + "shop_price": "13000", + "ge_buy_limit": "2", + "examine": "Saradomin blessed dragonhide body armour.", + "durability": null, + "destroy": "true", + "weight": "6", + "absorb": "0,6,3", + "equip_audio": "2241", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "164100", + "name": "Saradomin d'hide", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10386", + "bonuses": "0,0,0,-15,30,55,47,60,50,55,55,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "164100", + "durability": null, + "name": "Saradomin d'hide", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10387" + }, + { + "requirements": "{1,40}-{4,70}", + "ge_buy_limit": "2", + "examine": "Saradomin blessed dragonhide chaps.", + "durability": null, + "absorb": "0,4,2", + "equip_audio": "2241", + "equipment_slot": "7", + "grand_exchange_price": "36600", + "name": "Saradomin chaps", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10388", + "bonuses": "0,0,0,-10,17,31,25,33,28,31,30,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "36600", + "durability": null, + "name": "Saradomin chaps", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10389" + }, + { + "remove_head": "true", + "requirements": "{1,40}-{4,70}", + "ge_buy_limit": "2", + "examine": "Saradomin blessed dragonhide coif.", + "durability": null, + "absorb": "0,3,1", + "equip_audio": "2238", + "equipment_slot": "0", + "grand_exchange_price": "28000", + "name": "Saradomin coif", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10390", + "bonuses": "0,0,0,-1,7,4,7,10,4,8,8,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "28000", + "durability": null, + "name": "Saradomin coif", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10391" + }, + { + "remove_head": "true", + "lendable": "true", + "ge_buy_limit": "2", + "examine": "A big 'do about nothing.", + "grand_exchange_price": "45400", + "durability": null, + "name": "A powdered wig", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "10392", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "45400", + "durability": null, + "name": "A powdered wig", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10393" + }, + { + "lendable": "true", + "ge_buy_limit": "2", + "examine": "These'll help me stay alive.", + "grand_exchange_price": "448900", + "durability": null, + "name": "Flared trousers", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10394", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "448900", + "durability": null, + "name": "Flared trousers", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10395" + }, + { + "lendable": "true", + "ge_buy_limit": "2", + "examine": "Alas, someone has slashed my pantaloons.", + "grand_exchange_price": "9863", + "durability": null, + "name": "Pantaloons", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10396", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "9863", + "durability": null, + "name": "Pantaloons", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10397" + }, + { + "remove_head": "true", + "lendable": "true", + "ge_buy_limit": "2", + "examine": "A cap for wearing whil...zzzzzzzzz", + "grand_exchange_price": "276400", + "durability": null, + "name": "Sleeping cap", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "10398", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "276400", + "durability": null, + "name": "Sleeping cap", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10399" + }, + { + "remove_sleeves": "true", + "ge_buy_limit": "2", + "examine": "A well made elegant mans' black shirt.", + "grand_exchange_price": "921500", + "durability": null, + "name": "Black ele' shirt", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10400", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "921500", + "durability": null, + "name": "Black ele' shirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10401" + }, + { + "ge_buy_limit": "2", + "examine": "A rather elegant black pair of pantaloons.", + "grand_exchange_price": "270700", + "durability": null, + "name": "Black ele' legs", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10402", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "270700", + "durability": null, + "name": "Black ele' legs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10403" + }, + { + "remove_sleeves": "true", + "ge_buy_limit": "2", + "examine": "A well made elegant men's red shirt.", + "grand_exchange_price": "118600", + "durability": null, + "name": "Red ele' shirt", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10404", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "118600", + "durability": null, + "name": "Red ele' shirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10405" + }, + { + "ge_buy_limit": "2", + "examine": "A rather elegant red pair of pantaloons.", + "grand_exchange_price": "39400", + "durability": null, + "name": "Red ele' legs", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10406", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "39400", + "durability": null, + "name": "Red ele' legs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10407" + }, + { + "remove_sleeves": "true", + "ge_buy_limit": "2", + "examine": "A well made elegant mans' blue shirt.", + "grand_exchange_price": "134700", + "durability": null, + "name": "Blue ele' shirt", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10408", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "134700", + "durability": null, + "name": "Blue ele' shirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10409" + }, + { + "ge_buy_limit": "2", + "examine": "A rather elegant pair of men's blue pantaloons", + "grand_exchange_price": "80700", + "durability": null, + "name": "Blue ele' legs", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10410", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "80700", + "durability": null, + "name": "Blue ele' legs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10411" + }, + { + "remove_sleeves": "true", + "ge_buy_limit": "2", + "examine": "A well made elegant men's green shirt.", + "grand_exchange_price": "162600", + "durability": null, + "name": "Green ele' shirt", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10412", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "162600", + "durability": null, + "name": "Green ele' shirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10413" + }, + { + "ge_buy_limit": "2", + "examine": "A rather elegant green pair of men's pantaloons.", + "grand_exchange_price": "36100", + "durability": null, + "name": "Green ele' legs", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10414", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "36100", + "durability": null, + "name": "Green ele' legs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10415" + }, + { + "remove_sleeves": "true", + "ge_buy_limit": "2", + "examine": "A well made elegant men's purple shirt.", + "grand_exchange_price": "116200", + "durability": null, + "name": "Purple ele' shirt", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10416", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "116200", + "durability": null, + "name": "Purple ele' shirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10417" + }, + { + "ge_buy_limit": "2", + "examine": "A rather elegant purple pair of pantaloons.", + "grand_exchange_price": "73400", + "durability": null, + "name": "Purple ele' legs", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10418", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "73400", + "durability": null, + "name": "Purple ele' legs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10419" + }, + { + "remove_sleeves": "true", + "ge_buy_limit": "2", + "examine": "A well made ladies' elegant white blouse.", + "grand_exchange_price": "571500", + "durability": null, + "name": "White ele' blouse", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10420", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "571500", + "durability": null, + "name": "White ele' blouse", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10421" + }, + { + "ge_buy_limit": "2", + "examine": "A rather elegant white skirt.", + "grand_exchange_price": "56600", + "durability": null, + "name": "White ele' skirt", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10422", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "56600", + "durability": null, + "name": "White ele' skirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10423" + }, + { + "remove_sleeves": "true", + "ge_buy_limit": "2", + "examine": "A well made elegant ladies' red blouse.", + "grand_exchange_price": "15000", + "durability": null, + "name": "Red ele' blouse", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10424", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "15000", + "durability": null, + "name": "Red ele' blouse", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10425" + }, + { + "ge_buy_limit": "2", + "examine": "A rather elegant Red skirt.", + "grand_exchange_price": "7132", + "durability": null, + "name": "Red ele' skirt", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10426", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "7132", + "durability": null, + "name": "Red ele' skirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10427" + }, + { + "remove_sleeves": "true", + "ge_buy_limit": "2", + "examine": "A well made ladies' elegant blue blouse.", + "grand_exchange_price": "22200", + "durability": null, + "name": "Blue ele' blouse", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10428", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "22200", + "durability": null, + "name": "Blue ele' blouse", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10429" + }, + { + "ge_buy_limit": "2", + "examine": "A rather elegant blue skirt.", + "grand_exchange_price": "12200", + "durability": null, + "name": "Blue ele' skirt", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10430", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "12200", + "durability": null, + "name": "Blue ele' skirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10431" + }, + { + "remove_sleeves": "true", + "ge_buy_limit": "2", + "examine": "A well made ladies' elegant green blouse.", + "grand_exchange_price": "12300", + "durability": null, + "name": "Green ele' blouse", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10432", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "12300", + "durability": null, + "name": "Green ele' blouse", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10433" + }, + { + "ge_buy_limit": "2", + "examine": "A rather elegant green skirt.", + "grand_exchange_price": "10300", + "durability": null, + "name": "Green ele' skirt", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10434", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "10300", + "durability": null, + "name": "Green ele' skirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10435" + }, + { + "remove_sleeves": "true", + "ge_buy_limit": "2", + "examine": "A well made elegant ladies' purple blouse.", + "grand_exchange_price": "22800", + "durability": null, + "name": "Purple ele' blouse", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10436", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "22800", + "durability": null, + "name": "Purple ele' blouse", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10437" + }, + { + "ge_buy_limit": "2", + "examine": "A rather elegant purple skirt.", + "grand_exchange_price": "16700", + "durability": null, + "name": "Purple ele' skirt", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10438", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "16700", + "durability": null, + "name": "Purple ele' skirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10439" + }, + { + "ge_buy_limit": "2", + "turn90cw_anim": "1207", + "examine": "A Saradomin crozier.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "turn180_anim": "1206", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "grand_exchange_price": "8611", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "10440", + "stand_turn_anim": "1209", + "bonuses": "7,-1,25,10,0,2,3,1,10,0,0,32,6,0,0", + "requirements": "{5,60}", + "durability": null, + "weight": "2", + "weapon_interface": "1", + "render_anim": "28", + "attack_audios": "2555,0,0,0", + "name": "Saradomin crozier" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "8611", + "durability": null, + "name": "Saradomin crozier", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10441" + }, + { + "ge_buy_limit": "2", + "turn90cw_anim": "1207", + "examine": "A Guthix crozier.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "turn180_anim": "1206", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "grand_exchange_price": "2925", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "10442", + "stand_turn_anim": "1209", + "bonuses": "7,-1,25,10,0,2,3,1,10,0,0,32,6,0,0", + "requirements": "{5,60}", + "durability": null, + "weight": "2", + "weapon_interface": "1", + "render_anim": "28", + "attack_audios": "2555,0,0,0", + "name": "Guthix crozier" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "2925", + "durability": null, + "name": "Guthix crozier", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10443" + }, + { + "ge_buy_limit": "2", + "turn90cw_anim": "1207", + "examine": "A Zamorak crozier.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "turn180_anim": "1206", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "grand_exchange_price": "2794", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "10444", + "stand_turn_anim": "1209", + "bonuses": "7,-1,25,10,0,2,3,1,10,0,0,32,6,0,0", + "requirements": "{5,60}", + "durability": null, + "weight": "2", + "weapon_interface": "1", + "render_anim": "28", + "attack_audios": "2555,0,0,0", + "name": "Zamorak crozier" + }, + { + "attack_anims": "", + "ge_buy_limit": "2", + "grand_exchange_price": "2794", + "durability": null, + "name": "Zamorak crozier", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10445" + }, + { + "requirements": "{5,40}", + "ge_buy_limit": "2", + "examine": "A Saradomin cloak.", + "grand_exchange_price": "1200000", + "durability": null, + "name": "Saradomin cloak", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10446", + "bonuses": "0,0,0,1,0,3,3,3,3,3,3,0,3,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "1200000", + "durability": null, + "name": "Saradomin cloak", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10447" + }, + { + "requirements": "{5,40}", + "ge_buy_limit": "2", + "examine": "A Guthix cloak.", + "grand_exchange_price": "391000", + "durability": null, + "name": "Guthix cloak", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10448", + "bonuses": "0,0,0,1,0,3,3,3,3,3,3,0,3,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "391000", + "durability": null, + "name": "Guthix cloak", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10449" + }, + { + "requirements": "{5,40}", + "ge_buy_limit": "2", + "examine": "A Zamorak cloak.", + "grand_exchange_price": "1000000", + "durability": null, + "name": "Zamorak cloak", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10450", + "bonuses": "0,0,0,1,0,3,3,3,3,3,3,0,3,0,0", + "equipment_slot": "1" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "1000000", + "durability": null, + "name": "Zamorak cloak", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10451" + }, + { + "remove_head": "true", + "requirements": "{5,40}-{6,40}", + "ge_buy_limit": "2", + "examine": "A Saradomin mitre.", + "grand_exchange_price": "299200", + "durability": null, + "name": "Saradomin mitre", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10452", + "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,5,0,0", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "299200", + "durability": null, + "name": "Saradomin mitre", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10453" + }, + { + "remove_head": "true", + "requirements": "{5,40}-{6,40}", + "ge_buy_limit": "2", + "examine": "A Guthix mitre.", + "grand_exchange_price": "130300", + "durability": null, + "name": "Guthix mitre", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10454", + "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,5,0,0", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "130300", + "durability": null, + "name": "Guthix mitre", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10455" + }, + { + "remove_head": "true", + "requirements": "{5,40}-{6,40}", + "ge_buy_limit": "2", + "examine": "A Zamorak mitre.", + "durability": null, + "weight": "0.3", + "equipment_slot": "0", + "grand_exchange_price": "346500", + "name": "Zamorak mitre", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10456", + "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,5,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "346500", + "durability": null, + "name": "Zamorak mitre", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10457" + }, + { + "requirements": "{5,20}", + "remove_sleeves": "true", + "ge_buy_limit": "2", + "examine": "Blessed vestments of Saradomin.", + "grand_exchange_price": "121400", + "durability": null, + "name": "Saradomin robe top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10458", + "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,4,0,0", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "121400", + "durability": null, + "name": "Saradomin robe top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10459" + }, + { + "requirements": "{5,20}", + "ge_buy_limit": "2", + "examine": "Zamorak Vestments.", + "durability": null, + "weight": "1", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "154700", + "name": "Zamorak robe top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10460", + "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,4,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "154700", + "durability": null, + "name": "Zamorak robe top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10461" + }, + { + "requirements": "{5,20}", + "ge_buy_limit": "2", + "examine": "Blessed vestments of Guthix.", + "durability": null, + "weight": "1", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "75200", + "name": "Guthix robe top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10462", + "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,4,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "75200", + "durability": null, + "name": "Guthix robe top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10463" + }, + { + "requirements": "{5,20}", + "ge_buy_limit": "2", + "examine": "Leggings from the Saradomin Vestments.", + "grand_exchange_price": "56300", + "durability": null, + "name": "Saradomin robe legs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10464", + "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,4,0,0", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "56300", + "durability": null, + "name": "Saradomin robe legs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10465" + }, + { + "requirements": "{5,20}", + "ge_buy_limit": "2", + "examine": "Leggings from the Guthix Vestments.", + "grand_exchange_price": "56900", + "durability": null, + "name": "Guthix robe legs", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "10466", + "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,4,0,0", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "56900", + "durability": null, + "name": "Guthix robe legs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10467" + }, + { + "requirements": "{5,20}", + "ge_buy_limit": "2", + "examine": "Legs of the Zamorak Vestments.", + "grand_exchange_price": "79400", + "durability": null, + "name": "Zamorak robe legs", + "tradeable": "true", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "10468", + "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,4,0,0", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "79400", + "durability": null, + "name": "Zamorak robe legs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10469" + }, + { + "requirements": "{5,60}", + "ge_buy_limit": "2", + "examine": "A Saradomin stole.", + "grand_exchange_price": "14000", + "durability": null, + "name": "Saradomin stole", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10470", + "bonuses": "0,0,0,2,0,0,0,0,2,0,0,0,10,0,0", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "14000", + "durability": null, + "name": "Saradomin stole", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10471" + }, + { + "requirements": "{5,60}", + "ge_buy_limit": "2", + "examine": "A blessed stole.", + "grand_exchange_price": "3849", + "durability": null, + "name": "Guthix stole", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10472", + "bonuses": "0,0,0,2,0,0,0,0,2,0,0,0,10,0,0", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "3849", + "durability": null, + "name": "Guthix stole", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10473" + }, + { + "requirements": "{5,60}", + "ge_buy_limit": "2", + "examine": "A Zamorak stole.", + "grand_exchange_price": "13700", + "durability": null, + "name": "Zamorak stole", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10474", + "bonuses": "0,0,0,2,0,0,0,0,2,0,0,0,10,0,0", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "13700", + "durability": null, + "name": "Zamorak stole", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10475" + }, + { + "ge_buy_limit": "1000", + "examine": "Remember to brush after eating!", + "grand_exchange_price": "22700", + "durability": null, + "name": "Purple sweets", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10476" + }, + { + "durability": null, + "name": "Scroll", + "archery_ticket_price": "0", + "id": "10485", + "equipment_slot": "3" + }, + { + "shop_price": "1", + "examine": "An empty sack.", + "grand_exchange_price": "30", + "durability": null, + "name": "Empty sack", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10486" + }, + { + "turn90cw_anim": "821", + "examine": "Yup, definitely a chicken...an undead chicken.", + "walk_anim": "5364", + "durability": null, + "turn90ccw_anim": "822", + "weapon_interface": "12", + "turn180_anim": "5438", + "equip_audio": "3277", + "render_anim": "1171", + "equipment_slot": "3", + "stand_anim": "5363", + "name": "Undead chicken", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "10487", + "stand_turn_anim": "823", + "bonuses": "-100,-100,-50,0,0,0,0,0,0,0,0,-10,0,0,0" + }, + { + "destroy_message": "The Witch in Draynor supplies these bars.", + "examine": "An iron bar supplied by an insane old crone.", + "durability": null, + "name": "Selected iron", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10488", + "equipment_slot": "3" + }, + { + "destroy_message": "I can make another magnet using special bars. The Witch in Draynor supplies these bars.", + "examine": "A magnet designed for undead chicken use.", + "durability": null, + "name": "Bar magnet", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10489" + }, + { + "destroy_message": "I can chop more wood from undead trees using my blessed axe.", + "examine": "Were they trying to escape just then?", + "durability": null, + "name": "Undead twigs", + "tradeable": "false", + "destroy": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10490" + }, + { + "examine": "It radiates purity but can still lop off heads.", + "durability": null, + "destroy": "true", + "weight": "1.1", + "attack_speed": "5", + "weapon_interface": "2", + "render_anim": "2586", + "equipment_slot": "3", + "destroy_message": "I can obtain a replacement axe from the Burthorpe Slayer Master.", + "name": "Blessed axe", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10491", + "bonuses": "-2,12,10,0,0,0,1,0,0,0,0,13,2,0,0" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "These make no sense at all.", + "durability": null, + "name": "Research notes", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10492" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "They still make no sense, but look more meaningful now.", + "durability": null, + "name": "Translated notes", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10493" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Attach tab A to button B then fold along line C...", + "durability": null, + "name": "A pattern", + "archery_ticket_price": "0", + "id": "10494" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A desirable residence for discerning, undead chickens.", + "durability": null, + "name": "A container", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10495" + }, + { + "examine": "Shiny!", + "durability": null, + "name": "Polished buttons", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10496" + }, + { + "shop_price": "999", + "examine": "A bagged chicken ready to serve you, magnet in claw.", + "durability": null, + "destroy": "true", + "weight": "4.5", + "equip_audio": "3284", + "equipment_slot": "1", + "destroy_message": "I can buy a replacement from Ava in Draynor Manor; she will charge me 999 coins for this service.", + "name": "Ava's attractor", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10498", + "bonuses": "0,0,0,0,2,0,0,0,2,0,0,0,0,0,0" + }, + { + "shop_price": "999", + "examine": "A superior bagged chicken ready to serve you, magnet in claw.", + "durability": null, + "destroy": "true", + "weight": "4.5", + "equip_audio": "3284", + "equipment_slot": "1", + "destroy_message": "I can obtain a replacement for this from Ava in Draynor Manor. She will need 999 coins to buy the lower", + "name": "Ava's accumulator", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10499", + "bonuses": "0,0,0,0,4,0,1,0,4,0,0,0,0,0,0" + }, + { + "destroy_message": "I can obtain a replacement for this from the crone who lives west of the Port Phasmatys farm.", + "examine": "Allows the ghost farmer to talk to Alice - a breakthrough!", + "durability": null, + "name": "Crone-made amulet", + "tradeable": "false", + "destroy": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "10500", + "equipment_slot": "2" + }, + { + "examine": "Made from snow. / It's a ball of snow! Uncanny. / How did this not melt in the box?", + "durability": null, + "name": "Snowball", + "archery_ticket_price": "0", + "id": "10501", + "weapon_interface": "18", + "bonuses": "0,0,0,0,10,0,0,0,0,0,0,0,0,0,1", + "equipment_slot": "3" + }, + { + "examine": "A gublinch frozen and crumbled into shards.", + "durability": null, + "name": "Gublinch shards", + "tradeable": "false", + "destroy": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "10506" + }, + { + "remove_head": "true", + "destroy_message": "You can reclaim this item from the place you found it. this item", + "examine": "A reindeer hat and a matching flashing nose.", + "durability": null, + "name": "Reindeer hat", + "tradeable": "false", + "destroy": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "10507", + "equipment_slot": "0" + }, + { + "destroy_message": "You can get another from Diango in Draynor Village.", + "examine": "A wintumber tree for your player-owned house.", + "durability": null, + "name": "Wintumber tree", + "tradeable": "false", + "destroy": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "10508" + }, + { + "examine": "Made from snow. / It's a ball of snow! Uncanny. / How did this not melt in the box?", + "durability": null, + "name": "Snowball", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10509" + }, + { + "durability": null, + "name": "Snowball", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10510" + }, + { + "examine": "They're going to sing to you!", + "durability": null, + "name": "Zanaris choir", + "archery_ticket_price": "0", + "id": "10511" + }, + { + "destroy_message": "Unknown You can reclaim this item from the place you found it.", + "examine": "Some dry crackers.", + "durability": null, + "name": "Crackers", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10513" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A block of tofu.", + "durability": null, + "name": "Tofu", + "archery_ticket_price": "0", + "id": "10514" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Some meaty worms.", + "durability": null, + "name": "Worms", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10515" + }, + { + "examine": "A horn to call others.", + "durability": null, + "name": "Attacker horn", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10516" + }, + { + "examine": "A horn to call others.", + "durability": null, + "name": "Attacker horn", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10517" + }, + { + "examine": "A horn to call others.", + "durability": null, + "name": "Attacker horn", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10518" + }, + { + "examine": "A horn to call others.", + "durability": null, + "name": "Attacker horn", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10519" + }, + { + "examine": "A horn to call others.", + "durability": null, + "name": "Attacker horn", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10520" + }, + { + "examine": "A very small/small/medium-sized/large/very large collection bag.", + "durability": null, + "name": "Collection bag", + "archery_ticket_price": "0", + "id": "10521" + }, + { + "examine": "A very small/small/medium-sized/large/very large collection bag.", + "durability": null, + "name": "Collection bag", + "archery_ticket_price": "0", + "id": "10522" + }, + { + "examine": "A very small/small/medium-sized/large/very large collection bag.", + "durability": null, + "name": "Collection bag", + "archery_ticket_price": "0", + "id": "10523" + }, + { + "examine": "A very small/small/medium-sized/large/very large collection bag.", + "durability": null, + "name": "Collection bag", + "archery_ticket_price": "0", + "id": "10524" + }, + { + "examine": "A very small/small/medium-sized/large/very large collection bag.", + "durability": null, + "name": "Collection bag", + "archery_ticket_price": "0", + "id": "10525" + }, + { + "examine": "A horn to call others.", + "durability": null, + "name": "Healer horn", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10526" + }, + { + "examine": "A horn to call others.", + "durability": null, + "name": "Healer horn", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10527" + }, + { + "examine": "A horn to call others.", + "durability": null, + "name": "Healer horn", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10528" + }, + { + "examine": "A horn to call others.", + "durability": null, + "name": "Healer horn", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10529" + }, + { + "examine": "A horn to call others.", + "durability": null, + "name": "Healer horn", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10530" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Used to poison your enemies!", + "durability": null, + "name": "Green egg", + "archery_ticket_price": "0", + "id": "10531" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Will explode when fired.", + "durability": null, + "name": "Red egg", + "archery_ticket_price": "0", + "id": "10532" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Stun your foes!", + "durability": null, + "name": "Blue egg", + "archery_ticket_price": "0", + "id": "10533" + }, + { + "examine": "A yellow egg; it needs passing to the Healer to be poisoned!", + "durability": null, + "name": "Yellow egg", + "archery_ticket_price": "0", + "id": "10534" + }, + { + "examine": "A poisoned yellow egg; pass it to the Attacker for spikes to be added!", + "durability": null, + "name": "Poisoned egg", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10535" + }, + { + "examine": "A poisoned, spiky egg; pass to the defender for heating!", + "durability": null, + "name": "Spiked/pois. egg", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10536" + }, + { + "examine": "A heated, poisoned, spiky egg; pass to the Collector for loading.", + "durability": null, + "name": "Omega egg", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10537" + }, + { + "examine": "A horn to call others.", + "durability": null, + "name": "Defender horn", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10538" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Some poisoned tofu.", + "durability": null, + "name": "Poisoned tofu", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10539" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Some poisoned worms.", + "durability": null, + "name": "Poisoned worms", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10540" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A poisoned leg of meat.", + "durability": null, + "name": "Poisoned meat", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10541" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "name": "Healing vial(4)", + "archery_ticket_price": "0", + "id": "10542" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "name": "Healing vial(3)", + "archery_ticket_price": "0", + "id": "10543" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "name": "Healing vial(2)", + "archery_ticket_price": "0", + "id": "10544" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "durability": null, + "name": "Healing vial(1)", + "archery_ticket_price": "0", + "id": "10545" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A full healing vial.", + "durability": null, + "name": "Healing vial", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10546" + }, + { + "remove_head": "true", + "requirements": "{1,40}", + "shop_price": "275", + "examine": "A Penance Healer hat.", + "durability": null, + "name": "Healer hat", + "weight": "2", + "archery_ticket_price": "0", + "id": "10547", + "absorb": "3,1,0", + "bonuses": "-5,-5,-5,7,-5,6,8,10,8,0,7,0,0,0,0", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "requirements": "{1,40}", + "shop_price": "275", + "examine": "A Penance Fighter hat.", + "durability": null, + "weight": "2", + "absorb": "1,0,3", + "equip_audio": "2240", + "equipment_slot": "0", + "name": "Fighter hat", + "archery_ticket_price": "0", + "id": "10548", + "bonuses": "5,5,5,-7,-7,30,32,28,-3,28,7,0,0,0,0" + }, + { + "requirements": "{1,40}", + "shop_price": "275", + "examine": "A Penance Runner hat.", + "durability": null, + "name": "Runner hat", + "weight": "1", + "archery_ticket_price": "0", + "id": "10549", + "absorb": "1,0,3", + "bonuses": "0,0,0,0,0,30,32,27,1,30,7,0,0,0,0", + "equipment_slot": "0" + }, + { + "requirements": "{1,40}", + "shop_price": "275", + "examine": "A Penance ranger hat.", + "durability": null, + "name": "Ranger hat", + "weight": "2", + "archery_ticket_price": "0", + "id": "10550", + "absorb": "0,3,1", + "bonuses": "-5,-5,-5,-5,7,7,10,11,5,9,7,0,0,0,0", + "equipment_slot": "0" + }, + { + "requirements": "{1,40}", + "shop_price": "375", + "examine": "Penance Fighter torso armour.", + "durability": null, + "destroy": "true", + "weight": "4", + "absorb": "3,0,6", + "equip_audio": "2239", + "equipment_slot": "4", + "remove_sleeves": "true", + "name": "Fighter torso", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10551", + "bonuses": "0,0,0,-30,0,66,85,62,-6,67,40,4,0,0,0" + }, + { + "requirements": "{1,40}", + "shop_price": "100", + "examine": "Boots made from a Penance Runner.", + "durability": null, + "name": "Runner boots", + "archery_ticket_price": "0", + "id": "10552", + "bonuses": "0,0,0,-3,-1,12,13,14,0,0,10,2,0,0,0", + "equipment_slot": "10" + }, + { + "requirements": "{1,40}", + "shop_price": "150", + "examine": "These gloves seem unbelievably light!", + "durability": null, + "name": "Penance gloves", + "weight": "-7", + "archery_ticket_price": "0", + "id": "10553", + "bonuses": "0,0,0,0,0,0,3,4,0,2,2,4,0,0,0", + "equipment_slot": "9" + }, + { + "requirements": "{1,40}", + "shop_price": "150", + "examine": "These gloves seem unbelievably light!", + "durability": null, + "name": "Penance gloves", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "10554", + "bonuses": "0,0,0,0,0,0,3,4,0,2,2,4,0,0,0", + "equipment_slot": "9" + }, + { + "requirements": "{1,40}", + "shop_price": "375", + "examine": "A skirt made from the skin of a Penance Ranger.", + "durability": null, + "name": "Penance skirt", + "weight": "3", + "archery_ticket_price": "0", + "id": "10555", + "absorb": "0,4,2", + "bonuses": "0,0,0,-10,16,26,21,28,19,27,15,0,0,0,0", + "equipment_slot": "7" + }, + { + "durability": null, + "name": "Picture", + "archery_ticket_price": "0", + "id": "10556", + "equipment_slot": "1" + }, + { + "durability": null, + "name": "Picture", + "archery_ticket_price": "0", + "id": "10557", + "equipment_slot": "1" + }, + { + "durability": null, + "name": "Picture", + "archery_ticket_price": "0", + "id": "10558", + "equipment_slot": "1" + }, + { + "durability": null, + "name": "Picture", + "archery_ticket_price": "0", + "id": "10559", + "equipment_slot": "1" + }, + { + "examine": "A horn for communication with your team members.", + "durability": null, + "name": "Collector horn", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10560" + }, + { + "destroy_message": "You will have to ask Captain Cain for another.", + "shop_price": "160", + "examine": "A book about the Barbarian Assault Queen.", + "durability": null, + "name": "Queen help book", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10562" + }, + { + "requirements": "{1,50}-{2,50}", + "shop_price": "95000", + "ge_buy_limit": "10", + "examine": "Provides excellent protection.", + "durability": null, + "weight": "22.6", + "absorb": "4,0,8", + "equipment_slot": "4", + "lendable": "true", + "remove_sleeves": "true", + "grand_exchange_price": "126800", + "name": "Granite body", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10564", + "bonuses": "0,0,0,-22,-5,87,84,79,-6,97,45,0,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "126800", + "durability": null, + "name": "Granite body", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10565" + }, + { + "examine": "A cape of fire.", + "durability": null, + "name": "Fire cape", + "tradeable": "false", + "weight": "1.8", + "archery_ticket_price": "0", + "id": "10566", + "bonuses": "1,1,1,1,1,11,11,11,11,11,11,4,2,0,0", + "equipment_slot": "1" + }, + { + "examine": "Mabob.", + "grand_exchange_price": "2", + "durability": null, + "name": "Picture", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10567", + "equipment_slot": "2" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10568" + }, + { + "examine": "Mabob.", + "grand_exchange_price": "2", + "durability": null, + "name": "Picture", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10569", + "equipment_slot": "2" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10570" + }, + { + "examine": "Mabob.", + "grand_exchange_price": "2", + "durability": null, + "name": "Picture", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10571", + "equipment_slot": "2" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10572" + }, + { + "examine": "Mabob.", + "grand_exchange_price": "2", + "durability": null, + "name": "Picture", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10573", + "equipment_slot": "2" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10574" + }, + { + "examine": "Mabob.", + "grand_exchange_price": "2", + "durability": null, + "name": "Picture", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10575", + "equipment_slot": "2" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10576" + }, + { + "examine": "Mabob.", + "grand_exchange_price": "2", + "durability": null, + "name": "Picture", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10577", + "equipment_slot": "2" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10578" + }, + { + "examine": "Mabob.", + "grand_exchange_price": "2", + "durability": null, + "name": "Picture", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10579", + "equipment_slot": "2" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10580" + }, + { + "examine": "(Normal) A mystical-feeling dagger. (Poisoned) The twisted blade is covered with a nasty poison.", + "durability": null, + "destroy": "true", + "weight": "0.4", + "attack_speed": "4", + "weapon_interface": "5", + "render_anim": "2584", + "defence_anim": "378", + "equipment_slot": "3", + "attack_anims": "376,376,377,376", + "destroy_message": "You can obtain another from Osman. You will then need to poison it.", + "name": "Keris", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10581", + "bonuses": "40,20,-10,2,0,0,0,0,2,0,0,30,2,0,0" + }, + { + "attack_anims": "376,376,377,376", + "destroy_message": "You can obtain another from Osman. You will then need to poison it.", + "durability": null, + "name": "Keris(p)", + "archery_ticket_price": "0", + "id": "10582", + "weapon_interface": "5", + "bonuses": "40,20,-10,2,0,0,0,0,2,0,0,30,2,0,0", + "render_anim": "2584", + "defence_anim": "378", + "equipment_slot": "3" + }, + { + "attack_anims": "376,376,377,376", + "destroy_message": "You can obtain another from Osman. You will then need to poison it.", + "durability": null, + "name": "Keris(p+)", + "archery_ticket_price": "0", + "id": "10583", + "weapon_interface": "5", + "bonuses": "40,20,-10,2,0,0,0,0,2,0,0,30,2,0,0", + "render_anim": "2584", + "defence_anim": "378", + "equipment_slot": "3" + }, + { + "attack_anims": "376,376,377,376", + "destroy_message": "You can obtain another from Osman. You will then need to poison it.", + "durability": null, + "name": "Keris(p++)", + "archery_ticket_price": "0", + "id": "10584", + "weapon_interface": "5", + "bonuses": "40,20,-10,2,0,0,0,0,2,0,0,30,2,0,0", + "render_anim": "2584", + "defence_anim": "378", + "equipment_slot": "3" + }, + { + "destroy_message": "You can obtain a replacement lamp from the high priest in Sophanem.", + "examine": "A mystical lamp, engraved with scenes of carnage.", + "durability": null, + "name": "Combat lamp", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10586" + }, + { + "destroy_message": "I got this diary in Tarn's Lair, perhaps I can get another one there.", + "examine": "Tarn Razorlor's diary.", + "durability": null, + "name": "Tarn's diary", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10587" + }, + { + "examine": "Increases the wearer's Strength and Attack by 20% when fighting the undead.", + "durability": null, + "name": "Salve amulet(e)", + "weight": "1", + "archery_ticket_price": "0", + "id": "10588", + "bonuses": "0,0,0,0,0,3,3,3,0,0,3,0,3,0,0", + "equipment_slot": "2" + }, + { + "remove_head": "true", + "requirements": "{1,50}-{2,50}", + "ge_buy_limit": "10", + "examine": "A stone helmet.", + "durability": null, + "weight": "4", + "absorb": "2,0,4", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "28000", + "name": "Granite helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10589", + "bonuses": "0,0,0,-9,-7,31,33,29,-1,39,9,0,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "28000", + "durability": null, + "name": "Granite helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10590" + }, + { + "examine": "A terrifying dog beast.", + "durability": null, + "name": "Terror dog", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "10591" + }, + { + "destroy_message": "You can make another with tanned leather and a mahogany plank.", + "examine": "Small drums.", + "durability": null, + "name": "Penguin bongos", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10592" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Every song needs a cowbell.", + "durability": null, + "name": "Cowbells", + "weight": "2", + "archery_ticket_price": "0", + "id": "10593" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A book about clockwork mechanisms.", + "durability": null, + "name": "Clockwork book", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10594" + }, + { + "destroy_message": "You'll have to make another one at your house. Speak to Larry to learn how to make one.", + "examine": "A clockwork penguin suit.", + "durability": null, + "name": "Clockwork suit", + "tradeable": "false", + "destroy": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "10595" + }, + { + "destroy_message": "You'll have to make another one at your house. Speak to Larry to learn how to make one.", + "examine": "A clockwork penguin suit.", + "durability": null, + "name": "Clockwork suit", + "tradeable": "false", + "destroy": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "10596" + }, + { + "destroy_message": "You will need to speak to Noodle to get another.", + "examine": "So you can be a penguin too!", + "durability": null, + "name": "Kgp id card", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10600" + }, + { + "shop_price": "15000", + "examine": "Blue: A magical hat. ", + "durability": null, + "weight": "0.4", + "absorb": "3,1,0", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "1", + "name": "Mystic hat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10601", + "bonuses": "0,0,0,4,0,0,0,0,4,0,0,0,0,0,0" + }, + { + "shop_price": "15000", + "examine": "Blue: A magical hat. ", + "durability": null, + "weight": "0.4", + "absorb": "3,1,0", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "1", + "name": "Mystic hat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10602", + "bonuses": "0,0,0,4,0,0,0,0,4,0,0,0,0,0,0" + }, + { + "shop_price": "15000", + "examine": "Blue: A magical hat. ", + "durability": null, + "weight": "0.4", + "absorb": "3,1,0", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "1", + "name": "Mystic hat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10603", + "bonuses": "0,0,0,4,0,0,0,0,4,0,0,0,0,0,0" + }, + { + "remove_head": "true", + "examine": "Make your foes cower by wearing a skull as a helmet!", + "durability": null, + "weight": "1.3", + "absorb": "3,1,0", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "25569", + "name": "Skeletal helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10604", + "bonuses": "0,0,0,2,-2,10,9,11,3,0,0,0,0,0,0" + }, + { + "remove_sleeves": "true", + "examine": "Mystical robes.", + "grand_exchange_price": "3932123", + "durability": null, + "name": "Infinity top", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "10605", + "absorb": "3,1,0", + "bonuses": "0,0,0,22,0,0,0,0,22,0,0,0,0,0,0", + "equipment_slot": "4" + }, + { + "lendable": "true", + "examine": "A wooden helmet.", + "grand_exchange_price": "5623", + "durability": null, + "name": "Splitbark helm", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "10606", + "absorb": "3,1,0", + "bonuses": "0,0,0,3,-2,10,9,11,3,0,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "examine": "They seem to be not quite of this world...", + "durability": null, + "name": "Ghostly boots", + "archery_ticket_price": "0", + "id": "10607", + "bonuses": "0,0,0,2,0,0,0,0,2,0,0,0,0,0,0", + "equipment_slot": "10" + }, + { + "shop_price": "1000", + "examine": "A mystical hat.", + "durability": null, + "name": "Moonclan hat", + "weight": "1", + "archery_ticket_price": "0", + "id": "10608", + "bonuses": "0,0,0,3,-5,3,3,3,3,-5,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "shop_price": "15000", + "examine": "A mystical helmet.", + "durability": null, + "destroy": "true", + "weight": "0.9", + "absorb": "3,1,0", + "remove_beard": "true", + "equipment_slot": "0", + "destroy_message": "The Oneiromancer might be able to help you get another.", + "name": "Lunar helm", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "10609", + "bonuses": "0,0,0,3,-2,8,7,10,2,0,0,0,0,0,0" + }, + { + "remove_sleeves": "true", + "durability": null, + "name": "Decorative armour", + "archery_ticket_price": "0", + "id": "10610", + "bonuses": "0,0,0,-30,-10,32,31,24,-6,31,5,0,0,0,0", + "equipment_slot": "4" + }, + { + "remove_sleeves": "true", + "requirements": "{0,42}-{1,42}-{2,42}-{3,42}-{4,42}-{5,22}-{6,42}", + "shop_price": "250", + "examine": "Torso armour from the order of the Void Knights.", + "durability": null, + "name": "Void knight top", + "tradeable": "false", + "weight": "6.5", + "archery_ticket_price": "0", + "id": "10611", + "bonuses": "0,0,0,0,0,40,40,40,40,40,0,0,0,0,0", + "equipment_slot": "4" + }, + { + "remove_head": "true", + "examine": "Black banded leather armour, a rogue's dream!", + "durability": null, + "name": "Rogue mask", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "10612", + "bonuses": "0,0,0,0,0,5,5,5,5,5,0,0,0,0,0", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "requirements": "{1,40}", + "examine": "Protective headwear made from crabs. Better than it sounds.", + "durability": null, + "weight": "2.7", + "absorb": "1,0,3", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "24661", + "name": "Rock-shell helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10613", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,0,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,40}-{4,40}", + "examine": "A helm fit for any Fremennik ranger.", + "durability": null, + "weight": "1", + "absorb": "0,3,1", + "remove_beard": "true", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "35640", + "name": "Spined helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10614", + "bonuses": "-6,-6,-6,-6,6,6,6,6,6,0,0,0,0,0,0" + }, + { + "examine": "A ceremonial wooden mask.", + "grand_exchange_price": "1021", + "durability": null, + "name": "Tribal mask", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "10615", + "equipment_slot": "0" + }, + { + "examine": "A ceremonial wooden mask.", + "grand_exchange_price": "1021", + "durability": null, + "name": "Tribal mask", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "10616", + "equipment_slot": "0" + }, + { + "examine": "A ceremonial wooden mask.", + "grand_exchange_price": "1021", + "durability": null, + "name": "Tribal mask", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "10617", + "equipment_slot": "0" + }, + { + "shop_price": "3840", + "examine": "Provides excellent protection.", + "durability": null, + "weight": "9.9", + "absorb": "1,0,2", + "equip_audio": "2239", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "4595", + "name": "White platebody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10618", + "bonuses": "0,0,0,-30,-10,41,40,30,-6,40,0,0,1,0,0" + }, + { + "shop_price": "10000", + "examine": "An initiate Temple Knight's Armour.", + "durability": null, + "weight": "8", + "absorb": "1,0,3", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "5821", + "name": "Initiate hauberk", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10619", + "bonuses": "0,0,0,-30,-10,46,44,38,-6,44,0,0,6,0,0" + }, + { + "shop_price": "12000", + "examine": "A Proselyte Temple Knight's armour.", + "durability": null, + "weight": "8.6", + "absorb": "2,0,4", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "6960", + "name": "Proselyte hauberk", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10620", + "bonuses": "0,0,0,-30,-10,65,63,55,-6,63,0,0,8,0,0" + }, + { + "remove_sleeves": "true", + "examine": "A thick heavy leather top.", + "durability": null, + "name": "Mourner top", + "archery_ticket_price": "0", + "id": "10621", + "equipment_slot": "4" + }, + { + "remove_sleeves": "true", + "examine": "This should make me harder to spot in polar areas.", + "grand_exchange_price": "216", + "durability": null, + "name": "Kyatt top", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "10622", + "bonuses": "0,0,0,0,0,10,15,19,0,12,0,0,0,0,0", + "equipment_slot": "4" + }, + { + "remove_sleeves": "true", + "examine": "This should make me harder to spot in woodland and jungle areas.", + "grand_exchange_price": "1793", + "durability": null, + "name": "Larupia top", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "10623", + "bonuses": "0,0,0,0,0,10,15,19,0,12,0,0,0,0,0", + "equipment_slot": "4" + }, + { + "remove_sleeves": "true", + "shop_price": "300", + "examine": "This should make me harder to spot in desert areas.", + "grand_exchange_price": "246", + "durability": null, + "name": "Graahk top", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "10624", + "bonuses": "0,0,0,0,0,10,15,19,0,12,0,0,0,0,0", + "equipment_slot": "4" + }, + { + "remove_sleeves": "true", + "examine": "This should make me harder to spot in wooded areas.", + "grand_exchange_price": "3883", + "durability": null, + "name": "Wood camo top", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "10625", + "bonuses": "0,0,0,0,0,10,15,19,0,12,0,0,0,0,0", + "equipment_slot": "4" + }, + { + "remove_sleeves": "true", + "examine": "This should make me harder to spot in jungle areas.", + "grand_exchange_price": "325", + "durability": null, + "name": "Jungle camo top", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "10626", + "bonuses": "0,0,0,0,0,10,15,19,0,12,0,0,0,0,0", + "equipment_slot": "4" + }, + { + "remove_sleeves": "true", + "examine": "This should make me harder to spot in desert areas.", + "grand_exchange_price": "606", + "durability": null, + "name": "Desert camo top", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "10627", + "bonuses": "0,0,0,0,0,10,15,19,0,12,0,0,0,0,0", + "equipment_slot": "4" + }, + { + "remove_sleeves": "true", + "examine": "This should make me harder to spot in polar areas.", + "grand_exchange_price": "5614", + "durability": null, + "name": "Polar camo top", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "10628", + "bonuses": "0,0,0,0,0,10,15,19,0,12,0,0,0,0,0", + "equipment_slot": "4" + }, + { + "examine": "A mime would wear this.", + "durability": null, + "name": "Mime mask", + "archery_ticket_price": "0", + "id": "10629", + "equipment_slot": "0" + }, + { + "remove_sleeves": "true", + "examine": "Very posh!", + "durability": null, + "name": "Princess blouse", + "weight": "2", + "archery_ticket_price": "0", + "id": "10630", + "equipment_slot": "4" + }, + { + "examine": "Aside from the braaaains on the lapel, it's still quite good.", + "durability": null, + "name": "Zombie shirt", + "archery_ticket_price": "0", + "id": "10631", + "equipment_slot": "4" + }, + { + "remove_sleeves": "true", + "examine": "Examine what?", + "durability": null, + "name": "Camo top", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "10632", + "equipment_slot": "4" + }, + { + "remove_sleeves": "true", + "examine": "A leather strapped top.", + "durability": null, + "name": "Lederhosen top", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "10633", + "equipment_slot": "4" + }, + { + "remove_sleeves": "true", + "examine": "I feel closer to the gods when I am wearing this. (Top) If a shade had knees, this would keep them nice and warm. (Bottom)", + "durability": null, + "name": "Shade robe", + "weight": "2", + "archery_ticket_price": "0", + "id": "10634", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,5,0,0", + "equipment_slot": "4" + }, + { + "shop_price": "450", + "examine": "The cape worn by members of the Legends Guild.", + "durability": null, + "name": "Cape of legends", + "tradeable": "false", + "weight": "1.8", + "archery_ticket_price": "0", + "id": "10635", + "bonuses": "0,0,0,0,0,7,7,7,7,7,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "lendable": "true", + "shop_price": "90000", + "examine": "A cape woven of obsidian plates.", + "grand_exchange_price": "38500", + "durability": null, + "name": "Obsidian cape", + "tradeable": "true", + "weight": "1.8", + "archery_ticket_price": "0", + "id": "10636", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "examine": "A cape of fire.", + "durability": null, + "name": "Fire cape", + "tradeable": "false", + "weight": "1.8", + "archery_ticket_price": "0", + "id": "10637", + "bonuses": "1,1,1,1,1,11,11,11,11,11,0,4,2,0,0", + "equipment_slot": "1" + }, + { + "shop_price": "50", + "examine": "Ooohhh look at the pretty colours...", + "durability": null, + "name": "Team-1 cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10638", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{0,99}", + "shop_price": "99000", + "examine": "The cape worn by masters of attack.", + "durability": null, + "name": "Attack cape", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10639", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{2,99}", + "shop_price": "99000", + "examine": "The cape only worn by the strongest people.", + "durability": null, + "name": "Strength cape", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10640", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{1,99}", + "shop_price": "99000", + "examine": "The cape worn by masters of the art of Defence.", + "durability": null, + "name": "Defence cape", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10641", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{4,99}", + "shop_price": "99000", + "examine": "The cape worn by master archers.", + "durability": null, + "name": "Ranging cape", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10642", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{5,99}", + "shop_price": "99000", + "examine": "The cape worn by the most pious of heroes.", + "durability": null, + "name": "Prayer cape", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10643", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{6,99}", + "shop_price": "99000", + "examine": "The cape worn by the most powerful mages.", + "durability": null, + "name": "Magic cape", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10644", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{20,99}", + "shop_price": "99000", + "examine": "The cape worn by master runecrafters.", + "durability": null, + "name": "Runecraft cape", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10645", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{21,99}", + "shop_price": "99000", + "examine": "The cape worn by master hunters.", + "durability": null, + "name": "Hunter cape", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10646", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{3,99}", + "shop_price": "99000", + "examine": "The cape worn by well-constituted adventurers.", + "durability": null, + "name": "Hitpoints cape", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10647", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{16,99}", + "shop_price": "99000", + "examine": "The cape worn by the most agile of heroes.", + "durability": null, + "name": "Agility cape", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10648", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{15,99}", + "shop_price": "99000", + "examine": "The cape worn by the most skilled at the art of herblore.", + "durability": null, + "name": "Herblore cape", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10649", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{17,99}", + "shop_price": "99000", + "examine": "The cape worn by master thieves.", + "durability": null, + "name": "Thieving cape", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10650", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{12,99}", + "shop_price": "99000", + "examine": "The cape worn by master craftworkers.", + "durability": null, + "name": "Crafting cape", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10651", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{9,99}", + "shop_price": "99000", + "examine": "The cape worn by the best of fletchers.", + "durability": null, + "name": "Fletching cape", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10652", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{18,99}", + "shop_price": "99000", + "examine": "The cape worn by slayer masters.", + "durability": null, + "name": "Slayer cape", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10653", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{22,99}", + "shop_price": "99000", + "examine": "The cape worn by master builders.", + "durability": null, + "name": "Construct. cape", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10654", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{14,99}", + "shop_price": "99000", + "examine": "The cape worn by the most skilled miners.", + "durability": null, + "name": "Mining cape", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10655", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{13,99}", + "shop_price": "99000", + "examine": "The cape worn by master smiths.", + "durability": null, + "name": "Smithing cape", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10656", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{10,99}", + "shop_price": "99000", + "examine": "The cape worn by the best fishermen.", + "durability": null, + "name": "Fishing cape", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10657", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{7,99}", + "shop_price": "99000", + "examine": "The cape worn by the world's best chefs.", + "durability": null, + "name": "Cooking cape", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10658", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{11,99}", + "shop_price": "99000", + "examine": "The cape worn by master firelighters.", + "durability": null, + "name": "Firemaking cape", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10659", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{8,99}", + "shop_price": "99000", + "examine": "The cape worn by master woodcutters (Obtaining level 99 skill)", + "durability": null, + "name": "Woodcutting cape", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10660", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{19,99}", + "shop_price": "99000", + "examine": "The cape worn by master farmers.", + "durability": null, + "name": "Farming cape", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10661", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "shop_price": "99000", + "examine": "The cape worn by only the most experienced adventurers.", + "durability": null, + "name": "Quest point cape", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10662", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "examine": "A surprisingly aerodynamic cape.", + "grand_exchange_price": "951", + "durability": null, + "name": "Spotted cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10663", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "examine": "A really surprisingly aerodynamic cape.", + "grand_exchange_price": "881", + "durability": null, + "name": "Spottier cape", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10664", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{1,10}", + "examine": "A black kitesheild with a heraldic design.", + "grand_exchange_price": "15249", + "durability": null, + "name": "Black shield(h1)", + "tradeable": "true", + "weight": "4", + "archery_ticket_price": "0", + "id": "10665", + "absorb": "1,0,2", + "bonuses": "0,0,0,-8,-2,17,19,18,-1,18,0,0,0,0,0", + "equipment_slot": "5" + }, + { + "requirements": "{1,30}", + "ge_buy_limit": "2", + "examine": "A shield with a heraldic design.", + "durability": null, + "weight": "5", + "absorb": "3,0,6", + "equipment_slot": "5", + "grand_exchange_price": "16339", + "name": "Adamant shield(h1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10666", + "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,0,0,0,0,0" + }, + { + "requirements": "{1,40}", + "examine": "A rune kiteshield with a heraldic design.", + "durability": null, + "weight": "5.4", + "absorb": "3,0,7", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "35300", + "name": "Rune shield(h1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10667", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,0,0,0,0,0" + }, + { + "requirements": "{1,10}", + "examine": "A black kiteshield with a heraldic design.", + "grand_exchange_price": "9751", + "durability": null, + "name": "Black shield(h2)", + "tradeable": "true", + "weight": "4", + "archery_ticket_price": "0", + "id": "10668", + "absorb": "1,0,2", + "bonuses": "0,0,0,-8,-2,17,19,18,-1,18,0,0,0,0,0", + "equipment_slot": "5" + }, + { + "requirements": "{1,30}", + "ge_buy_limit": "2", + "examine": "A shield with a heraldic design.", + "durability": null, + "weight": "5", + "absorb": "3,0,6", + "equipment_slot": "5", + "grand_exchange_price": "3353", + "name": "Adamant shield(h2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10669", + "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,0,0,0,0,0" + }, + { + "requirements": "{1,40}", + "examine": "A rune kiteshield with a heraldic design.", + "durability": null, + "weight": "5.4", + "absorb": "3,0,7", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "31903", + "name": "Rune shield(h2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10670", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,0,0,0,0,0" + }, + { + "requirements": "{1,10}", + "examine": "A black shield with a heraldic design.", + "grand_exchange_price": "6791", + "durability": null, + "name": "Black shield(h3)", + "tradeable": "true", + "weight": "4", + "archery_ticket_price": "0", + "id": "10671", + "absorb": "1,0,2", + "bonuses": "0,0,0,-8,-2,17,19,18,-1,18,0,0,0,0,0", + "equipment_slot": "5" + }, + { + "requirements": "{1,30}", + "ge_buy_limit": "2", + "examine": "A shield with a heraldic design.", + "durability": null, + "weight": "5", + "absorb": "3,0,6", + "equipment_slot": "5", + "grand_exchange_price": "5566", + "name": "Adamant shield(h3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10672", + "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,0,0,0,0,0" + }, + { + "requirements": "{1,40}", + "examine": "A rune kiteshield with a heraldic design.", + "durability": null, + "weight": "5", + "absorb": "3,0,7", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "32082", + "name": "Rune shield(h3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10673", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,0,0,0,0,0" + }, + { + "requirements": "{1,10}", + "examine": "A black shield with a heraldic design.", + "grand_exchange_price": "5159", + "durability": null, + "name": "Black shield(h4)", + "tradeable": "true", + "weight": "4", + "archery_ticket_price": "0", + "id": "10674", + "absorb": "1,0,2", + "bonuses": "0,0,0,-8,-2,17,19,18,-1,18,0,0,0,0,0", + "equipment_slot": "5" + }, + { + "requirements": "{1,30}", + "ge_buy_limit": "2", + "examine": "A shield with a heraldic design.", + "durability": null, + "weight": "5", + "absorb": "3,0,6", + "equipment_slot": "5", + "grand_exchange_price": "3219", + "name": "Adamant shield(h4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10675", + "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,0,0,0,0,0" + }, + { + "requirements": "{1,40}", + "examine": "A rune kiteshield with a heraldic design.", + "durability": null, + "weight": "5", + "absorb": "3,0,7", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "32351", + "name": "Rune shield(h4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10676", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,0,0,0,0,0" + }, + { + "requirements": "{1,10}", + "examine": "A black shield with a heraldic design.", + "grand_exchange_price": "8451", + "durability": null, + "name": "Black shield(h5)", + "tradeable": "true", + "weight": "4", + "archery_ticket_price": "0", + "id": "10677", + "absorb": "1,0,2", + "bonuses": "0,0,0,-8,-2,17,19,18,-1,18,0,0,0,0,0", + "equipment_slot": "5" + }, + { + "requirements": "{1,30}", + "ge_buy_limit": "2", + "examine": "A shield with a heraldic design.", + "durability": null, + "weight": "5", + "absorb": "3,0,6", + "equipment_slot": "5", + "grand_exchange_price": "5905", + "name": "Adamant shield(h5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10678", + "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,0,0,0,0,0" + }, + { + "requirements": "{1,40}", + "examine": "A rune kiteshield with a heraldic design.", + "durability": null, + "weight": "5", + "absorb": "3,0,7", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "35200", + "name": "Rune shield(h5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10679", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,0,0,0,0,0" + }, + { + "examine": "Those studs should provide a bit more protection. Nice trim too!", + "grand_exchange_price": "67430", + "durability": null, + "name": "Studded body (g)", + "tradeable": "true", + "weight": "5.4", + "archery_ticket_price": "0", + "id": "10680", + "absorb": "0,3,1", + "bonuses": "0,0,0,-4,8,18,25,22,8,25,0,0,0,0,0", + "equipment_slot": "4" + }, + { + "examine": "Those studs should provide a bit more protection. Nice trim too!", + "grand_exchange_price": "22400", + "durability": null, + "name": "Studded body (t)", + "tradeable": "true", + "weight": "5.4", + "archery_ticket_price": "0", + "id": "10681", + "absorb": "0,3,1", + "bonuses": "0,0,0,-4,8,18,25,22,8,25,0,0,0,0,0", + "equipment_slot": "4" + }, + { + "durability": null, + "name": "D'hide body(g)", + "archery_ticket_price": "0", + "id": "10682", + "bonuses": "0,0,0,-15,15,40,32,45,20,40,0,0,0,0,0", + "equip_audio": "2241", + "equipment_slot": "4" + }, + { + "durability": null, + "name": "D'hide body (t)", + "archery_ticket_price": "0", + "id": "10683", + "bonuses": "0,0,0,-15,15,40,32,45,20,40,0,0,0,0,0", + "equip_audio": "2241", + "equipment_slot": "4" + }, + { + "durability": null, + "name": "D'hide body (g)", + "archery_ticket_price": "0", + "id": "10684", + "bonuses": "0,0,0,-15,20,45,37,50,30,45,0,0,0,0,0", + "equip_audio": "2241", + "equipment_slot": "4" + }, + { + "durability": null, + "name": "D'hide body (t)", + "archery_ticket_price": "0", + "id": "10685", + "bonuses": "0,0,0,-15,20,45,37,50,30,45,0,0,0,0,0", + "equip_audio": "2241", + "equipment_slot": "4" + }, + { + "remove_sleeves": "true", + "examine": "I can practise magic better in this.", + "durability": null, + "name": "Wizard robe (g)", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10686", + "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0", + "equipment_slot": "4" + }, + { + "remove_sleeves": "true", + "examine": "I can do magic better in this.", + "durability": null, + "name": "Wizard robe (t)", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10687", + "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0", + "equipment_slot": "4" + }, + { + "requirements": "{1,20}-{6,40}", + "examine": "Enchanted Wizards robes.", + "durability": null, + "weight": "1", + "absorb": "3,1,0", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "72800", + "name": "Enchanted top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10688", + "bonuses": "0,0,0,20,0,0,0,0,20,0,20,0,0,0,0" + }, + { + "lendable": "true", + "examine": "Slightly magical boots.", + "grand_exchange_price": "763602", + "durability": null, + "name": "Wizard boots", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10689", + "bonuses": "0,0,0,4,0,0,0,0,4,0,0,0,0,0,0", + "equipment_slot": "10" + }, + { + "requirements": "{1,10}", + "examine": "Black platebody with trim.", + "durability": null, + "weight": "9.07", + "absorb": "1,0,2", + "equip_audio": "2239", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "90744", + "name": "Black platebody (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10690", + "bonuses": "0,0,0,-30,-10,41,40,30,-6,40,0,0,0,0,0" + }, + { + "requirements": "{1,10}", + "examine": "Black platebody with gold trim.", + "durability": null, + "weight": "9.07", + "absorb": "1,0,2", + "equip_audio": "2239", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "230800", + "name": "Black platebody (g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10691", + "bonuses": "0,0,0,-30,-10,41,40,30,-6,40,0,0,0,0,0" + }, + { + "lendable": "true", + "examine": "Your money or your life!", + "grand_exchange_price": "92519", + "durability": null, + "name": "Highwayman mask", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10692", + "equipment_slot": "0" + }, + { + "lendable": "true", + "examine": "Parlez-vous francais? (Do you speak French?)", + "grand_exchange_price": "64066", + "durability": null, + "name": "Blue beret", + "tradeable": "true", + "archery_ticket_price": "0", + "hat": true, + "id": "10693", + "equipment_slot": "0" + }, + { + "lendable": "true", + "examine": "Parlez-vous francais?(Do you speak French?)", + "grand_exchange_price": "158274", + "durability": null, + "name": "Black beret", + "tradeable": "true", + "archery_ticket_price": "0", + "hat": true, + "id": "10694", + "equipment_slot": "0" + }, + { + "lendable": "true", + "examine": "Parlez-vous francais? (Do you speak French?)", + "grand_exchange_price": "281900", + "durability": null, + "name": "White beret", + "tradeable": "true", + "archery_ticket_price": "0", + "hat": true, + "id": "10695", + "equipment_slot": "0" + }, + { + "lendable": "true", + "examine": "Lightweight boots ideal for rangers.", + "grand_exchange_price": "11781186", + "durability": null, + "name": "Ranger boots", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "10696", + "bonuses": "0,0,0,-10,8,2,3,4,2,0,0,0,0,0,0", + "equipment_slot": "10" + }, + { + "requirements": "{1,30}", + "ge_buy_limit": "2", + "examine": "Adamant platebody with trim.", + "durability": null, + "weight": "9.07", + "absorb": "2,0,4", + "equip_audio": "2239", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "79300", + "name": "Adam platebody (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10697", + "bonuses": "0,0,0,-30,-10,65,63,55,-6,63,0,0,0,0,0" + }, + { + "requirements": "{1,30}", + "ge_buy_limit": "2", + "examine": "Adamant platebody with gold trim.", + "durability": null, + "weight": "9.07", + "absorb": "2,0,4", + "equip_audio": "2239", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "207912", + "name": "Adam platebody (g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10698", + "bonuses": "0,0,0,-30,-10,65,63,55,-6,63,0,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,10}", + "examine": "A black helmet with a heraldic design.", + "durability": null, + "weight": "1.8", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "22022", + "name": "Black helm (h1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10699", + "bonuses": "0,0,0,-6,-2,12,13,10,-1,12,0,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,10}", + "examine": "A black helmet with a heraldic design.", + "durability": null, + "weight": "1.8", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "11700", + "name": "Black helm (h2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10700", + "bonuses": "0,0,0,-6,-2,12,13,10,-1,12,0,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,10}", + "examine": "A black helmet with a heraldic design.", + "durability": null, + "weight": "1.8", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "10424", + "name": "Black helm (h3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10701", + "bonuses": "0,0,0,-6,-2,12,13,10,-1,12,0,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,10}", + "examine": "A black helmet with a heraldic design.", + "durability": null, + "weight": "1.8", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "12717", + "name": "Black helm (h4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10702", + "bonuses": "0,0,0,-6,-2,12,13,10,-1,12,0,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,10}", + "examine": "A black helmet with a heraldic design.", + "durability": null, + "weight": "1.8", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "17852", + "name": "Black helm (h5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10703", + "bonuses": "0,0,0,-6,-2,12,13,10,-1,12,0,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,40}", + "examine": "A rune helmet with a heraldic design.", + "durability": null, + "absorb": "1,0,3", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "30298", + "name": "Rune helm (h1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10704", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,0,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,40}", + "examine": "A rune helmet with a heraldic design.", + "durability": null, + "weight": "3", + "absorb": "1,0,3", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "26127", + "name": "Rune helm (h2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10705", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,0,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,40}", + "examine": "A rune helmet with a heraldic design.", + "durability": null, + "weight": "4", + "absorb": "1,0,3", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "37333", + "name": "Rune helm (h3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10706", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,0,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,40}", + "examine": "A rune helmet with a heraldic design.", + "durability": null, + "weight": "2", + "absorb": "1,0,3", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "29600", + "name": "Rune helm (h4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10707", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,0,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,40}", + "examine": "A rune helmet with a heraldic design.", + "durability": null, + "weight": "2", + "absorb": "1,0,3", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "41325", + "name": "Rune helm (h5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10708", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,0,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,30}", + "ge_buy_limit": "2", + "examine": "An adamant helmet with a heraldic design.", + "durability": null, + "weight": "3", + "absorb": "1,0,2", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "28407", + "name": "Adamant helm (h1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10709", + "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,0,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,30}", + "ge_buy_limit": "2", + "examine": "An adamant helmet with a heraldic design.", + "durability": null, + "weight": "3", + "absorb": "1,0,2", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "9839", + "name": "Adamant helm (h2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10710", + "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,0,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,30}", + "ge_buy_limit": "2", + "examine": "An adamant helmet with a heraldic design.", + "durability": null, + "weight": "3", + "absorb": "1,0,2", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "8485", + "name": "Adamant helm (h3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10711", + "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,0,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,30}", + "ge_buy_limit": "2", + "examine": "An Adamant helmet with a heraldic design.", + "durability": null, + "weight": "3", + "absorb": "1,0,2", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "10774", + "name": "Adamant helm (h4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10712", + "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,0,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,30}", + "ge_buy_limit": "2", + "examine": "An adamant helmet with a heraldic design.", + "durability": null, + "weight": "3", + "absorb": "1,0,2", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "17390", + "name": "Adamant helm (h5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10713", + "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,0,0,0,0,0" + }, + { + "remove_sleeves": "true", + "examine": "See table", + "grand_exchange_price": "8425", + "durability": null, + "name": "Bob shirt", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "10714", + "equipment_slot": "4" + }, + { + "remove_sleeves": "true", + "examine": "See table", + "grand_exchange_price": "8425", + "durability": null, + "name": "Bob shirt", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "10715", + "equipment_slot": "4" + }, + { + "remove_sleeves": "true", + "examine": "See table", + "grand_exchange_price": "8425", + "durability": null, + "name": "Bob shirt", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "10716", + "equipment_slot": "4" + }, + { + "remove_sleeves": "true", + "examine": "See table", + "grand_exchange_price": "8425", + "durability": null, + "name": "Bob shirt", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "10717", + "equipment_slot": "4" + }, + { + "remove_sleeves": "true", + "examine": "See table", + "grand_exchange_price": "8425", + "durability": null, + "name": "Bob shirt", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "10718", + "equipment_slot": "4" + }, + { + "examine": "A very powerful dragonstone amulet.", + "grand_exchange_price": "1", + "durability": null, + "name": "Amulet of glory(t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10719", + "bonuses": "10,10,10,10,10,3,3,3,3,3,3,6,3,0,0", + "equipment_slot": "2" + }, + { + "examine": "A cape from the almighty god Guthix.", + "durability": null, + "name": "Guthix cape", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10720", + "bonuses": "0,0,0,10,0,1,1,2,10,0,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "remove_head": "true", + "examine": "Now that's just silly.", + "durability": null, + "name": "Frog mask", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10721", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "destroy_message": "You can get another from Diango in Draynor Village.", + "examine": "A reindeer hat and a matching flashing nose.", + "durability": null, + "name": "Reindeer hat", + "tradeable": "false", + "destroy": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "10722" + }, + { + "remove_head": "true", + "destroy_message": "You may get another from Diango in Draynor Village.", + "examine": "Better not light it!", + "durability": null, + "name": "Jack lantern mask", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10723", + "equip_audio": "3227", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Skeleton feet.", + "durability": null, + "name": "Skeleton boots", + "weight": "2", + "archery_ticket_price": "0", + "id": "10724", + "equipment_slot": "10" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Some skeletal gloves.", + "durability": null, + "name": "Skeleton gloves", + "weight": "2", + "archery_ticket_price": "0", + "id": "10725", + "equipment_slot": "9" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Does my pelvis look big in this?", + "durability": null, + "name": "Skeleton leggings", + "weight": "2", + "archery_ticket_price": "0", + "id": "10726", + "equipment_slot": "7" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "remove_sleeves": "true", + "examine": "The shirt of a fully body skeleton costume.", + "durability": null, + "name": "Skeleton shirt", + "weight": "2", + "archery_ticket_price": "0", + "id": "10727", + "equipment_slot": "4" + }, + { + "remove_head": "true", + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A scary skeleton mask.", + "durability": null, + "name": "Skeleton mask", + "weight": "2", + "archery_ticket_price": "0", + "id": "10728", + "equipment_slot": "0" + }, + { + "examine": "A ring given to you by the Easter Bunny.", + "durability": null, + "name": "Easter ring", + "archery_ticket_price": "0", + "id": "10729", + "equip_audio": "", + "equipment_slot": "" + }, + { + "destroy_message": "You can obtain another marionette in Diango's workshop by the trap door.", + "examine": "I've got no strings ... oh hang on!", + "durability": null, + "name": "Blue marionette", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10730" + }, + { + "examine": "Alas...I hardly knew him.", + "durability": null, + "name": "Zombie head", + "archery_ticket_price": "0", + "id": "10731" + }, + { + "turn90cw_anim": "821", + "examine": "Perhaps not the most powerful weapon in 2009Scape.", + "walk_anim": "1830", + "durability": null, + "weight": "0.4", + "turn90ccw_anim": "822", + "attack_speed": "4", + "weapon_interface": "12", + "turn180_anim": "1830", + "equip_audio": "2238", + "render_anim": "182", + "equipment_slot": "3", + "fun_weapon": "true", + "stand_anim": "1832", + "attack_audios": "2257,2257,2257", + "name": "Rubber chicken", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "10732", + "stand_turn_anim": "823", + "bonuses": "-100,-100,-50,0,0,0,0,0,0,0,0,-10,0,0,0" + }, + { + "examine": "A gift from Santa.", + "durability": null, + "name": "Yo-yo", + "archery_ticket_price": "0", + "id": "10733" + }, + { + "examine": "A rabbit-like adornment.", + "durability": null, + "name": "Bunny ears", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "10734", + "equipment_slot": "0" + }, + { + "turn90cw_anim": "821", + "examine": "It's a Scythe.", + "walk_anim": "819", + "durability": null, + "weight": "3", + "turn90ccw_anim": "822", + "attack_speed": "7", + "two_handed": "true", + "turn180_anim": "820", + "equip_audio": "2247", + "render_anim": "1383", + "equipment_slot": "3", + "stand_anim": "847", + "name": "Scythe", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "10735", + "stand_turn_anim": "823", + "bonuses": "3,8,3,0,0,0,3,1,0,0,0,10,0,0,0" + }, + { + "examine": "An enchanted ruby amulet with a nice trim.", + "grand_exchange_price": "443800", + "durability": null, + "name": "Strength amulet(t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10736", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,10,0,0,0", + "equipment_slot": "2" + }, + { + "examine": "An enchanted sapphire amulet of magic.", + "grand_exchange_price": "67158", + "durability": null, + "name": "Amulet of magic(t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10738", + "bonuses": "0,0,0,10,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "2" + }, + { + "remove_head": "true", + "lendable": "true", + "examine": "A big 'do about nothing.", + "grand_exchange_price": "36879", + "durability": null, + "name": "A powdered wig", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "10740", + "equipment_slot": "0" + }, + { + "lendable": "true", + "examine": "These'll help me stay alive.", + "grand_exchange_price": "559284", + "durability": null, + "name": "Flared trousers", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10742", + "equipment_slot": "7" + }, + { + "lendable": "true", + "examine": "Alas, someone has slashed my pantaloons.", + "grand_exchange_price": "12022", + "durability": null, + "name": "Pantaloons", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10744", + "equipment_slot": "7" + }, + { + "remove_head": "true", + "lendable": "true", + "examine": "A cap for wearing whil...zzzzzzzzz", + "grand_exchange_price": "376084", + "durability": null, + "name": "Sleeping cap", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "10746", + "equipment_slot": "0" + }, + { + "remove_sleeves": "true", + "examine": "Blouse: A well made elegant ladies' [colour] blouse.Skirt: A rather elegant [colour] skirt.Shirt: A well made elegant mans' [colour] shirt.Legs: A rather elegant [colour] pair of pantaloons.", + "durability": null, + "name": "Elegant shirt", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10748", + "equipment_slot": "4" + }, + { + "remove_sleeves": "true", + "examine": "Blouse: A well made elegant ladies' [colour] blouse.Skirt: A rather elegant [colour] skirt.Shirt: A well made elegant mans' [colour] shirt.Legs: A rather elegant [colour] pair of pantaloons.", + "durability": null, + "name": "Elegant shirt", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10750", + "equipment_slot": "4" + }, + { + "remove_sleeves": "true", + "examine": "Blouse: A well made elegant ladies' [colour] blouse.Skirt: A rather elegant [colour] skirt.Shirt: A well made elegant mans' [colour] shirt.Legs: A rather elegant [colour] pair of pantaloons.", + "durability": null, + "name": "Elegant shirt", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10752", + "equipment_slot": "4" + }, + { + "remove_sleeves": "true", + "examine": "Blouse: A well made elegant ladies' [colour] blouse.Skirt: A rather elegant [colour] skirt.Shirt: A well made elegant mans' [colour] shirt.Legs: A rather elegant [colour] pair of pantaloons.", + "durability": null, + "name": "Elegant shirt", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10754", + "equipment_slot": "4" + }, + { + "remove_sleeves": "true", + "examine": "Blouse: A well made elegant ladies' [colour] blouse.Skirt: A rather elegant [colour] skirt.Shirt: A well made elegant mans' [colour] shirt.Legs: A rather elegant [colour] pair of pantaloons.", + "durability": null, + "name": "Elegant shirt", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10756", + "equipment_slot": "4" + }, + { + "examine": "Stylish!", + "grand_exchange_price": "56600", + "durability": null, + "name": "Red boater", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10758", + "equipment_slot": "0" + }, + { + "examine": "Stylish!", + "grand_exchange_price": "20300", + "durability": null, + "name": "Orange boater", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10760", + "equipment_slot": "0" + }, + { + "examine": "Stylish!", + "grand_exchange_price": "59940", + "durability": null, + "name": "Green boater", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10762", + "equipment_slot": "0" + }, + { + "examine": "Stylish!", + "grand_exchange_price": "54236", + "durability": null, + "name": "Blue boater", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10764", + "equipment_slot": "0" + }, + { + "examine": "Stylish!", + "grand_exchange_price": "56495", + "durability": null, + "name": "Black boater", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10766", + "equipment_slot": "0" + }, + { + "lendable": "true", + "examine": "A minimalist's hat.", + "grand_exchange_price": "114319", + "durability": null, + "name": "Red headband", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10768", + "equipment_slot": "0" + }, + { + "lendable": "true", + "examine": "A minimalist's hat.", + "grand_exchange_price": "41778", + "durability": null, + "name": "Black headband", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10770", + "equipment_slot": "0" + }, + { + "lendable": "true", + "examine": "A minimalist's hat.", + "grand_exchange_price": "21764", + "durability": null, + "name": "Brown headband", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10772", + "equipment_slot": "0" + }, + { + "examine": "Shiver me timbers!", + "grand_exchange_price": "83200", + "durability": null, + "name": "Pirate's hat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10774", + "equipment_slot": "0" + }, + { + "requirements": "{1,40}", + "examine": "Rune platebody in the colours of Zamorak.", + "durability": null, + "weight": "9", + "absorb": "3,0,6", + "equip_audio": "2239", + "equipment_slot": "4", + "lendable": "true", + "remove_sleeves": "true", + "grand_exchange_price": "647800", + "name": "Zamorak platebody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10776", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,0,0,0,0,0" + }, + { + "requirements": "{1,40}", + "examine": "Rune platebody in the colours of Saradomin.", + "durability": null, + "weight": "9.07", + "absorb": "3,0,6", + "equipment_slot": "4", + "lendable": "true", + "remove_sleeves": "true", + "grand_exchange_price": "1097689", + "name": "Saradomin plate", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10778", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,0,0,0,0,0" + }, + { + "requirements": "{1,40}", + "examine": "Rune platebody in the colours of Guthix.", + "durability": null, + "weight": "9.07", + "absorb": "3,0,6", + "equip_audio": "2239", + "equipment_slot": "4", + "lendable": "true", + "remove_sleeves": "true", + "grand_exchange_price": "241600", + "name": "Guthix platebody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10780", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,0,0,0,0,0" + }, + { + "requirements": "{1,40}", + "examine": "Rune platebody with complete gold trim & plating.", + "durability": null, + "weight": "10", + "absorb": "3,0,6", + "equip_audio": "2239", + "equipment_slot": "4", + "lendable": "true", + "remove_sleeves": "true", + "grand_exchange_price": "1653821", + "name": "Gilded platebody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10782", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,0,0,0,0,0" + }, + { + "requirements": "{5,20}", + "remove_sleeves": "true", + "examine": "Blessed vestments of Saradomin.", + "grand_exchange_price": "106389", + "durability": null, + "name": "Saradomin robe top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10784", + "bonuses": "0,0,0,4,0,0,0,0,4,0,0,0,4,0,0", + "equipment_slot": "4" + }, + { + "requirements": "{5,20}", + "remove_sleeves": "true", + "examine": "Zamorak Vestments.", + "grand_exchange_price": "151000", + "durability": null, + "name": "Zamorak robe top", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10786", + "bonuses": "0,0,0,4,0,0,0,0,4,0,0,0,4,0,0", + "equipment_slot": "4" + }, + { + "requirements": "{5,20}", + "remove_sleeves": "true", + "examine": "Blessed vestments of Guthix.", + "grand_exchange_price": "80181", + "durability": null, + "name": "Guthix robe top", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10788", + "bonuses": "0,0,0,4,0,0,0,0,4,0,0,0,4,0,0", + "equipment_slot": "4" + }, + { + "requirements": "{1,40}-{4,70}", + "examine": "Zamorak blessed dragonhide body armour.", + "durability": null, + "weight": "6", + "absorb": "0,6,3", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "84966", + "name": "Zamorak d'hide", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10790", + "bonuses": "0,0,0,-15,30,55,47,60,50,55,0,0,0,0,0" + }, + { + "requirements": "{1,40}-{4,70}", + "shop_price": "13000", + "examine": "Saradomin blessed dragonhide body armour.", + "durability": null, + "destroy": "true", + "weight": "6", + "absorb": "0,6,3", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "92762", + "name": "Saradomin d'hide", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10792", + "bonuses": "0,0,0,-15,30,55,47,60,50,55,0,0,0,0,0" + }, + { + "requirements": "{1,40}-{4,70}", + "shop_price": "13", + "examine": "Guthix blessed dragonhide body armour.", + "durability": null, + "weight": "6", + "absorb": "0,6,3", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "22384", + "name": "Guthix dragonhide", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10794", + "bonuses": "0,0,0,-15,30,55,47,60,50,55,0,0,0,0,0" + }, + { + "lendable": "true", + "requirements": "{4,40}", + "examine": "Endorsed by Robin Hood.", + "grand_exchange_price": "3070557", + "durability": null, + "name": "Robin hood hat", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "10796", + "bonuses": "0,0,0,-10,8,4,6,8,4,4,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "requirements": "{1,40}", + "examine": "Rune platebody with gold trim.", + "durability": null, + "weight": "9.07", + "absorb": "3,0,6", + "equip_audio": "2239", + "equipment_slot": "4", + "lendable": "true", + "remove_sleeves": "true", + "grand_exchange_price": "231400", + "name": "Rune platebody (g)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10798", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,0,0,0,0,0" + }, + { + "requirements": "{1,40}", + "examine": "Rune platebody with trim.", + "durability": null, + "weight": "9.07", + "absorb": "3,0,6", + "equip_audio": "2239", + "equipment_slot": "4", + "lendable": "true", + "remove_sleeves": "true", + "grand_exchange_price": "61100", + "name": "Rune platebody (t)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10800", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,0,0,0,0,0" + }, + { + "lendable": "true", + "examine": "All for one and one for all!", + "grand_exchange_price": "56677", + "durability": null, + "name": "Tan cavalier", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10802", + "equipment_slot": "0" + }, + { + "lendable": "true", + "examine": "All for one and one for all!", + "grand_exchange_price": "18942", + "durability": null, + "name": "Dark cavalier", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10804", + "equipment_slot": "0" + }, + { + "lendable": "true", + "examine": "All for one and one for all!", + "grand_exchange_price": "421305", + "durability": null, + "name": "Black cavalier", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10806", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "1000", + "examine": "Arctic Pine logs prepared with sacred oil for a funeral pyre", + "grand_exchange_price": "3453", + "durability": null, + "name": "Arctic pyre logs", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "10808" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "3453", + "durability": null, + "name": "Arctic pyre logs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10809" + }, + { + "ge_buy_limit": "25000", + "examine": "Log cut from an arctic pine.", + "grand_exchange_price": "90", + "durability": null, + "name": "Arctic pine logs", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "10810", + "equipment_slot": "5" + }, + { + "ge_buy_limit": "25000", + "grand_exchange_price": "90", + "durability": null, + "name": "Arctic pine logs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10811" + }, + { + "ge_buy_limit": "1000", + "examine": "Used to repair bridges.", + "grand_exchange_price": "18", + "durability": null, + "name": "Split log", + "tradeable": "true", + "weight": "1.8", + "archery_ticket_price": "0", + "id": "10812" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "18", + "durability": null, + "name": "Split log", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10813" + }, + { + "shop_price": "120", + "ge_buy_limit": "1000", + "examine": "I can spin this into rope.", + "grand_exchange_price": "113", + "durability": null, + "name": "Hair", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10814" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "113", + "durability": null, + "name": "Hair", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10815" + }, + { + "shop_price": "2", + "ge_buy_limit": "1000", + "examine": "I need to cook this.", + "grand_exchange_price": "14", + "durability": null, + "name": "Raw yak meat", + "tradeable": "true", + "weight": "3", + "archery_ticket_price": "0", + "id": "10816" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "14", + "durability": null, + "name": "Raw yak meat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10817" + }, + { + "shop_price": "50", + "ge_buy_limit": "5000", + "examine": "Thakkrad, of Neitiznot, can cure this.", + "grand_exchange_price": "301", + "durability": null, + "name": "Yak-hide", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10818" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "301", + "durability": null, + "name": "Yak-hide", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10819" + }, + { + "ge_buy_limit": "5000", + "examine": "Ready to be cut and sewn into armour.", + "grand_exchange_price": "396", + "durability": null, + "name": "Cured yak-hide", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10820" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "396", + "durability": null, + "name": "Cured yak-hide", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10821" + }, + { + "requirements": "{1,20}", + "ge_buy_limit": "100", + "examine": "Smelly yak body armour.", + "durability": null, + "weight": "3", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "122", + "name": "Yak-hide armour", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10822", + "bonuses": "0,0,0,-5,0,25,20,15,-2,25,5,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "122", + "durability": null, + "name": "Yak-hide armour", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10823" + }, + { + "requirements": "{1,20}", + "ge_buy_limit": "100", + "grand_exchange_price": "83", + "examine": "Leg protection, made from smelly yak-hide.", + "durability": null, + "name": "Yak-hide armour", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "2", + "id": "10824", + "bonuses": "0,0,0,-5,10,25,20,15,-2,10,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "83", + "durability": null, + "name": "Yak-hide armour", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10825" + }, + { + "requirements": "{1,25}", + "ge_buy_limit": "100", + "examine": "A wooden shield with a rope rim.", + "durability": null, + "destroy": "true", + "weight": "3", + "equipment_slot": "5", + "grand_exchange_price": "402", + "name": "Fremennik round shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10826", + "bonuses": "0,0,0,-10,-10,17,17,31,-4,33,20,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "402", + "durability": null, + "name": "Fremennik round shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10827" + }, + { + "remove_head": "true", + "requirements": "{1,55}", + "shop_price": "50000", + "ge_buy_limit": "100", + "examine": "A gift from Neitiznot's Burgher.", + "durability": null, + "weight": "2.2", + "absorb": "2,0,4", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "44800", + "name": "Helm of neitiznot", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10828", + "bonuses": "0,0,0,0,0,31,29,34,3,30,8,3,3,0,0" + }, + { + "destroy_message": "King Sorvott of Jatizso will give you another one, grudgingly.", + "examine": "The document is stamped with King Gjuki Sorvott IV's royal seal.", + "durability": null, + "name": "Royal decree", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10830" + }, + { + "destroy_message": "Are you sure? You can replace it by talking to King Sorvott.", + "examine": "An empty tax bag.", + "durability": null, + "name": "Empty tax bag", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10831" + }, + { + "destroy_message": "Are you sure? You can find another in King Sorvott's chest.", + "examine": "A silly hat with bells.", + "durability": null, + "name": "Silly jester hat", + "tradeable": "false", + "destroy": "true", + "weight": "2.7", + "archery_ticket_price": "0", + "id": "10836", + "bonuses": "0,0,0,0,0,0,0,0,5,-5,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "destroy_message": "Are you sure? You can find another in King Sorvott's chest.", + "remove_sleeves": "true", + "examine": "A jester's jangly top.", + "durability": null, + "name": "Silly jester top", + "tradeable": "false", + "destroy": "true", + "weight": "6.8", + "archery_ticket_price": "0", + "id": "10837", + "bonuses": "0,0,0,0,0,0,0,0,5,-5,5,0,0,0,0", + "equipment_slot": "4" + }, + { + "destroy_message": "Are you sure? You can find another in King Sorvott's chest.", + "examine": "Silly jester tights.", + "durability": null, + "name": "Silly jester tights", + "tradeable": "false", + "destroy": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "10838", + "bonuses": "0,0,0,0,0,0,0,0,5,-5,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "destroy_message": "Are you sure? You can find another in King Sorvott's chest.", + "examine": "Silly jester boots.", + "durability": null, + "name": "Silly jester boots", + "tradeable": "false", + "destroy": "true", + "weight": "1.3", + "archery_ticket_price": "0", + "id": "10839", + "bonuses": "0,0,0,0,0,0,0,0,5,-5,0,0,0,0,0", + "equipment_slot": "10" + }, + { + "durability": null, + "name": "A jester stick", + "archery_ticket_price": "0", + "id": "10840", + "bonuses": "0,0,0,0,0,0,0,0,5,-5,0,0,0,0,0", + "alchemizable": "true", + "equipment_slot": "3" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "No brain: A gruesome, decapitated head, whose brain has rotted away. Brain: A gruesome, decapitated head - its eyes stare lifelessly at nothing.", + "durability": null, + "name": "Decapitated head", + "weight": "3", + "archery_ticket_price": "0", + "id": "10842" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "44800", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Helm of neitiznot", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10843" + }, + { + "examine": "A slightly sq'irky, I mean quirky, fruit.", + "durability": null, + "name": "Spring sq'irk", + "archery_ticket_price": "0", + "id": "10844" + }, + { + "examine": "A slightly sq'irky, I mean quirky, fruit.", + "durability": null, + "name": "Summer sq'irk", + "archery_ticket_price": "0", + "id": "10845" + }, + { + "examine": "A slightly sq'irky, I mean quirky, fruit.", + "durability": null, + "name": "Autumn sq'irk", + "archery_ticket_price": "0", + "id": "10846" + }, + { + "examine": "A slightly sq'irky, I mean quirky, fruit.", + "durability": null, + "name": "Winter sq'irk", + "archery_ticket_price": "0", + "id": "10847" + }, + { + "examine": "Made from 4 spring sq'irks.", + "durability": null, + "name": "Spring sq'irkjuice", + "weight": "1", + "archery_ticket_price": "0", + "id": "10848" + }, + { + "examine": "Made from 2 summer sq'irks.", + "durability": null, + "name": "Summer sq'irkjuice", + "weight": "1", + "archery_ticket_price": "0", + "id": "10849" + }, + { + "examine": "Made from 3 autumn sq'irks.", + "durability": null, + "name": "Autumn sq'irkjuice", + "weight": "1", + "archery_ticket_price": "0", + "id": "10850" + }, + { + "examine": "Made from 5 winter sq'irks.", + "durability": null, + "name": "Winter sq'irkjuice", + "archery_ticket_price": "0", + "id": "10851" + }, + { + "destroy_message": "You will need to speak to Sin Seer in Seers' Village to get another one.", + "shop_price": "40", + "examine": "Her writing is too scrawled to make out what it says.", + "durability": null, + "name": "Sin seer's note", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10856" + }, + { + "destroy_message": "You will need to speak to General Khazard, near the Fremennik Province, to get another.", + "examine": "A severed human leg.", + "durability": null, + "name": "Severed leg", + "tradeable": "false", + "destroy": "true", + "weight": "12", + "archery_ticket_price": "0", + "id": "10857" + }, + { + "turn90cw_anim": "7044", + "examine": "A shadow sword.", + "walk_anim": "7046", + "durability": null, + "destroy": "true", + "weight": "3.6", + "turn90ccw_anim": "7043", + "attack_speed": "7", + "two_handed": "true", + "weapon_interface": "7", + "turn180_anim": "7045", + "equip_audio": "2248", + "render_anim": "124", + "equipment_slot": "3", + "destroy_message": "You can get another one by visiting the cave near the Fishing guild. A friendly ghost will replace it for you. You must be wearing a Ring of visibility, or you cannot get it back.", + "stand_anim": "7047", + "name": "Shadow sword", + "tradeable": "false", + "run_anim": "7039", + "archery_ticket_price": "0", + "id": "10858", + "stand_turn_anim": "7040", + "bonuses": "-4,27,21,4,0,0,0,0,4,-1,0,26,0,0,0" + }, + { + "examine": "You can put nice, hot tea in it.", + "durability": null, + "name": "Tea flask", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "10859" + }, + { + "examine": "You can put nice, hot tea in it.", + "durability": null, + "name": "Tea flask", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "10860" + }, + { + "examine": "You can put nice, hot tea in it.", + "durability": null, + "name": "Tea flask", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "10861" + }, + { + "destroy_message": "You'll have to find another within the Tower of Life!", + "examine": "Can't get any safer than this.", + "durability": null, + "name": "Hard hat", + "tradeable": "false", + "destroy": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "10862", + "equipment_slot": "0" + }, + { + "destroy_message": "You'll have to find another within the Tower of Life!", + "remove_sleeves": "true", + "examine": "Very fetching.", + "durability": null, + "name": "Builder's shirt", + "tradeable": "false", + "destroy": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "10863", + "equipment_slot": "4" + }, + { + "destroy_message": "You'll have to find another within the Tower of Life!", + "examine": "Slightly tatty in my opinion.", + "durability": null, + "name": "Builder's trousers", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10864", + "equipment_slot": "7" + }, + { + "destroy_message": "You'll have to find another within the Tower of Life!", + "examine": "They'll offer good protection for my toes.", + "durability": null, + "name": "Builder's boots", + "tradeable": "false", + "destroy": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10865", + "equipment_slot": "10" + }, + { + "examine": "Used to bolt things together.", + "durability": null, + "name": "Rivets", + "archery_ticket_price": "0", + "id": "10866" + }, + { + "examine": "Some magical fluid to bind surfaces.", + "durability": null, + "name": "Binding fluid", + "archery_ticket_price": "0", + "id": "10870" + }, + { + "examine": "A pipe that belongs in a cannon stand.", + "durability": null, + "name": "Pipe", + "tradeable": "false", + "destroy": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "10871" + }, + { + "examine": "A ring used to join two pipes together.", + "durability": null, + "name": "Pipe ring", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10872" + }, + { + "examine": "A sheet of metal.", + "durability": null, + "name": "Metal sheet", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10873" + }, + { + "examine": "Bound to have some use.", + "durability": null, + "name": "Coloured ball", + "archery_ticket_price": "0", + "id": "10874" + }, + { + "examine": "A wheel used to control valves.", + "durability": null, + "name": "Valve wheel", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10875" + }, + { + "examine": "Some unknown metal substance.", + "durability": null, + "name": "Metal bar", + "archery_ticket_price": "0", + "id": "10876" + }, + { + "shop_price": "128", + "examine": "I can keep my grub in here.", + "durability": null, + "name": "Plain satchel", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "10877", + "equipment_slot": "5" + }, + { + "examine": "I can keep my grub in here.", + "durability": null, + "name": "Green satchel", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "10878", + "equipment_slot": "5" + }, + { + "shop_price": "128", + "examine": "I can keep my grub in here.", + "durability": null, + "name": "Red satchel", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "10879", + "equipment_slot": "5" + }, + { + "examine": "I can keep my grub in here.", + "durability": null, + "name": "Black satchel", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "10880", + "equipment_slot": "5" + }, + { + "examine": "I can keep my grub in here.", + "durability": null, + "name": "Gold satchel", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "10881", + "equipment_slot": "5" + }, + { + "examine": "I can keep my grub in here.", + "durability": null, + "name": "Rune satchel", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "10882", + "equipment_slot": "5" + }, + { + "destroy_message": "You'll have to find another within the Tower of Life!", + "examine": "Can't get any safer than this.", + "durability": null, + "name": "Hard hat", + "tradeable": "false", + "destroy": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "10883", + "equipment_slot": "0" + }, + { + "examine": "A fuse.", + "durability": null, + "name": "Fuse", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10884" + }, + { + "examine": "A small keg of gunpowder.", + "durability": null, + "name": "Keg", + "weight": "12", + "archery_ticket_price": "0", + "id": "10885" + }, + { + "examine": "Used to cure poison through prayer.", + "durability": null, + "name": "Prayer book", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10886" + }, + { + "turn90cw_anim": "5867", + "examine": "This is likely to put my back out... (when fixed) OR It's broken. I should see if a pirate smith can fix it. (when broken)", + "walk_anim": "5867", + "has_special": "true", + "durability": null, + "weight": "30", + "turn90ccw_anim": "5867", + "attack_speed": "6", + "two_handed": "true", + "weapon_interface": "8", + "turn180_anim": "5867", + "equip_audio": "2246", + "defence_anim": "5866", + "render_anim": "985", + "equipment_slot": "3", + "attack_anims": "5865,5865,5865,5865", + "destroy_message": "If you drop the Anchor it will be destroyed, and you will need to get a new one from Brother Tranquillity, then pay Smith to re", + "stand_anim": "5869", + "name": "Barrelchest anchor", + "run_anim": "5868", + "archery_ticket_price": "0", + "id": "10887", + "stand_turn_anim": "823", + "bonuses": "-2,10,92,0,0,0,0,0,0,0,0,100,0,0,0" + }, + { + "examine": "This is likely to put my back out... (when fixed) OR It's broken. I should see if a pirate smith can fix it. (when broken)", + "durability": null, + "name": "Barrelchest anchor", + "weight": "30", + "archery_ticket_price": "0", + "attack_speed": "6", + "id": "10888", + "bonuses": "-2,10,92,0,0,0,0,0,0,0,0,100,0,0,0" + }, + { + "destroy_message": "If you drop this lamp it will be destroyed, and you will need to see Brother Tranquility for another.", + "examine": "This will answer my prayers.", + "durability": null, + "name": "Blessed lamp", + "archery_ticket_price": "0", + "id": "10889" + }, + { + "destroy_message": "This book is old and delicate. You can reclaim this item from the place you found it.ping it here will destroy it and you will have to search the Edgeville Monastery bookcase for another.", + "examine": "Used to cure poison through prayer.", + "durability": null, + "name": "Prayer book", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10890" + }, + { + "ge_buy_limit": "100", + "examine": "A wooden cat toy.", + "grand_exchange_price": "922", + "durability": null, + "name": "Wooden cat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10891" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "922", + "durability": null, + "name": "Wooden cat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10892" + }, + { + "examine": "A cranial clamp.", + "durability": null, + "name": "Cranial clamp", + "archery_ticket_price": "0", + "id": "10893" + }, + { + "examine": "Some tongs for use with brains.", + "durability": null, + "name": "Brain tongs", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10894" + }, + { + "examine": "A bell jar for covering things.", + "durability": null, + "name": "Bell jar", + "weight": "1", + "archery_ticket_price": "0", + "id": "10895" + }, + { + "examine": "A silver whistle.", + "durability": null, + "name": "Wolf whistle", + "archery_ticket_price": "0", + "id": "10896" + }, + { + "examine": "A shipping order list.", + "durability": null, + "name": "Shipping order", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10897" + }, + { + "examine": "A small keg of gunpowder.", + "durability": null, + "name": "Keg", + "weight": "12", + "archery_ticket_price": "0", + "id": "10898" + }, + { + "examine": "Part of a crate.", + "durability": null, + "name": "Crate part", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10899" + }, + { + "examine": "One skull staple.", + "durability": null, + "name": "Skull staple", + "archery_ticket_price": "0", + "id": "10904" + }, + { + "ge_buy_limit": "100", + "examine": "This super restore and unicorn dust potion needs more ingredients.", + "grand_exchange_price": "8420", + "durability": null, + "name": "Mixture - step 1(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10909" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "8420", + "durability": null, + "name": "Mixture - step 1(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10910" + }, + { + "ge_buy_limit": "100", + "examine": "This super restore and unicorn dust potion needs more ingredients.", + "grand_exchange_price": "6543", + "durability": null, + "name": "Mixture - step 1(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10911" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "6543", + "durability": null, + "name": "Mixture - step 1(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10912" + }, + { + "ge_buy_limit": "100", + "examine": "This super restore and unicorn dust potion needs more ingredients.", + "grand_exchange_price": "4335", + "durability": null, + "name": "Mixture - step 1(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10913" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "4335", + "durability": null, + "name": "Mixture - step 1(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10914" + }, + { + "ge_buy_limit": "100", + "examine": "This super restore and unicorn dust potion needs more ingredients.", + "grand_exchange_price": "2168", + "durability": null, + "name": "Mixture - step 1(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10915" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2168", + "durability": null, + "name": "Mixture - step 1(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10916" + }, + { + "ge_buy_limit": "100", + "examine": "This super restore, unicorn dust, snake weed potion needs more ingredients.", + "grand_exchange_price": "8665", + "durability": null, + "name": "Mixture - step 2(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10917" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "8665", + "durability": null, + "name": "Mixture - step 2(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10918" + }, + { + "ge_buy_limit": "100", + "examine": "This super restore, unicorn dust, snake weed potion needs more ingredients.", + "grand_exchange_price": "6695", + "durability": null, + "name": "Mixture - step 2(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10919" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "6695", + "durability": null, + "name": "Mixture - step 2(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10920" + }, + { + "ge_buy_limit": "100", + "examine": "This super restore, unicorn dust, snake weed potion needs more ingredients.", + "grand_exchange_price": "4335", + "durability": null, + "name": "Mixture - step 2(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10921" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "4335", + "durability": null, + "name": "Mixture - step 2(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10922" + }, + { + "ge_buy_limit": "100", + "examine": "This super restore, unicorn dust, snake weed potion needs more ingredients.", + "grand_exchange_price": "2168", + "durability": null, + "name": "Mixture - step 2(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10923" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2168", + "durability": null, + "name": "Mixture - step 2(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10924" + }, + { + "ge_buy_limit": "100", + "examine": "A \"X\" dose Sanfew Serum.", + "grand_exchange_price": "15900", + "durability": null, + "name": "Sanfew serum(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10925" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "15900", + "durability": null, + "name": "Sanfew serum(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10926" + }, + { + "ge_buy_limit": "100", + "examine": "A \"X\" dose Sanfew Serum.", + "grand_exchange_price": "12000", + "durability": null, + "name": "Sanfew serum(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10927" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "12000", + "durability": null, + "name": "Sanfew serum(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10928" + }, + { + "ge_buy_limit": "100", + "examine": "A \"X\" dose Sanfew Serum.", + "grand_exchange_price": "10200", + "durability": null, + "name": "Sanfew serum(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10929" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "10200", + "durability": null, + "name": "Sanfew serum(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10930" + }, + { + "ge_buy_limit": "100", + "examine": "A \"X\" dose Sanfew Serum.", + "grand_exchange_price": "6114", + "durability": null, + "name": "Sanfew serum(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10931" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "6114", + "durability": null, + "name": "Sanfew serum(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10932" + }, + { + "examine": "You certainly will be alright wearing these.", + "durability": null, + "name": "Lumberjack boots", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "10933", + "equip_audio": "2237", + "equipment_slot": "10" + }, + { + "destroy_message": "Warning! If you destroy this item, you will lose ALL rewards that it relates to and you will have to make another trek in order to get another one.", + "examine": "Blue/Red/Yellow reward token exchanged at Burgh de Rott/Paterdomus.", + "durability": null, + "name": "Reward token", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10934" + }, + { + "destroy_message": "Warning! If you destroy this item, you will lose ALL rewards that it relates to and you will have to make another trek in order to get another one.", + "examine": "Blue/Red/Yellow reward token exchanged at Burgh de Rott/Paterdomus.", + "durability": null, + "name": "Reward token", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10935" + }, + { + "destroy_message": "Warning! If you destroy this item, you will lose ALL rewards that it relates to and you will have to make another trek in order to get another one.", + "examine": "Blue/Red/Yellow reward token exchanged at Burgh de Rott/Paterdomus.", + "durability": null, + "name": "Reward token", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10936" + }, + { + "ge_buy_limit": "100", + "examine": "The claws from a nail beast", + "grand_exchange_price": "203", + "durability": null, + "name": "Nail beast nails", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10937" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "203", + "durability": null, + "name": "Nail beast nails", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10938" + }, + { + "remove_sleeves": "true", + "examine": "You certainly will be alright wearing this.", + "durability": null, + "name": "Lumberjack top", + "weight": "1.3", + "archery_ticket_price": "0", + "id": "10939", + "equipment_slot": "4" + }, + { + "examine": "You certainly will be alright wearing these.", + "durability": null, + "name": "Lumberjack legs", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "10940", + "equipment_slot": "7" + }, + { + "remove_head": "true", + "examine": "You certainly will be alright wearing this.", + "durability": null, + "name": "Lumberjack hat", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "10941", + "equipment_slot": "0" + }, + { + "destroy_message": "Warning! If you destroy this item, you will lose ALL rewards that it relates to and you will have to make another trek in order to get another one.", + "examine": "Blue/Red/Yellow reward token exchanged at Burgh de Rott/Paterdomus.", + "durability": null, + "name": "Reward token", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10942" + }, + { + "destroy_message": "Warning! If you destroy this item, you will lose ALL rewards that it relates to and you will have to make another trek in order to get another one.", + "examine": "Blue/Red/Yellow reward token exchanged at Burgh de Rott/Paterdomus.", + "durability": null, + "name": "Reward token", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10943" + }, + { + "destroy_message": "Warning! If you destroy this item, you will lose ALL rewards that it relates to and you will have to make another trek in order to get another one.", + "examine": "Blue/Red/Yellow reward token exchanged at Burgh de Rott/Paterdomus.", + "durability": null, + "name": "Reward token", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10944" + }, + { + "remove_sleeves": "true", + "examine": "You certainly will be alright wearing this.", + "durability": null, + "name": "Lumberjack top", + "weight": "1.3", + "archery_ticket_price": "0", + "id": "10945", + "equipment_slot": "4" + }, + { + "examine": "One skull staple.", + "durability": null, + "name": "Skull staples", + "archery_ticket_price": "0", + "id": "10950" + }, + { + "examine": "One skull staple.", + "durability": null, + "name": "Skull staples", + "archery_ticket_price": "0", + "id": "10951" + }, + { + "requirements": "{18,39}", + "shop_price": "150", + "ge_buy_limit": "100", + "examine": "Don't make anyone jump when you ring this!", + "grand_exchange_price": "57", + "durability": null, + "name": "Slayer bell", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10952" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "57", + "durability": null, + "name": "Slayer bell", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10953" + }, + { + "requirements": "{1,25}-{4,25}", + "shop_price": "1000", + "ge_buy_limit": "100", + "examine": "Armour made out of Frog hide.", + "durability": null, + "weight": "3", + "absorb": "0,3,1", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "1797", + "name": "Frog-leather body", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10954", + "bonuses": "0,0,0,-5,10,23,26,30,15,32,20,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1797", + "durability": null, + "name": "Frog-leather body", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10955" + }, + { + "requirements": "{1,25}-{4,25}", + "shop_price": "900", + "ge_buy_limit": "100", + "examine": "Chaps made out of Frog hide.", + "durability": null, + "weight": "3", + "absorb": "0,2,1", + "equipment_slot": "7", + "grand_exchange_price": "361", + "name": "Frog-leather chaps", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10956", + "bonuses": "0,0,0,-5,2,7,7,9,4,9,5,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "361", + "durability": null, + "name": "Frog-leather chaps", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10957" + }, + { + "requirements": "{1,25}-{4,25}", + "shop_price": "200", + "ge_buy_limit": "100", + "examine": "Boots made out of Frog hide.", + "durability": null, + "weight": "1", + "equipment_slot": "10", + "grand_exchange_price": "1156", + "name": "Frog-leather boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10958", + "bonuses": "0,0,0,-8,2,1,1,1,0,1,0,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1156", + "durability": null, + "name": "Frog-leather boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10959" + }, + { + "shop_price": "10", + "examine": "Thick and tasty soup.", + "durability": null, + "name": "Green gloop soup", + "archery_ticket_price": "0", + "id": "10960" + }, + { + "shop_price": "10", + "examine": "A big bowl of frogspawn gumbo.", + "durability": null, + "name": "Frogspawn gumbo", + "archery_ticket_price": "0", + "id": "10961" + }, + { + "shop_price": "10", + "examine": "A juicy frogburger.", + "durability": null, + "name": "Frogburger", + "weight": "1", + "archery_ticket_price": "0", + "id": "10962" + }, + { + "examine": "Nice and crunchy.", + "durability": null, + "name": "Coated frogs' legs", + "archery_ticket_price": "0", + "id": "10963" + }, + { + "shop_price": "10", + "examine": "Bat shish kebab.", + "durability": null, + "name": "Bat shish", + "archery_ticket_price": "0", + "id": "10964" + }, + { + "shop_price": "10", + "examine": "Wall beast fingers in a white fern sauce.", + "durability": null, + "name": "Fingers", + "archery_ticket_price": "0", + "id": "10965" + }, + { + "examine": "A whole roasted frog.", + "durability": null, + "name": "Roast frog", + "weight": "1", + "archery_ticket_price": "0", + "id": "10967" + }, + { + "examine": "Tasty saut??ed mushrooms.", + "durability": null, + "name": "Mushrooms", + "archery_ticket_price": "0", + "id": "10968" + }, + { + "examine": "Chunky cave-crawler fillets.", + "durability": null, + "name": "Fillets", + "archery_ticket_price": "0", + "id": "10969" + }, + { + "examine": "Steamed cave pond loach.", + "durability": null, + "name": "Loach", + "weight": "1", + "archery_ticket_price": "0", + "id": "10970" + }, + { + "examine": "Cave-eel sushi.", + "durability": null, + "name": "Eel sushi", + "archery_ticket_price": "0", + "id": "10971" + }, + { + "shop_price": "2", + "examine": "Oldak's Marvellous Moving-Over-Distance Sphere.", + "durability": null, + "name": "Dorgesh-kaan sphere", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "10972" + }, + { + "requirements": "{11,52}", + "ge_buy_limit": "1000", + "examine": "A component of cave goblin Magic.", + "grand_exchange_price": "90", + "durability": null, + "name": "Light orb", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10973" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "90", + "durability": null, + "name": "Light orb", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10974" + }, + { + "examine": "A goblin wrench.", + "durability": null, + "name": "Spanner", + "weight": "1", + "archery_ticket_price": "0", + "id": "10975" + }, + { + "shop_price": "1000", + "examine": "A Construction bone.", + "durability": null, + "name": "Long bone", + "weight": "1", + "archery_ticket_price": "0", + "id": "10976" + }, + { + "shop_price": "2000", + "examine": "A curved Construction bone.", + "durability": null, + "name": "Curved bone", + "weight": "1", + "archery_ticket_price": "0", + "id": "10977" + }, + { + "ge_buy_limit": "500", + "examine": "Swamp weed found in the caves near Dorgesh-Kaan.", + "grand_exchange_price": "292", + "durability": null, + "name": "Swamp weed", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "10978" + }, + { + "ge_buy_limit": "500", + "grand_exchange_price": "292", + "durability": null, + "name": "Swamp weed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10979" + }, + { + "examine": "Add a wire to complete it.", + "durability": null, + "name": "Empty light orb", + "archery_ticket_price": "0", + "id": "10980" + }, + { + "ge_buy_limit": "1000", + "examine": "Wire found in Dorgesh-Kaan.", + "grand_exchange_price": "988", + "durability": null, + "name": "Cave goblin wire", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10981" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "988", + "durability": null, + "name": "Cave goblin wire", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "10982" + }, + { + "destroy_message": "You can get another cog from the old power station.", + "shop_price": "160", + "examine": "A cog. Broken: A broken cog.", + "durability": null, + "name": "Cog", + "tradeable": "false", + "destroy": "true", + "weight": "3", + "archery_ticket_price": "0", + "id": "10983" + }, + { + "destroy_message": "You can get another cog from the old power station.", + "shop_price": "160", + "examine": "A cog. Broken: A broken cog.", + "durability": null, + "name": "Cog", + "tradeable": "false", + "destroy": "true", + "weight": "3", + "archery_ticket_price": "0", + "id": "10984" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A fuse.", + "durability": null, + "name": "Fuse", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10985" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A fuse.", + "durability": null, + "name": "Fuse", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10986" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A meter.", + "durability": null, + "name": "Meter", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10987" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A meter.", + "durability": null, + "name": "Meter", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "10988" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A capacitor.", + "durability": null, + "name": "Capacitor", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10989" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A capacitor.", + "durability": null, + "name": "Capacitor", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "10990" + }, + { + "destroy_message": "You can get another power box from the old power station.", + "examine": "A powerbox. Broken: A broken powerbox.", + "durability": null, + "name": "Powerbox", + "tradeable": "false", + "destroy": "true", + "weight": "3", + "archery_ticket_price": "0", + "id": "10993" + }, + { + "destroy_message": "You can get another power box from the old power station.", + "examine": "A powerbox. Broken: A broken powerbox.", + "durability": null, + "name": "Powerbox", + "tradeable": "false", + "destroy": "true", + "weight": "3", + "archery_ticket_price": "0", + "id": "10994" + }, + { + "examine": "A perfect example of a tortoise shell.", + "durability": null, + "name": "Perfect shell", + "weight": "6.8", + "archery_ticket_price": "0", + "id": "10995" + }, + { + "examine": "A perfect example of a snail shell.", + "durability": null, + "name": "Perfect snail shell", + "weight": "7", + "archery_ticket_price": "0", + "id": "10996" + }, + { + "examine": "On wall: That white dot looks like an eye! Off wall: A strange mole-like being.", + "durability": null, + "name": "Molanisk", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "10997" + }, + { + "examine": "One of the many citizens of Dorgesh-Kaan.", + "durability": null, + "name": "Cave goblin", + "archery_ticket_price": "0", + "id": "10998" + }, + { + "examine": "A tattered goblin holy book.", + "durability": null, + "name": "Goblin book", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "10999" + }, + { + "destroy_message": "You will need to get another copy from the Varrock Palace Library if you destroy this one.", + "examine": "The History of Dagon'hai.", + "durability": null, + "name": "Dagon'hai history", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11001" + }, + { + "destroy_message": "You will need to get another copy from the Varrock Palace Library if you destroy this one.", + "examine": "The diary of Sin'keth Magis.", + "durability": null, + "name": "Sin'keth's diary", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11002" + }, + { + "destroy_message": "You will need to ask Rat for another empty folder if you destroy this one.", + "examine": "A folder for Rat's papers.", + "durability": null, + "name": "An empty folder", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11003" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A folder for rat's papers. It needs more pages.", + "durability": null, + "name": "Used folder", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11006" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A full folder. You should take this back to Rat.", + "durability": null, + "name": "Full folder", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11007" + }, + { + "destroy_message": "You will need to find more papers about the outlaws if you destroy this.", + "examine": "A page of Rat's document.", + "durability": null, + "name": "Rat's paper", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11008" + }, + { + "destroy_message": "You will need to get another copy of the letter from Rat if you destroy this.", + "shop_price": "160", + "examine": "A letter in a strange language.", + "durability": null, + "name": "Rat's letter", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11009" + }, + { + "destroy_message": "You will need to ask Surok for another letter to Rat if you destroy this.", + "shop_price": "27", + "examine": "A letter.", + "durability": null, + "name": "Surok's letter", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11010" + }, + { + "examine": "Instructions for the beacon ring.", + "durability": null, + "name": "Zaff's instructions", + "archery_ticket_price": "0", + "id": "11011" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A wand.", + "durability": null, + "name": "Wand", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11012", + "equipment_slot": "3" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "This wand is glowing with chaos magic.", + "durability": null, + "name": "Infused wand", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11013", + "equipment_slot": "3" + }, + { + "destroy_message": "You will need to get another ring from Zaff if you destroy this one.", + "examine": "A magical ring.", + "durability": null, + "name": "Beacon ring", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11014", + "bonuses": "0,0,0,2,0,0,0,0,1,0,0,0,0,0,0", + "equipment_slot": "12" + }, + { + "remove_head": "true", + "examine": "Cock-a-doodle-do!", + "durability": null, + "name": "Chicken head", + "tradeable": "false", + "destroy": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "11015", + "equipment_slot": "0" + }, + { + "examine": "Perfect for crossing the road.", + "durability": null, + "name": "Chicken feet", + "tradeable": "false", + "destroy": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "11016", + "equipment_slot": "10" + }, + { + "remove_sleeves": "true", + "examine": "I look fowl in this.", + "durability": null, + "name": "Chicken wings", + "tradeable": "false", + "destroy": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "11017", + "equipment_slot": "4" + }, + { + "examine": "What's the matter, are you chicken?", + "durability": null, + "name": "Chicken legs", + "tradeable": "false", + "destroy": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "11018", + "equipment_slot": "7" + }, + { + "destroy_message": "You will need to speak to Diango to get another pair of chicken feet.", + "examine": "Perfect for crossing the road.", + "durability": null, + "name": "Chicken feet", + "tradeable": "false", + "destroy": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "11019", + "equipment_slot": "10" + }, + { + "destroy_message": "You will need to speak to Diango to get another set of chicken wings.", + "remove_sleeves": "true", + "examine": "I look fowl in this.", + "durability": null, + "name": "Chicken wings", + "tradeable": "false", + "destroy": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "11020", + "equipment_slot": "4" + }, + { + "remove_head": "true", + "destroy_message": "You will need to speak to Diango to get another chicken head.", + "examine": "Cock-a-doodle-do!", + "durability": null, + "name": "Chicken head", + "tradeable": "false", + "destroy": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "11021", + "equipment_slot": "0" + }, + { + "destroy_message": "You will need to speak to Diango to get another set of chicken legs.", + "examine": "What's the matter, are you chicken?", + "durability": null, + "name": "Chicken legs", + "tradeable": "false", + "destroy": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "11022", + "equipment_slot": "7" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Let's see how far the rabbit hole goes.", + "durability": null, + "name": "Magic egg", + "archery_ticket_price": "0", + "id": "11023" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Used for making chocolate rabbits.", + "durability": null, + "name": "Rabbit mould", + "archery_ticket_price": "0", + "id": "11024" + }, + { + "examine": "Some chocolate chunks.", + "durability": null, + "name": "Chocolate chunks", + "archery_ticket_price": "0", + "id": "11025" + }, + { + "examine": "Chocolatey kebbit goodness.", + "durability": null, + "name": "Chocolate kebbit", + "archery_ticket_price": "0", + "id": "11026" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Happy Easter.", + "grand_exchange_price": "64747137", + "durability": null, + "name": "Easter egg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11027", + "equipment_slot": "3" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Happy Easter.", + "grand_exchange_price": "64747137", + "durability": null, + "name": "Easter egg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11028", + "equipment_slot": "3" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Happy Easter.", + "grand_exchange_price": "64747137", + "durability": null, + "name": "Easter egg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11029", + "equipment_slot": "3" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Happy Easter.", + "grand_exchange_price": "64747137", + "durability": null, + "name": "Easter egg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11030", + "equipment_slot": "3" + }, + { + "destroy_message": "These logs will be destroyed if you drop them and you will need to see Olaf Hradson to get some more.", + "examine": "A number of dripping, waterlogged planks.", + "durability": null, + "name": "Damp planks", + "archery_ticket_price": "0", + "id": "11031" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A log with some squiggles carved into it.", + "durability": null, + "name": "Crude carving", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11032" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Another log with some sort of bird hacked into it.", + "durability": null, + "name": "Cruder carving", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11033" + }, + { + "destroy_message": "This map will be destroyed if you drop it and you will need to see Olaf Hradson to get another.", + "examine": "A faded map marking a cross next to a section of the landscape.", + "durability": null, + "name": "Sven's last map", + "archery_ticket_price": "0", + "id": "11034" + }, + { + "destroy_message": "These logs will be destroyed if you drop them and you will need to chop more from the windswept tree.", + "examine": "Logs taken from the exotic-looking windswept tree.", + "durability": null, + "name": "Windswept logs", + "archery_ticket_price": "0", + "id": "11035" + }, + { + "requirements": "{0,40}", + "ge_buy_limit": "100", + "examine": "A salty sword.", + "has_special": "true", + "durability": null, + "weight": "1.8", + "attack_speed": "4", + "weapon_interface": "6", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "grand_exchange_price": "120200", + "name": "Brine sabre", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11037", + "bonuses": "7,47,-2,0,0,0,0,0,0,0,0,46,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "120200", + "durability": null, + "name": "Brine sabre", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11038" + }, + { + "examine": "Looks like it might still float.", + "durability": null, + "name": "Rotten barrel", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11044" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Looks like it might still float.", + "durability": null, + "name": "Rotten barrel", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11045" + }, + { + "shop_price": "18", + "examine": "A coil of rope.", + "grand_exchange_price": "101", + "durability": null, + "name": "Rope", + "tradeable": "true", + "weight": "1.3", + "archery_ticket_price": "0", + "id": "11046" + }, + { + "examine": "Eww, a bald rat!", + "durability": null, + "name": "Brine rat", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "11047" + }, + { + "examine": "A piece of ancient goblin armour.", + "durability": null, + "name": "Armour shard", + "archery_ticket_price": "0", + "id": "11048" + }, + { + "examine": "An ancient goblin object encrusted in dirt.", + "durability": null, + "name": "Artefact", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11049" + }, + { + "shop_price": "1", + "examine": "It's missing a handle.", + "durability": null, + "name": "Axe head", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11050" + }, + { + "examine": "An ancient goblin object encrusted in dirt.", + "durability": null, + "name": "Artefact", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11051" + }, + { + "examine": "A piece of ancient goblin helmet.", + "durability": null, + "name": "Helmet fragment", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11052" + }, + { + "examine": "An ancient goblin object encrusted in dirt.", + "durability": null, + "name": "Artefact", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11053" + }, + { + "examine": "A piece of an ancient goblin shield.", + "durability": null, + "name": "Shield fragment", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11054" + }, + { + "examine": "An ancient goblin object encrusted in dirt.", + "durability": null, + "name": "Artefact", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11055" + }, + { + "examine": "A piece of an ancient goblin sword.", + "durability": null, + "name": "Sword fragment", + "archery_ticket_price": "0", + "id": "11056" + }, + { + "examine": "An ancient goblin object encrusted in dirt.", + "durability": null, + "name": "Artefact", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11057" + }, + { + "durability": null, + "attack_audios": "2508,2508,25092508", + "name": "Mace", + "archery_ticket_price": "0", + "attack_speed": "5", + "id": "11058" + }, + { + "examine": "An ancient goblin object encrusted in dirt.", + "durability": null, + "name": "Artefact", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11059" + }, + { + "shop_price": "2", + "examine": "Oldak's marvellous Moving-over-distance Sphere", + "durability": null, + "name": "Goblin village sphere", + "weight": "0.05", + "archery_ticket_price": "0", + "id": "11060" + }, + { + "requirements": "{0,25}-{5,15}", + "shop_price": "1000", + "ge_buy_limit": "100", + "examine": "It has ancient goblin symbols on it.", + "has_special": "true", + "durability": null, + "weight": "1.8", + "attack_speed": "5", + "weapon_interface": "8", + "equip_audio": "2246", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "grand_exchange_price": "4093", + "attack_audios": "2508,2508,25092508", + "name": "Ancient mace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11061", + "bonuses": "10,-2,16,0,0,0,0,0,0,0,0,14,3,0,0" + }, + { + "durability": null, + "name": "Ancient mace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11064" + }, + { + "shop_price": "5", + "ge_buy_limit": "100", + "examine": "Used to make gold bracelets.", + "grand_exchange_price": "456", + "durability": null, + "name": "Bracelet mould", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "11065" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "456", + "durability": null, + "name": "Bracelet mould", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11066" + }, + { + "shop_price": "165", + "ge_buy_limit": "5000", + "examine": "I wonder if this is valuable.", + "grand_exchange_price": "223", + "durability": null, + "name": "Gold bracelet", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "11069", + "equipment_slot": "9" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "223", + "durability": null, + "name": "Gold bracelet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11070" + }, + { + "shop_price": "1035", + "ge_buy_limit": "5000", + "examine": "I wonder if this is valuable.", + "grand_exchange_price": "578", + "durability": null, + "name": "Sapphire bracelet", + "tradeable": "true", + "weight": "0.25", + "archery_ticket_price": "0", + "id": "11072", + "equipment_slot": "9" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "578", + "durability": null, + "name": "Sapphire bracelet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11073" + }, + { + "shop_price": "506", + "ge_buy_limit": "5000", + "examine": "Now I can become a potter.", + "grand_exchange_price": "644", + "durability": null, + "name": "Bracelet of clay", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11074", + "equipment_slot": "9" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "644", + "durability": null, + "name": "Bracelet of clay", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11075" + }, + { + "ge_buy_limit": "5000", + "examine": "I wonder if this is valuable.", + "grand_exchange_price": "786", + "durability": null, + "name": "Emerald bracelet", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "11076", + "equipment_slot": "9" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "786", + "durability": null, + "name": "Emerald bracelet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11077" + }, + { + "ge_buy_limit": "34464", + "examine": "Must be worn as you enter the game to receive the bonus for that game.", + "grand_exchange_price": "926", + "durability": null, + "name": "Castlewar brace(3)", + "tradeable": "true", + "weight": "0.25", + "archery_ticket_price": "0", + "id": "11079", + "equipment_slot": "9" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "926", + "durability": null, + "name": "Castlewar brace(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11080" + }, + { + "examine": "Must be worn as you enter the game to receive the bonus for that game.", + "grand_exchange_price": "3", + "durability": null, + "name": "Castlewar brace(2)", + "tradeable": "true", + "weight": "0.25", + "archery_ticket_price": "0", + "id": "11081", + "equipment_slot": "9" + }, + { + "durability": null, + "name": "Castlewar brace(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11082" + }, + { + "ge_buy_limit": "5000", + "examine": "Must be worn as you enter the game to receive the bonus for that game.", + "grand_exchange_price": "3484", + "durability": null, + "name": "Castlewar brace(1)", + "tradeable": "true", + "weight": "0.25", + "archery_ticket_price": "0", + "id": "11083", + "equipment_slot": "9" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "3484", + "durability": null, + "name": "Castlewar brace(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11084" + }, + { + "shop_price": "2325", + "ge_buy_limit": "5000", + "examine": "I wonder if this is valuable.", + "grand_exchange_price": "1271", + "durability": null, + "name": "Ruby bracelet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11085", + "equipment_slot": "9" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "1271", + "durability": null, + "name": "Ruby bracelet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11086" + }, + { + "ge_buy_limit": "5000", + "examine": "It eases diseases!", + "grand_exchange_price": "1376", + "durability": null, + "name": "Inoculation brace", + "tradeable": "true", + "weight": "0.25", + "archery_ticket_price": "0", + "id": "11088", + "equipment_slot": "9" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "1376", + "durability": null, + "name": "Inoculation brace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11089" + }, + { + "ge_buy_limit": "5000", + "examine": "In case of emergency, wear necklace.", + "grand_exchange_price": "15400", + "durability": null, + "name": "Phoenix necklace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11090", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "15400", + "durability": null, + "name": "Phoenix necklace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11091" + }, + { + "shop_price": "3422", + "ge_buy_limit": "5000", + "examine": "I wonder if this is valuable.", + "grand_exchange_price": "12100", + "durability": null, + "name": "Diamond bracelet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11092", + "equipment_slot": "9" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "12100", + "durability": null, + "name": "Diamond bracelet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11093" + }, + { + "ge_buy_limit": "5000", + "examine": "It repels revenants and helps you enter the Abyss.", + "grand_exchange_price": "15200", + "durability": null, + "name": "Forinthry brace(5)", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "11095", + "equipment_slot": "9" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "15200", + "durability": null, + "name": "Forinthry brace(5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11096" + }, + { + "examine": "It repels revenants and helps you enter the Abyss.", + "grand_exchange_price": "5", + "durability": null, + "name": "Forinthry brace(4)", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "11097", + "equipment_slot": "9" + }, + { + "durability": null, + "name": "Forinthry brace(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11098" + }, + { + "examine": "It repels revenants and helps you enter the Abyss.", + "grand_exchange_price": "5", + "durability": null, + "name": "Forinthry brace(3)", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "11099", + "equipment_slot": "9" + }, + { + "durability": null, + "name": "Forinthry brace(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11100" + }, + { + "examine": "It repels revenants and helps you enter the Abyss.", + "grand_exchange_price": "5", + "durability": null, + "name": "Forinthry brace(2)", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "11101", + "equipment_slot": "9" + }, + { + "durability": null, + "name": "Forinthry brace(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11102" + }, + { + "ge_buy_limit": "5000", + "examine": "It repels revenants and helps you enter the Abyss.", + "grand_exchange_price": "2537", + "durability": null, + "name": "Forinthry brace(1)", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "11103", + "equipment_slot": "9" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "2537", + "durability": null, + "name": "Forinthry brace(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11104" + }, + { + "ge_buy_limit": "100", + "examine": "This will help me travel.", + "grand_exchange_price": "30400", + "durability": null, + "name": "Skills necklace(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11105", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "30400", + "durability": null, + "name": "Skills necklace(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11106" + }, + { + "examine": "This will help me travel.", + "grand_exchange_price": "1", + "durability": null, + "name": "Skills necklace(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11107", + "equipment_slot": "2" + }, + { + "durability": null, + "name": "Skills necklace(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11108" + }, + { + "examine": "This will help me travel.", + "grand_exchange_price": "1", + "durability": null, + "name": "Skills necklace(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11109", + "equipment_slot": "2" + }, + { + "durability": null, + "name": "Skills necklace(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11110" + }, + { + "examine": "This will help me travel.", + "grand_exchange_price": "1", + "durability": null, + "name": "Skills necklace(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11111", + "equipment_slot": "2" + }, + { + "durability": null, + "name": "Skills necklace(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11112" + }, + { + "ge_buy_limit": "100", + "examine": "This will help me travel.", + "grand_exchange_price": "28400", + "durability": null, + "name": "Skills necklace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11113", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "28400", + "durability": null, + "name": "Skills necklace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11114" + }, + { + "ge_buy_limit": "100", + "examine": "I wonder if this is valuable.", + "grand_exchange_price": "26000", + "durability": null, + "name": "Dragon bracelet", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "11115", + "equipment_slot": "9" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "26000", + "durability": null, + "name": "Dragon bracelet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11116" + }, + { + "ge_buy_limit": "100", + "examine": "A handy way to get around.", + "grand_exchange_price": "29700", + "durability": null, + "name": "Combat bracelet(4)", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "11118", + "bonuses": "7,7,7,3,7,5,5,5,3,5,5,6,0,0,0", + "equipment_slot": "9" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "29700", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Combat bracelet(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11119" + }, + { + "examine": "A handy way to get around.", + "grand_exchange_price": "1", + "durability": null, + "name": "Combat bracelet(3)", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "11120", + "bonuses": "7,7,7,3,7,5,5,5,3,5,5,6,0,0,0", + "equipment_slot": "9" + }, + { + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Combat bracelet(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11121" + }, + { + "examine": "A handy way to get around.", + "grand_exchange_price": "1", + "durability": null, + "name": "Combat bracelet(2)", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "11122", + "bonuses": "7,7,7,3,7,5,5,5,3,5,5,6,0,0,0", + "equipment_slot": "9" + }, + { + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Combat bracelet(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11123" + }, + { + "examine": "A handy way to get around.", + "grand_exchange_price": "1", + "durability": null, + "name": "Combat bracelet(1)", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "11124", + "bonuses": "7,7,7,3,7,5,5,5,3,5,5,6,0,0,0", + "equipment_slot": "9" + }, + { + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Combat bracelet(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11125" + }, + { + "ge_buy_limit": "100", + "examine": "You will need to recharge the bracelet at the Legends Guild.", + "grand_exchange_price": "29000", + "durability": null, + "name": "Combat bracelet", + "tradeable": "true", + "weight": "0.3", + "archery_ticket_price": "0", + "id": "11126", + "bonuses": "7,7,7,3,7,5,5,5,3,5,5,6,0,0,0", + "equipment_slot": "9" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "29000", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Combat bracelet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11127" + }, + { + "ge_buy_limit": "100", + "examine": "Makes obsidian weapons even stronger!", + "grand_exchange_price": "2400000", + "durability": null, + "name": "Berserker necklace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11128", + "bonuses": "-10,-10,-10,0,0,-20,-20,-20,-20,-20,-20,7,3,0,0", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2400000", + "durability": null, + "name": "Berserker necklace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11129" + }, + { + "shop_price": "80400", + "ge_buy_limit": "100", + "examine": "I wonder if this is valuable.", + "grand_exchange_price": "941200", + "durability": null, + "name": "Onyx bracelet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11130", + "equipment_slot": "9" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "941200", + "durability": null, + "name": "Onyx bracelet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11131" + }, + { + "ge_buy_limit": "100", + "examine": "Helps to restore your life points.", + "grand_exchange_price": "124200", + "durability": null, + "name": "Regen bracelet", + "tradeable": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "11133", + "bonuses": "8,8,8,3,7,6,6,6,3,6,5,7,0,0,0", + "equipment_slot": "9" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "124200", + "durability": null, + "name": "Regen bracelet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11134" + }, + { + "remove_sleeves": "true", + "examine": "For all your flying needs.", + "durability": null, + "name": "Bomber jacket", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11135", + "equipment_slot": "4" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A pair of pale green Karamja gloves.", + "durability": null, + "name": "Karamja gloves 1", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11136", + "bonuses": "1,1,1,1,1,1,1,1,1,1,1,1,0,0,0", + "equipment_slot": "9" + }, + { + "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", + "examine": "I wonder what happens if I rub it.", + "durability": null, + "name": "Antique lamp", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11137" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A pair of green Karamja gloves.", + "durability": null, + "name": "Karamja gloves 2", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11138", + "bonuses": "1,1,1,1,1,1,1,1,1,1,1,1,0,0,0", + "equipment_slot": "9" + }, + { + "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", + "examine": "I wonder what happens if I rub it.", + "durability": null, + "name": "Antique lamp", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11139" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A pair of dark green Karamja gloves.", + "durability": null, + "name": "Karamja gloves 3", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11140", + "bonuses": "1,1,1,1,1,1,1,1,1,1,1,1,0,0,0", + "equipment_slot": "9" + }, + { + "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", + "examine": "I wonder what happens if I rub it.", + "durability": null, + "name": "Antique lamp", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11141" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "When empty: A vessel for holding liquid. Filled with water: A vessel containing water. Filled with Goutweed: A vessel containing water and goutweed.", + "durability": null, + "name": "Dream vial (empty)", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11151" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "When empty: A vessel for holding liquid. Filled with water: A vessel containing water. Filled with Goutweed: A vessel containing water and goutweed.", + "durability": null, + "name": "Dream vial (water)", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11152" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "When empty: A vessel for holding liquid. Filled with water: A vessel containing water. Filled with Goutweed: A vessel containing water and goutweed.", + "durability": null, + "name": "Dream vial (herb)", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11153" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Potion of Shared Dreaming. One dream for two!", + "durability": null, + "name": "Dream potion", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11154" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A ground astral rune.", + "durability": null, + "name": "Ground astral rune", + "archery_ticket_price": "0", + "id": "11155" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "An astral rune that has been broken into shards.", + "durability": null, + "name": "Astral rune shards", + "archery_ticket_price": "0", + "id": "11156" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A lunar-styled lamp. I wonder what's inside?", + "durability": null, + "name": "Dreamy lamp", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11157" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Perfect for storing heavy things.", + "durability": null, + "name": "Cyrisus's chest", + "tradeable": "false", + "destroy": "true", + "weight": "6", + "archery_ticket_price": "0", + "id": "11158" + }, + { + "destroy_message": "You will have to create another using the Lunar Spellbook.", + "ge_buy_limit": "100", + "examine": "A box of Hunter goodies.", + "grand_exchange_price": "3", + "durability": null, + "name": "Hunter kit", + "tradeable": "false", + "destroy": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "11159" + }, + { + "destroy_message": "You'll need to get it back from Captain Rovin.", + "examine": "Complete Shield of Arrav.", + "durability": null, + "name": "Restored shield", + "destroy": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "11164" + }, + { + "turn90cw_anim": "821", + "examine": "Second-rate crossbow, former property of the Phoenix Gang.", + "walk_anim": "4226", + "durability": null, + "weight": "3", + "turn90ccw_anim": "822", + "attack_speed": "6", + "weapon_interface": "17", + "turn180_anim": "4227", + "equip_audio": "2244", + "render_anim": "175", + "equipment_slot": "3", + "stand_anim": "4591", + "attack_audios": "2700,0,0,0", + "name": "Phoenix crossbow", + "tradeable": "true", + "run_anim": "4228", + "archery_ticket_price": "0", + "id": "11165", + "stand_turn_anim": "823", + "bonuses": "0,0,0,0,6,0,0,0,0,0,0,0,0,0,0" + }, + { + "durability": null, + "name": "Phoenix crossbow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11166" + }, + { + "turn90cw_anim": "821", + "examine": "Second-rate crossbow, former property of the Phoenix Gang.", + "walk_anim": "4226", + "durability": null, + "weight": "3", + "turn90ccw_anim": "822", + "attack_speed": "6", + "weapon_interface": "17", + "turn180_anim": "4227", + "equip_audio": "2244", + "render_anim": "175", + "equipment_slot": "3", + "stand_anim": "4591", + "attack_audios": "2700,0,0,0", + "name": "Phoenix crossbow", + "tradeable": "true", + "run_anim": "4228", + "archery_ticket_price": "0", + "id": "11167", + "stand_turn_anim": "823", + "bonuses": "0,0,0,0,6,0,0,0,0,0,0,0,0,0,0" + }, + { + "durability": null, + "name": "Phoenix crossbow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11168" + }, + { + "shop_price": "50", + "examine": "A collection of written news on paper!", + "durability": null, + "name": "Newspaper", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11169" + }, + { + "durability": null, + "name": "Newspaper", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11170" + }, + { + "shop_price": "50", + "examine": "A collection of written news on paper!", + "durability": null, + "name": "Newspaper", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11171" + }, + { + "durability": null, + "name": "Newspaper", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11172" + }, + { + "destroy_message": "Instead of destroying this I should get a friend to help me retrieve the other half.", + "examine": "I can use this to claim a reward from the King, if I get the other half.", + "durability": null, + "name": "Half certificate", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11173" + }, + { + "destroy_message": "Instead of destroying this I should get a friend to help me retrieve the other half.", + "examine": "I can use this to claim a reward from the King, if I get the other half.", + "durability": null, + "name": "Half certificate", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11174" + }, + { + "destroy_message": "You can get another find from the pile in the cleaning area of Varrock Museum.", + "examine": "A roughly-prepared archaeological find ready for cleaning.", + "durability": null, + "name": "Uncleaned find", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11175" + }, + { + "examine": "An old looking coin.", + "durability": null, + "name": "Old coin", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11179" + }, + { + "examine": "A cracked and rusty looking coin.", + "durability": null, + "name": "Ancient coin", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11180" + }, + { + "examine": "A very old symbol of Saradomin.", + "durability": null, + "name": "Ancient symbol", + "archery_ticket_price": "0", + "id": "11181" + }, + { + "examine": "An old symbol of Saradomin.", + "durability": null, + "name": "Old symbol", + "archery_ticket_price": "0", + "id": "11182" + }, + { + "examine": "An old vase with Saradominist markings - it has been chipped.", + "durability": null, + "name": "Old chipped vase", + "archery_ticket_price": "0", + "id": "11183" + }, + { + "examine": "A map of Varrock Museum.", + "durability": null, + "name": "Museum map", + "archery_ticket_price": "0", + "id": "11184" + }, + { + "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", + "examine": "I wonder what happens if I rub it.", + "durability": null, + "name": "Antique lamp", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11185" + }, + { + "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", + "examine": "I wonder what happens if I rub it.", + "durability": null, + "name": "Antique lamp", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11186" + }, + { + "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", + "examine": "I wonder what happens if I rub it.", + "durability": null, + "name": "Antique lamp", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11187" + }, + { + "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", + "examine": "I wonder what happens if I rub it.", + "durability": null, + "name": "Antique lamp", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11188" + }, + { + "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", + "examine": "I wonder what happens if I rub it.", + "durability": null, + "name": "Antique lamp", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11189" + }, + { + "examine": "An enchanted necklace.", + "durability": null, + "name": "Digsite pendant (1)", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "11190", + "equipment_slot": "2" + }, + { + "examine": "An enchanted necklace.", + "durability": null, + "name": "Digsite pendant (2)", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "11191", + "equipment_slot": "2" + }, + { + "examine": "An enchanted necklace.", + "durability": null, + "name": "Digsite pendant (3)", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "11192", + "equipment_slot": "2" + }, + { + "examine": "An enchanted necklace.", + "durability": null, + "name": "Digsite pendant (4)", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "11193", + "equipment_slot": "2" + }, + { + "examine": "An enchanted necklace.", + "durability": null, + "name": "Digsite pendant (5)", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "11194", + "equipment_slot": "2" + }, + { + "examine": "A recently-cleaned necklace.", + "durability": null, + "name": "Clean necklace", + "archery_ticket_price": "0", + "id": "11195", + "equipment_slot": "2" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "One of Grimgnash's feathers.", + "durability": null, + "name": "Griffin feather", + "archery_ticket_price": "0", + "id": "11196" + }, + { + "destroy_message": "You will need to try and find another pendant in the mouse hole if you destroy this.", + "examine": "The pendant belonging to Miazrqa.", + "durability": null, + "name": "Miazrqa's pendant", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11197" + }, + { + "destroy_message": "You will need to find another sheet of music in the witch's basement if you destroy this.", + "examine": "A sheet of music.", + "durability": null, + "name": "Music sheet", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11198" + }, + { + "destroy_message": "You will need to obtain another helmet from Rupert the Beard if you destroy this", + "shop_price": "60000", + "examine": "A sturdy helmet that belonged to Rupert the beard.", + "durability": null, + "name": "Rupert's helmet", + "tradeable": "false", + "destroy": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "11199" + }, + { + "remove_head": "true", + "requirements": "{1,50}", + "shop_price": "60000", + "ge_buy_limit": "100", + "examine": "A sturdy helmet that belonged to Rupert the beard.", + "durability": null, + "weight": "1.9", + "equipment_slot": "0", + "grand_exchange_price": "35800", + "name": "Dwarven helmet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11200", + "bonuses": "0,0,6,-2,-2,27,28,31,5,24,8,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "35800", + "durability": null, + "name": "Dwarven helmet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11201" + }, + { + "destroy_message": "You will need to find another copy in the witch's basement if you destroy this.", + "examine": "A recipe for a shrinking potion.", + "durability": null, + "name": "Shrinking recipe", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11202" + }, + { + "destroy_message": "You will need to find another copy in the witch's basement if you destroy this.", + "examine": "A list of tasks for the day.", + "durability": null, + "name": "To-do list", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11203" + }, + { + "destroy_message": "You will need to make another shrinking potion if you destroy this.", + "examine": "Apparently it shrinks you. Very fast.", + "durability": null, + "name": "Shrink-me-quick", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11204", + "equipment_slot": "3" + }, + { + "shop_price": "4", + "ge_buy_limit": "100", + "examine": "A shrunk ogleroot! How odd...", + "grand_exchange_price": "35", + "durability": null, + "name": "Shrunk ogleroot", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11205" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A shiny golden goblin. Strange!", + "durability": null, + "name": "Golden goblin", + "tradeable": "false", + "destroy": "true", + "weight": "30", + "archery_ticket_price": "0", + "id": "11210" + }, + { + "destroy_message": "You will need to get another bag of beans from Sylas if you destroy this one.", + "examine": "A bag of magic beans.", + "durability": null, + "name": "Magic beans", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11211" + }, + { + "requirements": "{4,60}", + "ge_buy_limit": "10000", + "examine": "An arrow made using a dragon's talon.", + "grand_exchange_price": "2674", + "durability": null, + "name": "Dragon arrow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11212", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,60", + "equipment_slot": "13" + }, + { + "requirements": "{4,60}", + "ge_buy_limit": "10000", + "examine": "unlit: Arrows with dragon heads and oil-soaked cloth.lit: Dragon-headed fire arrow.", + "grand_exchange_price": "3988", + "durability": null, + "name": "Dragon fire arrows", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11217", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,60", + "equipment_slot": "13" + }, + { + "requirements": "{4,60}", + "ge_buy_limit": "10000", + "examine": "unlit: Arrows with dragon heads and oil-soaked cloth.lit: Dragon-headed fire arrow.", + "grand_exchange_price": "3834", + "durability": null, + "name": "Dragon fire arrows", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11222", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,60", + "equipment_slot": "13" + }, + { + "requirements": "{4,60}", + "ge_buy_limit": "10000", + "examine": "An arrow made using a dragon's talon.", + "grand_exchange_price": "3141", + "durability": null, + "name": "Dragon arrow(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11227", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,60", + "equipment_slot": "13" + }, + { + "requirements": "{4,60}", + "ge_buy_limit": "10000", + "examine": "An arrow made using a dragon's talon.", + "grand_exchange_price": "2866", + "durability": null, + "name": "Dragon arrow(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11228", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,60", + "equipment_slot": "13" + }, + { + "requirements": "{4,60}", + "ge_buy_limit": "10000", + "examine": "An arrow made using a dragon's talon.", + "grand_exchange_price": "3766", + "durability": null, + "name": "Dragon arrow(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11229", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,60", + "equipment_slot": "13" + }, + { + "requirements": "{4,60}", + "ge_buy_limit": "10000", + "examine": "A deadly throwing dart with a dragon tip.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "equipment_slot": "3", + "grand_exchange_price": "315", + "attack_audios": "2547,0,0,0", + "name": "Dragon dart", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11230", + "bonuses": "0,0,0,0,18,0,0,0,0,0,0,0,0,0,20" + }, + { + "requirements": "{4,60}", + "ge_buy_limit": "10000", + "examine": "A deadly throwing dart with a dragon tip.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "equipment_slot": "3", + "grand_exchange_price": "445", + "attack_audios": "2547,0,0,0", + "name": "Dragon dart(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11231", + "bonuses": "0,0,0,0,18,0,0,0,0,0,0,0,0,0,20" + }, + { + "ge_buy_limit": "5000", + "examine": "A deadly looking dragon dart tip - needs feathers for flight.", + "grand_exchange_price": "746", + "attack_audios": "2547,0,0,0", + "durability": null, + "name": "Dragon dart tip", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11232" + }, + { + "requirements": "{4,60}", + "ge_buy_limit": "10000", + "examine": "A deadly throwing dart with a dragon tip.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "equipment_slot": "3", + "grand_exchange_price": "516", + "attack_audios": "2547,0,0,0", + "name": "Dragon dart(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11233", + "bonuses": "0,0,0,0,18,0,0,0,0,0,0,0,0,0,20" + }, + { + "requirements": "{4,60}", + "ge_buy_limit": "10000", + "examine": "A deadly throwing dart with a dragon tip.", + "durability": null, + "attack_speed": "3", + "weapon_interface": "18", + "equip_audio": "2244", + "equipment_slot": "3", + "grand_exchange_price": "1248", + "attack_audios": "2547,0,0,0", + "name": "Dragon dart(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11234", + "bonuses": "0,0,0,0,18,0,0,0,0,0,0,0,0,0,20" + }, + { + "ge_buy_limit": "10", + "turn90cw_anim": "821", + "examine": "A bow from a darker dimension.", + "walk_anim": "819", + "has_special": "true", + "rare_item": "true", + "turn90ccw_anim": "822", + "attack_speed": "9", + "two_handed": "true", + "turn180_anim": "820", + "defence_anim": "424", + "equipment_slot": "3", + "attack_anims": "426,426,426,426", + "grand_exchange_price": "143400", + "stand_anim": "808", + "tradeable": "true", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "11235", + "stand_turn_anim": "823", + "bonuses": "0,0,0,0,95,0,0,0,0,0,0,0,0,0,0", + "requirements": "{4,60}", + "durability": null, + "weight": "1.9", + "weapon_interface": "16", + "equip_audio": "3738", + "render_anim": "1", + "lendable": "true", + "attack_audios": "3731,0,0,0", + "name": "Dark bow" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "143400", + "durability": null, + "name": "Dark bow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11236" + }, + { + "ge_buy_limit": "10000", + "examine": "Dragon talons, usable as arrowheads.", + "grand_exchange_price": "3391", + "durability": null, + "name": "Dragon arrowtips", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11237" + }, + { + "destroy_message": "If you drop this it will disappear. Are you sure you want to do this?", + "ge_buy_limit": "1000", + "examine": "A baby impling in a jar. That's a bit cruel.", + "grand_exchange_price": "529", + "durability": null, + "name": "Baby impling jar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11238" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "529", + "durability": null, + "name": "Baby impling jar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11239" + }, + { + "destroy_message": "If you drop this it will disappear. Are you sure you want to do this?", + "ge_buy_limit": "1000", + "examine": "A young impling in a jar. Don't trap me, man.", + "grand_exchange_price": "514", + "durability": null, + "name": "Young impling jar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11240" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "514", + "durability": null, + "name": "Young impling jar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11241" + }, + { + "destroy_message": "If you drop this it will disappear. Are you sure you want to do this?", + "ge_buy_limit": "1000", + "examine": "A gourmet impling in a jar.", + "grand_exchange_price": "677", + "durability": null, + "name": "Gourm' impling jar", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "11242" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "677", + "durability": null, + "name": "Gourm' impling jar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11243" + }, + { + "destroy_message": "If you drop this it will disappear. Are you sure you want to do this?", + "ge_buy_limit": "1000", + "examine": "Earth impling in a jar.", + "grand_exchange_price": "1343", + "durability": null, + "name": "Earth impling jar", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "11244" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1343", + "durability": null, + "name": "Earth impling jar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11245" + }, + { + "destroy_message": "If you drop this it will disappear. Are you sure you want to do this?", + "ge_buy_limit": "1000", + "examine": "Essence impling in a jar.", + "grand_exchange_price": "1266", + "durability": null, + "name": "Ess' impling jar", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11246" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1266", + "durability": null, + "name": "Ess' impling jar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11247" + }, + { + "destroy_message": "If you drop this it will disappear. Are you sure you want to do this?", + "ge_buy_limit": "1000", + "examine": "Eclectic impling in a jar.", + "grand_exchange_price": "2943", + "durability": null, + "name": "Eclectic impling jar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11248" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "2943", + "durability": null, + "name": "Eclectic impling jar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11249" + }, + { + "destroy_message": "If you drop this it will disappear. Are you sure you want to do this?", + "ge_buy_limit": "1000", + "examine": "Nature impling in a jar.", + "grand_exchange_price": "8593", + "durability": null, + "name": "Nature impling jar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11250" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "8593", + "durability": null, + "name": "Nature impling jar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11251" + }, + { + "destroy_message": "If you drop this it will disappear. Are you sure you want to do this?", + "ge_buy_limit": "1000", + "examine": "Magpie impling in a jar.", + "grand_exchange_price": "22900", + "durability": null, + "name": "Magpie impling jar", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11252" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "22900", + "durability": null, + "name": "Magpie impling jar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11253" + }, + { + "destroy_message": "If you drop this it will disappear. Are you sure you want to do this?", + "ge_buy_limit": "1000", + "examine": "Ninja impling in a jar.", + "grand_exchange_price": "21800", + "durability": null, + "name": "Ninja impling jar", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11254" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "21800", + "durability": null, + "name": "Ninja impling jar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11255" + }, + { + "destroy_message": "If you drop this it will disappear. Are you sure you want to do this?", + "ge_buy_limit": "500", + "examine": "Dragon impling in a jar.", + "grand_exchange_price": "423600", + "durability": null, + "name": "Dragon impling jar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11256" + }, + { + "ge_buy_limit": "500", + "grand_exchange_price": "423600", + "durability": null, + "name": "Dragon impling jar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11257" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Creates butterfly and impling jars.", + "durability": null, + "name": "Jar generator", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11258" + }, + { + "turn90cw_anim": "6610", + "examine": "For catching butterflies.", + "walk_anim": "6607", + "turn90ccw_anim": "6609", + "attack_speed": "4", + "two_handed": "", + "turn180_anim": "6608", + "defence_anim": "403", + "equipment_slot": "3", + "attack_anims": "401,401,400,401", + "destroy_message": "You will have to trade with Elnock to get a new magic butterfly net.", + "stand_anim": "6604", + "tradeable": "false", + "run_anim": "6603", + "archery_ticket_price": "0", + "id": "11259", + "stand_turn_anim": "6611", + "requirements": "{21,17}", + "shop_price": "3", + "durability": null, + "destroy": "true", + "weight": "0.2", + "weapon_interface": "14", + "render_anim": "1426", + "name": "Magic butterfly net" + }, + { + "shop_price": "1", + "ge_buy_limit": "1000", + "examine": "It's got little holes in the top.", + "grand_exchange_price": "248", + "durability": null, + "name": "Impling jar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11260" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "248", + "durability": null, + "name": "Impling jar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11261" + }, + { + "shop_price": "3", + "ge_buy_limit": "100", + "examine": "Imps seem to hate this stuff. Can't say I blame them.", + "grand_exchange_price": "1016", + "durability": null, + "name": "Imp repellent", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11262" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1016", + "durability": null, + "name": "Imp repellent", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11263" + }, + { + "ge_buy_limit": "100", + "examine": "Omega 3 oil. Good for the brain, not so for the nose.", + "grand_exchange_price": "601", + "durability": null, + "name": "Anchovy oil", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11264" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "601", + "durability": null, + "name": "Anchovy oil", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11265" + }, + { + "ge_buy_limit": "100", + "examine": "Fish paste. Urk.", + "grand_exchange_price": "57", + "durability": null, + "name": "Anchovy paste", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11266" + }, + { + "examine": "I can train on this", + "durability": null, + "name": "Picture", + "archery_ticket_price": "0", + "id": "11267" + }, + { + "examine": "I can train on this", + "durability": null, + "name": "Picture", + "archery_ticket_price": "0", + "id": "11268" + }, + { + "examine": "I can train on this", + "durability": null, + "name": "Picture", + "archery_ticket_price": "0", + "id": "11269" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11270" + }, + { + "examine": "I can train on this", + "durability": null, + "name": "Picture", + "archery_ticket_price": "0", + "id": "11271" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11272" + }, + { + "destroy_message": "You will have to ask Elnock for another one of these.", + "examine": "Lets you easily identify your prey.", + "durability": null, + "name": "Impling scroll", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11273" + }, + { + "remove_sleeves": "true", + "examine": "The label says 'Vivid Crimson', but it looks like pink to me!", + "grand_exchange_price": "27", + "durability": null, + "name": "Ham shirt", + "tradeable": "true", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "11274", + "bonuses": "0,0,0,0,0,0,2,2,0,0,0,0,0,0,0", + "equipment_slot": "4" + }, + { + "durability": null, + "name": "Mith grapple", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11275" + }, + { + "durability": null, + "name": "Mith grapple", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11276" + }, + { + "lendable": "true", + "examine": "I hope I don't meet any roundheads...", + "durability": null, + "name": "Cavalier mask", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11277", + "equipment_slot": "8" + }, + { + "examine": "Essential mime wear.", + "durability": null, + "name": "Beret mask", + "weight": "1", + "archery_ticket_price": "0", + "id": "11278", + "equipment_slot": "0" + }, + { + "destroy_message": "You can complete the quest by speaking to Oziach even if you do not have the head.", + "examine": "The severed head of the great dragon Elvarg!", + "durability": null, + "name": "Elvarg's head", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11279", + "equipment_slot": "3" + }, + { + "remove_head": "true", + "lendable": "true", + "examine": "I hope I don't meet any roundheads...", + "durability": null, + "name": "Cavalier and mask", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11280", + "equipment_slot": "0" + }, + { + "durability": null, + "name": "Cavalier and mask", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11281" + }, + { + "remove_head": "true", + "examine": "Essential mime wear.", + "durability": null, + "name": "Beret and mask", + "weight": "1", + "archery_ticket_price": "0", + "id": "11282", + "equipment_slot": "0" + }, + { + "requirements": "{1,75}", + "examine": "A heavy shield with a snarling, draconic visage.", + "grand_exchange_price": "5653008", + "rare_item": "true", + "durability": null, + "name": "Dragonfire shield", + "weight": "7.2", + "archery_ticket_price": "0", + "id": "11283", + "bonuses": "0,0,0,-10,-5,20,25,22,10,22,17,7,0,0,0", + "equip_audio": "2245", + "equipment_slot": "5" + }, + { + "requirements": "{1,75}", + "ge_buy_limit": "10", + "examine": "A heavy shield with a snarling, draconic visage.", + "rare_item": "true", + "durability": null, + "weight": "7.2", + "equip_audio": "2245", + "equipment_slot": "5", + "grand_exchange_price": "7700000", + "name": "Dragonfire shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11284", + "bonuses": "0,0,0,-10,-5,20,25,22,10,22,17,7,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "7700000", + "durability": null, + "name": "Dragonfire shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11285" + }, + { + "ge_buy_limit": "10", + "examine": "It looks like this could be attached to a shield somehow.", + "grand_exchange_price": "8000000", + "rare_item": "true", + "durability": null, + "name": "Draconic visage", + "tradeable": "true", + "weight": "1.8", + "archery_ticket_price": "0", + "id": "11286" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "8000000", + "durability": null, + "name": "Draconic visage", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11287" + }, + { + "examine": "A heavy barbarian Fishing rod.", + "durability": null, + "name": "Barbarian rod", + "weight": "1", + "archery_ticket_price": "0", + "id": "11323" + }, + { + "shop_price": "6", + "ge_buy_limit": "5000", + "examine": "Roe, or cheap fishy eggs.", + "grand_exchange_price": "17", + "durability": null, + "name": "Roe", + "tradeable": "true", + "weight": "0.05", + "archery_ticket_price": "0", + "id": "11324" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "17", + "durability": null, + "name": "Roe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11325" + }, + { + "ge_buy_limit": "5000", + "examine": "Caviar, or expensive fishy eggs.", + "grand_exchange_price": "370", + "durability": null, + "name": "Caviar", + "tradeable": "true", + "weight": "0.05", + "archery_ticket_price": "0", + "id": "11326" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "370", + "durability": null, + "name": "Caviar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11327" + }, + { + "shop_price": "11", + "ge_buy_limit": "5000", + "examine": "A sad-looking trout.", + "grand_exchange_price": "9", + "durability": null, + "name": "Leaping trout", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11328" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "9", + "durability": null, + "name": "Leaping trout", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11329" + }, + { + "ge_buy_limit": "5000", + "examine": "Some non-tasty salmon.", + "grand_exchange_price": "19", + "durability": null, + "name": "Leaping salmon", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11330" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "19", + "durability": null, + "name": "Leaping salmon", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11331" + }, + { + "ge_buy_limit": "5000", + "examine": "A bloated sturgeon.", + "grand_exchange_price": "151", + "durability": null, + "name": "Leaping sturgeon", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11332" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "151", + "durability": null, + "name": "Leaping sturgeon", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11333" + }, + { + "ge_buy_limit": "100", + "examine": "Slices of inedible fish.", + "grand_exchange_price": "2", + "durability": null, + "name": "Fish offcuts", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11334" + }, + { + "remove_head": "true", + "requirements": "{1,60}", + "ge_buy_limit": "10", + "examine": "Protects your head and looks impressive too.", + "rare_item": "true", + "durability": null, + "weight": "2", + "absorb": "2,0,4", + "equip_audio": "2240", + "remove_beard": "true", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "51600000", + "name": "Dragon full helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11335", + "bonuses": "0,0,0,-6,-2,45,48,41,-1,46,12,0,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "51600000", + "durability": null, + "name": "Dragon full helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11336" + }, + { + "destroy_message": "I can gather more from the caverns below the Baxtorian Lake.", + "examine": "The bones of a barbarian warrior, slain by his fellow adventurers.", + "durability": null, + "name": "Mangled bones", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11337" + }, + { + "destroy_message": "I can gather more from the caverns below the Baxtorian Lake.", + "examine": "The bones of a barbarian warrior, slain by vile dragons.", + "durability": null, + "name": "Chewed bones", + "destroy": "true", + "weight": "9.6", + "archery_ticket_price": "0", + "id": "11338" + }, + { + "destroy_message": "I can obtain another from Otto.", + "examine": "Records from my discoveries beneath the lake.", + "durability": null, + "name": "My notes", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11339" + }, + { + "destroy_message": "I can obtain another from Otto.", + "examine": "A record of Otto's instructions to me.", + "durability": null, + "name": "Barbarian skills", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11340" + }, + { + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "durability": null, + "name": "Ancient page", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11341" + }, + { + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "durability": null, + "name": "Ancient page", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11342" + }, + { + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "durability": null, + "name": "Ancient page", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11343" + }, + { + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "durability": null, + "name": "Ancient page", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11344" + }, + { + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "durability": null, + "name": "Ancient page", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11345" + }, + { + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "durability": null, + "name": "Ancient page", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11346" + }, + { + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "durability": null, + "name": "Ancient page", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11347" + }, + { + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "durability": null, + "name": "Ancient page", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11348" + }, + { + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "durability": null, + "name": "Ancient page", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11349" + }, + { + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "durability": null, + "name": "Ancient page", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11350" + }, + { + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "durability": null, + "name": "Ancient page", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11351" + }, + { + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "durability": null, + "name": "Ancient page", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11352" + }, + { + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "durability": null, + "name": "Ancient page", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11353" + }, + { + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "durability": null, + "name": "Ancient page", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11354" + }, + { + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "durability": null, + "name": "Ancient page", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11355" + }, + { + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "durability": null, + "name": "Ancient page", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11356" + }, + { + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "durability": null, + "name": "Ancient page", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11357" + }, + { + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "durability": null, + "name": "Ancient page", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11358" + }, + { + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "durability": null, + "name": "Ancient page", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11359" + }, + { + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "durability": null, + "name": "Ancient page", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11360" + }, + { + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "durability": null, + "name": "Ancient page", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11361" + }, + { + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "durability": null, + "name": "Ancient page", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11362" + }, + { + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "durability": null, + "name": "Ancient page", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11363" + }, + { + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "durability": null, + "name": "Ancient page", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11364" + }, + { + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "durability": null, + "name": "Ancient page", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11365" + }, + { + "destroy_message": "I can loot another from the caverns beneath the Baxtorian Lake.", + "examine": "Could a dragon have written this?; Tiny writing.;Smells disgusting.", + "durability": null, + "name": "Ancient page", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11366" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A bronze-tipped, one-handed hasta.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "weapon_interface": "14", + "turn180_anim": "1206", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "204", + "stand_anim": "813", + "attack_audios": "2562,2556,2555,2562", + "name": "Bronze hasta", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "11367", + "stand_turn_anim": "1209", + "bonuses": "5,5,5,0,0,-1,-1,-1,0,-1,0,6,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "204", + "durability": null, + "name": "Bronze hasta", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11368" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "An iron-tipped, one-handed hasta.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "weapon_interface": "14", + "turn180_anim": "1206", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "25", + "stand_anim": "813", + "attack_audios": "2562,2556,2555,2562", + "name": "Iron hasta", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "11369", + "stand_turn_anim": "1209", + "bonuses": "8,8,8,0,0,-2,-2,-2,0,-2,0,10,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "25", + "durability": null, + "name": "Iron hasta", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11370" + }, + { + "requirements": "{0,5}", + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A steel-tipped, one-handed hasta.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "weapon_interface": "14", + "turn180_anim": "1206", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "93", + "stand_anim": "813", + "attack_audios": "2562,2556,2555,2562", + "name": "Steel hasta", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "11371", + "stand_turn_anim": "1209", + "bonuses": "12,12,12,0,0,-3,-3,-3,0,-3,0,12,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "93", + "durability": null, + "name": "Steel hasta", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11372" + }, + { + "requirements": "{0,20}", + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A mithril-tipped, one-handed hasta.", + "walk_anim": "1205", + "durability": null, + "weight": "1.8", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "weapon_interface": "14", + "turn180_anim": "1206", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "357", + "stand_anim": "813", + "attack_audios": "2562,2556,2555,2562", + "name": "Mithril hasta", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "11373", + "stand_turn_anim": "1209", + "bonuses": "17,17,17,0,0,-5,-5,-4,0,-5,0,18,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "357", + "durability": null, + "name": "Mithril hasta", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11374" + }, + { + "requirements": "{0,30}", + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "An adamant-tipped, one-handed hasta.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "weapon_interface": "14", + "turn180_anim": "1206", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "1095", + "stand_anim": "813", + "attack_audios": "2562,2556,2555,2562", + "name": "Adamant hasta", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "11375", + "stand_turn_anim": "1209", + "bonuses": "24,24,24,0,0,-6,-7,-5,0,-6,0,28,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1095", + "durability": null, + "name": "Adamant hasta", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11376" + }, + { + "requirements": "{0,40}", + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A rune-tipped, one-handed hasta.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "weapon_interface": "14", + "turn180_anim": "1206", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "12300", + "stand_anim": "813", + "attack_audios": "2562,2556,2555,2562", + "name": "Rune hasta", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "11377", + "stand_turn_anim": "1209", + "bonuses": "36,36,36,0,0,-10,-10,-9,0,-10,0,42,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "12300", + "durability": null, + "name": "Rune hasta", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11378" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A bronze-tipped, one-handed hasta.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "weapon_interface": "14", + "turn180_anim": "1206", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "290", + "stand_anim": "813", + "attack_audios": "2562,2556,2555,2562", + "name": "Bronze hasta(p)", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "11379", + "stand_turn_anim": "1209", + "bonuses": "5,5,5,0,0,-1,-1,-1,0,-1,0,6,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "290", + "durability": null, + "name": "Bronze hasta(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11380" + }, + { + "turn90cw_anim": "1207", + "examine": "A karambwan poison-tipped, one-handed bronze hasta.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "weapon_interface": "14", + "turn180_anim": "1206", + "render_anim": "28", + "equipment_slot": "3", + "stand_anim": "813", + "name": "Bronze hasta(kp)", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "11381", + "stand_turn_anim": "1209", + "bonuses": "5,5,5,0,0,-1,-1,-1,0,-1,0,6,0,0,0" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A bronze-tipped, one-handed hasta.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "weapon_interface": "14", + "turn180_anim": "1206", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "775", + "stand_anim": "813", + "attack_audios": "2562,2556,2555,2562", + "name": "Bronze hasta(p+)", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "11382", + "stand_turn_anim": "1209", + "bonuses": "5,5,5,0,0,-1,-1,-1,0,-1,0,6,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "775", + "durability": null, + "name": "Bronze hasta(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11383" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A bronze-tipped, one-handed hasta.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "weapon_interface": "14", + "turn180_anim": "1206", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "8974", + "stand_anim": "813", + "attack_audios": "2562,2556,2555,2562", + "name": "Bronze hasta(p++)", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "11384", + "stand_turn_anim": "1209", + "bonuses": "5,5,5,0,0,-1,-1,-1,0,-1,0,6,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "8974", + "durability": null, + "name": "Bronze hasta(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11385" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "An iron-tipped, one-handed hasta.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "weapon_interface": "14", + "turn180_anim": "1206", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "99", + "stand_anim": "813", + "attack_audios": "2562,2556,2555,2562", + "name": "Iron hasta(p)", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "11386", + "stand_turn_anim": "1209", + "bonuses": "8,8,8,0,0,-2,-2,-2,0,-2,0,10,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "99", + "durability": null, + "name": "Iron hasta(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11387" + }, + { + "turn90cw_anim": "1207", + "examine": "A karambwan poison-tipped, one-handed iron hasta.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "weapon_interface": "14", + "turn180_anim": "1206", + "render_anim": "28", + "equipment_slot": "3", + "stand_anim": "813", + "name": "Iron hasta(kp)", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "11388", + "stand_turn_anim": "1209", + "bonuses": "8,8,8,0,0,-2,-2,-2,0,-2,0,10,0,0,0" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "An iron-tipped, one-handed hasta.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "weapon_interface": "14", + "turn180_anim": "1206", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "584", + "stand_anim": "813", + "attack_audios": "2562,2556,2555,2562", + "name": "Iron hasta(p+)", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "11389", + "stand_turn_anim": "1209", + "bonuses": "8,8,8,0,0,-2,-2,-2,0,-2,0,10,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "584", + "durability": null, + "name": "Iron hasta(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11390" + }, + { + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "An iron-tipped, one-handed hasta.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "weapon_interface": "14", + "turn180_anim": "1206", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "8783", + "stand_anim": "813", + "attack_audios": "2562,2556,2555,2562", + "name": "Iron hasta(p++)", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "11391", + "stand_turn_anim": "1209", + "bonuses": "8,8,8,0,0,-2,-2,-2,0,-2,0,10,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "8783", + "durability": null, + "name": "Iron hasta(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11392" + }, + { + "requirements": "{0,5}", + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A steel-tipped, one-handed hasta.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "weapon_interface": "14", + "turn180_anim": "1206", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "151", + "stand_anim": "813", + "attack_audios": "2562,2556,2555,2562", + "name": "Steel hasta(p)", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "11393", + "stand_turn_anim": "1209", + "bonuses": "12,12,12,0,0,-3,-3,-3,0,-3,0,12,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "151", + "durability": null, + "name": "Steel hasta(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11394" + }, + { + "requirements": "{0,5}", + "turn90cw_anim": "1207", + "examine": "A karambwan poison-tipped, one-handed steel hasta.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "weapon_interface": "14", + "turn180_anim": "1206", + "render_anim": "28", + "equipment_slot": "3", + "stand_anim": "813", + "name": "Steel hasta(kp)", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "11395", + "stand_turn_anim": "1209", + "bonuses": "12,12,12,0,0,-3,-3,-3,0,-3,0,12,0,0,0" + }, + { + "requirements": "{0,5}", + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A steel-tipped, one-handed hasta.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "weapon_interface": "14", + "turn180_anim": "1206", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "636", + "stand_anim": "813", + "attack_audios": "2562,2556,2555,2562", + "name": "Steel hasta(p+)", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "11396", + "stand_turn_anim": "1209", + "bonuses": "12,12,12,0,0,-3,-3,-3,0,-3,0,12,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "636", + "durability": null, + "name": "Steel hasta(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11397" + }, + { + "requirements": "{0,5}", + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A steel-tipped, one-handed hasta.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "weapon_interface": "14", + "turn180_anim": "1206", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "8835", + "stand_anim": "813", + "attack_audios": "2562,2556,2555,2562", + "name": "Steel hasta(p++)", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "11398", + "stand_turn_anim": "1209", + "bonuses": "12,12,12,0,0,-3,-3,-3,0,-3,0,12,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "8835", + "durability": null, + "name": "Steel hasta(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11399" + }, + { + "requirements": "{0,20}", + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A mithril-tipped, one-handed hasta.", + "walk_anim": "1205", + "durability": null, + "weight": "1.8", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "weapon_interface": "14", + "turn180_anim": "1206", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "440", + "stand_anim": "813", + "attack_audios": "2562,2556,2555,2562", + "name": "Mithril hasta(p)", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "11400", + "stand_turn_anim": "1209", + "bonuses": "17,17,17,0,0,-5,-5,-4,0,-5,0,18,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "440", + "durability": null, + "name": "Mithril hasta(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11401" + }, + { + "requirements": "{0,20}", + "turn90cw_anim": "1207", + "examine": "A karambwan poison-tipped, one-handed mithril hasta", + "walk_anim": "1205", + "durability": null, + "weight": "1.8", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "weapon_interface": "14", + "turn180_anim": "1206", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "353", + "stand_anim": "813", + "attack_audios": "2562,2556,2555,2562", + "name": "Mithril hasta(kp)", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "11402", + "stand_turn_anim": "1209", + "bonuses": "17,17,17,0,0,-5,-5,-4,0,-5,0,18,0,0,0" + }, + { + "requirements": "{0,20}", + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A mithril-tipped, one-handed hasta.", + "walk_anim": "1205", + "durability": null, + "weight": "1.8", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "weapon_interface": "14", + "turn180_anim": "1206", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "925", + "stand_anim": "813", + "attack_audios": "2562,2556,2555,2562", + "name": "Mithril hasta(p+)", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "11403", + "stand_turn_anim": "1209", + "bonuses": "17,17,17,0,0,-5,-5,-4,0,-5,0,18,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "925", + "durability": null, + "name": "Mithril hasta(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11404" + }, + { + "requirements": "{0,20}", + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A mithril-tipped, one-handed hasta.", + "walk_anim": "1205", + "durability": null, + "weight": "1.8", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "weapon_interface": "14", + "turn180_anim": "1206", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "8711", + "stand_anim": "813", + "attack_audios": "2562,2556,2555,2562", + "name": "Mithril hasta(p++)", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "11405", + "stand_turn_anim": "1209", + "bonuses": "17,17,17,0,0,-5,-5,-4,0,-5,0,18,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "8711", + "durability": null, + "name": "Mithril hasta(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11406" + }, + { + "requirements": "{0,30}", + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "An adamant-tipped, one-handed hasta.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "weapon_interface": "14", + "turn180_anim": "1206", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "1154", + "stand_anim": "813", + "attack_audios": "2562,2556,2555,2562", + "name": "Adamant hasta(p)", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "11407", + "stand_turn_anim": "1209", + "bonuses": "24,24,24,0,0,-6,-7,-5,0,-6,0,28,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1154", + "durability": null, + "name": "Adamant hasta(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11408" + }, + { + "requirements": "{0,30}", + "turn90cw_anim": "1207", + "examine": "\tA karambwan poison-tipped, one-handed adamantite hasta.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "weapon_interface": "14", + "turn180_anim": "1206", + "render_anim": "28", + "equipment_slot": "3", + "stand_anim": "813", + "attack_audios": "2562,2556,2555,2562", + "name": "Adamant hasta(kp)", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "11409", + "stand_turn_anim": "1209", + "bonuses": "24,24,24,0,0,-6,-7,-5,0,-6,0,28,0,0,0" + }, + { + "requirements": "{0,30}", + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "An adamant-tipped, one-handed hasta.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "weapon_interface": "14", + "turn180_anim": "1206", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "1639", + "stand_anim": "813", + "attack_audios": "2562,2556,2555,2562", + "name": "Adamant hasta(p+)", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "11410", + "stand_turn_anim": "1209", + "bonuses": "24,24,24,0,0,-6,-7,-5,0,-6,0,28,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1639", + "durability": null, + "name": "Adamant hasta(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11411" + }, + { + "requirements": "{0,30}", + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "An adamant-tipped, one-handed hasta.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "weapon_interface": "14", + "turn180_anim": "1206", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "9388", + "stand_anim": "813", + "name": "Adamant hasta(p++)", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "11412", + "stand_turn_anim": "1209", + "bonuses": "24,24,24,0,0,-6,-7,-5,0,-6,0,28,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "9388", + "durability": null, + "name": "Adamant hasta(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11413" + }, + { + "requirements": "{0,40}", + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A rune-tipped, one-handed hasta.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "weapon_interface": "14", + "turn180_anim": "1206", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "12300", + "stand_anim": "813", + "attack_audios": "2562,2556,2555,2562", + "name": "Rune hasta(p)", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "11414", + "stand_turn_anim": "1209", + "bonuses": "36,36,36,0,0,-10,-10,-9,0,-10,0,42,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "12300", + "durability": null, + "name": "Rune hasta(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11415" + }, + { + "requirements": "{0,40}", + "turn90cw_anim": "1207", + "examine": "A karambwan poison-tipped, one-handed rune hasta.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "weapon_interface": "14", + "turn180_anim": "1206", + "render_anim": "28", + "equipment_slot": "3", + "stand_anim": "813", + "attack_audios": "2562,2556,2555,2562", + "name": "Rune hasta(kp)", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "11416", + "stand_turn_anim": "1209", + "bonuses": "36,36,36,0,0,-10,-10,-9,0,-10,0,42,0,0,0" + }, + { + "requirements": "{0,40}", + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A rune-tipped, one-handed hasta.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "weapon_interface": "14", + "turn180_anim": "1206", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "12200", + "stand_anim": "813", + "attack_audios": "2562,2556,2555,2562", + "name": "Rune hasta(p+)", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "11417", + "stand_turn_anim": "1209", + "bonuses": "36,36,36,0,0,-10,-10,-9,0,-10,0,42,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "12200", + "durability": null, + "name": "Rune hasta(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11418" + }, + { + "requirements": "{0,40}", + "ge_buy_limit": "100", + "turn90cw_anim": "1207", + "examine": "A rune-tipped, one-handed hasta.", + "walk_anim": "1205", + "durability": null, + "weight": "2.2", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "weapon_interface": "14", + "turn180_anim": "1206", + "render_anim": "28", + "equipment_slot": "3", + "grand_exchange_price": "15500", + "stand_anim": "813", + "attack_audios": "2562,2556,2555,2562", + "name": "Rune hasta(p++)", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "11419", + "stand_turn_anim": "1209", + "bonuses": "36,36,36,0,0,-10,-10,-9,0,-10,0,42,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "15500", + "durability": null, + "name": "Rune hasta(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11420" + }, + { + "ge_buy_limit": "1000", + "examine": "One/Two dose(s) of fishy attack potion", + "grand_exchange_price": "20", + "durability": null, + "name": "Attack mix(2)", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "11429" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "20", + "durability": null, + "name": "Attack mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11430" + }, + { + "ge_buy_limit": "1000", + "examine": "One/Two dose(s) of fishy attack potion", + "grand_exchange_price": "19", + "durability": null, + "name": "Attack mix(1)", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "11431" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "19", + "durability": null, + "name": "Attack mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11432" + }, + { + "ge_buy_limit": "1000", + "examine": "Two doses of fishy antipoison potion.", + "grand_exchange_price": "455", + "durability": null, + "name": "Antipoison mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11433" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "455", + "durability": null, + "name": "Antipoison mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11434" + }, + { + "ge_buy_limit": "1000", + "examine": "Two doses of fishy antipoison potion.", + "grand_exchange_price": "608", + "durability": null, + "name": "Antipoison mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11435" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "608", + "durability": null, + "name": "Antipoison mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11436" + }, + { + "ge_buy_limit": "1000", + "examine": "2 dose: Two doses of fishy Relicym's balm.", + "grand_exchange_price": "264", + "durability": null, + "name": "Relicym's mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11437" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "264", + "durability": null, + "name": "Relicym's mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11438" + }, + { + "ge_buy_limit": "1000", + "examine": "2 dose: Two doses of fishy Relicym's balm.", + "grand_exchange_price": "131", + "durability": null, + "name": "Relicym's mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11439" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "131", + "durability": null, + "name": "Relicym's mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11440" + }, + { + "ge_buy_limit": "1000", + "examine": "One/two doses of fishy strength potion.", + "grand_exchange_price": "159", + "durability": null, + "name": "Strength mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11441" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "159", + "durability": null, + "name": "Strength mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11442" + }, + { + "ge_buy_limit": "1000", + "examine": "One/two doses of fishy strength potion.", + "grand_exchange_price": "164", + "durability": null, + "name": "Strength mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11443" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "164", + "durability": null, + "name": "Strength mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11444" + }, + { + "ge_buy_limit": "1000", + "examine": "One/two doses of a fishy Combat potion", + "grand_exchange_price": "366", + "durability": null, + "name": "Combat mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11445" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "366", + "durability": null, + "name": "Combat mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11446" + }, + { + "ge_buy_limit": "1000", + "examine": "One/two doses of a fishy Combat potion", + "grand_exchange_price": "328", + "durability": null, + "name": "Combat mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11447" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "328", + "durability": null, + "name": "Combat mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11448" + }, + { + "ge_buy_limit": "1000", + "examine": "One/two dose(s) of fishy restore potion.", + "grand_exchange_price": "17", + "durability": null, + "name": "Restore mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11449" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "17", + "durability": null, + "name": "Restore mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11450" + }, + { + "ge_buy_limit": "1000", + "examine": "One/two dose(s) of fishy restore potion.", + "grand_exchange_price": "24", + "durability": null, + "name": "Restore mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11451" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "24", + "durability": null, + "name": "Restore mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11452" + }, + { + "ge_buy_limit": "1000", + "examine": "One/two doses of fishy energy potion.", + "grand_exchange_price": "248", + "durability": null, + "name": "Energy mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11453" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "248", + "durability": null, + "name": "Energy mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11454" + }, + { + "ge_buy_limit": "1000", + "examine": "One/two doses of fishy energy potion.", + "grand_exchange_price": "212", + "durability": null, + "name": "Energy mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11455" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "212", + "durability": null, + "name": "Energy mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11456" + }, + { + "ge_buy_limit": "1000", + "examine": "One/two doses of a fishy defence potion", + "grand_exchange_price": "887", + "durability": null, + "name": "Defence mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11457" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "887", + "durability": null, + "name": "Defence mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11458" + }, + { + "ge_buy_limit": "1000", + "examine": "One/two doses of a fishy defence potion", + "grand_exchange_price": "780", + "durability": null, + "name": "Defence mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11459" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "780", + "durability": null, + "name": "Defence mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11460" + }, + { + "ge_buy_limit": "1000", + "examine": "2 doses of a fishy agility potion", + "grand_exchange_price": "388", + "durability": null, + "name": "Agility mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11461" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "388", + "durability": null, + "name": "Agility mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11462" + }, + { + "ge_buy_limit": "1000", + "examine": "1 dose of a fishy agility potion", + "grand_exchange_price": "459", + "durability": null, + "name": "Agility mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11463" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "459", + "durability": null, + "name": "Agility mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11464" + }, + { + "ge_buy_limit": "1000", + "examine": "One/two dose(s) of a fishy Prayer potion.", + "grand_exchange_price": "2761", + "durability": null, + "name": "Prayer mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11465" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "2761", + "durability": null, + "name": "Prayer mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11466" + }, + { + "ge_buy_limit": "1000", + "examine": "One/two dose(s) of a fishy Prayer potion.", + "grand_exchange_price": "1857", + "durability": null, + "name": "Prayer mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11467" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1857", + "durability": null, + "name": "Prayer mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11468" + }, + { + "ge_buy_limit": "1000", + "examine": "one/two doses of fishy super attack potion", + "grand_exchange_price": "375", + "durability": null, + "name": "Superattack mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11469" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "375", + "durability": null, + "name": "Superattack mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11470" + }, + { + "ge_buy_limit": "1000", + "examine": "one/two doses of fishy super attack potion", + "grand_exchange_price": "516", + "durability": null, + "name": "Superattack mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11471" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "516", + "durability": null, + "name": "Superattack mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11472" + }, + { + "ge_buy_limit": "1000", + "examine": "One/Two dose(s) of fishy super antipoison potion.", + "grand_exchange_price": "613", + "durability": null, + "name": "Anti-p supermix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11473" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "613", + "durability": null, + "name": "Anti-p supermix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11474" + }, + { + "ge_buy_limit": "1000", + "examine": "One/Two dose(s) of fishy super antipoison potion.", + "grand_exchange_price": "1119", + "durability": null, + "name": "Anti-p supermix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11475" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1119", + "durability": null, + "name": "Anti-p supermix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11476" + }, + { + "ge_buy_limit": "1000", + "examine": "One/Two Doses of fishy fishing potion.", + "grand_exchange_price": "123", + "durability": null, + "name": "Fishing mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11477" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "123", + "durability": null, + "name": "Fishing mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11478" + }, + { + "ge_buy_limit": "1000", + "examine": "One/Two Doses of fishy fishing potion.", + "grand_exchange_price": "87", + "durability": null, + "name": "Fishing mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11479" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "87", + "durability": null, + "name": "Fishing mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11480" + }, + { + "ge_buy_limit": "1000", + "examine": "One/Two doses of fishy super energy potion.", + "grand_exchange_price": "1062", + "durability": null, + "name": "Super energy mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11481" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1062", + "durability": null, + "name": "Super energy mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11482" + }, + { + "ge_buy_limit": "1000", + "examine": "One/Two doses of fishy super energy potion.", + "grand_exchange_price": "562", + "durability": null, + "name": "Super energy mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11483" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "562", + "durability": null, + "name": "Super energy mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11484" + }, + { + "ge_buy_limit": "1000", + "examine": "One/Two doses of fishy Super strength potion.", + "grand_exchange_price": "955", + "durability": null, + "name": "Super strength mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11485" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "955", + "durability": null, + "name": "Super strength mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11486" + }, + { + "ge_buy_limit": "1000", + "examine": "One/Two doses of fishy Super strength potion.", + "grand_exchange_price": "1040", + "durability": null, + "name": "Super strength mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11487" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1040", + "durability": null, + "name": "Super strength mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11488" + }, + { + "ge_buy_limit": "1000", + "examine": "One/Two doses of fishy Magic essence potion.", + "grand_exchange_price": "808", + "durability": null, + "name": "Magic ess. mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11489" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "808", + "durability": null, + "name": "Magic ess. mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11490" + }, + { + "ge_buy_limit": "1000", + "examine": "One/Two doses of fishy Magic essence potion.", + "grand_exchange_price": "447", + "durability": null, + "name": "Magic ess. mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11491" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "447", + "durability": null, + "name": "Magic ess. mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11492" + }, + { + "ge_buy_limit": "1000", + "examine": "One/Two doses of fishy super restore potion.", + "grand_exchange_price": "3670", + "durability": null, + "name": "Super restore mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11493" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "3670", + "durability": null, + "name": "Super restore mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11494" + }, + { + "ge_buy_limit": "1000", + "examine": "One/Two doses of fishy super restore potion.", + "grand_exchange_price": "3104", + "durability": null, + "name": "Super restore mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11495" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "3104", + "durability": null, + "name": "Super restore mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11496" + }, + { + "ge_buy_limit": "1000", + "examine": "One/two doses of fishy super defence potion", + "grand_exchange_price": "38", + "durability": null, + "name": "Super defence mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11497" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "38", + "durability": null, + "name": "Super defence mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11498" + }, + { + "ge_buy_limit": "1000", + "examine": "One/two doses of fishy super defence potion", + "grand_exchange_price": "66", + "durability": null, + "name": "Super defence mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11499" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "66", + "durability": null, + "name": "Super defence mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11500" + }, + { + "ge_buy_limit": "1000", + "examine": "One/Two doses of fishy extra strength antidote potion.", + "grand_exchange_price": "1909", + "durability": null, + "name": "Antidote+ mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11501" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1909", + "durability": null, + "name": "Antidote+ mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11502" + }, + { + "ge_buy_limit": "1000", + "examine": "One/Two doses of fishy extra strength antidote potion.", + "grand_exchange_price": "1330", + "durability": null, + "name": "Antidote+ mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11503" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1330", + "durability": null, + "name": "Antidote+ mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11504" + }, + { + "ge_buy_limit": "1000", + "examine": "One/Two dose(s) of fishy anti-fire breath potion.", + "grand_exchange_price": "2048", + "durability": null, + "name": "Antifire mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11505" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "2048", + "durability": null, + "name": "Antifire mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11506" + }, + { + "ge_buy_limit": "1000", + "examine": "One/Two dose(s) of fishy anti-fire breath potion.", + "grand_exchange_price": "1444", + "durability": null, + "name": "Antifire mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11507" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1444", + "durability": null, + "name": "Antifire mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11508" + }, + { + "ge_buy_limit": "1000", + "examine": "One/Two doses of fishy ranging potion.", + "grand_exchange_price": "2879", + "durability": null, + "name": "Ranging mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11509" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "2879", + "durability": null, + "name": "Ranging mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11510" + }, + { + "ge_buy_limit": "1000", + "examine": "One/Two doses of fishy ranging potion.", + "grand_exchange_price": "1880", + "durability": null, + "name": "Ranging mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11511" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1880", + "durability": null, + "name": "Ranging mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11512" + }, + { + "ge_buy_limit": "1000", + "examine": "One/Two doses of fishy magic potion.", + "grand_exchange_price": "1022", + "durability": null, + "name": "Magic mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11513" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1022", + "durability": null, + "name": "Magic mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11514" + }, + { + "ge_buy_limit": "1000", + "examine": "One/Two doses of fishy magic potion.", + "grand_exchange_price": "1323", + "durability": null, + "name": "Magic mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11515" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "1323", + "durability": null, + "name": "Magic mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11516" + }, + { + "ge_buy_limit": "1000", + "examine": "Doses of fishy hunting potion", + "grand_exchange_price": "146", + "durability": null, + "name": "Hunting mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11517" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "146", + "durability": null, + "name": "Hunting mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11518" + }, + { + "ge_buy_limit": "1000", + "examine": "Doses of fishy hunting potion", + "grand_exchange_price": "87", + "durability": null, + "name": "Hunting mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11519" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "87", + "durability": null, + "name": "Hunting mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11520" + }, + { + "ge_buy_limit": "1000", + "examine": "One/Two doses of fishy Zamorak potion.", + "grand_exchange_price": "665", + "durability": null, + "name": "Zamorak mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11521" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "665", + "durability": null, + "name": "Zamorak mix(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11522" + }, + { + "ge_buy_limit": "1000", + "examine": "One/Two doses of fishy Zamorak potion.", + "grand_exchange_price": "339", + "durability": null, + "name": "Zamorak mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0.1", + "id": "11523" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "339", + "durability": null, + "name": "Zamorak mix(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11524" + }, + { + "ge_buy_limit": "5000", + "examine": "More fluff than feather.", + "grand_exchange_price": "325", + "durability": null, + "name": "Wimpy feather", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11525" + }, + { + "destroy_message": "If you drop this book it will be destroyed. You cannot replace it.", + "examine": "Educate yourself.", + "durability": null, + "name": "Book of knowledge", + "weight": "1", + "archery_ticket_price": "0", + "id": "11640" + }, + { + "durability": null, + "name": "Astronomy book", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11655" + }, + { + "ge_buy_limit": "100", + "examine": "A book that explains the art of crafting items from glass.", + "grand_exchange_price": "278", + "durability": null, + "name": "Glassblowing book", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11656" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "278", + "durability": null, + "name": "Glassblowing book", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11657" + }, + { + "remove_head": "true", + "requirements": "{0,42}-{1,42}-{2,42}-{3,42}-{4,42}-{5,22}-{6,42}", + "shop_price": "200", + "examine": "A mage helm from the order of the Void Knights.", + "durability": null, + "name": "Void mage helm", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11663", + "bonuses": "0,0,0,0,0,6,6,6,6,6,6,0,0,0,0", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "requirements": "{0,42}-{1,42}-{2,42}-{3,42}-{4,42}-{5,22}-{6,42}", + "shop_price": "200", + "examine": "A ranger helm from the order of the Void Knights", + "durability": null, + "name": "Void ranger helm", + "tradeable": "false", + "weight": "3.6", + "archery_ticket_price": "0", + "id": "11664", + "bonuses": "0,0,0,0,0,6,6,6,6,6,6,0,0,0,0", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "requirements": "{0,42}-{1,42}-{2,42}-{3,42}-{4,42}-{5,22}-{6,42}", + "shop_price": "200", + "examine": "A melee helm from the order of the Void Knights.", + "durability": null, + "name": "Void melee helm", + "tradeable": "false", + "weight": "1", + "archery_ticket_price": "0", + "id": "11665", + "bonuses": "0,0,0,0,0,6,6,6,6,6,6,0,0,0,0", + "equipment_slot": "0" + }, + { + "durability": null, + "name": "Void seal(8)", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "11666", + "bonuses": "0,0,0,0,0,1,1,1,1,1,1,0,0,0,0", + "equipment_slot": "2" + }, + { + "durability": null, + "name": "Void seal(7)", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "11667", + "bonuses": "0,0,0,0,0,1,1,1,1,1,1,0,0,0,0", + "equipment_slot": "2" + }, + { + "durability": null, + "name": "Void seal(6)", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "11668", + "bonuses": "0,0,0,0,0,1,1,1,1,1,1,0,0,0,0", + "equipment_slot": "2" + }, + { + "durability": null, + "name": "Void seal(5)", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "11669", + "bonuses": "0,0,0,0,0,1,1,1,1,1,1,0,0,0,0", + "equipment_slot": "2" + }, + { + "durability": null, + "name": "Void seal(4)", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "11670", + "bonuses": "0,0,0,0,0,1,1,1,1,1,1,0,0,0,0", + "equipment_slot": "2" + }, + { + "durability": null, + "name": "Void seal(3)", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "11671", + "bonuses": "0,0,0,0,0,1,1,1,1,1,1,0,0,0,0", + "equipment_slot": "2" + }, + { + "durability": null, + "name": "Void seal(2)", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "11672", + "bonuses": "0,0,0,0,0,1,1,1,1,1,1,0,0,0,0", + "equipment_slot": "2" + }, + { + "durability": null, + "name": "Void seal(1)", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "11673", + "bonuses": "0,0,0,0,0,1,1,1,1,1,1,0,0,0,0", + "equipment_slot": "2" + }, + { + "remove_head": "true", + "requirements": "{0,42}-{1,42}-{2,42}-{3,42}-{4,42}-{5,22}-{6,42}", + "shop_price": "200", + "examine": "A mage helm from the order of the Void Knights.", + "durability": null, + "name": "Void mage helm", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11674", + "bonuses": "0,0,0,0,0,6,6,6,6,6,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "requirements": "{0,42}-{1,42}-{2,42}-{3,42}-{4,42}-{5,22}-{6,42}", + "shop_price": "200", + "examine": "A ranger helm from the order of the Void Knights", + "durability": null, + "name": "Void ranger helm", + "tradeable": "false", + "weight": "3.6", + "archery_ticket_price": "0", + "id": "11675", + "bonuses": "0,0,0,0,0,6,6,6,6,6,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "requirements": "{0,42}-{1,42}-{2,42}-{3,42}-{4,42}-{5,22}-{6,42}", + "shop_price": "200", + "examine": "A melee helm from the order of the Void Knights.", + "durability": null, + "name": "Void melee helm", + "tradeable": "false", + "weight": "1", + "archery_ticket_price": "0", + "id": "11676", + "bonuses": "0,0,0,0,0,6,6,6,6,6,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "destroy_message": "I can find another book in the Keldagrim library.", + "examine": "\"Beyond Trollheim\" by Nestor Peregrine.", + "durability": null, + "name": "Explorer's notes", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11677" + }, + { + "destroy_message": "You'll need to visit the Sinclair Mansion to get another one.", + "examine": "A black helm, too small for your head", + "durability": null, + "name": "Black knight helm", + "tradeable": "false", + "destroy": "true", + "weight": "3", + "archery_ticket_price": "0", + "id": "11678" + }, + { + "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", + "examine": "I wonder what happens if I rub it.", + "durability": null, + "name": "Antique lamp", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11679" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A change of address form.", + "durability": null, + "name": "Address form", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11680" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "It has something written on it.", + "durability": null, + "name": "Scrap paper", + "archery_ticket_price": "0", + "id": "11681" + }, + { + "examine": "I could use this to pick the lock.", + "durability": null, + "name": "Hair clip", + "archery_ticket_price": "0", + "id": "11682" + }, + { + "ge_buy_limit": "10", + "examine": "Godsword shards 1 and 2.Godsword shards 2 and 3.Godsword shards 1 and 3.", + "grand_exchange_price": "331300", + "durability": null, + "name": "Godsword shards", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11686" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "331300", + "durability": null, + "name": "Godsword shards", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11687" + }, + { + "ge_buy_limit": "10", + "examine": "Godsword shards 1 and 2.Godsword shards 2 and 3.Godsword shards 1 and 3.", + "grand_exchange_price": "342100", + "durability": null, + "name": "Godsword shards", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11688" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "342100", + "durability": null, + "name": "Godsword shards", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11689" + }, + { + "ge_buy_limit": "10", + "examine": "The blade for the ultimate weapon.", + "grand_exchange_price": "466800", + "durability": null, + "name": "Godsword blade", + "tradeable": "true", + "weight": "7.5", + "archery_ticket_price": "0", + "id": "11690" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "466800", + "durability": null, + "name": "Godsword blade", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11691" + }, + { + "ge_buy_limit": "10", + "examine": "Godsword shards 1 and 2.Godsword shards 2 and 3.Godsword shards 1 and 3.", + "grand_exchange_price": "348500", + "durability": null, + "name": "Godsword shards", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11692" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "348500", + "durability": null, + "name": "Godsword shards", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11693" + }, + { + "ge_buy_limit": "10", + "turn90cw_anim": "7043", + "examine": "A beautiful, heavy sword.", + "walk_anim": "7046", + "has_special": "true", + "rare_item": "true", + "turn90ccw_anim": "7044", + "attack_speed": "6", + "two_handed": "true", + "turn180_anim": "7045", + "defence_anim": "7050", + "equipment_slot": "3", + "attack_anims": "7041,7041,7048,7049", + "grand_exchange_price": "28000000", + "stand_anim": "7047", + "tradeable": "true", + "run_anim": "7039", + "archery_ticket_price": "0", + "id": "11694", + "stand_turn_anim": "7040", + "bonuses": "0,132,80,0,0,0,0,0,0,0,0,132,8,0,0", + "requirements": "{0,75}", + "durability": null, + "weight": "10", + "weapon_interface": "7", + "equip_audio": "2248", + "render_anim": "124", + "lendable": "true", + "attack_audios": "3846,0,0,0", + "name": "Armadyl godsword" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "28000000", + "durability": null, + "name": "Armadyl godsword", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11695" + }, + { + "ge_buy_limit": "10", + "turn90cw_anim": "7043", + "examine": "A brutally heavy sword.", + "walk_anim": "7046", + "has_special": "true", + "rare_item": "true", + "turn90ccw_anim": "7044", + "attack_speed": "6", + "two_handed": "true", + "turn180_anim": "7045", + "defence_anim": "7050", + "equipment_slot": "3", + "attack_anims": "7041,7041,7048,7049", + "grand_exchange_price": "3700000", + "stand_anim": "7047", + "tradeable": "true", + "run_anim": "7039", + "archery_ticket_price": "0", + "id": "11696", + "stand_turn_anim": "7040", + "bonuses": "0,132,80,0,0,0,0,0,0,0,0,132,8,0,0", + "requirements": "{0,75}", + "durability": null, + "weight": "10", + "weapon_interface": "7", + "equip_audio": "2248", + "render_anim": "124", + "lendable": "true", + "attack_audios": "3846,0,0,0", + "name": "Bandos godsword" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "3700000", + "durability": null, + "name": "Bandos godsword", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11697" + }, + { + "ge_buy_limit": "10", + "turn90cw_anim": "7043", + "examine": "A gracious, heavy sword.", + "walk_anim": "7046", + "has_special": "true", + "turn90ccw_anim": "7044", + "attack_speed": "6", + "two_handed": "true", + "turn180_anim": "7045", + "defence_anim": "7050", + "equipment_slot": "3", + "attack_anims": "7041,7041,7048,7049", + "grand_exchange_price": "22000000", + "stand_anim": "7047", + "tradeable": "true", + "run_anim": "7039", + "archery_ticket_price": "0", + "id": "11698", + "stand_turn_anim": "7040", + "bonuses": "0,132,80,0,0,0,0,0,0,0,0,132,8,0,0", + "requirements": "{0,75}", + "durability": null, + "weight": "10", + "weapon_interface": "7", + "equip_audio": "2248", + "render_anim": "124", + "lendable": "true", + "attack_audios": "3846,0,0,0", + "name": "Saradomin godsword" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "22000000", + "durability": null, + "name": "Saradomin godsword", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11699" + }, + { + "ge_buy_limit": "10", + "turn90cw_anim": "7043", + "examine": "A terrifying, heavy sword.", + "walk_anim": "7046", + "has_special": "true", + "turn90ccw_anim": "7044", + "attack_speed": "6", + "two_handed": "true", + "turn180_anim": "7045", + "defence_anim": "7050", + "equipment_slot": "3", + "attack_anims": "7041,7041,7048,7049", + "grand_exchange_price": "6100000", + "stand_anim": "7047", + "tradeable": "true", + "run_anim": "7039", + "archery_ticket_price": "0", + "id": "11700", + "stand_turn_anim": "7040", + "bonuses": "0,132,80,0,0,0,0,0,0,0,0,132,8,0,0", + "requirements": "{0,75}", + "durability": null, + "weight": "10", + "weapon_interface": "7", + "equip_audio": "2248", + "render_anim": "124", + "lendable": "true", + "attack_audios": "3846,0,0,0", + "name": "Zamorak godsword" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "6100000", + "durability": null, + "name": "Zamorak godsword", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11701" + }, + { + "ge_buy_limit": "10", + "examine": "Brimming with potential.", + "grand_exchange_price": "30600000", + "rare_item": "true", + "durability": null, + "name": "Armadyl hilt", + "tradeable": "true", + "weight": "2.5", + "archery_ticket_price": "0", + "id": "11702" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "30600000", + "durability": null, + "name": "Armadyl hilt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11703" + }, + { + "ge_buy_limit": "10", + "examine": "Brimming with potential.", + "grand_exchange_price": "3300000", + "rare_item": "true", + "durability": null, + "name": "Bandos hilt", + "tradeable": "true", + "weight": "2.5", + "archery_ticket_price": "0", + "id": "11704" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "3300000", + "durability": null, + "name": "Bandos hilt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11705" + }, + { + "ge_buy_limit": "10", + "examine": "Brimming with potential.", + "grand_exchange_price": "24900000", + "rare_item": "true", + "durability": null, + "name": "Saradomin hilt", + "tradeable": "true", + "weight": "2.5", + "archery_ticket_price": "0", + "id": "11706" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "24900000", + "durability": null, + "name": "Saradomin hilt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11707" + }, + { + "ge_buy_limit": "10", + "examine": "Brimming with potential.", + "grand_exchange_price": "6100000", + "rare_item": "true", + "durability": null, + "name": "Zamorak hilt", + "tradeable": "true", + "weight": "2.5", + "archery_ticket_price": "0", + "id": "11708" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "6100000", + "durability": null, + "name": "Zamorak hilt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11709" + }, + { + "ge_buy_limit": "10", + "examine": "Part of the Godsword blade.", + "grand_exchange_price": "150200", + "durability": null, + "rare_item": "true", + "name": "Godsword shard 1", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "11710" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "150200", + "durability": null, + "name": "Godsword shard 1", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11711" + }, + { + "ge_buy_limit": "10", + "examine": "Part of the Godsword blade.", + "grand_exchange_price": "149100", + "durability": null, + "rare_item": "true", + "name": "Godsword shard 2", + "tradeable": "true", + "destroy": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "11712" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "149100", + "durability": null, + "name": "Godsword shard 2", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11713" + }, + { + "ge_buy_limit": "10", + "examine": "Part of the Godsword blade.", + "grand_exchange_price": "149800", + "durability": null, + "rare_item": "true", + "name": "Godsword shard 3", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "11714" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "149800", + "durability": null, + "name": "Godsword shard 3", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11715" + }, + { + "ge_buy_limit": "10", + "turn90cw_anim": "1207", + "examine": "An evil spear.", + "walk_anim": "1205", + "has_special": "true", + "rare_item": "true", + "turn90ccw_anim": "1208", + "attack_speed": "4", + "two_handed": "true", + "turn180_anim": "1206", + "defence_anim": "2079", + "equipment_slot": "3", + "attack_anims": "2080,2081,2082,2080", + "grand_exchange_price": "5400000", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "11716", + "stand_turn_anim": "1209", + "bonuses": "85,65,65,0,0,13,13,12,0,13,0,75,2,0,0", + "requirements": "{0,70}", + "durability": null, + "weight": "3", + "weapon_interface": "14", + "equip_audio": "2247", + "render_anim": "28", + "lendable": "true", + "name": "Zamorakian spear" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "5400000", + "durability": null, + "name": "Zamorakian spear", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11717" + }, + { + "remove_head": "true", + "requirements": "{1,70}-{4,70}", + "ge_buy_limit": "1", + "examine": "A helmet of great craftmanship.", + "rare_item": "true", + "durability": null, + "weight": "0.5", + "absorb": "0,5,2", + "equip_audio": "2240", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "4100000", + "name": "Armadyl helmet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11718", + "bonuses": "-5,-5,-5,-5,10,6,8,10,10,8,12,0,1,0,0" + }, + { + "ge_buy_limit": "1", + "grand_exchange_price": "4100000", + "durability": null, + "name": "Armadyl helmet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11719" + }, + { + "requirements": "{1,70}-{4,70}", + "ge_buy_limit": "1", + "examine": "A chestplate of great craftsmanship", + "rare_item": "true", + "durability": null, + "weight": "4", + "absorb": "0,10,5", + "equip_audio": "2239", + "equipment_slot": "4", + "lendable": "true", + "remove_sleeves": "true", + "grand_exchange_price": "14800000", + "name": "Armadyl chestplate", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11720", + "bonuses": "-7,-7,-7,-15,33,56,48,61,70,57,52,0,1,0,0" + }, + { + "ge_buy_limit": "1", + "grand_exchange_price": "14800000", + "durability": null, + "name": "Armadyl chestplate", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11721" + }, + { + "requirements": "{1,70}-{4,70}", + "ge_buy_limit": "2", + "examine": "A plateskirt of great craftsmanship.", + "rare_item": "true", + "durability": null, + "weight": "8", + "absorb": "2,0,4", + "equip_audio": "2242", + "equipment_slot": "7", + "lendable": "true", + "grand_exchange_price": "14800000", + "name": "Armadyl plateskirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11722", + "bonuses": "-6,-6,-6,-10,20,32,26,34,40,33,25,0,1,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "14800000", + "durability": null, + "name": "Armadyl plateskirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11723" + }, + { + "requirements": "{1,65}", + "ge_buy_limit": "1", + "examine": "A sturdy chestplate.", + "rare_item": "true", + "durability": null, + "weight": "12", + "absorb": "4,0,9", + "equipment_slot": "4", + "lendable": "true", + "remove_sleeves": "true", + "grand_exchange_price": "14700000", + "name": "Bandos chestplate", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11724", + "bonuses": "0,0,0,-15,-10,98,93,105,-6,133,52,4,1,0,0" + }, + { + "ge_buy_limit": "1", + "grand_exchange_price": "14700000", + "durability": null, + "name": "Bandos chestplate", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11725" + }, + { + "requirements": "{1,65}", + "ge_buy_limit": "1", + "examine": "A sturdy pair of tassets.", + "rare_item": "true", + "durability": null, + "weight": "8", + "absorb": "3,0,6", + "equipment_slot": "7", + "lendable": "true", + "grand_exchange_price": "15200000", + "name": "Bandos tassets", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11726", + "bonuses": "0,0,0,-21,-7,71,63,66,-4,93,25,2,1,0,0" + }, + { + "ge_buy_limit": "1", + "grand_exchange_price": "15200000", + "durability": null, + "name": "Bandos tassets", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11727" + }, + { + "requirements": "{1,65}", + "ge_buy_limit": "1", + "examine": "Some sturdy boots", + "rare_item": "true", + "durability": null, + "weight": "6", + "equip_audio": "2237", + "equipment_slot": "10", + "lendable": "true", + "grand_exchange_price": "111700", + "name": "Bandos boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11728", + "bonuses": "0,0,0,-5,-3,17,18,19,0,0,15,0,1,0,0" + }, + { + "ge_buy_limit": "1", + "grand_exchange_price": "111700", + "durability": null, + "name": "Bandos boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11729" + }, + { + "ge_buy_limit": "10", + "turn90cw_anim": "7043", + "examine": "The incredible blade of an Icyene.", + "walk_anim": "7046", + "has_special": "true", + "rare_item": "true", + "turn90ccw_anim": "7044", + "attack_speed": "4", + "two_handed": "true", + "turn180_anim": "7045", + "defence_anim": "7050", + "equipment_slot": "3", + "attack_anims": "7041,7041,7048,7049", + "grand_exchange_price": "5300000", + "stand_anim": "7047", + "tradeable": "true", + "run_anim": "7039", + "archery_ticket_price": "0", + "id": "11730", + "stand_turn_anim": "7040", + "bonuses": "0,82,60,0,0,0,0,0,0,0,0,82,2,0,0", + "requirements": "{0,70}", + "durability": null, + "weight": "3", + "weapon_interface": "7", + "equip_audio": "2248", + "render_anim": "124", + "lendable": "true", + "attack_audios": "3846,0,0,0", + "name": "Saradomin sword" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "5300000", + "durability": null, + "name": "Saradomin sword", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11731" + }, + { + "requirements": "{1,60}", + "ge_buy_limit": "10", + "examine": "These will protect my feet.", + "durability": null, + "rare_item": "true", + "weight": "1", + "equip_audio": "2237", + "equipment_slot": "10", + "lendable": "true", + "grand_exchange_price": "95400", + "name": "Dragon boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11732", + "bonuses": "0,0,0,-3,-1,16,17,18,0,0,15,4,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "95400", + "durability": null, + "name": "Dragon boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11733" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A scroll for Sir Tiffy. It is sealed with a wax insignia.", + "durability": null, + "name": "Knight's notes", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11734" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A scroll for Sir Tiffy. The wax seal is broken.", + "durability": null, + "name": "Knight's notes", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11735" + }, + { + "ge_buy_limit": "10", + "turn90cw_anim": "1207", + "examine": "It's a slightly magical stick.", + "walk_anim": "1205", + "rare_item": "true", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "turn180_anim": "1206", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "grand_exchange_price": "231300", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "11736", + "stand_turn_anim": "1209", + "bonuses": "7,-1,28,12,0,2,3,1,12,0,0,35,0,0,0", + "requirements": "{0,30}-{6,30}", + "durability": null, + "weight": "2", + "weapon_interface": "1", + "equip_audio": "2230", + "render_anim": "28", + "attack_audios": "2555,0,0,0", + "name": "Steam battlestaff" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "231300", + "durability": null, + "name": "Steam battlestaff", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11737" + }, + { + "ge_buy_limit": "10", + "turn90cw_anim": "1207", + "examine": "It's a slightly magical stick.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "turn180_anim": "1206", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "grand_exchange_price": "267600", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "11738", + "stand_turn_anim": "1209", + "bonuses": "10,-1,40,14,0,2,3,1,14,0,0,50,0,0,0", + "requirements": "{0,40}-{6,40}", + "durability": null, + "weight": "2", + "weapon_interface": "1", + "equip_audio": "2247", + "render_anim": "28", + "attack_audios": "2555,0,0,0", + "name": "Mystic steam staff" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "267600", + "durability": null, + "name": "Mystic steam staff", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11739" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11741" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11743" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11745" + }, + { + "destroy_message": "There may be another in the chest where you found this.", + "examine": "This probably opens a chest in Golrie's caves. (Path of Glophrie)", + "durability": null, + "name": "A key to a chest", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11747" + }, + { + "destroy_message": "There may be another in the chest where you found this.", + "examine": "This opens the door into Golrie's strongroom. (Path of Glophrie)", + "durability": null, + "name": "Strongroom key", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11748" + }, + { + "destroy_message": "Maybe Brimstail will have another crystal seed you could grow into a chime.", + "examine": "It makes a sound.", + "durability": null, + "name": "Crystal chime", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11749", + "equipment_slot": "3" + }, + { + "destroy_message": "There may be another in the chest where you found this.", + "examine": "Notes written by Yewnock while copying Oaknock's machine.", + "durability": null, + "name": "Yewnock's notes", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11750" + }, + { + "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", + "examine": "I wonder what happens if I rub it.", + "durability": null, + "name": "Antique lamp", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11753" + }, + { + "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", + "examine": "I wonder what happens if I rub it.", + "durability": null, + "name": "Antique lamp", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11754" + }, + { + "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", + "examine": "I wonder what happens if I rub it.", + "durability": null, + "name": "Antique lamp", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11755" + }, + { + "destroy_message": "You will need to get a new set of armour from Rat Burgiss if you destroy this one.", + "remove_sleeves": "true", + "examine": "Varrock Smithing armour.", + "durability": null, + "name": "Varrock armour 1", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11756", + "bonuses": "0,0,0,-30,-10,15,14,9,-6,14,5,0,0,0,0", + "equipment_slot": "4" + }, + { + "destroy_message": "You will need to get a new set of armour from Reldo if you destroy this one.", + "remove_sleeves": "true", + "examine": "Varrock smithing armour.", + "durability": null, + "name": "Varrock armour 2", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11757", + "bonuses": "0,0,0,-30,-10,21,20,12,-6,20,5,0,0,0,0", + "equipment_slot": "4" + }, + { + "destroy_message": "You will need to get a new set of armour from Vannaka if you destroy this one.", + "remove_sleeves": "true", + "examine": "Varrock smithing armour.", + "durability": null, + "name": "Varrock armour 3", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11758", + "bonuses": "0,0,0,-30,-10,32,31,24,-6,31,5,0,0,0,0", + "equipment_slot": "4" + }, + { + "shop_price": "4", + "examine": "A number of wooden logs.", + "grand_exchange_price": "124", + "durability": null, + "name": "Logs", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "11760" + }, + { + "destroy_message": "You can get the diary again from Sandy's desk.", + "examine": "A locked/unlocked diary.", + "durability": null, + "name": "Locked diary", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11761" + }, + { + "destroy_message": "You can get the diary again from Sandy's desk.", + "examine": "A locked/unlocked diary.", + "durability": null, + "name": "Unlocked diary", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11762" + }, + { + "destroy_message": "You can get the foot again from the creatures in the Jade Vine.", + "examine": "A wizard's severed foot. You can tell by the robes.", + "durability": null, + "name": "Foot", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11764" + }, + { + "destroy_message": "You can get the arm again from the creatures in the Jade Vine.", + "examine": "\"A wizard's severed arm. You can tell by the robes.", + "durability": null, + "name": "Left arm", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11766" + }, + { + "destroy_message": "You can get the arm again from the creatures in the Jade Vine.", + "examine": "A wizard's severed arm. You can tell by the robes.", + "durability": null, + "name": "Right arm", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11767" + }, + { + "destroy_message": "You can get the leg again from the creatures in the Jade Vine.", + "examine": "A wizard's severed leg. You can tell by the robes.", + "durability": null, + "name": "Left leg", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11768" + }, + { + "destroy_message": "You can get the leg again from the creatures in the Jade Vine.", + "examine": "A wizard's severed leg. You can tell by the robes.", + "durability": null, + "name": "Right leg", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11769" + }, + { + "examine": "A root cutting.", + "durability": null, + "name": "Root cutting", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11770" + }, + { + "examine": "A root cutting.", + "durability": null, + "name": "Root cutting", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11771" + }, + { + "examine": "A root cutting.", + "durability": null, + "name": "Root cutting", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11772" + }, + { + "examine": "A root cutting.", + "durability": null, + "name": "Root cutting", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11773" + }, + { + "examine": "A root cutting.", + "durability": null, + "name": "Root cutting", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11774" + }, + { + "examine": "A floppy root cutting. Quite dead.", + "durability": null, + "name": "Wilted cutting", + "archery_ticket_price": "0", + "id": "11775" + }, + { + "examine": "A potted root.", + "durability": null, + "name": "Potted root", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11776" + }, + { + "destroy_message": "You can get the sealed pot back by visiting Garth, the farmer on Karamja.", + "examine": "This sealed pot contains your vine cutting - hopefully still alive.", + "durability": null, + "name": "Sealed pot", + "tradeable": "false", + "destroy": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11777" + }, + { + "examine": "A large seed.", + "durability": null, + "name": "Jade vine seed", + "archery_ticket_price": "0", + "id": "11778" + }, + { + "destroy_message": "You'll have to find another from the Grim Reaper's house.", + "examine": "Surely this holds many a dark tale...", + "durability": null, + "name": "The grim reaper's diary", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11780" + }, + { + "bankable": "false", + "destroy_message": "Another can be found in the Grim Reaper's house.", + "examine": "Some of the Grim Reaper's garb.", + "durability": null, + "name": "Grim's robe", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11781" + }, + { + "bankable": "false", + "destroy_message": "You'll have to find another from the Grim Reaper's house.", + "examine": "Someone's Last Will and Testament.", + "durability": null, + "name": "Last will and testament", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11782" + }, + { + "bankable": "false", + "destroy_message": "You'll have to find another from the Grim Reaper's house.", + "examine": "A tasty treat for Muncher.", + "durability": null, + "name": "Human bones", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11783" + }, + { + "bankable": "false", + "destroy_message": "You'll have to find another from the Grim Reaper's house.", + "examine": "Ooooh spooky!", + "durability": null, + "name": "Servant's skull", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11784" + }, + { + "bankable": "false", + "destroy_message": "You can get a replacement from Diango in Draynor Village.", + "examine": "There's not much sand left in the top half...", + "durability": null, + "name": "Hourglass", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11785" + }, + { + "bankable": "false", + "destroy_message": "Another can be found in the Grim Reaper's house.", + "examine": "Used to sharpen the blade of a scythe.", + "durability": null, + "attack_audios": "2524,2524,2522,2524", + "name": "Scythe sharpener", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11786" + }, + { + "bankable": "false", + "destroy_message": "You'll have to find another from the Grim Reaper's house.", + "examine": "That's gross. Why am I carrying it around?", + "durability": null, + "name": "Human eye", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11787" + }, + { + "bankable": "false", + "destroy_message": "You'll have to find another from the Grim Reaper's house.", + "examine": "A 'Voice of Doom' potion, used to deepen your voice.", + "durability": null, + "name": "'voice of doom' potion", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11788" + }, + { + "remove_head": "true", + "destroy_message": "You should be able to get another from Diango in Draynor Village.", + "examine": "Allows me to imitate the harbinger of doom, the stealer of souls, the eternal end...", + "durability": null, + "name": "Grim reaper hood", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11789", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "destroy_message": "You should be able to get another from Diango in Draynor Village.", + "examine": "Allows me to imitate the harbinger of doom, the stealer of souls, the eternal end...", + "durability": null, + "name": "Grim reaper hood", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11790", + "remove_beard": "true", + "equipment_slot": "0" + }, + { + "examine": "Armour designed to fit goblins.", + "durability": null, + "name": "White goblin mail", + "weight": "3", + "archery_ticket_price": "0", + "id": "11791", + "equipment_slot": "4" + }, + { + "examine": "Smaller than the average goblin. After The Chosen Commander: Oldak's new assistant.", + "durability": null, + "name": "Grubfoot", + "archery_ticket_price": "0", + "id": "11792" + }, + { + "examine": "See article", + "durability": null, + "name": "Zanik", + "archery_ticket_price": "0", + "id": "11793" + }, + { + "shop_price": "32", + "examine": "Oldak's Marvellous Moving-Over-Distance Sphere", + "durability": null, + "name": "Plain of mud sphere", + "archery_ticket_price": "0", + "id": "11794" + }, + { + "destroy_message": "The Ekeleshuun priest probably has a spare.", + "examine": "The key you stole from the Ekeleshuun priest.", + "durability": null, + "name": "Ekeleshuun key", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11795" + }, + { + "destroy_message": "The Narogoshuun priest probably has a spare.", + "examine": "The key you stole from the Narogoshuun priest.", + "durability": null, + "name": "Narogoshuun key", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11796" + }, + { + "destroy_message": "The Huzamogaarb priest probably has a spare.", + "examine": "The key you stole from the Huzamogaarb priest.", + "durability": null, + "name": "Huzamogaarb key", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11797" + }, + { + "destroy_message": "The Saragorgak priest probably has a spare.", + "examine": "The key you stole from the Saragorgak priest.", + "durability": null, + "name": "Saragorgak key", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11798" + }, + { + "destroy_message": "The Horogothgar priest probably has a spare.", + "examine": "The key you stole from the Horogothgar priest.", + "durability": null, + "name": "Horogothgar key", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11799" + }, + { + "destroy_message": "The Yurkolgokh priest probably has a spare.", + "examine": "The key you stole from the Yurkolgokh priest.", + "durability": null, + "name": "Yurkolgokh key", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11800" + }, + { + "examine": "\"An ancient goblin bone wrapped in fragments of priestly robes.", + "durability": null, + "name": "Snothead's bone", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11802" + }, + { + "examine": "\"An ancient goblin bone wrapped in fragments of priestly robes.", + "durability": null, + "name": "Snailfeet's bone", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11803" + }, + { + "examine": "\"An ancient goblin bone wrapped in fragments of priestly robes.", + "durability": null, + "name": "Mosschin's bone", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11804" + }, + { + "examine": "\"An ancient goblin bone wrapped in fragments of priestly robes.", + "durability": null, + "name": "Redeyes's bone", + "archery_ticket_price": "0", + "id": "11805" + }, + { + "examine": "An ancient goblin bone wrapped in fragments of priestly robes.", + "durability": null, + "name": "Strongbones's bone", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11806" + }, + { + "examine": "You can combine these with a toadflax to make a goblin transformation potion.", + "durability": null, + "name": "Pharmakos berries", + "archery_ticket_price": "0", + "id": "11807" + }, + { + "examine": "An ugly albino fish.", + "durability": null, + "name": "Whitefish", + "weight": "0.25", + "archery_ticket_price": "0", + "id": "11808" + }, + { + "examine": "4 doses of goblin transmogrification potion.", + "durability": null, + "name": "Goblin potion (4)", + "archery_ticket_price": "0", + "id": "11809", + "equipment_slot": "5" + }, + { + "examine": "3 doses of goblin transmogrification potion.", + "durability": null, + "name": "Goblin potion (3)", + "archery_ticket_price": "0", + "id": "11810" + }, + { + "examine": "2 doses of goblin transmogrification potion.", + "durability": null, + "name": "Goblin potion (2)", + "archery_ticket_price": "0", + "id": "11811" + }, + { + "examine": "1 dose of goblin transmogrification potion.", + "durability": null, + "name": "Goblin potion (1)", + "archery_ticket_price": "0", + "id": "11812" + }, + { + "shop_price": "177", + "ge_buy_limit": "100", + "examine": "Grand Exchange set containing bronze full helm, platebody, legs and kiteshield.", + "grand_exchange_price": "614", + "durability": null, + "name": "Bronze armour set (l)", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11814" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "614", + "durability": null, + "name": "Bronze armour set (l)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11815" + }, + { + "shop_price": "177", + "ge_buy_limit": "100", + "examine": "Grand Exchange set containing bronze full helm, platebody, skirt and kiteshield.", + "grand_exchange_price": "938", + "durability": null, + "name": "Bronze armour set (sk)", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11816", + "bonuses": "0,0,0,-59,-19,27,26,18,-11,25,5,0,0,1,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "938", + "durability": null, + "name": "Bronze armour set (sk)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11817" + }, + { + "shop_price": "1022", + "ge_buy_limit": "100", + "examine": "Grand Exchange set containing iron full helm, platebody, legs, and kiteshield.", + "grand_exchange_price": "1830", + "durability": null, + "name": "Iron armour set (l)", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11818", + "bonuses": "0,0,0,-65,-21,46,44,33,-12,45,7,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1830", + "durability": null, + "name": "Iron armour set (l)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11819" + }, + { + "shop_price": "1022", + "ge_buy_limit": "100", + "examine": "Grand Exchange set containing iron full helm, platebody, skirt, and kiteshield.", + "grand_exchange_price": "1711", + "durability": null, + "name": "Iron armour set (sk)", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11820", + "bonuses": "0,0,0,-65,-21,46,44,33,-12,45,7,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1711", + "durability": null, + "name": "Iron armour set (sk)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11821" + }, + { + "requirements": "{5,1}", + "shop_price": "2365", + "ge_buy_limit": "100", + "examine": "Grand Exchange set containing steel full helm, platebody, legs and kiteshield.", + "grand_exchange_price": "3646", + "durability": null, + "name": "Steel armour set (l)", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11822", + "bonuses": "0,0,0,-65,-21,71,72,60,-12,70,15,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3646", + "durability": null, + "name": "Steel armour set (l)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11823" + }, + { + "requirements": "{5,1}", + "shop_price": "2365", + "ge_buy_limit": "100", + "examine": "Grand Exchange set containing steel full helm, platebody, skirt and kiteshield.", + "grand_exchange_price": "3796", + "durability": null, + "name": "Steel armour set (sk)", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11824", + "bonuses": "0,0,0,-65,-21,71,72,60,-12,70,15,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3796", + "durability": null, + "name": "Steel armour set (sk)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11825" + }, + { + "requirements": "{10,1}", + "shop_price": "11286", + "ge_buy_limit": "100", + "examine": "Grand Exchange set containing Black full helm, platebody, legs and kiteshield.", + "grand_exchange_price": "18900", + "durability": null, + "name": "Black armour set (l)", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11826" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "18900", + "durability": null, + "name": "Black armour set (l)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11827" + }, + { + "requirements": "{10,1}", + "shop_price": "11286", + "ge_buy_limit": "100", + "examine": "Grand Exchange set containing a black full helm, platebody, skirt and kiteshield.", + "durability": null, + "weight": "2.2", + "absorb": "2,0,4", + "grand_exchange_price": "14600", + "name": "Black armour set (sk)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11828", + "bonuses": "0,0,0,-65,-21,91,92,78,-12,90,27,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "14600", + "durability": null, + "name": "Black armour set (sk)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11829" + }, + { + "requirements": "{20,1}", + "shop_price": "15232", + "ge_buy_limit": "100", + "examine": "Grand Exchange set containing a mithril full helm, platebody, legs and kiteshield.", + "durability": null, + "weight": "2.2", + "absorb": "2,0,6", + "grand_exchange_price": "8764", + "name": "Mithril armour set (l)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11830", + "bonuses": "0,0,0,-65,-21,101,102,89,-12,97,52,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "8764", + "durability": null, + "name": "Mithril armour set (l)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11831" + }, + { + "requirements": "{20,1}", + "shop_price": "15232", + "ge_buy_limit": "100", + "examine": "Grand Exchange set containing a mithril full helm, platebody, skirt and kiteshield.", + "durability": null, + "weight": "2.2", + "absorb": "2,0,5", + "grand_exchange_price": "7829", + "name": "Mithril armour set (sk)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11832", + "bonuses": "0,0,0,-65,-21,101,102,89,-12,99,50,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "7829", + "durability": null, + "name": "Mithril armour set (sk)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11833" + }, + { + "requirements": "{1,30}", + "shop_price": "28276", + "ge_buy_limit": "100", + "examine": "Grand Exchange set containing an adamant full helm, platebody, legs and kiteshield.", + "durability": null, + "weight": "2.2", + "absorb": "7,0,15", + "grand_exchange_price": "20600", + "name": "Adamant armour set (l)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11834", + "bonuses": "0,0,0,-65,-21,144,146,129,-12,142,76,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "20600", + "durability": null, + "name": "Adamant armour set (l)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11835" + }, + { + "requirements": "{1,30}", + "shop_price": "28276", + "ge_buy_limit": "100", + "examine": "Grand Exchange set containing an adamant full helm, platebody, skirt and kiteshield.", + "durability": null, + "weight": "2.2", + "absorb": "7,0,15", + "grand_exchange_price": "21500", + "name": "Adamant armour set (sk)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11836", + "bonuses": "0,0,0,-65,-21,144,146,129,-12,142,76,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "21500", + "durability": null, + "name": "Adamant armour set (sk)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11837" + }, + { + "requirements": "{1,40}", + "shop_price": "136112", + "ge_buy_limit": "100", + "examine": "Grand Exchange set containing a rune full helm, platebody, legs and kiteshield.", + "durability": null, + "weight": "2.2", + "absorb": "9,0,20", + "grand_exchange_price": "136300", + "name": "Rune armour set (l)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11838", + "bonuses": "0,0,0,-65,-21,207,209,192,-12,205,102,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "136300", + "durability": null, + "name": "Rune armour set (l)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11839" + }, + { + "requirements": "{1,40}", + "shop_price": "136112", + "ge_buy_limit": "100", + "examine": "Grand Exchange set containing a rune full helm, platebody, skirt and kiteshield.", + "grand_exchange_price": "140300", + "durability": null, + "name": "Rune armour set (sk)", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11840" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "140300", + "durability": null, + "name": "Rune armour set (sk)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11841" + }, + { + "requirements": "{1,60}", + "ge_buy_limit": "10", + "grand_exchange_price": "4800000", + "examine": "Grand Exchange set containing a dragon helm, chainbody, legs.", + "durability": null, + "name": "Dragon chain armour set (l)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "2.2", + "id": "11842" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "4800000", + "durability": null, + "name": "Dragon chain armour set (l)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11843" + }, + { + "requirements": "{1,60}", + "ge_buy_limit": "10", + "grand_exchange_price": "4600000", + "examine": "Grand Exchange set containing a dragon helm, chainbody, skirt.", + "durability": null, + "name": "Dragon chain armour set (sk)", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "2.2", + "id": "11844" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "4600000", + "durability": null, + "name": "Dragon chain armour set (sk)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11845" + }, + { + "requirements": "{0,70}-{1,70}-{6,70}", + "ge_buy_limit": "10", + "examine": "Grand Exchange set containing Ahrim's robetop, robeskirt, hood, and staff.", + "grand_exchange_price": "3100000", + "durability": null, + "name": "Barrows - ahrim's set", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11846" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "3100000", + "durability": null, + "name": "Barrows - ahrim's set", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11847" + }, + { + "requirements": "{0,70}-{1,70}-{2,70}", + "ge_buy_limit": "10", + "examine": "Grand Exchange set containing Dharok's helm, body, legs and greataxe.", + "grand_exchange_price": "3100000", + "durability": null, + "name": "Barrows - dharok's set", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11848" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "3100000", + "durability": null, + "name": "Barrows - dharok's set", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11849" + }, + { + "requirements": "{0,70}-{1,70}", + "ge_buy_limit": "10", + "examine": "Grand Exchange set containing Guthan's helm, platebody, chainskirt and warspear.", + "grand_exchange_price": "1600000", + "durability": null, + "name": "Barrows - guthan's set", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11850" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "1600000", + "durability": null, + "name": "Barrows - guthan's set", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11851" + }, + { + "requirements": "{1,70}-{4,70}", + "ge_buy_limit": "10", + "examine": "A Grand Exchange set containing Karil's coif, crossbow, leather body, and leather skirt.", + "grand_exchange_price": "2200000", + "durability": null, + "name": "Barrows - karil's set", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11852" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "2200000", + "durability": null, + "name": "Barrows - karil's set", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11853" + }, + { + "requirements": "{0,70}-{1,70}-{2,70}", + "ge_buy_limit": "10", + "examine": "Grand Exchange set containing Torag's helm, body, legs and hammers.", + "grand_exchange_price": "1100000", + "durability": null, + "name": "Barrows - torag's set", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11854" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "1100000", + "durability": null, + "name": "Barrows - torag's set", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11855" + }, + { + "requirements": "{0,70}-{1,70}", + "ge_buy_limit": "10", + "examine": "Grand Exchange set containing Verac's helm, brassard, plateskirt and flail.", + "grand_exchange_price": "1500000", + "durability": null, + "name": "Barrows - verac's set", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11856" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "1500000", + "durability": null, + "name": "Barrows - verac's set", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11857" + }, + { + "requirements": "{1,65}", + "ge_buy_limit": "2", + "examine": "Grand Exchange set containing a helm, body, legs and shield", + "grand_exchange_price": "388700000", + "durability": null, + "name": "Third age melee set", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "11858" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "388700000", + "durability": null, + "name": "Third age melee set", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11859" + }, + { + "requirements": "{1,45}-{4,65}", + "ge_buy_limit": "2", + "examine": "Grand Exchange set containing coif, body, chaps and vambraces.", + "grand_exchange_price": "87500000", + "durability": null, + "name": "Third age ranger set", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11860" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "87500000", + "durability": null, + "name": "Third age ranger set", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11861" + }, + { + "requirements": "{1,30}-{6,65}", + "ge_buy_limit": "2", + "examine": "Grand Exchange set containing a body, legs, amulet and hat", + "grand_exchange_price": "163100000", + "durability": null, + "name": "Third age mage set", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11862" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "163100000", + "durability": null, + "name": "Third age mage set", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11863" + }, + { + "requirements": "{1,40}-{4,40}", + "shop_price": "9000", + "ge_buy_limit": "100", + "examine": "Grand Exchange set containing body, chaps and vambraces.", + "durability": null, + "weight": "2.2", + "absorb": "0,10,5", + "grand_exchange_price": "8932", + "name": "Green dragonhide set", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11864", + "bonuses": "0,0,0,-40,31,65,50,73,30,62,58,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "8932", + "durability": null, + "name": "Green dragonhide set", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11865" + }, + { + "requirements": "{1,40}-{4,50}", + "shop_price": "12000", + "ge_buy_limit": "100", + "examine": "Grand Exchange set containing body, chaps and vambraces.", + "grand_exchange_price": "9062", + "durability": null, + "name": "Blue dragonhide set", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11866" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "9062", + "durability": null, + "name": "Blue dragonhide set", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11867" + }, + { + "requirements": "{1,40}-{4,60}", + "shop_price": "15000", + "ge_buy_limit": "100", + "examine": "Grand Exchange set containing body, chaps and vambraces.", + "grand_exchange_price": "12800", + "durability": null, + "name": "Red dragonhide set", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11868" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "12800", + "durability": null, + "name": "Red dragonhide set", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11869" + }, + { + "requirements": "{1,40}-{4,70}", + "shop_price": "40000", + "ge_buy_limit": "100", + "examine": "Grand Exchange set containing body, chaps and vambraces.", + "grand_exchange_price": "17600", + "durability": null, + "name": "Black dragonhide set", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11870" + }, + { + "durability": null, + "name": "Black dragonhide set", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11871" + }, + { + "requirements": "{20,1}-{6,40}", + "shop_price": "169143", + "ge_buy_limit": "100", + "examine": "Grand Exchange set containing mystic hat, top, bottoms, gloves, and boots.", + "grand_exchange_price": "163300", + "durability": null, + "name": "Mystic robes set", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11872" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "163300", + "durability": null, + "name": "Mystic robes set", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11873" + }, + { + "requirements": "{1,25}-{6,50}", + "ge_buy_limit": "10", + "examine": "Grand Exchange set containing hat, top, bottoms, gloves, and boots", + "grand_exchange_price": "11000000", + "durability": null, + "name": "Infinity robes set", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11874" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "11000000", + "durability": null, + "name": "Infinity robes set", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11875" + }, + { + "requirements": "{1,40}-{6,40}", + "ge_buy_limit": "100", + "examine": "Grand Exchange set containing a helm, body, boots, gauntlets and legs.", + "grand_exchange_price": "107400", + "durability": null, + "name": "Splitbark armour set", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11876", + "absorb": "13,6,0", + "bonuses": "0,0,0,24,-21,74,59,86,32,0,74,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "107400", + "durability": null, + "name": "Splitbark armour set", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11877" + }, + { + "requirements": "{10,1}", + "ge_buy_limit": "2", + "examine": "Grand Exchange set containing full helm, platebody, legs and kiteshield.", + "grand_exchange_price": "341200", + "durability": null, + "name": "Black trimmed armour set (l)", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11878", + "absorb": "2,0,4", + "bonuses": "0,0,0,-65,-21,91,92,77,-12,90,23,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "341200", + "durability": null, + "name": "Black trimmed armour set (l)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11879" + }, + { + "requirements": "{10,1}", + "ge_buy_limit": "2", + "examine": "Grand Exchange set containing full helm, platebody, skirt and kiteshield.", + "grand_exchange_price": "331600", + "durability": null, + "name": "Black trimmed armour set (sk)", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11880", + "absorb": "2,0,4", + "bonuses": "0,0,0,-65,-21,91,92,77,-12,90,23,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "331600", + "durability": null, + "name": "Black trimmed armour set (sk)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11881" + }, + { + "requirements": "{10,1}", + "ge_buy_limit": "2", + "examine": "Grand Exchange set containing full helm, platebody, legs and kiteshield.", + "grand_exchange_price": "1700000", + "durability": null, + "name": "Black gold-trimmed armour set (l)", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11882" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "1700000", + "durability": null, + "name": "Black gold-trimmed armour set (l)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11883" + }, + { + "requirements": "{10,1}", + "ge_buy_limit": "2", + "examine": "Grand Exchange set containing full helm, platebody, skirt and kiteshield.", + "grand_exchange_price": "1300000", + "durability": null, + "name": "Black gold-trimmed armour set (sk)", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11884" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "1300000", + "durability": null, + "name": "Black gold-trimmed armour set (sk)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11885" + }, + { + "requirements": "{1,30}", + "ge_buy_limit": "2", + "examine": "Grand Exchange set containing a full helm, platebody, legs and kiteshield.", + "grand_exchange_price": "318100", + "durability": null, + "name": "Adamant trimmed armour set (l)", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11886" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "318100", + "durability": null, + "name": "Adamant trimmed armour set (l)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11887" + }, + { + "requirements": "{1,30}", + "ge_buy_limit": "2", + "examine": "Grand Exchange set containing a full helm, platebody, skirt and kiteshield.", + "grand_exchange_price": "293700", + "durability": null, + "name": "Adamant trimmed armour set (sk)", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11888" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "293700", + "durability": null, + "name": "Adamant trimmed armour set (sk)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11889" + }, + { + "requirements": "{1,30}", + "ge_buy_limit": "2", + "examine": "Grand Exchange set containing full helm, platebody, legs and kiteshield.", + "grand_exchange_price": "949400", + "durability": null, + "name": "Adamant gold-trimmed armour set (l)", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11890" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "949400", + "durability": null, + "name": "Adamant gold-trimmed armour set (l)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11891" + }, + { + "requirements": "{1,30}", + "ge_buy_limit": "2", + "examine": "Grand Exchange set containing full helm, platebody, skirt and kiteshield.", + "grand_exchange_price": "880500", + "durability": null, + "name": "Adamant gold-trimmed armour set (sk)", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11892" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "880500", + "durability": null, + "name": "Adamant gold-trimmed armour set (sk)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11893" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "Grand Exchange set containing a full helm, platebody, legs and kiteshield.", + "grand_exchange_price": "702500", + "durability": null, + "name": "Rune trimmed armour set (l)", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11894", + "absorb": "9,0,20", + "bonuses": "0,0,0,-65,-21,207,209,192,-12,205,102,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "702500", + "durability": null, + "name": "Rune trimmed armour set (l)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11895" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "Grand Exchange set containing a full helm, platebody, skirt and kiteshield.", + "grand_exchange_price": "675400", + "durability": null, + "name": "Rune trimmed armour set (sk)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11896", + "absorb": "9,0,20", + "bonuses": "0,0,0,-65,-21,207,209,192,-12,205,102,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "675400", + "durability": null, + "name": "Rune trimmed armour set (sk)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11897" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "Grand Exchange set containing a full helm, platebody, legs and kiteshield.", + "grand_exchange_price": "1700000", + "durability": null, + "name": "Rune gold-trimmed armour set (l)", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11898", + "absorb": "9,0,20", + "bonuses": "0,0,0,-65,-21,207,209,192,-12,205,102,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "1700000", + "durability": null, + "name": "Rune gold-trimmed armour set (l)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11899" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "Grand Exchange set containing a full helm, platebody, skirt and kiteshield.", + "grand_exchange_price": "1400000", + "durability": null, + "name": "Rune gold-trimmed armour set (sk)", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11900", + "absorb": "9,0,20", + "bonuses": "0,0,0,-65,-21,207,209,192,-12,205,102,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "1400000", + "durability": null, + "name": "Rune gold-trimmed armour set (sk)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11901" + }, + { + "requirements": "{20,1}-{6,40}", + "ge_buy_limit": "2", + "examine": "Grand Exchange set containing hat, robetops and bottoms", + "grand_exchange_price": "207200", + "durability": null, + "name": "Enchanted set", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11902" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "207200", + "durability": null, + "name": "Enchanted set", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11903" + }, + { + "ge_buy_limit": "2", + "examine": "Grand Exchange set containing hat, robetops and bottoms", + "grand_exchange_price": "877900", + "durability": null, + "name": "Trimmed blue wizard set", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "11904" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "877900", + "durability": null, + "name": "Trimmed blue wizard set", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11905" + }, + { + "ge_buy_limit": "2", + "examine": "Grand Exchange set containing hat, robe top and bottom", + "grand_exchange_price": "3100000", + "durability": null, + "name": "Gold-trimmed blue wizard set", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11906" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "3100000", + "durability": null, + "name": "Gold-trimmed blue wizard set", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11907" + }, + { + "requirements": "{20,4}", + "ge_buy_limit": "10000", + "examine": "Grand Exchange set containing body and chaps", + "grand_exchange_price": "85100", + "durability": null, + "name": "Trimmed leather armour set", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11908" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "85100", + "durability": null, + "name": "Trimmed leather armour set", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11909" + }, + { + "requirements": "{20,4}", + "ge_buy_limit": "10000", + "examine": "Grand Exchange set containing body and chaps", + "grand_exchange_price": "217200", + "durability": null, + "name": "Gold-trimmed leather armour set", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11910" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "217200", + "durability": null, + "name": "Gold-trimmed leather armour set", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11911" + }, + { + "requirements": "{1,40}-{4,40}", + "ge_buy_limit": "2", + "examine": "Grand Exchange set containing body and chaps", + "grand_exchange_price": "371600", + "durability": null, + "name": "Green d'hide trimmed set", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11912", + "absorb": "0,10,5", + "bonuses": "0,0,0,-40,31,65,50,73,30,62,58,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "371600", + "durability": null, + "name": "Green d'hide trimmed set", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11913" + }, + { + "requirements": "{1,40}-{4,40}", + "ge_buy_limit": "2", + "examine": "Grand Exchange set containing body and chaps", + "grand_exchange_price": "1600000", + "durability": null, + "name": "Green d'hide gold-trimmed set", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11914", + "absorb": "0,10,5", + "bonuses": "0,0,0,-40,31,65,50,73,30,62,58,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "1600000", + "durability": null, + "name": "Green d'hide gold-trimmed set", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11915" + }, + { + "requirements": "{1,40}-{4,50}", + "ge_buy_limit": "2", + "examine": "Grand Exchange set containing body and chaps", + "grand_exchange_price": "38300", + "durability": null, + "name": "Blue d'hide trimmed set", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11916" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "38300", + "durability": null, + "name": "Blue d'hide trimmed set", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11917" + }, + { + "requirements": "{1,40}-{4,50}", + "ge_buy_limit": "2", + "examine": "Grand Exchange set containing body and chaps.", + "grand_exchange_price": "50000", + "durability": null, + "name": "Blue d'hide gold-trimmed set", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11918" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "50000", + "durability": null, + "name": "Blue d'hide gold-trimmed set", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11919" + }, + { + "requirements": "{1,40}-{4,70}", + "ge_buy_limit": "2", + "examine": "Grand Exchange set containing body, chaps, bracers and coif.", + "grand_exchange_price": "179500", + "durability": null, + "name": "Green d'hide blessed set", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11920" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "179500", + "durability": null, + "name": "Green d'hide blessed set", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11921" + }, + { + "requirements": "{1,40}-{4,70}", + "ge_buy_limit": "2", + "examine": "Grand Exchange set containing body, chaps, bracers and coif.", + "grand_exchange_price": "477500", + "durability": null, + "name": "Blue d'hide blessed set", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11922" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "477500", + "durability": null, + "name": "Blue d'hide blessed set", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11923" + }, + { + "requirements": "{1,40}-{4,70}", + "ge_buy_limit": "2", + "examine": "Grand Exchange set containing body, chaps, bracers and coif.", + "grand_exchange_price": "585300", + "durability": null, + "name": "Red d'hide blessed set", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11924" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "585300", + "durability": null, + "name": "Red d'hide blessed set", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11925" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "Grand Exchange set containing full helm, platebody, legs and shield.", + "grand_exchange_price": "1100000", + "durability": null, + "name": "Guthix armour set (l)", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11926", + "absorb": "9,0,20", + "bonuses": "0,0,0,-65,-21,207,209,192,-12,205,102,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "1100000", + "durability": null, + "name": "Guthix armour set (l)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11927" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "Grand Exchange set containing full helm, platebody, legs and kiteshield", + "grand_exchange_price": "4000000", + "durability": null, + "name": "Saradomin armour set (l)", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11928", + "absorb": "9,0,20", + "bonuses": "0,0,0,-65,-21,207,209,192,-12,205,102,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "4000000", + "durability": null, + "name": "Saradomin armour set (l)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11929" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "Grand Exchange set containing full helm, platebody, legs and kiteshield", + "grand_exchange_price": "2300000", + "durability": null, + "name": "Zamorak armour set (l)", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11930", + "absorb": "9,0,20", + "bonuses": "0,0,0,-65,-21,207,209,192,-12,205,102,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "2300000", + "durability": null, + "name": "Zamorak armour set (l)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11931" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "Grand Exchange set containing full helm, platebody, skirt and kiteshield.", + "grand_exchange_price": "1000000", + "durability": null, + "name": "Guthix armour set (sk)", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11932", + "absorb": "9,0,20", + "bonuses": "0,0,0,-65,-21,207,209,192,-12,205,102,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "1000000", + "durability": null, + "name": "Guthix armour set (sk)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11933" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "Grand Exchange set containing full helm, platebody, skirt and kiteshield", + "grand_exchange_price": "3600000", + "durability": null, + "name": "Saradomin armour set (sk)", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11934", + "absorb": "9,0,20", + "bonuses": "0,0,0,-65,-21,207,209,192,-12,205,102,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "3600000", + "durability": null, + "name": "Saradomin armour set (sk)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11935" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "Grand Exchange set containing a full helm, platebody, skirt and kiteshield", + "grand_exchange_price": "2000000", + "durability": null, + "name": "Zamorak armour set (sk)", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11936", + "absorb": "9,0,20", + "bonuses": "0,0,0,-65,-21,207,209,192,-12,205,102,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "2000000", + "durability": null, + "name": "Zamorak armour set (sk)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11937" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "Grand Exchange set containing a full helm, platebody, legs and kiteshield.", + "grand_exchange_price": "5900000", + "durability": null, + "name": "Gilded armour set (l)", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11938" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "5900000", + "durability": null, + "name": "Gilded armour set (l)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11939" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "2", + "examine": "Grand Exchange set containing a full helm, platebody, skirt and kiteshield.", + "grand_exchange_price": "4300000", + "durability": null, + "name": "Gilded armour set (sk)", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11940" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "4300000", + "durability": null, + "name": "Gilded armour set (sk)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11941" + }, + { + "requirements": "{1,40}", + "ge_buy_limit": "100", + "examine": "Grand Exchange set containing helm, platebody, legs, boots and gloves", + "grand_exchange_price": "145000", + "durability": null, + "name": "Rockshell armour set", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11942" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "145000", + "durability": null, + "name": "Rockshell armour set", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11943" + }, + { + "requirements": "{1,40}-{4,40}", + "ge_buy_limit": "100", + "examine": "Grand Exchange set containing helm, body, chaps, boots and gloves", + "grand_exchange_price": "94500", + "durability": null, + "name": "Spined armour set", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11944", + "absorb": "0,13,6", + "bonuses": "-6,-6,-6,-31,29,68,56,78,34,62,47,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "94500", + "durability": null, + "name": "Spined armour set", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11945" + }, + { + "requirements": "{1,40}-{6,40}", + "ge_buy_limit": "100", + "examine": "Grand Exchange set containing helm, top, bottoms, boots and gloves", + "grand_exchange_price": "145200", + "durability": null, + "name": "Skeletal armour set", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11946" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "145200", + "durability": null, + "name": "Skeletal armour set", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11947" + }, + { + "destroy_message": "You can get another from Diango in Draynor Village.", + "examine": "A tiny model of Lumbridge Castle inside a glass dome.", + "durability": null, + "name": "Snow globe", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11949", + "equipment_slot": "3" + }, + { + "destroy_message": "You can get another from Diango in Draynor Village.", + "examine": "A tiny model of Lumbridge Castle inside a glass dome.", + "durability": null, + "name": "Snow globe", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11950", + "equipment_slot": "3" + }, + { + "attack_anims": "5063", + "examine": "Made from snow. / It's a ball of snow! Uncanny. / How did this not melt in the box?", + "durability": null, + "name": "Snowball", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "11951", + "weapon_interface": "18", + "equipment_slot": "3" + }, + { + "bankable": "false", + "destroy_message": "You can get another from a snow imp.", + "examine": "Add this to a snowman to make a snow warrior.", + "durability": null, + "name": "Ice sword", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11952" + }, + { + "bankable": "false", + "destroy_message": "You can get another from a snow imp.", + "examine": "Add this to a snowman to make a snow mage.", + "attack_audios": "2555,0,0,0", + "durability": null, + "name": "Winter staff", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11953" + }, + { + "bankable": "false", + "destroy_message": "You can get another from a snow imp.", + "examine": "Add this to a snowman to make a snow ranger.", + "durability": null, + "name": "Holly bow", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11954" + }, + { + "bankable": "false", + "destroy_message": "You can get another from a snow imp.", + "examine": "Add this to a snowman to make a barbarian snowman.", + "durability": null, + "name": "Barbarian snowman hat", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11955" + }, + { + "bankable": "false", + "destroy_message": "You can get another from a snow imp.", + "examine": "It's actually made of cardboard, but it looks like a dragon full helm.", + "durability": null, + "name": "Dragon snowman hat", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11956" + }, + { + "bankable": "false", + "destroy_message": "You can get another from a snow imp.", + "examine": "Use this to make your snowman look like a dwarf.", + "durability": null, + "name": "Dwarf snowman hat", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11957" + }, + { + "bankable": "false", + "destroy_message": "Talk to a snow imp to get another.", + "examine": "Arr! Shiver me snowman!", + "durability": null, + "name": "Pirate snowman hat", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11958" + }, + { + "bankable": "false", + "destroy_message": "You can get another from a snow imp.", + "examine": "The most traditional snowman hat.", + "durability": null, + "name": "Snowman top hat", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11959" + }, + { + "requirements": "{20,1}-{6,40}", + "shop_price": "215431", + "ge_buy_limit": "100", + "examine": "Grand Exchange set containing hat, top, bottoms, gloves, and boots", + "grand_exchange_price": "487300", + "durability": null, + "name": "Light mystic robes set", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11960" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "487300", + "durability": null, + "name": "Light mystic robes set", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11961" + }, + { + "requirements": "{20,1}-{6,40}", + "shop_price": "228541", + "ge_buy_limit": "100", + "examine": "Grand Exchange set containing hat, top, bottoms, gloves, and boots", + "grand_exchange_price": "294000", + "durability": null, + "name": "Dark mystic robes set", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11962" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "294000", + "durability": null, + "name": "Dark mystic robes set", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11963" + }, + { + "examine": "I can hatch this in an incubator.", + "durability": null, + "name": "Raven egg", + "archery_ticket_price": "0", + "id": "11964" + }, + { + "examine": "I can hatch this in an incubator.", + "durability": null, + "name": "Vulture egg", + "archery_ticket_price": "0", + "id": "11965" + }, + { + "examine": "Full: ", + "durability": null, + "name": "Bird's nest", + "archery_ticket_price": "0", + "id": "11966" + }, + { + "shop_price": "750000", + "ge_buy_limit": "10", + "examine": "Grand Exchange set containing cannon base, stand, barrels and furnace.", + "grand_exchange_price": "718900", + "durability": null, + "name": "Dwarf cannon set", + "tradeable": "true", + "weight": "2.2", + "archery_ticket_price": "0", + "id": "11967" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "718900", + "durability": null, + "name": "Dwarf cannon set", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "11968" + }, + { + "destroy_message": "If I destroy this it will disintegrate into its component parts and drop to the floor.", + "examine": "A water tiara infused with water runes. Protects from the hot desert sun.", + "durability": null, + "name": "Enchanted water tiara", + "weight": "1", + "archery_ticket_price": "0", + "id": "11969", + "bonuses": "0,0,0,2,0,5,5,5,3,3,0,0,2,0,0", + "equipment_slot": "0" + }, + { + "destroy_message": "I can obtain and fill another one from the archaeologist near Sophanem.", + "examine": "A crate full of distressed gear.", + "durability": null, + "name": "Smelly crate", + "tradeable": "false", + "destroy": "true", + "weight": "30", + "archery_ticket_price": "0", + "id": "11970" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "An empty crate, ready for bronze gear.", + "durability": null, + "name": "Empty crate", + "archery_ticket_price": "0", + "id": "11972" + }, + { + "destroy_message": "I can obtain another one from the archaeologist near Sophanem.", + "examine": "A book of research on Scabarite history.", + "durability": null, + "name": "Scabaras research", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "11973" + }, + { + "destroy_message": "I can obtain another one from Simon Templeton.", + "examine": "Issued by Simon Templeton.", + "durability": null, + "name": "Artefact receipt", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11974" + }, + { + "destroy_message": "I can loot another one from the monsters in the areas east of Sophanem.", + "examine": "See article", + "durability": null, + "name": "Scabarite notes", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11975" + }, + { + "destroy_message": "I can loot another one from the monsters in the areas east of Sophanem.", + "examine": "See article", + "durability": null, + "name": "Scabarite notes", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11976" + }, + { + "destroy_message": "I can loot another one from the monsters in the areas east of Sophanem.", + "examine": "See article", + "durability": null, + "name": "Scabarite notes", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11977" + }, + { + "destroy_message": "I can loot another one from the monsters in the areas east of Sophanem.", + "examine": "See article", + "durability": null, + "name": "Scabarite notes", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11978" + }, + { + "destroy_message": "I can loot another one from the monsters in the areas east of Sophanem.", + "examine": "See article", + "durability": null, + "name": "Scabarite notes", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11979" + }, + { + "destroy_message": "I can loot another one from the monsters in the areas east of Sophanem.", + "examine": "See article", + "durability": null, + "name": "Scabarite notes", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11980" + }, + { + "destroy_message": "I can loot another one from the monsters in the areas east of Sophanem.", + "examine": "See article", + "durability": null, + "name": "Scabarite notes", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11981" + }, + { + "destroy_message": "I can loot another one from the monsters in the areas east of Sophanem.", + "examine": "See article", + "durability": null, + "name": "Scabarite notes", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11982" + }, + { + "destroy_message": "I can loot another one from the monsters in the areas east of Sophanem.", + "examine": "See article", + "durability": null, + "name": "Scabarite notes", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11983" + }, + { + "destroy_message": "I can loot another one from the monsters in the areas east of Sophanem.", + "examine": "See article", + "durability": null, + "name": "Scabarite notes", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11984" + }, + { + "destroy_message": "I can loot another one from the monsters in the areas east of Sophanem.", + "examine": "See article", + "durability": null, + "name": "Scabarite notes", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11985" + }, + { + "destroy_message": "I can loot another one from the monsters in the areas east of Sophanem.", + "examine": "See article", + "durability": null, + "name": "Scabarite notes", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11986" + }, + { + "destroy_message": "I can loot another one from the monsters in the areas east of Sophanem.", + "examine": "See article", + "durability": null, + "name": "Scabarite notes", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11987" + }, + { + "destroy_message": "I can loot another one from the monsters in the areas east of Sophanem.", + "examine": "See article", + "durability": null, + "name": "Scabarite notes", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11988" + }, + { + "destroy_message": "I can loot another one from the monsters in the areas east of Sophanem.", + "examine": "See article", + "durability": null, + "name": "Scabarite notes", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11989" + }, + { + "destroy_message": "I can loot another one from the monsters in the areas east of Sophanem.", + "examine": "See article", + "durability": null, + "name": "Scabarite notes", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11990" + }, + { + "destroy_message": "I can loot another one from the monsters in the areas east of Sophanem.", + "examine": "See article", + "durability": null, + "name": "Scabarite notes", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11991" + }, + { + "destroy_message": "I can loot another one from the monsters in the areas east of Sophanem.", + "examine": "See article", + "durability": null, + "name": "Scabarite notes", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11992" + }, + { + "destroy_message": "I can loot another one from the monsters in the areas east of Sophanem.", + "examine": "See article", + "durability": null, + "name": "Scabarite notes", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11993" + }, + { + "destroy_message": "I can obtain another one from the archaeologists near Sophanem.", + "examine": "Newly made, but to an ancient pattern. (Dealing with Scabaras)", + "durability": null, + "name": "Scabarite key", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11994" + }, + { + "destroy_message": "I can make another one by using camel dung on a bronze dagger.", + "examine": "It has been oxidised.", + "attack_audios": "2517,2517,2500,2517", + "durability": null, + "name": "Oxidised dagger", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11995" + }, + { + "examine": "It has been oxidised.", + "durability": null, + "name": "Oxidised medium helm", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11996" + }, + { + "destroy_message": "I can make another one by using camel dung on a bronze sword.", + "examine": "It has been oxidised.", + "durability": null, + "name": "Oxidised sword", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11997" + }, + { + "turn90cw_anim": "821", + "examine": "It has been oxidised.", + "walk_anim": "819", + "durability": null, + "destroy": "true", + "turn90ccw_anim": "822", + "turn180_anim": "820", + "render_anim": "1", + "destroy_message": "I can make another one by using camel dung on a bronze scimitar.", + "stand_anim": "808", + "attack_audios": "2500,0,2517,0", + "name": "Oxidised scimitar", + "tradeable": "false", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "11998", + "stand_turn_anim": "823" + }, + { + "destroy_message": "I can make another one by using camel dung on a bronze longsword.", + "examine": "It has been oxidised.", + "durability": null, + "name": "Oxidised longsword", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "11999" + }, + { + "destroy_message": "I can make another one by using camel dung on a bronze full helmet.", + "examine": "It has been oxidised.", + "durability": null, + "name": "Oxidised full helm", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "12000" + }, + { + "destroy_message": "I can make another one by using camel dung on a bronze square shield.", + "examine": "It has been oxidised.", + "durability": null, + "name": "Oxidised square shield", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "12001" + }, + { + "destroy_message": "I can make another one by using camel dung on a bronze chainbody.", + "examine": "It has been oxidised.", + "durability": null, + "name": "Oxidised chainbody", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "12002" + }, + { + "destroy_message": "I can make another one by using camel dung on a bronze kiteshield.", + "examine": "It has been oxidised.", + "durability": null, + "name": "Oxidised kiteshield", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "12003", + "equip_audio": "2245" + }, + { + "destroy_message": "I can make another one by using camel dung on a bronze two", + "examine": "It has been oxidised.", + "durability": null, + "name": "Oxidised two-handed sword", + "tradeable": "false", + "destroy": "true", + "weight": "4", + "archery_ticket_price": "0", + "id": "12004" + }, + { + "destroy_message": "I can make another one by using camel dung on some bronze platelegs.", + "examine": "It has been oxidised.", + "durability": null, + "name": "Oxidised platelegs", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "12005" + }, + { + "destroy_message": "I can make another one by using camel dung on a bronze plateskirt.", + "examine": "It has been oxidised.", + "durability": null, + "name": "Oxidised plateskirt", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "12006" + }, + { + "requirements": "{23,52}", + "ge_buy_limit": "5000", + "grand_exchange_price": "330", + "examine": "I can summon a spirit terrorbird familiar with this.", + "durability": null, + "name": "Spirit terrorbird pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12007" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "330", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Spirit terrorbird pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12008" + }, + { + "requirements": "{16,23}", + "ge_buy_limit": "5000", + "grand_exchange_price": "239", + "examine": "I can summon a granite crab familiar with this.", + "durability": null, + "name": "Granite crab pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12009" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "239", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Granite crab pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12010" + }, + { + "requirements": "{23,75}", + "ge_buy_limit": "5000", + "grand_exchange_price": "2918", + "examine": "I can summon a praying mantis familiar with this.", + "durability": null, + "name": "Praying mantis pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12011" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "2918", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Praying mantis pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12012" + }, + { + "requirements": "{23,78}", + "ge_buy_limit": "5000", + "grand_exchange_price": "2167", + "examine": "I can summon a giant ent familiar with this.", + "durability": null, + "name": "Giant ent pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12013" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "2167", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Giant ent pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12014" + }, + { + "requirements": "{23,63}", + "ge_buy_limit": "5000", + "grand_exchange_price": "2018", + "examine": "I can summon a spirit cobra familiar with this.", + "durability": null, + "name": "Spirit cobra pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12015" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "2018", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Spirit cobra pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12016" + }, + { + "requirements": "{23,83}", + "ge_buy_limit": "5000", + "grand_exchange_price": "121", + "examine": "I can summon a spirit dagannoth familiar with this.", + "durability": null, + "name": "Spirit dagannoth pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12017" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "121", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Spirit dagannoth pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12018" + }, + { + "requirements": "{13,23}", + "ge_buy_limit": "5000", + "grand_exchange_price": "248", + "examine": "I can summon a thorny snail familiar with this.", + "durability": null, + "name": "Thorny snail pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12019" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "248", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Thorny snail pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12020" + }, + { + "requirements": "{23,33}", + "ge_buy_limit": "5000", + "grand_exchange_price": "1268", + "examine": "I can summon a beaver familiar with this.", + "durability": null, + "name": "Beaver pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12021" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "1268", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Beaver pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12022" + }, + { + "requirements": "{23,58}", + "ge_buy_limit": "5000", + "grand_exchange_price": "2520", + "examine": "I can summon a karamthulhu overlord familiar with this.", + "durability": null, + "name": "Karam. overlord pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12023" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "2520", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Karam. overlord pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12024" + }, + { + "requirements": "{23,80}", + "ge_buy_limit": "5000", + "grand_exchange_price": "2235", + "examine": "I can summon a hydra familiar with this.", + "durability": null, + "name": "Hydra pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12025" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "2235", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Hydra pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12026" + }, + { + "requirements": "{23,55}", + "ge_buy_limit": "5000", + "grand_exchange_price": "2641", + "examine": "I can summon a spirit jelly familiar with this.", + "durability": null, + "name": "Spirit jelly pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12027" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "2641", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Spirit jelly pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12028" + }, + { + "requirements": "{23,68}", + "ge_buy_limit": "5000", + "grand_exchange_price": "3506", + "examine": "I can summon a bunyip familiar with this.", + "durability": null, + "name": "Bunyip pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12029" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "3506", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Bunyip pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12030" + }, + { + "requirements": "{23,67}", + "ge_buy_limit": "5000", + "grand_exchange_price": "13200", + "examine": "I can summon a war tortoise familiar with this.", + "durability": null, + "name": "War tortoise pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12031" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "13200", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "War tortoise pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12032" + }, + { + "requirements": "{23,69}", + "ge_buy_limit": "5000", + "grand_exchange_price": "2269", + "examine": "I can summon a fruit bat familiar with this.", + "durability": null, + "name": "Fruit bat pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12033" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "2269", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Fruit bat pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12034" + }, + { + "requirements": "{23,54}", + "ge_buy_limit": "5000", + "grand_exchange_price": "4004", + "examine": "I can summon an abyssal parasite familiar with this.", + "durability": null, + "name": "Abyssal parasite pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12035" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "4004", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Abyssal parasite pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12036" + }, + { + "requirements": "{23,62}", + "ge_buy_limit": "5000", + "grand_exchange_price": "5660", + "examine": "I can summon an abyssal lurker familiar with this.", + "durability": null, + "name": "Abyssal lurker pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12037" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "5660", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Abyssal lurker pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12038" + }, + { + "requirements": "{23,88}", + "ge_buy_limit": "5000", + "grand_exchange_price": "2439", + "examine": "I can summon a unicorn stallion familiar with this.", + "durability": null, + "name": "Unicorn stallion pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12039" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "2439", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Unicorn stallion pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12040" + }, + { + "requirements": "{23,47}", + "ge_buy_limit": "5000", + "grand_exchange_price": "1559", + "examine": "I can summon a magpie familiar with this.", + "durability": null, + "name": "Magpie pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12041" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "1559", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Magpie pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12042" + }, + { + "requirements": "{4,23}", + "ge_buy_limit": "5000", + "grand_exchange_price": "258", + "examine": "I can summon a dreadfowl familiar with this.", + "durability": null, + "name": "Dreadfowl pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12043" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "258", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Dreadfowl pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12044" + }, + { + "requirements": "{23,64}", + "ge_buy_limit": "5000", + "grand_exchange_price": "2216", + "examine": "I can summon a stranger plant familiar with this.", + "durability": null, + "name": "Stranger plant pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12045" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "2216", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Stranger plant pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12046" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "301", + "examine": "I can summon a spirit wolf familiar with this.", + "durability": null, + "name": "Spirit wolf pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12047" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "301", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Spirit wolf pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12048" + }, + { + "requirements": "{18,23}", + "ge_buy_limit": "5000", + "grand_exchange_price": "808", + "examine": "I can summon a desert wyrm familiar with this.", + "durability": null, + "name": "Desert wyrm pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12049" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "808", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Desert wyrm pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12050" + }, + { + "requirements": "{23,42}", + "ge_buy_limit": "5000", + "grand_exchange_price": "1812", + "examine": "I can summon an evil turnip familiar with this.", + "durability": null, + "name": "Evil turnip pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12051" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "1812", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Evil turnip pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12052" + }, + { + "requirements": "{23,31}", + "ge_buy_limit": "10000", + "grand_exchange_price": "1416", + "examine": "I can summon a vampire bat familiar with this.", + "durability": null, + "name": "Vampire bat pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12053" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "1416", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Vampire bat pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12054" + }, + { + "requirements": "{19,23}", + "ge_buy_limit": "5000", + "grand_exchange_price": "992", + "examine": "I can summon a spirit scorpion familiar with this.", + "durability": null, + "name": "Spirit scorpion pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12055" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "992", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Spirit scorpion pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12056" + }, + { + "requirements": "{23,71}", + "ge_buy_limit": "5000", + "grand_exchange_price": "332", + "examine": "I can summon an arctic bear familiar with this.", + "durability": null, + "name": "Arctic bear pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12057" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "332", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Arctic bear pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12058" + }, + { + "requirements": "{10,23}", + "ge_buy_limit": "5000", + "grand_exchange_price": "2225", + "examine": "I can summon a spirit spider familiar with this.", + "durability": null, + "name": "Spirit spider pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12059" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "2225", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Spirit spider pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12060" + }, + { + "requirements": "{23,49}", + "ge_buy_limit": "5000", + "grand_exchange_price": "2045", + "examine": "I can summon a bloated leech familiar with this.", + "durability": null, + "name": "Bloated leech pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12061" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "2045", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Bloated leech pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12062" + }, + { + "requirements": "{23,25}", + "ge_buy_limit": "5000", + "grand_exchange_price": "3746", + "examine": "I can summon a spirit kalphite familiar with this.", + "durability": null, + "name": "Spirit kalphite pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12063" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "3746", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Spirit kalphite pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12064" + }, + { + "requirements": "{23,32}", + "ge_buy_limit": "5000", + "grand_exchange_price": "1470", + "examine": "I can summon a honey badger familiar with this.", + "durability": null, + "name": "Honey badger pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12065" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "1470", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Honey badger pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12066" + }, + { + "requirements": "{23,23}", + "ge_buy_limit": "5000", + "grand_exchange_price": "1578", + "examine": "I can summon an albino rat familiar with this.", + "durability": null, + "name": "Albino rat pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12067" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "1578", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Albino rat pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12068" + }, + { + "requirements": "{23,74}", + "ge_buy_limit": "5000", + "grand_exchange_price": "2924", + "examine": "I can summon a granite lobster familiar with this.", + "durability": null, + "name": "Granite lobster pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12069" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "2924", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Granite lobster pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12070" + }, + { + "requirements": "{23,41}", + "ge_buy_limit": "5000", + "grand_exchange_price": "1375", + "examine": "I can summon a macaw familiar with this.", + "durability": null, + "name": "Macaw pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12071" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "1375", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Macaw pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12072" + }, + { + "requirements": "{23,36}", + "ge_buy_limit": "5000", + "grand_exchange_price": "1804", + "examine": "I can summon a bronze minotaur familiar with this.", + "durability": null, + "name": "Bronze minotaur pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12073" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "1804", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Bronze minotaur pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12074" + }, + { + "requirements": "{23,46}", + "ge_buy_limit": "5000", + "grand_exchange_price": "2216", + "examine": "I can summon an iron minotaur familiar with this.", + "durability": null, + "name": "Iron minotaur pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12075" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "2216", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Iron minotaur pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12076" + }, + { + "requirements": "{23,56}", + "ge_buy_limit": "5000", + "grand_exchange_price": "2529", + "examine": "I can summon a steel minotaur familiar with this", + "durability": null, + "name": "Steel minotaur pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12077" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "2529", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Steel minotaur pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12078" + }, + { + "requirements": "{23,66}", + "ge_buy_limit": "5000", + "grand_exchange_price": "2666", + "examine": "I can summon a mithril minotaur with this.", + "durability": null, + "name": "Mithril minotaur pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12079" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "2666", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Mithril minotaur pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12080" + }, + { + "requirements": "{23,76}", + "ge_buy_limit": "5000", + "grand_exchange_price": "2520", + "examine": "I can summon an adamant minotaur familiar with this.", + "durability": null, + "name": "Adamant minotaur pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12081" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "2520", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Adamant minotaur pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12082" + }, + { + "requirements": "{23,86}", + "ge_buy_limit": "5000", + "grand_exchange_price": "373", + "examine": "I can summon a rune minotaur with this.", + "durability": null, + "name": "Rune minotaur pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12083" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "373", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Rune minotaur pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12084" + }, + { + "requirements": "{23,61}", + "ge_buy_limit": "5000", + "grand_exchange_price": "2468", + "examine": "I can summon a smoke devil familiar with this.", + "durability": null, + "name": "Smoke devil pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12085" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "2468", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Smoke devil pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12086" + }, + { + "requirements": "{23,40}", + "ge_buy_limit": "5000", + "grand_exchange_price": "319", + "examine": "I can summon a bull ant familiar with this.", + "durability": null, + "name": "Bull ant pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12087" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "319", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Bull ant pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12088" + }, + { + "requirements": "{23,92}", + "ge_buy_limit": "5000", + "grand_exchange_price": "3625", + "examine": "I can summon a wolpertinger familiar with this.", + "durability": null, + "name": "Wolpertinger pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12089" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "3625", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Wolpertinger pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12090" + }, + { + "requirements": "{23,28}", + "ge_buy_limit": "5000", + "grand_exchange_price": "906", + "examine": "I can summon a compost mound familiar with this.", + "durability": null, + "name": "Compost mound pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12091" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "906", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Compost mound pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12092" + }, + { + "requirements": "{23,96}", + "ge_buy_limit": "5000", + "grand_exchange_price": "3696", + "examine": "I can summon a pack yak familiar with this.", + "durability": null, + "name": "Pack yak pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12093" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "3696", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Pack yak pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12094" + }, + { + "requirements": "{23,43}", + "ge_buy_limit": "5000", + "grand_exchange_price": "1514", + "examine": "I can summon a spirit cockatrice familiar with this.", + "durability": null, + "name": "Sp. cockatrice pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12095" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "1514", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Sp. cockatrice pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12096" + }, + { + "requirements": "{23,43}", + "ge_buy_limit": "5000", + "grand_exchange_price": "1523", + "examine": "I can summon a spirit guthatrice familiar with this.", + "durability": null, + "name": "Sp. guthatrice pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12097" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "1523", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Sp. guthatrice pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12098" + }, + { + "requirements": "{23,43}", + "ge_buy_limit": "5000", + "grand_exchange_price": "1492", + "examine": "I can summon a spirit saratrice familiar with this.", + "durability": null, + "name": "Sp. saratrice pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12099" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "1492", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Sp. saratrice pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12100" + }, + { + "requirements": "{23,43}", + "ge_buy_limit": "5000", + "grand_exchange_price": "1515", + "examine": "I can summon a spirit zamatrice familiar with this.", + "durability": null, + "name": "Sp. zamatrice pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12101" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "1515", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Sp. zamatrice pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12102" + }, + { + "requirements": "{23,43}", + "ge_buy_limit": "5000", + "grand_exchange_price": "1531", + "examine": "I can summon a spirit pengatrice familiar with this.", + "durability": null, + "name": "Sp. pengatrice pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12103" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "1531", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Sp. pengatrice pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12104" + }, + { + "requirements": "{23,43}", + "ge_buy_limit": "5000", + "grand_exchange_price": "3085", + "examine": "I can summon a spirit coraxatrice familiar with this.", + "durability": null, + "name": "Sp. coraxatrice pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12105" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "3085", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Sp. coraxatrice pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12106" + }, + { + "requirements": "{23,43}", + "ge_buy_limit": "5000", + "grand_exchange_price": "3881", + "examine": "I can summon a spirit vulatrice familiar with this.", + "durability": null, + "name": "Sp. vulatrice pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12107" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "3881", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Sp. vulatrice pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12108" + }, + { + "ge_buy_limit": "10000", + "examine": "A stripy brown egg.", + "grand_exchange_price": "1053", + "durability": null, + "name": "Cockatrice egg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12109" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "1053", + "durability": null, + "name": "Cockatrice egg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12110" + }, + { + "ge_buy_limit": "5000", + "examine": "A stripy green egg.", + "grand_exchange_price": "1171", + "durability": null, + "name": "Guthatrice egg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12111" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "1171", + "durability": null, + "name": "Guthatrice egg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12112" + }, + { + "ge_buy_limit": "5000", + "examine": "A stripy blue egg.", + "grand_exchange_price": "1080", + "durability": null, + "name": "Saratrice egg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12113" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "1080", + "durability": null, + "name": "Saratrice egg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12114" + }, + { + "ge_buy_limit": "5000", + "examine": "A stripy red egg.", + "grand_exchange_price": "1154", + "durability": null, + "name": "Zamatrice egg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12115" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "1154", + "durability": null, + "name": "Zamatrice egg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12116" + }, + { + "ge_buy_limit": "5000", + "examine": "A stripy grey egg.", + "grand_exchange_price": "2676", + "durability": null, + "name": "Pengatrice egg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12117" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "2676", + "durability": null, + "name": "Pengatrice egg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12118" + }, + { + "ge_buy_limit": "5000", + "examine": "A stripy black egg.", + "grand_exchange_price": "2865", + "durability": null, + "name": "Coraxatrice egg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12119" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "2865", + "durability": null, + "name": "Coraxatrice egg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12120" + }, + { + "ge_buy_limit": "5000", + "examine": "A stripy pink egg.", + "grand_exchange_price": "18900", + "durability": null, + "name": "Vulatrice egg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12121" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "18900", + "durability": null, + "name": "Vulatrice egg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12122" + }, + { + "requirements": "{23,66}", + "ge_buy_limit": "5000", + "grand_exchange_price": "293", + "examine": "I can summon a barker toad familiar with this.", + "durability": null, + "name": "Barker toad pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12123" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "293", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Barker toad pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12124" + }, + { + "shop_price": "10", + "ge_buy_limit": "100", + "examine": "A swarm of little flies.", + "grand_exchange_price": "97", + "durability": null, + "name": "Flies", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12125" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "97", + "durability": null, + "name": "Flies", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12126" + }, + { + "shop_price": "10", + "ge_buy_limit": "100", + "examine": "Some beetle bits.", + "grand_exchange_price": "176", + "durability": null, + "name": "Beetle bits", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12127" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "176", + "durability": null, + "name": "Beetle bits", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12128" + }, + { + "ge_buy_limit": "100", + "examine": "Good for feeding birds.", + "grand_exchange_price": "1", + "durability": null, + "name": "Ground fishing bait", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12129" + }, + { + "shop_price": "10", + "ge_buy_limit": "100", + "examine": "Mmmm...nuts.", + "grand_exchange_price": "673", + "durability": null, + "name": "Nuts", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12130" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "673", + "durability": null, + "name": "Nuts", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12131" + }, + { + "examine": "Makes me want to do a truffle shuffle.", + "durability": null, + "name": "Truffle", + "tradeable": "false", + "destroy": "true", + "weight": "28.928", + "archery_ticket_price": "0", + "id": "12132" + }, + { + "durability": null, + "name": "Truffle", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12133", + "equipment_slot": "3" + }, + { + "ge_buy_limit": "5000", + "examine": "An evil turnip.", + "grand_exchange_price": "6750", + "durability": null, + "name": "Evil turnip", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12134" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "6750", + "durability": null, + "name": "Evil turnip", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12135" + }, + { + "ge_buy_limit": "5000", + "examine": "An evil turnip.", + "grand_exchange_price": "133", + "durability": null, + "name": "2/3 evil turnip", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12136" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "133", + "durability": null, + "name": "2/3 evil turnip", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12137" + }, + { + "ge_buy_limit": "5000", + "examine": "An evil turnip.", + "grand_exchange_price": "20", + "durability": null, + "name": "1/3 evil turnip", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12138" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "20", + "durability": null, + "name": "1/3 evil turnip", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12139" + }, + { + "ge_buy_limit": "100", + "examine": "4 doses of Summoning potion.", + "grand_exchange_price": "4489", + "durability": null, + "name": "Summoning potion(4)", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "12140" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "4489", + "durability": null, + "name": "Summoning potion(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12141" + }, + { + "ge_buy_limit": "100", + "examine": "3 doses of Summoning potion.", + "grand_exchange_price": "3320", + "durability": null, + "name": "Summoning potion(3)", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "12142" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3320", + "durability": null, + "name": "Summoning potion(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12143" + }, + { + "ge_buy_limit": "100", + "examine": "2 doses of Summoning potion.", + "grand_exchange_price": "1671", + "durability": null, + "name": "Summoning potion(2)", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "12144" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1671", + "durability": null, + "name": "Summoning potion(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12145" + }, + { + "ge_buy_limit": "100", + "examine": "1 dose of Summoning potion.", + "grand_exchange_price": "1576", + "durability": null, + "name": "Summoning potion(1)", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "12146" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1576", + "durability": null, + "name": "Summoning potion(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12147" + }, + { + "ge_buy_limit": "100", + "examine": "Grows into the root-vegetable of all evil.", + "grand_exchange_price": "68", + "durability": null, + "name": "Evil turnip seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12148" + }, + { + "ge_buy_limit": "5000", + "examine": "Utterly terrifying!", + "grand_exchange_price": "7101", + "durability": null, + "name": "Carved evil turnip", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12153" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "7101", + "durability": null, + "name": "Carved evil turnip", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12154" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "3", + "examine": "Can be used to create Summoning pouches.", + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12155" + }, + { + "ge_buy_limit": "5000", + "examine": "This is what bees craft.", + "grand_exchange_price": "393", + "durability": null, + "name": "Honeycomb", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12156" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "393", + "durability": null, + "name": "Honeycomb", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12157" + }, + { + "shop_price": "1", + "examine": "A charm used to summon familiars.", + "durability": null, + "name": "Gold charm", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12158" + }, + { + "examine": "A charm used to summon familiars.", + "durability": null, + "name": "Green charm", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12159" + }, + { + "examine": "A charm used to summon familiars.", + "durability": null, + "name": "Crimson charm", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12160" + }, + { + "examine": "A charm used to summon familiars", + "durability": null, + "name": "Abyssal charm", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12161" + }, + { + "examine": "A charm used to summon talon beasts.", + "durability": null, + "name": "Talon beast charm", + "archery_ticket_price": "0", + "id": "12162" + }, + { + "examine": "A charm used to summon familiars.", + "durability": null, + "name": "Blue charm", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12163" + }, + { + "shop_price": "2", + "examine": "A charm needed to summon a Void ravager.", + "durability": null, + "name": "Ravager charm", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12164" + }, + { + "shop_price": "2", + "examine": "A charm needed to summon a Void shifter.", + "durability": null, + "name": "Shifter charm", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12165" + }, + { + "shop_price": "2", + "examine": "A charm needed to summon a Void Spinner.", + "durability": null, + "name": "Spinner charm", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12166" + }, + { + "shop_price": "2", + "examine": "A charm needed to summon a Void torcher.", + "durability": null, + "name": "Torcher charm", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12167" + }, + { + "examine": "A charm used to summon familiars.", + "durability": null, + "name": "Obsidian charm", + "archery_ticket_price": "0", + "id": "12168" + }, + { + "requirements": "{23,99}", + "shop_price": "99000", + "examine": "The cape worn by master summoners.", + "durability": null, + "name": "Summoning cape", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "12169", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0", + "equipment_slot": "1" + }, + { + "requirements": "{23,99}", + "durability": null, + "name": "Summoning cape(t)", + "archery_ticket_price": "0", + "id": "12170", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,4,0,0", + "equipment_slot": "1" + }, + { + "remove_head": "true", + "requirements": "{23,99}", + "shop_price": "99000", + "examine": "Summoning skillcape hood.", + "durability": null, + "name": "Summoning hood", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "12171", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "10000", + "examine": "A fresh herb.", + "grand_exchange_price": "3597", + "durability": null, + "name": "Clean spirit weed", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "12172" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "3597", + "durability": null, + "name": "Clean spirit weed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12173" + }, + { + "requirements": "{15,35}", + "ge_buy_limit": "10000", + "examine": "I need to clean this herb before I can use it.", + "grand_exchange_price": "3634", + "durability": null, + "name": "Grimy spirit weed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12174" + }, + { + "ge_buy_limit": "10000", + "grand_exchange_price": "3634", + "durability": null, + "name": "Grimy spirit weed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12175" + }, + { + "requirements": "{19,36}", + "ge_buy_limit": "100", + "examine": "A seed for spirit weed.", + "grand_exchange_price": "698", + "durability": null, + "name": "Spirit weed seed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12176" + }, + { + "ge_buy_limit": "100", + "examine": "I need another ingredient to finish this spirit weed potion.", + "grand_exchange_price": "2963", + "durability": null, + "name": "Spirit weed potion(unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12181" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "2963", + "durability": null, + "name": "Spirit weed potion(unf)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12182" + }, + { + "shop_price": "25", + "ge_buy_limit": "10000", + "examine": "Shards of an obelisk.", + "grand_exchange_price": "24", + "durability": null, + "name": "Spirit shards", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12183" + }, + { + "examine": "(Baby) It's so adorably tiny! (Adult) How cute!", + "durability": null, + "name": "Gecko", + "archery_ticket_price": "0", + "id": "12184" + }, + { + "examine": "A fantastic saradomin owl.", + "durability": null, + "name": "Saradomin owl", + "archery_ticket_price": "0", + "id": "12185" + }, + { + "examine": "A stately zamorak hawk.", + "durability": null, + "name": "Zamorak hawk", + "archery_ticket_price": "0", + "id": "12186" + }, + { + "examine": "An impressive Guthix raptor.", + "durability": null, + "name": "Guthix raptor", + "archery_ticket_price": "0", + "id": "12187" + }, + { + "examine": "If you see them circling: run.", + "durability": null, + "name": "Vulture", + "archery_ticket_price": "0", + "id": "12190" + }, + { + "examine": "It's lively and energetic.", + "durability": null, + "name": "Terrier puppy", + "archery_ticket_price": "0", + "id": "12191" + }, + { + "examine": "This is one fast little pooch.", + "durability": null, + "name": "Greyhound puppy", + "archery_ticket_price": "0", + "id": "12192" + }, + { + "examine": "Soft but strong... and cute.", + "durability": null, + "name": "Labrador puppy", + "archery_ticket_price": "0", + "id": "12193" + }, + { + "examine": "Now, if only I could find another hundred...", + "durability": null, + "name": "Dalmatian puppy", + "archery_ticket_price": "0", + "id": "12194" + }, + { + "examine": "This little puppy is very quiet. (Puppy)Come by! Come by! (Adult)", + "durability": null, + "name": "Sheepdog puppy", + "archery_ticket_price": "0", + "id": "12195" + }, + { + "examine": "One proud little puppy. (Puppy)Looks like it's chewing a wasp. (Adult)", + "durability": null, + "name": "Bulldog puppy", + "archery_ticket_price": "0", + "id": "12196" + }, + { + "examine": "A hatchling green dragon.", + "durability": null, + "name": "Dragon hatchling", + "archery_ticket_price": "0", + "id": "12197" + }, + { + "examine": "Little Nipper.", + "durability": null, + "name": "Baby giant crab", + "archery_ticket_price": "0", + "id": "12198" + }, + { + "examine": "A stripy little baby raccoon.", + "durability": null, + "name": "Baby raccoon", + "archery_ticket_price": "0", + "id": "12199" + }, + { + "examine": "An experienced nut-thief.", + "durability": null, + "name": "Squirrel", + "archery_ticket_price": "0", + "id": "12200" + }, + { + "examine": "It's a colour-coordinated lizard!", + "durability": null, + "name": "Chameleon", + "archery_ticket_price": "0", + "id": "12203" + }, + { + "remove_head": "true", + "requirements": "{23,10}", + "shop_price": "100", + "ge_buy_limit": "100", + "examine": "Doors could be a problem, wearing these...", + "durability": null, + "weight": "1", + "equipment_slot": "0", + "grand_exchange_price": "40", + "name": "Antlers", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12204", + "bonuses": "0,0,0,0,0,0,0,0,0,0,8,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "40", + "durability": null, + "name": "Antlers", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12205" + }, + { + "remove_head": "true", + "shop_price": "100", + "examine": "Doors could be a problem, wearing these...", + "grand_exchange_price": "50", + "durability": null, + "name": "Antlers (charged)", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "12206", + "bonuses": "0,0,0,0,0,0,0,0,0,0,8,0,0,0,0", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "requirements": "{23,30}", + "shop_price": "200", + "ge_buy_limit": "100", + "examine": "It's a little smelly in there.", + "durability": null, + "weight": "3", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "254", + "name": "Lizard skull", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12207", + "bonuses": "0,0,0,0,1,2,3,4,2,3,12,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "254", + "durability": null, + "name": "Lizard skull", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12208" + }, + { + "remove_head": "true", + "shop_price": "200", + "examine": "It's a little smelly in there.", + "durability": null, + "weight": "3", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "211", + "name": "Lizard skull (charged)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12209", + "bonuses": "0,0,0,0,1,2,3,4,2,3,12,0,0,0,0" + }, + { + "requirements": "{4,50}-{23,20}", + "ge_buy_limit": "100", + "examine": "It's fun to go to the O-B-E-L-I-S-K!", + "grand_exchange_price": "234", + "durability": null, + "name": "Feather headdress", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "12210", + "bonuses": "0,0,0,-1,2,4,6,8,4,4,20,0,0,0,0", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "234", + "durability": null, + "name": "Feather headdress", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12211" + }, + { + "examine": "It's fun to go to the O-B-E-L-I-S-K!", + "grand_exchange_price": "107", + "durability": null, + "name": "Feather headdress (charged)", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "12212", + "bonuses": "0,0,0,-1,2,4,6,8,4,4,20,0,0,0,0", + "equipment_slot": "0" + }, + { + "requirements": "{4,50}-{23,20}", + "ge_buy_limit": "100", + "examine": "It's fun to go to the O-B-E-L-I-S-K!", + "grand_exchange_price": "662", + "durability": null, + "name": "Feather headdress", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "12213", + "bonuses": "0,0,0,-1,2,4,6,8,4,4,20,0,0,0,0", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "662", + "durability": null, + "name": "Feather headdress", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12214" + }, + { + "examine": "It's fun to go to the O-B-E-L-I-S-K!", + "grand_exchange_price": "107", + "durability": null, + "name": "Feather headdress (charged)", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "12215", + "bonuses": "0,0,0,-1,2,4,6,8,4,4,20,0,0,0,0", + "equipment_slot": "0" + }, + { + "requirements": "{4,50}-{23,20}", + "ge_buy_limit": "100", + "examine": "It's fun to go to the O-B-E-L-I-S-K!", + "grand_exchange_price": "90", + "durability": null, + "name": "Feather headdress", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "12216", + "bonuses": "0,0,0,-1,2,4,6,8,4,4,20,0,0,0,0", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "90", + "durability": null, + "name": "Feather headdress", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12217" + }, + { + "examine": "It's fun to go to the O-B-E-L-I-S-K!", + "grand_exchange_price": "107", + "durability": null, + "name": "Feather headdress (charged)", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "12218", + "bonuses": "0,0,0,-1,2,4,6,8,4,4,20,0,0,0,0", + "equipment_slot": "0" + }, + { + "requirements": "{4,50}-{23,20}", + "ge_buy_limit": "100", + "examine": "It's fun to go to the O-B-E-L-I-S-K!", + "grand_exchange_price": "107", + "durability": null, + "name": "Feather headdress", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "12219", + "bonuses": "0,0,0,-1,2,4,6,8,4,4,20,0,0,0,0", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "107", + "durability": null, + "name": "Feather headdress", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12220" + }, + { + "examine": "It's fun to go to the O-B-E-L-I-S-K!", + "grand_exchange_price": "107", + "durability": null, + "name": "Feather headdress (charged)", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "12221", + "bonuses": "0,0,0,-1,2,4,6,8,4,4,20,0,0,0,0", + "equipment_slot": "0" + }, + { + "requirements": "{4,50}-{23,20}", + "ge_buy_limit": "100", + "examine": "It's fun to go to the O-B-E-L-I-S-K!", + "grand_exchange_price": "211", + "durability": null, + "name": "Feather headdress", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "12222", + "bonuses": "0,0,0,-1,2,4,6,8,4,4,20,0,0,0,0", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "211", + "durability": null, + "name": "Feather headdress", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12223" + }, + { + "examine": "It's fun to go to the O-B-E-L-I-S-K!", + "grand_exchange_price": "107", + "durability": null, + "name": "Feather headdress (charged)", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "12224", + "bonuses": "0,0,0,-1,2,4,6,8,4,4,20,0,0,0,0", + "equipment_slot": "0" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12294" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12296" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12298" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12300" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12302" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12304" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12306" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12308" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12310" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12312" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12314" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12316" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12318" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12320" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12322" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12324" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12326" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12328" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12330" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12332" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12334" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12336" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12338" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12340" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12342" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12344" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12346" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12348" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12350" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12352" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12354" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12356" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12358" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12360" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12362" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12364" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12366" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12368" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12370" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12372" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12374" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12376" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12378" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12380" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12382" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12384" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12386" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12388" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12390" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12392" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12394" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12396" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12398" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12400" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12402" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12404" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12406" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12408" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12410" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12412" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12414" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12416" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12418" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12420" + }, + { + "requirements": "{23,41}", + "ge_buy_limit": "5000", + "grand_exchange_price": "96", + "examine": "A scroll for a macaw familiar.", + "durability": null, + "name": "Herbcall scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12422" + }, + { + "requirements": "{23,69}", + "ge_buy_limit": "5000", + "grand_exchange_price": "258", + "examine": "A scroll for a fruit bat familiar.", + "durability": null, + "name": "Fruitfall scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12423" + }, + { + "requirements": "{23,56}", + "ge_buy_limit": "5000", + "grand_exchange_price": "146", + "examine": "A scroll for an ibis familiar.", + "durability": null, + "name": "Fish rain scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12424" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "7", + "examine": "A scroll for a spirit wolf familiar.", + "durability": null, + "name": "Howl scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12425" + }, + { + "requirements": "{23,47}", + "ge_buy_limit": "5000", + "grand_exchange_price": "97", + "examine": "A scroll for a magpie familiar.", + "durability": null, + "name": "Thieving fingers scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12426" + }, + { + "requirements": "{23,62}", + "ge_buy_limit": "5000", + "grand_exchange_price": "533", + "examine": "A scroll for an abyssal lurker familiar.", + "durability": null, + "name": "Abyssal stealth scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12427" + }, + { + "requirements": "{23,10}", + "ge_buy_limit": "5000", + "grand_exchange_price": "237", + "examine": "A scroll for a spirit spider familiar.", + "durability": null, + "name": "Egg spawn scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12428" + }, + { + "requirements": "{23,33}", + "ge_buy_limit": "5000", + "grand_exchange_price": "97", + "examine": "A scroll for a beaver familiar.", + "durability": null, + "name": "Multichop scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12429" + }, + { + "requirements": "{23,23}", + "ge_buy_limit": "5000", + "grand_exchange_price": "121", + "examine": "A scroll for an albino rat familiar.", + "durability": null, + "name": "Cheese feast scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12430" + }, + { + "requirements": "{23,40}", + "ge_buy_limit": "5000", + "grand_exchange_price": "39", + "examine": "A scroll for a bull ant familiar.", + "durability": null, + "name": "Unburden scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12431" + }, + { + "requirements": "{23,19}", + "ge_buy_limit": "5000", + "grand_exchange_price": "72", + "examine": "A scroll for a spirit scorpion familiar.", + "durability": null, + "name": "Venom shot scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12432" + }, + { + "requirements": "{23,32}", + "ge_buy_limit": "5000", + "grand_exchange_price": "99", + "examine": "A scroll for a honey badger familiar.", + "durability": null, + "name": "Insane ferocity scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12433" + }, + { + "requirements": "{23,88}", + "ge_buy_limit": "5000", + "grand_exchange_price": "299", + "examine": "A scroll for a unicorn stallion familiar.", + "durability": null, + "name": "Healing aura scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12434" + }, + { + "requirements": "{23,96}", + "ge_buy_limit": "5000", + "grand_exchange_price": "428", + "examine": "A scroll for a pack yak familiar.", + "durability": null, + "name": "Winter storage scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12435" + }, + { + "requirements": "{23,63}", + "ge_buy_limit": "5000", + "grand_exchange_price": "223", + "examine": "A scroll for a spirit cobra familiar.", + "durability": null, + "name": "Oph. incubation scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12436" + }, + { + "requirements": "{23,92}", + "ge_buy_limit": "5000", + "grand_exchange_price": "419", + "examine": "A scroll for a wolpertinger familiar.", + "durability": null, + "name": "Magic focus scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12437" + }, + { + "requirements": "{23,68}", + "ge_buy_limit": "5000", + "grand_exchange_price": "220", + "examine": "A scroll for a bunyip familiar.", + "durability": null, + "name": "Swallow whole scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12438" + }, + { + "requirements": "{23,67}", + "ge_buy_limit": "5000", + "grand_exchange_price": "269", + "examine": "A scroll for a war tortoise familiar.", + "durability": null, + "name": "Testudo scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12439" + }, + { + "requirements": "{23,28}", + "ge_buy_limit": "5000", + "grand_exchange_price": "47", + "examine": "A scroll for a compost mound familiar.", + "durability": null, + "name": "Generate compost scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12440" + }, + { + "requirements": "{23,52}", + "ge_buy_limit": "5000", + "grand_exchange_price": "35", + "examine": "A scroll for a spirit terrorbird familiar.", + "durability": null, + "name": "Tireless run scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12441" + }, + { + "requirements": "{23,80}", + "ge_buy_limit": "5000", + "grand_exchange_price": "174", + "examine": "A scroll for a hydra familiar.", + "durability": null, + "name": "Regrowth scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12442" + }, + { + "requirements": "{23,34}", + "ge_buy_limit": "5000", + "grand_exchange_price": "1118", + "examine": "A scroll for a Pest Control familiar.", + "durability": null, + "name": "Call to arms scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12443" + }, + { + "requirements": "{23,49}", + "ge_buy_limit": "5000", + "grand_exchange_price": "148", + "examine": "A scroll for a bloated leech familiar.", + "durability": null, + "name": "Blood drain scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12444" + }, + { + "requirements": "{23,4}", + "ge_buy_limit": "5000", + "grand_exchange_price": "7", + "examine": "A scroll for a dreadfowl familiar.", + "durability": null, + "name": "Dreadfowl strike scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12445" + }, + { + "requirements": "{23,25}", + "ge_buy_limit": "5000", + "grand_exchange_price": "122", + "examine": "A scroll for a spirit kalphite familiar.", + "durability": null, + "name": "Sandstorm scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12446" + }, + { + "requirements": "{23,31}", + "ge_buy_limit": "1000", + "grand_exchange_price": "98", + "examine": "A scroll for a vampire bat familiar.", + "durability": null, + "name": "Vampire touch scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12447" + }, + { + "requirements": "{23,42}", + "ge_buy_limit": "5000", + "grand_exchange_price": "123", + "examine": "A scroll for an evil turnip familiar.", + "durability": null, + "name": "Evil flames scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12448" + }, + { + "requirements": "{23,74}", + "ge_buy_limit": "5000", + "grand_exchange_price": "219", + "examine": "A scroll for a granite lobster familiar.", + "durability": null, + "name": "Crushing claw scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12449" + }, + { + "requirements": "{23,75}", + "ge_buy_limit": "5000", + "grand_exchange_price": "221", + "examine": "A scroll for a praying mantis familiar.", + "durability": null, + "name": "Mantis strike scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12450" + }, + { + "requirements": "{23,71}", + "ge_buy_limit": "5000", + "grand_exchange_price": "12", + "examine": "A scroll for an arctic bear familiar.", + "durability": null, + "name": "Arctic blast scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12451" + }, + { + "requirements": "{23,66}", + "ge_buy_limit": "5000", + "grand_exchange_price": "10", + "examine": "A scroll for a barker toad familiar.", + "durability": null, + "name": "Toad bark scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12452" + }, + { + "requirements": "{23,55}", + "ge_buy_limit": "5000", + "grand_exchange_price": "202", + "examine": "A scroll for a spirit jelly familiar.", + "durability": null, + "name": "Dissolve scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12453" + }, + { + "requirements": "{23,54}", + "ge_buy_limit": "5000", + "grand_exchange_price": "163", + "examine": "A scroll for an abyssal parasite familiar.", + "durability": null, + "name": "Abyssal drain scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12454" + }, + { + "requirements": "{23,58}", + "ge_buy_limit": "5000", + "grand_exchange_price": "198", + "examine": "A scroll for a karamthulhu overlord familiar.", + "durability": null, + "name": "Doomsphere scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12455" + }, + { + "requirements": "{23,83}", + "ge_buy_limit": "5000", + "grand_exchange_price": "9", + "examine": "A scroll for a spirit dagannoth familiar.", + "durability": null, + "name": "Spike shot scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12456" + }, + { + "requirements": "{23,78}", + "ge_buy_limit": "5000", + "grand_exchange_price": "146", + "examine": "A scroll for a giant ent familiar.", + "durability": null, + "name": "Acorn missile scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12457" + }, + { + "requirements": "{23,43}", + "ge_buy_limit": "5000", + "grand_exchange_price": "97", + "examine": "A scroll for a cockatrice variant familiar.", + "durability": null, + "name": "Petrifying gaze scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12458" + }, + { + "requirements": "{23,13}", + "ge_buy_limit": "5000", + "grand_exchange_price": "10", + "examine": "A scroll for a thorny snail familiar.", + "durability": null, + "name": "Slime spray scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12459" + }, + { + "requirements": "{23,18}", + "ge_buy_limit": "5000", + "grand_exchange_price": "47", + "examine": "A scroll for a desert wyrm familiar.", + "durability": null, + "name": "Electric lash scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12460" + }, + { + "requirements": "{23,36}", + "ge_buy_limit": "5000", + "grand_exchange_price": "135", + "examine": "A scroll for a bronze minotaur familiar.", + "durability": null, + "name": "Bronze bull rush scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12461" + }, + { + "requirements": "{23,46}", + "ge_buy_limit": "5000", + "grand_exchange_price": "180", + "examine": "A scroll for an iron minotaur familiar.", + "durability": null, + "name": "Iron bull rush scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12462" + }, + { + "requirements": "{23,56}", + "ge_buy_limit": "5000", + "grand_exchange_price": "182", + "examine": "A scroll for a steel minotaur familiar.", + "durability": null, + "name": "Steel bull rush scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12463" + }, + { + "requirements": "{23,66}", + "ge_buy_limit": "5000", + "grand_exchange_price": "198", + "examine": "A scroll for a mithril minotaur familiar.", + "durability": null, + "name": "Mith bull rush scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12464" + }, + { + "requirements": "{23,76}", + "ge_buy_limit": "5000", + "grand_exchange_price": "203", + "examine": "A scroll for an adamant minotaur familiar.", + "durability": null, + "name": "Addy bull rush scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12465" + }, + { + "requirements": "{23,86}", + "ge_buy_limit": "5000", + "grand_exchange_price": "67", + "examine": "A scroll for a rune minotaur familiar.", + "durability": null, + "name": "Rune bull rush scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12466" + }, + { + "requirements": "{23,64}", + "ge_buy_limit": "5000", + "grand_exchange_price": "171", + "examine": "A scroll for a stranger plant familiar.", + "durability": null, + "name": "Poisonous blast scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12467" + }, + { + "requirements": "{23,61}", + "ge_buy_limit": "5000", + "grand_exchange_price": "170", + "examine": "A scroll for a smoke devil familiar.", + "durability": null, + "name": "Dust cloud scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12468" + }, + { + "examine": "A hatchling red dragon.", + "durability": null, + "name": "Dragon hatchling", + "archery_ticket_price": "0", + "id": "12469" + }, + { + "examine": "A hatchling blue dragon.", + "durability": null, + "name": "Hatchling dragon", + "archery_ticket_price": "0", + "id": "12471" + }, + { + "examine": "A hatchling green dragon.", + "durability": null, + "name": "Hatchling dragon", + "archery_ticket_price": "0", + "id": "12473" + }, + { + "examine": "A hatchling black dragon.", + "durability": null, + "name": "Hatchling dragon", + "archery_ticket_price": "0", + "id": "12475" + }, + { + "examine": "This will hatch into a mighty dragon.", + "durability": null, + "name": "Red dragon egg", + "tradeable": "false", + "destroy": "false", + "weight": "1", + "archery_ticket_price": "0", + "id": "12477" + }, + { + "examine": "This will hatch into a mighty dragon.", + "durability": null, + "name": "Blue dragon egg", + "tradeable": "false", + "destroy": "false", + "weight": "1", + "archery_ticket_price": "0", + "id": "12478" + }, + { + "examine": "This will hatch into a mighty dragon.", + "durability": null, + "name": "Green dragon egg", + "tradeable": "false", + "destroy": "false", + "weight": "1", + "archery_ticket_price": "0", + "id": "12479" + }, + { + "examine": "This will hatch into a mighty dragon.", + "durability": null, + "name": "Black dragon egg", + "tradeable": "false", + "destroy": "false", + "weight": "1", + "archery_ticket_price": "0", + "id": "12480" + }, + { + "examine": "Can't fly and can barely walk, but adorable nonetheless.", + "durability": null, + "name": "Baby penguin", + "archery_ticket_price": "0", + "id": "12481" + }, + { + "examine": "I can hatch this in an incubator.", + "durability": null, + "name": "Penguin egg", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12483" + }, + { + "examine": "Chick: A raven chick.", + "durability": null, + "name": "Raven chick", + "archery_ticket_price": "0", + "id": "12484" + }, + { + "examine": "Chick: A raven chick.", + "durability": null, + "name": "Raven", + "archery_ticket_price": "0", + "id": "12485" + }, + { + "examine": "(Baby) A stripy little baby raccoon.(Adult) He can run with us.", + "durability": null, + "name": "Baby raccoon", + "archery_ticket_price": "0", + "id": "12486" + }, + { + "examine": "(Baby) A stripy little baby raccoon.(Adult) He can run with us.", + "durability": null, + "name": "Raccoon", + "archery_ticket_price": "0", + "id": "12487" + }, + { + "examine": "(Baby) It's so adorably tiny! (Adult) How cute!", + "durability": null, + "name": "Baby gecko", + "archery_ticket_price": "0", + "id": "12488" + }, + { + "examine": "(Baby) It's so adorably tiny! (Adult) How cute!", + "durability": null, + "name": "Gecko", + "archery_ticket_price": "0", + "id": "12489" + }, + { + "examine": "Adult: An experienced nut-thief.Baby: A tiny nut-thief.", + "durability": null, + "name": "Baby squirrel", + "archery_ticket_price": "0", + "id": "12490" + }, + { + "examine": "Adult: An experienced nut-thief.Baby: A tiny nut-thief.", + "durability": null, + "name": "Squirrel", + "archery_ticket_price": "0", + "id": "12491" + }, + { + "examine": "It's a colour-coordinated lizard!", + "durability": null, + "name": "Baby chameleon", + "archery_ticket_price": "0", + "id": "12492" + }, + { + "examine": "It's a colour-coordinated lizard!", + "durability": null, + "name": "Chameleon", + "archery_ticket_price": "0", + "id": "12493" + }, + { + "examine": "A lizard's egg.", + "durability": null, + "name": "Chameleon egg", + "weight": "1", + "archery_ticket_price": "0", + "id": "12494" + }, + { + "examine": "A lizard's egg.", + "durability": null, + "name": "Chameleon egg", + "weight": "1", + "archery_ticket_price": "0", + "id": "12495" + }, + { + "examine": "(Baby) It's a tiny, cheeky monkey. (Adult) Hide the bananas!", + "durability": null, + "name": "Baby monkey", + "archery_ticket_price": "0", + "id": "12496" + }, + { + "examine": "If you see them circling: run.", + "durability": null, + "name": "Vulture chick", + "archery_ticket_price": "0", + "id": "12498" + }, + { + "examine": "If you see them circling: run.", + "durability": null, + "name": "Vulture", + "archery_ticket_price": "0", + "id": "12499" + }, + { + "requirements": "{23,40}", + "examine": "Baby: Little NipperAdult: Bigger Nipper.", + "durability": null, + "name": "Baby giant crab", + "archery_ticket_price": "0", + "id": "12500" + }, + { + "requirements": "{23,40}", + "examine": "Baby: Little NipperAdult: Bigger Nipper.", + "durability": null, + "name": "Giant crab", + "archery_ticket_price": "0", + "id": "12501" + }, + { + "examine": "Apparently, this token is worth one baby giant crab to someone called Nung.", + "durability": null, + "name": "Crunchy claw token", + "archery_ticket_price": "0", + "id": "12502" + }, + { + "examine": "A fluffy chick.", + "durability": null, + "name": "Saradomin chick", + "archery_ticket_price": "0", + "id": "12503" + }, + { + "examine": "Lovely blue plumage.", + "durability": null, + "name": "Saradomin bird", + "archery_ticket_price": "0", + "id": "12504" + }, + { + "examine": "A fantastic saradomin owl.", + "durability": null, + "name": "Saradomin owl", + "archery_ticket_price": "0", + "id": "12505" + }, + { + "examine": "A fluffy chick.", + "durability": null, + "name": "Zamorak chick", + "archery_ticket_price": "0", + "id": "12506" + }, + { + "examine": "Lovely red plumage.", + "durability": null, + "name": "Zamorak bird", + "archery_ticket_price": "0", + "id": "12507" + }, + { + "examine": "A stately zamorak hawk.", + "durability": null, + "name": "Zamorak hawk", + "archery_ticket_price": "0", + "id": "12508" + }, + { + "examine": "A fluffy chick.", + "durability": null, + "name": "Guthix chick", + "archery_ticket_price": "0", + "id": "12509" + }, + { + "examine": "Lovely green plumage.", + "durability": null, + "name": "Guthix bird", + "archery_ticket_price": "0", + "id": "12510" + }, + { + "examine": "An impressive Guthix raptor.", + "durability": null, + "name": "Guthix raptor", + "archery_ticket_price": "0", + "id": "12511" + }, + { + "requirements": "{4,23}", + "examine": "It's lively and energetic.", + "durability": null, + "name": "Terrier puppy", + "archery_ticket_price": "0", + "id": "12512" + }, + { + "requirements": "{4,23}", + "examine": "It's lively and energetic.", + "durability": null, + "name": "Terrier", + "archery_ticket_price": "0", + "id": "12513" + }, + { + "requirements": "{4,23}", + "examine": "This is one fast little pooch.", + "durability": null, + "name": "Greyhound puppy", + "archery_ticket_price": "0", + "id": "12514" + }, + { + "requirements": "{4,23}", + "examine": "An aerodynamic doggy.", + "durability": null, + "name": "Greyhound", + "archery_ticket_price": "0", + "id": "12515" + }, + { + "requirements": "{4,23}", + "examine": "Soft but strong... and cute.", + "durability": null, + "name": "Labrador puppy", + "archery_ticket_price": "0", + "id": "12516" + }, + { + "requirements": "{4,23}", + "examine": "My most faithful friend.", + "durability": null, + "name": "Labrador", + "archery_ticket_price": "0", + "id": "12517" + }, + { + "requirements": "{4,23}", + "examine": "Now, if only I could find another hundred...", + "durability": null, + "name": "Dalmatian puppy", + "archery_ticket_price": "0", + "id": "12518" + }, + { + "requirements": "{4,23}", + "examine": "A purebred doggy.", + "durability": null, + "name": "Dalmatian", + "archery_ticket_price": "0", + "id": "12519" + }, + { + "requirements": "{4,23}", + "examine": "This little puppy is very quiet.", + "durability": null, + "name": "Sheepdog puppy", + "archery_ticket_price": "0", + "id": "12520" + }, + { + "requirements": "{4,23}", + "examine": "Come by! Come by!", + "durability": null, + "name": "Sheepdog", + "archery_ticket_price": "0", + "id": "12521" + }, + { + "requirements": "{4,23}", + "examine": "One proud little puppy.", + "durability": null, + "name": "Bulldog puppy", + "archery_ticket_price": "0", + "id": "12522" + }, + { + "requirements": "{4,23}", + "examine": "Looks like it's chewing a wasp.", + "durability": null, + "name": "Bulldog", + "archery_ticket_price": "0", + "id": "12523" + }, + { + "requirements": "{23,99}", + "shop_price": "99000", + "examine": "The cape worn by master summoners.", + "durability": null, + "name": "Summoning cape", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "12524", + "bonuses": "0,0,0,0,0,9,9,9,9,9,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "shop_price": "1", + "examine": "A charm used to summon familiars.", + "durability": null, + "name": "Gold charm", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12527" + }, + { + "examine": "A key to Pikkupstix's trapdoor.", + "durability": null, + "name": "Trapdoor key", + "archery_ticket_price": "0", + "id": "12528" + }, + { + "shop_price": "25", + "examine": "Shards of an obelisk.", + "grand_exchange_price": "24", + "durability": null, + "name": "Spirit shards", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12530" + }, + { + "requirements": "{23,56}", + "ge_buy_limit": "5000", + "grand_exchange_price": "1914", + "examine": "I can summon an ibis familiar with this.", + "durability": null, + "name": "Ibis pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12531" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "1914", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Ibis pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12532" + }, + { + "requirements": "{23,16}", + "ge_buy_limit": "5000", + "grand_exchange_price": "7", + "examine": "A scroll for a granite crab familiar.", + "durability": null, + "name": "Stony shell scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12533" + }, + { + "ge_buy_limit": "1000", + "examine": "Meat from a creature that can be hunted in Isafdar.", + "grand_exchange_price": "7968", + "durability": null, + "name": "Raw pawya meat", + "tradeable": "true", + "weight": "0.33", + "archery_ticket_price": "0", + "id": "12535" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "7968", + "durability": null, + "name": "Raw pawya meat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12536" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12538" + }, + { + "ge_buy_limit": "5000", + "examine": "Spikes from a grenwall.", + "grand_exchange_price": "1704", + "durability": null, + "name": "Grenwall spikes", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12539" + }, + { + "durability": null, + "name": "Picture", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12545" + }, + { + "examine": "A most unlikely creature.", + "durability": null, + "name": "Platypus", + "archery_ticket_price": "0", + "id": "12547" + }, + { + "examine": "A most unlikely creature.", + "durability": null, + "name": "Platypus", + "archery_ticket_price": "0", + "id": "12548" + }, + { + "examine": "A most unlikely creature.", + "durability": null, + "name": "Platypus", + "archery_ticket_price": "0", + "id": "12549" + }, + { + "examine": "A most unlikely creature.", + "durability": null, + "name": "Platypus", + "archery_ticket_price": "0", + "id": "12550" + }, + { + "examine": "A most unlikely creature.", + "durability": null, + "name": "Baby platypus", + "archery_ticket_price": "0", + "id": "12551" + }, + { + "examine": "A most unlikely creature.", + "durability": null, + "name": "Baby platypus", + "archery_ticket_price": "0", + "id": "12552" + }, + { + "examine": "A most unlikely creature.", + "durability": null, + "name": "Baby platypus", + "archery_ticket_price": "0", + "id": "12553" + }, + { + "examine": "A most unlikely creature.", + "durability": null, + "name": "Patrick", + "archery_ticket_price": "0", + "id": "12554" + }, + { + "examine": "A most unlikely creature.", + "durability": null, + "name": "Penelope", + "archery_ticket_price": "0", + "id": "12555" + }, + { + "examine": "I bet he can't wait until it's cooked.", + "durability": null, + "name": "Peter", + "archery_ticket_price": "0", + "id": "12556" + }, + { + "examine": "A most unlikely creature.", + "durability": null, + "name": "Peanut", + "archery_ticket_price": "0", + "id": "12557" + }, + { + "examine": "Marginally better than egg on your face.", + "durability": null, + "name": "Mud", + "archery_ticket_price": "0", + "id": "12558", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "The height of style?", + "grand_exchange_price": "1004", + "durability": null, + "name": "Ogre wig", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "12559", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "1004", + "durability": null, + "name": "Ogre wig", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12560" + }, + { + "shop_price": "60", + "ge_buy_limit": "100", + "examine": "It's a little big on me.", + "grand_exchange_price": "197", + "durability": null, + "name": "Ogre kilt", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "12561", + "equipment_slot": "7" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "197", + "durability": null, + "name": "Ogre kilt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12562" + }, + { + "remove_sleeves": "true", + "shop_price": "60", + "ge_buy_limit": "100", + "examine": "It's a little big on me.", + "grand_exchange_price": "536", + "durability": null, + "name": "Ogre top", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "12563", + "equipment_slot": "4" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "536", + "durability": null, + "name": "Ogre top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12564" + }, + { + "shop_price": "60", + "ge_buy_limit": "100", + "examine": "Good for stomping.", + "grand_exchange_price": "420", + "durability": null, + "name": "Ogre boots", + "tradeable": "true", + "weight": "3", + "archery_ticket_price": "0", + "id": "12565", + "equip_audio": "2237", + "equipment_slot": "10" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "420", + "durability": null, + "name": "Ogre boots", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12566" + }, + { + "ge_buy_limit": "100", + "examine": "It's a slightly sickly-looking fur.", + "grand_exchange_price": "1468", + "durability": null, + "name": "Diseased kebbit fur", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "12567" + }, + { + "remove_head": "true", + "ge_buy_limit": "100", + "examine": "A furry hat with an unnerving tail.", + "grand_exchange_price": "3656", + "durability": null, + "name": "Davy kebbit hat", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "12568", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3656", + "durability": null, + "name": "Davy kebbit hat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12569" + }, + { + "requirements": "{0,5}", + "ge_buy_limit": "100", + "turn90cw_anim": "8684", + "examine": "A big piece of tree.", + "walk_anim": "8684", + "durability": null, + "weight": "10", + "turn90ccw_anim": "8684", + "attack_speed": "7", + "weapon_interface": "10", + "turn180_anim": "8684", + "render_anim": "1157", + "defence_anim": "403", + "equipment_slot": "3", + "attack_anims": "401,401,401,401", + "grand_exchange_price": "77", + "stand_anim": "8683", + "name": "Ogre club", + "tradeable": "true", + "run_anim": "8685", + "archery_ticket_price": "0", + "id": "12570", + "stand_turn_anim": "823", + "bonuses": "-6,-2,15,0,0,0,0,0,0,0,0,12,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "77", + "durability": null, + "name": "Ogre club", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12571" + }, + { + "ge_buy_limit": "100", + "examine": "A delicate, sweet-smelling flower.", + "grand_exchange_price": "20", + "durability": null, + "name": "Lavender", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12572" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "20", + "durability": null, + "name": "Lavender", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12573" + }, + { + "ge_buy_limit": "100", + "examine": "A stiff, pungent grass.", + "grand_exchange_price": "31", + "durability": null, + "name": "Fever grass", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12574" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "31", + "durability": null, + "name": "Fever grass", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12575" + }, + { + "ge_buy_limit": "100", + "examine": "A cheerful, aromatic flower.", + "grand_exchange_price": "12", + "durability": null, + "name": "Tansymum", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12576" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "12", + "durability": null, + "name": "Tansymum", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12577" + }, + { + "turn90cw_anim": "8681", + "examine": "A stiff, pungent grass.", + "walk_anim": "8681", + "durability": null, + "turn90ccw_anim": "8681", + "turn180_anim": "8681", + "render_anim": "294", + "equipment_slot": "3", + "grand_exchange_price": "41", + "stand_anim": "8682", + "name": "Smouldering fever grass", + "tradeable": "true", + "run_anim": "8690", + "archery_ticket_price": "0", + "id": "12578", + "stand_turn_anim": "8682" + }, + { + "turn90cw_anim": "8681", + "examine": "A delicate, sweet-smelling flower.", + "walk_anim": "8681", + "durability": null, + "turn90ccw_anim": "8681", + "turn180_anim": "8681", + "render_anim": "294", + "equipment_slot": "3", + "grand_exchange_price": "29", + "stand_anim": "8682", + "name": "Smouldering lavender", + "tradeable": "true", + "run_anim": "8690", + "archery_ticket_price": "0", + "id": "12579", + "stand_turn_anim": "8682" + }, + { + "turn90cw_anim": "8681", + "examine": "A cheerful, aromatic flower.", + "walk_anim": "8681", + "durability": null, + "turn90ccw_anim": "8681", + "turn180_anim": "8681", + "render_anim": "294", + "equipment_slot": "3", + "grand_exchange_price": "18", + "stand_anim": "8682", + "name": "Smouldering tansymum", + "tradeable": "true", + "run_anim": "8690", + "archery_ticket_price": "0", + "id": "12580", + "stand_turn_anim": "8682" + }, + { + "ge_buy_limit": "25000", + "examine": "Logs cut from a eucalyptus tree.", + "grand_exchange_price": "507", + "durability": null, + "name": "Eucalyptus logs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12581", + "equipment_slot": "5" + }, + { + "ge_buy_limit": "25000", + "grand_exchange_price": "507", + "durability": null, + "name": "Eucalyptus logs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12582" + }, + { + "ge_buy_limit": "1000", + "examine": "Logs cut from a eucalyptus tree.", + "grand_exchange_price": "3609", + "durability": null, + "name": "Eucalyptus pyre logs", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "12583" + }, + { + "ge_buy_limit": "1000", + "grand_exchange_price": "3609", + "durability": null, + "name": "Eucalyptus pyre logs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12584" + }, + { + "ge_buy_limit": "100", + "examine": "A modest and mild plant.", + "grand_exchange_price": "20", + "durability": null, + "name": "Primweed", + "tradeable": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "12588" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "20", + "durability": null, + "name": "Primweed", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12589" + }, + { + "ge_buy_limit": "100", + "examine": "A pretty but putrid flower.", + "grand_exchange_price": "16", + "durability": null, + "name": "Stinkbloom", + "tradeable": "true", + "weight": "0.01", + "archery_ticket_price": "0", + "id": "12590" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "16", + "durability": null, + "name": "Stinkbloom", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12591" + }, + { + "durability": null, + "name": "Diseased kebbit fur", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12592" + }, + { + "destroy_message": "If you need to, you can get another from the Tyras Camp catapult engineer.", + "examine": "The plans for repairing the Tyras Camp catapult.", + "durability": null, + "name": "Catapult schematics", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "12593" + }, + { + "destroy_message": "If you need to, you can get another from General Hining in the Tyras Camp.", + "examine": "General Hining wants me to deliver this to the Catapult Engineer.", + "durability": null, + "name": "Engineer's letter", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "12594" + }, + { + "destroy_message": "You can always get another from the drunken sailor in Port Sarim.", + "examine": "Taken from a drunken sailor in Port Sarim.", + "durability": null, + "name": "Sailor's hat", + "tradeable": "false", + "destroy": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "12595", + "equipment_slot": "0" + }, + { + "destroy_message": "You can get another set from Thaki the delivery dwarf in Port Sarim.", + "examine": "Dwarf-made parts for repairing the Tyras Camp catapult.", + "durability": null, + "name": "Metal catapult parts", + "tradeable": "false", + "destroy": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "12596" + }, + { + "destroy_message": "If you need to, you can make another from the Tyras Camp catapult engineer's schematics.", + "examine": "Used to repair the Tyras Camp catapult.", + "durability": null, + "name": "Mahogany catapult part", + "tradeable": "false", + "destroy": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "12597" + }, + { + "destroy_message": "If you need to, you can make another from the Tyras Camp catapult engineer's schematics.", + "examine": "Used to repair the Tyras Camp catapult.", + "durability": null, + "name": "Mahogany catapult part", + "tradeable": "false", + "destroy": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "12598" + }, + { + "destroy_message": "If you need to, you can make another from the Tyras Camp catapult engineer's schematics.", + "examine": "Used to repair the Tyras Camp catapult.", + "durability": null, + "name": "Mahogany catapult part", + "tradeable": "false", + "destroy": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "12599" + }, + { + "destroy_message": "If you need to, you can make another from the Tyras Camp catapult engineer's schematics.", + "examine": "Used to repair the Tyras Camp catapult.", + "durability": null, + "name": "Mahogany catapult part", + "tradeable": "false", + "destroy": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "12600" + }, + { + "destroy_message": "If you need to, you can make another from the Tyras Camp catapult engineer's schematics.", + "examine": "Used to repair the Tyras Camp catapult.", + "durability": null, + "name": "Mahogany catapult part", + "tradeable": "false", + "destroy": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "12601" + }, + { + "destroy_message": "If you need to, you can make another from the Tyras Camp catapult engineer's schematics.", + "examine": "Used to repair the Tyras Camp catapult.", + "durability": null, + "name": "Mahogany catapult part", + "tradeable": "false", + "destroy": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "12602" + }, + { + "destroy_message": "If you need to, you can make another from the Tyras Camp catapult engineer's schematics.", + "examine": "Used to repair the Tyras Camp catapult.", + "durability": null, + "name": "Mahogany catapult part", + "tradeable": "false", + "destroy": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "12603" + }, + { + "destroy_message": "If you need to, you can make another from the Tyras Camp catapult engineer's schematics.", + "examine": "Used to repair the Tyras Camp catapult.", + "durability": null, + "name": "Mahogany catapult part", + "tradeable": "false", + "destroy": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "12604" + }, + { + "destroy_message": "If you need to, you can make another from the Tyras Camp catapult engineer's schematics.", + "examine": "Used to repair the Tyras Camp catapult.", + "durability": null, + "name": "Mahogany catapult part", + "tradeable": "false", + "destroy": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "12605" + }, + { + "destroy_message": "If you need to, you can make another from the Tyras Camp catapult engineer's schematics.", + "examine": "Used to repair the Tyras Camp catapult.", + "durability": null, + "name": "Mahogany catapult part", + "tradeable": "false", + "destroy": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "12606" + }, + { + "examine": "Used to repair the Tyras Camp catapult.", + "durability": null, + "name": "Picture", + "tradeable": "false", + "destroy": "true", + "weight": "2", + "archery_ticket_price": "0", + "id": "12607", + "equipment_slot": "5" + }, + { + "shop_price": "200", + "ge_buy_limit": "100", + "examine": "An amulet of Farming with 1 charge.", + "grand_exchange_price": "271", + "durability": null, + "name": "Amulet of farming(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12608", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "271", + "durability": null, + "name": "Amulet of farming(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12609" + }, + { + "shop_price": "200", + "examine": "An amulet of Farming with 2 charges.", + "grand_exchange_price": "8", + "durability": null, + "name": "Amulet of farming(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12610", + "equipment_slot": "2" + }, + { + "durability": null, + "name": "Amulet of farming(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12611" + }, + { + "shop_price": "200", + "examine": "An amulet of Farming with 3 charges.", + "grand_exchange_price": "8", + "durability": null, + "name": "Amulet of farming(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12612", + "equipment_slot": "2" + }, + { + "durability": null, + "name": "Amulet of farming(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12613" + }, + { + "shop_price": "200", + "examine": "An amulet of Farming with 4 charges.", + "grand_exchange_price": "8", + "durability": null, + "name": "Amulet of farming(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12614", + "equipment_slot": "2" + }, + { + "durability": null, + "name": "Amulet of farming(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12615" + }, + { + "shop_price": "200", + "examine": "An amulet of Farming with 5 charges.", + "grand_exchange_price": "8", + "durability": null, + "name": "Amulet of farming(5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12616", + "equipment_slot": "2" + }, + { + "durability": null, + "name": "Amulet of farming(5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12617" + }, + { + "shop_price": "200", + "examine": "An amulet of Farming with 6 charges.", + "grand_exchange_price": "8", + "durability": null, + "name": "Amulet of farming(6)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12618", + "equipment_slot": "2" + }, + { + "durability": null, + "name": "Amulet of farming(6)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12619" + }, + { + "shop_price": "200", + "examine": "An amulet of Farming with 7 charges.", + "grand_exchange_price": "8", + "durability": null, + "name": "Amulet of farming(7)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12620", + "equipment_slot": "2" + }, + { + "durability": null, + "name": "Amulet of farming(7)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12621" + }, + { + "shop_price": "200", + "ge_buy_limit": "100", + "examine": "An amulet of Farming with 8 charges.", + "grand_exchange_price": "210", + "durability": null, + "name": "Amulet of farming(8)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12622", + "equipment_slot": "2" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "210", + "durability": null, + "name": "Amulet of farming(8)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12623" + }, + { + "shop_price": "10", + "examine": "An ogleroot. How odd.", + "durability": null, + "name": "Ogleroot", + "tradeable": "true", + "archery_ticket_price": "0", + "weight": "0", + "id": "12624" + }, + { + "destroy_message": "You will need to obtain more flags from Mrs. Winkin or Farmer Blinkin if you have lost all of the flags you have.", + "shop_price": "500", + "examine": "A flag to put in the ground.", + "durability": null, + "name": "Flag", + "tradeable": "false", + "destroy": "true", + "weight": "0", + "archery_ticket_price": "0", + "id": "12625" + }, + { + "destroy_message": "You will need to get another exam paper from Professor Henry", + "examine": "Player Safety test", + "durability": null, + "name": "Test paper", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "12626" + }, + { + "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", + "examine": "I wonder what happens if I rub it.", + "durability": null, + "name": "Antique lamp", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "12627" + }, + { + "destroy_message": "Are you sure you want to destroy the lamp? You won't be able to get another one.", + "examine": "I wonder what happens if I rub it.", + "durability": null, + "name": "Antique lamp", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "12628" + }, + { + "destroy_message": "You can get another pair of gloves from the chest in the Stronghold of Player Safety.", + "examine": "Gloves from the Stronghold of Player Safety.", + "durability": null, + "name": "Safety gloves", + "tradeable": "false", + "destroy": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "12629", + "bonuses": "0,0,0,0,0,1,2,2,1,2,1,0,0,0,0", + "equipment_slot": "9" + }, + { + "destroy_message": "Rubium is very unstable", + "shop_price": "10", + "examine": "Be careful with this near water.", + "durability": null, + "name": "Rubium", + "weight": "1", + "archery_ticket_price": "0", + "id": "12630" + }, + { + "destroy_message": "The train is tiny", + "examine": "(While on the ground) Kennith's lost toy. (While in your inventory) A wooden toy train.", + "durability": null, + "name": "Toy train", + "archery_ticket_price": "0", + "id": "12631" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "shop_price": "160", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Note", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12632" + }, + { + "examine": "The jar is shaking violently!", + "durability": null, + "name": "Super fishing explosive", + "archery_ticket_price": "0", + "id": "12633" + }, + { + "destroy_message": "You can get another chocatrice cape from Diango in Draynor Village.", + "examine": "A thick, orange cape.", + "durability": null, + "name": "Chocatrice cape", + "tradeable": "false", + "destroy": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "12634", + "equip_audio": "2238", + "equipment_slot": "1" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Happy Easter.", + "grand_exchange_price": "64747137", + "durability": null, + "name": "Easter egg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12635" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Happy Easter.", + "grand_exchange_price": "64747137", + "durability": null, + "name": "Easter egg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12636" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Happy Easter.", + "grand_exchange_price": "64747137", + "durability": null, + "name": "Easter egg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12637" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Happy Easter.", + "grand_exchange_price": "64747137", + "durability": null, + "name": "Easter egg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12638" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Happy Easter.", + "grand_exchange_price": "64747137", + "durability": null, + "name": "Easter egg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12639" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Happy Easter.", + "grand_exchange_price": "64747137", + "durability": null, + "name": "Easter egg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12640" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Happy Easter.", + "grand_exchange_price": "64747137", + "durability": null, + "name": "Easter egg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12641" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Happy Easter.", + "grand_exchange_price": "64747137", + "durability": null, + "name": "Easter egg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12642" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Happy Easter.", + "grand_exchange_price": "64747137", + "durability": null, + "name": "Easter egg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12643" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Happy Easter.", + "grand_exchange_price": "64747137", + "durability": null, + "name": "Easter egg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12644" + }, + { + "destroy_message": "You can get another chocatrice cape from Diango in Draynor Village.", + "examine": "A thick, orange cape.", + "durability": null, + "name": "Chocatrice cape", + "tradeable": "false", + "destroy": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "12645", + "equip_audio": "2238", + "equipment_slot": "1" + }, + { + "examine": "A chocolate egg wrapped in coloured foil.", + "durability": null, + "name": "Chocolate egg", + "archery_ticket_price": "0", + "id": "12646" + }, + { + "examine": "A chocolate egg wrapped in coloured foil.", + "durability": null, + "name": "Chocolate egg", + "archery_ticket_price": "0", + "id": "12647" + }, + { + "examine": "A chocolate egg wrapped in coloured foil.", + "durability": null, + "name": "Chocolate egg", + "archery_ticket_price": "0", + "id": "12648" + }, + { + "shop_price": "2", + "examine": "It's an empty bucket.", + "grand_exchange_price": "50", + "durability": null, + "name": "Bucket", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "12649" + }, + { + "examine": "Common bucket: It's a bucket of water.2008 Easter event: It's a bucket of water from the Easter Bunny's warren. Regular bucket filled from Braindeath Island: It's a bucket of... water?", + "grand_exchange_price": "74", + "durability": null, + "name": "Bucket of water", + "tradeable": "true", + "weight": "3", + "archery_ticket_price": "0", + "id": "12650" + }, + { + "examine": "It's a bucket of water.", + "grand_exchange_price": "74", + "durability": null, + "name": "Bucket of water", + "tradeable": "true", + "weight": "3", + "archery_ticket_price": "0", + "id": "12651" + }, + { + "examine": "It's a bucket of coal from the Easter Bunny's warren.", + "durability": null, + "name": "Bucket of coal", + "weight": "3", + "archery_ticket_price": "0", + "id": "12652" + }, + { + "examine": "It's a bucket of coal from the Easter Bunny's warren.", + "durability": null, + "name": "Bucket of coal", + "weight": "3", + "archery_ticket_price": "0", + "id": "12653" + }, + { + "destroy_message": "Are you sure you want to destroy this object?
You can get another in the Easter Bunny's warren.", + "examine": "A stripy brown egg.", + "grand_exchange_price": "1255", + "durability": null, + "name": "Cockatrice egg", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12654" + }, + { + "destroy_message": "Are you sure you want to destroy this object?
You can make another at the Easter Bunny's warren.", + "examine": "A cockatrice egg that has been dipped in molten chocolate.", + "durability": null, + "name": "Chocatrice egg", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "12655", + "equipment_slot": "3" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Some chocolate chunks.", + "durability": null, + "name": "Chocolate chunks", + "archery_ticket_price": "0", + "id": "12657" + }, + { + "remove_head": "true", + "shop_price": "3520", + "examine": "A full face helmet.", + "durability": null, + "weight": "2.7", + "absorb": "1,0,2", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "1913", + "name": "Adamant full helm (e)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12658", + "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,6,0,0,0,0" + }, + { + "remove_head": "true", + "shop_price": "3520", + "examine": "A full face helmet.", + "durability": null, + "weight": "2.7", + "absorb": "1,0,2", + "remove_beard": "true", + "equipment_slot": "0", + "grand_exchange_price": "1913", + "name": "Adamant full helm (charged)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12659", + "bonuses": "0,0,0,-6,-2,19,21,16,-1,19,6,0,0,0,0" + }, + { + "remove_head": "true", + "examine": "Lightweight head protection.", + "grand_exchange_price": "1040", + "durability": null, + "name": "Snakeskin bandana (e)", + "tradeable": "false", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "12660", + "absorb": "0,2,1", + "bonuses": "0,0,0,-5,4,2,4,4,2,2,6,0,0,0,0", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "examine": "Lightweight head protection.", + "grand_exchange_price": "1040", + "durability": null, + "name": "Snakeskin bandana (charged)", + "tradeable": "false", + "weight": "0.9", + "archery_ticket_price": "0", + "id": "12661", + "absorb": "0,2,1", + "bonuses": "0,0,0,-5,4,2,4,4,2,2,6,0,0,0,0", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "examine": "A wooden helmet.", + "durability": null, + "weight": "0.9", + "absorb": "3,1,0", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "5623", + "name": "Splitbark helm (e)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12662", + "bonuses": "0,0,0,3,-2,10,9,11,3,0,7,0,0,0,0" + }, + { + "remove_head": "true", + "examine": "A wooden helmet.", + "durability": null, + "weight": "0.9", + "absorb": "3,1,0", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "5623", + "name": "Splitbark helm (charged)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12663", + "bonuses": "0,0,0,3,-2,10,9,11,3,0,7,0,0,0,0" + }, + { + "remove_head": "true", + "examine": "A full face helmet.", + "durability": null, + "weight": "2.7", + "absorb": "1,0,3", + "remove_beard": "true", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "21200", + "name": "Rune full helm (e)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12664", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0" + }, + { + "remove_head": "true", + "examine": "A full face helmet.", + "durability": null, + "weight": "2.7", + "absorb": "1,0,3", + "remove_beard": "true", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "21200", + "name": "Rune full helm (charged)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12665", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0" + }, + { + "remove_head": "true", + "examine": "Makes the wearer pretty intimidating.", + "durability": null, + "weight": "1.3", + "absorb": "2,0,4", + "equip_audio": "2240", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "61200", + "name": "Dragon med helm (e)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12666", + "bonuses": "0,0,0,-3,-1,33,35,32,-1,34,10,0,0,0,0" + }, + { + "remove_head": "true", + "examine": "Makes the wearer pretty intimidating.", + "durability": null, + "weight": "1.3", + "absorb": "2,0,4", + "equip_audio": "2240", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "61200", + "name": "Dragon med helm (charged)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12667", + "bonuses": "0,0,0,-3,-1,33,35,32,-1,34,10,0,0,0,0" + }, + { + "remove_head": "true", + "shop_price": "15000", + "examine": "A mystical helmet.", + "durability": null, + "destroy": "true", + "weight": "0.9", + "absorb": "3,1,0", + "remove_beard": "true", + "equipment_slot": "0", + "destroy_message": "The Oneiromancer might be able to help you get another.", + "name": "Lunar helm (e)", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12668", + "bonuses": "0,0,0,3,-2,8,7,10,2,0,7,0,0,0,0" + }, + { + "remove_head": "true", + "shop_price": "15000", + "examine": "A mystical helmet.", + "durability": null, + "destroy": "true", + "weight": "0.9", + "absorb": "3,1,0", + "remove_beard": "true", + "equipment_slot": "0", + "destroy_message": "The Oneiromancer might be able to help you get another.", + "name": "Lunar helm (charged)", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12669", + "bonuses": "0,0,0,3,-2,8,7,10,2,0,7,0,0,0,0" + }, + { + "remove_head": "true", + "examine": "A helmet of great craftmanship.", + "durability": null, + "weight": "0.5", + "absorb": "0,5,2", + "equip_audio": "2240", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "3932989", + "name": "Armadyl helmet (e)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12670", + "bonuses": "-5,-5,-5,-5,10,6,8,10,10,8,12,0,1,0,0" + }, + { + "remove_head": "true", + "examine": "A helmet of great craftmanship.", + "durability": null, + "weight": "0.5", + "absorb": "0,5,2", + "equip_audio": "2240", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "3932989", + "name": "Armadyl helmet (charged)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12671", + "bonuses": "-5,-5,-5,-5,10,6,8,10,10,8,12,0,1,0,0" + }, + { + "remove_head": "true", + "shop_price": "78000", + "examine": "This helmet is worn by archers.", + "durability": null, + "weight": "2", + "absorb": "0,3,1", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "41000", + "name": "Archer helm (e)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12672", + "bonuses": "-5,-5,-5,-5,6,6,8,10,6,6,0,0,0,0,0" + }, + { + "remove_head": "true", + "shop_price": "78000", + "examine": "This helmet is worn by archers.", + "durability": null, + "weight": "2", + "absorb": "0,3,1", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "41000", + "name": "Archer helm (charged)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12673", + "bonuses": "-5,-5,-5,-5,6,6,8,10,6,6,0,0,0,0,0" + }, + { + "remove_head": "true", + "shop_price": "78000", + "examine": "This helmet is worn by berserkers.", + "durability": null, + "weight": "2.7", + "absorb": "1,0,3", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "48800", + "name": "Berserker helm (e)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12674", + "bonuses": "0,0,0,-5,-5,31,29,33,0,30,7,3,0,0,0" + }, + { + "remove_head": "true", + "shop_price": "78000", + "examine": "This helmet is worn by berserkers.", + "durability": null, + "weight": "2.7", + "absorb": "1,0,3", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "48800", + "name": "Berserker helm (charged)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12675", + "bonuses": "0,0,0,-5,-5,31,29,33,0,30,7,3,0,0,0" + }, + { + "remove_head": "true", + "shop_price": "78000", + "examine": "This helm is worn by warriors.", + "durability": null, + "weight": "2.7", + "absorb": "1,0,3", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "48200", + "name": "Warrior helm (e)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12676", + "bonuses": "0,5,0,-5,-5,31,33,29,0,30,7,0,0,0,0" + }, + { + "remove_head": "true", + "shop_price": "78000", + "examine": "This helm is worn by warriors.", + "durability": null, + "weight": "2.7", + "absorb": "1,0,3", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "48200", + "name": "Warrior helm (charged)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12677", + "bonuses": "0,5,0,-5,-5,31,33,29,0,30,7,0,0,0,0" + }, + { + "remove_head": "true", + "shop_price": "78000", + "examine": "This helm is worn by farseers.", + "durability": null, + "weight": "2.7", + "absorb": "3,1,0", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "46400", + "name": "Farseer helm (e)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12678", + "bonuses": "-5,-5,-5,6,-5,8,10,12,6,0,7,0,0,0,0" + }, + { + "remove_head": "true", + "shop_price": "78000", + "examine": "This helm is worn by farseers.", + "durability": null, + "weight": "2.7", + "absorb": "3,1,0", + "equipment_slot": "0", + "lendable": "true", + "grand_exchange_price": "46400", + "name": "Farseer helm (charged)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12679", + "bonuses": "-5,-5,-5,6,-5,8,10,12,6,0,7,0,0,0,0" + }, + { + "remove_head": "true", + "shop_price": "50000", + "examine": "A gift from Neitiznot's Burgher.", + "durability": null, + "weight": "2.2", + "absorb": "2,0,4", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "44831", + "name": "Helm of neitiznot (e)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12680", + "bonuses": "0,0,0,0,0,31,29,34,3,30,8,3,3,0,0" + }, + { + "remove_head": "true", + "shop_price": "50000", + "examine": "A gift from Neitiznot's Burgher.", + "durability": null, + "weight": "2.2", + "absorb": "2,0,4", + "equip_audio": "2240", + "equipment_slot": "0", + "grand_exchange_price": "44831", + "name": "Helm of neitiznot (charged)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12681", + "bonuses": "0,0,0,0,0,31,29,34,3,30,8,3,3,0,0" + }, + { + "examine": "(Baby) It's a tiny, cheeky monkey. (Adult) Hide the bananas!", + "durability": null, + "name": "Baby monkey", + "archery_ticket_price": "0", + "id": "12682" + }, + { + "examine": "(Baby) It's a tiny, cheeky monkey. (Adult) Hide the bananas!", + "durability": null, + "name": "Baby monkey", + "archery_ticket_price": "0", + "id": "12684" + }, + { + "examine": "(Baby) It's a tiny, cheeky monkey. (Adult) Hide the bananas!", + "durability": null, + "name": "Baby monkey", + "archery_ticket_price": "0", + "id": "12686" + }, + { + "examine": "(Baby) It's a tiny, cheeky monkey. (Adult) Hide the bananas!", + "durability": null, + "name": "Baby monkey", + "archery_ticket_price": "0", + "id": "12688" + }, + { + "examine": "(Baby) It's a tiny, cheeky monkey. (Adult) Hide the bananas!", + "durability": null, + "name": "Baby monkey", + "archery_ticket_price": "0", + "id": "12690" + }, + { + "examine": "(Baby) It's a tiny, cheeky monkey. (Adult) Hide the bananas!", + "durability": null, + "name": "Baby monkey", + "archery_ticket_price": "0", + "id": "12692" + }, + { + "examine": "(Baby) It's a tiny, cheeky monkey. (Adult) Hide the bananas!", + "durability": null, + "name": "Baby monkey", + "archery_ticket_price": "0", + "id": "12694" + }, + { + "examine": "(Baby) It's a tiny, cheeky monkey. (Adult) Hide the bananas!", + "durability": null, + "name": "Baby monkey", + "archery_ticket_price": "0", + "id": "12696" + }, + { + "examine": "(Baby) It's a tiny, cheeky monkey. (Adult) Hide the bananas!", + "durability": null, + "name": "Baby monkey", + "archery_ticket_price": "0", + "id": "12698" + }, + { + "requirements": "{4,23}", + "examine": "A hyperactive little pup.", + "durability": null, + "name": "Terrier puppy", + "archery_ticket_price": "0", + "id": "12700" + }, + { + "requirements": "{4,23}", + "examine": "A hyperactive little pup.", + "durability": null, + "name": "Terrier", + "archery_ticket_price": "0", + "id": "12701" + }, + { + "requirements": "{4,23}", + "examine": "Such a brave doggy.", + "durability": null, + "name": "Terrier puppy", + "archery_ticket_price": "0", + "id": "12702" + }, + { + "requirements": "{4,23}", + "examine": "Such a brave doggy.", + "durability": null, + "name": "Terrier", + "archery_ticket_price": "0", + "id": "12703" + }, + { + "requirements": "{4,23}", + "examine": "This is one fast little pooch.", + "durability": null, + "name": "Greyhound puppy", + "archery_ticket_price": "0", + "id": "12704" + }, + { + "requirements": "{4,23}", + "examine": "An aerodynamic doggy.", + "durability": null, + "name": "Greyhound", + "archery_ticket_price": "0", + "id": "12705" + }, + { + "requirements": "{4,23}", + "examine": "This is one fast little pooch.", + "durability": null, + "name": "Greyhound puppy", + "archery_ticket_price": "0", + "id": "12706" + }, + { + "requirements": "{4,23}", + "examine": "An aerodynamic doggy.", + "durability": null, + "name": "Greyhound", + "archery_ticket_price": "0", + "id": "12707" + }, + { + "requirements": "{4,23}", + "examine": "Soft but strong... and cute.", + "durability": null, + "name": "Labrador puppy", + "archery_ticket_price": "0", + "id": "12708" + }, + { + "requirements": "{4,23}", + "examine": "My most faithful friend.", + "durability": null, + "name": "Labrador", + "archery_ticket_price": "0", + "id": "12709" + }, + { + "requirements": "{4,23}", + "examine": "Soft but strong... and cute.", + "durability": null, + "name": "Labrador puppy", + "archery_ticket_price": "0", + "id": "12710" + }, + { + "requirements": "{4,23}", + "examine": "My most faithful friend.", + "durability": null, + "name": "Labrador", + "archery_ticket_price": "0", + "id": "12711" + }, + { + "requirements": "{4,23}", + "examine": "Now, if only I could find another hundred...", + "durability": null, + "name": "Dalmatian puppy", + "archery_ticket_price": "0", + "id": "12712" + }, + { + "requirements": "{4,23}", + "examine": "A purebred doggy.", + "durability": null, + "name": "Dalmatian", + "archery_ticket_price": "0", + "id": "12713" + }, + { + "requirements": "{4,23}", + "examine": "Now, if only I could find another hundred...", + "durability": null, + "name": "Dalmatian puppy", + "archery_ticket_price": "0", + "id": "12714" + }, + { + "requirements": "{4,23}", + "examine": "A purebred doggy.", + "durability": null, + "name": "Dalmatian", + "archery_ticket_price": "0", + "id": "12715" + }, + { + "requirements": "{4,23}", + "examine": "This little puppy is very quiet.", + "durability": null, + "name": "Sheepdog puppy", + "archery_ticket_price": "0", + "id": "12716" + }, + { + "requirements": "{4,23}", + "examine": "Come by! Come by!", + "durability": null, + "name": "Sheepdog", + "archery_ticket_price": "0", + "id": "12717" + }, + { + "requirements": "{4,23}", + "examine": "This little puppy is very quiet.", + "durability": null, + "name": "Sheepdog puppy", + "archery_ticket_price": "0", + "id": "12718" + }, + { + "requirements": "{4,23}", + "examine": "Come by! Come by!", + "durability": null, + "name": "Sheepdog", + "archery_ticket_price": "0", + "id": "12719" + }, + { + "requirements": "{4,23}", + "examine": "One proud little puppy.", + "durability": null, + "name": "Bulldog puppy", + "archery_ticket_price": "0", + "id": "12720" + }, + { + "requirements": "{4,23}", + "examine": "Looks like it's chewing a wasp.", + "durability": null, + "name": "Bulldog", + "archery_ticket_price": "0", + "id": "12721" + }, + { + "requirements": "{4,23}", + "examine": "One proud little puppy.", + "durability": null, + "name": "Bulldog puppy", + "archery_ticket_price": "0", + "id": "12722" + }, + { + "requirements": "{4,23}", + "examine": "Looks like it's chewing a wasp.", + "durability": null, + "name": "Bulldog", + "archery_ticket_price": "0", + "id": "12723" + }, + { + "examine": "Chick: A raven chick.", + "durability": null, + "name": "Raven chick", + "archery_ticket_price": "0", + "id": "12724" + }, + { + "examine": "Chick: A raven chick.", + "durability": null, + "name": "Raven", + "archery_ticket_price": "0", + "id": "12725" + }, + { + "examine": "Chick: A raven chick.", + "durability": null, + "name": "Raven chick", + "archery_ticket_price": "0", + "id": "12726" + }, + { + "examine": "Chick: A raven chick.", + "durability": null, + "name": "Raven", + "archery_ticket_price": "0", + "id": "12727" + }, + { + "examine": "Chick: A raven chick.", + "durability": null, + "name": "Raven chick", + "archery_ticket_price": "0", + "id": "12728" + }, + { + "examine": "Chick: A raven chick.", + "durability": null, + "name": "Raven", + "archery_ticket_price": "0", + "id": "12729" + }, + { + "examine": "Chick: A raven chick.", + "durability": null, + "name": "Raven chick", + "archery_ticket_price": "0", + "id": "12730" + }, + { + "examine": "Chick: A raven chick.", + "durability": null, + "name": "Raven", + "archery_ticket_price": "0", + "id": "12731" + }, + { + "examine": "Chick: A raven chick.", + "durability": null, + "name": "Raven chick", + "archery_ticket_price": "0", + "id": "12732" + }, + { + "examine": "Chick: A raven chick.", + "durability": null, + "name": "Raven", + "archery_ticket_price": "0", + "id": "12733" + }, + { + "examine": "(Baby) A stripy little baby raccoon.(Adult) He can run with us.", + "durability": null, + "name": "Baby raccoon", + "archery_ticket_price": "0", + "id": "12734" + }, + { + "examine": "(Baby) A stripy little baby raccoon.(Adult) He can run with us.", + "durability": null, + "name": "Raccoon", + "archery_ticket_price": "0", + "id": "12735" + }, + { + "examine": "(Baby) A stripy little baby raccoon.(Adult) He can run with us.", + "durability": null, + "name": "Baby raccoon", + "archery_ticket_price": "0", + "id": "12736" + }, + { + "examine": "(Baby) A stripy little baby raccoon.(Adult) He can run with us.", + "durability": null, + "name": "Raccoon", + "archery_ticket_price": "0", + "id": "12737" + }, + { + "examine": "(Baby) It's so adorably tiny! (Adult) How cute!", + "durability": null, + "name": "Baby gecko", + "archery_ticket_price": "0", + "id": "12738" + }, + { + "examine": "(Baby) It's so adorably tiny! (Adult) How cute!", + "durability": null, + "name": "Baby gecko", + "archery_ticket_price": "0", + "id": "12739" + }, + { + "examine": "(Baby) It's so adorably tiny! (Adult) How cute!", + "durability": null, + "name": "Baby gecko", + "archery_ticket_price": "0", + "id": "12740" + }, + { + "examine": "(Baby) It's so adorably tiny! (Adult) How cute!", + "durability": null, + "name": "Baby gecko", + "archery_ticket_price": "0", + "id": "12741" + }, + { + "examine": "(Baby) It's so adorably tiny! (Adult) How cute!", + "durability": null, + "name": "Gecko", + "archery_ticket_price": "0", + "id": "12742" + }, + { + "examine": "(Baby) It's so adorably tiny! (Adult) How cute!", + "durability": null, + "name": "Gecko", + "archery_ticket_price": "0", + "id": "12743" + }, + { + "examine": "(Baby) It's so adorably tiny! (Adult) How cute!", + "durability": null, + "name": "Gecko", + "archery_ticket_price": "0", + "id": "12744" + }, + { + "examine": "(Baby) It's so adorably tiny! (Adult) How cute!", + "durability": null, + "name": "Gecko", + "archery_ticket_price": "0", + "id": "12745" + }, + { + "requirements": "{23,40}", + "examine": "Baby: Little NipperAdult: Bigger Nipper.", + "durability": null, + "name": "Baby giant crab", + "archery_ticket_price": "0", + "id": "12746" + }, + { + "requirements": "{23,40}", + "examine": "Baby: Little NipperAdult: Bigger Nipper.", + "durability": null, + "name": "Giant crab", + "archery_ticket_price": "0", + "id": "12747" + }, + { + "requirements": "{23,40}", + "examine": "Baby: Little NipperAdult: Bigger Nipper.", + "durability": null, + "name": "Baby giant crab", + "archery_ticket_price": "0", + "id": "12748" + }, + { + "requirements": "{23,40}", + "examine": "Baby: Little NipperAdult: Bigger Nipper.", + "durability": null, + "name": "Giant crab", + "archery_ticket_price": "0", + "id": "12749" + }, + { + "requirements": "{23,40}", + "examine": "Baby: Little NipperAdult: Bigger Nipper.", + "durability": null, + "name": "Baby giant crab", + "archery_ticket_price": "0", + "id": "12750" + }, + { + "requirements": "{23,40}", + "examine": "Baby: Little NipperAdult: Bigger Nipper.", + "durability": null, + "name": "Giant crab", + "archery_ticket_price": "0", + "id": "12751" + }, + { + "requirements": "{23,40}", + "examine": "Baby: Little NipperAdult: Bigger Nipper.", + "durability": null, + "name": "Baby giant crab", + "archery_ticket_price": "0", + "id": "12752" + }, + { + "requirements": "{23,40}", + "examine": "Baby: Little NipperAdult: Bigger Nipper.", + "durability": null, + "name": "Giant crab", + "archery_ticket_price": "0", + "id": "12753" + }, + { + "examine": "Adult: An experienced nut-thief.Baby: A tiny nut-thief.", + "durability": null, + "name": "Baby squirrel", + "archery_ticket_price": "0", + "id": "12754" + }, + { + "examine": "Adult: An experienced nut-thief.Baby: A tiny nut-thief.", + "durability": null, + "name": "Squirrel", + "archery_ticket_price": "0", + "id": "12755" + }, + { + "examine": "Adult: An experienced nut-thief.Baby: A tiny nut-thief.", + "durability": null, + "name": "Baby squirrel", + "archery_ticket_price": "0", + "id": "12756" + }, + { + "examine": "Adult: An experienced nut-thief.Baby: A tiny nut-thief.", + "durability": null, + "name": "Squirrel", + "archery_ticket_price": "0", + "id": "12757" + }, + { + "examine": "Adult: An experienced nut-thief.Baby: A tiny nut-thief.", + "durability": null, + "name": "Baby squirrel", + "archery_ticket_price": "0", + "id": "12758" + }, + { + "examine": "Adult: An experienced nut-thief.Baby: A tiny nut-thief.", + "durability": null, + "name": "Squirrel", + "archery_ticket_price": "0", + "id": "12759" + }, + { + "examine": "Adult: An experienced nut-thief.Baby: A tiny nut-thief.", + "durability": null, + "name": "Baby squirrel", + "archery_ticket_price": "0", + "id": "12760" + }, + { + "examine": "Adult: An experienced nut-thief.Baby: A tiny nut-thief.", + "durability": null, + "name": "Squirrel", + "archery_ticket_price": "0", + "id": "12761" + }, + { + "examine": "Can't fly and can barely walk, but adorable nonetheless.", + "durability": null, + "name": "Baby penguin", + "archery_ticket_price": "0", + "id": "12763" + }, + { + "examine": "Can't fly and can barely walk, but adorable nonetheless.", + "durability": null, + "name": "Baby penguin", + "archery_ticket_price": "0", + "id": "12765" + }, + { + "examine": "If you see them circling: run.", + "durability": null, + "name": "Vulture chick", + "archery_ticket_price": "0", + "id": "12766" + }, + { + "examine": "If you see them circling: run.", + "durability": null, + "name": "Vulture", + "archery_ticket_price": "0", + "id": "12767" + }, + { + "examine": "If you see them circling: run.", + "durability": null, + "name": "Vulture chick", + "archery_ticket_price": "0", + "id": "12768" + }, + { + "examine": "If you see them circling: run.", + "durability": null, + "name": "Vulture", + "archery_ticket_price": "0", + "id": "12769" + }, + { + "examine": "If you see them circling: run.", + "durability": null, + "name": "Vulture chick", + "archery_ticket_price": "0", + "id": "12770" + }, + { + "examine": "If you see them circling: run.", + "durability": null, + "name": "Vulture", + "archery_ticket_price": "0", + "id": "12771" + }, + { + "examine": "If you see them circling: run.", + "durability": null, + "name": "Vulture chick", + "archery_ticket_price": "0", + "id": "12772" + }, + { + "examine": "If you see them circling: run.", + "durability": null, + "name": "Vulture", + "archery_ticket_price": "0", + "id": "12773" + }, + { + "examine": "If you see them circling: run.", + "durability": null, + "name": "Vulture chick", + "archery_ticket_price": "0", + "id": "12774" + }, + { + "examine": "If you see them circling: run.", + "durability": null, + "name": "Vulture", + "archery_ticket_price": "0", + "id": "12775" + }, + { + "requirements": "{23,85}", + "ge_buy_limit": "5000", + "grand_exchange_price": "2613", + "examine": "I can summon a swamp titan familiar with this.", + "durability": null, + "name": "Swamp titan pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12776" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "2613", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Swamp titan pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12777" + }, + { + "requirements": "{17,23}", + "ge_buy_limit": "5000", + "grand_exchange_price": "130", + "examine": "I can summon a spirit mosquito familiar with this.", + "durability": null, + "name": "Spirit mosquito pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12778" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "130", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Spirit mosquito pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12779" + }, + { + "requirements": "{23,34}", + "ge_buy_limit": "5000", + "grand_exchange_price": "16100", + "examine": "I can summon a void spinner familiar with this.", + "durability": null, + "name": "Void spinner pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12780" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "16100", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Void spinner pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12781" + }, + { + "requirements": "{23,76}", + "ge_buy_limit": "5000", + "grand_exchange_price": "2458", + "examine": "I can summon a forge regent familiar with this.", + "durability": null, + "name": "Forge regent pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12782" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "2458", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Forge regent pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12783" + }, + { + "requirements": "{23,57}", + "ge_buy_limit": "5000", + "grand_exchange_price": "4097", + "examine": "I can summon a spirit larupia familiar with this.", + "durability": null, + "name": "Spirit larupia pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12784" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "4097", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Spirit larupia pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12785" + }, + { + "requirements": "{23,89}", + "ge_buy_limit": "5000", + "grand_exchange_price": "3856", + "examine": "I can summon a geyser titan familiar with this.", + "durability": null, + "name": "Geyser titan pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12786" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "3856", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Geyser titan pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12787" + }, + { + "requirements": "{23,83}", + "ge_buy_limit": "5000", + "grand_exchange_price": "3840", + "examine": "I can summon a lava titan familiar with this.", + "durability": null, + "name": "Lava titan pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12788" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "3840", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Lava titan pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12789" + }, + { + "requirements": "{23,99}", + "ge_buy_limit": "5000", + "grand_exchange_price": "5800", + "examine": "I can summon a steel titan familiar with this.", + "durability": null, + "name": "Steel titan pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12790" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "5800", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Steel titan pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12791" + }, + { + "requirements": "{23,73}", + "ge_buy_limit": "5000", + "grand_exchange_price": "3436", + "examine": "I can summon an obsidian golem familiar with this.", + "durability": null, + "name": "Obsidian golem pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12792" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "3436", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Obsidian golem pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12793" + }, + { + "requirements": "{23,77}", + "ge_buy_limit": "5000", + "grand_exchange_price": "3017", + "examine": "I can summon a talon beast familiar with this.", + "durability": null, + "name": "Talon beast pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12794" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "3017", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Talon beast pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12795" + }, + { + "requirements": "{23,93}", + "ge_buy_limit": "5000", + "grand_exchange_price": "2991", + "examine": "I can summon an abyssal titan familiar with this.", + "durability": null, + "name": "Abyssal titan pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12796" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "2991", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Abyssal titan pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12797" + }, + { + "requirements": "{23,34}", + "ge_buy_limit": "5000", + "grand_exchange_price": "18300", + "examine": "I can summon a void torcher familiar with this.", + "durability": null, + "name": "Void torcher pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12798" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "18300", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Void torcher pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12799" + }, + { + "requirements": "{23,29}", + "ge_buy_limit": "5000", + "grand_exchange_price": "1513", + "examine": "I can summon a giant chinchompa familiar with this.", + "durability": null, + "name": "Giant chinchompa pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12800" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "1513", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Giant chinchompa pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12801" + }, + { + "requirements": "{23,79}", + "ge_buy_limit": "5000", + "grand_exchange_price": "3567", + "examine": "I can summon a fire titan familiar with this.", + "durability": null, + "name": "Fire titan pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12802" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "3567", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Fire titan pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12803" + }, + { + "requirements": "{23,79}", + "ge_buy_limit": "5000", + "grand_exchange_price": "3548", + "examine": "I can summon a moss titan familiar with this.", + "durability": null, + "name": "Moss titan pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12804" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "3548", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Moss titan pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12805" + }, + { + "requirements": "{23,79}", + "ge_buy_limit": "5000", + "grand_exchange_price": "7184", + "examine": "I can summon an ice titan familiar with this.", + "durability": null, + "name": "Ice titan pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12806" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "7184", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Ice titan pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12807" + }, + { + "requirements": "{22,23}", + "ge_buy_limit": "5000", + "grand_exchange_price": "1116", + "examine": "I can summon a spirit Tz-Kih familiar with this.", + "durability": null, + "name": "Spirit tz-kih pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12808" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "1116", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Spirit tz-kih pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12809" + }, + { + "requirements": "{23,57}", + "ge_buy_limit": "5000", + "grand_exchange_price": "7919", + "examine": "I can summon a spirit graahk familiar with this.", + "durability": null, + "name": "Spirit graahk pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12810" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "7919", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Spirit graahk pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12811" + }, + { + "requirements": "{23,57}", + "ge_buy_limit": "5000", + "grand_exchange_price": "13300", + "examine": "I can summon a spirit kyatt familiar with this.", + "durability": null, + "name": "Spirit kyatt pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12812" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "13300", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Spirit kyatt pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12813" + }, + { + "requirements": "{23,34}", + "ge_buy_limit": "5000", + "grand_exchange_price": "18600", + "examine": "I can summon a void shifter familiar with this.", + "durability": null, + "name": "Void shifter pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12814" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "18600", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Void shifter pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12815" + }, + { + "requirements": "{23,46}", + "ge_buy_limit": "5000", + "grand_exchange_price": "1951", + "examine": "I can summon a pyrelord familiar with this.", + "durability": null, + "name": "Pyrelord pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12816" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "1951", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Pyrelord pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12817" + }, + { + "requirements": "{23,34}", + "ge_buy_limit": "5000", + "grand_exchange_price": "10700", + "examine": "I can summon a void ravager familiar with this.", + "durability": null, + "name": "Void ravager pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12818" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "10700", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Void ravager pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12819" + }, + { + "requirements": "{23,70}", + "ge_buy_limit": "5000", + "grand_exchange_price": "1382", + "examine": "I can summon a ravenous locust familiar with this.", + "durability": null, + "name": "Ravenous locust pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12820" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "1382", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Ravenous locust pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12821" + }, + { + "requirements": "{23,95}", + "ge_buy_limit": "5000", + "grand_exchange_price": "3470", + "examine": "I can summon an iron titan familiar with this.", + "durability": null, + "name": "Iron titan pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12822" + }, + { + "ge_buy_limit": "5000", + "grand_exchange_price": "3470", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Iron titan pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12823" + }, + { + "requirements": "{23,79}", + "ge_buy_limit": "5000", + "grand_exchange_price": "380", + "examine": "A scroll for an elemental titan familiar.", + "durability": null, + "name": "Titan's con. scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12824" + }, + { + "requirements": "{23,99}", + "ge_buy_limit": "5000", + "grand_exchange_price": "646", + "examine": "A scroll for a steel titan familiar.", + "durability": null, + "name": "Steel of legends scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12825" + }, + { + "requirements": "{23,73}", + "ge_buy_limit": "5000", + "grand_exchange_price": "271", + "examine": "A scroll for an obsidian golem familiar.", + "durability": null, + "name": "Volcanic str. scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12826" + }, + { + "requirements": "{23,93}", + "ge_buy_limit": "5000", + "grand_exchange_price": "310", + "examine": "A scroll for an abyssal titan familiar.", + "durability": null, + "name": "Essence shipment scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12827" + }, + { + "requirements": "{23,95}", + "ge_buy_limit": "5000", + "grand_exchange_price": "389", + "examine": "A scroll for an iron titan familiar.", + "durability": null, + "name": "Iron within scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12828" + }, + { + "requirements": "{23,46}", + "ge_buy_limit": "5000", + "grand_exchange_price": "146", + "examine": "A scroll for a pyrelord familiar.", + "durability": null, + "name": "Immense heat scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12829" + }, + { + "requirements": "{23,70}", + "ge_buy_limit": "5000", + "grand_exchange_price": "149", + "examine": "A scroll for a ravenous locust familiar.", + "durability": null, + "name": "Famine scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12830" + }, + { + "requirements": "{23,77}", + "ge_buy_limit": "5000", + "grand_exchange_price": "245", + "examine": "A scroll for a talon beast familiar.", + "durability": null, + "name": "Deadly claw scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12831" + }, + { + "requirements": "{23,85}", + "ge_buy_limit": "5000", + "grand_exchange_price": "192", + "examine": "A scroll for a swamp titan familiar.", + "durability": null, + "name": "Swamp plague scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12832" + }, + { + "requirements": "{23,89}", + "ge_buy_limit": "5000", + "grand_exchange_price": "294", + "examine": "A scroll for a geyser titan familiar.", + "durability": null, + "name": "Boil scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12833" + }, + { + "requirements": "{23,29}", + "ge_buy_limit": "5000", + "grand_exchange_price": "103", + "examine": "A scroll for a giant chinchompa familiar.", + "durability": null, + "name": "Explode scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12834" + }, + { + "requirements": "{23,57}", + "ge_buy_limit": "5000", + "grand_exchange_price": "250", + "examine": "A scroll for a spirit graahk familiar.", + "durability": null, + "name": "Goad scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12835" + }, + { + "requirements": "{23,57}", + "ge_buy_limit": "5000", + "grand_exchange_price": "1428", + "examine": "A scroll for a spirit kyatt familiar.", + "durability": null, + "name": "Ambush scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12836" + }, + { + "requirements": "{23,83}", + "ge_buy_limit": "5000", + "grand_exchange_price": "300", + "examine": "A scroll for a lava titan familiar.", + "durability": null, + "name": "Ebon thunder scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12837" + }, + { + "requirements": "{23,17}", + "ge_buy_limit": "5000", + "grand_exchange_price": "1", + "examine": "A scroll for a spirit mosquito familiar.", + "durability": null, + "name": "Pester scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12838" + }, + { + "requirements": "{23,22}", + "ge_buy_limit": "5000", + "grand_exchange_price": "78", + "examine": "A scroll for a spirit Tz-Kih familiar.", + "durability": null, + "name": "Fireball assault scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12839" + }, + { + "requirements": "{23,57}", + "ge_buy_limit": "5000", + "grand_exchange_price": "196", + "examine": "A scroll for a spirit larupia familiar.", + "durability": null, + "name": "Rending scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12840" + }, + { + "requirements": "{23,76}", + "ge_buy_limit": "5000", + "grand_exchange_price": "173", + "examine": "A scroll for a forge regent familiar.", + "durability": null, + "name": "Inferno scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12841" + }, + { + "turn90cw_anim": "8963", + "stand_anim": "8964", + "walk_anim": "8961", + "durability": null, + "name": "Gnomecopter", + "run_anim": "8963", + "archery_ticket_price": "0", + "turn90ccw_anim": "8963", + "id": "12842", + "stand_turn_anim": "8963", + "turn180_anim": "8963", + "equipment_slot": "1" + }, + { + "destroy_message": "This is for use with the gnomecopters, north of Lumbridge. Sasquine Huburns will give you another one.", + "examine": "It tells gnomecopters where you wish to go.", + "durability": null, + "name": "Gnomecopter ticket", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "12843" + }, + { + "shop_price": "100", + "turn90cw_anim": "8983", + "examine": "A kite with a dragon on it.", + "walk_anim": "8982", + "durability": null, + "turn90ccw_anim": "8984", + "attack_speed": "4", + "turn180_anim": "8985", + "render_anim": "593", + "equipment_slot": "3", + "stand_anim": "8981", + "name": "Toy kite", + "run_anim": "8986", + "archery_ticket_price": "0", + "id": "12844", + "stand_turn_anim": "8987" + }, + { + "turn90cw_anim": "9002", + "examine": "A stone used to gather energy.", + "walk_anim": "8997", + "durability": null, + "destroy": "true", + "weight": "30", + "turn90ccw_anim": "9003", + "turn180_anim": "9001", + "render_anim": "370", + "equipment_slot": "3", + "destroy_message": "You can reclaim this item from the place you found it.", + "stand_anim": "8998", + "name": "Stone of power", + "tradeable": "false", + "run_anim": "9004", + "archery_ticket_price": "0", + "id": "12845", + "stand_turn_anim": "9000" + }, + { + "turn90cw_anim": "9002", + "examine": "A stone used to gather energy.", + "walk_anim": "8997", + "durability": null, + "destroy": "true", + "weight": "30", + "turn90ccw_anim": "9003", + "turn180_anim": "9001", + "render_anim": "370", + "equipment_slot": "3", + "destroy_message": "You can reclaim this item from the place you found it.", + "stand_anim": "8998", + "name": "Stone of power", + "tradeable": "false", + "run_anim": "9004", + "archery_ticket_price": "0", + "id": "12846", + "stand_turn_anim": "9000" + }, + { + "turn90cw_anim": "9002", + "examine": "A stone used to gather energy.", + "walk_anim": "8997", + "durability": null, + "destroy": "true", + "weight": "30", + "turn90ccw_anim": "9003", + "turn180_anim": "9001", + "render_anim": "370", + "equipment_slot": "3", + "destroy_message": "You can reclaim this item from the place you found it.", + "stand_anim": "8998", + "name": "Stone of power", + "tradeable": "false", + "run_anim": "9004", + "archery_ticket_price": "0", + "id": "12847", + "stand_turn_anim": "9000" + }, + { + "turn90cw_anim": "9002", + "examine": "A stone used to gather energy.", + "walk_anim": "8997", + "durability": null, + "destroy": "true", + "weight": "30", + "turn90ccw_anim": "9003", + "turn180_anim": "9001", + "render_anim": "370", + "equipment_slot": "3", + "destroy_message": "You can reclaim this item from the place you found it.", + "stand_anim": "8998", + "name": "Stone of power", + "tradeable": "false", + "run_anim": "9004", + "archery_ticket_price": "0", + "id": "12848", + "stand_turn_anim": "9000" + }, + { + "turn90cw_anim": "9002", + "examine": "A stone used to gather energy.", + "walk_anim": "8997", + "durability": null, + "destroy": "true", + "weight": "30", + "turn90ccw_anim": "9003", + "turn180_anim": "9001", + "render_anim": "370", + "equipment_slot": "3", + "destroy_message": "You can reclaim this item from the place you found it.", + "stand_anim": "8998", + "name": "Stone of power", + "tradeable": "false", + "run_anim": "9004", + "archery_ticket_price": "0", + "id": "12849", + "stand_turn_anim": "9000" + }, + { + "examine": "A generic elemental rune", + "durability": null, + "name": "Elemental rune", + "archery_ticket_price": "0", + "id": "12850" + }, + { + "examine": "A generic non-elemental rune", + "durability": null, + "name": "Catalytic rune", + "archery_ticket_price": "0", + "id": "12851" + }, + { + "examine": "A token awarded for taking part in the Fist of Guthix minigame.", + "durability": null, + "name": "Fist of guthix token", + "archery_ticket_price": "0", + "id": "12852" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "A box of bandages for healing.", + "durability": null, + "name": "Bandages", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12853" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "examine": "Teleports you to the centre of the arena.", + "durability": null, + "name": "Tele-orb", + "archery_ticket_price": "0", + "id": "12855" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "requirements": "{15,50}", + "shop_price": "75", + "examine": "A pair of mystical gloves.", + "durability": null, + "name": "Irit gloves", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12856", + "equipment_slot": "9" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "requirements": "{15,60}", + "shop_price": "100", + "examine": "A pair of mystical gloves.", + "durability": null, + "name": "Avantoe gloves", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12857", + "equipment_slot": "9" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "requirements": "{15,70}", + "shop_price": "200", + "examine": "A pair of mystical gloves.", + "durability": null, + "name": "Kwuarm gloves", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12858", + "equipment_slot": "9" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "requirements": "{15,80}", + "shop_price": "200", + "examine": "A pair of mystical gloves.", + "durability": null, + "name": "Cadantine gloves", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12859", + "equipment_slot": "9" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "requirements": "{10,65}", + "shop_price": "200", + "examine": "A pair of mystical gloves.", + "durability": null, + "name": "Swordfish gloves", + "tradeable": "false", + "weight": "1", + "archery_ticket_price": "0", + "id": "12860", + "equipment_slot": "9" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "requirements": "{10,90}", + "shop_price": "200", + "examine": "A pair of mystical gloves", + "durability": null, + "name": "Shark gloves", + "tradeable": "false", + "weight": "1", + "archery_ticket_price": "0", + "id": "12861", + "equipment_slot": "9" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "requirements": "{18,70}", + "shop_price": "200", + "examine": "A pair of mystical gloves.", + "durability": null, + "name": "Dragon slayer gloves", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12862", + "equipment_slot": "9" + }, + { + "destroy_message": "You can buy a new pair from the druids at the Fist of Guthix activity.", + "requirements": "{20,10}", + "shop_price": "75", + "examine": "A pair of mystical gloves.", + "durability": null, + "name": "Air runecrafting gloves", + "tradeable": "false", + "weight": "1", + "destroy": "true", + "archery_ticket_price": "0", + "id": "12863", + "equipment_slot": "9" + }, + { + "destroy_message": "You can buy a new pair from the druids at the Fist of Guthix activity.", + "requirements": "{20,20}", + "shop_price": "75", + "examine": "A pair of mystical gloves.", + "durability": null, + "name": "Water runecrafting gloves", + "tradeable": "false", + "weight": "1", + "destroy": "true", + "archery_ticket_price": "0", + "id": "12864", + "equipment_slot": "9" + }, + { + "destroy_message": "You can buy a new pair from the druids at the Fist of Guthix minigame.", + "requirements": "{20,30}", + "shop_price": "75", + "examine": "A pair of mystical gloves.", + "durability": null, + "name": "Earth runecrafting gloves", + "tradeable": "false", + "weight": "1", + "destroy": "true", + "archery_ticket_price": "0", + "id": "12865", + "equipment_slot": "9" + }, + { + "remove_head": "true", + "requirements": "{1,50}-{6,60}", + "shop_price": "250", + "examine": "Its arcane power is waning.", + "durability": null, + "absorb": "4,3,0", + "equipment_slot": "0", + "grand_exchange_price": "70529", + "name": "Battle hood 100", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12866", + "bonuses": "0,0,0,5,0,7,6,8,5,0,8,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,50}-{6,60}", + "shop_price": "250", + "examine": "Its arcane power is waning.", + "durability": null, + "absorb": "4,3,0", + "equipment_slot": "0", + "grand_exchange_price": "70529", + "name": "Battle hood 80", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12867", + "bonuses": "0,0,0,5,0,7,6,8,5,0,8,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,50}-{6,60}", + "shop_price": "250", + "examine": "Its arcane power is waning.", + "durability": null, + "absorb": "4,3,0", + "equipment_slot": "0", + "grand_exchange_price": "70529", + "name": "Battle hood 60", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12868", + "bonuses": "0,0,0,5,0,7,6,8,5,0,8,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,50}-{6,60}", + "shop_price": "250", + "examine": "Its arcane power is waning.", + "durability": null, + "absorb": "4,3,0", + "equipment_slot": "0", + "grand_exchange_price": "70529", + "name": "Battle hood 40", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12869", + "bonuses": "0,0,0,5,0,7,6,8,5,0,8,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,50}-{6,60}", + "shop_price": "250", + "examine": "Its arcane power is waning.", + "durability": null, + "absorb": "4,3,0", + "equipment_slot": "0", + "grand_exchange_price": "70529", + "name": "Battle hood 20", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12870", + "bonuses": "0,0,0,5,0,7,6,8,5,0,8,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,50}-{6,60}", + "shop_price": "250", + "ge_buy_limit": "10", + "examine": "Its arcane power is waning.", + "durability": null, + "absorb": "4,3,0", + "equipment_slot": "0", + "grand_exchange_price": "78900", + "name": "Battle hood 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12871", + "bonuses": "0,0,0,2,0,3,2,3,2,0,3,0,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "78900", + "durability": null, + "name": "Battle hood 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12872" + }, + { + "requirements": "{1,50}-{6,60}", + "shop_price": "1500", + "examine": "A robe top infused with arcane power, especially created for combat spells.", + "durability": null, + "weight": "4", + "absorb": "8,4,0", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "537714", + "name": "Battle robe top 100", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12873", + "bonuses": "0,0,0,26,0,17,15,20,26,0,30,0,0,0,0" + }, + { + "requirements": "{1,50}-{6,60}", + "shop_price": "1500", + "examine": "A robe top infused with arcane power, especially created for combat spells.", + "durability": null, + "weight": "4", + "absorb": "8,4,0", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "537714", + "name": "Battle robe top 80", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12874", + "bonuses": "0,0,0,26,0,17,15,20,26,0,30,0,0,0,0" + }, + { + "requirements": "{1,50}-{6,60}", + "shop_price": "1500", + "examine": "A robe top infused with arcane power, especially created for combat spells.", + "durability": null, + "weight": "4", + "absorb": "8,4,0", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "537714", + "name": "Battle robe top 60", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12875", + "bonuses": "0,0,0,26,0,17,15,20,26,0,30,0,0,0,0" + }, + { + "requirements": "{1,50}-{6,60}", + "shop_price": "1500", + "examine": "A robe top infused with arcane power, especially created for combat spells.", + "durability": null, + "weight": "4", + "absorb": "8,4,0", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "537714", + "name": "Battle robe top 40", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12876", + "bonuses": "0,0,0,26,0,17,15,20,26,0,30,0,0,0,0" + }, + { + "requirements": "{1,50}-{6,60}", + "shop_price": "1500", + "examine": "A robe top infused with arcane power, especially created for combat spells.", + "durability": null, + "weight": "4", + "absorb": "8,4,0", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "537714", + "name": "Battle robe top 20", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12877", + "bonuses": "0,0,0,26,0,17,15,20,26,0,30,0,0,0,0" + }, + { + "requirements": "{1,50}-{6,60}", + "shop_price": "1500", + "ge_buy_limit": "10", + "examine": "Its arcane power is waning.", + "durability": null, + "weight": "4", + "absorb": "8,4,0", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "431400", + "name": "Battle robe top 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12878", + "bonuses": "0,0,0,7,0,4,4,5,7,0,8,0,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "431400", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Battle robe top 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12879" + }, + { + "requirements": "{1,50}-{6,60}", + "shop_price": "1000", + "examine": "A robe bottom infused with arcane power, especially created for combat spells.", + "durability": null, + "weight": "3", + "absorb": "5,2,0", + "equipment_slot": "7", + "grand_exchange_price": "364878", + "name": "Battle robe bottom 100", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12880", + "bonuses": "0,0,0,20,0,14,11,16,20,0,23,0,0,0,0" + }, + { + "requirements": "{1,50}-{6,60}", + "shop_price": "1000", + "examine": "A robe bottom infused with arcane power, especially created for combat spells.", + "durability": null, + "weight": "3", + "absorb": "5,2,0", + "equipment_slot": "7", + "grand_exchange_price": "364878", + "name": "Battle robe bottom 80", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12881", + "bonuses": "0,0,0,20,0,14,11,16,20,0,23,0,0,0,0" + }, + { + "requirements": "{1,50}-{6,60}", + "shop_price": "1000", + "examine": "A robe bottom infused with arcane power, especially created for combat spells.", + "durability": null, + "weight": "3", + "absorb": "5,2,0", + "equipment_slot": "7", + "grand_exchange_price": "364878", + "name": "Battle robe bottom 60", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12882", + "bonuses": "0,0,0,20,0,14,11,16,20,0,23,0,0,0,0" + }, + { + "requirements": "{1,50}-{6,60}", + "shop_price": "1000", + "examine": "A robe bottom infused with arcane power, especially created for combat spells.", + "durability": null, + "weight": "3", + "absorb": "5,2,0", + "equipment_slot": "7", + "grand_exchange_price": "364878", + "name": "Battle robe bottom 40", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12883", + "bonuses": "0,0,0,20,0,14,11,16,20,0,23,0,0,0,0" + }, + { + "requirements": "{1,50}-{6,60}", + "shop_price": "1000", + "examine": "A robe bottom infused with arcane power, especially created for combat spells.", + "durability": null, + "weight": "3", + "absorb": "5,2,0", + "equipment_slot": "7", + "grand_exchange_price": "364878", + "name": "Battle robe bottom 20", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12884", + "bonuses": "0,0,0,20,0,14,11,16,20,0,23,0,0,0,0" + }, + { + "requirements": "{1,50}-{6,60}", + "shop_price": "1000", + "ge_buy_limit": "10", + "examine": "Its arcane power is waning.", + "durability": null, + "weight": "3", + "absorb": "5,2,0", + "equipment_slot": "7", + "grand_exchange_price": "538000", + "name": "Battle robe bottom 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12885", + "bonuses": "0,0,0,6,0,4,3,4,6,0,7,0,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "538000", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Battle robe bottom 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12886" + }, + { + "remove_head": "true", + "requirements": "{1,10}-{6,20}", + "shop_price": "100", + "examine": "A worn-out hood, formerly worn by the followers of Guthix.", + "durability": null, + "weight": "7", + "equipment_slot": "0", + "grand_exchange_price": "6915", + "name": "Druidic mage hood 100", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12887", + "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,10}-{6,20}", + "shop_price": "100", + "examine": "A worn-out hood, formerly worn by the followers of Guthix.", + "durability": null, + "weight": "7", + "equipment_slot": "0", + "grand_exchange_price": "6915", + "name": "Druidic mage hood 80", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12888", + "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,10}-{6,20}", + "shop_price": "100", + "examine": "A worn-out hood, formerly worn by the followers of Guthix.", + "durability": null, + "weight": "7", + "equipment_slot": "0", + "grand_exchange_price": "6915", + "name": "Druidic mage hood 60", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12889", + "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,10}-{6,20}", + "shop_price": "100", + "examine": "A worn-out hood, formerly worn by the followers of Guthix.", + "durability": null, + "weight": "7", + "equipment_slot": "0", + "grand_exchange_price": "6915", + "name": "Druidic mage hood 40", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12890", + "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,10}-{6,20}", + "shop_price": "100", + "examine": "A worn-out hood, formerly worn by the followers of Guthix.", + "durability": null, + "weight": "7", + "equipment_slot": "0", + "grand_exchange_price": "6915", + "name": "Druidic mage hood 20", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12891", + "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,10}-{6,20}", + "shop_price": "100", + "ge_buy_limit": "10", + "examine": "A worn-out hood, formerly worn by the followers of Guthix.", + "durability": null, + "weight": "7", + "equipment_slot": "0", + "grand_exchange_price": "8504", + "name": "Druidic mage hood 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12892", + "bonuses": "0,0,0,1,0,0,0,0,1,0,1,0,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "8504", + "durability": null, + "name": "Druidic mage hood 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12893" + }, + { + "requirements": "{1,10}-{6,20}", + "shop_price": "300", + "examine": "A magical robe top worn by followers of Guthix.", + "durability": null, + "weight": "4", + "absorb": "2,1,0", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "80273", + "name": "Druidic mage top 100", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12894", + "bonuses": "0,0,0,7,0,0,0,0,7,0,7,0,0,0,0" + }, + { + "requirements": "{1,10}-{6,20}", + "shop_price": "300", + "examine": "A magical robe top worn by followers of Guthix.", + "durability": null, + "weight": "4", + "absorb": "2,1,0", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "80273", + "name": "Druidic mage top 80", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12895", + "bonuses": "0,0,0,7,0,0,0,0,7,0,7,0,0,0,0" + }, + { + "requirements": "{1,10}-{6,20}", + "shop_price": "300", + "examine": "A magical robe top worn by followers of Guthix.", + "durability": null, + "weight": "4", + "absorb": "2,1,0", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "80273", + "name": "Druidic mage top 60", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12896", + "bonuses": "0,0,0,7,0,0,0,0,7,0,7,0,0,0,0" + }, + { + "requirements": "{1,10}-{6,20}", + "shop_price": "300", + "examine": "A magical robe top worn by followers of Guthix.", + "durability": null, + "weight": "4", + "absorb": "2,1,0", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "80273", + "name": "Druidic mage top 40", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12897", + "bonuses": "0,0,0,7,0,0,0,0,7,0,7,0,0,0,0" + }, + { + "requirements": "{1,10}-{6,20}", + "shop_price": "300", + "examine": "A magical robe top worn by followers of Guthix.", + "durability": null, + "weight": "4", + "absorb": "2,1,0", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "80273", + "name": "Druidic mage top 20", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12898", + "bonuses": "0,0,0,7,0,0,0,0,7,0,7,0,0,0,0" + }, + { + "requirements": "{1,10}-{6,20}", + "shop_price": "300", + "ge_buy_limit": "10", + "examine": "A magical robe top worn by followers of Guthix.", + "durability": null, + "weight": "4", + "absorb": "2,1,0", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "76300", + "name": "Druidic mage top 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12899", + "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "76300", + "durability": null, + "name": "Druidic mage top 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12900" + }, + { + "requirements": "{1,10}-{6,20}", + "shop_price": "200", + "examine": "A magical robe bottom worn by a person who follows Guthix.", + "durability": null, + "weight": "3", + "absorb": "1,0,0", + "equipment_slot": "7", + "grand_exchange_price": "54532", + "name": "Druidic mage bottom 100", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12901", + "bonuses": "0,0,0,6,0,0,0,0,6,0,6,0,0,0,0" + }, + { + "requirements": "{1,10}-{6,20}", + "shop_price": "200", + "examine": "A magical robe bottom worn by a person who follows Guthix.", + "durability": null, + "weight": "3", + "absorb": "1,0,0", + "equipment_slot": "7", + "grand_exchange_price": "54532", + "name": "Druidic mage bottom 80", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12902", + "bonuses": "0,0,0,6,0,0,0,0,6,0,6,0,0,0,0" + }, + { + "requirements": "{1,10}-{6,20}", + "shop_price": "200", + "examine": "A magical robe bottom worn by a person who follows Guthix.", + "durability": null, + "weight": "3", + "absorb": "1,0,0", + "equipment_slot": "7", + "grand_exchange_price": "54532", + "name": "Druidic mage bottom 60", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12903", + "bonuses": "0,0,0,6,0,0,0,0,6,0,6,0,0,0,0" + }, + { + "requirements": "{1,10}-{6,20}", + "shop_price": "200", + "examine": "A magical robe bottom worn by a person who follows Guthix.", + "durability": null, + "weight": "3", + "absorb": "1,0,0", + "equipment_slot": "7", + "grand_exchange_price": "54532", + "name": "Druidic mage bottom 40", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12904", + "bonuses": "0,0,0,6,0,0,0,0,6,0,6,0,0,0,0" + }, + { + "requirements": "{1,10}-{6,20}", + "shop_price": "200", + "examine": "A magical robe bottom worn by a person who follows Guthix.", + "durability": null, + "weight": "3", + "absorb": "1,0,0", + "equipment_slot": "7", + "grand_exchange_price": "54532", + "name": "Druidic mage bottom 20", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12905", + "bonuses": "0,0,0,6,0,0,0,0,6,0,6,0,0,0,0" + }, + { + "requirements": "{1,10}-{6,20}", + "shop_price": "200", + "ge_buy_limit": "10", + "examine": "A magical robe bottom worn by a person who follows Guthix.", + "durability": null, + "weight": "3", + "absorb": "1,0,0", + "equipment_slot": "7", + "grand_exchange_price": "60800", + "name": "Druidic mage bottom 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12906", + "bonuses": "0,0,0,2,0,0,0,0,2,0,2,0,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "60800", + "durability": null, + "name": "Druidic mage bottom 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12907" + }, + { + "requirements": "{1,35}", + "shop_price": "50", + "examine": "A spiked square shield.", + "durability": null, + "weight": "5", + "absorb": "3,0,6", + "equipment_slot": "5", + "grand_exchange_price": "2271", + "name": "Adamant spikeshield 100", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12908", + "bonuses": "0,0,0,-6,-2,25,27,23,0,25,26,1,0,0,0" + }, + { + "requirements": "{1,35}", + "shop_price": "50", + "examine": "A spiked square shield.", + "durability": null, + "weight": "5", + "absorb": "3,0,6", + "equipment_slot": "5", + "grand_exchange_price": "2271", + "name": "Adamant spikeshield 80", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12909", + "bonuses": "0,0,0,-6,-2,25,27,23,0,25,26,1,0,0,0" + }, + { + "requirements": "{1,35}", + "shop_price": "50", + "examine": "A spiked square shield.", + "durability": null, + "weight": "5", + "absorb": "3,0,6", + "equipment_slot": "5", + "grand_exchange_price": "2271", + "name": "Adamant spikeshield 60", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12910", + "bonuses": "0,0,0,-6,-2,25,27,23,0,25,26,1,0,0,0" + }, + { + "requirements": "{1,35}", + "shop_price": "50", + "examine": "A spiked square shield.", + "durability": null, + "weight": "5", + "absorb": "3,0,6", + "equipment_slot": "5", + "grand_exchange_price": "2271", + "name": "Adamant spikeshield 40", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12911", + "bonuses": "0,0,0,-6,-2,25,27,23,0,25,26,1,0,0,0" + }, + { + "requirements": "{1,35}", + "shop_price": "50", + "examine": "A spiked square shield.", + "durability": null, + "weight": "5", + "absorb": "3,0,6", + "equipment_slot": "5", + "grand_exchange_price": "2271", + "name": "Adamant spikeshield 20", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12912", + "bonuses": "0,0,0,-6,-2,25,27,23,0,25,26,1,0,0,0" + }, + { + "requirements": "{1,35}", + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "Not so spiky anymore.", + "durability": null, + "weight": "5", + "absorb": "3,0,6", + "equipment_slot": "5", + "grand_exchange_price": "2718", + "name": "Adamant spikeshield 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12913", + "bonuses": "0,0,0,-6,-2,11,12,10,0,11,4,1,0,0,0" + }, + { + "ge_buy_limit": "100", + "examine": "Not so spiky anymore!", + "grand_exchange_price": "2718", + "durability": null, + "name": "Adamant spikeshield 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12914" + }, + { + "requirements": "{1,35}", + "shop_price": "100", + "examine": "A large, spiked metal shield", + "durability": null, + "weight": "7", + "absorb": "3,0,6", + "equipment_slot": "5", + "grand_exchange_price": "19190", + "name": "Adamant berserker shield 100", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12915", + "bonuses": "0,0,0,-8,-2,28,32,30,-1,30,31,2,0,0,0" + }, + { + "requirements": "{1,35}", + "shop_price": "100", + "examine": "A large, spiked metal shield", + "durability": null, + "weight": "7", + "absorb": "3,0,6", + "equipment_slot": "5", + "grand_exchange_price": "19190", + "name": "Adamant berserker shield 80", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12916", + "bonuses": "0,0,0,-8,-2,28,32,30,-1,30,31,2,0,0,0" + }, + { + "requirements": "{1,35}", + "shop_price": "100", + "examine": "A large, spiked metal shield", + "durability": null, + "weight": "7", + "absorb": "3,0,6", + "equipment_slot": "5", + "grand_exchange_price": "19190", + "name": "Adamant berserker shield 60", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12917", + "bonuses": "0,0,0,-8,-2,28,32,30,-1,30,31,2,0,0,0" + }, + { + "requirements": "{1,35}", + "shop_price": "100", + "examine": "A large, spiked metal shield", + "durability": null, + "weight": "7", + "absorb": "3,0,6", + "equipment_slot": "5", + "grand_exchange_price": "19190", + "name": "Adamant berserker shield 40", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12918", + "bonuses": "0,0,0,-8,-2,28,32,30,-1,30,31,2,0,0,0" + }, + { + "requirements": "{1,35}", + "shop_price": "100", + "examine": "A large, spiked metal shield", + "durability": null, + "weight": "7", + "absorb": "3,0,6", + "equipment_slot": "5", + "grand_exchange_price": "19190", + "name": "Adamant berserker shield 20", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12919", + "bonuses": "0,0,0,-8,-2,28,32,30,-1,30,31,2,0,0,0" + }, + { + "requirements": "{1,35}", + "shop_price": "100", + "ge_buy_limit": "10", + "examine": "Not so spiky anymore!", + "durability": null, + "weight": "7", + "absorb": "3,0,6", + "equipment_slot": "5", + "grand_exchange_price": "23700", + "name": "Adamant berserker shield 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12920", + "bonuses": "0,0,0,-8,-2,12,14,13,-1,8,4,1,0,0,0" + }, + { + "ge_buy_limit": "10", + "examine": "Not so spiky anymore!", + "grand_exchange_price": "23700", + "durability": null, + "name": "Adamant berserker shield 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12921" + }, + { + "requirements": "{1,45}", + "shop_price": "200", + "examine": "A spiked, medium square shield.", + "durability": null, + "weight": "4", + "absorb": "3,0,7", + "equipment_slot": "5", + "grand_exchange_price": "57548", + "name": "Rune spikeshield 100", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12922", + "bonuses": "0,0,0,-6,-2,39,41,37,0,39,36,3,0,0,0", + "point_price": "35" + }, + { + "requirements": "{1,45}", + "shop_price": "200", + "examine": "A spiked, medium square shield.", + "durability": null, + "weight": "4", + "absorb": "3,0,7", + "equipment_slot": "5", + "grand_exchange_price": "57548", + "name": "Rune spikeshield 80", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12923", + "bonuses": "0,0,0,-6,-2,39,41,37,0,39,36,3,0,0,0" + }, + { + "requirements": "{1,45}", + "shop_price": "200", + "examine": "A spiked, medium square shield.", + "durability": null, + "weight": "4", + "absorb": "3,0,7", + "equipment_slot": "5", + "grand_exchange_price": "57548", + "name": "Rune spikeshield 60", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12924", + "bonuses": "0,0,0,-6,-2,39,41,37,0,39,36,3,0,0,0" + }, + { + "requirements": "{1,45}", + "shop_price": "200", + "examine": "A spiked, medium square shield.", + "durability": null, + "weight": "4", + "absorb": "3,0,7", + "equipment_slot": "5", + "grand_exchange_price": "57548", + "name": "Rune spikeshield 40", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12925", + "bonuses": "0,0,0,-6,-2,39,41,37,0,39,36,3,0,0,0" + }, + { + "requirements": "{1,45}", + "shop_price": "200", + "examine": "A spiked, medium square shield.", + "durability": null, + "weight": "4", + "absorb": "3,0,7", + "equipment_slot": "5", + "grand_exchange_price": "57548", + "name": "Rune spikeshield 20", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12926", + "bonuses": "0,0,0,-6,-2,39,41,37,0,39,36,3,0,0,0" + }, + { + "requirements": "{1,45}", + "shop_price": "200", + "ge_buy_limit": "10", + "examine": "Not so spiky anymore.", + "durability": null, + "weight": "4", + "absorb": "3,0,7", + "equipment_slot": "5", + "grand_exchange_price": "50500", + "name": "Rune spikeshield 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12927", + "bonuses": "0,0,0,-6,-2,14,15,13,0,14,8,2,0,0,0" + }, + { + "ge_buy_limit": "10", + "examine": "Not so spiky anymore.", + "grand_exchange_price": "50500", + "durability": null, + "name": "Rune spikeshield 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12928" + }, + { + "requirements": "{1,45}", + "shop_price": "300", + "examine": "A Large, spiked metal shield.", + "durability": null, + "weight": "6", + "absorb": "3,0,7", + "equipment_slot": "5", + "grand_exchange_price": "82000", + "name": "Rune berserker shield 100", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12929", + "bonuses": "0,0,0,-8,-2,45,49,47,-1,47,41,4,0,0,0", + "point_price": "35" + }, + { + "requirements": "{1,45}", + "shop_price": "300", + "examine": "A Large, spiked metal shield.", + "durability": null, + "weight": "6", + "absorb": "3,0,7", + "equipment_slot": "5", + "grand_exchange_price": "82000", + "name": "Rune berserker shield 80", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12930", + "bonuses": "0,0,0,-8,-2,45,49,47,-1,47,41,4,0,0,0" + }, + { + "requirements": "{1,45}", + "shop_price": "300", + "examine": "A Large, spiked metal shield.", + "durability": null, + "weight": "6", + "absorb": "3,0,7", + "equipment_slot": "5", + "grand_exchange_price": "82000", + "name": "Rune berserker shield 60", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12931", + "bonuses": "0,0,0,-8,-2,45,49,47,-1,47,41,4,0,0,0" + }, + { + "requirements": "{1,45}", + "shop_price": "300", + "examine": "A Large, spiked metal shield.", + "durability": null, + "weight": "6", + "absorb": "3,0,7", + "equipment_slot": "5", + "grand_exchange_price": "82000", + "name": "Rune berserker shield 40", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12932", + "bonuses": "0,0,0,-8,-2,45,49,47,-1,47,41,4,0,0,0" + }, + { + "requirements": "{1,45}", + "shop_price": "300", + "examine": "A Large, spiked metal shield.", + "durability": null, + "weight": "6", + "absorb": "3,0,7", + "equipment_slot": "5", + "grand_exchange_price": "82000", + "name": "Rune berserker shield 20", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12933", + "bonuses": "0,0,0,-8,-2,45,49,47,-1,47,41,4,0,0,0" + }, + { + "requirements": "{1,45}", + "shop_price": "300", + "ge_buy_limit": "10", + "examine": "Not so spiky anymore.", + "durability": null, + "weight": "6", + "absorb": "3,0,7", + "equipment_slot": "5", + "grand_exchange_price": "135300", + "name": "Rune berserker shield 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12934", + "bonuses": "0,0,0,-8,-2,16,18,17,-1,17,9,2,0,0,0" + }, + { + "ge_buy_limit": "10", + "examine": "Not so spiky anymore.", + "grand_exchange_price": "135300", + "durability": null, + "name": "Rune berserker shield 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12935" + }, + { + "remove_head": "true", + "requirements": "{1,40}-{4,40}", + "shop_price": "150", + "examine": "A coif made of green dragonhide.", + "durability": null, + "weight": "0.9", + "absorb": "0,3,1", + "equip_audio": "2238", + "equipment_slot": "0", + "grand_exchange_price": "88084", + "name": "Green d'hide coif 100", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12936", + "bonuses": "0,0,0,-1,4,4,6,8,4,5,4,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,40}-{4,40}", + "shop_price": "150", + "examine": "A coif made of green dragonhide.", + "durability": null, + "weight": "0.9", + "absorb": "0,3,1", + "equip_audio": "2238", + "equipment_slot": "0", + "grand_exchange_price": "88084", + "name": "Green d'hide coif 80", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12937", + "bonuses": "0,0,0,-1,4,4,6,8,4,5,4,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,40}-{4,40}", + "shop_price": "150", + "examine": "A coif made of green dragonhide.", + "durability": null, + "weight": "0.9", + "absorb": "0,3,1", + "equip_audio": "2238", + "equipment_slot": "0", + "grand_exchange_price": "88084", + "name": "Green d'hide coif 60", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12938", + "bonuses": "0,0,0,-1,4,4,6,8,4,5,4,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,40}-{4,40}", + "shop_price": "150", + "examine": "A coif made of green dragonhide.", + "durability": null, + "weight": "0.9", + "absorb": "0,3,1", + "equip_audio": "2238", + "equipment_slot": "0", + "grand_exchange_price": "88084", + "name": "Green d'hide coif 40", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12939", + "bonuses": "0,0,0,-1,4,4,6,8,4,5,4,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,40}-{4,40}", + "shop_price": "150", + "examine": "A coif made of green dragonhide.", + "durability": null, + "weight": "0.9", + "absorb": "0,3,1", + "equip_audio": "2238", + "equipment_slot": "0", + "grand_exchange_price": "88084", + "name": "Green d'hide coif 20", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12940", + "bonuses": "0,0,0,-1,4,4,6,8,4,5,4,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,40}-{4,40}", + "shop_price": "150", + "ge_buy_limit": "100", + "examine": "A worn out coif made of green dragonhide.", + "durability": null, + "weight": "0.9", + "absorb": "0,3,1", + "equip_audio": "2238", + "equipment_slot": "0", + "grand_exchange_price": "92700", + "name": "Green d'hide coif 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12941", + "bonuses": "0,0,0,-1,1,1,2,2,1,2,1,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "examine": "A worn out coif made of green dragonhide.", + "grand_exchange_price": "92700", + "durability": null, + "name": "Green d'hide coif 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12942" + }, + { + "remove_head": "true", + "requirements": "{1,40}-{4,50}", + "shop_price": "200", + "examine": "A coif made of blue dragonhide.", + "durability": null, + "weight": "1", + "absorb": "0,3,1", + "equip_audio": "2238", + "equipment_slot": "0", + "grand_exchange_price": "186985", + "name": "Blue d'hide coif 100", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12943", + "bonuses": "0,0,0,-1,5,4,6,8,4,6,5,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,40}-{4,50}", + "shop_price": "200", + "examine": "A coif made of blue dragonhide.", + "durability": null, + "weight": "1", + "absorb": "0,3,1", + "equip_audio": "2238", + "equipment_slot": "0", + "grand_exchange_price": "186985", + "name": "Blue d'hide coif 80", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12944", + "bonuses": "0,0,0,-1,5,4,6,8,4,6,5,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,40}-{4,50}", + "shop_price": "200", + "examine": "Fully charged: A coif made of blue dragonhide. Fully degraded: A worn out coif made of blue dragonhide.", + "durability": null, + "weight": "1", + "absorb": "0,3,1", + "equip_audio": "2238", + "equipment_slot": "0", + "grand_exchange_price": "186985", + "name": "Blue d'hide coif 60", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12945", + "bonuses": "0,0,0,-1,5,4,6,8,4,6,5,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,40}-{4,50}", + "shop_price": "200", + "examine": "A coif made of blue dragonhide.", + "durability": null, + "weight": "1", + "absorb": "0,3,1", + "equip_audio": "2238", + "equipment_slot": "0", + "grand_exchange_price": "186985", + "name": "Blue d'hide coif 40", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12946", + "bonuses": "0,0,0,-1,5,4,6,8,4,6,5,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,40}-{4,50}", + "shop_price": "200", + "examine": "A coif made of blue dragonhide.", + "durability": null, + "weight": "1", + "absorb": "0,3,1", + "equip_audio": "2238", + "equipment_slot": "0", + "grand_exchange_price": "186985", + "name": "Blue d'hide coif 20", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12947", + "bonuses": "0,0,0,-1,5,4,6,8,4,6,5,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,40}-{4,50}", + "shop_price": "200", + "ge_buy_limit": "100", + "examine": "A worn out coif made of blue dragonhide.", + "durability": null, + "weight": "1", + "absorb": "0,3,1", + "equip_audio": "2238", + "equipment_slot": "0", + "grand_exchange_price": "131900", + "name": "Blue d'hide coif 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12948", + "bonuses": "0,0,0,-1,1,1,2,2,1,2,2,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "examine": "A worn out coif made of blue dragonhide.", + "grand_exchange_price": "131900", + "durability": null, + "name": "Blue d'hide coif 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12949" + }, + { + "remove_head": "true", + "requirements": "{1,40}-{4,60}", + "shop_price": "300", + "examine": "A coif made of red dragonhide.", + "durability": null, + "weight": "1", + "absorb": "0,3,1", + "equip_audio": "2238", + "equipment_slot": "0", + "grand_exchange_price": "230059", + "name": "Red d'hide coif 100", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12950", + "bonuses": "0,0,0,-1,6,4,6,9,4,6,6,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,40}-{4,60}", + "shop_price": "300", + "examine": "A coif made of red dragonhide.", + "durability": null, + "weight": "1", + "absorb": "0,3,1", + "equip_audio": "2238", + "equipment_slot": "0", + "grand_exchange_price": "230059", + "name": "Red d'hide coif 80", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12951", + "bonuses": "0,0,0,-1,6,4,6,9,4,6,6,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,40}-{4,60}", + "shop_price": "300", + "examine": "Fully charged: A coif made of red dragonhide.Fully degraded: A worn out coif made of red dragonhide.", + "durability": null, + "weight": "1", + "absorb": "0,3,1", + "equip_audio": "2238", + "equipment_slot": "0", + "grand_exchange_price": "230059", + "name": "Red d'hide coif 60", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12952", + "bonuses": "0,0,0,-1,6,4,6,9,4,6,6,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,40}-{4,60}", + "shop_price": "300", + "examine": "A coif made of red dragonhide.", + "durability": null, + "weight": "1", + "absorb": "0,3,1", + "equip_audio": "2238", + "equipment_slot": "0", + "grand_exchange_price": "230059", + "name": "Red d'hide coif 40", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12953", + "bonuses": "0,0,0,-1,6,4,6,9,4,6,6,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,40}-{4,60}", + "shop_price": "300", + "examine": "A coif made of red dragonhide.", + "durability": null, + "weight": "1", + "absorb": "0,3,1", + "equip_audio": "2238", + "equipment_slot": "0", + "grand_exchange_price": "230059", + "name": "Red d'hide coif 20", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12954", + "bonuses": "0,0,0,-1,6,4,6,9,4,6,6,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,40}-{4,60}", + "shop_price": "300", + "ge_buy_limit": "100", + "examine": "A worn out coif made of red dragonhide.", + "durability": null, + "weight": "1", + "absorb": "0,3,1", + "equip_audio": "2238", + "equipment_slot": "0", + "grand_exchange_price": "156600", + "name": "Red d'hide coif 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12955", + "bonuses": "0,0,0,-1,2,1,2,3,1,2,2,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "examine": "A worn out coif made of red dragonhide.", + "grand_exchange_price": "156600", + "durability": null, + "name": "Red d'hide coif 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12956" + }, + { + "remove_head": "true", + "requirements": "{1,40}-{4,70}", + "shop_price": "500", + "examine": "A coif made of black dragonhide.", + "durability": null, + "weight": "1", + "absorb": "0,3,1", + "equip_audio": "2238", + "equipment_slot": "0", + "grand_exchange_price": "379555", + "name": "Black d'hide coif 100", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12957", + "bonuses": "0,0,0,-1,7,4,7,9,4,7,7,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,40}-{4,70}", + "shop_price": "500", + "examine": "A coif made of black dragonhide.", + "durability": null, + "weight": "1", + "absorb": "0,3,1", + "equip_audio": "2238", + "equipment_slot": "0", + "grand_exchange_price": "379555", + "name": "Black d'hide coif 80", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12958", + "bonuses": "0,0,0,-1,7,4,7,9,4,7,7,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,40}-{4,70}", + "shop_price": "500", + "examine": "A coif made of black dragonhide.", + "durability": null, + "weight": "1", + "absorb": "0,3,1", + "equip_audio": "2238", + "equipment_slot": "0", + "grand_exchange_price": "379555", + "name": "Black d'hide coif 60", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12959", + "bonuses": "0,0,0,-1,7,4,7,9,4,7,7,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,40}-{4,70}", + "shop_price": "500", + "examine": "A coif made of black dragonhide.", + "durability": null, + "weight": "1", + "absorb": "0,3,1", + "equip_audio": "2238", + "equipment_slot": "0", + "grand_exchange_price": "379555", + "name": "Black d'hide coif 40", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12960", + "bonuses": "0,0,0,-1,7,4,7,9,4,7,7,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,40}-{4,70}", + "shop_price": "500", + "examine": "Fully charged: A coif made of black dragonhide. Fully degraded: A worn out coif made of black dragonhide.", + "durability": null, + "weight": "1", + "absorb": "0,3,1", + "equip_audio": "2238", + "equipment_slot": "0", + "grand_exchange_price": "379555", + "name": "Black d'hide coif 20", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12961", + "bonuses": "0,0,0,-1,7,4,7,9,4,7,7,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,40}-{4,70}", + "shop_price": "500", + "ge_buy_limit": "100", + "examine": "A coif made of black dragonhide.", + "durability": null, + "weight": "1", + "absorb": "0,3,1", + "equip_audio": "2238", + "equipment_slot": "0", + "grand_exchange_price": "229000", + "name": "Black d'hide coif 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12962", + "bonuses": "0,0,0,-1,3,1,3,3,1,2,3,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "examine": "A coif made of black dragonhide.", + "grand_exchange_price": "229000", + "durability": null, + "name": "Black d'hide coif 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12963" + }, + { + "remove_head": "true", + "requirements": "{1,10}-{6,20}", + "shop_price": "50", + "examine": "A magical hood, especially created for combat spells.", + "durability": null, + "weight": "0.8", + "equipment_slot": "0", + "grand_exchange_price": "5661", + "name": "Combat hood 100", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12964", + "bonuses": "0,0,0,3,0,1,1,1,3,0,4,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,10}-{6,20}", + "shop_price": "50", + "examine": "A magical hood, especially created for combat spells.", + "durability": null, + "weight": "0.8", + "equipment_slot": "0", + "grand_exchange_price": "5661", + "name": "Combat hood 80", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12965", + "bonuses": "0,0,0,3,0,1,1,1,3,0,4,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,10}-{6,20}", + "shop_price": "50", + "examine": "A magical hood, especially created for combat spells.", + "durability": null, + "weight": "0.8", + "equipment_slot": "0", + "grand_exchange_price": "5661", + "name": "Combat hood 60", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12966", + "bonuses": "0,0,0,3,0,1,1,1,3,0,4,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,10}-{6,20}", + "shop_price": "50", + "examine": "A magical hood, especially created for combat spells.", + "durability": null, + "weight": "0.8", + "equipment_slot": "0", + "grand_exchange_price": "5661", + "name": "Combat hood 40", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12967", + "bonuses": "0,0,0,3,0,1,1,1,3,0,4,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,10}-{6,20}", + "shop_price": "50", + "examine": "A magical hood, especially created for combat spells.", + "durability": null, + "weight": "0.8", + "equipment_slot": "0", + "grand_exchange_price": "5661", + "name": "Combat hood 20", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12968", + "bonuses": "0,0,0,3,0,1,1,1,3,0,4,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,10}-{6,20}", + "shop_price": "50", + "ge_buy_limit": "10", + "examine": "A magical hood, especially created for combat spells.", + "durability": null, + "weight": "0.8", + "equipment_slot": "0", + "grand_exchange_price": "6511", + "name": "Combat hood 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12969", + "bonuses": "0,0,0,1,0,0,0,0,1,0,2,0,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "6511", + "durability": null, + "name": "Combat hood 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12970" + }, + { + "requirements": "{1,10}-{6,20}", + "shop_price": "150", + "examine": "A magical robe top, especially made for combat spells.", + "durability": null, + "weight": "4", + "absorb": "2,1,0", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "37700", + "name": "Combat robe top 100", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12971", + "bonuses": "0,0,0,7,0,1,1,1,7,0,8,0,0,0,0" + }, + { + "requirements": "{1,10}-{6,20}", + "shop_price": "150", + "examine": "A magical robe top, especially made for combat spells.", + "durability": null, + "weight": "4", + "absorb": "2,1,0", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "37700", + "name": "Combat robe top 80", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12972", + "bonuses": "0,0,0,7,0,1,1,1,7,0,8,0,0,0,0" + }, + { + "requirements": "{1,10}-{6,20}", + "shop_price": "150", + "examine": "A magical robe top, especially made for combat spells.", + "durability": null, + "weight": "4", + "absorb": "2,1,0", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "37700", + "name": "Combat robe top 60", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12973", + "bonuses": "0,0,0,7,0,1,1,1,7,0,8,0,0,0,0" + }, + { + "requirements": "{1,10}-{6,20}", + "shop_price": "150", + "examine": "A magical robe top, especially made for combat spells.", + "durability": null, + "weight": "4", + "absorb": "2,1,0", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "37700", + "name": "Combat robe top 40", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12974", + "bonuses": "0,0,0,7,0,1,1,1,7,0,8,0,0,0,0" + }, + { + "requirements": "{1,10}-{6,20}", + "shop_price": "150", + "examine": "A magical robe top, especially made for combat spells.", + "durability": null, + "weight": "4", + "absorb": "2,1,0", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "37700", + "name": "Combat robe top 20", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12975", + "bonuses": "0,0,0,7,0,1,1,1,7,0,8,0,0,0,0" + }, + { + "requirements": "{1,10}-{6,20}", + "shop_price": "150", + "ge_buy_limit": "10", + "examine": "A magical robe top, especially made for combat spells.", + "durability": null, + "weight": "4", + "absorb": "2,1,0", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "61500", + "name": "Combat robe top 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12976", + "bonuses": "0,0,0,3,0,0,0,0,3,0,4,0,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "61500", + "durability": null, + "name": "Combat robe top 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12977" + }, + { + "requirements": "{1,10}-{6,20}", + "shop_price": "100", + "examine": "A magical robe bottom, especially created for combat spells.", + "durability": null, + "weight": "3", + "absorb": "1,0,0", + "equipment_slot": "7", + "grand_exchange_price": "50200", + "name": "Combat robe bottom 100", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12978", + "bonuses": "0,0,0,6,0,1,1,1,6,0,7,0,0,0,0" + }, + { + "requirements": "{1,10}-{6,20}", + "shop_price": "100", + "examine": "A magical robe bottom, especially created for combat spells.", + "durability": null, + "weight": "3", + "absorb": "1,0,0", + "equipment_slot": "7", + "grand_exchange_price": "50200", + "name": "Combat robe bottom 80", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12979", + "bonuses": "0,0,0,6,0,1,1,1,6,0,7,0,0,0,0" + }, + { + "requirements": "{1,10}-{6,20}", + "shop_price": "100", + "examine": "A magical robe bottom, especially created for combat spells.", + "durability": null, + "weight": "3", + "absorb": "1,0,0", + "equipment_slot": "7", + "grand_exchange_price": "50200", + "name": "Combat robe bottom 60", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12980", + "bonuses": "0,0,0,6,0,1,1,1,6,0,7,0,0,0,0" + }, + { + "requirements": "{1,10}-{6,20}", + "shop_price": "100", + "examine": "A magical robe bottom, especially created for combat spells.", + "durability": null, + "weight": "3", + "absorb": "1,0,0", + "equipment_slot": "7", + "grand_exchange_price": "50200", + "name": "Combat robe bottom 40", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12981", + "bonuses": "0,0,0,6,0,1,1,1,6,0,7,0,0,0,0" + }, + { + "requirements": "{1,10}-{6,20}", + "shop_price": "100", + "examine": "A magical robe bottom, especially created for combat spells.", + "durability": null, + "weight": "3", + "absorb": "1,0,0", + "equipment_slot": "7", + "grand_exchange_price": "50200", + "name": "Combat robe bottom 20", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12982", + "bonuses": "0,0,0,6,0,1,1,1,6,0,7,0,0,0,0" + }, + { + "requirements": "{1,10}-{6,20}", + "shop_price": "100", + "ge_buy_limit": "10", + "examine": "A magical robe bottom, especially created for combat spells.", + "durability": null, + "weight": "3", + "absorb": "1,0,0", + "equipment_slot": "7", + "grand_exchange_price": "47800", + "name": "Combat robe bottom 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12983", + "bonuses": "0,0,0,2,0,0,0,0,2,0,3,0,0,0,0" + }, + { + "ge_buy_limit": "10", + "grand_exchange_price": "47800", + "durability": null, + "name": "Combat robe bottom 0", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12984" + }, + { + "shop_price": "15", + "examine": "I have to keep my hands safe!", + "grand_exchange_price": "3694", + "durability": null, + "name": "Bronze gauntlets", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12985", + "bonuses": "0,0,0,-1,-1,2,3,3,-1,2,2,0,0,0,0", + "equipment_slot": "9" + }, + { + "shop_price": "15", + "ge_buy_limit": "100", + "examine": "I have to keep my hands safe!", + "grand_exchange_price": "3275", + "durability": null, + "name": "Worn-out bronze gauntlets", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12986", + "bonuses": "0,0,0,-1,-1,0,1,1,-1,0,1,0,0,0,0", + "equipment_slot": "9" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "3275", + "durability": null, + "name": "Worn-out bronze gauntlets", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12987" + }, + { + "shop_price": "30", + "examine": "I have to keep my hands safe!", + "grand_exchange_price": "17339", + "durability": null, + "name": "Iron gauntlets", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12988", + "bonuses": "0,0,0,-1,-1,3,4,4,-1,3,3,0,0,0,0", + "equipment_slot": "9" + }, + { + "shop_price": "30", + "ge_buy_limit": "100", + "examine": "I have to keep my hands safe!", + "grand_exchange_price": "16000", + "durability": null, + "name": "Worn-out iron gauntlets", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12989", + "bonuses": "0,0,0,-1,-1,0,1,1,-1,0,1,0,0,0,0", + "equipment_slot": "9" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "16000", + "durability": null, + "name": "Worn-out iron gauntlets", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12990" + }, + { + "requirements": "{1,5}", + "shop_price": "50", + "examine": "I have to keep my hands safe!", + "grand_exchange_price": "29844", + "durability": null, + "name": "Steel gauntlets", + "tradeable": "false", + "weight": "10", + "archery_ticket_price": "0", + "id": "12991", + "bonuses": "0,0,0,-1,-1,4,5,5,-1,4,4,0,0,0,0", + "equipment_slot": "9" + }, + { + "requirements": "{1,5}", + "shop_price": "50", + "ge_buy_limit": "100", + "examine": "I have to keep my hands safe!", + "durability": null, + "weight": "10", + "equipment_slot": "9", + "grand_exchange_price": "27000", + "name": "Worn-out steel gauntlets", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12992", + "bonuses": "0,0,0,-1,-1,1,1,1,-1,1,1,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "27000", + "durability": null, + "name": "Worn-out steel gauntlets", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12993" + }, + { + "requirements": "{1,10}", + "shop_price": "75", + "examine": "I have to keep my hands safe!", + "grand_exchange_price": "50808", + "durability": null, + "name": "Black gauntlets", + "tradeable": "false", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "12994", + "bonuses": "0,0,0,-1,-1,5,6,6,-1,5,5,0,0,0,0", + "equipment_slot": "9" + }, + { + "requirements": "{1,10}", + "shop_price": "75", + "ge_buy_limit": "100", + "examine": "I have to keep my hands safe!", + "durability": null, + "weight": "0.2", + "equipment_slot": "9", + "grand_exchange_price": "40100", + "name": "Worn-out black gauntlets", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12995", + "bonuses": "0,0,0,-1,-1,1,2,2,-1,1,1,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "40100", + "durability": null, + "name": "Worn-out black gauntlets", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12996" + }, + { + "requirements": "{1,20}", + "shop_price": "100", + "examine": "I have to keep my hands safe!", + "grand_exchange_price": "60064", + "durability": null, + "name": "Mithril gauntlets", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "12997", + "bonuses": "0,0,0,-1,-1,6,7,7,-1,6,6,0,0,0,0", + "equipment_slot": "9" + }, + { + "requirements": "{1,20}", + "shop_price": "100", + "ge_buy_limit": "100", + "examine": "I have to keep my hands safe!", + "grand_exchange_price": "54200", + "durability": null, + "name": "Worn-out mithril gauntlets", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12998", + "bonuses": "0,0,0,-1,-1,2,2,2,-1,2,2,0,0,0,0", + "equipment_slot": "9" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "54200", + "durability": null, + "name": "Worn-out mithril gauntlets", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "12999" + }, + { + "requirements": "{1,30}", + "shop_price": "150", + "examine": "I have to keep my hands safe! Uncharged: A bit worse for wear.", + "grand_exchange_price": "74526", + "durability": null, + "name": "Adamant gauntlets", + "tradeable": "false", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "13000", + "bonuses": "0,0,0,-1,-1,8,9,9,-1,8,8,1,0,0,0", + "equipment_slot": "9" + }, + { + "requirements": "{1,30}", + "shop_price": "150", + "ge_buy_limit": "100", + "examine": "I have to keep my hands safe! Uncharged: A bit worse for wear.", + "durability": null, + "weight": "0.2", + "equipment_slot": "9", + "grand_exchange_price": "71500", + "name": "Worn-out adamant gauntlets", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13001", + "bonuses": "0,0,0,-1,-1,2,3,3,-1,2,2,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "71500", + "durability": null, + "name": "Worn-out adamant gauntlets", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13002" + }, + { + "requirements": "{1,40}", + "shop_price": "200", + "examine": "Fully charged: I have to keep my hands safe! Worn-Out: A bit worse for wear.", + "grand_exchange_price": "95700", + "durability": null, + "name": "Rune gauntlets", + "tradeable": "false", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "13003", + "bonuses": "0,0,0,-1,-1,10,11,11,-1,10,10,2,0,0,0", + "equipment_slot": "9" + }, + { + "requirements": "{1,40}", + "shop_price": "200", + "ge_buy_limit": "100", + "examine": "Fully charged: I have to keep my hands safe! Worn-Out: A bit worse for wear.", + "durability": null, + "weight": "0.2", + "equipment_slot": "9", + "grand_exchange_price": "99900", + "name": "Worn-out rune gauntlets", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13004", + "bonuses": "0,0,0,-1,-1,3,4,4,-1,3,3,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "99900", + "durability": null, + "name": "Worn-out rune gauntlets", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13005" + }, + { + "requirements": "{1,60}", + "shop_price": "300", + "examine": "Uncharged: A bit worse for wear. Charged: I have to keep my hands safe!", + "grand_exchange_price": "214700", + "durability": null, + "name": "Dragon gauntlets", + "tradeable": "false", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "13006", + "bonuses": "0,0,0,-1,-1,14,15,15,-1,14,14,3,0,0,0", + "equipment_slot": "9" + }, + { + "requirements": "{1,60}", + "shop_price": "300", + "ge_buy_limit": "100", + "examine": "Uncharged: A bit worse for wear. Charged: I have to keep my hands safe!", + "durability": null, + "weight": "0.2", + "equipment_slot": "9", + "grand_exchange_price": "166200", + "name": "Worn-out dragon gauntlets", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13007", + "bonuses": "0,0,0,-1,-1,4,5,5,-1,4,4,1,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "166200", + "durability": null, + "name": "Worn-out dragon gauntlets", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13008" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13010" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "shop_price": "5", + "examine": "I need to solve this.", + "durability": null, + "name": "Puzzle box", + "archery_ticket_price": "0", + "id": "13011" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13012" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "shop_price": "5", + "examine": "I need to solve this.", + "durability": null, + "name": "Puzzle box", + "archery_ticket_price": "0", + "id": "13013" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13014" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "shop_price": "5", + "examine": "I need to solve this.", + "durability": null, + "name": "Puzzle box", + "archery_ticket_price": "0", + "id": "13015" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13016" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "shop_price": "5", + "examine": "I need to solve this.", + "durability": null, + "name": "Puzzle box", + "archery_ticket_price": "0", + "id": "13017" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13018" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "shop_price": "5", + "examine": "I need to solve this.", + "durability": null, + "name": "Puzzle box", + "archery_ticket_price": "0", + "id": "13019" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13020" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "shop_price": "5", + "examine": "I need to solve this.", + "durability": null, + "name": "Puzzle box", + "archery_ticket_price": "0", + "id": "13021" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13022" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "shop_price": "5", + "examine": "I need to solve this.", + "durability": null, + "name": "Puzzle box", + "archery_ticket_price": "0", + "id": "13023" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13024" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "shop_price": "5", + "examine": "I need to solve this.", + "durability": null, + "name": "Puzzle box", + "archery_ticket_price": "0", + "id": "13025" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13026" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "shop_price": "5", + "examine": "I need to solve this.", + "durability": null, + "name": "Puzzle box", + "archery_ticket_price": "0", + "id": "13027" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13028" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "shop_price": "5", + "examine": "I need to solve this.", + "durability": null, + "name": "Puzzle box", + "archery_ticket_price": "0", + "id": "13029" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13030" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "shop_price": "5", + "examine": "I need to solve this.", + "durability": null, + "name": "Puzzle box", + "archery_ticket_price": "0", + "id": "13031" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13032" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "shop_price": "5", + "examine": "I need to solve this.", + "durability": null, + "name": "Puzzle box", + "archery_ticket_price": "0", + "id": "13033" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13034" + }, + { + "destroy_message": "You can reclaim this item from the place you found it.", + "shop_price": "5", + "examine": "I need to solve this.", + "durability": null, + "name": "Puzzle box", + "archery_ticket_price": "0", + "id": "13035" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13036" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "13037" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13038" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "13039" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13040" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13041" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13042" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "13043" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13044" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "13045" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13046" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "13047" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13048" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13049" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13050" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13051" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "13052" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13053" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "13054" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13055" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13056" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "13057" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13058" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "13059" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13060" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13061" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "13062" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13063" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "13064" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13065" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "13066" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13067" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13068" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13069" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13070" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13071" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13072" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13074" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13075" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13076" + }, + { + "examine": "I hope there's treasure in it.", + "grand_exchange_price": "3726", + "durability": null, + "name": "Casket", + "tradeable": "true", + "weight": "5", + "archery_ticket_price": "0", + "id": "13077" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13078" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13079" + }, + { + "shop_price": "5000", + "examine": "A set of instructions to be followed.", + "durability": null, + "name": "Clue scroll", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13080" + }, + { + "requirements": "{4,33}", + "ge_buy_limit": "100", + "turn90cw_anim": "821", + "examine": "A black crossbow.", + "walk_anim": "4226", + "durability": null, + "weight": "5", + "turn90ccw_anim": "822", + "attack_speed": "6", + "weapon_interface": "17", + "turn180_anim": "4227", + "equip_audio": "2244", + "render_anim": "175", + "equipment_slot": "3", + "grand_exchange_price": "261", + "stand_anim": "4591", + "attack_audios": "2700,0,0,0", + "tradeable": "true", + "name": "Black crossbow", + "run_anim": "4228", + "archery_ticket_price": "0", + "id": "13081", + "stand_turn_anim": "823", + "bonuses": "0,0,0,0,60,0,0,0,0,0,0,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "grand_exchange_price": "261", + "durability": null, + "name": "Black crossbow", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13082" + }, + { + "requirements": "{4,33}", + "ge_buy_limit": "100", + "examine": "Black crossbow bolts.", + "grand_exchange_price": "55", + "durability": null, + "name": "Black bolts", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13083", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,75", + "equipment_slot": "13" + }, + { + "requirements": "{4,33}", + "ge_buy_limit": "100", + "examine": "Black crossbow bolts.", + "grand_exchange_price": "141", + "durability": null, + "name": "Black bolts(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13084", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,75", + "equipment_slot": "13" + }, + { + "requirements": "{4,33}", + "ge_buy_limit": "100", + "examine": "Black crossbow bolts.", + "grand_exchange_price": "233", + "durability": null, + "name": "Black bolts(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13085", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,75", + "equipment_slot": "13" + }, + { + "requirements": "{4,33}", + "ge_buy_limit": "100", + "examine": "Black crossbow bolts.", + "grand_exchange_price": "1690", + "durability": null, + "name": "Black bolts(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13086", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,75", + "equipment_slot": "13" + }, + { + "requirements": "{0,8}", + "ge_buy_limit": "2", + "examine": "A sapphire-topped cane.", + "durability": null, + "weight": "0.5", + "attack_speed": "5", + "weapon_interface": "10", + "equipment_slot": "3", + "grand_exchange_price": "77000", + "name": "Black cane", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13095", + "bonuses": "0,-2,16,0,0,0,0,0,0,0,0,13,2,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "77000", + "durability": null, + "name": "Black cane", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13096" + }, + { + "requirements": "{0,28}", + "ge_buy_limit": "2", + "examine": "A ruby-topped cane.", + "durability": null, + "weight": "0.5", + "weapon_interface": "10", + "equipment_slot": "3", + "grand_exchange_price": "19100", + "name": "Adamant cane", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13097", + "bonuses": "0,-2,25,0,0,0,0,0,0,0,0,23,3,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "19100", + "durability": null, + "name": "Adamant cane", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13098" + }, + { + "requirements": "{0,38}", + "ge_buy_limit": "2", + "examine": "A diamond-topped cane.", + "durability": null, + "weight": "0.5", + "attack_speed": "5", + "weapon_interface": "10", + "equipment_slot": "3", + "lendable": "true", + "grand_exchange_price": "14500", + "name": "Rune cane", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13099", + "bonuses": "0,-2,39,0,0,0,0,0,0,0,0,36,4,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "14500", + "durability": null, + "name": "Rune cane", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13100" + }, + { + "lendable": "true", + "ge_buy_limit": "2", + "examine": "Comes with a free rabbit!", + "grand_exchange_price": "160400", + "durability": null, + "name": "Top hat", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "13101", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "160400", + "durability": null, + "name": "Top hat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13102" + }, + { + "ge_buy_limit": "2", + "examine": "Official explorer headgear!", + "grand_exchange_price": "85400", + "durability": null, + "name": "Pith helmet", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "13103", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "85400", + "durability": null, + "name": "Pith helmet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13104" + }, + { + "remove_head": "true", + "requirements": "{1,5}", + "ge_buy_limit": "2", + "examine": "Spikier than normal.", + "durability": null, + "weight": "10", + "equipment_slot": "0", + "grand_exchange_price": "38300", + "name": "Spiked helmet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13105", + "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "38300", + "durability": null, + "name": "Spiked helmet", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13106" + }, + { + "remove_head": "true", + "lendable": "true", + "ge_buy_limit": "2", + "examine": "Shear elegance.", + "grand_exchange_price": "296700", + "durability": null, + "name": "Sheep mask", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "13107", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "296700", + "durability": null, + "name": "Sheep mask", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13108" + }, + { + "remove_head": "true", + "lendable": "true", + "ge_buy_limit": "2", + "examine": "I can get the look right, but can I do the waddle too?", + "grand_exchange_price": "633600", + "durability": null, + "name": "Penguin mask", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "13109", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "633600", + "durability": null, + "name": "Penguin mask", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13110" + }, + { + "remove_head": "true", + "lendable": "true", + "ge_buy_limit": "2", + "examine": "The bats have left the belltower.", + "grand_exchange_price": "399000", + "durability": null, + "name": "Bat mask", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "13111", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "399000", + "durability": null, + "name": "Bat mask", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13112" + }, + { + "remove_head": "true", + "lendable": "true", + "ge_buy_limit": "2", + "examine": "It's the year of the cat!", + "grand_exchange_price": "1200000", + "durability": null, + "name": "Cat mask", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13113", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "1200000", + "durability": null, + "name": "Cat mask", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13114" + }, + { + "remove_head": "true", + "lendable": "true", + "ge_buy_limit": "2", + "examine": "I'm hungry like the wolf.", + "grand_exchange_price": "1500000", + "durability": null, + "name": "Wolf mask", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "13115", + "equipment_slot": "0" + }, + { + "ge_buy_limit": "2", + "grand_exchange_price": "1500000", + "durability": null, + "name": "Wolf mask", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13116" + }, + { + "turn90cw_anim": "9053", + "examine": "A fully charged flail.", + "walk_anim": "9051", + "has_special": "true", + "durability": null, + "weight": "5", + "turn90ccw_anim": "9054", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "23", + "turn180_anim": "9052", + "render_anim": "712", + "defence_anim": "9048", + "equipment_slot": "3", + "attack_anims": "9097,9097,9097,9097", + "stand_anim": "9049", + "name": "Ivandis flail (30)", + "run_anim": "9050", + "archery_ticket_price": "0", + "id": "13117", + "stand_turn_anim": "823", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" + }, + { + "turn90cw_anim": "9053", + "examine": "A partially charged flail.", + "walk_anim": "9051", + "has_special": "true", + "durability": null, + "weight": "5", + "turn90ccw_anim": "9054", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "23", + "turn180_anim": "9052", + "render_anim": "712", + "equipment_slot": "3", + "stand_anim": "9049", + "name": "Ivandis flail (29)", + "run_anim": "9050", + "archery_ticket_price": "0", + "id": "13118", + "stand_turn_anim": "823", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" + }, + { + "turn90cw_anim": "9053", + "examine": "A partially charged flail.", + "walk_anim": "9051", + "has_special": "true", + "durability": null, + "turn90ccw_anim": "9054", + "two_handed": "true", + "weapon_interface": "23", + "turn180_anim": "9052", + "render_anim": "712", + "equipment_slot": "3", + "stand_anim": "9049", + "name": "Ivandis flail(28)", + "run_anim": "9050", + "archery_ticket_price": "0", + "id": "13119", + "stand_turn_anim": "823", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" + }, + { + "turn90cw_anim": "9053", + "examine": "A partially charged flail.", + "walk_anim": "9051", + "has_special": "true", + "durability": null, + "weight": "5", + "turn90ccw_anim": "9054", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "23", + "turn180_anim": "9052", + "render_anim": "712", + "equipment_slot": "3", + "stand_anim": "9049", + "name": "Ivandis flail (27)", + "run_anim": "9050", + "archery_ticket_price": "0", + "id": "13120", + "stand_turn_anim": "823", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" + }, + { + "turn90cw_anim": "9053", + "examine": "A partially charged flail.", + "walk_anim": "9051", + "has_special": "true", + "durability": null, + "weight": "5", + "turn90ccw_anim": "9054", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "23", + "turn180_anim": "9052", + "render_anim": "712", + "equipment_slot": "3", + "stand_anim": "9049", + "name": "Ivandis flail (26)", + "run_anim": "9050", + "archery_ticket_price": "0", + "id": "13121", + "stand_turn_anim": "823", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" + }, + { + "turn90cw_anim": "9053", + "examine": "A partially charged flail.", + "walk_anim": "9051", + "has_special": "true", + "durability": null, + "weight": "5", + "turn90ccw_anim": "9054", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "23", + "turn180_anim": "9052", + "render_anim": "712", + "equipment_slot": "3", + "stand_anim": "9049", + "name": "Ivandis flail (25)", + "run_anim": "9050", + "archery_ticket_price": "0", + "id": "13122", + "stand_turn_anim": "823", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" + }, + { + "turn90cw_anim": "9053", + "examine": "A partially charged flail.", + "walk_anim": "9051", + "has_special": "true", + "durability": null, + "weight": "5", + "turn90ccw_anim": "9054", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "23", + "turn180_anim": "9052", + "render_anim": "712", + "equipment_slot": "3", + "stand_anim": "9049", + "name": "Ivandis flail (24)", + "run_anim": "9050", + "archery_ticket_price": "0", + "id": "13123", + "stand_turn_anim": "823", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" + }, + { + "turn90cw_anim": "9053", + "examine": "A partially charged flail.", + "walk_anim": "9051", + "has_special": "true", + "durability": null, + "weight": "5", + "turn90ccw_anim": "9054", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "23", + "turn180_anim": "9052", + "render_anim": "712", + "equipment_slot": "3", + "stand_anim": "9049", + "name": "Ivandis flail (23)", + "run_anim": "9050", + "archery_ticket_price": "0", + "id": "13124", + "stand_turn_anim": "823", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" + }, + { + "turn90cw_anim": "9053", + "examine": "A partially charged flail.", + "walk_anim": "9051", + "has_special": "true", + "durability": null, + "weight": "5", + "turn90ccw_anim": "9054", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "23", + "turn180_anim": "9052", + "render_anim": "712", + "equipment_slot": "3", + "stand_anim": "9049", + "name": "Ivandis flail (22)", + "run_anim": "9050", + "archery_ticket_price": "0", + "id": "13125", + "stand_turn_anim": "823", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" + }, + { + "turn90cw_anim": "9053", + "examine": "A partially charged flail.", + "walk_anim": "9051", + "has_special": "true", + "durability": null, + "weight": "5", + "turn90ccw_anim": "9054", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "23", + "turn180_anim": "9052", + "render_anim": "712", + "equipment_slot": "3", + "stand_anim": "9049", + "name": "Ivandis flail (21)", + "run_anim": "9050", + "archery_ticket_price": "0", + "id": "13126", + "stand_turn_anim": "823", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" + }, + { + "turn90cw_anim": "9053", + "examine": "A partially charged flail.", + "walk_anim": "9051", + "has_special": "true", + "durability": null, + "weight": "5", + "turn90ccw_anim": "9054", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "23", + "turn180_anim": "9052", + "render_anim": "712", + "equipment_slot": "3", + "stand_anim": "9049", + "name": "Ivandis flail (20)", + "run_anim": "9050", + "archery_ticket_price": "0", + "id": "13127", + "stand_turn_anim": "823", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" + }, + { + "turn90cw_anim": "9053", + "examine": "A partially charged flail.", + "walk_anim": "9051", + "has_special": "true", + "durability": null, + "weight": "5", + "turn90ccw_anim": "9054", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "23", + "turn180_anim": "9052", + "render_anim": "712", + "equipment_slot": "3", + "stand_anim": "9049", + "name": "Ivandis flail (19)", + "run_anim": "9050", + "archery_ticket_price": "0", + "id": "13128", + "stand_turn_anim": "823", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" + }, + { + "turn90cw_anim": "9053", + "examine": "A partially charged flail.", + "walk_anim": "9051", + "has_special": "true", + "durability": null, + "weight": "5", + "turn90ccw_anim": "9054", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "23", + "turn180_anim": "9052", + "render_anim": "712", + "equipment_slot": "3", + "stand_anim": "9049", + "name": "Ivandis flail (18)", + "run_anim": "9050", + "archery_ticket_price": "0", + "id": "13129", + "stand_turn_anim": "823", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" + }, + { + "turn90cw_anim": "9053", + "examine": "A partially charged flail.", + "walk_anim": "9051", + "has_special": "true", + "durability": null, + "weight": "5", + "turn90ccw_anim": "9054", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "23", + "turn180_anim": "9052", + "render_anim": "712", + "equipment_slot": "3", + "stand_anim": "9049", + "name": "Ivandis flail (17)", + "run_anim": "9050", + "archery_ticket_price": "0", + "id": "13130", + "stand_turn_anim": "823", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" + }, + { + "turn90cw_anim": "9053", + "examine": "A partially charged flail.", + "walk_anim": "9051", + "has_special": "true", + "durability": null, + "weight": "5", + "turn90ccw_anim": "9054", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "23", + "turn180_anim": "9052", + "render_anim": "712", + "equipment_slot": "3", + "stand_anim": "9049", + "name": "Ivandis flail (16)", + "run_anim": "9050", + "archery_ticket_price": "0", + "id": "13131", + "stand_turn_anim": "823", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" + }, + { + "turn90cw_anim": "9053", + "examine": "A partially charged flail.", + "walk_anim": "9051", + "has_special": "true", + "durability": null, + "weight": "5", + "turn90ccw_anim": "9054", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "23", + "turn180_anim": "9052", + "render_anim": "712", + "equipment_slot": "3", + "stand_anim": "9049", + "name": "Ivandis flail (15)", + "run_anim": "9050", + "archery_ticket_price": "0", + "id": "13132", + "stand_turn_anim": "823", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" + }, + { + "turn90cw_anim": "9053", + "examine": "A partially charged flail.", + "walk_anim": "9051", + "has_special": "true", + "durability": null, + "weight": "5", + "turn90ccw_anim": "9054", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "23", + "turn180_anim": "9052", + "render_anim": "712", + "equipment_slot": "3", + "stand_anim": "9049", + "name": "Ivandis flail (14)", + "run_anim": "9050", + "archery_ticket_price": "0", + "id": "13133", + "stand_turn_anim": "823", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" + }, + { + "turn90cw_anim": "9053", + "examine": "A partially charged flail.", + "walk_anim": "9051", + "has_special": "true", + "durability": null, + "weight": "5", + "turn90ccw_anim": "9054", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "23", + "turn180_anim": "9052", + "render_anim": "712", + "equipment_slot": "3", + "stand_anim": "9049", + "name": "Ivandis flail (13)", + "run_anim": "9050", + "archery_ticket_price": "0", + "id": "13134", + "stand_turn_anim": "823", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" + }, + { + "turn90cw_anim": "9053", + "examine": "A partially charged flail.", + "walk_anim": "9051", + "has_special": "true", + "durability": null, + "weight": "5", + "turn90ccw_anim": "9054", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "23", + "turn180_anim": "9052", + "render_anim": "712", + "equipment_slot": "3", + "stand_anim": "9049", + "name": "Ivandis flail (12)", + "run_anim": "9050", + "archery_ticket_price": "0", + "id": "13135", + "stand_turn_anim": "823", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" + }, + { + "turn90cw_anim": "9053", + "examine": "A partially charged flail.", + "walk_anim": "9051", + "has_special": "true", + "durability": null, + "weight": "5", + "turn90ccw_anim": "9054", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "23", + "turn180_anim": "9052", + "render_anim": "712", + "equipment_slot": "3", + "stand_anim": "9049", + "name": "Ivandis flail (11)", + "run_anim": "9050", + "archery_ticket_price": "0", + "id": "13136", + "stand_turn_anim": "823", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" + }, + { + "turn90cw_anim": "9053", + "examine": "A partially charged flail.", + "walk_anim": "9051", + "has_special": "true", + "durability": null, + "weight": "5", + "turn90ccw_anim": "9054", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "23", + "turn180_anim": "9052", + "render_anim": "712", + "equipment_slot": "3", + "stand_anim": "9049", + "name": "Ivandis flail (10)", + "run_anim": "9050", + "archery_ticket_price": "0", + "id": "13137", + "stand_turn_anim": "823", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" + }, + { + "turn90cw_anim": "9053", + "examine": "A partially charged flail.", + "walk_anim": "9051", + "has_special": "true", + "durability": null, + "weight": "5", + "turn90ccw_anim": "9054", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "23", + "turn180_anim": "9052", + "render_anim": "712", + "equipment_slot": "3", + "stand_anim": "9049", + "name": "Ivandis flail (9)", + "run_anim": "9050", + "archery_ticket_price": "0", + "id": "13138", + "stand_turn_anim": "823", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" + }, + { + "turn90cw_anim": "9053", + "examine": "A partially charged flail.", + "walk_anim": "9051", + "has_special": "true", + "durability": null, + "weight": "5", + "turn90ccw_anim": "9054", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "23", + "turn180_anim": "9052", + "render_anim": "712", + "equipment_slot": "3", + "stand_anim": "9049", + "name": "Ivandis flail (8)", + "run_anim": "9050", + "archery_ticket_price": "0", + "id": "13139", + "stand_turn_anim": "823", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" + }, + { + "turn90cw_anim": "9053", + "examine": "A partially charged flail.", + "walk_anim": "9051", + "has_special": "true", + "durability": null, + "weight": "5", + "turn90ccw_anim": "9054", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "23", + "turn180_anim": "9052", + "render_anim": "712", + "equipment_slot": "3", + "stand_anim": "9049", + "name": "Ivandis flail (7)", + "run_anim": "9050", + "archery_ticket_price": "0", + "id": "13140", + "stand_turn_anim": "823", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" + }, + { + "turn90cw_anim": "9053", + "examine": "A partially charged flail.", + "walk_anim": "9051", + "has_special": "true", + "durability": null, + "weight": "5", + "turn90ccw_anim": "9054", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "23", + "turn180_anim": "9052", + "render_anim": "712", + "equipment_slot": "3", + "stand_anim": "9049", + "name": "Ivandis flail (6)", + "run_anim": "9050", + "archery_ticket_price": "0", + "id": "13141", + "stand_turn_anim": "823", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" + }, + { + "turn90cw_anim": "9053", + "examine": "A partially charged flail - it's nearly out of charges.", + "walk_anim": "9051", + "has_special": "true", + "durability": null, + "weight": "5", + "turn90ccw_anim": "9054", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "23", + "turn180_anim": "9052", + "render_anim": "712", + "equipment_slot": "3", + "stand_anim": "9049", + "name": "Ivandis flail (5)", + "run_anim": "9050", + "archery_ticket_price": "0", + "id": "13142", + "stand_turn_anim": "823", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" + }, + { + "turn90cw_anim": "9053", + "examine": "A partially charged flail - it's nearly out of charges.", + "walk_anim": "9051", + "has_special": "true", + "durability": null, + "weight": "5", + "turn90ccw_anim": "9054", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "23", + "turn180_anim": "9052", + "render_anim": "712", + "equipment_slot": "3", + "stand_anim": "9049", + "name": "Ivandis flail (4)", + "run_anim": "9050", + "archery_ticket_price": "0", + "id": "13143", + "stand_turn_anim": "823", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" + }, + { + "turn90cw_anim": "9053", + "examine": "A partially charged flail - it's nearly out of charges.", + "walk_anim": "9051", + "has_special": "true", + "durability": null, + "weight": "5", + "turn90ccw_anim": "9054", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "23", + "turn180_anim": "9052", + "render_anim": "712", + "equipment_slot": "3", + "stand_anim": "9049", + "name": "Ivandis flail (3)", + "run_anim": "9050", + "archery_ticket_price": "0", + "id": "13144", + "stand_turn_anim": "823", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" + }, + { + "turn90cw_anim": "9053", + "examine": "A partially charged flail - it's nearly out of charges.", + "walk_anim": "9051", + "has_special": "true", + "durability": null, + "weight": "5", + "turn90ccw_anim": "9054", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "23", + "turn180_anim": "9052", + "render_anim": "712", + "equipment_slot": "3", + "stand_anim": "9049", + "name": "Ivandis flail (2)", + "run_anim": "9050", + "archery_ticket_price": "0", + "id": "13145", + "stand_turn_anim": "823", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" + }, + { + "turn90cw_anim": "9053", + "examine": "A partially charged flail - one last charge left.", + "walk_anim": "9051", + "has_special": "true", + "durability": null, + "weight": "5", + "turn90ccw_anim": "9054", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "23", + "turn180_anim": "9052", + "render_anim": "712", + "equipment_slot": "3", + "stand_anim": "9049", + "name": "Ivandis flail (1)", + "run_anim": "9050", + "archery_ticket_price": "0", + "id": "13146", + "stand_turn_anim": "823", + "bonuses": "0,16,11,6,0,2,3,1,6,0,0,26,5,0,0" + }, + { + "examine": "Flail of Ivandis dust.", + "durability": null, + "name": "Flail dust", + "archery_ticket_price": "0", + "id": "13147" + }, + { + "destroy_message": "You found this page in the top floor of Paterdomus temple on an old table.", + "examine": "A page ripped from a book; it looks like a map of some kind.", + "durability": null, + "name": "Book page", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "13149" + }, + { + "destroy_message": "You got this book from a bunk bed in Sanguinesti Myreque base.", + "examine": "A big book of combat techniques.", + "durability": null, + "name": "Combat book", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "13151" + }, + { + "examine": "Used to make a metal chain.", + "durability": null, + "name": "Chain link mould", + "weight": "1", + "archery_ticket_price": "0", + "id": "13153" + }, + { + "examine": "A chain made from mithril and silver.", + "durability": null, + "name": "Silvthril chain", + "weight": "3", + "archery_ticket_price": "0", + "id": "13154" + }, + { + "examine": "A blessed sickle with an emerald recessed into it.", + "durability": null, + "name": "Silver sickle emerald(b)", + "weight": "1", + "archery_ticket_price": "0", + "id": "13155", + "equipment_slot": "3" + }, + { + "examine": "A blessed and enchanted silver sickle with an emerald recessed into it.", + "durability": null, + "name": "Enchanted sickle emerald(b)", + "weight": "1", + "archery_ticket_price": "0", + "id": "13156", + "equipment_slot": "3" + }, + { + "examine": "A Vyrewatch corpse. Just a husk, really.", + "durability": null, + "name": "Vyre corpse", + "weight": "5", + "archery_ticket_price": "0", + "id": "13157" + }, + { + "examine": "An ornate key: precise workmanship and an ethereal glow. (Legacy of Seergaze)", + "durability": null, + "name": "Columbarium key", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "13158" + }, + { + "destroy_message": "You got this key by cremating a Vyrewatch in the Paterdomus Columbarium.", + "examine": "An ornate key: precise workmanship and an ethereal glow. (Legacy of Seergaze)", + "durability": null, + "name": "Ornate tomb key", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "13159" + }, + { + "destroy_message": "You can get another Tome of Experience from Veliaf in Burgh de Rott.", + "examine": "A Tome of Experience (2nd Edition) that awards 2500 XP per chapter.", + "durability": null, + "name": "Tome of xp 2nd ed (3)", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "13160" + }, + { + "destroy_message": "You can get another Tome of Experience from Veliaf in Burgh de Rott.", + "examine": "A Tome of Experience (2nd Edition) that awards 2500 XP per chapter.", + "durability": null, + "name": "Tome of xp 2nd ed (2)", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "13161" + }, + { + "destroy_message": "You can get another Tome of Experience from Veliaf in Burgh de Rott.", + "examine": "A Tome of Experience (2nd Edition) that awards 2500 XP per chapter.", + "durability": null, + "name": "Tome of xp 2nd ed (1)", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "13162" + }, + { + "examine": "A sapphire-topped cane.", + "grand_exchange_price": "115390", + "durability": null, + "name": "Black cane", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "attack_speed": "5", + "weapon_interface": "10", + "id": "13163", + "bonuses": "0,-2,16,0,0,0,0,0,0,0,0,13,2,0,0", + "equipment_slot": "3" + }, + { + "examine": "A ruby-topped cane.", + "grand_exchange_price": "18514", + "durability": null, + "name": "Adamant cane", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "weapon_interface": "10", + "id": "13164", + "bonuses": "0,-2,25,0,0,0,0,0,0,0,0,23,3,0,0", + "equipment_slot": "3" + }, + { + "examine": "A diamond-topped cane.", + "durability": null, + "weight": "0.5", + "attack_speed": "5", + "weapon_interface": "10", + "equipment_slot": "3", + "lendable": "true", + "grand_exchange_price": "15023", + "name": "Rune cane", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13165", + "bonuses": "0,-2,39,0,0,0,0,0,0,0,0,36,4,0,0" + }, + { + "lendable": "true", + "examine": "Comes with a free rabbit!", + "grand_exchange_price": "425919", + "durability": null, + "name": "Top hat", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "13166", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "examine": "Official explorer headgear!", + "grand_exchange_price": "99682", + "durability": null, + "name": "Pith helmet", + "tradeable": "true", + "weight": "0.5", + "archery_ticket_price": "0", + "id": "13167", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "examine": "Spikier than normal.", + "grand_exchange_price": "39643", + "durability": null, + "name": "Spiked helmet", + "tradeable": "true", + "weight": "10", + "archery_ticket_price": "0", + "id": "13168", + "bonuses": "0,0,0,-6,-2,9,10,7,-1,9,3,0,0,0,0", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "lendable": "true", + "examine": "Shear elegance.", + "grand_exchange_price": "313558", + "durability": null, + "name": "Sheep mask", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "13169", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "lendable": "true", + "examine": "I can get the look right, but can I do the waddle too?", + "grand_exchange_price": "609515", + "durability": null, + "name": "Penguin mask", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "13170", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "lendable": "true", + "examine": "The bats have left the belltower.", + "grand_exchange_price": "371616", + "durability": null, + "name": "Bat mask", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "13171", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "lendable": "true", + "examine": "It's the year of the cat!", + "grand_exchange_price": "1066648", + "durability": null, + "name": "Cat mask", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13172", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "lendable": "true", + "examine": "I'm hungry like the wolf.", + "grand_exchange_price": "1303443", + "durability": null, + "name": "Wolf mask", + "tradeable": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "13173", + "equipment_slot": "0" + }, + { + "shop_price": "100", + "examine": "Not for slackers", + "durability": null, + "name": "Blue navy slacks", + "archery_ticket_price": "0", + "id": "13174", + "equipment_slot": "7" + }, + { + "shop_price": "100", + "examine": "Not for slackers", + "durability": null, + "name": "Green navy slacks", + "archery_ticket_price": "0", + "id": "13175", + "equipment_slot": "7" + }, + { + "shop_price": "100", + "examine": "Not for slackers", + "durability": null, + "name": "Red navy slacks", + "archery_ticket_price": "0", + "id": "13176", + "equipment_slot": "7" + }, + { + "shop_price": "100", + "examine": "Not for slackers", + "durability": null, + "name": "Brown navy slacks", + "archery_ticket_price": "0", + "id": "13177", + "equipment_slot": "7" + }, + { + "shop_price": "100", + "examine": "Not for slackers", + "durability": null, + "name": "Black navy slacks", + "archery_ticket_price": "0", + "id": "13178", + "equipment_slot": "7" + }, + { + "shop_price": "100", + "examine": "Not for slackers", + "durability": null, + "name": "Purple navy slacks", + "archery_ticket_price": "0", + "id": "13179", + "equipment_slot": "7" + }, + { + "shop_price": "100", + "examine": "Not for slackers", + "durability": null, + "name": "Grey navy slacks", + "archery_ticket_price": "0", + "id": "13180", + "equipment_slot": "7" + }, + { + "remove_sleeves": "true", + "shop_price": "100", + "examine": "...You can sail the seven seas...", + "durability": null, + "name": "Blue naval shirt", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "13181", + "equipment_slot": "4" + }, + { + "remove_sleeves": "true", + "shop_price": "100", + "examine": "...You can sail the seven seas...", + "durability": null, + "name": "Green naval shirt", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "13182", + "equipment_slot": "4" + }, + { + "remove_sleeves": "true", + "shop_price": "100", + "examine": "...You can sail the seven seas...", + "durability": null, + "name": "Red naval shirt", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "13183", + "equipment_slot": "4" + }, + { + "remove_sleeves": "true", + "shop_price": "100", + "examine": "...You can sail the seven seas...", + "durability": null, + "name": "Brown naval shirt", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "13184", + "equipment_slot": "4" + }, + { + "remove_sleeves": "true", + "shop_price": "100", + "examine": "...You can sail the seven seas...", + "durability": null, + "name": "Black naval shirt", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "13185", + "equipment_slot": "4" + }, + { + "remove_sleeves": "true", + "shop_price": "100", + "examine": "...You can sail the seven seas...", + "durability": null, + "name": "Purple naval shirt", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "13186", + "equipment_slot": "4" + }, + { + "remove_sleeves": "true", + "shop_price": "100", + "examine": "...You can sail the seven seas...", + "durability": null, + "name": "Grey naval shirt", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "13187", + "equipment_slot": "4" + }, + { + "remove_head": "true", + "shop_price": "50", + "examine": "I could never look square in this.", + "durability": null, + "name": "Blue tricorn hat", + "archery_ticket_price": "0", + "id": "13188", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "shop_price": "50", + "examine": "I could never look square in this.", + "durability": null, + "name": "Green tricorn hat", + "archery_ticket_price": "0", + "id": "13189", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "shop_price": "50", + "examine": "I could never look square in this.", + "durability": null, + "name": "Red tricorn hat", + "archery_ticket_price": "0", + "id": "13190", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "shop_price": "50", + "examine": "I could never look square in this.", + "durability": null, + "name": "Brown tricorn hat", + "archery_ticket_price": "0", + "id": "13191", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "shop_price": "50", + "examine": "I could never look square in this.", + "durability": null, + "name": "Black tricorn hat", + "archery_ticket_price": "0", + "id": "13192", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "shop_price": "50", + "examine": "I could never look square in this.", + "durability": null, + "name": "Purple tricorn hat", + "archery_ticket_price": "0", + "id": "13193", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "shop_price": "50", + "examine": "I could never look square in this.", + "durability": null, + "name": "Grey tricorn hat", + "archery_ticket_price": "0", + "id": "13194", + "equipment_slot": "0" + }, + { + "destroy_message": "If you drop this lamp, it will be destroyed. You can obtain another from Dunstan.", + "examine": "I wonder what happens if I rub it.", + "durability": null, + "name": "Mysterious lamp", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13227" + }, + { + "destroy_message": "You can get another net from Professor Arblenap on Ice Mountain.", + "examine": "Professor Arblenap gave you this net to catch the baby icefiends on Ice Mountain.", + "durability": null, + "name": "Icefiend net", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "13230", + "equipment_slot": "3" + }, + { + "examine": "You should give this to Professor Arblenap.", + "durability": null, + "name": "Baby icefiend", + "tradeable": "false", + "destroy": "true", + "weight": "1", + "archery_ticket_price": "0", + "id": "13231", + "equipment_slot": "3" + }, + { + "destroy_message": "It will reappear near the bottom of Ice Mountain.", + "examine": "The remains of the Oracle's tent on Ice Mountain.", + "durability": null, + "name": "Tent", + "tradeable": "false", + "destroy": "true", + "weight": "30", + "archery_ticket_price": "0", + "id": "13232" + }, + { + "destroy_message": "You can get it back by pickpocketing Drorkar again.", + "examine": "You took this key from Drorkar's pocket in the power station. (Perils of Ice Mountain)", + "durability": null, + "name": "Dwarven key", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "id": "13234" + }, + { + "examine": "A plank of oak that has been treated to resist fire.", + "durability": null, + "name": "Treated oak plank", + "weight": "0.8", + "archery_ticket_price": "0", + "id": "13238" + }, + { + "shop_price": "14", + "examine": "Good for detailed crafting.", + "grand_exchange_price": "33", + "durability": null, + "name": "Chisel", + "tradeable": "true", + "weight": "0.4", + "archery_ticket_price": "0", + "id": "13239" + }, + { + "durability": null, + "name": ".", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13240", + "equipment_slot": "5" + }, + { + "examine": "A plank of oak that has been treated to resist fire.", + "durability": null, + "name": "Treated plank", + "weight": "0.8", + "archery_ticket_price": "0", + "id": "13241" + }, + { + "durability": null, + "name": ".", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13242" + }, + { + "examine": "An old stone slab with writing on it.", + "durability": null, + "name": "Stone tablet", + "archery_ticket_price": "0", + "id": "13243" + }, + { + "examine": "A book for those who want to visit the TzHaar city.", + "durability": null, + "name": "Tzhaar tourist guide", + "archery_ticket_price": "0", + "id": "13244" + }, + { + "destroy_message": "You can mine more stone slabs in the TzHaar mine.", + "examine": "A flawed block of obsidian from the Karamja volcano.", + "durability": null, + "name": "Stone slab", + "tradeable": "false", + "destroy": "true", + "weight": "32", + "archery_ticket_price": "0", + "id": "13245" + }, + { + "destroy_message": "You can get more pillars by crafting stone slabs from the TzHaar mine.", + "examine": "A support pillar.", + "durability": null, + "name": "Pillar", + "tradeable": "false", + "destroy": "true", + "weight": "25", + "archery_ticket_price": "0", + "id": "13246" + }, + { + "durability": null, + "name": "Splat", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13247", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "durability": null, + "name": "Splat", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13248", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "durability": null, + "name": "Splat", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13249", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "durability": null, + "name": "Splat", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13250", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You can obtain another from the mummy guardian in the undead slayer's tomb.", + "examine": "A key obtained in Catolax's tomb.", + "durability": null, + "name": "Ranged path key", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13259", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You can obtain another from the mummy guardian in the undead slayer's tomb.", + "examine": "A key obtained in Catolax's tomb.", + "durability": null, + "name": "Magic path key", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13260", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,10}", + "shop_price": "650", + "examine": "You don't want to wear it inside-out.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "remove_beard": "true", + "equipment_slot": "0", + "destroy_message": "Drop", + "name": "Slayer helmet", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13263", + "bonuses": "0,0,0,0,0,30,32,27,0,30,7,0,0,0,0" + }, + { + "destroy_message": "Drop", + "examine": "The remains of a banshee's scream.", + "durability": null, + "name": "Banshee voice", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13276", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "400", + "examine": "More of that crazy Slayer headgear.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "remove_beard": "true", + "equipment_slot": "0", + "destroy_message": "Drop", + "name": "Masked earmuffs", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13277", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "50", + "examine": "For use against turoth and kurasks.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "89", + "name": "Broad arrow heads", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13278", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "50", + "examine": "For use against turoth and kurasks.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "17", + "name": "Unfinished broad bolts", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13279", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "50", + "examine": "For use against turoth and kurasks.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "13", + "destroy_message": "Drop", + "grand_exchange_price": "34", + "name": "Broad-tipped bolts", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13280", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,100" + }, + { + "shop_price": "150", + "examine": "An enchanted ring.", + "durability": null, + "name": "Ring of slaying(8)", + "tradeable": "false", + "destroy": "false", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13281", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "12" + }, + { + "shop_price": "150", + "examine": "An enchanted ring.", + "durability": null, + "name": "Ring of slaying(7)", + "tradeable": "false", + "destroy": "false", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13282", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "12" + }, + { + "shop_price": "150", + "examine": "An enchanted ring.", + "durability": null, + "name": "Ring of slaying(6)", + "tradeable": "false", + "destroy": "false", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13283", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "12" + }, + { + "shop_price": "150", + "examine": "An enchanted ring.", + "durability": null, + "name": "Ring of slaying(5)", + "tradeable": "false", + "destroy": "false", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13284", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "12" + }, + { + "shop_price": "150", + "examine": "An enchanted ring.", + "durability": null, + "name": "Ring of slaying(4)", + "tradeable": "false", + "destroy": "false", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13285", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "12" + }, + { + "shop_price": "150", + "examine": "An enchanted ring.", + "durability": null, + "name": "Ring of slaying(3)", + "tradeable": "false", + "destroy": "false", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13286", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "12" + }, + { + "shop_price": "150", + "examine": "An enchanted ring.", + "durability": null, + "name": "Ring of slaying(2)", + "tradeable": "false", + "destroy": "false", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13287", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "12" + }, + { + "shop_price": "150", + "examine": "An enchanted ring.", + "durability": null, + "name": "Ring of slaying(1)", + "tradeable": "false", + "destroy": "false", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13288", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "12" + }, + { + "turn90cw_anim": "1207", + "examine": "A razor-sharp sword.", + "walk_anim": "1205", + "rare_item": "true", + "turn90ccw_anim": "1208", + "attack_speed": "4", + "turn180_anim": "1206", + "absorb": "0,0,0", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "381,381,390,381", + "grand_exchange_price": "43082", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "13290", + "stand_turn_anim": "823", + "bonuses": "67,62,0,0,0,0,0,0,0,0,0,50,0,0,0", + "requirements": "{0,50}-{18,55}", + "shop_price": "68000", + "durability": null, + "destroy": "false", + "weapon_interface": "5", + "equip_audio": "2248", + "attack_audios": "2517,2517,2500,2517", + "name": "Leaf-bladed sword" + }, + { + "shop_price": "68000", + "examine": "A razor-sharp sword.", + "grand_exchange_price": "43082", + "durability": null, + "name": "Leaf-bladed sword", + "tradeable": "true", + "destroy": "false", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13291" + }, + { + "durability": null, + "name": "Letter", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13292", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "durability": null, + "name": "Plans", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13293", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "If you drop these plans, they will be lost and you will need to see Captain Donnie for a replacement.", + "examine": "A charcoal rubbing taken from 50% Luke.", + "durability": null, + "name": "Charcoal rubbing", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13294", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "If you drop Frank's mark, you will need to see him to get another.", + "examine": "Signature from Frank.", + "durability": null, + "name": "Frank's mark", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13295", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "If you drop these lockpicks, you will need to look under the mattress to get another set.", + "examine": "A device for opening locked doors.", + "durability": null, + "name": "Crude lockpick", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13296", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "examine": "The top of a Custom Officer's uniform.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "4", + "destroy_message": "If you drop this shirt you will need to kill another Customs officer for a replacement.", + "remove_sleeves": "true", + "name": "Customs shirt", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13297", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "If you drop these trousers you will need to kill another Customs officer for a replacement.", + "examine": "The trousers of a Custom Officer's uniform.", + "durability": null, + "name": "Customs trousers", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13298", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "destroy_message": "If you drop this hat you will need to kill another Customs officer for a replacement.", + "examine": "The hat of a Custom Officer's uniform.", + "durability": null, + "name": "Customs hat", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13299", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "destroy_message": "If you drop this file, it and all the marks inside it will be destroyed.", + "examine": "A folder containing all the marks I have gathered.", + "durability": null, + "name": "File", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13300", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "If you drop this file, it and all the marks inside it will be destroyed.", + "examine": "A folder containing all the marks I have gathered.", + "durability": null, + "name": "File", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13301", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "durability": null, + "name": "Brooch", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13302", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "If you drop Izzy's No-Beard's mark, you will need to see him to get another.", + "examine": "Signature from Izzy No-Beard.", + "durability": null, + "name": "Izzy's mark", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13303", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "durability": null, + "name": "Key", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13304", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "If you drop this crowbar, you will need to get another from the chest on the sunken ship.", + "examine": "This could be useful.", + "durability": null, + "name": "Crowbar", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13305", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "If you drop the idol, you will need to go diving to get another replacement.", + "examine": "An idol. It has many heads.", + "durability": null, + "name": "Idol of many heads", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13307", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "If you drop Bill Teach's mark, you will need to see him to get another.", + "examine": "Signature from Bill Teach.", + "durability": null, + "name": "Bill teach's mark", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13308", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "If you drop this paper, you will need to call to the guards for a replacement. ", + "examine": "This is generally used for writing on.", + "durability": null, + "name": "Paper", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13309", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "If you drop this note, you'll need to call the guards for replacement paper.", + "examine": "A written confession.", + "durability": null, + "name": "Confession", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13310", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Note", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13311", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "If you drop this ink, you will need to call to the guards for a replacement.", + "examine": "An empty ink bottle./This is full of ink.", + "durability": null, + "name": "Ink bottle", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13312", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "If you drop this paper you will need to call to the guards to replace it and the ink.", + "examine": "It's got ink all over it.", + "durability": null, + "name": "Inky paper", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13313", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "If you drop this ink, you will need to call to the guards for a replacement.", + "examine": "An empty ink bottle./This is full of ink.", + "durability": null, + "name": "Ink bottle", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13314", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "If you drop this bottle, you will need to call to the guards for a replacement.", + "examine": "It's smashed. I should mind my fingers.", + "durability": null, + "name": "Smashed bottle", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13315", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "examine": "The top part of a prisoner's uniform.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "4", + "destroy_message": "If you drop this top, then you will need to speak to the guards to get it replaced.", + "remove_sleeves": "true", + "name": "Prison uniform top", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13316", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "If you drop these trousers, then you will need to speak to the guards to get it replaced.", + "examine": "The bottom part of a prisoner's uniform.", + "durability": null, + "name": "Prison uniform trousers", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13317", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "examine": "It's covered in fish slop.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "4", + "destroy_message": "If you drop this top, you will need to speak to the guards to get it replaced, then find a way to get stew on it again.", + "remove_sleeves": "true", + "name": "Fishy prison uniform top", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13318", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "If you drop this cup it will be destroyed and you will have to pick up another.", + "examine": "A standard prison-issue tin cup.", + "durability": null, + "name": "Tin cup", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13319", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "3" + }, + { + "destroy_message": "If you drop this cup it will be destroyed and you will have to pick up another.", + "examine": "A standard prison-issue tin cup.", + "durability": null, + "name": "Tin cup", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13320", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "3" + }, + { + "destroy_message": "Destroy", + "examine": "A pipe that belongs in a cannon stand.", + "durability": null, + "name": "Pipe", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13321", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "If you drop this accordion, it will be destroyed and you will have to get another.", + "durability": null, + "name": "Accordion", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13322", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "If you drop this accordion, it will be destroyed and you will have to get another.", + "durability": null, + "name": "Accordion", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13323", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "If you drop this accordion, it will be destroyed and you will have to get another.", + "durability": null, + "name": "Accordion", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13324", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "If you drop this accordion, pipe and inky paper, it will all be destroyed and you will need to get all the items back again.", + "examine": "A very crude vacuum pump.", + "durability": null, + "name": "Vacuum pump", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13325", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "If you drop this, you will lose all the items you put in it, as well as the seagull.", + "examine": "It sounds like a law firm.", + "durability": null, + "name": "Vacuum pump and gull", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13326", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "3" + }, + { + "destroy_message": "If you drop this quill, you will need to talk to the guard for a replacement.", + "examine": "From a bird - can be used for writing.", + "durability": null, + "name": "Quill", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13327", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Unknown ", + "examine": "From a bird - can be used for writing. It has some ink on the tip.", + "durability": null, + "name": "Inky quill", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13328", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "If you drop this file, it and all the marks inside it will be destroyed.", + "examine": "A folder containing all the marks I have gathered.", + "durability": null, + "name": "File", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13329", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "If you drop this file, it and all the marks inside it will be destroyed.", + "examine": "A folder containing all the marks I have gathered.", + "durability": null, + "name": "File", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13330", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "If you drop this dead parrot, there is a chance that bad, bad things will happen to you - unless you see 50 Ships Mufassah for a replacement.", + "examine": "A very dead rotten parrot.", + "durability": null, + "name": "Ex-parrot", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13331", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "If you drop this cage, you will need to see Bill Teach for a replacement.", + "examine": "It feels very cold to the touch.", + "durability": null, + "name": "Magical cage", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13332", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "If you drop this dead parrot in a cage (and who wouldn't) then you will need to see ", + "examine": "A very dead rotten parrot in a magical cage.", + "durability": null, + "name": "Ex-parrot in a magic cage", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13333", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "If you drop the cage, the ex-ex-parrot will escape.", + "examine": "A very alive rotten parrot in a magic cage.", + "durability": null, + "name": "Ex-ex-parrot in a magic cage", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13334", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "durability": null, + "name": "Ex-ex-parrot", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13335", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "durability": null, + "name": "Ex-ex-parrot", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13336", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "50", + "examine": "A pirate impling in a jar.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "If you drop this it will disappear. Are you sure you want to do this?", + "grand_exchange_price": "7346", + "name": "Pirate impling jar", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13337", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "If you drop this it will disappear. Are you sure you want to do this?", + "shop_price": "50", + "grand_exchange_price": "7346", + "durability": null, + "name": "Pirate impling jar", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13338" + }, + { + "remove_head": "true", + "shop_price": "100", + "examine": "A white bandana and a patch for the left eye.", + "durability": null, + "name": "Bandana and eyepatch", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "13339", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "shop_price": "100", + "examine": "A white bandana and a patch for both eyes.", + "durability": null, + "name": "Bandana and eyepatches", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "13340", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "shop_price": "100", + "examine": "A red bandana and a patch for the left eye.", + "durability": null, + "name": "Bandana and eyepatch", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "13341", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "shop_price": "100", + "examine": "A red bandana and a patch for both eyes.", + "durability": null, + "name": "Bandana and eyepatches", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "13342", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "shop_price": "100", + "examine": "A blue bandana and a patch for the left eye.", + "durability": null, + "name": "Bandana and eyepatch", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "13343", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "shop_price": "100", + "examine": "A blue bandana and a patch for both eyes.", + "durability": null, + "name": "Bandana and eyepatches", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "13344", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "shop_price": "100", + "examine": "A brown bandana and a patch for the left eye.", + "durability": null, + "name": "Bandana and eyepatch", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "13345", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "shop_price": "100", + "examine": "A brown bandana and a patch for both eyes.", + "durability": null, + "name": "Bandana and eyepatches", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "13346", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "shop_price": "100", + "examine": "A grey bandana and a patch for the left eye.", + "durability": null, + "name": "Bandana and eyepatch", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "13347", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "shop_price": "100", + "examine": "A grey bandana and a patch for both eyes.", + "durability": null, + "name": "Bandana and eyepatches", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "13348", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "shop_price": "100", + "examine": "A purple bandana and a patch for the left eye.", + "durability": null, + "name": "Bandana and eyepatch", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "13349", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "shop_price": "100", + "examine": "A purple bandana and a patch for both eyes.", + "durability": null, + "name": "Bandana and eyepatches", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "13350", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "shop_price": "100", + "examine": "A orange bandana and a patch for the left eye.", + "durability": null, + "name": "Bandana and eyepatch", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "13351", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "shop_price": "100", + "examine": "A orange bandana and a patch for both eyes.", + "durability": null, + "name": "Bandana and eyepatches", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "13352", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "shop_price": "100", + "examine": "It's dark, and I'm wearing two patches. Hit it!", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "0", + "destroy_message": "Drop", + "name": "Double eyepatches", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13353", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "remove_head": "true", + "shop_price": "100", + "examine": "Two patches and a hat.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "0", + "destroy_message": "Drop", + "name": "Pirate hat and eyepatches", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13354", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "100", + "examine": "A patch for the left eye.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "0", + "destroy_message": "Drop", + "grand_exchange_price": "23485", + "name": "Left eyepatch", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13355", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "100", + "examine": "A patch for the left eye.", + "grand_exchange_price": "23485", + "durability": null, + "name": "Left eyepatch", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13356" + }, + { + "remove_head": "true", + "shop_price": "100", + "examine": "A hat and a patch.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "0", + "destroy_message": "Drop", + "name": "Pirate hat and eyepatch", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13357", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "300", + "ge_buy_limit": "100", + "examine": "A seaworthy grey shirt.", + "durability": null, + "weight": "1", + "absorb": "0,0,0", + "equipment_slot": "4", + "remove_sleeves": "true", + "name": "Stripy pirate shirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13358", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "300", + "durability": null, + "name": "Stripy pirate shirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13359" + }, + { + "shop_price": "300", + "ge_buy_limit": "100", + "examine": "A seaworthy purple shirt.", + "durability": null, + "weight": "1", + "absorb": "0,0,0", + "equipment_slot": "4", + "remove_sleeves": "true", + "name": "Stripy pirate shirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13360", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "300", + "durability": null, + "name": "Stripy pirate shirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13361" + }, + { + "shop_price": "300", + "ge_buy_limit": "100", + "examine": "A seaworthy orange shirt.", + "durability": null, + "weight": "1", + "absorb": "0,0,0", + "equipment_slot": "4", + "remove_sleeves": "true", + "name": "Stripy pirate shirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13362", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "300", + "durability": null, + "name": "Stripy pirate shirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13363" + }, + { + "shop_price": "350", + "ge_buy_limit": "100", + "examine": "A seaworthy pair of grey trousers.", + "durability": null, + "weight": "1", + "absorb": "0,0,0", + "equipment_slot": "7", + "grand_exchange_price": "1", + "name": "Pirate leggings", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13364", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "350", + "grand_exchange_price": "1", + "durability": null, + "name": "Pirate leggings", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13365" + }, + { + "shop_price": "350", + "ge_buy_limit": "100", + "examine": "A seaworthy pair of purple trousers.", + "durability": null, + "weight": "1", + "absorb": "0,0,0", + "equipment_slot": "7", + "grand_exchange_price": "1", + "name": "Pirate leggings", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13366", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "350", + "grand_exchange_price": "1", + "durability": null, + "name": "Pirate leggings", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13367" + }, + { + "shop_price": "350", + "ge_buy_limit": "100", + "examine": "A seaworthy pair of orange trousers.", + "durability": null, + "weight": "1", + "absorb": "0,0,0", + "equipment_slot": "7", + "grand_exchange_price": "1", + "name": "Pirate leggings", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13368", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "350", + "grand_exchange_price": "1", + "durability": null, + "name": "Pirate leggings", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13369" + }, + { + "remove_head": "true", + "shop_price": "100", + "examine": "A grey bandana.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "0", + "destroy_message": "Drop", + "name": "Bandana", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13370", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "100", + "durability": null, + "name": "Bandana", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13371" + }, + { + "remove_head": "true", + "shop_price": "100", + "examine": "A purple bandana.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "0", + "destroy_message": "Drop", + "name": "Bandana", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13372", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "100", + "durability": null, + "name": "Bandana", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13373" + }, + { + "remove_head": "true", + "shop_price": "100", + "examine": "An orange bandana.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "0", + "destroy_message": "Drop", + "name": "Bandana", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13374", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "100", + "durability": null, + "name": "Bandana", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13375" + }, + { + "remove_head": "true", + "shop_price": "100", + "examine": "A purple bandana and a patch for the right eye.", + "durability": null, + "name": "Bandana and eyepatch", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "13376", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "shop_price": "100", + "examine": "A orange bandana and a patch for the right eye.", + "durability": null, + "name": "Bandana and eyepatch", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "13377", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "shop_price": "100", + "examine": "A grey bandana and a patch for the right eye.", + "durability": null, + "name": "Bandana and eyepatch", + "tradeable": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "13378", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "destroy_message": "Destroy", + "examine": "Some rock fragments.", + "durability": null, + "name": "Rock fragments", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13379", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "If you drop the letter, it will be destroyed and you'll need to see Bill Teach for another.", + "examine": "Note from Teach to Brass Hand Harry.", + "durability": null, + "name": "Introduction letter", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13380", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "The hand is already broken and dropping it will destroy it completely. You will need to see Brass Hand Harry for a replacement.", + "examine": "One of many broken hands.", + "durability": null, + "name": "Broken hand", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13381", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "The hand is already broken and dropping it will destroy it completely. You will need to see Brass Hand Harry for a replacement.", + "examine": "One of many broken hands.", + "durability": null, + "name": "Broken hand", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13382", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "The hand is already broken and dropping it will destroy it completely. You will need to see Brass Hand Harry for a replacement.", + "examine": "One of many broken hands.", + "durability": null, + "name": "Broken hand", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13383", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "The hand is already broken and dropping it will destroy it completely. You will need to see Brass Hand Harry for a replacement.", + "examine": "One of many broken hands.", + "durability": null, + "name": "Broken hand", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13384", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "The hand is already broken and dropping it will destroy it completely. You will need to see Brass Hand Harry for a replacement.", + "examine": "One of many broken hands.", + "durability": null, + "name": "Broken hand", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13385", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "examine": "Wall beast fingers in a white fern sauce.", + "durability": null, + "name": "Fingers", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13386", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "This hand part is small and delicate, and dropping it here will lose it. If you lose it, you will need to see Brass Hand Harry for a replacement.", + "examine": "A brass thumb.", + "durability": null, + "name": "Thumb", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13387", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "durability": null, + "name": "Hand", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13388", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "This hand part is small and delicate, and dropping it here will lose it. If you lose it, you will need to see Brass Hand Harry for a replacement.", + "examine": "A brass wrist.", + "durability": null, + "name": "Wrist", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13389", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "This hand part is small and delicate, and dropping it here will lose it. If you lose it, you will need to see Brass Hand Harry for a replacement.", + "examine": "A brass brace.", + "durability": null, + "name": "Brace", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13390", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "If you drop this hand, you will destroy it and you will have to remake it from parts that Brass Hand Harry has.", + "examine": "A completed brass hand.", + "durability": null, + "name": "Brass hand", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13391", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "If you drop this ink pad, you will lose it and will need to see Brass Hand Harry for a replacement.", + "examine": "It's soaked with ink.", + "durability": null, + "name": "Ink pad", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13392", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "If you drop this hand, you will destroy it and you will have to remake it from parts that Brass Hand Harry has.", + "examine": "An inky brass hand.", + "durability": null, + "name": "Inky hand", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13393", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "If you drop this paper, you will need to call to the guards for a replacement. ", + "examine": "This is generally used for writing on.", + "durability": null, + "name": "Paper", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13394", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "If you drop Brass Hand Harry's mark, it will be destroyed and you need to see him to get another.", + "examine": "Handprint from Brass Hand Harry.", + "durability": null, + "name": "Brass hand harry's mark", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13395", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "examine": "Makes me itch.", + "durability": null, + "name": "Fake beard", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13396", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "destroy_message": "If you drop this disguise you will need to see Captain Braindeath for a replacement.", + "examine": "It looks like someone has sneezed in it.", + "durability": null, + "name": "Fake moustache and nose", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13397", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "destroy_message": "If you drop this disguise you will need to see Captain Braindeath for a replacement.", + "examine": "Why is the monocle nailed to it?", + "durability": null, + "name": "Fake monocle, moustache and nose", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13398", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "examine": "You can barely see where it connected to the mop handle.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "0", + "destroy_message": "If you drop this disguise you will need to see Captain Braindeath for a replacement.", + "name": "Curly wig", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13399", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "remove_head": "true", + "examine": "It looks like it is part-dog, part-mould.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "0", + "destroy_message": "If you drop this disguise you will need to see Captain Braindeath for a replacement.", + "name": "Straight wig", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "13400", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "If you drop this order for 'rum' you will need to speak to the Rusty Anchor barman to get another.", + "examine": "An order simply for 'rum'.", + "durability": null, + "name": "Order", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13401", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "If you drop Captain Braindeath's mark, you will need to speak to him to get another.", + "examine": "Signature of Captain Braindeath.", + "durability": null, + "name": "Braindeath's mark", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13402", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "300", + "examine": "A replica tinderbox made of solid gold.", + "durability": null, + "name": "Golden tinderbox", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13403", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "examine": "A bow from a darker dimension.", + "has_special": "true", + "durability": null, + "destroy": "true", + "attack_speed": "9", + "two_handed": "true", + "weapon_interface": "16", + "absorb": "0,0,0", + "equip_audio": "3738", + "render_anim": "303", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "86850", + "attack_audios": "3731,0,0,0", + "name": "Dark bow", + "archery_ticket_price": "0", + "id": "13405", + "bonuses": "0,0,0,0,95,0,0,0,0,0,0,0,0,0,0" + }, + { + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "1", + "absorb": "0,0,0", + "render_anim": "28", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "59171", + "name": "Ancient staff", + "archery_ticket_price": "0", + "id": "13406", + "bonuses": "10,-1,40,15,0,2,3,1,15,0,5,50,0,-1,10" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "This helmet is worn by archers.", + "grand_exchange_price": "46334", + "durability": null, + "name": "Archer helm", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13407", + "absorb": "0,3,1", + "bonuses": "-5,-5,-5,-5,6,6,8,10,6,6,0,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "This helmet is worn by berserkers.", + "grand_exchange_price": "45978", + "durability": null, + "name": "Berserker helm", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13408", + "absorb": "1,0,3", + "bonuses": "0,0,0,-5,-5,31,29,33,0,30,7,3,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "This helm is worn by warriors.", + "grand_exchange_price": "45664", + "durability": null, + "name": "Warrior helm", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13409", + "absorb": "1,0,3", + "bonuses": "0,5,0,-5,-5,31,33,29,0,30,7,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "This helm is worn by farseers.", + "grand_exchange_price": "45989", + "durability": null, + "name": "Farseer helm", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13410", + "absorb": "3,1,0", + "bonuses": "-5,-5,-5,6,-5,8,10,12,6,0,7,0,0,0,0" + }, + { + "destroy_message": "Drop", + "examine": "Protective headwear made from crabs. Better than it sounds.", + "grand_exchange_price": "20378", + "durability": null, + "name": "Rock-shell helm", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13411", + "absorb": "1,0,3", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,6,0,0,0,0" + }, + { + "destroy_message": "Drop", + "examine": "A sturdy body armour made from rock crab pieces.", + "grand_exchange_price": "41788", + "durability": null, + "name": "Rock-shell plate", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13412", + "absorb": "3,0,6", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,30,0,0,0,0" + }, + { + "destroy_message": "Drop", + "examine": "Some tough leggings made from rock crab parts.", + "grand_exchange_price": "37139", + "durability": null, + "name": "Rock-shell legs", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13413", + "absorb": "2,0,4", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,10,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "A helm fit for any Fremennik ranger.", + "grand_exchange_price": "37724", + "durability": null, + "name": "Spined helm", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13414", + "absorb": "0,3,1", + "bonuses": "0,-6,-6,-6,6,6,6,6,6,0,6,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "A constant reminder that I'm above a Dagannoth in the food chain.", + "grand_exchange_price": "5773", + "durability": null, + "name": "Spined body", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13415", + "absorb": "0,6,3", + "bonuses": "0,0,0,-15,15,40,32,45,20,40,30,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Stylish leg armour for rangers with a lingering smell of raw fish...", + "grand_exchange_price": "2696", + "durability": null, + "name": "Spined chaps", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13416", + "absorb": "0,4,2", + "bonuses": "0,0,0,-10,8,22,16,24,8,22,10,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Make your foes cower by wearing a skull as a helmet!", + "grand_exchange_price": "39060", + "durability": null, + "name": "Skeletal helm", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13417", + "absorb": "3,1,0", + "bonuses": "0,0,0,2,-2,10,9,11,3,0,6,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "The bones in this armour seems to vibrate with a magic quality...", + "grand_exchange_price": "26289", + "durability": null, + "name": "Skeletal top", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13418", + "absorb": "6,3,0", + "bonuses": "0,0,0,8,-10,35,25,42,15,0,30,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "A superior set of strengthened slacks for any self respecting seer.", + "grand_exchange_price": "24591", + "durability": null, + "name": "Skeletal bottoms", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13419", + "absorb": "4,2,0", + "bonuses": "0,0,0,6,-7,22,20,24,10,0,10,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Some finely crafted Fremennik boots, made from spined dagannoth hide.", + "grand_exchange_price": "158181", + "durability": null, + "name": "Spined boots", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13420", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,1,1,0,0,0,1,0,0,0,0" + }, + { + "destroy_message": "Drop", + "examine": "Some Fremennik boots, made from the shards of a rock crab's shell.", + "grand_exchange_price": "1358", + "durability": null, + "name": "Rock-shell boots", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13421", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,1,1,0,0,1,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Some finely crafted Fremennik boots, made from the bones of a Wallasalki.", + "grand_exchange_price": "7788", + "durability": null, + "name": "Skeletal boots", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13422", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,1,1,0,0,1,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Fremennik gloves stitched together from spined dagannoth hide.", + "grand_exchange_price": "3027", + "durability": null, + "name": "Spined gloves", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13423", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,1,2,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "examine": "Fremennik gloves stitched together from rock crab shell shards.", + "grand_exchange_price": "12839", + "durability": null, + "name": "Rock-shell gloves", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13424", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Fremennik gloves stitched together from wallasalki bones fragments.", + "grand_exchange_price": "25838", + "durability": null, + "name": "Skeletal gloves", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13425", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,1,2,0,0,0,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "A mysterious ring that can fill the wearer with magical power...", + "grand_exchange_price": "799703", + "durability": null, + "name": "Seers ring", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13426", + "absorb": "0,0,0", + "bonuses": "0,0,0,4,0,0,0,0,4,0,0,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "A fabled ring that improves the wearer's skill with a bow...", + "grand_exchange_price": "483521", + "durability": null, + "name": "Archers ring", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13427", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,4,0,0,0,0,4,0,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "A legendary ring once worn by Fremennik warriors.", + "grand_exchange_price": "361302", + "durability": null, + "name": "Warrior ring", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13428", + "absorb": "0,0,0", + "bonuses": "0,4,0,0,0,0,4,0,0,0,0,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "A ring reputed to bring out a berserk fury in its wearer.", + "grand_exchange_price": "963418", + "durability": null, + "name": "Berserker ring", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13429", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,4,0,0,0,4,0,0,0" + }, + { + "examine": "A two-handed dragon sword.", + "has_special": "true", + "durability": null, + "destroy": "true", + "attack_speed": "7", + "two_handed": "true", + "weapon_interface": "7", + "absorb": "0,0,0", + "equip_audio": "2248", + "render_anim": "124", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "1024000", + "name": "Dragon 2h sword", + "archery_ticket_price": "0", + "id": "13430", + "bonuses": "-4,92,80,-4,0,0,0,0,0,-1,0,93,0,0,0" + }, + { + "shop_price": "20", + "examine": "Useful for catching crayfish.", + "durability": null, + "destroy": "false", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "25", + "name": "Crayfish cage", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13431", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "20", + "examine": "Swap this note at any bank for the equivalent item.", + "grand_exchange_price": "25", + "durability": null, + "name": "Crayfish cage", + "tradeable": "true", + "destroy": "false", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13432" + }, + { + "shop_price": "5", + "examine": "Some cooked crayfish. Eat it to heal.", + "durability": null, + "destroy": "false", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "32", + "name": "Crayfish", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13433", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "5", + "examine": "Swap this note at any bank for the equivalent item.", + "grand_exchange_price": "32", + "durability": null, + "name": "Crayfish", + "tradeable": "true", + "destroy": "false", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13434" + }, + { + "shop_price": "5", + "examine": "I should try cooking this. Used in Cooking (1).", + "durability": null, + "destroy": "false", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "41", + "name": "Raw crayfish", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13435", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "5", + "examine": "Swap this note at any bank for the equivalent item.", + "grand_exchange_price": "41", + "durability": null, + "name": "Raw crayfish", + "tradeable": "true", + "destroy": "false", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13436" + }, + { + "shop_price": "1", + "durability": null, + "name": "Burnt crayfish", + "tradeable": "true", + "archery_ticket_price": "0", + "destroy": "false", + "attack_speed": "4", + "id": "13437", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "1", + "examine": "Swap this note at any bank for the equivalent item.", + "durability": null, + "name": "Burnt crayfish", + "tradeable": "true", + "archery_ticket_price": "0", + "destroy": "false", + "attack_speed": "4", + "id": "13438" + }, + { + "examine": "I wonder what happens if I rub it.", + "durability": null, + "name": "Antique lamp", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13439", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "examine": "This is a bag of runes for Sir Vant.", + "durability": null, + "name": "Bag of runes", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13440", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "A very powerful onyx amulet.", + "grand_exchange_price": "2285210", + "durability": null, + "name": "Amulet of fury", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13442", + "absorb": "0,0,0", + "bonuses": "10,10,10,10,10,15,15,15,15,15,15,8,0,5,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "A cape woven of obsidian plates.", + "grand_exchange_price": "56575", + "durability": null, + "name": "Obsidian cape", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13443", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,9,9,9,9,9,9,0,0,0,0" + }, + { + "examine": "A weapon from the Abyss.", + "has_special": "true", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "11", + "absorb": "0,0,0", + "equip_audio": "2249", + "render_anim": "1578", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "114775", + "name": "Abyssal whip", + "archery_ticket_price": "0", + "id": "13444", + "bonuses": "0,82,0,0,0,0,0,0,0,0,0,82,0,0,0" + }, + { + "examine": "Simplicity is the best weapon.", + "has_special": "true", + "durability": null, + "destroy": "true", + "attack_speed": "7", + "two_handed": "true", + "weapon_interface": "10", + "absorb": "0,0,0", + "render_anim": "27", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "29584", + "name": "Granite maul", + "archery_ticket_price": "0", + "id": "13445", + "bonuses": "0,0,81,0,0,0,0,0,0,0,0,79,0,0,0" + }, + { + "examine": "I wonder what happens if I rub it.", + "durability": null, + "name": "Antique lamp", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13446", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "examine": "I wonder what happens if I rub it.", + "durability": null, + "name": "Antique lamp", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13447", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "examine": "I wonder what happens if I rub it.", + "durability": null, + "name": "Antique lamp", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13448", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Protects your head and looks impressive too.", + "grand_exchange_price": "5756658", + "durability": null, + "name": "Dragon full helm", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13449", + "absorb": "2,0,4", + "bonuses": "0,0,0,-6,-2,45,48,41,-1,46,12,0,0,0,0" + }, + { + "examine": "A beautiful, heavy sword.", + "has_special": "true", + "durability": null, + "destroy": "true", + "attack_speed": "6", + "two_handed": "true", + "weapon_interface": "7", + "absorb": "0,0,0", + "equip_audio": "2248", + "render_anim": "1579", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "7767458", + "name": "Armadyl godsword", + "archery_ticket_price": "0", + "id": "13450", + "bonuses": "0,132,80,0,0,0,0,0,0,0,0,132,0,8,0" + }, + { + "examine": "A brutally heavy sword.", + "has_special": "true", + "durability": null, + "destroy": "true", + "attack_speed": "6", + "two_handed": "true", + "weapon_interface": "7", + "absorb": "0,0,0", + "equip_audio": "2248", + "render_anim": "1579", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "1504919", + "name": "Bandos godsword", + "archery_ticket_price": "0", + "id": "13451", + "bonuses": "0,132,80,0,0,0,0,0,0,0,0,132,0,8,0" + }, + { + "examine": "A gracious, heavy sword.", + "has_special": "true", + "durability": null, + "destroy": "true", + "attack_speed": "6", + "two_handed": "true", + "weapon_interface": "7", + "absorb": "0,0,0", + "equip_audio": "2248", + "render_anim": "1579", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "34966317", + "name": "Saradomin godsword", + "archery_ticket_price": "0", + "id": "13452", + "bonuses": "0,132,80,0,0,0,0,0,0,0,0,132,0,8,0" + }, + { + "examine": "A terrifying, heavy sword.", + "has_special": "true", + "durability": null, + "destroy": "true", + "attack_speed": "6", + "two_handed": "true", + "weapon_interface": "7", + "absorb": "0,0,0", + "equip_audio": "2248", + "render_anim": "1579", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "2132037", + "name": "Zamorak godsword", + "archery_ticket_price": "0", + "id": "13453", + "bonuses": "0,132,80,0,0,0,0,0,0,0,0,132,0,8,0" + }, + { + "examine": "An evil spear.", + "has_special": "true", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "two_handed": "true", + "weapon_interface": "14", + "absorb": "0,0,0", + "render_anim": "1581", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "2070507", + "name": "Zamorakian spear", + "archery_ticket_price": "0", + "id": "13454", + "bonuses": "85,65,65,0,0,13,13,12,0,13,0,75,0,2,0" + }, + { + "examine": "A helmet of great craftmanship.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,5,2", + "equip_audio": "2240", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "3732060", + "name": "Armadyl helmet", + "archery_ticket_price": "0", + "id": "13455", + "bonuses": "-5,-5,-5,-5,10,6,6,10,10,8,12,0,0,1,0" + }, + { + "examine": "A chestplate of great craftsmanship", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,10,5", + "equip_audio": "2239", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "9628666", + "name": "Armadyl chestplate", + "archery_ticket_price": "0", + "id": "13456", + "bonuses": "-7,-7,-7,-15,33,56,48,61,70,57,52,0,0,1,0" + }, + { + "examine": "A chainskirt of great craftsmanship.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,7,3", + "equip_audio": "2242", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "9754868", + "name": "Armadyl plateskirt", + "archery_ticket_price": "0", + "id": "13457", + "bonuses": "-6,-6,-6,-10,20,32,26,34,40,33,25,0,0,1,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "A sturdy chestplate.", + "grand_exchange_price": "6460055", + "durability": null, + "name": "Bandos chestplate", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13458", + "absorb": "4,0,9", + "bonuses": "0,0,0,-15,-10,98,93,105,-6,133,52,4,0,1,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "A sturdy pair of tassets.", + "grand_exchange_price": "4228256", + "durability": null, + "name": "Bandos tassets", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13459", + "absorb": "3,0,6", + "bonuses": "0,0,0,-21,-7,71,63,66,-4,93,25,2,0,1,0" + }, + { + "examine": "Some sturdy boots.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equip_audio": "2237", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "1259091", + "name": "Bandos boots", + "archery_ticket_price": "0", + "id": "13460", + "bonuses": "0,0,0,-5,-3,17,18,19,0,0,15,0,0,1,0" + }, + { + "examine": "The incredible blade of an Icyene.", + "has_special": "true", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "two_handed": "true", + "weapon_interface": "7", + "absorb": "0,0,0", + "equip_audio": "2248", + "render_anim": "1579", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "850151", + "name": "Saradomin sword", + "archery_ticket_price": "0", + "id": "13461", + "bonuses": "0,82,60,0,0,0,0,0,0,0,0,82,0,2,0" + }, + { + "examine": "These will protect my feet.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equip_audio": "2237", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "17336", + "name": "Dragon boots", + "archery_ticket_price": "0", + "id": "13462", + "bonuses": "0,0,0,-3,-1,16,17,18,0,0,15,4,0,0,0" + }, + { + "examine": "I wonder what happens if I rub it.", + "durability": null, + "name": "Antique lamp", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13463", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You can get another by talking about jobs with citizens and tutors around Lumbridge.", + "examine": "This reminds me of my current job and who set me to the task.", + "durability": null, + "name": "Task list", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13464", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "examine": "A powerful dagger.", + "has_special": "true", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "5", + "absorb": "0,0,0", + "equip_audio": "2248", + "defence_anim": "397", + "attack_anims": "396,396,395,396", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "16744", + "attack_audios": "2517,2517,2500,2517", + "name": "Dragon dagger", + "archery_ticket_price": "0", + "id": "13465", + "bonuses": "40,25,-4,1,0,0,0,0,1,0,0,40,0,0,0" + }, + { + "shop_price": "1", + "examine": "A picture of a lady called Elena.", + "has_special": "true", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equip_audio": "2248", + "defence_anim": "397", + "attack_anims": "396,396,395,396", + "destroy_message": "Drop", + "attack_audios": "2517,2517,2500,2517", + "name": "Dragon dagger(p)", + "archery_ticket_price": "0", + "id": "13466", + "bonuses": "40,25,-4,1,0,0,0,0,1,0,0,40,0,0,0" + }, + { + "shop_price": "1", + "examine": "A picture of a lady called Elena.", + "has_special": "true", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equip_audio": "2248", + "defence_anim": "397", + "attack_anims": "396,396,395,396", + "destroy_message": "Drop", + "attack_audios": "2517,2517,2500,2517", + "name": "Dragon dagger(p+)", + "archery_ticket_price": "0", + "id": "13467", + "bonuses": "40,25,-4,1,0,0,0,0,1,0,0,40,0,0,0" + }, + { + "shop_price": "1", + "examine": "A picture of a lady called Elena.", + "has_special": "true", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equip_audio": "2248", + "defence_anim": "397", + "attack_anims": "396,396,395,396", + "destroy_message": "Drop", + "attack_audios": "2517,2517,2500,2517", + "name": "Dragon dagger(p++)", + "archery_ticket_price": "0", + "id": "13468", + "bonuses": "40,25,-4,1,0,0,0,0,1,0,0,40,0,0,0" + }, + { + "examine": "A powerful axe.", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "weapon_interface": "2", + "absorb": "0,0,0", + "equip_audio": "2229", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "7263", + "name": "Rune axe", + "archery_ticket_price": "0", + "id": "13469", + "bonuses": "-2,26,24,0,0,0,1,0,0,0,0,29,0,0,0" + }, + { + "examine": "A very powerful axe.", + "has_special": "true", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "weapon_interface": "2", + "absorb": "0,0,0", + "equip_audio": "2229", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "3794577", + "name": "Dragon axe", + "archery_ticket_price": "0", + "id": "13470", + "bonuses": "-2,38,32,0,0,0,1,0,0,0,0,42,0,0,0" + }, + { + "examine": "A vicious looking axe.", + "durability": null, + "destroy": "true", + "attack_speed": "6", + "weapon_interface": "2", + "absorb": "0,0,0", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "23993", + "name": "Rune battleaxe", + "archery_ticket_price": "0", + "id": "13471", + "bonuses": "-2,48,43,0,0,0,0,0,0,-1,0,64,0,0,0" + }, + { + "requirements": "{0,60}", + "examine": "A vicious looking axe.", + "has_special": "true", + "durability": null, + "destroy": "true", + "weight": "2.7", + "attack_speed": "6", + "weapon_interface": "2", + "absorb": "0,0,0", + "render_anim": "2586", + "defence_anim": "397", + "attack_anims": "395,395,401,395", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "123019", + "attack_audios": "2498,2498,2497,2498", + "name": "Dragon battleaxe", + "archery_ticket_price": "0", + "id": "13472", + "bonuses": "-2,70,65,0,0,0,0,0,0,-1,0,85,0,0,0" + }, + { + "examine": "I don't think it's intended for joinery.", + "durability": null, + "destroy": "true", + "attack_speed": "6", + "weapon_interface": "10", + "absorb": "0,0,0", + "equip_audio": "2233", + "render_anim": "1430", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "24357", + "name": "Rune warhammer", + "archery_ticket_price": "0", + "id": "13473", + "bonuses": "-4,-4,53,-4,0,0,0,0,0,0,0,48,0,0,0" + }, + { + "examine": "A razor-sharp longsword", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "weapon_interface": "5", + "absorb": "0,0,0", + "render_anim": "1582", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "18420", + "name": "Rune longsword", + "archery_ticket_price": "0", + "id": "13474", + "bonuses": "38,47,-2,0,0,0,3,2,0,0,0,49,0,0,0" + }, + { + "examine": "A very powerful sword.", + "has_special": "true", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "weapon_interface": "5", + "absorb": "0,0,0", + "render_anim": "1582", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "58355", + "name": "Dragon longsword", + "archery_ticket_price": "0", + "id": "13475", + "bonuses": "58,69,-2,0,0,0,3,2,0,0,0,71,0,0,0" + }, + { + "examine": "A vicious, curved sword.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "6", + "absorb": "0,0,0", + "render_anim": "1582", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "14690", + "name": "Rune scimitar", + "archery_ticket_price": "0", + "id": "13476", + "bonuses": "7,45,-2,0,0,0,1,0,0,0,0,44,0,0,0" + }, + { + "examine": "A vicious, curved sword.", + "has_special": "true", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "6", + "absorb": "0,0,0", + "equip_audio": "2248", + "render_anim": "1928", + "attack_anims": "390,390,381,390", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "60405", + "name": "Dragon scimitar", + "archery_ticket_price": "0", + "id": "13477", + "bonuses": "8,67,-2,0,0,0,1,0,0,0,0,66,0,0,0" + }, + { + "examine": "A dragon halberd.", + "has_special": "true", + "durability": null, + "destroy": "true", + "attack_speed": "7", + "two_handed": "true", + "weapon_interface": "15", + "absorb": "0,0,0", + "equip_audio": "2247", + "render_anim": "28", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "200189", + "name": "Dragon halberd", + "archery_ticket_price": "0", + "id": "13478", + "bonuses": "70,95,0,-4,0,-1,4,5,0,0,0,89,0,0,0" + }, + { + "requirements": "{0,60}", + "examine": "A spiky mace.", + "has_special": "true", + "durability": null, + "destroy": "true", + "weight": "1.8", + "attack_speed": "5", + "weapon_interface": "8", + "absorb": "0,0,0", + "equip_audio": "2246", + "defence_anim": "397", + "attack_anims": "390,390,381,390", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "28817", + "attack_audios": "2508,2508,25092508", + "name": "Dragon mace", + "archery_ticket_price": "0", + "id": "13479", + "bonuses": "40,-2,60,0,0,0,0,0,0,0,0,55,0,5,0" + }, + { + "examine": "Used for mining.", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "weapon_interface": "4", + "absorb": "0,0,0", + "equip_audio": "2232", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "18546", + "name": "Rune pickaxe", + "archery_ticket_price": "0", + "id": "13480", + "bonuses": "26,-2,24,0,0,0,1,0,0,0,0,29,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "A series of connected metal rings.", + "grand_exchange_price": "2280904", + "durability": null, + "name": "Dragon chainbody", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13481", + "absorb": "4,0,9", + "bonuses": "0,0,0,-15,0,81,93,98,-3,82,50,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Provides excellent protection.", + "grand_exchange_price": "38062", + "durability": null, + "name": "Rune platebody", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13482", + "absorb": "3,0,6", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0" + }, + { + "examine": "Made from 100% real dragonhide.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,6,3", + "equip_audio": "2241", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "4373", + "name": "Green d'hide body", + "archery_ticket_price": "0", + "id": "13483", + "bonuses": "0,0,0,-20,15,40,32,45,20,40,40,0,0,0,0" + }, + { + "examine": "Made from 100% real dragonhide.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,6,3", + "equip_audio": "2241", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "5266", + "name": "Blue d'hide body", + "archery_ticket_price": "0", + "id": "13484", + "bonuses": "0,0,0,-15,20,45,37,50,30,45,45,0,0,0,0" + }, + { + "examine": "Made from 100% real dragonhide.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,6,3", + "equip_audio": "2241", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "6276", + "name": "Red d'hide body", + "archery_ticket_price": "0", + "id": "13485", + "bonuses": "0,0,0,-15,25,50,42,55,40,50,50,0,0,0,0" + }, + { + "examine": "Made from 100% real dragonhide.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,6,3", + "equip_audio": "2241", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "7619", + "name": "Black d'hide body", + "archery_ticket_price": "0", + "id": "13486", + "bonuses": "0,0,0,-15,30,55,47,60,50,55,55,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "These look pretty heavy.", + "grand_exchange_price": "37355", + "durability": null, + "name": "Rune platelegs", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13487", + "absorb": "2,0,4", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Looks pretty heavy.", + "grand_exchange_price": "160755", + "durability": null, + "name": "Dragon platelegs", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13488", + "absorb": "3,0,6", + "bonuses": "0,0,0,-21,-7,68,66,63,-4,65,20,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Designer leg protection.", + "grand_exchange_price": "37248", + "durability": null, + "name": "Rune plateskirt", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13489", + "absorb": "2,0,4", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "This looks pretty heavy.", + "grand_exchange_price": "161006", + "durability": null, + "name": "Dragon plateskirt", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13490", + "absorb": "3,0,6", + "bonuses": "0,0,0,-21,-7,68,66,63,-4,65,20,0,0,0,0" + }, + { + "examine": "100% real dragonhide.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,4,2", + "equip_audio": "2241", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "2037", + "name": "Green d'hide chaps", + "archery_ticket_price": "0", + "id": "13491", + "bonuses": "0,0,0,-10,8,22,16,24,8,22,15,0,0,0,0" + }, + { + "examine": "Made from 100% real dragonhide.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,5,2", + "equip_audio": "2241", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "2352", + "name": "Blue d'hide chaps", + "archery_ticket_price": "0", + "id": "13492", + "bonuses": "0,0,0,-10,11,25,19,27,14,25,20,0,0,0,0" + }, + { + "examine": "Made from 100% real dragonhide.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,6,3", + "equip_audio": "2241", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "2761", + "name": "Red d'hide chaps", + "archery_ticket_price": "0", + "id": "13493", + "bonuses": "0,0,0,-10,14,28,22,30,20,28,25,0,0,0,0" + }, + { + "examine": "Made from 100% real dragonhide.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,7,3", + "equip_audio": "2241", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "3377", + "name": "Black d'hide chaps", + "archery_ticket_price": "0", + "id": "13494", + "bonuses": "0,0,0,-10,17,31,25,33,28,31,30,0,0,0,0" + }, + { + "examine": "Makes the wearer pretty intimidating.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "2,0,4", + "equip_audio": "2240", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "59676", + "name": "Dragon med helm", + "archery_ticket_price": "0", + "id": "13495", + "bonuses": "0,0,0,-3,-1,33,35,32,-1,34,10,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "A full face helmet.", + "grand_exchange_price": "20388", + "durability": null, + "name": "Rune full helm", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13496", + "absorb": "1,0,3", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0" + }, + { + "examine": "Made from 100% real dragonhide.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equip_audio": "2241", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "1208", + "name": "Green d'hide vamb", + "archery_ticket_price": "0", + "id": "13497", + "bonuses": "0,0,0,-10,8,3,2,4,2,0,3,0,0,0,0" + }, + { + "examine": "Made from 100% real dragonhide.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equip_audio": "2241", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "1488", + "name": "Blue d'hide vamb", + "archery_ticket_price": "0", + "id": "13498", + "bonuses": "0,0,0,-10,9,4,3,5,4,0,4,0,0,0,0" + }, + { + "examine": "Vambraces made from 100% real dragonhide.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equip_audio": "2241", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "1714", + "name": "Red d'hide vamb", + "archery_ticket_price": "0", + "id": "13499", + "bonuses": "0,0,0,-10,10,5,4,6,6,0,5,0,0,0,0" + }, + { + "examine": "Vambraces made from 100% real dragonhide.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equip_audio": "2241", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "2208", + "name": "Black d'hide vamb", + "archery_ticket_price": "0", + "id": "13500", + "bonuses": "0,0,0,-10,11,6,5,7,8,0,6,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "A wooden helmet.", + "grand_exchange_price": "5210", + "durability": null, + "name": "Splitbark helm", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13501", + "absorb": "3,1,0", + "bonuses": "0,0,0,3,-2,10,9,11,3,0,7,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Provides good protection.", + "grand_exchange_price": "27106", + "durability": null, + "name": "Splitbark body", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13502", + "absorb": "6,3,0", + "bonuses": "0,0,0,10,-10,36,26,42,15,0,40,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "These should protect my legs.", + "grand_exchange_price": "56050", + "durability": null, + "name": "Splitbark legs", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13503", + "absorb": "4,2,0", + "bonuses": "0,0,0,7,-7,22,20,25,10,0,15,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "These should keep my hands safe.", + "grand_exchange_price": "2442", + "durability": null, + "name": "Splitbark gauntlets", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13504", + "absorb": "0,0,0", + "bonuses": "0,0,0,2,-1,3,2,4,2,0,3,0,0,0,0" + }, + { + "examine": "Wooden foot protection.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equip_audio": "2237", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "6845", + "name": "Splitbark boots", + "archery_ticket_price": "0", + "id": "13505", + "bonuses": "0,0,0,2,-1,3,2,4,2,0,9,0,0,0,0" + }, + { + "examine": "An ancient and powerful looking Dragon Square shield.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "5,0,11", + "equip_audio": "2245", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "328356", + "name": "Dragon sq shield", + "archery_ticket_price": "0", + "id": "13506", + "bonuses": "0,0,0,-6,-2,50,52,48,0,50,50,0,0,0,0" + }, + { + "examine": "A large metal shield.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "3,0,7", + "equip_audio": "2245", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "31885", + "name": "Rune kiteshield", + "archery_ticket_price": "0", + "id": "13507", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Blue: A magical hat. ", + "grand_exchange_price": "1", + "durability": null, + "name": "Mystic hat", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13508", + "absorb": "3,1,0", + "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "The upper half of a magical robe.", + "grand_exchange_price": "1", + "durability": null, + "name": "Mystic robe top", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13509", + "absorb": "3,1,0", + "bonuses": "0,0,0,20,0,0,0,0,20,0,20,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "The lower half of a magical robe.", + "grand_exchange_price": "1", + "durability": null, + "name": "Mystic robe bottom", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13510", + "absorb": "4,2,0", + "bonuses": "0,0,0,15,0,0,0,0,15,0,15,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Bright/Dark magical gloves.", + "grand_exchange_price": "1", + "durability": null, + "name": "Mystic gloves", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13511", + "absorb": "0,0,0", + "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Magical boots.", + "grand_exchange_price": "1", + "durability": null, + "name": "Mystic boots", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13512", + "absorb": "0,0,0", + "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Blue: A magical hat. ", + "grand_exchange_price": "1", + "durability": null, + "name": "Mystic hat", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13513", + "absorb": "3,1,0", + "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "The upper half of a magical robe.", + "grand_exchange_price": "1", + "durability": null, + "name": "Mystic robe top", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13514", + "absorb": "3,1,0", + "bonuses": "0,0,0,20,0,0,0,0,20,0,20,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "The lower half of a magical robe.", + "grand_exchange_price": "1", + "durability": null, + "name": "Mystic robe bottom", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13515", + "absorb": "4,2,0", + "bonuses": "0,0,0,15,0,0,0,0,15,0,15,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Bright/Dark magical gloves.", + "grand_exchange_price": "1", + "durability": null, + "name": "Mystic gloves", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13516", + "absorb": "0,0,0", + "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Magical boots.", + "grand_exchange_price": "1", + "durability": null, + "name": "Mystic boots", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13517", + "absorb": "0,0,0", + "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Blue: A magical hat. ", + "grand_exchange_price": "1", + "durability": null, + "name": "Mystic hat", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13518", + "absorb": "3,1,0", + "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "The upper half of a magical robe.", + "grand_exchange_price": "1", + "durability": null, + "name": "Mystic robe top", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13519", + "absorb": "3,1,0", + "bonuses": "0,0,0,20,0,0,0,0,20,0,20,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "The lower half of a magical robe.", + "grand_exchange_price": "1", + "durability": null, + "name": "Mystic robe bottom", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13520", + "absorb": "4,2,0", + "bonuses": "0,0,0,15,0,0,0,0,15,0,15,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Bright/Dark magical gloves.", + "grand_exchange_price": "1", + "durability": null, + "name": "Mystic gloves", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13521", + "absorb": "0,0,0", + "bonuses": "0,0,0,3,0,0,0,0,3,0,0,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Magical boots.", + "grand_exchange_price": "1", + "durability": null, + "name": "Mystic boots", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13522", + "absorb": "0,0,0", + "bonuses": "0,0,0,3,0,0,0,0,3,0,3,0,0,0,0" + }, + { + "examine": "A nice sturdy bow made out of maple.", + "durability": null, + "destroy": "true", + "attack_speed": "6", + "two_handed": "true", + "weapon_interface": "16", + "absorb": "0,0,0", + "equip_audio": "2244", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "193", + "name": "Maple longbow", + "archery_ticket_price": "0", + "id": "13523", + "bonuses": "0,0,0,0,29,0,0,0,0,0,0,0,0,0,0" + }, + { + "examine": "A shortbow made out of maple, still effective.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "two_handed": "true", + "weapon_interface": "16", + "absorb": "0,0,0", + "equip_audio": "2244", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "111", + "name": "Maple shortbow", + "archery_ticket_price": "0", + "id": "13524", + "bonuses": "0,0,0,0,29,0,0,0,0,0,0,0,0,0,0" + }, + { + "examine": "A nice sturdy bow made out of yew.", + "durability": null, + "destroy": "true", + "attack_speed": "6", + "two_handed": "true", + "weapon_interface": "16", + "absorb": "0,0,0", + "equip_audio": "2244", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "486", + "name": "Yew longbow", + "archery_ticket_price": "0", + "id": "13525", + "bonuses": "0,0,0,0,47,0,0,0,0,0,0,0,0,0,0" + }, + { + "examine": "A shortbow made out of yew, still effective.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "two_handed": "true", + "weapon_interface": "16", + "absorb": "0,0,0", + "equip_audio": "2244", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "253", + "name": "Yew shortbow", + "archery_ticket_price": "0", + "id": "13526", + "bonuses": "0,0,0,0,47,0,0,0,0,0,0,0,0,0,0" + }, + { + "examine": "A nice sturdy magical bow.", + "has_special": "true", + "durability": null, + "destroy": "true", + "attack_speed": "6", + "two_handed": "true", + "weapon_interface": "16", + "absorb": "0,0,0", + "equip_audio": "2244", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "1211", + "name": "Magic longbow", + "archery_ticket_price": "0", + "id": "13527", + "bonuses": "0,0,0,0,69,0,0,0,0,0,0,0,0,0,0" + }, + { + "examine": "Short and magical, but still effective.", + "has_special": "true", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "two_handed": "true", + "weapon_interface": "16", + "absorb": "0,0,0", + "equip_audio": "2244", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "655", + "name": "Magic shortbow", + "archery_ticket_price": "0", + "id": "13528", + "bonuses": "0,0,0,0,69,0,0,0,0,0,0,0,0,0,0" + }, + { + "examine": "An ancient Fremennik bow that was once used to battle the Moon Clan.", + "has_special": "true", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "16", + "absorb": "0,0,0", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "21698", + "name": "Seercull", + "archery_ticket_price": "0", + "id": "13529", + "bonuses": "0,0,0,0,69,0,0,0,0,0,0,0,0,0,0" + }, + { + "examine": "A runite crossbow.", + "durability": null, + "destroy": "true", + "attack_speed": "6", + "weapon_interface": "17", + "absorb": "0,0,0", + "equip_audio": "2244", + "render_anim": "175", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "8890", + "name": "Rune crossbow", + "archery_ticket_price": "0", + "id": "13530", + "bonuses": "0,0,0,0,90,0,0,0,0,0,0,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "A nice hat from a cracker.", + "grand_exchange_price": "1696744720", + "durability": null, + "name": "Red partyhat", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13531", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "A nice hat from a cracker.", + "grand_exchange_price": "1314730495", + "durability": null, + "name": "Yellow partyhat", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13532", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "A nice hat from a cracker.", + "grand_exchange_price": "2147483647", + "durability": null, + "name": "Blue partyhat", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13533", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "A nice hat from a cracker.", + "grand_exchange_price": "1481913809", + "durability": null, + "name": "Green partyhat", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13534", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "A nice hat from a cracker.", + "grand_exchange_price": "1248900588", + "durability": null, + "name": "Purple partyhat", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13535", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "A nice hat from a cracker.", + "grand_exchange_price": "2147473360", + "durability": null, + "name": "White partyhat", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13536", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "It's a Santa hat.", + "grand_exchange_price": "130433327", + "durability": null, + "name": "Santa hat", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13537", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Aaaarrrghhh ... I'm a monster.", + "grand_exchange_price": "104671288", + "durability": null, + "name": "Green h'ween mask", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13538", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Aaaarrrghhh ... I'm a monster.", + "grand_exchange_price": "127720943", + "durability": null, + "name": "Blue h'ween mask", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13539", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Aaaarrrghhh ... I'm a monster.", + "grand_exchange_price": "171640098", + "durability": null, + "name": "Red h'ween mask", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13540", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "examine": "A powerful bow made from willow.", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "16", + "absorb": "0,0,0", + "render_anim": "28", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "2606", + "name": "Willow comp bow", + "archery_ticket_price": "0", + "id": "13541", + "bonuses": "0,0,0,0,22,0,0,0,0,0,0,0,0,0,0" + }, + { + "examine": "A powerful bow made from yew wood.", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "16", + "absorb": "0,0,0", + "render_anim": "28", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "588", + "name": "Yew comp bow", + "archery_ticket_price": "0", + "id": "13542", + "bonuses": "0,0,0,0,49,0,0,0,0,0,0,0,0,0,0" + }, + { + "examine": "A powerful bow made from magic wood.", + "has_special": "true", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "16", + "absorb": "0,0,0", + "render_anim": "28", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "1345", + "name": "Magic comp bow", + "archery_ticket_price": "0", + "id": "13543", + "bonuses": "0,0,0,0,71,0,0,0,0,0,0,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Ancient range protection crafted from white dragonhide.", + "grand_exchange_price": "74503559", + "durability": null, + "name": "3rd age range top", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13544", + "absorb": "0,6,3", + "bonuses": "0,0,0,-15,30,55,47,60,60,55,52,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Fabulously ancient range protection crafted from white dragonhide.", + "grand_exchange_price": "47837515", + "durability": null, + "name": "3rd age range legs", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13545", + "absorb": "0,4,2", + "bonuses": "0,0,0,-10,17,31,25,33,30,31,25,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Ancient range protection crafted from white dragonhide.", + "grand_exchange_price": "9746895", + "durability": null, + "name": "3rd age range coif", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13546", + "absorb": "0,3,1", + "bonuses": "0,0,0,-2,9,4,7,10,5,8,12,0,0,0,0" + }, + { + "examine": "Fabulously ancient range protection crafted from white dragonhide.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equip_audio": "2241", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "6826420", + "name": "3rd age vambraces", + "archery_ticket_price": "0", + "id": "13547", + "bonuses": "0,0,0,-11,11,6,5,7,9,0,5,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Ancient mage protection enchanted in the Third-Age.", + "grand_exchange_price": "138719269", + "durability": null, + "name": "3rd age robe top", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13548", + "absorb": "4,2,0", + "bonuses": "0,0,0,24,0,0,0,0,24,0,24,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Ancient mage protection enchanted in the Third-Age.", + "grand_exchange_price": "89961678", + "durability": null, + "name": "3rd age robe", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13549", + "absorb": "4,2,0", + "bonuses": "0,0,0,19,0,0,0,0,19,0,20,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Ancient mage protection enchanted in the Third-Age.", + "grand_exchange_price": "14976830", + "durability": null, + "name": "3rd age mage hat", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13550", + "absorb": "2,1,0", + "bonuses": "0,0,0,8,0,0,0,0,8,0,12,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Ancient mage protection enchanted in the Third-Age.", + "grand_exchange_price": "35019596", + "durability": null, + "name": "3rd age amulet", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13551", + "absorb": "0,0,0", + "bonuses": "0,0,0,15,0,0,0,0,10,0,0,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Ancient armour beaten from magical silver.", + "grand_exchange_price": "244180930", + "durability": null, + "name": "3rd age platelegs", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13552", + "absorb": "3,0,6", + "bonuses": "0,0,0,-25,-2,78,76,83,-5,75,25,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Ancient armour beaten from magical silver.", + "grand_exchange_price": "266509014", + "durability": null, + "name": "3rd age platebody", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13553", + "absorb": "4,0,9", + "bonuses": "0,0,0,-20,0,96,108,113,-4,97,52,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Ancient armour beaten from magical silver.", + "grand_exchange_price": "50697678", + "durability": null, + "name": "3rd age full helmet", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13554", + "absorb": "2,0,4", + "bonuses": "0,0,0,-5,-2,47,49,43,-3,48,12,0,0,0,0" + }, + { + "examine": "Ancient armour beaten from magical silver.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "5,0,11", + "equip_audio": "2245", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "91262203", + "name": "3rd age kiteshield", + "archery_ticket_price": "0", + "id": "13555", + "bonuses": "0,0,0,-10,-4,63,65,61,-3,63,60,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Lightweight boots ideal for rangers.", + "grand_exchange_price": "6253527", + "durability": null, + "name": "Ranger boots", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13556", + "absorb": "0,0,0", + "bonuses": "0,0,0,-10,8,2,3,4,2,0,10,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Slightly magical boots.", + "grand_exchange_price": "388955", + "durability": null, + "name": "Wizard boots", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13557", + "absorb": "0,0,0", + "bonuses": "0,0,0,4,0,0,0,0,4,0,0,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Endorsed by Robin Hood.", + "grand_exchange_price": "1962571", + "durability": null, + "name": "Robin hood hat", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13558", + "absorb": "0,0,0", + "bonuses": "0,0,0,-10,8,4,6,8,4,4,7,0,0,0,0" + }, + { + "destroy_message": "You will have talk to Explorer Jack in Lumbridge if you destroy this one.", + "shop_price": "350", + "examine": "A Lumbridge explorer's ring.", + "durability": null, + "name": "Explorer's ring 1", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13560", + "absorb": "0,0,0", + "bonuses": "0,0,0,1,0,0,0,0,1,0,0,0,1,0,0", + "equipment_slot": "12" + }, + { + "destroy_message": "You will have talk to ", + "shop_price": "350", + "examine": "A Lumbridge explorer's ring.", + "durability": null, + "name": "Explorer's ring 2", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13561", + "absorb": "0,0,0", + "bonuses": "0,0,0,1,0,0,0,0,1,0,0,0,1,0,0", + "equipment_slot": "12" + }, + { + "destroy_message": "You will need to obtain a new ring from Ned in Draynor if you destroy this one.", + "shop_price": "350", + "examine": "A Lumbridge explorer's ring.", + "durability": null, + "name": "Explorer's ring 3", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13562", + "absorb": "0,0,0", + "bonuses": "0,0,0,1,0,0,0,0,1,0,0,0,1,0,0", + "equipment_slot": "12" + }, + { + "shop_price": "38", + "examine": "An occasionally edible mushroom.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "100", + "name": "Button mushroom", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13563", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "38", + "examine": "An occasionally edible mushroom.", + "grand_exchange_price": "100", + "durability": null, + "name": "Button mushroom", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13564" + }, + { + "durability": null, + "name": "Doll", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13565", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You may be able to find a new ring near where Summer stood outside the wilderness wall.", + "examine": "This magical ring once belonged to Summer's mother.", + "durability": null, + "name": "Jennica's ring", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13566", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "12" + }, + { + "destroy_message": "Drop", + "examine": "Logs cut from a cursed magic tree.", + "durability": null, + "name": "Cursed magic logs", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13567", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "examine": "Logs cut from a cursed magic tree.", + "durability": null, + "name": "Cursed magic logs", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13568" + }, + { + "destroy_message": "Hopefully, Jorral will be able to return them.", + "examine": "Notes on how to use the enchanted key.", + "durability": null, + "name": "Enchanted key notes", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13569", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "examine": "Useful for mixing things.", + "grand_exchange_price": "106", + "durability": null, + "name": "Bowl", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13570", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "examine": "It's a bucket of milk.", + "grand_exchange_price": "177", + "durability": null, + "name": "Bucket of milk", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13571", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "examine": "A fresh herb.", + "grand_exchange_price": "595", + "durability": null, + "name": "Clean guam", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13572", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You'll have to start again from stratch.", + "examine": "A bowlful of bees' precious product.", + "durability": null, + "name": "Bowl of honey", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13573", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You'll have to start again from stratch.", + "examine": "A bowlful of milk and honey.", + "durability": null, + "name": "Bowl of milk and honey", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13574", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You'll have to start again from stratch.", + "examine": "A bowl full of milk, honey and guam.", + "durability": null, + "name": "Bowl of milk, honey and guam", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13575", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Hopefully, the family has more papyrus and charcoal.", + "examine": "Your best impression of a map of 2009Scape.", + "durability": null, + "name": "Map of 2009Scape", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13576", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "examine": "Used for making notes.", + "grand_exchange_price": "290", + "durability": null, + "name": "Papyrus", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13577", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "examine": "A lump of charcoal.", + "grand_exchange_price": "296", + "durability": null, + "name": "Charcoal", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13578", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "examine": "A slightly muddy spade. ", + "grand_exchange_price": "130", + "durability": null, + "name": "Spade", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13579", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "examine": "A plant pot filled with soil.", + "durability": null, + "name": "Plant pot", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13580", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "examine": "A seedling has been sown in this plant pot.", + "durability": null, + "name": "Pear tree seedling", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13581", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "examine": "A seedling has been sown in this plant pot.", + "durability": null, + "name": "Mango tree seedling", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13582", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "examine": "A seedling has been sown in this plant pot.", + "durability": null, + "name": "Quince tree seedling", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13583", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "examine": "A seedling has been sown in this plant pot.", + "durability": null, + "name": "Lemon tree seedling", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13584", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "examine": "A seedling has been sown in this plant pot.", + "durability": null, + "name": "Avocado tree seedling", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13585", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "examine": "A seedling has been sown in this plant pot.", + "durability": null, + "name": "Plum tree seedling", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13586", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "4", + "examine": "I can grind things for potions in this.", + "grand_exchange_price": "169", + "durability": null, + "name": "Pestle and mortar", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13587", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "examine": "One of the ingredients for making fish food.", + "grand_exchange_price": "5", + "durability": null, + "name": "Ground guam", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13588", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "2", + "examine": "It's an empty bucket. ", + "grand_exchange_price": "39", + "durability": null, + "name": "Bucket", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13589", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "examine": "It seems to change temperature as I walk. (Making History)", + "durability": null, + "name": "Enchanted key", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13591", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Hopefully, you can find another.", + "examine": "Some ladies jewellery.", + "durability": null, + "name": "A brooch", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13592", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You will not get another chance to read the book!", + "examine": "It's falling apart, but full of knowledge.", + "durability": null, + "name": "Old tome", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13593", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "100", + "examine": "A tablet containing a magic spell.", + "durability": null, + "name": "Runecrafting guild teleport", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13598", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "100", + "examine": "A tablet containing a magic spell.", + "durability": null, + "name": "Air altar teleport", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13599", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "100", + "examine": "A tablet containing a magic spell.", + "durability": null, + "name": "Mind altar teleport", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13600", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "100", + "examine": "A tablet containing a magic spell.", + "durability": null, + "name": "Water altar teleport", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13601", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "100", + "examine": "A tablet containing a magic spell.", + "durability": null, + "name": "Earth altar teleport", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13602", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "100", + "examine": "A tablet containing a magic spell.", + "durability": null, + "name": "Fire altar teleport", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13603", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "100", + "examine": "A tablet containing a magic spell.", + "durability": null, + "name": "Body altar teleport", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13604", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "100", + "examine": "A tablet containing a magic spell.", + "durability": null, + "name": "Cosmic altar teleport", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13605", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "100", + "examine": "A tablet containing a magic spell.", + "durability": null, + "name": "Chaos altar teleport", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13606", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "100", + "examine": "A tablet containing a magic spell.", + "durability": null, + "name": "Nature altar teleport", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13607", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "100", + "examine": "A tablet containing a magic spell.", + "durability": null, + "name": "Law altar teleport", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13608", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "100", + "examine": "A tablet containing a magic spell.", + "durability": null, + "name": "Death altar teleport", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13609", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "100", + "examine": "A tablet containing a magic spell.", + "durability": null, + "name": "Blood altar teleport", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13610", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "100", + "examine": "A tablet containing a magic spell.", + "durability": null, + "name": "Astral altar teleport", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13611", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "20", + "examine": "Comes with goggles, for extra safety while Runecrafting.", + "durability": null, + "name": "Runecrafter hat", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13612", + "absorb": "0,0,0", + "bonuses": "0,0,0,3,0,3,3,3,3,3,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "destroy_message": "Drop", + "shop_price": "20", + "examine": "Comes with goggles, for extra safety while Runecrafting.", + "durability": null, + "name": "Runecrafter hat", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13613", + "absorb": "0,0,0", + "bonuses": "0,0,0,3,0,3,3,3,3,3,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "shop_price": "75", + "examine": "Heavy duty wizard robes.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "4", + "destroy_message": "Drop", + "remove_sleeves": "true", + "name": "Runecrafter robe", + "archery_ticket_price": "0", + "id": "13614", + "bonuses": "0,0,0,5,0,5,5,5,5,5,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "75", + "examine": "Comes with goggles, for extra safety while Runecrafting.", + "durability": null, + "name": "Runecrafter hat", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13615", + "absorb": "0,0,0", + "bonuses": "0,0,0,3,0,3,3,3,3,3,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "destroy_message": "Drop", + "shop_price": "75", + "examine": "Comes with goggles, for extra safety while Runecrafting.", + "durability": null, + "name": "Runecrafter hat", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13616", + "absorb": "0,0,0", + "bonuses": "0,0,0,3,0,3,3,3,3,3,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "destroy_message": "Drop", + "shop_price": "75", + "examine": "A heavy-duty wizard robe.", + "durability": null, + "name": "Runecrafter skirt", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13617", + "absorb": "0,0,0", + "bonuses": "0,0,0,4,0,4,4,4,4,4,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "destroy_message": "Drop", + "shop_price": "75", + "examine": "Essence can be rough on the hands", + "durability": null, + "name": "Runecrafter gloves", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13618", + "absorb": "0,0,0", + "bonuses": "0,0,0,2,0,2,2,2,2,2,0,0,0,0,0", + "equipment_slot": "9" + }, + { + "shop_price": "75", + "examine": "Heavy duty wizard robes.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "4", + "destroy_message": "Drop", + "remove_sleeves": "true", + "name": "Runecrafter robe", + "archery_ticket_price": "0", + "id": "13619", + "bonuses": "0,0,0,5,0,5,5,5,5,5,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "75", + "examine": "Comes with goggles, for extra safety while Runecrafting.", + "durability": null, + "name": "Runecrafter hat", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13620", + "absorb": "0,0,0", + "bonuses": "0,0,0,3,0,3,3,3,3,3,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "destroy_message": "Drop", + "shop_price": "75", + "examine": "Comes with goggles, for extra safety while Runecrafting.", + "durability": null, + "name": "Runecrafter hat", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13621", + "absorb": "0,0,0", + "bonuses": "0,0,0,3,0,3,3,3,3,3,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "destroy_message": "Drop", + "shop_price": "75", + "examine": "A heavy-duty wizard robe.", + "durability": null, + "name": "Runecrafter skirt", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13622", + "absorb": "0,0,0", + "bonuses": "0,0,0,4,0,4,4,4,4,4,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "destroy_message": "Drop", + "shop_price": "75", + "examine": "Essence can be rough on the hands", + "durability": null, + "name": "Runecrafter gloves", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13623", + "absorb": "0,0,0", + "bonuses": "0,0,0,2,0,2,2,2,2,2,0,0,0,0,0", + "equipment_slot": "9" + }, + { + "shop_price": "75", + "examine": "Heavy duty wizard robes.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "4", + "destroy_message": "Drop", + "remove_sleeves": "true", + "name": "Runecrafter robe", + "archery_ticket_price": "0", + "id": "13624", + "bonuses": "0,0,0,5,0,5,5,5,5,5,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "75", + "examine": "Comes with goggles, for extra safety while Runecrafting.", + "durability": null, + "name": "Runecrafter hat", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13625", + "absorb": "0,0,0", + "bonuses": "0,0,0,3,0,3,3,3,3,3,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "destroy_message": "Drop", + "shop_price": "75", + "examine": "Comes with goggles, for extra safety while Runecrafting.", + "durability": null, + "name": "Runecrafter hat", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13626", + "absorb": "0,0,0", + "bonuses": "0,0,0,3,0,3,3,3,3,3,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "destroy_message": "Drop", + "shop_price": "75", + "examine": "A heavy-duty wizard robe.", + "durability": null, + "name": "Runecrafter skirt", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13627", + "absorb": "0,0,0", + "bonuses": "0,0,0,4,0,4,4,4,4,4,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "destroy_message": "Drop", + "shop_price": "75", + "examine": "Essence can be rough on the hands", + "durability": null, + "name": "Runecrafter gloves", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13628", + "absorb": "0,0,0", + "bonuses": "0,0,0,2,0,2,2,2,2,2,0,0,0,0,0", + "equipment_slot": "9" + }, + { + "destroy_message": "Drop", + "shop_price": "15", + "examine": "Staff with a holder for a talisman on top.", + "durability": null, + "name": "Runecrafting staff", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "5", + "id": "13629", + "absorb": "0,0,0", + "bonuses": "0,-1,7,5,0,2,3,1,15,0,0,33,0,0,0", + "render_anim": "28" + }, + { + "shop_price": "1500", + "examine": "A staff with a talisman on top.", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "weapon_interface": "1", + "absorb": "0,0,0", + "equip_audio": "2247", + "render_anim": "28", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Air talisman staff", + "archery_ticket_price": "0", + "id": "13630", + "bonuses": "0,-1,7,5,0,2,3,1,15,0,0,33,0,0,0" + }, + { + "shop_price": "1500", + "examine": "A staff with a talisman on top.", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "weapon_interface": "1", + "absorb": "0,0,0", + "equip_audio": "2247", + "render_anim": "28", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Mind talisman staff", + "archery_ticket_price": "0", + "id": "13631", + "bonuses": "0,-1,7,5,0,2,3,1,15,0,0,33,0,0,0" + }, + { + "shop_price": "1500", + "examine": "A staff with a talisman on top.", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "weapon_interface": "1", + "absorb": "0,0,0", + "equip_audio": "2247", + "render_anim": "28", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Water talisman staff", + "archery_ticket_price": "0", + "id": "13632", + "bonuses": "0,-1,7,5,0,2,3,1,16,0,0,33,0,0,0" + }, + { + "shop_price": "1500", + "examine": "A staff with a talisman on top.", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "weapon_interface": "1", + "absorb": "0,0,0", + "equip_audio": "2247", + "render_anim": "28", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Earth talisman staff", + "archery_ticket_price": "0", + "id": "13633", + "bonuses": "0,-1,7,5,0,2,3,1,16,0,0,33,0,0,0" + }, + { + "shop_price": "1500", + "examine": "A staff with a talisman on top.", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "weapon_interface": "1", + "absorb": "0,0,0", + "equip_audio": "2247", + "render_anim": "28", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Fire talisman staff", + "archery_ticket_price": "0", + "id": "13634", + "bonuses": "0,-1,7,5,0,2,3,1,16,0,0,33,0,0,0" + }, + { + "shop_price": "1500", + "examine": "A staff with a talisman on top.", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "weapon_interface": "1", + "absorb": "0,0,0", + "equip_audio": "2247", + "render_anim": "28", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Body talisman staff", + "archery_ticket_price": "0", + "id": "13635", + "bonuses": "0,-1,7,5,0,2,3,1,15,0,0,33,0,0,0" + }, + { + "shop_price": "1500", + "examine": "A staff with a talisman on top.", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "weapon_interface": "1", + "absorb": "0,0,0", + "equip_audio": "2247", + "render_anim": "28", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Cosmic talisman staff", + "archery_ticket_price": "0", + "id": "13636", + "bonuses": "0,-1,7,5,0,2,3,1,16,0,0,33,0,0,0" + }, + { + "shop_price": "1500", + "examine": "A staff with a talisman on top.", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "weapon_interface": "1", + "absorb": "0,0,0", + "equip_audio": "2247", + "render_anim": "28", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Chaos talisman staff", + "archery_ticket_price": "0", + "id": "13637", + "bonuses": "0,-1,7,5,0,2,3,1,16,0,0,33,0,0,0" + }, + { + "shop_price": "1500", + "examine": "A staff with a talisman on top.", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "weapon_interface": "1", + "absorb": "0,0,0", + "equip_audio": "2247", + "render_anim": "28", + "equipment_slot": "3", + "destroy_message": "No", + "name": "Nature talisman staff", + "archery_ticket_price": "0", + "id": "13638", + "bonuses": "0,-1,7,5,0,2,3,1,16,0,0,33,0,0,0" + }, + { + "shop_price": "1500", + "examine": "A staff with a talisman on top.", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "weapon_interface": "1", + "absorb": "0,0,0", + "equip_audio": "2247", + "render_anim": "28", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Law talisman staff", + "archery_ticket_price": "0", + "id": "13639", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "1500", + "examine": "A staff with a talisman on top.", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "weapon_interface": "1", + "absorb": "0,0,0", + "equip_audio": "2247", + "render_anim": "28", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Death talisman staff", + "archery_ticket_price": "0", + "id": "13640", + "bonuses": "0,-1,7,5,0,2,3,1,16,0,0,33,0,0,0" + }, + { + "shop_price": "1500", + "examine": "A staff with a talisman on top.", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "weapon_interface": "1", + "absorb": "0,0,0", + "equip_audio": "2247", + "render_anim": "28", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Blood talisman staff", + "archery_ticket_price": "0", + "id": "13641", + "bonuses": "0,-1,7,5,0,2,3,1,16,0,0,33,0,0,0" + }, + { + "shop_price": "1500", + "examine": "A staff with a talisman on top.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "1", + "absorb": "0,0,0", + "equip_audio": "2247", + "render_anim": "28", + "equipment_slot": "3", + "destroy_message": "You will have to speak to Wizard Elriss to get another omni-talisman.", + "name": "Omni-talisman staff", + "archery_ticket_price": "0", + "id": "13642", + "bonuses": "0,-1,7,5,0,2,3,1,16,0,0,33,0,0,0" + }, + { + "shop_price": "20", + "examine": "Attracts Runecrafting energy orbs in the rune altars.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "1", + "absorb": "0,0,0", + "render_anim": "28", + "equipment_slot": "3", + "destroy_message": "If you destroy this, you will leave the game.", + "name": "Yellow attractor", + "archery_ticket_price": "0", + "id": "13643", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "20", + "examine": "Repels Runecrafting energy orbs in the rune altars.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "1", + "absorb": "0,0,0", + "render_anim": "28", + "equipment_slot": "3", + "destroy_message": "If you destroy this, you will leave the game.", + "name": "Yellow repeller", + "archery_ticket_price": "0", + "id": "13644", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "20", + "examine": "Attracts Runecrafting energy orbs in the rune altars.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "1", + "absorb": "0,0,0", + "render_anim": "28", + "equipment_slot": "3", + "destroy_message": "If you destroy this, you will leave the game.", + "name": "Green attractor", + "archery_ticket_price": "0", + "id": "13645", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "20", + "examine": "Repels Runecrafting energy orbs in the rune altars.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "1", + "absorb": "0,0,0", + "render_anim": "28", + "equipment_slot": "3", + "destroy_message": "If you destroy this, you will leave the game.", + "name": "Green repeller", + "archery_ticket_price": "0", + "id": "13646", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "20", + "examine": "It creates barriers.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "1", + "absorb": "0,0,0", + "render_anim": "28", + "equipment_slot": "3", + "destroy_message": "If you destroy this, you will leave the game.", + "name": "Green barrier generator", + "archery_ticket_price": "0", + "id": "13647", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "20", + "examine": "It creates barriers.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "1", + "absorb": "0,0,0", + "render_anim": "28", + "equipment_slot": "3", + "destroy_message": "If you destroy this, you will leave the game.", + "name": "Yellow barrier generator", + "archery_ticket_price": "0", + "id": "13648", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You will have to speak to ", + "shop_price": "4", + "examine": "Many mysterious powers emanate from the talisman.", + "durability": null, + "name": "Omni-talisman", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13649", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Unknown ", + "examine": "Wizard Elriss will exchange these for rewards.", + "durability": null, + "name": "Runecrafting guild token", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13650", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Unknown ", + "examine": "Wizard Elriss will exchange these for rewards.", + "durability": null, + "name": "Runecrafting guild token", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13651", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Unknown ", + "examine": "Wizard Elriss will exchange these for rewards.", + "durability": null, + "name": "Runecrafting guild token", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13652", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Unknown ", + "examine": "Wizard Elriss will exchange these for rewards.", + "durability": null, + "name": "Runecrafting guild token", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13653", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Unknown ", + "examine": "Wizard Elriss will exchange these for rewards.", + "durability": null, + "name": "Runecrafting guild token", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13654", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You will have to speak to Wizard Elriss to get another omni-talisman.", + "shop_price": "100", + "examine": "A tiara infused with the properties of all talismans.", + "durability": null, + "name": "Omni-tiara", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13655", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "destroy_message": "Drop", + "shop_price": "75", + "examine": "Comes with goggles, for extra safety while Runecrafting.", + "durability": null, + "name": "Runecrafter hat", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13656", + "absorb": "0,0,0", + "bonuses": "0,0,0,3,0,3,3,3,3,3,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "destroy_message": "Drop", + "shop_price": "75", + "examine": "Comes with goggles, for extra safety while Runecrafting.", + "durability": null, + "name": "Runecrafter hat", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13657", + "absorb": "0,0,0", + "bonuses": "0,0,0,3,0,3,3,3,3,3,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "destroy_message": "Drop", + "shop_price": "75", + "examine": "Comes with goggles, for extra safety while Runecrafting.", + "durability": null, + "name": "Runecrafter hat", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13658", + "absorb": "0,0,0", + "bonuses": "0,0,0,3,0,3,3,3,3,3,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "requirements": "{11,62}", + "shop_price": "100", + "examine": "It burns, burns, burns...", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "12", + "destroy_message": "To get another Ring of Fire, you need to keep six beacons alight simultaneously and then talk to King Roald.", + "name": "Ring of fire", + "archery_ticket_price": "0", + "id": "13659", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "point_price": "50" + }, + { + "requirements": "{11,79}", + "destroy_message": "To get another pair of Flame Gloves, you need to keep ten beacons alight simultaneously and then talk to King Roald.", + "shop_price": "200", + "examine": "The hottest gloves in town.", + "durability": null, + "name": "Flame gloves", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13660", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "9" + }, + { + "requirements": "{11,92}", + "shop_price": "300", + "examine": "Danger: risk of fire.", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "weapon_interface": "2", + "absorb": "0,0,0", + "render_anim": "1096", + "equipment_slot": "3", + "attack_anims": "395,395,401,395", + "destroy_message": "To get another Inferno Adze, you need to keep all fourteen beacons alight simultaneously and then talk to King Roald.", + "name": "Inferno adze", + "archery_ticket_price": "0", + "id": "13661", + "bonuses": "10,9,7,0,0,0,1,0,0,0,0,11,0,0,0", + "point_price": "75" + }, + { + "durability": null, + "name": "Fire beacon", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13662", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "The ticket says: Tearing this ticket will make you leave the circus. Choose wisely.", + "shop_price": "10", + "examine": "Tear ticket to exit the circus.", + "durability": null, + "name": "Circus ticket", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13663", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "3" + }, + { + "shop_price": "10", + "examine": "Let's give them a big hand!", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "7", + "absorb": "0,0,0", + "render_anim": "326", + "equipment_slot": "3", + "destroy_message": "You will need to speak to the ringmaster to get another one.", + "name": "Giant's hand", + "archery_ticket_price": "0", + "id": "13666", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "remove_head": "true", + "shop_price": "10", + "examine": "A clown hat!", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "0", + "destroy_message": "You will need to speak to the ringmaster to get another.", + "name": "Clown hat", + "archery_ticket_price": "0", + "id": "13667", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "10", + "examine": "Buttoning this up is tricky.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "4", + "destroy_message": "You will need to speak to the ringmaster to get another.", + "remove_sleeves": "true", + "name": "Clown shirt", + "archery_ticket_price": "0", + "id": "13668", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You will need to speak to the ringmaster to get another.", + "shop_price": "10", + "examine": "These are my funny pants.", + "durability": null, + "name": "Clown leggings", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13669", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "destroy_message": "You will need to speak to the ringmaster to get another.", + "shop_price": "10", + "examine": "For helping clowns stay upright.", + "durability": null, + "name": "Clown shoes", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13670", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "10" + }, + { + "shop_price": "10", + "examine": "For making a happy noise.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "8", + "absorb": "0,0,0", + "render_anim": "327", + "equipment_slot": "3", + "destroy_message": "You will need to speak to the ringmaster to get another.", + "name": "Tambourine", + "archery_ticket_price": "0", + "id": "13671", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You will need to speak to the ringmaster to get another one.", + "shop_price": "10", + "examine": "Very stylish.", + "durability": null, + "name": "Ringmaster hat", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13672", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "shop_price": "10", + "examine": "Fits nicely.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "4", + "destroy_message": "You will need to speak to the ringmaster to get another one.", + "remove_sleeves": "true", + "name": "Ringmaster shirt", + "archery_ticket_price": "0", + "id": "13673", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You will need to speak to the ringmaster to get another one.", + "shop_price": "10", + "examine": "Very stylish.", + "durability": null, + "name": "Ringmaster pants", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13674", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "destroy_message": "You will need to speak to the ringmaster to get another one.", + "shop_price": "10", + "examine": "Shiny.", + "durability": null, + "name": "Ringmaster boots", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13675", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "10" + }, + { + "shop_price": "10", + "examine": "For shouting at people.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "8", + "absorb": "0,0,0", + "render_anim": "328", + "equipment_slot": "3", + "destroy_message": "You will need to speak to the ringmaster to get another one.", + "name": "Mega-phonus", + "archery_ticket_price": "0", + "id": "13676", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "10", + "examine": "Stretchy.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "4", + "destroy_message": "You will need to speak to the ringmaster to get another.", + "remove_sleeves": "true", + "name": "Acrobat shirt", + "archery_ticket_price": "0", + "id": "13677", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You will need to speak to the ringmaster to get another.", + "shop_price": "10", + "examine": "Very tight fitting.", + "durability": null, + "name": "Acrobat pants", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13678", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "destroy_message": "You will need to speak to the ringmaster to get another.", + "shop_price": "10", + "examine": "These keep your feet off the floor.", + "durability": null, + "name": "Acrobat shoes", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13679", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "10" + }, + { + "remove_head": "true", + "shop_price": "10", + "examine": "Oh no, I'm bald! Just kidding.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "remove_beard": "true", + "equipment_slot": "0", + "destroy_message": "You will need to speak to the ringmaster to get another.", + "name": "Acrobat hood", + "archery_ticket_price": "0", + "id": "13680", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "10", + "examine": "Stretchy.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "4", + "destroy_message": "You will need to speak to the ringmaster to get another.", + "remove_sleeves": "true", + "name": "Acrobat shirt", + "archery_ticket_price": "0", + "id": "13681", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You will need to speak to the ringmaster to get another.", + "shop_price": "10", + "examine": "Very tight fitting.", + "durability": null, + "name": "Acrobat pants", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13682", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "destroy_message": "You will need to speak to the ringmaster to get another.", + "shop_price": "10", + "examine": "These keep your feet off the floor.", + "durability": null, + "name": "Acrobat shoes", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13683", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "10" + }, + { + "remove_head": "true", + "shop_price": "10", + "examine": "Oh no, I'm bald! Just kidding.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "0", + "destroy_message": "You will need to speak to the ringmaster to get another.", + "name": "Acrobat hood", + "archery_ticket_price": "0", + "id": "13684", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You will need to speak to the ringmaster to get another.", + "shop_price": "10", + "examine": "Very dapper!", + "durability": null, + "name": "A stylish hat", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13685", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "destroy_message": "You will need to speak to the ringmaster to get another.", + "shop_price": "10", + "examine": "Very dapper!", + "durability": null, + "name": "A stylish hat", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13686", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "destroy_message": "You will need to speak to the ringmaster to get another.", + "shop_price": "10", + "examine": "Very dapper!", + "durability": null, + "name": "A stylish hat", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13687", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "remove_head": "true", + "shop_price": "10", + "examine": "Very dapper!", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "0", + "destroy_message": "You will need to speak to the ringmaster to get another.", + "name": "A stylish hat", + "archery_ticket_price": "0", + "id": "13688", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "remove_head": "true", + "shop_price": "10", + "examine": "Very dapper!", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "0", + "destroy_message": "You will need to speak to the ringmaster to get another.", + "name": "A stylish hat", + "archery_ticket_price": "0", + "id": "13689", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "remove_head": "true", + "shop_price": "10", + "examine": "Very dapper!", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "0", + "destroy_message": "You will need to speak to the ringmaster to get another.", + "name": "A stylish hat", + "archery_ticket_price": "0", + "id": "13690", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "remove_sleeves": "true", + "shop_price": "10", + "durability": null, + "name": "Shirt", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13691", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "4" + }, + { + "remove_sleeves": "true", + "shop_price": "10", + "durability": null, + "name": "Shirt", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13692", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "4" + }, + { + "remove_sleeves": "true", + "shop_price": "10", + "durability": null, + "name": "Shirt", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13693", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "4" + }, + { + "remove_sleeves": "true", + "shop_price": "10", + "durability": null, + "name": "Shirt", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13694", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "4" + }, + { + "remove_sleeves": "true", + "shop_price": "10", + "durability": null, + "name": "Shirt", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13695", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "4" + }, + { + "remove_sleeves": "true", + "shop_price": "10", + "durability": null, + "name": "Shirt", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13696", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "4" + }, + { + "shop_price": "10", + "durability": null, + "name": "Leggings", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13697", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "shop_price": "10", + "durability": null, + "name": "Leggings", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13698", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "shop_price": "10", + "durability": null, + "name": "Leggings", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13699", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "shop_price": "10", + "durability": null, + "name": "Skirt", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13700", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "shop_price": "10", + "durability": null, + "name": "Skirt", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13701", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "shop_price": "10", + "durability": null, + "name": "Skirt", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13702", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "shop_price": "10", + "durability": null, + "name": "Shoes", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13703", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "10" + }, + { + "shop_price": "10", + "durability": null, + "name": "Shoes", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13704", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "10" + }, + { + "shop_price": "10", + "durability": null, + "name": "Shoes", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13705", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "10" + }, + { + "shop_price": "10", + "durability": null, + "name": "Shoes", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13706", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "10" + }, + { + "destroy_message": "You can get another Tightrope 101 by speaking to the Agility assistant.", + "examine": "Shows you the moves you need to succeed!", + "durability": null, + "name": "Tightrope 101", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13707", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You can get another Tightrope 101 by speaking to the Agility assistant.", + "examine": "Shows you the moves you need to succeed!", + "durability": null, + "name": "Tightrope 101", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13708" + }, + { + "destroy_message": "You can get another one from the equipment box for this performance.", + "examine": "An Agility level of 10 is advised when juggling these.", + "durability": null, + "name": "Balls (level 10 approx.)", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13709", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "3" + }, + { + "destroy_message": "You can get another one from the equipment box for this performance.", + "examine": "An Agility level of 20 is advised when juggling these.", + "durability": null, + "name": "Plates (level 20 approx.)", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13710", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "3" + }, + { + "destroy_message": "You can get another one from the equipment box for this performance.", + "examine": "An Agility level of 30 is advised when juggling these.", + "durability": null, + "name": "Eggs (level 30 approx.)", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13711", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "3" + }, + { + "destroy_message": "You can get another one from the equipment box for this performance.", + "examine": "An Agility level of 40 is advised when juggling these.", + "durability": null, + "name": "Knives (level 40 approx.)", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13712", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "3" + }, + { + "destroy_message": "You can get another one from the equipment box for this performance.", + "examine": "An Agility level of 50 is advised when juggling these.", + "durability": null, + "name": "Spades (level 50 approx.)", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13713", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "3" + }, + { + "destroy_message": "You can get another one from the equipment box for this performance.", + "examine": "An Agility level of 60 is advised when juggling these.", + "durability": null, + "name": "Tuna (level 60 approx.)", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13714", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "3" + }, + { + "destroy_message": "You can get another one from the equipment box for this performance.", + "examine": "An Agility level of 70 is advised when juggling these.", + "durability": null, + "name": "Soap (level 70 approx.)", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13715", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "3" + }, + { + "destroy_message": "You can get another one from the equipment box for this performance.", + "examine": "An Agility level of 80 is advised when juggling these.", + "durability": null, + "name": "Cannon balls (level 80 approx.)", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13716", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "3" + }, + { + "destroy_message": "You can get another one from the equipment box for this performance.", + "examine": "An Agility level of 90 is advised when juggling these.", + "durability": null, + "name": "Torches (level 90 approx.)", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13717", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "3" + }, + { + "destroy_message": "You can get another one from the equipment box for this performance.", + "examine": "An Agility level of 99 is advised when juggling these.", + "durability": null, + "name": "Chinchompas (level 99 approx.)", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13718", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "3" + }, + { + "shop_price": "50", + "examine": "Short, but effective.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "16", + "absorb": "0,0,0", + "render_anim": "176", + "equipment_slot": "3", + "destroy_message": "You can get another one from the equipment box for this performance.", + "name": "Performance shortbow", + "archery_ticket_price": "0", + "id": "13719", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "14", + "examine": "A finely balanced throwing knife.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "18", + "absorb": "0,0,0", + "equip_audio": "", + "equipment_slot": "3", + "destroy_message": "You can get another one from the equipment box for this performance.", + "name": "Performance knife", + "archery_ticket_price": "0", + "id": "13720", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "4", + "examine": "A finely balanced throwing axe.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "18", + "absorb": "0,0,0", + "equipment_slot": "3", + "destroy_message": "You can get another one from the equipment box for this performance.", + "name": "Performance throwing axe", + "archery_ticket_price": "0", + "id": "13721", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You can get another one from the equipment box for this performance.", + "shop_price": "7", + "examine": "Arrows with bronze heads.", + "durability": null, + "name": "Performance arrow", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13722", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "13" + }, + { + "destroy_message": "You can get another one from the equipment box for this performance.", + "shop_price": "100", + "examine": "A tablet containing a Magic spell.", + "durability": null, + "name": "Teleport spell", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13723", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You can get another one from the equipment box for this performance.", + "shop_price": "100", + "examine": "A tablet containing a Magic spell.", + "durability": null, + "name": "Levitation spell", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13724", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You can get another one from the equipment box for this performance.", + "shop_price": "100", + "examine": "A tablet containing a Magic spell.", + "durability": null, + "name": "Alchemy spell", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13725", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You can get another one from the equipment box for this performance.", + "shop_price": "100", + "examine": "A tablet containing a Magic spell.", + "durability": null, + "name": "Elemental spell", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13726", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You can mine more if you find another crashed star.", + "shop_price": "50", + "examine": "Small, shiny bits of rock.", + "durability": null, + "name": "Stardust", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13727", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You will need to speak with Larry/Chuck at Ardougne Zoo to get another.", + "examine": "Notes on the locations of penguin spies.", + "durability": null, + "name": "Spy notebook", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13732", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "requirements": "{1,40}-{5,55}", + "shop_price": "70000", + "examine": "An ethereal shield.", + "rare_item": "true", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equip_audio": "2245", + "equipment_slot": "5", + "destroy_message": "Drop", + "grand_exchange_price": "39982", + "name": "Spirit shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13734", + "bonuses": "0,0,0,0,0,39,41,50,1,45,40,0,1,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "70000", + "examine": "An ethereal shield.", + "grand_exchange_price": "39982", + "durability": null, + "name": "Spirit shield", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13735" + }, + { + "requirements": "{1,70}-{5,60}", + "shop_price": "1400000", + "examine": "An ethereal shield that has been blessed with holy powers.", + "rare_item": "true", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equip_audio": "2245", + "equipment_slot": "5", + "destroy_message": "Drop", + "grand_exchange_price": "936814", + "name": "Blessed spirit shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13736", + "bonuses": "0,0,0,0,0,53,55,73,2,52,65,0,3,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "1400000", + "examine": "An ethereal shield that has been blessed with holy powers.", + "grand_exchange_price": "936814", + "durability": null, + "name": "Blessed spirit shield", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13737" + }, + { + "requirements": "{1,75}-{6,65}-{5,70}", + "shop_price": "2000000", + "examine": "An ethereal shield with an arcane sigil attached to it.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equip_audio": "2245", + "equipment_slot": "5", + "destroy_message": "Drop", + "grand_exchange_price": "15076199", + "name": "Arcane spirit shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13738", + "bonuses": "0,0,0,20,0,53,55,73,2,52,65,0,3,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "2000000", + "examine": "An ethereal shield with an arcane sigil attached to it.", + "grand_exchange_price": "15076199", + "durability": null, + "name": "Arcane spirit shield", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13739" + }, + { + "requirements": "{1,75}-{5,75}", + "shop_price": "2000000", + "examine": "An ethereal shield with a divine sigil attached to it.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equip_audio": "2245", + "equipment_slot": "5", + "destroy_message": "Drop", + "grand_exchange_price": "40003587", + "name": "Divine spirit shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13740", + "bonuses": "0,0,0,0,0,63,65,75,2,57,65,0,3,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "2000000", + "examine": "An ethereal shield with a divine sigil attached to it.", + "grand_exchange_price": "40003587", + "durability": null, + "name": "Divine spirit shield", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13741" + }, + { + "requirements": "{1,75}-{5,75}", + "shop_price": "2000000", + "examine": "An ethereal shield with an elysian sigil attached to it.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equip_audio": "2245", + "equipment_slot": "5", + "destroy_message": "Drop", + "grand_exchange_price": "28420591", + "name": "Elysian spirit shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13742", + "bonuses": "0,0,0,0,0,63,65,75,2,57,65,0,3,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "2000000", + "examine": "An ethereal shield with an elysian sigil attached to it.", + "grand_exchange_price": "28420591", + "durability": null, + "name": "Elysian spirit shield", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13743" + }, + { + "requirements": "{1,75}-{5,70}-{6,65}", + "shop_price": "2000000", + "examine": "An ethereal shield with a spectral sigil attached to it.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equip_audio": "2245", + "equipment_slot": "5", + "destroy_message": "Drop", + "grand_exchange_price": "3616112", + "name": "Spectral spirit shield", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13744", + "bonuses": "0,0,0,0,0,53,55,73,30,52,65,0,3,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "2000000", + "examine": "An ethereal shield with a spectral sigil attached to it.", + "grand_exchange_price": "3616112", + "durability": null, + "name": "Spectral spirit shield", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13745" + }, + { + "shop_price": "750000", + "examine": "A sigil in the shape of an arcane rune.", + "rare_item": "true", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "19508553", + "name": "Arcane sigil", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13746", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "750000", + "examine": "A sigil in the shape of an arcane rune.", + "grand_exchange_price": "19508553", + "durability": null, + "name": "Arcane sigil", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13747" + }, + { + "shop_price": "750000", + "examine": "A sigil in the shape of a divine symbol.", + "rare_item": "true", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "53026134", + "name": "Divine sigil", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13748", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "750000", + "examine": "A sigil in the shape of a divine symbol.", + "grand_exchange_price": "53026134", + "durability": null, + "name": "Divine sigil", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13749" + }, + { + "shop_price": "750000", + "examine": "A sigil marked with elysian signs.", + "rare_item": "true", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "36159098", + "name": "Elysian sigil", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13750", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "750000", + "examine": "A sigil marked with elysian signs.", + "grand_exchange_price": "36159098", + "durability": null, + "name": "Elysian sigil", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13751" + }, + { + "shop_price": "750000", + "examine": "A sigil tempered with spectral powers.", + "rare_item": "true", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "3116720", + "name": "Spectral sigil", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13752", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "750000", + "examine": "A sigil tempered with spectral powers.", + "grand_exchange_price": "3116720", + "durability": null, + "name": "Spectral sigil", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13753" + }, + { + "shop_price": "750000", + "examine": "A bottle of holy elixir.", + "rare_item": "true", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "950904", + "name": "Holy elixir", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13754", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "750000", + "examine": "A bottle of holy elixir.", + "grand_exchange_price": "950904", + "durability": null, + "name": "Holy elixir", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13755" + }, + { + "destroy_message": "Drop", + "shop_price": "40", + "examine": "Logs cut from cursed willow roots.", + "durability": null, + "name": "Cursed willow logs", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13756", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "1", + "examine": "A loyal scout of Varrock.", + "durability": null, + "name": "Hartwin", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13757", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You'll have to keep searching trees near the zombie trails until you find another.", + "examine": "A key that was found while tracking zombies. (Defender of Varrock)", + "durability": null, + "name": "Grubby key", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13758", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You'll have to speak to Thurgo to find another.", + "shop_price": "1", + "examine": "The location of ", + "durability": null, + "name": "Scrap of paper", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13759", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "durability": null, + "name": "Bottle", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13760", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "examine": "A bottle of red mist.", + "durability": null, + "name": "Bottle of mist", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13761", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You can get another from ", + "examine": "This lists each of the founding members of the ", + "durability": null, + "name": "List of elders", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13762", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "I hope I don't meet any roundheads...", + "durability": null, + "name": "Cavalier and mask", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13763", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "examine": "A right hand fighting claw.", + "has_special": "true", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "two_handed": "true", + "weapon_interface": "9", + "absorb": "0,0,0", + "equip_audio": "1003", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "6535", + "name": "Rune claws", + "archery_ticket_price": "0", + "id": "13764", + "bonuses": "26,38,-4,0,0,10,19,5,0,0,0,39,0,0,0" + }, + { + "examine": "A powerful dagger.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "5", + "absorb": "0,0,0", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "4381", + "name": "Rune dagger", + "archery_ticket_price": "0", + "id": "13765", + "bonuses": "25,12,-4,1,0,0,0,0,1,0,0,24,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "1", + "examine": "A picture of a lady called Elena.", + "durability": null, + "name": "Rune dagger(p)", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13766", + "absorb": "0,0,0", + "bonuses": "25,12,-4,1,0,0,0,0,1,0,0,24,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "1", + "examine": "A picture of a lady called Elena.", + "durability": null, + "name": "Rune dagger(p+)", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13767", + "absorb": "0,0,0", + "bonuses": "25,12,-4,1,0,0,0,0,1,0,0,24,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "1", + "examine": "A picture of a lady called Elena.", + "durability": null, + "name": "Rune dagger(p++)", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13768", + "absorb": "0,0,0", + "bonuses": "25,12,-4,1,0,0,0,0,1,0,0,24,0,0,0" + }, + { + "examine": "A rune tipped spear.", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "14", + "absorb": "0,0,0", + "render_anim": "28", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "11317", + "name": "Rune spear", + "archery_ticket_price": "0", + "id": "13769", + "bonuses": "36,36,36,0,0,1,1,0,0,0,0,42,0,0,0" + }, + { + "examine": "A dragon tipped spear.", + "has_special": "true", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "14", + "absorb": "0,0,0", + "render_anim": "28", + "defence_anim": "2079", + "attack_anims": "2080,2081,2082,2080", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "36774", + "name": "Dragon spear", + "archery_ticket_price": "0", + "id": "13770", + "bonuses": "55,55,55,0,0,5,5,5,5,5,0,60,0,0,0" + }, + { + "shop_price": "1", + "examine": "A picture of a lady called Elena.", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "two_handed": "true", + "absorb": "0,0,0", + "render_anim": "28", + "destroy_message": "Drop", + "name": "Rune spear(p)", + "archery_ticket_price": "0", + "id": "13771", + "bonuses": "36,36,36,0,0,1,1,0,0,0,0,42,0,0,0" + }, + { + "shop_price": "1", + "examine": "A picture of a lady called Elena.", + "has_special": "true", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "two_handed": "true", + "absorb": "0,0,0", + "render_anim": "28", + "defence_anim": "2079", + "attack_anims": "2080,2081,2082,2080", + "destroy_message": "Drop", + "name": "Dragon spear(p)", + "archery_ticket_price": "0", + "id": "13772", + "bonuses": "55,55,55,0,0,5,5,5,5,5,0,60,0,0,0" + }, + { + "shop_price": "1", + "examine": "A picture of a lady called Elena.", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "two_handed": "true", + "absorb": "0,0,0", + "render_anim": "28", + "destroy_message": "Drop", + "name": "Rune spear(p+)", + "archery_ticket_price": "0", + "id": "13773", + "bonuses": "36,36,36,0,0,1,1,0,0,0,0,42,0,0,0" + }, + { + "shop_price": "1", + "examine": "A picture of a lady called Elena.", + "has_special": "true", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "two_handed": "true", + "absorb": "0,0,0", + "render_anim": "28", + "defence_anim": "2079", + "attack_anims": "2080,2081,2082,2080", + "destroy_message": "Drop", + "name": "Dragon spear(p+)", + "archery_ticket_price": "0", + "id": "13774", + "bonuses": "55,55,55,0,0,5,5,5,5,5,0,60,0,0,0" + }, + { + "shop_price": "1", + "examine": "A picture of a lady called Elena.", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "two_handed": "true", + "absorb": "0,0,0", + "render_anim": "28", + "destroy_message": "Drop", + "name": "Rune spear(p++)", + "archery_ticket_price": "0", + "id": "13775", + "bonuses": "36,36,36,0,0,1,1,0,0,0,0,42,0,0,0" + }, + { + "shop_price": "1", + "examine": "A picture of a lady called Elena.", + "has_special": "true", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "two_handed": "true", + "absorb": "0,0,0", + "render_anim": "28", + "defence_anim": "2079", + "attack_anims": "2080,2081,2082,2080", + "destroy_message": "Drop", + "name": "Dragon spear(p++)", + "archery_ticket_price": "0", + "id": "13776", + "bonuses": "55,55,55,0,0,5,5,5,5,5,0,60,0,0,0" + }, + { + "examine": "A razor-sharp sword.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "5", + "absorb": "0,0,0", + "render_anim": "1381", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "11849", + "name": "Rune sword", + "archery_ticket_price": "0", + "id": "13777", + "bonuses": "38,26,-2,0,0,0,2,1,0,0,0,39,0,0,0" + }, + { + "examine": "A two handed sword.", + "durability": null, + "destroy": "true", + "attack_speed": "7", + "two_handed": "true", + "weapon_interface": "7", + "absorb": "0,0,0", + "equip_audio": "2248", + "render_anim": "124", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "37511", + "name": "Rune 2h sword", + "archery_ticket_price": "0", + "id": "13778", + "bonuses": "-4,69,50,-4,0,0,0,0,0,-1,0,70,0,0,0" + }, + { + "examine": "A rune halberd.", + "durability": null, + "destroy": "true", + "attack_speed": "7", + "two_handed": "true", + "weapon_interface": "15", + "absorb": "0,0,0", + "equip_audio": "2247", + "render_anim": "28", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "74298", + "name": "Rune halberd", + "archery_ticket_price": "0", + "id": "13779", + "bonuses": "48,67,0,-4,0,-1,4,5,0,0,0,68,0,0,0" + }, + { + "examine": "A spiky mace.", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "weapon_interface": "8", + "absorb": "0,0,0", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "7917", + "attack_audios": "2508,2508,25092508", + "name": "Rune mace", + "archery_ticket_price": "0", + "id": "13780", + "bonuses": "20,-2,39,0,0,0,0,0,0,0,0,36,0,4,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "A series of connected metal rings.", + "grand_exchange_price": "29145", + "durability": null, + "name": "Rune chainbody", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13781", + "absorb": "3,0,6", + "bonuses": "0,0,0,-15,0,63,72,78,-3,65,40,0,0,0,0" + }, + { + "examine": "These will protect my feet.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equip_audio": "2237", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "7036", + "name": "Rune boots", + "archery_ticket_price": "0", + "id": "13782", + "bonuses": "0,0,0,-3,-1,12,13,14,0,0,10,2,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "A medium sized helmet.", + "grand_exchange_price": "10678", + "durability": null, + "name": "Rune med helm", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13783", + "absorb": "1,0,3", + "bonuses": "0,0,0,-3,-1,22,23,21,-1,22,7,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "A stone helmet.", + "grand_exchange_price": "26576", + "durability": null, + "name": "Granite helm", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13784", + "absorb": "2,0,4", + "bonuses": "0,0,0,-9,-7,31,33,29,-1,39,9,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Provides excellent protection.", + "grand_exchange_price": "136414", + "durability": null, + "name": "Granite body", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13785", + "absorb": "4,0,8", + "bonuses": "0,0,0,-22,-5,87,84,79,-6,97,45,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "These look pretty heavy.", + "grand_exchange_price": "72213", + "durability": null, + "name": "Granite legs", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13786", + "absorb": "2,0,5", + "bonuses": "0,0,0,-31,-18,43,45,41,-4,68,20,0,0,0,0" + }, + { + "examine": "A medium square shield.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "3,0,7", + "equip_audio": "2245", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "22225", + "name": "Rune sq shield", + "archery_ticket_price": "0", + "id": "13787", + "bonuses": "0,0,0,-6,-2,38,40,36,0,38,35,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "A solid stone shield.", + "grand_exchange_price": "32512", + "durability": null, + "name": "Granite shield", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13788", + "absorb": "5,0,10", + "bonuses": "0,0,0,-12,-8,40,42,38,0,65,50,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "A big 'do about nothing.", + "grand_exchange_price": "42991", + "durability": null, + "name": "A powdered wig", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13789", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "These'll help me stay alive.", + "grand_exchange_price": "811293", + "durability": null, + "name": "Flared trousers", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13790", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Alas, someone has slashed my pantaloons.", + "grand_exchange_price": "19286", + "durability": null, + "name": "Pantaloons", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13791", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "A cap for wearing whil...zzzzzzzzz", + "grand_exchange_price": "75357", + "durability": null, + "name": "Sleeping cap", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13792", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "examine": "A diamond-topped cane.", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "weapon_interface": "8", + "absorb": "0,0,0", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "76692", + "name": "Rune cane", + "archery_ticket_price": "0", + "id": "13793", + "bonuses": "0,-2,39,0,0,0,0,0,0,0,0,36,0,4,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Comes with a free rabbit!", + "grand_exchange_price": "333537", + "durability": null, + "name": "Top hat", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13794", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Shear elegance.", + "grand_exchange_price": "582969", + "durability": null, + "name": "Sheep mask", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13795", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "I can get the look right, but can I do the waddle too?", + "grand_exchange_price": "1159807", + "durability": null, + "name": "Penguin mask", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13796", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "The bats have left the belltower.", + "grand_exchange_price": "681595", + "durability": null, + "name": "Bat mask", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13797", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "It's the year of the cat!", + "grand_exchange_price": "2512014", + "durability": null, + "name": "Cat mask", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13798", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "I'm hungry like the wolf.", + "grand_exchange_price": "3240770", + "durability": null, + "name": "Wolf mask", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13799", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Rune platebody with gold trim.", + "grand_exchange_price": "343688", + "durability": null, + "name": "Rune platebody (g)", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13800", + "absorb": "3,0,6", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "drop", + "examine": "Rune platelegs with gold trim.", + "grand_exchange_price": "238139", + "durability": null, + "name": "Rune platelegs (g)", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13801", + "absorb": "2,0,4", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Rune plateskirt with gold trim.", + "grand_exchange_price": "37616", + "durability": null, + "name": "Rune plateskirt (g)", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13802", + "absorb": "2,0,4", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Rune full helmet with gold trim.", + "grand_exchange_price": "247877", + "durability": null, + "name": "Rune full helm(g)", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13803", + "absorb": "1,0,3", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0" + }, + { + "examine": "Rune kiteshield with gold trim", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "3,0,7", + "equip_audio": "2245", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "118205", + "name": "Rune kiteshield (g)", + "archery_ticket_price": "0", + "id": "13804", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Rune platebody with trim.", + "grand_exchange_price": "100586", + "durability": null, + "name": "Rune platebody (t)", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13805", + "absorb": "3,0,6", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Rune platelegs with trim!", + "grand_exchange_price": "81577", + "durability": null, + "name": "Rune platelegs (t)", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13806", + "absorb": "2,0,4", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Rune plateskirt with trim.", + "grand_exchange_price": "37701", + "durability": null, + "name": "Rune plateskirt (t)", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13807", + "absorb": "2,0,4", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Rune full helmet with trim.", + "grand_exchange_price": "95809", + "durability": null, + "name": "Rune full helm (t)", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13808", + "absorb": "1,0,3", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0" + }, + { + "examine": "A large, metal shield with a nice trim.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "3,0,7", + "equip_audio": "2245", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "46469", + "name": "Rune kiteshield (t)", + "archery_ticket_price": "0", + "id": "13809", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Your money or your life!", + "grand_exchange_price": "252995", + "durability": null, + "name": "Highwayman mask", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13810", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "examine": "Parlez-vous francais?", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "135411", + "name": "Blue beret", + "archery_ticket_price": "0", + "hat": true, + "id": "13811", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "examine": "Parlez-vous francais?", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "451371", + "name": "Black beret", + "archery_ticket_price": "0", + "hat": true, + "id": "13812", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "examine": "Parlez-vous Francais?", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "704147", + "name": "White beret", + "archery_ticket_price": "0", + "hat": true, + "id": "13813", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "All for one and one for all!", + "grand_exchange_price": "42014", + "durability": null, + "name": "Tan cavalier", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13814", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "All for one and one for all!", + "grand_exchange_price": "61518", + "durability": null, + "name": "Dark cavalier", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13815", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "All for one and one for all!", + "grand_exchange_price": "338530", + "durability": null, + "name": "Black cavalier", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13816", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "A minimalist's hat.", + "grand_exchange_price": "159694", + "durability": null, + "name": "Red headband", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13817", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "A minimalist's hat.", + "grand_exchange_price": "83543", + "durability": null, + "name": "Black headband", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13818", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "A minimalist's hat.", + "grand_exchange_price": "26474", + "durability": null, + "name": "Brown headband", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13819", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Rune platebody in the colours of Zamorak.", + "grand_exchange_price": "868398", + "durability": null, + "name": "Zamorak platebody", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13820", + "absorb": "3,0,6", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Rune platelegs in the colours of Zamorak.", + "grand_exchange_price": "316989", + "durability": null, + "name": "Zamorak platelegs", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13821", + "absorb": "2,0,4", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Rune plateskirt in the colours of Zamorak.", + "grand_exchange_price": "38597", + "durability": null, + "name": "Zamorak plateskirt", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13822", + "absorb": "2,0,4", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "A full helmet in the colours of Zamorak.", + "grand_exchange_price": "618480", + "durability": null, + "name": "Zamorak full helm", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13823", + "absorb": "1,0,3", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0" + }, + { + "examine": "A Rune kiteshield in the colours of Zamorak.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "3,0,7", + "equip_audio": "2245", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "225574", + "name": "Zamorak kiteshield", + "archery_ticket_price": "0", + "id": "13824", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Rune platebody in the colours of Saradomin.", + "grand_exchange_price": "1555099", + "durability": null, + "name": "Saradomin platebody", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13825", + "absorb": "3,0,6", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Rune platelegs in the colours of Saradomin.", + "grand_exchange_price": "376849", + "durability": null, + "name": "Saradomin platelegs", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13826", + "absorb": "2,0,4", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Rune plateskirt in the colours of Saradomin.", + "grand_exchange_price": "53048", + "durability": null, + "name": "Saradomin plateskirt", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13827", + "absorb": "2,0,4", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Rune full helmet in the colours of Saradomin.", + "grand_exchange_price": "1025974", + "durability": null, + "name": "Saradomin full helm", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13828", + "absorb": "1,0,3", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0" + }, + { + "examine": "Rune kiteshield in the colours of Saradomin.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "3,0,7", + "equip_audio": "2245", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "353916", + "name": "Saradomin kiteshield", + "archery_ticket_price": "0", + "id": "13829", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Rune platebody in the colours of Guthix.", + "grand_exchange_price": "406762", + "durability": null, + "name": "Guthix platebody", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13830", + "absorb": "3,0,6", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Rune platelegs in the colours of Guthix.", + "grand_exchange_price": "181471", + "durability": null, + "name": "Guthix platelegs", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13831", + "absorb": "2,0,4", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Rune plateskirt in the colours of Guthix.", + "grand_exchange_price": "38388", + "durability": null, + "name": "Guthix plateskirt", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13832", + "absorb": "2,0,4", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "A rune full helmet in the colours of Guthix.", + "grand_exchange_price": "399963", + "durability": null, + "name": "Guthix full helm", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13833", + "absorb": "1,0,3", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0" + }, + { + "examine": "Rune kiteshield in the colours of Guthix.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "3,0,7", + "equip_audio": "2245", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "185266", + "name": "Guthix kiteshield", + "archery_ticket_price": "0", + "id": "13834", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,40,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Rune platebody with complete gold trim & plating.", + "grand_exchange_price": "2034838", + "durability": null, + "name": "Gilded platebody", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13835", + "absorb": "3,0,6", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Rune platelegs with gold plate.", + "grand_exchange_price": "1299758", + "durability": null, + "name": "Gilded platelegs", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13836", + "absorb": "2,0,4", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Rune plateskirt with gold plate.", + "grand_exchange_price": "84191", + "durability": null, + "name": "Gilded plateskirt", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13837", + "absorb": "2,0,4", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Rune full helmet with gold plate.", + "grand_exchange_price": "1057068", + "durability": null, + "name": "Gilded full helm", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13838", + "absorb": "1,0,3", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0" + }, + { + "examine": "Rune kiteshield with gold plate.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "3,0,7", + "equip_audio": "2245", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "506093", + "name": "Gilded kiteshield", + "archery_ticket_price": "0", + "id": "13839", + "bonuses": "0,0,0,-8,-2,44,48,46,-1,46,45,0,0,0,0" + }, + { + "destroy_message": "Your brawling gloves are fragile and will disappear if you drop them. Are you sure you want to drop them?", + "shop_price": "50000", + "examine": "A pair of gloves that gives you bonus Atk, Def, Str and LP xp.", + "durability": null, + "name": "Brawling gloves (melee)", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13845", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "9" + }, + { + "destroy_message": "Your brawling gloves are fragile and will disappear if you drop them. Are you sure you want to drop them?", + "shop_price": "50000", + "examine": "A pair of gloves that gives you bonus Ranged xp.", + "durability": null, + "name": "Brawling gloves (ranged)", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13846", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "9" + }, + { + "destroy_message": "Your brawling gloves are fragile and will disappear if you drop them. Are you sure you want to drop them?", + "shop_price": "50000", + "examine": "A pair of gloves that gives you bonus Magic xp.", + "durability": null, + "name": "Brawling gloves (magic)", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13847", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "9" + }, + { + "destroy_message": "Your brawling gloves are fragile and will disappear if you drop them. Are you sure you want to drop them?", + "shop_price": "50000", + "examine": "A pair of gloves that gives you bonus Prayer xp.", + "durability": null, + "name": "Brawling gloves (prayer)", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13848", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "9" + }, + { + "destroy_message": "Your brawling gloves are fragile and will disappear if you drop them. Are you sure you want to drop them?", + "shop_price": "50000", + "examine": "A pair of gloves that gives you bonus Agility xp.", + "durability": null, + "name": "Brawling gloves (agility)", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13849", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "9" + }, + { + "destroy_message": "Your brawling gloves are fragile and will disappear if you drop them. Are you sure you want to drop them?", + "shop_price": "50000", + "examine": "A pair of gloves that gives you bonus Woodcutting xp.", + "durability": null, + "name": "Brawling gloves (wc)", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13850", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "9" + }, + { + "destroy_message": "Your brawling gloves are fragile and will disappear if you drop them. Are you sure you want to drop them?", + "shop_price": "50000", + "examine": "A pair of gloves that gives you bonus Firemaking xp.", + "durability": null, + "name": "Brawling gloves (fm)", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13851", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "9" + }, + { + "destroy_message": "Your brawling gloves are fragile and will disappear if you drop them. Are you sure you want to drop them?", + "shop_price": "50000", + "examine": "A pair of gloves that gives you bonus Mining xp.", + "durability": null, + "name": "Brawling gloves (mining)", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13852", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "9" + }, + { + "destroy_message": "Your brawling gloves are fragile and will disappear if you drop them. Are you sure you want to drop them?", + "shop_price": "50000", + "examine": "A pair of gloves that gives you bonus Hunting xp.", + "durability": null, + "name": "Brawling gloves (hunter)", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13853", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "9" + }, + { + "destroy_message": "Your brawling gloves are fragile and will disappear if you drop them. Are you sure you want to drop them?", + "shop_price": "50000", + "examine": "A pair of gloves that gives you bonus Thieving xp.", + "durability": null, + "name": "Brawling gloves (thieving)", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13854", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "9" + }, + { + "destroy_message": "Your brawling gloves are fragile and will disappear if you drop them. Are you sure you want to drop them?", + "shop_price": "50000", + "examine": "A pair of gloves that gives you bonus Smithing xp.", + "durability": null, + "name": "Brawling gloves (smithing)", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13855", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "9" + }, + { + "destroy_message": "Your brawling gloves are fragile and will disappear if you drop them. Are you sure you want to drop them?", + "shop_price": "50000", + "examine": "A pair of gloves that gives you bonus Fishing xp.", + "durability": null, + "name": "Brawling gloves (fishing)", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13856", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "9" + }, + { + "destroy_message": "Your brawling gloves are fragile and will disappear if you drop them. Are you sure you want to drop them?", + "shop_price": "50000", + "examine": "A pair of gloves that gives you bonus Cooking xp.", + "durability": null, + "name": "Brawling gloves (cooking)", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13857", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "9" + }, + { + "requirements": "{1,78}-{6,78}", + "shop_price": "500000", + "examine": "This item degrades in combat, and will turn to dust.", + "durability": null, + "destroy": "false", + "attack_speed": "4", + "absorb": "12,6,0", + "equipment_slot": "4", + "destroy_message": "Drop", + "remove_sleeves": "true", + "grand_exchange_price": "1412812", + "name": "Zuriel's robe top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13858", + "bonuses": "0,0,0,35,-10,63,45,74,35,0,60,0,0,0,0" + }, + { + "destroy_message": "Drop", + "requirements": "{1,78}-{6,78}", + "shop_price": "500000", + "examine": "This item degrades in combat, and will turn to dust.", + "grand_exchange_price": "1412812", + "durability": null, + "name": "Zuriel's robe top", + "tradeable": "true", + "destroy": "false", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13859" + }, + { + "requirements": "{1,78}-{6,78}", + "shop_price": "300000", + "examine": "This item degrades in combat, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "12,6,0", + "equipment_slot": "4", + "destroy_message": "Drop", + "remove_sleeves": "true", + "grand_exchange_price": "1412812", + "name": "Zuriel's robe top (deg)", + "archery_ticket_price": "0", + "id": "13860", + "bonuses": "0,0,0,35,-10,63,45,74,35,0,60,0,0,0,0" + }, + { + "requirements": "{1,78}-{6,78}", + "shop_price": "500000", + "examine": "This item degrades in combat, and will turn to dust.", + "durability": null, + "destroy": "false", + "attack_speed": "4", + "absorb": "8,4,0", + "equipment_slot": "7", + "destroy_message": "Drop", + "grand_exchange_price": "986668", + "name": "Zuriel's robe bottom", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13861", + "bonuses": "0,0,0,25,-7,38,35,44,24,0,30,0,0,0,0" + }, + { + "destroy_message": "Drop", + "requirements": "{1,78}-{6,78}", + "shop_price": "500000", + "examine": "This item degrades in combat, and will turn to dust.", + "grand_exchange_price": "986668", + "durability": null, + "name": "Zuriel's robe bottom", + "tradeable": "true", + "destroy": "false", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13862" + }, + { + "requirements": "{1,78}-{6,78}", + "shop_price": "300000", + "examine": "This item degrades in combat, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "8,4,0", + "equipment_slot": "7", + "destroy_message": "Drop", + "grand_exchange_price": "986668", + "name": "Zuriel's robe bottom (deg)", + "archery_ticket_price": "0", + "id": "13863", + "bonuses": "0,0,0,25,-7,38,35,44,24,0,30,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,78}-{6,78}", + "shop_price": "250000", + "examine": "This item degrades in combat, and will turn to dust.", + "durability": null, + "destroy": "false", + "attack_speed": "4", + "absorb": "6,3,0", + "equipment_slot": "0", + "destroy_message": "Drop", + "grand_exchange_price": "361542", + "name": "Zuriel's hood", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13864", + "bonuses": "0,0,0,8,-2,20,16,22,8,0,15,0,0,0,0" + }, + { + "destroy_message": "Drop", + "requirements": "{1,78}-{6,78}", + "shop_price": "250000", + "examine": "This item degrades in combat, and will turn to dust.", + "grand_exchange_price": "361542", + "durability": null, + "name": "Zuriel's hood", + "tradeable": "true", + "destroy": "false", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13865" + }, + { + "remove_head": "true", + "requirements": "{1,78}-{6,78}", + "shop_price": "150000", + "examine": "This item degrades in combat, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "6,3,0", + "equipment_slot": "0", + "destroy_message": "Drop", + "grand_exchange_price": "361542", + "name": "Zuriel's hood (deg)", + "archery_ticket_price": "0", + "id": "13866", + "bonuses": "0,0,0,8,-2,20,16,22,8,0,15,0,0,0,0" + }, + { + "turn90cw_anim": "1207", + "examine": "This item degrades in combat, and will turn to dust.", + "walk_anim": "1205", + "rare_item": "true", + "turn90ccw_anim": "1208", + "attack_speed": "6", + "turn180_anim": "1206", + "absorb": "0,0,0", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "destroy_message": "Drop", + "grand_exchange_price": "2116989", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "13867", + "stand_turn_anim": "1209", + "bonuses": "13,-1,65,18,0,5,7,4,18,0,0,72,0,0,10", + "requirements": "{0,78}-{6,78}", + "shop_price": "300000", + "durability": null, + "destroy": "false", + "weapon_interface": "1", + "equip_audio": "2247", + "render_anim": "28", + "attack_audios": "2555,0,0,0", + "name": "Zuriel's staff" + }, + { + "destroy_message": "Drop", + "requirements": "{0,78}-{6,78}", + "shop_price": "300000", + "examine": "This item degrades in combat, and will turn to dust.", + "grand_exchange_price": "2116989", + "durability": null, + "name": "Zuriel's staff", + "tradeable": "true", + "destroy": "false", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13868" + }, + { + "turn90cw_anim": "1207", + "examine": "This item degrades in combat, and will turn to dust.", + "walk_anim": "1205", + "rare_item": "true", + "turn90ccw_anim": "1208", + "attack_speed": "6", + "turn180_anim": "1206", + "absorb": "0,0,0", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "destroy_message": "Drop", + "grand_exchange_price": "2116989", + "stand_anim": "813", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "13869", + "stand_turn_anim": "1209", + "bonuses": "13,-1,65,18,0,5,7,4,18,0,0,72,0,0,10", + "requirements": "{0,78}-{6,78}", + "shop_price": "300000", + "durability": null, + "destroy": "true", + "weapon_interface": "1", + "equip_audio": "2247", + "render_anim": "28", + "attack_audios": "2555,0,0,0", + "name": "Zuriel's staff (deg)" + }, + { + "requirements": "{1,78}-{4,78}", + "shop_price": "500000", + "examine": "This item degrades in combat, and will turn to dust.", + "durability": null, + "destroy": "false", + "attack_speed": "4", + "absorb": "0,12,6", + "equipment_slot": "4", + "destroy_message": "Drop", + "remove_sleeves": "true", + "grand_exchange_price": "926341", + "name": "Morrigan's leather body", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13870", + "bonuses": "0,0,0,-15,36,61,53,66,75,62,60,0,0,0,0" + }, + { + "destroy_message": "Drop", + "requirements": "{1,78}-{4,78}", + "shop_price": "500000", + "examine": "This item degrades in combat, and will turn to dust.", + "grand_exchange_price": "926341", + "durability": null, + "name": "Morrigan's leather body", + "tradeable": "true", + "destroy": "false", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13871" + }, + { + "requirements": "{1,78}-{4,78}", + "shop_price": "300000", + "examine": "This item degrades in combat, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,12,6", + "equipment_slot": "4", + "destroy_message": "Drop", + "remove_sleeves": "true", + "grand_exchange_price": "926341", + "name": "Morrigan's leather body (deg)", + "archery_ticket_price": "0", + "id": "13872", + "bonuses": "0,0,0,-15,36,61,53,66,75,62,60,0,0,0,0" + }, + { + "requirements": "{1,78}-{4,78}", + "shop_price": "500000", + "examine": "This item degrades in combat, and will turn to dust.", + "durability": null, + "destroy": "false", + "attack_speed": "4", + "absorb": "0,8,4", + "equipment_slot": "7", + "destroy_message": "Drop, Destroy after degrading.", + "grand_exchange_price": "510395", + "name": "Morrigan's leather chaps", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13873", + "bonuses": "0,0,0,-10,23,35,29,37,46,35,30,0,0,0,0" + }, + { + "destroy_message": "Drop, Destroy after degrading.", + "requirements": "{1,78}-{4,78}", + "shop_price": "500000", + "examine": "This item degrades in combat, and will turn to dust.", + "grand_exchange_price": "510395", + "durability": null, + "name": "Morrigan's leather chaps", + "tradeable": "true", + "destroy": "false", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13874" + }, + { + "requirements": "{1,78}-{4,78}", + "shop_price": "300000", + "examine": "This item degrades in combat, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,8,4", + "equipment_slot": "7", + "destroy_message": "Drop, Destroy after degrading.", + "grand_exchange_price": "510395", + "name": "Morrigan's leather chaps (deg)", + "archery_ticket_price": "0", + "id": "13875", + "bonuses": "0,0,0,-10,23,35,29,37,46,35,30,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,78}-{4,78}", + "shop_price": "250000", + "examine": "This item degrades in combat, and will turn to dust.", + "durability": null, + "destroy": "false", + "attack_speed": "4", + "absorb": "0,6,3", + "equip_audio": "2238", + "equipment_slot": "0", + "destroy_message": "Drop", + "grand_exchange_price": "236411", + "name": "Morrigan's coif", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13876", + "bonuses": "0,0,0,-5,13,8,11,14,8,12,15,0,0,0,0" + }, + { + "destroy_message": "Drop", + "requirements": "{1,78}-{4,78}", + "shop_price": "250000", + "examine": "This item degrades in combat, and will turn to dust.", + "grand_exchange_price": "236411", + "durability": null, + "name": "Morrigan's coif", + "tradeable": "true", + "destroy": "false", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13877" + }, + { + "remove_head": "true", + "requirements": "{1,78}-{4,78}", + "shop_price": "150000", + "examine": "This item degrades in combat, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,6,3", + "equip_audio": "2238", + "equipment_slot": "0", + "destroy_message": "Drop", + "grand_exchange_price": "236411", + "name": "Morrigan's coif (deg)", + "archery_ticket_price": "0", + "id": "13878", + "bonuses": "0,0,0,-5,13,8,11,14,8,12,15,0,0,0,0" + }, + { + "requirements": "{4,78}", + "shop_price": "4000", + "examine": "A vicious javelin.", + "has_special": "true", + "durability": null, + "destroy": "false", + "attack_speed": "6", + "weapon_interface": "18", + "absorb": "0,0,0", + "equip_audio": "2244", + "render_anim": "1381", + "equipment_slot": "3", + "destroy_message": "Drop", + "grand_exchange_price": "19944", + "name": "Morrigan's javelin", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13879", + "bonuses": "0,0,0,0,105,0,0,0,0,0,0,0,0,0,145" + }, + { + "requirements": "{4,78}", + "shop_price": "10000", + "examine": "A vicious javelin.", + "has_special": "true", + "durability": null, + "destroy": "false", + "attack_speed": "6", + "weapon_interface": "18", + "absorb": "0,0,0", + "equip_audio": "2244", + "render_anim": "1381", + "equipment_slot": "3", + "destroy_message": "Drop", + "grand_exchange_price": "19944", + "name": "Morrigan's javelin(p)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13880", + "bonuses": "0,0,0,0,105,0,0,0,0,0,0,0,0,0,145" + }, + { + "requirements": "{4,78}", + "shop_price": "10000", + "examine": "A vicious javelin.", + "has_special": "true", + "durability": null, + "destroy": "false", + "attack_speed": "6", + "weapon_interface": "18", + "absorb": "0,0,0", + "equip_audio": "2244", + "render_anim": "1381", + "equipment_slot": "3", + "destroy_message": "Drop", + "grand_exchange_price": "19944", + "name": "Morrigan's javelin(p+)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13881", + "bonuses": "0,0,0,0,105,0,0,0,0,0,0,0,0,0,145" + }, + { + "requirements": "{4,78}", + "shop_price": "10000", + "examine": "A vicious javelin.", + "has_special": "true", + "durability": null, + "destroy": "false", + "attack_speed": "6", + "weapon_interface": "18", + "absorb": "0,0,0", + "equip_audio": "2244", + "render_anim": "1381", + "equipment_slot": "3", + "destroy_message": "Drop", + "grand_exchange_price": "19944", + "name": "Morrigan's javelin(p++)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13882", + "bonuses": "0,0,0,0,105,0,0,0,0,0,0,0,0,0,145" + }, + { + "requirements": "{4,78}", + "shop_price": "4000", + "examine": "A vicious throwing axe.", + "has_special": "true", + "durability": null, + "destroy": "false", + "attack_speed": "5", + "weapon_interface": "18", + "absorb": "0,0,0", + "equipment_slot": "3", + "destroy_message": "Drop", + "grand_exchange_price": "9994", + "name": "Morrigan's throwing axe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13883", + "bonuses": "0,0,0,0,93,0,0,0,0,0,0,0,0,0,117" + }, + { + "requirements": "{1,78}", + "shop_price": "500000", + "examine": "This item degrades in combat, and will turn to dust.", + "durability": null, + "destroy": "false", + "attack_speed": "4", + "absorb": "6,0,12", + "equip_audio": "2239", + "equipment_slot": "4", + "destroy_message": "Drop", + "remove_sleeves": "true", + "grand_exchange_price": "1619096", + "name": "Statius's platebody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13884", + "bonuses": "5,5,7,-30,-10,154,145,121,-6,157,60,5,0,0,0" + }, + { + "destroy_message": "Drop", + "requirements": "{1,78}", + "shop_price": "500000", + "examine": "This item degrades in combat, and will turn to dust.", + "grand_exchange_price": "1619096", + "durability": null, + "name": "Statius's platebody", + "tradeable": "true", + "destroy": "false", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13885" + }, + { + "requirements": "{1,78}", + "shop_price": "300000", + "examine": "This item degrades in combat, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "6,0,12", + "equip_audio": "2239", + "equipment_slot": "4", + "destroy_message": "Drop", + "remove_sleeves": "true", + "grand_exchange_price": "1619096", + "name": "Statius's platebody (deg)", + "archery_ticket_price": "0", + "id": "13886", + "bonuses": "5,5,7,-30,-10,154,145,121,-6,157,60,5,0,0,0" + }, + { + "requirements": "{1,78}", + "shop_price": "500000", + "examine": "This item degrades in combat, and will turn to dust.", + "durability": null, + "destroy": "false", + "attack_speed": "4", + "absorb": "6,0,12", + "equipment_slot": "4", + "destroy_message": "Drop, Destroy once it has been degraded.", + "remove_sleeves": "true", + "grand_exchange_price": "2154168", + "name": "Vesta's chainbody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13887", + "bonuses": "5,7,7,-15,0,120,131,145,-3,140,60,6,0,0,0" + }, + { + "destroy_message": "Drop, Destroy once it has been degraded.", + "requirements": "{1,78}", + "shop_price": "500000", + "examine": "This item degrades in combat, and will turn to dust.", + "grand_exchange_price": "2154168", + "durability": null, + "name": "Vesta's chainbody", + "tradeable": "true", + "destroy": "false", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13888" + }, + { + "requirements": "{1,78}", + "shop_price": "300000", + "examine": "This item degrades in combat, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "6,0,12", + "equipment_slot": "4", + "destroy_message": "Drop, Destroy once it has been degraded.", + "remove_sleeves": "true", + "grand_exchange_price": "2154168", + "name": "Vesta's chainbody (deg)", + "archery_ticket_price": "0", + "id": "13889", + "bonuses": "5,7,7,-15,0,120,131,145,-3,140,60,6,0,0,0" + }, + { + "requirements": "{1,78}", + "shop_price": "500000", + "examine": "This item degrades in combat, and will turn to dust.", + "durability": null, + "destroy": "false", + "attack_speed": "4", + "absorb": "4,0,8", + "equip_audio": "2242", + "equipment_slot": "7", + "destroy_message": "Drop", + "grand_exchange_price": "1735029", + "name": "Statius's platelegs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13890", + "bonuses": "3,3,5,-21,-7,110,106,97,-4,121,30,3,0,0,0" + }, + { + "destroy_message": "Drop", + "requirements": "{1,78}", + "shop_price": "500000", + "examine": "This item degrades in combat, and will turn to dust.", + "grand_exchange_price": "1735029", + "durability": null, + "name": "Statius's platelegs", + "tradeable": "true", + "destroy": "false", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13891" + }, + { + "requirements": "{1,78}", + "shop_price": "300000", + "examine": "This item degrades in combat, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "4,0,8", + "equip_audio": "2242", + "equipment_slot": "7", + "destroy_message": "Drop", + "grand_exchange_price": "1735029", + "name": "Statius's platelegs (deg)", + "archery_ticket_price": "0", + "id": "13892", + "bonuses": "3,3,5,-21,-7,110,106,97,-4,121,30,3,0,0,0" + }, + { + "requirements": "{1,78}", + "shop_price": "500000", + "examine": "This item degrades in combat, and will turn to dust.", + "durability": null, + "destroy": "false", + "attack_speed": "4", + "absorb": "4,0,8", + "equipment_slot": "7", + "destroy_message": "Drop", + "grand_exchange_price": "1860767", + "name": "Vesta's plateskirt", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13893", + "bonuses": "3,5,5,-17,-4,86,100,112,-2,118,30,3,0,0,0" + }, + { + "destroy_message": "Drop", + "requirements": "{1,78}", + "shop_price": "500000", + "examine": "This item degrades in combat, and will turn to dust.", + "grand_exchange_price": "1860767", + "durability": null, + "name": "Vesta's plateskirt", + "tradeable": "true", + "destroy": "false", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13894" + }, + { + "requirements": "{1,78}", + "shop_price": "300000", + "examine": "This item degrades in combat, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "4,0,8", + "equipment_slot": "7", + "destroy_message": "Drop", + "grand_exchange_price": "1860767", + "name": "Vesta's plateskirt (deg)", + "archery_ticket_price": "0", + "id": "13895", + "bonuses": "3,5,5,-17,-4,86,100,112,-2,118,30,3,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,78}", + "shop_price": "250000", + "examine": "This item degrades in combat, and will turn to dust.", + "durability": null, + "destroy": "false", + "attack_speed": "4", + "absorb": "3,0,6", + "equip_audio": "2240", + "equipment_slot": "0", + "destroy_message": "Drop", + "grand_exchange_price": "1301986", + "name": "Statius's full helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13896", + "bonuses": "3,3,4,-6,-2,65,70,63,-1,71,15,3,0,0,0" + }, + { + "requirements": "{1,78}", + "shop_price": "250000", + "examine": "This item degrades in combat, and will turn to dust.", + "durability": null, + "destroy": "false", + "attack_speed": "4", + "equip_audio": "", + "destroy_message": "Drop", + "grand_exchange_price": "1301986", + "name": "Statius's full helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13897" + }, + { + "remove_head": "true", + "requirements": "{1,78}", + "shop_price": "150000", + "examine": "This item degrades in combat, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "3,0,6", + "equip_audio": "2240", + "equipment_slot": "0", + "destroy_message": "Drop", + "grand_exchange_price": "1301986", + "name": "Statius' full helm (deg)", + "archery_ticket_price": "0", + "id": "13898", + "bonuses": "3,3,4,-6,-2,65,70,63,-1,71,15,3,0,0,0" + }, + { + "turn90cw_anim": "1207", + "examine": "This item degrades in combat, and will turn to dust.", + "walk_anim": "1205", + "has_special": "true", + "rare_item": "true", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "turn180_anim": "1206", + "absorb": "0,0,0", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "destroy_message": "Drop", + "grand_exchange_price": "10464249", + "tradeable": "true", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "13899", + "stand_turn_anim": "823", + "bonuses": "106,121,-2,0,0,1,4,3,0,0,0,118,0,0,0", + "requirements": "{0,78}", + "shop_price": "300000", + "durability": null, + "destroy": "false", + "weapon_interface": "6", + "equip_audio": "2248", + "render_anim": "1426", + "attack_audios": "2500,2500,2517,2500", + "name": "Vesta's longsword" + }, + { + "destroy_message": "Drop", + "requirements": "{0,78}", + "shop_price": "300000", + "examine": "This item degrades in combat, and will turn to dust.", + "grand_exchange_price": "10464249", + "durability": null, + "name": "Vesta's longsword", + "tradeable": "true", + "destroy": "false", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13900" + }, + { + "turn90cw_anim": "1207", + "examine": "This item degrades in combat, and will turn to dust.", + "walk_anim": "1205", + "has_special": "true", + "rare_item": "true", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "turn180_anim": "1206", + "absorb": "0,0,0", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "destroy_message": "Drop", + "grand_exchange_price": "10464249", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "13901", + "stand_turn_anim": "823", + "bonuses": "106,121,-2,0,0,1,4,3,0,0,0,118,0,0,0", + "requirements": "{0,78}", + "shop_price": "300000", + "durability": null, + "destroy": "true", + "weapon_interface": "6", + "equip_audio": "2248", + "render_anim": "1426", + "attack_audios": "2500,2500,2517,2500", + "name": "Vesta's longsword (deg)" + }, + { + "turn90cw_anim": "821", + "examine": "This item degrades in combat, and will turn to dust.", + "walk_anim": "819", + "has_special": "true", + "turn90ccw_anim": "822", + "attack_speed": "6", + "turn180_anim": "820", + "absorb": "0,0,0", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "395,395,395,395", + "destroy_message": "Drop, Destroy once it has been degraded.", + "grand_exchange_price": "7424450", + "stand_anim": "808", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "13902", + "stand_turn_anim": "823", + "bonuses": "-4,-4,123,0,0,0,0,0,0,0,0,114,0,0,0", + "requirements": "{0,78}", + "shop_price": "300000", + "durability": null, + "destroy": "false", + "weapon_interface": "10", + "equip_audio": "2233", + "attack_audios": "2504,0,0,0", + "name": "Statius's warhammer" + }, + { + "destroy_message": "Drop, Destroy once it has been degraded.", + "requirements": "{0,78}", + "shop_price": "300000", + "examine": "This item degrades in combat, and will turn to dust.", + "grand_exchange_price": "7424450", + "durability": null, + "name": "Statius's warhammer", + "tradeable": "true", + "destroy": "false", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13903" + }, + { + "turn90cw_anim": "821", + "examine": "This item degrades in combat, and will turn to dust.", + "walk_anim": "819", + "has_special": "true", + "turn90ccw_anim": "822", + "attack_speed": "6", + "turn180_anim": "820", + "absorb": "0,0,0", + "equipment_slot": "3", + "attack_anims": "395,395,395,395", + "destroy_message": "Drop, Destroy once it has been degraded.", + "grand_exchange_price": "7424450", + "stand_anim": "808", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "13904", + "stand_turn_anim": "823", + "bonuses": "-4,-4,123,0,0,0,0,0,0,0,0,114,0,0,0", + "shop_price": "300000", + "durability": null, + "destroy": "true", + "weapon_interface": "10", + "equip_audio": "2233", + "render_anim": "1426", + "attack_audios": "2504,0,0,0", + "name": "Statius' warhammer (deg)" + }, + { + "turn90cw_anim": "1207", + "examine": "This item degrades in combat, and will turn to dust.", + "walk_anim": "1205", + "has_special": "true", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "two_handed": "true", + "turn180_anim": "1206", + "absorb": "0,0,0", + "defence_anim": "2079", + "equipment_slot": "3", + "attack_anims": "2080,2081,2082,2080", + "destroy_message": "Drop", + "grand_exchange_price": "5264612", + "stand_anim": "813", + "tradeable": "true", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "13905", + "stand_turn_anim": "1209", + "bonuses": "133,113,120,0,0,18,21,21,0,0,0,122,0,0,0", + "requirements": "{0,78}", + "shop_price": "300000", + "durability": null, + "destroy": "false", + "weight": "4.2", + "weapon_interface": "14", + "equip_audio": "2247", + "render_anim": "28", + "name": "Vesta's spear" + }, + { + "requirements": "{0,78}", + "shop_price": "300000", + "examine": "This item degrades in combat, and will turn to dust.", + "durability": null, + "destroy": "false", + "attack_speed": "4", + "two_handed": "true", + "destroy_message": "Drop", + "grand_exchange_price": "5264612", + "name": "Vesta's spear", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13906" + }, + { + "requirements": "{0,78}", + "shop_price": "180000", + "examine": "This item degrades in combat, and will turn to dust.", + "walk_anim": "1205", + "has_special": "true", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "two_handed": "true", + "turn90ccw_anim": "1208", + "weapon_interface": "14", + "absorb": "0,0,0", + "equip_audio": "2247", + "defence_anim": "2079", + "render_anim": "28", + "equipment_slot": "3", + "attack_anims": "2080,2081,2082,2080", + "destroy_message": "Drop", + "grand_exchange_price": "5264612", + "name": "Vesta's spear (deg)", + "archery_ticket_price": "0", + "id": "13907", + "bonuses": "133,113,120,0,0,18,21,21,0,0,0,122,0,0,0" + }, + { + "requirements": "{1,20}", + "shop_price": "125000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "6,0,12", + "equip_audio": "2239", + "equipment_slot": "4", + "destroy_message": "Drop", + "remove_sleeves": "true", + "grand_exchange_price": "1897306", + "name": "Corrupt statius's platebody", + "archery_ticket_price": "0", + "id": "13908", + "bonuses": "5,5,7,-10,-30,154,145,121,-6,157,60,5,0,0,0" + }, + { + "destroy_message": "Drop", + "requirements": "{1,20}", + "shop_price": "125000", + "examine": "This item degrades while worn, and will turn to dust.", + "grand_exchange_price": "1897306", + "durability": null, + "name": "Corrupt statius's platebody", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13909" + }, + { + "requirements": "{1,20}}", + "shop_price": "75000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "6,0,12", + "equip_audio": "2239", + "equipment_slot": "4", + "destroy_message": "Drop", + "remove_sleeves": "true", + "grand_exchange_price": "1897306", + "name": "Corrupt statius's platebody (deg)", + "archery_ticket_price": "0", + "id": "13910", + "bonuses": "5,5,7,-10,-30,154,145,121,-6,157,60,5,0,0,0" + }, + { + "requirements": "{1,20}", + "shop_price": "125000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "6,0,12", + "equipment_slot": "4", + "destroy_message": "Drop", + "remove_sleeves": "true", + "grand_exchange_price": "2546175", + "name": "Corrupt vesta's chainbody", + "archery_ticket_price": "0", + "id": "13911", + "bonuses": "5,7,7,-15,0,120,131,145,-3,140,60,6,0,0,0" + }, + { + "destroy_message": "Drop", + "requirements": "{1,20}", + "shop_price": "125000", + "examine": "This item degrades while worn, and will turn to dust.", + "grand_exchange_price": "2546175", + "durability": null, + "name": "Corrupt vesta's chainbody", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13912" + }, + { + "requirements": "{1,20}", + "shop_price": "75000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "6,0,12", + "equipment_slot": "4", + "destroy_message": "Drop", + "remove_sleeves": "true", + "grand_exchange_price": "2546175", + "name": "Corrupt vesta's chainbody (deg)", + "archery_ticket_price": "0", + "id": "13913", + "bonuses": "5,7,7,-15,0,120,131,145,-3,140,60,6,0,0,0" + }, + { + "requirements": "{1,20}", + "shop_price": "125000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "4,0,8", + "equip_audio": "2242", + "equipment_slot": "7", + "destroy_message": "Drop", + "grand_exchange_price": "1734527", + "name": "Corrupt statius's platelegs", + "archery_ticket_price": "0", + "id": "13914", + "bonuses": "3,3,5,-21,-7,110,106,97,-4,121,30,3,0,0,0" + }, + { + "destroy_message": "Drop", + "requirements": "{1,20}", + "shop_price": "125000", + "examine": "This item degrades while worn, and will turn to dust.", + "grand_exchange_price": "1734527", + "durability": null, + "name": "Corrupt statius's platelegs", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13915" + }, + { + "requirements": "{1,20}", + "shop_price": "75000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "4,0,8", + "equip_audio": "2242", + "equipment_slot": "7", + "destroy_message": "Drop", + "grand_exchange_price": "1734527", + "name": "Corrupt statius's platelegs (deg)", + "archery_ticket_price": "0", + "id": "13916", + "bonuses": "3,3,5,-21,-7,110,106,97,-4,121,30,3,0,0,0" + }, + { + "requirements": "{1,20}", + "shop_price": "125000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "4,0,8", + "equipment_slot": "7", + "destroy_message": "Drop", + "grand_exchange_price": "1942627", + "name": "Corrupt vesta's plateskirt", + "archery_ticket_price": "0", + "id": "13917", + "bonuses": "3,5,5,-17,-4,86,100,112,-2,118,30,3,0,0,0" + }, + { + "destroy_message": "Drop", + "requirements": "{1,20}", + "shop_price": "125000", + "examine": "This item degrades while worn, and will turn to dust.", + "grand_exchange_price": "1942627", + "durability": null, + "name": "Corrupt vesta's plateskirt", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13918" + }, + { + "requirements": "{1,20}", + "shop_price": "75000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "4,0,8", + "equipment_slot": "7", + "destroy_message": "Drop", + "grand_exchange_price": "1942627", + "name": "Corrupt vesta's plateskirt (deg)", + "archery_ticket_price": "0", + "id": "13919", + "bonuses": "3,5,5,-17,-4,86,100,112,-2,118,30,3,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,20}", + "shop_price": "50000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "3,0,6", + "equipment_slot": "0", + "destroy_message": "Drop", + "grand_exchange_price": "1062835", + "name": "Corrupt statius's full helm", + "archery_ticket_price": "0", + "id": "13920", + "bonuses": "3,3,4,-6,-2,65,70,63,-1,71,15,3,0,0,0" + }, + { + "destroy_message": "Drop", + "requirements": "{1,20}", + "shop_price": "50000", + "examine": "This item degrades while worn, and will turn to dust.", + "grand_exchange_price": "1062835", + "durability": null, + "name": "Corrupt statius's full helm", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13921" + }, + { + "remove_head": "true", + "requirements": "{1,20}", + "shop_price": "30000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "3,0,6", + "equip_audio": "2240", + "equipment_slot": "0", + "destroy_message": "Drop", + "grand_exchange_price": "1062835", + "name": "Corrupt statius' full helm (deg)", + "archery_ticket_price": "0", + "id": "13922", + "bonuses": "3,3,4,-6,-2,65,70,63,-1,71,15,3,0,0,0" + }, + { + "requirements": "{0,20}", + "shop_price": "125000", + "turn90cw_anim": "1207", + "examine": "This item degrades while worn, and will turn to dust.", + "walk_anim": "1205", + "durability": null, + "destroy": "true", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "weapon_interface": "5", + "turn180_anim": "1206", + "absorb": "0,0,0", + "equip_audio": "2248", + "render_anim": "1426", + "equipment_slot": "3", + "attack_anims": "381,390,390,390", + "destroy_message": "Drop", + "grand_exchange_price": "3739998", + "name": "Corrupt vesta's longsword", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "13923", + "stand_turn_anim": "823", + "bonuses": "106,121,-2,0,0,1,4,3,0,0,0,118,0,0,0" + }, + { + "requirements": "{0,20}", + "shop_price": "125000", + "turn90cw_anim": "1207", + "examine": "This item degrades while worn, and will turn to dust.", + "walk_anim": "1205", + "durability": null, + "destroy": "true", + "turn90ccw_anim": "1208", + "attack_speed": "4", + "turn180_anim": "1206", + "render_anim": "1426", + "attack_anims": "381,390,390,390", + "destroy_message": "Drop", + "grand_exchange_price": "3739998", + "name": "Corrupt vesta's longsword", + "tradeable": "true", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "13924", + "stand_turn_anim": "823" + }, + { + "requirements": "{0,20}", + "shop_price": "75000", + "turn90cw_anim": "1207", + "examine": "This item degrades while worn, and will turn to dust.", + "walk_anim": "1205", + "durability": null, + "destroy": "true", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "weapon_interface": "5", + "turn180_anim": "1206", + "absorb": "0,0,0", + "equip_audio": "2248", + "render_anim": "1426", + "equipment_slot": "3", + "destroy_message": "Drop", + "grand_exchange_price": "3739998", + "name": "C. vesta's longsword (deg)", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "13925", + "stand_turn_anim": "823", + "bonuses": "106,121,-2,0,0,1,4,3,0,0,0,118,0,0,0" + }, + { + "requirements": "{0,20}", + "shop_price": "125000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "6", + "weapon_interface": "8", + "absorb": "0,0,0", + "equip_audio": "2233", + "defence_anim": "397", + "equipment_slot": "3", + "destroy_message": "Drop", + "grand_exchange_price": "3033516", + "attack_audios": "395,395,395,395", + "name": "Corrupt statius's warhammer", + "archery_ticket_price": "0", + "id": "13926", + "bonuses": "-4,-4,123,0,0,0,0,0,0,0,0,114,0,0,0" + }, + { + "destroy_message": "Drop", + "requirements": "{0,20}", + "shop_price": "125000", + "examine": "This item degrades while worn, and will turn to dust.", + "grand_exchange_price": "3033516", + "durability": null, + "name": "Corrupt statius's warhammer", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13927" + }, + { + "requirements": "{0,20}", + "shop_price": "75000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "6", + "weapon_interface": "8", + "absorb": "0,0,0", + "equip_audio": "2233", + "equipment_slot": "3", + "destroy_message": "Drop", + "grand_exchange_price": "3033516", + "name": "C. statius's warhammer (deg)", + "archery_ticket_price": "0", + "id": "13928", + "bonuses": "-4,-4,123,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "requirements": "{0,20}", + "shop_price": "125000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "14", + "absorb": "0,0,0", + "equip_audio": "2247", + "render_anim": "28", + "equipment_slot": "3", + "attack_anims": "2080,2081,2082,2080", + "destroy_message": "Drop", + "grand_exchange_price": "343474", + "name": "Corrupt vesta's spear", + "archery_ticket_price": "0", + "id": "13929", + "bonuses": "133,113,120,0,0,18,21,21,0,0,0,0,0,0,0" + }, + { + "requirements": "{0,20}", + "shop_price": "125000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "two_handed": "true", + "destroy_message": "Drop", + "grand_exchange_price": "343474", + "name": "Corrupt vesta's spear", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13930" + }, + { + "requirements": "{0,20}", + "shop_price": "75000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "14", + "absorb": "0,0,0", + "equip_audio": "2247", + "render_anim": "28", + "equipment_slot": "3", + "destroy_message": "Drop", + "grand_exchange_price": "343474", + "name": "Corrupt vesta's spear (deg)", + "archery_ticket_price": "0", + "id": "13931", + "bonuses": "133,113,120,0,0,18,21,21,0,0,0,0,0,0,0" + }, + { + "requirements": "{1,20}-{6,20}", + "shop_price": "125000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "12,6,0", + "equipment_slot": "4", + "destroy_message": "Drop", + "remove_sleeves": "true", + "grand_exchange_price": "253230", + "name": "Corrupt zuriel's robe top", + "archery_ticket_price": "0", + "id": "13932", + "bonuses": "0,0,0,35,-10,63,45,74,35,0,60,0,0,0,0" + }, + { + "destroy_message": "Drop", + "requirements": "{1,20}-{6,20}", + "shop_price": "125000", + "examine": "This item degrades while worn, and will turn to dust.", + "grand_exchange_price": "253230", + "durability": null, + "name": "Corrupt zuriel's robe top", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13933" + }, + { + "requirements": "{1,20}-{6,20}", + "shop_price": "75000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "12,6,0", + "equipment_slot": "4", + "destroy_message": "Drop", + "remove_sleeves": "true", + "grand_exchange_price": "253230", + "name": "Corrupt zuriel's robe top (deg)", + "archery_ticket_price": "0", + "id": "13934", + "bonuses": "0,0,0,35,-10,63,45,74,35,0,60,0,0,0,0" + }, + { + "requirements": "{1,20}-{6,20}", + "shop_price": "125000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "8,4,0", + "equipment_slot": "7", + "destroy_message": "Drop", + "grand_exchange_price": "121290", + "name": "Corrupt zuriel's robe bottom", + "archery_ticket_price": "0", + "id": "13935", + "bonuses": "0,0,0,25,-7,38,35,44,24,0,30,0,0,0,0" + }, + { + "destroy_message": "Drop", + "requirements": "{1,20}-{6,20}", + "shop_price": "125000", + "examine": "This item degrades while worn, and will turn to dust.", + "grand_exchange_price": "121290", + "durability": null, + "name": "Corrupt zuriel's robe bottom", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13936" + }, + { + "requirements": "{1,20}-{6,20}", + "shop_price": "75000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "8,4,0", + "equipment_slot": "7", + "destroy_message": "Drop", + "grand_exchange_price": "121290", + "name": "Corrupt zuriel's robe bottom (deg)", + "archery_ticket_price": "0", + "id": "13937", + "bonuses": "0,0,0,25,-7,38,35,44,24,0,30,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,20}-{6,20}", + "shop_price": "50000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "6,3,0", + "equipment_slot": "0", + "destroy_message": "Drop", + "grand_exchange_price": "43778", + "name": "Corrupt zuriel's hood", + "archery_ticket_price": "0", + "id": "13938", + "bonuses": "0,0,0,8,-2,20,16,22,8,0,15,0,0,0,0" + }, + { + "destroy_message": "Drop", + "requirements": "{1,20}-{6,20}", + "shop_price": "50000", + "examine": "This item degrades while worn, and will turn to dust.", + "grand_exchange_price": "43778", + "durability": null, + "name": "Corrupt zuriel's hood", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13939" + }, + { + "remove_head": "true", + "requirements": "{1,20}-{6,20}", + "shop_price": "30000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "6,3,0", + "equipment_slot": "0", + "destroy_message": "Drop", + "grand_exchange_price": "43778", + "name": "Corrupt zuriel's hood (deg)", + "archery_ticket_price": "0", + "id": "13940", + "bonuses": "0,0,0,8,-2,20,16,22,8,0,15,0,0,0,0" + }, + { + "requirements": "{6,20}", + "shop_price": "125000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "6", + "weapon_interface": "1", + "absorb": "0,0,0", + "equip_audio": "2247", + "render_anim": "28", + "equipment_slot": "3", + "attack_anims": "2555,0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "219418", + "attack_audios": "2555,0,0,0", + "name": "Corrupt zuriel's staff", + "archery_ticket_price": "0", + "id": "13941", + "bonuses": "13,-1,65,18,0,5,7,4,18,0,0,72,0,0,10" + }, + { + "destroy_message": "Drop", + "requirements": "{6,20}", + "shop_price": "125000", + "examine": "This item degrades while worn, and will turn to dust.", + "grand_exchange_price": "219418", + "durability": null, + "name": "Corrupt zuriel's staff", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13942" + }, + { + "requirements": "{6,20}", + "shop_price": "70000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "6", + "weapon_interface": "1", + "absorb": "0,0,0", + "equip_audio": "2247", + "render_anim": "28", + "equipment_slot": "3", + "destroy_message": "Drop", + "grand_exchange_price": "219418", + "name": "Corrupt zuriel's staff (deg)", + "archery_ticket_price": "0", + "id": "13943", + "bonuses": "13,-1,65,18,0,5,7,4,18,0,0,72,0,0,10" + }, + { + "requirements": "{1,20}-{4,20}", + "shop_price": "125000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,12,6", + "equipment_slot": "4", + "destroy_message": "Drop", + "remove_sleeves": "true", + "grand_exchange_price": "387212", + "name": "Corrupt morrigan's leather body", + "archery_ticket_price": "0", + "id": "13944", + "bonuses": "0,0,0,-15,36,61,53,66,75,62,60,0,0,0,0" + }, + { + "destroy_message": "Drop", + "requirements": "{1,20}-{4,20}", + "shop_price": "125000", + "examine": "This item degrades while worn, and will turn to dust.", + "grand_exchange_price": "387212", + "durability": null, + "name": "Corrupt morrigan's leather body", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13945" + }, + { + "requirements": "{1,20}-{4,20}", + "shop_price": "75000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,12,6", + "equipment_slot": "4", + "destroy_message": "Drop", + "remove_sleeves": "true", + "grand_exchange_price": "387212", + "name": "Corrupt morrigan's leather body (deg)", + "archery_ticket_price": "0", + "id": "13946", + "bonuses": "0,0,0,-15,36,61,53,66,75,62,60,0,0,0,0" + }, + { + "requirements": "{1,20}-{4,20}", + "shop_price": "125000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,8,4", + "equipment_slot": "7", + "destroy_message": "Drop", + "grand_exchange_price": "84592", + "name": "Corrupt morrigan's leather chaps", + "archery_ticket_price": "0", + "id": "13947", + "bonuses": "0,0,0,-10,23,35,29,37,46,35,30,0,0,0,0" + }, + { + "destroy_message": "Drop", + "requirements": "{1,20}-{4,20}", + "shop_price": "125000", + "examine": "This item degrades while worn, and will turn to dust.", + "grand_exchange_price": "84592", + "durability": null, + "name": "Corrupt morrigan's leather chaps", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13948" + }, + { + "requirements": "{1,20}-{4,20}", + "shop_price": "75000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,8,4", + "equipment_slot": "7", + "destroy_message": "Drop", + "grand_exchange_price": "84592", + "name": "Corrupt morrigan's leather chaps (deg)", + "archery_ticket_price": "0", + "id": "13949", + "bonuses": "0,0,0,-10,23,35,29,37,46,35,30,0,0,0,0" + }, + { + "remove_head": "true", + "requirements": "{1,20}-{4,20}", + "shop_price": "50000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,6,3", + "equip_audio": "2238", + "equipment_slot": "0", + "destroy_message": "Drop", + "grand_exchange_price": "63502", + "name": "Corrupt morrigan's coif", + "archery_ticket_price": "0", + "id": "13950", + "bonuses": "0,0,0,-5,13,8,11,14,8,12,15,0,0,0,0" + }, + { + "destroy_message": "Drop", + "requirements": "{1,20}-{4,20}", + "shop_price": "50000", + "examine": "This item degrades while worn, and will turn to dust.", + "grand_exchange_price": "63502", + "durability": null, + "name": "Corrupt morrigan's coif", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13951" + }, + { + "remove_head": "true", + "requirements": "{1,20}-{4,20}", + "shop_price": "30000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,6,3", + "equip_audio": "2238", + "equipment_slot": "0", + "destroy_message": "Drop", + "grand_exchange_price": "63502", + "name": "Corrupt morrigan's coif (deg)", + "archery_ticket_price": "0", + "id": "13952", + "bonuses": "0,0,0,-5,13,8,11,14,8,12,15,0,0,0,0" + }, + { + "requirements": "{4,20}", + "shop_price": "1000", + "examine": "A vicious javelin.", + "durability": null, + "destroy": "true", + "attack_speed": "6", + "weapon_interface": "18", + "absorb": "0,0,0", + "equip_audio": "2244", + "render_anim": "1381", + "equipment_slot": "3", + "destroy_message": "Drop", + "grand_exchange_price": "6752", + "name": "Corrupt morrigan's javelin", + "archery_ticket_price": "0", + "id": "13953", + "bonuses": "0,0,0,0,105,0,0,0,0,0,0,0,0,0,145" + }, + { + "requirements": "{4,20}", + "shop_price": "10000", + "examine": "A vicious javelin.", + "durability": null, + "destroy": "true", + "attack_speed": "6", + "weapon_interface": "18", + "absorb": "0,0,0", + "equip_audio": "2244", + "render_anim": "1381", + "equipment_slot": "3", + "destroy_message": "Drop", + "grand_exchange_price": "6752", + "name": "C. morrigan's javelin (p)", + "archery_ticket_price": "0", + "id": "13954", + "bonuses": "0,0,0,0,105,0,0,0,0,0,0,0,0,0,145" + }, + { + "requirements": "{4,20}", + "shop_price": "10000", + "examine": "A vicious javelin.", + "durability": null, + "destroy": "true", + "attack_speed": "6", + "weapon_interface": "18", + "absorb": "0,0,0", + "equip_audio": "2244", + "render_anim": "1381", + "equipment_slot": "3", + "destroy_message": "Drop", + "grand_exchange_price": "6752", + "name": "C. morrigan's javelin (p+)", + "archery_ticket_price": "0", + "id": "13955", + "bonuses": "0,0,0,0,105,0,0,0,0,0,0,0,0,0,145" + }, + { + "requirements": "{4,20}", + "shop_price": "10000", + "examine": "A vicious javelin.", + "durability": null, + "destroy": "true", + "attack_speed": "6", + "weapon_interface": "18", + "absorb": "0,0,0", + "equip_audio": "2244", + "render_anim": "1381", + "equipment_slot": "3", + "destroy_message": "Drop", + "grand_exchange_price": "6752", + "name": "C. morrigan's javelin (p++)", + "archery_ticket_price": "0", + "id": "13956", + "bonuses": "0,0,0,0,105,0,0,0,0,0,0,0,0,0,145" + }, + { + "requirements": "{4,20}", + "shop_price": "1000", + "examine": "A vicious throwing axe.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "18", + "absorb": "0,0,0", + "equipment_slot": "3", + "destroy_message": "Drop", + "grand_exchange_price": "5388", + "name": "C. morrigan's throwing axe", + "archery_ticket_price": "0", + "id": "13957", + "bonuses": "0,0,0,0,93,0,0,0,0,0,0,0,0,0,117" + }, + { + "requirements": "{0,20}-{4,20}", + "shop_price": "120000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "4,0,9", + "equipment_slot": "4", + "destroy_message": "Drop", + "remove_sleeves": "true", + "grand_exchange_price": "168278", + "name": "Corrupt dragon chainbody", + "archery_ticket_price": "0", + "id": "13958", + "bonuses": "0,0,0,-15,0,81,93,98,-3,82,50,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "120000", + "examine": "This item degrades while worn, and will turn to dust.", + "grand_exchange_price": "168278", + "durability": null, + "name": "Corrupt dragon chainbody", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13959" + }, + { + "shop_price": "72000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "4,0,9", + "equipment_slot": "4", + "destroy_message": "Drop", + "remove_sleeves": "true", + "grand_exchange_price": "168278", + "name": "Corrupt dragon chainbody (deg)", + "archery_ticket_price": "0", + "id": "13960", + "bonuses": "0,0,0,-15,0,81,93,98,-3,82,50,0,0,0,0" + }, + { + "remove_head": "true", + "shop_price": "60000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "2,0,4", + "equip_audio": "2240", + "equipment_slot": "0", + "destroy_message": "Drop", + "grand_exchange_price": "121835", + "name": "Corrupt dragon med helm", + "archery_ticket_price": "0", + "id": "13961", + "bonuses": "0,0,0,-3,-1,33,35,32,-1,34,10,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "60000", + "examine": "This item degrades while worn, and will turn to dust.", + "grand_exchange_price": "121835", + "durability": null, + "name": "Corrupt dragon med helm", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13962" + }, + { + "remove_head": "true", + "shop_price": "36000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "2,0,4", + "equip_audio": "2240", + "equipment_slot": "0", + "destroy_message": "Drop", + "grand_exchange_price": "121835", + "name": "Corrupt dragon med helm (deg)", + "archery_ticket_price": "0", + "id": "13963", + "bonuses": "0,0,0,-3,-1,33,35,32,-1,34,10,0,0,0,0" + }, + { + "shop_price": "120000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "5,0,11", + "equip_audio": "2245", + "equipment_slot": "5", + "destroy_message": "Drop", + "grand_exchange_price": "79703", + "name": "Corrupt dragon sq shield", + "archery_ticket_price": "0", + "id": "13964", + "bonuses": "0,0,0,-6,-2,50,52,48,0,50,50,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "120000", + "examine": "This item degrades while worn, and will turn to dust.", + "grand_exchange_price": "79703", + "durability": null, + "name": "Corrupt dragon sq shield", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13965" + }, + { + "shop_price": "72000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "5,0,11", + "equip_audio": "2245", + "equipment_slot": "5", + "destroy_message": "Drop", + "grand_exchange_price": "79703", + "name": "Corrupt dragon sq shield (deg)", + "archery_ticket_price": "0", + "id": "13966", + "bonuses": "0,0,0,-6,-2,50,52,48,0,50,50,0,0,0,0" + }, + { + "shop_price": "120000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "3,0,6", + "equipment_slot": "7", + "destroy_message": "Destroy", + "grand_exchange_price": "71066", + "name": "Corrupt dragon plateskirt", + "archery_ticket_price": "0", + "id": "13967", + "bonuses": "0,0,0,-21,-7,68,66,63,-4,65,20,0,0,0,0" + }, + { + "destroy_message": "Destroy", + "shop_price": "120000", + "examine": "This item degrades while worn, and will turn to dust.", + "grand_exchange_price": "71066", + "durability": null, + "name": "Corrupt dragon plateskirt", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13968" + }, + { + "shop_price": "72000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "3,0,6", + "equipment_slot": "7", + "destroy_message": "Destroy", + "grand_exchange_price": "71066", + "name": "Corrupt dragon plateskirt (deg)", + "archery_ticket_price": "0", + "id": "13969", + "bonuses": "0,0,0,-21,-7,68,66,63,-4,65,20,0,0,0,0" + }, + { + "shop_price": "120000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "3,0,6", + "equip_audio": "2242", + "equipment_slot": "7", + "destroy_message": "Drop", + "grand_exchange_price": "87957", + "name": "Corrupt dragon platelegs", + "archery_ticket_price": "0", + "id": "13970", + "bonuses": "0,0,0,-21,-7,68,66,63,-4,65,20,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "120000", + "examine": "This item degrades while worn, and will turn to dust.", + "grand_exchange_price": "87957", + "durability": null, + "name": "Corrupt dragon platelegs", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13971" + }, + { + "shop_price": "72000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "3,0,6", + "equip_audio": "2242", + "equipment_slot": "7", + "destroy_message": "Drop", + "grand_exchange_price": "87957", + "name": "Corrupt dragon platelegs (deg)", + "archery_ticket_price": "0", + "id": "13972", + "bonuses": "0,0,0,-21,-7,68,66,63,-4,65,20,0,0,0,0" + }, + { + "requirements": "{0,60}", + "shop_price": "120000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "weight": "2.7", + "attack_speed": "6", + "weapon_interface": "2", + "absorb": "0,0,0", + "equip_audio": "2232", + "render_anim": "2586", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "395,395,401,395", + "destroy_message": "Drop", + "grand_exchange_price": "332229", + "attack_audios": "2498,2498,2497,2498", + "name": "Corrupt dragon battleaxe", + "archery_ticket_price": "0", + "id": "13973", + "bonuses": "-2,70,65,0,0,0,0,0,-1,-1,0,85,0,0,0" + }, + { + "requirements": "{0,60}", + "shop_price": "120000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "weight": "2.7", + "attack_speed": "4", + "render_anim": "2586", + "defence_anim": "397", + "attack_anims": "395,395,401,395", + "destroy_message": "Drop", + "grand_exchange_price": "332229", + "attack_audios": "2498,2498,2497,2498", + "name": "Corrupt dragon battleaxe", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13974", + "bonuses": "-2,70,65,0,0,0,0,0,0,-1,0,85,0,0,0" + }, + { + "requirements": "{0,60}", + "shop_price": "72000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "weight": "2.7", + "attack_speed": "6", + "weapon_interface": "2", + "absorb": "0,0,0", + "equip_audio": "2232", + "render_anim": "2586", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "395,395,401,395", + "destroy_message": "Drop", + "grand_exchange_price": "332229", + "attack_audios": "2498,2498,2497,2498", + "name": "C. dragon battleaxe (deg)", + "archery_ticket_price": "0", + "id": "13975", + "bonuses": "-2,70,65,0,0,0,0,0,-1,-1,0,85,0,0,0" + }, + { + "shop_price": "30000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "5", + "absorb": "0,0,0", + "equip_audio": "2248", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "396,396,395,396", + "destroy_message": "Drop", + "grand_exchange_price": "33358", + "attack_audios": "2517,2517,2500,2517", + "name": "Corrupt dragon dagger", + "archery_ticket_price": "0", + "id": "13976", + "bonuses": "40,25,-4,1,0,0,0,0,1,0,0,40,0,0,0" + }, + { + "shop_price": "30000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "equip_audio": "2248", + "defence_anim": "397", + "attack_anims": "396,396,395,396", + "destroy_message": "Drop", + "grand_exchange_price": "33358", + "attack_audios": "2517,2517,2500,2517", + "name": "Corrupt dragon dagger", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13977" + }, + { + "shop_price": "18000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "5", + "absorb": "0,0,0", + "equip_audio": "2248", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "396,396,395,396", + "destroy_message": "Drop", + "grand_exchange_price": "33358", + "attack_audios": "2517,2517,2500,2517", + "name": "C. dragon dagger (deg)", + "archery_ticket_price": "0", + "id": "13978", + "bonuses": "40,25,-4,1,0,0,0,0,1,0,0,40,0,0,0" + }, + { + "requirements": "{0,60}", + "shop_price": "100000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "weight": "1.8", + "attack_speed": "4", + "weapon_interface": "6", + "absorb": "0,0,0", + "equip_audio": "2248", + "render_anim": "1928", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "destroy_message": "Drop", + "grand_exchange_price": "338644", + "attack_audios": "2500,0,2517,0", + "name": "Corrupt dragon scimitar", + "archery_ticket_price": "0", + "id": "13979", + "bonuses": "8,67,-2,0,0,0,1,0,0,0,0,66,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "100000", + "examine": "This item degrades while worn, and will turn to dust.", + "grand_exchange_price": "338644", + "durability": null, + "name": "Corrupt dragon scimitar", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13980", + "equip_audio": "" + }, + { + "shop_price": "60000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "6", + "absorb": "0,0,0", + "equip_audio": "2248", + "render_anim": "1928", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "destroy_message": "Drop", + "grand_exchange_price": "338644", + "attack_audios": "2500,0,2517,0", + "name": "C. dragon scimitar (deg)", + "archery_ticket_price": "0", + "id": "13981", + "bonuses": "8,67,-2,0,0,0,1,0,0,0,0,66,0,0,0" + }, + { + "requirements": "{0,60}", + "shop_price": "100000", + "ge_buy_limit": "10", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "weight": "1.8", + "attack_speed": "5", + "weapon_interface": "5", + "absorb": "0,0,0", + "equip_audio": "2248", + "render_anim": "1582", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "destroy_message": "Drop", + "grand_exchange_price": "207053", + "attack_audios": "2500,2500,2517,2500", + "name": "Corrupt dragon longsword", + "archery_ticket_price": "0", + "id": "13982", + "bonuses": "58,69,-2,0,0,0,3,2,1,0,0,71,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "100000", + "examine": "This item degrades while worn, and will turn to dust.", + "grand_exchange_price": "207053", + "durability": null, + "name": "Corrupt dragon longsword", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "13983" + }, + { + "shop_price": "60000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "weapon_interface": "5", + "absorb": "0,0,0", + "equip_audio": "2248", + "render_anim": "1582", + "equipment_slot": "3", + "destroy_message": "Drop", + "grand_exchange_price": "207053", + "name": "C. dragon longsword (deg)", + "archery_ticket_price": "0", + "id": "13984", + "bonuses": "58,69,-2,0,0,0,3,2,1,0,0,71,0,0,0" + }, + { + "requirements": "{0,60}", + "shop_price": "50000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "weight": "1.8", + "attack_speed": "5", + "weapon_interface": "8", + "absorb": "0,0,0", + "equip_audio": "2246", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "destroy_message": "Drop", + "grand_exchange_price": "50096", + "attack_audios": "2508,2508,25092508", + "name": "Corrupt dragon mace", + "archery_ticket_price": "0", + "id": "13985", + "bonuses": "40,-2,60,1,0,0,0,0,0,0,0,55,0,5,0" + }, + { + "requirements": "{0,60}", + "shop_price": "50000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "weight": "1.8", + "attack_speed": "4", + "defence_anim": "397", + "attack_anims": "390,390,381,390", + "destroy_message": "Drop", + "grand_exchange_price": "50096", + "attack_audios": "2508,2508,25092508", + "name": "Corrupt dragon mace", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13986" + }, + { + "requirements": "{0,60}", + "shop_price": "30000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "weight": "1.8", + "attack_speed": "5", + "weapon_interface": "8", + "absorb": "0,0,0", + "equip_audio": "2246", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "destroy_message": "Drop", + "grand_exchange_price": "50096", + "attack_audios": "2508,2508,25092508", + "name": "Corrupt dragon mace (deg)", + "archery_ticket_price": "0", + "id": "13987", + "bonuses": "40,-2,60,1,0,0,0,0,0,0,0,55,0,5,0" + }, + { + "shop_price": "40000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "14", + "absorb": "0,0,0", + "equip_audio": "2247", + "render_anim": "28", + "defence_anim": "2079", + "equipment_slot": "3", + "attack_anims": "2080,2081,2082,2080", + "destroy_message": "Drop", + "grand_exchange_price": "920922", + "name": "Corrupt dragon spear", + "archery_ticket_price": "0", + "id": "13988", + "bonuses": "55,55,55,0,0,5,5,5,5,5,0,60,0,0,0" + }, + { + "shop_price": "40000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "two_handed": "true", + "defence_anim": "2079", + "attack_anims": "2080,2081,2082,2080", + "destroy_message": "Drop", + "grand_exchange_price": "920922", + "name": "Corrupt dragon spear", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "13989" + }, + { + "shop_price": "24000", + "examine": "This item degrades while worn, and will turn to dust.", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "two_handed": "true", + "weapon_interface": "14", + "absorb": "0,0,0", + "equip_audio": "2247", + "render_anim": "28", + "defence_anim": "2079", + "equipment_slot": "3", + "attack_anims": "2080,2081,2082,2080", + "destroy_message": "Drop", + "grand_exchange_price": "920922", + "name": "Corrupt dragon spear (deg)", + "archery_ticket_price": "0", + "id": "13990", + "bonuses": "55,55,55,0,0,5,5,5,5,5,0,60,0,0,0" + }, + { + "destroy_message": "You can get another copy by searching bookshelves around 2009Scape.", + "shop_price": "5", + "examine": "A book about the Wilderness.", + "durability": null, + "name": "Pvp worlds manual", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14056", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "25", + "examine": "A threat to dusty corners everywhere.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "8", + "absorb": "0,0,0", + "render_anim": "1072", + "equipment_slot": "3", + "destroy_message": "You can obtain another by talking to Maggie the witch.", + "name": "Broomstick", + "archery_ticket_price": "0", + "id": "14057", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "If you drop the goulash, it will be destroyed. You can get some more by dipping a bowl into Maggie's cauldron.", + "shop_price": "2", + "examine": "What a curious and ghoulish smell!", + "durability": null, + "name": "Goulash", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14058", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "3" + }, + { + "destroy_message": "You can get another flask of magic unguent from the chest in Betty's basement.", + "shop_price": "2", + "examine": "Purple and pungent.", + "durability": null, + "name": "Magic unguent", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14061", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You can get another flask of broom ointment from Hetty in Rimmington.", + "shop_price": "2", + "examine": "To be used on brooms.", + "durability": null, + "name": "Broom ointment", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14062", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "If you release this newt, you can get another from the crate in Hetty's basement in Rimmington.", + "shop_price": "5", + "examine": "A newt from Hetty's basement.", + "durability": null, + "name": "Newt", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14064", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "3" + }, + { + "destroy_message": "You can get another newt label from Gus in Hetty's basement in Rimmington.", + "shop_price": "1", + "examine": "A label for a shipping crate.", + "durability": null, + "name": "Newt label", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14065", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You can get another toad label from Gus in Hetty's basement in Rimmington.", + "shop_price": "1", + "examine": "A label for a shipping crate.", + "durability": null, + "name": "Toad label", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14066", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You can get another newt-and-toad label from Gus in Hetty's basement in Rimmington.", + "shop_price": "1", + "examine": "A label for a shipping crate.", + "durability": null, + "name": "Newts and toads label", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14067", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You can obtain another wand from the chest in Betty's basement.", + "shop_price": "15", + "examine": "Warm to the touch.", + "durability": null, + "name": "Betty's wand", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14068", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "If you destroy this item, you can get another from Lottie in Betty's basement.", + "shop_price": "2", + "examine": "What a view!", + "durability": null, + "name": "Magic slate", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14069", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "If you release this creature, you will have to restart the puzzle in Betty's basement.", + "shop_price": "1", + "examine": "Desert dweller.", + "durability": null, + "name": "Reptile", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14070", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "If you release this creature, you will have to restart the puzzle in Betty's basement.", + "shop_price": "1", + "examine": "Bleak and beaky.", + "durability": null, + "name": "Blackbird", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14071", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "1", + "examine": "An annoying flappy thing.", + "durability": null, + "name": "Bat", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14072", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "1", + "examine": "It's an extremely small brown spider, probably very poisonous.", + "durability": null, + "name": "Spider", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14073", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "1", + "examine": "A popular dwarven delicacy.", + "durability": null, + "name": "Rat", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14074", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "1", + "durability": null, + "name": "Snail", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14075", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "15", + "examine": "The height of warlock fashion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "4", + "destroy_message": "You can get another warlock top from Diango in Draynor Village.", + "remove_sleeves": "true", + "name": "Warlock top", + "archery_ticket_price": "0", + "id": "14076", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You can get another set of warlock legs from Diango in Draynor Village.", + "shop_price": "15", + "examine": "Tattered but trendy.", + "durability": null, + "name": "Warlock legs", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14077", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "shop_price": "15", + "examine": "The height of witchly fashion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "4", + "destroy_message": "You can get another witch top from Diango in Draynor.", + "remove_sleeves": "true", + "name": "Witch top", + "archery_ticket_price": "0", + "id": "14078", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You can get another witch top from Diango in Draynor.", + "shop_price": "15", + "examine": "Tattered but trendy.", + "durability": null, + "name": "Witch skirt", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14079", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "destroy_message": "You can get another witch cloak from Diango in Draynor.", + "shop_price": "15", + "examine": "Ragged but rugged.", + "durability": null, + "name": "Witch cloak", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14080", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "destroy_message": "You can get another warlock cloak from Diango in Draynor Village.", + "shop_price": "15", + "examine": "Ragged but rugged.", + "durability": null, + "name": "Warlock cloak", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14081", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "destroy_message": "Drop", + "shop_price": "1", + "examine": "A sticky orb of popped corn.", + "durability": null, + "name": "Popcorn ball", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14082", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "1", + "examine": "Chocolatey goodness.", + "durability": null, + "name": "Chocolate drop", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14083", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "1", + "examine": "Sugary bliss.", + "durability": null, + "name": "Wrapped candy", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14084", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "1", + "examine": "An urgent communiqu?? revealing important information.", + "durability": null, + "name": "Armadyl communiqu?", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14085", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "15", + "examine": "The height of witchly fashion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "4", + "destroy_message": "You can get another witch top from Diango in Draynor.", + "remove_sleeves": "true", + "name": "Witch top", + "archery_ticket_price": "0", + "id": "14086", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You can get another witch top from Diango in Draynor.", + "shop_price": "15", + "examine": "Tattered but trendy.", + "durability": null, + "name": "Witch skirt", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14087", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "destroy_message": "You can get another witch cloak from Diango in Draynor.", + "shop_price": "15", + "examine": "Ragged but rugged.", + "durability": null, + "name": "Witch cloak", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14088", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "durability": null, + "name": "Pet kitten", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14089", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "durability": null, + "name": "Pet cat", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14090", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "durability": null, + "name": "Lazy cat", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14091", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "durability": null, + "name": "Overgrown cat", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14092", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "durability": null, + "name": "Wily cat", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14093", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "43333", + "examine": "The sacred clay top has transformed into a spiked, platemail body.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "3,0,6", + "equipment_slot": "4", + "destroy_message": "Drop", + "remove_sleeves": "true", + "name": "Sacred clay platebody", + "archery_ticket_price": "0", + "id": "14094", + "bonuses": "0,0,0,-30,-10,82,80,72,-6,80,40,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "42667", + "examine": "The sacred clay bottom has transformed into spiked, platemail legs.", + "durability": null, + "name": "Sacred clay platelegs", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14095", + "absorb": "2,0,4", + "bonuses": "0,0,0,-21,-7,51,49,47,-4,49,15,0,0,0,0", + "equipment_slot": "7" + }, + { + "remove_head": "true", + "shop_price": "23467", + "examine": "The sacred clay hat has transformed into a spined helm.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "1,0,3", + "equipment_slot": "0", + "destroy_message": "Drop", + "name": "Sacred clay helm", + "archery_ticket_price": "0", + "id": "14096", + "bonuses": "0,0,0,-6,-2,30,32,27,-1,30,7,0,0,0,0" + }, + { + "shop_price": "17066", + "examine": "The sacred clay weapon has transformed into a sharp scimitar.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "5", + "absorb": "0,0,0", + "equip_audio": "2248", + "render_anim": "1629", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Sacred clay scimitar", + "archery_ticket_price": "0", + "id": "14097", + "bonuses": "7,45,-2,0,0,0,1,0,0,0,0,44,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "21333", + "examine": "This can turn into a variety of tools.", + "durability": null, + "name": "Volatile clay tool", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14098", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "21333", + "examine": "Your volatile tool wants to mine some rocks.", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "weapon_interface": "4", + "absorb": "0,0,0", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Volatile clay pickaxe", + "archery_ticket_price": "0", + "id": "14099", + "bonuses": "4,-2,2,0,0,0,1,0,0,0,0,5,0,0,0" + }, + { + "shop_price": "21333", + "examine": "Your volatile tool wants to cut some wood.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "2", + "absorb": "0,0,0", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Volatile clay hatchet", + "archery_ticket_price": "0", + "id": "14100", + "bonuses": "-2,26,24,0,0,0,1,0,0,0,0,29,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "21333", + "examine": "Your volatile tool wants to spear some big fish.", + "durability": null, + "name": "Volatile clay harpoon", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14101", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "3" + }, + { + "shop_price": "21333", + "examine": "Your volatile tool wants to catch some butterflies.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "5", + "absorb": "0,0,0", + "render_anim": "158", + "defence_anim": "403", + "equipment_slot": "3", + "attack_anims": "401,401,400,401", + "destroy_message": "Drop", + "name": "Volatile clay butterfly net", + "archery_ticket_price": "0", + "id": "14102", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "21333", + "examine": "Your volatile tool wants to make some bows or arrows.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equip_audio": "", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Volatile clay fletching knife", + "archery_ticket_price": "0", + "id": "14103", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "21333", + "examine": "Your volatile tool wants to work metal or build furniture.", + "durability": null, + "name": "Volatile clay hammer", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14104", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "3" + }, + { + "destroy_message": "Drop", + "shop_price": "21333", + "examine": "Your volatile tool wants to make some leather armour.", + "durability": null, + "name": "Volatile clay needle", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14105", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "21333", + "examine": "This can turn into a variety of tools.", + "durability": null, + "name": "Proto-tool", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14106", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "21333", + "examine": "Your sacred clay tool has transformed into a pickaxe.", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "weapon_interface": "4", + "absorb": "0,0,0", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Sacred clay pickaxe", + "archery_ticket_price": "0", + "id": "14107", + "bonuses": "4,-2,2,0,0,0,1,0,0,0,0,5,0,0,0" + }, + { + "shop_price": "21333", + "examine": "Your sacred clay tool has transformed into a hatchet.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "2", + "absorb": "0,0,0", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Sacred clay hatchet", + "archery_ticket_price": "0", + "id": "14108", + "bonuses": "-2,4,2,0,0,0,1,0,0,0,0,5,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "21333", + "examine": "Your sacred clay tool has transformed into a harpoon.", + "durability": null, + "name": "Sacred clay harpoon", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14109", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "3" + }, + { + "shop_price": "1", + "examine": "Your sacred clay tool has transformed into a butterfly net.", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "weapon_interface": "5", + "absorb": "0,0,0", + "render_anim": "158", + "defence_anim": "403", + "equipment_slot": "3", + "attack_anims": "401,401,400,401", + "destroy_message": "Drop", + "name": "Sacred clay butterfly net", + "archery_ticket_price": "0", + "id": "14110", + "bonuses": "4,-2,2,0,0,0,1,0,0,0,0,5,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "21333", + "examine": "The sacred clay has transformed into a knife.", + "durability": null, + "name": "Sacred clay fletching knife", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14111", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "21333", + "examine": "Your sacred clay tool has transformed into a hammer.", + "durability": null, + "name": "Sacred clay hammer", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14112", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "21333", + "examine": "The sacred clay has transformed into a needle.", + "durability": null, + "name": "Sacred clay needle", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14113", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "43333", + "examine": "The sacred clay top has transformed into a heavy, magical robe.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "6,3,0", + "equipment_slot": "4", + "destroy_message": "Drop", + "remove_sleeves": "true", + "name": "Sacred clay robe top", + "archery_ticket_price": "0", + "id": "14114", + "bonuses": "0,0,0,20,0,0,0,0,20,0,20,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "42667", + "examine": "The sacred clay bottom has transformed into a heavy, magical robe.", + "durability": null, + "name": "Sacred clay robe bottom", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14115", + "absorb": "4,2,0", + "bonuses": "0,0,0,15,0,0,0,0,15,0,15,0,0,0,0", + "equipment_slot": "7" + }, + { + "destroy_message": "Drop", + "shop_price": "23467", + "examine": "The sacred clay hat has transformed into a wizard hat.", + "durability": null, + "name": "Sacred clay hat", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14116", + "absorb": "3,1,0", + "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,0,0,0", + "equipment_slot": "0" + }, + { + "shop_price": "17066", + "examine": "The sacred clay weapon has transformed into a magical staff.", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "weapon_interface": "1", + "absorb": "0,0,0", + "render_anim": "28", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Sacred clay staff", + "archery_ticket_price": "0", + "id": "14117", + "bonuses": "10,-1,40,10,0,2,3,1,10,0,0,50,0,0,0" + }, + { + "shop_price": "43333", + "examine": "The sacred clay top has transformed into a leather body.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,6,3", + "equipment_slot": "4", + "destroy_message": "Drop", + "remove_sleeves": "true", + "name": "Sacred clay body", + "archery_ticket_price": "0", + "id": "14118", + "bonuses": "0,0,0,-15,15,40,32,45,20,40,40,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "42667", + "examine": "The sacred clay bottom has been transformed into a set of chaps.", + "durability": null, + "name": "Sacred clay chaps", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14119", + "absorb": "0,4,2", + "bonuses": "0,0,0,-10,8,22,16,24,8,22,15,0,0,0,0", + "equipment_slot": "7" + }, + { + "remove_head": "true", + "shop_price": "23467", + "examine": "The sacred clay hat has transformed into a coif.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,3,1", + "equip_audio": "", + "equipment_slot": "0", + "destroy_message": "Drop", + "name": "Sacred clay coif", + "archery_ticket_price": "0", + "id": "14120", + "bonuses": "0,0,0,-1,2,4,6,8,4,4,5,0,0,0,0" + }, + { + "shop_price": "17066", + "examine": "The sacred clay weapon has transformed into a bow.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "two_handed": "true", + "weapon_interface": "16", + "absorb": "0,0,0", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Sacred clay bow", + "archery_ticket_price": "0", + "id": "14121", + "bonuses": "0,0,0,0,47,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "30", + "examine": "The sacred clay has become hard enough to chip stone.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "4", + "absorb": "0,0,0", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Pickaxe (class 1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14122", + "bonuses": "10,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "30", + "examine": "The sacred clay has become hard enough to chip stone.", + "durability": null, + "name": "Pickaxe (class 1)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14123" + }, + { + "shop_price": "60", + "examine": "The sacred clay has become hard enough to chip stone.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "4", + "absorb": "0,0,0", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Pickaxe (class 2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14124", + "bonuses": "15,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "60", + "examine": "The sacred clay has become hard enough to chip stone.", + "durability": null, + "name": "Pickaxe (class 2)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14125" + }, + { + "shop_price": "90", + "examine": "The sacred clay has become hard enough to chip stone.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "4", + "absorb": "0,0,0", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Pickaxe (class 3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14126", + "bonuses": "20,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "90", + "examine": "The sacred clay has become hard enough to chip stone.", + "durability": null, + "name": "Pickaxe (class 3)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14127" + }, + { + "shop_price": "120", + "examine": "The sacred clay has become hard enough to chip stone.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "4", + "absorb": "0,0,0", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Pickaxe (class 4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14128", + "bonuses": "25,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "120", + "examine": "The sacred clay has become hard enough to chip stone.", + "durability": null, + "name": "Pickaxe (class 4)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14129" + }, + { + "shop_price": "150", + "examine": "The sacred clay has become hard enough to chip stone.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "4", + "absorb": "0,0,0", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Pickaxe (class 5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14130", + "bonuses": "30,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "150", + "examine": "The sacred clay has become hard enough to chip stone.", + "durability": null, + "name": "Pickaxe (class 5)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14131" + }, + { + "shop_price": "30", + "examine": "The sacred clay has become sharp enough to cut wood.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "2", + "absorb": "0,0,0", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Hatchet (class 1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14132", + "bonuses": "0,10,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "30", + "examine": "The sacred clay has become sharp enough to cut wood.", + "durability": null, + "name": "Hatchet (class 1)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14133" + }, + { + "shop_price": "60", + "examine": "The sacred clay has become sharp enough to cut wood.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "2", + "absorb": "0,0,0", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Hatchet (class 2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14134", + "bonuses": "0,15,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "60", + "examine": "The sacred clay has become sharp enough to cut wood.", + "durability": null, + "name": "Hatchet (class 2)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14135" + }, + { + "shop_price": "90", + "examine": "The sacred clay has become sharp enough to cut wood.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "2", + "absorb": "0,0,0", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Hatchet (class 3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14136", + "bonuses": "0,20,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "90", + "examine": "The sacred clay has become sharp enough to cut wood.", + "durability": null, + "name": "Hatchet (class 3)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14137" + }, + { + "shop_price": "120", + "examine": "The sacred clay has become sharp enough to cut wood.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "2", + "absorb": "0,0,0", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Hatchet (class 4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14138", + "bonuses": "0,25,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "120", + "examine": "The sacred clay has become sharp enough to cut wood.", + "durability": null, + "name": "Hatchet (class 4)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14139" + }, + { + "shop_price": "150", + "examine": "The sacred clay has become sharp enough to cut wood.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "2", + "absorb": "0,0,0", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Hatchet (class 5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14140", + "bonuses": "0,30,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "150", + "examine": "The sacred clay has become sharp enough to cut wood.", + "durability": null, + "name": "Hatchet (class 5)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14141" + }, + { + "shop_price": "30", + "examine": "The sacred clay has become long enough to reach the depths of pools.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "5", + "absorb": "0,0,0", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Harpoon (class 1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14142", + "bonuses": "10,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "30", + "examine": "The sacred clay has become long enough to reach the depths of pools.", + "durability": null, + "name": "Harpoon (class 1)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14143" + }, + { + "shop_price": "60", + "examine": "The sacred clay has become long enough to reach the depths of pools.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "5", + "absorb": "0,0,0", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Harpoon (class 2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14144", + "bonuses": "15,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "60", + "examine": "The sacred clay has become long enough to reach the depths of pools.", + "durability": null, + "name": "Harpoon (class 2)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14145" + }, + { + "shop_price": "90", + "examine": "The sacred clay has become long enough to reach the depths of pools.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "5", + "absorb": "0,0,0", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Harpoon (class 3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14146", + "bonuses": "20,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "90", + "examine": "The sacred clay has become long enough to reach the depths of pools.", + "durability": null, + "name": "Harpoon (class 3)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14147" + }, + { + "shop_price": "120", + "examine": "The sacred clay has become long enough to reach the depths of pools.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "5", + "absorb": "0,0,0", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Harpoon (class 4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14148", + "bonuses": "25,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "120", + "examine": "The sacred clay has become long enough to reach the depths of pools.", + "durability": null, + "name": "Harpoon (class 4)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14149" + }, + { + "shop_price": "150", + "examine": "The sacred clay has become long enough to reach the depths of pools.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "5", + "absorb": "0,0,0", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Harpoon (class 5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14150", + "bonuses": "30,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "150", + "examine": "The sacred clay has become long enough to reach the depths of pools.", + "durability": null, + "name": "Harpoon (class 5)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14151" + }, + { + "shop_price": "30", + "examine": "The sacred clay has become light enough to swing at floating shards.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "14", + "absorb": "0,0,0", + "render_anim": "158", + "defence_anim": "403", + "equipment_slot": "3", + "attack_anims": "401,401,400,401", + "destroy_message": "Drop", + "name": "Butterfly net (class 1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14152", + "bonuses": "0,0,10,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "30", + "examine": "The sacred clay has become light enough to swing at floating shards.", + "durability": null, + "name": "Butterfly net (class 1)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14153" + }, + { + "shop_price": "60", + "examine": "The sacred clay has become light enough to swing at floating shards.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "14", + "absorb": "0,0,0", + "render_anim": "158", + "defence_anim": "403", + "equipment_slot": "3", + "attack_anims": "401,401,400,401", + "destroy_message": "Drop", + "name": "Butterfly net (class 2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14154", + "bonuses": "0,0,15,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "60", + "examine": "The sacred clay has become light enough to swing at floating shards.", + "durability": null, + "name": "Butterfly net (class 2)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14155" + }, + { + "shop_price": "90", + "examine": "The sacred clay has become light enough to swing at floating shards.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "14", + "absorb": "0,0,0", + "render_anim": "158", + "defence_anim": "403", + "equipment_slot": "3", + "attack_anims": "401,401,400,401", + "destroy_message": "Drop", + "name": "Butterfly net (class 3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14156", + "bonuses": "0,0,20,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "90", + "examine": "The sacred clay has become light enough to swing at floating shards.", + "durability": null, + "name": "Butterfly net (class 3)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14157" + }, + { + "shop_price": "120", + "examine": "The sacred clay has become light enough to swing at floating shards.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "14", + "absorb": "0,0,0", + "render_anim": "158", + "defence_anim": "403", + "equipment_slot": "3", + "attack_anims": "401,401,400,401", + "destroy_message": "Drop", + "name": "Butterfly net (class 4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14158", + "bonuses": "0,0,25,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "120", + "examine": "The sacred clay has become light enough to swing at floating shards.", + "durability": null, + "name": "Butterfly net (class 4)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14159" + }, + { + "shop_price": "150", + "examine": "The sacred clay has become light enough to swing at floating shards.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "14", + "absorb": "0,0,0", + "render_anim": "158", + "defence_anim": "403", + "equipment_slot": "3", + "attack_anims": "401,401,400,401", + "destroy_message": "Drop", + "name": "Butterfly net (class 5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14160", + "bonuses": "0,0,30,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "150", + "examine": "The sacred clay has become light enough to swing at floating shards.", + "durability": null, + "name": "Butterfly net (class 5)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14161" + }, + { + "destroy_message": "Drop", + "shop_price": "30", + "examine": "The sacred clay has transformed into something bland, but edible.", + "durability": null, + "name": "Food (class 1)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14162", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "30", + "examine": "The sacred clay has transformed into something bland, but edible.", + "durability": null, + "name": "Food (class 1)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14163" + }, + { + "destroy_message": "Drop", + "shop_price": "60", + "examine": "The sacred clay has transformed into something bland, but edible.", + "durability": null, + "name": "Food (class 2)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14164", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "60", + "examine": "The sacred clay has transformed into something bland, but edible.", + "durability": null, + "name": "Food (class 2)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14165" + }, + { + "destroy_message": "Drop", + "shop_price": "90", + "examine": "The sacred clay has transformed into something bland, but edible.", + "durability": null, + "name": "Food (class 3)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14166", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "90", + "examine": "The sacred clay has transformed into something bland, but edible.", + "durability": null, + "name": "Food (class 3)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14167" + }, + { + "destroy_message": "Drop", + "shop_price": "120", + "examine": "The sacred clay has transformed into something bland, but edible.", + "durability": null, + "name": "Food (class 4)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14168", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "120", + "examine": "The sacred clay has transformed into something bland, but edible.", + "durability": null, + "name": "Food (class 4)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14169" + }, + { + "destroy_message": "Drop", + "shop_price": "150", + "examine": "The sacred clay has transformed into something bland, but edible.", + "durability": null, + "name": "Food (class 5)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14170", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "150", + "examine": "The sacred clay has transformed into something bland, but edible.", + "durability": null, + "name": "Food (class 5)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14171" + }, + { + "destroy_message": "Drop", + "shop_price": "30", + "examine": "The clay has transformed into an expandable wall.", + "durability": null, + "name": "Barrier (class 1)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14172", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "30", + "examine": "The clay has transformed into an expandable wall.", + "durability": null, + "name": "Barrier (class 1)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14173" + }, + { + "destroy_message": "Drop", + "shop_price": "60", + "examine": "The clay has transformed into an expandable wall.", + "durability": null, + "name": "Barrier (class 2)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14174", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "60", + "examine": "The clay has transformed into an expandable wall.", + "durability": null, + "name": "Barrier (class 2)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14175" + }, + { + "destroy_message": "Drop", + "shop_price": "90", + "examine": "The clay has transformed into an expandable wall.", + "durability": null, + "name": "Barrier (class 3)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14176", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "90", + "examine": "The clay has transformed into an expandable wall.", + "durability": null, + "name": "Barrier (class 3)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14177" + }, + { + "destroy_message": "Drop", + "shop_price": "120", + "examine": "The clay has transformed into an expandable wall.", + "durability": null, + "name": "Barrier (class 4)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14178", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "120", + "examine": "The clay has transformed into an expandable wall.", + "durability": null, + "name": "Barrier (class 4)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14179" + }, + { + "destroy_message": "Drop", + "shop_price": "150", + "examine": "The clay has transformed into an expandable wall.", + "durability": null, + "name": "Barrier (class 5)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14180", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "150", + "examine": "The clay has transformed into an expandable wall.", + "durability": null, + "name": "Barrier (class 5)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14181" + }, + { + "destroy_message": "Drop", + "shop_price": "15", + "examine": "Very low quality sacred clay.", + "durability": null, + "name": "Sacred clay (class 1)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14182", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "15", + "examine": "Very low quality sacred clay.", + "durability": null, + "name": "Sacred clay (class 1)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14183" + }, + { + "destroy_message": "Drop", + "shop_price": "30", + "examine": "Low quality sacred clay.", + "durability": null, + "name": "Sacred clay (class 2)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14184", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "30", + "examine": "Low quality sacred clay.", + "durability": null, + "name": "Sacred clay (class 2)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14185" + }, + { + "destroy_message": "Drop", + "shop_price": "45", + "examine": "Medium quality sacred clay.", + "durability": null, + "name": "Sacred clay (class 3)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14186", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "45", + "examine": "Medium quality sacred clay.", + "durability": null, + "name": "Sacred clay (class 3)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14187" + }, + { + "destroy_message": "Drop", + "shop_price": "60", + "examine": "High quality sacred clay.", + "durability": null, + "name": "Sacred clay (class 4)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14188", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "60", + "examine": "High quality sacred clay.", + "durability": null, + "name": "Sacred clay (class 4)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14189" + }, + { + "destroy_message": "Drop", + "shop_price": "75", + "examine": "Very high quality sacred clay.", + "durability": null, + "name": "Sacred clay (class 5)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14190", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "75", + "examine": "Very high quality sacred clay.", + "durability": null, + "name": "Sacred clay (class 5)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14191" + }, + { + "shop_price": "30", + "examine": "The sacred clay has transformed into a wood-like substance.", + "durability": null, + "destroy": "true", + "attack_speed": "6", + "two_handed": "true", + "weapon_interface": "16", + "absorb": "0,0,0", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Bow (class 1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14192", + "bonuses": "0,0,0,0,55,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "30", + "examine": "The sacred clay has transformed into a wood-like substance.", + "durability": null, + "name": "Bow (class 1)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "two_handed": "true", + "id": "14193" + }, + { + "shop_price": "60", + "examine": "The sacred clay has transformed into a wood-like substance.", + "durability": null, + "destroy": "true", + "attack_speed": "6", + "two_handed": "true", + "weapon_interface": "16", + "absorb": "0,0,0", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Bow (class 2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14194", + "bonuses": "0,0,0,0,90,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "60", + "examine": "The sacred clay has transformed into a wood-like substance.", + "durability": null, + "name": "Bow (class 2)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "two_handed": "true", + "id": "14195" + }, + { + "shop_price": "90", + "examine": "The sacred clay has transformed into a wood-like substance.", + "durability": null, + "destroy": "true", + "attack_speed": "6", + "two_handed": "true", + "weapon_interface": "16", + "absorb": "0,0,0", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Bow (class 3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14196", + "bonuses": "0,0,0,0,135,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "90", + "examine": "The sacred clay has transformed into a wood-like substance.", + "durability": null, + "name": "Bow (class 3)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "two_handed": "true", + "id": "14197" + }, + { + "shop_price": "120", + "examine": "The sacred clay has transformed into a wood-like substance.", + "durability": null, + "destroy": "true", + "attack_speed": "6", + "two_handed": "true", + "weapon_interface": "16", + "absorb": "0,0,0", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Bow (class 4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14198", + "bonuses": "0,0,0,0,180,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "120", + "examine": "The sacred clay has transformed into a wood-like substance.", + "durability": null, + "name": "Bow (class 4)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "two_handed": "true", + "id": "14199" + }, + { + "shop_price": "150", + "examine": "The sacred clay has transformed into a wood-like substance.", + "durability": null, + "destroy": "true", + "attack_speed": "6", + "two_handed": "true", + "weapon_interface": "16", + "absorb": "0,0,0", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Bow (class 5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14200", + "bonuses": "0,0,0,0,225,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "150", + "examine": "The sacred clay has transformed into a wood-like substance.", + "durability": null, + "name": "Bow (class 5)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "two_handed": "true", + "id": "14201" + }, + { + "shop_price": "2", + "examine": "The Sacred Clay has transformed into a wood-like substance.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "13", + "destroy_message": "Drop", + "name": "Arrows (class 1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14202", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,15" + }, + { + "shop_price": "4", + "examine": "The Sacred Clay has transformed into a wood-like substance.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "13", + "destroy_message": "Drop", + "name": "Arrows (class 2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14203", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,30" + }, + { + "shop_price": "6", + "examine": "The Sacred Clay has transformed into a wood-like substance.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "13", + "destroy_message": "Drop", + "name": "Arrows (class 3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14204", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,45" + }, + { + "shop_price": "8", + "examine": "The Sacred Clay has transformed into a wood-like substance.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "13", + "destroy_message": "Drop", + "name": "Arrows (class 4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14205", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,60" + }, + { + "shop_price": "10", + "examine": "The Sacred Clay has transformed into a wood-like substance.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "13", + "destroy_message": "Drop", + "name": "Arrows (class 5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14206", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,75" + }, + { + "shop_price": "150", + "examine": "3 doses of Prayer restore potion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "4", + "name": "Prayer potion(5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14207", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "150", + "examine": "3 doses of Prayer restore potion.", + "grand_exchange_price": "4", + "durability": null, + "name": "Prayer potion(5)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14208" + }, + { + "shop_price": "120", + "examine": "4 doses of Prayer restore potion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "4", + "name": "Prayer potion(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14209", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "120", + "examine": "4 doses of Prayer restore potion.", + "grand_exchange_price": "4", + "durability": null, + "name": "Prayer potion(4)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14210" + }, + { + "shop_price": "90", + "examine": "3 doses of Prayer restore potion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "4", + "name": "Prayer potion(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14211", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "90", + "examine": "3 doses of Prayer restore potion.", + "grand_exchange_price": "4", + "durability": null, + "name": "Prayer potion(3)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14212" + }, + { + "shop_price": "60", + "examine": "2 doses of Prayer restore potion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "4", + "name": "Prayer potion(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14213", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "60", + "examine": "2 doses of Prayer restore potion.", + "grand_exchange_price": "4", + "durability": null, + "name": "Prayer potion(2)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14214" + }, + { + "shop_price": "30", + "examine": "1 dose of Prayer restore potion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "4", + "name": "Prayer potion(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14215", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "30", + "examine": "1 dose of Prayer restore potion.", + "grand_exchange_price": "4", + "durability": null, + "name": "Prayer potion(1)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14216" + }, + { + "shop_price": "150", + "examine": "4 doses of energy potion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "4", + "name": "Energy potion (5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14217", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "150", + "examine": "4 doses of energy potion.", + "grand_exchange_price": "4", + "durability": null, + "name": "Energy potion (5)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14218" + }, + { + "shop_price": "120", + "examine": "4 doses of energy potion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "4", + "name": "Energy potion (4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14219", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "120", + "examine": "4 doses of energy potion.", + "grand_exchange_price": "4", + "durability": null, + "name": "Energy potion (4)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14220" + }, + { + "shop_price": "90", + "examine": "3 doses of energy potion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "4", + "name": "Energy potion (3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14221", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "90", + "examine": "3 doses of energy potion.", + "grand_exchange_price": "4", + "durability": null, + "name": "Energy potion (3)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14222" + }, + { + "shop_price": "60", + "examine": "2 doses of energy potion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "4", + "name": "Energy potion (2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14223", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "60", + "examine": "2 doses of energy potion.", + "grand_exchange_price": "4", + "durability": null, + "name": "Energy potion (2)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14224" + }, + { + "shop_price": "30", + "examine": "1 dose of energy potion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "4", + "name": "Energy potion (1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14225", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "30", + "examine": "1 dose of energy potion.", + "grand_exchange_price": "4", + "durability": null, + "name": "Energy potion (1)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14226" + }, + { + "shop_price": "150", + "examine": "5 doses of super Attack potion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "4", + "name": "Super attack(5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14227", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "150", + "examine": "5 doses of super Attack potion.", + "grand_exchange_price": "4", + "durability": null, + "name": "Super attack(5)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14228" + }, + { + "shop_price": "120", + "examine": "4 doses of super Attack potion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "4", + "name": "Super attack(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14229", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "120", + "examine": "4 doses of super Attack potion.", + "grand_exchange_price": "4", + "durability": null, + "name": "Super attack(4)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14230" + }, + { + "shop_price": "90", + "examine": "3 doses of super Attack potion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "4", + "name": "Super attack(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14231", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "90", + "examine": "3 doses of super Attack potion.", + "grand_exchange_price": "4", + "durability": null, + "name": "Super attack(3)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14232" + }, + { + "shop_price": "60", + "examine": "2 doses of super Attack potion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "4", + "name": "Super attack(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14233", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "60", + "examine": "2 doses of super Attack potion.", + "grand_exchange_price": "4", + "durability": null, + "name": "Super attack(2)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14234" + }, + { + "shop_price": "30", + "examine": "1 dose of super Attack potion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "4", + "name": "Super attack(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14235", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "30", + "examine": "1 dose of super Attack potion.", + "grand_exchange_price": "4", + "durability": null, + "name": "Super attack(1)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14236" + }, + { + "shop_price": "150", + "examine": "5 doses of super Strength potion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "4", + "name": "Super strength(5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14237", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "150", + "examine": "5 doses of super Strength potion.", + "grand_exchange_price": "4", + "durability": null, + "name": "Super strength(5)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14238" + }, + { + "shop_price": "120", + "examine": "4 doses of super Strength potion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "4", + "name": "Super strength(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14239", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "120", + "examine": "4 doses of super Strength potion.", + "grand_exchange_price": "4", + "durability": null, + "name": "Super strength(4)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14240" + }, + { + "shop_price": "90", + "examine": "3 doses of super Strength potion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "4", + "name": "Super strength(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14241", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "90", + "examine": "3 doses of super Strength potion.", + "grand_exchange_price": "4", + "durability": null, + "name": "Super strength(3)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14242" + }, + { + "shop_price": "60", + "examine": "2 doses of super Strength potion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "4", + "name": "Super strength(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14243", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "60", + "examine": "2 doses of super Strength potion.", + "grand_exchange_price": "4", + "durability": null, + "name": "Super strength(2)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14244" + }, + { + "shop_price": "30", + "examine": "1 dose of super Strength potion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "4", + "name": "Super strength(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14245", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "30", + "examine": "1 dose of super Strength potion.", + "grand_exchange_price": "4", + "durability": null, + "name": "Super strength(1)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14246" + }, + { + "shop_price": "150", + "examine": "4 doses of ranging potion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "4", + "name": "Ranging potion(5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14247", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "150", + "examine": "5 doses of ranging potion.", + "grand_exchange_price": "4", + "durability": null, + "name": "Ranging potion(5)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14248" + }, + { + "shop_price": "120", + "examine": "4 doses of ranging potion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "4", + "name": "Ranging potion(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14249", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "120", + "examine": "4 doses of ranging potion.", + "grand_exchange_price": "4", + "durability": null, + "name": "Ranging potion(4)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14250" + }, + { + "shop_price": "90", + "examine": "3 doses of ranging potion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "4", + "name": "Ranging potion(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14251", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "90", + "examine": "3 doses of ranging potion.", + "grand_exchange_price": "4", + "durability": null, + "name": "Ranging potion(3)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14252" + }, + { + "shop_price": "60", + "examine": "2 doses of ranging potion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "4", + "name": "Ranging potion(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14253", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "60", + "examine": "2 doses of ranging potion.", + "grand_exchange_price": "4", + "durability": null, + "name": "Ranging potion(2)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14254" + }, + { + "shop_price": "30", + "examine": "1 dose of ranging potion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "4", + "name": "Ranging potion(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14255", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "30", + "examine": "1 dose of ranging potion.", + "grand_exchange_price": "4", + "durability": null, + "name": "Ranging potion(1)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14256" + }, + { + "shop_price": "150", + "examine": "3 doses of Defence Potion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "4", + "name": "Defence potion(5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14257", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "150", + "examine": "3 doses of Defence Potion.", + "grand_exchange_price": "4", + "durability": null, + "name": "Defence potion(5)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14258" + }, + { + "shop_price": "120", + "examine": "4 doses of Defence Potion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "4", + "name": "Defence potion(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14259", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "120", + "examine": "4 doses of Defence Potion.", + "grand_exchange_price": "4", + "durability": null, + "name": "Defence potion(4)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14260" + }, + { + "shop_price": "90", + "examine": "3 doses of Defence Potion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "4", + "name": "Defence potion(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14261", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "90", + "examine": "3 doses of Defence Potion.", + "grand_exchange_price": "4", + "durability": null, + "name": "Defence potion(3)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14262" + }, + { + "shop_price": "60", + "examine": "2 doses of Defence Potion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "4", + "name": "Defence potion(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14263", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "60", + "examine": "2 doses of Defence Potion.", + "grand_exchange_price": "4", + "durability": null, + "name": "Defence potion(2)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14264" + }, + { + "shop_price": "30", + "examine": "1 dose of Defence Potion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "4", + "name": "Defence potion(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14265", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "30", + "examine": "1 dose of Defence Potion.", + "grand_exchange_price": "4", + "durability": null, + "name": "Defence potion(1)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14266" + }, + { + "shop_price": "150", + "examine": "4 doses of Magic potion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "4", + "name": "Magic potion(5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14267", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "150", + "examine": "5 doses of Magic potion.", + "grand_exchange_price": "4", + "durability": null, + "name": "Magic potion(5)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14268" + }, + { + "shop_price": "120", + "examine": "4 doses of Magic potion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "4", + "name": "Magic potion(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14269", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "120", + "examine": "4 doses of Magic potion.", + "grand_exchange_price": "4", + "durability": null, + "name": "Magic potion(4)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14270" + }, + { + "shop_price": "90", + "examine": "3 doses of Magic potion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "4", + "name": "Magic potion(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14271", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "90", + "examine": "3 doses of Magic potion.", + "grand_exchange_price": "4", + "durability": null, + "name": "Magic potion(3)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14272" + }, + { + "shop_price": "60", + "examine": "2 doses of Magic potion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "4", + "name": "Magic potion(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14273", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "60", + "examine": "2 doses of Magic potion.", + "grand_exchange_price": "4", + "durability": null, + "name": "Magic potion(2)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14274" + }, + { + "shop_price": "30", + "examine": "1 dose of Magic potion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "4", + "name": "Magic potion(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14275", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "30", + "examine": "1 dose of Magic potion.", + "grand_exchange_price": "4", + "durability": null, + "name": "Magic potion(1)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14276" + }, + { + "shop_price": "150", + "examine": "3 doses of Summoning potion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "4", + "name": "Summoning potion(5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14277", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "150", + "examine": "3 doses of Summoning potion.", + "grand_exchange_price": "4", + "durability": null, + "name": "Summoning potion(5)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14278" + }, + { + "shop_price": "120", + "examine": "4 doses of Summoning potion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "4", + "name": "Summoning potion(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14279", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "120", + "examine": "4 doses of Summoning potion.", + "grand_exchange_price": "4", + "durability": null, + "name": "Summoning potion(4)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14280" + }, + { + "shop_price": "90", + "examine": "3 doses of Summoning potion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "4", + "name": "Summoning potion(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14281", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "90", + "examine": "3 doses of Summoning potion.", + "grand_exchange_price": "4", + "durability": null, + "name": "Summoning potion(3)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14282" + }, + { + "shop_price": "60", + "examine": "2 doses of Summoning potion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "4", + "name": "Summoning potion(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14283", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "60", + "examine": "2 doses of Summoning potion.", + "grand_exchange_price": "4", + "durability": null, + "name": "Summoning potion(2)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14284" + }, + { + "shop_price": "30", + "examine": "1 dose of Summoning potion.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "4", + "name": "Summoning potion(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14285", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "30", + "examine": "1 dose of Summoning potion.", + "grand_exchange_price": "4", + "durability": null, + "name": "Summoning potion(1)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14286" + }, + { + "shop_price": "30", + "examine": "The sacred clay has transformed into a vicious, curved sword.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "6", + "absorb": "0,0,0", + "render_anim": "1629", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "destroy_message": "Drop", + "attack_audios": "2500,0,2517,0", + "name": "Scimitar (class 1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14287", + "bonuses": "0,55,0,0,0,0,0,0,0,0,0,15,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "30", + "examine": "The sacred clay has transformed into a vicious, curved sword.", + "durability": null, + "name": "Scimitar (class 1)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14288" + }, + { + "shop_price": "60", + "examine": "The sacred clay has transformed into a vicious, curved sword.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "6", + "absorb": "0,0,0", + "render_anim": "1629", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "destroy_message": "Drop", + "attack_audios": "2500,0,2517,0", + "name": "Scimitar (class 2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14289", + "bonuses": "0,90,0,0,0,0,0,0,0,0,0,30,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "60", + "examine": "The sacred clay has transformed into a vicious, curved sword.", + "durability": null, + "name": "Scimitar (class 2)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14290" + }, + { + "shop_price": "90", + "examine": "The sacred clay has transformed into a vicious, curved sword.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "6", + "absorb": "0,0,0", + "render_anim": "1629", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "destroy_message": "Drop", + "attack_audios": "2500,0,2517,0", + "name": "Scimitar (class 3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14291", + "bonuses": "0,145,0,0,0,0,0,0,0,0,0,45,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "90", + "examine": "The sacred clay has transformed into a vicious, curved sword.", + "durability": null, + "name": "Scimitar (class 3)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14292" + }, + { + "shop_price": "120", + "examine": "The sacred clay has transformed into a vicious, curved sword.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "6", + "absorb": "0,0,0", + "render_anim": "1629", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "destroy_message": "Drop", + "attack_audios": "2500,0,2517,0", + "name": "Scimitar (class 4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14293", + "bonuses": "0,180,0,0,0,0,0,0,0,0,0,60,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "120", + "examine": "The sacred clay has transformed into a vicious, curved sword.", + "durability": null, + "name": "Scimitar (class 4)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14294" + }, + { + "shop_price": "150", + "examine": "The sacred clay has transformed into a vicious, curved sword.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "weapon_interface": "6", + "absorb": "0,0,0", + "render_anim": "1629", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "destroy_message": "Drop", + "attack_audios": "2500,0,2517,0", + "name": "Scimitar (class 5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14295", + "bonuses": "0,225,0,0,0,0,0,0,0,0,0,75,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "150", + "examine": "The sacred clay has transformed into a vicious, curved sword.", + "durability": null, + "name": "Scimitar (class 5)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14296" + }, + { + "shop_price": "30", + "examine": "The sacred clay transformed into a sharp dagger.", + "durability": null, + "destroy": "true", + "attack_speed": "3", + "weapon_interface": "5", + "absorb": "0,0,0", + "equipment_slot": "3", + "attack_anims": "400,400,401,400", + "destroy_message": "Drop", + "attack_audios": "2517,2517,2500,2517", + "name": "Dagger (class 1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14297", + "bonuses": "41,0,0,0,0,0,0,0,0,0,0,15,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "30", + "examine": "The sacred clay transformed into a sharp dagger.", + "durability": null, + "name": "Dagger (class 1)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14298" + }, + { + "shop_price": "60", + "examine": "The sacred clay transformed into a sharp dagger.", + "durability": null, + "destroy": "true", + "attack_speed": "3", + "weapon_interface": "5", + "absorb": "0,0,0", + "equipment_slot": "3", + "attack_anims": "400,400,401,400", + "destroy_message": "Drop", + "attack_audios": "2517,2517,2500,2517", + "name": "Dagger (class 2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14299", + "bonuses": "68,0,0,0,0,0,0,0,0,0,0,30,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "60", + "examine": "The sacred clay transformed into a sharp dagger.", + "durability": null, + "name": "Dagger (class 2)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14300" + }, + { + "shop_price": "90", + "examine": "The sacred clay transformed into a sharp dagger.", + "durability": null, + "destroy": "true", + "attack_speed": "3", + "weapon_interface": "5", + "absorb": "0,0,0", + "equipment_slot": "3", + "attack_anims": "400,400,401,400", + "destroy_message": "Drop", + "attack_audios": "2517,2517,2500,2517", + "name": "Dagger (class 3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14301", + "bonuses": "101,0,0,0,0,0,0,0,0,0,0,45,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "90", + "examine": "The sacred clay transformed into a sharp dagger.", + "durability": null, + "name": "Dagger (class 3)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14302" + }, + { + "shop_price": "120", + "examine": "The sacred clay transformed into a sharp dagger.", + "durability": null, + "destroy": "true", + "attack_speed": "3", + "weapon_interface": "5", + "absorb": "0,0,0", + "equipment_slot": "3", + "attack_anims": "400,400,401,400", + "destroy_message": "Drop", + "attack_audios": "2517,2517,2500,2517", + "name": "Dagger (class 4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14303", + "bonuses": "135,0,0,0,0,0,0,0,0,0,0,60,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "120", + "examine": "The sacred clay transformed into a sharp dagger.", + "durability": null, + "name": "Dagger (class 4)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14304" + }, + { + "shop_price": "150", + "examine": "The sacred clay transformed into a sharp dagger.", + "durability": null, + "destroy": "true", + "attack_speed": "3", + "weapon_interface": "5", + "absorb": "0,0,0", + "equipment_slot": "3", + "attack_anims": "400,400,401,400", + "destroy_message": "Drop", + "attack_audios": "2517,2517,2500,2517", + "name": "Dagger (class 5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14305", + "bonuses": "168,0,0,0,0,0,0,0,0,0,0,75,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "150", + "examine": "The sacred clay transformed into a sharp dagger.", + "durability": null, + "name": "Dagger (class 5)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14306" + }, + { + "shop_price": "30", + "examine": "The sacred clay has transformed into a heavy warhammer.", + "durability": null, + "destroy": "true", + "attack_speed": "6", + "weapon_interface": "10", + "absorb": "0,0,0", + "equip_audio": "", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Warhammer (class 1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14307", + "bonuses": "0,0,83,0,0,0,0,0,0,0,0,15,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "30", + "examine": "The sacred clay has transformed into a heavy warhammer.", + "durability": null, + "name": "Warhammer (class 1)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14308" + }, + { + "shop_price": "60", + "examine": "The sacred clay has transformed into a heavy warhammer.", + "durability": null, + "destroy": "true", + "attack_speed": "6", + "weapon_interface": "10", + "absorb": "0,0,0", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Warhammer (class 2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14309", + "bonuses": "0,0,135,0,0,0,0,0,0,0,0,30,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "60", + "examine": "The sacred clay has transformed into a heavy warhammer.", + "durability": null, + "name": "Warhammer (class 2)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14310" + }, + { + "shop_price": "90", + "examine": "The sacred clay has transformed into a heavy warhammer.", + "durability": null, + "destroy": "true", + "attack_speed": "6", + "weapon_interface": "10", + "absorb": "0,0,0", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Warhammer (class 3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14311", + "bonuses": "0,0,202,0,0,0,0,0,0,0,0,45,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "90", + "examine": "The sacred clay has transformed into a heavy warhammer.", + "durability": null, + "name": "Warhammer (class 3)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14312" + }, + { + "shop_price": "120", + "examine": "The Sacred Clay has transformed into a heavy warhammer.", + "durability": null, + "destroy": "true", + "attack_speed": "6", + "weapon_interface": "10", + "absorb": "0,0,0", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Warhammer (class 4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14313", + "bonuses": "0,0,270,0,0,0,0,0,0,0,0,60,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "120", + "examine": "The Sacred Clay has transformed into a heavy warhammer.", + "durability": null, + "name": "Warhammer (class 4)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14314" + }, + { + "shop_price": "150", + "examine": "The sacred clay has transformed into a heavy warhammer.", + "durability": null, + "destroy": "true", + "attack_speed": "6", + "weapon_interface": "10", + "absorb": "0,0,0", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Warhammer (class 5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14315", + "bonuses": "0,0,338,0,0,0,0,0,0,0,0,75,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "150", + "examine": "The sacred clay has transformed into a heavy warhammer.", + "durability": null, + "name": "Warhammer (class 5)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14316" + }, + { + "shop_price": "30", + "examine": "The sacred clay has transformed into a light, cloth-like material.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "4", + "destroy_message": "Drop", + "remove_sleeves": "true", + "name": "Robe top (class 1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14317", + "bonuses": "0,0,0,0,0,0,0,0,20,0,20,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "30", + "examine": "The sacred clay has transformed into a light, cloth-like material.", + "durability": null, + "name": "Robe top (class 1)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14318" + }, + { + "shop_price": "60", + "examine": "The sacred clay has transformed into a light, cloth-like substance.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "4", + "destroy_message": "Drop", + "remove_sleeves": "true", + "name": "Robe top (class 2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14319", + "bonuses": "0,0,0,0,0,0,0,0,40,0,40,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "60", + "examine": "The sacred clay has transformed into a light, cloth-like substance.", + "durability": null, + "name": "Robe top (class 2)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14320" + }, + { + "shop_price": "90", + "examine": "The sacred clay has transformed into a light, cloth-like substance.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "4", + "destroy_message": "Drop", + "remove_sleeves": "true", + "name": "Robe top (class 3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14321", + "bonuses": "0,0,0,0,0,0,0,0,60,0,60,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "90", + "examine": "The sacred clay has transformed into a light, cloth-like substance.", + "durability": null, + "name": "Robe top (class 3)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14322" + }, + { + "shop_price": "120", + "examine": "The sacred clay has transformed into a light, cloth-like substance.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "4", + "destroy_message": "Drop", + "remove_sleeves": "true", + "name": "Robe top (class 4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14323", + "bonuses": "0,0,0,0,0,0,0,0,80,0,80,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "120", + "examine": "The sacred clay has transformed into a light, cloth-like substance.", + "durability": null, + "name": "Robe top (class 4)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14324" + }, + { + "shop_price": "150", + "examine": "The sacred clay has transformed into a light, cloth-like substance.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "4", + "destroy_message": "Drop", + "remove_sleeves": "true", + "name": "Robe top (class 5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14325", + "bonuses": "0,0,0,0,0,0,0,0,100,0,100,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "150", + "examine": "The sacred clay has transformed into a light, cloth-like substance.", + "durability": null, + "name": "Robe top (class 5)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14326" + }, + { + "shop_price": "30", + "examine": "The sacred clay has transformed into a light, cloth-like material.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "7", + "destroy_message": "Drop", + "name": "Robe bottom (class 1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14327", + "bonuses": "0,0,0,0,0,0,0,0,15,0,15,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "30", + "examine": "The sacred clay has transformed into a light, cloth-like material.", + "durability": null, + "name": "Robe bottom (class 1)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14328" + }, + { + "shop_price": "60", + "examine": "The sacred clay has transformed into a light, cloth-like material.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "7", + "destroy_message": "Drop", + "name": "Robe bottom (class 2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14329", + "bonuses": "0,0,0,0,0,0,0,0,30,0,30,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "60", + "examine": "The sacred clay has transformed into a light, cloth-like material.", + "durability": null, + "name": "Robe bottom (class 2)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14330" + }, + { + "shop_price": "90", + "examine": "The sacred clay transformed into a light, cloth-like material.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "7", + "destroy_message": "Drop", + "name": "Robe bottom (class 3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14331", + "bonuses": "0,0,0,0,0,0,0,0,45,0,45,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "90", + "examine": "The sacred clay transformed into a light, cloth-like material.", + "durability": null, + "name": "Robe bottom (class 3)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14332" + }, + { + "shop_price": "120", + "examine": "The sacred clay has transformed into a light, cloth-like material.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "7", + "destroy_message": "Drop", + "name": "Robe bottom (class 4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14333", + "bonuses": "0,0,0,0,0,0,0,0,60,0,60,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "120", + "examine": "The sacred clay has transformed into a light, cloth-like material.", + "durability": null, + "name": "Robe bottom (class 4)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14334" + }, + { + "shop_price": "150", + "examine": "The sacred clay has transformed into a light, cloth-like material.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "7", + "destroy_message": "Drop", + "name": "Robe bottom (class 5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14335", + "bonuses": "0,0,0,0,0,0,0,0,75,0,75,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "150", + "examine": "The sacred clay has transformed into a light, cloth-like material.", + "durability": null, + "name": "Robe bottom (class 5)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14336" + }, + { + "shop_price": "30", + "examine": "The sacred clay has transformed into a light, cloth-like material.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "0", + "destroy_message": "Drop", + "name": "Hat (class 1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14337", + "bonuses": "0,0,0,0,0,0,0,0,10,0,10,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "30", + "examine": "The sacred clay has transformed into a light, cloth-like material.", + "durability": null, + "name": "Hat (class 1)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14338" + }, + { + "shop_price": "60", + "examine": "The sacred clay has transformed into a light, cloth-like material.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "0", + "destroy_message": "Drop", + "name": "Hat (class 2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14339", + "bonuses": "0,0,0,0,0,0,0,0,20,0,20,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "60", + "examine": "The sacred clay has transformed into a light, cloth-like material.", + "durability": null, + "name": "Hat (class 2)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14340" + }, + { + "shop_price": "90", + "examine": "The sacred clay has transformed into a light, cloth-like material.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "0", + "destroy_message": "Drop", + "name": "Hat (class 3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14341", + "bonuses": "0,0,0,0,0,0,0,0,30,0,30,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "90", + "examine": "The sacred clay has transformed into a light, cloth-like material.", + "durability": null, + "name": "Hat (class 3)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14342" + }, + { + "shop_price": "120", + "examine": "The sacred clay has transformed into a light, cloth-like material.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "0", + "destroy_message": "Drop", + "name": "Hat (class 4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14343", + "bonuses": "0,0,0,0,0,0,0,0,40,0,40,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "120", + "examine": "The sacred clay has transformed into a light, cloth-like material.", + "durability": null, + "name": "Hat (class 4)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14344" + }, + { + "shop_price": "150", + "examine": "The sacred clay has transformed into a light, cloth-like material.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "0", + "destroy_message": "Drop", + "name": "Hat (class 5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14345", + "bonuses": "0,0,0,0,0,0,0,0,50,0,50,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "150", + "examine": "The sacred clay has transformed into a light, cloth-like material.", + "durability": null, + "name": "Hat (class 5)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14346" + }, + { + "shop_price": "30", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "4", + "destroy_message": "Drop", + "remove_sleeves": "true", + "name": "Platebody (class 1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14347", + "bonuses": "0,0,0,-30,-10,20,20,20,-10,10,20,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "30", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "durability": null, + "name": "Platebody (class 1)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14348" + }, + { + "shop_price": "60", + "examine": "The sacred clay transformed into a hard, metallic substance.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "4", + "destroy_message": "Drop", + "remove_sleeves": "true", + "name": "Platebody (class 2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14349", + "bonuses": "0,0,0,-30,-10,40,40,40,-10,20,40,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "60", + "examine": "The sacred clay transformed into a hard, metallic substance.", + "durability": null, + "name": "Platebody (class 2)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14350" + }, + { + "shop_price": "90", + "examine": "The sacred clay top has transformed into a spiked, platemail body.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "4", + "destroy_message": "Drop", + "remove_sleeves": "true", + "name": "Platebody (class 3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14351", + "bonuses": "0,0,0,-30,-10,60,60,60,-10,30,60,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "90", + "examine": "The sacred clay top has transformed into a spiked, platemail body.", + "durability": null, + "name": "Platebody (class 3)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14352" + }, + { + "shop_price": "120", + "examine": "The sacred clay top has transformed into a spiked, platemail body.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "4", + "destroy_message": "Drop", + "remove_sleeves": "true", + "name": "Platebody (class 4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14353", + "bonuses": "0,0,0,-30,-10,80,80,80,-10,40,80,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "120", + "examine": "The sacred clay top has transformed into a spiked, platemail body.", + "durability": null, + "name": "Platebody (class 4)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14354" + }, + { + "shop_price": "150", + "examine": "The sacred clay top has transformed into a spiked, platemail body.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "4", + "destroy_message": "Drop", + "remove_sleeves": "true", + "name": "Platebody (class 5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14355", + "bonuses": "0,0,0,-30,-10,100,100,100,-10,50,100,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "150", + "examine": "The sacred clay top has transformed into a spiked, platemail body.", + "durability": null, + "name": "Platebody (class 5)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14356" + }, + { + "shop_price": "30", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "7", + "destroy_message": "Drop", + "name": "Platelegs (class 1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14357", + "bonuses": "0,0,0,-30,-10,15,15,15,-10,7,15,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "30", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "durability": null, + "name": "Platelegs (class 1)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14358" + }, + { + "shop_price": "60", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "7", + "destroy_message": "Drop", + "name": "Platelegs (class 2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14359", + "bonuses": "0,0,0,-30,-10,30,30,30,-10,15,30,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "60", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "durability": null, + "name": "Platelegs (class 2)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14360" + }, + { + "shop_price": "90", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "7", + "destroy_message": "Drop", + "name": "Platelegs (class 3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14361", + "bonuses": "0,0,0,-30,-10,45,45,45,-10,23,45,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "90", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "durability": null, + "name": "Platelegs (class 3)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14362" + }, + { + "shop_price": "120", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "7", + "destroy_message": "Drop", + "name": "Platelegs (class 4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14363", + "bonuses": "0,0,0,-30,-10,60,60,60,-10,30,60,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "120", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "durability": null, + "name": "Platelegs (class 4)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14364" + }, + { + "shop_price": "150", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "7", + "destroy_message": "Drop", + "name": "Platelegs (class 5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14365", + "bonuses": "0,0,0,-30,-10,75,75,75,-10,37,75,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "150", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "durability": null, + "name": "Platelegs (class 5)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14366" + }, + { + "remove_head": "true", + "shop_price": "30", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "0", + "destroy_message": "Drop", + "name": "Helm (class 1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14367", + "bonuses": "0,0,0,-30,-10,10,10,10,-10,5,10,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "30", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "durability": null, + "name": "Helm (class 1)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14368" + }, + { + "remove_head": "true", + "shop_price": "60", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "0", + "destroy_message": "Drop", + "name": "Helm (class 2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14369", + "bonuses": "0,0,0,-30,-10,20,20,20,-10,10,20,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "60", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "durability": null, + "name": "Helm (class 2)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14370" + }, + { + "remove_head": "true", + "shop_price": "90", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "0", + "destroy_message": "Drop", + "name": "Helm (class 3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14371", + "bonuses": "0,0,0,-30,-10,30,30,30,-10,15,30,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "90", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "durability": null, + "name": "Helm (class 3)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14372" + }, + { + "remove_head": "true", + "shop_price": "120", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "0", + "destroy_message": "Drop", + "name": "Helm (class 4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14373", + "bonuses": "0,0,0,-30,-10,40,40,40,-10,20,40,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "120", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "durability": null, + "name": "Helm (class 4)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14374" + }, + { + "remove_head": "true", + "shop_price": "150", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "0", + "destroy_message": "Drop", + "name": "Helm (class 5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14375", + "bonuses": "0,0,0,-30,-10,50,50,50,-10,25,50,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "150", + "examine": "The sacred clay has transformed into a hard, metallic substance.", + "durability": null, + "name": "Helm (class 5)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14376" + }, + { + "shop_price": "30", + "examine": "The sacred clay has transformed into a light weight, magical stick.", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "weapon_interface": "1", + "absorb": "0,0,0", + "render_anim": "28", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Staff (class 1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14377", + "bonuses": "0,0,0,55,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "30", + "examine": "The sacred clay has transformed into a light weight, magical stick.", + "durability": null, + "name": "Staff (class 1)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14378" + }, + { + "shop_price": "60", + "examine": "The sacred clay has transformed into a light weight, magical stick.", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "weapon_interface": "1", + "absorb": "0,0,0", + "render_anim": "28", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Staff (class 2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14379", + "bonuses": "0,0,0,90,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "60", + "examine": "The sacred clay has transformed into a light weight, magical stick.", + "durability": null, + "name": "Staff (class 2)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14380" + }, + { + "shop_price": "90", + "examine": "The sacred clay has transformed into a lightweight, magical stick.", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "weapon_interface": "1", + "absorb": "0,0,0", + "render_anim": "28", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Staff (class 3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14381", + "bonuses": "0,0,0,135,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "90", + "examine": "The sacred clay has transformed into a lightweight, magical stick.", + "durability": null, + "name": "Staff (class 3)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14382" + }, + { + "shop_price": "120", + "examine": "The sacred clay has transformed into a lightweight, magical stick.", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "weapon_interface": "1", + "absorb": "0,0,0", + "render_anim": "28", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Staff (class 4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14383", + "bonuses": "0,0,0,180,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "120", + "examine": "The sacred clay has transformed into a lightweight, magical stick.", + "durability": null, + "name": "Staff (class 4)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14384" + }, + { + "shop_price": "150", + "examine": "The sacred clay has transformed into a lightweight, magical stick.", + "durability": null, + "destroy": "true", + "attack_speed": "5", + "weapon_interface": "1", + "absorb": "0,0,0", + "render_anim": "28", + "equipment_slot": "3", + "destroy_message": "Drop", + "name": "Staff (class 5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14385", + "bonuses": "0,0,0,225,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "150", + "examine": "The sacred clay has transformed into a lightweight, magical stick.", + "durability": null, + "name": "Staff (class 5)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14386" + }, + { + "durability": null, + "name": "Cape", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14387", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "durability": null, + "name": "Cape", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14389", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,1,1,0,2,0,0,0,0,0", + "equipment_slot": "1" + }, + { + "shop_price": "30", + "examine": "The sacred clay has transformed into a flexible mesh.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "4", + "destroy_message": "Drop", + "remove_sleeves": "true", + "name": "Leather body (class 1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14391", + "bonuses": "0,0,0,0,0,10,10,10,10,20,20,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "30", + "examine": "The sacred clay has transformed into a flexible mesh.", + "durability": null, + "name": "Leather body (class 1)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14392" + }, + { + "shop_price": "60", + "examine": "The sacred clay has transformed into a flexible mesh.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "4", + "destroy_message": "Drop", + "remove_sleeves": "true", + "name": "Leather body (class 2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14393", + "bonuses": "0,0,0,0,0,20,20,20,20,40,40,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "60", + "examine": "The sacred clay has transformed into a flexible mesh.", + "durability": null, + "name": "Leather body (class 2)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14394" + }, + { + "shop_price": "90", + "examine": "The sacred clay has transformed into a flexible mesh.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "4", + "destroy_message": "Drop", + "remove_sleeves": "true", + "name": "Leather body (class 3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14395", + "bonuses": "0,0,0,0,0,30,30,30,30,60,60,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "90", + "examine": "The sacred clay has transformed into a flexible mesh.", + "durability": null, + "name": "Leather body (class 3)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14396" + }, + { + "shop_price": "120", + "examine": "The sacred clay has transformed into a flexible mesh.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "4", + "destroy_message": "Drop", + "remove_sleeves": "true", + "name": "Leather body (class 4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14397", + "bonuses": "0,0,0,0,0,40,40,40,40,80,80,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "120", + "examine": "The sacred clay has transformed into a flexible mesh.", + "durability": null, + "name": "Leather body (class 4)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14398" + }, + { + "shop_price": "150", + "examine": "The sacred clay has transformed into a flexible mesh.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "4", + "destroy_message": "Drop", + "remove_sleeves": "true", + "name": "Leather body (class 5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14399", + "bonuses": "0,0,0,0,0,50,50,50,50,100,100,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "150", + "examine": "The sacred clay has transformed into a flexible mesh.", + "durability": null, + "name": "Leather body (class 5)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14400" + }, + { + "shop_price": "30", + "examine": "The sacred clay transformed into a flexible mesh.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "7", + "destroy_message": "Drop", + "name": "Chaps (class 1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14401", + "bonuses": "0,0,0,0,0,7,7,7,0,15,15,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "30", + "examine": "The sacred clay transformed into a flexible mesh.", + "durability": null, + "name": "Chaps (class 1)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14402" + }, + { + "shop_price": "60", + "examine": "The sacred clay transformed into a flexible mesh.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "7", + "destroy_message": "Drop", + "name": "Chaps (class 2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14403", + "bonuses": "0,0,0,0,0,15,15,15,0,30,30,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "60", + "examine": "The sacred clay transformed into a flexible mesh.", + "durability": null, + "name": "Chaps (class 2)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14404" + }, + { + "shop_price": "90", + "examine": "The sacred clay transformed into a flexible mesh.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "7", + "destroy_message": "Drop", + "name": "Chaps (class 3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14405", + "bonuses": "0,0,0,0,0,23,23,23,0,45,45,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "90", + "examine": "The sacred clay transformed into a flexible mesh.", + "durability": null, + "name": "Chaps (class 3)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14406" + }, + { + "shop_price": "120", + "examine": "The sacred clay transformed into a flexible mesh.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "7", + "destroy_message": "Drop", + "name": "Chaps (class 4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14407", + "bonuses": "0,0,0,0,0,30,30,30,0,60,60,0,0,1,0" + }, + { + "destroy_message": "Drop", + "shop_price": "120", + "examine": "The sacred clay transformed into a flexible mesh.", + "durability": null, + "name": "Chaps (class 4)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14408" + }, + { + "shop_price": "150", + "examine": "The sacred clay transformed into a flexible mesh.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "7", + "destroy_message": "Drop", + "name": "Chaps (class 5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14409", + "bonuses": "0,0,0,0,0,37,37,37,0,75,75,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "150", + "examine": "The sacred clay transformed into a flexible mesh.", + "durability": null, + "name": "Chaps (class 5)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14410" + }, + { + "remove_head": "true", + "shop_price": "30", + "examine": "The sacred clay has transformed into a flexible, protective mesh.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equip_audio": "", + "equipment_slot": "0", + "destroy_message": "Drop", + "name": "Coif (class 1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14411", + "bonuses": "0,0,0,0,0,5,5,5,0,10,10,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "30", + "examine": "The sacred clay has transformed into a flexible, protective mesh.", + "durability": null, + "name": "Coif (class 1)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14412", + "equip_audio": "" + }, + { + "remove_head": "true", + "shop_price": "60", + "examine": "The sacred clay has transformed into a flexible, protective mesh.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equip_audio": "", + "equipment_slot": "0", + "destroy_message": "Drop", + "name": "Coif (class 2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14413", + "bonuses": "0,0,0,0,0,10,10,10,0,20,20,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "60", + "examine": "The sacred clay has transformed into a flexible, protective mesh.", + "durability": null, + "name": "Coif (class 2)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14414" + }, + { + "remove_head": "true", + "shop_price": "90", + "examine": "The sacred clay has transformed into a flexible, protective mesh.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equip_audio": "", + "equipment_slot": "0", + "destroy_message": "Drop", + "name": "Coif (class 3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14415", + "bonuses": "0,0,0,0,0,15,15,15,0,30,30,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "90", + "examine": "The sacred clay has transformed into a flexible, protective mesh.", + "durability": null, + "name": "Coif (class 3)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14416" + }, + { + "remove_head": "true", + "shop_price": "120", + "examine": "The sacred clay has transformed into a flexible, protective mesh.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equip_audio": "", + "equipment_slot": "0", + "destroy_message": "Drop", + "name": "Coif (class 4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14417", + "bonuses": "0,0,0,0,0,20,20,20,0,40,40,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "120", + "examine": "The sacred clay has transformed into a flexible, protective mesh.", + "durability": null, + "name": "Coif (class 4)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14418" + }, + { + "remove_head": "true", + "shop_price": "150", + "examine": "The sacred clay has transformed into a flexible, protective mesh.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equipment_slot": "0", + "destroy_message": "Drop", + "name": "Coif (class 5)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14419", + "bonuses": "0,0,0,0,0,25,25,25,0,50,50,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "150", + "examine": "The sacred clay has transformed into a flexible, protective mesh.", + "durability": null, + "name": "Coif (class 5)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14420" + }, + { + "shop_price": "30", + "durability": null, + "name": "Clay deposit scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14421", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "30", + "examine": "This scroll will make your familiar deposit its items at your base.", + "durability": null, + "name": "Sacred clay pouch (class 1)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14422", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "30", + "examine": "This scroll will make your familiar deposit its items at your base.", + "durability": null, + "name": "Sacred clay pouch (class 1)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14423" + }, + { + "destroy_message": "Drop", + "shop_price": "60", + "examine": "This scroll will make your familiar deposit its items at your base.", + "durability": null, + "name": "Sacred clay pouch (class 2)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14424", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "60", + "examine": "This scroll will make your familiar deposit its items at your base.", + "durability": null, + "name": "Sacred clay pouch (class 2)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14425" + }, + { + "destroy_message": "Drop", + "shop_price": "90", + "examine": "This scroll will make your familiar deposit its items at your base.", + "durability": null, + "name": "Sacred clay pouch (class 3)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14426", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "90", + "examine": "This scroll will make your familiar deposit its items at your base.", + "durability": null, + "name": "Sacred clay pouch (class 3)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14427" + }, + { + "destroy_message": "Drop", + "shop_price": "120", + "examine": "This scroll will make your familiar deposit its items at your base.", + "durability": null, + "name": "Sacred clay pouch (class 4)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14428", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "120", + "examine": "This scroll will make your familiar deposit its items at your base.", + "durability": null, + "name": "Sacred clay pouch (class 4)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14429" + }, + { + "destroy_message": "Drop", + "shop_price": "150", + "examine": "This scroll will make your familiar deposit its items at your base.", + "durability": null, + "name": "Sacred clay pouch (class 5)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14430", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "150", + "examine": "This scroll will make your familiar deposit its items at your base.", + "durability": null, + "name": "Sacred clay pouch (class 5)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14431" + }, + { + "durability": null, + "name": "Null sacred clay", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14432", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "5", + "examine": "A vine flower grown through magical means.", + "durability": null, + "name": "Vine flower", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14458", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You caught this broav west of the Hunting Expert's home. You can catch another one with a trap baited with mort Myre Fungus.", + "examine": "Its unconscious, poor thing.", + "durability": null, + "name": "Unconscious broav", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14459", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You got these clothes from a washerman who lives near the Khazard battle arena.", + "shop_price": "10", + "examine": "Some dirty clothes that apparently belong to Movario.", + "durability": null, + "name": "Dirty laundry", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14460", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "3" + }, + { + "destroy_message": "You found this basket in Movario's base.", + "examine": "A receptacle for rubbish.", + "durability": null, + "name": "Waste-paper basket", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14461", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You found this key attached to the bottom of the bin in Movario's base.", + "examine": "A superbly made key with a fine ruby inserted into it. (While Guthix Sleeps)", + "durability": null, + "name": "Ruby key", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14462", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You found these notes in Movario's basement.", + "examine": "A collection of notes made by an absent-minded fellow.", + "durability": null, + "name": "Notes on pressure", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14463", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You found these notes loosely piled up on ", + "examine": "A loose-leaf collection of research notes, found on Movario's study desk.", + "durability": null, + "name": "Movario's notes (volume 1)", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14464", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You found these notes in Movario's bedchest, in his base of operations near the Khazard Battlefield.", + "examine": "A loose-leaf collection of research notes, found in Movario's bed chest.", + "durability": null, + "name": "Movario's notes (volume 2)", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14465", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "examine": "A 1kg weight.", + "durability": null, + "name": "Weight (1kg)", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14466", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "examine": "A 2kg weight.", + "durability": null, + "name": "Weight (2kg)", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14467", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "examine": "A 5kg weight.", + "durability": null, + "name": "Weight (5kg)", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14468", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You can find another under the bed on the top level of Movario's base", + "examine": "The loop half of a strange key.", + "durability": null, + "name": "Strange key loop", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14469", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You can find another under the bed on the top level of Movario's base", + "examine": "The teeth half of a strange key.", + "durability": null, + "name": "Strange key teeth", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14470", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You fused together two parts of a Dragonkin key which you obtained from Movario's base.", + "examine": "The completed dragonkin key.", + "durability": null, + "name": "Dragonkin key", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14471", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "30000", + "examine": "A badly damaged lump of dragon metal.", + "durability": null, + "rare_item": "true", + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "955683", + "name": "Ruined dragon armour lump", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14472", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "30000", + "examine": "A badly damaged lump of dragon metal.", + "grand_exchange_price": "955683", + "durability": null, + "name": "Ruined dragon armour lump", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14473" + }, + { + "shop_price": "30000", + "examine": "A badly damaged slice of dragon metal.", + "durability": null, + "rare_item": "true", + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "1761141", + "name": "Ruined dragon armour slice", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14474", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "30000", + "examine": "A badly damaged slice of dragon metal.", + "grand_exchange_price": "1761141", + "durability": null, + "name": "Ruined dragon armour slice", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14475" + }, + { + "shop_price": "30000", + "examine": "A badly damaged shard of dragon metal.", + "durability": null, + "rare_item": "true", + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "1090493", + "name": "Ruined dragon armour shard", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14476", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "30000", + "examine": "A badly damaged shard of dragon metal.", + "grand_exchange_price": "1090493", + "durability": null, + "name": "Ruined dragon armour shard", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14477" + }, + { + "destroy_message": "Drop", + "examine": "A very powerful Smithing hammer.", + "durability": null, + "name": "Blast fusion hammer", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14478", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "3" + }, + { + "requirements": "{1,60}", + "shop_price": "1760000", + "examine": "Provides excellent protection.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "4,0,9", + "equip_audio": "2239", + "equipment_slot": "4", + "lendable": "true", + "destroy_message": "Drop", + "remove_sleeves": "true", + "grand_exchange_price": "4453643", + "name": "Dragon platebody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14479", + "bonuses": "0,0,0,-30,0,109,107,97,-6,106,50,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "1760000", + "examine": "Provides excellent protection.", + "grand_exchange_price": "4453643", + "durability": null, + "name": "Dragon platebody", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14480" + }, + { + "requirements": "{1,60}", + "examine": "Provides excellent protection.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "4,0,9", + "equip_audio": "", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "4453643", + "name": "Dragon platebody", + "archery_ticket_price": "0", + "id": "14481", + "bonuses": "0,0,0,-30,0,109,107,97,-6,106,50,0,0,0,0" + }, + { + "examine": "A set of fighting claws.", + "has_special": "true", + "rare_item": "true", + "attack_speed": "4", + "two_handed": "true", + "absorb": "0,0,0", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "393,393,1067,393", + "destroy_message": "Drop", + "grand_exchange_price": "1472441", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14484", + "bonuses": "41,57,-4,0,0,13,26,7,0,0,0,56,0,0,0", + "requirements": "{0,60}", + "shop_price": "67500", + "durability": null, + "destroy": "true", + "weapon_interface": "9", + "equip_audio": "1003", + "render_anim": "2583", + "lendable": "true", + "attack_audios": "2548,2548,2548,2548", + "name": "Dragon claws" + }, + { + "destroy_message": "Drop", + "shop_price": "67500", + "examine": "A set of fighting claws.", + "grand_exchange_price": "1472441", + "durability": null, + "name": "Dragon claws", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "two_handed": "true", + "id": "14485" + }, + { + "requirements": "{0,60}", + "examine": "A set of fighting claws.", + "has_special": "true", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "two_handed": "true", + "weapon_interface": "9", + "absorb": "0,0,0", + "equip_audio": "1003", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "1472441", + "attack_audios": "2548,2548,2548,2548", + "name": "Dragon claws", + "archery_ticket_price": "0", + "id": "14486", + "bonuses": "41,57,-4,0,0,13,26,7,0,0,0,56,0,0,0" + }, + { + "destroy_message": "You grew this herb by planting an enriched snapdragon seed in the special herb patch on top of Falador castle.", + "examine": "An enriched snapdragon herb.", + "durability": null, + "name": "Enriched snapdragon", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14487", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You made this serum by mixing an enriched snapdragon into one of Betty's truth serums.", + "examine": "Fluid sloshes innocently in this vial.", + "durability": null, + "name": "Super truth serum", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14488", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You gained this item by having papyrus and charcoal in your inventory while interrogating a spy in Falador castle.", + "examine": "A sketch of the suspect known as Dark Squall.", + "durability": null, + "name": "Suspect sketch", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14489", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "requirements": "{1,40}", + "shop_price": "65000", + "examine": "These look pretty heavy, but very elite.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "2,0,4", + "equip_audio": "2242", + "equipment_slot": "7", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "41559", + "name": "Elite black platelegs", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14490", + "bonuses": "0,0,0,-14,-6,52,50,25,-1,49,15,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "65000", + "examine": "These look pretty heavy, but very elite.", + "grand_exchange_price": "41559", + "durability": null, + "name": "Elite black platelegs", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14491" + }, + { + "requirements": "{1,40}", + "shop_price": "64000", + "examine": "Provides excellent protection, and is elite.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "3,0,6", + "equip_audio": "2239", + "equipment_slot": "4", + "lendable": "true", + "destroy_message": "Drop", + "remove_sleeves": "true", + "grand_exchange_price": "38275", + "name": "Elite black platebody", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14492", + "bonuses": "0,0,0,-20,-8,80,85,40,-2,80,40,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "64000", + "examine": "Provides excellent protection, and is elite.", + "grand_exchange_price": "38275", + "durability": null, + "name": "Elite black platebody", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14493" + }, + { + "remove_head": "true", + "requirements": "{1,40}", + "shop_price": "35200", + "examine": "A full face helmet, and elite.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "1,0,3", + "remove_beard": "true", + "equipment_slot": "0", + "lendable": "true", + "destroy_message": "Drop", + "grand_exchange_price": "30542", + "name": "Elite black full helm", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14494", + "bonuses": "0,0,0,-4,-2,31,33,15,0,30,7,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "35200", + "examine": "A full face helmet, and elite.", + "grand_exchange_price": "30542", + "durability": null, + "name": "Elite black full helm", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14495" + }, + { + "destroy_message": "You got this key from the key rack in Dark Squall's base.", + "examine": "Opens the cells beneath the Black Knights' Fortress. (While Guthix Sleeps)", + "durability": null, + "name": "Cell key", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14496", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "requirements": "{1,20}-{6,40}", + "shop_price": "120000", + "examine": "A robe worn by members of the Dagon'hai.", + "durability": null, + "destroy": "false", + "attack_speed": "4", + "absorb": "3,1,0", + "equipment_slot": "4", + "remove_sleeves": "true", + "grand_exchange_price": "71098", + "name": "Dagon'hai robe top", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14497", + "bonuses": "0,0,0,20,0,0,0,0,20,0,20,0,0,2,0" + }, + { + "shop_price": "120000", + "examine": "A robe worn by members of the Dagon'hai.", + "grand_exchange_price": "71098", + "durability": null, + "name": "Dagon'hai robe top", + "tradeable": "true", + "destroy": "false", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14498" + }, + { + "requirements": "{1,20}-{6,40}", + "shop_price": "15000", + "examine": "A hat worn by members of the Dagon'hai.", + "durability": null, + "destroy": "false", + "attack_speed": "4", + "absorb": "1,0,0", + "equipment_slot": "0", + "grand_exchange_price": "9580", + "name": "Dagon'hai hat", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14499", + "bonuses": "0,0,0,4,0,0,0,0,4,0,4,0,0,0,0" + }, + { + "shop_price": "15000", + "examine": "A hat worn by members of the Dagon'hai.", + "grand_exchange_price": "9580", + "durability": null, + "name": "Dagon'hai hat", + "tradeable": "true", + "destroy": "false", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14500" + }, + { + "requirements": "{1,20}-{6,40}", + "shop_price": "80000", + "examine": "A robe worn by members of the Dagon'hai.", + "durability": null, + "destroy": "false", + "attack_speed": "4", + "absorb": "2,1,0", + "equipment_slot": "7", + "grand_exchange_price": "45691", + "name": "Dagon'hai robe bottom", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14501", + "bonuses": "0,0,0,15,0,0,0,0,15,0,15,0,0,2,0" + }, + { + "shop_price": "80000", + "examine": "A robe worn by members of the Dagon'hai.", + "grand_exchange_price": "45691", + "durability": null, + "name": "Dagon'hai robe bottom", + "tradeable": "true", + "destroy": "false", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14502" + }, + { + "shop_price": "1", + "examine": "Elite Black Knight armour adds to his stealthiness.", + "durability": null, + "name": "Silif", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14503", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "1", + "examine": "Elite Black Knight armour adds to his stealthiness.", + "durability": null, + "name": "Silif", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14504", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "durability": null, + "name": "Teleorb", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14505", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "5" + }, + { + "destroy_message": "You created this by focusing the light onto a snapdragon seed from a rose tinted lens while in Betty's shop.", + "examine": "An enriched snapdragon seed. The herb that grows from this seed will be extra potent!", + "durability": null, + "name": "Enriched snapdragon seed", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14506", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You got this by solving a puzzle in the a Guthixian temple near the Chasm of Tears.", + "examine": "Part of a stone circle.", + "durability": null, + "name": "Dolmen", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14507", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You got this by solving a puzzle in the a Guthixian temple near the Chasm of Tears.", + "examine": "Part of a stone circle.", + "durability": null, + "name": "Dolmen", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14508", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You got this by solving a puzzle in the a Guthixian temple near the Chasm of Tears.", + "examine": "Part of a stone circle.", + "durability": null, + "name": "Dolmen", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14509", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You got this by solving a puzzle in the a Guthixian temple near the Chasm of Tears.", + "examine": "Part of a stone circle.", + "durability": null, + "name": "Dolmen", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14510", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You got this by solving a puzzle in the a Guthixian temple near the Chasm of Tears.", + "examine": "Part of a stone circle.", + "durability": null, + "name": "Dolmen", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14511", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You got this by solving a puzzle in the a Guthixian temple near the Chasm of Tears.", + "examine": "Part of a stone circle.", + "durability": null, + "name": "Dolmen", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14512", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You got this by solving a puzzle in the a Guthixian temple near the Chasm of Tears.", + "examine": "Part of a stone circle.", + "durability": null, + "name": "Dolmen", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14513", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You got this by solving a puzzle in the a Guthixian temple near the Chasm of Tears.", + "examine": "Part of a stone circle.", + "durability": null, + "name": "Dolmen", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14514", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You found this in the Chasm of Tears by using an air-orb on an etched wall section.", + "examine": "An elemental key of air.", + "durability": null, + "name": "Air key", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14515", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You found this in the Chasm of Tears by using an earth-orb on an etched wall section.", + "examine": "An elemental key of earth.", + "durability": null, + "name": "Earth key", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14516", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You found this in the Chasm of Tears by using an", + "examine": "An elemental key of fire.", + "durability": null, + "name": "Fire key", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14517", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You found this in the Chasm of Tears by using an", + "examine": "An elemental key of water.", + "durability": null, + "name": "Water key", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14518", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You found this in the Chasm of Tears by using an air-orb on an etched wall section.", + "examine": "An elemental key of air.", + "durability": null, + "name": "Air key", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14519", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You found this in the Chasm of Tears by using an earth-orb on an etched wall section.", + "examine": "An elemental key of earth.", + "durability": null, + "name": "Earth key", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14520", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You found this in the Chasm of Tears by using an", + "examine": "An elemental key of fire.", + "durability": null, + "name": "Fire key", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14521", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You found this in the Chasm of Tears by using an", + "examine": "An elemental key of water.", + "durability": null, + "name": "Water key", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14522", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "20", + "examine": "Grand Exchange set containing a hat, top and bottoms.", + "grand_exchange_price": "193541", + "durability": null, + "name": "Dagon'hai robes set", + "tradeable": "true", + "destroy": "false", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14525", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "20", + "examine": "Grand Exchange set containing a hat, top and bottoms.", + "grand_exchange_price": "193541", + "durability": null, + "name": "Dagon'hai robes set", + "tradeable": "true", + "destroy": "false", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14526" + }, + { + "shop_price": "20", + "examine": "Grand Exchange set containing an elite black full helm, platebody and legs.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "6,0,13", + "destroy_message": "Drop", + "grand_exchange_price": "140536", + "name": "Elite black armour set", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14527", + "bonuses": "0,0,0,-38,-16,163,168,80,-3,159,62,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "20", + "examine": "Grand Exchange set containing an elite black full helm, platebody and legs.", + "grand_exchange_price": "140536", + "durability": null, + "name": "Elite black armour set", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14528" + }, + { + "shop_price": "20", + "examine": "Grand Exchange set containing a dragon full helm, platebody, legs.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "9,0,19", + "destroy_message": "Drop", + "grand_exchange_price": "10629814", + "name": "Dragon plate armour set (l)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14529", + "bonuses": "0,0,0,-57,-9,222,221,201,-11,217,82,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "20", + "examine": "Grand Exchange set containing a dragon full helm, platebody, legs.", + "grand_exchange_price": "10629814", + "durability": null, + "name": "Dragon plate armour set (l)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14530" + }, + { + "shop_price": "20", + "examine": "Grand Exchange set containing a dragon full helm, platebody, skirt.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "9,0,19", + "destroy_message": "Drop", + "grand_exchange_price": "12243786", + "name": "Dragon plate armour set (sk)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14531", + "bonuses": "0,0,0,-57,-9,222,221,201,-11,217,82,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "20", + "examine": "Grand Exchange set containing a dragon full helm, platebody, skirt.", + "grand_exchange_price": "12243786", + "durability": null, + "name": "Dragon plate armour set (sk)", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14532" + }, + { + "durability": null, + "name": "Broav", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14533", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You gained this orb from Dark Squall's base. You can probably get another one from visiting the same place.", + "examine": "This orb can used to teleport people...somehow.", + "durability": null, + "name": "Strange teleorb", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14534", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You will not be able to get the book back if you destroy it.", + "examine": "Notes on the locations of turkeys.", + "durability": null, + "name": "Turkey book", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14536", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You will lose all food stored in the Cornucopia. You can get another empty one from Diango in Draynor Village.", + "durability": null, + "name": "Cornucopia", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14537", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You will lose all food stored in the Cornucopia. You can get another empty one from Diango in Draynor Village.", + "durability": null, + "name": "Cornucopia", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14538", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "9", + "durability": null, + "name": "Raw turkey", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14539", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "4", + "examine": "Mmm, this looks tasty.", + "durability": null, + "name": "Cooked turkey", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14540", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "1", + "durability": null, + "name": "Burnt turkey", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14541", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "9", + "examine": "I need to cook this first.", + "durability": null, + "name": "Raw turkey drumstick", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14542", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "4", + "examine": "Mmm, this looks tasty.", + "durability": null, + "name": "Cooked turkey drumstick", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14543", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "1", + "durability": null, + "name": "Burnt turkey drumstick", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14544", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You will lose all food stored in the Cornucopia. You can get another empty one from Diango in Draynor Village.", + "durability": null, + "name": "Cornucopia", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14570", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "examine": "Not-so-sturdy boots for northern winters.", + "durability": null, + "name": "Fremennik sea boots 1", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14571", + "absorb": "0,0,0", + "bonuses": "0,0,0,-3,-1,2,3,4,0,0,0,0,0,0,0", + "equip_audio": "2237", + "equipment_slot": "10" + }, + { + "destroy_message": "You can claim replacement Fremennik sea boots from Yrsa in Rellekka.", + "examine": "Sturdy boots for northern winters.", + "durability": null, + "name": "Fremennik sea boots 2", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14572", + "absorb": "0,0,0", + "bonuses": "0,0,0,-3,-1,8,9,10,0,0,8,0,0,0,0", + "equip_audio": "2237", + "equipment_slot": "10" + }, + { + "examine": "Very sturdy boots for northern winters.", + "durability": null, + "name": "Fremennik sea boots 3", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14573", + "absorb": "0,0,0", + "bonuses": "0,0,0,-3,-1,10,11,12,0,0,9,1,0,0,0", + "equip_audio": "2237", + "equipment_slot": "10" + }, + { + "examine": "I wonder what happens if I rub it.", + "durability": null, + "name": "Antique lamp", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14574", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "examine": "I wonder what happens if I rub it.", + "durability": null, + "name": "Antique lamp", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14575", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "examine": "I wonder what happens if I rub it.", + "durability": null, + "name": "Antique lamp", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14576", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "100", + "examine": "A buckler shield from Falador.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equip_audio": "2245", + "equipment_slot": "5", + "destroy_message": "You will be able to get a replacement shield from Redbeard the Pirate in Port Sarim.", + "name": "Falador shield 1", + "archery_ticket_price": "0", + "id": "14577", + "bonuses": "0,0,0,-8,-2,17,19,18,-1,18,10,0,3,0,0" + }, + { + "shop_price": "200", + "examine": "A kiteshield from Falador.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equip_audio": "2245", + "equipment_slot": "5", + "destroy_message": "You will be able to get a replacement shield from the chemist in Rimmington.", + "name": "Falador shield 2", + "archery_ticket_price": "0", + "id": "14578", + "bonuses": "0,0,0,-8,-2,18,22,20,-1,20,20,0,5,0,0" + }, + { + "shop_price": "300", + "examine": "A tower shield from Falador.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "equip_audio": "2245", + "equipment_slot": "5", + "destroy_message": "You will be able to get a replacement shield from Sir Vyvin's squire in the White Knights' Castle.", + "name": "Falador shield 3", + "archery_ticket_price": "0", + "id": "14579", + "bonuses": "0,0,0,-8,-2,27,31,29,-1,29,30,0,7,0,0" + }, + { + "shop_price": "1000", + "examine": "I wonder what happens if I rub it.", + "durability": null, + "name": "Antique lamp", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14580", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "5000", + "examine": "I wonder what happens if I rub it.", + "durability": null, + "name": "Antique lamp", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14581", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "10000", + "examine": "I wonder what happens if I rub it.", + "durability": null, + "name": "Antique lamp", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14582", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Harvest (turns to ", + "examine": "A white lily seed - plant in a flower patch.", + "durability": null, + "name": "White lily", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14583", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You will not be able to replace this voucher - it is a one-time offer only!", + "shop_price": "500000", + "examine": "I can take this to the Herald to get my money crest back for free.", + "durability": null, + "name": "Money crest voucher", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14584", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "1250", + "examine": "A white lily seed - plant in a flower patch.", + "durability": null, + "name": "White lily seed", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14589", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "1000", + "examine": "This will teleport me to Rellekka when I play it.", + "durability": null, + "name": "Enchanted lyre(5)", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14590", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "3" + }, + { + "destroy_message": "Drop", + "shop_price": "1000", + "examine": "This will teleport me to Rellekka when I play it.", + "durability": null, + "name": "Enchanted lyre(6)", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14591", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "3" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "These look pretty heavy, but very elite.", + "grand_exchange_price": "41559", + "durability": null, + "name": "Elite black platelegs", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14592", + "absorb": "2,0,4", + "bonuses": "0,0,0,-14,-6,52,50,25,-1,49,15,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "Provides excellent protection, and is elite.", + "grand_exchange_price": "38275", + "durability": null, + "name": "Elite black platebody", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14593", + "absorb": "3,0,6", + "bonuses": "0,0,0,-20,-8,80,85,40,-2,80,40,0,0,0,0" + }, + { + "lendable": "true", + "destroy_message": "Drop", + "examine": "A full face helmet, and elite.", + "grand_exchange_price": "30542", + "durability": null, + "name": "Elite black full helm", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14594", + "absorb": "1,0,3", + "bonuses": "0,0,0,-4,-2,31,33,15,0,30,7,0,0,0,0" + }, + { + "destroy_message": "You can get another from Diango in Draynor Village.", + "remove_sleeves": "true", + "examine": "A red and jolly top.", + "durability": null, + "name": "Santa costume top", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14595", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "4" + }, + { + "examine": "A spikey amulet made of ice crystals. It has been enchanted so it will not melt.", + "durability": null, + "name": "Ice amulet", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14596", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "2" + }, + { + "destroy_message": "You can probably get more in the last room of the yeti cave, in the Land of Snow.", + "shop_price": "1", + "durability": null, + "name": "Stones", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14597", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You will have to fetch more in the last room of the yeti cave, then get them enchanted by snow imps.", + "shop_price": "1", + "examine": "According to the snow imps, this is enchanted, frozen yeti dung.", + "durability": null, + "name": "Enchanted stones", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14598", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "examine": "A spikey amulet made of ice crystals. It has been enchanted so it will not melt.", + "durability": null, + "name": "Ice amulet", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14599", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "2" + }, + { + "destroy_message": "You can get another from Diango in Draynor Village.", + "remove_sleeves": "true", + "examine": "A red and jolly top.", + "durability": null, + "name": "Santa costume top", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14600", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "4" + }, + { + "destroy_message": "You can get another from Diango in Draynor Village.", + "remove_sleeves": "true", + "examine": "A red and jolly top.", + "durability": null, + "name": "Santa costume top", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14601", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "4" + }, + { + "destroy_message": "You can get another pair from Diango in Draynor Village.", + "examine": "Some black and jolly gloves.", + "durability": null, + "name": "Santa costume gloves", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14602", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "9" + }, + { + "destroy_message": "You can get another from Diango in Draynor Village.", + "examine": "Some red and jolly legs.", + "durability": null, + "name": "Santa costume legs", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14603", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "destroy_message": "You can get another from Diango in Draynor Village.", + "examine": "Some red and jolly legs.", + "durability": null, + "name": "Santa costume legs", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14604", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "7" + }, + { + "destroy_message": "You can get another pair from Diango in Draynor Village.", + "examine": "Some black and jolly boots.", + "durability": null, + "name": "Santa costume boots", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14605", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "10" + }, + { + "destroy_message": "You harvested these from a tree in the phoenix's lair. You need one to complete the dungeon.", + "examine": "Aromatic twigs from a cinnamon tree.", + "durability": null, + "name": "Cinnamon twigs", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14606", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You harvested these from a tree in the phoenix's lair. You need one to complete the dungeon.", + "examine": "Aromatic twigs from a sassafras tree.", + "durability": null, + "name": "Sassafras twigs", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14607", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You harvested these from a tree in the phoenix's lair. You need one to complete the dungeon.", + "examine": "Aromatic twigs from a ailanthus tree.", + "durability": null, + "name": "Ailanthus twigs", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14608", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You harvested these from a tree in the phoenix's lair. You need one to complete the dungeon.", + "examine": "Aromatic twigs from a cedar tree.", + "durability": null, + "name": "Cedar twigs", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14609", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You harvested these from a tree in the phoenix's lair. You need one to complete the dungeon.", + "examine": "Aromatic twigs from a mastic tree.", + "durability": null, + "name": "Mastic twigs", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14610", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You fletched this from twigs found in the phoenix's lair. You need one to complete the dungeon.", + "examine": "Cinnamon twigs, fletched into ribbons of wood and ready to be woven.", + "durability": null, + "name": "Cinnamon weaving ribbon", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14611", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You fletched this from twigs found in the phoenix's lair. You need one to complete the dungeon.", + "examine": "Sassafras twigs, fletched into ribbons of wood and ready to be woven.", + "durability": null, + "name": "Sassafras weaving ribbon", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14612", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You fletched this from twigs found in the phoenix's lair. You need one to complete the dungeon.", + "examine": "Ailanthus twigs, fletched into ribbons of wood and ready to be woven.", + "durability": null, + "name": "Ailanthus weaving ribbon", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14613", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You fletched this from twigs found in the phoenix's lair. You need one to complete the dungeon.", + "examine": "Cedar twigs, fletched into ribbons of wood and ready to be woven.", + "durability": null, + "name": "Cedar weaving ribbon", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14614", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "You fletched this from twigs found in the phoenix's lair. You need one to complete the dungeon.", + "examine": "Mastic twigs, fletched into ribbons of wood and ready to be woven.", + "durability": null, + "name": "Mastic weaving ribbon", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14615", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "100", + "examine": "A feather from a phoenix. Used in Summoning (72).", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "destroy_message": "Drop", + "grand_exchange_price": "3431", + "name": "Phoenix quill", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14616", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Drop", + "shop_price": "100", + "examine": "A feather from a phoenix. Used in Summoning (72).", + "grand_exchange_price": "3431", + "durability": null, + "name": "Phoenix quill", + "tradeable": "true", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14617" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14620", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "durability": null, + "name": "Pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14621" + }, + { + "requirements": "{23,72}", + "shop_price": "498", + "examine": "A scroll for a phoenix familiar.", + "durability": null, + "name": "Rise from the ashes scroll", + "tradeable": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14622", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "4986", + "durability": null, + "name": "Phoenix pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14623", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "shop_price": "4986", + "durability": null, + "name": "Phoenix pouch", + "tradeable": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14624" + }, + { + "durability": null, + "name": "Pouch", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14625", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "examine": "A baby phoenix and it's bad to the bone!", + "durability": null, + "name": "Phoenix eggling", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14626", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "examine": "A baby phoenix and it's bad to the bone!", + "durability": null, + "name": "Phoenix eggling", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14627", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Unknown ", + "examine": "I found this egg in the Phoenix's Lair, and clapped at it!", + "durability": null, + "name": "Phoenix egg", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14629", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "Unknown ", + "examine": "I found this egg in the Phoenix's Lair, and kicked it!", + "durability": null, + "name": "Cracked phoenix egg", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14630", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "destroy_message": "A player can get a new one by talking to any seer around Seer's village.", + "examine": "A headband with an eye embroidered on it.", + "durability": null, + "name": "Seer's headband", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14631", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,3,0,0,0,0,0,0", + "equipment_slot": "0" + }, + { + "turn90cw_anim": "821", + "examine": "This used to belong to King Arthur and has since been improved.", + "walk_anim": "819", + "has_special": "true", + "turn90ccw_anim": "822", + "attack_speed": "5", + "turn180_anim": "820", + "absorb": "0,0,0", + "defence_anim": "397", + "equipment_slot": "3", + "attack_anims": "390,390,381,390", + "destroy_message": "You can retrieve the Enhanced Excalibur from the Lady of the Lake for 500 coins.", + "stand_anim": "808", + "run_anim": "824", + "archery_ticket_price": "0", + "id": "14632", + "stand_turn_anim": "823", + "bonuses": "38,47,-2,0,0,0,3,2,1,0,0,45,0,0,0", + "requirements": "{0,30}", + "shop_price": "200", + "durability": null, + "destroy": "true", + "weapon_interface": "6", + "render_anim": "1", + "attack_audios": "2500,2500,2517,2500", + "name": "Enhanced excalibur" + }, + { + "examine": "I wonder what happens if I rub it.", + "durability": null, + "name": "Antique lamp", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14633", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "examine": "I wonder what happens if I rub it.", + "durability": null, + "name": "Antique lamp", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14634", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "examine": "I wonder what happens if I rub it.", + "durability": null, + "name": "Antique lamp", + "tradeable": "false", + "destroy": "true", + "archery_ticket_price": "0", + "attack_speed": "4", + "id": "14635", + "absorb": "0,0,0", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "remove_head": "true", + "shop_price": "650", + "examine": "You don't want to wear it inside-out.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "remove_beard": "true", + "equipment_slot": "0", + "destroy_message": "Drop", + "name": "Slayer helmet (e)", + "archery_ticket_price": "0", + "id": "14636", + "bonuses": "0,0,0,0,0,30,32,27,0,30,7,0,0,0,0" + }, + { + "remove_head": "true", + "shop_price": "650", + "examine": "You don't want to wear it inside-out.", + "durability": null, + "destroy": "true", + "attack_speed": "4", + "absorb": "0,0,0", + "remove_beard": "true", + "equipment_slot": "0", + "destroy_message": "Drop", + "name": "Slayer helmet (charged)", + "archery_ticket_price": "0", + "id": "14637", + "bonuses": "0,0,0,0,0,30,32,27,0,30,7,0,0,0,0" + }, + { + "ge_buy_limit": "100", + "examine": "It can be charged at the Fountain of Rune.", + "grand_exchange_price": "26000", + "durability": null, + "name": "Ring of wealth", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14638", + "equipment_slot": "12" + }, + { + "ge_buy_limit": "100", + "examine": "It can be charged at the Fountain of Rune.", + "grand_exchange_price": "29800", + "durability": null, + "name": "Ring of wealth", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14639" + }, + { + "ge_buy_limit": "100", + "examine": "An enchanted ring with one teleport charge.", + "grand_exchange_price": "27000", + "durability": null, + "name": "Ring of wealth(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14640", + "equipment_slot": "12" + }, + { + "ge_buy_limit": "100", + "examine": "An enchanted ring with one teleport charge.", + "grand_exchange_price": "29800", + "durability": null, + "name": "Ring of wealth(1)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14641" + }, + { + "ge_buy_limit": "100", + "examine": "An enchanted ring with two teleport charges.", + "grand_exchange_price": "28000", + "durability": null, + "name": "Ring of wealth(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14642", + "equipment_slot": "12" + }, + { + "ge_buy_limit": "100", + "examine": "An enchanted ring with two teleport charges.", + "grand_exchange_price": "29800", + "durability": null, + "name": "Ring of wealth(2)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14643" + }, + { + "ge_buy_limit": "100", + "examine": "An enchanted ring with three teleport charges.", + "grand_exchange_price": "30000", + "durability": null, + "name": "Ring of wealth(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14644", + "equipment_slot": "12" + }, + { + "ge_buy_limit": "100", + "examine": "An enchanted ring with three teleport charges.", + "grand_exchange_price": "29800", + "durability": null, + "name": "Ring of wealth(3)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14645" + }, + { + "ge_buy_limit": "100", + "examine": "An enchanted ring with four teleport charges.", + "grand_exchange_price": "35000", + "durability": null, + "name": "Ring of wealth(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14646", + "equipment_slot": "12" + }, + { + "ge_buy_limit": "100", + "examine": "An enchanted ring with four teleport charges.", + "grand_exchange_price": "29800", + "durability": null, + "name": "Ring of wealth(4)", + "tradeable": "true", + "archery_ticket_price": "0", + "id": "14647" + }, + { + "shop_price": "0", + "ge_buy_limit": "0", + "examine": "A totally alive monkey friend for your back!", + "durability": null, + "destroy": "true", + "weight": "0.0", + "equipment_slot": "1", + "grand_exchange_price": "0", + "name": "Jangles the Monkey Backpack", + "tradeable": "false", + "archery_ticket_price": "0", + "id": "14648", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" + }, + { + "ge_buy_limit": "0", + "examine": "A ring for only the truest of cave goblins. And Logg too.", + "grand_exchange_price": "0", + "durability": null, + "name": "Zanik ring", + "tradeable": "false", + "archery_ticket_price": "0", + "destroy": "true", + "id": "14649", + "equipment_slot": "12" + }, + { + "ge_buy_limit": "0", + "examine": "A standard issue wizard hat.", + "durability": null, + "weight": "0.1", + "destroy": "true", + "equipment_slot": "0", + "grand_exchange_price": "0", + "name": "Wizard hat", + "tradeable": "false", + "archery_ticket_price": "0", + "hat": "true", + "id": "14650", + "bonuses": "0,0,0,2,0,0,0,0,2,0,0,0,0,0,0" + }, + { + "destroy_message": " WARNING: You will have to reobtain this item the hard way.", + "examine": "Mysterious blueprints written in an alien language.", + "durability": null, + "name": "Ancient Blueprints", + "destroy": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "14651" + }, + { + "destroy_message": "You can get another by bringing the materials along with the blueprint to a Star Sprite.", + "examine": "A stardust-infused dragonstone ring.", + "durability": null, + "name": "Ring of the Star Sprite", + "destroy": "true", + "weight": "0.1", + "archery_ticket_price": "0", + "id": "14652", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "equipment_slot": "12" + }, + { + "examine": "A chunk of rock.", + "name": "Rock", + "id": "1480" + }, + { + "turn90cw_anim": "1207", + "examine": "A staff with a spooky raven head attached.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "turn180_anim": "1206", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "stand_anim": "813", + "tradeable": "false", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "14654", + "stand_turn_anim": "1209", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "shop_price": "200", + "durability": null, + "destroy": "true", + "weight": "2.2", + "weapon_interface": "1", + "equip_audio": "2247", + "render_anim": "28", + "attack_audios": "2555,0,0,0", + "name": "Staff of the raven" + }, + { + "turn90cw_anim": "1207", + "examine": "A staff with a spooky raven head attached.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "turn180_anim": "1206", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "stand_anim": "813", + "tradeable": "false", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "14655", + "stand_turn_anim": "1209", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "shop_price": "200", + "durability": null, + "destroy": "true", + "weight": "2.2", + "weapon_interface": "1", + "equip_audio": "2247", + "render_anim": "28", + "attack_audios": "2555,0,0,0", + "name": "Staff of the raven" + }, + { + "turn90cw_anim": "1207", + "examine": "A staff with a spooky raven head attached.", + "walk_anim": "1205", + "turn90ccw_anim": "1208", + "attack_speed": "5", + "turn180_anim": "1206", + "defence_anim": "420", + "equipment_slot": "3", + "attack_anims": "419,419,419,419", + "stand_anim": "813", + "tradeable": "false", + "run_anim": "1210", + "archery_ticket_price": "0", + "id": "14656", + "stand_turn_anim": "1209", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "shop_price": "200", + "durability": null, + "destroy": "true", + "weight": "2.2", + "weapon_interface": "1", + "equip_audio": "2247", + "render_anim": "28", + "attack_audios": "2555,0,0,0", + "name": "Staff of the raven" + }, + { + "examine": "Item container for C. Ele Minor Drop Table. You should not be able to obtain this item.", + "name": "C. Ele Minor Drop Table", + "id": "799" + }, + { + "examine": "This will unlock something. (Waterfall Quest)", + "name": "A key", + "tradeable": "false", + "weight": "0.01", + "archery_ticket_price": "0", + "id": "293" + }, + { + "examine": "This will unlock something. (Waterfall dungeon)", + "name": "A key", + "tradeable": "false", + "archery_ticket_price": "0", + "weight": "0.01", + "id": "298" + }, + { + "examine": "You should not have this.", + "name": "USDT Slot", + "id": "14422" + }, + { + "examine": "You should not have this.", + "name": "HDT Slot", + "id": "14424" + }, + { + "examine": "You should not have this.", + "name": "GDT Slot", + "id": "14426" + }, + { + "examine": "You should not have this.", + "name": "RSDT Slot", + "id": "14428" + }, + { + "examine": "You should not have this.", + "name": "ASDT Slot", + "id": "14430" + }, + { + "destroy_message": "This item can not be reclaimed.", + "shop_price": "1", + "examine": "A rabbit-like adornment, back in black!", + "name": "Bunny ears", + "tradeable": "false", + "destroy": "true", + "weight": "0.2", + "archery_ticket_price": "0", + "id": "14658", + "equipment_slot": "0" + }, + { + "examine": "Emperor of all he surveys.", + "name": "Penguin", + "id": "12482" + }, + { + "examine": "Emperor of all he surveys.", + "name": "Penguin", + "id": "12762" + }, + { + "examine": "Emperor of all he surveys.", + "name": "Penguin", + "id": "12764" + } +] \ No newline at end of file diff --git a/Server/data/configs/music_regions.json b/Server/data/configs/music_regions.json new file mode 100644 index 0000000..ebfb70c --- /dev/null +++ b/Server/data/configs/music_regions.json @@ -0,0 +1,2566 @@ +[ + { + "region": "6234", + "id": "67" + }, + { + "region": "6473", + "id": "487" + }, + { + "region": "6475", + "id": "432" + }, + { + "region": "6486", + "id": "588" + }, + { + "region": "6487", + "id": "503" + }, + { + "region": "6488", + "id": "507" + }, + { + "region": "6489", + "id": "507" + }, + { + "region": "6722", + "id": "74" + }, + { + "region": "6726", + "id": "205" + }, + { + "region": "6741", + "id": "561" + }, + { + "region": "6744", + "id": "507" + }, + { + "region": "6745", + "id": "507" + }, + { + "region": "6989", + "id": "309" + }, + { + "region": "6992", + "id": "573" + }, + { + "region": "6993", + "id": "573" + }, + { + "region": "6994", + "id": "367" + }, + { + "region": "7236", + "id": "198" + }, + { + "region": "7490", + "id": "374" + }, + { + "region": "7492", + "id": "524" + }, + { + "region": "7494", + "id": "470" + }, + { + "region": "7496", + "id": "376" + }, + { + "region": "7499", + "id": "38" + }, + { + "region": "7500", + "id": "203" + }, + { + "region": "7502", + "id": "371" + }, + { + "region": "7504", + "id": "612" + }, + { + "region": "7505", + "id": "537" + }, + { + "region": "7507", + "id": "583" + }, + { + "region": "7508", + "id": "211" + }, + { + "region": "7509", + "id": "604" + }, + { + "region": "7748", + "id": "198" + }, + { + "region": "7749", + "id": "591" + }, + { + "region": "7752", + "id": "375" + }, + { + "region": "7753", + "id": "489" + }, + { + "region": "7754", + "id": "413" + }, + { + "region": "7755", + "id": "51" + }, + { + "region": "7756", + "id": "620" + }, + { + "region": "7757", + "id": "434" + }, + { + "region": "7758", + "id": "324" + }, + { + "region": "7760", + "id": "202" + }, + { + "region": "7769", + "id": "578" + }, + { + "region": "8001", + "id": "426" + }, + { + "region": "8002", + "id": "426" + }, + { + "region": "8004", + "id": "579" + }, + { + "region": "8005", + "id": "532" + }, + { + "region": "8009", + "id": "271" + }, + { + "region": "8010", + "id": "247" + }, + { + "region": "8013", + "id": "620" + }, + { + "region": "8014", + "id": "244" + }, + { + "region": "8015", + "id": "640" + }, + { + "region": "8017", + "id": "558" + }, + { + "region": "8022", + "id": "421" + }, + { + "region": "8025", + "id": "595" + }, + { + "region": "8252", + "id": "625" + }, + { + "region": "8253", + "id": "625" + }, + { + "region": "8261", + "id": "511" + }, + { + "region": "8267", + "id": "126" + }, + { + "region": "8276", + "id": "303" + }, + { + "region": "8280", + "id": "527" + }, + { + "region": "8282", + "id": "592" + }, + { + "region": "8496", + "id": "91" + }, + { + "region": "8497", + "id": "254" + }, + { + "region": "8498", + "id": "255" + }, + { + "region": "8499", + "id": "268" + }, + { + "region": "8508", + "id": "627" + }, + { + "region": "8509", + "id": "627" + }, + { + "region": "8519", + "id": "1" + }, + { + "region": "8523", + "id": "243" + }, + { + "region": "8526", + "id": "286" + }, + { + "region": "8527", + "id": "497" + }, + { + "region": "8528", + "id": "498" + }, + { + "region": "8529", + "id": "559" + }, + { + "region": "8530", + "id": "559" + }, + { + "region": "8534", + "id": "23" + }, + { + "region": "8752", + "id": "270" + }, + { + "region": "8763", + "id": "630" + }, + { + "region": "8770", + "id": "433" + }, + { + "region": "8779", + "id": "134" + }, + { + "region": "8781", + "id": "269" + }, + { + "region": "8782", + "id": "241" + }, + { + "region": "8787", + "id": "456" + }, + { + "region": "9008", + "id": "253" + }, + { + "region": "9009", + "id": "251" + }, + { + "region": "9010", + "id": "132" + }, + { + "region": "9011", + "id": "259" + }, + { + "region": "9014", + "id": "366" + }, + { + "region": "9015", + "id": "460" + }, + { + "region": "9033", + "id": "28" + }, + { + "region": "9034", + "id": "97" + }, + { + "region": "9035", + "id": "142" + }, + { + "region": "9038", + "id": "245" + }, + { + "region": "9046", + "id": "150" + }, + { + "region": "9263", + "id": "390" + }, + { + "region": "9265", + "id": "372" + }, + { + "region": "9266", + "id": "252" + }, + { + "region": "9267", + "id": "256" + }, + { + "region": "9268", + "id": "130" + }, + { + "region": "9269", + "id": "101" + }, + { + "region": "9270", + "id": "112" + }, + { + "region": "9272", + "id": "544" + }, + { + "region": "9273", + "id": "544" + }, + { + "region": "9275", + "id": "225" + }, + { + "region": "9276", + "id": "220" + }, + { + "region": "9285", + "id": "73" + }, + { + "region": "9293", + "id": "373" + }, + { + "region": "9294", + "id": "84" + }, + { + "region": "9295", + "id": "201" + }, + { + "region": "9297", + "id": "560" + }, + { + "region": "9362", + "id": "153" + }, + { + "region": "9365", + "id": "271" + }, + { + "region": "9366", + "id": "271" + }, + { + "region": "9369", + "id": "95" + }, + { + "region": "9372", + "id": "456" + }, + { + "region": "9520", + "id": "314" + }, + { + "region": "9521", + "id": "110" + }, + { + "region": "9522", + "id": "41" + }, + { + "region": "9523", + "id": "10" + }, + { + "region": "9526", + "id": "112" + }, + { + "region": "9531", + "id": "223" + }, + { + "region": "9532", + "id": "220" + }, + { + "region": "9540", + "id": "118" + }, + { + "region": "9541", + "id": "118" + }, + { + "region": "9544", + "id": "197" + }, + { + "region": "9545", + "id": "30" + }, + { + "region": "9547", + "id": "131" + }, + { + "region": "9550", + "id": "84" + }, + { + "region": "9551", + "id": "473" + }, + { + "region": "9552", + "id": "463" + }, + { + "region": "9553", + "id": "531" + }, + { + "region": "9558", + "id": "276" + }, + { + "region": "9620", + "id": "318" + }, + { + "region": "9621", + "id": "323" + }, + { + "region": "9623", + "id": "59" + }, + { + "region": "9625", + "id": "194" + }, + { + "region": "9626", + "id": "296" + }, + { + "region": "9631", + "id": "222" + }, + { + "region": "9632", + "id": "224" + }, + { + "region": "9774", + "id": "80" + }, + { + "region": "9775", + "id": "392" + }, + { + "region": "9776", + "id": "317" + }, + { + "region": "9778", + "id": "41" + }, + { + "region": "9780", + "id": "155" + }, + { + "region": "9781", + "id": "33" + }, + { + "region": "9782", + "id": "22" + }, + { + "region": "9787", + "id": "225" + }, + { + "region": "9794", + "id": "439" + }, + { + "region": "9796", + "id": "575" + }, + { + "region": "9797", + "id": "181" + }, + { + "region": "9802", + "id": "409" + }, + { + "region": "9803", + "id": "262" + }, + { + "region": "9804", + "id": "512" + }, + { + "region": "9805", + "id": "425" + }, + { + "region": "9808", + "id": "469" + }, + { + "region": "9810", + "id": "603" + }, + { + "region": "9812", + "id": "279" + }, + { + "region": "9814", + "id": "275" + }, + { + "region": "9874", + "id": "394" + }, + { + "region": "9875", + "id": "394" + }, + { + "region": "9878", + "id": "41" + }, + { + "region": "9879", + "id": "59" + }, + { + "region": "9882", + "id": "348" + }, + { + "region": "9886", + "id": "448" + }, + { + "region": "10031", + "id": "159" + }, + { + "region": "10032", + "id": "83" + }, + { + "region": "10033", + "id": "148" + }, + { + "region": "10034", + "id": "24" + }, + { + "region": "10035", + "id": "5" + }, + { + "region": "10036", + "id": "328" + }, + { + "region": "10037", + "id": "82" + }, + { + "region": "10038", + "id": "32" + }, + { + "region": "10039", + "id": "66" + }, + { + "region": "10040", + "id": "320" + }, + { + "region": "10042", + "id": "461" + }, + { + "region": "10043", + "id": "225" + }, + { + "region": "10044", + "id": "284" + }, + { + "region": "10055", + "id": "129" + }, + { + "region": "10056", + "id": "322" + }, + { + "region": "10057", + "id": "13" + }, + { + "region": "10058", + "id": "411" + }, + { + "region": "10059", + "id": "190" + }, + { + "region": "10061", + "id": "370" + }, + { + "region": "10074", + "id": "589" + }, + { + "region": "10075", + "id": "589" + }, + { + "region": "10129", + "id": "453" + }, + { + "region": "10131", + "id": "159" + }, + { + "region": "10133", + "id": "148" + }, + { + "region": "10134", + "id": "102" + }, + { + "region": "10135", + "id": "478" + }, + { + "region": "10136", + "id": "133" + }, + { + "region": "10137", + "id": "82" + }, + { + "region": "10138", + "id": "109" + }, + { + "region": "10139", + "id": "66" + }, + { + "region": "10140", + "id": "322" + }, + { + "region": "10142", + "id": "517" + }, + { + "region": "10144", + "id": "506" + }, + { + "region": "10284", + "id": "474" + }, + { + "region": "10286", + "id": "128" + }, + { + "region": "10287", + "id": "188" + }, + { + "region": "10288", + "id": "185" + }, + { + "region": "10289", + "id": "27" + }, + { + "region": "10290", + "id": "152" + }, + { + "region": "10291", + "id": "191" + }, + { + "region": "10292", + "id": "133" + }, + { + "region": "10293", + "id": "193" + }, + { + "region": "10294", + "id": "109" + }, + { + "region": "10296", + "id": "290" + }, + { + "region": "10297", + "id": "289" + }, + { + "region": "10298", + "id": "289" + }, + { + "region": "10299", + "id": "225" + }, + { + "region": "10300", + "id": "285" + }, + { + "region": "10307", + "id": "349" + }, + { + "region": "10309", + "id": "148" + }, + { + "region": "10310", + "id": "296" + }, + { + "region": "10311", + "id": "308" + }, + { + "region": "10314", + "id": "419" + }, + { + "region": "10315", + "id": "158" + }, + { + "region": "10321", + "id": "638" + }, + { + "region": "10322", + "id": "66" + }, + { + "region": "10330", + "id": "589" + }, + { + "region": "10387", + "id": "29" + }, + { + "region": "10388", + "id": "68" + }, + { + "region": "10389", + "id": "27" + }, + { + "region": "10390", + "id": "102" + }, + { + "region": "10393", + "id": "346" + }, + { + "region": "10394", + "id": "109" + }, + { + "region": "10536", + "id": "588" + }, + { + "region": "10537", + "id": "587" + }, + { + "region": "10542", + "id": "71" + }, + { + "region": "10544", + "id": "161" + }, + { + "region": "10545", + "id": "167" + }, + { + "region": "10546", + "id": "70" + }, + { + "region": "10547", + "id": "99" + }, + { + "region": "10548", + "id": "81" + }, + { + "region": "10549", + "id": "60" + }, + { + "region": "10550", + "id": "140" + }, + { + "region": "10551", + "id": "20" + }, + { + "region": "10552", + "id": "290" + }, + { + "region": "10553", + "id": "289" + }, + { + "region": "10554", + "id": "289" + }, + { + "region": "10555", + "id": "225" + }, + { + "region": "10558", + "id": "217" + }, + { + "region": "10569", + "id": "107" + }, + { + "region": "10571", + "id": "143" + }, + { + "region": "10575", + "id": "393" + }, + { + "region": "10577", + "id": "568" + }, + { + "region": "10642", + "id": "71" + }, + { + "region": "10644", + "id": "363" + }, + { + "region": "10645", + "id": "363" + }, + { + "region": "10646", + "id": "481" + }, + { + "region": "10647", + "id": "169" + }, + { + "region": "10648", + "id": "63" + }, + { + "region": "10649", + "id": "63" + }, + { + "region": "10650", + "id": "63" + }, + { + "region": "10652", + "id": "316" + }, + { + "region": "10653", + "id": "295" + }, + { + "region": "10794", + "id": "306" + }, + { + "region": "10795", + "id": "305" + }, + { + "region": "10801", + "id": "164" + }, + { + "region": "10802", + "id": "115" + }, + { + "region": "10803", + "id": "91" + }, + { + "region": "10804", + "id": "192" + }, + { + "region": "10805", + "id": "184" + }, + { + "region": "10806", + "id": "7" + }, + { + "region": "10807", + "id": "21" + }, + { + "region": "10808", + "id": "293" + }, + { + "region": "10809", + "id": "291" + }, + { + "region": "10810", + "id": "291" + }, + { + "region": "10811", + "id": "291" + }, + { + "region": "10820", + "id": "563" + }, + { + "region": "10821", + "id": "282" + }, + { + "region": "10822", + "id": "278" + }, + { + "region": "10823", + "id": "278" + }, + { + "region": "10827", + "id": "146" + }, + { + "region": "10828", + "id": "378" + }, + { + "region": "10829", + "id": "378" + }, + { + "region": "10833", + "id": "249" + }, + { + "region": "10834", + "id": "240" + }, + { + "region": "10838", + "id": "442" + }, + { + "region": "10839", + "id": "442" + }, + { + "region": "10840", + "id": "444" + }, + { + "region": "10841", + "id": "444" + }, + { + "region": "10842", + "id": "444" + }, + { + "region": "10894", + "id": "312" + }, + { + "region": "10895", + "id": "311" + }, + { + "region": "10899", + "id": "362" + }, + { + "region": "10900", + "id": "362" + }, + { + "region": "10901", + "id": "364" + }, + { + "region": "10903", + "id": "17" + }, + { + "region": "10904", + "id": "192" + }, + { + "region": "10905", + "id": "63" + }, + { + "region": "10906", + "id": "88" + }, + { + "region": "10907", + "id": "340" + }, + { + "region": "10908", + "id": "340" + }, + { + "region": "10910", + "id": "274" + }, + { + "region": "10911", + "id": "548" + }, + { + "region": "11051", + "id": "303" + }, + { + "region": "11053", + "id": "129" + }, + { + "region": "11054", + "id": "114" + }, + { + "region": "11055", + "id": "117" + }, + { + "region": "11056", + "id": "58" + }, + { + "region": "11057", + "id": "55" + }, + { + "region": "11058", + "id": "6" + }, + { + "region": "11059", + "id": "347" + }, + { + "region": "11060", + "id": "324" + }, + { + "region": "11061", + "id": "74" + }, + { + "region": "11062", + "id": "104" + }, + { + "region": "11065", + "id": "356" + }, + { + "region": "11066", + "id": "4" + }, + { + "region": "11068", + "id": "335" + }, + { + "region": "11077", + "id": "277" + }, + { + "region": "11078", + "id": "282" + }, + { + "region": "11081", + "id": "5" + }, + { + "region": "11083", + "id": "65" + }, + { + "region": "11084", + "id": "378" + }, + { + "region": "11085", + "id": "378" + }, + { + "region": "11096", + "id": "444" + }, + { + "region": "11097", + "id": "444" + }, + { + "region": "11098", + "id": "444" + }, + { + "region": "11151", + "id": "307" + }, + { + "region": "11153", + "id": "265" + }, + { + "region": "11154", + "id": "114" + }, + { + "region": "11157", + "id": "248" + }, + { + "region": "11161", + "id": "19" + }, + { + "region": "11164", + "id": "341" + }, + { + "region": "11165", + "id": "357" + }, + { + "region": "11166", + "id": "261" + }, + { + "region": "11309", + "id": "172" + }, + { + "region": "11310", + "id": "90" + }, + { + "region": "11311", + "id": "165" + }, + { + "region": "11312", + "id": "162" + }, + { + "region": "11313", + "id": "172" + }, + { + "region": "11314", + "id": "170" + }, + { + "region": "11317", + "id": "119" + }, + { + "region": "11318", + "id": "87" + }, + { + "region": "11319", + "id": "9" + }, + { + "region": "11320", + "id": "187" + }, + { + "region": "11321", + "id": "257" + }, + { + "region": "11322", + "id": "292" + }, + { + "region": "11323", + "id": "294" + }, + { + "region": "11324", + "id": "569" + }, + { + "region": "11331", + "id": "553" + }, + { + "region": "11332", + "id": "564" + }, + { + "region": "11335", + "id": "504" + }, + { + "region": "11339", + "id": "52" + }, + { + "region": "11343", + "id": "491" + }, + { + "region": "11352", + "id": "444" + }, + { + "region": "11353", + "id": "444" + }, + { + "region": "11354", + "id": "444" + }, + { + "region": "11356", + "id": "442" + }, + { + "region": "11408", + "id": "365" + }, + { + "region": "11410", + "id": "90" + }, + { + "region": "11412", + "id": "162" + }, + { + "region": "11413", + "id": "336" + }, + { + "region": "11414", + "id": "25" + }, + { + "region": "11416", + "id": "179" + }, + { + "region": "11417", + "id": "19" + }, + { + "region": "11418", + "id": "100" + }, + { + "region": "11419", + "id": "100" + }, + { + "region": "11421", + "id": "261" + }, + { + "region": "11422", + "id": "369" + }, + { + "region": "11423", + "id": "396" + }, + { + "region": "11562", + "id": "304" + }, + { + "region": "11565", + "id": "78" + }, + { + "region": "11566", + "id": "94" + }, + { + "region": "11567", + "id": "89" + }, + { + "region": "11568", + "id": "479" + }, + { + "region": "11569", + "id": "92" + }, + { + "region": "11570", + "id": "138" + }, + { + "region": "11571", + "id": "107" + }, + { + "region": "11572", + "id": "186" + }, + { + "region": "11573", + "id": "18" + }, + { + "region": "11574", + "id": "77" + }, + { + "region": "11575", + "id": "149" + }, + { + "region": "11576", + "id": "258" + }, + { + "region": "11578", + "id": "292" + }, + { + "region": "11587", + "id": "564" + }, + { + "region": "11588", + "id": "564" + }, + { + "region": "11589", + "id": "524" + }, + { + "region": "11591", + "id": "242" + }, + { + "region": "11595", + "id": "57" + }, + { + "region": "11599", + "id": "482" + }, + { + "region": "11605", + "id": "232" + }, + { + "region": "11606", + "id": "442" + }, + { + "region": "11608", + "id": "442" + }, + { + "region": "11612", + "id": "442" + }, + { + "region": "11665", + "id": "30" + }, + { + "region": "11666", + "id": "103" + }, + { + "region": "11668", + "id": "129" + }, + { + "region": "11670", + "id": "138" + }, + { + "region": "11671", + "id": "53" + }, + { + "region": "11672", + "id": "173" + }, + { + "region": "11673", + "id": "178" + }, + { + "region": "11676", + "id": "153" + }, + { + "region": "11677", + "id": "264" + }, + { + "region": "11678", + "id": "395" + }, + { + "region": "11821", + "id": "162" + }, + { + "region": "11823", + "id": "166" + }, + { + "region": "11824", + "id": "515" + }, + { + "region": "11825", + "id": "180" + }, + { + "region": "11826", + "id": "12" + }, + { + "region": "11827", + "id": "127" + }, + { + "region": "11828", + "id": "72" + }, + { + "region": "11829", + "id": "54" + }, + { + "region": "11831", + "id": "34" + }, + { + "region": "11832", + "id": "435" + }, + { + "region": "11833", + "id": "183" + }, + { + "region": "11834", + "id": "43" + }, + { + "region": "11835", + "id": "37" + }, + { + "region": "11837", + "id": "52" + }, + { + "region": "11853", + "id": "402" + }, + { + "region": "11864", + "id": "443" + }, + { + "region": "11865", + "id": "443" + }, + { + "region": "11866", + "id": "443" + }, + { + "region": "11924", + "id": "576" + }, + { + "region": "11925", + "id": "108" + }, + { + "region": "11926", + "id": "490" + }, + { + "region": "11929", + "id": "325" + }, + { + "region": "11930", + "id": "582" + }, + { + "region": "11936", + "id": "52" + }, + { + "region": "11937", + "id": "52" + }, + { + "region": "12078", + "id": "549" + }, + { + "region": "12079", + "id": "62" + }, + { + "region": "12080", + "id": "62" + }, + { + "region": "12081", + "id": "105" + }, + { + "region": "12082", + "id": "35" + }, + { + "region": "12083", + "id": "49" + }, + { + "region": "12084", + "id": "15" + }, + { + "region": "12085", + "id": "310" + }, + { + "region": "12086", + "id": "102" + }, + { + "region": "12087", + "id": "96" + }, + { + "region": "12088", + "id": "160" + }, + { + "region": "12089", + "id": "66" + }, + { + "region": "12090", + "id": "159" + }, + { + "region": "12091", + "id": "42" + }, + { + "region": "12092", + "id": "475" + }, + { + "region": "12093", + "id": "334" + }, + { + "region": "12100", + "id": "236" + }, + { + "region": "12102", + "id": "633" + }, + { + "region": "12105", + "id": "505" + }, + { + "region": "12107", + "id": "412" + }, + { + "region": "12108", + "id": "412" + }, + { + "region": "12109", + "id": "402" + }, + { + "region": "12111", + "id": "403" + }, + { + "region": "12115", + "id": "86" + }, + { + "region": "12117", + "id": "304" + }, + { + "region": "12120", + "id": "443" + }, + { + "region": "12121", + "id": "443" + }, + { + "region": "12122", + "id": "443" + }, + { + "region": "12181", + "id": "529" + }, + { + "region": "12184", + "id": "325" + }, + { + "region": "12186", + "id": "570" + }, + { + "region": "12187", + "id": "585" + }, + { + "region": "12192", + "id": "26" + }, + { + "region": "12193", + "id": "68" + }, + { + "region": "12335", + "id": "62" + }, + { + "region": "12336", + "id": "62" + }, + { + "region": "12337", + "id": "85" + }, + { + "region": "12338", + "id": "3" + }, + { + "region": "12339", + "id": "151" + }, + { + "region": "12340", + "id": "333" + }, + { + "region": "12341", + "id": "141" + }, + { + "region": "12342", + "id": "98" + }, + { + "region": "12343", + "id": "113" + }, + { + "region": "12344", + "id": "8" + }, + { + "region": "12345", + "id": "176" + }, + { + "region": "12346", + "id": "435" + }, + { + "region": "12349", + "id": "13" + }, + { + "region": "12354", + "id": "494" + }, + { + "region": "12367", + "id": "441" + }, + { + "region": "12376", + "id": "443" + }, + { + "region": "12377", + "id": "443" + }, + { + "region": "12378", + "id": "443" + }, + { + "region": "12436", + "id": "85" + }, + { + "region": "12437", + "id": "144" + }, + { + "region": "12438", + "id": "361" + }, + { + "region": "12440", + "id": "338" + }, + { + "region": "12441", + "id": "141" + }, + { + "region": "12442", + "id": "98" + }, + { + "region": "12589", + "id": "352" + }, + { + "region": "12590", + "id": "263" + }, + { + "region": "12591", + "id": "79" + }, + { + "region": "12593", + "id": "64" + }, + { + "region": "12594", + "id": "327" + }, + { + "region": "12595", + "id": "163" + }, + { + "region": "12596", + "id": "116" + }, + { + "region": "12597", + "id": "175" + }, + { + "region": "12598", + "id": "496" + }, + { + "region": "12599", + "id": "56" + }, + { + "region": "12600", + "id": "10" + }, + { + "region": "12601", + "id": "476" + }, + { + "region": "12602", + "id": "67" + }, + { + "region": "12603", + "id": "449" + }, + { + "region": "12604", + "id": "332" + }, + { + "region": "12605", + "id": "106" + }, + { + "region": "12610", + "id": "493" + }, + { + "region": "12610", + "id": "493" + }, + { + "region": "12614", + "id": "572" + }, + { + "region": "12615", + "id": "214" + }, + { + "region": "12619", + "id": "418" + }, + { + "region": "12623", + "id": "441" + }, + { + "region": "12625", + "id": "272" + }, + { + "region": "12693", + "id": "389" + }, + { + "region": "12694", + "id": "343" + }, + { + "region": "12696", + "id": "528" + }, + { + "region": "12697", + "id": "330" + }, + { + "region": "12698", + "id": "144" + }, + { + "region": "12843", + "id": "383" + }, + { + "region": "12846", + "id": "267" + }, + { + "region": "12848", + "id": "124" + }, + { + "region": "12849", + "id": "145" + }, + { + "region": "12850", + "id": "76" + }, + { + "region": "12851", + "id": "2" + }, + { + "region": "12852", + "id": "106" + }, + { + "region": "12853", + "id": "125" + }, + { + "region": "12854", + "id": "177" + }, + { + "region": "12855", + "id": "169" + }, + { + "region": "12856", + "id": "337" + }, + { + "region": "12857", + "id": "332" + }, + { + "region": "12858", + "id": "120" + }, + { + "region": "12861", + "id": "127" + }, + { + "region": "12880", + "id": "441" + }, + { + "region": "12888", + "id": "445" + }, + { + "region": "12889", + "id": "445" + }, + { + "region": "12890", + "id": "445" + }, + { + "region": "12944", + "id": "606" + }, + { + "region": "12945", + "id": "359" + }, + { + "region": "12946", + "id": "266" + }, + { + "region": "12948", + "id": "397" + }, + { + "region": "12949", + "id": "108" + }, + { + "region": "12950", + "id": "46" + }, + { + "region": "12952", + "id": "106" + }, + { + "region": "12953", + "id": "125" + }, + { + "region": "12956", + "id": "569" + }, + { + "region": "13099", + "id": "383" + }, + { + "region": "13100", + "id": "387" + }, + { + "region": "13102", + "id": "174" + }, + { + "region": "13104", + "id": "69" + }, + { + "region": "13105", + "id": "50" + }, + { + "region": "13106", + "id": "36" + }, + { + "region": "13107", + "id": "123" + }, + { + "region": "13108", + "id": "111" + }, + { + "region": "13109", + "id": "157" + }, + { + "region": "13110", + "id": "93" + }, + { + "region": "13111", + "id": "121" + }, + { + "region": "13113", + "id": "14" + }, + { + "region": "13114", + "id": "182" + }, + { + "region": "13115", + "id": "182" + }, + { + "region": "13116", + "id": "331" + }, + { + "region": "13117", + "id": "329" + }, + { + "region": "13131", + "id": "428" + }, + { + "region": "13133", + "id": "552" + }, + { + "region": "13135", + "id": "441" + }, + { + "region": "13141", + "id": "272" + }, + { + "region": "13142", + "id": "459" + }, + { + "region": "13144", + "id": "445" + }, + { + "region": "13145", + "id": "445" + }, + { + "region": "13146", + "id": "445" + }, + { + "region": "13199", + "id": "388" + }, + { + "region": "13200", + "id": "213" + }, + { + "region": "13203", + "id": "168" + }, + { + "region": "13206", + "id": "407" + }, + { + "region": "13209", + "id": "594" + }, + { + "region": "13356", + "id": "505" + }, + { + "region": "13357", + "id": "267" + }, + { + "region": "13358", + "id": "351" + }, + { + "region": "13359", + "id": "174" + }, + { + "region": "13361", + "id": "50" + }, + { + "region": "13362", + "id": "47" + }, + { + "region": "13363", + "id": "122" + }, + { + "region": "13364", + "id": "75" + }, + { + "region": "13365", + "id": "20" + }, + { + "region": "13366", + "id": "93" + }, + { + "region": "13368", + "id": "179" + }, + { + "region": "13369", + "id": "326" + }, + { + "region": "13373", + "id": "586" + }, + { + "region": "13400", + "id": "445" + }, + { + "region": "13401", + "id": "445" + }, + { + "region": "13402", + "id": "445" + }, + { + "region": "13456", + "id": "452" + }, + { + "region": "13457", + "id": "464" + }, + { + "region": "13458", + "id": "540" + }, + { + "region": "13459", + "id": "540" + }, + { + "region": "13461", + "id": "462" + }, + { + "region": "13463", + "id": "534" + }, + { + "region": "13464", + "id": "45" + }, + { + "region": "13465", + "id": "45" + }, + { + "region": "13611", + "id": "451" + }, + { + "region": "13613", + "id": "447" + }, + { + "region": "13614", + "id": "465" + }, + { + "region": "13616", + "id": "377" + }, + { + "region": "13617", + "id": "36" + }, + { + "region": "13618", + "id": "286" + }, + { + "region": "13619", + "id": "154" + }, + { + "region": "13620", + "id": "245" + }, + { + "region": "13621", + "id": "84" + }, + { + "region": "13622", + "id": "48" + }, + { + "region": "13623", + "id": "339" + }, + { + "region": "13642", + "id": "411" + }, + { + "region": "13712", + "id": "452" + }, + { + "region": "13718", + "id": "11" + }, + { + "region": "13720", + "id": "246" + }, + { + "region": "13722", + "id": "156" + }, + { + "region": "13723", + "id": "514" + }, + { + "region": "13872", + "id": "377" + }, + { + "region": "13873", + "id": "501" + }, + { + "region": "13875", + "id": "286" + }, + { + "region": "13876", + "id": "241" + }, + { + "region": "13877", + "id": "244" + }, + { + "region": "13878", + "id": "61" + }, + { + "region": "13879", + "id": "344" + }, + { + "region": "13899", + "id": "146" + }, + { + "region": "13968", + "id": "539" + }, + { + "region": "13972", + "id": "260" + }, + { + "region": "13975", + "id": "287" + }, + { + "region": "13977", + "id": "319" + }, + { + "region": "13979", + "id": "342" + }, + { + "region": "14131", + "id": "380" + }, + { + "region": "14134", + "id": "288" + }, + { + "region": "14155", + "id": "146" + }, + { + "region": "14157", + "id": "379" + }, + { + "region": "14158", + "id": "379" + }, + { + "region": "14167", + "id": "562" + }, + { + "region": "14231", + "id": "381" + }, + { + "region": "14234", + "id": "345" + }, + { + "region": "14391", + "id": "353" + }, + { + "region": "14413", + "id": "379" + }, + { + "region": "14414", + "id": "379" + }, + { + "region": "14486", + "id": "197" + }, + { + "region": "14488", + "id": "521" + }, + { + "region": "14638", + "id": "530" + }, + { + "region": "14646", + "id": "355" + }, + { + "region": "14746", + "id": "354" + }, + { + "region": "14747", + "id": "471" + }, + { + "region": "14894", + "id": "631" + }, + { + "region": "14994", + "id": "632" + }, + { + "region": "14995", + "id": "632" + }, + { + "region": "15148", + "id": "238" + }, + { + "region": "15150", + "id": "611" + }, + { + "region": "15151", + "id": "610" + }, + { + "region": "15159", + "id": "358" + }, + { + "region": "15248", + "id": "238" + }, + { + "region": "15251", + "id": "632" + } +] \ No newline at end of file diff --git a/Server/data/configs/music_tiles.json b/Server/data/configs/music_tiles.json new file mode 100644 index 0000000..7b901f9 --- /dev/null +++ b/Server/data/configs/music_tiles.json @@ -0,0 +1,62 @@ +[ + { + "id": "98", + "borders": "{3072,3456,3135,3519,[3076,3456,3085,3458]~,[3082,3459,3085,3460]}" + }, + { + "id": "141", + "borders": "{3072,3392,3135,3455,[3076,3452,3085,3455]}" + }, + { + "id": "228", + "borders": "{2896,5446,2919,5462}" + }, + { + "id": "229", + "borders": "{2921,5456,2937,5479}" + }, + { + "id": "230", + "borders": "{2904,5481,2927,5497}" + }, + { + "id": "231", + "borders": "{2886,5464,2902,5487}" + }, + { + "id": "386", + "borders": "{2820,5312,2849,5369}-{2849,5349,2880,5374}" + }, + { + "id": "391", + "borders": "{2879,5340,2944,5366}-{2909,5316,2944,5340}" + }, + { + "id": "399", + "borders": "{2816,5248,2943,5375,[2823,5250,2844,5310]~,[2844,5250,2878,5280]~,[2879,5340,2944,5366]~,[2909,5316,2944,5340]~,[2820,5312,2849,5369]~,[2849,5349,2880,5374]~,[2885,5253,2934,5278]~,[2913,5278,2937,5306]}" + }, + { + "id": "404", + "borders": "{2823,5250,2844,5310}-{2844,5250,2878,5276}" + }, + { + "id": "408", + "borders": "{2885,5253,2934,5278}-{2913,5278,2937,5306}" + }, + { + "id": "459", + "borders": "{3137,5442,3192,5564}-{3193,5442,3198,5472}-{3193,5507,3198,5564}" + }, + { + "id": "467", + "borders": "{3199,5441,3262,5564}-{3193,5482,3198,5497}" + }, + { + "id": "488", + "borders": "{3263,5441,3327,5566}" + }, + { + "id": "492", + "borders": "{3076,3452,3085,3460,[3076,3459,3081,3460]}" + } +] \ No newline at end of file diff --git a/Server/data/configs/npc_configs.json b/Server/data/configs/npc_configs.json new file mode 100644 index 0000000..71d194e --- /dev/null +++ b/Server/data/configs/npc_configs.json @@ -0,0 +1,87896 @@ +[ + { + "examine": "Servant of the Duke of Lumbridge.", + "melee_animation": "422", + "range_animation": "422", + "attack_speed": "4", + "magic_level": "22", + "defence_animation": "404", + "magic_animation": "422", + "death_animation": "9055", + "name": "Hans", + "defence_level": "14", + "safespot": "0", + "lifepoints": "12", + "strength_level": "17", + "id": "0", + "range_level": "1", + "attack_level": "17" + }, + { + "examine": "One of Gielinor's many citizens.", + "melee_animation": "422", + "range_animation": "422", + "combat_audio": "511,513,512", + "attack_speed": "4", + "magic_level": "6", + "respawn_delay": "18", + "defence_animation": "404", + "weakness": "9", + "slayer_exp": "0", + "magic_animation": "422", + "death_animation": "9055", + "name": "Man", + "defence_level": "5", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "1", + "clue_level": "0", + "range_level": "1", + "attack_level": "5" + }, + { + "examine": "One of Gielinor's many citizens.", + "melee_animation": "422", + "range_animation": "422", + "combat_audio": "511,513,512", + "attack_speed": "4", + "respawn_delay": "60", + "defence_animation": "404", + "weakness": "9", + "magic_animation": "422", + "death_animation": "9055", + "name": "Man", + "defence_level": "3", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2", + "clue_level": "0", + "range_level": "1", + "attack_level": "3" + }, + { + "examine": "One of Gielinor's many citizens.", + "melee_animation": "422", + "range_animation": "422", + "combat_audio": "511,513,512", + "attack_speed": "4", + "defence_animation": "404", + "weakness": "9", + "slayer_exp": "0", + "magic_animation": "422", + "death_animation": "9055", + "name": "Man", + "defence_level": "3", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3", + "clue_level": "0", + "range_level": "1", + "attack_level": "3" + }, + { + "examine": "One of Gielinor's many citizens.", + "melee_animation": "422", + "range_animation": "422", + "combat_audio": "511,506,505", + "attack_speed": "4", + "defence_animation": "404", + "weakness": "9", + "magic_animation": "422", + "death_animation": "9055", + "name": "Woman", + "defence_level": "3", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4", + "clue_level": "0", + "range_level": "1", + "attack_level": "3" + }, + { + "examine": "One of Gielinor's many citizens.", + "melee_animation": "422", + "range_animation": "422", + "combat_audio": "511,506,505", + "attack_speed": "4", + "defence_animation": "404", + "weakness": "9", + "magic_animation": "422", + "death_animation": "9055", + "name": "Woman", + "defence_level": "3", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5", + "clue_level": "0", + "range_level": "1", + "attack_level": "3" + }, + { + "examine": "One of Gielinor's many citizens.", + "melee_animation": "422", + "range_animation": "0", + "combat_audio": "511,506,505", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "404", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Woman", + "defence_level": "3", + "safespot": null, + "lifepoints": "4", + "strength_level": "1", + "id": "6", + "clue_level": "0", + "range_level": "1", + "attack_level": "3" + }, + { + "examine": "He grows the crops in this area.", + "melee_animation": "422", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "404", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Farmer", + "defence_level": "5", + "safespot": null, + "lifepoints": "7", + "strength_level": "5", + "id": "7", + "range_level": "1", + "attack_level": "5" + }, + { + "examine": "Known for his light-fingered qualities.", + "melee_animation": "422", + "range_animation": "0", + "attack_speed": "4", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Thief", + "defence_level": "10", + "safespot": null, + "lifepoints": "14", + "strength_level": "10", + "id": "8", + "range_level": "1", + "attack_level": "10" + }, + { + "examine": "He tries to keep order around here.", + "melee_animation": "400", + "range_animation": "0", + "combat_audio": "2549,1979,512", + "attack_speed": "4", + "respawn_delay": "60", + "defence_animation": "404", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Guard", + "defence_level": "13", + "safespot": null, + "lifepoints": "18", + "strength_level": "13", + "id": "9", + "clue_level": "1", + "range_level": "1", + "attack_level": "13" + }, + { + "examine": "She looks happy.", + "melee_animation": "0", + "range_animation": "1142", + "defence_animation": "285", + "magic_animation": "0", + "death_animation": "287", + "name": "Schoolgirl", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "10", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A man down on his luck.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Tramp", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "11", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Not very civilised looking.", + "name": "Barbarian", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "12", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Slightly magical.", + "start_gfx": "2728", + "combat_style": "2", + "melee_animation": "2791", + "range_animation": "711", + "combat_audio": "511,513,512", + "magic_level": "21", + "respawn_delay": "12", + "end_gfx": "2737", + "defence_animation": "404", + "weakness": "3", + "slayer_exp": "0", + "magic_animation": "711", + "death_animation": "9055", + "name": "Wizard", + "defence_level": "12", + "safespot": null, + "lifepoints": "14", + "strength_level": "1", + "id": "13", + "bonuses": "23,7,8,2,1,8,12,0,0,0,0,0,0,0,0", + "range_level": "1", + "projectile": "2729", + "attack_level": "1" + }, + { + "examine": "Loves nature.", + "combat_audio": "511,513,512", + "range_animation": "0", + "melee_animation": "422", + "attack_speed": "4", + "magic_level": "25", + "respawn_delay": "25", + "defence_animation": "404", + "magic_animation": "711", + "name": "Druid", + "defence_level": "32", + "safespot": null, + "lifepoints": "30", + "strength_level": "28", + "id": "14", + "range_level": "1", + "attack_level": "28" + }, + { + "examine": "Not very fashion conscious.", + "melee_animation": "386", + "range_animation": "0", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "836", + "name": "Warrior woman", + "defence_level": "22", + "safespot": null, + "lifepoints": "20", + "strength_level": "22", + "id": "15", + "range_level": "1", + "attack_level": "22" + }, + { + "examine": "One of the citizens of Al Kharid.", + "melee_animation": "422", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "836", + "name": "Man", + "defence_level": "3", + "safespot": null, + "lifepoints": "4", + "strength_level": "3", + "id": "16", + "clue_level": "0", + "range_level": "1", + "attack_level": "3" + }, + { + "examine": "Part of Al-Kharid's elite fighting force.", + "melee_animation": "390", + "range_animation": "390", + "combat_audio": "2500,1976,512", + "attack_speed": "4", + "respawn_delay": "25", + "defence_animation": "387", + "weakness": "7", + "magic_animation": "390", + "death_animation": "836", + "name": "Al-Kharid warrior", + "defence_level": "4", + "safespot": null, + "lifepoints": "19", + "strength_level": "5", + "id": "18", + "clue_level": "0", + "bonuses": "10,10,10,0,0,12,15,10,-1,12,0,9,0,0,0", + "range_level": "1", + "attack_level": "7" + }, + { + "examine": "Shiny armour!", + "melee_animation": "7042", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "8", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "836", + "name": "White Knight", + "defence_level": "25", + "safespot": null, + "lifepoints": "35", + "strength_level": "25", + "id": "19", + "range_level": "1", + "attack_level": "25" + }, + { + "examine": "A holy warrior.", + "melee_animation": "390", + "combat_audio": "511,513,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Paladin", + "defence_level": "54", + "safespot": null, + "lifepoints": "66", + "strength_level": "54", + "id": "20", + "range_level": "1", + "attack_level": "54" + }, + { + "examine": "Heroic!", + "melee_animation": "390", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "425", + "weakness": "7", + "magic_animation": "0", + "death_animation": "836", + "name": "Hero", + "defence_level": "54", + "safespot": null, + "lifepoints": "82", + "strength_level": "55", + "id": "21", + "range_level": "1", + "attack_level": "54" + }, + { + "examine": "They love the forests.", + "melee_animation": "422", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "4", + "respawn_delay": "18", + "defence_animation": "404", + "magic_animation": "0", + "death_animation": "9055", + "name": "Forester", + "defence_level": "8", + "safespot": null, + "lifepoints": "17", + "strength_level": "13", + "id": "22", + "range_level": "1", + "attack_level": "14" + }, + { + "examine": "A member of Ardougne's militia.", + "melee_animation": "390", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "836", + "name": "Knight of Ardougne", + "defence_level": "31", + "safespot": null, + "lifepoints": "52", + "strength_level": "40", + "id": "23", + "range_level": "1", + "attack_level": "38" + }, + { + "examine": "One of Gielinor's many citizens.", + "melee_animation": "422", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Man", + "defence_level": "3", + "safespot": null, + "lifepoints": "4", + "strength_level": "3", + "id": "24", + "clue_level": "0", + "range_level": "1", + "attack_level": "3" + }, + { + "examine": "One of Gielinor's many citizens.", + "melee_animation": "422", + "range_animation": "0", + "combat_audio": "511,506,505", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Woman", + "defence_level": "3", + "safespot": null, + "lifepoints": "4", + "strength_level": "3", + "id": "25", + "clue_level": "0", + "range_level": "1", + "attack_level": "3" + }, + { + "examine": "To protect and serve the populace of Ardougne.", + "melee_animation": "390", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "836", + "name": "Knight of Ardougne", + "defence_level": "31", + "safespot": null, + "lifepoints": "52", + "strength_level": "40", + "id": "26", + "range_level": "1", + "attack_level": "38" + }, + { + "examine": "Good with arrows.", + "start_gfx": "19", + "combat_style": "1", + "melee_animation": "426", + "range_animation": "426", + "respawn_delay": "12", + "defence_animation": "404", + "magic_animation": "426", + "death_animation": "9055", + "name": "Archer", + "defence_level": "20", + "safespot": null, + "lifepoints": "50", + "strength_level": "20", + "id": "27", + "range_level": "40", + "projectile": "10", + "attack_level": "20" + }, + { + "examine": "Enjoys locking up animals in small pens.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Zoo keeper", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "28", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He's a lumberjack, and he's ok.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Chuck", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "29", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Doesn't water down the beer too much.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Barman", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "30", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A holy man.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Priest", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "31", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Keeps the peace... kind of.", + "melee_animation": "401", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Guard", + "defence_level": "13", + "safespot": null, + "lifepoints": "22", + "strength_level": "18", + "id": "32", + "clue_level": "1", + "range_level": "1", + "attack_level": "17" + }, + { + "examine": "What a boring job he has.", + "name": "Door man", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "33", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Watches stuff. But who watches him?", + "melee_animation": "422", + "range_animation": "0", + "attack_speed": "6", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "836", + "name": "Watchman", + "defence_level": "31", + "safespot": null, + "lifepoints": "22", + "strength_level": "31", + "id": "34", + "range_level": "1", + "attack_level": "31" + }, + { + "examine": "A soldier of the town of Yanille.", + "melee_animation": "390", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "836", + "name": "Soldier", + "defence_level": "26", + "safespot": null, + "lifepoints": "22", + "strength_level": "25", + "id": "35", + "range_level": "1", + "attack_level": "26" + }, + { + "examine": "The head gardener.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Wyson the gardener", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "36", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A bold knight famed for his travels.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Sigbert the Adventurer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "37", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Builds ships for a living.", + "melee_animation": "422", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "836", + "name": "Shipyard worker", + "defence_level": "10", + "safespot": null, + "lifepoints": "10", + "strength_level": "10", + "id": "38", + "range_level": "1", + "attack_level": "10" + }, + { + "examine": "Builds ships for a living.", + "melee_animation": "401", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "836", + "name": "Shipyard worker", + "defence_level": "10", + "safespot": null, + "lifepoints": "10", + "strength_level": "10", + "id": "39", + "range_level": "1", + "attack_level": "10" + }, + { + "examine": "Let's not go skinny dipping eh?", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Shark", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "40", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Yep. Definitely a chicken.", + "melee_animation": "5387", + "range_animation": "5387", + "combat_audio": "355,357,356", + "attack_speed": "6", + "respawn_delay": "18", + "defence_animation": "5388", + "weakness": "9", + "magic_animation": "5387", + "death_animation": "5389", + "name": "Chicken", + "defence_level": "1", + "safespot": null, + "lifepoints": "3", + "strength_level": "1", + "id": "41", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Freshly sheared.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Sheep", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "42", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "White and fluffy.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Sheep", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "43", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He can look after my money.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Banker", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "44", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "She can look after my money.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Banker", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "45", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Quackers.", + "melee_animation": "0", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "3468", + "name": "Duck", + "defence_level": "1", + "water_npc": "true", + "safespot": null, + "lifepoints": "1", + "strength_level": "1", + "id": "46", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A popular dwarven delicacy.", + "melee_animation": "2705", + "range_animation": "2705", + "combat_audio": "3102,3104,3103", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "3", + "defence_animation": "2706", + "slayer_exp": "2", + "magic_animation": "2705", + "death_animation": "2707", + "name": "Rat", + "defence_level": "1", + "safespot": null, + "lifepoints": "2", + "strength_level": "1", + "id": "47", + "bonuses": "-47,-47,-47,0,0,-42,-42,-42,-42,-42,-42,-53,0,0,0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A jungle version of the chicken, but more vicious.", + "melee_animation": "5387", + "range_animation": "0", + "attack_speed": "4", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "5389", + "name": "Oomlie bird", + "defence_level": "40", + "safespot": null, + "lifepoints": "40", + "strength_level": "40", + "id": "48", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "Hello, nice doggy...", + "melee_animation": "6562", + "range_animation": "6562", + "combat_audio": "3717,3719,3718", + "attack_speed": "4", + "respawn_delay": "50", + "defence_animation": "6563", + "weakness": "1", + "slayer_exp": "116", + "magic_animation": "6562", + "death_animation": "6564", + "name": "Hellhound", + "defence_level": "102", + "safespot": null, + "lifepoints": "116", + "strength_level": "104", + "id": "49", + "aggressive": "true", + "clue_level": "2", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "105" + }, + { + "agg_radius": "64", + "examine": "The biggest, meanest dragon around.", + "melee_animation": "80", + "range_animation": "80", + "combat_audio": "408,410,409", + "magic_level": "240", + "respawn_delay": "50", + "defence_animation": "89", + "weakness": "4", + "slayer_exp": "258", + "magic_animation": "80", + "death_animation": "92", + "name": "King Black Dragon", + "defence_level": "240", + "safespot": null, + "lifepoints": "240", + "strength_level": "240", + "id": "50", + "aggressive": "true", + "bonuses": "0,0,0,0,0,70,90,90,80,70,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "240" + }, + { + "examine": "Young but still dangerous.", + "combat_audio": "407,405,406", + "magic_level": "116", + "respawn_delay": "25", + "weakness": "0", + "name": "Baby dragon", + "defence_level": "112", + "safespot": null, + "lifepoints": "160", + "strength_level": "103", + "id": "51", + "aggressive": "true", + "bonuses": "124,130,137,184,176,128,168,145,104,54,0,0,0,0,0", + "range_level": "80", + "attack_level": "102" + }, + { + "examine": "Young but still dangerous.", + "combat_audio": "405,407,406", + "melee_animation": "25", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "26", + "weakness": "3", + "slayer_exp": "50", + "magic_animation": "25", + "death_animation": "28", + "name": "Baby blue dragon", + "defence_level": "40", + "safespot": null, + "lifepoints": "50", + "strength_level": "40", + "id": "52", + "aggressive": "true", + "bonuses": "0,0,0,0,0,30,50,50,40,30,0,0,0,0,0", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "A big powerful dragon.", + "melee_animation": "80", + "range_animation": "80", + "combat_audio": "408,410,409", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "35", + "defence_animation": "89", + "weakness": "3", + "slayer_exp": "143", + "magic_animation": "80", + "death_animation": "92", + "name": "Red dragon", + "defence_level": "130", + "safespot": null, + "lifepoints": "140", + "strength_level": "130", + "id": "53", + "aggressive": "true", + "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "130" + }, + { + "examine": "A fierce dragon with black scales!", + "melee_animation": "80", + "range_animation": "80", + "combat_audio": "408,410,409", + "attack_speed": "4", + "magic_level": "100", + "respawn_delay": "35", + "defence_animation": "89", + "weakness": "3", + "slayer_exp": "200", + "magic_animation": "80", + "death_animation": "92", + "name": "Black dragon", + "defence_level": "200", + "safespot": null, + "lifepoints": "190", + "strength_level": "200", + "id": "54", + "aggressive": "true", + "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "200" + }, + { + "examine": "A mother dragon.", + "melee_animation": "80", + "range_animation": "80", + "combat_audio": "408,410,409", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "35", + "defence_animation": "89", + "weakness": "3", + "slayer_exp": "108", + "magic_animation": "80", + "death_animation": "92", + "name": "Blue dragon", + "defence_level": "95", + "safespot": null, + "lifepoints": "105", + "strength_level": "95", + "id": "55", + "aggressive": "true", + "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "95" + }, + { + "examine": "A wood nymph.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Dryad", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "56", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A delicate creature from this strange realm.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fairy", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "57", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Is it a spider or is it a shadow?", + "melee_animation": "5327", + "range_animation": "0", + "combat_audio": "537,539,538", + "attack_speed": "4", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "2", + "slayer_exp": "55", + "magic_animation": "0", + "death_animation": "5329", + "name": "Shadow spider", + "defence_level": "44", + "safespot": null, + "lifepoints": "55", + "strength_level": "42", + "id": "58", + "aggressive": "true", + "range_level": "1", + "attack_level": "44" + }, + { + "examine": "I think this spider has been genetically modified.", + "melee_animation": "5327", + "range_animation": "0", + "combat_audio": "537,539,538", + "attack_speed": "4", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "2", + "slayer_exp": "5", + "magic_animation": "0", + "death_animation": "5329", + "name": "Giant spider", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "1", + "id": "59", + "aggressive": "false", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "I think this spider has been genetically modified.", + "melee_animation": "5327", + "range_animation": "5327", + "combat_audio": "537,539,538", + "defence_animation": "5328", + "weakness": "2", + "slayer_exp": "33", + "magic_animation": "5327", + "death_animation": "5329", + "name": "Giant spider", + "defence_level": "21", + "safespot": null, + "lifepoints": "32", + "strength_level": "24", + "id": "60", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "20" + }, + { + "examine": "Incey wincey.", + "melee_animation": "6249", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "2", + "slayer_exp": "2", + "magic_animation": "0", + "death_animation": "6251", + "name": "Spider", + "defence_level": "1", + "safespot": null, + "lifepoints": "1", + "strength_level": "1", + "id": "61", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A barely visible deadly jungle spider.", + "melee_animation": "5327", + "range_animation": "5327", + "combat_audio": "537,539,538", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "25", + "defence_animation": "5328", + "weakness": "2", + "slayer_exp": "50", + "magic_animation": "5327", + "death_animation": "5329", + "name": "Jungle spider", + "defence_level": "35", + "poison_immune": "false", + "safespot": null, + "lifepoints": "50", + "strength_level": "37", + "id": "62", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "35" + }, + { + "examine": "I think this spider has been genetically modified.", + "melee_animation": "5327", + "range_animation": "5327", + "combat_audio": "537,539,538", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "5328", + "weakness": "2", + "slayer_exp": "35", + "magic_animation": "5327", + "death_animation": "5329", + "name": "Deadly red spider", + "defence_level": "30", + "safespot": null, + "lifepoints": "35", + "strength_level": "25", + "id": "63", + "bonuses": "0,0,0,0,0,0,15,16,7,12,16,0,0,0,0", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "I think this spider has been genetically modified.", + "melee_animation": "5327", + "range_animation": "0", + "combat_audio": "537,539,538", + "attack_speed": "4", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "2", + "slayer_exp": "65", + "magic_animation": "0", + "death_animation": "5329", + "name": "Ice spider", + "defence_level": "43", + "safespot": null, + "lifepoints": "65", + "strength_level": "55", + "id": "64", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,20,17,12,13,13,0,0,0,0", + "range_level": "1", + "attack_level": "50" + }, + { + "examine": "A funny little man normally associated with rainbows.", + "melee_animation": "422", + "range_animation": "422", + "magic_level": "1", + "defence_animation": "404", + "magic_animation": "422", + "death_animation": "9055", + "name": "Leprechaun", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "65", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Like a mini man!", + "melee_animation": "422", + "range_animation": "422", + "magic_level": "1", + "defence_animation": "404", + "magic_animation": "422", + "death_animation": "9055", + "name": "Gnome", + "defence_level": "1", + "safespot": null, + "lifepoints": "3", + "strength_level": "1", + "id": "66", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Like a mini man!", + "melee_animation": "422", + "range_animation": "422", + "magic_level": "1", + "defence_animation": "404", + "magic_animation": "422", + "death_animation": "9055", + "name": "Gnome", + "defence_level": "1", + "safespot": null, + "lifepoints": "3", + "strength_level": "1", + "id": "67", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Like a mini man!", + "melee_animation": "422", + "range_animation": "422", + "magic_level": "1", + "defence_animation": "404", + "magic_animation": "422", + "death_animation": "9055", + "name": "Gnome", + "defence_level": "1", + "safespot": null, + "lifepoints": "3", + "strength_level": "1", + "id": "68", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A scaly reptilian creature.", + "melee_animation": "422", + "range_animation": "422", + "attack_speed": "4", + "magic_level": "1", + "defence_animation": "404", + "magic_animation": "422", + "death_animation": "9055", + "name": "Lizard man", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "69", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A hideous malformed elf.", + "melee_animation": "422", + "range_animation": "422", + "magic_level": "1", + "defence_animation": "404", + "magic_animation": "422", + "death_animation": "9055", + "name": "Orc", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "71", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A hideously deformed creature.", + "melee_animation": "422", + "range_animation": "422", + "magic_level": "1", + "defence_animation": "404", + "magic_animation": "422", + "death_animation": "9055", + "name": "Troll", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "72", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Dead man walking.", + "melee_animation": "5567", + "combat_audio": "931,923,922", + "attack_speed": "4", + "respawn_delay": "60", + "defence_animation": "5568", + "slayer_exp": "22", + "death_animation": "5569", + "name": "Zombie", + "defence_level": "10", + "safespot": null, + "lifepoints": "22", + "strength_level": "9", + "id": "73", + "aggressive": "true", + "range_level": "1", + "attack_level": "8" + }, + { + "examine": "Dead woman walking.", + "melee_animation": "5578", + "range_animation": "5578", + "combat_audio": "931,923,922", + "attack_speed": "4", + "respawn_delay": "30", + "defence_animation": "5579", + "slayer_exp": "24", + "magic_animation": "5578", + "death_animation": "5580", + "name": "Zombie", + "defence_level": "10", + "safespot": null, + "lifepoints": "24", + "strength_level": "13", + "id": "74", + "aggressive": "true", + "range_level": "1", + "attack_level": "13" + }, + { + "examine": "The walking dead.", + "melee_animation": "5578", + "range_animation": "5578", + "combat_audio": "931,923,922", + "attack_speed": "4", + "respawn_delay": "30", + "defence_animation": "5579", + "slayer_exp": "30", + "magic_animation": "5578", + "death_animation": "5580", + "name": "Zombie", + "defence_level": "16", + "safespot": null, + "lifepoints": "30", + "strength_level": "21", + "id": "75", + "aggressive": "true", + "range_level": "1", + "attack_level": "19" + }, + { + "examine": "The walking dead.", + "melee_animation": "5571", + "combat_audio": "931,923,922", + "attack_speed": "4", + "respawn_delay": "60", + "defence_animation": "5574", + "slayer_exp": "30", + "death_animation": "5575", + "name": "Zombie", + "defence_level": "16", + "safespot": null, + "lifepoints": "30", + "strength_level": "21", + "id": "76", + "aggressive": "true", + "range_level": "1", + "attack_level": "19" + }, + { + "examine": "The living dead.", + "melee_animation": "5568", + "range_animation": "0", + "attack_speed": "4", + "defence_animation": "0", + "weakness": "9", + "slayer_exp": "22", + "magic_animation": "0", + "death_animation": "5569", + "name": "Summoned Zombie", + "defence_level": "10", + "safespot": null, + "lifepoints": "22", + "strength_level": "9", + "id": "77", + "range_level": "1", + "attack_level": "8" + }, + { + "examine": "An annoying flappy thing.", + "melee_animation": "4915", + "range_animation": "4915", + "combat_audio": "292,294,293", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "35", + "defence_animation": "4916", + "weakness": "4", + "slayer_exp": "32", + "magic_animation": "4915", + "death_animation": "4917", + "name": "Giant bat", + "defence_level": "22", + "safespot": null, + "lifepoints": "32", + "strength_level": "22", + "id": "78", + "aggressive": "true", + "bonuses": "0,0,0,0,0,10,10,12,10,8,0,0,0,0,0", + "range_level": "1", + "attack_level": "22" + }, + { + "examine": "A shadowy, barely visible flying entity from some evil place.", + "melee_animation": "4915", + "range_animation": "0", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "3", + "slayer_exp": "80", + "magic_animation": "0", + "death_animation": "4917", + "name": "Death wing", + "defence_level": "70", + "safespot": null, + "lifepoints": "80", + "strength_level": "70", + "id": "79", + "aggressive": "true", + "range_level": "1", + "attack_level": "70" + }, + { + "examine": "Oh, it's a camel.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Camel", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "80", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Converts grass to beef.", + "melee_animation": "5849", + "range_animation": "5849", + "combat_audio": "369,371,370", + "attack_speed": "5", + "defence_animation": "5850", + "weakness": "8", + "slayer_exp": "8", + "magic_animation": "5849", + "death_animation": "5851", + "name": "Cow", + "defence_level": "1", + "safespot": null, + "lifepoints": "8", + "strength_level": "1", + "id": "81", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Lesser, but still pretty big.", + "melee_animation": "4630", + "range_animation": "4630", + "combat_audio": "400,404,403", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "65", + "weakness": "4", + "slayer_exp": "79", + "magic_animation": "4630", + "death_animation": "67", + "name": "Lesser demon", + "defence_level": "71", + "safespot": null, + "lifepoints": "79", + "strength_level": "70", + "id": "82", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,-10,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "68" + }, + { + "examine": "Big, red, and incredibly evil.", + "melee_animation": "64", + "range_animation": "64", + "combat_audio": "400,404,403", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "32", + "defence_animation": "65", + "weakness": "4", + "slayer_exp": "87", + "magic_animation": "64", + "death_animation": "68", + "name": "Greater demon", + "defence_level": "81", + "safespot": null, + "lifepoints": "89", + "strength_level": "78", + "id": "83", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,-10,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "76" + }, + { + "examine": "A big, scary, jet-black demon.", + "melee_animation": "64", + "range_animation": "64", + "combat_audio": "397,399,398", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "65", + "weakness": "4", + "slayer_exp": "157", + "facing_booth": "", + "magic_animation": "64", + "death_animation": "67", + "name": "Black demon", + "defence_level": "152", + "safespot": null, + "lifepoints": "157", + "strength_level": "148", + "id": "84", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,-10,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "145" + }, + { + "examine": "A creature made from clay.", + "melee_animation": "422", + "range_animation": "422", + "magic_level": "1", + "defence_animation": "404", + "magic_animation": "422", + "death_animation": "9055", + "name": "Golem", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "85", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Overgrown vermin.", + "melee_animation": "4933", + "range_animation": "4933", + "combat_audio": "703,705,704", + "attack_speed": "4", + "defence_animation": "4934", + "weakness": "8", + "slayer_exp": "5", + "magic_animation": "4933", + "death_animation": "4935", + "name": "Giant rat", + "defence_level": "2", + "safespot": null, + "lifepoints": "5", + "strength_level": "3", + "id": "86", + "aggressive": "true", + "range_level": "1", + "attack_level": "2" + }, + { + "examine": "Overgrown vermin.", + "melee_animation": "4933", + "range_animation": "0", + "combat_audio": "703,705,704", + "attack_speed": "4", + "respawn_delay": "60", + "defence_animation": "4934", + "weakness": "8", + "slayer_exp": "10", + "magic_animation": "0", + "death_animation": "4935", + "name": "Giant rat", + "defence_level": "2", + "safespot": null, + "lifepoints": "10", + "strength_level": "5", + "id": "87", + "aggressive": "true", + "range_level": "1", + "attack_level": "6" + }, + { + "examine": "A dirty rat.", + "range_animation": "0", + "combat_audio": "703,705,704", + "attack_speed": "4", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "slayer_exp": "12", + "magic_animation": "0", + "death_animation": "4935", + "name": "Dungeon rat", + "defence_level": "10", + "safespot": null, + "lifepoints": "12", + "strength_level": "10", + "id": "88", + "aggressive": "true", + "range_level": "1", + "attack_level": "10" + }, + { + "examine": "Horse with a horn.", + "melee_animation": "6376", + "range_animation": "6376", + "combat_audio": "369,371,370", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "90", + "defence_animation": "6375", + "weakness": "3", + "magic_animation": "6376", + "death_animation": "6377", + "name": "Unicorn", + "defence_level": "13", + "safespot": null, + "lifepoints": "19", + "strength_level": "13", + "id": "89", + "range_level": "1", + "attack_level": "11" + }, + { + "examine": "Not man's best friend.", + "melee_animation": "6559", + "combat_audio": "481,491,490", + "attack_speed": "4", + "defence_animation": "6557", + "slayer_exp": "69", + "death_animation": "6558", + "name": "Wolf", + "defence_level": "52", + "safespot": null, + "lifepoints": "69", + "strength_level": "55", + "id": "95", + "range_level": "1", + "attack_level": "50" + }, + { + "examine": "A vicious mountain wolf.", + "melee_animation": "6579", + "range_animation": "6579", + "combat_audio": "909,912,911", + "attack_speed": "4", + "defence_animation": "6578", + "weakness": "9", + "slayer_exp": "34", + "magic_animation": "6579", + "death_animation": "6576", + "name": "White wolf", + "defence_level": "22", + "safespot": null, + "lifepoints": "34", + "strength_level": "16", + "id": "96", + "aggressive": "true", + "range_level": "1", + "attack_level": "20" + }, + { + "examine": "A vicious mountain wolf.", + "melee_animation": "6579", + "range_animation": "6579", + "combat_audio": "909,912,911", + "attack_speed": "4", + "defence_animation": "6578", + "weakness": "7", + "slayer_exp": "44", + "magic_animation": "6579", + "death_animation": "6576", + "name": "White wolf", + "defence_level": "32", + "safespot": null, + "lifepoints": "44", + "strength_level": "31", + "id": "97", + "aggressive": "true", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "Bow wow.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Dog", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "98", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He doesn't seem pleased to see me.", + "melee_animation": "6562", + "range_animation": "6562", + "attack_speed": "4", + "respawn_delay": "15", + "defence_animation": "6563", + "weakness": "7", + "slayer_exp": "49", + "magic_animation": "6562", + "death_animation": "6564", + "name": "Guard dog", + "defence_level": "37", + "safespot": null, + "lifepoints": "49", + "strength_level": "36", + "id": "99", + "aggressive": "true", + "range_level": "1", + "attack_level": "35" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "4", + "defence_animation": "6183", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "1", + "id": "100", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "3", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "101", + "clue_level": "0", + "range_level": "1", + "attack_level": "3" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "slayer_exp": "16", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "102", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "agg_radius": "", + "examine": "Eeek! A ghost!", + "melee_animation": "5540", + "range_animation": "5540", + "combat_audio": "436,439,438", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "40", + "defence_animation": "5541", + "weakness": "5", + "slayer_exp": "25", + "magic_animation": "5540", + "death_animation": "5542", + "name": "Ghost", + "defence_level": "18", + "safespot": null, + "lifepoints": "25", + "strength_level": "13", + "id": "103", + "aggressive": "true", + "bonuses": "0,0,0,0,0,5,5,5,-5,5,0,0,0,0,0", + "range_level": "1", + "attack_level": "13" + }, + { + "examine": "Eeek! A ghost!", + "melee_animation": "5540", + "range_animation": "0", + "combat_audio": "436,439,438", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "40", + "defence_animation": "5541", + "weakness": "5", + "slayer_exp": "25", + "magic_animation": "0", + "death_animation": "5542", + "name": "Ghost", + "defence_level": "18", + "safespot": null, + "lifepoints": "25", + "strength_level": "13", + "id": "104", + "aggressive": "true", + "bonuses": "0,0,0,0,0,5,5,5,-5,5,0,0,0,0,0", + "range_level": "1", + "attack_level": "13" + }, + { + "examine": "Eek! A bear!", + "melee_animation": "4925", + "range_animation": "0", + "combat_audio": "300,302,301", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "50", + "defence_animation": "0", + "weakness": "7", + "slayer_exp": "27", + "magic_animation": "0", + "death_animation": "4929", + "name": "Grizzly bear", + "defence_level": "15", + "safespot": null, + "lifepoints": "27", + "strength_level": "18", + "id": "105", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "17" + }, + { + "examine": "Eek! A bear!", + "melee_animation": "4925", + "range_animation": "0", + "combat_audio": "300,302,301", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "50", + "defence_animation": "0", + "weakness": "7", + "slayer_exp": "25", + "magic_animation": "0", + "death_animation": "4929", + "name": "Black bear", + "defence_level": "13", + "safespot": null, + "lifepoints": "25", + "strength_level": "16", + "id": "106", + "aggressive": "false", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "15" + }, + { + "examine": "An extremely vicious scorpion.", + "melee_animation": "6254", + "combat_audio": "3611,3612,3610", + "respawn_delay": "60", + "defence_animation": "6255", + "slayer_exp": "17", + "death_animation": "6256", + "name": "Scorpion", + "defence_level": "1", + "safespot": null, + "lifepoints": "17", + "strength_level": "1", + "id": "107", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It has a very vicious looking tail.", + "melee_animation": "6254", + "range_animation": "0", + "combat_audio": "3611,3612,3610", + "attack_speed": "4", + "poisonous": "true", + "respawn_delay": "25", + "defence_animation": "6255", + "weakness": "0", + "slayer_exp": "23", + "poison_amount": "3", + "magic_animation": "0", + "death_animation": "6256", + "name": "Poison Scorpion", + "defence_level": "15", + "safespot": null, + "lifepoints": "23", + "strength_level": "17", + "id": "108", + "aggressive": "true", + "bonuses": "0,0,0,0,0,5,15,15,0,5,0,0,0,0,0", + "range_level": "1", + "attack_level": "16" + }, + { + "examine": "Tiny", + "melee_animation": "6254", + "range_animation": "0", + "combat_audio": "3611,3612,3610", + "respawn_delay": "60", + "defence_animation": "6255", + "weakness": "0", + "magic_animation": "0", + "death_animation": "6256", + "name": "Pit Scorpion", + "defence_level": "40", + "safespot": null, + "lifepoints": "57", + "strength_level": "1", + "id": "109", + "aggressive": "true", + "range_level": "40", + "attack_level": "1" + }, + { + "examine": "A very large elemental adversary.", + "melee_animation": "4666", + "range_animation": "4666", + "combat_audio": "447,451,450", + "attack_speed": "5", + "magic_level": "1", + "respawn_delay": "20", + "defence_animation": "4664", + "weakness": "1", + "slayer_exp": "111", + "magic_animation": "4666", + "death_animation": "4668", + "name": "Fire giant", + "defence_level": "65", + "safespot": null, + "lifepoints": "111", + "strength_level": "65", + "id": "110", + "aggressive": "true", + "bonuses": "29,29,29,0,0,0,3,2,0,0,0,31,0,0,0", + "range_level": "1", + "attack_level": "65" + }, + { + "examine": "He's got icicles in his beard.", + "melee_animation": "4672", + "range_animation": "0", + "combat_audio": "448,451,450", + "attack_speed": "5", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "0", + "weakness": "9", + "slayer_exp": "70", + "magic_animation": "0", + "death_animation": "4673", + "name": "Ice giant", + "defence_level": "40", + "safespot": null, + "lifepoints": "70", + "strength_level": "40", + "id": "111", + "aggressive": "true", + "bonuses": "29,29,29,0,0,0,3,2,0,0,0,31,0,0,0", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "His beard seems to have a life of its own.", + "melee_animation": "4666", + "range_animation": "4666", + "combat_audio": "449,451,450", + "attack_speed": "6", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "4665", + "weakness": "1", + "slayer_exp": "60", + "magic_animation": "4666", + "death_animation": "4668", + "name": "Moss giant", + "defence_level": "30", + "safespot": null, + "lifepoints": "60", + "strength_level": "30", + "id": "112", + "aggressive": "true", + "bonuses": "33,33,33,0,0,0,0,0,0,0,0,31,0,0,0", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "An aggressive humanoid.", + "melee_animation": "128", + "range_animation": "128", + "attack_speed": "5", + "defence_animation": "129", + "weakness": "7", + "magic_animation": "128", + "death_animation": "131", + "name": "Jogre", + "defence_level": "41", + "safespot": null, + "lifepoints": "50", + "strength_level": "36", + "id": "113", + "aggressive": "true", + "clue_level": "1", + "range_level": "1", + "attack_level": "41" + }, + { + "examine": "Big, ugly, and smelly.", + "melee_animation": "359", + "range_animation": "359", + "attack_speed": "6", + "magic_level": "27", + "respawn_delay": "25", + "defence_animation": "360", + "slayer_exp": "", + "magic_animation": "359", + "death_animation": "361", + "name": "Mogre", + "defence_level": "27", + "safespot": null, + "lifepoints": "60", + "strength_level": "27", + "id": "114", + "aggressive": "true", + "bonuses": "15,15,10,20,40,15,50,50,50,20,50,58,0,0,0", + "range_level": "27", + "attack_level": "27" + }, + { + "examine": "A large dim looking humanoid.", + "melee_animation": "359", + "range_animation": "359", + "attack_speed": "6", + "magic_level": "1", + "respawn_delay": "25", + "defence_animation": "360", + "magic_animation": "359", + "death_animation": "361", + "name": "Ogre", + "defence_level": "43", + "safespot": null, + "lifepoints": "60", + "strength_level": "43", + "id": "115", + "aggressive": "true", + "bonuses": "22,22,22,0,0,0,0,0,0,0,0,20,0,0,0", + "range_level": "1", + "attack_level": "43" + }, + { + "examine": "Big, ugly, and smelly.", + "melee_animation": "359", + "range_animation": "359", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "25", + "defence_animation": "360", + "weakness": "8", + "slayer_exp": "75", + "magic_animation": "359", + "death_animation": "361", + "name": "Cyclops", + "defence_level": "35", + "safespot": null, + "lifepoints": "75", + "strength_level": "65", + "id": "116", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "65" + }, + { + "examine": "A very large foe.", + "melee_animation": "4652", + "range_animation": "4652", + "combat_audio": "448,451,450", + "attack_speed": "6", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "4651", + "weakness": "6", + "slayer_exp": "35", + "magic_animation": "4652", + "death_animation": "4653", + "name": "Hill Giant", + "defence_level": "26", + "safespot": null, + "lifepoints": "35", + "strength_level": "22", + "id": "117", + "aggressive": "true", + "bonuses": "18,18,18,0,0,0,0,0,0,0,0,16,0,0,0", + "range_level": "1", + "attack_level": "18" + }, + { + "examine": "A short angry guy.", + "melee_animation": "99", + "range_animation": "0", + "attack_speed": "7", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "slayer_exp": "16", + "magic_animation": "0", + "death_animation": "102", + "name": "Dwarf", + "defence_level": "7", + "safespot": null, + "lifepoints": "10", + "strength_level": "7", + "id": "118", + "range_level": "1", + "attack_level": "7" + }, + { + "examine": "A dwarf gone bad.", + "melee_animation": "99", + "range_animation": "0", + "combat_audio": "2567,419,418", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "150", + "defence_animation": "0", + "weakness": "6", + "slayer_exp": "61", + "magic_animation": "0", + "death_animation": "102", + "name": "Chaos dwarf", + "defence_level": "28", + "safespot": null, + "lifepoints": "61", + "strength_level": "42", + "id": "119", + "aggressive": "true", + "bonuses": "13,13,13,0,0,40,34,25,10,35,0,9,0,0,0", + "range_level": "1", + "attack_level": "38" + }, + { + "examine": "A mountain dwelling short angry guy.", + "melee_animation": "99", + "range_animation": "0", + "attack_speed": "6", + "defence_animation": "0", + "weakness": "6", + "slayer_exp": "16", + "magic_animation": "0", + "death_animation": "102", + "name": "Dwarf", + "defence_level": "16", + "safespot": null, + "lifepoints": "26", + "strength_level": "16", + "id": "120", + "range_level": "1", + "attack_level": "15" + }, + { + "slayer_exp": "16", + "name": "Dwarf", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "121", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly smelly creature.", + "melee_animation": "164", + "range_animation": "164", + "combat_audio": "469,472,471", + "attack_speed": "6", + "defence_animation": "165", + "magic_animation": "164", + "death_animation": "167", + "name": "Hobgoblin", + "defence_level": "3", + "safespot": null, + "lifepoints": "29", + "strength_level": "10", + "id": "122", + "aggressive": "true", + "range_level": "20", + "attack_level": "20" + }, + { + "examine": "An ugly smelly creature.", + "melee_animation": "164", + "range_animation": "164", + "combat_audio": "3520,472,471", + "attack_speed": "6", + "defence_animation": "165", + "magic_animation": "164", + "death_animation": "167", + "name": "Hobgoblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "29", + "strength_level": "10", + "id": "123", + "aggressive": "true", + "range_level": "20", + "attack_level": "20" + }, + { + "examine": "A strange, inhuman, elemental warrior.", + "melee_animation": "393", + "range_animation": "0", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "0", + "weakness": "7", + "slayer_exp": "54", + "magic_animation": "0", + "death_animation": "836", + "name": "Earth warrior", + "defence_level": "42", + "safespot": null, + "lifepoints": "54", + "strength_level": "42", + "id": "124", + "aggressive": "true", + "bonuses": "0,0,0,0,0,30,40,20,10,30,0,0,0,0,0", + "range_level": "1", + "attack_level": "42" + }, + { + "examine": "A cold-hearted elemental warrior.", + "melee_animation": "451", + "range_animation": "451", + "combat_audio": "2500,530,529", + "attack_speed": "4", + "respawn_delay": "30", + "defence_animation": "404", + "weakness": "9", + "slayer_exp": "59", + "magic_animation": "451", + "death_animation": "843", + "name": "Ice warrior", + "defence_level": "47", + "safespot": null, + "lifepoints": "59", + "strength_level": "47", + "id": "125", + "aggressive": "true", + "bonuses": "0,0,0,0,0,30,40,20,10,30,0,0,0,0,0", + "clue_level": "1", + "range_level": "1", + "attack_level": "47" + }, + { + "examine": "Looks pretty otherworldly to me!", + "range_animation": "0", + "attack_speed": "5", + "magic_level": "45", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "5", + "magic_animation": "0", + "name": "Otherworldly being", + "defence_level": "45", + "safespot": null, + "lifepoints": "64", + "strength_level": "1", + "id": "126", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A magic axe with a mind of its own.", + "melee_animation": "185", + "range_animation": "0", + "combat_audio": "2498,12,1976", + "attack_speed": "4", + "respawn_delay": "30", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "188", + "name": "Magic axe", + "defence_level": "29", + "safespot": null, + "lifepoints": "44", + "strength_level": "38", + "id": "127", + "aggressive": "true", + "bonuses": "0,0,0,0,0,10,5,15,5,10,0,0,0,0,0", + "range_level": "1", + "attack_level": "38" + }, + { + "examine": "A slithering serpent.", + "melee_animation": "275", + "range_animation": "0", + "combat_audio": "3609,3608,3610", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "278", + "name": "Snake", + "defence_level": "3", + "safespot": null, + "lifepoints": "6", + "strength_level": "5", + "id": "128", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "4" + }, + { + "examine": "An inhabitant of icy regions.", + "melee_animation": "5669", + "range_animation": "0", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "5671", + "name": "Penguin", + "defence_level": "6", + "safespot": null, + "lifepoints": "8", + "strength_level": "6", + "id": "131", + "range_level": "1", + "attack_level": "6" + }, + { + "examine": "Perhaps our oldest relatives?", + "melee_animation": "220", + "range_animation": "0", + "combat_audio": "629,631,630", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "37", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "223", + "name": "Monkey", + "defence_level": "2", + "safespot": null, + "lifepoints": "6", + "strength_level": "3", + "id": "132", + "aggressive": "false", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "2" + }, + { + "examine": "A unicorn with a blackened heart.", + "melee_animation": "6376", + "range_animation": "6376", + "combat_audio": "369,371,370", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "90", + "defence_animation": "6375", + "weakness": "3", + "magic_animation": "6376", + "death_animation": "6377", + "name": "Black unicorn", + "defence_level": "23", + "safespot": null, + "lifepoints": "29", + "strength_level": "23", + "id": "133", + "aggressive": "false", + "range_level": "1", + "attack_level": "21" + }, + { + "examine": "A nasty, poisonous arachnid.", + "melee_animation": "5327", + "range_animation": "0", + "combat_audio": "537,539,538", + "attack_speed": "4", + "poisonous": "true", + "respawn_delay": "30", + "defence_animation": "5328", + "weakness": "2", + "poison_amount": "6", + "magic_animation": "0", + "death_animation": "5329", + "name": "Poison spider", + "safespot": null, + "defence_level": "52", + "lifepoints": "64", + "strength_level": "65", + "id": "134", + "aggressive": "true", + "range_level": "1", + "attack_level": "50" + }, + { + "examine": "Aaw", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Terrorchick gnome", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "137", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A giant raptor.", + "melee_animation": "1010", + "range_animation": "0", + "combat_audio": "832,834,833", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "1012", + "weakness": "6", + "magic_animation": "0", + "death_animation": "1013", + "name": "Terrorbird", + "defence_level": "19", + "safespot": null, + "lifepoints": "34", + "strength_level": "23", + "id": "138", + "aggressive": "false", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "23" + }, + { + "examine": "A giant raptor.", + "melee_animation": "1010", + "combat_audio": "832,834,833", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "1012", + "magic_animation": "0", + "death_animation": "1013", + "name": "Terrorbird", + "defence_level": "19", + "safespot": null, + "lifepoints": "34", + "strength_level": "23", + "id": "139", + "aggressive": "false", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "23" + }, + { + "examine": "A servant to Iban.", + "melee_animation": "338", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "340", + "name": "Souless", + "defence_level": "33", + "safespot": null, + "lifepoints": "47", + "strength_level": "33", + "id": "140", + "aggressive": "true", + "range_level": "1", + "attack_level": "33" + }, + { + "examine": "Must be the pack leader.", + "melee_animation": "6559", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "slayer_exp": "74", + "magic_animation": "0", + "death_animation": "6558", + "name": "Big Wolf", + "defence_level": "31", + "safespot": null, + "lifepoints": "44", + "strength_level": "31", + "id": "141", + "aggressive": "true", + "range_level": "1", + "attack_level": "31" + }, + { + "slayer_exp": "34", + "death_animation": "6558", + "name": "Wolf", + "defence_level": "1", + "safespot": null, + "lifepoints": "69", + "melee_animation": "6559", + "combat_audio": "481,491,490", + "strength_level": "1", + "id": "142", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A rare jungle wolf - specific to the Kharazi jungle.", + "melee_animation": "6559", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "slayer_exp": "69", + "magic_animation": "0", + "death_animation": "6558", + "name": "Jungle Wolf", + "defence_level": "63", + "safespot": null, + "lifepoints": "90", + "strength_level": "63", + "id": "143", + "aggressive": "true", + "range_level": "1", + "attack_level": "63" + }, + { + "examine": "Wow! Scorpions shouldn't grow that big.", + "melee_animation": "6254", + "range_animation": "0", + "combat_audio": "3611,3612,3610", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "2", + "slayer_exp": "17", + "magic_animation": "0", + "death_animation": "6256", + "name": "King Scorpion", + "defence_level": "28", + "safespot": null, + "lifepoints": "40", + "strength_level": "21", + "id": "144", + "aggressive": "true", + "range_level": "28", + "attack_level": "21" + }, + { + "examine": "A cold-hearted elemental warrior.", + "melee_animation": "451", + "range_animation": "451", + "combat_audio": "2500,530,529", + "attack_speed": "4", + "respawn_delay": "30", + "defence_animation": "404", + "weakness": "9", + "slayer_exp": "59", + "magic_animation": "451", + "death_animation": "843", + "name": "Ice warrior", + "defence_level": "47", + "safespot": null, + "lifepoints": "59", + "strength_level": "47", + "id": "145", + "aggressive": "true", + "bonuses": "0,0,0,0,0,30,40,20,10,30,0,0,0,0,0", + "clue_level": "1", + "range_level": "1", + "attack_level": "47" + }, + { + "examine": "A sea bird.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Gull", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "146", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A sea bird.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cormorant", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "147", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A sea bird.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Pelican", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "148", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "These look much better in the wild.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Butterfly", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "153", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "I love butterflies.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Butterfly", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "154", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A fighter from the supernatural world. He's a shadow of his former self.", + "melee_animation": "394", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "843", + "name": "Shadow warrior", + "defence_level": "47", + "safespot": null, + "lifepoints": "67", + "strength_level": "47", + "id": "158", + "aggressive": "true", + "range_level": "1", + "attack_level": "47" + }, + { + "examine": "Small, even by gnome standards.", + "melee_animation": "191", + "range_animation": "0", + "defence_animation": "193", + "weakness": "9", + "magic_animation": "0", + "death_animation": "196", + "name": "Gnome child", + "defence_level": "1", + "safespot": null, + "lifepoints": "2", + "strength_level": "1", + "id": "159", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Small, even by gnome standards.", + "melee_animation": "191", + "range_animation": "0", + "defence_animation": "193", + "weakness": "9", + "magic_animation": "0", + "death_animation": "196", + "name": "Gnome child", + "defence_level": "1", + "safespot": null, + "lifepoints": "2", + "strength_level": "1", + "id": "160", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Small, even by gnome standards.", + "melee_animation": "191", + "range_animation": "0", + "defence_animation": "193", + "weakness": "9", + "magic_animation": "0", + "death_animation": "196", + "name": "Gnome child", + "defence_level": "1", + "safespot": null, + "lifepoints": "2", + "strength_level": "1", + "id": "161", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He can advise on training.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Gnome trainer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "162", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A tree gnome guard.", + "melee_animation": "1218", + "range_animation": "0", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "1224", + "name": "Gnome guard", + "defence_level": "38", + "safespot": null, + "lifepoints": "54", + "strength_level": "38", + "id": "163", + "range_level": "1", + "attack_level": "38" + }, + { + "examine": "A tree gnome guard.", + "melee_animation": "192", + "range_animation": "0", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "196", + "name": "Gnome guard", + "defence_level": "38", + "safespot": null, + "lifepoints": "54", + "strength_level": "38", + "id": "164", + "range_level": "1", + "attack_level": "38" + }, + { + "examine": "A female gnome.", + "combat_style": "1", + "melee_animation": "191", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "196", + "name": "Gnome woman", + "defence_level": "30", + "safespot": null, + "lifepoints": "42", + "strength_level": "30", + "id": "168", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "A female gnome.", + "combat_style": "1", + "melee_animation": "191", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "196", + "name": "Gnome woman", + "defence_level": "30", + "safespot": null, + "lifepoints": "42", + "strength_level": "30", + "id": "169", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "One of Gielinor's many citizens", + "melee_animation": "422", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Man", + "defence_level": "3", + "safespot": null, + "lifepoints": "4", + "strength_level": "3", + "id": "170", + "clue_level": "0", + "range_level": "1", + "attack_level": "3" + }, + { + "examine": "He works evil magic.", + "combat_style": "2", + "melee_animation": "422", + "range_animation": "0", + "combat_audio": "511,513,512", + "magic_level": "27", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "4", + "magic_animation": "711", + "death_animation": "836", + "name": "Dark wizard", + "defence_level": "27", + "safespot": null, + "lifepoints": "24", + "strength_level": "1", + "id": "172", + "aggressive": "true", + "range_level": "1", + "attack_level": "1", + "prj_height": "3" + }, + { + "examine": "An evil user of Magic powers", + "melee_animation": "422", + "range_animation": "0", + "attack_speed": "5", + "magic_level": "30", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "4", + "magic_animation": "0", + "death_animation": "836", + "name": "Invrigar the Necromancer", + "defence_level": "30", + "safespot": null, + "lifepoints": "42", + "strength_level": "1", + "id": "173", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He works evil magic.", + "combat_style": "2", + "melee_animation": "422", + "range_animation": "0", + "combat_audio": "511,513,512", + "magic_level": "24", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "4", + "magic_animation": "711", + "death_animation": "836", + "name": "Dark wizard", + "defence_level": "24", + "safespot": null, + "lifepoints": "12", + "strength_level": "1", + "id": "174", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "agg_radius": "2", + "examine": "He jumps out and attacks people.", + "melee_animation": "422", + "range_animation": "0", + "combat_audio": "511,513,512", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Mugger", + "defence_level": "11", + "safespot": null, + "lifepoints": "15", + "strength_level": "11", + "id": "175", + "aggressive": "true", + "range_level": "1", + "attack_level": "11" + }, + { + "examine": "The hat's a dead give away.", + "melee_animation": "423", + "range_animation": "0", + "magic_level": "22", + "defence_animation": "0", + "weakness": "4", + "magic_animation": "0", + "death_animation": "836", + "name": "Witch", + "defence_level": "22", + "safespot": null, + "lifepoints": "31", + "strength_level": "1", + "id": "176", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A dark-hearted knight.", + "melee_animation": "390", + "range_animation": "0", + "combat_audio": "2503,15,512", + "attack_speed": "5", + "respawn_delay": "25", + "defence_animation": "388", + "weakness": "7", + "magic_animation": "0", + "death_animation": "836", + "name": "Black Knight", + "defence_level": "25", + "safespot": null, + "lifepoints": "42", + "strength_level": "25", + "id": "178", + "aggressive": "true", + "bonuses": "18,18,18,0,0,73,76,70,-11,72,0,16,0,0,0", + "range_level": "1", + "attack_level": "25" + }, + { + "examine": "A dark-hearted knight.", + "melee_animation": "390", + "combat_audio": "2503,15,512", + "attack_speed": "5", + "respawn_delay": "25", + "defence_animation": "388", + "death_animation": "836", + "name": "Black Knight", + "defence_level": "25", + "safespot": null, + "lifepoints": "42", + "strength_level": "25", + "id": "179", + "aggressive": "true", + "bonuses": "18,18,18,0,0,73,76,70,-11,72,0,16,0,0,0", + "range_level": "1", + "attack_level": "25" + }, + { + "examine": "He holds up passers by.", + "melee_animation": "799", + "range_animation": "799", + "combat_audio": "511,513,512", + "attack_speed": "5", + "defence_animation": "404", + "weakness": "7", + "magic_animation": "799", + "death_animation": "9055", + "name": "Highwayman", + "defence_level": "8", + "safespot": null, + "lifepoints": "13", + "strength_level": "8", + "id": "180", + "aggressive": "true", + "range_level": "1", + "attack_level": "8" + }, + { + "examine": "A crazy, evil druid.", + "start_gfx": "105", + "melee_animation": "422", + "range_animation": "422", + "attack_speed": "4", + "magic_level": "10", + "end_gfx": "107", + "respawn_delay": "25", + "defence_animation": "404", + "weakness": "3", + "slayer_exp": "0", + "magic_animation": "422", + "death_animation": "9055", + "name": "Chaos druid", + "defence_level": "12", + "safespot": null, + "lifepoints": "20", + "strength_level": "8", + "id": "181", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "projectile": "106", + "attack_level": "8" + }, + { + "melee_animation": "422", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "20", + "strength_level": "1", + "id": "182", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "422", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "20", + "strength_level": "1", + "id": "183", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "422", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "23", + "strength_level": "1", + "id": "184", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "703,705,704", + "strength_level": "1", + "id": "185", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Low on brains, high on aggression.", + "melee_animation": "386", + "range_animation": "0", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "50", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Thug", + "defence_level": "9", + "safespot": null, + "lifepoints": "18", + "strength_level": "5", + "id": "186", + "aggressive": "true", + "clue_level": "0", + "bonuses": "5,5,5,0,0,2,3,3,0,0,0,5,0,0,0", + "range_level": "1", + "attack_level": "7" + }, + { + "examine": "An evil human cleric.", + "start_gfx": "99", + "combat_style": "2", + "combat_audio": "511,513,512", + "melee_animation": "422", + "range_animation": "0", + "attack_speed": "4", + "magic_level": "25", + "end_gfx": "101", + "respawn_delay": "60", + "defence_animation": "404", + "weakness": "5", + "magic_animation": "711", + "death_animation": "836", + "name": "Monk of Zamorak", + "defence_level": "22", + "safespot": null, + "lifepoints": "20", + "strength_level": "18", + "id": "188", + "aggressive": "true", + "range_level": "1", + "projectile": "100", + "attack_level": "18" + }, + { + "examine": "An evil human cleric.", + "start_gfx": "99", + "combat_style": "2", + "combat_audio": "511,513,512", + "melee_animation": "422", + "range_animation": "0", + "attack_speed": "4", + "magic_level": "25", + "end_gfx": "101", + "respawn_delay": "60", + "defence_animation": "404", + "weakness": "5", + "magic_animation": "711", + "death_animation": "836", + "name": "Monk of Zamorak", + "defence_level": "12", + "safespot": null, + "lifepoints": "10", + "strength_level": "8", + "id": "189", + "aggressive": "true", + "range_level": "1", + "projectile": "100", + "attack_level": "8" + }, + { + "examine": "An evil human cleric.", + "start_gfx": "99", + "combat_style": "2", + "combat_audio": "511,513,512", + "melee_animation": "422", + "range_animation": "0", + "attack_speed": "4", + "magic_level": "40", + "end_gfx": "101", + "respawn_delay": "60", + "defence_animation": "404", + "weakness": "5", + "magic_animation": "711", + "death_animation": "836", + "name": "Monk of Zamorak", + "defence_level": "42", + "safespot": null, + "lifepoints": "40", + "strength_level": "38", + "id": "190", + "aggressive": "true", + "range_level": "1", + "projectile": "100", + "attack_level": "38" + }, + { + "examine": "A primitive warrior.", + "melee_animation": "428", + "range_animation": "0", + "attack_speed": "4", + "poisonous": "true", + "magic_level": "1", + "respawn_delay": "50", + "defence_animation": "0", + "weakness": "8", + "poison_amount": "11", + "magic_animation": "0", + "death_animation": "836", + "name": "Tribesman", + "defence_level": "26", + "safespot": null, + "lifepoints": "39", + "strength_level": "27", + "id": "191", + "aggressive": "true", + "clue_level": "1", + "bonuses": "8,8,8,0,0,4,6,6,0,0,0,5,0,0,0", + "range_level": "1", + "attack_level": "23" + }, + { + "examine": "A warrior of Darkness.", + "melee_animation": "451", + "attack_speed": "5", + "respawn_delay": "20", + "defence_animation": "388", + "weakness": "8", + "death_animation": "9055", + "name": "Dark warrior", + "defence_level": "10", + "safespot": null, + "lifepoints": "10", + "strength_level": "10", + "id": "192", + "bonuses": "1,1,1,1,1,1,1,1,1,1,1,1,1,1,1", + "range_level": "1", + "attack_level": "10" + }, + { + "examine": "A crazy evil druid.", + "start_gfx": "105", + "melee_animation": "422", + "range_animation": "422", + "attack_speed": "4", + "magic_level": "10", + "respawn_delay": "25", + "end_gfx": "107", + "defence_animation": "404", + "weakness": "3", + "magic_animation": "422", + "death_animation": "836", + "name": "Chaos druid warrior", + "defence_level": "12", + "safespot": null, + "lifepoints": "20", + "strength_level": "8", + "id": "193", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "projectile": "106", + "attack_level": "8" + }, + { + "examine": "A crazy evil necromancer.", + "melee_animation": "422", + "range_animation": "0", + "magic_level": "28", + "defence_animation": "0", + "weakness": "5", + "magic_animation": "0", + "death_animation": "836", + "name": "Necromancer", + "defence_level": "28", + "safespot": null, + "lifepoints": "40", + "strength_level": "1", + "id": "194", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Bandit Camp guard.", + "melee_animation": "386", + "range_animation": "0", + "defence_animation": "0", + "weakness": "1", + "magic_animation": "0", + "death_animation": "836", + "name": "Guard Bandit", + "defence_level": "20", + "safespot": null, + "lifepoints": "28", + "strength_level": "1", + "id": "196", + "range_level": "20", + "attack_level": "1" + }, + { + "examine": "Master of the Champions' Guild.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Guildmaster", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "198", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A mighty warrior!", + "melee_animation": "395", + "range_animation": "0", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "836", + "name": "Gunthor the Brave", + "defence_level": "29", + "safespot": null, + "lifepoints": "41", + "strength_level": "29", + "id": "199", + "range_level": "1", + "attack_level": "29" + }, + { + "examine": "Guards prisoners for the black knights.", + "melee_animation": "422", + "range_animation": "0", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "50", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "836", + "name": "Jailer", + "defence_level": "40", + "safespot": null, + "lifepoints": "47", + "strength_level": "40", + "id": "201", + "aggressive": "false", + "bonuses": "0,0,0,0,0,79,63,47,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "Has a fearsome scowl.", + "melee_animation": "390", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "836", + "name": "Black Heather", + "defence_level": "28", + "lifepoints": "40", + "strength_level": "28", + "id": "202", + "range_level": "1", + "attack_level": "28" + }, + { + "examine": "A rocky slug.", + "melee_animation": "1595", + "range_animation": "1595", + "combat_audio": "729,731,730", + "attack_speed": "5", + "magic_level": "1", + "defence_animation": "1596", + "weakness": "7", + "magic_animation": "1595", + "death_animation": "1597", + "name": "Rockslug", + "defence_level": "30", + "safespot": null, + "lifepoints": "30", + "strength_level": "30", + "id": "1631", + "clue_level": "2", + "range_level": "1", + "attack_level": "24" + }, + { + "examine": "A rocky slug.", + "melee_animation": "1595", + "range_animation": "1595", + "combat_audio": "729,731,730", + "attack_speed": "5", + "magic_level": "1", + "defence_animation": "1596", + "weakness": "7", + "magic_animation": "1595", + "death_animation": "1597", + "name": "Rockslug", + "defence_level": "30", + "safespot": null, + "lifepoints": "30", + "strength_level": "30", + "id": "1632", + "clue_level": "2", + "range_level": "1", + "attack_level": "24" + }, + { + "examine": "Has a fearsome posture.", + "melee_animation": "390", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Donny the Lad", + "defence_level": "28", + "safespot": null, + "lifepoints": "40", + "strength_level": "28", + "id": "203", + "range_level": "1", + "attack_level": "28" + }, + { + "examine": "Nice hair.", + "melee_animation": "390", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "836", + "name": "Speedy Keith", + "defence_level": "28", + "safespot": null, + "lifepoints": "40", + "strength_level": "28", + "id": "204", + "range_level": "1", + "attack_level": "28" + }, + { + "examine": "A crazy evil druid.", + "melee_animation": "422", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "836", + "name": "Salarin the Twisted", + "defence_level": "62", + "safespot": null, + "lifepoints": "70", + "strength_level": "58", + "id": "205", + "aggressive": "true", + "bonuses": "45,50,43,55,39,31,19,28,33,22,22,15,13,9,8", + "range_level": "1", + "attack_level": "58" + }, + { + "examine": "A dwarven guard.", + "melee_animation": "99", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "102", + "name": "Guard", + "defence_level": "12", + "safespot": null, + "lifepoints": "17", + "strength_level": "12", + "id": "206", + "aggressive": "false", + "clue_level": "1", + "range_level": "1", + "attack_level": "12" + }, + { + "examine": "The head honcho around here.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Captain Lawgof", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "208", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "She looks serene.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Grail Maiden", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "210", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A former Knight of the Round Table.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "King Percival", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "212", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He looks unhappy...", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Peasant", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "214", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "High Priest of Entrana.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "High Priest", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "216", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It's a fisherman.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fisherman", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "219", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He doesn't look very well...", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "The Fisher King", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "220", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He looks mean and powerful.", + "melee_animation": "128", + "range_animation": "0", + "attack_speed": "7", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "131", + "name": "Black Knight Titan", + "defence_level": "91", + "safespot": null, + "lifepoints": "142", + "strength_level": "100", + "id": "221", + "aggressive": "true", + "bonuses": "27,27,27,0,0,18,27,18,1000,1000,0,0,0,0,0", + "range_level": "1", + "attack_level": "91" + }, + { + "examine": "A holy man.", + "melee_animation": "422", + "range_animation": "0", + "combat_audio": "511,513,512", + "magic_level": "10", + "defence_animation": "0", + "weakness": "5", + "magic_animation": "0", + "death_animation": "836", + "name": "Monk", + "defence_level": "10", + "safespot": null, + "lifepoints": "14", + "strength_level": "7", + "id": "222", + "range_level": "1", + "attack_level": "7" + }, + { + "examine": "A peaceful monk.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Brother Kojo", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "223", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A dirty rat.", + "melee_animation": "4933", + "range_animation": "0", + "combat_audio": "703,705,704", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "4935", + "name": "Dungeon rat", + "defence_level": "8", + "safespot": null, + "lifepoints": "11", + "strength_level": "8", + "id": "224", + "aggressive": "true", + "range_level": "1", + "attack_level": "8" + }, + { + "examine": "He looks elderly.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Grandpa Jack", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "230", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He likes to cut down trees.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Forester", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "231", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "I can fish here.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fishing spot", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "233", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He isn't very friendly.", + "melee_animation": "6489", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "6490", + "name": "Renegade Knight", + "defence_level": "15", + "safespot": null, + "lifepoints": "42", + "strength_level": "15", + "id": "237", + "aggressive": "true", + "range_level": "1", + "attack_level": "15" + }, + { + "examine": "A terrifying spirit.", + "melee_animation": "5540", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "5542", + "name": "Thrantax the Mighty", + "defence_level": "50", + "safespot": null, + "lifepoints": "142", + "strength_level": "50", + "id": "238", + "range_level": "1", + "attack_level": "50" + }, + { + "examine": "Specialist meat transporter.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "2301", + "name": "Teapotspout", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "246", + "range_level": "1", + "attack_level": "1" + }, + { + "death_animation": "6490", + "name": "Sir Mordred", + "defence_level": "1", + "safespot": null, + "lifepoints": "50", + "melee_animation": "6489", + "strength_level": "1", + "id": "247", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1", + "defence_animation": "6488" + }, + { + "examine": "Legendary King of the Britons.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "King Arthur", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "251", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It's one of General Khazard's guards.", + "melee_animation": "395", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "6", + "respawn_delay": "60", + "defence_animation": "397", + "weakness": "6", + "magic_animation": "0", + "death_animation": "836", + "name": "Khazard Guard", + "defence_level": "22", + "safespot": null, + "lifepoints": "31", + "strength_level": "22", + "id": "253", + "range_level": "1", + "attack_level": "22" + }, + { + "examine": "He's been guarding the tavern for a bit too long.", + "melee_animation": "395", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "6", + "respawn_delay": "60", + "defence_animation": "397", + "weakness": "6", + "magic_animation": "0", + "death_animation": "836", + "name": "Khazard Guard", + "defence_level": "22", + "safespot": null, + "lifepoints": "31", + "strength_level": "22", + "id": "254", + "range_level": "1", + "attack_level": "22" + }, + { + "examine": "His armour indicates he's a Khazard Guard.", + "melee_animation": "395", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "6", + "respawn_delay": "60", + "defence_animation": "397", + "weakness": "6", + "magic_animation": "0", + "death_animation": "836", + "name": "Khazard Guard", + "defence_level": "22", + "safespot": null, + "lifepoints": "31", + "strength_level": "22", + "id": "255", + "range_level": "1", + "attack_level": "22" + }, + { + "examine": "His armour indicates he's a Khazard Guard.", + "melee_animation": "395", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "6", + "respawn_delay": "60", + "defence_animation": "397", + "weakness": "6", + "magic_animation": "0", + "death_animation": "836", + "name": "Khazard Guard", + "defence_level": "22", + "safespot": null, + "lifepoints": "31", + "strength_level": "22", + "id": "256", + "range_level": "1", + "attack_level": "22" + }, + { + "examine": "He takes the slaves to the arena. He rarely takes them back..", + "melee_animation": "395", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "6", + "respawn_delay": "60", + "defence_animation": "397", + "weakness": "6", + "magic_animation": "0", + "death_animation": "836", + "name": "Khazard Guard", + "defence_level": "22", + "safespot": null, + "lifepoints": "31", + "strength_level": "22", + "id": "257", + "range_level": "1", + "attack_level": "22" + }, + { + "examine": "He looks really nasty. Smells bad too.", + "melee_animation": "7049", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "4", + "respawn_delay": "60", + "defence_animation": "7050", + "weakness": "6", + "magic_animation": "0", + "death_animation": "836", + "name": "General Khazard", + "defence_level": "80", + "safespot": null, + "lifepoints": "170", + "strength_level": "78", + "id": "258", + "range_level": "1", + "attack_level": "75" + }, + { + "examine": "A tough looking barman.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "6", + "respawn_delay": "60", + "defence_animation": "397", + "weakness": "6", + "magic_animation": "0", + "death_animation": "0", + "name": "Khazard barman", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "259", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A slave fighter. He looks mistreated and weak.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fightslave", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "262", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "She looks wealthy.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Lady Servil", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "264", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A young squire. He looks worse for wear.", + "magic_animation": "0", + "death_animation": "0", + "name": "Jeremy Servil", + "defence_level": "0", + "safespot": null, + "lifepoints": "10", + "strength_level": "0", + "id": "265", + "clue_level": "0", + "range_level": "0", + "attack_level": "0" + }, + { + "examine": "A young squire. He looks worse for wear.", + "magic_animation": "0", + "death_animation": "0", + "name": "Jeremy Servil", + "defence_level": "0", + "safespot": null, + "lifepoints": "10", + "strength_level": "0", + "id": "266", + "clue_level": "0", + "range_level": "0", + "attack_level": "0" + }, + { + "examine": "Jeremy father, Sir Servil.", + "magic_animation": "0", + "death_animation": "0", + "name": "Justin Servil", + "defence_level": "0", + "safespot": null, + "lifepoints": "10", + "strength_level": "0", + "id": "267", + "clue_level": "0", + "range_level": "0", + "attack_level": "0" + }, + { + "examine": "A scruffy looking chap.", + "magic_animation": "0", + "death_animation": "0", + "name": "Local", + "defence_level": "0", + "safespot": null, + "lifepoints": "10", + "strength_level": "0", + "id": "268", + "clue_level": "0", + "range_level": "0", + "attack_level": "0" + }, + { + "melee_animation": "6581", + "respawn_delay": "60", + "defence_animation": "6578", + "death_animation": "6576", + "name": "Bouncer", + "defence_level": "120", + "safespot": null, + "lifepoints": "116", + "strength_level": "120", + "id": "269", + "aggressive": "true", + "range_level": "1", + "attack_level": "120" + }, + { + "examine": "Khazard's strongest ogre warrior.", + "melee_animation": "359", + "range_animation": "359", + "attack_speed": "6", + "magic_level": "1", + "respawn_delay": "25", + "defence_animation": "360", + "magic_animation": "359", + "death_animation": "361", + "name": "Khazard Ogre", + "defence_level": "46", + "safespot": null, + "lifepoints": "65", + "strength_level": "46", + "id": "270", + "aggressive": "true", + "bonuses": "22,22,22,0,0,0,0,0,0,0,0,20,0,0,0", + "range_level": "1", + "attack_level": "46" + }, + { + "examine": "A large angry scorpion", + "melee_animation": "6254", + "range_animation": "0", + "combat_audio": "3611,3612,3610", + "defence_animation": "0", + "weakness": "2", + "magic_animation": "0", + "death_animation": "6256", + "name": "Khazard Scorpion", + "defence_level": "36", + "safespot": null, + "lifepoints": "51", + "strength_level": "27", + "id": "271", + "aggressive": "true", + "range_level": "36", + "attack_level": "27" + }, + { + "examine": "He walks with a slight limp.", + "melee_animation": "401", + "range_animation": "0", + "combat_audio": "511,513,512", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "404", + "weakness": "", + "magic_animation": "0", + "death_animation": "836", + "name": "Lucien", + "defence_level": "10", + "safespot": null, + "lifepoints": "17", + "strength_level": "11", + "id": "272", + "aggressive": "", + "range_level": "1", + "attack_level": "12" + }, + { + "examine": "He walks with a slight limp.", + "melee_animation": "", + "range_animation": "", + "combat_audio": "", + "defence_animation": "404", + "weakness": "", + "magic_animation": "", + "death_animation": "836", + "name": "Lucien", + "defence_level": "", + "safespot": null, + "lifepoints": "", + "strength_level": "", + "id": "273", + "aggressive": "", + "range_level": "", + "attack_level": "12" + }, + { + "examine": "A guard who has devoted their life to Armadyl.", + "range_animation": "0", + "melee_animation": "401", + "combat_audio": "511,513,512", + "respawn_delay": "60", + "defence_animation": "404", + "weakness": "8", + "magic_animation": "0", + "death_animation": "836", + "name": "Guardian of Armadyl", + "defence_level": "30", + "safespot": null, + "lifepoints": "42", + "strength_level": "30", + "id": "274", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "A guard who has devoted their life to Armadyl.", + "range_animation": "0", + "melee_animation": "401", + "combat_audio": "511,513,512", + "respawn_delay": "60", + "defence_animation": "404", + "weakness": "8", + "magic_animation": "0", + "death_animation": "836", + "name": "Guardian of Armadyl", + "defence_level": "30", + "safespot": null, + "lifepoints": "42", + "strength_level": "30", + "id": "275", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "Intimidating!", + "start_gfx": "99", + "combat_style": "2", + "start_height": "96", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "8", + "magic_level": "62", + "end_gfx": "101", + "respawn_delay": "60", + "defence_animation": "425", + "weakness": "3", + "magic_animation": "711", + "death_animation": "836", + "name": "Fire Warrior of Lesarkus", + "defence_level": "78", + "safespot": null, + "lifepoints": "59", + "strength_level": "78", + "id": "277", + "range_level": "1", + "projectile": "127", + "attack_level": "55" + }, + { + "examine": "Lumbridge Castle's head cook.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cook", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "278", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An old monk.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Brother Omad", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "279", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An old drunk monk.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Brother Cedric", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "280", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An Ardougne Monk.", + "melee_animation": "422", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Monk", + "defence_level": "4", + "safespot": null, + "lifepoints": "5", + "strength_level": "4", + "id": "281", + "range_level": "1", + "attack_level": "4" + }, + { + "examine": "A dastardly blanket thief.", + "melee_animation": "386", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Thief", + "defence_level": "15", + "safespot": null, + "lifepoints": "21", + "strength_level": "15", + "id": "282", + "range_level": "1", + "attack_level": "15" + }, + { + "examine": "The head of the treacherous blanket stealing gang.", + "melee_animation": "390", + "range_animation": "0", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Head Thief", + "defence_level": "18", + "safespot": null, + "lifepoints": "25", + "strength_level": "18", + "id": "283", + "range_level": "1", + "attack_level": "18" + }, + { + "examine": "A dwarf smith. Quite handy with a hammer.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Doric", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "284", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "She doesn't look too happy.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Veronica", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "285", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Yep. Definitely a chicken.", + "melee_animation": "5387", + "range_animation": "5387", + "combat_audio": "355,357,356", + "attack_speed": "6", + "respawn_delay": "18", + "defence_animation": "5388", + "magic_animation": "5387", + "death_animation": "5389", + "name": "Chicken", + "defence_level": "1", + "safespot": null, + "lifepoints": "3", + "strength_level": "1", + "id": "288", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An official of Ardougne.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Councillor Halgrive", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "289", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A serious-looking doctor.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Doctor Orbon", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "290", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A farmer who's seen happier times.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Farmer Brumty", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "291", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He tries to keep order around here.", + "melee_animation": "7218", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "7219", + "name": "Guard", + "defence_level": "25", + "safespot": null, + "lifepoints": "35", + "strength_level": "25", + "id": "296", + "clue_level": "1", + "range_level": "1", + "attack_level": "25" + }, + { + "examine": "He tries to keep order around here.", + "melee_animation": "7218", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "7220", + "name": "Guard", + "defence_level": "25", + "safespot": null, + "lifepoints": "35", + "strength_level": "25", + "id": "297", + "clue_level": "1", + "range_level": "1", + "attack_level": "25" + }, + { + "examine": "He tries to keep order around here.", + "melee_animation": "7218", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "7219", + "name": "Guard", + "defence_level": "25", + "safespot": null, + "lifepoints": "35", + "strength_level": "25", + "id": "298", + "clue_level": "1", + "range_level": "1", + "attack_level": "25" + }, + { + "examine": "He tries to keep order around here.", + "melee_animation": "583", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "7213", + "name": "Guard", + "defence_level": "25", + "safespot": null, + "lifepoints": "35", + "strength_level": "25", + "id": "299", + "clue_level": "1", + "range_level": "1", + "attack_level": "25" + }, + { + "examine": "An old motherly witch with a curious smile and a hooked nose.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Hetty", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "307", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The man in charge of the fishing guild.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Master fisher", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "308", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He has a colourful personality.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Da Vinci", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "336", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He's ready for a bet.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Chancy", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "338", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He's ready for a bet.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Chancy", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "339", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He's drunk.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Hops", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "340", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He's drunk.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Hops", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "341", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "She looks rather concerned.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Guidor's wife", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "342", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He tries to keep order around here.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "344", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He tries to keep order around here.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "345", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "346", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of Gielinor's many citizens.", + "melee_animation": "422", + "range_animation": "", + "combat_audio": "511,513,512", + "attack_speed": "4", + "defence_animation": "404", + "weakness": "", + "magic_animation": "", + "death_animation": "836", + "name": "Man", + "defence_level": "1", + "safespot": null, + "lifepoints": "13", + "strength_level": "1", + "id": "351", + "clue_level": "", + "bonuses": "0,0,0,0,0,1,1,1,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "2" + }, + { + "examine": "One of Gielinor's many citizens.", + "melee_animation": "422", + "range_animation": "", + "combat_audio": "511,506,505", + "attack_speed": "4", + "respawn_delay": "50", + "defence_animation": "404", + "weakness": "", + "magic_animation": "", + "death_animation": "836", + "name": "Woman", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "352", + "clue_level": "", + "bonuses": "0,0,0,0,0,1,1,1,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "2" + }, + { + "examine": "One of Gielinor's many citizens.", + "melee_animation": "422", + "range_animation": "", + "combat_audio": "511,506,505", + "attack_speed": "4", + "respawn_delay": "50", + "defence_animation": "404", + "weakness": "", + "magic_animation": "", + "death_animation": "836", + "name": "Woman", + "defence_level": "1", + "safespot": null, + "lifepoints": "13", + "strength_level": "1", + "id": "353", + "clue_level": "", + "bonuses": "0,0,0,0,0,1,1,1,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "2" + }, + { + "examine": "One of Gielinor's many citizens.", + "melee_animation": "422", + "range_animation": "", + "combat_audio": "511,506,505", + "attack_speed": "4", + "respawn_delay": "50", + "defence_animation": "404", + "weakness": "", + "magic_animation": "", + "death_animation": "836", + "name": "Woman", + "defence_level": "1", + "safespot": null, + "lifepoints": "13", + "strength_level": "1", + "id": "354", + "clue_level": "", + "bonuses": "0,0,0,0,0,1,1,1,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "2" + }, + { + "examine": "A child of West Ardougne.", + "melee_animation": "", + "range_animation": "", + "magic_level": "", + "defence_animation": "", + "poison_amount": "", + "magic_animation": "", + "death_animation": "", + "name": "Child", + "defence_level": "", + "safespot": null, + "movement_radius": "", + "lifepoints": "", + "strength_level": "", + "id": "355", + "range_level": "", + "attack_level": "" + }, + { + "examine": "A child of West Ardougne.", + "melee_animation": "", + "range_animation": "", + "magic_level": "", + "defence_animation": "", + "poison_amount": "", + "magic_animation": "", + "death_animation": "", + "name": "Child", + "defence_level": "", + "safespot": null, + "movement_radius": "", + "lifepoints": "", + "strength_level": "", + "id": "356", + "range_level": "", + "attack_level": "" + }, + { + "examine": "A holy man.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Priest", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "358", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of Gielinor's many citizens.", + "melee_animation": "422", + "range_animation": "422", + "combat_audio": "511,513,512", + "attack_speed": "4", + "magic_level": "6", + "respawn_delay": "18", + "defence_animation": "404", + "weakness": "9", + "magic_animation": "422", + "death_animation": "9055", + "name": "Man", + "defence_level": "5", + "safespot": null, + "lifepoints": "7", + "strength_level": "2", + "id": "359", + "clue_level": "0", + "range_level": "1", + "attack_level": "5" + }, + { + "examine": "One of Gielinor's many citizens.", + "melee_animation": "422", + "range_animation": "", + "combat_audio": "511,506,505", + "attack_speed": "4", + "respawn_delay": "50", + "defence_animation": "404", + "weakness": "", + "magic_animation": "", + "death_animation": "836", + "name": "Woman", + "defence_level": "1", + "safespot": null, + "lifepoints": "13", + "strength_level": "1", + "id": "360", + "clue_level": "", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "2" + }, + { + "examine": "One of Gielinor's many citizens.", + "melee_animation": "422", + "range_animation": "422", + "combat_audio": "511,506,505", + "attack_speed": "4", + "respawn_delay": "50", + "defence_animation": "404", + "weakness": "", + "magic_animation": "", + "death_animation": "836", + "name": "Woman", + "defence_level": "10", + "safespot": null, + "lifepoints": "13", + "strength_level": "10", + "id": "361", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "10" + }, + { + "examine": "One of Gielinor's many citizens.", + "melee_animation": "422", + "range_animation": "", + "combat_audio": "511,506,505", + "attack_speed": "4", + "respawn_delay": "50", + "defence_animation": "404", + "weakness": "", + "magic_animation": "", + "death_animation": "836", + "name": "Woman", + "defence_level": "2", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "362", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of Gielinor's many citizens.", + "melee_animation": "422", + "range_animation": "", + "combat_audio": "511,506,505", + "attack_speed": "4", + "respawn_delay": "50", + "defence_animation": "404", + "weakness": "", + "magic_animation": "", + "death_animation": "836", + "name": "Woman", + "defence_level": "10", + "safespot": null, + "lifepoints": "23", + "strength_level": "10", + "id": "363", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "10" + }, + { + "examine": "King Lathas of East Ardougne.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "King Lathas", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "364", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A holy warrior.", + "name": "Paladin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "365", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Smells very chemically...", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Chemist", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "367", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He tries to keep order around here.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "368", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "She's quite a looker!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Nurse Sarah", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "373", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Big, ugly, and smelly.", + "melee_animation": "359", + "range_animation": "359", + "attack_speed": "6", + "magic_level": "27", + "respawn_delay": "25", + "defence_animation": "360", + "weakness": "8", + "magic_animation": "359", + "death_animation": "361", + "name": "Ogre", + "defence_level": "27", + "safespot": null, + "lifepoints": "60", + "strength_level": "27", + "id": "374", + "aggressive": "true", + "bonuses": "15,15,10,20,40,15,50,50,50,20,50,58,0,0,0", + "range_level": "27", + "attack_level": "27" + }, + { + "examine": "A pirate. Smells of brine and brimstone. Also vomit.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "498,500,499", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Redbeard Frank", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "375", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Inspects people's packages.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Customs officer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "380", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A dwarf who looks after the mining guild.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "slayer_exp": "16", + "magic_animation": "0", + "death_animation": "0", + "name": "Dwarf", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "382", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Not very civilised looking.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Barbarian guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "384", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Looks vicious!", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "3611,3612,3610", + "respawn_delay": "60", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Kharid Scorpion", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "385", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Looks vicious!", + "name": "Kharid Scorpion", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "3611,3612,3610", + "strength_level": "1", + "id": "386", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "examine": "Looks vicious!", + "name": "Kharid Scorpion", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "3611,3612,3610", + "strength_level": "1", + "id": "387", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "examine": "Could do with a shave...", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "slayer_exp": "25", + "magic_animation": "0", + "death_animation": "0", + "name": "Seer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "388", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A brightly coloured game bird.", + "melee_animation": "2371", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "2373", + "name": "Big fish", + "defence_level": "3", + "safespot": null, + "lifepoints": "1", + "strength_level": "3", + "id": "390", + "range_level": "1", + "attack_level": "3" + }, + { + "examine": "Likes fish... hates people.", + "melee_animation": "284", + "range_animation": "0", + "attack_speed": "4", + "magic_level": "1", + "defence_animation": "285", + "magic_animation": "0", + "death_animation": "287", + "name": "River troll", + "defence_level": "32", + "safespot": null, + "lifepoints": "35", + "strength_level": "32", + "id": "392", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "32" + }, + { + "examine": "Beefy.", + "melee_animation": "5849", + "range_animation": "5849", + "combat_audio": "369,371,370", + "attack_speed": "5", + "defence_animation": "5850", + "weakness": "8", + "slayer_exp": "8", + "magic_animation": "5849", + "death_animation": "5851", + "name": "Cow", + "defence_level": "1", + "safespot": null, + "lifepoints": "8", + "strength_level": "1", + "id": "397", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A Legends Guild guard; he protects the entrance to the Legends Guild.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Legends guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "398", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He deals in exotic types of wood.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Jungle forester", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "401", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "She deals in exotic types of wood.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Jungle forester", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "402", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Insects buzzing around.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "819,821,820", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Swarm", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "411", + "aggressive": "false", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An annoying flappy thing.", + "melee_animation": "4915", + "range_animation": "4915", + "attack_speed": "5", + "magic_level": "10", + "respawn_delay": "30", + "defence_animation": "4916", + "weakness": "4", + "slayer_exp": "8", + "death_animation": "4918", + "name": "Bat", + "defence_level": "2", + "safespot": null, + "lifepoints": "8", + "strength_level": "1", + "id": "412", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Dead man walking.", + "melee_animation": "5578", + "range_animation": "5578", + "combat_audio": "931,923,922", + "attack_speed": "5", + "magic_level": "5", + "defence_animation": "5574", + "magic_animation": "5578", + "death_animation": "5575", + "name": "Zombie", + "defence_level": "20", + "safespot": null, + "lifepoints": "14", + "strength_level": "5", + "id": "419", + "range_level": "5", + "attack_level": "5" + }, + { + "examine": "Dead man walking.", + "melee_animation": "5578", + "range_animation": "5578", + "combat_audio": "931,923,922", + "attack_speed": "5", + "magic_level": "10", + "defence_animation": "5574", + "magic_animation": "5578", + "death_animation": "5575", + "name": "Zombie", + "defence_level": "40", + "safespot": null, + "lifepoints": "14", + "strength_level": "10", + "id": "420", + "range_level": "10", + "attack_level": "10" + }, + { + "examine": "Dead man walking.", + "melee_animation": "5578", + "range_animation": "5578", + "combat_audio": "931,923,922", + "attack_speed": "5", + "magic_level": "15", + "defence_animation": "5574", + "magic_animation": "5578", + "death_animation": "5575", + "name": "Zombie", + "defence_level": "50", + "safespot": null, + "lifepoints": "30", + "strength_level": "15", + "id": "421", + "range_level": "15", + "attack_level": "15" + }, + { + "examine": "Dead man walking.", + "melee_animation": "5578", + "range_animation": "5578", + "combat_audio": "931,923,922", + "attack_speed": "5", + "magic_level": "45", + "defence_animation": "5574", + "magic_animation": "5578", + "death_animation": "5575", + "name": "Zombie", + "defence_level": "60", + "safespot": null, + "lifepoints": "79", + "strength_level": "45", + "id": "422", + "range_level": "45", + "attack_level": "45" + }, + { + "examine": "Dead man walking.", + "melee_animation": "5578", + "range_animation": "5578", + "combat_audio": "931,923,922", + "attack_speed": "5", + "magic_level": "35", + "defence_animation": "5574", + "magic_animation": "5578", + "death_animation": "5575", + "name": "Zombie", + "defence_level": "70", + "safespot": null, + "lifepoints": "120", + "strength_level": "45", + "id": "423", + "range_level": "45", + "attack_level": "45" + }, + { + "examine": "Dead man walking.", + "melee_animation": "5578", + "range_animation": "5578", + "combat_audio": "931,923,922", + "attack_speed": "5", + "magic_level": "45", + "defence_animation": "5574", + "magic_animation": "5578", + "death_animation": "5575", + "name": "Zombie", + "defence_level": "90", + "safespot": null, + "lifepoints": "159", + "strength_level": "45", + "id": "424", + "range_level": "45", + "attack_level": "45" + }, + { + "examine": "Dead but not gone.", + "melee_animation": "390", + "range_animation": "0", + "combat_audio": "511,439,438", + "respawn_delay": "50", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Shade", + "defence_level": "7", + "safespot": null, + "lifepoints": "8", + "strength_level": "6", + "id": "425", + "range_level": "1", + "attack_level": "6" + }, + { + "examine": "Dead but not gone.", + "melee_animation": "390", + "range_animation": "0", + "combat_audio": "511,439,438", + "respawn_delay": "50", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Shade", + "defence_level": "30", + "safespot": null, + "lifepoints": "17", + "strength_level": "20", + "id": "426", + "range_level": "1", + "attack_level": "20" + }, + { + "examine": "Dead but not gone.", + "melee_animation": "390", + "range_animation": "0", + "combat_audio": "511,439,438", + "respawn_delay": "50", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Shade", + "defence_level": "45", + "safespot": null, + "lifepoints": "28", + "strength_level": "43", + "id": "427", + "range_level": "1", + "attack_level": "43" + }, + { + "examine": "Dead but not gone.", + "melee_animation": "390", + "range_animation": "0", + "combat_audio": "511,439,438", + "respawn_delay": "50", + "defence_animation": "0", + "weakness": "9", + "slayer_exp": "4.2", + "magic_animation": "0", + "death_animation": "836", + "name": "Shade", + "defence_level": "80", + "safespot": null, + "lifepoints": "42", + "strength_level": "74", + "id": "428", + "range_level": "1", + "attack_level": "74" + }, + { + "examine": "Dead but not gone.", + "melee_animation": "390", + "range_animation": "0", + "combat_audio": "511,439,438", + "magic_level": "1", + "respawn_delay": "50", + "defence_animation": "0", + "weakness": "9", + "slayer_exp": "4.2", + "magic_animation": "0", + "death_animation": "836", + "name": "Shade", + "defence_level": "130", + "safespot": null, + "lifepoints": "170", + "strength_level": "90", + "id": "429", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "130" + }, + { + "examine": "Dead but not gone.", + "melee_animation": "390", + "range_animation": "0", + "respawn_delay": "50", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Shade", + "defence_level": "105", + "safespot": null, + "lifepoints": "100", + "strength_level": "150", + "id": "430", + "range_level": "1", + "attack_level": "150" + }, + { + "examine": "I hope he's not dead!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fallen Man", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "435", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Entrance clerk for the Brimhaven Agility Arena.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "498,500,499", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cap'n Izzy No-Beard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "437", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A very angry nymph.", + "melee_animation": "94", + "combat_audio": "498,500,499", + "attack_speed": "4", + "magic_level": "1", + "defence_animation": "95", + "death_animation": "97", + "name": "Tree spirit", + "defence_level": "8", + "safespot": null, + "lifepoints": "25", + "strength_level": "8", + "id": "438", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "8" + }, + { + "examine": "A very angry nymph.", + "melee_animation": "94", + "combat_audio": "498,500,499", + "attack_speed": "4", + "magic_level": "1", + "defence_animation": "95", + "death_animation": "97", + "name": "Tree spirit", + "defence_level": "17", + "safespot": null, + "lifepoints": "40", + "strength_level": "17", + "id": "439", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "17" + }, + { + "examine": "A very angry nymph.", + "melee_animation": "94", + "combat_audio": "498,500,499", + "attack_speed": "4", + "magic_level": "1", + "defence_animation": "95", + "death_animation": "97", + "name": "Tree spirit", + "defence_level": "38", + "safespot": null, + "lifepoints": "60", + "strength_level": "38", + "id": "440", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "38" + }, + { + "examine": "A very angry nymph.", + "melee_animation": "94", + "combat_audio": "498,500,499", + "attack_speed": "4", + "magic_level": "1", + "defence_animation": "95", + "death_animation": "97", + "name": "Tree spirit", + "defence_level": "64", + "safespot": null, + "lifepoints": "86", + "strength_level": "64", + "id": "441", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "64" + }, + { + "examine": "A very angry nymph.", + "melee_animation": "94", + "combat_audio": "498,500,499", + "attack_speed": "4", + "magic_level": "1", + "defence_animation": "95", + "death_animation": "97", + "name": "Tree spirit", + "defence_level": "100", + "safespot": null, + "lifepoints": "120", + "strength_level": "100", + "id": "442", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "100" + }, + { + "examine": "A very angry nymph.", + "melee_animation": "94", + "combat_audio": "498,500,499", + "attack_speed": "4", + "magic_level": "1", + "defence_animation": "95", + "death_animation": "97", + "name": "Tree spirit", + "defence_level": "130", + "safespot": null, + "lifepoints": "170", + "strength_level": "130", + "id": "443", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "130" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "444", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "445", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Overgrown vermin.", + "melee_animation": "4933", + "range_animation": "0", + "combat_audio": "703,705,704", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "4934", + "weakness": "8", + "magic_animation": "0", + "death_animation": "4935", + "name": "Giant rat", + "defence_level": "2", + "safespot": null, + "lifepoints": "5", + "strength_level": "5", + "id": "446", + "aggressive": "true", + "range_level": "1", + "attack_level": "5" + }, + { + "examine": "I wonder who he's guarding?", + "melee_animation": "401", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "836", + "name": "Jail guard", + "defence_level": "21", + "safespot": null, + "lifepoints": "32", + "strength_level": "23", + "id": "447", + "aggressive": "true", + "range_level": "1", + "attack_level": "19" + }, + { + "examine": "I wonder who he's guarding?", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "836", + "name": "Jail guard", + "defence_level": "21", + "safespot": null, + "lifepoints": "32", + "strength_level": "23", + "id": "448", + "aggressive": "true", + "range_level": "1", + "attack_level": "19" + }, + { + "examine": "I wonder who he's guarding?", + "melee_animation": "401", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "836", + "name": "Jail guard", + "defence_level": "21", + "safespot": null, + "lifepoints": "32", + "strength_level": "23", + "id": "449", + "aggressive": "true", + "range_level": "1", + "attack_level": "19" + }, + { + "examine": "A large well built farmer.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Seth Groats", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "452", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Aargh! It's alive!", + "melee_animation": "390", + "range_animation": "0", + "attack_speed": "5", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "836", + "name": "Suit of armour", + "defence_level": "9", + "safespot": null, + "lifepoints": "29", + "strength_level": "14", + "id": "453", + "bonuses": "8,8,8,0,0,46,50,46,-12,45,0,10,0,0,0", + "range_level": "1", + "attack_level": "16" + }, + { + "examine": "He seems to be very devout.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Father Aereck", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "456", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Eek! A ghost!", + "name": "Restless ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "436,439,438", + "strength_level": "1", + "id": "457", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Very holy.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Father Urhney", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "458", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A Wizard of the Magic Guild.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Wizard Frumscone", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "460", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A Supplier of Magical items.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Magic Store owner", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "461", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Head of the Magic Guild.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Wizard Distentor", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "462", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It's a gnome. He looks important.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "King Bolren", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "469", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It's a tree gnome.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Commander Montai", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "470", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It's one of General Khazard's warriors.", + "melee_animation": "401", + "range_animation": "0", + "attack_speed": "6", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "836", + "name": "Khazard trooper", + "defence_level": "32", + "safespot": null, + "lifepoints": "45", + "strength_level": "32", + "id": "475", + "range_level": "1", + "attack_level": "32" + }, + { + "examine": "An open eye of World-gorger.", + "magic_level": "5", + "defence_animation": "0", + "weakness": "3", + "magic_animation": "0", + "name": "Khazard trooper", + "defence_level": "5", + "safespot": null, + "lifepoints": "11", + "strength_level": "1", + "id": "476", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He looks real nasty", + "melee_animation": "401", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "836", + "name": "Khazard warlord", + "defence_level": "38", + "safespot": null, + "lifepoints": "54", + "strength_level": "38", + "id": "477", + "aggressive": "true", + "range_level": "1", + "attack_level": "38" + }, + { + "examine": "It's one of General Khazard's commanders.", + "melee_animation": "428", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "836", + "name": "Khazard commander", + "defence_level": "35", + "safespot": null, + "lifepoints": "50", + "strength_level": "35", + "id": "478", + "range_level": "1", + "attack_level": "35" + }, + { + "examine": "It's a tree gnome trooper.", + "melee_animation": "190", + "range_animation": "0", + "defence_animation": "0", + "weakness": "1", + "magic_animation": "0", + "death_animation": "196", + "name": "Gnome troop", + "defence_level": "32", + "safespot": null, + "lifepoints": "45", + "strength_level": "24", + "id": "479", + "range_level": "32", + "attack_level": "24" + }, + { + "examine": "It's a gnome who specialises in covert operations.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Tracker gnome 1", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "481", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It's a gnome who specialises in covert operations.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Tracker gnome 2", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "482", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It's a gnome who specialises in covert operations.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Tracker gnome 3", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "483", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It's a young tree gnome.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Local Gnome", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "485", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "I guess he wants to be more than just the muscle.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Giant", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "487", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He doesn't look like he'd trust his own mother.", + "melee_animation": "6199", + "range_animation": "0", + "combat_audio": "469,472,471", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "6190", + "name": "Goblin guard", + "defence_level": "20", + "safespot": null, + "lifepoints": "28", + "strength_level": "20", + "id": "489", + "range_level": "1", + "attack_level": "20" + }, + { + "examine": "If the mummy is at school", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Mummy", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "490", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "5540", + "combat_audio": "436,439,438", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "5541", + "slayer_exp": "25", + "death_animation": "5542", + "name": "Ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "20", + "strength_level": "1", + "id": "491", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The essence of evil.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Spirit of Scorpius", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "492", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A vicious", + "melee_animation": "6261", + "range_animation": "0", + "combat_audio": "3611,3612,3610", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "2", + "magic_animation": "0", + "death_animation": "6260", + "name": "Grave scorpion", + "defence_level": "7", + "safespot": null, + "lifepoints": "10", + "strength_level": "5", + "id": "493", + "aggressive": "true", + "range_level": "7", + "attack_level": "5" + }, + { + "examine": "He can look after my money.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Banker", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "494", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Good with money.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Banker", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "495", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Manages money momentarily.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Banker", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "498", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He can look after my money.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Banker", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "499", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A minion of Rashiliyia.", + "melee_animation": "5485", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "5491", + "name": "Undead one", + "defence_level": "32", + "safespot": null, + "lifepoints": "45", + "strength_level": "32", + "id": "502", + "aggressive": "true", + "range_level": "1", + "attack_level": "32" + }, + { + "examine": "A minion of Rashiliyia.", + "melee_animation": "5485", + "range_animation": "0", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "5491", + "name": "Undead one", + "defence_level": "33", + "safespot": null, + "lifepoints": "47", + "strength_level": "33", + "id": "503", + "range_level": "1", + "attack_level": "33" + }, + { + "examine": "The animated dead; one of Rashiliyia's minions.", + "melee_animation": "5568", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "5569", + "name": "Undead one", + "defence_level": "32", + "safespot": null, + "lifepoints": "45", + "strength_level": "32", + "id": "504", + "aggressive": "true", + "range_level": "1", + "attack_level": "32" + }, + { + "examine": "The animated dead; one of Rashiliyia's minions.", + "melee_animation": "5571", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "5575", + "name": "Undead one", + "defence_level": "33", + "safespot": null, + "lifepoints": "47", + "strength_level": "33", + "id": "505", + "aggressive": "true", + "range_level": "1", + "attack_level": "33" + }, + { + "melee_animation": "5571", + "respawn_delay": "60", + "defence_animation": "5574", + "death_animation": "5575", + "name": "Nazastarool", + "defence_level": "1", + "safespot": null, + "lifepoints": "100", + "strength_level": "1", + "id": "507", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "5507", + "respawn_delay": "60", + "defence_animation": "5508", + "death_animation": "5509", + "name": "Nazastarool", + "defence_level": "1", + "safespot": null, + "lifepoints": "75", + "strength_level": "1", + "id": "508", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "5532", + "respawn_delay": "60", + "defence_animation": "5533", + "death_animation": "5534", + "name": "Nazastarool", + "defence_level": "1", + "safespot": null, + "lifepoints": "110", + "strength_level": "1", + "id": "509", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He's the Captain of the 'Lady of the Waves'.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Captain Shanks", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "518", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An expert on axes.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Bob", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "519", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Sells stuff.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Shopkeeper", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "520", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Helps sell stuff.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Shop assistant", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "521", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Likes people spending money.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Shopkeeper", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "522", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Likes helping sell stuff.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Shop assistant", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "523", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A product of a consumerist society.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Shopkeeper", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "524", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Likes you more, the more you spend.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Shop assistant", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "525", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A product of a consumerist society.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Shopkeeper", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "526", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Likes you more, the more you spend.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Shop assistant", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "527", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Has an interesting assortment of items for sale.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Shopkeeper", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "530", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Works on commission.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Shop assistant", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "531", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He clearly takes pride in his appearance.", + "range_animation": "0", + "magic_level": "60", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "name": "Shopkeeper Kofi", + "defence_level": "60", + "safespot": null, + "lifepoints": "285", + "strength_level": "60", + "id": "532", + "aggressive": "true", + "range_level": "60", + "attack_level": "60" + }, + { + "examine": "Needs a haircut.", + "range_animation": "0", + "magic_level": "60", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "name": "Shop assistant", + "defence_level": "60", + "safespot": null, + "lifepoints": "285", + "strength_level": "60", + "id": "533", + "aggressive": "true", + "range_level": "60", + "attack_level": "60" + }, + { + "examine": "Sells stuff.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fairy shopkeeper", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "534", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Sells stuff.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fairy shop assistant", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "535", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Very snappily dressed.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Silk trader", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "539", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Makes his money selling rocks.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Gem trader", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "540", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "For the finest in armoured legware.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Louie Legs", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "542", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Ironically, makes a living from swords.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Shopkeeper", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "551", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Helps the shopkeeper sell swords.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Shop assistant", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "552", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "For the interesting clothing items you just can't find elsewhere.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fancy-dress shop owner", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "554", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Has a fine moustache.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Shopkeeper", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "555", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Could stand to lose a few pounds.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Shopkeeper", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "561", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Has an odd smell about him.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Candle-maker", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "562", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A being from a mysterious realm.", + "name": "Jukat", + "id": "564" + }, + { + "examine": "Is he invisible, or just floating clothing?", + "name": "Irksol", + "id": "566" + }, + { + "examine": "Looks strange and mysterious.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fairy", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "567", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Looks fairly well fed.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Silver merchant", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "569", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Seems very well-off.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Gem merchant", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "570", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "So where are the butcher and the candlestick-maker?", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Baker", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "571", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Has a very exotic aroma about him.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Spice seller", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "572", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Knows how to keep warm in the winter.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fur trader", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "573", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Seems very well-off.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Silk merchant", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "574", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He runs a Mining store.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Drogo dwarf", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "579", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "I wonder if he wants to buy my junk?", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Dwarf", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "582", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He seems to sell tea.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Tea seller", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "595", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A pizza expert; in both making and eating.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fat Tony", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "596", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Anyone fancy a trim?", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Hairdresser", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "598", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Master of the mystical make-over.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Make-over Mage", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "599", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Indentured servant of a Knight.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Squire", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "606", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A generic evil henchman.", + "melee_animation": "428", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Fortress Guard", + "defence_level": "26", + "safespot": null, + "lifepoints": "37", + "strength_level": "26", + "id": "609", + "range_level": "1", + "attack_level": "26" + }, + { + "examine": "One of the Black Knights.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Black Knight Captain", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "610", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The Black Knights' resident witch.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Witch", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "611", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "This person is working on the site.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Digsite workman", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "613", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "This person is working on the site.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Doug Deeping", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "614", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A student busy studying the digsite.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Student", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "615", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A student busy studying the digsite.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Student", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "616", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A student busy studying the digsite.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Student", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "617", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Upon examining the examiner you examine it is indeed an examiner!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Examiner", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "618", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An expert on archaeology.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Archaeological expert", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "619", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A specialist in panning for gold.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Panning guide", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "620", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A professional gnome baller.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Gnome baller", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "621", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A professional gnome baller.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Gnome winger", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "633", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Keeps the game fair.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Gnome ball referee", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "635", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A dealer in potions.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Apothecary", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "638", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A religious man... And occasional drunk.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Father Lawrence", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "640", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Looks down on his luck.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Charlie the Tramp", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "641", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Looks kind of obsessive...", + "melee_animation": "390", + "range_animation": "0", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Weaponsmaster", + "defence_level": "15", + "safespot": null, + "lifepoints": "42", + "strength_level": "15", + "id": "643", + "range_level": "1", + "attack_level": "15" + }, + { + "examine": "Looks kind of shifty...", + "melee_animation": "422", + "range_animation": "0", + "combat_audio": "498,500,499", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Jonny the beard", + "defence_level": "1", + "safespot": null, + "lifepoints": "2", + "strength_level": "1", + "id": "645", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Curator of the museum.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "703,705,704", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Curator Haig Halen", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "646", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Varrock's resident monarch.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "King Roald", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "648", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "She looks quite experienced.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Archer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "649", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He looks big and dumb.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Warrior", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "650", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He looks holy.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Monk", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "651", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He looks kind of puny...", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Wizard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "652", + "range_level": "1", + "attack_level": "1", + "prj_height": "3" + }, + { + "examine": "Guardian of the dramen tree.", + "melee_animation": "5532", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "5534", + "name": "Tree spirit", + "defence_level": "45", + "safespot": null, + "lifepoints": "64", + "strength_level": "45", + "id": "655", + "range_level": "1", + "attack_level": "45" + }, + { + "examine": "Unsurprisingly monk like.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cave monk", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "656", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Holy looking.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Monk of Entrana", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "657", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Holy looking.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Monk of Entrana", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "658", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He likes to paaaarty!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Party Pete", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "659", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Knight", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "660", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Man", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "663", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A short and angry dwarf.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Boot", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "665", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Chronozon the blood demon.", + "melee_animation": "64", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "65", + "death_animation": "67", + "name": "Chronozon", + "defence_level": "173", + "safespot": null, + "lifepoints": "60", + "strength_level": "172", + "id": "667", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "173" + }, + { + "examine": "An important looking gnome.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "King Narnode Shareen", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "670", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The boss!", + "melee_animation": "422", + "range_animation": "0", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Foreman", + "defence_level": "20", + "safespot": null, + "lifepoints": "28", + "strength_level": "20", + "id": "674", + "range_level": "1", + "attack_level": "20" + }, + { + "examine": "A big, scary, jet-black demon.", + "melee_animation": "64", + "range_animation": "64", + "combat_audio": "397,399,398", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "65", + "weakness": "4", + "slayer_exp": "157", + "magic_animation": "64", + "death_animation": "67", + "name": "Black demon", + "defence_level": "152", + "safespot": null, + "lifepoints": "157", + "strength_level": "148", + "id": "677", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,-10,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "145" + }, + { + "examine": "Keeps order in the ranging guild.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "678", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The keeper of the gates to the ranging guild.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ranging Guild Doorman", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "679", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An expert leatherworker.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Leatherworker", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "680", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Mysterious swamp lights...", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Held vampyre juvinate", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "681", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Supplier of Rangers armour.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Armour salesman", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "682", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Supplier of Archery equipment.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Bow and Arrow salesman", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "683", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Tower keeper and competition judge.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Tower Advisor", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "684", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Defender of the north tower.", + "combat_style": "1", + "melee_animation": "426", + "range_animation": "426", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "0", + "magic_animation": "0", + "death_animation": "836", + "name": "Tower Archer", + "defence_level": "10", + "safespot": null, + "lifepoints": "14", + "strength_level": "7", + "id": "688", + "aggressive": "true", + "range_level": "10", + "attack_level": "7" + }, + { + "examine": "Defender of the east tower.", + "combat_style": "1", + "melee_animation": "426", + "range_animation": "426", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "0", + "magic_animation": "0", + "death_animation": "836", + "name": "Tower Archer", + "defence_level": "20", + "safespot": null, + "lifepoints": "28", + "strength_level": "15", + "id": "689", + "aggressive": "true", + "range_level": "20", + "attack_level": "15" + }, + { + "examine": "Defender of the south tower.", + "combat_style": "1", + "melee_animation": "426", + "range_animation": "426", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "0", + "magic_animation": "0", + "death_animation": "836", + "name": "Tower Archer", + "defence_level": "30", + "safespot": null, + "lifepoints": "42", + "strength_level": "22", + "id": "690", + "aggressive": "true", + "range_level": "30", + "attack_level": "22" + }, + { + "examine": "Defender of the west tower.", + "combat_style": "1", + "melee_animation": "426", + "range_animation": "426", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "0", + "magic_animation": "0", + "death_animation": "836", + "name": "Tower Archer", + "defence_level": "40", + "safespot": null, + "lifepoints": "57", + "strength_level": "30", + "id": "691", + "aggressive": "true", + "range_level": "40", + "attack_level": "30" + }, + { + "examine": "Supplier of authentic throwing weapons.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Tribal Weapon Salesman", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "692", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Sells equipment in exchange for archery tickets.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ticket Merchant", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "694", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Harlan, ready to teach swordplay.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Melee tutor", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "705", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An old wizard.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Wizard Mizgog", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "706", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A cheeky little imp.", + "melee_animation": "169", + "range_animation": "169", + "combat_audio": "534,536,535", + "attack_speed": "5", + "defence_animation": "170", + "weakness": "7", + "magic_animation": "169", + "death_animation": "172", + "name": "Imp", + "defence_level": "2", + "safespot": null, + "movement_radius": "25", + "lifepoints": "8", + "strength_level": "2", + "id": "708", + "range_level": "1", + "attack_level": "2" + }, + { + "examine": "A cheeky little imp.", + "melee_animation": "169", + "range_animation": "169", + "combat_audio": "534,536,535", + "attack_speed": "5", + "defence_animation": "170", + "magic_animation": "169", + "death_animation": "172", + "name": "Imp", + "defence_level": "1", + "safespot": null, + "movement_radius": "25", + "lifepoints": "8", + "strength_level": "1", + "id": "709", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A bureaucratic administrator.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Clerk", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "713", + "range_level": "1", + "attack_level": "1" + }, + { + "slayer_exp": "", + "examine": "A local civilian.", + "name": "Edmond", + "defence_level": "", + "safespot": null, + "lifepoints": "", + "combat_audio": "", + "strength_level": "", + "id": "714", + "range_level": "", + "attack_level": "" + }, + { + "slayer_exp": "", + "examine": "A local civilian.", + "name": "Edmond", + "defence_level": "", + "safespot": null, + "lifepoints": "", + "combat_audio": "", + "strength_level": "", + "id": "3213", + "range_level": "", + "attack_level": "" + }, + { + "slayer_exp": "", + "examine": "A local civilian.", + "name": "Edmond", + "defence_level": "", + "safespot": null, + "lifepoints": "", + "combat_audio": "", + "strength_level": "", + "id": "3214", + "range_level": "", + "attack_level": "" + }, + { + "examine": "A member of the Ardougne Royal Army.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Recruiter", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "720", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of Gielinor's many citizens.", + "name": "Man", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "726", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of Gielinor's many citizens.", + "name": "Man", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "727", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of Gielinor's many citizens.", + "melee_animation": "", + "range_animation": "", + "combat_audio": "", + "protect_style": "", + "respawn_delay": "", + "defence_animation": "0", + "slayer_exp": "", + "magic_animation": "", + "death_animation": "0", + "name": "Man", + "defence_level": "1", + "safespot": "", + "lifepoints": "", + "strength_level": "", + "id": "728", + "clue_level": "", + "range_level": "", + "attack_level": "" + }, + { + "examine": "One of Gielinor's many citizens.", + "melee_animation": "", + "range_animation": "", + "combat_audio": "", + "defence_animation": "", + "magic_animation": "", + "death_animation": "", + "name": "Man", + "defence_level": "", + "safespot": null, + "lifepoints": "", + "strength_level": "", + "id": "729", + "clue_level": "", + "range_level": "", + "attack_level": "" + }, + { + "examine": "One of Gielinor's many citizens.", + "name": "Man", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "730", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "I could get a beer from him.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Bartender", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "731", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "I could get a beer from him.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Bartender", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "732", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "I could get a beer from him.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Bartender", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "735", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "I could get a beer from him.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Bartender", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "737", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "I could get a beer from him.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Bartender", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "738", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "I could get a beer from him.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Bartender", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "739", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Duke Horacio of Lumbridge.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Duke Horacio", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "741", + "range_level": "1", + "attack_level": "1" + }, + { + "agg_radius": "64", + "examine": "Roar! A dragon!", + "melee_animation": "80", + "attack_speed": "4", + "magic_level": "70", + "respawn_delay": "35", + "defence_animation": "89", + "death_animation": "4642", + "name": "Elvarg", + "defence_level": "70", + "safespot": null, + "lifepoints": "80", + "strength_level": "70", + "id": "742", + "aggressive": "true", + "bonuses": "0,0,0,0,0,20,40,40,30,20,0,0,0,0,0", + "range_level": "1", + "attack_level": "70" + }, + { + "examine": "A badly-behaved goblin.", + "melee_animation": "6184", + "range_animation": "0", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "6204", + "name": "Wormbrain", + "defence_level": "1", + "safespot": null, + "lifepoints": "1", + "strength_level": "1", + "id": "745", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He looks a tad upset.", + "melee_animation": "6726", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "6727", + "name": "Angry barbarian spirit", + "defence_level": "76", + "safespot": null, + "lifepoints": "108", + "strength_level": "76", + "id": "749", + "aggressive": "true", + "range_level": "1", + "attack_level": "76" + }, + { + "examine": "He looks a tad upset.", + "melee_animation": "6726", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "6727", + "name": "Enraged barbarian spirit", + "defence_level": "76", + "safespot": null, + "lifepoints": "108", + "strength_level": "76", + "id": "750", + "aggressive": "true", + "range_level": "1", + "attack_level": "76" + }, + { + "examine": "He looks a tad upset.", + "melee_animation": "6726", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "6727", + "name": "Berserk barbarian spirit", + "defence_level": "76", + "safespot": null, + "lifepoints": "108", + "strength_level": "76", + "id": "751", + "aggressive": "true", + "range_level": "1", + "attack_level": "76" + }, + { + "examine": "He looks a tad upset.", + "melee_animation": "6726", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "6727", + "name": "Ferocious barbarian spirit", + "defence_level": "76", + "safespot": null, + "lifepoints": "190", + "strength_level": "76", + "id": "752", + "aggressive": "true", + "bonuses": "80,100,60,70,85,70,70,90,60,100,50,90,90,0,0", + "range_level": "1", + "attack_level": "76" + }, + { + "examine": "He looks totally insane!", + "melee_animation": "423", + "range_animation": "0", + "magic_level": "28", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "836", + "name": "Melzar the Mad", + "defence_level": "28", + "safespot": null, + "lifepoints": "40", + "strength_level": "28", + "id": "753", + "aggressive": "true", + "range_level": "28", + "attack_level": "28" + }, + { + "examine": "Stop looking and run!", + "melee_animation": "422", + "range_animation": "422", + "attack_speed": "5", + "defence_animation": "404", + "magic_animation": "422", + "death_animation": "9055", + "name": "Count Draynor", + "defence_level": "20", + "safespot": null, + "lifepoints": "4", + "strength_level": "1", + "id": "757", + "aggressive": "true", + "range_level": "1", + "attack_level": "20" + }, + { + "examine": "A well-fed farmer.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fred the Farmer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "758", + "range_level": "1", + "attack_level": "1" + }, + { + "combat_style": "2", + "melee_animation": "192", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "194", + "death_animation": "196", + "name": "Crate", + "defence_level": "1", + "safespot": null, + "lifepoints": "88", + "strength_level": "1", + "id": "767", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Overgrown cat", + "defence_level": "1", + "safespot": null, + "lifepoints": "66", + "strength_level": "1", + "id": "778", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A citizen of Ardougne.", + "melee_animation": "", + "range_animation": "", + "defence_animation": "", + "magic_animation": "", + "death_animation": "", + "name": "Civilian", + "defence_level": "", + "safespot": null, + "lifepoints": "", + "strength_level": "", + "id": "785", + "range_level": "", + "attack_level": "" + }, + { + "examine": "A citizen of Ardougne.", + "melee_animation": "", + "range_animation": "", + "defence_animation": "", + "magic_animation": "", + "death_animation": "", + "name": "Civilian", + "defence_level": "", + "safespot": null, + "lifepoints": "", + "strength_level": "", + "id": "786", + "range_level": "", + "attack_level": "" + }, + { + "examine": "A citizen of Ardougne.", + "melee_animation": "", + "range_animation": "", + "defence_animation": "", + "magic_animation": "", + "death_animation": "", + "name": "Civilian", + "defence_level": "", + "safespot": null, + "lifepoints": "", + "strength_level": "", + "id": "787", + "range_level": "", + "attack_level": "" + }, + { + "examine": "A gnome who's supposed to be cleaning up a mess.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Letham", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "790", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Smartly dressed", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Alfonse the waiter", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "793", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Distinctly cook-like.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Charlie the cook", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "794", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A cold hearted lady.", + "melee_animation": "422", + "range_animation": "0", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "836", + "name": "Ice Queen", + "defence_level": "95", + "safespot": null, + "lifepoints": "104", + "strength_level": "94", + "id": "795", + "bonuses": "0,0,0,0,0,30,40,20,10,30,0,0,0,0,0", + "range_level": "1", + "attack_level": "95" + }, + { + "examine": "He looks cold and hungry.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Velrak the explorer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "798", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A morally ambiguous guard.", + "melee_animation": "390", + "range_animation": "0", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "836", + "name": "Pirate Guard", + "defence_level": "30", + "safespot": null, + "lifepoints": "42", + "strength_level": "30", + "id": "799", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "It looks like there might be eels swimming in the lava.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fishing spot", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "800", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A holy man.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Abbot Langley", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "801", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A holy man.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Brother Jered", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "802", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A holy man.", + "melee_animation": "422", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Monk", + "defence_level": "12", + "safespot": null, + "lifepoints": "17", + "strength_level": "12", + "id": "803", + "range_level": "1", + "attack_level": "12" + }, + { + "examine": "Manufacturer of fine leathers.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Tanner", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "804", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He's in charge of the Crafting Guild.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Master Crafter", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "805", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He looks very tired...", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Donovan the Family Handyman", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "806", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An officer of the Law.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "812", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of those people who love to gossip!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Gossip", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "813", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He sure likes to sell stuff!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Poison Salesman", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "820", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Big", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Sinclair Guard dog", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "821", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It looks like he's been here a long time.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Male slave", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "825", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He looks a bit aggressive.", + "melee_animation": "422", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Rowdy slave", + "defence_level": "5", + "safespot": null, + "lifepoints": "7", + "strength_level": "5", + "id": "827", + "aggressive": "true", + "range_level": "1", + "attack_level": "5" + }, + { + "examine": "He looks a bit aggressive.", + "melee_animation": "390", + "range_animation": "0", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Mercenary Captain", + "defence_level": "20", + "safespot": null, + "lifepoints": "28", + "strength_level": "1", + "id": "830", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He's in control of the whole mining camp.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Captain Siad", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "831", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A Bedabin nomad", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Bedabin Nomad", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "833", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A Bedabin nomad guard - it looks like he's protecting an area.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Bedabin Nomad Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "834", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He patrols the Shantay Pass.", + "melee_animation": "390", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Shantay Guard", + "defence_level": "11", + "safespot": null, + "lifepoints": "15", + "strength_level": "11", + "id": "837", + "range_level": "1", + "attack_level": "11" + }, + { + "examine": "He patrols the Shantay Pass.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Shantay Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "838", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A vicious desert wolf.", + "melee_animation": "6559", + "range_animation": "0", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "6558", + "name": "Desert Wolf", + "defence_level": "11", + "safespot": null, + "lifepoints": "15", + "strength_level": "11", + "id": "839", + "range_level": "1", + "attack_level": "11" + }, + { + "death_animation": "9674", + "name": "Ugthanki", + "defence_level": "1", + "safespot": null, + "lifepoints": "46", + "strength_level": "1", + "attack_speed": "5", + "id": "840", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "examine": "He looks busy attending to his cart.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Mine cart driver", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "841", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "This pickaxe has been possessed by a dwarf ancestor spirit.", + "melee_animation": "185", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "188", + "name": "Rowdy Guard", + "defence_level": "40", + "safespot": null, + "lifepoints": "400", + "strength_level": "40", + "id": "842", + "aggressive": "true", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "Inefficient looking.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "RPDT employee", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "843", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Despite his name", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Head chef", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "847", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The famous tree gnome chef.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Aluft Gianne snr.", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "850", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He can serve you gnome food.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Gnome Waiter", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "851", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Tough-looking.", + "range_animation": "0", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "300", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "name": "Ogre chieftain", + "defence_level": "75", + "safespot": null, + "lifepoints": "60", + "strength_level": "71", + "id": "852", + "bonuses": "5,5,5,0,0,0,0,0,0,0,0,7,0,0,0", + "range_level": "1", + "attack_level": "75" + }, + { + "name": "Gorad", + "defence_level": "1", + "safespot": null, + "lifepoints": "81", + "strength_level": "1", + "id": "856", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "examine": "These ogres protect the city.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "0", + "name": "Ogre guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "858", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ogre that guards.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "0", + "name": "Ogre guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "859", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Tries to keep the peace.", + "melee_animation": "2100", + "range_animation": "0", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "8576", + "name": "City guard", + "defence_level": "58", + "safespot": null, + "lifepoints": "331", + "strength_level": "58", + "id": "862", + "range_level": "1", + "attack_level": "58" + }, + { + "examine": "Frightened-looking.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Scared skavid", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "863", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Looks mad.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Mad skavid", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "864", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Big and ugly looking.", + "melee_animation": "2100", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "8576", + "name": "Enclave guard", + "defence_level": "58", + "safespot": null, + "lifepoints": "331", + "strength_level": "58", + "id": "870", + "range_level": "1", + "attack_level": "58" + }, + { + "examine": "The hat is a dead giveaway.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Watchtower Wizard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "872", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Funnily enough", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ogre trader", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "873", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Funnily enough", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ogre merchant", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "874", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Funnily enough", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ogre trader", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "875", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Tries to keep the peace.", + "melee_animation": "386", + "range_animation": "0", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "836", + "name": "Tower guard", + "defence_level": "17", + "safespot": null, + "lifepoints": "97", + "strength_level": "17", + "id": "877", + "range_level": "1", + "attack_level": "17" + }, + { + "melee_animation": "395", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Colonel Radick", + "defence_level": "1", + "safespot": null, + "lifepoints": "71", + "strength_level": "1", + "id": "878", + "range_level": "1", + "attack_level": "1" + }, + { + "death_animation": "67", + "name": "Delrith", + "defence_level": "1", + "safespot": null, + "lifepoints": "7", + "melee_animation": "64", + "strength_level": "1", + "id": "879", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1", + "defence_animation": "65" + }, + { + "examine": "The head of the palace guard.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Captain Rovin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "884", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Head of the Carnillean household.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ceril Carnillean", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "885", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "887", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "death_animation": "836", + "name": "Clivet", + "defence_level": "1", + "safespot": null, + "lifepoints": "25", + "melee_animation": "811", + "strength_level": "1", + "id": "893", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1", + "defence_animation": "425" + }, + { + "examine": "A member of the Hazeel cult.", + "melee_animation": "422", + "range_animation": "0", + "magic_level": "20", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "3", + "magic_animation": "0", + "death_animation": "836", + "name": "Hazeel Cultist", + "defence_level": "20", + "safespot": null, + "lifepoints": "28", + "strength_level": "15", + "id": "894", + "range_level": "1", + "attack_level": "15" + }, + { + "examine": "Children are just like real people...just smaller.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Boy", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "895", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Looks unnatural.", + "melee_animation": "255", + "range_animation": "0", + "attack_speed": "4", + "magic_level": "1", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "258", + "name": "Witch's experiment", + "defence_level": "19", + "safespot": null, + "lifepoints": "21", + "strength_level": "10", + "id": "897", + "range_level": "1", + "attack_level": "18" + }, + { + "examine": "Looks unnatural.", + "melee_animation": "5327", + "range_animation": "0", + "attack_speed": "4", + "magic_level": "1", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "5329", + "name": "Witch's experiment (second form)", + "defence_level": "29", + "safespot": null, + "lifepoints": "31", + "strength_level": "20", + "id": "898", + "range_level": "1", + "attack_level": "28" + }, + { + "examine": "Looks unnatural.", + "melee_animation": "4925", + "range_animation": "0", + "attack_speed": "4", + "magic_level": "1", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "4929", + "name": "Witch's experiment (third form)", + "defence_level": "39", + "safespot": null, + "lifepoints": "41", + "strength_level": "30", + "id": "899", + "range_level": "1", + "attack_level": "38" + }, + { + "examine": "Looks unnatural.", + "melee_animation": "6559", + "range_animation": "0", + "attack_speed": "4", + "magic_level": "1", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "6558", + "name": "Witch's experiment (fourth form)", + "defence_level": "49", + "safespot": null, + "lifepoints": "51", + "strength_level": "40", + "id": "900", + "range_level": "1", + "attack_level": "48" + }, + { + "examine": "He hasn't seen much sun lately.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Chamber guardian", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "904", + "range_level": "1", + "attack_level": "1" + }, + { + "slayer_exp": "0", + "examine": "Runs the Mage Arena.", + "name": "Kolodion", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "905", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He's a shape-shifter", + "combat_style": "2", + "melee_animation": "811", + "attack_speed": "7", + "magic_level": "75", + "defence_animation": "404", + "slayer_exp": "0", + "death_animation": "1816", + "name": "Kolodion", + "defence_level": "20", + "safespot": null, + "lifepoints": "3", + "strength_level": "1", + "id": "907", + "range_level": "1", + "attack_level": "42" + }, + { + "examine": "He's a shape-shifter", + "combat_style": "2", + "melee_animation": "132", + "attack_speed": "7", + "magic_level": "89", + "defence_animation": "404", + "slayer_exp": "0", + "death_animation": "133", + "name": "Kolodion", + "defence_level": "25", + "safespot": null, + "lifepoints": "65", + "strength_level": "1", + "id": "908", + "range_level": "1", + "attack_level": "74" + }, + { + "examine": "He's a shape-shifter", + "combat_style": "2", + "melee_animation": "5322", + "attack_speed": "7", + "magic_level": "89", + "defence_animation": "5320", + "slayer_exp": "0", + "death_animation": "5323", + "name": "Kolodion", + "defence_level": "28", + "safespot": null, + "lifepoints": "65", + "strength_level": "1", + "id": "909", + "range_level": "1", + "attack_level": "74" + }, + { + "examine": "He's a shape-shifter", + "combat_style": "2", + "melee_animation": "811", + "attack_speed": "7", + "magic_level": "89", + "defence_animation": "404", + "slayer_exp": "0", + "death_animation": "714", + "name": "Kolodion", + "defence_level": "30", + "safespot": null, + "lifepoints": "78", + "strength_level": "1", + "id": "910", + "range_level": "1", + "attack_level": "74" + }, + { + "examine": "He's a shape-shifter", + "melee_animation": "69", + "attack_speed": "7", + "magic_level": "80", + "defence_animation": "65", + "slayer_exp": "0", + "death_animation": "68", + "name": "Kolodion", + "defence_level": "105", + "safespot": null, + "lifepoints": "107", + "strength_level": "98", + "id": "911", + "range_level": "1", + "attack_level": "85" + }, + { + "examine": "He kills in the name of Zamorak.", + "combat_style": "2", + "melee_animation": "811", + "range_animation": "0", + "attack_speed": "4", + "magic_level": "50", + "respawn_delay": "150", + "defence_animation": "0", + "weakness": "3", + "magic_animation": "0", + "death_animation": "836", + "name": "Battle mage", + "defence_level": "1", + "safespot": null, + "lifepoints": "120", + "strength_level": "1", + "id": "912", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He kills in the name of Saradomin.", + "combat_style": "2", + "melee_animation": "811", + "range_animation": "0", + "attack_speed": "4", + "magic_level": "50", + "respawn_delay": "150", + "defence_animation": "0", + "weakness": "3", + "slayer_exp": "0", + "magic_animation": "0", + "death_animation": "836", + "name": "Battle mage", + "defence_level": "1", + "safespot": null, + "lifepoints": "120", + "strength_level": "1", + "id": "913", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He kills in the name of Guthix.", + "combat_style": "2", + "melee_animation": "197", + "range_animation": "0", + "attack_speed": "4", + "magic_level": "50", + "respawn_delay": "150", + "defence_animation": "0", + "weakness": "3", + "slayer_exp": "0", + "magic_animation": "0", + "death_animation": "196", + "name": "Battle mage", + "defence_level": "1", + "safespot": null, + "lifepoints": "120", + "strength_level": "1", + "id": "914", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A crafter at the pinnacle of his art.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Joe", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "916", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "I wonder who he's guarding?", + "melee_animation": "401", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "836", + "name": "Jail guard", + "defence_level": "21", + "safespot": null, + "lifepoints": "32", + "strength_level": "23", + "id": "917", + "aggressive": "true", + "range_level": "1", + "attack_level": "19" + }, + { + "examine": "The emir's chief advisor and physician.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Hassan", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "923", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Guards the border between Al Kharid and the Kingdom of Misthalin.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Border Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "925", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An aggressive native of the Kharazi Jungle.", + "melee_animation": "428", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "836", + "name": "Jungle savage", + "defence_level": "44", + "safespot": null, + "lifepoints": "62", + "strength_level": "44", + "id": "931", + "aggressive": "true", + "range_level": "1", + "attack_level": "44" + }, + { + "melee_animation": "64", + "respawn_delay": "60", + "defence_animation": "65", + "death_animation": "67", + "name": "Nezikchened", + "defence_level": "1", + "safespot": null, + "lifepoints": "150", + "strength_level": "1", + "id": "934", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "5485", + "respawn_delay": "60", + "defence_animation": "5489", + "death_animation": "5491", + "name": "Ranalph Devere", + "defence_level": "1", + "safespot": null, + "lifepoints": "130", + "strength_level": "1", + "id": "938", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "I wonder what this is doing here.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Boulder", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "939", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Must be related to Elvarg.", + "melee_animation": "80", + "range_animation": "80", + "combat_audio": "408,410,409", + "attack_speed": "4", + "magic_level": "68", + "respawn_delay": "35", + "defence_animation": "89", + "weakness": "3", + "slayer_exp": "75", + "magic_animation": "80", + "death_animation": "92", + "name": "Green dragon", + "defence_level": "68", + "safespot": null, + "lifepoints": "75", + "strength_level": "68", + "id": "941", + "aggressive": "true", + "bonuses": "0,0,0,0,0,20,40,40,30,20,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "68" + }, + { + "examine": "An expert on all things culinary.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Master chef", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "942", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Very much an outdoors type.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Survival expert", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "943", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An expert on all forms of combat.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Combat instructor", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "944", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Your introduction to the world of Gielinor.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "RuneScape guide", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "945", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A master of Magic.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Magic instructor", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "946", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An official representative from the First National Bank of Gielinor.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Financial advisor", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "947", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An expert on Mining-related skills.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Mining instructor", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "948", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Your introduction to the world of Gielinor.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Quest guide", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "949", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "4933", + "combat_audio": "703,705,704", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "4934", + "death_animation": "4935", + "name": "Giant rat", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "1", + "id": "950", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Yep. Definitely a chicken.", + "melee_animation": "5387", + "range_animation": "5387", + "combat_audio": "355,357,356", + "attack_speed": "6", + "respawn_delay": "18", + "defence_animation": "5388", + "magic_animation": "5387", + "death_animation": "5389", + "name": "Chicken", + "defence_level": "1", + "safespot": null, + "lifepoints": "3", + "strength_level": "1", + "id": "951", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A holy man.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Brother Brace", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "954", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Converts grass to beef.", + "melee_animation": "5849", + "range_animation": "5849", + "combat_audio": "369,371,370", + "attack_speed": "5", + "defence_animation": "5850", + "weakness": "8", + "slayer_exp": "8", + "magic_animation": "5849", + "death_animation": "5851", + "name": "Cow", + "defence_level": "1", + "safespot": null, + "lifepoints": "8", + "strength_level": "1", + "id": "955", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He's had a fair bit to drink...", + "start_gfx": "", + "combat_style": "1", + "melee_animation": "99", + "range_animation": "99", + "combat_audio": "2707,419,418", + "attack_speed": "5", + "magic_level": "20", + "defence_animation": "101", + "slayer_exp": "0", + "magic_animation": "99", + "death_animation": "102", + "name": "Drunken Dwarf", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "5", + "id": "956", + "range_level": "6", + "projectile": "33", + "attack_level": "5", + "prj_height": "45" + }, + { + "examine": "This doctor really knows her stuff.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Surgeon General Tafani", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "961", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It's one of Iban's pets.", + "melee_animation": "5327", + "range_animation": "0", + "combat_audio": "537,539,538", + "defence_animation": "0", + "weakness": "2", + "magic_animation": "0", + "death_animation": "5329", + "name": "Blessed spider", + "defence_level": "30", + "safespot": null, + "lifepoints": "42", + "strength_level": "22", + "id": "977", + "range_level": "30", + "attack_level": "22" + }, + { + "examine": "It's one of Iban's pet vermin.", + "range_animation": "0", + "combat_audio": "703,705,704", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "name": "Blessed giant rat", + "defence_level": "12", + "safespot": null, + "lifepoints": "17", + "strength_level": "12", + "id": "978", + "range_level": "1", + "attack_level": "12" + }, + { + "examine": "A wretched slave of Iban.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Slave", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "979", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A wretched slave of Iban.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Slave", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "980", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A wretched slave of Iban.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Slave", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "981", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A wretched slave of Iban.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Slave", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "982", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A wretched slave of Iban.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Slave", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "983", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A wretched slave of Iban.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Slave", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "984", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A wretched slave of Iban.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Slave", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "985", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Precariously balanced...", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Boulder", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "986", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Unicorn", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "369,371,370", + "strength_level": "1", + "id": "987", + "range_level": "1", + "attack_level": "1" + }, + { + "death_animation": "836", + "name": "Sir Jerro", + "defence_level": "1", + "safespot": null, + "lifepoints": "57", + "melee_animation": "400", + "strength_level": "1", + "id": "988", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1", + "defence_animation": "425" + }, + { + "death_animation": "836", + "name": "Sir Carl", + "defence_level": "1", + "safespot": null, + "lifepoints": "57", + "melee_animation": "400", + "strength_level": "1", + "id": "989", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1", + "defence_animation": "425" + }, + { + "death_animation": "836", + "name": "Sir Harry", + "defence_level": "1", + "safespot": null, + "lifepoints": "57", + "melee_animation": "400", + "strength_level": "1", + "id": "990", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1", + "defence_animation": "425" + }, + { + "examine": "A creature empty of emotion.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Half-soulless", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "991", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Curiosity is yet to kill this one...", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Witch's cat", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "993", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A giant spider.", + "melee_animation": "5319", + "respawn_delay": "60", + "defence_animation": "5320", + "death_animation": "5321", + "name": "Kalrag", + "defence_level": "1", + "safespot": null, + "lifepoints": "91", + "strength_level": "1", + "id": "997", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of the guardians of Iban.", + "melee_animation": "64", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "65", + "death_animation": "67", + "name": "Othainian", + "defence_level": "1", + "safespot": null, + "lifepoints": "90", + "strength_level": "1", + "id": "998", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of the guardians of Iban.", + "melee_animation": "64", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "65", + "death_animation": "67", + "name": "Doomion", + "defence_level": "1", + "safespot": null, + "lifepoints": "90", + "strength_level": "1", + "id": "999", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of the guardians of Iban.", + "melee_animation": "64", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "65", + "death_animation": "67", + "name": "Holthion", + "defence_level": "1", + "safespot": null, + "lifepoints": "90", + "strength_level": "1", + "id": "1000", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A user of dark magic.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "weakness": "3", + "magic_animation": "0", + "death_animation": "0", + "name": "Dark mage", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1001", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A dark magic user.", + "melee_animation": "422", + "range_animation": "0", + "magic_level": "32", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "3", + "magic_animation": "0", + "death_animation": "836", + "name": "Disciple of Iban", + "defence_level": "32", + "safespot": null, + "lifepoints": "45", + "strength_level": "24", + "id": "1002", + "range_level": "1", + "attack_level": "24" + }, + { + "examine": "Incey wincey.", + "melee_animation": "6249", + "respawn_delay": "60", + "defence_animation": "6250", + "death_animation": "6251", + "name": "Spider", + "defence_level": "1", + "safespot": null, + "lifepoints": "2", + "strength_level": "1", + "id": "1004", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An annoying flappy thing.", + "combat_audio": "292,294,293", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "35", + "slayer_exp": "8", + "name": "Giant bat", + "defence_level": "22", + "safespot": null, + "lifepoints": "32", + "strength_level": "22", + "id": "1005", + "bonuses": "0,0,0,0,0,10,10,12,10,8,0,0,0,0,0", + "range_level": "1", + "attack_level": "22" + }, + { + "examine": "A rather nasty looking crustacean.", + "name": "Sea slug", + "id": "1006" + }, + { + "examine": "A servant of Zamorak.", + "combat_style": "2", + "melee_animation": "811", + "range_animation": "0", + "attack_speed": "5", + "magic_level": "60", + "spell_id": "43", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "3", + "magic_animation": "811", + "death_animation": "836", + "name": "Zamorak wizard", + "defence_level": "50", + "safespot": null, + "lifepoints": "73", + "strength_level": "50", + "id": "1007", + "aggressive": "true", + "range_level": "50", + "attack_level": "50" + }, + { + "examine": "A nasty, poisonous arachnid.", + "melee_animation": "5327", + "range_animation": "0", + "combat_audio": "537,539,538", + "attack_speed": "4", + "poisonous": "true", + "respawn_delay": "30", + "defence_animation": "5328", + "weakness": "2", + "poison_amount": "6", + "magic_animation": "0", + "death_animation": "5329", + "name": "Poison spider", + "safespot": null, + "defence_level": "52", + "lifepoints": "64", + "strength_level": "65", + "id": "1009", + "aggressive": "true", + "range_level": "1", + "attack_level": "50" + }, + { + "examine": "A green skinned croaker", + "melee_animation": "0", + "range_animation": "0", + "respawn_delay": "34", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Swamp toad", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1013", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Useful for hitting rocks.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "0", + "name": "Iron pickaxe", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1015", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Yep. Definitely a chicken.", + "melee_animation": "5387", + "range_animation": "5387", + "combat_audio": "355,357,356", + "attack_speed": "6", + "respawn_delay": "18", + "defence_animation": "5388", + "weakness": "9", + "magic_animation": "5387", + "death_animation": "5389", + "name": "Chicken", + "defence_level": "1", + "safespot": null, + "lifepoints": "3", + "strength_level": "1", + "id": "1017", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He rules the", + "melee_animation": "5387", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "5389", + "name": "Rooster", + "defence_level": "2", + "safespot": null, + "lifepoints": "2", + "strength_level": "2", + "id": "1018", + "range_level": "1", + "attack_level": "2" + }, + { + "examine": "A fire elemental.", + "melee_animation": "1029", + "range_animation": "0", + "combat_audio": "1534,1536,1535", + "magic_level": "32", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "3", + "magic_animation": "0", + "death_animation": "1031", + "name": "Fire elemental", + "defence_level": "32", + "safespot": null, + "movement_radius": "4", + "lifepoints": "45", + "strength_level": "24", + "id": "1019", + "range_level": "1", + "attack_level": "24" + }, + { + "examine": "An earth elemental.", + "melee_animation": "4868", + "range_animation": "0", + "combat_audio": "1531,1533,1532", + "attack_speed": "6", + "magic_level": "10", + "respawn_delay": "50", + "defence_animation": "4869", + "weakness": "7", + "magic_animation": "0", + "death_animation": "4870", + "name": "Earth elemental", + "defence_level": "35", + "safespot": null, + "movement_radius": "4", + "lifepoints": "35", + "strength_level": "32", + "id": "1020", + "aggressive": "false", + "range_level": "30", + "attack_level": "20" + }, + { + "examine": "An air elemental.", + "melee_animation": "1040", + "range_animation": "0", + "combat_audio": "1527,1529,1528", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "1", + "magic_animation": "0", + "death_animation": "1041", + "name": "Air elemental", + "defence_level": "32", + "safespot": null, + "movement_radius": "4", + "lifepoints": "45", + "strength_level": "24", + "id": "1021", + "range_level": "32", + "attack_level": "24" + }, + { + "examine": "A water elemental.", + "melee_animation": "1044", + "range_animation": "0", + "combat_audio": "1546,1543,1545", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "1", + "magic_animation": "0", + "death_animation": "1048", + "name": "Water elemental", + "defence_level": "32", + "safespot": null, + "movement_radius": "4", + "lifepoints": "45", + "strength_level": "24", + "id": "1022", + "range_level": "32", + "attack_level": "24" + }, + { + "examine": "It looks very hungry!", + "melee_animation": "7183", + "slayer_exp": "50", + "death_animation": "7185", + "name": "Vampire", + "defence_level": "52", + "safespot": null, + "lifepoints": "50", + "strength_level": "1", + "id": "1023", + "clue_level": "1", + "range_level": "1", + "attack_level": "52" + }, + { + "examine": "An evil human cleric.", + "start_gfx": "99", + "combat_style": "2", + "combat_audio": "511,513,512", + "melee_animation": "422", + "range_animation": "0", + "attack_speed": "4", + "magic_level": "25", + "end_gfx": "101", + "respawn_delay": "60", + "defence_animation": "404", + "weakness": "3", + "magic_animation": "711", + "death_animation": "836", + "name": "Monk of Zamorak", + "defence_level": "22", + "safespot": null, + "lifepoints": "20", + "strength_level": "18", + "id": "1044", + "aggressive": "true", + "range_level": "1", + "projectile": "100", + "attack_level": "18" + }, + { + "examine": "An evil human cleric.", + "start_gfx": "99", + "combat_style": "2", + "combat_audio": "511,513,512", + "melee_animation": "422", + "range_animation": "0", + "attack_speed": "4", + "magic_level": "25", + "end_gfx": "101", + "respawn_delay": "60", + "defence_animation": "404", + "weakness": "3", + "magic_animation": "711", + "death_animation": "836", + "name": "Monk of Zamorak", + "defence_level": "17", + "safespot": null, + "lifepoints": "10", + "strength_level": "8", + "id": "1045", + "aggressive": "true", + "range_level": "1", + "projectile": "100", + "attack_level": "8" + }, + { + "examine": "An evil human cleric.", + "start_gfx": "99", + "combat_style": "2", + "combat_audio": "511,513,512", + "melee_animation": "422", + "range_animation": "0", + "attack_speed": "4", + "magic_level": "40", + "end_gfx": "101", + "respawn_delay": "60", + "defence_animation": "404", + "weakness": "3", + "magic_animation": "711", + "death_animation": "836", + "name": "Monk of Zamorak", + "defence_level": "25", + "safespot": null, + "lifepoints": "25", + "strength_level": "25", + "id": "1046", + "aggressive": "true", + "range_level": "1", + "projectile": "100", + "attack_level": "25" + }, + { + "examine": "Arrghhh... a Ghast.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "433,435,434", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "0", + "name": "Ghast", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1052", + "aggressive": "false", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Arrghhh... A Ghast.", + "death_gfx": "265", + "range_animation": "0", + "melee_animation": "1087", + "combat_audio": "433,435,434", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "1088", + "weakness": "9", + "magic_animation": "0", + "death_animation": "1089", + "name": "Ghast", + "defence_level": "18", + "safespot": null, + "lifepoints": "45", + "strength_level": "22", + "id": "1053", + "aggressive": "true", + "range_level": "1", + "attack_level": "22" + }, + { + "examine": "Ticket trader for the Brimhaven Agility Arena.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "703,705,704", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Pirate Jackie the Fruit", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1055", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A member of the audience.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Strange watcher", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1057", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A member of the audience.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Strange watcher", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1058", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A member of the audience.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Strange watcher", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1059", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Commander of the Imperial Guard.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Denulth", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1060", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A sergeant of the Imperial Guard.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Sergeant", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1061", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A sergeant of the Imperial Guard.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Sergeant", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1062", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A soldier of the Imperial Guard.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Soldier", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1063", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A soldier of the Imperial Guard.", + "name": "Soldier", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "1064", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A soldier of the Imperial Guard.", + "name": "Soldier", + "defence_level": "44", + "safespot": null, + "lifepoints": "55", + "combat_audio": "511,513,512", + "strength_level": "44", + "id": "1065", + "magic_level": "1", + "range_level": "1", + "attack_level": "44" + }, + { + "examine": "A soldier of the Imperial Guard.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Soldier", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1066", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A soldier of the Imperial Guard.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Soldier", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1067", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A soldier of the Imperial Guard.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Soldier", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1068", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A soldier of the Imperial Guard.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Soldier", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1069", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The Burthorpe Castle cook.", + "melee_animation": "422", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Eadburg", + "defence_level": "3", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "1072", + "range_level": "1", + "attack_level": "3" + }, + { + "examine": "A Burthorpe Castle Archer.", + "start_gfx": "19", + "combat_style": "1", + "melee_animation": "426", + "range_animation": "426", + "magic_level": "1", + "respawn_delay": "12", + "defence_animation": "404", + "magic_animation": "426", + "death_animation": "9055", + "name": "Archer", + "defence_level": "44", + "safespot": null, + "lifepoints": "55", + "strength_level": "1", + "id": "1073", + "bonuses": "54,68,75,72,67,81,54,35,35,0,0,0,0,0,0", + "range_level": "44", + "projectile": "10", + "attack_level": "1" + }, + { + "examine": "A Burthorpe Castle Archer.", + "start_gfx": "19", + "combat_style": "1", + "melee_animation": "426", + "range_animation": "426", + "magic_level": "1", + "respawn_delay": "12", + "defence_animation": "404", + "magic_animation": "426", + "death_animation": "9055", + "name": "Archer", + "defence_level": "44", + "safespot": null, + "lifepoints": "55", + "strength_level": "1", + "id": "1074", + "bonuses": "54,68,75,72,67,81,54,35,35,0,0,0,0,0,0", + "range_level": "44", + "projectile": "10", + "attack_level": "1" + }, + { + "examine": "A Burthorpe Castle guard.", + "melee_animation": "401", + "combat_audio": "511,513,512", + "magic_level": "1", + "defence_animation": "404", + "death_animation": "836", + "name": "Guard", + "defence_level": "33", + "safespot": null, + "lifepoints": "44", + "strength_level": "33", + "id": "1076", + "clue_level": "1", + "range_level": "1", + "attack_level": "33" + }, + { + "examine": "A Burthorpe Castle guard.", + "melee_animation": "401", + "combat_audio": "511,513,512", + "magic_level": "1", + "defence_animation": "404", + "death_animation": "836", + "name": "Guard", + "defence_level": "33", + "safespot": null, + "lifepoints": "44", + "strength_level": "33", + "id": "1077", + "clue_level": "1", + "range_level": "1", + "attack_level": "33" + }, + { + "examine": "An off-duty Burthorpe Castle guard.", + "name": "Harold", + "id": "1078" + }, + { + "examine": "Barman of the Toad and Chicken.", + "name": "Tostig", + "id": "1079" + }, + { + "examine": "Head servant for Prince Anlaf.", + "name": "Eohric", + "id": "1080" + }, + { + "examine": "A servant for Prince Anlaf.", + "melee_animation": "422", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Servant", + "defence_level": "3", + "safespot": null, + "lifepoints": "10", + "strength_level": "3", + "id": "1081", + "range_level": "1", + "attack_level": "3" + }, + { + "examine": "Smithy for Burthorpe.", + "name": "Dunstan", + "id": "1082" + }, + { + "examine": "Shopkeeper for Burthorpe.", + "name": "Wistan", + "id": "1083" + }, + { + "examine": "A citizen of Burthorpe.", + "melee_animation": "422", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Breoca", + "defence_level": "3", + "safespot": null, + "lifepoints": "10", + "strength_level": "3", + "id": "1084", + "range_level": "1", + "attack_level": "3" + }, + { + "examine": "A citizen of Burthorpe.", + "melee_animation": "422", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Ocga", + "defence_level": "3", + "safespot": null, + "lifepoints": "10", + "strength_level": "3", + "id": "1085", + "range_level": "1", + "attack_level": "3" + }, + { + "name": "Man", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "1086", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A citizen of Burthorpe.", + "melee_animation": "422", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Penda", + "defence_level": "3", + "safespot": null, + "lifepoints": "10", + "strength_level": "3", + "id": "1087", + "range_level": "1", + "attack_level": "3" + }, + { + "examine": "A citizen of Burthorpe.", + "melee_animation": "422", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Hygd", + "defence_level": "3", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "1088", + "range_level": "1", + "attack_level": "3" + }, + { + "examine": "A citizen of Burthorpe.", + "melee_animation": "422", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Ceolburg", + "defence_level": "3", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "1089", + "range_level": "1", + "attack_level": "3" + }, + { + "examine": "A pretty young woman with an air of mystery around her.", + "name": "Hild", + "id": "1090" + }, + { + "examine": "The knight seems to be watching something.", + "melee_animation": "7042", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "8", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "White Knight", + "defence_level": "27", + "safespot": null, + "lifepoints": "38", + "strength_level": "27", + "id": "1092", + "range_level": "1", + "attack_level": "27" + }, + { + "examine": "The biggest and baddest troll.", + "melee_animation": "6523", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "name": "Rock", + "defence_level": "70", + "safespot": null, + "lifepoints": "140", + "strength_level": "110", + "id": "1095", + "aggressive": "true", + "bonuses": "60,60,60,0,0,35,60,35,200,200,0,100,0,0,0", + "range_level": "1", + "attack_level": "70" + }, + { + "examine": "Careful, he is a big.", + "melee_animation": "284", + "range_animation": "284", + "attack_speed": "7", + "respawn_delay": "60", + "defence_animation": "285", + "weakness": "7", + "magic_animation": "0", + "death_animation": "287", + "name": "Stick", + "defence_level": "60", + "safespot": null, + "lifepoints": "135", + "strength_level": "110", + "id": "1096", + "aggressive": "true", + "bonuses": "50,50,50,0,0,30,30,50,200,200,0,80,0,0,0", + "range_level": "1", + "attack_level": "60" + }, + { + "examine": "A nasty looking troll.", + "melee_animation": "284", + "range_animation": "284", + "attack_speed": "6", + "respawn_delay": "60", + "defence_animation": "285", + "weakness": "7", + "magic_animation": "284", + "death_animation": "287", + "name": "Pee Hat", + "defence_level": "50", + "safespot": null, + "lifepoints": "120", + "strength_level": "100", + "id": "1097", + "aggressive": "true", + "bonuses": "40,40,40,0,0,25,25,40,200,200,0,70,0,0,0", + "range_level": "1", + "attack_level": "50" + }, + { + "examine": "A nasty looking troll.", + "melee_animation": "284", + "range_animation": "284", + "attack_speed": "6", + "respawn_delay": "60", + "defence_animation": "285", + "weakness": "7", + "magic_animation": "284", + "death_animation": "287", + "name": "Kraka", + "defence_level": "50", + "safespot": null, + "lifepoints": "120", + "strength_level": "100", + "id": "1098", + "aggressive": "true", + "bonuses": "40,40,40,0,0,25,25,40,200,400,0,70,0,0,0", + "range_level": "1", + "attack_level": "50" + }, + { + "examine": "Human is his speciality.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "weakness": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Dung", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1099", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Human is his speciality.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "weakness": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ash", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1100", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "agg_radius": "6", + "examine": "Small for a troll, but mean, ugly and throws rocks.", + "melee_animation": "284", + "range_animation": "284", + "attack_speed": "7", + "respawn_delay": "35", + "defence_animation": "285", + "weakness": "0", + "magic_animation": "284", + "death_animation": "287", + "name": "Thrower Troll", + "defence_level": "30", + "safespot": null, + "lifepoints": "95", + "strength_level": "41", + "id": "1101", + "range_level": "40", + "projectile": "276", + "attack_level": "41" + }, + { + "agg_radius": "6", + "examine": "Small for a troll, but mean, ugly and throws rocks.", + "melee_animation": "284", + "range_animation": "284", + "attack_speed": "7", + "respawn_delay": "35", + "defence_animation": "285", + "weakness": "0", + "magic_animation": "284", + "death_animation": "287", + "name": "Thrower Troll", + "defence_level": "30", + "safespot": null, + "lifepoints": "95", + "strength_level": "41", + "id": "1102", + "range_level": "40", + "projectile": "276", + "attack_level": "41" + }, + { + "agg_radius": "6", + "examine": "Small for a troll, but mean, ugly and throws rocks.", + "melee_animation": "284", + "range_animation": "284", + "attack_speed": "7", + "respawn_delay": "35", + "defence_animation": "285", + "weakness": "0", + "magic_animation": "284", + "death_animation": "287", + "name": "Thrower Troll", + "defence_level": "30", + "safespot": null, + "lifepoints": "95", + "strength_level": "41", + "id": "1103", + "range_level": "40", + "projectile": "276", + "attack_level": "41" + }, + { + "agg_radius": "6", + "examine": "Small for a troll, but mean, ugly and throws rocks.", + "melee_animation": "284", + "range_animation": "284", + "attack_speed": "7", + "respawn_delay": "35", + "defence_animation": "285", + "weakness": "0", + "magic_animation": "284", + "death_animation": "287", + "name": "Thrower Troll", + "defence_level": "30", + "safespot": null, + "lifepoints": "95", + "strength_level": "41", + "id": "1104", + "range_level": "40", + "projectile": "276", + "attack_level": "41" + }, + { + "agg_radius": "6", + "examine": "Small for a troll, but mean, ugly and throws rocks.", + "melee_animation": "284", + "range_animation": "284", + "attack_speed": "7", + "respawn_delay": "35", + "defence_animation": "285", + "weakness": "0", + "magic_animation": "284", + "death_animation": "287", + "name": "Thrower Troll", + "defence_level": "30", + "safespot": null, + "lifepoints": "95", + "strength_level": "41", + "id": "1105", + "range_level": "40", + "projectile": "276", + "attack_level": "41" + }, + { + "examine": "Small for a troll, but mean and ugly.", + "melee_animation": "284", + "range_animation": "284", + "attack_speed": "5", + "defence_animation": "285", + "weakness": "7", + "magic_animation": "284", + "death_animation": "287", + "name": "Mountain troll", + "defence_level": "53", + "safespot": null, + "lifepoints": "90", + "strength_level": "20", + "id": "1106", + "range_level": "1", + "attack_level": "53" + }, + { + "examine": "Small for a troll, but mean and ugly.", + "melee_animation": "284", + "range_animation": "284", + "attack_speed": "5", + "defence_animation": "285", + "weakness": "7", + "magic_animation": "284", + "death_animation": "287", + "name": "Mountain troll", + "defence_level": "53", + "safespot": null, + "lifepoints": "90", + "strength_level": "20", + "id": "1107", + "range_level": "1", + "attack_level": "53" + }, + { + "examine": "Small for a troll, but mean and ugly.", + "melee_animation": "284", + "range_animation": "284", + "attack_speed": "5", + "defence_animation": "285", + "weakness": "7", + "magic_animation": "284", + "death_animation": "287", + "name": "Mountain troll", + "defence_level": "53", + "safespot": null, + "lifepoints": "90", + "strength_level": "20", + "id": "1108", + "range_level": "1", + "attack_level": "53" + }, + { + "examine": "Small for a troll, but mean and ugly.", + "melee_animation": "284", + "range_animation": "284", + "attack_speed": "5", + "defence_animation": "285", + "weakness": "7", + "magic_animation": "284", + "death_animation": "287", + "name": "Mountain troll", + "defence_level": "53", + "safespot": null, + "lifepoints": "90", + "strength_level": "20", + "id": "1109", + "range_level": "1", + "attack_level": "53" + }, + { + "examine": "Small for a troll, but mean and ugly.", + "melee_animation": "284", + "range_animation": "284", + "attack_speed": "5", + "defence_animation": "285", + "weakness": "7", + "magic_animation": "284", + "death_animation": "287", + "name": "Mountain troll", + "defence_level": "53", + "safespot": null, + "lifepoints": "90", + "strength_level": "20", + "id": "1110", + "range_level": "1", + "attack_level": "53" + }, + { + "examine": "Small for a troll, but mean and ugly.", + "melee_animation": "284", + "range_animation": "284", + "attack_speed": "5", + "defence_animation": "285", + "weakness": "7", + "magic_animation": "284", + "death_animation": "287", + "name": "Mountain troll", + "defence_level": "53", + "safespot": null, + "lifepoints": "90", + "strength_level": "20", + "id": "1111", + "range_level": "1", + "attack_level": "53" + }, + { + "examine": "Small for a troll, but mean and ugly.", + "melee_animation": "284", + "range_animation": "284", + "attack_speed": "5", + "defence_animation": "285", + "weakness": "7", + "magic_animation": "284", + "death_animation": "287", + "name": "Mountain troll", + "defence_level": "53", + "safespot": null, + "lifepoints": "90", + "strength_level": "20", + "id": "1112", + "range_level": "1", + "attack_level": "53" + }, + { + "examine": "One of the troll generals.", + "melee_animation": "1259", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "287", + "name": "Troll general", + "defence_level": "65", + "safespot": null, + "lifepoints": "92", + "strength_level": "65", + "id": "1115", + "aggressive": "true", + "range_level": "1", + "attack_level": "65" + }, + { + "examine": "One of the troll generals.", + "melee_animation": "1259", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "287", + "name": "Troll general", + "defence_level": "65", + "safespot": null, + "lifepoints": "92", + "strength_level": "65", + "id": "1116", + "aggressive": "true", + "range_level": "1", + "attack_level": "65" + }, + { + "examine": "One of the troll generals.", + "melee_animation": "1259", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "287", + "name": "Troll general", + "defence_level": "65", + "safespot": null, + "lifepoints": "92", + "strength_level": "65", + "id": "1117", + "aggressive": "true", + "range_level": "1", + "attack_level": "65" + }, + { + "examine": "He's watching the arena.", + "melee_animation": "1259", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "287", + "name": "Troll spectator", + "defence_level": "47", + "safespot": null, + "lifepoints": "67", + "strength_level": "47", + "id": "1118", + "range_level": "1", + "attack_level": "47" + }, + { + "examine": "He's watching the arena.", + "melee_animation": "1259", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "287", + "name": "Troll spectator", + "defence_level": "47", + "safespot": null, + "lifepoints": "67", + "strength_level": "47", + "id": "1119", + "range_level": "1", + "attack_level": "47" + }, + { + "examine": "He's watching the arena.", + "melee_animation": "1259", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "287", + "name": "Troll spectator", + "defence_level": "47", + "safespot": null, + "lifepoints": "67", + "strength_level": "47", + "id": "1120", + "range_level": "1", + "attack_level": "47" + }, + { + "examine": "He's watching the arena.", + "melee_animation": "1259", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "287", + "name": "Troll spectator", + "defence_level": "47", + "safespot": null, + "lifepoints": "67", + "strength_level": "47", + "id": "1121", + "range_level": "1", + "attack_level": "47" + }, + { + "examine": "He's watching the arena.", + "melee_animation": "1259", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "287", + "name": "Troll spectator", + "defence_level": "47", + "safespot": null, + "lifepoints": "67", + "strength_level": "47", + "id": "1122", + "range_level": "1", + "attack_level": "47" + }, + { + "examine": "He's watching the arena.", + "melee_animation": "1259", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "287", + "name": "Troll spectator", + "defence_level": "47", + "safespot": null, + "lifepoints": "67", + "strength_level": "47", + "id": "1123", + "range_level": "1", + "attack_level": "47" + }, + { + "examine": "He's watching the arena.", + "melee_animation": "1259", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "287", + "name": "Troll spectator", + "defence_level": "47", + "safespot": null, + "lifepoints": "67", + "strength_level": "47", + "id": "1124", + "range_level": "1", + "attack_level": "47" + }, + { + "examine": "An unusually large troll.", + "melee_animation": "1158", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "287", + "name": "Dad", + "defence_level": "50", + "safespot": null, + "lifepoints": "120", + "strength_level": "120", + "id": "1125", + "bonuses": "40,40,40,0,0,25,25,40,200,200,0,70,0,0,0", + "range_level": "1", + "attack_level": "60" + }, + { + "examine": "He's guarding the cells.", + "range_animation": "0", + "melee_animation": "1158", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "287", + "name": "Twig", + "defence_level": "25", + "safespot": null, + "lifepoints": "90", + "strength_level": "90", + "id": "1126", + "aggressive": "true", + "bonuses": "20,20,20,0,0,0,0,10,200,200,0,20,0,0,0", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "He's guarding the cells.", + "range_animation": "0", + "melee_animation": "1158", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "287", + "name": "Berry", + "defence_level": "40", + "safespot": null, + "lifepoints": "90", + "strength_level": "90", + "id": "1127", + "aggressive": "true", + "bonuses": "20,20,20,0,0,0,0,10,200,200,0,20,0,0,0", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "He's guarding the cells.", + "range_animation": "0", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "name": "Twig", + "defence_level": "25", + "safespot": null, + "lifepoints": "90", + "strength_level": "90", + "id": "1128", + "bonuses": "20,20,20,0,0,0,0,10,200,200,0,20,0,0,0", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "He's guarding the cells.", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "name": "Berry", + "defence_level": "40", + "safespot": null, + "lifepoints": "90", + "strength_level": "90", + "id": "1129", + "bonuses": "20,20,20,0,0,0,0,10,200,200,0,20,0,0,0", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "Small for a troll, but it's mean, ugly and throws rocks.", + "start_gfx": "33", + "combat_style": "1", + "melee_animation": "284", + "range_animation": "284", + "attack_speed": "7", + "respawn_delay": "35", + "defence_animation": "285", + "weakness": "0", + "magic_animation": "284", + "death_animation": "287", + "name": "Thrower troll", + "defence_level": "30", + "safespot": null, + "lifepoints": "95", + "strength_level": "41", + "id": "1130", + "aggressive": "true", + "bonuses": "30,60,40,40,50,70,50,0,0,0,0,0,0,0,0", + "range_level": "40", + "projectile": "276", + "attack_level": "41" + }, + { + "agg_radius": "6", + "examine": "Small for a troll, but it's mean, ugly and throws rocks.", + "start_gfx": "33", + "combat_style": "1", + "melee_animation": "284", + "range_animation": "284", + "attack_speed": "7", + "respawn_delay": "35", + "defence_animation": "285", + "weakness": "0", + "magic_animation": "284", + "death_animation": "287", + "name": "Thrower troll", + "defence_level": "30", + "safespot": null, + "lifepoints": "95", + "strength_level": "41", + "id": "1131", + "aggressive": "true", + "bonuses": "30,60,40,40,50,70,50,0,0,0,0,0,0,0,0", + "range_level": "40", + "projectile": "276", + "attack_level": "41" + }, + { + "agg_radius": "6", + "examine": "Small for a troll, but it's mean, ugly and throws rocks.", + "start_gfx": "33", + "combat_style": "1", + "melee_animation": "284", + "range_animation": "284", + "attack_speed": "7", + "respawn_delay": "35", + "defence_animation": "285", + "weakness": "0", + "magic_animation": "284", + "death_animation": "287", + "name": "Thrower troll", + "defence_level": "30", + "safespot": null, + "lifepoints": "95", + "strength_level": "41", + "id": "1132", + "aggressive": "true", + "bonuses": "30,60,40,40,50,70,50,0,0,0,0,0,0,0,0", + "range_level": "40", + "projectile": "276", + "attack_level": "41" + }, + { + "agg_radius": "6", + "examine": "Small for a troll, but it's mean, ugly and throws rocks.", + "start_gfx": "33", + "combat_style": "1", + "melee_animation": "284", + "range_animation": "284", + "attack_speed": "7", + "respawn_delay": "35", + "defence_animation": "285", + "weakness": "0", + "magic_animation": "284", + "death_animation": "287", + "name": "Thrower troll", + "defence_level": "30", + "safespot": null, + "lifepoints": "95", + "strength_level": "41", + "id": "1133", + "aggressive": "true", + "bonuses": "30,60,40,40,50,70,50,0,0,0,0,0,0,0,0", + "range_level": "40", + "projectile": "276", + "attack_level": "41" + }, + { + "agg_radius": "6", + "examine": "Small for a troll, but it's mean, ugly and throws rocks.", + "start_gfx": "33", + "combat_style": "1", + "melee_animation": "284", + "range_animation": "284", + "attack_speed": "7", + "respawn_delay": "35", + "defence_animation": "285", + "weakness": "0", + "magic_animation": "284", + "death_animation": "287", + "name": "Thrower troll", + "defence_level": "30", + "safespot": null, + "lifepoints": "95", + "strength_level": "41", + "id": "1134", + "aggressive": "true", + "bonuses": "30,60,40,40,50,70,50,0,0,0,0,0,0,0,0", + "range_level": "40", + "projectile": "276", + "attack_level": "41" + }, + { + "examine": "Human is his speciality.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cook", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1135", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Human is his speciality.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cook", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1136", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Human is his speciality.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cook", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1137", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Small for a troll, but mean and ugly.", + "melee_animation": "284", + "range_animation": "284", + "attack_speed": "5", + "defence_animation": "285", + "weakness": "7", + "magic_animation": "284", + "death_animation": "287", + "name": "Mountain troll", + "defence_level": "53", + "safespot": null, + "lifepoints": "90", + "strength_level": "20", + "id": "1138", + "range_level": "1", + "attack_level": "53" + }, + { + "examine": "He's fast asleep.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "0", + "name": "Mushroom", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1139", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "This beast doesn't need climbing boots.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Mountain goat", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1140", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "This beast doesn't need climbing boots.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Mountain goat", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1141", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He's guarding the storeroom.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1142", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He's guarding the storeroom.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1143", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "1144", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "1145", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "1146", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "1147", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "1148", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "death_animation": "", + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "1149", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He's guarding the goutweed.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1150", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Human is his speciality.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Burntmeat", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1151", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "What's he mumbling about?", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Weird Old Man", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1152", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "I don't think insect repellent will work...", + "melee_animation": "6223", + "range_animation": "6223", + "combat_audio": "571,573,572", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "38", + "defence_animation": "6232", + "weakness": "7", + "slayer_exp": "40", + "magic_animation": "6223", + "death_animation": "6230", + "name": "Kalphite Worker", + "defence_level": "20", + "safespot": null, + "lifepoints": "40", + "strength_level": "20", + "id": "1153", + "bonuses": "0,0,0,0,0,5,5,1,10,10,0,0,0,0,0", + "range_level": "1", + "attack_level": "20" + }, + { + "examine": "I don't think insect repellent will work...", + "melee_animation": "6224", + "range_animation": "0", + "combat_audio": "567,569,568", + "attack_speed": "4", + "poisonous": "true", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "6227", + "weakness": "7", + "slayer_exp": "90", + "poison_amount": "4", + "magic_animation": "0", + "death_animation": "6228", + "name": "Kalphite Soldier", + "defence_level": "70", + "safespot": null, + "lifepoints": "90", + "strength_level": "70", + "id": "1154", + "aggressive": "true", + "bonuses": "0,0,0,0,0,25,25,5,50,50,0,0,0,0,0", + "range_level": "1", + "attack_level": "70" + }, + { + "examine": "I don't think insect repellent will work...", + "melee_animation": "6223", + "range_animation": "6223", + "attack_speed": "4", + "poisonous": "true", + "magic_level": "1", + "respawn_delay": "65", + "defence_animation": "6232", + "weakness": "7", + "poison_amount": "6", + "magic_animation": "6223", + "death_animation": "6230", + "name": "Kalphite Guardian", + "defence_level": "110", + "safespot": null, + "lifepoints": "170", + "strength_level": "110", + "id": "1155", + "aggressive": "true", + "bonuses": "0,0,0,0,0,25,25,5,50,50,0,0,0,0,0", + "range_level": "1", + "attack_level": "110" + }, + { + "examine": "I don't think insect repellent will work...", + "melee_animation": "6223", + "range_animation": "6223", + "combat_audio": "571,573,572", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "38", + "defence_animation": "6232", + "weakness": "7", + "slayer_exp": "40", + "magic_animation": "6223", + "death_animation": "6230", + "name": "Kalphite Worker", + "defence_level": "20", + "safespot": null, + "lifepoints": "40", + "strength_level": "20", + "id": "1156", + "bonuses": "0,0,0,0,0,5,5,1,10,10,0,0,0,0,0", + "range_level": "1", + "attack_level": "20" + }, + { + "examine": "I don't think insect repellent will work...", + "melee_animation": "6223", + "range_animation": "6223", + "attack_speed": "4", + "poisonous": "true", + "magic_level": "1", + "respawn_delay": "65", + "defence_animation": "6232", + "weakness": "7", + "poison_amount": "6", + "magic_animation": "6223", + "death_animation": "6230", + "name": "Kalphite Guardian", + "defence_level": "110", + "safespot": null, + "lifepoints": "170", + "strength_level": "110", + "id": "1157", + "aggressive": "true", + "bonuses": "0,0,0,0,0,25,25,5,50,50,0,0,0,0,0", + "range_level": "1", + "attack_level": "110" + }, + { + "agg_radius": "64", + "examine": "I don't think insect repellent will work...", + "melee_animation": "6241", + "range_animation": "6241", + "attack_speed": "4", + "poisonous": "true", + "magic_level": "150", + "respawn_delay": "0", + "defence_animation": "6232", + "weakness": "10", + "magic_animation": "6241", + "death_animation": "6242", + "name": "Kalphite Queen", + "defence_level": "300", + "safespot": null, + "lifepoints": "255", + "strength_level": "300", + "id": "1158", + "aggressive": "true", + "bonuses": "0,0,0,0,0,50,50,10,100,100,0,0,0,0,0", + "range_level": "1000", + "attack_level": "300" + }, + { + "agg_radius": "64", + "examine": "I don't think insect repellent will work...", + "melee_animation": "6235", + "range_animation": "6235", + "attack_speed": "4", + "magic_level": "150", + "respawn_delay": "45", + "defence_animation": "6234", + "weakness": "10", + "magic_animation": "6235", + "death_animation": "6233", + "name": "Kalphite Queen", + "defence_level": "300", + "safespot": null, + "lifepoints": "255", + "strength_level": "300", + "id": "1160", + "aggressive": "true", + "bonuses": "0,0,0,0,0,100,100,100,10,10,0,0,0,0,0", + "range_level": "1000", + "attack_level": "300" + }, + { + "examine": "I don't think insect repellent will work...", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Kalphite Larva", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1161", + "aggressive": "false", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A huge beast, resembling in some ways a lion, but mostly a twisted nightmare.", + "melee_animation": "1199", + "range_animation": "1197", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "1200", + "weakness": "9", + "magic_animation": "1197", + "death_animation": "1201", + "name": "The Shaikahan", + "defence_level": "50", + "safespot": null, + "lifepoints": "100", + "strength_level": "50", + "id": "1172", + "aggressive": "true", + "range_level": "1", + "attack_level": "50" + }, + { + "examine": "He looks pretty handy with that bow.", + "start_gfx": "250", + "combat_style": "1", + "melee_animation": "428", + "range_animation": "426", + "combat_audio": "425,427,426", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "2", + "magic_animation": "0", + "death_animation": "836", + "name": "Elf warrior", + "defence_level": "64", + "safespot": null, + "lifepoints": "91", + "strength_level": "1", + "id": "1183", + "clue_level": "2", + "range_level": "72", + "projectile": "249", + "attack_level": "1" + }, + { + "examine": "I don't wanna be at the wrong end of that pike.", + "melee_animation": "428", + "range_animation": "0", + "combat_audio": "425,427,426", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Elf warrior", + "defence_level": "68", + "safespot": null, + "lifepoints": "85", + "strength_level": "68", + "id": "1184", + "clue_level": "2", + "range_level": "1", + "attack_level": "68" + }, + { + "examine": "An elven city guard.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Elven city guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1185", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A cute bunny rabbit.", + "melee_animation": "6090", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "6092", + "name": "Rabbit", + "defence_level": "1", + "safespot": null, + "lifepoints": "1", + "strength_level": "1", + "id": "1192", + "range_level": "1", + "attack_level": "1" + }, + { + "death_animation": "6092", + "name": "Rabbit", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "melee_animation": "6090", + "strength_level": "1", + "id": "1193", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1", + "defence_animation": "6091" + }, + { + "death_animation": "6092", + "name": "Rabbit", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "melee_animation": "6090", + "strength_level": "1", + "id": "1194", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1", + "defence_animation": "6091" + }, + { + "examine": "It's an NPC.", + "melee_animation": "4921", + "combat_audio": "300,302,301", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "50", + "defence_animation": "4927", + "slayer_exp": "0", + "death_animation": "4929", + "name": "Grizzly bear", + "defence_level": "35", + "safespot": null, + "lifepoints": "35", + "strength_level": "36", + "id": "1195", + "aggressive": "true", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "Eek! A bear cub!", + "range_animation": "0", + "combat_audio": "498,500,499", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "name": "Grizzly bear cub", + "defence_level": "21", + "safespot": null, + "lifepoints": "30", + "strength_level": "21", + "id": "1196", + "range_level": "1", + "attack_level": "21" + }, + { + "name": "Grizzly bear cub", + "defence_level": "1", + "safespot": null, + "lifepoints": "35", + "combat_audio": "498,500,499", + "strength_level": "1", + "id": "1197", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "examine": "What big teeth you have.", + "melee_animation": "6559", + "range_animation": "0", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "6558", + "name": "Dire Wolf", + "defence_level": "33", + "safespot": null, + "lifepoints": "47", + "strength_level": "33", + "id": "1198", + "range_level": "1", + "attack_level": "33" + }, + { + "examine": "An elf tracker.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Elf Tracker", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1199", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of King Tyras's men.", + "melee_animation": "414", + "range_animation": "0", + "attack_speed": "6", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "836", + "name": "Tyras guard", + "defence_level": "42", + "safespot": null, + "lifepoints": "60", + "strength_level": "42", + "id": "1200", + "range_level": "1", + "attack_level": "42" + }, + { + "examine": "I don't want to get on the wrong side of him.", + "start_gfx": "250", + "combat_style": "1", + "melee_animation": "426", + "combat_audio": "425,427,426", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Elf warrior", + "defence_level": "1", + "safespot": null, + "lifepoints": "105", + "strength_level": "1", + "id": "1201", + "clue_level": "2", + "range_level": "1", + "projectile": "249", + "attack_level": "1" + }, + { + "examine": "One of King Tyras's men.", + "melee_animation": "395", + "attack_speed": "6", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Tyras guard", + "defence_level": "110", + "safespot": null, + "lifepoints": "110", + "strength_level": "105", + "id": "1203", + "range_level": "50", + "attack_level": "95" + }, + { + "examine": "One of King Tyras's men.", + "melee_animation": "395", + "attack_speed": "6", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Tyras guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "112", + "strength_level": "1", + "id": "1204", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Responsible for the food and equipment of the troops.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Quartermaster", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1208", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Mysterious swamp lights...", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Will o' the wisp", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1211", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He seems strangely familiar...", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Parroty Pete", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1216", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An old gardener.", + "melee_animation": "433", + "range_animation": "0", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "836", + "name": "Gardener", + "defence_level": "4", + "safespot": null, + "lifepoints": "5", + "strength_level": "4", + "id": "1217", + "range_level": "1", + "attack_level": "4" + }, + { + "examine": "A scary, man eating ghoul.", + "melee_animation": "422", + "range_animation": "422", + "combat_audio": "442,444,443", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "35", + "defence_animation": "404", + "weakness": "9", + "slayer_exp": "50", + "magic_animation": "422", + "death_animation": "9055", + "name": "Ghoul", + "defence_level": "30", + "safespot": null, + "lifepoints": "50", + "strength_level": "40", + "id": "1218", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "Yuck! It's all slimy!", + "melee_animation": "1273", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "1272", + "name": "Leech", + "defence_level": "42", + "safespot": null, + "lifepoints": "60", + "strength_level": "42", + "id": "1219", + "aggressive": "true", + "range_level": "1", + "attack_level": "42" + }, + { + "examine": "It looks very hungry!", + "melee_animation": "1264", + "slayer_exp": "50", + "death_animation": "7185", + "name": "Vampire", + "defence_level": "52", + "safespot": null, + "lifepoints": "50", + "strength_level": "1", + "id": "1220", + "clue_level": "1", + "range_level": "1", + "attack_level": "52" + }, + { + "examine": "It looks very hungry!", + "melee_animation": "1264", + "slayer_exp": "40", + "name": "Vampire", + "defence_level": "1", + "safespot": null, + "lifepoints": "50", + "strength_level": "1", + "id": "1223", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It looks very hungry!", + "name": "Vampire", + "defence_level": "1", + "safespot": null, + "lifepoints": "50", + "strength_level": "1", + "id": "1225", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A marsh coloured blamish snail, these types are said to spit acid.", + "combat_style": "1", + "melee_animation": "8143", + "range_animation": "0", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "50", + "defence_animation": "0", + "weakness": "9", + "slayer_exp": "0", + "magic_animation": "0", + "death_animation": "8144", + "name": "Myre Blamish Snail", + "defence_level": "22", + "safespot": null, + "lifepoints": "8", + "strength_level": "0", + "id": "1227", + "aggressive": "true", + "bonuses": "10,10,10,0,0,5,5,30,5,50,0,10,0,0,0", + "range_level": "5", + "attack_level": "0" + }, + { + "examine": "A blood coloured blamish snail, these types are said to spit acid.", + "combat_style": "1", + "melee_animation": "8143", + "range_animation": "0", + "attack_speed": "6", + "magic_level": "1", + "respawn_delay": "50", + "defence_animation": "0", + "weakness": "9", + "slayer_exp": "0", + "magic_animation": "0", + "death_animation": "8144", + "name": "Blood Blamish Snail", + "defence_level": "45", + "safespot": null, + "lifepoints": "13", + "strength_level": "0", + "id": "1228", + "aggressive": "true", + "bonuses": "10,10,10,0,0,5,5,30,5,50,0,10,0,0,0", + "range_level": "12", + "attack_level": "0" + }, + { + "examine": "A muddy coloured blamish snail, these types are said to spit acid.", + "combat_style": "1", + "melee_animation": "8143", + "range_animation": "0", + "attack_speed": "6", + "magic_level": "1", + "respawn_delay": "50", + "defence_animation": "0", + "weakness": "9", + "slayer_exp": "0", + "magic_animation": "0", + "death_animation": "8144", + "name": "Ochre Blamish Snail", + "defence_level": "18", + "safespot": null, + "lifepoints": "10", + "strength_level": "0", + "id": "1229", + "aggressive": "true", + "bonuses": "10,10,10,0,0,5,5,30,5,50,0,10,0,0,0", + "range_level": "7", + "attack_level": "0" + }, + { + "examine": "A bruise blue coloured blamish snail, these types are said to spit acid.", + "combat_style": "1", + "melee_animation": "8143", + "range_animation": "0", + "attack_speed": "6", + "magic_level": "1", + "respawn_delay": "50", + "defence_animation": "0", + "weakness": "9", + "slayer_exp": "0", + "magic_animation": "0", + "death_animation": "8144", + "name": "Bruise Blamish Snail", + "defence_level": "40", + "safespot": null, + "lifepoints": "12", + "strength_level": "0", + "id": "1230", + "aggressive": "true", + "bonuses": "10,10,10,0,0,5,5,30,5,50,0,10,0,0,0", + "range_level": "15", + "attack_level": "0" + }, + { + "agg_radius": "", + "examine": "A branch bark coloured blamish snail, these types are said to spit acid.", + "combat_style": "1", + "melee_animation": "8143", + "range_animation": "0", + "attack_speed": "6", + "magic_level": "1", + "respawn_delay": "50", + "defence_animation": "0", + "weakness": "9", + "slayer_exp": "0", + "magic_animation": "0", + "death_animation": "8144", + "name": "Bark Blamish Snail", + "defence_level": "20", + "safespot": null, + "lifepoints": "22", + "strength_level": "0", + "id": "1231", + "aggressive": "true", + "bonuses": "10,10,10,0,0,5,5,30,5,50,0,10,0,0,0", + "range_level": "10", + "attack_level": "0" + }, + { + "examine": "A marsh coloured blamish snail, these types are said to spit acid.", + "combat_style": "1", + "melee_animation": "8143", + "range_animation": "0", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "50", + "defence_animation": "0", + "weakness": "9", + "slayer_exp": "0", + "magic_animation": "0", + "death_animation": "8144", + "name": "Myre Blamish Snail", + "defence_level": "22", + "safespot": null, + "lifepoints": "8", + "strength_level": "0", + "id": "1232", + "aggressive": "true", + "bonuses": "10,10,10,0,0,5,5,30,5,50,0,10,0,0,0", + "range_level": "5", + "attack_level": "0" + }, + { + "examine": "A blood coloured blamish snail, these types are said to spit acid.", + "combat_style": "1", + "melee_animation": "8143", + "range_animation": "0", + "attack_speed": "6", + "magic_level": "1", + "respawn_delay": "50", + "defence_animation": "0", + "weakness": "9", + "slayer_exp": "0", + "magic_animation": "0", + "death_animation": "8144", + "name": "Blood Blamish Snail", + "defence_level": "45", + "safespot": null, + "lifepoints": "13", + "strength_level": "0", + "id": "1233", + "aggressive": "true", + "bonuses": "10,10,10,0,0,5,5,30,5,50,0,10,0,0,0", + "range_level": "12", + "attack_level": "0" + }, + { + "examine": "A muddy coloured blamish snail, these types are said to spit acid.", + "combat_style": "1", + "melee_animation": "8143", + "range_animation": "0", + "attack_speed": "6", + "magic_level": "1", + "respawn_delay": "50", + "defence_animation": "0", + "weakness": "9", + "slayer_exp": "0", + "magic_animation": "0", + "death_animation": "8144", + "name": "Ochre Blamish Snail", + "defence_level": "18", + "safespot": null, + "lifepoints": "10", + "strength_level": "0", + "id": "1234", + "aggressive": "true", + "bonuses": "10,10,10,0,0,5,5,30,5,50,0,10,0,0,0", + "range_level": "7", + "attack_level": "0" + }, + { + "examine": "A bruise blue coloured blamish snail, these types are said to spit acid.", + "combat_style": "1", + "melee_animation": "8143", + "range_animation": "0", + "attack_speed": "6", + "magic_level": "1", + "respawn_delay": "50", + "defence_animation": "0", + "weakness": "9", + "slayer_exp": "0", + "magic_animation": "0", + "death_animation": "8144", + "name": "Bruise Blamish Snail", + "defence_level": "40", + "safespot": null, + "lifepoints": "12", + "strength_level": "0", + "id": "1235", + "aggressive": "true", + "bonuses": "10,10,10,0,0,5,5,30,5,50,0,10,0,0,0", + "range_level": "15", + "attack_level": "0" + }, + { + "examine": "A Bedabin nomad fighter - a sandy swordsman.", + "melee_animation": "390", + "range_animation": "0", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Bedabin Nomad Fighter", + "defence_level": "30", + "safespot": null, + "lifepoints": "42", + "strength_level": "30", + "id": "1239", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "A shadowy sort of entity", + "melee_animation": "0", + "range_animation": "0", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "3", + "magic_animation": "0", + "death_animation": "0", + "name": "Loar Shadow", + "defence_level": "26", + "safespot": null, + "lifepoints": "38", + "strength_level": "30", + "id": "1240", + "aggressive": "true", + "range_level": "1", + "attack_level": "45" + }, + { + "examine": "The shadowy remains of a long departed soul.", + "melee_animation": "1283", + "range_animation": "0", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "1284", + "weakness": "3", + "magic_animation": "0", + "death_animation": "1308", + "name": "Loar Shade", + "defence_level": "26", + "safespot": null, + "lifepoints": "38", + "strength_level": "30", + "id": "1241", + "aggressive": "true", + "range_level": "1", + "attack_level": "45" + }, + { + "examine": "A shadowy sort of entity", + "melee_animation": "0", + "range_animation": "0", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "3", + "magic_animation": "0", + "death_animation": "0", + "name": "Phrin Shadow", + "defence_level": "42", + "safespot": null, + "lifepoints": "56", + "strength_level": "47", + "id": "1243", + "aggressive": "true", + "range_level": "1", + "attack_level": "64" + }, + { + "examine": "The shadowy remains of a long departed soul.", + "melee_animation": "1283", + "range_animation": "0", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "3", + "magic_animation": "0", + "death_animation": "1287", + "name": "Phrin Shade", + "defence_level": "42", + "safespot": null, + "lifepoints": "56", + "strength_level": "47", + "id": "1244", + "aggressive": "true", + "range_level": "1", + "attack_level": "64" + }, + { + "examine": "A shadowy sort of entity", + "melee_animation": "0", + "range_animation": "0", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "3", + "magic_animation": "0", + "death_animation": "0", + "name": "Riyl Shadow", + "defence_level": "60", + "safespot": null, + "lifepoints": "76", + "strength_level": "55", + "id": "1245", + "aggressive": "true", + "range_level": "1", + "attack_level": "88" + }, + { + "examine": "The shadowy remains of a long departed soul.", + "melee_animation": "1283", + "range_animation": "0", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "3", + "magic_animation": "0", + "death_animation": "1287", + "name": "Riyl Shade", + "defence_level": "60", + "safespot": null, + "lifepoints": "76", + "strength_level": "55", + "id": "1246", + "aggressive": "true", + "range_level": "1", + "attack_level": "88" + }, + { + "examine": "A shadowy sort of entity", + "melee_animation": "0", + "range_animation": "0", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "3", + "magic_animation": "0", + "death_animation": "0", + "name": "Asyn Shadow", + "defence_level": "70", + "safespot": null, + "lifepoints": "90", + "strength_level": "84", + "id": "1247", + "aggressive": "true", + "range_level": "1", + "attack_level": "102" + }, + { + "examine": "The shadowy remains of a long departed soul.", + "melee_animation": "1283", + "range_animation": "0", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "3", + "magic_animation": "0", + "death_animation": "1287", + "name": "Asyn Shade", + "defence_level": "70", + "safespot": null, + "lifepoints": "90", + "strength_level": "84", + "id": "1248", + "aggressive": "true", + "range_level": "1", + "attack_level": "102" + }, + { + "examine": "A shadowy sort of entity", + "melee_animation": "0", + "range_animation": "0", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "3", + "magic_animation": "0", + "death_animation": "0", + "name": "Fiyr Shadow", + "defence_level": "85", + "safespot": null, + "lifepoints": "110", + "strength_level": "100", + "id": "1249", + "aggressive": "true", + "range_level": "1", + "attack_level": "120" + }, + { + "examine": "The shadowy remains of a long departed soul.", + "melee_animation": "1283", + "range_animation": "0", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "3", + "magic_animation": "0", + "death_animation": "1287", + "name": "Fiyr Shade", + "defence_level": "85", + "safespot": null, + "lifepoints": "110", + "strength_level": "100", + "id": "1250", + "aggressive": "true", + "range_level": "1", + "attack_level": "120" + }, + { + "examine": "A local villager of Mort'ton.", + "melee_animation": "422", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "836", + "name": "Afflicted", + "defence_level": "43", + "safespot": null, + "lifepoints": "61", + "strength_level": "43", + "id": "1257", + "range_level": "1", + "attack_level": "43" + }, + { + "examine": "A local villager of Mort'ton.", + "melee_animation": "422", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "836", + "name": "Afflicted", + "defence_level": "44", + "safespot": null, + "lifepoints": "62", + "strength_level": "44", + "id": "1258", + "range_level": "1", + "attack_level": "44" + }, + { + "examine": "A local villager of Mort'ton.", + "melee_animation": "422", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "836", + "name": "Afflicted", + "defence_level": "45", + "safespot": null, + "lifepoints": "64", + "strength_level": "45", + "id": "1261", + "range_level": "1", + "attack_level": "45" + }, + { + "examine": "A local villager of Mort'ton.", + "melee_animation": "422", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "836", + "name": "Afflicted", + "defence_level": "46", + "safespot": null, + "lifepoints": "65", + "strength_level": "46", + "id": "1262", + "aggressive": "true", + "range_level": "1", + "attack_level": "46" + }, + { + "examine": "Slightly more magical.", + "name": "Wizard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "1263", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A follower of Saradomin.", + "melee_animation": "376", + "range_animation": "0", + "poisonous": "true", + "magic_level": "90", + "spell_id": "41", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "3", + "magic_animation": "811", + "death_animation": "836", + "name": "Saradomin wizard", + "defence_level": "70", + "safespot": null, + "lifepoints": "120", + "strength_level": "90", + "id": "1264", + "aggressive": "true", + "range_level": "70", + "attack_level": "90" + }, + { + "examine": "No one likes crabs...", + "melee_animation": "1312", + "range_animation": "1312", + "combat_audio": "717,723,722", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "50", + "defence_animation": "1313", + "weakness": "7", + "magic_animation": "1312", + "death_animation": "1314", + "name": "Rock Crab", + "defence_level": "1", + "safespot": null, + "lifepoints": "50", + "strength_level": "1", + "id": "1265", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A rocky outcrop.", + "melee_animation": "1312", + "range_animation": "1312", + "attack_speed": "5", + "defence_animation": "1313", + "weakness": "7", + "magic_animation": "1312", + "death_animation": "1314", + "name": "Rocks", + "defence_level": "1", + "safespot": null, + "lifepoints": "50", + "strength_level": "1", + "id": "1266", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "No one likes crabs...", + "melee_animation": "1312", + "range_animation": "1312", + "combat_audio": "717,723,722", + "attack_speed": "4", + "respawn_delay": "50", + "defence_animation": "1313", + "magic_animation": "1312", + "death_animation": "1314", + "name": "Rock Crab", + "defence_level": "1", + "safespot": null, + "lifepoints": "50", + "strength_level": "1", + "id": "1267", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A rocky outcrop.", + "melee_animation": "1312", + "range_animation": "1312", + "attack_speed": "5", + "defence_animation": "1313", + "magic_animation": "1312", + "death_animation": "1314", + "name": "Rocks", + "defence_level": "4", + "safespot": null, + "lifepoints": "50", + "strength_level": "1", + "id": "1268", + "aggressive": "true", + "range_level": "1", + "attack_level": "4" + }, + { + "examine": "A Fremennik bard.", + "melee_animation": "1312", + "range_animation": "1312", + "attack_speed": "5", + "defence_animation": "1313", + "magic_animation": "1312", + "death_animation": "1314", + "name": "Olaf the Bard", + "defence_level": "8", + "safespot": null, + "lifepoints": "50", + "strength_level": "1", + "id": "1269", + "aggressive": "true", + "range_level": "1", + "attack_level": "10" + }, + { + "examine": "Distinctly troll-shaped.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Lalli", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1270", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Freshly shorn.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Golden sheep", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1271", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Lovely thick wool.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Golden sheep", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1272", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A powerful spirit that lives in this lake.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fossegrimen", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1273", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Looks like he's had a few drinks already.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ospak", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1274", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Doesn't look like the musical type.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Styrmir", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1275", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Waiting for the show.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Torbrund", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1276", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He sits impatiently with his friends.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fridgeir", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1277", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He's fat, he's round, he bounces on the ground. That's how he got the job.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Longhall Bouncer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1278", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A fearful spirit of the drowned.", + "melee_animation": "390", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "The Draugen", + "defence_level": "40", + "safespot": null, + "lifepoints": "57", + "strength_level": "40", + "id": "1279", + "aggressive": "true", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "A Fremennik hunter.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Sigli the Huntsman", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1281", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A Fremennik merchant.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Sigmund The Merchant", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1282", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A Fremennik navigator.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Swensen the Navigator", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1283", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Every innkeeper's best friend!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Manni the Reveller", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1286", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Supposedly fixes things around Gielinor.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Council workman", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1287", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A Fremennik riddler.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Peer the Seer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1288", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A Fremennik hero.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Thorvald the Warrior", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1289", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Your challenge awaits! ", + "melee_animation": "390", + "range_animation": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "836", + "name": "Koschei the deathless", + "defence_level": "13", + "safespot": null, + "lifepoints": "14", + "strength_level": "13", + "id": "1290", + "range_level": "1", + "attack_level": "13" + }, + { + "examine": "He lives again!", + "melee_animation": "390", + "range_animation": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "836", + "name": "Koschei the deathless", + "defence_level": "13", + "safespot": null, + "lifepoints": "14", + "strength_level": "13", + "id": "1291", + "range_level": "1", + "attack_level": "13" + }, + { + "examine": "He keeps on living!", + "melee_animation": "390", + "range_animation": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "836", + "name": "Koschei the deathless", + "defence_level": "13", + "safespot": null, + "lifepoints": "14", + "strength_level": "13", + "id": "1292", + "range_level": "1", + "attack_level": "13" + }, + { + "examine": "He just keeps on going.", + "melee_animation": "390", + "range_animation": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "836", + "name": "Koschei the deathless", + "defence_level": "13", + "safespot": null, + "lifepoints": "14", + "strength_level": "13", + "id": "1293", + "range_level": "1", + "attack_level": "13" + }, + { + "examine": "The Fremennik tribe's chieftain.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Brundt the Chieftain", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1294", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Stands around and looks at stuff all day.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1296", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "1297", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "What a rubbish job he has.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Town Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1298", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The Longhall barkeep", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "A bartender.", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1300", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Pretty shabbily dressed for a clothes shop owner.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Yrsa", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1301", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "There's something fishy about this guy.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fisherman", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1302", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Sells and makes weapons and armour.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Skulgrimen", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1303", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He's strong to the finish", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Sailor", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1304", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of Rellekka's many citizens.", + "melee_animation": "422", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Agnar", + "defence_level": "1", + "safespot": null, + "lifepoints": "50", + "strength_level": "1", + "id": "1305", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of Rellekka's many citizens.", + "melee_animation": "422", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Freidir", + "defence_level": "1", + "safespot": null, + "lifepoints": "50", + "strength_level": "1", + "id": "1306", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of Rellekka's many citizens.", + "melee_animation": "395", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Borrokar", + "defence_level": "1", + "safespot": null, + "lifepoints": "50", + "strength_level": "1", + "id": "1307", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of Rellekka's many citizens.", + "melee_animation": "422", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Lanzig", + "defence_level": "1", + "safespot": null, + "lifepoints": "51", + "strength_level": "1", + "id": "1308", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of Rellekka's many citizens.", + "melee_animation": "422", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Pontak", + "defence_level": "1", + "safespot": null, + "lifepoints": "51", + "strength_level": "1", + "id": "1309", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of Rellekka's many citizens.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Sassilik", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1313", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of Rellekka's many citizens.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Inga", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1314", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Fish-tastic!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fish monger", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1315", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "I wonder what he does with all that fur?", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fur trader", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1316", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Keeps the stalls secure.", + "melee_animation": "390", + "range_animation": "0", + "combat_audio": "", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Market Guard", + "defence_level": "28", + "safespot": null, + "lifepoints": "40", + "strength_level": "28", + "id": "1317", + "range_level": "1", + "attack_level": "28" + }, + { + "examine": "A hardened Fremennik warrior.", + "melee_animation": "401", + "range_animation": "0", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Warrior", + "defence_level": "28", + "safespot": null, + "lifepoints": "40", + "strength_level": "28", + "id": "1318", + "range_level": "1", + "attack_level": "28" + }, + { + "examine": "A cunning animal.", + "melee_animation": "6562", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "6570", + "name": "Fox", + "defence_level": "32", + "safespot": null, + "lifepoints": "45", + "strength_level": "32", + "id": "1319", + "range_level": "1", + "attack_level": "32" + }, + { + "examine": "Hoppity", + "melee_animation": "1245", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "1246", + "name": "Bunny", + "defence_level": "1", + "safespot": null, + "lifepoints": "1", + "strength_level": "1", + "id": "1320", + "range_level": "1", + "attack_level": "1" + }, + { + "death_animation": "1246", + "name": "Bunny", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "melee_animation": "1245", + "strength_level": "1", + "id": "1321", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1", + "defence_animation": "1244" + }, + { + "examine": "Cute. But deadly.", + "range_animation": "0", + "combat_audio": "498,500,499", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "name": "Bear Cub", + "defence_level": "8", + "safespot": null, + "lifepoints": "11", + "strength_level": "8", + "id": "1326", + "aggressive": "true", + "range_level": "1", + "attack_level": "8" + }, + { + "examine": "Cute. But deadly.", + "name": "Bear Cub", + "defence_level": "1", + "safespot": null, + "lifepoints": "20", + "combat_audio": "498,500,499", + "strength_level": "1", + "id": "1327", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "examine": "Horned horsey.", + "melee_animation": "6376", + "range_animation": "6376", + "combat_audio": "369,371,370", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "90", + "defence_animation": "6375", + "weakness": "7", + "magic_animation": "6376", + "death_animation": "6377", + "name": "Unicorn Foal", + "defence_level": "10", + "safespot": null, + "lifepoints": "15", + "strength_level": "6", + "id": "1328", + "range_level": "1", + "attack_level": "10" + }, + { + "examine": "Cute but evil.", + "melee_animation": "6376", + "range_animation": "0", + "combat_audio": "369,371,370", + "attack_speed": "4", + "respawn_delay": "20", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "6377", + "name": "Black unicorn Foal", + "defence_level": "18", + "safespot": null, + "lifepoints": "25", + "strength_level": "18", + "id": "1329", + "aggressive": "false", + "range_level": "1", + "attack_level": "18" + }, + { + "examine": "Fearsome predator found only in the Fremennik Province", + "melee_animation": "6559", + "range_animation": "0", + "combat_audio": "481,491,490", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "slayer_exp": "69", + "magic_animation": "0", + "death_animation": "6558", + "name": "Wolf", + "defence_level": "35", + "safespot": null, + "lifepoints": "69", + "strength_level": "35", + "id": "1330", + "aggressive": "true", + "range_level": "1", + "attack_level": "35" + }, + { + "examine": "A horror from the ocean depths...", + "combat_style": "1", + "melee_animation": "1340", + "range_animation": "1340", + "attack_speed": "5", + "defence_animation": "1341", + "magic_animation": "1340", + "death_animation": "1342", + "name": "Dagannoth", + "defence_level": "70", + "safespot": null, + "lifepoints": "70", + "strength_level": "80", + "id": "1338", + "clue_level": "1", + "range_level": "85", + "projectile": "288", + "attack_level": "80" + }, + { + "examine": "A horror from the ocean depths...", + "combat_style": "1", + "melee_animation": "1343", + "respawn_delay": "60", + "defence_animation": "1340", + "death_animation": "1342", + "name": "Dagannoth", + "defence_level": "1", + "safespot": null, + "lifepoints": "70", + "strength_level": "1", + "id": "1339", + "aggressive": "true", + "clue_level": "1", + "range_level": "1", + "projectile": "288", + "attack_level": "1" + }, + { + "examine": "A horror from the ocean depths...", + "combat_style": "1", + "melee_animation": "1343", + "respawn_delay": "60", + "defence_animation": "1340", + "death_animation": "1342", + "name": "Dagannoth", + "defence_level": "1", + "safespot": null, + "lifepoints": "70", + "strength_level": "1", + "id": "1340", + "aggressive": "true", + "clue_level": "1", + "range_level": "1", + "projectile": "288", + "attack_level": "1" + }, + { + "examine": "A horror from the ocean depths...", + "melee_animation": "1341", + "respawn_delay": "60", + "defence_animation": "1340", + "death_animation": "1342", + "name": "Dagannoth", + "defence_level": "1", + "safespot": null, + "lifepoints": "120", + "strength_level": "1", + "id": "1341", + "aggressive": "true", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A horror from the ocean depths...", + "melee_animation": "1341", + "respawn_delay": "60", + "defence_animation": "1340", + "death_animation": "1342", + "name": "Dagannoth", + "defence_level": "1", + "safespot": null, + "lifepoints": "120", + "strength_level": "1", + "id": "1342", + "aggressive": "true", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A horror from the ocean depths...", + "melee_animation": "1341", + "respawn_delay": "60", + "defence_animation": "1340", + "death_animation": "1342", + "name": "Dagannoth", + "defence_level": "1", + "safespot": null, + "lifepoints": "120", + "strength_level": "1", + "id": "1343", + "aggressive": "true", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A horror from the ocean depths...", + "name": "Dagannoth", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1344", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A horror from the ocean depths...", + "name": "Dagannoth", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1345", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A horror from the ocean depths...", + "name": "Dagannoth", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1346", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A horror from the ocean depths...", + "name": "Dagannoth", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1347", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A horror from the ocean depths.", + "melee_animation": "1341", + "range_animation": "0", + "magic_level": "60", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "1342", + "name": "Dagannoth mother", + "defence_level": "60", + "safespot": null, + "lifepoints": "128", + "strength_level": "60", + "id": "1351", + "aggressive": "true", + "range_level": "60", + "attack_level": "60" + }, + { + "examine": "A horror from the ocean depths.", + "melee_animation": "1341", + "respawn_delay": "60", + "defence_animation": "1340", + "death_animation": "1342", + "name": "Dagannoth mother", + "defence_level": "1", + "safespot": null, + "lifepoints": "100", + "strength_level": "1", + "id": "1352", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A horror from the ocean depths.", + "melee_animation": "1341", + "respawn_delay": "60", + "defence_animation": "1340", + "death_animation": "1342", + "name": "Dagannoth mother", + "defence_level": "1", + "safespot": null, + "lifepoints": "100", + "strength_level": "1", + "id": "1353", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A horror from the ocean depths.", + "melee_animation": "1341", + "respawn_delay": "60", + "defence_animation": "1340", + "death_animation": "1342", + "name": "Dagannoth mother", + "defence_level": "1", + "safespot": null, + "lifepoints": "100", + "strength_level": "1", + "id": "1354", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A horror from the ocean depths.", + "melee_animation": "1341", + "respawn_delay": "60", + "defence_animation": "1340", + "death_animation": "1342", + "name": "Dagannoth mother", + "defence_level": "1", + "safespot": null, + "lifepoints": "100", + "strength_level": "1", + "id": "1355", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A horror from the ocean depths.", + "melee_animation": "1341", + "respawn_delay": "60", + "defence_animation": "1340", + "death_animation": "1342", + "name": "Dagannoth mother", + "defence_level": "1", + "safespot": null, + "lifepoints": "100", + "strength_level": "1", + "id": "1356", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Pretty barmaid.", + "name": "Sam", + "id": "1357" + }, + { + "examine": "Pretty barmaid.", + "name": "Rachael", + "id": "1358" + }, + { + "examine": "He seems happy to see you.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Banker", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1360", + "range_level": "1", + "attack_level": "1" + }, + { + "death_animation": "836", + "name": "Skraeling", + "defence_level": "1", + "safespot": null, + "lifepoints": "1", + "melee_animation": "401", + "strength_level": "1", + "id": "1367", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1", + "defence_animation": "425" + }, + { + "death_animation": "836", + "name": "Skraeling", + "defence_level": "1", + "safespot": null, + "lifepoints": "1", + "melee_animation": "395", + "strength_level": "1", + "id": "1368", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1", + "defence_animation": "425" + }, + { + "examine": "Hmm", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fishmonger", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1369", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "At least he eats his greens.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Greengrocer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1370", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He's guarding the throne room.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1374", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He's cutting the wheat.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Farmer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1377", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "No-one would mistake her for a duchess.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Flower Girl", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1378", + "range_level": "1", + "attack_level": "1" + }, + { + "death_animation": "836", + "name": "Alrik", + "defence_level": "1", + "safespot": null, + "lifepoints": "1", + "melee_animation": "422", + "strength_level": "1", + "id": "1381", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1", + "defence_animation": "425" + }, + { + "examine": "He's strong to the finish, because he eats cabbage.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Sailor", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1385", + "range_level": "1", + "attack_level": "1" + }, + { + "death_animation": "836", + "name": "Rannveig", + "defence_level": "1", + "safespot": null, + "lifepoints": "1", + "melee_animation": "422", + "strength_level": "1", + "id": "1386", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1", + "defence_animation": "425" + }, + { + "death_animation": "836", + "name": "Valgerd", + "defence_level": "1", + "safespot": null, + "lifepoints": "1", + "melee_animation": "422", + "strength_level": "1", + "id": "1388", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1", + "defence_animation": "425" + }, + { + "death_animation": "836", + "name": "Skraeling", + "defence_level": "1", + "safespot": null, + "lifepoints": "1", + "melee_animation": "395", + "strength_level": "1", + "id": "1389", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1", + "defence_animation": "425" + }, + { + "death_animation": "836", + "name": "Broddi", + "defence_level": "1", + "safespot": null, + "lifepoints": "1", + "melee_animation": "422", + "strength_level": "1", + "id": "1390", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1", + "defence_animation": "425" + }, + { + "death_animation": "836", + "name": "Skraeling", + "defence_level": "1", + "safespot": null, + "lifepoints": "1", + "melee_animation": "395", + "strength_level": "1", + "id": "1391", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1", + "defence_animation": "425" + }, + { + "death_animation": "836", + "name": "Ragnvald", + "defence_level": "1", + "safespot": null, + "lifepoints": "1", + "melee_animation": "810", + "strength_level": "1", + "id": "1392", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1", + "defence_animation": "425" + }, + { + "examine": "Hmm", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fishmonger", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1393", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "At least he eats his greens.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Greengrocer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1394", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He's a lumberjack", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Lumberjack Leif", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1395", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He's just mining his own business.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Miner Magnus", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1396", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "There's something fishy about him.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fisherman Frodi", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1397", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "She's looking a bit weedy.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Gardener Gunnhild", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1398", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Yep. Definitely a chicken.", + "melee_animation": "5387", + "range_animation": "5387", + "combat_audio": "355,357,356", + "attack_speed": "6", + "respawn_delay": "18", + "defence_animation": "5388", + "magic_animation": "5387", + "death_animation": "5389", + "name": "Chicken", + "defence_level": "1", + "safespot": null, + "lifepoints": "3", + "strength_level": "1", + "id": "1401", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Yep. Definitely a chicken.", + "melee_animation": "5387", + "range_animation": "5387", + "combat_audio": "355,357,356", + "attack_speed": "6", + "respawn_delay": "18", + "defence_animation": "5388", + "magic_animation": "5387", + "death_animation": "5389", + "name": "Chicken", + "defence_level": "1", + "safespot": null, + "lifepoints": "3", + "strength_level": "1", + "id": "1402", + "range_level": "1", + "attack_level": "1" + }, + { + "death_animation": "5389", + "name": "Rooster", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "melee_animation": "5387", + "strength_level": "1", + "id": "1403", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1", + "defence_animation": "5388" + }, + { + "death_animation": "6092", + "name": "Rabbit", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "melee_animation": "6090", + "strength_level": "1", + "id": "1404", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1", + "defence_animation": "6091" + }, + { + "examine": "There to help me make my bids.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Lumdo", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1419", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An official looking Gnome with small beady eyes.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "G.L.O. Caranock", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1427", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "1383", + "respawn_delay": "60", + "defence_animation": "1393", + "death_animation": "1384", + "name": "Duke", + "defence_level": "1", + "safespot": null, + "lifepoints": "130", + "strength_level": "1", + "id": "1442", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "1383", + "respawn_delay": "60", + "defence_animation": "1393", + "death_animation": "1384", + "name": "Oipuis", + "defence_level": "1", + "safespot": null, + "lifepoints": "130", + "strength_level": "1", + "id": "1443", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "1383", + "respawn_delay": "60", + "defence_animation": "1393", + "death_animation": "1384", + "name": "Uyoro", + "defence_level": "1", + "safespot": null, + "lifepoints": "130", + "strength_level": "1", + "id": "1444", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "1383", + "respawn_delay": "60", + "defence_animation": "1387", + "death_animation": "1384", + "name": "Ouhai", + "defence_level": "1", + "safespot": null, + "lifepoints": "130", + "strength_level": "1", + "id": "1445", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "1383", + "respawn_delay": "60", + "defence_animation": "1393", + "death_animation": "1384", + "name": "Uodai", + "defence_level": "1", + "safespot": null, + "lifepoints": "130", + "strength_level": "1", + "id": "1446", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "1383", + "respawn_delay": "60", + "defence_animation": "1393", + "death_animation": "1384", + "name": "Padulah", + "defence_level": "1", + "safespot": null, + "lifepoints": "133", + "strength_level": "1", + "id": "1447", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A rather sleepy looking guard", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "629,631,630", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Sleeping Monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1451", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An adorable little monkey child.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "629,631,630", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Monkey Child", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1452", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He looks like the Monkey's Uncle.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "629,631,630", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "The Monkey's Uncle", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1453", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "She looks like the Monkey's Aunt.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "629,631,630", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "The Monkey's Aunt", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1454", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A scimitar wielding ninja monkey.", + "melee_animation": "1392", + "range_animation": "0", + "combat_audio": "629,631,630", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "1384", + "name": "Monkey Guard", + "defence_level": "66", + "safespot": null, + "lifepoints": "94", + "strength_level": "66", + "id": "1455", + "range_level": "1", + "attack_level": "66" + }, + { + "examine": "A bow wielding ninja monkey.", + "combat_style": "1", + "melee_animation": "0", + "range_animation": "1394", + "combat_audio": "629,631,630", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "1", + "magic_animation": "0", + "death_animation": "0", + "name": "Monkey Archer", + "defence_level": "58", + "safespot": null, + "lifepoints": "82", + "strength_level": "43", + "id": "1456", + "aggressive": "true", + "range_level": "58", + "attack_level": "43" + }, + { + "combat_style": "1", + "melee_animation": "1394", + "combat_audio": "629,631,630", + "respawn_delay": "60", + "defence_animation": "1393", + "death_animation": "1384", + "name": "Monkey Archer", + "defence_level": "1", + "safespot": null, + "lifepoints": "50", + "strength_level": "1", + "id": "1457", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "combat_style": "1", + "melee_animation": "1394", + "combat_audio": "629,631,630", + "respawn_delay": "60", + "defence_animation": "1393", + "death_animation": "1384", + "name": "Monkey Archer", + "defence_level": "1", + "safespot": null, + "lifepoints": "50", + "strength_level": "1", + "id": "1458", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A huge brutish gorilla armoured with dangerous looking vambraces.", + "melee_animation": "1402", + "range_animation": "1402", + "combat_audio": "629,631,630", + "attack_speed": "6", + "defence_animation": "1403", + "weakness": "8", + "magic_animation": "1402", + "death_animation": "1404", + "name": "Monkey Guard", + "defence_level": "90", + "safespot": null, + "lifepoints": "130", + "strength_level": "130", + "id": "1459", + "range_level": "1", + "attack_level": "100" + }, + { + "examine": "A huge brutish gorilla armoured with dangerous looking vambraces.", + "melee_animation": "1402", + "range_animation": "0", + "combat_audio": "629,631,630", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "1404", + "name": "Monkey Guard", + "defence_level": "63", + "safespot": null, + "lifepoints": "90", + "strength_level": "63", + "id": "1460", + "aggressive": "true", + "range_level": "1", + "attack_level": "63" + }, + { + "examine": "A huge brutish gorilla stands here", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Elder Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1461", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "629,631,630", + "strength_level": "1", + "id": "1463", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "629,631,630", + "strength_level": "1", + "id": "1464", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A large and lumbering undead monkey.", + "melee_animation": "1383", + "range_animation": "0", + "combat_audio": "629,631,630", + "attack_speed": "4", + "magic_level": "60", + "respawn_delay": "50", + "defence_animation": "1393", + "weakness": "6", + "magic_animation": "0", + "death_animation": "1384", + "name": "Monkey Zombie", + "defence_level": "60", + "safespot": null, + "lifepoints": "60", + "strength_level": "60", + "id": "1465", + "aggressive": "true", + "bonuses": "35,35,35,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "150" + }, + { + "examine": "A large and lumbering undead monkey stands here, blocking the way.", + "melee_animation": "1392", + "combat_audio": "629,631,630", + "attack_speed": "4", + "magic_level": "90", + "respawn_delay": "13", + "defence_animation": "1393", + "death_animation": "1384", + "name": "Monkey Zombie", + "defence_level": "90", + "safespot": null, + "lifepoints": "90", + "strength_level": "110", + "id": "1466", + "aggressive": "true", + "bonuses": "35,35,35,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "150" + }, + { + "examine": "A recently deceased monkey. Its flesh seems to be worse for the wear.", + "melee_animation": "1392", + "combat_audio": "629,631,630", + "attack_speed": "4", + "magic_level": "60", + "respawn_delay": "50", + "defence_animation": "1393", + "death_animation": "1384", + "name": "Monkey Zombie", + "defence_level": "60", + "safespot": null, + "lifepoints": "60", + "strength_level": "60", + "id": "1467", + "aggressive": "true", + "bonuses": "15,15,15,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "100" + }, + { + "examine": "He looks like the type of guy who would mind monkeys.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "629,631,630", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Monkey minder", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1469", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A Greater Jungle demon. A magical aura emanates from its hide.", + "range_animation": "0", + "combat_audio": "400,404,403", + "attack_speed": "2", + "magic_level": "50", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "name": "Jungle demon", + "defence_level": "50", + "safespot": null, + "lifepoints": "428", + "strength_level": "50", + "id": "1472", + "aggressive": "true", + "range_level": "50", + "attack_level": "50" + }, + { + "melee_animation": "6249", + "respawn_delay": "60", + "defence_animation": "6250", + "death_animation": "6251", + "name": "Spider", + "defence_level": "1", + "safespot": null, + "lifepoints": "2", + "strength_level": "1", + "id": "1473", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It's a brightly coloured bird of the jungle.", + "melee_animation": "6775", + "range_animation": "0", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "6779", + "name": "Bird", + "defence_level": "5", + "safespot": null, + "lifepoints": "7", + "strength_level": "5", + "id": "1475", + "range_level": "1", + "attack_level": "5" + }, + { + "examine": "It's a brightly coloured bird of the jungle. It flies very quickly.", + "melee_animation": "6775", + "range_animation": "0", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "6777", + "name": "Bird", + "defence_level": "5", + "safespot": null, + "lifepoints": "7", + "strength_level": "5", + "id": "1476", + "range_level": "1", + "attack_level": "5" + }, + { + "slayer_exp": "17", + "name": "Scorpion", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "3611,3612,3610", + "strength_level": "1", + "id": "1477", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A very dangerous looking spider", + "melee_animation": "5327", + "range_animation": "0", + "combat_audio": "537,539,538", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "2", + "magic_animation": "0", + "death_animation": "5329", + "name": "Jungle spider", + "defence_level": "63", + "safespot": null, + "lifepoints": "90", + "strength_level": "47", + "id": "1478", + "aggressive": "true", + "range_level": "63", + "attack_level": "47" + }, + { + "name": "Snake", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "3609,3608,3610", + "strength_level": "1", + "id": "1479", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Small ninja monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "629,631,630", + "strength_level": "1", + "id": "1480", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Medium ninja monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "629,631,630", + "strength_level": "1", + "id": "1481", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Bearded gorilla", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "498,500,499", + "strength_level": "1", + "id": "1483", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Ancient monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "629,631,630", + "strength_level": "1", + "id": "1484", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Small zombie monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "629,631,630", + "strength_level": "1", + "id": "1485", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Large zombie monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "629,631,630", + "strength_level": "1", + "id": "1486", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "629,631,630", + "strength_level": "1", + "id": "1487", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A huge nail beast. Its nails appear very sharp.", + "melee_animation": "5989", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "5990", + "name": "Nail beast", + "defence_level": "20", + "safespot": null, + "lifepoints": "550", + "strength_level": "150", + "id": "1521", + "range_level": "1", + "attack_level": "150" + }, + { + "examine": "He is one", + "melee_animation": "5970", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "5972", + "name": "Undead Lumberjack", + "defence_level": "10", + "safespot": null, + "lifepoints": "100", + "strength_level": "73", + "id": "1524", + "range_level": "1", + "attack_level": "73" + }, + { + "examine": "His robes prominently display the star of Saradomin.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Zealot", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1528", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Imp", + "defence_level": "1", + "safespot": null, + "movement_radius": "25", + "lifepoints": "8", + "strength_level": "1", + "id": "1531", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Handy for hindering the enemy team's movement.", + "combat_style": "1", + "melee_animation": "0", + "range_animation": "0", + "attack_speed": "5", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "9658", + "name": "Barricade", + "defence_level": "1", + "poison_immune": "true", + "safespot": null, + "lifepoints": "50", + "strength_level": "1", + "id": "1532", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Handy for hindering the enemy team's movement.", + "combat_style": "1", + "melee_animation": "0", + "range_animation": "0", + "attack_speed": "5", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "9658", + "name": "Barricade", + "defence_level": "1", + "poison_immune": "true", + "safespot": null, + "lifepoints": "50", + "strength_level": "1", + "id": "1533", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Handy for hindering the enemy team's movement.", + "melee_animation": "0", + "range_animation": "0", + "attack_speed": "5", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "9658", + "name": "Barricade", + "defence_level": "1", + "poison_immune": "true", + "safespot": null, + "lifepoints": "50", + "strength_level": "1", + "id": "1534", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Handy for hindering the enemy team's movement.", + "melee_animation": "0", + "range_animation": "0", + "attack_speed": "5", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "9658", + "name": "Barricade", + "defence_level": "1", + "poison_immune": "true", + "safespot": null, + "lifepoints": "50", + "strength_level": "1", + "id": "1535", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "185", + "respawn_delay": "60", + "defence_animation": "186", + "death_animation": "188", + "name": "Possessed pickaxe", + "defence_level": "1", + "safespot": null, + "lifepoints": "40", + "strength_level": "1", + "id": "1536", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A strange disturbance in the air.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "0", + "name": "Haze", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1537", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Well", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "0", + "name": "Corpse", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1538", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "I don't think the pickaxe is for hitting rocks.", + "melee_animation": "5485", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "slayer_exp": "0", + "magic_animation": "0", + "death_animation": "5491", + "name": "Skeletal miner", + "defence_level": "35", + "safespot": null, + "lifepoints": "50", + "strength_level": "35", + "id": "1539", + "aggressive": "true", + "range_level": "1", + "attack_level": "35" + }, + { + "melee_animation": "5540", + "respawn_delay": "60", + "defence_animation": "5541", + "death_animation": "5542", + "name": "Treus Dayth", + "defence_level": "1", + "safespot": null, + "lifepoints": "100", + "strength_level": "1", + "id": "1540", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "slayer_exp": "25", + "name": "Ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "436,439,438", + "strength_level": "1", + "id": "1541", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "5540", + "combat_audio": "436,439,438", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "5541", + "slayer_exp": "25", + "death_animation": "5542", + "name": "Ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "30", + "strength_level": "1", + "id": "1549", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A large boisterous bird, a delicacy for ogres.", + "melee_animation": "6761", + "range_animation": "0", + "combat_audio": "1449,1451,1450", + "defence_animation": "0", + "weakness": "3", + "magic_animation": "0", + "death_animation": "6762", + "name": "Chompy bird", + "defence_level": "3", + "safespot": null, + "poison_immune": "true", + "lifepoints": "10", + "strength_level": "5", + "id": "1550", + "aggressive": "false", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "5" + }, + { + "name": "Mischievous ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "436,439,438", + "strength_level": "1", + "id": "1551", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Ug", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "1553", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Arrg", + "defence_level": "1", + "safespot": null, + "lifepoints": "150", + "strength_level": "1", + "attack_speed": "5", + "id": "1556", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Ug", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "1557", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Not man's best friend.", + "melee_animation": "6559", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "6558", + "name": "Ice wolf", + "defence_level": "51", + "safespot": null, + "lifepoints": "72", + "strength_level": "51", + "id": "1558", + "aggressive": "true", + "range_level": "1", + "attack_level": "51" + }, + { + "examine": "Brrrrr...he must be cold!", + "melee_animation": "284", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "285", + "weakness": "9", + "magic_animation": "0", + "death_animation": "287", + "name": "Ice Troll", + "defence_level": "60", + "safespot": null, + "lifepoints": "85", + "strength_level": "60", + "id": "1560", + "aggressive": "true", + "range_level": "1", + "attack_level": "60" + }, + { + "examine": "Brrrrr...he must be cold!", + "melee_animation": "284", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "285", + "weakness": "9", + "magic_animation": "0", + "death_animation": "287", + "name": "Ice Troll", + "defence_level": "60", + "safespot": null, + "lifepoints": "85", + "strength_level": "60", + "id": "1561", + "range_level": "1", + "attack_level": "60" + }, + { + "examine": "Brrrrr...he must be cold!", + "melee_animation": "284", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "285", + "weakness": "9", + "magic_animation": "0", + "death_animation": "287", + "name": "Ice Troll", + "defence_level": "60", + "safespot": null, + "lifepoints": "85", + "strength_level": "60", + "id": "1562", + "aggressive": "true", + "range_level": "1", + "attack_level": "60" + }, + { + "examine": "Brrrrr...he must be cold!", + "melee_animation": "284", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "285", + "weakness": "9", + "magic_animation": "0", + "death_animation": "287", + "name": "Ice Troll", + "defence_level": "60", + "safespot": null, + "lifepoints": "85", + "strength_level": "60", + "id": "1563", + "range_level": "1", + "attack_level": "60" + }, + { + "examine": "Brrrrr...he must be cold!", + "melee_animation": "284", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "285", + "weakness": "9", + "magic_animation": "0", + "death_animation": "287", + "name": "Ice Troll", + "defence_level": "60", + "safespot": null, + "lifepoints": "85", + "strength_level": "60", + "id": "1564", + "aggressive": "true", + "range_level": "1", + "attack_level": "60" + }, + { + "examine": "Brrrrr...he must be cold!", + "melee_animation": "284", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "285", + "weakness": "9", + "magic_animation": "0", + "death_animation": "287", + "name": "Ice Troll", + "defence_level": "60", + "safespot": null, + "lifepoints": "85", + "strength_level": "60", + "id": "1565", + "aggressive": "true", + "range_level": "1", + "attack_level": "60" + }, + { + "examine": "Brrrrr...he must be cold!", + "melee_animation": "284", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "285", + "weakness": "9", + "magic_animation": "0", + "death_animation": "287", + "name": "Ice Troll", + "defence_level": "60", + "safespot": null, + "lifepoints": "85", + "strength_level": "60", + "id": "1566", + "range_level": "1", + "attack_level": "60" + }, + { + "examine": "A tall and imposing man who's more than familiar with boating.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cyreg Paddlehorn", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1567", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A very large elemental adversary.", + "melee_animation": "4666", + "range_animation": "4666", + "combat_audio": "447,451,450", + "attack_speed": "5", + "magic_level": "1", + "respawn_delay": "20", + "defence_animation": "4664", + "weakness": "1", + "slayer_exp": "111", + "magic_animation": "4666", + "death_animation": "4668", + "name": "Fire giant", + "defence_level": "65", + "safespot": null, + "lifepoints": "111", + "strength_level": "65", + "id": "1582", + "aggressive": "true", + "bonuses": "29,29,29,0,0,0,3,2,0,0,0,31,0,0,0", + "range_level": "1", + "attack_level": "65" + }, + { + "examine": "A very large elemental adversary.", + "melee_animation": "4666", + "range_animation": "4666", + "combat_audio": "447,451,450", + "attack_speed": "5", + "magic_level": "1", + "respawn_delay": "20", + "defence_animation": "4664", + "weakness": "1", + "slayer_exp": "111", + "magic_animation": "4666", + "death_animation": "4668", + "name": "Fire giant", + "defence_level": "65", + "safespot": null, + "lifepoints": "111", + "strength_level": "65", + "id": "1583", + "aggressive": "true", + "bonuses": "29,29,29,0,0,0,3,2,0,0,0,31,0,0,0", + "range_level": "1", + "attack_level": "65" + }, + { + "examine": "A very large elemental adversary.", + "melee_animation": "4666", + "range_animation": "4666", + "combat_audio": "447,451,450", + "attack_speed": "5", + "magic_level": "1", + "respawn_delay": "20", + "defence_animation": "4664", + "weakness": "1", + "slayer_exp": "111", + "magic_animation": "4666", + "death_animation": "4668", + "name": "Fire giant", + "defence_level": "65", + "safespot": null, + "lifepoints": "111", + "strength_level": "65", + "id": "1584", + "aggressive": "true", + "bonuses": "29,29,29,0,0,0,3,2,0,0,0,31,0,0,0", + "range_level": "1", + "attack_level": "65" + }, + { + "examine": "A very large elemental adversary.", + "melee_animation": "4666", + "range_animation": "4666", + "combat_audio": "447,451,450", + "attack_speed": "5", + "magic_level": "1", + "respawn_delay": "20", + "defence_animation": "4664", + "weakness": "1", + "slayer_exp": "111", + "magic_animation": "4666", + "death_animation": "4668", + "name": "Fire giant", + "defence_level": "65", + "safespot": null, + "lifepoints": "111", + "strength_level": "65", + "id": "1585", + "aggressive": "true", + "bonuses": "29,29,29,0,0,0,3,2,0,0,0,31,0,0,0", + "range_level": "1", + "attack_level": "65" + }, + { + "examine": "A very large elemental adversary.", + "melee_animation": "4666", + "range_animation": "4666", + "combat_audio": "447,451,450", + "attack_speed": "5", + "magic_level": "1", + "respawn_delay": "20", + "defence_animation": "4664", + "weakness": "1", + "slayer_exp": "111", + "magic_animation": "4666", + "death_animation": "4668", + "name": "Fire giant", + "defence_level": "65", + "safespot": null, + "lifepoints": "111", + "strength_level": "65", + "id": "1586", + "aggressive": "true", + "bonuses": "29,29,29,0,0,0,3,2,0,0,0,31,0,0,0", + "range_level": "1", + "attack_level": "65" + }, + { + "examine": "His beard seems to have a life of its own.", + "melee_animation": "4666", + "range_animation": "4666", + "combat_audio": "449,451,450", + "attack_speed": "6", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "4665", + "weakness": "1", + "slayer_exp": "60", + "magic_animation": "4666", + "death_animation": "4668", + "name": "Moss giant", + "defence_level": "30", + "safespot": null, + "lifepoints": "60", + "strength_level": "30", + "id": "1587", + "aggressive": "true", + "bonuses": "33,33,33,0,0,0,0,0,0,0,0,31,0,0,0", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "His beard seems to have a life of its own.", + "melee_animation": "4666", + "range_animation": "4666", + "combat_audio": "449,451,450", + "attack_speed": "6", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "4665", + "weakness": "1", + "slayer_exp": "60", + "magic_animation": "4666", + "death_animation": "4668", + "name": "Moss giant", + "defence_level": "30", + "safespot": null, + "lifepoints": "60", + "strength_level": "30", + "id": "1588", + "aggressive": "true", + "bonuses": "33,33,33,0,0,0,0,0,0,0,0,31,0,0,0", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "Young but still dangerous.", + "melee_animation": "25", + "range_animation": "25", + "combat_audio": "405,407,406", + "attack_speed": "5", + "magic_level": "40", + "respawn_delay": "32", + "defence_animation": "26", + "weakness": "3", + "magic_animation": "25", + "death_animation": "28", + "name": "Baby red dragon", + "defence_level": "42", + "safespot": null, + "lifepoints": "50", + "strength_level": "40", + "id": "1589", + "aggressive": "true", + "bonuses": "50,40,64,60,30,45,40,40,20,40,40,20,0,0,0", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "Its scales seem to be made of bronze.", + "melee_animation": "80", + "range_animation": "80", + "combat_audio": "408,410,409", + "attack_speed": "4", + "magic_level": "100", + "respawn_delay": "40", + "defence_animation": "89", + "weakness": "7", + "slayer_exp": "125", + "magic_animation": "80", + "death_animation": "92", + "name": "Bronze dragon", + "defence_level": "112", + "safespot": null, + "lifepoints": "122", + "strength_level": "112", + "id": "1590", + "aggressive": "true", + "bonuses": "0,0,0,0,0,50,70,70,30,90,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "112" + }, + { + "examine": "Its scales seem to be made of iron.", + "melee_animation": "80", + "range_animation": "80", + "combat_audio": "408,410,409", + "attack_speed": "4", + "magic_level": "100", + "respawn_delay": "45", + "defence_animation": "89", + "weakness": "7", + "slayer_exp": "173", + "magic_animation": "80", + "death_animation": "92", + "name": "Iron dragon", + "defence_level": "165", + "safespot": null, + "lifepoints": "165", + "strength_level": "165", + "id": "1591", + "aggressive": "true", + "bonuses": "0,0,0,0,0,50,70,70,30,90,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "165" + }, + { + "examine": "Its scales seem to be made of steel.", + "melee_animation": "80", + "range_animation": "80", + "combat_audio": "408,410,409", + "attack_speed": "4", + "magic_level": "100", + "respawn_delay": "45", + "defence_animation": "89", + "weakness": "7", + "slayer_exp": "221", + "magic_animation": "80", + "death_animation": "92", + "name": "Steel dragon", + "defence_level": "215", + "safespot": null, + "lifepoints": "210", + "strength_level": "215", + "id": "1592", + "aggressive": "true", + "bonuses": "0,0,0,0,0,50,70,70,30,90,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "215" + }, + { + "examine": "An unsuitable pet.", + "melee_animation": "6562", + "range_animation": "6562", + "magic_level": "20", + "respawn_delay": "20", + "defence_animation": "6563", + "weakness": "7", + "magic_animation": "6562", + "death_animation": "6564", + "name": "Wild dog", + "defence_level": "25", + "safespot": null, + "lifepoints": "62", + "strength_level": "25", + "id": "1593", + "aggressive": "true", + "bonuses": "10,15,5,10,30,5,30,30,30,10,30,5,40,5,5", + "range_level": "1", + "attack_level": "25" + }, + { + "examine": "Looks like it's got Rabies!", + "melee_animation": "6562", + "range_animation": "6562", + "magic_level": "20", + "respawn_delay": "20", + "defence_animation": "6563", + "magic_animation": "6562", + "death_animation": "6564", + "name": "Wild dog", + "defence_level": "25", + "safespot": null, + "lifepoints": "62", + "strength_level": "25", + "id": "1594", + "aggressive": "true", + "bonuses": "10,15,5,10,30,5,30,30,30,10,30,5,40,5,5", + "range_level": "1", + "attack_level": "25" + }, + { + "examine": "She looks dangerous!", + "name": "Chaeldar", + "id": "1598" + }, + { + "examine": "A spiky crawling critter. ", + "melee_animation": "266", + "range_animation": "266", + "combat_audio": "341,343,342", + "attack_speed": "4", + "poisonous": "true", + "respawn_delay": "25", + "defence_animation": "267", + "weakness": "1", + "slayer_exp": "22", + "magic_animation": "266", + "death_animation": "265", + "name": "Cave crawler", + "defence_level": "30", + "safespot": null, + "lifepoints": "23", + "strength_level": "30", + "id": "1600", + "bonuses": "30,60,60,60,60,66,0,0,0,0,0,0,0,0,0", + "range_level": "38", + "attack_level": "28" + }, + { + "examine": "A spiky crawling critter. ", + "melee_animation": "266", + "range_animation": "266", + "combat_audio": "341,343,342", + "attack_speed": "4", + "poisonous": "true", + "respawn_delay": "25", + "defence_animation": "267", + "slayer_exp": "22", + "magic_animation": "266", + "death_animation": "265", + "name": "Cave crawler", + "defence_level": "30", + "safespot": null, + "lifepoints": "23", + "strength_level": "30", + "id": "1601", + "bonuses": "30,60,60,60,60,66,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "28" + }, + { + "examine": "A spiky crawling critter. ", + "melee_animation": "266", + "range_animation": "266", + "combat_audio": "341,343,342", + "attack_speed": "4", + "poisonous": "true", + "respawn_delay": "25", + "defence_animation": "267", + "slayer_exp": "22", + "magic_animation": "266", + "death_animation": "265", + "name": "Cave crawler", + "defence_level": "30", + "safespot": null, + "lifepoints": "23", + "strength_level": "30", + "id": "1602", + "bonuses": "30,60,60,60,60,66,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "28" + }, + { + "examine": "A spiky crawling critter. ", + "melee_animation": "266", + "range_animation": "266", + "combat_audio": "341,343,342", + "attack_speed": "4", + "poisonous": "true", + "respawn_delay": "25", + "defence_animation": "267", + "slayer_exp": "22", + "magic_animation": "266", + "death_animation": "265", + "name": "Cave crawler", + "defence_level": "30", + "safespot": null, + "lifepoints": "23", + "strength_level": "30", + "id": "1603", + "bonuses": "30,60,60,60,60,66,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "28" + }, + { + "examine": "A very smelly ghost.", + "start_gfx": "334", + "combat_style": "2", + "melee_animation": "9466", + "attack_speed": "4", + "weakness": "5", + "slayer_exp": "90", + "magic_animation": "9466", + "death_animation": "9467", + "lifepoints": "90", + "id": "1604", + "aggressive": "true", + "bonuses": "0,0,0,0,0,20,20,20,0,15,0,0,0,0,0", + "range_animation": "1507", + "combat_audio": "272,275,274", + "magic_level": "105", + "end_gfx": "336", + "defence_animation": "9468", + "name": "Aberrant spectre", + "defence_level": "90", + "safespot": null, + "strength_level": "1", + "clue_level": "2", + "range_level": "1", + "projectile": "335", + "attack_level": "1" + }, + { + "examine": "A very smelly ghost.", + "start_gfx": "334", + "combat_style": "2", + "melee_animation": "9466", + "attack_speed": "4", + "weakness": "5", + "slayer_exp": "90", + "magic_animation": "9466", + "death_animation": "9467", + "lifepoints": "90", + "id": "1605", + "aggressive": "true", + "bonuses": "0,0,0,0,0,20,20,20,0,15,0,0,0,0,0", + "range_animation": "1507", + "combat_audio": "272,275,274", + "magic_level": "105", + "end_gfx": "336", + "defence_animation": "9468", + "name": "Aberrant spectre", + "defence_level": "90", + "safespot": null, + "strength_level": "1", + "clue_level": "2", + "range_level": "1", + "projectile": "335", + "attack_level": "1" + }, + { + "examine": "A very smelly ghost.", + "start_gfx": "334", + "combat_style": "2", + "melee_animation": "9466", + "attack_speed": "4", + "weakness": "5", + "slayer_exp": "90", + "magic_animation": "9466", + "death_animation": "9467", + "lifepoints": "90", + "id": "1606", + "aggressive": "true", + "bonuses": "0,0,0,0,0,20,20,20,0,15,0,0,0,0,0", + "range_animation": "1507", + "combat_audio": "272,275,274", + "magic_level": "105", + "end_gfx": "336", + "defence_animation": "9468", + "name": "Aberrant spectre", + "defence_level": "90", + "safespot": null, + "strength_level": "1", + "clue_level": "2", + "range_level": "1", + "projectile": "335", + "attack_level": "1" + }, + { + "examine": "A very smelly ghost.", + "start_gfx": "334", + "combat_style": "2", + "melee_animation": "9466", + "attack_speed": "4", + "weakness": "5", + "slayer_exp": "90", + "magic_animation": "9466", + "death_animation": "9467", + "lifepoints": "90", + "id": "1607", + "aggressive": "true", + "bonuses": "0,0,0,0,0,20,20,20,0,15,0,0,0,0,0", + "range_animation": "1507", + "combat_audio": "272,275,274", + "magic_level": "105", + "end_gfx": "336", + "defence_animation": "9468", + "name": "Aberrant spectre", + "defence_level": "90", + "safespot": null, + "strength_level": "1", + "clue_level": "2", + "range_level": "1", + "projectile": "335", + "attack_level": "1" + }, + { + "examine": "Large, heavy, with sharp things attached to its head.", + "melee_animation": "9439", + "range_animation": "9439", + "combat_audio": "588,590,589", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "15", + "defence_animation": "9441", + "slayer_exp": "97", + "magic_animation": "9439", + "death_animation": "9440", + "name": "Kurask", + "defence_level": "105", + "safespot": null, + "lifepoints": "97", + "strength_level": "105", + "id": "1608", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,20,20,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "67" + }, + { + "examine": "Large, heavy, with sharp things attached to its head.", + "melee_animation": "9439", + "range_animation": "9439", + "combat_audio": "588,590,589", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "15", + "defence_animation": "9441", + "slayer_exp": "97", + "magic_animation": "9439", + "death_animation": "9440", + "name": "Kurask", + "defence_level": "105", + "safespot": null, + "lifepoints": "97", + "strength_level": "105", + "id": "1609", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,20,20,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "67" + }, + { + "examine": "Flies like a rock.", + "melee_animation": "9454", + "range_animation": "1516", + "combat_audio": "428,430,429", + "attack_speed": "4", + "magic_level": "1", + "defence_animation": "9455", + "slayer_exp": "105", + "magic_animation": "1516", + "death_animation": "1518", + "name": "Gargoyle", + "defence_level": "107", + "safespot": null, + "lifepoints": "105", + "strength_level": "95", + "id": "1610", + "aggressive": "true", + "bonuses": "0,0,0,0,0,20,20,0,20,20,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "75" + }, + { + "examine": "Flies like a rock.", + "melee_animation": "1516", + "range_animation": "1516", + "attack_speed": "5", + "defence_animation": "0", + "weakness": "0", + "slayer_exp": "105", + "magic_animation": "1516", + "death_animation": "1518", + "name": "Swarming turoth", + "defence_level": "42", + "safespot": null, + "lifepoints": "105", + "strength_level": "104", + "id": "1611", + "clue_level": "2", + "range_level": "49", + "attack_level": "45" + }, + { + "examine": "A tortured screaming soul.", + "melee_animation": "9449", + "range_animation": "1523", + "combat_audio": "284,286,285", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "15", + "defence_animation": "9451", + "slayer_exp": "22", + "magic_animation": "1523", + "death_animation": "9450", + "name": "Banshee", + "defence_level": "22", + "safespot": null, + "lifepoints": "22", + "strength_level": "15", + "id": "1612", + "aggressive": "true", + "clue_level": "0", + "bonuses": "0,0,0,0,0,5,5,5,0,5,0,0,0,0,0", + "range_level": "1", + "attack_level": "22" + }, + { + "examine": "An evil death demon.", + "melee_animation": "9487", + "range_animation": "1528", + "combat_audio": "645,647,646", + "attack_speed": "4", + "magic_level": "1", + "defence_animation": "9489", + "magic_animation": "1528", + "death_animation": "9488", + "name": "Nechryael", + "defence_level": "105", + "safespot": null, + "lifepoints": "105", + "strength_level": "97", + "id": "1613", + "bonuses": "0,0,0,0,0,20,20,20,0,20,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "97" + }, + { + "examine": "An evil death spawn.", + "melee_animation": "1540", + "range_animation": "1540", + "attack_speed": "4", + "magic_level": "1", + "defence_animation": "0", + "weakness": "2", + "magic_animation": "1540", + "death_animation": "9460", + "name": "Death spawn", + "defence_level": "30", + "poison_immune": "true", + "safespot": null, + "lifepoints": "60", + "strength_level": "7", + "id": "1614", + "aggressive": "true", + "bonuses": "0,0,0,0,0,20,20,20,0,20,0,0,0,0,0", + "range_level": "1", + "attack_level": "67" + }, + { + "examine": "A denizen of the Abyss!", + "melee_animation": "1537", + "range_animation": "1537", + "combat_audio": "276,278,277", + "attack_speed": "4", + "magic_level": "1", + "defence_animation": "0", + "weakness": "1", + "slayer_exp": "150", + "magic_animation": "1537", + "death_animation": "1538", + "name": "Abyssal demon", + "defence_level": "135", + "safespot": null, + "lifepoints": "150", + "strength_level": "67", + "id": "1615", + "bonuses": "0,0,0,0,0,20,20,20,0,20,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "97" + }, + { + "examine": "The eyes of evil.", + "melee_animation": "260", + "range_animation": "260", + "combat_audio": "288,290,289", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "15", + "defence_animation": "261", + "slayer_exp": "75", + "magic_animation": "260", + "death_animation": "264", + "name": "Basilisk", + "defence_level": "75", + "safespot": null, + "lifepoints": "75", + "strength_level": "45", + "id": "1616", + "aggressive": "false", + "bonuses": "0,0,0,0,0,20,20,0,20,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "The eyes of evil.", + "melee_animation": "260", + "range_animation": "260", + "combat_audio": "288,290,289", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "15", + "defence_animation": "261", + "slayer_exp": "75", + "magic_animation": "260", + "death_animation": "264", + "name": "Basilisk", + "defence_level": "75", + "safespot": null, + "lifepoints": "75", + "strength_level": "45", + "id": "1617", + "aggressive": "false", + "bonuses": "0,0,0,0,0,20,20,0,20,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "The tongue of evil.", + "melee_animation": "9130", + "range_animation": "1552", + "combat_audio": "312,314,313", + "attack_speed": "4", + "respawn_delay": "60", + "defence_animation": "9132", + "slayer_exp": "120", + "magic_animation": "1552", + "death_animation": "9131", + "name": "Bloodveld", + "defence_level": "30", + "safespot": null, + "lifepoints": "120", + "strength_level": "45", + "id": "1618", + "aggressive": "true", + "clue_level": "2", + "range_level": "1", + "attack_level": "75" + }, + { + "examine": "The tongue of evil.", + "melee_animation": "9130", + "range_animation": "1552", + "combat_audio": "312,314,313", + "attack_speed": "4", + "respawn_delay": "60", + "defence_animation": "9132", + "slayer_exp": "120", + "magic_animation": "1552", + "death_animation": "9131", + "name": "Bloodveld", + "defence_level": "30", + "safespot": null, + "lifepoints": "120", + "strength_level": "45", + "id": "1619", + "aggressive": "true", + "clue_level": "2", + "range_level": "1", + "attack_level": "75" + }, + { + "examine": "The winged reptile.", + "melee_animation": "7762", + "range_animation": "7762", + "combat_audio": "363,365,364", + "attack_speed": "5", + "defence_animation": "7761", + "weakness": "2", + "slayer_exp": "37", + "magic_animation": "7762", + "death_animation": "7763", + "name": "Cockatrice", + "defence_level": "35", + "safespot": null, + "lifepoints": "37", + "strength_level": "32", + "id": "1620", + "bonuses": "30,30,30,30,30,35,0,0,0,0,0,0,0,0,0", + "clue_level": "1", + "range_level": "32", + "attack_level": "32" + }, + { + "examine": "The winged reptile.", + "melee_animation": "7762", + "range_animation": "7762", + "combat_audio": "363,365,364", + "attack_speed": "5", + "defence_animation": "7761", + "slayer_exp": "37", + "magic_animation": "7762", + "death_animation": "7763", + "name": "Cockatrice", + "defence_level": "35", + "safespot": null, + "lifepoints": "37", + "strength_level": "32", + "id": "1621", + "bonuses": "30,30,30,30,30,35,0,0,0,0,0,0,0,0,0", + "clue_level": "1", + "range_level": "1", + "attack_level": "32" + }, + { + "examine": "He's one big leg short!", + "melee_animation": "9471", + "range_animation": "9471", + "combat_audio": "873,875,874", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "15", + "defence_animation": "9473", + "magic_animation": "9471", + "death_animation": "9472", + "name": "Turoth", + "defence_level": "85", + "safespot": null, + "lifepoints": "78", + "strength_level": "85", + "id": "1622", + "bonuses": "0,0,0,0,0,0,20,20,0,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "55" + }, + { + "examine": "He's one big leg short!", + "melee_animation": "9471", + "range_animation": "9471", + "combat_audio": "873,875,874", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "15", + "defence_animation": "9473", + "magic_animation": "9471", + "death_animation": "9472", + "name": "Turoth", + "defence_level": "88", + "safespot": null, + "lifepoints": "81", + "strength_level": "88", + "id": "1623", + "bonuses": "0,0,0,0,0,0,20,20,0,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "58" + }, + { + "examine": "The vacuumed face of evil.", + "melee_animation": "1557", + "range_animation": "1557", + "combat_audio": "414,416,415", + "attack_speed": "4", + "defence_animation": "1555", + "weakness": "2", + "slayer_exp": "105", + "magic_animation": "1557", + "death_animation": "1558", + "name": "Dust devil", + "defence_level": "40", + "safespot": null, + "lifepoints": "105", + "strength_level": "70", + "id": "1624", + "range_level": "1", + "attack_level": "105" + }, + { + "examine": "The cave-dwelling cousin of the dust devils.", + "melee_animation": "1557", + "range_animation": "0", + "defence_animation": "0", + "weakness": "2", + "magic_animation": "0", + "death_animation": "1558", + "name": "Smokedevil", + "defence_level": "61", + "safespot": null, + "lifepoints": "87", + "strength_level": "105", + "id": "1625", + "range_level": "61", + "attack_level": "105" + }, + { + "examine": "She's one leg short!", + "melee_animation": "9471", + "range_animation": "9471", + "combat_audio": "873,875,874", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "15", + "defence_animation": "9473", + "magic_animation": "9471", + "death_animation": "9472", + "name": "Turoth", + "defence_level": "86", + "safespot": null, + "lifepoints": "79", + "strength_level": "86", + "id": "1626", + "bonuses": "0,0,0,0,0,0,20,20,0,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "56" + }, + { + "examine": "It's one leg short!", + "melee_animation": "9471", + "range_animation": "9471", + "combat_audio": "873,875,874", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "15", + "defence_animation": "9473", + "magic_animation": "9471", + "death_animation": "9472", + "name": "Turoth", + "defence_level": "84", + "safespot": null, + "lifepoints": "77", + "strength_level": "84", + "id": "1627", + "bonuses": "0,0,0,0,0,0,20,20,0,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "54" + }, + { + "examine": "It's one small leg short!", + "melee_animation": "9471", + "range_animation": "9471", + "combat_audio": "873,875,874", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "15", + "defence_animation": "9473", + "magic_animation": "9471", + "death_animation": "9472", + "name": "Turoth", + "defence_level": "83", + "safespot": null, + "lifepoints": "76", + "strength_level": "83", + "id": "1628", + "bonuses": "0,0,0,0,0,0,20,20,0,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "53" + }, + { + "examine": "He's one big leg short!", + "melee_animation": "9471", + "range_animation": "9471", + "combat_audio": "873,875,874", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "15", + "defence_animation": "9473", + "magic_animation": "9471", + "death_animation": "9472", + "name": "Turoth", + "defence_level": "87", + "safespot": null, + "lifepoints": "80", + "strength_level": "87", + "id": "1629", + "bonuses": "0,0,0,0,0,0,20,20,0,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "57" + }, + { + "examine": "He's one big leg short!", + "melee_animation": "9471", + "range_animation": "9471", + "combat_audio": "873,875,874", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "15", + "defence_animation": "9473", + "magic_animation": "9471", + "death_animation": "9472", + "name": "Turoth", + "defence_level": "87", + "safespot": null, + "lifepoints": "80", + "strength_level": "87", + "id": "1630", + "bonuses": "0,0,0,0,0,0,20,20,0,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "57" + }, + { + "spawn_animation": "8081", + "examine": "A small fire demon.", + "melee_animation": "8080", + "combat_audio": "696,698,697", + "attack_speed": "5", + "magic_level": "10", + "respawn_delay": "60", + "defence_animation": "8084", + "weakness": "4", + "slayer_exp": "45", + "death_animation": "8078", + "name": "Pyrefiend", + "defence_level": "19", + "safespot": null, + "lifepoints": "45", + "strength_level": "29", + "id": "1633", + "bonuses": "52,30,22,1,1,0,0,0,0,0,0,10,10,10,0", + "clue_level": "1", + "range_level": "19", + "attack_level": "22" + }, + { + "spawn_animation": "8081", + "examine": "A small fire demon.", + "melee_animation": "8080", + "combat_audio": "696,698,697", + "attack_speed": "5", + "magic_level": "10", + "respawn_delay": "60", + "defence_animation": "8084", + "weakness": "4", + "slayer_exp": "45", + "death_animation": "8078", + "name": "Pyrefiend", + "defence_level": "19", + "safespot": null, + "lifepoints": "45", + "strength_level": "29", + "id": "1634", + "bonuses": "52,30,22,1,1,0,0,0,0,0,0,10,10,10,0", + "clue_level": "1", + "range_level": "19", + "attack_level": "22" + }, + { + "spawn_animation": "8081", + "examine": "A small fire demon.", + "melee_animation": "8080", + "combat_audio": "696,698,697", + "attack_speed": "5", + "magic_level": "10", + "respawn_delay": "60", + "defence_animation": "8084", + "weakness": "4", + "slayer_exp": "45", + "death_animation": "8078", + "name": "Pyrefiend", + "defence_level": "19", + "safespot": null, + "lifepoints": "45", + "strength_level": "29", + "id": "1635", + "bonuses": "52,30,22,1,1,0,0,0,0,0,0,10,10,10,0", + "clue_level": "1", + "range_level": "19", + "attack_level": "22" + }, + { + "spawn_animation": "8081", + "examine": "A small fire demon.", + "melee_animation": "8080", + "combat_audio": "696,698,697", + "attack_speed": "5", + "magic_level": "10", + "respawn_delay": "60", + "defence_animation": "8084", + "weakness": "4", + "slayer_exp": "45", + "death_animation": "8078", + "name": "Pyrefiend", + "defence_level": "19", + "safespot": null, + "lifepoints": "45", + "strength_level": "29", + "id": "1636", + "bonuses": "52,30,22,1,1,0,0,0,0,0,0,10,10,10,0", + "clue_level": "1", + "range_level": "19", + "attack_level": "22" + }, + { + "examine": "It's a Jelly.", + "melee_animation": "8569", + "range_animation": "8569", + "combat_audio": "547,550,549", + "attack_speed": "5", + "magic_level": "40", + "defence_animation": "8571", + "weakness": "2", + "slayer_exp": "75", + "magic_animation": "8569", + "death_animation": "8570", + "name": "Jelly", + "defence_level": "40", + "safespot": null, + "lifepoints": "75", + "strength_level": "45", + "id": "1637", + "clue_level": "2", + "range_level": "40", + "attack_level": "40" + }, + { + "examine": "Doesn't look so tough...", + "melee_animation": "8569", + "range_animation": "0", + "combat_audio": "547,550,549", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "2", + "slayer_exp": "75", + "magic_animation": "0", + "death_animation": "8570", + "name": "Jelly", + "defence_level": "49", + "safespot": null, + "lifepoints": "70", + "strength_level": "1", + "id": "1638", + "clue_level": "2", + "range_level": "49", + "attack_level": "1" + }, + { + "examine": "Wibbly.", + "melee_animation": "8569", + "range_animation": "0", + "combat_audio": "547,550,549", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "2", + "slayer_exp": "75", + "magic_animation": "0", + "death_animation": "8570", + "name": "Jelly", + "defence_level": "49", + "safespot": null, + "lifepoints": "70", + "strength_level": "1", + "id": "1639", + "clue_level": "2", + "range_level": "49", + "attack_level": "1" + }, + { + "examine": "There's always room for jelly.", + "melee_animation": "8569", + "range_animation": "0", + "combat_audio": "547,550,549", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "2", + "slayer_exp": "75", + "magic_animation": "0", + "death_animation": "8570", + "name": "Jelly", + "defence_level": "49", + "safespot": null, + "lifepoints": "140", + "strength_level": "1", + "id": "1640", + "clue_level": "2", + "range_level": "49", + "attack_level": "1" + }, + { + "melee_animation": "8569", + "combat_audio": "547,550,549", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "8571", + "slayer_exp": "75", + "name": "Jelly", + "defence_level": "1", + "safespot": null, + "lifepoints": "75", + "strength_level": "1", + "id": "1641", + "clue_level": "2", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "8569", + "combat_audio": "547,550,549", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "8571", + "slayer_exp": "75", + "name": "Jelly", + "defence_level": "1", + "safespot": null, + "lifepoints": "75", + "strength_level": "1", + "id": "1642", + "clue_level": "2", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An evil magic user.", + "start_gfx": "99", + "combat_style": "2", + "melee_animation": "811", + "range_animation": "811", + "magic_level": "75", + "respawn_delay": "12", + "end_gfx": "101", + "defence_animation": "0", + "weakness": "3", + "magic_animation": "811", + "death_animation": "836", + "name": "Infernal Mage", + "defence_level": "60", + "safespot": null, + "lifepoints": "60", + "strength_level": "1", + "id": "1643", + "bonuses": "0,0,0,0,0,0,0,0,40,0,0,0,0,0,0", + "range_level": "1", + "projectile": "100", + "attack_level": "1" + }, + { + "start_gfx": "99", + "combat_style": "2", + "melee_animation": "811", + "range_animation": "811", + "magic_level": "75", + "respawn_delay": "12", + "end_gfx": "101", + "defence_animation": "0", + "weakness": "3", + "magic_animation": "811", + "death_animation": "836", + "name": "Infernal Mage", + "defence_level": "60", + "safespot": null, + "lifepoints": "60", + "strength_level": "1", + "id": "1644", + "bonuses": "0,0,0,0,0,0,0,0,40,0,0,0,0,0,0", + "range_level": "1", + "projectile": "100", + "attack_level": "1" + }, + { + "examine": "An evil magic user.", + "start_gfx": "99", + "combat_style": "2", + "melee_animation": "811", + "range_animation": "811", + "magic_level": "75", + "respawn_delay": "12", + "end_gfx": "101", + "defence_animation": "0", + "weakness": "3", + "magic_animation": "811", + "death_animation": "836", + "name": "Infernal Mage", + "defence_level": "60", + "safespot": null, + "lifepoints": "60", + "strength_level": "1", + "id": "1645", + "bonuses": "0,0,0,0,0,0,0,0,40,0,0,0,0,0,0", + "range_level": "1", + "projectile": "100", + "attack_level": "1" + }, + { + "examine": "An evil magic user.", + "start_gfx": "99", + "combat_style": "2", + "melee_animation": "811", + "range_animation": "811", + "magic_level": "75", + "respawn_delay": "12", + "end_gfx": "101", + "defence_animation": "0", + "weakness": "3", + "magic_animation": "811", + "death_animation": "836", + "name": "Infernal Mage", + "defence_level": "60", + "safespot": null, + "lifepoints": "60", + "strength_level": "1", + "id": "1646", + "bonuses": "0,0,0,0,0,0,0,0,40,0,0,0,0,0,0", + "range_level": "1", + "projectile": "100", + "attack_level": "1" + }, + { + "examine": "An evil magic user.", + "start_gfx": "99", + "combat_style": "2", + "melee_animation": "811", + "range_animation": "811", + "magic_level": "75", + "respawn_delay": "12", + "end_gfx": "101", + "defence_animation": "0", + "weakness": "3", + "magic_animation": "811", + "death_animation": "836", + "name": "Infernal Mage", + "defence_level": "60", + "safespot": null, + "lifepoints": "60", + "strength_level": "1", + "id": "1647", + "bonuses": "0,0,0,0,0,0,0,0,40,0,0,0,0,0,0", + "range_level": "1", + "projectile": "100", + "attack_level": "1" + }, + { + "examine": "Now THAT'S handy.", + "melee_animation": "9125", + "range_animation": "9125", + "combat_audio": "377,379,378", + "attack_speed": "5", + "respawn_delay": "20", + "defence_animation": "9127", + "weakness": "9", + "slayer_exp": "19", + "magic_animation": "9125", + "death_animation": "9126", + "name": "Crawling Hand", + "defence_level": "5", + "safespot": null, + "lifepoints": "16", + "strength_level": "5", + "id": "1648", + "bonuses": "5,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "5" + }, + { + "examine": "Gimmie five. Actually", + "melee_animation": "9125", + "range_animation": "0", + "combat_audio": "377,379,378", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "slayer_exp": "19", + "magic_animation": "0", + "death_animation": "9126", + "name": "Crawling Hand", + "defence_level": "8", + "safespot": null, + "lifepoints": "5", + "strength_level": "8", + "id": "1649", + "range_level": "1", + "attack_level": "8" + }, + { + "examine": "Gimmie five. Actually", + "melee_animation": "9125", + "range_animation": "0", + "combat_audio": "377,379,378", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "9126", + "name": "Crawling Hand", + "defence_level": "8", + "safespot": null, + "lifepoints": "5", + "strength_level": "8", + "id": "1650", + "range_level": "1", + "attack_level": "8" + }, + { + "examine": "Gimmie five. Actually", + "melee_animation": "9125", + "range_animation": "0", + "combat_audio": "377,379,378", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "slayer_exp": "19", + "magic_animation": "0", + "death_animation": "9126", + "name": "Crawling Hand", + "defence_level": "8", + "safespot": null, + "lifepoints": "5", + "strength_level": "8", + "id": "1651", + "range_level": "1", + "attack_level": "8" + }, + { + "examine": "Gimmie five. Actually", + "melee_animation": "9125", + "range_animation": "0", + "combat_audio": "377,379,378", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "slayer_exp": "19", + "magic_animation": "0", + "death_animation": "9126", + "name": "Crawling Hand", + "defence_level": "8", + "safespot": null, + "lifepoints": "5", + "strength_level": "8", + "id": "1652", + "range_level": "1", + "attack_level": "8" + }, + { + "examine": "Now THAT's handy.", + "melee_animation": "9444", + "range_animation": "0", + "combat_audio": "377,379,378", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "slayer_exp": "16", + "magic_animation": "0", + "death_animation": "9445", + "name": "Crawling Hand", + "defence_level": "13", + "safespot": null, + "lifepoints": "18", + "strength_level": "13", + "id": "1653", + "range_level": "1", + "attack_level": "13" + }, + { + "examine": "I'm glad it's just the hand I can see...", + "melee_animation": "9444", + "range_animation": "0", + "combat_audio": "377,379,378", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "slayer_exp": "16", + "magic_animation": "0", + "death_animation": "9445", + "name": "Crawling Hand", + "defence_level": "13", + "safespot": null, + "lifepoints": "18", + "strength_level": "13", + "id": "1654", + "range_level": "1", + "attack_level": "13" + }, + { + "examine": "A big severed hand.", + "melee_animation": "9444", + "range_animation": "0", + "combat_audio": "377,379,378", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "9445", + "name": "Crawling Hand", + "defence_level": "13", + "safespot": null, + "lifepoints": "18", + "strength_level": "13", + "id": "1655", + "range_level": "1", + "attack_level": "13" + }, + { + "examine": "Give the guy a big hand.....", + "melee_animation": "9444", + "range_animation": "0", + "combat_audio": "377,379,378", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "slayer_exp": "16", + "magic_animation": "0", + "death_animation": "9445", + "name": "Crawling Hand", + "defence_level": "13", + "safespot": null, + "lifepoints": "18", + "strength_level": "13", + "id": "1656", + "range_level": "1", + "attack_level": "13" + }, + { + "examine": "A big severed hand.", + "melee_animation": "9444", + "range_animation": "0", + "combat_audio": "377,379,378", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "slayer_exp": "16", + "magic_animation": "0", + "death_animation": "9445", + "name": "Crawling Hand", + "defence_level": "13", + "safespot": null, + "lifepoints": "18", + "strength_level": "13", + "id": "1657", + "range_level": "1", + "attack_level": "13" + }, + { + "examine": "A Supplier of Magical robes.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Robe Store owner", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1658", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He's in charge of the Skullball Course.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Skullball Boss", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1660", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He's in charge of the Agility Course.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Agility Boss", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1661", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A skullball guide.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Skullball Trainer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1662", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A werewolf agility trainer.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Agility Trainer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1663", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Looks like he's guarding a trapdoor...", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Werewolf", + "defence_level": "1", + "safespot": null, + "lifepoints": "100", + "strength_level": "1", + "id": "1665", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Gardener Ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "436,439,438", + "strength_level": "1", + "id": "1675", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "His beard seems to have a life of its own.", + "melee_animation": "4666", + "range_animation": "4666", + "combat_audio": "449,451,450", + "magic_level": "1", + "defence_animation": "4665", + "weakness": "3", + "magic_animation": "4666", + "death_animation": "4668", + "name": "Moss giant", + "defence_level": "60", + "safespot": null, + "lifepoints": "120", + "strength_level": "60", + "id": "1681", + "aggressive": "true", + "bonuses": "66,62,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "60" + }, + { + "examine": "A ghost disciple.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "436,439,438", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ghost disciple", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1686", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A trader from across the eastern sea.", + "start_gfx": "0", + "start_height": "0", + "melee_animation": "386", + "range_animation": "0", + "magic_level": "1", + "respawn_delay": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "836", + "name": "Ak-Haranu", + "defence_level": "1", + "movement_radius": "2", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1688", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It's an undead cow.", + "melee_animation": "5849", + "range_animation": "0", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "5", + "defence_animation": "5850", + "weakness": "8", + "magic_animation": "0", + "death_animation": "5851", + "name": "Undead cow", + "defence_level": "1", + "safespot": null, + "lifepoints": "8", + "strength_level": "3", + "id": "1691", + "aggressive": "false", + "bonuses": "-15,-15,-15,0,0,-21,-21,-21,-21,-21,0,-15,0,0,0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Yup, definitely a chicken... an undead chicken.", + "melee_animation": "5387", + "range_animation": "0", + "combat_audio": "355,357,356", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "25", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "5389", + "name": "Undead chicken", + "defence_level": "1", + "safespot": null, + "lifepoints": "3", + "strength_level": "1", + "id": "1692", + "aggressive": "false", + "bonuses": "-47,-47,-47,0,0,-42,-42,-42,-42,-42,0,-42,0,0,0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An extremely vicious lobster.", + "melee_animation": "6265", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "6267", + "name": "Giant lobster", + "defence_level": "30", + "safespot": null, + "lifepoints": "128", + "strength_level": "30", + "id": "1693", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "An old", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Old crone", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1695", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A creaky old man.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Old man", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1696", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A spooky ghost villager.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "436,439,438", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ghost villager", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1697", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "This poor soul cannot understand why it has not passed to the next world.", + "melee_animation": "422", + "range_animation": "0", + "attack_speed": "5", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "3", + "slayer_exp": "51", + "magic_animation": "0", + "death_animation": "836", + "name": "Tortured soul", + "defence_level": "38", + "safespot": null, + "lifepoints": "51", + "strength_level": "62", + "id": "1698", + "aggressive": "true", + "range_level": "1", + "attack_level": "52" + }, + { + "examine": "Beware the ghostly shopkeeper's wares!", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "436,439,438", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ghost shopkeeper", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1699", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Doesn't look like the bar's open anymore.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "436,439,438", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ghost innkeeper", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1700", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Ghost farmer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "436,439,438", + "strength_level": "1", + "id": "1701", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A ghost banker.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "436,439,438", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ghost banker", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1702", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A ghost sailor.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "436,439,438", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ghost sailor", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1703", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A ghostship captain.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "436,439,438", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ghost captain", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1704", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Ghost captain", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "436,439,438", + "strength_level": "1", + "id": "1705", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "This ghost guards the gates of Port Phasmatys.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "436,439,438", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ghost guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1706", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Ghost (?)", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "436,439,438", + "strength_level": "1", + "id": "1707", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Ghost (?)", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "436,439,438", + "strength_level": "1", + "id": "1708", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A guard for the humans against monster group.", + "melee_animation": "390", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "836", + "name": "H.A.M. Guard", + "defence_level": "22", + "safespot": null, + "lifepoints": "31", + "strength_level": "22", + "id": "1710", + "clue_level": "0", + "range_level": "1", + "attack_level": "22" + }, + { + "examine": "A guard for the humans against monster group.", + "melee_animation": "390", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "836", + "name": "H.A.M. Guard", + "defence_level": "22", + "safespot": null, + "lifepoints": "31", + "strength_level": "22", + "id": "1711", + "clue_level": "0", + "range_level": "1", + "attack_level": "22" + }, + { + "examine": "A guard for the humans against monster group.", + "melee_animation": "390", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "836", + "name": "H.A.M. Guard", + "defence_level": "22", + "safespot": null, + "lifepoints": "31", + "strength_level": "22", + "id": "1712", + "clue_level": "0", + "range_level": "1", + "attack_level": "22" + }, + { + "examine": "A deacon in the Humans Against Monsters group. A rather enthusiastic chap.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "H.A.M. Deacon", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1713", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A member of the 'Humans Against Monsters' group.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "H.A.M. Member", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1714", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A member of the 'Humans Against Monsters' group.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "H.A.M. Member", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1715", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A member of the 'Humans Against Monsters' group.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "H.A.M. Member", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1716", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A member of the 'Humans Against Monsters' group.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "H.A.M. Member", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1717", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A young man with a dark and mysterious past.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Jimmy the Chisel", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1718", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Manages the mill.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Oak", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1739", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of Sigmund's elite guards.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Yew", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1740", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of Sigmund's elite guards.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Evergreen", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1741", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A member of Sigmund's H.A.M. splinter group.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Evergreen", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1742", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A member of Sigmund's H.A.M. splinter group.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Evergreen", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1743", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A member of Sigmund's H.A.M. splinter group.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Tree", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1744", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A member of Sigmund's H.A.M. splinter group.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Dead tree", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1745", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A member of Sigmund's H.A.M. splinter group.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Achey Tree", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1746", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A member of Sigmund's H.A.M. splinter group.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Tree", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1747", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A member of Sigmund's H.A.M. splinter group.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Tree", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1748", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A giant raptor.", + "melee_animation": "1010", + "combat_audio": "832,834,833", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "1012", + "magic_animation": "0", + "death_animation": "1013", + "name": "Terrorbird", + "defence_level": "19", + "safespot": null, + "lifepoints": "34", + "strength_level": "23", + "id": "1751", + "aggressive": "false", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "23" + }, + { + "examine": "These gnomes know how to get around!", + "melee_animation": "6790", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "6791", + "name": "Mounted terrorbird gnome", + "defence_level": "33", + "safespot": null, + "lifepoints": "37", + "strength_level": "33", + "id": "1752", + "range_level": "1", + "attack_level": "33" + }, + { + "examine": "A farmer's enemy.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Crow", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1754", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He grows the crops in this area.", + "melee_animation": "7181", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Farmer", + "defence_level": "5", + "safespot": null, + "lifepoints": "7", + "strength_level": "5", + "id": "1757", + "range_level": "1", + "attack_level": "5" + }, + { + "examine": "He grows the crops in this area.", + "melee_animation": "7181", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Farmer", + "defence_level": "5", + "safespot": null, + "lifepoints": "7", + "strength_level": "5", + "id": "1758", + "range_level": "1", + "attack_level": "5" + }, + { + "examine": "Farming.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Farmer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1759", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He grows the crops in this area.", + "melee_animation": "7181", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "7185", + "name": "Farmer", + "defence_level": "5", + "safespot": null, + "lifepoints": "7", + "strength_level": "5", + "id": "1760", + "range_level": "1", + "attack_level": "5" + }, + { + "examine": "Farming the wheat.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Farmer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1761", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "White and fluffy.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Sheep", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1763", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Young, but still beefy.", + "melee_animation": "5849", + "range_animation": "5849", + "combat_audio": "366,368,367", + "attack_speed": "5", + "defence_animation": "5850", + "slayer_exp": "8", + "magic_animation": "5849", + "death_animation": "5851", + "name": "Cow calf", + "defence_level": "1", + "safespot": null, + "lifepoints": "6", + "strength_level": "1", + "id": "1766", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Where beef comes from.", + "melee_animation": "5849", + "range_animation": "5849", + "combat_audio": "369,371,370", + "attack_speed": "5", + "defence_animation": "5850", + "weakness": "8", + "slayer_exp": "8", + "magic_animation": "5849", + "death_animation": "5851", + "name": "Cow", + "defence_level": "1", + "safespot": null, + "lifepoints": "8", + "strength_level": "1", + "id": "1767", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Young, but still beefy.", + "melee_animation": "5849", + "range_animation": "5849", + "combat_audio": "366,368,367", + "attack_speed": "5", + "defence_animation": "5850", + "slayer_exp": "8", + "magic_animation": "5849", + "death_animation": "5851", + "name": "Cow calf", + "defence_level": "1", + "safespot": null, + "lifepoints": "6", + "strength_level": "1", + "id": "1768", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "weakness": "7", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "2", + "id": "1769", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "weakness": "7", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "2", + "id": "1770", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "weakness": "7", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "2", + "id": "1771", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "weakness": "7", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "2", + "id": "1772", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "weakness": "7", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "2", + "id": "1773", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "weakness": "7", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "2", + "id": "1774", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "weakness": "7", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "2", + "id": "1775", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "weakness": "7", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "2", + "id": "1776", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He looks quite independent in an aggressive and business like way.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "498,500,499", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Hammerspike Stoutbeard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1794", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A short stout menacing fellow.", + "melee_animation": "99", + "range_animation": "0", + "attack_speed": "6", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "102", + "name": "Dwarf gang member", + "defence_level": "25", + "safespot": null, + "lifepoints": "35", + "strength_level": "25", + "id": "1795", + "range_level": "1", + "attack_level": "25" + }, + { + "examine": "A short stout menacing fellow.", + "melee_animation": "99", + "range_animation": "0", + "attack_speed": "6", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "102", + "name": "Dwarf gang member", + "defence_level": "25", + "safespot": null, + "lifepoints": "35", + "strength_level": "25", + "id": "1796", + "range_level": "1", + "attack_level": "25" + }, + { + "examine": "A short stout menacing fellow.", + "melee_animation": "99", + "range_animation": "0", + "attack_speed": "6", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "102", + "name": "Dwarf gang member", + "defence_level": "25", + "safespot": null, + "lifepoints": "35", + "strength_level": "25", + "id": "1797", + "range_level": "1", + "attack_level": "25" + }, + { + "melee_animation": "1750", + "respawn_delay": "60", + "defence_animation": "1751", + "death_animation": "1752", + "name": "Slagilith", + "defence_level": "1", + "safespot": null, + "lifepoints": "60", + "strength_level": "1", + "id": "1802", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A pile of boulders.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Rock pile", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1803", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He seems to be guarding a pile of rocks. Interesting job.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1805", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He seems to be guarding a single rock. Interesting job.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1806", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The Chieftain of the mountain camp.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Hamal the Chieftain", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1807", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Is that a bear... or a man?", + "melee_animation": "1760", + "range_animation": "0", + "magic_level": "23", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "1759", + "name": "The Kendal", + "defence_level": "23", + "safespot": null, + "lifepoints": "85", + "strength_level": "23", + "id": "1812", + "aggressive": "true", + "range_level": "23", + "attack_level": "23" + }, + { + "melee_animation": "1760", + "respawn_delay": "60", + "defence_animation": "1758", + "death_animation": "1759", + "name": "The Kendal", + "defence_level": "1", + "safespot": null, + "lifepoints": "50", + "strength_level": "1", + "id": "1813", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of the inhabitants of the camp.", + "melee_animation": "422", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Camp dweller", + "defence_level": "11", + "safespot": null, + "lifepoints": "15", + "strength_level": "11", + "id": "1814", + "range_level": "1", + "attack_level": "11" + }, + { + "examine": "One of the inhabitants of the camp.", + "melee_animation": "422", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Camp dweller", + "defence_level": "11", + "safespot": null, + "lifepoints": "15", + "strength_level": "11", + "id": "1815", + "range_level": "1", + "attack_level": "11" + }, + { + "examine": "One of the inhabitants of the camp.", + "melee_animation": "422", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Camp dweller", + "defence_level": "11", + "safespot": null, + "lifepoints": "15", + "strength_level": "11", + "id": "1816", + "range_level": "1", + "attack_level": "11" + }, + { + "examine": "One of the inhabitants of the camp.", + "melee_animation": "422", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Camp dweller", + "defence_level": "11", + "safespot": null, + "lifepoints": "15", + "strength_level": "11", + "id": "1817", + "range_level": "1", + "attack_level": "11" + }, + { + "examine": "One of the inhabitants of the camp.", + "melee_animation": "422", + "range_animation": "0", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Camp dweller", + "defence_level": "11", + "safespot": null, + "lifepoints": "15", + "strength_level": "11", + "id": "1818", + "range_level": "1", + "attack_level": "11" + }, + { + "examine": "Looks a little underfed.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Mountain Goat", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1819", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "This goat belongs to the mountain camp people.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Mountain Goat", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1820", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A goblin with big bulging eyes.", + "melee_animation": "6001", + "range_animation": "0", + "combat_audio": "469,472,471", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "6003", + "name": "Cave goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "1", + "strength_level": "1", + "id": "1822", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A goblin with big bulging eyes.", + "melee_animation": "6001", + "range_animation": "0", + "combat_audio": "469,472,471", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "6003", + "name": "Cave goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "1", + "strength_level": "1", + "id": "1823", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A goblin with big bulging eyes.", + "melee_animation": "6001", + "range_animation": "0", + "combat_audio": "469,472,471", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "6003", + "name": "Cave goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "1", + "strength_level": "1", + "id": "1824", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A goblin with big bulging eyes.", + "melee_animation": "6001", + "range_animation": "0", + "combat_audio": "469,472,471", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "6003", + "name": "Cave goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "1", + "strength_level": "1", + "id": "1825", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A human zombie.", + "melee_animation": "5568", + "combat_audio": "931,923,922", + "defence_animation": "5567", + "death_animation": "5569", + "name": "Zombie", + "defence_level": "30", + "safespot": null, + "lifepoints": "50", + "strength_level": "30", + "id": "1826", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "Flies like a rock.", + "melee_animation": "9454", + "range_animation": "1516", + "combat_audio": "428,430,429", + "attack_speed": "4", + "magic_level": "1", + "defence_animation": "9455", + "slayer_exp": "105", + "magic_animation": "1516", + "death_animation": "1518", + "name": "Gargoyle", + "defence_level": "107", + "safespot": null, + "lifepoints": "105", + "strength_level": "95", + "id": "1827", + "aggressive": "true", + "bonuses": "0,0,0,0,0,20,20,0,20,20,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "75" + }, + { + "examine": "It didn't get that big eating flies!", + "melee_animation": "1793", + "range_animation": "1793", + "attack_speed": "6", + "defence_animation": "1794", + "weakness": "1", + "magic_animation": "1793", + "death_animation": "1795", + "name": "Giant frog", + "defence_level": "60", + "safespot": null, + "lifepoints": "100", + "strength_level": "45", + "id": "1828", + "bonuses": "10,10,10,10,10,10,1,10,10,10,10,37,0,0,0", + "range_level": "32", + "attack_level": "45" + }, + { + "examine": "It didn't get that big eating flies.", + "melee_animation": "1793", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "1", + "magic_animation": "0", + "death_animation": "1795", + "name": "Big frog", + "defence_level": "26", + "safespot": null, + "lifepoints": "37", + "strength_level": "1", + "id": "1829", + "range_level": "26", + "attack_level": "1" + }, + { + "examine": "A foul-smelling blob of protoplasm.", + "melee_animation": "1789", + "range_animation": "0", + "combat_audio": "784,786,785", + "attack_speed": "4", + "poisonous": "true", + "magic_level": "13", + "respawn_delay": "15", + "defence_animation": "0", + "weakness": "1", + "slayer_exp": "25", + "poison_amount": "3", + "magic_animation": "0", + "death_animation": "1792", + "name": "Cave slime", + "defence_level": "35", + "safespot": null, + "lifepoints": "25", + "strength_level": "13", + "id": "1831", + "aggressive": "false", + "clue_level": "0", + "range_level": "1", + "attack_level": "13" + }, + { + "examine": "A nasty crawling critter.", + "melee_animation": "6079", + "range_animation": "0", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "2", + "slayer_exp": "5", + "magic_animation": "0", + "death_animation": "6082", + "name": "Cave bug", + "defence_level": "6", + "safespot": null, + "lifepoints": "5", + "strength_level": "5", + "id": "1832", + "bonuses": "0,0,0,0,0,10,10,5,5,10,0,0,0,0,0", + "range_level": "1", + "attack_level": "6" + }, + { + "examine": "A little", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cave bug larva", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1833", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Has an odd smell about him.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Candle seller", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1834", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A short angry guy.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Dwarven Engineer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1840", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The little guy is having trouble standing up right.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Khorvak, a dwarven engineer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1842", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It's probably you who will be paying the ferryman.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Dwarven Ferryman", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1843", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It's probably you who will be paying the ferryman.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Dwarven Ferryman", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1844", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He seems to be in charge of the ship on the river.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Dwarven Boatman", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1846", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It is the avatar of the Arzinian Being of Bordanzan", + "melee_animation": "1840", + "range_animation": "0", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "1841", + "name": "Arzinian Avatar of Strength", + "defence_level": "40", + "safespot": null, + "lifepoints": "114", + "strength_level": "40", + "id": "1850", + "range_level": "1", + "attack_level": "40" + }, + { + "melee_animation": "1840", + "respawn_delay": "60", + "defence_animation": "1842", + "death_animation": "1843", + "name": "Arzinian Avatar of Strength", + "defence_level": "1", + "safespot": null, + "lifepoints": "110", + "strength_level": "1", + "id": "1851", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "1840", + "respawn_delay": "60", + "defence_animation": "1842", + "death_animation": "1843", + "name": "Arzinian Avatar of Strength", + "defence_level": "1", + "safespot": null, + "lifepoints": "70", + "strength_level": "1", + "id": "1852", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It is the avatar of the Arzinian Being of Bordanzan", + "melee_animation": "1843", + "range_animation": "1843", + "defence_animation": "0", + "weakness": "0", + "magic_animation": "0", + "death_animation": "1841", + "name": "Arzinian Avatar of Ranging", + "defence_level": "40", + "safespot": null, + "lifepoints": "114", + "strength_level": "30", + "id": "1853", + "aggressive": "true", + "range_level": "40", + "attack_level": "30" + }, + { + "melee_animation": "1840", + "respawn_delay": "60", + "defence_animation": "1842", + "death_animation": "1843", + "name": "Arzinian Avatar of Ranging", + "defence_level": "1", + "safespot": null, + "lifepoints": "110", + "strength_level": "1", + "id": "1854", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "1840", + "respawn_delay": "60", + "defence_animation": "1842", + "death_animation": "1843", + "name": "Arzinian Avatar of Ranging", + "defence_level": "1", + "safespot": null, + "lifepoints": "70", + "strength_level": "1", + "id": "1855", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It is the avatar of the Arzinian Being of Bordanzan", + "melee_animation": "1844", + "range_animation": "0", + "magic_level": "40", + "defence_animation": "0", + "weakness": "3", + "magic_animation": "0", + "death_animation": "1841", + "name": "Arzinian Avatar of Magic", + "defence_level": "40", + "safespot": null, + "lifepoints": "114", + "strength_level": "30", + "id": "1856", + "aggressive": "true", + "range_level": "1", + "attack_level": "30" + }, + { + "melee_animation": "1840", + "respawn_delay": "60", + "defence_animation": "1842", + "death_animation": "1843", + "name": "Arzinian Avatar of Magic", + "defence_level": "1", + "safespot": null, + "lifepoints": "110", + "strength_level": "1", + "id": "1857", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "1840", + "respawn_delay": "60", + "defence_animation": "1842", + "death_animation": "1843", + "name": "Arzinian Avatar of Magic", + "defence_level": "1", + "safespot": null, + "lifepoints": "70", + "strength_level": "1", + "id": "1858", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It's the Arzinian Being", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Arzinian Being of Bordanzan", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1859", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He sells ranging equipment.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Brian", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1866", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Nemarti looks ready to teach you about ranged combat.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ranged Tutor", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1861", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Drunk man.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Drunken Ali", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1863", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A hassled looking barman.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ali The barman", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1864", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A kebab seller.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ali the Kebab seller", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1865", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Ali the discount animal seller.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ali the Camel Man", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1867", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A mischievous looking child.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Street urchin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1868", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An old Hag named Alice.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ali the Hag", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1871", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A snake charmer.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "3609,3608,3610", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ali the Snake Charmer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1872", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A foul tempered ugly lumpy yellow horse prone to spitting.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ali the Camel", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1873", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A slithering serpent.", + "melee_animation": "275", + "range_animation": "0", + "combat_audio": "3609,3608,3610", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "1", + "magic_animation": "0", + "death_animation": "278", + "name": "Desert snake", + "defence_level": "6", + "safespot": null, + "lifepoints": "8", + "strength_level": "4", + "id": "1874", + "range_level": "6", + "attack_level": "4" + }, + { + "examine": "A toothless old Snake.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "3609,3608,3610", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Snake", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1875", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A very tough-looking bandit.", + "melee_animation": "390", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Bandit champion", + "defence_level": "39", + "safespot": null, + "lifepoints": "55", + "strength_level": "39", + "id": "1885", + "aggressive": "true", + "range_level": "1", + "attack_level": "39" + }, + { + "examine": "Probably the weakest bandit in the world ....ever.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cowardly Bandit", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1886", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Smooth operator.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "703,705,704", + "attack_speed": "4", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ali the Operator", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1902", + "bonuses": "0,0,0,0,0,10,10,5,5,10,0,0,0,0,0", + "range_level": "1", + "attack_level": "6" + }, + { + "examine": "Menaphite thug.", + "melee_animation": "0", + "range_animation": "0", + "attack_speed": "4", + "magic_level": "0", + "respawn_delay": "5", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "0", + "name": "Menaphite Thug", + "defence_level": "20", + "safespot": null, + "lifepoints": "60", + "strength_level": "50", + "id": "1904", + "aggressive": "false", + "bonuses": "4,4,4,0,0,9,8,10,0,0,0,9,0,0,0", + "range_level": "0", + "attack_level": "60" + }, + { + "examine": "Menaphite thug.", + "melee_animation": "395", + "range_animation": "0", + "attack_speed": "4", + "magic_level": "0", + "respawn_delay": "5", + "defence_animation": "425", + "magic_animation": "0", + "death_animation": "836", + "name": "Menaphite Thug", + "defence_level": "20", + "safespot": null, + "lifepoints": "60", + "strength_level": "50", + "id": "1905", + "aggressive": "false", + "bonuses": "4,4,4,0,0,9,8,10,0,0,0,9,0,0,0", + "range_level": "0", + "attack_level": "60" + }, + { + "examine": "Tough looking Menaphite.", + "melee_animation": "395", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Tough Guy", + "defence_level": "39", + "safespot": null, + "lifepoints": "114", + "strength_level": "39", + "id": "1906", + "aggressive": "true", + "range_level": "1", + "attack_level": "39" + }, + { + "examine": "Definitely not a chicken.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Desert Phoenix", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1911", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Ice warrior.", + "melee_animation": "440", + "range_animation": "440", + "attack_speed": "5", + "defence_animation": "404", + "magic_animation": "412", + "death_animation": "9055", + "name": "Kamil", + "defence_level": "135", + "safespot": null, + "lifepoints": "130", + "strength_level": "80", + "id": "1913", + "bonuses": "0,60,0,0,0,35,60,35,0,0,0,100,0,0,0", + "range_level": "1", + "attack_level": "190" + }, + { + "examine": "A vampyre warrior of Zamorak.", + "melee_animation": "1264", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Dessous", + "defence_level": "99", + "safespot": null, + "lifepoints": "200", + "strength_level": "99", + "id": "1914", + "aggressive": "true", + "bonuses": "0,0,50,0,0,10,150,150,0,0,0,50,0,0,0", + "range_level": "1", + "attack_level": "99" + }, + { + "examine": "A vampyre warrior of Zamorak.", + "melee_animation": "1264", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Dessous", + "defence_level": "99", + "safespot": null, + "lifepoints": "200", + "strength_level": "99", + "id": "1915", + "aggressive": "true", + "bonuses": "0,0,50,0,0,10,150,150,0,0,0,50,0,0,0", + "range_level": "1", + "attack_level": "99" + }, + { + "examine": "Luckily, I can't see much of his face.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ruantun", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1916", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "I guess he sells what he steals...?", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Bandit shopkeeper", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1917", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Hardened by the cutthroat world of archaeology.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Archaeologist", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1918", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Very mysterious looking...", + "melee_animation": "377", + "range_animation": "0", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "836", + "name": "Stranger", + "defence_level": "58", + "safespot": null, + "lifepoints": "82", + "strength_level": "58", + "id": "1919", + "aggressive": "true", + "range_level": "1", + "attack_level": "58" + }, + { + "examine": "One of Morytania's vampyric nobility.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Malak", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1920", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Looks like a rough-and-ready type.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Bartender", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1921", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A tough-looking criminal.", + "melee_animation": "412", + "range_animation": "412", + "attack_speed": "5", + "defence_animation": "404", + "magic_animation": "412", + "death_animation": "9055", + "name": "Bandit", + "defence_level": "30", + "safespot": null, + "lifepoints": "65", + "strength_level": "70", + "id": "1926", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "This is an NPC.", + "melee_animation": "412", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "100", + "defence_animation": "404", + "magic_animation": "0", + "death_animation": "9055", + "name": "Bandit", + "defence_level": "1", + "safespot": null, + "lifepoints": "65", + "strength_level": "1", + "id": "1931", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ice troll.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ice troll", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1935", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Brrrrr...he must be cold!", + "melee_animation": "284", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "285", + "weakness": "9", + "magic_animation": "0", + "death_animation": "287", + "name": "Ice troll", + "defence_level": "64", + "safespot": null, + "lifepoints": "91", + "strength_level": "64", + "id": "1936", + "aggressive": "true", + "range_level": "1", + "attack_level": "64" + }, + { + "examine": "Brrrrr...he must be cold!", + "melee_animation": "284", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "285", + "weakness": "9", + "magic_animation": "0", + "death_animation": "287", + "name": "Ice troll", + "defence_level": "64", + "safespot": null, + "lifepoints": "91", + "strength_level": "64", + "id": "1937", + "range_level": "1", + "attack_level": "64" + }, + { + "examine": "Brrrrr...he must be cold!", + "melee_animation": "284", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "285", + "weakness": "9", + "magic_animation": "0", + "death_animation": "287", + "name": "Ice troll", + "defence_level": "64", + "safespot": null, + "lifepoints": "91", + "strength_level": "64", + "id": "1938", + "aggressive": "true", + "range_level": "1", + "attack_level": "64" + }, + { + "examine": "Brrrrr...he must be cold!", + "melee_animation": "284", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "285", + "weakness": "9", + "magic_animation": "0", + "death_animation": "287", + "name": "Ice troll", + "defence_level": "64", + "safespot": null, + "lifepoints": "91", + "strength_level": "64", + "id": "1939", + "range_level": "1", + "attack_level": "64" + }, + { + "examine": "Brrrrr...he must be cold!", + "melee_animation": "284", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "285", + "weakness": "9", + "magic_animation": "0", + "death_animation": "287", + "name": "Ice troll", + "defence_level": "64", + "safespot": null, + "lifepoints": "91", + "strength_level": "64", + "id": "1940", + "aggressive": "true", + "range_level": "1", + "attack_level": "64" + }, + { + "examine": "Brrrrr...he must be cold!", + "melee_animation": "284", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "285", + "weakness": "9", + "magic_animation": "0", + "death_animation": "287", + "name": "Ice troll", + "defence_level": "64", + "safespot": null, + "lifepoints": "91", + "strength_level": "64", + "id": "1941", + "aggressive": "true", + "range_level": "1", + "attack_level": "64" + }, + { + "examine": "Brrrrr...he must be cold!", + "melee_animation": "284", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "285", + "weakness": "9", + "magic_animation": "0", + "death_animation": "287", + "name": "Ice troll", + "defence_level": "64", + "safespot": null, + "lifepoints": "91", + "strength_level": "64", + "id": "1942", + "range_level": "1", + "attack_level": "64" + }, + { + "examine": "A troll frozen in a block of ice.", + "melee_animation": "0", + "range_animation": "0", + "respawn_delay": "1", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "0", + "name": "Ice block", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1943", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A troll frozen in a block of ice.", + "melee_animation": "0", + "range_animation": "0", + "respawn_delay": "1", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "0", + "name": "Ice block", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1944", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A troll frozen in a block of ice.", + "melee_animation": "0", + "range_animation": "0", + "respawn_delay": "1", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "0", + "name": "Ice block", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1945", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A troll frozen in a block of ice.", + "melee_animation": "0", + "range_animation": "0", + "respawn_delay": "1", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "0", + "name": "Ice block", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1946", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ice troll.", + "name": "Troll father", + "id": "1947" + }, + { + "examine": "An ice troll.", + "name": "Troll father", + "id": "1948" + }, + { + "examine": "An ice troll.", + "name": "Troll mother", + "id": "1949" + }, + { + "examine": "An ice troll.", + "name": "Troll mother", + "id": "1950" + }, + { + "examine": "Not a man's best friend.", + "melee_animation": "6579", + "range_animation": "6579", + "magic_level": "30", + "respawn_delay": "28", + "defence_animation": "6578", + "magic_animation": "6579", + "death_animation": "6576", + "name": "Ice wolf", + "defence_level": "60", + "safespot": null, + "lifepoints": "72", + "strength_level": "60", + "id": "1951", + "aggressive": "true", + "bonuses": "40,120,150,150,150,40,130,75,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "60" + }, + { + "examine": "Not a man's best friend.", + "melee_animation": "6579", + "range_animation": "6579", + "magic_level": "30", + "respawn_delay": "28", + "defence_animation": "6578", + "magic_animation": "6579", + "death_animation": "6576", + "name": "Ice wolf", + "defence_level": "60", + "safespot": null, + "lifepoints": "72", + "strength_level": "60", + "id": "1952", + "aggressive": "true", + "bonuses": "40,120,150,150,150,40,130,75,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "60" + }, + { + "examine": "Not a man's best friend.", + "melee_animation": "6579", + "range_animation": "6579", + "magic_level": "30", + "respawn_delay": "28", + "defence_animation": "6578", + "magic_animation": "6579", + "death_animation": "6576", + "name": "Ice wolf", + "defence_level": "60", + "safespot": null, + "lifepoints": "72", + "strength_level": "60", + "id": "1953", + "aggressive": "true", + "bonuses": "40,120,150,150,150,40,130,75,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "60" + }, + { + "examine": "Not a man's best friend.", + "melee_animation": "6579", + "range_animation": "6579", + "magic_level": "30", + "respawn_delay": "28", + "defence_animation": "6578", + "magic_animation": "6579", + "death_animation": "6576", + "name": "Ice wolf", + "defence_level": "60", + "safespot": null, + "lifepoints": "72", + "strength_level": "60", + "id": "1954", + "aggressive": "true", + "bonuses": "40,120,150,150,150,40,130,75,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "60" + }, + { + "examine": "Not a man's best friend.", + "melee_animation": "6579", + "range_animation": "6579", + "magic_level": "30", + "respawn_delay": "28", + "defence_animation": "6578", + "magic_animation": "6579", + "death_animation": "6576", + "name": "Ice wolf", + "defence_level": "60", + "safespot": null, + "lifepoints": "72", + "strength_level": "60", + "id": "1955", + "aggressive": "true", + "bonuses": "40,120,150,150,150,40,130,75,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "60" + }, + { + "examine": "Not a man's best friend.", + "melee_animation": "6579", + "range_animation": "6579", + "magic_level": "30", + "respawn_delay": "28", + "defence_animation": "6578", + "magic_animation": "6579", + "death_animation": "6576", + "name": "Ice wolf", + "defence_level": "60", + "safespot": null, + "lifepoints": "72", + "strength_level": "60", + "id": "1956", + "aggressive": "true", + "bonuses": "40,120,150,150,150,40,130,75,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "60" + }, + { + "examine": "Highly flammable!", + "melee_animation": "5549", + "range_animation": "0", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "5555", + "name": "Mummy", + "defence_level": "55", + "safespot": null, + "lifepoints": "78", + "strength_level": "55", + "id": "1958", + "range_level": "1", + "attack_level": "55" + }, + { + "examine": "A tightly-wrapped monster.", + "melee_animation": "5549", + "range_animation": "0", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "5555", + "name": "Mummy", + "defence_level": "90", + "safespot": null, + "lifepoints": "90", + "strength_level": "90", + "id": "1961", + "aggressive": "true", + "range_level": "1", + "attack_level": "90" + }, + { + "examine": "Spooky, bandaged dead dude.", + "melee_animation": "5549", + "range_animation": "0", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "5555", + "name": "Mummy", + "defence_level": "90", + "poison_immune": "true", + "safespot": null, + "lifepoints": "90", + "strength_level": "90", + "id": "1962", + "aggressive": "true", + "range_level": "1", + "attack_level": "90" + }, + { + "examine": "A victim of poor first aid.", + "melee_animation": "5549", + "range_animation": "0", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "5555", + "name": "Mummy", + "defence_level": "90", + "poison_immune": "true", + "safespot": null, + "lifepoints": "90", + "strength_level": "90", + "id": "1963", + "aggressive": "true", + "range_level": "1", + "attack_level": "90" + }, + { + "examine": "But who's the daddy?", + "melee_animation": "5549", + "range_animation": "0", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "5555", + "name": "Mummy", + "defence_level": "90", + "safespot": null, + "lifepoints": "90", + "strength_level": "90", + "id": "1964", + "aggressive": "true", + "range_level": "1", + "attack_level": "90" + }, + { + "examine": "A tightly-wrapped monster.", + "melee_animation": "5549", + "range_animation": "0", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "5555", + "name": "Mummy", + "defence_level": "55", + "safespot": null, + "lifepoints": "78", + "strength_level": "55", + "id": "1965", + "range_level": "1", + "attack_level": "55" + }, + { + "examine": "A victim of poor first aid.", + "melee_animation": "5549", + "range_animation": "0", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "5555", + "name": "Mummy", + "defence_level": "55", + "safespot": null, + "lifepoints": "78", + "strength_level": "55", + "id": "1967", + "range_level": "1", + "attack_level": "55" + }, + { + "examine": "I think they're some kind of beetle...", + "melee_animation": "1948", + "range_animation": "0", + "attack_speed": "3", + "poisonous": "true", + "defence_animation": "1946", + "weakness": "7", + "magic_animation": "0", + "death_animation": "5464", + "name": "Scarabs", + "defence_level": "10", + "safespot": null, + "lifepoints": "25", + "strength_level": "2", + "id": "1969", + "range_level": "1", + "attack_level": "255" + }, + { + "examine": "A wandering merchant.", + "name": "Rasolo", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1972", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A giant skeleton.", + "melee_animation": "5499", + "range_animation": "0", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "5503", + "name": "Giant skeleton", + "defence_level": "60", + "safespot": null, + "lifepoints": "85", + "strength_level": "60", + "id": "1973", + "range_level": "1", + "attack_level": "60" + }, + { + "examine": "The warrior of darkness.", + "melee_animation": "440", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "0", + "magic_animation": "0", + "death_animation": "836", + "name": "Damis", + "defence_level": "90", + "safespot": null, + "lifepoints": "90", + "strength_level": "90", + "id": "1974", + "bonuses": "0,0,0,0,0,60,60,60,60,60,0,80,0,0,0", + "range_level": "1", + "attack_level": "90" + }, + { + "examine": "The warrior of darkness.", + "melee_animation": "440", + "range_animation": "0", + "attack_speed": "3", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "0", + "magic_animation": "0", + "death_animation": "836", + "name": "Damis", + "defence_level": "160", + "safespot": null, + "lifepoints": "200", + "strength_level": "100", + "id": "1975", + "bonuses": "0,0,0,0,0,100,100,100,80,120,0,100,0,0,0", + "range_level": "1", + "attack_level": "160" + }, + { + "examine": "Looks hungry!", + "melee_animation": "6565", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "6564", + "name": "Shadow Hound", + "defence_level": "48", + "safespot": null, + "lifepoints": "68", + "strength_level": "48", + "id": "1976", + "range_level": "1", + "attack_level": "48" + }, + { + "examine": "Zamorak's warrior of fire.", + "melee_animation": "799", + "magic_level": "100", + "respawn_delay": "60", + "defence_animation": "434", + "death_animation": "836", + "name": "Fareed", + "defence_level": "135", + "safespot": null, + "lifepoints": "130", + "strength_level": "120", + "id": "1977", + "aggressive": "true", + "bonuses": "0,0,0,0,0,100,100,100,0,0,0,120,0,0,0", + "range_level": "100", + "attack_level": "190" + }, + { + "examine": "A malnourished worker.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Slave", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1978", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A malnourished worker.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Slave", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1979", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A strange-smelling merchant.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Embalmer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1980", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A block of a man.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Carpenter", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1981", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Preach my brother!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Priest", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1988", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He has a dangerous glint in his eye.", + "combat_style": "2", + "melee_animation": "429", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "1", + "magic_animation": "0", + "death_animation": "836", + "name": "Possessed Priest", + "defence_level": "40", + "safespot": null, + "lifepoints": "57", + "strength_level": "30", + "id": "1991", + "aggressive": "true", + "range_level": "40", + "attack_level": "30" + }, + { + "melee_animation": "7588", + "combat_audio": "386,388,387", + "attack_speed": "6", + "respawn_delay": "60", + "defence_animation": "7590", + "slayer_exp": "62", + "death_animation": "7591", + "name": "Crocodile", + "defence_level": "1", + "safespot": null, + "lifepoints": "63", + "strength_level": "1", + "id": "1993", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He has had his day.", + "melee_animation": "6568", + "range_animation": "0", + "combat_audio": "544,546,545", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "50", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "6567", + "name": "Jackal", + "defence_level": "15", + "safespot": null, + "lifepoints": "27", + "strength_level": "18", + "id": "1994", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "17" + }, + { + "examine": "Obnoxious", + "melee_animation": "2015", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "2013", + "name": "Locust", + "defence_level": "12", + "safespot": null, + "lifepoints": "34", + "strength_level": "12", + "id": "1995", + "aggressive": "true", + "range_level": "1", + "attack_level": "12" + }, + { + "examine": "A very smelly frog.", + "melee_animation": "1021", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "1022", + "name": "Plague frog", + "defence_level": "15", + "safespot": null, + "lifepoints": "42", + "strength_level": "15", + "id": "1997", + "aggressive": "true", + "range_level": "1", + "attack_level": "15" + }, + { + "examine": "I might give the burgers a miss in this town.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "0", + "name": "Plague cow", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1998", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "I don't fancy eating any part of this.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "0", + "name": "Plague cow", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "1999", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "I think they're some kind of beetle.", + "melee_animation": "1948", + "range_animation": "0", + "attack_speed": "2", + "poisonous": "true", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "1946", + "name": "Scarab swarm", + "defence_level": "9", + "safespot": null, + "lifepoints": "900", + "strength_level": "9", + "id": "2001", + "aggressive": "true", + "range_level": "1", + "attack_level": "9" + }, + { + "examine": "This mummy looks like it means business!", + "melee_animation": "5554", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "5555", + "name": "Mummy", + "defence_level": "50", + "safespot": null, + "lifepoints": "71", + "strength_level": "50", + "id": "2015", + "aggressive": "true", + "range_level": "1", + "attack_level": "50" + }, + { + "examine": "An irate warrior-mummy.", + "melee_animation": "5554", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "5555", + "name": "Mummy", + "defence_level": "50", + "safespot": null, + "lifepoints": "71", + "strength_level": "50", + "id": "2016", + "aggressive": "true", + "range_level": "1", + "attack_level": "50" + }, + { + "examine": "This mummy looks like it means business!", + "melee_animation": "5554", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "5555", + "name": "Mummy", + "defence_level": "50", + "safespot": null, + "lifepoints": "71", + "strength_level": "50", + "id": "2017", + "aggressive": "true", + "range_level": "1", + "attack_level": "50" + }, + { + "examine": "An irate mummy.", + "melee_animation": "5554", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "5555", + "name": "Mummy", + "defence_level": "50", + "safespot": null, + "lifepoints": "71", + "strength_level": "50", + "id": "2018", + "aggressive": "true", + "range_level": "1", + "attack_level": "50" + }, + { + "examine": "A wizened old warrior.", + "melee_animation": "5554", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "5555", + "name": "Mummy", + "defence_level": "50", + "safespot": null, + "lifepoints": "71", + "strength_level": "50", + "id": "2019", + "aggressive": "true", + "range_level": "1", + "attack_level": "50" + }, + { + "examine": "A shimmering creature of blue light.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Light creature", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2021", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Wonder how long he's been here...", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Strange Old Man", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2024", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A vengeful spirit corrupted by dark magic.", + "start_gfx": "155", + "combat_style": "2", + "start_height": "96", + "melee_animation": "1162", + "range_animation": "1162", + "attack_speed": "5", + "magic_level": "100", + "end_gfx": "157", + "defence_animation": "420", + "weakness": "3", + "magic_animation": "1162", + "death_animation": "7197", + "name": "Ahrim the Blighted", + "defence_level": "100", + "safespot": null, + "lifepoints": "100", + "strength_level": "1", + "id": "2025", + "aggressive": "true", + "bonuses": "68,68,68,73,-19,103,85,117,73,0,0,68,0,49,0", + "range_level": "1", + "projectile": "156", + "attack_level": "1" + }, + { + "examine": "A vengeful spirit corrupted by dark magic.", + "melee_animation": "2066", + "range_animation": "2066", + "attack_speed": "7", + "magic_level": "1", + "respawn_delay": "0", + "defence_animation": "2063", + "weakness": "9", + "magic_animation": "2066", + "death_animation": "7197", + "name": "Dharok the Wretched", + "defence_level": "100", + "safespot": null, + "lifepoints": "100", + "strength_level": "100", + "id": "2026", + "aggressive": "true", + "bonuses": "105,105,105,-58,-18,252,250,244,-11,249,0,105,0,0,0", + "range_level": "1", + "attack_level": "100" + }, + { + "examine": "A vengeful spirit corrupted by dark magic.", + "melee_animation": "2080", + "range_animation": "2080", + "attack_speed": "5", + "magic_level": "1", + "respawn_delay": "0", + "defence_animation": "2079", + "weakness": "6", + "magic_animation": "2080", + "death_animation": "7197", + "name": "Guthan the Infested", + "defence_level": "100", + "safespot": null, + "lifepoints": "100", + "strength_level": "100", + "id": "2027", + "aggressive": "true", + "bonuses": "75,75,75,-50,-19,259,247,241,-11,-250,0,75,0,0,0", + "range_level": "1", + "attack_level": "100" + }, + { + "examine": "A vengeful spirit corrupted by dark magic.", + "combat_style": "1", + "melee_animation": "2075", + "range_animation": "2075", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "16", + "defence_animation": "424", + "weakness": "0", + "magic_animation": "2075", + "death_animation": "7197", + "name": "Karil the Tainted", + "defence_level": "100", + "safespot": null, + "lifepoints": "100", + "strength_level": "1", + "id": "2028", + "aggressive": "true", + "bonuses": "0,0,0,-26,134,79,71,90,106,100,0,0,0,0,61", + "range_level": "100", + "projectile": "27", + "attack_level": "1" + }, + { + "examine": "A vengeful spirit corrupted by dark magic.", + "melee_animation": "2068", + "range_animation": "2068", + "attack_speed": "5", + "magic_level": "1", + "respawn_delay": "0", + "defence_animation": "404", + "weakness": "7", + "magic_animation": "2068", + "death_animation": "7197", + "name": "Torag the Corrupted", + "defence_level": "100", + "safespot": null, + "lifepoints": "100", + "strength_level": "100", + "id": "2029", + "aggressive": "true", + "bonuses": "72,72,72,-33,-11,221,235,222,0,221,0,72,0,0,0", + "range_level": "1", + "attack_level": "100" + }, + { + "examine": "A vengeful spirit corrupted by dark magic.", + "melee_animation": "2062", + "range_animation": "2062", + "combat_audio": "", + "attack_speed": "5", + "magic_level": "1", + "defence_animation": "2063", + "weakness": "8", + "magic_animation": "2062", + "death_animation": "7197", + "name": "Verac the Defiled", + "defence_level": "100", + "safespot": null, + "lifepoints": "100", + "strength_level": "100", + "id": "2030", + "aggressive": "true", + "bonuses": "72,72,72,-42,-14,227,230,221,0,225,72,78,0,0,0", + "range_level": "1", + "attack_level": "100" + }, + { + "examine": "I think I should keep my distance...", + "melee_animation": "2070", + "range_animation": "2070", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "26", + "defence_animation": "2072", + "weakness": "6", + "magic_animation": "2070", + "death_animation": "2073", + "name": "Bloodworm", + "defence_level": "35", + "safespot": null, + "lifepoints": "45", + "strength_level": "20", + "id": "2031", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "80" + }, + { + "examine": "A nasty little rodent.", + "melee_animation": "240", + "range_animation": "240", + "combat_audio": "703,705,704", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "20", + "defence_animation": "241", + "weakness": "9", + "magic_animation": "240", + "death_animation": "243", + "name": "Crypt rat", + "defence_level": "20", + "safespot": null, + "lifepoints": "35", + "strength_level": "20", + "id": "2032", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "70" + }, + { + "examine": "A nasty overgrown rodent.", + "melee_animation": "4933", + "range_animation": "4933", + "combat_audio": "703,705,704", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "4934", + "weakness": "9", + "magic_animation": "4933", + "death_animation": "4935", + "name": "Giant crypt rat", + "defence_level": "65", + "safespot": null, + "lifepoints": "70", + "strength_level": "50", + "id": "2033", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "80" + }, + { + "examine": "Incey wincey.", + "melee_animation": "6249", + "range_animation": "6249", + "combat_audio": "537,539,538", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "25", + "defence_animation": "6250", + "weakness": "7", + "magic_animation": "6249", + "death_animation": "6251", + "name": "Crypt spider", + "defence_level": "45", + "safespot": null, + "lifepoints": "45", + "strength_level": "47", + "id": "2034", + "aggressive": "true", + "bonuses": "0,0,0,0,0,20,20,10,17,20,0,0,0,0,0", + "range_level": "1", + "attack_level": "45" + }, + { + "examine": "Not very incey wincey.", + "melee_animation": "5327", + "range_animation": "5327", + "combat_audio": "537,539,538", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "35", + "defence_animation": "5328", + "weakness": "7", + "magic_animation": "5327", + "death_animation": "5329", + "name": "Giant crypt spider", + "defence_level": "65", + "safespot": null, + "lifepoints": "80", + "strength_level": "67", + "id": "2035", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "65" + }, + { + "examine": "A partially decomposing zombie ogre.", + "combat_audio": "", + "melee_animation": "359", + "range_animation": "359", + "attack_speed": "6", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "360", + "slayer_exp": "", + "weakness": "7", + "magic_animation": "359", + "death_animation": "361", + "name": "Zogre", + "defence_level": "35", + "safespot": null, + "lifepoints": "71", + "strength_level": "36", + "id": "2044", + "aggressive": "true", + "range_level": "1", + "attack_level": "20" + }, + { + "examine": "A partially decomposing zombie ogre.", + "melee_animation": "359", + "range_animation": "359", + "attack_speed": "6", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "360", + "slayer_exp": "", + "weakness": "7", + "magic_animation": "359", + "death_animation": "361", + "name": "Zogre", + "defence_level": "35", + "safespot": null, + "lifepoints": "71", + "strength_level": "36", + "id": "2045", + "aggressive": "true", + "range_level": "1", + "attack_level": "20" + }, + { + "examine": "A partially decomposing zombie ogre.", + "melee_animation": "359", + "range_animation": "359", + "attack_speed": "6", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "360", + "slayer_exp": "", + "weakness": "7", + "magic_animation": "359", + "death_animation": "361", + "name": "Zogre", + "defence_level": "35", + "safespot": null, + "lifepoints": "71", + "strength_level": "36", + "id": "2046", + "aggressive": "true", + "range_level": "1", + "attack_level": "20" + }, + { + "examine": "A partially decomposing zombie ogre.", + "melee_animation": "359", + "range_animation": "359", + "attack_speed": "6", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "360", + "slayer_exp": "", + "weakness": "7", + "magic_animation": "359", + "death_animation": "361", + "name": "Zogre", + "defence_level": "35", + "safespot": null, + "lifepoints": "71", + "strength_level": "36", + "id": "2047", + "aggressive": "true", + "range_level": "1", + "attack_level": "20" + }, + { + "examine": "A partially decomposing zombie ogre.", + "melee_animation": "359", + "range_animation": "359", + "attack_speed": "6", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "360", + "slayer_exp": "", + "weakness": "7", + "magic_animation": "359", + "death_animation": "361", + "name": "Zogre", + "defence_level": "35", + "safespot": null, + "lifepoints": "71", + "strength_level": "36", + "id": "2048", + "aggressive": "true", + "range_level": "1", + "attack_level": "20" + }, + { + "examine": "A partially decomposing zombie ogre.", + "melee_animation": "359", + "range_animation": "359", + "attack_speed": "6", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "360", + "slayer_exp": "", + "weakness": "7", + "magic_animation": "359", + "death_animation": "361", + "name": "Zogre", + "defence_level": "35", + "safespot": null, + "lifepoints": "71", + "strength_level": "36", + "id": "2049", + "aggressive": "true", + "range_level": "1", + "attack_level": "20" + }, + { + "examine": "It's falling apart!", + "combat_audio": "", + "range_animation": "359", + "melee_animation": "359", + "attack_speed": "6", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "360", + "weakness": "7", + "slayer_exp": "", + "magic_animation": "359", + "death_animation": "361", + "name": "Skogre", + "defence_level": "35", + "safespot": null, + "lifepoints": "71", + "strength_level": "36", + "id": "2050", + "aggressive": "true", + "range_level": "1", + "attack_level": "20" + }, + { + "examine": "A partially decomposing zombie ogre.", + "melee_animation": "359", + "range_animation": "359", + "attack_speed": "6", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "360", + "slayer_exp": "", + "weakness": "7", + "magic_animation": "359", + "death_animation": "361", + "name": "Zogre", + "defence_level": "35", + "safespot": null, + "lifepoints": "71", + "strength_level": "36", + "id": "2051", + "aggressive": "true", + "range_level": "1", + "attack_level": "20" + }, + { + "examine": "A partially decomposing zombie ogre.", + "melee_animation": "359", + "range_animation": "359", + "attack_speed": "6", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "360", + "slayer_exp": "", + "weakness": "7", + "magic_animation": "359", + "death_animation": "361", + "name": "Zogre", + "defence_level": "35", + "safespot": null, + "lifepoints": "71", + "strength_level": "36", + "id": "2052", + "aggressive": "true", + "range_level": "1", + "attack_level": "20" + }, + { + "examine": "A partially decomposing zombie ogre.", + "melee_animation": "359", + "range_animation": "359", + "attack_speed": "6", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "360", + "slayer_exp": "", + "weakness": "7", + "magic_animation": "359", + "death_animation": "361", + "name": "Zogre", + "defence_level": "35", + "safespot": null, + "lifepoints": "71", + "strength_level": "36", + "id": "2053", + "aggressive": "true", + "range_level": "1", + "attack_level": "20" + }, + { + "examine": "A partially decomposing zombie ogre.", + "melee_animation": "359", + "range_animation": "359", + "attack_speed": "6", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "360", + "slayer_exp": "", + "weakness": "7", + "magic_animation": "359", + "death_animation": "361", + "name": "Zogre", + "defence_level": "35", + "safespot": null, + "lifepoints": "71", + "strength_level": "36", + "id": "2054", + "aggressive": "true", + "range_level": "1", + "attack_level": "20" + }, + { + "examine": "A partially decomposing zombie ogre.", + "melee_animation": "359", + "range_animation": "359", + "attack_speed": "6", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "360", + "slayer_exp": "", + "weakness": "7", + "magic_animation": "359", + "death_animation": "361", + "name": "Zogre", + "defence_level": "35", + "safespot": null, + "lifepoints": "71", + "strength_level": "36", + "id": "2055", + "aggressive": "true", + "range_level": "1", + "attack_level": "20" + }, + { + "examine": "It's falling apart!", + "combat_audio": "", + "melee_animation": "359", + "range_animation": "359", + "attack_speed": "6", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "360", + "slayer_exp": "", + "weakness": "7", + "magic_animation": "359", + "death_animation": "361", + "name": "Skogre", + "defence_level": "35", + "safespot": null, + "lifepoints": "71", + "strength_level": "36", + "id": "2056", + "aggressive": "true", + "range_level": "1", + "attack_level": "20" + }, + { + "examine": "It's falling apart!", + "combat_audio": "", + "range_animation": "359", + "melee_animation": "359", + "attack_speed": "6", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "360", + "slayer_exp": "", + "weakness": "7", + "magic_animation": "359", + "death_animation": "361", + "name": "Skogre", + "defence_level": "35", + "safespot": null, + "lifepoints": "71", + "strength_level": "36", + "id": "2057", + "aggressive": "true", + "range_level": "1", + "attack_level": "20" + }, + { + "examine": "What could be hiding in that crack in the wall?", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "931,923,922", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "slayer_exp": "30", + "magic_animation": "0", + "death_animation": "0", + "name": "Hole in the wall", + "defence_level": "1", + "safespot": null, + "lifepoints": "60", + "strength_level": "1", + "id": "2058", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A partially decomposing zombie ogre.", + "slayer_task": "64", + "combat_audio": "", + "melee_animation": "359", + "range_animation": "359", + "attack_speed": "6", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "360", + "slayer_exp": "", + "weakness": "7", + "magic_animation": "359", + "death_animation": "361", + "name": "Slash Bash", + "defence_level": "60", + "safespot": null, + "lifepoints": "100", + "strength_level": "120", + "id": "2060", + "aggressive": "true", + "range_level": "100", + "attack_level": "100" + }, + { + "examine": "I can see fish swimming in the water.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fishing spot", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2067", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "This one is slacking off.", + "melee_animation": "6007", + "range_animation": "0", + "combat_audio": "469,472,471", + "defence_animation": "6008", + "weakness": "6", + "magic_animation": "0", + "death_animation": "6003", + "name": "Cave goblin miner", + "defence_level": "5", + "safespot": null, + "lifepoints": "7", + "strength_level": "5", + "id": "2069", + "range_level": "1", + "attack_level": "5" + }, + { + "examine": "This one is slacking off.", + "melee_animation": "6007", + "range_animation": "0", + "combat_audio": "469,472,471", + "defence_animation": "6008", + "weakness": "6", + "magic_animation": "0", + "death_animation": "6003", + "name": "Cave goblin miner", + "defence_level": "5", + "safespot": null, + "lifepoints": "7", + "strength_level": "5", + "id": "2070", + "range_level": "1", + "attack_level": "5" + }, + { + "examine": "This one is slacking off.", + "melee_animation": "6007", + "range_animation": "0", + "combat_audio": "469,472,471", + "defence_animation": "6008", + "weakness": "6", + "magic_animation": "0", + "death_animation": "6003", + "name": "Cave goblin miner", + "defence_level": "5", + "safespot": null, + "lifepoints": "7", + "strength_level": "5", + "id": "2071", + "range_level": "1", + "attack_level": "5" + }, + { + "examine": "This one is slacking off.", + "melee_animation": "6007", + "range_animation": "0", + "combat_audio": "469,472,471", + "defence_animation": "6008", + "weakness": "6", + "magic_animation": "0", + "death_animation": "6003", + "name": "Cave goblin miner", + "defence_level": "5", + "safespot": null, + "lifepoints": "7", + "strength_level": "5", + "id": "2072", + "range_level": "1", + "attack_level": "5" + }, + { + "examine": "He protects the miners.", + "melee_animation": "6007", + "range_animation": "0", + "combat_audio": "469,472,471", + "respawn_delay": "60", + "defence_animation": "6008", + "weakness": "6", + "magic_animation": "0", + "death_animation": "6003", + "name": "Cave goblin guard", + "defence_level": "15", + "safespot": null, + "lifepoints": "21", + "strength_level": "15", + "id": "2073", + "range_level": "1", + "attack_level": "15" + }, + { + "examine": "He protects the miners.", + "melee_animation": "6007", + "range_animation": "0", + "combat_audio": "469,472,471", + "respawn_delay": "60", + "defence_animation": "6008", + "weakness": "6", + "magic_animation": "0", + "death_animation": "6003", + "name": "Cave goblin guard", + "defence_level": "15", + "safespot": null, + "lifepoints": "21", + "strength_level": "15", + "id": "2074", + "range_level": "1", + "attack_level": "15" + }, + { + "examine": "He's working hard!", + "melee_animation": "6007", + "combat_audio": "469,472,471", + "defence_animation": "6008", + "death_animation": "6003", + "name": "Cave goblin miner", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2075", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He's working hard!", + "melee_animation": "6007", + "combat_audio": "469,472,471", + "defence_animation": "6008", + "death_animation": "6003", + "name": "Cave goblin miner", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2076", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He's working hard!", + "melee_animation": "6007", + "combat_audio": "469,472,471", + "defence_animation": "6008", + "death_animation": "6003", + "name": "Cave goblin miner", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2077", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He's working hard!", + "melee_animation": "6007", + "combat_audio": "469,472,471", + "defence_animation": "6008", + "death_animation": "6003", + "name": "Cave goblin miner", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2078", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Advisor to the Duke of Lumbridge.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Sigmund", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2082", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "5327", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "5328", + "death_animation": "5329", + "name": "Secretary", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2091", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The head secretary of the Purple Pewter mining company.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Purple Pewter Secretary", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2092", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The head secretary of the Yellow Fortune mining company.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Yellow Fortune Secretary", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2093", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The head secretary of the Blue Opal mining company.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Blue Opal Secretary", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2094", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The head secretary of the Green Gemstone mining company.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Green Gemstone Secretary", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2095", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The head secretary of the White Chisel mining company.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "White Chisel Secretary", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2096", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The head secretary of the Silver Cog mining company.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Silver Cog Secretary", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2097", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The head secretary of the Brown Engine mining company.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Brown Engine Secretary", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2098", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of the leaders of the business Consortium", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Purple Pewter Director", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2100", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of the leaders of the business Consortium", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Blue Opal Director", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2101", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of the leaders of the business Consortium", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Yellow Fortune Director", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2102", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of the leaders of the business Consortium", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Green Gemstone Director", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2103", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of the leaders of the business Consortium", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "White Chisel Director", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2104", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of the leaders of the business Consortium", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Silver Cog Director", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2105", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of the leaders of the business Consortium", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Brown Engine Director", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2106", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A trader for the Purple Pewter mining company.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Trader", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2109", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A trader for the Purple Pewter mining company.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Trader", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2110", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A trader for the Blue Opal mining company.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Trader", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2111", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A trader for the Blue Opal mining company.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Trader", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2112", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A trader for the Yellow Fortune mining company.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Trader", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2113", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A trader for the Yellow Fortune mining company.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Trader", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2114", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A trader for the Green Gemstone mining company.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Trader", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2115", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A trader for the Green Gemstone mining company.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Trader", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2116", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A trader for the White Chisel mining company.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Trader", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2117", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A trader for the White Chisel mining company.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Trader", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2118", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A trader for the Silver Cog mining company.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Trader", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2119", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A trader for the Silver Cog mining company.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Trader", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2120", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A trader for the Brown Engine mining company.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Trader", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2121", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A trader for the Brown Engine mining company.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Trader", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2122", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He is regulating the flow of goods on the trade floor and maintaining order.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Trade Referee", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2127", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A member of the Black Guard", + "melee_animation": "99", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "slayer_exp": "16", + "magic_animation": "0", + "death_animation": "102", + "name": "Black Guard", + "defence_level": "34", + "safespot": null, + "lifepoints": "48", + "strength_level": "34", + "id": "2130", + "range_level": "1", + "attack_level": "34" + }, + { + "examine": "A member of the Black Guard", + "melee_animation": "99", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "slayer_exp": "16", + "magic_animation": "0", + "death_animation": "102", + "name": "Black Guard", + "defence_level": "34", + "safespot": null, + "lifepoints": "48", + "strength_level": "34", + "id": "2131", + "range_level": "1", + "attack_level": "34" + }, + { + "examine": "A member of the Black Guard", + "melee_animation": "99", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "slayer_exp": "16", + "magic_animation": "0", + "death_animation": "102", + "name": "Black Guard", + "defence_level": "34", + "safespot": null, + "lifepoints": "48", + "strength_level": "34", + "id": "2132", + "range_level": "1", + "attack_level": "34" + }, + { + "examine": "A member of the Black Guard", + "melee_animation": "99", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "slayer_exp": "16", + "magic_animation": "0", + "death_animation": "102", + "name": "Black Guard", + "defence_level": "34", + "safespot": null, + "lifepoints": "48", + "strength_level": "34", + "id": "2133", + "range_level": "1", + "attack_level": "34" + }, + { + "examine": "An elite member of the Black Guard.", + "melee_animation": "99", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "102", + "name": "Black Guard Berserker", + "defence_level": "38", + "safespot": null, + "lifepoints": "54", + "strength_level": "38", + "id": "2134", + "range_level": "1", + "attack_level": "38" + }, + { + "examine": "An elite member of the Black Guard.", + "melee_animation": "99", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "102", + "name": "Black Guard Berserker", + "defence_level": "38", + "safespot": null, + "lifepoints": "54", + "strength_level": "38", + "id": "2135", + "range_level": "1", + "attack_level": "38" + }, + { + "examine": "An elite member of the Black Guard.", + "melee_animation": "99", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "102", + "name": "Black Guard Berserker", + "defence_level": "38", + "safespot": null, + "lifepoints": "54", + "strength_level": "38", + "id": "2136", + "range_level": "1", + "attack_level": "38" + }, + { + "examine": "A gnome traveller, visiting Keldagrim.", + "name": "Gnome traveller", + "defence_level": "1", + "force_talk": "", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2138", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A gnome traveller, visiting Keldagrim.", + "name": "Gnome traveller", + "defence_level": "1", + "force_talk": "", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2139", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Very protective of his master... and his property.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Dromund's cat", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2140", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Makes sculptures.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Blasidar the sculptor", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2141", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Proprietor of Gunslik's Assorted Items.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Gunslik", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2154", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An old mining dwarf, now he sells pickaxes and generally acts grumpy.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Tati", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2160", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A rather personable banker lady.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Banker", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2163", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A rather serious old fella.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Banker", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2164", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He takes care of the library and its many books.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Librarian", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2165", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A customer looking for books.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Customer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2167", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Looks like a human traveler visiting the library.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Customer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2168", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He tends to the plants in the palace garden.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Rind the gardener", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2170", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Looks after the factory.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Factory Manager", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2171", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Works hard at whatever it is he does.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Factory Worker", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2172", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Works hard at whatever it is he does.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Factory Worker", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2173", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Works hard at whatever it is he does.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Factory Worker", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2174", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Works hard at whatever it is he does.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Factory Worker", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2175", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "These Dwarf ladies are so attractive!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Barmaid", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2178", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He makes sure the carts don't run anyone over.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cart conductor", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2180", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He makes sure the carts don't run anyone over.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cart conductor", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2181", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He makes sure the carts don't run anyone over.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cart conductor", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2182", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He makes sure the carts don't run anyone over.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cart conductor", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2183", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He makes sure the carts don't run anyone over.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cart conductor", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2184", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Remember: don't drink and ride in mine carts.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cart conductor", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2185", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Keeps the line clear of traffic.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cart conductor", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2186", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A loud, drunk and generally obnoxious dwarf.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Rowdy dwarf", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2187", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A sad old dwarf living in a sad old home.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Runvastr", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2190", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He seems to always be busy.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Sune", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2191", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "This dwarf doesn't seem to be very well off.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Bentamir", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2192", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A dwarf minding his own business.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ulifed", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2193", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A short, merry guy.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Karl", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2195", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "His kebabs certainly smell delicious.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Kjut", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2198", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He seems to be very well off.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Audmann", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2201", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He's had a fair bit to drink...", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Drunken Dwarf", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2202", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He's had a fair bit to drink...", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Drunken Dwarf", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2203", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "You cannot see his ship, but presumably he has one.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Dwarven Boatman", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2205", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "You cannot see his ship, but presumably he has one.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Dwarven Boatman", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2206", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He carries a heavy load.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Dwarven Miner", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2207", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An elite member of the Black Guard.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Black Guard Berserker", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2232", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A master at farming.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Master Farmer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2234", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A master at farming.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Master Farmer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2235", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He guards the Draynor Market stalls from thieves.", + "melee_animation": "390", + "range_animation": "0", + "combat_audio": "2547,1979,512", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "836", + "name": "Market Guard", + "defence_level": "30", + "safespot": null, + "lifepoints": "42", + "strength_level": "30", + "id": "2236", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "A local farmer. He may be able to provide some useful information.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Gee", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2237", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "There to help me make my bids.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Pig", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2240", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "There to help me make my bids.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Piglet", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2241", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Porcine.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Piglet", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2242", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He provides new players with useful information.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Lumbridge Guide", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2244", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It's one of General Khazard's warriors.", + "melee_animation": "401", + "attack_speed": "6", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Khazard trooper", + "defence_level": "1", + "safespot": null, + "lifepoints": "22", + "strength_level": "1", + "id": "2245", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It's one of General Khazard's warriors.", + "melee_animation": "429", + "range_animation": "0", + "attack_speed": "6", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "836", + "name": "Khazard trooper", + "defence_level": "32", + "safespot": null, + "lifepoints": "45", + "strength_level": "32", + "id": "2246", + "range_level": "1", + "attack_level": "32" + }, + { + "examine": "It's a tree gnome trooper.", + "combat_style": "1", + "melee_animation": "190", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "193", + "death_animation": "196", + "name": "Gnome troop", + "defence_level": "1", + "safespot": null, + "lifepoints": "3", + "strength_level": "1", + "id": "2247", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It's a tree gnome trooper.", + "combat_style": "1", + "melee_animation": "190", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "193", + "death_animation": "196", + "name": "Gnome troop", + "defence_level": "1", + "safespot": null, + "lifepoints": "3", + "strength_level": "1", + "id": "2248", + "range_level": "1", + "attack_level": "1" + }, + { + "combat_audio": "511,513,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Paladin", + "defence_level": "1", + "safespot": null, + "lifepoints": "66", + "strength_level": "1", + "id": "2256", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An initiate of Zamorak.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Dark mage", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2262", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A blood-drinking denizen of the abyss.", + "melee_animation": "2181", + "range_animation": "0", + "combat_audio": "232,231,230", + "attack_speed": "3", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "2", + "slayer_exp": "0", + "magic_animation": "0", + "death_animation": "2183", + "name": "Abyssal leech", + "defence_level": "52", + "safespot": null, + "lifepoints": "74", + "strength_level": "1", + "id": "2263", + "aggressive": "true", + "range_level": "52", + "attack_level": "1" + }, + { + "examine": "It seems to have eyes in the back of its head...", + "melee_animation": "2186", + "range_animation": "2186", + "attack_speed": "6", + "magic_level": "57", + "defence_animation": "2188", + "weakness": "3", + "slayer_exp": "0", + "magic_animation": "2186", + "death_animation": "2189", + "name": "Abyssal guardian", + "defence_level": "65", + "safespot": null, + "lifepoints": "50", + "strength_level": "96", + "id": "2264", + "aggressive": "true", + "range_level": "135", + "attack_level": "65" + }, + { + "examine": "Apparently walks the abyss.", + "melee_animation": "2192", + "range_animation": "2192", + "combat_audio": "233,235,234", + "attack_speed": "5", + "defence_animation": "2193", + "weakness": "8", + "slayer_exp": "0", + "magic_animation": "2192", + "death_animation": "2194", + "name": "Abyssal walker", + "defence_level": "55", + "safespot": null, + "lifepoints": "95", + "strength_level": "116", + "id": "2265", + "aggressive": "true", + "range_level": "1", + "attack_level": "60" + }, + { + "examine": "Sparkles the Tinsel Snake", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Rogue Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2267", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A snowman armed with a holly bow.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Rogue Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2269", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A snowman armed with an ice sword.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Emerald Benedict", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2271", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A snowman armed with a winter staff.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Spin Blades", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2272", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "2", + "id": "2274", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "2", + "id": "2275", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "2", + "id": "2276", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "2", + "id": "2277", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "2", + "id": "2278", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "2", + "id": "2279", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "2", + "id": "2280", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "2", + "id": "2281", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An observer for the Temple Knights.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Sir Spishyus", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2282", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An observer for the Temple Knights.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Lady Table", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2283", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An observer for the Temple Knights.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Sir Kuam Ferentse", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2284", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A warrior blessed by Saradomin.", + "melee_animation": "400", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Sir Leye", + "defence_level": "15", + "safespot": null, + "lifepoints": "21", + "strength_level": "18", + "id": "2285", + "aggressive": "true", + "range_level": "1", + "attack_level": "18" + }, + { + "examine": "An observer for the Temple Knights.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Sir Tinley", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2286", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An observer for the Temple Knights.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Sir Ren Itchood", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2287", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An observer for the Temple Knights.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Miss Cheevers", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2288", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An observer for the Temple Knights.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ms. Hynn Terprett", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2289", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Head of recruitment for the Temple Knights.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Sir Tiffy Cashien", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2290", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A carpet merchant.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Rug Merchant", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2291", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A carpet merchant.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Rug Merchant", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2292", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A man who deals in rugs.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Rug Merchant", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2293", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A man who deals in rugs.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Rug Merchant", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2294", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Perhaps our oldest relatives.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "629,631,630", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2301", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Young, but still beefy.", + "melee_animation": "5849", + "range_animation": "5849", + "combat_audio": "366,368,367", + "attack_speed": "5", + "defence_animation": "5850", + "weakness": "8", + "slayer_exp": "8", + "magic_animation": "5849", + "death_animation": "5851", + "name": "Cow calf", + "defence_level": "2", + "safespot": null, + "lifepoints": "6", + "strength_level": "2", + "id": "2310", + "range_level": "1", + "attack_level": "2" + }, + { + "examine": "Farmer/sheep liaison officer. Go on - give the dog a bone!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Sheepdog", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2311", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He rules the", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Rooster", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2312", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Yep. Definitely a chicken.", + "melee_animation": "5387", + "range_animation": "5387", + "combat_audio": "355,357,356", + "attack_speed": "6", + "respawn_delay": "18", + "defence_animation": "5388", + "magic_animation": "5387", + "death_animation": "5389", + "name": "Chicken", + "defence_level": "1", + "safespot": null, + "lifepoints": "3", + "strength_level": "1", + "id": "2313", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Yep. Definitely a chicken.", + "melee_animation": "5387", + "range_animation": "5387", + "combat_audio": "355,357,356", + "attack_speed": "6", + "respawn_delay": "18", + "defence_animation": "5388", + "magic_animation": "5387", + "death_animation": "5389", + "name": "Chicken", + "defence_level": "1", + "safespot": null, + "lifepoints": "3", + "strength_level": "1", + "id": "2314", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Yep. Definitely a chicken.", + "melee_animation": "5387", + "range_animation": "5387", + "combat_audio": "355,357,356", + "attack_speed": "6", + "respawn_delay": "18", + "defence_animation": "5388", + "magic_animation": "5387", + "death_animation": "5389", + "name": "Chicken", + "defence_level": "1", + "safespot": null, + "lifepoints": "3", + "strength_level": "1", + "id": "2315", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Swine.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Pig", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2316", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Porker.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Pig", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2317", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Hog.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Piglet", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2318", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Porcine.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Piglet", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2319", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He has a certain bovine aroma.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Piglet", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2320", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An expert on the brewing of ales and cider.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Blandebir", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2321", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Only the Grim Reaper would have a pet like this.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Muncher", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2329", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Perhaps this farmer might look after your crops for you.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Vasquen", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2333", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Perhaps this gardener might look after your crops for you.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Taria", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2336", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Perhaps this gardener might look after your crops for you.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fayeth", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2342", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He can look after my money.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Banker", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2354", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "She can look after my money.", + "combat_style": "2", + "melee_animation": "0", + "range_animation": "0", + "respawn_delay": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Banker", + "defence_level": "1", + "safespot": null, + "lifepoints": "476", + "strength_level": "1", + "id": "2355", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "I don't wanna be at the wrong end of that pike.", + "melee_animation": "428", + "range_animation": "0", + "combat_audio": "425,427,426", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Elf warrior", + "defence_level": "60", + "safespot": null, + "lifepoints": "85", + "strength_level": "60", + "id": "2359", + "clue_level": "2", + "range_level": "1", + "attack_level": "60" + }, + { + "examine": "I don't wanna be at the wrong end of that pike.", + "melee_animation": "428", + "range_animation": "0", + "combat_audio": "425,427,426", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Elf warrior", + "defence_level": "60", + "safespot": null, + "lifepoints": "85", + "strength_level": "60", + "id": "2360", + "clue_level": "2", + "range_level": "1", + "attack_level": "60" + }, + { + "examine": "He looks pretty handy with that bow.", + "start_gfx": "250", + "combat_style": "1", + "melee_animation": "428", + "range_animation": "426", + "combat_audio": "425,427,426", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "2", + "magic_animation": "0", + "death_animation": "836", + "name": "Elf warrior", + "defence_level": "64", + "safespot": null, + "lifepoints": "91", + "strength_level": "1", + "id": "2361", + "clue_level": "2", + "range_level": "64", + "projectile": "249", + "attack_level": "1" + }, + { + "examine": "He looks pretty handy with that bow.", + "start_gfx": "250", + "combat_style": "1", + "melee_animation": "428", + "range_animation": "426", + "combat_audio": "425,427,426", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "2", + "magic_animation": "0", + "death_animation": "836", + "name": "Elf warrior", + "defence_level": "64", + "safespot": null, + "lifepoints": "91", + "strength_level": "1", + "id": "2362", + "clue_level": "2", + "range_level": "64", + "projectile": "249", + "attack_level": "1" + }, + { + "examine": "A Mourner showing his true identity.", + "melee_animation": "", + "range_animation": "", + "defence_animation": "", + "magic_animation": "", + "death_animation": "", + "name": "Head mourner", + "defence_level": "", + "safespot": null, + "lifepoints": "", + "strength_level": "", + "id": "2372", + "range_level": "", + "attack_level": "" + }, + { + "examine": "A mourner, or plague healer.", + "melee_animation": "428", + "range_animation": "", + "attack_speed": "4", + "defence_animation": "", + "weakness": "", + "magic_animation": "", + "death_animation": "836", + "name": "Mourner", + "defence_level": "80", + "safespot": null, + "lifepoints": "87", + "strength_level": "61", + "id": "2373", + "aggressive": "true", + "range_level": "", + "attack_level": "61" + }, + { + "examine": "Seems to flitter in and out of existence...", + "name": "Mysterious ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "436,439,438", + "strength_level": "1", + "id": "2381", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Seems to flitter in and out of existence...", + "name": "Mysterious ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "436,439,438", + "strength_level": "1", + "id": "2382", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Seems to flitter in and out of existence...", + "name": "Mysterious ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "436,439,438", + "strength_level": "1", + "id": "2383", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Seems to flitter in and out of existence...", + "name": "Mysterious ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "436,439,438", + "strength_level": "1", + "id": "2384", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Seems to flitter in and out of existence...", + "name": "Mysterious ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "436,439,438", + "strength_level": "1", + "id": "2385", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Seems to flitter in and out of existence...", + "name": "Mysterious ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "436,439,438", + "strength_level": "1", + "id": "2386", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Seems to flitter in and out of existence...", + "name": "Mysterious ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "436,439,438", + "strength_level": "1", + "id": "2387", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Seems to flitter in and out of existence...", + "name": "Mysterious ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "436,439,438", + "strength_level": "1", + "id": "2388", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Seems to flitter in and out of existence...", + "name": "Mysterious ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "436,439,438", + "strength_level": "1", + "id": "2389", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Seems to flitter in and out of existence...", + "name": "Mysterious ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "436,439,438", + "strength_level": "1", + "id": "2390", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Seems to flitter in and out of existence...", + "name": "Mysterious ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "436,439,438", + "strength_level": "1", + "id": "2391", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Seems to flitter in and out of existence...", + "name": "Mysterious ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "436,439,438", + "strength_level": "1", + "id": "2392", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Seems to flitter in and out of existence...", + "name": "Mysterious ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "436,439,438", + "strength_level": "1", + "id": "2393", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Seems to flitter in and out of existence...", + "name": "Mysterious ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "436,439,438", + "strength_level": "1", + "id": "2394", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Seems to flitter in and out of existence...", + "name": "Mysterious ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "436,439,438", + "strength_level": "1", + "id": "2395", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Seems to flitter in and out of existence...", + "name": "Mysterious ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "436,439,438", + "strength_level": "1", + "id": "2396", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Seems to flitter in and out of existence...", + "name": "Mysterious ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "436,439,438", + "strength_level": "1", + "id": "2397", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Seems to flitter in and out of existence...", + "name": "Mysterious ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "436,439,438", + "strength_level": "1", + "id": "2398", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Seems to flitter in and out of existence...", + "name": "Mysterious ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "436,439,438", + "strength_level": "1", + "id": "2399", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Seems to flitter in and out of existence...", + "name": "Mysterious ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "436,439,438", + "strength_level": "1", + "id": "2400", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Seems to flitter in and out of existence...", + "name": "Mysterious ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "436,439,438", + "strength_level": "1", + "id": "2401", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Seems to flitter in and out of existence...", + "name": "Mysterious ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "436,439,438", + "strength_level": "1", + "id": "2402", + "range_level": "1", + "attack_level": "1" + }, + { + "slayer_exp": "61", + "weakness": "6", + "examine": "A dwarf gone bad.", + "name": "Chaos dwarf", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2423", + "respawn_delay": "150", + "range_level": "1", + "attack_level": "1" + }, + { + "death_animation": "9230", + "name": "Jarvald", + "defence_level": "10", + "safespot": null, + "lifepoints": "10", + "melee_animation": "9232", + "strength_level": "10", + "id": "2436", + "range_level": "1", + "attack_level": "10", + "defence_animation": "9231" + }, + { + "examine": "Looks like a wanna be Fremennik.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Askeladden", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2439", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "This support is propping the door closed.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Door-support", + "defence_level": "1", + "safespot": null, + "lifepoints": "0", + "strength_level": "1", + "id": "2443", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "No one likes crabs... especially really big ones!", + "melee_animation": "2368", + "range_animation": "0", + "combat_audio": "717,723,722", + "attack_speed": "4", + "respawn_delay": "50", + "defence_animation": "1313", + "weakness": "9", + "magic_animation": "0", + "death_animation": "1314", + "name": "Giant Rock Crab", + "defence_level": "200", + "safespot": null, + "lifepoints": "180", + "strength_level": "80", + "id": "2452", + "aggressive": "true", + "bonuses": "0,0,0,0,0,225,200,175,-10,250,0,0,0,0,0", + "range_level": "1", + "attack_level": "50" + }, + { + "examine": "Heavy rock!", + "melee_animation": "0", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Boulder", + "defence_level": "1", + "safespot": null, + "lifepoints": "240", + "strength_level": "1", + "id": "2453", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A teeny-tiny horror from the ocean depths...", + "melee_animation": "1341", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "1342", + "name": "Dagannoth spawn", + "defence_level": "47", + "safespot": null, + "lifepoints": "67", + "strength_level": "47", + "id": "2454", + "aggressive": "true", + "range_level": "1", + "attack_level": "47" + }, + { + "examine": "A horror from the ocean depths...", + "melee_animation": "1343", + "attack_speed": "4", + "respawn_delay": "60", + "defence_animation": "1340", + "slayer_exp": "120", + "death_animation": "1342", + "name": "Dagannoth", + "defence_level": "71", + "safespot": null, + "lifepoints": "120", + "strength_level": "70", + "id": "2455", + "aggressive": "true", + "clue_level": "1", + "range_level": "1", + "projectile": "294", + "attack_level": "68" + }, + { + "examine": "A horror from the ocean depths...", + "combat_style": "1", + "melee_animation": "1343", + "attack_speed": "4", + "respawn_delay": "60", + "defence_animation": "1340", + "slayer_exp": "0", + "death_animation": "1342", + "name": "Dagannoth", + "defence_level": "50", + "safespot": null, + "lifepoints": "70", + "strength_level": "70", + "id": "2456", + "aggressive": "true", + "clue_level": "1", + "range_level": "70", + "projectile": "294", + "attack_level": "68" + }, + { + "examine": "A fearsome magical creature from the deep.", + "combat_style": "2", + "melee_animation": "2365", + "combat_audio": "1077,1079,1078", + "attack_speed": "6", + "spell_id": "48", + "magic_level": "100", + "respawn_delay": "60", + "defence_animation": "2366", + "magic_animation": "2365", + "death_animation": "2367", + "name": "Wallasalki", + "defence_level": "80", + "safespot": null, + "lifepoints": "120", + "strength_level": "1", + "id": "2457", + "aggressive": "true", + "bonuses": "0,0,0,0,0,100,150,175,250,-10,0,0,0,0,0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A brightly coloured game bird.", + "melee_animation": "2372", + "range_animation": "2372", + "combat_audio": "690,692,691", + "attack_speed": "6", + "respawn_delay": "18", + "defence_animation": "2371", + "magic_animation": "2372", + "death_animation": "2373", + "name": "Pheasant", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "1", + "id": "2459", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A brightly coloured game bird.", + "melee_animation": "2372", + "range_animation": "2372", + "combat_audio": "690,692,691", + "attack_speed": "6", + "respawn_delay": "18", + "defence_animation": "2371", + "magic_animation": "2372", + "death_animation": "2373", + "name": "Pheasant", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "1", + "id": "2460", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A brightly coloured game bird.", + "melee_animation": "2372", + "range_animation": "2372", + "combat_audio": "690,692,691", + "attack_speed": "6", + "respawn_delay": "18", + "defence_animation": "2371", + "magic_animation": "2372", + "death_animation": "2373", + "name": "Pheasant", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "1", + "id": "2461", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A brightly coloured game bird.", + "melee_animation": "2372", + "range_animation": "2372", + "combat_audio": "690,692,691", + "attack_speed": "6", + "respawn_delay": "18", + "defence_animation": "2371", + "magic_animation": "2372", + "death_animation": "2373", + "name": "Pheasant", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "1", + "id": "2462", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A fowl beast.", + "combat_style": "2", + "melee_animation": "2302", + "range_animation": "2302", + "combat_audio": "2288,357,356", + "magic_level": "5", + "respawn_delay": "25", + "defence_animation": "2300", + "magic_animation": "2302", + "death_animation": "2301", + "name": "Evil Chicken", + "defence_level": "20", + "safespot": null, + "lifepoints": "19", + "strength_level": "5", + "id": "2463", + "aggressive": "true", + "bonuses": "25,85,105,75,103,85,65,0,0,0,0,0,0,0,0", + "range_level": "5", + "projectile": "337", + "attack_level": "5" + }, + { + "examine": "A fowl beast.", + "combat_style": "2", + "melee_animation": "2302", + "range_animation": "2302", + "combat_audio": "2288,357,356", + "magic_level": "10", + "respawn_delay": "25", + "defence_animation": "2300", + "magic_animation": "2302", + "death_animation": "2301", + "name": "Evil Chicken", + "defence_level": "40", + "safespot": null, + "lifepoints": "40", + "strength_level": "10", + "id": "2464", + "aggressive": "true", + "bonuses": "35,105,125,95,128,105,85,0,0,0,0,0,0,0,0", + "range_level": "10", + "projectile": "337", + "attack_level": "10" + }, + { + "examine": "A fowl beast.", + "combat_style": "2", + "melee_animation": "2302", + "range_animation": "2302", + "combat_audio": "2288,357,356", + "magic_level": "15", + "respawn_delay": "25", + "defence_animation": "2300", + "magic_animation": "2302", + "death_animation": "2301", + "name": "Evil Chicken", + "defence_level": "50", + "safespot": null, + "lifepoints": "60", + "strength_level": "15", + "id": "2465", + "aggressive": "true", + "bonuses": "35,185,185,155,188,125,165,0,0,0,0,0,0,0,0", + "range_level": "15", + "projectile": "337", + "attack_level": "15" + }, + { + "examine": "A fowl beast.", + "combat_style": "2", + "melee_animation": "2302", + "range_animation": "2302", + "combat_audio": "2288,357,356", + "magic_level": "25", + "respawn_delay": "25", + "defence_animation": "2300", + "magic_animation": "2302", + "death_animation": "2301", + "name": "Evil Chicken", + "defence_level": "60", + "safespot": null, + "lifepoints": "80", + "strength_level": "45", + "id": "2466", + "aggressive": "true", + "bonuses": "45,235,235,205,238,145,165,0,0,0,0,0,0,0,0", + "range_level": "45", + "projectile": "337", + "attack_level": "45" + }, + { + "examine": "A fowl beast.", + "combat_style": "2", + "melee_animation": "2302", + "range_animation": "2302", + "combat_audio": "2288,357,356", + "magic_level": "35", + "respawn_delay": "25", + "defence_animation": "2300", + "magic_animation": "2302", + "death_animation": "2301", + "name": "Evil Chicken", + "defence_level": "70", + "safespot": null, + "lifepoints": "105", + "strength_level": "45", + "id": "2467", + "aggressive": "true", + "bonuses": "45,285,285,255,288,145,165,0,0,0,0,0,0,0,0", + "range_level": "45", + "projectile": "337", + "attack_level": "45" + }, + { + "examine": "A fowl beast.", + "combat_style": "2", + "melee_animation": "2302", + "range_animation": "2302", + "combat_audio": "2288,357,356", + "magic_level": "45", + "respawn_delay": "25", + "defence_animation": "2300", + "weakness": "9", + "magic_animation": "2302", + "death_animation": "2301", + "name": "Evil Chicken", + "defence_level": "90", + "safespot": null, + "lifepoints": "120", + "strength_level": "45", + "id": "2468", + "aggressive": "true", + "bonuses": "45,285,285,255,288,145,165,0,0,0,0,0,0,0,0", + "range_level": "45", + "projectile": "337", + "attack_level": "45" + }, + { + "examine": "A Retired Highwayman", + "combat_style": "1", + "melee_animation": "4230", + "range_animation": "4230", + "combat_audio": "2695,513,512", + "attack_speed": "5", + "magic_level": "30", + "defence_animation": "404", + "magic_animation": "4230", + "death_animation": "9055", + "name": "Rick Turpentine", + "defence_level": "8", + "safespot": null, + "lifepoints": "10", + "strength_level": "8", + "id": "2476", + "bonuses": "30,20,10,20,20,30,30,10,20,10,30,30,20,30,20", + "range_level": "20", + "projectile": "27", + "attack_level": "8", + "prj_height": "" + }, + { + "examine": "Apparently a master of quizzes!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Quiz Master", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2477", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Hey, it's Bob the cat! Or... is it?", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Evil Bob", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2479", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Servant of Evil Bob.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Servant", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2481", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Annoying flappy thing.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "292,294,293", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "35", + "defence_animation": "0", + "slayer_exp": "8", + "magic_animation": "0", + "death_animation": "0", + "name": "Giant bat", + "defence_level": "22", + "safespot": null, + "lifepoints": "32", + "strength_level": "22", + "id": "2482", + "bonuses": "0,0,0,0,0,10,10,12,10,8,0,0,0,0,0", + "range_level": "1", + "attack_level": "22" + }, + { + "examine": "A slithering serpent that likes to hide in the bush.", + "melee_animation": "275", + "range_animation": "0", + "combat_audio": "3609,3608,3610", + "poisonous": "true", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "1", + "poison_amount": "11", + "magic_animation": "0", + "death_animation": "278", + "name": "Bush snake", + "defence_level": "61", + "safespot": null, + "lifepoints": "87", + "strength_level": "1", + "id": "2489", + "aggressive": "true", + "range_level": "61", + "attack_level": "1" + }, + { + "melee_animation": "275", + "combat_audio": "3609,3608,3610", + "poisonous": "true", + "respawn_delay": "60", + "defence_animation": "276", + "poison_amount": "11", + "death_animation": "278", + "name": "Bush snake", + "defence_level": "1", + "safespot": null, + "lifepoints": "25", + "strength_level": "1", + "id": "2490", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "5327", + "combat_audio": "537,539,538", + "respawn_delay": "60", + "defence_animation": "5328", + "death_animation": "5329", + "name": "Jungle spider", + "defence_level": "1", + "safespot": null, + "lifepoints": "50", + "strength_level": "1", + "id": "2491", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "5327", + "combat_audio": "537,539,538", + "respawn_delay": "60", + "defence_animation": "5328", + "death_animation": "5329", + "name": "Jungle spider", + "defence_level": "1", + "safespot": null, + "lifepoints": "50", + "strength_level": "1", + "id": "2492", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A flying bloodsucker.", + "melee_animation": "2397", + "range_animation": "0", + "defence_animation": "0", + "weakness": "2", + "magic_animation": "0", + "death_animation": "2398", + "name": "Large mosquito", + "defence_level": "63", + "safespot": null, + "lifepoints": "90", + "strength_level": "1", + "id": "2493", + "range_level": "63", + "attack_level": "1" + }, + { + "examine": "A swarm of three highly agile mosquitoes.", + "melee_animation": "2397", + "range_animation": "0", + "defence_animation": "0", + "weakness": "2", + "magic_animation": "0", + "death_animation": "2398", + "name": "Mosquito swarm", + "defence_level": "66", + "safespot": null, + "lifepoints": "94", + "strength_level": "1", + "id": "2494", + "range_level": "66", + "attack_level": "1" + }, + { + "examine": "A swarm of five highly agile mosquitoes.", + "melee_animation": "2397", + "range_animation": "0", + "defence_animation": "0", + "weakness": "2", + "magic_animation": "0", + "death_animation": "2398", + "name": "Mosquito swarm", + "defence_level": "68", + "safespot": null, + "lifepoints": "97", + "strength_level": "1", + "id": "2495", + "range_level": "68", + "attack_level": "1" + }, + { + "name": "Tribesman", + "defence_level": "1", + "safespot": null, + "lifepoints": "40", + "strength_level": "1", + "id": "2496", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A vicious warrior.", + "melee_animation": "428", + "range_animation": "0", + "attack_speed": "4", + "poisonous": "true", + "magic_level": "1", + "respawn_delay": "50", + "defence_animation": "0", + "weakness": "9", + "poison_amount": "11", + "magic_animation": "0", + "death_animation": "836", + "name": "Tribesman", + "defence_level": "26", + "safespot": null, + "lifepoints": "39", + "strength_level": "27", + "id": "2497", + "aggressive": "true", + "clue_level": "1", + "bonuses": "8,8,8,0,0,4,6,6,0,0,0,5,0,0,0", + "range_level": "1", + "attack_level": "23" + }, + { + "examine": "An undead victim of some ancient murderous ritual; his skin appears deep green.", + "combat_style": "2", + "melee_animation": "0", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Broodoo victim", + "defence_level": "45", + "safespot": null, + "lifepoints": "64", + "strength_level": "45", + "id": "2499", + "aggressive": "true", + "range_level": "1", + "attack_level": "45" + }, + { + "examine": "An undead victim of some ancient murderous ritual; his skin appears pale yellow.", + "combat_style": "2", + "melee_animation": "428", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Broodoo victim", + "defence_level": "43", + "safespot": null, + "lifepoints": "61", + "strength_level": "43", + "id": "2501", + "aggressive": "true", + "range_level": "1", + "attack_level": "43" + }, + { + "combat_style": "2", + "melee_animation": "810", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Broodoo victim", + "defence_level": "1", + "safespot": null, + "lifepoints": "100", + "strength_level": "1", + "id": "2503", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He used to swashbuckle his away across the seven seas.", + "combat_style": "1", + "melee_animation": "4230", + "range_animation": "4230", + "attack_speed": "5", + "magic_level": "20", + "defence_animation": "404", + "magic_animation": "4230", + "death_animation": "9055", + "name": "Cap'n Hand", + "defence_level": "10", + "safespot": null, + "lifepoints": "10", + "strength_level": "10", + "id": "2539", + "bonuses": "10,30,20,30,10,20,15,30,10,30,15,20,20,0,0", + "range_level": "30", + "attack_level": "30" + }, + { + "examine": "A crazy, evil druid.", + "start_gfx": "105", + "melee_animation": "422", + "range_animation": "422", + "attack_speed": "4", + "magic_level": "10", + "end_gfx": "107", + "respawn_delay": "25", + "defence_animation": "404", + "weakness": "3", + "magic_animation": "422", + "death_animation": "9055", + "name": "Chaos druid", + "defence_level": "12", + "safespot": null, + "lifepoints": "20", + "strength_level": "8", + "id": "2547", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "projectile": "106", + "attack_level": "8" + }, + { + "examine": "A colourful character.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ali the dyer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2549", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Looks after the blast furnace.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Blast Furnace Foreman", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2553", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He smells of rock dust.", + "name": "Ordan", + "id": "2564" + }, + { + "examine": "He buys stuff.", + "name": "Jorzik", + "id": "2565" + }, + { + "death_animation": "836", + "name": "Market Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "23", + "melee_animation": "400", + "strength_level": "1", + "id": "2571", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1", + "defence_animation": "425" + }, + { + "examine": "He's guarding the bank.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Bank guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2574", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A holy man.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Brother Althric", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2588", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Looks like some kind of mystic.", + "start_gfx": "1618", + "combat_style": "2", + "melee_animation": "9260", + "range_animation": "9260", + "attack_speed": "5", + "magic_level": "70", + "end_gfx": "1621", + "defence_animation": "9287", + "magic_animation": "9260", + "death_animation": "9291", + "name": "TzHaar-Mej", + "defence_level": "70", + "safespot": null, + "lifepoints": "100", + "strength_level": "70", + "id": "2591", + "bonuses": "60,120,90,120,60,60,50,45,0,0,0,0,0,0,0", + "range_level": "70", + "projectile": "1617", + "attack_level": "70" + }, + { + "examine": "Looks like some kind of mystic.", + "start_gfx": "1618", + "combat_style": "2", + "melee_animation": "9260", + "range_animation": "9260", + "attack_speed": "5", + "magic_level": "70", + "end_gfx": "1621", + "defence_animation": "9287", + "magic_animation": "9260", + "death_animation": "9291", + "name": "TzHaar-Mej", + "defence_level": "70", + "safespot": null, + "lifepoints": "100", + "strength_level": "70", + "id": "2592", + "bonuses": "60,120,90,120,60,60,50,45,0,0,0,0,0,0,0", + "range_level": "70", + "projectile": "1617", + "attack_level": "70" + }, + { + "examine": "Looks like some kind of mystic.", + "start_gfx": "1618", + "combat_style": "2", + "melee_animation": "9260", + "range_animation": "9260", + "attack_speed": "5", + "magic_level": "70", + "end_gfx": "1621", + "defence_animation": "9287", + "magic_animation": "9260", + "death_animation": "9291", + "name": "TzHaar-Mej", + "defence_level": "70", + "safespot": null, + "lifepoints": "100", + "strength_level": "70", + "id": "2593", + "bonuses": "60,120,90,120,60,60,50,45,0,0,0,0,0,0,0", + "range_level": "70", + "projectile": "1617", + "attack_level": "70" + }, + { + "examine": "Looks like some kind of mystic.", + "start_gfx": "1618", + "combat_style": "2", + "melee_animation": "9260", + "range_animation": "9260", + "attack_speed": "5", + "magic_level": "70", + "end_gfx": "1621", + "defence_animation": "9287", + "magic_animation": "9260", + "death_animation": "9291", + "name": "TzHaar-Mej", + "defence_level": "70", + "safespot": null, + "lifepoints": "100", + "strength_level": "70", + "id": "2594", + "bonuses": "60,120,90,120,60,60,50,45,0,0,0,0,0,0,0", + "range_level": "70", + "projectile": "1617", + "attack_level": "70" + }, + { + "examine": "Looks like some kind of mystic.", + "start_gfx": "1618", + "combat_style": "2", + "melee_animation": "9260", + "range_animation": "9260", + "attack_speed": "5", + "magic_level": "70", + "end_gfx": "1621", + "defence_animation": "9287", + "magic_animation": "9260", + "death_animation": "9291", + "name": "TzHaar-Mej", + "defence_level": "70", + "safespot": null, + "lifepoints": "100", + "strength_level": "70", + "id": "2595", + "bonuses": "60,120,90,120,60,60,50,45,0,0,0,0,0,0,0", + "range_level": "70", + "projectile": "1617", + "attack_level": "70" + }, + { + "examine": "Looks like some kind of mystic.", + "start_gfx": "1618", + "combat_style": "2", + "melee_animation": "9260", + "range_animation": "9260", + "attack_speed": "5", + "magic_level": "70", + "end_gfx": "1621", + "defence_animation": "9287", + "magic_animation": "9260", + "death_animation": "9291", + "name": "TzHaar-Mej", + "defence_level": "70", + "safespot": null, + "lifepoints": "100", + "strength_level": "70", + "id": "2596", + "bonuses": "60,120,90,120,60,60,50,45,0,0,0,0,0,0,0", + "range_level": "70", + "projectile": "1617", + "attack_level": "70" + }, + { + "examine": "Looks like some kind of mystic.", + "start_gfx": "1618", + "combat_style": "2", + "melee_animation": "9260", + "range_animation": "9260", + "attack_speed": "5", + "magic_level": "70", + "end_gfx": "1621", + "defence_animation": "9287", + "magic_animation": "9260", + "death_animation": "9291", + "name": "TzHaar-Mej", + "defence_level": "70", + "safespot": null, + "lifepoints": "100", + "strength_level": "70", + "id": "2597", + "bonuses": "60,120,90,120,60,60,50,45,0,0,0,0,0,0,0", + "range_level": "70", + "projectile": "1617", + "attack_level": "70" + }, + { + "examine": "Looks like a craftsman of some kind.", + "melee_animation": "9286", + "range_animation": "9286", + "attack_speed": "5", + "magic_level": "50", + "defence_animation": "9287", + "magic_animation": "9286", + "death_animation": "9288", + "name": "TzHaar-Hur", + "defence_level": "50", + "safespot": null, + "lifepoints": "80", + "strength_level": "50", + "id": "2598", + "bonuses": "30,30,80,85,80,40,40,60,38,0,0,0,0,0,0", + "range_level": "70", + "attack_level": "50" + }, + { + "examine": "Looks like a craftsman of some kind.", + "melee_animation": "9286", + "range_animation": "9286", + "attack_speed": "5", + "magic_level": "50", + "defence_animation": "9287", + "magic_animation": "9286", + "death_animation": "9288", + "name": "TzHaar-Hur", + "defence_level": "50", + "safespot": null, + "lifepoints": "80", + "strength_level": "50", + "id": "2599", + "bonuses": "30,30,80,85,80,40,40,60,38,0,0,0,0,0,0", + "range_level": "70", + "attack_level": "50" + }, + { + "examine": "Looks like a craftsman of some kind.", + "melee_animation": "9286", + "range_animation": "9286", + "attack_speed": "5", + "magic_level": "50", + "defence_animation": "9287", + "magic_animation": "9286", + "death_animation": "9288", + "name": "TzHaar-Hur", + "defence_level": "50", + "safespot": null, + "lifepoints": "80", + "strength_level": "50", + "id": "2600", + "bonuses": "30,30,80,85,80,40,40,60,38,0,0,0,0,0,0", + "range_level": "70", + "attack_level": "50" + }, + { + "examine": "Looks like a craftsman of some kind.", + "melee_animation": "9286", + "range_animation": "9286", + "attack_speed": "5", + "magic_level": "50", + "defence_animation": "9287", + "magic_animation": "9286", + "death_animation": "9288", + "name": "TzHaar-Hur", + "defence_level": "50", + "safespot": null, + "lifepoints": "80", + "strength_level": "50", + "id": "2601", + "bonuses": "30,30,80,85,80,40,40,60,38,0,0,0,0,0,0", + "range_level": "70", + "attack_level": "50" + }, + { + "examine": "Looks like a craftsman of some kind.", + "melee_animation": "9286", + "range_animation": "9286", + "attack_speed": "5", + "magic_level": "50", + "defence_animation": "9287", + "magic_animation": "9286", + "death_animation": "9288", + "name": "TzHaar-Hur", + "defence_level": "50", + "safespot": null, + "lifepoints": "80", + "strength_level": "50", + "id": "2602", + "bonuses": "30,30,80,85,80,40,40,60,38,0,0,0,0,0,0", + "range_level": "70", + "attack_level": "50" + }, + { + "examine": "Looks like a craftsman of some kind.", + "melee_animation": "9286", + "range_animation": "9286", + "attack_speed": "5", + "magic_level": "50", + "defence_animation": "9287", + "magic_animation": "9286", + "death_animation": "9288", + "name": "TzHaar-Hur", + "defence_level": "50", + "safespot": null, + "lifepoints": "80", + "strength_level": "50", + "id": "2603", + "bonuses": "30,30,80,85,80,40,40,60,38,0,0,0,0,0,0", + "range_level": "70", + "attack_level": "50" + }, + { + "examine": "Doesn't look very social.", + "melee_animation": "9345", + "range_animation": "9345", + "magic_level": "70", + "defence_animation": "9287", + "magic_animation": "9345", + "death_animation": "9291", + "name": "TzHaar-Xil", + "defence_level": "70", + "safespot": null, + "lifepoints": "120", + "strength_level": "70", + "id": "2604", + "bonuses": "50,30,120,120,120,130,20,50,45,0,0,0,0,0,0", + "range_level": "70", + "attack_level": "70" + }, + { + "examine": "Doesn't look very social.", + "melee_animation": "9345", + "range_animation": "9345", + "magic_level": "70", + "defence_animation": "9287", + "magic_animation": "9345", + "death_animation": "9291", + "name": "TzHaar-Xil", + "defence_level": "70", + "safespot": null, + "lifepoints": "120", + "strength_level": "70", + "id": "2605", + "bonuses": "50,30,120,120,120,130,20,50,45,0,0,0,0,0,0", + "range_level": "70", + "attack_level": "70" + }, + { + "examine": "Doesn't look very social.", + "combat_style": "1", + "melee_animation": "9345", + "range_animation": "9345", + "magic_level": "70", + "defence_animation": "9287", + "magic_animation": "9345", + "death_animation": "9291", + "name": "TzHaar-Xil", + "defence_level": "70", + "safespot": null, + "lifepoints": "120", + "strength_level": "70", + "id": "2606", + "bonuses": "50,30,80,56,80,80,100,60,50,45,45,0,0,0,0", + "range_level": "70", + "projectile": "442", + "attack_level": "70" + }, + { + "examine": "Doesn't look very social.", + "melee_animation": "9345", + "range_animation": "9345", + "magic_level": "70", + "defence_animation": "9287", + "magic_animation": "9345", + "death_animation": "9291", + "name": "TzHaar-Xil", + "defence_level": "70", + "safespot": null, + "lifepoints": "120", + "strength_level": "70", + "id": "2607", + "bonuses": "50,30,120,120,120,130,20,50,45,0,0,0,0,0,0", + "range_level": "70", + "attack_level": "70" + }, + { + "examine": "Doesn't look very social.", + "melee_animation": "9345", + "range_animation": "9345", + "magic_level": "70", + "defence_animation": "9287", + "magic_animation": "9345", + "death_animation": "9291", + "name": "TzHaar-Xil", + "defence_level": "70", + "safespot": null, + "lifepoints": "120", + "strength_level": "70", + "id": "2608", + "bonuses": "50,30,120,120,120,130,20,50,45,0,0,0,0,0,0", + "range_level": "70", + "attack_level": "70" + }, + { + "examine": "Doesn't look very social.", + "combat_style": "1", + "melee_animation": "9345", + "range_animation": "9345", + "magic_level": "70", + "defence_animation": "9287", + "slayer_exp": "0", + "magic_animation": "9345", + "death_animation": "9291", + "name": "TzHaar-Xil", + "defence_level": "70", + "safespot": null, + "lifepoints": "120", + "strength_level": "70", + "id": "2609", + "bonuses": "50,30,80,56,80,80,100,60,50,45,45,0,0,0,0", + "range_level": "70", + "projectile": "442", + "attack_level": "70" + }, + { + "examine": "Must be a guard or something.", + "melee_animation": "9345", + "range_animation": "9345", + "magic_level": "70", + "defence_animation": "9287", + "magic_animation": "9345", + "death_animation": "9288", + "name": "TzHaar-Ket", + "defence_level": "70", + "safespot": null, + "lifepoints": "140", + "strength_level": "70", + "id": "2610", + "bonuses": "50,120,120,120,130,20,60,45,0,0,0,0,0,0,0", + "range_level": "70", + "attack_level": "70" + }, + { + "examine": "Must be a guard or something.", + "melee_animation": "9345", + "range_animation": "9345", + "magic_level": "70", + "defence_animation": "9287", + "magic_animation": "9345", + "death_animation": "9288", + "name": "TzHaar-Ket", + "defence_level": "70", + "safespot": null, + "lifepoints": "140", + "strength_level": "70", + "id": "2611", + "bonuses": "50,120,120,120,130,20,60,45,0,0,0,0,0,0,0", + "range_level": "70", + "attack_level": "70" + }, + { + "examine": "Must be a guard or something.", + "melee_animation": "9345", + "range_animation": "9345", + "magic_level": "70", + "defence_animation": "9287", + "magic_animation": "9345", + "death_animation": "9288", + "name": "TzHaar-Ket", + "defence_level": "70", + "safespot": null, + "lifepoints": "140", + "strength_level": "70", + "id": "2612", + "bonuses": "50,120,120,120,130,20,60,45,0,0,0,0,0,0,0", + "range_level": "70", + "attack_level": "70" + }, + { + "examine": "Must be a guard or something.", + "melee_animation": "9345", + "range_animation": "9345", + "magic_level": "70", + "defence_animation": "9287", + "magic_animation": "9345", + "death_animation": "9288", + "name": "TzHaar-Ket", + "defence_level": "70", + "safespot": null, + "lifepoints": "140", + "strength_level": "70", + "id": "2613", + "bonuses": "50,120,120,120,130,20,60,45,0,0,0,0,0,0,0", + "range_level": "70", + "attack_level": "70" + }, + { + "examine": "Must be a guard or something.", + "melee_animation": "9345", + "range_animation": "9345", + "magic_level": "70", + "defence_animation": "9287", + "magic_animation": "9345", + "death_animation": "9288", + "name": "TzHaar-Ket", + "defence_level": "70", + "safespot": null, + "lifepoints": "140", + "strength_level": "70", + "id": "2614", + "bonuses": "50,120,120,120,130,20,60,45,0,0,0,0,0,0,0", + "range_level": "70", + "attack_level": "70" + }, + { + "examine": "Must be a guard or something.", + "melee_animation": "9345", + "range_animation": "9345", + "magic_level": "70", + "defence_animation": "9287", + "magic_animation": "9345", + "death_animation": "9288", + "name": "TzHaar-Ket", + "defence_level": "70", + "safespot": null, + "lifepoints": "140", + "strength_level": "70", + "id": "2615", + "bonuses": "50,120,120,120,130,20,60,45,0,0,0,0,0,0,0", + "range_level": "70", + "attack_level": "70" + }, + { + "examine": "Must be a guard or something.", + "melee_animation": "9345", + "range_animation": "9345", + "magic_level": "70", + "defence_animation": "9287", + "magic_animation": "9345", + "death_animation": "9288", + "name": "TzHaar-Ket", + "defence_level": "70", + "safespot": null, + "lifepoints": "140", + "strength_level": "70", + "id": "2616", + "bonuses": "50,120,120,120,130,20,60,45,0,0,0,0,0,0,0", + "range_level": "70", + "attack_level": "70" + }, + { + "name": "Tz-Kih", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "attack_speed": "7", + "id": "2627", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Tz-Kih", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "attack_speed": "7", + "id": "2628", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Tz-Kek", + "defence_level": "1", + "safespot": null, + "lifepoints": "20", + "strength_level": "1", + "attack_speed": "5", + "id": "2629", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Tz-Kek", + "defence_level": "1", + "safespot": null, + "lifepoints": "20", + "strength_level": "1", + "attack_speed": "5", + "id": "2630", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "examine": "The Tok-Xil fires deadly spines out of its arm", + "range_animation": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "name": "Tok-Xil", + "defence_level": "80", + "safespot": null, + "lifepoints": "114", + "strength_level": "1", + "id": "2631", + "aggressive": "true", + "range_level": "80", + "attack_level": "1" + }, + { + "examine": "A busy-body who loves a bit of gossip.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Miss Schism", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2634", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Dragonkin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "408,410,409", + "strength_level": "1", + "id": "2641", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Nice but dim.", + "name": "Unferth", + "id": "2655" + }, + { + "examine": "Known for his light-fingered qualities.", + "melee_animation": "422", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Thief", + "defence_level": "10", + "safespot": null, + "lifepoints": "14", + "strength_level": "10", + "id": "2674", + "range_level": "1", + "attack_level": "10" + }, + { + "name": "Man", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "2675", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He holds up passers by.", + "melee_animation": "799", + "range_animation": "799", + "combat_audio": "511,513,512", + "attack_speed": "5", + "defence_animation": "404", + "weakness": "7", + "magic_animation": "799", + "death_animation": "9055", + "name": "Highwayman", + "defence_level": "8", + "safespot": null, + "lifepoints": "13", + "strength_level": "8", + "id": "2677", + "aggressive": "true", + "range_level": "1", + "attack_level": "8" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "2", + "id": "2678", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "2", + "id": "2679", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "2", + "id": "2680", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "2", + "id": "2681", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A popular dwarven delicacy.", + "melee_animation": "2705", + "range_animation": "2705", + "combat_audio": "3102,3104,3103", + "attack_speed": "5", + "defence_animation": "2706", + "magic_animation": "2705", + "death_animation": "2707", + "name": "Rat", + "defence_level": "1", + "safespot": null, + "lifepoints": "2", + "strength_level": "1", + "id": "2682", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A citizen of Rimmington.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Hengel", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2683", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A citizen of Rimmington.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Anja", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2684", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly smelly creature.", + "melee_animation": "164", + "range_animation": "164", + "combat_audio": "469,472,471", + "attack_speed": "6", + "defence_animation": "165", + "magic_animation": "164", + "death_animation": "167", + "name": "Hobgoblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "29", + "strength_level": "10", + "id": "2685", + "aggressive": "true", + "range_level": "20", + "attack_level": "20" + }, + { + "examine": "An ugly smelly creature.", + "melee_animation": "164", + "range_animation": "164", + "combat_audio": "469,472,471", + "attack_speed": "6", + "defence_animation": "165", + "magic_animation": "164", + "death_animation": "167", + "name": "Hobgoblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "29", + "strength_level": "10", + "id": "2686", + "aggressive": "true", + "range_level": "20", + "attack_level": "20" + }, + { + "examine": "An ugly smelly creature.", + "melee_animation": "164", + "range_animation": "164", + "combat_audio": "469,472,471", + "attack_speed": "6", + "defence_animation": "165", + "magic_animation": "164", + "death_animation": "167", + "name": "Hobgoblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "29", + "strength_level": "10", + "id": "2687", + "aggressive": "true", + "range_level": "20", + "attack_level": "20" + }, + { + "examine": "An ugly smelly creature, with a spear.", + "melee_animation": "163", + "range_animation": "163", + "combat_audio": "3520,472,471", + "attack_speed": "6", + "defence_animation": "165", + "magic_animation": "163", + "death_animation": "167", + "name": "Hobgoblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "29", + "strength_level": "10", + "id": "2688", + "aggressive": "true", + "range_level": "20", + "attack_level": "20" + }, + { + "examine": "Didn't the mage say this procedure was totally safe?", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Frog", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2689", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A salty seafarer. Needs a wash.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Jack Seagull", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2690", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A strange man with a strange name. Probably a strange past, too.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Longbow Ben", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2691", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "She quackers.", + "melee_animation": "0", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "3468", + "name": "Duck", + "defence_level": "1", + "water_npc": "true", + "safespot": null, + "lifepoints": "1", + "strength_level": "1", + "id": "2693", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Mini quackers.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "3468", + "name": "Duckling", + "defence_level": "1", + "water_npc": "true", + "safespot": null, + "lifepoints": "1", + "strength_level": "1", + "id": "2694", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "This one's had too much to drink!", + "melee_animation": "422", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "20", + "strength_level": "1", + "id": "2695", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Known for his light-fingered qualities.", + "melee_animation": "422", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "836", + "name": "Thief", + "defence_level": "11", + "safespot": null, + "lifepoints": "15", + "strength_level": "11", + "id": "2696", + "range_level": "1", + "attack_level": "11" + }, + { + "examine": "He doesn't look so happy now he's in jail.", + "melee_animation": "422", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "836", + "name": "Mugger", + "defence_level": "11", + "safespot": null, + "lifepoints": "15", + "strength_level": "11", + "id": "2697", + "aggressive": "true", + "range_level": "1", + "attack_level": "11" + }, + { + "examine": "A dark-hearted knight.", + "melee_animation": "422", + "range_animation": "0", + "attack_speed": "5", + "magic_level": "1", + "respawn_delay": "25", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "836", + "name": "Black knight", + "defence_level": "25", + "safespot": null, + "lifepoints": "42", + "strength_level": "24", + "id": "2698", + "aggressive": "true", + "range_level": "1", + "attack_level": "25" + }, + { + "examine": "He's guarding the prison.", + "melee_animation": "390", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "836", + "name": "Guard", + "defence_level": "13", + "safespot": null, + "lifepoints": "18", + "strength_level": "13", + "id": "2699", + "clue_level": "1", + "range_level": "1", + "attack_level": "13" + }, + { + "examine": "A prison guard.", + "melee_animation": "422", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "836", + "name": "Guard", + "defence_level": "13", + "safespot": null, + "lifepoints": "18", + "strength_level": "13", + "id": "2700", + "clue_level": "1", + "range_level": "1", + "attack_level": "13" + }, + { + "examine": "A prison guard.", + "melee_animation": "422", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "836", + "name": "Guard", + "defence_level": "13", + "safespot": null, + "lifepoints": "18", + "strength_level": "13", + "id": "2701", + "clue_level": "1", + "range_level": "1", + "attack_level": "13" + }, + { + "examine": "A prison guard.", + "melee_animation": "390", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "836", + "name": "Guard", + "defence_level": "13", + "safespot": null, + "lifepoints": "18", + "strength_level": "13", + "id": "2702", + "clue_level": "1", + "range_level": "1", + "attack_level": "13" + }, + { + "examine": "A prison guard.", + "melee_animation": "390", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "836", + "name": "Guard", + "defence_level": "13", + "safespot": null, + "lifepoints": "18", + "strength_level": "13", + "id": "2703", + "clue_level": "1", + "range_level": "1", + "attack_level": "13" + }, + { + "examine": "He's asleep.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2704", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Keeping an eye out for suspicious activity.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2705", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "No one likes crabs...", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Crab", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2706", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A sea bird.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "309,311,310", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Seagull", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2707", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Caution: HOT!", + "start_gfx": "99", + "combat_style": "2", + "start_height": "80", + "melee_animation": "414", + "range_animation": "0", + "magic_level": "18", + "respawn_delay": "60", + "end_gfx": "101", + "defence_animation": "0", + "weakness": "3", + "magic_animation": "711", + "death_animation": "2553", + "name": "Fire wizard", + "defence_level": "18", + "safespot": null, + "lifepoints": "25", + "strength_level": "1", + "id": "2709", + "range_level": "1", + "projectile": "100", + "attack_level": "1" + }, + { + "examine": "Hydro-power!", + "combat_style": "2", + "melee_animation": "414", + "range_animation": "0", + "magic_level": "14", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "3", + "magic_animation": "711", + "death_animation": "2553", + "name": "Water wizard", + "defence_level": "14", + "safespot": null, + "lifepoints": "20", + "strength_level": "1", + "id": "2710", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "His hands are covered in mud, at least.", + "start_gfx": "96", + "combat_style": "2", + "start_height": "80", + "melee_animation": "414", + "range_animation": "0", + "magic_level": "16", + "respawn_delay": "60", + "end_gfx": "98", + "defence_animation": "0", + "weakness": "3", + "magic_animation": "711", + "death_animation": "2553", + "name": "Earth wizard", + "defence_level": "16", + "safespot": null, + "lifepoints": "22", + "strength_level": "1", + "id": "2711", + "range_level": "1", + "projectile": "97", + "attack_level": "1" + }, + { + "examine": "At least he looks solid enough to fight.", + "start_gfx": "90", + "combat_style": "2", + "start_height": "80", + "melee_animation": "414", + "range_animation": "0", + "magic_level": "12", + "respawn_delay": "60", + "end_gfx": "92", + "defence_animation": "0", + "weakness": "3", + "magic_animation": "711", + "death_animation": "2553", + "name": "Air wizard", + "defence_level": "12", + "safespot": null, + "lifepoints": "17", + "strength_level": "1", + "id": "2712", + "range_level": "1", + "projectile": "91", + "attack_level": "1" + }, + { + "slayer_exp": "30", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "40", + "combat_audio": "931,923,922", + "strength_level": "1", + "id": "2714", + "range_level": "1", + "attack_level": "1" + }, + { + "slayer_exp": "25", + "name": "Ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "436,439,438", + "strength_level": "1", + "id": "2716", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "She'll store my items for me.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Betty", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2718", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A wise barbarian, apparently. He still looks like a thug.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Otto Godblessed", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2725", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Holy looking.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Monk of Entrana", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2728", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Holy looking.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Monk of Entrana", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2729", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Holy looking.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Monk of Entrana", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2731", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He works in the Crafting Guild.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Master Crafter", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2732", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He wanders around the Crafting Guild pretending to be working.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Master Crafter", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2733", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Hangs out in caves.", + "melee_animation": "9232", + "range_animation": "9232", + "attack_speed": "5", + "respawn_delay": "0", + "defence_animation": "9231", + "magic_animation": "9232", + "death_animation": "9230", + "name": "Tz-Kih", + "defence_level": "11", + "safespot": null, + "lifepoints": "10", + "strength_level": "27", + "id": "2734", + "aggressive": "true", + "bonuses": "150,22,22,22,22,11,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "Hangs out in caves.", + "melee_animation": "9232", + "range_animation": "9232", + "attack_speed": "5", + "respawn_delay": "0", + "defence_animation": "9231", + "magic_animation": "9232", + "death_animation": "9230", + "name": "Tz-Kih", + "defence_level": "11", + "safespot": null, + "lifepoints": "10", + "strength_level": "27", + "id": "2735", + "aggressive": "true", + "bonuses": "150,22,22,22,22,11,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "Looks like living lava...", + "melee_animation": "9233", + "range_animation": "9233", + "attack_speed": "5", + "magic_level": "20", + "defence_animation": "9235", + "magic_animation": "9233", + "death_animation": "9234", + "name": "Tz-Kek", + "defence_level": "22", + "safespot": null, + "lifepoints": "20", + "strength_level": "60", + "id": "2736", + "aggressive": "true", + "bonuses": "80,45,45,45,45,22,0,0,0,0,0,0,0,0,0", + "range_level": "20", + "attack_level": "60" + }, + { + "examine": "Looks like living lava...", + "melee_animation": "9233", + "range_animation": "9233", + "attack_speed": "5", + "magic_level": "20", + "defence_animation": "9235", + "magic_animation": "9233", + "death_animation": "9234", + "name": "Tz-Kek", + "defence_level": "22", + "safespot": null, + "lifepoints": "20", + "strength_level": "60", + "id": "2737", + "aggressive": "true", + "bonuses": "80,45,45,45,45,22,0,0,0,0,0,0,0,0,0", + "range_level": "20", + "attack_level": "60" + }, + { + "examine": "Looks like living lava...", + "melee_animation": "9233", + "range_animation": "9233", + "attack_speed": "5", + "defence_animation": "9235", + "magic_animation": "9233", + "death_animation": "9234", + "name": "Tz-Kek", + "defence_level": "11", + "safespot": null, + "lifepoints": "10", + "strength_level": "30", + "id": "2738", + "bonuses": "60,22,22,22,22,11,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "I don't like the look of those spines...", + "melee_animation": "9245", + "range_animation": "9245", + "attack_speed": "5", + "defence_animation": "9242", + "weakness": "4", + "magic_animation": "9245", + "death_animation": "9239", + "name": "Tok-Xil", + "defence_level": "45", + "safespot": null, + "lifepoints": "40", + "strength_level": "80", + "id": "2739", + "bonuses": "80,90,86,90,90,90,45,55,26,55,0,0,0,0,0", + "range_level": "80", + "attack_level": "80" + }, + { + "examine": "I don't like the look of those spines...", + "melee_animation": "9245", + "range_animation": "9245", + "attack_speed": "5", + "defence_animation": "9242", + "weakness": "4", + "magic_animation": "9245", + "death_animation": "9239", + "name": "Tok-Xil", + "defence_level": "45", + "safespot": null, + "lifepoints": "40", + "strength_level": "80", + "id": "2740", + "bonuses": "80,90,86,90,90,90,45,55,26,55,0,0,0,0,0", + "range_level": "80", + "attack_level": "80" + }, + { + "examine": "Holy reptile...", + "melee_animation": "9252", + "range_animation": "9252", + "attack_speed": "5", + "defence_animation": "9249", + "magic_animation": "9252", + "death_animation": "9257", + "name": "Yt-MejKot", + "defence_level": "90", + "safespot": null, + "lifepoints": "80", + "strength_level": "100", + "id": "2741", + "aggressive": "true", + "bonuses": "100,180,180,180,180,90,97,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "100" + }, + { + "examine": "Holy reptile...", + "melee_animation": "9252", + "range_animation": "9252", + "attack_speed": "5", + "defence_animation": "9249", + "magic_animation": "9252", + "death_animation": "9257", + "name": "Yt-MejKot", + "defence_level": "90", + "safespot": null, + "lifepoints": "80", + "strength_level": "100", + "id": "2742", + "aggressive": "true", + "bonuses": "100,180,180,180,180,90,97,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "100" + }, + { + "examine": "That's one hot dog!", + "melee_animation": "9265", + "range_animation": "9265", + "attack_speed": "5", + "magic_level": "150", + "defence_animation": "9268", + "magic_animation": "9265", + "death_animation": "9269", + "name": "Ket-Zek", + "defence_level": "180", + "safespot": null, + "lifepoints": "160", + "strength_level": "150", + "id": "2743", + "bonuses": "180,180,280,280,280,250,140,152,131,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "150" + }, + { + "examine": "That's one hot dog!", + "melee_animation": "9265", + "range_animation": "9265", + "attack_speed": "5", + "magic_level": "150", + "defence_animation": "9268", + "magic_animation": "9265", + "death_animation": "9269", + "name": "Ket-Zek", + "defence_level": "180", + "safespot": null, + "lifepoints": "160", + "strength_level": "150", + "id": "2744", + "bonuses": "180,180,280,280,280,250,140,152,131,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "150" + }, + { + "agg_radius": "64", + "examine": "This is going to hurt...", + "melee_animation": "9277", + "range_animation": "9277", + "attack_speed": "8", + "magic_level": "480", + "defence_animation": "9278", + "weakness": "10", + "slayer_exp": "0", + "magic_animation": "9277", + "death_animation": "9279", + "name": "TzTok-Jad", + "defence_level": "480", + "safespot": null, + "lifepoints": "250", + "strength_level": "960", + "id": "2745", + "aggressive": "true", + "bonuses": "0,0,0,60,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "960", + "attack_level": "640" + }, + { + "examine": "Mini Menace.", + "melee_animation": "9252", + "range_animation": "9252", + "attack_speed": "5", + "defence_animation": "9253", + "magic_animation": "9252", + "death_animation": "9257", + "name": "Yt-HurKot", + "defence_level": "75", + "safespot": null, + "lifepoints": "40", + "strength_level": "75", + "id": "2746", + "aggressive": "true", + "bonuses": "100,110,110,110,110,60,110,30,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "75" + }, + { + "examine": "She can look after my money.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "null", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2759", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Woman", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,506,505", + "strength_level": "1", + "id": "2776", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A Ranger of the Temple Knights.", + "melee_animation": "426", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "836", + "name": "Ranger", + "defence_level": "1", + "safespot": null, + "lifepoints": "20", + "strength_level": "1", + "id": "2779", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A shadow.", + "melee_animation": "2738", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "2739", + "name": "Shadow", + "defence_level": "68", + "safespot": null, + "lifepoints": "100", + "strength_level": "68", + "id": "2782", + "aggressive": "true", + "range_level": "1", + "attack_level": "68" + }, + { + "examine": "From a darker dimension.", + "melee_animation": "2731", + "range_animation": "2731", + "combat_audio": "389,391,390", + "attack_speed": "4", + "magic_level": "160", + "defence_animation": "2732", + "weakness": "4", + "slayer_exp": "225", + "magic_animation": "2731", + "death_animation": "2733", + "name": "Dark beast", + "defence_level": "120", + "safespot": null, + "lifepoints": "220", + "can_tolerate": "false", + "strength_level": "160", + "id": "2783", + "aggressive": "true", + "bonuses": "0,0,0,0,0,30,40,100,90,100,0,0,0,0,0", + "range_level": "1", + "attack_level": "140" + }, + { + "examine": "Digging.", + "melee_animation": "", + "range_animation": "", + "defence_animation": "", + "magic_animation": "", + "death_animation": "", + "name": "Slave", + "defence_level": "", + "safespot": null, + "lifepoints": "", + "strength_level": "", + "id": "2785", + "range_level": "", + "attack_level": "" + }, + { + "examine": "Digging.", + "melee_animation": "", + "range_animation": "", + "defence_animation": "", + "magic_animation": "", + "death_animation": "", + "name": "Slave", + "defence_level": "", + "safespot": null, + "lifepoints": "", + "strength_level": "", + "id": "2786", + "range_level": "", + "attack_level": "" + }, + { + "examine": "Confused.", + "melee_animation": "", + "range_animation": "", + "defence_animation": "", + "magic_animation": "", + "death_animation": "", + "name": "Slave", + "defence_level": "", + "safespot": null, + "lifepoints": "", + "strength_level": "", + "id": "2787", + "range_level": "", + "attack_level": "" + }, + { + "examine": "Drill Sergeant from heck!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Sergeant Damien", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2790", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A man down on his luck.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Tramp", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2792", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Big, ugly, and smelly.", + "melee_animation": "359", + "range_animation": "359", + "attack_speed": "6", + "defence_animation": "360", + "magic_animation": "359", + "death_animation": "361", + "name": "Ogre", + "defence_level": "54", + "safespot": null, + "lifepoints": "60", + "strength_level": "54", + "id": "2801", + "aggressive": "true", + "range_level": "1", + "attack_level": "54" + }, + { + "examine": "They just call him 'Coach'.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Gnome Coach", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2802", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A cold-blooded creature, partial to warmth.", + "melee_animation": "2776", + "range_animation": "2776", + "attack_speed": "5", + "defence_animation": "2777", + "weakness": "0", + "slayer_exp": "40", + "magic_animation": "2776", + "death_animation": "2778", + "name": "Lizard", + "defence_level": "55", + "safespot": null, + "lifepoints": "40", + "strength_level": "1", + "id": "2803", + "aggressive": "true", + "range_level": "55", + "attack_level": "1" + }, + { + "examine": "A cold-blooded creature, partial to warmth.", + "melee_animation": "2776", + "range_animation": "2776", + "attack_speed": "5", + "defence_animation": "2777", + "weakness": "0", + "slayer_exp": "25", + "magic_animation": "2776", + "death_animation": "2778", + "name": "Desert Lizard", + "defence_level": "45", + "safespot": null, + "lifepoints": "25", + "strength_level": "1", + "id": "2804", + "aggressive": "true", + "range_level": "45", + "attack_level": "1" + }, + { + "examine": "A cold-blooded creature, partial to warmth.", + "melee_animation": "2776", + "range_animation": "2776", + "attack_speed": "5", + "defence_animation": "2777", + "weakness": "0", + "slayer_exp": "25", + "magic_animation": "2776", + "death_animation": "2778", + "name": "Desert Lizard", + "defence_level": "45", + "safespot": null, + "lifepoints": "25", + "strength_level": "1", + "id": "2805", + "aggressive": "true", + "range_level": "45", + "attack_level": "1" + }, + { + "examine": "A cold-blooded creature, partial to warmth.", + "melee_animation": "2776", + "range_animation": "2776", + "attack_speed": "5", + "defence_animation": "2777", + "slayer_exp": "25", + "magic_animation": "2776", + "death_animation": "2778", + "name": "Desert Lizard", + "defence_level": "45", + "safespot": null, + "lifepoints": "25", + "strength_level": "1", + "id": "2806", + "aggressive": "true", + "range_level": "45", + "attack_level": "1" + }, + { + "examine": "A cold-blooded creature, partial to warmth.", + "melee_animation": "2776", + "range_animation": "2776", + "attack_speed": "5", + "defence_animation": "2777", + "weakness": "0", + "slayer_exp": "15", + "magic_animation": "2776", + "death_animation": "2778", + "name": "Small Lizard", + "defence_level": "15", + "safespot": null, + "lifepoints": "15", + "strength_level": "1", + "id": "2807", + "range_level": "15", + "attack_level": "1" + }, + { + "examine": "A cold-blooded creature, partial to warmth.", + "melee_animation": "2776", + "range_animation": "2776", + "attack_speed": "5", + "defence_animation": "2777", + "weakness": "0", + "magic_animation": "2776", + "death_animation": "2778", + "name": "Small Lizard", + "defence_level": "15", + "safespot": null, + "lifepoints": "15", + "strength_level": "1", + "id": "2808", + "aggressive": "true", + "range_level": "15", + "attack_level": "1" + }, + { + "examine": "A camel who has the soul of a poet.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Al the Camel", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2809", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A camel whose love is unrequited.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Elly the Camel", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2810", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A camel who wants to fly some day.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ollie the Camel", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2811", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A camel who likes to rest.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cam the Camel", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2812", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A camel who wants to see the world.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Neferti the Camel", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2815", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A shifty-looking character.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "703,705,704", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Pirate Pete", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2825", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Pirate Pete", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "703,705,704", + "strength_level": "1", + "id": "2826", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A shabby-looking leader.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Captain Braindeath", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2827", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Most of an angry", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "50% Luke", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2828", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "I wonder if it was all the 'rum' that pickled him.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Captain Donnie", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2830", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Sticking it to 'The Man'.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Zombie protester", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2831", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Sticking it to 'The Man'.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Zombie protester", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2832", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Sticking it to 'The Man'.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Zombie protester", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2833", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Sticking it to 'The Man'.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Zombie protester", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2834", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Sticking it to 'The Man'.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Zombie protester", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2835", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Sticking it to 'The Man'.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Zombie protester", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2836", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An undead sea scoundrel.", + "melee_animation": "5647", + "range_animation": "0", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5649", + "name": "Zombie pirate", + "defence_level": "36", + "safespot": null, + "lifepoints": "51", + "strength_level": "36", + "id": "2837", + "aggressive": "true", + "range_level": "1", + "attack_level": "36" + }, + { + "examine": "An undead sea scoundrel.", + "melee_animation": "5651", + "range_animation": "0", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5654", + "name": "Zombie pirate", + "defence_level": "36", + "safespot": null, + "lifepoints": "51", + "strength_level": "36", + "id": "2838", + "aggressive": "true", + "range_level": "1", + "attack_level": "36" + }, + { + "examine": "An undead sea scoundrel.", + "melee_animation": "5651", + "range_animation": "0", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5654", + "name": "Zombie pirate", + "defence_level": "36", + "safespot": null, + "lifepoints": "51", + "strength_level": "36", + "id": "2839", + "aggressive": "true", + "range_level": "1", + "attack_level": "36" + }, + { + "examine": "An undead sea scoundrel.", + "melee_animation": "5651", + "range_animation": "0", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5654", + "name": "Zombie pirate", + "defence_level": "36", + "safespot": null, + "lifepoints": "51", + "strength_level": "36", + "id": "2840", + "aggressive": "true", + "range_level": "1", + "attack_level": "36" + }, + { + "examine": "An undead sea scoundrel.", + "melee_animation": "5647", + "range_animation": "0", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5649", + "name": "Zombie pirate", + "defence_level": "36", + "safespot": null, + "lifepoints": "51", + "strength_level": "36", + "id": "2841", + "aggressive": "true", + "range_level": "1", + "attack_level": "36" + }, + { + "examine": "An undead sea scoundrel.", + "melee_animation": "5647", + "range_animation": "0", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5649", + "name": "Zombie pirate", + "defence_level": "36", + "safespot": null, + "lifepoints": "51", + "strength_level": "36", + "id": "2842", + "aggressive": "true", + "range_level": "1", + "attack_level": "36" + }, + { + "examine": "He talks a good fight.", + "melee_animation": "5647", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5649", + "name": "Zombie swab", + "defence_level": "34", + "safespot": null, + "lifepoints": "48", + "strength_level": "34", + "id": "2843", + "aggressive": "true", + "range_level": "1", + "attack_level": "34" + }, + { + "examine": "He talks a good fight.", + "melee_animation": "5647", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5649", + "name": "Zombie swab", + "defence_level": "34", + "safespot": null, + "lifepoints": "48", + "strength_level": "34", + "id": "2844", + "aggressive": "true", + "range_level": "1", + "attack_level": "34" + }, + { + "examine": "He talks a good fight.", + "melee_animation": "5651", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5654", + "name": "Zombie swab", + "defence_level": "34", + "safespot": null, + "lifepoints": "48", + "strength_level": "34", + "id": "2845", + "aggressive": "true", + "range_level": "1", + "attack_level": "34" + }, + { + "examine": "He talks a good fight.", + "melee_animation": "5651", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5654", + "name": "Zombie swab", + "defence_level": "34", + "safespot": null, + "lifepoints": "48", + "strength_level": "34", + "id": "2846", + "aggressive": "true", + "range_level": "1", + "attack_level": "34" + }, + { + "examine": "He talks a good fight.", + "melee_animation": "5647", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5649", + "name": "Zombie swab", + "defence_level": "34", + "safespot": null, + "lifepoints": "48", + "strength_level": "34", + "id": "2847", + "aggressive": "true", + "range_level": "1", + "attack_level": "34" + }, + { + "examine": "He talks a good fight.", + "melee_animation": "5647", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5649", + "name": "Zombie swab", + "defence_level": "34", + "safespot": null, + "lifepoints": "48", + "strength_level": "34", + "id": "2848", + "aggressive": "true", + "range_level": "1", + "attack_level": "34" + }, + { + "examine": "The pun was intended.", + "melee_animation": "2804", + "range_animation": "0", + "magic_level": "40", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "2805", + "name": "Evil spirit", + "defence_level": "40", + "safespot": null, + "lifepoints": "57", + "strength_level": "40", + "id": "2849", + "aggressive": "true", + "range_level": "40", + "attack_level": "40" + }, + { + "examine": "A bunch of legs, eyes and teeth.", + "melee_animation": "5319", + "range_animation": "0", + "combat_audio": "537,539,538", + "attack_speed": "4", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "2", + "slayer_exp": "40", + "magic_animation": "0", + "death_animation": "5321", + "name": "Fever spider", + "defence_level": "40", + "safespot": null, + "lifepoints": "40", + "strength_level": "30", + "id": "2850", + "bonuses": "0,0,0,0,0,20,15,10,15,15,0,0,0,0,0", + "range_level": "1", + "attack_level": "60" + }, + { + "examine": "A worker in the brewery.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Brewer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2851", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A worker in the brewery.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Brewer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2852", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A worker in the brewery.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Brewer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2853", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A worker in the brewery.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Brewer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2854", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A worker in the brewery.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Brewer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2855", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A worker in the brewery.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Brewer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2856", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A worker in the brewery.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Brewer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2857", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A worker in the brewery.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Brewer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2858", + "range_level": "1", + "attack_level": "1" + }, + { + "slayer_exp": "30", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "40", + "combat_audio": "931,923,922", + "strength_level": "1", + "id": "2863", + "range_level": "1", + "attack_level": "1" + }, + { + "slayer_exp": "30", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "40", + "combat_audio": "931,923,922", + "strength_level": "1", + "id": "2866", + "range_level": "1", + "attack_level": "1" + }, + { + "slayer_exp": "30", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "40", + "combat_audio": "931,923,922", + "strength_level": "1", + "id": "2869", + "range_level": "1", + "attack_level": "1" + }, + { + "slayer_exp": "30", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "40", + "combat_audio": "931,923,922", + "strength_level": "1", + "id": "2878", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A knee-high horror from the ocean depths...", + "melee_animation": "1579", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "1581", + "name": "Dagannoth fledgeling", + "defence_level": "52", + "safespot": null, + "lifepoints": "74", + "strength_level": "52", + "id": "2880", + "aggressive": "true", + "range_level": "1", + "attack_level": "52" + }, + { + "agg_radius": "8", + "examine": "The Dagannoth King responsible for the death of Bukalla.", + "combat_style": "1", + "melee_animation": "2855", + "attack_speed": "4", + "magic_level": "255", + "respawn_delay": "60", + "defence_animation": "2852", + "death_animation": "2856", + "name": "Dagannoth Supreme", + "defence_level": "128", + "movement_radius": "8", + "safespot": null, + "lifepoints": "255", + "strength_level": "255", + "id": "2881", + "aggressive": "true", + "bonuses": "0,0,0,0,0,10,10,10,255,550,0,0,0,0,0", + "clue_level": "2", + "range_level": "255", + "projectile": "475", + "attack_level": "255" + }, + { + "agg_radius": "8", + "examine": "A legendary Dagannoth King, rumoured to fly on the North winds.", + "combat_style": "2", + "melee_animation": "2854", + "attack_speed": "4", + "magic_level": "255", + "spell_id": "48", + "respawn_delay": "60", + "defence_animation": "2852", + "death_animation": "2856", + "name": "Dagannoth Prime", + "defence_level": "255", + "movement_radius": "8", + "safespot": null, + "lifepoints": "255", + "strength_level": "255", + "id": "2882", + "aggressive": "true", + "bonuses": "0,0,0,0,0,255,255,255,255,10,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "255" + }, + { + "agg_radius": "8", + "examine": "Firstborn of the legendary Dagannoth Kings.", + "melee_animation": "2853", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "2852", + "death_animation": "2856", + "name": "Dagannoth Rex", + "defence_level": "255", + "movement_radius": "8", + "safespot": null, + "lifepoints": "255", + "strength_level": "255", + "id": "2883", + "aggressive": "true", + "bonuses": "0,0,0,0,0,255,255,255,10,255,0,0,0,0,0", + "clue_level": "2", + "range_level": "255", + "attack_level": "255" + }, + { + "melee_animation": "1312", + "combat_audio": "717,723,722", + "attack_speed": "4", + "respawn_delay": "50", + "defence_animation": "1313", + "death_animation": "1314", + "name": "Giant Rock Crab", + "defence_level": "200", + "safespot": null, + "lifepoints": "180", + "strength_level": "80", + "id": "2885", + "aggressive": "true", + "bonuses": "0,0,0,0,0,225,200,175,-10,250,0,0,0,0,0", + "range_level": "1", + "attack_level": "50" + }, + { + "name": "Boulder", + "defence_level": "1", + "safespot": null, + "lifepoints": "240", + "strength_level": "1", + "attack_speed": "5", + "id": "2886", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "combat_style": "1", + "melee_animation": "1343", + "respawn_delay": "60", + "defence_animation": "1340", + "death_animation": "1342", + "name": "Dagannoth", + "defence_level": "1", + "safespot": null, + "lifepoints": "85", + "strength_level": "1", + "id": "2887", + "aggressive": "true", + "clue_level": "1", + "range_level": "1", + "projectile": "288", + "attack_level": "1" + }, + { + "combat_style": "1", + "melee_animation": "1343", + "respawn_delay": "60", + "defence_animation": "1340", + "death_animation": "1342", + "name": "Dagannoth", + "defence_level": "1", + "safespot": null, + "lifepoints": "70", + "strength_level": "1", + "id": "2888", + "aggressive": "true", + "clue_level": "1", + "range_level": "1", + "projectile": "288", + "attack_level": "1" + }, + { + "examine": "It wasn't a rock... It was a rock lobster!", + "melee_animation": "2860", + "range_animation": "2860", + "combat_audio": "726,728,727", + "attack_speed": "2", + "defence_animation": "2861", + "weakness": "7", + "magic_animation": "2860", + "death_animation": "2862", + "name": "Rock lobster", + "defence_level": "100", + "safespot": null, + "movement_radius": "30", + "lifepoints": "150", + "strength_level": "100", + "id": "2889", + "bonuses": "0,0,0,0,0,100,100,50,50,150,0,0,0,0,0", + "range_level": "1", + "attack_level": "100" + }, + { + "examine": "A Rock.", + "melee_animation": "2860", + "range_animation": "2860", + "attack_speed": "2", + "defence_animation": "2861", + "weakness": "7", + "magic_animation": "2860", + "death_animation": "2861", + "name": "Large rock", + "defence_level": "100", + "safespot": null, + "lifepoints": "150", + "strength_level": "100", + "id": "2890", + "aggressive": "true", + "range_level": "1", + "attack_level": "100" + }, + { + "agg_radius": "12", + "examine": "A sneaky, spiny, subterranean sea-dwelling scamp.", + "combat_style": "2", + "melee_animation": "2868", + "range_animation": "2866", + "attack_speed": "6", + "magic_level": "65", + "spell_id": "14", + "respawn_delay": "55", + "defence_animation": "2869", + "slayer_exp": "0", + "magic_animation": "2866", + "death_animation": "2866", + "name": "Spinolyp", + "defence_level": "1", + "safespot": null, + "lifepoints": "75", + "strength_level": "10", + "id": "2892", + "aggressive": "true", + "bonuses": "70,50,60,50,10,60,30,10,60,60,70,50,0,0,0", + "range_level": "20", + "projectile": "294", + "attack_level": "1" + }, + { + "agg_radius": "12", + "examine": "A sneaky, spiny, subterranean sea-dwelling scamp.", + "combat_style": "2", + "melee_animation": "2868", + "range_animation": "2866", + "attack_speed": "6", + "magic_level": "65", + "spell_id": "14", + "respawn_delay": "55", + "defence_animation": "2869", + "magic_animation": "2866", + "death_animation": "2866", + "name": "Spinolyp", + "defence_level": "1", + "safespot": null, + "lifepoints": "75", + "strength_level": "10", + "id": "2894", + "aggressive": "true", + "bonuses": "70,50,60,50,10,60,30,10,60,60,70,50,0,0,0", + "range_level": "20", + "projectile": "294", + "attack_level": "1" + }, + { + "agg_radius": "12", + "examine": "A sneaky, spiny, subterranean sea-dwelling scamp.", + "combat_style": "2", + "melee_animation": "2868", + "range_animation": "2866", + "attack_speed": "6", + "magic_level": "65", + "spell_id": "14", + "respawn_delay": "55", + "defence_animation": "2869", + "slayer_exp": "0", + "magic_animation": "2866", + "death_animation": "2866", + "name": "Spinolyp", + "defence_level": "1", + "safespot": null, + "lifepoints": "75", + "strength_level": "60", + "id": "2896", + "aggressive": "true", + "bonuses": "70,50,60,50,10,60,30,10,60,60,70,50,0,0,0", + "range_level": "70", + "projectile": "294", + "attack_level": "1" + }, + { + "melee_animation": "64", + "respawn_delay": "60", + "defence_animation": "65", + "death_animation": "67", + "name": "Agrith Naar", + "defence_level": "1", + "safespot": null, + "lifepoints": "95", + "strength_level": "1", + "id": "2919", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "slayer_exp": "25", + "name": "Ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "436,439,438", + "strength_level": "1", + "id": "2931", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Who ate all the rats?", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "The Beast", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2941", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Lovely, cute, and possibly what dreams are made of.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Bones", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2945", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Obviously punches above his weight.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Hooknosed Jack", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2948", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Looks rich like an actor of sorts.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Jimmy Dazzler", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2949", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Once beautiful, now repugnant.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "The Face", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2950", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "What is he?", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Smokin' Joe", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2952", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Looks fairly well fed.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Silver merchant", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2958", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "2962", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "2963", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "2964", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "2965", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "2966", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "2967", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "2968", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "2969", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "2970", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "2971", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "2972", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "2973", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A popular dwarven delicacy.", + "melee_animation": "2705", + "range_animation": "2705", + "combat_audio": "703,705,704", + "attack_speed": "5", + "defence_animation": "2706", + "magic_animation": "2705", + "death_animation": "2707", + "name": "Rat", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "1", + "id": "2980", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A popular dwarven delicacy.", + "melee_animation": "2705", + "range_animation": "2705", + "combat_audio": "703,705,704", + "attack_speed": "5", + "defence_animation": "2706", + "magic_animation": "2705", + "death_animation": "2707", + "name": "Rat", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "1", + "id": "2981", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The master of all rats.", + "name": "King rat", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "703,705,704", + "strength_level": "1", + "id": "2982", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Not a soft touch.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Pusskins", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2984", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A not-so friendly, not-so little cat.", + "melee_animation": "0", + "range_animation": "0", + "attack_speed": "4", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Captain Tom", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2986", + "aggressive": "true", + "range_level": "1", + "attack_level": "10" + }, + { + "examine": "A fully grown feline.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Mittens", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2988", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Cute and fluffy.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Topsy", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2990", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A friendly feline?", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Gertrude's cat", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2997", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Very well to do. I wonder what he's doing here.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Gambler", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2998", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Rich.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Gambler", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3001", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Poor.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Gambler", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3002", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Poor.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Gambler", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3003", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Poor.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Gambler", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3004", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Poor.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Gambler", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3005", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Poor.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Gambler", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3006", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A popular dwarven delicacy.", + "melee_animation": "2705", + "range_animation": "2705", + "combat_audio": "703,705,704", + "attack_speed": "5", + "defence_animation": "2706", + "magic_animation": "2705", + "death_animation": "2707", + "name": "Rat", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "1", + "id": "3007", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A popular dwarven delicacy.", + "melee_animation": "2705", + "range_animation": "2705", + "combat_audio": "703,705,704", + "attack_speed": "5", + "defence_animation": "2706", + "magic_animation": "2705", + "death_animation": "2707", + "name": "Rat", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "1", + "id": "3008", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A popular dwarven delicacy.", + "melee_animation": "2705", + "range_animation": "2705", + "combat_audio": "703,705,704", + "attack_speed": "5", + "defence_animation": "2706", + "magic_animation": "2705", + "death_animation": "2707", + "name": "Rat", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "1", + "id": "3009", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A popular dwarven delicacy.", + "melee_animation": "2705", + "range_animation": "2705", + "combat_audio": "703,705,704", + "attack_speed": "5", + "defence_animation": "2706", + "magic_animation": "2705", + "death_animation": "2707", + "name": "Rat", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "1", + "id": "3010", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A popular dwarven delicacy.", + "melee_animation": "2705", + "range_animation": "2705", + "combat_audio": "703,705,704", + "attack_speed": "5", + "defence_animation": "2706", + "magic_animation": "2705", + "death_animation": "2707", + "name": "Rat", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "1", + "id": "3011", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A popular dwarven delicacy.", + "melee_animation": "2705", + "range_animation": "2705", + "combat_audio": "703,705,704", + "attack_speed": "5", + "defence_animation": "2706", + "magic_animation": "2705", + "death_animation": "2707", + "name": "Rat", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "1", + "id": "3012", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A popular dwarven delicacy.", + "melee_animation": "2705", + "range_animation": "2705", + "combat_audio": "703,705,704", + "attack_speed": "5", + "defence_animation": "2706", + "magic_animation": "2705", + "death_animation": "2707", + "name": "Rat", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "1", + "id": "3013", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A popular dwarven delicacy.", + "melee_animation": "2705", + "range_animation": "2705", + "combat_audio": "703,705,704", + "attack_speed": "5", + "defence_animation": "2706", + "magic_animation": "2705", + "death_animation": "2707", + "name": "Rat", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "1", + "id": "3014", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A popular dwarven delicacy.", + "melee_animation": "2705", + "range_animation": "2705", + "combat_audio": "703,705,704", + "attack_speed": "5", + "defence_animation": "2706", + "magic_animation": "2705", + "death_animation": "2707", + "name": "Rat", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "1", + "id": "3015", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A popular dwarven delicacy.", + "melee_animation": "2705", + "range_animation": "2705", + "combat_audio": "703,705,704", + "attack_speed": "5", + "defence_animation": "2706", + "magic_animation": "2705", + "death_animation": "2707", + "name": "Rat", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "1", + "id": "3016", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A popular dwarven delicacy.", + "melee_animation": "2705", + "range_animation": "2705", + "combat_audio": "703,705,704", + "attack_speed": "5", + "defence_animation": "2706", + "magic_animation": "2705", + "death_animation": "2707", + "name": "Rat", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "1", + "id": "3017", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A popular dwarven delicacy.", + "melee_animation": "2705", + "range_animation": "2705", + "combat_audio": "703,705,704", + "attack_speed": "5", + "defence_animation": "2706", + "magic_animation": "2705", + "death_animation": "2707", + "name": "Rat", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "1", + "id": "3018", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Looks after your Farming tools.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Tool leprechaun", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3021", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Phenomenal cosmic powers", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Genie", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3022", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An animated clay statue.", + "melee_animation": "2917", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "2", + "magic_animation": "0", + "death_animation": "2919", + "name": "Black golem", + "defence_level": "55", + "safespot": null, + "lifepoints": "78", + "strength_level": "55", + "id": "3026", + "aggressive": "true", + "range_level": "1", + "attack_level": "55" + }, + { + "examine": "An animated clay statue.", + "melee_animation": "2917", + "range_animation": "0", + "defence_animation": "0", + "weakness": "0", + "magic_animation": "0", + "death_animation": "2919", + "name": "White golem", + "defence_level": "55", + "safespot": null, + "lifepoints": "78", + "strength_level": "55", + "id": "3027", + "aggressive": "true", + "range_level": "1", + "attack_level": "55" + }, + { + "examine": "An animated clay statue.", + "melee_animation": "2917", + "range_animation": "0", + "defence_animation": "0", + "weakness": "1", + "magic_animation": "0", + "death_animation": "2919", + "name": "Grey golem", + "defence_level": "55", + "safespot": null, + "lifepoints": "78", + "strength_level": "55", + "id": "3028", + "aggressive": "true", + "range_level": "1", + "attack_level": "55" + }, + { + "examine": "The oldest man in Nardah.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ghaslor the Elder", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3029", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A water salesman from Pollnivneach.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ali the Carter", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3030", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The Mayor of Nardah.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Awusah the Mayor", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3040", + "range_level": "1", + "attack_level": "1" + }, + { + "death_animation": "836", + "name": "Poltenip", + "defence_level": "1", + "safespot": null, + "lifepoints": "22", + "melee_animation": "395", + "strength_level": "1", + "id": "3042", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1", + "defence_animation": "425" + }, + { + "death_animation": "836", + "name": "Radat", + "defence_level": "1", + "safespot": null, + "lifepoints": "22", + "melee_animation": "395", + "strength_level": "1", + "id": "3043", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1", + "defence_animation": "425" + }, + { + "examine": "Custodian of the shrine to Elidinis.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "703,705,704", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Shiratti the Custodian", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3044", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A banker of Nardah.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Nardah Banker", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3046", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A mysterious watcher.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Mystery figure", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3051", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A mysterious watcher.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Mystery figure", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3052", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A mysterious watcher.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Mystery figure", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3053", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A mysterious watcher.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Mystery figure", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3054", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A mysterious watcher.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Mystery figure", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3055", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A mysterious watcher.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Mystery figure", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3056", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Champion of the earth warriors.", + "melee_animation": "2951", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "2946", + "name": "Earth Warrior Champion", + "defence_level": "84", + "safespot": null, + "lifepoints": "108", + "strength_level": "84", + "id": "3057", + "aggressive": "true", + "range_level": "1", + "attack_level": "84" + }, + { + "examine": "Champion of the giants.", + "melee_animation": "6368", + "range_animation": "0", + "attack_speed": "4", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "slayer_exp": "35", + "magic_animation": "0", + "death_animation": "6369", + "name": "Giant Champion", + "defence_level": "52", + "safespot": null, + "lifepoints": "70", + "strength_level": "44", + "id": "3058", + "aggressive": "true", + "range_level": "1", + "attack_level": "36" + }, + { + "examine": "Champion of the ghouls.", + "melee_animation": "422", + "range_animation": "0", + "combat_audio": "441,444,443", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "slayer_exp": "50", + "magic_animation": "0", + "death_animation": "836", + "name": "Ghoul Champion", + "defence_level": "60", + "safespot": null, + "lifepoints": "100", + "strength_level": "80", + "id": "3059", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "60", + "attack_level": "60" + }, + { + "examine": "Champion of the goblins.", + "melee_animation": "6188", + "range_animation": "0", + "combat_audio": "469,472,471", + "attack_speed": "4", + "magic_level": "26", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "6190", + "name": "Goblin Champion", + "defence_level": "14", + "safespot": null, + "lifepoints": "32", + "strength_level": "1", + "id": "3060", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Champion of the hobgoblins.", + "combat_style": "1", + "melee_animation": "164", + "range_animation": "164", + "combat_audio": "469,472,471", + "attack_speed": "4", + "respawn_delay": "60", + "defence_animation": "165", + "weakness": "0", + "magic_animation": "164", + "death_animation": "167", + "name": "Hobgoblin Champion", + "defence_level": "48", + "safespot": null, + "lifepoints": "58", + "strength_level": "48", + "id": "3061", + "aggressive": "true", + "range_level": "44", + "attack_level": "44" + }, + { + "examine": "Champion of the imps.", + "melee_animation": "5285", + "range_animation": "0", + "attack_speed": "4", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "172", + "name": "Imp Champion", + "defence_level": "5", + "safespot": null, + "lifepoints": "40", + "strength_level": "5", + "id": "3062", + "aggressive": "true", + "range_level": "5", + "attack_level": "5" + }, + { + "examine": "Champion of the jogres.", + "melee_animation": "2936", + "range_animation": "2936", + "poisonous": "true", + "respawn_delay": "60", + "defence_animation": "2937", + "weakness": "9", + "magic_animation": "2936", + "death_animation": "2938", + "name": "Jogre Champion", + "defence_level": "86", + "safespot": null, + "lifepoints": "120", + "strength_level": "86", + "id": "3063", + "aggressive": "true", + "range_level": "1", + "attack_level": "86" + }, + { + "examine": "Champion of the lesser demons.", + "melee_animation": "64", + "range_animation": "0", + "combat_audio": "396,402,401", + "magic_level": "136", + "respawn_delay": "60", + "defence_animation": "65", + "weakness": "5", + "slayer_exp": "79", + "magic_animation": "0", + "death_animation": "67", + "name": "Lesser Demon Champion", + "defence_level": "142", + "safespot": null, + "lifepoints": "148", + "strength_level": "140", + "id": "3064", + "aggressive": "true", + "range_level": "1", + "attack_level": "136" + }, + { + "examine": "Champion of the jogres.", + "melee_animation": "5485", + "range_animation": "5493", + "poisonous": "true", + "respawn_delay": "60", + "defence_animation": "5493", + "weakness": "9", + "magic_animation": "0", + "death_animation": "1444", + "name": "Skeleton Champion", + "defence_level": "54", + "safespot": null, + "lifepoints": "58", + "strength_level": "1", + "id": "3065", + "aggressive": "true", + "range_level": "36", + "attack_level": "1" + }, + { + "examine": "Champion of the zombies.", + "melee_animation": "5581", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "5575", + "name": "Zombies Champion", + "defence_level": "26", + "safespot": null, + "lifepoints": "37", + "strength_level": "26", + "id": "3066", + "aggressive": "true", + "range_level": "1", + "attack_level": "26" + }, + { + "melee_animation": "7049", + "respawn_delay": "60", + "defence_animation": "7050", + "death_animation": "836", + "name": "Leon d'Cour", + "defence_level": "1", + "safespot": null, + "lifepoints": "123", + "strength_level": "1", + "id": "3067", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A very dangerous pile of animated Wyvern bones.", + "start_gfx": "499", + "melee_animation": "2985", + "attack_speed": "6", + "weakness": "9", + "slayer_exp": "210", + "magic_animation": "2985", + "death_animation": "2987", + "lifepoints": "200", + "id": "3068", + "aggressive": "true", + "bonuses": "0,0,0,0,0,140,90,90,80,140,0,0,0,0,0", + "agg_radius": "6", + "range_animation": "2989", + "combat_audio": "0,771,770", + "magic_level": "125", + "end_gfx": "501", + "defence_animation": "2983", + "name": "Skeletal Wyvern", + "defence_level": "120", + "safespot": null, + "strength_level": "116", + "clue_level": "2", + "range_level": "120", + "projectile": "500", + "attack_level": "125" + }, + { + "examine": "A very dangerous pile of animated Wyvern bones.", + "start_gfx": "499", + "melee_animation": "2985", + "attack_speed": "6", + "weakness": "9", + "slayer_exp": "210", + "magic_animation": "2985", + "death_animation": "2987", + "lifepoints": "200", + "id": "3069", + "aggressive": "true", + "bonuses": "0,0,0,0,0,140,90,90,80,140,0,0,0,0,0", + "agg_radius": "6", + "range_animation": "2989", + "combat_audio": "0,771,770", + "magic_level": "125", + "end_gfx": "501", + "defence_animation": "2983", + "name": "Skeletal Wyvern", + "defence_level": "120", + "safespot": null, + "strength_level": "116", + "clue_level": "2", + "range_level": "120", + "projectile": "500", + "attack_level": "125" + }, + { + "examine": "A very dangerous pile of animated Wyvern bones.", + "start_gfx": "499", + "melee_animation": "2985", + "attack_speed": "6", + "weakness": "9", + "slayer_exp": "210", + "magic_animation": "2985", + "death_animation": "2987", + "lifepoints": "200", + "id": "3070", + "aggressive": "true", + "bonuses": "0,0,0,0,0,140,90,90,80,140,0,0,0,0,0", + "agg_radius": "6", + "range_animation": "2989", + "combat_audio": "0,771,770", + "magic_level": "125", + "end_gfx": "501", + "defence_animation": "2983", + "name": "Skeletal Wyvern", + "defence_level": "120", + "safespot": null, + "strength_level": "116", + "clue_level": "2", + "range_level": "120", + "projectile": "500", + "attack_level": "125" + }, + { + "examine": "A very dangerous pile of animated Wyvern bones.", + "start_gfx": "499", + "melee_animation": "2985", + "attack_speed": "6", + "weakness": "9", + "slayer_exp": "210", + "magic_animation": "2985", + "death_animation": "2987", + "lifepoints": "200", + "id": "3071", + "aggressive": "true", + "bonuses": "0,0,0,0,0,140,90,90,80,140,0,0,0,0,0", + "agg_radius": "6", + "range_animation": "2989", + "combat_audio": "0,771,770", + "magic_level": "125", + "end_gfx": "501", + "defence_animation": "2983", + "name": "Skeletal Wyvern", + "defence_level": "120", + "safespot": null, + "strength_level": "116", + "clue_level": "2", + "range_level": "120", + "projectile": "500", + "attack_level": "125" + }, + { + "examine": "He's got icicles in his beard.", + "melee_animation": "4672", + "range_animation": "0", + "combat_audio": "448,451,450", + "attack_speed": "5", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "0", + "weakness": "9", + "slayer_exp": "70", + "magic_animation": "0", + "death_animation": "4673", + "name": "Ice giant", + "defence_level": "40", + "safespot": null, + "lifepoints": "70", + "strength_level": "40", + "id": "3072", + "aggressive": "true", + "bonuses": "29,29,29,0,0,0,3,2,0,0,0,31,0,0,0", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "A cold-hearted elemental warrior.", + "melee_animation": "451", + "range_animation": "451", + "combat_audio": "2500,530,529", + "attack_speed": "4", + "respawn_delay": "30", + "defence_animation": "404", + "weakness": "9", + "slayer_exp": "59", + "magic_animation": "451", + "death_animation": "843", + "name": "Ice warrior", + "defence_level": "47", + "safespot": null, + "lifepoints": "59", + "strength_level": "47", + "id": "3073", + "aggressive": "true", + "bonuses": "0,0,0,0,0,30,40,20,10,30,0,0,0,0,0", + "clue_level": "1", + "range_level": "1", + "attack_level": "47" + }, + { + "name": "Monk", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "3074", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Monk", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "3075", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Monk", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "3079", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Monk", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "3080", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "3089", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A mighty warrior", + "melee_animation": "7048", + "range_animation": "0", + "combat_audio": "511,513,512", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "836", + "name": "", + "defence_level": "17", + "safespot": null, + "lifepoints": "24", + "strength_level": "17", + "id": "3090", + "aggressive": "true", + "range_level": "1", + "attack_level": "17" + }, + { + "name": "", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "3091", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The book moves by itself!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Flying Book", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3094", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A guardian of the arena.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Entrance Guardian", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3097", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A guardian of the arena.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Telekinetic Guardian", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3098", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A guardian of the arena.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Alchemy Guardian", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3099", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A guardian of the arena.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Enchantment Guardian", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3100", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A guardian of the arena.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Graveyard Guardian", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3101", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A guardian of the arena.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Maze Guardian", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3102", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A guardian of the arena.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Rewards Guardian", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3103", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Equipment that moves by itself!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Charmed Warrior", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3104", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Equipment that moves by itself!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Charmed Warrior", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3105", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Equipment that moves by itself!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Charmed Warrior", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3106", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "This guard looks rather drunk and has beer stains down his armour.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Guard Captain", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3109", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Looks after farming tools.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Balloon Animal", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3121", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "I saw the witchdoctor", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Balloon Animal", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3122", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Looks like he's seen the inside of a few tombs.", + "melee_animation": "422", + "range_animation": "422", + "attack_speed": "5", + "defence_animation": "404", + "magic_animation": "422", + "death_animation": "9055", + "name": "Simon Templeton", + "defence_level": "1", + "safespot": "0", + "lifepoints": "12", + "strength_level": "1", + "id": "3123", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It seems to be blocked.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "703,705,704", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Furnace grate", + "defence_level": "1", + "safespot": null, + "lifepoints": "0", + "strength_level": "1", + "id": "3135", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Knight", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "3150", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A swarm of bugs.", + "melee_animation": "1584", + "range_animation": "0", + "combat_audio": "2743,2745,2744", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "25", + "defence_animation": "0", + "weakness": "2", + "slayer_exp": "25", + "magic_animation": "0", + "death_animation": "1585", + "name": "Harpie Bug Swarm", + "defence_level": "32", + "safespot": null, + "lifepoints": "25", + "strength_level": "46", + "id": "3153", + "aggressive": "true", + "bonuses": "0,0,0,0,0,10,5,10,5,10,0,0,0,0,0", + "clue_level": "1", + "range_level": "1", + "attack_level": "54" + }, + { + "examine": "Bill Teach the pirate.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Bill Teach", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3155", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "703,705,704", + "strength_level": "1", + "id": "3167", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "703,705,704", + "strength_level": "1", + "id": "3168", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "703,705,704", + "strength_level": "1", + "id": "3169", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "703,705,704", + "strength_level": "1", + "id": "3170", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "703,705,704", + "strength_level": "1", + "id": "3171", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "703,705,704", + "strength_level": "1", + "id": "3172", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "703,705,704", + "strength_level": "1", + "id": "3173", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "703,705,704", + "strength_level": "1", + "id": "3174", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "703,705,704", + "strength_level": "1", + "id": "3175", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "703,705,704", + "strength_level": "1", + "id": "3176", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "703,705,704", + "strength_level": "1", + "id": "3177", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "703,705,704", + "strength_level": "1", + "id": "3178", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "703,705,704", + "strength_level": "1", + "id": "3179", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "703,705,704", + "strength_level": "1", + "id": "3180", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "703,705,704", + "strength_level": "1", + "id": "3181", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "703,705,704", + "strength_level": "1", + "id": "3182", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "703,705,704", + "strength_level": "1", + "id": "3183", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "703,705,704", + "strength_level": "1", + "id": "3184", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "703,705,704", + "strength_level": "1", + "id": "3185", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "703,705,704", + "strength_level": "1", + "id": "3186", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "422", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "52", + "strength_level": "1", + "id": "3187", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Arghh matey!", + "combat_audio": "703,705,704", + "attack_speed": "5", + "respawn_delay": "20", + "defence_animation": "388", + "death_animation": "9055", + "name": "Pirate", + "defence_level": "40", + "safespot": null, + "lifepoints": "45", + "strength_level": "40", + "id": "3188", + "bonuses": "10,10,10,10,10,10,10,10,10,10,10,10,10,10,10", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "Arghh matey!", + "combat_audio": "703,705,704", + "attack_speed": "5", + "respawn_delay": "20", + "defence_animation": "388", + "death_animation": "9055", + "name": "Pirate", + "defence_level": "40", + "safespot": null, + "lifepoints": "45", + "strength_level": "40", + "id": "3189", + "bonuses": "10,10,10,10,10,10,10,10,10,10,10,10,10,10,10", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "Arghh matey!", + "combat_audio": "703,705,704", + "attack_speed": "5", + "respawn_delay": "20", + "defence_animation": "388", + "death_animation": "9055", + "name": "Pirate", + "defence_level": "40", + "safespot": null, + "lifepoints": "45", + "strength_level": "40", + "id": "3190", + "bonuses": "10,10,10,10,10,10,10,10,10,10,10,10,10,10,10", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "Arghh matey!", + "combat_audio": "703,705,704", + "attack_speed": "5", + "respawn_delay": "20", + "defence_animation": "388", + "death_animation": "9055", + "name": "Pirate", + "defence_level": "40", + "safespot": null, + "lifepoints": "45", + "strength_level": "40", + "id": "3191", + "bonuses": "10,10,10,10,10,10,10,10,10,10,10,10,10,10,10", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "Arghh matey!", + "combat_audio": "703,705,704", + "attack_speed": "5", + "respawn_delay": "20", + "defence_animation": "388", + "death_animation": "9055", + "name": "Pirate", + "defence_level": "40", + "safespot": null, + "lifepoints": "45", + "strength_level": "40", + "id": "3192", + "bonuses": "10,10,10,10,10,10,10,10,10,10,10,10,10,10,10", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "Arghh matey!", + "combat_audio": "703,705,704", + "attack_speed": "5", + "respawn_delay": "20", + "defence_animation": "388", + "death_animation": "9055", + "name": "Pirate", + "defence_level": "40", + "safespot": null, + "lifepoints": "45", + "strength_level": "40", + "id": "3193", + "bonuses": "10,10,10,10,10,10,10,10,10,10,10,10,10,10,10", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "Arghh matey!", + "combat_audio": "703,705,704", + "attack_speed": "5", + "respawn_delay": "20", + "defence_animation": "388", + "death_animation": "9055", + "name": "Pirate", + "defence_level": "40", + "safespot": null, + "lifepoints": "45", + "strength_level": "40", + "id": "3194", + "bonuses": "10,10,10,10,10,10,10,10,10,10,10,10,10,10,10", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "Arghh matey!", + "combat_audio": "703,705,704", + "attack_speed": "5", + "respawn_delay": "20", + "defence_animation": "388", + "death_animation": "9055", + "name": "Pirate", + "defence_level": "40", + "safespot": null, + "lifepoints": "45", + "strength_level": "40", + "id": "3195", + "bonuses": "10,10,10,10,10,10,10,10,10,10,10,10,10,10,10", + "range_level": "1", + "attack_level": "40" + }, + { + "melee_animation": "400", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "52", + "strength_level": "1", + "id": "3196", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He can look after my money.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Banker", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3198", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He can look after my money.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Banker", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3199", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "pUre A cHaOs of crEatuRe!", + "start_gfx": "556", + "melee_animation": "3146", + "attack_speed": "5", + "respawn_delay": "100", + "weakness": "4", + "magic_animation": "5443", + "death_animation": "3147", + "lifepoints": "250", + "id": "3200", + "aggressive": "true", + "bonuses": "0,0,0,0,0,70,70,70,70,70,0,0,0,0,0", + "agg_radius": "16", + "range_animation": "5443", + "combat_audio": "345,351,347", + "magic_level": "270", + "end_gfx": "558", + "defence_animation": "3149", + "name": "Chaos Elemental", + "defence_level": "270", + "movement_radius": "30", + "safespot": "true", + "strength_level": "270", + "range_level": "270", + "projectile": "557", + "attack_level": "270" + }, + { + "slayer_exp": "51", + "name": "Killerwatt", + "defence_level": "1", + "safespot": null, + "lifepoints": "51", + "strength_level": "1", + "attack_speed": "3", + "id": "3201", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "slayer_exp": "51", + "name": "Killerwatt", + "defence_level": "1", + "safespot": null, + "lifepoints": "51", + "strength_level": "1", + "attack_speed": "3", + "id": "3202", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "examine": "A very small storm!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Storm Cloud", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3203", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A very small storm!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Storm Cloud", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3204", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Loves mining.", + "melee_animation": "99", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "slayer_exp": "16", + "magic_animation": "0", + "death_animation": "102", + "name": "Dwarf", + "defence_level": "28", + "safespot": null, + "lifepoints": "40", + "strength_level": "28", + "id": "3219", + "range_level": "1", + "attack_level": "28" + }, + { + "examine": "Loves mining.", + "melee_animation": "99", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "slayer_exp": "16", + "magic_animation": "0", + "death_animation": "102", + "name": "Dwarf", + "defence_level": "32", + "safespot": null, + "lifepoints": "45", + "strength_level": "32", + "id": "3220", + "range_level": "1", + "attack_level": "32" + }, + { + "examine": "Loves mining.", + "melee_animation": "99", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "slayer_exp": "16", + "magic_animation": "0", + "death_animation": "102", + "name": "Dwarf", + "defence_level": "28", + "safespot": null, + "lifepoints": "40", + "strength_level": "28", + "id": "3221", + "range_level": "1", + "attack_level": "28" + }, + { + "examine": "One of Gielinor's many citizens.", + "melee_animation": "422", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Man", + "defence_level": "3", + "safespot": null, + "lifepoints": "4", + "strength_level": "3", + "id": "3223", + "range_level": "1", + "attack_level": "3" + }, + { + "name": "Man", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "3224", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of Gielinor's many citizens. He looks worried about something.", + "melee_animation": "422", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Man", + "defence_level": "3", + "safespot": null, + "lifepoints": "4", + "strength_level": "3", + "id": "3225", + "clue_level": "0", + "range_level": "1", + "attack_level": "3" + }, + { + "melee_animation": "422", + "combat_audio": "511,506,505", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Woman", + "defence_level": "1", + "safespot": null, + "lifepoints": "9", + "strength_level": "1", + "id": "3226", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Woman", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,506,505", + "strength_level": "1", + "id": "3227", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He tries to keep order around here.", + "melee_animation": "386", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "404", + "weakness": "7", + "magic_animation": "0", + "death_animation": "836", + "name": "Guard", + "defence_level": "13", + "safespot": null, + "lifepoints": "18", + "strength_level": "13", + "id": "3228", + "clue_level": "1", + "range_level": "1", + "attack_level": "13" + }, + { + "examine": "He tries to keep order around here.", + "melee_animation": "4230", + "range_animation": "2075", + "combat_audio": "511,513,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "404", + "weakness": "0", + "magic_animation": "0", + "death_animation": "836", + "name": "Guard", + "defence_level": "13", + "safespot": null, + "lifepoints": "18", + "strength_level": "1", + "id": "3229", + "clue_level": "1", + "range_level": "13", + "attack_level": "1" + }, + { + "examine": "He tries to keep order around here.", + "melee_animation": "395", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "404", + "weakness": "7", + "magic_animation": "0", + "death_animation": "836", + "name": "Guard", + "defence_level": "13", + "safespot": null, + "lifepoints": "18", + "strength_level": "13", + "id": "3230", + "clue_level": "1", + "range_level": "1", + "attack_level": "13" + }, + { + "examine": "He tries to keep order around here.", + "melee_animation": "422", + "range_animation": "426", + "combat_audio": "511,513,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "0", + "magic_animation": "0", + "death_animation": "836", + "name": "Guard", + "defence_level": "13", + "safespot": null, + "lifepoints": "18", + "strength_level": "1", + "id": "3231", + "clue_level": "1", + "range_level": "13", + "attack_level": "1" + }, + { + "examine": "Keeping an eye out for threats to the city.", + "melee_animation": "422", + "range_animation": "426", + "combat_audio": "511,513,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "0", + "magic_animation": "0", + "death_animation": "836", + "name": "Guard", + "defence_level": "13", + "safespot": null, + "lifepoints": "18", + "strength_level": "1", + "id": "3232", + "clue_level": "1", + "range_level": "13", + "attack_level": "1" + }, + { + "examine": "Keeping an eye out for threats to the city.", + "melee_animation": "422", + "range_animation": "426", + "combat_audio": "511,513,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "0", + "magic_animation": "0", + "death_animation": "836", + "name": "Guard", + "defence_level": "13", + "safespot": null, + "lifepoints": "18", + "strength_level": "1", + "id": "3233", + "clue_level": "1", + "range_level": "13", + "attack_level": "1" + }, + { + "examine": "An old gardener.", + "melee_animation": "433", + "range_animation": "0", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "836", + "name": "Gardener", + "defence_level": "4", + "safespot": null, + "lifepoints": "5", + "strength_level": "4", + "id": "3234", + "range_level": "1", + "attack_level": "4" + }, + { + "examine": "He's learning a trade.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Apprentice workman", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3235", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A busy workman", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Workman", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3236", + "range_level": "1", + "attack_level": "1" + }, + { + "agg_radius": "", + "examine": "He looks a bit dodgy.", + "melee_animation": "422", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Cuffs", + "defence_level": "1", + "safespot": null, + "lifepoints": "7", + "strength_level": "1", + "id": "3237", + "range_level": "1", + "attack_level": "1" + }, + { + "agg_radius": "", + "examine": "Looks unpleasant.", + "melee_animation": "422", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Narf", + "defence_level": "1", + "safespot": null, + "lifepoints": "7", + "strength_level": "1", + "id": "3238", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Seems to be loitering.", + "melee_animation": "422", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Rusty", + "defence_level": "1", + "safespot": null, + "lifepoints": "7", + "strength_level": "1", + "id": "3239", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Untrustworthy.", + "melee_animation": "422", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Jeff", + "defence_level": "1", + "safespot": null, + "lifepoints": "7", + "strength_level": "1", + "id": "3240", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "395", + "combat_audio": "511,513,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "404", + "death_animation": "836", + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "22", + "strength_level": "1", + "id": "3241", + "aggressive": "true", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A practicer of dark arts.", + "combat_style": "2", + "melee_animation": "422", + "range_animation": "0", + "combat_audio": "511,513,512", + "magic_level": "25", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "4", + "magic_animation": "711", + "death_animation": "836", + "name": "Dark wizard", + "defence_level": "25", + "safespot": null, + "lifepoints": "30", + "strength_level": "1", + "id": "3242", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A practicer of dark arts.", + "combat_style": "2", + "melee_animation": "422", + "range_animation": "0", + "combat_audio": "511,513,512", + "magic_level": "27", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "4", + "magic_animation": "711", + "death_animation": "836", + "name": "Dark wizard", + "defence_level": "27", + "safespot": null, + "lifepoints": "38", + "strength_level": "1", + "id": "3243", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A practicer of dark arts.", + "combat_style": "2", + "melee_animation": "422", + "range_animation": "0", + "combat_audio": "511,513,512", + "magic_level": "16", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "4", + "magic_animation": "711", + "death_animation": "836", + "name": "Dark wizard", + "defence_level": "16", + "safespot": null, + "lifepoints": "22", + "strength_level": "1", + "id": "3244", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A practicer of dark arts.", + "combat_style": "2", + "melee_animation": "422", + "range_animation": "0", + "combat_audio": "511,513,512", + "magic_level": "16", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "4", + "magic_animation": "711", + "death_animation": "836", + "name": "Dark wizard", + "defence_level": "16", + "safespot": null, + "lifepoints": "22", + "strength_level": "1", + "id": "3245", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Alberich, a fierce barbarian warrior.", + "melee_animation": "2067", + "range_animation": "0", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "836", + "name": "Barbarian", + "defence_level": "22", + "safespot": null, + "lifepoints": "31", + "strength_level": "22", + "id": "3246", + "clue_level": "0", + "range_level": "1", + "attack_level": "22" + }, + { + "examine": "Fafner, a tough barbarian warrior.", + "melee_animation": "7048", + "range_animation": "7048", + "attack_speed": "6", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "7048", + "death_animation": "836", + "name": "Barbarian", + "defence_level": "22", + "safespot": null, + "lifepoints": "18", + "strength_level": "22", + "id": "3247", + "clue_level": "0", + "range_level": "1", + "attack_level": "22" + }, + { + "examine": "Fasolt, a strong barbarian warrior.", + "melee_animation": "2067", + "range_animation": "0", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "836", + "name": "Barbarian", + "defence_level": "22", + "safespot": null, + "lifepoints": "31", + "strength_level": "22", + "id": "3248", + "clue_level": "0", + "range_level": "1", + "attack_level": "22" + }, + { + "examine": "Siegmund, a guard in the Barbarian Village.", + "melee_animation": "401", + "range_animation": "0", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "836", + "name": "Barbarian", + "defence_level": "22", + "safespot": null, + "lifepoints": "31", + "strength_level": "22", + "id": "3249", + "clue_level": "0", + "range_level": "1", + "attack_level": "22" + }, + { + "examine": "Siegfried, a young guard in the Barbarian Village.", + "melee_animation": "2067", + "range_animation": "0", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "836", + "name": "Barbarian", + "defence_level": "22", + "safespot": null, + "lifepoints": "31", + "strength_level": "22", + "id": "3250", + "clue_level": "0", + "range_level": "1", + "attack_level": "22" + }, + { + "examine": "Lydspor, a well-traveld barbarian warrior.", + "melee_animation": "7048", + "range_animation": "0", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "836", + "name": "Barbarian", + "defence_level": "22", + "safespot": null, + "lifepoints": "31", + "strength_level": "22", + "id": "3251", + "clue_level": "0", + "range_level": "1", + "attack_level": "22" + }, + { + "examine": "Hagen, a guard in the Barbarian Village.", + "melee_animation": "2067", + "range_animation": "0", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "836", + "name": "Barbarian", + "defence_level": "22", + "safespot": null, + "lifepoints": "31", + "strength_level": "22", + "id": "3252", + "clue_level": "0", + "range_level": "1", + "attack_level": "22" + }, + { + "examine": "Minarch, a barbarian who likes his beer.", + "melee_animation": "401", + "range_animation": "0", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "836", + "name": "Barbarian", + "defence_level": "22", + "safespot": null, + "lifepoints": "31", + "strength_level": "22", + "id": "3253", + "clue_level": "0", + "range_level": "1", + "attack_level": "22" + }, + { + "examine": "Wotan, a sturdy barbarian warrior.", + "melee_animation": "401", + "range_animation": "0", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "836", + "name": "Barbarian", + "defence_level": "22", + "safespot": null, + "lifepoints": "31", + "strength_level": "22", + "id": "3255", + "clue_level": "0", + "range_level": "1", + "attack_level": "22" + }, + { + "examine": "Acelin, a guard in the Barbarian Village.", + "melee_animation": "390", + "range_animation": "0", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "836", + "name": "Barbarian", + "defence_level": "22", + "safespot": null, + "lifepoints": "31", + "strength_level": "22", + "id": "3256", + "clue_level": "0", + "range_level": "1", + "attack_level": "22" + }, + { + "examine": "Adelino, a barbarian warrior with a big axe.", + "melee_animation": "2067", + "range_animation": "0", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "836", + "name": "Barbarian", + "defence_level": "22", + "safespot": null, + "lifepoints": "31", + "strength_level": "22", + "id": "3257", + "clue_level": "0", + "range_level": "1", + "attack_level": "22" + }, + { + "examine": "Adolpho, a barbarian warrior with a warhammer.", + "melee_animation": "401", + "range_animation": "0", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "836", + "name": "Barbarian", + "defence_level": "22", + "safespot": null, + "lifepoints": "31", + "strength_level": "22", + "id": "3258", + "clue_level": "0", + "range_level": "1", + "attack_level": "22" + }, + { + "examine": "Aitan, a barbarian archer.", + "melee_animation": "426", + "range_animation": "426", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "836", + "name": "Barbarian", + "defence_level": "22", + "safespot": null, + "lifepoints": "31", + "strength_level": "22", + "id": "3259", + "clue_level": "0", + "range_level": "1", + "attack_level": "22" + }, + { + "examine": "Brunnhilde, a fierce barbarian warrior.", + "melee_animation": "428", + "range_animation": "0", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "836", + "name": "Barbarian", + "defence_level": "20", + "safespot": null, + "lifepoints": "28", + "strength_level": "20", + "id": "3260", + "clue_level": "0", + "range_level": "1", + "attack_level": "20" + }, + { + "examine": "Gutrune, a mighty barbarian warrior.", + "melee_animation": "428", + "range_animation": "0", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "836", + "name": "Barbarian", + "defence_level": "20", + "safespot": null, + "lifepoints": "28", + "strength_level": "20", + "id": "3261", + "clue_level": "0", + "range_level": "1", + "attack_level": "20" + }, + { + "examine": "Edelschwarz, a barbarian warrior with a spear.", + "melee_animation": "428", + "range_animation": "0", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "836", + "name": "Barbarian", + "defence_level": "20", + "safespot": null, + "lifepoints": "28", + "strength_level": "20", + "id": "3262", + "clue_level": "0", + "range_level": "1", + "attack_level": "20" + }, + { + "examine": "Sieglinde, a muscular barbarian warrior.", + "melee_animation": "428", + "range_animation": "428", + "attack_speed": "6", + "defence_animation": "404", + "weakness": "8", + "magic_animation": "428", + "death_animation": "836", + "name": "Barbarian", + "defence_level": "22", + "safespot": null, + "lifepoints": "20", + "strength_level": "20", + "id": "3263", + "clue_level": "0", + "range_level": "1", + "attack_level": "22" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "3264", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "3265", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "3266", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "470,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "3267", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A dwarven worker.", + "melee_animation": "99", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "slayer_exp": "16", + "magic_animation": "0", + "death_animation": "102", + "name": "Dwarf", + "defence_level": "10", + "safespot": null, + "lifepoints": "14", + "strength_level": "10", + "id": "3268", + "range_level": "1", + "attack_level": "10" + }, + { + "examine": "A dwarven worker.", + "melee_animation": "99", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "slayer_exp": "16", + "magic_animation": "0", + "death_animation": "102", + "name": "Dwarf", + "defence_level": "10", + "safespot": null, + "lifepoints": "14", + "strength_level": "10", + "id": "3269", + "range_level": "1", + "attack_level": "10" + }, + { + "examine": "A dwarven worker.", + "melee_animation": "99", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "slayer_exp": "16", + "magic_animation": "0", + "death_animation": "102", + "name": "Dwarf", + "defence_level": "10", + "safespot": null, + "lifepoints": "14", + "strength_level": "10", + "id": "3270", + "range_level": "1", + "attack_level": "10" + }, + { + "examine": "A dwarven worker.", + "melee_animation": "99", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "slayer_exp": "16", + "magic_animation": "0", + "death_animation": "102", + "name": "Dwarf", + "defence_level": "10", + "safespot": null, + "lifepoints": "14", + "strength_level": "10", + "id": "3271", + "range_level": "1", + "attack_level": "10" + }, + { + "examine": "A dwarven worker.", + "melee_animation": "99", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "slayer_exp": "16", + "magic_animation": "0", + "death_animation": "102", + "name": "Dwarf", + "defence_level": "10", + "safespot": null, + "lifepoints": "14", + "strength_level": "10", + "id": "3272", + "range_level": "1", + "attack_level": "10" + }, + { + "examine": "A dwarven worker.", + "melee_animation": "99", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "slayer_exp": "16", + "magic_animation": "0", + "death_animation": "102", + "name": "Dwarf", + "defence_level": "10", + "safespot": null, + "lifepoints": "14", + "strength_level": "10", + "id": "3273", + "range_level": "1", + "attack_level": "10" + }, + { + "examine": "A dwarven worker.", + "melee_animation": "99", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "slayer_exp": "16", + "magic_animation": "0", + "death_animation": "102", + "name": "Dwarf", + "defence_level": "10", + "safespot": null, + "lifepoints": "14", + "strength_level": "10", + "id": "3274", + "range_level": "1", + "attack_level": "10" + }, + { + "examine": "A dwarven worker.", + "melee_animation": "99", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "slayer_exp": "16", + "magic_animation": "0", + "death_animation": "102", + "name": "Dwarf", + "defence_level": "10", + "safespot": null, + "lifepoints": "14", + "strength_level": "10", + "id": "3275", + "range_level": "1", + "attack_level": "10" + }, + { + "examine": "A member of the Black Guard", + "melee_animation": "99", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "slayer_exp": "16", + "magic_animation": "0", + "death_animation": "102", + "name": "Black Guard", + "defence_level": "30", + "safespot": null, + "lifepoints": "42", + "strength_level": "30", + "id": "3276", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "A member of the Black Guard", + "melee_animation": "99", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "slayer_exp": "16", + "magic_animation": "0", + "death_animation": "102", + "name": "Black Guard", + "defence_level": "30", + "safespot": null, + "lifepoints": "42", + "strength_level": "30", + "id": "3277", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "A member of the Black Guard", + "melee_animation": "99", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "slayer_exp": "16", + "magic_animation": "0", + "death_animation": "102", + "name": "Black Guard", + "defence_level": "30", + "safespot": null, + "lifepoints": "42", + "strength_level": "30", + "id": "3278", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "A member of the Black Guard", + "melee_animation": "99", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "slayer_exp": "16", + "magic_animation": "0", + "death_animation": "102", + "name": "Black Guard", + "defence_level": "30", + "safespot": null, + "lifepoints": "42", + "strength_level": "30", + "id": "3279", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "He looks busy.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Engineering assistant", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3280", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He's building a cannon.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Engineer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3282", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Bushy tail!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Squirrel", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3283", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A raccoon.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Raccoon", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3286", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A raccoon.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Raccoon", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3288", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "She'll store my items for me.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "null", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3293", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A dwarf who looks after the mining guild.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "slayer_exp": "16", + "magic_animation": "0", + "death_animation": "0", + "name": "Dwarf", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3294", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A dwarf who looks after the mining guild.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "slayer_exp": "16", + "magic_animation": "0", + "death_animation": "0", + "name": "Dwarf", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3295", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A graceful bird.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Swan", + "defence_level": "1", + "safespot": null, + "water_npc": true, + "lifepoints": "10", + "strength_level": "1", + "id": "3296", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Keeps this magic area tidy.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Sweeper", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3298", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A master at gardening.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Martin the Master Gardener", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3299", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Manages the fairies.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Co-ordinator", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3302", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "I'm gonna make him an offer he can't refuse.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fairy Godfather", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3304", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Guardian of the market gate.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Gatekeeper", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3307", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Converts grass to beef.", + "melee_animation": "5849", + "range_animation": "5849", + "combat_audio": "369,371,370", + "attack_speed": "5", + "defence_animation": "5850", + "weakness": "8", + "slayer_exp": "8", + "magic_animation": "5849", + "death_animation": "5851", + "name": "Cow", + "defence_level": "1", + "safespot": null, + "lifepoints": "8", + "strength_level": "1", + "id": "3309", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "White and fluffy", + "name": "Sheep", + "id": "3310" + }, + { + "name": "Tanglefoot", + "defence_level": "1", + "safespot": null, + "lifepoints": "102", + "strength_level": "1", + "id": "3313", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "examine": "An animated shrub.", + "range_animation": "0", + "defence_animation": "0", + "weakness": "2", + "magic_animation": "0", + "name": "Baby tanglefoot", + "defence_level": "41", + "safespot": null, + "lifepoints": "58", + "strength_level": "1", + "id": "3319", + "range_level": "41", + "attack_level": "1" + }, + { + "examine": "An aggressive bush.", + "range_animation": "0", + "defence_animation": "0", + "weakness": "2", + "magic_animation": "0", + "name": "Baby tanglefoot", + "defence_level": "41", + "safespot": null, + "lifepoints": "58", + "strength_level": "1", + "id": "3320", + "range_level": "41", + "attack_level": "1" + }, + { + "examine": "Rather more tired than most.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Jeremy Clerksin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3327", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Looks a little green around the gills.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Barfy Bill", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3331", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It's made of pure fire.", + "attack_speed": "6", + "magic_level": "300", + "respawn_delay": "25", + "name": "Cavemouth", + "defence_level": "500", + "safespot": null, + "lifepoints": "1000", + "strength_level": "1500", + "id": "3334", + "aggressive": "true", + "bonuses": "126,98,86,297,311,304,319,13,284,30,0,0,0,0,0", + "range_level": "300", + "attack_level": "200" + }, + { + "examine": "Holy Mole-y!", + "melee_animation": "3312", + "range_animation": "3312", + "combat_audio": "1642,1646,1645", + "attack_speed": "4", + "magic_level": "200", + "respawn_delay": "56", + "defence_animation": "3311", + "weakness": "7", + "magic_animation": "3312", + "death_animation": "3310", + "name": "Giant Mole", + "defence_level": "200", + "safespot": null, + "lifepoints": "200", + "strength_level": "200", + "id": "3340", + "bonuses": "0,0,0,0,0,60,80,100,80,60,0,0,0,0,0", + "range_level": "1", + "attack_level": "200" + }, + { + "examine": "I will call him, Mini Mole.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Baby Mole", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3341", + "aggressive": "false", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A fun guy. No wait, that's awful. Plus it doesn't even make sense.", + "melee_animation": "0", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fungi", + "defence_level": "1", + "safespot": null, + "lifepoints": "65", + "strength_level": "1", + "id": "3344", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A fun guy. No wait, that's awful. Plus it doesn't even make sense.", + "melee_animation": "2776", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "2775", + "death_animation": "2777", + "name": "Fungi", + "defence_level": "1", + "safespot": null, + "lifepoints": "75", + "strength_level": "1", + "id": "3345", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A bouncy fungus.", + "melee_animation": "2776", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "1", + "magic_animation": "0", + "death_animation": "2777", + "name": "Zygomite", + "defence_level": "42", + "safespot": null, + "lifepoints": "60", + "strength_level": "1", + "id": "3346", + "range_level": "42", + "attack_level": "1" + }, + { + "examine": "Have a fungus.", + "melee_animation": "2776", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "2775", + "death_animation": "2777", + "name": "Zygomite", + "defence_level": "1", + "safespot": null, + "lifepoints": "75", + "strength_level": "1", + "id": "3347", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "7049", + "combat_audio": "511,513,512", + "attack_speed": "8", + "respawn_delay": "60", + "defence_animation": "7050", + "death_animation": "836", + "name": "White Knight", + "defence_level": "1", + "safespot": null, + "lifepoints": "53", + "strength_level": "1", + "id": "3348", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "7049", + "combat_audio": "511,513,512", + "attack_speed": "8", + "respawn_delay": "60", + "defence_animation": "7050", + "death_animation": "836", + "name": "White Knight", + "defence_level": "1", + "safespot": null, + "lifepoints": "53", + "strength_level": "1", + "id": "3349", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "7049", + "combat_audio": "511,513,512", + "attack_speed": "8", + "respawn_delay": "60", + "defence_animation": "7050", + "death_animation": "836", + "name": "White Knight", + "defence_level": "1", + "safespot": null, + "lifepoints": "53", + "strength_level": "1", + "id": "3350", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Evil Chicken", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "355,357,356", + "strength_level": "1", + "id": "3366", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Evil Chicken", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "355,357,356", + "strength_level": "1", + "id": "3367", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Evil Chicken", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "355,357,356", + "strength_level": "1", + "id": "3368", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Evil Chicken", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "355,357,356", + "strength_level": "1", + "id": "3369", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Evil Chicken", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "355,357,356", + "strength_level": "1", + "id": "3370", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Evil Chicken", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "355,357,356", + "strength_level": "1", + "id": "3371", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A fowl beast.", + "melee_animation": "2299", + "range_animation": "0", + "combat_audio": "355,357,356", + "magic_level": "55", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "2301", + "name": "Evil Chicken", + "defence_level": "55", + "safespot": null, + "lifepoints": "117", + "strength_level": "55", + "id": "3375", + "aggressive": "true", + "range_level": "55", + "attack_level": "55" + }, + { + "examine": "Young but still dangerous.", + "melee_animation": "25", + "range_animation": "25", + "combat_audio": "405,407,406", + "attack_speed": "5", + "magic_level": "40", + "respawn_delay": "32", + "defence_animation": "26", + "weakness": "3", + "slayer_exp": "0", + "magic_animation": "25", + "death_animation": "28", + "name": "Baby black dragon", + "defence_level": "42", + "safespot": null, + "lifepoints": "50", + "strength_level": "80", + "id": "3376", + "aggressive": "true", + "bonuses": "50,40,64,60,30,45,40,40,20,40,40,20,0,0,0", + "range_level": "1", + "attack_level": "80" + }, + { + "examine": "He seems to like wearing black.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Evil Dave", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3378", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Vermin from the underworld.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "703,705,704", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Hell-Rat", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3382", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A shifty-looking character.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "703,705,704", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Pirate Pete", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3389", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He looks short and grumpy.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "0", + "name": "Mountain Dwarf", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3390", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "General Wartface", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3391", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "General Bentnoze", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3392", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He provides new players with useful information.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Lumbridge Guide", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3393", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He seems to like wearing black.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Evil Dave", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3394", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Rutmir's assistant.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "null", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3404", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A small ice demon.", + "range_animation": "0", + "combat_audio": "531,533,532", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "name": "Icefiend", + "defence_level": "60", + "safespot": null, + "lifepoints": "171", + "strength_level": "60", + "id": "3406", + "aggressive": "true", + "clue_level": "0", + "range_level": "1", + "attack_level": "60" + }, + { + "examine": "He tries to keep order around here.", + "melee_animation": "7218", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "7219", + "name": "Guard", + "defence_level": "25", + "safespot": null, + "lifepoints": "35", + "strength_level": "25", + "id": "3407", + "clue_level": "1", + "range_level": "1", + "attack_level": "25" + }, + { + "examine": "He tries to keep order around here.", + "melee_animation": "583", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "7213", + "name": "Guard", + "defence_level": "25", + "safespot": null, + "lifepoints": "35", + "strength_level": "25", + "id": "3408", + "clue_level": "1", + "range_level": "1", + "attack_level": "25" + }, + { + "examine": "A sentient plant - ready", + "melee_animation": "7246", + "range_animation": "0", + "poisonous": "true", + "magic_level": "65", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7249", + "name": "Wild jade vine", + "defence_level": "65", + "safespot": null, + "lifepoints": "185", + "strength_level": "65", + "id": "3409", + "aggressive": "true", + "range_level": "65", + "attack_level": "65" + }, + { + "examine": "A sentient plant - ready", + "melee_animation": "7246", + "range_animation": "0", + "poisonous": "true", + "magic_level": "65", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7249", + "name": "Wild jade vine", + "defence_level": "65", + "safespot": null, + "lifepoints": "185", + "strength_level": "65", + "id": "3410", + "aggressive": "true", + "range_level": "65", + "attack_level": "65" + }, + { + "examine": "A sentient plant - ready", + "melee_animation": "7246", + "range_animation": "0", + "poisonous": "true", + "magic_level": "65", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7249", + "name": "Wild jade vine", + "defence_level": "65", + "safespot": null, + "lifepoints": "185", + "strength_level": "65", + "id": "3411", + "aggressive": "true", + "range_level": "65", + "attack_level": "65" + }, + { + "examine": "A sentient plant - ready", + "melee_animation": "7246", + "range_animation": "0", + "poisonous": "true", + "magic_level": "65", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7249", + "name": "Wild jade vine", + "defence_level": "65", + "safespot": null, + "lifepoints": "185", + "strength_level": "65", + "id": "3412", + "aggressive": "true", + "range_level": "65", + "attack_level": "65" + }, + { + "examine": "He's got funky socks, but he's still an ugly green creature.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "469,472,471", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Goblin Cook", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3413", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "More like a goblin cooked.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "469,472,471", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Goblin Cook", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3414", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Half way up the wall is maybe not a naturally tenable position for a goblin.", + "name": "Goblin Cook", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "3415", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He'll store my items for me.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "703,705,704", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Pirate Pete", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3416", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He'll store my items for me.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "703,705,704", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Pirate Pete", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3418", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Big, ugly, and smelly.", + "slayer_task": "64", + "melee_animation": "359", + "attack_speed": "7", + "respawn_delay": "60", + "defence_animation": "360", + "weakness": "8", + "death_animation": "361", + "name": "Ogre", + "defence_level": "27", + "safespot": null, + "lifepoints": "60", + "strength_level": "27", + "id": "3419", + "aggressive": "true", + "attack_level": "1" + }, + { + "examine": "An angry Ogre in a highly amusing hat.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Mogre Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3420", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Nice claw!", + "melee_animation": "3428", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "3430", + "name": "Crab", + "defence_level": "22", + "safespot": null, + "lifepoints": "31", + "strength_level": "22", + "id": "3421", + "range_level": "1", + "attack_level": "22" + }, + { + "examine": "Not the most beautiful fish in the sea.", + "melee_animation": "3433", + "range_animation": "0", + "combat_audio": "241,243,242", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "10", + "defence_animation": "3434", + "weakness": "9", + "magic_animation": "0", + "death_animation": "3435", + "name": "Mudskipper", + "defence_level": "26", + "safespot": null, + "lifepoints": "20", + "strength_level": "29", + "id": "3422", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "29" + }, + { + "examine": "Not the most beautiful fish in the sea.", + "melee_animation": "3433", + "combat_audio": "241,243,242", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "5", + "defence_animation": "3434", + "death_animation": "3435", + "name": "Mudskipper", + "defence_level": "29", + "safespot": null, + "lifepoints": "20", + "strength_level": "30", + "id": "3423", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "30" + }, + { + "death_animation": "3430", + "name": "Crab", + "defence_level": "1", + "safespot": null, + "lifepoints": "18", + "melee_animation": "3428", + "strength_level": "1", + "id": "3424", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1", + "defence_animation": "3429" + }, + { + "examine": "A Red Fantail.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fish", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3425", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A Red Fantail.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fish", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3426", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A Red Fantail.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fish", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3427", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An Angel Fish.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fish", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3431", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An Angel Fish.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fish", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3432", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An Angel Fish.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fish", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3433", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A Harlequin Fish.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fish", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3434", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A Harlequin Fish.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fish", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3435", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A Harlequin Fish.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fish", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3436", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A Discus Fish.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fish", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3437", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A Discus Fish.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fish", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3438", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A Discus Fish.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fish", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3439", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A shoal of Neon Tetra.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fish", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3443", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A shoal of Neon Tetra.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fish", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3444", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A shoal of Neon Tetra.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fish", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3445", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Lumbridge Guide", + "defence_level": "1", + "safespot": null, + "lifepoints": "60", + "strength_level": "1", + "attack_speed": "7", + "id": "3449", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "null", + "defence_level": "1", + "safespot": null, + "lifepoints": "60", + "strength_level": "1", + "attack_speed": "7", + "id": "3450", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Lumbridge Guide", + "defence_level": "1", + "safespot": null, + "lifepoints": "60", + "strength_level": "1", + "attack_speed": "7", + "id": "3451", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "examine": "What restful music!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Skrach Uglogwee", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3463", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A large boisterous bird", + "melee_animation": "6800", + "range_animation": "0", + "defence_animation": "0", + "weakness": "0", + "magic_animation": "0", + "death_animation": "6801", + "name": "Jubbly bird", + "defence_level": "8", + "safespot": null, + "lifepoints": "11", + "strength_level": "6", + "id": "3476", + "aggressive": "true", + "range_level": "8", + "attack_level": "6" + }, + { + "name": "King Awowogei", + "defence_level": "1", + "safespot": null, + "lifepoints": "328", + "strength_level": "1", + "id": "3478", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "examine": "A big snake.", + "melee_animation": "3538", + "range_animation": "0", + "combat_audio": "3609,3608,3610", + "poisonous": "true", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "3540", + "name": "Big Snake", + "defence_level": "46", + "safespot": null, + "lifepoints": "65", + "strength_level": "46", + "id": "3484", + "aggressive": "true", + "range_level": "1", + "attack_level": "46" + }, + { + "name": "Culinaromancer", + "defence_level": "1", + "safespot": null, + "lifepoints": "140", + "strength_level": "1", + "id": "3491", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "melee_animation": "3501", + "respawn_delay": "60", + "defence_animation": "3500", + "death_animation": "3503", + "name": "Agrith-Na-Na", + "defence_level": "1", + "safespot": null, + "lifepoints": "200", + "strength_level": "1", + "id": "3493", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "1750", + "respawn_delay": "60", + "defence_animation": "1751", + "death_animation": "1752", + "name": "Flambeed", + "defence_level": "1", + "safespot": null, + "lifepoints": "210", + "strength_level": "1", + "id": "3494", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "422", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Karamel", + "defence_level": "1", + "safespot": null, + "lifepoints": "240", + "strength_level": "1", + "id": "3495", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "3507", + "respawn_delay": "60", + "defence_animation": "3505", + "death_animation": "3510", + "name": "Dessourt", + "defence_level": "1", + "safespot": null, + "lifepoints": "140", + "strength_level": "1", + "id": "3496", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Deadly AND fruity!", + "melee_animation": "1341", + "range_animation": "0", + "magic_level": "65", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "5", + "magic_animation": "0", + "death_animation": "1342", + "name": "Gelatinnoth Mother", + "defence_level": "65", + "safespot": null, + "lifepoints": "139", + "strength_level": "48", + "id": "3497", + "aggressive": "true", + "range_level": "1", + "attack_level": "48" + }, + { + "melee_animation": "1341", + "respawn_delay": "60", + "defence_animation": "1340", + "death_animation": "1342", + "name": "Gelatinnoth Mother", + "defence_level": "1", + "safespot": null, + "lifepoints": "240", + "strength_level": "1", + "id": "3498", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "1341", + "respawn_delay": "60", + "defence_animation": "1340", + "death_animation": "1342", + "name": "Gelatinnoth Mother", + "defence_level": "1", + "safespot": null, + "lifepoints": "240", + "strength_level": "1", + "id": "3499", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "1341", + "respawn_delay": "60", + "defence_animation": "1340", + "death_animation": "1342", + "name": "Gelatinnoth Mother", + "defence_level": "1", + "safespot": null, + "lifepoints": "240", + "strength_level": "1", + "id": "3500", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "1341", + "respawn_delay": "60", + "defence_animation": "1340", + "death_animation": "1342", + "name": "Gelatinnoth Mother", + "defence_level": "1", + "safespot": null, + "lifepoints": "240", + "strength_level": "1", + "id": "3501", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "1341", + "respawn_delay": "60", + "defence_animation": "1340", + "death_animation": "1342", + "name": "Gelatinnoth Mother", + "defence_level": "1", + "safespot": null, + "lifepoints": "240", + "strength_level": "1", + "id": "3502", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Chronicler and regaler of your piratical exploits.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Sorin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3509", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An initiate juvenile vampyre.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Vampyre Juvinate", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3514", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An initiate juvenile vampyre.", + "melee_animation": "5783", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "0", + "magic_animation": "0", + "death_animation": "5798", + "name": "Vampyre Juvinate", + "defence_level": "45", + "safespot": null, + "lifepoints": "64", + "strength_level": "1", + "id": "3521", + "aggressive": "true", + "range_level": "45", + "attack_level": "1" + }, + { + "death_animation": "5798", + "name": "Vampyre Juvinate", + "defence_level": "1", + "safespot": null, + "lifepoints": "85", + "melee_animation": "5783", + "strength_level": "1", + "id": "3522", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "death_animation": "5798", + "name": "Vampyre Juvinate", + "defence_level": "1", + "safespot": null, + "lifepoints": "85", + "melee_animation": "5783", + "strength_level": "1", + "id": "3523", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "death_animation": "5798", + "name": "Vampyre Juvinate", + "defence_level": "1", + "safespot": null, + "lifepoints": "85", + "melee_animation": "5783", + "strength_level": "1", + "id": "3524", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "death_animation": "5798", + "name": "Vampyre Juvinate", + "defence_level": "1", + "safespot": null, + "lifepoints": "85", + "melee_animation": "5783", + "strength_level": "1", + "id": "3525", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "examine": "An initiate juvenile vampyre", + "melee_animation": "6016", + "range_animation": "0", + "defence_animation": "0", + "weakness": "0", + "magic_animation": "0", + "death_animation": "6031", + "name": "Vampyre Juvinate", + "defence_level": "46", + "safespot": null, + "lifepoints": "65", + "strength_level": "1", + "id": "3526", + "range_level": "46", + "attack_level": "1" + }, + { + "examine": "A Juvinate vampyre", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "weakness": "0", + "magic_animation": "0", + "death_animation": "5798", + "name": "Held Vampyre Juvinate", + "defence_level": "45", + "safespot": null, + "lifepoints": "64", + "strength_level": "1", + "id": "3527", + "range_level": "45", + "attack_level": "1" + }, + { + "examine": "He looks really hungry!", + "melee_animation": "6276", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "6781", + "name": "Vampyre Juvenile", + "defence_level": "40", + "safespot": null, + "lifepoints": "57", + "strength_level": "40", + "id": "3531", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "She looks really hungry!", + "melee_animation": "6276", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "6781", + "name": "Vampyre Juvenile", + "defence_level": "40", + "safespot": null, + "lifepoints": "57", + "strength_level": "40", + "id": "3532", + "range_level": "1", + "attack_level": "40" + }, + { + "death_animation": "6781", + "name": "Vampyre Juvenile", + "defence_level": "1", + "safespot": null, + "lifepoints": "60", + "melee_animation": "6276", + "strength_level": "1", + "id": "3533", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "examine": "He looks really hungry!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "6781", + "name": "Held Vampyre Juvenile", + "defence_level": "40", + "safespot": null, + "lifepoints": "57", + "strength_level": "40", + "id": "3534", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "An initiate juvenile vampyre", + "melee_animation": "6016", + "range_animation": "0", + "defence_animation": "0", + "weakness": "0", + "magic_animation": "0", + "death_animation": "6031", + "name": "Juvinate", + "defence_level": "46", + "safespot": null, + "lifepoints": "65", + "strength_level": "1", + "id": "3577", + "range_level": "46", + "attack_level": "1" + }, + { + "examine": "Is it a sheep?", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Sheep", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3579", + "range_level": "1", + "attack_level": "1" + }, + { + "slayer_exp": "49", + "name": "Guard dog", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3582", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "164", + "combat_audio": "469,472,471", + "respawn_delay": "60", + "defence_animation": "163", + "death_animation": "167", + "name": "Hobgoblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "29", + "strength_level": "1", + "id": "3583", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "No spider could grow that big! It's unrealistic!", + "melee_animation": "5319", + "range_animation": "0", + "combat_audio": "537,539,538", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "2", + "magic_animation": "0", + "death_animation": "5321", + "name": "Huge spider", + "defence_level": "72", + "safespot": null, + "lifepoints": "122", + "strength_level": "1", + "id": "3585", + "aggressive": "true", + "range_level": "72", + "attack_level": "1" + }, + { + "examine": "Good doggy...", + "melee_animation": "6562", + "range_animation": "0", + "combat_audio": "3717,3719,3718", + "attack_speed": "4", + "respawn_delay": "50", + "defence_animation": "0", + "weakness": "7", + "slayer_exp": "116", + "magic_animation": "0", + "death_animation": "6576", + "name": "Hellhound", + "defence_level": "102", + "safespot": null, + "lifepoints": "116", + "strength_level": "104", + "id": "3586", + "aggressive": "true", + "clue_level": "2", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "105" + }, + { + "examine": "Big, ugly, and smelly.", + "melee_animation": "359", + "range_animation": "359", + "attack_speed": "6", + "magic_level": "27", + "respawn_delay": "25", + "defence_animation": "360", + "magic_animation": "359", + "death_animation": "361", + "name": "Rantz", + "defence_level": "27", + "safespot": null, + "lifepoints": "60", + "strength_level": "27", + "id": "3587", + "aggressive": "true", + "bonuses": "15,15,10,20,40,15,50,50,50,20,50,58,0,0,0", + "range_level": "27", + "attack_level": "27" + }, + { + "examine": "Young but still dangerous.", + "melee_animation": "25", + "range_animation": "25", + "combat_audio": "405,407,406", + "attack_speed": "5", + "magic_level": "40", + "respawn_delay": "32", + "defence_animation": "26", + "weakness": "8", + "magic_animation": "25", + "death_animation": "28", + "name": "Baby red dragon", + "defence_level": "42", + "safespot": null, + "lifepoints": "50", + "strength_level": "40", + "id": "3588", + "aggressive": "true", + "bonuses": "20,10,10,20,40,40,20,40,40,20,0,0,0,0,0", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "I don't think insect repellent will work...", + "melee_animation": "6223", + "range_animation": "0", + "combat_audio": "567,569,568", + "attack_speed": "4", + "poisonous": "true", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "6227", + "weakness": "6", + "poison_amount": "4", + "magic_animation": "0", + "death_animation": "6228", + "name": "Kalphite Soldier", + "defence_level": "70", + "safespot": null, + "lifepoints": "90", + "strength_level": "70", + "id": "3589", + "aggressive": "true", + "bonuses": "0,0,0,0,0,25,25,5,50,50,0,0,0,0,0", + "range_level": "1", + "attack_level": "70" + }, + { + "examine": "Its scales seem to be made of steel.", + "combat_audio": "408,410,409", + "magic_level": "72", + "respawn_delay": "35", + "weakness": "8", + "slayer_exp": "221", + "name": "Steel dragon", + "defence_level": "238", + "safespot": null, + "lifepoints": "210", + "strength_level": "229", + "id": "3590", + "aggressive": "true", + "bonuses": "56,42,104,51,212,115,232,302,331,21,264,100,100,40,0", + "clue_level": "2", + "range_level": "185", + "attack_level": "234" + }, + { + "examine": "A darkened horror from the ocean depths.", + "name": "Dagannoth", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3591", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Arrgh! Look at its pointy teeth!", + "range_animation": "0", + "combat_audio": "400,404,403", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "name": "Demon", + "defence_level": "75", + "safespot": null, + "lifepoints": "107", + "strength_level": "75", + "id": "3593", + "aggressive": "true", + "range_level": "1", + "attack_level": "75" + }, + { + "examine": "A large snake that thrives in swamps.", + "melee_animation": "3538", + "range_animation": "3538", + "combat_audio": "3609,3608,3610", + "attack_speed": "5", + "defence_animation": "3539", + "weakness": "0", + "magic_animation": "3538", + "death_animation": "3540", + "name": "Swamp snake", + "defence_level": "40", + "safespot": null, + "lifepoints": "121", + "strength_level": "33", + "id": "3599", + "bonuses": "10,10,10,10,10,10,1,10,6,10,6,4,0,0,0", + "range_level": "45", + "attack_level": "35" + }, + { + "examine": "A large snake that thrives in swamps.", + "melee_animation": "3538", + "range_animation": "3538", + "combat_audio": "3609,3608,3610", + "attack_speed": "5", + "defence_animation": "3539", + "magic_animation": "3538", + "death_animation": "3540", + "name": "Swamp snake", + "defence_level": "60", + "safespot": null, + "lifepoints": "121", + "strength_level": "50", + "id": "3600", + "bonuses": "10,10,10,10,10,10,1,10,6,10,6,4,0,0,0", + "range_level": "1", + "attack_level": "60" + }, + { + "examine": "A large snake that thrives in swamps.", + "melee_animation": "3538", + "range_animation": "3538", + "combat_audio": "3609,3608,3610", + "attack_speed": "5", + "defence_animation": "3539", + "weakness": "7", + "magic_animation": "3538", + "death_animation": "3540", + "name": "Swamp snake", + "defence_level": "40", + "safespot": null, + "lifepoints": "121", + "strength_level": "33", + "id": "3601", + "bonuses": "10,10,10,10,10,10,1,10,6,10,6,4,0,0,0", + "range_level": "1", + "attack_level": "35" + }, + { + "examine": "A large snake that thrives in swamps.", + "melee_animation": "3538", + "range_animation": "3538", + "combat_audio": "3609,3608,3610", + "attack_speed": "5", + "defence_animation": "3539", + "magic_animation": "3538", + "death_animation": "3540", + "name": "Swamp snake", + "defence_level": "40", + "safespot": null, + "lifepoints": "121", + "strength_level": "33", + "id": "3602", + "bonuses": "10,10,10,10,10,10,1,10,6,10,6,4,0,0,0", + "range_level": "1", + "attack_level": "35" + }, + { + "name": "Dead swamp snake", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "3609,3608,3610", + "strength_level": "1", + "id": "3603", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Dead swamp snake", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "3609,3608,3610", + "strength_level": "1", + "id": "3604", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Dead swamp snake", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "3609,3608,3610", + "strength_level": "1", + "id": "3605", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "I'm glad I can't see the rest of it!", + "melee_animation": "3618", + "range_animation": "3618", + "magic_level": "80", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "3620", + "name": "Tentacle", + "defence_level": "60", + "safespot": null, + "lifepoints": "171", + "strength_level": "80", + "id": "3618", + "aggressive": "true", + "range_level": "80", + "attack_level": "80" + }, + { + "examine": "I'm glad I can't see the rest of it!", + "melee_animation": "3731", + "range_animation": "0", + "attack_speed": "10", + "magic_level": "80", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "3733", + "name": "Head", + "defence_level": "60", + "safespot": null, + "lifepoints": "171", + "strength_level": "85", + "id": "3619", + "aggressive": "true", + "range_level": "80", + "attack_level": "85" + }, + { + "melee_animation": "3731", + "attack_speed": "10", + "respawn_delay": "60", + "defence_animation": "3732", + "death_animation": "3733", + "name": "Head", + "defence_level": "1", + "safespot": null, + "lifepoints": "150", + "strength_level": "1", + "id": "3620", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "slayer_exp": "30", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "40", + "combat_audio": "931,923,922", + "strength_level": "1", + "id": "3622", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A high-ranking Vyrewatch", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fyiona Fray", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3634", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He looks a little on the cross side!", + "range_animation": "0", + "combat_audio": "297,299,298", + "melee_animation": "4927", + "attack_speed": "4", + "magic_level": "1", + "defence_animation": "4927", + "weakness": "9", + "magic_animation": "0", + "death_animation": "4929", + "name": "Angry bear", + "defence_level": "38", + "safespot": null, + "lifepoints": "35", + "strength_level": "41", + "id": "3645", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "38" + }, + { + "examine": "He looks a little on the cross side!", + "melee_animation": "6376", + "range_animation": "0", + "combat_audio": "876,878,877", + "attack_speed": "4", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "6377", + "name": "Angry unicorn", + "defence_level": "38", + "safespot": null, + "lifepoints": "50", + "strength_level": "41", + "id": "3646", + "aggressive": "false", + "range_level": "1", + "attack_level": "38" + }, + { + "examine": "He looks a little on the cross side!", + "melee_animation": "4933", + "range_animation": "0", + "combat_audio": "703,705,704", + "defence_animation": "4934", + "weakness": "9", + "magic_animation": "0", + "death_animation": "4935", + "name": "Angry giant rat", + "defence_level": "25", + "safespot": null, + "lifepoints": "35", + "strength_level": "25", + "id": "3647", + "range_level": "1", + "attack_level": "25" + }, + { + "examine": "He looks a little on the cross side!", + "melee_animation": "6185", + "range_animation": "0", + "combat_audio": "469,472,471", + "defence_animation": "6183", + "weakness": "9", + "magic_animation": "0", + "death_animation": "6182", + "name": "Angry goblin", + "defence_level": "25", + "safespot": null, + "lifepoints": "35", + "strength_level": "25", + "id": "3648", + "range_level": "1", + "attack_level": "25" + }, + { + "examine": "AHHHHH!", + "melee_animation": "3812", + "range_animation": "0", + "combat_audio": "297,299,298", + "attack_speed": "4", + "defence_animation": "3811", + "weakness": "", + "magic_animation": "0", + "death_animation": "3813", + "name": "Fear reaper", + "defence_level": "40", + "safespot": null, + "lifepoints": "25", + "strength_level": "41", + "id": "3649", + "range_level": "1", + "attack_level": "41" + }, + { + "examine": "What on Gielinor is that?!?", + "melee_animation": "3818", + "range_animation": "0", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "3821", + "name": "Confusion beast", + "defence_level": "28", + "safespot": null, + "lifepoints": "40", + "strength_level": "28", + "id": "3650", + "range_level": "1", + "attack_level": "28" + }, + { + "examine": "A hopeless poor creature.", + "melee_animation": "3823", + "range_animation": "0", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "3827", + "name": "Hopeless creature", + "defence_level": "25", + "safespot": null, + "lifepoints": "35", + "strength_level": "25", + "id": "3655", + "range_level": "1", + "attack_level": "25" + }, + { + "examine": "He looks a little on the cross side!", + "melee_animation": "6376", + "range_animation": "0", + "combat_audio": "876,878,877", + "attack_speed": "4", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "6377", + "name": "Angry unicorn", + "defence_level": "38", + "safespot": null, + "lifepoints": "50", + "strength_level": "41", + "id": "3661", + "aggressive": "false", + "range_level": "1", + "attack_level": "38" + }, + { + "examine": "He looks a little on the cross side!", + "combat_audio": "703,705,704", + "melee_animation": "4933", + "defence_animation": "4934", + "death_animation": "4935", + "name": "Angry giant rat", + "defence_level": "38", + "safespot": null, + "lifepoints": "50", + "strength_level": "41", + "id": "3662", + "range_level": "1", + "attack_level": "38" + }, + { + "examine": "He looks a little on the cross side!", + "melee_animation": "6185", + "range_animation": "0", + "combat_audio": "469,472,471", + "defence_animation": "6183", + "weakness": "9", + "magic_animation": "0", + "death_animation": "6182", + "name": "Angry goblin", + "defence_level": "38", + "safespot": null, + "lifepoints": "50", + "strength_level": "41", + "id": "3663", + "range_level": "1", + "attack_level": "38" + }, + { + "examine": "He looks a little on the cross side!", + "combat_audio": "297,299,298", + "melee_animation": "4927", + "attack_speed": "4", + "magic_level": "1", + "defence_animation": "4927", + "death_animation": "4929", + "name": "Angry bear", + "defence_level": "38", + "safespot": null, + "lifepoints": "10", + "strength_level": "41", + "id": "3664", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "38" + }, + { + "examine": "AHHHHH!", + "melee_animation": "3812", + "combat_audio": "297,299,298", + "attack_speed": "4", + "magic_level": "1", + "defence_animation": "3811", + "death_animation": "3813", + "name": "Fear reaper", + "defence_level": "45", + "safespot": null, + "lifepoints": "57", + "strength_level": "48", + "id": "3665", + "bonuses": "", + "range_level": "1", + "attack_level": "45" + }, + { + "examine": "What on Gielinor is that?!?", + "melee_animation": "3818", + "combat_audio": "297,299,298", + "attack_speed": "4", + "magic_level": "1", + "defence_animation": "3820", + "death_animation": "3821", + "name": "Confusion beast", + "defence_level": "52", + "safespot": null, + "lifepoints": "64", + "strength_level": "55", + "id": "3666", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "52" + }, + { + "examine": "He looks a little on the cross side!", + "melee_animation": "3823", + "combat_audio": "297,299,298", + "attack_speed": "4", + "magic_level": "1", + "defence_animation": "0", + "death_animation": "3827", + "name": "Hopeless creature", + "defence_level": "59", + "safespot": null, + "lifepoints": "71", + "strength_level": "62", + "id": "3667", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "59" + }, + { + "examine": "That's a lot of bones on his back...", + "name": "Odd Old Man", + "id": "3670" + }, + { + "examine": "Freshly sheared.", + "melee_animation": "5341", + "range_animation": "0", + "combat_audio": "757,759,758", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "5337", + "weakness": "9", + "magic_animation": "0", + "death_animation": "5343", + "name": "Ram", + "defence_level": "1", + "safespot": null, + "lifepoints": "8", + "strength_level": "1", + "id": "3672", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "White and fluffy.", + "melee_animation": "5338", + "range_animation": "0", + "combat_audio": "757,759,758", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "5337", + "weakness": "9", + "magic_animation": "0", + "death_animation": "5336", + "name": "Ram", + "defence_level": "1", + "safespot": null, + "lifepoints": "8", + "strength_level": "1", + "id": "3673", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Sack", + "id": "3674" + }, + { + "examine": "If you see them circling, run.", + "melee_animation": "2019", + "range_animation": "0", + "combat_audio": "890,892,891", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "50", + "defence_animation": "2024", + "weakness": "9", + "magic_animation": "0", + "death_animation": "2021", + "name": "Vulture", + "defence_level": "10", + "safespot": null, + "lifepoints": "10", + "strength_level": "40", + "id": "3675", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "If you see them circling, run.", + "melee_animation": "2025", + "combat_audio": "890,892,891", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "50", + "defence_animation": "2024", + "death_animation": "2026", + "name": "Vulture", + "defence_level": "10", + "safespot": null, + "lifepoints": "10", + "strength_level": "40", + "id": "3676", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "A young boy handing out flyers.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ali the Leaflet Dropper", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3680", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Ulfric", + "defence_level": "1", + "safespot": null, + "lifepoints": "60", + "melee_animation": "6118", + "strength_level": "1", + "id": "3706", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "examine": "Eww", + "melee_animation": "6117", + "range_animation": "0", + "combat_audio": "703,705,704", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "slayer_exp": "50", + "magic_animation": "0", + "death_animation": "6115", + "name": "Brine rat", + "defence_level": "35", + "safespot": null, + "lifepoints": "50", + "strength_level": "35", + "id": "3707", + "range_level": "1", + "attack_level": "35" + }, + { + "examine": "A Wilderness fighter of massive repute.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Boulder", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3709", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An annoying flappy thing.", + "melee_animation": "4915", + "range_animation": "4915", + "combat_audio": "292,294,293", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "35", + "defence_animation": "4916", + "weakness": "4", + "slayer_exp": "8", + "magic_animation": "4915", + "death_animation": "4917", + "name": "Giant bat", + "defence_level": "22", + "safespot": null, + "lifepoints": "32", + "strength_level": "22", + "id": "3711", + "aggressive": "true", + "bonuses": "0,0,0,0,0,10,10,12,10,8,0,0,0,0,0", + "range_level": "1", + "attack_level": "12" + }, + { + "melee_animation": "395", + "combat_audio": "511,513,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "22", + "strength_level": "1", + "id": "3715", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "3726", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Don't burst its bubble!", + "melee_animation": "3891", + "range_animation": "3891", + "combat_audio": "809,811,810", + "magic_level": "5", + "respawn_delay": "120", + "defence_animation": "3890", + "weakness": "8", + "magic_animation": "3891", + "death_animation": "3888", + "name": "Splatter", + "defence_level": "20", + "safespot": null, + "lifepoints": "13", + "strength_level": "20", + "id": "3727", + "bonuses": "5,10,10,10,10,2,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "20" + }, + { + "examine": "Don't burst its bubble!", + "melee_animation": "3891", + "range_animation": "3891", + "combat_audio": "809,811,810", + "magic_level": "10", + "respawn_delay": "120", + "defence_animation": "3890", + "magic_animation": "3891", + "death_animation": "3888", + "name": "Splatter", + "defence_level": "25", + "safespot": null, + "lifepoints": "23", + "strength_level": "25", + "id": "3728", + "bonuses": "10,15,15,15,15,5,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "25" + }, + { + "examine": "Don't burst its bubble!", + "melee_animation": "3891", + "range_animation": "3891", + "combat_audio": "809,811,810", + "magic_level": "10", + "respawn_delay": "120", + "defence_animation": "3890", + "magic_animation": "3891", + "death_animation": "3888", + "name": "Splatter", + "defence_level": "30", + "safespot": null, + "lifepoints": "23", + "strength_level": "30", + "id": "3729", + "bonuses": "15,20,20,20,20,8,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "Don't burst its bubble!", + "melee_animation": "3891", + "range_animation": "3891", + "combat_audio": "809,811,810", + "magic_level": "15", + "respawn_delay": "120", + "defence_animation": "3890", + "magic_animation": "3891", + "death_animation": "3888", + "name": "Splatter", + "defence_level": "35", + "safespot": null, + "lifepoints": "23", + "strength_level": "35", + "id": "3730", + "bonuses": "20,25,25,25,25,10,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "35" + }, + { + "examine": "Don't burst its bubble!", + "melee_animation": "3891", + "range_animation": "3891", + "combat_audio": "809,811,810", + "magic_level": "20", + "respawn_delay": "120", + "defence_animation": "3890", + "magic_animation": "3891", + "death_animation": "3888", + "name": "Splatter", + "defence_level": "40", + "safespot": null, + "lifepoints": "23", + "strength_level": "40", + "id": "3731", + "bonuses": "25,30,30,30,30,15,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "Nippy little thing!", + "melee_animation": "3901", + "range_animation": "3901", + "combat_audio": "766,768,767", + "magic_level": "14", + "respawn_delay": "127", + "defence_animation": "3902", + "weakness": "9", + "magic_animation": "3901", + "death_animation": "3903", + "name": "Shifter", + "defence_level": "28", + "poison_immune": "true", + "safespot": null, + "lifepoints": "23", + "strength_level": "28", + "id": "3732", + "aggressive": "true", + "bonuses": "20,25,20,40,40,40,40,5,18,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "28" + }, + { + "examine": "Nippy little thing!", + "melee_animation": "3901", + "range_animation": "3901", + "combat_audio": "766,768,767", + "magic_level": "14", + "respawn_delay": "127", + "defence_animation": "3902", + "magic_animation": "3901", + "death_animation": "3903", + "name": "Shifter", + "defence_level": "28", + "poison_immune": "true", + "safespot": null, + "lifepoints": "23", + "strength_level": "28", + "id": "3733", + "aggressive": "true", + "bonuses": "20,25,20,40,40,40,40,5,18,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "28" + }, + { + "examine": "Nippy little thing!", + "melee_animation": "3901", + "range_animation": "3901", + "combat_audio": "766,768,767", + "magic_level": "20", + "respawn_delay": "127", + "defence_animation": "3902", + "magic_animation": "3901", + "death_animation": "3903", + "name": "Shifter", + "defence_level": "42", + "poison_immune": "true", + "safespot": null, + "lifepoints": "38", + "strength_level": "42", + "id": "3734", + "aggressive": "true", + "bonuses": "30,35,30,50,50,50,50,10,15,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "42" + }, + { + "examine": "Nippy little thing!", + "melee_animation": "3901", + "range_animation": "3901", + "combat_audio": "766,768,767", + "magic_level": "20", + "respawn_delay": "127", + "defence_animation": "3902", + "magic_animation": "3901", + "death_animation": "3903", + "name": "Shifter", + "defence_level": "42", + "poison_immune": "true", + "safespot": null, + "lifepoints": "38", + "strength_level": "42", + "id": "3735", + "aggressive": "true", + "bonuses": "30,35,30,50,50,50,50,10,15,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "42" + }, + { + "examine": "Nippy little thing!", + "melee_animation": "3901", + "range_animation": "3901", + "combat_audio": "766,768,767", + "magic_level": "25", + "respawn_delay": "127", + "defence_animation": "3902", + "magic_animation": "3901", + "death_animation": "3903", + "name": "Shifter", + "defence_level": "54", + "poison_immune": "true", + "safespot": null, + "lifepoints": "53", + "strength_level": "54", + "id": "3736", + "aggressive": "true", + "bonuses": "35,40,35,60,60,60,60,20,15,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "54" + }, + { + "examine": "Nippy little thing!", + "melee_animation": "3901", + "range_animation": "3901", + "combat_audio": "766,768,767", + "magic_level": "25", + "respawn_delay": "127", + "defence_animation": "3902", + "magic_animation": "3901", + "death_animation": "3903", + "name": "Shifter", + "defence_level": "54", + "poison_immune": "true", + "safespot": null, + "lifepoints": "53", + "strength_level": "54", + "id": "3737", + "aggressive": "true", + "bonuses": "35,40,35,60,60,60,60,20,15,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "54" + }, + { + "examine": "Nippy little thing!", + "melee_animation": "3901", + "range_animation": "3901", + "combat_audio": "766,768,767", + "magic_level": "30", + "respawn_delay": "127", + "defence_animation": "3902", + "magic_animation": "3901", + "death_animation": "3903", + "name": "Shifter", + "defence_level": "60", + "poison_immune": "true", + "safespot": null, + "lifepoints": "68", + "strength_level": "60", + "id": "3738", + "aggressive": "true", + "bonuses": "40,50,40,70,70,70,70,30,15,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "60" + }, + { + "examine": "Nippy little thing!", + "melee_animation": "3901", + "range_animation": "3901", + "combat_audio": "766,768,767", + "magic_level": "30", + "respawn_delay": "127", + "defence_animation": "3902", + "magic_animation": "3901", + "death_animation": "3903", + "name": "Shifter", + "defence_level": "60", + "poison_immune": "true", + "safespot": null, + "lifepoints": "68", + "strength_level": "60", + "id": "3739", + "aggressive": "true", + "bonuses": "40,50,40,70,70,70,70,30,15,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "60" + }, + { + "examine": "Nippy little thing!", + "melee_animation": "3901", + "range_animation": "3901", + "combat_audio": "766,768,767", + "magic_level": "35", + "respawn_delay": "127", + "defence_animation": "3902", + "magic_animation": "3901", + "death_animation": "3903", + "name": "Shifter", + "defence_level": "70", + "poison_immune": "true", + "safespot": null, + "lifepoints": "83", + "strength_level": "70", + "id": "3740", + "aggressive": "true", + "bonuses": "50,60,50,80,70,90,80,35,14,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "70" + }, + { + "examine": "Nippy little thing!", + "melee_animation": "3901", + "range_animation": "3901", + "combat_audio": "766,768,767", + "magic_level": "35", + "respawn_delay": "127", + "defence_animation": "3902", + "magic_animation": "3901", + "death_animation": "3903", + "name": "Shifter", + "defence_level": "70", + "poison_immune": "true", + "safespot": null, + "lifepoints": "83", + "strength_level": "70", + "id": "3741", + "aggressive": "true", + "bonuses": "50,60,50,80,70,90,80,35,14,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "70" + }, + { + "examine": "Worse than termites!", + "melee_animation": "3915", + "range_animation": "3915", + "combat_audio": "714,716,715", + "attack_speed": "5", + "magic_level": "10", + "respawn_delay": "120", + "defence_animation": "3916", + "weakness": "7", + "magic_animation": "3915", + "death_animation": "3917", + "name": "Ravager", + "defence_level": "15", + "safespot": null, + "lifepoints": "23", + "strength_level": "30", + "id": "3742", + "bonuses": "45,45,45,45,50,5,45,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "15" + }, + { + "examine": "Worse than termites!", + "melee_animation": "3915", + "range_animation": "3915", + "combat_audio": "714,716,715", + "attack_speed": "5", + "magic_level": "15", + "respawn_delay": "120", + "defence_animation": "3916", + "magic_animation": "3915", + "death_animation": "3917", + "name": "Ravager", + "defence_level": "20", + "safespot": null, + "lifepoints": "38", + "strength_level": "40", + "id": "3743", + "bonuses": "45,45,45,45,50,5,55,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "20" + }, + { + "examine": "Worse than termites!", + "melee_animation": "3915", + "range_animation": "3915", + "combat_audio": "714,716,715", + "attack_speed": "5", + "magic_level": "20", + "respawn_delay": "120", + "defence_animation": "3916", + "magic_animation": "3915", + "death_animation": "3917", + "name": "Ravager", + "defence_level": "30", + "safespot": null, + "lifepoints": "53", + "strength_level": "60", + "id": "3744", + "bonuses": "45,55,55,55,50,10,45,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "Worse than termites!", + "melee_animation": "3915", + "range_animation": "3915", + "combat_audio": "714,716,715", + "attack_speed": "5", + "magic_level": "30", + "respawn_delay": "120", + "defence_animation": "3916", + "magic_animation": "3915", + "death_animation": "3917", + "name": "Ravager", + "defence_level": "45", + "safespot": null, + "lifepoints": "53", + "strength_level": "75", + "id": "3745", + "bonuses": "60,60,60,60,80,10,45,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "45" + }, + { + "examine": "Worse than termites!", + "melee_animation": "3915", + "range_animation": "3915", + "combat_audio": "714,716,715", + "attack_speed": "5", + "magic_level": "40", + "respawn_delay": "120", + "defence_animation": "3916", + "magic_animation": "3915", + "death_animation": "3917", + "name": "Ravager", + "defence_level": "60", + "safespot": null, + "lifepoints": "53", + "strength_level": "80", + "id": "3746", + "bonuses": "65,70,70,70,90,20,56,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "60" + }, + { + "examine": "Eeewww!", + "melee_animation": "3908", + "range_animation": "3908", + "combat_audio": "805,807,806", + "magic_level": "10", + "respawn_delay": "125", + "defence_animation": "3909", + "weakness": "6", + "magic_animation": "3908", + "death_animation": "3910", + "name": "Spinner", + "defence_level": "20", + "safespot": null, + "lifepoints": "33", + "strength_level": "20", + "id": "3747", + "bonuses": "20,40,40,40,40,10,38,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "20" + }, + { + "examine": "Eeewww!", + "melee_animation": "3908", + "range_animation": "3908", + "combat_audio": "805,807,806", + "magic_level": "15", + "respawn_delay": "125", + "defence_animation": "3909", + "magic_animation": "3908", + "death_animation": "3910", + "name": "Spinner", + "defence_level": "30", + "safespot": null, + "lifepoints": "50", + "strength_level": "30", + "id": "3748", + "bonuses": "30,60,60,60,60,15,38,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "Eeewww!", + "melee_animation": "3908", + "range_animation": "3908", + "combat_audio": "805,807,806", + "magic_level": "20", + "respawn_delay": "125", + "defence_animation": "3909", + "magic_animation": "3908", + "death_animation": "3910", + "name": "Spinner", + "defence_level": "40", + "safespot": null, + "lifepoints": "67", + "strength_level": "40", + "id": "3749", + "bonuses": "50,70,70,70,70,20,38,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "Eeewww!", + "melee_animation": "3908", + "range_animation": "3908", + "combat_audio": "805,807,806", + "magic_level": "30", + "respawn_delay": "125", + "defence_animation": "3909", + "magic_animation": "3908", + "death_animation": "3910", + "name": "Spinner", + "defence_level": "60", + "safespot": null, + "lifepoints": "101", + "strength_level": "60", + "id": "3750", + "bonuses": "60,100,100,100,100,30,25,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "60" + }, + { + "examine": "Eeewww!", + "melee_animation": "3908", + "range_animation": "3908", + "combat_audio": "805,807,806", + "magic_level": "25", + "respawn_delay": "125", + "defence_animation": "3909", + "magic_animation": "3908", + "death_animation": "3910", + "name": "Spinner", + "defence_level": "50", + "safespot": null, + "lifepoints": "84", + "strength_level": "50", + "id": "3751", + "bonuses": "55,80,80,80,85,25,30,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "50" + }, + { + "examine": "Burn, baby, burn!", + "start_gfx": "646", + "combat_style": "2", + "melee_animation": "3882", + "range_animation": "3882", + "combat_audio": "845,848,846", + "magic_level": "25", + "respawn_delay": "120", + "end_gfx": "648", + "defence_animation": "3880", + "weakness": "5", + "magic_animation": "3882", + "death_animation": "3881", + "name": "Torcher", + "defence_level": "25", + "safespot": null, + "lifepoints": "18", + "strength_level": "1", + "id": "3752", + "aggressive": "true", + "bonuses": "30,30,30,30,15,30,40,0,0,0,0,0,0,0,0", + "range_level": "1", + "projectile": "647", + "attack_level": "1" + }, + { + "examine": "Burn, baby, burn!", + "start_gfx": "646", + "combat_style": "2", + "melee_animation": "3882", + "range_animation": "3882", + "combat_audio": "845,848,846", + "magic_level": "25", + "respawn_delay": "120", + "end_gfx": "648", + "defence_animation": "3880", + "magic_animation": "3882", + "death_animation": "3881", + "name": "Torcher", + "defence_level": "25", + "safespot": null, + "lifepoints": "18", + "strength_level": "1", + "id": "3753", + "aggressive": "true", + "bonuses": "30,30,30,30,15,30,40,0,0,0,0,0,0,0,0", + "range_level": "1", + "projectile": "647", + "attack_level": "1" + }, + { + "examine": "Burn, baby, burn!", + "start_gfx": "646", + "combat_style": "2", + "melee_animation": "3882", + "range_animation": "3882", + "combat_audio": "845,848,846", + "magic_level": "40", + "respawn_delay": "120", + "end_gfx": "648", + "defence_animation": "3880", + "magic_animation": "3882", + "death_animation": "3881", + "name": "Torcher", + "defence_level": "40", + "safespot": null, + "lifepoints": "30", + "strength_level": "1", + "id": "3754", + "aggressive": "true", + "bonuses": "45,40,40,40,25,35,35,0,0,0,0,0,0,0,0", + "range_level": "1", + "projectile": "647", + "attack_level": "1" + }, + { + "examine": "Burn, baby, burn!", + "start_gfx": "646", + "combat_style": "2", + "melee_animation": "3882", + "range_animation": "3882", + "combat_audio": "845,848,846", + "magic_level": "40", + "respawn_delay": "120", + "end_gfx": "648", + "defence_animation": "3880", + "magic_animation": "3882", + "death_animation": "3881", + "name": "Torcher", + "defence_level": "40", + "safespot": null, + "lifepoints": "30", + "strength_level": "1", + "id": "3755", + "aggressive": "true", + "bonuses": "45,40,40,40,25,35,35,0,0,0,0,0,0,0,0", + "range_level": "1", + "projectile": "647", + "attack_level": "1" + }, + { + "examine": "Burn, baby, burn!", + "start_gfx": "646", + "combat_style": "2", + "melee_animation": "3882", + "range_animation": "3882", + "combat_audio": "845,848,846", + "magic_level": "50", + "respawn_delay": "120", + "end_gfx": "648", + "defence_animation": "3880", + "magic_animation": "3882", + "death_animation": "3881", + "name": "Torcher", + "defence_level": "50", + "safespot": null, + "lifepoints": "42", + "strength_level": "1", + "id": "3756", + "aggressive": "true", + "bonuses": "35,40,40,40,30,35,35,0,0,0,0,0,0,0,0", + "range_level": "1", + "projectile": "647", + "attack_level": "1" + }, + { + "examine": "Burn, baby, burn!", + "start_gfx": "646", + "combat_style": "2", + "melee_animation": "3882", + "range_animation": "3882", + "combat_audio": "845,848,846", + "magic_level": "50", + "respawn_delay": "120", + "end_gfx": "648", + "defence_animation": "3880", + "magic_animation": "3882", + "death_animation": "3881", + "name": "Torcher", + "defence_level": "50", + "safespot": null, + "lifepoints": "42", + "strength_level": "1", + "id": "3757", + "aggressive": "true", + "bonuses": "35,40,40,40,30,35,35,0,0,0,0,0,0,0,0", + "range_level": "1", + "projectile": "647", + "attack_level": "1" + }, + { + "examine": "Burn, baby, burn!", + "start_gfx": "646", + "combat_style": "2", + "melee_animation": "3882", + "range_animation": "3882", + "combat_audio": "845,848,846", + "magic_level": "60", + "respawn_delay": "120", + "end_gfx": "648", + "defence_animation": "3880", + "magic_animation": "3882", + "death_animation": "3881", + "name": "Torcher", + "defence_level": "60", + "safespot": null, + "lifepoints": "51", + "strength_level": "1", + "id": "3758", + "aggressive": "true", + "bonuses": "60,80,80,80,50,50,35,0,0,0,0,0,0,0,0", + "range_level": "1", + "projectile": "647", + "attack_level": "1" + }, + { + "examine": "Burn, baby, burn!", + "start_gfx": "646", + "combat_style": "2", + "melee_animation": "3882", + "range_animation": "3882", + "combat_audio": "845,848,846", + "magic_level": "60", + "respawn_delay": "120", + "end_gfx": "648", + "defence_animation": "3880", + "magic_animation": "3882", + "death_animation": "3881", + "name": "Torcher", + "defence_level": "60", + "safespot": null, + "lifepoints": "51", + "strength_level": "1", + "id": "3759", + "aggressive": "true", + "bonuses": "60,80,80,80,50,50,35,0,0,0,0,0,0,0,0", + "range_level": "1", + "projectile": "647", + "attack_level": "1" + }, + { + "examine": "Burn, baby, burn!", + "start_gfx": "646", + "combat_style": "2", + "melee_animation": "3882", + "range_animation": "3882", + "combat_audio": "845,848,846", + "magic_level": "70", + "respawn_delay": "120", + "end_gfx": "648", + "defence_animation": "3880", + "magic_animation": "3882", + "death_animation": "3881", + "name": "Torcher", + "defence_level": "70", + "safespot": null, + "lifepoints": "62", + "strength_level": "1", + "id": "3760", + "aggressive": "true", + "bonuses": "40,100,100,100,50,50,35,0,0,0,0,0,0,0,0", + "range_level": "1", + "projectile": "647", + "attack_level": "1" + }, + { + "examine": "Burn, baby, burn!", + "start_gfx": "646", + "combat_style": "2", + "melee_animation": "3882", + "range_animation": "3882", + "combat_audio": "845,848,846", + "magic_level": "70", + "respawn_delay": "120", + "end_gfx": "648", + "defence_animation": "3880", + "magic_animation": "3882", + "death_animation": "3881", + "name": "Torcher", + "defence_level": "70", + "safespot": null, + "lifepoints": "62", + "strength_level": "1", + "id": "3761", + "aggressive": "true", + "bonuses": "40,100,100,100,50,50,35,0,0,0,0,0,0,0,0", + "range_level": "1", + "projectile": "647", + "attack_level": "1" + }, + { + "examine": "Duck!", + "start_gfx": "657", + "combat_style": "1", + "melee_animation": "3920", + "range_animation": "3920", + "combat_audio": "392,394,393", + "magic_level": "30", + "respawn_delay": "120", + "defence_animation": "3921", + "weakness": "0", + "magic_animation": "3920", + "death_animation": "3922", + "name": "Defiler", + "defence_level": "25", + "safespot": null, + "lifepoints": "27", + "strength_level": "1", + "id": "3762", + "aggressive": "true", + "bonuses": "20,40,40,40,40,40,40,40,0,0,0,0,0,0,0", + "range_level": "25", + "projectile": "657", + "attack_level": "1" + }, + { + "examine": "Duck!", + "combat_style": "1", + "melee_animation": "3920", + "range_animation": "3920", + "combat_audio": "392,394,393", + "magic_level": "30", + "respawn_delay": "120", + "defence_animation": "3921", + "magic_animation": "3920", + "death_animation": "3922", + "name": "Defiler", + "defence_level": "25", + "safespot": null, + "lifepoints": "27", + "strength_level": "1", + "id": "3763", + "aggressive": "true", + "bonuses": "20,40,40,40,40,40,40,40,0,0,0,0,0,0,0", + "range_level": "25", + "projectile": "657", + "attack_level": "1" + }, + { + "examine": "Duck!", + "start_gfx": "657", + "combat_style": "1", + "melee_animation": "3920", + "range_animation": "3920", + "combat_audio": "392,394,393", + "magic_level": "40", + "respawn_delay": "120", + "defence_animation": "3921", + "magic_animation": "3920", + "death_animation": "3922", + "name": "Defiler", + "defence_level": "40", + "safespot": null, + "lifepoints": "45", + "strength_level": "1", + "id": "3764", + "aggressive": "true", + "bonuses": "30,50,60,60,60,60,40,40,0,0,0,0,0,0,0", + "range_level": "40", + "projectile": "657", + "attack_level": "1" + }, + { + "examine": "Duck!", + "combat_style": "1", + "melee_animation": "3920", + "range_animation": "3920", + "combat_audio": "392,394,393", + "magic_level": "40", + "respawn_delay": "120", + "defence_animation": "3921", + "magic_animation": "3920", + "death_animation": "3922", + "name": "Defiler", + "defence_level": "40", + "safespot": null, + "lifepoints": "45", + "strength_level": "1", + "id": "3765", + "aggressive": "true", + "bonuses": "30,40,60,60,60,60,40,40,0,0,0,0,0,0,0", + "range_level": "40", + "projectile": "657", + "attack_level": "1" + }, + { + "examine": "Duck!", + "start_gfx": "657", + "combat_style": "1", + "melee_animation": "3920", + "range_animation": "3920", + "combat_audio": "392,394,393", + "magic_level": "50", + "respawn_delay": "120", + "defence_animation": "3921", + "magic_animation": "3920", + "death_animation": "3922", + "name": "Defiler", + "defence_level": "50", + "safespot": null, + "lifepoints": "62", + "strength_level": "1", + "id": "3766", + "aggressive": "true", + "bonuses": "35,65,70,70,70,70,40,40,0,0,0,0,0,0,0", + "range_level": "50", + "projectile": "657", + "attack_level": "1" + }, + { + "examine": "Duck!", + "combat_style": "1", + "melee_animation": "3920", + "range_animation": "3920", + "combat_audio": "392,394,393", + "magic_level": "50", + "respawn_delay": "120", + "defence_animation": "3921", + "magic_animation": "3920", + "death_animation": "3922", + "name": "Defiler", + "defence_level": "50", + "safespot": null, + "lifepoints": "62", + "strength_level": "1", + "id": "3767", + "aggressive": "true", + "bonuses": "35,65,70,70,70,70,40,40,0,0,0,0,0,0,0", + "range_level": "50", + "projectile": "657", + "attack_level": "1" + }, + { + "examine": "Duck!", + "start_gfx": "657", + "combat_style": "1", + "melee_animation": "3920", + "range_animation": "3920", + "combat_audio": "392,394,393", + "magic_level": "60", + "respawn_delay": "120", + "defence_animation": "3921", + "magic_animation": "3920", + "death_animation": "3922", + "name": "Defiler", + "defence_level": "60", + "safespot": null, + "lifepoints": "78", + "strength_level": "1", + "id": "3768", + "aggressive": "true", + "bonuses": "40,90,80,80,80,80,40,40,0,0,0,0,0,0,0", + "range_level": "60", + "projectile": "657", + "attack_level": "1" + }, + { + "examine": "Duck!", + "combat_style": "1", + "melee_animation": "3920", + "range_animation": "3920", + "combat_audio": "392,394,393", + "magic_level": "60", + "respawn_delay": "120", + "defence_animation": "3921", + "magic_animation": "3920", + "death_animation": "3922", + "name": "Defiler", + "defence_level": "60", + "safespot": null, + "lifepoints": "78", + "strength_level": "1", + "id": "3769", + "aggressive": "true", + "bonuses": "40,90,80,80,80,80,40,40,0,0,0,0,0,0,0", + "range_level": "60", + "projectile": "657", + "attack_level": "1" + }, + { + "examine": "Duck!", + "start_gfx": "657", + "combat_style": "1", + "melee_animation": "3920", + "range_animation": "3920", + "combat_audio": "392,394,393", + "magic_level": "70", + "respawn_delay": "120", + "defence_animation": "3921", + "magic_animation": "3920", + "death_animation": "3922", + "name": "Defiler", + "defence_level": "70", + "safespot": null, + "lifepoints": "97", + "strength_level": "1", + "id": "3770", + "aggressive": "true", + "bonuses": "50,100,100,100,120,100,40,40,80,0,0,0,0,0,0", + "range_level": "70", + "projectile": "657", + "attack_level": "1" + }, + { + "examine": "Duck!", + "combat_style": "1", + "melee_animation": "3920", + "range_animation": "3920", + "combat_audio": "392,394,393", + "magic_level": "70", + "respawn_delay": "120", + "defence_animation": "3921", + "magic_animation": "3920", + "death_animation": "3922", + "name": "Defiler", + "defence_level": "70", + "safespot": null, + "lifepoints": "97", + "strength_level": "1", + "id": "3771", + "aggressive": "true", + "bonuses": "50,100,100,100,120,100,40,40,80,0,0,0,0,0,0", + "range_level": "70", + "projectile": "657", + "attack_level": "1" + }, + { + "examine": "Mind your toes!", + "melee_animation": "3896", + "range_animation": "3896", + "combat_audio": "323,326,325", + "magic_level": "14", + "respawn_delay": "120", + "defence_animation": "3895", + "weakness": "9", + "magic_animation": "3896", + "death_animation": "3894", + "name": "Brawler", + "defence_level": "28", + "safespot": null, + "lifepoints": "53", + "strength_level": "28", + "id": "3772", + "aggressive": "true", + "bonuses": "45,45,50,50,50,50,50,15,50,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "28" + }, + { + "examine": "Mind your toes!", + "melee_animation": "3896", + "range_animation": "3896", + "combat_audio": "323,326,325", + "magic_level": "21", + "respawn_delay": "120", + "defence_animation": "3895", + "magic_animation": "3896", + "death_animation": "3894", + "name": "Brawler", + "defence_level": "42", + "safespot": null, + "lifepoints": "83", + "strength_level": "42", + "id": "3773", + "aggressive": "true", + "bonuses": "45,45,60,50,50,50,50,15,50,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "42" + }, + { + "examine": "Mind your toes!", + "melee_animation": "3896", + "range_animation": "3896", + "combat_audio": "323,326,325", + "magic_level": "32", + "respawn_delay": "120", + "defence_animation": "3895", + "magic_animation": "3896", + "death_animation": "3894", + "name": "Brawler", + "defence_level": "56", + "safespot": null, + "lifepoints": "113", + "strength_level": "56", + "id": "3774", + "aggressive": "true", + "bonuses": "45,45,60,80,80,80,80,25,50,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "56" + }, + { + "examine": "Mind your toes!", + "melee_animation": "3896", + "range_animation": "3896", + "combat_audio": "323,326,325", + "magic_level": "38", + "respawn_delay": "120", + "defence_animation": "3895", + "magic_animation": "3896", + "death_animation": "3894", + "name": "Brawler", + "defence_level": "74", + "safespot": null, + "lifepoints": "143", + "strength_level": "74", + "id": "3775", + "aggressive": "true", + "bonuses": "45,45,60,60,60,60,60,20,50,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "74" + }, + { + "examine": "Mind your toes!", + "melee_animation": "3896", + "range_animation": "3896", + "combat_audio": "323,326,325", + "magic_level": "45", + "respawn_delay": "120", + "defence_animation": "3895", + "magic_animation": "3896", + "death_animation": "3894", + "name": "Brawler", + "defence_level": "88", + "safespot": null, + "lifepoints": "173", + "strength_level": "88", + "id": "3776", + "aggressive": "true", + "bonuses": "45,45,80,100,100,100,100,30,46,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "88" + }, + { + "examine": "Cheerful, helpful and optimistic, I'll bet.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Doomsayer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3777", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A squire of balance.", + "attack_speed": "5", + "magic_level": "80", + "respawn_delay": "120", + "name": "Void Knight", + "defence_level": "80", + "safespot": null, + "lifepoints": "200", + "strength_level": "1", + "id": "3782", + "bonuses": "180,180,180,180,80,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Long legged licker.", + "melee_animation": "7260", + "range_animation": "0", + "poisonous": "true", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "7256", + "name": "Frog", + "defence_level": "55", + "safespot": null, + "lifepoints": "78", + "strength_level": "55", + "id": "3783", + "range_level": "1", + "attack_level": "55" + }, + { + "name": "Void Knight", + "defence_level": "1", + "safespot": null, + "lifepoints": "200", + "strength_level": "1", + "attack_speed": "0", + "id": "3784", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "examine": "A squire of balance.", + "attack_speed": "5", + "magic_level": "80", + "respawn_delay": "120", + "name": "Void Knight", + "defence_level": "80", + "safespot": null, + "lifepoints": "200", + "strength_level": "1", + "id": "3785", + "bonuses": "180,180,180,180,80,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A powerful knight of balance.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Void Knight", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3786", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A powerful knight of balance.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Void Knight", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3788", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A squire of balance.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Squire", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3790", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A squire of balance.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Squire", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3791", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A squire of balance.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Squire", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3792", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A squire of balance.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Squire", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3793", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A squire of balance.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Squire", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3794", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A squire of balance.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Squire", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3795", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A squire of balance.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Squire", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3796", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A squire of balance.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Squire", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3797", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A squire of balance.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Squire", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3798", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A squire of balance.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Squire", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3799", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A squire of balance.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Squire", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3800", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A squire of balance.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Squire", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3801", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A squire of balance.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Squire (Novice)", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3802", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Posts things.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Postie Pete", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3805", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Miss Millicent Miller the Miller of Mill Lane Mill.", + "name": "Millie Miller", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3806", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Gillie the Milkmaid milks cows. She's udderly fantastic at it.", + "name": "Gillie Groats", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3807", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Massive beast of War with extra Gnome.", + "melee_animation": "3960", + "range_animation": "3954", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "3962", + "name": "Tortoise", + "defence_level": "36", + "safespot": null, + "lifepoints": "51", + "strength_level": "36", + "id": "3808", + "range_level": "1", + "attack_level": "36" + }, + { + "examine": "Tally Ho!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Captain Dalbur", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3809", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Huzzah!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Captain Bleemadge", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3810", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Up up and away!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Captain Errdo", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3811", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Up up and away!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Captain Klemfoodle", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3812", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A Gnome Arrow-chucker", + "combat_style": "1", + "melee_animation": "190", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "2", + "magic_animation": "0", + "death_animation": "196", + "name": "Gnome Archer", + "defence_level": "30", + "safespot": null, + "lifepoints": "42", + "strength_level": "1", + "id": "3814", + "aggressive": "true", + "range_level": "30", + "attack_level": "1" + }, + { + "examine": "Yee haa!", + "melee_animation": "3969", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "196", + "name": "Gnome Driver", + "defence_level": "33", + "safespot": null, + "lifepoints": "47", + "strength_level": "33", + "id": "3815", + "aggressive": "true", + "range_level": "1", + "attack_level": "33" + }, + { + "examine": "A battle mage of the gnomish variety.", + "combat_style": "2", + "melee_animation": "3968", + "range_animation": "0", + "magic_level": "34", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "5", + "magic_animation": "0", + "death_animation": "196", + "name": "Gnome Mage", + "defence_level": "34", + "safespot": null, + "lifepoints": "48", + "strength_level": "1", + "id": "3816", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The cruel tortoise trainer. Boo!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Trainer Nacklepen", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3818", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A large tortoise.", + "melee_animation": "3960", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "3962", + "name": "Tortoise", + "defence_level": "36", + "safespot": null, + "lifepoints": "51", + "strength_level": "36", + "id": "3819", + "range_level": "1", + "attack_level": "36" + }, + { + "agg_radius": "64", + "melee_animation": "6241", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "6240", + "death_animation": "6242", + "name": "Kalphite Queen", + "defence_level": "1", + "safespot": null, + "lifepoints": "255", + "strength_level": "1", + "id": "3835", + "aggressive": "true", + "range_level": "1000", + "attack_level": "1" + }, + { + "agg_radius": "64", + "melee_animation": "6234", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "6237", + "death_animation": "6233", + "name": "Kalphite Queen", + "defence_level": "1", + "safespot": null, + "lifepoints": "255", + "strength_level": "1", + "id": "3836", + "aggressive": "true", + "range_level": "1000", + "attack_level": "1" + }, + { + "examine": "An aquatic troll.", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "name": "Sea troll", + "defence_level": "45", + "safespot": null, + "lifepoints": "64", + "strength_level": "45", + "id": "3840", + "aggressive": "true", + "range_level": "1", + "attack_level": "45" + }, + { + "examine": "An aquatic troll.", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "name": "Sea troll", + "defence_level": "60", + "safespot": null, + "lifepoints": "85", + "strength_level": "60", + "id": "3843", + "aggressive": "true", + "range_level": "1", + "attack_level": "60" + }, + { + "examine": "The mother of all sea trolls!", + "melee_animation": "3991", + "range_animation": "0", + "magic_level": "65", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "3993", + "name": "Sea Troll Queen", + "defence_level": "65", + "safespot": null, + "lifepoints": "428", + "strength_level": "65", + "id": "3847", + "aggressive": "true", + "range_level": "65", + "attack_level": "65" + }, + { + "examine": "What have they done to him?", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fishing spot", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3849", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of Gielinor's many citizens.", + "melee_animation": "422", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "25", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Man", + "defence_level": "1", + "safespot": null, + "lifepoints": "7", + "strength_level": "1", + "id": "3915", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "His bark's worse than his blight.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Carpenter Kjallak", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3916", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He looks a bit seedy.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Farmer Fromund", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3917", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Snake", + "melee_animation": "3538", + "range_animation": "0", + "combat_audio": "3609,3608,3610", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "1", + "magic_animation": "0", + "death_animation": "3540", + "name": "Sea Snake Young", + "defence_level": "45", + "safespot": null, + "lifepoints": "128", + "strength_level": "33", + "id": "3939", + "aggressive": "true", + "range_level": "45", + "attack_level": "33" + }, + { + "examine": "A baby sea snake. Snaaaaaaake!", + "melee_animation": "3538", + "range_animation": "0", + "combat_audio": "3609,3608,3610", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "1", + "magic_animation": "0", + "death_animation": "3540", + "name": "Sea Snake Hatchling", + "defence_level": "45", + "safespot": null, + "lifepoints": "100", + "strength_level": "33", + "id": "3940", + "aggressive": "true", + "range_level": "45", + "attack_level": "33" + }, + { + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "3941", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He's guarding the entrance to the dungeons.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "3942", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A big snake that lives in the sea. How did it get in here?", + "melee_animation": "4040", + "range_animation": "0", + "combat_audio": "3609,3608,3610", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "1", + "magic_animation": "0", + "death_animation": "4039", + "name": "Giant Sea Snake", + "defence_level": "45", + "safespot": null, + "lifepoints": "385", + "strength_level": "33", + "id": "3943", + "aggressive": "true", + "range_level": "45", + "attack_level": "33" + }, + { + "slayer_exp": "37", + "name": "Cockatrice", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4227", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "slayer_exp": "75", + "name": "Basilisk", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "288,290,289", + "strength_level": "1", + "id": "4228", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Large, heavy, with sharp things attached to its head.", + "melee_animation": "9439", + "range_animation": "9439", + "combat_audio": "588,590,589", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "15", + "defence_animation": "9441", + "slayer_exp": "97", + "magic_animation": "9439", + "death_animation": "9440", + "name": "Kurask", + "defence_level": "105", + "safespot": null, + "lifepoints": "97", + "strength_level": "105", + "id": "4229", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,20,20,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "67" + }, + { + "examine": "A denizen of the Abyss!", + "melee_animation": "1537", + "range_animation": "1537", + "combat_audio": "276,278,277", + "attack_speed": "4", + "magic_level": "1", + "defence_animation": "0", + "weakness": "1", + "slayer_exp": "150", + "magic_animation": "1537", + "death_animation": "1538", + "name": "Abyssal demon", + "defence_level": "135", + "safespot": null, + "lifepoints": "150", + "strength_level": "67", + "id": "4230", + "bonuses": "0,0,0,0,0,20,20,20,0,20,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "97" + }, + { + "name": "Demon butler", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "400,404,403", + "strength_level": "1", + "id": "4243", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Head of the servants' guild.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Chief servant", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4245", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "She smells unpleasantly of chemicals.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Taxidermist", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4246", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A fancy businessman with a mighty fine hat.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Estate agent", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4247", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Someone has to get rid of all the stone they dug Keldagrim out of.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Stonemason", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4248", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He changes the shape of wood.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "703,705,704", + "defence_animation": "0", + "facing_booth": "true", + "magic_animation": "0", + "death_animation": "0", + "name": "Sawmill operator", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4250", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "She has green fingers. (Not literally.)", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Garden supplier", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4251", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Beak areful with this one", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Macaroni Penguin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4252", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "4257", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A dwarven guard.", + "melee_animation": "99", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "102", + "name": "Guard", + "defence_level": "12", + "safespot": null, + "lifepoints": "17", + "strength_level": "12", + "id": "4258", + "aggressive": "true", + "clue_level": "1", + "range_level": "1", + "attack_level": "12" + }, + { + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "4259", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "4260", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "4261", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "4262", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "4263", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "4264", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "4265", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "4266", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "4267", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "4268", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "4269", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "4270", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "4271", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "4272", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "4273", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "4274", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "4275", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "4276", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Animated bronze armour.", + "melee_animation": "386", + "range_animation": "386", + "combat_audio": "2549,1979,512", + "attack_speed": "4", + "respawn_delay": "20", + "defence_animation": "388", + "weakness": "7", + "magic_animation": "386", + "death_animation": "4167", + "name": "Animated Bronze Armour", + "defence_level": "10", + "safespot": null, + "poison_immune": "true", + "lifepoints": "10", + "strength_level": "10", + "id": "4278", + "aggressive": "true", + "bonuses": "4,4,4,0,0,50,25,19,400,400,0,5,0,0,0", + "range_level": "1", + "attack_level": "10" + }, + { + "examine": "Animated iron armour.", + "melee_animation": "386", + "range_animation": "386", + "combat_audio": "2549,1979,512", + "attack_speed": "4", + "respawn_delay": "20", + "defence_animation": "388", + "weakness": "7", + "magic_animation": "386", + "death_animation": "4167", + "name": "Animated Iron Armour", + "defence_level": "20", + "safespot": null, + "poison_immune": "true", + "lifepoints": "20", + "strength_level": "20", + "id": "4279", + "aggressive": "true", + "bonuses": "4,4,4,0,0,50,25,19,400,400,0,5,0,0,0", + "range_level": "1", + "attack_level": "20" + }, + { + "examine": "Animated steel armour.", + "melee_animation": "386", + "range_animation": "386", + "combat_audio": "2549,1979,512", + "attack_speed": "4", + "respawn_delay": "20", + "defence_animation": "388", + "weakness": "7", + "magic_animation": "386", + "death_animation": "4167", + "name": "Animated Steel Armour", + "defence_level": "40", + "safespot": null, + "poison_immune": "true", + "lifepoints": "40", + "strength_level": "40", + "id": "4280", + "aggressive": "true", + "bonuses": "4,4,4,0,0,50,25,19,400,400,0,5,0,0,0", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "Animated black armour.", + "melee_animation": "386", + "range_animation": "386", + "combat_audio": "2549,1979,512", + "attack_speed": "4", + "respawn_delay": "20", + "defence_animation": "388", + "weakness": "7", + "magic_animation": "386", + "death_animation": "4167", + "name": "Animated Black Armour", + "defence_level": "60", + "safespot": null, + "poison_immune": "true", + "lifepoints": "60", + "strength_level": "60", + "id": "4281", + "aggressive": "true", + "bonuses": "4,4,4,0,0,50,25,19,400,400,0,5,0,0,0", + "range_level": "1", + "attack_level": "60" + }, + { + "examine": "Animated mithril armour.", + "melee_animation": "386", + "range_animation": "386", + "combat_audio": "2549,1979,512", + "attack_speed": "4", + "respawn_delay": "20", + "defence_animation": "388", + "weakness": "7", + "magic_animation": "386", + "death_animation": "4167", + "name": "Animated Mithril Armour", + "defence_level": "80", + "safespot": null, + "poison_immune": "true", + "lifepoints": "80", + "strength_level": "80", + "id": "4282", + "aggressive": "true", + "bonuses": "4,4,4,0,0,50,25,19,400,400,0,5,0,0,0", + "range_level": "1", + "attack_level": "80" + }, + { + "examine": "Animated adamant armour.", + "melee_animation": "386", + "range_animation": "386", + "combat_audio": "2549,1979,512", + "attack_speed": "4", + "respawn_delay": "20", + "defence_animation": "388", + "weakness": "7", + "magic_animation": "386", + "death_animation": "4167", + "name": "Animated Adamant Armour", + "defence_level": "99", + "safespot": null, + "poison_immune": "true", + "lifepoints": "99", + "strength_level": "99", + "id": "4283", + "aggressive": "true", + "bonuses": "4,4,4,0,0,50,25,19,400,400,0,5,0,0,0", + "range_level": "1", + "attack_level": "99" + }, + { + "examine": "Animated rune armour.", + "melee_animation": "386", + "range_animation": "386", + "combat_audio": "2549,1979,512", + "attack_speed": "4", + "respawn_delay": "20", + "defence_animation": "388", + "weakness": "7", + "magic_animation": "386", + "death_animation": "4167", + "name": "Animated Rune Armour", + "defence_level": "120", + "safespot": null, + "poison_immune": "true", + "lifepoints": "120", + "strength_level": "120", + "id": "4284", + "aggressive": "true", + "bonuses": "4,4,4,0,0,50,25,19,400,400,0,5,0,0,0", + "range_level": "1", + "attack_level": "120" + }, + { + "examine": "The big door man.", + "name": "Ghommal", + "id": "4285" + }, + { + "examine": "Guild Master.", + "name": "Harrallak Menarous", + "id": "4286" + }, + { + "examine": "The guild engineer.", + "name": "Gamfred", + "id": "4287" + }, + { + "examine": "Used to be a black knight.", + "name": "Ajjat", + "id": "4288" + }, + { + "examine": "Blademistress, skillful female warrior.", + "name": "Kamfreena", + "id": "4289" + }, + { + "examine": "A warrior mage from the east.", + "name": "Shanomi", + "id": "4290" + }, + { + "examine": "A one-eyed man eater.", + "melee_animation": "4652", + "range_animation": "0", + "combat_audio": "448,451,450", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "4651", + "weakness": "8", + "slayer_exp": "75", + "magic_animation": "0", + "death_animation": "4653", + "name": "Cyclops", + "defence_level": "26", + "safespot": null, + "lifepoints": "75", + "strength_level": "50", + "id": "4291", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "47" + }, + { + "examine": "A one-eyed woman eater.", + "melee_animation": "4652", + "range_animation": "0", + "combat_audio": "448,451,450", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "4651", + "weakness": "1", + "slayer_exp": "100", + "magic_animation": "0", + "death_animation": "4653", + "name": "Cyclops", + "defence_level": "35", + "safespot": null, + "lifepoints": "100", + "strength_level": "65", + "id": "4292", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "65" + }, + { + "examine": "Food shopkeeper.", + "name": "Lidio", + "id": "4293" + }, + { + "examine": "Potion shopkeeper.", + "name": "Lilly", + "id": "4294" + }, + { + "examine": "Armour shopkeeper.", + "name": "Anton", + "id": "4295" + }, + { + "examine": "Bank staff.", + "name": "Jade", + "id": "4296" + }, + { + "examine": "He looks like a strong warrior.", + "name": "Sloane", + "id": "4297" + }, + { + "examine": "He looks a bit drunk.", + "name": "Jimmy", + "id": "4298" + }, + { + "examine": "He looks fair and reliable.", + "name": "Ref", + "id": "4299" + }, + { + "examine": "He looks fair and reliable.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ref", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4300", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "4301", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "4302", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "4303", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "4304", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "4305", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "4306", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A guard for the humans against monster group.", + "melee_animation": "390", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Guard", + "defence_level": "26", + "safespot": null, + "lifepoints": "37", + "strength_level": "26", + "id": "4307", + "clue_level": "1", + "range_level": "1", + "attack_level": "26" + }, + { + "melee_animation": "395", + "combat_audio": "511,513,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "22", + "strength_level": "1", + "id": "4308", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "395", + "combat_audio": "511,513,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "22", + "strength_level": "1", + "id": "4309", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "395", + "combat_audio": "511,513,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "22", + "strength_level": "1", + "id": "4310", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "395", + "combat_audio": "511,513,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "22", + "strength_level": "1", + "id": "4311", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "slayer_exp": "16", + "name": "Dwarf", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4316", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "H.A.M. Member", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4318", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "H.A.M. Member", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4320", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "H.A.M. Deacon", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4329", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "395", + "combat_audio": "511,513,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "22", + "strength_level": "1", + "id": "4336", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Snake", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "3609,3608,3610", + "strength_level": "1", + "id": "4343", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "220", + "combat_audio": "629,631,630", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "221", + "death_animation": "223", + "name": "Monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "12", + "strength_level": "1", + "id": "4344", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It's all white by me.", + "melee_animation": "4915", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "4917", + "name": "Albino bat", + "defence_level": "31", + "safespot": null, + "lifepoints": "44", + "strength_level": "31", + "id": "4345", + "range_level": "1", + "attack_level": "31" + }, + { + "examine": "A flying blood sucker.", + "melee_animation": "2397", + "range_animation": "0", + "attack_speed": "10", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "2398", + "name": "Giant mosquito", + "defence_level": "63", + "safespot": null, + "lifepoints": "90", + "strength_level": "63", + "id": "4347", + "range_level": "1", + "attack_level": "63" + }, + { + "examine": "A horrible, emaciated ape like creature with beady red eyes.", + "melee_animation": "4235", + "range_animation": "0", + "combat_audio": "496,500,499", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "50", + "defence_animation": "4232", + "weakness": "7", + "slayer_exp": "45", + "magic_animation": "0", + "death_animation": "4233", + "name": "Jungle horror", + "defence_level": "55", + "safespot": null, + "lifepoints": "45", + "strength_level": "70", + "id": "4348", + "aggressive": "true", + "clue_level": "1", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "70" + }, + { + "examine": "A horrible, emaciated ape like creature with beady yellow eyes.", + "melee_animation": "4234", + "combat_audio": "496,500,499", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "50", + "defence_animation": "4232", + "slayer_exp": "45", + "death_animation": "4233", + "name": "Jungle horror", + "defence_level": "55", + "safespot": null, + "lifepoints": "45", + "strength_level": "70", + "id": "4349", + "aggressive": "true", + "clue_level": "1", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "70" + }, + { + "examine": "A horrible, emaciated ape like creature with beady green eyes.", + "melee_animation": "4235", + "range_animation": "0", + "combat_audio": "496,500,499", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "50", + "defence_animation": "4232", + "weakness": "7", + "slayer_exp": "45", + "magic_animation": "0", + "death_animation": "4233", + "name": "Jungle horror", + "defence_level": "55", + "safespot": null, + "lifepoints": "45", + "strength_level": "70", + "id": "4350", + "aggressive": "true", + "clue_level": "1", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "70" + }, + { + "examine": "A horrible, emaciated ape like creature with beady blue eyes.", + "melee_animation": "4234", + "combat_audio": "496,500,499", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "50", + "defence_animation": "4232", + "slayer_exp": "45", + "death_animation": "4233", + "name": "Jungle horror", + "defence_level": "55", + "safespot": null, + "lifepoints": "45", + "strength_level": "70", + "id": "4351", + "aggressive": "true", + "clue_level": "1", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "70" + }, + { + "examine": "A horrible, emaciated ape like creature with beady pink eyes.", + "melee_animation": "4234", + "combat_audio": "496,500,499", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "50", + "defence_animation": "4232", + "slayer_exp": "45", + "death_animation": "4233", + "name": "Jungle horror", + "defence_level": "55", + "safespot": null, + "lifepoints": "45", + "strength_level": "70", + "id": "4352", + "aggressive": "true", + "clue_level": "1", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "70" + }, + { + "examine": "A horrible, emaciated ape like creature with beady red eyes.", + "melee_animation": "4234", + "range_animation": "4234", + "combat_audio": "496,500,499", + "attack_speed": "4", + "magic_level": "80", + "respawn_delay": "50", + "defence_animation": "4232", + "weakness": "6", + "slayer_exp": "55", + "magic_animation": "4234", + "death_animation": "4233", + "name": "Cave horror", + "defence_level": "62", + "safespot": null, + "lifepoints": "55", + "strength_level": "77", + "id": "4353", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "80" + }, + { + "examine": "A horrible, emaciated ape like creature with beady red eyes.", + "melee_animation": "4234", + "range_animation": "4234", + "combat_audio": "496,500,499", + "attack_speed": "4", + "magic_level": "80", + "respawn_delay": "50", + "defence_animation": "4232", + "weakness": "6", + "slayer_exp": "55", + "magic_animation": "4234", + "death_animation": "4233", + "name": "Cave horror", + "defence_level": "62", + "safespot": null, + "lifepoints": "55", + "strength_level": "77", + "id": "4354", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "80" + }, + { + "examine": "A horrible, emaciated ape like creature with beady red eyes.", + "melee_animation": "4234", + "range_animation": "4234", + "combat_audio": "496,500,499", + "attack_speed": "4", + "magic_level": "80", + "respawn_delay": "50", + "defence_animation": "4232", + "weakness": "6", + "slayer_exp": "55", + "magic_animation": "4234", + "death_animation": "4233", + "name": "Cave horror", + "defence_level": "62", + "safespot": null, + "lifepoints": "55", + "strength_level": "77", + "id": "4355", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "80" + }, + { + "examine": "A horrible, emaciated ape like creature with beady red eyes.", + "melee_animation": "4234", + "range_animation": "4234", + "combat_audio": "496,500,499", + "attack_speed": "4", + "magic_level": "80", + "respawn_delay": "50", + "defence_animation": "4232", + "weakness": "6", + "slayer_exp": "55", + "magic_animation": "4234", + "death_animation": "4233", + "name": "Cave horror", + "defence_level": "62", + "safespot": null, + "lifepoints": "55", + "strength_level": "77", + "id": "4356", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "80" + }, + { + "examine": "A horrible, emaciated ape like creature with beady red eyes.", + "melee_animation": "4234", + "range_animation": "4234", + "combat_audio": "496,500,499", + "attack_speed": "4", + "magic_level": "80", + "respawn_delay": "50", + "defence_animation": "4232", + "weakness": "6", + "slayer_exp": "55", + "magic_animation": "4234", + "death_animation": "4233", + "name": "Cave horror", + "defence_level": "62", + "safespot": null, + "lifepoints": "55", + "strength_level": "77", + "id": "4357", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "80" + }, + { + "examine": "Patchy the pirate.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Patchy", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4359", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A very flamboyant pirate.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fancy Dan", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4361", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "I can't wait to buy from a guy with Honest in his name...", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Honest Jimmy", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4362", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "629,631,630", + "strength_level": "1", + "id": "4363", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Blue Monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "629,631,630", + "strength_level": "1", + "id": "4371", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Red Monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "629,631,630", + "strength_level": "1", + "id": "4372", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A colourful bird.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Parrot", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4373", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A retired Gielinor security guard.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Security Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4375", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A boney ghost.", + "melee_animation": "422", + "range_animation": "422", + "combat_audio": "924,926,925", + "attack_speed": "4", + "defence_animation": "404", + "slayer_exp": "60", + "magic_animation": "422", + "death_animation": "9055", + "name": "Ankou", + "defence_level": "50", + "safespot": null, + "lifepoints": "60", + "strength_level": "69", + "id": "4381", + "aggressive": "true", + "clue_level": "2", + "range_level": "1", + "attack_level": "50" + }, + { + "examine": "A boney ghost.", + "melee_animation": "422", + "range_animation": "422", + "combat_audio": "924,926,925", + "attack_speed": "4", + "defence_animation": "404", + "slayer_exp": "60", + "magic_animation": "422", + "death_animation": "9055", + "name": "Ankou", + "defence_level": "50", + "safespot": null, + "lifepoints": "66", + "strength_level": "69", + "id": "4382", + "aggressive": "true", + "clue_level": "2", + "range_level": "1", + "attack_level": "50" + }, + { + "examine": "A boney ghost.", + "melee_animation": "422", + "range_animation": "422", + "combat_audio": "924,926,925", + "attack_speed": "4", + "defence_animation": "404", + "slayer_exp": "60", + "magic_animation": "422", + "death_animation": "9055", + "name": "Ankou", + "defence_level": "55", + "safespot": null, + "lifepoints": "66", + "strength_level": "74", + "id": "4383", + "aggressive": "true", + "clue_level": "2", + "range_level": "1", + "attack_level": "60" + }, + { + "melee_animation": "5540", + "combat_audio": "436,439,438", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "5541", + "slayer_exp": "25", + "death_animation": "5542", + "name": "Ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "36", + "strength_level": "1", + "id": "4387", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Eeek! A ghost!", + "melee_animation": "5532", + "range_animation": "0", + "combat_audio": "436,439,438", + "attack_speed": "5", + "magic_level": "30", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "5", + "magic_animation": "0", + "death_animation": "5534", + "name": "Ghost", + "defence_level": "30", + "safespot": null, + "lifepoints": "42", + "strength_level": "1", + "id": "4388", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "I don't think insect repellent will work.", + "melee_animation": "1184", + "range_animation": "1184", + "combat_audio": "571,573,572", + "attack_speed": "3", + "respawn_delay": "30", + "defence_animation": "1186", + "weakness": "0", + "slayer_exp": "25", + "magic_animation": "1184", + "death_animation": "1190", + "name": "Flesh Crawler", + "defence_level": "10", + "safespot": null, + "lifepoints": "25", + "strength_level": "2", + "id": "4389", + "aggressive": "true", + "bonuses": "0,0,0,0,0,15,15,15,15,15,15,15,15,15,15", + "range_level": "1", + "attack_level": "60" + }, + { + "examine": "I don't think insect repellent will work.", + "melee_animation": "1184", + "range_animation": "1184", + "combat_audio": "571,573,572", + "attack_speed": "3", + "respawn_delay": "30", + "defence_animation": "1186", + "slayer_exp": "25", + "magic_animation": "1184", + "death_animation": "1190", + "name": "Flesh Crawler", + "defence_level": "10", + "safespot": null, + "lifepoints": "25", + "strength_level": "2", + "id": "4390", + "aggressive": "true", + "bonuses": "0,0,0,0,0,15,15,15,15,15,15,15,15,15,15", + "range_level": "1", + "attack_level": "80" + }, + { + "examine": "I don't think insect repellent will work.", + "melee_animation": "1184", + "range_animation": "1184", + "combat_audio": "571,573,572", + "attack_speed": "3", + "respawn_delay": "30", + "defence_animation": "1186", + "slayer_exp": "25", + "magic_animation": "1184", + "death_animation": "1190", + "name": "Flesh Crawler", + "defence_level": "10", + "safespot": null, + "lifepoints": "25", + "strength_level": "2", + "id": "4391", + "aggressive": "true", + "bonuses": "0,0,0,0,0,15,15,15,15,15,15,15,15,15,15", + "range_level": "1", + "attack_level": "100" + }, + { + "examine": "Dead man walking.", + "melee_animation": "5568", + "range_animation": "5568", + "combat_audio": "918,923,922", + "attack_speed": "5", + "respawn_delay": "30", + "defence_animation": "5567", + "slayer_exp": "30", + "magic_animation": "5568", + "death_animation": "5569", + "name": "Zombie", + "defence_level": "25", + "safespot": null, + "lifepoints": "23", + "strength_level": "1", + "id": "4392", + "aggressive": "true", + "bonuses": "15,25,25,25,25,25,25,15,15,25,25,25,25,25,25", + "range_level": "1", + "attack_level": "24" + }, + { + "examine": "Dead man walking.", + "melee_animation": "5578", + "range_animation": "5578", + "combat_audio": "918,923,922", + "attack_speed": "5", + "respawn_delay": "30", + "defence_animation": "5579", + "slayer_exp": "30", + "magic_animation": "5578", + "death_animation": "5580", + "name": "Zombie", + "defence_level": "28", + "safespot": null, + "lifepoints": "18", + "strength_level": "1", + "id": "4393", + "aggressive": "true", + "bonuses": "15,25,28,28,25,28,28,15,15,28,25,25,25,25,25", + "range_level": "1", + "attack_level": "35" + }, + { + "examine": "Dead man walking.", + "melee_animation": "5578", + "range_animation": "5578", + "combat_audio": "918,923,922", + "attack_speed": "5", + "respawn_delay": "30", + "defence_animation": "5579", + "slayer_exp": "30", + "magic_animation": "5578", + "death_animation": "5580", + "name": "Zombie", + "defence_level": "48", + "safespot": null, + "lifepoints": "40", + "strength_level": "1", + "id": "4394", + "aggressive": "true", + "bonuses": "35,45,45,45,45,45,45,35,35,45,45,45,45,45,45", + "range_level": "1", + "attack_level": "47" + }, + { + "examine": "Overgrown vermin.", + "combat_audio": "703,705,704", + "melee_animation": "4933", + "attack_speed": "5", + "defence_animation": "4934", + "weakness": "9", + "death_animation": "4935", + "name": "Giant rat", + "defence_level": "23", + "safespot": null, + "lifepoints": "26", + "strength_level": "20", + "id": "4395", + "aggressive": "true", + "bonuses": "19,15,15,34,36,38,33,31,30,14,0,0,0,0,0", + "range_level": "1", + "attack_level": "21" + }, + { + "examine": "A popular dwarven delicacy.", + "melee_animation": "2705", + "range_animation": "2705", + "combat_audio": "710,713,711", + "attack_speed": "5", + "defence_animation": "2706", + "magic_animation": "2705", + "death_animation": "2707", + "name": "Rat", + "defence_level": "1", + "safespot": null, + "lifepoints": "2", + "strength_level": "1", + "id": "4396", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Big Cow-like... But cows don't have serpent tails!", + "melee_animation": "4271", + "combat_audio": "511,330,329", + "attack_speed": "5", + "magic_level": "38", + "spell_id": "7", + "respawn_delay": "74", + "defence_animation": "4273", + "slayer_exp": "50", + "magic_animation": "4272", + "death_animation": "4270", + "name": "Catablepon", + "defence_level": "38", + "safespot": null, + "lifepoints": "50", + "strength_level": "38", + "id": "4397", + "aggressive": "true", + "bonuses": "5,20,15,3,10,20,10,10,20,15,23,25,15,25,10", + "clue_level": "1", + "range_level": "1", + "attack_level": "38" + }, + { + "examine": "Big Cow-like... But cows don't have serpent tails!", + "melee_animation": "4271", + "combat_audio": "511,330,329", + "attack_speed": "5", + "magic_level": "38", + "spell_id": "7", + "respawn_delay": "74", + "defence_animation": "4273", + "slayer_exp": "50", + "magic_animation": "4272", + "death_animation": "4270", + "name": "Catablepon", + "defence_level": "38", + "safespot": null, + "lifepoints": "70", + "strength_level": "38", + "id": "4398", + "aggressive": "true", + "bonuses": "20,25,10,20,25,10,10,11,0,0,0,0,0,0,0", + "clue_level": "1", + "range_level": "1", + "attack_level": "38" + }, + { + "examine": "Big Cow-like... But cows don't have serpent tails!", + "melee_animation": "4271", + "combat_audio": "511,330,329", + "attack_speed": "5", + "magic_level": "45", + "spell_id": "7", + "respawn_delay": "74", + "defence_animation": "4273", + "slayer_exp": "50", + "magic_animation": "4272", + "death_animation": "4270", + "name": "Catablepon", + "defence_level": "38", + "safespot": null, + "lifepoints": "50", + "strength_level": "58", + "id": "4399", + "aggressive": "true", + "bonuses": "50,45,50,40,45,20,30,25,33,25,25,20,20,40,0", + "clue_level": "1", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "I think this spider has been genetically modified.", + "melee_animation": "5327", + "range_animation": "5327", + "combat_audio": "537,539,538", + "defence_animation": "5328", + "magic_animation": "5327", + "death_animation": "5329", + "name": "Giant spider", + "defence_level": "51", + "safespot": null, + "lifepoints": "50", + "strength_level": "45", + "id": "4400", + "aggressive": "true", + "bonuses": "19,21,19,62,45,51,54,63,60,18,0,0,0,0,0", + "range_level": "1", + "attack_level": "48" + }, + { + "melee_animation": "6249", + "combat_audio": "3604,3609,3608", + "respawn_delay": "60", + "defence_animation": "6250", + "death_animation": "6251", + "name": "Spider", + "defence_level": "1", + "safespot": null, + "lifepoints": "22", + "strength_level": "1", + "id": "4401", + "aggressive": "false", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An extremely vicious scorpion.", + "melee_animation": "6254", + "range_animation": "6254", + "combat_audio": "3611,3612,3610", + "attack_speed": "5", + "defence_animation": "6255", + "slayer_exp": "17", + "magic_animation": "6254", + "death_animation": "6256", + "name": "Scorpion", + "defence_level": "49", + "safespot": null, + "lifepoints": "55", + "strength_level": "51", + "id": "4402", + "aggressive": "true", + "bonuses": "12,23,10,51,32,62,29,54,48,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "50" + }, + { + "examine": "An extremely vicious scorpion.", + "melee_animation": "6254", + "range_animation": "6254", + "combat_audio": "3611,3612,3610", + "attack_speed": "5", + "defence_animation": "6255", + "slayer_exp": "17", + "magic_animation": "6254", + "death_animation": "6256", + "name": "Scorpion", + "defence_level": "35", + "safespot": null, + "lifepoints": "37", + "strength_level": "31", + "id": "4403", + "aggressive": "true", + "bonuses": "15,16,12,32,19,38,18,34,32,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "He doesn't look very pleased to see you.", + "melee_animation": "4266", + "range_animation": "4266", + "combat_audio": "626,628,627", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "15", + "defence_animation": "4267", + "weakness": "7", + "slayer_exp": "10", + "magic_animation": "4266", + "death_animation": "4265", + "name": "Minotaur", + "defence_level": "10", + "safespot": null, + "lifepoints": "10", + "strength_level": "10", + "id": "4404", + "aggressive": "false", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "clue_level": "0", + "range_level": "1", + "attack_level": "12" + }, + { + "examine": "He doesn't look very pleased to see you.", + "melee_animation": "4266", + "range_animation": "4266", + "combat_audio": "626,628,627", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "15", + "defence_animation": "4267", + "magic_animation": "4266", + "death_animation": "4265", + "name": "Minotaur", + "defence_level": "10", + "safespot": null, + "lifepoints": "10", + "strength_level": "10", + "id": "4405", + "aggressive": "false", + "bonuses": "11,11,13,11,11,13,11,11,11,13,11,11,11,11,11", + "clue_level": "0", + "range_level": "1", + "attack_level": "12" + }, + { + "examine": "He doesn't look very pleased to see you.", + "melee_animation": "4266", + "range_animation": "4266", + "combat_audio": "626,628,627", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "15", + "defence_animation": "4267", + "slayer_exp": "22", + "magic_animation": "4266", + "death_animation": "4265", + "name": "Minotaur", + "defence_level": "25", + "safespot": null, + "lifepoints": "22", + "strength_level": "25", + "id": "4406", + "aggressive": "false", + "bonuses": "0,0,0,0,0,-10,-10,-10,21,-10,0,0,0,0,0", + "clue_level": "0", + "range_level": "1", + "attack_level": "23" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "3520,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "5", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "4407", + "bonuses": "3,3,3,3,3,3,3,3,3,3,3,3,3,3,3", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "3520,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "slayer_exp": "16", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "11", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "4408", + "bonuses": "8,8,8,8,8,8,8,8,8,8,8,8,8,8,8", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "3520,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "slayer_exp": "7", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "9", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "4409", + "bonuses": "6,6,6,6,6,6,6,6,6,6,6,6,6,6,6", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "3520,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "10", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "4410", + "bonuses": "8,8,8,8,8,8,8,8,8,8,8,8,8,8,8", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "3520,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "17", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "4411", + "bonuses": "10,10,10,10,10,10,10,10,10,10,10,10,10,10,10", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "3520,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "10", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "4412", + "bonuses": "8,8,8,8,8,8,8,8,8,8,8,8,8,8,8", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "They say inside you there are two wolves...", + "melee_animation": "6559", + "range_animation": "6559", + "combat_audio": "481,491,490", + "attack_speed": "5", + "respawn_delay": "30", + "defence_animation": "6557", + "slayer_exp": "15", + "magic_animation": "6559", + "death_animation": "6558", + "name": "Wolf", + "defence_level": "9", + "safespot": null, + "lifepoints": "15", + "strength_level": "1", + "id": "4413", + "bonuses": "7,7,7,7,7,7,7,7,7,7,7,7,7,7,7", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "They say inside you there are two wolves...", + "melee_animation": "6559", + "range_animation": "6559", + "combat_audio": "481,491,490", + "attack_speed": "5", + "respawn_delay": "30", + "defence_animation": "6557", + "slayer_exp": "10", + "magic_animation": "6559", + "death_animation": "6558", + "name": "Wolf", + "defence_level": "7", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4414", + "bonuses": "5,5,5,5,5,5,5,5,5,5,5,5,5,5,5", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A popular dwarven delicacy.", + "melee_animation": "2705", + "range_animation": "2705", + "combat_audio": "710,713,711", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "3", + "defence_animation": "2706", + "slayer_exp": "2", + "magic_animation": "2705", + "death_animation": "2707", + "name": "Rat", + "defence_level": "1", + "safespot": null, + "lifepoints": "2", + "strength_level": "1", + "id": "4415", + "bonuses": "-47,-47,-47,0,0,-42,-42,-42,-42,-42,-42,-53,0,0,0", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "4300", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "4301", + "slayer_exp": "112", + "death_animation": "4302", + "name": "Gorak", + "defence_level": "1", + "safespot": null, + "lifepoints": "112", + "strength_level": "1", + "id": "4418", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A highly enlightened being.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cosmic Being", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4419", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A healing fairy.", + "name": "Fairy Nuff", + "id": "4434" + }, + { + "examine": "Horseplay.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Centaur", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4438", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Horseplay.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Centaur", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4439", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A noble creature!", + "melee_animation": "6376", + "range_animation": "0", + "combat_audio": "812,814,813", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "90", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "6377", + "name": "Stag", + "defence_level": "13", + "safespot": null, + "lifepoints": "19", + "strength_level": "13", + "id": "4440", + "aggressive": "false", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "11" + }, + { + "examine": "Twiggy.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Wood Dryad", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4441", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Fairy ring maintenance division.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fairy Fixit", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4455", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He works in the bank.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ork", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4457", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "She works in the bank.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ork", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4458", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "She works in the bank.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ork", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4459", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A very angry nymph.", + "melee_animation": "94", + "range_animation": "0", + "attack_speed": "6", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "97", + "name": "Tree spirit", + "defence_level": "9", + "safespot": null, + "lifepoints": "12", + "strength_level": "9", + "id": "4470", + "aggressive": "true", + "range_level": "1", + "attack_level": "9" + }, + { + "examine": "A magic training dummy", + "melee_animation": "94", + "range_animation": "0", + "attack_speed": "6", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "97", + "name": "Magic dummy", + "defence_level": "1", + "safespot": null, + "lifepoints": "15", + "strength_level": "1", + "id": "4474", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Who's your mummy?", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Guardian mummy", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4476", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "4479", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "4480", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "4481", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "4482", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "4483", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "4484", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "4485", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "4486", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "4487", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "4488", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "4489", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "4490", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "4491", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "4492", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "General Wartface", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4494", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ugly green creature.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "attack_speed": "5", + "defence_animation": "6183", + "slayer_exp": "5", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "4499", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Is he real or is it just my imagination?", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ethereal Man", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4501", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Does she really exist?", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ethereal Lady", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4502", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He reminds me of my old mathematics teacher.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "703,705,704", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ethereal Numerator", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4503", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The master of accomplishment.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ethereal Expert", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4504", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He knows what is possible.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ethereal Perceptive", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4505", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He knows the past, present and future. But what of my shoe size?", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ethereal Guide", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4506", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Luck is probably on his side.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ethereal Fluke", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4507", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It's like looking in the mirror.", + "melee_animation": "414", + "range_animation": "0", + "magic_level": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Me", + "defence_level": "60", + "safespot": null, + "lifepoints": "171", + "strength_level": "60", + "id": "4509", + "range_level": "60", + "attack_level": "60" + }, + { + "examine": "It's like looking in the mirror.", + "melee_animation": "414", + "range_animation": "0", + "magic_level": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Me", + "defence_level": "60", + "safespot": null, + "lifepoints": "171", + "strength_level": "60", + "id": "4510", + "range_level": "60", + "attack_level": "60" + }, + { + "examine": "Spiritual leader of the Moonclan.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Oneiromancer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4511", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The craziest house I ever did see!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "House", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4512", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "How does it see where to sweep?", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Enchanted Broom", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4521", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "I'm not sure if it's actually doing anything of use.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Enchanted Bucket", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4524", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "4388", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "4384", + "death_animation": "4389", + "name": "Suqah", + "defence_level": "95", + "safespot": null, + "lifepoints": "105", + "strength_level": "95", + "id": "4529", + "aggressive": "true", + "clue_level": "2", + "bonuses": "0,0,0,0,0,50,70,70,90,50,0,0,0,0,0", + "range_level": "1", + "attack_level": "95" + }, + { + "melee_animation": "4388", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "4385", + "death_animation": "4389", + "name": "Suqah", + "defence_level": "95", + "safespot": null, + "lifepoints": "105", + "strength_level": "95", + "id": "4530", + "aggressive": "true", + "clue_level": "2", + "bonuses": "0,0,0,0,0,50,70,70,90,50,0,0,0,0,0", + "range_level": "1", + "attack_level": "95" + }, + { + "melee_animation": "4388", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "4385", + "death_animation": "4389", + "name": "Suqah", + "defence_level": "95", + "safespot": null, + "lifepoints": "105", + "strength_level": "95", + "id": "4531", + "aggressive": "true", + "clue_level": "2", + "bonuses": "0,0,0,0,0,50,70,70,70,50,0,0,0,0,0", + "range_level": "1", + "attack_level": "95" + }, + { + "melee_animation": "4388", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "4384", + "death_animation": "4389", + "name": "Suqah", + "defence_level": "95", + "safespot": null, + "lifepoints": "105", + "strength_level": "95", + "id": "4533", + "aggressive": "true", + "clue_level": "2", + "bonuses": "0,0,0,0,0,50,70,70,90,50,0,0,0,0,0", + "range_level": "1", + "attack_level": "95" + }, + { + "examine": "His beard seems to have a life of its own.", + "melee_animation": "4666", + "range_animation": "4666", + "combat_audio": "449,451,450", + "attack_speed": "6", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "4665", + "weakness": "1", + "slayer_exp": "85", + "magic_animation": "4666", + "death_animation": "4668", + "name": "Moss giant", + "defence_level": "30", + "safespot": null, + "lifepoints": "85", + "strength_level": "30", + "id": "4534", + "aggressive": "true", + "bonuses": "33,33,33,0,0,0,0,0,0,0,0,31,0,0,0", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "Either a very fremennikey pirate, or a very piratey fremnnik.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Lokar Searunner", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4537", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "I always wondered what that job description actually meant...", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cabin boy", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4539", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The High Priest has been transformed into an avatar of Bandos.", + "range_animation": "0", + "magic_level": "55", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "0", + "name": "Captain Bentley", + "defence_level": "55", + "safespot": null, + "lifepoints": "214", + "strength_level": "55", + "id": "4540", + "aggressive": "true", + "range_level": "55", + "attack_level": "55" + }, + { + "examine": "A stickler for hygiene in the kitchen.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "'Beefy' Burns", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4541", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A keen-eyed lookout with a telescope.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "'Eagle-eye' Shultz", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4542", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "First mate to Captain Bentley.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "First mate 'Davey-boy", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4543", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A pirate through and through.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "'Picarron' Pete", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4545", + "range_level": "1", + "attack_level": "1" + }, + { + "death_animation": "836", + "name": "Jake", + "defence_level": "1", + "safespot": null, + "lifepoints": "50", + "melee_animation": "422", + "strength_level": "1", + "id": "4546", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1", + "defence_animation": "425" + }, + { + "examine": "He got his name from his favourite hobby. Reading about beds.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Bedread the bold", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4547", + "range_level": "1", + "attack_level": "1" + }, + { + "death_animation": "836", + "name": "Wilson", + "defence_level": "1", + "safespot": null, + "lifepoints": "50", + "melee_animation": "395", + "strength_level": "1", + "id": "4548", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1", + "defence_animation": "425" + }, + { + "examine": "Nobody really knows why he's called Tommy 2-times...", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Tommy 2-times", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4549", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Don't look him straight in the eyes. He'll eat you alive!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Murky Pat", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4550", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Nice beard.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Jack Sails", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4551", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Is he looking at me?", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "'Beedy-eye' Jones", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4554", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Yes", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Jenny Blade", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4555", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A low-down", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "'Lecherous' Lee", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4556", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Apparently his nickname comes from his fondness for jam.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "'Sticky' Sanders", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4557", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "This person is working on the site.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Digsite workman", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4564", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "This person is working on the site.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Digsite workman", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4565", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Upon examining the examiner you examine it is indeed an examiner!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Examiner", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4566", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Upon examining the examiner you examine it is indeed an examiner!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Examiner", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4567", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Must be hard at work.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Researcher", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4568", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He makes pots.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Generic Diplomat", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4579", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He's very diplomatic.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ambassador Gimblewap", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4580", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Peaceful man!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ambassador Spanfipple", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4581", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Peaceful man!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ambassador Ferrnook", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4582", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Your common man.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Sorrn", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4589", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Your common woman.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Mimm", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4590", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Your common man.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Portobello", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4593", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A gnome pilot off duty", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Captain Ninto", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4594", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A gnome pilot off duty", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Captain Daerkin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4595", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He looks alert and ready for action.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Guard Vemmeldo", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4600", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A generic evil henchman.", + "melee_animation": "390", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Fortress Guard", + "defence_level": "26", + "safespot": null, + "lifepoints": "37", + "strength_level": "26", + "id": "4603", + "range_level": "1", + "attack_level": "26" + }, + { + "examine": "A generic evil henchman.", + "melee_animation": "428", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Fortress Guard", + "defence_level": "26", + "safespot": null, + "lifepoints": "37", + "strength_level": "26", + "id": "4604", + "range_level": "1", + "attack_level": "26" + }, + { + "examine": "A generic evil henchman.", + "melee_animation": "428", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Fortress Guard", + "defence_level": "26", + "safespot": null, + "lifepoints": "37", + "strength_level": "26", + "id": "4605", + "range_level": "1", + "attack_level": "26" + }, + { + "examine": "A generic evil henchman.", + "melee_animation": "390", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Fortress Guard", + "defence_level": "26", + "safespot": null, + "lifepoints": "37", + "strength_level": "26", + "id": "4606", + "range_level": "1", + "attack_level": "26" + }, + { + "examine": "A witch's black cat.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "0", + "name": "Black Cat", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4607", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Monk", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "4608", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Swine.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Saboteur", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4611", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "What is that thing!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "0", + "name": "Evil creature", + "defence_level": "1", + "safespot": null, + "lifepoints": "0", + "strength_level": "1", + "id": "4615", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "4633", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "4634", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "4635", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "4636", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "4637", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A little warrior.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Gnome soldier", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4638", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A little warrior.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Gnome soldier", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4639", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A little warrior.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Gnome soldier", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4640", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A little warrior.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Gnome soldier", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4641", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A little warrior.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Gnome soldier", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4642", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "King Healthorg riding his War Tortoise.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Healthorg and tortoise", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4643", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A weasly, shifty-looking Gnome Mage.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Glouphrie the Untrusted", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4645", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "With the prices he charges, no wonder he can afford to look so sharp.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Trader Stan", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4650", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Looks very stylish.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Trader Crewmember", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4651", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "That suit looks a little briny around the edges.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Trader Crewmember", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4652", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "First storm he is in that hat will blow away.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Trader Crewmember", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4653", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "She'll never be able to climb rigging in that.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Trader Crewmember", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4654", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "High heels on a ship? What is she thinking?", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Trader Crewmember", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4655", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The effect is sort of spoiled by all those tattoos.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Trader Crewmember", + "defence_level": "1", + "movement_radius": "710", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4656", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He works evil magic.", + "start_gfx": "93", + "combat_style": "2", + "melee_animation": "810", + "range_animation": "0", + "combat_audio": "511,513,512", + "magic_level": "6", + "end_gfx": "95", + "respawn_delay": "60", + "defence_animation": "425", + "magic_animation": "711", + "death_animation": "836", + "name": "Dark wizard", + "defence_level": "5", + "safespot": null, + "lifepoints": "12", + "strength_level": "2", + "id": "4659", + "aggressive": "true", + "range_level": "1", + "projectile": "94", + "attack_level": "5" + }, + { + "examine": "He works evil magic.", + "start_gfx": "96", + "combat_style": "2", + "melee_animation": "810", + "range_animation": "0", + "combat_audio": "511,513,512", + "magic_level": "22", + "end_gfx": "98", + "respawn_delay": "60", + "defence_animation": "425", + "magic_animation": "711", + "death_animation": "836", + "name": "Dark wizard", + "defence_level": "14", + "safespot": null, + "lifepoints": "24", + "strength_level": "17", + "id": "4660", + "aggressive": "true", + "range_level": "1", + "projectile": "97", + "attack_level": "17" + }, + { + "examine": "He works evil magic.", + "combat_style": "2", + "combat_audio": "511,513,512", + "attack_speed": "4", + "magic_level": "15", + "respawn_delay": "20", + "defence_animation": "404", + "magic_animation": "711", + "death_animation": "9055", + "name": "Dark wizard", + "defence_level": "15", + "safespot": null, + "lifepoints": "30", + "strength_level": "1", + "id": "4661", + "aggressive": "true", + "range_level": "1", + "projectile": "98", + "attack_level": "1" + }, + { + "examine": "Young but still dangerous.", + "melee_animation": "25", + "range_animation": "25", + "combat_audio": "405,407,406", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "26", + "weakness": "3", + "slayer_exp": "50", + "magic_animation": "25", + "death_animation": "28", + "name": "Baby blue dragon", + "defence_level": "40", + "safespot": null, + "lifepoints": "50", + "strength_level": "40", + "id": "4665", + "aggressive": "true", + "bonuses": "0,0,0,0,0,30,50,50,40,30,0,0,0,0,0", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "Young but still dangerous.", + "combat_audio": "405,407,406", + "melee_animation": "25", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "26", + "slayer_exp": "50", + "weakness": "3", + "magic_animation": "25", + "death_animation": "28", + "name": "Baby blue dragon", + "defence_level": "40", + "safespot": null, + "lifepoints": "50", + "strength_level": "40", + "id": "4666", + "aggressive": "true", + "bonuses": "0,0,0,0,0,30,50,50,40,30,0,0,0,0,0", + "range_level": "1", + "attack_level": "45" + }, + { + "examine": "Young but still dangerous.", + "name": "Baby red dragon", + "defence_level": "1", + "safespot": null, + "lifepoints": "50", + "combat_audio": "405,407,406", + "strength_level": "1", + "id": "4667", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "examine": "Young but still dangerous.", + "name": "Baby red dragon", + "defence_level": "1", + "safespot": null, + "lifepoints": "50", + "combat_audio": "405,407,406", + "strength_level": "1", + "id": "4668", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "examine": "A big powerful dragon.", + "melee_animation": "80", + "range_animation": "80", + "combat_audio": "408,410,409", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "35", + "defence_animation": "89", + "weakness": "3", + "slayer_exp": "143", + "magic_animation": "80", + "death_animation": "92", + "name": "Red dragon", + "defence_level": "130", + "safespot": null, + "lifepoints": "140", + "strength_level": "130", + "id": "4669", + "aggressive": "true", + "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "130" + }, + { + "examine": "A big powerful dragon.", + "melee_animation": "80", + "range_animation": "80", + "combat_audio": "408,410,409", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "35", + "defence_animation": "89", + "weakness": "3", + "slayer_exp": "143", + "magic_animation": "80", + "death_animation": "92", + "name": "Red dragon", + "defence_level": "130", + "safespot": null, + "lifepoints": "140", + "strength_level": "130", + "id": "4670", + "aggressive": "true", + "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "130" + }, + { + "examine": "A big powerful dragon.", + "melee_animation": "80", + "range_animation": "80", + "combat_audio": "408,410,409", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "35", + "defence_animation": "89", + "weakness": "3", + "slayer_exp": "143", + "magic_animation": "80", + "death_animation": "92", + "name": "Red dragon", + "defence_level": "130", + "safespot": null, + "lifepoints": "140", + "strength_level": "130", + "id": "4671", + "aggressive": "true", + "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "130" + }, + { + "examine": "A big powerful dragon.", + "melee_animation": "80", + "range_animation": "80", + "combat_audio": "408,410,409", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "35", + "defence_animation": "89", + "weakness": "3", + "slayer_exp": "143", + "magic_animation": "80", + "death_animation": "92", + "name": "Red dragon", + "defence_level": "130", + "safespot": null, + "lifepoints": "140", + "strength_level": "130", + "id": "4672", + "aggressive": "true", + "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "130" + }, + { + "examine": "A fierce dragon with black scales!", + "melee_animation": "80", + "range_animation": "80", + "combat_audio": "408,410,409", + "attack_speed": "4", + "magic_level": "100", + "respawn_delay": "35", + "defence_animation": "89", + "weakness": "3", + "slayer_exp": "200", + "magic_animation": "80", + "death_animation": "92", + "name": "Black dragon", + "defence_level": "200", + "safespot": null, + "lifepoints": "190", + "strength_level": "200", + "id": "4673", + "aggressive": "true", + "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "200" + }, + { + "examine": "A fierce dragon with black scales!", + "melee_animation": "80", + "range_animation": "80", + "combat_audio": "408,410,409", + "attack_speed": "4", + "magic_level": "100", + "respawn_delay": "35", + "defence_animation": "89", + "weakness": "3", + "slayer_exp": "200", + "magic_animation": "80", + "death_animation": "92", + "name": "Black dragon", + "defence_level": "200", + "safespot": null, + "lifepoints": "190", + "strength_level": "200", + "id": "4674", + "aggressive": "true", + "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "200" + }, + { + "examine": "A fierce dragon with black scales!", + "melee_animation": "80", + "range_animation": "80", + "combat_audio": "408,410,409", + "attack_speed": "4", + "magic_level": "100", + "respawn_delay": "35", + "defence_animation": "89", + "weakness": "3", + "slayer_exp": "200", + "magic_animation": "80", + "death_animation": "92", + "name": "Black dragon", + "defence_level": "200", + "safespot": null, + "lifepoints": "190", + "strength_level": "200", + "id": "4675", + "aggressive": "true", + "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "200" + }, + { + "examine": "A fierce dragon with black scales!", + "melee_animation": "80", + "range_animation": "80", + "combat_audio": "408,410,409", + "attack_speed": "4", + "magic_level": "100", + "respawn_delay": "35", + "defence_animation": "89", + "weakness": "3", + "slayer_exp": "200", + "magic_animation": "80", + "death_animation": "92", + "name": "Black dragon", + "defence_level": "200", + "safespot": null, + "lifepoints": "190", + "strength_level": "200", + "id": "4676", + "aggressive": "true", + "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "200" + }, + { + "examine": "Must be related to Elvarg.", + "melee_animation": "80", + "range_animation": "80", + "combat_audio": "408,410,409", + "attack_speed": "4", + "magic_level": "68", + "respawn_delay": "35", + "defence_animation": "89", + "weakness": "3", + "slayer_exp": "75", + "magic_animation": "80", + "death_animation": "92", + "name": "Green dragon", + "defence_level": "68", + "safespot": null, + "lifepoints": "75", + "strength_level": "68", + "id": "4677", + "aggressive": "true", + "bonuses": "0,0,0,0,0,20,40,40,30,20,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "68" + }, + { + "examine": "Must be related to Elvarg.", + "melee_animation": "80", + "range_animation": "80", + "combat_audio": "408,410,409", + "attack_speed": "4", + "magic_level": "68", + "respawn_delay": "35", + "defence_animation": "89", + "weakness": "3", + "slayer_exp": "75", + "magic_animation": "80", + "death_animation": "92", + "name": "Green dragon", + "defence_level": "68", + "safespot": null, + "lifepoints": "75", + "strength_level": "68", + "id": "4678", + "aggressive": "true", + "bonuses": "0,0,0,0,0,20,40,40,30,20,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "68" + }, + { + "examine": "Must be related to Elvarg.", + "melee_animation": "80", + "range_animation": "80", + "combat_audio": "408,410,409", + "attack_speed": "4", + "magic_level": "68", + "respawn_delay": "35", + "defence_animation": "89", + "weakness": "3", + "slayer_exp": "75", + "magic_animation": "80", + "death_animation": "92", + "name": "Green dragon", + "defence_level": "68", + "safespot": null, + "lifepoints": "75", + "strength_level": "68", + "id": "4679", + "aggressive": "true", + "bonuses": "0,0,0,0,0,20,40,40,30,20,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "68" + }, + { + "examine": "Must be related to Elvarg.", + "melee_animation": "80", + "range_animation": "80", + "combat_audio": "408,410,409", + "attack_speed": "4", + "magic_level": "68", + "respawn_delay": "35", + "defence_animation": "89", + "weakness": "3", + "slayer_exp": "75", + "magic_animation": "80", + "death_animation": "92", + "name": "Green dragon", + "defence_level": "68", + "safespot": null, + "lifepoints": "75", + "strength_level": "68", + "id": "4680", + "aggressive": "true", + "bonuses": "0,0,0,0,0,20,40,40,30,20,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "68" + }, + { + "examine": "A mother dragon.", + "melee_animation": "80", + "range_animation": "80", + "combat_audio": "408,410,409", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "35", + "defence_animation": "89", + "weakness": "3", + "slayer_exp": "108", + "magic_animation": "80", + "death_animation": "92", + "name": "Blue dragon", + "defence_level": "95", + "safespot": null, + "lifepoints": "105", + "strength_level": "95", + "id": "4681", + "aggressive": "true", + "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "95" + }, + { + "examine": "A mother dragon.", + "melee_animation": "80", + "range_animation": "80", + "combat_audio": "408,410,409", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "35", + "defence_animation": "89", + "weakness": "3", + "slayer_exp": "108", + "magic_animation": "80", + "death_animation": "92", + "name": "Blue dragon", + "defence_level": "95", + "safespot": null, + "lifepoints": "105", + "strength_level": "95", + "id": "4682", + "aggressive": "true", + "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "95" + }, + { + "examine": "A mother dragon.", + "melee_animation": "80", + "range_animation": "80", + "combat_audio": "408,410,409", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "35", + "defence_animation": "89", + "weakness": "3", + "slayer_exp": "108", + "magic_animation": "80", + "death_animation": "92", + "name": "Blue dragon", + "defence_level": "95", + "safespot": null, + "lifepoints": "105", + "strength_level": "95", + "id": "4683", + "aggressive": "true", + "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "95" + }, + { + "examine": "A mother dragon.", + "melee_animation": "80", + "range_animation": "80", + "combat_audio": "408,410,409", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "35", + "defence_animation": "89", + "weakness": "3", + "slayer_exp": "108", + "magic_animation": "80", + "death_animation": "92", + "name": "Blue dragon", + "defence_level": "95", + "safespot": null, + "lifepoints": "105", + "strength_level": "95", + "id": "4684", + "aggressive": "true", + "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "95" + }, + { + "examine": "He's got icicles in his beard.", + "melee_animation": "4672", + "range_animation": "0", + "combat_audio": "448,451,450", + "attack_speed": "5", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "0", + "weakness": "9", + "slayer_exp": "70", + "magic_animation": "0", + "death_animation": "4673", + "name": "Ice giant", + "defence_level": "40", + "safespot": null, + "lifepoints": "70", + "strength_level": "40", + "id": "4685", + "aggressive": "true", + "bonuses": "29,29,29,0,0,0,3,2,0,0,0,31,0,0,0", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "He's got icicles in his beard.", + "melee_animation": "4672", + "range_animation": "0", + "combat_audio": "448,451,450", + "attack_speed": "5", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "0", + "weakness": "9", + "slayer_exp": "70", + "magic_animation": "0", + "death_animation": "4673", + "name": "Ice giant", + "defence_level": "40", + "safespot": null, + "lifepoints": "70", + "strength_level": "40", + "id": "4686", + "aggressive": "true", + "bonuses": "29,29,29,0,0,0,3,2,0,0,0,31,0,0,0", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "He's got icicles in his beard.", + "melee_animation": "4672", + "range_animation": "0", + "combat_audio": "448,451,450", + "attack_speed": "5", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "0", + "weakness": "9", + "slayer_exp": "70", + "magic_animation": "0", + "death_animation": "4673", + "name": "Ice giant", + "defence_level": "40", + "safespot": null, + "lifepoints": "70", + "strength_level": "40", + "id": "4687", + "aggressive": "true", + "bonuses": "29,29,29,0,0,0,3,2,0,0,0,31,0,0,0", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "His beard seems to have a life of its own.", + "melee_animation": "4666", + "range_animation": "4666", + "combat_audio": "449,451,450", + "attack_speed": "6", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "4665", + "weakness": "1", + "slayer_exp": "60", + "magic_animation": "4666", + "death_animation": "4668", + "name": "Moss giant", + "defence_level": "30", + "safespot": null, + "lifepoints": "60", + "strength_level": "30", + "id": "4688", + "aggressive": "true", + "bonuses": "33,33,33,0,0,0,0,0,0,0,0,31,0,0,0", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "A very large foe.", + "melee_animation": "4652", + "range_animation": "4652", + "combat_audio": "448,451,450", + "attack_speed": "6", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "4651", + "weakness": "6", + "slayer_exp": "35", + "magic_animation": "4652", + "death_animation": "4653", + "name": "Hill Giant", + "defence_level": "26", + "safespot": null, + "lifepoints": "35", + "strength_level": "22", + "id": "4689", + "aggressive": "true", + "bonuses": "18,18,18,0,0,0,0,0,0,0,0,16,0,0,0", + "range_level": "1", + "attack_level": "18" + }, + { + "examine": "A very large foe.", + "melee_animation": "4652", + "range_animation": "4652", + "combat_audio": "448,451,450", + "attack_speed": "6", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "4651", + "weakness": "6", + "slayer_exp": "35", + "magic_animation": "4652", + "death_animation": "4653", + "name": "Hill Giant", + "defence_level": "26", + "safespot": null, + "lifepoints": "35", + "strength_level": "22", + "id": "4690", + "aggressive": "true", + "bonuses": "18,18,18,0,0,0,0,0,0,0,0,16,0,0,0", + "range_level": "1", + "attack_level": "18" + }, + { + "examine": "A very large foe.", + "melee_animation": "4652", + "range_animation": "4652", + "combat_audio": "448,451,450", + "attack_speed": "6", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "4651", + "weakness": "6", + "slayer_exp": "35", + "magic_animation": "4652", + "death_animation": "4653", + "name": "Hill Giant", + "defence_level": "26", + "safespot": null, + "lifepoints": "35", + "strength_level": "22", + "id": "4691", + "aggressive": "true", + "bonuses": "18,18,18,0,0,0,0,0,0,0,0,16,0,0,0", + "range_level": "1", + "attack_level": "18" + }, + { + "examine": "A very large foe.", + "melee_animation": "4652", + "range_animation": "4652", + "combat_audio": "448,451,450", + "attack_speed": "6", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "4651", + "weakness": "6", + "slayer_exp": "35", + "magic_animation": "4652", + "death_animation": "4653", + "name": "Hill Giant", + "defence_level": "26", + "safespot": null, + "lifepoints": "35", + "strength_level": "22", + "id": "4692", + "aggressive": "true", + "bonuses": "18,18,18,0,0,0,0,0,0,0,0,16,0,0,0", + "range_level": "1", + "attack_level": "18" + }, + { + "examine": "A very large foe.", + "melee_animation": "4652", + "range_animation": "4652", + "combat_audio": "448,451,450", + "attack_speed": "6", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "4651", + "weakness": "6", + "slayer_exp": "35", + "magic_animation": "4652", + "death_animation": "4653", + "name": "Hill Giant", + "defence_level": "26", + "safespot": null, + "lifepoints": "35", + "strength_level": "22", + "id": "4693", + "aggressive": "true", + "bonuses": "18,18,18,0,0,0,0,0,0,0,0,16,0,0,0", + "range_level": "1", + "attack_level": "18" + }, + { + "examine": "Lesser, but still pretty big.", + "melee_animation": "4630", + "range_animation": "4630", + "combat_audio": "400,404,403", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "65", + "weakness": "4", + "slayer_exp": "79", + "magic_animation": "4630", + "death_animation": "67", + "name": "Lesser demon", + "defence_level": "71", + "safespot": null, + "lifepoints": "79", + "strength_level": "70", + "id": "4694", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,-10,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "68" + }, + { + "examine": "Lesser, but still pretty big.", + "melee_animation": "4630", + "range_animation": "4630", + "combat_audio": "400,404,403", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "65", + "weakness": "4", + "slayer_exp": "79", + "magic_animation": "4630", + "death_animation": "67", + "name": "Lesser demon", + "defence_level": "71", + "safespot": null, + "lifepoints": "79", + "strength_level": "70", + "id": "4695", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,-10,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "68" + }, + { + "examine": "Lesser, but still pretty big.", + "melee_animation": "4630", + "range_animation": "4630", + "combat_audio": "400,404,403", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "65", + "weakness": "4", + "slayer_exp": "79", + "magic_animation": "4630", + "death_animation": "67", + "name": "Lesser demon", + "defence_level": "71", + "safespot": null, + "lifepoints": "79", + "strength_level": "70", + "id": "4696", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,-10,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "68" + }, + { + "examine": "Lesser, but still pretty big.", + "melee_animation": "4630", + "range_animation": "4630", + "combat_audio": "400,404,403", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "65", + "weakness": "4", + "slayer_exp": "79", + "magic_animation": "4630", + "death_animation": "67", + "name": "Lesser demon", + "defence_level": "71", + "safespot": null, + "lifepoints": "79", + "strength_level": "70", + "id": "4697", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,-10,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "68" + }, + { + "examine": "Big, red, and incredibly evil.", + "melee_animation": "64", + "range_animation": "64", + "combat_audio": "400,404,403", + "attack_speed": "5", + "magic_level": "59", + "respawn_delay": "32", + "defence_animation": "65", + "weakness": "4", + "slayer_exp": "87", + "magic_animation": "64", + "death_animation": "68", + "name": "Greater demon", + "defence_level": "59", + "safespot": null, + "lifepoints": "87", + "strength_level": "59", + "id": "4698", + "aggressive": "true", + "bonuses": "30,20,20,30,20,50,50,50,10,50,20,0,0,0,0", + "clue_level": "2", + "range_level": "59", + "attack_level": "59" + }, + { + "examine": "Big, red, and incredibly evil.", + "melee_animation": "64", + "range_animation": "64", + "combat_audio": "400,404,403", + "attack_speed": "5", + "magic_level": "59", + "respawn_delay": "32", + "defence_animation": "65", + "weakness": "4", + "slayer_exp": "87", + "magic_animation": "64", + "death_animation": "68", + "name": "Greater demon", + "defence_level": "59", + "safespot": null, + "lifepoints": "87", + "strength_level": "59", + "id": "4699", + "aggressive": "true", + "bonuses": "30,20,20,30,20,50,50,50,10,50,20,0,0,0,0", + "clue_level": "2", + "range_level": "59", + "attack_level": "59" + }, + { + "examine": "Big, red, and incredibly evil.", + "melee_animation": "64", + "range_animation": "64", + "combat_audio": "400,404,403", + "attack_speed": "5", + "magic_level": "59", + "respawn_delay": "32", + "defence_animation": "65", + "weakness": "4", + "slayer_exp": "87", + "magic_animation": "64", + "death_animation": "68", + "name": "Greater demon", + "defence_level": "59", + "safespot": null, + "lifepoints": "87", + "strength_level": "59", + "id": "4700", + "aggressive": "true", + "bonuses": "30,20,20,30,20,50,50,50,10,50,20,0,0,0,0", + "clue_level": "2", + "range_level": "59", + "attack_level": "59" + }, + { + "examine": "Big, red, and incredibly evil.", + "melee_animation": "64", + "range_animation": "64", + "combat_audio": "400,404,403", + "attack_speed": "5", + "magic_level": "59", + "respawn_delay": "32", + "defence_animation": "65", + "weakness": "4", + "slayer_exp": "87", + "magic_animation": "64", + "death_animation": "68", + "name": "Greater demon", + "defence_level": "59", + "safespot": null, + "lifepoints": "87", + "strength_level": "59", + "id": "4701", + "aggressive": "true", + "bonuses": "30,20,20,30,20,50,50,50,10,50,20,0,0,0,0", + "clue_level": "2", + "range_level": "59", + "attack_level": "59" + }, + { + "examine": "A big, scary, jet-black demon.", + "melee_animation": "64", + "range_animation": "64", + "combat_audio": "397,399,398", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "65", + "weakness": "4", + "slayer_exp": "157", + "magic_animation": "64", + "death_animation": "67", + "name": "Black demon", + "defence_level": "152", + "safespot": null, + "lifepoints": "157", + "strength_level": "148", + "id": "4702", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,-10,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "145" + }, + { + "examine": "A big, scary, jet-black demon.", + "melee_animation": "64", + "range_animation": "64", + "combat_audio": "397,399,398", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "65", + "weakness": "4", + "slayer_exp": "157", + "magic_animation": "64", + "death_animation": "67", + "name": "Black demon", + "defence_level": "152", + "safespot": null, + "lifepoints": "157", + "strength_level": "148", + "id": "4703", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,-10,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "145" + }, + { + "examine": "A big, scary, jet-black demon.", + "melee_animation": "64", + "range_animation": "64", + "combat_audio": "397,399,398", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "65", + "weakness": "4", + "slayer_exp": "157", + "magic_animation": "64", + "death_animation": "67", + "name": "Black demon", + "defence_level": "152", + "safespot": null, + "lifepoints": "157", + "strength_level": "148", + "id": "4704", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,-10,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "145" + }, + { + "examine": "A big, scary, jet-black demon.", + "melee_animation": "64", + "range_animation": "64", + "combat_audio": "397,399,398", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "65", + "weakness": "4", + "slayer_exp": "157", + "magic_animation": "64", + "death_animation": "67", + "name": "Black demon", + "defence_level": "152", + "safespot": null, + "lifepoints": "157", + "strength_level": "148", + "id": "4705", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,-10,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "145" + }, + { + "examine": "His beard seems to have a life of its own.", + "melee_animation": "4666", + "range_animation": "4666", + "combat_audio": "449,451,450", + "attack_speed": "6", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "4665", + "weakness": "1", + "slayer_exp": "85", + "magic_animation": "4666", + "death_animation": "4668", + "name": "Moss giant", + "defence_level": "30", + "safespot": null, + "lifepoints": "85", + "strength_level": "30", + "id": "4706", + "aggressive": "true", + "bonuses": "33,33,33,0,0,0,0,0,0,0,0,31,0,0,0", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "Mikasi looks ready to teach you about magic.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Magic Tutor", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4707", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A flea-infested", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Old Man Ral", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4708", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A flea-infested black market trader.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Trader Sven", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4716", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A flea-infested", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Meiyerditch citizen", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4717", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A flea-infested", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Meiyerditch citizen", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4718", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "This citizen looks pale", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Meiyerditch citizen", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4719", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "This citizen looks pale", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Meiyerditch citizen", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4720", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "This citizen looks pale", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Meiyerditch citizen", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4721", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "This citizen looks pale", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Meiyerditch citizen", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4722", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "This citizen looks pale", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Meiyerditch citizen", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4723", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "This citizen looks pale", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Meiyerditch citizen", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4724", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "This citizen looks pale", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Meiyerditch citizen", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4725", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "This citizen looks pale", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Meiyerditch citizen", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4726", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Cowardly mage.", + "magic_level": "90", + "defence_animation": "0", + "magic_animation": "0", + "name": "Meiyerditch citizen", + "defence_level": "60", + "safespot": null, + "lifepoints": "28", + "strength_level": "1", + "id": "4733", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "This citizen looks pale", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Meiyerditch citizen", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4734", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "This citizen looks pale", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Meiyerditch citizen", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4735", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "This citizen looks pale", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Meiyerditch citizen", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4736", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "This citizen looks pale", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Meiyerditch citizen", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4737", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "This citizen looks pale", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Meiyerditch citizen", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4738", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "This citizen looks pale", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Meiyerditch citizen", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4739", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "This citizen looks pale", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Meiyerditch citizen", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4740", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "This citizen looks pale", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Meiyerditch citizen", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4741", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A poor street urchin!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "A Meiyerditch child", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4746", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A poor street urchin!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "A Meiyerditch child", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4747", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A poor street urchin!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "A Meiyerditch child", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4748", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A poor street urchin!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "A Meiyerditch child", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4749", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A poor street urchin!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "A Meiyerditch child", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4750", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A poor street urchin!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "A Meiyerditch child", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4751", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A poor street urchin!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "A Meiyerditch child", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4752", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A poor street urchin!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "A Meiyerditch child", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4753", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A poor street urchin!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "A Meiyerditch child", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4754", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A poor street urchin!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "A Meiyerditch child", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4755", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "This citizen looks dirty and tired!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Meiyerditch miner", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4756", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "This citizen looks dirty and tired!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Meiyerditch miner", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4757", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "This citizen looks dirty and tired!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Meiyerditch miner", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4759", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Some rubbish.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "null", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4765", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Looks like it's got fleas!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Stray dog", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4766", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A smelly cat.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cat", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4768", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An initiate juvenile vampyre; a guard for the mining area.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "weakness": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Juvinate guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4772", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An initiate juvenile vampyre; a guard for the mining area.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "weakness": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Juvinate guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4773", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A juvenile vampyre.", + "melee_animation": "6276", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "6781", + "name": "Vampyre juvenile", + "defence_level": "40", + "safespot": null, + "lifepoints": "57", + "strength_level": "40", + "id": "4774", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "A juvenile vampyre.", + "melee_animation": "6276", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "6781", + "name": "Vampyre juvenile", + "defence_level": "40", + "safespot": null, + "lifepoints": "57", + "strength_level": "40", + "id": "4775", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "An initiate juvenile vampyre; seems to be a servant.", + "melee_animation": "5783", + "range_animation": "0", + "defence_animation": "0", + "weakness": "0", + "magic_animation": "0", + "death_animation": "5798", + "name": "Vampyre juvinate", + "defence_level": "44", + "safespot": null, + "lifepoints": "62", + "strength_level": "1", + "id": "4776", + "range_level": "44", + "attack_level": "1" + }, + { + "examine": "An initiate juvenile vampyre.", + "melee_animation": "5783", + "range_animation": "0", + "defence_animation": "0", + "weakness": "0", + "magic_animation": "0", + "death_animation": "5798", + "name": "Vampyre juvinate", + "defence_level": "44", + "safespot": null, + "lifepoints": "62", + "strength_level": "1", + "id": "4777", + "range_level": "44", + "attack_level": "1" + }, + { + "examine": "A juvenile vampyre.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "6781", + "name": "Held vampyre juvenile", + "defence_level": "40", + "safespot": null, + "lifepoints": "57", + "strength_level": "40", + "id": "4778", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "A juvenile vampyre.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "6781", + "name": "Held vampyre juvenile", + "defence_level": "40", + "safespot": null, + "lifepoints": "57", + "strength_level": "40", + "id": "4779", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "An initiate juvenile vampyre; seems to be a servant.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "weakness": "0", + "magic_animation": "0", + "death_animation": "5798", + "name": "Held vampyre juvinate", + "defence_level": "44", + "safespot": null, + "lifepoints": "62", + "strength_level": "1", + "id": "4780", + "range_level": "44", + "attack_level": "1" + }, + { + "examine": "An enraged vampyre!", + "melee_animation": "6016", + "range_animation": "0", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "6031", + "name": "Angry vampyre", + "defence_level": "42", + "safespot": null, + "lifepoints": "60", + "strength_level": "42", + "id": "4789", + "range_level": "1", + "attack_level": "42" + }, + { + "name": "Vanstrom Klause", + "defence_level": "1", + "safespot": null, + "lifepoints": "155", + "strength_level": "1", + "id": "4793", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "examine": "Not as strong as Thok.", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "name": "Vanstrom Klause", + "defence_level": "60", + "safespot": null, + "lifepoints": "28", + "strength_level": "90", + "id": "4796", + "aggressive": "true", + "range_level": "1", + "attack_level": "90" + }, + { + "examine": "An evil", + "melee_animation": "7435", + "range_animation": "0", + "attack_speed": "6", + "magic_level": "50", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "4", + "magic_animation": "0", + "death_animation": "0", + "name": "Vyrewatch", + "defence_level": "50", + "safespot": null, + "lifepoints": "71", + "strength_level": "1", + "id": "4805", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An evil", + "melee_animation": "7435", + "range_animation": "0", + "attack_speed": "6", + "magic_level": "52", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "4", + "magic_animation": "0", + "death_animation": "0", + "name": "Vyrewatch", + "defence_level": "52", + "safespot": null, + "lifepoints": "74", + "strength_level": "1", + "id": "4806", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An evil", + "melee_animation": "7435", + "range_animation": "0", + "attack_speed": "6", + "magic_level": "54", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "4", + "magic_animation": "0", + "death_animation": "0", + "name": "Vyrewatch", + "defence_level": "54", + "safespot": null, + "lifepoints": "77", + "strength_level": "1", + "id": "4807", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An evil", + "melee_animation": "7435", + "range_animation": "0", + "attack_speed": "6", + "magic_level": "56", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "4", + "magic_animation": "0", + "death_animation": "0", + "name": "Vyrewatch", + "defence_level": "56", + "safespot": null, + "lifepoints": "80", + "strength_level": "1", + "id": "4808", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A very high-ranking vampyre.", + "melee_animation": "7435", + "range_animation": "0", + "attack_speed": "5", + "magic_level": "70", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "5", + "magic_animation": "0", + "death_animation": "7524", + "name": "Flying female vampire", + "defence_level": "70", + "safespot": null, + "lifepoints": "100", + "strength_level": "1", + "id": "4810", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A very high-ranking vampyre.", + "melee_animation": "7435", + "range_animation": "0", + "attack_speed": "5", + "magic_level": "70", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "5", + "magic_animation": "0", + "death_animation": "7524", + "name": "Flying female vampire", + "defence_level": "70", + "safespot": null, + "lifepoints": "100", + "strength_level": "1", + "id": "4811", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A very high-ranking vampyre.", + "melee_animation": "7435", + "range_animation": "0", + "attack_speed": "5", + "magic_level": "70", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "5", + "magic_animation": "0", + "death_animation": "7524", + "name": "Flying female vampire", + "defence_level": "70", + "safespot": null, + "lifepoints": "100", + "strength_level": "1", + "id": "4812", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A thirsty-looking", + "melee_animation": "6783", + "range_animation": "0", + "attack_speed": "6", + "magic_level": "50", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "4", + "magic_animation": "0", + "death_animation": "6861", + "name": "Vyrewatch", + "defence_level": "50", + "safespot": null, + "lifepoints": "71", + "strength_level": "1", + "id": "4813", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A thirsty-looking", + "melee_animation": "6783", + "range_animation": "0", + "attack_speed": "6", + "magic_level": "52", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "4", + "magic_animation": "0", + "death_animation": "6861", + "name": "Vyrewatch", + "defence_level": "52", + "safespot": null, + "lifepoints": "74", + "strength_level": "1", + "id": "4814", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A thirsty-looking", + "melee_animation": "6783", + "range_animation": "0", + "attack_speed": "6", + "magic_level": "54", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "4", + "magic_animation": "0", + "death_animation": "6861", + "name": "Vyrewatch", + "defence_level": "54", + "safespot": null, + "lifepoints": "77", + "strength_level": "1", + "id": "4815", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A thirsty-looking", + "melee_animation": "6783", + "range_animation": "0", + "attack_speed": "6", + "magic_level": "56", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "4", + "magic_animation": "0", + "death_animation": "6861", + "name": "Vyrewatch", + "defence_level": "56", + "safespot": null, + "lifepoints": "80", + "strength_level": "1", + "id": "4816", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An evil", + "melee_animation": "7435", + "range_animation": "0", + "attack_speed": "6", + "magic_level": "50", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "4", + "magic_animation": "0", + "death_animation": "0", + "name": "Vyrewatch", + "defence_level": "50", + "safespot": null, + "lifepoints": "71", + "strength_level": "1", + "id": "4817", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An evil", + "melee_animation": "7435", + "range_animation": "0", + "attack_speed": "6", + "magic_level": "52", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "4", + "magic_animation": "0", + "death_animation": "0", + "name": "Vyrewatch", + "defence_level": "52", + "safespot": null, + "lifepoints": "74", + "strength_level": "1", + "id": "4818", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An evil", + "melee_animation": "7435", + "range_animation": "0", + "attack_speed": "6", + "magic_level": "54", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "4", + "magic_animation": "0", + "death_animation": "0", + "name": "Vyrewatch", + "defence_level": "54", + "safespot": null, + "lifepoints": "77", + "strength_level": "1", + "id": "4819", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An evil", + "melee_animation": "7435", + "range_animation": "0", + "attack_speed": "6", + "magic_level": "56", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "4", + "magic_animation": "0", + "death_animation": "0", + "name": "Vyrewatch", + "defence_level": "56", + "safespot": null, + "lifepoints": "80", + "strength_level": "1", + "id": "4820", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A very high-ranking vampyre.", + "melee_animation": "7435", + "range_animation": "0", + "attack_speed": "5", + "magic_level": "70", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "5", + "magic_animation": "0", + "death_animation": "7524", + "name": "Vyrewatch", + "defence_level": "70", + "safespot": null, + "lifepoints": "100", + "strength_level": "1", + "id": "4821", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A very high-ranking vampyre.", + "melee_animation": "7435", + "range_animation": "0", + "attack_speed": "5", + "magic_level": "70", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "5", + "magic_animation": "0", + "death_animation": "7524", + "name": "Vyrewatch", + "defence_level": "70", + "safespot": null, + "lifepoints": "100", + "strength_level": "1", + "id": "4822", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A very high-ranking vampyre.", + "melee_animation": "7435", + "range_animation": "0", + "attack_speed": "5", + "magic_level": "70", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "5", + "magic_animation": "0", + "death_animation": "7524", + "name": "Vyrewatch", + "defence_level": "70", + "safespot": null, + "lifepoints": "100", + "strength_level": "1", + "id": "4823", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A very high-ranking vampyre.", + "melee_animation": "7435", + "range_animation": "0", + "attack_speed": "5", + "magic_level": "70", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "5", + "magic_animation": "0", + "death_animation": "7524", + "name": "Vyrewatch", + "defence_level": "70", + "safespot": null, + "lifepoints": "100", + "strength_level": "1", + "id": "4824", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A thirsty-looking", + "melee_animation": "6783", + "range_animation": "0", + "attack_speed": "6", + "magic_level": "50", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "4", + "magic_animation": "0", + "death_animation": "6861", + "name": "Vyrewatch", + "defence_level": "50", + "safespot": null, + "lifepoints": "71", + "strength_level": "1", + "id": "4825", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A thirsty-looking", + "melee_animation": "6783", + "range_animation": "0", + "attack_speed": "6", + "magic_level": "52", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "4", + "magic_animation": "0", + "death_animation": "6861", + "name": "Vyrewatch", + "defence_level": "52", + "safespot": null, + "lifepoints": "74", + "strength_level": "1", + "id": "4826", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A thirsty-looking", + "melee_animation": "6783", + "range_animation": "0", + "attack_speed": "6", + "magic_level": "54", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "4", + "magic_animation": "0", + "death_animation": "6861", + "name": "Vyrewatch", + "defence_level": "54", + "safespot": null, + "lifepoints": "77", + "strength_level": "1", + "id": "4827", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A thirsty-looking", + "melee_animation": "6783", + "range_animation": "0", + "attack_speed": "6", + "magic_level": "56", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "4", + "magic_animation": "0", + "death_animation": "6861", + "name": "Vyrewatch", + "defence_level": "56", + "safespot": null, + "lifepoints": "80", + "strength_level": "1", + "id": "4828", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "95", + "strength_level": "1", + "attack_speed": "6", + "id": "4829", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "105", + "strength_level": "1", + "attack_speed": "6", + "id": "4830", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "120", + "strength_level": "1", + "attack_speed": "6", + "id": "4831", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "130", + "strength_level": "1", + "attack_speed": "6", + "id": "4832", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "95", + "strength_level": "1", + "attack_speed": "6", + "id": "4833", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "105", + "strength_level": "1", + "attack_speed": "6", + "id": "4834", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "120", + "strength_level": "1", + "attack_speed": "6", + "id": "4835", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "130", + "strength_level": "1", + "attack_speed": "6", + "id": "4836", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "95", + "strength_level": "1", + "attack_speed": "6", + "id": "4837", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "105", + "strength_level": "1", + "attack_speed": "6", + "id": "4838", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "120", + "strength_level": "1", + "attack_speed": "6", + "id": "4839", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "130", + "strength_level": "1", + "attack_speed": "6", + "id": "4840", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "95", + "strength_level": "1", + "attack_speed": "6", + "id": "4841", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "105", + "strength_level": "1", + "attack_speed": "6", + "id": "4842", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "120", + "strength_level": "1", + "attack_speed": "6", + "id": "4843", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "130", + "strength_level": "1", + "attack_speed": "6", + "id": "4844", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "examine": "A very high-ranking vampyre.", + "melee_animation": "7435", + "range_animation": "0", + "attack_speed": "5", + "magic_level": "70", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "5", + "magic_animation": "0", + "death_animation": "7524", + "name": "Flying female vampire", + "defence_level": "70", + "safespot": null, + "lifepoints": "100", + "strength_level": "1", + "id": "4845", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Flying female vampire", + "defence_level": "1", + "safespot": null, + "lifepoints": "95", + "strength_level": "1", + "attack_speed": "6", + "id": "4847", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Flying female vampire", + "defence_level": "1", + "safespot": null, + "lifepoints": "95", + "strength_level": "1", + "attack_speed": "6", + "id": "4848", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "105", + "strength_level": "1", + "attack_speed": "6", + "id": "4849", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "95", + "strength_level": "1", + "attack_speed": "6", + "id": "4850", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "95", + "strength_level": "1", + "attack_speed": "6", + "id": "4851", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "105", + "strength_level": "1", + "attack_speed": "6", + "id": "4852", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "examine": "Her knives tickle Thok.", + "magic_animation": "0", + "name": "Holgart", + "defence_level": "60", + "safespot": null, + "lifepoints": "28", + "strength_level": "1", + "id": "4868", + "aggressive": "true", + "range_level": "90", + "attack_level": "1", + "defence_animation": "0" + }, + { + "examine": "Not Thok's pretty lass.", + "magic_level": "90", + "defence_animation": "0", + "magic_animation": "0", + "name": "Fisherman", + "defence_level": "60", + "safespot": null, + "lifepoints": "28", + "strength_level": "1", + "id": "4870", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A child of aquatic evil.", + "melee_animation": "4829", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "4830", + "name": "Slug Prince", + "defence_level": "37", + "safespot": null, + "lifepoints": "105", + "strength_level": "37", + "id": "4890", + "aggressive": "true", + "range_level": "1", + "attack_level": "37" + }, + { + "examine": "An extremely vicious lobster.", + "melee_animation": "6265", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "6267", + "name": "Giant Lobster", + "defence_level": "29", + "safespot": null, + "lifepoints": "82", + "strength_level": "29", + "id": "4893", + "aggressive": "true", + "range_level": "1", + "attack_level": "29" + }, + { + "examine": "A rather nasty looking crustacean.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Sea slug", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4894", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "164", + "combat_audio": "3520,472,471", + "respawn_delay": "60", + "defence_animation": "163", + "death_animation": "167", + "name": "Hobgoblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "29", + "strength_level": "1", + "id": "4898", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Cordero looks ready to teach you how to cook.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cooking Tutor", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4899", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Cadmus, looking a little bit crafty.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Crafting Tutor", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4900", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Finlay, mending a crayfish cage.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fishing Tutor", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4901", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Monlum, surveying the rocks.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Mining Tutor", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4902", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Yauchomi, follower of Saradomin.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Prayer Tutor", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4903", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Feoras looks a bit fiery.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Smelting Tutor", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4904", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Wilfred, a chip off the old block.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Woodcutting Tutor", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4906", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Barb, ready to teach you about banking.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Bank Tutor", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4907", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "His motives are see-through.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fritz the Glassblower", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4909", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An earth elemental.", + "melee_animation": "4868", + "combat_audio": "1531,1533,1532", + "attack_speed": "6", + "magic_level": "10", + "respawn_delay": "5", + "defence_animation": "4869", + "death_animation": "4870", + "name": "Earth elemental", + "defence_level": "35", + "safespot": null, + "lifepoints": "35", + "strength_level": "35", + "id": "4910", + "aggressive": "false", + "range_level": "30", + "attack_level": "20" + }, + { + "examine": "An elemental rock.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "0", + "name": "Elemental rock", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4911", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A nasty overgrown rodent.", + "melee_animation": "4933", + "range_animation": "4933", + "combat_audio": "703,705,704", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "4934", + "weakness": "9", + "magic_animation": "4933", + "death_animation": "4935", + "name": "Giant crypt rat", + "defence_level": "65", + "safespot": null, + "lifepoints": "70", + "strength_level": "50", + "id": "4920", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "80" + }, + { + "examine": "A nasty overgrown rodent.", + "melee_animation": "4933", + "range_animation": "4933", + "combat_audio": "703,705,704", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "4934", + "weakness": "9", + "magic_animation": "4933", + "death_animation": "4935", + "name": "Giant crypt rat", + "defence_level": "65", + "safespot": null, + "lifepoints": "70", + "strength_level": "50", + "id": "4921", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "80" + }, + { + "examine": "Overgrown vermin.", + "melee_animation": "4933", + "range_animation": "0", + "combat_audio": "703,705,704", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "4934", + "weakness": "8", + "magic_animation": "0", + "death_animation": "4935", + "name": "Giant rat", + "defence_level": "5", + "safespot": null, + "lifepoints": "7", + "strength_level": "5", + "id": "4922", + "aggressive": "true", + "range_level": "1", + "attack_level": "5" + }, + { + "examine": "Overgrown vermin.", + "melee_animation": "4933", + "range_animation": "0", + "combat_audio": "703,705,704", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "4934", + "weakness": "8", + "magic_animation": "0", + "death_animation": "4935", + "name": "Giant rat", + "defence_level": "5", + "safespot": null, + "lifepoints": "7", + "strength_level": "5", + "id": "4923", + "aggressive": "true", + "range_level": "1", + "attack_level": "5" + }, + { + "examine": "Overgrown vermin.", + "melee_animation": "4933", + "range_animation": "0", + "combat_audio": "703,705,704", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "4934", + "weakness": "8", + "magic_animation": "0", + "death_animation": "4935", + "name": "Giant rat", + "defence_level": "5", + "safespot": null, + "lifepoints": "7", + "strength_level": "5", + "id": "4924", + "aggressive": "true", + "range_level": "1", + "attack_level": "5" + }, + { + "melee_animation": "4933", + "combat_audio": "703,705,704", + "defence_animation": "4934", + "death_animation": "4935", + "name": "Giant rat", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4925", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Overgrown vermin.", + "melee_animation": "4933", + "range_animation": "0", + "combat_audio": "703,705,704", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "4934", + "weakness": "8", + "magic_animation": "0", + "death_animation": "4935", + "name": "Giant rat", + "defence_level": "7", + "safespot": null, + "lifepoints": "10", + "strength_level": "7", + "id": "4926", + "aggressive": "true", + "range_level": "1", + "attack_level": "7" + }, + { + "examine": "Overgrown vermin.", + "melee_animation": "4933", + "range_animation": "0", + "combat_audio": "703,705,704", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "4934", + "weakness": "8", + "magic_animation": "0", + "death_animation": "4935", + "name": "Giant rat", + "defence_level": "7", + "safespot": null, + "lifepoints": "10", + "strength_level": "7", + "id": "4927", + "aggressive": "true", + "range_level": "1", + "attack_level": "7" + }, + { + "examine": "Overgrown vermin.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "703,705,704", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "4934", + "weakness": "8", + "magic_animation": "0", + "death_animation": "4935", + "name": "Dungeon rat", + "defence_level": "13", + "safespot": null, + "lifepoints": "18", + "strength_level": "13", + "id": "4928", + "aggressive": "true", + "range_level": "1", + "attack_level": "13" + }, + { + "examine": "Overgrown vermin.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "703,705,704", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "4934", + "weakness": "8", + "magic_animation": "0", + "death_animation": "4935", + "name": "Dungeon rat", + "defence_level": "13", + "safespot": null, + "lifepoints": "18", + "strength_level": "13", + "id": "4929", + "aggressive": "true", + "range_level": "1", + "attack_level": "13" + }, + { + "examine": "They'll eat anything!", + "melee_animation": "5341", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5343", + "name": "Goat", + "defence_level": "5", + "safespot": null, + "lifepoints": "7", + "strength_level": "5", + "id": "4930", + "range_level": "1", + "attack_level": "5" + }, + { + "examine": "They'll eat anything!", + "melee_animation": "5341", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5343", + "name": "Goat", + "defence_level": "5", + "safespot": null, + "lifepoints": "7", + "strength_level": "5", + "id": "4931", + "range_level": "1", + "attack_level": "5" + }, + { + "examine": "They'll eat anything!", + "melee_animation": "5341", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5343", + "name": "Billy Goat", + "defence_level": "11", + "safespot": null, + "lifepoints": "15", + "strength_level": "11", + "id": "4932", + "range_level": "1", + "attack_level": "11" + }, + { + "death_animation": "5343", + "name": "Goat", + "defence_level": "1", + "safespot": null, + "lifepoints": "21", + "melee_animation": "5341", + "strength_level": "1", + "id": "4933", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1", + "defence_animation": "5342" + }, + { + "death_animation": "5343", + "name": "Goat", + "defence_level": "1", + "safespot": null, + "lifepoints": "21", + "melee_animation": "5341", + "strength_level": "1", + "id": "4934", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1", + "defence_animation": "5342" + }, + { + "death_animation": "5343", + "name": "Billy Goat", + "defence_level": "1", + "safespot": null, + "lifepoints": "28", + "melee_animation": "5341", + "strength_level": "1", + "id": "4935", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1", + "defence_animation": "5342" + }, + { + "examine": "A dirty rat.", + "melee_animation": "4933", + "range_animation": "0", + "combat_audio": "703,705,704", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "4935", + "name": "Dungeon rat", + "defence_level": "8", + "safespot": null, + "lifepoints": "11", + "strength_level": "8", + "id": "4936", + "aggressive": "true", + "range_level": "1", + "attack_level": "8" + }, + { + "examine": "A dirty rat.", + "melee_animation": "4933", + "range_animation": "0", + "combat_audio": "703,705,704", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "4935", + "name": "Dungeon rat", + "defence_level": "8", + "safespot": null, + "lifepoints": "11", + "strength_level": "8", + "id": "4937", + "aggressive": "true", + "range_level": "1", + "attack_level": "8" + }, + { + "name": "Angry giant rat", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "703,705,704", + "strength_level": "1", + "id": "4938", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Angry giant rat", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "703,705,704", + "strength_level": "1", + "id": "4939", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He looks a little on the cross side!", + "melee_animation": "4933", + "range_animation": "0", + "combat_audio": "703,705,704", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "4935", + "name": "Angry giant rat", + "defence_level": "25", + "safespot": null, + "lifepoints": "35", + "strength_level": "25", + "id": "4940", + "range_level": "1", + "attack_level": "25" + }, + { + "examine": "It's one of Iban's pet vermin.", + "range_animation": "0", + "combat_audio": "703,705,704", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "name": "Blessed giant rat", + "defence_level": "12", + "safespot": null, + "lifepoints": "17", + "strength_level": "12", + "id": "4941", + "range_level": "1", + "attack_level": "12" + }, + { + "melee_animation": "4933", + "combat_audio": "703,705,704", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "4934", + "death_animation": "4935", + "name": "Giant rat", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "1", + "id": "4942", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "4933", + "combat_audio": "703,705,704", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "4934", + "death_animation": "4935", + "name": "Giant rat", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "1", + "id": "4943", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Overgrown vermin.", + "combat_audio": "703,705,704", + "melee_animation": "4933", + "attack_speed": "5", + "defence_animation": "4934", + "death_animation": "4935", + "name": "Giant rat", + "defence_level": "23", + "safespot": null, + "lifepoints": "26", + "strength_level": "20", + "id": "4944", + "aggressive": "true", + "bonuses": "19,15,15,34,36,38,33,31,30,14,0,0,0,0,0", + "range_level": "1", + "attack_level": "21" + }, + { + "examine": "Overgrown vermin.", + "combat_audio": "703,705,704", + "melee_animation": "4933", + "attack_speed": "5", + "defence_animation": "4934", + "weakness": "9", + "death_animation": "4935", + "name": "Giant rat", + "defence_level": "23", + "safespot": null, + "lifepoints": "26", + "strength_level": "20", + "id": "4945", + "aggressive": "true", + "bonuses": "19,15,15,34,36,38,33,31,30,14,0,0,0,0,0", + "range_level": "1", + "attack_level": "21" + }, + { + "examine": "Trollish.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "My Arm", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4947", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An old sailor.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Captain Barnaby", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4962", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It's a leprechaun sunbathing on a mountain.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Tool Leprechaun", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4965", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A mountain-dwelling bird. Cute", + "melee_animation": "5031", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "5033", + "name": "Baby Roc", + "defence_level": "40", + "safespot": null, + "lifepoints": "100", + "strength_level": "40", + "id": "4971", + "aggressive": "true", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "A very", + "melee_animation": "5024", + "range_animation": "5025", + "magic_level": "55", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "5027", + "name": "Giant Roc", + "defence_level": "55", + "safespot": null, + "lifepoints": "285", + "strength_level": "55", + "id": "4972", + "aggressive": "true", + "range_level": "55", + "attack_level": "55" + }, + { + "examine": "It looks like he's been here a long time.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Male slave", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4975", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "She looks like she's been down here a long time.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Female slave", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4977", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He looks a bit aggressive.", + "melee_animation": "390", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Mercenary", + "defence_level": "25", + "safespot": null, + "lifepoints": "35", + "strength_level": "25", + "id": "4989", + "range_level": "1", + "attack_level": "25" + }, + { + "examine": "He looks a bit aggressive.", + "melee_animation": "390", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Mercenary", + "defence_level": "25", + "safespot": null, + "lifepoints": "35", + "strength_level": "25", + "id": "4990", + "range_level": "1", + "attack_level": "25" + }, + { + "examine": "He looks a bit aggressive.", + "melee_animation": "390", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Mercenary", + "defence_level": "25", + "safespot": null, + "lifepoints": "35", + "strength_level": "25", + "id": "4991", + "range_level": "1", + "attack_level": "25" + }, + { + "examine": "He looks a bit aggressive.", + "melee_animation": "390", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Mercenary", + "defence_level": "25", + "safespot": null, + "lifepoints": "35", + "strength_level": "25", + "id": "4992", + "range_level": "1", + "attack_level": "25" + }, + { + "examine": "He looks a bit aggressive.", + "melee_animation": "390", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Guard", + "defence_level": "25", + "safespot": null, + "lifepoints": "35", + "strength_level": "25", + "id": "4993", + "clue_level": "1", + "range_level": "1", + "attack_level": "25" + }, + { + "examine": "He looks a bit aggressive.", + "melee_animation": "390", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Guard", + "defence_level": "25", + "safespot": null, + "lifepoints": "35", + "strength_level": "25", + "id": "4994", + "clue_level": "1", + "range_level": "1", + "attack_level": "25" + }, + { + "examine": "He looks a bit aggressive.", + "melee_animation": "390", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Guard", + "defence_level": "25", + "safespot": null, + "lifepoints": "35", + "strength_level": "25", + "id": "4995", + "clue_level": "1", + "range_level": "1", + "attack_level": "25" + }, + { + "examine": "He looks a bit aggressive.", + "melee_animation": "390", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Guard", + "defence_level": "25", + "safespot": null, + "lifepoints": "35", + "strength_level": "25", + "id": "4996", + "clue_level": "1", + "range_level": "1", + "attack_level": "25" + }, + { + "examine": "He looks a bit aggressive.", + "melee_animation": "390", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Guard", + "defence_level": "25", + "safespot": null, + "lifepoints": "35", + "strength_level": "25", + "id": "4997", + "clue_level": "1", + "range_level": "1", + "attack_level": "25" + }, + { + "examine": "He looks a bit aggressive.", + "melee_animation": "390", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Guard", + "defence_level": "25", + "safespot": null, + "lifepoints": "35", + "strength_level": "25", + "id": "4998", + "clue_level": "1", + "range_level": "1", + "attack_level": "25" + }, + { + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "4999", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "5000", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "5001", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "5002", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An apprentice.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Egg launcher", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5026", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A tired old wizard.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Egg launcher", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5027", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An egg launcher.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Egg launcher", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5028", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A slightly more approachable barbarian.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Commander Connad", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5029", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He looks pretty mean.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Captain Cain", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5030", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A stressed out barbarian private.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Private Paldo", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5031", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A barbarian private.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Private Pendron", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5032", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A barbarian private.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Private Pierreb", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5033", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A barbarian private.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Private Paldon", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5034", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A barbarian army teacher.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Major Attack", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5035", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A barbarian army teacher.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Major Collect", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5036", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A barbarian army teacher.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Major Defend", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5037", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A barbarian army teacher.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Major Heal", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5038", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He's keeping a close eye on that nearby door.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Sergeant Sambur", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5039", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "What on Gielinor is that?", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "670,672,671", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Penance Fighter", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5040", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Shooty-shooty.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Penance Ranger", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5041", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He's making a run for it!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Penance Runner", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5042", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A nasty piece of work.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Penance Healer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5043", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Not as strong as Thok.", + "melee_animation": "401", + "range_animation": "0", + "magic_level": "80", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "836", + "name": "Jeff", + "defence_level": "40", + "safespot": null, + "lifepoints": "22", + "strength_level": "80", + "id": "5048", + "aggressive": "true", + "range_level": "80", + "attack_level": "80" + }, + { + "examine": "Time to run away...", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Shark", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5067", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It blends in very well with its surroundings.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Tropical wagtail", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5072", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "This bird obviously doesn't believe in subtlety.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Crimson swift", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5073", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Best served ice cold.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cerulean twitch", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5074", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Actually", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Golden warbler", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5075", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Nothing much to get in a flap about.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Copper longtail", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5076", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Chinchompa", + "defence_level": "1", + "safespot": null, + "lifepoints": "1", + "strength_level": "1", + "id": "5079", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It looks fluffy and cute; it's probably deadly.", + "melee_animation": "0", + "range_animation": "0", + "magic_level": "2", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "5183", + "name": "Carnivorous chinchompa", + "defence_level": "2", + "safespot": null, + "lifepoints": "10", + "strength_level": "2", + "id": "5080", + "range_level": "2", + "attack_level": "2" + }, + { + "examine": "Wild.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ferret", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5081", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A black warlock. The air seems to distort wherever it passes.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Black warlock", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5082", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It's a snowy knight butterfly.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Snowy knight", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5083", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A sapphire glacialis. It doesn't look as pretentious as its name sounds.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Sapphire glacialis", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5084", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It's a ruby harvest butterfly.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ruby harvest", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5085", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Curls up into a ball to protect itself from attack.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Prickly kebbit", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5086", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Now that's a big overbite.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Sabre-toothed kebbit", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5087", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It uses its tail to hunt and skewer fish.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Barb-tailed kebbit", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5088", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "That's a mean looking set of claws.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Wild kebbit", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5089", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Ha! Thok much stronger.", + "melee_animation": "395", + "range_animation": "0", + "magic_level": "80", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "836", + "name": "Gyr Falcon", + "defence_level": "40", + "safespot": null, + "lifepoints": "22", + "strength_level": "80", + "id": "5097", + "aggressive": "true", + "range_level": "80", + "attack_level": "80" + }, + { + "examine": "It seems to be on a permanent sugar rush.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Spotted kebbit", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5098", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Quieter than a ninja mouse with slippers on.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Dark kebbit", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5099", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Now you see it; now you don't.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Dashing kebbit", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5100", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It's just like a big, white, furry, deadly can opener.", + "melee_animation": "5228", + "range_animation": "5228", + "attack_speed": "5", + "respawn_delay": "10", + "defence_animation": "404", + "magic_animation": "5228", + "death_animation": "5234", + "name": "Sabre-toothed kyatt", + "defence_level": "99", + "safespot": null, + "lifepoints": "10", + "strength_level": "25", + "id": "5103", + "range_level": "1", + "attack_level": "25" + }, + { + "examine": "If you tried to ride that, you'd just impale yourself!", + "melee_animation": "5228", + "range_animation": "5228", + "attack_speed": "5", + "defence_animation": "404", + "magic_animation": "5228", + "death_animation": "5234", + "name": "Spined larupia", + "defence_level": "99", + "safespot": null, + "lifepoints": "10", + "strength_level": "15", + "id": "5104", + "range_level": "1", + "attack_level": "15" + }, + { + "examine": "Get in a graahk's way and you're going to know about it... however briefly.", + "melee_animation": "5228", + "range_animation": "5228", + "attack_speed": "5", + "defence_animation": "404", + "magic_animation": "5228", + "death_animation": "5234", + "name": "Horned graahk", + "defence_level": "99", + "safespot": null, + "lifepoints": "10", + "strength_level": "25", + "id": "5105", + "range_level": "1", + "attack_level": "25" + }, + { + "examine": "It's just like a big, white, furry, deadly can opener.", + "melee_animation": "5228", + "range_animation": "5228", + "attack_speed": "5", + "defence_animation": "404", + "magic_animation": "5228", + "death_animation": "9055", + "name": "null", + "defence_level": "40", + "safespot": null, + "lifepoints": "10", + "strength_level": "20", + "id": "5106", + "range_level": "1", + "attack_level": "20" + }, + { + "examine": "He must be good at hunting; even his hair blends in with the surroundings.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Hunting expert", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5112", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "With all the furs", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Hunting expert", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5113", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Slightly slimy but kind of cute.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Orange salamander", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5114", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Slightly slimy but certainly striking.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Red salamander", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5115", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Slightly slimy and somewhat menacing.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Black salamander", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5116", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Very slimy and generally disgusting.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Swamp lizard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5117", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A very large", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Eagle", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5120", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A very large", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Desert eagle", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5130", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A very large", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Jungle eagle", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5131", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A very large", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Polar eagle", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5132", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It seems to be protecting the nest.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Eagle", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5133", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Kebbit", + "defence_level": "1", + "safespot": null, + "lifepoints": "40", + "melee_animation": "5304", + "strength_level": "1", + "id": "5137", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1", + "defence_animation": "5305" + }, + { + "examine": "Now", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Boulder", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5140", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He's playing both sides!", + "melee_animation": "422", + "range_animation": "0", + "attack_speed": "5", + "magic_level": "75", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "836", + "name": "Double agent", + "defence_level": "75", + "safespot": null, + "lifepoints": "85", + "strength_level": "75", + "id": "5144", + "aggressive": "true", + "range_level": "1", + "attack_level": "75" + }, + { + "melee_animation": "422", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Double agent", + "defence_level": "1", + "safespot": null, + "lifepoints": "120", + "strength_level": "1", + "id": "5145", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "How cute!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Li'l lamb", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5146", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The black sheep of the family.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Lamb", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5147", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "White and fluffy.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Sheep", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5162", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "White and fluffy.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Sheep", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5163", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "White and fluffy", + "name": "Sheep", + "id": "5164" + }, + { + "examine": "This goat belongs to the mountain camp people.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Mountain Goat", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5166", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "This goat belongs to the mountain camp people.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Mountain Goat", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5167", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "White and fluffy.", + "melee_animation": "5338", + "combat_audio": "757,759,758", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "5337", + "weakness": "9", + "death_animation": "5336", + "name": "Ram", + "defence_level": "1", + "safespot": null, + "lifepoints": "8", + "strength_level": "1", + "id": "5168", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "White and fluffy.", + "melee_animation": "5338", + "combat_audio": "757,759,758", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "5337", + "weakness": "9", + "death_animation": "5336", + "name": "Ram", + "defence_level": "1", + "safespot": null, + "lifepoints": "8", + "strength_level": "1", + "id": "5169", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "White and fluffy.", + "melee_animation": "5338", + "range_animation": "0", + "combat_audio": "757,759,758", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "5337", + "weakness": "9", + "magic_animation": "0", + "death_animation": "5336", + "name": "Ram", + "defence_level": "1", + "safespot": null, + "lifepoints": "8", + "strength_level": "1", + "id": "5170", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "This beast doesn't need climbing boots.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Mountain goat", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5171", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Freshly shorn.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Golden sheep", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5172", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Lovely thick wool.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Golden sheep", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5173", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Seems intelligent... for an ogre.", + "combat_style": "2", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "name": "Ogre shaman", + "defence_level": "65", + "safespot": null, + "lifepoints": "371", + "strength_level": "65", + "id": "5176", + "aggressive": "true", + "range_level": "1", + "attack_level": "65" + }, + { + "examine": "A mother dragon.", + "melee_animation": "80", + "range_animation": "80", + "combat_audio": "408,410,409", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "35", + "defence_animation": "89", + "weakness": "3", + "slayer_exp": "108", + "magic_animation": "80", + "death_animation": "92", + "name": "Blue dragon", + "defence_level": "95", + "safespot": null, + "lifepoints": "105", + "strength_level": "95", + "id": "5178", + "aggressive": "true", + "bonuses": "0,0,0,0,0,50,70,70,60,50,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "95" + }, + { + "examine": "Seems intelligent... for an ogre.", + "range_animation": "0", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "name": "Ogre shaman", + "defence_level": "65", + "safespot": null, + "lifepoints": "371", + "strength_level": "65", + "id": "5181", + "range_level": "1", + "attack_level": "65" + }, + { + "examine": "Seems intelligent... for an ogre.", + "combat_style": "2", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "name": "Ogre shaman", + "defence_level": "65", + "safespot": null, + "lifepoints": "371", + "strength_level": "65", + "id": "5184", + "aggressive": "true", + "range_level": "1", + "attack_level": "65" + }, + { + "examine": "Seems intelligent... for an ogre.", + "combat_style": "2", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "name": "Ogre shaman", + "defence_level": "65", + "safespot": null, + "lifepoints": "371", + "strength_level": "65", + "id": "5187", + "aggressive": "true", + "range_level": "1", + "attack_level": "65" + }, + { + "examine": "It's Nial", + "melee_animation": "8946", + "range_animation": "0", + "magic_level": "58", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "8948", + "name": "Saff Waldon", + "defence_level": "58", + "safespot": null, + "lifepoints": "165", + "strength_level": "58", + "id": "5188", + "aggressive": "true", + "range_level": "58", + "attack_level": "58" + }, + { + "examine": "Seems intelligent. For an ogre.", + "combat_style": "2", + "name": "Ogre shaman", + "defence_level": "1", + "safespot": null, + "lifepoints": "1", + "strength_level": "1", + "id": "5190", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "examine": "Seems intelligent. For an ogre.", + "combat_style": "2", + "name": "Ogre shaman", + "defence_level": "1", + "safespot": null, + "lifepoints": "1", + "strength_level": "1", + "id": "5193", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "examine": "A wizard.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Wizard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5195", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A wizard.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Wizard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5196", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A wizard.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Wizard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5197", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "She needs to work out before facing Thok.", + "melee_animation": "7041", + "range_animation": "0", + "magic_level": "80", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "836", + "name": "Alice's husband", + "defence_level": "40", + "safespot": null, + "lifepoints": "22", + "strength_level": "80", + "id": "5204", + "aggressive": "true", + "range_level": "80", + "attack_level": "80" + }, + { + "examine": "It's an undead cow.", + "melee_animation": "5849", + "range_animation": "5849", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "5", + "defence_animation": "5850", + "magic_animation": "5849", + "death_animation": "5851", + "name": "Undead cow", + "defence_level": "1", + "safespot": null, + "lifepoints": "8", + "strength_level": "1", + "id": "5211", + "aggressive": "false", + "bonuses": "-15,-15,-15,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Shooty-shooty.", + "combat_style": "1", + "melee_animation": "5395", + "respawn_delay": "60", + "defence_animation": "5396", + "death_animation": "5937", + "name": "Penance Ranger", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5229", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Shooty-shooty.", + "combat_style": "1", + "melee_animation": "5395", + "respawn_delay": "60", + "defence_animation": "5396", + "death_animation": "5937", + "name": "Penance Ranger", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5237", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Run away! Run away!", + "melee_animation": "5411", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "5412", + "name": "Penance Queen", + "defence_level": "132", + "safespot": null, + "lifepoints": "71", + "strength_level": "260", + "id": "5247", + "aggressive": "true", + "range_level": "116", + "attack_level": "260" + }, + { + "examine": "What's it looking at?", + "melee_animation": "5092", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "5093", + "name": "Queen spawn", + "defence_level": "50", + "safespot": null, + "lifepoints": "450", + "strength_level": "60", + "id": "5248", + "aggressive": "true", + "range_level": "1", + "attack_level": "60" + }, + { + "examine": "He looks embarrassed", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Captain Errdo", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5249", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Part scarab, part man.", + "combat_style": "2", + "melee_animation": "7615", + "range_animation": "0", + "magic_level": "54", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "3", + "magic_animation": "0", + "death_animation": "7616", + "name": "Scarab mage", + "defence_level": "54", + "safespot": null, + "lifepoints": "77", + "strength_level": "40", + "id": "5250", + "aggressive": "true", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "A mounted lancer.", + "melee_animation": "7584", + "range_animation": "0", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "7581", + "name": "Locust rider", + "defence_level": "54", + "safespot": null, + "lifepoints": "77", + "strength_level": "54", + "id": "5251", + "aggressive": "true", + "range_level": "1", + "attack_level": "54" + }, + { + "examine": "A mounted archer.", + "melee_animation": "5451", + "range_animation": "5451", + "defence_animation": "0", + "weakness": "2", + "magic_animation": "0", + "death_animation": "7581", + "name": "Locust rider", + "defence_level": "54", + "safespot": null, + "lifepoints": "77", + "strength_level": "40", + "id": "5252", + "aggressive": "true", + "range_level": "54", + "attack_level": "40" + }, + { + "examine": "A huge scarab beast.", + "melee_animation": "5457", + "range_animation": "0", + "magic_level": "62", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "5456", + "name": "Giant scarab", + "defence_level": "62", + "safespot": null, + "lifepoints": "571", + "strength_level": "62", + "id": "5253", + "aggressive": "true", + "range_level": "62", + "attack_level": "62" + }, + { + "examine": "Part scarab, part man.", + "combat_style": "2", + "melee_animation": "7615", + "respawn_delay": "60", + "defence_animation": "7617", + "death_animation": "7616", + "name": "Scarab mage", + "defence_level": "1", + "safespot": null, + "lifepoints": "50", + "strength_level": "1", + "id": "5254", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He can look after my money.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Banker", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5258", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "She can look after my money.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Banker", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5260", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A guard of Sophanem.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Sophanem guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5270", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A guard of Sophanem.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Sophanem guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5274", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A guard of Menaphos.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Menaphite guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5277", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Flings annoying splinters at Thok.", + "melee_animation": "426", + "range_animation": "426", + "magic_level": "80", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "836", + "name": "Osman", + "defence_level": "40", + "safespot": null, + "lifepoints": "22", + "strength_level": "80", + "id": "5285", + "aggressive": "true", + "range_level": "80", + "attack_level": "80" + }, + { + "examine": "Brains!", + "melee_animation": "5568", + "combat_audio": "931,923,922", + "respawn_delay": "60", + "defence_animation": "5567", + "slayer_exp": "30", + "death_animation": "5569", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "22", + "strength_level": "1", + "id": "5293", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Brains!", + "melee_animation": "5568", + "combat_audio": "931,923,922", + "respawn_delay": "60", + "defence_animation": "5567", + "slayer_exp": "30", + "death_animation": "5569", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "22", + "strength_level": "1", + "id": "5294", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Brains!", + "melee_animation": "5568", + "combat_audio": "931,923,922", + "respawn_delay": "60", + "defence_animation": "5567", + "slayer_exp": "30", + "death_animation": "5569", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "22", + "strength_level": "1", + "id": "5295", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Brains!", + "melee_animation": "5568", + "combat_audio": "931,923,922", + "respawn_delay": "60", + "defence_animation": "5567", + "slayer_exp": "30", + "death_animation": "5569", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "22", + "strength_level": "1", + "id": "5296", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Brains!", + "melee_animation": "5568", + "combat_audio": "931,923,922", + "respawn_delay": "60", + "defence_animation": "5567", + "slayer_exp": "30", + "death_animation": "5569", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "22", + "strength_level": "1", + "id": "5297", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Brains!", + "melee_animation": "5568", + "combat_audio": "931,923,922", + "respawn_delay": "60", + "defence_animation": "5567", + "slayer_exp": "30", + "death_animation": "5569", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "22", + "strength_level": "1", + "id": "5298", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Brains!", + "melee_animation": "5568", + "combat_audio": "931,923,922", + "respawn_delay": "60", + "defence_animation": "5567", + "slayer_exp": "30", + "death_animation": "5569", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "22", + "strength_level": "1", + "id": "5299", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Brains!", + "melee_animation": "5568", + "combat_audio": "931,923,922", + "respawn_delay": "60", + "defence_animation": "5567", + "slayer_exp": "30", + "death_animation": "5569", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "22", + "strength_level": "1", + "id": "5300", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Brains!", + "melee_animation": "5568", + "combat_audio": "931,923,922", + "respawn_delay": "60", + "defence_animation": "5567", + "slayer_exp": "30", + "death_animation": "5569", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "22", + "strength_level": "1", + "id": "5301", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Brains!", + "melee_animation": "5568", + "combat_audio": "931,923,922", + "respawn_delay": "60", + "defence_animation": "5567", + "slayer_exp": "30", + "death_animation": "5569", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "22", + "strength_level": "1", + "id": "5302", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Brains!", + "melee_animation": "5568", + "combat_audio": "931,923,922", + "respawn_delay": "60", + "defence_animation": "5567", + "slayer_exp": "30", + "death_animation": "5569", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "22", + "strength_level": "1", + "id": "5303", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Brains!", + "melee_animation": "5568", + "combat_audio": "931,923,922", + "respawn_delay": "60", + "defence_animation": "5567", + "slayer_exp": "30", + "death_animation": "5569", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "22", + "strength_level": "1", + "id": "5304", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Brains!", + "melee_animation": "5568", + "range_animation": "5568", + "combat_audio": "931,923,922", + "attack_speed": "5", + "respawn_delay": "30", + "defence_animation": "5567", + "slayer_exp": "30", + "magic_animation": "5568", + "death_animation": "5569", + "name": "Zombie", + "defence_level": "10", + "safespot": null, + "lifepoints": "18", + "strength_level": "1", + "id": "5305", + "bonuses": "6,15,15,15,15,15,15,6,6,15,15,15,15,15,15", + "range_level": "1", + "attack_level": "11" + }, + { + "examine": "Brains!", + "melee_animation": "5568", + "combat_audio": "931,923,922", + "respawn_delay": "60", + "defence_animation": "5567", + "slayer_exp": "30", + "death_animation": "5569", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "22", + "strength_level": "1", + "id": "5306", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Brains!", + "melee_animation": "5568", + "range_animation": "5568", + "combat_audio": "931,923,922", + "attack_speed": "5", + "respawn_delay": "30", + "defence_animation": "5567", + "slayer_exp": "30", + "magic_animation": "5568", + "death_animation": "5569", + "name": "Zombie", + "defence_level": "10", + "safespot": null, + "lifepoints": "18", + "strength_level": "1", + "id": "5307", + "bonuses": "6,15,15,15,15,15,15,6,6,15,15,15,15,15,15", + "range_level": "1", + "attack_level": "11" + }, + { + "examine": "Brains!", + "melee_animation": "5568", + "combat_audio": "931,923,922", + "respawn_delay": "60", + "defence_animation": "5567", + "slayer_exp": "30", + "death_animation": "5569", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "24", + "strength_level": "1", + "id": "5308", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Brains!", + "melee_animation": "5571", + "range_animation": "5571", + "combat_audio": "931,923,922", + "attack_speed": "5", + "respawn_delay": "30", + "defence_animation": "5574", + "slayer_exp": "30", + "magic_animation": "5571", + "death_animation": "5575", + "name": "Zombie", + "defence_level": "16", + "safespot": null, + "lifepoints": "40", + "strength_level": "1", + "id": "5309", + "bonuses": "10,15,16,16,15,16,16,10,10,16,15,15,15,15,15", + "range_level": "1", + "attack_level": "15" + }, + { + "melee_animation": "5568", + "combat_audio": "931,923,922", + "respawn_delay": "60", + "defence_animation": "5567", + "slayer_exp": "30", + "death_animation": "5569", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "24", + "strength_level": "1", + "id": "5310", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "5568", + "combat_audio": "931,923,922", + "respawn_delay": "60", + "defence_animation": "5567", + "slayer_exp": "30", + "death_animation": "5569", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "24", + "strength_level": "1", + "id": "5311", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "5568", + "combat_audio": "931,923,922", + "respawn_delay": "60", + "defence_animation": "5567", + "slayer_exp": "30", + "death_animation": "5569", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "24", + "strength_level": "1", + "id": "5312", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "5568", + "combat_audio": "931,923,922", + "respawn_delay": "60", + "defence_animation": "5567", + "slayer_exp": "30", + "death_animation": "5569", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "24", + "strength_level": "1", + "id": "5313", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "5568", + "combat_audio": "931,923,922", + "respawn_delay": "60", + "defence_animation": "5567", + "slayer_exp": "30", + "death_animation": "5569", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "30", + "strength_level": "1", + "id": "5314", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "5568", + "combat_audio": "931,923,922", + "respawn_delay": "60", + "defence_animation": "5567", + "slayer_exp": "30", + "death_animation": "5569", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "30", + "strength_level": "1", + "id": "5315", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "5568", + "combat_audio": "931,923,922", + "respawn_delay": "60", + "defence_animation": "5567", + "slayer_exp": "30", + "death_animation": "5569", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "30", + "strength_level": "1", + "id": "5316", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "5568", + "combat_audio": "931,923,922", + "respawn_delay": "60", + "defence_animation": "5567", + "slayer_exp": "30", + "death_animation": "5569", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "30", + "strength_level": "1", + "id": "5317", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "5568", + "combat_audio": "931,923,922", + "respawn_delay": "60", + "defence_animation": "5567", + "slayer_exp": "30", + "death_animation": "5569", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "30", + "strength_level": "1", + "id": "5318", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Examine not added", + "melee_animation": "5571", + "range_animation": "5571", + "combat_audio": "931,923,922", + "attack_speed": "5", + "respawn_delay": "30", + "defence_animation": "5574", + "slayer_exp": "30", + "magic_animation": "5571", + "death_animation": "5575", + "name": "Zombie", + "defence_level": "20", + "safespot": null, + "lifepoints": "40", + "strength_level": "1", + "id": "5319", + "bonuses": "12,20,20,20,20,20,20,12,12,20,20,20,20,20,20", + "range_level": "1", + "attack_level": "15" + }, + { + "examine": "Examine not added", + "melee_animation": "5571", + "range_animation": "5571", + "combat_audio": "931,923,922", + "attack_speed": "5", + "respawn_delay": "30", + "defence_animation": "5574", + "slayer_exp": "30", + "magic_animation": "5571", + "death_animation": "5575", + "name": "Zombie", + "defence_level": "20", + "safespot": null, + "lifepoints": "40", + "strength_level": "1", + "id": "5320", + "bonuses": "12,20,20,20,20,20,20,12,12,20,20,20,20,20,20", + "range_level": "1", + "attack_level": "18" + }, + { + "examine": "Examine not added", + "melee_animation": "5571", + "range_animation": "5571", + "combat_audio": "931,923,922", + "attack_speed": "5", + "respawn_delay": "30", + "defence_animation": "5574", + "slayer_exp": "30", + "magic_animation": "5571", + "death_animation": "5575", + "name": "Zombie", + "defence_level": "20", + "safespot": null, + "lifepoints": "40", + "strength_level": "1", + "id": "5321", + "bonuses": "12,20,20,20,20,20,20,12,12,20,20,20,20,20,20", + "range_level": "1", + "attack_level": "18" + }, + { + "examine": "Dead man walking.", + "melee_animation": "5571", + "range_animation": "5571", + "combat_audio": "931,923,922", + "attack_speed": "5", + "defence_animation": "5574", + "slayer_exp": "30", + "magic_animation": "5571", + "death_animation": "5575", + "name": "Zombie", + "defence_level": "23", + "safespot": null, + "lifepoints": "30", + "strength_level": "19", + "id": "5322", + "aggressive": "true", + "bonuses": "21,19,20,42,44,34,41,38,40,21,0,0,0,0,0", + "range_level": "1", + "attack_level": "20" + }, + { + "melee_animation": "5568", + "combat_audio": "931,923,922", + "respawn_delay": "60", + "defence_animation": "5567", + "slayer_exp": "30", + "death_animation": "5569", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "30", + "strength_level": "1", + "id": "5323", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "5568", + "combat_audio": "931,923,922", + "respawn_delay": "60", + "defence_animation": "5567", + "slayer_exp": "30", + "death_animation": "5569", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "30", + "strength_level": "1", + "id": "5324", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "5568", + "combat_audio": "931,923,922", + "respawn_delay": "60", + "defence_animation": "5567", + "slayer_exp": "30", + "death_animation": "5569", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "30", + "strength_level": "1", + "id": "5325", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "5568", + "combat_audio": "931,923,922", + "respawn_delay": "60", + "defence_animation": "5567", + "slayer_exp": "30", + "death_animation": "5569", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "30", + "strength_level": "1", + "id": "5326", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "5568", + "combat_audio": "931,923,922", + "respawn_delay": "60", + "defence_animation": "5567", + "slayer_exp": "30", + "death_animation": "5569", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "30", + "strength_level": "1", + "id": "5327", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "5568", + "combat_audio": "931,923,922", + "respawn_delay": "60", + "defence_animation": "5567", + "slayer_exp": "30", + "death_animation": "5569", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "30", + "strength_level": "1", + "id": "5328", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "5568", + "combat_audio": "931,923,922", + "respawn_delay": "60", + "defence_animation": "5567", + "slayer_exp": "30", + "death_animation": "5569", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "30", + "strength_level": "1", + "id": "5329", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "", + "melee_animation": "5568", + "combat_audio": "931,923,922", + "respawn_delay": "60", + "defence_animation": "5567", + "slayer_exp": "30", + "death_animation": "5569", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "30", + "strength_level": "1", + "id": "5330", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "5568", + "combat_audio": "931,923,922", + "respawn_delay": "60", + "defence_animation": "5567", + "slayer_exp": "30", + "death_animation": "5569", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "30", + "strength_level": "1", + "id": "5331", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Eeek! A ghost!", + "melee_animation": "5532", + "range_animation": "0", + "combat_audio": "436,439,438", + "attack_speed": "5", + "magic_level": "18", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "5", + "slayer_exp": "25", + "magic_animation": "0", + "death_animation": "5534", + "name": "Ghost", + "defence_level": "18", + "safespot": null, + "lifepoints": "25", + "strength_level": "1", + "id": "5342", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Eeek! A ghost!", + "melee_animation": "5532", + "combat_audio": "436,439,438", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "5533", + "slayer_exp": "25", + "death_animation": "5534", + "name": "Ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "25", + "strength_level": "1", + "id": "5343", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Eeek! A ghost!", + "melee_animation": "5532", + "range_animation": "0", + "combat_audio": "436,439,438", + "attack_speed": "5", + "magic_level": "18", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "5", + "slayer_exp": "25", + "magic_animation": "0", + "death_animation": "5534", + "name": "Ghost", + "defence_level": "18", + "safespot": null, + "lifepoints": "25", + "strength_level": "1", + "id": "5344", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Eeek! A ghost!", + "melee_animation": "5532", + "range_animation": "0", + "combat_audio": "436,439,438", + "attack_speed": "5", + "magic_level": "18", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "5", + "slayer_exp": "25", + "magic_animation": "0", + "death_animation": "5534", + "name": "Ghost", + "defence_level": "18", + "safespot": null, + "lifepoints": "25", + "strength_level": "1", + "id": "5345", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Eeek! A ghost!", + "melee_animation": "5532", + "combat_audio": "436,439,438", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "5533", + "slayer_exp": "25", + "death_animation": "5534", + "name": "Ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "25", + "strength_level": "1", + "id": "5346", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Eeek! A ghost!", + "melee_animation": "5532", + "range_animation": "0", + "combat_audio": "436,439,438", + "attack_speed": "5", + "magic_level": "18", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "5", + "slayer_exp": "25", + "magic_animation": "0", + "death_animation": "5534", + "name": "Ghost", + "defence_level": "18", + "safespot": null, + "lifepoints": "25", + "strength_level": "1", + "id": "5347", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Eeek! A ghost!", + "melee_animation": "5532", + "range_animation": "0", + "combat_audio": "436,439,438", + "attack_speed": "5", + "magic_level": "18", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "5", + "slayer_exp": "25", + "magic_animation": "0", + "death_animation": "5534", + "name": "Ghost", + "defence_level": "18", + "safespot": null, + "lifepoints": "25", + "strength_level": "1", + "id": "5348", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Eeek! A ghost!", + "melee_animation": "5532", + "combat_audio": "436,439,438", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "5533", + "slayer_exp": "25", + "death_animation": "5534", + "name": "Ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "25", + "strength_level": "1", + "id": "5349", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Eeek! A ghost!", + "melee_animation": "5532", + "combat_audio": "436,439,438", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "5533", + "slayer_exp": "25", + "death_animation": "5534", + "name": "Ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "25", + "strength_level": "1", + "id": "5350", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Eeek! A ghost!", + "melee_animation": "5532", + "combat_audio": "436,439,438", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "5533", + "slayer_exp": "25", + "death_animation": "5534", + "name": "Ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "25", + "strength_level": "1", + "id": "5351", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Eeek! A ghost!", + "melee_animation": "5532", + "combat_audio": "436,439,438", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "5533", + "slayer_exp": "25", + "death_animation": "5534", + "name": "Ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "25", + "strength_level": "1", + "id": "5352", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A minion of Rashiliyia.", + "melee_animation": "5485", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "5491", + "name": "Undead one", + "defence_level": "32", + "safespot": null, + "lifepoints": "45", + "strength_level": "32", + "id": "5353", + "aggressive": "true", + "range_level": "1", + "attack_level": "32" + }, + { + "examine": "A minion of Rashiliyia.", + "melee_animation": "5487", + "range_animation": "0", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "5491", + "name": "Undead one", + "defence_level": "33", + "safespot": null, + "lifepoints": "47", + "strength_level": "33", + "id": "5354", + "range_level": "1", + "attack_level": "33" + }, + { + "examine": "The animated dead; one of Rashiliyia's minions.", + "melee_animation": "5568", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "5569", + "name": "Undead one", + "defence_level": "32", + "safespot": null, + "lifepoints": "45", + "strength_level": "32", + "id": "5355", + "aggressive": "true", + "range_level": "1", + "attack_level": "32" + }, + { + "examine": "The animated dead; one of Rashiliyia's minions.", + "melee_animation": "5568", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "5569", + "name": "Undead one", + "defence_level": "32", + "safespot": null, + "lifepoints": "45", + "strength_level": "32", + "id": "5356", + "aggressive": "true", + "range_level": "1", + "attack_level": "32" + }, + { + "examine": "The animated dead; one of Rashiliyia's minions.", + "melee_animation": "5571", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "5575", + "name": "Undead one", + "defence_level": "33", + "safespot": null, + "lifepoints": "47", + "strength_level": "33", + "id": "5357", + "aggressive": "true", + "range_level": "1", + "attack_level": "33" + }, + { + "examine": "The animated dead; one of Rashiliyia's minions.", + "melee_animation": "5571", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "5575", + "name": "Undead one", + "defence_level": "33", + "safespot": null, + "lifepoints": "47", + "strength_level": "33", + "id": "5358", + "aggressive": "true", + "range_level": "1", + "attack_level": "33" + }, + { + "examine": "A giant skeleton.", + "melee_animation": "5499", + "range_animation": "0", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "5503", + "name": "Giant skeleton", + "defence_level": "60", + "safespot": null, + "lifepoints": "85", + "strength_level": "60", + "id": "5359", + "range_level": "1", + "attack_level": "60" + }, + { + "examine": "A fiendish embodiment of water.", + "combat_style": "1", + "melee_animation": "1582", + "range_animation": "1582", + "combat_audio": "3774,3773,3772", + "attack_speed": "4", + "magic_level": "105", + "defence_animation": "1581", + "weakness": "4", + "magic_animation": "1582", + "death_animation": "1580", + "name": "Waterfiend", + "defence_level": "128", + "poison_immune": "true", + "safespot": null, + "lifepoints": "128", + "strength_level": "0", + "id": "5361", + "aggressive": "true", + "bonuses": "0,0,0,0,0,100,100,10,100,100,0,0,0,0,0", + "range_level": "105", + "projectile": "16", + "attack_level": "0" + }, + { + "examine": "It appears to be intelligent and savage.", + "melee_animation": "91", + "range_animation": "91", + "combat_audio": "408,410,409", + "attack_speed": "4", + "magic_level": "168", + "defence_animation": "89", + "weakness": "3", + "slayer_exp": "183", + "magic_animation": "91", + "death_animation": "92", + "name": "Brutal green dragon", + "defence_level": "168", + "poison_immune": "true", + "safespot": null, + "lifepoints": "175", + "strength_level": "168", + "id": "5362", + "aggressive": "true", + "clue_level": "2", + "range_level": "0", + "attack_level": "268" + }, + { + "examine": "Experimenting with mithril gone bad!", + "melee_animation": "91", + "range_animation": "91", + "combat_audio": "408,410,409", + "attack_speed": "4", + "magic_level": "168", + "respawn_delay": "30", + "defence_animation": "89", + "weakness": "8", + "slayer_exp": "273", + "magic_animation": "91", + "death_animation": "92", + "name": "Mithril dragon", + "defence_level": "268", + "safespot": null, + "lifepoints": "254", + "strength_level": "268", + "id": "5363", + "aggressive": "true", + "bonuses": "0,0,0,0,0,50,100,70,30,90,0,0,0,0,0", + "clue_level": "2", + "range_level": "168", + "attack_level": "268" + }, + { + "weakness": "7", + "examine": "It appears to be intelligent and savage.", + "name": "Confused barbarian", + "defence_level": "50", + "safespot": null, + "lifepoints": "175", + "strength_level": "167", + "attack_speed": "6", + "id": "5364", + "range_level": "167", + "attack_level": "70" + }, + { + "examine": "Eeek! A ghost!", + "melee_animation": "5532", + "combat_audio": "436,439,438", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "5533", + "slayer_exp": "25", + "death_animation": "5534", + "name": "Ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "36", + "strength_level": "1", + "id": "5369", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Eeek! A ghost!", + "melee_animation": "5532", + "combat_audio": "436,439,438", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "5533", + "slayer_exp": "25", + "death_animation": "5534", + "name": "Ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "36", + "strength_level": "1", + "id": "5370", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Eeek! A ghost!", + "melee_animation": "5532", + "combat_audio": "436,439,438", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "5533", + "slayer_exp": "25", + "death_animation": "5534", + "name": "Ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "36", + "strength_level": "1", + "id": "5371", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Why does it attack with twigs? Swords and axes much better.", + "melee_animation": "5532", + "range_animation": "426", + "combat_audio": "436,439,438", + "magic_level": "80", + "defence_animation": "5533", + "weakness": "10", + "slayer_exp": "25", + "magic_animation": "0", + "death_animation": "5534", + "name": "Ghost", + "defence_level": "40", + "safespot": null, + "lifepoints": "36", + "strength_level": "80", + "id": "5372", + "aggressive": "true", + "range_level": "80", + "attack_level": "80" + }, + { + "examine": "Are these twigs meant to hurt Thok?", + "melee_animation": "5532", + "range_animation": "426", + "combat_audio": "436,439,438", + "magic_level": "80", + "defence_animation": "5533", + "weakness": "10", + "slayer_exp": "25", + "magic_animation": "0", + "death_animation": "5534", + "name": "Ghost", + "defence_level": "40", + "safespot": null, + "lifepoints": "36", + "strength_level": "80", + "id": "5373", + "aggressive": "true", + "range_level": "80", + "attack_level": "80" + }, + { + "examine": "It thinks it scary. Thok show it scary.", + "melee_animation": "5532", + "range_animation": "0", + "combat_audio": "436,439,438", + "magic_level": "80", + "defence_animation": "5533", + "weakness": "10", + "slayer_exp": "25", + "magic_animation": "0", + "death_animation": "5534", + "name": "Ghost", + "defence_level": "70", + "safespot": null, + "lifepoints": "36", + "strength_level": "80", + "id": "5374", + "aggressive": "true", + "range_level": "80", + "attack_level": "80" + }, + { + "examine": "Dead man walking.", + "melee_animation": "5568", + "range_animation": "5568", + "combat_audio": "918,923,922", + "attack_speed": "5", + "respawn_delay": "30", + "defence_animation": "5567", + "slayer_exp": "30", + "magic_animation": "5568", + "death_animation": "5569", + "name": "Zombie", + "defence_level": "25", + "safespot": null, + "lifepoints": "23", + "strength_level": "1", + "id": "5375", + "aggressive": "true", + "bonuses": "15,25,25,25,25,25,25,15,15,25,25,25,25,25,25", + "range_level": "1", + "attack_level": "25" + }, + { + "examine": "Dead man walking.", + "melee_animation": "5568", + "range_animation": "5568", + "combat_audio": "918,923,922", + "attack_speed": "5", + "respawn_delay": "30", + "defence_animation": "5567", + "slayer_exp": "30", + "magic_animation": "5568", + "death_animation": "5569", + "name": "Zombie", + "defence_level": "25", + "safespot": null, + "lifepoints": "23", + "strength_level": "1", + "id": "5376", + "aggressive": "true", + "bonuses": "15,25,25,25,25,25,25,15,15,25,25,25,25,25,25", + "range_level": "1", + "attack_level": "25" + }, + { + "examine": "Dead man walking.", + "melee_animation": "5578", + "range_animation": "5578", + "combat_audio": "918,923,922", + "attack_speed": "5", + "respawn_delay": "30", + "defence_animation": "5579", + "slayer_exp": "30", + "magic_animation": "5578", + "death_animation": "5580", + "name": "Zombie", + "defence_level": "28", + "safespot": null, + "lifepoints": "30", + "strength_level": "1", + "id": "5377", + "aggressive": "true", + "bonuses": "15,25,28,28,25,28,28,15,15,28,25,25,25,25,25", + "range_level": "1", + "attack_level": "38" + }, + { + "examine": "Dead man walking.", + "melee_animation": "5578", + "range_animation": "5578", + "combat_audio": "918,923,922", + "attack_speed": "5", + "respawn_delay": "30", + "defence_animation": "5579", + "slayer_exp": "30", + "magic_animation": "5578", + "death_animation": "5580", + "name": "Zombie", + "defence_level": "28", + "safespot": null, + "lifepoints": "30", + "strength_level": "1", + "id": "5378", + "aggressive": "true", + "bonuses": "15,25,28,28,25,28,28,15,15,28,25,25,25,25,25", + "range_level": "1", + "attack_level": "38" + }, + { + "examine": "The walking dead.", + "melee_animation": "5578", + "range_animation": "5578", + "combat_audio": "918,923,922", + "attack_speed": "5", + "respawn_delay": "30", + "defence_animation": "5579", + "slayer_exp": "30", + "magic_animation": "5578", + "death_animation": "5580", + "name": "Zombie", + "defence_level": "48", + "safespot": null, + "lifepoints": "40", + "strength_level": "1", + "id": "5379", + "aggressive": "true", + "bonuses": "35,45,45,45,45,45,45,35,35,45,45,45,45,45,45", + "range_level": "1", + "attack_level": "47" + }, + { + "examine": "The walking dead.", + "melee_animation": "5578", + "range_animation": "5578", + "combat_audio": "918,923,922", + "attack_speed": "5", + "respawn_delay": "30", + "defence_animation": "5579", + "slayer_exp": "30", + "magic_animation": "5578", + "death_animation": "5580", + "name": "Zombie", + "defence_level": "48", + "safespot": null, + "lifepoints": "40", + "strength_level": "1", + "id": "5380", + "aggressive": "true", + "bonuses": "35,45,45,45,45,45,45,35,35,45,45,45,45,45,45", + "range_level": "1", + "attack_level": "47" + }, + { + "examine": "Animated steel armour.", + "melee_animation": "386", + "range_animation": "0", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "4167", + "name": "Animated steel armour", + "defence_level": "28", + "safespot": null, + "lifepoints": "40", + "strength_level": "28", + "id": "5382", + "range_level": "1", + "attack_level": "28" + }, + { + "examine": "Big and bony, just how I like them.", + "start_gfx": "2713", + "melee_animation": "5499", + "range_animation": "5499", + "attack_speed": "2", + "defence_animation": "5489", + "magic_animation": "5499", + "death_animation": "5503", + "name": "Giant skeleton", + "defence_level": "85", + "poison_immune": "true", + "safespot": null, + "lifepoints": "100", + "strength_level": "95", + "id": "5384", + "aggressive": "true", + "bonuses": "25,25,25,25,25,25,25,25,25,25,25,25,25,25,25", + "range_level": "1", + "projectile": "2718", + "attack_level": "95" + }, + { + "melee_animation": "5568", + "combat_audio": "931,923,922", + "respawn_delay": "60", + "defence_animation": "5567", + "slayer_exp": "30", + "death_animation": "5569", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "56", + "strength_level": "1", + "id": "5393", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "slayer_exp": "30", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "40", + "combat_audio": "931,923,922", + "strength_level": "1", + "id": "5394", + "range_level": "1", + "attack_level": "1" + }, + { + "slayer_exp": "30", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "40", + "combat_audio": "931,923,922", + "strength_level": "1", + "id": "5395", + "range_level": "1", + "attack_level": "1" + }, + { + "slayer_exp": "30", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "40", + "combat_audio": "931,923,922", + "strength_level": "1", + "id": "5396", + "range_level": "1", + "attack_level": "1" + }, + { + "slayer_exp": "30", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "40", + "combat_audio": "931,923,922", + "strength_level": "1", + "id": "5397", + "range_level": "1", + "attack_level": "1" + }, + { + "slayer_exp": "30", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "40", + "combat_audio": "931,923,922", + "strength_level": "1", + "id": "5398", + "range_level": "1", + "attack_level": "1" + }, + { + "slayer_exp": "30", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "40", + "combat_audio": "931,923,922", + "strength_level": "1", + "id": "5399", + "range_level": "1", + "attack_level": "1" + }, + { + "slayer_exp": "30", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "40", + "combat_audio": "931,923,922", + "strength_level": "1", + "id": "5400", + "range_level": "1", + "attack_level": "1" + }, + { + "slayer_exp": "30", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "40", + "combat_audio": "931,923,922", + "strength_level": "1", + "id": "5401", + "range_level": "1", + "attack_level": "1" + }, + { + "slayer_exp": "30", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "40", + "combat_audio": "931,923,922", + "strength_level": "1", + "id": "5402", + "range_level": "1", + "attack_level": "1" + }, + { + "slayer_exp": "30", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "40", + "combat_audio": "931,923,922", + "strength_level": "1", + "id": "5403", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "5568", + "combat_audio": "931,923,922", + "respawn_delay": "60", + "defence_animation": "5567", + "slayer_exp": "30", + "death_animation": "5569", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "92", + "strength_level": "1", + "id": "5404", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "slayer_exp": "30", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "40", + "combat_audio": "931,923,922", + "strength_level": "1", + "id": "5405", + "range_level": "1", + "attack_level": "1" + }, + { + "slayer_exp": "30", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "40", + "combat_audio": "931,923,922", + "strength_level": "1", + "id": "5406", + "range_level": "1", + "attack_level": "1" + }, + { + "slayer_exp": "30", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "40", + "combat_audio": "931,923,922", + "strength_level": "1", + "id": "5407", + "range_level": "1", + "attack_level": "1" + }, + { + "slayer_exp": "30", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "40", + "combat_audio": "931,923,922", + "strength_level": "1", + "id": "5408", + "range_level": "1", + "attack_level": "1" + }, + { + "slayer_exp": "30", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "40", + "combat_audio": "931,923,922", + "strength_level": "1", + "id": "5409", + "range_level": "1", + "attack_level": "1" + }, + { + "slayer_exp": "30", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "40", + "combat_audio": "931,923,922", + "strength_level": "1", + "id": "5410", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "How does it move of its own accord?", + "melee_animation": "5591", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5592", + "name": "Possessed pickaxe", + "defence_level": "55", + "safespot": null, + "lifepoints": "78", + "strength_level": "55", + "id": "5413", + "aggressive": "true", + "range_level": "1", + "attack_level": "55" + }, + { + "examine": "How does it move of its own accord?", + "melee_animation": "5597", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5596", + "name": "Animated spade", + "defence_level": "52", + "safespot": null, + "lifepoints": "74", + "strength_level": "52", + "id": "5414", + "range_level": "1", + "attack_level": "52" + }, + { + "examine": "A terrifying dog beast.", + "melee_animation": "5625", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "1", + "magic_animation": "0", + "death_animation": "5628", + "name": "Terror dog", + "defence_level": "47", + "safespot": null, + "lifepoints": "134", + "strength_level": "47", + "id": "5417", + "aggressive": "true", + "range_level": "1", + "attack_level": "47" + }, + { + "melee_animation": "5625", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "5626", + "death_animation": "5627", + "name": "Terror dog", + "defence_level": "1", + "safespot": null, + "lifepoints": "82", + "strength_level": "1", + "id": "5418", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "5617", + "attack_speed": "6", + "respawn_delay": "60", + "defence_animation": "5618", + "death_animation": "5619", + "name": "Tarn", + "defence_level": "1", + "safespot": null, + "lifepoints": "65", + "strength_level": "1", + "id": "5420", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "I preferred him when he was human.", + "melee_animation": "5617", + "range_animation": "0", + "attack_speed": "6", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5619", + "name": "Mutant tarn", + "defence_level": "57", + "safespot": null, + "lifepoints": "325", + "strength_level": "57", + "id": "5421", + "aggressive": "true", + "range_level": "1", + "attack_level": "57" + }, + { + "examine": "What restful music!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "null", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5439", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "What restful music!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "KGP Agent", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5442", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Instructs agility.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Agility Instructor", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5447", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An army commander.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Army Commander", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5448", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Sturdy cold being.", + "melee_animation": "5724", + "range_animation": "5725", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "0", + "magic_animation": "0", + "death_animation": "5726", + "name": "Icelord", + "defence_level": "30", + "safespot": null, + "lifepoints": "42", + "strength_level": "22", + "id": "5452", + "aggressive": "true", + "range_level": "30", + "attack_level": "22" + }, + { + "examine": "Sturdy cold being.", + "melee_animation": "5724", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "5726", + "name": "Icelord", + "defence_level": "30", + "safespot": null, + "lifepoints": "42", + "strength_level": "30", + "id": "5453", + "aggressive": "true", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "Sturdy cold being.", + "melee_animation": "5724", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "5726", + "name": "Icelord", + "defence_level": "30", + "safespot": null, + "lifepoints": "42", + "strength_level": "30", + "id": "5454", + "aggressive": "true", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "Sturdy cold being.", + "melee_animation": "5724", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "5726", + "name": "Icelord", + "defence_level": "30", + "safespot": null, + "lifepoints": "42", + "strength_level": "30", + "id": "5455", + "aggressive": "true", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "An impressive-looking troll.", + "melee_animation": "5374", + "range_animation": "0", + "magic_level": "65", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "5209", + "name": "Ice Troll King", + "defence_level": "65", + "safespot": null, + "lifepoints": "185", + "strength_level": "65", + "id": "5472", + "aggressive": "true", + "range_level": "65", + "attack_level": "65" + }, + { + "examine": "An ice troll youngling.", + "range_animation": "0", + "melee_animation": "284", + "attack_speed": "4", + "respawn_delay": "60", + "defence_animation": "285", + "weakness": "9", + "magic_animation": "0", + "death_animation": "287", + "name": "Ice troll runt", + "defence_level": "70", + "safespot": null, + "lifepoints": "60", + "strength_level": "70", + "id": "5473", + "aggressive": "true", + "bonuses": "60,60,60,0,0,30,60,30,0,0,0,60,0,0,0", + "range_level": "1", + "attack_level": "60" + }, + { + "examine": "A male troll wielding a large club.", + "range_animation": "0", + "melee_animation": "284", + "attack_speed": "4", + "respawn_delay": "60", + "defence_animation": "285", + "weakness": "9", + "magic_animation": "0", + "death_animation": "287", + "name": "Ice troll male", + "defence_level": "40", + "safespot": null, + "lifepoints": "80", + "strength_level": "80", + "id": "5474", + "aggressive": "true", + "bonuses": "60,60,60,0,0,30,60,30,0,0,0,60,0,0,0", + "range_level": "1", + "attack_level": "80" + }, + { + "examine": "An ice troll with a bag of rocks.", + "combat_style": "1", + "range_animation": "1142", + "melee_animation": "1142", + "attack_speed": "4", + "respawn_delay": "60", + "defence_animation": "285", + "weakness": "0", + "magic_animation": "0", + "death_animation": "287", + "name": "Ice troll female", + "defence_level": "40", + "safespot": null, + "lifepoints": "80", + "strength_level": "80", + "id": "5475", + "aggressive": "true", + "bonuses": "60,60,60,0,0,30,60,30,0,0,0,60,0,0,0", + "range_level": "1", + "projectile": "276", + "attack_level": "80" + }, + { + "examine": "A large ice troll.", + "melee_animation": "4332", + "range_animation": "0", + "attack_speed": "4", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "name": "Ice troll grunt", + "defence_level": "60", + "safespot": null, + "lifepoints": "80", + "strength_level": "100", + "id": "5476", + "aggressive": "true", + "bonuses": "60,60,60,0,0,30,60,30,0,0,0,60,0,0,0", + "range_level": "1", + "attack_level": "100" + }, + { + "examine": "An ill-tempered king.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "King Gjuki Sorvott IV", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5478", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Thorkel Silkbeard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "498,500,499", + "strength_level": "1", + "id": "5480", + "range_level": "1", + "attack_level": "1" + }, + { + "facing_booth": "true", + "name": "Magnus Gram", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "498,500,499", + "strength_level": "1", + "id": "5488", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A guard on insult duty.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5489", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "5490", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "5491", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of King Sorvott's militia.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "0", + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5492", + "aggressive": "true", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A miner at work.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Miner", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5497", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The Burgher's protectors.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "0", + "name": "Honour guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5514", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The Burgher's protectors.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "0", + "name": "Honour guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5516", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of your militia.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "0", + "name": "Honour guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5517", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ice troll youngling.", + "range_animation": "0", + "melee_animation": "284", + "attack_speed": "4", + "respawn_delay": "60", + "defence_animation": "285", + "weakness": "9", + "magic_animation": "0", + "death_animation": "287", + "name": "Ice troll runt", + "defence_level": "70", + "safespot": null, + "lifepoints": "60", + "strength_level": "70", + "id": "5521", + "aggressive": "true", + "bonuses": "60,60,60,0,0,30,60,30,0,0,0,60,0,0,0", + "range_level": "1", + "attack_level": "60" + }, + { + "examine": "A male troll wielding a large club.", + "range_animation": "0", + "melee_animation": "284", + "attack_speed": "4", + "respawn_delay": "60", + "defence_animation": "285", + "weakness": "9", + "magic_animation": "0", + "death_animation": "287", + "name": "Ice troll male", + "defence_level": "40", + "safespot": null, + "lifepoints": "80", + "strength_level": "80", + "id": "5522", + "aggressive": "true", + "bonuses": "60,60,60,0,0,30,60,30,0,0,0,60,0,0,0", + "range_level": "1", + "attack_level": "80" + }, + { + "examine": "An ice troll with a bag of rocks.", + "combat_style": "1", + "range_animation": "1142", + "melee_animation": "1142", + "attack_speed": "4", + "respawn_delay": "60", + "defence_animation": "285", + "weakness": "0", + "magic_animation": "0", + "death_animation": "287", + "name": "Ice troll female", + "defence_level": "40", + "safespot": null, + "lifepoints": "80", + "strength_level": "80", + "id": "5523", + "aggressive": "true", + "bonuses": "60,60,60,0,0,30,60,30,0,0,0,60,0,0,0", + "range_level": "1", + "projectile": "276", + "attack_level": "80" + }, + { + "examine": "An ice troll youngling.", + "range_animation": "0", + "melee_animation": "284", + "attack_speed": "4", + "respawn_delay": "60", + "defence_animation": "285", + "weakness": "9", + "magic_animation": "0", + "death_animation": "287", + "name": "Ice troll runt", + "defence_level": "70", + "safespot": null, + "lifepoints": "60", + "strength_level": "70", + "id": "5525", + "aggressive": "true", + "bonuses": "60,60,60,0,0,30,60,30,0,0,0,60,0,0,0", + "range_level": "1", + "attack_level": "60" + }, + { + "examine": "A male troll wielding a large club.", + "range_animation": "0", + "melee_animation": "284", + "attack_speed": "4", + "respawn_delay": "60", + "defence_animation": "285", + "weakness": "9", + "magic_animation": "0", + "death_animation": "287", + "name": "Ice troll male", + "defence_level": "40", + "safespot": null, + "lifepoints": "80", + "strength_level": "80", + "id": "5526", + "aggressive": "true", + "bonuses": "60,60,60,0,0,30,60,30,0,0,0,60,0,0,0", + "range_level": "1", + "attack_level": "80" + }, + { + "examine": "An ice troll with a bag of rocks.", + "combat_style": "1", + "range_animation": "1142", + "melee_animation": "1142", + "attack_speed": "4", + "respawn_delay": "60", + "defence_animation": "285", + "weakness": "0", + "magic_animation": "0", + "death_animation": "287", + "name": "Ice troll female", + "defence_level": "40", + "safespot": null, + "lifepoints": "80", + "strength_level": "80", + "id": "5527", + "aggressive": "true", + "bonuses": "60,60,60,0,0,30,60,30,0,0,0,60,0,0,0", + "range_level": "1", + "projectile": "276", + "attack_level": "80" + }, + { + "examine": "A hairy, smelly, grazing animal.", + "melee_animation": "5782", + "range_animation": "5782", + "combat_audio": "3378,3380,3379", + "attack_speed": "4", + "defence_animation": "5783", + "weakness": "7", + "magic_animation": "5782", + "death_animation": "5784", + "name": "Yak", + "defence_level": "1", + "safespot": null, + "lifepoints": "50", + "strength_level": "10", + "id": "5529", + "range_level": "1", + "attack_level": "20" + }, + { + "examine": "Antisocial.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Sorceress", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5531", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Come", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Apprentice", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5532", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An autumn elemental.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Autumn Elemental", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5533", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A spring elemental.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Spring Elemental", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5539", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A summer elemental.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Summer Elemental", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5547", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A winter elemental.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Winter Elemental", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5553", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It dare attack Pretty Lass? Thok crush its puny skull!", + "range_animation": "0", + "magic_level": "95", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "name": "Osman", + "defence_level": "50", + "safespot": null, + "lifepoints": "157", + "strength_level": "95", + "id": "5561", + "aggressive": "true", + "range_level": "95", + "attack_level": "95" + }, + { + "examine": "She's honest about the things you aren't.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Sin Seer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5571", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A Shadow Realm guardian.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "436,439,438", + "defence_animation": "0", + "slayer_exp": "25", + "magic_animation": "0", + "death_animation": "0", + "name": "Ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5572", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Is it male or female?", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Homunculus", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5581", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Strong", + "range_animation": "0", + "magic_level": "95", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "name": "Cage", + "defence_level": "70", + "safespot": null, + "lifepoints": "85", + "strength_level": "95", + "id": "5584", + "aggressive": "true", + "range_level": "95", + "attack_level": "95" + }, + { + "examine": "Famous for his fights.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "'Black-eye", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5589", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Count them pinkies!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "'No fingers", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5590", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He wishes he had teeth.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "'Gummy", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5591", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Is it a frog", + "melee_animation": "5842", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "2", + "magic_animation": "0", + "death_animation": "5841", + "name": "Frogeel", + "defence_level": "49", + "safespot": null, + "lifepoints": "70", + "strength_level": "36", + "id": "5593", + "aggressive": "true", + "range_level": "49", + "attack_level": "36" + }, + { + "death_animation": "146", + "name": "Spidine", + "defence_level": "1", + "safespot": null, + "lifepoints": "35", + "melee_animation": "143", + "strength_level": "1", + "id": "5594", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1", + "defence_animation": "144" + }, + { + "examine": "Definitely not a chicken or a swordfish.", + "melee_animation": "5387", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "5389", + "name": "Swordchick", + "defence_level": "45", + "safespot": null, + "lifepoints": "64", + "strength_level": "45", + "id": "5595", + "range_level": "1", + "attack_level": "45" + }, + { + "melee_animation": "6800", + "respawn_delay": "60", + "defence_animation": "6802", + "death_animation": "6801", + "name": "Jubster", + "defence_level": "1", + "safespot": null, + "lifepoints": "60", + "strength_level": "1", + "id": "5596", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Since when did newts have beaks?", + "melee_animation": "2299", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "2301", + "name": "Newtroost", + "defence_level": "40", + "safespot": null, + "lifepoints": "57", + "strength_level": "40", + "id": "5597", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "Half unicorn", + "melee_animation": "5849", + "range_animation": "0", + "attack_speed": "5", + "magic_level": "41", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "4", + "magic_animation": "0", + "death_animation": "5851", + "name": "Unicow", + "defence_level": "41", + "safespot": null, + "lifepoints": "58", + "strength_level": "30", + "id": "5603", + "aggressive": "true", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "Holier than thou.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Monk", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5608", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Holier than thou.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Monk", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5609", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Holier than thou.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Monk", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5610", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Holier than thou.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Monk", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5611", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "I'd prefer it if it were a muffin...", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Puffin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5614", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Monk", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "5619", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Monk", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "5620", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Monk", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "5621", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Monk", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "5622", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Bedside manner is a little lacking", + "melee_animation": "5643", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5658", + "name": "Sorebones", + "defence_level": "35", + "safespot": null, + "lifepoints": "50", + "strength_level": "35", + "id": "5627", + "range_level": "1", + "attack_level": "35" + }, + { + "examine": "I hope his hands don't shake.", + "melee_animation": "5643", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5658", + "name": "Sorebones", + "defence_level": "35", + "safespot": null, + "lifepoints": "50", + "strength_level": "35", + "id": "5628", + "range_level": "1", + "attack_level": "35" + }, + { + "examine": "Aaaarg", + "melee_animation": "5647", + "range_animation": "0", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5649", + "name": "Zombie pirate", + "defence_level": "35", + "safespot": null, + "lifepoints": "50", + "strength_level": "35", + "id": "5629", + "aggressive": "true", + "range_level": "1", + "attack_level": "35" + }, + { + "melee_animation": "5647", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "5648", + "death_animation": "5649", + "name": "Zombie pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "52", + "strength_level": "1", + "id": "5630", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Aaaarg", + "melee_animation": "5647", + "range_animation": "0", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5649", + "name": "Zombie pirate", + "defence_level": "35", + "safespot": null, + "lifepoints": "50", + "strength_level": "35", + "id": "5631", + "aggressive": "true", + "range_level": "1", + "attack_level": "35" + }, + { + "melee_animation": "5647", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "5648", + "death_animation": "5649", + "name": "Zombie pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "52", + "strength_level": "1", + "id": "5632", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Aaaarg", + "melee_animation": "5647", + "range_animation": "0", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5649", + "name": "Zombie pirate", + "defence_level": "35", + "safespot": null, + "lifepoints": "50", + "strength_level": "35", + "id": "5633", + "aggressive": "true", + "range_level": "1", + "attack_level": "35" + }, + { + "examine": "Aaaarg", + "melee_animation": "5647", + "range_animation": "0", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5649", + "name": "Zombie pirate", + "defence_level": "35", + "safespot": null, + "lifepoints": "50", + "strength_level": "35", + "id": "5634", + "aggressive": "true", + "range_level": "1", + "attack_level": "35" + }, + { + "examine": "Aaaarg", + "melee_animation": "5647", + "range_animation": "0", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5649", + "name": "Zombie pirate", + "defence_level": "35", + "safespot": null, + "lifepoints": "50", + "strength_level": "35", + "id": "5635", + "aggressive": "true", + "range_level": "1", + "attack_level": "35" + }, + { + "melee_animation": "5647", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "5648", + "death_animation": "5649", + "name": "Zombie pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "52", + "strength_level": "1", + "id": "5636", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Aaaarg", + "melee_animation": "5651", + "range_animation": "0", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5654", + "name": "Zombie pirate", + "defence_level": "35", + "safespot": null, + "lifepoints": "50", + "strength_level": "35", + "id": "5637", + "aggressive": "true", + "range_level": "1", + "attack_level": "35" + }, + { + "examine": "Aaaarg", + "melee_animation": "5651", + "range_animation": "0", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5654", + "name": "Zombie pirate", + "defence_level": "35", + "safespot": null, + "lifepoints": "50", + "strength_level": "35", + "id": "5638", + "aggressive": "true", + "range_level": "1", + "attack_level": "35" + }, + { + "examine": "Aaaarg", + "melee_animation": "5651", + "range_animation": "0", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5654", + "name": "Zombie pirate", + "defence_level": "35", + "safespot": null, + "lifepoints": "50", + "strength_level": "35", + "id": "5639", + "aggressive": "true", + "range_level": "1", + "attack_level": "35" + }, + { + "examine": "Aaaarg", + "melee_animation": "5651", + "range_animation": "0", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5654", + "name": "Zombie pirate", + "defence_level": "35", + "safespot": null, + "lifepoints": "50", + "strength_level": "35", + "id": "5640", + "aggressive": "true", + "range_level": "1", + "attack_level": "35" + }, + { + "examine": "Aaaarg", + "melee_animation": "5651", + "range_animation": "0", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5654", + "name": "Zombie pirate", + "defence_level": "35", + "safespot": null, + "lifepoints": "50", + "strength_level": "35", + "id": "5641", + "aggressive": "true", + "range_level": "1", + "attack_level": "35" + }, + { + "examine": "Aaaarg", + "melee_animation": "5880", + "range_animation": "0", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5654", + "name": "Zombie pirate", + "defence_level": "35", + "safespot": null, + "lifepoints": "50", + "strength_level": "35", + "id": "5642", + "aggressive": "true", + "range_level": "1", + "attack_level": "35" + }, + { + "examine": "Aaaarg", + "melee_animation": "5880", + "range_animation": "0", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5654", + "name": "Zombie pirate", + "defence_level": "35", + "safespot": null, + "lifepoints": "50", + "strength_level": "35", + "id": "5643", + "aggressive": "true", + "range_level": "1", + "attack_level": "35" + }, + { + "examine": "Aaaarg", + "melee_animation": "5880", + "range_animation": "0", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5654", + "name": "Zombie pirate", + "defence_level": "35", + "safespot": null, + "lifepoints": "50", + "strength_level": "35", + "id": "5644", + "aggressive": "true", + "range_level": "1", + "attack_level": "35" + }, + { + "examine": "Aaaarg", + "melee_animation": "5880", + "range_animation": "0", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5654", + "name": "Zombie pirate", + "defence_level": "35", + "safespot": null, + "lifepoints": "50", + "strength_level": "35", + "id": "5645", + "aggressive": "true", + "range_level": "1", + "attack_level": "35" + }, + { + "examine": "Aaaarg", + "melee_animation": "5880", + "range_animation": "0", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5654", + "name": "Zombie pirate", + "defence_level": "35", + "safespot": null, + "lifepoints": "50", + "strength_level": "35", + "id": "5646", + "aggressive": "true", + "range_level": "1", + "attack_level": "35" + }, + { + "examine": "Aaaarg", + "melee_animation": "5884", + "range_animation": "0", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5886", + "name": "Zombie pirate", + "defence_level": "35", + "safespot": null, + "lifepoints": "50", + "strength_level": "35", + "id": "5647", + "aggressive": "true", + "range_level": "1", + "attack_level": "35" + }, + { + "examine": "Aaaarg", + "melee_animation": "5884", + "range_animation": "0", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5886", + "name": "Zombie pirate", + "defence_level": "35", + "safespot": null, + "lifepoints": "50", + "strength_level": "35", + "id": "5648", + "aggressive": "true", + "range_level": "1", + "attack_level": "35" + }, + { + "melee_animation": "5647", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "5648", + "death_animation": "5649", + "name": "Zombie pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "52", + "strength_level": "1", + "id": "5649", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Aaaarg", + "melee_animation": "5884", + "range_animation": "0", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5886", + "name": "Zombie pirate", + "defence_level": "35", + "safespot": null, + "lifepoints": "50", + "strength_level": "35", + "id": "5650", + "aggressive": "true", + "range_level": "1", + "attack_level": "35" + }, + { + "melee_animation": "5647", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "5648", + "death_animation": "5649", + "name": "Zombie pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "52", + "strength_level": "1", + "id": "5651", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Aaaarg", + "melee_animation": "5884", + "range_animation": "0", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5886", + "name": "Zombie pirate", + "defence_level": "35", + "safespot": null, + "lifepoints": "50", + "strength_level": "35", + "id": "5652", + "aggressive": "true", + "range_level": "1", + "attack_level": "35" + }, + { + "melee_animation": "5647", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "5648", + "death_animation": "5649", + "name": "Zombie pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "52", + "strength_level": "1", + "id": "5653", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Aaaarg", + "melee_animation": "5884", + "range_animation": "0", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5886", + "name": "Zombie pirate", + "defence_level": "35", + "safespot": null, + "lifepoints": "50", + "strength_level": "35", + "id": "5654", + "aggressive": "true", + "range_level": "1", + "attack_level": "35" + }, + { + "melee_animation": "5647", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "5648", + "death_animation": "5649", + "name": "Zombie pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "52", + "strength_level": "1", + "id": "5655", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Aaaarg", + "melee_animation": "5889", + "range_animation": "0", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5891", + "name": "Zombie pirate", + "defence_level": "35", + "safespot": null, + "lifepoints": "50", + "strength_level": "35", + "id": "5656", + "aggressive": "true", + "range_level": "1", + "attack_level": "35" + }, + { + "melee_animation": "5647", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "5648", + "death_animation": "5649", + "name": "Zombie pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "52", + "strength_level": "1", + "id": "5657", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Aaaarg", + "melee_animation": "5889", + "range_animation": "0", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5891", + "name": "Zombie pirate", + "defence_level": "35", + "safespot": null, + "lifepoints": "50", + "strength_level": "35", + "id": "5658", + "aggressive": "true", + "range_level": "1", + "attack_level": "35" + }, + { + "examine": "Aaaarg", + "melee_animation": "5889", + "range_animation": "0", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5891", + "name": "Zombie pirate", + "defence_level": "35", + "safespot": null, + "lifepoints": "50", + "strength_level": "35", + "id": "5659", + "aggressive": "true", + "range_level": "1", + "attack_level": "35" + }, + { + "melee_animation": "5647", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "5648", + "death_animation": "5649", + "name": "Zombie pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "52", + "strength_level": "1", + "id": "5660", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Aaaarg", + "melee_animation": "5889", + "range_animation": "0", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5891", + "name": "Zombie pirate", + "defence_level": "35", + "safespot": null, + "lifepoints": "50", + "strength_level": "35", + "id": "5661", + "aggressive": "true", + "range_level": "1", + "attack_level": "35" + }, + { + "melee_animation": "5647", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "5648", + "death_animation": "5649", + "name": "Zombie pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "52", + "strength_level": "1", + "id": "5662", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Aaaarg", + "melee_animation": "5889", + "range_animation": "0", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5891", + "name": "Zombie pirate", + "defence_level": "35", + "safespot": null, + "lifepoints": "50", + "strength_level": "35", + "id": "5663", + "aggressive": "true", + "range_level": "1", + "attack_level": "35" + }, + { + "melee_animation": "5647", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "5648", + "death_animation": "5649", + "name": "Zombie pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "52", + "strength_level": "1", + "id": "5664", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Aaaarg", + "melee_animation": "5889", + "range_animation": "0", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5891", + "name": "Zombie pirate", + "defence_level": "35", + "safespot": null, + "lifepoints": "50", + "strength_level": "35", + "id": "5665", + "aggressive": "true", + "range_level": "1", + "attack_level": "35" + }, + { + "examine": "It's trying to mash you flat! Less examine", + "melee_animation": "5895", + "range_animation": "0", + "magic_level": "52", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "5898", + "name": "Barrelchest", + "defence_level": "52", + "safespot": null, + "lifepoints": "285", + "strength_level": "52", + "id": "5666", + "aggressive": "true", + "range_level": "52", + "attack_level": "52" + }, + { + "examine": "He is one", + "melee_animation": "5970", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "5972", + "name": "Undead Lumberjack", + "defence_level": "10", + "safespot": null, + "lifepoints": "100", + "strength_level": "73", + "id": "5680", + "range_level": "1", + "attack_level": "73" + }, + { + "examine": "A big", + "melee_animation": "6079", + "range_animation": "0", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "2", + "slayer_exp": "93", + "magic_animation": "0", + "death_animation": "6081", + "name": "Cave bug", + "defence_level": "84", + "safespot": null, + "lifepoints": "93", + "strength_level": "80", + "id": "5750", + "bonuses": "0,0,0,0,0,72,59,35,25,95,0,0,0,0,0", + "range_level": "1", + "attack_level": "82" + }, + { + "examine": "A strange mole-like being.", + "melee_animation": "6012", + "combat_audio": "3492,3494,3493", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "6013", + "slayer_exp": "52", + "death_animation": "6014", + "name": "Molanisk", + "defence_level": "50", + "safespot": null, + "lifepoints": "52", + "strength_level": "40", + "id": "5751", + "aggressive": "true", + "clue_level": "1", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "One of the many citizens of Dorgesh-Kaan.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "469,472,471", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cave goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5752", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of the many citizens of Dorgesh-Kaan.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "469,472,471", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cave goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5753", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Cave goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "5754", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of the many citizens of Dorgesh-Kaan.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "469,472,471", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cave goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5755", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of the many citizens of Dorgesh-Kaan.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "469,472,471", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cave goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5756", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of the many citizens of Dorgesh-Kaan.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "469,472,471", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cave goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5757", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of the many citizens of Dorgesh-Kaan.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "469,472,471", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cave goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5758", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of the many citizens of Dorgesh-Kaan.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "469,472,471", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cave goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5759", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Cave goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "5760", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of the many citizens of Dorgesh-Kaan.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "469,472,471", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cave goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5761", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Cave goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "5762", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Cave goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "5763", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of the many citizens of Dorgesh-Kaan.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "469,472,471", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cave goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5764", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of the many citizens of Dorgesh-Kaan.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "469,472,471", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cave goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5765", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of the many citizens of Dorgesh-Kaan.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "469,472,471", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cave goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5766", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of the many citizens of Dorgesh-Kaan.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "469,472,471", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cave goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5767", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of the many citizens of Dorgesh-Kaan.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "469,472,471", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cave goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5768", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Cave goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "5769", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Looks after cave goblin money.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Banker", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5776", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Looks after cave goblin money.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Banker", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5777", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of the many citizens of Dorgesh-Kaan.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "469,472,471", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cave goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5783", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Taking a terribly important box from one place to another.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "703,705,704", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Crate goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5784", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of the many citizens of Dorgesh-Kaan.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "469,472,471", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cave goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5785", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Good at shorthand.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "469,472,471", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Goblin scribe", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5786", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He keeps order in the city.", + "melee_animation": "6007", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "6003", + "name": "Guard", + "defence_level": "42", + "safespot": null, + "lifepoints": "60", + "strength_level": "42", + "id": "5800", + "clue_level": "1", + "range_level": "1", + "attack_level": "42" + }, + { + "examine": "He keeps order in the city.", + "melee_animation": "6007", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "6003", + "name": "Guard", + "defence_level": "42", + "safespot": null, + "lifepoints": "60", + "strength_level": "42", + "id": "5801", + "clue_level": "1", + "range_level": "1", + "attack_level": "42" + }, + { + "examine": "A goblin baby.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Young 'un", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5803", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A goblin baby.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Nipper", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5805", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Cave goblin child", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "5807", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Cave goblin child", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "5808", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Cave goblin child", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "5809", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Cave goblin child", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "5810", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Cave goblin child", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "5811", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Cave goblin child", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "5812", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Cave goblin child", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "5813", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Cave goblin child", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "5814", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Cave goblin child", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "5815", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Cave goblin child", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "5816", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Cave goblin child", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "5817", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Cave goblin child", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "5818", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Cave goblin child", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "5819", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Cave goblin child", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "5820", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Cave goblin child", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "5821", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Cave goblin child", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "5822", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Don't spit", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "469,472,471", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Spit goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5823", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A bug-eyed little goblin fish. How cute.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "469,472,471", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Goblin fish", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5824", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Annoying little flappy things.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Moths", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5827", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "death_animation": "6092", + "name": "Rabbit", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "melee_animation": "6090", + "strength_level": "1", + "id": "5829", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1", + "defence_animation": "6091" + }, + { + "name": "Rat Burgiss", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "703,705,704", + "strength_level": "1", + "id": "5833", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A mean looking outlaw. Don't get too close!", + "melee_animation": "390", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Outlaw", + "defence_level": "23", + "safespot": null, + "lifepoints": "32", + "strength_level": "23", + "id": "5842", + "range_level": "1", + "attack_level": "23" + }, + { + "examine": "A mean looking outlaw. Don't get too close!", + "melee_animation": "390", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Outlaw", + "defence_level": "23", + "safespot": null, + "lifepoints": "32", + "strength_level": "23", + "id": "5843", + "range_level": "1", + "attack_level": "23" + }, + { + "examine": "A mean looking outlaw. Don't get too close!", + "melee_animation": "390", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Outlaw", + "defence_level": "23", + "safespot": null, + "lifepoints": "32", + "strength_level": "23", + "id": "5844", + "range_level": "1", + "attack_level": "23" + }, + { + "examine": "A mean looking outlaw. Don't get too close!", + "melee_animation": "390", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Outlaw", + "defence_level": "23", + "safespot": null, + "lifepoints": "32", + "strength_level": "23", + "id": "5845", + "range_level": "1", + "attack_level": "23" + }, + { + "examine": "A mean looking outlaw. Don't get too close!", + "melee_animation": "390", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Outlaw", + "defence_level": "23", + "safespot": null, + "lifepoints": "32", + "strength_level": "23", + "id": "5846", + "range_level": "1", + "attack_level": "23" + }, + { + "examine": "A mean looking outlaw. Don't get too close!", + "melee_animation": "390", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Outlaw", + "defence_level": "23", + "safespot": null, + "lifepoints": "32", + "strength_level": "23", + "id": "5847", + "range_level": "1", + "attack_level": "23" + }, + { + "examine": "A mean looking outlaw. Don't get too close!", + "melee_animation": "390", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Outlaw", + "defence_level": "23", + "safespot": null, + "lifepoints": "32", + "strength_level": "23", + "id": "5848", + "range_level": "1", + "attack_level": "23" + }, + { + "examine": "A mean looking outlaw. Don't get too close!", + "melee_animation": "390", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Outlaw", + "defence_level": "23", + "safespot": null, + "lifepoints": "32", + "strength_level": "23", + "id": "5849", + "range_level": "1", + "attack_level": "23" + }, + { + "examine": "A mean looking outlaw. Don't get too close!", + "melee_animation": "390", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Outlaw", + "defence_level": "23", + "safespot": null, + "lifepoints": "32", + "strength_level": "23", + "id": "5850", + "range_level": "1", + "attack_level": "23" + }, + { + "examine": "A mean looking outlaw. Don't get too close!", + "melee_animation": "390", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Outlaw", + "defence_level": "23", + "safespot": null, + "lifepoints": "32", + "strength_level": "23", + "id": "5851", + "range_level": "1", + "attack_level": "23" + }, + { + "examine": "Weird eyeball thing. Reminds Thok of breakfast.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "629,631,630", + "magic_level": "60", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "name": "Monkey", + "defence_level": "40", + "safespot": null, + "lifepoints": "85", + "strength_level": "60", + "id": "5852", + "aggressive": "true", + "range_level": "60", + "attack_level": "60" + }, + { + "examine": "For sitting on.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Bench", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5854", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "5855", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "5856", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He looks pretty skilled with that bow.", + "melee_animation": "426", + "range_animation": "0", + "defence_animation": "0", + "weakness": "0", + "magic_animation": "0", + "death_animation": "836", + "name": "H.A.M. Archer", + "defence_level": "20", + "safespot": null, + "lifepoints": "57", + "strength_level": "15", + "id": "5859", + "aggressive": "true", + "clue_level": "0", + "range_level": "20", + "attack_level": "15" + }, + { + "examine": "He bristles with arcane power.", + "combat_style": "2", + "melee_animation": "429", + "range_animation": "0", + "magic_level": "20", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "3", + "magic_animation": "0", + "death_animation": "836", + "name": "H.A.M. Mage", + "defence_level": "20", + "safespot": null, + "lifepoints": "57", + "strength_level": "15", + "id": "5860", + "aggressive": "true", + "clue_level": "0", + "range_level": "1", + "attack_level": "15" + }, + { + "examine": "No match for Thok. Silly demon.", + "magic_level": "85", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "name": "Zanik", + "defence_level": "85", + "safespot": null, + "lifepoints": "71", + "strength_level": "85", + "id": "5861", + "aggressive": "true", + "range_level": "85", + "attack_level": "85" + }, + { + "examine": "A worker on the train link.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Builder", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5864", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A worker on the train link.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Builder", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5865", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A worker on the train link.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Builder", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5866", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A worker on the train link.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Builder", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5867", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Cave goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "5873", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A goblin with big", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "469,472,471", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cave goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5874", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A goblin with big", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "469,472,471", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cave goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5875", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Cave goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "5876", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Cave goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "5877", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Cave goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "5878", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He sells tickets to Keldagrim.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "469,472,471", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ticket goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5879", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A dwarf from Keldagrim.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "slayer_exp": "16", + "magic_animation": "0", + "death_animation": "0", + "name": "Dwarf", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5880", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A dwarf from Keldagrim.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "slayer_exp": "16", + "magic_animation": "0", + "death_animation": "0", + "name": "Dwarf", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5881", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A dwarf from Keldagrim.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "slayer_exp": "16", + "magic_animation": "0", + "death_animation": "0", + "name": "Dwarf", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5882", + "range_level": "1", + "attack_level": "1" + }, + { + "slayer_exp": "16", + "examine": "A dwarf from Keldagrim.", + "name": "Dwarf", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5883", + "range_level": "1", + "attack_level": "1" + }, + { + "slayer_exp": "16", + "examine": "A dwarf from Keldagrim.", + "name": "Dwarf", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5884", + "range_level": "1", + "attack_level": "1" + }, + { + "slayer_exp": "16", + "examine": "A dwarf from Keldagrim.", + "name": "Dwarf", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5885", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He sells tickets to Dorgesh-Kaan.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ticket dwarf", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5886", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Are you good enough to fight?", + "melee_animation": "6318", + "range_animation": "0", + "magic_level": "70", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "6322", + "name": "The Inadequacy", + "defence_level": "70", + "safespot": null, + "lifepoints": "100", + "strength_level": "70", + "id": "5902", + "aggressive": "true", + "range_level": "70", + "attack_level": "70" + }, + { + "examine": "Can you endure long enough?", + "melee_animation": "6345", + "range_animation": "0", + "magic_level": "67", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "6347", + "name": "The Everlasting", + "defence_level": "67", + "safespot": null, + "lifepoints": "191", + "strength_level": "67", + "id": "5903", + "aggressive": "true", + "range_level": "67", + "attack_level": "67" + }, + { + "examine": "Can you bring yourself to hurt another?", + "melee_animation": "6329", + "range_animation": "0", + "magic_level": "65", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "6331", + "name": "The Untouchable", + "defence_level": "75", + "safespot": null, + "lifepoints": "100", + "strength_level": "65", + "id": "5904", + "aggressive": "true", + "range_level": "65", + "attack_level": "65" + }, + { + "examine": "What if you don't know how to win?", + "melee_animation": "6342", + "range_animation": "0", + "magic_level": "63", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "0", + "name": "The Illusive", + "defence_level": "63", + "safespot": null, + "lifepoints": "90", + "strength_level": "63", + "id": "5905", + "aggressive": "true", + "range_level": "63", + "attack_level": "63" + }, + { + "examine": "You can't escape your inadequacy!", + "melee_animation": "6310", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "6315", + "name": "A Doubt", + "defence_level": "55", + "safespot": null, + "lifepoints": "78", + "strength_level": "55", + "id": "5906", + "aggressive": "true", + "range_level": "1", + "attack_level": "55" + }, + { + "examine": "Dead stone defending a dead throne room.", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "name": "Dying tree", + "defence_level": "50", + "safespot": null, + "lifepoints": "142", + "strength_level": "50", + "id": "5908", + "aggressive": "true", + "range_level": "1", + "attack_level": "50" + }, + { + "examine": "Don't let her arm-wrestle you for money.", + "melee_animation": "422", + "range_animation": "0", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "836", + "name": "Barbarian", + "defence_level": "20", + "safespot": null, + "lifepoints": "28", + "strength_level": "20", + "id": "5909", + "clue_level": "0", + "range_level": "1", + "attack_level": "20" + }, + { + "examine": "A greasy, grimy gourmet.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cook", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5910", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He's suspiciously talented with a meat-cleaver.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cook", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5911", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "This grizzled soldier is here to distribute Rated Clan Wars badges.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Iffie", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5914", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Does what too many people aren't interested in doing.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cleaner", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5916", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A mangy mutt.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Stray dog", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5917", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He tries to keep order around here. His bizarre uniform isn't helping.", + "melee_animation": "6489", + "range_animation": "0", + "combat_audio": "2548,1979,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "6490", + "name": "Guard", + "defence_level": "18", + "safespot": null, + "lifepoints": "25", + "strength_level": "18", + "id": "5919", + "clue_level": "1", + "range_level": "1", + "attack_level": "18" + }, + { + "examine": "He tries to keep order around here. His bizarre uniform isn't helping.", + "melee_animation": "6489", + "range_animation": "0", + "combat_audio": "2548,1979,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "6490", + "name": "Guard", + "defence_level": "18", + "safespot": null, + "lifepoints": "25", + "strength_level": "18", + "id": "5920", + "clue_level": "1", + "range_level": "1", + "attack_level": "18" + }, + { + "examine": "He's studying to be a guard.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Trainee Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5921", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Trains the guards of the future.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Captain", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5922", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of Gielinor's many citizens.", + "melee_animation": "422", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Man", + "defence_level": "3", + "safespot": null, + "lifepoints": "4", + "strength_level": "3", + "id": "5923", + "clue_level": "0", + "range_level": "1", + "attack_level": "3" + }, + { + "examine": "One of Gielinor's many citizens.", + "melee_animation": "422", + "range_animation": "0", + "combat_audio": "511,506,505", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Woman", + "defence_level": "3", + "safespot": null, + "lifepoints": "4", + "strength_level": "3", + "id": "5924", + "clue_level": "0", + "range_level": "1", + "attack_level": "3" + }, + { + "examine": "Known for his light-fingered qualities.", + "melee_animation": "422", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Thief", + "defence_level": "9", + "safespot": null, + "lifepoints": "25", + "strength_level": "9", + "id": "5926", + "range_level": "1", + "attack_level": "9" + }, + { + "examine": "Known for his light-fingered qualities.", + "melee_animation": "422", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Thief", + "defence_level": "9", + "safespot": null, + "lifepoints": "25", + "strength_level": "9", + "id": "5927", + "range_level": "1", + "attack_level": "9" + }, + { + "examine": "Known for her light-fingered qualities.", + "melee_animation": "422", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Thief", + "defence_level": "8", + "safespot": null, + "lifepoints": "24", + "strength_level": "9", + "id": "5928", + "range_level": "1", + "attack_level": "9" + }, + { + "examine": "Known for her light-fingered qualities.", + "melee_animation": "422", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Thief", + "defence_level": "8", + "safespot": null, + "lifepoints": "24", + "strength_level": "9", + "id": "5929", + "range_level": "1", + "attack_level": "9" + }, + { + "examine": "Jacques Netis - a slightly pompous art expert.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Art Critic Jacques", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5930", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Seth Minas - an aged expert in Gielinor history.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Historian Minas", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5931", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A lady with lots of information about the Museum.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Information clerk", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5938", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A teacher and one of his pupils.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Teacher and pupil", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5944", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Looks kind of familiar.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Schoolboy", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5945", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A teacher and one of her pupils.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Teacher and pupil", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5947", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Looks hard at work.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Workman", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5952", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Could there be something exciting in his wheelbarrow?", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Workman", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5954", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A powerful knight of balance.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Void Knight", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5956", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Wheelbarrow loader.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Digsite workman", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5958", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Working hard.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Barge workman", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5959", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Working hard.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Barge workman", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5960", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Working hard.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Barge workman", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5961", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Working hard.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Barge workman", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5962", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Working hard.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Barge foreman", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5963", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An aged expert in natural history.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Natural historian", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5966", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Bloodsuckers!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Leech display", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5971", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Slugs of the sea variety.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Sea slugs display", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5972", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A house on its back.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Snail display", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5973", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A cheeky little monkey.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "629,631,630", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Monkey display", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5974", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A scaly little fellow.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Lizard display", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5975", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Nice suit.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Penguin display", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5976", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He's got the hump.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Camel display", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5977", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Terrifying!", + "melee_animation": "1010", + "range_animation": "0", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Terrorbird display", + "defence_level": "1", + "safespot": null, + "lifepoints": "34", + "strength_level": "23", + "id": "5978", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Looks like a fire-breather.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "408,410,409", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Dragon display", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5979", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Needs a good square meal.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Wyvern display", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5980", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A huge beast.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Battle tortoise display", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5981", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Loves making molehills.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Mole display", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5982", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It hides in stone", + "range_animation": "0", + "magic_level": "95", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "name": "Workman", + "defence_level": "1", + "safespot": null, + "lifepoints": "34", + "strength_level": "95", + "id": "5986", + "aggressive": "true", + "range_level": "95", + "attack_level": "95" + }, + { + "name": "Rupert the Beard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "498,500,499", + "strength_level": "1", + "id": "5990", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Rupert the Beard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "498,500,499", + "strength_level": "1", + "id": "5992", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A very odd looking creature.", + "melee_animation": "6513", + "range_animation": "0", + "magic_level": "46", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "6512", + "name": "Experiment No.2", + "defence_level": "46", + "safespot": null, + "lifepoints": "131", + "strength_level": "46", + "id": "5993", + "range_level": "46", + "attack_level": "46" + }, + { + "examine": "A huge mouse. It looks hungry...", + "melee_animation": "6519", + "range_animation": "0", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "6521", + "name": "Mouse", + "defence_level": "44", + "safespot": null, + "lifepoints": "62", + "strength_level": "44", + "id": "5994", + "aggressive": "true", + "range_level": "1", + "attack_level": "44" + }, + { + "melee_animation": "6501", + "respawn_delay": "60", + "defence_animation": "6503", + "death_animation": "6502", + "name": "Glod", + "defence_level": "1", + "safespot": null, + "lifepoints": "160", + "strength_level": "1", + "id": "5996", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Rupert the Beard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "498,500,499", + "strength_level": "1", + "id": "5999", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Rupert the Beard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "498,500,499", + "strength_level": "1", + "id": "6001", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Eek! A werewolf!", + "melee_animation": "6536", + "range_animation": "", + "combat_audio": "481,491,490", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "20", + "defence_animation": "6538", + "weakness": "", + "magic_animation": "", + "death_animation": "6537", + "name": "Werewolf", + "defence_level": "70", + "safespot": null, + "lifepoints": "100", + "strength_level": "70", + "id": "6006", + "aggressive": "false", + "bonuses": "0,0,0,0,0,0,0,0,60,0,0,0,0,0,0", + "clue_level": "1", + "range_level": "1", + "attack_level": "70" + }, + { + "examine": "Eek! A werewolf!", + "melee_animation": "6536", + "range_animation": "", + "combat_audio": "481,491,490", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "20", + "defence_animation": "6538", + "weakness": "", + "magic_animation": "", + "death_animation": "6537", + "name": "Werewolf", + "defence_level": "70", + "safespot": null, + "lifepoints": "100", + "strength_level": "70", + "id": "6007", + "aggressive": "false", + "bonuses": "0,0,0,0,0,0,0,0,60,0,0,0,0,0,0", + "clue_level": "1", + "range_level": "1", + "attack_level": "70" + }, + { + "examine": "Eek! A werewolf!", + "melee_animation": "6536", + "range_animation": "", + "combat_audio": "481,491,490", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "20", + "defence_animation": "6538", + "weakness": "", + "magic_animation": "", + "death_animation": "6537", + "name": "Werewolf", + "defence_level": "70", + "safespot": null, + "lifepoints": "100", + "strength_level": "70", + "id": "6008", + "aggressive": "false", + "bonuses": "0,0,0,0,0,0,0,0,60,0,0,0,0,0,0", + "clue_level": "1", + "range_level": "1", + "attack_level": "70" + }, + { + "examine": "Eek! A werewolf!", + "melee_animation": "6536", + "range_animation": "", + "combat_audio": "481,491,490", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "20", + "defence_animation": "6538", + "weakness": "", + "magic_animation": "", + "death_animation": "6537", + "name": "Werewolf", + "defence_level": "70", + "safespot": null, + "lifepoints": "100", + "strength_level": "70", + "id": "6009", + "aggressive": "false", + "bonuses": "0,0,0,0,0,0,0,0,60,0,0,0,0,0,0", + "clue_level": "1", + "range_level": "1", + "attack_level": "70" + }, + { + "examine": "Eek! A werewolf!", + "melee_animation": "6536", + "range_animation": "", + "combat_audio": "481,491,490", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "20", + "defence_animation": "6538", + "weakness": "", + "magic_animation": "", + "death_animation": "6537", + "name": "Werewolf", + "defence_level": "70", + "safespot": null, + "lifepoints": "100", + "strength_level": "70", + "id": "6010", + "aggressive": "false", + "bonuses": "0,0,0,0,0,0,0,0,60,0,0,0,0,0,0", + "clue_level": "1", + "range_level": "1", + "attack_level": "70" + }, + { + "examine": "Eek! A werewolf!", + "melee_animation": "6536", + "range_animation": "", + "combat_audio": "481,491,490", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "20", + "defence_animation": "6538", + "weakness": "", + "magic_animation": "", + "death_animation": "6537", + "name": "Werewolf", + "defence_level": "70", + "safespot": null, + "lifepoints": "100", + "strength_level": "70", + "id": "6011", + "aggressive": "false", + "bonuses": "0,0,0,0,0,0,0,0,60,0,0,0,0,0,0", + "clue_level": "1", + "range_level": "1", + "attack_level": "70" + }, + { + "examine": "Eek! A werewolf!", + "melee_animation": "6536", + "range_animation": "", + "combat_audio": "481,491,490", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "20", + "defence_animation": "6538", + "weakness": "", + "magic_animation": "", + "death_animation": "6537", + "name": "Werewolf", + "defence_level": "70", + "safespot": null, + "lifepoints": "100", + "strength_level": "70", + "id": "6012", + "aggressive": "false", + "bonuses": "0,0,0,0,0,0,0,0,60,0,0,0,0,0,0", + "clue_level": "1", + "range_level": "1", + "attack_level": "70" + }, + { + "examine": "Eek! A werewolf!", + "melee_animation": "6536", + "range_animation": "", + "combat_audio": "481,491,490", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "20", + "defence_animation": "6538", + "weakness": "", + "magic_animation": "", + "death_animation": "6537", + "name": "Werewolf", + "defence_level": "70", + "safespot": null, + "lifepoints": "100", + "strength_level": "70", + "id": "6013", + "aggressive": "false", + "bonuses": "0,0,0,0,0,0,0,0,60,0,0,0,0,0,0", + "clue_level": "1", + "range_level": "1", + "attack_level": "70" + }, + { + "examine": "Eek! A werewolf!", + "melee_animation": "6536", + "range_animation": "", + "combat_audio": "481,491,490", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "20", + "defence_animation": "6538", + "weakness": "", + "magic_animation": "", + "death_animation": "6537", + "name": "Werewolf", + "defence_level": "70", + "safespot": null, + "lifepoints": "100", + "strength_level": "70", + "id": "6014", + "aggressive": "false", + "bonuses": "0,0,0,0,0,0,0,0,60,0,0,0,0,0,0", + "clue_level": "1", + "range_level": "1", + "attack_level": "70" + }, + { + "examine": "Eek! A werewolf!", + "melee_animation": "6536", + "range_animation": "", + "combat_audio": "481,491,490", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "20", + "defence_animation": "6538", + "weakness": "", + "magic_animation": "", + "death_animation": "6537", + "name": "Werewolf", + "defence_level": "70", + "safespot": null, + "lifepoints": "100", + "strength_level": "70", + "id": "6015", + "aggressive": "false", + "bonuses": "0,0,0,0,0,0,0,0,60,0,0,0,0,0,0", + "clue_level": "1", + "range_level": "1", + "attack_level": "70" + }, + { + "examine": "Eek! A werewolf!", + "melee_animation": "6536", + "range_animation": "", + "combat_audio": "481,491,490", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "20", + "defence_animation": "6538", + "weakness": "", + "magic_animation": "", + "death_animation": "6537", + "name": "Werewolf", + "defence_level": "70", + "safespot": null, + "lifepoints": "100", + "strength_level": "70", + "id": "6016", + "aggressive": "false", + "bonuses": "0,0,0,0,0,0,0,0,60,0,0,0,0,0,0", + "clue_level": "1", + "range_level": "1", + "attack_level": "70" + }, + { + "examine": "Eek! A werewolf!", + "melee_animation": "6536", + "range_animation": "", + "combat_audio": "481,491,490", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "20", + "defence_animation": "6538", + "weakness": "", + "magic_animation": "", + "death_animation": "6537", + "name": "Werewolf", + "defence_level": "70", + "safespot": null, + "lifepoints": "100", + "strength_level": "70", + "id": "6017", + "aggressive": "false", + "bonuses": "0,0,0,0,0,0,0,0,60,0,0,0,0,0,0", + "clue_level": "1", + "range_level": "1", + "attack_level": "70" + }, + { + "examine": "Eek! A werewolf!", + "melee_animation": "6536", + "range_animation": "", + "combat_audio": "481,491,490", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "20", + "defence_animation": "6538", + "weakness": "", + "magic_animation": "", + "death_animation": "6537", + "name": "Werewolf", + "defence_level": "70", + "safespot": null, + "lifepoints": "100", + "strength_level": "70", + "id": "6018", + "aggressive": "false", + "bonuses": "0,0,0,0,0,0,0,0,60,0,0,0,0,0,0", + "clue_level": "1", + "range_level": "1", + "attack_level": "70" + }, + { + "examine": "Eek! A werewolf!", + "melee_animation": "6536", + "range_animation": "", + "combat_audio": "481,491,490", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "20", + "defence_animation": "6538", + "weakness": "", + "magic_animation": "", + "death_animation": "6537", + "name": "Werewolf", + "defence_level": "70", + "safespot": null, + "lifepoints": "100", + "strength_level": "70", + "id": "6019", + "aggressive": "false", + "bonuses": "0,0,0,0,0,0,0,0,60,0,0,0,0,0,0", + "clue_level": "1", + "range_level": "1", + "attack_level": "70" + }, + { + "examine": "Eek! A werewolf!", + "melee_animation": "6536", + "range_animation": "", + "combat_audio": "481,491,490", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "20", + "defence_animation": "6538", + "weakness": "", + "magic_animation": "", + "death_animation": "6537", + "name": "Werewolf", + "defence_level": "70", + "safespot": null, + "lifepoints": "100", + "strength_level": "70", + "id": "6020", + "aggressive": "false", + "bonuses": "0,0,0,0,0,0,0,0,60,0,0,0,0,0,0", + "clue_level": "1", + "range_level": "1", + "attack_level": "70" + }, + { + "examine": "Eek! A werewolf!", + "melee_animation": "6536", + "range_animation": "", + "combat_audio": "481,491,490", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "20", + "defence_animation": "6538", + "weakness": "", + "magic_animation": "", + "death_animation": "6537", + "name": "Werewolf", + "defence_level": "70", + "safespot": null, + "lifepoints": "100", + "strength_level": "70", + "id": "6021", + "aggressive": "false", + "bonuses": "0,0,0,0,0,0,0,0,60,0,0,0,0,0,0", + "clue_level": "1", + "range_level": "1", + "attack_level": "70" + }, + { + "examine": "Eek! A werewolf!", + "melee_animation": "6536", + "range_animation": "", + "combat_audio": "481,491,490", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "20", + "defence_animation": "6538", + "weakness": "", + "magic_animation": "", + "death_animation": "6537", + "name": "Werewolf", + "defence_level": "70", + "safespot": null, + "lifepoints": "100", + "strength_level": "70", + "id": "6022", + "aggressive": "false", + "bonuses": "0,0,0,0,0,0,0,0,60,0,0,0,0,0,0", + "clue_level": "1", + "range_level": "1", + "attack_level": "70" + }, + { + "examine": "Eek! A werewolf!", + "melee_animation": "6536", + "range_animation": "", + "combat_audio": "481,491,490", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "20", + "defence_animation": "6538", + "weakness": "", + "magic_animation": "", + "death_animation": "6537", + "name": "Werewolf", + "defence_level": "70", + "safespot": null, + "lifepoints": "100", + "strength_level": "70", + "id": "6023", + "aggressive": "false", + "bonuses": "0,0,0,0,0,0,0,0,60,0,0,0,0,0,0", + "clue_level": "1", + "range_level": "1", + "attack_level": "70" + }, + { + "examine": "Eek! A werewolf!", + "melee_animation": "6536", + "range_animation": "", + "combat_audio": "481,491,490", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "20", + "defence_animation": "6538", + "weakness": "", + "magic_animation": "", + "death_animation": "6537", + "name": "Werewolf", + "defence_level": "70", + "safespot": null, + "lifepoints": "100", + "strength_level": "70", + "id": "6024", + "aggressive": "false", + "bonuses": "0,0,0,0,0,0,0,0,60,0,0,0,0,0,0", + "clue_level": "1", + "range_level": "1", + "attack_level": "70" + }, + { + "examine": "Eek! A werewolf!", + "melee_animation": "6536", + "range_animation": "", + "combat_audio": "481,491,490", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "20", + "defence_animation": "6538", + "weakness": "", + "magic_animation": "", + "death_animation": "6537", + "name": "Werewolf", + "defence_level": "70", + "safespot": null, + "lifepoints": "100", + "strength_level": "70", + "id": "6025", + "aggressive": "false", + "bonuses": "0,0,0,0,0,0,0,0,60,0,0,0,0,0,0", + "clue_level": "1", + "range_level": "1", + "attack_level": "70" + }, + { + "examine": "A traveling man. Are those fleas?", + "melee_animation": "422", + "combat_audio": "511,513,512", + "attack_speed": "4", + "respawn_delay": "15", + "defence_animation": "425", + "death_animation": "836", + "name": "Boris", + "defence_level": "10", + "safespot": null, + "lifepoints": "60", + "strength_level": "10", + "id": "6026", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "range_level": "1", + "attack_level": "10" + }, + { + "examine": "A well organised shop keeper.", + "melee_animation": "422", + "combat_audio": "511,513,512", + "attack_speed": "4", + "respawn_delay": "15", + "defence_animation": "425", + "death_animation": "836", + "name": "Imre", + "defence_level": "10", + "safespot": null, + "lifepoints": "60", + "strength_level": "10", + "id": "6027", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "range_level": "1", + "attack_level": "10" + }, + { + "examine": "He's staring at the moon.", + "melee_animation": "422", + "combat_audio": "511,513,512", + "attack_speed": "4", + "respawn_delay": "15", + "defence_animation": "425", + "death_animation": "836", + "name": "Yuri", + "defence_level": "10", + "safespot": null, + "lifepoints": "60", + "strength_level": "10", + "id": "6028", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "range_level": "1", + "attack_level": "10" + }, + { + "examine": "He keeps calling me comrade.", + "melee_animation": "422", + "combat_audio": "511,513,512", + "attack_speed": "4", + "respawn_delay": "15", + "defence_animation": "425", + "death_animation": "836", + "name": "Joseph", + "defence_level": "10", + "safespot": null, + "lifepoints": "60", + "strength_level": "10", + "id": "6029", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "range_level": "1", + "attack_level": "10" + }, + { + "examine": "There's a set of brows that mean business.", + "melee_animation": "422", + "combat_audio": "511,513,512", + "attack_speed": "4", + "respawn_delay": "15", + "defence_animation": "425", + "death_animation": "836", + "name": "Nikolai", + "defence_level": "10", + "safespot": null, + "lifepoints": "60", + "strength_level": "10", + "id": "6030", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "range_level": "1", + "attack_level": "10" + }, + { + "examine": "This is one feral looking innkeeper.", + "melee_animation": "422", + "combat_audio": "511,513,512", + "attack_speed": "4", + "respawn_delay": "15", + "defence_animation": "425", + "death_animation": "836", + "name": "Eduard", + "defence_level": "10", + "safespot": null, + "lifepoints": "60", + "strength_level": "10", + "id": "6031", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "range_level": "1", + "attack_level": "10" + }, + { + "examine": "A tough looking villager.", + "melee_animation": "422", + "combat_audio": "511,513,512", + "attack_speed": "4", + "respawn_delay": "15", + "defence_animation": "425", + "death_animation": "836", + "name": "Lev", + "defence_level": "10", + "safespot": null, + "lifepoints": "60", + "strength_level": "10", + "id": "6032", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "range_level": "1", + "attack_level": "10" + }, + { + "examine": "A simple villager.", + "melee_animation": "422", + "combat_audio": "511,513,512", + "attack_speed": "4", + "respawn_delay": "15", + "defence_animation": "425", + "death_animation": "836", + "name": "Georgy", + "defence_level": "10", + "safespot": null, + "lifepoints": "60", + "strength_level": "10", + "id": "6033", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "range_level": "1", + "attack_level": "10" + }, + { + "examine": "Seems a bit of a drama queen.", + "melee_animation": "422", + "combat_audio": "511,513,512", + "attack_speed": "4", + "respawn_delay": "15", + "defence_animation": "425", + "death_animation": "836", + "name": "Svetlana", + "defence_level": "10", + "safespot": null, + "lifepoints": "60", + "strength_level": "10", + "id": "6034", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "range_level": "1", + "attack_level": "10" + }, + { + "examine": "I bet she works out.", + "melee_animation": "422", + "combat_audio": "511,513,512", + "attack_speed": "4", + "respawn_delay": "15", + "defence_animation": "425", + "death_animation": "836", + "name": "Irina", + "defence_level": "10", + "safespot": null, + "lifepoints": "60", + "strength_level": "10", + "id": "6035", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "range_level": "1", + "attack_level": "10" + }, + { + "examine": "She doesn't say much.", + "melee_animation": "422", + "combat_audio": "511,513,512", + "attack_speed": "4", + "respawn_delay": "15", + "defence_animation": "425", + "death_animation": "836", + "name": "Alexis", + "defence_level": "10", + "safespot": null, + "lifepoints": "60", + "strength_level": "10", + "id": "6036", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "range_level": "1", + "attack_level": "10" + }, + { + "examine": "She looks like she can handle herself.", + "melee_animation": "422", + "combat_audio": "511,513,512", + "attack_speed": "4", + "respawn_delay": "15", + "defence_animation": "425", + "death_animation": "836", + "name": "Milla", + "defence_level": "10", + "safespot": null, + "lifepoints": "60", + "strength_level": "10", + "id": "6037", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "range_level": "1", + "attack_level": "10" + }, + { + "examine": "She seems light on her feet.", + "melee_animation": "422", + "combat_audio": "511,513,512", + "attack_speed": "4", + "respawn_delay": "15", + "defence_animation": "425", + "death_animation": "836", + "name": "Galina", + "defence_level": "10", + "safespot": null, + "lifepoints": "60", + "strength_level": "10", + "id": "6038", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "range_level": "1", + "attack_level": "10" + }, + { + "examine": "A wise villager.", + "melee_animation": "422", + "combat_audio": "511,513,512", + "attack_speed": "4", + "respawn_delay": "15", + "defence_animation": "425", + "death_animation": "836", + "name": "Sofiya", + "defence_level": "10", + "safespot": null, + "lifepoints": "60", + "strength_level": "10", + "id": "6039", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "range_level": "1", + "attack_level": "10" + }, + { + "examine": "Not exactly a warrior princess.", + "melee_animation": "422", + "combat_audio": "511,513,512", + "attack_speed": "4", + "respawn_delay": "15", + "defence_animation": "425", + "death_animation": "836", + "name": "Ksenia", + "defence_level": "10", + "safespot": null, + "lifepoints": "60", + "strength_level": "10", + "id": "6040", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "range_level": "1", + "attack_level": "10" + }, + { + "examine": "A well off villager.", + "melee_animation": "422", + "combat_audio": "511,513,512", + "attack_speed": "4", + "respawn_delay": "15", + "defence_animation": "425", + "death_animation": "836", + "name": "Yadviga", + "defence_level": "10", + "safespot": null, + "lifepoints": "60", + "strength_level": "10", + "id": "6041", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "range_level": "1", + "attack_level": "10" + }, + { + "examine": "The woman.", + "melee_animation": "422", + "combat_audio": "511,513,512", + "attack_speed": "4", + "respawn_delay": "15", + "defence_animation": "425", + "death_animation": "836", + "name": "Nikita", + "defence_level": "10", + "safespot": null, + "lifepoints": "60", + "strength_level": "10", + "id": "6042", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "range_level": "1", + "attack_level": "10" + }, + { + "examine": "She seems sure of herself.", + "melee_animation": "422", + "combat_audio": "511,513,512", + "attack_speed": "4", + "respawn_delay": "15", + "defence_animation": "425", + "death_animation": "836", + "name": "Vera", + "defence_level": "10", + "safespot": null, + "lifepoints": "60", + "strength_level": "10", + "id": "6043", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "range_level": "1", + "attack_level": "10" + }, + { + "examine": "A healthy villager.", + "melee_animation": "422", + "combat_audio": "511,513,512", + "attack_speed": "4", + "respawn_delay": "15", + "defence_animation": "425", + "death_animation": "836", + "name": "Zoja", + "defence_level": "10", + "safespot": null, + "lifepoints": "60", + "strength_level": "10", + "id": "6044", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "range_level": "1", + "attack_level": "10" + }, + { + "examine": "She's looking for flowers.", + "melee_animation": "422", + "combat_audio": "511,513,512", + "attack_speed": "4", + "respawn_delay": "15", + "defence_animation": "425", + "death_animation": "836", + "name": "Liliya", + "defence_level": "10", + "safespot": null, + "lifepoints": "60", + "strength_level": "10", + "id": "6045", + "bonuses": "0,0,0,0,0,-21,-21,-21,-21,-21,0,0,0,0,0", + "range_level": "1", + "attack_level": "10" + }, + { + "melee_animation": "6559", + "combat_audio": "909,912,911", + "respawn_delay": "60", + "defence_animation": "6557", + "slayer_exp": "74", + "death_animation": "6558", + "name": "Big Wolf", + "defence_level": "1", + "safespot": null, + "lifepoints": "74", + "strength_level": "1", + "id": "6046", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A vicious mountain wolf.", + "melee_animation": "6579", + "range_animation": "6579", + "combat_audio": "909,912,911", + "attack_speed": "6", + "defence_animation": "6578", + "slayer_exp": "34", + "magic_animation": "6579", + "death_animation": "6576", + "name": "Wolf", + "defence_level": "22", + "safespot": null, + "lifepoints": "69", + "strength_level": "1", + "id": "6047", + "aggressive": "true", + "range_level": "1", + "attack_level": "22" + }, + { + "examine": "Now it has no armour", + "range_animation": "0", + "combat_audio": "481,491,490", + "magic_level": "95", + "defence_animation": "0", + "weakness": "10", + "slayer_exp": "34", + "magic_animation": "0", + "name": "Wolf", + "defence_level": "1", + "safespot": null, + "lifepoints": "157", + "strength_level": "95", + "id": "6048", + "aggressive": "true", + "range_level": "95", + "attack_level": "95" + }, + { + "examine": "A big coward. Thok mocks scaredy man.", + "combat_audio": "481,491,490", + "magic_level": "75", + "defence_animation": "0", + "weakness": "10", + "slayer_exp": "34", + "magic_animation": "0", + "name": "Wolf", + "defence_level": "75", + "safespot": null, + "lifepoints": "100", + "strength_level": "75", + "id": "6049", + "aggressive": "true", + "range_level": "75", + "attack_level": "75" + }, + { + "examine": "A vicious desert wolf.", + "melee_animation": "6579", + "range_animation": "6579", + "attack_speed": "5", + "defence_animation": "6578", + "weakness": "9", + "magic_animation": "6579", + "death_animation": "6558", + "name": "Desert Wolf", + "defence_level": "5", + "safespot": null, + "lifepoints": "55", + "strength_level": "20", + "id": "6050", + "range_level": "1", + "attack_level": "20" + }, + { + "examine": "A vicious desert wolf.", + "melee_animation": "6579", + "range_animation": "6579", + "attack_speed": "5", + "defence_animation": "6578", + "magic_animation": "6579", + "death_animation": "6558", + "name": "Desert Wolf", + "defence_level": "5", + "safespot": null, + "lifepoints": "55", + "strength_level": "20", + "id": "6051", + "range_level": "1", + "attack_level": "20" + }, + { + "examine": "Not man's best friend.", + "melee_animation": "6559", + "respawn_delay": "60", + "defence_animation": "6557", + "death_animation": "6558", + "name": "Ice wolf", + "defence_level": "1", + "safespot": null, + "lifepoints": "70", + "strength_level": "1", + "id": "6052", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An impling who likes the word \"dragon\".", + "name": "Dragon impling", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "408,410,409", + "strength_level": "1", + "id": "6054", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An impling who likes the word \"dragon.\"", + "name": "Dragon impling", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "408,410,409", + "strength_level": "1", + "id": "6064", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "She tends the wheat.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fairy Aeryka", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6072", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He looks a little lost.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Wandering impling", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6073", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An angry little imp. Grrr.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Imp defender", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6074", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A one-eyed man eater.", + "melee_animation": "4652", + "range_animation": "0", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "25", + "defence_animation": "4651", + "weakness": "8", + "slayer_exp": "75", + "magic_animation": "0", + "death_animation": "4653", + "name": "Cyclops", + "defence_level": "35", + "safespot": null, + "lifepoints": "75", + "strength_level": "65", + "id": "6078", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "65" + }, + { + "examine": "A one-eyed woman eater.", + "melee_animation": "4652", + "range_animation": "0", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "4651", + "weakness": "1", + "slayer_exp": "100", + "magic_animation": "0", + "death_animation": "4653", + "name": "Cyclops", + "defence_level": "65", + "safespot": null, + "lifepoints": "100", + "strength_level": "65", + "id": "6079", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "65" + }, + { + "examine": "A one-eyed man eater.", + "melee_animation": "4652", + "range_animation": "0", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "25", + "defence_animation": "4651", + "weakness": "8", + "slayer_exp": "75", + "magic_animation": "0", + "death_animation": "4653", + "name": "Cyclops", + "defence_level": "35", + "safespot": null, + "lifepoints": "75", + "strength_level": "65", + "id": "6080", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "65" + }, + { + "examine": "A one-eyed woman eater.", + "melee_animation": "4652", + "range_animation": "0", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "4651", + "weakness": "1", + "slayer_exp": "100", + "magic_animation": "0", + "death_animation": "4653", + "name": "Cyclops", + "defence_level": "65", + "safespot": null, + "lifepoints": "100", + "strength_level": "65", + "id": "6081", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "65" + }, + { + "examine": "Overgrown undead vermin.", + "melee_animation": "4933", + "range_animation": "0", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "4935", + "name": "Zombie rat", + "defence_level": "2", + "safespot": null, + "lifepoints": "2", + "strength_level": "2", + "id": "6088", + "range_level": "1", + "attack_level": "2" + }, + { + "examine": "Overgrown undead vermin.", + "melee_animation": "4933", + "range_animation": "0", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "4935", + "name": "Zombie rat", + "defence_level": "2", + "safespot": null, + "lifepoints": "2", + "strength_level": "2", + "id": "6089", + "range_level": "1", + "attack_level": "2" + }, + { + "examine": "Overgrown undead vermin.", + "melee_animation": "4933", + "range_animation": "0", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "4935", + "name": "Zombie rat", + "defence_level": "2", + "safespot": null, + "lifepoints": "2", + "strength_level": "2", + "id": "6090", + "range_level": "1", + "attack_level": "2" + }, + { + "melee_animation": "5540", + "combat_audio": "436,439,438", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "5541", + "slayer_exp": "25", + "death_animation": "5542", + "name": "Ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "25", + "strength_level": "1", + "id": "6094", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "5532", + "combat_audio": "436,439,438", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "5533", + "slayer_exp": "25", + "death_animation": "5534", + "name": "Ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "25", + "strength_level": "1", + "id": "6095", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "5532", + "combat_audio": "436,439,438", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "5533", + "slayer_exp": "25", + "death_animation": "5534", + "name": "Ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "25", + "strength_level": "1", + "id": "6096", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "5532", + "combat_audio": "436,439,438", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "5533", + "slayer_exp": "25", + "death_animation": "5534", + "name": "Ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "25", + "strength_level": "1", + "id": "6097", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "5532", + "combat_audio": "436,439,438", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "5533", + "slayer_exp": "25", + "death_animation": "5534", + "name": "Ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "25", + "strength_level": "1", + "id": "6098", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "5571", + "combat_audio": "931,923,922", + "respawn_delay": "60", + "defence_animation": "5574", + "slayer_exp": "30", + "death_animation": "5575", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "30", + "strength_level": "1", + "id": "6099", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "5571", + "combat_audio": "931,923,922", + "respawn_delay": "60", + "defence_animation": "5574", + "slayer_exp": "30", + "death_animation": "5575", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "30", + "strength_level": "1", + "id": "6100", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Lesser, but still pretty big.", + "melee_animation": "4630", + "range_animation": "4630", + "combat_audio": "400,404,403", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "30", + "defence_animation": "65", + "weakness": "4", + "slayer_exp": "79", + "magic_animation": "4630", + "death_animation": "67", + "name": "Lesser demon", + "defence_level": "71", + "safespot": null, + "lifepoints": "79", + "strength_level": "70", + "id": "6101", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,-10,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "68" + }, + { + "examine": "His face is expressionless.", + "melee_animation": "422", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "836", + "name": "Lost barbarian", + "defence_level": "60", + "safespot": null, + "lifepoints": "85", + "strength_level": "60", + "id": "6102", + "range_level": "1", + "attack_level": "60" + }, + { + "examine": "Probably not a chicken.", + "melee_animation": "6811", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "1", + "magic_animation": "0", + "death_animation": "6812", + "name": "Entrana firebird", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "1", + "id": "6108", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "These gnomes know how to get around!", + "melee_animation": "6790", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "6791", + "name": "Mounted terrorbird gnome", + "defence_level": "38", + "safespot": null, + "lifepoints": "54", + "strength_level": "38", + "id": "6109", + "range_level": "1", + "attack_level": "38" + }, + { + "examine": "These gnomes know how to get around!", + "melee_animation": "6790", + "respawn_delay": "60", + "defence_animation": "6792", + "death_animation": "6791", + "name": "Mounted terrorbird gnome", + "defence_level": "1", + "safespot": null, + "lifepoints": "55", + "strength_level": "1", + "id": "6110", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "These gnomes know how to get around!", + "melee_animation": "6790", + "respawn_delay": "60", + "defence_animation": "6792", + "death_animation": "6791", + "name": "Mounted terrorbird gnome", + "defence_level": "1", + "safespot": null, + "lifepoints": "55", + "strength_level": "1", + "id": "6111", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Aww, cute.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ducklings", + "defence_level": "1", + "water_npc": "true", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6112", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Quackers.", + "melee_animation": "747", + "respawn_delay": "60", + "defence_animation": "3268", + "death_animation": "750", + "name": "Duck", + "defence_level": "1", + "safespot": null, + "lifepoints": "3", + "strength_level": "1", + "id": "6113", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A messy bird.", + "melee_animation": "3467", + "range_animation": "3467", + "combat_audio": "309,311,310", + "attack_speed": "5", + "defence_animation": "1014", + "weakness": "6", + "magic_animation": "3467", + "death_animation": "3468", + "name": "Seagull", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "1", + "id": "6115", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A messy bird.", + "melee_animation": "3467", + "range_animation": "3467", + "combat_audio": "309,311,310", + "attack_speed": "5", + "defence_animation": "1014", + "magic_animation": "3467", + "death_animation": "3468", + "name": "Seagull", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "1", + "id": "6116", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Do not upset this teacher. You have been warned!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Mr. Mordaut", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6117", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He helps the professor.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Observatory assistant", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6118", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Sleeping like an ugly baby.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Sleeping guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6122", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An old goblin hag.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Naghead", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6123", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A young goblin 'beauty'.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Wagchin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6124", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6125", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6126", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Big appetite for a small creature.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Greasycheeks", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6127", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Likes drink a little too much.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Smellytoes", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6128", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Lean and green.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Creakyknees", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6129", + "range_level": "1", + "attack_level": "1" + }, + { + "slayer_exp": "30", + "name": "Zombie", + "defence_level": "1", + "safespot": null, + "lifepoints": "40", + "combat_audio": "931,923,922", + "strength_level": "1", + "id": "6131", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6132", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6133", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "This imp is clearly the class clown.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Dunce", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6134", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Get useful information from this guy.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Town crier", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6135", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A squire of balance.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Squire (Intermediate)", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6140", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A squire of balance.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Squire (Veteran)", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6141", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Not somewhere I want to go...", + "attack_speed": "5", + "magic_level": "50", + "respawn_delay": "125", + "name": "Portal", + "defence_level": "50", + "safespot": null, + "lifepoints": "200", + "strength_level": "1", + "id": "6142", + "bonuses": "100,100,100,50,50,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Not somewhere I want to go...", + "attack_speed": "5", + "magic_level": "25", + "respawn_delay": "125", + "name": "Portal", + "defence_level": "50", + "safespot": null, + "lifepoints": "200", + "strength_level": "1", + "id": "6143", + "bonuses": "100,100,100,100,25,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Not somewhere I want to go...", + "attack_speed": "5", + "magic_level": "50", + "respawn_delay": "125", + "name": "Portal", + "defence_level": "50", + "safespot": null, + "lifepoints": "200", + "strength_level": "1", + "id": "6144", + "bonuses": "100,100,50,100,50,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Not somewhere I want to go...", + "attack_speed": "5", + "magic_level": "50", + "respawn_delay": "125", + "name": "Portal", + "defence_level": "50", + "safespot": null, + "lifepoints": "200", + "strength_level": "1", + "id": "6145", + "bonuses": "50,50,100,100,50,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The Void Knight will soon weaken the shield.", + "attack_speed": "5", + "magic_level": "30", + "respawn_delay": "125", + "name": "Portal", + "defence_level": "30", + "safespot": null, + "lifepoints": "200", + "strength_level": "1", + "id": "6146", + "bonuses": "100,100,100,50,50,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The Void Knight will soon weaken the shield.", + "attack_speed": "5", + "magic_level": "15", + "respawn_delay": "125", + "name": "Portal", + "defence_level": "30", + "safespot": null, + "lifepoints": "200", + "strength_level": "1", + "id": "6147", + "bonuses": "100,100,100,100,25,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The Void Knight will soon weaken the shield.", + "attack_speed": "5", + "magic_level": "30", + "respawn_delay": "125", + "name": "Portal", + "defence_level": "30", + "safespot": null, + "lifepoints": "200", + "strength_level": "1", + "id": "6148", + "bonuses": "100,100,50,100,50,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The Void Knight will soon weaken the shield.", + "attack_speed": "5", + "magic_level": "30", + "respawn_delay": "125", + "name": "Portal", + "defence_level": "30", + "safespot": null, + "lifepoints": "200", + "strength_level": "1", + "id": "6149", + "bonuses": "50,50,100,100,50,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Not somewhere I want to go...", + "attack_speed": "5", + "magic_level": "70", + "respawn_delay": "125", + "name": "Portal", + "defence_level": "70", + "safespot": null, + "lifepoints": "250", + "strength_level": "1", + "id": "6150", + "bonuses": "150,150,150,75,75,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Not somewhere I want to go...", + "attack_speed": "5", + "magic_level": "40", + "respawn_delay": "125", + "name": "Portal", + "defence_level": "70", + "safespot": null, + "lifepoints": "250", + "strength_level": "1", + "id": "6151", + "bonuses": "150,150,150,150,37,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Not somewhere I want to go...", + "attack_speed": "5", + "magic_level": "70", + "respawn_delay": "125", + "name": "Portal", + "defence_level": "70", + "safespot": null, + "lifepoints": "250", + "strength_level": "1", + "id": "6152", + "bonuses": "150,150,75,150,75,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Not somewhere I want to go...", + "attack_speed": "5", + "magic_level": "70", + "respawn_delay": "125", + "name": "Portal", + "defence_level": "70", + "safespot": null, + "lifepoints": "250", + "strength_level": "1", + "id": "6153", + "bonuses": "75,75,150,150,75,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The Void Knight will soon weaken the shield.", + "attack_speed": "5", + "magic_level": "30", + "respawn_delay": "125", + "name": "Portal", + "defence_level": "30", + "safespot": null, + "lifepoints": "250", + "strength_level": "1", + "id": "6154", + "bonuses": "100,100,100,50,50,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The Void Knight will soon weaken the shield.", + "attack_speed": "5", + "magic_level": "15", + "respawn_delay": "125", + "name": "Portal", + "defence_level": "30", + "safespot": null, + "lifepoints": "250", + "strength_level": "1", + "id": "6155", + "bonuses": "100,100,100,100,25,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The Void Knight will soon weaken the shield.", + "attack_speed": "5", + "magic_level": "30", + "respawn_delay": "125", + "name": "Portal", + "defence_level": "30", + "safespot": null, + "lifepoints": "250", + "strength_level": "1", + "id": "6156", + "bonuses": "100,100,50,100,50,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The Void Knight will soon weaken the shield.", + "attack_speed": "5", + "magic_level": "30", + "respawn_delay": "125", + "name": "Portal", + "defence_level": "30", + "safespot": null, + "lifepoints": "250", + "strength_level": "1", + "id": "6157", + "bonuses": "50,50,100,100,50,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It is cold and solid. Thok will strap it to Marmaros's leg.", + "range_animation": "0", + "magic_level": "50", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "name": "Workman", + "defence_level": "65", + "safespot": null, + "lifepoints": "114", + "strength_level": "50", + "id": "6159", + "aggressive": "true", + "range_level": "50", + "attack_level": "50" + }, + { + "examine": "Squire to the Knights of the Round Table.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Squire", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6169", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "400", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "422", + "death_animation": "836", + "name": "Sir Lancelot", + "defence_level": "1", + "safespot": null, + "lifepoints": "118", + "strength_level": "1", + "id": "6170", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An officer of the law.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6183", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An officer of the law.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6184", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He isn't very friendly.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "0", + "name": "Renegade knight", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6188", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A dark-hearted knight.", + "melee_animation": "390", + "range_animation": "0", + "combat_audio": "2503,15,512", + "attack_speed": "5", + "respawn_delay": "25", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "836", + "name": "Black Knight", + "defence_level": "25", + "safespot": null, + "lifepoints": "42", + "strength_level": "25", + "id": "6189", + "aggressive": "true", + "bonuses": "18,18,18,0,0,73,76,70,-11,72,0,16,0,0,0", + "range_level": "1", + "attack_level": "25" + }, + { + "examine": "Primping with combs and hair clips.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6190", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The name isn't just for show.", + "range_animation": "0", + "magic_level": "55", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "name": "Sinclair", + "defence_level": "55", + "safespot": null, + "lifepoints": "85", + "strength_level": "55", + "id": "6198", + "aggressive": "true", + "range_level": "55", + "attack_level": "55" + }, + { + "examine": "He can look after my money.", + "name": "Banker", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6200", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Knight", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "6201", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A servant of the god Zamorak. ", + "melee_animation": "6945", + "attack_speed": "6", + "poisonous": "true", + "respawn_delay": "150", + "weakness": "9", + "slayer_exp": "350", + "poison_amount": "16", + "magic_animation": "6945", + "death_animation": "6946", + "lifepoints": "255", + "id": "6203", + "aggressive": "true", + "bonuses": "160,160,160,0,0,80,80,80,130,80,0,31,0,0,0", + "agg_radius": "64", + "range_animation": "6945", + "magic_level": "200", + "defence_animation": "6944", + "name": "K'ril Tsutsaroth", + "defence_level": "270", + "poison_immune": "true", + "safespot": null, + "strength_level": "300", + "clue_level": "2", + "range_level": "1", + "attack_level": "340" + }, + { + "agg_radius": "64", + "examine": "Destroyer of 1000 planes!", + "melee_animation": "6945", + "range_animation": "6945", + "attack_speed": "5", + "magic_level": "50", + "respawn_delay": "50", + "defence_animation": "6944", + "weakness": "9", + "slayer_exp": "142", + "magic_animation": "6945", + "death_animation": "6946", + "name": "Tstanon Karlak", + "defence_level": "125", + "safespot": null, + "lifepoints": "142", + "strength_level": "118", + "id": "6204", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,-5,0,0,14,0,0,0", + "range_level": "50", + "attack_level": "124" + }, + { + "name": "", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "6205", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Scourge of light.", + "start_gfx": "1208", + "combat_style": "1", + "melee_animation": "7033", + "attack_speed": "5", + "respawn_delay": "50", + "weakness": "0", + "slayer_exp": "150", + "magic_animation": "7033", + "death_animation": "6946", + "lifepoints": "150", + "id": "6206", + "aggressive": "true", + "bonuses": "0,0,0,0,20,0,0,0,-5,0,0,0,0,0,20", + "agg_radius": "64", + "range_animation": "7033", + "magic_level": "50", + "defence_animation": "6945", + "name": "Zakl'n Gritch", + "defence_level": "127", + "safespot": null, + "strength_level": "76", + "range_level": "150", + "projectile": "1209", + "attack_level": "83" + }, + { + "name": "", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "6207", + "range_level": "1", + "attack_level": "1" + }, + { + "agg_radius": "64", + "examine": "Despoiler of Ullek.", + "start_gfx": "1212", + "combat_style": "2", + "melee_animation": "7033", + "range_animation": "7033", + "attack_speed": "5", + "magic_level": "150", + "respawn_delay": "50", + "defence_animation": "6944", + "slayer_exp": "161", + "magic_animation": "7033", + "death_animation": "6946", + "name": "Balfrug Kreeyath", + "defence_level": "153", + "safespot": null, + "lifepoints": "161", + "strength_level": "60", + "id": "6208", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,10,0,0,0,0,0,0", + "range_level": "1", + "projectile": "1213", + "attack_level": "115" + }, + { + "name": "", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "6209", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "From the maws of hell.", + "melee_animation": "6579", + "range_animation": "6579", + "combat_audio": "3717,3719,3718", + "attack_speed": "4", + "respawn_delay": "50", + "defence_animation": "6578", + "weakness": "7", + "slayer_exp": "116", + "magic_animation": "6579", + "death_animation": "6576", + "name": "Hellhound", + "defence_level": "102", + "safespot": null, + "lifepoints": "116", + "strength_level": "104", + "id": "6210", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "105" + }, + { + "examine": "Have you checked your pockets lately?", + "melee_animation": "169", + "range_animation": "169", + "combat_audio": "534,536,535", + "defence_animation": "170", + "weakness": "7", + "magic_animation": "169", + "death_animation": "172", + "name": "Imp", + "defence_level": "4", + "safespot": null, + "movement_radius": "25", + "lifepoints": "10", + "strength_level": "4", + "id": "6211", + "aggressive": "true", + "bonuses": "10,5,5,10,10,10,10,10,10,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "4" + }, + { + "examine": "He doesn't look pleased to see me.", + "melee_animation": "6536", + "range_animation": "6536", + "respawn_delay": "25", + "defence_animation": "6538", + "weakness": "7", + "magic_animation": "6536", + "death_animation": "6537", + "name": "Werewolf", + "defence_level": "64", + "safespot": null, + "lifepoints": "100", + "strength_level": "64", + "id": "6212", + "aggressive": "true", + "bonuses": "50,40,45,60,70,70,70,40,40,50,0,0,0,0,0", + "clue_level": "1", + "range_level": "1", + "attack_level": "64" + }, + { + "examine": "He doesn't look pleased to see me.", + "melee_animation": "6536", + "range_animation": "6536", + "respawn_delay": "25", + "defence_animation": "6538", + "weakness": "7", + "magic_animation": "6536", + "death_animation": "6537", + "name": "Werewolf", + "defence_level": "64", + "safespot": null, + "lifepoints": "100", + "strength_level": "64", + "id": "6213", + "aggressive": "true", + "bonuses": "50,40,45,60,70,70,70,40,40,50,0,0,0,0,0", + "clue_level": "1", + "range_level": "1", + "attack_level": "64" + }, + { + "examine": "It looks really hungry!", + "melee_animation": "810", + "range_animation": "810", + "respawn_delay": "25", + "defence_animation": "404", + "magic_animation": "810", + "death_animation": "9055", + "name": "Vampire", + "defence_level": "44", + "safespot": null, + "lifepoints": "60", + "strength_level": "44", + "id": "6214", + "aggressive": "true", + "bonuses": "30,35,30,40,50,50,50,25,30,30,0,0,0,0,0", + "clue_level": "1", + "range_level": "1", + "attack_level": "44" + }, + { + "examine": "The tongue of evil.", + "melee_animation": "9130", + "range_animation": "1552", + "combat_audio": "312,314,313", + "attack_speed": "4", + "respawn_delay": "60", + "defence_animation": "9132", + "slayer_exp": "120", + "magic_animation": "1552", + "death_animation": "9131", + "name": "Bloodveld", + "defence_level": "30", + "safespot": null, + "lifepoints": "120", + "strength_level": "45", + "id": "6215", + "aggressive": "true", + "clue_level": "2", + "range_level": "1", + "attack_level": "75" + }, + { + "examine": "A small fire demon.", + "melee_animation": "1582", + "range_animation": "1582", + "combat_audio": "696,698,697", + "respawn_delay": "25", + "defence_animation": "1581", + "weakness": "7", + "magic_animation": "1582", + "death_animation": "1580", + "name": "Pyrefiend", + "defence_level": "25", + "safespot": null, + "lifepoints": "48", + "strength_level": "25", + "id": "6216", + "aggressive": "true", + "bonuses": "25,25,20,40,40,40,15,30,20,60,20,0,0,0,0", + "clue_level": "1", + "range_level": "1", + "attack_level": "25" + }, + { + "examine": "A small ice demon.", + "melee_animation": "8080", + "range_animation": "8080", + "combat_audio": "531,533,532", + "respawn_delay": "25", + "defence_animation": "8079", + "magic_animation": "8080", + "death_animation": "8078", + "name": "Icefiend", + "defence_level": "5", + "safespot": null, + "lifepoints": "15", + "strength_level": "5", + "id": "6217", + "bonuses": "5,5,5,5,10,10,10,10,10,10,5,0,0,0,0", + "clue_level": "0", + "range_level": "1", + "attack_level": "5" + }, + { + "examine": "Those horns look pretty sharp...", + "melee_animation": "4300", + "range_animation": "4300", + "respawn_delay": "25", + "defence_animation": "4301", + "weakness": "9", + "slayer_exp": "112", + "magic_animation": "4300", + "death_animation": "4302", + "name": "Gorak", + "defence_level": "70", + "safespot": null, + "lifepoints": "112", + "strength_level": "70", + "id": "6218", + "aggressive": "true", + "bonuses": "30,30,50,70,40,70,70,50,60,55,0,0,0,0,0", + "range_level": "1", + "attack_level": "70" + }, + { + "examine": "Warrior of Zamorak.", + "melee_animation": "390", + "range_animation": "390", + "attack_speed": "5", + "respawn_delay": "25", + "defence_animation": "1156", + "weakness": "6", + "magic_animation": "390", + "death_animation": "9055", + "name": "Spiritual warrior", + "defence_level": "66", + "safespot": null, + "lifepoints": "102", + "strength_level": "66", + "id": "6219", + "aggressive": "true", + "bonuses": "40,60,60,60,60,20,50,55,0,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "66" + }, + { + "examine": "A ranger spirit dedicated to Zamorak.", + "start_gfx": "18", + "combat_style": "1", + "start_height": "96", + "melee_animation": "426", + "range_animation": "426", + "respawn_delay": "25", + "defence_animation": "404", + "weakness": "1", + "magic_animation": "426", + "death_animation": "9055", + "name": "Spiritual ranger", + "defence_level": "70", + "safespot": null, + "lifepoints": "120", + "strength_level": "1", + "id": "6220", + "aggressive": "true", + "bonuses": "50,70,50,50,50,70,50,85,85,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "70", + "projectile": "9", + "attack_level": "1" + }, + { + "examine": "A deadly servant of Zamorak.", + "combat_style": "2", + "melee_animation": "811", + "attack_speed": "5", + "respawn_delay": "25", + "weakness": "3", + "magic_animation": "811", + "death_animation": "9055", + "lifepoints": "75", + "id": "6221", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_animation": "811", + "magic_level": "180", + "end_gfx": "78", + "defence_animation": "404", + "end_height": "0", + "name": "Spiritual mage", + "defence_level": "61", + "safespot": null, + "strength_level": "1", + "clue_level": "2", + "range_level": "1", + "projectile": "78", + "attack_level": "1" + }, + { + "agg_radius": "64", + "examine": "Graceful avatar of Armadyl.", + "melee_animation": "6977", + "range_animation": "6977", + "attack_speed": "3", + "magic_level": "200", + "respawn_delay": "150", + "defence_animation": "6974", + "weakness": "10", + "slayer_exp": "357", + "magic_animation": "6977", + "death_animation": "6975", + "name": "Kree'arra", + "defence_level": "260", + "poison_immune": "true", + "safespot": null, + "lifepoints": "255", + "strength_level": "200", + "id": "6222", + "aggressive": "true", + "bonuses": "136,136,136,0,120,180,180,180,200,200,0,12,0,0,0", + "clue_level": "2", + "range_level": "380", + "attack_level": "300" + }, + { + "examine": "Graceful, bird-like creature.", + "combat_style": "2", + "melee_animation": "6952", + "attack_speed": "5", + "respawn_delay": "50", + "weakness": "3", + "slayer_exp": "124", + "magic_animation": "6952", + "death_animation": "6956", + "lifepoints": "121", + "id": "6223", + "aggressive": "true", + "bonuses": "45,45,45,0,0,0,0,0,0,0,0,25,0,0,0", + "prj_height": "92", + "agg_radius": "64", + "range_animation": "6952", + "magic_level": "150", + "defence_animation": "6955", + "name": "Wingman Skree", + "defence_level": "160", + "poison_immune": "false", + "safespot": null, + "strength_level": "50", + "range_level": "100", + "projectile": "1199", + "attack_level": "80" + }, + { + "name": "", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "6224", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Graceful, bird-like creature.", + "combat_style": "1", + "melee_animation": "6953", + "attack_speed": "5", + "respawn_delay": "50", + "weakness": "4", + "slayer_exp": "133", + "magic_animation": "6953", + "death_animation": "6956", + "lifepoints": "132", + "id": "6225", + "aggressive": "true", + "bonuses": "0,0,0,0,60,0,0,0,0,0,0,0,0,0,0", + "prj_height": "92", + "agg_radius": "64", + "range_animation": "6953", + "magic_level": "50", + "defence_animation": "6955", + "name": "Flockleader Geerin", + "defence_level": "175", + "poison_immune": "false", + "safespot": null, + "strength_level": "80", + "range_level": "150", + "projectile": "1190", + "attack_level": "80" + }, + { + "name": "", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "6226", + "range_level": "1", + "attack_level": "1" + }, + { + "agg_radius": "64", + "examine": "Graceful, bird-like creature.", + "melee_animation": "6954", + "range_animation": "6954", + "attack_speed": "5", + "magic_level": "50", + "respawn_delay": "50", + "defence_animation": "6955", + "weakness": "6", + "slayer_exp": "133", + "magic_animation": "6954", + "death_animation": "6956", + "name": "Flight Kilisa", + "defence_level": "175", + "safespot": null, + "lifepoints": "133", + "strength_level": "118", + "id": "6227", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,14,0,0,0", + "range_level": "169", + "attack_level": "124" + }, + { + "name": "", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "6228", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A servant of Armadyl.", + "combat_style": "1", + "melee_animation": "6954", + "range_animation": "6954", + "respawn_delay": "25", + "defence_animation": "6955", + "weakness": "6", + "magic_animation": "6954", + "death_animation": "6956", + "name": "Spiritual warrior", + "defence_level": "70", + "safespot": null, + "lifepoints": "98", + "strength_level": "70", + "id": "6229", + "aggressive": "true", + "bonuses": "40,40,50,50,20,50,50,0,0,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "68", + "attack_level": "70" + }, + { + "examine": "Armadyl's favourite servant.", + "combat_style": "1", + "melee_animation": "6953", + "range_animation": "6953", + "respawn_delay": "25", + "defence_animation": "6955", + "weakness": "4", + "magic_animation": "6953", + "death_animation": "6956", + "name": "Spiritual ranger", + "defence_level": "70", + "safespot": null, + "lifepoints": "89", + "strength_level": "1", + "id": "6230", + "aggressive": "true", + "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "70", + "projectile": "1190", + "attack_level": "1", + "prj_height": "92" + }, + { + "examine": "A mage who serves Armadyl above all else - even death.", + "combat_style": "2", + "melee_animation": "6952", + "range_animation": "6952", + "attack_speed": "5", + "magic_level": "150", + "respawn_delay": "25", + "defence_animation": "6955", + "weakness": "4", + "magic_animation": "6952", + "death_animation": "6956", + "name": "Spiritual mage", + "defence_level": "111", + "safespot": null, + "lifepoints": "75", + "strength_level": "1", + "id": "6231", + "aggressive": "true", + "bonuses": "0,0,0,0,0,9,12,5,45,28,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "projectile": "1199", + "prj_height": "92", + "attack_level": "1" + }, + { + "examine": "Graceful, bird-like creature.", + "combat_style": "1", + "melee_animation": "6953", + "range_animation": "6953", + "respawn_delay": "25", + "defence_animation": "6955", + "magic_animation": "6953", + "death_animation": "6956", + "name": "Aviansie", + "defence_level": "40", + "safespot": null, + "lifepoints": "70", + "strength_level": "1", + "id": "6232", + "aggressive": "true", + "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "40", + "projectile": "1191", + "attack_level": "1", + "prj_height": "92" + }, + { + "examine": "Graceful, bird-like creature.", + "combat_style": "1", + "melee_animation": "6953", + "range_animation": "6953", + "respawn_delay": "25", + "defence_animation": "6955", + "magic_animation": "6953", + "death_animation": "6956", + "name": "Aviansie", + "defence_level": "45", + "safespot": null, + "lifepoints": "83", + "strength_level": "1", + "id": "6233", + "aggressive": "true", + "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "45", + "projectile": "1190", + "attack_level": "1", + "prj_height": "92" + }, + { + "examine": "Graceful, bird-like creature.", + "combat_style": "1", + "melee_animation": "6953", + "range_animation": "6953", + "respawn_delay": "25", + "defence_animation": "6955", + "magic_animation": "6953", + "death_animation": "6956", + "name": "Aviansie", + "defence_level": "50", + "safespot": null, + "lifepoints": "86", + "strength_level": "1", + "id": "6234", + "aggressive": "true", + "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "50", + "projectile": "1190", + "attack_level": "1", + "prj_height": "92" + }, + { + "examine": "Graceful, bird-like creature.", + "combat_style": "1", + "melee_animation": "6953", + "range_animation": "6953", + "respawn_delay": "25", + "defence_animation": "6955", + "magic_animation": "6953", + "death_animation": "6956", + "name": "Aviansie", + "defence_level": "50", + "safespot": null, + "lifepoints": "86", + "strength_level": "1", + "id": "6235", + "aggressive": "true", + "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "50", + "projectile": "1190", + "attack_level": "1", + "prj_height": "92" + }, + { + "examine": "Graceful, bird-like creature.", + "combat_style": "1", + "melee_animation": "6953", + "range_animation": "6953", + "respawn_delay": "25", + "defence_animation": "6955", + "magic_animation": "6953", + "death_animation": "6956", + "name": "Aviansie", + "defence_level": "55", + "safespot": null, + "lifepoints": "95", + "strength_level": "1", + "id": "6236", + "aggressive": "true", + "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "55", + "projectile": "1190", + "attack_level": "1", + "prj_height": "92" + }, + { + "examine": "Graceful, bird-like creature.", + "combat_style": "1", + "melee_animation": "6953", + "range_animation": "6953", + "respawn_delay": "25", + "defence_animation": "6955", + "magic_animation": "6953", + "death_animation": "6956", + "name": "Aviansie", + "defence_level": "55", + "safespot": null, + "lifepoints": "98", + "strength_level": "1", + "id": "6237", + "aggressive": "true", + "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "55", + "projectile": "1191", + "attack_level": "1", + "prj_height": "92" + }, + { + "examine": "Graceful, bird-like creature.", + "combat_style": "1", + "melee_animation": "6953", + "range_animation": "6953", + "respawn_delay": "25", + "defence_animation": "6955", + "magic_animation": "6953", + "death_animation": "6956", + "name": "Aviansie", + "defence_level": "65", + "safespot": null, + "lifepoints": "124", + "strength_level": "1", + "id": "6238", + "aggressive": "true", + "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "65", + "projectile": "1190", + "attack_level": "1", + "prj_height": "92" + }, + { + "examine": "Graceful, bird-like creature.", + "combat_style": "1", + "melee_animation": "6953", + "range_animation": "6953", + "respawn_delay": "25", + "defence_animation": "6955", + "magic_animation": "6953", + "death_animation": "6956", + "name": "Aviansie", + "defence_level": "65", + "safespot": null, + "lifepoints": "139", + "strength_level": "1", + "id": "6239", + "aggressive": "true", + "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "65", + "projectile": "1191", + "attack_level": "1", + "prj_height": "92" + }, + { + "examine": "Graceful, bird-like creature.", + "combat_style": "1", + "melee_animation": "6953", + "range_animation": "6953", + "respawn_delay": "25", + "defence_animation": "6955", + "magic_animation": "6953", + "death_animation": "6956", + "name": "Aviansie", + "defence_level": "40", + "safespot": null, + "lifepoints": "63", + "strength_level": "1", + "id": "6240", + "aggressive": "true", + "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "40", + "projectile": "1191", + "attack_level": "1", + "prj_height": "92" + }, + { + "examine": "Graceful, bird-like creature.", + "combat_style": "1", + "melee_animation": "6953", + "range_animation": "6953", + "respawn_delay": "25", + "defence_animation": "6955", + "magic_animation": "6953", + "death_animation": "6956", + "name": "Aviansie", + "defence_level": "40", + "safespot": null, + "lifepoints": "65", + "strength_level": "1", + "id": "6241", + "aggressive": "true", + "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "40", + "projectile": "1190", + "attack_level": "1", + "prj_height": "92" + }, + { + "examine": "Graceful, bird-like creature.", + "combat_style": "1", + "melee_animation": "6953", + "range_animation": "6953", + "respawn_delay": "25", + "defence_animation": "6955", + "magic_animation": "6953", + "death_animation": "6956", + "name": "Aviansie", + "defence_level": "40", + "safespot": null, + "lifepoints": "83", + "strength_level": "1", + "id": "6242", + "aggressive": "true", + "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "40", + "projectile": "1190", + "attack_level": "1", + "prj_height": "92" + }, + { + "examine": "Graceful, bird-like creature.", + "combat_style": "1", + "melee_animation": "6953", + "range_animation": "6953", + "respawn_delay": "25", + "defence_animation": "6955", + "magic_animation": "6953", + "death_animation": "6956", + "name": "Aviansie", + "defence_level": "50", + "safespot": null, + "lifepoints": "69", + "strength_level": "1", + "id": "6243", + "aggressive": "true", + "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "50", + "projectile": "1190", + "attack_level": "1", + "prj_height": "92" + }, + { + "examine": "Graceful, bird-like creature.", + "combat_style": "1", + "melee_animation": "6953", + "range_animation": "6953", + "respawn_delay": "25", + "defence_animation": "6955", + "magic_animation": "6953", + "death_animation": "6956", + "name": "Aviansie", + "defence_level": "55", + "safespot": null, + "lifepoints": "75", + "strength_level": "1", + "id": "6244", + "aggressive": "true", + "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "55", + "projectile": "1190", + "attack_level": "1", + "prj_height": "92" + }, + { + "examine": "Graceful, bird-like creature.", + "combat_style": "1", + "melee_animation": "6953", + "range_animation": "6953", + "respawn_delay": "25", + "defence_animation": "6955", + "magic_animation": "6953", + "death_animation": "6956", + "name": "Aviansie", + "defence_level": "55", + "safespot": null, + "lifepoints": "98", + "strength_level": "1", + "id": "6245", + "aggressive": "true", + "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "55", + "projectile": "1190", + "attack_level": "1", + "prj_height": "92" + }, + { + "examine": "Graceful, bird-like creature.", + "combat_style": "1", + "melee_animation": "6953", + "range_animation": "6953", + "respawn_delay": "25", + "defence_animation": "6955", + "magic_animation": "6953", + "death_animation": "6956", + "name": "Aviansie", + "defence_level": "65", + "safespot": null, + "lifepoints": "73", + "strength_level": "1", + "id": "6246", + "aggressive": "true", + "bonuses": "60,50,60,50,65,65,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "65", + "projectile": "1191", + "attack_level": "1", + "prj_height": "92" + }, + { + "agg_radius": "64", + "examine": "Commander of Saradomin's forces. ", + "melee_animation": "6964", + "range_animation": "6964", + "attack_speed": "2", + "magic_level": "300", + "respawn_delay": "150", + "defence_animation": "6966", + "weakness": "7", + "slayer_exp": "360", + "magic_animation": "6964", + "death_animation": "6965", + "name": "Commander Zilyana", + "defence_level": "300", + "poison_immune": "true", + "safespot": null, + "lifepoints": "255", + "strength_level": "196", + "id": "6247", + "aggressive": "true", + "bonuses": "195,195,195,200,0,100,100,100,100,100,0,20,0,0,0", + "clue_level": "2", + "range_level": "250", + "attack_level": "280" + }, + { + "agg_radius": "64", + "examine": "The bane of darkness.", + "melee_animation": "6376", + "range_animation": "6376", + "combat_audio": "3829,3866,3849", + "attack_speed": "5", + "magic_level": "125", + "respawn_delay": "50", + "defence_animation": "6375", + "weakness": "7", + "slayer_exp": "0", + "magic_animation": "6376", + "death_animation": "6377", + "name": "Starlight", + "defence_level": "120", + "poison_immune": "false", + "safespot": null, + "lifepoints": "160", + "strength_level": "125", + "id": "6248", + "aggressive": "true", + "bonuses": "60,60,60,0,0,12,14,13,5,13,0,10,0,0,0", + "range_level": "1", + "attack_level": "120" + }, + { + "name": "", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "6249", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Defender of the faithful.", + "start_gfx": "1184", + "combat_style": "2", + "melee_animation": "7019", + "attack_speed": "5", + "respawn_delay": "50", + "slayer_exp": "0", + "magic_animation": "7019", + "death_animation": "7016", + "lifepoints": "146", + "id": "6250", + "aggressive": "true", + "bonuses": "10,10,10,0,0,12,14,14,18,5,0,7,0,0,0", + "prj_height": "0", + "agg_radius": "64", + "range_animation": "7019", + "combat_audio": "3830,3869,3867", + "magic_level": "150", + "end_gfx": "1186", + "defence_animation": "7017", + "name": "Growler", + "defence_level": "120", + "safespot": null, + "strength_level": "101", + "range_level": "1", + "projectile": "1185", + "attack_level": "100" + }, + { + "name": "", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "6251", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Champion of Truth.", + "combat_style": "1", + "melee_animation": "7009", + "attack_speed": "5", + "respawn_delay": "50", + "weakness": "0", + "slayer_exp": "0", + "magic_animation": "7009", + "death_animation": "7011", + "lifepoints": "162", + "id": "6252", + "aggressive": "true", + "bonuses": "10,10,10,0,0,12,14,14,18,5,0,7,0,0,0", + "prj_height": "50", + "agg_radius": "64", + "range_animation": "7009", + "magic_level": "80", + "end_gfx": "24", + "defence_animation": "7010", + "name": "Bree", + "defence_level": "130", + "safespot": null, + "strength_level": "80", + "range_level": "150", + "projectile": "1188", + "attack_level": "110" + }, + { + "name": "", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "6253", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A holy man wearing ancient clothing.", + "combat_style": "2", + "melee_animation": "811", + "range_animation": "811", + "poisonous": "true", + "magic_level": "60", + "respawn_delay": "25", + "end_gfx": "76", + "defence_animation": "404", + "weakness": "3", + "magic_animation": "811", + "death_animation": "9055", + "name": "Saradomin priest", + "defence_level": "60", + "safespot": null, + "lifepoints": "89", + "strength_level": "1", + "id": "6254", + "aggressive": "true", + "bonuses": "40,40,40,40,20,50,40,55,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Warrior of Saradomin.", + "melee_animation": "390", + "range_animation": "390", + "attack_speed": "5", + "respawn_delay": "25", + "defence_animation": "1156", + "weakness": "8", + "magic_animation": "390", + "death_animation": "9055", + "name": "Spiritual warrior", + "defence_level": "66", + "safespot": null, + "lifepoints": "100", + "strength_level": "66", + "id": "6255", + "aggressive": "true", + "bonuses": "40,60,60,60,60,20,50,45,0,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "66" + }, + { + "examine": "A ranger spirit dedicated to Saradomin.", + "start_gfx": "18", + "combat_style": "1", + "start_height": "96", + "melee_animation": "426", + "range_animation": "426", + "respawn_delay": "25", + "defence_animation": "404", + "weakness": "0", + "magic_animation": "426", + "death_animation": "9055", + "name": "Spiritual ranger", + "defence_level": "70", + "safespot": null, + "lifepoints": "106", + "strength_level": "1", + "id": "6256", + "aggressive": "true", + "bonuses": "50,70,50,50,50,70,50,65,65,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "70", + "projectile": "9", + "attack_level": "1" + }, + { + "examine": "Saradomin's holy mage.", + "combat_style": "2", + "melee_animation": "811", + "attack_speed": "5", + "respawn_delay": "25", + "weakness": "4", + "magic_animation": "811", + "death_animation": "9055", + "lifepoints": "85", + "id": "6257", + "aggressive": "true", + "bonuses": "0,0,0,0,0,8,7,3,16,2,0,0,0,0,0", + "range_animation": "811", + "magic_level": "160", + "end_gfx": "76", + "defence_animation": "404", + "end_height": "0", + "name": "Spiritual mage", + "defence_level": "86", + "safespot": null, + "strength_level": "1", + "clue_level": "2", + "range_level": "1", + "projectile": "76", + "attack_level": "1" + }, + { + "examine": "A valiant knight.", + "melee_animation": "407", + "range_animation": "407", + "respawn_delay": "25", + "defence_animation": "410", + "weakness": "7", + "magic_animation": "407", + "death_animation": "9055", + "name": "Knight of Saradomin", + "defence_level": "50", + "safespot": null, + "lifepoints": "135", + "strength_level": "50", + "id": "6258", + "aggressive": "true", + "bonuses": "40,40,40,40,50,20,40,50,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "50" + }, + { + "examine": "A valiant knight.", + "melee_animation": "401", + "range_animation": "401", + "respawn_delay": "25", + "defence_animation": "424", + "weakness": "7", + "magic_animation": "401", + "death_animation": "9055", + "name": "Knight of Saradomin", + "defence_level": "50", + "safespot": null, + "lifepoints": "108", + "strength_level": "50", + "id": "6259", + "aggressive": "true", + "bonuses": "40,40,40,40,50,20,40,65,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "50" + }, + { + "agg_radius": "64", + "examine": "A huge war chief.", + "melee_animation": "7060", + "range_animation": "7060", + "attack_speed": "6", + "magic_level": "280", + "respawn_delay": "150", + "defence_animation": "7061", + "weakness": "10", + "slayer_exp": "0", + "magic_animation": "7060", + "death_animation": "7062", + "name": "General Graardor", + "defence_level": "250", + "poison_immune": "true", + "safespot": null, + "lifepoints": "255", + "strength_level": "350", + "id": "6260", + "aggressive": "true", + "bonuses": "120,120,120,0,100,90,90,90,65,90,0,43,0,0,0", + "clue_level": "2", + "range_level": "350", + "attack_level": "280" + }, + { + "agg_radius": "64", + "examine": "A battle-honed goblin. ", + "melee_animation": "6154", + "range_animation": "6154", + "attack_speed": "5", + "magic_level": "50", + "respawn_delay": "50", + "defence_animation": "6155", + "weakness": "8", + "magic_animation": "6154", + "death_animation": "6156", + "name": "Sergeant Strongstack", + "defence_level": "126", + "safespot": null, + "lifepoints": "128", + "strength_level": "118", + "id": "6261", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,14,0,0,0", + "range_level": "50", + "attack_level": "124" + }, + { + "name": "", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "6262", + "range_level": "1", + "attack_level": "1" + }, + { + "agg_radius": "64", + "examine": "A battle-honed goblin. ", + "start_gfx": "1202", + "combat_style": "2", + "melee_animation": "6154", + "range_animation": "6154", + "attack_speed": "5", + "magic_level": "150", + "respawn_delay": "50", + "defence_animation": "6155", + "weakness": "3", + "magic_animation": "6154", + "death_animation": "6156", + "name": "Sergeant Steelwill", + "defence_level": "150", + "safespot": null, + "lifepoints": "127", + "strength_level": "50", + "id": "6263", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,6,0,0,0", + "range_level": "1", + "projectile": "1203", + "attack_level": "80" + }, + { + "name": "", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "6264", + "range_level": "1", + "attack_level": "1" + }, + { + "agg_radius": "64", + "examine": "A battle-honed goblin. ", + "combat_style": "1", + "melee_animation": "6154", + "range_animation": "6154", + "attack_speed": "5", + "magic_level": "50", + "respawn_delay": "50", + "defence_animation": "6155", + "weakness": "2", + "magic_animation": "6154", + "death_animation": "6156", + "name": "Sergeant Grimspike", + "defence_level": "132", + "safespot": null, + "lifepoints": "146", + "strength_level": "80", + "id": "6265", + "aggressive": "true", + "bonuses": "0,0,0,0,20,0,0,0,0,0,0,0,0,0,20", + "range_level": "150", + "projectile": "1206", + "attack_level": "80" + }, + { + "name": "", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "6266", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Big, ugly, and smelly.", + "melee_animation": "359", + "range_animation": "359", + "attack_speed": "6", + "magic_level": "27", + "respawn_delay": "25", + "defence_animation": "360", + "magic_animation": "359", + "death_animation": "361", + "name": "Fishing spot", + "defence_level": "27", + "safespot": null, + "lifepoints": "60", + "strength_level": "27", + "id": "6267", + "aggressive": "true", + "bonuses": "15,15,10,20,40,15,50,50,50,20,50,58,0,0,0", + "range_level": "27", + "attack_level": "27" + }, + { + "examine": "Green and aggressive.", + "melee_animation": "2936", + "range_animation": "2936", + "attack_speed": "6", + "respawn_delay": "25", + "defence_animation": "2937", + "weakness": "8", + "magic_animation": "2936", + "death_animation": "2938", + "name": "Jogre", + "defence_level": "62", + "safespot": null, + "lifepoints": "70", + "strength_level": "62", + "id": "6268", + "aggressive": "true", + "bonuses": "10,20,20,20,20,20,10,20,0,0,0,0,0,0,0", + "clue_level": "1", + "range_level": "1", + "attack_level": "62" + }, + { + "examine": "A one-eyed man-eater.", + "melee_animation": "4652", + "range_animation": "0", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "25", + "defence_animation": "4651", + "weakness": "8", + "slayer_exp": "110", + "magic_animation": "0", + "death_animation": "4653", + "name": "Cyclops", + "defence_level": "48", + "safespot": null, + "lifepoints": "110", + "strength_level": "70", + "id": "6269", + "aggressive": "true", + "bonuses": "22,22,22,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "60" + }, + { + "examine": "A one-eyed man-eater.", + "melee_animation": "4652", + "range_animation": "0", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "25", + "defence_animation": "4651", + "weakness": "8", + "slayer_exp": "110", + "magic_animation": "0", + "death_animation": "4653", + "name": "Cyclops", + "defence_level": "48", + "safespot": null, + "lifepoints": "110", + "strength_level": "70", + "id": "6270", + "aggressive": "true", + "bonuses": "22,22,22,0,0,0,0,0,0,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "60" + }, + { + "examine": "Ugly, fierce and with a bad attitude.", + "melee_animation": "4320", + "range_animation": "4320", + "respawn_delay": "25", + "defence_animation": "4322", + "weakness": "8", + "magic_animation": "4320", + "death_animation": "4321", + "name": "Ork", + "defence_level": "68", + "safespot": null, + "lifepoints": "110", + "strength_level": "68", + "id": "6271", + "aggressive": "true", + "bonuses": "40,20,30,45,45,45,45,20,45,35,0,0,0,0,0", + "range_level": "1", + "attack_level": "68" + }, + { + "examine": "Ugly, fierce and with a bad attitude.", + "melee_animation": "4320", + "range_animation": "4320", + "respawn_delay": "25", + "defence_animation": "4322", + "magic_animation": "4320", + "death_animation": "4321", + "name": "Ork", + "defence_level": "68", + "safespot": null, + "lifepoints": "110", + "strength_level": "68", + "id": "6272", + "aggressive": "true", + "bonuses": "40,20,30,45,45,45,45,20,45,35,0,0,0,0,0", + "range_level": "1", + "attack_level": "68" + }, + { + "examine": "Ugly, fierce and with a bad attitude.", + "melee_animation": "4320", + "range_animation": "4320", + "respawn_delay": "25", + "defence_animation": "4322", + "magic_animation": "4320", + "death_animation": "4321", + "name": "Ork", + "defence_level": "68", + "safespot": null, + "lifepoints": "110", + "strength_level": "68", + "id": "6273", + "aggressive": "true", + "bonuses": "40,20,30,45,45,45,45,20,45,35,0,0,0,0,0", + "range_level": "1", + "attack_level": "68" + }, + { + "examine": "Ugly, fierce and with a bad attitude.", + "melee_animation": "4320", + "range_animation": "4320", + "respawn_delay": "25", + "defence_animation": "4322", + "magic_animation": "4320", + "death_animation": "4321", + "name": "Ork", + "defence_level": "68", + "safespot": null, + "lifepoints": "110", + "strength_level": "68", + "id": "6274", + "aggressive": "true", + "bonuses": "40,20,30,45,45,45,45,20,45,35,0,0,0,0,0", + "range_level": "1", + "attack_level": "68" + }, + { + "examine": "An ugly, smelly creature.", + "melee_animation": "164", + "range_animation": "164", + "combat_audio": "469,472,471", + "respawn_delay": "25", + "defence_animation": "165", + "weakness": "8", + "magic_animation": "164", + "death_animation": "167", + "name": "Hobgoblin", + "defence_level": "40", + "safespot": null, + "lifepoints": "52", + "strength_level": "40", + "id": "6275", + "aggressive": "true", + "bonuses": "20,30,30,30,30,30,10,30,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "The spirit of a ranger, serving bandos beyond death.", + "start_gfx": "95", + "combat_style": "1", + "melee_animation": "4320", + "range_animation": "4320", + "respawn_delay": "25", + "defence_animation": "4322", + "weakness": "0", + "magic_animation": "4320", + "death_animation": "4321", + "name": "Spiritual ranger", + "defence_level": "70", + "safespot": null, + "lifepoints": "130", + "strength_level": "1", + "id": "6276", + "aggressive": "true", + "bonuses": "30,50,30,30,50,60,50,40,40,0,0,0,0,0,0", + "clue_level": "2", + "range_level": "70", + "projectile": "1195", + "attack_level": "1" + }, + { + "examine": "A true servant of Bandos.", + "melee_animation": "4320", + "range_animation": "4320", + "respawn_delay": "25", + "defence_animation": "4322", + "weakness": "8", + "magic_animation": "4320", + "death_animation": "4321", + "name": "Spiritual warrior", + "defence_level": "70", + "safespot": null, + "lifepoints": "131", + "strength_level": "70", + "id": "6277", + "aggressive": "true", + "bonuses": "50,40,45,60,60,60,60,20,50,60,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "70" + }, + { + "examine": "One of Bandos' chosen.", + "combat_style": "2", + "melee_animation": "4320", + "range_animation": "4320", + "attack_speed": "5", + "magic_level": "142", + "respawn_delay": "25", + "defence_animation": "4322", + "weakness": "4", + "magic_animation": "4320", + "death_animation": "4321", + "name": "Spiritual mage", + "defence_level": "103", + "safespot": null, + "lifepoints": "106", + "strength_level": "1", + "id": "6278", + "aggressive": "true", + "bonuses": "0,0,0,0,0,12,14,13,35,13,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ancient goblin.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "respawn_delay": "25", + "defence_animation": "6183", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "5", + "safespot": null, + "lifepoints": "20", + "strength_level": "5", + "id": "6279", + "aggressive": "true", + "bonuses": "10,20,20,20,20,5,20,10,0,0,0,0,0,0,0", + "clue_level": "0", + "range_level": "1", + "attack_level": "5" + }, + { + "examine": "A warrior for Bandos.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "respawn_delay": "25", + "defence_animation": "6183", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "5", + "safespot": null, + "lifepoints": "15", + "strength_level": "5", + "id": "6280", + "aggressive": "true", + "bonuses": "10,20,20,20,20,5,20,10,0,0,0,0,0,0,0", + "clue_level": "0", + "range_level": "1", + "attack_level": "5" + }, + { + "examine": "A soldier to the death.", + "melee_animation": "6188", + "range_animation": "6188", + "combat_audio": "469,472,471", + "respawn_delay": "25", + "defence_animation": "6189", + "magic_animation": "6188", + "death_animation": "6190", + "name": "Goblin", + "defence_level": "5", + "safespot": null, + "lifepoints": "15", + "strength_level": "5", + "id": "6281", + "aggressive": "true", + "bonuses": "5,10,10,10,10,10,5,10,5,0,0,0,0,0,0", + "clue_level": "0", + "range_level": "1", + "attack_level": "5" + }, + { + "examine": "A soldier to the death.", + "melee_animation": "6188", + "range_animation": "6188", + "combat_audio": "469,472,471", + "respawn_delay": "25", + "defence_animation": "6189", + "magic_animation": "6188", + "death_animation": "6190", + "name": "Goblin", + "defence_level": "5", + "safespot": null, + "lifepoints": "18", + "strength_level": "5", + "id": "6282", + "aggressive": "true", + "bonuses": "5,10,10,10,10,10,5,10,5,0,0,0,0,0,0", + "clue_level": "0", + "range_level": "1", + "attack_level": "5" + }, + { + "examine": "A warrior for Bandos.", + "melee_animation": "6185", + "range_animation": "6185", + "combat_audio": "469,472,471", + "respawn_delay": "25", + "defence_animation": "6183", + "slayer_exp": "16", + "magic_animation": "6185", + "death_animation": "6182", + "name": "Goblin", + "defence_level": "5", + "safespot": null, + "lifepoints": "16", + "strength_level": "5", + "id": "6283", + "aggressive": "true", + "bonuses": "10,20,20,20,20,5,20,10,0,0,0,0,0,0,0", + "clue_level": "0", + "range_level": "1", + "attack_level": "5" + }, + { + "examine": "You don't think you can harm this terrorbird.", + "combat_style": "1", + "melee_animation": "7108", + "range_animation": "0", + "magic_level": "59", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "1", + "magic_animation": "0", + "death_animation": "7109", + "name": "Warped terrorbird", + "defence_level": "59", + "safespot": null, + "lifepoints": "168", + "strength_level": "59", + "id": "6285", + "aggressive": "true", + "range_level": "59", + "projectile": "1468", + "attack_level": "59" + }, + { + "examine": "You don't think you can harm this terrorbird.", + "combat_style": "1", + "melee_animation": "7108", + "range_animation": "0", + "magic_level": "59", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "1", + "magic_animation": "0", + "death_animation": "7109", + "name": "Warped terrorbird", + "defence_level": "59", + "safespot": null, + "lifepoints": "168", + "strength_level": "59", + "id": "6286", + "aggressive": "true", + "range_level": "59", + "projectile": "1468", + "attack_level": "59" + }, + { + "examine": "You don't think you can harm this terrorbird.", + "combat_style": "1", + "melee_animation": "7108", + "range_animation": "0", + "magic_level": "59", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "1", + "magic_animation": "0", + "death_animation": "7109", + "name": "Warped terrorbird", + "defence_level": "59", + "safespot": null, + "lifepoints": "168", + "strength_level": "59", + "id": "6287", + "aggressive": "true", + "range_level": "59", + "projectile": "1468", + "attack_level": "59" + }, + { + "examine": "You don't think you can harm this terrorbird.", + "combat_style": "1", + "melee_animation": "7108", + "range_animation": "0", + "magic_level": "59", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "1", + "magic_animation": "0", + "death_animation": "7109", + "name": "Warped terrorbird", + "defence_level": "59", + "safespot": null, + "lifepoints": "168", + "strength_level": "59", + "id": "6288", + "aggressive": "true", + "range_level": "59", + "projectile": "1468", + "attack_level": "59" + }, + { + "examine": "You don't think you can harm this terrorbird.", + "combat_style": "1", + "melee_animation": "7108", + "range_animation": "0", + "magic_level": "59", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "1", + "magic_animation": "0", + "death_animation": "7109", + "name": "Warped terrorbird", + "defence_level": "59", + "safespot": null, + "lifepoints": "168", + "strength_level": "59", + "id": "6289", + "aggressive": "true", + "range_level": "59", + "projectile": "1468", + "attack_level": "59" + }, + { + "combat_style": "1", + "melee_animation": "7108", + "respawn_delay": "60", + "defence_animation": "7110", + "death_animation": "7109", + "name": "Warped terrorbird", + "defence_level": "1", + "safespot": null, + "lifepoints": "154", + "strength_level": "1", + "id": "6290", + "aggressive": "true", + "range_level": "1", + "projectile": "1468", + "attack_level": "1" + }, + { + "examine": "You don't think you can harm this terrorbird.", + "combat_style": "1", + "melee_animation": "7108", + "range_animation": "0", + "magic_level": "59", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "1", + "magic_animation": "0", + "death_animation": "7109", + "name": "Warped terrorbird", + "defence_level": "59", + "safespot": null, + "lifepoints": "168", + "strength_level": "59", + "id": "6291", + "aggressive": "true", + "range_level": "59", + "projectile": "1468", + "attack_level": "59" + }, + { + "examine": "You don't think you can harm this terrorbird.", + "combat_style": "1", + "melee_animation": "7108", + "range_animation": "0", + "magic_level": "59", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "1", + "magic_animation": "0", + "death_animation": "7109", + "name": "Warped terrorbird", + "defence_level": "59", + "safespot": null, + "lifepoints": "168", + "strength_level": "59", + "id": "6292", + "aggressive": "true", + "range_level": "59", + "projectile": "1468", + "attack_level": "59" + }, + { + "combat_style": "1", + "melee_animation": "7108", + "respawn_delay": "60", + "defence_animation": "7110", + "death_animation": "7109", + "name": "Warped terrorbird", + "defence_level": "1", + "safespot": null, + "lifepoints": "154", + "strength_level": "1", + "id": "6293", + "aggressive": "true", + "range_level": "1", + "projectile": "1468", + "attack_level": "1" + }, + { + "examine": "You don't think you can harm this terrorbird.", + "combat_style": "1", + "melee_animation": "7108", + "range_animation": "0", + "magic_level": "59", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "1", + "magic_animation": "0", + "death_animation": "7109", + "name": "Warped terrorbird", + "defence_level": "59", + "safespot": null, + "lifepoints": "308", + "strength_level": "59", + "id": "6294", + "aggressive": "true", + "range_level": "59", + "projectile": "1468", + "attack_level": "59" + }, + { + "examine": "You don't think you can harm this terrorbird.", + "combat_style": "1", + "melee_animation": "7108", + "range_animation": "0", + "magic_level": "59", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "1", + "magic_animation": "0", + "death_animation": "7109", + "name": "Warped terrorbird", + "defence_level": "59", + "safespot": null, + "lifepoints": "308", + "strength_level": "59", + "id": "6295", + "aggressive": "true", + "range_level": "59", + "projectile": "1468", + "attack_level": "59" + }, + { + "examine": "You don't think you can harm this creature.", + "melee_animation": "7093", + "range_animation": "0", + "attack_speed": "5", + "magic_level": "52", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "4", + "magic_animation": "0", + "death_animation": "7091", + "name": "Warped tortoise", + "defence_level": "52", + "safespot": null, + "lifepoints": "148", + "strength_level": "39", + "id": "6296", + "range_level": "1", + "attack_level": "39" + }, + { + "melee_animation": "7093", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "7092", + "death_animation": "7091", + "name": "Warped tortoise", + "defence_level": "1", + "safespot": null, + "lifepoints": "87", + "strength_level": "1", + "id": "6297", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Annoyingly easy to squish.", + "melee_animation": "0", + "range_animation": "0", + "magic_level": "2", + "defence_animation": "0", + "magic_animation": "0", + "name": "Bolrie", + "defence_level": "2", + "safespot": null, + "lifepoints": "0", + "strength_level": "1", + "id": "6306", + "aggressive": "true", + "range_level": "2", + "attack_level": "1" + }, + { + "examine": "She looks bored.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Guard no. 21", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6314", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He looks even more bored.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Guard no. 72", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6315", + "range_level": "1", + "attack_level": "1" + }, + { + "combat_style": "1", + "melee_animation": "7108", + "respawn_delay": "60", + "defence_animation": "7110", + "death_animation": "7109", + "name": "Warped terrorbird", + "defence_level": "1", + "safespot": null, + "lifepoints": "154", + "strength_level": "1", + "id": "6322", + "aggressive": "true", + "range_level": "1", + "projectile": "1468", + "attack_level": "1" + }, + { + "combat_style": "1", + "melee_animation": "7108", + "respawn_delay": "60", + "defence_animation": "7110", + "death_animation": "7109", + "name": "Warped terrorbird", + "defence_level": "1", + "safespot": null, + "lifepoints": "154", + "strength_level": "1", + "id": "6323", + "aggressive": "true", + "range_level": "1", + "projectile": "1468", + "attack_level": "1" + }, + { + "combat_style": "1", + "melee_animation": "7108", + "respawn_delay": "60", + "defence_animation": "7110", + "death_animation": "7109", + "name": "Warped terrorbird", + "defence_level": "1", + "safespot": null, + "lifepoints": "154", + "strength_level": "1", + "id": "6324", + "aggressive": "true", + "range_level": "1", + "projectile": "1468", + "attack_level": "1" + }, + { + "combat_style": "1", + "melee_animation": "7108", + "respawn_delay": "60", + "defence_animation": "7110", + "death_animation": "7109", + "name": "Warped terrorbird", + "defence_level": "1", + "safespot": null, + "lifepoints": "154", + "strength_level": "1", + "id": "6325", + "aggressive": "true", + "range_level": "1", + "projectile": "1468", + "attack_level": "1" + }, + { + "combat_style": "1", + "melee_animation": "7108", + "respawn_delay": "60", + "defence_animation": "7110", + "death_animation": "7109", + "name": "Warped terrorbird", + "defence_level": "1", + "safespot": null, + "lifepoints": "154", + "strength_level": "1", + "id": "6326", + "aggressive": "true", + "range_level": "1", + "projectile": "1468", + "attack_level": "1" + }, + { + "combat_style": "1", + "melee_animation": "7108", + "respawn_delay": "60", + "defence_animation": "7110", + "death_animation": "7109", + "name": "Warped terrorbird", + "defence_level": "1", + "safespot": null, + "lifepoints": "154", + "strength_level": "1", + "id": "6327", + "aggressive": "true", + "range_level": "1", + "projectile": "1468", + "attack_level": "1" + }, + { + "combat_style": "1", + "melee_animation": "7108", + "respawn_delay": "60", + "defence_animation": "7110", + "death_animation": "7109", + "name": "Warped terrorbird", + "defence_level": "1", + "safespot": null, + "lifepoints": "154", + "strength_level": "1", + "id": "6328", + "aggressive": "true", + "range_level": "1", + "projectile": "1468", + "attack_level": "1" + }, + { + "combat_style": "1", + "melee_animation": "7108", + "respawn_delay": "60", + "defence_animation": "7110", + "death_animation": "7109", + "name": "Warped terrorbird", + "defence_level": "1", + "safespot": null, + "lifepoints": "154", + "strength_level": "1", + "id": "6329", + "aggressive": "true", + "range_level": "1", + "projectile": "1468", + "attack_level": "1" + }, + { + "combat_style": "1", + "melee_animation": "7108", + "respawn_delay": "60", + "defence_animation": "7110", + "death_animation": "7109", + "name": "Warped terrorbird", + "defence_level": "1", + "safespot": null, + "lifepoints": "154", + "strength_level": "1", + "id": "6330", + "aggressive": "true", + "range_level": "1", + "projectile": "1468", + "attack_level": "1" + }, + { + "combat_style": "1", + "melee_animation": "7108", + "respawn_delay": "60", + "defence_animation": "7110", + "death_animation": "7109", + "name": "Warped terrorbird", + "defence_level": "1", + "safespot": null, + "lifepoints": "154", + "strength_level": "1", + "id": "6331", + "aggressive": "true", + "range_level": "1", + "projectile": "1468", + "attack_level": "1" + }, + { + "combat_style": "1", + "melee_animation": "7108", + "respawn_delay": "60", + "defence_animation": "7110", + "death_animation": "7109", + "name": "Warped terrorbird", + "defence_level": "1", + "safespot": null, + "lifepoints": "154", + "strength_level": "1", + "id": "6332", + "aggressive": "true", + "range_level": "1", + "projectile": "1468", + "attack_level": "1" + }, + { + "examine": "A child of West Ardougne.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Child", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6334", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A child of West Ardougne.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Child", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6335", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A child of West Ardougne.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Child", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6336", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A child of West Ardougne.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Child", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6337", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A child of West Ardougne.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Child", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6338", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A child of West Ardougne.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Child", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6339", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Duck!", + "combat_style": "1", + "melee_animation": "3920", + "range_animation": "3920", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "1", + "magic_animation": "0", + "death_animation": "3922", + "name": "Child", + "defence_level": "65", + "safespot": null, + "lifepoints": "92", + "strength_level": "48", + "id": "6344", + "aggressive": "true", + "range_level": "65", + "attack_level": "48" + }, + { + "melee_animation": "390", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "20", + "strength_level": "1", + "id": "6346", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "390", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "20", + "strength_level": "1", + "id": "6347", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "390", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "20", + "strength_level": "1", + "id": "6348", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "390", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "20", + "strength_level": "1", + "id": "6349", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "390", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "20", + "strength_level": "1", + "id": "6350", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "390", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "23", + "strength_level": "1", + "id": "6351", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "390", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "23", + "strength_level": "1", + "id": "6352", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "390", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "23", + "strength_level": "1", + "id": "6353", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "390", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "23", + "strength_level": "1", + "id": "6354", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "390", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "23", + "strength_level": "1", + "id": "6355", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "390", + "combat_audio": "703,705,704", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Pirate", + "defence_level": "1", + "safespot": null, + "lifepoints": "23", + "strength_level": "1", + "id": "6356", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The mother of all pests!", + "attack_speed": "6", + "magic_level": "70", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "0", + "name": "Street urchin", + "defence_level": "70", + "safespot": null, + "lifepoints": "1428", + "strength_level": "70", + "id": "6358", + "aggressive": "true", + "range_level": "70", + "attack_level": "70" + }, + { + "examine": "A warrior of Zamorak.", + "melee_animation": "390", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "836", + "name": "Zamorak warrior", + "defence_level": "44", + "safespot": null, + "lifepoints": "62", + "strength_level": "44", + "id": "6363", + "aggressive": "true", + "range_level": "1", + "attack_level": "44" + }, + { + "examine": "A warrior of Zamorak.", + "melee_animation": "390", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "836", + "name": "Zamorak warrior", + "defence_level": "47", + "safespot": null, + "lifepoints": "67", + "strength_level": "47", + "id": "6364", + "aggressive": "true", + "range_level": "1", + "attack_level": "47" + }, + { + "examine": "A ranger of Zamorak.", + "combat_style": "1", + "melee_animation": "426", + "range_animation": "426", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "1", + "magic_animation": "0", + "death_animation": "836", + "name": "Zamorak ranger", + "defence_level": "46", + "safespot": null, + "lifepoints": "65", + "strength_level": "1", + "id": "6365", + "aggressive": "true", + "range_level": "46", + "attack_level": "1" + }, + { + "examine": "A ranger of Zamorak.", + "melee_animation": "426", + "range_animation": "426", + "defence_animation": "0", + "weakness": "1", + "magic_animation": "0", + "death_animation": "836", + "name": "Zamorak ranger", + "defence_level": "46", + "safespot": null, + "lifepoints": "65", + "strength_level": "1", + "id": "6366", + "aggressive": "true", + "range_level": "46", + "attack_level": "1" + }, + { + "examine": "A mage of Zamorak.", + "combat_style": "2", + "melee_animation": "0", + "range_animation": "0", + "magic_level": "49", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "5", + "magic_animation": "0", + "death_animation": "836", + "name": "Zamorak mage", + "defence_level": "49", + "safespot": null, + "lifepoints": "70", + "strength_level": "1", + "id": "6367", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A mage of Zamorak.", + "melee_animation": "0", + "range_animation": "0", + "magic_level": "49", + "defence_animation": "0", + "weakness": "5", + "magic_animation": "0", + "death_animation": "836", + "name": "Zamorak mage", + "defence_level": "49", + "safespot": null, + "lifepoints": "70", + "strength_level": "1", + "id": "6368", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A cave dweller.", + "melee_animation": "7207", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "0", + "magic_animation": "0", + "death_animation": "7205", + "name": "Cave lizard", + "defence_level": "47", + "safespot": null, + "lifepoints": "67", + "strength_level": "1", + "id": "6369", + "aggressive": "true", + "range_level": "47", + "attack_level": "1" + }, + { + "examine": "A representative of the Z.M.I.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Mage of Zamorak", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6370", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A Z.M.I. runecrafter.", + "melee_animation": "422", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "836", + "name": "Zamorak crafter", + "defence_level": "19", + "safespot": null, + "lifepoints": "27", + "strength_level": "19", + "id": "6371", + "range_level": "1", + "attack_level": "19" + }, + { + "death_animation": "836", + "name": "Zamorak crafter", + "defence_level": "1", + "safespot": null, + "lifepoints": "25", + "melee_animation": "422", + "strength_level": "1", + "id": "6372", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1", + "defence_animation": "425" + }, + { + "slayer_exp": "49", + "name": "Guard dog", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6374", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "5327", + "combat_audio": "537,539,538", + "respawn_delay": "60", + "defence_animation": "5328", + "death_animation": "5329", + "name": "Jungle spider", + "defence_level": "1", + "safespot": null, + "lifepoints": "25", + "strength_level": "1", + "id": "6376", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "5327", + "combat_audio": "537,539,538", + "respawn_delay": "60", + "defence_animation": "5328", + "death_animation": "5329", + "name": "Jungle spider", + "defence_level": "1", + "safespot": null, + "lifepoints": "25", + "strength_level": "1", + "id": "6377", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "I wouldn't want to be footing that bill.", + "melee_animation": "6775", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "6779", + "name": "Tenacious toucan", + "defence_level": "60", + "safespot": null, + "lifepoints": "85", + "strength_level": "60", + "id": "6378", + "range_level": "1", + "attack_level": "60" + }, + { + "examine": "I wonder how much he can lift.", + "melee_animation": "7237", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "7238", + "name": "Giant ant worker", + "defence_level": "35", + "safespot": null, + "lifepoints": "50", + "strength_level": "35", + "id": "6379", + "range_level": "1", + "attack_level": "35" + }, + { + "examine": "Gi-ant-ant-ant-ant...", + "melee_animation": "7237", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "7238", + "name": "Giant ant soldier", + "defence_level": "50", + "safespot": null, + "lifepoints": "71", + "strength_level": "50", + "id": "6380", + "aggressive": "true", + "range_level": "1", + "attack_level": "50" + }, + { + "examine": "That stinger has to hurt...", + "melee_animation": "7242", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "7244", + "name": "Giant wasp", + "defence_level": "60", + "safespot": null, + "lifepoints": "85", + "strength_level": "60", + "id": "6381", + "aggressive": "true", + "range_level": "1", + "attack_level": "60" + }, + { + "examine": "Polynomial - a parrot that goes without breakfast", + "melee_animation": "6775", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "6777", + "name": "Pernicious parrot", + "defence_level": "45", + "safespot": null, + "lifepoints": "64", + "strength_level": "45", + "id": "6382", + "range_level": "1", + "attack_level": "45" + }, + { + "melee_animation": "7242", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "7243", + "death_animation": "7244", + "name": "Giant wasp", + "defence_level": "1", + "safespot": null, + "lifepoints": "37", + "strength_level": "1", + "id": "6383", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A very large", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Karamjan Jungle eagle", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6385", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Flies like a rock.", + "melee_animation": "9454", + "range_animation": "1516", + "combat_audio": "428,430,429", + "attack_speed": "4", + "magic_level": "1", + "defence_animation": "9455", + "slayer_exp": "105", + "magic_animation": "1516", + "death_animation": "1518", + "name": "Gargoyle", + "defence_level": "107", + "safespot": null, + "lifepoints": "105", + "strength_level": "95", + "id": "6389", + "aggressive": "true", + "bonuses": "0,0,0,0,0,20,20,0,20,20,0,0,0,0,0", + "clue_level": "2", + "range_level": "1", + "attack_level": "75" + }, + { + "examine": "I wish I could tell where he was looking. What could be beneath that hood?", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Grim Reaper", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6390", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6402", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6403", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6404", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6405", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6406", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6407", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6408", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6409", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6410", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6411", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6412", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6413", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6414", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6415", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6416", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6417", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6418", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6419", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6420", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6421", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6422", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6423", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6424", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6425", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6426", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6427", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6428", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6429", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6430", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6431", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6432", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6433", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6434", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6435", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6436", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6437", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6438", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6439", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6440", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6441", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6442", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6443", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6444", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6445", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6446", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6447", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6448", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6449", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6450", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6451", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6452", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6453", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6454", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6455", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6456", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6457", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6458", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6459", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6460", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6461", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6462", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6463", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6464", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6465", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6466", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6467", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A goblin high priest", + "melee_animation": "7317", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "6182", + "name": "Snothead", + "defence_level": "14", + "safespot": null, + "lifepoints": "20", + "strength_level": "14", + "id": "6469", + "aggressive": "true", + "range_level": "1", + "attack_level": "14" + }, + { + "examine": "A goblin high priest", + "melee_animation": "7317", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "2", + "magic_animation": "0", + "death_animation": "6182", + "name": "Snailfeet", + "defence_level": "18", + "safespot": null, + "lifepoints": "25", + "strength_level": "13", + "id": "6470", + "aggressive": "true", + "range_level": "18", + "attack_level": "13" + }, + { + "examine": "A goblin high priest", + "melee_animation": "7317", + "range_animation": "0", + "magic_level": "22", + "defence_animation": "0", + "weakness": "5", + "magic_animation": "0", + "death_animation": "6182", + "name": "Mosschin", + "defence_level": "22", + "safespot": null, + "lifepoints": "31", + "strength_level": "16", + "id": "6471", + "aggressive": "true", + "range_level": "1", + "attack_level": "16" + }, + { + "examine": "A goblin high priest", + "melee_animation": "7317", + "range_animation": "0", + "magic_level": "26", + "defence_animation": "0", + "weakness": "5", + "magic_animation": "0", + "death_animation": "6182", + "name": "Redeyes", + "defence_level": "26", + "safespot": null, + "lifepoints": "37", + "strength_level": "19", + "id": "6472", + "aggressive": "true", + "range_level": "1", + "attack_level": "19" + }, + { + "examine": "A goblin high priest", + "melee_animation": "7317", + "range_animation": "0", + "magic_level": "26", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "5", + "magic_animation": "0", + "death_animation": "6182", + "name": "Strongbones", + "defence_level": "26", + "safespot": null, + "lifepoints": "37", + "strength_level": "19", + "id": "6473", + "aggressive": "true", + "range_level": "1", + "attack_level": "19" + }, + { + "examine": "Priest of the Ekeleshuun tribe.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Priest", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6482", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He is expounding the word of the Big High War God.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Preacher", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6488", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6490", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6491", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6492", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6493", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6494", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Goblin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "469,472,471", + "strength_level": "1", + "id": "6495", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He doesn't look very welcoming.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "469,472,471", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Goblin guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6496", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He doesn't look very welcoming.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "469,472,471", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Goblin guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6497", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A guard wearing blue armour.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6498", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A guard wearing orange armour.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6499", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A guard wearing black armour.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6500", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A guard wearing white armour.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6501", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A guard wearing purple armour.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6502", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A guard wearing yellow armour.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6503", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "slayer_exp": "25", + "name": "Ghost", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "436,439,438", + "strength_level": "1", + "id": "6504", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A very noble spider and attendant to the Queen.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Registrar 2", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6507", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The highest ranking of the Spider Queen's servants.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Registrar 3", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6508", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The head of the Spider Queen's army.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Registrar 4", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6509", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Trying hard to hide his identity.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Jury", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6510", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Sir Amik's loyal squire.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Spectator", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6512", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A being of ore and minerals.", + "magic_animation": "0", + "name": "Spectator", + "defence_level": "1", + "safespot": null, + "lifepoints": "1", + "range_animation": "0", + "strength_level": "1", + "id": "6514", + "range_level": "1", + "attack_level": "1", + "defence_animation": "0" + }, + { + "examine": "A monkey on a mission.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Spectator", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6516", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He works for Doric & Son.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Spectator", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6518", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Gives an introduction to the Grand Exchange.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Grand Exchange Tutor", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6521", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The son of Ali M!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Farid Morrisane (ores)", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6523", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He's probably seen better days.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Bob Barter (herbs)", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6524", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "You can never miss a pirate in disguise.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Murky Matt (runes)", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6525", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A tribal man", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Relobo Blinyo (logs)", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6526", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He's travelled a long way.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Hofuthand (armour and weapons)", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6527", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Chief architect of the Spider Realm.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Registrar 5", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6536", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "6543", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "511,513,512", + "strength_level": "1", + "id": "6544", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Tapping his feet and looking very bored.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "null", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6558", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A huge war chief. ", + "melee_animation": "422", + "range_animation": "422", + "attack_speed": "5", + "respawn_delay": "20", + "defence_animation": "7061", + "magic_animation": "422", + "death_animation": "7062", + "name": "null", + "defence_level": "250", + "safespot": null, + "lifepoints": "254", + "strength_level": "251", + "id": "6560", + "aggressive": "true", + "bonuses": "300,300,300,300,300,300,150,300,300,250,43,96,43,30,0", + "range_level": "200", + "attack_level": "250" + }, + { + "spawn_animation": "7410", + "examine": "The essence of an imp slain during the god wars.", + "melee_animation": "7407", + "range_animation": "7501", + "combat_audio": "0,0,0", + "magic_level": "10", + "defence_animation": "7404", + "slayer_exp": "10", + "magic_animation": "7500", + "death_animation": "7408", + "name": "Revenant imp", + "defence_level": "10", + "safespot": null, + "lifepoints": "20", + "strength_level": "10", + "id": "6604", + "range_level": "10", + "attack_level": "10" + }, + { + "spawn_animation": "7447", + "examine": "The ghost of a goblin slain during the god wars.", + "melee_animation": "7449", + "range_animation": "7513", + "combat_audio": "469,472,471", + "magic_level": "12", + "defence_animation": "7450", + "magic_animation": "7499", + "death_animation": "7448", + "name": "Revenant goblin", + "defence_level": "12", + "safespot": null, + "lifepoints": "24", + "strength_level": "12", + "id": "6605", + "clue_level": "1", + "range_level": "12", + "attack_level": "12" + }, + { + "spawn_animation": "7485", + "examine": "The ghost of an icefiend slain during the God Wars.", + "melee_animation": "7481", + "range_animation": "7519", + "attack_speed": "3", + "magic_level": "27", + "defence_animation": "7483", + "slayer_exp": "40", + "magic_animation": "7506", + "death_animation": "7482", + "name": "Revenant icefiend", + "defence_level": "27", + "safespot": null, + "lifepoints": "40", + "strength_level": "27", + "id": "6606", + "clue_level": "1", + "range_level": "27", + "attack_level": "27" + }, + { + "spawn_animation": "7403", + "examine": "The ghost of a werewolf slain during the god wars.", + "melee_animation": "7397", + "range_animation": "7521", + "magic_level": "38", + "defence_animation": "7399", + "magic_animation": "7496", + "death_animation": "7398", + "name": "Revenant werewolf", + "defence_level": "38", + "safespot": null, + "lifepoints": "65", + "strength_level": "38", + "id": "6607", + "clue_level": "2", + "range_level": "38", + "attack_level": "38" + }, + { + "examine": "The ghost of a hobgoblin slain during the God Wars.", + "melee_animation": "7418", + "range_animation": "7516", + "combat_audio": "469,472,471", + "magic_level": "32", + "defence_animation": "7420", + "slayer_exp": "72", + "magic_animation": "7503", + "death_animation": "7419", + "name": "Revenant hobgoblin", + "defence_level": "32", + "safespot": null, + "lifepoints": "72", + "strength_level": "32", + "id": "6608", + "clue_level": "1", + "range_level": "32", + "attack_level": "32" + }, + { + "spawn_animation": "7403", + "examine": "The ghost of a werewolf slain during the god wars.", + "melee_animation": "7397", + "range_animation": "7521", + "magic_level": "38", + "defence_animation": "7399", + "magic_animation": "7496", + "death_animation": "7398", + "name": "Revenant werewolf", + "defence_level": "38", + "safespot": null, + "lifepoints": "65", + "strength_level": "38", + "id": "6609", + "clue_level": "2", + "range_level": "38", + "attack_level": "38" + }, + { + "examine": "A ghost of an ork slain during the god wars.", + "melee_animation": "7411", + "range_animation": "7518", + "magic_level": "70", + "defence_animation": "7413", + "magic_animation": "7505", + "death_animation": "7412", + "name": "Revenant ork", + "defence_level": "70", + "safespot": null, + "lifepoints": "105", + "strength_level": "70", + "id": "6610", + "clue_level": "2", + "range_level": "70", + "attack_level": "70" + }, + { + "spawn_animation": "7440", + "examine": "A ghost of a knight slain during the god wars.", + "melee_animation": "7441", + "range_animation": "7522", + "poisonous": "true", + "magic_level": "80", + "defence_animation": "7443", + "slayer_exp": "143", + "poison_amount": "8", + "magic_animation": "7508", + "death_animation": "7442", + "name": "Revenant knight", + "defence_level": "80", + "safespot": null, + "lifepoints": "143", + "strength_level": "80", + "id": "6611", + "clue_level": "2", + "range_level": "80", + "attack_level": "80" + }, + { + "spawn_animation": "7447", + "examine": "The ghost of a goblin slain during the god wars.", + "melee_animation": "7449", + "range_animation": "7513", + "combat_audio": "469,472,471", + "magic_level": "12", + "defence_animation": "7450", + "magic_animation": "7499", + "death_animation": "7448", + "name": "Revenant goblin", + "defence_level": "12", + "safespot": null, + "lifepoints": "24", + "strength_level": "12", + "id": "6612", + "clue_level": "1", + "range_level": "12", + "attack_level": "12" + }, + { + "spawn_animation": "7426", + "examine": "The ghost of a vampire slain in the god wars.", + "melee_animation": "7427", + "range_animation": "7520", + "magic_level": "34", + "defence_animation": "7429", + "slayer_exp": "60", + "magic_animation": "7507", + "death_animation": "7428", + "name": "Revenant vampire", + "defence_level": "34", + "safespot": null, + "lifepoints": "60", + "strength_level": "34", + "id": "6613", + "clue_level": "1", + "range_level": "34", + "attack_level": "34" + }, + { + "spawn_animation": "7403", + "examine": "The ghost of a werewolf slain during the god wars.", + "melee_animation": "7397", + "range_animation": "7521", + "magic_level": "38", + "defence_animation": "7399", + "magic_animation": "7496", + "death_animation": "7398", + "name": "Revenant werewolf", + "defence_level": "38", + "safespot": null, + "lifepoints": "65", + "strength_level": "38", + "id": "6614", + "clue_level": "2", + "range_level": "38", + "attack_level": "38" + }, + { + "examine": "A ghost of an ork slain during the god wars.", + "melee_animation": "7411", + "range_animation": "7518", + "magic_level": "70", + "defence_animation": "7413", + "magic_animation": "7505", + "death_animation": "7412", + "name": "Revenant ork", + "defence_level": "70", + "safespot": null, + "lifepoints": "105", + "strength_level": "70", + "id": "6615", + "clue_level": "2", + "range_level": "70", + "attack_level": "70" + }, + { + "spawn_animation": "7447", + "examine": "The ghost of a goblin slain during the god wars.", + "melee_animation": "7449", + "range_animation": "7513", + "combat_audio": "469,472,471", + "magic_level": "12", + "defence_animation": "7450", + "magic_animation": "7499", + "death_animation": "7448", + "name": "Revenant goblin", + "defence_level": "12", + "safespot": null, + "lifepoints": "24", + "strength_level": "12", + "id": "6616", + "clue_level": "1", + "range_level": "12", + "attack_level": "12" + }, + { + "spawn_animation": "7403", + "examine": "The ghost of a werewolf slain during the god wars.", + "melee_animation": "7397", + "range_animation": "7521", + "magic_level": "38", + "defence_animation": "7399", + "magic_animation": "7496", + "death_animation": "7398", + "name": "Revenant werewolf", + "defence_level": "38", + "safespot": null, + "lifepoints": "65", + "strength_level": "38", + "id": "6617", + "clue_level": "2", + "range_level": "38", + "attack_level": "38" + }, + { + "examine": "A ghost of an ork slain during the god wars.", + "melee_animation": "7411", + "range_animation": "7518", + "magic_level": "70", + "defence_animation": "7413", + "magic_animation": "7505", + "death_animation": "7412", + "name": "Revenant ork", + "defence_level": "70", + "safespot": null, + "lifepoints": "105", + "strength_level": "70", + "id": "6618", + "clue_level": "2", + "range_level": "70", + "attack_level": "70" + }, + { + "spawn_animation": "7440", + "examine": "A ghost of a knight slain during the god wars.", + "melee_animation": "7441", + "range_animation": "7522", + "poisonous": "true", + "magic_level": "80", + "defence_animation": "7443", + "slayer_exp": "143", + "poison_amount": "8", + "magic_animation": "7508", + "death_animation": "7442", + "name": "Revenant knight", + "defence_level": "80", + "safespot": null, + "lifepoints": "143", + "strength_level": "80", + "id": "6619", + "clue_level": "2", + "range_level": "80", + "attack_level": "80" + }, + { + "spawn_animation": "7447", + "examine": "The ghost of a goblin slain during the god wars.", + "melee_animation": "7449", + "range_animation": "7513", + "combat_audio": "469,472,471", + "magic_level": "12", + "defence_animation": "7450", + "magic_animation": "7499", + "death_animation": "7448", + "name": "Revenant goblin", + "defence_level": "12", + "safespot": null, + "lifepoints": "24", + "strength_level": "12", + "id": "6620", + "clue_level": "1", + "range_level": "12", + "attack_level": "12" + }, + { + "spawn_animation": "7485", + "examine": "The ghost of an icefiend slain during the God Wars.", + "melee_animation": "7481", + "range_animation": "7519", + "attack_speed": "3", + "magic_level": "27", + "defence_animation": "7483", + "slayer_exp": "40", + "magic_animation": "7506", + "death_animation": "7482", + "name": "Revenant icefiend", + "defence_level": "27", + "safespot": null, + "lifepoints": "40", + "strength_level": "27", + "id": "6621", + "clue_level": "1", + "range_level": "27", + "attack_level": "27" + }, + { + "spawn_animation": "7485", + "examine": "The essence of a pyrefiend slain during the god wars.", + "melee_animation": "7481", + "range_animation": "7519", + "attack_speed": "3", + "magic_level": "29", + "defence_animation": "7483", + "slayer_exp": "48", + "magic_animation": "7506", + "death_animation": "7482", + "name": "Revenant pyrefiend", + "defence_level": "29", + "safespot": null, + "lifepoints": "48", + "strength_level": "29", + "id": "6622", + "clue_level": "1", + "range_level": "29", + "attack_level": "29" + }, + { + "spawn_animation": "7426", + "examine": "The ghost of a vampire slain in the god wars.", + "melee_animation": "7427", + "range_animation": "7520", + "magic_level": "34", + "defence_animation": "7429", + "slayer_exp": "60", + "magic_animation": "7507", + "death_animation": "7428", + "name": "Revenant vampire", + "defence_level": "34", + "safespot": null, + "lifepoints": "60", + "strength_level": "34", + "id": "6623", + "clue_level": "1", + "range_level": "34", + "attack_level": "34" + }, + { + "examine": "A ghost of an ork slain during the god wars.", + "melee_animation": "7411", + "range_animation": "7518", + "magic_level": "70", + "defence_animation": "7413", + "magic_animation": "7505", + "death_animation": "7412", + "name": "Revenant ork", + "defence_level": "70", + "safespot": null, + "lifepoints": "105", + "strength_level": "70", + "id": "6624", + "clue_level": "2", + "range_level": "70", + "attack_level": "70" + }, + { + "spawn_animation": "7403", + "examine": "The ghost of a werewolf slain during the god wars.", + "melee_animation": "7397", + "range_animation": "7521", + "magic_level": "38", + "defence_animation": "7399", + "magic_animation": "7496", + "death_animation": "7398", + "name": "Revenant werewolf", + "defence_level": "38", + "safespot": null, + "lifepoints": "65", + "strength_level": "38", + "id": "6625", + "clue_level": "2", + "range_level": "38", + "attack_level": "38" + }, + { + "examine": "A ghost of an ork slain during the god wars.", + "melee_animation": "7411", + "range_animation": "7518", + "magic_level": "70", + "defence_animation": "7413", + "magic_animation": "7505", + "death_animation": "7412", + "name": "Revenant ork", + "defence_level": "70", + "safespot": null, + "lifepoints": "105", + "strength_level": "70", + "id": "6626", + "clue_level": "2", + "range_level": "70", + "attack_level": "70" + }, + { + "spawn_animation": "7440", + "examine": "A ghost of a knight slain during the god wars.", + "melee_animation": "7441", + "range_animation": "7522", + "poisonous": "true", + "magic_level": "80", + "defence_animation": "7443", + "slayer_exp": "143", + "poison_amount": "8", + "magic_animation": "7508", + "death_animation": "7442", + "name": "Revenant knight", + "defence_level": "80", + "safespot": null, + "lifepoints": "143", + "strength_level": "80", + "id": "6627", + "clue_level": "2", + "range_level": "80", + "attack_level": "80" + }, + { + "spawn_animation": "7485", + "examine": "The ghost of an icefiend slain during the God Wars.", + "melee_animation": "7481", + "range_animation": "7519", + "attack_speed": "3", + "magic_level": "27", + "defence_animation": "7483", + "slayer_exp": "40", + "magic_animation": "7506", + "death_animation": "7482", + "name": "Revenant icefiend", + "defence_level": "27", + "safespot": null, + "lifepoints": "40", + "strength_level": "27", + "id": "6628", + "clue_level": "1", + "range_level": "27", + "attack_level": "27" + }, + { + "examine": "A ghost of an ork slain during the god wars.", + "melee_animation": "7411", + "range_animation": "7518", + "magic_level": "70", + "defence_animation": "7413", + "magic_animation": "7505", + "death_animation": "7412", + "name": "Revenant ork", + "defence_level": "70", + "safespot": null, + "lifepoints": "105", + "strength_level": "70", + "id": "6629", + "clue_level": "2", + "range_level": "70", + "attack_level": "70" + }, + { + "spawn_animation": "7440", + "examine": "A ghost of a knight slain during the god wars.", + "melee_animation": "7441", + "range_animation": "7522", + "poisonous": "true", + "magic_level": "80", + "defence_animation": "7443", + "slayer_exp": "143", + "poison_amount": "8", + "magic_animation": "7508", + "death_animation": "7442", + "name": "Revenant knight", + "defence_level": "80", + "safespot": null, + "lifepoints": "143", + "strength_level": "80", + "id": "6630", + "clue_level": "2", + "range_level": "80", + "attack_level": "80" + }, + { + "spawn_animation": "7485", + "examine": "The essence of a pyrefiend slain during the god wars.", + "melee_animation": "7481", + "range_animation": "7519", + "attack_speed": "3", + "magic_level": "29", + "defence_animation": "7483", + "slayer_exp": "48", + "magic_animation": "7506", + "death_animation": "7482", + "name": "Revenant pyrefiend", + "defence_level": "29", + "safespot": null, + "lifepoints": "48", + "strength_level": "29", + "id": "6631", + "clue_level": "1", + "range_level": "29", + "attack_level": "29" + }, + { + "spawn_animation": "7403", + "examine": "The ghost of a werewolf slain during the god wars.", + "melee_animation": "7397", + "range_animation": "7521", + "magic_level": "38", + "defence_animation": "7399", + "magic_animation": "7496", + "death_animation": "7398", + "name": "Revenant werewolf", + "defence_level": "38", + "safespot": null, + "lifepoints": "65", + "strength_level": "38", + "id": "6632", + "clue_level": "2", + "range_level": "38", + "attack_level": "38" + }, + { + "examine": "A ghost of an ork slain during the god wars.", + "melee_animation": "7411", + "range_animation": "7518", + "magic_level": "70", + "defence_animation": "7413", + "magic_animation": "7505", + "death_animation": "7412", + "name": "Revenant ork", + "defence_level": "70", + "safespot": null, + "lifepoints": "105", + "strength_level": "70", + "id": "6633", + "clue_level": "2", + "range_level": "70", + "attack_level": "70" + }, + { + "spawn_animation": "7440", + "examine": "A ghost of a knight slain during the god wars.", + "melee_animation": "7441", + "range_animation": "7522", + "poisonous": "true", + "magic_level": "80", + "defence_animation": "7443", + "slayer_exp": "143", + "poison_amount": "8", + "magic_animation": "7508", + "death_animation": "7442", + "name": "Revenant knight", + "defence_level": "80", + "safespot": null, + "lifepoints": "143", + "strength_level": "80", + "id": "6634", + "clue_level": "2", + "range_level": "80", + "attack_level": "80" + }, + { + "spawn_animation": "7410", + "examine": "The essence of an imp slain during the god wars.", + "melee_animation": "7407", + "range_animation": "7501", + "combat_audio": "0,0,0", + "magic_level": "10", + "defence_animation": "7404", + "slayer_exp": "10", + "magic_animation": "7500", + "death_animation": "7408", + "name": "Revenant imp", + "defence_level": "10", + "safespot": null, + "lifepoints": "20", + "strength_level": "10", + "id": "6635", + "range_level": "10", + "attack_level": "10" + }, + { + "spawn_animation": "7447", + "examine": "The ghost of a goblin slain during the god wars.", + "melee_animation": "7449", + "range_animation": "7513", + "combat_audio": "469,472,471", + "magic_level": "12", + "defence_animation": "7450", + "magic_animation": "7499", + "death_animation": "7448", + "name": "Revenant goblin", + "defence_level": "12", + "safespot": null, + "lifepoints": "24", + "strength_level": "12", + "id": "6636", + "clue_level": "1", + "range_level": "12", + "attack_level": "12" + }, + { + "spawn_animation": "7447", + "examine": "The ghost of a goblin slain during the god wars.", + "melee_animation": "7449", + "range_animation": "7513", + "combat_audio": "469,472,471", + "magic_level": "12", + "defence_animation": "7450", + "magic_animation": "7499", + "death_animation": "7448", + "name": "Revenant goblin", + "defence_level": "12", + "safespot": null, + "lifepoints": "24", + "strength_level": "12", + "id": "6637", + "clue_level": "1", + "range_level": "12", + "attack_level": "12" + }, + { + "spawn_animation": "7447", + "examine": "The ghost of a goblin slain during the god wars.", + "melee_animation": "7449", + "range_animation": "7513", + "combat_audio": "469,472,471", + "magic_level": "12", + "defence_animation": "7450", + "magic_animation": "7499", + "death_animation": "7448", + "name": "Revenant goblin", + "defence_level": "12", + "safespot": null, + "lifepoints": "24", + "strength_level": "12", + "id": "6638", + "clue_level": "1", + "range_level": "12", + "attack_level": "12" + }, + { + "spawn_animation": "7447", + "examine": "The ghost of a goblin slain during the god wars.", + "melee_animation": "7449", + "range_animation": "7513", + "combat_audio": "469,472,471", + "magic_level": "12", + "defence_animation": "7450", + "magic_animation": "7499", + "death_animation": "7448", + "name": "Revenant goblin", + "defence_level": "12", + "safespot": null, + "lifepoints": "24", + "strength_level": "12", + "id": "6639", + "clue_level": "1", + "range_level": "12", + "attack_level": "12" + }, + { + "spawn_animation": "7485", + "examine": "The ghost of an icefiend slain during the God Wars.", + "melee_animation": "7481", + "range_animation": "7519", + "attack_speed": "3", + "magic_level": "27", + "defence_animation": "7483", + "slayer_exp": "40", + "magic_animation": "7506", + "death_animation": "7482", + "name": "Revenant icefiend", + "defence_level": "27", + "safespot": null, + "lifepoints": "40", + "strength_level": "27", + "id": "6640", + "clue_level": "1", + "range_level": "27", + "attack_level": "27" + }, + { + "spawn_animation": "7485", + "examine": "The essence of a pyrefiend slain during the god wars.", + "melee_animation": "7481", + "range_animation": "7519", + "attack_speed": "3", + "magic_level": "29", + "defence_animation": "7483", + "slayer_exp": "48", + "magic_animation": "7506", + "death_animation": "7482", + "name": "Revenant pyrefiend", + "defence_level": "29", + "safespot": null, + "lifepoints": "48", + "strength_level": "29", + "id": "6641", + "clue_level": "1", + "range_level": "29", + "attack_level": "29" + }, + { + "examine": "The ghost of a hobgoblin slain during the God Wars.", + "melee_animation": "7418", + "range_animation": "7516", + "combat_audio": "469,472,471", + "magic_level": "32", + "defence_animation": "7420", + "slayer_exp": "72", + "magic_animation": "7503", + "death_animation": "7419", + "name": "Revenant hobgoblin", + "defence_level": "32", + "safespot": null, + "lifepoints": "72", + "strength_level": "32", + "id": "6642", + "clue_level": "1", + "range_level": "32", + "attack_level": "32" + }, + { + "spawn_animation": "7426", + "examine": "The ghost of a vampire slain in the god wars.", + "melee_animation": "7427", + "range_animation": "7520", + "magic_level": "34", + "defence_animation": "7429", + "slayer_exp": "60", + "magic_animation": "7507", + "death_animation": "7428", + "name": "Revenant vampire", + "defence_level": "34", + "safespot": null, + "lifepoints": "60", + "strength_level": "34", + "id": "6643", + "clue_level": "1", + "range_level": "34", + "attack_level": "34" + }, + { + "spawn_animation": "7403", + "examine": "The ghost of a werewolf slain during the god wars.", + "melee_animation": "7397", + "range_animation": "7521", + "magic_level": "38", + "defence_animation": "7399", + "magic_animation": "7496", + "death_animation": "7398", + "name": "Revenant werewolf", + "defence_level": "38", + "safespot": null, + "lifepoints": "65", + "strength_level": "38", + "id": "6644", + "clue_level": "2", + "range_level": "38", + "attack_level": "38" + }, + { + "spawn_animation": "7457", + "examine": "The ghost of a cyclops slain during the god wars.", + "melee_animation": "7453", + "range_animation": "7510", + "magic_level": "43", + "defence_animation": "7455", + "weakness": "0", + "slayer_exp": "110", + "magic_animation": "7497", + "death_animation": "7454", + "name": "Revenant cyclops", + "defence_level": "43", + "safespot": null, + "lifepoints": "110", + "strength_level": "43", + "id": "6645", + "clue_level": "2", + "range_level": "43", + "attack_level": "43" + }, + { + "spawn_animation": "7464", + "examine": "The essence of a hellhound slain during the god wars.", + "melee_animation": "7460", + "range_animation": "7501", + "combat_audio": "3717,3719,3718", + "magic_level": "50", + "defence_animation": "7462", + "slayer_exp": "80", + "magic_animation": "7515", + "death_animation": "7461", + "name": "Revenant hellhound", + "defence_level": "1", + "safespot": null, + "lifepoints": "80", + "strength_level": "50", + "id": "6646", + "clue_level": "2", + "range_level": "50", + "attack_level": "50" + }, + { + "spawn_animation": "7478", + "examine": "The essence of a demon slain during the god wars.", + "melee_animation": "7474", + "range_animation": "7512", + "combat_audio": "400,404,403", + "magic_level": "60", + "defence_animation": "7476", + "slayer_exp": "80", + "magic_animation": "7498", + "death_animation": "7475", + "name": "Revenant demon", + "defence_level": "60", + "safespot": null, + "lifepoints": "80", + "strength_level": "60", + "id": "6647", + "clue_level": "2", + "range_level": "60", + "attack_level": "60" + }, + { + "examine": "A ghost of an ork slain during the god wars.", + "melee_animation": "7411", + "range_animation": "7518", + "magic_level": "70", + "defence_animation": "7413", + "magic_animation": "7505", + "death_animation": "7412", + "name": "Revenant ork", + "defence_level": "70", + "safespot": null, + "lifepoints": "105", + "strength_level": "70", + "id": "6648", + "clue_level": "2", + "range_level": "70", + "attack_level": "70" + }, + { + "spawn_animation": "7471", + "examine": "The ghost of a dark beast slain during the god wars.", + "melee_animation": "7467", + "range_animation": "7514", + "defence_animation": "7469", + "slayer_exp": "140", + "magic_animation": "7515", + "death_animation": "7468", + "name": "Revenant dark beast", + "defence_level": "80", + "safespot": null, + "lifepoints": "140", + "strength_level": "80", + "id": "6649", + "clue_level": "2", + "range_level": "80", + "attack_level": "80" + }, + { + "spawn_animation": "7440", + "examine": "A ghost of a knight slain during the god wars.", + "melee_animation": "7441", + "range_animation": "7522", + "poisonous": "true", + "magic_level": "80", + "defence_animation": "7443", + "slayer_exp": "143", + "poison_amount": "8", + "magic_animation": "7508", + "death_animation": "7442", + "name": "Revenant knight", + "defence_level": "80", + "safespot": null, + "lifepoints": "143", + "strength_level": "80", + "id": "6650", + "clue_level": "2", + "range_level": "80", + "attack_level": "80" + }, + { + "spawn_animation": "7447", + "examine": "The ghost of a goblin slain during the god wars.", + "melee_animation": "7449", + "range_animation": "7513", + "combat_audio": "469,472,471", + "magic_level": "12", + "defence_animation": "7450", + "magic_animation": "7499", + "death_animation": "7448", + "name": "Revenant goblin", + "defence_level": "12", + "safespot": null, + "lifepoints": "24", + "strength_level": "12", + "id": "6651", + "clue_level": "1", + "range_level": "12", + "attack_level": "12" + }, + { + "spawn_animation": "7426", + "examine": "The ghost of a vampire slain in the god wars.", + "melee_animation": "7427", + "range_animation": "7520", + "magic_level": "34", + "defence_animation": "7429", + "slayer_exp": "60", + "magic_animation": "7507", + "death_animation": "7428", + "name": "Revenant vampire", + "defence_level": "34", + "safespot": null, + "lifepoints": "60", + "strength_level": "34", + "id": "6652", + "clue_level": "1", + "range_level": "34", + "attack_level": "34" + }, + { + "examine": "A ghost of an ork slain during the god wars.", + "melee_animation": "7411", + "range_animation": "7518", + "magic_level": "70", + "defence_animation": "7413", + "magic_animation": "7505", + "death_animation": "7412", + "name": "Revenant ork", + "defence_level": "70", + "safespot": null, + "lifepoints": "105", + "strength_level": "70", + "id": "6653", + "clue_level": "2", + "range_level": "70", + "attack_level": "70" + }, + { + "spawn_animation": "7440", + "examine": "A ghost of a knight slain during the god wars.", + "melee_animation": "7441", + "range_animation": "7522", + "poisonous": "true", + "magic_level": "80", + "defence_animation": "7443", + "slayer_exp": "143", + "poison_amount": "8", + "magic_animation": "7508", + "death_animation": "7442", + "name": "Revenant knight", + "defence_level": "80", + "safespot": null, + "lifepoints": "143", + "strength_level": "80", + "id": "6654", + "clue_level": "2", + "range_level": "80", + "attack_level": "80" + }, + { + "spawn_animation": "7410", + "examine": "The essence of an imp slain during the god wars.", + "melee_animation": "7407", + "range_animation": "7501", + "combat_audio": "0,0,0", + "magic_level": "10", + "defence_animation": "7404", + "slayer_exp": "10", + "magic_animation": "7500", + "death_animation": "7408", + "name": "Revenant imp", + "defence_level": "10", + "safespot": null, + "lifepoints": "20", + "strength_level": "10", + "id": "6655", + "range_level": "10", + "attack_level": "10" + }, + { + "spawn_animation": "7447", + "examine": "The ghost of a goblin slain during the god wars.", + "melee_animation": "7449", + "range_animation": "7513", + "combat_audio": "469,472,471", + "magic_level": "12", + "defence_animation": "7450", + "magic_animation": "7499", + "death_animation": "7448", + "name": "Revenant goblin", + "defence_level": "12", + "safespot": null, + "lifepoints": "24", + "strength_level": "12", + "id": "6656", + "clue_level": "1", + "range_level": "12", + "attack_level": "12" + }, + { + "spawn_animation": "7447", + "examine": "The ghost of a goblin slain during the god wars.", + "melee_animation": "7449", + "range_animation": "7513", + "combat_audio": "469,472,471", + "magic_level": "22", + "defence_animation": "7450", + "magic_animation": "7499", + "death_animation": "7448", + "name": "Revenant goblin", + "defence_level": "22", + "safespot": null, + "lifepoints": "34", + "strength_level": "22", + "id": "6657", + "clue_level": "1", + "range_level": "22", + "attack_level": "22" + }, + { + "spawn_animation": "7447", + "examine": "The ghost of a goblin slain during the god wars.", + "melee_animation": "7449", + "range_animation": "7513", + "combat_audio": "469,472,471", + "magic_level": "12", + "defence_animation": "7450", + "magic_animation": "7499", + "death_animation": "7448", + "name": "Revenant goblin", + "defence_level": "12", + "safespot": null, + "lifepoints": "24", + "strength_level": "12", + "id": "6658", + "clue_level": "1", + "range_level": "12", + "attack_level": "12" + }, + { + "spawn_animation": "7485", + "examine": "The ghost of an icefiend slain during the God Wars.", + "melee_animation": "7481", + "range_animation": "7519", + "attack_speed": "3", + "magic_level": "27", + "defence_animation": "7483", + "slayer_exp": "40", + "magic_animation": "7506", + "death_animation": "7482", + "name": "Revenant icefiend", + "defence_level": "27", + "safespot": null, + "lifepoints": "40", + "strength_level": "27", + "id": "6659", + "clue_level": "1", + "range_level": "27", + "attack_level": "27" + }, + { + "spawn_animation": "7485", + "examine": "The essence of a pyrefiend slain during the god wars.", + "melee_animation": "7481", + "range_animation": "7519", + "attack_speed": "3", + "magic_level": "29", + "defence_animation": "7483", + "slayer_exp": "48", + "magic_animation": "7506", + "death_animation": "7482", + "name": "Revenant pyrefiend", + "defence_level": "29", + "safespot": null, + "lifepoints": "48", + "strength_level": "29", + "id": "6660", + "clue_level": "1", + "range_level": "29", + "attack_level": "29" + }, + { + "examine": "The ghost of a hobgoblin slain during the God Wars.", + "melee_animation": "7418", + "range_animation": "7516", + "combat_audio": "469,472,471", + "magic_level": "32", + "defence_animation": "7420", + "slayer_exp": "72", + "magic_animation": "7503", + "death_animation": "7419", + "name": "Revenant hobgoblin", + "defence_level": "32", + "safespot": null, + "lifepoints": "72", + "strength_level": "32", + "id": "6661", + "clue_level": "1", + "range_level": "32", + "attack_level": "32" + }, + { + "spawn_animation": "7426", + "examine": "The ghost of a vampire slain in the god wars.", + "melee_animation": "7427", + "range_animation": "7520", + "magic_level": "34", + "defence_animation": "7429", + "slayer_exp": "60", + "magic_animation": "7507", + "death_animation": "7428", + "name": "Revenant vampire", + "defence_level": "34", + "safespot": null, + "lifepoints": "60", + "strength_level": "34", + "id": "6662", + "clue_level": "1", + "range_level": "34", + "attack_level": "34" + }, + { + "spawn_animation": "7403", + "examine": "The ghost of a werewolf slain during the god wars.", + "melee_animation": "7397", + "range_animation": "7521", + "magic_level": "38", + "defence_animation": "7399", + "magic_animation": "7496", + "death_animation": "7398", + "name": "Revenant werewolf", + "defence_level": "38", + "safespot": null, + "lifepoints": "65", + "strength_level": "38", + "id": "6663", + "clue_level": "2", + "range_level": "38", + "attack_level": "38" + }, + { + "examine": "A ghost of an ork slain during the god wars.", + "melee_animation": "7411", + "range_animation": "7518", + "magic_level": "70", + "defence_animation": "7413", + "magic_animation": "7505", + "death_animation": "7412", + "name": "Revenant ork", + "defence_level": "70", + "safespot": null, + "lifepoints": "105", + "strength_level": "70", + "id": "6664", + "clue_level": "2", + "range_level": "70", + "attack_level": "70" + }, + { + "spawn_animation": "7440", + "examine": "A ghost of a knight slain during the god wars.", + "melee_animation": "7441", + "range_animation": "7522", + "poisonous": "true", + "magic_level": "80", + "defence_animation": "7443", + "slayer_exp": "143", + "poison_amount": "8", + "magic_animation": "7508", + "death_animation": "7442", + "name": "Revenant knight", + "defence_level": "80", + "safespot": null, + "lifepoints": "143", + "strength_level": "80", + "id": "6665", + "clue_level": "2", + "range_level": "80", + "attack_level": "80" + }, + { + "spawn_animation": "7410", + "examine": "The essence of an imp slain during the god wars.", + "melee_animation": "7407", + "range_animation": "7501", + "combat_audio": "0,0,0", + "magic_level": "10", + "defence_animation": "7404", + "slayer_exp": "10", + "magic_animation": "7500", + "death_animation": "7408", + "name": "Revenant imp", + "defence_level": "10", + "safespot": null, + "lifepoints": "20", + "strength_level": "10", + "id": "6666", + "range_level": "10", + "attack_level": "10" + }, + { + "spawn_animation": "7447", + "examine": "The ghost of a goblin slain during the god wars.", + "melee_animation": "7449", + "range_animation": "7513", + "combat_audio": "469,472,471", + "magic_level": "12", + "defence_animation": "7450", + "magic_animation": "7499", + "death_animation": "7448", + "name": "Revenant goblin", + "defence_level": "12", + "safespot": null, + "lifepoints": "24", + "strength_level": "12", + "id": "6667", + "clue_level": "1", + "range_level": "12", + "attack_level": "12" + }, + { + "spawn_animation": "7485", + "examine": "The essence of a pyrefiend slain during the god wars.", + "melee_animation": "7481", + "range_animation": "7519", + "attack_speed": "3", + "magic_level": "29", + "defence_animation": "7483", + "slayer_exp": "48", + "magic_animation": "7506", + "death_animation": "7482", + "name": "Revenant pyrefiend", + "defence_level": "29", + "safespot": null, + "lifepoints": "48", + "strength_level": "29", + "id": "6668", + "clue_level": "1", + "range_level": "29", + "attack_level": "29" + }, + { + "spawn_animation": "7426", + "examine": "The ghost of a vampire slain in the god wars.", + "melee_animation": "7427", + "range_animation": "7520", + "magic_level": "34", + "defence_animation": "7429", + "slayer_exp": "60", + "magic_animation": "7507", + "death_animation": "7428", + "name": "Revenant vampire", + "defence_level": "34", + "safespot": null, + "lifepoints": "60", + "strength_level": "34", + "id": "6669", + "clue_level": "1", + "range_level": "34", + "attack_level": "34" + }, + { + "examine": "A ghost of an ork slain during the god wars.", + "melee_animation": "7411", + "range_animation": "7518", + "magic_level": "70", + "defence_animation": "7413", + "magic_animation": "7505", + "death_animation": "7412", + "name": "Revenant ork", + "defence_level": "70", + "safespot": null, + "lifepoints": "105", + "strength_level": "70", + "id": "6670", + "clue_level": "2", + "range_level": "70", + "attack_level": "70" + }, + { + "spawn_animation": "7426", + "examine": "The ghost of a vampire slain in the god wars.", + "melee_animation": "7427", + "range_animation": "7520", + "magic_level": "34", + "defence_animation": "7429", + "slayer_exp": "60", + "magic_animation": "7507", + "death_animation": "7428", + "name": "Revenant vampire", + "defence_level": "34", + "safespot": null, + "lifepoints": "60", + "strength_level": "34", + "id": "6671", + "clue_level": "1", + "range_level": "34", + "attack_level": "34" + }, + { + "examine": "A ghost of an ork slain during the god wars.", + "melee_animation": "7411", + "range_animation": "7518", + "magic_level": "70", + "defence_animation": "7413", + "magic_animation": "7505", + "death_animation": "7412", + "name": "Revenant ork", + "defence_level": "70", + "safespot": null, + "lifepoints": "105", + "strength_level": "70", + "id": "6672", + "clue_level": "2", + "range_level": "70", + "attack_level": "70" + }, + { + "spawn_animation": "7440", + "examine": "A ghost of a knight slain during the god wars.", + "melee_animation": "7441", + "range_animation": "7522", + "poisonous": "true", + "magic_level": "80", + "defence_animation": "7443", + "slayer_exp": "143", + "poison_amount": "8", + "magic_animation": "7508", + "death_animation": "7442", + "name": "Revenant knight", + "defence_level": "80", + "safespot": null, + "lifepoints": "143", + "strength_level": "80", + "id": "6673", + "clue_level": "2", + "range_level": "80", + "attack_level": "80" + }, + { + "spawn_animation": "7426", + "examine": "The ghost of a vampire slain in the god wars.", + "melee_animation": "7427", + "range_animation": "7520", + "magic_level": "34", + "defence_animation": "7429", + "slayer_exp": "60", + "magic_animation": "7507", + "death_animation": "7428", + "name": "Revenant vampire", + "defence_level": "34", + "safespot": null, + "lifepoints": "60", + "strength_level": "34", + "id": "6674", + "clue_level": "1", + "range_level": "34", + "attack_level": "34" + }, + { + "spawn_animation": "7403", + "examine": "The ghost of a werewolf slain during the god wars.", + "melee_animation": "7397", + "range_animation": "7521", + "magic_level": "38", + "defence_animation": "7399", + "magic_animation": "7496", + "death_animation": "7398", + "name": "Revenant werewolf", + "defence_level": "38", + "safespot": null, + "lifepoints": "65", + "strength_level": "38", + "id": "6675", + "clue_level": "2", + "range_level": "38", + "attack_level": "38" + }, + { + "spawn_animation": "7440", + "examine": "A ghost of a knight slain during the god wars.", + "melee_animation": "7441", + "range_animation": "7522", + "poisonous": "true", + "magic_level": "80", + "defence_animation": "7443", + "slayer_exp": "143", + "poison_amount": "8", + "magic_animation": "7508", + "death_animation": "7442", + "name": "Revenant knight", + "defence_level": "80", + "safespot": null, + "lifepoints": "143", + "strength_level": "80", + "id": "6676", + "clue_level": "2", + "range_level": "80", + "attack_level": "80" + }, + { + "spawn_animation": "7410", + "examine": "The essence of an imp slain during the god wars.", + "melee_animation": "7407", + "range_animation": "7501", + "combat_audio": "0,0,0", + "magic_level": "10", + "defence_animation": "7404", + "slayer_exp": "10", + "magic_animation": "7500", + "death_animation": "7408", + "name": "Revenant imp", + "defence_level": "10", + "safespot": null, + "lifepoints": "20", + "strength_level": "10", + "id": "6677", + "range_level": "10", + "attack_level": "10" + }, + { + "spawn_animation": "7447", + "examine": "The ghost of a goblin slain during the god wars.", + "melee_animation": "7449", + "range_animation": "7513", + "combat_audio": "469,472,471", + "magic_level": "12", + "defence_animation": "7450", + "magic_animation": "7499", + "death_animation": "7448", + "name": "Revenant goblin", + "defence_level": "12", + "safespot": null, + "lifepoints": "24", + "strength_level": "12", + "id": "6678", + "clue_level": "1", + "range_level": "12", + "attack_level": "12" + }, + { + "spawn_animation": "7447", + "examine": "The ghost of a goblin slain during the god wars.", + "melee_animation": "7449", + "range_animation": "7513", + "combat_audio": "469,472,471", + "magic_level": "12", + "defence_animation": "7450", + "magic_animation": "7499", + "death_animation": "7448", + "name": "Revenant goblin", + "defence_level": "12", + "safespot": null, + "lifepoints": "24", + "strength_level": "12", + "id": "6679", + "clue_level": "1", + "range_level": "12", + "attack_level": "12" + }, + { + "spawn_animation": "7447", + "examine": "The ghost of a goblin slain during the god wars.", + "melee_animation": "7449", + "range_animation": "7513", + "combat_audio": "469,472,471", + "magic_level": "12", + "defence_animation": "7450", + "magic_animation": "7499", + "death_animation": "7448", + "name": "Revenant goblin", + "defence_level": "12", + "safespot": null, + "lifepoints": "24", + "strength_level": "12", + "id": "6680", + "clue_level": "1", + "range_level": "12", + "attack_level": "12" + }, + { + "spawn_animation": "7447", + "examine": "The ghost of a goblin slain during the god wars.", + "melee_animation": "7449", + "range_animation": "7513", + "combat_audio": "469,472,471", + "magic_level": "12", + "defence_animation": "7450", + "magic_animation": "7499", + "death_animation": "7448", + "name": "Revenant goblin", + "defence_level": "12", + "safespot": null, + "lifepoints": "24", + "strength_level": "12", + "id": "6681", + "clue_level": "1", + "range_level": "12", + "attack_level": "12" + }, + { + "spawn_animation": "7485", + "examine": "The ghost of an icefiend slain during the God Wars.", + "melee_animation": "7481", + "range_animation": "7519", + "attack_speed": "3", + "magic_level": "27", + "defence_animation": "7483", + "slayer_exp": "40", + "magic_animation": "7506", + "death_animation": "7482", + "name": "Revenant icefiend", + "defence_level": "27", + "safespot": null, + "lifepoints": "40", + "strength_level": "27", + "id": "6682", + "clue_level": "1", + "range_level": "27", + "attack_level": "27" + }, + { + "spawn_animation": "7485", + "examine": "The essence of a pyrefiend slain during the god wars.", + "melee_animation": "7481", + "range_animation": "7519", + "attack_speed": "3", + "magic_level": "29", + "defence_animation": "7483", + "slayer_exp": "48", + "magic_animation": "7506", + "death_animation": "7482", + "name": "Revenant pyrefiend", + "defence_level": "29", + "safespot": null, + "lifepoints": "48", + "strength_level": "29", + "id": "6683", + "clue_level": "1", + "range_level": "29", + "attack_level": "29" + }, + { + "examine": "The ghost of a hobgoblin slain during the God Wars.", + "melee_animation": "7418", + "range_animation": "7516", + "combat_audio": "469,472,471", + "magic_level": "32", + "defence_animation": "7420", + "slayer_exp": "72", + "magic_animation": "7503", + "death_animation": "7419", + "name": "Revenant hobgoblin", + "defence_level": "32", + "safespot": null, + "lifepoints": "72", + "strength_level": "32", + "id": "6684", + "clue_level": "1", + "range_level": "32", + "attack_level": "32" + }, + { + "spawn_animation": "7426", + "examine": "The ghost of a vampire slain in the god wars.", + "melee_animation": "7427", + "range_animation": "7520", + "magic_level": "34", + "defence_animation": "7429", + "slayer_exp": "60", + "magic_animation": "7507", + "death_animation": "7428", + "name": "Revenant vampire", + "defence_level": "34", + "safespot": null, + "lifepoints": "60", + "strength_level": "34", + "id": "6685", + "clue_level": "1", + "range_level": "34", + "attack_level": "34" + }, + { + "spawn_animation": "7403", + "examine": "The ghost of a werewolf slain during the god wars.", + "melee_animation": "7397", + "range_animation": "7521", + "magic_level": "38", + "defence_animation": "7399", + "magic_animation": "7496", + "death_animation": "7398", + "name": "Revenant werewolf", + "defence_level": "38", + "safespot": null, + "lifepoints": "65", + "strength_level": "38", + "id": "6686", + "clue_level": "2", + "range_level": "38", + "attack_level": "38" + }, + { + "spawn_animation": "7457", + "examine": "The ghost of a cyclops slain during the god wars.", + "melee_animation": "7453", + "range_animation": "7510", + "magic_level": "43", + "defence_animation": "7455", + "weakness": "0", + "slayer_exp": "110", + "magic_animation": "7497", + "death_animation": "7454", + "name": "Revenant cyclops", + "defence_level": "43", + "safespot": null, + "lifepoints": "110", + "strength_level": "43", + "id": "6687", + "clue_level": "2", + "range_level": "43", + "attack_level": "43" + }, + { + "spawn_animation": "7464", + "examine": "The essence of a hellhound slain during the god wars.", + "melee_animation": "7460", + "range_animation": "7501", + "combat_audio": "3717,3719,3718", + "magic_level": "50", + "defence_animation": "7462", + "slayer_exp": "80", + "magic_animation": "7515", + "death_animation": "7461", + "name": "Revenant hellhound", + "defence_level": "1", + "safespot": null, + "lifepoints": "80", + "strength_level": "50", + "id": "6688", + "clue_level": "2", + "range_level": "50", + "attack_level": "50" + }, + { + "spawn_animation": "7478", + "examine": "The essence of a demon slain during the god wars.", + "melee_animation": "7474", + "range_animation": "7512", + "combat_audio": "400,404,403", + "magic_level": "60", + "defence_animation": "7476", + "slayer_exp": "80", + "magic_animation": "7498", + "death_animation": "7475", + "name": "Revenant demon", + "defence_level": "60", + "safespot": null, + "lifepoints": "80", + "strength_level": "60", + "id": "6689", + "clue_level": "2", + "range_level": "60", + "attack_level": "60" + }, + { + "examine": "A ghost of an ork slain during the god wars.", + "melee_animation": "7411", + "range_animation": "7518", + "magic_level": "70", + "defence_animation": "7413", + "magic_animation": "7505", + "death_animation": "7412", + "name": "Revenant ork", + "defence_level": "70", + "safespot": null, + "lifepoints": "105", + "strength_level": "70", + "id": "6690", + "clue_level": "2", + "range_level": "70", + "attack_level": "70" + }, + { + "spawn_animation": "7471", + "examine": "The ghost of a dark beast slain during the god wars.", + "melee_animation": "7467", + "range_animation": "7514", + "defence_animation": "7469", + "slayer_exp": "140", + "magic_animation": "7515", + "death_animation": "7468", + "name": "Revenant dark beast", + "defence_level": "80", + "safespot": null, + "lifepoints": "140", + "strength_level": "80", + "id": "6691", + "clue_level": "2", + "range_level": "80", + "attack_level": "80" + }, + { + "spawn_animation": "7440", + "examine": "A ghost of a knight slain during the god wars.", + "melee_animation": "7441", + "range_animation": "7522", + "poisonous": "true", + "magic_level": "80", + "defence_animation": "7443", + "slayer_exp": "143", + "poison_amount": "8", + "magic_animation": "7508", + "death_animation": "7442", + "name": "Revenant knight", + "defence_level": "80", + "safespot": null, + "lifepoints": "143", + "strength_level": "80", + "id": "6692", + "clue_level": "2", + "range_level": "80", + "attack_level": "80" + }, + { + "spawn_animation": "7447", + "examine": "The ghost of a goblin slain during the god wars.", + "melee_animation": "7449", + "range_animation": "7513", + "combat_audio": "469,472,471", + "magic_level": "12", + "defence_animation": "7450", + "magic_animation": "7499", + "death_animation": "7448", + "name": "Revenant goblin", + "defence_level": "12", + "safespot": null, + "lifepoints": "24", + "strength_level": "12", + "id": "6693", + "clue_level": "1", + "range_level": "12", + "attack_level": "12" + }, + { + "spawn_animation": "7485", + "examine": "The ghost of an icefiend slain during the God Wars.", + "melee_animation": "7481", + "range_animation": "7519", + "attack_speed": "3", + "magic_level": "27", + "defence_animation": "7483", + "slayer_exp": "40", + "magic_animation": "7506", + "death_animation": "7482", + "name": "Revenant icefiend", + "defence_level": "27", + "safespot": null, + "lifepoints": "40", + "strength_level": "27", + "id": "6694", + "clue_level": "1", + "range_level": "27", + "attack_level": "27" + }, + { + "spawn_animation": "7426", + "examine": "The ghost of a vampire slain in the god wars.", + "melee_animation": "7427", + "range_animation": "7520", + "magic_level": "34", + "defence_animation": "7429", + "slayer_exp": "60", + "magic_animation": "7507", + "death_animation": "7428", + "name": "Revenant vampire", + "defence_level": "34", + "safespot": null, + "lifepoints": "60", + "strength_level": "34", + "id": "6695", + "clue_level": "1", + "range_level": "34", + "attack_level": "34" + }, + { + "examine": "A ghost of an ork slain during the god wars.", + "melee_animation": "7411", + "range_animation": "7518", + "magic_level": "70", + "defence_animation": "7413", + "magic_animation": "7505", + "death_animation": "7412", + "name": "Revenant ork", + "defence_level": "70", + "safespot": null, + "lifepoints": "105", + "strength_level": "70", + "id": "6696", + "clue_level": "2", + "range_level": "70", + "attack_level": "70" + }, + { + "spawn_animation": "7410", + "examine": "The essence of an imp slain during the god wars.", + "melee_animation": "7407", + "range_animation": "7501", + "combat_audio": "0,0,0", + "magic_level": "10", + "defence_animation": "7404", + "slayer_exp": "10", + "magic_animation": "7500", + "death_animation": "7408", + "name": "Revenant imp", + "defence_level": "10", + "safespot": null, + "lifepoints": "20", + "strength_level": "10", + "id": "6697", + "range_level": "10", + "attack_level": "10" + }, + { + "spawn_animation": "7447", + "examine": "The ghost of a goblin slain during the god wars.", + "melee_animation": "7449", + "range_animation": "7513", + "combat_audio": "469,472,471", + "magic_level": "12", + "defence_animation": "7450", + "magic_animation": "7499", + "death_animation": "7448", + "name": "Revenant goblin", + "defence_level": "12", + "safespot": null, + "lifepoints": "24", + "strength_level": "12", + "id": "6698", + "clue_level": "1", + "range_level": "12", + "attack_level": "12" + }, + { + "spawn_animation": "7447", + "examine": "The ghost of a goblin slain during the god wars.", + "melee_animation": "7449", + "range_animation": "7513", + "combat_audio": "469,472,471", + "magic_level": "12", + "defence_animation": "7450", + "magic_animation": "7499", + "death_animation": "7448", + "name": "Revenant goblin", + "defence_level": "12", + "safespot": null, + "lifepoints": "24", + "strength_level": "12", + "id": "6699", + "clue_level": "1", + "range_level": "12", + "attack_level": "12" + }, + { + "spawn_animation": "7426", + "examine": "The ghost of a vampire slain in the god wars.", + "melee_animation": "7427", + "range_animation": "7520", + "magic_level": "34", + "defence_animation": "7429", + "slayer_exp": "60", + "magic_animation": "7507", + "death_animation": "7428", + "name": "Revenant vampire", + "defence_level": "34", + "safespot": null, + "lifepoints": "60", + "strength_level": "34", + "id": "6700", + "clue_level": "1", + "range_level": "34", + "attack_level": "34" + }, + { + "spawn_animation": "7403", + "examine": "The ghost of a werewolf slain during the god wars.", + "melee_animation": "7397", + "range_animation": "7521", + "magic_level": "38", + "defence_animation": "7399", + "magic_animation": "7496", + "death_animation": "7398", + "name": "Revenant werewolf", + "defence_level": "38", + "safespot": null, + "lifepoints": "65", + "strength_level": "38", + "id": "6701", + "clue_level": "2", + "range_level": "38", + "attack_level": "38" + }, + { + "examine": "A ghost of an ork slain during the god wars.", + "melee_animation": "7411", + "range_animation": "7518", + "magic_level": "70", + "defence_animation": "7413", + "magic_animation": "7505", + "death_animation": "7412", + "name": "Revenant ork", + "defence_level": "70", + "safespot": null, + "lifepoints": "105", + "strength_level": "70", + "id": "6702", + "clue_level": "2", + "range_level": "70", + "attack_level": "70" + }, + { + "spawn_animation": "7410", + "examine": "The essence of an imp slain during the god wars.", + "melee_animation": "7407", + "range_animation": "7501", + "combat_audio": "0,0,0", + "magic_level": "10", + "defence_animation": "7404", + "slayer_exp": "10", + "magic_animation": "7500", + "death_animation": "7408", + "name": "Revenant imp", + "defence_level": "10", + "safespot": null, + "lifepoints": "20", + "strength_level": "10", + "id": "6703", + "range_level": "10", + "attack_level": "10" + }, + { + "spawn_animation": "7447", + "examine": "The ghost of a goblin slain during the god wars.", + "melee_animation": "7449", + "range_animation": "7513", + "combat_audio": "469,472,471", + "magic_level": "12", + "defence_animation": "7450", + "magic_animation": "7499", + "death_animation": "7448", + "name": "Revenant goblin", + "defence_level": "12", + "safespot": null, + "lifepoints": "24", + "strength_level": "12", + "id": "6704", + "clue_level": "1", + "range_level": "12", + "attack_level": "12" + }, + { + "spawn_animation": "7447", + "examine": "The ghost of a goblin slain during the god wars.", + "melee_animation": "7449", + "range_animation": "7513", + "combat_audio": "469,472,471", + "magic_level": "12", + "defence_animation": "7450", + "magic_animation": "7499", + "death_animation": "7448", + "name": "Revenant goblin", + "defence_level": "12", + "safespot": null, + "lifepoints": "24", + "strength_level": "12", + "id": "6705", + "clue_level": "1", + "range_level": "12", + "attack_level": "12" + }, + { + "spawn_animation": "7447", + "examine": "The ghost of a goblin slain during the god wars.", + "melee_animation": "7449", + "range_animation": "7513", + "combat_audio": "469,472,471", + "magic_level": "12", + "defence_animation": "7450", + "magic_animation": "7499", + "death_animation": "7448", + "name": "Revenant goblin", + "defence_level": "12", + "safespot": null, + "lifepoints": "24", + "strength_level": "12", + "id": "6706", + "clue_level": "1", + "range_level": "12", + "attack_level": "12" + }, + { + "spawn_animation": "7447", + "examine": "The ghost of a goblin slain during the god wars.", + "melee_animation": "7449", + "range_animation": "7513", + "combat_audio": "469,472,471", + "magic_level": "12", + "defence_animation": "7450", + "magic_animation": "7499", + "death_animation": "7448", + "name": "Revenant goblin", + "defence_level": "12", + "safespot": null, + "lifepoints": "24", + "strength_level": "12", + "id": "6707", + "clue_level": "1", + "range_level": "12", + "attack_level": "12" + }, + { + "spawn_animation": "7485", + "examine": "The ghost of an icefiend slain during the God Wars.", + "melee_animation": "7481", + "range_animation": "7519", + "attack_speed": "3", + "magic_level": "27", + "defence_animation": "7483", + "slayer_exp": "40", + "magic_animation": "7506", + "death_animation": "7482", + "name": "Revenant icefiend", + "defence_level": "27", + "safespot": null, + "lifepoints": "40", + "strength_level": "27", + "id": "6708", + "clue_level": "1", + "range_level": "27", + "attack_level": "27" + }, + { + "spawn_animation": "7485", + "examine": "The essence of a pyrefiend slain during the god wars.", + "melee_animation": "7481", + "range_animation": "7519", + "attack_speed": "3", + "magic_level": "29", + "defence_animation": "7483", + "slayer_exp": "48", + "magic_animation": "7506", + "death_animation": "7482", + "name": "Revenant pyrefiend", + "defence_level": "29", + "safespot": null, + "lifepoints": "48", + "strength_level": "29", + "id": "6709", + "clue_level": "1", + "range_level": "29", + "attack_level": "29" + }, + { + "examine": "The ghost of a hobgoblin slain during the God Wars.", + "melee_animation": "7418", + "range_animation": "7516", + "combat_audio": "469,472,471", + "magic_level": "32", + "defence_animation": "7420", + "slayer_exp": "72", + "magic_animation": "7503", + "death_animation": "7419", + "name": "Revenant hobgoblin", + "defence_level": "32", + "safespot": null, + "lifepoints": "72", + "strength_level": "32", + "id": "6710", + "clue_level": "1", + "range_level": "32", + "attack_level": "32" + }, + { + "spawn_animation": "7426", + "examine": "The ghost of a vampire slain in the god wars.", + "melee_animation": "7427", + "range_animation": "7520", + "magic_level": "34", + "defence_animation": "7429", + "slayer_exp": "60", + "magic_animation": "7507", + "death_animation": "7428", + "name": "Revenant vampire", + "defence_level": "34", + "safespot": null, + "lifepoints": "60", + "strength_level": "34", + "id": "6711", + "clue_level": "1", + "range_level": "34", + "attack_level": "34" + }, + { + "spawn_animation": "7403", + "examine": "The ghost of a werewolf slain during the god wars.", + "melee_animation": "7397", + "range_animation": "7521", + "magic_level": "38", + "defence_animation": "7399", + "magic_animation": "7496", + "death_animation": "7398", + "name": "Revenant werewolf", + "defence_level": "38", + "safespot": null, + "lifepoints": "65", + "strength_level": "38", + "id": "6712", + "clue_level": "2", + "range_level": "38", + "attack_level": "38" + }, + { + "examine": "A ghost of an ork slain during the god wars.", + "melee_animation": "7411", + "range_animation": "7518", + "magic_level": "70", + "defence_animation": "7413", + "magic_animation": "7505", + "death_animation": "7412", + "name": "Revenant ork", + "defence_level": "70", + "safespot": null, + "lifepoints": "105", + "strength_level": "70", + "id": "6713", + "clue_level": "2", + "range_level": "70", + "attack_level": "70" + }, + { + "spawn_animation": "7440", + "examine": "A ghost of a knight slain during the god wars.", + "melee_animation": "7441", + "range_animation": "7522", + "poisonous": "true", + "magic_level": "80", + "defence_animation": "7443", + "slayer_exp": "143", + "poison_amount": "8", + "magic_animation": "7508", + "death_animation": "7442", + "name": "Revenant knight", + "defence_level": "80", + "safespot": null, + "lifepoints": "143", + "strength_level": "80", + "id": "6714", + "clue_level": "2", + "range_level": "80", + "attack_level": "80" + }, + { + "spawn_animation": "7410", + "examine": "The essence of an imp slain during the god wars.", + "melee_animation": "7407", + "range_animation": "7501", + "combat_audio": "0,0,0", + "magic_level": "10", + "defence_animation": "7404", + "slayer_exp": "10", + "magic_animation": "7500", + "death_animation": "7408", + "name": "Revenant imp", + "defence_level": "10", + "safespot": null, + "lifepoints": "20", + "strength_level": "10", + "id": "6715", + "range_level": "10", + "attack_level": "10" + }, + { + "spawn_animation": "7447", + "examine": "The ghost of a goblin slain during the god wars.", + "melee_animation": "7449", + "range_animation": "7513", + "combat_audio": "469,472,471", + "magic_level": "12", + "defence_animation": "7450", + "magic_animation": "7499", + "death_animation": "7448", + "name": "Revenant goblin", + "defence_level": "12", + "safespot": null, + "lifepoints": "24", + "strength_level": "12", + "id": "6716", + "clue_level": "1", + "range_level": "12", + "attack_level": "12" + }, + { + "spawn_animation": "7447", + "examine": "The ghost of a goblin slain during the god wars.", + "melee_animation": "7449", + "range_animation": "7513", + "combat_audio": "469,472,471", + "magic_level": "12", + "defence_animation": "7450", + "magic_animation": "7499", + "death_animation": "7448", + "name": "Revenant goblin", + "defence_level": "12", + "safespot": null, + "lifepoints": "24", + "strength_level": "12", + "id": "6717", + "clue_level": "1", + "range_level": "12", + "attack_level": "12" + }, + { + "spawn_animation": "7447", + "examine": "The ghost of a goblin slain during the god wars.", + "melee_animation": "7449", + "range_animation": "7513", + "combat_audio": "469,472,471", + "magic_level": "12", + "defence_animation": "7450", + "magic_animation": "7499", + "death_animation": "7448", + "name": "Revenant goblin", + "defence_level": "12", + "safespot": null, + "lifepoints": "24", + "strength_level": "12", + "id": "6718", + "clue_level": "1", + "range_level": "12", + "attack_level": "12" + }, + { + "spawn_animation": "7447", + "examine": "The ghost of a goblin slain during the god wars.", + "melee_animation": "7449", + "range_animation": "7513", + "combat_audio": "469,472,471", + "magic_level": "12", + "defence_animation": "7450", + "magic_animation": "7499", + "death_animation": "7448", + "name": "Revenant goblin", + "defence_level": "12", + "safespot": null, + "lifepoints": "24", + "strength_level": "12", + "id": "6719", + "clue_level": "1", + "range_level": "12", + "attack_level": "12" + }, + { + "spawn_animation": "7485", + "examine": "The ghost of an icefiend slain during the God Wars.", + "melee_animation": "7481", + "range_animation": "7519", + "attack_speed": "3", + "magic_level": "27", + "defence_animation": "7483", + "slayer_exp": "40", + "magic_animation": "7506", + "death_animation": "7482", + "name": "Revenant icefiend", + "defence_level": "27", + "safespot": null, + "lifepoints": "40", + "strength_level": "27", + "id": "6720", + "clue_level": "1", + "range_level": "27", + "attack_level": "27" + }, + { + "spawn_animation": "7485", + "examine": "The essence of a pyrefiend slain during the god wars.", + "melee_animation": "7481", + "range_animation": "7519", + "attack_speed": "3", + "magic_level": "29", + "defence_animation": "7483", + "slayer_exp": "48", + "magic_animation": "7506", + "death_animation": "7482", + "name": "Revenant pyrefiend", + "defence_level": "29", + "safespot": null, + "lifepoints": "48", + "strength_level": "29", + "id": "6721", + "clue_level": "1", + "range_level": "29", + "attack_level": "29" + }, + { + "examine": "The ghost of a hobgoblin slain during the God Wars.", + "melee_animation": "7418", + "range_animation": "7516", + "combat_audio": "469,472,471", + "magic_level": "32", + "defence_animation": "7420", + "slayer_exp": "72", + "magic_animation": "7503", + "death_animation": "7419", + "name": "Revenant hobgoblin", + "defence_level": "32", + "safespot": null, + "lifepoints": "72", + "strength_level": "32", + "id": "6722", + "clue_level": "1", + "range_level": "32", + "attack_level": "32" + }, + { + "spawn_animation": "7426", + "examine": "The ghost of a vampire slain in the god wars.", + "melee_animation": "7427", + "range_animation": "7520", + "magic_level": "34", + "defence_animation": "7429", + "slayer_exp": "60", + "magic_animation": "7507", + "death_animation": "7428", + "name": "Revenant vampire", + "defence_level": "34", + "safespot": null, + "lifepoints": "60", + "strength_level": "34", + "id": "6723", + "clue_level": "1", + "range_level": "34", + "attack_level": "34" + }, + { + "spawn_animation": "7403", + "examine": "The ghost of a werewolf slain during the god wars.", + "melee_animation": "7397", + "range_animation": "7521", + "magic_level": "38", + "defence_animation": "7399", + "magic_animation": "7496", + "death_animation": "7398", + "name": "Revenant werewolf", + "defence_level": "38", + "safespot": null, + "lifepoints": "65", + "strength_level": "38", + "id": "6724", + "clue_level": "2", + "range_level": "38", + "attack_level": "38" + }, + { + "examine": "A ghost of an ork slain during the god wars.", + "melee_animation": "7411", + "range_animation": "7518", + "magic_level": "70", + "defence_animation": "7413", + "magic_animation": "7505", + "death_animation": "7412", + "name": "Revenant ork", + "defence_level": "70", + "safespot": null, + "lifepoints": "105", + "strength_level": "70", + "id": "6725", + "clue_level": "2", + "range_level": "70", + "attack_level": "70" + }, + { + "spawn_animation": "7440", + "examine": "A ghost of a knight slain during the god wars.", + "melee_animation": "7441", + "range_animation": "7522", + "poisonous": "true", + "magic_level": "80", + "defence_animation": "7443", + "slayer_exp": "143", + "poison_amount": "8", + "magic_animation": "7508", + "death_animation": "7442", + "name": "Revenant knight", + "defence_level": "80", + "safespot": null, + "lifepoints": "143", + "strength_level": "80", + "id": "6726", + "clue_level": "2", + "range_level": "80", + "attack_level": "80" + }, + { + "examine": "The ghost of a hobgoblin slain during the God Wars.", + "melee_animation": "7418", + "range_animation": "7516", + "combat_audio": "469,472,471", + "magic_level": "32", + "defence_animation": "7420", + "slayer_exp": "72", + "magic_animation": "7503", + "death_animation": "7419", + "name": "Revenant hobgoblin", + "defence_level": "32", + "safespot": null, + "lifepoints": "72", + "strength_level": "32", + "id": "6727", + "clue_level": "1", + "range_level": "32", + "attack_level": "32" + }, + { + "spawn_animation": "7403", + "examine": "The ghost of a werewolf slain during the god wars.", + "melee_animation": "7397", + "range_animation": "7521", + "magic_level": "38", + "defence_animation": "7399", + "magic_animation": "7496", + "death_animation": "7398", + "name": "Revenant werewolf", + "defence_level": "38", + "safespot": null, + "lifepoints": "65", + "strength_level": "38", + "id": "6728", + "clue_level": "2", + "range_level": "38", + "attack_level": "38" + }, + { + "examine": "A ghost of an ork slain during the god wars.", + "melee_animation": "7411", + "range_animation": "7518", + "magic_level": "70", + "defence_animation": "7413", + "magic_animation": "7505", + "death_animation": "7412", + "name": "Revenant ork", + "defence_level": "70", + "safespot": null, + "lifepoints": "105", + "strength_level": "70", + "id": "6729", + "clue_level": "2", + "range_level": "70", + "attack_level": "70" + }, + { + "spawn_animation": "7440", + "examine": "A ghost of a knight slain during the god wars.", + "melee_animation": "7441", + "range_animation": "7522", + "poisonous": "true", + "magic_level": "80", + "defence_animation": "7443", + "slayer_exp": "143", + "poison_amount": "8", + "magic_animation": "7508", + "death_animation": "7442", + "name": "Revenant knight", + "defence_level": "80", + "safespot": null, + "lifepoints": "143", + "strength_level": "80", + "id": "6730", + "clue_level": "2", + "range_level": "80", + "attack_level": "80" + }, + { + "examine": "Her lack of body heat is unsettling.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Queen of Snow", + "defence_level": "1", + "movement_radius": "5", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6731", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It looks right at home here.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Snow imp", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6739", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Snowflakes swirling in the wind.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Snow", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6740", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A snowman in fake dragon armour.", + "combat_audio": "29,3295,3287", + "melee_animation": "7558", + "defence_animation": "7559", + "death_animation": "7560", + "name": "Dragon snowman", + "defence_level": "1", + "safespot": null, + "lifepoints": "20", + "strength_level": "1", + "id": "6743", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Arr!", + "combat_audio": "29,3295,3287", + "melee_animation": "7558", + "defence_animation": "7559", + "death_animation": "7560", + "name": "Pirate snowman", + "defence_level": "1", + "safespot": null, + "lifepoints": "20", + "strength_level": "1", + "id": "6745", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A snowman armed with a holly bow.", + "name": "Snow ranger", + "defence_level": "10", + "safespot": null, + "lifepoints": "30", + "strength_level": "1", + "id": "6747", + "range_level": "30", + "attack_level": "30" + }, + { + "examine": "A snowman armed with an ice sword.", + "name": "Snow ranger", + "defence_level": "10", + "safespot": null, + "lifepoints": "20", + "strength_level": "1", + "id": "6748", + "magic_level": "30", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "A snowman armed with a winter staff.", + "name": "Snow mage", + "defence_level": "10", + "safespot": null, + "lifepoints": "20", + "strength_level": "1", + "id": "6749", + "range_level": "30", + "attack_level": "30" + }, + { + "examine": "Cut-down and dried.", + "melee_animation": "5568", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "5569", + "name": "Dried zombie", + "defence_level": "48", + "safespot": null, + "lifepoints": "68", + "strength_level": "48", + "id": "6761", + "range_level": "1", + "attack_level": "48" + }, + { + "examine": "Needs moisturising.", + "melee_animation": "5568", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "5569", + "name": "Dried zombie", + "defence_level": "48", + "safespot": null, + "lifepoints": "68", + "strength_level": "48", + "id": "6762", + "range_level": "1", + "attack_level": "48" + }, + { + "examine": "I bet it's parched.", + "melee_animation": "5568", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "5569", + "name": "Dried zombie", + "defence_level": "48", + "safespot": null, + "lifepoints": "68", + "strength_level": "48", + "id": "6763", + "range_level": "1", + "attack_level": "48" + }, + { + "examine": "A guard.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Doorman", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6769", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A huge beast of a beetle.", + "melee_animation": "7596", + "range_animation": "0", + "defence_animation": "0", + "weakness": "2", + "magic_animation": "0", + "death_animation": "7595", + "name": "Giant scarab", + "defence_level": "66", + "safespot": null, + "lifepoints": "285", + "strength_level": "49", + "id": "6770", + "aggressive": "true", + "range_level": "66", + "attack_level": "49" + }, + { + "examine": "It's not quite small enough to stamp upon.", + "melee_animation": "7657", + "range_animation": "0", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "7656", + "name": "Scarab larva", + "defence_level": "18", + "safespot": null, + "lifepoints": "25", + "strength_level": "18", + "id": "6772", + "range_level": "1", + "attack_level": "18" + }, + { + "examine": "Bred to shoot you down.", + "start_gfx": "18", + "combat_style": "1", + "melee_animation": "7607", + "range_animation": "7607", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "2", + "magic_animation": "0", + "death_animation": "7609", + "name": "Scabaras ranger", + "defence_level": "55", + "safespot": null, + "lifepoints": "157", + "strength_level": "41", + "id": "6773", + "aggressive": "true", + "range_level": "55", + "projectile": "11", + "attack_level": "41" + }, + { + "examine": "It might be angry...it's hard to tell.", + "melee_animation": "7612", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "7614", + "name": "Scabaras lancer", + "defence_level": "55", + "safespot": null, + "lifepoints": "78", + "strength_level": "55", + "id": "6774", + "aggressive": "true", + "range_level": "1", + "attack_level": "55" + }, + { + "examine": "A giant, mountable locust.", + "melee_animation": "7586", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "2", + "magic_animation": "0", + "death_animation": "7581", + "name": "Scabaras locust", + "defence_level": "55", + "safespot": null, + "lifepoints": "78", + "strength_level": "41", + "id": "6776", + "aggressive": "true", + "range_level": "55", + "attack_level": "41" + }, + { + "examine": "Bouncy", + "melee_animation": "7584", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "7581", + "name": "Locust lancer", + "defence_level": "55", + "safespot": null, + "lifepoints": "78", + "strength_level": "55", + "id": "6777", + "aggressive": "true", + "range_level": "1", + "attack_level": "55" + }, + { + "examine": "He'll have someone's eye out with that.", + "start_gfx": "18", + "combat_style": "1", + "melee_animation": "5451", + "range_animation": "5451", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "2", + "magic_animation": "0", + "death_animation": "7581", + "name": "Locust ranger", + "defence_level": "55", + "safespot": null, + "lifepoints": "78", + "strength_level": "41", + "id": "6778", + "aggressive": "true", + "range_level": "55", + "projectile": "11", + "attack_level": "41" + }, + { + "melee_animation": "7588", + "combat_audio": "386,388,387", + "attack_speed": "6", + "respawn_delay": "60", + "defence_animation": "7590", + "slayer_exp": "62", + "death_animation": "7591", + "name": "Crocodile", + "defence_level": "1", + "safespot": null, + "lifepoints": "72", + "strength_level": "1", + "id": "6779", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Part scarab, part man.", + "combat_style": "2", + "melee_animation": "7615", + "range_animation": "0", + "magic_level": "55", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "4", + "magic_animation": "0", + "death_animation": "7616", + "name": "Scabaras mage", + "defence_level": "55", + "safespot": null, + "lifepoints": "78", + "strength_level": "41", + "id": "6780", + "aggressive": "true", + "range_level": "1", + "attack_level": "41" + }, + { + "examine": "Part scarab, part man.", + "combat_style": "2", + "melee_animation": "7620", + "respawn_delay": "60", + "defence_animation": "7617", + "death_animation": "7616", + "name": "Scabaras mage", + "defence_level": "1", + "safespot": null, + "lifepoints": "70", + "strength_level": "1", + "id": "6781", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An animated clay statue.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Clay golem", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6785", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "She looks a bit dirty from digging.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Lead archaeologist Abigail", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6786", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He looks a bit dusty from troweling.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Assistant archaeologist Kerner", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6787", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He exudes something like holiness.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "High Priest of Scabaras", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6788", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He exudes something like holiness.", + "melee_animation": "7612", + "range_animation": "0", + "magic_level": "66", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7614", + "name": "High Priest of Scabaras", + "defence_level": "66", + "safespot": null, + "lifepoints": "94", + "strength_level": "66", + "id": "6789", + "range_level": "66", + "attack_level": "66" + }, + { + "examine": "He exudes something like holiness.", + "melee_animation": "7607", + "range_animation": "7607", + "magic_level": "66", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7609", + "name": "High Priest of Scabaras", + "defence_level": "66", + "safespot": null, + "lifepoints": "94", + "strength_level": "66", + "id": "6790", + "range_level": "66", + "attack_level": "66" + }, + { + "examine": "A bird. Literally terrifying.", + "melee_animation": "1010", + "range_animation": "0", + "magic_level": "50", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "1013", + "name": "Spirit terrorbird", + "defence_level": "50", + "safespot": null, + "lifepoints": "74", + "strength_level": "50", + "id": "6794", + "range_level": "50", + "attack_level": "50" + }, + { + "examine": "A bird. Literally terrifying.", + "melee_animation": "1010", + "range_animation": "0", + "magic_level": "50", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "1013", + "name": "Spirit terrorbird", + "defence_level": "50", + "safespot": null, + "lifepoints": "74", + "strength_level": "50", + "id": "6795", + "range_level": "50", + "attack_level": "50" + }, + { + "examine": "Is it a stone? Is it a crab? No! It's Granite Crab!", + "melee_animation": "8104", + "range_animation": "8104", + "attack_speed": "3", + "magic_level": "13", + "respawn_delay": "50", + "defence_animation": "8105", + "magic_animation": "8104", + "death_animation": "8106", + "name": "Granite crab", + "defence_level": "22", + "safespot": null, + "lifepoints": "39", + "strength_level": "17", + "id": "6796", + "bonuses": "16,9,5,12,4,11,57,53,61,12,45,22,0,0,0", + "range_level": "16", + "attack_level": "18" + }, + { + "examine": "Is it a stone? Is it a crab? No! It's Granite Crab!", + "melee_animation": "8104", + "range_animation": "8104", + "attack_speed": "3", + "magic_level": "13", + "respawn_delay": "50", + "defence_animation": "8105", + "weakness": "10", + "magic_animation": "8104", + "death_animation": "8106", + "name": "Granite crab", + "defence_level": "22", + "safespot": null, + "lifepoints": "39", + "strength_level": "17", + "id": "6797", + "bonuses": "16,9,5,12,4,11,57,53,61,12,45,22,0,0,0", + "range_level": "16", + "attack_level": "18" + }, + { + "examine": "Wax on", + "melee_animation": "8069", + "range_animation": "0", + "magic_level": "60", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "8065", + "name": "Praying mantis", + "defence_level": "60", + "safespot": null, + "lifepoints": "107", + "strength_level": "60", + "id": "6798", + "range_level": "60", + "attack_level": "60" + }, + { + "examine": "Wax on", + "melee_animation": "8069", + "range_animation": "0", + "magic_level": "60", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "8065", + "name": "Praying mantis", + "defence_level": "60", + "safespot": null, + "lifepoints": "107", + "strength_level": "60", + "id": "6799", + "range_level": "60", + "attack_level": "60" + }, + { + "examine": "He ent such a bad guy.", + "melee_animation": "7853", + "range_animation": "0", + "magic_level": "60", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7854", + "name": "Giant ent", + "defence_level": "60", + "safespot": null, + "lifepoints": "111", + "strength_level": "60", + "id": "6800", + "range_level": "60", + "attack_level": "60" + }, + { + "examine": "He ent such a bad guy.", + "melee_animation": "7853", + "range_animation": "0", + "magic_level": "60", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7854", + "name": "Giant ent", + "defence_level": "60", + "safespot": null, + "lifepoints": "111", + "strength_level": "60", + "id": "6801", + "range_level": "60", + "attack_level": "60" + }, + { + "examine": "Serpentine.", + "melee_animation": "8152", + "range_animation": "0", + "magic_level": "55", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "8153", + "name": "Spirit cobra", + "defence_level": "55", + "safespot": null, + "lifepoints": "90", + "strength_level": "55", + "id": "6802", + "range_level": "55", + "attack_level": "55" + }, + { + "examine": "Serpentine.", + "melee_animation": "8152", + "range_animation": "0", + "magic_level": "55", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "8153", + "name": "Spirit cobra", + "defence_level": "55", + "safespot": null, + "lifepoints": "90", + "strength_level": "55", + "id": "6803", + "range_level": "55", + "attack_level": "55" + }, + { + "examine": "Face the thing that should not be!", + "melee_animation": "7786", + "range_animation": "0", + "magic_level": "65", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7780", + "name": "Spirit dagannoth", + "defence_level": "65", + "safespot": null, + "lifepoints": "115", + "strength_level": "65", + "id": "6804", + "range_level": "65", + "attack_level": "65" + }, + { + "examine": "Face the thing that should not be!", + "melee_animation": "7786", + "range_animation": "0", + "magic_level": "65", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7780", + "name": "Spirit dagannoth", + "defence_level": "65", + "safespot": null, + "lifepoints": "115", + "strength_level": "65", + "id": "6805", + "range_level": "65", + "attack_level": "65" + }, + { + "examine": "A hermit slug.", + "combat_style": "1", + "melee_animation": "8143", + "range_animation": "8143", + "attack_speed": "5", + "magic_level": "18", + "respawn_delay": "55", + "end_gfx": "1387", + "defence_animation": "8145", + "magic_animation": "8143", + "death_animation": "8143", + "name": "Thorny snail", + "defence_level": "22", + "poison_immune": "true", + "safespot": null, + "lifepoints": "28", + "strength_level": "18", + "id": "6806", + "bonuses": "47,50,52,52,54,49,13,3,13,4,0,0,0,0,0", + "range_level": "21", + "projectile": "1386", + "attack_level": "19" + }, + { + "examine": "A hermit slug.", + "combat_style": "1", + "melee_animation": "8143", + "range_animation": "8143", + "attack_speed": "5", + "magic_level": "18", + "respawn_delay": "55", + "end_gfx": "1387", + "defence_animation": "8145", + "weakness": "10", + "magic_animation": "8143", + "death_animation": "8143", + "name": "Thorny snail", + "defence_level": "22", + "poison_immune": "true", + "safespot": null, + "lifepoints": "28", + "strength_level": "18", + "id": "6807", + "bonuses": "47,50,52,52,54,49,13,3,13,4,0,0,0,0,0", + "range_level": "21", + "projectile": "1386", + "attack_level": "19" + }, + { + "examine": "Kneel before squid!", + "combat_style": "2", + "melee_animation": "7963", + "range_animation": "0", + "magic_level": "50", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7964", + "name": "Karamthulhu overlord", + "defence_level": "50", + "safespot": null, + "lifepoints": "82", + "strength_level": "50", + "id": "6809", + "range_level": "50", + "attack_level": "50" + }, + { + "examine": "Kneel before squid!", + "combat_style": "2", + "melee_animation": "7963", + "range_animation": "0", + "magic_level": "50", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7964", + "name": "Karamthulhu overlord", + "defence_level": "50", + "safespot": null, + "lifepoints": "82", + "strength_level": "50", + "id": "6810", + "range_level": "50", + "attack_level": "50" + }, + { + "combat_style": "1", + "melee_animation": "7935", + "respawn_delay": "0", + "defence_animation": "7936", + "death_animation": "7937", + "name": "Hydra", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6811", + "range_level": "1", + "attack_level": "1" + }, + { + "combat_style": "1", + "melee_animation": "7935", + "respawn_delay": "0", + "defence_animation": "7936", + "death_animation": "7937", + "name": "Hydra", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6812", + "range_level": "1", + "attack_level": "1" + }, + { + "death_animation": "7740", + "name": "Bunyip", + "defence_level": "1", + "safespot": null, + "lifepoints": "40", + "melee_animation": "7741", + "strength_level": "1", + "id": "6813", + "range_level": "1", + "respawn_delay": "0", + "attack_level": "1", + "defence_animation": "7742" + }, + { + "death_animation": "7740", + "name": "Bunyip", + "defence_level": "1", + "safespot": null, + "lifepoints": "40", + "melee_animation": "7741", + "strength_level": "1", + "id": "6814", + "range_level": "1", + "respawn_delay": "0", + "attack_level": "1", + "defence_animation": "7742" + }, + { + "examine": "Definitely not teenaged", + "combat_style": "0", + "melee_animation": "8286", + "range_animation": "0", + "magic_level": "55", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "8285", + "name": "War tortoise", + "defence_level": "55", + "safespot": null, + "lifepoints": "95", + "strength_level": "55", + "id": "6815", + "range_level": "55", + "attack_level": "55" + }, + { + "examine": "Definitely not teenaged", + "combat_style": "0", + "melee_animation": "8286", + "range_animation": "0", + "magic_level": "55", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "8285", + "name": "War tortoise", + "defence_level": "55", + "safespot": null, + "lifepoints": "95", + "strength_level": "55", + "id": "6816", + "range_level": "55", + "attack_level": "55" + }, + { + "examine": "Fruity and bat-shaped. A winning combination!.", + "name": "Fruit bat", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6817", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It's an extra-planar little blood hoover.", + "combat_style": "2", + "melee_animation": "8910", + "range_animation": "0", + "magic_level": "50", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7671", + "name": "Abyssal parasite", + "defence_level": "50", + "safespot": null, + "lifepoints": "77", + "strength_level": "50", + "id": "6818", + "range_level": "50", + "attack_level": "50" + }, + { + "examine": "It's an extra-planar little blood hoover.", + "combat_style": "2", + "melee_animation": "8910", + "range_animation": "0", + "magic_level": "50", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7671", + "name": "Abyssal parasite", + "defence_level": "50", + "safespot": null, + "lifepoints": "77", + "strength_level": "50", + "id": "6819", + "range_level": "50", + "attack_level": "50" + }, + { + "examine": "Lurking like only a lurker can.", + "melee_animation": "7680", + "range_animation": "0", + "magic_level": "55", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7684", + "name": "Abyssal lurker", + "defence_level": "55", + "safespot": null, + "lifepoints": "88", + "strength_level": "55", + "id": "6820", + "range_level": "55", + "attack_level": "55" + }, + { + "examine": "Lurking like only a lurker can.", + "melee_animation": "7680", + "range_animation": "0", + "magic_level": "55", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7684", + "name": "Abyssal lurker", + "defence_level": "55", + "safespot": null, + "lifepoints": "88", + "strength_level": "55", + "id": "6821", + "range_level": "55", + "attack_level": "55" + }, + { + "examine": "The pointiest horse on the planet.", + "melee_animation": "6376", + "range_animation": "6376", + "combat_audio": "4135,4196,4195", + "magic_level": "69", + "defence_animation": "6375", + "magic_animation": "6376", + "death_animation": "6377", + "name": "Unicorn stallion", + "defence_level": "70", + "poison_immune": "true", + "safespot": null, + "lifepoints": "100", + "strength_level": "62", + "id": "6822", + "bonuses": "48,59,43,52,104,52,116,123,134,46,127,4,0,0,0", + "range_level": "72", + "attack_level": "64" + }, + { + "examine": "The pointiest horse on the planet.", + "melee_animation": "6376", + "range_animation": "6376", + "combat_audio": "4135,4196,4195", + "magic_level": "69", + "defence_animation": "6375", + "weakness": "10", + "magic_animation": "6376", + "death_animation": "6377", + "name": "Unicorn stallion", + "defence_level": "70", + "poison_immune": "true", + "safespot": null, + "lifepoints": "100", + "strength_level": "62", + "id": "6823", + "bonuses": "48,59,43,52,104,52,116,123,134,46,127,4,0,0,0", + "range_level": "72", + "attack_level": "64" + }, + { + "combat_style": "2", + "melee_animation": "7810", + "attack_speed": "5", + "respawn_delay": "0", + "defence_animation": "5388", + "death_animation": "8012", + "name": "Magpie", + "defence_level": "1", + "safespot": null, + "lifepoints": "16", + "strength_level": "1", + "id": "6824", + "range_level": "1", + "projectile": "1318", + "attack_level": "1" + }, + { + "examine": "Southern fried please!", + "combat_style": "2", + "melee_animation": "7810", + "range_animation": "7810", + "attack_speed": "5", + "magic_level": "23", + "respawn_delay": "50", + "defence_animation": "5388", + "magic_animation": "7810", + "death_animation": "5389", + "name": "Dreadfowl", + "defence_level": "22", + "poison_immune": "true", + "safespot": null, + "lifepoints": "16", + "strength_level": "15", + "id": "6825", + "bonuses": "16,15,29,12,39,13,41,35,29,39,47,2,2,2,7", + "range_level": "16", + "projectile": "1318", + "attack_level": "17" + }, + { + "examine": "Southern fried please!", + "combat_style": "2", + "melee_animation": "7810", + "range_animation": "7810", + "attack_speed": "5", + "magic_level": "23", + "respawn_delay": "50", + "defence_animation": "5388", + "weakness": "10", + "magic_animation": "7810", + "death_animation": "5389", + "name": "Dreadfowl", + "defence_level": "22", + "poison_immune": "true", + "safespot": null, + "lifepoints": "16", + "strength_level": "15", + "id": "6826", + "bonuses": "16,15,29,12,39,13,41,35,29,39,47,2,2,2,7", + "range_level": "16", + "projectile": "1318", + "attack_level": "17" + }, + { + "examine": "It's mean and green!", + "melee_animation": "8208", + "range_animation": "0", + "attack_speed": "5", + "magic_level": "55", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "8209", + "name": "Stranger plant", + "defence_level": "55", + "safespot": null, + "lifepoints": "91", + "strength_level": "55", + "id": "6827", + "range_level": "55", + "attack_level": "55" + }, + { + "examine": "It's mean and green!", + "melee_animation": "8208", + "range_animation": "0", + "attack_speed": "5", + "magic_level": "55", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "8209", + "name": "Stranger plant", + "defence_level": "55", + "safespot": null, + "lifepoints": "91", + "strength_level": "55", + "id": "6828", + "range_level": "55", + "attack_level": "55" + }, + { + "examine": "Man's significantly less-domesticated friend.", + "melee_animation": "8292", + "range_animation": "8292", + "attack_speed": "5", + "magic_level": "7", + "defence_animation": "8294", + "magic_animation": "8292", + "death_animation": "8295", + "name": "Spirit wolf", + "defence_level": "21", + "safespot": null, + "lifepoints": "15", + "strength_level": "18", + "id": "6829", + "bonuses": "12,7,4,10,23,5,29,27,16,12,13,17,0,0,0", + "range_level": "9", + "attack_level": "16" + }, + { + "examine": "Man's significantly less-domesticated friend.", + "melee_animation": "8292", + "range_animation": "8292", + "attack_speed": "5", + "magic_level": "7", + "defence_animation": "8294", + "weakness": "10", + "magic_animation": "8292", + "death_animation": "8295", + "name": "Spirit wolf", + "defence_level": "21", + "safespot": null, + "lifepoints": "15", + "strength_level": "18", + "id": "6830", + "bonuses": "12,7,4,10,23,5,29,27,16,12,13,17,0,0,0", + "range_level": "9", + "attack_level": "16" + }, + { + "examine": "Surprisingly slime-free.", + "combat_style": "1", + "melee_animation": "7795", + "range_animation": "0", + "magic_level": "18", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7797", + "name": "Desert wyrm", + "defence_level": "18", + "safespot": null, + "lifepoints": "25", + "strength_level": "18", + "id": "6831", + "range_level": "18", + "attack_level": "18" + }, + { + "examine": "Surprisingly slime-free.", + "combat_style": "1", + "melee_animation": "7795", + "range_animation": "0", + "magic_level": "18", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7797", + "name": "Desert wyrm", + "defence_level": "18", + "safespot": null, + "lifepoints": "25", + "strength_level": "18", + "id": "6832", + "range_level": "18", + "attack_level": "18" + }, + { + "examine": "If you think he's evil", + "combat_style": "1", + "melee_animation": "8248", + "range_animation": "0", + "magic_level": "42", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "8250", + "name": "Evil turnip", + "defence_level": "42", + "safespot": null, + "lifepoints": "60", + "strength_level": "42", + "id": "6833", + "range_level": "42", + "attack_level": "42" + }, + { + "examine": "If you think he's evil", + "combat_style": "1", + "melee_animation": "8248", + "range_animation": "0", + "magic_level": "42", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "8250", + "name": "Evil turnip", + "defence_level": "42", + "safespot": null, + "lifepoints": "60", + "strength_level": "42", + "id": "6834", + "range_level": "42", + "attack_level": "42" + }, + { + "examine": "It vants to suck my blood!", + "melee_animation": "8275", + "range_animation": "0", + "magic_level": "31", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "8276", + "name": "Vampire bat", + "defence_level": "31", + "safespot": null, + "lifepoints": "44", + "strength_level": "31", + "id": "6835", + "range_level": "31", + "attack_level": "31" + }, + { + "examine": "It vants to suck my blood!", + "melee_animation": "8275", + "range_animation": "0", + "magic_level": "31", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "8276", + "name": "Vampire bat", + "defence_level": "31", + "safespot": null, + "lifepoints": "44", + "strength_level": "31", + "id": "6836", + "range_level": "31", + "attack_level": "31" + }, + { + "examine": "Salt and vinegaroon.", + "melee_animation": "6254", + "range_animation": "0", + "combat_audio": "3611,3612,3610", + "magic_level": "19", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "6256", + "name": "Spirit scorpion", + "defence_level": "19", + "safespot": null, + "lifepoints": "27", + "strength_level": "19", + "id": "6837", + "range_level": "19", + "attack_level": "19" + }, + { + "examine": "Salt and vinegaroon.", + "melee_animation": "6254", + "range_animation": "0", + "combat_audio": "3611,3612,3610", + "magic_level": "19", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "6256", + "name": "Spirit scorpion", + "defence_level": "19", + "safespot": null, + "lifepoints": "27", + "strength_level": "19", + "id": "6838", + "range_level": "19", + "attack_level": "19" + }, + { + "examine": "Crikey! Look at the size of those teeth!", + "melee_animation": "4925", + "combat_audio": "498,500,499", + "magic_level": "60", + "respawn_delay": "0", + "defence_animation": "4928", + "death_animation": "4929", + "name": "Arctic bear", + "defence_level": "60", + "safespot": null, + "lifepoints": "10", + "strength_level": "60", + "id": "6839", + "bonuses": "90,50,50,60,90,80,50,30,40,100,0,0,0,0,0", + "range_level": "60", + "attack_level": "60" + }, + { + "examine": "Crikey! Look at the size of those teeth!", + "melee_animation": "4925", + "range_animation": "0", + "combat_audio": "498,500,499", + "magic_level": "60", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "4929", + "name": "Arctic bear", + "defence_level": "60", + "safespot": null, + "lifepoints": "101", + "strength_level": "60", + "id": "6840", + "bonuses": "90,50,50,60,90,80,50,30,40,100,0,0,0,0,0", + "range_level": "60", + "attack_level": "60" + }, + { + "examine": "Would scare anyone off their tuffet.", + "melee_animation": "5327", + "range_animation": "5327", + "combat_audio": "537,539,538", + "magic_level": "15", + "respawn_delay": "50", + "defence_animation": "5328", + "magic_animation": "5327", + "death_animation": "5329", + "name": "Spirit spider", + "defence_level": "17", + "safespot": null, + "lifepoints": "18", + "strength_level": "16", + "id": "6841", + "bonuses": "15,16,11,14,34,12,24,36,46,16,37,0,0,0,0", + "range_level": "12", + "attack_level": "17" + }, + { + "examine": "Would scare anyone off their tuffet.", + "melee_animation": "5327", + "range_animation": "5327", + "combat_audio": "537,539,538", + "magic_level": "15", + "respawn_delay": "50", + "defence_animation": "5328", + "weakness": "10", + "magic_animation": "5327", + "death_animation": "5329", + "name": "Spirit spider", + "defence_level": "17", + "safespot": null, + "lifepoints": "18", + "strength_level": "16", + "id": "6842", + "bonuses": "15,16,11,14,34,12,24,36,46,16,37,0,0,0,0", + "range_level": "12", + "attack_level": "17" + }, + { + "examine": "It's like a little suction pump with eyes.", + "melee_animation": "7657", + "range_animation": "0", + "magic_level": "49", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7656", + "name": "Bloated leech", + "defence_level": "49", + "safespot": null, + "lifepoints": "70", + "strength_level": "49", + "id": "6843", + "range_level": "49", + "attack_level": "49" + }, + { + "examine": "It's like a little suction pump with eyes.", + "melee_animation": "7657", + "range_animation": "0", + "magic_level": "49", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7656", + "name": "Bloated leech", + "defence_level": "49", + "safespot": null, + "lifepoints": "70", + "strength_level": "49", + "id": "6844", + "range_level": "49", + "attack_level": "49" + }, + { + "examine": "Violent little so-and-so.", + "melee_animation": "7928", + "range_animation": "0", + "magic_level": "32", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7925", + "name": "Honey badger", + "defence_level": "32", + "safespot": null, + "lifepoints": "45", + "strength_level": "32", + "id": "6845", + "range_level": "32", + "attack_level": "32" + }, + { + "examine": "Violent little so-and-so.", + "melee_animation": "7928", + "range_animation": "0", + "magic_level": "32", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7925", + "name": "Honey badger", + "defence_level": "32", + "safespot": null, + "lifepoints": "45", + "strength_level": "32", + "id": "6846", + "range_level": "32", + "attack_level": "32" + }, + { + "examine": "The big cheese.", + "combat_audio": "703,705,704", + "magic_level": "27", + "respawn_delay": "50", + "name": "Albino rat", + "defence_level": "32", + "poison_immune": "true", + "safespot": null, + "lifepoints": "68", + "strength_level": "28", + "id": "6847", + "bonuses": "64,42,40,57,64,50,76,82,72,24,75,5,15,5,5", + "range_level": "31", + "attack_level": "31" + }, + { + "examine": "The big cheese.", + "combat_audio": "703,705,704", + "magic_level": "27", + "respawn_delay": "50", + "weakness": "10", + "name": "Albino rat", + "defence_level": "32", + "poison_immune": "true", + "safespot": null, + "lifepoints": "68", + "strength_level": "28", + "id": "6848", + "bonuses": "64,42,40,57,64,50,76,82,72,24,75,5,15,5,5", + "range_level": "31", + "attack_level": "31" + }, + { + "examine": "Puts the 'crust' in 'crustacean'.", + "melee_animation": "8112", + "respawn_delay": "0", + "defence_animation": "8114", + "death_animation": "8113", + "name": "Granite lobster", + "defence_level": "60", + "safespot": null, + "lifepoints": "10", + "strength_level": "60", + "id": "6849", + "bonuses": "93,90,65,90,30,40,50,50,60,40,0,0,0,0,0", + "range_level": "60", + "attack_level": "60" + }, + { + "examine": "Puts the 'crust' in 'crustacean'.", + "melee_animation": "8112", + "range_animation": "0", + "magic_level": "60", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "8113", + "name": "Granite lobster", + "defence_level": "60", + "safespot": null, + "lifepoints": "105", + "strength_level": "60", + "id": "6850", + "bonuses": "93,90,65,90,30,40,50,50,60,40,0,0,0,0,0", + "range_level": "60", + "attack_level": "60" + }, + { + "death_animation": "8012", + "name": "Macaw", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6851", + "range_level": "1", + "respawn_delay": "0", + "attack_level": "1" + }, + { + "death_animation": "8012", + "name": "Macaw", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6852", + "range_level": "1", + "respawn_delay": "0", + "attack_level": "1" + }, + { + "examine": "He's just a big bully.", + "combat_style": "0", + "melee_animation": "8024", + "magic_level": "1", + "respawn_delay": "0", + "defence_animation": "8023", + "death_animation": "8025", + "name": "Bronze minotaur", + "defence_level": "19", + "safespot": null, + "lifepoints": "133", + "strength_level": "19", + "id": "6853", + "bonuses": "-2,6,3,0,0,15,14,9,-6,14,5,90,0,0,0", + "range_level": "1", + "attack_level": "19" + }, + { + "examine": "He's just a big bully.", + "combat_style": "0", + "melee_animation": "8024", + "range_animation": "0", + "magic_level": "1", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "8025", + "name": "Bronze minotaur", + "defence_level": "19", + "safespot": null, + "lifepoints": "133", + "strength_level": "19", + "id": "6854", + "bonuses": "15,20,10,15,10,15,15,15,0,0,0,90,0,0,0", + "range_level": "1", + "attack_level": "19" + }, + { + "examine": "He's just a big bully.", + "combat_style": "0", + "melee_animation": "8024", + "magic_level": "25", + "respawn_delay": "0", + "defence_animation": "8023", + "magic_animation": "", + "death_animation": "8025", + "name": "Iron minotaur", + "defence_level": "25", + "safespot": null, + "lifepoints": "193", + "strength_level": "25", + "id": "6855", + "bonuses": "-2,8,5,0,0,21,17,9,-6,20,5,100,0,100,0", + "range_level": "1", + "attack_level": "25" + }, + { + "examine": "He's just a big bully.", + "combat_style": "0", + "melee_animation": "8024", + "range_animation": "0", + "magic_level": "25", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "8025", + "name": "Iron minotaur", + "defence_level": "25", + "safespot": null, + "lifepoints": "193", + "strength_level": "25", + "id": "6856", + "bonuses": "25,25,25,25,0,25,25,25,25,0,0,100,0,100,0", + "clue_level": "", + "range_level": "1", + "attack_level": "25" + }, + { + "examine": "He's just a big bully!", + "combat_style": "0", + "melee_animation": "8024", + "magic_level": "28", + "respawn_delay": "0", + "defence_animation": "8023", + "death_animation": "8025", + "name": "Steel minotaur", + "defence_level": "28", + "safespot": null, + "lifepoints": "260", + "strength_level": "28", + "id": "6857", + "bonuses": "-2,16,11,0,0,32,31,24,-6,31,5,122,0,122,0", + "range_level": "1", + "attack_level": "28" + }, + { + "examine": "He's just a big bully.", + "combat_style": "0", + "melee_animation": "8024", + "range_animation": "0", + "magic_level": "28", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "8025", + "name": "Steel minotaur", + "defence_level": "28", + "safespot": null, + "lifepoints": "260", + "strength_level": "28", + "id": "6858", + "bonuses": "40,30,30,30,30,30,30,30,30,30,0,127,0,0,0", + "range_level": "1", + "attack_level": "28" + }, + { + "examine": "He's just a big bully", + "combat_style": "0", + "melee_animation": "8024", + "magic_level": "30", + "respawn_delay": "0", + "defence_animation": "8023", + "death_animation": "8025", + "name": "Mithril minotaur", + "defence_level": "30", + "safespot": null, + "lifepoints": "340", + "can_tolerate": "", + "strength_level": "30", + "id": "6859", + "bonuses": "-2,22,17,0,0,46,44,38,-6,44,20,146,0,147,0", + "range_level": "0", + "attack_level": "30" + }, + { + "examine": "He's just a big bully.", + "combat_style": "0", + "melee_animation": "8024", + "range_animation": "0", + "magic_level": "30", + "respawn_delay": "0", + "defence_animation": "8023", + "weakness": "10", + "magic_animation": "0", + "death_animation": "8025", + "name": "Mithril minotaur", + "defence_level": "30", + "safespot": null, + "lifepoints": "340", + "strength_level": "30", + "id": "6860", + "bonuses": "30,30,30,30,0,30,30,30,30,0,30,146,0,147,0", + "range_level": "0", + "attack_level": "30" + }, + { + "examine": "He's just a big bully.", + "combat_style": "0", + "melee_animation": "8024", + "attack_speed": "", + "magic_level": "35", + "respawn_delay": "0", + "defence_animation": "8023", + "death_animation": "8025", + "name": "Adamant minotaur", + "defence_level": "35", + "safespot": null, + "poison_immune": "", + "lifepoints": "441", + "strength_level": "35", + "id": "6861", + "bonuses": "-2,31,26,-3,-17,65,63,55,-6,63,30,146,0,181,0", + "range_level": "1", + "attack_level": "35" + }, + { + "examine": "He's just a big bully.", + "combat_style": "0", + "melee_animation": "8024", + "range_animation": "0", + "magic_level": "35", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "8025", + "name": "Adamant minotaur", + "defence_level": "35", + "safespot": null, + "lifepoints": "441", + "strength_level": "35", + "id": "6862", + "bonuses": "40,50,40,45,35,20,50,36,30,40,15,180,30,10,0", + "range_level": "1", + "attack_level": "35" + }, + { + "examine": "He's just a big bully.", + "melee_animation": "8024", + "magic_level": "40", + "respawn_delay": "0", + "defence_animation": "8023", + "death_animation": "8025", + "name": "Rune minotaur", + "defence_level": "40", + "safespot": null, + "lifepoints": "570", + "strength_level": "40", + "id": "6863", + "bonuses": "-2,48,43,0,-1,207,209,192,-12,205,102,157,0,195,0", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "He's just a big bully.", + "melee_animation": "8024", + "magic_level": "40", + "respawn_delay": "0", + "defence_animation": "8023", + "slayer_exp": "0", + "death_animation": "8025", + "name": "Rune minotaur", + "defence_level": "40", + "safespot": null, + "lifepoints": "570", + "strength_level": "40", + "id": "6864", + "bonuses": "50,40,40,56,40,30,50,30,60,30,40,219,50,40,40", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "Well", + "melee_animation": "7816", + "range_animation": "0", + "magic_level": "55", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7818", + "name": "Smoke devil", + "defence_level": "55", + "safespot": null, + "lifepoints": "87", + "strength_level": "55", + "id": "6865", + "range_level": "55", + "attack_level": "55" + }, + { + "examine": "Well", + "melee_animation": "7816", + "range_animation": "0", + "magic_level": "55", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7818", + "name": "Smoke devil", + "defence_level": "55", + "safespot": null, + "lifepoints": "87", + "strength_level": "55", + "id": "6866", + "range_level": "55", + "attack_level": "55" + }, + { + "examine": "Putting all three of its best feet forward.", + "melee_animation": "7896", + "range_animation": "0", + "magic_level": "40", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7897", + "name": "Bull ant", + "defence_level": "40", + "safespot": null, + "lifepoints": "57", + "strength_level": "40", + "id": "6867", + "range_level": "40", + "attack_level": "40" + }, + { + "examine": "Putting all three of its best feet forward.", + "melee_animation": "7896", + "range_animation": "0", + "magic_level": "40", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7897", + "name": "Bull ant", + "defence_level": "40", + "safespot": null, + "lifepoints": "57", + "strength_level": "40", + "id": "6868", + "range_level": "40", + "attack_level": "40" + }, + { + "examine": "It's just a harmless wee rabbit. ", + "combat_style": "2", + "melee_animation": "8304", + "range_animation": "8304", + "attack_speed": "5", + "magic_level": "95", + "defence_animation": "8306", + "magic_animation": "8304", + "death_animation": "8305", + "name": "Wolpertinger", + "defence_level": "95", + "poison_immune": "true", + "safespot": null, + "lifepoints": "619", + "strength_level": "1", + "id": "6869", + "bonuses": "59,50,50,50,50,50,50,50,50,50,50,50,50,68,0", + "range_level": "95", + "attack_level": "1" + }, + { + "examine": "It's just a harmless wee rabbit. ", + "combat_style": "2", + "melee_animation": "8304", + "range_animation": "8304", + "attack_speed": "5", + "magic_level": "95", + "defence_animation": "8306", + "magic_animation": "8304", + "death_animation": "8305", + "name": "Wolpertinger", + "defence_level": "95", + "poison_immune": "true", + "safespot": null, + "lifepoints": "619", + "strength_level": "1", + "id": "6870", + "bonuses": "59,50,50,50,50,50,50,50,50,50,50,50,50,68,0", + "range_level": "95", + "attack_level": "1" + }, + { + "examine": "I suppose it could smell worse", + "melee_animation": "7769", + "range_animation": "0", + "attack_speed": "5", + "magic_level": "28", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7770", + "name": "Compost mound", + "defence_level": "28", + "safespot": null, + "lifepoints": "40", + "strength_level": "28", + "id": "6871", + "range_level": "28", + "attack_level": "28" + }, + { + "examine": "I suppose it could smell worse", + "melee_animation": "7769", + "range_animation": "0", + "attack_speed": "5", + "magic_level": "28", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7770", + "name": "Compost mound", + "defence_level": "28", + "safespot": null, + "lifepoints": "40", + "strength_level": "28", + "id": "6872", + "range_level": "28", + "attack_level": "28" + }, + { + "examine": "Bulk haulage never smelled so bad.", + "melee_animation": "5782", + "range_animation": "5782", + "attack_speed": "5", + "magic_level": "91", + "defence_animation": "5783", + "magic_animation": "5782", + "death_animation": "5784", + "name": "Pack yak", + "defence_level": "121", + "poison_immune": "true", + "safespot": null, + "lifepoints": "710", + "strength_level": "104", + "id": "6873", + "bonuses": "64,67,5,72,128,49,264,234,164,49,132,40,35,40,40", + "range_level": "86", + "attack_level": "112" + }, + { + "examine": "Bulk haulage never smelled so bad.", + "melee_animation": "5782", + "range_animation": "5782", + "attack_speed": "5", + "magic_level": "91", + "defence_animation": "5783", + "weakness": "10", + "magic_animation": "5782", + "death_animation": "5784", + "name": "Pack yak", + "defence_level": "121", + "poison_immune": "true", + "safespot": null, + "lifepoints": "710", + "strength_level": "104", + "id": "6874", + "bonuses": "64,67,5,72,128,49,264,234,164,49,132,40,35,40,40", + "range_level": "86", + "attack_level": "112" + }, + { + "examine": "If looks could kill... Wait", + "start_gfx": "1467", + "combat_style": "2", + "melee_animation": "7762", + "range_animation": "0", + "magic_level": "43", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7763", + "name": "Spirit cockatrice", + "defence_level": "43", + "safespot": null, + "lifepoints": "61", + "strength_level": "43", + "id": "6875", + "range_level": "43", + "projectile": "1468", + "attack_level": "43" + }, + { + "examine": "If looks could kill... Wait", + "start_gfx": "1467", + "combat_style": "2", + "melee_animation": "7762", + "range_animation": "0", + "magic_level": "43", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7763", + "name": "Spirit cockatrice", + "defence_level": "43", + "safespot": null, + "lifepoints": "61", + "strength_level": "43", + "id": "6876", + "range_level": "43", + "projectile": "1468", + "attack_level": "43" + }, + { + "examine": "If looks could kill... Wait", + "start_gfx": "1467", + "combat_style": "2", + "melee_animation": "7762", + "range_animation": "0", + "magic_level": "43", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7763", + "name": "Spirit guthatrice", + "defence_level": "43", + "safespot": null, + "lifepoints": "61", + "strength_level": "43", + "id": "6877", + "range_level": "43", + "projectile": "1468", + "attack_level": "43" + }, + { + "examine": "If looks could kill... Wait", + "start_gfx": "1467", + "combat_style": "2", + "melee_animation": "7762", + "range_animation": "0", + "magic_level": "43", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7763", + "name": "Spirit guthatrice", + "defence_level": "43", + "safespot": null, + "lifepoints": "61", + "strength_level": "43", + "id": "6878", + "range_level": "43", + "projectile": "1468", + "attack_level": "43" + }, + { + "examine": "If looks could kill... Wait", + "start_gfx": "1467", + "combat_style": "2", + "melee_animation": "7762", + "range_animation": "0", + "combat_audio": "703,705,704", + "magic_level": "43", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7763", + "name": "Spirit saratrice", + "defence_level": "43", + "safespot": null, + "lifepoints": "61", + "strength_level": "43", + "id": "6879", + "range_level": "43", + "projectile": "1468", + "attack_level": "43" + }, + { + "examine": "If looks could kill... Wait", + "start_gfx": "1467", + "combat_style": "2", + "melee_animation": "7762", + "range_animation": "0", + "combat_audio": "703,705,704", + "magic_level": "43", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7763", + "name": "Spirit saratrice", + "defence_level": "43", + "safespot": null, + "lifepoints": "61", + "strength_level": "43", + "id": "6880", + "range_level": "43", + "projectile": "1468", + "attack_level": "43" + }, + { + "examine": "If looks could kill... Wait", + "start_gfx": "1467", + "combat_style": "2", + "melee_animation": "7762", + "range_animation": "0", + "magic_level": "43", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7763", + "name": "Spirit zamatrice", + "defence_level": "43", + "safespot": null, + "lifepoints": "61", + "strength_level": "43", + "id": "6881", + "range_level": "43", + "projectile": "1468", + "attack_level": "43" + }, + { + "examine": "If looks could kill... Wait", + "start_gfx": "1467", + "combat_style": "2", + "melee_animation": "7762", + "range_animation": "0", + "magic_level": "43", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7763", + "name": "Spirit zamatrice", + "defence_level": "43", + "safespot": null, + "lifepoints": "61", + "strength_level": "43", + "id": "6882", + "range_level": "43", + "projectile": "1468", + "attack_level": "43" + }, + { + "examine": "If looks could kill... Wait", + "start_gfx": "1467", + "combat_style": "2", + "melee_animation": "7762", + "range_animation": "0", + "magic_level": "43", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7763", + "name": "Spirit pengatrice", + "defence_level": "43", + "safespot": null, + "lifepoints": "61", + "strength_level": "43", + "id": "6883", + "range_level": "43", + "projectile": "1468", + "attack_level": "43" + }, + { + "examine": "If looks could kill... Wait", + "start_gfx": "1467", + "combat_style": "2", + "melee_animation": "7762", + "range_animation": "0", + "magic_level": "43", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7763", + "name": "Spirit pengatrice", + "defence_level": "43", + "safespot": null, + "lifepoints": "61", + "strength_level": "43", + "id": "6884", + "range_level": "43", + "projectile": "1468", + "attack_level": "43" + }, + { + "examine": "If looks could kill... Wait", + "start_gfx": "1467", + "combat_style": "2", + "melee_animation": "7762", + "range_animation": "0", + "magic_level": "43", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7763", + "name": "Spirit coraxatrice", + "defence_level": "43", + "safespot": null, + "lifepoints": "61", + "strength_level": "43", + "id": "6885", + "range_level": "43", + "projectile": "1468", + "attack_level": "43" + }, + { + "examine": "If looks could kill... Wait", + "start_gfx": "1467", + "combat_style": "2", + "melee_animation": "7762", + "range_animation": "0", + "magic_level": "43", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7763", + "name": "Spirit coraxatrice", + "defence_level": "43", + "safespot": null, + "lifepoints": "61", + "strength_level": "43", + "id": "6886", + "range_level": "43", + "projectile": "1468", + "attack_level": "43" + }, + { + "examine": "If looks could kill... Wait", + "start_gfx": "1467", + "combat_style": "2", + "melee_animation": "7762", + "range_animation": "0", + "magic_level": "43", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7763", + "name": "Spirit vulatrice", + "defence_level": "43", + "safespot": null, + "lifepoints": "61", + "strength_level": "43", + "id": "6887", + "range_level": "43", + "projectile": "1468", + "attack_level": "43" + }, + { + "examine": "If looks could kill... Wait", + "start_gfx": "1467", + "combat_style": "2", + "melee_animation": "7762", + "range_animation": "0", + "magic_level": "43", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7763", + "name": "Spirit vulatrice", + "defence_level": "43", + "safespot": null, + "lifepoints": "61", + "strength_level": "43", + "id": "6888", + "range_level": "43", + "projectile": "1468", + "attack_level": "43" + }, + { + "examine": "The only creature with a mouth big enough to fit a cannon ball into.", + "melee_animation": "7260", + "range_animation": "0", + "magic_level": "55", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7256", + "name": "Barker toad", + "defence_level": "55", + "safespot": null, + "lifepoints": "94", + "strength_level": "55", + "id": "6889", + "range_level": "55", + "attack_level": "55" + }, + { + "examine": "The only creature with a mouth big enough to fit a cannon ball into.", + "melee_animation": "7260", + "range_animation": "0", + "magic_level": "55", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7256", + "name": "Barker toad", + "defence_level": "55", + "safespot": null, + "lifepoints": "94", + "strength_level": "55", + "id": "6890", + "range_level": "55", + "attack_level": "55" + }, + { + "examine": "He looks like the type of guy who would keep penguins.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Penguin keeper", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6891", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The lady of the pet shop.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Pet shop owner", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6892", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The man of the pet shop.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Pet shop owner", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6893", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A dalmatian puppy.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Dalmatian", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6896", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A bulldog puppy.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Bulldog", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6897", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Hatchling dragon", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "408,410,409", + "strength_level": "1", + "id": "6900", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Baby dragon", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "407,405,406", + "strength_level": "1", + "id": "6901", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Hatchling dragon", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "408,410,409", + "strength_level": "1", + "id": "6902", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Baby dragon", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "407,405,406", + "strength_level": "1", + "id": "6903", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Hatchling dragon", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "408,410,409", + "strength_level": "1", + "id": "6904", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Baby dragon", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "407,405,406", + "strength_level": "1", + "id": "6905", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Hatchling dragon", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "408,410,409", + "strength_level": "1", + "id": "6906", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Baby dragon", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "407,405,406", + "strength_level": "1", + "id": "6907", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It's so adorably tiny!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Baby gecko", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6917", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A tiny nut-thief.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Baby squirrel", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6921", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Baby monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "629,631,630", + "strength_level": "1", + "id": "6942", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "629,631,630", + "strength_level": "1", + "id": "6943", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It's a tiny", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "629,631,630", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Baby monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6944", + "range_level": "1", + "attack_level": "1" + }, + { + "combat_style": "2", + "melee_animation": "8304", + "attack_speed": "5", + "magic_level": "28", + "respawn_delay": "0", + "defence_animation": "8306", + "death_animation": "8305", + "name": "Bulldog puppy", + "defence_level": "1", + "safespot": null, + "lifepoints": "651", + "strength_level": "1", + "id": "6969", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A nature lover.", + "melee_animation": "7181", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "4", + "magic_level": "25", + "respawn_delay": "25", + "defence_animation": "7186", + "weakness": "3", + "magic_animation": "711", + "death_animation": "7185", + "name": "Druid", + "defence_level": "32", + "safespot": null, + "lifepoints": "30", + "strength_level": "28", + "id": "6972", + "range_level": "1", + "attack_level": "28" + }, + { + "examine": "A nature lover.", + "range_animation": "0", + "combat_audio": "511,513,512", + "melee_animation": "7182", + "attack_speed": "4", + "magic_level": "25", + "respawn_delay": "25", + "defence_animation": "0", + "weakness": "3", + "magic_animation": "711", + "death_animation": "7185", + "name": "Druid", + "defence_level": "32", + "safespot": null, + "lifepoints": "30", + "strength_level": "28", + "id": "6973", + "range_level": "1", + "attack_level": "28" + }, + { + "examine": "A nature lover.", + "range_animation": "0", + "combat_audio": "511,513,512", + "melee_animation": "7182", + "attack_speed": "4", + "magic_level": "25", + "respawn_delay": "25", + "defence_animation": "0", + "weakness": "3", + "magic_animation": "711", + "death_animation": "7185", + "name": "Druid", + "defence_level": "32", + "safespot": null, + "lifepoints": "30", + "strength_level": "28", + "id": "6974", + "range_level": "1", + "attack_level": "28" + }, + { + "examine": "A nature lover.", + "melee_animation": "7181", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "4", + "magic_level": "25", + "respawn_delay": "25", + "defence_animation": "7186", + "weakness": "3", + "magic_animation": "711", + "death_animation": "7185", + "name": "Druid", + "defence_level": "32", + "safespot": null, + "lifepoints": "30", + "strength_level": "28", + "id": "6975", + "range_level": "1", + "attack_level": "28" + }, + { + "examine": "A nature lover.", + "melee_animation": "7182", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "4", + "magic_level": "25", + "respawn_delay": "25", + "defence_animation": "0", + "weakness": "3", + "magic_animation": "711", + "death_animation": "7185", + "name": "Druid", + "defence_level": "32", + "safespot": null, + "lifepoints": "30", + "strength_level": "28", + "id": "6976", + "range_level": "1", + "attack_level": "28" + }, + { + "examine": "A nature lover.", + "melee_animation": "7182", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "4", + "magic_level": "25", + "respawn_delay": "25", + "defence_animation": "0", + "weakness": "3", + "magic_animation": "711", + "death_animation": "7185", + "name": "Druid", + "defence_level": "32", + "safespot": null, + "lifepoints": "30", + "strength_level": "28", + "id": "6977", + "range_level": "1", + "attack_level": "28" + }, + { + "examine": "A nature lover.", + "melee_animation": "7182", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "4", + "magic_level": "25", + "respawn_delay": "25", + "defence_animation": "0", + "weakness": "3", + "magic_animation": "711", + "death_animation": "7185", + "name": "Druid", + "defence_level": "32", + "safespot": null, + "lifepoints": "30", + "strength_level": "28", + "id": "6978", + "range_level": "1", + "attack_level": "28" + }, + { + "examine": "A nature lover.", + "melee_animation": "7181", + "combat_audio": "511,513,512", + "range_animation": "0", + "attack_speed": "4", + "magic_level": "25", + "respawn_delay": "25", + "defence_animation": "7186", + "magic_animation": "711", + "death_animation": "7185", + "name": "Druid", + "defence_level": "32", + "safespot": null, + "lifepoints": "30", + "strength_level": "28", + "id": "6979", + "range_level": "1", + "attack_level": "28" + }, + { + "examine": "A nature lover.", + "melee_animation": "7182", + "range_animation": "0", + "combat_audio": "511,513,512", + "attack_speed": "4", + "magic_level": "25", + "respawn_delay": "25", + "defence_animation": "0", + "weakness": "3", + "magic_animation": "711", + "death_animation": "7185", + "name": "Druid", + "defence_level": "32", + "safespot": null, + "lifepoints": "30", + "strength_level": "28", + "id": "6980", + "range_level": "1", + "attack_level": "28" + }, + { + "examine": "A nature lover.", + "melee_animation": "7182", + "range_animation": "0", + "combat_audio": "511,506,505", + "attack_speed": "4", + "magic_level": "25", + "respawn_delay": "25", + "defence_animation": "0", + "weakness": "3", + "magic_animation": "711", + "death_animation": "7185", + "name": "Druidess", + "defence_level": "32", + "safespot": null, + "lifepoints": "30", + "strength_level": "28", + "id": "6981", + "range_level": "1", + "attack_level": "28" + }, + { + "examine": "A nature lover.", + "melee_animation": "7181", + "range_animation": "0", + "combat_audio": "511,506,505", + "attack_speed": "4", + "magic_level": "25", + "respawn_delay": "25", + "defence_animation": "7186", + "weakness": "3", + "magic_animation": "711", + "death_animation": "7185", + "name": "Druidess", + "defence_level": "32", + "safespot": null, + "lifepoints": "30", + "strength_level": "28", + "id": "6982", + "range_level": "1", + "attack_level": "28" + }, + { + "examine": "A nature lover.", + "melee_animation": "7182", + "range_animation": "0", + "combat_audio": "511,506,505", + "attack_speed": "4", + "magic_level": "25", + "respawn_delay": "25", + "defence_animation": "0", + "weakness": "3", + "magic_animation": "711", + "death_animation": "7185", + "name": "Druidess", + "defence_level": "32", + "safespot": null, + "lifepoints": "30", + "strength_level": "28", + "id": "6983", + "range_level": "1", + "attack_level": "28" + }, + { + "examine": "A nature lover.", + "melee_animation": "7181", + "range_animation": "0", + "combat_audio": "511,506,505", + "attack_speed": "4", + "magic_level": "25", + "respawn_delay": "25", + "defence_animation": "7186", + "weakness": "3", + "magic_animation": "711", + "death_animation": "7185", + "name": "Druidess", + "defence_level": "32", + "safespot": null, + "lifepoints": "30", + "strength_level": "28", + "id": "6984", + "range_level": "1", + "attack_level": "28" + }, + { + "examine": "A nature lover.", + "melee_animation": "7182", + "range_animation": "0", + "combat_audio": "511,506,505", + "attack_speed": "4", + "magic_level": "25", + "respawn_delay": "25", + "defence_animation": "0", + "weakness": "3", + "magic_animation": "711", + "death_animation": "7185", + "name": "Druidess", + "defence_level": "32", + "safespot": null, + "lifepoints": "30", + "strength_level": "28", + "id": "6985", + "range_level": "1", + "attack_level": "28" + }, + { + "examine": "A nature lover.", + "melee_animation": "7182", + "range_animation": "0", + "combat_audio": "511,506,505", + "attack_speed": "4", + "magic_level": "25", + "respawn_delay": "25", + "defence_animation": "0", + "weakness": "3", + "magic_animation": "711", + "death_animation": "7185", + "name": "Druidess", + "defence_level": "32", + "safespot": null, + "lifepoints": "30", + "strength_level": "28", + "id": "6986", + "range_level": "1", + "attack_level": "28" + }, + { + "examine": "A nature lover.", + "melee_animation": "7182", + "range_animation": "0", + "combat_audio": "511,506,505", + "attack_speed": "4", + "magic_level": "25", + "respawn_delay": "25", + "defence_animation": "0", + "weakness": "3", + "magic_animation": "711", + "death_animation": "7185", + "name": "Druidess", + "defence_level": "32", + "safespot": null, + "lifepoints": "30", + "strength_level": "28", + "id": "6987", + "range_level": "1", + "attack_level": "28" + }, + { + "examine": "On Gielinor", + "melee_animation": "8569", + "range_animation": "0", + "magic_level": "50", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "8570", + "name": "Spirit jelly", + "defence_level": "50", + "safespot": null, + "lifepoints": "78", + "strength_level": "50", + "id": "6992", + "range_level": "50", + "attack_level": "50" + }, + { + "examine": "On Gielinor", + "melee_animation": "8569", + "range_animation": "0", + "magic_level": "50", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "8570", + "name": "Spirit jelly", + "defence_level": "50", + "safespot": null, + "lifepoints": "78", + "strength_level": "50", + "id": "6993", + "range_level": "50", + "attack_level": "50" + }, + { + "examine": "Hail to the Queen", + "combat_style": "1", + "melee_animation": "6223", + "range_animation": "0", + "magic_level": "25", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "6228", + "name": "Spirit kalphite", + "defence_level": "25", + "safespot": null, + "lifepoints": "35", + "strength_level": "25", + "id": "6994", + "range_level": "25", + "attack_level": "25" + }, + { + "examine": "Hail to the Queen", + "combat_style": "1", + "melee_animation": "6223", + "range_animation": "0", + "magic_level": "25", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "6228", + "name": "Spirit kalphite", + "defence_level": "25", + "safespot": null, + "lifepoints": "35", + "strength_level": "25", + "id": "6995", + "range_level": "25", + "attack_level": "25" + }, + { + "examine": "A stripy little baby raccoon.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Baby raccoon", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "6997", + "range_level": "1", + "attack_level": "1" + }, + { + "spawn_animation": "8595", + "examine": "A ghost of a dragon slain during the god wars.", + "melee_animation": "8591", + "range_animation": "8594", + "combat_audio": "408,410,409", + "poisonous": "true", + "defence_animation": "8592", + "poison_amount": "8", + "magic_animation": "8594", + "death_animation": "8593", + "name": "Revenant dragon", + "defence_level": "85", + "safespot": null, + "lifepoints": "155", + "strength_level": "85", + "id": "6998", + "clue_level": "2", + "range_level": "85", + "attack_level": "85" + }, + { + "spawn_animation": "8595", + "examine": "A ghost of a dragon slain during the god wars.", + "melee_animation": "8591", + "range_animation": "8594", + "combat_audio": "408,410,409", + "poisonous": "true", + "defence_animation": "8592", + "poison_amount": "8", + "magic_animation": "8594", + "death_animation": "8593", + "name": "Revenant dragon", + "defence_level": "85", + "safespot": null, + "lifepoints": "155", + "strength_level": "85", + "id": "6999", + "clue_level": "2", + "range_level": "85", + "attack_level": "85" + }, + { + "examine": "A very large elemental adversary.", + "melee_animation": "4666", + "range_animation": "4666", + "combat_audio": "447,451,450", + "attack_speed": "5", + "magic_level": "1", + "respawn_delay": "20", + "defence_animation": "4664", + "weakness": "1", + "slayer_exp": "111", + "magic_animation": "4666", + "death_animation": "4668", + "name": "Fire giant", + "defence_level": "65", + "safespot": null, + "lifepoints": "111", + "strength_level": "65", + "id": "7003", + "bonuses": "29,29,29,0,0,0,3,2,0,0,0,31,0,0,0", + "range_level": "1", + "attack_level": "65" + }, + { + "examine": "A very large elemental adversary.", + "melee_animation": "4666", + "range_animation": "4666", + "combat_audio": "447,451,450", + "attack_speed": "5", + "magic_level": "1", + "respawn_delay": "20", + "defence_animation": "4664", + "weakness": "1", + "slayer_exp": "111", + "magic_animation": "4666", + "death_animation": "4668", + "name": "Fire giant", + "defence_level": "65", + "safespot": null, + "lifepoints": "111", + "strength_level": "65", + "id": "7004", + "bonuses": "29,29,29,0,0,0,3,2,0,0,0,31,0,0,0", + "range_level": "1", + "attack_level": "65" + }, + { + "examine": "Must be the pack leader.", + "melee_animation": "6559", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "slayer_exp": "74", + "magic_animation": "0", + "death_animation": "6558", + "name": "Big wolf", + "defence_level": "62", + "safespot": null, + "lifepoints": "21", + "strength_level": "60", + "id": "7005", + "aggressive": "true", + "range_level": "1", + "attack_level": "60" + }, + { + "examine": "An active spiny creature.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Grenwall", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7010", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A hiding spiny creature.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Grenwall", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7011", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "What a strange little creature.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Pawya", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7012", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Dug by a Pawya (Not actual exam).", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Earth Mound", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7013", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "What a strange little creature.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Pawya", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7014", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A most unlikely creature.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Platypus", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7021", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A most unlikely creature.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Baby platypus", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7024", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An ogre snack with wings.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Wimpy bird", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7031", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A shy creature with a toxic bite.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Diseased kebbit", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7039", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Fit to wear the uniform?", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ogress banker", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7049", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "She walks as if she owns the place.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Chief Tess", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7051", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A fearsome adversary with no sense of humour.", + "melee_animation": "8636", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "8640", + "name": "Ogress champion", + "defence_level": "48", + "safespot": null, + "lifepoints": "68", + "strength_level": "48", + "id": "7078", + "aggressive": "true", + "range_level": "1", + "attack_level": "48" + }, + { + "examine": "Irascible, belligerent and stupefyingly impolite.", + "melee_animation": "8636", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "8640", + "name": "Ogress warrior", + "defence_level": "45", + "safespot": null, + "lifepoints": "64", + "strength_level": "45", + "id": "7079", + "aggressive": "true", + "range_level": "1", + "attack_level": "45" + }, + { + "examine": "Irascible, beliggerent and stupefyingly impolite.", + "melee_animation": "8637", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "8641", + "name": "Ogress warrior", + "defence_level": "45", + "safespot": null, + "lifepoints": "64", + "strength_level": "45", + "id": "7080", + "aggressive": "true", + "range_level": "1", + "attack_level": "45" + }, + { + "examine": "A large and contentious lady ogre.", + "melee_animation": "8636", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "8640", + "name": "Ogress", + "defence_level": "42", + "safespot": null, + "lifepoints": "60", + "strength_level": "42", + "id": "7081", + "aggressive": "true", + "range_level": "1", + "attack_level": "42" + }, + { + "examine": "A large and contentious lady ogre.", + "melee_animation": "8637", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "8641", + "name": "Ogress", + "defence_level": "42", + "safespot": null, + "lifepoints": "60", + "strength_level": "42", + "id": "7082", + "aggressive": "true", + "range_level": "1", + "attack_level": "42" + }, + { + "examine": "Dead stone defending a dead throne room.", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "name": "Eucalyptus ent", + "defence_level": "51", + "safespot": null, + "lifepoints": "145", + "strength_level": "51", + "id": "7084", + "aggressive": "true", + "range_level": "1", + "attack_level": "51" + }, + { + "examine": "Dead stone defending a dead throne room.", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "name": "Eucalyptus ent", + "defence_level": "54", + "safespot": null, + "lifepoints": "142", + "strength_level": "54", + "id": "7085", + "aggressive": "true", + "range_level": "1", + "attack_level": "54" + }, + { + "examine": "Dead stone defending a dead throne room.", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "name": "Eucalyptus ent", + "defence_level": "57", + "safespot": null, + "lifepoints": "162", + "strength_level": "57", + "id": "7086", + "aggressive": "true", + "range_level": "1", + "attack_level": "57" + }, + { + "examine": "A crazy, evil druid.", + "start_gfx": "105", + "melee_animation": "422", + "range_animation": "422", + "attack_speed": "4", + "magic_level": "10", + "end_gfx": "107", + "respawn_delay": "25", + "defence_animation": "404", + "weakness": "3", + "magic_animation": "422", + "death_animation": "9055", + "name": "Chaos druid", + "defence_level": "12", + "safespot": null, + "lifepoints": "20", + "strength_level": "8", + "id": "7105", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "projectile": "106", + "attack_level": "8" + }, + { + "examine": "Low on brains, high on aggression.", + "melee_animation": "386", + "range_animation": "0", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "50", + "defence_animation": "404", + "magic_animation": "0", + "death_animation": "9055", + "name": "Thug", + "defence_level": "9", + "safespot": null, + "lifepoints": "18", + "strength_level": "5", + "id": "7106", + "aggressive": "true", + "bonuses": "5,5,5,0,0,0,2,3,3,0,0,5,0,0,0", + "clue_level": "0", + "range_level": "1", + "attack_level": "7" + }, + { + "examine": "Low on brains, high on aggression.", + "melee_animation": "386", + "range_animation": "0", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "50", + "defence_animation": "404", + "magic_animation": "0", + "death_animation": "9055", + "name": "Thug", + "defence_level": "9", + "safespot": null, + "lifepoints": "18", + "strength_level": "5", + "id": "7107", + "aggressive": "true", + "bonuses": "5,5,5,0,0,0,2,3,3,0,0,5,0,0,0", + "clue_level": "0", + "range_level": "1", + "attack_level": "7" + }, + { + "examine": "Low on brains, high on aggression.", + "melee_animation": "386", + "range_animation": "0", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "50", + "defence_animation": "404", + "magic_animation": "0", + "death_animation": "9055", + "name": "Thug", + "defence_level": "9", + "safespot": null, + "lifepoints": "18", + "strength_level": "5", + "id": "7108", + "aggressive": "true", + "bonuses": "5,5,5,0,0,0,2,3,3,0,0,5,0,0,0", + "clue_level": "0", + "range_level": "1", + "attack_level": "7" + }, + { + "examine": "Low on brains, high on aggression.", + "melee_animation": "386", + "range_animation": "0", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "50", + "defence_animation": "404", + "magic_animation": "0", + "death_animation": "9055", + "name": "Thug", + "defence_level": "9", + "safespot": null, + "lifepoints": "18", + "strength_level": "5", + "id": "7109", + "aggressive": "true", + "bonuses": "5,5,5,0,0,0,2,3,3,0,0,5,0,0,0", + "clue_level": "0", + "range_level": "1", + "attack_level": "7" + }, + { + "examine": "Low on brains, high on aggression.", + "melee_animation": "386", + "range_animation": "0", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "50", + "defence_animation": "404", + "magic_animation": "0", + "death_animation": "9055", + "name": "Thug", + "defence_level": "9", + "safespot": null, + "lifepoints": "18", + "strength_level": "5", + "id": "7110", + "aggressive": "true", + "bonuses": "5,5,5,0,0,0,2,3,3,0,0,5,0,0,0", + "clue_level": "0", + "range_level": "1", + "attack_level": "7" + }, + { + "examine": "Low on brains, high on aggression.", + "melee_animation": "386", + "range_animation": "0", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "50", + "defence_animation": "404", + "magic_animation": "0", + "death_animation": "9055", + "name": "Thug", + "defence_level": "9", + "safespot": null, + "lifepoints": "18", + "strength_level": "5", + "id": "7111", + "aggressive": "true", + "bonuses": "5,5,5,0,0,0,2,3,3,0,0,5,0,0,0", + "clue_level": "0", + "range_level": "1", + "attack_level": "7" + }, + { + "examine": "Low on brains, high on aggression.", + "melee_animation": "386", + "range_animation": "0", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "50", + "defence_animation": "404", + "magic_animation": "0", + "death_animation": "9055", + "name": "Thug", + "defence_level": "9", + "safespot": null, + "lifepoints": "18", + "strength_level": "5", + "id": "7112", + "aggressive": "true", + "bonuses": "5,5,5,0,0,0,2,3,3,0,0,5,0,0,0", + "clue_level": "0", + "range_level": "1", + "attack_level": "7" + }, + { + "examine": "Low on brains, high on aggression.", + "melee_animation": "386", + "range_animation": "0", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "50", + "defence_animation": "404", + "magic_animation": "0", + "death_animation": "9055", + "name": "Thug", + "defence_level": "9", + "safespot": null, + "lifepoints": "18", + "strength_level": "5", + "id": "7113", + "aggressive": "true", + "bonuses": "5,5,5,0,0,0,2,3,3,0,0,5,0,0,0", + "clue_level": "0", + "range_level": "1", + "attack_level": "7" + }, + { + "examine": "Low on brains, high on aggression.", + "melee_animation": "386", + "range_animation": "0", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "50", + "defence_animation": "404", + "magic_animation": "0", + "death_animation": "9055", + "name": "Thug", + "defence_level": "9", + "safespot": null, + "lifepoints": "18", + "strength_level": "5", + "id": "7114", + "aggressive": "true", + "bonuses": "5,5,5,0,0,0,2,3,3,0,0,5,0,0,0", + "clue_level": "0", + "range_level": "1", + "attack_level": "7" + }, + { + "examine": "He seems to be enjoying his time in the bar.", + "melee_animation": "0", + "range_animation": "0", + "magic_level": "1", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Thaki the delivery dwarf", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7115", + "bonuses": "5,5,0,0,0,0,2,3,3,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of King Tyras's men.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Tyras guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7120", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A hungry-looking rabbit.", + "melee_animation": "0", + "range_animation": "0", + "respawn_delay": "50", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Rabbit", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7125", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A gnome farmer.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Farmer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7128", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A gnome farmer.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Farmer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7130", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Owner of this homestead.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Mrs. Winkin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7132", + "range_level": "1", + "attack_level": "1" + }, + { + "agg_radius": "64", + "examine": "That's one big Ork... ", + "melee_animation": "8754", + "attack_speed": "6", + "respawn_delay": "60", + "defence_animation": "8755", + "death_animation": "8756", + "name": "Bork", + "defence_level": "80", + "lifepoints": "300", + "strength_level": "90", + "id": "7133", + "bonuses": "200,120,100,300,300,120,400,500,300,200,300,400,200,90,0", + "range_level": "1", + "attack_level": "100" + }, + { + "examine": "A native of Tai Bwo Wannai.", + "name": "Sharimika", + "id": "2505" + }, + { + "examine": "A native of Tai Bwo Wannai.", + "name": "Sharimika", + "id": "2506" + }, + { + "examine": "A native of Tai Bwo Wannai.", + "name": "Mamma Bufetta", + "id": "2508" + }, + { + "examine": "A native of Tai Bwo Wannai.", + "name": "Mamma Bufetta", + "id": "2509" + }, + { + "examine": "A native of Tai Bwo Wannai.", + "name": "Layleen", + "id": "2511" + }, + { + "examine": "A native of Tai Bwo Wannai.", + "name": "Layleen", + "id": "2512" + }, + { + "examine": "A native of Tai Bwo Wannai.", + "name": "Karaday", + "id": "2514" + }, + { + "examine": "A native of Tai Bwo Wannai.", + "name": "Karaday", + "id": "2515" + }, + { + "examine": "A native of Tai Bwo Wannai.", + "name": "Safta Doc", + "id": "2517" + }, + { + "examine": "A native of Tai Bwo Wannai.", + "name": "Safta Doc", + "id": "2518" + }, + { + "examine": "A native of Tai Bwo Wannai.", + "name": "Gabooty", + "id": "2520" + }, + { + "examine": "A native of Tai Bwo Wannai.", + "name": "Gabooty", + "id": "2521" + }, + { + "examine": "A native of Tai Bwo Wannai.", + "name": "Fanellaman", + "id": "2523" + }, + { + "examine": "A native of Tai Bwo Wannai.", + "name": "Fanellaman", + "id": "2524" + }, + { + "examine": "A native of Tai Bwo Wannai.", + "name": "Jagbakoba", + "id": "2526" + }, + { + "examine": "A native of Tai Bwo Wannai.", + "name": "Jagbakoba", + "id": "2527" + }, + { + "examine": "A native of Tai Bwo Wannai.", + "name": "Murcaily", + "id": "2529" + }, + { + "examine": "A native of Tai Bwo Wannai.", + "name": "Murcaily", + "id": "2530" + }, + { + "examine": "A native of Tai Bwo Wannai.", + "name": "Rionasta", + "id": "2532" + }, + { + "examine": "A native of Tai Bwo Wannai.", + "name": "Rionasta", + "id": "2533" + }, + { + "agg_radius": "64", + "melee_animation": "8754", + "attack_speed": "8", + "respawn_delay": "60", + "defence_animation": "8755", + "death_animation": "8756", + "name": "Bork", + "defence_level": "1", + "safespot": null, + "lifepoints": "300", + "strength_level": "1", + "id": "7134", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Aww, aren't they the cutest li - Argh!", + "melee_animation": "8760", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "8761", + "name": "Ork legion", + "defence_level": "57", + "poison_immune": "true", + "safespot": null, + "lifepoints": "100", + "strength_level": "68", + "id": "7135", + "aggressive": "true", + "bonuses": "5,10,3,5,3,5,5,5,10,0,0,0,0,0,0", + "range_level": "68", + "attack_level": "68" + }, + { + "examine": "A powerful wizard.", + "combat_style": "2", + "attack_speed": "25", + "magic_level": "90", + "spell_id": "11", + "name": "Dagon'hai Elite", + "defence_level": "40", + "safespot": null, + "lifepoints": "70", + "strength_level": "90", + "id": "7137", + "aggressive": "true", + "bonuses": "220,190,140,120,120,130,90,120,120,200,100,154,150,93,190", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A monk of the Dagon'hai.", + "melee_animation": "422", + "range_animation": "0", + "attack_speed": "5", + "magic_level": "98", + "respawn_delay": "60", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "836", + "name": "Dagon'hai Monk", + "defence_level": "80", + "safespot": null, + "lifepoints": "88", + "strength_level": "84", + "id": "7138", + "aggressive": "true", + "range_level": "1", + "attack_level": "84" + }, + { + "examine": "A monk of the Dagon'hai.", + "melee_animation": "422", + "range_animation": "0", + "attack_speed": "5", + "magic_level": "98", + "respawn_delay": "60", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "836", + "name": "Dagon'hai Monk", + "defence_level": "80", + "safespot": null, + "lifepoints": "88", + "strength_level": "84", + "id": "7139", + "aggressive": "true", + "range_level": "1", + "attack_level": "84" + }, + { + "examine": "A monk of the Dagon'hai.", + "melee_animation": "422", + "range_animation": "0", + "attack_speed": "5", + "magic_level": "98", + "respawn_delay": "60", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "836", + "name": "Dagon'hai Monk", + "defence_level": "80", + "safespot": null, + "lifepoints": "88", + "strength_level": "84", + "id": "7140", + "aggressive": "true", + "range_level": "1", + "attack_level": "84" + }, + { + "examine": "He seems to have gone mad.", + "melee_animation": "426", + "range_animation": "426", + "magic_level": "25", + "defence_animation": "0", + "weakness": "1", + "magic_animation": "0", + "death_animation": "836", + "name": "null", + "defence_level": "25", + "safespot": null, + "lifepoints": "4", + "strength_level": "25", + "id": "7141", + "aggressive": "true", + "range_level": "25", + "attack_level": "25" + }, + { + "examine": "He thumps people who cheat.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Guard", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7142", + "clue_level": "1", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An imprisoned gublinch.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Gublinch jailmate", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7144", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An imprisoned gublinch.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Gublinchette jailmate", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7145", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An imprisoned gublinch.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Gublinchette jailmate", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7146", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An imprisoned gublinch.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Gublinch jailmate", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7147", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An imprisoned gublinch.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Gublinch jailmate", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7148", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An imprisoned gublinch.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Gublinch jailmate", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7149", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An imprisoned gublinch.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Gublinch jailmate", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7150", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A person sitting an exam.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Student", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7152", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A person sitting an exam.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Student", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7156", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A person sitting an exam.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Student", + "defence_level": "1", + "lifepoints": "10", + "strength_level": "1", + "id": "7157", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A household pest.", + "melee_animation": "8785", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "8788", + "name": "Cockroach drone", + "defence_level": "3", + "safespot": null, + "lifepoints": "4", + "strength_level": "3", + "id": "7158", + "range_level": "1", + "attack_level": "3" + }, + { + "examine": "Eurgh! A big bug.", + "melee_animation": "8787", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "8790", + "name": "Cockroach worker", + "defence_level": "70", + "safespot": null, + "lifepoints": "31", + "strength_level": "22", + "id": "7159", + "range_level": "1", + "attack_level": "22" + }, + { + "examine": "Euww! A giant bug.", + "melee_animation": "8786", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "8789", + "name": "Cockroach soldier", + "defence_level": "70", + "safespot": null, + "lifepoints": "97", + "strength_level": "26", + "id": "7160", + "bonuses": "10,10,10,5,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "38" + }, + { + "melee_animation": "422", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Mugger", + "defence_level": "1", + "safespot": null, + "lifepoints": "8", + "strength_level": "1", + "id": "7161", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "422", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Mugger", + "defence_level": "1", + "safespot": null, + "lifepoints": "8", + "strength_level": "1", + "id": "7162", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A popular dwarven delicacy.", + "melee_animation": "4933", + "range_animation": "4933", + "combat_audio": "703,705,704", + "attack_speed": "5", + "defence_animation": "4934", + "magic_animation": "4933", + "death_animation": "4935", + "name": "Rat", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "1", + "id": "7202", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A popular dwarven delicacy.", + "melee_animation": "4933", + "range_animation": "4933", + "combat_audio": "703,705,704", + "attack_speed": "5", + "defence_animation": "4934", + "magic_animation": "4933", + "death_animation": "4935", + "name": "Rat", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "1", + "id": "7204", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It seems to have eaten a lot of chocolate.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Cockroach", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7206", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It's searching for crumbs of chocolate.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Spider", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7207", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It seems to have eaten a lot of chocolate.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Snail", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7209", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Baby monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "629,631,630", + "strength_level": "1", + "id": "7210", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "629,631,630", + "strength_level": "1", + "id": "7211", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Baby monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "629,631,630", + "strength_level": "1", + "id": "7212", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "629,631,630", + "strength_level": "1", + "id": "7213", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Baby monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "629,631,630", + "strength_level": "1", + "id": "7214", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "629,631,630", + "strength_level": "1", + "id": "7215", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Baby monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "629,631,630", + "strength_level": "1", + "id": "7216", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "629,631,630", + "strength_level": "1", + "id": "7217", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Baby monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "629,631,630", + "strength_level": "1", + "id": "7218", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "629,631,630", + "strength_level": "1", + "id": "7219", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Baby monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "629,631,630", + "strength_level": "1", + "id": "7220", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "629,631,630", + "strength_level": "1", + "id": "7221", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Baby monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "629,631,630", + "strength_level": "1", + "id": "7222", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "629,631,630", + "strength_level": "1", + "id": "7223", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Baby monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "629,631,630", + "strength_level": "1", + "id": "7224", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "629,631,630", + "strength_level": "1", + "id": "7225", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Baby monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "629,631,630", + "strength_level": "1", + "id": "7226", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "629,631,630", + "strength_level": "1", + "id": "7227", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It's a tiny", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "629,631,630", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Baby monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7228", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It's a tiny", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "629,631,630", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Baby monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7229", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It's a tiny", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "629,631,630", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Baby monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7230", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It's a tiny", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "629,631,630", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Baby monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7231", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It's a tiny", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "629,631,630", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Baby monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7232", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It's a tiny", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "629,631,630", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Baby monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7233", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Baby monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "629,631,630", + "strength_level": "1", + "id": "7234", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Baby monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "629,631,630", + "strength_level": "1", + "id": "7235", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Baby monkey", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "629,631,630", + "strength_level": "1", + "id": "7236", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A stripy little baby raccoon.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Baby Raccoon", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7275", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It's so adorably tiny!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Baby gecko", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7285", + "range_level": "1", + "attack_level": "1" + }, + { + "combat_style": "0", + "melee_animation": "8222", + "magic_level": "70", + "respawn_delay": "0", + "defence_animation": "8224", + "death_animation": "8226", + "name": "Swamp titan", + "defence_level": "78", + "safespot": null, + "lifepoints": "556", + "strength_level": "1", + "id": "7329", + "bonuses": "60,60,60,60,50,50,100,200,200,28,100,100,70,70,70", + "range_level": "70", + "attack_level": "1" + }, + { + "examine": "Do you hear duelling banjos?", + "combat_style": "0", + "melee_animation": "8222", + "range_animation": "0", + "magic_level": "65", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "8226", + "name": "Swamp titan", + "defence_level": "65", + "safespot": null, + "lifepoints": "117", + "strength_level": "60", + "id": "7330", + "bonuses": "60,60,60,60,50,50,100,200,200,28,100,100,70,70,70", + "range_level": "65", + "attack_level": "60" + }, + { + "examine": "It buzzes and bites. Nasty.", + "melee_animation": "8032", + "range_animation": "8032", + "magic_level": "21", + "respawn_delay": "50", + "defence_animation": "8034", + "magic_animation": "8032", + "death_animation": "8033", + "name": "Spirit mosquito", + "defence_level": "25", + "poison_immune": "true", + "safespot": null, + "lifepoints": "43", + "strength_level": "24", + "id": "7331", + "bonuses": "45,49,42,39,47,46,29,43,51,16,53,10,0,0,0", + "range_level": "25", + "attack_level": "28" + }, + { + "examine": "It buzzes and bites. Nasty.", + "melee_animation": "8032", + "range_animation": "8032", + "magic_level": "21", + "respawn_delay": "50", + "defence_animation": "8034", + "weakness": "10", + "magic_animation": "8032", + "death_animation": "8033", + "name": "Spirit mosquito", + "defence_level": "25", + "poison_immune": "true", + "safespot": null, + "lifepoints": "43", + "strength_level": "24", + "id": "7332", + "bonuses": "45,49,42,39,47,46,29,43,51,16,53,10,0,0,0", + "range_level": "25", + "attack_level": "28" + }, + { + "examine": "It spins.", + "melee_animation": "8172", + "range_animation": "0", + "magic_level": "34", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "8176", + "name": "Void spinner", + "defence_level": "34", + "safespot": null, + "lifepoints": "48", + "strength_level": "34", + "id": "7333", + "range_level": "34", + "attack_level": "34" + }, + { + "examine": "It spins.", + "melee_animation": "8172", + "range_animation": "0", + "magic_level": "34", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "8176", + "name": "Void spinner", + "defence_level": "34", + "safespot": null, + "lifepoints": "48", + "strength_level": "34", + "id": "7334", + "range_level": "34", + "attack_level": "34" + }, + { + "examine": "This one will burn right through the net!", + "combat_style": "1", + "melee_animation": "7863", + "range_animation": "0", + "magic_level": "60", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7864", + "name": "Forge regent", + "defence_level": "60", + "safespot": null, + "lifepoints": "108", + "strength_level": "60", + "id": "7335", + "range_level": "60", + "attack_level": "60" + }, + { + "examine": "This one will burn right through the net!", + "combat_style": "1", + "melee_animation": "7863", + "range_animation": "0", + "magic_level": "60", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7864", + "name": "Forge regent", + "defence_level": "60", + "safespot": null, + "lifepoints": "108", + "strength_level": "60", + "id": "7336", + "range_level": "60", + "attack_level": "60" + }, + { + "examine": "Fast cat is fast.", + "melee_animation": "5228", + "range_animation": "0", + "magic_level": "50", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "5230", + "name": "Spirit larupia", + "defence_level": "50", + "safespot": null, + "lifepoints": "81", + "strength_level": "50", + "id": "7337", + "range_level": "50", + "attack_level": "50" + }, + { + "examine": "Fast cat is fast.", + "melee_animation": "5228", + "range_animation": "0", + "magic_level": "50", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "5230", + "name": "Spirit larupia", + "defence_level": "50", + "safespot": null, + "lifepoints": "81", + "strength_level": "50", + "id": "7338", + "range_level": "50", + "attack_level": "50" + }, + { + "examine": "It'll kill your enemies, and makes a great cup of tea.", + "combat_style": "1", + "melee_animation": "7879", + "range_animation": "422", + "magic_level": "70", + "respawn_delay": "50", + "defence_animation": "7878", + "weakness": "0", + "magic_animation": "422", + "death_animation": "7880", + "name": "Geyser titan", + "defence_level": "70", + "poison_immune": "true", + "safespot": null, + "lifepoints": "620", + "strength_level": "70", + "id": "7339", + "bonuses": "115,115,115,110,110,102,95,110,110,105,78,120,115,120,120", + "range_level": "70", + "attack_level": "70" + }, + { + "examine": "It'll kill your enemies, and makes a great cup of tea.", + "combat_style": "1", + "melee_animation": "7879", + "range_animation": "422", + "magic_level": "70", + "respawn_delay": "50", + "defence_animation": "7878", + "weakness": "0", + "slayer_exp": "0", + "magic_animation": "422", + "death_animation": "7880", + "name": "Geyser titan", + "defence_level": "70", + "poison_immune": "true", + "safespot": null, + "lifepoints": "620", + "strength_level": "70", + "id": "7340", + "bonuses": "115,115,115,110,110,102,95,110,110,105,78,120,115,120,120", + "range_level": "70", + "attack_level": "70" + }, + { + "examine": "Made of lava.", + "combat_style": "0", + "melee_animation": "7980", + "range_animation": "0", + "magic_level": "65", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7979", + "name": "Lava titan", + "defence_level": "65", + "safespot": null, + "lifepoints": "115", + "strength_level": "65", + "id": "7341", + "bonuses": "100,120,90,100,90,90,40,50,0,0,0,0,0,0,0", + "range_level": "65", + "attack_level": "65" + }, + { + "examine": "Made of lava.", + "combat_style": "0", + "melee_animation": "7980", + "range_animation": "0", + "magic_level": "65", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7979", + "name": "Lava titan", + "defence_level": "65", + "safespot": null, + "lifepoints": "115", + "strength_level": "65", + "id": "7342", + "bonuses": "100,120,90,100,90,90,40,50,0,0,0,0,0,0,0", + "range_level": "65", + "attack_level": "65" + }, + { + "examine": "The King of the Titans!", + "combat_style": "1", + "melee_animation": "8183", + "range_animation": "8183", + "magic_level": "70", + "respawn_delay": "15", + "defence_animation": "8185", + "weakness": "10", + "slayer_exp": "0", + "magic_animation": "8183", + "death_animation": "8184", + "name": "Steel titan", + "defence_level": "70", + "poison_immune": "true", + "safespot": null, + "lifepoints": "750", + "strength_level": "70", + "id": "7343", + "bonuses": "105,105,105,100,110,102,95,110,110,105,78,120,115,120,120", + "range_level": "70", + "attack_level": "70" + }, + { + "examine": "The King of the Titans!", + "combat_style": "1", + "melee_animation": "8183", + "range_animation": "8183", + "magic_level": "70", + "respawn_delay": "15", + "defence_animation": "8185", + "weakness": "10", + "slayer_exp": "0", + "magic_animation": "8183", + "death_animation": "8184", + "name": "Steel titan", + "defence_level": "70", + "poison_immune": "true", + "safespot": null, + "lifepoints": "750", + "strength_level": "70", + "id": "7344", + "bonuses": "105,105,105,100,110,102,95,110,110,105,78,120,115,120,120", + "range_level": "70", + "attack_level": "70" + }, + { + "examine": "Four fists can make quite an impression IN someone...", + "melee_animation": "8050", + "magic_level": "60", + "respawn_delay": "0", + "defence_animation": "8051", + "death_animation": "8052", + "name": "Obsidian golem", + "defence_level": "60", + "safespot": null, + "lifepoints": "10", + "strength_level": "60", + "id": "7345", + "bonuses": "100,120,90,100,90,90,40,50,0,0,0,0,0,0,0", + "range_level": "60", + "attack_level": "60" + }, + { + "examine": "Four fists can make quite an impression IN someone...", + "melee_animation": "8050", + "range_animation": "0", + "magic_level": "60", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "8052", + "name": "Obsidian golem", + "defence_level": "60", + "safespot": null, + "lifepoints": "104", + "strength_level": "60", + "id": "7346", + "bonuses": "100,120,90,100,90,90,40,50,0,0,0,0,0,0,0", + "range_level": "60", + "attack_level": "60" + }, + { + "examine": "If a normal black cat is bad luck", + "melee_animation": "5989", + "range_animation": "0", + "magic_level": "60", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "5990", + "name": "Talon beast", + "defence_level": "60", + "safespot": null, + "lifepoints": "110", + "strength_level": "60", + "id": "7347", + "range_level": "60", + "attack_level": "60" + }, + { + "examine": "If a normal black cat is bad luck", + "melee_animation": "5989", + "range_animation": "0", + "magic_level": "60", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "5990", + "name": "Talon beast", + "defence_level": "60", + "safespot": null, + "lifepoints": "110", + "strength_level": "60", + "id": "7348", + "range_level": "60", + "attack_level": "60" + }, + { + "examine": "Big", + "melee_animation": "7693", + "range_animation": "0", + "magic_level": "70", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7692", + "name": "Abyssal titan", + "defence_level": "70", + "safespot": null, + "lifepoints": "125", + "strength_level": "70", + "id": "7349", + "range_level": "70", + "attack_level": "70" + }, + { + "examine": "Big", + "melee_animation": "7693", + "range_animation": "0", + "magic_level": "70", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7692", + "name": "Abyssal titan", + "defence_level": "70", + "safespot": null, + "lifepoints": "125", + "strength_level": "70", + "id": "7350", + "range_level": "70", + "attack_level": "70" + }, + { + "examine": "It torches.", + "combat_style": "2", + "melee_animation": "8235", + "range_animation": "0", + "magic_level": "34", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "8236", + "name": "Void torcher", + "defence_level": "34", + "safespot": null, + "lifepoints": "48", + "strength_level": "34", + "id": "7351", + "range_level": "34", + "attack_level": "34" + }, + { + "examine": "It torches.", + "combat_style": "2", + "melee_animation": "8235", + "range_animation": "0", + "magic_level": "34", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "8236", + "name": "Void torcher", + "defence_level": "34", + "safespot": null, + "lifepoints": "48", + "strength_level": "34", + "id": "7352", + "range_level": "34", + "attack_level": "34" + }, + { + "examine": "Looks a little...volatile.", + "combat_style": "1", + "melee_animation": "7755", + "range_animation": "0", + "magic_level": "29", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7758", + "name": "Giant chinchompa", + "defence_level": "29", + "safespot": null, + "lifepoints": "41", + "strength_level": "29", + "id": "7353", + "range_level": "29", + "attack_level": "29" + }, + { + "examine": "Looks a little...volatile.", + "combat_style": "1", + "melee_animation": "7755", + "range_animation": "0", + "magic_level": "29", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7758", + "name": "Giant chinchompa", + "defence_level": "29", + "safespot": null, + "lifepoints": "41", + "strength_level": "29", + "id": "7354", + "range_level": "29", + "attack_level": "29" + }, + { + "examine": "Scorching!", + "combat_style": "2", + "melee_animation": "7834", + "range_animation": "7834", + "attack_speed": "5", + "magic_level": "40", + "respawn_delay": "50", + "defence_animation": "7832", + "weakness": "10", + "slayer_exp": "0", + "magic_animation": "7834", + "death_animation": "7833", + "name": "Fire titan", + "defence_level": "40", + "poison_immune": "true", + "safespot": null, + "lifepoints": "476", + "strength_level": "30", + "id": "7355", + "bonuses": "64,45,76,82,120,84,140,120,106,89,113,80,0,0,0", + "range_level": "30", + "attack_level": "40" + }, + { + "examine": "Scorching!", + "combat_style": "2", + "melee_animation": "7834", + "range_animation": "7834", + "attack_speed": "5", + "magic_level": "40", + "respawn_delay": "50", + "defence_animation": "7832", + "weakness": "10", + "slayer_exp": "0", + "magic_animation": "7834", + "death_animation": "7833", + "name": "Fire titan", + "defence_level": "40", + "poison_immune": "true", + "safespot": null, + "lifepoints": "476", + "strength_level": "30", + "id": "7356", + "bonuses": "64,45,76,82,208,84,221,231,179,89,113,23,0,0,0", + "range_level": "30", + "attack_level": "40" + }, + { + "examine": "Gathers rolling stones to bash people with.", + "melee_animation": "7844", + "range_animation": "7834", + "attack_speed": "5", + "magic_level": "40", + "respawn_delay": "50", + "defence_animation": "7832", + "weakness": "10", + "slayer_exp": "0", + "magic_animation": "7834", + "death_animation": "7843", + "name": "Moss titan", + "defence_level": "40", + "poison_immune": "true", + "safespot": null, + "lifepoints": "476", + "strength_level": "30", + "id": "7357", + "bonuses": "64,45,76,82,120,84,140,120,106,89,113,80,0,0,0", + "range_level": "30", + "attack_level": "40" + }, + { + "examine": "Gathers rolling stones to bash people with.", + "melee_animation": "7844", + "range_animation": "7834", + "attack_speed": "5", + "magic_level": "40", + "respawn_delay": "50", + "defence_animation": "7832", + "weakness": "10", + "slayer_exp": "0", + "magic_animation": "7834", + "death_animation": "7843", + "name": "Moss titan", + "defence_level": "40", + "poison_immune": "true", + "safespot": null, + "lifepoints": "476", + "strength_level": "30", + "id": "7358", + "bonuses": "64,45,76,82,120,84,140,120,106,89,113,80,0,0,0", + "range_level": "30", + "attack_level": "40" + }, + { + "examine": "Frosty the highly violent snowman.", + "melee_animation": "7845", + "range_animation": "7834", + "attack_speed": "5", + "magic_level": "40", + "respawn_delay": "50", + "defence_animation": "7832", + "weakness": "10", + "slayer_exp": "0", + "magic_animation": "7834", + "death_animation": "7846", + "name": "Ice titan", + "defence_level": "40", + "poison_immune": "true", + "safespot": null, + "lifepoints": "476", + "strength_level": "30", + "id": "7359", + "bonuses": "64,45,76,82,120,84,140,120,106,89,113,80,0,0,0", + "range_level": "30", + "attack_level": "40" + }, + { + "examine": "Frosty the highly violent snowman.", + "melee_animation": "7845", + "range_animation": "7834", + "attack_speed": "5", + "magic_level": "40", + "respawn_delay": "50", + "defence_animation": "7832", + "weakness": "10", + "slayer_exp": "0", + "magic_animation": "7834", + "death_animation": "7846", + "name": "Ice titan", + "defence_level": "40", + "poison_immune": "true", + "safespot": null, + "lifepoints": "476", + "strength_level": "30", + "id": "7360", + "bonuses": "64,45,76,82,120,84,140,120,106,89,113,80,0,0,0", + "range_level": "30", + "attack_level": "40" + }, + { + "examine": "This bat burned down the belfry.", + "combat_style": "2", + "melee_animation": "8257", + "range_animation": "0", + "attack_speed": "3", + "magic_level": "22", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "8258", + "name": "Spirit Tz-Kih", + "defence_level": "22", + "safespot": null, + "lifepoints": "31", + "strength_level": "22", + "id": "7361", + "range_level": "22", + "attack_level": "22" + }, + { + "examine": "This bat burned down the belfry.", + "combat_style": "2", + "melee_animation": "8257", + "range_animation": "0", + "attack_speed": "3", + "magic_level": "22", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "8258", + "name": "Spirit Tz-Kih", + "defence_level": "22", + "safespot": null, + "lifepoints": "31", + "strength_level": "22", + "id": "7362", + "range_level": "22", + "attack_level": "22" + }, + { + "examine": "Those spikes are pretty big!", + "start_gfx": "1367", + "melee_animation": "5229", + "range_animation": "0", + "magic_level": "50", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "5230", + "name": "Spirit graahk", + "defence_level": "50", + "safespot": null, + "lifepoints": "81", + "strength_level": "50", + "id": "7363", + "range_level": "50", + "attack_level": "50" + }, + { + "examine": "Those spikes are pretty big!", + "start_gfx": "1367", + "melee_animation": "5229", + "range_animation": "0", + "magic_level": "50", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "5230", + "name": "Spirit graahk", + "defence_level": "50", + "safespot": null, + "lifepoints": "81", + "strength_level": "50", + "id": "7364", + "range_level": "50", + "attack_level": "50" + }, + { + "examine": "Those teeth are pretty big!", + "start_gfx": "1365", + "melee_animation": "5228", + "range_animation": "0", + "magic_level": "50", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "5230", + "name": "Spirit kyatt", + "defence_level": "50", + "safespot": null, + "lifepoints": "81", + "strength_level": "50", + "id": "7365", + "range_level": "50", + "attack_level": "50" + }, + { + "examine": "Those teeth are pretty big!", + "start_gfx": "1365", + "melee_animation": "5228", + "range_animation": "0", + "magic_level": "50", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "5230", + "name": "Spirit kyatt", + "defence_level": "50", + "safespot": null, + "lifepoints": "81", + "strength_level": "50", + "id": "7366", + "range_level": "50", + "attack_level": "50" + }, + { + "examine": "It shifts.", + "melee_animation": "8131", + "range_animation": "0", + "magic_level": "34", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "8133", + "name": "Void shifter", + "defence_level": "34", + "safespot": null, + "lifepoints": "48", + "strength_level": "34", + "id": "7367", + "range_level": "34", + "attack_level": "34" + }, + { + "examine": "It shifts.", + "melee_animation": "8131", + "range_animation": "0", + "magic_level": "34", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "8133", + "name": "Void shifter", + "defence_level": "34", + "safespot": null, + "lifepoints": "48", + "strength_level": "34", + "id": "7368", + "range_level": "34", + "attack_level": "34" + }, + { + "examine": "It ravages.", + "melee_animation": "8086", + "range_animation": "0", + "magic_level": "34", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "8087", + "name": "Void ravager", + "defence_level": "34", + "safespot": null, + "lifepoints": "48", + "strength_level": "34", + "id": "7370", + "range_level": "34", + "attack_level": "34" + }, + { + "examine": "It ravages.", + "melee_animation": "8086", + "range_animation": "0", + "magic_level": "34", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "8087", + "name": "Void ravager", + "defence_level": "34", + "safespot": null, + "lifepoints": "48", + "strength_level": "34", + "id": "7371", + "range_level": "34", + "attack_level": "34" + }, + { + "examine": "It's like a little stomach on wings.", + "melee_animation": "7994", + "range_animation": "0", + "magic_level": "60", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7996", + "name": "Ravenous locust", + "defence_level": "60", + "safespot": null, + "lifepoints": "100", + "strength_level": "60", + "id": "7373", + "range_level": "60", + "attack_level": "60" + }, + { + "examine": "It's like a little stomach on wings.", + "melee_animation": "7994", + "range_animation": "0", + "magic_level": "60", + "respawn_delay": "0", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "7996", + "name": "Ravenous locust", + "defence_level": "60", + "safespot": null, + "lifepoints": "100", + "strength_level": "60", + "id": "7374", + "range_level": "60", + "attack_level": "60" + }, + { + "examine": "He is an iron man!", + "combat_style": "0", + "melee_animation": "7946", + "magic_level": "65", + "respawn_delay": "0", + "defence_animation": "7948", + "weakness": "10", + "death_animation": "7947", + "name": "Iron titan", + "defence_level": "65", + "safespot": null, + "lifepoints": "694", + "strength_level": "65", + "id": "7375", + "bonuses": "120,130,100,109,80,120,102,90,103,80,100,108,105,66,90", + "range_level": "65", + "attack_level": "65" + }, + { + "examine": "He is an iron man!", + "combat_style": "0", + "melee_animation": "7946", + "combat_audio": "0,0,0", + "magic_level": "65", + "respawn_delay": "0", + "defence_animation": "7948", + "weakness": "10", + "slayer_exp": "0", + "death_animation": "7947", + "name": "Iron titan", + "defence_level": "65", + "safespot": null, + "lifepoints": "694", + "strength_level": "65", + "id": "7376", + "bonuses": "120,130,100,109,80,120,102,90,103,80,100,108,105,66,90", + "range_level": "65", + "attack_level": "65" + }, + { + "examine": "Where did I put the marshmallows?", + "melee_animation": "8080", + "range_animation": "0", + "magic_level": "46", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "8078", + "name": "Pyrelord", + "defence_level": "46", + "safespot": null, + "lifepoints": "65", + "strength_level": "46", + "id": "7377", + "range_level": "46", + "attack_level": "46" + }, + { + "examine": "Where did I put the marshmallows?", + "melee_animation": "8080", + "range_animation": "0", + "magic_level": "46", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "death_animation": "8078", + "name": "Pyrelord", + "defence_level": "46", + "safespot": null, + "lifepoints": "65", + "strength_level": "46", + "id": "7378", + "range_level": "46", + "attack_level": "46" + }, + { + "melee_animation": "8965", + "respawn_delay": "60", + "defence_animation": "8966", + "death_animation": "8967", + "name": "Elfinlocks", + "defence_level": "1", + "safespot": null, + "lifepoints": "120", + "strength_level": "1", + "id": "7379", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "8965", + "respawn_delay": "60", + "defence_animation": "8966", + "death_animation": "8967", + "name": "Missi Sissi", + "defence_level": "1", + "safespot": null, + "lifepoints": "120", + "strength_level": "1", + "id": "7380", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "combat_style": "2", + "melee_animation": "8955", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "8957", + "death_animation": "8956", + "name": "Missi Sissi", + "defence_level": "1", + "safespot": null, + "lifepoints": "75", + "strength_level": "1", + "id": "7381", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "combat_style": "2", + "melee_animation": "8955", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "8957", + "death_animation": "8956", + "name": "Uberlass", + "defence_level": "1", + "safespot": null, + "lifepoints": "75", + "strength_level": "1", + "id": "7382", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The vengeful spirit of one who died within Daemonheim.", + "melee_animation": "0", + "range_animation": "0", + "magic_level": "25", + "defence_animation": "0", + "weakness": "3", + "magic_animation": "0", + "name": "Elisabeta", + "defence_level": "25", + "safespot": null, + "lifepoints": "7", + "strength_level": "25", + "id": "7398", + "aggressive": "true", + "range_level": "25", + "attack_level": "25" + }, + { + "examine": "A popular dwarven delicacy.", + "melee_animation": "2705", + "range_animation": "2705", + "combat_audio": "3102,3104,3103", + "attack_speed": "5", + "defence_animation": "2706", + "magic_animation": "2705", + "death_animation": "2707", + "name": "Rat", + "defence_level": "1", + "safespot": null, + "lifepoints": "2", + "strength_level": "1", + "id": "7417", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "An impling manager: what a terrifying thought!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Wigglewoo", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7425", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "This worker looks after the incubator.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Orangeowns", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7426", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Elf warrior", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "425,427,426", + "strength_level": "1", + "id": "7438", + "clue_level": "2", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Elf warrior", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "425,427,426", + "strength_level": "1", + "id": "7439", + "clue_level": "2", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Elf warrior", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "425,427,426", + "strength_level": "1", + "id": "7440", + "clue_level": "2", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Elf warrior", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "425,427,426", + "strength_level": "1", + "id": "7441", + "clue_level": "2", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He holds up passers by.", + "melee_animation": "386", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "836", + "name": "Eudav", + "defence_level": "8", + "safespot": null, + "lifepoints": "11", + "strength_level": "8", + "id": "7443", + "aggressive": "true", + "range_level": "1", + "attack_level": "8" + }, + { + "name": "Fairtrade", + "defence_level": "1", + "safespot": null, + "lifepoints": "75", + "strength_level": "1", + "attack_speed": "5", + "id": "7459", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Teapotspout", + "defence_level": "1", + "safespot": null, + "lifepoints": "75", + "strength_level": "1", + "attack_speed": "5", + "id": "7460", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "examine": "A popular dwarven delicacy.", + "melee_animation": "4933", + "range_animation": "4933", + "combat_audio": "703,705,704", + "attack_speed": "5", + "defence_animation": "4934", + "magic_animation": "4933", + "death_animation": "4935", + "name": "Rat", + "defence_level": "1", + "safespot": null, + "lifepoints": "5", + "strength_level": "1", + "id": "7461", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It's bubbling, gross.", + "melee_animation": "9130", + "range_animation": "9130", + "attack_speed": "5", + "respawn_delay": "20", + "defence_animation": "9132", + "magic_animation": "9130", + "death_animation": "9131", + "name": "Hotwater", + "defence_level": "99", + "safespot": null, + "lifepoints": "120", + "strength_level": "99", + "id": "7462", + "bonuses": "20,20,20,20,20,20,20,20,20,20,20,20,45,20,0", + "range_level": "1", + "attack_level": "99" + }, + { + "examine": "It's bubbling, gross.", + "melee_animation": "9130", + "range_animation": "9130", + "attack_speed": "5", + "respawn_delay": "20", + "defence_animation": "9132", + "magic_animation": "9130", + "death_animation": "9131", + "name": "Hotwater", + "defence_level": "99", + "safespot": null, + "lifepoints": "120", + "strength_level": "99", + "id": "7463", + "bonuses": "20,20,20,20,20,20,20,20,20,20,20,20,45,20,0", + "range_level": "1", + "attack_level": "99" + }, + { + "examine": "His usual sunny disposition is not in evidence.", + "range_animation": "0", + "magic_level": "30", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "10", + "magic_animation": "0", + "name": "Lady Seenit", + "defence_level": "30", + "safespot": null, + "lifepoints": "42", + "strength_level": "30", + "id": "7475", + "range_level": "30", + "attack_level": "30" + }, + { + "name": "Berrybree", + "defence_level": "1", + "safespot": null, + "lifepoints": "50", + "strength_level": "1", + "id": "7476", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Stuffstuffer", + "defence_level": "1", + "safespot": null, + "lifepoints": "50", + "strength_level": "1", + "id": "7477", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Learking", + "defence_level": "1", + "safespot": null, + "lifepoints": "60", + "strength_level": "1", + "id": "7479", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Rachael", + "defence_level": "1", + "safespot": null, + "lifepoints": "70", + "strength_level": "1", + "id": "7480", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "examine": "You clearly can't live on treasure alone.", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5491", + "name": "Cool Mom227", + "defence_level": "30", + "safespot": null, + "lifepoints": "42", + "strength_level": "30", + "id": "7481", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "A testament to the effect of greed.", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5491", + "name": "Purepker895", + "defence_level": "30", + "safespot": null, + "lifepoints": "42", + "strength_level": "30", + "id": "7482", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "He wanted loot", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5491", + "name": "Pkmaster0036", + "defence_level": "30", + "safespot": null, + "lifepoints": "42", + "strength_level": "30", + "id": "7483", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "Eternally looking for that big payday.", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5491", + "name": "Cow1337killr", + "defence_level": "30", + "safespot": null, + "lifepoints": "42", + "strength_level": "30", + "id": "7484", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "No more tea-breaks for this one.", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5491", + "name": "Mathdude", + "defence_level": "30", + "safespot": null, + "lifepoints": "42", + "strength_level": "30", + "id": "7485", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "Even in death you can smell his feet.", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5491", + "name": "Mathdude", + "defence_level": "30", + "safespot": null, + "lifepoints": "42", + "strength_level": "30", + "id": "7486", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "An anatomist's dream.", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5491", + "name": "1337sp34kr", + "defence_level": "30", + "safespot": null, + "lifepoints": "42", + "strength_level": "30", + "id": "7487", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "A hand seems to be gripping his spine through his chest. Ouch.", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "5491", + "name": "1337sp34kr", + "defence_level": "30", + "safespot": null, + "lifepoints": "42", + "strength_level": "30", + "id": "7488", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "A desert dweller taken to banditry.", + "melee_animation": "9705", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "836", + "name": "Sarah Domin", + "defence_level": "30", + "safespot": null, + "lifepoints": "42", + "strength_level": "30", + "id": "7492", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "Calls himself an archaeologist.", + "melee_animation": "9715", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "836", + "name": "Sarah Domin", + "defence_level": "30", + "safespot": null, + "lifepoints": "42", + "strength_level": "30", + "id": "7493", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "He hasn't found much of use", + "melee_animation": "9705", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "836", + "name": "Sue Spammers", + "defence_level": "30", + "safespot": null, + "lifepoints": "42", + "strength_level": "30", + "id": "7494", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "An amateur historian with added greed.", + "melee_animation": "9715", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "836", + "name": "Killerwail", + "defence_level": "30", + "safespot": null, + "lifepoints": "42", + "strength_level": "30", + "id": "7495", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "It all started with her love of genealogy.", + "melee_animation": "9705", + "range_animation": "0", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "836", + "name": "Wise Old Man", + "defence_level": "30", + "safespot": null, + "lifepoints": "42", + "strength_level": "30", + "id": "7496", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "A rocky horror.", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "name": "Sabre-toothed kyatt", + "defence_level": "27", + "safespot": null, + "lifepoints": "38", + "strength_level": "27", + "id": "7497", + "range_level": "1", + "attack_level": "27" + }, + { + "examine": "This dung beetle has mistaken you for its staple diet.", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "name": "Cerulean twitch", + "defence_level": "30", + "safespot": null, + "lifepoints": "42", + "strength_level": "30", + "id": "7500", + "aggressive": "true", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "It's looking unwell - probably something it ate.", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "name": "Abone", + "defence_level": "30", + "safespot": null, + "lifepoints": "42", + "strength_level": "30", + "id": "7501", + "aggressive": "true", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "Once a valuable contributor to the ecosystem.", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "name": "Mythmaster", + "defence_level": "30", + "safespot": null, + "lifepoints": "42", + "strength_level": "30", + "id": "7502", + "aggressive": "true", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "This is what happens if you play with your food.", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "name": "Donkey Wrong", + "defence_level": "30", + "safespot": null, + "lifepoints": "42", + "strength_level": "30", + "id": "7503", + "aggressive": "true", + "range_level": "1", + "attack_level": "30" + }, + { + "examine": "He likes a good fight", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Creapantic", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7504", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He likes a good fight", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Frondlike", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7505", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "His favourite must be winning.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Happy Spud", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7506", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Blood-thirsty and enthusiastic.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Nobodyhere", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7507", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Probably discussing the strengths and weaknesses of the fighting slaves.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Bluehairlass", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7508", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "His favourite must be winning.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ilikekebabs", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7510", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "His favourite must be winning.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Trunka Lex", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7511", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Probably discussing the strengths and weaknesses of the fighting slaves.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Val Razz", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7512", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Probably discussing the strengths and weaknesses of the fighting slaves.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Abstractclas", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7513", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Bloodthirsty and enthusiastic.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Bigbluebox", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7514", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Bloodthirsty and enthusiastic.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Funorbrox", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7515", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He's asleep.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Morrisnorris", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7518", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He's propping the bar up. Or is it the other way round?", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Matt Blitzer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7519", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He demands to have some booze.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ketchuppl0x", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7520", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "395", + "attack_speed": "6", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Redheadmonky", + "defence_level": "1", + "safespot": null, + "lifepoints": "22", + "strength_level": "1", + "id": "7528", + "range_level": "1", + "attack_level": "1" + }, + { + "slayer_exp": "0", + "examine": "It's an NPC.", + "name": "3sacrowd", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7532", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Not somewhere I want to go...", + "attack_speed": "90", + "magic_level": "70", + "respawn_delay": "125", + "name": "Portal", + "defence_level": "90", + "safespot": null, + "lifepoints": "250", + "strength_level": "1", + "id": "7551", + "bonuses": "200,200,200,100,100,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Not somewhere I want to go...", + "attack_speed": "5", + "magic_level": "50", + "respawn_delay": "125", + "name": "Portal", + "defence_level": "90", + "safespot": null, + "lifepoints": "250", + "strength_level": "1", + "id": "7552", + "bonuses": "200,200,200,200,50,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Not somewhere I want to go...", + "attack_speed": "5", + "magic_level": "90", + "respawn_delay": "125", + "name": "Portal", + "defence_level": "90", + "safespot": null, + "lifepoints": "250", + "strength_level": "1", + "id": "7553", + "bonuses": "200,200,100,200,100,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Not somewhere I want to go...", + "melee_animation": "0", + "range_animation": "0", + "attack_speed": "5", + "magic_level": "90", + "respawn_delay": "125", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Portal", + "defence_level": "90", + "safespot": null, + "lifepoints": "250", + "strength_level": "1", + "id": "7554", + "bonuses": "100,100,200,200,100,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The Void Knight will soon weaken the shield.", + "attack_speed": "5", + "magic_level": "30", + "respawn_delay": "125", + "name": "Portal", + "defence_level": "30", + "safespot": null, + "lifepoints": "250", + "strength_level": "1", + "id": "7555", + "bonuses": "100,100,100,50,50,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The Void Knight will soon weaken the shield.", + "attack_speed": "5", + "magic_level": "15", + "respawn_delay": "125", + "name": "Portal", + "defence_level": "30", + "safespot": null, + "lifepoints": "250", + "strength_level": "1", + "id": "7556", + "bonuses": "100,100,100,100,25,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The Void Knight will soon weaken the shield.", + "melee_animation": "0", + "range_animation": "0", + "attack_speed": "5", + "magic_level": "30", + "respawn_delay": "125", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Portal", + "defence_level": "30", + "safespot": null, + "lifepoints": "250", + "strength_level": "1", + "id": "7557", + "bonuses": "100,100,50,100,50,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The Void Knight will soon weaken the shield.", + "melee_animation": "0", + "range_animation": "0", + "attack_speed": "5", + "magic_level": "30", + "respawn_delay": "125", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Portal", + "defence_level": "30", + "safespot": null, + "lifepoints": "250", + "strength_level": "1", + "id": "7558", + "bonuses": "50,50,100,100,50,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Looks after your Farming tools.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "323,326,325", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Brawler", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7559", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Looks after your Farming tools.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Lostme", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7560", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Looks after your Farming tools.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Chiercat", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7561", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Looks after your Farming tools.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Skydischarge", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7562", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Looks after your Farming tools.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Agplus", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7563", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Looks after your Farming tools.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Distantthin", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7564", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Looks after your Farming tools.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Allmarshes", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7565", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Looks after your Farming tools.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Explosive67", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7566", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Looks after your Farming tools.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Alpha1beta", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7569", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Enjoys locking up animals in small pens.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Solltalk", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7570", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Enjoys locking up animals in small pens.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Hm Val", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7571", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He looks like the type of guy who would mind monkeys.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Wizzydumped", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7572", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He looks like the type of guy who would mind monkeys.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Oddskater", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7573", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Poledragon", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "408,410,409", + "strength_level": "1", + "id": "7580", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He likes inflicting pain.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Al Truism", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7582", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The Don of penguins.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ohhhhdude", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7583", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A penguin pushing paper", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "845,848,846", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Torcher", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7585", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A penguin pushing paper", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "845,848,846", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Torcher", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7586", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He's a little rough around the edges.", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "766,768,767", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Shifter", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7593", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He has unbelievable strength!", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Banker", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7605", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "95", + "strength_level": "1", + "attack_speed": "6", + "id": "7606", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "105", + "strength_level": "1", + "attack_speed": "6", + "id": "7607", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "120", + "strength_level": "1", + "attack_speed": "6", + "id": "7608", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "130", + "strength_level": "1", + "attack_speed": "6", + "id": "7609", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "95", + "strength_level": "1", + "attack_speed": "6", + "id": "7614", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "105", + "strength_level": "1", + "attack_speed": "6", + "id": "7615", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "120", + "strength_level": "1", + "attack_speed": "6", + "id": "7616", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "130", + "strength_level": "1", + "attack_speed": "6", + "id": "7617", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "95", + "strength_level": "1", + "attack_speed": "6", + "id": "7618", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "105", + "strength_level": "1", + "attack_speed": "6", + "id": "7619", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "120", + "strength_level": "1", + "attack_speed": "6", + "id": "7620", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "130", + "strength_level": "1", + "attack_speed": "6", + "id": "7621", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "95", + "strength_level": "1", + "attack_speed": "6", + "id": "7626", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "105", + "strength_level": "1", + "attack_speed": "6", + "id": "7627", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "120", + "strength_level": "1", + "attack_speed": "6", + "id": "7628", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "130", + "strength_level": "1", + "attack_speed": "6", + "id": "7629", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "95", + "strength_level": "1", + "attack_speed": "6", + "id": "7631", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "120", + "strength_level": "1", + "attack_speed": "6", + "id": "7632", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "95", + "strength_level": "1", + "attack_speed": "6", + "id": "7634", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "120", + "strength_level": "1", + "attack_speed": "6", + "id": "7635", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "examine": "Ew it's still alive.", + "melee_animation": "9125", + "range_animation": "9125", + "attack_speed": "5", + "respawn_delay": "20", + "defence_animation": "9127", + "weakness": "9", + "magic_animation": "9125", + "death_animation": "9126", + "name": "Skeletal hand", + "defence_level": "85", + "safespot": null, + "lifepoints": "90", + "strength_level": "85", + "id": "7640", + "aggressive": "true", + "bonuses": "15,15,15,15,15,15,15,15,15,15,15,15,15,15,15", + "range_level": "1", + "attack_level": "85" + }, + { + "examine": "Ew it's still alive.", + "melee_animation": "9125", + "range_animation": "9125", + "attack_speed": "5", + "respawn_delay": "20", + "defence_animation": "9127", + "weakness": "9", + "magic_animation": "9125", + "death_animation": "9126", + "name": "Zombie hand", + "defence_level": "75", + "safespot": null, + "lifepoints": "90", + "strength_level": "75", + "id": "7641", + "aggressive": "true", + "bonuses": "15,15,15,15,15,15,15,15,15,15,15,15,15,15,15", + "range_level": "1", + "attack_level": "75" + }, + { + "examine": "A bloodveld with a very mixed heritage.", + "melee_animation": "9102", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "slayer_exp": "206", + "magic_animation": "0", + "death_animation": "9131", + "name": "Mutated bloodveld", + "defence_level": "56", + "safespot": null, + "lifepoints": "112", + "strength_level": "56", + "id": "7642", + "aggressive": "true", + "range_level": "1", + "attack_level": "56" + }, + { + "examine": "A bloodveld with a very mixed heritage.", + "melee_animation": "9102", + "range_animation": "0", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "slayer_exp": "206", + "magic_animation": "0", + "death_animation": "9131", + "name": "Mutated bloodveld", + "defence_level": "58", + "safespot": null, + "lifepoints": "116", + "strength_level": "58", + "id": "7643", + "aggressive": "true", + "range_level": "1", + "attack_level": "58" + }, + { + "name": "Zaromark Sliver", + "defence_level": "1", + "safespot": null, + "lifepoints": "88", + "strength_level": "1", + "id": "7644", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Zaromark Sliver", + "defence_level": "1", + "safespot": null, + "lifepoints": "88", + "strength_level": "1", + "id": "7645", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Zaromark Sliver", + "defence_level": "1", + "safespot": null, + "lifepoints": "88", + "strength_level": "1", + "id": "7646", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Zaromark Sliver", + "defence_level": "1", + "safespot": null, + "lifepoints": "88", + "strength_level": "1", + "id": "7647", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Zaromark Sliver", + "defence_level": "1", + "safespot": null, + "lifepoints": "88", + "strength_level": "1", + "id": "7648", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Zaromark Sliver", + "defence_level": "1", + "safespot": null, + "lifepoints": "88", + "strength_level": "1", + "id": "7649", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Zaromark Sliver", + "defence_level": "1", + "safespot": null, + "lifepoints": "88", + "strength_level": "1", + "id": "7650", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Zaromark Sliver", + "defence_level": "1", + "safespot": null, + "lifepoints": "88", + "strength_level": "1", + "id": "7651", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Fistandantilus", + "defence_level": "1", + "safespot": null, + "lifepoints": "65", + "strength_level": "1", + "id": "7654", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Fistandantilus", + "defence_level": "1", + "safespot": null, + "lifepoints": "65", + "strength_level": "1", + "id": "7655", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Fistandantilus", + "defence_level": "1", + "safespot": null, + "lifepoints": "65", + "strength_level": "1", + "id": "7656", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Fistandantilus", + "defence_level": "1", + "safespot": null, + "lifepoints": "65", + "strength_level": "1", + "id": "7657", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Fistandantilus", + "defence_level": "1", + "safespot": null, + "lifepoints": "65", + "strength_level": "1", + "id": "7658", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Fistandantilus", + "defence_level": "1", + "safespot": null, + "lifepoints": "65", + "strength_level": "1", + "id": "7659", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Fistandantilus", + "defence_level": "1", + "safespot": null, + "lifepoints": "65", + "strength_level": "1", + "id": "7660", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Fistandantilus", + "defence_level": "1", + "safespot": null, + "lifepoints": "65", + "strength_level": "1", + "id": "7661", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "105", + "strength_level": "1", + "attack_speed": "6", + "id": "7682", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "105", + "strength_level": "1", + "attack_speed": "6", + "id": "7683", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "95", + "strength_level": "1", + "attack_speed": "6", + "id": "7691", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "105", + "strength_level": "1", + "attack_speed": "6", + "id": "7692", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "120", + "strength_level": "1", + "attack_speed": "6", + "id": "7693", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "120", + "strength_level": "1", + "attack_speed": "6", + "id": "7694", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "95", + "strength_level": "1", + "attack_speed": "6", + "id": "7695", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "105", + "strength_level": "1", + "attack_speed": "6", + "id": "7696", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "120", + "strength_level": "1", + "attack_speed": "6", + "id": "7697", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "120", + "strength_level": "1", + "attack_speed": "6", + "id": "7698", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "95", + "strength_level": "1", + "attack_speed": "6", + "id": "7699", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "105", + "strength_level": "1", + "attack_speed": "6", + "id": "7700", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "120", + "strength_level": "1", + "attack_speed": "6", + "id": "7701", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "130", + "strength_level": "1", + "attack_speed": "6", + "id": "7702", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "95", + "strength_level": "1", + "attack_speed": "6", + "id": "7703", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "105", + "strength_level": "1", + "attack_speed": "6", + "id": "7704", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "120", + "strength_level": "1", + "attack_speed": "6", + "id": "7705", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "name": "Vyrewatch", + "defence_level": "1", + "safespot": null, + "lifepoints": "130", + "strength_level": "1", + "attack_speed": "6", + "id": "7706", + "aggressive": "true", + "range_level": "1", + "respawn_delay": "60", + "attack_level": "1" + }, + { + "examine": "Looks like a big ugly dog.", + "melee_animation": "6565", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "6564", + "name": "Temple guardian", + "defence_level": "24", + "safespot": null, + "lifepoints": "34", + "strength_level": "24", + "id": "7711", + "range_level": "1", + "attack_level": "24" + }, + { + "melee_animation": "8080", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "8084", + "death_animation": "8078", + "name": "Baby icefiend", + "defence_level": "1", + "safespot": null, + "lifepoints": "50", + "strength_level": "1", + "id": "7713", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A small ice demon.", + "melee_animation": "8080", + "range_animation": "0", + "combat_audio": "531,533,532", + "attack_speed": "5", + "magic_level": "25", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "5", + "magic_animation": "0", + "death_animation": "8078", + "name": "Icefiend", + "defence_level": "25", + "safespot": null, + "lifepoints": "35", + "strength_level": "1", + "id": "7714", + "aggressive": "true", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The icefiend seems to be melting.", + "melee_animation": "8080", + "range_animation": "0", + "combat_audio": "531,533,532", + "attack_speed": "5", + "magic_level": "25", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "5", + "magic_animation": "0", + "death_animation": "8078", + "name": "Icefiend", + "defence_level": "25", + "safespot": null, + "lifepoints": "35", + "strength_level": "1", + "id": "7715", + "aggressive": "true", + "clue_level": "0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "The icefiend seems to be melting.", + "melee_animation": "8080", + "range_animation": "0", + "attack_speed": "5", + "magic_level": "25", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "5", + "magic_animation": "0", + "death_animation": "8078", + "name": "null", + "defence_level": "25", + "safespot": null, + "lifepoints": "35", + "strength_level": "1", + "id": "7716", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A holy man.", + "melee_animation": "422", + "range_animation": "0", + "combat_audio": "511,513,512", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Monk", + "defence_level": "12", + "safespot": null, + "lifepoints": "17", + "strength_level": "12", + "id": "7727", + "range_level": "1", + "attack_level": "12" + }, + { + "melee_animation": "8080", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "8084", + "death_animation": "8078", + "name": "Baby icefiend", + "defence_level": "1", + "safespot": null, + "lifepoints": "50", + "strength_level": "1", + "id": "7736", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Is it full of rats?", + "melee_animation": "0", + "range_animation": "0", + "combat_audio": "703,705,704", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Jiggling crate", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7740", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A warrior who has been long forgotten.", + "range_animation": "0", + "magic_level": "25", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "836", + "name": "Three little kittens", + "defence_level": "25", + "safespot": null, + "lifepoints": "5", + "strength_level": "30", + "id": "7741", + "aggressive": "true", + "range_level": "25", + "attack_level": "30" + }, + { + "examine": "It looks upset.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "TzHaar-Xil-Tog", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7747", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A TzHaar librarian.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "TzHaar-Mej-Lor", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7752", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A TzHaar-Hur stamping stone tablets.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Library assistant", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7756", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Looks like a craftsman of some kind.", + "melee_animation": "9286", + "range_animation": "9286", + "attack_speed": "5", + "magic_level": "50", + "defence_animation": "9287", + "magic_animation": "9286", + "death_animation": "9288", + "name": "TzHaar-Hur", + "defence_level": "50", + "safespot": null, + "lifepoints": "80", + "strength_level": "50", + "id": "7767", + "bonuses": "30,30,80,85,80,40,40,60,38,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "50" + }, + { + "examine": "Looks like a craftsman of some kind.", + "melee_animation": "9286", + "range_animation": "9286", + "attack_speed": "5", + "magic_level": "50", + "defence_animation": "9287", + "magic_animation": "9286", + "death_animation": "9288", + "name": "TzHaar-Hur", + "defence_level": "50", + "safespot": null, + "lifepoints": "80", + "strength_level": "50", + "id": "7768", + "bonuses": "30,30,80,85,80,40,40,60,38,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "50" + }, + { + "examine": "Looks like a craftsman of some kind.", + "melee_animation": "9286", + "range_animation": "9286", + "attack_speed": "5", + "magic_level": "50", + "defence_animation": "9287", + "magic_animation": "9286", + "death_animation": "9288", + "name": "TzHaar-Hur", + "defence_level": "50", + "safespot": null, + "lifepoints": "80", + "strength_level": "50", + "id": "7769", + "bonuses": "30,30,80,85,80,40,40,60,38,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "50" + }, + { + "examine": "A monster made of magma.", + "combat_style": "1", + "melee_animation": "9337", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "0", + "magic_animation": "0", + "death_animation": "9340", + "name": "Lava monster", + "defence_level": "38", + "safespot": null, + "lifepoints": "54", + "strength_level": "28", + "id": "7772", + "aggressive": "true", + "range_level": "38", + "attack_level": "28" + }, + { + "examine": "A monster like many others", + "combat_style": "2", + "melee_animation": "9341", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "0", + "magic_animation": "0", + "death_animation": "9344", + "name": "Fire monster", + "defence_level": "38", + "safespot": null, + "lifepoints": "54", + "strength_level": "28", + "id": "7773", + "aggressive": "true", + "range_level": "38", + "attack_level": "28" + }, + { + "examine": "Not the best of vocalists.", + "combat_style": "1", + "melee_animation": "9449", + "range_animation": "9382", + "combat_audio": "284,286,285", + "magic_level": "65", + "respawn_delay": "60", + "defence_animation": "9451", + "weakness": "0", + "magic_animation": "9382", + "death_animation": "9450", + "name": "Mighty banshee", + "defence_level": "65", + "safespot": null, + "lifepoints": "85", + "strength_level": "65", + "id": "7786", + "aggressive": "true", + "range_level": "0", + "attack_level": "65" + }, + { + "examine": "A big, scary hand! ", + "melee_animation": "1802", + "attack_speed": "6", + "respawn_delay": "60", + "defence_animation": "1803", + "slayer_exp": "105", + "death_animation": "1804", + "name": "Wall Beast", + "defence_level": "38", + "movement_radius": "1", + "safespot": null, + "lifepoints": "105", + "strength_level": "38", + "id": "7823", + "aggressive": "true", + "range_level": "1", + "attack_level": "38" + }, + { + "examine": "A melee training dummy", + "melee_animation": "94", + "range_animation": "0", + "attack_speed": "6", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "97", + "name": "Melee dummy", + "defence_level": "1", + "safespot": null, + "lifepoints": "15", + "strength_level": "1", + "id": "7891", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A man of his craft.", + "name": "Smelting Tutor", + "defence_level": "1", + "movement_radius": "5", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7958", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A master of his craft.", + "name": "Smelting Tutor", + "defence_level": "1", + "movement_radius": "5", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7959", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He looks like a professional explorer.", + "name": "Explorer Jack", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7969", + "range_level": "1", + "attack_level": "1" + }, + { + "agg_radius": "64", + "examine": "A vision of supernatural horror.", + "melee_animation": "10058", + "attack_speed": "6", + "magic_level": "350", + "respawn_delay": "80", + "defence_animation": "10386", + "magic_animation": "10053", + "death_animation": "10385", + "name": "Corporeal Beast", + "defence_level": "310", + "poison_immune": "true", + "movement_radius": "64", + "safespot": null, + "lifepoints": "2000", + "strength_level": "320", + "id": "8133", + "aggressive": "true", + "bonuses": "50,50,50,0,0,25,200,100,150,230,0,0,0,0,0", + "range_level": "150", + "attack_level": "320" + }, + { + "examine": "He sure looks grave.", + "melee_animation": "5571", + "combat_audio": "931,923,922", + "attack_speed": "6", + "respawn_delay": "35", + "defence_animation": "5574", + "slayer_exp": "30", + "death_animation": "5575", + "name": "Armoured zombie", + "defence_level": "50", + "safespot": null, + "lifepoints": "62", + "strength_level": "50", + "id": "8149", + "aggressive": "true", + "bonuses": "30,30,80,85,80,40,40,60,38,0,0,0,0,0,0", + "range_level": "50", + "attack_level": "50" + }, + { + "examine": "This is a rotten one.", + "melee_animation": "5571", + "combat_audio": "931,923,922", + "attack_speed": "6", + "respawn_delay": "35", + "defence_animation": "5574", + "slayer_exp": "30", + "death_animation": "5575", + "name": "Armoured zombie", + "defence_level": "50", + "safespot": null, + "lifepoints": "62", + "strength_level": "50", + "id": "8150", + "aggressive": "true", + "bonuses": "30,30,80,85,80,40,40,60,38,0,0,0,0,0,0", + "range_level": "50", + "attack_level": "50" + }, + { + "examine": "It hasn't quite gotten around to dying.", + "melee_animation": "5571", + "combat_audio": "931,923,922", + "attack_speed": "6", + "respawn_delay": "35", + "defence_animation": "5574", + "slayer_exp": "30", + "death_animation": "5575", + "name": "Armoured zombie", + "defence_level": "50", + "safespot": null, + "lifepoints": "62", + "strength_level": "50", + "id": "8151", + "aggressive": "true", + "bonuses": "30,30,80,85,80,40,40,60,38,0,0,0,0,0,0", + "range_level": "50", + "attack_level": "50" + }, + { + "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", + "combat_style": "2", + "melee_animation": "10922", + "range_animation": "10919", + "attack_speed": "6", + "magic_level": "85", + "protect_style": "0", + "respawn_delay": "100", + "defence_animation": "10923", + "slayer_exp": "136", + "magic_animation": "10918", + "death_animation": "10924", + "name": "Tormented demon", + "defence_level": "85", + "poison_immune": "true", + "safespot": "true", + "movement_radius": "40", + "lifepoints": "326", + "strength_level": "85", + "id": "8349", + "aggressive": "true", + "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", + "range_level": "85", + "attack_level": "85" + }, + { + "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", + "combat_style": "2", + "melee_animation": "10922", + "range_animation": "10919", + "attack_speed": "6", + "magic_level": "85", + "protect_style": "2", + "respawn_delay": "100", + "defence_animation": "10923", + "slayer_exp": "136", + "magic_animation": "10918", + "death_animation": "10924", + "name": "Tormented demon", + "defence_level": "85", + "poison_immune": "true", + "safespot": "true", + "movement_radius": "40", + "lifepoints": "326", + "strength_level": "85", + "id": "8350", + "aggressive": "true", + "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", + "range_level": "85", + "attack_level": "85" + }, + { + "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", + "combat_style": "2", + "melee_animation": "10922", + "range_animation": "10919", + "attack_speed": "6", + "magic_level": "85", + "protect_style": "1", + "respawn_delay": "100", + "defence_animation": "10923", + "slayer_exp": "136", + "magic_animation": "10918", + "death_animation": "10924", + "name": "Tormented demon", + "defence_level": "85", + "poison_immune": "true", + "safespot": "true", + "movement_radius": "40", + "lifepoints": "326", + "strength_level": "85", + "id": "8351", + "aggressive": "true", + "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", + "range_level": "85", + "attack_level": "85" + }, + { + "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", + "combat_style": "1", + "melee_animation": "10922", + "range_animation": "10919", + "attack_speed": "6", + "magic_level": "85", + "protect_style": "0", + "respawn_delay": "100", + "defence_animation": "10923", + "slayer_exp": "136", + "magic_animation": "10918", + "death_animation": "10924", + "name": "Tormented demon", + "defence_level": "85", + "poison_immune": "true", + "safespot": "true", + "movement_radius": "40", + "lifepoints": "326", + "strength_level": "85", + "id": "8352", + "aggressive": "true", + "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", + "range_level": "85", + "attack_level": "85" + }, + { + "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", + "combat_style": "1", + "melee_animation": "10922", + "range_animation": "10919", + "attack_speed": "6", + "magic_level": "85", + "protect_style": "2", + "respawn_delay": "100", + "defence_animation": "10923", + "slayer_exp": "136", + "magic_animation": "10918", + "death_animation": "10924", + "name": "Tormented demon", + "defence_level": "85", + "poison_immune": "true", + "safespot": "true", + "movement_radius": "40", + "lifepoints": "326", + "strength_level": "85", + "id": "8353", + "aggressive": "true", + "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", + "range_level": "85", + "attack_level": "85" + }, + { + "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", + "combat_style": "1", + "melee_animation": "10922", + "range_animation": "10919", + "attack_speed": "6", + "magic_level": "85", + "protect_style": "1", + "respawn_delay": "100", + "defence_animation": "10923", + "slayer_exp": "136", + "magic_animation": "10918", + "death_animation": "10924", + "name": "Tormented demon", + "defence_level": "85", + "poison_immune": "true", + "safespot": "true", + "movement_radius": "40", + "lifepoints": "326", + "strength_level": "85", + "id": "8354", + "aggressive": "true", + "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", + "range_level": "85", + "attack_level": "85" + }, + { + "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", + "combat_style": "0", + "melee_animation": "10922", + "range_animation": "10919", + "attack_speed": "6", + "magic_level": "85", + "protect_style": "0", + "respawn_delay": "100", + "defence_animation": "10923", + "slayer_exp": "136", + "magic_animation": "10918", + "death_animation": "10924", + "name": "Tormented demon", + "defence_level": "85", + "poison_immune": "true", + "safespot": "true", + "movement_radius": "40", + "lifepoints": "326", + "strength_level": "85", + "id": "8355", + "aggressive": "true", + "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", + "range_level": "85", + "attack_level": "85" + }, + { + "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", + "combat_style": "0", + "melee_animation": "10922", + "range_animation": "10919", + "attack_speed": "6", + "magic_level": "85", + "protect_style": "2", + "respawn_delay": "100", + "defence_animation": "10923", + "slayer_exp": "136", + "magic_animation": "10918", + "death_animation": "10924", + "name": "Tormented demon", + "defence_level": "85", + "poison_immune": "true", + "safespot": "true", + "movement_radius": "40", + "lifepoints": "326", + "strength_level": "85", + "id": "8356", + "aggressive": "true", + "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", + "range_level": "85", + "attack_level": "85" + }, + { + "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", + "combat_style": "0", + "melee_animation": "10922", + "range_animation": "10919", + "attack_speed": "6", + "magic_level": "85", + "protect_style": "1", + "respawn_delay": "100", + "defence_animation": "10923", + "slayer_exp": "136", + "magic_animation": "10918", + "death_animation": "10924", + "name": "Tormented demon", + "defence_level": "85", + "poison_immune": "true", + "safespot": "true", + "movement_radius": "40", + "lifepoints": "326", + "strength_level": "85", + "id": "8357", + "aggressive": "true", + "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", + "range_level": "85", + "attack_level": "85" + }, + { + "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", + "combat_style": "2", + "melee_animation": "10922", + "range_animation": "10919", + "attack_speed": "6", + "magic_level": "85", + "protect_style": "0", + "respawn_delay": "100", + "defence_animation": "10923", + "slayer_exp": "136", + "magic_animation": "10918", + "death_animation": "10924", + "name": "Tormented demon", + "defence_level": "85", + "poison_immune": "true", + "safespot": "true", + "movement_radius": "40", + "lifepoints": "326", + "strength_level": "85", + "id": "8358", + "aggressive": "true", + "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", + "range_level": "85", + "attack_level": "85" + }, + { + "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", + "combat_style": "2", + "melee_animation": "10922", + "range_animation": "10919", + "attack_speed": "6", + "magic_level": "85", + "protect_style": "2", + "respawn_delay": "100", + "defence_animation": "10923", + "slayer_exp": "136", + "magic_animation": "10918", + "death_animation": "10924", + "name": "Tormented demon", + "defence_level": "85", + "poison_immune": "true", + "safespot": "true", + "movement_radius": "40", + "lifepoints": "326", + "strength_level": "85", + "id": "8359", + "aggressive": "true", + "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", + "range_level": "85", + "attack_level": "85" + }, + { + "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", + "combat_style": "2", + "melee_animation": "10922", + "range_animation": "10919", + "attack_speed": "6", + "magic_level": "85", + "protect_style": "1", + "respawn_delay": "100", + "defence_animation": "10923", + "slayer_exp": "136", + "magic_animation": "10918", + "death_animation": "10924", + "name": "Tormented demon", + "defence_level": "85", + "poison_immune": "true", + "safespot": "true", + "movement_radius": "40", + "lifepoints": "326", + "strength_level": "85", + "id": "8360", + "aggressive": "true", + "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", + "range_level": "85", + "attack_level": "85" + }, + { + "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", + "combat_style": "1", + "melee_animation": "10922", + "range_animation": "10919", + "attack_speed": "6", + "magic_level": "85", + "protect_style": "0", + "respawn_delay": "100", + "defence_animation": "10923", + "slayer_exp": "136", + "magic_animation": "10918", + "death_animation": "10924", + "name": "Tormented demon", + "defence_level": "85", + "poison_immune": "true", + "safespot": "true", + "movement_radius": "40", + "lifepoints": "326", + "strength_level": "85", + "id": "8361", + "aggressive": "true", + "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", + "range_level": "85", + "attack_level": "85" + }, + { + "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", + "combat_style": "1", + "melee_animation": "10922", + "range_animation": "10919", + "attack_speed": "6", + "magic_level": "85", + "protect_style": "2", + "respawn_delay": "100", + "defence_animation": "10923", + "slayer_exp": "136", + "magic_animation": "10918", + "death_animation": "10924", + "name": "Tormented demon", + "defence_level": "85", + "poison_immune": "true", + "safespot": "true", + "movement_radius": "40", + "lifepoints": "326", + "strength_level": "85", + "id": "8362", + "aggressive": "true", + "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", + "range_level": "85", + "attack_level": "85" + }, + { + "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", + "combat_style": "1", + "melee_animation": "10922", + "range_animation": "10919", + "attack_speed": "6", + "magic_level": "85", + "protect_style": "1", + "respawn_delay": "100", + "defence_animation": "10923", + "slayer_exp": "136", + "magic_animation": "10918", + "death_animation": "10924", + "name": "Tormented demon", + "defence_level": "85", + "poison_immune": "true", + "safespot": "true", + "movement_radius": "40", + "lifepoints": "326", + "strength_level": "85", + "id": "8363", + "aggressive": "true", + "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", + "range_level": "85", + "attack_level": "85" + }, + { + "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", + "combat_style": "0", + "melee_animation": "10922", + "range_animation": "10919", + "attack_speed": "6", + "magic_level": "85", + "protect_style": "0", + "respawn_delay": "100", + "defence_animation": "10923", + "slayer_exp": "136", + "magic_animation": "10918", + "death_animation": "10924", + "name": "Tormented demon", + "defence_level": "85", + "poison_immune": "true", + "safespot": "true", + "movement_radius": "40", + "lifepoints": "326", + "strength_level": "85", + "id": "8364", + "aggressive": "true", + "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", + "range_level": "85", + "attack_level": "85" + }, + { + "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", + "combat_style": "0", + "melee_animation": "10922", + "range_animation": "10919", + "attack_speed": "6", + "magic_level": "85", + "protect_style": "2", + "respawn_delay": "100", + "defence_animation": "10923", + "slayer_exp": "136", + "magic_animation": "10918", + "death_animation": "10924", + "name": "Tormented demon", + "defence_level": "85", + "poison_immune": "true", + "safespot": "true", + "movement_radius": "40", + "lifepoints": "326", + "strength_level": "85", + "id": "8365", + "aggressive": "true", + "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", + "range_level": "85", + "attack_level": "85" + }, + { + "examine": "Lucien must be incredibly powerful if he can bind such demons to his will.", + "combat_style": "0", + "melee_animation": "10922", + "range_animation": "10919", + "attack_speed": "6", + "magic_level": "85", + "protect_style": "1", + "respawn_delay": "100", + "defence_animation": "10923", + "slayer_exp": "136", + "magic_animation": "10918", + "death_animation": "10924", + "name": "Tormented demon", + "defence_level": "85", + "poison_immune": "true", + "safespot": "true", + "movement_radius": "40", + "lifepoints": "326", + "strength_level": "85", + "id": "8366", + "aggressive": "true", + "bonuses": "112,132,113,111,245,167,394,346,213,349,167,65,39,65,58", + "range_level": "85", + "attack_level": "85" + }, + { + "examine": "Flappy bird.", + "name": "Gull", + "water_npc": "true", + "id": "1179" + }, + { + "examine": "Flappy bird.", + "name": "Gull", + "water_npc": "true", + "id": "450" + }, + { + "examine": "Flappy bird.", + "name": "Gull", + "water_npc": "true", + "id": "451" + }, + { + "examine": "Tough-looking combat type.", + "name": "Mubariz", + "id": "957" + }, + { + "examine": "Looks kinda bored.", + "name": "Fadli", + "id": "958" + }, + { + "examine": "Trained to deal with all sorts of injuries.", + "name": "A'abla", + "id": "959" + }, + { + "examine": "Wow! She's made a statement with that hair!", + "name": "Sabreen", + "id": "960" + }, + { + "examine": "Has the messy job of putting players back together again.", + "name": "Jaraah", + "id": "962" + }, + { + "examine": "Battle-scarred.", + "name": "Zahwa", + "id": "963" + }, + { + "examine": "A citizen of Al Kharid", + "name": "Ima", + "id": "964" + }, + { + "examine": "A citizen of Al Kharid", + "name": "Sabeil", + "id": "965" + }, + { + "examine": "A citizen of Al Kharid", + "name": "Jadid", + "id": "966" + }, + { + "examine": "A citizen of Al Kharid", + "name": "Dalal", + "id": "967" + }, + { + "examine": "A citizen of Al Kharid", + "name": "Afrah", + "id": "968" + }, + { + "examine": "A citizen of Al Kharid", + "name": "Jeed", + "id": "969" + }, + { + "examine": "He smells funny.", + "name": "Diango", + "id": "970" + }, + { + "examine": "Shopkeeper.", + "name": "Chadwell", + "id": "971" + }, + { + "examine": "The cave guide.", + "name": "Koftik", + "id": "972" + }, + { + "examine": "The cave guide.", + "name": "Koftik", + "id": "973" + }, + { + "examine": "The cave guide.", + "name": "Koftik", + "id": "974" + }, + { + "examine": "The cave guide.", + "name": "Koftik", + "id": "975" + }, + { + "examine": "The cave guide.", + "name": "Koftik", + "id": "976" + }, + { + "examine": "This dwarf looks intoxicated.", + "name": "Kamen", + "id": "996" + }, + { + "examine": "A dwarven maker of gauntlets.", + "name": "Klank", + "id": "995" + }, + { + "examine": "One of King Tyras's men.", + "name": "Tyras guard", + "id": "1206" + }, + { + "examine": "The cave guide.", + "name": "Koftik", + "id": "1209" + }, + { + "examine": "One of King Lathas' messengers.", + "name": "Kings messenger", + "id": "1210" + }, + { + "examine": "Mysterious swamp lights...", + "name": "Will o' the wisp", + "id": "1212" + }, + { + "examine": "He's washing his clothes in the lake.", + "name": "Tegid", + "id": "1213" + }, + { + "examine": "A plant.", + "name": "Thistle", + "id": "1214" + }, + { + "examine": "What a colourful bunch of parrots!", + "name": "Parrots", + "id": "1215" + }, + { + "examine": "Rather dense and soppy looking.", + "name": "Romeo", + "id": "639" + }, + { + "examine": "Newspaper seller.", + "name": "Benny", + "id": "5925" + }, + { + "examine": "One of Gertrude's Sons.", + "name": "Wilough", + "id": "783" + }, + { + "examine": "An old gypsy lady.", + "name": "Gypsy Aris", + "id": "882" + }, + { + "examine": "Interesting assortment of clothes on offer...", + "name": "Thessalia", + "id": "548" + }, + { + "examine": "Sells superior staffs.", + "name": "Zaff", + "id": "546" + }, + { + "examine": "A retired vampyre hunter.", + "name": "Dr Harlow", + "id": "756" + }, + { + "examine": "I could get a beer from him.", + "name": "Bartender", + "id": "733" + }, + { + "examine": "Director of the Grand Exchange.", + "id": "6522" + }, + { + "examine": "He can look after my money. Good with money.", + "id": "6535" + }, + { + "examine": "She can look after my money. Good with money.", + "id": "6532" + }, + { + "examine": "There to help me make my bids.", + "id": "6530" + }, + { + "examine": "There to help me make my bids.", + "id": "6528" + }, + { + "examine": "He can look after my money. Good with money.", + "id": "6534" + }, + { + "examine": "She can look after my money. Good with money.", + "id": "6533" + }, + { + "examine": "There to help me make my bids.", + "id": "6531" + }, + { + "examine": "There to help me make my bids.", + "id": "6529" + }, + { + "examine": "She looks very worried about something.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Caroline", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "696", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A very good sailor.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Holgart", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "698", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Smells a bit fishy.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Ezekial Lovecraft", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4856", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A (semi) retired member of the Temple Knights.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Col. O'Niall", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4872", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "There's something fishy about him.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Mayor Hobb", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4874", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A fresh-faced and innocent priest.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Brother Maledict", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4878", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A down on his luck fisherman.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Witchaven villager", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4883", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A down on her luck fisherman.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Witchaven villager", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4885", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A down on his luck fisherman.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Witchaven villager", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4887", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A villager named Jeb.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Jeb", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "4895", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A little girl. She looks terrified.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Kimberly", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7168", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Stinky! Poor guy.", + "name": "Yeti", + "id": "130" + }, + { + "examine": "A regal cat with an evil glint in its eye.", + "melee_animation": "422", + "range_animation": "422", + "combat_audio": "511,513,512", + "defence_animation": "404", + "magic_animation": "422", + "death_animation": "9055", + "name": "HRH Hrafn", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5479", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Harder than the rocks he sells.", + "melee_animation": "422", + "range_animation": "422", + "combat_audio": "511,513,512", + "defence_animation": "404", + "magic_animation": "422", + "death_animation": "9055", + "name": "Hring Hring", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5483", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Jatizso's fishmonger.", + "melee_animation": "422", + "range_animation": "422", + "combat_audio": "511,513,512", + "defence_animation": "404", + "magic_animation": "422", + "death_animation": "9055", + "name": "Flossi Dalksson", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5484", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A guy that will sell you armour.", + "melee_animation": "422", + "range_animation": "422", + "combat_audio": "511,513,512", + "defence_animation": "404", + "magic_animation": "422", + "death_animation": "9055", + "name": "Raum Urda-Stein", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5485", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Jatizso's armour merchant.", + "melee_animation": "422", + "range_animation": "422", + "combat_audio": "511,513,512", + "defence_animation": "404", + "magic_animation": "422", + "death_animation": "9055", + "name": "Skuli Myrka", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5486", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A rough-looking chef.", + "melee_animation": "422", + "range_animation": "422", + "combat_audio": "511,513,512", + "defence_animation": "404", + "magic_animation": "422", + "death_animation": "9055", + "name": "Keepa Kettilon", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5487", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of Jatizso's many citizens.", + "melee_animation": "422", + "range_animation": "422", + "combat_audio": "511,513,512", + "defence_animation": "404", + "magic_animation": "422", + "death_animation": "9055", + "name": "Freygerd", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5493", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of Jatizso's many citizens.", + "melee_animation": "422", + "range_animation": "422", + "combat_audio": "511,513,512", + "defence_animation": "404", + "magic_animation": "422", + "death_animation": "9055", + "name": "Lensa", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5494", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A happy, friendly landlady.", + "melee_animation": "422", + "range_animation": "422", + "combat_audio": "511,513,512", + "defence_animation": "404", + "magic_animation": "422", + "death_animation": "9055", + "name": "Vanligga Gastfrihet", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5495", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of Jatizso's many citizens.", + "melee_animation": "422", + "range_animation": "422", + "combat_audio": "511,513,512", + "defence_animation": "404", + "magic_animation": "422", + "death_animation": "9055", + "name": "Sassilik", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5496", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A bedraggled-looking tramp.", + "melee_animation": "422", + "range_animation": "422", + "combat_audio": "511,513,512", + "defence_animation": "404", + "magic_animation": "422", + "death_animation": "9055", + "name": "Eric", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5499", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Mina guards the mine entrance.", + "melee_animation": "422", + "range_animation": "422", + "combat_audio": "511,513,512", + "defence_animation": "404", + "magic_animation": "422", + "death_animation": "9055", + "name": "Gruva Patrull", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5500", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A dwarven trader from Keldagrim.", + "melee_animation": "422", + "range_animation": "422", + "combat_audio": "511,513,512", + "defence_animation": "404", + "magic_animation": "422", + "death_animation": "9055", + "name": "Brendt", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "5501", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A hungry-looking rabbit.", + "melee_animation": "0", + "range_animation": "0", + "respawn_delay": "50", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Rabbit", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7126", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A gnome farmer.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Farmer", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7129", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of the Burgher's Protectors", + "death_animation": "836", + "name": "Honour Guard", + "melee_animation": "395", + "id": "5515", + "defence_animation": "404" + }, + { + "examine": "Could do with gaining a few pounds.", + "melee_animation": "5485", + "range_animation": "5485", + "combat_audio": "774,775,777", + "attack_speed": "4", + "respawn_delay": "70", + "defence_animation": "5489", + "weakness": "8", + "slayer_exp": "29", + "magic_animation": "5485", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "17", + "safespot": null, + "lifepoints": "29", + "strength_level": "18", + "id": "90", + "range_level": "1", + "attack_level": "15" + }, + { + "examine": "Could do with gaining a few pounds.", + "melee_animation": "5485", + "range_animation": "5485", + "combat_audio": "774,775,777", + "attack_speed": "4", + "defence_animation": "5489", + "weakness": "8", + "slayer_exp": "24", + "magic_animation": "5485", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "17", + "safespot": null, + "lifepoints": "24", + "strength_level": "17", + "id": "91", + "range_level": "1", + "attack_level": "17" + }, + { + "examine": "Could do with gaining a few pounds.", + "melee_animation": "5485", + "range_animation": "5485", + "combat_audio": "774,775,777", + "attack_speed": "4", + "defence_animation": "5489", + "weakness": "8", + "slayer_exp": "17", + "magic_animation": "5485", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "24", + "safespot": null, + "lifepoints": "17", + "strength_level": "24", + "id": "92", + "range_level": "1", + "attack_level": "24" + }, + { + "examine": "Could do with gaining a few pounds.", + "melee_animation": "5485", + "range_animation": "5485", + "combat_audio": "774,775,777", + "attack_speed": "4", + "defence_animation": "5489", + "weakness": "8", + "slayer_exp": "59", + "magic_animation": "5485", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "36", + "safespot": null, + "lifepoints": "59", + "strength_level": "35", + "id": "93", + "range_level": "1", + "attack_level": "32" + }, + { + "examine": "Rogueish.", + "melee_animation": "386", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Rogue", + "defence_level": "7", + "safespot": null, + "lifepoints": "10", + "strength_level": "7", + "aggressive": "false", + "id": "187", + "range_level": "1", + "attack_level": "7" + }, + { + "examine": "It rattles when it moves.", + "combat_style": "2", + "melee_animation": "5485", + "range_animation": "5485", + "combat_audio": "774,775,777", + "magic_level": "5", + "respawn_delay": "60", + "defence_animation": "5489", + "weakness": "3", + "magic_animation": "5485", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "5", + "safespot": null, + "lifepoints": "14", + "strength_level": "3", + "id": "459", + "aggressive": "true", + "range_level": "1", + "attack_level": "3" + }, + { + "examine": "It looks just a bit... underfed.", + "melee_animation": "5519", + "range_animation": "5519", + "combat_audio": "774,775,777", + "attack_speed": "4", + "magic_level": "110", + "respawn_delay": "100", + "defence_animation": "5520", + "weakness": "8", + "slayer_exp": "110", + "magic_animation": "5519", + "death_animation": "5521", + "name": "Skeleton", + "defence_level": "110", + "safespot": null, + "lifepoints": "77", + "strength_level": "90", + "id": "1471", + "aggressive": "true", + "bonuses": "50,50,50,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "180" + }, + { + "examine": "Could do with gaining a few pounds.", + "melee_animation": "5487", + "range_animation": "5487", + "combat_audio": "774,775,777", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "20", + "defence_animation": "5513", + "weakness": "8", + "magic_animation": "5487", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "72", + "safespot": null, + "lifepoints": "51", + "strength_level": "72", + "id": "2036", + "aggressive": "true", + "bonuses": "0,0,0,0,0,5,5,-5,0,5,0,0,0,0,0", + "range_level": "1", + "attack_level": "72" + }, + { + "examine": "Could do with gaining a few pounds.", + "melee_animation": "5487", + "range_animation": "5487", + "combat_audio": "774,775,777", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "20", + "defence_animation": "5513", + "weakness": "8", + "magic_animation": "5487", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "72", + "safespot": null, + "lifepoints": "51", + "strength_level": "72", + "id": "2037", + "aggressive": "true", + "bonuses": "0,0,0,0,0,5,5,-5,0,5,0,0,0,0,0", + "range_level": "1", + "attack_level": "72" + }, + { + "name": "Skeleton", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "774,775,777", + "strength_level": "1", + "id": "2715", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Skeleton mage", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "774,775,777", + "strength_level": "1", + "id": "2717", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Skeleton", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "774,775,777", + "strength_level": "1", + "id": "3151", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "One of Gielinor's many citizens, currently incapacitated by alcohol.", + "melee_animation": "422", + "range_animation": "0", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "death_animation": "836", + "name": "Drunken man", + "defence_level": "4", + "safespot": null, + "lifepoints": "5", + "strength_level": "4", + "id": "3222", + "range_level": "1", + "attack_level": "4" + }, + { + "examine": "Could do with gaining a few pounds.", + "melee_animation": "5485", + "range_animation": "0", + "combat_audio": "774,775,777", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "8", + "safespot": null, + "lifepoints": "11", + "strength_level": "8", + "id": "3291", + "aggressive": "true", + "range_level": "1", + "attack_level": "8" + }, + { + "examine": "He guards the dungeon with the faithfulness of the undead.", + "melee_animation": "5487", + "range_animation": "0", + "combat_audio": "774,775,777", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "70", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "17", + "safespot": null, + "lifepoints": "29", + "strength_level": "18", + "id": "3581", + "aggressive": "true", + "range_level": "1", + "attack_level": "15" + }, + { + "examine": "Could use a good meal.", + "melee_animation": "6128", + "range_animation": "0", + "combat_audio": "774,775,777", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "836", + "name": "Skeleton fremennik", + "defence_level": "17", + "safespot": null, + "lifepoints": "24", + "strength_level": "17", + "id": "3697", + "range_level": "1", + "attack_level": "17" + }, + { + "melee_animation": "400", + "combat_audio": "774,775,777", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Skeleton fremennik", + "defence_level": "1", + "safespot": null, + "lifepoints": "25", + "strength_level": "1", + "id": "3698", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "400", + "combat_audio": "774,775,777", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Skeleton fremennik", + "defence_level": "1", + "safespot": null, + "lifepoints": "25", + "strength_level": "1", + "id": "3699", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He seems a little underweight.", + "melee_animation": "6128", + "range_animation": "0", + "combat_audio": "774,775,777", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "836", + "name": "Skeleton fremennik", + "defence_level": "20", + "safespot": null, + "lifepoints": "28", + "strength_level": "20", + "id": "3700", + "range_level": "1", + "attack_level": "20" + }, + { + "examine": "He seems a little underweight.", + "melee_animation": "6128", + "range_animation": "0", + "combat_audio": "774,775,777", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "836", + "name": "Skeleton fremennik", + "defence_level": "20", + "safespot": null, + "lifepoints": "28", + "strength_level": "20", + "id": "3701", + "range_level": "1", + "attack_level": "20" + }, + { + "melee_animation": "395", + "combat_audio": "774,775,777", + "respawn_delay": "60", + "defence_animation": "425", + "death_animation": "836", + "name": "Skeleton fremennik", + "defence_level": "1", + "safespot": null, + "lifepoints": "35", + "strength_level": "1", + "id": "3702", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "He seems a little underweight.", + "melee_animation": "6128", + "range_animation": "0", + "combat_audio": "774,775,777", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "836", + "name": "Skeleton fremennik", + "defence_level": "22", + "safespot": null, + "lifepoints": "31", + "strength_level": "22", + "id": "3703", + "range_level": "1", + "attack_level": "22" + }, + { + "examine": "He seems a little underweight.", + "melee_animation": "6128", + "range_animation": "0", + "combat_audio": "774,775,777", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "6", + "magic_animation": "0", + "death_animation": "836", + "name": "Skeleton fremennik", + "defence_level": "22", + "safespot": null, + "lifepoints": "31", + "strength_level": "22", + "id": "3704", + "range_level": "1", + "attack_level": "22" + }, + { + "name": "Skeleton fremennik", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "combat_audio": "774,775,777", + "melee_animation": "5485", + "strength_level": "1", + "id": "3705", + "range_level": "1", + "attack_level": "1" + }, + { + "combat_audio": "774,775,777", + "melee_animation": "5485", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "5513", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "1", + "safespot": null, + "lifepoints": "68", + "strength_level": "1", + "id": "4384", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Could do with gaining a few pounds.", + "melee_animation": "5485", + "range_animation": "0", + "combat_audio": "774,775,777", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "34", + "safespot": null, + "lifepoints": "48", + "strength_level": "34", + "id": "4385", + "aggressive": "true", + "range_level": "1", + "attack_level": "34" + }, + { + "combat_audio": "774,775,777", + "melee_animation": "5485", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "5513", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "1", + "safespot": null, + "lifepoints": "85", + "strength_level": "1", + "id": "4386", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "4388", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "4384", + "death_animation": "4389", + "name": "Suqah", + "defence_level": "95", + "safespot": null, + "lifepoints": "105", + "strength_level": "95", + "id": "4532", + "aggressive": "true", + "clue_level": "2", + "bonuses": "0,0,0,0,0,50,70,70,90,50,0,0,0,0,0", + "range_level": "1", + "attack_level": "95" + }, + { + "examine": "Could do with gaining a few pounds.", + "combat_audio": "774,775,777", + "melee_animation": "5485", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "70", + "defence_animation": "5513", + "weakness": "8", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "17", + "safespot": null, + "lifepoints": "29", + "strength_level": "18", + "id": "5332", + "aggressive": "true", + "range_level": "1", + "attack_level": "15" + }, + { + "examine": "Could do with gaining a few pounds.", + "range_animation": "0", + "combat_audio": "774,775,777", + "melee_animation": "5485", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "70", + "defence_animation": "5513", + "weakness": "8", + "magic_animation": "0", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "17", + "safespot": null, + "lifepoints": "29", + "strength_level": "18", + "id": "5333", + "aggressive": "true", + "range_level": "1", + "attack_level": "15" + }, + { + "examine": "Could do with gaining a few pounds.", + "range_animation": "0", + "combat_audio": "774,775,777", + "melee_animation": "5485", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "70", + "defence_animation": "5513", + "weakness": "8", + "magic_animation": "0", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "17", + "safespot": null, + "lifepoints": "29", + "strength_level": "18", + "id": "5334", + "aggressive": "true", + "range_level": "1", + "attack_level": "15" + }, + { + "examine": "Could do with gaining a few pounds.", + "melee_animation": "5485", + "range_animation": "5485", + "combat_audio": "774,775,777", + "attack_speed": "6", + "defence_animation": "5489", + "magic_animation": "5485", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "1", + "safespot": null, + "lifepoints": "24", + "strength_level": "11", + "id": "5335", + "range_level": "1", + "attack_level": "11" + }, + { + "examine": "Could do with gaining a few pounds.", + "melee_animation": "5485", + "range_animation": "5485", + "combat_audio": "774,775,777", + "attack_speed": "6", + "defence_animation": "5489", + "magic_animation": "5485", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "1", + "safespot": null, + "lifepoints": "24", + "strength_level": "11", + "id": "5336", + "range_level": "1", + "attack_level": "11" + }, + { + "examine": "Could do with gaining a few pounds.", + "melee_animation": "5485", + "range_animation": "5485", + "combat_audio": "774,775,777", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "60", + "defence_animation": "5489", + "weakness": "8", + "magic_animation": "5485", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "24", + "safespot": null, + "lifepoints": "17", + "strength_level": "24", + "id": "5337", + "aggressive": "true", + "range_level": "1", + "attack_level": "24" + }, + { + "examine": "Could do with gaining a few pounds.", + "melee_animation": "5485", + "range_animation": "5485", + "combat_audio": "774,775,777", + "attack_speed": "6", + "defence_animation": "5489", + "weakness": "8", + "magic_animation": "5485", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "23", + "safespot": null, + "lifepoints": "17", + "strength_level": "12", + "id": "5338", + "range_level": "1", + "attack_level": "12" + }, + { + "examine": "Could do with gaining a few pounds.", + "melee_animation": "5485", + "range_animation": "5485", + "combat_audio": "774,775,777", + "attack_speed": "6", + "defence_animation": "5489", + "weakness": "8", + "magic_animation": "5485", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "23", + "safespot": null, + "lifepoints": "17", + "strength_level": "12", + "id": "5339", + "range_level": "1", + "attack_level": "12" + }, + { + "examine": "Could do with gaining a few pounds.", + "melee_animation": "5485", + "range_animation": "5485", + "combat_audio": "774,775,777", + "attack_speed": "6", + "defence_animation": "5489", + "weakness": "8", + "magic_animation": "5485", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "23", + "safespot": null, + "lifepoints": "17", + "strength_level": "12", + "id": "5340", + "range_level": "1", + "attack_level": "12" + }, + { + "examine": "Could do with gaining a few pounds.", + "melee_animation": "5499", + "range_animation": "0", + "combat_audio": "774,775,777", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "5503", + "name": "Skeleton", + "defence_level": "42", + "safespot": null, + "lifepoints": "60", + "strength_level": "42", + "id": "5341", + "aggressive": "true", + "range_level": "1", + "attack_level": "42" + }, + { + "examine": "Could do with gaining a few pounds.", + "melee_animation": "5485", + "range_animation": "0", + "combat_audio": "774,775,777", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "7", + "magic_animation": "0", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "34", + "safespot": null, + "lifepoints": "48", + "strength_level": "34", + "id": "5365", + "aggressive": "true", + "range_level": "1", + "attack_level": "34" + }, + { + "examine": "Could do with gaining a few pounds.", + "combat_audio": "774,775,777", + "melee_animation": "5485", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "5513", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "1", + "safespot": null, + "lifepoints": "60", + "strength_level": "1", + "id": "5366", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Could do with gaining a few pounds.", + "combat_audio": "774,775,777", + "melee_animation": "5485", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "5513", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "1", + "safespot": null, + "lifepoints": "85", + "strength_level": "1", + "id": "5367", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Could do with gaining a few pounds.", + "combat_audio": "774,775,777", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "5513", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "1", + "safespot": null, + "lifepoints": "85", + "strength_level": "1", + "id": "5368", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Could do with gaining a few pounds.", + "melee_animation": "5485", + "range_animation": "0", + "combat_audio": "774,775,777", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "62", + "safespot": null, + "lifepoints": "88", + "strength_level": "62", + "id": "5381", + "aggressive": "true", + "range_level": "1", + "attack_level": "62" + }, + { + "examine": "A skeleton in a dress!", + "melee_animation": "5487", + "range_animation": "0", + "combat_audio": "774,775,777", + "attack_speed": "5", + "magic_level": "57", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "5", + "magic_animation": "0", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "57", + "safespot": null, + "lifepoints": "81", + "strength_level": "1", + "id": "5385", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Achingly thin.", + "melee_animation": "5487", + "range_animation": "0", + "combat_audio": "774,775,777", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "55", + "safespot": null, + "lifepoints": "78", + "strength_level": "55", + "id": "5386", + "aggressive": "true", + "range_level": "1", + "attack_level": "55" + }, + { + "examine": "Look: another skeleton.", + "melee_animation": "5485", + "range_animation": "0", + "combat_audio": "774,775,777", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "55", + "safespot": null, + "lifepoints": "78", + "strength_level": "55", + "id": "5387", + "aggressive": "true", + "range_level": "1", + "attack_level": "55" + }, + { + "examine": "That skeleton's grinning at me.", + "melee_animation": "5487", + "range_animation": "0", + "combat_audio": "774,775,777", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "50", + "safespot": null, + "lifepoints": "71", + "strength_level": "50", + "id": "5388", + "aggressive": "true", + "range_level": "1", + "attack_level": "50" + }, + { + "examine": "He needs a tan.", + "melee_animation": "5487", + "range_animation": "0", + "combat_audio": "774,775,777", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "51", + "safespot": null, + "lifepoints": "72", + "strength_level": "51", + "id": "5389", + "aggressive": "true", + "range_level": "1", + "attack_level": "51" + }, + { + "examine": "How do you know if a skeleton's male or female?", + "melee_animation": "5485", + "range_animation": "0", + "combat_audio": "774,775,777", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "30", + "safespot": null, + "lifepoints": "420", + "strength_level": "36", + "id": "5390", + "aggressive": "true", + "range_level": "1", + "attack_level": "36" + }, + { + "examine": "He obviously hasn't realised he's dead.", + "melee_animation": "5485", + "range_animation": "0", + "combat_audio": "774,775,777", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "55", + "safespot": null, + "lifepoints": "78", + "strength_level": "55", + "id": "5391", + "aggressive": "true", + "range_level": "1", + "attack_level": "55" + }, + { + "examine": "Put some meat on those bones!", + "melee_animation": "5485", + "range_animation": "0", + "combat_audio": "774,775,777", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "52", + "safespot": null, + "lifepoints": "74", + "strength_level": "52", + "id": "5392", + "aggressive": "true", + "range_level": "1", + "attack_level": "52" + }, + { + "examine": "An angry skeleton.", + "melee_animation": "5487", + "range_animation": "0", + "combat_audio": "774,775,777", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "55", + "safespot": null, + "lifepoints": "78", + "strength_level": "55", + "id": "5411", + "aggressive": "true", + "range_level": "1", + "attack_level": "55" + }, + { + "examine": "Cross bones.", + "melee_animation": "5485", + "range_animation": "0", + "combat_audio": "774,775,777", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "57", + "safespot": null, + "lifepoints": "81", + "strength_level": "57", + "id": "5412", + "aggressive": "true", + "range_level": "1", + "attack_level": "57" + }, + { + "examine": "Could do with gaining a few pounds.", + "melee_animation": "5485", + "range_animation": "0", + "combat_audio": "774,775,777", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "63", + "safespot": null, + "lifepoints": "90", + "strength_level": "63", + "id": "5422", + "aggressive": "true", + "range_level": "1", + "attack_level": "63" + }, + { + "examine": "Ey.", + "combat_audio": "774,775,777", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "5513", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "1", + "safespot": null, + "lifepoints": "22", + "strength_level": "1", + "id": "6091", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Could do with gaining a few pounds.", + "combat_audio": "774,775,777", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "5513", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "1", + "safespot": null, + "lifepoints": "22", + "strength_level": "1", + "id": "6092", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Could do with gaining a few pounds.", + "melee_animation": "5487", + "range_animation": "0", + "combat_audio": "774,775,777", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "9", + "safespot": null, + "lifepoints": "12", + "strength_level": "9", + "id": "6093", + "aggressive": "true", + "range_level": "1", + "attack_level": "9" + }, + { + "examine": "An opponent from the grave. He seems unimpressed by your bone rummaging.", + "melee_animation": "2067", + "range_animation": "0", + "combat_audio": "774,775,777", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "836", + "name": "Skeleton hero", + "defence_level": "53", + "safespot": null, + "lifepoints": "75", + "strength_level": "53", + "id": "6103", + "aggressive": "true", + "range_level": "1", + "attack_level": "53" + }, + { + "examine": "An ex-barbarian, willing to make you ex too.", + "melee_animation": "422", + "range_animation": "0", + "combat_audio": "774,775,777", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "836", + "name": "Skeleton brute", + "defence_level": "63", + "safespot": null, + "lifepoints": "90", + "strength_level": "63", + "id": "6104", + "aggressive": "true", + "range_level": "1", + "attack_level": "63" + }, + { + "examine": "He's heartless.", + "melee_animation": "2067", + "range_animation": "0", + "combat_audio": "774,775,777", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "836", + "name": "Skeleton warlord", + "defence_level": "65", + "safespot": null, + "lifepoints": "92", + "strength_level": "65", + "id": "6105", + "aggressive": "true", + "range_level": "1", + "attack_level": "65" + }, + { + "examine": "He's less heavy now.", + "melee_animation": "390", + "range_animation": "0", + "combat_audio": "774,775,777", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "836", + "name": "Skeleton heavy", + "defence_level": "64", + "safespot": null, + "lifepoints": "91", + "strength_level": "64", + "id": "6106", + "aggressive": "true", + "range_level": "1", + "attack_level": "64" + }, + { + "examine": "Floats like an anvil, hits like a hammer.", + "melee_animation": "422", + "range_animation": "0", + "combat_audio": "774,775,777", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "8", + "magic_animation": "0", + "death_animation": "836", + "name": "Skeleton thug", + "defence_level": "61", + "safespot": null, + "lifepoints": "87", + "strength_level": "61", + "id": "6107", + "aggressive": "true", + "range_level": "1", + "attack_level": "61" + }, + { + "combat_audio": "774,775,777", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "5513", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "1", + "safespot": null, + "lifepoints": "97", + "strength_level": "1", + "id": "6764", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "combat_audio": "774,775,777", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "5513", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "1", + "safespot": null, + "lifepoints": "108", + "strength_level": "1", + "id": "6765", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "combat_audio": "774,775,777", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "5513", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "1", + "safespot": null, + "lifepoints": "120", + "strength_level": "1", + "id": "6766", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "combat_audio": "774,775,777", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "5513", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "1", + "safespot": null, + "lifepoints": "115", + "strength_level": "1", + "id": "6767", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "combat_audio": "774,775,777", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "5513", + "death_animation": "5491", + "name": "Skeleton", + "defence_level": "1", + "safespot": null, + "lifepoints": "140", + "strength_level": "1", + "id": "6768", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A hungry-looking rabbit.", + "melee_animation": "0", + "range_animation": "0", + "respawn_delay": "50", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Rabbit", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "7127", + "aggressive": "true", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A rich landlord, fat and jolly.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Inn Keeper", + "defence_level": "1", + "safespot": null, + "lifepoints": "10", + "strength_level": "1", + "id": "2177", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Likes to cook with mushrooms.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Fairy chef", + "defence_level": "1", + "safespot": null, + "movement_radius": "2", + "lifepoints": "10", + "strength_level": "1", + "id": "3322", + "range_level": "1", + "attack_level": "1" + }, + { + "melee_animation": "4388", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "4384", + "death_animation": "4389", + "name": "Suqah", + "defence_level": "95", + "safespot": null, + "lifepoints": "105", + "strength_level": "95", + "id": "4527", + "aggressive": "true", + "clue_level": "2", + "bonuses": "0,0,0,0,0,50,70,70,90,50,0,0,0,0,0", + "range_level": "1", + "attack_level": "95" + }, + { + "melee_animation": "4388", + "attack_speed": "5", + "respawn_delay": "60", + "defence_animation": "4384", + "death_animation": "4389", + "name": "Suqah", + "defence_level": "95", + "safespot": null, + "lifepoints": "105", + "strength_level": "95", + "id": "4528", + "aggressive": "true", + "clue_level": "2", + "bonuses": "0,0,0,0,0,50,70,70,90,50,0,0,0,0,0", + "range_level": "1", + "attack_level": "95" + }, + { + "examine": "A large ice troll.", + "melee_animation": "4332", + "range_animation": "0", + "attack_speed": "4", + "respawn_delay": "60", + "defence_animation": "0", + "weakness": "9", + "magic_animation": "0", + "name": "Ice troll grunt", + "defence_level": "60", + "safespot": null, + "lifepoints": "80", + "strength_level": "100", + "id": "5524", + "aggressive": "true", + "bonuses": "60,60,60,0,0,30,60,30,0,0,0,60,0,0,0", + "range_level": "1", + "attack_level": "100" + }, + { + "examine": "Soft but strong... and cute.", + "name": "Labrador puppy", + "id": "7247" + }, + { + "examine": "Soft but strong... and cute.", + "name": "Labrador puppy", + "id": "6962" + }, + { + "examine": "Soft but strong... and cute.", + "name": "Labrador puppy", + "id": "7245" + }, + { + "examine": "My most faithful friend.", + "name": "Labrador", + "id": "7248" + }, + { + "examine": "My most faithful friend.", + "name": "Labrador", + "id": "6963" + }, + { + "examine": "My most faithful friend.", + "name": "Labrador", + "id": "7246" + }, + { + "examine": "One proud little puppy.", + "name": "Bulldog puppy", + "id": "7260" + }, + { + "examine": "One proud little puppy.", + "name": "Bulldog puppy", + "id": "7259" + }, + { + "examine": "Looks like it's chewing a wasp.", + "name": "Bulldog", + "id": "6968" + }, + { + "examine": "Looks like it's chewing a wasp.", + "name": "Bulldog", + "id": "7258" + }, + { + "examine": "Looks like it's chewing a wasp.", + "name": "Bulldog", + "id": "7257" + }, + { + "examine": "Now, if only I could find another hundred...", + "name": "Dalmatian puppy", + "id": "6964" + }, + { + "examine": "Now, if only I could find another hundred...", + "name": "Dalmatian puppy", + "id": "7249" + }, + { + "examine": "Now, if only I could find another hundred...", + "name": "Dalmatian puppy", + "id": "7251" + }, + { + "examine": "A purebred doggy.", + "name": "Dalmatian", + "id": "7252" + }, + { + "examine": "A purebred doggy.", + "name": "Dalmatian", + "id": "7250" + }, + { + "examine": "A purebred doggy.", + "name": "Dalmatian", + "id": "6965" + }, + { + "examine": "This is one fast little pooch.", + "name": "Greyhound puppy", + "id": "6960" + }, + { + "examine": "This is one fast little pooch.", + "name": "Greyhound puppy", + "id": "7241" + }, + { + "examine": "This is one fast little pooch.", + "name": "Greyhound puppy", + "id": "7243" + }, + { + "examine": "An aerodynamic doggy.", + "name": "Greyhound", + "id": "6961" + }, + { + "examine": "An aerodynamic doggy.", + "name": "Greyhound", + "id": "7242" + }, + { + "examine": "An aerodynamic doggy.", + "name": "Greyhound", + "id": "7244" + }, + { + "examine": "It's lively and energetic.", + "name": "Terrier puppy", + "id": "6958" + }, + { + "examine": "A hyperactive little pup.", + "name": "Terrier puppy", + "id": "7237" + }, + { + "examine": "Such a brave doggy.", + "name": "Terrier puppy", + "id": "7239" + }, + { + "examine": "It's lively and energetic.", + "name": "Terrier", + "id": "6959" + }, + { + "examine": "A hyperactive little pup.", + "name": "Terrier", + "id": "7238" + }, + { + "examine": "Such a brave doggy.", + "name": "Terrier", + "id": "7240" + }, + { + "examine": "This little puppy is very quiet.", + "name": "Sheepdog puppy", + "id": "7253" + }, + { + "examine": "This little puppy is very quiet.", + "name": "Sheepdog puppy", + "id": "6966" + }, + { + "examine": "This little puppy is very quiet.", + "name": "Sheepdog puppy", + "id": "7255" + }, + { + "examine": "Come by! Come by!", + "name": "Sheepdog", + "id": "6967" + }, + { + "examine": "Come by! Come by!", + "name": "Sheepdog", + "id": "7254" + }, + { + "examine": "Come by! Come by!", + "name": "Sheepdog", + "id": "7256" + }, + { + "examine": "The sandwich lady.", + "name": "Sandwich lady", + "id": "3117" + }, + { + "examine": "A holy man.", + "name": "Drezel", + "id": "1049" + }, + { + "examine": "A holy man.", + "name": "Drezel", + "id": "7690" + }, + { + "examine": "A holy man.", + "name": "Drezel", + "id": "7707" + }, + { + "examine": "A slightly nervous guard.", + "name": "Ulizius", + "id": "1054" + }, + { + "examine": "A local holy man who supports the people trying to get though Mort Myre.", + "name": "Hiylik Myna", + "id": "1514" + }, + { + "examine": "The animated spirit of a soul not at rest.", + "name": "Filiman Tarlock", + "id": "1050" + }, + { + "examine": "The animated spirit of a soul not at rest.", + "name": "Nature Spirit", + "id": "1051" + }, + { + "examine": "I can see fish swimming in the water.", + "name": "Fishing spot", + "id": "323" + }, + { + "examine": "I can see fish swimming in the water.", + "name": "Fishing spot", + "id": "1176" + }, + { + "examine": "Nice hat.", + "name": "Thormac", + "id": "389" + }, + { + "examine": "An evil priest.", + "name": "Necrovarus", + "id": "1684" + }, + { + "examine": "He looks dangerous.", + "name": "Vannaka", + "id": "1597" + }, + { + "examine": "A soggy, smelly Fremennik.", + "name": "Olaf Hardson", + "id": "2621" + }, + { + "examine": "Perhaps this gardener might look after your crops for you.", + "name": "Elstan", + "id": "2323" + }, + { + "examine": "Perhaps this gardener might look after your crops for you.", + "name": "Dantaera", + "id": "2324" + }, + { + "examine": "Perhaps this gardener might look after your crops for you.", + "name": "Kragen", + "id": "2325" + }, + { + "examine": "Perhaps this gardener might look after your crops for you.", + "name": "Lyra", + "id": "2326" + }, + { + "examine": "Perhaps this gardener might look after your crops for you.", + "name": "Francis", + "id": "2327" + }, + { + "examine": "Perhaps this gardener might look after your crops for you.", + "name": "Rhonen", + "id": "2334" + }, + { + "examine": "Banks gnomish things.", + "name": "Gnome banker", + "id": "166" + }, + { + "examine": "Perhaps this gardener might look after your crops for you.", + "name": "Ellena", + "id": "2331" + }, + { + "examine": "Perhaps this gardener might look after your crops for you.", + "name": "Alain", + "id": "2339" + }, + { + "examine": "Perhaps this gardener might look after your crops for you.", + "name": "Dreven", + "id": "2335" + }, + { + "examine": "Founder and Director of the Piscatoris Fishing Colony.", + "name": "Herman Caranos", + "id": "3822" + }, + { + "examine": "Engineer for the Piscatoris Fishing Colony.", + "name": "Franklin Caranos", + "id": "3823" + }, + { + "examine": "Secretary and Storemaster for the Piscatoris Fishing Colony.", + "name": "Arnold Lydspor", + "id": "3824" + }, + { + "examine": "Perhaps this gardener might look after your crops for you.", + "name": "Frizzy Skernip", + "id": "4560" + }, + { + "examine": "She sells farming equipment.", + "name": "Sarah", + "id": "2304" + }, + { + "examine": "Perhaps this gardener might look after your crops for you.", + "name": "Garth", + "id": "2330" + }, + { + "examine": "Perhaps this gardener might look after your crops for you.", + "name": "Selena", + "id": "2332" + }, + { + "examine": "Perhaps this gardener might look after your crops for you.", + "name": "Rhazien", + "id": "2337" + }, + { + "examine": "Perhaps this gardener might look after your crops for you.", + "name": "Torrell", + "id": "2338" + }, + { + "examine": "Perhaps this gardener might look after your crops for you.", + "name": "Heskel", + "id": "2340" + }, + { + "examine": "Perhaps this gardener might look after your crops for you.", + "name": "Treznor", + "id": "2341" + }, + { + "examine": "Perhaps this gardener might look after your crops for you.", + "name": "Bolongo", + "id": "2343" + }, + { + "examine": "Perhaps this gardener might look after your crops for you.", + "name": "Gileth", + "id": "2344" + }, + { + "examine": "Perhaps this gardener might look after your crops for you.", + "name": "Amaethwyr", + "id": "2860" + }, + { + "examine": "Perhaps this gardener might look after your crops for you.", + "name": "Praistan Ebola", + "id": "4562" + }, + { + "examine": "Perhaps this gardener might look after your crops for you.", + "name": "Imiago", + "id": "8041" + }, + { + "examine": "Perhaps this gardener might look after your crops for you.", + "name": "Prissy Scilla", + "id": "1037" + }, + { + "examine": "Looks after your Farming tools.", + "name": "Teclyn", + "id": "2861" + }, + { + "examine": "Perhaps this gardener might look after your crops for you.", + "name": "Yulf Squecks", + "id": "4561" + }, + { + "examine": "The head farmer, apparently.", + "name": "Farmer Blinkin", + "id": "7131" + }, + { + "examine": "The lady of the pet shop.", + "name": "Pet shop owner", + "id": "6750" + }, + { + "examine": "Looks after the Burthorpe vinery.", + "name": "Bernald", + "id": "2580" + }, + { + "examine": "An old druid.", + "name": "Sanfew", + "id": "454" + }, + { + "examine": "He runs the Herblore Shop.", + "name": "Jatix", + "id": "587" + }, + { + "examine": "A wise druid.", + "name": "Kaqemeex", + "id": "455" + }, + { + "examine": "He's a very important druid.", + "name": "Pikkupstix", + "id": "6971" + }, + { + "examine": "Ironically, makes a living from swords.", + "name": "Gaius", + "id": "586" + }, + { + "examine": "A gnarly old man.", + "name": "Sylas", + "id": "5987" + }, + { + "examine": "A terrier puppy.", + "name": "Terrier", + "id": "6894" + }, + { + "examine": "A labrador puppy.", + "name": "Labrador", + "id": "6895" + }, + { + "examine": "Dwarvish.", + "name": "Thurgo", + "id": "604" + }, + { + "examine": "Get useful information from this guy.", + "name": "Town crier", + "id": "6137" + }, + { + "examine": "The mace salesman.", + "name": "Flynn", + "id": "580" + }, + { + "examine": "Works in the Rising Sun.", + "name": "Kaylee", + "id": "3217" + }, + { + "examine": "Works in the Rising Sun.", + "name": "Emily", + "id": "736" + }, + { + "examine": "Nice eyes.", + "name": "Cassie", + "id": "577" + }, + { + "examine": "Chief Herald of Falador.", + "name": "Sir Renitee", + "id": "4249" + }, + { + "examine": "An elderly White Knight.", + "name": "Sir Vyvin", + "id": "605" + }, + { + "examine": "An armourer.", + "name": "Wayne", + "id": "581" + }, + { + "examine": "A master of necromancy!", + "name": "Malignius Mortifer", + "id": "2713" + }, + { + "examine": "She seems like a nice sort of person.", + "name": "Betty", + "id": "583" + }, + { + "examine": "Loves his gold!", + "name": "Grum", + "id": "556" + }, + { + "examine": "Unkempt and a bit smelly.", + "name": "Bellemorde", + "id": "2942" + }, + { + "examine": "A Fishing expert.", + "name": "Gerrant", + "id": "558" + }, + { + "examine": "Likes his food to be kept fresh.", + "name": "Wydin", + "id": "557" + }, + { + "examine": "A sea bird.", + "name": "Gull", + "water_npc": "true", + "id": "2726" + }, + { + "examine": "An old sea dog.", + "name": "Captain Tobias", + "id": "376" + }, + { + "examine": "A young sailor.", + "name": "Klarense", + "id": "744" + }, + { + "examine": "An expert on axes.", + "name": "Brian", + "id": "559" + }, + { + "examine": "I could get a beer from him.", + "name": "Bartender", + "id": "734" + }, + { + "examine": "She is a seed merchant.", + "name": "Olivia", + "id": "2572" + }, + { + "examine": "Get useful information from this guy.", + "name": "Town crier", + "id": "6136" + }, + { + "examine": "Looks like he could do with a sip of Amontillado.", + "name": "Fortunato", + "id": "3671" + }, + { + "examine": "A young sailor.", + "name": "Seaman Thresnor", + "id": "378" + }, + { + "examine": "A young sailor.", + "name": "Seaman Lorris", + "id": "377" + }, + { + "examine": "A venerable and rich sage.", + "name": "Wise Old Man", + "id": "2253" + }, + { + "examine": "She comes from Al-Kharid.", + "name": "Leela", + "id": "915" + }, + { + "examine": "An old sailor.", + "name": "Ned", + "id": "743" + }, + { + "examine": "He looks scared.", + "name": "Morgan", + "id": "755" + }, + { + "examine": "A witch.", + "name": "Aggie", + "id": "922" + }, + { + "examine": "Bacon-in-training.", + "name": "Piglet", + "id": "2243" + }, + { + "examine": "An infamous bandit.", + "name": "Lady Keli", + "id": "919" + }, + { + "examine": "A young prince.", + "name": "Prince Ali", + "id": "920" + }, + { + "examine": "A gnome mage on sabbatical.", + "name": "Professor Onglewip", + "id": "4585" + }, + { + "examine": "Chief of research at Wizards Tower.", + "name": "Sedridor", + "id": "300" + }, + { + "examine": "An old wizard.", + "name": "Traiborn", + "id": "881" + }, + { + "examine": "Master of imps.", + "name": "Wizard Grayzag", + "id": "707" + }, + { + "examine": "A very brave merchant.", + "name": "Edmond", + "id": "1785" + }, + { + "examine": "She's an expert on armoured skirts.", + "name": "Ranael", + "id": "544" + }, + { + "examine": "Spymaster of Al Kharid.", + "name": "Osman", + "id": "924" + }, + { + "examine": "Kebabs are full of meaty goodness!", + "name": "Karim", + "id": "543" + }, + { + "examine": "He can look after my money.", + "name": "Banker", + "id": "496" + }, + { + "examine": "She can look after my money.", + "name": "Banker", + "id": "497" + }, + { + "examine": "Manufacturer of fine leathers.", + "name": "Ellis", + "id": "2824" + }, + { + "examine": "Sells superior scimitars.", + "name": "Zeke", + "id": "541" + }, + { + "examine": "If Crafting's your thing, he's your man.", + "name": "Dommik", + "id": "545" + }, + { + "examine": "He's in control of the Shantay Pass.", + "name": "Shantay", + "id": "836" + }, + { + "examine": "A resident of Al Kharid.", + "name": "Irena", + "id": "835" + }, + { + "examine": "A farmer's enemy.", + "name": "Crow", + "id": "1755" + }, + { + "examine": "The hat's a dead giveaway.", + "name": "Witch", + "id": "5200" + }, + { + "examine": "A mad scientist if I ever saw one!", + "name": "Professor Oddenstein", + "id": "286" + }, + { + "examine": "She's watching you.", + "name": "Ava", + "id": "5198" + }, + { + "examine": "Litara, a barbarian explorer.", + "name": "Litara", + "id": "4376" + }, + { + "examine": "Always up-to-date with the latest helmet fashions.", + "name": "Peksa", + "id": "538" + }, + { + "examine": "A strange little man.", + "name": "Oziach", + "id": "747" + }, + { + "examine": "A very brave merchant.", + "name": "Richard", + "id": "1783" + }, + { + "examine": "Loves you more, the more you spend.", + "name": "Shop assistant", + "id": "529" + }, + { + "examine": "Sells stuff.", + "name": "Shopkeeper", + "id": "528" + }, + { + "examine": "One of the king's knights.", + "name": "Sir Prysin", + "id": "883" + }, + { + "examine": "Reldo the librarian.", + "name": "Reldo", + "id": "2660" + }, + { + "examine": "A powerful wizard.", + "name": "Surok Magis", + "id": "5834" + }, + { + "examine": "Animal skins are a specialty.", + "name": "Baraek", + "id": "547" + }, + { + "examine": "One of Gertrude's Sons.", + "name": "Shilop", + "id": "781" + }, + { + "examine": "The man with the armour.", + "name": "Horvik", + "id": "549" + }, + { + "examine": "Sells arrows.", + "name": "Lowe", + "id": "550" + }, + { + "examine": "This looks like an angry, aggressive man.", + "name": "Draul Leptoc", + "id": "3324" + }, + { + "examine": "A quiet, more reserved sort of lady.", + "name": "Phillipa", + "id": "3325" + }, + { + "examine": "A tearful damsel, maybe I can help her?", + "name": "Juliet", + "id": "637" + }, + { + "agg_radius": "", + "examine": "Like a mini man!", + "combat_style": "1", + "melee_animation": "190", + "attack_speed": "4", + "respawn_delay": "60", + "defence_animation": "193", + "weakness": "", + "end_height": "", + "death_animation": "196", + "name": "Gnome", + "defence_level": "1", + "lifepoints": "2", + "strength_level": "1", + "id": "2250", + "aggressive": "", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "Like a mini man!", + "combat_style": "1", + "melee_animation": "190", + "attack_speed": "4", + "respawn_delay": "60", + "defence_animation": "193", + "death_animation": "196", + "name": "Gnome", + "defence_level": "1", + "lifepoints": "3", + "strength_level": "1", + "id": "2249", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "null", + "defence_level": "1", + "safespot": "null", + "combat_audio": "511,513,512", + "id": "2309", + "range_level": "1", + "attack_level": "1", + "defence_animation": "" + }, + { + "examine": "Yanni Salika; he buys and sells antiques.", + "name": "Yanni Salika", + "id": "515" + }, + { + "examine": "This is Kaleb Paramaya, a warm and friendly inn owner.", + "name": "Kaleb Paramaya", + "id": "512" + }, + { + "examine": "This is Fernahei; he owns the local fishing tackle shop.", + "name": "Fernahei", + "id": "517" + }, + { + "examine": "A warrior from Shilo Village.", + "name": "Mosol Rei", + "id": "500" + }, + { + "examine": "An unquiet soul.", + "name": "Spirit of Zadimus", + "id": "501" + }, + { + "examine": "The animated spirit of Rashiliyia the Zombie Queen.", + "name": "Rashiliyia ", + "id": "506" + }, + { + "examine": "A dwarf miner. He's shoring up the walls.", + "name": "Ferd", + "id": "3937" + }, + { + "examine": "A crafty dwarf.", + "name": "Nolar", + "id": "2158" + }, + { + "examine": "She sells general items at the Legends Guild.", + "name": "Fionella", + "id": "932" + }, + { + "examine": "A dwarf who's currently living in Miscellania.", + "name": "Alviss", + "id": "3933" + }, + { + "examine": "Smithy for Sogthorpe.", + "name": "Derrik", + "id": "1376" + }, + { + "examine": "A rather scared-looking dwarf. He doesn't seem all that drunk.", + "name": "Donal", + "id": "3938" + }, + { + "examine": "Runs the general store.", + "name": "Finn", + "id": "3922" + }, + { + "examine": "A dwarf who's currently living in Miscellania.", + "name": "Fullangr", + "id": "3934" + }, + { + "examine": "A subject of Miscellania.", + "name": "Halla", + "id": "3921" + }, + { + "examine": "A dwarf who's currently living in Miscellania.", + "name": "Jari", + "id": "3935" + }, + { + "examine": "A subject of Miscellania.", + "name": "Einar", + "id": "1380" + }, + { + "examine": "A subject of Miscellania.", + "name": "Ragnar", + "id": "1379" + }, + { + "examine": "A subject of Miscellania.", + "name": "Thora", + "id": "3927" + }, + { + "examine": "A subject of Miscellania.", + "name": "Thorhild", + "id": "1382" + }, + { + "examine": "A subject of Miscellania.", + "name": "Tjorvi", + "id": "3925" + }, + { + "examine": "Likes fish... hates people.", + "melee_animation": "284", + "attack_speed": "4", + "magic_level": "1", + "respawn_delay": "", + "defence_animation": "285", + "death_animation": "287", + "name": "River troll", + "defence_level": "17", + "lifepoints": "20", + "strength_level": "17", + "id": "391", + "aggressive": "true", + "clue_level": "", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "17" + }, + { + "examine": "Likes fish... hates people.", + "melee_animation": "284", + "attack_speed": "4", + "magic_level": "1", + "defence_animation": "285", + "death_animation": "287", + "name": "River troll", + "defence_level": "48", + "lifepoints": "48", + "strength_level": "48", + "id": "393", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "48" + }, + { + "examine": "Likes fish... hates people.", + "melee_animation": "284", + "attack_speed": "4", + "magic_level": "1", + "defence_animation": "285", + "death_animation": "287", + "name": "River troll", + "defence_level": "65", + "lifepoints": "85", + "strength_level": "65", + "id": "394", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "65" + }, + { + "examine": "Likes fish... hates people.", + "melee_animation": "284", + "attack_speed": "4", + "magic_level": "1", + "defence_animation": "285", + "death_animation": "287", + "name": "River troll", + "defence_level": "100", + "lifepoints": "120", + "strength_level": "100", + "id": "395", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "100" + }, + { + "examine": "Likes fish... hates people.", + "melee_animation": "284", + "attack_speed": "4", + "magic_level": "1", + "defence_animation": "285", + "death_animation": "287", + "name": "River troll", + "defence_level": "130", + "lifepoints": "170", + "strength_level": "130", + "id": "396", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "130" + }, + { + "examine": "Rock with attitude.", + "combat_style": "1", + "range_animation": "0", + "attack_speed": "4", + "defence_animation": "8", + "name": "Rock Golem", + "lifepoints": "25", + "strength_level": "8", + "id": "413", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "15", + "attack_level": "8" + }, + { + "examine": "Rock with attitude.", + "combat_style": "1", + "range_animation": "0", + "attack_speed": "4", + "defence_animation": "17", + "name": "Rock Golem", + "lifepoints": "40", + "strength_level": "17", + "id": "414", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "30", + "attack_level": "17" + }, + { + "examine": "Rock with attitude.", + "combat_style": "1", + "range_animation": "0", + "attack_speed": "4", + "defence_animation": "36", + "name": "Rock Golem", + "lifepoints": "60", + "strength_level": "36", + "id": "415", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "40", + "attack_level": "38" + }, + { + "examine": "Rock with attitude.", + "combat_style": "1", + "range_animation": "0", + "attack_speed": "4", + "defence_animation": "64", + "name": "Rock Golem", + "lifepoints": "86", + "strength_level": "64", + "id": "416", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "60", + "attack_level": "64" + }, + { + "examine": "Rock with attitude.", + "combat_style": "1", + "range_animation": "0", + "attack_speed": "4", + "defence_animation": "100", + "name": "Rock Golem", + "lifepoints": "120", + "strength_level": "100", + "id": "417", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "75", + "attack_level": "100" + }, + { + "examine": "Rock with attitude.", + "combat_style": "1", + "range_animation": "0", + "attack_speed": "4", + "defence_animation": "130", + "name": "Rock Golem", + "lifepoints": "166", + "strength_level": "130", + "id": "418", + "aggressive": "true", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "80", + "attack_level": "130" + }, + { + "examine": "Mooooooooooooole.", + "name": "Baby Mole", + "id": "3342" + }, + { + "examine": "Moley, moley, moley!", + "name": "Baby Mole", + "id": "3343" + }, + { + "examine": "He hungry.", + "combat_style": "1", + "start_gfx": "243", + "name": "Rantz", + "start_height": "100", + "range_animation": "3460", + "id": "1010", + "projectile": "242", + "prj_height": "50" + }, + { + "examine": "One of Fenkenstrain's failed experiments.", + "combat_style": "", + "melee_animation": "1616", + "attack_speed": "4", + "magic_level": "1", + "defence_animation": "1617", + "death_animation": "1618", + "name": "Experiment", + "defence_level": "30", + "lifepoints": "100", + "strength_level": "1", + "id": "1677", + "aggressive": "", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "It has a key hanging from its collar.", + "melee_animation": "1626", + "attack_speed": "4", + "magic_level": "1", + "defence_animation": "1627", + "death_animation": "1628", + "name": "Experiment", + "defence_level": "50", + "lifepoints": "40", + "strength_level": "50", + "id": "1676", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "40" + }, + { + "examine": "One of Fenkenstrain's failed experiments.", + "melee_animation": "1612", + "attack_speed": "4", + "magic_level": "1", + "defence_animation": "1613", + "death_animation": "1611", + "name": "Experiment", + "defence_level": "30", + "lifepoints": "100", + "strength_level": "1", + "id": "1678", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "1" + }, + { + "name": "Puro Spawn (Low)", + "id": "6065", + "respawn_delay": "1" + }, + { + "name": "Puro Spawn (Mid)", + "id": "6066", + "respawn_delay": "1" + }, + { + "name": "Puro Spawn (High)", + "id": "6067", + "respawn_delay": "1" + }, + { + "examine": "A baby impling. Ahhh.", + "name": "Baby Impling Puro", + "id": "6055", + "respawn_delay": "7" + }, + { + "examine": "A young impling. It's not fair!", + "name": "Young Impling Puro", + "id": "6056", + "respawn_delay": "7" + }, + { + "examine": "An impling gourmet. Mmmm, tasty.", + "name": "Gourmet Impling Puro", + "id": "6057", + "respawn_delay": "7" + }, + { + "examine": "An earth impling. Rock on.", + "name": "Earth Impling Puro", + "id": "6058", + "respawn_delay": "50" + }, + { + "examine": "An impling who likes magic. Magic!", + "name": "Essence Impling Puro", + "id": "6059", + "respawn_delay": "50" + }, + { + "examine": "An impling with varied tastes.", + "name": "Eclectic Impling Puro", + "id": "6060", + "respawn_delay": "7" + }, + { + "examine": "A very stealthy impling.", + "name": "Ninja Impling Puro", + "id": "6063", + "respawn_delay": "9999" + }, + { + "examine": "A nature impling. Right on, maaan.", + "name": "Nature Impling Puro", + "id": "6061", + "respawn_delay": "9999" + }, + { + "examine": "Ooh, shiny things!", + "name": "Magpie Impling Puro", + "id": "6062", + "respawn_delay": "9999" + }, + { + "examine": "He looks dangerous!", + "name": "Turael", + "id": "8273" + }, + { + "examine": "Doesn't seem to want to go away.", + "combat_style": "2", + "melee_animation": "811", + "range_animation": "811", + "attack_speed": "4", + "magic_level": "100", + "defence_animation": "0", + "magic_animation": "811", + "death_animation": "836", + "name": "Skeleton Mage", + "defence_level": "60", + "lifepoints": "80", + "strength_level": "10", + "id": "3851", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "range_level": "1", + "attack_level": "10" + }, + { + "examine": "Blaec seems to be covered in sand.", + "name": "Blaec", + "id": "3115" + }, + { + "examine": "Looks otherworldy...", + "name": "Fairy Queen", + "id": "4437" + }, + { + "examine": "A delicate creature from this strange realm.", + "name": "Fairy", + "id": "4443" + }, + { + "examine": "A very strange plant.", + "death_animation": "355", + "name": "Strange Plant", + "defence_level": "300", + "melee_animation": "353", + "lifepoints": "100", + "id": "408", + "magic_level": "200", + "defence_animation": "354" + }, + { + "examine": "A very strange plant.", + "name": "Strange Plant", + "id": "407" + }, + { + "agg_radius": "", + "examine": "A helmetted, barbarian snowman.", + "death_animation": "7560", + "name": "Barbarian Snowman", + "defence_level": "1", + "melee_animation": "7565", + "lifepoints": "20", + "combat_audio": "12,3295,3287", + "id": "6742", + "defence_animation": "7559" + }, + { + "examine": "A snow dwarf.", + "death_animation": "7560", + "name": "Dwarf Snowman", + "defence_level": "1", + "melee_animation": "7565", + "lifepoints": "20", + "combat_audio": "12,3295,3287", + "id": "6744", + "defence_animation": "7559" + }, + { + "examine": "Distinctly heroic.", + "name": "Achietties", + "id": "796" + }, + { + "name": "Wizard Cromperty", + "id": "2328", + "examine": "The hat is a dead give away." + }, + { + "examine": "An intelligent-looking shop owner.", + "name": "Obli", + "id": "516" + }, + { + "examine": "A person sitting an exam.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Student", + "defence_level": "1", + "lifepoints": "10", + "strength_level": "1", + "id": "7151", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A person sitting an exam.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Student", + "defence_level": "1", + "lifepoints": "10", + "strength_level": "1", + "id": "7153", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A person sitting an exam.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Student", + "defence_level": "1", + "lifepoints": "10", + "strength_level": "1", + "id": "7154", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "A person sitting an exam.", + "melee_animation": "0", + "range_animation": "0", + "defence_animation": "0", + "magic_animation": "0", + "death_animation": "0", + "name": "Student", + "defence_level": "1", + "lifepoints": "10", + "strength_level": "1", + "id": "7155", + "range_level": "1", + "attack_level": "1" + }, + { + "examine": "She looks like she means business.", + "name": "Balnea", + "id": "7047" + }, + { + "id": "17", + "name": "Schoolgirl" + }, + { + "id": "70", + "name": "Orc" + }, + { + "id": "94", + "name": "Skeleton Mage" + }, + { + "id": "129", + "name": "Skavid" + }, + { + "id": "135", + "name": "Mammoth" + }, + { + "id": "136", + "name": "Mounted terrorchick gnome" + }, + { + "id": "149", + "name": "Gull" + }, + { + "id": "150", + "name": "Gull" + }, + { + "id": "151", + "name": "Fly trap" + }, + { + "id": "152", + "name": "Butterfly" + }, + { + "id": "155", + "name": "Butterfly" + }, + { + "id": "156", + "name": "Butterfly" + }, + { + "id": "157", + "name": "Butterfly" + }, + { + "id": "165", + "name": "Gnome shop keeper" + }, + { + "id": "167", + "name": "Gnome baller" + }, + { + "id": "171", + "name": "Brimstail" + }, + { + "id": "177", + "name": "Witch" + }, + { + "id": "195", + "name": "Bandit" + }, + { + "id": "197", + "name": "Barbarian guard" + }, + { + "id": "200", + "name": "Lord Daquarius" + }, + { + "id": "207", + "name": "Lollk" + }, + { + "id": "209", + "name": "Nulodion" + }, + { + "id": "211", + "name": "Sir Percival" + }, + { + "id": "213", + "name": "Merlin" + }, + { + "id": "215", + "name": "Peasant" + }, + { + "id": "217", + "name": "Crone" + }, + { + "id": "218", + "name": "Galahad" + }, + { + "id": "225", + "name": "Bonzo" + }, + { + "id": "226", + "name": "Morris" + }, + { + "id": "228", + "name": "Big Dave" + }, + { + "id": "229", + "name": "Joshua" + }, + { + "id": "232", + "name": "Austri" + }, + { + "id": "234", + "name": "Fishing spot" + }, + { + "id": "235", + "name": "Fishing spot" + }, + { + "id": "236", + "name": "Fishing spot" + }, + { + "id": "239", + "name": "Sir Lancelot" + }, + { + "id": "240", + "name": "Sir Gawain" + }, + { + "id": "241", + "name": "Sir Kay" + }, + { + "id": "242", + "name": "Sir Bedivere" + }, + { + "id": "243", + "name": "Sir Tristram" + }, + { + "id": "244", + "name": "Sir Pelleas" + }, + { + "id": "245", + "name": "Sir Lucan" + }, + { + "id": "248", + "name": "Morgan Le Faye" + }, + { + "id": "249", + "name": "Merlin" + }, + { + "id": "250", + "name": "The Lady of the Lake" + }, + { + "id": "252", + "name": "Beggar" + }, + { + "id": "260", + "name": "Kelvin" + }, + { + "id": "261", + "name": "Joe" + }, + { + "id": "263", + "name": "Hengrad" + }, + { + "id": "276", + "name": "Winelda" + }, + { + "id": "287", + "name": "Ernest" + }, + { + "id": "292", + "name": "Guard" + }, + { + "id": "301", + "name": "Twig" + }, + { + "id": "302", + "name": "Hadley" + }, + { + "id": "303", + "name": "Gerald" + }, + { + "id": "304", + "name": "Almera" + }, + { + "id": "305", + "name": "Hudon" + }, + { + "id": "306", + "name": "Golrie" + }, + { + "id": "309", + "name": "Fishing spot" + }, + { + "id": "310", + "name": "Fishing spot" + }, + { + "id": "311", + "name": "Fishing spot" + }, + { + "id": "312", + "name": "Fishing spot" + }, + { + "id": "313", + "name": "Fishing spot" + }, + { + "id": "314", + "name": "Fishing spot" + }, + { + "id": "315", + "name": "Fishing spot" + }, + { + "id": "316", + "name": "Fishing spot" + }, + { + "id": "317", + "name": "Fishing spot" + }, + { + "id": "318", + "name": "Fishing spot" + }, + { + "id": "319", + "name": "Fishing spot" + }, + { + "id": "320", + "name": "Fishing spot" + }, + { + "id": "321", + "name": "Fishing spot" + }, + { + "id": "322", + "name": "Fishing spot" + }, + { + "id": "324", + "name": "Fishing spot" + }, + { + "id": "325", + "name": "Fishing spot" + }, + { + "id": "326", + "name": "Fishing spot" + }, + { + "id": "327", + "name": "Fishing spot" + }, + { + "id": "328", + "name": "Fishing spot" + }, + { + "id": "329", + "name": "Fishing spot" + }, + { + "id": "330", + "name": "Fishing spot" + }, + { + "id": "331", + "name": "Fishing spot" + }, + { + "id": "332", + "name": "Fishing spot" + }, + { + "id": "333", + "name": "Fishing spot" + }, + { + "id": "334", + "name": "Fishing spot" + }, + { + "id": "337", + "name": "Da Vinci" + }, + { + "id": "343", + "name": "Guidor" + }, + { + "id": "349", + "name": "Kilron" + }, + { + "id": "350", + "name": "Omart" + }, + { + "id": "366", + "name": "Jerico" + }, + { + "id": "379", + "name": "Luthas" + }, + { + "id": "381", + "name": "Dwarf" + }, + { + "id": "383", + "name": "Stankers" + }, + { + "id": "399", + "name": "Legends guard" + }, + { + "id": "400", + "name": "Radimus Erkle" + }, + { + "id": "403", + "name": "Fishing spot" + }, + { + "id": "404", + "name": "Fishing spot" + }, + { + "id": "405", + "name": "Fishing spot" + }, + { + "id": "406", + "name": "Fishing spot" + }, + { + "id": "409", + "name": "Genie" + }, + { + "id": "410", + "name": "Mysterious Old Man" + }, + { + "id": "431", + "name": "Cyrisus" + }, + { + "id": "433", + "name": "Cyrisus" + }, + { + "id": "434", + "name": "Cyrisus" + }, + { + "id": "436", + "name": "Fallen Man" + }, + { + "id": "463", + "name": "Murphy" + }, + { + "id": "464", + "name": "Murphy" + }, + { + "id": "465", + "name": "Murphy" + }, + { + "id": "466", + "name": "Murphy" + }, + { + "id": "467", + "name": "Shark" + }, + { + "id": "468", + "name": "Shark" + }, + { + "id": "471", + "name": "Bolkoy" + }, + { + "id": "472", + "name": "Remsai" + }, + { + "id": "473", + "name": "Khazard trooper" + }, + { + "id": "480", + "name": "Gnome troop" + }, + { + "id": "484", + "name": "Local Gnome" + }, + { + "id": "486", + "name": "Kalron" + }, + { + "id": "488", + "name": "Observatory professor" + }, + { + "id": "510", + "name": "Hajedy" + }, + { + "id": "511", + "name": "Vigroy" + }, + { + "id": "513", + "name": "Yohnus" + }, + { + "id": "514", + "name": "Seravel" + }, + { + "id": "536", + "name": "Valaine" + }, + { + "id": "537", + "name": "Scavvo" + }, + { + "id": "553", + "name": "Aubury" + }, + { + "id": "560", + "name": "Jiminua" + }, + { + "id": "563", + "name": "Arhein" + }, + { + "id": "565", + "name": "Lunderwin" + }, + { + "id": "568", + "name": "Zambo" + }, + { + "id": "575", + "name": "Hickton" + }, + { + "id": "576", + "name": "Harry" + }, + { + "id": "578", + "name": "Frincos" + }, + { + "id": "584", + "name": "Herquin" + }, + { + "id": "585", + "name": "Rommik" + }, + { + "id": "588", + "name": "Davon" + }, + { + "id": "589", + "name": "Zenesha" + }, + { + "id": "590", + "name": "Aemad" + }, + { + "id": "591", + "name": "Kortan" + }, + { + "id": "592", + "name": "Roachey" + }, + { + "id": "593", + "name": "Frenita" + }, + { + "id": "594", + "name": "Nurmof" + }, + { + "id": "597", + "name": "Noterazzo" + }, + { + "id": "600", + "name": "Hudo" + }, + { + "id": "601", + "name": "Rometti" + }, + { + "id": "602", + "name": "Gulluck" + }, + { + "id": "603", + "name": "Heckel Funch" + }, + { + "id": "607", + "name": "Gunnjorn" + }, + { + "id": "608", + "name": "Sir Amik Varze" + }, + { + "id": "612", + "name": "Greldo" + }, + { + "id": "622", + "name": "Gnome baller" + }, + { + "id": "623", + "name": "Gnome baller" + }, + { + "id": "624", + "name": "Gnome baller" + }, + { + "id": "625", + "name": "Gnome baller" + }, + { + "id": "626", + "name": "Gnome baller" + }, + { + "id": "627", + "name": "Gnome baller" + }, + { + "id": "628", + "name": "Gnome baller" + }, + { + "id": "629", + "name": "Gnome baller" + }, + { + "id": "630", + "name": "Gnome baller" + }, + { + "id": "631", + "name": "Gnome baller" + }, + { + "id": "632", + "name": "Gnome baller" + }, + { + "id": "634", + "name": "Gnome winger" + }, + { + "id": "636", + "name": "Cheerleader" + }, + { + "id": "642", + "name": "Katrine" + }, + { + "id": "644", + "name": "Straven" + }, + { + "id": "647", + "name": "King Roald" + }, + { + "id": "653", + "name": "Fairy Queen" + }, + { + "id": "654", + "name": "Shamus" + }, + { + "id": "661", + "name": "Megan" + }, + { + "id": "662", + "name": "Lucy" + }, + { + "id": "664", + "name": "Boot" + }, + { + "id": "666", + "name": "Caleb" + }, + { + "id": "668", + "name": "Johnathon" + }, + { + "id": "669", + "name": "Hazelmere" + }, + { + "id": "671", + "name": "Glough" + }, + { + "id": "672", + "name": "Anita" + }, + { + "id": "673", + "name": "Charlie" + }, + { + "id": "675", + "name": "Shipyard worker" + }, + { + "id": "676", + "name": "Femi" + }, + { + "id": "685", + "name": "Tower Advisor" + }, + { + "id": "686", + "name": "Tower Advisor" + }, + { + "id": "687", + "name": "Tower Advisor" + }, + { + "id": "693", + "name": "Competition Judge" + }, + { + "id": "695", + "name": "Bailey" + }, + { + "id": "697", + "name": "Holgart" + }, + { + "id": "699", + "name": "Holgart" + }, + { + "id": "700", + "name": "Holgart" + }, + { + "id": "701", + "name": "Kent" + }, + { + "id": "702", + "name": "Fisherman" + }, + { + "id": "703", + "name": "Fisherman" + }, + { + "id": "704", + "name": "Fisherman" + }, + { + "id": "710", + "name": "Alrena" + }, + { + "id": "711", + "name": "Bravek" + }, + { + "id": "712", + "name": "Carla" + }, + { + "id": "721", + "name": "Ted Rehnison" + }, + { + "id": "722", + "name": "Martha Rehnison" + }, + { + "id": "723", + "name": "Billy Rehnison" + }, + { + "id": "724", + "name": "Milli Rehnison" + }, + { + "id": "725", + "name": "Jethick" + }, + { + "id": "740", + "name": "Trufitus" + }, + { + "id": "746", + "name": "Oracle" + }, + { + "id": "748", + "name": "Angry barbarian spirit" + }, + { + "id": "754", + "name": "Peaceful barbarian spirit" + }, + { + "id": "759", + "name": "Kittens" + }, + { + "id": "761", + "name": "Kitten" + }, + { + "id": "762", + "name": "Kitten" + }, + { + "id": "763", + "name": "Kitten" + }, + { + "id": "764", + "name": "Kitten" + }, + { + "id": "765", + "name": "Kitten" + }, + { + "id": "766", + "name": "Kitten" + }, + { + "id": "768", + "name": "Cat" + }, + { + "id": "769", + "name": "Cat" + }, + { + "id": "770", + "name": "Cat" + }, + { + "id": "771", + "name": "Cat" + }, + { + "id": "772", + "name": "Cat" + }, + { + "id": "773", + "name": "Cat" + }, + { + "id": "774", + "name": "Overgrown cat" + }, + { + "id": "775", + "name": "Overgrown cat" + }, + { + "id": "776", + "name": "Overgrown cat" + }, + { + "id": "777", + "name": "Overgrown cat" + }, + { + "id": "779", + "name": "Overgrown cat" + }, + { + "id": "780", + "name": "Gertrude" + }, + { + "id": "782", + "name": "Philop" + }, + { + "id": "784", + "name": "Kanel" + }, + { + "id": "788", + "name": "Garv" + }, + { + "id": "789", + "name": "Grubor" + }, + { + "id": "791", + "name": "Seth" + }, + { + "id": "792", + "name": "Grip" + }, + { + "id": "797", + "name": "Helemos" + }, + { + "id": "807", + "name": "Pierre" + }, + { + "id": "808", + "name": "Hobbes" + }, + { + "id": "809", + "name": "Louisa" + }, + { + "id": "810", + "name": "Mary" + }, + { + "id": "811", + "name": "Stanford" + }, + { + "id": "814", + "name": "Anna" + }, + { + "id": "815", + "name": "Bob" + }, + { + "id": "816", + "name": "Carol" + }, + { + "id": "817", + "name": "David" + }, + { + "id": "818", + "name": "Elizabeth" + }, + { + "id": "819", + "name": "Frank" + }, + { + "id": "822", + "name": "Ana" + }, + { + "id": "823", + "name": "Ana" + }, + { + "id": "824", + "name": "Female slave" + }, + { + "id": "826", + "name": "Escaping slave" + }, + { + "id": "828", + "name": "Shanty Claws" + }, + { + "id": "829", + "name": "Mercenary Captain" + }, + { + "id": "832", + "name": "Al Shabim" + }, + { + "id": "844", + "name": "Horacio" + }, + { + "id": "846", + "name": "Kangai Mau" + }, + { + "id": "848", + "name": "Blurberry" + }, + { + "id": "849", + "name": "Barman" + }, + { + "id": "853", + "name": "Og" + }, + { + "id": "854", + "name": "Grew" + }, + { + "id": "855", + "name": "Toban" + }, + { + "id": "857", + "name": "Ogre guard" + }, + { + "id": "860", + "name": "Ogre guard" + }, + { + "id": "861", + "name": "Ogre guard" + }, + { + "id": "865", + "name": "Skavid" + }, + { + "id": "866", + "name": "Skavid" + }, + { + "id": "867", + "name": "Skavid" + }, + { + "id": "868", + "name": "Skavid" + }, + { + "id": "869", + "name": "Skavid" + }, + { + "id": "871", + "name": "Watchtower Wizard" + }, + { + "id": "876", + "name": "Ogre trader" + }, + { + "id": "880", + "name": "Weakened Delrith" + }, + { + "id": "886", + "name": "Claus the chef" + }, + { + "id": "888", + "name": "Philipe Carnillean" + }, + { + "id": "889", + "name": "Henryeta Carnillean" + }, + { + "id": "890", + "name": "Butler Jones" + }, + { + "id": "891", + "name": "Alomone" + }, + { + "id": "892", + "name": "Hazeel" + }, + { + "id": "896", + "name": "Nora T. Hagg" + }, + { + "id": "901", + "name": "Mouse" + }, + { + "id": "902", + "name": "Gundai" + }, + { + "id": "903", + "name": "Lundail" + }, + { + "id": "906", + "name": "Kolodion" + }, + { + "id": "918", + "name": "Ned" + }, + { + "id": "921", + "name": "Prince Ali" + }, + { + "id": "926", + "name": "Border Guard" + }, + { + "id": "927", + "name": "Fishing spot" + }, + { + "id": "928", + "name": "Gujuo" + }, + { + "id": "929", + "name": "Ungadulu" + }, + { + "id": "930", + "name": "Ungadulu" + }, + { + "id": "933", + "name": "Siegfried Erkle" + }, + { + "id": "935", + "name": "Viyeldi" + }, + { + "id": "936", + "name": "San Tojalon" + }, + { + "id": "937", + "name": "Irvig Senay" + }, + { + "id": "940", + "name": "Echned Zekin" + }, + { + "id": "952", + "name": "Fishing spot" + }, + { + "id": "953", + "name": "Banker" + }, + { + "id": "992", + "name": "Kardia" + }, + { + "id": "994", + "name": "Niloof" + }, + { + "id": "1003", + "name": "Lord Iban" + }, + { + "id": "1008", + "name": "Hamid" + }, + { + "id": "1011", + "name": "Fycie" + }, + { + "id": "1012", + "name": "Bugs" + }, + { + "id": "1014", + "name": "Bloated Toad" + }, + { + "id": "1016", + "name": "Chompy bird" + }, + { + "id": "1024", + "name": "Baby impling" + }, + { + "id": "1036", + "name": "Banker" + }, + { + "id": "1038", + "name": "Rufus" + }, + { + "id": "1039", + "name": "Barker" + }, + { + "id": "1040", + "name": "Fidelio" + }, + { + "id": "1041", + "name": "Sbott" + }, + { + "id": "1042", + "name": "Roavar" + }, + { + "id": "1043", + "name": "Will o' the wisp" + }, + { + "id": "1047", + "name": "Drezel" + }, + { + "id": "1056", + "name": "Mime" + }, + { + "id": "1070", + "name": "Saba" + }, + { + "id": "1071", + "name": "Tenzing" + }, + { + "id": "1075", + "name": "Archer" + }, + { + "id": "1091", + "name": "Bob" + }, + { + "id": "1093", + "name": "Billy" + }, + { + "id": "1094", + "name": "Mountain goat" + }, + { + "id": "1113", + "name": "Eadgar" + }, + { + "id": "1114", + "name": "Godric" + }, + { + "id": "1159", + "name": "Kalphite Queen" + }, + { + "id": "1162", + "name": "Timfraku" + }, + { + "id": "1163", + "name": "Tiadeche" + }, + { + "id": "1164", + "name": "Tiadeche" + }, + { + "id": "1165", + "name": "Tinsay" + }, + { + "id": "1166", + "name": "Tinsay" + }, + { + "id": "1167", + "name": "Tamayu" + }, + { + "id": "1168", + "name": "Tamayu" + }, + { + "id": "1169", + "name": "Tamayu" + }, + { + "id": "1170", + "name": "Tamayu" + }, + { + "id": "1171", + "name": "Lubufu" + }, + { + "id": "1173", + "name": "The Shaikahan" + }, + { + "id": "1174", + "name": "Fishing spot" + }, + { + "id": "1175", + "name": "Fishing spot" + }, + { + "id": "1177", + "name": "Fishing spot" + }, + { + "id": "1178", + "name": "Fishing spot" + }, + { + "id": "1180", + "name": "Cormorant" + }, + { + "id": "1181", + "name": "Pelican" + }, + { + "id": "1182", + "name": "Lord Iorwerth" + }, + { + "id": "1186", + "name": "Idris" + }, + { + "id": "1187", + "name": "Essyllt" + }, + { + "id": "1188", + "name": "Morvran" + }, + { + "id": "1189", + "name": "Fishing spot" + }, + { + "id": "1190", + "name": "Fishing spot" + }, + { + "id": "1191", + "name": "Fishing spot" + }, + { + "id": "1202", + "name": "Arianwyn" + }, + { + "id": "1205", + "name": "Tyras guard" + }, + { + "id": "1207", + "name": "Quartermaster" + }, + { + "id": "1221", + "name": "Spider" + }, + { + "id": "1222", + "name": "Mist" + }, + { + "id": "1224", + "name": "Vampyric hound" + }, + { + "id": "1226", + "name": "Tree" + }, + { + "id": "1236", + "name": "Fishing spot" + }, + { + "id": "1237", + "name": "Fishing spot" + }, + { + "id": "1238", + "name": "Fishing spot" + }, + { + "id": "1242", + "name": "Shade Spirit" + }, + { + "id": "1251", + "name": "Afflicted(Ulsquire)" + }, + { + "id": "1252", + "name": "Ulsquire Shauncy" + }, + { + "id": "1253", + "name": "Afflicted(Razmire)" + }, + { + "id": "1254", + "name": "Razmire Keelgan" + }, + { + "id": "1255", + "name": "Mort'ton Local" + }, + { + "id": "1256", + "name": "Mort'ton Local" + }, + { + "id": "1259", + "name": "Mort'ton local" + }, + { + "id": "1260", + "name": "Mort'ton local" + }, + { + "id": "1280", + "name": "Butterfly" + }, + { + "id": "1284", + "name": "Bjorn" + }, + { + "id": "1285", + "name": "Eldgrim" + }, + { + "id": "1295", + "name": "Askeladden" + }, + { + "id": "1299", + "name": "Town Guard" + }, + { + "id": "1310", + "name": "Freygerd" + }, + { + "id": "1311", + "name": "Lensa" + }, + { + "id": "1312", + "name": "Jennella" + }, + { + "id": "1322", + "name": "Gull" + }, + { + "id": "1323", + "name": "Gull" + }, + { + "id": "1324", + "name": "Gull" + }, + { + "id": "1325", + "name": "Gull" + }, + { + "id": "1331", + "name": "Fishing spot" + }, + { + "id": "1332", + "name": "Fishing spot" + }, + { + "id": "1333", + "name": "Fishing spot" + }, + { + "id": "1334", + "name": "Jossik" + }, + { + "id": "1335", + "name": "Jossik" + }, + { + "id": "1336", + "name": "Larrissa" + }, + { + "id": "1337", + "name": "Larrissa" + }, + { + "id": "1348", + "name": "Dagannoth mother" + }, + { + "id": "1349", + "name": "Dagannoth mother" + }, + { + "id": "1350", + "name": "Dagannoth mother" + }, + { + "id": "1359", + "name": "Queen Sigrid" + }, + { + "id": "1361", + "name": "Arnor" + }, + { + "id": "1362", + "name": "Haming" + }, + { + "id": "1363", + "name": "Moldof" + }, + { + "id": "1364", + "name": "Helga" + }, + { + "id": "1365", + "name": "Matilda" + }, + { + "id": "1366", + "name": "Ashild" + }, + { + "id": "1371", + "name": "Prince Brand" + }, + { + "id": "1372", + "name": "Princess Astrid" + }, + { + "id": "1373", + "name": "King Vargas" + }, + { + "id": "1375", + "name": "Advisor Ghrim" + }, + { + "id": "1383", + "name": "Halla" + }, + { + "id": "1384", + "name": "Yrsa" + }, + { + "id": "1387", + "name": "Thora" + }, + { + "id": "1399", + "name": "Fishing spot" + }, + { + "id": "1400", + "name": "Gull" + }, + { + "id": "1405", + "name": "Fishing spot" + }, + { + "id": "1406", + "name": "Fishing spot" + }, + { + "id": "1407", + "name": "Daero" + }, + { + "id": "1408", + "name": "Waydar" + }, + { + "id": "1409", + "name": "Waydar" + }, + { + "id": "1410", + "name": "Waydar" + }, + { + "id": "1411", + "name": "Garkor" + }, + { + "id": "1412", + "name": "Garkor" + }, + { + "id": "1413", + "name": "Lumo" + }, + { + "id": "1414", + "name": "Lumo" + }, + { + "id": "1415", + "name": "Bunkdo" + }, + { + "id": "1416", + "name": "Bunkdo" + }, + { + "id": "1417", + "name": "Carado" + }, + { + "id": "1418", + "name": "Carado" + }, + { + "id": "1420", + "name": "Karam" + }, + { + "id": "1421", + "name": "Karam" + }, + { + "id": "1422", + "name": "Karam" + }, + { + "id": "1423", + "name": "Bunkwicket" + }, + { + "id": "1424", + "name": "Waymottin" + }, + { + "id": "1425", + "name": "Zooknock" + }, + { + "id": "1426", + "name": "Zooknock" + }, + { + "id": "1428", + "name": "G.L.O. Caranock" + }, + { + "id": "1429", + "name": "Dugopul" + }, + { + "id": "1430", + "name": "Salenab" + }, + { + "id": "1431", + "name": "Trefaji" + }, + { + "id": "1432", + "name": "Aberab" + }, + { + "id": "1433", + "name": "Solihib" + }, + { + "id": "1434", + "name": "Daga" + }, + { + "id": "1435", + "name": "Tutab" + }, + { + "id": "1436", + "name": "Ifaba" + }, + { + "id": "1437", + "name": "Hamab" + }, + { + "id": "1438", + "name": "Hafuba" + }, + { + "id": "1439", + "name": "Denadu" + }, + { + "id": "1440", + "name": "Lofu" + }, + { + "id": "1441", + "name": "Kruk" + }, + { + "id": "1448", + "name": "Awowogei" + }, + { + "id": "1449", + "name": "Uwogo" + }, + { + "id": "1450", + "name": "Muruwoi" + }, + { + "id": "1462", + "name": "Elder Guard" + }, + { + "id": "1468", + "name": "Bonzara" + }, + { + "id": "1470", + "name": "Foreman" + }, + { + "id": "1474", + "name": "Spider" + }, + { + "id": "1482", + "name": "Gorilla" + }, + { + "id": "1488", + "name": "Dummy" + }, + { + "id": "1489", + "name": "Dummy" + }, + { + "id": "1490", + "name": "Dummy" + }, + { + "id": "1491", + "name": "Dummy" + }, + { + "id": "1492", + "name": "Dummy" + }, + { + "id": "1493", + "name": "Dummy" + }, + { + "id": "1494", + "name": "Dummy" + }, + { + "id": "1495", + "name": "Dummy" + }, + { + "id": "1496", + "name": "Dummy" + }, + { + "id": "1497", + "name": "Dummy" + }, + { + "id": "1498", + "name": "Dummy" + }, + { + "id": "1499", + "name": "Dummy" + }, + { + "id": "1500", + "name": "Dummy" + }, + { + "id": "1501", + "name": "Dummy" + }, + { + "id": "1502", + "name": "Dummy" + }, + { + "id": "1503", + "name": "Dummy" + }, + { + "id": "1504", + "name": "Dummy" + }, + { + "id": "1505", + "name": "Dummy" + }, + { + "id": "1506", + "name": "Dummy" + }, + { + "id": "1507", + "name": "Dummy" + }, + { + "id": "1508", + "name": "Forester" + }, + { + "id": "1509", + "name": "Woman-at-arms" + }, + { + "id": "1510", + "name": "Apprentice" + }, + { + "id": "1511", + "name": "Ranger" + }, + { + "id": "1512", + "name": "Adventurer" + }, + { + "id": "1513", + "name": "Mage" + }, + { + "id": "1515", + "name": "Nail beast" + }, + { + "id": "1522", + "name": "Nail beast" + }, + { + "id": "1523", + "name": "Nail beast" + }, + { + "id": "1525", + "name": "Undead Lumberjack" + }, + { + "id": "1526", + "name": "Lanthus" + }, + { + "id": "1527", + "name": "Mine cart" + }, + { + "id": "1529", + "name": "Sheep" + }, + { + "id": "1530", + "name": "Rabbit" + }, + { + "id": "1542", + "name": "Loading crane" + }, + { + "id": "1543", + "name": "Innocent-looking key" + }, + { + "id": "1544", + "name": "Mine cart" + }, + { + "id": "1545", + "name": "Mine cart" + }, + { + "id": "1546", + "name": "Mine cart" + }, + { + "id": "1547", + "name": "Mine cart" + }, + { + "id": "1548", + "name": "Mine cart" + }, + { + "id": "1552", + "name": "Santa" + }, + { + "id": "1554", + "name": "Aga" + }, + { + "id": "1555", + "name": "Arrg" + }, + { + "id": "1559", + "name": "Ice wolf" + }, + { + "id": "1568", + "name": "Curpile Fyod" + }, + { + "id": "1569", + "name": "Veliaf Hurtz" + }, + { + "id": "1570", + "name": "Sani Piliu" + }, + { + "id": "1571", + "name": "Harold Evans" + }, + { + "id": "1572", + "name": "Radigad Ponfit" + }, + { + "id": "1573", + "name": "Polmafi Ferdygris" + }, + { + "id": "1574", + "name": "Ivan Strom" + }, + { + "id": "1575", + "name": "Skeleton Hellhound" + }, + { + "id": "1576", + "name": "Stranger" + }, + { + "id": "1577", + "name": "Vanstrom Klause" + }, + { + "id": "1578", + "name": "Mist" + }, + { + "id": "1579", + "name": "Vanstrom Klause" + }, + { + "id": "1580", + "name": "Vanstrom Klause" + }, + { + "id": "1581", + "name": "Vanstrom Klause" + }, + { + "id": "1595", + "name": "Saniboch" + }, + { + "id": "1596", + "name": "Vannaka" + }, + { + "id": "1599", + "name": "Cave crawler" + }, + { + "id": "1659", + "name": "Skullball" + }, + { + "id": "1664", + "name": "Agility Trainer" + }, + { + "id": "1666", + "name": "Dr Fenkenstrain" + }, + { + "id": "1671", + "name": "Fenkenstrain's Monster" + }, + { + "id": "1674", + "name": "Lord Rologarth" + }, + { + "id": "1679", + "name": "Eluned" + }, + { + "id": "1680", + "name": "Islwyn" + }, + { + "id": "1682", + "name": "Golrie" + }, + { + "id": "1683", + "name": "Velorina" + }, + { + "id": "1685", + "name": "Gravingas" + }, + { + "id": "1687", + "name": "Ak-Haranu" + }, + { + "id": "1689", + "name": "Undead cow" + }, + { + "id": "1694", + "name": "Robin" + }, + { + "id": "1709", + "name": "Johanhus Ulsbrecht" + }, + { + "id": "1719", + "name": "Tree" + }, + { + "id": "1720", + "name": "Tree" + }, + { + "id": "1721", + "name": "Tree" + }, + { + "id": "1722", + "name": "Dead tree" + }, + { + "id": "1723", + "name": "Dead tree" + }, + { + "id": "1724", + "name": "Dead tree" + }, + { + "id": "1725", + "name": "Dead tree" + }, + { + "id": "1726", + "name": "Dead tree" + }, + { + "id": "1727", + "name": "Dead tree" + }, + { + "id": "1728", + "name": "Dead tree" + }, + { + "id": "1729", + "name": "Dead tree" + }, + { + "id": "1730", + "name": "Dead tree" + }, + { + "id": "1731", + "name": "Dead tree" + }, + { + "id": "1732", + "name": "Dramen tree" + }, + { + "id": "1734", + "name": "Magic tree" + }, + { + "id": "1735", + "name": "Maple tree" + }, + { + "id": "1736", + "name": "Willow" + }, + { + "id": "1737", + "name": "Willow" + }, + { + "id": "1738", + "name": "Willow" + }, + { + "id": "1749", + "name": "Hollow tree" + }, + { + "id": "1750", + "name": "Hollow tree" + }, + { + "id": "1753", + "name": "Mounted terrorbird gnome" + }, + { + "id": "1756", + "name": "Crow" + }, + { + "id": "1762", + "name": "Sheep" + }, + { + "id": "1764", + "name": "Sheep" + }, + { + "id": "1765", + "name": "Sheep" + }, + { + "id": "1777", + "name": "Ilfeen" + }, + { + "id": "1778", + "name": "William" + }, + { + "id": "1779", + "name": "Ian" + }, + { + "id": "1780", + "name": "Larry" + }, + { + "id": "1781", + "name": "Darren" + }, + { + "id": "1782", + "name": "Edward" + }, + { + "id": "1784", + "name": "Neil" + }, + { + "id": "1786", + "name": "Simon" + }, + { + "id": "1787", + "name": "Sam" + }, + { + "id": "1788", + "name": "Lumdo" + }, + { + "id": "1789", + "name": "Bunkwicket" + }, + { + "id": "1790", + "name": "Waymottin" + }, + { + "id": "1791", + "name": "Jungle Tree" + }, + { + "id": "1792", + "name": "Jungle Tree" + }, + { + "id": "1793", + "name": "Tassie Slipcast" + }, + { + "id": "1798", + "name": "Phantuwti Fanstuwi Farsight" + }, + { + "id": "1799", + "name": "Tindel Marchant" + }, + { + "id": "1800", + "name": "Gnormadium Avlafrim" + }, + { + "id": "1801", + "name": "Petra Fiyed" + }, + { + "id": "1804", + "name": "Slagilith" + }, + { + "id": "1808", + "name": "Ragnar" + }, + { + "id": "1809", + "name": "Svidi" + }, + { + "id": "1810", + "name": "Jokul" + }, + { + "id": "1811", + "name": "The Kendal" + }, + { + "id": "1821", + "name": "Bald Headed Eagle" + }, + { + "id": "1826", + "name": "Zombie" + }, + { + "id": "1830", + "name": "Frog" + }, + { + "id": "1835", + "name": "Easter Bunny" + }, + { + "id": "1836", + "name": "Dondakan the Dwarf" + }, + { + "id": "1838", + "name": "Dondakan the Dwarf" + }, + { + "id": "1839", + "name": "Dondakan the Dwarf" + }, + { + "id": "1841", + "name": "Rolad" + }, + { + "id": "1845", + "name": "Dwarven Boatman" + }, + { + "id": "1847", + "name": "Miodvetnir" + }, + { + "id": "1848", + "name": "Dernu" + }, + { + "id": "1849", + "name": "Derni" + }, + { + "id": "1860", + "name": "Brian" + }, + { + "id": "1862", + "name": "Ali Morrisane" + }, + { + "id": "1869", + "name": "Ali the Mayor" + }, + { + "id": "1876", + "name": "Bandit Leader" + }, + { + "id": "1879", + "name": "Bandit" + }, + { + "id": "1881", + "name": "Bandit" + }, + { + "id": "1882", + "name": "Sir Palomedes" + }, + { + "id": "1883", + "name": "Sir Palomedes" + }, + { + "id": "1884", + "name": "Trobert" + }, + { + "id": "1887", + "name": "Villager" + }, + { + "id": "1889", + "name": "Villager" + }, + { + "id": "1890", + "name": "Villager" + }, + { + "id": "1891", + "name": "Villager" + }, + { + "id": "1893", + "name": "Villager" + }, + { + "id": "1894", + "name": "Villager" + }, + { + "id": "1895", + "name": "Villager" + }, + { + "id": "1897", + "name": "Villager" + }, + { + "id": "1898", + "name": "Villager" + }, + { + "id": "1899", + "name": "Menaphite Leader" + }, + { + "id": "1903", + "name": "Menaphite Thug" + }, + { + "id": "1907", + "name": "Broken clay golem" + }, + { + "id": "1909", + "name": "Damaged clay golem" + }, + { + "id": "1910", + "name": "Clay golem" + }, + { + "id": "1912", + "name": "Elissa" + }, + { + "id": "1922", + "name": "Eblis" + }, + { + "id": "1924", + "name": "Eblis" + }, + { + "id": "1927", + "name": "Bandit" + }, + { + "id": "1928", + "name": "Bandit" + }, + { + "id": "1929", + "name": "Bandit" + }, + { + "id": "1930", + "name": "Bandit" + }, + { + "id": "1932", + "name": "Troll child" + }, + { + "id": "1934", + "name": "Troll child" + }, + { + "id": "1943", + "name": "Ice block" + }, + { + "id": "1945", + "name": "Ice block" + }, + { + "id": "1957", + "name": "Mummy" + }, + { + "id": "1959", + "name": "Mummy" + }, + { + "id": "1960", + "name": "Mummy ashes" + }, + { + "id": "1966", + "name": "Mummy" + }, + { + "id": "1968", + "name": "Mummy" + }, + { + "id": "1970", + "name": "Azzanadra" + }, + { + "id": "1982", + "name": "Raetul" + }, + { + "id": "1983", + "name": "Siamun" + }, + { + "id": "1984", + "name": "High Priest" + }, + { + "id": "1987", + "name": "Priest" + }, + { + "id": "1989", + "name": "Priest" + }, + { + "id": "1990", + "name": "Sphinx" + }, + { + "id": "1992", + "name": "Neite" + }, + { + "id": "1996", + "name": "Vulture" + }, + { + "id": "2000", + "name": "Plague cow" + }, + { + "id": "2002", + "name": "Wanderer" + }, + { + "id": "2006", + "name": "Wanderer" + }, + { + "id": "2007", + "name": "Het" + }, + { + "id": "2008", + "name": "Apmeken" + }, + { + "id": "2009", + "name": "Scabaras" + }, + { + "id": "2010", + "name": "Crondis" + }, + { + "id": "2011", + "name": "Icthlarin" + }, + { + "id": "2013", + "name": "Klenter" + }, + { + "id": "2020", + "name": "Light creature" + }, + { + "id": "2022", + "name": "Light creature" + }, + { + "id": "2023", + "name": "Juna" + }, + { + "id": "2038", + "name": "Grish" + }, + { + "id": "2039", + "name": "Uglug Nar" + }, + { + "id": "2040", + "name": "Pilg" + }, + { + "id": "2041", + "name": "Grug" + }, + { + "id": "2042", + "name": "Ogre guard" + }, + { + "id": "2043", + "name": "Ogre guard" + }, + { + "id": "2059", + "name": "Zavistic Rarve" + }, + { + "id": "2061", + "name": "Sithik Ints" + }, + { + "id": "2062", + "name": "Sithik Ints" + }, + { + "id": "2063", + "name": "Gargh" + }, + { + "id": "2064", + "name": "Scarg" + }, + { + "id": "2065", + "name": "Gruh" + }, + { + "id": "2066", + "name": "Irwin Feaselbaum" + }, + { + "id": "2068", + "name": "Fishing spot" + }, + { + "id": "2079", + "name": "Sigmund" + }, + { + "id": "2083", + "name": "Sigmund" + }, + { + "id": "2084", + "name": "Mistag" + }, + { + "id": "2085", + "name": "Kazgar" + }, + { + "id": "2087", + "name": "Ur-tag" + }, + { + "id": "2088", + "name": "Duke Horacio" + }, + { + "id": "2089", + "name": "Mistag" + }, + { + "id": "2090", + "name": "Sigmund" + }, + { + "id": "2099", + "name": "Red Axe Secretary" + }, + { + "id": "2107", + "name": "Red Axe Director" + }, + { + "id": "2108", + "name": "Red Axe Cat" + }, + { + "id": "2123", + "name": "Trader" + }, + { + "id": "2125", + "name": "Trader" + }, + { + "id": "2128", + "name": "Supreme Commander" + }, + { + "id": "2129", + "name": "Commander Veldaban" + }, + { + "id": "2137", + "name": "Gnome emissary" + }, + { + "id": "2142", + "name": "Riki the sculptor's model" + }, + { + "id": "2144", + "name": "Riki the sculptor's model" + }, + { + "id": "2145", + "name": "Riki the sculptor's model" + }, + { + "id": "2146", + "name": "Riki the sculptor's model" + }, + { + "id": "2147", + "name": "Riki the sculptor's model" + }, + { + "id": "2148", + "name": "Riki the sculptor's model" + }, + { + "id": "2149", + "name": "Riki the sculptor's model" + }, + { + "id": "2150", + "name": "Riki the sculptor's model" + }, + { + "id": "2151", + "name": "Vigr" + }, + { + "id": "2152", + "name": "Santiri" + }, + { + "id": "2153", + "name": "Saro" + }, + { + "id": "2155", + "name": "Wemund" + }, + { + "id": "2156", + "name": "Randivor" + }, + { + "id": "2157", + "name": "Hervi" + }, + { + "id": "2159", + "name": "Gulldamar" + }, + { + "id": "2161", + "name": "Agmundi" + }, + { + "id": "2162", + "name": "Vermundi" + }, + { + "id": "2166", + "name": "Assistant" + }, + { + "id": "2169", + "name": "Dromund" + }, + { + "id": "2176", + "name": "Inn Keeper" + }, + { + "id": "2179", + "name": "Barman" + }, + { + "id": "2188", + "name": "Hegir" + }, + { + "id": "2189", + "name": "Haera" + }, + { + "id": "2194", + "name": "Reinald" + }, + { + "id": "2196", + "name": "Gauss" + }, + { + "id": "2197", + "name": "Myndill" + }, + { + "id": "2199", + "name": "Tombar" + }, + { + "id": "2200", + "name": "Odmar" + }, + { + "id": "2204", + "name": "Drunken Dwarf" + }, + { + "id": "2208", + "name": "Dwarven Miner" + }, + { + "id": "2209", + "name": "Dwarven Miner" + }, + { + "id": "2210", + "name": "Dwarven Miner" + }, + { + "id": "2211", + "name": "Dwarven Miner" + }, + { + "id": "2212", + "name": "Dwarven Miner" + }, + { + "id": "2213", + "name": "Dwarven Miner" + }, + { + "id": "2214", + "name": "Dwarven Miner" + }, + { + "id": "2215", + "name": "Dwarven Miner" + }, + { + "id": "2216", + "name": "Dwarven Miner" + }, + { + "id": "2217", + "name": "Dwarven Miner" + }, + { + "id": "2218", + "name": "Dwarven Miner" + }, + { + "id": "2219", + "name": "Purple Pewter Director" + }, + { + "id": "2220", + "name": "Purple Pewter Director" + }, + { + "id": "2221", + "name": "Blue Opal Director" + }, + { + "id": "2222", + "name": "Yellow Fortune Director" + }, + { + "id": "2223", + "name": "Green Gemstone Director" + }, + { + "id": "2224", + "name": "White Chisel Director" + }, + { + "id": "2225", + "name": "Silver Cog Director" + }, + { + "id": "2226", + "name": "Brown Engine Director" + }, + { + "id": "2227", + "name": "Red Axe Director" + }, + { + "id": "2228", + "name": "Commander Veldaban" + }, + { + "id": "2229", + "name": "Red Axe Cat" + }, + { + "id": "2230", + "name": "Red Axe Cat" + }, + { + "id": "2231", + "name": "Black Guard Berserker" + }, + { + "id": "2233", + "name": "Olivia" + }, + { + "id": "2238", + "name": "Donie" + }, + { + "id": "2239", + "name": "Pig" + }, + { + "id": "2251", + "name": "Gnome" + }, + { + "id": "2252", + "name": "Crow" + }, + { + "id": "2254", + "name": "Bed" + }, + { + "id": "2255", + "name": "Thing under the bed" + }, + { + "id": "2257", + "name": "Mage of Zamorak" + }, + { + "id": "2259", + "name": "Mage of Zamorak" + }, + { + "id": "2260", + "name": "Mage of Zamorak" + }, + { + "id": "2266", + "name": "Brian O'Richard" + }, + { + "id": "2268", + "name": "Rogue Guard" + }, + { + "id": "2270", + "name": "Martin Thwait" + }, + { + "id": "2273", + "name": "Spin Blades" + }, + { + "id": "2295", + "name": "Rug Merchant" + }, + { + "id": "2297", + "name": "Rug Merchant" + }, + { + "id": "2299", + "name": "Rug Station Attendant" + }, + { + "id": "2302", + "name": "Sarah" + }, + { + "id": "2305", + "name": "Vanessa" + }, + { + "id": "2306", + "name": "Richard" + }, + { + "id": "2307", + "name": "Alice" + }, + { + "id": "2308", + "name": "Capt' Arnav" + }, + { + "id": "2322", + "name": "Metarialus" + }, + { + "id": "2345", + "name": "Sick-looking sheep (1)" + }, + { + "id": "2346", + "name": "Sick-looking sheep (2)" + }, + { + "id": "2347", + "name": "Sick-looking sheep (3)" + }, + { + "id": "2348", + "name": "Sick-looking sheep (4)" + }, + { + "id": "2349", + "name": "Mourner" + }, + { + "id": "2350", + "name": "Mourner" + }, + { + "id": "2351", + "name": "Mourner" + }, + { + "id": "2352", + "name": "Eudav" + }, + { + "id": "2353", + "name": "Oronwen" + }, + { + "id": "2356", + "name": "Dalldav" + }, + { + "id": "2357", + "name": "Gethin" + }, + { + "id": "2358", + "name": "Arianwyn" + }, + { + "id": "2363", + "name": "Goreu" + }, + { + "id": "2364", + "name": "Ysgawyn" + }, + { + "id": "2365", + "name": "Arvel" + }, + { + "id": "2366", + "name": "Mawrth" + }, + { + "id": "2367", + "name": "Kelyn" + }, + { + "id": "2368", + "name": "Eoin" + }, + { + "id": "2369", + "name": "Iona" + }, + { + "id": "2370", + "name": "Gnome" + }, + { + "id": "2375", + "name": "Eluned" + }, + { + "id": "2377", + "name": "Sick-looking sheep (1)" + }, + { + "id": "2378", + "name": "Sick-looking sheep (2)" + }, + { + "id": "2379", + "name": "Sick-looking sheep (3)" + }, + { + "id": "2380", + "name": "Sick-looking sheep (4)" + }, + { + "id": "2381", + "name": "Mysterious ghost" + }, + { + "id": "2403", + "name": "Cart conductor" + }, + { + "id": "2410", + "name": "Red Axe Director" + }, + { + "id": "2411", + "name": "Red Axe Director" + }, + { + "id": "2412", + "name": "Red Axe Henchman" + }, + { + "id": "2413", + "name": "Red Axe Henchman" + }, + { + "id": "2414", + "name": "Red Axe Henchman" + }, + { + "id": "2415", + "name": "Colonel Grimsson" + }, + { + "id": "2416", + "name": "Colonel Grimsson" + }, + { + "id": "2417", + "name": "Ogre shaman" + }, + { + "id": "2418", + "name": "Ogre shaman" + }, + { + "id": "2419", + "name": "Grunsh" + }, + { + "id": "2420", + "name": "Gnome emissary" + }, + { + "id": "2421", + "name": "Gnome companion" + }, + { + "id": "2422", + "name": "Gnome companion" + }, + { + "id": "2424", + "name": "Gunslik" + }, + { + "id": "2425", + "name": "Nolar" + }, + { + "id": "2426", + "name": "Factory Worker" + }, + { + "id": "2427", + "name": "Cart conductor" + }, + { + "id": "2428", + "name": "Gauss" + }, + { + "id": "2429", + "name": "Drunken Dwarf" + }, + { + "id": "2430", + "name": "Rowdy dwarf" + }, + { + "id": "2431", + "name": "Ulifed" + }, + { + "id": "2432", + "name": "Red Axe Henchman" + }, + { + "id": "2433", + "name": "Red Axe Henchman" + }, + { + "id": "2434", + "name": "Ogre shaman" + }, + { + "id": "2435", + "name": "Jarvald" + }, + { + "id": "2437", + "name": "Jarvald" + }, + { + "id": "2438", + "name": "Jarvald" + }, + { + "id": "2440", + "name": "Door-support" + }, + { + "id": "2441", + "name": "Door" + }, + { + "id": "2442", + "name": "Door" + }, + { + "id": "2444", + "name": "Door" + }, + { + "id": "2445", + "name": "Door" + }, + { + "id": "2446", + "name": "Door-support" + }, + { + "id": "2447", + "name": "Door" + }, + { + "id": "2448", + "name": "Door" + }, + { + "id": "2449", + "name": "Egg" + }, + { + "id": "2450", + "name": "Egg" + }, + { + "id": "2451", + "name": "Egg" + }, + { + "id": "2458", + "name": "Freaky Forester" + }, + { + "id": "2469", + "name": "Frog" + }, + { + "id": "2470", + "name": "Frog" + }, + { + "id": "2471", + "name": "Frog" + }, + { + "id": "2472", + "name": "Frog" + }, + { + "id": "2473", + "name": "Frog" + }, + { + "id": "2474", + "name": "Frog prince" + }, + { + "id": "2475", + "name": "Frog princess" + }, + { + "id": "2478", + "name": "Evil Bob" + }, + { + "id": "2480", + "name": "Servant" + }, + { + "id": "2483", + "name": "Bush snake" + }, + { + "id": "2498", + "name": "Broodoo victim" + }, + { + "id": "2500", + "name": "Broodoo victim" + }, + { + "id": "2502", + "name": "Broodoo victim" + }, + { + "id": "2504", + "name": "Sharimika" + }, + { + "id": "2507", + "name": "Mamma Bufetta" + }, + { + "id": "2510", + "name": "Layleen" + }, + { + "id": "2513", + "name": "Karaday" + }, + { + "id": "2516", + "name": "Safta Doc" + }, + { + "id": "2519", + "name": "Gabooty" + }, + { + "id": "2522", + "name": "Fanellaman" + }, + { + "id": "2525", + "name": "Jagbakoba" + }, + { + "id": "2528", + "name": "Murcaily" + }, + { + "id": "2531", + "name": "Rionasta" + }, + { + "id": "2534", + "name": "Mahogany" + }, + { + "id": "2535", + "name": "Teak" + }, + { + "id": "2536", + "name": "Niles" + }, + { + "id": "2537", + "name": "Miles" + }, + { + "id": "2538", + "name": "Giles" + }, + { + "id": "2540", + "name": "Dr Jekyll" + }, + { + "id": "2541", + "name": "Mr Hyde" + }, + { + "id": "2542", + "name": "Mr Hyde" + }, + { + "id": "2543", + "name": "Mr Hyde" + }, + { + "id": "2544", + "name": "Mr Hyde" + }, + { + "id": "2545", + "name": "Mr Hyde" + }, + { + "id": "2546", + "name": "Mr Hyde" + }, + { + "id": "2548", + "name": "Blackjack seller" + }, + { + "id": "2550", + "name": "Dwarven Miner" + }, + { + "id": "2551", + "name": "Dwarven Miner" + }, + { + "id": "2552", + "name": "Dwarven Miner" + }, + { + "id": "2554", + "name": "Tin ore" + }, + { + "id": "2555", + "name": "Copper ore" + }, + { + "id": "2556", + "name": "Iron ore" + }, + { + "id": "2557", + "name": "Mithril ore" + }, + { + "id": "2558", + "name": "Adamantite ore" + }, + { + "id": "2559", + "name": "Runite ore" + }, + { + "id": "2560", + "name": "Silver ore" + }, + { + "id": "2561", + "name": "Gold ore" + }, + { + "id": "2562", + "name": "Coal" + }, + { + "id": "2563", + "name": "Perfect gold ore" + }, + { + "id": "2566", + "name": "Wise Old Man" + }, + { + "id": "2567", + "name": "Wise Old Man" + }, + { + "id": "2568", + "name": "Banker" + }, + { + "id": "2569", + "name": "Banker" + }, + { + "id": "2570", + "name": "Banker" + }, + { + "id": "2573", + "name": "Pillory Guard" + }, + { + "id": "2575", + "name": "Purepker895" + }, + { + "id": "2576", + "name": "Qutiedoll" + }, + { + "id": "2577", + "name": "1337sp34kr" + }, + { + "id": "2578", + "name": "Elfinlocks" + }, + { + "id": "2579", + "name": "Cool Mom227" + }, + { + "id": "2581", + "name": "Ellamaria" + }, + { + "id": "2582", + "name": "Trolley" + }, + { + "id": "2583", + "name": "Trolley" + }, + { + "id": "2584", + "name": "Trolley" + }, + { + "id": "2585", + "name": "Billy, a guard of Falador" + }, + { + "id": "2587", + "name": "Bob, another guard of Falador" + }, + { + "id": "2589", + "name": "PKMaster0036" + }, + { + "id": "2590", + "name": "King Roald" + }, + { + "id": "2617", + "name": "TzHaar-Mej-Jal" + }, + { + "id": "2618", + "name": "TzHaar-Mej-Kah" + }, + { + "id": "2619", + "name": "TzHaar-Ket-Zuh" + }, + { + "id": "2620", + "name": "TzHaar-Hur-Tel" + }, + { + "id": "2622", + "name": "TzHaar-Hur-Lek" + }, + { + "id": "2623", + "name": "TzHaar-Mej-Roh" + }, + { + "id": "2624", + "name": "TzHaar-Ket" + }, + { + "id": "2625", + "name": "TzHaar-Ket" + }, + { + "id": "2626", + "name": "Rocks" + }, + { + "id": "2632", + "name": "Tok-Xil" + }, + { + "id": "2633", + "name": "Wise Old Man" + }, + { + "id": "2635", + "name": "Bob" + }, + { + "id": "2636", + "name": "Bob" + }, + { + "id": "2637", + "name": "Sphinx" + }, + { + "id": "2638", + "name": "Neite" + }, + { + "id": "2639", + "name": "Robert the Strong" + }, + { + "id": "2640", + "name": "Odysseus" + }, + { + "id": "2642", + "name": "King Black Dragon" + }, + { + "id": "2643", + "name": "R4ng3rNo0b889" + }, + { + "id": "2644", + "name": "Love Cats" + }, + { + "id": "2645", + "name": "Love Cats" + }, + { + "id": "2646", + "name": "Neite" + }, + { + "id": "2647", + "name": "Bob" + }, + { + "id": "2648", + "name": "Beite" + }, + { + "id": "2649", + "name": "Gnome" + }, + { + "id": "2650", + "name": "Gnome" + }, + { + "id": "2651", + "name": "Odysseus" + }, + { + "id": "2652", + "name": "Neite" + }, + { + "id": "2654", + "name": "Unferth" + }, + { + "id": "2656", + "name": "Unferth" + }, + { + "id": "2657", + "name": "Unferth" + }, + { + "id": "2658", + "name": "Unferth" + }, + { + "id": "2659", + "name": "Unferth" + }, + { + "id": "2661", + "name": "Reldo" + }, + { + "id": "2662", + "name": "Lazy cat" + }, + { + "id": "2663", + "name": "Lazy cat" + }, + { + "id": "2664", + "name": "Lazy cat" + }, + { + "id": "2665", + "name": "Lazy cat" + }, + { + "id": "2666", + "name": "Lazy cat" + }, + { + "id": "2667", + "name": "Lazy cat" + }, + { + "id": "2668", + "name": "Wily cat" + }, + { + "id": "2669", + "name": "Wily cat" + }, + { + "id": "2670", + "name": "Wily cat" + }, + { + "id": "2671", + "name": "Wily cat" + }, + { + "id": "2672", + "name": "Wily cat" + }, + { + "id": "2673", + "name": "Wily cat" + }, + { + "id": "2676", + "name": "Make-over Mage" + }, + { + "examine": "So what can one do with a drunken sailor?", + "id": "2692", + "name": "Ahab" + }, + { + "id": "2708", + "name": "Seagull" + }, + { + "id": "2719", + "name": "Grum" + }, + { + "id": "2720", + "name": "Gerrant" + }, + { + "id": "2721", + "name": "Wydin" + }, + { + "id": "2722", + "name": "Fishing spot" + }, + { + "id": "2723", + "name": "Fishing spot" + }, + { + "id": "2724", + "name": "Fishing spot" + }, + { + "id": "2727", + "name": "Gull" + }, + { + "id": "2730", + "name": "Monk of Entrana" + }, + { + "id": "2747", + "name": "Solus Dellagar" + }, + { + "id": "2748", + "name": "Savant" + }, + { + "id": "2749", + "name": "Lord Daquarius" + }, + { + "id": "2750", + "name": "Solus Dellagar" + }, + { + "id": "2751", + "name": "Black Knight" + }, + { + "id": "2752", + "name": "Lord Daquarius" + }, + { + "id": "2753", + "name": "Mage of Zamorak" + }, + { + "id": "2754", + "name": "Mage of Zamorak" + }, + { + "id": "2755", + "name": "Mage of Zamorak" + }, + { + "id": "2756", + "name": "Woman" + }, + { + "id": "2777", + "name": "Black Knight" + }, + { + "id": "2778", + "name": "Black Knight" + }, + { + "id": "2780", + "name": "Solus Dellagar" + }, + { + "id": "2781", + "name": "Gnome guard" + }, + { + "id": "2788", + "name": "Thorgel" + }, + { + "id": "2791", + "name": "Pillory Guard" + }, + { + "id": "2793", + "name": "Tramp" + }, + { + "id": "2794", + "name": "Tramp" + }, + { + "id": "2795", + "name": "Skippy" + }, + { + "id": "2797", + "name": "Skippy" + }, + { + "id": "2798", + "name": "Skippy" + }, + { + "id": "2799", + "name": "Skippy" + }, + { + "id": "2800", + "name": "A pile of broken glass" + }, + { + "id": "2813", + "name": "Alice the Camel" + }, + { + "id": "2816", + "name": "Ali the Smith" + }, + { + "id": "2821", + "name": "Ali the Farmer" + }, + { + "id": "2822", + "name": "Ali the Tailor" + }, + { + "id": "2823", + "name": "Ali the Guard" + }, + { + "id": "2829", + "name": "Davey" + }, + { + "id": "2859", + "name": "Fishing spot" + }, + { + "id": "2862", + "name": "Death" + }, + { + "id": "2864", + "name": "Most of a Zombie" + }, + { + "id": "2865", + "name": "Most of a Zombie" + }, + { + "id": "2867", + "name": "Most of a Zombie" + }, + { + "id": "2868", + "name": "Zombie Head" + }, + { + "id": "2870", + "name": "Half-Zombie" + }, + { + "id": "2871", + "name": "Other Half-Zombie" + }, + { + "id": "2872", + "name": "Child" + }, + { + "id": "2873", + "name": "Child" + }, + { + "id": "2874", + "name": "Child" + }, + { + "id": "2875", + "name": "Child" + }, + { + "id": "2876", + "name": "Child" + }, + { + "id": "2877", + "name": "Child" + }, + { + "id": "2879", + "name": "Bardur" + }, + { + "id": "2884", + "name": "Wallasalki" + }, + { + "id": "2891", + "name": "Suspicious water" + }, + { + "id": "2893", + "name": "Suspicious water" + }, + { + "id": "2895", + "name": "Suspicious water" + }, + { + "id": "2897", + "name": "Father Reen" + }, + { + "id": "2900", + "name": "Father Reen" + }, + { + "id": "2901", + "name": "Father Badden" + }, + { + "id": "2903", + "name": "Father Badden" + }, + { + "id": "2904", + "name": "Denath" + }, + { + "id": "2905", + "name": "Denath" + }, + { + "id": "2906", + "name": "Eric" + }, + { + "id": "2907", + "name": "Eric" + }, + { + "id": "2908", + "name": "Evil Dave" + }, + { + "id": "2910", + "name": "Evil Dave" + }, + { + "id": "2911", + "name": "Matthew" + }, + { + "id": "2912", + "name": "Matthew" + }, + { + "id": "2913", + "name": "Jennifer" + }, + { + "id": "2914", + "name": "Jennifer" + }, + { + "id": "2915", + "name": "Tanya" + }, + { + "id": "2916", + "name": "Tanya" + }, + { + "id": "2917", + "name": "Patrick" + }, + { + "id": "2918", + "name": "Patrick" + }, + { + "id": "2920", + "name": "Sand storm" + }, + { + "id": "2922", + "name": "Clay golem" + }, + { + "id": "2928", + "name": "Clay golem" + }, + { + "id": "2929", + "name": "Ghost" + }, + { + "id": "2932", + "name": "Jorral" + }, + { + "id": "2933", + "name": "Melina" + }, + { + "id": "2935", + "name": "Melina" + }, + { + "id": "2936", + "name": "Droalak" + }, + { + "id": "2938", + "name": "Droalak" + }, + { + "id": "2939", + "name": "Dron" + }, + { + "id": "2940", + "name": "Blanin" + }, + { + "id": "2943", + "name": "Pox" + }, + { + "id": "2944", + "name": "Pox" + }, + { + "examine": "Cracking personality.", + "id": "2946", + "name": "Grimesquit" + }, + { + "examine": "Lovely girl, shame about the smell.", + "id": "2947", + "name": "Phingspet" + }, + { + "id": "2951", + "name": "Felkrash" + }, + { + "id": "2953", + "name": "Ceril Carnillean" + }, + { + "id": "2954", + "name": "Councillor Halgrive" + }, + { + "id": "2955", + "name": "Spice seller" + }, + { + "id": "2956", + "name": "Fur trader" + }, + { + "id": "2957", + "name": "Gem merchant" + }, + { + "id": "2959", + "name": "Silk merchant" + }, + { + "id": "2960", + "name": "Zenesha" + }, + { + "id": "2961", + "name": "Ali Morrisane" + }, + { + "id": "2974", + "name": "Rat" + }, + { + "id": "2983", + "name": "Turbogroomer" + }, + { + "id": "2985", + "name": "Loki" + }, + { + "id": "2987", + "name": "Treacle" + }, + { + "id": "2989", + "name": "Claude" + }, + { + "id": "2991", + "name": "Rauborn" + }, + { + "id": "2992", + "name": "Vaeringk" + }, + { + "id": "2993", + "name": "Oxi" + }, + { + "id": "2994", + "name": "Fior" + }, + { + "id": "2995", + "name": "Sagira" + }, + { + "id": "2996", + "name": "Anleif" + }, + { + "id": "2999", + "name": "Gambler" + }, + { + "id": "3000", + "name": "Barman" + }, + { + "id": "3019", + "name": "Fishing spot" + }, + { + "id": "3020", + "name": "Rug Merchant" + }, + { + "id": "3023", + "name": "Nirrie" + }, + { + "id": "3024", + "name": "Tirrie" + }, + { + "id": "3025", + "name": "Hallak" + }, + { + "id": "3031", + "name": "Usi" + }, + { + "id": "3032", + "name": "Nkuku" + }, + { + "id": "3033", + "name": "Garai" + }, + { + "id": "3034", + "name": "Habibah" + }, + { + "id": "3035", + "name": "Meskhenet" + }, + { + "id": "3036", + "name": "Zahra" + }, + { + "id": "3037", + "name": "Zahur" + }, + { + "id": "3038", + "name": "Seddu" + }, + { + "id": "3039", + "name": "Kazemde" + }, + { + "id": "3041", + "name": "Tarik" + }, + { + "id": "3045", + "name": "Rokuh" + }, + { + "id": "3047", + "name": "Target" + }, + { + "id": "3048", + "name": "Target" + }, + { + "id": "3049", + "name": "Larxus" + }, + { + "id": "3076", + "name": "Dead Monk" + }, + { + "id": "3078", + "name": "High Priest" + }, + { + "id": "3081", + "name": "Assassin" + }, + { + "id": "3082", + "name": "Rosie" + }, + { + "id": "3083", + "name": "Sorcha" + }, + { + "id": "3084", + "name": "Cait" + }, + { + "id": "3085", + "name": "Cormac" + }, + { + "id": "3086", + "name": "Fionn" + }, + { + "id": "3087", + "name": "Donnacha" + }, + { + "id": "3088", + "name": "Ronan" + }, + { + "id": "3093", + "name": "Flying Book" + }, + { + "id": "3095", + "name": "Flying Book" + }, + { + "id": "3096", + "name": "Pizzaz Hat" + }, + { + "id": "3107", + "name": "Charmed Warrior" + }, + { + "id": "3108", + "name": "Bert" + }, + { + "id": "3110", + "name": "Sandy" + }, + { + "id": "3113", + "name": "Sandy" + }, + { + "id": "3114", + "name": "Mazion" + }, + { + "id": "3116", + "name": "Reeso" + }, + { + "id": "3118", + "name": "Prison Pete" + }, + { + "id": "3119", + "name": "Balloon Animal" + }, + { + "id": "3120", + "name": "Balloon Animal" + }, + { + "id": "3124", + "name": "Pyramid block" + }, + { + "id": "3125", + "name": "Pyramid block" + }, + { + "id": "3126", + "name": "Pentyn" + }, + { + "id": "3127", + "name": "Aristarchus" + }, + { + "id": "3128", + "name": "Boneguard" + }, + { + "id": "3130", + "name": "Pile of bones" + }, + { + "id": "3131", + "name": "Desert Spirit" + }, + { + "id": "3132", + "name": "Crust of ice" + }, + { + "id": "3134", + "name": "Furnace grate" + }, + { + "id": "3136", + "name": "Enakhra" + }, + { + "id": "3138", + "name": "Enakhra" + }, + { + "id": "3139", + "name": "Boneguard" + }, + { + "id": "3141", + "name": "Akthanakos" + }, + { + "id": "3142", + "name": "Akthanakos" + }, + { + "id": "3143", + "name": "Lazim" + }, + { + "id": "3148", + "name": "Enakhra" + }, + { + "id": "3149", + "name": "Akthanakos" + }, + { + "id": "3152", + "name": "Harpie Bug Swarm" + }, + { + "id": "3154", + "name": "Count Draynor" + }, + { + "id": "3156", + "name": "Bill Teach" + }, + { + "id": "3157", + "name": "Bill Teach" + }, + { + "id": "3158", + "name": "Bill Teach" + }, + { + "id": "3159", + "name": "Bill Teach" + }, + { + "id": "3160", + "name": "Bill Teach" + }, + { + "id": "3161", + "name": "Charley" + }, + { + "id": "3162", + "name": "Smith" + }, + { + "id": "3163", + "name": "Joe" + }, + { + "id": "3164", + "name": "Mama" + }, + { + "id": "3165", + "name": "Mama" + }, + { + "id": "3197", + "name": "Gull" + }, + { + "id": "3205", + "name": "Romily Weaklax" + }, + { + "id": "3206", + "name": "Priest" + }, + { + "id": "3207", + "name": "Pious Pete" + }, + { + "id": "3208", + "name": "Taper" + }, + { + "id": "3210", + "name": "Alrena" + }, + { + "id": "3211", + "name": "Alrena" + }, + { + "id": "3212", + "name": "Bravek" + }, + { + "id": "3218", + "name": "Tina" + }, + { + "id": "3254", + "name": "Hunding" + }, + { + "id": "3281", + "name": "Engineering assistant" + }, + { + "id": "3284", + "name": "Squirrel" + }, + { + "id": "3285", + "name": "Squirrel" + }, + { + "id": "3287", + "name": "Raccoon" + }, + { + "id": "3289", + "name": "Skeleton" + }, + { + "id": "3292", + "name": "Witch" + }, + { + "id": "3300", + "name": "Frog" + }, + { + "id": "3301", + "name": "Storm cloud" + }, + { + "id": "3303", + "name": "Fairy Nuff" + }, + { + "id": "3305", + "name": "Slim Louie" + }, + { + "id": "3306", + "name": "Fat Rocco" + }, + { + "id": "3308", + "name": "Zandar Horfyre" + }, + { + "id": "3311", + "name": "Sheep" + }, + { + "id": "3312", + "name": "Zanaris choir" + }, + { + "id": "3314", + "name": "Baby tanglefoot" + }, + { + "id": "3321", + "name": "Gatekeeper" + }, + { + "id": "3323", + "name": "Draul Leptoc" + }, + { + "id": "3326", + "name": "Martina Scorsby" + }, + { + "id": "3328", + "name": "Tarquin" + }, + { + "id": "3329", + "name": "Sigurd" + }, + { + "id": "3330", + "name": "Hari" + }, + { + "id": "3332", + "name": "Trees" + }, + { + "id": "3333", + "name": "Trees" + }, + { + "id": "3335", + "name": "Bullrush" + }, + { + "id": "3336", + "name": "Bullrush" + }, + { + "id": "3337", + "name": "Cave scenery" + }, + { + "id": "3338", + "name": "Cave scenery" + }, + { + "id": "3339", + "name": "Cave scenery" + }, + { + "id": "3351", + "name": "Genie" + }, + { + "id": "3352", + "name": "Mysterious Old Man" + }, + { + "id": "3353", + "name": "Swarm" + }, + { + "id": "3354", + "name": "Cap'n Hand" + }, + { + "id": "3355", + "name": "Rick Turpentine" + }, + { + "id": "3356", + "name": "Niles" + }, + { + "id": "3357", + "name": "Miles" + }, + { + "id": "3358", + "name": "Giles" + }, + { + "id": "3359", + "name": "Dr Jekyll" + }, + { + "id": "3360", + "name": "Mr Hyde" + }, + { + "id": "3361", + "name": "Mr Hyde" + }, + { + "id": "3362", + "name": "Mr Hyde" + }, + { + "id": "3363", + "name": "Mr Hyde" + }, + { + "id": "3364", + "name": "Mr Hyde" + }, + { + "id": "3365", + "name": "Mr Hyde" + }, + { + "id": "3372", + "name": "Sir Amik Varze" + }, + { + "id": "3373", + "name": "Sir Amik Varze" + }, + { + "id": "3377", + "name": "K'klik" + }, + { + "id": "3379", + "name": "Evil Dave" + }, + { + "id": "3381", + "name": "Doris" + }, + { + "id": "3383", + "name": "Gypsy" + }, + { + "id": "3386", + "name": "Gypsy" + }, + { + "id": "3387", + "name": "Culinaromancer" + }, + { + "id": "3388", + "name": "Osman" + }, + { + "id": "3395", + "name": "Sir Amik Varze" + }, + { + "id": "3396", + "name": "Awowogei" + }, + { + "id": "3397", + "name": "Awowogei" + }, + { + "id": "3398", + "name": "Skrach Uglogwee" + }, + { + "id": "3399", + "name": "Culinaromancer" + }, + { + "id": "3401", + "name": "An old Dwarf" + }, + { + "id": "3403", + "name": "Rohak" + }, + { + "id": "3417", + "name": "Pirate Pete" + }, + { + "id": "3428", + "name": "Fish" + }, + { + "id": "3429", + "name": "Fish" + }, + { + "id": "3430", + "name": "Fish" + }, + { + "id": "3440", + "name": "Fish" + }, + { + "id": "3441", + "name": "Fish" + }, + { + "id": "3442", + "name": "Fish" + }, + { + "id": "3446", + "name": "Fish" + }, + { + "id": "3447", + "name": "Fish" + }, + { + "id": "3448", + "name": "Fish" + }, + { + "id": "3452", + "name": "? ? ? ?" + }, + { + "id": "3453", + "name": "? ? ? ?" + }, + { + "id": "3454", + "name": "? ? ? ?" + }, + { + "id": "3455", + "name": "? ? ? ?" + }, + { + "id": "3456", + "name": "? ? ? ?" + }, + { + "id": "3457", + "name": "? ? ? ?" + }, + { + "id": "3458", + "name": "? ? ? ?" + }, + { + "id": "3459", + "name": "? ? ? ?" + }, + { + "id": "3460", + "name": "? ? ? ?" + }, + { + "id": "3461", + "name": "? ? ? ?" + }, + { + "id": "3462", + "name": "Skrach Uglogwee" + }, + { + "id": "3464", + "name": "Skrach Uglogwee" + }, + { + "id": "3465", + "name": "Nung" + }, + { + "id": "3466", + "name": "Ogre" + }, + { + "id": "3467", + "name": "Rantz" + }, + { + "id": "3468", + "name": "Rantz" + }, + { + "id": "3469", + "name": "Ogre boat" + }, + { + "id": "3472", + "name": "Ogre boat" + }, + { + "id": "3473", + "name": "Balloon Toad" + }, + { + "id": "3474", + "name": "Balloon Toad" + }, + { + "id": "3475", + "name": "Balloon Toad" + }, + { + "id": "3477", + "name": "Jubbly bird" + }, + { + "id": "3479", + "name": "King Awowogei" + }, + { + "id": "3481", + "name": "Mizaru" + }, + { + "id": "3482", + "name": "Kikazaru" + }, + { + "id": "3483", + "name": "Iwazaru" + }, + { + "id": "3485", + "name": "Culinaromancer" + }, + { + "id": "3486", + "name": "Culinaromancer" + }, + { + "id": "3487", + "name": "Culinaromancer" + }, + { + "id": "3488", + "name": "Culinaromancer" + }, + { + "id": "3489", + "name": "Culinaromancer" + }, + { + "id": "3490", + "name": "Culinaromancer" + }, + { + "id": "3492", + "name": "Culinaromancer" + }, + { + "id": "3503", + "name": "Overgrown hellcat" + }, + { + "id": "3504", + "name": "Hellcat" + }, + { + "id": "3505", + "name": "Hell-kitten" + }, + { + "id": "3506", + "name": "Lazy hellcat" + }, + { + "id": "3507", + "name": "Wily hellcat" + }, + { + "id": "3508", + "name": "Leo" + }, + { + "id": "3510", + "name": "Wiskit" + }, + { + "id": "3512", + "name": "Vampyre Juvinate" + }, + { + "id": "3515", + "name": "Vampyre Juvinate" + }, + { + "id": "3516", + "name": "Gadderanks" + }, + { + "id": "3518", + "name": "Gadderanks" + }, + { + "id": "3519", + "name": "Gadderanks" + }, + { + "id": "3520", + "name": "Vampyre Juvinate" + }, + { + "id": "3528", + "name": "Vampyre Juvinate" + }, + { + "id": "3529", + "name": "Vampyre Juvinate" + }, + { + "id": "3530", + "name": "Mist" + }, + { + "id": "3535", + "name": "Ivan Strom" + }, + { + "id": "3536", + "name": "Ivan Strom" + }, + { + "id": "3537", + "name": "Vampyre Juvinate" + }, + { + "id": "3538", + "name": "Vampyre Juvinate" + }, + { + "id": "3539", + "name": "Veliaf Hurtz" + }, + { + "id": "3540", + "name": "Elisabeta" + }, + { + "id": "3541", + "name": "Aurel" + }, + { + "id": "3542", + "name": "Sorin" + }, + { + "id": "3543", + "name": "Luscion" + }, + { + "id": "3544", + "name": "Sergiu" + }, + { + "id": "3545", + "name": "Radu" + }, + { + "id": "3546", + "name": "Grigore" + }, + { + "id": "3547", + "name": "Ileana" + }, + { + "id": "3548", + "name": "Valeria" + }, + { + "id": "3549", + "name": "Emilia" + }, + { + "id": "3550", + "name": "Florin" + }, + { + "id": "3551", + "name": "Catalina" + }, + { + "id": "3552", + "name": "Ivan" + }, + { + "id": "3553", + "name": "Victor" + }, + { + "id": "3554", + "name": "Helena" + }, + { + "id": "3555", + "name": "Teodor" + }, + { + "id": "3556", + "name": "Marius" + }, + { + "id": "3557", + "name": "Gabriela" + }, + { + "id": "3558", + "name": "Vladimir" + }, + { + "id": "3559", + "name": "Calin" + }, + { + "id": "3560", + "name": "Mihail" + }, + { + "id": "3561", + "name": "Nicoleta" + }, + { + "id": "3562", + "name": "Simona" + }, + { + "id": "3563", + "name": "Vasile" + }, + { + "id": "3564", + "name": "Razvan" + }, + { + "id": "3565", + "name": "Luminata" + }, + { + "id": "3566", + "name": "Cornelius" + }, + { + "id": "3569", + "name": "Cornelius" + }, + { + "id": "3570", + "name": "Benjamin" + }, + { + "id": "3571", + "name": "Liam" + }, + { + "id": "3572", + "name": "Miala" + }, + { + "id": "3573", + "name": "Verak" + }, + { + "id": "3574", + "name": "Fishing spot" + }, + { + "id": "3575", + "name": "Fishing spot" + }, + { + "id": "3576", + "name": "Juvinate" + }, + { + "id": "3578", + "name": "Juvinate" + }, + { + "id": "3580", + "name": "Tentacle" + }, + { + "id": "3584", + "name": "Troll" + }, + { + "id": "3592", + "name": "Tok-Xil" + }, + { + "id": "3594", + "name": "Rocnar" + }, + { + "id": "3595", + "name": "Toy Soldier" + }, + { + "id": "3596", + "name": "Toy Doll" + }, + { + "id": "3597", + "name": "Toy Mouse" + }, + { + "id": "3598", + "name": "Clockwork cat" + }, + { + "id": "3606", + "name": "Ghast" + }, + { + "id": "3607", + "name": "Ghast" + }, + { + "id": "3608", + "name": "Ghast" + }, + { + "id": "3609", + "name": "Ghast" + }, + { + "id": "3610", + "name": "Ghast" + }, + { + "id": "3611", + "name": "Ghast" + }, + { + "id": "3612", + "name": "Giant snail" + }, + { + "id": "3613", + "name": "Giant snail" + }, + { + "id": "3614", + "name": "Giant snail" + }, + { + "id": "3615", + "name": "Riyl shadow" + }, + { + "id": "3616", + "name": "Asyn shadow" + }, + { + "id": "3617", + "name": "Shade" + }, + { + "id": "3621", + "name": "Tentacle" + }, + { + "id": "3623", + "name": "Smiddi Ryak" + }, + { + "id": "3625", + "name": "Rolayne Twickit" + }, + { + "id": "3627", + "name": "Jayene Kliyn" + }, + { + "id": "3629", + "name": "Valantay Eppel" + }, + { + "id": "3631", + "name": "Dalcian Fang" + }, + { + "id": "3633", + "name": "Fyiona Fray" + }, + { + "id": "3635", + "name": "Abidor Crank" + }, + { + "id": "3636", + "name": "Spirit tree" + }, + { + "id": "3637", + "name": "Spirit tree" + }, + { + "id": "3638", + "name": "Launa" + }, + { + "id": "3640", + "name": "Launa" + }, + { + "id": "3641", + "name": "Brana" + }, + { + "id": "3642", + "name": "Mawnis Burowgar" + }, + { + "id": "3643", + "name": "Tolna" + }, + { + "id": "3644", + "name": "Tolna" + }, + { + "id": "3651", + "name": "Confusion beast" + }, + { + "id": "3652", + "name": "Confusion beast" + }, + { + "id": "3653", + "name": "Confusion beast" + }, + { + "id": "3654", + "name": "Confusion beast" + }, + { + "id": "3656", + "name": "Hopeless creature" + }, + { + "id": "3657", + "name": "Hopeless creature" + }, + { + "id": "3658", + "name": "Tolna" + }, + { + "id": "3659", + "name": "Tolna" + }, + { + "id": "3660", + "name": "Tolna" + }, + { + "id": "3668", + "name": "Hopeless beast" + }, + { + "id": "3669", + "name": "Hopeless beast" + }, + { + "id": "3677", + "name": "Sinister Stranger" + }, + { + "id": "3678", + "name": "Sinister Stranger" + }, + { + "id": "3679", + "name": "Vestri" + }, + { + "id": "3681", + "name": "Nigel" + }, + { + "id": "3682", + "name": "Egg" + }, + { + "id": "3683", + "name": "Egg" + }, + { + "id": "3684", + "name": "Egg" + }, + { + "id": "3685", + "name": "Egg" + }, + { + "id": "3686", + "name": "Chocolate kebbit" + }, + { + "id": "3687", + "name": "Chocolate kebbit" + }, + { + "id": "3688", + "name": "Easter Bunny" + }, + { + "id": "3689", + "name": "Egg" + }, + { + "id": "3690", + "name": "Egg" + }, + { + "id": "3691", + "name": "Egg" + }, + { + "id": "3692", + "name": "Egg" + }, + { + "id": "3693", + "name": "Egg" + }, + { + "id": "3694", + "name": "Egg" + }, + { + "id": "3695", + "name": "Volf Olafson" + }, + { + "id": "3696", + "name": "Ingrid Hradson" + }, + { + "id": "3708", + "name": "Boulder" + }, + { + "id": "3710", + "name": "Ulfric" + }, + { + "id": "3712", + "name": "Zanik" + }, + { + "id": "3713", + "name": "Sigmund" + }, + { + "id": "3714", + "name": "Zanik" + }, + { + "id": "3716", + "name": "Sigmund" + }, + { + "id": "3717", + "name": "Sigmund" + }, + { + "id": "3718", + "name": "Sigmund" + }, + { + "id": "3719", + "name": "Sigmund" + }, + { + "id": "3720", + "name": "Sigmund" + }, + { + "id": "3721", + "name": "Zanik" + }, + { + "id": "3722", + "name": "Zanik" + }, + { + "id": "3723", + "name": "General Bentnoze" + }, + { + "id": "3724", + "name": "General Wartface" + }, + { + "id": "3725", + "name": "Grubfoot" + }, + { + "id": "3778", + "name": "Arthur" + }, + { + "id": "3780", + "name": "Squire" + }, + { + "id": "3787", + "name": "Sir Palomedes" + }, + { + "id": "3789", + "name": "Void Knight" + }, + { + "id": "3803", + "name": "Fishing spot" + }, + { + "id": "3817", + "name": "Lieutenant Schepbur" + }, + { + "id": "3820", + "name": "Wise Old Man" + }, + { + "id": "3825", + "name": "Devin Mendelberg" + }, + { + "id": "3826", + "name": "George Laxmeister" + }, + { + "id": "3827", + "name": "Ramara du Croissant" + }, + { + "id": "3828", + "name": "Kathy Corkat" + }, + { + "id": "3831", + "name": "Kathy Corkat" + }, + { + "id": "3832", + "name": "Kalphite Queen" + }, + { + "id": "3837", + "name": "Drunken Dwarf" + }, + { + "id": "3838", + "name": "Wise Old Man" + }, + { + "id": "3839", + "name": "Wise Old Man" + }, + { + "id": "3841", + "name": "Sea troll" + }, + { + "id": "3842", + "name": "Sea troll" + }, + { + "id": "3844", + "name": "Skeleton Mage" + }, + { + "id": "3845", + "name": "Sea troll" + }, + { + "id": "3846", + "name": "Sea Troll General" + }, + { + "id": "3848", + "name": "Fishing spot" + }, + { + "id": "3850", + "name": "Skeleton Mage" + }, + { + "id": "3852", + "name": "Suspect" + }, + { + "id": "3853", + "name": "Suspect" + }, + { + "id": "3854", + "name": "Suspect" + }, + { + "id": "3855", + "name": "Suspect" + }, + { + "id": "3856", + "name": "Suspect" + }, + { + "id": "3857", + "name": "Suspect" + }, + { + "id": "3858", + "name": "Suspect" + }, + { + "id": "3859", + "name": "Suspect" + }, + { + "id": "3860", + "name": "Suspect" + }, + { + "id": "3861", + "name": "Suspect" + }, + { + "id": "3862", + "name": "Suspect" + }, + { + "id": "3863", + "name": "Suspect" + }, + { + "id": "3864", + "name": "Suspect" + }, + { + "id": "3865", + "name": "Suspect" + }, + { + "id": "3866", + "name": "Suspect" + }, + { + "id": "3867", + "name": "Suspect" + }, + { + "id": "3868", + "name": "Suspect" + }, + { + "id": "3869", + "name": "Suspect" + }, + { + "id": "3870", + "name": "Suspect" + }, + { + "id": "3871", + "name": "Suspect" + }, + { + "id": "3872", + "name": "Suspect" + }, + { + "id": "3873", + "name": "Suspect" + }, + { + "id": "3874", + "name": "Suspect" + }, + { + "id": "3875", + "name": "Suspect" + }, + { + "id": "3876", + "name": "Suspect" + }, + { + "id": "3877", + "name": "Suspect" + }, + { + "id": "3878", + "name": "Suspect" + }, + { + "id": "3879", + "name": "Suspect" + }, + { + "id": "3880", + "name": "Suspect" + }, + { + "id": "3881", + "name": "Suspect" + }, + { + "id": "3882", + "name": "Suspect" + }, + { + "id": "3883", + "name": "Suspect" + }, + { + "id": "3884", + "name": "Suspect" + }, + { + "id": "3885", + "name": "Suspect" + }, + { + "id": "3886", + "name": "Suspect" + }, + { + "id": "3887", + "name": "Suspect" + }, + { + "id": "3888", + "name": "Suspect" + }, + { + "id": "3889", + "name": "Suspect" + }, + { + "id": "3890", + "name": "Suspect" + }, + { + "id": "3891", + "name": "Suspect" + }, + { + "id": "3892", + "name": "Molly" + }, + { + "id": "3893", + "name": "Molly" + }, + { + "id": "3894", + "name": "Molly" + }, + { + "id": "3895", + "name": "Molly" + }, + { + "id": "3896", + "name": "Molly" + }, + { + "id": "3897", + "name": "Molly" + }, + { + "id": "3898", + "name": "Molly" + }, + { + "id": "3899", + "name": "Molly" + }, + { + "id": "3900", + "name": "Molly" + }, + { + "id": "3901", + "name": "Molly" + }, + { + "id": "3902", + "name": "Molly" + }, + { + "id": "3903", + "name": "Molly" + }, + { + "id": "3904", + "name": "Molly" + }, + { + "id": "3905", + "name": "Molly" + }, + { + "id": "3906", + "name": "Molly" + }, + { + "id": "3907", + "name": "Molly" + }, + { + "id": "3908", + "name": "Molly" + }, + { + "id": "3909", + "name": "Molly" + }, + { + "id": "3910", + "name": "Molly" + }, + { + "id": "3911", + "name": "Molly" + }, + { + "id": "3912", + "name": "Flippa" + }, + { + "id": "3913", + "name": "Tilt" + }, + { + "id": "3914", + "name": "Gardener" + }, + { + "id": "3918", + "name": "Prince Brand" + }, + { + "id": "3919", + "name": "Princess Astrid" + }, + { + "id": "3920", + "name": "Runa" + }, + { + "id": "3923", + "name": "Osvald" + }, + { + "id": "3924", + "name": "Runolf" + }, + { + "id": "3926", + "name": "Ingrid" + }, + { + "id": "3928", + "name": "Signy" + }, + { + "id": "3929", + "name": "Hild" + }, + { + "id": "3930", + "name": "Armod" + }, + { + "id": "3931", + "name": "Beigarth" + }, + { + "id": "3932", + "name": "Reinn" + }, + { + "id": "3936", + "name": "Thorodin" + }, + { + "id": "3944", + "name": "Hangman game" + }, + { + "id": "3945", + "name": "Hangman game" + }, + { + "id": "3946", + "name": "Hangman game" + }, + { + "id": "3947", + "name": "Hangman game" + }, + { + "id": "3948", + "name": "Hangman game" + }, + { + "id": "3949", + "name": "Hangman game" + }, + { + "id": "3950", + "name": "Hangman game" + }, + { + "id": "3951", + "name": "Hangman game" + }, + { + "id": "3952", + "name": "Hangman game" + }, + { + "id": "3953", + "name": "Hangman game" + }, + { + "id": "3954", + "name": "Treasure fairy" + }, + { + "id": "3955", + "name": "Jacky Jester" + }, + { + "id": "3956", + "name": "Combat stone" + }, + { + "id": "3957", + "name": "Combat stone" + }, + { + "id": "3958", + "name": "Combat stone" + }, + { + "id": "3959", + "name": "Combat stone" + }, + { + "id": "3960", + "name": "Combat stone" + }, + { + "id": "3961", + "name": "Combat stone" + }, + { + "id": "3962", + "name": "Combat stone" + }, + { + "id": "3963", + "name": "Combat stone" + }, + { + "id": "3964", + "name": "Combat stone" + }, + { + "id": "3965", + "name": "Combat stone" + }, + { + "id": "3966", + "name": "Combat stone" + }, + { + "id": "3967", + "name": "Combat stone" + }, + { + "id": "3968", + "name": "Combat stone" + }, + { + "id": "3969", + "name": "Combat stone" + }, + { + "id": "3970", + "name": "Combat stone" + }, + { + "id": "3971", + "name": "Combat stone" + }, + { + "id": "3972", + "name": "Combat stone" + }, + { + "id": "3973", + "name": "Combat stone" + }, + { + "id": "3974", + "name": "Combat stone" + }, + { + "id": "3975", + "name": "Combat stone" + }, + { + "id": "3976", + "name": "Combat stone" + }, + { + "id": "3977", + "name": "Combat stone" + }, + { + "id": "3978", + "name": "Combat stone" + }, + { + "id": "3979", + "name": "Combat stone" + }, + { + "id": "3980", + "name": "Combat stone" + }, + { + "id": "3981", + "name": "Combat stone" + }, + { + "id": "3982", + "name": "Combat stone" + }, + { + "id": "3983", + "name": "Combat stone" + }, + { + "id": "3984", + "name": "Combat stone" + }, + { + "id": "3985", + "name": "Combat stone" + }, + { + "id": "3986", + "name": "Combat stone" + }, + { + "id": "3987", + "name": "Combat stone" + }, + { + "id": "3988", + "name": "Combat stone" + }, + { + "id": "3989", + "name": "Combat stone" + }, + { + "id": "3990", + "name": "Combat stone" + }, + { + "id": "3991", + "name": "Combat stone" + }, + { + "id": "3992", + "name": "Combat stone" + }, + { + "id": "3993", + "name": "Combat stone" + }, + { + "id": "3994", + "name": "Combat stone" + }, + { + "id": "3995", + "name": "Combat stone" + }, + { + "id": "3996", + "name": "Combat stone" + }, + { + "id": "3997", + "name": "Combat stone" + }, + { + "id": "3998", + "name": "Combat stone" + }, + { + "id": "3999", + "name": "Combat stone" + }, + { + "id": "4000", + "name": "Combat stone" + }, + { + "id": "4001", + "name": "Combat stone" + }, + { + "id": "4002", + "name": "Combat stone" + }, + { + "id": "4003", + "name": "Combat stone" + }, + { + "id": "4004", + "name": "Combat stone" + }, + { + "id": "4005", + "name": "Combat stone" + }, + { + "id": "4006", + "name": "Combat stone" + }, + { + "id": "4007", + "name": "Combat stone" + }, + { + "id": "4008", + "name": "Combat stone" + }, + { + "id": "4009", + "name": "Combat stone" + }, + { + "id": "4010", + "name": "Combat stone" + }, + { + "id": "4011", + "name": "Combat stone" + }, + { + "id": "4012", + "name": "Combat stone" + }, + { + "id": "4013", + "name": "Combat stone" + }, + { + "id": "4014", + "name": "Combat stone" + }, + { + "id": "4015", + "name": "Combat stone" + }, + { + "id": "4016", + "name": "Combat stone" + }, + { + "id": "4017", + "name": "Combat stone" + }, + { + "id": "4018", + "name": "Combat stone" + }, + { + "id": "4019", + "name": "Combat stone" + }, + { + "id": "4020", + "name": "Combat stone" + }, + { + "id": "4021", + "name": "Elemental balance" + }, + { + "id": "4022", + "name": "Elemental balance" + }, + { + "id": "4023", + "name": "Elemental balance" + }, + { + "id": "4024", + "name": "Elemental balance" + }, + { + "id": "4025", + "name": "Elemental balance" + }, + { + "id": "4026", + "name": "Elemental balance" + }, + { + "id": "4027", + "name": "Elemental balance" + }, + { + "id": "4028", + "name": "Elemental balance" + }, + { + "id": "4029", + "name": "Elemental balance" + }, + { + "id": "4030", + "name": "Elemental balance" + }, + { + "id": "4031", + "name": "Elemental balance" + }, + { + "id": "4032", + "name": "Elemental balance" + }, + { + "id": "4033", + "name": "Elemental balance" + }, + { + "id": "4034", + "name": "Elemental balance" + }, + { + "id": "4035", + "name": "Elemental balance" + }, + { + "id": "4036", + "name": "Elemental balance" + }, + { + "id": "4037", + "name": "Elemental balance" + }, + { + "id": "4038", + "name": "Elemental balance" + }, + { + "id": "4039", + "name": "Elemental balance" + }, + { + "id": "4040", + "name": "Elemental balance" + }, + { + "id": "4041", + "name": "Elemental balance" + }, + { + "id": "4042", + "name": "Elemental balance" + }, + { + "id": "4043", + "name": "Elemental balance" + }, + { + "id": "4044", + "name": "Elemental balance" + }, + { + "id": "4045", + "name": "Elemental balance" + }, + { + "id": "4046", + "name": "Elemental balance" + }, + { + "id": "4047", + "name": "Elemental balance" + }, + { + "id": "4048", + "name": "Elemental balance" + }, + { + "id": "4049", + "name": "Elemental balance" + }, + { + "id": "4050", + "name": "Elemental balance" + }, + { + "id": "4051", + "name": "Elemental balance" + }, + { + "id": "4052", + "name": "Elemental balance" + }, + { + "id": "4053", + "name": "Elemental balance" + }, + { + "id": "4054", + "name": "Elemental balance" + }, + { + "id": "4055", + "name": "Elemental balance" + }, + { + "id": "4056", + "name": "Elemental balance" + }, + { + "id": "4057", + "name": "Elemental balance" + }, + { + "id": "4058", + "name": "Elemental balance" + }, + { + "id": "4059", + "name": "Elemental balance" + }, + { + "id": "4060", + "name": "Elemental balance" + }, + { + "id": "4061", + "name": "Elemental balance" + }, + { + "id": "4062", + "name": "Elemental balance" + }, + { + "id": "4063", + "name": "Elemental balance" + }, + { + "id": "4064", + "name": "Elemental balance" + }, + { + "id": "4065", + "name": "Elemental balance" + }, + { + "id": "4066", + "name": "Elemental balance" + }, + { + "id": "4067", + "name": "Elemental balance" + }, + { + "id": "4068", + "name": "Elemental balance" + }, + { + "id": "4069", + "name": "Elemental balance" + }, + { + "id": "4070", + "name": "Elemental balance" + }, + { + "id": "4071", + "name": "Elemental balance" + }, + { + "id": "4072", + "name": "Elemental balance" + }, + { + "id": "4073", + "name": "Elemental balance" + }, + { + "id": "4074", + "name": "Elemental balance" + }, + { + "id": "4075", + "name": "Elemental balance" + }, + { + "id": "4076", + "name": "Elemental balance" + }, + { + "id": "4077", + "name": "Elemental balance" + }, + { + "id": "4078", + "name": "Elemental balance" + }, + { + "id": "4079", + "name": "Elemental balance" + }, + { + "id": "4080", + "name": "Elemental balance" + }, + { + "id": "4081", + "name": "Elemental balance" + }, + { + "id": "4082", + "name": "Elemental balance" + }, + { + "id": "4083", + "name": "Elemental balance" + }, + { + "id": "4084", + "name": "Elemental balance" + }, + { + "id": "4085", + "name": "Elemental balance" + }, + { + "id": "4086", + "name": "Elemental balance" + }, + { + "id": "4087", + "name": "Elemental balance" + }, + { + "id": "4088", + "name": "Elemental balance" + }, + { + "id": "4089", + "name": "Elemental balance" + }, + { + "id": "4090", + "name": "Elemental balance" + }, + { + "id": "4091", + "name": "Elemental balance" + }, + { + "id": "4092", + "name": "Elemental balance" + }, + { + "id": "4093", + "name": "Elemental balance" + }, + { + "id": "4094", + "name": "Elemental balance" + }, + { + "id": "4095", + "name": "Elemental balance" + }, + { + "id": "4096", + "name": "Combat stone" + }, + { + "id": "4097", + "name": "Combat stone" + }, + { + "id": "4098", + "name": "Combat stone" + }, + { + "id": "4099", + "name": "Combat stone" + }, + { + "id": "4100", + "name": "Combat stone" + }, + { + "id": "4101", + "name": "Combat stone" + }, + { + "id": "4102", + "name": "Combat stone" + }, + { + "id": "4103", + "name": "Combat stone" + }, + { + "id": "4104", + "name": "Combat stone" + }, + { + "id": "4105", + "name": "Combat stone" + }, + { + "id": "4106", + "name": "Combat stone" + }, + { + "id": "4107", + "name": "Combat stone" + }, + { + "id": "4108", + "name": "Combat stone" + }, + { + "id": "4109", + "name": "Combat stone" + }, + { + "id": "4110", + "name": "Combat stone" + }, + { + "id": "4111", + "name": "Combat stone" + }, + { + "id": "4112", + "name": "Combat stone" + }, + { + "id": "4113", + "name": "Combat stone" + }, + { + "id": "4114", + "name": "Combat stone" + }, + { + "id": "4115", + "name": "Combat stone" + }, + { + "id": "4116", + "name": "Combat stone" + }, + { + "id": "4117", + "name": "Combat stone" + }, + { + "id": "4118", + "name": "Combat stone" + }, + { + "id": "4119", + "name": "Combat stone" + }, + { + "id": "4120", + "name": "Combat stone" + }, + { + "id": "4121", + "name": "Combat stone" + }, + { + "id": "4122", + "name": "Combat stone" + }, + { + "id": "4123", + "name": "Combat stone" + }, + { + "id": "4124", + "name": "Combat stone" + }, + { + "id": "4125", + "name": "Combat stone" + }, + { + "id": "4126", + "name": "Combat stone" + }, + { + "id": "4127", + "name": "Combat stone" + }, + { + "id": "4128", + "name": "Combat stone" + }, + { + "id": "4129", + "name": "Combat stone" + }, + { + "id": "4130", + "name": "Combat stone" + }, + { + "id": "4131", + "name": "Combat stone" + }, + { + "id": "4132", + "name": "Combat stone" + }, + { + "id": "4133", + "name": "Combat stone" + }, + { + "id": "4134", + "name": "Combat stone" + }, + { + "id": "4135", + "name": "Combat stone" + }, + { + "id": "4136", + "name": "Combat stone" + }, + { + "id": "4137", + "name": "Combat stone" + }, + { + "id": "4138", + "name": "Combat stone" + }, + { + "id": "4139", + "name": "Combat stone" + }, + { + "id": "4140", + "name": "Combat stone" + }, + { + "id": "4141", + "name": "Combat stone" + }, + { + "id": "4142", + "name": "Combat stone" + }, + { + "id": "4143", + "name": "Combat stone" + }, + { + "id": "4144", + "name": "Combat stone" + }, + { + "id": "4145", + "name": "Combat stone" + }, + { + "id": "4146", + "name": "Combat stone" + }, + { + "id": "4147", + "name": "Combat stone" + }, + { + "id": "4148", + "name": "Combat stone" + }, + { + "id": "4149", + "name": "Combat stone" + }, + { + "id": "4150", + "name": "Combat stone" + }, + { + "id": "4151", + "name": "Combat stone" + }, + { + "id": "4152", + "name": "Combat stone" + }, + { + "id": "4153", + "name": "Combat stone" + }, + { + "id": "4154", + "name": "Combat stone" + }, + { + "id": "4155", + "name": "Combat stone" + }, + { + "id": "4156", + "name": "Combat stone" + }, + { + "id": "4157", + "name": "Combat stone" + }, + { + "id": "4158", + "name": "Combat stone" + }, + { + "id": "4159", + "name": "Combat stone" + }, + { + "id": "4160", + "name": "Combat stone" + }, + { + "id": "4161", + "name": "Combat stone" + }, + { + "id": "4162", + "name": "Combat stone" + }, + { + "id": "4163", + "name": "Combat stone" + }, + { + "id": "4164", + "name": "Combat stone" + }, + { + "id": "4165", + "name": "Combat stone" + }, + { + "id": "4166", + "name": "Combat stone" + }, + { + "id": "4167", + "name": "Combat stone" + }, + { + "id": "4168", + "name": "Combat stone" + }, + { + "id": "4169", + "name": "Combat stone" + }, + { + "id": "4170", + "name": "Combat stone" + }, + { + "id": "4171", + "name": "Combat stone" + }, + { + "id": "4172", + "name": "Combat stone" + }, + { + "id": "4173", + "name": "Combat stone" + }, + { + "id": "4174", + "name": "Combat stone" + }, + { + "id": "4175", + "name": "Combat stone" + }, + { + "id": "4176", + "name": "Combat stone" + }, + { + "id": "4177", + "name": "Combat stone" + }, + { + "id": "4178", + "name": "Combat stone" + }, + { + "id": "4179", + "name": "Combat stone" + }, + { + "id": "4180", + "name": "Combat stone" + }, + { + "id": "4181", + "name": "Combat stone" + }, + { + "id": "4182", + "name": "Combat stone" + }, + { + "id": "4183", + "name": "Combat stone" + }, + { + "id": "4184", + "name": "Combat stone" + }, + { + "id": "4185", + "name": "Combat stone" + }, + { + "id": "4186", + "name": "Combat stone" + }, + { + "id": "4187", + "name": "Combat stone" + }, + { + "id": "4188", + "name": "Combat stone" + }, + { + "id": "4189", + "name": "Combat stone" + }, + { + "id": "4190", + "name": "Combat stone" + }, + { + "id": "4191", + "name": "Combat stone" + }, + { + "id": "4192", + "name": "Combat stone" + }, + { + "id": "4193", + "name": "Combat stone" + }, + { + "id": "4194", + "name": "Combat stone" + }, + { + "id": "4195", + "name": "Combat stone" + }, + { + "id": "4196", + "name": "Combat stone" + }, + { + "id": "4197", + "name": "Combat stone" + }, + { + "id": "4198", + "name": "Combat stone" + }, + { + "id": "4199", + "name": "Combat stone" + }, + { + "id": "4200", + "name": "Combat stone" + }, + { + "id": "4201", + "name": "Combat stone" + }, + { + "id": "4202", + "name": "Combat stone" + }, + { + "id": "4203", + "name": "Combat stone" + }, + { + "id": "4204", + "name": "Combat stone" + }, + { + "id": "4205", + "name": "Combat stone" + }, + { + "id": "4206", + "name": "Combat stone" + }, + { + "id": "4207", + "name": "Combat stone" + }, + { + "id": "4208", + "name": "Combat stone" + }, + { + "id": "4209", + "name": "Combat stone" + }, + { + "id": "4210", + "name": "Combat stone" + }, + { + "id": "4211", + "name": "Combat stone" + }, + { + "id": "4212", + "name": "Combat stone" + }, + { + "id": "4213", + "name": "Combat stone" + }, + { + "id": "4214", + "name": "Combat stone" + }, + { + "id": "4215", + "name": "Combat stone" + }, + { + "id": "4216", + "name": "Combat stone" + }, + { + "id": "4217", + "name": "Combat stone" + }, + { + "id": "4218", + "name": "Combat stone" + }, + { + "id": "4219", + "name": "Combat stone" + }, + { + "id": "4220", + "name": "Combat stone" + }, + { + "id": "4221", + "name": "Combat stone" + }, + { + "id": "4222", + "name": "Combat stone" + }, + { + "id": "4223", + "name": "Combat stone" + }, + { + "id": "4224", + "name": "Combat stone" + }, + { + "id": "4225", + "name": "Combat stone" + }, + { + "id": "4226", + "name": "Crawling hand" + }, + { + "id": "4231", + "name": "Left head" + }, + { + "id": "4232", + "name": "Middle head" + }, + { + "id": "4233", + "name": "Right head" + }, + { + "id": "4234", + "name": "Kalphite Queen" + }, + { + "id": "4235", + "name": "Rick" + }, + { + "id": "4236", + "name": "Maid" + }, + { + "id": "4238", + "name": "Cook" + }, + { + "id": "4240", + "name": "Butler" + }, + { + "id": "4242", + "name": "Demon butler" + }, + { + "id": "4244", + "name": "Chief servant" + }, + { + "id": "4253", + "name": "Guard" + }, + { + "id": "4277", + "name": "Buinn" + }, + { + "id": "4312", + "name": "Nardok" + }, + { + "id": "4313", + "name": "Dartog" + }, + { + "id": "4315", + "name": "Dwarf" + }, + { + "id": "4317", + "name": "H.A.M. Member" + }, + { + "id": "4319", + "name": "H.A.M. Member" + }, + { + "id": "4321", + "name": "Zanik" + }, + { + "id": "4323", + "name": "Zanik" + }, + { + "id": "4324", + "name": "Zanik" + }, + { + "id": "4325", + "name": "Light creature" + }, + { + "id": "4326", + "name": "Zanik" + }, + { + "id": "4327", + "name": "HAM member" + }, + { + "id": "4328", + "name": "Sigmund" + }, + { + "id": "4330", + "name": "Johanhus Ulsbrecht" + }, + { + "id": "4331", + "name": "Sigmund" + }, + { + "id": "4332", + "name": "Sigmund" + }, + { + "id": "4333", + "name": "Sigmund" + }, + { + "id": "4334", + "name": "Sigmund" + }, + { + "id": "4335", + "name": "Sigmund" + }, + { + "id": "4337", + "name": "Zanik" + }, + { + "id": "4338", + "name": "Zanik" + }, + { + "id": "4340", + "name": "Zanik" + }, + { + "id": "4341", + "name": "Zanik" + }, + { + "id": "4342", + "name": "Zanik" + }, + { + "id": "4346", + "name": "Crab" + }, + { + "id": "4358", + "name": "Cavey Davey" + }, + { + "id": "4360", + "name": "San Fan" + }, + { + "id": "4364", + "name": "Swarm" + }, + { + "id": "4365", + "name": "Blue Monkey" + }, + { + "id": "4374", + "name": "Parrot" + }, + { + "id": "4377", + "name": "Gate of War" + }, + { + "id": "4378", + "name": "Ricketty door" + }, + { + "id": "4379", + "name": "Oozing barrier" + }, + { + "id": "4380", + "name": "Portal of Death" + }, + { + "id": "4416", + "name": "Bee keeper" + }, + { + "id": "4417", + "name": "Bees!" + }, + { + "id": "4420", + "name": "Fairy Godfather" + }, + { + "id": "4435", + "name": "Fairy Queen" + }, + { + "id": "4442", + "name": "Fairy Very Wise" + }, + { + "id": "4444", + "name": "Fairy" + }, + { + "id": "4445", + "name": "Fairy" + }, + { + "id": "4446", + "name": "Fairy" + }, + { + "id": "4447", + "name": "Rabbit" + }, + { + "id": "4448", + "name": "Rabbit" + }, + { + "id": "4449", + "name": "Butterfly" + }, + { + "id": "4450", + "name": "Butterfly" + }, + { + "id": "4451", + "name": "Starflower" + }, + { + "id": "4452", + "name": "Starflower" + }, + { + "id": "4453", + "name": "Fairy Fixit" + }, + { + "id": "4456", + "name": "Ork" + }, + { + "id": "4460", + "name": "Fake Man" + }, + { + "id": "4461", + "name": "Held vampyre juvinate" + }, + { + "id": "4462", + "name": "Held vampyre juvinate" + }, + { + "id": "4463", + "name": "Angry juvinate" + }, + { + "id": "4464", + "name": "Angry juvinate" + }, + { + "id": "4465", + "name": "Angry juvinate" + }, + { + "id": "4466", + "name": "Benjamin" + }, + { + "id": "4467", + "name": "Liam" + }, + { + "id": "4468", + "name": "Miala" + }, + { + "id": "4469", + "name": "Verak" + }, + { + "id": "4471", + "name": "Bogrog" + }, + { + "id": "4473", + "name": "Woman" + }, + { + "id": "4475", + "name": "Ned" + }, + { + "id": "4477", + "name": "Annoyed guardian mummy" + }, + { + "id": "4478", + "name": "Tarik" + }, + { + "id": "4493", + "name": "General Bentnoze" + }, + { + "id": "4495", + "name": "Grubfoot" + }, + { + "id": "4497", + "name": "Grubfoot" + }, + { + "id": "4498", + "name": "Grubfoot" + }, + { + "id": "4500", + "name": "Scarab swarm" + }, + { + "id": "4508", + "name": "Ethereal Mimic" + }, + { + "id": "4513", + "name": "Baba Yaga" + }, + { + "id": "4514", + "name": "Pauline Polaris" + }, + { + "id": "4515", + "name": "Meteora" + }, + { + "id": "4516", + "name": "Melana Moonlander" + }, + { + "id": "4517", + "name": "Selene" + }, + { + "id": "4518", + "name": "Rimae Sirsalis" + }, + { + "id": "4519", + "name": "Sirsal Banker" + }, + { + "id": "4520", + "name": "Clan Guard" + }, + { + "id": "4522", + "name": "Enchanted Broom" + }, + { + "id": "4523", + "name": "Enchanted Broom" + }, + { + "id": "4525", + "name": "Enchanted Bucket" + }, + { + "id": "4526", + "name": "Bouquet Mac Hyacinth" + }, + { + "id": "4535", + "name": "Parrot" + }, + { + "id": "4536", + "name": "Lokar Searunner" + }, + { + "id": "4538", + "name": "Cabin boy" + }, + { + "id": "4544", + "name": "'Bird's-Eye' Jack" + }, + { + "id": "4552", + "name": "Palmer" + }, + { + "id": "4553", + "name": "'Betty' B.Boppin" + }, + { + "id": "4558", + "name": "Hirko" + }, + { + "id": "4559", + "name": "Holoy" + }, + { + "id": "4563", + "name": "Hura" + }, + { + "id": "4569", + "name": "Nick" + }, + { + "id": "4570", + "name": "Crow" + }, + { + "id": "4571", + "name": "Crow" + }, + { + "id": "4572", + "name": "Gianne jnr." + }, + { + "id": "4573", + "name": "Timble" + }, + { + "id": "4574", + "name": "Tamble" + }, + { + "id": "4575", + "name": "Spang" + }, + { + "id": "4576", + "name": "Brambickle" + }, + { + "id": "4577", + "name": "Wingstone" + }, + { + "id": "4578", + "name": "Penwie" + }, + { + "id": "4583", + "name": "Professor Manglethorp" + }, + { + "id": "4584", + "name": "Damwin" + }, + { + "id": "4586", + "name": "Professor Imblewyn" + }, + { + "id": "4587", + "name": "Perrdur" + }, + { + "id": "4588", + "name": "Dalila" + }, + { + "id": "4591", + "name": "Eebel" + }, + { + "id": "4592", + "name": "Ermin" + }, + { + "id": "4596", + "name": "Captain Lamdoo" + }, + { + "id": "4597", + "name": "Meegle" + }, + { + "id": "4598", + "name": "Wurbel" + }, + { + "id": "4599", + "name": "Sarble" + }, + { + "id": "4601", + "name": "Burkor" + }, + { + "id": "4602", + "name": "Froono" + }, + { + "id": "4609", + "name": "Brimstail" + }, + { + "id": "4612", + "name": "Gnome shop keeper" + }, + { + "id": "4613", + "name": "Cute creature" + }, + { + "id": "4616", + "name": "Cute creature" + }, + { + "id": "4618", + "name": "Evil creature" + }, + { + "id": "4619", + "name": "Cute creature" + }, + { + "id": "4621", + "name": "Evil creature" + }, + { + "id": "4622", + "name": "Cute creature" + }, + { + "id": "4624", + "name": "Evil creature" + }, + { + "id": "4625", + "name": "Cute creature" + }, + { + "id": "4627", + "name": "Evil creature" + }, + { + "id": "4628", + "name": "Cute creature" + }, + { + "id": "4630", + "name": "Evil creature" + }, + { + "id": "4631", + "name": "fluffie" + }, + { + "id": "4632", + "name": "fluffie" + }, + { + "id": "4644", + "name": "Oaknock the Engineer" + }, + { + "id": "4646", + "name": "King Healthorg" + }, + { + "id": "4647", + "name": "Hazelmere" + }, + { + "id": "4648", + "name": "Nisha" + }, + { + "id": "4649", + "name": "Tyras guard" + }, + { + "id": "4657", + "name": "Sir Prysin" + }, + { + "id": "4658", + "name": "Dark wizard" + }, + { + "id": "4662", + "name": "Denath" + }, + { + "id": "4663", + "name": "Denath" + }, + { + "id": "4664", + "name": "Wally" + }, + { + "id": "4709", + "name": "Vertida Sefalatis" + }, + { + "id": "4710", + "name": "Aeonisig Raispher" + }, + { + "id": "4711", + "name": "Safalaan" + }, + { + "id": "4714", + "name": "Sarius Guile" + }, + { + "id": "4727", + "name": "Meiyerditch citizen" + }, + { + "id": "4728", + "name": "Meiyerditch citizen" + }, + { + "id": "4729", + "name": "Meiyerditch citizen" + }, + { + "id": "4730", + "name": "Meiyerditch citizen" + }, + { + "id": "4731", + "name": "Meiyerditch citizen" + }, + { + "id": "4732", + "name": "Meiyerditch citizen" + }, + { + "id": "4742", + "name": "Meiyerditch citizen" + }, + { + "id": "4743", + "name": "Meiyerditch citizen" + }, + { + "id": "4744", + "name": "Meiyerditch citizen" + }, + { + "id": "4745", + "name": "Meiyerditch citizen" + }, + { + "id": "4758", + "name": "Meiyerditch miner" + }, + { + "id": "4760", + "name": "Meiyerditch miner" + }, + { + "id": "4761", + "name": "Meiyerditch miner" + }, + { + "id": "4762", + "name": "Shadowy figure" + }, + { + "id": "4763", + "name": "Shadowy figure" + }, + { + "id": "4764", + "name": "Shadowy figure" + }, + { + "id": "4767", + "name": "Stray dog" + }, + { + "id": "4769", + "name": "Cat" + }, + { + "id": "4770", + "name": "Boat" + }, + { + "id": "4771", + "name": "Boat" + }, + { + "id": "4781", + "name": "Held vampyre juvinate" + }, + { + "id": "4782", + "name": "Vampyre juvinate" + }, + { + "id": "4783", + "name": "Former vampyre" + }, + { + "id": "4784", + "name": "Former vampyre" + }, + { + "id": "4785", + "name": "Former vampyre" + }, + { + "id": "4786", + "name": "Former vampyre" + }, + { + "id": "4787", + "name": "Former vampyre" + }, + { + "id": "4788", + "name": "Former vampyre" + }, + { + "id": "4790", + "name": "Angry vampyre" + }, + { + "id": "4791", + "name": "Vanstrom Klause" + }, + { + "id": "4792", + "name": "Vanstrom Klause" + }, + { + "id": "4794", + "name": "Vanstrom Klause" + }, + { + "id": "4795", + "name": "Vanstrom Klause" + }, + { + "id": "4797", + "name": "Vanescula Drakan" + }, + { + "id": "4798", + "name": "Vanescula Drakan" + }, + { + "id": "4799", + "name": "Vanescula Drakan" + }, + { + "id": "4800", + "name": "Vanescula Drakan" + }, + { + "id": "4801", + "name": "Ranis Drakan" + }, + { + "id": "4802", + "name": "Ranis Drakan" + }, + { + "id": "4803", + "name": "Ranis Drakan" + }, + { + "id": "4804", + "name": "Ranis Drakan" + }, + { + "id": "4809", + "name": "Flying female vampire" + }, + { + "id": "4846", + "name": "Flying female vampire" + }, + { + "id": "4853", + "name": "Ezekial Lovecraft" + }, + { + "id": "4857", + "name": "Sarius Guile" + }, + { + "id": "4862", + "name": "Vanstrom Klause" + }, + { + "id": "4863", + "name": "Kennith" + }, + { + "id": "4864", + "name": "Kennith" + }, + { + "id": "4865", + "name": "Holgart" + }, + { + "id": "4867", + "name": "Holgart" + }, + { + "id": "4869", + "name": "Fisherman" + }, + { + "id": "4871", + "name": "Col. O'Niall" + }, + { + "id": "4873", + "name": "Col. O'Niall" + }, + { + "id": "4875", + "name": "Mayor Hobb" + }, + { + "id": "4876", + "name": "Brother Maledict" + }, + { + "id": "4879", + "name": "Brother Maledict" + }, + { + "id": "4880", + "name": "Witchaven villager" + }, + { + "id": "4884", + "name": "Witchaven villager" + }, + { + "id": "4886", + "name": "Witchaven villager" + }, + { + "id": "4888", + "name": "Witchaven villager" + }, + { + "id": "4889", + "name": "Mother Mallum" + }, + { + "id": "4891", + "name": "Giant lobster" + }, + { + "id": "4896", + "name": "Jeb" + }, + { + "id": "4897", + "name": "Sir Tinley" + }, + { + "id": "4905", + "name": "Smithing Tutor" + }, + { + "id": "4908", + "name": "Fishing spot" + }, + { + "id": "4912", + "name": "Jig cart" + }, + { + "id": "4914", + "name": "Jig cart" + }, + { + "id": "4915", + "name": "Jig cart" + }, + { + "id": "4916", + "name": "Jig cart" + }, + { + "id": "4917", + "name": "Jig cart" + }, + { + "id": "4918", + "name": "Jig cart" + }, + { + "id": "4919", + "name": "Abidor Crank" + }, + { + "id": "4946", + "name": "Ignatius Vulcan" + }, + { + "id": "4948", + "name": "My Arm" + }, + { + "id": "4949", + "name": "My Arm" + }, + { + "id": "4950", + "name": "My Arm" + }, + { + "id": "4958", + "name": "My Arm" + }, + { + "id": "4959", + "name": "My Arm" + }, + { + "id": "4960", + "name": "Adventurer" + }, + { + "id": "4961", + "name": "Captain Barnaby" + }, + { + "id": "4963", + "name": "Murcaily" + }, + { + "id": "4964", + "name": "Jagbakoba" + }, + { + "id": "4966", + "name": "Flies" + }, + { + "id": "4968", + "name": "Unnamed troll child" + }, + { + "id": "4969", + "name": "Drunken dwarf's leg" + }, + { + "id": "4970", + "name": "Baby Roc" + }, + { + "id": "4973", + "name": "Shadow" + }, + { + "id": "4974", + "name": "Captain Barnaby" + }, + { + "id": "4976", + "name": "Male slave" + }, + { + "id": "4978", + "name": "Female slave" + }, + { + "id": "4979", + "name": "Cart Camel" + }, + { + "id": "4980", + "name": "Mine Cart" + }, + { + "id": "4981", + "name": "Mine Cart" + }, + { + "id": "4982", + "name": "Ana" + }, + { + "id": "4983", + "name": "Mercenary" + }, + { + "id": "4984", + "name": "Irena" + }, + { + "id": "5003", + "name": "Gublinch" + }, + { + "id": "5018", + "name": "Gublinch" + }, + { + "id": "5019", + "name": "Gublinch" + }, + { + "id": "5020", + "name": "Jack" + }, + { + "id": "5024", + "name": "Jill" + }, + { + "id": "5025", + "name": "Jeff" + }, + { + "id": "5044", + "name": "Penance Fighter" + }, + { + "id": "5045", + "name": "Penance Fighter" + }, + { + "id": "5046", + "name": "Jack" + }, + { + "id": "5047", + "name": "Jill" + }, + { + "id": "5049", + "name": "Auguste" + }, + { + "id": "5050", + "name": "Auguste" + }, + { + "id": "5051", + "name": "Auguste" + }, + { + "id": "5052", + "name": "Auguste" + }, + { + "id": "5053", + "name": "Assistant Serf" + }, + { + "id": "5054", + "name": "Assistant Brock" + }, + { + "id": "5055", + "name": "Assistant Marrow" + }, + { + "id": "5056", + "name": "Assistant Le Smith" + }, + { + "id": "5057", + "name": "Assistant Stan" + }, + { + "id": "5058", + "name": "Bob" + }, + { + "id": "5059", + "name": "Curly" + }, + { + "id": "5060", + "name": "Moe" + }, + { + "id": "5061", + "name": "Larry" + }, + { + "id": "5062", + "name": "Shark" + }, + { + "id": "5068", + "name": "Shark" + }, + { + "id": "5069", + "name": "Shark" + }, + { + "id": "5070", + "name": "Tropical wagtail" + }, + { + "id": "5077", + "name": "Chinchompa" + }, + { + "id": "5090", + "name": "Matthias" + }, + { + "id": "5093", + "name": "Matthias" + }, + { + "id": "5094", + "name": "Gyr Falcon" + }, + { + "id": "5095", + "name": "Gyr Falcon" + }, + { + "id": "5096", + "name": "Gyr Falcon" + }, + { + "id": "5101", + "name": "Sabre-toothed kyatt" + }, + { + "id": "5110", + "name": "Aleck" + }, + { + "id": "5118", + "name": "Eagle" + }, + { + "id": "5121", + "name": "Eagle" + }, + { + "id": "5122", + "name": "Eagle" + }, + { + "id": "5123", + "name": "Eagle" + }, + { + "id": "5124", + "name": "Nickolaus" + }, + { + "id": "5127", + "name": "Nickolaus" + }, + { + "id": "5128", + "name": "Nickolaus" + }, + { + "id": "5129", + "name": "Nickolaus" + }, + { + "id": "5134", + "name": "Kebbit" + }, + { + "id": "5138", + "name": "Charlie" + }, + { + "id": "5139", + "name": "Boulder" + }, + { + "id": "5141", + "name": "Uri" + }, + { + "id": "5142", + "name": "Uri" + }, + { + "id": "5143", + "name": "Uri" + }, + { + "id": "5148", + "name": "Sheep" + }, + { + "id": "5149", + "name": "Sheep" + }, + { + "id": "5150", + "name": "Sheep" + }, + { + "id": "5151", + "name": "Sheep" + }, + { + "id": "5152", + "name": "Sheep" + }, + { + "id": "5153", + "name": "Sheep" + }, + { + "id": "5154", + "name": "Sheep" + }, + { + "id": "5155", + "name": "Sheep" + }, + { + "id": "5156", + "name": "Sheep" + }, + { + "id": "5157", + "name": "Sheep" + }, + { + "id": "5158", + "name": "Sheep" + }, + { + "id": "5159", + "name": "Sheep" + }, + { + "id": "5160", + "name": "Sheep" + }, + { + "id": "5161", + "name": "Sheep" + }, + { + "id": "5165", + "name": "Sheep" + }, + { + "id": "5174", + "name": "Ogre chieftain" + }, + { + "id": "5175", + "name": "Ogre shaman" + }, + { + "id": "5177", + "name": "Ogre shaman" + }, + { + "id": "5179", + "name": "Elkoy" + }, + { + "id": "5180", + "name": "Ogre shaman" + }, + { + "id": "5182", + "name": "Elkoy" + }, + { + "id": "5183", + "name": "Ogre shaman" + }, + { + "id": "5185", + "name": "Biggleswade" + }, + { + "id": "5186", + "name": "Ogre shaman" + }, + { + "id": "5189", + "name": "Ogre shaman" + }, + { + "id": "5191", + "name": "Blaze Sharpeye" + }, + { + "id": "5192", + "name": "Ogre shaman" + }, + { + "id": "5194", + "name": "Blaze Sharpeye" + }, + { + "id": "5199", + "name": "Witch" + }, + { + "id": "5201", + "name": "Alice's husband" + }, + { + "id": "5203", + "name": "Alice's husband" + }, + { + "id": "5205", + "name": "Alice's husband" + }, + { + "id": "5206", + "name": "Tree" + }, + { + "id": "5208", + "name": "Undead tree" + }, + { + "id": "5209", + "name": " Sneaky undead fowl" + }, + { + "id": "5210", + "name": "Cow1337killr" + }, + { + "id": "5212", + "name": "Alice" + }, + { + "id": "5213", + "name": "Penance Fighter" + }, + { + "id": "5214", + "name": "Penance Fighter" + }, + { + "id": "5215", + "name": "Penance Fighter" + }, + { + "id": "5216", + "name": "Penance Fighter" + }, + { + "id": "5217", + "name": "Penance Fighter" + }, + { + "id": "5218", + "name": "Penance Fighter" + }, + { + "id": "5219", + "name": "Penance Fighter" + }, + { + "id": "5220", + "name": "Penance Runner" + }, + { + "id": "5221", + "name": "Penance Runner" + }, + { + "id": "5222", + "name": "Penance Runner" + }, + { + "id": "5223", + "name": "Penance Runner" + }, + { + "id": "5224", + "name": "Penance Runner" + }, + { + "id": "5225", + "name": "Penance Runner" + }, + { + "id": "5226", + "name": "Penance Runner" + }, + { + "id": "5227", + "name": "Penance Runner" + }, + { + "id": "5228", + "name": "Penance Runner" + }, + { + "id": "5230", + "name": "Penance Ranger" + }, + { + "id": "5231", + "name": "Penance Ranger" + }, + { + "id": "5232", + "name": "Penance Ranger" + }, + { + "id": "5233", + "name": "Penance Ranger" + }, + { + "id": "5234", + "name": "Penance Ranger" + }, + { + "id": "5235", + "name": "Penance Ranger" + }, + { + "id": "5236", + "name": "Penance Ranger" + }, + { + "id": "5238", + "name": "Penance Healer" + }, + { + "id": "5239", + "name": "Penance Healer" + }, + { + "id": "5240", + "name": "Penance Healer" + }, + { + "id": "5241", + "name": "Penance Healer" + }, + { + "id": "5242", + "name": "Penance Healer" + }, + { + "id": "5243", + "name": "Penance Healer" + }, + { + "id": "5244", + "name": "Penance Healer" + }, + { + "id": "5245", + "name": "Penance Healer" + }, + { + "id": "5246", + "name": "Penance Healer" + }, + { + "id": "5255", + "name": "Locust rider" + }, + { + "id": "5256", + "name": "Locust rider" + }, + { + "id": "5257", + "name": "Banker" + }, + { + "id": "5259", + "name": "Banker" + }, + { + "id": "5261", + "name": "Stonemason" + }, + { + "id": "5263", + "name": "Nathifa" + }, + { + "id": "5265", + "name": "Urbi" + }, + { + "id": "5267", + "name": "Jamila" + }, + { + "id": "5269", + "name": "Sophanem guard" + }, + { + "id": "5271", + "name": "Sophanem guard" + }, + { + "id": "5273", + "name": "Sophanem guard" + }, + { + "id": "5275", + "name": "Sophanem guard" + }, + { + "id": "5278", + "name": "Coenus" + }, + { + "id": "5279", + "name": "Jex" + }, + { + "id": "5280", + "name": "Maisa" + }, + { + "id": "5282", + "name": "Osman" + }, + { + "id": "5286", + "name": "Osman" + }, + { + "id": "5287", + "name": "Osman" + }, + { + "id": "5288", + "name": "Embalmer" + }, + { + "id": "5289", + "name": "Carpenter" + }, + { + "id": "5290", + "name": "Linen worker" + }, + { + "id": "5291", + "name": "Priest" + }, + { + "id": "5292", + "name": "Giant scarab" + }, + { + "id": "5360", + "name": "Mummy ashes" + }, + { + "id": "5383", + "name": "Odovacar" + }, + { + "id": "5415", + "name": "Terror dog statue" + }, + { + "id": "5416", + "name": "Terror dog statue" + }, + { + "id": "5419", + "name": "Tarn" + }, + { + "id": "5423", + "name": "Larry" + }, + { + "id": "5425", + "name": "Larry" + }, + { + "id": "5426", + "name": "Larry" + }, + { + "id": "5427", + "name": "Penguin" + }, + { + "id": "5429", + "name": "Penguin" + }, + { + "id": "5430", + "name": "Penguin" + }, + { + "id": "5431", + "name": "KGP Guard" + }, + { + "id": "5432", + "name": "Pescaling Pax" + }, + { + "id": "5433", + "name": "Ping" + }, + { + "id": "5434", + "name": "Ping" + }, + { + "id": "5435", + "name": "Pong" + }, + { + "id": "5436", + "name": "Pong" + }, + { + "id": "5437", + "name": "Ping" + }, + { + "id": "5438", + "name": "Pong" + }, + { + "id": "5443", + "name": "Noodle" + }, + { + "id": "5445", + "name": "Penguin" + }, + { + "id": "5446", + "name": "Penguin suit" + }, + { + "id": "5449", + "name": "Penguin" + }, + { + "id": "5450", + "name": "Penguin" + }, + { + "id": "5451", + "name": "Penguin" + }, + { + "id": "5456", + "name": "Crusher" + }, + { + "id": "5457", + "name": "Crusher" + }, + { + "id": "5458", + "name": "Crusher" + }, + { + "id": "5459", + "name": "Crusher" + }, + { + "id": "5460", + "name": "Tree" + }, + { + "id": "5461", + "name": "Jungle Tree" + }, + { + "id": "5462", + "name": "Tolna" + }, + { + "id": "5463", + "name": "Honour guard" + }, + { + "id": "5464", + "name": "Honour guard" + }, + { + "id": "5465", + "name": "Fridleif Shieldson" + }, + { + "id": "5466", + "name": "Thakkrad Sigmundson" + }, + { + "id": "5467", + "name": "Iceberg" + }, + { + "id": "5468", + "name": "Iceberg" + }, + { + "id": "5469", + "name": "Arctic Pine" + }, + { + "id": "5470", + "name": "Fishing spot" + }, + { + "id": "5471", + "name": "Fishing spot" + }, + { + "id": "5477", + "name": "Bork Sigmundson" + }, + { + "id": "5481", + "name": "Mord Gunnars" + }, + { + "id": "5482", + "name": "Mord Gunnars" + }, + { + "id": "5498", + "name": "Miner" + }, + { + "id": "5502", + "name": "Grundt" + }, + { + "id": "5503", + "name": "Mawnis Burowgar" + }, + { + "id": "5504", + "name": "Mawnis Burowgar" + }, + { + "id": "5505", + "name": "Fridleif Shieldson" + }, + { + "id": "5506", + "name": "Thakkrad Sigmundson" + }, + { + "id": "5507", + "name": "Maria Gunnars" + }, + { + "id": "5508", + "name": "Maria Gunnars" + }, + { + "id": "5509", + "name": "Jofridr Mordstatter" + }, + { + "id": "5510", + "name": "Morten Holdstrom" + }, + { + "id": "5511", + "name": "Gunnar Holdstrom" + }, + { + "id": "5512", + "name": "Anne Isaakson" + }, + { + "id": "5513", + "name": "Lisse Isaakson" + }, + { + "id": "5518", + "name": "Kjedelig Uppsen" + }, + { + "id": "5519", + "name": "Trogen Konungarde" + }, + { + "id": "5520", + "name": "Slug Hemligssen" + }, + { + "id": "5528", + "name": "Ice troll grunt" + }, + { + "id": "5530", + "name": "Sorceress" + }, + { + "id": "5560", + "name": "Osman" + }, + { + "id": "5562", + "name": "Del-Monty" + }, + { + "id": "5564", + "name": "Bouncer" + }, + { + "id": "5565", + "name": "Bouncer" + }, + { + "id": "5566", + "name": "General Khazard" + }, + { + "id": "5567", + "name": "Scout" + }, + { + "id": "5568", + "name": "Scout" + }, + { + "id": "5569", + "name": "Scout" + }, + { + "id": "5570", + "name": "Scout" + }, + { + "id": "5573", + "name": "Effigy" + }, + { + "id": "5579", + "name": "Effigy" + }, + { + "id": "5580", + "name": "Bonafido" + }, + { + "id": "5582", + "name": "Homunculus" + }, + { + "id": "5583", + "name": "Homunculus" + }, + { + "id": "5585", + "name": "'Transmute' The Alchemist" + }, + { + "id": "5586", + "name": "'Transmute' The Alchemist" + }, + { + "id": "5587", + "name": "'Currency' The Alchemist" + }, + { + "id": "5588", + "name": "'Currency' The Alchemist" + }, + { + "id": "5592", + "name": "'The Guns'" + }, + { + "id": "5598", + "name": "Unicow" + }, + { + "id": "5604", + "name": "Elfinlocks" + }, + { + "id": "5605", + "name": "Clockwork cat" + }, + { + "id": "5606", + "name": "Clockwork cat" + }, + { + "id": "5612", + "name": "Rufus" + }, + { + "id": "5613", + "name": "Mi-Gor" + }, + { + "id": "5615", + "name": "Puffin" + }, + { + "id": "5616", + "name": "Brother Tranquility" + }, + { + "id": "5617", + "name": "Brother Tranquility" + }, + { + "id": "5618", + "name": "Brother Tranquility" + }, + { + "id": "5623", + "name": "Zombie monk" + }, + { + "id": "5624", + "name": "Zombie monk" + }, + { + "id": "5625", + "name": "Zombie monk" + }, + { + "id": "5626", + "name": "Zombie monk" + }, + { + "id": "5667", + "name": "Undead Lumberjack" + }, + { + "id": "5679", + "name": "Undead Lumberjack" + }, + { + "id": "5681", + "name": "Undead Lumberjack" + }, + { + "id": "5682", + "name": "Undead Lumberjack" + }, + { + "id": "5683", + "name": "Undead Lumberjack" + }, + { + "id": "5684", + "name": "Undead Lumberjack" + }, + { + "id": "5685", + "name": "Undead Lumberjack" + }, + { + "id": "5686", + "name": "Undead Lumberjack" + }, + { + "id": "5687", + "name": "Undead Lumberjack" + }, + { + "id": "5688", + "name": "Undead Lumberjack" + }, + { + "id": "5689", + "name": "Undead Lumberjack" + }, + { + "id": "5690", + "name": "Undead Lumberjack" + }, + { + "id": "5691", + "name": "Undead Lumberjack" + }, + { + "id": "5692", + "name": "Undead Lumberjack" + }, + { + "id": "5693", + "name": "Undead Lumberjack" + }, + { + "id": "5694", + "name": "Undead Lumberjack" + }, + { + "id": "5695", + "name": "Undead Lumberjack" + }, + { + "id": "5696", + "name": "Undead Lumberjack" + }, + { + "id": "5697", + "name": "Undead Lumberjack" + }, + { + "id": "5698", + "name": "Undead Lumberjack" + }, + { + "id": "5699", + "name": "Undead Lumberjack" + }, + { + "id": "5700", + "name": "Undead Lumberjack" + }, + { + "id": "5701", + "name": "Undead Lumberjack" + }, + { + "id": "5702", + "name": "Undead Lumberjack" + }, + { + "id": "5703", + "name": "Undead Lumberjack" + }, + { + "id": "5704", + "name": "Undead Lumberjack" + }, + { + "id": "5705", + "name": "Undead Lumberjack" + }, + { + "id": "5706", + "name": "Undead Lumberjack" + }, + { + "id": "5707", + "name": "Undead Lumberjack" + }, + { + "id": "5708", + "name": "Undead Lumberjack" + }, + { + "id": "5709", + "name": "Undead Lumberjack" + }, + { + "id": "5710", + "name": "Undead Lumberjack" + }, + { + "id": "5711", + "name": "Undead Lumberjack" + }, + { + "id": "5712", + "name": "Undead Lumberjack" + }, + { + "id": "5713", + "name": "Undead Lumberjack" + }, + { + "id": "5714", + "name": "Undead Lumberjack" + }, + { + "id": "5715", + "name": "Undead Lumberjack" + }, + { + "id": "5716", + "name": "Undead Lumberjack" + }, + { + "id": "5717", + "name": "Undead Lumberjack" + }, + { + "id": "5718", + "name": "Undead Lumberjack" + }, + { + "id": "5719", + "name": "Undead Lumberjack" + }, + { + "id": "5720", + "name": "Undead Lumberjack" + }, + { + "id": "5721", + "name": "Undead Lumberjack" + }, + { + "id": "5722", + "name": "Undead Lumberjack" + }, + { + "id": "5723", + "name": "Undead Lumberjack" + }, + { + "id": "5724", + "name": "Undead Lumberjack" + }, + { + "id": "5725", + "name": "Undead Lumberjack" + }, + { + "id": "5726", + "name": "Undead Lumberjack" + }, + { + "id": "5727", + "name": "Undead Lumberjack" + }, + { + "id": "5728", + "name": "Undead Lumberjack" + }, + { + "id": "5729", + "name": "Undead Lumberjack" + }, + { + "id": "5730", + "name": "Undead Lumberjack" + }, + { + "id": "5731", + "name": "Undead Lumberjack" + }, + { + "id": "5732", + "name": "Undead Lumberjack" + }, + { + "id": "5733", + "name": "Undead Lumberjack" + }, + { + "id": "5734", + "name": "Undead Lumberjack" + }, + { + "id": "5735", + "name": "Undead Lumberjack" + }, + { + "id": "5736", + "name": "Undead Lumberjack" + }, + { + "id": "5737", + "name": "Undead Lumberjack" + }, + { + "id": "5738", + "name": "Undead Lumberjack" + }, + { + "id": "5739", + "name": "Undead Lumberjack" + }, + { + "id": "5740", + "name": "Undead Lumberjack" + }, + { + "id": "5741", + "name": "Undead Lumberjack" + }, + { + "id": "5742", + "name": "Undead Lumberjack" + }, + { + "id": "5743", + "name": "Undead Lumberjack" + }, + { + "id": "5744", + "name": "Undead Lumberjack" + }, + { + "id": "5745", + "name": "Undead Lumberjack" + }, + { + "id": "5746", + "name": "Undead Lumberjack" + }, + { + "id": "5747", + "name": "Undead Lumberjack" + }, + { + "id": "5748", + "name": "Fishing spot" + }, + { + "id": "5749", + "name": "Fishing spot" + }, + { + "id": "5770", + "name": "Ur-zek" + }, + { + "id": "5771", + "name": "Ur-vass" + }, + { + "id": "5772", + "name": "Ur-taal" + }, + { + "id": "5773", + "name": "Ur-meg" + }, + { + "id": "5774", + "name": "Ur-lun" + }, + { + "id": "5775", + "name": "Ur-pel" + }, + { + "id": "5778", + "name": "Bartak" + }, + { + "id": "5779", + "name": "Turgall" + }, + { + "id": "5780", + "name": "Reldak" + }, + { + "id": "5781", + "name": "Miltog" + }, + { + "id": "5782", + "name": "Mernik" + }, + { + "id": "5787", + "name": "Gourmet" + }, + { + "id": "5789", + "name": "Gourmet" + }, + { + "id": "5790", + "name": "Gourmet" + }, + { + "id": "5791", + "name": "Gourmet" + }, + { + "id": "5792", + "name": "Turgok" + }, + { + "id": "5793", + "name": "Markog" + }, + { + "id": "5794", + "name": "Durgok" + }, + { + "id": "5795", + "name": "Tindar" + }, + { + "id": "5796", + "name": "Gundik" + }, + { + "id": "5797", + "name": "Zenkog" + }, + { + "id": "5798", + "name": "Lurgon" + }, + { + "id": "5799", + "name": "Ur-tag" + }, + { + "id": "5802", + "name": "Young 'un" + }, + { + "id": "5804", + "name": "Tyke" + }, + { + "id": "5806", + "name": "Nipper" + }, + { + "id": "5825", + "name": "Movario" + }, + { + "id": "5826", + "name": "Darve" + }, + { + "id": "5828", + "name": "Barlak" + }, + { + "id": "5830", + "name": "Rat Burgiss" + }, + { + "id": "5835", + "name": "Surok Magis" + }, + { + "id": "5836", + "name": "Zaff" + }, + { + "id": "5837", + "name": "Anna Jones" + }, + { + "id": "5838", + "name": "King Roald" + }, + { + "id": "5839", + "name": "Mishkal'un Dorn" + }, + { + "id": "5840", + "name": "Dakh'thoulan Aegis" + }, + { + "id": "5841", + "name": "Sil'as Dahcsnu" + }, + { + "id": "5853", + "name": "Bench" + }, + { + "id": "5857", + "name": "Zanik" + }, + { + "id": "5858", + "name": "Ur-tag" + }, + { + "id": "5862", + "name": "Sigmund and Zanik" + }, + { + "id": "5863", + "name": "Ambassador Alvijar" + }, + { + "id": "5868", + "name": "Tegdak" + }, + { + "id": "5869", + "name": "Zanik" + }, + { + "id": "5871", + "name": "Sergeant Mossfists" + }, + { + "id": "5872", + "name": "Sergeant Slimetoes" + }, + { + "id": "5887", + "name": "Cyrisus" + }, + { + "id": "5894", + "name": "Cyrisus" + }, + { + "id": "5895", + "name": "Cyrisus" + }, + { + "id": "5896", + "name": "Cyrisus" + }, + { + "id": "5897", + "name": "Cyrisus" + }, + { + "id": "5898", + "name": "'Bird's-Eye' Jack" + }, + { + "id": "5899", + "name": "The Inadequacy" + }, + { + "id": "5907", + "name": "The Illusive" + }, + { + "id": "5912", + "name": "Banker" + }, + { + "id": "5913", + "name": "Banker" + }, + { + "id": "5915", + "name": "Elsie" + }, + { + "id": "5918", + "name": "Stray dog" + }, + { + "id": "5932", + "name": "Barnabus Hurma" + }, + { + "id": "5933", + "name": "Marius Giste" + }, + { + "id": "5934", + "name": "Caden Azro" + }, + { + "id": "5935", + "name": "Thias Leacke" + }, + { + "id": "5936", + "name": "Sinco Doar" + }, + { + "id": "5937", + "name": "Tinse Torpe" + }, + { + "id": "5939", + "name": "Torrcs" + }, + { + "id": "5940", + "name": "Marfet" + }, + { + "id": "5941", + "name": "Museum guard" + }, + { + "id": "5942", + "name": "Museum guard" + }, + { + "id": "5943", + "name": "Museum guard" + }, + { + "id": "5946", + "name": "Schoolboy" + }, + { + "id": "5948", + "name": "Teacher and pupil" + }, + { + "id": "5949", + "name": "Schoolboy" + }, + { + "id": "5950", + "name": "Teacher" + }, + { + "id": "5951", + "name": "Schoolgirl" + }, + { + "id": "5953", + "name": "Workman" + }, + { + "id": "5955", + "name": "Workman" + }, + { + "id": "5957", + "name": "Schoolgirl" + }, + { + "id": "5964", + "name": "Ed Wood" + }, + { + "id": "5965", + "name": "Orlando Smith" + }, + { + "id": "5967", + "name": "Natural historian" + }, + { + "id": "5968", + "name": "Natural historian" + }, + { + "id": "5969", + "name": "Natural historian" + }, + { + "id": "5970", + "name": "Natural historian" + }, + { + "id": "5983", + "name": "Schoolgirl" + }, + { + "id": "5984", + "name": "Schoolgirl" + }, + { + "id": "5985", + "name": "Schoolgirl" + }, + { + "id": "5988", + "name": "Miazrqa" + }, + { + "id": "5989", + "name": "Grimgnash" + }, + { + "id": "5991", + "name": "Drain pipe" + }, + { + "id": "5995", + "name": "Mouse" + }, + { + "id": "5997", + "name": "Rupert the Beard" + }, + { + "id": "6000", + "name": "Rupert the Beard" + }, + { + "id": "6002", + "name": "Gnome" + }, + { + "id": "6003", + "name": "Winkin" + }, + { + "id": "6004", + "name": "Gnome" + }, + { + "id": "6005", + "name": "Cage" + }, + { + "id": "6071", + "name": "Immenizz" + }, + { + "id": "6075", + "name": "Cyclops" + }, + { + "id": "6082", + "name": "Captain Ned" + }, + { + "id": "6085", + "name": "Cabin boy Jenkins" + }, + { + "id": "6086", + "name": "Cabin boy Jenkins" + }, + { + "id": "6087", + "name": "Elvarg" + }, + { + "id": "6114", + "name": "Drake" + }, + { + "id": "6119", + "name": "Observatory professor" + }, + { + "id": "6130", + "name": "Clothears" + }, + { + "id": "6138", + "name": "Town crier" + }, + { + "id": "6139", + "name": "Town crier" + }, + { + "id": "6158", + "name": "Sir Lucan" + }, + { + "id": "6160", + "name": "Sir Lancelot" + }, + { + "id": "6161", + "name": "Sir Bedivere" + }, + { + "id": "6162", + "name": "Sir Tristram" + }, + { + "id": "6163", + "name": "Sir Pelleas" + }, + { + "id": "6164", + "name": "Sir Gawain" + }, + { + "id": "6165", + "name": "Sir Kay" + }, + { + "id": "6166", + "name": "Sir Pelleas" + }, + { + "id": "6167", + "name": "Sir Gawain" + }, + { + "id": "6168", + "name": "Sir Kay" + }, + { + "id": "6171", + "name": "Sir Kay" + }, + { + "id": "6172", + "name": "Sir Gawain" + }, + { + "id": "6173", + "name": "Sir Lucan" + }, + { + "id": "6174", + "name": "Bandit" + }, + { + "id": "6175", + "name": "Sir Tristram" + }, + { + "id": "6176", + "name": "Sir Pelleas" + }, + { + "id": "6177", + "name": "Sir Bedivere" + }, + { + "id": "6178", + "name": "Anna" + }, + { + "id": "6179", + "name": "David" + }, + { + "id": "6180", + "name": "Anna" + }, + { + "id": "6181", + "name": "Court judge" + }, + { + "id": "6182", + "name": "Jury" + }, + { + "id": "6185", + "name": "Prosecutor" + }, + { + "id": "6186", + "name": "Morgan Le Faye" + }, + { + "id": "6191", + "name": "Sinclair" + }, + { + "id": "6199", + "name": "Banker" + }, + { + "id": "6202", + "name": "K'ril Tsutsaroth" + }, + { + "id": "6284", + "name": "Warped terrorbird" + }, + { + "id": "6298", + "name": "Jeffery" + }, + { + "id": "6299", + "name": "Big monolith" + }, + { + "id": "6300", + "name": "Small monolith" + }, + { + "id": "6301", + "name": "Cute creature" + }, + { + "id": "6302", + "name": "Evil creature" + }, + { + "id": "6303", + "name": "Yewnock the engineer" + }, + { + "id": "6304", + "name": "Bolrie" + }, + { + "id": "6305", + "name": "Hazelmere" + }, + { + "id": "6307", + "name": "Advisor" + }, + { + "id": "6308", + "name": "King Argenthorg" + }, + { + "id": "6309", + "name": "Prince Argenthorg" + }, + { + "id": "6310", + "name": "Cute creature" + }, + { + "id": "6312", + "name": "Evil creature" + }, + { + "id": "6313", + "name": "Terrorbird servant" + }, + { + "id": "6316", + "name": "Guard no. 21" + }, + { + "id": "6317", + "name": "Guard no. 72" + }, + { + "id": "6318", + "name": "Longramble" + }, + { + "id": "6319", + "name": "Spirit tree" + }, + { + "id": "6321", + "name": "Spirit tree" + }, + { + "id": "6333", + "name": "Child" + }, + { + "id": "6340", + "name": "Child" + }, + { + "id": "6341", + "name": "Child" + }, + { + "id": "6342", + "name": "Child" + }, + { + "id": "6343", + "name": "Child" + }, + { + "id": "6345", + "name": "Child" + }, + { + "id": "6357", + "name": "Street urchin" + }, + { + "id": "6359", + "name": "Street urchin" + }, + { + "id": "6360", + "name": "Street urchin" + }, + { + "id": "6361", + "name": "Street urchin" + }, + { + "id": "6362", + "name": "Eniola" + }, + { + "id": "6373", + "name": "Kennith" + }, + { + "id": "6375", + "name": "Wizard Cromperty" + }, + { + "id": "6384", + "name": "Karamjan Jungle Eagle" + }, + { + "id": "6386", + "name": "Bandit" + }, + { + "id": "6391", + "name": "Glough" + }, + { + "id": "6392", + "name": "Oldak" + }, + { + "id": "6393", + "name": "Zanik" + }, + { + "id": "6394", + "name": "Zanik" + }, + { + "id": "6396", + "name": "Zanik" + }, + { + "id": "6398", + "name": "Zanik" + }, + { + "id": "6400", + "name": "Oldak" + }, + { + "id": "6468", + "name": "Skoblin" + }, + { + "id": "6474", + "name": "Snothead" + }, + { + "id": "6475", + "name": "Snailfeet" + }, + { + "id": "6476", + "name": "Mosschin" + }, + { + "id": "6477", + "name": "Redeyes" + }, + { + "id": "6478", + "name": "Strongbones" + }, + { + "id": "6479", + "name": "Grubfoot" + }, + { + "id": "6480", + "name": "Grubfoot" + }, + { + "id": "6483", + "name": "Priest" + }, + { + "id": "6484", + "name": "Priest" + }, + { + "id": "6485", + "name": "Priest" + }, + { + "id": "6486", + "name": "Priest" + }, + { + "id": "6487", + "name": "Priest" + }, + { + "id": "6489", + "name": "High priest" + }, + { + "id": "6505", + "name": "Registrar 1" + }, + { + "id": "6511", + "name": "Jury" + }, + { + "id": "6513", + "name": "Spectator" + }, + { + "id": "6515", + "name": "Spectator" + }, + { + "id": "6517", + "name": "Spectator" + }, + { + "id": "6519", + "name": "Spectator" + }, + { + "id": "6520", + "name": "Head Registrar" + }, + { + "id": "6537", + "name": "Mandrith" + }, + { + "id": "6538", + "name": "Banker" + }, + { + "id": "6539", + "name": "Charley the Cleaner" + }, + { + "id": "6540", + "name": "Scotty the Cleaner" + }, + { + "id": "6541", + "name": "Sanchez the Cleaner" + }, + { + "id": "6542", + "name": "Summer Bonde" + }, + { + "id": "6566", + "name": "Broken grave marker" + }, + { + "id": "6567", + "name": "Collapsing grave marker" + }, + { + "id": "6568", + "name": "Grave marker" + }, + { + "id": "6569", + "name": "Broken grave marker" + }, + { + "id": "6570", + "name": "Collapsing grave marker" + }, + { + "id": "6571", + "name": "Gravestone" + }, + { + "id": "6572", + "name": "Broken gravestone" + }, + { + "id": "6573", + "name": "Collapsing gravestone" + }, + { + "id": "6574", + "name": "Gravestone" + }, + { + "id": "6575", + "name": "Broken gravestone" + }, + { + "id": "6576", + "name": "Collapsing gravestone" + }, + { + "id": "6577", + "name": "Gravestone" + }, + { + "id": "6578", + "name": "Broken gravestone" + }, + { + "id": "6579", + "name": "Collapsing gravestone" + }, + { + "id": "6580", + "name": "Stele" + }, + { + "id": "6581", + "name": "Broken stele" + }, + { + "id": "6582", + "name": "Collapsing stele" + }, + { + "id": "6583", + "name": "Saradomin symbol" + }, + { + "id": "6584", + "name": "Broken Saradomin symbol" + }, + { + "id": "6585", + "name": "Collapsing Saradomin symbol" + }, + { + "id": "6586", + "name": "Zamorak symbol" + }, + { + "id": "6587", + "name": "Broken Zamorak symbol" + }, + { + "id": "6588", + "name": "Collapsing Zamorak symbol" + }, + { + "id": "6589", + "name": "Guthix symbol" + }, + { + "id": "6590", + "name": "Broken Guthix symbol" + }, + { + "id": "6591", + "name": "Collapsing Guthix symbol" + }, + { + "id": "6592", + "name": "Bandos symbol" + }, + { + "id": "6593", + "name": "Broken Bandos symbol" + }, + { + "id": "6594", + "name": "Collapsing Bandos symbol" + }, + { + "id": "6595", + "name": "Armadyl symbol" + }, + { + "id": "6596", + "name": "Broken Armadyl symbol" + }, + { + "id": "6597", + "name": "Collapsing Armadyl symbol" + }, + { + "id": "6598", + "name": "Memorial stone" + }, + { + "id": "6599", + "name": "Broken memorial stone" + }, + { + "id": "6600", + "name": "Collapsing memorial stone" + }, + { + "id": "6601", + "name": "Memorial stone" + }, + { + "id": "6602", + "name": "Broken memorial stone" + }, + { + "id": "6603", + "name": "Collapsing memorial stone" + }, + { + "id": "6732", + "name": "Snow imp" + }, + { + "id": "6733", + "name": "Snow imp" + }, + { + "id": "6734", + "name": "Snow imp" + }, + { + "id": "6735", + "name": "Snow imp" + }, + { + "id": "6736", + "name": "Snow imp" + }, + { + "id": "6737", + "name": "Snow imp" + }, + { + "id": "6738", + "name": "Snow imp" + }, + { + "id": "6741", + "name": "Snow" + }, + { + "id": "6746", + "name": "Snowman" + }, + { + "id": "6751", + "name": "Bulldog" + }, + { + "id": "6753", + "name": "Mummy" + }, + { + "id": "6754", + "name": "Mummy" + }, + { + "id": "6755", + "name": "Mummy" + }, + { + "id": "6756", + "name": "Mummy" + }, + { + "id": "6757", + "name": "Mummy" + }, + { + "id": "6758", + "name": "Mummy" + }, + { + "id": "6759", + "name": "Mummy" + }, + { + "id": "6760", + "name": "Mummy" + }, + { + "id": "6771", + "name": "Giant scarab" + }, + { + "id": "6775", + "name": "Scabaras priest" + }, + { + "id": "6782", + "name": "Maisa" + }, + { + "id": "6783", + "name": "Maisa" + }, + { + "id": "6784", + "name": "Priest" + }, + { + "id": "6791", + "name": "High Priest of Scabaras" + }, + { + "id": "6792", + "name": "Vulture" + }, + { + "id": "6793", + "name": "Spirit terrorbird" + }, + { + "id": "6808", + "name": "Beaver" + }, + { + "id": "6898", + "name": "Pet shop owner" + }, + { + "id": "6899", + "name": "Bulldog" + }, + { + "id": "6908", + "name": "Baby penguin" + }, + { + "id": "6909", + "name": "Penguin" + }, + { + "id": "6910", + "name": "Penguin" + }, + { + "id": "6911", + "name": "Raven chick" + }, + { + "id": "6912", + "name": "Raven" + }, + { + "id": "6913", + "name": "Baby raccoon" + }, + { + "id": "6914", + "name": "Raccoon" + }, + { + "id": "6915", + "name": "Baby gecko" + }, + { + "id": "6916", + "name": "Gecko" + }, + { + "id": "6918", + "name": "Gecko" + }, + { + "id": "6919", + "name": "Baby squirrel" + }, + { + "id": "6920", + "name": "Squirrel" + }, + { + "id": "6922", + "name": "Baby chameleon" + }, + { + "id": "6923", + "name": "Chameleon" + }, + { + "id": "6924", + "name": "Baby chameleon" + }, + { + "id": "6925", + "name": "Chameleon" + }, + { + "id": "6926", + "name": "Baby chameleon" + }, + { + "id": "6927", + "name": "Chameleon" + }, + { + "id": "6928", + "name": "Baby chameleon" + }, + { + "id": "6929", + "name": "Chameleon" + }, + { + "id": "6930", + "name": "Baby chameleon" + }, + { + "id": "6931", + "name": "Chameleon" + }, + { + "id": "6932", + "name": "Baby chameleon" + }, + { + "id": "6933", + "name": "Chameleon" + }, + { + "id": "6934", + "name": "Baby chameleon" + }, + { + "id": "6935", + "name": "Chameleon" + }, + { + "id": "6936", + "name": "Baby chameleon" + }, + { + "id": "6937", + "name": "Chameleon" + }, + { + "id": "6938", + "name": "Baby chameleon" + }, + { + "id": "6939", + "name": "Chameleon" + }, + { + "id": "6940", + "name": "Baby chameleon" + }, + { + "id": "6941", + "name": "Chameleon" + }, + { + "id": "6945", + "name": "Vulture chick" + }, + { + "id": "6946", + "name": "Vulture" + }, + { + "id": "6947", + "name": "Baby giant crab" + }, + { + "id": "6948", + "name": "Giant crab" + }, + { + "id": "6949", + "name": "Saradomin chick" + }, + { + "id": "6950", + "name": "Saradomin bird" + }, + { + "id": "6951", + "name": "Saradomin owl" + }, + { + "id": "6952", + "name": "Zamorak chick" + }, + { + "id": "6953", + "name": "Zamorak bird" + }, + { + "id": "6954", + "name": "Zamorak hawk" + }, + { + "id": "6955", + "name": "Guthix chick" + }, + { + "id": "6956", + "name": "Guthix bird" + }, + { + "id": "6957", + "name": "Guthix raptor" + }, + { + "id": "6970", + "name": "Pikkupstix" + }, + { + "id": "6988", + "name": "Giant wolpertinger" + }, + { + "id": "6991", + "name": "Ibis" + }, + { + "id": "6996", + "name": "Fishing spot" + }, + { + "id": "7000", + "name": "Dark Squall" + }, + { + "id": "7002", + "name": "Surok Magis" + }, + { + "id": "7006", + "name": "Grenwall" + }, + { + "id": "7015", + "name": "Platypus" + }, + { + "id": "7016", + "name": "Platypus" + }, + { + "id": "7017", + "name": "Platypus" + }, + { + "id": "7018", + "name": "Baby platypus" + }, + { + "id": "7019", + "name": "Baby platypus" + }, + { + "id": "7020", + "name": "Baby platypus" + }, + { + "id": "7022", + "name": "Platypus" + }, + { + "id": "7023", + "name": "Platypus" + }, + { + "id": "7025", + "name": "Baby platypus" + }, + { + "id": "7026", + "name": "Baby platypus" + }, + { + "id": "7027", + "name": "Patrick" + }, + { + "id": "7028", + "name": "Penelope" + }, + { + "id": "7029", + "name": "Peter" + }, + { + "id": "7030", + "name": "Peanut" + }, + { + "id": "7032", + "name": "Diseased kebbit" + }, + { + "id": "7040", + "name": "Fishing spot" + }, + { + "id": "7045", + "name": "Fishing spot" + }, + { + "id": "7046", + "name": "Fishing spot" + }, + { + "id": "7048", + "name": "Frawd" + }, + { + "id": "7050", + "name": "Ogress banker" + }, + { + "id": "7052", + "name": "Seegud" + }, + { + "id": "7053", + "name": "Chargurr" + }, + { + "id": "7054", + "name": "Chargurr" + }, + { + "id": "7055", + "name": "Snurgh" + }, + { + "id": "7058", + "name": "Kringk" + }, + { + "id": "7059", + "name": "Thump" + }, + { + "id": "7060", + "name": "Massage table" + }, + { + "id": "7061", + "name": "Thump" + }, + { + "id": "7062", + "name": "Muggh" + }, + { + "id": "7063", + "name": "Kringk" + }, + { + "id": "7064", + "name": "Hairdryer" + }, + { + "id": "7065", + "name": "Snert" + }, + { + "id": "7068", + "name": "Tyke" + }, + { + "id": "7069", + "name": "Snarrl" + }, + { + "id": "7070", + "name": "Snarrk" + }, + { + "id": "7071", + "name": "I'rk" + }, + { + "id": "7072", + "name": "Thuddley" + }, + { + "id": "7073", + "name": "Grr'bah" + }, + { + "id": "7074", + "name": "Chomp" + }, + { + "id": "7075", + "name": "Grubb" + }, + { + "id": "7076", + "name": "Grunther" + }, + { + "id": "7077", + "name": "Glum" + }, + { + "id": "7083", + "name": "Flying bugs" + }, + { + "id": "7087", + "name": "Balnea" + }, + { + "id": "7088", + "name": "Chief Tess" + }, + { + "id": "7089", + "name": "Chargurr" + }, + { + "id": "7090", + "name": "Wise Old Man" + }, + { + "id": "7091", + "name": "Dawg" + }, + { + "id": "7116", + "name": "Drunken sailor" + }, + { + "id": "7117", + "name": "Drunken sailor" + }, + { + "id": "7118", + "name": "Catapult engineer" + }, + { + "id": "7119", + "name": "Tyras guard" + }, + { + "id": "7121", + "name": "General Hining" + }, + { + "id": "7122", + "name": "Githan" + }, + { + "id": "7123", + "name": "Amulet of Nature" + }, + { + "id": "7124", + "name": "Mud" + }, + { + "id": "7136", + "name": "Surok Magis" + }, + { + "id": "7143", + "name": "Professor Henry" + }, + { + "id": "7163", + "name": "Villager" + }, + { + "id": "7165", + "name": "Villager" + }, + { + "id": "7166", + "name": "Villager" + }, + { + "id": "7167", + "name": "Villager" + }, + { + "id": "7169", + "name": "Kimberly" + }, + { + "id": "7170", + "name": "Kimberly" + }, + { + "id": "7171", + "name": "Kennith" + }, + { + "id": "7172", + "name": "Kennith" + }, + { + "id": "7173", + "name": "Kennith" + }, + { + "id": "7174", + "name": "Kennith" + }, + { + "id": "7175", + "name": "Kennith" + }, + { + "id": "7176", + "name": "Villager" + }, + { + "id": "7184", + "name": "Ezekial Lovecraft" + }, + { + "id": "7185", + "name": "Clive" + }, + { + "id": "7186", + "name": "Katherine" + }, + { + "id": "7187", + "name": "Katherine" + }, + { + "id": "7188", + "name": "Clive" + }, + { + "id": "7189", + "name": "Kent" + }, + { + "id": "7190", + "name": "Rabbit hole" + }, + { + "id": "7197", + "name": "Easter Bunny" + }, + { + "id": "7198", + "name": "Bunny" + }, + { + "id": "7199", + "name": "Bunny" + }, + { + "id": "7200", + "name": "Guard bunny" + }, + { + "id": "7201", + "name": "Chocatrice" + }, + { + "id": "7203", + "name": "Void Knight" + }, + { + "id": "7205", + "name": "Mouse" + }, + { + "id": "7208", + "name": "Rabbit" + }, + { + "id": "7261", + "name": "Raven chick" + }, + { + "id": "7262", + "name": "Raven" + }, + { + "id": "7263", + "name": "Raven chick" + }, + { + "id": "7264", + "name": "Raven" + }, + { + "id": "7265", + "name": "Raven chick" + }, + { + "id": "7266", + "name": "Raven" + }, + { + "id": "7267", + "name": "Raven chick" + }, + { + "id": "7268", + "name": "Raven" + }, + { + "id": "7269", + "name": "Raven chick" + }, + { + "id": "7270", + "name": "Raven" + }, + { + "id": "7271", + "name": "Baby raccoon" + }, + { + "id": "7272", + "name": "Raccoon" + }, + { + "id": "7273", + "name": "Baby raccoon" + }, + { + "id": "7274", + "name": "Raccoon" + }, + { + "id": "7276", + "name": "Baby raccoon" + }, + { + "id": "7277", + "name": "Baby gecko" + }, + { + "id": "7278", + "name": "Baby gecko" + }, + { + "id": "7279", + "name": "Baby gecko" + }, + { + "id": "7280", + "name": "Baby gecko" + }, + { + "id": "7281", + "name": "Gecko" + }, + { + "id": "7282", + "name": "Gecko" + }, + { + "id": "7283", + "name": "Gecko" + }, + { + "id": "7284", + "name": "Gecko" + }, + { + "id": "7286", + "name": "Baby gecko" + }, + { + "id": "7287", + "name": "Baby gecko" + }, + { + "id": "7288", + "name": "Baby gecko" + }, + { + "id": "7289", + "name": "Gecko" + }, + { + "id": "7290", + "name": "Gecko" + }, + { + "id": "7291", + "name": "Gecko" + }, + { + "id": "7292", + "name": "Gecko" + }, + { + "id": "7293", + "name": "Baby giant crab" + }, + { + "id": "7294", + "name": "Giant crab" + }, + { + "id": "7295", + "name": "Baby giant crab" + }, + { + "id": "7296", + "name": "Giant crab" + }, + { + "id": "7297", + "name": "Baby giant crab" + }, + { + "id": "7298", + "name": "Giant crab" + }, + { + "id": "7299", + "name": "Baby giant crab" + }, + { + "id": "7300", + "name": "Giant crab" + }, + { + "id": "7301", + "name": "Baby squirrel" + }, + { + "id": "7302", + "name": "Squirrel" + }, + { + "id": "7303", + "name": "Baby squirrel" + }, + { + "id": "7304", + "name": "Squirrel" + }, + { + "id": "7305", + "name": "Baby squirrel" + }, + { + "id": "7306", + "name": "Squirrel" + }, + { + "id": "7307", + "name": "Baby squirrel" + }, + { + "id": "7308", + "name": "Squirrel" + }, + { + "id": "7309", + "name": "Baby squirrel" + }, + { + "id": "7310", + "name": "Baby squirrel" + }, + { + "id": "7311", + "name": "Baby squirrel" + }, + { + "id": "7312", + "name": "Baby squirrel" + }, + { + "id": "7313", + "name": "Baby penguin" + }, + { + "id": "7314", + "name": "Penguin" + }, + { + "id": "7315", + "name": "Penguin" + }, + { + "id": "7316", + "name": "Baby penguin" + }, + { + "id": "7317", + "name": "Penguin" + }, + { + "id": "7318", + "name": "Penguin" + }, + { + "id": "7319", + "name": "Vulture chick" + }, + { + "id": "7320", + "name": "Vulture" + }, + { + "id": "7321", + "name": "Vulture chick" + }, + { + "id": "7322", + "name": "Vulture" + }, + { + "id": "7323", + "name": "Vulture chick" + }, + { + "id": "7324", + "name": "Vulture" + }, + { + "id": "7325", + "name": "Vulture chick" + }, + { + "id": "7326", + "name": "Vulture" + }, + { + "id": "7327", + "name": "Vulture chick" + }, + { + "id": "7328", + "name": "Vulture" + }, + { + "id": "7369", + "name": "Void shifter" + }, + { + "id": "7372", + "name": "Ravenous locust" + }, + { + "id": "7383", + "name": "Uberlass" + }, + { + "id": "7384", + "name": "Uberlass" + }, + { + "id": "7385", + "name": "Uberlass" + }, + { + "id": "7386", + "name": "Uberlass" + }, + { + "id": "7387", + "name": "Sannytea" + }, + { + "id": "7388", + "name": "Sannytea" + }, + { + "id": "7389", + "name": "Irollsixes" + }, + { + "id": "7390", + "name": "Irollsixes" + }, + { + "id": "7391", + "name": "Foxyhunter" + }, + { + "id": "7392", + "name": "Foxyhunter" + }, + { + "id": "7393", + "name": "Foxyhunter" + }, + { + "id": "7394", + "name": "Gabriela" + }, + { + "id": "7395", + "name": "Teodor" + }, + { + "id": "7396", + "name": "Aurel" + }, + { + "id": "7397", + "name": "Cornelius" + }, + { + "id": "7399", + "name": "Sorin" + }, + { + "id": "7400", + "name": "Luscion" + }, + { + "id": "7401", + "name": "Sergiu" + }, + { + "id": "7402", + "name": "Radu" + }, + { + "id": "7403", + "name": "Grigore" + }, + { + "id": "7404", + "name": "Ileana" + }, + { + "id": "7405", + "name": "Valeria" + }, + { + "id": "7406", + "name": "Emilia" + }, + { + "id": "7407", + "name": "Florin" + }, + { + "id": "7408", + "name": "Catalina" + }, + { + "id": "7409", + "name": "Ivan" + }, + { + "id": "7410", + "name": "Victor" + }, + { + "id": "7411", + "name": "Helena" + }, + { + "id": "7412", + "name": "Mihail" + }, + { + "id": "7413", + "name": "Nicoleta" + }, + { + "id": "7414", + "name": "Vasile" + }, + { + "id": "7415", + "name": "Razvan" + }, + { + "id": "7416", + "name": "Luminata" + }, + { + "id": "7418", + "name": "Juvinate" + }, + { + "id": "7419", + "name": "Held vampyre juvinate" + }, + { + "id": "7420", + "name": "Hieronymus Avlafrim" + }, + { + "id": "7421", + "name": "Sasquine Huburns" + }, + { + "id": "7422", + "name": "Sasquine Huburns" + }, + { + "id": "7423", + "name": "Lollery" + }, + { + "id": "7424", + "name": "Wigglewoo" + }, + { + "id": "7427", + "name": "Orangeowns" + }, + { + "id": "7428", + "name": "I like m0m" + }, + { + "id": "7429", + "name": "I like m0m" + }, + { + "id": "7430", + "name": "Qutiedoll" + }, + { + "id": "7431", + "name": "Goreu" + }, + { + "id": "7432", + "name": "Ysgawyn" + }, + { + "id": "7433", + "name": "Arvel" + }, + { + "id": "7434", + "name": "Mawrth" + }, + { + "id": "7435", + "name": "Kelyn" + }, + { + "id": "7436", + "name": "Eoin" + }, + { + "id": "7437", + "name": "Iona" + }, + { + "id": "7442", + "name": "Arianwyn" + }, + { + "id": "7444", + "name": "Oronwen" + }, + { + "id": "7445", + "name": "Banker" + }, + { + "id": "7446", + "name": "Banker" + }, + { + "id": "7447", + "name": "Dalldav" + }, + { + "id": "7448", + "name": "Gethin" + }, + { + "id": "7449", + "name": "Amaethwr" + }, + { + "id": "7450", + "name": "Teclyn" + }, + { + "id": "7451", + "name": "Butterfly" + }, + { + "id": "7452", + "name": "Lapsang" + }, + { + "id": "7453", + "name": "Lapsang" + }, + { + "id": "7454", + "name": "Souchong" + }, + { + "id": "7455", + "name": "Souchong" + }, + { + "id": "7456", + "name": "Earlgrey" + }, + { + "id": "7457", + "name": "Earlgrey" + }, + { + "id": "7458", + "name": "Fairtrade" + }, + { + "id": "7464", + "name": "Sliceoflemon" + }, + { + "id": "7465", + "name": "Sliceoflemon" + }, + { + "id": "7466", + "name": "Milknosugar" + }, + { + "id": "7467", + "name": "Milknosugar" + }, + { + "id": "7468", + "name": "Randomdood" + }, + { + "id": "7469", + "name": "Employedman" + }, + { + "id": "7470", + "name": "Heidiggle" + }, + { + "id": "7471", + "name": "Dodgy Penny" + }, + { + "id": "7472", + "name": "Shadydude98" + }, + { + "id": "7473", + "name": "Madam C" + }, + { + "id": "7474", + "name": "M0m Online" + }, + { + "id": "7478", + "name": "Learking" + }, + { + "id": "7489", + "name": "Moglewee" + }, + { + "id": "7490", + "name": "Moglewee" + }, + { + "id": "7491", + "name": "Sarah Domin" + }, + { + "id": "7498", + "name": "Snowy knight" + }, + { + "id": "7499", + "name": "Sapphire glacialis" + }, + { + "id": "7509", + "name": "Evil Wibbler" + }, + { + "id": "7516", + "name": "Heresjohnny" + }, + { + "id": "7517", + "name": "Mogglewump" + }, + { + "id": "7521", + "name": "Renderorder" + }, + { + "id": "7522", + "name": "Boolean" + }, + { + "id": "7523", + "name": "Stress Diva" + }, + { + "id": "7524", + "name": "Treadsoftly" + }, + { + "id": "7525", + "name": "Helphelphelp" + }, + { + "id": "7526", + "name": "Doorbellpl0x" + }, + { + "id": "7527", + "name": "Fixmydoorup" + }, + { + "id": "7529", + "name": "Wallscaler" + }, + { + "id": "7530", + "name": "2scompany" + }, + { + "id": "7531", + "name": "2scompany" + }, + { + "id": "7533", + "name": "4sjustsilly" + }, + { + "id": "7534", + "name": "Roadblocked" + }, + { + "id": "7535", + "name": "Barricade" + }, + { + "id": "7536", + "name": "Barricade" + }, + { + "id": "7537", + "name": "Yoinker" + }, + { + "id": "7538", + "name": "Yoinker" + }, + { + "id": "7539", + "name": "Stopthief" + }, + { + "id": "7540", + "name": "Stopthief" + }, + { + "id": "7541", + "name": "Knickknack" + }, + { + "id": "7542", + "name": "Paddywhack" + }, + { + "id": "7543", + "name": "Giveadog" + }, + { + "id": "7544", + "name": "Spacebadgers" + }, + { + "id": "7545", + "name": "Freakypeaky" + }, + { + "id": "7546", + "name": "Rollinghome" + }, + { + "id": "7547", + "name": "Nullpointer" + }, + { + "id": "7548", + "name": "Badgerfreak" + }, + { + "id": "7549", + "name": "Windstrike32" + }, + { + "id": "7550", + "name": "Void Knight" + }, + { + "id": "7567", + "name": "Wraithboss" + }, + { + "id": "7568", + "name": "What Goudron" + }, + { + "id": "7574", + "name": "Lvzyoda" + }, + { + "id": "7575", + "name": "Airstriker" + }, + { + "id": "7576", + "name": "Droepedoff" + }, + { + "id": "7577", + "name": "Plzpudding" + }, + { + "id": "7578", + "name": "Assassin10" + }, + { + "id": "7579", + "name": "Steallake" + }, + { + "id": "7581", + "name": "Deepkiwi" + }, + { + "id": "7584", + "name": "Bigface Oz" + }, + { + "id": "7587", + "name": "Torcher" + }, + { + "id": "7588", + "name": "Torcher" + }, + { + "id": "7589", + "name": "Defiler" + }, + { + "id": "7590", + "name": "Defiler" + }, + { + "id": "7591", + "name": "Shifter" + }, + { + "id": "7592", + "name": "Shifter" + }, + { + "id": "7594", + "name": "Shifter" + }, + { + "id": "7595", + "name": "Splatter" + }, + { + "id": "7596", + "name": "Splatter" + }, + { + "id": "7597", + "name": "Splatter" + }, + { + "id": "7598", + "name": "Spinner" + }, + { + "id": "7599", + "name": "Ravager" + }, + { + "id": "7600", + "name": "Fiara" + }, + { + "id": "7601", + "name": "Reggie" + }, + { + "id": "7602", + "name": "Getorix" + }, + { + "id": "7603", + "name": "Pontimer" + }, + { + "id": "7604", + "name": "Alran" + }, + { + "id": "7610", + "name": "Flying female vampire" + }, + { + "id": "7611", + "name": "Flying female vampire" + }, + { + "id": "7612", + "name": "Flying female vampire" + }, + { + "id": "7613", + "name": "Flying female vampire" + }, + { + "id": "7622", + "name": "Vyrewatch" + }, + { + "id": "7623", + "name": "Vyrewatch" + }, + { + "id": "7624", + "name": "Vyrewatch" + }, + { + "id": "7625", + "name": "Vyrewatch" + }, + { + "id": "7630", + "name": "Vyrewatch" + }, + { + "id": "7633", + "name": "Vyrewatch" + }, + { + "id": "7636", + "name": "Fishing spot" + }, + { + "id": "7637", + "name": "Skeletal hand" + }, + { + "id": "7652", + "name": "Zaromark Sliver" + }, + { + "id": "7653", + "name": "Zaromark Sliver" + }, + { + "id": "7662", + "name": "Fistandantilus" + }, + { + "id": "7663", + "name": "Fistandantilus" + }, + { + "id": "7664", + "name": "Mercenary Adventurer" + }, + { + "id": "7665", + "name": "Ivan Strom" + }, + { + "id": "7666", + "name": "Mysterious person" + }, + { + "id": "7667", + "name": "Mysterious person" + }, + { + "id": "7668", + "name": "Mysterious person" + }, + { + "id": "7669", + "name": "Mysterious person" + }, + { + "id": "7670", + "name": "Mysterious person" + }, + { + "id": "7671", + "name": "Mysterious person" + }, + { + "id": "7672", + "name": "Flaygian Screwte" + }, + { + "id": "7673", + "name": "Mekritus A'hara" + }, + { + "id": "7674", + "name": "Andiess Juip" + }, + { + "id": "7675", + "name": "Kael Forshaw" + }, + { + "id": "7676", + "name": "Andiess Juip" + }, + { + "id": "7677", + "name": "Kael Forshaw" + }, + { + "id": "7678", + "name": "Safalaan" + }, + { + "id": "7679", + "name": "Andiess Juip" + }, + { + "id": "7680", + "name": "Kael Forshaw" + }, + { + "id": "7681", + "name": "Safalaan" + }, + { + "id": "7684", + "name": "Vyrewatch" + }, + { + "id": "7685", + "name": "Vyrewatch" + }, + { + "id": "7686", + "name": "Safalaan" + }, + { + "id": "7687", + "name": "Spectral Vyrewatch" + }, + { + "id": "7688", + "name": "Drezel" + }, + { + "id": "7708", + "name": "Temple guardian" + }, + { + "id": "7712", + "name": "Baby icefiend" + }, + { + "id": "7718", + "name": "Brother Bordiss" + }, + { + "id": "7719", + "name": "Brother Althric" + }, + { + "id": "7720", + "name": "Drorkar" + }, + { + "id": "7721", + "name": "Nurmof" + }, + { + "id": "7722", + "name": "Lakki the delivery dwarf" + }, + { + "id": "7723", + "name": "Drorkar" + }, + { + "id": "7724", + "name": "Brother Bordiss" + }, + { + "id": "7725", + "name": "Professor Arblenap" + }, + { + "id": "7726", + "name": "Assistant" + }, + { + "id": "7728", + "name": "Baby icefiend" + }, + { + "id": "7737", + "name": "Will" + }, + { + "id": "7738", + "name": "Will" + }, + { + "id": "7739", + "name": "Phil" + }, + { + "id": "7742", + "name": "Fluffs" + }, + { + "id": "7743", + "name": "Fluffs" + }, + { + "id": "7744", + "name": "Kittens" + }, + { + "id": "7746", + "name": "TzHaar-Mej-Malk" + }, + { + "id": "7748", + "name": "TzHaar-Hur-Frok" + }, + { + "id": "7749", + "name": "TzHaar-Ket-Grol" + }, + { + "id": "7750", + "name": "TzHaar-Ket-Rok" + }, + { + "id": "7751", + "name": "TzHaar-Ket-Lurk" + }, + { + "id": "7753", + "name": "TzHaar-Mej" + }, + { + "id": "7754", + "name": "TzHaar-Hur" + }, + { + "id": "7755", + "name": "TzHaar-Xil" + }, + { + "id": "7757", + "name": "TzHaar-Hur-Brekt" + }, + { + "id": "7758", + "name": "TzHaar-Hur-Brekt" + }, + { + "id": "7759", + "name": "TzHaar-Ket-Jok" + }, + { + "id": "7760", + "name": "TzHaar-Ket-Jok" + }, + { + "id": "7761", + "name": "TzHaar-Xil-Mor" + }, + { + "id": "7762", + "name": "TzHaar-Xil-Mor" + }, + { + "id": "7763", + "name": "TzHaar-Mej-Kol" + }, + { + "id": "7764", + "name": "TzHaar-Mej-Kol" + }, + { + "id": "7765", + "name": "TzHaar-Hur-Klag" + }, + { + "id": "7766", + "name": "TzHaar-Hur-Klag" + }, + { + "id": "7770", + "name": "TokTz-Ket-Dill" + }, + { + "id": "7771", + "name": "TokTz-Ket-Dill" + }, + { + "id": "7774", + "name": "Skeleton" + }, + { + "id": "7775", + "name": "Skeleton" + }, + { + "id": "7776", + "name": "Skeleton" + }, + { + "id": "7777", + "name": "Skeleton" + }, + { + "id": "7778", + "name": "Skeleton" + }, + { + "id": "7779", + "name": "Sumona" + }, + { + "id": "7781", + "name": "Jesmona" + }, + { + "id": "7782", + "name": "Catolax" + }, + { + "id": "7783", + "name": "Ali Cat" + }, + { + "id": "7787", + "name": "Cave crawler" + }, + { + "id": "7788", + "name": "Skeleton" + }, + { + "id": "7789", + "name": "Zombie" + }, + { + "id": "7790", + "name": "Zombie" + }, + { + "id": "7791", + "name": "Zombie" + }, + { + "id": "7792", + "name": "Zombie" + }, + { + "id": "7793", + "name": "Banshee mistress" + }, + { + "id": "7794", + "name": "Banshee mistress" + }, + { + "id": "7795", + "name": "Insectoid assassin" + }, + { + "id": "7796", + "name": "Insectoid assassin" + }, + { + "id": "7797", + "name": "Kurask overlord" + }, + { + "id": "7798", + "name": "Monstrous cave crawler" + }, + { + "id": "7799", + "name": "Basilisk boss" + }, + { + "id": "7800", + "name": "Mightiest turoth" + }, + { + "id": "7801", + "name": "Aberrant spectre" + }, + { + "id": "7802", + "name": "Aberrant spectre" + }, + { + "id": "7803", + "name": "Aberrant spectre" + }, + { + "id": "7804", + "name": "Aberrant spectre" + }, + { + "id": "7805", + "name": "Kurask minion" + }, + { + "id": "7806", + "name": "Mummy warrior" + }, + { + "id": "7807", + "name": "Mummy warrior" + }, + { + "id": "7808", + "name": "Mummy warrior" + }, + { + "id": "7809", + "name": "Cat" + }, + { + "id": "7810", + "name": "Banshee" + }, + { + "id": "7811", + "name": "Kurask" + }, + { + "id": "7812", + "name": "Cave crawler" + }, + { + "id": "7813", + "name": "Basilisk" + }, + { + "id": "7814", + "name": "Turoth" + }, + { + "id": "7815", + "name": "Skeleton" + }, + { + "id": "7816", + "name": "Master" + }, + { + "id": "7817", + "name": "Zombie" + }, + { + "id": "7818", + "name": "Zombie" + }, + { + "id": "7819", + "name": "Zombie" + }, + { + "id": "7820", + "name": "Zombie" + }, + { + "id": "7821", + "name": "A wanderer." + }, + { + "id": "7822", + "name": "A wanderer." + }, + { + "id": "7824", + "name": "Osman" + }, + { + "id": "7825", + "name": "50 Ships Mufassah" + }, + { + "id": "7826", + "name": "Karamthulhu" + }, + { + "id": "7827", + "name": "Karamthulhu" + }, + { + "id": "7828", + "name": "Giant lobster" + }, + { + "id": "7829", + "name": "Giant crab" + }, + { + "id": "7830", + "name": "Customs Sergeant" + }, + { + "id": "7831", + "name": "Customs Sergeant" + }, + { + "id": "7832", + "name": "Young Ralph" + }, + { + "id": "7833", + "name": "Young Ralph" + }, + { + "id": "7834", + "name": "Young Ralph" + }, + { + "id": "7835", + "name": "Young Ralph" + }, + { + "id": "7836", + "name": "Young Ralph" + }, + { + "id": "7837", + "name": "Customs Officer" + }, + { + "id": "7838", + "name": "Customs Officer" + }, + { + "id": "7839", + "name": "Customs Officer" + }, + { + "id": "7840", + "name": "Heavy-Handed Harry" + }, + { + "id": "7841", + "name": "Player" + }, + { + "id": "7842", + "name": "Locker Officer" + }, + { + "id": "7843", + "name": "Locker Officer" + }, + { + "id": "7844", + "name": "Ex-ex-parrot" + }, + { + "id": "7845", + "name": "Pirate impling" + }, + { + "id": "7846", + "name": "Pirate impling" + }, + { + "id": "7847", + "name": "Captain Rabid Jack" + }, + { + "id": "7848", + "name": "Jack" + }, + { + "id": "7849", + "name": "Bosun Giles" + }, + { + "id": "7850", + "name": "Pirate" + }, + { + "id": "7851", + "name": "Lizzie" + }, + { + "id": "7852", + "name": "Cap'n Izzy No-Beard" + }, + { + "id": "7853", + "name": "Ralph" + }, + { + "id": "7854", + "name": "Brass Hand Harry" + }, + { + "id": "7855", + "name": "Bill Teach" + }, + { + "id": "7856", + "name": "Pirate" + }, + { + "id": "7857", + "name": "Brass Hand Harry" + }, + { + "id": "7858", + "name": "Gull" + }, + { + "id": "7861", + "name": "Jack" + }, + { + "id": "7862", + "name": "Fishing spot" + }, + { + "id": "7863", + "name": "Fishing spot" + }, + { + "id": "7864", + "name": "Fishing spot" + }, + { + "id": "7865", + "name": "Guardsman Dante" + }, + { + "id": "7866", + "name": "Guardsman DeShawn" + }, + { + "id": "7867", + "name": "Guardsman Brawn" + }, + { + "id": "7868", + "name": "Iain" + }, + { + "id": "7869", + "name": "Julian" + }, + { + "id": "7870", + "name": "Lachtopher" + }, + { + "id": "7871", + "name": "Samuel" + }, + { + "id": "7872", + "name": "Victoria" + }, + { + "id": "7873", + "name": "Man" + }, + { + "id": "7874", + "name": "Man" + }, + { + "id": "7875", + "name": "Man" + }, + { + "id": "7876", + "name": "Man" + }, + { + "id": "7877", + "name": "Man" + }, + { + "id": "7878", + "name": "Man" + }, + { + "id": "7879", + "name": "Man" + }, + { + "id": "7880", + "name": "Woman" + }, + { + "id": "7881", + "name": "Woman" + }, + { + "id": "7882", + "name": "Woman" + }, + { + "id": "7883", + "name": "Woman" + }, + { + "id": "7884", + "name": "Woman" + }, + { + "id": "7885", + "name": "Guardsman Dante" + }, + { + "id": "7886", + "name": "Guardsman DeShawn" + }, + { + "id": "7887", + "name": "Guardsman Brawn" + }, + { + "id": "7888", + "name": "Sergeant Abram" + }, + { + "id": "7889", + "name": "Guardsman Pazel" + }, + { + "id": "7890", + "name": "Guardsman Peale" + }, + { + "id": "7892", + "name": "General Wartface" + }, + { + "id": "7893", + "name": "General Bentnoze" + }, + { + "id": "7894", + "name": "General Wartface" + }, + { + "id": "7896", + "name": "General Bentnoze" + }, + { + "id": "7898", + "name": "Loar Shadow" + }, + { + "id": "7901", + "name": "Loar Shadow" + }, + { + "id": "7902", + "name": "Sergeant Abram" + }, + { + "id": "7903", + "name": "Guardsman Pazel" + }, + { + "id": "7904", + "name": "Guardsman Peale" + }, + { + "id": "7905", + "name": "Barricade guard" + }, + { + "id": "7906", + "name": "Barricade guard" + }, + { + "id": "7907", + "name": "Barricade guard" + }, + { + "id": "7908", + "name": "Barricade guard" + }, + { + "id": "7909", + "name": "Barricade guard" + }, + { + "id": "7910", + "name": "Barricade guard" + }, + { + "id": "7911", + "name": "Barricade guard" + }, + { + "id": "7912", + "name": "Border guard" + }, + { + "id": "7913", + "name": "Iain" + }, + { + "id": "7914", + "name": "Julian" + }, + { + "id": "7915", + "name": "Lachtopher" + }, + { + "id": "7916", + "name": "Samuel" + }, + { + "id": "7917", + "name": "Victoria" + }, + { + "id": "7918", + "name": "Man" + }, + { + "id": "7919", + "name": "Man" + }, + { + "id": "7920", + "name": "Man" + }, + { + "id": "7921", + "name": "Man" + }, + { + "id": "7922", + "name": "Man" + }, + { + "id": "7923", + "name": "Man" + }, + { + "id": "7924", + "name": "Man" + }, + { + "id": "7925", + "name": "Woman" + }, + { + "id": "7926", + "name": "Woman" + }, + { + "id": "7927", + "name": "Woman" + }, + { + "id": "7928", + "name": "Woman" + }, + { + "id": "7929", + "name": "Lumbridge Guide" + }, + { + "id": "7930", + "name": "Doomsayer" + }, + { + "id": "7931", + "name": "Donie" + }, + { + "id": "7932", + "name": "Gee" + }, + { + "id": "7933", + "name": "Duke Horacio" + }, + { + "id": "7934", + "name": "Sigmund" + }, + { + "id": "7935", + "name": "Hans" + }, + { + "id": "7936", + "name": "Cook" + }, + { + "id": "7937", + "name": "Father Aereck" + }, + { + "id": "7938", + "name": "Sir Vant" + }, + { + "id": "7939", + "name": "Sir Vant" + }, + { + "id": "7940", + "name": "Sir Vant" + }, + { + "id": "7941", + "name": "Sir Vant" + }, + { + "id": "7942", + "name": "Sir Vant" + }, + { + "id": "7943", + "name": "Dragon" + }, + { + "id": "7944", + "name": "Dragon" + }, + { + "id": "7945", + "name": "Dragon" + }, + { + "id": "7946", + "name": "Dragon" + }, + { + "id": "7947", + "name": "Dragon" + }, + { + "id": "7948", + "name": "Dragon" + }, + { + "id": "7949", + "name": "Lumbridge Guide" + }, + { + "id": "7950", + "name": "Melee Tutor" + }, + { + "id": "7951", + "name": "Ranged Tutor" + }, + { + "id": "7952", + "name": "Magic Tutor" + }, + { + "id": "7953", + "name": "Cooking Tutor" + }, + { + "id": "7954", + "name": "Crafting Tutor" + }, + { + "id": "7955", + "name": "Fishing Tutor" + }, + { + "id": "7956", + "name": "Mining Tutor" + }, + { + "id": "7957", + "name": "Prayer Tutor" + }, + { + "id": "7960", + "name": "Woodcutting Tutor" + }, + { + "id": "7961", + "name": "Bank Tutor" + }, + { + "id": "7962", + "name": "Gee" + }, + { + "id": "7963", + "name": "Spirit" + }, + { + "id": "7964", + "name": "Goblin" + }, + { + "id": "7965", + "name": "Goblin" + }, + { + "id": "7966", + "name": "Chaos druid" + }, + { + "id": "7967", + "name": "Shopkeeper" + }, + { + "id": "7968", + "name": "Explorer Jack" + }, + { + "id": "7970", + "name": "Smithing Tutor" + }, + { + "id": "7971", + "name": "Mining Tutor" + }, + { + "id": "7972", + "name": "Spirit" + }, + { + "id": "7977", + "name": "Spirit" + }, + { + "id": "7978", + "name": "Spirit" + }, + { + "id": "7979", + "name": "Spirit" + }, + { + "id": "7980", + "name": "Spirit" + }, + { + "id": "7981", + "name": "Spirit" + }, + { + "id": "7982", + "name": "Spirit" + }, + { + "id": "7983", + "name": "Spirit" + }, + { + "id": "7984", + "name": "Spirit" + }, + { + "id": "7985", + "name": "Summer Bonde" + }, + { + "id": "7987", + "name": "Spirit" + }, + { + "id": "7988", + "name": "Spirit" + }, + { + "id": "7989", + "name": "Erik Bonde" + }, + { + "id": "7990", + "name": "Spirit" + }, + { + "id": "7991", + "name": "Jallek Lenkin" + }, + { + "id": "7992", + "name": "Spirit" + }, + { + "id": "7993", + "name": "Meranek Thanatos" + }, + { + "id": "7994", + "name": "Ghostly warrior" + }, + { + "id": "7995", + "name": "Spirit Beast" + }, + { + "id": "7996", + "name": "Spirit Beast" + }, + { + "id": "7997", + "name": "Spirit Beast" + }, + { + "id": "7998", + "name": "Ghost" + }, + { + "id": "7999", + "name": "Ghost" + }, + { + "id": "8000", + "name": "Goth leprechaun" + }, + { + "id": "8001", + "name": "Jack" + }, + { + "id": "8003", + "name": "Sarah" + }, + { + "id": "8004", + "name": "Laura" + }, + { + "id": "8005", + "name": "Laura" + }, + { + "id": "8006", + "name": "Roger" + }, + { + "id": "8007", + "name": "Jorral" + }, + { + "id": "8008", + "name": "Guthix" + }, + { + "id": "8009", + "name": "Max the traveller" + }, + { + "id": "8010", + "name": "Man" + }, + { + "id": "8011", + "name": "Man" + }, + { + "id": "8012", + "name": "Woman" + }, + { + "id": "8013", + "name": "Woman" + }, + { + "id": "8014", + "name": "Haluned" + }, + { + "id": "8015", + "name": "Jack" + }, + { + "id": "8016", + "name": "Baby Sarah" + }, + { + "id": "8017", + "name": "Snowy" + }, + { + "id": "8018", + "name": "Roger" + }, + { + "id": "8019", + "name": "Portal" + }, + { + "id": "8020", + "name": "Portal" + }, + { + "id": "8021", + "name": "Yellow orb" + }, + { + "id": "8023", + "name": "Yellow orb" + }, + { + "id": "8024", + "name": "Yellow orb" + }, + { + "id": "8025", + "name": "Green orb" + }, + { + "id": "8027", + "name": "Green orb" + }, + { + "id": "8028", + "name": "Green orb" + }, + { + "id": "8029", + "name": "Wizard Korvak" + }, + { + "id": "8030", + "name": "Wizard Vief" + }, + { + "id": "8031", + "name": "Wizard Acantha" + }, + { + "id": "8032", + "name": "Wizard Elriss" + }, + { + "id": "8033", + "name": "Wizard" + }, + { + "id": "8034", + "name": "Wizard" + }, + { + "id": "8035", + "name": "Wizard" + }, + { + "id": "8036", + "name": "Wizard" + }, + { + "id": "8037", + "name": "Wizard" + }, + { + "id": "8038", + "name": "Wizard" + }, + { + "id": "8039", + "name": "Wizard" + }, + { + "id": "8040", + "name": "Wizard" + }, + { + "id": "8042", + "name": "Squire Fyre" + }, + { + "id": "8043", + "name": "Squire Fyre" + }, + { + "id": "8044", + "name": "Orry" + }, + { + "id": "8045", + "name": "Orry" + }, + { + "id": "8046", + "name": "Ube" + }, + { + "id": "8047", + "name": "Ube" + }, + { + "id": "8048", + "name": "Waldo" + }, + { + "id": "8049", + "name": "Waldo" + }, + { + "id": "8050", + "name": "Gjalp" + }, + { + "id": "8051", + "name": "Gjalp" + }, + { + "id": "8052", + "name": "Brother Fintan" + }, + { + "id": "8053", + "name": "Brother Fintan" + }, + { + "id": "8054", + "name": "Stubthumb" + }, + { + "id": "8055", + "name": "Stubthumb" + }, + { + "id": "8056", + "name": "Stubthumb" + }, + { + "id": "8057", + "name": "Doronbol" + }, + { + "id": "8058", + "name": "Doronbol" + }, + { + "id": "8059", + "name": "Crate" + }, + { + "id": "8060", + "name": "Crate" + }, + { + "id": "8061", + "name": "Egg" + }, + { + "id": "8062", + "name": "Egg" + }, + { + "id": "8063", + "name": "Nanuq" + }, + { + "id": "8064", + "name": "Nanuq" + }, + { + "id": "8065", + "name": "Pumpkin" + }, + { + "id": "8078", + "name": "Maggie" + }, + { + "id": "8079", + "name": "Circus barker" + }, + { + "id": "8080", + "name": "Circus barker" + }, + { + "id": "8081", + "name": "Circus barker" + }, + { + "id": "8082", + "name": "Agility assistant" + }, + { + "id": "8083", + "name": "Magic assistant" + }, + { + "id": "8084", + "name": "Ranged assistant" + }, + { + "id": "8085", + "name": "Ringmaster" + }, + { + "id": "8086", + "name": "Audience" + }, + { + "id": "8087", + "name": "Audience" + }, + { + "id": "8088", + "name": "Ticket vendor" + }, + { + "id": "8089", + "name": "Rock" + }, + { + "id": "8091", + "name": "Star sprite" + }, + { + "id": "8092", + "name": "Shooting star shadow" + }, + { + "id": "8093", + "name": "Penguin" + }, + { + "id": "8094", + "name": "Penguin" + }, + { + "id": "8095", + "name": "Penguin" + }, + { + "id": "8096", + "name": "Penguin" + }, + { + "id": "8097", + "name": "Penguin" + }, + { + "id": "8098", + "name": "Penguin" + }, + { + "id": "8099", + "name": "Penguin" + }, + { + "id": "8100", + "name": "Penguin" + }, + { + "id": "8101", + "name": "Penguin" + }, + { + "id": "8102", + "name": "Penguin" + }, + { + "id": "8103", + "name": "Penguin" + }, + { + "id": "8104", + "name": "Barrel" + }, + { + "id": "8105", + "name": "Bush" + }, + { + "id": "8106", + "name": "Bush" + }, + { + "id": "8107", + "name": "Cactus" + }, + { + "id": "8108", + "name": "Crate" + }, + { + "id": "8109", + "name": "Rock" + }, + { + "id": "8110", + "name": "Toadstool" + }, + { + "id": "8111", + "name": "Calladin" + }, + { + "id": "8112", + "name": "Summer Bonde" + }, + { + "id": "8114", + "name": "Summer Bonde" + }, + { + "id": "8115", + "name": "Erik Bonde" + }, + { + "id": "8116", + "name": "Erik Bonde" + }, + { + "id": "8117", + "name": "Jallek Lenkin" + }, + { + "id": "8118", + "name": "Jallek Lenkin" + }, + { + "id": "8119", + "name": "Meranek Thanatos" + }, + { + "id": "8120", + "name": "Meranek Thanatos" + }, + { + "id": "8121", + "name": "Spirit" + }, + { + "id": "8122", + "name": "Rogue" + }, + { + "id": "8123", + "name": "Tormented wraith" + }, + { + "id": "8126", + "name": "Dark energy core" + }, + { + "id": "8127", + "name": "Dark energy core" + }, + { + "id": "8128", + "name": "Spirit Beast" + }, + { + "id": "8129", + "name": "Spirit Beast" + }, + { + "id": "8130", + "name": "Spirit Beast" + }, + { + "id": "8131", + "name": "Spirit Beast" + }, + { + "id": "8132", + "name": "Spirit Beast" + }, + { + "id": "8134", + "name": "Spirit" + }, + { + "id": "8135", + "name": "Summer Bonde" + }, + { + "id": "8136", + "name": "Erik Bonde" + }, + { + "id": "8137", + "name": "Jallek Lenkin" + }, + { + "id": "8138", + "name": "Meranek Thanatos" + }, + { + "id": "8139", + "name": "Hartwin" + }, + { + "id": "8140", + "name": "Hartwin" + }, + { + "id": "8141", + "name": "Zombie" + }, + { + "id": "8143", + "name": "Zombie" + }, + { + "id": "8144", + "name": "Zombie" + }, + { + "id": "8145", + "name": "Zombie" + }, + { + "id": "8146", + "name": "Zemouregal" + }, + { + "id": "8147", + "name": "Zemouregal" + }, + { + "id": "8152", + "name": "Armoured zombie" + }, + { + "id": "8153", + "name": "Armoured zombie" + }, + { + "id": "8154", + "name": "Armoured zombie" + }, + { + "id": "8155", + "name": "Armoured zombie" + }, + { + "id": "8156", + "name": "Armoured zombie" + }, + { + "id": "8157", + "name": "Armoured zombie" + }, + { + "id": "8158", + "name": "Armoured zombie" + }, + { + "id": "8159", + "name": "Armoured zombie" + }, + { + "id": "8160", + "name": "Armoured zombie" + }, + { + "id": "8161", + "name": "Armoured zombie" + }, + { + "id": "8162", + "name": "Armoured zombie" + }, + { + "id": "8163", + "name": "Armoured zombie" + }, + { + "id": "8164", + "name": "Armoured zombie" + }, + { + "id": "8165", + "name": "Sharathteerk" + }, + { + "id": "8166", + "name": "Sharathteerk" + }, + { + "id": "8168", + "name": "Arrav" + }, + { + "id": "8169", + "name": "Arrav" + }, + { + "id": "8170", + "name": "Ramarno" + }, + { + "id": "8171", + "name": "Dimintheis" + }, + { + "id": "8172", + "name": "Dimintheis" + }, + { + "id": "8173", + "name": "Guard" + }, + { + "id": "8174", + "name": "Clive" + }, + { + "id": "8175", + "name": "Ellamaria" + }, + { + "id": "8176", + "name": "Fish" + }, + { + "id": "8177", + "name": "Fish" + }, + { + "id": "8178", + "name": "Monk of Zamorak" + }, + { + "id": "8179", + "name": "Ellamaria" + }, + { + "id": "8180", + "name": "Traiborn" + }, + { + "id": "8181", + "name": "Fenkenstrain's Monster" + }, + { + "id": "8182", + "name": "Wise Old Man" + }, + { + "id": "8183", + "name": "Acrobat" + }, + { + "id": "8186", + "name": "Acrobat" + }, + { + "id": "8187", + "name": "Acrobat" + }, + { + "id": "8188", + "name": "Acrobat" + }, + { + "id": "8189", + "name": "Acrobat" + }, + { + "id": "8190", + "name": "Acrobat" + }, + { + "id": "8191", + "name": "Acrobat" + }, + { + "id": "8192", + "name": "Acrobat" + }, + { + "id": "8193", + "name": "Acrobat" + }, + { + "id": "8194", + "name": "Acrobat" + }, + { + "id": "8195", + "name": "Acrobat" + }, + { + "id": "8196", + "name": "Acrobat" + }, + { + "id": "8197", + "name": "Acrobat" + }, + { + "id": "8198", + "name": "Acrobat" + }, + { + "id": "8199", + "name": "Acrobat" + }, + { + "id": "8200", + "name": "Acrobat" + }, + { + "id": "8201", + "name": "Wendy" + }, + { + "id": "8202", + "name": "Trogs" + }, + { + "id": "8203", + "name": "Norman" + }, + { + "id": "8204", + "name": "Babe" + }, + { + "id": "8205", + "name": "Gus" + }, + { + "id": "8206", + "name": "Lottie" + }, + { + "id": "8207", + "name": "Aggie" + }, + { + "id": "8208", + "name": "Bat" + }, + { + "id": "8209", + "name": "Rat" + }, + { + "id": "8210", + "name": "Lizard" + }, + { + "id": "8211", + "name": "Blackbird" + }, + { + "id": "8212", + "name": "Spider" + }, + { + "id": "8213", + "name": "Snail" + }, + { + "id": "8214", + "name": "Cat" + }, + { + "id": "8215", + "name": "Lazy cat" + }, + { + "id": "8216", + "name": "Overgrown cat" + }, + { + "id": "8217", + "name": "Kitten" + }, + { + "id": "8218", + "name": "Wily cat" + }, + { + "id": "8219", + "name": "Guardian of Armadyl" + }, + { + "id": "8227", + "name": "Head mystic" + }, + { + "id": "8228", + "name": "Rewards mystic" + }, + { + "id": "8229", + "name": "Mystic" + }, + { + "id": "8230", + "name": "Mystic" + }, + { + "id": "8231", + "name": "Mystic" + }, + { + "id": "8232", + "name": "Mystic" + }, + { + "id": "8233", + "name": "Mystic" + }, + { + "id": "8234", + "name": "Mystic" + }, + { + "id": "8235", + "name": "Mystic" + }, + { + "id": "8236", + "name": "Mystic" + }, + { + "id": "8237", + "name": "Mystic" + }, + { + "id": "8238", + "name": "Mystic" + }, + { + "id": "8239", + "name": "Head mystic" + }, + { + "id": "8240", + "name": "Clay familiar (class 1)" + }, + { + "id": "8241", + "name": "Clay familiar (class 1)" + }, + { + "id": "8242", + "name": "Clay familiar (class 2)" + }, + { + "id": "8243", + "name": "Clay familiar (class 2)" + }, + { + "id": "8244", + "name": "Clay familiar (class 3)" + }, + { + "id": "8245", + "name": "Clay familiar (class 3)" + }, + { + "id": "8246", + "name": "Clay familiar (class 4)" + }, + { + "id": "8247", + "name": "Clay familiar (class 4)" + }, + { + "id": "8248", + "name": "Clay familiar (class 5)" + }, + { + "id": "8249", + "name": "Clay familiar (class 5)" + }, + { + "id": "8250", + "name": "Grindxplox" + }, + { + "id": "8251", + "name": "Grindxplox" + }, + { + "id": "8252", + "name": "Stealing Creation team" + }, + { + "id": "8253", + "name": "Resource NPC" + }, + { + "id": "8254", + "name": "Game NPC" + }, + { + "id": "8255", + "name": "Resource NPC" + }, + { + "id": "8257", + "name": "Harrallak Menarous" + }, + { + "id": "8269", + "name": "Yadech Strongarm" + }, + { + "id": "8271", + "name": "Turael" + }, + { + "id": "8274", + "name": "Mazchna" + }, + { + "id": "8275", + "name": "Duradel" + }, + { + "id": "8276", + "name": "Cyrisus" + }, + { + "id": "8280", + "name": "Sloane" + }, + { + "id": "8281", + "name": "Balance Elemental" + }, + { + "id": "8282", + "name": "Balance Elemental" + }, + { + "id": "8283", + "name": "Balance Elemental" + }, + { + "id": "8284", + "name": "Balance Elemental" + }, + { + "id": "8285", + "name": "Balance Elemental" + }, + { + "id": "8286", + "name": "Undead hero" + }, + { + "id": "8287", + "name": "Undead hero" + }, + { + "id": "8288", + "name": "Undead hero" + }, + { + "id": "8289", + "name": "Undead hero" + }, + { + "id": "8290", + "name": "Undead hero" + }, + { + "id": "8291", + "name": "Undead hero" + }, + { + "id": "8292", + "name": "Undead hero" + }, + { + "id": "8293", + "name": "Undead hero" + }, + { + "id": "8294", + "name": "Undead hero" + }, + { + "id": "8295", + "name": "Undead hero" + }, + { + "id": "8296", + "name": "Undead hero" + }, + { + "id": "8297", + "name": "Undead hero" + }, + { + "id": "8298", + "name": "Stone block" + }, + { + "id": "8299", + "name": "Harrallak Menarous" + }, + { + "id": "8300", + "name": "Harrallak Menarous" + }, + { + "id": "8301", + "name": "Harrallak Menarous" + }, + { + "id": "8302", + "name": "Turael" + }, + { + "id": "8303", + "name": "Turael" + }, + { + "id": "8304", + "name": "Cyrisus" + }, + { + "id": "8305", + "name": "Cyrisus" + }, + { + "id": "8306", + "name": "Ghommal" + }, + { + "id": "8307", + "name": "Mazchna" + }, + { + "id": "8308", + "name": "Mazchna" + }, + { + "id": "8309", + "name": "Mazchna" + }, + { + "id": "8310", + "name": "Duradel" + }, + { + "id": "8311", + "name": "Sloane" + }, + { + "id": "8317", + "name": "Elite Dark Ranger" + }, + { + "id": "8318", + "name": "Elite Dark Ranger" + }, + { + "id": "8319", + "name": "Elite Dark Ranger" + }, + { + "id": "8320", + "name": "Elite Dark Mage" + }, + { + "id": "8321", + "name": "Elite Dark Mage" + }, + { + "id": "8322", + "name": "Elite Dark Mage" + }, + { + "id": "8323", + "name": "Elite Dark Mage" + }, + { + "id": "8324", + "name": "Elite Black Knight" + }, + { + "id": "8325", + "name": "Elite Black Knight" + }, + { + "id": "8326", + "name": "Elite Black Knight" + }, + { + "id": "8327", + "name": "Elite Black Knight" + }, + { + "id": "8328", + "name": "Elite Black Knight" + }, + { + "id": "8329", + "name": "Elite Black Knight" + }, + { + "id": "8330", + "name": "Elite Black Knight" + }, + { + "id": "8331", + "name": "Guardian of Armadyl" + }, + { + "id": "8332", + "name": "Guardian of Armadyl" + }, + { + "id": "8333", + "name": "Guardian of Armadyl" + }, + { + "id": "8334", + "name": "Mercenary axeman" + }, + { + "id": "8335", + "name": "Mercenary mage" + }, + { + "id": "8336", + "name": "Idria" + }, + { + "id": "8337", + "name": "Idria" + }, + { + "id": "8338", + "name": "Akrisae" + }, + { + "id": "8339", + "name": "Shady stranger" + }, + { + "id": "8340", + "name": "Shady stranger" + }, + { + "id": "8341", + "name": "Shady stranger" + }, + { + "id": "8342", + "name": "Guardian of Armadyl" + }, + { + "id": "8344", + "name": "Guardian of Armadyl" + }, + { + "id": "8345", + "name": "Local thug" + }, + { + "id": "8347", + "name": "Local mage" + }, + { + "id": "8367", + "name": "Undead troll" + }, + { + "id": "8378", + "name": "Undead troll" + }, + { + "id": "8379", + "name": "Undead troll" + }, + { + "id": "8380", + "name": "Undead troll" + }, + { + "id": "8381", + "name": "Undead troll" + }, + { + "id": "8382", + "name": "Undead troll" + }, + { + "id": "8383", + "name": "Undead troll" + }, + { + "id": "8384", + "name": "Undead troll" + }, + { + "id": "8385", + "name": "Undead troll" + }, + { + "id": "8386", + "name": "Undead troll" + }, + { + "id": "8387", + "name": "Undead troll" + }, + { + "id": "8388", + "name": "Undead troll" + }, + { + "id": "8389", + "name": "Undead troll" + }, + { + "id": "8390", + "name": "Undead troll" + }, + { + "id": "8391", + "name": "Undead troll" + }, + { + "id": "8392", + "name": "Undead troll" + }, + { + "id": "8393", + "name": "Vasador" + }, + { + "id": "8394", + "name": "Valator" + }, + { + "id": "8395", + "name": "Vaasdor" + }, + { + "id": "8396", + "name": "Varosad" + }, + { + "id": "8397", + "name": "Verisad" + }, + { + "id": "8398", + "name": "Vudisor" + }, + { + "id": "8399", + "name": "Vlatoad" + }, + { + "id": "8400", + "name": "Vedolas" + }, + { + "id": "8401", + "name": "Vundiar" + }, + { + "id": "8402", + "name": "Versita" + }, + { + "id": "8403", + "name": "Vislota" + }, + { + "id": "8404", + "name": "Vanjuta" + }, + { + "id": "8405", + "name": "Vasador" + }, + { + "id": "8406", + "name": "Valator" + }, + { + "id": "8407", + "name": "Vaasdor" + }, + { + "id": "8408", + "name": "Varosad" + }, + { + "id": "8409", + "name": "Verisad" + }, + { + "id": "8410", + "name": "Vudisor" + }, + { + "id": "8411", + "name": "Vlatoad" + }, + { + "id": "8412", + "name": "Vedolas" + }, + { + "id": "8413", + "name": "Vundiar" + }, + { + "id": "8414", + "name": "Versita" + }, + { + "id": "8415", + "name": "Vislota" + }, + { + "id": "8416", + "name": "Vanjuta" + }, + { + "id": "8417", + "name": "Ivy Sophista" + }, + { + "id": "8418", + "name": "Thaerisk Cemphier" + }, + { + "id": "8419", + "name": "Thaerisk Cemphier" + }, + { + "id": "8420", + "name": "Assassin" + }, + { + "id": "8423", + "name": "Assassin" + }, + { + "id": "8424", + "name": "Mithril dragon" + }, + { + "id": "8425", + "name": "Dragon head" + }, + { + "id": "8426", + "name": "Dragon head" + }, + { + "id": "8427", + "name": "Dragon head" + }, + { + "id": "8428", + "name": "Khazard launderer" + }, + { + "id": "8429", + "name": "Khazard cook" + }, + { + "id": "8430", + "name": "Silif" + }, + { + "id": "8431", + "name": "Silif" + }, + { + "id": "8432", + "name": "Silif" + }, + { + "id": "8433", + "name": "Silif" + }, + { + "id": "8434", + "name": "Silif" + }, + { + "id": "8435", + "name": "Shady stranger" + }, + { + "id": "8436", + "name": "Suspicious outsider" + }, + { + "id": "8437", + "name": "Elite Khazard guard" + }, + { + "id": "8438", + "name": "Elite Khazard guard" + }, + { + "id": "8439", + "name": "Elite Khazard guard" + }, + { + "id": "8440", + "name": "Elite Khazard guard" + }, + { + "id": "8441", + "name": "Dark Squall" + }, + { + "id": "8442", + "name": "Surok Magis" + }, + { + "id": "8443", + "name": "Lucien" + }, + { + "id": "8444", + "name": "Druid" + }, + { + "id": "8445", + "name": "Druid" + }, + { + "id": "8446", + "name": "Druid" + }, + { + "id": "8447", + "name": "Druid bodyguard" + }, + { + "id": "8448", + "name": "Druid bodyguard" + }, + { + "id": "8449", + "name": "Movario" + }, + { + "id": "8450", + "name": "Darve" + }, + { + "id": "8451", + "name": "Cave goblin" + }, + { + "id": "8452", + "name": "Movario" + }, + { + "id": "8453", + "name": "Darve" + }, + { + "id": "8454", + "name": "Light creature" + }, + { + "id": "8455", + "name": "Light creature" + }, + { + "id": "8456", + "name": "Druid spirit" + }, + { + "id": "8457", + "name": "Druid spirit" + }, + { + "id": "8458", + "name": "Druid spirit" + }, + { + "id": "8459", + "name": "Druid spirit" + }, + { + "id": "8460", + "name": "Turael" + }, + { + "id": "8462", + "name": "Spria" + }, + { + "id": "8463", + "name": "Mazchna" + }, + { + "id": "8464", + "name": "Mazchna" + }, + { + "id": "8465", + "name": "Achtryn" + }, + { + "id": "8466", + "name": "Duradel" + }, + { + "id": "8467", + "name": "Lapalok" + }, + { + "id": "8468", + "name": "Laidee Gnonock" + }, + { + "id": "8485", + "name": "Hazelmere" + }, + { + "id": "8486", + "name": "Undead mage" + }, + { + "id": "8487", + "name": "Wild broav" + }, + { + "id": "8488", + "name": "Hazelmere" + }, + { + "id": "8490", + "name": "Hazelmere" + }, + { + "id": "8491", + "name": "Broav" + }, + { + "id": "8492", + "name": "Sithaph" + }, + { + "id": "8494", + "name": "Strisath" + }, + { + "id": "8495", + "name": "Sakirth" + }, + { + "id": "8496", + "name": "Hazelmere's hat" + }, + { + "id": "8497", + "name": "Lucien" + }, + { + "id": "8498", + "name": "A lazy Khazard guard" + }, + { + "id": "8499", + "name": "Thanksgiving Turkey" + }, + { + "id": "8500", + "name": "Cook's brother" + }, + { + "id": "8501", + "name": "Turkey" + }, + { + "id": "8502", + "name": "Cactus" + }, + { + "id": "8503", + "name": "Cactus" + }, + { + "id": "8504", + "name": "Bush" + }, + { + "id": "8505", + "name": "Toadstool" + }, + { + "id": "8506", + "name": "Barrel" + }, + { + "id": "8507", + "name": "Bush" + }, + { + "id": "8508", + "name": "Crate" + }, + { + "id": "8509", + "name": "Bush" + }, + { + "id": "8510", + "name": "Rock" + }, + { + "id": "8511", + "name": "Bush" + }, + { + "id": "8512", + "name": "Marvin" + }, + { + "id": "8513", + "name": "Marius" + }, + { + "id": "8514", + "name": "Benny" + }, + { + "id": "8515", + "name": "Yeti" + }, + { + "id": "8516", + "name": "Yeti" + }, + { + "id": "8517", + "name": "Jack Frost" + }, + { + "id": "8518", + "name": "Jack Frost" + }, + { + "id": "8519", + "name": "Jack Frost" + }, + { + "id": "8520", + "name": "Jack Frost" + }, + { + "id": "8521", + "name": "Snow imp" + }, + { + "id": "8537", + "name": "Snow imp" + }, + { + "id": "8538", + "name": "Snow imp" + }, + { + "id": "8539", + "name": "Queen of Snow" + }, + { + "id": "8540", + "name": "Santa Claus" + }, + { + "id": "8541", + "name": "Head snow imp" + }, + { + "id": "8542", + "name": "Head snow imp" + }, + { + "id": "8543", + "name": "Head snow imp" + }, + { + "id": "8544", + "name": "Isidor" + }, + { + "id": "8545", + "name": "Mystic" + }, + { + "id": "8546", + "name": "Balance Elemental" + }, + { + "id": "8547", + "name": "Wounded phoenix" + }, + { + "id": "8548", + "name": "Phoenix" + }, + { + "id": "8549", + "name": "Phoenix" + }, + { + "id": "8550", + "name": "Phoenix eggling" + }, + { + "id": "8551", + "name": "Phoenix eggling" + }, + { + "id": "8552", + "name": "Large egg" + }, + { + "id": "8553", + "name": "Priest of Guthix" + }, + { + "id": "8556", + "name": "Brian Twitcher" + }, + { + "id": "8557", + "name": "Lesser reborn warrior" + }, + { + "id": "8558", + "name": "Lesser reborn warrior" + }, + { + "id": "8559", + "name": "Greater reborn warrior" + }, + { + "id": "8560", + "name": "Greater reborn warrior" + }, + { + "id": "8561", + "name": "Lesser reborn ranger" + }, + { + "id": "8562", + "name": "Lesser reborn ranger" + }, + { + "id": "8563", + "name": "Greater reborn ranger" + }, + { + "id": "8564", + "name": "Greater reborn ranger" + }, + { + "id": "8565", + "name": "Lesser reborn mage" + }, + { + "id": "8566", + "name": "Lesser reborn mage" + }, + { + "id": "8567", + "name": "Greater reborn mage" + }, + { + "id": "8568", + "name": "Greater reborn mage" + }, + { + "id": "8569", + "name": "Lesser reborn warrior" + }, + { + "id": "8570", + "name": "Greater reborn warrior" + }, + { + "id": "8571", + "name": "Lesser reborn ranger" + }, + { + "id": "8572", + "name": "Greater reborn ranger" + }, + { + "id": "8573", + "name": "Lesser reborn mage" + }, + { + "id": "8574", + "name": "Greater reborn mage" + }, + { + "id": "8575", + "name": "Phoenix" + }, + { + "id": "8576", + "name": "Phoenix" + }, + { + "id": "8577", + "name": "Phoenix eggling" + }, + { + "id": "8578", + "name": "Phoenix eggling" + }, + { + "id": "8579", + "name": "Karma the chameleon" + }, + { + "id": "8581", + "name": "Karma the chameleon" + }, + { + "id": "8582", + "name": "Karma the chameleon" + }, + { + "id": "8583", + "name": "Karma the chameleon" + }, + { + "id": "8584", + "name": "Karma the chameleon" + }, + { + "id": "8585", + "name": "Karma the chameleon" + }, + { + "id": "8586", + "name": "Karma the chameleon" + }, + { + "id": "8587", + "name": "Karma the chameleon" + }, + { + "id": "8588", + "name": "Karma the chameleon" + }, + { + "id": "8589", + "name": "Karma the chameleon" + }, + { + "id": "8590", + "name": "Geoffrey" + }, + { + "examine": "Ooh, shiny things!", + "name": "Magpie Impling", + "id": "1035" + }, + { + "examine": "An earth impling. Rock on.", + "name": "Earth Impling", + "id": "1031" + }, + { + "examine": "A baby impling. Ahhh.", + "name": "Baby Impling", + "id": "1028" + }, + { + "examine": "A young impling. It's not fair!", + "name": "Young Impling", + "id": "1029" + }, + { + "examine": "An impling gourmet. Mmmm, tasty.", + "name": "Gourmet Impling", + "id": "1030" + }, + { + "examine": "An impling who likes magic. Magic!", + "name": "Essence Impling", + "id": "1032" + }, + { + "examine": "Dodgy Mike.", + "name": "Mike", + "id": "3166" + }, + { + "examine": "An impling with varied tastes.", + "name": "Eclectic Impling", + "id": "1033" + }, + { + "examine": "He seems to be making odd sucking noises with his teeth.", + "name": "Leon", + "id": "5111" + }, + { + "examine": "A very stealthy impling.", + "name": "Ninja Impling", + "id": "6053" + }, + { + "examine": "A rare bird.", + "name": "Black Swan", + "water_npc": "true", + "id": "3297" + }, + { + "examine": "A nature impling. Right on, maaan.", + "name": "Nature Impling", + "id": "1034" + }, + { + "examine": "A mourner, or plague healer.", + "death_animation": "836", + "name": "Mourner (boss)", + "defence_level": "10", + "lifepoints": "19", + "melee_animation": "428", + "attack_speed": "4", + "strength_level": "10", + "id": "370", + "bonuses": "0,0,0,0,0,3,2,4,0,0,0,0,0,0,0", + "attack_level": "10" + }, + { + "examine": "A mourner, or plague healer.", + "name": "Mourner", + "id": "717" + }, + { + "examine": "A mourner, or plague healer.", + "name": "Mourner", + "id": "718" + }, + { + "examine": "A mourner, or plague healer.", + "name": "Mourner", + "id": "719" + }, + { + "examine": "A mourner, or plague healer.", + "name": "Mourner", + "id": "3216" + }, + { + "examine": "A mourner, or plague healer.", + "death_animation": "836", + "name": "Mourner", + "defence_level": "14", + "melee_animation": "428", + "lifepoints": "24", + "attack_speed": "4", + "strength_level": "14", + "id": "357", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "attack_level": "14" + }, + { + "examine": "A mourner, or plague healer.", + "death_animation": "836", + "name": "Mourner", + "defence_level": "19", + "melee_animation": "422", + "lifepoints": "30", + "attack_speed": "4", + "strength_level": "19", + "id": "348", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "attack_level": "19" + }, + { + "examine": "A mourner, or plague healer.", + "death_animation": "836", + "name": "Mourner", + "defence_level": "19", + "melee_animation": "422", + "lifepoints": "30", + "attack_speed": "4", + "strength_level": "19", + "id": "369", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "attack_level": "19" + }, + { + "examine": "A mourner, or plague healer.", + "death_animation": "836", + "name": "Mourner", + "defence_level": "8", + "lifepoints": "18", + "melee_animation": "428", + "strength_level": "8", + "attack_speed": "4", + "id": "347", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "attack_level": "8" + }, + { + "examine": "A Mourner, or plague healer.", + "name": "Mourner", + "id": "2374" + }, + { + "examine": "A mourner, or plague healer.", + "name": "Mourner", + "id": "372" + }, + { + "examine": "A mourner, or plague healer.", + "death_animation": "836", + "name": "Mourner", + "defence_level": "8", + "lifepoints": "20", + "melee_animation": "422", + "attack_speed": "4", + "strength_level": "8", + "id": "371", + "bonuses": "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0", + "attack_level": "8" + }, + { + "examine": "In charge of people with silly outfits.", + "name": "Head Mourner", + "id": "716" + }, + { + "examine": "A mourner, or plague healer.", + "name": "Mourner", + "id": "2784" + }, + { + "examine": "She looks concerned.", + "name": "Elena", + "id": "3215" + }, + { + "examine": "She looks concerned.", + "name": "Elena", + "id": "715" + }, + { + "examine": "She doesn't look too happy.", + "name": "Elena", + "id": "3209" + }, + { + "name": "Elena", + "id": "335", + "examine": "She doesn't look too happy." + }, + { + "examine": "Use 1344 to change me", + "name": "Skippy Varbit", + "id": "2795" + }, + { + "examine": "He looks angry and smells drunk.", + "name": "Skippy", + "id": "2796" + }, + { + "name": "Skippy", + "id": "2797", + "examine": "Skippy, just looking a little 'tender'." + }, + { + "name": "Skippy", + "id": "2798", + "examine": "He seems a lot less angry and smells a great deal fresher." + }, + { + "name": "Skippy", + "id": "2799", + "examine": "He seems a bit confused." + } +] \ No newline at end of file diff --git a/Server/data/configs/npc_spawns.json b/Server/data/configs/npc_spawns.json new file mode 100644 index 0000000..8899eea --- /dev/null +++ b/Server/data/configs/npc_spawns.json @@ -0,0 +1,12306 @@ +[ + { + "npc_id": "0", + "loc_data": "{3221,3218,0,1,0}-" + }, + { + "npc_id": "1", + "loc_data": "{3093,3509,0,1,3}-{3098,3508,0,1,7}-{3096,3510,0,1,3}-{3222,3221,0,1,3}-{3210,3223,1,1,4}-{3230,3208,0,1,1}-{3237,3404,0,1,6}-{3237,3408,0,1,0}-{3247,3396,0,1,3}-{3263,3403,0,1,3}-{2712,3484,0,1,4}-{2693,3495,0,1,1}-{3285,3208,0,1,4}-{3017,3239,0,1,2}-{2804,3427,0,1,2}-" + }, + { + "npc_id": "2", + "loc_data": "{3101,3511,0,1,4}-{3236,3203,0,1,4}-{3217,3209,0,1,4}-{3237,3217,0,1,6}-{2690,3489,0,1,3}-{3298,3185,0,1,3}-{3282,3503,0,1,6}-" + }, + { + "npc_id": "3", + "loc_data": "{2818,3443,0,1,3}-{3095,3511,0,1,3}-{3094,3513,0,1,4}-{3097,3510,0,1,4}-{3231,3239,0,1,4}-{2699,3491,0,1,1}-{3306,3200,0,1,6}-{3300,3208,0,1,3}-{3278,3502,0,1,6}-" + }, + { + "npc_id": "4", + "loc_data": "{3230,3204,0,1,3}-{2693,3493,0,1,7}-{2693,3492,0,1,0}-{2695,3497,0,1,1}-{2700,3496,0,1,5}-{3010,3236,0,1,6}-{3281,3499,0,1,4}-" + }, + { + "npc_id": "5", + "loc_data": "{2817,3447,0,1,5}-{3236,3205,0,1,2}-{3230,3238,0,1,1}-{2697,3493,0,1,4}-{3279,3497,0,1,3}-" + }, + { + "npc_id": "6", + "loc_data": "{3097,3259,0,1,4}-{3246,3207,0,1,4}-{3280,3491,0,1,0}-" + }, + { + "npc_id": "7", + "loc_data": "{3158,3301,0,1,0}-{2629,3360,0,1,4}-{2920,3434,0,1,0}-{3226,3290,0,1,3}-" + }, + { + "npc_id": "8", + "loc_data": "{2804,3186,0,1,4}-{3019,3230,0,1,4}-" + }, + { + "npc_id": "9", + "loc_data": "{3007,3321,0,1,6}-{3005,3321,0,1,4}-{2965,3389,0,1,6}-{2964,3392,0,1,6}-{2967,3393,0,1,1}-{2966,3392,0,1,1}-{2964,3392,0,1,1}-{3008,3324,0,1,2}-" + }, + { + "npc_id": "10", + "loc_data": "{1740,4970,0,1,4}-{1783,4950,0,1,4}-{1755,4951,0,1,3}-{1754,4986,0,1,6}-{1763,4972,0,1,6}-" + }, + { + "npc_id": "11", + "loc_data": "{3235,3399,0,1,5}-" + }, + { + "npc_id": "13", + "loc_data": "{2588,3087,0,1,4}-{2592,3086,0,1,6}-{2590,3083,1,1,4}-{2587,3086,1,1,4}-{2594,3084,1,1,6}-{2593,3090,2,1,5}-{2594,3085,2,1,1}-{2588,3089,2,1,4}-{3108,3157,1,1,3}-{3113,3157,1,1,4}-{3107,3170,0,1,0}-{3112,3167,0,1,0}-{3106,3157,0,1,3}-{3110,3155,0,1,6}-" + }, + { + "npc_id": "14", + "loc_data": "{2914,3444,0,1,3}-{2905,3450,1,1,0}-" + }, + { + "npc_id": "15", + "loc_data": "{2584,3304,0,1,3}-{2588,3291,0,1,7}-{2584,3288,0,1,0}-{2563,3382,0,1,6}-{2569,3383,0,1,6}-{2571,3381,0,1,1}-{2575,3384,0,1,4}-{2572,3385,0,1,4}-{2631,3294,0,1,6}-{2629,3296,0,1,4}-{3203,3479,0,1,0}-{3202,3484,0,1,0}-" + }, + { + "npc_id": "16", + "loc_data": "{3279,3191,0,1,4}-{3296,3202,1,1,3}-" + }, + { + "npc_id": "18", + "loc_data": "{3282,3176,0,1,0}-{3284,3170,0,1,7}-{3284,3174,0,1,0}-{3288,3168,0,1,5}-{3292,3169,0,1,3}-{3295,3168,0,1,3}-{3301,3170,0,1,6}-{3301,3174,0,1,6}-{3301,3177,0,1,0}-" + }, + { + "npc_id": "19", + "loc_data": "{2971,3349,0,1,4}-{2979,3350,0,1,2}-{2973,3337,0,1,3}-{2959,3335,0,1,6}-{2982,3339,0,1,6}-{2983,3346,0,1,4}-{2980,3329,0,1,4}-{2987,3330,0,1,6}-{2958,3340,1,1,1}-{2970,3333,1,1,3}-{2966,3329,1,1,4}-{2961,3353,1,1,4}-{2973,3337,1,1,6}-{2998,3341,0,1,6}-{2983,3342,2,1,6}-" + }, + { + "npc_id": "20", + "loc_data": "{2588,3301,1,0,0}-" + }, + { + "npc_id": "21", + "loc_data": "{2630,3288,0,1,1}-{2647,3306,0,1,1}-{2667,3315,0,1,4}-" + }, + { + "npc_id": "23", + "loc_data": "{2582,3297,0,1,6}-{2652,3318,0,1,0}-{2653,3300,0,1,5}-{2669,3298,0,1,4}-{2671,3313,0,1,6}-" + }, + { + "npc_id": "24", + "loc_data": "{2614,3318,0,1,6}-{2621,3293,0,1,3}-" + }, + { + "npc_id": "25", + "loc_data": "{2612,3316,0,1,1}-{2574,3321,1,1,4}-{2621,3293,1,1,3}-" + }, + { + "npc_id": "27", + "loc_data": "{2574,3285,2,0,0}-{2574,3308,2,0,0}-{2582,3284,2,0,0}-{2582,3309,2,0,0}-{2588,3290,2,0,0}-{2588,3303,2,0,0}-" + }, + { + "npc_id": "28", + "loc_data": "{2611,3269,0,0,0}-" + }, + { + "npc_id": "31", + "loc_data": "{2616,3308,0,1,1}-" + }, + { + "npc_id": "32", + "loc_data": "{2651,3307,0,1,1}-{2659,3309,0,1,6}-{2660,3309,0,1,3}-{2661,3309,0,1,1}-{2661,3317,0,1,5}-{2663,3301,0,1,3}-{2665,3300,0,1,3}-{2636,3342,0,1,4}-{2634,3342,0,1,3}-{2635,3339,0,1,3}-" + }, + { + "npc_id": "34", + "loc_data": "{2548,3111,1,1,3}-{2545,3116,1,1,7}-{2549,3115,1,1,1}-{2549,3112,1,1,4}-" + }, + { + "npc_id": "35", + "loc_data": "{2545,3094,0,1,3}-{2549,3093,0,1,2}-{2543,3089,0,1,3}-{2540,3098,0,1,3}-" + }, + { + "npc_id": "36", + "loc_data": "{3020,3373,0,1,0}-" + }, + { + "npc_id": "38", + "loc_data": "{2952,3063,0,0,0}-{2955,3057,0,0,0}-{2956,3035,0,0,0}-{2969,3034,0,0,0}-{2984,3048,0,0,0}-" + }, + { + "npc_id": "39", + "loc_data": "{2958,3055,0,0,0}-{2954,3029,0,0,0}-{2968,3039,0,0,0}-{2984,3048,0,0,0}-{2989,3058,0,0,0}-{2982,3060,0,0,0}-{2972,3060,0,0,0}-{2998,3061,0,0,0}-{2999,3049,0,0,0}-" + }, + { + "npc_id": "40", + "loc_data": "{3005,3060,0,0,0}-{3008,3067,0,0,0}-" + }, + { + "npc_id": "41", + "loc_data": "{2851,3370,0,1,3}-{2846,3374,0,1,3}-{2853,3372,0,1,3}-{2847,3373,0,1,3}-{2850,3371,0,1,1}-{2851,3373,0,1,4}-{2852,3370,0,1,4}-{2819,3561,0,1,4}-{2818,3559,0,1,6}-{3110,9573,0,1,6}-{3140,3096,0,1,3}-{3140,3093,0,1,0}-{3138,3094,0,1,1}-{3140,3093,0,1,3}-{3138,3093,0,1,1}-{3138,3094,0,1,0}-{3140,3093,0,1,1}-{3187,3276,0,1,5}-{3188,3278,0,1,4}-{3197,3356,0,1,4}-{2655,3441,0,1,6}-{2649,3438,0,1,7}-{2649,3446,0,1,6}-{2653,3444,0,1,6}-{2647,3441,0,1,1}-{2674,3652,0,1,3}-{2672,3655,0,1,6}-{2677,3655,0,1,6}-{3234,3297,0,1,3}-{3230,3296,0,1,5}-{3236,3288,0,1,6}-{3236,3300,0,1,2}-{3234,3293,0,1,4}-{3229,3298,0,1,1}-{3228,3296,0,1,4}-{2694,3274,0,1,6}-{2695,3275,0,1,3}-{2965,3336,0,1,4}-{2784,3062,0,1,4}-{2789,3063,0,1,4}-{2815,3560,0,1,7}-" + }, + { + "npc_id": "42", + "loc_data": "{3185,3220,0,1,0}-{3183,3222,0,1,0}-{3237,3346,0,1,1}-" + }, + { + "npc_id": "43", + "loc_data": "{2926,3323,0,1,0}-{2922,3325,0,1,3}-{3200,3263,0,1,0}-{3212,3262,0,1,1}-{3204,3268,0,1,0}-{3241,3354,0,1,3}-" + }, + { + "npc_id": "44", + "loc_data": "{3096,3489,0,0,3}-{3096,3493,0,0,3}-{3097,3494,0,0,1}-{3147,3448,0,0,1}-{3180,3436,0,0,4}-{3180,3440,0,0,4}-{3180,3444,0,0,4}-{3191,3437,0,0,3}-{3191,3441,0,0,3}-{3191,3445,0,0,3}-{3251,3418,0,0,1}-{3252,3418,0,0,1}-{3253,3418,0,0,1}-{3254,3418,0,0,1}-{3255,3418,0,0,1}-{3256,3418,0,0,1}-" + }, + { + "npc_id": "45", + "loc_data": "{3096,3491,0,0,3}-{2843,5214,0,0,4}-{3148,3448,0,0,0}-{3191,3443,0,0,3}-{3191,3439,0,0,3}-{3191,3435,0,0,3}-{3180,3442,0,0,4}-{3180,3434,0,0,4}-{3180,3438,0,0,4}-" + }, + { + "npc_id": "46", + "loc_data": "{3179,3348,0,1,0}-{3178,3353,0,1,0}-{3235,3259,0,1,0}-{3238,3244,0,1,0}-{3241,3230,0,1,0}-{3241,3234,0,1,0}-{3243,3228,0,1,0}-{3247,3221,0,1,0}-{3248,3220,0,1,0}-{3259,3212,0,1,0}-{3211,3322,0,1,0}-{3214,3314,0,1,0}-{3214,3318,0,1,0}-{3216,3314,0,1,0}-{3218,3287,0,1,0}-{3223,3281,0,1,0}-{3231,3271,0,1,0}-{3233,3267,0,1,0}-{3233,3270,0,1,0}-{3235,3265,0,1,0}-{2979,3359,0,1,0}-{2979,3357,0,1,0}-{2993,3384,0,1,6}-{3015,3285,0,1,0}-" + }, + { + "npc_id": "47", + "loc_data": "{2821,3170,0,1,1}-{3341,3267,0,1,5}-{3076,3282,0,1,5}-{3089,3266,0,1,4}-{3091,3266,0,1,4}-{3097,3364,0,1,3}-{3102,3363,0,1,5}-{3127,3487,0,1,4}-{3125,3486,0,1,6}-{3127,3486,0,1,4}-{2603,9480,0,1,1}-{2600,9477,0,1,0}-{2579,9496,0,1,4}-{2580,9508,0,1,0}-{2571,9522,0,1,4}-{2565,9505,0,1,1}-{2566,9510,0,1,6}-{2594,9497,0,1,4}-{2852,9642,0,1,6}-{2858,9632,0,1,3}-{2568,9620,0,1,0}-{2573,9612,0,1,0}-{2579,9631,0,1,0}-{2580,9600,0,1,0}-{2580,9614,0,1,0}-{2580,9620,0,1,0}-{2580,9626,0,1,0}-{2583,9632,0,1,0}-{2584,9625,0,1,0}-{2584,9637,0,1,0}-{2589,9644,0,1,0}-{2590,9601,0,1,0}-{2590,9638,0,1,0}-{2591,9601,0,1,0}-{2591,9621,0,1,0}-{2594,9636,0,1,0}-{2594,9644,0,1,0}-{2597,9604,0,1,0}-{2607,9615,0,1,0}-{2608,9628,0,1,0}-{2614,9651,0,1,0}-{2614,9656,0,1,0}-{2615,9647,0,1,0}-{2615,9661,0,1,0}-{2616,9633,0,1,0}-{2618,9630,0,1,0}-{3108,9754,0,1,5}-{3110,9754,0,1,5}-{3108,9750,0,1,5}-{2592,9831,0,1,3}-{2588,9825,0,1,6}-{2583,9829,0,1,4}-{2581,9841,0,1,0}-{2597,9823,0,1,2}-{2579,9805,0,1,3}-{2576,9804,0,1,0}-{2573,9805,0,1,5}-{2571,9808,0,1,3}-{2576,9810,0,1,2}-{2587,9802,0,1,2}-{2592,9800,0,1,4}-{2596,9805,0,1,6}-{2601,9802,0,1,5}-{2585,9801,0,1,7}-{2594,9803,0,1,0}-{2590,9806,0,1,3}-{2612,9808,0,1,6}-{2604,9810,0,1,6}-{2579,9821,0,1,2}-{2576,9812,0,1,6}-{2580,9813,0,1,6}-{2600,9813,0,1,4}-{2599,9809,0,1,4}-{3158,3226,0,1,5}-{3160,3202,0,1,4}-{3192,3203,0,1,0}-{3194,3204,0,1,0}-{3196,3206,0,1,0}-{3197,3204,0,1,0}-{2654,9640,0,1,6}-{2655,9637,0,1,4}-{2656,9639,0,1,7}-{2651,9636,0,1,5}-{2648,9637,0,1,4}-{2651,9642,0,1,1}-{2654,9640,0,1,0}-{2654,9635,0,1,6}-{2655,9635,0,1,3}-{2664,9626,0,1,6}-{2664,9624,0,1,1}-{2661,9623,0,1,1}-{2663,9623,0,1,3}-{2664,9626,0,1,6}-{2930,9699,0,1,0}-{2933,9697,0,1,0}-{2932,9685,0,1,0}-{2930,9693,0,1,0}-{3235,3224,0,1,3}-{3229,3220,0,1,4}-{3211,3211,0,1,3}-{3225,3220,0,1,1}-{3237,3215,0,1,5}-{3211,3210,0,1,7}-{3227,3220,0,1,7}-{3233,3227,0,1,5}-{3227,3210,0,1,6}-{3228,3222,0,1,4}-{3229,3226,0,1,0}-{3236,3217,0,1,4}-{3259,3230,0,1,4}-{3233,3237,0,1,7}-{3205,3204,0,1,0}-{3206,3204,0,1,0}-{3205,3203,0,1,0}-{3206,3202,0,1,0}-{3207,3202,0,1,0}-{3208,3203,0,1,0}-{3001,3202,0,1,5}-{3243,3687,0,1,5}-{3249,3669,0,1,3}-{3252,3675,0,1,4}-{3252,3680,0,1,3}-{3259,3683,0,1,0}-{3475,9840,0,1,6}-{3481,9842,0,1,1}-{3486,9843,0,1,7}-{3483,9824,0,1,4}-{3496,9808,0,0,5}-{3490,9815,0,1,1}-{3478,9834,0,0,3}-{3490,9824,0,1,4}-{3225,9862,0,1,4}-{3222,9861,0,1,6}-{3220,9860,0,1,6}-{3219,9865,0,1,6}-{3237,9862,0,1,4}-{2536,2982,0,1,3}-{2531,2980,0,1,0}-{2522,2981,0,1,4}-{2545,2989,0,1,4}-{2523,2970,0,1,2}-{3026,3174,0,1,5}-{3019,3176,0,1,7}-{2801,3158,0,1,2}-{2514,3193,0,1,6}-{2518,3192,0,1,3}-{2507,3181,0,1,3}-{2508,3178,0,1,6}-{2511,3183,0,1,3}-{2515,3182,0,1,1}-{3021,3205,0,1,6}-{3019,3292,0,1,7}-{3018,3295,0,1,7}-{2531,3325,0,1,3}-{2530,3327,0,1,5}-{2521,3331,0,1,3}-{2526,3328,0,1,3}-{2523,3331,0,1,4}-{2523,3334,0,1,1}-{2531,3329,0,1,5}-{2532,3333,0,1,5}-{3276,9871,0,1,1}-{3277,9871,0,1,3}-" + }, + { + "npc_id": "48", + "loc_data": "{2817,2921,0,1,2}-{2775,2929,0,1,2}-{2789,2926,0,1,5}-{2795,2932,0,1,6}-{2775,2933,0,1,0}-{2769,2928,0,1,3}-" + }, + { + "npc_id": "49", + "loc_data": "{3133,3678,0,1,0}-{3127,3677,0,1,0}-{3127,3667,0,1,0}-{3117,3674,0,1,0}-{3121,3679,0,1,0}-{3104,3678,0,1,0}-{3110,3687,0,1,0}-{3116,3688,0,1,0}-{3103,3704,0,1,0}-{2871,9819,0,1,0}-{2871,9822,0,1,0}-{2870,9826,0,1,0}-{2869,9829,0,1,0}-{2867,9834,0,1,0}-{2867,9841,0,1,0}-{2864,9853,0,1,0}-{2859,9852,0,1,0}-{2851,9850,0,1,0}-{2856,9846,0,1,0}-{2857,9841,0,1,0}-{2861,9838,0,1,0}-{2854,9838,0,1,0}-{3178,3929,0,1,0}-{3193,3926,0,1,0}-{3195,3915,0,1,0}-{3186,3913,0,1,0}-{3175,3906,0,1,0}-{2735,9692,0,1,1}-{2732,9687,0,1,1}-{2733,9688,0,1,1}-{2734,9690,0,1,1}-{2733,9686,0,1,1}-{2732,9692,0,1,1}-{2736,9685,0,1,1}-{2730,9691,0,1,1}-" + }, + { + "npc_id": "50", + "loc_data": "{2273,4698,0,0,0}-" + }, + { + "npc_id": "52", + "loc_data": "{2898,9764,0,1,0}-{2892,9800,0,1,0}-{2912,9808,0,1,0}-" + }, + { + "npc_id": "53", + "loc_data": "{3212,3820,0,1,0}-{3222,3829,0,1,0}-{2694,9508,0,0,3}-{2703,9505,0,0,6}-{2710,9499,0,0,1}-{2704,9520,0,0,5}-{2714,9523,0,0,3}-{2722,9520,0,0,7}-" + }, + { + "npc_id": "54", + "loc_data": "{2834,9824,0,1,0}-" + }, + { + "npc_id": "55", + "loc_data": "{2897,9802,0,1,0}-{2909,9906,0,1,4}-" + }, + { + "npc_id": "58", + "loc_data": "{2574,9874,0,1,0}-{2577,9877,0,1,3}-{2574,9878,0,1,0}-{2575,9871,0,1,4}-{3289,5482,0,1,1}-{3296,5472,0,1,0}-{3291,5466,0,1,6}-{3294,5481,0,1,0}-{3300,5479,0,1,7}-{3288,5480,0,1,3}-{3293,5475,0,1,3}-{3293,5481,0,1,2}-{3286,5465,0,1,3}-{3279,5478,0,1,4}-{3270,5464,0,1,2}-{3270,5468,0,1,1}-" + }, + { + "npc_id": "59", + "loc_data": "{3082,3362,0,1,4}-{2602,9640,0,1,0}-{2603,9635,0,1,0}-{2603,9638,0,1,0}-{2605,9637,0,1,0}-{2605,9639,0,1,0}-{2606,9635,0,1,0}-{2606,9646,0,1,0}-{2607,9637,0,1,0}-{2607,9641,0,1,0}-{2607,9644,0,1,0}-{2607,9648,0,1,0}-{2608,9635,0,1,0}-{2608,9642,0,1,0}-{2609,9639,0,1,0}-{2609,9643,0,1,0}-{3102,9881,0,1,3}-{3095,9883,0,1,2}-{3182,3244,0,1,1}-{3162,3223,0,1,7}-{3164,3242,0,1,0}-{3169,3246,0,1,0}-{3170,3250,0,1,0}-{3166,3247,0,1,0}-{3164,3249,0,1,0}-{3157,3226,0,1,0}-{3163,3227,0,1,0}-{3165,3223,0,1,0}-{3194,3236,0,1,0}-{3146,3347,0,1,3}-{2648,9766,0,1,4}-{2653,9761,0,1,3}-{2483,2877,0,1,3}-{2481,2876,0,1,4}-{2457,2867,0,1,4}-{2481,2847,0,1,0}-{2475,2854,0,1,3}-{2482,2873,0,1,3}-{2485,2876,0,1,2}-{2449,2865,0,1,1}-{2461,2880,0,1,5}-{2489,2935,0,1,7}-{2492,2907,0,1,1}-{2487,2894,0,1,2}-{2487,2888,0,1,7}-{2478,2916,0,1,5}-{2485,2902,0,1,3}-{2487,2902,0,1,2}-{2489,2894,0,1,2}-{2490,2905,0,1,7}-{2490,2917,0,1,5}-{2484,2890,0,1,1}-{2491,2927,0,1,1}-{3250,3239,0,1,1}-{3241,3241,0,1,1}-{3249,3249,0,1,1}-{3218,9890,0,1,3}-{3220,9887,0,1,0}-{3218,9887,0,1,1}-{3218,9889,0,1,5}-{3213,9890,0,1,1}-{2496,2890,0,1,4}-{2503,2889,0,1,1}-{2497,2939,0,1,2}-{2369,3374,0,1,0}-{2372,3379,0,1,0}-{2378,3366,0,1,0}-{2379,3378,0,1,0}-{2387,3370,0,1,0}-{2394,3365,0,1,0}-{2402,3386,0,1,0}-{2405,3381,0,1,0}-{2407,3387,0,1,0}-{2412,3384,0,1,0}-" + }, + { + "npc_id": "60", + "loc_data": "{3189,3883,0,1,5}-{3182,3882,0,1,5}-{3177,3871,0,1,0}-{3176,3878,0,1,0}-{3173,3892,0,1,6}-{3171,3884,0,1,4}-{3166,3874,0,1,1}-{3169,3900,0,1,1}-{3165,3881,0,1,3}-{3164,3888,0,1,6}-{3163,3894,0,1,7}-{3162,3894,0,1,4}-{2448,2784,0,1,7}-{2477,2866,0,1,5}-{2455,2857,0,1,6}-{2434,2845,0,1,4}-{2460,2869,0,1,3}-{2484,2897,0,1,3}-{2471,2890,0,1,6}-{2491,2906,0,1,0}-{2544,2904,0,1,2}-{2547,2982,0,1,6}-{2548,2981,0,1,1}-{2523,2975,0,1,1}-" + }, + { + "npc_id": "61", + "loc_data": "{3111,9747,0,1,5}-{3108,9747,0,1,5}-{3156,3248,0,1,4}-{3143,3241,0,1,4}-{3156,3249,0,1,4}-{3175,3248,0,1,7}-{3169,3260,0,1,4}-{3171,3254,0,1,5}-{3162,3246,0,1,6}-{3179,3262,0,1,1}-{3162,3226,0,1,1}-{3166,3222,0,1,1}-{3157,3229,0,1,5}-{3168,3222,0,1,4}-{3182,3878,0,1,6}-{3182,3886,0,1,7}-{3182,3888,0,1,5}-{3175,3888,0,1,4}-{3175,3879,0,1,7}-{3174,3879,0,1,3}-{3174,3882,0,1,0}-{3175,3885,0,1,3}-{3172,3876,0,1,2}-{3172,3894,0,1,1}-{3172,3885,0,1,3}-{3165,3886,0,1,3}-{3165,3896,0,1,1}-{3166,3886,0,1,1}-{3164,3893,0,1,4}-{3163,3881,0,1,4}-{3159,3889,0,1,0}-{2893,9835,0,1,0}-{2895,9828,0,1,0}-{2891,9831,0,1,0}-{3211,9622,0,1,2}-{3215,9620,0,1,4}-{3212,9618,0,1,3}-{3217,9617,0,1,3}-{3214,9620,0,1,7}-{3213,9890,0,1,5}-{3210,9886,0,1,4}-{3213,9887,0,1,1}-{3207,9880,0,1,0}-{3255,9870,0,1,4}-{3258,9872,0,1,3}-{3261,9870,0,1,4}-{3327,3131,0,1,5}-{3321,3145,0,1,3}-{3322,3143,0,1,3}-{2541,3189,0,1,3}-{2542,3187,0,1,6}-{2543,3186,0,1,4}-{2545,3183,0,1,3}-{2545,3183,0,1,3}-{2545,3182,0,1,3}-{2543,3183,0,1,0}-{2543,3182,0,1,3}-{2539,3182,0,1,0}-" + }, + { + "npc_id": "62", + "loc_data": "{2850,3060,0,1,6}-{2857,3044,0,1,7}-{2856,3066,0,1,4}-{2860,3094,0,1,6}-{2854,3086,0,1,6}-{2863,3083,0,1,3}-{2853,3081,0,1,4}-{2859,3079,0,1,4}-{2859,3075,0,1,6}-{2871,3092,0,1,1}-{2867,3094,0,1,1}-{2861,3082,0,1,3}-{2861,3094,0,1,3}-{2863,3081,0,1,2}-{2864,3089,0,1,3}-{2859,3084,0,1,0}-{2885,2950,0,1,4}-{2891,2951,0,1,6}-{2894,2946,0,1,4}-{2928,3022,0,1,3}-{2930,3029,0,1,4}-{2927,3039,0,1,6}-{2928,3043,0,1,0}-{2929,3036,0,1,7}-{2919,3040,0,1,4}-{2934,3045,0,1,2}-{2929,3035,0,1,4}-{2914,3055,0,1,4}-{2922,3059,0,1,3}-{2930,3049,0,1,4}-{2914,3047,0,1,4}-{2935,3049,0,1,1}-{2927,3058,0,1,3}-{2811,2975,0,1,7}-{2815,2987,0,1,5}-{2808,3007,0,1,6}-{2812,3007,0,1,1}-{2784,3030,0,1,4}-{2783,3017,0,1,3}-{2776,3107,0,1,1}-{2794,3121,0,1,3}-{2795,3118,0,1,1}-{2796,3109,0,1,1}-{2808,3112,0,1,6}-{2791,3124,0,1,1}-{2769,3198,0,1,7}-{2768,3206,0,1,1}-" + }, + { + "npc_id": "63", + "loc_data": "{3074,3892,0,1,3}-{2841,9583,0,1,4}-{2841,9582,0,1,4}-{2839,9582,0,1,1}-{2837,9572,0,1,6}-{2832,9580,0,1,1}-{3128,9954,0,1,0}-{3127,9956,0,1,0}-{3125,9958,0,1,0}-{3117,9956,0,1,0}-{3122,9956,0,1,0}-{3120,9952,0,1,0}-{3123,9951,0,1,0}-{3125,9948,0,1,0}-{3118,9950,0,1,0}-{3165,9891,0,1,6}-{3177,9886,0,1,4}-{3175,9889,0,1,4}-{3177,9879,0,1,4}-{3177,9888,0,1,1}-{3178,9895,0,1,4}-{3182,9884,0,1,3}-{3164,9888,0,1,3}-{3169,9892,0,1,6}-{3213,3728,0,1,0}-{3211,3734,0,1,0}-{3214,3738,0,1,0}-{3215,3748,0,1,0}-{3218,3746,0,1,0}-{3226,3750,0,1,0}-{3239,3749,0,1,0}-{3247,3748,0,1,0}-{3248,3746,0,1,0}-{3244,3743,0,1,0}-{3245,3737,0,1,0}-{3258,5560,0,1,2}-{3258,5555,0,1,3}-{3260,5557,0,1,3}-{3257,5552,0,1,1}-{3260,5558,0,1,5}-{3258,5556,0,1,6}-{3257,5555,0,1,6}-{3260,5559,0,1,7}-{3257,5561,0,1,1}-{3071,3894,0,1,7}-{3062,3897,0,1,3}-{3058,3889,0,1,4}-{3054,3880,0,1,2}-{3054,3895,0,1,7}-{3051,3879,0,1,6}-{3051,3886,0,1,6}-{3047,3893,0,1,1}-{3047,3881,0,1,4}-{3044,3893,0,1,5}-{3041,3894,0,1,1}-{3038,3890,0,1,1}-{3046,3872,0,1,4}-" + }, + { + "npc_id": "64", + "loc_data": "{2869,9912,0,1,0}-{2819,9950,0,1,0}-{2824,9934,0,1,0}-{2827,9925,0,1,0}-{2828,9956,0,1,0}-{2857,9969,0,1,0}-{2872,9972,0,1,0}-{2684,9798,0,1,2}-{2885,9962,0,1,0}-{2887,9936,0,1,0}-{2959,3917,0,1,0}-{2960,3925,0,1,0}-{2961,3920,0,1,0}-{2962,3915,0,1,0}-{2962,3933,0,1,0}-{2963,3923,0,1,0}-{2963,3929,0,1,0}-{2965,3927,0,1,0}-{2965,3931,0,1,0}-{2691,9814,0,1,5}-{2694,9819,0,1,6}-{2696,9831,0,1,3}-{2702,9837,0,1,6}-{2709,9844,0,1,3}-{2720,9847,0,1,4}-{2724,9843,0,1,6}-{2733,9846,0,1,4}-{2740,9841,0,1,3}-{2745,9836,0,1,4}-{2745,9828,0,1,5}-{2747,9826,0,1,1}-" + }, + { + "npc_id": "66", + "loc_data": "{2417,3493,1,1,0}-{2418,3495,1,1,0}-{2383,3452,0,1,0}-{2401,3417,0,1,0}-{2402,3422,0,1,0}-{2402,3441,0,1,0}-{2403,3430,0,1,0}-{2408,3441,0,1,0}-{2409,3430,0,1,0}-{2423,3426,0,1,0}-{2427,3428,0,1,0}-{2427,3440,0,1,0}-{2526,3168,0,1,0}-{2529,3163,0,1,0}-{2530,3172,0,1,0}-{2536,3169,0,1,0}-{2435,3460,0,1,0}-{2440,3470,0,1,0}-{2447,3502,0,1,0}-{2457,3462,0,1,0}-{2478,3502,0,1,0}-{2449,3492,1,1,0}-{2450,3490,1,1,0}-{2474,3490,1,1,0}-{2482,3492,1,1,0}-{2482,3498,1,1,0}-{2399,3356,0,1,0}-" + }, + { + "npc_id": "67", + "loc_data": "{2556,3226,0,1,0}-{2456,3425,0,1,0}-{2459,3421,0,1,0}-{2462,3431,0,1,0}-{2394,3500,1,1,0}-{2417,3483,1,1,0}-{2377,3442,0,1,0}-{2380,3425,0,1,0}-{2383,3433,0,1,0}-{2405,3447,0,1,0}-{2406,3440,0,1,0}-{2393,3451,1,1,0}-{2408,3437,1,1,0}-{2521,3169,0,1,0}-{2521,3171,0,1,0}-{2033,5530,1,1,0}-{2437,3478,0,1,0}-{2442,3465,0,1,0}-{2456,3467,0,1,0}-{2471,3496,0,1,0}-{2474,3508,0,1,0}-{2475,3471,0,1,0}-{2479,3468,0,1,0}-{2486,3470,0,1,0}-{2492,3474,0,1,0}-{2443,3464,1,1,0}-{2443,3502,1,1,0}-{2448,3496,1,1,0}-{2449,3506,1,1,0}-{2457,3498,1,1,0}-{2474,3498,1,1,0}-{2480,3502,1,1,0}-{2481,3482,1,1,0}-{2490,3503,1,1,0}-{2400,3356,0,1,0}-" + }, + { + "npc_id": "68", + "loc_data": "{2400,3514,1,1,0}-{2418,3485,1,1,0}-{2378,3423,0,1,0}-{2393,3435,0,1,0}-{2394,3425,0,1,0}-{2395,3449,0,1,0}-{2403,3433,0,1,0}-{2420,3429,0,1,0}-{2420,3438,0,1,0}-{2522,3172,0,1,0}-{2433,3474,0,1,0}-{2433,3492,0,1,0}-{2458,3497,0,1,0}-{2464,3505,0,1,0}-{2476,3458,0,1,0}-{2445,3502,1,1,0}-{2453,3488,1,1,0}-{2475,3502,1,1,0}-{2465,3490,2,1,0}-{2401,3357,0,1,0}-" + }, + { + "npc_id": "73", + "loc_data": "{3123,9657,0,1,2}-{3087,9672,0,1,1}-{3103,9672,0,1,1}-{3119,9670,0,1,1}-{3251,9896,0,1,6}-{3268,9893,0,1,3}-" + }, + { + "npc_id": "74", + "loc_data": "{3124,9660,0,1,3}-{3122,9656,0,1,4}-{3117,9646,0,1,1}-{3124,9651,0,1,2}-{3117,9645,0,1,3}-{3082,9671,0,1,3}-{3105,9672,0,1,1}-{3113,9673,0,1,3}-{3094,9671,0,1,3}-{2843,9767,0,1,3}-{2845,9762,0,1,7}-{2842,9759,0,1,6}-{3126,9865,0,1,7}-{3129,9859,0,1,3}-{3121,9863,0,1,3}-{3126,9862,0,1,5}-{3148,9899,0,1,3}-{3147,9905,0,1,6}-{3141,9901,0,1,5}-{3142,9891,0,1,6}-{3139,9886,0,1,2}-{3148,9883,0,1,1}-{3151,9889,0,1,3}-" + }, + { + "npc_id": "75", + "loc_data": "{2588,9493,0,1,3}-{2584,9491,0,1,3}-{2589,9492,0,1,4}-{2591,9492,0,1,6}-{2593,9491,0,1,6}-{2588,9491,0,1,3}-{2839,9774,0,1,4}-{2931,9641,0,1,6}-{2931,9643,0,1,6}-{3226,9909,0,1,4}-{3225,9905,0,1,0}-{3234,9907,0,1,4}-" + }, + { + "npc_id": "76", + "loc_data": "{2843,9774,0,1,6}-{2842,9769,0,1,4}-{2842,9764,0,1,7}-{2845,9754,0,1,4}-{2849,9751,0,1,1}-{2850,9747,0,1,3}-{2844,9758,0,1,7}-{2540,9814,0,1,6}-{2547,9817,0,1,6}-" + }, + { + "npc_id": "78", + "loc_data": "{2585,3479,0,1,1}-{2589,3480,0,1,2}-{2582,3476,0,1,3}-{2588,3485,0,1,4}-{2580,3490,0,1,5}-{2577,3482,0,1,6}-{2583,3484,0,1,7}-{3073,3961,0,1,0}-{3074,3952,0,1,0}-{3075,3955,0,1,0}-{3076,3961,0,1,0}-{3077,3949,0,1,0}-{3079,3957,0,1,0}-{3080,3961,0,1,0}-{2568,9528,0,1,5}-{2573,9530,0,1,3}-{2575,9525,0,1,6}-{2571,9528,0,1,7}-{2862,9569,0,1,4}-{2857,9571,0,1,7}-{2837,9561,0,1,1}-{2608,9818,0,1,7}-{2609,9825,0,1,5}-{2607,9830,0,1,1}-{2605,9837,0,1,1}-{2607,9833,0,1,6}-{2905,9832,0,1,0}-{2907,9831,0,1,0}-{2913,9828,0,1,0}-{2921,9826,0,1,0}-{2924,9831,0,1,0}-{2921,9834,0,1,0}-{2918,9831,0,1,0}-{2908,9838,0,1,0}-{2913,9841,0,1,0}-{2672,9805,0,1,3}-{2663,9804,0,1,4}-{2658,9809,0,1,5}-{3725,9369,0,1,1}-{3737,9390,0,1,4}-{3738,9399,0,1,0}-{3740,9407,0,1,1}-{3765,9407,0,1,1}-{3762,9395,0,1,3}-{3725,9390,0,1,3}-{3753,9387,0,1,0}-{3728,9382,0,1,3}-{3729,9360,0,1,6}-{3755,9424,0,1,0}-{3760,9440,0,1,4}-{3737,9425,0,1,7}-{3720,9430,0,1,4}-{3736,9451,0,1,3}-{3728,9463,0,1,2}-{3740,9462,0,1,4}-{3770,9463,0,1,1}-{3752,9450,0,1,6}-{3762,9432,0,1,1}-{3733,9421,0,1,7}-{2759,3402,0,1,2}-{2756,3400,0,1,0}-{3787,9459,0,1,1}-{3803,9447,0,1,4}-{3778,9438,0,1,1}-{3786,9422,0,1,4}-{3800,9419,0,1,3}-{3797,9427,0,1,4}-{3820,9432,0,1,5}-{3825,9414,0,1,3}-{3833,9415,0,1,0}-{3825,9449,0,1,3}-{3827,9459,0,1,1}-{3818,9466,0,1,4}-{3799,9460,0,1,1}-{3794,9451,0,1,1}-{2543,9564,0,1,1}-{2543,9562,0,1,1}-{2542,9557,0,1,1}-{2542,9569,0,1,4}-{2540,9566,0,1,0}-{2549,9568,0,1,6}-{2538,9568,0,1,3}-" + }, + { + "npc_id": "80", + "loc_data": "{2619,3265,0,1,0}-{2619,3265,0,1,3}-{2615,3267,0,1,4}-" + }, + { + "npc_id": "81", + "loc_data": "{2589,3120,0,1,4}-{2605,3116,0,1,5}-{2923,3277,0,1,1}-{2921,3289,0,1,1}-{2923,3280,0,1,6}-{3255,3255,0,1,3}-{3255,3256,0,1,4}-{3259,3261,0,1,1}-{3263,3283,0,1,6}-{3257,3268,0,1,4}-{2436,4443,0,1,3}-{2441,4449,0,1,6}-{3038,3310,0,1,5}-{3028,3312,0,1,6}-{3028,3299,0,1,6}-{3042,3300,0,1,6}-" + }, + { + "npc_id": "82", + "loc_data": "{3110,3157,2,1,5}-{3096,3703,0,1,0}-{2841,9557,0,1,3}-{2831,9562,0,1,3}-{2838,9605,0,1,3}-{2936,9652,0,1,3}-{2926,9803,0,1,0}-{2935,9794,0,1,0}-{3052,3117,2,1,1}-{3311,3845,0,1,0}-" + }, + { + "npc_id": "83", + "loc_data": "{3169,3711,0,1,7}-{2639,9477,2,0,3}-{2635,9497,2,0,2}-" + }, + { + "npc_id": "84", + "loc_data": "{2875,9776,0,1,0}-{2862,9776,0,1,0}-{2860,9762,0,1,0}-{2854,9780,0,1,0}-{2866,9781,0,1,0}-{2700,9481,0,0,5}-{2729,9483,0,0,5}-" + }, + { + "npc_id": "86", + "loc_data": "{3105,9517,0,1,7}-{3101,9517,0,1,6}-{3102,9521,0,1,4}-{3106,9519,0,1,1}-{3104,9514,0,1,4}-{3104,9518,0,1,1}-{3107,9519,0,1,1}-{3109,9516,0,1,1}-{3107,9515,0,1,7}-{3105,9512,0,1,6}-{3102,9513,0,1,3}-{3100,9514,0,1,1}-{3100,9516,0,1,7}-{3099,9521,0,1,0}-{3103,9523,0,1,1}-{3098,9880,0,1,5}-{3094,9883,0,1,1}-{3119,9891,0,1,4}-{3188,3181,0,1,7}-{3181,3191,0,1,7}-{3185,3199,0,1,4}-{3176,3198,0,1,6}-{3168,3188,0,1,4}-{3172,3178,0,1,1}-{3179,3174,0,1,1}-{3189,3168,0,1,5}-{3196,3208,0,1,1}-{3196,3205,0,1,0}-{3195,3212,0,1,0}-{2632,9696,0,1,1}-{2639,9697,0,1,3}-{2646,9696,0,1,3}-{2650,9697,0,1,4}-{2646,9702,0,1,6}-{2647,9713,0,1,3}-{2641,9719,0,1,1}-{2650,9716,0,1,1}-{3212,3191,0,1,6}-{3207,3192,0,1,2}-{3216,3184,0,1,2}-{3224,3174,0,1,4}-{3229,3183,0,1,5}-{3222,3185,0,1,3}-{3216,3177,0,1,4}-{3200,3182,0,1,5}-{3202,3189,0,1,6}-{2977,3700,0,1,0}-{2967,3694,0,1,0}-{2973,3694,0,1,0}-{3495,9812,0,1,1}-{3502,9807,0,0,4}-{3249,9868,0,1,4}-{3237,9868,0,1,3}-{3221,9873,0,1,6}-{3225,9862,0,1,2}-{3237,9866,0,1,6}-{3232,9867,0,1,7}-{3219,9862,0,1,7}-{3227,9875,0,1,4}-{2518,3187,0,1,3}-{3291,3388,0,1,6}-{3049,3691,0,1,0}-{3276,9870,0,1,3}-" + }, + { + "npc_id": "87", + "loc_data": "{3103,9881,0,1,3}-{3122,9889,0,1,2}-{3117,9890,0,1,2}-{3242,3530,0,1,7}-{3256,3541,0,1,7}-{3248,3553,0,1,7}-{2520,3188,0,1,3}-{3293,3382,0,1,4}-" + }, + { + "npc_id": "88", + "loc_data": "{2573,9630,0,1,0}-{2601,9802,0,1,6}-{2594,9805,0,1,1}-{2587,9806,0,1,2}-{2585,9803,0,1,1}-{2584,9801,0,1,5}-" + }, + { + "npc_id": "89", + "loc_data": "{2575,3058,0,0,6}-{3080,3451,0,1,1}-{3096,3460,0,1,3}-{3142,3211,0,1,6}-{2629,3266,0,1,2}-{2634,3265,0,1,1}-{2557,3065,0,0,1}-{3294,3344,0,1,3}-{3289,3349,0,1,6}-{3286,3345,0,1,1}-{2783,3463,0,1,7}-" + }, + { + "npc_id": "90", + "loc_data": "{3110,3367,0,0,3}-{3116,3534,0,0,4}-{3072,3531,0,1,0}-{3112,3538,0,1,0}-{2852,9577,0,1,1}-{2865,9567,0,1,3}-{3373,9748,0,1,0}-{3378,9748,0,1,0}-{3382,9753,0,1,0}-{3373,9812,0,1,0}-{3378,9812,0,1,0}-{3382,9817,0,1,0}-{3110,9909,0,1,4}-{3121,9910,0,1,4}-{3133,9909,0,1,5}-{3133,9904,0,1,6}-{3129,9916,0,1,3}-{3133,9916,0,1,0}-{2925,3254,2,0,3}-{2924,3252,2,1,3}-{2926,3255,2,1,4}-{2932,3255,2,1,3}-{2931,3251,2,1,4}-{3194,5448,0,1,3}-{3183,5447,0,1,3}-{3177,5457,0,1,4}-{3187,5456,0,1,1}-{2885,9812,0,1,0}-{2883,9836,0,1,0}-{3141,9875,0,1,6}-{3208,9905,0,1,4}-{3011,3590,0,1,0}-{3016,3596,0,1,0}-{3022,3586,0,1,0}-" + }, + { + "npc_id": "91", + "loc_data": "{3099,9910,0,1,3}-{3100,9906,0,1,6}-{3194,5454,0,1,4}-{3212,9906,0,1,6}-{3252,9916,0,1,3}-{3259,9915,0,1,3}-{3272,9913,0,1,6}-{3274,9914,0,1,1}-{3278,9908,0,1,1}-{3275,9911,0,1,5}-" + }, + { + "npc_id": "92", + "loc_data": "{2848,3248,0,1,3}-{2850,3235,0,1,3}-{2819,3288,0,1,1}-{3111,3561,0,1,3}-{2840,9652,0,1,1}-{2829,9657,0,1,4}-{3122,9661,0,1,6}-{3123,9648,0,1,6}-{3117,9671,0,1,1}-{2593,9883,0,1,1}-{2590,9885,0,1,4}-{2586,9883,0,1,1}-{2585,9878,0,1,3}-{3132,9915,0,1,5}-{3095,9909,0,1,3}-{3143,3802,0,1,0}-{3145,3779,0,1,0}-{3149,9869,0,1,6}-{3138,9878,0,1,5}-{3137,9869,0,1,3}-{2664,9877,0,1,0}-{2980,3763,0,1,0}-{2977,3753,0,1,0}-{2992,3942,0,1,4}-{3005,10362,0,1,1}-{3003,10358,0,1,1}-{3005,10351,0,1,1}-{3003,10345,0,1,5}-{2537,9845,0,1,1}-{2540,9846,0,1,4}-{2552,9844,0,1,6}-{2556,9846,0,1,4}-{2535,9844,0,1,3}-{2532,9843,0,1,4}-{2530,9845,0,1,3}-{2540,9820,0,1,4}-{2544,9824,0,1,4}-" + }, + { + "npc_id": "93", + "loc_data": "{2566,9507,0,1,3}-{2562,9505,0,1,1}-{2568,9509,0,1,3}-{2571,9509,0,1,1}-{2564,9504,0,1,1}-{2566,9505,0,1,1}-{2841,9625,0,1,4}-{2845,9628,0,1,3}-{2841,9638,0,1,6}-{2845,9645,0,1,1}-{3101,9956,0,1,3}-{3104,9948,0,1,0}-{3104,9955,0,1,4}-{3108,9951,0,1,4}-{3108,9954,0,1,1}-{3111,9954,0,1,6}-{3112,9958,0,1,4}-{3194,5460,0,1,6}-{3192,5466,0,1,7}-{3185,5493,0,1,4}-{3182,5494,0,1,6}-{3185,5486,0,1,7}-{3175,5492,0,1,3}-{3169,5496,0,1,4}-{3170,5492,0,1,3}-{3186,5487,0,1,4}-{3169,5491,0,1,2}-{2655,9824,0,1,1}-{2669,9824,0,1,4}-{2667,9823,0,1,5}-{2658,9830,0,1,6}-{2666,9829,0,1,6}-{2637,9891,0,1,0}-{2645,9891,0,1,0}-{2653,9892,0,1,0}-{2653,9892,0,1,0}-{2544,9841,0,1,1}-{2536,9844,0,1,6}-{2527,9844,0,1,3}-{2530,9842,0,1,4}-{2543,9815,0,1,3}-" + }, + { + "npc_id": "94", + "loc_data": "{2589,9881,0,1,6}-{2591,9882,0,1,4}-" + }, + { + "npc_id": "95", + "loc_data": "{2602,2955,0,1,0}-{2605,2963,0,1,0}-{2607,2967,0,1,0}-{2610,2958,0,1,0}-{2610,2961,0,1,0}-{2610,2965,0,1,0}-{2616,3283,0,1,0}-{2620,3283,0,1,0}-{2379,3344,0,1,0}-{2395,3340,0,1,0}-{2398,3330,0,1,0}-{2406,3329,0,1,0}-{2647,3584,0,1,0}-{2680,3585,0,1,0}-{2682,3592,0,1,0}-{2482,2923,0,1,0}-{2462,3274,0,1,0}-{2465,3272,0,1,0}-{2465,3275,0,1,0}-{2470,3272,0,1,0}-{2472,3274,0,1,0}-{2477,3275,0,1,0}-{2437,3336,0,1,0}-{2439,3333,0,1,0}-{2439,3335,0,1,0}-{2440,3333,0,1,0}-{2440,3335,0,1,0}-{2706,3580,0,1,0}-{2717,3569,0,1,0}-{3207,3919,0,1,0}-{3218,3924,0,1,0}-{3229,3917,0,1,0}-{3241,3921,0,1,0}-{2496,2959,0,1,0}-{2498,2968,0,1,0}-{2500,2959,0,1,0}-{2502,2969,0,1,0}-{2509,2964,0,1,0}-{2516,3197,0,1,0}-{2548,3179,0,1,0}-" + }, + { + "npc_id": "96", + "loc_data": "{2842,3450,0,1,0}-{2864,3453,0,1,0}-{2870,3438,0,1,0}-{2872,3445,0,1,0}-{2846,3477,0,1,0}-{2847,3474,0,1,0}-{2860,3492,0,1,0}-{2866,3498,0,1,0}-" + }, + { + "npc_id": "97", + "loc_data": "{2831,3515,0,1,0}-{2833,3513,0,1,0}-{2848,3487,0,1,0}-{2850,3484,0,1,0}-{2854,3509,0,1,0}-{2856,3508,0,1,0}-{2988,3921,0,1,0}-{2991,3924,0,1,0}-{2992,3917,0,1,0}-{2994,3921,0,1,0}-{3002,3924,0,1,0}-{3004,3917,0,1,0}-{3005,3926,0,1,0}-{3006,3921,0,1,0}-" + }, + { + "npc_id": "98", + "loc_data": "{3014,3294,0,1,1}-" + }, + { + "npc_id": "99", + "loc_data": "{2624,3319,0,1,1}-{2624,3327,0,1,6}-{2642,3314,0,1,4}-{2646,3325,0,1,1}-{2646,3504,0,1,4}-{2634,3476,0,1,5}-{2651,3477,0,1,5}-{2665,3472,0,1,5}-{2662,3488,0,1,5}-{2672,3505,0,1,5}-{2790,3199,0,1,2}-{2784,3188,0,1,1}-{2779,3207,0,1,1}-" + }, + { + "npc_id": "100", + "loc_data": "{2567,3440,0,1,3}-{2564,9653,0,1,0}-{2565,9655,0,1,0}-{2566,9626,0,1,0}-{2567,9653,0,1,0}-{2569,9633,0,1,0}-{2607,9621,0,1,0}-{2551,3408,0,1,6}-{2553,3405,0,1,3}-{2559,3452,0,1,3}-" + }, + { + "npc_id": "101", + "loc_data": "{2622,3389,0,1,4}-{2619,3390,0,1,4}-{2573,3437,0,1,3}-{2562,9659,0,1,0}-{2563,9661,0,1,0}-{2599,9626,0,1,0}-{2601,9627,0,1,0}-{2605,9621,0,1,0}-{2610,9620,0,1,0}-{2624,3391,0,1,1}-{2555,3407,0,1,3}-{2553,3457,0,1,3}-" + }, + { + "npc_id": "102", + "loc_data": "{2622,3390,0,1,7}-{2622,3390,0,1,7}-{2562,9657,0,1,0}-{2571,9653,0,1,0}-" + }, + { + "npc_id": "103", + "loc_data": "{2928,3251,1,1,3}-{2928,3244,1,1,4}-{2924,3253,1,1,3}-{2927,3252,1,1,4}-{2927,3254,1,1,3}-{2888,9850,0,1,0}-{2901,9848,0,1,0}-{2909,9848,0,1,0}-{2919,9848,0,1,0}-{2937,9837,0,1,0}-{2906,9818,0,1,0}-{2920,9818,0,1,0}-{2968,3761,0,1,0}-{2985,3761,0,1,0}-{2962,3755,0,1,0}-{2990,3755,0,1,0}-{2968,3749,0,1,0}-{2985,3749,0,1,0}-{2713,4892,0,1,3}-{2711,4899,0,1,3}-{2732,4901,0,1,3}-{2729,4893,0,1,3}-{2713,4907,0,1,3}-{3241,9907,0,1,4}-{3243,9914,0,1,1}-{3242,9913,0,1,6}-{3242,9916,0,1,5}-{3239,9914,0,1,1}-{2501,3289,0,1,1}-{3272,3664,0,1,1}-" + }, + { + "npc_id": "104", + "loc_data": "{3093,3357,1,1,6}-{2894,9849,0,1,0}-{2905,9851,0,1,0}-{2915,9852,0,1,0}-{2934,9837,0,1,0}-{2935,9828,0,1,0}-{2912,9820,0,1,0}-{2900,9819,0,1,0}-" + }, + { + "npc_id": "105", + "loc_data": "{3100,3594,0,1,6}-{3107,3608,0,1,2}-{3099,3602,0,1,0}-{2632,3280,0,1,1}-{2633,3274,0,1,3}-{2696,3329,0,1,4}-{2708,3336,0,1,4}-{3230,3500,0,1,5}-{2988,3671,0,1,0}-{3001,3674,0,1,0}-{2497,3164,0,1,2}-{2387,3376,0,1,0}-{2398,3366,0,1,0}-{2412,3378,0,1,0}-{2419,3372,0,1,0}-" + }, + { + "npc_id": "106", + "loc_data": "{2959,3445,0,1,3}-{2968,3480,0,1,6}-{2968,3490,0,1,3}-{2978,3507,0,1,1}-{2807,3377,0,1,6}-{3289,3353,0,1,3}-" + }, + { + "npc_id": "107", + "loc_data": "{2870,3166,0,1,3}-{2868,3159,0,1,4}-{2867,3172,0,1,5}-{2858,3167,0,1,3}-{2846,3153,0,1,3}-{2851,3149,0,1,1}-{2602,3267,0,1,6}-{2603,3270,0,1,4}-{2607,3268,0,1,5}-{2645,9823,0,1,1}-{2641,9819,0,1,7}-{2641,9817,0,1,2}-{2642,9813,0,1,5}-{2639,9809,0,1,2}-{3256,3954,0,1,1}-{3249,3949,0,1,1}-{3246,3945,0,1,1}-{3239,3943,0,1,1}-{3231,3940,0,1,1}-{3225,3943,0,1,1}-{3234,3945,0,1,1}-{3253,9909,0,1,4}-{2787,2943,0,1,3}-{2789,2949,0,1,3}-{2781,2949,0,1,3}-{2813,3112,0,1,4}-{3275,3154,0,1,6}-{3300,3312,0,1,1}-{3300,3305,0,1,3}-{3298,3300,0,1,5}-{3298,3294,0,1,0}-{3299,3290,0,1,6}-{3025,3568,0,1,0}-{3028,3577,0,1,0}-{3032,3570,0,1,0}-{3040,3581,0,1,0}-{3041,3572,0,1,0}-{3047,3567,0,1,0}-{3055,3574,0,1,0}-{3056,3566,0,1,0}-{3062,3555,0,1,0}-{3062,3570,0,1,0}-{3055,9776,0,1,4}-{3039,9769,0,1,6}-{3049,9764,0,1,3}-{3050,9770,0,1,1}-{3039,9765,0,1,1}-{3048,9762,0,1,4}-{3044,9760,0,1,6}-{3048,9779,0,1,1}-{3038,9802,0,1,5}-{3041,9804,0,1,6}-{3040,9795,0,1,7}-" + }, + { + "npc_id": "108", + "loc_data": "{2941,9779,0,1,0}-{2934,9776,0,1,0}-{2934,9768,0,1,0}-{2934,9757,0,1,0}-{2930,9752,0,1,0}-{2732,3225,0,1,0}-{2729,3224,0,1,0}-{2719,3223,0,1,0}-{2722,3220,0,1,0}-{2724,3216,0,1,0}-{2721,3213,0,1,0}-{2713,3217,0,1,0}-" + }, + { + "npc_id": "109", + "loc_data": "{2601,3269,0,0,0}-{2604,3272,0,0,0}-{2605,3268,0,0,0}-{2606,3271,0,0,0}-" + }, + { + "npc_id": "110", + "loc_data": "{2564,9887,0,1,4}-{2581,9897,0,1,1}-{2577,9888,0,1,1}-{3234,5497,0,1,1}-{3305,9400,0,1,1}-{3244,9356,0,1,1}-{3252,9370,0,1,1}-{3294,9375,0,1,3}-{3050,10337,0,1,4}-{3047,10340,0,1,4}-{3048,10346,0,1,4}-{3048,10346,0,1,3}-" + }, + { + "npc_id": "111", + "loc_data": "{2920,3800,0,1,3}-{2883,9932,0,1,0}-{2883,9965,0,1,0}-{2952,3902,0,1,6}-{2953,3889,0,1,6}-{2947,3921,0,1,6}-{2811,3506,0,1,0}-{3043,9581,0,1,1}-{3055,9577,0,1,6}-{3061,9576,0,1,4}-{3055,9571,0,1,7}-{3052,9566,0,1,6}-" + }, + { + "npc_id": "112", + "loc_data": "{2825,3249,0,1,6}-{2560,3406,0,1,3}-{3144,3822,0,1,0}-{3165,9880,0,1,3}-{3168,9880,0,1,1}-{3159,9903,0,1,4}-{3156,9907,0,1,0}-{2699,3206,0,1,1}-{3202,5490,0,1,4}-{3237,5555,0,1,5}-{2554,3411,0,1,3}-{2554,3400,0,1,3}-{2551,3401,0,1,4}-{2543,9823,0,1,3}-{2540,9819,0,1,5}-{2543,9817,0,1,4}-" + }, + { + "npc_id": "113", + "loc_data": "{2622,3272,0,0,0}-{2835,9526,0,1,4}-{2832,9514,0,1,4}-{2825,9521,0,1,5}-{2846,9520,0,1,3}-{2838,9508,0,1,0}-{2832,9495,0,1,6}-{2838,9492,0,1,6}-{2851,9485,0,1,3}-{2847,9481,0,1,3}-{2865,9494,0,1,3}-{2855,9502,0,1,2}-{2870,9496,0,1,1}-{2851,9511,0,1,2}-{2853,9519,0,1,3}-{2857,9520,0,1,6}-{2863,9525,0,1,1}-{2869,9530,0,1,5}-{2865,9515,0,1,4}-{2868,9507,0,1,3}-{2874,9512,0,1,6}-{2896,2946,0,0,0}-{2918,2961,0,0,0}-{2926,2986,0,0,0}-{2930,3044,0,0,0}-{2926,3056,0,0,0}-{2916,3065,0,0,0}-" + }, + { + "npc_id": "115", + "loc_data": "{2571,3027,0,1,0}-{2572,3031,0,1,0}-{2575,3024,0,1,0}-{2578,3031,0,1,0}-{2510,3044,0,1,0}-{2520,3046,0,1,0}-{2526,3039,0,1,0}-{2502,3114,0,1,0}-{2505,3111,0,1,0}-{2507,3108,0,1,0}-{2508,3119,0,1,0}-{2509,3087,0,1,0}-{2510,3084,0,1,0}-{2513,3087,0,1,0}-{2514,3081,0,1,0}-" + }, + { + "npc_id": "116", + "loc_data": "{2622,3277,0,1,5}-" + }, + { + "npc_id": "117", + "loc_data": "{2369,3404,0,1,0}-{3118,9845,0,1,4}-{3111,9844,0,1,6}-{3123,9845,0,1,3}-{3114,9833,0,1,3}-{3110,9841,0,1,1}-{3119,9839,0,1,1}-{3097,9832,0,1,0}-{3101,9832,0,1,1}-{3107,9829,0,1,3}-{3115,9831,0,1,4}-{3109,9835,0,1,4}-{2904,9734,0,1,0}-{2548,3146,0,1,1}-{2542,3145,0,1,4}-{2503,3150,0,1,4}-{3300,3649,0,1,0}-{3044,10321,0,1,2}-{3044,10316,0,1,4}-{3045,10308,0,1,4}-{3048,10317,0,1,2}-" + }, + { + "npc_id": "118", + "loc_data": "{2603,3056,0,1,0}-{2598,3064,0,1,3}-{2589,3068,0,1,5}-{2930,9703,0,1,0}-{2933,9702,0,1,0}-{3000,9842,0,1,2}-{2996,9844,0,1,4}-{3003,9828,0,1,1}-{2995,9811,0,1,3}-{3002,9811,0,1,3}-{2994,9809,0,1,5}-{3004,9813,0,1,6}-{2998,9828,0,1,4}-{3004,9799,0,1,4}-{2997,9809,0,1,0}-{2983,9807,0,1,6}-{2964,9811,0,1,1}-{3035,3443,0,1,6}-{3008,3449,0,1,4}-{3042,3465,0,1,1}-{3042,3468,0,1,3}-{3019,9813,0,1,4}-{3012,9812,0,1,3}-{3010,9811,0,1,3}-{3025,9801,0,1,4}-{3026,9824,0,1,1}-{3018,9819,0,1,6}-{3028,9815,0,1,3}-{3024,9811,0,1,4}-{3021,9826,0,1,5}-{3022,9832,0,1,1}-{3023,9833,0,1,6}-{3027,9833,0,1,3}-{3028,9828,0,1,6}-{3023,9814,0,1,6}-{3042,9831,0,1,4}-{3024,9824,0,1,6}-{3019,9847,0,1,0}-{3034,9847,0,1,7}-{3021,9851,0,1,5}-{3043,9824,0,1,3}-{3038,9821,0,1,1}-{3044,9818,0,1,4}-{3047,9814,0,1,4}-{3037,9814,0,1,6}-" + }, + { + "npc_id": "119", + "loc_data": "{2921,9757,0,1,0}-{2915,9759,0,1,0}-{2927,9761,0,1,0}-{2925,9769,0,1,0}-{2931,9784,0,1,0}-{2938,9788,0,1,0}-{3233,3783,0,1,0}-{3241,3796,0,1,0}-{3253,3782,0,1,0}-{3019,3760,0,1,0}-{3019,3766,0,1,0}-{3021,3755,0,1,0}-{3025,3763,0,1,0}-{3029,10313,0,1,4}-{3028,10309,0,1,4}-{3033,10311,0,1,6}-{3035,10309,0,1,1}-{3035,10313,0,1,1}-" + }, + { + "npc_id": "120", + "loc_data": "{2874,9880,0,1,0}-{2861,9874,0,1,0}-{2863,9874,0,1,0}-{2866,9874,0,1,0}-{2865,9877,0,1,0}-{2864,9877,0,1,0}-{2861,9877,0,1,0}-{2867,9877,0,1,0}-{2867,9879,0,1,0}-" + }, + { + "npc_id": "122", + "loc_data": "{2566,9632,0,1,0}-{2573,9626,0,1,0}-{2996,9574,0,1,6}-{3007,9579,0,1,7}-{3001,9580,0,1,4}-{2507,3726,0,1,2}-{2523,3724,0,1,3}-{2535,9556,0,1,4}-{3018,9580,0,1,3}-{3021,9585,0,1,4}-{3024,9582,0,1,4}-" + }, + { + "npc_id": "123", + "loc_data": "{2675,3731,0,1,6}-{2669,3726,0,1,6}-{2655,3727,0,1,6}-{2661,3732,0,1,6}-{2656,3720,0,1,6}-{3014,3787,0,1,0}-{3015,3813,0,1,0}-{3017,3781,0,1,0}-{3017,3793,0,1,0}-{3017,3803,0,1,0}-{3019,3789,0,1,0}-{3019,3798,0,1,0}-{3020,3809,0,1,0}-{3022,3805,0,1,0}-{3024,3781,0,1,0}-{3024,3796,0,1,0}-{3024,3812,0,1,0}-{3026,3791,0,1,0}-{3027,3797,0,1,0}-{3027,3804,0,1,0}-{3028,3809,0,1,0}-{3031,3795,0,1,0}-{3031,3802,0,1,0}-{3033,3785,0,1,0}-{3033,3811,0,1,0}-{3035,3806,0,1,0}-{3036,3795,0,1,0}-{3036,3800,0,1,0}-{3038,3809,0,1,0}-{3044,3802,0,1,0}-{3046,3797,0,1,0}-{2533,9554,0,1,4}-{2531,9556,0,1,5}-{2522,9562,0,1,4}-{2524,9558,0,1,4}-{2518,9562,0,1,6}-{2515,9566,0,1,3}-{2517,9573,0,1,1}-" + }, + { + "npc_id": "124", + "loc_data": "{3124,9974,0,1,0}-{3119,9976,0,1,0}-{3116,9974,0,1,0}-{3118,9971,0,1,0}-{3121,9997,0,1,0}-{3124,9996,0,1,0}-{3125,9993,0,1,0}-{3121,9993,0,1,0}-{3115,9992,0,1,0}-{3118,9990,0,1,0}-{3122,9989,0,1,0}-{3142,5532,0,1,6}-{3141,5531,0,1,6}-{3139,5526,0,1,3}-{3143,5524,0,1,3}-{3148,5523,0,1,4}-{3148,5531,0,1,4}-" + }, + { + "npc_id": "125", + "loc_data": "{2845,3517,0,1,4}-{2848,3515,0,1,4}-{2822,9901,0,1,0}-{2836,9905,0,1,0}-{2838,9917,0,1,0}-{2847,9919,0,1,0}-{2848,9912,0,1,0}-{2834,9940,0,1,0}-{2836,9953,0,1,0}-{2844,9944,0,1,0}-{2958,3867,0,1,3}-{2956,3857,0,1,6}-{2952,3862,0,1,3}-{2949,3858,0,1,4}-{2955,3875,0,1,7}-{2954,3874,0,1,5}-{2962,3876,0,1,1}-{2961,3877,0,1,3}-{2947,3878,0,1,6}-{2959,3884,0,1,4}-{2956,3885,0,1,3}-{2956,3886,0,1,3}-{2948,3886,0,1,1}-{2947,3934,0,1,0}-{2948,3917,0,1,0}-{2949,3926,0,1,0}-{2952,3913,0,1,0}-{2952,3936,0,1,0}-{2954,3921,0,1,0}-{2956,3930,0,1,0}-{2964,3944,0,1,0}-{2970,3947,0,1,0}-{2971,3938,0,1,0}-{2977,3953,0,1,0}-{2978,3942,0,1,0}-{2984,3933,0,1,0}-{3227,5443,0,1,5}-{3220,5448,0,1,5}-{3208,5443,0,1,6}-{3207,5448,0,1,4}-{3050,9570,0,1,3}-{3043,9579,0,1,2}-{3056,9585,0,1,0}-{3058,9575,0,1,1}-{3052,9582,0,1,0}-{3049,9577,0,1,4}-{3042,9586,0,1,6}-{3052,9588,0,1,1}-{3049,9590,0,1,5}-{3060,9578,0,1,3}-{3054,9566,0,1,7}-" + }, + { + "npc_id": "126", + "loc_data": "{2381,4422,0,1,5}-{2381,4425,0,1,4}-{2382,4429,0,1,0}-{2385,4419,0,1,0}-{2388,4421,0,1,1}-{2388,4428,0,1,4}-" + }, + { + "npc_id": "127", + "loc_data": "{3193,3959,0,1,0}-{3188,3960,0,1,0}-{3190,3962,0,1,0}-{3187,3959,0,1,0}-{3192,3961,0,1,0}-{3187,3960,0,1,0}-{3193,3959,0,1,0}-{3187,3961,0,1,0}-{3193,3958,0,1,0}-{2956,9791,0,1,0}-{2966,9788,0,1,0}-{2959,9783,0,1,0}-{2964,9775,0,1,0}-{2954,9776,0,1,0}-{2955,9795,0,1,0}-{2962,9792,0,1,0}-" + }, + { + "npc_id": "128", + "loc_data": "{2844,3040,0,1,0}-{2840,3049,0,1,0}-{2837,3043,0,1,0}-{2834,3042,0,1,0}-{2827,3026,0,1,0}-{2824,3018,0,1,0}-{2830,3021,0,1,0}-{2832,3018,0,1,0}-{2824,3084,0,1,0}-{2821,3078,0,1,0}-{2817,3078,0,1,0}-{2837,3076,0,1,0}-{2877,3154,0,1,0}-{2878,3153,0,1,0}-{2870,3161,0,1,0}-{2822,3192,0,1,5}-{2610,3274,0,1,0}-{2610,3275,0,1,0}-{2615,3276,0,1,0}-{2616,3275,0,1,0}-{2616,3276,0,1,0}-{2925,2969,0,1,0}-{2939,2977,0,1,0}-{2936,2980,0,1,0}-{2933,2976,0,1,0}-{2930,2971,0,1,0}-{2928,2984,0,1,0}-{2942,2983,0,1,0}-{2936,2989,0,1,0}-{2887,3145,0,1,0}-{2741,3173,0,0,0}-{2746,3167,0,0,0}-{2746,3147,0,1,0}-{2733,3162,0,1,0}-{2730,3146,0,1,0}-{2782,3104,0,1,0}-{2782,3103,0,1,0}-{2777,3090,0,1,0}-{2773,3089,0,1,0}-{2803,3115,0,1,0}-{2808,3112,0,1,0}-{2759,3179,0,0,0}-{2757,3170,0,0,0}-{2781,3173,0,1,0}-{2770,3213,0,0,0}-" + }, + { + "npc_id": "131", + "loc_data": "{2594,3271,0,1,4}-{2593,3269,0,1,1}-{2592,3272,0,1,6}-" + }, + { + "npc_id": "132", + "loc_data": "{2875,2936,0,1,2}-{2837,3038,0,1,0}-{2837,3041,0,1,3}-{2831,3031,0,1,3}-{2818,3054,0,1,4}-{2832,3050,0,1,6}-{2832,3011,0,1,4}-{2876,3011,0,1,3}-{2863,3021,0,1,3}-{2867,3016,0,1,1}-{2871,3022,0,1,4}-{2877,3028,0,1,3}-{2868,3012,0,1,4}-{2867,3163,0,1,3}-{2856,3144,0,1,7}-{2600,3275,0,1,6}-{2600,3279,0,1,4}-{2603,3279,0,1,3}-{2603,3281,0,1,3}-{2604,3277,0,1,6}-{2897,3064,0,1,0}-{2896,3071,0,1,1}-{2910,3026,0,1,5}-{2902,3010,0,1,1}-{2928,3029,0,1,4}-{2920,3027,0,1,6}-{2932,3023,0,1,3}-{2933,3024,0,1,3}-{2929,3009,0,1,0}-{2927,3022,0,1,1}-{2926,3023,0,1,6}-{2927,3020,0,1,7}-{2891,3079,0,1,1}-{2908,3078,0,1,4}-{2920,3081,0,1,4}-{2890,3082,0,1,1}-{2916,3082,0,1,1}-{2883,3147,0,1,6}-{2945,2979,0,1,3}-{2953,2965,0,1,4}-{2952,2982,0,1,4}-{2955,3003,0,1,3}-{2944,2999,0,1,5}-{2749,3173,0,1,3}-{2784,3005,0,1,1}-{2791,2999,0,1,2}-{2791,2988,0,1,1}-{2795,2987,0,1,6}-{2797,2985,0,1,3}-{2782,3008,0,1,1}-{2812,3180,0,1,1}-{2791,3181,0,1,3}-{2758,3170,0,1,4}-{2754,3167,0,1,3}-{2754,3175,0,1,1}-" + }, + { + "npc_id": "133", + "loc_data": "{3072,3625,0,1,7}-{3079,3627,0,1,3}-{3083,3632,0,1,6}-{3082,3643,0,1,0}-{3079,3637,0,1,5}-{3086,3636,0,1,3}-{3096,3641,0,1,2}-{3115,3644,1,0,5}-{3112,3614,0,1,5}-{3124,3600,0,1,1}-{3132,3597,0,1,0}-{2730,3659,0,1,7}-{2708,3672,0,1,7}-" + }, + { + "npc_id": "134", + "loc_data": "{2598,9558,0,1,6}-{2599,9557,0,1,4}-{2598,9556,0,1,4}-{2600,9555,0,1,3}-{2601,9553,0,1,1}-{2572,9569,0,1,3}-{2599,9552,0,1,6}-{2601,9560,0,1,1}-{2599,9564,0,1,6}-{2600,9563,0,1,4}-{2597,9569,0,1,1}-{2594,9571,0,1,2}-{2589,9571,0,1,4}-{2589,9574,0,1,3}-{2584,9572,0,1,6}-{2581,9575,0,1,6}-{2583,9577,0,1,6}-{2582,9572,0,1,3}-{2572,9568,0,1,1}-{2570,9567,0,1,1}-{2572,9571,0,1,3}-{2575,9572,0,1,0}-{2577,9574,0,1,3}-{2580,9578,0,1,3}-{2597,9572,0,1,6}-{2871,9793,0,1,0}-{2869,9799,0,1,0}-{2876,9806,0,1,0}-{2864,9819,0,1,0}-{2857,9822,0,1,0}-{2858,9814,0,1,0}-{2859,9802,0,1,0}-{2849,9809,0,1,0}-{3088,9945,0,1,3}-{3089,9943,0,1,0}-{3090,9944,0,1,7}-{3278,5477,0,1,1}-{3278,5476,0,1,2}-{3277,5451,0,1,5}-{3283,5449,0,1,4}-{3280,5476,0,1,3}-{3274,5463,0,1,1}-{3272,5477,0,1,1}-{3271,5473,0,1,4}-{3270,5459,0,1,1}-{3271,5454,0,1,3}-{3278,5525,0,1,3}-{3272,5529,0,1,3}-{3270,5536,0,1,6}-{3277,5536,0,1,4}-{3277,5512,0,1,3}-{3279,5516,0,1,6}-{3280,5531,0,1,6}-{3043,10262,0,1,1}-{3044,10252,0,1,4}-{3051,10257,0,1,3}-{3055,10253,0,1,3}-{3067,10255,0,1,3}-{3067,10257,0,1,3}-{3068,10253,0,1,2}-{3069,10257,0,1,4}-{3069,10259,0,1,0}-" + }, + { + "npc_id": "138", + "loc_data": "{2375,3434,0,1,4}-{2379,3438,0,1,6}-" + }, + { + "npc_id": "139", + "loc_data": "{2378,3432,0,1,2}-{2375,3438,0,1,7}-{2376,3431,0,1,1}-{2380,3438,0,1,4}-" + }, + { + "npc_id": "141", + "loc_data": "{3324,5510,0,1,3}-{3286,5512,0,1,1}-{3310,5524,0,1,2}-{3289,5527,0,1,7}-{3296,5519,0,1,4}-" + }, + { + "npc_id": "142", + "loc_data": "{2514,3194,0,1,3}-{2547,3178,0,1,1}-" + }, + { + "npc_id": "143", + "loc_data": "{2835,2934,0,1,4}-{2889,2936,0,1,2}-{2921,2937,0,1,1}-{2787,2929,0,1,6}-" + }, + { + "npc_id": "144", + "loc_data": "{2842,3298,0,1,6}-{2844,3291,0,1,6}-{2851,3298,0,1,4}-{2855,3303,0,1,4}-{2859,3283,0,1,1}-{2861,3295,0,1,5}-{3075,3848,0,1,0}-{3090,3841,0,1,0}-{3070,3829,0,1,0}-{3070,3836,0,1,0}-{3040,9775,0,1,4}-{3048,9770,0,1,1}-" + }, + { + "npc_id": "145", + "loc_data": "{2864,9950,0,1,0}-{2865,9951,0,1,0}-{2866,9948,0,1,0}-{2867,9948,0,1,0}-{2867,9951,0,1,0}-{2868,9950,0,1,0}-" + }, + { + "npc_id": "146", + "loc_data": "{2827,3139,0,1,0}-{2896,2992,0,1,7}-{2976,3053,0,1,0}-{2985,3038,0,1,0}-{2994,3048,0,1,5}-{2992,3030,0,1,0}-" + }, + { + "npc_id": "151", + "loc_data": "{2756,3156,0,0,4}-{2760,3152,0,0,6}-" + }, + { + "npc_id": "152", + "loc_data": "{3103,3347,0,0,0}-{3107,3337,0,0,0}-{3107,3342,0,0,0}-{3107,3344,0,0,0}-{3108,3346,0,0,0}-{3111,3339,0,0,0}-{3111,3348,0,0,0}-{3115,3344,0,0,0}-{3120,3344,0,0,0}-{3122,3335,0,0,0}-" + }, + { + "npc_id": "153", + "loc_data": "{2540,9820,0,1,0}-{2543,9813,0,1,0}-{2546,9817,0,1,0}-{2464,4421,0,1,0}-{2466,4423,0,1,0}-{2486,4464,0,1,0}-{2556,3444,0,1,0}-{3082,3077,0,1,0}-{3092,3082,0,1,0}-{3109,3090,0,1,0}-{3112,3093,0,1,0}-{2249,3260,0,1,0}-{2250,3257,0,1,0}-{2250,3259,0,1,0}-{2252,3261,0,1,0}-{2253,3256,0,1,0}-{2262,3226,0,1,0}-{2264,3225,0,1,0}-{2266,3229,0,1,0}-{2268,3227,0,1,0}-{2269,3222,0,1,0}-{2269,3224,0,1,0}-{2270,3223,0,1,0}-{2270,3226,0,1,0}-{3200,5954,0,1,0}-{3202,5958,0,1,0}-{3204,5955,0,1,0}-{3204,5959,0,1,0}-{3231,5967,0,1,0}-{3236,5974,0,1,0}-{3237,5968,0,1,0}-{3240,5992,0,1,0}-{3240,5994,0,1,0}-{3242,5990,0,1,0}-{3242,5993,0,1,0}-{3244,5994,0,1,0}-{3246,5989,0,1,0}-{2196,3191,0,1,0}-{2197,3189,0,1,0}-{2198,3181,0,1,0}-{2198,3187,0,1,0}-{2199,3183,0,1,0}-{2199,3187,0,1,0}-{2200,3185,0,1,0}-{2201,3185,0,1,0}-{2204,3180,0,1,0}-{2324,4599,0,1,0}-{2325,4597,0,1,0}-{2326,4589,0,1,0}-{2326,4595,0,1,0}-{2327,4591,0,1,0}-{2327,4595,0,1,0}-{2328,4593,0,1,0}-{2329,4593,0,1,0}-{2332,4588,0,1,0}-{2176,3202,0,1,0}-{2178,3206,0,1,0}-{2180,3203,0,1,0}-{2180,3207,0,1,0}-{2207,3215,0,1,0}-{2212,3222,0,1,0}-{2213,3216,0,1,0}-{2216,3240,0,1,0}-{2216,3242,0,1,0}-{2218,3238,0,1,0}-{2218,3241,0,1,0}-{2220,3242,0,1,0}-{2222,3237,0,1,0}-{2437,3425,0,1,0}-{2438,3422,0,1,0}-{2450,3419,0,1,0}-{2415,4466,0,1,0}-{2419,4427,0,1,0}-{2421,4468,0,1,0}-{2426,4431,0,1,0}-{3175,3226,0,1,0}-{3178,3228,0,1,0}-{3179,3226,0,1,0}-{3182,3251,0,1,0}-{3183,3254,0,1,0}-{2697,6204,0,1,0}-{2698,6201,0,1,0}-{2698,6203,0,1,0}-{2700,6205,0,1,0}-{2701,6200,0,1,0}-{2710,6170,0,1,0}-{2712,6169,0,1,0}-{2714,6173,0,1,0}-{2716,6171,0,1,0}-{2717,6166,0,1,0}-{2717,6168,0,1,0}-{2718,6167,0,1,0}-{2718,6170,0,1,0}-{2478,3373,0,1,0}-{2479,3381,0,1,0}-{2481,3384,0,1,0}-{2490,3371,0,1,0}-{2689,6083,0,1,0}-{2689,6088,0,1,0}-{2690,6094,0,1,0}-{2691,6084,0,1,0}-{2692,6081,0,1,0}-{2692,6090,0,1,0}-{2693,6083,0,1,0}-{2693,6085,0,1,0}-{2693,6090,0,1,0}-{2694,6083,0,1,0}-{2694,6086,0,1,0}-{2695,6082,0,1,0}-{2695,6085,0,1,0}-{2695,6088,0,1,0}-{2695,6091,0,1,0}-{2695,6121,0,1,0}-{2698,6121,0,1,0}-{2699,6082,0,1,0}-{2699,6085,0,1,0}-{2700,6084,0,1,0}-{2701,6085,0,1,0}-{2702,6081,0,1,0}-{2702,6083,0,1,0}-{2703,6119,0,1,0}-{2704,6117,0,1,0}-{2705,6121,0,1,0}-{2730,6091,0,1,0}-{2732,6095,0,1,0}-{2734,6090,0,1,0}-{2735,6094,0,1,0}-{2735,6097,0,1,0}-{2738,6098,0,1,0}-{2416,3404,0,1,0}-{2424,3410,0,1,0}-{2430,3405,0,1,0}-{1906,5223,0,1,0}-{1907,5221,0,1,0}-{3273,6012,0,1,0}-{3274,6009,0,1,0}-{3274,6011,0,1,0}-{3276,6013,0,1,0}-{3277,6008,0,1,0}-{3286,5978,0,1,0}-{3288,5977,0,1,0}-{3290,5981,0,1,0}-{3292,5979,0,1,0}-{3293,5974,0,1,0}-{3293,5976,0,1,0}-{3294,5975,0,1,0}-{3294,5978,0,1,0}-{2828,5091,0,1,0}-{2832,5108,0,1,0}-{2835,5079,0,1,0}-{2846,5067,0,1,0}-{2850,5111,0,1,0}-{2853,5086,0,1,0}-{2864,5071,0,1,0}-{2549,3139,0,1,0}-{2241,3139,0,1,0}-{2241,3144,0,1,0}-{2242,3150,0,1,0}-{2243,3140,0,1,0}-{2244,3137,0,1,0}-{2244,3146,0,1,0}-{2245,3139,0,1,0}-{2245,3141,0,1,0}-{2245,3146,0,1,0}-{2246,3139,0,1,0}-{2246,3142,0,1,0}-{2247,3138,0,1,0}-{2247,3141,0,1,0}-{2247,3144,0,1,0}-{2247,3147,0,1,0}-{2247,3177,0,1,0}-{2250,3177,0,1,0}-{2251,3138,0,1,0}-{2251,3141,0,1,0}-{2252,3140,0,1,0}-{2253,3141,0,1,0}-{2254,3137,0,1,0}-{2254,3139,0,1,0}-{2255,3175,0,1,0}-{2256,3173,0,1,0}-{2257,3177,0,1,0}-{2282,3147,0,1,0}-{2284,3151,0,1,0}-{2286,3146,0,1,0}-{2287,3150,0,1,0}-{2287,3153,0,1,0}-{2290,3154,0,1,0}-" + }, + { + "npc_id": "154", + "loc_data": "{2475,4459,0,1,0}-{2480,4458,0,1,0}-{2481,4454,0,1,0}-{2488,4465,0,1,0}-{3125,3084,0,1,0}-{2268,3228,0,1,0}-{3202,5955,0,1,0}-{3206,5953,0,1,0}-{3231,5976,0,1,0}-{3233,5974,0,1,0}-{3235,5970,0,1,0}-{3241,5996,0,1,0}-{3242,5988,0,1,0}-{3244,5992,0,1,0}-{2180,3173,0,1,0}-{2193,3187,0,1,0}-{2196,3184,0,1,0}-{2200,3181,0,1,0}-{2200,3188,0,1,0}-{2203,3189,0,1,0}-{2308,4581,0,1,0}-{2321,4595,0,1,0}-{2324,4592,0,1,0}-{2328,4589,0,1,0}-{2328,4596,0,1,0}-{2331,4597,0,1,0}-{2178,3203,0,1,0}-{2182,3201,0,1,0}-{2207,3224,0,1,0}-{2209,3222,0,1,0}-{2211,3218,0,1,0}-{2217,3244,0,1,0}-{2218,3236,0,1,0}-{2220,3240,0,1,0}-{2446,3396,0,1,0}-{2470,3397,0,1,0}-{2394,4453,0,1,0}-{2394,4457,0,1,0}-{2406,4447,0,1,0}-{2422,3489,0,1,0}-{2716,6172,0,1,0}-{2688,6092,0,1,0}-{2690,6087,0,1,0}-{2690,6095,0,1,0}-{2692,6082,0,1,0}-{2692,6088,0,1,0}-{2692,6123,0,1,0}-{2693,6081,0,1,0}-{2694,6125,0,1,0}-{2695,6087,0,1,0}-{2697,6086,0,1,0}-{2697,6087,0,1,0}-{2698,6081,0,1,0}-{2698,6124,0,1,0}-{2700,6083,0,1,0}-{2702,6084,0,1,0}-{2726,6085,0,1,0}-{2727,6081,0,1,0}-{2729,6083,0,1,0}-{2732,6084,0,1,0}-{2378,3418,0,1,0}-{2380,3422,0,1,0}-{2393,3442,0,1,0}-{2397,3440,0,1,0}-{2423,3399,0,1,0}-{2425,3406,0,1,0}-{2427,3402,0,1,0}-{1908,5222,0,1,0}-{3292,5980,0,1,0}-{2831,5070,0,1,0}-{2843,5106,0,1,0}-{2844,5080,0,1,0}-{2860,5079,0,1,0}-{2866,5104,0,1,0}-{2868,5096,0,1,0}-{2240,3148,0,1,0}-{2242,3143,0,1,0}-{2242,3151,0,1,0}-{2244,3138,0,1,0}-{2244,3144,0,1,0}-{2244,3179,0,1,0}-{2245,3137,0,1,0}-{2246,3181,0,1,0}-{2247,3143,0,1,0}-{2249,3142,0,1,0}-{2249,3143,0,1,0}-{2250,3137,0,1,0}-{2250,3180,0,1,0}-{2252,3139,0,1,0}-{2254,3140,0,1,0}-{2278,3141,0,1,0}-{2279,3137,0,1,0}-{2281,3139,0,1,0}-{2284,3140,0,1,0}-" + }, + { + "npc_id": "155", + "loc_data": "{3093,3086,0,1,0}-{3097,3085,0,1,0}-{3129,3091,0,1,0}-{3135,3084,0,1,0}-{2190,3180,0,1,0}-{2318,4588,0,1,0}-{2374,3469,0,1,0}-{2376,3466,0,1,0}-{3254,3230,0,1,0}-{1986,5564,0,1,0}-{2434,3516,0,1,0}-{2479,3501,0,1,0}-" + }, + { + "npc_id": "156", + "loc_data": "{2371,3460,0,1,0}-{2372,3456,0,1,0}-{2422,3467,0,1,0}-{2725,6127,0,1,0}-{2444,3491,0,1,0}-{2277,3183,0,1,0}-" + }, + { + "npc_id": "157", + "loc_data": "{2180,2798,0,1,0}-{2209,2812,0,1,0}-{2217,2780,0,1,0}-{1921,5931,0,1,0}-{1947,5908,0,1,0}-{1955,5949,0,1,0}-{1973,5888,0,1,0}-{1975,5918,0,1,0}-{1988,5870,0,1,0}-{2017,5884,0,1,0}-{2025,5852,0,1,0}-{2182,2979,0,1,0}-{2211,2963,0,1,0}-{1931,6038,0,1,0}-{1983,6037,0,1,0}-{2153,2810,0,1,0}-{2172,2806,0,1,0}-{1961,5882,0,1,0}-{1980,5878,0,1,0}-{2242,2788,0,1,0}-{2248,2858,0,1,0}-{2256,2828,0,1,0}-{2284,2874,0,1,0}-{2255,3216,0,1,0}-{2262,3210,0,1,0}-{2271,3204,0,1,0}-{2294,3219,0,1,0}-{2296,3206,0,1,0}-{2298,3201,0,1,0}-{2056,5930,0,1,0}-{2064,5900,0,1,0}-{2092,5946,0,1,0}-{2050,5860,0,1,0}-{3201,5986,0,1,0}-{3254,5972,0,1,0}-{3255,5986,0,1,0}-{3256,6008,0,1,0}-{3257,5973,0,1,0}-{3257,5975,0,1,0}-{3260,5974,0,1,0}-{3261,5977,0,1,0}-{3262,5957,0,1,0}-{2194,3158,0,1,0}-{2216,3188,0,1,0}-{2217,3190,0,1,0}-{2220,3158,0,1,0}-{2222,3141,0,1,0}-{2229,3138,0,1,0}-{2231,3181,0,1,0}-{2236,3155,0,1,0}-{2278,2956,0,1,0}-{2322,4566,0,1,0}-{2344,4596,0,1,0}-{2345,4598,0,1,0}-{2348,4566,0,1,0}-{2350,4549,0,1,0}-{2357,4546,0,1,0}-{2359,4589,0,1,0}-{2364,4563,0,1,0}-{2177,3234,0,1,0}-{2230,3220,0,1,0}-{2231,3234,0,1,0}-{2232,3256,0,1,0}-{2233,3221,0,1,0}-{2233,3223,0,1,0}-{2236,3222,0,1,0}-{2237,3225,0,1,0}-{2238,3205,0,1,0}-{2479,3396,0,1,0}-{2102,2942,0,1,0}-{2108,2919,0,1,0}-{2104,2873,0,1,0}-{2122,6032,0,1,0}-{1912,5945,0,1,0}-{3143,3210,0,1,0}-{3155,3253,0,1,0}-{3163,3261,0,1,0}-{3168,3258,0,1,0}-{2086,6028,0,1,0}-{2703,6160,0,1,0}-{2710,6154,0,1,0}-{2719,6148,0,1,0}-{2742,6163,0,1,0}-{2744,6150,0,1,0}-{2746,6145,0,1,0}-{2314,2960,0,1,0}-{2723,6105,0,1,0}-{2739,6123,0,1,0}-{2744,6108,0,1,0}-{2326,2894,0,1,0}-{2333,2920,0,1,0}-{3279,5968,0,1,0}-{3286,5962,0,1,0}-{3295,5956,0,1,0}-{3318,5971,0,1,0}-{3320,5958,0,1,0}-{3322,5953,0,1,0}-{2134,5966,0,1,0}-{2141,5992,0,1,0}-{2123,2966,0,1,0}-{2175,2965,0,1,0}-{1910,6014,0,1,0}-{1916,5991,0,1,0}-{2540,3167,0,1,0}-{2110,2955,0,1,0}-{1990,6051,0,1,0}-{2019,6035,0,1,0}-{2447,3467,0,1,0}-{2448,3469,0,1,0}-{1918,6027,0,1,0}-{2275,3161,0,1,0}-{2291,3179,0,1,0}-{2296,3164,0,1,0}-{2113,2859,0,1,0}-{2139,2836,0,1,0}-{2147,2877,0,1,0}-{2165,2816,0,1,0}-{2167,2846,0,1,0}-" + }, + { + "npc_id": "158", + "loc_data": "{2693,9776,0,1,0}-{2697,9773,0,1,0}-{2697,9779,0,1,0}-{2700,9770,0,1,0}-{2700,9774,0,1,0}-{2700,9777,0,1,0}-{2701,9781,0,1,0}-{2703,9770,0,1,0}-{2703,9774,0,1,0}-{2703,9779,0,1,0}-{2705,9757,0,1,0}-{2705,9760,0,1,0}-{2705,9766,0,1,0}-{2706,9753,0,1,0}-{2706,9763,0,1,0}-{2706,9772,0,1,0}-{2707,9756,0,1,0}-{2707,9761,0,1,0}-{2708,9758,0,1,0}-" + }, + { + "npc_id": "159", + "loc_data": "{2392,3475,0,1,0}-{2394,3506,0,1,0}-{2396,3471,0,1,0}-{2405,3499,0,1,0}-{2416,3487,0,1,0}-{2413,3445,1,1,0}-{2415,3435,1,1,0}-{2416,3416,1,1,0}-{2424,3434,1,1,0}-{2483,3500,1,1,0}-" + }, + { + "npc_id": "160", + "loc_data": "{2424,3430,1,1,0}-{2474,3500,1,1,0}-" + }, + { + "npc_id": "161", + "loc_data": "{2409,3436,1,1,0}-{2484,3501,1,1,0}-" + }, + { + "npc_id": "162", + "loc_data": "{2480,3426,0,1,6}-{2489,3429,0,1,1}-{2480,3431,0,1,0}-{2475,3418,0,1,4}-{2470,3423,0,1,1}-" + }, + { + "npc_id": "163", + "loc_data": "{2451,3414,0,1,0}-{2459,3395,0,1,0}-{2459,3438,0,1,0}-{2462,3395,0,1,0}-{2445,3429,1,1,0}-{2409,3470,1,1,0}-{2416,3466,1,1,0}-{2420,3466,1,1,0}-{2461,9895,0,1,0}-{2465,9894,0,1,0}-{2465,9899,0,1,0}-{2459,3385,0,1,0}-{2463,3385,0,1,0}-{2392,3454,0,1,0}-{2394,3436,0,1,0}-{2408,3452,0,1,0}-{2421,3413,0,1,0}-{2442,3489,0,1,0}-{2450,3485,0,1,0}-{2451,3507,0,1,0}-{2453,3490,0,1,0}-{2459,3503,0,1,0}-{2461,3509,0,1,0}-{2464,3465,0,1,0}-{2464,3468,0,1,0}-{2468,3465,0,1,0}-{2468,3468,0,1,0}-{2468,3506,0,1,0}-{2472,3484,0,1,0}-{2475,3490,0,1,0}-{2475,3502,0,1,0}-{2477,3512,0,1,0}-{2481,3485,0,1,0}-{2482,3501,0,1,0}-{2467,3495,1,1,0}-{2473,3495,1,1,0}-{2448,3497,2,1,0}-{2463,3480,2,1,0}-{2465,3497,2,1,0}-{2465,3510,2,1,0}-{2466,3480,2,1,0}-" + }, + { + "npc_id": "164", + "loc_data": "{2459,3392,0,1,0}-{2461,3422,0,1,0}-{2462,3392,0,1,0}-{2460,3382,0,1,0}-{2462,3382,0,1,0}-{2410,3416,0,1,0}-{2420,3435,0,1,0}-{2420,3447,0,1,0}-{2427,3410,0,1,0}-{2012,5535,2,1,0}-{2023,5544,2,1,0}-{2441,3497,0,1,0}-{2447,3510,0,1,0}-{2461,3487,0,1,0}-{2464,3472,0,1,0}-{2464,3489,0,1,0}-{2467,3489,0,1,0}-{2468,3472,0,1,0}-{2473,3503,0,1,0}-{2478,3497,0,1,0}-{2464,3496,1,1,0}-{2448,3495,2,1,0}-{2460,3487,2,1,0}-{2467,3494,2,1,0}-{2467,3510,2,1,0}-{2471,3496,2,1,0}-{2483,3495,2,1,0}-{2483,3497,2,1,0}-" + }, + { + "npc_id": "166", + "loc_data": "{2448,3427,1,0,6}-{2448,3424,1,0,6}-{2443,3424,1,0,3}-{2443,3425,1,0,3}-{2450,3480,1,0,1}-{2449,3480,1,0,1}-{2448,3480,1,0,1}-{2440,3488,1,0,4}-{2440,3487,1,0,4}-" + }, + { + "npc_id": "168", + "loc_data": "{2434,3436,0,1,0}-{2437,3451,0,1,0}-{2438,3427,0,1,0}-{2441,3411,0,1,0}-{2466,3449,0,1,0}-{2470,3399,0,1,0}-{2472,3400,0,1,0}-{2473,3412,0,1,0}-{2476,3454,0,1,0}-{2482,3397,0,1,0}-{2489,3401,0,1,0}-{2479,3407,1,1,0}-{2379,3482,0,1,0}-{2381,3496,0,1,0}-{2384,3497,0,1,0}-{2391,3476,0,1,0}-{2410,3496,0,1,0}-{2421,3481,0,1,0}-{2397,3514,1,1,0}-{2398,3451,1,1,0}-{2414,3447,1,1,0}-{2438,3465,0,1,0}-{2442,3505,0,1,0}-{2448,3486,0,1,0}-{2449,3487,0,1,0}-{2450,3489,0,1,0}-{2450,3505,0,1,0}-{2454,3465,0,1,0}-{2449,3486,1,1,0}-{2457,3488,1,1,0}-{2476,3488,1,1,0}-{2450,3496,2,1,0}-{2467,3488,2,1,0}-{2470,3503,2,1,0}-{2481,3498,2,1,0}-" + }, + { + "npc_id": "169", + "loc_data": "{2439,3433,0,1,0}-{2441,3449,0,1,0}-{2442,3428,0,1,0}-{2446,3403,0,1,0}-{2450,3416,0,1,0}-{2468,3441,0,1,0}-{2480,3408,0,1,0}-{2480,3406,1,1,0}-{2486,3400,1,1,0}-{2378,3482,0,1,0}-{2383,3496,0,1,0}-{2402,3507,0,1,0}-{2406,3476,0,1,0}-{2422,3485,0,1,0}-{2382,3506,1,1,0}-{2418,3472,1,1,0}-{2392,3450,1,1,0}-{2415,3415,1,1,0}-{2416,3434,1,1,0}-{2423,3425,1,1,0}-{2424,3442,1,1,0}-{2448,3489,0,1,0}-{2450,3488,0,1,0}-{2463,3508,0,1,0}-{2473,3489,0,1,0}-{2474,3457,0,1,0}-{2479,3503,0,1,0}-{2486,3467,0,1,0}-{2437,3463,1,1,0}-{2448,3489,1,1,0}-{2482,3508,1,1,0}-" + }, + { + "npc_id": "170", + "loc_data": "{2890,3175,0,1,4}-" + }, + { + "npc_id": "171", + "loc_data": "{2409,9817,0,1,0}-" + }, + { + "npc_id": "175", + "loc_data": "{3084,3495,0,1,4}-{3179,3215,0,1,0}-{3182,3365,0,1,6}-{2994,9549,0,1,6}-{2993,9551,0,1,6}-{2995,9555,0,1,6}-{2999,9548,0,1,0}-" + }, + { + "npc_id": "178", + "loc_data": "{3096,3220,0,1,1}-{2909,9690,0,1,0}-{2911,9689,0,1,0}-{2905,9687,0,1,0}-{2912,9682,0,1,0}-{2917,9681,0,1,0}-{2918,9679,0,1,0}-{2916,9677,0,1,0}-{2911,9675,0,1,0}-{2906,9675,0,1,0}-{2905,9673,0,1,0}-{2897,9675,0,1,0}-{2899,9678,0,1,0}-{2898,9682,0,1,0}-{2897,9687,0,1,0}-{2903,9690,0,1,0}-{2904,9692,0,1,0}-{2902,9693,0,1,0}-{2915,9691,0,1,0}-{2916,9694,0,1,0}-{2913,9694,0,1,0}-{2908,9694,0,1,0}-{2908,9702,0,1,0}-{2906,9706,0,1,0}-{2915,9703,0,1,0}-{2915,9711,0,1,0}-{2899,9700,0,1,0}-{2898,9703,0,1,0}-{2898,9708,0,1,0}-{2900,9710,0,1,0}-{2907,9711,0,1,0}-{2923,9710,0,1,0}-{2920,9708,0,1,0}-{2919,9703,0,1,0}-{2891,9679,0,1,0}-{2891,9682,0,1,0}-{2890,9692,0,1,0}-{2891,9695,0,1,0}-{2892,9701,0,1,0}-{2893,9701,0,1,0}-{2892,9709,0,1,0}-{2895,9710,0,1,0}-{2942,9801,0,1,0}-{2938,9812,0,1,0}-{3273,3507,0,1,6}-" + }, + { + "npc_id": "179", + "loc_data": "{3025,3511,1,1,3}-{3038,3505,0,1,4}-{3026,3494,0,1,6}-{3026,3505,0,1,4}-{3026,3512,0,1,6}-{3025,3512,0,1,4}-{3027,3512,0,1,6}-{3030,3511,0,1,6}-{3028,3511,0,1,1}-{3023,3514,1,1,3}-{3014,3516,2,1,1}-{3038,3854,0,1,4}-{3029,3852,0,1,1}-{3032,3851,0,1,3}-{3023,3849,0,1,6}-{3042,3856,0,1,0}-{3050,3849,0,1,0}-{3054,3852,0,1,0}-{3057,3842,0,1,0}-{3058,3854,0,1,0}-" + }, + { + "npc_id": "180", + "loc_data": "{3110,3295,0,1,4}-{2957,3238,0,1,4}-{2953,3240,0,1,3}-{2988,3423,0,1,7}-{2744,3519,0,0,0}-{3011,3277,0,1,1}-{3009,3280,0,1,1}-" + }, + { + "npc_id": "181", + "loc_data": "{2563,3355,0,1,4}-{2561,3355,0,1,3}-{2561,3357,0,1,1}-{2563,3358,0,1,4}-{3105,9942,0,1,3}-{3106,9934,0,1,3}-{3109,9930,0,1,1}-{2937,9847,0,1,0}-{2934,9846,0,1,0}-{2929,9848,0,1,0}-{2931,9846,0,1,0}-{2937,9849,0,1,0}-{2936,9850,0,1,0}-" + }, + { + "npc_id": "182", + "loc_data": "{3690,2966,0,1,4}-" + }, + { + "npc_id": "183", + "loc_data": "{3670,2977,0,1,1}-{3654,2960,0,1,0}-{3698,2969,0,1,2}-{3676,2991,0,1,3}-{3666,2994,0,1,7}-{3666,2981,1,1,4}-{2805,3160,0,0,0}-{2803,3190,0,1,4}-{2795,3167,0,0,0}-{2793,3184,0,1,3}-" + }, + { + "npc_id": "184", + "loc_data": "{3659,2952,0,1,6}-{3669,2961,0,1,4}-{3683,2977,0,1,6}-{3668,2981,0,1,3}-{3655,2973,0,1,1}-{3675,2967,0,1,3}-{2994,9584,0,1,6}-{2992,9573,0,1,1}-{2990,9583,0,1,4}-{2998,9572,0,1,2}-{2998,9573,0,1,4}-{2989,9578,0,1,0}-{2993,9566,0,1,4}-{2994,9570,0,1,3}-{3039,3958,0,1,0}-" + }, + { + "npc_id": "186", + "loc_data": "{3160,3568,0,1,0}-{3167,3576,0,1,0}-{3171,3579,0,1,0}-{3172,3561,0,1,0}-{3175,3572,0,1,0}-{3179,3564,0,1,0}-{3184,3580,0,1,0}-{3189,3563,0,1,0}-{3190,3570,0,1,0}-" + }, + { + "npc_id": "187", + "loc_data": "{3076,3916,0,1,0}-{3079,3909,0,1,0}-{3291,3924,0,1,4}-{3294,3930,0,1,4}-{3286,3933,0,1,6}-{3285,3928,0,1,6}-{3287,3935,1,1,6}-{3286,3927,1,1,6}-{3283,3936,2,1,6}-{3292,3932,1,1,4}-{3291,3940,0,1,6}-{3280,3943,0,1,6}-{3278,3926,0,1,4}-" + }, + { + "npc_id": "188", + "loc_data": "{2940,3517,0,1,3}-{2938,3517,0,1,3}-{3158,5497,0,1,6}-{3157,5494,0,1,1}-{3155,5498,0,1,6}-{3140,5494,0,1,6}-{3143,5493,0,1,5}-{3142,5497,0,1,4}-{3156,5494,0,1,5}-{3148,5496,0,1,4}-" + }, + { + "npc_id": "189", + "loc_data": "{2936,3514,0,1,3}-{2931,3514,0,1,3}-{2933,3517,0,1,3}-{2936,3517,0,1,3}-{3151,5489,0,1,7}-{3151,5489,0,1,7}-{3145,5495,0,1,3}-{3142,5493,0,1,3}-{3149,5489,0,1,6}-{3155,5491,0,1,2}-{3142,5497,0,1,3}-" + }, + { + "npc_id": "190", + "loc_data": "{2833,9814,0,1,0}-{2829,9812,0,1,0}-{2825,9811,0,1,0}-{2829,9808,0,1,0}-{2833,9808,0,1,0}-{2827,9805,0,1,0}-" + }, + { + "npc_id": "191", + "loc_data": "{2868,3053,0,1,0}-{2840,3018,0,1,0}-{2919,2983,0,1,0}-{2937,2993,0,1,0}-{2940,2994,0,1,0}-{2940,2997,0,1,0}-{2942,2997,0,1,0}-{2730,3161,0,1,0}-{2729,3159,0,1,0}-{2727,3163,0,1,0}-{2725,3157,0,1,0}-{2726,3161,0,1,0}-{2725,3161,0,1,0}-{2723,3155,0,1,0}-{2723,3156,0,1,0}-{2725,3162,0,1,0}-{2775,3066,0,1,0}-{2802,3071,0,1,0}-{2770,3018,0,1,0}-{2770,3014,0,1,0}-" + }, + { + "npc_id": "192", + "loc_data": "{3022,3624,0,1,0}-{3022,3639,0,1,0}-{3029,3638,0,1,0}-{3030,3626,0,1,0}-{3035,3632,0,1,0}-{3036,3624,0,1,0}-{3036,3639,0,1,0}-{3022,3624,1,1,0}-{3022,3639,1,1,0}-{3023,3632,1,1,0}-{3028,3626,1,1,0}-{3029,3637,1,1,0}-{3035,3631,1,1,0}-{3036,3624,1,1,0}-{3036,3639,1,1,0}-" + }, + { + "npc_id": "193", + "loc_data": "{2581,9505,0,1,4}-{2594,9497,0,1,1}-{2593,9499,0,1,7}-{2587,9498,0,1,3}-{2573,9500,0,1,5}-{2579,9503,0,1,5}-{2580,9500,0,1,4}-{2578,9497,0,1,7}-" + }, + { + "npc_id": "195", + "loc_data": "{3029,3701,0,1,6}-{3031,3685,0,1,6}-{3032,3695,0,1,6}-{3033,3705,0,1,6}-{3037,3683,0,1,6}-{3040,3703,0,1,6}-" + }, + { + "npc_id": "196", + "loc_data": "{3038,3670,0,1,1}-{3036,3672,0,1,2}-{3037,3661,0,1,6}-{3039,3660,0,1,6}-" + }, + { + "npc_id": "198", + "loc_data": "{3190,3358,0,1,1}-" + }, + { + "npc_id": "199", + "loc_data": "{3079,3443,0,1,3}-" + }, + { + "npc_id": "201", + "loc_data": "{2931,9692,0,0,0}-" + }, + { + "npc_id": "202", + "loc_data": "{3039,3700,0,1,0}-" + }, + { + "npc_id": "203", + "loc_data": "{3038,3695,0,1,0}-" + }, + { + "npc_id": "204", + "loc_data": "{3035,3696,0,1,0}-" + }, + { + "npc_id": "205", + "loc_data": "{2613,9523,0,1,0}-" + }, + { + "npc_id": "206", + "loc_data": "{3026,3455,0,1,6}-{3015,3458,0,1,5}-" + }, + { + "npc_id": "208", + "loc_data": "{2568,3459,0,1,4}-" + }, + { + "npc_id": "209", + "loc_data": "{3013,3452,0,1,6}-" + }, + { + "npc_id": "216", + "loc_data": "{2851,3348,0,0,7}-" + }, + { + "npc_id": "217", + "loc_data": "{2852,3343,0,1,2}-" + }, + { + "npc_id": "218", + "loc_data": "{2613,3475,0,1,2}-" + }, + { + "npc_id": "222", + "loc_data": "{2851,3351,0,0,7}-{2849,3348,0,0,7}-" + }, + { + "npc_id": "223", + "loc_data": "{2569,3250,0,1,0}-" + }, + { + "npc_id": "224", + "loc_data": "{2579,9655,0,1,0}-{2581,9656,0,1,0}-{2581,9659,0,1,0}-{2583,9659,0,1,0}-{2584,9656,0,1,0}-{2586,9659,0,1,0}-{2587,9656,0,1,0}-{2589,9654,0,1,0}-{2589,9658,0,1,0}-{2591,9656,0,1,0}-{2591,9659,0,1,0}-" + }, + { + "npc_id": "225", + "loc_data": "{2641,3437,0,0,0}-" + }, + { + "npc_id": "227", + "loc_data": "{2643,3440,0,0,0}-" + }, + { + "npc_id": "228", + "loc_data": "{2634,3427,0,0,0}-" + }, + { + "npc_id": "229", + "loc_data": "{2628,3413,0,1,4}-" + }, + { + "npc_id": "230", + "loc_data": "{2649,3454,0,0,0}-" + }, + { + "npc_id": "231", + "loc_data": "{2650,3468,0,0,0}-" + }, + { + "npc_id": "232", + "loc_data": "{2819,3487,0,0,4}-" + }, + { + "npc_id": "237", + "loc_data": "{2769,3403,0,1,0}-{2766,3402,0,1,3}-{2770,3402,0,1,0}-{2772,3404,0,1,1}-{2767,3405,1,1,0}-{2771,3403,1,1,6}-{2767,3401,1,1,7}-" + }, + { + "npc_id": "239", + "loc_data": "{2758,3516,1,0,0}-" + }, + { + "npc_id": "240", + "loc_data": "{2760,3501,0,1,1}-" + }, + { + "npc_id": "241", + "loc_data": "{2762,3498,0,0,0}-" + }, + { + "npc_id": "242", + "loc_data": "{2764,3509,1,0,0}-" + }, + { + "npc_id": "243", + "loc_data": "{2756,3513,1,0,0}-" + }, + { + "npc_id": "244", + "loc_data": "{2765,3504,1,0,0}-" + }, + { + "npc_id": "245", + "loc_data": "{2755,3517,0,0,0}-" + }, + { + "npc_id": "247", + "loc_data": "{2769,3402,2,1,5}-" + }, + { + "npc_id": "250", + "loc_data": "{2924,3405,0,0,1}-" + }, + { + "npc_id": "251", + "loc_data": "{2761,3512,0,0,0}-" + }, + { + "npc_id": "253", + "loc_data": "{2580,3163,0,1,1}-{2590,3184,0,1,1}-{2589,3140,0,1,1}-{2601,3177,0,1,1}-{2607,3182,0,1,1}-{2612,3187,0,1,1}-" + }, + { + "npc_id": "254", + "loc_data": "{2569,3149,0,0,1}-{2614,3169,0,1,1}-{2564,3153,0,1,1}-{2568,3147,0,1,1}-{2579,3176,0,1,3}-{2580,3174,0,1,1}-{2584,3149,0,1,3}-{2590,3190,0,1,1}-{2594,3181,0,1,1}-{2595,3186,0,1,1}-{2597,3175,0,1,1}-{2597,3181,0,1,1}-{2607,3185,0,1,1}-{2614,3150,0,1,1}-{2619,3168,0,1,1}-" + }, + { + "npc_id": "255", + "loc_data": "{2571,3142,0,1,1}-{2617,3150,0,1,1}-{2609,3171,0,0,1}-{2617,3157,0,1,1}-{2577,3167,0,1,1}-{2597,3176,0,1,1}-{2607,3181,0,1,1}-{2608,3148,0,1,1}-{2600,3190,0,1,1}-{2610,3150,0,1,1}-{2609,3171,0,1,1}-" + }, + { + "npc_id": "256", + "loc_data": "{2609,3194,0,1,2}-" + }, + { + "npc_id": "259", + "loc_data": "{2566,3140,0,0,1}-" + }, + { + "npc_id": "260", + "loc_data": "{2589,3142,0,1,4}-" + }, + { + "npc_id": "261", + "loc_data": "{2587,3142,0,1,3}-" + }, + { + "npc_id": "262", + "loc_data": "{2615,3160,0,1,4}-{2616,3164,0,1,1}-{2594,3143,0,0,2}-" + }, + { + "npc_id": "263", + "loc_data": "{2597,3143,0,0,4}-" + }, + { + "npc_id": "264", + "loc_data": "{2568,3200,0,1,0}-" + }, + { + "npc_id": "266", + "loc_data": "{2601,3154,0,1,0}-" + }, + { + "npc_id": "267", + "loc_data": "{2601,3168,0,1,3}-" + }, + { + "npc_id": "268", + "loc_data": "{2582,3172,0,1,1}-" + }, + { + "npc_id": "269", + "loc_data": "{2608,3163,0,1,3}-" + }, + { + "npc_id": "270", + "loc_data": "{2608,3165,0,1,3}-" + }, + { + "npc_id": "271", + "loc_data": "{2608,3158,0,1,3}-" + }, + { + "npc_id": "272", + "loc_data": "{3127,3485,0,1,1}-" + }, + { + "npc_id": "273", + "loc_data": "{2573,3321,0,1,3}-" + }, + { + "npc_id": "274", + "loc_data": "{2638,9899,0,1,6}-{2639,9911,0,1,6}-{2648,9901,0,1,6}-{2649,9912,0,1,6}-{2649,9905,0,1,6}-{2650,9897,0,1,6}-" + }, + { + "npc_id": "275", + "loc_data": "{2636,9910,0,1,4}-{2637,9897,0,1,4}-{2643,9913,0,1,6}-{2646,9906,0,1,6}-" + }, + { + "npc_id": "276", + "loc_data": "{2656,9875,0,1,3}-" + }, + { + "npc_id": "278", + "loc_data": "{3209,3215,0,0,0}-" + }, + { + "npc_id": "279", + "loc_data": "{2604,3209,0,0,0}-" + }, + { + "npc_id": "280", + "loc_data": "{2615,3258,0,1,6}-" + }, + { + "npc_id": "281", + "loc_data": "{2604,3219,0,1,6}-{2609,3207,0,1,6}-{2618,3211,0,1,6}-" + }, + { + "npc_id": "282", + "loc_data": "{2562,9608,0,1,6}-{2564,9604,0,1,6}-{3280,3494,0,1,6}-" + }, + { + "npc_id": "283", + "loc_data": "{2569,9602,0,1,6}-" + }, + { + "npc_id": "284", + "loc_data": "{2953,3450,0,0,0}-" + }, + { + "npc_id": "285", + "loc_data": "{3110,3330,0,0,0}-" + }, + { + "npc_id": "286", + "loc_data": "{3111,3367,2,0,4}-" + }, + { + "npc_id": "287", + "loc_data": "{2770,3403,2,1,3}-" + }, + { + "npc_id": "288", + "loc_data": "{3110,3366,2,0,2}-{2677,3655,0,1,3}-{2681,3653,0,1,6}-" + }, + { + "npc_id": "289", + "loc_data": "{2616,3302,0,1,3}-" + }, + { + "npc_id": "290", + "loc_data": "{2614,3306,0,1,4}-" + }, + { + "npc_id": "296", + "loc_data": "{3084,3518,0,1,1}-" + }, + { + "npc_id": "297", + "loc_data": "{3093,3518,0,1,5}-" + }, + { + "npc_id": "298", + "loc_data": "{3113,3513,0,1,3}-" + }, + { + "npc_id": "299", + "loc_data": "{3113,3511,0,1,3}-" + }, + { + "npc_id": "300", + "loc_data": "{3105,9569,0,0,0}-" + }, + { + "npc_id": "302", + "loc_data": "{2519,3429,0,1,1}-" + }, + { + "npc_id": "304", + "loc_data": "{2520,3496,0,1,3}-" + }, + { + "npc_id": "305", + "loc_data": "{2511,3484,0,0,4}-" + }, + { + "npc_id": "306", + "loc_data": "{2514,9580,0,1,1}-" + }, + { + "npc_id": "307", + "loc_data": "{2968,3206,0,0,0}-" + }, + { + "npc_id": "308", + "loc_data": "{2611,3393,0,1,4}-" + }, + { + "npc_id": "309", + "loc_data": "{2860,2976,0,0,4}-{2856,2977,0,0,4}-{2852,2973,0,0,4}-{2561,3374,0,0,4}-{2562,3374,0,0,4}-{2566,3370,0,0,0}-{3104,3424,0,0,0}-{3104,3425,0,0,0}-{2637,3444,0,0,0}-{2678,3595,0,0,4}-{2633,3693,0,0,4}-{2633,3694,0,0,4}-{2471,3146,0,0,4}-{2465,3156,0,0,4}-{2461,3150,0,0,4}-{2215,3248,0,0,4}-{2217,3245,0,0,4}-{2213,3241,0,0,4}-{2716,3530,0,0,0}-{2267,3253,0,0,4}-{2266,3253,0,0,4}-{2262,3249,0,0,4}-" + }, + { + "npc_id": "310", + "loc_data": "{2860,2972,0,0,6}-{2865,2972,0,0,4}-{2382,3414,0,0,4}-{2382,3415,0,0,0}-{2392,3420,0,0,0}-{3239,3243,0,0,6}-{3239,3241,0,0,6}-{3238,3252,0,0,6}-{2537,3406,0,0,4}-{2527,3412,0,0,4}-{2507,3421,0,0,4}-{2508,3421,0,0,4}-" + }, + { + "npc_id": "312", + "loc_data": "{2860,3426,0,0,1}-{2421,3789,0,0,0}-{2410,3780,0,0,0}-{2414,3780,0,0,0}-" + }, + { + "npc_id": "313", + "loc_data": "{2840,3356,0,0,1}-{2843,3359,0,0,1}-{2848,3361,0,0,1}-{2879,3339,0,0,1}-{2879,3338,0,0,1}-{2879,3335,0,0,1}-{2879,3334,0,0,1}-{2876,3331,0,0,1}-{2853,3423,0,0,1}-{2401,3781,0,0,0}-" + }, + { + "npc_id": "316", + "loc_data": "{3086,3227,0,0,1}-{3085,3230,0,0,0}-{2986,3176,0,0,4}-{2996,3157,0,0,1}-{2790,3273,0,0,1}-{2790,3276,0,0,6}-{2794,3283,0,0,6}-{2795,3279,0,0,3}-" + }, + { + "npc_id": "322", + "loc_data": "{2641,3700,0,0,4}-{2640,3700,0,0,4}-{2777,2740,0,0,4}-{2780,2741,0,0,4}-{2788,2741,0,0,4}-{2771,2733,0,0,4}-{2771,2734,0,0,4}-" + }, + { + "npc_id": "323", + "loc_data": "{2926,3177,0,0,6}-{3248,3161,0,0,4}-{2516,3575,0,0,7}-{2511,3562,0,0,7}-{2498,3547,0,0,7}-" + }, + { + "npc_id": "324", + "loc_data": "{2632,3427,0,0,0}-{2645,3708,0,0,1}-{2648,3708,0,0,1}-{2647,3711,0,0,1}-" + }, + { + "npc_id": "325", + "loc_data": "{2671,3160,0,0,4}-{2672,3160,0,0,4}-{2678,3160,0,0,4}-{2682,3160,0,0,4}-{2683,3160,0,0,4}-" + }, + { + "npc_id": "326", + "loc_data": "{2840,3431,0,0,0}-{2855,3423,0,0,1}-{2607,3416,0,0,1}-{2604,3417,0,0,1}-{2602,3419,0,0,1}-{3246,3156,0,0,0}-{3245,3152,0,0,0}-{3242,3148,0,0,0}-{3267,3148,0,0,6}-{3276,3140,0,0,6}-{3275,3140,0,0,6}-" + }, + { + "npc_id": "333", + "loc_data": "{2845,3429,0,0,6}-{2602,3411,0,0,3}-{2605,3413,0,0,3}-{2609,3416,0,0,3}-{2610,3413,0,0,3}-{2605,3421,0,0,1}-{2602,3423,0,0,1}-{2603,3426,0,0,1}-{2923,3178,0,0,6}-{2923,3180,0,0,6}-{2926,3180,0,0,6}-" + }, + { + "npc_id": "334", + "loc_data": "{2612,3411,0,0,0}-{2165,3268,0,0,4}-{2162,3274,0,0,4}-{2627,3415,0,0,0}-{2639,3698,0,0,4}-{2642,3698,0,0,4}-{2699,2702,0,0,4}-{2694,2706,0,0,4}-{2700,2702,0,0,4}-{2707,2698,0,0,4}-{2700,2702,0,0,0}-{2700,2702,0,0,0}-{2700,2702,0,0,0}-{2707,2698,0,0,0}-{2707,2698,0,0,0}-{2707,2698,0,0,0}-" + }, + { + "npc_id": "335", + "loc_data": "{2592,3336,0,1,0}-" + }, + { + "npc_id": "336", + "loc_data": "{2928,3218,0,1,4}-" + }, + { + "npc_id": "338", + "loc_data": "{2929,3222,0,0,6}-" + }, + { + "npc_id": "340", + "loc_data": "{2929,3217,0,1,6}-" + }, + { + "npc_id": "342", + "loc_data": "{3281,3382,0,0,0}-" + }, + { + "npc_id": "343", + "loc_data": "{3284,3382,0,0,0}-" + }, + { + "npc_id": "344", + "loc_data": "{2510,3378,0,1,0}-{2511,3383,0,1,0}-{2515,3356,0,1,0}-{2519,3356,0,1,0}-{2521,3383,0,1,0}-{2524,3362,0,1,0}-{2525,3383,0,1,0}-" + }, + { + "npc_id": "345", + "loc_data": "{2519,3366,0,1,0}-{2525,3369,0,1,0}-{2531,3368,0,1,0}-" + }, + { + "npc_id": "346", + "loc_data": "{2508,3370,0,1,0}-{2512,3374,0,1,0}-{2518,3371,0,1,0}-{2525,3380,0,1,0}-" + }, + { + "npc_id": "347", + "loc_data": "{2524,3292,0,1,3}-{2536,3294,0,1,3}-{2538,3321,0,1,3}-" + }, + { + "npc_id": "348", + "loc_data": "{2501,3315,0,1,3}-{2513,3325,0,1,3}-{2526,3279,0,1,3}-{2528,3297,0,1,3}-{2535,3288,0,1,3}-{2548,3287,0,1,3}-" + }, + { + "npc_id": "349", + "loc_data": "{2556,3266,0,0,0}-" + }, + { + "npc_id": "350", + "loc_data": "{2559,3266,0,0,0}-" + }, + { + "npc_id": "351", + "loc_data": "{2465,3307,0,1,0}-{2482,3293,0,1,0}-{2509,3325,0,1,0}-" + }, + { + "npc_id": "352", + "loc_data": "{2453,3307,0,1,0}-{2480,3300,0,1,0}-{2511,3322,0,1,0}-{2540,3279,0,1,0}-" + }, + { + "npc_id": "353", + "loc_data": "{2473,3288,0,1,0}-{2504,3326,0,1,0}-{2509,3314,0,1,0}-{2546,3277,0,1,0}-" + }, + { + "npc_id": "354", + "loc_data": "{2470,3290,0,1,0}-{2472,3296,0,1,0}-{2483,3318,0,1,0}-{2483,3323,0,1,0}-{2490,3293,0,1,0}-{2510,3318,0,1,0}-{2524,3271,0,1,0}-" + }, + { + "npc_id": "355", + "loc_data": "{2464,3302,0,1,0}-{2466,3300,0,1,0}-{2466,3307,0,1,0}-{2467,3306,0,1,0}-{2468,3315,0,1,0}-{2469,3319,0,1,0}-{2471,3323,0,1,0}-{2473,3305,0,1,0}-{2474,3296,0,1,0}-{2476,3307,0,1,0}-{2478,3323,0,1,0}-{2480,3296,0,1,0}-{2481,3313,0,1,0}-{2485,3312,0,1,0}-{2504,3318,0,1,0}-{2547,3277,0,1,0}-" + }, + { + "npc_id": "356", + "loc_data": "{2462,3306,0,1,0}-{2465,3305,0,1,0}-{2469,3295,0,1,0}-{2477,3320,0,1,0}-{2482,3311,0,1,0}-{2518,3275,0,1,0}-{2523,3307,0,1,0}-" + }, + { + "npc_id": "357", + "loc_data": "{2518,3309,0,1,3}-{2526,3303,0,1,3}-{2543,3309,0,1,3}-{2552,3320,0,1,3}-" + }, + { + "npc_id": "358", + "loc_data": "{2529,3285,0,1,0}-" + }, + { + "npc_id": "360", + "loc_data": "{2472,3307,0,1,0}-{2492,3314,0,1,0}-{2553,3275,0,1,0}-" + }, + { + "npc_id": "361", + "loc_data": "{2463,3317,0,1,0}-{2482,3296,0,1,0}-{2485,3315,0,1,0}-{2519,3277,0,1,0}-" + }, + { + "npc_id": "362", + "loc_data": "{2482,3286,0,1,0}-{2489,3295,0,1,0}-{2537,3324,0,1,0}-" + }, + { + "npc_id": "363", + "loc_data": "{2468,3290,0,1,0}-{2475,3325,0,1,0}-{2479,3312,0,1,0}-{2513,3315,0,1,0}-" + }, + { + "npc_id": "364", + "loc_data": "{2577,3298,1,0,0}-" + }, + { + "npc_id": "366", + "loc_data": "{2612,3324,0,0,0}-" + }, + { + "npc_id": "367", + "loc_data": "{2935,3210,0,1,2}-" + }, + { + "npc_id": "368", + "loc_data": "{3263,3407,0,1,2}-" + }, + { + "npc_id": "369", + "loc_data": "{2548,3324,0,1,3}-{2550,3326,0,1,3}-{2553,3325,0,1,3}-" + }, + { + "npc_id": "370", + "loc_data": "{2549,3325,1,1,0}-{2550,3327,1,1,0}-" + }, + { + "npc_id": "371", + "loc_data": "{2545,3326,0,1,3}-{2551,3322,0,1,3}-{2555,3324,0,1,3}-" + }, + { + "npc_id": "372", + "loc_data": "{2561,3305,0,1,2}-{2561,3303,0,1,7}-{2559,3304,0,1,3}-" + }, + { + "npc_id": "373", + "loc_data": "{2516,3274,0,1,0}-" + }, + { + "npc_id": "375", + "loc_data": "{3053,3249,0,0,0}-" + }, + { + "npc_id": "376", + "loc_data": "{3027,3217,0,1,4}-" + }, + { + "npc_id": "377", + "loc_data": "{3028,3223,0,1,2}-" + }, + { + "npc_id": "378", + "loc_data": "{3028,3220,0,1,4}-" + }, + { + "npc_id": "379", + "loc_data": "{2939,3156,0,1,4}-" + }, + { + "npc_id": "380", + "loc_data": "{2953,3149,0,0,0}-{2770,3226,0,0,0}-" + }, + { + "npc_id": "381", + "loc_data": "{2684,3272,0,1,4}-" + }, + { + "npc_id": "382", + "loc_data": "{3044,9758,0,1,3}-" + }, + { + "npc_id": "383", + "loc_data": "{2582,3485,0,1,7}-" + }, + { + "npc_id": "384", + "loc_data": "{2545,3568,0,1,7}-{2545,3571,0,1,6}-" + }, + { + "npc_id": "385", + "loc_data": "{2552,3570,0,1,6}-" + }, + { + "npc_id": "386", + "loc_data": "{2877,9797,0,1,0}-" + }, + { + "npc_id": "387", + "loc_data": "{3058,3488,1,0,0}-" + }, + { + "npc_id": "388", + "loc_data": "{2709,3485,0,1,1}-{2716,3475,0,1,3}-{2697,3472,0,1,6}-{2702,3469,0,1,3}-" + }, + { + "npc_id": "389", + "loc_data": "{2704,3405,3,1,3}-" + }, + { + "npc_id": "397", + "loc_data": "{3254,3258,0,1,1}-{3261,3260,0,1,1}-{3259,3279,0,1,6}-{3247,3292,0,1,3}-{3260,3291,0,1,2}-{3247,3282,0,1,5}-{3252,3283,0,1,6}-{3264,3258,0,1,2}-{3026,3303,0,1,4}-" + }, + { + "npc_id": "398", + "loc_data": "{2849,5091,0,0,0}-{2726,3349,0,1,6}-" + }, + { + "npc_id": "399", + "loc_data": "{2846,5081,0,0,0}-{2730,3349,0,1,1}-" + }, + { + "npc_id": "400", + "loc_data": "{2728,3377,0,1,1}-" + }, + { + "npc_id": "401", + "loc_data": "{2823,2941,0,0,0}-{2861,2941,0,0,0}-{2800,2943,0,0,0}-{2762,2944,0,0,0}-" + }, + { + "npc_id": "402", + "loc_data": "{2818,2939,0,0,0}-{2870,2943,0,0,0}-{2933,2944,0,0,0}-{2762,2943,0,0,0}-{2791,2944,0,0,0}-" + }, + { + "npc_id": "407", + "loc_data": "{3059,4507,0,0,3}-" + }, + { + "npc_id": "411", + "loc_data": "{2878,3161,0,0,0}-{2887,3164,0,0,0}-" + }, + { + "npc_id": "412", + "loc_data": "{3341,3478,0,1,0}-{3343,3484,0,1,0}-{3345,3484,0,1,0}-{3350,3493,0,1,0}-{3353,3494,0,1,0}-{3361,3484,0,1,0}-{3364,3489,0,1,0}-{3370,3497,0,1,0}-{3379,3478,0,1,0}-{3379,3484,0,1,0}-{3387,3483,0,1,0}-{3388,3494,0,1,0}-{3389,3483,0,1,0}-{3588,3472,0,1,0}-{3598,3509,0,1,0}-{3599,3486,0,1,0}-{3607,3462,0,1,0}-{3611,3499,0,1,0}-{3613,3482,0,1,0}-{3627,3511,0,1,0}-{3628,3473,0,1,0}-{3636,3466,0,1,0}-{3639,3510,0,1,0}-{3411,3536,0,1,0}-{3418,3522,0,1,0}-{3425,3525,0,1,0}-{3429,3522,0,1,0}-{3432,3527,0,1,0}-{3434,3521,0,1,0}-{3445,3526,0,1,0}-{2728,10122,0,1,1}-{2735,10123,0,1,3}-{2733,10129,0,1,1}-{2728,10133,0,1,6}-{2722,10133,0,1,6}-{2736,10137,0,1,1}-{2732,10142,0,1,0}-{2726,10142,0,1,6}-{2729,10140,0,1,3}-{2720,10144,0,1,6}-{2712,10142,0,1,3}-{3565,3503,0,1,0}-{3567,3481,0,1,0}-{3580,3491,0,1,0}-" + }, + { + "npc_id": "419", + "loc_data": "{3195,5450,0,1,6}-{3181,5449,0,1,1}-" + }, + { + "npc_id": "420", + "loc_data": "{3175,5454,0,1,4}-" + }, + { + "npc_id": "421", + "loc_data": "{3195,5459,0,1,6}-{3186,5454,0,1,5}-{3173,5494,0,1,6}-{3179,5491,0,1,1}-{3185,5492,0,1,4}-{3184,5487,0,1,3}-" + }, + { + "npc_id": "423", + "loc_data": "{2731,5340,0,1,7}-" + }, + { + "npc_id": "424", + "loc_data": "{2724,5359,0,1,3}-" + }, + { + "npc_id": "425", + "loc_data": "{2717,5332,0,1,7}-" + }, + { + "npc_id": "429", + "loc_data": "{2363,5214,0,1,6}-{2358,5214,0,1,7}-{2361,5212,0,1,6}-{2361,5209,0,1,4}-{2359,5213,0,1,1}-{2364,5215,0,1,6}-{2361,5216,0,1,1}-{2361,5212,0,1,0}-" + }, + { + "npc_id": "437", + "loc_data": "{2807,3191,0,0,0}-" + }, + { + "npc_id": "444", + "loc_data": "{2551,3197,0,1,1}-{2555,3194,0,1,4}-{2551,3157,0,1,3}-{2525,3155,0,1,3}-{2518,3149,0,1,3}-{2502,3175,0,1,1}-" + }, + { + "npc_id": "445", + "loc_data": "{2550,3196,0,1,4}-{2557,3197,0,1,1}-{2538,3155,0,1,7}-" + }, + { + "npc_id": "446", + "loc_data": "{2994,3194,0,1,1}-{3285,9896,0,1,1}-{3279,9895,0,1,6}-" + }, + { + "npc_id": "447", + "loc_data": "{3114,3242,0,1,1}-" + }, + { + "npc_id": "448", + "loc_data": "{3120,3238,0,1,6}-" + }, + { + "npc_id": "449", + "loc_data": "{3127,3248,0,1,1}-" + }, + { + "npc_id": "450", + "loc_data": "{3081,3220,0,1,0}-{3081,3222,0,1,0}-" + }, + { + "npc_id": "451", + "loc_data": "{3077,3234,0,1,0}-{2994,3215,0,1,2}-" + }, + { + "npc_id": "452", + "loc_data": "{3223,3293,0,0,0}-" + }, + { + "npc_id": "454", + "loc_data": "{2899,3430,1,1,3}-" + }, + { + "npc_id": "455", + "loc_data": "{2925,3485,0,1,5}-" + }, + { + "npc_id": "456", + "loc_data": "{3244,3205,0,0,0}-" + }, + { + "npc_id": "458", + "loc_data": "{3148,3175,0,1,4}-" + }, + { + "npc_id": "459", + "loc_data": "{2566,9507,0,1,6}-{2565,9506,0,0,5}-{2566,9507,0,1,3}-" + }, + { + "npc_id": "460", + "loc_data": "{2590,9488,0,1,3}-" + }, + { + "npc_id": "461", + "loc_data": "{2588,3091,1,1,3}-" + }, + { + "npc_id": "462", + "loc_data": "{2590,3084,0,1,5}-" + }, + { + "npc_id": "469", + "loc_data": "{2542,3169,0,1,4}-" + }, + { + "npc_id": "470", + "loc_data": "{2519,3212,0,1,3}-" + }, + { + "npc_id": "471", + "loc_data": "{2526,3160,1,1,6}-" + }, + { + "npc_id": "472", + "loc_data": "{2521,3168,0,1,4}-" + }, + { + "npc_id": "473", + "loc_data": "{2503,3192,0,0,0}-{2514,3159,0,0,6}-" + }, + { + "npc_id": "475", + "loc_data": "{2454,3300,0,1,7}-{2455,3301,0,1,7}-{2513,3262,0,1,3}-{2522,3251,0,1,1}-" + }, + { + "npc_id": "477", + "loc_data": "{2455,3301,0,1,6}-" + }, + { + "npc_id": "478", + "loc_data": "{2509,3255,0,1,3}-{2503,3254,1,1,3}-" + }, + { + "npc_id": "479", + "loc_data": "{1970,5522,3,1,0}-{2384,3481,0,1,0}-{2388,3473,0,1,0}-{2418,3474,3,1,0}-{2415,3433,3,1,0}-{2466,3500,2,1,0}-" + }, + { + "npc_id": "480", + "loc_data": "{1964,5522,3,1,0}-{2458,3417,1,1,0}-{2460,3417,1,1,0}-{2409,3507,0,1,0}-{2412,3474,3,1,0}-{2463,3504,2,1,0}-" + }, + { + "npc_id": "481", + "loc_data": "{2499,3266,0,0,4}-" + }, + { + "npc_id": "482", + "loc_data": "{2524,3258,0,1,4}-" + }, + { + "npc_id": "483", + "loc_data": "{2501,3234,0,0,4}-" + }, + { + "npc_id": "484", + "loc_data": "{2537,3168,0,1,5}-{2542,3167,0,0,1}-{2541,3168,0,0,2}-{2541,3171,0,0,3}-{2542,3172,0,0,4}-" + }, + { + "npc_id": "487", + "loc_data": "{1885,5029,0,0,6}-" + }, + { + "npc_id": "490", + "loc_data": "{1887,5026,0,0,6}-" + }, + { + "npc_id": "494", + "loc_data": "{2615,3094,0,0,3}-{2615,3092,0,0,3}-{2615,3092,0,0,3}-{2615,3094,0,0,3}-{3122,3125,0,0,6}-{3120,3125,0,0,6}-{3090,3242,0,0,4}-{3090,3245,0,0,4}-{3090,3243,0,0,4}-{2618,3330,0,0,0}-{2619,3330,0,0,0}-{2584,3422,0,0,4}-{2584,3419,0,0,4}-{2584,3418,0,0,4}-{2657,3283,0,0,3}-{2657,3286,0,0,3}-{2807,3443,0,0,6}-{2810,3443,0,0,6}-" + }, + { + "npc_id": "495", + "loc_data": "{2615,3091,0,0,3}-{2615,3091,0,0,3}-{2615,3330,0,0,0}-{2584,3421,0,0,4}-{2809,3443,0,0,6}-{2811,3443,0,0,6}-" + }, + { + "npc_id": "496", + "loc_data": "{3267,3164,0,0,4}-{3267,3167,0,0,4}-{3267,3169,0,0,4}-" + }, + { + "npc_id": "497", + "loc_data": "{3267,3166,0,0,4}-{3267,3168,0,0,4}-" + }, + { + "npc_id": "498", + "loc_data": "{2384,4457,0,0,7}-{2385,4461,0,0,1}-" + }, + { + "npc_id": "499", + "loc_data": "{2853,2953,0,0,1}-{2852,2953,0,0,1}-" + }, + { + "npc_id": "500", + "loc_data": "{2880,2951,0,0,6}-" + }, + { + "npc_id": "504", + "loc_data": "{2870,2950,0,0,0}-{2877,2959,0,0,0}-" + }, + { + "npc_id": "505", + "loc_data": "{2868,2954,0,0,6}-{2876,2948,0,0,1}-" + }, + { + "npc_id": "510", + "loc_data": "{2780,3211,0,0,0}-" + }, + { + "npc_id": "511", + "loc_data": "{2834,2956,0,0,0}-" + }, + { + "npc_id": "512", + "loc_data": "{2862,2995,1,0,0}-" + }, + { + "npc_id": "513", + "loc_data": "{2857,2962,0,0,6}-" + }, + { + "npc_id": "514", + "loc_data": "{2870,2974,1,0,6}-" + }, + { + "npc_id": "515", + "loc_data": "{2834,2987,0,0,0}-" + }, + { + "npc_id": "516", + "loc_data": "{2826,2958,0,1,3}-" + }, + { + "npc_id": "517", + "loc_data": "{2870,2970,0,0,0}-" + }, + { + "npc_id": "518", + "loc_data": "{2764,2959,1,0,0}-" + }, + { + "npc_id": "519", + "loc_data": "{3228,3203,0,1,6}-" + }, + { + "npc_id": "520", + "loc_data": "{3217,3241,0,1,4}-" + }, + { + "npc_id": "521", + "loc_data": "{3217,3240,0,1,3}-" + }, + { + "npc_id": "522", + "loc_data": "{3218,3415,0,1,3}-" + }, + { + "npc_id": "523", + "loc_data": "{3217,3411,0,1,3}-" + }, + { + "npc_id": "524", + "loc_data": "{3316,3184,0,1,3}-" + }, + { + "npc_id": "525", + "loc_data": "{3316,3182,0,1,3}-" + }, + { + "npc_id": "527", + "loc_data": "{2959,3390,0,1,1}-{2957,3388,0,1,3}-" + }, + { + "npc_id": "528", + "loc_data": "{3078,3512,0,1,3}-" + }, + { + "npc_id": "529", + "loc_data": "{3079,3507,0,1,7}-" + }, + { + "npc_id": "530", + "loc_data": "{2947,3217,0,1,1}-" + }, + { + "npc_id": "531", + "loc_data": "{2947,3212,0,1,1}-" + }, + { + "npc_id": "532", + "loc_data": "{2906,3145,0,1,3}-" + }, + { + "npc_id": "533", + "loc_data": "{2906,3144,0,1,3}-" + }, + { + "npc_id": "534", + "loc_data": "{2375,4449,0,1,5}-" + }, + { + "npc_id": "535", + "loc_data": "{2376,4447,0,0,0}-" + }, + { + "npc_id": "536", + "loc_data": "{3192,3359,1,1,3}-" + }, + { + "npc_id": "537", + "loc_data": "{3192,3355,1,1,6}-" + }, + { + "npc_id": "538", + "loc_data": "{3076,3429,0,1,3}-" + }, + { + "npc_id": "539", + "loc_data": "{3299,3204,0,0,0}-" + }, + { + "npc_id": "540", + "loc_data": "{3288,3212,0,1,6}-" + }, + { + "npc_id": "541", + "loc_data": "{3288,3190,0,1,3}-" + }, + { + "npc_id": "542", + "loc_data": "{3316,3175,0,1,3}-" + }, + { + "npc_id": "543", + "loc_data": "{3272,3182,0,1,6}-" + }, + { + "npc_id": "544", + "loc_data": "{3316,3164,0,1,3}-" + }, + { + "npc_id": "545", + "loc_data": "{3322,3195,0,1,3}-" + }, + { + "npc_id": "546", + "loc_data": "{3203,3433,0,1,3}-" + }, + { + "npc_id": "547", + "loc_data": "{3217,3435,0,0,3}-" + }, + { + "npc_id": "548", + "loc_data": "{3205,3416,0,1,6}-" + }, + { + "npc_id": "549", + "loc_data": "{3229,3438,0,1,6}-" + }, + { + "npc_id": "550", + "loc_data": "{3232,3423,0,1,6}-" + }, + { + "npc_id": "551", + "loc_data": "{3210,3400,0,1,3}-" + }, + { + "npc_id": "552", + "loc_data": "{3206,3400,0,1,3}-" + }, + { + "npc_id": "553", + "loc_data": "{3253,3403,0,1,1}-" + }, + { + "npc_id": "554", + "loc_data": "{3281,3398,0,1,3}-" + }, + { + "npc_id": "555", + "loc_data": "{2657,3153,0,1,0}-" + }, + { + "npc_id": "556", + "loc_data": "{3012,3244,0,1,6}-" + }, + { + "npc_id": "557", + "loc_data": "{3012,3203,0,1,1}-" + }, + { + "npc_id": "558", + "loc_data": "{3013,3225,0,1,1}-" + }, + { + "npc_id": "559", + "loc_data": "{3026,3252,0,1,3}-" + }, + { + "npc_id": "560", + "loc_data": "{2767,3122,0,1,6}-" + }, + { + "npc_id": "561", + "loc_data": "{2514,3385,0,1,0}-" + }, + { + "npc_id": "562", + "loc_data": "{2799,3438,0,1,1}-" + }, + { + "npc_id": "563", + "loc_data": "{2803,3430,0,1,6}-" + }, + { + "npc_id": "564", + "loc_data": "{2485,4450,0,1,3}-" + }, + { + "npc_id": "565", + "loc_data": "{2476,4467,0,1,2}-" + }, + { + "npc_id": "566", + "loc_data": "{2480,4471,0,1,4}-" + }, + { + "npc_id": "568", + "loc_data": "{2925,3143,0,1,3}-" + }, + { + "npc_id": "569", + "loc_data": "{2659,3316,0,1,2}-" + }, + { + "npc_id": "570", + "loc_data": "{2669,3303,0,1,5}-" + }, + { + "npc_id": "571", + "loc_data": "{2655,3310,0,1,1}-{2669,3310,0,1,3}-" + }, + { + "npc_id": "572", + "loc_data": "{2659,3296,0,1,4}-" + }, + { + "npc_id": "573", + "loc_data": "{2663,3296,0,1,4}-" + }, + { + "npc_id": "574", + "loc_data": "{2656,3300,0,1,3}-" + }, + { + "npc_id": "575", + "loc_data": "{2821,3442,0,1,6}-" + }, + { + "npc_id": "576", + "loc_data": "{2836,3447,0,1,4}-" + }, + { + "npc_id": "577", + "loc_data": "{2975,3384,0,1,3}-" + }, + { + "npc_id": "578", + "loc_data": "{2807,3342,0,1,6}-" + }, + { + "npc_id": "579", + "loc_data": "{3034,9845,0,1,3}-" + }, + { + "npc_id": "580", + "loc_data": "{2952,3388,0,1,3}-" + }, + { + "npc_id": "581", + "loc_data": "{2975,3314,0,1,3}-" + }, + { + "npc_id": "582", + "loc_data": "{2998,9828,0,1,1}-" + }, + { + "npc_id": "583", + "loc_data": "{3011,3257,0,1,3}-" + }, + { + "npc_id": "584", + "loc_data": "{2944,3332,0,1,3}-" + }, + { + "npc_id": "585", + "loc_data": "{2946,3205,0,1,6}-" + }, + { + "npc_id": "586", + "loc_data": "{2884,3450,0,1,3}-" + }, + { + "npc_id": "587", + "loc_data": "{2897,3428,0,1,3}-" + }, + { + "npc_id": "588", + "loc_data": "{2803,3152,0,1,3}-" + }, + { + "npc_id": "589", + "loc_data": "{2660,3291,0,1,3}-" + }, + { + "npc_id": "590", + "loc_data": "{2613,3294,0,1,3}-" + }, + { + "npc_id": "591", + "loc_data": "{2615,3292,0,1,6}-" + }, + { + "npc_id": "592", + "loc_data": "{2597,3401,0,1,2}-" + }, + { + "npc_id": "593", + "loc_data": "{2569,3098,0,1,3}-" + }, + { + "npc_id": "594", + "loc_data": "{2998,9840,0,1,3}-" + }, + { + "npc_id": "595", + "loc_data": "{3271,3412,0,1,3}-" + }, + { + "npc_id": "596", + "loc_data": "{3037,3705,0,0,0}-" + }, + { + "npc_id": "597", + "loc_data": "{3025,3701,0,1,5}-" + }, + { + "npc_id": "598", + "loc_data": "{2943,3384,0,1,3}-" + }, + { + "npc_id": "600", + "loc_data": "{2449,3511,1,1,6}-" + }, + { + "npc_id": "601", + "loc_data": "{2482,3510,1,1,0}-" + }, + { + "npc_id": "602", + "loc_data": "{2469,3488,2,1,6}-" + }, + { + "npc_id": "603", + "loc_data": "{2491,3488,1,1,6}-" + }, + { + "npc_id": "604", + "loc_data": "{3001,3144,0,0,0}-" + }, + { + "npc_id": "605", + "loc_data": "{2985,3343,2,1,2}-" + }, + { + "npc_id": "606", + "loc_data": "{2974,3343,0,1,0}-" + }, + { + "npc_id": "607", + "loc_data": "{2539,3547,0,1,4}-" + }, + { + "npc_id": "608", + "loc_data": "{2962,3337,2,1,4}-" + }, + { + "npc_id": "610", + "loc_data": "{3027,3506,0,0,0}-" + }, + { + "npc_id": "611", + "loc_data": "{3029,3505,0,1,0}-" + }, + { + "npc_id": "612", + "loc_data": "{3028,3510,0,0,0}-" + }, + { + "npc_id": "613", + "loc_data": "{3370,3387,0,1,6}-{3362,3416,0,1,6}-" + }, + { + "npc_id": "614", + "loc_data": "{3351,9756,0,1,1}-{3351,9820,0,1,1}-" + }, + { + "npc_id": "615", + "loc_data": "{3363,3397,0,1,3}-" + }, + { + "npc_id": "616", + "loc_data": "{3370,3416,0,1,3}-" + }, + { + "npc_id": "617", + "loc_data": "{3348,3424,0,1,3}-" + }, + { + "npc_id": "618", + "loc_data": "{3364,3342,0,1,3}-" + }, + { + "npc_id": "619", + "loc_data": "{3355,3333,0,1,3}-" + }, + { + "npc_id": "620", + "loc_data": "{3376,3377,0,1,0}-" + }, + { + "npc_id": "636", + "loc_data": "{2395,3494,0,0,6}-{2396,3494,0,0,6}-{2397,3494,0,0,6}-{2396,3493,0,0,6}-" + }, + { + "npc_id": "637", + "loc_data": "{3158,3425,1,1,5}-" + }, + { + "npc_id": "638", + "loc_data": "{3195,3404,0,0,0}-" + }, + { + "npc_id": "639", + "loc_data": "{3211,3425,0,1,7}-" + }, + { + "npc_id": "640", + "loc_data": "{3253,3487,0,1,6}-" + }, + { + "npc_id": "641", + "loc_data": "{3207,3392,0,1,6}-" + }, + { + "npc_id": "642", + "loc_data": "{3185,3385,0,1,6}-" + }, + { + "npc_id": "643", + "loc_data": "{3246,3383,1,1,5}-" + }, + { + "npc_id": "644", + "loc_data": "{3247,9781,0,1,6}-" + }, + { + "npc_id": "645", + "loc_data": "{3223,3401,0,1,2}-" + }, + { + "npc_id": "646", + "loc_data": "{3257,3447,0,1,0}-" + }, + { + "npc_id": "648", + "loc_data": "{3220,3471,0,0,6}-" + }, + { + "npc_id": "649", + "loc_data": "{3149,3210,0,1,0}-" + }, + { + "npc_id": "650", + "loc_data": "{3148,3205,0,1,0}-" + }, + { + "npc_id": "651", + "loc_data": "{3148,3207,0,1,0}-" + }, + { + "npc_id": "652", + "loc_data": "{3147,3209,0,1,0}-" + }, + { + "npc_id": "656", + "loc_data": "{2822,3374,0,0,3}-" + }, + { + "npc_id": "657", + "loc_data": "{3048,3236,0,1,2}-" + }, + { + "npc_id": "658", + "loc_data": "{2832,3336,0,1,2}-" + }, + { + "npc_id": "659", + "loc_data": "{3052,3373,0,0,0}-" + }, + { + "npc_id": "663", + "loc_data": "{3290,3290,0,1,2}-" + }, + { + "npc_id": "665", + "loc_data": "{2986,9811,0,0,0}-" + }, + { + "npc_id": "666", + "loc_data": "{2819,3451,0,0,3}-" + }, + { + "npc_id": "668", + "loc_data": "{3284,3503,1,1,1}-" + }, + { + "npc_id": "669", + "loc_data": "{2678,3086,1,1,1}-" + }, + { + "npc_id": "670", + "loc_data": "{2465,3496,0,1,6}-{2466,9896,0,0,6}-" + }, + { + "npc_id": "671", + "loc_data": "{2479,3463,1,1,6}-" + }, + { + "npc_id": "672", + "loc_data": "{2390,3515,1,1,6}-" + }, + { + "npc_id": "673", + "loc_data": "{2464,3495,3,0,6}-" + }, + { + "npc_id": "674", + "loc_data": "{3001,3041,0,0,0}-{2954,3025,0,0,0}-" + }, + { + "npc_id": "675", + "loc_data": "{2944,3041,0,0,0}-" + }, + { + "npc_id": "677", + "loc_data": "{2708,9486,0,0,5}-" + }, + { + "npc_id": "678", + "loc_data": "{2658,3436,0,1,3}-{2655,3431,0,1,0}-{2656,3424,0,1,1}-{2664,3426,0,1,4}-{2671,3438,0,1,1}-{2669,3441,0,1,7}-{2674,3438,0,1,5}-{2671,3418,0,1,7}-{2666,3417,0,1,3}-{2666,3415,0,1,2}-{2664,3416,0,1,3}-{2680,3431,0,1,6}-{2678,3431,0,1,1}-{2661,3430,0,1,4}-" + }, + { + "npc_id": "679", + "loc_data": "{2658,3439,0,0,0}-" + }, + { + "npc_id": "680", + "loc_data": "{2679,3432,0,1,6}-" + }, + { + "npc_id": "682", + "loc_data": "{2671,3434,0,1,4}-" + }, + { + "npc_id": "683", + "loc_data": "{2673,3434,0,1,3}-" + }, + { + "npc_id": "684", + "loc_data": "{2667,3430,2,0,6}-" + }, + { + "npc_id": "685", + "loc_data": "{2670,3429,2,0,3}-" + }, + { + "npc_id": "686", + "loc_data": "{2669,3426,2,0,1}-" + }, + { + "npc_id": "687", + "loc_data": "{2666,3427,2,0,4}-" + }, + { + "npc_id": "688", + "loc_data": "{2668,3442,2,1,6}-{2667,3444,2,1,6}-{2669,3444,2,1,6}-" + }, + { + "npc_id": "689", + "loc_data": "{2682,3428,2,1,3}-{2684,3427,2,1,3}-{2684,3429,2,1,3}-" + }, + { + "npc_id": "690", + "loc_data": "{2654,3428,2,1,1}-{2652,3427,2,1,1}-{2652,3429,2,1,1}-" + }, + { + "npc_id": "691", + "loc_data": "{2668,3414,2,1,4}-{2667,3412,2,1,4}-{2669,3412,2,1,4}-" + }, + { + "npc_id": "692", + "loc_data": "{2661,3419,0,1,7}-" + }, + { + "npc_id": "693", + "loc_data": "{2673,3416,0,0,0}-" + }, + { + "npc_id": "694", + "loc_data": "{2659,3431,0,0,3}-" + }, + { + "npc_id": "695", + "loc_data": "{2765,3276,0,1,3}-" + }, + { + "npc_id": "696", + "loc_data": "{2716,3303,0,1,1}-" + }, + { + "npc_id": "697", + "loc_data": "{2766,3288,1,0,6}-" + }, + { + "npc_id": "698", + "loc_data": "{2799,3320,0,1,1}-" + }, + { + "npc_id": "700", + "loc_data": "{2716,3303,0,1,1}-" + }, + { + "npc_id": "701", + "loc_data": "{2793,3321,0,1,1}-" + }, + { + "npc_id": "702", + "loc_data": "{2774,3273,0,1,0}-{2775,3284,0,1,0}-{2781,3290,1,1,0}-{2785,3284,1,1,0}-" + }, + { + "npc_id": "703", + "loc_data": "{2770,3284,0,1,0}-{2794,3279,0,1,0}-{2768,3285,1,1,0}-{2784,3277,1,1,0}-" + }, + { + "npc_id": "704", + "loc_data": "{2778,3291,0,1,0}-{2773,3282,1,1,0}-{2787,3280,1,1,0}-" + }, + { + "npc_id": "705", + "loc_data": "{3208,3252,0,0,6}-" + }, + { + "npc_id": "706", + "loc_data": "{3103,3163,2,0,0}-" + }, + { + "npc_id": "707", + "loc_data": "{3113,3160,2,0,0}-" + }, + { + "npc_id": "708", + "loc_data": "{2595,3125,0,1,1}-{2601,3135,0,1,3}-{2598,3120,0,1,6}-{2615,3120,0,1,4}-{2598,3108,0,1,4}-{2865,3175,0,1,0}-{2855,3188,0,1,1}-{2838,3194,0,1,3}-{2827,3170,0,1,5}-{2598,3145,0,1,1}-{2588,3145,0,1,7}-{2603,3221,0,1,7}-{2604,3212,0,1,3}-{2612,3230,0,1,0}-{2611,3204,0,1,7}-{2942,3247,0,1,7}-{2627,3231,0,1,4}-{2932,3322,0,0,5}-{2934,3301,0,1,5}-{2934,3301,0,1,3}-{2935,3343,0,1,1}-{2941,3356,0,0,7}-{3162,3410,0,1,2}-{3189,3503,0,1,6}-{3219,3221,0,1,4}-{2977,3202,0,1,7}-{2997,3300,0,1,3}-{2957,3308,0,1,0}-{2973,3274,0,1,3}-{2994,3270,0,1,0}-{3215,3282,0,1,1}-{3242,3306,0,1,1}-{2980,3337,0,1,6}-{2977,3377,0,0,3}-{3208,3357,0,1,3}-{2962,3424,0,1,6}-{3240,3393,0,1,3}-{2715,3451,0,1,4}-{2715,3436,0,1,3}-{2733,3459,0,1,3}-{2732,3457,0,1,6}-{3239,3523,0,1,4}-{3262,3523,0,1,2}-{2806,3181,0,1,3}-{2788,3179,0,1,3}-{2753,3178,0,1,3}-{2759,3155,0,1,0}-{2544,3184,0,1,3}-{3068,3251,0,1,6}-{3031,3322,0,1,1}-{3010,3271,0,1,6}-{3011,3513,0,1,1}-" + }, + { + "npc_id": "710", + "loc_data": "{2575,3333,0,1,0}-" + }, + { + "npc_id": "711", + "loc_data": "{2536,3314,1,0,0}-" + }, + { + "npc_id": "713", + "loc_data": "{2526,3319,0,0,6}-" + }, + { + "npc_id": "715", + "loc_data": "{2541,9672,0,1,0}-" + }, + { + "npc_id": "716", + "loc_data": "{2542,3286,0,1,3}-" + }, + { + "npc_id": "717", + "loc_data": "{2513,3294,0,1,0}-{2518,3320,0,1,0}-{2530,3274,0,1,0}-{2535,3296,0,1,0}-" + }, + { + "npc_id": "718", + "loc_data": "{2582,3329,0,1,2}-" + }, + { + "npc_id": "719", + "loc_data": "{2560,3288,0,1,2}-" + }, + { + "npc_id": "720", + "loc_data": "{2542,3306,0,1,0}-" + }, + { + "npc_id": "721", + "loc_data": "{2531,3331,0,1,3}-" + }, + { + "npc_id": "722", + "loc_data": "{2532,3331,0,1,3}-" + }, + { + "npc_id": "723", + "loc_data": "{2530,3331,0,1,3}-" + }, + { + "npc_id": "724", + "loc_data": "{2531,3331,1,1,6}-" + }, + { + "npc_id": "725", + "loc_data": "{2540,3305,0,1,0}-" + }, + { + "npc_id": "728", + "loc_data": "{2540,3308,0,1,0}-" + }, + { + "npc_id": "729", + "loc_data": "{2536,3308,0,1,0}-" + }, + { + "npc_id": "731", + "loc_data": "{3278,3487,0,1,1}-" + }, + { + "npc_id": "732", + "loc_data": "{3267,3392,0,0,0}-" + }, + { + "npc_id": "733", + "loc_data": "{3226,3399,0,0,0}-" + }, + { + "npc_id": "734", + "loc_data": "{3045,3256,0,1,3}-" + }, + { + "npc_id": "735", + "loc_data": "{2795,3155,0,1,7}-" + }, + { + "npc_id": "736", + "loc_data": "{2957,3373,0,1,7}-" + }, + { + "npc_id": "737", + "loc_data": "{2572,3319,0,1,3}-" + }, + { + "npc_id": "738", + "loc_data": "{2691,3492,0,0,0}-" + }, + { + "npc_id": "739", + "loc_data": "{2554,3080,0,1,3}-" + }, + { + "npc_id": "740", + "loc_data": "{2808,3086,0,1,0}-" + }, + { + "npc_id": "741", + "loc_data": "{3212,3220,1,1,1}-" + }, + { + "npc_id": "742", + "loc_data": "{2854,9636,0,1,4}-" + }, + { + "npc_id": "743", + "loc_data": "{3098,3257,0,1,4}-" + }, + { + "npc_id": "744", + "loc_data": "{3047,3204,0,0,0}-" + }, + { + "npc_id": "745", + "loc_data": "{3013,3189,0,1,1}-" + }, + { + "npc_id": "746", + "loc_data": "{3010,3502,0,1,3}-" + }, + { + "npc_id": "747", + "loc_data": "{3069,3516,0,1,6}-" + }, + { + "npc_id": "749", + "loc_data": "{1749,5323,0,1,4}-" + }, + { + "npc_id": "750", + "loc_data": "{1765,5321,0,1,2}-{1744,5326,0,1,4}-" + }, + { + "npc_id": "751", + "loc_data": "{1778,5323,0,1,6}-" + }, + { + "npc_id": "753", + "loc_data": "{2929,9649,0,1,4}-" + }, + { + "npc_id": "755", + "loc_data": "{3100,3268,0,0,0}-" + }, + { + "npc_id": "756", + "loc_data": "{3222,3398,0,0,3}-" + }, + { + "npc_id": "758", + "loc_data": "{3189,3273,0,0,4}-" + }, + { + "npc_id": "767", + "loc_data": "{3303,3511,0,0,1}-{3302,3514,0,0,1}-" + }, + { + "npc_id": "780", + "loc_data": "{3151,3410,0,1,6}-" + }, + { + "npc_id": "781", + "loc_data": "{3221,3434,0,1,0}-" + }, + { + "npc_id": "782", + "loc_data": "{3150,3406,0,0,0}-" + }, + { + "npc_id": "783", + "loc_data": "{3221,3435,0,1,0}-" + }, + { + "npc_id": "784", + "loc_data": "{3155,3406,0,0,0}-" + }, + { + "npc_id": "785", + "loc_data": "{2468,3304,0,1,0}-{2476,3317,0,1,0}-{2478,3291,0,1,0}-{2492,3312,0,1,0}-" + }, + { + "npc_id": "786", + "loc_data": "{2469,3309,0,1,0}-{2475,3298,0,1,0}-{2487,3308,0,1,0}-{2490,3289,0,1,0}-" + }, + { + "npc_id": "787", + "loc_data": "{2476,3313,0,1,0}-{2481,3289,0,1,0}-{2490,3313,0,1,0}-{2491,3300,0,1,0}-" + }, + { + "npc_id": "788", + "loc_data": "{2773,3187,0,0,6}-" + }, + { + "npc_id": "789", + "loc_data": "{2811,3167,0,1,0}-" + }, + { + "npc_id": "792", + "loc_data": "{2774,3197,0,1,0}-" + }, + { + "npc_id": "793", + "loc_data": "{2790,3189,0,1,1}-" + }, + { + "npc_id": "794", + "loc_data": "{2793,3191,0,1,3}-" + }, + { + "npc_id": "795", + "loc_data": "{2866,9956,0,1,6}-" + }, + { + "npc_id": "796", + "loc_data": "{2903,3511,0,1,3}-" + }, + { + "npc_id": "797", + "loc_data": "{2900,3511,1,1,6}-" + }, + { + "npc_id": "798", + "loc_data": "{2930,9686,0,1,0}-" + }, + { + "npc_id": "799", + "loc_data": "{2778,3197,0,1,4}-{2777,3194,0,1,4}-{2777,3199,0,1,3}-{2771,3193,0,1,3}-{2761,3192,0,1,5}-{2775,3190,0,1,4}-{2803,3195,0,1,4}-" + }, + { + "npc_id": "800", + "loc_data": "{2884,9765,0,0,0}-{2890,9766,0,0,0}-{2894,9764,0,0,0}-" + }, + { + "npc_id": "801", + "loc_data": "{3058,3485,0,1,6}-" + }, + { + "npc_id": "802", + "loc_data": "{3046,3486,1,0,0}-" + }, + { + "npc_id": "804", + "loc_data": "{2934,3285,1,1,0}-" + }, + { + "npc_id": "805", + "loc_data": "{2936,3288,0,1,4}-" + }, + { + "npc_id": "812", + "loc_data": "{2738,3473,0,0,1}-{2733,3473,0,0,1}-" + }, + { + "npc_id": "820", + "loc_data": "{2697,3496,0,0,0}-" + }, + { + "npc_id": "822", + "loc_data": "{3302,9466,0,1,6}-" + }, + { + "npc_id": "827", + "loc_data": "{3273,9417,0,1,6}-{3289,9443,0,1,4}-" + }, + { + "npc_id": "830", + "loc_data": "{3271,3028,0,1,4}-" + }, + { + "npc_id": "831", + "loc_data": "{3291,3032,1,0,1}-" + }, + { + "npc_id": "832", + "loc_data": "{3171,3025,0,1,4}-" + }, + { + "npc_id": "833", + "loc_data": "{3167,3033,0,1,2}-{3170,3027,0,1,5}-{3174,3028,0,1,6}-" + }, + { + "npc_id": "834", + "loc_data": "{3170,3045,0,0,3}-" + }, + { + "npc_id": "836", + "loc_data": "{3304,3124,0,1,6}-" + }, + { + "npc_id": "837", + "loc_data": "{3305,3121,0,1,0}-{3301,3120,0,1,1}-{3302,3123,0,1,6}-{3307,3125,0,1,1}-" + }, + { + "npc_id": "838", + "loc_data": "{3306,3117,0,1,4}-" + }, + { + "npc_id": "839", + "loc_data": "{3265,3066,0,1,0}-{3267,3066,0,1,0}-{3310,3068,0,1,0}-{3322,3011,0,1,0}-{3322,3052,0,1,0}-{3324,3030,0,1,0}-{3150,3044,0,1,0}-{3172,3009,0,1,0}-{3197,3012,0,1,0}-{3198,3040,0,1,0}-{3217,3092,0,1,0}-{3235,3074,0,1,0}-{3252,3125,0,1,0}-{3258,3078,0,1,0}-{3237,2968,0,1,0}-{3224,3013,0,1,0}-{3225,3034,0,1,0}-{3226,3060,0,1,0}-{3250,3057,0,1,0}-{3283,3108,0,1,0}-{3323,3094,0,1,0}-" + }, + { + "npc_id": "840", + "loc_data": "{3268,3052,0,1,0}-{3281,3056,0,1,0}-{3307,3055,0,1,0}-{3318,3020,0,1,0}-{3318,3040,0,1,0}-{3190,3054,0,1,0}-{3192,3016,0,1,0}-{3217,3111,0,1,0}-{3222,3086,0,1,0}-{3238,3101,0,1,0}-{3244,3080,0,1,0}-{3253,3116,0,1,0}-{3255,3095,0,1,0}-{3237,3000,0,1,0}-{3245,2960,0,1,0}-{3208,3032,0,1,0}-{3217,3064,0,1,0}-{3238,3015,0,1,0}-{3258,3063,0,1,0}-{3267,3077,0,1,0}-{3269,3110,0,1,0}-{3275,3094,0,1,0}-{3291,3078,0,1,0}-{3291,3100,0,1,0}-{3305,3089,0,1,0}-{3318,3078,0,1,0}-{3321,3104,0,1,0}-" + }, + { + "npc_id": "841", + "loc_data": "{3288,3022,0,1,1}-" + }, + { + "npc_id": "843", + "loc_data": "{2644,3274,0,1,3}-{2644,3276,0,1,5}-{2647,3271,0,1,6}-" + }, + { + "npc_id": "844", + "loc_data": "{2683,3323,0,0,0}-" + }, + { + "npc_id": "845", + "loc_data": "{2635,3311,0,0,0}-" + }, + { + "npc_id": "846", + "loc_data": "{2787,3184,0,1,4}-" + }, + { + "npc_id": "847", + "loc_data": "{3143,3447,0,1,5}-" + }, + { + "npc_id": "848", + "loc_data": "{2480,3489,1,1,3}-" + }, + { + "npc_id": "849", + "loc_data": "{2417,3498,1,1,0}-{2482,3487,1,1,0}-{2482,3489,1,1,0}-" + }, + { + "npc_id": "850", + "loc_data": "{2439,3502,1,0,4}-" + }, + { + "npc_id": "851", + "loc_data": "{2449,3503,1,1,4}-" + }, + { + "npc_id": "852", + "loc_data": "{2615,2987,0,1,0}-{2568,9432,0,1,0}-{2573,9447,0,1,0}-{2579,9441,0,1,0}-{2580,9431,0,1,0}-{2611,9454,0,1,0}-{2616,9447,0,1,0}-{2505,3032,0,1,0}-{2512,3022,0,1,0}-{2518,3041,0,1,0}-{2528,3044,0,1,0}-" + }, + { + "npc_id": "853", + "loc_data": "{2506,3115,0,1,3}-" + }, + { + "npc_id": "854", + "loc_data": "{2511,3085,0,1,4}-" + }, + { + "npc_id": "855", + "loc_data": "{2576,3027,0,1,3}-" + }, + { + "npc_id": "856", + "loc_data": "{2577,3021,0,1,1}-" + }, + { + "npc_id": "858", + "loc_data": "{2549,3029,0,1,0}-{2551,3031,0,1,0}-" + }, + { + "npc_id": "859", + "loc_data": "{2505,3062,0,1,0}-{2507,3062,0,1,0}-" + }, + { + "npc_id": "860", + "loc_data": "{2501,3012,0,1,0}-{2503,3011,0,1,0}-" + }, + { + "npc_id": "861", + "loc_data": "{2526,3018,0,1,0}-{2529,3019,0,1,0}-" + }, + { + "npc_id": "862", + "loc_data": "{2541,3034,0,1,3}-{2541,3029,0,1,3}-{2543,3031,0,1,3}-" + }, + { + "npc_id": "870", + "loc_data": "{2507,3040,0,1,0}-{2507,3036,0,1,0}-" + }, + { + "npc_id": "872", + "loc_data": "{2547,3117,2,1,3}-{2547,3112,2,1,6}-{2544,3114,2,1,3}-{2547,3118,2,1,3}-" + }, + { + "npc_id": "873", + "loc_data": "{2518,3035,0,1,1}-" + }, + { + "npc_id": "874", + "loc_data": "{2528,3048,0,1,6}-" + }, + { + "npc_id": "875", + "loc_data": "{2513,3034,0,1,1}-" + }, + { + "npc_id": "876", + "loc_data": "{2525,3043,0,1,3}-" + }, + { + "npc_id": "877", + "loc_data": "{2536,3092,0,1,1}-{2534,3091,0,1,1}-{2550,3118,0,1,4}-{2543,3117,0,1,3}-{2546,3113,0,1,4}-" + }, + { + "npc_id": "878", + "loc_data": "{2534,3092,0,1,1}-" + }, + { + "npc_id": "881", + "loc_data": "{3112,3162,1,0,0}-" + }, + { + "npc_id": "882", + "loc_data": "{3203,3424,0,0,6}-" + }, + { + "npc_id": "883", + "loc_data": "{3204,3470,0,1,3}-" + }, + { + "npc_id": "884", + "loc_data": "{3204,3495,2,1,6}-" + }, + { + "npc_id": "885", + "loc_data": "{2565,3271,0,0,0}-{2573,3268,1,0,0}-" + }, + { + "npc_id": "887", + "loc_data": "{2570,3275,0,1,3}-" + }, + { + "npc_id": "888", + "loc_data": "{2565,3273,0,0,0}-" + }, + { + "npc_id": "889", + "loc_data": "{2571,3270,0,0,0}-" + }, + { + "npc_id": "890", + "loc_data": "{2569,3272,0,0,0}-{2573,3269,1,0,0}-" + }, + { + "npc_id": "895", + "loc_data": "{2929,3456,0,1,4}-" + }, + { + "npc_id": "902", + "loc_data": "{2535,4715,0,1,6}-" + }, + { + "npc_id": "903", + "loc_data": "{2541,4715,0,1,3}-" + }, + { + "npc_id": "904", + "loc_data": "{2507,4693,0,1,3}-" + }, + { + "npc_id": "905", + "loc_data": "{2540,4719,0,1,6}-" + }, + { + "npc_id": "912", + "loc_data": "{3100,3927,0,1,0}-{3102,3938,0,1,0}-{3116,3934,0,1,0}-" + }, + { + "npc_id": "913", + "loc_data": "{3098,3925,0,1,0}-{3100,3940,0,1,0}-{3110,3934,0,1,0}-" + }, + { + "npc_id": "914", + "loc_data": "{3098,3942,0,1,0}-{3102,3929,0,1,0}-{3113,3934,0,1,0}-" + }, + { + "npc_id": "915", + "loc_data": "{3108,3264,0,1,2}-" + }, + { + "npc_id": "916", + "loc_data": "{3122,3245,0,0,0}-" + }, + { + "npc_id": "917", + "loc_data": "{3125,3250,0,1,6}-{3122,3249,0,1,6}-" + }, + { + "npc_id": "918", + "loc_data": "{3048,3209,1,1,3}-" + }, + { + "npc_id": "919", + "loc_data": "{3128,3245,0,1,4}-" + }, + { + "npc_id": "920", + "loc_data": "{3123,3241,0,1,1}-" + }, + { + "npc_id": "922", + "loc_data": "{3086,3261,0,1,7}-" + }, + { + "npc_id": "923", + "loc_data": "{3302,3163,0,0,0}-" + }, + { + "npc_id": "924", + "loc_data": "{3286,3180,0,0,0}-" + }, + { + "npc_id": "925", + "loc_data": "{3267,3226,0,0,3}-{3266,3229,0,0,3}-{3269,3229,0,0,4}-{3268,3226,0,0,4}-" + }, + { + "npc_id": "931", + "loc_data": "{2842,2935,0,0,0}-{2842,2929,0,0,0}-{2792,2929,0,0,0}-{2815,2935,0,0,0}-" + }, + { + "npc_id": "933", + "loc_data": "{2725,3367,0,0,2}-{2725,3380,2,0,6}-" + }, + { + "npc_id": "941", + "loc_data": "{3340,3678,0,1,1}-{3339,3695,0,1,6}-{3344,3705,0,1,3}-{3118,3820,0,1,0}-{2982,3618,0,1,3}-{3307,5462,0,1,0}-" + }, + { + "npc_id": "942", + "loc_data": "{3074,3086,0,0,0}-" + }, + { + "npc_id": "943", + "loc_data": "{3103,3096,0,0,0}-" + }, + { + "npc_id": "944", + "loc_data": "{3107,9511,0,1,5}-" + }, + { + "npc_id": "945", + "loc_data": "{3093,3107,0,0,0}-" + }, + { + "npc_id": "946", + "loc_data": "{3141,3090,0,0,6}-" + }, + { + "npc_id": "947", + "loc_data": "{3127,3124,0,0,3}-" + }, + { + "npc_id": "948", + "loc_data": "{3084,9506,0,0,0}-" + }, + { + "npc_id": "949", + "loc_data": "{3086,3122,0,0,0}-" + }, + { + "npc_id": "952", + "loc_data": "{3101,3092,0,0,4}-" + }, + { + "npc_id": "954", + "loc_data": "{3123,3107,0,1,5}-" + }, + { + "npc_id": "955", + "loc_data": "{3176,3317,0,1,3}-{3169,3319,0,1,1}-" + }, + { + "npc_id": "957", + "loc_data": "{3314,3241,0,0,1}-{3314,3240,1,0,0}-" + }, + { + "npc_id": "958", + "loc_data": "{3383,3272,0,1,3}-" + }, + { + "npc_id": "959", + "loc_data": "{3359,3272,0,1,5}-" + }, + { + "npc_id": "960", + "loc_data": "{3370,3276,0,1,3}-" + }, + { + "npc_id": "961", + "loc_data": "{3377,3276,0,1,4}-" + }, + { + "npc_id": "962", + "loc_data": "{3362,3276,0,1,3}-" + }, + { + "npc_id": "963", + "loc_data": "{3375,3274,0,1,2}-" + }, + { + "npc_id": "970", + "loc_data": "{3081,3247,0,0,1}-" + }, + { + "npc_id": "971", + "loc_data": "{2464,3287,0,1,0}-" + }, + { + "npc_id": "1005", + "loc_data": "{3057,3905,0,1,3}-" + }, + { + "npc_id": "1006", + "loc_data": "{2763,3284,0,1,0}-{2768,3274,0,1,0}-{2768,3288,0,1,0}-{2770,3277,0,1,0}-{2770,3290,0,1,0}-{2771,3279,0,1,0}-{2774,3291,0,1,0}-{2778,3285,0,1,0}-{2781,3278,0,1,0}-{2781,3285,0,1,0}-{2783,3275,0,1,0}-{2784,3279,0,1,0}-{2785,3276,0,1,0}-{2785,3287,0,1,0}-{2788,3274,0,1,0}-{2793,3275,0,1,0}-{2793,3280,0,1,0}-{2768,3282,1,1,0}-{2770,3282,1,1,0}-{2773,3291,1,1,0}-{2780,3283,1,1,0}-{2780,3290,1,1,0}-{2783,3286,1,1,0}-{2784,3279,1,1,0}-{2785,3282,1,1,0}-" + }, + { + "npc_id": "1010", + "loc_data": "{2629,2979,0,1,0}-" + }, + { + "npc_id": "1011", + "loc_data": "{2642,9394,0,1,0}-" + }, + { + "npc_id": "1012", + "loc_data": "{2650,9393,0,1,0}-" + }, + { + "npc_id": "1013", + "loc_data": "{2593,2971,0,1,0}-{2594,2971,0,1,0}-{2596,2961,0,1,0}-{2598,2971,0,1,0}-{2599,2960,0,1,0}-{2598,2960,0,1,0}-{2603,2966,0,1,0}-{2603,2970,0,1,0}-{2598,2960,0,1,0}-{2596,2963,0,1,0}-{2595,2964,0,1,0}-{2594,2964,0,1,0}-{2601,2964,0,1,0}-{2598,2969,0,1,0}-{2604,2971,0,1,0}-{2601,2972,0,1,0}-{2392,3057,0,1,0}-{2395,3056,0,1,0}-{2395,3052,0,1,0}-{2397,3048,0,1,0}-{2400,3050,0,1,0}-{2400,3053,0,1,0}-{2391,3052,0,1,0}-{2393,3047,0,1,0}-{2399,3046,0,1,0}-{2402,3044,0,1,0}-{2399,3040,0,1,0}-{2395,3042,0,1,0}-{2391,3045,0,1,0}-{2464,2912,0,1,0}-{2544,2904,0,1,0}-{2544,2988,0,1,0}-{2532,2983,0,1,0}-{2549,2983,0,1,0}-{2545,2983,0,1,0}-{2528,2986,0,1,0}-{2550,2979,0,1,0}-{2522,2978,0,1,0}-{2523,2976,0,1,0}-{2526,2974,0,1,0}-{2548,2990,0,1,0}-{2552,2988,0,1,0}-{2548,2979,0,1,0}-{2547,2991,0,1,0}-{2525,2975,0,1,0}-" + }, + { + "npc_id": "1017", + "loc_data": "{3191,3277,0,1,0}-{3188,3279,0,1,0}-{3187,3277,0,1,0}-{3190,3278,0,1,0}-{3187,3277,0,1,0}-{3189,3278,0,1,3}-{3198,3359,0,1,0}-{2677,3656,0,1,2}-{2672,3654,0,1,2}-{2676,3652,0,1,4}-{2681,3652,0,1,4}-{2675,3652,0,1,3}-{3231,3296,0,1,6}-{3233,3300,0,1,4}-{3235,3293,0,1,3}-{3232,3288,0,1,0}-{3234,3298,0,1,6}-{3234,3297,0,1,3}-{3234,3292,0,1,4}-{3235,3289,0,1,1}-{2693,3271,0,1,3}-{2692,3272,0,1,3}-{2785,3069,0,1,4}-{2800,3072,0,1,6}-" + }, + { + "npc_id": "1019", + "loc_data": "{3187,5555,0,1,4}-{3190,5563,0,1,1}-{3193,5555,0,1,3} -{3213,9377,0,1,3}-{3209,9397,0,1,4}-{3245,9401,0,1,6}- {3237,9402,0,1,2}-{3207,9349,0,1,3}-{3220,9347,0,1,6} -{3233,9359,0,1,4}-{3235,9354,0,0,6}-{3259,9370,0,1,1}- {3258,9387,0,1,6}-{2707,9880,0,1,0}-{2711,9876,0,1,0}- {2712,9871,0,1,0}-{2715,9874,0,1,0}-{2720,9871,0,1,0} -{2717,9880,0,1,0}-{2722,9879,0,1,0}-{2723,9875,0,1,0}- {3278,9368,0,1,5}-{3271,9359,0,1,3}-{3287,9359,0,1,5}- {3301,9394,0,1,5}-{3318,9352,0,1,5}-" + }, + { + "npc_id": "1020", + "loc_data": "{2697,9913,0,1,0}-{2695,9907,0,1,0}-{2693,9901,0,1,0}-{2701,9902,0,1,0}-{2704,9908,0,1,0}-{2694,9889,0,1,0}-{2694,9879,0,1,0}-{2699,9875,0,1,0}-{2700,9869,0,1,0}-{2695,9870,0,1,0}-" + }, + { + "npc_id": "1021", + "loc_data": "{2733,9882,0,1,0}-{2732,9888,0,1,0}-{2738,9889,0,1,0}-{2732,9892,0,1,0}-{2738,9894,0,1,0}-{2734,9896,0,1,0}-" + }, + { + "npc_id": "1022", + "loc_data": "{2714,9904,0,1,0}-{2718,9906,0,1,0}-{2717,9902,0,1,0}-{2720,9904,0,1,0}-{2724,9903,0,1,0}-{2727,9905,0,1,0}-{2726,9907,0,1,0}-" + }, + { + "npc_id": "1027", + "loc_data": "{2354,3608,0,0,0}-{3278,3155,0,0,0}-" + }, + { + "npc_id": "1036", + "loc_data": "{3514,3478,0,0,0}-{3514,3479,0,0,0}-{3514,3480,0,0,0}-{3514,3481,0,0,0}-{3514,3482,0,0,0}-{3514,3483,0,0,0}-" + }, + { + "npc_id": "1037", + "loc_data": "{2435,3412,0,1,3}-" + }, + { + "npc_id": "1038", + "loc_data": "{3507,3496,1,1,1}-{3508,3494,0,1,1}-" + }, + { + "npc_id": "1039", + "loc_data": "{3499,3506,1,1,5}-{3500,3505,0,1,5}-" + }, + { + "npc_id": "1040", + "loc_data": "{3475,3494,0,1,6}-" + }, + { + "npc_id": "1041", + "loc_data": "{3490,3503,1,0,0}-{3490,3500,0,1,4}-" + }, + { + "npc_id": "1042", + "loc_data": "{3495,3469,0,1,3}-" + }, + { + "npc_id": "1043", + "loc_data": "{3726,3381,0,0,0}-{3745,3359,0,0,0}-{3749,3365,0,0,0}-{3750,3354,0,0,0}-{3757,3363,0,0,0}-{3763,3337,0,0,0}-{3459,3457,0,0,0}-{3460,3462,0,0,0}-{3462,3459,0,0,0}-{3463,3490,0,0,0}-{3464,3511,0,0,0}-{3465,3466,0,0,0}-{3466,3495,0,0,0}-{3466,3497,0,0,0}-{3467,3485,0,0,0}-{3467,3497,0,0,0}-{3467,3509,0,0,0}-{3469,3470,0,0,0}-{3470,3469,0,0,0}-{3471,3477,0,0,0}-{3474,3505,0,0,0}-{3476,3507,0,0,0}-{3479,3511,0,0,0}-{3480,3468,0,0,0}-{3480,3470,0,0,0}-{3482,3469,0,0,0}-{3483,3511,0,0,0}-{3484,3464,0,0,0}-{3485,3509,0,0,0}-{3490,3461,0,0,0}-{3491,3460,0,0,0}-{3494,3461,0,0,0}-{3494,3512,0,0,0}-{3498,3461,0,0,0}-{3499,3513,0,0,0}-{3501,3513,0,0,0}-{3502,3464,0,0,0}-{3504,3463,0,0,0}-{3506,3512,0,0,0}-{3506,3515,0,0,0}-{3507,3515,0,0,0}-{3509,3512,0,0,0}-{3511,3488,0,0,0}-{3513,3467,0,0,0}-{3513,3487,0,0,0}-{3513,3489,0,0,0}-{3513,3503,0,0,0}-{3514,3490,0,0,0}-{3515,3495,0,0,0}-{3515,3499,0,0,0}-{3516,3469,0,0,0}-{3409,3369,0,0,0}-{3420,3349,0,0,0}-{3430,3340,0,0,0}-{3435,3330,0,0,0}-{3435,3359,0,0,0}-{3437,3374,0,0,0}-{3446,3385,0,0,0}-{3447,3388,0,0,0}-{3450,3370,0,0,0}-{3450,3387,0,0,0}-{3451,3336,0,0,0}-{3452,3355,0,0,0}-{3726,3289,0,0,0}-{3732,3291,0,0,0}-{3737,3280,0,0,0}-{3745,3285,0,0,0}-{3418,3420,0,0,0}-{3424,3452,0,0,0}-{3428,3409,0,0,0}-{3433,3416,0,0,0}-{3434,3394,0,0,0}-{3436,3407,0,0,0}-{3438,3414,0,0,0}-{3439,3449,0,0,0}-{3446,3439,0,0,0}-{3454,3410,0,0,0}-{3454,3423,0,0,0}-{2852,4561,0,0,0}-{2853,4566,0,0,0}-{2856,4568,0,0,0}-{2864,4561,0,0,0}-{2864,4563,0,0,0}-" + }, + { + "npc_id": "1044", + "loc_data": "{3408,3484,0,1,6}-{3408,3493,0,1,1}-{3410,3489,1,1,3}-{3412,3487,1,1,4}-" + }, + { + "npc_id": "1045", + "loc_data": "{3413,3489,0,1,3}-{3409,3485,1,1,4}-{3413,3489,1,1,1}-{3213,3476,0,1,3}-" + }, + { + "npc_id": "1046", + "loc_data": "{3409,3489,0,1,4}-{3413,3485,0,1,4}-{3414,3491,1,1,6}-" + }, + { + "npc_id": "1048", + "loc_data": "{3437,3486,0,0,0}-" + }, + { + "npc_id": "1051", + "loc_data": "{3440,9738,1,1,0}-" + }, + { + "npc_id": "1052", + "loc_data": "{3451,3380,0,1,0}-{3445,3374,0,1,0}-{3438,3365,0,1,0}-{3429,3367,0,1,0}-{3417,3367,0,1,0}-{3413,3362,0,1,0}-{3417,3358,0,1,0}-{3426,3352,0,1,0}-{3435,3349,0,1,0}-{3442,3353,0,1,0}-{3448,3358,0,1,0}-{3426,3338,0,1,0}-{3423,3335,0,1,0}-{3420,3442,0,1,0}-{3429,3436,0,1,0}-{3439,3437,0,1,0}-{3448,3444,0,1,0}-{3449,3420,0,1,0}-{3441,3421,0,1,0}-{3427,3421,0,1,0}-{3414,3422,0,1,0}-{3411,3423,0,1,0}-{3415,3414,0,1,0}-{3410,3409,0,1,0}-{3422,3405,0,1,0}-{3431,3402,0,1,0}-{3444,3405,0,1,0}-{3453,3397,0,1,0}-{3470,3385,0,1,0}-{3463,3379,0,1,0}-{3457,3355,0,1,0}-{3461,3348,0,1,0}-{3457,3343,0,1,0}-{3471,3344,0,1,0}-{3458,3433,0,1,0}-{3459,3419,0,1,0}-{3467,3402,0,1,0}-{3473,3395,0,1,0}-" + }, + { + "npc_id": "1054", + "loc_data": "{3444,3459,0,0,0}-" + }, + { + "npc_id": "1055", + "loc_data": "{2811,3191,0,0,0}-" + }, + { + "npc_id": "1060", + "loc_data": "{2898,3528,0,0,1}-" + }, + { + "npc_id": "1061", + "loc_data": "{2898,3532,0,0,4}-" + }, + { + "npc_id": "1062", + "loc_data": "{2893,3540,0,0,3}-" + }, + { + "npc_id": "1063", + "loc_data": "{2900,3531,0,0,7}-{2900,3533,0,0,7}-" + }, + { + "npc_id": "1064", + "loc_data": "{2895,3537,0,0,1}-{2894,3537,0,0,1}-{2893,3537,0,0,1}-{2892,3537,0,0,1}-{2891,3537,0,0,1}-{2891,3538,0,0,1}-{2892,3538,0,0,1}-{2893,3538,0,0,1}-{2894,3538,0,0,1}-{2895,3538,0,0,1}-" + }, + { + "npc_id": "1065", + "loc_data": "{2889,3529,0,1,1}-{2904,3538,0,1,6}-{2882,3531,0,1,4}-{2903,3544,0,1,4}-{2911,3542,0,1,4}-{2906,3540,0,1,3}-" + }, + { + "npc_id": "1066", + "loc_data": "{2892,3532,0,0,4}-" + }, + { + "npc_id": "1067", + "loc_data": "{2893,3533,0,0,6}-" + }, + { + "npc_id": "1068", + "loc_data": "{2894,3532,0,0,3}-" + }, + { + "npc_id": "1069", + "loc_data": "{2840,3589,0,0,3}-" + }, + { + "npc_id": "1070", + "loc_data": "{2269,4758,0,1,3}-" + }, + { + "npc_id": "1071", + "loc_data": "{2820,3554,0,1,1}-" + }, + { + "npc_id": "1072", + "loc_data": "{2893,3558,0,1,3}-" + }, + { + "npc_id": "1073", + "loc_data": "{2900,3549,0,0,3}-{2897,3549,0,0,4}-{2902,3568,1,1,3}-{2903,3559,1,1,3}-{2903,3557,1,1,3}-{2903,3569,1,1,3}-{2894,3559,1,1,3}-{2892,3557,1,0,3}-" + }, + { + "npc_id": "1074", + "loc_data": "{2893,3569,1,1,3}-" + }, + { + "npc_id": "1076", + "loc_data": "{2897,3556,0,0,6}-{2896,3566,0,0,6}-" + }, + { + "npc_id": "1077", + "loc_data": "{2900,3556,0,0,6}-" + }, + { + "npc_id": "1078", + "loc_data": "{2905,3540,1,1,0}-" + }, + { + "npc_id": "1079", + "loc_data": "{2906,3537,0,1,5}-" + }, + { + "npc_id": "1080", + "loc_data": "{2900,3567,1,1,0}-" + }, + { + "npc_id": "1081", + "loc_data": "{2897,3565,0,1,4}-" + }, + { + "npc_id": "1082", + "loc_data": "{2919,3576,0,0,0}-" + }, + { + "npc_id": "1083", + "loc_data": "{2931,3546,0,1,3}-" + }, + { + "npc_id": "1084", + "loc_data": "{2915,3549,0,1,0}-" + }, + { + "npc_id": "1085", + "loc_data": "{2927,3558,0,1,6}-" + }, + { + "npc_id": "1086", + "loc_data": "{2965,3262,0,1,4}-" + }, + { + "npc_id": "1087", + "loc_data": "{2911,3540,0,1,7}-" + }, + { + "npc_id": "1088", + "loc_data": "{2918,3545,0,1,0}-" + }, + { + "npc_id": "1089", + "loc_data": "{2919,3529,0,1,0}-" + }, + { + "npc_id": "1090", + "loc_data": "{2931,3566,0,1,1}-" + }, + { + "npc_id": "1093", + "loc_data": "{2817,3560,0,1,3}-" + }, + { + "npc_id": "1094", + "loc_data": "{2802,3841,0,1,0}-{2798,3842,0,1,0}-{2804,3843,0,1,0}-{2807,3843,0,1,0}-" + }, + { + "npc_id": "1096", + "loc_data": "{2852,3591,0,1,7}-" + }, + { + "npc_id": "1097", + "loc_data": "{2858,3596,0,1,4}-" + }, + { + "npc_id": "1098", + "loc_data": "{2868,3591,0,1,6}-" + }, + { + "npc_id": "1099", + "loc_data": "{2857,3589,0,0,0}-" + }, + { + "npc_id": "1100", + "loc_data": "{2859,3589,0,0,0}-" + }, + { + "npc_id": "1101", + "loc_data": "{2854,3600,0,0,1}-" + }, + { + "npc_id": "1102", + "loc_data": "{2859,3600,0,0,1}-" + }, + { + "npc_id": "1103", + "loc_data": "{2863,3600,0,0,1}-" + }, + { + "npc_id": "1104", + "loc_data": "{2867,3600,0,0,1}-" + }, + { + "npc_id": "1105", + "loc_data": "{2870,3600,0,0,1}-{2851,3598,0,0,1}-" + }, + { + "npc_id": "1106", + "loc_data": "{2864,3594,0,1,1}-{2857,3587,0,1,7}-{2855,3596,0,1,4}-{2843,3682,0,1,1}-{2827,10078,1,1,6}-{2881,3592,0,1,5}-{2916,3631,0,1,0}-{2769,10149,0,1,0}-{2777,10142,0,1,0}-" + }, + { + "npc_id": "1107", + "loc_data": "{2874,3595,0,1,3}-{2875,3596,0,1,1}-{2873,3598,0,1,1}-{2845,3674,0,1,4}-{2836,10088,1,1,5}-{2917,3634,0,1,0}-{2781,10143,0,1,0}-" + }, + { + "npc_id": "1108", + "loc_data": "{2878,3592,0,1,6}-{2861,3586,0,1,6}-{2852,3673,0,1,2}-{2855,10058,2,1,4}-{2783,10140,0,1,0}-" + }, + { + "npc_id": "1109", + "loc_data": "{2875,3588,0,1,1}-{2851,3667,0,1,3}-{2825,10087,1,1,3}-{2836,10080,1,1,6}-{2883,3586,0,1,6}-{2909,3641,0,1,0}-{2923,10029,0,1,7}-{2784,10040,2,1,3}-{2784,10134,0,1,0}-" + }, + { + "npc_id": "1110", + "loc_data": "{2869,3594,0,1,3}-{2861,3587,0,1,4}-{2872,3594,0,1,5}-{2829,10080,1,1,6}-{2836,10097,2,1,4}-{2852,10110,2,1,4}-{2883,3591,0,1,4}-{2771,10143,0,1,0}-" + }, + { + "npc_id": "1111", + "loc_data": "{2863,3588,0,1,6}-{2865,3591,0,1,0}-{2866,3598,0,1,1}-{2855,3685,0,1,1}-{2840,10101,1,1,4}-{2857,10055,2,1,3}-{2836,10090,2,1,1}-{2925,10033,0,1,6}-{2788,10131,0,1,0}-" + }, + { + "npc_id": "1112", + "loc_data": "{2867,3595,0,1,6}-{2871,3597,0,1,4}-{2832,10089,1,1,1}-{2836,10077,2,1,1}-{2925,10030,0,1,1}-" + }, + { + "npc_id": "1113", + "loc_data": "{2829,10083,0,1,0}-" + }, + { + "npc_id": "1114", + "loc_data": "{2827,10077,0,1,0}-" + }, + { + "npc_id": "1115", + "loc_data": "{2831,10086,2,0,0}-" + }, + { + "npc_id": "1116", + "loc_data": "{2822,10073,2,0,0}-" + }, + { + "npc_id": "1117", + "loc_data": "{2829,10100,2,0,0}-" + }, + { + "npc_id": "1118", + "loc_data": "{2906,3623,0,0,6}-" + }, + { + "npc_id": "1119", + "loc_data": "{2920,3622,0,0,3}-" + }, + { + "npc_id": "1120", + "loc_data": "{2923,3616,0,0,3}-" + }, + { + "npc_id": "1121", + "loc_data": "{2923,3612,0,0,3}-" + }, + { + "npc_id": "1122", + "loc_data": "{2916,3601,0,0,0}-" + }, + { + "npc_id": "1123", + "loc_data": "{2902,3604,0,0,1}-" + }, + { + "npc_id": "1124", + "loc_data": "{2922,3606,0,0,3}-" + }, + { + "npc_id": "1125", + "loc_data": "{2911,3612,0,0,3}-" + }, + { + "npc_id": "1128", + "loc_data": "{2832,10079,0,0,4}-" + }, + { + "npc_id": "1129", + "loc_data": "{2832,10083,0,0,4}-" + }, + { + "npc_id": "1130", + "loc_data": "{2902,3696,0,0,1}-" + }, + { + "npc_id": "1131", + "loc_data": "{2898,3698,0,0,1}-" + }, + { + "npc_id": "1132", + "loc_data": "{2893,3700,0,0,1}-" + }, + { + "npc_id": "1133", + "loc_data": "{2889,3699,0,0,1}-" + }, + { + "npc_id": "1134", + "loc_data": "{2886,3698,0,0,1}-" + }, + { + "npc_id": "1135", + "loc_data": "{2843,10057,1,0,0}-" + }, + { + "npc_id": "1136", + "loc_data": "{2840,10056,1,0,0}-" + }, + { + "npc_id": "1137", + "loc_data": "{2847,10056,1,0,0}-" + }, + { + "npc_id": "1138", + "loc_data": "{2826,10083,1,1,0}-{2837,10083,2,1,1}-{2904,3642,0,1,3}-{2923,10031,0,1,3}-" + }, + { + "npc_id": "1139", + "loc_data": "{2854,3689,0,0,6}-" + }, + { + "npc_id": "1140", + "loc_data": "{2819,3586,0,1,4}-{2856,10054,1,0,0}-{2860,10057,1,0,0}-{2892,3685,0,1,0}-{2900,3671,0,1,0}-" + }, + { + "npc_id": "1141", + "loc_data": "{2857,10059,1,0,0}-{2857,10057,1,0,0}-{2893,3678,0,1,0}-" + }, + { + "npc_id": "1142", + "loc_data": "{2851,10089,0,1,1}-{2854,10092,0,1,3}-" + }, + { + "npc_id": "1143", + "loc_data": "{2850,10088,0,1,3}-{2854,10086,0,1,6}-" + }, + { + "npc_id": "1144", + "loc_data": "{2856,10089,0,1,4}-{2858,10089,0,1,6}-" + }, + { + "npc_id": "1146", + "loc_data": "{2864,10081,0,1,7}-" + }, + { + "npc_id": "1147", + "loc_data": "{2853,10076,0,1,5}-" + }, + { + "npc_id": "1148", + "loc_data": "{2858,10082,0,1,3}-" + }, + { + "npc_id": "1149", + "loc_data": "{2861,10085,0,1,2}-" + }, + { + "npc_id": "1150", + "loc_data": "{2857,10075,0,1,1}-" + }, + { + "npc_id": "1151", + "loc_data": "{2845,10058,1,0,0}-" + }, + { + "npc_id": "1153", + "loc_data": "{3489,9509,2,1,4}-{3499,9515,2,1,6}-{3505,9527,2,1,5}-{3510,9521,2,1,1}-{3490,9526,2,1,3}-{3475,9524,2,1,5}-{3465,9505,2,1,1}-{3479,9501,2,1,3}-{3487,9491,2,1,3}-" + }, + { + "npc_id": "1154", + "loc_data": "{3472,9501,2,1,3}-{3495,9494,2,1,4}-{3479,9484,2,1,1}-{3500,9477,2,1,6}-{3470,9482,2,1,6}-{3465,9481,2,1,3}-{3465,9491,2,1,6}-{3468,9488,2,1,0}-" + }, + { + "npc_id": "1155", + "loc_data": "{3505,9496,2,1,6}-{3513,9496,2,1,7}-" + }, + { + "npc_id": "1157", + "loc_data": "{3480,9508,0,1,0}-{3495,9505,0,1,2}-{3492,9490,0,1,1}-{3472,9497,0,1,6}-" + }, + { + "npc_id": "1158", + "loc_data": "{3484,9491,0,1,2}-" + }, + { + "npc_id": "1161", + "loc_data": "{3487,9526,2,1,5}-{3474,9519,2,1,1}-{3465,9512,2,1,0}-{3489,9501,2,1,4}-{3494,9501,2,1,3}-{3480,9489,2,1,6}-{3483,9477,2,1,3}-{3494,9476,2,1,3}-{3473,9487,0,1,3}-{3476,9496,0,1,6}-{3473,9501,0,1,7}-{3481,9504,0,1,6}-{3488,9514,0,1,6}-{3497,9501,0,1,3}-{3486,9490,0,1,0}-" + }, + { + "npc_id": "1162", + "loc_data": "{2781,3088,1,1,0}-" + }, + { + "npc_id": "1164", + "loc_data": "{2780,3058,0,1,0}-" + }, + { + "npc_id": "1171", + "loc_data": "{2766,3168,0,1,6}-" + }, + { + "npc_id": "1172", + "loc_data": "{2909,3086,0,0,0}-" + }, + { + "npc_id": "1174", + "loc_data": "{2792,3015,0,0,0}-{2792,3019,0,0,0}-{2801,3010,0,0,0}-{2801,3010,0,0,4}-" + }, + { + "npc_id": "1176", + "loc_data": "{2928,3112,0,0,0}-" + }, + { + "npc_id": "1177", + "loc_data": "{2912,3119,0,0,0}-" + }, + { + "npc_id": "1178", + "loc_data": "{2768,3165,0,0,0}-" + }, + { + "npc_id": "1179", + "loc_data": "{2941,3100,0,1,6}-" + }, + { + "npc_id": "1180", + "loc_data": "{2916,3110,0,1,7}-" + }, + { + "npc_id": "1181", + "loc_data": "{2902,3101,0,1,1}-{2922,3105,0,1,6}-" + }, + { + "npc_id": "1183", + "loc_data": "{2206,3258,0,1,3}-{2200,3261,0,1,3}-{2193,3253,0,1,3}-{2192,3243,0,1,3}-" + }, + { + "npc_id": "1184", + "loc_data": "{2192,3249,0,1,3}-{2200,3249,0,1,3}-{2195,3247,0,1,3}-{2212,3258,0,1,3}-" + }, + { + "npc_id": "1192", + "loc_data": "{2924,3506,0,1,0}-{2927,3498,0,0,0}-{2297,3176,0,1,6}-" + }, + { + "npc_id": "1193", + "loc_data": "{2297,3176,0,1,6}-" + }, + { + "npc_id": "1194", + "loc_data": "{2298,3177,0,1,4}-" + }, + { + "npc_id": "1195", + "loc_data": "{2215,3171,0,1,4}-{2200,3224,0,1,0}-{2293,3156,0,1,3}-" + }, + { + "npc_id": "1196", + "loc_data": "{2217,3171,0,1,0}-{2199,3222,0,1,0}-{2201,3218,0,1,0}-{2291,3156,0,1,0}-" + }, + { + "npc_id": "1197", + "loc_data": "{2197,3218,0,1,0}-{2292,3153,0,1,0}-" + }, + { + "npc_id": "1198", + "loc_data": "{2296,3192,0,1,2}-" + }, + { + "npc_id": "1199", + "loc_data": "{2194,3255,0,0,6}-{2262,3151,0,1,0}-" + }, + { + "npc_id": "1201", + "loc_data": "{2198,3250,0,0,6}-{2203,3250,0,0,4}-{2264,3147,0,1,1}-{2266,3145,0,1,4}-" + }, + { + "npc_id": "1202", + "loc_data": "{2352,3172,0,1,4}-" + }, + { + "npc_id": "1203", + "loc_data": "{2189,3155,0,0,1}-{2183,3156,0,1,4}-{2194,3156,0,1,6}-{2182,3148,0,1,4}-{2179,3137,0,1,3}-{2189,3136,0,1,3}-{2182,3146,0,1,3}-{2187,3172,0,0,1}-{2180,3180,0,1,1}-" + }, + { + "npc_id": "1205", + "loc_data": "{3054,3254,0,0,0}-" + }, + { + "npc_id": "1206", + "loc_data": "{2185,3144,0,0,4}-" + }, + { + "npc_id": "1207", + "loc_data": "{3055,3254,0,0,0}-" + }, + { + "npc_id": "1208", + "loc_data": "{2194,3140,0,1,5}-" + }, + { + "npc_id": "1211", + "loc_data": "{2914,3418,0,0,6}-" + }, + { + "npc_id": "1212", + "loc_data": "{2247,3226,0,0,0}-{2249,3227,0,0,0}-{2249,3258,0,0,0}-{2251,3260,0,0,0}-{2259,3211,0,0,0}-{2267,3223,0,0,0}-{2267,3225,0,0,0}-{2298,3262,0,0,0}-{3202,5990,0,0,0}-{3232,5977,0,0,0}-{3234,5969,0,0,0}-{3237,5995,0,0,0}-{3242,5997,0,0,0}-{3244,5995,0,0,0}-{3245,5995,0,0,0}-{2194,3189,0,0,0}-{2196,3187,0,0,0}-{2196,3189,0,0,0}-{2206,3164,0,0,0}-{2209,3164,0,0,0}-{2216,3142,0,0,0}-{2218,3139,0,0,0}-{2178,3238,0,0,0}-{2208,3225,0,0,0}-{2210,3217,0,0,0}-{2213,3243,0,0,0}-{2218,3245,0,0,0}-{2220,3243,0,0,0}-{2221,3243,0,0,0}-{2695,6170,0,0,0}-{2697,6171,0,0,0}-{2697,6202,0,0,0}-{2699,6204,0,0,0}-{2707,6155,0,0,0}-{2715,6167,0,0,0}-{2715,6169,0,0,0}-{2746,6206,0,0,0}-{2729,6086,0,0,0}-{2731,6080,0,0,0}-{2731,6089,0,0,0}-{2744,6139,0,0,0}-{3271,5978,0,0,0}-{3273,5979,0,0,0}-{3273,6010,0,0,0}-{3275,6012,0,0,0}-{3283,5963,0,0,0}-{3291,5975,0,0,0}-{3291,5977,0,0,0}-{3322,6014,0,0,0}-{2281,3142,0,0,0}-{2283,3136,0,0,0}-{2283,3145,0,0,0}-{2296,3195,0,0,0}-" + }, + { + "npc_id": "1213", + "loc_data": "{2248,3225,0,0,0}-{2248,3227,0,0,0}-{2251,3257,0,0,0}-{2253,3259,0,0,0}-{2268,3224,0,0,0}-{2291,3262,0,0,0}-{3204,5988,0,0,0}-{3232,5979,0,0,0}-{3234,5967,0,0,0}-{3234,5976,0,0,0}-{3238,5996,0,0,0}-{3239,5997,0,0,0}-{3243,5996,0,0,0}-{2192,3188,0,0,0}-{2192,3191,0,0,0}-{2194,3190,0,0,0}-{2208,3163,0,0,0}-{2209,3163,0,0,0}-{2216,3136,0,0,0}-{2216,3140,0,0,0}-{2180,3236,0,0,0}-{2208,3227,0,0,0}-{2210,3215,0,0,0}-{2210,3224,0,0,0}-{2214,3244,0,0,0}-{2215,3245,0,0,0}-{2219,3244,0,0,0}-{2696,6169,0,0,0}-{2696,6171,0,0,0}-{2699,6201,0,0,0}-{2701,6203,0,0,0}-{2716,6168,0,0,0}-{2739,6206,0,0,0}-{2730,6084,0,0,0}-{3272,5977,0,0,0}-{3272,5979,0,0,0}-{3275,6009,0,0,0}-{3277,6011,0,0,0}-{3292,5976,0,0,0}-{3315,6014,0,0,0}-{2282,3140,0,0,0}-" + }, + { + "npc_id": "1214", + "loc_data": "{2891,3676,0,0,1}-" + }, + { + "npc_id": "1215", + "loc_data": "{2612,3287,0,0,0}-{2613,3287,0,0,0}-" + }, + { + "npc_id": "1216", + "loc_data": "{2611,3285,0,0,0}-" + }, + { + "npc_id": "1217", + "loc_data": "{3000,3386,0,1,0}-{3019,3368,0,1,0}-" + }, + { + "npc_id": "1218", + "loc_data": "{3412,3512,0,1,4}-{3412,3515,0,1,1}-{3413,3514,0,1,6}-{3414,3512,0,1,5}-{3415,3518,0,1,5}-{3416,3509,0,1,7}-{3416,3511,0,1,4}-{3417,3518,0,1,4}-{3418,3509,0,1,4}-{3419,3512,0,1,7}-{3420,3517,0,1,7}-{3420,3518,0,1,6}-{3423,3461,0,1,5}-{3426,3465,0,1,4}-{3427,3463,0,1,5}-{3428,3458,0,1,4}-{3428,3465,0,1,2}-{3430,3462,0,1,1}-{3430,3467,0,1,3}-{3433,3458,0,1,1}-{3433,3468,0,1,4}-{3434,3464,0,1,6}-" + }, + { + "npc_id": "1219", + "loc_data": "{3588,3461,0,1,0}-{3589,3493,0,1,0}-{3590,3509,0,1,0}-{3596,3476,0,1,0}-{3599,3483,0,1,0}-{3607,3460,0,1,0}-{3613,3499,0,1,0}-{3614,3515,0,1,0}-{3620,3472,0,1,0}-{3623,3504,0,1,0}-{3626,3475,0,1,0}-{3626,3491,0,1,0}-{3629,3511,0,1,0}-{3633,3463,0,1,0}-{3644,3498,0,1,0}-{3537,3496,0,1,0}-{3545,3502,0,1,0}-{3546,3462,0,1,0}-{3548,3480,0,1,0}-{3551,3489,0,1,0}-{3554,3506,0,1,0}-{3560,3462,0,1,0}-{3566,3483,0,1,0}-{3567,3474,0,1,0}-{3572,3492,0,1,0}-{3574,3507,0,1,0}-" + }, + { + "npc_id": "1221", + "loc_data": "{3597,3489,0,1,0}-{3611,3462,0,1,0}-{3620,3500,0,1,0}-{3636,3484,0,1,0}-{3566,3457,0,1,0}-{3567,3503,0,1,0}-" + }, + { + "npc_id": "1223", + "loc_data": "{3585,3478,0,1,0}-{3586,3480,0,1,0}-{3586,3496,0,1,0}-{3592,3477,0,1,0}-{3593,3458,0,1,0}-{3593,3508,0,1,0}-{3595,3491,0,1,0}-{3597,3479,0,1,0}-{3607,3466,0,1,0}-{3617,3477,0,1,0}-{3618,3514,0,1,0}-{3631,3471,0,1,0}-{3631,3499,0,1,0}-{3632,3459,0,1,0}-{3632,3475,0,1,0}-{3638,3472,0,1,0}-{3646,3467,0,1,0}-" + }, + { + "npc_id": "1227", + "loc_data": "{3424,3318,0,1,0}-{3423,3312,0,1,4}-{3494,3388,0,1,0}-{3507,3435,0,1,4}-{3511,3455,0,1,0}-{3508,3420,0,1,3}-{3508,3420,0,1,4}-{3506,3402,0,1,7}-{3502,3392,0,1,3}-{3484,3456,0,1,0}-{3486,3458,0,1,4}-" + }, + { + "npc_id": "1228", + "loc_data": "{3469,3346,0,1,0}-{3494,3447,0,1,0}-{3530,3440,0,1,0}-{3556,3453,0,1,0}-" + }, + { + "npc_id": "1229", + "loc_data": "{3421,3302,0,1,4}-{3417,3291,0,1,4}-{3423,3288,0,1,4}-{3418,3284,0,1,6}-{3427,3298,0,1,3}-{3431,3303,0,1,1}-{3432,3311,0,1,1}-{3502,3455,0,1,2}-{3516,3415,0,1,4}-{3511,3401,0,1,1}-{3492,3457,0,1,1}-" + }, + { + "npc_id": "1230", + "loc_data": "{3419,3280,0,1,4}-{3421,3277,0,1,4}-{3431,3275,0,1,3}-{3428,3314,0,1,1}-{3436,3318,0,1,5}-{3434,3322,0,1,6}-{3496,3447,0,1,7}-{3520,3437,0,1,4}-" + }, + { + "npc_id": "1231", + "loc_data": "{3429,3313,0,1,0}-{3429,3314,0,1,0}-{3437,3312,0,1,0}-{3437,3311,0,1,0}-{3451,3308,0,1,0}-{3447,3268,0,1,0}-{3438,3354,0,1,0}-{3504,3437,0,1,0}-{3509,3437,0,1,0}-{3498,3419,0,1,0}-{3493,3413,0,1,0}-{3524,3397,0,1,0}-" + }, + { + "npc_id": "1232", + "loc_data": "{3441,3265,0,1,5}-{3438,3277,0,1,7}-{3438,3283,0,1,4}-{3439,3315,0,1,3}-{3439,3310,0,1,1}-{3435,3302,0,1,3}-{3508,3420,0,1,1}-{3514,3415,0,1,7}-{3525,3417,0,1,3}-" + }, + { + "npc_id": "1233", + "loc_data": "{3485,3443,0,1,0}-{3516,3441,0,1,0}-{3537,3428,0,1,0}-" + }, + { + "npc_id": "1234", + "loc_data": "{3446,3282,0,1,1}-{3446,3298,0,1,3}-{3449,3304,0,1,1}-{3513,3383,0,1,0}-{3491,3388,0,1,3}-{3493,3454,0,1,2}-{3493,3454,0,1,0}-{3518,3454,0,1,2}-{3519,3441,0,1,7}-{3506,3417,0,1,5}-{3519,3401,0,1,2}-{3499,3420,0,1,3}-{3516,3410,0,1,7}-{3520,3412,0,1,0}-" + }, + { + "npc_id": "1235", + "loc_data": "{3425,3306,0,1,1}-{3442,3303,0,1,3}-{3437,3299,0,1,1}-{3422,3321,0,1,1}-{3509,3386,0,1,2}-{3503,3420,0,1,3}-{3514,3398,0,1,4}-{3486,3458,0,1,7}-{3524,3419,0,1,1}-" + }, + { + "npc_id": "1239", + "loc_data": "{3166,3033,0,1,1}-{3174,3043,0,1,6}-{3177,3041,0,1,4}-{3176,3038,0,1,4}-{3177,3035,0,1,7}-{3183,3035,0,1,6}-{3182,3032,0,1,6}-" + }, + { + "npc_id": "1240", + "loc_data": "{3502,3288,0,1,4}-{3505,3284,0,1,4}-{3490,3292,0,1,4}-{3502,3300,0,1,4}-{3492,3303,0,1,4}-{3516,3303,0,1,4}-{3478,3281,0,1,4}-{3473,3273,0,1,4}-{3469,3288,0,1,4}-{3469,3304,0,1,4}-" + }, + { + "npc_id": "1251", + "loc_data": "{3474,3309,0,1,5}-{3486,3277,0,1,4}-{3496,3289,0,0,3}-" + }, + { + "npc_id": "1253", + "loc_data": "{3488,3297,0,0,6}-" + }, + { + "npc_id": "1257", + "loc_data": "{3490,3290,0,0,3}-{3487,3303,0,1,5}-{3496,3296,0,1,4}-{3479,3303,0,1,4}-{3498,3282,0,1,3}-{3473,3281,0,1,3}-{3478,3308,0,1,1}-" + }, + { + "npc_id": "1258", + "loc_data": "{3488,3287,0,1,1}-{3501,3285,0,1,5}-{3478,3274,0,1,4}-{3497,3283,0,1,1}-" + }, + { + "npc_id": "1261", + "loc_data": "{3492,3300,0,1,4}-{3498,3300,0,1,5}-{3487,3302,0,1,6}-{3497,3299,0,1,5}-{3488,3273,0,1,6}-" + }, + { + "npc_id": "1262", + "loc_data": "{3487,3283,0,1,1}-{3477,3300,0,1,4}-{3497,3276,0,1,1}-{3502,3279,0,1,1}-{3481,3296,0,1,2}-" + }, + { + "npc_id": "1263", + "loc_data": "{3108,3160,1,1,1}-" + }, + { + "npc_id": "1266", + "loc_data": "{2680,3719,0,0,7}-{2684,3722,0,0,1}-{2684,3726,0,0,1}-{2678,3728,0,0,2}-{2673,3728,0,0,0}-{2670,3724,0,0,3}-{2671,3726,0,0,2}-{2679,3731,0,0,2}-{2684,3729,0,0,6}-{2706,3711,0,0,1}-{2688,3721,0,0,1}-{2693,3715,0,0,5}-{2699,3715,0,0,2}-{2712,3718,0,0,5}-{2716,3721,0,0,7}-{2722,3726,0,0,1}-{2524,3764,0,0,7}-{2508,3762,0,0,0}-{2510,3755,0,0,2}-{2523,3756,0,0,1}-{2532,3753,0,0,0}-{2529,3755,0,0,1}-{2528,3739,0,0,6}-{2529,3730,0,0,0}-{2518,3724,0,0,1}-{2508,3723,0,0,1}-{2525,3718,0,0,1}-{2549,3733,0,0,3}-" + }, + { + "npc_id": "1268", + "loc_data": "{2681,3716,0,0,2}-{2678,3721,0,0,2}-{2684,3719,0,0,1}-{2699,3719,0,0,4}-{2701,3717,0,0,2}-{2707,3719,0,0,0}-{2700,3726,0,0,2}-{2695,3713,0,0,2}-{2716,3718,0,0,5}-{2706,3713,0,0,2}-{2539,3761,0,0,7}-{2539,3759,0,0,7}-{2528,3767,0,0,3}-{2526,3753,0,0,2}-{2513,3755,0,0,3}-{2505,3753,0,0,3}-{2530,3751,0,0,1}-{2526,3755,0,0,1}-{2532,3758,0,0,6}-{2532,3751,0,0,3}-{2530,3737,0,0,2}-{2531,3728,0,0,0}-{2523,3723,0,0,1}-{2520,3724,0,0,3}-{2515,3718,0,0,3}-{2505,3724,0,0,4}-{2505,3729,0,0,6}-{2535,3718,0,0,4}-{2536,3724,0,0,1}-{2543,3729,0,0,6}-{2550,3734,0,0,1}-{2552,3747,0,0,6}-{2552,3752,0,0,6}-" + }, + { + "npc_id": "1269", + "loc_data": "{2672,3683,0,1,3}-" + }, + { + "npc_id": "1270", + "loc_data": "{2770,3624,0,0,0}-" + }, + { + "npc_id": "1274", + "loc_data": "{2660,3680,0,0,6}-" + }, + { + "npc_id": "1275", + "loc_data": "{2657,3680,0,0,6}-" + }, + { + "npc_id": "1276", + "loc_data": "{2658,3679,0,0,6}-" + }, + { + "npc_id": "1277", + "loc_data": "{2659,3678,0,0,6}-" + }, + { + "npc_id": "1278", + "loc_data": "{2659,3664,0,1,3}-" + }, + { + "npc_id": "1281", + "loc_data": "{2661,3651,0,1,3}-" + }, + { + "npc_id": "1282", + "loc_data": "{2640,3681,0,1,4}-" + }, + { + "npc_id": "1283", + "loc_data": "{2647,3660,0,1,5}-" + }, + { + "npc_id": "1284", + "loc_data": "{2658,3673,0,1,1}-" + }, + { + "npc_id": "1285", + "loc_data": "{2657,3669,0,1,1}-" + }, + { + "npc_id": "1286", + "loc_data": "{2656,3676,0,1,1}-" + }, + { + "npc_id": "1287", + "loc_data": "{2652,3588,0,1,1}-" + }, + { + "npc_id": "1288", + "loc_data": "{2634,3667,0,1,1}-" + }, + { + "npc_id": "1289", + "loc_data": "{2667,3692,0,1,1}-" + }, + { + "npc_id": "1294", + "loc_data": "{2658,3673,0,1,7}-" + }, + { + "npc_id": "1296", + "loc_data": "{2660,3663,0,0,6}-{2657,3663,0,0,6}-" + }, + { + "npc_id": "1298", + "loc_data": "{2663,3646,0,0,6}-" + }, + { + "npc_id": "1299", + "loc_data": "{2660,3646,0,0,6}-" + }, + { + "npc_id": "1300", + "loc_data": "{2662,3674,0,1,1}-" + }, + { + "npc_id": "1301", + "loc_data": "{2623,3675,0,1,6}-" + }, + { + "npc_id": "1302", + "loc_data": "{2641,3699,0,0,4}-" + }, + { + "npc_id": "1303", + "loc_data": "{2664,3692,0,1,3}-" + }, + { + "npc_id": "1304", + "loc_data": "{2582,3845,0,0,3}-" + }, + { + "npc_id": "1305", + "loc_data": "{2643,3676,0,1,7}-" + }, + { + "npc_id": "1306", + "loc_data": "{2674,3677,0,1,6}-" + }, + { + "npc_id": "1307", + "loc_data": "{2658,3673,0,1,7}-" + }, + { + "npc_id": "1308", + "loc_data": "{2672,3662,0,1,3}-" + }, + { + "npc_id": "1309", + "loc_data": "{2667,3653,0,1,3}-" + }, + { + "npc_id": "1310", + "loc_data": "{2667,3701,0,1,4}-" + }, + { + "npc_id": "1311", + "loc_data": "{2655,3651,0,1,3}-" + }, + { + "npc_id": "1312", + "loc_data": "{2639,3651,0,1,6}-" + }, + { + "npc_id": "1313", + "loc_data": "{2626,3653,0,1,5}-" + }, + { + "npc_id": "1314", + "loc_data": "{2675,3677,0,1,3}-" + }, + { + "npc_id": "1315", + "loc_data": "{2646,3675,0,1,3}-" + }, + { + "npc_id": "1317", + "loc_data": "{2632,3677,0,1,2}-{2641,3682,0,1,3}-{2643,3675,0,1,6}-{2643,3674,0,1,4}-{2646,3668,0,1,3}-{2651,3669,0,1,3}-{2648,3688,0,1,4}-{2656,3692,0,1,1}-" + }, + { + "npc_id": "1318", + "loc_data": "{2613,3668,0,1,3}-{2671,3658,0,1,2}-{2638,3648,0,1,3}-{2626,3658,0,1,4}-{2626,3668,0,1,1}-{2630,3673,0,1,7}-{2635,3680,0,1,4}-{2644,3675,0,1,5}-{2642,3681,0,1,3}-{2631,3678,0,1,6}-{2661,3698,0,1,1}-{2663,3687,0,1,3}-{2673,3695,0,1,3}-{2674,3710,0,1,1}-{2676,3693,0,1,3}-{2675,3685,0,1,4}-{2669,3677,0,1,1}-{2667,3670,0,1,2}-{2675,3670,0,1,4}-{2679,3685,0,1,2}-{2667,3671,0,1,3}-{2666,3663,0,1,6}-{2658,3657,0,1,4}-{2684,3649,0,1,4}-{2679,3649,0,1,4}-{2646,3664,0,1,4}-{2646,3655,0,1,1}-{2637,3655,0,1,3}-{2667,3658,0,1,3}-{2688,3659,0,1,2}-" + }, + { + "npc_id": "1320", + "loc_data": "{2738,3636,0,1,7}-{2739,3636,0,1,7}-{2738,3637,0,1,4}-{2735,3637,0,1,3}-" + }, + { + "npc_id": "1321", + "loc_data": "{2736,3642,0,1,4}-{2744,3638,0,1,4}-" + }, + { + "npc_id": "1329", + "loc_data": "{3085,3640,0,1,0}-" + }, + { + "npc_id": "1334", + "loc_data": "{2509,3639,1,1,3}-" + }, + { + "npc_id": "1335", + "loc_data": "{2518,4633,0,1,1}-" + }, + { + "npc_id": "1336", + "loc_data": "{2508,3635,0,1,3}-" + }, + { + "npc_id": "1337", + "loc_data": "{2445,4599,1,1,3}-" + }, + { + "npc_id": "1338", + "loc_data": "{3151,5559,0,1,2}-{3157,5548,0,1,3}-{3155,5553,0,1,4}-{3145,5559,0,1,6}-{3152,5556,0,1,3}-{3149,5544,0,1,0}-{3145,5548,0,1,3}-" + }, + { + "npc_id": "1339", + "loc_data": "{3153,5547,0,1,0}-{3150,5545,0,1,1}-" + }, + { + "npc_id": "1340", + "loc_data": "{3147,5557,0,1,3}-{3154,5559,0,1,4}-" + }, + { + "npc_id": "1343", + "loc_data": "{3145,5548,0,1,6}-" + }, + { + "npc_id": "1357", + "loc_data": "{2201,4942,0,1,4}-" + }, + { + "npc_id": "1358", + "loc_data": "{2208,4959,0,1,6}-" + }, + { + "npc_id": "1359", + "loc_data": "{2612,3875,1,1,6}-" + }, + { + "npc_id": "1360", + "loc_data": "{2620,3896,0,0,3}-" + }, + { + "npc_id": "1369", + "loc_data": "{2527,5876,0,1,0}-" + }, + { + "npc_id": "1373", + "loc_data": "{2500,3860,1,1,4}-" + }, + { + "npc_id": "1374", + "loc_data": "{2505,3854,1,0,4}-{2509,3849,0,0,4}-" + }, + { + "npc_id": "1375", + "loc_data": "{2501,3858,1,0,4}-" + }, + { + "npc_id": "1376", + "loc_data": "{2548,3895,0,1,0}-" + }, + { + "npc_id": "1377", + "loc_data": "{2544,3843,0,1,6}-" + }, + { + "npc_id": "1378", + "loc_data": "{2516,3865,0,1,4}-" + }, + { + "npc_id": "1385", + "loc_data": "{2629,3694,0,0,6}-" + }, + { + "npc_id": "1389", + "loc_data": "{2603,3877,0,1,1}-" + }, + { + "npc_id": "1390", + "loc_data": "{2604,3876,0,1,4}-" + }, + { + "npc_id": "1391", + "loc_data": "{2604,3876,0,1,3}-" + }, + { + "npc_id": "1393", + "loc_data": "{2519,3868,0,0,3}-" + }, + { + "npc_id": "1394", + "loc_data": "{2519,3863,0,0,1}-" + }, + { + "npc_id": "1395", + "loc_data": "{2547,3868,0,0,1}-" + }, + { + "npc_id": "1396", + "loc_data": "{2525,3892,0,0,4}-" + }, + { + "npc_id": "1397", + "loc_data": "{2573,3856,0,0,4}-" + }, + { + "npc_id": "1398", + "loc_data": "{2526,3850,0,0,6}-" + }, + { + "npc_id": "1399", + "loc_data": "{2577,3854,0,0,1}-" + }, + { + "npc_id": "1400", + "loc_data": "{3037,4512,0,1,0}-{3049,4498,0,1,1}-" + }, + { + "npc_id": "1401", + "loc_data": "{2605,3878,0,1,1}-" + }, + { + "npc_id": "1402", + "loc_data": "{2603,3877,0,1,1}-" + }, + { + "npc_id": "1404", + "loc_data": "{2239,3164,0,1,2}-{2241,3166,0,1,3}-{2242,3163,0,1,3}-{3037,4492,0,1,4}-{3036,4502,0,1,4}-{3029,4520,0,1,1}-{3019,4512,0,1,1}-" + }, + { + "npc_id": "1405", + "loc_data": "{2576,3843,0,0,6}-" + }, + { + "npc_id": "1427", + "loc_data": "{2957,3025,0,0,0}-" + }, + { + "npc_id": "1434", + "loc_data": "{2753,2770,0,1,6}-" + }, + { + "npc_id": "1447", + "loc_data": "{2761,2785,0,1,3}-" + }, + { + "npc_id": "1452", + "loc_data": "{2743,2796,0,1,6}-" + }, + { + "npc_id": "1454", + "loc_data": "{2742,2790,0,1,1}-" + }, + { + "npc_id": "1457", + "loc_data": "{2747,2782,0,0,1}-{2754,2778,0,1,1}-{2761,2778,0,1,1}-{2765,2779,0,1,4}-{2767,2784,0,1,6}-{2772,2781,0,1,5}-{2774,2787,0,1,1}-{2777,2790,0,1,4}-{2762,2793,0,1,3}-{2756,2789,0,1,3}-" + }, + { + "npc_id": "1458", + "loc_data": "{2728,2751,0,1,1}-{2715,2749,0,1,2}-{2728,2758,0,1,1}-{2727,2762,0,1,6}-{2728,2755,0,1,6}-{2714,2753,0,1,1}-{2714,2757,0,1,6}-{2714,2761,0,1,6}-" + }, + { + "npc_id": "1459", + "loc_data": "{2790,2791,0,1,4}-{2803,2785,0,1,7}-{2797,2792,0,1,0}-{2800,2779,0,1,5}-{2788,2779,0,1,7}-{2795,2776,0,1,3}-" + }, + { + "npc_id": "1460", + "loc_data": "{2787,2794,0,1,3}-" + }, + { + "npc_id": "1463", + "loc_data": "{2600,3276,0,1,4}-{2601,3276,0,1,6}-{2601,3277,0,1,6}-{2601,3278,0,1,2}-{2602,3279,0,1,5}-{2602,3282,0,1,4}-{2604,3276,0,1,4}-{2605,3280,0,1,4}-{2605,3281,0,1,7}-{2606,3280,0,1,4}-" + }, + { + "npc_id": "1469", + "loc_data": "{2595,3277,0,0,0}-" + }, + { + "npc_id": "1471", + "loc_data": "{2707,9102,0,1,0}-{2704,9107,0,1,0}-{2705,9110,0,1,0}-{2708,9107,0,1,0}-{2743,9105,0,1,0}-{2741,9103,0,1,0}-{2744,9101,0,1,0}-{2743,9099,0,1,0}-{2737,9124,0,1,0}-{2741,9123,0,1,0}-{2740,9120,0,1,0}-{2736,9119,0,1,0}-{2734,9117,0,1,0}-{2712,9135,0,1,0}-{2714,9131,0,1,0}-{2709,9131,0,1,0}-{2708,9135,0,1,0}-" + }, + { + "npc_id": "1514", + "loc_data": "{3432,3487,0,0,0}-" + }, + { + "npc_id": "1515", + "loc_data": "{3438,3487,0,0,0}-" + }, + { + "npc_id": "1516", + "loc_data": "{3437,3487,0,0,0}-" + }, + { + "npc_id": "1517", + "loc_data": "{3434,3483,0,0,0}-" + }, + { + "npc_id": "1518", + "loc_data": "{3435,3483,0,0,0}-" + }, + { + "npc_id": "1519", + "loc_data": "{3433,3486,0,0,0}-" + }, + { + "npc_id": "1520", + "loc_data": "{3434,3486,0,0,0}-" + }, + { + "npc_id": "1526", + "loc_data": "{2443,3089,0,0,0}-" + }, + { + "npc_id": "1544", + "loc_data": "{2911,10175,0,0,4}-{2912,10175,0,0,4}-{2913,10175,0,0,4}-{2914,10175,0,0,4}-{2909,10173,0,0,4}-{2910,10173,0,0,4}-{2911,10173,0,0,4}-{2912,10173,0,0,4}-{2913,10173,0,0,4}-{2909,10171,0,0,4}-{2910,10171,0,0,4}-{2911,10169,0,0,4}-{2912,10169,0,0,4}-{2913,10169,0,0,4}-" + }, + { + "npc_id": "1553", + "loc_data": "{2828,10065,1,0,0}-" + }, + { + "npc_id": "1554", + "loc_data": "{2829,10104,1,0,0}-" + }, + { + "npc_id": "1555", + "loc_data": "{2829,10096,1,0,0}-" + }, + { + "npc_id": "1558", + "loc_data": "{2800,3859,0,1,0}-{2803,3864,0,1,0}-{2805,3859,0,1,0}-" + }, + { + "npc_id": "1560", + "loc_data": "{3150,5454,0,1,4}-{3144,5446,0,1,7}-{3166,5446,0,1,3}-{3158,5451,0,1,7}-{2775,10224,0,1,0}-{2783,10199,0,1,0}-{2784,10233,0,1,0}-" + }, + { + "npc_id": "1561", + "loc_data": "{3144,5450,0,1,1}-{3153,5454,0,1,5}-{3160,5450,0,1,5}-{3167,5450,0,1,3}-{3161,5451,0,1,1}-{2777,10224,0,1,0}-{2784,10231,0,1,0}-{2792,10222,0,1,0}-" + }, + { + "npc_id": "1562", + "loc_data": "{3147,5448,0,1,4}-{2772,10221,0,1,0}-{2785,10201,0,1,0}-{2787,10232,0,1,0}-" + }, + { + "npc_id": "1563", + "loc_data": "{3152,5453,0,1,0}-{2773,10220,0,1,0}-{2788,10198,0,1,0}-{2790,10220,0,1,0}-{2800,10218,0,1,0}-" + }, + { + "npc_id": "1564", + "loc_data": "{2770,10219,0,1,0}-{2788,10230,0,1,0}-{2798,10216,0,1,0}-" + }, + { + "npc_id": "1565", + "loc_data": "{2788,10221,0,1,0}-{2801,10216,0,1,0}-" + }, + { + "npc_id": "1566", + "loc_data": "{2786,10199,0,1,0}-{2790,10222,0,1,0}-{2799,10214,0,1,0}-" + }, + { + "npc_id": "1582", + "loc_data": "{2568,9889,0,1,6}-{2578,9898,0,1,1}-{2657,9500,0,0,1}-{2632,9589,2,0,1}-{2628,9549,2,0,5}-{2629,9543,2,0,2}-{3249,5517,0,1,3}-" + }, + { + "npc_id": "1583", + "loc_data": "{2563,9885,0,1,7}-{2575,9897,0,1,1}-{2655,9481,0,0,3}-{2631,9579,2,0,4}-{3211,5519,0,1,0}-{3254,5513,0,1,7}-" + }, + { + "npc_id": "1584", + "loc_data": "{2661,9481,0,0,4}-{2635,9570,2,0,1}-{2627,9539,2,0,5}-{3231,5494,0,1,7}-{3209,5512,0,1,6}-" + }, + { + "npc_id": "1585", + "loc_data": "{2575,9892,0,1,6}-{2666,9482,0,0,5}-{2641,9563,2,0,5}-{3257,5523,0,1,1}-{3204,5516,0,1,3}-{3244,9369,0,1,3}-{3252,9359,0,1,3}-{3306,9400,0,1,3}-" + }, + { + "npc_id": "1586", + "loc_data": "{2668,9497,0,0,4}-{2635,9565,2,0,4}-{2633,9554,2,0,4}-{3247,5520,0,1,5}-{3205,5513,0,1,6}-{3213,5519,0,1,7}-" + }, + { + "npc_id": "1587", + "loc_data": "{2830,3241,0,1,6}-{3145,3812,0,1,0}-{3141,3826,0,1,0}-{2645,9489,0,0,7}-{2681,9577,0,0,0}-{2673,9591,0,0,5}-{2655,9575,0,0,5}-{2640,9580,0,0,0}-{2646,9553,0,0,1}-{2650,9536,0,0,7}-{2670,9543,0,0,0}-{2663,9555,0,0,7}-{2692,3202,0,1,4}-{2695,3216,0,1,0}-{3237,5557,0,1,3}-" + }, + { + "npc_id": "1588", + "loc_data": "{2826,3245,0,1,3}-{2637,9532,0,0,5}-{2634,9521,0,0,0}-{2642,9493,0,0,0}-{2645,9484,0,0,7}-{2679,9592,0,0,2}-{2654,9587,0,0,3}-{2650,9564,0,0,6}-{2647,9548,0,0,6}-{2637,9545,0,0,5}-{2678,9548,0,0,4}-{2658,9551,0,0,1}-{2691,3215,0,1,3}-{3246,5558,0,1,4}-" + }, + { + "npc_id": "1589", + "loc_data": "{2698,9503,0,0,7}-{2713,9505,0,0,0}-{2717,9502,0,0,7}-{2699,9523,0,0,0}-{2706,9525,0,0,2}-{2719,9517,0,0,5}-{2724,9515,0,0,3}-" + }, + { + "npc_id": "1590", + "loc_data": "{3184,5557,0,1,7}-{3148,5514,0,1,6}-{3144,5514,0,1,3}-{2730,9490,0,1,0}-{2731,9482,0,1,7}-{2742,9491,0,1,0}-" + }, + { + "npc_id": "1591", + "loc_data": "{2703,9456,0,0,0}-{2717,9459,0,0,7}-{2731,9460,0,0,3}-{2737,9454,0,0,3}-{2737,9444,0,0,3}-{2736,9432,0,0,3}-{2738,9421,0,0,5}-{2727,9418,0,0,1}-{2724,9439,0,0,0}-{2715,9443,0,0,4}-{2702,9443,0,0,3}-{2700,9428,0,0,3}-{2705,9419,0,0,7}-" + }, + { + "npc_id": "1592", + "loc_data": "{2728,9426,0,0,4}-{2714,9432,0,0,0}-{2707,9450,0,0,6}-{2724,9451,0,0,6}-" + }, + { + "npc_id": "1593", + "loc_data": "{2652,9526,0,0,7}-{2656,9514,0,0,7}-{2666,9522,0,0,4}-{2665,9513,0,0,3}-{2666,9489,0,0,1}-{2626,9535,2,0,6}-{2628,9507,2,0,5}-{2635,9508,2,0,2}-{2634,9483,2,0,7}-{2681,9563,0,0,5}-{2677,9586,0,0,2}-{2644,9587,0,0,1}-{2638,9592,2,0,5}-{2633,9583,2,0,7}-{2627,9545,2,0,6}-{2744,9503,0,0,2}-{2702,9525,0,0,2}-{2704,9487,0,0,7}-{2711,9485,0,0,2}-{2722,9486,0,0,4}-{2717,9480,0,0,6}-{2733,9494,0,0,1}-{2742,9489,0,0,0}-" + }, + { + "npc_id": "1594", + "loc_data": "{2646,9530,0,0,7}-{2643,9519,0,0,7}-{2660,9521,0,0,1}-{2665,9527,0,0,2}-{2671,9521,0,0,7}-{2670,9516,0,0,6}-{2660,9497,0,0,7}-{2643,9487,0,0,5}-{2653,9488,0,0,2}-{2677,9501,0,0,2}-{2683,9476,0,0,7}-{2630,9515,2,0,7}-{2642,9506,2,0,7}-{2629,9487,2,0,5}-{2648,9476,2,0,7}-{2672,9569,0,0,1}-{2657,9577,0,0,3}-{2643,9543,0,0,7}-{2658,9546,0,0,6}-{2636,9574,2,0,7}-{2643,9566,2,0,7}-{2635,9559,2,0,7}-{2699,9516,0,0,0}-{2709,9524,0,0,7}-{2700,9489,0,0,5}-{2703,9484,0,0,5}-{2710,9481,0,0,2}-{2716,9486,0,0,2}-{2726,9489,0,0,1}-{2735,9481,0,0,4}-{2740,9497,0,0,2}-{2739,9506,0,0,0}-" + }, + { + "npc_id": "1595", + "loc_data": "{2744,3152,0,1,7}-" + }, + { + "npc_id": "1597", + "loc_data": "{3147,9914,0,1,6}-" + }, + { + "npc_id": "1598", + "loc_data": "{2447,4429,0,1,6}-" + }, + { + "npc_id": "1600", + "loc_data": "{3190,9574,0,1,6}-{2791,9997,0,1,3}-" + }, + { + "npc_id": "1601", + "loc_data": "{2797,9997,0,1,6}-{2781,9996,0,1,7}-" + }, + { + "npc_id": "1602", + "loc_data": "{2793,9995,0,1,3}-{2783,9998,0,1,6}-" + }, + { + "npc_id": "1603", + "loc_data": "{2789,9994,0,1,1}-{2786,9998,0,1,5}-" + }, + { + "npc_id": "1604", + "loc_data": "{3434,3550,1,1,3}-{3439,3549,1,1,4}-{3425,3549,1,1,5}-{3423,3553,1,1,4}-{3426,3541,1,1,1}-{3425,3541,1,1,2}-{3426,3539,1,1,0}-{3420,3537,1,1,3}-{3417,3536,1,1,6}-" + }, + { + "npc_id": "1608", + "loc_data": "{2698,9999,0,1,6}-{2695,9997,0,1,7}-{2697,9996,0,1,5}-{2695,9999,0,1,6}-" + }, + { + "npc_id": "1609", + "loc_data": "{2700,9994,0,1,6}-{2698,10001,0,1,4}-{2703,9994,0,1,4}-{2701,10000,0,1,4}-" + }, + { + "npc_id": "1610", + "loc_data": "{3443,3537,2,1,4}-{3434,3536,2,1,4}-{3443,3540,2,1,3}-{3446,3548,2,1,4}-{3439,3549,2,1,3}-{3434,3547,2,1,1}-{3444,3537,2,1,3}-{3174,5474,0,1,4}-{3175,5479,0,1,6}-{3183,5473,0,1,7}-{3178,5468,0,1,4}-" + }, + { + "npc_id": "1612", + "loc_data": "{3438,3562,0,1,1}-{3430,3564,0,1,3}-{3434,3555,0,1,5}-{3443,3551,0,1,4}-{3442,3545,0,1,1}-{3449,3536,0,1,1}-{3440,3539,0,1,4}-" + }, + { + "npc_id": "1613", + "loc_data": "{3439,3565,2,1,6}-{3443,3571,2,1,1}-{3435,3565,2,1,3}-{3443,3564,2,1,2}-{3444,3559,2,1,2}-{3427,3558,2,1,0}-{3425,3557,2,1,4}-{3430,3557,2,1,3}-{3170,5554,0,1,2}-{3166,5556,0,1,5}-{3171,5560,0,1,4}-{3173,5556,0,1,3}-" + }, + { + "npc_id": "1615", + "loc_data": "{3422,3566,2,1,5}-{3426,3568,2,1,6}-{3418,3562,2,1,4}-{3414,3566,2,1,3}-{3412,3570,2,1,4}-{3421,3572,2,1,2}-{3422,3571,2,1,1}-{3033,4873,0,1,7}-{3039,4885,0,1,3}-{3050,4890,0,1,3}-{3062,4892,0,1,5}-{3064,4901,0,1,3}-{3056,4912,0,1,3}-{3048,4916,0,1,5}-{3038,4911,0,1,6}-{3022,4914,0,1,6}-{3018,4902,0,1,6}-{3025,4898,0,1,4}-{3033,4885,0,1,0}-{3021,4877,0,1,3}-{3048,4872,0,1,1}-{3061,4880,0,1,3}-{3061,4891,0,1,1}-{3054,4901,0,1,1}-" + }, + { + "npc_id": "1616", + "loc_data": "{2741,10011,0,1,2}-{2742,10010,0,1,3}-{2739,10014,0,1,1}-{2740,10006,0,1,3}-" + }, + { + "npc_id": "1617", + "loc_data": "{2743,10003,0,1,1}-{2746,10008,0,1,2}-{2743,10015,0,1,3}-{2745,10011,0,1,5}-{2744,10016,0,1,1}-" + }, + { + "npc_id": "1618", + "loc_data": "{3424,3565,1,1,1}-{3416,3562,1,1,6}-{3423,3559,1,1,0}-{3424,3560,1,1,4}-{3412,3558,1,1,1}-{3412,3568,1,1,1}-{3417,3565,1,1,3}-" + }, + { + "npc_id": "1620", + "loc_data": "{2794,10036,0,1,4}-{2788,10037,0,1,0}-{2795,10034,0,1,3}-{2785,10035,0,1,3}-" + }, + { + "npc_id": "1621", + "loc_data": "{2797,10035,0,1,6}-{2787,10032,0,1,3}-{2802,10031,0,1,3}-" + }, + { + "npc_id": "1623", + "loc_data": "{2725,9999,0,1,6}-" + }, + { + "npc_id": "1624", + "loc_data": "{3179,5522,0,1,6}-{3168,5513,0,1,3}-{3174,5514,0,1,6}-{3178,5517,0,1,4}-{3178,5528,0,1,1}-{3169,5516,0,1,3}-{3179,5524,0,1,4}-{3223,9393,0,1,5}-{3225,9401,0,1,0}-{3222,9375,0,1,6}-{3220,9380,0,1,6}-{3215,9364,0,1,3}-{3213,9361,0,1,1}-{3212,9355,0,1,2}-{3230,9367,0,1,3}-{3240,9350,0,1,5}-{3248,9348,0,1,4}-{3255,9350,0,1,4}-{3256,9392,0,1,4}-" + }, + { + "npc_id": "1626", + "loc_data": "{2723,10005,0,1,0}-{2726,9998,0,1,1}-{2723,10009,0,1,3}-" + }, + { + "npc_id": "1627", + "loc_data": "{2724,10008,0,1,4}-{2721,10005,0,1,1}-{2724,10005,0,1,3}-{2729,10004,0,1,3}-{2724,10012,0,1,4}-{2718,10009,0,1,1}-{2721,10001,0,1,7}-{2720,9996,0,1,7}-{2721,10006,0,1,3}-" + }, + { + "npc_id": "1628", + "loc_data": "{3155,5536,0,1,4}-{3156,5540,0,1,3}-{3157,5538,0,1,2}-{3166,5537,0,1,1}-{3165,5541,0,1,3}-{2723,10004,0,1,4}-{2722,9999,0,1,1}-{2729,10002,0,1,1}-" + }, + { + "npc_id": "1629", + "loc_data": "{3162,5538,0,1,2}-{3157,5538,0,1,4}-{3155,5537,0,1,1}-{3164,5538,0,1,2}-" + }, + { + "npc_id": "1631", + "loc_data": "{3160,9589,0,1,3}-{3167,9589,0,1,6}-{3179,9585,0,1,1}-{3188,9572,0,1,7}-{3190,9580,0,1,3}-{3206,9586,0,1,3}-{3221,9586,0,1,7}-{3226,9573,0,1,5}-{3223,9569,0,1,1}-{2800,10017,0,1,1}-{2796,10021,0,1,1}-{2805,10021,0,1,1}-{2803,10013,0,1,1}-" + }, + { + "npc_id": "1632", + "loc_data": "{2798,10019,0,1,1}-{2800,10015,0,1,1}-{2797,10018,0,1,1}-" + }, + { + "npc_id": "1633", + "loc_data": "{1837,3244,0,1,0}-{1836,3250,0,1,0}-{1845,3251,0,1,0}-{1845,3247,0,1,0}-{1849,3241,0,1,0}-{1853,3247,0,1,0}-{1848,3254,0,1,0}-{1858,3251,0,1,0}-{1935,3217,0,1,0}-{1933,3209,0,1,0}-{1930,3208,0,1,0}-{1929,3217,0,1,0}-{1927,3219,0,1,0}-{1924,3211,0,1,0}-{1920,3216,0,1,0}-{1925,3213,0,1,0}-{3263,9399,0,1,3}-{3274,9397,0,1,1}-{3275,9393,0,1,6}-{3271,9384,0,1,0}-{3270,9380,0,1,2}-{3283,9378,0,1,6}-{3285,9386,0,1,5}-{3284,9401,0,1,4}-{3278,9353,0,1,1}-{3299,9380,0,1,1}-{3319,9402,0,1,1}-{3305,9350,0,1,4}-{3248,9374,0,1,3}-{3253,9363,0,1,3}-{3249,9355,0,1,3}-{2761,10007,0,1,0}-{2757,10010,0,1,3}-{2763,10000,0,1,5}-{2760,10011,0,1,0}-{2761,9997,0,1,4}-" + }, + { + "npc_id": "1634", + "loc_data": "{2757,10008,0,1,6}-{2760,10005,0,1,5}-" + }, + { + "npc_id": "1635", + "loc_data": "{2758,10001,0,1,1}-{2763,10006,0,1,1}-{2766,10000,0,1,6}-{2759,9999,0,1,7}-" + }, + { + "npc_id": "1636", + "loc_data": "{2760,10004,0,1,1}-{2760,10002,0,1,6}-" + }, + { + "npc_id": "1637", + "loc_data": "{2700,10027,0,1,6}-{3276,5454,0,1,4}-{3279,5450,0,1,0}-{3271,5446,0,1,3}-{3277,5512,0,1,1}-{3278,5535,0,0,0}-{3277,5520,0,1,1}-" + }, + { + "npc_id": "1638", + "loc_data": "{2704,10022,0,1,4}-{2707,10023,0,1,4}-{3284,5456,0,1,1}-{3278,5453,0,1,1}-{3271,5512,0,1,4}-" + }, + { + "npc_id": "1639", + "loc_data": "{2711,10028,0,1,2}-{2710,10030,0,1,6}-{3283,5461,0,1,4}-{3285,5456,0,1,6}-{3275,5455,0,1,5}-{3272,5446,0,1,4}-{3277,5445,0,1,3}-" + }, + { + "npc_id": "1640", + "loc_data": "{2705,10028,0,1,3}-{2704,10031,0,1,6}-{3272,5445,0,1,4}-" + }, + { + "npc_id": "1641", + "loc_data": "{2708,10025,0,1,6}-" + }, + { + "npc_id": "1642", + "loc_data": "{2703,10020,0,1,0}-" + }, + { + "npc_id": "1643", + "loc_data": "{3434,3562,1,1,6}-{3439,3558,1,1,5}-{3444,3567,1,1,4}-{3439,3571,1,1,3}-{3435,3570,1,1,7}-{3447,3561,1,1,4}-{3442,3573,1,1,6}-{3246,5446,0,1,3}-{3237,5455,0,1,0}-{3246,5450,0,1,4}-" + }, + { + "npc_id": "1644", + "loc_data": "{3240,5448,0,1,7}-" + }, + { + "npc_id": "1648", + "loc_data": "{3426,3537,0,1,4}-{3413,3536,0,1,3}-{3419,3545,0,1,2}-{3426,3544,0,1,6}-{3410,3535,0,1,2}-{3425,3556,0,1,6}-{3418,3557,0,1,1}-{3428,3571,0,1,3}-{3432,3573,0,1,4}-" + }, + { + "npc_id": "1650", + "loc_data": "{3411,3541,0,1,3}-" + }, + { + "npc_id": "1655", + "loc_data": "{3424,3544,0,1,1}-{3423,3546,0,1,1}-{3409,3538,0,1,3}-{3421,3559,0,1,4}-{3413,3559,0,1,6}-{3433,3574,0,1,3}-{3428,3571,0,1,6}-" + }, + { + "npc_id": "1658", + "loc_data": "{2595,3087,1,1,1}-" + }, + { + "npc_id": "1665", + "loc_data": "{3544,3462,0,0,1}-" + }, + { + "npc_id": "1668", + "loc_data": "{3551,3550,0,1,0}-" + }, + { + "npc_id": "1669", + "loc_data": "{3549,3555,2,0,3}-" + }, + { + "npc_id": "1671", + "loc_data": "{3547,3555,2,0,6}-" + }, + { + "npc_id": "1672", + "loc_data": "{3552,3550,0,1,0}-" + }, + { + "npc_id": "1675", + "loc_data": "{3551,3561,0,1,0}-" + }, + { + "npc_id": "1676", + "loc_data": "{3481,9942,0,1,0}-{3493,9925,0,1,0}-{3525,9932,0,1,0}-{3555,9927,0,1,0}-{3554,9947,0,1,0}-{3529,9968,0,1,0}-" + }, + { + "npc_id": "1677", + "loc_data": "{3474,9933,0,1,0}-{3488,9934,0,1,0}-{3547,9932,0,1,0}-{3540,9958,0,1,0}-{3564,9959,0,1,0}-" + }, + { + "npc_id": "1678", + "loc_data": "{3473,9943,0,1,0}-{3488,9944,0,1,0}-{3498,9937,0,1,0}-{3534,9926,0,1,0}-{3553,9941,0,1,0}-{3548,9956,0,1,0}-{3564,9949,0,1,0}-" + }, + { + "npc_id": "1679", + "loc_data": "{2291,3145,0,1,2}-" + }, + { + "npc_id": "1680", + "loc_data": "{2290,3143,0,1,3}-" + }, + { + "npc_id": "1681", + "loc_data": "{3202,5483,0,1,4}-{2544,9843,0,1,3}-" + }, + { + "npc_id": "1683", + "loc_data": "{3678,3511,0,1,4}-" + }, + { + "npc_id": "1684", + "loc_data": "{3660,3517,0,1,7}-" + }, + { + "npc_id": "1685", + "loc_data": "{3659,3497,0,1,0}-" + }, + { + "npc_id": "1686", + "loc_data": "{3657,3516,0,1,3}-{3654,3518,1,1,6}-{3663,3522,0,1,7}-" + }, + { + "npc_id": "1688", + "loc_data": "{3709,3497,0,0,3}-" + }, + { + "npc_id": "1691", + "loc_data": "{3624,3530,0,1,1}-{3623,3524,0,1,2}-{3618,3526,0,1,6}-{3612,3527,0,1,6}-{3609,3527,0,1,4}-" + }, + { + "npc_id": "1692", + "loc_data": "{3632,3528,0,1,5}-{3633,3525,0,1,6}-{3631,3529,0,1,3}-{3631,3529,0,1,2}-{3628,3530,0,1,1}-{3631,3530,0,1,4}-{3629,3529,0,1,4}-" + }, + { + "npc_id": "1694", + "loc_data": "{3673,3491,0,1,3}-" + }, + { + "npc_id": "1695", + "loc_data": "{3461,3558,0,0,3}-" + }, + { + "npc_id": "1697", + "loc_data": "{3662,3502,0,1,4}-{3664,3493,0,1,6}-{3672,3486,0,1,2}-{3685,3485,0,1,3}-{3684,3496,0,1,3}-{3675,3502,0,1,3}-{3667,3484,0,1,0}-{3666,3471,0,1,4}-{3676,3464,0,1,3}-{3683,3467,0,1,6}-{3685,3474,0,1,4}-{3690,3474,0,1,1}-{3695,3473,0,1,3}-{3693,3466,0,1,7}-{3698,3463,0,1,3}-{3688,3467,0,1,3}-{3675,3474,0,1,4}-{3665,3476,0,1,6}-{3662,3491,0,1,1}-{3662,3495,0,1,4}-{3661,3501,0,1,6}-{3682,3486,0,1,4}-{3678,3493,0,1,4}-{3673,3491,0,1,3}-{3658,3502,0,1,4}-{3660,3505,0,1,1}-{3665,3469,0,1,6}-{3659,3465,0,1,6}-{3667,3461,0,1,1}-" + }, + { + "npc_id": "1698", + "loc_data": "{3647,3473,0,1,3}-{3649,3503,0,1,2}-{3665,3529,0,1,4}-{3669,3522,0,1,4}-{3672,3529,0,1,4}-{3668,3534,0,1,4}-{3657,3534,0,1,4}-{3654,3537,0,1,4}-" + }, + { + "npc_id": "1699", + "loc_data": "{3659,3480,0,1,3}-" + }, + { + "npc_id": "1700", + "loc_data": "{3681,3493,0,1,5}-" + }, + { + "npc_id": "1702", + "loc_data": "{3690,3464,0,0,1}-{3691,3464,0,0,1}-{3688,3464,0,0,1}-{3687,3464,0,0,1}-" + }, + { + "npc_id": "1703", + "loc_data": "{3697,3496,0,1,3}-{3699,3497,0,1,2}-{3689,3503,0,1,3}-{3690,3508,0,1,6}-{3690,3512,0,1,6}-{3689,3517,0,1,1}-{3690,3518,0,1,5}-{3689,3503,0,1,3}-{3689,3496,0,1,0}-{3690,3524,0,1,6}-{3689,3528,0,1,5}-" + }, + { + "npc_id": "1704", + "loc_data": "{3703,3487,0,0,3}-" + }, + { + "npc_id": "1706", + "loc_data": "{3661,3508,0,0,1}-{3658,3508,0,0,1}-{3652,3487,0,0,3}-{3652,3484,0,0,3}-" + }, + { + "npc_id": "1710", + "loc_data": "{3165,9631,0,1,6}-{3165,9633,0,1,0}-{3160,9634,0,1,7}-{3156,9630,0,1,6}-{3152,9627,0,1,4}-{3148,9621,0,1,4}-{3175,9630,0,1,1}-{3174,9634,0,1,3}-{3172,9638,0,1,0}-" + }, + { + "npc_id": "1711", + "loc_data": "{2566,5197,0,1,4}-{3160,9638,0,1,1}-{3159,9633,0,1,6}-{3161,9626,0,1,6}-{3169,9626,0,1,4}-{3171,9634,0,1,4}-{3164,9634,0,1,3}-{3165,9631,0,1,7}-{3180,9631,0,1,7}-{3183,9629,0,1,6}-{3182,9633,0,1,1}-{3172,9632,0,1,4}-{3158,9631,0,1,1}-{3160,9630,0,1,1}-{3159,9633,0,1,4}-{3150,9623,0,1,6}-{3152,9620,0,1,6}-{3159,9622,0,1,0}-{3169,9623,0,1,6}-{3169,9623,0,1,4}-" + }, + { + "npc_id": "1712", + "loc_data": "{2573,5201,0,1,4}-{2577,5195,0,1,4}-{2577,5189,0,0,6}-{2571,5195,0,0,6}-{3153,9646,0,1,3}-{3151,9651,0,1,1}-" + }, + { + "npc_id": "1714", + "loc_data": "{3172,9624,0,1,2}-{3161,9623,0,1,1}-{3151,9624,0,1,1}-{3150,9622,0,1,4}-{3153,9627,0,1,3}-{3157,9634,0,1,2}-{3171,9636,0,1,6}-{3174,9639,0,1,3}-{3174,9634,0,1,3}-" + }, + { + "npc_id": "1715", + "loc_data": "{3171,9635,0,1,3}-{3159,9636,0,1,2}-{3169,9630,0,1,3}-{3172,9625,0,1,0}-{3159,9627,0,1,3}-" + }, + { + "npc_id": "1752", + "loc_data": "{2437,3442,0,1,0}-{2449,3421,0,1,0}-{2457,3394,0,1,0}-{2464,3394,0,1,0}-{2480,3406,0,1,0}-{2432,3387,0,1,0}-{2442,3388,0,1,0}-{2453,3363,0,1,0}-{2463,3375,0,1,0}-{2381,3428,0,1,0}-{2392,3405,0,1,0}-{2413,3397,0,1,0}-{2415,3408,0,1,0}-{2463,3456,0,1,0}-{2468,3456,0,1,0}-" + }, + { + "npc_id": "1754", + "loc_data": "{3100,3246,0,1,2}-{3131,3263,0,1,5}-{3122,3278,0,1,2}-{3259,3308,0,1,4}-" + }, + { + "npc_id": "1755", + "loc_data": "{3106,3275,0,1,1}-{3106,3266,0,1,3}-{3114,3273,0,1,4}-{3258,3312,0,1,3}-" + }, + { + "npc_id": "1756", + "loc_data": "{3096,3251,0,1,3}-{3102,3261,0,1,1}-{3117,3278,0,1,0}-{3262,3320,0,1,1}-" + }, + { + "npc_id": "1757", + "loc_data": "{3233,3308,0,1,4}-" + }, + { + "npc_id": "1758", + "loc_data": "{2895,3403,0,0,0}-{3262,3325,0,0,0}-" + }, + { + "npc_id": "1759", + "loc_data": "{3250,3310,0,0,0}-" + }, + { + "npc_id": "1761", + "loc_data": "{3121,3274,0,0,0}-" + }, + { + "npc_id": "1765", + "loc_data": "{3198,3270,0,1,0}-{2923,3320,0,1,7}-{2921,3320,0,1,4}-{2923,3320,0,1,5}-{3206,3265,0,1,4}-{3201,3265,0,1,0}-" + }, + { + "npc_id": "1766", + "loc_data": "{3171,3320,0,1,0}-{3259,3262,0,1,4}-{3262,3274,0,1,3}-{3259,3278,0,1,1}-{3263,3273,0,1,7}-" + }, + { + "npc_id": "1767", + "loc_data": "{2924,3288,0,0,1}-{2921,3290,0,1,1}-{2926,3279,0,1,1}-{2931,3272,0,1,1}-{2936,3273,0,1,6}-{3262,3262,0,1,6}-{3025,3311,0,1,5}-" + }, + { + "npc_id": "1769", + "loc_data": "{2596,9822,0,1,4}-{2979,3203,0,1,4}-{3264,3249,0,1,4}-" + }, + { + "npc_id": "1770", + "loc_data": "{2595,9826,0,1,1}-{3189,3246,0,1,0}-{3143,3231,0,1,0}-{3140,3263,0,1,0}-{3262,3253,0,1,6}-{3259,3254,0,1,3}-{2999,3212,0,1,1}-" + }, + { + "npc_id": "1771", + "loc_data": "{3192,3245,0,1,0}-{3184,3248,0,1,0}-{3140,3230,0,1,0}-{3141,3261,0,1,0}-{3187,3286,0,1,0}-{3174,3294,0,1,0}-{3178,3294,0,1,0}-{3144,3302,0,1,0}-{3142,3303,0,1,0}-{3151,3300,0,1,0}-{3139,3299,0,1,0}-{2993,3199,0,1,6}-{3248,3233,0,1,6}-{3247,3240,0,1,3}-{3209,3277,0,1,0}-" + }, + { + "npc_id": "1772", + "loc_data": "{3194,3255,0,1,0}-{3143,3234,0,1,0}-{3251,3231,0,1,1}-{3260,3241,0,1,0}-{3259,3222,0,0,4}-{2993,3203,0,1,0}-" + }, + { + "npc_id": "1773", + "loc_data": "{3252,3227,0,1,1}-{3263,3219,0,1,0}-{2991,3219,0,1,1}-" + }, + { + "npc_id": "1774", + "loc_data": "{2592,9834,0,1,6}-{3255,3228,0,1,4}-{3265,3219,0,1,2}-{3012,3204,0,1,3}-" + }, + { + "npc_id": "1775", + "loc_data": "{2585,9829,0,1,1}-{3254,3224,0,1,1}-{3010,3211,0,1,6}-" + }, + { + "npc_id": "1776", + "loc_data": "{2999,3216,0,1,6}-{3264,3247,0,1,2}-" + }, + { + "npc_id": "1778", + "loc_data": "{3260,3859,0,0,0}-" + }, + { + "npc_id": "1779", + "loc_data": "{2978,3752,0,1,6}-" + }, + { + "npc_id": "1780", + "loc_data": "{3272,3687,0,1,3}-" + }, + { + "npc_id": "1781", + "loc_data": "{3008,3862,0,0,0}-" + }, + { + "npc_id": "1782", + "loc_data": "{3363,3883,0,1,4}-" + }, + { + "npc_id": "1783", + "loc_data": "{3079,3516,0,1,6}-" + }, + { + "npc_id": "1784", + "loc_data": "{3025,3705,0,1,1}-" + }, + { + "npc_id": "1785", + "loc_data": "{3144,3788,0,1,6}-" + }, + { + "npc_id": "1786", + "loc_data": "{3234,3633,0,1,1}-" + }, + { + "npc_id": "1787", + "loc_data": "{3074,3609,0,1,3}-" + }, + { + "npc_id": "1795", + "loc_data": "{2967,9811,0,0,0}-" + }, + { + "npc_id": "1796", + "loc_data": "{2968,9809,0,0,0}-" + }, + { + "npc_id": "1798", + "loc_data": "{2701,3471,0,0,0}-" + }, + { + "npc_id": "1805", + "loc_data": "{2760,3660,0,1,6}-" + }, + { + "npc_id": "1806", + "loc_data": "{2798,3667,0,1,3}-" + }, + { + "npc_id": "1807", + "loc_data": "{2811,3673,0,1,3}-" + }, + { + "npc_id": "1808", + "loc_data": "{2765,3676,0,1,3}-" + }, + { + "npc_id": "1810", + "loc_data": "{2811,3681,0,1,3}-" + }, + { + "npc_id": "1814", + "loc_data": "{2794,3668,0,1,0}-" + }, + { + "npc_id": "1815", + "loc_data": "{2801,3669,0,1,0}-" + }, + { + "npc_id": "1816", + "loc_data": "{2803,3668,0,1,0}-" + }, + { + "npc_id": "1817", + "loc_data": "{2797,3672,0,1,0}-" + }, + { + "npc_id": "1818", + "loc_data": "{2802,3674,0,1,0}-" + }, + { + "npc_id": "1819", + "loc_data": "{2813,3687,0,1,0}-" + }, + { + "npc_id": "1820", + "loc_data": "{2812,3685,0,1,0}-" + }, + { + "npc_id": "1821", + "loc_data": "{2757,3674,0,1,0}-{2762,3671,0,1,0}-{2785,3658,0,1,0}-" + }, + { + "npc_id": "1828", + "loc_data": "{3231,9545,0,1,6}-" + }, + { + "npc_id": "1829", + "loc_data": "{3153,9548,0,1,1}-{3154,9547,0,1,4}-{3176,9546,0,1,4}-{3221,9558,0,1,4}-{3226,9548,0,1,7}-{3224,9551,0,1,1}-{3219,9558,0,1,7}-" + }, + { + "npc_id": "1831", + "loc_data": "{3165,9542,0,1,3}-{3164,9542,0,1,3}-{3166,9542,0,1,3}-{3208,9555,0,1,1}-{3211,9570,0,1,5}-{3211,9570,0,1,5}-{3208,9555,0,1,1}-{3208,9555,0,1,1}-{3207,9555,0,1,1}-{3213,9570,0,1,5}-" + }, + { + "npc_id": "1832", + "loc_data": "{3150,9573,0,1,1}-{3188,9550,0,1,0}-{3148,9578,0,1,4}-{3152,9556,0,1,3}-{3150,9553,0,1,2}-{3167,9547,0,1,1}-{3168,9546,0,1,3}-{3184,9551,0,1,3}-{3191,9583,0,1,4}-{3187,9583,0,1,3}-{3220,9573,0,1,4}-{3224,9574,0,1,1}-{3208,9588,0,1,6}-{3210,9585,0,1,4}-{3272,5549,0,1,0}-{3275,5546,0,1,0}-{3281,5545,0,1,2}-{3286,5544,0,1,0}-{3285,5539,0,1,3}-{3268,5553,0,1,1}-{3274,5558,0,1,6}-{3281,5557,0,1,4}-{3282,5554,0,1,4}-{3269,5551,0,1,3}-{3287,5549,0,1,3}-{3279,5546,0,1,6}-{3283,5545,0,1,0}-{3269,5548,0,1,1}-" + }, + { + "npc_id": "1833", + "loc_data": "{3151,9575,0,1,3}-{3150,9577,0,1,4}-{3148,9554,0,1,6}-{3165,9547,0,1,1}-{3165,9546,0,1,2}-{3184,9551,0,1,3}-{3189,9581,0,1,4}-{3222,9575,0,1,4}-{3226,9576,0,1,3}-{3210,9587,0,1,2}-" + }, + { + "npc_id": "1834", + "loc_data": "{3169,3174,0,0,6}-" + }, + { + "npc_id": "1839", + "loc_data": "{2825,10167,0,1,0}-" + }, + { + "npc_id": "1841", + "loc_data": "{3020,3452,0,0,0}-" + }, + { + "npc_id": "1843", + "loc_data": "{2839,10128,0,1,0}-" + }, + { + "npc_id": "1844", + "loc_data": "{2855,10144,0,1,0}-" + }, + { + "npc_id": "1846", + "loc_data": "{2873,10166,0,1,3}-" + }, + { + "npc_id": "1847", + "loc_data": "{2868,10168,0,1,0}-" + }, + { + "npc_id": "1848", + "loc_data": "{2868,10168,0,1,0}-" + }, + { + "npc_id": "1849", + "loc_data": "{2868,10168,0,1,0}-" + }, + { + "npc_id": "1860", + "loc_data": "{2957,3203,0,1,3}-" + }, + { + "npc_id": "1861", + "loc_data": "{3208,3256,0,0,1}-" + }, + { + "npc_id": "1862", + "loc_data": "{3304,3211,0,1,1}-" + }, + { + "npc_id": "1863", + "loc_data": "{3358,2956,0,0,6}-" + }, + { + "npc_id": "1864", + "loc_data": "{3363,2956,0,0,3}-" + }, + { + "npc_id": "1865", + "loc_data": "{3352,2974,0,1,4}-" + }, + { + "npc_id": "1866", + "loc_data": "{3360,2983,0,1,4}-" + }, + { + "npc_id": "1867", + "loc_data": "{3347,2966,0,0,6}-" + }, + { + "npc_id": "1870", + "loc_data": "{3373,2972,0,1,5}-" + }, + { + "npc_id": "1871", + "loc_data": "{3344,2986,0,1,3}-" + }, + { + "npc_id": "1872", + "loc_data": "{3354,2953,0,0,6}-" + }, + { + "npc_id": "1873", + "loc_data": "{3343,2962,0,1,0}-{3343,2964,0,1,1}-" + }, + { + "npc_id": "1874", + "loc_data": "{3371,9301,0,1,0}-{3371,9303,0,1,0}-{3371,9305,0,1,0}-{3371,9307,0,1,0}-{3371,9309,0,1,0}-{3373,9301,0,1,0}-{3373,9303,0,1,0}-{3373,9306,0,1,0}-{3373,9308,0,1,0}-{3375,9301,0,1,0}-{3375,9303,0,1,0}-{3375,9305,0,1,0}-{3375,9307,0,1,0}-{3375,9309,0,1,0}-{3403,2963,0,1,0}-{3429,2976,0,1,0}-{3328,2952,0,1,0}-{3328,2957,0,1,0}-{3331,2955,0,1,0}-{3331,2961,0,1,0}-{3266,2955,0,1,0}-{3271,2967,0,1,0}-{3279,2957,0,1,0}-{3280,2975,0,1,0}-{3284,2959,0,1,0}-{3294,2964,0,1,0}-{3295,2978,0,1,0}-{3305,2966,0,1,0}-{3307,2959,0,1,0}-{3309,2973,0,1,0}-{3396,3029,0,1,0}-{3397,3044,0,1,0}-{3398,3038,0,1,0}-" + }, + { + "npc_id": "1875", + "loc_data": "{3354,2952,0,0,1}-" + }, + { + "npc_id": "1884", + "loc_data": "{2811,3174,0,1,0}-" + }, + { + "npc_id": "1902", + "loc_data": "{3333,2946,0,0,1}-" + }, + { + "npc_id": "1905", + "loc_data": "{3335,2948,0,1,2}-{3331,2948,0,1,6}-{3333,2950,0,1,0}-" + }, + { + "npc_id": "1907", + "loc_data": "{3488,3091,0,1,0}-" + }, + { + "npc_id": "1911", + "loc_data": "{3416,3155,0,1,0}-" + }, + { + "npc_id": "1912", + "loc_data": "{3376,3429,0,1,6}-" + }, + { + "npc_id": "1916", + "loc_data": "{3112,9690,0,0,7}-" + }, + { + "npc_id": "1917", + "loc_data": "{3177,2987,0,1,6}-" + }, + { + "npc_id": "1918", + "loc_data": "{3180,3043,0,1,2}-" + }, + { + "npc_id": "1920", + "loc_data": "{3497,3478,0,0,0}-" + }, + { + "npc_id": "1921", + "loc_data": "{3159,2980,0,1,1}-" + }, + { + "npc_id": "1923", + "loc_data": "{3185,2983,0,1,4}-" + }, + { + "npc_id": "1924", + "loc_data": "{3213,2956,0,1,1}-" + }, + { + "npc_id": "1926", + "loc_data": "{3179,2967,0,1,3}-{3172,2966,0,1,1}-{3171,2980,0,1,3}-{3166,2972,0,1,0}-{3181,2979,0,1,3}-{3187,2976,0,1,7}-{3174,2984,0,1,3}-{3183,2982,0,1,4}-{3187,2985,0,1,1}-{3182,2988,0,1,5}-{3188,2990,0,1,2}-{3172,2992,0,1,4}-{3171,2987,0,1,4}-{3161,2982,0,1,2}-{3161,2986,0,1,3}-{3159,2987,0,1,3}-{3163,2976,0,1,4}-{3161,2977,0,1,4}-{3161,2979,0,1,6}-{3162,2982,0,1,6}-{3164,2985,0,1,2}-{3158,2970,0,1,3}-{3155,2979,0,1,4}-{3167,2972,0,1,6}-{3172,2973,0,1,5}-{3175,2973,0,1,4}-{3185,2967,0,1,2}-" + }, + { + "npc_id": "1927", + "loc_data": "{3160,2979,0,0,5}-{3162,2989,0,0,1}-" + }, + { + "npc_id": "1928", + "loc_data": "{3161,2977,0,0,4}-{3161,2987,0,0,1}-" + }, + { + "npc_id": "1929", + "loc_data": "{3158,2987,0,0,3}-" + }, + { + "npc_id": "1930", + "loc_data": "{3161,2985,0,0,6}-{3161,2983,0,0,6}-{3161,2982,0,0,6}-{3161,2981,0,0,6}-{3161,2984,0,0,6}-" + }, + { + "npc_id": "1932", + "loc_data": "{2836,3740,0,0,6}-" + }, + { + "npc_id": "1935", + "loc_data": "{2841,3738,0,0,3}-" + }, + { + "npc_id": "1936", + "loc_data": "{2852,3735,0,1,0}-{2855,3729,0,1,0}-{2861,3725,0,1,0}-" + }, + { + "npc_id": "1937", + "loc_data": "{2850,3732,0,1,0}-{2857,3726,0,1,0}-{2865,3729,0,1,0}-" + }, + { + "npc_id": "1938", + "loc_data": "{2849,3735,0,1,0}-{2853,3731,0,1,0}-{2859,3728,0,1,0}-" + }, + { + "npc_id": "1939", + "loc_data": "{2856,3728,0,1,0}-{2862,3722,0,1,0}-{2864,3723,0,1,0}-" + }, + { + "npc_id": "1940", + "loc_data": "{2853,3728,0,1,0}-{2856,3732,0,1,0}-{2863,3720,0,1,0}-" + }, + { + "npc_id": "1941", + "loc_data": "{2854,3725,0,1,0}-{2862,3728,0,1,0}-{2862,3731,0,1,0}-" + }, + { + "npc_id": "1942", + "loc_data": "{2855,3735,0,1,0}-{2858,3730,0,1,0}-{2865,3726,0,1,0}-" + }, + { + "npc_id": "1943", + "loc_data": "{2825,3807,2,0,1}-" + }, + { + "npc_id": "1945", + "loc_data": "{2825,3811,2,0,6}-" + }, + { + "npc_id": "1947", + "loc_data": "{2835,3740,0,0,6}-" + }, + { + "npc_id": "1949", + "loc_data": "{2837,3740,0,0,6}-" + }, + { + "npc_id": "1951", + "loc_data": "{2886,3723,0,1,3}-{2887,3720,0,1,4}-{2890,3721,0,1,7}-{2890,3724,0,1,1}-{2909,3736,0,1,5}-{2910,3736,0,1,2}-{2891,3724,0,1,7}-" + }, + { + "npc_id": "1952", + "loc_data": "{2892,3726,0,1,0}-{2894,3726,0,1,6}-{2895,3728,0,1,0}-{2895,3730,0,1,5}-{2922,3755,0,1,3}-{2893,3725,0,1,2}-{2894,3727,0,1,6}-{2895,3725,0,1,3}-{2898,3735,0,1,6}-" + }, + { + "npc_id": "1953", + "loc_data": "{2897,3733,0,1,5}-{2897,3737,0,1,5}-{2913,3736,0,1,3}-{2897,3737,0,1,6}-{2915,3740,0,1,1}-{2894,3742,0,1,0}-" + }, + { + "npc_id": "1954", + "loc_data": "{2895,3751,0,1,1}-{2895,3755,0,1,6}-{2898,3751,0,1,3}-{2898,3755,0,1,6}-{2930,3765,0,1,5}-{2893,3748,0,1,5}-{2896,3749,0,1,1}-{2929,3762,0,1,3}-" + }, + { + "npc_id": "1955", + "loc_data": "{2895,3740,0,1,1}-{2895,3744,0,1,3}-{2898,3740,0,1,6}-{2898,3744,0,1,1}-{2908,3739,0,1,0}-{2928,3763,0,1,3}-{2899,3737,0,1,2}-{2897,3739,0,1,6}-{2912,3742,0,1,2}-{2898,3750,0,1,3}-{2895,3751,0,1,4}-" + }, + { + "npc_id": "1956", + "loc_data": "{2886,3758,0,1,6}-{2886,3762,0,1,3}-{2890,3756,0,1,4}-{2890,3762,0,1,1}-{2928,3753,0,1,2}-{2926,3753,0,1,6}-{2895,3754,0,1,3}-" + }, + { + "npc_id": "1958", + "loc_data": "{3147,5467,0,1,1}-{3144,5466,0,1,2}-{3147,5479,0,1,2}-{3144,5475,0,1,6}-{3161,5482,0,1,5}-{3147,5475,0,1,6}-{3240,9326,0,1,3}-{3209,9310,0,1,4}-{3245,9333,0,1,4}-{3213,9307,0,1,4}-{3221,9318,0,1,3}-{3229,9333,0,1,3}-{3216,9329,0,1,4}-{3208,9294,0,1,3}-{3201,9286,0,1,1}-{3212,9326,0,1,4}-{3217,9284,0,1,7}-{3226,9284,0,1,4}-{3232,9299,0,1,6}-{3242,9295,0,1,1}-{3220,9302,0,1,0}-{3238,9305,0,1,6}-{3220,9296,0,1,1}-{3246,9291,0,1,3}-{3240,9289,0,1,4}-{3237,9305,0,1,3}-{3257,9292,0,0,5}-{3246,9321,0,1,1}-{3261,9310,0,1,3}-{3258,9309,0,1,4}-{3251,9316,0,1,3}-{3247,9310,0,1,3}-" + }, + { + "npc_id": "1961", + "loc_data": "{3156,5477,0,1,5}-{3162,5479,0,1,4}-{3159,5477,0,1,6}-{3150,5474,0,1,3}-{3147,5480,0,1,1}-{3159,5484,0,1,3}-{2764,4944,1,1,0}-{2796,4976,1,1,0}-{2798,4950,1,1,0}-{2806,4939,1,1,0}-{2832,4959,2,1,0}-{3201,9293,0,1,0}-{3205,9303,0,1,0}-{3206,9328,0,1,0}-{3207,9310,0,1,0}-{3211,9284,0,1,0}-{3220,9289,0,1,0}-{3224,9334,0,1,0}-{3249,9286,0,1,0}-{3251,9303,0,1,0}-{3252,9327,0,1,0}-{3252,9332,0,1,0}-{3255,9315,0,1,0}-{3261,9296,0,1,0}-{3261,9306,0,1,0}-" + }, + { + "npc_id": "1962", + "loc_data": "{3168,5458,0,1,2}-{2900,4948,3,1,0}-{2762,4962,1,1,0}-{2763,4973,1,1,0}-{2780,4977,1,1,0}-{2787,4967,1,1,0}-{2796,4959,1,1,0}-{2838,4948,2,1,0}-{3205,9329,0,1,0}-{3210,9292,0,1,0}-{3221,9310,0,1,0}-{3225,9323,0,1,0}-{3243,9310,0,1,0}-{3246,9290,0,1,0}-{3255,9301,0,1,0}-{3255,9321,0,1,0}-{3261,9331,0,1,0}-" + }, + { + "npc_id": "1963", + "loc_data": "{3166,5465,0,1,7}-{3168,5462,0,1,0}-{3167,5467,0,1,1}-{3167,5467,0,1,7}-{2926,4965,3,1,0}-{2771,4947,1,1,0}-{2775,4963,1,1,0}-{2781,4948,1,1,0}-{2792,4942,1,1,0}-{2798,4954,1,1,0}-{2858,4964,2,1,0}-{3204,9309,0,1,0}-{3214,9333,0,1,0}-{3219,9297,0,1,0}-{3239,9300,0,1,0}-{3240,9286,0,1,0}-{3240,9330,0,1,0}-{3245,9306,0,1,0}-{3250,9316,0,1,0}-{3250,9317,0,1,0}-{3257,9290,0,1,0}-" + }, + { + "npc_id": "1964", + "loc_data": "{2761,4950,1,1,0}-{2765,4938,1,1,0}-{2770,4955,1,1,0}-{2772,4940,1,1,0}-{2777,4943,1,1,0}-{2782,4967,1,1,0}-{2797,4965,1,1,0}-{2799,4937,1,1,0}-{2799,4941,1,1,0}-{2807,4968,1,1,0}-{2808,4975,1,1,0}-{2809,4953,1,1,0}-{2864,4946,2,1,0}-{3202,9283,0,1,0}-{3206,9333,0,1,0}-{3209,9299,0,1,0}-{3219,9301,0,1,0}-{3226,9285,0,1,0}-{3227,9303,0,1,0}-{3228,9293,0,1,0}-{3229,9333,0,1,0}-{3237,9293,0,1,0}-{3246,9321,0,1,0}-{3256,9296,0,1,0}-{3260,9285,0,1,0}-{3262,9317,0,1,0}-" + }, + { + "npc_id": "1970", + "loc_data": "{3233,9317,0,1,1}-" + }, + { + "npc_id": "1972", + "loc_data": "{2536,3426,0,1,0}-" + }, + { + "npc_id": "1973", + "loc_data": "{2693,5075,0,1,0}-{2695,5089,0,1,0}-{2697,5096,0,1,0}-{2703,5064,0,1,0}-{2710,5105,0,1,0}-{2719,5078,0,1,0}-{2719,5112,0,1,0}-{2720,5096,0,1,0}-{2726,5086,0,1,0}-{2729,5096,0,1,0}-{2735,5061,0,1,0}-{2740,5069,0,1,0}-{2740,5085,0,1,0}-{2746,5092,0,1,0}-{2746,5114,0,1,0}-{2626,5065,0,1,0}-{2637,5099,0,1,0}-{2638,5058,0,1,0}-{2644,5090,0,1,0}-{2658,5082,0,1,0}-{2666,5097,0,1,0}-{2680,5074,0,1,0}-" + }, + { + "npc_id": "1976", + "loc_data": "{2694,5067,0,1,0}-{2717,5081,0,1,0}-{2718,5108,0,1,0}-{2721,5104,0,1,0}-{2726,5091,0,1,0}-{2731,5060,0,1,0}-{2732,5073,0,1,0}-{2740,5083,0,1,0}-{2742,5103,0,1,0}-{2747,5094,0,1,0}-{3315,5508,0,1,5}-{3308,5510,0,1,3}-{3304,5507,0,1,4}-{3299,5509,0,1,3}-{3317,5514,0,1,3}-{3319,5518,0,1,4}-{3320,5507,0,1,4}-{3324,5513,0,1,1}-{3283,5510,0,1,5}-{3320,5550,0,1,0}-{3313,5523,0,1,4}-{3310,5541,0,1,4}-{3308,5535,0,1,5}-{3301,5531,0,1,4}-{3315,5530,0,1,1}-{3322,5536,0,1,4}-{3320,5539,0,1,7}-{3311,5519,0,1,3}-{3289,5525,0,1,2}-{3300,5519,0,1,6}-{3289,5515,0,1,7}-{3287,5523,0,1,3}-" + }, + { + "npc_id": "1990", + "loc_data": "{3300,2797,0,0,6}-" + }, + { + "npc_id": "1993", + "loc_data": "{3264,2886,0,1,0}-{3267,2891,0,1,0}-{3268,2881,0,1,0}-{3269,2885,0,1,0}-{3296,2912,0,1,0}-{3297,2919,0,1,0}-{3301,2920,0,1,0}-{3308,2916,0,1,0}-{3258,2868,0,1,0}-{3259,2823,0,1,0}-{3259,2845,0,1,0}-{3260,2830,0,1,0}-{3260,2859,0,1,0}-{3261,2819,0,1,0}-{3261,2851,0,1,0}-{3337,2922,0,1,0}-{3343,2931,0,1,0}-{3349,2922,0,1,0}-{3351,2927,0,1,0}-{3357,2922,0,1,0}-{3359,2927,0,1,0}-{3364,2937,0,1,0}-{3268,2854,0,1,0}-{3269,2827,0,1,0}-{3269,2866,0,1,0}-{3269,2875,0,1,0}-{3270,2818,0,1,0}-{3272,2841,0,1,0}-{3276,2842,0,1,0}-{3282,2839,0,1,0}-{3290,2847,0,1,0}-" + }, + { + "npc_id": "1994", + "loc_data": "{3265,2931,0,1,0}-{3265,2935,0,1,0}-{3268,2932,0,1,0}-{3268,2935,0,1,0}-{3316,2900,0,1,0}-{3319,2897,0,1,0}-{3320,2901,0,1,0}-{3321,2899,0,1,0}-{3212,2863,0,1,0}-{3213,2866,0,1,0}-{3215,2863,0,1,0}-{3216,2865,0,1,0}-{3216,2868,0,1,0}-{3218,2831,0,1,0}-{3220,2830,0,1,0}-{3220,2833,0,1,0}-{3221,2831,0,1,0}-{3238,2845,0,1,0}-{3240,2845,0,1,0}-{3241,2843,0,1,0}-{3241,2847,0,1,0}-{3400,2997,0,1,0}-{3402,2999,0,1,0}-{3403,2997,0,1,0}-{3445,2993,0,1,0}-{3446,2992,0,1,0}-{3448,2991,0,1,0}-{3448,2994,0,1,0}-{3329,2933,0,1,0}-{3330,2931,0,1,0}-{3331,2933,0,1,0}-{3343,2895,0,1,0}-{3345,2896,0,1,0}-{3346,2894,0,1,0}-{3348,2894,0,1,0}-{3376,2934,0,1,0}-{3378,2933,0,1,0}-{3378,2935,0,1,0}-{3381,2907,0,1,0}-{3383,2905,0,1,0}-{3383,2908,0,1,0}-{3384,2907,0,1,0}-{3306,2817,0,1,0}-{3308,2818,0,1,0}-{3309,2816,0,1,0}-{3312,2817,0,1,0}-{3314,2861,0,1,0}-{3319,2873,0,1,0}-{3321,2871,0,1,0}-{3324,2870,0,1,0}-{3327,2858,0,1,0}-{3406,3014,0,1,0}-{3408,3013,0,1,0}-{3408,3016,0,1,0}-{3410,3015,0,1,0}-" + }, + { + "npc_id": "1995", + "loc_data": "{3309,2806,0,1,0}-{3312,2806,0,1,0}-{3314,2752,0,1,0}-{3314,2806,0,1,0}-{3315,2805,0,1,0}-{3316,2780,0,1,0}-{3316,2795,0,1,0}-{3317,2752,0,1,0}-{3317,2762,0,1,0}-{3317,2763,0,1,0}-{3317,2779,0,1,0}-{3317,2794,0,1,0}-{3318,2761,0,1,0}-{3318,2778,0,1,0}-{3318,2781,0,1,0}-{3318,2794,0,1,0}-{3318,2795,0,1,0}-{3319,2760,0,1,0}-{3319,2763,0,1,0}-" + }, + { + "npc_id": "1997", + "loc_data": "{3272,2802,0,1,0}-{3273,2802,0,1,0}-{3273,2805,0,1,0}-{3274,2798,0,1,0}-{3274,2799,0,1,0}-{3274,2802,0,1,0}-{3274,2804,0,1,0}-{3275,2795,0,1,0}-{3275,2796,0,1,0}-{3275,2798,0,1,0}-{3277,2752,0,1,0}-{3277,2753,0,1,0}-{3277,2756,0,1,0}-{3277,2757,0,1,0}-{3278,2752,0,1,0}-{3278,2753,0,1,0}-{3278,2754,0,1,0}-{3278,2755,0,1,0}-" + }, + { + "npc_id": "1998", + "loc_data": "{3275,2803,0,1,0}-" + }, + { + "npc_id": "1999", + "loc_data": "{3278,2804,0,1,0}-" + }, + { + "npc_id": "2000", + "loc_data": "{3277,2802,0,1,0}-" + }, + { + "npc_id": "2002", + "loc_data": "{3315,2849,0,1,0}-" + }, + { + "npc_id": "2003", + "loc_data": "{3304,9196,0,1,0}-" + }, + { + "npc_id": "2004", + "loc_data": "{3304,9195,0,1,0}-" + }, + { + "npc_id": "2014", + "loc_data": "{3293,2788,0,1,0}-" + }, + { + "npc_id": "2020", + "loc_data": "{3503,3477,0,0,0}-" + }, + { + "npc_id": "2021", + "loc_data": "{3224,9516,2,1,0}-{3224,9517,2,1,0}-{3224,9518,2,1,0}-{3225,9516,2,1,0}-{3225,9517,2,1,0}-{3225,9518,2,1,0}-{3226,9516,2,1,0}-{3226,9517,2,1,0}-{3226,9518,2,1,0}-" + }, + { + "npc_id": "2031", + "loc_data": "{3290,5448,0,1,6}-{3291,5452,0,1,1}-{3293,5456,0,1,6}-{3551,9680,0,0,2}-{3553,9679,0,0,1}-{3551,9675,0,0,6}-{3554,9676,0,0,7}-{3548,9676,0,0,5}-{3552,9691,0,0,2}-{3569,9681,0,0,7}-{3577,9711,0,0,5}-{3567,9675,0,0,5}-{3567,9675,0,0,5}-{3570,9678,0,0,2}-{3568,9686,0,0,1}-{3545,9721,0,0,7}-{3560,9712,0,0,6}-{3552,9685,0,0,1}-{3525,9698,0,0,6}-{3538,9668,0,0,4}-" + }, + { + "npc_id": "2032", + "loc_data": "{3187,5513,0,1,3}-{3186,5510,0,1,6}-{3186,5516,0,1,6}-{3194,5511,0,1,1}-{3185,5514,0,1,5}-{3549,9678,0,0,0}-{3569,9676,0,0,5}-{3566,9678,0,0,1}-{3560,9678,0,0,2}-{3526,9678,0,0,2}-{3532,9693,0,0,5}-{3534,9690,0,0,7}-{3536,9695,0,0,2}-{3542,9694,0,0,7}-{3548,9695,0,0,7}-{3556,9695,0,0,5}-{3554,9709,0,0,2}-{3533,9708,0,0,5}-{3534,9703,0,0,5}-{3538,9721,0,0,7}-{3567,9720,0,0,6}-{3561,9711,0,0,7}-{3552,9703,0,0,1}-{3551,9698,0,0,1}-{3532,9678,0,0,5}-{3531,9675,0,0,5}-{3537,9677,0,0,2}-" + }, + { + "npc_id": "2033", + "loc_data": "{3188,5511,0,1,7}-{3190,5511,0,1,6}-{3300,5494,0,1,2}-{3285,5492,0,1,6}-{3285,5495,0,1,0}-{3288,5497,0,1,3}-{3268,5487,0,0,0}-{3533,9691,0,0,4}-{3537,9694,0,0,2}-{3533,9696,0,0,2}-{3533,9693,0,0,5}-" + }, + { + "npc_id": "2034", + "loc_data": "{3288,5484,0,1,4}-{3288,5467,0,1,0}-{3293,5468,0,1,2}-{3296,5475,0,1,7}-{3296,5473,0,1,2}-{3297,5480,0,1,4}-{3565,9695,0,0,1}-{3566,9692,0,0,5}-{3572,9695,0,0,7}-" + }, + { + "npc_id": "2035", + "loc_data": "{3569,9696,0,0,2}-{3569,9693,0,0,6}-{3566,9694,0,0,6}-{3567,9698,0,0,2}-{3572,9692,0,0,5}-" + }, + { + "npc_id": "2036", + "loc_data": "{3569,9674,0,0,0}-{3561,9677,0,0,6}-{3535,9686,0,0,6}-{3535,9698,0,0,1}-{3576,9677,0,0,3}-{3577,9679,0,0,1}-{3568,9691,0,0,2}-{3560,9694,0,0,6}-{3570,9682,0,0,1}-{3569,9687,0,0,2}-{3550,9711,0,0,5}-{3551,9708,0,0,6}-{3548,9713,0,0,6}-{3537,9711,0,0,4}-{3535,9702,0,0,7}-{3553,9722,0,0,4}-{3567,9712,0,0,5}-{3569,9704,0,0,6}-{3579,9693,0,0,7}-{3534,9675,0,0,2}-{3526,9711,0,0,1}-{3566,9668,0,0,4}-" + }, + { + "npc_id": "2037", + "loc_data": "{3543,9677,0,0,3}-{3572,9680,0,0,7}-{3559,9677,0,0,4}-{3535,9685,0,0,1}-{3537,9693,0,0,1}-{3570,9697,0,0,2}-{3552,9713,0,0,6}-{3553,9711,0,0,3}-{3567,9708,0,0,6}-{3535,9679,0,0,1}-{3525,9683,0,0,6}-" + }, + { + "npc_id": "2038", + "loc_data": "{2443,3051,0,0,1}-" + }, + { + "npc_id": "2039", + "loc_data": "{2442,3049,0,0,3}-" + }, + { + "npc_id": "2040", + "loc_data": "{2444,3047,0,0,0}-" + }, + { + "npc_id": "2041", + "loc_data": "{2447,3050,0,0,0}-" + }, + { + "npc_id": "2042", + "loc_data": "{2454,3047,0,0,2}-" + }, + { + "npc_id": "2043", + "loc_data": "{2443,3038,0,1,1}-{2452,3030,0,1,1}-" + }, + { + "npc_id": "2044", + "loc_data": "{2486,3048,0,1,3}-{2484,9392,2,1,0}-{2465,9454,2,1,0}-{2471,9422,2,1,0}-{2448,9442,2,1,0}-" + }, + { + "npc_id": "2045", + "loc_data": "{2482,3046,0,1,3}-{2459,9394,2,1,0}-{2473,9430,2,1,0}-{2478,9442,2,1,0}-{2487,9455,2,1,0}-" + }, + { + "npc_id": "2046", + "loc_data": "{2466,9389,2,1,0}-{2449,9429,0,1,0}-{2436,9452,2,1,0}-{2436,9465,2,1,0}-{2450,9460,2,1,0}-{2455,9440,2,1,0}-{2473,9439,2,1,0}-{2483,9408,2,1,0}-" + }, + { + "npc_id": "2047", + "loc_data": "{2480,3046,0,1,3}-{2477,9384,2,1,0}-{2449,9434,0,1,0}-{2437,9429,2,1,0}-{2440,9438,2,1,0}-{2458,9408,2,1,0}-" + }, + { + "npc_id": "2048", + "loc_data": "{2485,9398,2,1,0}-{2455,9435,0,1,0}-{2457,9420,2,1,0}-{2462,9431,2,1,0}-{2482,9422,2,1,0}-" + }, + { + "npc_id": "2049", + "loc_data": "{2452,9440,0,1,0}-" + }, + { + "npc_id": "2050", + "loc_data": "{2461,3047,0,1,3}-{2466,3052,0,1,6}-" + }, + { + "npc_id": "2051", + "loc_data": "{2464,3049,0,1,2}-" + }, + { + "npc_id": "2052", + "loc_data": "{2464,3045,0,1,2}-" + }, + { + "npc_id": "2053", + "loc_data": "{2467,3049,0,1,2}-" + }, + { + "npc_id": "2054", + "loc_data": "{2468,3046,0,1,2}-" + }, + { + "npc_id": "2055", + "loc_data": "{2470,3055,0,0,5}-" + }, + { + "npc_id": "2056", + "loc_data": "{2470,3040,0,0,0}-" + }, + { + "npc_id": "2057", + "loc_data": "{2442,9436,2,1,0}-{2458,9413,2,1,0}-{2470,9435,2,1,0}-{2472,9460,2,1,0}-{2483,9413,2,1,0}-{2485,9447,2,1,0}-{2480,3046,0,1,0}-{2453,9393,2,1,0}-{2461,9403,2,1,0}-{2464,9380,2,1,0}-" + }, + { + "npc_id": "2059", + "loc_data": "{2588,3088,0,1,3}-" + }, + { + "npc_id": "2067", + "loc_data": "{3154,9544,0,0,0}-{3245,9570,0,0,0}-" + }, + { + "npc_id": "2069", + "loc_data": "{3313,9652,0,1,0}-" + }, + { + "npc_id": "2070", + "loc_data": "{3324,9621,0,1,0}-" + }, + { + "npc_id": "2071", + "loc_data": "{3323,9643,0,1,0}-" + }, + { + "npc_id": "2072", + "loc_data": "{3319,9632,0,1,0}-" + }, + { + "npc_id": "2074", + "loc_data": "{3319,9605,0,0,1}-" + }, + { + "npc_id": "2075", + "loc_data": "{3312,9638,0,0,3}-" + }, + { + "npc_id": "2076", + "loc_data": "{3312,9628,0,0,3}-" + }, + { + "npc_id": "2077", + "loc_data": "{3323,9616,0,0,6}-" + }, + { + "npc_id": "2078", + "loc_data": "{3313,9622,0,0,3}-" + }, + { + "npc_id": "2082", + "loc_data": "{3210,3220,1,1,6}-" + }, + { + "npc_id": "2084", + "loc_data": "{3314,9612,0,1,0}-" + }, + { + "npc_id": "2085", + "loc_data": "{3231,9610,0,1,0}-" + }, + { + "npc_id": "2092", + "loc_data": "{2869,10196,1,1,0}-" + }, + { + "npc_id": "2093", + "loc_data": "{2871,10207,1,1,0}-" + }, + { + "npc_id": "2094", + "loc_data": "{2869,10205,1,0,6}-" + }, + { + "npc_id": "2095", + "loc_data": "{2889,10211,1,0,6}-" + }, + { + "npc_id": "2096", + "loc_data": "{2890,10207,1,0,6}-" + }, + { + "npc_id": "2097", + "loc_data": "{2891,10196,1,0,6}-" + }, + { + "npc_id": "2098", + "loc_data": "{2890,10192,1,0,6}-" + }, + { + "npc_id": "2100", + "loc_data": "{2870,10196,1,1,0}-" + }, + { + "npc_id": "2101", + "loc_data": "{2868,10202,1,1,0}-" + }, + { + "npc_id": "2102", + "loc_data": "{2869,10208,1,1,0}-" + }, + { + "npc_id": "2103", + "loc_data": "{2892,10209,1,1,0}-" + }, + { + "npc_id": "2104", + "loc_data": "{2890,10204,1,1,0}-" + }, + { + "npc_id": "2105", + "loc_data": "{2890,10196,1,1,0}-" + }, + { + "npc_id": "2106", + "loc_data": "{2892,10190,1,1,0}-" + }, + { + "npc_id": "2110", + "loc_data": "{2877,10198,1,1,0}-{2878,10196,1,1,0}-" + }, + { + "npc_id": "2111", + "loc_data": "{2878,10201,1,1,0}-{2876,10201,1,1,0}-" + }, + { + "npc_id": "2113", + "loc_data": "{2878,10201,1,1,0}-{2876,10201,1,1,0}-" + }, + { + "npc_id": "2115", + "loc_data": "{2882,10201,1,1,0}-{2883,10200,1,1,0}-" + }, + { + "npc_id": "2117", + "loc_data": "{2883,10198,1,1,0}-{2884,10199,1,1,0}-" + }, + { + "npc_id": "2119", + "loc_data": "{2882,10197,1,1,0}-{2883,10196,1,1,0}-" + }, + { + "npc_id": "2121", + "loc_data": "{2879,10193,1,1,0}-{2880,10195,1,1,0}-" + }, + { + "npc_id": "2127", + "loc_data": "{2880,10199,1,1,0}-" + }, + { + "npc_id": "2130", + "loc_data": "{2889,10207,0,1,0}-" + }, + { + "npc_id": "2131", + "loc_data": "{2822,10212,0,1,0}-{2891,10192,0,1,0}-" + }, + { + "npc_id": "2132", + "loc_data": "{2828,10210,0,1,0}-{2891,10199,0,1,0}-" + }, + { + "npc_id": "2133", + "loc_data": "{2847,10190,0,1,0}-" + }, + { + "npc_id": "2134", + "loc_data": "{2823,10220,0,1,0}-" + }, + { + "npc_id": "2135", + "loc_data": "{2825,10209,0,1,0}-" + }, + { + "npc_id": "2136", + "loc_data": "{2827,10212,1,1,0}-" + }, + { + "npc_id": "2138", + "loc_data": "{2836,10192,1,1,0}-" + }, + { + "npc_id": "2139", + "loc_data": "{2835,10193,1,0,1}-" + }, + { + "npc_id": "2140", + "loc_data": "{2835,10226,0,0,6}-" + }, + { + "npc_id": "2141", + "loc_data": "{2906,10204,0,1,0}-" + }, + { + "npc_id": "2142", + "loc_data": "{2904,10206,0,1,0}-" + }, + { + "npc_id": "2151", + "loc_data": "{2873,10210,0,1,0}-" + }, + { + "npc_id": "2152", + "loc_data": "{2827,10231,0,1,0}-" + }, + { + "npc_id": "2153", + "loc_data": "{2826,10197,0,1,0}-" + }, + { + "npc_id": "2154", + "loc_data": "{2869,10190,0,1,0}-" + }, + { + "npc_id": "2155", + "loc_data": "{2871,10199,0,1,0}-" + }, + { + "npc_id": "2156", + "loc_data": "{2892,10212,0,1,0}-" + }, + { + "npc_id": "2157", + "loc_data": "{2887,10212,0,1,0}-" + }, + { + "npc_id": "2158", + "loc_data": "{2885,10207,0,1,0}-" + }, + { + "npc_id": "2159", + "loc_data": "{2885,10196,0,1,0}-" + }, + { + "npc_id": "2160", + "loc_data": "{2925,10210,0,1,0}-" + }, + { + "npc_id": "2161", + "loc_data": "{2869,10211,0,1,0}-" + }, + { + "npc_id": "2162", + "loc_data": "{2886,10187,0,1,0}-" + }, + { + "npc_id": "2163", + "loc_data": "{2836,10205,0,1,0}-" + }, + { + "npc_id": "2164", + "loc_data": "{2838,10205,0,0,1}-" + }, + { + "npc_id": "2169", + "loc_data": "{2836,10222,0,1,0}-" + }, + { + "npc_id": "2170", + "loc_data": "{2853,10196,0,1,0}-" + }, + { + "npc_id": "2171", + "loc_data": "{2931,10184,0,1,0}-" + }, + { + "npc_id": "2172", + "loc_data": "{2929,10191,0,1,0}-" + }, + { + "npc_id": "2173", + "loc_data": "{2931,10191,0,1,0}-" + }, + { + "npc_id": "2174", + "loc_data": "{2930,10188,0,1,0}-" + }, + { + "npc_id": "2175", + "loc_data": "{2931,10187,0,1,0}-" + }, + { + "npc_id": "2177", + "loc_data": "{2843,10191,1,0,1}-" + }, + { + "npc_id": "2178", + "loc_data": "{2916,10195,0,1,0}-" + }, + { + "npc_id": "2179", + "loc_data": "{2840,10199,0,0,6}-" + }, + { + "npc_id": "2180", + "loc_data": "{2997,9837,0,1,3}-" + }, + { + "npc_id": "2181", + "loc_data": "{2874,9871,0,1,0}-" + }, + { + "npc_id": "2182", + "loc_data": "{2908,10176,0,1,0}-" + }, + { + "npc_id": "2187", + "loc_data": "{2906,10198,0,1,0}-" + }, + { + "npc_id": "2188", + "loc_data": "{2851,10223,0,1,0}-" + }, + { + "npc_id": "2189", + "loc_data": "{2851,10223,0,1,0}-" + }, + { + "npc_id": "2190", + "loc_data": "{2923,10203,0,1,0}-" + }, + { + "npc_id": "2191", + "loc_data": "{2924,10213,0,1,0}-" + }, + { + "npc_id": "2192", + "loc_data": "{2933,10219,0,0,3}-" + }, + { + "npc_id": "2193", + "loc_data": "{2899,10218,0,1,0}-" + }, + { + "npc_id": "2194", + "loc_data": "{2926,10225,0,1,0}-" + }, + { + "npc_id": "2195", + "loc_data": "{2900,10227,0,1,0}-" + }, + { + "npc_id": "2196", + "loc_data": "{2838,10196,0,1,0}-" + }, + { + "npc_id": "2197", + "loc_data": "{2848,10198,0,1,0}-" + }, + { + "npc_id": "2198", + "loc_data": "{2906,10216,0,1,0}-" + }, + { + "npc_id": "2199", + "loc_data": "{2855,10199,0,1,0}-" + }, + { + "npc_id": "2201", + "loc_data": "{2866,10208,0,1,0}-" + }, + { + "npc_id": "2203", + "loc_data": "{2912,10222,0,1,0}-" + }, + { + "npc_id": "2205", + "loc_data": "{2842,10129,0,0,3}-" + }, + { + "npc_id": "2206", + "loc_data": "{2888,10227,0,0,6}-" + }, + { + "npc_id": "2234", + "loc_data": "{3081,3251,0,1,6}-{2636,3365,0,1,6}-" + }, + { + "npc_id": "2235", + "loc_data": "{3241,3345,0,1,4}-" + }, + { + "npc_id": "2236", + "loc_data": "{3078,3250,0,1,1}-{3081,3250,0,1,2}-" + }, + { + "npc_id": "2237", + "loc_data": "{3249,3266,0,1,5}-" + }, + { + "npc_id": "2238", + "loc_data": "{3219,3247,0,1,6}-" + }, + { + "npc_id": "2240", + "loc_data": "{3077,3259,0,1,4}-" + }, + { + "npc_id": "2241", + "loc_data": "{3078,3260,0,1,3}-" + }, + { + "npc_id": "2242", + "loc_data": "{3076,3260,0,1,1}-{3078,3260,0,1,6}-" + }, + { + "npc_id": "2243", + "loc_data": "{3078,3259,0,1,3}-" + }, + { + "npc_id": "2244", + "loc_data": "{3233,3228,0,1,3}-" + }, + { + "npc_id": "2245", + "loc_data": "{2505,3240,0,1,4}-{2512,3250,0,1,1}-{2506,3242,0,1,3}-{2510,3252,0,1,4}-{2516,3248,0,1,1}-{2518,3245,0,1,7}-{2518,3245,0,1,1}-{2517,3242,0,1,6}-{2523,3241,0,1,4}-{2525,3241,0,1,1}-{2515,3256,0,1,6}-{2519,3257,0,1,4}-" + }, + { + "npc_id": "2246", + "loc_data": "{2521,3239,0,1,5}-" + }, + { + "npc_id": "2247", + "loc_data": "{2543,3225,0,1,7}-{2553,3220,0,1,3}-{2545,3220,0,1,4}-{2525,3220,0,1,4}-{2518,3218,0,1,1}-" + }, + { + "npc_id": "2248", + "loc_data": "{2540,3218,0,1,1}-{2515,3216,0,1,1}-{2512,3215,0,1,7}-" + }, + { + "npc_id": "2249", + "loc_data": "{2530,3224,0,1,4}-{2524,3221,0,1,2}-{2543,3217,0,1,4}-{2530,3212,0,1,4}-{2557,3234,0,1,4}-{2540,3226,0,1,5}-{2532,3213,0,1,4}-{2527,3201,0,1,6}-{2544,3216,0,1,6}-{2519,3222,0,1,6}-{2526,3227,0,1,4}-{2550,3234,0,1,3}-{2553,3220,0,1,3}-{2521,3202,0,1,6}-{2525,3220,0,1,4}-{2544,3230,0,1,3}-{2547,3212,0,1,4}-{2545,3212,0,1,0}-{2540,3208,0,1,4}-{2533,3202,0,1,6}-{2536,3236,0,1,6}-{2525,3204,0,1,0}-{2539,3238,0,1,4}-" + }, + { + "npc_id": "2250", + "loc_data": "{2525,3209,0,1,4}-{2558,3228,0,1,4}-{2543,3212,0,1,3}-{2538,3223,0,1,0}-{2527,3201,0,1,7}-{2517,3222,0,1,3}-{2547,3231,0,1,6}-{2550,3220,0,1,4}-{2538,3224,0,1,3}-{2545,3213,0,1,0}-{2542,3208,0,1,5}-" + }, + { + "npc_id": "2251", + "loc_data": "{2520,3217,0,1,3}-{2524,3209,0,1,1}-{2529,3200,0,1,5}-{2530,3209,0,1,1}-{2519,3223,0,1,4}-{2518,3224,0,1,2}-{2527,3201,0,1,7}-{2521,3202,0,1,4}-{2542,3208,0,1,4}-{2539,3233,0,1,6}-" + }, + { + "npc_id": "2252", + "loc_data": "{3079,3257,0,1,1}-{3091,3250,0,1,6}-{3137,3254,0,1,0}-{3199,3302,0,1,3}-" + }, + { + "npc_id": "2256", + "loc_data": "{2571,3305,0,1,7}-{2572,3297,0,1,2}-{2572,3304,0,1,1}-{2577,3308,0,1,6}-{2582,3287,0,1,3}-{2582,3299,0,1,0}-{2583,3292,0,1,4}-{2572,3292,1,1,1}-{2577,3295,1,1,6}-{2576,3286,1,1,1}-{2585,3289,1,1,7}-{2585,3304,1,1,1}-{2582,3306,1,1,5}-{2582,3286,1,1,3}-{2653,3315,0,1,6}-{2658,3306,0,1,4}-" + }, + { + "npc_id": "2257", + "loc_data": "{3105,3554,0,1,1}-" + }, + { + "npc_id": "2260", + "loc_data": "{3259,3385,0,1,6}-" + }, + { + "npc_id": "2262", + "loc_data": "{3039,4834,0,0,7}-" + }, + { + "npc_id": "2263", + "loc_data": "{3021,4812,0,1,5}-{3014,4838,0,1,6}-{3061,4836,0,1,4}-{3017,4812,0,1,6}-{3061,4842,0,1,3}-{3048,4808,0,1,3}-{3021,4847,0,1,6}-{3054,4849,0,1,6}-{3015,4833,0,1,0}-{3035,4854,0,1,6}-{3016,4829,0,1,4}-{3040,4810,0,1,3}-{3059,4815,0,1,1}-{3027,4851,0,1,6}-{3020,4819,0,1,4}-{3020,4845,0,1,2}-{3061,4829,0,1,0}-{3018,4842,0,1,4}-{3037,4906,0,1,2}-{3057,4875,0,0,6}-{3016,4892,0,1,6}-{3058,4877,0,0,6}-{3051,4874,0,1,0}-{3029,4890,0,1,6}-{3032,4901,0,1,2}-{3024,4916,0,1,3}-{3020,4903,0,1,4}-{3061,4883,0,0,3}-{3058,4889,0,0,3}-{3053,4896,0,0,3}-{3038,4871,0,1,6}-{3053,4900,0,0,7}-{3055,4915,0,0,5}-{3037,4906,0,0,5}-{3047,4886,0,1,4}-{3033,4884,0,1,4}-{3030,4877,0,1,2}-{3026,4879,0,1,3}-{3024,4879,0,1,3}-" + }, + { + "npc_id": "2264", + "loc_data": "{3017,4821,0,1,4}-{3059,4813,0,1,0}-{3032,4808,0,1,3}-{3059,4820,0,1,3}-{3062,4828,0,1,6}-{3036,4856,0,1,7}-{3062,4837,0,1,5}-{3025,4850,0,1,1}-{3052,4858,0,1,1}-{3024,4813,0,1,4}-{3048,4854,0,1,3}-{3034,4852,0,1,1}-{3028,4808,0,1,1}-{3018,4843,0,1,2}-{3028,4851,0,1,0}-{3016,4831,0,1,1}-{3043,4810,0,1,3}-{3020,4888,0,1,3}-{3039,4871,0,1,4}-{3049,4921,0,1,7}-{3019,4877,0,1,6}-{3017,4893,0,1,7}-{3019,4898,0,1,4}-{3020,4912,0,1,2}-{3054,4915,0,1,7}-{3052,4898,0,1,1}-{3034,4905,0,1,4}-{3052,4896,0,1,3}-{3046,4901,0,1,2}-{3062,4884,0,1,6}-{3049,4873,0,1,1}-{3041,4871,0,1,1}-" + }, + { + "npc_id": "2265", + "loc_data": "{3038,4809,0,1,6}-{3024,4850,0,1,3}-{3052,4808,0,1,5}-{3021,4847,0,1,3}-{3058,4811,0,1,4}-{3055,4848,0,1,0}-{3062,4822,0,1,6}-{3017,4837,0,1,3}-{3017,4817,0,1,7}-{3025,4812,0,1,1}-{3060,4825,0,1,3}-{3062,4838,0,1,3}-{3054,4850,0,1,6}-{3020,4914,0,1,2}-{3059,4890,0,1,3}-{3031,4901,0,1,7}-{3044,4915,0,1,6}-{3044,4883,0,1,4}-{3039,4885,0,1,1}-{3048,4917,0,1,5}-{3059,4888,0,1,5}-{3047,4874,0,1,2}-{3055,4908,0,1,5}-{3016,4876,0,1,1}-{3029,4890,0,1,5}-{3059,4906,0,1,1}-{3021,4875,0,1,3}-{3032,4903,0,1,3}-{3026,4914,0,1,6}-" + }, + { + "npc_id": "2266", + "loc_data": "{3053,4978,1,1,1}-" + }, + { + "npc_id": "2270", + "loc_data": "{3048,4975,1,1,6}-" + }, + { + "npc_id": "2271", + "loc_data": "{3045,4971,1,0,4}-" + }, + { + "npc_id": "2274", + "loc_data": "{3243,3245,0,1,4}-" + }, + { + "npc_id": "2275", + "loc_data": "{3244,3248,0,1,1}-" + }, + { + "npc_id": "2276", + "loc_data": "{3243,3247,0,1,1}-" + }, + { + "npc_id": "2277", + "loc_data": "{3248,3247,0,1,4}-" + }, + { + "npc_id": "2278", + "loc_data": "{3190,3251,0,1,0}-{3179,3243,0,1,0}-{3179,3248,0,1,0}-{3146,3235,0,1,0}-{3146,3261,0,1,0}-{3247,3244,0,1,2}-" + }, + { + "npc_id": "2279", + "loc_data": "{3181,3243,0,1,0}-{3176,3248,0,1,0}-{3182,3248,0,1,0}-{3140,3226,0,1,0}-{3140,3259,0,1,0}-{3143,3260,0,1,0}-{3244,3247,0,1,3}-" + }, + { + "npc_id": "2280", + "loc_data": "{3144,3228,0,1,0}-{3245,3244,0,1,4}-" + }, + { + "npc_id": "2281", + "loc_data": "{3187,3241,0,1,0}-{3177,3243,0,1,0}-{3246,3245,0,1,4}-" + }, + { + "npc_id": "2282", + "loc_data": "{2488,4973,0,0,6}-" + }, + { + "npc_id": "2283", + "loc_data": "{2458,4980,0,0,6}-" + }, + { + "npc_id": "2284", + "loc_data": "{2457,4966,0,0,6}-" + }, + { + "npc_id": "2286", + "loc_data": "{2476,4958,0,0,3}-" + }, + { + "npc_id": "2287", + "loc_data": "{2443,4956,0,0,4}-" + }, + { + "npc_id": "2288", + "loc_data": "{2469,4941,0,0,6}-" + }, + { + "npc_id": "2289", + "loc_data": "{2451,4939,0,0,6}-" + }, + { + "npc_id": "2290", + "loc_data": "{2997,3373,0,0,0}-" + }, + { + "npc_id": "2291", + "loc_data": "{3311,3109,0,0,3}-" + }, + { + "npc_id": "2292", + "loc_data": "{3182,3043,0,0,3}-" + }, + { + "npc_id": "2293", + "loc_data": "{3469,3111,0,1,6}-" + }, + { + "npc_id": "2294", + "loc_data": "{3350,3004,0,0,6}-" + }, + { + "npc_id": "2296", + "loc_data": "{3401,2918,0,0,6}-" + }, + { + "npc_id": "2298", + "loc_data": "{3287,2813,0,1,1}-" + }, + { + "npc_id": "2300", + "loc_data": "{3243,2813,0,0,1}-" + }, + { + "npc_id": "2301", + "loc_data": "{3181,3043,0,1,3}-{3310,3107,0,1,4}-" + }, + { + "npc_id": "2302", + "loc_data": "{3243,2812,0,1,1}-" + }, + { + "npc_id": "2304", + "loc_data": "{3039,3292,0,1,6}-" + }, + { + "npc_id": "2305", + "loc_data": "{2821,3463,0,1,3}-" + }, + { + "npc_id": "2306", + "loc_data": "{2643,3363,0,0,5}-" + }, + { + "npc_id": "2307", + "loc_data": "{3627,3526,0,1,6}-" + }, + { + "npc_id": "2310", + "loc_data": "{2928,3282,0,1,1}-{2927,3269,0,1,1}-{3025,3312,0,1,4}-{3043,3308,0,1,6}-{3023,3297,0,1,5}-" + }, + { + "npc_id": "2311", + "loc_data": "{3035,3296,0,0,0}-" + }, + { + "npc_id": "2312", + "loc_data": "{3014,3292,0,0,0}-" + }, + { + "npc_id": "2313", + "loc_data": "{3020,3297,0,1,6}-{3040,3296,0,1,3}-{3031,3283,0,1,4}-{3020,3288,0,1,0}-" + }, + { + "npc_id": "2314", + "loc_data": "{3018,3296,0,1,1}-{3016,3288,0,1,4}-{3030,3287,0,1,4}-{3017,3282,0,1,3}-{2549,3566,0,1,2}-{2553,3564,0,1,4}-" + }, + { + "npc_id": "2315", + "loc_data": "{3018,3282,0,1,5}-{3037,3289,0,1,1}-{2551,3562,0,1,1}-{2554,3561,0,1,3}-" + }, + { + "npc_id": "2316", + "loc_data": "{3015,3311,0,1,4}-" + }, + { + "npc_id": "2317", + "loc_data": "{3016,3309,0,1,6}-" + }, + { + "npc_id": "2318", + "loc_data": "{3017,3307,0,0,0}-" + }, + { + "npc_id": "2319", + "loc_data": "{3017,3309,0,0,0}-" + }, + { + "npc_id": "2321", + "loc_data": "{2915,10194,1,1,0}-" + }, + { + "npc_id": "2323", + "loc_data": "{3056,3306,0,1,1}-" + }, + { + "npc_id": "2324", + "loc_data": "{2807,3464,0,1,3}-" + }, + { + "npc_id": "2325", + "loc_data": "{2664,3374,0,1,1}-" + }, + { + "npc_id": "2326", + "loc_data": "{3600,3527,0,1,1}-" + }, + { + "npc_id": "2327", + "loc_data": "{2814,3337,0,1,6}-" + }, + { + "npc_id": "2330", + "loc_data": "{2766,3211,0,1,0}-" + }, + { + "npc_id": "2331", + "loc_data": "{2860,3430,0,1,4}-" + }, + { + "npc_id": "2332", + "loc_data": "{2573,3102,0,1,4}-" + }, + { + "npc_id": "2333", + "loc_data": "{3226,3311,0,0,0}-" + }, + { + "npc_id": "2334", + "loc_data": "{2662,3525,0,1,1}-" + }, + { + "npc_id": "2335", + "loc_data": "{3181,3359,0,0,0}-" + }, + { + "npc_id": "2336", + "loc_data": "{2938,3221,0,1,0}-" + }, + { + "npc_id": "2337", + "loc_data": "{2589,3861,0,1,0}-" + }, + { + "npc_id": "2338", + "loc_data": "{2615,3229,0,1,0}-" + }, + { + "npc_id": "2339", + "loc_data": "{2934,3438,0,1,6}-" + }, + { + "npc_id": "2340", + "loc_data": "{3007,3373,0,1,4}-" + }, + { + "npc_id": "2341", + "loc_data": "{3229,3456,0,1,0}-" + }, + { + "npc_id": "2342", + "loc_data": "{3196,3231,0,1,4}-" + }, + { + "npc_id": "2343", + "loc_data": "{2473,3446,0,1,6}-" + }, + { + "npc_id": "2344", + "loc_data": "{2490,3183,0,1,3}-" + }, + { + "npc_id": "2352", + "loc_data": "{2334,3183,0,1,0}-" + }, + { + "npc_id": "2353", + "loc_data": "{2324,3179,0,1,5}-" + }, + { + "npc_id": "2355", + "loc_data": "{2353,3163,0,0,4}-" + }, + { + "npc_id": "2356", + "loc_data": "{2323,3163,0,1,0}-" + }, + { + "npc_id": "2357", + "loc_data": "{2340,3157,1,1,0}-" + }, + { + "npc_id": "2359", + "loc_data": "{2335,3169,0,1,3}-" + }, + { + "npc_id": "2360", + "loc_data": "{2335,3174,0,1,4}-{2322,3172,0,1,5}-" + }, + { + "npc_id": "2361", + "loc_data": "{2345,3172,0,1,2}-{2340,3178,0,1,3}-" + }, + { + "npc_id": "2362", + "loc_data": "{2330,3163,0,1,3}-" + }, + { + "npc_id": "2372", + "loc_data": "{2044,4628,0,1,0}-" + }, + { + "npc_id": "2373", + "loc_data": "{2037,4636,0,1,0}-{2038,4644,0,1,0}-{2041,4638,0,1,0}-{2044,4642,0,1,0}-" + }, + { + "npc_id": "2374", + "loc_data": "{2036,4633,0,0,6}-" + }, + { + "npc_id": "2381", + "loc_data": "{2555,3444,0,1,0}-" + }, + { + "npc_id": "2382", + "loc_data": "{3022,3946,0,1,0}-" + }, + { + "npc_id": "2383", + "loc_data": "{3034,3701,0,1,0}-" + }, + { + "npc_id": "2384", + "loc_data": "{3162,2982,0,1,0}-" + }, + { + "npc_id": "2385", + "loc_data": "{3112,3158,0,1,0}-" + }, + { + "npc_id": "2386", + "loc_data": "{3052,3496,1,1,0}-" + }, + { + "npc_id": "2387", + "loc_data": "{3053,3378,1,1,0}-" + }, + { + "npc_id": "2388", + "loc_data": "{2950,3820,0,1,0}-" + }, + { + "npc_id": "2389", + "loc_data": "{3218,3677,0,1,0}-" + }, + { + "npc_id": "2390", + "loc_data": "{3068,3858,0,1,0}-" + }, + { + "npc_id": "2391", + "loc_data": "{2850,3348,0,1,0}-" + }, + { + "npc_id": "2392", + "loc_data": "{3044,3204,0,1,0}-" + }, + { + "npc_id": "2393", + "loc_data": "{2396,3481,0,1,0}-" + }, + { + "npc_id": "2394", + "loc_data": "{3294,3934,1,1,0}-" + }, + { + "npc_id": "2395", + "loc_data": "{3448,3550,1,1,0}-" + }, + { + "npc_id": "2396", + "loc_data": "{3119,9996,0,1,0}-" + }, + { + "npc_id": "2414", + "loc_data": "{3263,3400,1,0,0}-" + }, + { + "npc_id": "2435", + "loc_data": "{2621,3682,0,0,6}-" + }, + { + "npc_id": "2438", + "loc_data": "{2544,3761,0,0,6}-" + }, + { + "npc_id": "2439", + "loc_data": "{2659,3657,0,1,3}-" + }, + { + "npc_id": "2440", + "loc_data": "{2545,10141,0,0,6}-" + }, + { + "npc_id": "2443", + "loc_data": "{2543,10143,0,0,3}-" + }, + { + "npc_id": "2446", + "loc_data": "{2545,10145,0,0,6}-" + }, + { + "npc_id": "2449", + "loc_data": "{2546,10144,0,0,1}-{2546,10142,0,0,6}-" + }, + { + "npc_id": "2452", + "loc_data": "{2526,10166,0,1,6}-" + }, + { + "npc_id": "2453", + "loc_data": "{1846,4405,3,0,2}-{1839,4400,3,0,3}-{1835,4394,3,0,3}-{1834,4406,3,0,1}-{1843,4406,3,0,2}-{1899,4372,0,0,2}-{1888,4362,0,0,7}-{1896,4362,0,0,2}-{1897,4368,0,0,5}-{2521,10160,0,0,1}-{2535,10163,0,0,6}-{2520,10165,0,0,3}-{2533,10162,0,0,3}-{2545,10158,0,0,5}-{2547,10151,0,0,3}-{2543,10166,0,0,3}-{2538,10160,0,0,6}-{2506,10163,0,0,3}-{2516,10163,0,0,3}-{2498,10164,0,0,5}-{2544,10160,0,0,0}-{2525,10162,0,0,3}-{2530,10161,0,0,0}-{2537,10167,0,0,7}-{2519,10163,0,0,3}-{2511,10163,0,0,3}-{2530,10161,0,0,7}-{2524,10166,0,0,3}-{2508,10159,0,0,0}-" + }, + { + "npc_id": "2455", + "loc_data": "{1815,4405,2,1,6}-{1818,4403,2,1,3}-{1813,4404,2,1,7}-{1814,4407,2,1,7}-{1821,4393,2,1,1}-{1823,4389,2,1,1}-{1828,4387,2,1,3}-{1821,4392,2,1,0}-{1826,4391,2,1,0}-{1844,4360,1,1,4}-{1844,4361,1,1,5}-{1851,4360,1,1,3}-{1831,4378,3,1,2}-{1838,4379,3,1,2}-{1824,4376,3,1,1}-{1832,4380,3,1,6}-{1844,4373,2,1,4}-{1849,4381,2,1,4}-{1846,4374,2,1,1}-{1865,4377,2,1,1}-{1865,4397,1,1,6}-{1857,4360,1,1,1}-{1862,4362,1,1,1}-{1862,4362,1,1,7}-{1864,4366,1,1,1}-{1865,4383,2,1,4}-{1864,4390,1,1,1}-{1865,4408,1,1,4}-{1877,4410,1,1,1}-{1883,4411,1,1,4}-{1889,4410,1,1,4}-{1887,4374,0,1,6}-{1890,4372,0,1,4}-{1890,4366,0,1,4}-{1896,4371,0,1,3}-{1890,4364,0,1,7}-{2457,10139,0,1,2}-{2465,10133,0,1,4}-{2449,10148,0,1,1}-{2471,10133,0,1,6}-{2446,10145,0,1,4}-{2443,10148,0,1,1}-{2452,10161,0,1,3}-{2444,10145,0,1,1}-{2462,10163,0,1,3}-{2446,10141,0,1,3}-{2454,10149,0,1,0}-{2476,10155,0,1,4}-{2456,10153,0,1,0}-{2485,10142,0,1,3}-{2457,10152,0,1,4}-{2485,10126,0,1,4}-{2475,10148,0,1,3}-{2471,10160,0,1,1}-{2453,10145,0,1,3}-{2463,10158,0,1,4}-{2457,10163,0,1,2}-{2471,10154,0,1,6}-{2476,10151,0,1,7}-{2479,10154,0,1,1}-{2486,10158,0,1,4}-{2485,10165,0,1,5}-{2485,10153,0,1,4}-{2474,10140,0,1,7}-{2466,10130,0,1,6}-{2464,10138,0,1,6}-{2486,10150,0,1,6}-{2473,10127,0,1,4}-{2483,10126,0,1,3}-{2456,10133,0,1,6}-{2467,10163,0,1,6}-{2477,10143,0,1,3}-{2489,10139,0,1,4}-{2486,10127,0,1,1}-{2480,10141,0,1,7}-{2490,10155,0,1,3}-{2459,10133,0,1,3}-{2455,10163,0,1,0}-{2494,10162,0,1,1}-{2493,10132,0,1,3}-{2494,10129,0,1,5}-{2496,10166,0,1,1}-{2502,10167,0,1,1}-{2499,10162,0,1,0}-{2502,10159,0,1,1}-{2502,10166,0,1,4}-{2496,10130,0,1,3}-{2498,10128,0,1,1}-{2497,10126,0,1,4}-{2499,10128,0,1,5}-{2501,10126,0,1,3}-{2506,10125,0,1,4}-{2506,10127,0,1,4}-{2507,10128,0,1,3}-{2507,10126,0,1,6}-{2511,10126,0,1,0}-{2513,10126,0,1,4}-{2517,10129,0,1,3}-{2513,10127,0,1,3}-{2516,10124,0,1,4}-{2520,10122,0,1,5}-{2522,10126,0,1,3}-{2524,10129,0,1,4}-{2525,10125,0,1,4}-{2529,10122,0,1,4}-{2529,10124,0,1,2}-{2526,10126,0,1,3}-{2529,10130,0,1,6}-{2530,10127,0,1,5}-{2532,10121,0,1,0}-{2532,10123,0,1,3}-{2538,10126,0,1,0}-{2535,10125,0,1,7}-{2536,10127,0,1,1}-{2539,10130,0,1,6}-{2543,10130,0,1,6}-{2548,10131,0,1,1}-{2542,10128,0,1,3}-" + }, + { + "npc_id": "2456", + "loc_data": "{2452,10145,0,0,4}-{2445,10138,0,0,7}-" + }, + { + "npc_id": "2457", + "loc_data": "{1804,4369,2,1,2}-{1812,4363,2,1,5}-{1817,4368,2,1,6}-{1801,4404,3,1,6}-{1805,4405,3,1,1}-{1803,4404,3,1,7}-{1811,4394,1,1,7}-{1804,4391,1,1,2}-{1798,4391,1,1,4}-{1802,4389,1,1,4}-{1799,4386,2,1,1}-{1799,4381,2,1,6}-{1798,4375,1,1,4}-{1803,4376,1,1,6}-{1797,4380,1,1,6}-{1848,4394,1,1,3}-{1850,4389,1,1,1}-{1850,4391,1,1,2}-{1902,4367,0,1,6}-{1894,4367,0,1,1}-{1893,4361,0,1,3}-{1886,4369,0,1,1}-{2500,10148,0,1,3}-{2505,10150,0,1,2}-{2510,10148,0,1,1}-{2511,10147,0,1,6}-{2517,10151,0,1,3}-{2519,10143,0,1,7}-{2529,10148,0,1,3}-{2528,10144,0,1,0}-{2532,10145,0,1,1}-{2532,10140,0,1,7}-{2520,10144,0,1,2}-" + }, + { + "npc_id": "2458", + "loc_data": "{2599,4774,0,0,3}-" + }, + { + "npc_id": "2459", + "loc_data": "{2604,4772,0,1,4}-{2606,4771,0,1,6}-{2604,4769,0,1,2}-" + }, + { + "npc_id": "2460", + "loc_data": "{2600,4778,0,1,1}-{2607,4777,0,1,1}-" + }, + { + "npc_id": "2461", + "loc_data": "{2597,4776,0,1,1}-{2606,4771,0,1,1}-" + }, + { + "npc_id": "2462", + "loc_data": "{2596,4773,0,1,2}-{2602,4771,0,1,6}-{2596,4780,0,1,4}-" + }, + { + "npc_id": "2477", + "loc_data": "{1952,4768,1,0,6}-" + }, + { + "npc_id": "2479", + "loc_data": "{3420,4777,0,0,0}-" + }, + { + "npc_id": "2481", + "loc_data": "{3423,4777,0,0,5}-" + }, + { + "npc_id": "2483", + "loc_data": "{2914,3116,0,0,0}-" + }, + { + "npc_id": "2484", + "loc_data": "{2782,3058,0,0,0}-" + }, + { + "npc_id": "2486", + "loc_data": "{2789,3055,0,0,0}-" + }, + { + "npc_id": "2487", + "loc_data": "{2848,3042,0,0,0}-" + }, + { + "npc_id": "2488", + "loc_data": "{2799,3058,0,0,0}-" + }, + { + "npc_id": "2489", + "loc_data": "{3703,3040,0,1,3}-{3706,3051,0,1,1}-{3664,3013,0,1,7}-{3749,3000,0,1,6}-{3723,2998,0,1,2}-{3731,2991,0,1,1}-{3775,3033,0,1,4}-{3766,3010,0,1,4}-{3764,3020,0,1,1}-{3738,3010,0,1,3}-{3720,3040,0,1,6}-{3719,3045,0,1,6}-{3781,3031,0,1,5}-{3780,3022,0,1,1}-{3788,3011,0,1,2}-{3793,3019,0,1,5}-{3779,3045,0,1,1}-{3784,3040,0,1,3}-{3802,3037,0,1,2}-{3808,3026,0,1,3}-{3799,3024,0,1,4}-" + }, + { + "npc_id": "2490", + "loc_data": "{3782,3016,0,1,7}-" + }, + { + "npc_id": "2491", + "loc_data": "{2679,3080,0,1,6}-{2684,3084,0,1,4}-{2682,3093,0,1,4}-{2678,3095,0,1,3}-{2679,3102,0,1,1}-{2681,3110,0,1,4}-{2683,3115,0,1,6}-{2675,3108,0,1,3}-{2671,3109,0,1,3}-{2671,3113,0,1,4}-{2676,3090,0,1,4}-{2670,3088,0,1,6}-{2671,3086,0,1,6}-{2664,3088,0,1,7}-{2660,3086,0,1,6}-{2662,3088,0,1,6}-{2670,3082,0,1,7}-{2674,3081,0,1,3}-{2663,3086,0,1,6}-{2679,3082,0,1,1}-{2682,3093,0,1,3}-" + }, + { + "npc_id": "2504", + "loc_data": "{2796,3077,1,1,3}-" + }, + { + "npc_id": "2507", + "loc_data": "{2794,3077,0,1,6}-" + }, + { + "npc_id": "2510", + "loc_data": "{2786,3075,1,1,4}-" + }, + { + "npc_id": "2513", + "loc_data": "{2796,3088,0,1,7}-" + }, + { + "npc_id": "2516", + "loc_data": "{2791,3102,0,1,3}-" + }, + { + "npc_id": "2519", + "loc_data": "{2794,3064,0,1,5}-" + }, + { + "npc_id": "2522", + "loc_data": "{2758,3099,0,1,1}-" + }, + { + "npc_id": "2525", + "loc_data": "{2800,3048,0,1,2}-" + }, + { + "npc_id": "2528", + "loc_data": "{2816,3085,0,1,3}-" + }, + { + "npc_id": "2531", + "loc_data": "{2784,3089,0,1,1}-" + }, + { + "npc_id": "2547", + "loc_data": "{2615,9525,0,1,4}-{2615,9521,0,1,1}-{3109,9942,0,1,4}-{3111,9938,0,1,4}-{3116,9926,0,1,4}-" + }, + { + "npc_id": "2548", + "loc_data": "{3349,2970,0,0,4}-{3358,2987,0,0,4}-" + }, + { + "npc_id": "2549", + "loc_data": "{3364,3001,0,0,6}-" + }, + { + "npc_id": "2553", + "loc_data": "{1944,4958,0,1,0}-" + }, + { + "npc_id": "2564", + "loc_data": "{1936,4966,0,0,4}-" + }, + { + "npc_id": "2565", + "loc_data": "{1939,4968,0,1,0}-" + }, + { + "npc_id": "2568", + "loc_data": "{2729,3495,0,0,6}-{2724,3495,0,0,6}-{2728,3495,0,0,6}-{2721,3495,0,0,6}-" + }, + { + "npc_id": "2569", + "loc_data": "{2727,3495,0,0,6}-{2722,3495,0,0,6}-" + }, + { + "npc_id": "2572", + "loc_data": "{3079,3250,0,1,2}-" + }, + { + "npc_id": "2574", + "loc_data": "{3087,3247,0,0,7}-" + }, + { + "npc_id": "2580", + "loc_data": "{2918,3535,0,1,0}-" + }, + { + "npc_id": "2591", + "loc_data": "{4786,5106,0,1,6}-{2474,5145,0,1,2}-" + }, + { + "npc_id": "2592", + "loc_data": "{4680,5117,0,1,6}-{2461,5142,0,1,6}-" + }, + { + "npc_id": "2594", + "loc_data": "{4730,5077,0,1,5}-{4703,5123,0,1,5}-{4680,5126,0,1,7}-" + }, + { + "npc_id": "2595", + "loc_data": "{4633,5069,0,1,4}-{4647,5132,0,1,7}-{4699,5100,0,1,6}-{4757,5100,0,1,2}-" + }, + { + "npc_id": "2596", + "loc_data": "{4628,5117,0,1,4}-{4787,5118,0,1,7}-{2483,5155,0,1,4}-" + }, + { + "npc_id": "2597", + "loc_data": "{4621,5094,0,1,5}-{2446,5144,0,1,1}-{2470,5141,0,1,6}-" + }, + { + "npc_id": "2598", + "loc_data": "{2485,5159,0,1,4}-{2489,5155,0,1,1}-{2471,5144,0,1,3}-{2476,5153,0,1,0}-{2477,5150,0,1,1}-" + }, + { + "npc_id": "2600", + "loc_data": "{4656,5125,0,1,5}-{4711,5072,0,1,4}-{4751,5087,0,1,3}-" + }, + { + "npc_id": "2601", + "loc_data": "{4724,5107,0,1,5}-{4676,5123,0,1,5}-{4693,5127,0,1,7}-{4788,5110,0,1,4}-" + }, + { + "npc_id": "2602", + "loc_data": "{4668,5133,0,1,7}-{4627,5122,0,1,5}-{4714,5113,0,1,6}-{4752,5074,0,1,7}-{4789,5122,0,1,2}-" + }, + { + "npc_id": "2603", + "loc_data": "{4711,5086,0,1,2}-{4760,5091,0,1,4}-" + }, + { + "npc_id": "2604", + "loc_data": "{2439,5170,0,1,3}-{2451,5170,0,1,3}-{2453,5161,0,1,6}-{2460,5160,0,1,7}-{2457,5155,0,1,3}-{2480,5168,0,1,6}-{2469,5166,0,1,1}-{2490,5173,0,1,3}-{2488,5171,0,1,4}-{2483,5156,0,1,3}-{2470,5147,0,1,4}-{2468,5139,0,1,7}-{2458,5141,0,1,3}-{2454,5141,0,1,1}-{2452,5124,0,1,3}-{2454,5122,0,1,2}-{2453,5143,0,1,3}-{2443,5144,0,1,6}-" + }, + { + "npc_id": "2605", + "loc_data": "{4631,5088,0,1,7}-{4633,5125,0,1,7}-{4760,5074,0,1,4}-" + }, + { + "npc_id": "2606", + "loc_data": "{4670,5081,0,1,6}-{4642,5115,0,1,7}-{4756,5086,0,1,4}-" + }, + { + "npc_id": "2607", + "loc_data": "{4638,5095,0,1,2}-{4647,5141,0,1,4}-{4699,5141,0,1,3}-{4774,5098,0,1,3}-" + }, + { + "npc_id": "2608", + "loc_data": "{4656,5091,0,1,5}-{4637,5093,0,1,0}-" + }, + { + "npc_id": "2609", + "loc_data": "{4617,5073,0,1,6}-{4691,5090,0,1,7}-{4727,5082,0,1,6}-{4711,5125,0,1,4}-{4748,5070,0,1,4}-{2440,5128,0,1,3}-{2436,5133,0,1,3}-{2450,5168,0,1,2}-{2443,5170,0,1,4}-{2445,5177,0,1,3}-" + }, + { + "npc_id": "2610", + "loc_data": "{2446,5169,0,1,4}-{2458,5159,0,1,3}-{2466,5166,0,1,7}-{2471,5166,0,1,3}-{2478,5164,0,1,4}-{2490,5174,0,1,4}-{2485,5159,0,1,5}-{2442,5173,0,1,0}-{2440,5171,0,1,7}-{2440,5170,0,1,3}-" + }, + { + "npc_id": "2611", + "loc_data": "{4646,5107,0,1,6}-{4683,5098,0,1,4}-{4690,5113,0,1,5}-{4720,5118,0,1,7}-{4716,5097,0,1,5}-{4762,5088,0,1,0}-" + }, + { + "npc_id": "2614", + "loc_data": "{4666,5082,0,1,0}-{4669,5103,0,1,2}-{4639,5074,0,1,3}-{4664,5121,0,1,4}-{4688,5016,0,1,3}-{4704,5077,0,1,5}-" + }, + { + "npc_id": "2615", + "loc_data": "{4625,5084,0,1,7}-{4628,5134,0,1,3}-{4725,5067,0,1,5}-{4695,5128,0,1,7}-{4748,5076,0,1,6}-{4790,5127,0,1,0}-" + }, + { + "npc_id": "2616", + "loc_data": "{4631,5106,0,1,0}-{4673,5114,0,1,1}-{2441,5130,0,1,1}-{2438,5135,0,1,6}-{2443,5138,0,1,2}-" + }, + { + "npc_id": "2617", + "loc_data": "{4611,5132,0,1,5}-{2440,5168,0,0,1}-" + }, + { + "npc_id": "2618", + "loc_data": "{2399,5178,0,1,6}-{4603,5065,0,1,1}-" + }, + { + "npc_id": "2619", + "loc_data": "{4644,5149,0,1,7}-{2418,5203,0,1,6}-{2446,5179,0,0,6}-" + }, + { + "npc_id": "2620", + "loc_data": "{4701,5153,0,1,0}-{2478,5146,0,1,2}-" + }, + { + "npc_id": "2621", + "loc_data": "{2724,3729,0,0,6}-" + }, + { + "npc_id": "2622", + "loc_data": "{4689,5173,0,0,0}-{2464,5149,0,0,7}-" + }, + { + "npc_id": "2623", + "loc_data": "{4655,5172,0,1,0}-{2462,5125,0,1,5}-" + }, + { + "npc_id": "2624", + "loc_data": "{4718,5148,0,1,6}-{4708,5173,0,1,6}-{4716,5178,0,1,7}-{4726,5173,0,1,0}-{4730,5163,0,1,3}-{4726,5153,0,1,5}-" + }, + { + "npc_id": "2625", + "loc_data": "{4668,5177,0,1,4}-{4676,5177,0,1,2}-" + }, + { + "npc_id": "2634", + "loc_data": "{3095,3252,0,0,0}-" + }, + { + "npc_id": "2652", + "loc_data": "{2868,3579,0,0,0}-{2851,3582,0,0,0}-" + }, + { + "npc_id": "2655", + "loc_data": "{2921,3558,0,1,6}-" + }, + { + "npc_id": "2660", + "loc_data": "{3208,3496,0,1,3}-" + }, + { + "npc_id": "2674", + "loc_data": "{3017,3231,0,1,1}-" + }, + { + "npc_id": "2676", + "loc_data": "{2914,3322,0,0,0}-" + }, + { + "npc_id": "2677", + "loc_data": "{2945,3307,0,0,0}-" + }, + { + "npc_id": "2678", + "loc_data": "{2988,3210,0,1,7}-" + }, + { + "npc_id": "2679", + "loc_data": "{3000,3222,0,1,1}-" + }, + { + "npc_id": "2680", + "loc_data": "{2582,9836,0,1,2}-{2985,3193,0,1,1}-" + }, + { + "npc_id": "2681", + "loc_data": "{2991,3199,0,1,3}-" + }, + { + "npc_id": "2682", + "loc_data": "{2904,3208,0,1,0}-{1866,4237,0,1,0}-{1866,4240,0,1,0}-{1867,4243,0,1,0}-{2950,3204,0,1,5}-{2971,3212,0,1,4}-{2960,3201,0,1,1}-{2959,3202,0,1,4}-{2956,3203,0,1,1}-{2969,3204,0,1,4}-" + }, + { + "npc_id": "2683", + "loc_data": "{2967,3212,1,0,7}-" + }, + { + "npc_id": "2684", + "loc_data": "{2965,3213,1,0,0}-" + }, + { + "npc_id": "2685", + "loc_data": "{3124,9873,0,1,3}-{2911,3285,0,1,1}-{2696,9689,0,1,1}-" + }, + { + "npc_id": "2686", + "loc_data": "{2907,3293,0,1,4}-{2700,9696,0,1,1}-" + }, + { + "npc_id": "2687", + "loc_data": "{2907,3293,0,1,6}-{2908,3290,0,1,3}-{2703,9698,0,1,1}-" + }, + { + "npc_id": "2688", + "loc_data": "{3127,9874,0,1,4}-{2906,3288,0,1,1}-{2910,3293,0,1,4}-{2699,9690,0,1,1}-" + }, + { + "npc_id": "2689", + "loc_data": "{2918,3319,0,0,0}-" + }, + { + "npc_id": "2690", + "loc_data": "{3048,3258,0,1,3}-" + }, + { + "npc_id": "2691", + "loc_data": "{3048,3256,0,1,4}-" + }, + { + "npc_id": "2692", + "loc_data": "{3049,3256,0,0,0}-" + }, + { + "npc_id": "2693", + "loc_data": "{3238,3238,0,1,0}-{3238,3246,0,1,0}-{3239,3235,0,1,0}-{3214,3313,0,1,0}-{3214,3320,0,1,0}-{3215,3303,0,1,0}-{3219,3285,0,1,0}-{3219,3288,0,1,0}-{3234,3267,0,1,0}-{3234,3268,0,1,0}-{2976,3359,0,1,0}-{2977,3357,0,1,0}-{2988,3383,0,1,1}-{2992,3385,0,1,3}-{3015,3285,0,1,0}-" + }, + { + "npc_id": "2695", + "loc_data": "{3013,3192,0,1,1}-" + }, + { + "npc_id": "2696", + "loc_data": "{3013,3196,0,1,1}-" + }, + { + "npc_id": "2697", + "loc_data": "{3018,3189,0,1,4}-" + }, + { + "npc_id": "2698", + "loc_data": "{3018,3181,0,1,6}-" + }, + { + "npc_id": "2699", + "loc_data": "{3016,3184,1,1,0}-" + }, + { + "npc_id": "2700", + "loc_data": "{3016,3182,1,1,0}-" + }, + { + "npc_id": "2701", + "loc_data": "{3011,3181,1,1,0}-" + }, + { + "npc_id": "2702", + "loc_data": "{3019,3180,1,1,0}-" + }, + { + "npc_id": "2703", + "loc_data": "{3012,3185,1,1,0}-" + }, + { + "npc_id": "2704", + "loc_data": "{3019,3185,0,0,0}-" + }, + { + "npc_id": "2705", + "loc_data": "{3018,3185,2,1,0}-" + }, + { + "npc_id": "2706", + "loc_data": "{3725,3015,0,1,4}-{3745,3026,0,1,6}-{3741,3033,0,1,6}-{3734,3045,0,1,1}-{3019,3145,0,1,3}-{3015,3142,0,1,4}-{3022,3139,0,1,4}-" + }, + { + "npc_id": "2709", + "loc_data": "{3002,3266,0,1,6}-" + }, + { + "npc_id": "2710", + "loc_data": "{3001,3268,0,1,4}-" + }, + { + "npc_id": "2711", + "loc_data": "{3002,3268,0,1,4}-" + }, + { + "npc_id": "2712", + "loc_data": "{3001,3268,0,1,3}-" + }, + { + "npc_id": "2713", + "loc_data": "{3002,3267,0,1,2}-" + }, + { + "npc_id": "2725", + "loc_data": "{2500,3488,0,1,2}-" + }, + { + "npc_id": "2726", + "loc_data": "{2994,3138,0,1,0}-" + }, + { + "npc_id": "2727", + "loc_data": "{2969,3146,0,1,0}-" + }, + { + "npc_id": "2728", + "loc_data": "{3043,3235,0,1,7}-" + }, + { + "npc_id": "2729", + "loc_data": "{3047,3234,0,1,7}-" + }, + { + "npc_id": "2730", + "loc_data": "{2835,3335,0,0,5}-" + }, + { + "npc_id": "2731", + "loc_data": "{2833,3335,0,0,3}-" + }, + { + "npc_id": "2732", + "loc_data": "{2933,3281,0,1,1}-" + }, + { + "npc_id": "2733", + "loc_data": "{2932,3286,0,1,1}-" + }, + { + "npc_id": "2759", + "loc_data": "{3104,3368,0,0,0}-{3096,3493,0,0,0}-{3097,3494,0,0,0}-{3180,3438,0,0,0}-{3180,3442,0,0,0}-{3191,3441,0,0,0}-{3191,3437,0,0,0}-{3191,3445,0,0,0}-{3254,3418,0,0,0}-{3255,3418,0,0,0}-{3256,3418,0,0,0}-" + }, + { + "npc_id": "2782", + "loc_data": "{1925,4636,0,1,7}-" + }, + { + "npc_id": "2783", + "loc_data": "{1995,4660,0,1,7}-{1989,4660,0,1,0}-{1989,4664,0,1,7}-{1997,4664,0,1,3}-{1989,4658,0,1,0}-{2001,4646,0,1,4}-{2000,4645,0,1,3}-{1997,4644,0,1,1}-{1999,4636,0,1,3}-{2022,4665,0,1,0}-{2024,4662,0,1,0}-{2020,4660,0,1,0}-{2023,4656,0,1,0}-{2029,4660,0,1,0}-{2031,4665,0,1,0}-{2034,4661,0,1,0}-{2032,4658,0,1,0}-{1991,4653,0,1,0}-{1995,4651,0,1,0}-" + }, + { + "npc_id": "2784", + "loc_data": "{2022,4616,0,1,5}-{2024,4620,0,1,5}-" + }, + { + "npc_id": "2785", + "loc_data": "{2000,4613,0,0,0}-{2000,4611,0,0,5}-" + }, + { + "npc_id": "2786", + "loc_data": "{2008,4613,0,1,0}-" + }, + { + "npc_id": "2787", + "loc_data": "{2023,4612,0,1,0}-" + }, + { + "npc_id": "2790", + "loc_data": "{3163,4822,0,0,6}-" + }, + { + "npc_id": "2792", + "loc_data": "{3228,3412,0,0,0}-" + }, + { + "npc_id": "2794", + "loc_data": "{2606,3100,0,0,0}-" + }, + { + "npc_id": "2795", + "loc_data": "{2979,3197,0,1,0}-" + }, + { + "npc_id": "2796", + "loc_data": "{3096,3108,0,0,6}-" + }, + { + "npc_id": "2800", + "loc_data": "{2981,3190,0,0,0}-" + }, + { + "npc_id": "2801", + "loc_data": "{2523,3373,0,1,0}-{2523,3376,0,1,0}-{2526,3373,0,1,0}-{2526,3376,0,1,0}-{2529,3373,0,1,0}-{2529,3376,0,1,0}-{2531,3376,0,1,0}-{2532,3373,0,1,0}-" + }, + { + "npc_id": "2802", + "loc_data": "{2406,3498,0,1,0}-" + }, + { + "npc_id": "2803", + "loc_data": "{3387,3068,0,1,0}-{3387,3017,0,1,0}-{3404,3062,0,1,0}-{3441,3061,0,1,0}-{3445,3034,0,1,0}-{3338,2804,0,1,0}-{3339,2815,0,1,0}-{3342,2809,0,1,0}-{3344,2800,0,1,0}-{3348,2809,0,1,0}-{3349,2814,0,1,0}-{3357,2813,0,1,0}-{3357,2806,0,1,0}-{3365,2815,0,1,0}-" + }, + { + "npc_id": "2804", + "loc_data": "{3388,3067,0,1,0}-{3396,3064,0,1,6}-{3402,3063,0,1,1}-{3423,3019,0,1,3}-{3420,3015,0,1,6}-{3430,3014,0,1,2}-{3426,3020,0,0,0}-{3416,3013,0,1,4}-{3410,3016,0,1,6}-" + }, + { + "npc_id": "2805", + "loc_data": "{3391,3071,0,1,2}-{3385,3064,0,1,6}-{3397,3069,0,1,2}-{3398,3068,0,1,1}-{3406,3064,0,1,6}-{3413,3053,0,1,6}-{3424,3061,0,1,2}-{3423,3020,0,1,0}-{3429,3019,0,0,0}-" + }, + { + "npc_id": "2806", + "loc_data": "{3426,3052,0,1,4}-{3423,3044,0,1,3}-{3415,3018,0,1,5}-{3425,3009,0,1,3}-" + }, + { + "npc_id": "2807", + "loc_data": "{3384,3013,0,1,0}-{3387,3014,0,1,0}-{3441,3059,0,1,0}-{3443,3033,0,1,0}-{3443,3059,0,1,0}-" + }, + { + "npc_id": "2808", + "loc_data": "{3385,3067,0,1,0}-{3389,3065,0,1,0}-{3400,3032,0,1,0}-{3402,3061,0,1,0}-{3404,3060,0,1,0}-{3407,3067,0,1,0}-{3408,3060,0,1,0}-{3411,3065,0,1,0}-{3412,3032,0,1,0}-{3412,3049,0,1,0}-{3414,3029,0,1,0}-{3417,3036,0,1,0}-{3418,3032,0,1,0}-{3419,3034,0,1,0}-{3422,3058,0,1,0}-{3424,3059,0,1,0}-{3435,3057,0,1,0}-{3435,3062,0,1,0}-{3439,3013,0,1,0}-{3439,3065,0,1,0}-{3440,3016,0,1,0}-{3443,3012,0,1,0}-{3443,3017,0,1,0}-{3443,3034,0,1,0}-{3443,3047,0,1,0}-{3446,3014,0,1,0}-" + }, + { + "npc_id": "2809", + "loc_data": "{3274,3168,0,1,0}-" + }, + { + "npc_id": "2810", + "loc_data": "{3311,3208,0,1,0}-" + }, + { + "npc_id": "2811", + "loc_data": "{3289,3209,0,1,0}-" + }, + { + "npc_id": "2812", + "loc_data": "{3296,3227,0,0,0}-" + }, + { + "npc_id": "2813", + "loc_data": "{3285,3201,0,0,0}-" + }, + { + "npc_id": "2816", + "loc_data": "{3301,3190,0,0,0}-" + }, + { + "npc_id": "2817", + "loc_data": "{3306,3197,0,0,0}-" + }, + { + "npc_id": "2818", + "loc_data": "{3303,3204,0,0,0}-" + }, + { + "npc_id": "2819", + "loc_data": "{3295,3193,0,0,0}-" + }, + { + "npc_id": "2820", + "loc_data": "{3302,3185,0,1,4}-" + }, + { + "npc_id": "2821", + "loc_data": "{3306,3196,0,0,4}-" + }, + { + "npc_id": "2823", + "loc_data": "{3302,3197,0,1,4}-" + }, + { + "npc_id": "2824", + "loc_data": "{3275,3193,0,0,0}-" + }, + { + "npc_id": "2860", + "loc_data": "{2345,3165,0,1,4}-" + }, + { + "npc_id": "2861", + "loc_data": "{2347,3165,0,1,3}-" + }, + { + "npc_id": "2881", + "loc_data": "{2907,4440,0,1,6}-" + }, + { + "npc_id": "2882", + "loc_data": "{2910,4457,0,1,6}-" + }, + { + "npc_id": "2883", + "loc_data": "{2923,4443,0,1,4}-" + }, + { + "npc_id": "2890", + "loc_data": "{1889,4411,0,0,4}-{1895,4409,0,0,2}-{1903,4409,0,0,3}-{1906,4407,0,0,5}-{1903,4400,0,0,1}-{1899,4400,0,0,2}-{1893,4398,0,0,2}-{1888,4386,0,0,6}-{1884,4383,0,0,5}-{1879,4376,0,0,5}-{1883,4376,0,0,1}-{1921,4368,0,0,2}-{1927,4362,0,0,7}-{1935,4360,0,0,7}-{1942,4356,0,0,7}-{1948,4355,0,0,7}-{1951,4358,0,0,2}-{1957,4365,0,0,2}-{1958,4368,0,0,2}-" + }, + { + "npc_id": "2894", + "loc_data": "{2908,4435,0,0,1}-{2924,4436,0,0,5}-{2924,4460,0,0,6}-{2908,4463,0,0,3}-{2901,4458,0,0,3}-{2928,4441,0,0,3}-{2929,4449,0,0,6}-{2902,4437,0,0,1}-" + }, + { + "npc_id": "2910", + "loc_data": "{3082,9885,0,1,4}-" + }, + { + "npc_id": "2932", + "loc_data": "{2437,3347,0,1,0}-" + }, + { + "npc_id": "2935", + "loc_data": "{3671,3484,0,1,4}-" + }, + { + "npc_id": "2939", + "loc_data": "{2657,3701,0,1,0}-" + }, + { + "npc_id": "2940", + "loc_data": "{2675,3671,0,1,3}-" + }, + { + "npc_id": "2942", + "loc_data": "{3017,3234,0,1,7}-" + }, + { + "npc_id": "2943", + "loc_data": "{3265,3400,0,0,0}-" + }, + { + "npc_id": "2945", + "loc_data": "{2562,3319,0,0,0}-" + }, + { + "npc_id": "2946", + "loc_data": "{3246,9865,0,1,1}-" + }, + { + "npc_id": "2947", + "loc_data": "{3245,9868,0,1,3}-" + }, + { + "npc_id": "2948", + "loc_data": "{3265,3403,0,0,0}-" + }, + { + "npc_id": "2949", + "loc_data": "{2562,3320,0,0,0}-" + }, + { + "npc_id": "2950", + "loc_data": "{3020,3229,0,0,7}-" + }, + { + "npc_id": "2997", + "loc_data": "{3308,3511,1,1,1}-" + }, + { + "npc_id": "2998", + "loc_data": "{2657,9641,0,1,0}-" + }, + { + "npc_id": "2999", + "loc_data": "{2658,9634,0,1,1}-" + }, + { + "npc_id": "3001", + "loc_data": "{2646,9639,0,1,4}-" + }, + { + "npc_id": "3002", + "loc_data": "{2666,9630,0,1,6}-" + }, + { + "npc_id": "3003", + "loc_data": "{2660,9624,0,1,6}-" + }, + { + "npc_id": "3020", + "loc_data": "{3348,2942,0,1,3}-" + }, + { + "npc_id": "3021", + "loc_data": "{2572,3105,0,1,0}-{2614,3226,0,1,4}-{3088,3357,0,1,0}-{2856,3435,0,1,0}-{3603,3529,0,1,6}-{2611,3859,0,1,6}-{2589,3863,0,1,0}-{3189,3234,0,1,0}-{2940,3225,0,1,6}-{2663,3374,0,1,4}-{3182,3354,0,1,0}-{2933,3434,0,1,4}-{3449,3471,0,1,6}-{2666,3521,0,1,4}-{2491,3177,0,1,1}-{3007,3371,0,1,2}-{2474,3446,0,1,4}-{2434,3415,0,1,3}-{3232,3459,0,1,3}-{2796,3104,0,1,0}-{2764,3210,0,1,1}-{3315,3205,0,1,6}-{3060,3263,0,1,0}-{3053,3304,0,1,1}-{2812,3333,0,1,4}-{2815,3466,0,1,3}-" + }, + { + "npc_id": "3022", + "loc_data": "{3371,9320,0,0,6}-" + }, + { + "npc_id": "3029", + "loc_data": "{3422,2937,0,1,1}-" + }, + { + "npc_id": "3030", + "loc_data": "{3421,2912,0,0,1}-" + }, + { + "npc_id": "3031", + "loc_data": "{3439,2890,0,0,3}-" + }, + { + "npc_id": "3032", + "loc_data": "{3439,2927,0,1,5}-" + }, + { + "npc_id": "3034", + "loc_data": "{3409,2929,1,1,4}-" + }, + { + "npc_id": "3035", + "loc_data": "{3450,2895,0,0,3}-" + }, + { + "npc_id": "3036", + "loc_data": "{3424,2900,0,1,3}-" + }, + { + "npc_id": "3037", + "loc_data": "{3424,2906,0,0,1}-" + }, + { + "npc_id": "3038", + "loc_data": "{3406,2924,0,1,3}-" + }, + { + "npc_id": "3039", + "loc_data": "{3414,2907,0,1,3}-" + }, + { + "npc_id": "3040", + "loc_data": "{3443,2914,0,0,3}-" + }, + { + "npc_id": "3041", + "loc_data": "{3445,2910,0,0,1}-" + }, + { + "npc_id": "3042", + "loc_data": "{3441,2920,0,1,4}-" + }, + { + "npc_id": "3043", + "loc_data": "{3445,2917,0,0,3}-" + }, + { + "npc_id": "3044", + "loc_data": "{3428,2928,0,1,5}-" + }, + { + "npc_id": "3045", + "loc_data": "{3432,2912,0,0,1}-" + }, + { + "npc_id": "3046", + "loc_data": "{3425,2891,0,0,4}-{3425,2894,0,0,4}-{3425,2893,0,0,4}-{3425,2889,0,0,4}-" + }, + { + "npc_id": "3050", + "loc_data": "{3187,9758,0,1,3}-" + }, + { + "npc_id": "3068", + "loc_data": "{3062,9550,0,1,5}-{3050,9554,0,1,7}-{3048,9545,0,1,4}-{3061,9542,0,1,3}-{3065,9548,0,1,1}-{3034,9544,0,1,4}-{3033,9552,0,1,3}-{3029,9545,0,1,7}-{3027,9555,0,1,3}-" + }, + { + "npc_id": "3072", + "loc_data": "{3207,5448,0,1,3}-{3223,5446,0,1,4}-{3210,5562,0,1,3}-" + }, + { + "npc_id": "3073", + "loc_data": "{3217,5442,0,1,4}-{3231,5444,0,1,0}-" + }, + { + "npc_id": "3074", + "loc_data": "{3404,3492,0,0,6}-" + }, + { + "npc_id": "3076", + "loc_data": "{3403,3492,0,0,0}-" + }, + { + "npc_id": "3090", + "loc_data": "{3082,3442,0,0,0}-" + }, + { + "npc_id": "3094", + "loc_data": "{3361,3306,0,1,6}-" + }, + { + "npc_id": "3095", + "loc_data": "{3364,3309,0,1,3}-{3363,3317,1,1,1}-" + }, + { + "npc_id": "3097", + "loc_data": "{3364,3304,0,1,6}-" + }, + { + "npc_id": "3099", + "loc_data": "{3364,9626,2,1,1}-" + }, + { + "npc_id": "3100", + "loc_data": "{3363,9646,0,1,1}-" + }, + { + "npc_id": "3101", + "loc_data": "{3364,9644,1,1,6}-" + }, + { + "npc_id": "3103", + "loc_data": "{3362,3318,1,0,6}-" + }, + { + "npc_id": "3104", + "loc_data": "{3364,3310,0,1,1}-{3379,9627,0,1,0}-{3367,9647,2,1,4}-" + }, + { + "npc_id": "3105", + "loc_data": "{3367,3304,1,1,1}-{3376,9655,0,1,7}-" + }, + { + "npc_id": "3106", + "loc_data": "{3360,3305,1,1,3}-{3348,9654,0,1,4}-{3362,9648,2,1,4}-" + }, + { + "npc_id": "3107", + "loc_data": "{3361,3306,0,1,3}-{3348,9626,0,1,6}-" + }, + { + "npc_id": "3108", + "loc_data": "{2549,3100,0,0,4}-" + }, + { + "npc_id": "3109", + "loc_data": "{2551,3079,0,1,3}-" + }, + { + "npc_id": "3110", + "loc_data": "{2789,3175,0,0,4}-" + }, + { + "npc_id": "3111", + "loc_data": "{2788,3176,0,0,0}-" + }, + { + "npc_id": "3114", + "loc_data": "{2815,3344,0,1,3}-" + }, + { + "npc_id": "3115", + "loc_data": "{2439,4444,0,1,3}-" + }, + { + "npc_id": "3123", + "loc_data": "{3344,2827,0,1,5}-" + }, + { + "npc_id": "3124", + "loc_data": "{3372,2847,1,0,3}-" + }, + { + "npc_id": "3125", + "loc_data": "{3366,2845,3,0,6}-" + }, + { + "npc_id": "3127", + "loc_data": "{3331,2948,0,1,4}-" + }, + { + "npc_id": "3153", + "loc_data": "{2871,3091,0,1,4}-{2862,3111,0,1,1}-{2861,3101,0,1,3}-{2870,3113,0,1,4}-{2870,3110,0,1,6}-{2865,3103,0,1,3}-{2873,3103,0,1,2}-{2863,3118,0,1,4}-{2886,3109,0,1,1}-{2892,3109,0,1,2}-{2883,3105,0,1,4}-{2889,3111,0,1,6}-{2883,3110,0,1,3}-" + }, + { + "npc_id": "3155", + "loc_data": "{3687,2953,0,1,1}-{3679,3494,0,1,3}-" + }, + { + "npc_id": "3162", + "loc_data": "{3691,2954,0,1,3}-" + }, + { + "npc_id": "3164", + "loc_data": "{3667,2990,0,1,3}-" + }, + { + "npc_id": "3166", + "loc_data": "{3693,2979,0,1,3}-" + }, + { + "npc_id": "3167", + "loc_data": "{3662,2978,1,1,4}-" + }, + { + "npc_id": "3168", + "loc_data": "{3663,2981,0,1,3}-" + }, + { + "npc_id": "3170", + "loc_data": "{3674,2970,0,1,0}-" + }, + { + "npc_id": "3188", + "loc_data": "{3664,2971,0,1,6}-" + }, + { + "npc_id": "3189", + "loc_data": "{3690,2976,0,1,1}-{3671,3006,0,1,6}-" + }, + { + "npc_id": "3191", + "loc_data": "{3659,2955,0,1,3}-{3683,2994,0,1,4}-{3662,3005,0,1,4}-" + }, + { + "npc_id": "3192", + "loc_data": "{3700,2994,0,1,4}-{3683,3005,0,1,3}-" + }, + { + "npc_id": "3193", + "loc_data": "{3696,2993,0,1,3}-{3693,3006,0,1,3}-" + }, + { + "npc_id": "3194", + "loc_data": "{3654,2992,0,1,4}-{3682,2962,0,1,3}-{3704,3006,0,1,0}-" + }, + { + "npc_id": "3195", + "loc_data": "{3696,2978,0,1,1}-" + }, + { + "npc_id": "3196", + "loc_data": "{3649,3004,0,1,6}-" + }, + { + "npc_id": "3198", + "loc_data": "{3682,2982,0,0,3}-" + }, + { + "npc_id": "3199", + "loc_data": "{3682,2981,0,0,3}-{3682,2983,0,0,3}-" + }, + { + "npc_id": "3200", + "loc_data": "{3263,3932,0,1,3}-" + }, + { + "npc_id": "3205", + "loc_data": "{3139,3448,0,1,3}-" + }, + { + "npc_id": "3213", + "loc_data": "{2568,3334,0,1,0}-" + }, + { + "npc_id": "3214", + "loc_data": "{2517,9755,0,1,0}-" + }, + { + "npc_id": "3216", + "loc_data": "{2534,3273,0,0,1}-{2539,3273,0,0,1}-" + }, + { + "npc_id": "3217", + "loc_data": "{2956,3370,0,1,3}-" + }, + { + "npc_id": "3219", + "loc_data": "{3027,3344,0,1,4}-" + }, + { + "npc_id": "3220", + "loc_data": "{3013,3338,0,1,4}-" + }, + { + "npc_id": "3221", + "loc_data": "{3016,3334,0,1,3}-{3016,3339,0,1,6}-{3019,3341,0,1,4}-" + }, + { + "npc_id": "3223", + "loc_data": "{2994,3365,0,1,4}-" + }, + { + "npc_id": "3224", + "loc_data": "{3047,3365,0,1,6}-" + }, + { + "npc_id": "3226", + "loc_data": "{2996,3375,0,1,4}-" + }, + { + "npc_id": "3227", + "loc_data": "{2756,3182,0,1,6}-" + }, + { + "npc_id": "3228", + "loc_data": "{2969,3373,0,1,3}-{2948,3353,0,1,3}-{3036,3357,0,1,3}-" + }, + { + "npc_id": "3229", + "loc_data": "{2912,3344,0,1,7}-{3040,3354,0,1,2}-" + }, + { + "npc_id": "3230", + "loc_data": "{2986,3370,0,1,1}-" + }, + { + "npc_id": "3234", + "loc_data": "{3011,3383,0,1,0}-" + }, + { + "npc_id": "3235", + "loc_data": "{2970,3369,1,1,6}-" + }, + { + "npc_id": "3236", + "loc_data": "{2973,3369,1,1,6}-" + }, + { + "npc_id": "3237", + "loc_data": "{2984,3435,0,0,0}-" + }, + { + "npc_id": "3238", + "loc_data": "{2981,3434,0,0,0}-" + }, + { + "npc_id": "3239", + "loc_data": "{2975,3436,0,0,0}-" + }, + { + "npc_id": "3240", + "loc_data": "{2977,3442,0,0,0}-" + }, + { + "npc_id": "3241", + "loc_data": "{2969,3451,0,1,4}-" + }, + { + "npc_id": "3242", + "loc_data": "{2910,3332,0,1,0}-{2910,3337,0,1,4}-{2904,3331,0,1,3}-{2979,3568,0,1,7}-{2983,3566,0,1,3}-{2979,3566,0,1,3}-{2981,3570,0,1,6}-{2984,3561,0,1,6}-" + }, + { + "npc_id": "3243", + "loc_data": "{2906,3331,0,1,6}-{2909,3333,0,1,6}-" + }, + { + "npc_id": "3244", + "loc_data": "{2909,3333,0,1,1}-" + }, + { + "npc_id": "3245", + "loc_data": "{2907,3336,0,1,0}-" + }, + { + "npc_id": "3246", + "loc_data": "{3071,3446,0,1,6}-{2548,3567,0,1,4}-" + }, + { + "npc_id": "3247", + "loc_data": "{2548,3567,0,1,1}-" + }, + { + "npc_id": "3248", + "loc_data": "{3073,3442,0,1,5}-" + }, + { + "npc_id": "3249", + "loc_data": "{3082,3441,0,1,0}-" + }, + { + "npc_id": "3250", + "loc_data": "{3088,3426,0,1,3}-{2547,3571,0,1,7}-" + }, + { + "npc_id": "3251", + "loc_data": "{3073,3422,0,1,6}-" + }, + { + "npc_id": "3252", + "loc_data": "{3077,3424,0,1,6}-" + }, + { + "npc_id": "3253", + "loc_data": "{2542,3578,0,1,3}-" + }, + { + "npc_id": "3255", + "loc_data": "{3073,3423,0,1,3}-" + }, + { + "npc_id": "3256", + "loc_data": "{3080,3415,0,1,3}-{3084,3415,0,1,6}-" + }, + { + "npc_id": "3257", + "loc_data": "{3096,3432,0,1,0}-" + }, + { + "npc_id": "3258", + "loc_data": "{3080,3444,0,1,3}-" + }, + { + "npc_id": "3259", + "loc_data": "{3075,3438,0,1,4}-" + }, + { + "npc_id": "3260", + "loc_data": "{3083,3425,0,1,3}-{2554,3564,0,1,6}-{2547,3558,0,1,6}-" + }, + { + "npc_id": "3261", + "loc_data": "{3086,3425,0,1,3}-" + }, + { + "npc_id": "3262", + "loc_data": "{3080,3423,0,1,1}-" + }, + { + "npc_id": "3263", + "loc_data": "{3084,3419,0,1,4}-" + }, + { + "npc_id": "3264", + "loc_data": "{3126,3450,0,1,6}-{3121,3422,0,1,3}-{2565,9843,0,1,0}-{3259,3338,0,1,7}-{3311,3375,0,1,0}-" + }, + { + "npc_id": "3265", + "loc_data": "{3121,3427,0,1,2}-{2582,9836,0,1,1}-" + }, + { + "npc_id": "3266", + "loc_data": "{3094,3406,0,1,3}-" + }, + { + "npc_id": "3267", + "loc_data": "{3134,3459,0,1,1}-" + }, + { + "npc_id": "3268", + "loc_data": "{3012,3454,0,1,1}-" + }, + { + "npc_id": "3269", + "loc_data": "{3022,3447,0,1,4}-" + }, + { + "npc_id": "3270", + "loc_data": "{3010,3452,0,1,3}-" + }, + { + "npc_id": "3272", + "loc_data": "{3042,3468,0,1,1}-" + }, + { + "npc_id": "3273", + "loc_data": "{3030,3465,0,1,5}-" + }, + { + "npc_id": "3276", + "loc_data": "{3039,3475,0,1,4}-" + }, + { + "npc_id": "3277", + "loc_data": "{3035,3471,0,1,2}-" + }, + { + "npc_id": "3278", + "loc_data": "{3045,3477,0,1,1}-" + }, + { + "npc_id": "3279", + "loc_data": "{3039,3471,0,1,6}-" + }, + { + "npc_id": "3280", + "loc_data": "{3015,3451,0,0,0}-" + }, + { + "npc_id": "3281", + "loc_data": "{3018,3450,0,0,0}-" + }, + { + "npc_id": "3282", + "loc_data": "{3008,3442,0,0,0}-" + }, + { + "npc_id": "3283", + "loc_data": "{2964,3455,0,0,0}-{3039,3424,0,1,5}-{3043,3429,0,1,4}-{3047,3427,0,1,1}-{3048,3441,0,1,3}-" + }, + { + "npc_id": "3284", + "loc_data": "{2969,3437,0,0,0}-{3058,3419,0,0,0}-{3048,3423,0,1,6}-{3054,3432,0,1,5}-" + }, + { + "npc_id": "3285", + "loc_data": "{2952,3376,0,0,0}-{3036,3430,0,1,3}-{3025,3442,0,0,0}-" + }, + { + "npc_id": "3286", + "loc_data": "{2968,3448,0,1,1}-{3034,3450,0,1,3}-{3057,3447,0,1,6}-" + }, + { + "npc_id": "3287", + "loc_data": "{3073,3443,0,1,0}-{2987,3444,0,1,0}-{3046,3453,0,1,6}-" + }, + { + "npc_id": "3288", + "loc_data": "{2987,3446,0,1,7}-{3034,3437,0,1,0}-" + }, + { + "npc_id": "3294", + "loc_data": "{3014,3339,0,1,2}-" + }, + { + "npc_id": "3295", + "loc_data": "{3020,3337,0,1,1}-" + }, + { + "npc_id": "3296", + "loc_data": "{2957,3359,0,1,0}-{2958,3358,0,1,0}-{2967,3360,0,1,0}-{2970,3361,0,1,0}-{2973,3359,0,1,0}-{2977,3357,0,1,0}-{2989,3384,0,1,0}-" + }, + { + "npc_id": "3298", + "loc_data": "{3366,9637,2,1,3}-" + }, + { + "npc_id": "3299", + "loc_data": "{3077,3257,0,1,1}-" + }, + { + "npc_id": "3302", + "loc_data": "{2453,4449,0,1,2}-" + }, + { + "npc_id": "3307", + "loc_data": "{2467,4438,0,1,4}-{2471,4439,0,1,7}-{2465,4436,0,1,3}-{2464,4432,0,1,4}-" + }, + { + "npc_id": "3308", + "loc_data": "{2905,3333,2,1,0}-" + }, + { + "npc_id": "3310", + "loc_data": "{2415,4451,0,1,6}-{2416,4435,0,1,7}-{2423,4432,0,1,4}-" + }, + { + "npc_id": "3318", + "loc_data": "{2401,4378,0,0,0}-" + }, + { + "npc_id": "3322", + "loc_data": "{2384,4439,0,1,0}-" + }, + { + "npc_id": "3324", + "loc_data": "{3159,3433,0,1,0}-" + }, + { + "npc_id": "3325", + "loc_data": "{3161,3432,1,1,4}-" + }, + { + "npc_id": "3328", + "loc_data": "{3203,3344,0,0,0}-" + }, + { + "npc_id": "3329", + "loc_data": "{3112,3414,0,0,0}-" + }, + { + "npc_id": "3330", + "loc_data": "{3132,3508,0,0,0}-" + }, + { + "npc_id": "3331", + "loc_data": "{3242,3240,0,0,4}-" + }, + { + "npc_id": "3340", + "loc_data": "{1759,5182,0,1,0}-" + }, + { + "npc_id": "3341", + "loc_data": "{1739,5154,0,1,0}-{1759,5191,0,1,0}-{1754,5200,0,1,0}-{1748,5223,0,1,0}-{1784,5199,0,1,0}-" + }, + { + "npc_id": "3342", + "loc_data": "{1768,5175,0,1,0}-{1760,5152,0,1,0}-{1745,5169,0,1,0}-{1745,5208,0,1,0}-{1737,5215,0,1,0}-{1758,5210,0,1,0}-" + }, + { + "npc_id": "3343", + "loc_data": "{1773,5149,0,1,0}-{1764,5198,0,1,0}-{1774,5195,0,1,0}-{1742,5292,0,1,0}-" + }, + { + "npc_id": "3344", + "loc_data": "{2412,4470,0,0,0}-{2414,4467,0,0,0}-{2415,4475,0,0,0}-{2419,4467,0,0,0}-{2419,4474,0,0,0}-" + }, + { + "npc_id": "3345", + "loc_data": "{2412,4370,0,0,0}-{2416,4376,0,0,0}-{2419,4374,0,0,0}-{2420,4377,0,0,0}-{2421,4370,0,0,0}-" + }, + { + "npc_id": "3348", + "loc_data": "{2978,3343,0,1,4}-{2978,3337,0,1,1}-{2966,3337,1,1,6}-{2970,3330,2,1,1}-" + }, + { + "npc_id": "3349", + "loc_data": "{2961,3330,2,1,0}-{2966,3352,2,1,1}-{2974,3328,2,1,6}-" + }, + { + "npc_id": "3350", + "loc_data": "{2959,3340,2,1,3}-" + }, + { + "npc_id": "3376", + "loc_data": "{2438,4393,0,1,1}-{3313,5453,0,1,3}-{3312,5452,0,1,3}-{3310,5452,0,1,6}-{3311,5462,0,1,5}-{3313,5554,0,1,6}-{3297,5562,0,1,1}-{3305,5554,0,1,1}-{3300,5540,0,1,1}-" + }, + { + "npc_id": "3382", + "loc_data": "{3080,9885,0,1,4}-{3076,9886,0,1,4}-{3081,9890,0,1,4}-{3081,9895,0,1,4}-" + }, + { + "npc_id": "3384", + "loc_data": "{3211,3225,0,0,0}-" + }, + { + "npc_id": "3402", + "loc_data": "{2560,2842,0,0,1}-" + }, + { + "npc_id": "3407", + "loc_data": "{3114,3515,0,1,4}-" + }, + { + "npc_id": "3408", + "loc_data": "{3113,3510,0,1,7}-" + }, + { + "npc_id": "3419", + "loc_data": "{2568,2991,0,1,0}-{2574,2988,0,1,0}-{2584,2967,0,1,0}-{2585,2977,0,1,0}-{2592,2965,0,1,0}-{2608,2980,0,1,0}-{2609,2990,0,1,0}-{2614,2998,0,1,0}-{2561,3020,0,1,0}-{2567,3046,0,1,0}-{2585,9608,0,1,0}-{2586,9614,0,1,0}-{2588,9606,0,1,0}-{2581,9738,0,1,0}-{2581,9742,0,1,0}-{2584,9734,0,1,0}-{2585,9738,0,1,0}-{2587,9733,0,1,0}-{2587,9740,0,1,0}-{2590,9737,0,1,0}-{2387,9685,0,1,0}-{2389,9683,0,1,0}-{2719,9668,0,1,0}-{2719,9715,0,1,0}-{2720,9702,0,1,0}-{2722,9669,0,1,0}-{2723,9707,0,1,0}-{2724,9713,0,1,0}-{2504,2965,0,1,0}-{2504,2984,0,1,0}-{2520,2973,0,1,0}-{2525,2986,0,1,0}-{2533,2977,0,1,0}-{2536,2975,0,1,0}-{2539,2990,0,1,0}-{2549,2979,0,1,0}-{2551,2955,0,1,0}-{2552,2961,0,1,0}-{2513,3026,0,1,0}-{2522,3055,0,1,0}-{2523,3057,0,1,0}-{2529,3032,0,1,0}-{2539,3018,0,1,0}-{2541,3016,0,1,0}-{2550,3043,0,1,0}-{2550,3046,0,1,0}-{2553,3047,0,1,0}-{2496,3092,0,1,0}-{2497,3089,0,1,0}-{2500,3092,0,1,0}-{2500,3097,0,1,0}-{2503,3095,0,1,0}-{2504,3133,0,1,0}-{2554,3192,0,1,0}-" + }, + { + "npc_id": "3450", + "loc_data": "{2901,2947,0,0,0}-{2925,2959,0,0,0}-{2920,3053,0,0,0}-{2924,3063,0,0,0}-" + }, + { + "npc_id": "3469", + "loc_data": "{2657,2966,0,0,0}-" + }, + { + "npc_id": "3470", + "loc_data": "{2755,3083,0,0,0}-" + }, + { + "npc_id": "3479", + "loc_data": "{2906,3514,1,0,0}-" + }, + { + "npc_id": "3541", + "loc_data": "{3517,3240,0,1,6}-" + }, + { + "npc_id": "3579", + "loc_data": "{3195,3263,0,1,0}-" + }, + { + "npc_id": "3638", + "loc_data": "{3309,3453,0,0,1}-" + }, + { + "npc_id": "3661", + "loc_data": "{3276,9836,0,1,0}-{3287,9840,0,1,0}-" + }, + { + "npc_id": "3662", + "loc_data": "{3280,9849,0,1,0}-{3286,9830,0,1,0}-" + }, + { + "npc_id": "3663", + "loc_data": "{3269,9849,0,1,0}-{3291,9843,0,1,0}-" + }, + { + "npc_id": "3664", + "loc_data": "{3269,9843,0,1,0}-{3275,9833,0,1,0}-" + }, + { + "npc_id": "3665", + "loc_data": "{3305,9832,0,1,0}-{3305,9843,0,1,0}-{3311,9850,0,1,0}-{3312,9845,0,1,0}-{3313,9827,0,1,0}-{3315,9837,0,1,0}-{3319,9832,0,1,0}-{3319,9849,0,1,0}-{3323,9842,0,1,0}-" + }, + { + "npc_id": "3666", + "loc_data": "{3302,9806,0,1,0}-{3302,9816,0,1,0}-{3304,9801,0,1,0}-{3310,9796,0,1,0}-{3312,9811,0,1,0}-{3313,9805,0,1,0}-{3313,9817,0,1,0}-{3314,9797,0,1,0}-{3319,9800,0,1,0}-{3319,9806,0,1,0}-{3321,9811,0,1,0}-" + }, + { + "npc_id": "3667", + "loc_data": "{3269,9798,0,1,0}-{3269,9806,0,1,0}-{3269,9814,0,1,0}-{3275,9817,0,1,0}-{3276,9809,0,1,0}-{3280,9803,0,1,0}-{3282,9797,0,1,0}-{3285,9812,0,1,0}-{3288,9819,0,1,0}-{3289,9809,0,1,0}-{3290,9797,0,1,0}-" + }, + { + "npc_id": "3670", + "loc_data": "{3361,3505,0,1,0}-" + }, + { + "npc_id": "3671", + "loc_data": "{3085,3251,0,0,3}-" + }, + { + "npc_id": "3673", + "loc_data": "{2322,3189,0,1,0}-{3195,3265,0,1,0}-{2924,3318,0,1,0}-{2924,3325,0,1,4}-{2656,3359,0,1,0}-{2656,3375,0,1,0}-{2653,4716,0,1,0}-{3248,3351,0,1,0}-" + }, + { + "npc_id": "3675", + "loc_data": "{3333,2864,0,1,1}-{3335,2860,0,1,2}-{3338,2864,0,1,4}-{3215,2841,0,1,0}-{3217,2845,0,1,0}-{3220,2841,0,1,0}-{3295,2866,0,1,0}-{3297,2863,0,1,0}-{3301,2864,0,1,0}-{3336,2778,0,1,0}-{3343,2793,0,1,0}-{3367,2791,0,1,0}-" + }, + { + "npc_id": "3677", + "loc_data": "{2637,3440,0,0,0}-" + }, + { + "npc_id": "3679", + "loc_data": "{2875,3482,0,0,4}-" + }, + { + "npc_id": "3680", + "loc_data": "{3282,3327,0,1,7}-" + }, + { + "npc_id": "3695", + "loc_data": "{2661,3701,0,1,0}-" + }, + { + "npc_id": "3696", + "loc_data": "{2673,3658,0,1,3}-" + }, + { + "npc_id": "3707", + "loc_data": "{2713,10133,0,1,2}-{2708,10133,0,1,4}-{2706,10135,0,0,3}-{2708,10133,0,1,3}-{2703,10135,0,1,6}-{2702,10131,0,1,4}-{2717,10133,0,1,0}-{2708,10130,0,1,1}-" + }, + { + "npc_id": "3709", + "loc_data": "{2847,5075,0,0,0}-{2974,2906,0,0,0}-" + }, + { + "npc_id": "3711", + "loc_data": "{2575,9746,0,1,0}-{2581,9747,0,1,0}-{2577,9743,0,1,1}-{2579,9740,0,1,0}-{2588,9733,0,1,4}-" + }, + { + "npc_id": "3777", + "loc_data": "{3230,3231,0,1,5}-" + }, + { + "npc_id": "3778", + "loc_data": "{1867,4233,0,0,0}-" + }, + { + "npc_id": "3780", + "loc_data": "{1906,4281,0,0,0}-" + }, + { + "npc_id": "3781", + "loc_data": "{2659,2675,0,1,1}-" + }, + { + "npc_id": "3786", + "loc_data": "{2658,2666,0,1,1}-" + }, + { + "npc_id": "3787", + "loc_data": "{2754,3509,0,0,0}-" + }, + { + "npc_id": "3788", + "loc_data": "{2664,2653,0,1,3}-" + }, + { + "npc_id": "3789", + "loc_data": "{2660,2649,0,1,3}-" + }, + { + "npc_id": "3790", + "loc_data": "{3041,3203,0,0,6}-" + }, + { + "npc_id": "3791", + "loc_data": "{2653,2655,0,1,1}-" + }, + { + "npc_id": "3793", + "loc_data": "{2659,2660,0,1,6}-" + }, + { + "npc_id": "3796", + "loc_data": "{2667,2661,0,0,3}-" + }, + { + "npc_id": "3797", + "loc_data": "{2649,2659,0,0,2}-" + }, + { + "npc_id": "3798", + "loc_data": "{2658,2652,0,1,6}-" + }, + { + "npc_id": "3799", + "loc_data": "{2650,2663,0,0,4}-" + }, + { + "npc_id": "3802", + "loc_data": "{2657,2637,0,0,6}-" + }, + { + "npc_id": "3804", + "loc_data": "{3349,3793,0,0,0}-" + }, + { + "npc_id": "3805", + "loc_data": "{2445,3097,0,1,5}-" + }, + { + "npc_id": "3806", + "loc_data": "{3166,3304,0,1,0}-" + }, + { + "npc_id": "3807", + "loc_data": "{3254,3274,0,0,0}-" + }, + { + "npc_id": "3808", + "loc_data": "{2422,3526,0,1,1}-{2517,3205,0,1,3}-{2513,3204,0,1,3}-" + }, + { + "npc_id": "3809", + "loc_data": "{3285,3213,0,1,1}-" + }, + { + "npc_id": "3810", + "loc_data": "{2847,3499,0,1,7}-{2970,2973,0,0,0}-" + }, + { + "npc_id": "3811", + "loc_data": "{2894,2730,0,1,2}-{2918,3057,0,0,0}-{2465,3501,3,1,3}-" + }, + { + "npc_id": "3813", + "loc_data": "{2541,2969,0,1,4}-" + }, + { + "npc_id": "3817", + "loc_data": "{2521,3208,0,1,1}-" + }, + { + "npc_id": "3819", + "loc_data": "{2416,3525,0,1,3}-{2412,3527,0,1,6}-" + }, + { + "npc_id": "3820", + "loc_data": "{3088,3255,0,0,6}-" + }, + { + "npc_id": "3822", + "loc_data": "{2353,3680,0,1,3}-" + }, + { + "npc_id": "3823", + "loc_data": "{2343,3668,0,1,3}-" + }, + { + "npc_id": "3824", + "loc_data": "{2329,3689,0,1,6}-" + }, + { + "npc_id": "3831", + "loc_data": "{2357,3637,0,0,0}-" + }, + { + "npc_id": "3832", + "loc_data": "{2345,3651,0,0,0}-" + }, + { + "npc_id": "3848", + "loc_data": "{2337,3703,0,0,6}-{2340,3702,0,0,6}-{2343,3702,0,0,3}-{2349,3702,0,0,6}-{2353,3703,0,0,6}-{2310,3704,0,0,6}-{2311,3696,0,0,4}-{2343,3702,0,0,3}-" + }, + { + "npc_id": "3851", + "loc_data": "{2332,3669,0,0,0}-{2325,3671,0,0,4}-{2331,3670,0,0,1}-{2333,3671,0,0,3}-" + }, + { + "npc_id": "3915", + "loc_data": "{2945,3146,0,1,3}-" + }, + { + "npc_id": "3916", + "loc_data": "{2595,3890,0,0,3}-" + }, + { + "npc_id": "3917", + "loc_data": "{2581,3861,0,0,1}-" + }, + { + "npc_id": "3920", + "loc_data": "{2527,10259,0,1,1}-" + }, + { + "npc_id": "3921", + "loc_data": "{2506,10251,0,1,1}-" + }, + { + "npc_id": "3922", + "loc_data": "{2508,10260,0,1,1}-" + }, + { + "npc_id": "3923", + "loc_data": "{2521,10251,0,1,1}-" + }, + { + "npc_id": "3937", + "loc_data": "{2508,3866,0,0,3}-" + }, + { + "npc_id": "4235", + "loc_data": "{2669,3332,0,0,1}-" + }, + { + "npc_id": "4237", + "loc_data": "{2669,3331,0,0,6}-" + }, + { + "npc_id": "4239", + "loc_data": "{2669,3331,0,0,6}-" + }, + { + "npc_id": "4241", + "loc_data": "{2669,3331,0,0,6}-" + }, + { + "npc_id": "4243", + "loc_data": "{2669,3331,0,0,6}-" + }, + { + "npc_id": "4246", + "loc_data": "{3480,3484,1,0,0}-{3479,3484,0,1,3}-" + }, + { + "npc_id": "4247", + "loc_data": "{2639,3291,0,0,0}-{2981,3370,0,0,0}-{2737,3500,0,1,6}-{3240,3474,0,0,0}-" + }, + { + "npc_id": "4248", + "loc_data": "{2849,10183,0,1,0}-" + }, + { + "npc_id": "4249", + "loc_data": "{2981,3341,1,0,0}-" + }, + { + "npc_id": "4250", + "loc_data": "{3302,3492,0,1,6}-" + }, + { + "npc_id": "4251", + "loc_data": "{3009,3380,0,1,0}-" + }, + { + "npc_id": "4261", + "loc_data": "{2569,9851,0,1,3}-{2579,9851,0,1,4}-" + }, + { + "npc_id": "4263", + "loc_data": "{2584,9838,0,1,6}-" + }, + { + "npc_id": "4264", + "loc_data": "{2588,9837,0,1,4}-" + }, + { + "npc_id": "4269", + "loc_data": "{2608,9817,0,1,3}-" + }, + { + "npc_id": "4270", + "loc_data": "{2593,9820,0,1,4}-" + }, + { + "npc_id": "4271", + "loc_data": "{2596,9822,0,1,0}-" + }, + { + "npc_id": "4273", + "loc_data": "{2564,9851,0,1,4}-" + }, + { + "npc_id": "4274", + "loc_data": "{2586,9826,0,1,7}-{2569,9849,0,1,4}-{2581,9847,0,1,0}-{2609,9826,0,1,1}-" + }, + { + "npc_id": "4275", + "loc_data": "{2594,9817,0,1,0}-" + }, + { + "npc_id": "4276", + "loc_data": "{2581,9851,0,1,1}-" + }, + { + "npc_id": "4285", + "loc_data": "{2880,3546,0,0,4}-" + }, + { + "npc_id": "4287", + "loc_data": "{2840,3541,1,0,2}-" + }, + { + "npc_id": "4288", + "loc_data": "{2851,3554,0,1,6}-" + }, + { + "npc_id": "4289", + "loc_data": "{2845,3539,2,0,7}-{2792,3488,2,0,0}-" + }, + { + "npc_id": "4290", + "loc_data": "{2854,3542,0,1,3}-" + }, + { + "npc_id": "4291", + "loc_data": "{2863,3546,2,1,3}-{2870,3551,2,1,0}-{2850,3547,2,1,0}-{2844,3552,2,1,5}-{2843,3547,2,1,5}-{2872,3542,2,1,3}-{2861,3551,2,1,1}-{2865,3538,2,1,2}-" + }, + { + "npc_id": "4292", + "loc_data": "{2847,3541,2,1,3}-{2855,3554,2,1,5}-{2860,3542,2,1,0}-{2869,3554,2,1,3}-{2872,3537,2,1,4}-{2850,3534,2,1,3}-{2857,3546,2,1,0}-{2838,3554,2,1,6}-{2869,3552,2,1,4}-" + }, + { + "npc_id": "4293", + "loc_data": "{2840,3554,0,1,1}-" + }, + { + "npc_id": "4294", + "loc_data": "{2847,3553,0,1,6}-" + }, + { + "npc_id": "4295", + "loc_data": "{2856,3537,1,1,1}-" + }, + { + "npc_id": "4296", + "loc_data": "{2841,3543,0,0,4}-" + }, + { + "npc_id": "4297", + "loc_data": "{2856,3549,1,0,2}-" + }, + { + "npc_id": "4298", + "loc_data": "{2864,3541,1,1,3}-" + }, + { + "npc_id": "4299", + "loc_data": "{2866,3556,1,0,5}-" + }, + { + "npc_id": "4300", + "loc_data": "{2865,3544,1,0,6}-" + }, + { + "npc_id": "4312", + "loc_data": "{3323,9609,0,0,6}-" + }, + { + "npc_id": "4315", + "loc_data": "{3224,3286,0,0,0}-" + }, + { + "npc_id": "4317", + "loc_data": "{3230,3285,0,0,0}-" + }, + { + "npc_id": "4344", + "loc_data": "{3733,2972,0,1,4}-{3747,3013,0,1,4}-{3766,3034,0,1,6}-" + }, + { + "npc_id": "4346", + "loc_data": "{3714,2952,0,1,1}-{3786,9463,0,1,6}-" + }, + { + "npc_id": "4347", + "loc_data": "{3749,2978,0,1,7}-{3756,2966,0,1,2}-{3759,2962,0,1,2}-{3749,2968,0,1,2}-{3757,2980,0,0,5}-{3728,3043,0,1,4}-{3725,3015,0,1,0}-{3722,3021,0,1,6}-{3717,3017,0,1,7}-{3723,3019,0,1,5}-{3731,3018,0,1,1}-{3734,3028,0,1,7}-{3743,3038,0,1,4}-{3742,3036,0,1,1}-{3747,3040,0,1,4}-{3748,3030,0,1,6}-{3748,3019,0,1,1}-{3745,3016,0,1,4}-{3741,3020,0,1,3}-{3727,3039,0,1,3}-{3734,3046,0,1,1}-{3736,3050,0,1,6}-{3735,3053,0,1,3}-{3741,3053,0,1,6}-{3756,3030,0,1,3}-{3754,3024,0,1,4}-{3769,3039,0,1,6}-{3766,3045,0,1,7}-{3764,3042,0,1,1}-" + }, + { + "npc_id": "4348", + "loc_data": "{3676,3017,0,1,3}-{3687,3018,0,1,3}-{3707,3015,0,1,6}-{3729,3021,0,1,3}-" + }, + { + "npc_id": "4349", + "loc_data": "{3664,3018,0,1,6}-{3658,3012,0,1,4}-{3729,2984,0,1,4}-{3720,3000,0,1,4}-{3718,3030,0,1,4}-{3757,3009,0,1,3}-{3727,3051,0,1,4}-{3809,3028,0,1,6}-" + }, + { + "npc_id": "4350", + "loc_data": "{3680,3026,0,1,4}-{3675,3029,0,1,3}-{3711,3028,0,1,4}-{3698,3046,0,1,6}-{3733,3011,0,1,4}-{3793,3036,0,1,4}-" + }, + { + "npc_id": "4351", + "loc_data": "{3694,3019,0,1,4}-{3728,2965,0,1,7}-{3760,3015,0,1,1}-{3758,3034,0,1,2}-{3714,3049,0,1,7}-{3770,3008,0,1,4}-{3787,3026,0,1,6}-" + }, + { + "npc_id": "4352", + "loc_data": "{3683,3034,0,1,4}-{3747,3007,0,1,4}-{3735,2957,0,1,2}-{3727,3003,0,1,3}-{3719,3037,0,1,7}-{3770,3027,0,1,5}-{3719,3011,0,1,3}-{3787,3035,0,1,1}-" + }, + { + "npc_id": "4353", + "loc_data": "{3719,9358,0,1,6}-{3738,9378,0,1,0}-{3765,9422,0,1,1}-{3741,9436,0,1,6}-{3727,9455,0,1,2}-{3737,9413,0,1,0}-{3735,9444,0,1,3}-{3780,9456,0,1,2}-{3827,9430,0,1,2}-{3819,9422,0,1,2}-" + }, + { + "npc_id": "4354", + "loc_data": "{3739,9369,0,1,0}-{3737,9350,0,1,4}-{3721,9349,0,1,4}-{3733,9396,0,1,6}-{3764,9404,0,1,6}-{3732,9368,0,1,1}-{3749,9461,0,1,0}-{3746,9423,0,1,0}-{3760,9417,0,1,3}-{3760,9451,0,1,6}-{3813,9445,0,1,0}-{3786,9443,0,1,6}-{3783,9430,0,1,5}-{3821,9443,0,1,4}-{3790,9456,0,1,7}-" + }, + { + "npc_id": "4355", + "loc_data": "{3728,9349,0,1,3}-{3752,9398,0,1,4}-{3723,9377,0,1,4}-{3749,9413,0,1,4}-{3721,9419,0,1,3}-{3754,9408,0,1,4}-{3810,9448,0,1,4}-{3786,9412,0,1,3}-{3797,9452,0,1,4}-" + }, + { + "npc_id": "4356", + "loc_data": "{3755,9391,0,1,5}-{3723,9441,0,1,4}-{3766,9459,0,1,4}-{3748,9450,0,1,6}-{3765,9424,0,1,2}-{3800,9414,0,1,2}-{3821,9418,0,1,3}-{3810,9462,0,1,0}-{3809,9440,0,1,2}-{3787,9464,0,1,0}-" + }, + { + "npc_id": "4357", + "loc_data": "{3771,9450,0,1,4}-{3730,9443,0,1,4}-{3808,9423,0,1,7}-{3797,9427,0,1,4}-{3833,9438,0,1,6}-{3834,9458,0,1,6}-{3797,9440,0,1,1}-{3793,9441,0,1,4}-{3829,9425,0,1,7}-" + }, + { + "npc_id": "4358", + "loc_data": "{3751,2977,0,1,2}-" + }, + { + "npc_id": "4359", + "loc_data": "{3669,2977,0,1,3}-" + }, + { + "npc_id": "4375", + "loc_data": "{3013,3192,1,0,6}-" + }, + { + "npc_id": "4376", + "loc_data": "{3081,3421,0,1,3}-" + }, + { + "npc_id": "4381", + "loc_data": "{2361,5241,0,1,1}-{2358,5240,0,1,1}-{2362,5239,0,1,1}-{2364,5240,0,1,1}-{2364,5242,0,1,1}-{2357,5242,0,1,1}-{2356,5240,0,1,1}-{2356,5242,0,1,1}-{2360,5243,0,1,1}-" + }, + { + "npc_id": "4382", + "loc_data": "{2324,5210,0,1,2}-{2322,5201,0,1,7}-{2324,5210,0,1,2}-{2322,5201,0,1,7}-{2327,5205,0,1,7}-{2328,5200,0,1,7}-{2326,5198,0,1,7}-{2331,5198,0,1,4}-{2333,5201,0,1,4}-{2333,5199,0,1,2}-{3139,3747,0,1,0}-{3141,3737,0,1,0}-{3157,3735,0,1,0}-{3165,3746,0,1,0}-{3164,3727,0,1,0}-{3172,3713,0,1,0}-{3177,3724,0,1,0}-" + }, + { + "npc_id": "4383", + "loc_data": "{2321,5225,0,1,3}-{2321,5223,0,1,4}-{2317,5229,0,1,7}-{2322,5225,0,1,1}-{2325,5231,0,1,6}-{2321,5225,0,1,1}-{2314,5227,0,1,2}-{2312,5229,0,1,2}-{2330,5229,0,1,1}-{2324,5233,0,1,4}-{2320,5232,0,1,3}-{2324,5237,0,1,1}-{2329,5229,0,1,6}-{2315,5227,0,1,7}-{2318,5226,0,1,6}-{2322,5222,0,1,6}-" + }, + { + "npc_id": "4384", + "loc_data": "{2355,5204,0,1,3}-{2347,5195,0,1,0}-{2336,5202,0,1,4}-{2332,5201,0,1,3}-{2327,5201,0,1,1}-{2328,5199,0,1,6}-" + }, + { + "npc_id": "4385", + "loc_data": "{2350,5201,0,1,1}-{2353,5192,0,1,1}-{2324,5203,0,1,1}-{2333,5204,0,1,4}-{2326,5197,0,1,5}-{2264,5136,0,1,6}-" + }, + { + "npc_id": "4386", + "loc_data": "{3097,3728,0,1,0}-{3130,3754,0,1,0}-{3128,3719,0,1,0}-{2311,5187,0,1,6}-" + }, + { + "npc_id": "4387", + "loc_data": "{2350,5192,0,1,6}-{2350,5191,0,1,4}-{2347,5188,0,1,2}-" + }, + { + "npc_id": "4388", + "loc_data": "{2305,5231,0,1,2}-{2312,5225,0,1,2}-{2314,5240,0,1,2}-{2310,5241,0,1,2}-{2308,5246,0,1,2}-{2309,5245,0,1,2}-{2315,5237,0,1,2}-" + }, + { + "npc_id": "4389", + "loc_data": "{2013,5238,0,1,0}-{2043,5233,0,1,0}-{2041,5231,0,1,0}-{2029,5233,0,1,0}-{2020,5238,0,1,0}-" + }, + { + "npc_id": "4390", + "loc_data": "{2040,5190,0,1,3}-{2044,5187,0,1,2}-{2042,5191,0,1,1}-{2045,5190,0,1,7}-{2041,5187,0,1,2}-{2045,5186,0,1,2}-{2044,5188,0,1,2}-{2042,5192,0,1,2}-" + }, + { + "npc_id": "4391", + "loc_data": "{1952,5192,0,1,2}-{1993,5240,0,1,4}-{1991,5235,0,1,4}-{1990,5240,0,1,3}-{1989,5237,0,1,6}-{2009,5202,0,1,1}-{2005,5199,0,1,3}-{1994,5236,0,1,6}-{1991,5242,0,1,6}-{2007,5201,0,1,6}-{2009,5201,0,1,6}-{2004,5197,0,1,6}-{2004,5207,0,1,6}-{2006,5205,0,1,6}-" + }, + { + "npc_id": "4392", + "loc_data": "{2033,5233,0,1,4}-{2033,5233,0,1,7}-{2026,5236,0,1,1}-" + }, + { + "npc_id": "4393", + "loc_data": "{2045,5222,0,1,4}-{1993,5190,0,1,6}-{1993,5190,0,1,4}-{2044,5216,0,1,4}-{2008,5203,0,1,1}-{2006,5208,0,1,1}-{2037,5214,0,1,3}-{2037,5210,0,1,1}-{2043,5217,0,1,1}-{2040,5214,0,1,1}-{2042,5217,0,1,1}-{2038,5214,0,1,1}-{2041,5218,0,1,1}-" + }, + { + "npc_id": "4394", + "loc_data": "{1997,5244,0,1,3}-{1992,5238,0,1,5}-{1990,5234,0,1,1}-{2010,5191,0,1,7}-{2018,5188,0,1,4}-{1989,5231,0,1,4}-{2018,5187,0,1,6}-" + }, + { + "npc_id": "4395", + "loc_data": "{2016,5237,0,1,7}-{1988,5190,0,1,2}-{2039,5216,0,1,6}-{2017,5238,0,1,6}-" + }, + { + "npc_id": "4396", + "loc_data": "{2034,5243,0,1,5}-{2034,5239,0,1,5}-{2032,5243,0,1,4}-{2034,5232,0,1,1}-{2033,5240,0,1,1}-{2029,5230,0,1,6}-{2030,5234,0,1,4}-{2029,5230,0,1,1}-{2029,5233,0,1,2}-{2031,5244,0,1,1}-{2039,5208,0,1,4}-{2029,5235,0,1,6}-{2028,5234,0,1,6}-{2030,5237,0,1,4}-{2033,5238,0,1,4}-{2030,5238,0,1,4}-{2032,5238,0,1,3}-{2027,5238,0,1,6}-{2034,5239,0,1,0}-{2016,5235,0,1,5}-{2015,5237,0,1,3}-{2004,5244,0,1,4}-{2005,5241,0,1,4}-{2035,5245,0,1,5}-{2004,5240,0,1,1}-{2027,5235,0,1,5}-{2027,5235,0,1,4}-{2027,5236,0,1,6}-{1999,5244,0,1,4}-{1995,5234,0,1,6}-{1993,5242,0,1,1}-{1990,5239,0,1,1}-{1990,5243,0,1,7}-{1989,5230,0,1,6}-{1990,5224,0,1,5}-{1993,5222,0,1,7}-{1986,5221,0,1,3}-{1990,5221,0,1,3}-{1986,5222,0,1,6}-{2002,5215,0,1,1}-{1996,5215,0,1,1}-{1994,5215,0,1,2}-{2002,5215,0,1,6}-{1995,5208,0,1,1}-{1993,5206,0,1,4}-{1986,5204,0,1,3}-{1986,5201,0,1,6}-{2001,5201,0,1,6}-{1987,5200,0,1,3}-{1986,5199,0,1,6}-{2009,5198,0,1,6}-{1995,5197,0,1,3}-{2009,5194,0,1,3}-{2005,5191,0,1,3}-{2004,5190,0,1,4}-{1991,5190,0,1,1}-{2003,5185,0,1,4}-{2004,5190,0,1,4}-{2004,5188,0,1,1}-{2005,5188,0,1,6}-{2008,5192,0,1,6}-{2008,5193,0,1,3}-{2009,5200,0,1,7}-{2010,5192,0,1,4}-{2010,5194,0,1,4}-{2013,5190,0,1,6}-{2018,5189,0,1,6}-{2018,5192,0,1,6}-{2018,5187,0,1,4}-{1993,5205,0,1,4}-{1994,5206,0,1,3}-{1989,5206,0,1,0}-{1993,5210,0,1,3}-{1989,5200,0,1,4}-{2002,5215,0,1,1}-{2022,5193,0,1,3}-{1995,5220,0,1,1}-{1992,5222,0,1,6}-{1992,5222,0,1,6}-{1988,5201,0,1,4}-{1988,5224,0,1,4}-{1989,5206,0,1,4}-{1987,5225,0,1,4}-{1988,5225,0,1,4}-{1986,5204,0,1,3}-{1987,5226,0,1,4}-{1990,5227,0,1,3}-{1993,5200,0,1,7}-{1990,5228,0,1,4}-{2004,5200,0,1,6}-{1990,5227,0,1,4}-{1990,5224,0,1,6}-{1994,5223,0,1,4}-{2036,5201,0,1,6}-{2038,5215,0,1,4}-{2042,5208,0,1,1}-{2045,5204,0,1,1}-{2046,5205,0,1,3}-{2028,5195,0,1,3}-{2026,5195,0,1,0}-{2039,5193,0,1,3}-{2025,5193,0,1,1}-{2022,5193,0,1,6}-{2043,5192,0,1,2}-{2018,5192,0,1,1}-{2045,5192,0,1,1}-{2032,5190,0,1,1}-{2030,5189,0,1,4}-{2024,5187,0,1,3}-{2038,5186,0,1,4}-{2038,5185,0,1,3}-{2033,5185,0,1,3}-{2016,5186,0,1,1}-{2017,5194,0,1,1}-{2024,5193,0,1,4}-{2008,5201,0,1,4}-{2005,5220,0,1,1}-{2005,5204,0,1,4}-{2037,5203,0,1,3}-{2037,5206,0,1,4}-{2041,5208,0,1,1}-" + }, + { + "npc_id": "4397", + "loc_data": "{2072,5200,0,1,5}-{2145,5251,0,1,3}-{2153,5253,0,1,1}-{2149,5255,0,1,3}-{2146,5252,0,1,5}-{2146,5261,0,1,6}-{2147,5254,0,1,4}-" + }, + { + "npc_id": "4398", + "loc_data": "{2160,5282,0,1,3}-{2162,5284,0,1,1}-{2164,5281,0,1,7}-" + }, + { + "npc_id": "4399", + "loc_data": "{2080,5240,0,1,2}-{2122,5290,0,1,0}-{2131,5297,0,1,6}-{2119,5297,0,1,4}-{2120,5302,0,1,3}-{2129,5306,0,1,3}-{2123,5304,0,1,1}-{2130,5306,0,1,4}-{2163,5301,0,1,5}-{2166,5306,0,1,0}-{2169,5303,0,1,4}-{2122,5291,0,1,0}-{2119,5296,0,1,3}-{2131,5297,0,1,6}-{2125,5302,0,1,0}-{2127,5304,0,1,4}-{2165,5302,0,1,3}-{2163,5301,0,1,4}-{2168,5306,0,1,4}-{2132,5300,0,1,6}-{2132,5302,0,1,4}-" + }, + { + "npc_id": "4400", + "loc_data": "{2072,5200,0,1,7}-{2130,5267,0,1,7}-{2140,5252,0,1,5}-{2141,5252,0,1,1}-{2142,5252,0,1,0}-{2148,5255,0,1,3}-{2125,5270,0,1,1}-{2148,5257,0,1,1}-{2117,5274,0,1,4}-{2146,5307,0,1,2}-{2145,5305,0,1,5}-{2152,5307,0,1,4}-{2148,5252,0,1,0}-{2142,5262,0,1,3}-{2124,5275,0,1,4}-{2121,5276,0,1,3}-{2148,5304,0,1,0}-{2146,5305,0,1,5}-{2148,5304,0,1,1}-{2151,5304,0,1,6}-{2145,5306,0,1,3}-{2134,5272,0,1,6}-{2151,5307,0,1,6}-{2151,5308,0,1,6}-{2149,5307,0,1,6}-{2150,5308,0,1,6}-{2150,5305,0,1,6}-{2153,5307,0,1,6}-{2152,5305,0,1,6}-{2128,5272,0,1,6}-{2129,5272,0,1,6}-{2124,5271,0,1,6}-{2124,5272,0,1,6}-{2122,5272,0,1,6}-{2121,5275,0,1,6}-{3018,10313,0,1,4}-{3016,10315,0,1,4}-{3018,10322,0,1,4}-{3024,10326,0,1,3}-{3030,10332,0,1,4}-{3029,10337,0,1,6}-{3034,10342,0,1,3}-" + }, + { + "npc_id": "4401", + "loc_data": "{2072,5200,0,1,6}-{2096,5248,0,1,6}-{2124,5273,0,1,1}-{2128,5270,0,1,4}-{2117,5274,0,1,3}-{2154,5273,0,1,3}-{2167,5259,0,1,6}-{2170,5257,0,1,1}-{2170,5256,0,1,0}-{2171,5256,0,1,4}-{2167,5256,0,1,3}-{2153,5273,0,1,3}-{2153,5270,0,1,1}-{2171,5255,0,1,2}-{2168,5250,0,1,4}-{2168,5251,0,1,3}-{2131,5264,0,1,6}-{2157,5272,0,1,6}-{2150,5268,0,1,0}-{2133,5272,0,1,2}-{2157,5274,0,1,1}-{2156,5270,0,1,3}-{2154,5271,0,1,5}-" + }, + { + "npc_id": "4402", + "loc_data": "{2080,5240,0,1,5}-{2171,5283,0,1,6}-{2170,5287,0,1,6}-{2170,5281,0,1,6}-{2172,5272,0,1,4}-{2172,5272,0,1,4}-" + }, + { + "npc_id": "4403", + "loc_data": "{2096,5248,0,1,4}-{2172,5276,0,1,1}-{2172,5284,0,1,1}-{2172,5281,0,1,2}-" + }, + { + "npc_id": "4404", + "loc_data": "{1872,5242,0,1,3}-{1873,5230,0,1,2}-{1870,5235,0,1,3}-{1872,5217,0,1,6}-{1873,5212,0,1,4}-{1877,5218,0,1,2}-{1877,5216,0,1,3}-{1875,5218,0,1,6}-{1871,5191,0,1,4}-{1868,5188,0,1,4}-{1861,5189,0,1,3}-{1882,5216,0,1,6}-{1874,5215,0,1,5}-{1873,5238,0,1,3}-" + }, + { + "npc_id": "4406", + "loc_data": "{1848,5176,0,1,2}-{1898,5197,0,1,6}-{1898,5191,0,1,7}-{1890,5195,0,1,3}-{1893,5191,0,1,4}-{1903,5190,0,1,0}-{1889,5190,0,1,3}-{1889,5190,0,1,4}-{1885,5191,0,1,4}-{1900,5208,0,1,1}-{1900,5210,0,1,1}-{1903,5243,0,1,6}-{1901,5245,0,1,4}-{1894,5243,0,1,5}-{1890,5242,0,1,6}-{1889,5244,0,1,4}-{1897,5196,0,1,1}-{1902,5207,0,1,3}-" + }, + { + "npc_id": "4407", + "loc_data": "{1860,5226,0,1,0}-{1859,5200,0,1,0}-{1860,5222,0,1,4}-{1865,5205,0,1,4}-{1862,5205,0,1,7}-{1862,5205,0,1,7}-{1864,5206,0,1,7}-" + }, + { + "npc_id": "4408", + "loc_data": "{1860,5215,0,1,5}-{1864,5218,0,1,1}-" + }, + { + "npc_id": "4409", + "loc_data": "{1864,5226,0,1,1}-{1859,5220,0,1,4}-{1861,5224,0,1,6}-" + }, + { + "npc_id": "4410", + "loc_data": "{1848,5176,0,1,2}-{1890,5205,0,1,6}-{1897,5232,0,1,6}-{1906,5236,0,1,3}-{1904,5235,0,1,6}-{1895,5227,0,1,3}-{1863,5221,0,1,4}-" + }, + { + "npc_id": "4411", + "loc_data": "{1882,5201,0,1,0}-{1884,5207,0,1,3}-{1912,5239,0,1,4}-{1912,5244,0,1,5}-{1890,5204,0,1,5}-" + }, + { + "npc_id": "4412", + "loc_data": "{1880,5200,0,1,6}-{1911,5241,0,1,0}-{1893,5228,0,1,3}-" + }, + { + "npc_id": "4413", + "loc_data": "{2645,3580,0,1,4}-{1871,5228,0,1,6}-{1872,5233,0,1,1}-" + }, + { + "npc_id": "4414", + "loc_data": "{1890,5215,0,1,5}-{1892,5216,0,1,1}-{1889,5223,0,1,3}-{1892,5224,0,1,2}-{1893,5219,0,1,5}-" + }, + { + "npc_id": "4415", + "loc_data": "{1848,5176,0,1,2}-{1874,5230,0,1,3}-{1870,5232,0,1,4}-{1858,5235,0,1,3}-{1871,5241,0,1,7}-{1860,5223,0,1,4}-{1862,5222,0,1,4}-{1874,5234,0,1,5}-{1874,5230,0,1,5}-{1875,5219,0,1,5}-{1876,5215,0,1,3}-{1876,5220,0,1,6}-{1859,5206,0,1,5}-{1877,5216,0,1,4}-{1862,5201,0,1,5}-{1858,5201,0,1,6}-{1874,5201,0,1,2}-{1858,5202,0,1,0}-{1860,5200,0,1,7}-{1875,5197,0,1,6}-{1875,5201,0,1,2}-{1861,5194,0,1,3}-{1861,5224,0,1,6}-{1860,5192,0,1,2}-{1874,5188,0,1,7}-{1867,5188,0,1,4}-{1866,5189,0,1,4}-{1876,5189,0,1,1}-{1876,5196,0,1,3}-{1876,5188,0,1,4}-{1876,5191,0,1,4}-{1877,5191,0,1,4}-{1877,5197,0,1,6}-{1881,5198,0,1,4}-{1882,5197,0,1,5}-{1883,5203,0,1,3}-{1882,5198,0,1,4}-{1863,5205,0,1,4}-{1883,5205,0,1,5}-{1861,5205,0,1,5}-{1887,5204,0,1,3}-{1883,5205,0,1,3}-{1884,5206,0,1,1}-{1876,5215,0,1,6}-{1879,5215,0,1,2}-{1870,5217,0,1,6}-{1881,5221,0,1,1}-{1871,5218,0,1,1}-{1872,5191,0,1,3}-{1874,5219,0,1,5}-{1884,5228,0,1,4}-{1882,5231,0,1,7}-{1882,5234,0,1,5}-{1879,5234,0,1,6}-{1897,5234,0,1,6}-{1884,5234,0,1,4}-{1884,5235,0,1,3}-{1885,5236,0,1,6}-{1879,5239,0,1,4}-{1893,5243,0,1,7}-{1880,5243,0,1,7}-{1882,5241,0,1,1}-{1902,5242,0,1,4}-{1901,5244,0,1,3}-{1910,5243,0,1,5}-{1911,5235,0,1,3}-{1881,5243,0,1,2}-{1879,5234,0,1,3}-{1880,5234,0,1,4}-{1879,5239,0,1,1}-{1874,5230,0,1,4}-{1874,5236,0,1,4}-{1911,5235,0,1,5}-{1912,5243,0,1,4}-{1912,5238,0,1,3}-{1913,5244,0,1,4}-{1890,5244,0,1,4}-{1907,5204,0,1,1}-{1909,5204,0,1,1}-{1908,5204,0,1,3}-{1889,5206,0,1,3}-{1890,5207,0,1,1}-{1890,5207,0,1,2}-{1912,5237,0,1,7}-" + }, + { + "npc_id": "4422", + "loc_data": "{2377,4450,0,0,0}-{2381,4459,0,0,0}-{2388,4425,0,0,0}-{2394,4440,0,0,0}-{2418,4447,0,0,0}-{2427,4461,0,0,0}-" + }, + { + "npc_id": "4423", + "loc_data": "{2387,4456,0,0,0}-{2423,4461,0,0,0}-" + }, + { + "npc_id": "4424", + "loc_data": "{2396,4455,0,0,0}-" + }, + { + "npc_id": "4425", + "loc_data": "{2398,4453,0,0,0}-" + }, + { + "npc_id": "4431", + "loc_data": "{2388,4470,0,0,0}-" + }, + { + "npc_id": "4437", + "loc_data": "{2447,4429,0,1,0}-" + }, + { + "npc_id": "4438", + "loc_data": "{3028,4498,0,1,3}-{3046,4493,0,1,4}-" + }, + { + "npc_id": "4439", + "loc_data": "{3035,4507,0,1,6}-{3041,4493,0,1,0}-" + }, + { + "npc_id": "4443", + "loc_data": "{2451,4424,0,1,6}-{2452,4428,0,1,3}-{2443,4423,0,1,7}-{2446,4422,0,1,3}-{2443,4431,0,1,1}-{2441,4427,0,1,1}-{2463,4422,0,1,4}-{2478,4420,0,1,6}-{2489,4428,0,1,6}-{2478,4452,0,1,3}-{2474,4444,0,1,6}-{2493,4454,0,1,3}-{2486,4463,0,1,4}-{2486,4469,0,1,7}-{2479,4456,0,1,4}-{2477,4462,0,1,3}-" + }, + { + "npc_id": "4455", + "loc_data": "{2410,4434,0,0,0}-" + }, + { + "npc_id": "4472", + "loc_data": "{2524,3056,0,1,2}-" + }, + { + "npc_id": "4474", + "loc_data": "{3214,3252,0,0,0}-{3214,3253,0,0,0}-{3214,3254,0,0,0}-" + }, + { + "npc_id": "4478", + "loc_data": "{3291,2787,0,0,6}-" + }, + { + "npc_id": "4479", + "loc_data": "{2952,3477,0,1,0}-{2959,3501,0,1,3}-" + }, + { + "npc_id": "4481", + "loc_data": "{2943,3474,0,1,3}-" + }, + { + "npc_id": "4482", + "loc_data": "{2952,3505,0,1,7}-{2950,3501,0,1,4}-" + }, + { + "npc_id": "4483", + "loc_data": "{2944,3467,0,1,6}-{2961,3508,0,1,6}-{2953,3467,0,1,3}-" + }, + { + "npc_id": "4484", + "loc_data": "{2956,3496,0,1,6}-" + }, + { + "npc_id": "4485", + "loc_data": "{2951,3509,0,1,4}-" + }, + { + "npc_id": "4487", + "loc_data": "{2943,3478,0,1,3}-" + }, + { + "npc_id": "4488", + "loc_data": "{2946,3474,0,1,4}-{2956,3494,0,1,3}-" + }, + { + "npc_id": "4489", + "loc_data": "{2943,3487,0,1,3}-{2946,3469,0,1,5}-" + }, + { + "npc_id": "4491", + "loc_data": "{2963,3510,0,1,2}-{2949,3475,0,1,3}-" + }, + { + "npc_id": "4492", + "loc_data": "{2987,3426,0,1,6}-{2953,3509,0,1,4}-" + }, + { + "npc_id": "4493", + "loc_data": "{2957,3513,0,1,6}-" + }, + { + "npc_id": "4494", + "loc_data": "{2957,3512,0,1,4}-" + }, + { + "npc_id": "4495", + "loc_data": "{2957,3512,0,1,5}-" + }, + { + "npc_id": "4511", + "loc_data": "{2149,3866,0,0,7}-" + }, + { + "npc_id": "4512", + "loc_data": "{2092,3930,0,1,4}-" + }, + { + "npc_id": "4513", + "loc_data": "{2450,4647,0,1,5}-" + }, + { + "npc_id": "4514", + "loc_data": "{2079,3923,0,1,7}-" + }, + { + "npc_id": "4515", + "loc_data": "{2081,3899,0,1,1}-" + }, + { + "npc_id": "4516", + "loc_data": "{2096,3907,0,1,6}-" + }, + { + "npc_id": "4517", + "loc_data": "{2086,3915,0,1,0}-" + }, + { + "npc_id": "4518", + "loc_data": "{2106,3907,0,1,6}-" + }, + { + "npc_id": "4519", + "loc_data": "{2098,3921,0,0,6}-{2099,3921,0,0,6}-{2097,3921,0,0,6}-" + }, + { + "npc_id": "4524", + "loc_data": "{2083,3903,0,1,3}-" + }, + { + "npc_id": "4525", + "loc_data": "{2098,3894,0,1,3}-" + }, + { + "npc_id": "4526", + "loc_data": "{2103,3914,0,1,7}-" + }, + { + "npc_id": "4527", + "loc_data": "{2071,3877,0,1,2}-{2084,3868,0,1,1}-{2089,3864,0,1,4}-" + }, + { + "npc_id": "4528", + "loc_data": "{2105,3848,0,1,1}-{2115,3864,0,1,6}-{2122,3946,0,1,3}-" + }, + { + "npc_id": "4529", + "loc_data": "{2070,3879,0,1,7}-{2097,3862,0,1,3}-{2118,3852,0,1,4}-{2144,3853,0,1,5}-" + }, + { + "npc_id": "4530", + "loc_data": "{2076,3866,0,1,1}-{2107,3945,0,1,1}-{2133,3874,0,1,4}-" + }, + { + "npc_id": "4531", + "loc_data": "{2103,3866,0,1,3}-{2134,3851,0,1,4}-{2116,3950,0,1,0}-" + }, + { + "npc_id": "4534", + "loc_data": "{3206,5487,0,1,6}-{3200,5492,0,1,1}-" + }, + { + "npc_id": "4536", + "loc_data": "{2213,3794,0,0,3}-" + }, + { + "npc_id": "4537", + "loc_data": "{2621,3688,0,0,6}-" + }, + { + "npc_id": "4539", + "loc_data": "{2079,3925,0,1,1}-" + }, + { + "npc_id": "4540", + "loc_data": "{2137,3899,2,1,2}-{2221,3797,2,1,3}-" + }, + { + "npc_id": "4558", + "loc_data": "{2885,10202,0,1,0}-" + }, + { + "npc_id": "4560", + "loc_data": "{3062,3260,0,1,6}-" + }, + { + "npc_id": "4561", + "loc_data": "{2615,3855,0,1,0}-" + }, + { + "npc_id": "4562", + "loc_data": "{2799,3200,0,1,0}-" + }, + { + "npc_id": "4563", + "loc_data": "{3003,9798,0,1,3}-" + }, + { + "npc_id": "4564", + "loc_data": "{3356,3385,0,1,0}-{3354,3408,0,1,0}-{3365,3429,0,1,0}-{3373,3418,0,1,0}-" + }, + { + "npc_id": "4565", + "loc_data": "{3350,3401,0,1,0}-{3362,3408,0,1,0}-{3366,3425,0,1,0}-" + }, + { + "npc_id": "4566", + "loc_data": "{3360,3343,0,1,6}-" + }, + { + "npc_id": "4567", + "loc_data": "{3364,3339,0,1,6}-" + }, + { + "npc_id": "4568", + "loc_data": "{3365,3333,0,1,6}-" + }, + { + "npc_id": "4569", + "loc_data": "{3381,3379,0,0,0}-" + }, + { + "npc_id": "4570", + "loc_data": "{3115,3276,0,1,6}-{3201,3301,0,1,3}-" + }, + { + "npc_id": "4571", + "loc_data": "{3098,3225,0,1,4}-{3095,3286,0,1,4}-{3205,3298,0,1,3}-{3056,3248,0,1,0}-" + }, + { + "npc_id": "4572", + "loc_data": "{2448,3510,1,0,4}-" + }, + { + "npc_id": "4573", + "loc_data": "{2441,3501,1,1,3}-" + }, + { + "npc_id": "4575", + "loc_data": "{2441,3503,1,1,4}-" + }, + { + "npc_id": "4576", + "loc_data": "{2786,3862,0,1,0}-" + }, + { + "npc_id": "4578", + "loc_data": "{2933,2972,0,0,0}-" + }, + { + "npc_id": "4580", + "loc_data": "{2572,3299,1,0,0}-" + }, + { + "npc_id": "4585", + "loc_data": "{3115,3160,0,0,0}-" + }, + { + "npc_id": "4586", + "loc_data": "{2593,3087,0,1,4}-" + }, + { + "npc_id": "4587", + "loc_data": "{2449,3503,1,0,6}-" + }, + { + "npc_id": "4588", + "loc_data": "{2448,3500,1,0,3}-" + }, + { + "npc_id": "4597", + "loc_data": "{2375,3433,0,1,0}-" + }, + { + "npc_id": "4599", + "loc_data": "{2417,3513,0,1,4}-" + }, + { + "npc_id": "4603", + "loc_data": "{3008,3514,0,1,3}-" + }, + { + "npc_id": "4604", + "loc_data": "{3017,3513,0,1,0}-{3018,3515,0,1,1}-" + }, + { + "npc_id": "4605", + "loc_data": "{3018,3512,0,1,7}-{3019,3514,0,1,1}-{3019,3516,0,1,1}-" + }, + { + "npc_id": "4606", + "loc_data": "{3017,3514,0,1,4}-" + }, + { + "npc_id": "4607", + "loc_data": "{3030,3505,0,0,0}-" + }, + { + "npc_id": "4611", + "loc_data": "{3076,3259,0,0,0}-" + }, + { + "npc_id": "4648", + "loc_data": "{3376,3373,0,0,0}-" + }, + { + "npc_id": "4649", + "loc_data": "{2142,3122,0,1,4}-{2147,3122,0,1,3}-" + }, + { + "npc_id": "4650", + "loc_data": "{3041,3194,0,1,4}-" + }, + { + "npc_id": "4651", + "loc_data": "{2143,3121,0,1,6}-{2760,3239,0,1,3}-" + }, + { + "npc_id": "4652", + "loc_data": "{2674,3144,0,1,3}-{3701,3501,0,1,6}-" + }, + { + "npc_id": "4653", + "loc_data": "{3671,2930,0,1,6}-{2954,3154,0,1,6}-{3040,3192,0,1,3}-{2794,3414,0,1,6}-" + }, + { + "npc_id": "4654", + "loc_data": "{2145,3122,0,1,3}-{2674,3146,0,1,6}-{3001,3033,0,1,6}-" + }, + { + "npc_id": "4655", + "loc_data": "{3701,3503,0,1,1}-{2954,3157,0,1,3}-" + }, + { + "npc_id": "4656", + "loc_data": "{3038,3192,0,1,3}-{2760,3238,0,1,3}-{2795,3414,0,1,6}-" + }, + { + "npc_id": "4659", + "loc_data": "{3095,3232,0,1,6}-{3095,3231,0,1,0}-{3225,3370,0,1,4}-{3230,3370,0,1,3}-" + }, + { + "npc_id": "4660", + "loc_data": "{3225,3369,0,1,3}-{3226,3371,0,1,7}-{3230,3372,0,1,0}-{3230,3370,0,1,3}-{3229,3368,0,1,1}-{3227,3367,0,1,1}-" + }, + { + "npc_id": "4665", + "loc_data": "{2894,9766,0,1,0}-{2904,9797,0,1,0}-{2918,9800,0,1,0}-" + }, + { + "npc_id": "4666", + "loc_data": "{2893,9769,0,1,0}-{2912,9797,0,1,0}-{2909,9807,0,1,0}-" + }, + { + "npc_id": "4670", + "loc_data": "{3181,3850,0,1,6}-" + }, + { + "npc_id": "4672", + "loc_data": "{3190,3834,0,1,6}-" + }, + { + "npc_id": "4673", + "loc_data": "{2829,9827,0,1,0}-{2454,4368,0,1,0}-" + }, + { + "npc_id": "4674", + "loc_data": "{2464,4365,0,1,4}-" + }, + { + "npc_id": "4675", + "loc_data": "{2460,4374,0,1,4}-{3048,10266,0,1,4}-" + }, + { + "npc_id": "4676", + "loc_data": "{2451,4362,0,1,4}-{3054,10269,0,1,4}-" + }, + { + "npc_id": "4677", + "loc_data": "{3335,3687,0,1,4}-{3337,3701,0,1,2}-{3107,3812,0,1,0}-{3316,5448,0,1,2}-{3299,5545,0,1,6}-" + }, + { + "npc_id": "4678", + "loc_data": "{3333,3699,0,1,6}-{3350,3687,0,1,5}-{3098,3821,0,1,0}-{3305,5454,0,1,6}-" + }, + { + "npc_id": "4679", + "loc_data": "{3332,3693,0,1,6}-{3341,3685,0,1,4}-{3092,3810,0,1,0}-{2973,3620,0,1,3}-{3312,5558,0,1,1}-" + }, + { + "npc_id": "4680", + "loc_data": "{3331,3672,0,1,0}-{3347,3694,0,1,5}-{3078,3810,0,1,0}-{2977,3611,0,1,3}-" + }, + { + "npc_id": "4681", + "loc_data": "{2904,9802,0,1,0}-" + }, + { + "npc_id": "4682", + "loc_data": "{2896,9796,0,1,0}-" + }, + { + "npc_id": "4685", + "loc_data": "{2817,3514,0,1,0}-{2884,9959,0,1,0}-{2890,9950,0,1,0}-{3209,5552,0,1,1}-{3223,5555,0,1,4}-{3220,5548,0,1,6}-{3220,5557,0,1,4}-" + }, + { + "npc_id": "4686", + "loc_data": "{2824,3510,0,1,5}-{2880,9927,0,1,0}-{2887,9955,0,1,0}-{2891,9941,0,1,0}-{2954,3894,0,1,4}-{2950,3932,0,1,0}-{2955,3945,0,1,0}-{3213,5548,0,1,4}-{2804,3507,0,1,0}-" + }, + { + "npc_id": "4687", + "loc_data": "{2957,3898,0,1,6}-{2946,3898,0,1,7}-{2978,3956,0,1,0}-" + }, + { + "npc_id": "4688", + "loc_data": "{3139,3818,0,1,0}-{2700,3212,0,1,6}-" + }, + { + "npc_id": "4689", + "loc_data": "{2369,3401,0,1,0}-{2902,9736,0,1,0}-" + }, + { + "npc_id": "4690", + "loc_data": "{2372,3401,0,1,0}-{3104,3875,0,1,2}-{2912,9731,0,1,0}-{3256,3624,0,1,5}-{3308,3661,0,1,2}-" + }, + { + "npc_id": "4691", + "loc_data": "{2371,3398,0,1,0}-{3110,3854,0,1,0}-" + }, + { + "npc_id": "4692", + "loc_data": "{2372,3395,0,1,0}-{3116,3858,0,1,0}-" + }, + { + "npc_id": "4693", + "loc_data": "{2369,3394,0,1,0}-{3094,3849,0,1,0}-{2912,9741,0,1,0}-{2906,9736,0,1,0}-" + }, + { + "npc_id": "4694", + "loc_data": "{3103,3709,0,1,0}-{3094,3869,0,1,1}-{2843,9558,0,1,1}-{2840,9605,0,1,4}-{3017,3852,0,1,7}-" + }, + { + "npc_id": "4695", + "loc_data": "{2840,3279,0,1,6}-{3098,3699,0,1,4}-{2839,9565,0,1,3}-{2837,9601,0,1,4}-{2631,9880,0,1,1}-{3015,3851,0,1,2}-" + }, + { + "npc_id": "4696", + "loc_data": "{3096,3691,0,1,6}-{3091,3861,0,1,0}-{2839,9560,0,1,4}-{2846,9613,0,1,6}-{2931,9808,0,1,0}-{2930,9799,0,1,0}-{2632,9874,0,1,1}-{3014,3848,0,1,1}-" + }, + { + "npc_id": "4697", + "loc_data": "{2825,3277,0,1,3}-{3105,3695,0,1,5}-{2845,9557,0,1,2}-{2839,9624,0,1,6}-{2630,9867,0,1,1}-{3016,3845,0,1,4}-{3324,3856,0,1,2}-" + }, + { + "npc_id": "4698", + "loc_data": "{2861,9752,0,1,4}-{3139,3712,0,1,5}-{3304,3886,0,1,6}-" + }, + { + "npc_id": "4699", + "loc_data": "{3159,3707,0,1,3}-{2629,9477,2,0,0}-{2640,9502,2,0,1}-{3296,3872,0,1,5}-{3035,10245,0,1,4}-" + }, + { + "npc_id": "4700", + "loc_data": "{2862,9750,0,1,7}-{3144,3701,0,1,4}-{2633,9488,2,0,6}-{3282,3880,0,1,4}-" + }, + { + "npc_id": "4701", + "loc_data": "{3149,3690,0,1,4}-{3287,3894,0,1,3}-{3028,10250,0,1,4}-" + }, + { + "npc_id": "4702", + "loc_data": "{2869,9775,0,1,0}-{2853,9775,0,1,0}-{3084,9957,0,1,6}-{2712,9480,0,0,5}-" + }, + { + "npc_id": "4703", + "loc_data": "{2857,9774,0,1,0}-{2860,9781,0,1,0}-{3092,9958,0,1,2}-" + }, + { + "npc_id": "4704", + "loc_data": "{2863,9767,0,1,0}-{2871,9782,0,1,0}-{3160,5521,0,1,1}-" + }, + { + "npc_id": "4705", + "loc_data": "{3088,9961,0,1,1}-{3169,5528,0,1,0}-" + }, + { + "npc_id": "4706", + "loc_data": "{2195,3808,0,1,0}-{2196,3822,0,1,0}-{2197,3805,0,1,0}-{2197,3813,0,1,0}-{2201,3812,0,1,0}-{2202,3824,0,1,0}-{2203,3804,0,1,0}-{2207,3813,0,1,0}-{2211,3818,0,1,0}-{2214,3819,0,1,0}-{3237,5559,0,1,3}-{3244,5554,0,1,3}-{3239,5553,0,1,5}-{3249,5559,0,1,5}-" + }, + { + "npc_id": "4707", + "loc_data": "{3213,3253,0,0,6}-" + }, + { + "npc_id": "4710", + "loc_data": "{3222,3475,0,0,5}-" + }, + { + "npc_id": "4732", + "loc_data": "{3429,3701,0,0,0}-" + }, + { + "npc_id": "4856", + "loc_data": "{2732,3292,0,1,1}-" + }, + { + "npc_id": "4871", + "loc_data": "{2782,3276,0,1,0}-" + }, + { + "npc_id": "4872", + "loc_data": "{2740,3310,0,0,0}-" + }, + { + "npc_id": "4874", + "loc_data": "{2709,3291,0,0,0}-" + }, + { + "npc_id": "4878", + "loc_data": "{2726,3283,0,1,1}-" + }, + { + "npc_id": "4883", + "loc_data": "{2713,3278,0,1,1}-" + }, + { + "npc_id": "4885", + "loc_data": "{2705,3287,0,1,1}-{2716,3287,0,1,1}-{2732,3282,0,1,1}-" + }, + { + "npc_id": "4887", + "loc_data": "{2738,3303,0,1,1}-{2723,3274,0,1,1}-" + }, + { + "npc_id": "4891", + "loc_data": "{2768,3286,0,1,0}-{2777,3278,0,1,0}-{2783,3289,0,1,0}-{2784,3277,0,1,0}-{2768,3289,1,1,0}-{2780,3288,1,1,0}-" + }, + { + "npc_id": "4895", + "loc_data": "{2718,3302,0,1,1}-" + }, + { + "npc_id": "4898", + "loc_data": "{3124,9874,0,1,3}-{3128,9875,0,1,6}-" + }, + { + "npc_id": "4899", + "loc_data": "{3231,3197,0,1,6}-" + }, + { + "npc_id": "4900", + "loc_data": "{3210,3213,1,1,1}-" + }, + { + "npc_id": "4901", + "loc_data": "{3245,3157,0,0,7}-" + }, + { + "npc_id": "4902", + "loc_data": "{3227,3147,0,0,1}-" + }, + { + "npc_id": "4903", + "loc_data": "{3244,3214,0,1,1}-" + }, + { + "npc_id": "4904", + "loc_data": "{3228,3254,0,1,3}-" + }, + { + "npc_id": "4906", + "loc_data": "{3230,3244,0,1,4}-" + }, + { + "npc_id": "4907", + "loc_data": "{3208,3222,2,0,6}-" + }, + { + "npc_id": "4909", + "loc_data": "{2831,3352,0,0,7}-" + }, + { + "npc_id": "4911", + "loc_data": "{2703,9894,0,0,0}-{2705,9897,0,0,0}-{2706,9904,0,0,0}-{2707,9906,0,0,0}-{2704,9906,0,0,0}-{2706,9910,0,0,0}-{2703,9911,0,0,0}-{2699,9915,0,0,0}-{2697,9915,0,0,0}-{2694,9915,0,0,0}-{2692,9914,0,0,0}-{2696,9910,0,0,0}-{2694,9908,0,0,0}-{2693,9906,0,0,0}-{2696,9906,0,0,0}-{2698,9901,0,0,0}-{2698,9900,0,0,0}-{2696,9900,0,0,0}-{2690,9903,0,0,0}-{2692,9902,0,0,0}-{2693,9900,0,0,0}-{2692,9900,0,0,0}-{2691,9899,0,0,0}-{2692,9895,0,0,0}-{2693,9891,0,0,0}-{2695,9889,0,0,0}-{2692,9885,0,0,0}-{2699,9882,0,0,0}-{2695,9881,0,0,0}-{2693,9881,0,0,0}-{2690,9880,0,0,0}-{2700,9879,0,0,0}-{2696,9880,0,0,0}-{2694,9878,0,0,0}-{2695,9877,0,0,0}-{2699,9876,0,0,0}-{2692,9876,0,0,0}-{2692,9874,0,0,0}-{2699,9872,0,0,0}-{2698,9871,0,0,0}-{2701,9870,0,0,0}-{2695,9870,0,0,0}-{2695,9869,0,0,0}-{2702,9868,0,0,0}-{2701,9867,0,0,0}-{2697,9866,0,0,0}-{2699,9865,0,0,0}-" + }, + { + "npc_id": "4920", + "loc_data": "{3188,5510,0,1,6}-{3194,5510,0,1,2}-{3289,5496,0,0,5}-{3272,5490,0,0,0}-" + }, + { + "npc_id": "4921", + "loc_data": "{3304,5493,0,1,3}-{3303,5496,0,1,0}-{3271,5490,0,0,5}-" + }, + { + "npc_id": "4926", + "loc_data": "{3227,3547,0,1,1}-{3251,3528,0,1,1}-{2969,3686,0,1,1}-" + }, + { + "npc_id": "4927", + "loc_data": "{3227,3533,0,1,1}-{3236,3549,0,1,1}-{2962,3689,0,1,1}-{2971,3690,0,1,1}-{3049,3695,0,1,1}-" + }, + { + "npc_id": "4930", + "loc_data": "{3412,2889,0,1,3}-{3414,2892,0,1,1}-{3414,2890,0,1,1}-{3416,2886,0,1,4}-{3416,2893,0,1,6}-" + }, + { + "npc_id": "4932", + "loc_data": "{3414,2891,0,1,1}-{3410,2888,0,1,7}-" + }, + { + "npc_id": "4942", + "loc_data": "{3191,3210,0,1,0}-" + }, + { + "npc_id": "4944", + "loc_data": "{2042,5213,0,1,5}-{2020,5236,0,1,2}-{1993,5188,0,1,2}-{1994,5191,0,1,2}-" + }, + { + "npc_id": "4945", + "loc_data": "{1994,5192,0,1,4}-{1997,5190,0,1,1}-" + }, + { + "npc_id": "4946", + "loc_data": "{2721,3432,0,1,4}-" + }, + { + "npc_id": "4947", + "loc_data": "{2825,3696,0,1,3}-" + }, + { + "npc_id": "4950", + "loc_data": "{2855,10051,1,0,0}-" + }, + { + "npc_id": "4953", + "loc_data": "{2684,3274,1,0,0}-" + }, + { + "npc_id": "4955", + "loc_data": "{2772,3223,0,0,0}-" + }, + { + "npc_id": "4956", + "loc_data": "{2783,3119,0,0,0}-" + }, + { + "npc_id": "4961", + "loc_data": "{2683,3275,1,0,0}-" + }, + { + "npc_id": "4965", + "loc_data": "{2826,3685,0,0,1}-" + }, + { + "npc_id": "4975", + "loc_data": "{3034,2971,0,0,5}-{3030,2971,0,0,1}-{3303,3024,0,0,7}-{3299,3016,0,0,2}-{3280,9438,0,0,6}-{3275,9460,0,0,3}-{3267,9458,0,0,3}-{3270,9415,0,0,6}-{3272,9429,0,0,4}-{3272,9421,0,0,4}-{3271,9450,0,0,1}-{3288,9413,0,0,6}-{3297,9414,0,0,6}-{3300,9414,0,0,6}-{3304,9424,0,0,1}-{3292,9426,0,0,4}-{3295,9421,0,0,3}-{3297,9412,0,0,1}-{3292,9413,0,0,3}-{3324,9429,0,0,3}-{3311,9440,0,0,6}-{3294,9459,0,0,1}-{3291,9463,0,0,6}-{3296,9468,0,0,1}-{3288,9468,0,0,1}-{3313,9449,0,0,1}-" + }, + { + "npc_id": "4976", + "loc_data": "{3036,2972,0,0,1}-{3039,2968,0,0,1}-{3046,2982,0,0,6}-{3045,2974,0,0,6}-{3042,2972,0,0,6}-{3301,3017,0,0,7}-{3281,9446,0,0,1}-{3270,9451,0,0,4}-{3269,9418,0,0,1}-{3267,9441,0,0,1}-{3280,9436,0,0,1}-{3291,9414,0,0,6}-{3305,9413,0,0,6}-{3308,9415,0,0,1}-{3309,9420,0,0,1}-{3296,9425,0,0,1}-{3294,9420,0,0,1}-{3295,9412,0,0,3}-{3323,9439,0,0,6}-{3295,9460,0,0,3}-{3294,9464,0,0,6}-{3294,9467,0,0,1}-{3311,9454,0,0,6}-" + }, + { + "npc_id": "4977", + "loc_data": "{3038,2973,0,0,1}-{3027,2974,0,0,1}-{3023,2977,0,0,1}-{3035,2989,0,0,4}-{3039,2985,0,0,4}-{3294,3016,0,0,6}-{3287,3016,0,0,3}-{3277,9452,0,0,1}-{3267,9443,0,0,6}-{3267,9431,0,0,6}-{3269,9420,0,0,6}-{3273,9460,0,0,4}-{3277,9454,0,0,6}-{3281,9448,0,0,6}-{3294,9413,0,0,6}-{3306,9423,0,0,1}-{3298,9436,0,0,6}-{3292,9466,0,0,6}-{3296,9462,0,0,3}-{3290,9467,0,0,1}-{3315,9451,0,0,1}-{3316,9454,0,0,3}-" + }, + { + "npc_id": "4978", + "loc_data": "{3042,2969,0,0,1}-{3038,2976,0,0,6}-{3041,2983,0,0,6}-{3043,2983,0,0,6}-{3044,2981,0,0,6}-{3043,2979,0,0,1}-{3038,2989,0,0,1}-{3025,2984,0,0,1}-{3026,2988,0,0,1}-{3030,2990,0,0,1}-{3024,2979,0,0,3}-{3291,3017,0,0,5}-{3275,9463,0,0,1}-{3273,9430,0,0,6}-{3273,9422,0,0,6}-{3267,9428,0,0,1}-{3294,9411,0,0,6}-{3300,9424,0,0,1}-{3289,9412,0,0,3}-" + }, + { + "npc_id": "4985", + "loc_data": "{3304,3027,0,1,2}-" + }, + { + "npc_id": "4986", + "loc_data": "{3308,3112,0,1,1}-" + }, + { + "npc_id": "4989", + "loc_data": "{3272,3029,0,1,4}-" + }, + { + "npc_id": "4990", + "loc_data": "{3269,3029,0,1,4}-" + }, + { + "npc_id": "4991", + "loc_data": "{3270,3030,0,1,6}-" + }, + { + "npc_id": "4992", + "loc_data": "{3267,3029,0,1,0}-" + }, + { + "npc_id": "4993", + "loc_data": "{3277,3028,0,1,1}-{3279,9441,0,1,4}-" + }, + { + "npc_id": "4994", + "loc_data": "{3285,3027,0,1,7}-" + }, + { + "npc_id": "4995", + "loc_data": "{3279,3024,0,1,3}-{3286,3036,1,1,4}-" + }, + { + "npc_id": "4996", + "loc_data": "{3284,3022,0,1,2}-" + }, + { + "npc_id": "4997", + "loc_data": "{3289,3026,0,1,3}-{3317,9438,0,0,3}-" + }, + { + "npc_id": "4998", + "loc_data": "{3293,3027,0,1,5}-{3286,9419,0,1,3}-{3296,9433,0,1,7}-{3310,9457,0,1,1}-" + }, + { + "npc_id": "4999", + "loc_data": "{3280,3020,0,1,6}-{3319,9439,0,1,0}-{3299,9467,0,1,3}-" + }, + { + "npc_id": "5000", + "loc_data": "{3285,3022,0,1,6}-{3295,9434,0,1,3}-" + }, + { + "npc_id": "5001", + "loc_data": "{3297,3020,0,1,6}-{3280,9414,0,1,1}-{3279,9416,0,1,1}-" + }, + { + "npc_id": "5002", + "loc_data": "{3295,3028,0,1,3}-{3291,9423,0,1,1}-" + }, + { + "npc_id": "5020", + "loc_data": "{2905,3180,0,0,0}-" + }, + { + "npc_id": "5021", + "loc_data": "{2906,3173,0,0,0}-" + }, + { + "npc_id": "5022", + "loc_data": "{2907,3169,0,0,0}-" + }, + { + "npc_id": "5029", + "loc_data": "{2534,3575,0,1,0}-" + }, + { + "npc_id": "5030", + "loc_data": "{2533,3570,0,1,4}-" + }, + { + "npc_id": "5031", + "loc_data": "{2525,3575,0,1,3}-" + }, + { + "npc_id": "5032", + "loc_data": "{2525,3566,0,1,3}-" + }, + { + "npc_id": "5033", + "loc_data": "{2520,3569,0,1,3}-" + }, + { + "npc_id": "5049", + "loc_data": "{2808,3355,0,1,6}-" + }, + { + "npc_id": "5062", + "loc_data": "{2927,3410,0,0,0}-" + }, + { + "npc_id": "5063", + "loc_data": "{2460,3108,0,1,3}-" + }, + { + "npc_id": "5065", + "loc_data": "{2925,3303,0,0,0}-" + }, + { + "npc_id": "5070", + "loc_data": "{2912,3480,0,0,0}-{2911,3480,0,0,0}-" + }, + { + "npc_id": "5071", + "loc_data": "{2609,2922,0,0,0}-" + }, + { + "npc_id": "5072", + "loc_data": "{2464,2832,0,1,2}-{2510,2876,0,1,3}-{2517,2878,0,1,6}-{2527,2877,0,1,2}-{2507,2877,0,1,1}-{2536,2877,0,1,3}-{2530,2872,0,1,3}-{2517,2870,0,1,4}-{2526,2928,0,1,6}-{2532,2938,0,1,4}-{2527,2933,0,1,4}-{2521,2938,0,1,6}-{2507,2914,0,1,0}-{2512,2910,0,1,4}-{2517,2912,0,1,1}-{2517,2921,0,1,6}-{2511,2911,0,1,3}-{2521,2917,0,1,7}-{2522,2929,0,1,4}-{2510,2888,0,1,1}-{2502,2890,0,1,3}-{2520,2882,0,1,7}-{2500,2893,0,1,4}-{2548,2887,0,1,1}-{2544,2889,0,1,7}-{2520,2885,0,1,0}-{2498,2883,0,1,6}-{2501,2886,0,1,7}-{2508,2916,0,1,4}-{2502,2888,0,1,7}-{2514,2915,0,1,4}-{2520,2908,0,1,6}-{2526,2943,0,1,4}-{2525,2893,0,1,4}-{2521,2896,0,1,1}-{2515,2944,0,1,4}-" + }, + { + "npc_id": "5073", + "loc_data": "{2588,2879,0,1,6}-{2603,2892,0,1,1}-{2604,2892,0,1,6}-{2611,2917,0,1,6}-{2611,2916,0,1,3}-{2613,2894,0,1,1}-{2614,2892,0,1,6}-{2608,2927,0,1,2}-{2612,2934,0,1,4}-{2609,2930,0,1,0}-{2594,2929,0,1,2}-{2616,2922,0,1,4}-{2593,2911,0,1,1}-{2617,2911,0,1,1}-{2602,2900,0,1,3}-{2601,2886,0,1,6}-{2587,2897,0,1,4}-{2612,2936,0,1,3}-{2606,2929,0,1,5}-{2615,2930,0,1,3}-{2576,2896,0,1,1}-{2593,2880,0,1,7}-{2583,2886,0,1,5}-{2609,2897,0,1,3}-{2608,2905,0,1,2}-{2606,2917,0,1,4}-{2604,2918,0,1,4}-{2613,2890,0,1,5}-{2608,2921,0,1,6}-{2604,2886,0,1,6}-{2602,2920,0,1,1}-{2607,2932,0,1,6}-{2578,2885,0,1,1}-" + }, + { + "npc_id": "5074", + "loc_data": "{2727,3763,0,1,1}-{2724,3765,0,1,2}-{2725,3768,0,1,2}-{2730,3768,0,1,2}-{2731,3764,0,1,2}-{2731,3763,0,1,2}-{2731,3765,0,1,2}-{2733,3765,0,1,2}-{2709,3823,1,1,2}-{2713,3823,1,1,2}-{2709,3825,1,1,2}-{2710,3826,1,1,2}-{2709,3825,1,1,2}-" + }, + { + "npc_id": "5075", + "loc_data": "{3409,3078,0,1,5}-{3410,3075,0,1,5}-{3411,3079,0,1,5}-{3408,3076,0,1,5}-{3414,3077,0,1,5}-{3402,3140,0,1,2}-{3402,3138,0,1,3}-{3404,3139,0,1,5}-{3400,3142,0,1,6}-{3405,3143,0,1,5}-" + }, + { + "npc_id": "5076", + "loc_data": "{2310,3581,0,1,2}-{2314,3580,0,1,2}-{2311,3583,0,1,2}-{2304,3588,0,1,6}-{2305,3601,0,1,7}-{2341,3610,0,1,7}-{2344,3606,0,1,3}-{2340,3603,0,1,4}-{2348,3591,0,1,1}-{2356,3595,0,1,6}-{2361,3595,0,1,1}-{2359,3589,0,1,4}-{2346,3585,0,1,6}-{2360,3584,0,1,7}-" + }, + { + "npc_id": "5077", + "loc_data": "{2560,2911,0,0,0}-{2561,2914,0,0,0}-{2560,2909,0,0,0}-{2561,2916,0,0,0}-{2467,2879,0,0,0}-{2484,2877,0,0,0}-{2485,2876,0,0,0}-{2456,2832,0,0,0}-{2456,2832,0,0,0}-{2456,2832,0,0,0}-{2456,2832,0,0,0}-{2494,2940,0,0,0}-{2495,2940,0,0,0}-{2512,2864,0,0,0}-{2558,2911,0,0,0}-{2558,2913,0,0,0}-{2556,2913,0,0,0}-{2557,2912,0,0,0}-{2559,2910,0,0,0}-{2559,2909,0,0,0}-{2559,2917,0,0,0}-{2558,2914,0,0,0}-{2559,2915,0,0,0}-{2558,2916,0,0,0}-{2559,2932,0,0,0}-{2559,2928,0,0,0}-{2558,2928,0,0,0}-{2558,2931,0,0,0}-{2558,2929,0,0,0}-{2556,2911,0,0,0}-{2557,2911,0,0,0}-{2556,2910,0,0,0}-{2556,2912,0,0,0}-{2557,2919,0,0,0}-{2556,2914,0,0,0}-{2556,2913,0,0,0}-{2556,2918,0,0,0}-{2556,2929,0,0,0}-{2557,2933,0,0,0}-{2556,2932,0,0,0}-{2557,2932,0,0,0}-{2557,2928,0,0,0}-{2559,2934,0,0,0}-{2554,2911,0,0,0}-{2555,2911,0,0,0}-{2554,2912,0,0,0}-{2555,2915,0,0,0}-{2555,2919,0,0,0}-{2554,2919,0,0,0}-{2554,2913,0,0,0}-{2556,2915,0,0,0}-{2555,2931,0,0,0}-{2554,2933,0,0,0}-{2555,2934,0,0,0}-{2555,2933,0,0,0}-{2555,2932,0,0,0}-{2554,2935,0,0,0}-{2554,2934,0,0,0}-{2556,2936,0,0,0}-{2558,2936,0,0,0}-{2554,2936,0,0,0}-{2553,2935,0,0,0}-{2556,2933,0,0,0}-{2558,2938,0,0,0}-{2556,2938,0,0,0}-{2557,2937,0,0,0}-{2557,2917,0,0,0}-{2555,2917,0,0,0}-{2555,2912,0,0,0}-{2555,2935,0,0,0}-{2547,2940,0,0,0}-{2546,2939,0,0,0}-{2548,2939,0,0,0}-{2557,2930,0,0,0}-{2556,2929,0,0,0}-{2546,2941,0,0,0}-{2548,2941,0,0,0}-{2557,2931,0,0,0}-{2556,2935,0,0,0}-{2555,2936,0,0,0}-{2553,2935,0,0,0}-{2559,2930,0,0,0}-{2547,2940,0,0,0}-{2509,2910,0,0,0}-{2507,2910,0,0,0}-{2509,2908,0,0,0}-{2508,2908,0,0,0}-{2508,2909,0,0,0}-{2510,2908,0,0,0}-{2506,2906,0,0,0}-{2508,2906,0,0,0}-{2507,2906,0,0,0}-{2507,2905,0,0,0}-{2509,2905,0,0,0}-{2505,2907,0,0,0}-{2504,2908,0,0,0}-{2511,2908,0,0,0}-{2504,2906,0,0,0}-{2508,2907,0,0,0}-{2509,2906,0,0,0}-{2508,2909,0,0,0}-{2506,2906,0,0,0}-{2510,2907,0,0,0}-{2503,2907,0,0,0}-{2509,2908,0,0,0}-{2507,2908,0,0,0}-{2508,2906,0,0,0}-{2505,2907,0,0,0}-{2507,2905,0,0,0}-{2506,2904,0,0,0}-{2505,2903,0,0,0}-{2508,2902,0,0,0}-{2504,2901,0,0,0}-{2506,2907,0,0,0}-{2507,2906,0,0,0}-{2524,2898,0,0,0}-{2524,2896,0,0,0}-{2525,2897,0,0,0}-{2521,2895,0,0,0}-{2525,2895,0,0,0}-{2507,2903,0,0,0}-{2526,2898,0,0,0}-{2507,2889,0,0,0}-{2506,2903,0,0,0}-{2503,2905,0,0,0}-{2507,2905,0,0,0}-{2511,2908,0,0,0}-{2507,2887,0,0,0}-{2554,2937,0,0,0}-{2558,2938,0,0,0}-{2557,2937,0,0,0}-{2556,2938,0,0,0}-{2553,2937,0,0,0}-{2556,2937,0,0,0}-{2553,2935,0,0,0}-{2556,2935,0,0,0}-{2558,2936,0,0,0}-{2555,2936,0,0,0}-{2552,2936,0,0,0}-{2554,2936,0,0,0}-{2552,2934,0,0,0}-{2553,2934,0,0,0}-{2557,2931,0,0,0}-{2559,2932,0,0,0}-{2558,2932,0,0,0}-{2556,2936,0,0,0}-{2553,2936,0,0,0}-{2554,2935,0,0,0}-{2559,2917,0,0,0}-{2556,2916,0,0,0}-{2555,2917,0,0,0}-{2559,2914,0,0,0}-{2557,2915,0,0,0}-{2557,2912,0,0,0}-{2559,2912,0,0,0}-{2558,2913,0,0,0}-{2555,2911,0,0,0}-{2554,2910,0,0,0}-{2559,2916,0,0,0}-{2557,2932,0,0,0}-{2557,2909,0,0,0}-{2559,2913,0,0,0}-{2552,2935,0,0,0}-{2559,2909,0,0,0}-{2557,2914,0,0,0}-{2555,2915,0,0,0}-{2527,2896,0,0,0}-{2524,2895,0,0,0}-{2524,2894,0,0,0}-{2525,2896,0,0,0}-{2524,2896,0,0,0}-{2523,2893,0,0,0}-{2523,2896,0,0,0}-{2523,2897,0,0,0}-{2521,2895,0,0,0}-{2521,2893,0,0,0}-{2526,2895,0,0,0}-{2507,2887,0,0,0}-{2507,2890,0,0,0}-{2506,2886,0,0,0}-{2505,2887,0,0,0}-{2505,2888,0,0,0}-{2503,2889,0,0,0}-{2504,2889,0,0,0}-{2504,2903,0,0,0}-{2505,2907,0,0,0}-{2504,2906,0,0,0}-{2505,2905,0,0,0}-{2506,2907,0,0,0}-{2506,2905,0,0,0}-{2506,2906,0,0,0}-{2507,2903,0,0,0}-{2507,2906,0,0,0}-{2507,2907,0,0,0}-{2505,2893,0,0,0}-{2504,2892,0,0,0}-{2508,2909,0,0,0}-{2502,2891,0,0,0}-{2503,2890,0,0,0}-{2503,2891,0,0,0}-{2508,2891,0,0,0}-{2507,2891,0,0,0}-{2507,2890,0,0,0}-{2503,2889,0,0,0}-{2504,2889,0,0,0}-{2505,2888,0,0,0}-{2506,2909,0,0,0}-{2507,2887,0,0,0}-{2505,2887,0,0,0}-{2506,2887,0,0,0}-{2508,2890,0,0,0}-{2504,2894,0,0,0}-{2502,2891,0,0,0}-{2524,2899,0,0,0}-{2524,2898,0,0,0}-{2526,2899,0,0,0}-{2526,2895,0,0,0}-{2526,2900,0,0,0}-{2524,2900,0,0,0}-{2525,2900,0,0,0}-{2525,2899,0,0,0}-{2524,2893,0,0,0}-{2522,2894,0,0,0}-{2521,2895,0,0,0}-{2523,2895,0,0,0}-{2524,2895,0,0,0}-{2506,2886,0,0,0}-{2521,2893,0,0,0}-{2526,2898,0,0,0}-{2524,2899,0,0,0}-{2523,2896,0,0,0}-{2522,2894,0,0,0}-{2524,2901,0,0,0}-{2524,2900,0,0,0}-{2523,2895,0,0,0}-{2526,2901,0,0,0}-{2525,2896,0,0,0}-{2526,2900,0,0,0}-{2523,2893,0,0,0}-{2525,2900,0,0,0}-{2524,2898,0,0,0}-{2525,2894,0,0,0}-{2527,2894,0,0,0}-{2524,2899,0,0,0}-{2508,2904,0,0,0}-{2507,2907,0,0,0}-{2506,2902,0,0,0}-{2506,2907,0,0,0}-{2506,2906,0,0,0}-{2503,2907,0,0,0}-{2503,2905,0,0,0}-{2505,2893,0,0,0}-{2503,2891,0,0,0}-{2506,2891,0,0,0}-{2508,2891,0,0,0}-{2506,2892,0,0,0}-{2506,2909,0,0,0}-{2503,2890,0,0,0}-{2503,2889,0,0,0}-{2504,2889,0,0,0}-{2507,2890,0,0,0}-{2505,2887,0,0,0}-{2505,2888,0,0,0}-{2508,2890,0,0,0}-{2507,2905,0,0,0}-{2503,2890,0,0,0}-{2503,2891,0,0,0}-{2504,2892,0,0,0}-{2504,2894,0,0,0}-{2506,2887,0,0,0}-{2507,2887,0,0,0}-{2507,2891,0,0,0}-{2504,2889,0,0,0}-{2508,2891,0,0,0}-{2505,2888,0,0,0}-{2506,2894,0,0,0}-{2506,2902,0,0,0}-{2506,2904,0,0,0}-{2506,2886,0,0,0}-{2507,2903,0,0,0}-{2505,2893,0,0,0}-{2506,2891,0,0,0}-{2503,2889,0,0,0}-{2506,2887,0,0,0}-{2506,2892,0,0,0}-{2507,2891,0,0,0}-{2507,2887,0,0,0}-{2507,2890,0,0,0}-{2503,2905,0,0,0}-{2505,2906,0,0,0}-{2506,2905,0,0,0}-{2506,2906,0,0,0}-{2507,2905,0,0,0}-{2505,2905,0,0,0}-{2504,2906,0,0,0}-{2503,2907,0,0,0}-{2506,2894,0,0,0}-{2507,2908,0,0,0}-{2507,2907,0,0,0}-{2508,2909,0,0,0}-{2505,2888,0,0,0}-{2505,2907,0,0,0}-{2496,2939,0,0,0}-{2497,2938,0,0,0}-{2498,2942,0,0,0}-{2499,2943,0,0,0}-{2500,2942,0,0,0}-{2503,2940,0,0,0}-{2496,2939,0,0,0}-{2502,2939,0,0,0}-{2498,2944,0,0,0}-{2500,2944,0,0,0}-" + }, + { + "npc_id": "5078", + "loc_data": "{2560,2909,0,0,0}-{2560,2933,0,0,0}-{2560,2918,0,0,0}-{2561,2916,0,0,0}-{2560,2915,0,0,0}-{2467,2878,0,0,0}-{2486,2877,0,0,0}-{2495,2938,0,0,0}-{2556,2911,0,0,0}-{2558,2910,0,0,0}-{2558,2909,0,0,0}-{2558,2918,0,0,0}-{2559,2930,0,0,0}-{2557,2915,0,0,0}-{2557,2931,0,0,0}-{2558,2935,0,0,0}-{2555,2936,0,0,0}-{2553,2936,0,0,0}-{2553,2933,0,0,0}-{2553,2934,0,0,0}-{2506,2908,0,0,0}-{2507,2908,0,0,0}-{2510,2906,0,0,0}-{2509,2907,0,0,0}-{2508,2907,0,0,0}-{2506,2904,0,0,0}-{2508,2904,0,0,0}-{2504,2906,0,0,0}-{2506,2909,0,0,0}-{2508,2904,0,0,0}-{2506,2902,0,0,0}-{2504,2903,0,0,0}-{2504,2902,0,0,0}-{2525,2899,0,0,0}-{2523,2897,0,0,0}-{2522,2897,0,0,0}-{2523,2895,0,0,0}-{2521,2893,0,0,0}-{2523,2893,0,0,0}-{2506,2888,0,0,0}-{2509,2889,0,0,0}-{2505,2889,0,0,0}-{2508,2888,0,0,0}-{2506,2887,0,0,0}-{2505,2887,0,0,0}-{2554,2935,0,0,0}-{2552,2935,0,0,0}-{2557,2934,0,0,0}-{2554,2934,0,0,0}-{2558,2933,0,0,0}-{2559,2931,0,0,0}-{2558,2916,0,0,0}-{2557,2917,0,0,0}-{2555,2915,0,0,0}-{2557,2914,0,0,0}-{2554,2912,0,0,0}-{2556,2912,0,0,0}-{2559,2909,0,0,0}-{2558,2909,0,0,0}-{2527,2894,0,0,0}-{2525,2894,0,0,0}-{2523,2895,0,0,0}-{2522,2894,0,0,0}-{2508,2890,0,0,0}-{2508,2891,0,0,0}-{2503,2905,0,0,0}-{2503,2907,0,0,0}-{2506,2902,0,0,0}-{2506,2904,0,0,0}-{2504,2894,0,0,0}-{2506,2894,0,0,0}-{2506,2892,0,0,0}-{2508,2904,0,0,0}-{2506,2891,0,0,0}-{2524,2901,0,0,0}-{2526,2901,0,0,0}-{2524,2894,0,0,0}-{2525,2894,0,0,0}-{2527,2894,0,0,0}-{2523,2896,0,0,0}-{2525,2896,0,0,0}-{2507,2903,0,0,0}-{2507,2905,0,0,0}-{2505,2902,0,0,0}-{2506,2904,0,0,0}-{2505,2907,0,0,0}-{2506,2905,0,0,0}-{2505,2905,0,0,0}-{2504,2906,0,0,0}-{2506,2894,0,0,0}-{2504,2894,0,0,0}-{2507,2891,0,0,0}-{2507,2887,0,0,0}-{2506,2891,0,0,0}-{2506,2907,0,0,0}-{2501,2938,0,0,0}-{2501,2940,0,0,0}-{2503,2938,0,0,0}-" + }, + { + "npc_id": "5079", + "loc_data": "{2323,3538,0,1,6}-{2319,3539,0,1,6}-{2321,3545,0,1,5}-{2324,3556,0,1,1}-{2358,3573,0,1,3}-{2360,3571,0,1,4}-{2342,3549,0,1,0}-{2357,3539,0,1,1}-{2357,3537,0,1,4}-{2357,3549,0,1,6}-{2322,3594,0,1,5}-{2323,3594,0,1,1}-{2323,3602,0,1,1}-{2326,3602,0,1,4}-{2324,3622,0,1,1}-{2326,3630,0,1,6}-{2347,3617,0,1,7}-{2341,3615,0,1,3}-{2339,3596,0,1,3}-{2329,3584,0,1,6}-{2337,3589,0,1,5}-{2371,3560,0,1,3}-" + }, + { + "npc_id": "5080", + "loc_data": "{2562,2927,0,1,4}-{2466,2878,0,1,6}-{2464,2832,0,1,2}-{2490,2877,0,1,1}-{2467,2881,0,1,7}-{2557,2915,0,1,3}-{2557,2921,0,1,1}-{2556,2938,0,1,7}-{2551,2930,0,1,6}-{2558,2912,0,1,4}-{2558,2909,0,1,3}-{2557,2932,0,1,6}-{2556,2935,0,1,1}-{2555,2915,0,1,2}-{2553,2935,0,1,4}-{2559,2918,0,1,4}-{2508,2909,0,1,3}-{2501,2912,0,1,6}-{2507,2907,0,1,1}-{2505,2902,0,1,2}-{2504,2896,0,1,2}-{2522,2895,0,1,3}-{2526,2897,0,1,1}-{2527,2904,0,1,0}-{2507,2889,0,1,4}-{2553,2935,0,1,1}-{2556,2931,0,1,5}-{2555,2915,0,1,6}-{2559,2911,0,1,4}-{2559,2918,0,1,3}-{2527,2896,0,1,4}-{2533,2896,0,1,5}-{2508,2890,0,1,4}-{2522,2895,0,1,2}-{2496,2897,0,1,1}-{2506,2906,0,1,0}-{2506,2894,0,1,3}-{2506,2902,0,1,6}-{2499,2942,0,1,7}-{2496,2936,0,1,4}-{2498,2939,0,1,3}-{2545,2948,0,1,2}-" + }, + { + "npc_id": "5081", + "loc_data": "{2318,3501,0,1,5}-{2316,3502,0,1,6}-{2317,3512,0,1,6}-{2315,3512,0,1,5}-{2312,3504,0,1,1}-{2307,3513,0,1,6}-{2311,3517,0,1,0}-{2320,3517,0,1,1}-{2309,3520,0,1,6}-" + }, + { + "npc_id": "5082", + "loc_data": "{2561,2913,0,1,1}-{2561,2918,0,1,7}-{2560,2915,0,1,1}-{2566,2881,0,1,7}-{2568,2917,0,1,6}-{2568,2918,0,1,4}-{2568,2885,0,1,4}-{2487,2878,0,1,4}-{2554,2894,0,1,4}-{2538,2897,0,1,6}-{2545,2899,0,1,3}-{2559,2908,0,1,6}-{2557,2920,0,1,4}-{2553,2913,0,1,4}-{2544,2910,0,1,2}-{2547,2909,0,1,4}-{2537,2906,0,1,5}-{2525,2914,0,1,3}-{2555,2920,0,1,6}-{2557,2908,0,1,6}-{2539,2920,0,1,1}-{2528,2915,0,1,4}-{2527,2904,0,1,0}-{2518,2901,0,1,5}-{2528,2902,0,1,1}-{2529,2918,0,1,6}-{2557,2915,0,1,7}-{2546,2912,0,1,3}-{2542,2911,0,1,5}-{2548,2910,0,1,6}-{2554,2907,0,1,1}-{2548,2896,0,1,5}-{2545,2895,0,1,6}-{2544,2910,0,1,7}-{2536,2895,0,1,3}-{2538,2902,0,1,6}-{2523,2910,0,1,3}-{2533,2910,0,1,2}-" + }, + { + "npc_id": "5083", + "loc_data": "{2621,3835,1,1,4}-{2708,3772,0,1,0}-{2714,3765,0,1,0}-{2699,3780,0,1,4}-{2694,3785,0,1,4}-{2717,3776,0,1,0}-{2718,3784,0,1,0}-{2723,3786,0,1,0}-{2725,3833,1,1,0}-{2728,3776,0,1,0}-" + }, + { + "npc_id": "5084", + "loc_data": "{2724,3771,0,1,0}-{2738,3769,0,1,0}-{2703,3829,1,1,0}-{2708,3824,1,1,0}-{2714,3826,1,1,0}-{2722,3833,1,1,0}-{2737,3776,0,1,0}-" + }, + { + "npc_id": "5085", + "loc_data": "{2328,3526,0,0,0}-{2313,3528,0,0,0}-{2312,3542,0,0,0}-{2312,3544,0,0,0}-{2323,3543,0,0,0}-{2325,3544,0,0,0}-{2328,3539,0,0,0}-{2311,3564,0,0,0}-{2332,3548,0,0,0}-{2335,3545,0,0,0}-{2320,3580,0,0,0}-{2325,3582,0,0,0}-{2330,3583,0,0,0}-{2355,3573,0,0,0}-{2359,3571,0,0,0}-{2352,3567,0,0,0}-{2361,3554,0,0,0}-{2329,3561,0,0,0}-{2341,3560,0,0,0}-{2344,3543,0,0,0}-{2342,3539,0,0,0}-{2349,3547,0,0,0}-{2352,3545,0,0,0}-{2334,3522,0,0,0}-{2310,3585,0,0,0}-{2324,3584,0,0,0}-{2312,3587,0,0,0}-{2316,3599,0,0,0}-{2324,3599,0,0,0}-{2323,3600,0,0,0}-{2315,3602,0,0,0}-{2309,3605,0,0,0}-{2316,3608,0,0,0}-{2315,3608,0,0,0}-{2325,3614,0,0,0}-{2313,3620,0,0,0}-{2333,3612,0,0,0}-{2331,3608,0,0,0}-{2331,3604,0,0,0}-{2346,3591,0,0,0}-{2369,3573,0,0,0}-{2372,3561,0,0,0}-" + }, + { + "npc_id": "5086", + "loc_data": "{2321,3593,0,1,1}-{2322,3597,0,1,0}-{2309,3603,0,1,5}-{2306,3607,0,1,0}-{2305,3619,0,1,1}-{2309,3618,0,1,6}-{2322,3627,0,1,3}-{2324,3614,0,1,1}-{2323,3614,0,1,1}-{2323,3629,0,1,6}-{2329,3633,0,1,4}-{2328,3634,0,1,3}-{2311,3642,0,1,1}-{2307,3644,0,1,6}-{2318,3645,0,1,1}-{2323,3645,0,1,3}-{2333,3629,0,1,3}-{2340,3641,0,1,7}-{2343,3640,0,1,6}-{2335,3633,0,1,6}-" + }, + { + "npc_id": "5087", + "loc_data": "{2712,3774,0,1,3}-{2715,3772,0,1,3}-{2720,3767,0,1,4}-{2712,3766,0,1,0}-{2718,3767,0,1,7}-{2719,3771,0,1,3}-{2706,3776,0,1,4}-{2716,3778,0,1,4}-" + }, + { + "npc_id": "5088", + "loc_data": "{2586,2883,0,1,6}-{2589,2909,0,1,1}-{2574,2915,0,1,3}-{2572,2928,0,1,3}-{2567,2932,0,1,6}-{2568,2933,0,1,0}-{2585,2884,0,1,5}-{2577,2890,0,1,0}-{2578,2918,0,1,1}-{2568,2934,0,1,1}-{2574,2930,0,1,1}-{2576,2928,0,1,4}-{2580,2889,0,1,1}-{2580,2886,0,1,1}-{2580,2886,0,1,0}-{2572,2900,0,1,4}-{2572,2896,0,1,3}-{2568,2905,0,1,4}-{2536,2872,0,1,4}-{2536,2872,0,1,6}-{2536,2872,0,1,4}-{2536,2872,0,1,6}-{2536,2872,0,1,3}-{2536,2864,0,1,7}-{2512,2864,0,1,6}-{2512,2864,0,1,1}-{2538,2889,0,1,3}-{2538,2902,0,1,4}-" + }, + { + "npc_id": "5089", + "loc_data": "{2315,3523,0,1,1}-{2315,3530,0,1,6}-{2308,3536,0,1,4}-{2307,3538,0,1,1}-{2325,3551,0,1,3}-{2316,3559,0,1,1}-{2312,3559,0,1,1}-{2310,3572,0,1,3}-{2334,3552,0,1,4}-{2308,3582,0,1,2}-{2363,3579,0,1,1}-{2363,3577,0,1,1}-{2350,3568,0,1,1}-{2352,3561,0,1,1}-{2346,3547,0,1,7}-{2347,3546,0,1,3}-{2363,3541,0,1,1}-{2362,3536,0,1,2}-{2350,3526,0,1,7}-{2350,3521,0,1,4}-{2351,3562,0,1,0}-{2310,3574,0,1,6}-" + }, + { + "npc_id": "5093", + "loc_data": "{2375,3607,0,0,0}-" + }, + { + "npc_id": "5098", + "loc_data": "{2376,3582,0,1,6}-{2378,3582,0,1,1}-{2383,3582,0,1,5}-{2372,3592,0,1,5}-{2370,3587,0,1,3}-{2371,3586,0,1,6}-{2393,3590,0,1,6}-" + }, + { + "npc_id": "5099", + "loc_data": "{2366,3577,0,1,4}-{2365,3597,0,1,5}-{2372,3573,0,1,1}-{2369,3588,0,1,4}-{2377,3584,0,1,1}-{2385,3590,0,1,3}-{2388,3598,0,1,3}-" + }, + { + "npc_id": "5100", + "loc_data": "{2369,3579,0,1,5}-{2373,3575,0,1,1}-{2390,3588,0,1,4}-" + }, + { + "npc_id": "5103", + "loc_data": "{2733,3777,0,1,6}-{2731,3784,0,1,4}-{2735,3790,0,1,6}-{2741,3783,0,1,2}-{2738,3790,0,1,1}-{2731,3783,0,1,1}-{2724,3791,0,1,4}-" + }, + { + "npc_id": "5104", + "loc_data": "{2564,2896,0,0,4}-{2571,2882,0,1,1}-{2573,2900,0,1,3}-{2551,2890,0,0,1}-{2541,2899,0,0,0}-{2552,2910,0,0,0}-{2558,2881,0,0,0}-{2543,2899,0,0,0}-{2545,2925,0,0,0}-{2549,2905,0,1,3}-" + }, + { + "npc_id": "5105", + "loc_data": "{2785,3006,0,1,0}-{2775,2996,0,1,0}-{2780,3017,0,1,0}-{2766,3013,0,1,0}-" + }, + { + "npc_id": "5109", + "loc_data": "{3443,2902,0,1,3}-" + }, + { + "npc_id": "5110", + "loc_data": "{2566,3084,0,1,6}-" + }, + { + "npc_id": "5111", + "loc_data": "{2569,3083,0,1,1}-" + }, + { + "npc_id": "5112", + "loc_data": "{2712,3833,1,1,1}-" + }, + { + "npc_id": "5113", + "loc_data": "{2525,2916,0,1,5}-" + }, + { + "npc_id": "5114", + "loc_data": "{3411,3076,0,1,6}-{3415,3075,0,1,1}-{3406,3093,0,1,3}-{3413,3078,0,1,1}-{3403,3093,0,1,1}-{3412,3081,0,1,3}-{3405,3099,0,1,3}-{3405,3102,0,1,0}-{3406,3098,0,1,4}-{3401,3099,0,1,7}-{3405,3093,0,1,4}-{3404,3085,0,1,5}-{3402,3094,0,1,6}-{3399,3096,0,1,1}-{3405,3088,0,1,3}-{3411,3088,0,1,2}-" + }, + { + "npc_id": "5115", + "loc_data": "{2451,3219,0,1,3}-{2448,3221,0,1,3}-{2476,3236,0,1,3}-{2450,3226,0,1,6}-{2474,3239,0,1,0}-{2470,3240,0,1,2}-{2468,3243,0,1,0}-{2455,3219,0,1,6}-{2449,3225,0,1,7}-{2445,3226,0,1,2}-{2467,3241,0,1,1}-{2452,3221,0,1,3}-{2473,3235,0,1,7}-{2472,3241,0,1,4}-{2475,3237,0,1,3}-" + }, + { + "npc_id": "5116", + "loc_data": "{3291,3675,0,1,6}-{3293,3678,0,1,1}-{3302,3671,0,1,0}-{3299,3666,0,1,5}-{3319,3662,0,1,2}-{3309,3661,0,1,5}-{3321,3661,0,1,1}-{3298,3672,0,1,0}-{3316,3657,0,1,4}-{3302,3667,0,1,1}-{3302,3666,0,1,3}-{3315,3663,0,1,1}-" + }, + { + "npc_id": "5117", + "loc_data": "{3537,3449,0,1,2}-{3535,3447,0,1,6}-{3539,3447,0,1,2}-{3533,3446,0,1,1}-{3549,3439,0,1,4}-{3547,3439,0,1,7}-{3549,3439,0,1,4}-" + }, + { + "npc_id": "5120", + "loc_data": "{2326,3488,0,1,2}-{2325,3483,0,1,2}-{2315,3482,0,1,2}-{2336,3491,0,1,2}-" + }, + { + "npc_id": "5125", + "loc_data": "{2316,3501,0,0,0}-" + }, + { + "npc_id": "5138", + "loc_data": "{2607,3264,0,0,0}-" + }, + { + "npc_id": "5139", + "loc_data": "{2607,3260,0,0,0}-" + }, + { + "npc_id": "5146", + "loc_data": "{2925,3324,0,1,0}-{3205,3263,0,0,0}-" + }, + { + "npc_id": "5147", + "loc_data": "{3207,3270,0,1,0}-" + }, + { + "npc_id": "5148", + "loc_data": "{3229,3347,0,1,1}-{3238,3347,0,1,1}-" + }, + { + "npc_id": "5149", + "loc_data": "{3233,3350,0,1,0}-" + }, + { + "npc_id": "5156", + "loc_data": "{3195,3265,0,1,0}-{3199,3267,0,1,0}-{3203,3262,0,1,5}-" + }, + { + "npc_id": "5157", + "loc_data": "{3194,3265,0,1,0}-{3205,3262,0,1,1}-{3201,3274,0,1,0}-" + }, + { + "npc_id": "5160", + "loc_data": "{3195,3272,0,1,0}-{3195,3268,0,1,0}-{3205,3270,0,1,4}-{3249,3345,0,1,5}-" + }, + { + "npc_id": "5161", + "loc_data": "{2926,3326,0,1,6}-{2924,3324,0,1,1}-{3210,3273,0,1,6}-{3233,3340,0,1,5}-{3241,3344,0,1,3}-" + }, + { + "npc_id": "5164", + "loc_data": "{2410,4456,0,1,1}-{2415,4429,0,1,2}-" + }, + { + "npc_id": "5166", + "loc_data": "{2811,3687,0,1,0}-" + }, + { + "npc_id": "5167", + "loc_data": "{2810,3684,0,1,0}-" + }, + { + "npc_id": "5168", + "loc_data": "{3199,3270,0,1,1}-{2658,4713,0,1,0}-{3209,3259,0,1,3}-{3260,3349,0,1,0}-" + }, + { + "npc_id": "5169", + "loc_data": "{3196,3275,0,1,0}-{2657,4705,0,1,0}-{3234,3345,0,1,0}-" + }, + { + "npc_id": "5170", + "loc_data": "{3052,3516,0,1,0}-" + }, + { + "npc_id": "5171", + "loc_data": "{2860,10054,1,0,0}-" + }, + { + "npc_id": "5173", + "loc_data": "{2769,3611,0,1,7}-{2768,3607,0,1,6}-{2764,3612,0,1,2}-{2763,3608,0,1,6}-{2762,3611,0,1,4}-{2765,3606,0,1,0}-" + }, + { + "npc_id": "5199", + "loc_data": "{3093,3357,0,0,0}-" + }, + { + "npc_id": "5200", + "loc_data": "{3099,3369,0,1,1}-" + }, + { + "npc_id": "5202", + "loc_data": "{3621,3528,0,1,4}-" + }, + { + "npc_id": "5249", + "loc_data": "{3321,3431,0,0,1}-" + }, + { + "npc_id": "5258", + "loc_data": "{2666,2651,0,0,1}-{2668,2651,0,0,1}-" + }, + { + "npc_id": "5260", + "loc_data": "{2665,2651,0,0,1}-{2667,2651,0,0,1}-" + }, + { + "npc_id": "5277", + "loc_data": "{3264,2784,0,0,4}-{3264,2785,0,0,4}-" + }, + { + "npc_id": "5291", + "loc_data": "{3300,2792,0,0,6}-{3282,2807,0,0,6}-{3285,2811,0,0,1}-{3283,2772,0,1,5}-{3281,2771,0,1,7}-{3283,2776,0,1,6}-{3278,2770,0,1,6}-" + }, + { + "npc_id": "5298", + "loc_data": "{2499,3286,0,1,6}-" + }, + { + "npc_id": "5300", + "loc_data": "{2500,3283,0,1,0}-" + }, + { + "npc_id": "5303", + "loc_data": "{2506,3284,0,1,6}-" + }, + { + "npc_id": "5310", + "loc_data": "{3212,3682,0,1,0}-{3228,3680,0,1,6}-{3230,3683,0,1,1}-{3234,3692,0,1,5}-" + }, + { + "npc_id": "5311", + "loc_data": "{3231,3673,0,1,0}-{3225,3677,0,1,3}-{3229,3689,0,1,4}-{3239,3681,0,1,4}-{3236,3694,0,1,6}-" + }, + { + "npc_id": "5312", + "loc_data": "{3210,3667,0,1,4}-{3217,3688,0,1,4}-{3241,3694,0,1,3}-" + }, + { + "npc_id": "5313", + "loc_data": "{3224,3686,0,1,5}-{3243,3688,0,1,1}-{3242,3687,0,1,0}-" + }, + { + "npc_id": "5314", + "loc_data": "{2588,9491,0,1,3}-{2585,9492,0,1,3}-{2586,9491,0,1,5}-{2591,9492,0,1,3}-" + }, + { + "npc_id": "5316", + "loc_data": "{2497,3292,0,1,3}-" + }, + { + "npc_id": "5318", + "loc_data": "{2511,3287,0,1,3}-" + }, + { + "npc_id": "5323", + "loc_data": "{3221,3693,0,1,6}-" + }, + { + "npc_id": "5324", + "loc_data": "{3221,3682,0,1,4}-" + }, + { + "npc_id": "5325", + "loc_data": "{3223,3675,0,1,6}-{3237,3692,0,1,7}-" + }, + { + "npc_id": "5326", + "loc_data": "{3232,3685,0,1,0}-" + }, + { + "npc_id": "5327", + "loc_data": "{3229,3678,0,1,6}-" + }, + { + "npc_id": "5332", + "loc_data": "{3102,3571,0,1,3}-{2855,9571,0,1,0}-{3368,9748,0,1,0}-{3378,9757,0,1,0}-{3383,9746,0,1,0}-{3368,9812,0,1,0}-{3378,9821,0,1,0}-{3383,9810,0,1,0}-{2887,9822,0,1,0}-{2884,9824,0,1,0}-{3008,3595,0,1,0}-{3018,3584,0,1,0}-{3022,3595,0,1,0}-" + }, + { + "npc_id": "5333", + "loc_data": "{3116,3524,0,1,4}-{3106,3548,0,1,2}-{2860,9571,0,1,7}-{3376,9751,0,1,0}-{3380,9756,0,1,0}-{3376,9815,0,1,0}-{3380,9820,0,1,0}-{2886,9816,0,1,0}-{3013,3586,0,1,0}-{3013,3602,0,1,0}-{3025,3597,0,1,0}-" + }, + { + "npc_id": "5334", + "loc_data": "{3107,3528,0,1,1}-{2859,9572,0,1,6}-{3377,9743,0,1,0}-{3377,9754,0,1,0}-{3377,9807,0,1,0}-{3377,9818,0,1,0}-{2885,9819,0,1,0}-{3012,3597,0,1,0}-{3018,3592,0,1,0}-{3018,3599,0,1,0}-{3025,3590,0,1,0}-" + }, + { + "npc_id": "5337", + "loc_data": "{2846,3250,0,1,7}-{2834,3233,0,1,5}-{3100,3563,0,1,1}-{2832,9656,0,1,6}-{3179,3786,0,1,0}-{2885,9825,0,1,0}-{3003,10347,0,1,7}-{3003,10350,0,1,6}-{3003,10357,0,1,4}-{2996,10343,0,1,3}-{2993,10346,0,1,4}-" + }, + { + "npc_id": "5338", + "loc_data": "{2843,3248,0,1,1}-{2840,3240,0,1,3}-{3119,3565,0,1,1}-{2838,9648,0,1,5}-{2831,9654,0,1,1}-{2989,3944,0,1,4}-{2994,10349,0,1,5}-{2998,10350,0,1,0}-{3003,10350,0,1,4}-" + }, + { + "npc_id": "5339", + "loc_data": "{2844,3239,0,1,0}-{3095,3554,0,1,4}-{2831,9655,0,1,7}-" + }, + { + "npc_id": "5340", + "loc_data": "{2848,3246,0,1,3}-{3112,3573,0,1,6}-{2833,9655,0,1,6}-{2982,3947,0,1,0}-" + }, + { + "npc_id": "5341", + "loc_data": "{2840,9633,0,1,1}-{2844,9634,0,1,6}-{2842,9637,0,1,3}-{2641,9889,0,1,0}-{2648,9890,0,1,0}-{2657,9894,0,1,0}-{2658,9888,0,1,0}-" + }, + { + "npc_id": "5342", + "loc_data": "{3276,3659,0,1,0}-" + }, + { + "npc_id": "5343", + "loc_data": "{3282,3662,0,1,0}-" + }, + { + "npc_id": "5345", + "loc_data": "{2501,3294,0,1,3}-" + }, + { + "npc_id": "5346", + "loc_data": "{3279,3654,0,1,0}-" + }, + { + "npc_id": "5347", + "loc_data": "{3288,3650,0,1,0}-" + }, + { + "npc_id": "5348", + "loc_data": "{3290,3653,0,1,0}-" + }, + { + "npc_id": "5349", + "loc_data": "{3099,3354,1,1,3}-" + }, + { + "npc_id": "5350", + "loc_data": "{3116,3367,1,1,3}-" + }, + { + "npc_id": "5351", + "loc_data": "{3110,3358,1,1,1}-" + }, + { + "npc_id": "5352", + "loc_data": "{3121,3359,1,1,4}-" + }, + { + "npc_id": "5355", + "loc_data": "{2873,2950,0,0,0}-{2876,2951,0,0,0}-" + }, + { + "npc_id": "5356", + "loc_data": "{2877,2958,0,0,0}-" + }, + { + "npc_id": "5357", + "loc_data": "{2876,2958,0,0,0}-" + }, + { + "npc_id": "5358", + "loc_data": "{2874,2954,0,0,6}-" + }, + { + "npc_id": "5359", + "loc_data": "{2693,5065,0,1,0}-{2693,5089,0,1,0}-{2704,5091,0,1,0}-{2710,5095,0,1,0}-{2712,5076,0,1,0}-{2714,5108,0,1,0}-{2716,5092,0,1,0}-{2719,5071,0,1,0}-{2722,5061,0,1,0}-{2732,5087,0,1,0}-{2739,5078,0,1,0}-{2740,5104,0,1,0}-{2747,5083,0,1,0}-{2627,5093,0,1,0}-{2629,5061,0,1,0}-{2638,5090,0,1,0}-{2651,5105,0,1,0}-{2654,5079,0,1,0}-{2663,5116,0,1,0}-{2683,5059,0,1,0}-{2685,5111,0,1,0}-" + }, + { + "npc_id": "5361", + "loc_data": "{3176,5543,0,1,3}-{3191,5542,0,1,4}-{3175,5543,0,1,2}-{3178,5541,0,1,2}-{3187,5542,0,1,3}-{3192,5545,0,1,2}-{3192,5542,0,1,3}-{3179,5549,0,1,6}-{1757,5358,0,1,5}-{1760,5357,0,1,5}-{1755,5352,0,1,5}-{1751,5342,0,1,3}-{1745,5342,0,1,6}-{1739,5342,0,1,3}-{1737,5344,0,1,7}-{1739,5347,0,1,6}-{1740,5350,0,1,5}-{1739,5355,0,1,3}-{1747,5363,0,1,4}-{1749,5363,0,1,4}-{1743,5360,0,1,3}-{1739,5356,0,1,0}-" + }, + { + "npc_id": "5362", + "loc_data": "{1774,5361,0,1,3}-{1776,5350,0,1,3}-{1772,5342,0,1,1}-{1772,5336,0,1,4}-{1778,5328,0,1,7}-{1761,5334,0,1,4}-{1754,5337,0,1,7}-{1749,5331,0,0,1}-" + }, + { + "npc_id": "5363", + "loc_data": "{1781,5340,1,1,5}-{1782,5356,1,1,1}-{1767,5343,1,1,6}-{1761,5338,1,1,3}-{1767,5332,1,1,6}-{1757,5326,1,1,7}-{1784,5329,1,1,1}-" + }, + { + "npc_id": "5364", + "loc_data": "{1765,5344,0,1,3}-" + }, + { + "npc_id": "5365", + "loc_data": "{2354,5191,0,1,4}-{2351,5191,0,1,5}-" + }, + { + "npc_id": "5366", + "loc_data": "{2357,5196,0,1,2}-{2356,5188,0,1,4}-{2343,5195,0,1,6}-{2335,5202,0,1,3}-{2323,5211,0,1,1}-" + }, + { + "npc_id": "5367", + "loc_data": "{3092,3717,0,1,0}-{3105,3721,0,1,0}-{3113,3740,0,1,0}-{2312,5189,0,1,7}-" + }, + { + "npc_id": "5368", + "loc_data": "{3096,3738,0,1,0}-{3102,3716,0,1,0}-{3118,3733,0,1,0}-{3128,3741,0,1,0}-" + }, + { + "npc_id": "5369", + "loc_data": "{2345,5195,0,1,3}-{2323,5227,0,1,5}-{2319,5223,0,1,6}-{2264,5136,0,1,1}-" + }, + { + "npc_id": "5370", + "loc_data": "{2347,5195,0,1,3}-{2323,5225,0,1,3}-{2319,5227,0,1,0}-{2323,5227,0,1,3}-{2318,5227,0,1,0}-{2326,5227,0,1,6}-" + }, + { + "npc_id": "5371", + "loc_data": "{2356,5204,0,1,1}-{2324,5223,0,1,1}-" + }, + { + "npc_id": "5375", + "loc_data": "{2029,5236,0,1,6}-{2031,5235,0,1,1}-{2029,5230,0,1,3}-" + }, + { + "npc_id": "5376", + "loc_data": "{2031,5233,0,1,1}-" + }, + { + "npc_id": "5377", + "loc_data": "{2004,5189,0,1,3}-{2002,5207,0,1,3}-{2009,5199,0,1,5}-{2004,5203,0,1,6}-{1989,5192,0,1,6}-{1988,5187,0,1,6}-" + }, + { + "npc_id": "5378", + "loc_data": "{1993,5192,0,1,5}-{1999,5190,0,1,6}-{1989,5187,0,1,4}-{2008,5205,0,1,4}-" + }, + { + "npc_id": "5379", + "loc_data": "{1952,5192,0,1,5}-{1995,5240,0,1,5}-{2010,5186,0,1,4}-{2023,5190,0,1,1}-" + }, + { + "npc_id": "5380", + "loc_data": "{1952,5192,0,1,2}-{2028,5192,0,1,0}-{2031,5186,0,1,0}-{2027,5194,0,1,0}-{2021,5188,0,1,0}-" + }, + { + "npc_id": "5383", + "loc_data": "{3194,4569,0,0,0}-" + }, + { + "npc_id": "5384", + "loc_data": "{3165,4598,0,0,0}-{3167,4577,0,0,0}-" + }, + { + "npc_id": "5385", + "loc_data": "{3191,4595,1,1,1}-{3191,4601,1,1,2}-" + }, + { + "npc_id": "5386", + "loc_data": "{3143,4595,0,1,1}-{3145,4598,0,1,3}-{3182,4577,0,1,1}-{3187,4578,0,1,0}-{3158,4589,1,1,7}-{3194,4599,1,1,4}-" + }, + { + "npc_id": "5387", + "loc_data": "{3158,4584,0,1,4}-{3159,4577,0,1,6}-{3169,4587,0,1,1}-{3152,4569,1,1,1}-" + }, + { + "npc_id": "5388", + "loc_data": "{3156,4567,2,1,0}-" + }, + { + "npc_id": "5389", + "loc_data": "{3157,4568,0,1,6}-{3185,4562,0,1,3}-" + }, + { + "npc_id": "5390", + "loc_data": "{3182,4562,0,1,3}-{3185,4560,0,1,3}-" + }, + { + "npc_id": "5391", + "loc_data": "{3158,4552,0,1,4}-{3163,4569,0,1,1}-{3177,4549,0,1,3}-{3184,4550,0,1,3}-{3158,4560,1,1,4}-{3174,4566,1,1,1}-{3195,4577,1,1,6}-" + }, + { + "npc_id": "5393", + "loc_data": "{3146,4596,0,1,1}-{3163,4598,0,1,3}-{3155,4591,1,1,3}-" + }, + { + "npc_id": "5394", + "loc_data": "{3167,4589,0,1,6}-{3172,4598,0,1,1}-{2677,9688,0,1,1}-{2676,9679,0,1,4}-{2669,9681,0,1,1}-" + }, + { + "npc_id": "5395", + "loc_data": "{3141,4598,0,1,3}-{3170,4592,0,1,6}-{3144,4589,1,1,3}-" + }, + { + "npc_id": "5396", + "loc_data": "{3145,4583,1,1,0}-" + }, + { + "npc_id": "5397", + "loc_data": "{3155,4583,0,1,3}-{3176,4576,1,1,3}-" + }, + { + "npc_id": "5398", + "loc_data": "{3145,4574,1,1,3}-{3182,4586,1,1,3}-" + }, + { + "npc_id": "5399", + "loc_data": "{3140,4557,2,1,4}-{3188,4578,2,1,1}-" + }, + { + "npc_id": "5400", + "loc_data": "{3175,4579,1,1,6}-{3142,4560,2,1,3}-{3159,4569,2,1,1}-" + }, + { + "npc_id": "5401", + "loc_data": "{3151,4573,1,1,4}-" + }, + { + "npc_id": "5402", + "loc_data": "{3154,4559,0,1,6}-{3171,4571,1,1,6}-{3179,4586,1,1,1}-" + }, + { + "npc_id": "5403", + "loc_data": "{3141,4557,0,1,4}-{3182,4577,2,1,6}-" + }, + { + "npc_id": "5404", + "loc_data": "{3143,4555,0,1,4}-{3144,4549,1,1,4}-{3190,4587,1,1,1}-{3186,4576,2,1,3}-" + }, + { + "npc_id": "5405", + "loc_data": "{3163,4559,0,1,4}-{3146,4565,1,1,3}-{3195,4582,1,1,6}-" + }, + { + "npc_id": "5406", + "loc_data": "{3159,4603,1,1,1}-" + }, + { + "npc_id": "5407", + "loc_data": "{3141,4547,1,1,3}-" + }, + { + "npc_id": "5408", + "loc_data": "{3170,4559,1,1,4}-" + }, + { + "npc_id": "5409", + "loc_data": "{3173,4550,0,1,6}-{3190,4551,0,1,2}-" + }, + { + "npc_id": "5410", + "loc_data": "{3190,4561,0,1,5}-" + }, + { + "npc_id": "5413", + "loc_data": "{3187,5450,0,1,6}-{3177,5453,0,1,6}-" + }, + { + "npc_id": "5414", + "loc_data": "{3176,5454,0,1,3}-{3182,5447,0,1,3}-" + }, + { + "npc_id": "5423", + "loc_data": "{3212,3263,0,0,0}-" + }, + { + "npc_id": "5424", + "loc_data": "{2594,3269,0,0,0}-" + }, + { + "npc_id": "5439", + "loc_data": "{3017,3277,0,0,0}-" + }, + { + "npc_id": "5445", + "loc_data": "{2596,3269,0,1,4}-{2571,3907,0,1,7}-{2571,3907,0,1,3}-{2569,3908,0,1,3}-{2571,3908,0,1,3}-{2572,3906,0,1,6}-" + }, + { + "npc_id": "5463", + "loc_data": "{2324,3809,0,1,0}-{2317,3802,0,1,0}-" + }, + { + "npc_id": "5473", + "loc_data": "{2377,10212,0,1,0}-{2392,10226,0,1,0}-{2407,10228,0,1,0}-{2406,10214,0,1,0}-{2420,10214,0,1,0}-" + }, + { + "npc_id": "5474", + "loc_data": "{2390,10216,0,1,0}-{2417,10228,0,1,0}-{2385,10227,0,1,0}-" + }, + { + "npc_id": "5475", + "loc_data": "{2396,10232,0,1,0}-{2402,10225,0,1,0}-{2420,10221,0,1,0}-" + }, + { + "npc_id": "5478", + "loc_data": "{2407,3803,0,1,3}-" + }, + { + "npc_id": "5479", + "loc_data": "{2407,3803,0,1,3}-" + }, + { + "npc_id": "5480", + "loc_data": "{2406,3803,0,1,3}-" + }, + { + "npc_id": "5481", + "loc_data": "{2644,3709,0,1,0}-" + }, + { + "npc_id": "5482", + "loc_data": "{2422,3781,0,1,0}-" + }, + { + "npc_id": "5483", + "loc_data": "{2395,3796,0,1,2}-" + }, + { + "npc_id": "5484", + "loc_data": "{2418,3816,0,1,3}-" + }, + { + "npc_id": "5485", + "loc_data": "{2393,3796,0,1,2}-" + }, + { + "npc_id": "5486", + "loc_data": "{2396,3805,0,1,3}-" + }, + { + "npc_id": "5487", + "loc_data": "{2417,3815,0,1,3}-" + }, + { + "npc_id": "5488", + "loc_data": "{2416,3799,0,0,1}-" + }, + { + "npc_id": "5489", + "loc_data": "{2372,3801,2,0,3}-" + }, + { + "npc_id": "5490", + "loc_data": "{2364,3800,2,0,4}-" + }, + { + "npc_id": "5491", + "loc_data": "{2387,3800,0,0,3}-{2411,3795,0,0,6}-{2417,3825,0,0,1}-" + }, + { + "npc_id": "5492", + "loc_data": "{2387,3797,0,0,3}-{2414,3825,0,0,1}-{2414,3795,0,0,6}-" + }, + { + "npc_id": "5493", + "loc_data": "{2391,3800,0,1,5}-" + }, + { + "npc_id": "5494", + "loc_data": "{2416,3808,0,1,5}-" + }, + { + "npc_id": "5495", + "loc_data": "{2406,3813,0,1,3}-" + }, + { + "npc_id": "5496", + "loc_data": "{2402,3800,0,1,4}-" + }, + { + "npc_id": "5497", + "loc_data": "{2376,10198,0,1,0}-{2384,10202,0,1,0}-{2390,10207,0,1,0}-{2385,10193,0,1,0}-{2419,10192,0,1,0}-{2412,10200,0,1,0}-" + }, + { + "npc_id": "5498", + "loc_data": "{2412,3818,0,1,0}-{2412,3801,0,1,0}-{2392,3802,0,1,0}-" + }, + { + "npc_id": "5499", + "loc_data": "{2403,3807,0,1,4}-" + }, + { + "npc_id": "5500", + "loc_data": "{2395,3812,0,0,2}-" + }, + { + "npc_id": "5501", + "loc_data": "{2408,3816,0,1,3}-" + }, + { + "npc_id": "5502", + "loc_data": "{2409,3814,0,1,3}-" + }, + { + "npc_id": "5504", + "loc_data": "{2336,3799,0,0,4}-" + }, + { + "npc_id": "5505", + "loc_data": "{2334,3800,0,0,4}-" + }, + { + "npc_id": "5506", + "loc_data": "{2334,3798,0,0,4}-" + }, + { + "npc_id": "5507", + "loc_data": "{2311,3781,0,0,1}-" + }, + { + "npc_id": "5508", + "loc_data": "{2646,3710,0,0,4}-" + }, + { + "npc_id": "5509", + "loc_data": "{2336,3808,0,0,6}-" + }, + { + "npc_id": "5510", + "loc_data": "{2333,3804,0,1,1}-" + }, + { + "npc_id": "5511", + "loc_data": "{2327,3794,0,1,6}-" + }, + { + "npc_id": "5512", + "loc_data": "{2319,3795,0,1,3}-" + }, + { + "npc_id": "5513", + "loc_data": "{2352,3797,0,1,2}-" + }, + { + "npc_id": "5514", + "loc_data": "{2333,3795,1,1,4}-{2337,3831,0,1,0}-{2321,3833,0,1,0}-{2399,3852,0,1,0}-" + }, + { + "npc_id": "5515", + "loc_data": "{2330,3799,1,1,3}-{2327,3858,0,1,0}-{2321,3860,0,1,0}-{2343,3862,0,1,0}-" + }, + { + "npc_id": "5516", + "loc_data": "{2329,3808,1,1,4}-{2347,3890,0,1,0}-{2347,3890,0,1,0}-{2393,3861,0,1,0}-" + }, + { + "npc_id": "5517", + "loc_data": "{2328,3830,0,1,0}-{2335,3894,0,1,0}-{2403,3853,0,1,0}-{2405,3860,0,1,0}-" + }, + { + "npc_id": "5518", + "loc_data": "{2338,3798,0,0,1}-" + }, + { + "npc_id": "5519", + "loc_data": "{2338,3800,0,0,6}-" + }, + { + "npc_id": "5520", + "loc_data": "{2338,3810,0,0,3}-" + }, + { + "npc_id": "5521", + "loc_data": "{2324,3832,0,1,0}-{2350,3859,0,1,0}-{2350,3862,0,1,0}-{2352,3857,0,1,0}-{2375,3892,0,1,0}-{2388,3867,0,1,0}-{2384,3863,0,1,0}-{2387,3859,0,1,0}-" + }, + { + "npc_id": "5522", + "loc_data": "{2362,3893,0,1,0}-{2323,3857,0,1,0}-{2331,3860,0,1,0}-{2390,3861,0,1,0}-{2395,3859,0,1,0}-" + }, + { + "npc_id": "5523", + "loc_data": "{2367,3832,0,1,0}-{2319,3854,0,1,0}-{2324,3891,0,1,0}-{2406,3854,0,1,0}-{2405,3863,0,1,0}-{2400,3856,0,1,0}-" + }, + { + "npc_id": "5524", + "loc_data": "{2340,3830,0,1,0}-{2338,3860,0,1,0}-{2339,3895,0,1,0}-{2411,3886,0,1,0}-{2396,3854,0,1,0}-" + }, + { + "npc_id": "5529", + "loc_data": "{2323,3790,0,1,1}-{2323,3795,0,1,0}-{2322,3795,0,1,0}-{2317,3794,0,1,6}-{2317,3790,0,1,3}-{2321,3792,0,1,6}-" + }, + { + "npc_id": "5531", + "loc_data": "{3323,3138,1,1,6}-" + }, + { + "npc_id": "5532", + "loc_data": "{3320,3138,0,1,3}-" + }, + { + "npc_id": "5533", + "loc_data": "{2904,5460,0,1,4}-" + }, + { + "npc_id": "5534", + "loc_data": "{2900,5455,0,1,1}-" + }, + { + "npc_id": "5535", + "loc_data": "{2903,5449,0,1,4}-" + }, + { + "npc_id": "5536", + "loc_data": "{2905,5451,0,1,1}-" + }, + { + "npc_id": "5537", + "loc_data": "{2905,5457,0,1,4}-" + }, + { + "npc_id": "5538", + "loc_data": "{2912,5455,0,1,3}-" + }, + { + "npc_id": "5539", + "loc_data": "{2922,5464,0,1,1}-" + }, + { + "npc_id": "5540", + "loc_data": "{2924,5462,0,1,4}-" + }, + { + "npc_id": "5541", + "loc_data": "{2924,5458,0,1,4}-" + }, + { + "npc_id": "5542", + "loc_data": "{2930,5458,0,1,1}-" + }, + { + "npc_id": "5544", + "loc_data": "{2931,5469,0,1,3}-" + }, + { + "npc_id": "5545", + "loc_data": "{2925,5471,0,1,1}-" + }, + { + "npc_id": "5546", + "loc_data": "{2931,5475,0,1,1}-" + }, + { + "npc_id": "5547", + "loc_data": "{2907,5486,0,1,6}-" + }, + { + "npc_id": "5548", + "loc_data": "{2907,5492,0,1,6}-" + }, + { + "npc_id": "5549", + "loc_data": "{2910,5491,0,1,6}-" + }, + { + "npc_id": "5550", + "loc_data": "{2915,5483,0,1,1}-" + }, + { + "npc_id": "5551", + "loc_data": "{2922,5486,0,1,4}-" + }, + { + "npc_id": "5552", + "loc_data": "{2921,5493,0,1,4}-" + }, + { + "npc_id": "5553", + "loc_data": "{2899,5468,0,1,4}-" + }, + { + "npc_id": "5554", + "loc_data": "{2894,5470,0,1,3}-" + }, + { + "npc_id": "5555", + "loc_data": "{2898,5478,0,1,4}-" + }, + { + "npc_id": "5556", + "loc_data": "{2896,5482,0,1,3}-" + }, + { + "npc_id": "5557", + "loc_data": "{2894,5483,0,1,4}-" + }, + { + "npc_id": "5558", + "loc_data": "{2894,5485,0,1,3}-" + }, + { + "npc_id": "5562", + "loc_data": "{2913,5462,0,0,0}-{2900,5458,0,0,0}-{2908,5455,0,0,0}-{2910,5455,0,0,0}-{2913,5452,0,0,0}-{2914,5453,0,0,0}-" + }, + { + "npc_id": "5563", + "loc_data": "{2911,5474,0,0,0}-" + }, + { + "npc_id": "5574", + "loc_data": "{2836,3066,0,0,0}-" + }, + { + "npc_id": "5576", + "loc_data": "{3072,3336,0,0,0}-{3063,3348,0,0,0}-" + }, + { + "npc_id": "5608", + "loc_data": "{3786,2827,2,0,0}-" + }, + { + "npc_id": "5609", + "loc_data": "{3786,2824,1,0,0}-" + }, + { + "npc_id": "5610", + "loc_data": "{3785,2827,0,0,0}-" + }, + { + "npc_id": "5611", + "loc_data": "{3784,2824,0,0,0}-" + }, + { + "npc_id": "5614", + "loc_data": "{3779,2826,0,0,0}-{3789,2817,0,0,0}-{3794,2821,0,0,0}-{3808,2823,0,0,0}-{3812,2861,0,0,0}-{3813,2822,0,0,0}-{3818,2862,0,0,0}-{3819,2870,0,0,0}-{3821,2824,0,0,0}-{3831,2828,0,0,0}-" + }, + { + "npc_id": "5627", + "loc_data": "{3808,2845,0,0,0}-{3812,2846,0,0,0}-{3815,2844,0,0,3}-{3819,2839,0,0,0}-{3819,2851,0,0,0}-{3819,2838,1,0,0}-{3823,2836,1,0,0}-{3823,2846,1,0,0}-" + }, + { + "npc_id": "5628", + "loc_data": "{3810,2843,0,0,0}-{3813,2844,0,0,0}-{3821,2837,0,0,0}-{3820,2840,1,0,0}-{3820,2851,1,0,0}-{3823,2839,1,0,0}-" + }, + { + "npc_id": "5629", + "loc_data": "{3811,2826,0,0,0}-" + }, + { + "npc_id": "5631", + "loc_data": "{3827,2833,0,0,0}-" + }, + { + "npc_id": "5633", + "loc_data": "{3815,2859,0,0,0}-" + }, + { + "npc_id": "5634", + "loc_data": "{3793,2851,0,0,0}-" + }, + { + "npc_id": "5635", + "loc_data": "{3784,2843,0,0,0}-" + }, + { + "npc_id": "5637", + "loc_data": "{3803,2843,0,0,0}-" + }, + { + "npc_id": "5638", + "loc_data": "{3810,2833,0,0,0}-" + }, + { + "npc_id": "5639", + "loc_data": "{3824,2857,0,0,0}-" + }, + { + "npc_id": "5640", + "loc_data": "{3817,2824,0,0,0}-" + }, + { + "npc_id": "5641", + "loc_data": "{3799,2855,0,0,0}-" + }, + { + "npc_id": "5642", + "loc_data": "{3796,2858,0,0,0}-" + }, + { + "npc_id": "5644", + "loc_data": "{3795,2845,0,0,3}-" + }, + { + "npc_id": "5646", + "loc_data": "{3792,2830,0,0,0}-" + }, + { + "npc_id": "5647", + "loc_data": "{3803,2872,2,0,0}-" + }, + { + "npc_id": "5650", + "loc_data": "{3800,2835,0,0,0}-" + }, + { + "npc_id": "5656", + "loc_data": "{3794,2873,1,0,0}-" + }, + { + "npc_id": "5658", + "loc_data": "{3804,2873,1,0,0}-" + }, + { + "npc_id": "5659", + "loc_data": "{3805,2874,2,0,0}-" + }, + { + "npc_id": "5661", + "loc_data": "{3794,2874,3,0,0}-" + }, + { + "npc_id": "5665", + "loc_data": "{3803,2848,0,0,0}-" + }, + { + "npc_id": "5668", + "loc_data": "{3787,2824,0,0,0}-" + }, + { + "npc_id": "5669", + "loc_data": "{3787,2827,0,0,0}-" + }, + { + "npc_id": "5670", + "loc_data": "{3786,2827,1,0,0}-" + }, + { + "npc_id": "5671", + "loc_data": "{3788,2826,1,0,0}-" + }, + { + "npc_id": "5672", + "loc_data": "{3788,2825,2,0,0}-" + }, + { + "npc_id": "5748", + "loc_data": "{3429,3276,0,0,0}-{3440,3281,0,0,0}-{3437,3272,0,0,0}-{3440,3271,0,0,0}-{3443,3272,0,0,0}-{3445,3279,0,0,0}-{3445,3274,0,0,0}-{3434,3417,0,0,0}-{3431,3415,0,0,0}-{3440,3410,0,0,0}-{3424,3409,0,0,0}-{3425,3410,0,0,0}-{3425,3407,0,0,0}-{3483,3449,0,0,0}-{3490,3444,0,0,0}-{3479,3434,0,0,0}-{3479,3430,0,0,0}-{3481,3473,0,0,0}-" + }, + { + "npc_id": "5750", + "loc_data": "{3290,5544,0,1,4}-{3270,5552,0,1,1}-{3274,5547,0,1,7}-" + }, + { + "npc_id": "5752", + "loc_data": "{2711,5331,0,0,0}-" + }, + { + "npc_id": "5753", + "loc_data": "{2697,5332,0,0,0}-" + }, + { + "npc_id": "5755", + "loc_data": "{2723,5336,0,0,0}-" + }, + { + "npc_id": "5756", + "loc_data": "{2702,5352,1,0,0}-" + }, + { + "npc_id": "5757", + "loc_data": "{2743,5358,0,0,0}-" + }, + { + "npc_id": "5758", + "loc_data": "{2693,5332,0,0,0}-{2729,5329,0,0,0}-" + }, + { + "npc_id": "5761", + "loc_data": "{2725,5349,0,0,0}-" + }, + { + "npc_id": "5764", + "loc_data": "{2712,5342,0,0,0}-" + }, + { + "npc_id": "5765", + "loc_data": "{2694,5333,0,0,0}-" + }, + { + "npc_id": "5766", + "loc_data": "{2701,5352,1,0,0}-" + }, + { + "npc_id": "5767", + "loc_data": "{2695,5331,0,0,0}-{2719,5331,0,0,0}-" + }, + { + "npc_id": "5770", + "loc_data": "{2717,5359,0,0,0}-" + }, + { + "npc_id": "5771", + "loc_data": "{2722,5333,0,0,0}-" + }, + { + "npc_id": "5772", + "loc_data": "{2716,5359,0,0,0}-" + }, + { + "npc_id": "5776", + "loc_data": "{2699,5349,0,0,4}-" + }, + { + "npc_id": "5777", + "loc_data": "{2699,5348,0,0,4}-" + }, + { + "npc_id": "5780", + "loc_data": "{2722,5313,0,0,0}-" + }, + { + "npc_id": "5781", + "loc_data": "{2723,5321,0,0,0}-" + }, + { + "npc_id": "5782", + "loc_data": "{2742,5339,1,0,0}-" + }, + { + "npc_id": "5783", + "loc_data": "{2701,5348,0,0,0}-" + }, + { + "npc_id": "5785", + "loc_data": "{2726,5372,1,0,0}-" + }, + { + "npc_id": "5786", + "loc_data": "{2712,5369,1,0,0}-" + }, + { + "npc_id": "5787", + "loc_data": "{2704,5366,0,0,0}-" + }, + { + "npc_id": "5789", + "loc_data": "{2718,5313,0,0,0}-" + }, + { + "npc_id": "5790", + "loc_data": "{2715,5313,0,0,0}-" + }, + { + "npc_id": "5794", + "loc_data": "{2712,5321,0,0,0}-" + }, + { + "npc_id": "5796", + "loc_data": "{2711,5314,0,0,0}-" + }, + { + "npc_id": "5798", + "loc_data": "{2717,5315,0,1,2}-" + }, + { + "npc_id": "5799", + "loc_data": "{2730,5365,1,0,0}-" + }, + { + "npc_id": "5800", + "loc_data": "{2719,5335,0,1,1}-{2747,5373,0,1,3}-" + }, + { + "npc_id": "5801", + "loc_data": "{2730,5333,0,1,2}-" + }, + { + "npc_id": "5802", + "loc_data": "{2744,5353,1,0,0}-" + }, + { + "npc_id": "5803", + "loc_data": "{2741,5344,1,0,0}-" + }, + { + "npc_id": "5804", + "loc_data": "{2744,5333,1,0,0}-" + }, + { + "npc_id": "5805", + "loc_data": "{2743,5345,1,0,0}-" + }, + { + "npc_id": "5806", + "loc_data": "{2746,5333,1,0,0}-" + }, + { + "npc_id": "5807", + "loc_data": "{2741,5334,1,0,0}-" + }, + { + "npc_id": "5809", + "loc_data": "{2741,5341,1,0,0}-" + }, + { + "npc_id": "5811", + "loc_data": "{2744,5342,1,0,0}-" + }, + { + "npc_id": "5813", + "loc_data": "{2742,5338,1,0,0}-" + }, + { + "npc_id": "5815", + "loc_data": "{2743,5341,1,0,0}-" + }, + { + "npc_id": "5817", + "loc_data": "{2744,5338,1,0,0}-" + }, + { + "npc_id": "5819", + "loc_data": "{2744,5336,1,0,0}-" + }, + { + "npc_id": "5821", + "loc_data": "{2740,5334,1,0,0}-" + }, + { + "npc_id": "5827", + "loc_data": "{2699,5329,0,0,0}-{2699,5335,0,0,0}-{2747,5342,0,0,0}-" + }, + { + "npc_id": "5828", + "loc_data": "{2697,5316,0,0,0}-{3323,9606,0,0,0}-" + }, + { + "npc_id": "5832", + "loc_data": "{2730,5366,1,0,0}-" + }, + { + "npc_id": "5833", + "loc_data": "{3267,3334,0,1,3}-" + }, + { + "npc_id": "5834", + "loc_data": "{3208,3496,0,1,6}-" + }, + { + "npc_id": "5837", + "loc_data": "{3285,3468,0,0,4}-" + }, + { + "npc_id": "5839", + "loc_data": "{3183,5205,0,0,0}-" + }, + { + "npc_id": "5840", + "loc_data": "{3159,5211,0,0,0}-" + }, + { + "npc_id": "5841", + "loc_data": "{3176,5215,0,0,0}-" + }, + { + "npc_id": "5842", + "loc_data": "{3115,3475,0,1,1}-" + }, + { + "npc_id": "5843", + "loc_data": "{3117,3474,0,1,4}-" + }, + { + "npc_id": "5844", + "loc_data": "{3113,3473,0,1,7}-" + }, + { + "npc_id": "5845", + "loc_data": "{3115,3475,0,1,2}-" + }, + { + "npc_id": "5846", + "loc_data": "{3110,3471,0,0,2}-" + }, + { + "npc_id": "5847", + "loc_data": "{3115,3476,0,1,6}-" + }, + { + "npc_id": "5848", + "loc_data": "{3116,3475,0,1,1}-" + }, + { + "npc_id": "5849", + "loc_data": "{3112,3473,0,1,3}-" + }, + { + "npc_id": "5850", + "loc_data": "{3115,3476,0,1,4}-" + }, + { + "npc_id": "5851", + "loc_data": "{3119,3474,0,1,5}-" + }, + { + "npc_id": "5869", + "loc_data": "{2744,5344,0,0,0}-" + }, + { + "npc_id": "5880", + "loc_data": "{2439,5544,0,1,0}-{2485,5535,0,1,0}-" + }, + { + "npc_id": "5881", + "loc_data": "{2436,5540,0,1,0}-" + }, + { + "npc_id": "5882", + "loc_data": "{2437,5549,0,1,0}-{2484,5531,0,1,0}-" + }, + { + "npc_id": "5883", + "loc_data": "{2436,5526,0,1,0}-{2486,5525,0,1,0}-" + }, + { + "npc_id": "5884", + "loc_data": "{2439,5520,0,1,0}-" + }, + { + "npc_id": "5885", + "loc_data": "{2487,5538,0,1,0}-" + }, + { + "npc_id": "5887", + "loc_data": "{2737,5351,1,0,0}-" + }, + { + "npc_id": "5909", + "loc_data": "{3224,3402,0,1,4}-" + }, + { + "npc_id": "5910", + "loc_data": "{3230,3401,0,0,0}-{3284,3491,0,1,1}-" + }, + { + "npc_id": "5914", + "loc_data": "{3204,3419,0,0,6}-" + }, + { + "npc_id": "5915", + "loc_data": "{3255,3488,1,0,6}-" + }, + { + "npc_id": "5916", + "loc_data": "{3250,3429,0,1,5}-" + }, + { + "npc_id": "5917", + "loc_data": "{3176,3431,0,1,5}-{3200,3399,0,1,4}-{3262,3410,0,1,3}-{3261,3424,0,1,2}-" + }, + { + "npc_id": "5918", + "loc_data": "{3233,3394,0,0,7}-{3271,3399,0,1,3}-" + }, + { + "npc_id": "5919", + "loc_data": "{3175,3432,0,1,3}-{3175,3427,0,1,5}-{3172,3430,0,1,2}-{3175,3416,1,1,6}-{3175,3404,1,1,7}-{3205,3379,0,1,6}-{3211,3381,0,1,3}-{3244,3498,0,1,1}-{3244,3503,0,1,6}-{3247,3500,0,1,3}-" + }, + { + "npc_id": "5920", + "loc_data": "{3175,3421,0,1,0}-{3211,3378,0,1,0}-{3220,3461,0,1,3}-{3221,3464,0,1,4}-{3213,3466,0,1,1}-{3214,3461,0,1,5}-{3215,3464,0,1,0}-{3208,3467,0,1,6}-{3209,3460,0,1,4}-{3205,3463,0,1,4}-{3273,3430,0,1,0}-{3272,3429,0,1,1}-{3274,3427,0,1,3}-" + }, + { + "npc_id": "5923", + "loc_data": "{3224,3394,1,1,6}-" + }, + { + "npc_id": "5924", + "loc_data": "{3227,3396,0,1,1}-" + }, + { + "npc_id": "5925", + "loc_data": "{3220,3433,0,1,5}-" + }, + { + "npc_id": "5926", + "loc_data": "{3184,3386,0,1,4}-{3185,3391,0,1,5}-{3229,3392,0,1,6}-{3247,9775,0,1,3}-{3240,9770,0,1,4}-{3235,9766,0,1,3}-" + }, + { + "npc_id": "5927", + "loc_data": "{3250,9776,0,1,3}-" + }, + { + "npc_id": "5928", + "loc_data": "{3249,9772,0,1,5}-" + }, + { + "npc_id": "5929", + "loc_data": "{3245,9772,0,1,7}-{3239,9766,0,1,2}-" + }, + { + "npc_id": "5930", + "loc_data": "{3257,3454,2,0,0}-" + }, + { + "npc_id": "5932", + "loc_data": "{3253,3445,0,0,6}-" + }, + { + "npc_id": "5933", + "loc_data": "{3254,3444,0,0,1}-" + }, + { + "npc_id": "5934", + "loc_data": "{3256,3443,0,0,6}-" + }, + { + "npc_id": "5935", + "loc_data": "{3257,3442,0,0,1}-" + }, + { + "npc_id": "5936", + "loc_data": "{3266,3445,0,0,6}-" + }, + { + "npc_id": "5937", + "loc_data": "{3267,3444,0,0,1}-" + }, + { + "npc_id": "5938", + "loc_data": "{3253,3454,0,0,0}-" + }, + { + "npc_id": "5939", + "loc_data": "{3253,3453,1,1,0}-" + }, + { + "npc_id": "5940", + "loc_data": "{3262,3442,1,1,0}-" + }, + { + "npc_id": "5941", + "loc_data": "{3260,3447,0,0,0}-" + }, + { + "npc_id": "5942", + "loc_data": "{3295,3427,0,0,1}-" + }, + { + "npc_id": "5943", + "loc_data": "{3263,3441,0,0,0}-" + }, + { + "npc_id": "5944", + "loc_data": "{3263,3450,0,0,0}-{1746,4961,0,1,4}-{1761,4938,0,1,4}-{1761,4976,0,1,5}-" + }, + { + "npc_id": "5945", + "loc_data": "{1743,4959,0,1,4}-{1739,4969,0,1,4}-{1748,4941,0,1,4}-{1759,4979,0,1,6}-" + }, + { + "npc_id": "5946", + "loc_data": "{3261,3455,0,1,0}-{1758,4945,0,1,4}-{1757,4935,0,1,4}-{1746,4980,0,1,4}-" + }, + { + "npc_id": "5947", + "loc_data": "{3260,3452,0,1,0}-{3261,3451,2,1,0}-{1735,4950,0,1,4}-{1759,4948,0,1,4}-{1780,4960,0,1,4}-{1760,4974,0,1,5}-" + }, + { + "npc_id": "5952", + "loc_data": "{3326,3443,0,1,5}-" + }, + { + "npc_id": "5954", + "loc_data": "{3310,3425,0,1,5}-" + }, + { + "npc_id": "5956", + "loc_data": "{2659,2664,0,1,3}-" + }, + { + "npc_id": "5958", + "loc_data": "{3357,3415,0,0,3}-" + }, + { + "npc_id": "5959", + "loc_data": "{3352,3449,0,0,0}-" + }, + { + "npc_id": "5960", + "loc_data": "{3354,3449,0,0,0}-" + }, + { + "npc_id": "5961", + "loc_data": "{3352,3446,0,0,0}-" + }, + { + "npc_id": "5962", + "loc_data": "{3357,3446,0,0,0}-" + }, + { + "npc_id": "5963", + "loc_data": "{3363,3445,0,0,0}-" + }, + { + "npc_id": "5964", + "loc_data": "{3324,3445,0,1,7}-" + }, + { + "npc_id": "5965", + "loc_data": "{1759,4955,0,0,0}-" + }, + { + "npc_id": "5966", + "loc_data": "{1754,4960,0,1,4}-" + }, + { + "npc_id": "5967", + "loc_data": "{1735,4950,0,1,4}-{1758,4937,0,1,4}-{1756,4947,0,1,4}-{1771,4960,0,1,4}-{1779,4950,0,1,4}-{1759,4971,0,1,4}-{1773,4983,0,1,4}-" + }, + { + "npc_id": "5971", + "loc_data": "{1742,4964,0,0,0}-" + }, + { + "npc_id": "5972", + "loc_data": "{1781,4954,0,0,0}-" + }, + { + "npc_id": "5973", + "loc_data": "{1774,4964,0,0,0}-" + }, + { + "npc_id": "5974", + "loc_data": "{1774,4954,0,0,0}-" + }, + { + "npc_id": "5975", + "loc_data": "{1740,4979,0,0,0}-" + }, + { + "npc_id": "5976", + "loc_data": "{1742,4954,0,0,0}-" + }, + { + "npc_id": "5977", + "loc_data": "{1735,4964,0,0,0}-" + }, + { + "npc_id": "5978", + "loc_data": "{1752,4938,0,0,0}-" + }, + { + "npc_id": "5979", + "loc_data": "{1765,4979,0,0,0}-" + }, + { + "npc_id": "5980", + "loc_data": "{1775,4979,0,0,0}-" + }, + { + "npc_id": "5981", + "loc_data": "{1750,4979,0,0,0}-" + }, + { + "npc_id": "5982", + "loc_data": "{1735,4954,0,0,0}-" + }, + { + "npc_id": "5984", + "loc_data": "{3263,3452,0,1,0}-{1743,4950,0,1,4}-{1770,4935,0,1,4}-{1772,4962,0,1,4}-{1771,4957,0,1,4}-{1777,4976,0,1,6}-" + }, + { + "npc_id": "5987", + "loc_data": "{2891,3455,0,1,0}-" + }, + { + "npc_id": "5991", + "loc_data": "{2966,3466,0,0,0}-" + }, + { + "npc_id": "5997", + "loc_data": "{2862,3511,0,0,0}-" + }, + { + "npc_id": "5998", + "loc_data": "{2971,3473,0,0,0}-" + }, + { + "npc_id": "6026", + "loc_data": "{3489,3490,0,1,3}-" + }, + { + "npc_id": "6027", + "loc_data": "{3493,3472,0,1,4}-" + }, + { + "npc_id": "6028", + "loc_data": "{3497,3497,0,1,2}-" + }, + { + "npc_id": "6030", + "loc_data": "{3496,3476,0,1,2}-" + }, + { + "npc_id": "6031", + "loc_data": "{3511,3482,1,0,0}-" + }, + { + "npc_id": "6032", + "loc_data": "{3502,3487,0,1,1}-" + }, + { + "npc_id": "6033", + "loc_data": "{3484,3478,0,1,4}-" + }, + { + "npc_id": "6034", + "loc_data": "{3502,3493,0,1,3}-" + }, + { + "npc_id": "6035", + "loc_data": "{3486,3488,0,1,3}-" + }, + { + "npc_id": "6036", + "loc_data": "{3499,3474,1,0,0}-" + }, + { + "npc_id": "6037", + "loc_data": "{3499,3477,0,1,3}-" + }, + { + "npc_id": "6038", + "loc_data": "{3490,3472,1,0,0}-" + }, + { + "npc_id": "6039", + "loc_data": "{3483,3495,0,1,4}-" + }, + { + "npc_id": "6040", + "loc_data": "{3498,3472,1,0,0}-" + }, + { + "npc_id": "6041", + "loc_data": "{3479,3492,0,1,4}-" + }, + { + "npc_id": "6042", + "loc_data": "{3479,3498,0,1,4}-" + }, + { + "npc_id": "6044", + "loc_data": "{3505,3491,1,0,0}-" + }, + { + "npc_id": "6045", + "loc_data": "{3479,3498,1,0,0}-" + }, + { + "npc_id": "6046", + "loc_data": "{2835,3509,0,1,1}-{3306,5510,0,1,5}-{3309,5543,0,1,6}-" + }, + { + "npc_id": "6047", + "loc_data": "{2836,3495,0,1,0}-{2837,3499,0,1,0}-{2839,3502,0,1,0}-{2839,3506,0,1,0}-{2842,3504,0,1,0}-{2844,3507,0,1,0}-" + }, + { + "npc_id": "6050", + "loc_data": "{3264,3008,0,1,0}-{3266,3008,0,1,0}-{3285,3066,0,1,0}-{3322,3032,0,1,0}-{3323,3055,0,1,0}-{3325,3010,0,1,0}-{3174,3010,0,1,0}-{3198,3061,0,1,0}-{3199,3016,0,1,0}-{3219,3125,0,1,0}-{3233,3075,0,1,0}-{3250,3126,0,1,0}-{3223,3011,0,1,0}-{3228,3060,0,1,0}-{3251,3059,0,1,0}-{3310,3076,0,1,0}-" + }, + { + "npc_id": "6051", + "loc_data": "{3266,3010,0,1,0}-{3267,3068,0,1,0}-{3287,3065,0,1,0}-{3287,3067,0,1,0}-{3310,3070,0,1,0}-{3312,3068,0,1,0}-{3320,3054,0,1,0}-{3324,3013,0,1,0}-{3325,3033,0,1,0}-{3153,3047,0,1,0}-{3196,3063,0,1,0}-{3199,3036,0,1,0}-{3215,3092,0,1,0}-{3217,3124,0,1,0}-{3260,3077,0,1,0}-{3223,3035,0,1,0}-{3225,3011,0,1,0}-{3283,3084,0,1,0}-" + }, + { + "npc_id": "6052", + "loc_data": "{2761,3863,0,1,0}-{2764,3858,0,1,0}-{2769,3854,0,1,0}-{2769,3861,0,1,0}-" + }, + { + "npc_id": "6055", + "loc_data": "{2563,4348,0,1,0}-{2620,4348,0,1,0}-{2620,4291,0,1,0}-{2563,4291,0,1,0}-{2572,4339,0,1,0}-{2565,4327,0,1,0}-{2575,4315,0,1,0}-{2586,4306,0,1,0}-{2593,4304,0,1,0}-{2605,4312,0,1,0}-{2614,4330,0,1,0}-" + }, + { + "npc_id": "6056", + "loc_data": "{2565,4320,0,1,0}-{2592,4348,0,1,0}-{2596,4346,0,1,0}-{2576,4333,0,1,0}-{2576,4324,0,1,0}-{2612,4333,0,1,0}-{2617,4329,0,1,0}-{2608,4316,0,1,0}-{2593,4295,0,1,0}-{2587,4307,0,1,0}-" + }, + { + "npc_id": "6057", + "loc_data": "{2604,4348,0,1,0}-{2613,4346,0,1,0}-{2582,4347,0,1,0}-{2568,4333,0,1,0}-{2576,4321,0,1,0}-{2571,4302,0,1,0}-{2587,4296,0,1,0}-{2598,4301,0,1,0}-{2612,4303,0,1,0}-{2607,4321,0,1,0}-{2617,4325,0,1,0}-{2617,4346,0,1,0}-" + }, + { + "npc_id": "6058", + "loc_data": "{2585,4343,0,1,0}-{2599,4338,0,1,0}-{2612,4338,0,1,0}-{2573,4329,0,1,0}-{2572,4320,0,1,0}-{2575,4309,0,1,0}-{2587,4302,0,1,0}-{2606,4319,0,1,0}-{2608,4336,0,1,0}-" + }, + { + "npc_id": "6059", + "loc_data": "{2579,4340,0,1,0}-{2578,4323,0,1,0}-{2580,4302,0,1,0}-{2611,4324,0,1,0}-{2594,4338,0,1,0}-" + }, + { + "npc_id": "6060", + "loc_data": "{2589,4341,0,1,0}-{2569,4315,0,1,0}-{2591,4299,0,1,0}-{2611,4330,0,1,0}-" + }, + { + "npc_id": "6065", + "loc_data": "{2612,4348,0,1,0}-{2606,4340,0,1,0}-{2592,4333,0,1,0}-{2579,4336,0,1,0}-{2565,4340,0,1,0}-{2569,4329,0,1,0}-{2574,4311,0,1,0}-{2570,4304,0,1,0}-{2567,4294,0,1,0}-{2604,4305,0,1,0}-{2610,4293,0,1,0}-{2612,4320,0,1,0}-" + }, + { + "npc_id": "6066", + "loc_data": "{2601,4334,0,1,0}-{2586,4335,0,1,0}-{2572,4334,0,1,0}-{2574,4323,0,1,0}-{2579,4295,0,1,0}-{2588,4298,0,1,0}-{2600,4304,0,1,0}-{2612,4312,0,1,0}-{2607,4329,0,1,0}-{2616,4336,0,1,0}-" + }, + { + "npc_id": "6067", + "loc_data": "{2570,4341,0,0,0}-{2613,4298,0,0,0}-" + }, + { + "npc_id": "6070", + "loc_data": "{2589,4313,0,1,6}-" + }, + { + "npc_id": "6072", + "loc_data": "{2426,4442,0,0,0}-" + }, + { + "npc_id": "6073", + "loc_data": "{2594,4319,0,1,6}-{2424,4436,0,0,0}-" + }, + { + "npc_id": "6074", + "loc_data": "{2603,4306,0,1,4}-{2607,4312,0,1,7}-{2610,4319,0,1,6}-{2613,4326,0,1,5}-{2616,4333,0,1,0}-{2619,4340,0,1,6}-{2614,4344,0,1,3}-{2609,4347,0,1,4}-{2605,4347,0,1,4}-{2599,4345,0,1,3}-{2598,4342,0,1,3}-{2597,4339,0,1,3}-{2596,4336,0,1,3}-{2595,4333,0,1,3}-{2594,4330,0,1,4}-{2587,4330,0,1,3}-{2583,4332,0,1,4}-{2579,4335,0,1,3}-{2576,4339,0,1,4}-{2571,4342,0,1,1}-{2569,4332,0,1,4}-{2572,4326,0,1,6}-{2572,4297,0,1,1}-{2585,4291,0,1,3}-{2599,4297,0,1,4}-{2607,4300,0,1,1}-{2614,4301,0,1,6}-{2619,4305,0,1,0}-{2616,4320,0,1,6}-{2613,4327,0,1,0}-{2611,4335,0,1,6}-{2607,4336,0,1,6}-{2581,4322,0,1,1}-{2578,4315,0,1,6}-{2575,4308,0,1,6}-{2572,4301,0,1,4}-{2567,4295,0,1,3}-{2577,4291,0,1,3}-{2587,4298,0,1,3}-{2595,4307,0,1,3}-{2603,4314,0,1,3}-" + }, + { + "npc_id": "6085", + "loc_data": "{3046,3207,1,0,2}-" + }, + { + "npc_id": "6088", + "loc_data": "{2932,3253,0,1,4}-{2936,3249,0,1,2}-{2933,3244,0,1,4}-{2927,3247,0,1,5}-{2925,3256,0,1,0}-" + }, + { + "npc_id": "6089", + "loc_data": "{2932,3249,0,1,0}-{2929,3253,0,1,3}-{2938,3248,0,1,5}-" + }, + { + "npc_id": "6090", + "loc_data": "{2932,3245,0,1,0}-{2934,3246,0,1,3}-" + }, + { + "npc_id": "6101", + "loc_data": "{2932,9811,0,1,0}-" + }, + { + "npc_id": "6102", + "loc_data": "{1762,5329,0,1,1}-" + }, + { + "npc_id": "6104", + "loc_data": "{1751,5326,0,1,1}-" + }, + { + "npc_id": "6105", + "loc_data": "{1767,5355,0,0,6}-" + }, + { + "npc_id": "6108", + "loc_data": "{2854,3385,0,1,0}-" + }, + { + "npc_id": "6109", + "loc_data": "{2526,3215,0,1,6}-{2545,3231,0,1,4}-{2537,3236,0,1,4}-" + }, + { + "npc_id": "6110", + "loc_data": "{2532,3222,0,1,3}-{2533,3209,0,1,4}-" + }, + { + "npc_id": "6112", + "loc_data": "{3238,3247,0,1,0}-" + }, + { + "npc_id": "6113", + "loc_data": "{3232,3280,0,1,4}-{3222,3289,0,1,1}-" + }, + { + "npc_id": "6114", + "loc_data": "{3232,3283,0,1,1}-" + }, + { + "npc_id": "6115", + "loc_data": "{3033,3236,0,1,3}-{3041,3237,0,1,6}-{3035,3234,0,1,7}-{3028,3205,0,1,4}-{3019,3202,0,1,6}-{3026,3203,0,1,1}-" + }, + { + "npc_id": "6116", + "loc_data": "{3030,3244,0,1,0}-{3025,3203,0,1,3}-{3034,3204,0,1,4}-" + }, + { + "npc_id": "6117", + "loc_data": "{1884,5020,0,0,6}-" + }, + { + "npc_id": "6127", + "loc_data": "{2467,3183,0,0,3}-" + }, + { + "npc_id": "6128", + "loc_data": "{2465,3183,0,0,4}-" + }, + { + "npc_id": "6129", + "loc_data": "{2470,3185,0,0,6}-" + }, + { + "npc_id": "6131", + "loc_data": "{1885,5026,0,0,6}-" + }, + { + "npc_id": "6132", + "loc_data": "{1883,5029,0,0,6}-" + }, + { + "npc_id": "6133", + "loc_data": "{1883,5026,0,0,6}-" + }, + { + "npc_id": "6134", + "loc_data": "{1890,5018,0,0,0}-" + }, + { + "npc_id": "6135", + "loc_data": "{3254,3427,0,1,1}-" + }, + { + "npc_id": "6136", + "loc_data": "{3077,3250,0,1,0}-" + }, + { + "npc_id": "6137", + "loc_data": "{2952,3381,0,1,0}-" + }, + { + "npc_id": "6138", + "loc_data": "{2665,3311,0,0,0}-" + }, + { + "npc_id": "6139", + "loc_data": "{2734,3484,0,1,1}-" + }, + { + "npc_id": "6140", + "loc_data": "{2644,2641,0,0,6}-" + }, + { + "npc_id": "6141", + "loc_data": "{2638,2656,0,0,0}-" + }, + { + "npc_id": "6166", + "loc_data": "{1904,4279,0,0,0}-" + }, + { + "npc_id": "6167", + "loc_data": "{1906,4277,0,0,0}-" + }, + { + "npc_id": "6168", + "loc_data": "{1904,4274,0,0,0}-" + }, + { + "npc_id": "6188", + "loc_data": "{1901,4271,0,0,0}-{1909,4271,0,0,0}-" + }, + { + "npc_id": "6189", + "loc_data": "{3016,3516,0,1,7}-" + }, + { + "npc_id": "6190", + "loc_data": "{1906,4270,0,1,0}-" + }, + { + "npc_id": "6200", + "loc_data": "{2947,3366,0,0,1}-{2949,3366,0,0,1}-{2946,3366,0,0,1}-{2948,3366,0,0,1}-{2945,3366,0,0,1}-{3010,3353,0,0,1}-{3011,3353,0,0,1}-{3012,3353,0,0,1}-{3013,3353,0,0,1}-{3014,3353,0,0,1}-{3015,3353,0,0,1}-" + }, + { + "npc_id": "6202", + "loc_data": "{2912,3749,0,0,0}-" + }, + { + "npc_id": "6203", + "loc_data": "{2924,5322,2,1,4}-" + }, + { + "npc_id": "6205", + "loc_data": "{2933,5329,2,1,1}-" + }, + { + "npc_id": "6210", + "loc_data": "{2837,5336,2,1,4}-{2876,5326,2,1,4}-{2838,5336,2,1,4}-{2898,5306,2,1,5}-{2927,5340,2,1,3}-{2884,5325,2,1,3}-{2886,5325,2,1,1}-{2919,5345,2,1,5}-" + }, + { + "npc_id": "6211", + "loc_data": "{2920,5353,2,1,4}-{2902,5357,2,1,4}-{2885,5315,2,1,4}-{2898,5313,2,1,2}-{2908,5354,2,1,2}-{2924,5354,2,1,6}-{2925,5352,2,1,3}-{2928,5355,2,1,6}-" + }, + { + "npc_id": "6212", + "loc_data": "{2836,5289,2,1,0}-{2869,5287,2,1,1}-{2858,5267,2,1,6}-{2867,5333,2,1,0}-{2877,5321,2,1,1}-{2872,5318,2,1,2}-{2836,5349,2,1,2}-{2921,5293,1,1,6}-{2894,5286,2,1,7}-{2920,5339,2,1,1}-{2888,5326,2,1,3}-{2896,5312,2,1,4}-{2894,5322,2,1,3}-" + }, + { + "npc_id": "6213", + "loc_data": "{2862,5290,2,1,1}-{2838,5347,2,1,6}-{2872,5318,2,1,4}-{2875,5313,2,1,4}-{2865,5327,2,1,4}-{2843,5352,2,1,4}-{2886,5293,2,1,5}-{2909,5297,2,1,0}-{2919,5293,1,1,4}-{2922,5295,1,1,0}-{2919,5293,1,1,5}-{2894,5353,2,1,0}-{2908,5346,2,1,6}-{2913,5355,2,1,3}-{2916,5345,2,1,1}-{2919,5349,2,1,2}-{2922,5356,2,1,1}-{2927,5354,2,1,6}-{2928,5350,2,1,4}-{2931,5357,2,1,3}-{2911,5338,2,1,6}-" + }, + { + "npc_id": "6214", + "loc_data": "{2862,5292,2,1,7}-{2861,5292,2,1,4}-{2864,5319,2,1,7}-{2828,5337,2,1,6}-{2878,5327,2,1,4}-{2853,5327,2,1,4}-{2854,5345,2,1,2}-{2828,5331,2,1,1}-{2919,5284,1,1,0}-{2895,5309,2,1,6}-{2881,5291,2,1,1}-{2924,5292,1,1,6}-{2918,5281,1,1,1}-{2918,5280,1,1,1}-{2884,5312,2,1,2}-{2883,5320,2,1,0}-{2892,5328,2,1,1}-" + }, + { + "npc_id": "6215", + "loc_data": "{2839,5275,2,1,5}-{2845,5286,2,1,0}-{2832,5288,2,1,6}-{2856,5349,2,1,1}-{2862,5334,2,1,0}-{2862,5337,2,1,4}-{2855,5352,2,1,1}-{2880,5293,2,1,4}-{2926,5345,2,1,7}-{2888,5361,2,1,5}-{2886,5313,2,1,3}-{2881,5320,2,1,3}-{2886,5325,2,1,2}-{2889,5322,2,1,4}-{2919,5359,2,1,0}-{2923,5357,2,1,6}-{2891,5353,2,1,1}-" + }, + { + "npc_id": "6216", + "loc_data": "{2865,5306,2,1,3}-{2867,5304,2,1,6}-{2871,5281,2,1,1}-{2864,5279,2,1,4}-{2871,5312,2,1,3}-{2888,5290,2,1,1}-" + }, + { + "npc_id": "6217", + "loc_data": "{2884,5307,2,1,0}-{2899,5304,2,1,3}-{2915,5270,0,1,5}-" + }, + { + "npc_id": "6218", + "loc_data": "{2856,5267,2,1,7}-{2861,5294,2,1,0}-{2836,5290,2,1,6}-{2858,5266,2,1,1}-{2859,5328,2,1,6}-{2911,5268,0,1,4}-{2916,5269,0,1,1}-{2906,5347,2,1,6}-{2913,5358,2,1,6}-{2887,5318,2,1,4}-{2888,5314,2,1,6}-{2931,5345,2,1,2}-{2903,5353,2,1,4}-{2907,5346,2,1,6}-{2921,5351,2,1,2}-{3044,5347,0,1,2}-{3041,5347,0,1,0}-{3031,5346,0,1,2}-{3023,5346,0,1,6}-{3038,5333,0,1,3}-{3048,5333,0,1,1}-{3054,5345,0,1,3}-{3043,5360,0,1,3}-{3030,5362,0,1,3}-{3040,5341,0,1,4}-" + }, + { + "npc_id": "6219", + "loc_data": "{2915,5340,2,1,6}-" + }, + { + "npc_id": "6220", + "loc_data": "{2846,5286,2,1,5}-{2848,5268,2,1,4}-{2931,5356,2,1,3}-{2937,5351,2,1,3}-" + }, + { + "npc_id": "6221", + "loc_data": "{2906,5354,2,1,7}-{2886,5354,2,1,5}-{2885,5352,2,1,2}-{2901,5362,2,1,1}-{2914,5344,2,1,3}-{2918,5343,2,1,2}-{2918,5361,2,1,0}-{2923,5345,2,1,3}-{2924,5352,2,1,4}-" + }, + { + "npc_id": "6222", + "loc_data": "{2831,5301,2,1,4}-" + }, + { + "npc_id": "6229", + "loc_data": "{2841,5285,2,1,3}-{2841,5289,2,1,1}-{2856,5264,2,1,5}-{2842,5282,2,1,6}-" + }, + { + "npc_id": "6230", + "loc_data": "{2843,5265,2,1,4}-{2851,5273,2,1,3}-{2846,5262,2,1,4}-" + }, + { + "npc_id": "6231", + "loc_data": "{2870,5265,2,1,0}-{2869,5266,2,1,7}-{2855,5273,2,1,2}-{2840,5263,2,1,3}-{2831,5285,2,1,4}-" + }, + { + "npc_id": "6232", + "loc_data": "{2872,5261,2,1,4}-{2863,5308,2,1,1}-{2872,5288,2,1,4}-" + }, + { + "npc_id": "6233", + "loc_data": "{2861,5261,2,1,0}-{2852,5264,2,1,0}-{2865,5263,2,1,6}-" + }, + { + "npc_id": "6234", + "loc_data": "{2839,5293,2,1,0}-{2842,5264,2,1,4}-{2862,5313,2,1,3}-" + }, + { + "npc_id": "6235", + "loc_data": "{2864,5270,2,1,3}-{2859,5303,2,1,4}-{2863,5293,2,1,7}-{2862,5286,2,1,1}-{2869,5314,2,1,3}-" + }, + { + "npc_id": "6236", + "loc_data": "{2854,5271,2,1,6}-{2872,5267,2,1,0}-{2858,5269,2,1,5}-" + }, + { + "npc_id": "6237", + "loc_data": "{2840,5290,2,1,6}-{2841,5269,2,1,7}-{2833,5292,2,1,3}-" + }, + { + "npc_id": "6238", + "loc_data": "{2874,5308,2,1,3}-{2851,5276,2,1,2}-{2864,5268,2,1,2}-" + }, + { + "npc_id": "6239", + "loc_data": "{2824,5216,2,1,7}-{2875,5298,2,1,4}-{2846,5288,2,1,0}-{2845,5281,2,1,1}-" + }, + { + "npc_id": "6240", + "loc_data": "{2837,5269,2,1,2}-{2860,5300,2,1,1}-{2852,5311,2,1,4}-{2879,5286,2,1,5}-" + }, + { + "npc_id": "6241", + "loc_data": "{2863,5272,2,1,6}-{2850,5269,2,1,7}-" + }, + { + "npc_id": "6242", + "loc_data": "{2836,5272,2,1,1}-" + }, + { + "npc_id": "6243", + "loc_data": "{2848,5275,2,1,0}-{2869,5304,2,1,4}-{2850,5292,2,1,1}-{2857,5300,2,1,3}-{2874,5287,2,1,4}-" + }, + { + "npc_id": "6244", + "loc_data": "{2847,5299,2,1,6}-{2844,5283,2,1,6}-" + }, + { + "npc_id": "6245", + "loc_data": "{2861,5299,2,1,4}-{2833,5290,2,1,1}-{2851,5262,2,1,0}-" + }, + { + "npc_id": "6246", + "loc_data": "{2855,5311,2,1,1}-{2872,5299,2,1,0}-{2856,5284,2,1,4}-{2872,5315,2,1,1}-" + }, + { + "npc_id": "6247", + "loc_data": "{2894,5265,0,1,2}-" + }, + { + "npc_id": "6254", + "loc_data": "{2917,5272,0,1,7}-{2898,5295,2,1,4}-{2881,5283,2,1,1}-{2883,5311,2,1,2}-{2894,5301,2,1,3}-{2882,5284,2,1,5}-{2890,5292,2,1,4}-{2896,5296,2,1,2}-{2905,5299,2,1,3}-{2905,5301,2,1,5}-{2921,5283,1,1,1}-{2923,5292,1,1,7}-{2906,5299,0,1,6}-{2910,5297,0,1,6}-{2915,5270,0,1,2}-{2910,5269,0,1,5}-" + }, + { + "npc_id": "6255", + "loc_data": "{2922,5290,1,1,5}-{2880,5304,2,1,1}-{2884,5311,2,1,2}-{2885,5311,2,1,2}-{2895,5310,2,1,1}-{2884,5280,2,1,3}-{2885,5293,2,1,6}-{2886,5291,2,1,6}-{2894,5285,2,1,3}-{2893,5286,2,1,7}-{2905,5292,2,1,4}-{2908,5297,2,1,4}-{2910,5297,2,1,6}-{2897,5308,2,1,4}-{2919,5299,1,1,1}-{2921,5292,1,1,5}-{2924,5288,1,1,0}-{2923,5287,1,1,1}-{2908,5300,0,1,6}-{2907,5294,0,1,6}-{2923,5293,1,1,5}-{2919,5298,1,1,1}-{2922,5291,1,1,6}-{2917,5285,1,1,0}-{2905,5295,0,1,6}-{2887,5312,2,1,1}-{2886,5313,2,1,0}-" + }, + { + "npc_id": "6256", + "loc_data": "{2922,5285,1,1,0}-{2886,5295,2,1,1}-{2891,5300,2,1,1}-{2889,5310,2,1,2}-{2887,5299,2,1,6}-{2891,5297,2,1,3}-{2884,5283,2,1,3}-{2885,5286,2,1,3}-{2886,5294,2,1,1}-{2896,5286,2,1,4}-{2908,5302,2,1,1}-{2919,5290,1,1,1}-{2919,5298,1,1,4}-{2918,5298,1,1,4}-{2911,5298,0,1,6}-{2919,5293,1,1,1}-{2917,5294,1,1,2}-{2923,5284,1,1,1}-{2916,5267,0,1,2}-" + }, + { + "npc_id": "6257", + "loc_data": "{2877,5293,2,1,5}-{2879,5329,2,1,5}-{2913,5267,0,1,6}-{2892,5291,2,1,4}-{2886,5311,2,1,0}-{2888,5305,2,1,3}-{2894,5285,2,1,0}-{2900,5287,2,1,0}-{2905,5302,2,1,1}-{2898,5307,2,1,6}-{2918,5292,1,1,3}-{2924,5286,1,1,0}-{2924,5292,1,1,1}-{2920,5297,1,1,3}-{2924,5285,1,1,1}-{2921,5289,1,1,6}-{2923,5294,1,1,0}-{2922,5285,1,1,3}-{2915,5273,0,1,7}-{2915,5271,0,1,4}-{2895,5313,2,1,6}-" + }, + { + "npc_id": "6258", + "loc_data": "{2918,5289,1,1,6}-{2884,5287,2,1,0}-{2895,5294,2,1,4}-{2897,5307,2,1,7}-{2918,5298,1,1,5}-{2917,5291,1,1,4}-{2916,5269,0,1,2}-" + }, + { + "npc_id": "6259", + "loc_data": "{2890,5304,2,1,7}-{2886,5299,2,1,3}-{2891,5297,2,1,5}-{2890,5291,2,1,3}-{2900,5286,2,1,7}-{2905,5303,2,1,1}-{2918,5282,1,1,6}-{2922,5295,1,1,2}-{2905,5297,0,1,6}-{2920,5291,1,1,5}-{2920,5290,1,1,6}-" + }, + { + "npc_id": "6260", + "loc_data": "{2870,5359,2,1,4}-" + }, + { + "npc_id": "6262", + "loc_data": "{2873,5356,0,1,1}-{2866,5358,2,1,6}-" + }, + { + "npc_id": "6264", + "loc_data": "{2870,5354,2,1,4}-" + }, + { + "npc_id": "6266", + "loc_data": "{2868,5362,2,1,3}-" + }, + { + "npc_id": "6268", + "loc_data": "{2856,5355,2,1,7}-{2838,5358,2,1,2}-{2841,5319,2,1,7}-{2856,5331,2,1,2}-{2854,5325,2,1,2}-{2873,5323,2,1,6}-{2860,5321,2,1,7}-{2868,5334,2,1,0}-{2856,5328,2,1,6}-{2855,5332,2,1,1}-{2845,5339,2,1,5}-{2831,5320,2,1,3}-{2847,5334,2,1,1}-{2858,5349,2,1,2}-{2829,5339,2,1,6}-{2856,5361,2,1,5}-{2839,5360,2,1,6}-" + }, + { + "npc_id": "6269", + "loc_data": "{2846,5351,2,1,3}-{2846,5339,2,1,2}-{2840,5327,2,1,1}-{2836,5345,2,1,7}-{2834,5328,2,1,2}-{2857,5359,2,1,4}-{2846,5357,2,1,3}-" + }, + { + "npc_id": "6270", + "loc_data": "{2845,5336,2,1,2}-{2848,5344,2,1,6}-{2842,5328,2,1,6}-{2844,5349,2,1,2}-{2836,5323,2,1,4}-{2832,5353,2,1,6}-{2848,5358,2,1,7}-" + }, + { + "npc_id": "6271", + "loc_data": "{2840,5330,2,1,0}-{2859,5328,2,1,6}-{2873,5317,2,1,3}-{2862,5332,2,1,2}-{2869,5332,2,1,6}-" + }, + { + "npc_id": "6272", + "loc_data": "{2838,5326,2,1,4}-{2870,5313,2,1,1}-{2865,5332,2,1,0}-{2838,5334,2,1,6}-{2837,5353,2,1,7}-" + }, + { + "npc_id": "6273", + "loc_data": "{2832,5324,2,1,7}-{2864,5325,2,1,2}-{2873,5325,2,1,7}-{2873,5324,2,1,7}-{2865,5336,2,1,6}-{2840,5333,2,1,6}-{2836,5336,2,1,4}-{2838,5354,2,1,6}-" + }, + { + "npc_id": "6274", + "loc_data": "{2872,5307,2,1,5}-{2858,5325,2,1,4}-{2873,5319,2,1,6}-{2867,5333,2,1,6}-{2866,5333,2,1,0}-{2839,5331,2,1,5}-{2837,5355,2,1,6}-" + }, + { + "npc_id": "6275", + "loc_data": "{2865,5340,2,1,1}-{2869,5326,2,1,7}-{2875,5318,2,1,1}-{2875,5314,2,1,1}-{2878,5313,2,1,3}-{2879,5322,2,1,3}-{2859,5317,2,1,6}-{2858,5319,2,1,4}-{2878,5320,2,1,0}-{2863,5337,2,1,7}-{2862,5338,2,1,7}-{2867,5341,2,1,6}-{2852,5312,2,1,2}-" + }, + { + "npc_id": "6276", + "loc_data": "{2856,5360,2,1,7}-{2854,5346,2,1,3}-{2845,5332,2,1,0}-{2845,5344,2,1,3}-{2848,5349,2,1,6}-{2837,5347,2,1,3}-{2835,5324,2,1,2}-{2835,5321,2,1,5}-{2858,5349,2,1,4}-{2830,5339,2,1,3}-{2828,5332,2,1,3}-{2846,5358,2,1,4}-{2855,5356,2,1,7}-" + }, + { + "npc_id": "6277", + "loc_data": "{2843,5341,2,1,3}-{2843,5331,2,1,3}-{2847,5341,2,1,5}-{2852,5350,2,1,1}-{2844,5341,2,1,6}-{2843,5347,2,1,1}-{2836,5325,2,1,6}-{2826,5335,2,1,2}-{2837,5351,2,1,4}-{2845,5353,2,1,3}-{2840,5361,2,1,3}-" + }, + { + "npc_id": "6278", + "loc_data": "{2845,5359,2,1,4}-{2830,5318,2,1,3}-{2848,5342,2,1,0}-{2846,5332,2,1,1}-{2843,5320,2,1,3}-{2838,5329,2,1,1}-{2855,5349,2,1,0}-{2837,5342,2,1,1}-{2827,5331,2,1,6}-{2830,5315,2,1,6}-{2845,5352,2,1,6}-{2839,5360,2,1,6}-{2851,5359,2,1,7}-{2860,5353,2,1,6}-{2792,5280,2,1,6}-" + }, + { + "npc_id": "6279", + "loc_data": "{2857,5315,2,1,6}-{2859,5318,2,1,5}-{2858,5329,2,1,3}-{2879,5326,2,1,4}-" + }, + { + "npc_id": "6280", + "loc_data": "{2869,5332,2,1,6}-{2871,5313,2,1,2}-{2879,5330,2,1,2}-{2877,5327,2,1,0}-" + }, + { + "npc_id": "6281", + "loc_data": "{2865,5316,2,1,2}-{2861,5333,2,1,2}-" + }, + { + "npc_id": "6282", + "loc_data": "{2874,5318,2,1,0}-{2859,5316,2,1,3}-{2878,5329,2,1,2}-{2858,5330,2,1,2}-" + }, + { + "npc_id": "6283", + "loc_data": "{2877,5326,2,1,2}-{2857,5328,2,1,3}-{2861,5315,2,1,7}-" + }, + { + "npc_id": "6346", + "loc_data": "{2799,3186,0,1,7}-{2797,3169,0,0,0}-{2793,3161,0,1,3}-" + }, + { + "npc_id": "6347", + "loc_data": "{2799,3167,0,0,0}-{2787,3188,0,1,1}-" + }, + { + "npc_id": "6348", + "loc_data": "{2793,3158,0,1,3}-{2798,3154,0,1,4}-{2796,3189,0,1,0}-" + }, + { + "npc_id": "6349", + "loc_data": "{2797,3186,0,1,6}-{2793,3161,0,1,0}-" + }, + { + "npc_id": "6350", + "loc_data": "{2798,3182,0,1,7}-{2793,3161,0,1,1}-" + }, + { + "npc_id": "6351", + "loc_data": "{3041,3951,0,1,0}-{3043,3958,0,1,0}-" + }, + { + "npc_id": "6352", + "loc_data": "{3039,3955,0,1,0}-{3043,3951,0,1,0}-" + }, + { + "npc_id": "6353", + "loc_data": "{3040,3955,0,1,0}-{3039,3950,0,1,0}-" + }, + { + "npc_id": "6354", + "loc_data": "{3041,3950,0,1,0}-{3041,3956,0,1,0}-" + }, + { + "npc_id": "6355", + "loc_data": "{3043,3950,0,1,0}-{3043,3956,0,1,0}-" + }, + { + "npc_id": "6356", + "loc_data": "{3041,3953,0,1,0}-" + }, + { + "npc_id": "6357", + "loc_data": "{3359,2969,0,1,3}-" + }, + { + "npc_id": "6362", + "loc_data": "{3270,4856,0,1,3}-" + }, + { + "npc_id": "6363", + "loc_data": "{3190,5523,0,1,3}-{3194,5530,0,1,3}-{3251,5455,0,1,4}-{3258,5456,0,1,6}-{3257,5451,0,1,6}-{3257,5464,0,1,2}-{3256,5473,0,1,2}-{3244,5469,0,1,1}-{3225,5485,0,1,5}-{3218,5482,0,1,7}-{3219,5486,0,1,4}-{3207,5461,0,1,6}-{3208,5458,0,1,3}-{3219,5528,0,1,2}-{3223,5520,0,1,3}-{3225,5511,0,1,0}-{3236,5511,0,1,6}-{3232,5523,0,1,0}-{3239,5530,0,1,4}-{3233,5546,0,1,3}-{3222,5539,0,1,5}-{3269,4829,0,1,3}-{3271,4823,0,1,2}-{3283,4809,0,1,3}-" + }, + { + "npc_id": "6364", + "loc_data": "{3188,5529,0,1,3}-{3194,5531,0,1,1}-{3188,5527,0,1,3}-{3222,5486,0,1,3}-{3221,5482,0,1,4}-{3212,5459,0,1,6}-{3210,5462,0,1,2}-{3234,5510,0,1,6}-{3271,4809,0,1,3}-" + }, + { + "npc_id": "6365", + "loc_data": "{3267,4817,0,1,4}-{3290,4803,0,1,3}-" + }, + { + "npc_id": "6367", + "loc_data": "{3207,5466,0,1,6}-{3223,5462,0,1,1}-{3237,5524,0,1,6}-{3229,5510,0,1,4}-{3276,4808,0,1,3}-{3291,4812,0,1,6}-" + }, + { + "npc_id": "6368", + "loc_data": "{3226,5458,0,1,3}-{3222,5470,0,1,6}-{3238,5541,0,1,1}-{3226,5540,0,1,7}-{3222,5522,0,1,7}-" + }, + { + "npc_id": "6369", + "loc_data": "{3268,4825,0,1,6}-{3268,4809,0,1,4}-{3288,4803,0,1,6}-{3298,4810,0,1,4}-" + }, + { + "npc_id": "6376", + "loc_data": "{2925,2976,0,1,1}-{2909,2978,0,1,5}-" + }, + { + "npc_id": "6377", + "loc_data": "{2920,2973,0,1,6}-{2919,2976,0,1,6}-{2910,2978,0,1,7}-" + }, + { + "npc_id": "6379", + "loc_data": "{2894,2995,0,0,0}-{2909,2970,0,0,0}-{3303,5485,0,1,1}-{3320,5494,0,1,4}-{3313,5490,0,1,4}-{3315,5484,0,1,3}-{3323,5471,0,1,6}-{3319,5471,0,1,4}-{3323,5477,0,1,0}-{3310,5484,0,1,4}-{3313,5488,0,1,6}-{3309,5481,0,1,1}-{3320,5495,0,1,0}-" + }, + { + "npc_id": "6380", + "loc_data": "{2883,2994,0,0,0}-{2882,2994,0,0,0}-{3319,5490,0,1,5}-{3298,5486,0,1,3}-{3312,5480,0,1,4}-{3315,5480,0,1,1}-{3308,5482,0,1,2}-{3321,5477,0,1,0}-{3317,5470,0,1,6}-{3324,5472,0,1,6}-{3311,5482,0,1,0}-" + }, + { + "npc_id": "6383", + "loc_data": "{2888,3001,0,0,0}-{2891,3002,0,0,0}-{2890,2998,0,0,0}-{2887,2994,0,0,0}-{2901,2991,0,0,0}-{2905,2990,0,0,0}-{2886,2989,0,0,0}-{2927,2979,0,0,0}-{2926,2973,0,0,0}-{2919,2973,0,0,0}-{2919,2976,0,0,0}-{2920,2979,0,0,0}-" + }, + { + "npc_id": "6386", + "loc_data": "{2683,3326,0,0,0}-" + }, + { + "npc_id": "6387", + "loc_data": "{3275,4808,0,1,3}-{3276,4808,0,1,4}-" + }, + { + "npc_id": "6388", + "loc_data": "{3369,2999,0,1,7}-{3368,2995,0,1,6}-{3362,2997,0,1,3}-{3361,2988,0,1,2}-{3367,2988,0,1,7}-{3379,2983,0,1,1}-" + }, + { + "npc_id": "6390", + "loc_data": "{1707,4814,0,0,6}-" + }, + { + "npc_id": "6394", + "loc_data": "{2703,5366,0,0,0}-" + }, + { + "npc_id": "6396", + "loc_data": "{2791,4279,0,0,0}-" + }, + { + "npc_id": "6405", + "loc_data": "{2799,4260,0,1,0}-" + }, + { + "npc_id": "6406", + "loc_data": "{2765,4267,0,1,0}-" + }, + { + "npc_id": "6407", + "loc_data": "{2802,4246,0,1,0}-" + }, + { + "npc_id": "6408", + "loc_data": "{2770,4238,0,1,0}-" + }, + { + "npc_id": "6409", + "loc_data": "{2787,4262,0,1,0}-{2792,4275,0,1,0}-" + }, + { + "npc_id": "6410", + "loc_data": "{2766,4257,0,1,0}-" + }, + { + "npc_id": "6416", + "loc_data": "{2801,4258,0,1,0}-" + }, + { + "npc_id": "6417", + "loc_data": "{2765,4264,0,1,0}-{2777,4260,0,1,0}-" + }, + { + "npc_id": "6418", + "loc_data": "{2799,4243,0,1,0}-" + }, + { + "npc_id": "6419", + "loc_data": "{2771,4237,0,1,0}-" + }, + { + "npc_id": "6420", + "loc_data": "{2796,4277,0,1,0}-" + }, + { + "npc_id": "6421", + "loc_data": "{2768,4254,0,1,0}-" + }, + { + "npc_id": "6427", + "loc_data": "{2802,4259,0,1,0}-" + }, + { + "npc_id": "6428", + "loc_data": "{2768,4268,0,1,0}-" + }, + { + "npc_id": "6429", + "loc_data": "{2776,4252,0,1,0}-{2805,4242,0,1,0}-" + }, + { + "npc_id": "6430", + "loc_data": "{2769,4236,0,1,0}-" + }, + { + "npc_id": "6431", + "loc_data": "{2792,4260,0,1,0}-{2796,4275,0,1,0}-" + }, + { + "npc_id": "6432", + "loc_data": "{2766,4255,0,1,0}-" + }, + { + "npc_id": "6438", + "loc_data": "{2790,4254,0,1,0}-{2800,4256,0,1,0}-" + }, + { + "npc_id": "6439", + "loc_data": "{2766,4265,0,1,0}-" + }, + { + "npc_id": "6440", + "loc_data": "{2789,4248,0,1,0}-{2802,4244,0,1,0}-" + }, + { + "npc_id": "6441", + "loc_data": "{2771,4241,0,1,0}-{2777,4252,0,1,0}-" + }, + { + "npc_id": "6442", + "loc_data": "{2795,4273,0,1,0}-" + }, + { + "npc_id": "6443", + "loc_data": "{2767,4252,0,1,0}-{2776,4250,0,1,0}-" + }, + { + "npc_id": "6449", + "loc_data": "{2792,4252,0,1,0}-{2800,4254,0,1,0}-" + }, + { + "npc_id": "6450", + "loc_data": "{2764,4266,0,1,0}-{2781,4261,0,1,0}-" + }, + { + "npc_id": "6451", + "loc_data": "{2802,4243,0,1,0}-" + }, + { + "npc_id": "6452", + "loc_data": "{2772,4235,0,1,0}-" + }, + { + "npc_id": "6453", + "loc_data": "{2797,4272,0,1,0}-" + }, + { + "npc_id": "6454", + "loc_data": "{2765,4253,0,1,0}-{2779,4256,0,1,0}-" + }, + { + "npc_id": "6458", + "loc_data": "{2784,4249,0,1,0}-" + }, + { + "npc_id": "6459", + "loc_data": "{2778,4264,0,1,0}-{2784,4252,0,1,0}-" + }, + { + "npc_id": "6460", + "loc_data": "{2783,4251,0,1,0}-{2789,4264,0,1,0}-{2801,4252,0,1,0}-" + }, + { + "npc_id": "6461", + "loc_data": "{2787,4250,0,1,0}-{2791,4249,0,1,0}-" + }, + { + "npc_id": "6462", + "loc_data": "{2785,4248,0,1,0}-{2786,4251,0,1,0}-{2801,4242,0,1,0}-" + }, + { + "npc_id": "6463", + "loc_data": "{2773,4238,0,1,0}-{2779,4248,0,1,0}-{2785,4250,0,1,0}-" + }, + { + "npc_id": "6464", + "loc_data": "{2796,4267,0,1,0}-" + }, + { + "npc_id": "6465", + "loc_data": "{2764,4251,0,1,0}-" + }, + { + "npc_id": "6482", + "loc_data": "{2801,4260,0,0,0}-" + }, + { + "npc_id": "6483", + "loc_data": "{2804,4246,0,0,0}-" + }, + { + "npc_id": "6484", + "loc_data": "{2795,4276,0,0,0}-" + }, + { + "npc_id": "6485", + "loc_data": "{2766,4250,0,0,0}-" + }, + { + "npc_id": "6486", + "loc_data": "{2774,4236,0,0,0}-" + }, + { + "npc_id": "6487", + "loc_data": "{2765,4268,0,0,0}-" + }, + { + "npc_id": "6488", + "loc_data": "{2784,4255,1,0,0}-" + }, + { + "npc_id": "6489", + "loc_data": "{2787,4266,0,0,0}-" + }, + { + "npc_id": "6498", + "loc_data": "{2796,4256,0,1,0}-" + }, + { + "npc_id": "6499", + "loc_data": "{2793,4247,0,1,0}-" + }, + { + "npc_id": "6500", + "loc_data": "{2793,4265,0,1,0}-" + }, + { + "npc_id": "6501", + "loc_data": "{2772,4256,0,1,0}-" + }, + { + "npc_id": "6502", + "loc_data": "{2775,4247,0,1,0}-" + }, + { + "npc_id": "6503", + "loc_data": "{2775,4265,0,1,0}-" + }, + { + "npc_id": "6521", + "loc_data": "{3161,3475,0,0,6}-" + }, + { + "npc_id": "6522", + "loc_data": "{3168,3475,0,0,6}-" + }, + { + "npc_id": "6523", + "loc_data": "{3173,3498,0,0,1}-" + }, + { + "npc_id": "6524", + "loc_data": "{3156,3481,0,0,1}-" + }, + { + "npc_id": "6525", + "loc_data": "{3175,3481,0,0,1}-" + }, + { + "npc_id": "6526", + "loc_data": "{3152,3490,0,0,1}-" + }, + { + "npc_id": "6527", + "loc_data": "{3154,3498,0,0,1}-" + }, + { + "npc_id": "6528", + "loc_data": "{3165,3491,0,0,1}-" + }, + { + "npc_id": "6529", + "loc_data": "{3164,3488,0,0,6}-" + }, + { + "npc_id": "6530", + "loc_data": "{3164,3491,0,0,1}-" + }, + { + "npc_id": "6531", + "loc_data": "{3165,3488,0,0,6}-" + }, + { + "npc_id": "6532", + "loc_data": "{3163,3489,0,0,3}-" + }, + { + "npc_id": "6533", + "loc_data": "{3166,3489,0,0,4}-" + }, + { + "npc_id": "6534", + "loc_data": "{3166,3490,0,0,4}-" + }, + { + "npc_id": "6535", + "loc_data": "{3163,3490,0,0,3}-" + }, + { + "npc_id": "6538", + "loc_data": "{3189,3690,0,0,3}-" + }, + { + "npc_id": "6731", + "loc_data": "{2655,5615,0,1,4}-" + }, + { + "npc_id": "6750", + "loc_data": "{2577,3078,0,1,3}-" + }, + { + "npc_id": "6753", + "loc_data": "{3381,2816,1,1,0}-{3061,4672,1,1,0}-" + }, + { + "npc_id": "6754", + "loc_data": "{3386,2824,1,1,0}-{3066,4680,1,1,0}-" + }, + { + "npc_id": "6755", + "loc_data": "{3382,2820,1,1,0}-{3062,4676,1,1,0}-" + }, + { + "npc_id": "6756", + "loc_data": "{3384,2822,1,1,0}-{3064,4678,1,1,0}-" + }, + { + "npc_id": "6761", + "loc_data": "{3424,2828,1,1,3}-{3430,2835,1,1,3}-{3436,2830,1,1,3}-" + }, + { + "npc_id": "6762", + "loc_data": "{3420,2829,1,1,3}-{3429,2827,1,1,3}-{3432,2832,1,1,3}-" + }, + { + "npc_id": "6763", + "loc_data": "{3427,2832,1,1,3}-{3432,2828,1,1,3}-{3435,2835,1,1,3}-" + }, + { + "npc_id": "6764", + "loc_data": "{3415,2840,1,1,0}-{3426,2852,1,1,0}-{3439,2857,1,1,0}-" + }, + { + "npc_id": "6765", + "loc_data": "{3418,2851,1,1,0}-{3432,2854,1,1,0}-" + }, + { + "npc_id": "6766", + "loc_data": "{3406,2837,1,1,0}-{3434,2848,1,1,0}-" + }, + { + "npc_id": "6767", + "loc_data": "{3409,2844,1,1,0}-{3421,2855,1,1,0}-" + }, + { + "npc_id": "6768", + "loc_data": "{3414,2844,1,1,0}-{3439,2851,1,1,0}-" + }, + { + "npc_id": "6773", + "loc_data": "{3358,9233,1,1,0}-{3363,9246,1,1,0}-{3369,9233,1,1,0}-{3373,9246,1,1,0}-{3377,9244,1,1,0}-{3381,9225,1,1,0}-{3389,9241,1,1,0}-{3391,9237,1,1,0}-{3391,9230,1,1,0}-{3439,2808,0,1,0}-" + }, + { + "npc_id": "6774", + "loc_data": "{3361,9238,1,1,0}-{3363,9241,1,1,0}-{3373,9241,1,1,0}-{3374,9225,1,1,0}-{3379,9230,1,1,0}-{3383,9232,1,1,0}-{3387,9229,1,1,0}-{3389,9236,1,1,0}-{3435,2808,0,1,2}-" + }, + { + "npc_id": "6776", + "loc_data": "{3441,2810,0,1,0}-{3445,2813,0,1,0}-" + }, + { + "npc_id": "6777", + "loc_data": "{3432,2810,0,1,4}-" + }, + { + "npc_id": "6778", + "loc_data": "{3440,2806,0,1,0}-" + }, + { + "npc_id": "6779", + "loc_data": "{3337,2762,0,1,0}-{3340,2767,0,1,0}-{3345,2763,0,1,0}-{3350,2766,0,1,0}-{3352,2761,0,1,0}-{3356,2769,0,1,0}-{3358,2758,0,1,0}-{3359,2763,0,1,0}-{3365,2769,0,1,0}-{3368,2764,0,1,0}-{3375,2762,0,1,0}-{3392,2759,0,1,2}-{3408,2763,0,1,7}-{3410,2786,0,1,2}-{3420,2778,0,1,6}-{3427,2792,0,1,6}-{3429,2802,0,1,4}-" + }, + { + "npc_id": "6780", + "loc_data": "{3366,9254,1,1,6}-{3398,9232,1,1,0}-{3409,9230,1,1,0}-" + }, + { + "npc_id": "6781", + "loc_data": "{3363,9231,1,1,0}-{3369,9254,1,1,6}-{3370,9226,1,1,0}-{3397,9225,1,1,0}-{3408,9226,1,1,0}-" + }, + { + "npc_id": "6785", + "loc_data": "{3442,9245,1,0,1}-" + }, + { + "npc_id": "6786", + "loc_data": "{3409,2812,1,0,0}-" + }, + { + "npc_id": "6787", + "loc_data": "{3408,2813,1,0,0}-" + }, + { + "npc_id": "6788", + "loc_data": "{3368,9263,1,0,6}-" + }, + { + "npc_id": "6891", + "loc_data": "{2598,3272,0,1,0}-" + }, + { + "npc_id": "6893", + "loc_data": "{2926,3435,0,1,2}-" + }, + { + "npc_id": "6894", + "loc_data": "{2928,3432,0,1,0}-" + }, + { + "npc_id": "6895", + "loc_data": "{2927,3431,0,1,0}-" + }, + { + "npc_id": "6896", + "loc_data": "{2573,3082,0,1,2}-" + }, + { + "npc_id": "6897", + "loc_data": "{2574,3083,0,1,0}-" + }, + { + "npc_id": "6917", + "loc_data": "{2916,3082,0,0,0}-{2917,3089,0,0,0}-{2912,3090,0,0,0}-" + }, + { + "npc_id": "6918", + "loc_data": "{2917,3088,0,1,4}-{2917,3092,0,1,4}-" + }, + { + "npc_id": "6921", + "loc_data": "{2954,3273,0,1,6}-{2974,3448,0,1,4}-{2971,3442,0,1,6}-{2968,3451,0,1,1}-{2967,3439,0,1,4}-{2965,3451,0,1,5}-" + }, + { + "npc_id": "6942", + "loc_data": "{2890,3100,0,1,4}-" + }, + { + "npc_id": "6944", + "loc_data": "{2855,3028,0,0,0}-{2841,3039,0,0,0}-{2838,3031,0,0,0}-{2836,3014,0,0,0}-{2839,3022,0,0,0}-" + }, + { + "npc_id": "6962", + "loc_data": "{2842,5222,0,1,6}-" + }, + { + "npc_id": "6971", + "loc_data": "{2926,3443,0,0,5}-" + }, + { + "npc_id": "6972", + "loc_data": "{2922,3482,0,1,0}-" + }, + { + "npc_id": "6973", + "loc_data": "{2893,3419,0,1,0}-" + }, + { + "npc_id": "6974", + "loc_data": "{2897,3419,0,1,0}-" + }, + { + "npc_id": "6975", + "loc_data": "{2928,3480,0,1,0}-{2932,3485,0,1,0}-" + }, + { + "npc_id": "6976", + "loc_data": "{2897,3432,1,1,0}-{2884,3418,0,1,0}-{2884,3434,0,1,0}-{2902,3449,0,1,0}-" + }, + { + "npc_id": "6977", + "loc_data": "{2890,3435,0,1,0}-" + }, + { + "npc_id": "6978", + "loc_data": "{2896,3437,0,1,0}-{2917,3446,0,1,0}-" + }, + { + "npc_id": "6979", + "loc_data": "{2888,3448,0,1,0}-" + }, + { + "npc_id": "6981", + "loc_data": "{2883,3431,0,1,0}-{2900,3449,0,1,0}-" + }, + { + "npc_id": "6982", + "loc_data": "{2896,3429,0,1,0}-{2918,3485,0,1,0}-" + }, + { + "npc_id": "6983", + "loc_data": "{2908,3441,0,1,0}-{2926,3488,0,1,0}-" + }, + { + "npc_id": "6985", + "loc_data": "{2894,3438,0,1,0}-{2913,3451,0,1,0}-" + }, + { + "npc_id": "6986", + "loc_data": "{2887,3441,0,1,0}-" + }, + { + "npc_id": "6987", + "loc_data": "{2894,3445,0,1,0}-" + }, + { + "npc_id": "6996", + "loc_data": "{3169,3266,0,0,3}-{3173,3274,0,0,3}-{3259,3206,0,0,3}-{3259,3204,0,0,3}-{2689,3598,0,0,4}-" + }, + { + "npc_id": "6997", + "loc_data": "{3002,3257,0,0,0}-{3007,3261,0,0,0}-{3058,3429,0,0,0}-{3059,3420,0,0,0}-{3059,3425,0,0,0}-{3049,3429,0,0,0}-" + }, + { + "npc_id": "7003", + "loc_data": "{2582,9895,0,1,7}-{3230,5493,0,1,1}-{3224,5497,0,1,5}-{3253,5535,0,1,7}-" + }, + { + "npc_id": "7004", + "loc_data": "{2581,9891,0,1,2}-{3225,5495,0,1,4}-{3256,5540,0,1,4}-{3247,5536,0,1,6}-" + }, + { + "npc_id": "7005", + "loc_data": "{2487,2924,0,1,0}-" + }, + { + "npc_id": "7009", + "loc_data": "{3282,3467,0,0,0}-" + }, + { + "npc_id": "7010", + "loc_data": "{2204,3229,0,1,3}-{2204,3229,0,1,3}-{2204,3229,0,1,3}-{2243,3200,0,1,3}-{2268,3239,0,1,3}-{2268,3239,0,1,3}-{2268,3239,0,1,3}-{2261,3260,0,1,3}-{2261,3260,0,1,3}-{2261,3260,0,1,3}-" + }, + { + "npc_id": "7011", + "loc_data": "{2243,3200,0,1,3}-{2268,3239,0,1,3}-{2261,3260,0,1,3}-{2261,3260,0,1,3}-" + }, + { + "npc_id": "7012", + "loc_data": "{2226,3143,0,1,3}-{2226,3143,0,1,3}-{2226,3143,0,1,3}-{2223,3146,0,1,3}-{2223,3146,0,1,3}-{2180,3201,0,1,3}-{2180,3201,0,1,3}-{2182,3204,0,1,3}-{2288,3147,0,1,3}-{2288,3147,0,1,3}-{2288,3147,0,1,3}-{2247,3187,0,1,3}-{2247,3187,0,1,3}-" + }, + { + "npc_id": "7014", + "loc_data": "{2226,3143,0,1,3}-{2180,3201,0,1,3}-{2288,3147,0,1,3}-{2247,3187,0,1,3}-" + }, + { + "npc_id": "7021", + "loc_data": "{2510,2822,0,1,3}-{2511,2823,0,1,4}-{2509,2825,0,1,6}-" + }, + { + "npc_id": "7022", + "loc_data": "{2503,2821,0,1,1}-{2500,2818,0,1,4}-{2503,2819,0,1,3}-" + }, + { + "npc_id": "7023", + "loc_data": "{2552,2821,0,1,4}-" + }, + { + "npc_id": "7024", + "loc_data": "{2523,2823,0,1,1}-" + }, + { + "npc_id": "7025", + "loc_data": "{2537,2820,0,1,1}-" + }, + { + "npc_id": "7026", + "loc_data": "{2543,2822,0,1,1}-" + }, + { + "npc_id": "7027", + "loc_data": "{2609,2863,0,1,0}-" + }, + { + "npc_id": "7028", + "loc_data": "{2610,2865,0,1,0}-" + }, + { + "npc_id": "7029", + "loc_data": "{2611,2862,0,1,0}-" + }, + { + "npc_id": "7030", + "loc_data": "{2611,2864,0,1,0}-" + }, + { + "npc_id": "7031", + "loc_data": "{2588,2801,0,1,1}-{2566,2820,0,1,5}-{2575,2818,0,1,4}-{2578,2819,0,1,4}-{2587,2819,0,1,7}-{2595,2821,0,1,4}-{2595,2826,0,1,0}-{2562,2819,0,1,6}-{2565,2828,0,1,0}-{2573,2825,0,1,1}-{2578,2820,0,1,6}-{2584,2822,0,1,4}-{2590,2831,0,1,4}-{2594,2823,0,1,4}-{2488,2768,0,1,1}-{2499,2820,0,1,4}-{2511,2819,0,1,3}-{2525,2820,0,1,0}-{2527,2818,0,1,3}-{2542,2819,0,1,4}-{2551,2817,0,1,3}-{2554,2819,0,1,3}-{2559,2819,0,1,4}-{2503,2824,0,1,3}-{2509,2822,0,1,4}-{2518,2825,0,1,7}-{2526,2822,0,1,1}-{2547,2822,0,1,4}-{2557,2826,0,1,4}-{2502,2823,0,1,4}-{2513,2820,0,1,7}-{2527,2819,0,1,4}-{2529,2818,0,1,6}-{2541,2822,0,1,3}-{2549,2817,0,1,2}-{2557,2818,0,1,2}-" + }, + { + "npc_id": "7032", + "loc_data": "{2539,2838,0,1,1}-" + }, + { + "npc_id": "7033", + "loc_data": "{2541,2837,0,1,1}-" + }, + { + "npc_id": "7034", + "loc_data": "{2536,2839,0,1,1}-" + }, + { + "npc_id": "7035", + "loc_data": "{2542,2839,0,1,1}-" + }, + { + "npc_id": "7036", + "loc_data": "{2538,2841,0,1,1}-" + }, + { + "npc_id": "7039", + "loc_data": "{2560,2822,0,1,1}-{2570,2823,0,1,1}-{2582,2824,0,1,6}-{2588,2828,0,1,4}-{2503,2824,0,1,4}-{2518,2824,0,1,4}-{2534,2821,0,1,1}-{2548,2823,0,1,4}-" + }, + { + "npc_id": "7040", + "loc_data": "{2562,2863,0,1,4}-{2617,5539,0,1,4}-" + }, + { + "npc_id": "7041", + "loc_data": "{2562,2863,0,1,4}-{2616,5540,0,1,4}-" + }, + { + "npc_id": "7042", + "loc_data": "{2605,5540,0,1,6}-{2551,2863,0,1,6}-" + }, + { + "npc_id": "7043", + "loc_data": "{2607,5539,0,1,6}-{2553,2862,0,1,6}-" + }, + { + "npc_id": "7044", + "loc_data": "{2467,2933,0,0,4}-{2470,2937,0,0,4}-{2445,2897,0,0,4}-{2444,2894,0,0,4}-" + }, + { + "npc_id": "7045", + "loc_data": "{2460,2922,0,0,4}-{2463,2928,0,0,4}-" + }, + { + "npc_id": "7046", + "loc_data": "{3364,3800,0,0,4}-{3368,3811,0,0,4}-{3347,3814,0,0,4}-{3363,3816,0,0,4}-{2460,2925,0,0,4}-" + }, + { + "npc_id": "7047", + "loc_data": "{2611,5513,0,0,1}-{2557,2836,0,1,1}-" + }, + { + "npc_id": "7048", + "loc_data": "{2599,5513,0,0,0}-{2545,2836,0,0,0}-" + }, + { + "npc_id": "7049", + "loc_data": "{2553,2839,0,0,4}-{2553,2836,0,0,4}-" + }, + { + "npc_id": "7051", + "loc_data": "{2547,2852,0,1,0}-" + }, + { + "npc_id": "7052", + "loc_data": "{2571,2855,0,1,3}-" + }, + { + "npc_id": "7054", + "loc_data": "{2560,2851,0,0,1}-" + }, + { + "npc_id": "7055", + "loc_data": "{2559,2851,0,0,1}-" + }, + { + "npc_id": "7056", + "loc_data": "{2560,2851,0,1,6}-{2613,5528,0,0,6}-" + }, + { + "npc_id": "7057", + "loc_data": "{2596,2845,0,1,0}-" + }, + { + "npc_id": "7062", + "loc_data": "{2571,2840,0,1,4}-" + }, + { + "npc_id": "7065", + "loc_data": "{2621,2857,0,1,3}-" + }, + { + "npc_id": "7066", + "loc_data": "{2619,2856,0,1,3}-" + }, + { + "npc_id": "7067", + "loc_data": "{2572,5519,0,0,6}-{2518,2842,0,1,0}-" + }, + { + "npc_id": "7068", + "loc_data": "{2585,5527,0,0,6}-{2531,2850,0,1,6}-" + }, + { + "npc_id": "7069", + "loc_data": "{2613,5535,0,0,6}-{2559,2858,0,1,0}-" + }, + { + "npc_id": "7070", + "loc_data": "{2581,2866,0,1,6}-" + }, + { + "npc_id": "7071", + "loc_data": "{2598,2864,0,1,6}-" + }, + { + "npc_id": "7072", + "loc_data": "{2517,2840,0,1,6}-" + }, + { + "npc_id": "7073", + "loc_data": "{2533,2848,0,1,6}-" + }, + { + "npc_id": "7074", + "loc_data": "{2556,2858,0,1,6}-" + }, + { + "npc_id": "7075", + "loc_data": "{2583,2865,0,1,6}-" + }, + { + "npc_id": "7076", + "loc_data": "{2596,2865,0,1,6}-" + }, + { + "npc_id": "7077", + "loc_data": "{2617,2856,0,1,3}-" + }, + { + "npc_id": "7078", + "loc_data": "{2451,2857,0,1,0}-{2453,2874,0,1,0}-{2475,2868,0,1,0}-{2477,2832,0,1,0}-{2475,2896,0,1,0}-{2476,2883,0,1,0}-{2502,2838,0,1,0}-" + }, + { + "npc_id": "7079", + "loc_data": "{2451,2849,0,1,0}-{2463,2872,0,1,0}-{2470,2853,0,1,0}-{2487,2837,0,1,0}-{2477,2903,0,1,0}-{2478,2907,0,1,0}-{2501,2851,0,1,0}-" + }, + { + "npc_id": "7080", + "loc_data": "{2562,5530,0,0,6}-{2456,2867,0,1,0}-{2457,2836,0,1,0}-{2484,2873,0,1,0}-{2487,2856,0,1,0}-{2480,2916,0,1,0}-{2492,2888,0,1,0}-{2508,2853,0,1,0}-" + }, + { + "npc_id": "7081", + "loc_data": "{2446,2869,0,1,0}-{2451,2828,0,1,0}-{2467,2860,0,1,0}-{2487,2844,0,1,0}-{2480,2892,0,1,0}-{2484,2917,0,1,0}-{2499,2860,0,1,0}-" + }, + { + "npc_id": "7082", + "loc_data": "{2569,5541,0,0,6}-{2440,2858,0,1,0}-{2459,2859,0,1,0}-{2471,2839,0,1,0}-{2482,2863,0,1,0}-{2483,2883,0,1,0}-{2491,2901,0,1,0}-{2516,2858,0,1,0}-" + }, + { + "npc_id": "7091", + "loc_data": "{2609,2863,0,0,0}-" + }, + { + "npc_id": "7092", + "loc_data": "{2610,2865,0,0,0}-" + }, + { + "npc_id": "7093", + "loc_data": "{2611,2862,0,0,0}-" + }, + { + "npc_id": "7094", + "loc_data": "{2611,2864,0,0,0}-" + }, + { + "npc_id": "7095", + "loc_data": "{2609,2863,0,0,0}-{2610,2862,0,0,0}-" + }, + { + "npc_id": "7096", + "loc_data": "{2610,2865,0,0,0}-{2605,2866,0,0,0}-" + }, + { + "npc_id": "7097", + "loc_data": "{2611,2862,0,0,0}-{2607,2867,0,0,0}-" + }, + { + "npc_id": "7098", + "loc_data": "{2611,2864,0,0,0}-{2608,2863,0,0,0}-" + }, + { + "npc_id": "7099", + "loc_data": "{2585,2844,0,1,3}-" + }, + { + "npc_id": "7100", + "loc_data": "{2586,2840,0,0,4}-" + }, + { + "npc_id": "7101", + "loc_data": "{2585,2842,0,1,1}-" + }, + { + "npc_id": "7102", + "loc_data": "{2576,2840,0,0,0}-{2576,2840,0,0,0}-" + }, + { + "npc_id": "7103", + "loc_data": "{2579,2843,0,0,0}-{2582,2843,0,0,0}-{2579,2843,0,0,0}-{2582,2843,0,0,0}-" + }, + { + "npc_id": "7104", + "loc_data": "{2603,5529,0,0,4}-{2549,2852,0,1,4}-" + }, + { + "npc_id": "7105", + "loc_data": "{2612,9484,0,1,1}-{2611,9484,0,1,0}-{2614,9484,0,1,6}-{2611,9486,0,1,1}-{3111,9929,0,1,7}-{3106,9941,0,1,1}-{3111,9935,0,1,4}-{3114,9931,0,1,1}-" + }, + { + "npc_id": "7106", + "loc_data": "{3131,9930,0,1,4}-" + }, + { + "npc_id": "7107", + "loc_data": "{3130,9928,0,1,0}-{3131,9931,0,1,4}-" + }, + { + "npc_id": "7109", + "loc_data": "{3127,9932,0,1,1}-" + }, + { + "npc_id": "7110", + "loc_data": "{3121,9929,0,1,4}-" + }, + { + "npc_id": "7112", + "loc_data": "{3130,9934,0,1,3}-" + }, + { + "npc_id": "7113", + "loc_data": "{3127,9932,0,1,4}-" + }, + { + "npc_id": "7114", + "loc_data": "{3132,9921,0,0,0}-{3132,9935,0,1,1}-" + }, + { + "npc_id": "7115", + "loc_data": "{3050,3259,0,0,0}-" + }, + { + "npc_id": "7121", + "loc_data": "{2189,3148,0,1,4}-" + }, + { + "npc_id": "7125", + "loc_data": "{1605,4702,0,1,0}-{1649,4730,0,1,0}-" + }, + { + "npc_id": "7126", + "loc_data": "{1605,4720,0,1,0}-{1658,4705,0,1,0}-{1633,4678,0,1,0}-" + }, + { + "npc_id": "7127", + "loc_data": "{1631,4730,0,1,0}-{1658,4687,0,1,0}-{1615,4678,0,1,0}-" + }, + { + "npc_id": "7128", + "loc_data": "{1625,4689,0,1,0}-{1614,4704,0,1,0}-{1631,4719,0,1,0}-{1651,4705,0,1,0}-" + }, + { + "npc_id": "7129", + "loc_data": "{1625,4689,0,1,0}-{1614,4704,0,1,0}-{1631,4719,0,1,0}-{1651,4705,0,1,0}-" + }, + { + "npc_id": "7130", + "loc_data": "{1625,4689,0,1,0}-{1614,4704,0,1,0}-{1631,4719,0,1,0}-{1651,4705,0,1,0}-" + }, + { + "npc_id": "7131", + "loc_data": "{1634,4699,0,1,0}-" + }, + { + "npc_id": "7132", + "loc_data": "{1630,4705,0,0,0}-" + }, + { + "npc_id": "7138", + "loc_data": "{3190,5523,0,1,2}-{3195,5527,0,1,6}-{3245,5462,0,1,7}-{3257,5454,0,1,3}-{3255,5461,0,1,1}-{3251,5473,0,1,3}-{3213,5472,0,1,3}-{3210,5469,0,1,5}-{3221,5468,0,1,0}-{3223,5465,0,1,0}-{3224,5540,0,1,0}-{3240,5541,0,1,6}-{3239,5529,0,1,6}-{3233,5524,0,1,4}-{3237,5512,0,1,6}-{3225,5510,0,1,1}-{3222,5524,0,1,1}-{3225,5540,0,1,7}-{3218,5537,0,1,3}-" + }, + { + "npc_id": "7139", + "loc_data": "{3220,5463,0,1,7}-" + }, + { + "npc_id": "7142", + "loc_data": "{3082,4246,0,1,4}-" + }, + { + "npc_id": "7143", + "loc_data": "{3082,3459,0,0,0}-" + }, + { + "npc_id": "7144", + "loc_data": "{3085,4230,0,1,3}-" + }, + { + "npc_id": "7145", + "loc_data": "{3081,4252,0,1,7}-" + }, + { + "npc_id": "7146", + "loc_data": "{3078,4240,0,1,4}-" + }, + { + "npc_id": "7147", + "loc_data": "{3079,4245,0,1,4}-" + }, + { + "npc_id": "7148", + "loc_data": "{3077,4229,0,1,4}-" + }, + { + "npc_id": "7149", + "loc_data": "{3085,4235,0,1,4}-" + }, + { + "npc_id": "7150", + "loc_data": "{3085,4240,0,1,3}-" + }, + { + "npc_id": "7151", + "loc_data": "{3081,3457,0,0,4}-" + }, + { + "npc_id": "7152", + "loc_data": "{3081,3455,0,0,4}-" + }, + { + "npc_id": "7153", + "loc_data": "{3081,3453,0,0,4}-" + }, + { + "npc_id": "7154", + "loc_data": "{3079,3457,0,0,4}-" + }, + { + "npc_id": "7155", + "loc_data": "{3079,3455,0,0,4}-" + }, + { + "npc_id": "7156", + "loc_data": "{3077,3457,0,0,4}-" + }, + { + "npc_id": "7157", + "loc_data": "{3077,3453,0,0,4}-" + }, + { + "npc_id": "7158", + "loc_data": "{3080,3463,0,1,0}-{3079,3463,0,1,0}-{3144,4250,2,1,4}-{3143,4255,2,1,2}-{3140,4253,2,1,3}-{3145,4255,2,1,6}-{3149,4257,2,1,5}-{3148,4262,2,1,5}-{3142,4260,2,1,3}-{3144,4259,2,1,4}-{3145,4261,2,1,4}-{3146,4265,2,1,5}-{3143,4264,2,1,3}-{3144,4266,2,1,5}-{3141,4265,2,1,1}-{3144,4270,2,1,1}-{3142,4269,2,1,6}-{3157,4262,2,1,1}-{3164,4265,2,1,6}-{3162,4266,2,1,6}-{3165,4266,2,1,3}-{3164,4261,2,1,2}-{3162,4259,2,1,5}-{3162,4255,2,1,7}-{3165,4256,2,1,4}-{3163,4251,2,1,3}-{3165,4249,2,1,6}-{3162,4250,2,1,4}-{3163,4241,2,1,4}-{3165,4239,2,1,4}-{3165,4241,2,1,0}-{3160,4235,2,1,2}-{3165,4235,2,1,4}-{3165,4237,2,1,4}-{3162,4234,2,1,3}-{3164,4231,2,1,4}-{3166,4229,2,1,6}-{3162,4230,2,1,1}-{3167,4229,2,1,3}-{3184,4236,2,1,1}-{3153,4246,1,1,3}-{3159,4236,1,1,6}-{3163,4236,1,1,4}-{3163,4234,1,1,7}-{3146,4235,1,1,5}-{3144,4236,1,1,1}-{3143,4234,1,1,2}-{3145,4240,1,1,4}-{3148,4242,1,1,1}-{3145,4241,1,1,7}-{3142,4242,1,1,3}-{3146,4230,1,1,4}-" + }, + { + "npc_id": "7159", + "loc_data": "{3174,4238,2,1,6}-{3175,4243,2,1,6}-{3179,4236,2,1,4}-{3145,4272,1,1,3}-{3145,4276,1,1,3}-{3152,4271,1,1,6}-{3144,4264,1,1,4}-{3153,4266,1,1,1}-{3152,4261,1,1,4}-{3145,4259,1,1,6}-{3161,4259,1,1,0}-{3160,4265,1,1,0}-{3153,4246,1,1,3}-{3157,4248,1,1,6}-{3161,4247,1,1,4}-{3146,4247,1,1,6}-{3153,4233,1,1,4}-{3153,4240,1,1,6}-{3155,4238,1,1,5}-{3169,4267,3,1,3}-{3160,4265,3,1,6}-{3168,4250,3,1,4}-{3168,4244,3,1,6}-{3160,4239,3,1,1}-{3160,4228,3,1,3}-{3147,4225,3,1,3}-{3145,4242,3,1,5}-{3139,4249,3,1,6}-{3144,4253,3,1,3}-{3145,4266,3,1,0}-{3138,4266,3,1,3}-{3151,4272,3,1,0}-{3139,4272,3,1,0}-{3146,4231,3,1,0}-{3169,4270,3,1,0}-" + }, + { + "npc_id": "7160", + "loc_data": "{3175,4254,2,1,7}-{3176,4247,2,1,5}-{3174,4269,2,1,1}-{3190,4253,2,1,3}-{3192,4247,2,1,3}-{3189,4235,2,1,0}-{3152,4269,0,1,4}-{3160,4278,0,1,1}-{3160,4262,0,1,3}-{3149,4250,0,1,0}-{3158,4250,0,1,5}-{3161,4236,0,1,6}-{3172,4250,0,1,2}-{3171,4269,3,1,1}-{3157,4277,3,1,3}-{3150,4278,3,1,3}-{3160,4271,1,1,0}-{3163,4274,1,1,0}-{3167,4277,1,1,0}-{3173,4277,1,1,0}-{3175,4275,1,1,0}-{3160,4269,0,1,0}-{3173,4264,0,1,0}-{3190,4237,2,1,0}-{3154,4279,3,1,0}-" + }, + { + "npc_id": "7161", + "loc_data": "{3142,4230,2,1,6}-{3143,4231,2,1,3}-{3141,4235,2,1,4}-{3144,4241,2,1,4}-" + }, + { + "npc_id": "7162", + "loc_data": "{3144,4229,2,1,1}-{3143,4236,2,1,1}-{3145,4235,2,1,1}-{3148,4244,2,1,6}-" + }, + { + "npc_id": "7168", + "loc_data": "{2714,3309,0,1,1}-" + }, + { + "npc_id": "7228", + "loc_data": "{2862,3101,0,0,0}-{2879,3109,0,0,0}-{2874,3098,0,0,0}-{2882,3104,0,0,0}-{2882,3098,0,0,0}-" + }, + { + "npc_id": "7229", + "loc_data": "{2833,3088,0,0,0}-{2830,3085,0,0,0}-{2844,3089,0,0,0}-{2837,3084,0,0,0}-{2840,3076,0,0,0}-" + }, + { + "npc_id": "7230", + "loc_data": "{2840,3008,0,0,0}-{2887,3051,0,0,0}-{2890,3052,0,0,0}-{2894,3058,0,0,0}-{2897,3035,0,0,0}-" + }, + { + "npc_id": "7231", + "loc_data": "{2930,2961,0,0,0}-{2942,2964,0,0,0}-{2933,2964,0,0,0}-{2932,2967,0,0,0}-{2936,2973,0,0,0}-" + }, + { + "npc_id": "7232", + "loc_data": "{2802,3106,0,0,0}-{2807,3101,0,0,0}-{2806,3108,0,0,0}-{2808,3105,0,0,0}-{2814,3100,0,0,0}-" + }, + { + "npc_id": "7233", + "loc_data": "{2922,3070,0,0,0}-{2929,3075,0,0,0}-{2919,3080,0,0,0}-{2924,3080,0,0,0}-{2923,3081,0,0,0}-" + }, + { + "npc_id": "7234", + "loc_data": "{2900,3107,0,0,0}-{2903,3098,0,0,0}-{2908,3104,0,0,0}-{2905,3107,0,0,0}-{2904,3107,0,0,0}-" + }, + { + "npc_id": "7235", + "loc_data": "{2820,3065,0,0,0}-{2830,3059,0,0,0}-{2825,3057,0,0,0}-{2827,3050,0,0,0}-{2822,3053,0,0,0}-" + }, + { + "npc_id": "7236", + "loc_data": "{2799,3005,0,0,0}-{2801,2995,0,0,0}-{2804,3001,0,0,0}-{2803,2986,0,0,0}-{2811,2999,0,0,0}-" + }, + { + "npc_id": "7275", + "loc_data": "{2995,3252,0,0,0}-{2996,3259,0,0,0}-{2993,3250,0,0,0}-{3000,3258,0,0,0}-" + }, + { + "npc_id": "7276", + "loc_data": "{2994,3256,0,0,0}-{3002,3250,0,0,0}-{2992,3252,0,0,0}-{3000,3250,0,0,0}-{2728,3422,0,1,1}-{2718,3413,0,1,4}-{2729,3420,0,1,4}-{2727,3414,0,1,6}-{2714,3419,0,1,3}-{2719,3427,0,1,7}-" + }, + { + "npc_id": "7285", + "loc_data": "{2835,3107,0,0,0}-{2836,3101,0,0,0}-{2836,3110,0,0,0}-{2837,3112,0,0,0}-{2841,3107,0,0,0}-{2885,3018,0,0,0}-{2885,3019,0,0,0}-{2891,3018,0,0,0}-" + }, + { + "npc_id": "7286", + "loc_data": "{2931,3090,0,0,0}-{2925,3097,0,0,0}-{2936,3096,0,0,0}-{2924,3102,0,0,0}-{2933,3104,0,0,0}-" + }, + { + "npc_id": "7288", + "loc_data": "{2834,3045,0,0,0}-{2826,3048,0,0,0}-{2824,3043,0,0,0}-{2822,3045,0,0,0}-{2818,3049,0,0,0}-" + }, + { + "npc_id": "7289", + "loc_data": "{2882,3018,0,1,7}-{2887,3024,0,1,2}-" + }, + { + "npc_id": "7290", + "loc_data": "{2845,3088,0,1,6}-{2854,3085,0,1,1}-" + }, + { + "npc_id": "7292", + "loc_data": "{2863,3048,0,1,5}-{2868,3037,0,1,4}-" + }, + { + "npc_id": "7309", + "loc_data": "{2946,3280,0,0,0}-{3023,3410,0,0,0}-" + }, + { + "npc_id": "7310", + "loc_data": "{2946,3272,0,0,0}-{3015,3409,0,0,0}-" + }, + { + "npc_id": "7311", + "loc_data": "{2956,3273,0,0,0}-" + }, + { + "npc_id": "7312", + "loc_data": "{2950,3268,0,0,0}-" + }, + { + "npc_id": "7420", + "loc_data": "{3168,3334,0,0,3}-" + }, + { + "npc_id": "7421", + "loc_data": "{3163,3336,0,0,1}-" + }, + { + "npc_id": "7451", + "loc_data": "{2328,3170,0,1,6}-{2341,3179,0,1,4}-{2338,3164,0,1,4}-{2189,3181,0,1,2}-{2178,3186,0,1,7}-{2199,3182,0,1,0}-{2288,3149,0,1,2}-{2282,3144,0,1,3}-{2285,3144,0,1,2}-{2281,3139,0,1,1}-{2289,3152,0,1,6}-{2287,3155,0,1,1}-{2286,3146,0,1,1}-{2289,3156,0,0,5}-{2285,3136,0,1,3}-" + }, + { + "npc_id": "7600", + "loc_data": "{1714,5602,0,0,6}-" + }, + { + "npc_id": "7601", + "loc_data": "{1697,5605,0,0,6}-" + }, + { + "npc_id": "7602", + "loc_data": "{1693,5598,0,1,0}-" + }, + { + "npc_id": "7603", + "loc_data": "{1696,5600,0,1,0}-" + }, + { + "npc_id": "7604", + "loc_data": "{1699,5599,0,1,0}-" + }, + { + "npc_id": "7605", + "loc_data": "{1705,5599,0,0,1}-" + }, + { + "npc_id": "7636", + "loc_data": "{3618,9736,0,0,0}-{3620,9732,0,0,0}-{3624,9736,0,0,0}-{3625,9738,0,0,0}-{3618,9736,0,0,4}-{3620,9732,0,0,4}-{3624,9736,0,0,4}-{3625,9738,0,0,4}-" + }, + { + "npc_id": "7637", + "loc_data": "{3588,9768,0,0,0}-{3600,9768,0,0,0}-{3606,9780,0,0,0}-{3612,9729,0,0,0}-{3613,9764,0,0,0}-{3614,9740,0,0,0}-{3614,9750,0,0,0}-{3621,9748,0,0,0}-{3629,9737,0,0,0}-" + }, + { + "npc_id": "7639", + "loc_data": "{3592,9766,0,0,0}-{3603,9770,0,0,0}-{3605,9757,0,0,0}-{3611,9749,0,0,0}-{3611,9766,0,0,0}-{3616,9737,0,0,0}-{3616,9756,0,0,0}-{3616,9762,0,0,0}-{3617,9779,0,0,0}-{3621,9754,0,0,0}-" + }, + { + "npc_id": "7640", + "loc_data": "{3608,9780,0,1,3}-{3610,9777,0,1,1}-{3613,9772,0,1,4}-{3617,9748,0,1,7}-{3617,9758,0,1,1}-{3621,9751,0,1,1}-" + }, + { + "npc_id": "7641", + "loc_data": "{3607,9776,0,1,1}-{3610,9772,0,1,0}-{3614,9778,0,1,7}-{3615,9746,0,1,7}-{3618,9753,0,1,1}-{3619,9748,0,1,6}-" + }, + { + "npc_id": "7642", + "loc_data": "{3595,9742,0,0,0}-{3597,9751,0,0,0}-{3598,9736,0,0,0}-{3604,9746,0,0,0}-" + }, + { + "npc_id": "7643", + "loc_data": "{3587,9737,0,0,0}-{3592,9746,0,0,0}-{3600,9740,0,0,0}-{3605,9738,0,0,0}-" + }, + { + "npc_id": "7690", + "loc_data": "{3415,3489,2,0,0}-" + }, + { + "npc_id": "7707", + "loc_data": "{3440,9895,0,0,0}-" + }, + { + "npc_id": "7711", + "loc_data": "{3405,9902,0,0,0}-" + }, + { + "npc_id": "7716", + "loc_data": "{3005,3475,0,1,7}-{3003,3473,0,1,4}-{2997,3471,0,0,0}-{3004,3494,0,0,0}-{3005,3505,0,0,0}-" + }, + { + "npc_id": "7724", + "loc_data": "{3054,3503,0,1,0}-" + }, + { + "npc_id": "7726", + "loc_data": "{2996,3451,0,0,0}-" + }, + { + "npc_id": "7727", + "loc_data": "{3045,3483,0,0,0}-{3053,3492,0,0,4}-{3055,3491,0,0,0}-{3045,3496,0,0,0}-{3046,3490,1,0,0}-{3057,3497,1,0,3}-" + }, + { + "npc_id": "7728", + "loc_data": "{3009,3433,0,0,0}-" + }, + { + "npc_id": "7731", + "loc_data": "{3008,3466,0,0,0}-" + }, + { + "npc_id": "7732", + "loc_data": "{3009,3466,0,0,0}-" + }, + { + "npc_id": "7733", + "loc_data": "{3008,3479,0,0,0}-" + }, + { + "npc_id": "7734", + "loc_data": "{3009,3487,0,0,0}-" + }, + { + "npc_id": "7735", + "loc_data": "{2999,3469,0,0,0}-" + }, + { + "npc_id": "7744", + "loc_data": "{3149,3411,0,0,0}-" + }, + { + "npc_id": "7746", + "loc_data": "{4755,5116,0,1,7}-" + }, + { + "npc_id": "7747", + "loc_data": "{4751,5116,0,1,5}-" + }, + { + "npc_id": "7748", + "loc_data": "{4752,5114,0,1,5}-" + }, + { + "npc_id": "7749", + "loc_data": "{4739,5070,0,1,0}-" + }, + { + "npc_id": "7750", + "loc_data": "{4765,5064,0,1,7}-" + }, + { + "npc_id": "7751", + "loc_data": "{4778,5070,0,1,2}-" + }, + { + "npc_id": "7752", + "loc_data": "{4432,5096,0,1,0}-" + }, + { + "npc_id": "7753", + "loc_data": "{4438,5089,0,1,0}-{4428,5083,0,1,0}-{4437,5075,0,1,0}-" + }, + { + "npc_id": "7763", + "loc_data": "{4777,5080,0,1,2}-" + }, + { + "npc_id": "7765", + "loc_data": "{4776,5076,0,1,6}-" + }, + { + "npc_id": "7767", + "loc_data": "{2457,5139,0,1,6}-{2460,5140,0,1,0}-{2443,5147,0,1,3}-{2454,5155,0,1,5}-{2461,5125,0,1,3}-{2456,5124,0,1,4}-{2458,5129,0,1,4}-{2443,5145,0,1,1}-{2451,5148,0,1,1}-{2447,5143,0,1,4}-{2443,5138,0,1,4}-{4762,5145,0,1,2}-" + }, + { + "npc_id": "7768", + "loc_data": "{4762,5156,0,1,6}-" + }, + { + "npc_id": "7780", + "loc_data": "{3358,2993,0,1,0}-" + }, + { + "npc_id": "7786", + "loc_data": "{3348,9388,0,1,0}-{3350,9393,0,1,0}-{3350,9400,0,1,0}-{3350,9406,0,1,0}-{3351,9380,0,1,0}-{3352,9374,0,1,0}-{3354,9387,0,1,0}-{3358,9378,0,1,0}-{3358,9396,0,1,0}-{3358,9406,0,1,0}-{3365,9381,0,1,0}-{3365,9387,0,1,0}-{3365,9402,0,1,0}-{3369,9390,0,1,0}-{3350,9412,0,1,0}-{3351,9420,0,1,0}-{3356,9414,0,1,0}-{3358,9421,0,1,0}-{3364,9424,0,1,0}-{3365,9416,0,1,0}-" + }, + { + "npc_id": "7787", + "loc_data": "{3301,4413,0,1,0}-{3302,4394,0,1,0}-{3304,4397,0,1,0}-{3306,4410,0,1,0}-{3307,4383,0,1,0}-{3307,4397,0,1,0}-{3308,4407,0,1,0}-{3310,4383,0,1,0}-{3310,4386,0,1,0}-{3310,4398,0,1,0}-{3311,4407,0,1,0}-{3312,4380,0,1,0}-{3313,4401,0,1,0}-{3314,4411,0,1,0}-{3316,4376,0,1,0}-{3316,4382,0,1,0}-{3316,4387,0,1,0}-{3316,4397,0,1,0}-{3316,4401,0,1,0}-{3316,4405,0,1,0}-{3317,4391,0,1,0}-{3318,4412,0,1,0}-{3319,4373,0,1,0}-{3319,4407,0,1,0}-{3321,4385,0,1,0}-{3321,4398,0,1,0}-{3322,4412,0,1,0}-{3323,4402,0,1,0}-{3324,4394,0,1,0}-{3324,4397,0,1,0}-{3325,4410,0,1,0}-" + }, + { + "npc_id": "7801", + "loc_data": "{3283,4346,0,1,0}-{3308,4349,0,1,0}-{3293,4375,0,1,0}-{3303,4363,0,1,0}-" + }, + { + "npc_id": "7802", + "loc_data": "{3288,4350,0,1,0}-{3296,4340,0,1,0}-{3288,4361,0,1,0}-{3310,4355,0,1,0}-" + }, + { + "npc_id": "7803", + "loc_data": "{3297,4347,0,1,0}-{3315,4346,0,1,0}-{3282,4357,0,1,0}-{3303,4369,0,1,0}-" + }, + { + "npc_id": "7804", + "loc_data": "{3279,4350,0,1,0}-{3294,4353,0,1,0}-{3294,4366,0,1,0}-" + }, + { + "npc_id": "7823", + "loc_data": "{3161,9547,0,0,3}-{3164,9556,0,0,4}-{3162,9574,0,0,3}-{3198,9554,0,0,7}-{3198,9572,0,0,1}-{3215,9560,0,0,1}-{3216,9588,0,0,1}-" + }, + { + "npc_id": "7891", + "loc_data": "{3207,3250,0,0,0}-{3208,3250,0,0,0}-{3209,3250,0,0,0}-" + }, + { + "npc_id": "7942", + "loc_data": "{3294,4937,0,0,6}-" + }, + { + "npc_id": "7959", + "loc_data": "{3188,3425,0,1,0}-" + }, + { + "npc_id": "7969", + "loc_data": "{3205,3240,0,0,0}-" + }, + { + "npc_id": "8000", + "loc_data": "{2987,3691,0,1,3}-" + }, + { + "npc_id": "8041", + "loc_data": "{2794,3100,0,1,0}-" + }, + { + "npc_id": "8065", + "loc_data": "{3399,3464,0,0,1}-" + }, + { + "npc_id": "8066", + "loc_data": "{3346,3513,0,0,6}-" + }, + { + "npc_id": "8067", + "loc_data": "{3280,3524,0,0,0}-" + }, + { + "npc_id": "8068", + "loc_data": "{3237,3525,0,0,0}-" + }, + { + "npc_id": "8069", + "loc_data": "{3171,3535,0,0,0}-" + }, + { + "npc_id": "8070", + "loc_data": "{3088,3515,0,0,0}-" + }, + { + "npc_id": "8071", + "loc_data": "{3035,3517,0,0,0}-" + }, + { + "npc_id": "8072", + "loc_data": "{2972,3515,0,0,0}-" + }, + { + "npc_id": "8073", + "loc_data": "{2941,3564,0,0,0}-" + }, + { + "npc_id": "8074", + "loc_data": "{2946,3621,0,0,0}-" + }, + { + "npc_id": "8075", + "loc_data": "{2938,3679,0,0,0}-" + }, + { + "npc_id": "8076", + "loc_data": "{2939,3772,0,0,0}-" + }, + { + "npc_id": "8082", + "loc_data": "{3552,5590,2,1,2}-" + }, + { + "npc_id": "8083", + "loc_data": "{3560,5602,0,1,3}-" + }, + { + "npc_id": "8084", + "loc_data": "{3541,5597,0,1,4}-" + }, + { + "npc_id": "8085", + "loc_data": "{3550,5598,0,1,3}-" + }, + { + "npc_id": "8111", + "loc_data": "{3273,3681,0,1,0}-" + }, + { + "npc_id": "8133", + "loc_data": "{2993,4380,2,1,0}-" + }, + { + "npc_id": "8149", + "loc_data": "{3244,9996,0,1,6}-{3229,10008,0,1,6}-{3222,10012,0,1,6}-{3205,10010,0,1,6}-{3212,10012,0,1,6}-{3205,10023,0,1,6}-{3210,10030,0,1,6}-{3212,10039,0,1,6}-{3213,10009,0,1,6}-{3243,9993,0,1,6}-{3218,10036,0,1,6}-{3218,10010,0,1,6}-" + }, + { + "npc_id": "8150", + "loc_data": "{3241,9997,0,1,6}-{3230,10011,0,1,6}-{3221,10012,0,1,6}-{3207,10006,0,1,6}-{3207,10017,0,1,6}-{3209,10031,0,1,6}-{3209,10019,0,1,6}-{3217,10012,0,1,6}-{3224,10012,0,1,6}-" + }, + { + "npc_id": "8151", + "loc_data": "{3241,9998,0,1,6}-{3223,10010,0,1,6}-{3208,10012,0,1,6}-{3209,10026,0,1,6}-{3214,10038,0,1,6}-{3211,10035,0,1,6}-{3214,10037,0,1,6}-{3240,9991,0,1,6}-{3231,10010,0,1,6}-{3210,10007,0,1,6}-{3222,10010,0,1,6}-" + }, + { + "npc_id": "8171", + "loc_data": "{3281,3403,0,1,6}-" + }, + { + "npc_id": "8227", + "loc_data": "{3135,3631,0,1,6}-" + }, + { + "npc_id": "8228", + "loc_data": "{3142,3635,0,1,0}-" + }, + { + "npc_id": "8229", + "loc_data": "{3128,3632,0,1,0}-{3135,3616,0,1,6}-" + }, + { + "npc_id": "8231", + "loc_data": "{3135,3627,0,1,0}-" + }, + { + "npc_id": "8233", + "loc_data": "{3133,3628,0,1,0}-" + }, + { + "npc_id": "8267", + "loc_data": "{2866,3546,0,1,1}-" + }, + { + "npc_id": "8273", + "loc_data": "{2931,3536,0,1,5}-" + }, + { + "npc_id": "8274", + "loc_data": "{3514,3513,0,1,6}-" + }, + { + "npc_id": "8275", + "loc_data": "{2869,2982,1,1,5}-" + }, + { + "npc_id": "8312", + "loc_data": "{3016,9974,1,1,0}-{3021,9940,1,1,0}-{3023,9940,1,1,0}-{3024,9959,1,1,0}-{3027,9960,1,1,0}-{3043,9967,1,1,0}-{3023,9992,1,1,0}-{3016,10021,2,1,0}-{3028,10013,2,1,0}-{3029,10028,2,1,0}-{3038,10005,2,1,0}-{3044,10001,2,1,0}-{3045,9993,2,1,0}-{3045,9999,2,1,0}-{3047,10000,2,1,0}-{3052,10009,2,1,0}-{3054,10001,2,1,0}-{3056,10006,2,1,0}-{3032,10090,1,1,0}-{3040,10096,1,1,0}-{3048,10095,1,1,0}-" + }, + { + "npc_id": "8316", + "loc_data": "{3017,9972,1,1,0}-{3025,9962,1,1,0}-{3030,9943,1,1,0}-{3033,9941,1,1,0}-{3034,9950,1,1,0}-{3035,9950,1,1,0}-{3036,9940,1,1,0}-{3038,9939,1,1,0}-{3045,9968,1,1,0}-{3058,9952,1,1,0}-{3063,9952,1,1,0}-{3025,9995,1,1,0}-{3027,10029,2,1,0}-{3051,10006,2,1,0}-{3052,10002,2,1,0}-{3054,10005,2,1,0}-{3027,10101,1,1,0}-{3039,10100,1,1,0}-{3054,10097,1,1,0}-" + }, + { + "npc_id": "8320", + "loc_data": "{3014,9971,1,1,0}-{3016,9969,1,1,0}-{3028,9942,1,1,0}-{3029,9943,1,1,0}-{3030,9951,1,1,0}-{3033,9950,1,1,0}-{3045,9965,1,1,0}-{3061,9953,1,1,0}-{3062,9953,1,1,0}-{3030,9995,1,1,0}-{3016,10023,2,1,0}-{3029,10014,2,1,0}-{3029,10030,2,1,0}-{3036,10005,2,1,0}-{3042,9994,2,1,0}-{3047,10005,2,1,0}-{3049,10002,2,1,0}-{3053,9998,2,1,0}-{3031,10100,1,1,0}-{3044,10098,1,1,0}-{3049,10102,1,1,0}-" + }, + { + "npc_id": "8324", + "loc_data": "{2911,3811,0,1,0}-{2911,3812,0,1,0}-{2911,3813,0,1,0}-{2925,3821,0,1,0}-{2925,3822,0,1,0}-{2925,3823,0,1,0}-{2929,3798,0,1,0}-{2936,3790,0,1,0}-{2936,3810,0,1,0}-{2939,3823,0,1,0}-{2949,3819,1,1,0}-{2949,3822,1,1,0}-{2955,3822,1,1,0}-{2957,3822,1,1,0}-{3016,9977,1,1,0}-{3021,9939,1,1,0}-{3024,9954,1,1,0}-{3025,9943,1,1,0}-{3025,9954,1,1,0}-{3026,9966,1,1,0}-{3032,9952,1,1,0}-{3039,9954,1,1,0}-{3044,9967,1,1,0}-{3044,9971,1,1,0}-{3057,9936,1,1,0}-{3059,9953,1,1,0}-{3041,9975,2,1,0}-{3043,9975,2,1,0}-{3045,9975,2,1,0}-{3016,10022,2,1,0}-{3017,10039,2,1,0}-{3027,10028,2,1,0}-{3029,10013,2,1,0}-{3036,10038,2,1,0}-{3037,10006,2,1,0}-{3041,10024,2,1,0}-{3043,10032,2,1,0}-{3057,10002,2,1,0}-{3058,10021,2,1,0}-{3065,10006,2,1,0}-{3027,10092,1,1,0}-{3035,10097,1,1,0}-{3051,10099,1,1,0}-{3427,5102,0,1,0}-{3428,5099,0,1,0}-{3428,5102,0,1,0}-{3430,5099,0,1,0}-" + }, + { + "npc_id": "8328", + "loc_data": "{3055,10103,1,1,0}-" + }, + { + "npc_id": "8349", + "loc_data": "{2589,5735,0,1,0}-{2589,5713,0,1,0}-{2610,5709,0,1,0}-{2613,5732,0,1,0}-" + }, + { + "npc_id": "8358", + "loc_data": "{2601,5710,0,1,0}-{2603,5737,0,1,0}-" + }, + { + "npc_id": "8380", + "loc_data": "{2907,3806,0,1,0}-" + }, + { + "npc_id": "8381", + "loc_data": "{2910,3805,0,1,0}-" + }, + { + "npc_id": "8382", + "loc_data": "{2912,3812,0,1,0}-{2923,3823,0,1,0}-" + }, + { + "npc_id": "8383", + "loc_data": "{2908,3809,0,1,0}-{2919,3823,0,1,0}-" + }, + { + "npc_id": "8384", + "loc_data": "{2922,3827,0,1,0}-" + }, + { + "npc_id": "8385", + "loc_data": "{2924,3825,0,1,0}-" + }, + { + "npc_id": "8386", + "loc_data": "{2921,3824,0,1,0}-" + }, + { + "npc_id": "8387", + "loc_data": "{2934,3786,0,1,0}-" + }, + { + "npc_id": "8388", + "loc_data": "{2935,3784,0,1,0}-{2940,3827,0,1,0}-" + }, + { + "npc_id": "8389", + "loc_data": "{2937,3785,0,1,0}-" + }, + { + "npc_id": "8390", + "loc_data": "{2935,3781,0,1,0}-{2939,3829,0,1,0}-" + }, + { + "npc_id": "8391", + "loc_data": "{2937,3780,0,1,0}-{2940,3833,0,1,0}-" + }, + { + "npc_id": "8392", + "loc_data": "{2938,3782,0,1,0}-{2938,3831,0,1,0}-" + }, + { + "npc_id": "8536", + "loc_data": "{2654,5600,0,1,3}-{2650,5600,0,0,3}-{2662,5593,0,0,3}-{2653,5590,0,0,3}-{2644,5592,0,0,3}-{2644,5601,0,0,3}-{2654,5604,0,0,3}-{2663,5606,0,0,3}-{2670,5597,0,0,3}-{2657,5589,0,0,3}-" + }, + { + "npc_id": "8545", + "loc_data": "{3122,3626,0,1,0}-" + }, + { + "npc_id": "8590", + "loc_data": "{2743,3444,0,1,0}-" + } +] \ No newline at end of file diff --git a/Server/data/configs/object_configs.json b/Server/data/configs/object_configs.json new file mode 100644 index 0000000..54f50f6 --- /dev/null +++ b/Server/data/configs/object_configs.json @@ -0,0 +1,20718 @@ +[ + { + "examine": "I wonder what's inside.", + "ids": "0,1" + }, + { + "examine": "Looks and smells like a place where goblins live.", + "ids": "2" + }, + { + "examine": "The door is closed.", + "ids": "3,4" + }, + { + "examine": "A powerful ranging device, unfortunately not working.", + "ids": "5" + }, + { + "examine": "A powerful ranging device that fires metal balls.", + "ids": "6" + }, + { + "examine": "The cannon is built on here.", + "ids": "7" + }, + { + "examine": "The mounting for the multicannon.", + "ids": "8" + }, + { + "examine": "The barrels of the multicannon.", + "ids": "9" + }, + { + "examine": "I can climb down this.", + "ids": "10" + }, + { + "examine": "I can climb up this.", + "ids": "11" + }, + { + "examine": "A pile of rocks is blocking my path.", + "ids": "12" + }, + { + "examine": "Mud caved in from above.", + "ids": "13" + }, + { + "examine": "Intended to keep the goblins away from the mines.", + "ids": "14,15,16,17,18,19,20" + }, + { + "examine": "Its eyes stare off into the distance...", + "ids": "21" + }, + { + "examine": "The door is shut.", + "ids": "22" + }, + { + "examine": "Unusually lumpy looking.", + "ids": "23" + }, + { + "examine": "The door is shut.", + "ids": "24" + }, + { + "examine": "Seems to be some kind of clock part.", + "ids": "25,26,27,28,29,30,31,32" + }, + { + "examine": "Yup, definitely a lever.", + "ids": "33,34,35,36" + }, + { + "examine": "Stops people walking past.", + "ids": "37,38,39" + }, + { + "examine": "Animals have no table manners.", + "ids": "40" + }, + { + "examine": "Looks like an outlet pipe to the lake.", + "ids": "41" + }, + { + "examine": "I can see fish swimming in the water.", + "ids": "42,326" + }, + { + "examine": "It seems to sparkle.", + "ids": "43" + }, + { + "examine": "I can see really big fish swimming in the water.", + "ids": "44" + }, + { + "examine": "Big Dave is fishing here.", + "ids": "45" + }, + { + "examine": "Joshua is fishing here.", + "ids": "46" + }, + { + "examine": "A wooden gate.", + "ids": "47,48,49,50" + }, + { + "examine": "Hmmm... I wonder if it's loose enough to get through.", + "ids": "51" + }, + { + "examine": "It's locked.", + "ids": "52,53" + }, + { + "examine": "It's a flight of stairs.", + "ids": "54,55,56,57" + }, + { + "examine": "Known commonly as Red worm vine.", + "ids": "58" + }, + { + "examine": "A fancy hole in the wall.", + "ids": "59" + }, + { + "examine": "A fancy hole in the ceiling.", + "ids": "60" + }, + { + "examine": "A shrine to evil.", + "ids": "61" + }, + { + "examine": "Is there something in there?", + "ids": "62" + }, + { + "examine": "Used for storage.", + "ids": "63,64,36351,36352" + }, + { + "examine": "Surprisingly sturdy looking.", + "ids": "65,66" + }, + { + "examine": "Used for storage.", + "ids": "67" + }, + { + "examine": "Where bees live.", + "ids": "68" + }, + { + "examine": "Handy for boarding boats.", + "ids": "69,70" + }, + { + "examine": "Sturdy looking door.", + "ids": "71,72" + }, + { + "examine": "Securely fastened shut.", + "ids": "73,74" + }, + { + "examine": "I wonder what's inside?", + "ids": "75" + }, + { + "examine": "It's open.", + "ids": "76" + }, + { + "examine": "Securely fastened shut.", + "ids": "77,78" + }, + { + "examine": "Looks secure.", + "ids": "79,80" + }, + { + "examine": "The door is closed.", + "ids": "81,82" + }, + { + "examine": "Seems very old...", + "ids": "86" + }, + { + "examine": "I guess you pull it...", + "ids": "87" + }, + { + "examine": "A wrought iron gate.", + "ids": "89,90" + }, + { + "examine": "I don't like the look of this!", + "ids": "91" + }, + { + "examine": "The door is closed.", + "ids": "92,93" + }, + { + "examine": "A wrought iron gate.", + "ids": "94,95" + }, + { + "examine": "A dark flight of stairs.", + "ids": "96,98" + }, + { + "examine": "The door is closed.", + "ids": "99" + }, + { + "examine": "Don't you open that trapdoor!", + "ids": "100" + }, + { + "examine": "I can climb this.", + "ids": "101" + }, + { + "examine": "A sturdy door.", + "ids": "102" + }, + { + "examine": "I wonder what's inside.", + "ids": "103" + }, + { + "examine": "Perhaps I should search it.", + "ids": "104" + }, + { + "examine": "I wonder what that's there for...", + "ids": "105,106" + }, + { + "examine": "An appliance for cooking with.", + "ids": "114" + }, + { + "examine": "A party balloon.", + "ids": "115,116,117,118,119,120" + }, + { + "examine": "Aren't they pretty?", + "ids": "121" + }, + { + "examine": "Paaaarty!", + "ids": "122" + }, + { + "examine": "A party balloon.", + "ids": "123,124,125,126,127,128,129,130" + }, + { + "examine": "The door is closed.", + "ids": "131" + }, + { + "examine": "An escape route.", + "ids": "132" + }, + { + "examine": "Looks spooky down there.", + "ids": "133" + }, + { + "examine": "A large double door.", + "ids": "134,135,1516,1517,1518,1519,1520,1521,1522,1523,1524,1525,4423,4424,4425,4426,4427,4428,4429,4430,4629,4630,4631,4632,4633,4634,4635,4963,4964,12349,12350,12446,12447,12448,12449,13094,13095,13096,13097,13098,13099,31814,31815,31816" + }, + { + "examine": "The door is closed.", + "ids": "136" + }, + { + "examine": "Smelly.", + "ids": "152" + }, + { + "examine": "An ornate fountain.", + "ids": "153,36781" + }, + { + "examine": "A pipe I can squeeze through.", + "ids": "154,2287,2288,2290,2291,2292,2293,3236,3237,4058,5099,5100,5101,5102,5152,5153,5154,5155,9293,9295,10063,10064,10065,10066,10067,10068,10069,10070,10071,10072,10073,10074,10075,29370" + }, + { + "examine": "Lots of books.", + "ids": "155,156,157" + }, + { + "examine": "This wall looks odd...", + "ids": "158,159" + }, + { + "examine": "I wonder what this does...", + "ids": "160" + }, + { + "examine": "I'm not touching that.", + "ids": "162,163,164" + }, + { + "examine": "A special furnace for destroying contaminated items.", + "ids": "165" + }, + { + "examine": "A wooden gate.", + "ids": "166,167" + }, + { + "examine": "I wonder what's inside.", + "ids": "170" + }, + { + "examine": "Perhaps I should search it.", + "ids": "171" + }, + { + "examine": "I wonder what's inside.", + "ids": "172" + }, + { + "examine": "Perhaps I should search it.", + "ids": "173" + }, + { + "examine": "Fly Gnome Air.", + "ids": "187" + }, + { + "examine": "Probably pilot error.", + "ids": "188" + }, + { + "examine": "The Blurberry bar", + "ids": "189" + }, + { + "examine": "A large gate in the gnome style.", + "ids": "190" + }, + { + "examine": "The entrance to the cave.", + "ids": "194" + }, + { + "examine": "I can climb this.", + "ids": "195" + }, + { + "examine": "A quirky gnome lamp.", + "ids": "200" + }, + { + "examine": "These insects love this light.", + "ids": "201" + }, + { + "examine": "It's amazing what bees produce!", + "ids": "202" + }, + { + "examine": "Posh candlesticks.", + "ids": "203,204,32287,40074" + }, + { + "examine": "Scary lighting apparatus.", + "ids": "208" + }, + { + "examine": "An ornamental lighting fixture.", + "ids": "209" + }, + { + "examine": "A mysterious glowing ice crystal.", + "ids": "210" + }, + { + "examine": "It's amazing what bees produce!", + "ids": "211" + }, + { + "examine": "Useful for making ships move.", + "ids": "212,218" + }, + { + "examine": "This figure brings luck to those who sail.", + "ids": "221,222" + }, + { + "examine": "Useful for making ships move.", + "ids": "225,226" + }, + { + "examine": "Barnacle infested rope.", + "ids": "227" + }, + { + "examine": "Allows access to other parts of the ship.", + "ids": "245,246" + }, + { + "examine": "Without this I'm going around in circles.", + "ids": "252,253" + }, + { + "examine": "This figure brings luck to those who sail.", + "ids": "254" + }, + { + "examine": "Used for pulling things up.", + "ids": "255" + }, + { + "examine": "This figure brings luck to those who sail.", + "ids": "260" + }, + { + "examine": "Useful if there is any wind.", + "ids": "265" + }, + { + "examine": "Useful for making ships move.", + "ids": "266,267" + }, + { + "examine": "Useful for making ships move", + "ids": "268" + }, + { + "examine": "How much does this weigh?", + "ids": "271" + }, + { + "examine": "I can climb up here.", + "ids": "272" + }, + { + "examine": "I can go below decks with this ladder.", + "ids": "273" + }, + { + "examine": "A conveniently rolled sail.", + "ids": "274,275,276,277,278,279" + }, + { + "examine": "I'm not allowed to climb this ladder.", + "ids": "287" + }, + { + "examine": "It's like a land rudder.", + "ids": "296" + }, + { + "examine": "Disturbingly man-like.", + "ids": "297" + }, + { + "examine": "I bet there's a needle in it somewhere.", + "ids": "298,299,300" + }, + { + "examine": "Animals have no table manners.", + "ids": "301" + }, + { + "examine": "A home for baby creatures.", + "ids": "302" + }, + { + "examine": "In the city we would call this mouldy rubbish.", + "ids": "303" + }, + { + "examine": "I bet there's a needle in it somewhere.", + "ids": "304" + }, + { + "examine": "Where bees live.", + "ids": "305" + }, + { + "examine": "A used cart seller will probably try and sell it later.", + "ids": "306" + }, + { + "examine": "One horsepower; wooden suspension: a beauty.", + "ids": "307,308" + }, + { + "examine": "Dead tree parts piled together neatly.", + "ids": "309" + }, + { + "examine": "A patch of soft dark brown matter. Probably mud.", + "ids": "310" + }, + { + "examine": "A pile of something I hope is mud.", + "ids": "311" + }, + { + "examine": "Potato-licious!", + "ids": "312" + }, + { + "examine": "Baby bread.", + "ids": "313" + }, + { + "examine": "The remains of a bad driver.", + "ids": "327" + }, + { + "examine": "The perfect place to store things.", + "ids": "346,347" + }, + { + "examine": "These open and close!", + "ids": "348" + }, + { + "examine": "This may be worth searching.", + "ids": "349" + }, + { + "examine": "These open and close!", + "ids": "350" + }, + { + "examine": "This may be worth searching.", + "ids": "351" + }, + { + "examine": "These open and close!", + "ids": "352" + }, + { + "examine": "This may be worth searching.", + "ids": "353" + }, + { + "examine": "A wooden crate for storage.", + "ids": "354,355" + }, + { + "examine": "An old crate for storage.", + "ids": "356,357,358" + }, + { + "examine": "A pile of boxes for storage.", + "ids": "359,360,361" + }, + { + "examine": "A wooden barrel for storage.", + "ids": "362" + }, + { + "examine": "A wooden barrel containing lots of fish.", + "ids": "363" + }, + { + "examine": "It's got ale in it.", + "ids": "364,32063" + }, + { + "examine": "These may have something in them.", + "ids": "365" + }, + { + "examine": "Useful for transportation of delicate items.", + "ids": "366" + }, + { + "examine": "This may be worth opening.", + "ids": "367,368,369" + }, + { + "examine": "This may be worth searching.", + "ids": "370,371,372" + }, + { + "examine": "The perfect accompaniment to a bedroom.", + "ids": "373" + }, + { + "examine": "A stand for hats!", + "ids": "374" + }, + { + "examine": "I wonder what's inside.", + "ids": "375,376,377" + }, + { + "examine": "Perhaps I should search it.", + "ids": "378,379" + }, + { + "examine": "A good source of books!", + "ids": "380,381" + }, + { + "examine": "A woven storage basket.", + "ids": "382,383,384,385" + }, + { + "examine": "A gigantic pottery urn.", + "ids": "386" + }, + { + "examine": "This no doubt contains arcane knowledge.", + "ids": "387" + }, + { + "examine": "I wonder what this spooky item contains.", + "ids": "388" + }, + { + "examine": "It smells funny in there.", + "ids": "389,390" + }, + { + "examine": "A fishing net full of fish.", + "ids": "392" + }, + { + "examine": "A good source of books!", + "ids": "393" + }, + { + "examine": "Bamboo storage!", + "ids": "394,395,396" + }, + { + "examine": "The perfect place to store things.", + "ids": "397" + }, + { + "examine": "I hope no-one's home...", + "ids": "398,26931,26935,26937,26939,32290" + }, + { + "examine": "I see dead people.", + "ids": "399,36737,32291" + }, + { + "examine": "A small simple gravestone.", + "ids": "400" + }, + { + "examine": "A simple marker for a forgotten person.", + "ids": "401" + }, + { + "examine": "The remains of someone lie inside.", + "ids": "402" + }, + { + "examine": "A monument to a special person.", + "ids": "403" + }, + { + "examine": "The inscription is worn away and unreadable.", + "ids": "404" + }, + { + "examine": "'Here lies...' is all I can read.", + "ids": "405" + }, + { + "examine": "Whoever bought this must have really cared for the inhabitant.", + "ids": "406" + }, + { + "examine": "Looks like a stone doorway to me.", + "ids": "407" + }, + { + "examine": "Looks like a stone doorway to my untrained eye.", + "ids": "408" + }, + { + "examine": "Shrine to the glory of Saradomin.", + "ids": "409" + }, + { + "examine": "An ancient altar to the glory of Guthix.", + "ids": "410" + }, + { + "examine": "Shrine to the glory of Zamorak.", + "ids": "411,412" + }, + { + "examine": "Looks suspiciously like a big stone table.", + "ids": "413" + }, + { + "examine": "A really posh upright coffin.", + "ids": "414" + }, + { + "examine": "Whoever's inside must have been rich.", + "ids": "415" + }, + { + "examine": "With skill I can play this.", + "ids": "416" + }, + { + "examine": "Great for sleeping in.", + "ids": "417" + }, + { + "examine": "A stylish-looking bed.", + "ids": "418" + }, + { + "examine": "A drab-looking bed.", + "ids": "419" + }, + { + "examine": "A stylish-looking bed.", + "ids": "420,421" + }, + { + "examine": "Technically a bed.", + "ids": "422" + }, + { + "examine": "I guess I could sleep in it if I were really tired.", + "ids": "423" + }, + { + "examine": "Lovely comfy-looking big bed.", + "ids": "424,425" + }, + { + "examine": "Posh-looking bed.", + "ids": "426" + }, + { + "examine": "A bed fit for a king.", + "ids": "427,428" + }, + { + "examine": "One of the nicest beds I have ever seen.", + "ids": "429" + }, + { + "examine": "Perfect for snoozing in the sun.", + "ids": "430" + }, + { + "examine": "A comfortable seat to recline and recuperate.", + "ids": "431" + }, + { + "examine": "I don't think anyone's slept here for a long time.", + "ids": "432" + }, + { + "examine": "Bamboo's a versatile material.", + "ids": "433,434,435" + }, + { + "examine": "A lump of rock.", + "ids": "436,437,438,439" + }, + { + "examine": "A big slimy lump of rock.", + "ids": "440" + }, + { + "examine": "A slimy lump of rock.", + "ids": "441" + }, + { + "examine": "A slippery looking rock.", + "ids": "442,443" + }, + { + "examine": "A huge lump of rock.", + "ids": "444,445" + }, + { + "examine": "Some small stones.", + "ids": "446,447,448" + }, + { + "examine": "A rocky ledge.", + "ids": "449" + }, + { + "examine": "Stoney!", + "ids": "450,451,452,453" + }, + { + "examine": "Solid rock from the cave floor.", + "ids": "454,455" + }, + { + "examine": "Looks slippery!", + "ids": "462,463" + }, + { + "examine": "Formed over many years of dripping limestone.", + "ids": "464,465,466" + }, + { + "examine": "A limestone ceiling growth.", + "ids": "467" + }, + { + "examine": "Limestone floor growth.", + "ids": "468" + }, + { + "examine": "A limestone ceiling growth.", + "ids": "469,470" + }, + { + "examine": "A deposit of rocks.", + "ids": "471,472,473,474" + }, + { + "examine": "Looks slippery!", + "ids": "477,478" + }, + { + "examine": "A deposit of rocks.", + "ids": "479,480,481,482,483,484,485,486" + }, + { + "examine": "A collection of rocks over what looks like a depression.", + "ids": "492" + }, + { + "examine": "A deposit of rocks.", + "ids": "507,508,509,510" + }, + { + "examine": "A rock with a pickaxe and mining tools.", + "ids": "511" + }, + { + "examine": "A very tall column of ice.", + "ids": "516" + }, + { + "examine": "A deposit of rocks.", + "ids": "517,518,519,520" + }, + { + "examine": "Formed over many years of dripping limestone.", + "ids": "523,524,525,526,527,528" + }, + { + "examine": "A limestone ceiling growth.", + "ids": "529" + }, + { + "examine": "Formed over many years of dripping limestone.", + "ids": "530" + }, + { + "examine": "A limestone ceiling growth.", + "ids": "531" + }, + { + "examine": "Limestone floor growth.", + "ids": "532" + }, + { + "examine": "A limestone ceiling growth.", + "ids": "533" + }, + { + "examine": "A tooth shaped rock formation protruding from the floor.", + "ids": "534" + }, + { + "examine": "A tooth shaped rock formation protruding from the ceiling.", + "ids": "539,540" + }, + { + "examine": "A tooth shaped rock formation protruding from the floor.", + "ids": "541,542" + }, + { + "examine": "A tooth shaped rock formation protruding from the ceiling.", + "ids": "543" + }, + { + "examine": "A tooth shaped rock formation protruding from the floor.", + "ids": "544" + }, + { + "examine": "A huge lump of rock.", + "ids": "545" + }, + { + "examine": "Intimidating!", + "ids": "546,547" + }, + { + "examine": "A deposit of rocks.", + "ids": "548,549,550,551,552,553" + }, + { + "examine": "Frozen water has formed an icicle here.", + "ids": "554,555,556,557" + }, + { + "examine": "It looks cold in there.", + "ids": "558,559,560,561" + }, + { + "examine": "This person was of great importance.", + "ids": "562" + }, + { + "examine": "A monarch chiselled in stone.", + "ids": "563,564" + }, + { + "examine": "A sculpture of a monarch.", + "ids": "565" + }, + { + "examine": "This person was of great importance.", + "ids": "566" + }, + { + "examine": "A huge carving of an ancient race.", + "ids": "567" + }, + { + "examine": "A depiction of a great dwarven miner.", + "ids": "568" + }, + { + "examine": "A depiction of a famous gnome warrior.", + "ids": "569,570" + }, + { + "examine": "The head and shoulders of a famous gnome.", + "ids": "571,572" + }, + { + "examine": "A depiction of a famous gnomeballer.", + "ids": "573" + }, + { + "examine": "A carving of a figure from the history of 2009Scape.", + "ids": "574,575,576,577,578" + }, + { + "examine": "An expertly chiselled statue.", + "ids": "579,580,581" + }, + { + "examine": "An unusual symbol of ancient times.", + "ids": "582" + }, + { + "examine": "An expertly crafted vase.", + "ids": "583" + }, + { + "examine": "An expertly chiselled statue of a bird.", + "ids": "584" + }, + { + "examine": "What a good likeness!", + "ids": "585,586" + }, + { + "examine": "A depiction of the evil god Zamorak.", + "ids": "587" + }, + { + "examine": "A base for the statue to sit on.", + "ids": "588" + }, + { + "examine": "The scrying glass of a seer.", + "ids": "589" + }, + { + "examine": "Banking transactions are processed here.", + "ids": "590" + }, + { + "examine": "Banking transactions are recorded here.", + "ids": "591" + }, + { + "examine": "Contains washing items.", + "ids": "592" + }, + { + "examine": "A nice sturdy looking table.", + "ids": "593,594,595" + }, + { + "examine": "A banquet could be eaten from this.", + "ids": "596,597" + }, + { + "examine": "Useful for putting things on.", + "ids": "598" + }, + { + "examine": "At one time it was for putting things on.", + "ids": "599" + }, + { + "examine": "The napkins are made from real silk.", + "ids": "600" + }, + { + "examine": "Useful for putting things on.", + "ids": "601,602,603,604,605,606" + }, + { + "examine": "Items for making clothes are kept on here.", + "ids": "607" + }, + { + "examine": "The ideal place to study.", + "ids": "608" + }, + { + "examine": "A handy workbench for a handy person.", + "ids": "609,610" + }, + { + "examine": "Sit back and enjoy the view.", + "ids": "611" + }, + { + "examine": "Items are for sale here.", + "ids": "612" + }, + { + "examine": "Useful for putting things on.", + "ids": "613,614,615" + }, + { + "examine": "A creepy looking table.", + "ids": "616" + }, + { + "examine": "Items are for sale here.", + "ids": "617" + }, + { + "examine": "There are some strange chemicals here.", + "ids": "618,619" + }, + { + "examine": "Bamboo's a versatile material.", + "ids": "620" + }, + { + "examine": "It's a banquet table.", + "ids": "621,622" + }, + { + "examine": "A nice sturdy looking table.", + "ids": "623,624,625,626,627" + }, + { + "examine": "Finely wrought wares of silver.", + "ids": "628" + }, + { + "examine": "Garments for the discerning.", + "ids": "629" + }, + { + "examine": "Bread cakes and pastries.", + "ids": "630" + }, + { + "examine": "Finest precious stones.", + "ids": "631" + }, + { + "examine": "These will keep you warm.", + "ids": "632" + }, + { + "examine": "The spice is right.", + "ids": "633" + }, + { + "examine": "Always a source of good bargains.", + "ids": "634" + }, + { + "examine": "Fine brews from exotic regions.", + "ids": "635" + }, + { + "examine": "Keeps mine carts from rolling away.", + "ids": "636" + }, + { + "examine": "You can 'cart' things around on this.", + "ids": "637" + }, + { + "examine": "Makes you taller.", + "ids": "647,29314" + }, + { + "examine": "A bit large for a bracelet!", + "ids": "648" + }, + { + "examine": "A macabre variation on the neck tie.", + "ids": "649,650" + }, + { + "examine": "Dead and half buried.", + "ids": "651,652,653,654,655,656,657" + }, + { + "examine": "Disturbing but tidy.", + "ids": "658" + }, + { + "examine": "I don't even want to think about what did that...", + "ids": "659" + }, + { + "examine": "Now that's what I call slimline!", + "ids": "660,664,3797,3971,5122,7206,29340" + }, + { + "examine": "He looks very relaxed.", + "ids": "661,665,3798,3972,5123,7207,29341" + }, + { + "examine": "Now he's just too thin.", + "ids": "662,666,3799,3973,5124,7208,7209,7210,7211,7212,7213,7214,7215,7216,7217,7218,29342" + }, + { + "examine": "He hasn't eaten in a long time.", + "ids": "663,667,3974,5125,29343" + }, + { + "examine": "Disturbing but tidy.", + "ids": "658,668,669,670,3969,29347" + }, + { + "examine": "No cats were harmed in the making of this device.", + "ids": "671" + }, + { + "examine": "Shattered.", + "ids": "672,673,674,675,676,677" + }, + { + "examine": "I see fish.", + "ids": "678" + }, + { + "examine": "I can see fish swimming in the water.", + "ids": "679" + }, + { + "examine": "I was always forced to play this as a child.", + "ids": "680" + }, + { + "examine": "I never learnt to play.", + "ids": "681" + }, + { + "examine": "Time for a recital?", + "ids": "682" + }, + { + "examine": "Tick-tock, it's a clock.", + "ids": "683" + }, + { + "examine": "The noxious liquid bubbles horribly.", + "ids": "684" + }, + { + "examine": "Shows which way the wind blows.", + "ids": "685,686,687,688" + }, + { + "examine": "Looking good!", + "ids": "689" + }, + { + "examine": "A privacy aid!", + "ids": "690" + }, + { + "examine": "Use this to get changed behind and retain modesty.", + "ids": "691" + }, + { + "examine": "I don't even want to think about what's cooking in that.", + "ids": "692" + }, + { + "examine": "Good for sweeping.", + "ids": "693" + }, + { + "examine": "I'm guessing it's for making women's clothes.", + "ids": "694" + }, + { + "examine": "Helps make human clothing.", + "ids": "695" + }, + { + "examine": "A hole.", + "ids": "696" + }, + { + "examine": "Dead animal head. Lovely.", + "ids": "697,736,29344" + }, + { + "examine": "Must have been laid by a huge bird.", + "ids": "698" + }, + { + "examine": "Whatever it was I'm glad it's not alive.", + "ids": "699" + }, + { + "examine": "Spooky!", + "ids": "700,701,2614,4048,4049,4050,29345" + }, + { + "examine": "A dog's idea of heaven.", + "ids": "702,703,704,705,706,29346" + }, + { + "examine": "Ding-Dong!", + "ids": "707" + }, + { + "examine": "Some kind of pulley system.", + "ids": "708" + }, + { + "examine": "Surprisingly rope-shaped.", + "ids": "709" + }, + { + "examine": "Suspiciously hole-shaped.", + "ids": "710" + }, + { + "examine": "A huge chunk of shining natural crystal.", + "ids": "711,712,713" + }, + { + "examine": "A recently extinguished fire.", + "ids": "714,715,716,717" + }, + { + "examine": "A barrel full of swords...", + "ids": "718,719,720,721,722" + }, + { + "examine": "I'm glad this isn't around anymore!", + "ids": "723" + }, + { + "examine": "A crude torch stuck in the ground.", + "ids": "724,725,726,25200" + }, + { + "examine": "A fissure in the cave wall.", + "ids": "727,728,729,730,731,732" + }, + { + "examine": "This huge web blocks your path.", + "ids": "733" + }, + { + "examine": "A huge web, cruelly slashed in half.", + "ids": "734" + }, + { + "examine": "The noxious liquid bubbles horribly.", + "ids": "735" + }, + { + "examine": "Whatever it was I'm glad it's not alive.", + "ids": "737,738,739,740" + }, + { + "examine": "Looks a little too broken to climb.", + "ids": "741,742" + }, + { + "examine": "An old-looking ladder.", + "ids": "743" + }, + { + "examine": "An old-looking bit of scaffolding.", + "ids": "744,745,746,747" + }, + { + "examine": "The entrance to the cave.", + "ids": "748" + }, + { + "examine": "A map icon..", + "ids": "771" + }, + { + "examine": "It's a door made from bamboo.", + "ids": "779" + }, + { + "examine": "A loom.", + "ids": "787" + }, + { + "examine": "You'd need a big siege engine to force that.", + "ids": "788,789" + }, + { + "examine": "I always wonder if someone's hiding inside when I see these.", + "ids": "817" + }, + { + "examine": "Looks kind of like a man made of metal.", + "ids": "818,819,820" + }, + { + "examine": "Not suitable for children. Aim away from face.", + "ids": "821,36780" + }, + { + "examine": "Big heavy metal balls.", + "ids": "822,36790" + }, + { + "examine": "The easiest opponent I'll ever fight.", + "ids": "823" + }, + { + "examine": "A wooden defensive structure.", + "ids": "824,825,826,827,828,36928" + }, + { + "examine": "For private use only!", + "ids": "829,830,831,832,833" + }, + { + "examine": "Break glass in case of emergency.", + "ids": "834,835" + }, + { + "examine": "An attractively laid out collection of ranging weapons.", + "ids": "836" + }, + { + "examine": "Break glass in case of emergency.", + "ids": "837,838" + }, + { + "examine": "An attractively laid out collection of ranging weapons.", + "ids": "839" + }, + { + "examine": "A row of sharp pointy spears.", + "ids": "848" + }, + { + "examine": "Rows of sharp pointy spears.", + "ids": "849,850" + }, + { + "examine": "A tatty old standard.", + "ids": "851,852" + }, + { + "examine": "A standard.", + "ids": "853" + }, + { + "examine": "A blue standard.", + "ids": "854,855,856" + }, + { + "examine": "A standard of the gnome race.", + "ids": "857,858" + }, + { + "examine": "The standard of the ogre race.", + "ids": "859" + }, + { + "examine": "The flag of Asgarnia.", + "ids": "860" + }, + { + "examine": "The flag of Kandarin.", + "ids": "861" + }, + { + "examine": "The flag of Ardougne.", + "ids": "862" + }, + { + "examine": "A standard of Asgarnia.", + "ids": "863" + }, + { + "examine": "A standard of Kandarin.", + "ids": "864" + }, + { + "examine": "A standard of Asgarnia.", + "ids": "865" + }, + { + "examine": "A standard of Kandarin.", + "ids": "866" + }, + { + "examine": "A standard of Misthalin.", + "ids": "867" + }, + { + "examine": "A standard of Varrock.", + "ids": "868" + }, + { + "examine": "A flag flies here.", + "ids": "869" + }, + { + "examine": "A sculpted trunk of wood.", + "ids": "870" + }, + { + "examine": "Takes my dirty bath water away.", + "ids": "871" + }, + { + "examine": "It smells horrible in there.", + "ids": "872" + }, + { + "examine": "Ideal for washing things in.", + "ids": "873,874,4063,36971" + }, + { + "examine": "Wash here.", + "ids": "875,876,877" + }, + { + "examine": "No this is not a mirage!", + "ids": "878" + }, + { + "examine": "Everyone needs a water feature.", + "ids": "879,28682" + }, + { + "examine": "A beautiful water feature.", + "ids": "880" + }, + { + "examine": "There's a cover over this manhole.", + "ids": "881" + }, + { + "examine": "How dangerous, someone has left this manhole open.", + "ids": "882" + }, + { + "examine": "This is supposed to stop people falling down the manhole.", + "ids": "883" + }, + { + "examine": "Best used with a bucket.", + "ids": "884" + }, + { + "examine": "If only I had one of those at home...", + "ids": "885,886" + }, + { + "examine": "A painting of the King looking royal.", + "ids": "887" + }, + { + "examine": "A beautiful landscape.", + "ids": "888" + }, + { + "examine": "A mysterious figure stands alone in this haunting image.", + "ids": "889" + }, + { + "examine": "Hail to the King!", + "ids": "890" + }, + { + "examine": "I don't know much about art, but I like this.", + "ids": "891" + }, + { + "examine": "A painting of some guy standing around somewhere.", + "ids": "892" + }, + { + "examine": "A really bad portrait of the King.", + "ids": "893" + }, + { + "examine": "Fine brushwork adds to the realism of this serene landscape.", + "ids": "894" + }, + { + "examine": "Pretty good painting.", + "ids": "895" + }, + { + "examine": "I can see the stars on this.", + "ids": "896" + }, + { + "examine": "A picture of the stars with funny diagrams and things on.", + "ids": "897" + }, + { + "examine": "Cross shaped.", + "ids": "898" + }, + { + "examine": "Mmmm decorative!", + "ids": "899" + }, + { + "examine": "Brightens up the room a bit.", + "ids": "900" + }, + { + "examine": "I don't know art, but I like it!", + "ids": "901" + }, + { + "examine": "Not bad at all.", + "ids": "902" + }, + { + "examine": "Alas poor unicorn, I knew him well.", + "ids": "903" + }, + { + "examine": "The scary-looking head of a scary-looking dragon.", + "ids": "904" + }, + { + "examine": "Not what I would pick as wall decoration.", + "ids": "905" + }, + { + "examine": "Looks like the bull lost.", + "ids": "906" + }, + { + "examine": "Trinkets and stuff.", + "ids": "907" + }, + { + "examine": "Not everyone's idea of a nice wall decoration.", + "ids": "908" + }, + { + "examine": "Something is written on it. I can't read what.", + "ids": "909" + }, + { + "examine": "Looks like an eye with huge lashes.", + "ids": "910" + }, + { + "examine": "A tablet covered in weird looking little squiggles and pictures.", + "ids": "911" + }, + { + "examine": "A posh water bowl.", + "ids": "915" + }, + { + "examine": "For wiping muddy feet on.", + "ids": "954" + }, + { + "examine": "Disturbingly its eyes look everywhere in the room except at you.", + "ids": "955,956,957,958" + }, + { + "examine": "What has a face and hands but is not a man?", + "ids": "959" + }, + { + "examine": "It's a time machine....sort of!", + "ids": "960" + }, + { + "examine": "'Ask about our low, low interest rates!'", + "ids": "961" + }, + { + "examine": "Some helpful people have placed notes on here, how nice.", + "ids": "962" + }, + { + "examine": "Essentials for a seamstress.", + "ids": "963" + }, + { + "examine": "It really was this big!", + "ids": "964,965" + }, + { + "examine": "He doesn't look too jolly to me!", + "ids": "966" + }, + { + "examine": "Looks like this ship was way off course!", + "ids": "967" + }, + { + "examine": "X marks the spot.", + "ids": "968" + }, + { + "examine": "Complete with authentic seaweed!", + "ids": "969" + }, + { + "examine": "This mentions the monk trapped here...", + "ids": "970" + }, + { + "examine": "A useful ranging device.", + "ids": "971" + }, + { + "examine": "Use these with bows.", + "ids": "972" + }, + { + "examine": "A powerful throwing weapon.", + "ids": "973" + }, + { + "examine": "Improved Leather armour for archers.", + "ids": "974" + }, + { + "examine": "Leather made from the skin of a Dragon.", + "ids": "975" + }, + { + "examine": "I can climb over the fence with this..", + "ids": "993" + }, + { + "examine": "This section of railing has been broken", + "ids": "1004,1005" + }, + { + "examine": "There is a hole in this section of the railing.", + "ids": "1006,1007,1008,1009" + }, + { + "examine": "Someone was thirsty...", + "ids": "1010" + }, + { + "examine": "Full of lovely drinks!", + "ids": "1011,1012" + }, + { + "examine": "Storage for cookery items.", + "ids": "1013,32283,40055" + }, + { + "examine": "Storage for all needs.", + "ids": "1014,1015,1016,1017,1018,10495,10496,10497,10498,11768,11769,11770,11771,11772,11773,11774,11775,11776,11777,11778,11779,11780,11781,12980,30648,30649,30650,32284,40045,40046,40047" + }, + { + "examine": "What kind of sick person keeps a skull on their wall?", + "ids": "1019" + }, + { + "examine": "Esoteric artefacts.", + "ids": "1020" + }, + { + "examine": "I don't want to know what's in those little urns.", + "ids": "1021,1022,1023" + }, + { + "examine": "Used for storing things on.", + "ids": "1024" + }, + { + "examine": "Tailor made for needlework supplies", + "ids": "1025,1026" + }, + { + "examine": "Prepared hides hang here drying.", + "ids": "1027" + }, + { + "examine": "This contains dye for leather.", + "ids": "1028,1029" + }, + { + "examine": "Used to squeeze moisture from the hide.", + "ids": "1030,1031" + }, + { + "examine": "Danger!", + "ids": "1032,5127" + }, + { + "examine": "This tells you which way is which.", + "ids": "1033,1034,1035" + }, + { + "examine": "Ye olde Shrimp and Parrot.", + "ids": "1057" + }, + { + "examine": "The Blue Moon Inn", + "ids": "1068" + }, + { + "examine": "The Jolly Boar", + "ids": "1069" + }, + { + "examine": "The Rusty Anchor", + "ids": "1070" + }, + { + "examine": "The Shrimp and Parrot", + "ids": "1071" + }, + { + "examine": "The Dead Man's Chest", + "ids": "1072" + }, + { + "examine": "The Rising Sun", + "ids": "1073" + }, + { + "examine": "The Forester's Arms", + "ids": "1074" + }, + { + "examine": "The Flying Horse", + "ids": "1075" + }, + { + "examine": "The Dancing Donkey", + "ids": "1076" + }, + { + "examine": "The Dragon Inn", + "ids": "1077" + }, + { + "examine": "Karamja Spirits bar", + "ids": "1078" + }, + { + "examine": "North to Varrock :: East to Al-Kharid.", + "ids": "1079" + }, + { + "examine": "North road to Draynor Village :: East road to Varrock.", + "ids": "1080" + }, + { + "examine": "North to Draynor Village.", + "ids": "1081" + }, + { + "examine": "North to Draynor Manor :: West to Asgarnia.", + "ids": "1082" + }, + { + "examine": "South to the Wizards' Tower :: East to Lumbridge.", + "ids": "1083" + }, + { + "examine": "South to Lumbridge :: West to Varrock :: East to the Digsite.", + "ids": "1084" + }, + { + "examine": "South to Al-Kharid :: West to Lumbridge :: East to the Digsite.", + "ids": "1085" + }, + { + "examine": "North to Varrock :: East to the Digsite.", + "ids": "1086" + }, + { + "examine": "South to the Wizards' Tower :: North to Draynor Village :: East to Lumbridge.", + "ids": "1087" + }, + { + "examine": "The ideal thing to sit on.", + "ids": "1088,1115,3801,5345,5614,7385,7386,7387,10491,11489,12885,12886,13582,32032,36830,40039" + }, + { + "examine": "Not so good for sitting on.", + "ids": "1089" + }, + { + "examine": "A comfortable seat.", + "ids": "1090,1091,1092,11760,13583,13584,13585,13586,13587,32286" + }, + { + "examine": "Good for sitting on.", + "ids": "1093,1094,1095,1102,5880,10492,12440,12441,12973,32033" + }, + { + "examine": "Good for rocking in!", + "ids": "1096" + }, + { + "examine": "A kingly seat for a royal behind.", + "ids": "1097,1098,1099,1105,1108,1109,32285" + }, + { + "examine": "The perfect way to sit at the bar.", + "ids": "1100,1101" + }, + { + "examine": "Gnomes sit on these.", + "ids": "1103" + }, + { + "examine": "Gnomes are found sitting here.", + "ids": "1104" + }, + { + "examine": "Sit back and relax...", + "ids": "1106,1107" + }, + { + "examine": "Used for sitting on.", + "ids": "1110" + }, + { + "examine": "Do I dare sit on this?", + "ids": "1111" + }, + { + "examine": "Church seating.", + "ids": "1112" + }, + { + "examine": "Park it here...", + "ids": "1113" + }, + { + "examine": "Wouldn't like to sit on that for too long...", + "ids": "1114" + }, + { + "examine": "Keeps the neighbours out!", + "ids": "1116,1117" + }, + { + "examine": "Found in wild areas.", + "ids": "1118" + }, + { + "examine": "These are commonly found.", + "ids": "1119" + }, + { + "examine": "An unusual bush.", + "ids": "1120" + }, + { + "examine": "A wild bush.", + "ids": "1121" + }, + { + "examine": "All the leaves have fallen off.", + "ids": "1122,1123" + }, + { + "examine": "A commonly found bush.", + "ids": "1124,36782" + }, + { + "examine": "Bushy!", + "ids": "1125" + }, + { + "examine": "A rose by any other name would still have prickly bits.", + "ids": "1126" + }, + { + "examine": "A leafy bush.", + "ids": "1144,1145,1146" + }, + { + "examine": "The abode of a fairy.", + "ids": "1147,1148,1149" + }, + { + "examine": "Fairies need money too!", + "ids": "1150" + }, + { + "examine": "A fairy is selling items here.", + "ids": "1151" + }, + { + "examine": "A small potted plant.", + "ids": "1152" + }, + { + "examine": "Someone has planted this.", + "ids": "1153" + }, + { + "examine": "A nicely potted fern.", + "ids": "1154" + }, + { + "examine": "Better than weeding.", + "ids": "1155" + }, + { + "examine": "I bet bees like this.", + "ids": "1156,1157" + }, + { + "examine": "A large potted plant.", + "ids": "1158,1159" + }, + { + "examine": "A plant in a bamboo pot.", + "ids": "1160" + }, + { + "examine": "Cabbage... yuck!", + "ids": "1161" + }, + { + "examine": "Found near the water's edge.", + "ids": "1162" + }, + { + "examine": "Not good for eating.", + "ids": "1163,1164" + }, + { + "examine": "Fungal growth.", + "ids": "1165" + }, + { + "examine": "Poisonous no doubt.", + "ids": "1166" + }, + { + "examine": "Fungal growth.", + "ids": "1167" + }, + { + "examine": "Poisonous no doubt.", + "ids": "1168,1169" + }, + { + "examine": "I doubt that's edible.", + "ids": "1170,1171,1172" + }, + { + "examine": "A commonly found fern.", + "ids": "1173" + }, + { + "examine": "Spiky!", + "ids": "1174" + }, + { + "examine": "A home for frogs.", + "ids": "1175" + }, + { + "examine": "Otherwise known as a lilypad.", + "ids": "1176" + }, + { + "examine": "A home for frogs.", + "ids": "1177" + }, + { + "examine": "Smells lovely!", + "ids": "1178" + }, + { + "examine": "Who is this Heather girl?", + "ids": "1179" + }, + { + "examine": "I wonder why it's purple?", + "ids": "1180" + }, + { + "examine": "I'd better not get stung.", + "ids": "1181,1182,1183" + }, + { + "examine": "The tendrils of a creeping plant.", + "ids": "1184" + }, + { + "examine": "Nicely planted.", + "ids": "1185" + }, + { + "examine": "A large curling plant.", + "ids": "1186" + }, + { + "examine": "That's pretty.", + "ids": "1187" + }, + { + "examine": "Blooming!", + "ids": "1188" + }, + { + "examine": "Commonly found in grassy areas.", + "ids": "1189" + }, + { + "examine": "Is this the biggest flower around?", + "ids": "1190" + }, + { + "examine": "These are huge!", + "ids": "1191" + }, + { + "examine": "A rare flower.", + "ids": "1192" + }, + { + "examine": "Don't flowers make you feel better?", + "ids": "1193" + }, + { + "examine": "Can this talk?", + "ids": "1194" + }, + { + "examine": "You don't see that many of these.", + "ids": "1195" + }, + { + "examine": "I wonder what these are?", + "ids": "1196" + }, + { + "examine": "A rarely found flower.", + "ids": "1197" + }, + { + "examine": "Very rare flowers.", + "ids": "1198" + }, + { + "examine": "These smell nice.", + "ids": "1199" + }, + { + "examine": "A bed of red flowers.", + "ids": "1200" + }, + { + "examine": "These are pretty.", + "ids": "1201" + }, + { + "examine": "Found only in jungle areas.", + "ids": "1202" + }, + { + "examine": "A very rare exotic flower.", + "ids": "1203" + }, + { + "examine": "A small fernlike plant.", + "ids": "1204" + }, + { + "examine": "The leaves of a nasty creeping plant.", + "ids": "1205" + }, + { + "examine": "The flower of a nasty creeping plant.", + "ids": "1206,1207,1208" + }, + { + "examine": "Nasty curling tendrils of a creeping plant.", + "ids": "1231" + }, + { + "examine": "One of the most common trees in 2009Scape.", + "ids": "1276" + }, + { + "examine": "A healthy young tree.", + "ids": "1277" + }, + { + "examine": "A commonly found tree.", + "ids": "1278,1279" + }, + { + "examine": "A healthy young tree.", + "ids": "1280" + }, + { + "examine": "A beautiful old oak.", + "ids": "1281" + }, + { + "examine": "This tree has long been dead.", + "ids": "1282,1283,1284" + }, + { + "examine": "An old weather beaten tree.", + "ids": "1285" + }, + { + "examine": "It's only useful for firewood now.", + "ids": "1286,1287,1288,1289,1290,1291" + }, + { + "examine": "An ancient magical tree.", + "ids": "1292" + }, + { + "examine": "An ancient sentient tree.", + "ids": "1293,1294,1295" + }, + { + "examine": "This tree has fallen to the ground.", + "ids": "1296" + }, + { + "examine": "This tree was either the victim of weather or mankind.", + "ids": "1297" + }, + { + "examine": "A commonly found fern.", + "ids": "1298" + }, + { + "examine": "Is this a weed?", + "ids": "1299" + }, + { + "examine": "A fern is growing here.", + "ids": "1300" + }, + { + "examine": "Home to many unusual creatures.", + "ids": "1301" + }, + { + "examine": "A leafy tree.", + "ids": "1302" + }, + { + "examine": "A tree found in tropical areas.", + "ids": "1303,1304,1305" + }, + { + "examine": "The tree shimmers with a magical force.", + "ids": "1306" + }, + { + "examine": "I bet this makes good syrup!", + "ids": "1307" + }, + { + "examine": "These trees are found near water.", + "ids": "1308" + }, + { + "examine": "A splendid tree.", + "ids": "1309" + }, + { + "examine": "This tree has vines hanging from it.", + "ids": "1310" + }, + { + "examine": "This would be good to sleep under.", + "ids": "1311" + }, + { + "examine": "An essential for tropical islands.", + "ids": "1312" + }, + { + "examine": "An unusual tree grows here.", + "ids": "1313,1314" + }, + { + "examine": "A hardy evergreen tree.", + "ids": "1315,1316" + }, + { + "examine": "A young sentient tree.", + "ids": "1317" + }, + { + "examine": "This would make good firewood.", + "ids": "1318,1319" + }, + { + "examine": "The branch is infested with moss.", + "ids": "1320,1321" + }, + { + "examine": "The trunk of this tree is hollow.", + "ids": "1322" + }, + { + "examine": "A gnarly old tree root.", + "ids": "1323" + }, + { + "examine": "The roots of a tree are exposed.", + "ids": "1324" + }, + { + "examine": "I hope I don't trip over any of these.", + "ids": "1325" + }, + { + "examine": "A terribly tall tropical tree.", + "ids": "1326,1327,1328" + }, + { + "examine": "Leaves of a bamboo tree.", + "ids": "1329" + }, + { + "examine": "It's thick with snow.", + "ids": "1330,1331,1332" + }, + { + "examine": "This old tree has been taken over by parasitic plants.", + "ids": "1333" + }, + { + "examine": "This old tree is rotting away.", + "ids": "1334,1335,1336,1337,1338" + }, + { + "examine": "They're just waiting to trip someone up.", + "ids": "1339,1340" + }, + { + "examine": "This tree has been cut down.", + "ids": "1341,1342,1343,1344,1345,1346,1347,1348,1349,1350,1351,1352,1353,1354,1355,1356,1357,1358,1359" + }, + { + "examine": "This tree contains dangerous insects no doubt.", + "ids": "1360,1361,1362" + }, + { + "examine": "They're just waiting to trip someone up.", + "ids": "1363,1364" + }, + { + "examine": "It's only useful for firewood now.", + "ids": "1365" + }, + { + "examine": "A gnarly old tree root.", + "ids": "1366" + }, + { + "examine": "The roots of this tree are exposed.", + "ids": "1367" + }, + { + "examine": "I hope I don't trip over any of these.", + "ids": "1368" + }, + { + "examine": "An unusual tree grows here.", + "ids": "1369" + }, + { + "examine": "This old tree is rotting away.", + "ids": "1370" + }, + { + "examine": "This tree contains dangerous insects no doubt.", + "ids": "1371,1372,1373,1374,1375,1376,1377" + }, + { + "examine": "This old tree is rotting away.", + "ids": "1378,1379" + }, + { + "examine": "A gnarly old tree root.", + "ids": "1380" + }, + { + "examine": "The roots of this tree are exposed.", + "ids": "1381" + }, + { + "examine": "I hope I don't trip over any of these.", + "ids": "1382" + }, + { + "examine": "This tree has long been dead.", + "ids": "1383" + }, + { + "examine": "It's only useful for firewood now.", + "ids": "1384" + }, + { + "examine": "A gnarly old tree root.", + "ids": "1385" + }, + { + "examine": "The roots of this tree are exposed.", + "ids": "1386" + }, + { + "examine": "I hope I don't trip over any of these.", + "ids": "1387" + }, + { + "examine": "They're just waiting to trip someone up.", + "ids": "1388,1389" + }, + { + "examine": "Commonly found in these parts.", + "ids": "1390" + }, + { + "examine": "A leafy plant.", + "ids": "1391" + }, + { + "examine": "A leafy fern.", + "ids": "1392" + }, + { + "examine": "A small bushy plant.", + "ids": "1393" + }, + { + "examine": "A leafy shrub.", + "ids": "1394" + }, + { + "examine": "No flies on me.", + "ids": "1395" + }, + { + "examine": "How do these things manage to grow?", + "ids": "1396" + }, + { + "examine": "This cactus has recently had a chunk taken off.", + "ids": "1397" + }, + { + "examine": "A leafy fern.", + "ids": "1398" + }, + { + "examine": "This has broad leaves.", + "ids": "1399" + }, + { + "examine": "A large waxy jungle plant.", + "ids": "1400" + }, + { + "examine": "A type of jungle fern.", + "ids": "1401" + }, + { + "examine": "A large waxy jungle plant.", + "ids": "1402" + }, + { + "examine": "How do these things manage to grow?", + "ids": "1403,1404,1405,1406" + }, + { + "examine": "Leaves a nasty mark.", + "ids": "1407" + }, + { + "examine": "Looks spiky.", + "ids": "1408,1409,1410,1411,1412,1413,1414,1415,1416,1417,1418,1419,1420,1421,1422,1423,1424,1425,1426,1427,1428,1429,1430,1431,1432,1433,1434,1435,1436,1437,1438,1439,1440,1441,1442,1443,1444,1445,1446,1447,1448,1449,1450,1451,1452,1453,1454,1455,1456,1457,1458,1459,1460,1461,1462,1463,1464,1465,1466,1467,1468,1469,1470,1471,1472,1473,1474,1475,1476,1477,1478,1479,1480,1481,1482,1483,1484,1485,1486,1487,1488,1489,1490,1491,1492,1493,1494,1495,1496,1497,1498,1499,1500,1501,1502,1503" + }, + { + "examine": "The door is open.", + "ids": "1504" + }, + { + "examine": "The door is closed.", + "ids": "1505" + }, + { + "examine": "A sturdy wooden door.", + "ids": "1506,1507,1508,1509,1510,1511,1512,1513,1514,1515" + }, + { + "examine": "The curtain is closed.", + "ids": "1526,1527,1528" + }, + { + "examine": "The curtain is open.", + "ids": "1529" + }, + { + "examine": "The door is closed.", + "ids": "1530" + }, + { + "examine": "The door is open.", + "ids": "1531,1532" + }, + { + "examine": "A nicely fitted door.", + "ids": "1533,1534,1535" + }, + { + "examine": "An ornately-fashioned door.", + "ids": "1536" + }, + { + "examine": "An elf-fashioned door.", + "ids": "1537,1538" + }, + { + "examine": "Solid bars of iron.", + "ids": "1539,1540,1541,1542,1543,1544,1545,1546,1547,1548,1549,1550" + }, + { + "examine": "A wooden gate.", + "ids": "1551,1552,1553,1554,1555,1556" + }, + { + "examine": "A wrought iron gate.", + "ids": "1557,1558,1559,1560,1561,1562,1563,1564,1565,1566,1567" + }, + { + "examine": "I wonder what's under it?", + "ids": "1568,1569" + }, + { + "examine": "I wonder what's down there?", + "ids": "1570,1571" + }, + { + "examine": "This door has been boarded up.", + "ids": "1572" + }, + { + "examine": "A door to a grand place.", + "ids": "1573,1574,1575,1576" + }, + { + "examine": "The top of the archway.", + "ids": "1577,1578,1579" + }, + { + "examine": "The base of the archway.", + "ids": "1580,1581,1582" + }, + { + "examine": "There is something strange about this wall...", + "ids": "1583,1584,1585,1586,1587,1588" + }, + { + "examine": "A wrought iron gate.", + "ids": "1589,1590" + }, + { + "examine": "The door is closed.", + "ids": "1591" + }, + { + "examine": "Something is strange about this panel.", + "ids": "1592,1593" + }, + { + "examine": "An entranceway into the dungeon.", + "ids": "1594" + }, + { + "examine": "The way in.", + "ids": "1595" + }, + { + "examine": "A wrought iron gate.", + "ids": "1596,1597" + }, + { + "examine": "A wooden gate.", + "ids": "1598,1599" + }, + { + "examine": "The doors to the Magic Guild.", + "ids": "1600" + }, + { + "examine": "The doors to the Magic guild.", + "ids": "1601,1602,1603,1604,1605,1606,1607,1608" + }, + { + "examine": "A wooden structure used in the process of building.", + "ids": "1609,1610,1611,1612" + }, + { + "examine": "This timber is broken", + "ids": "1613,1614,1615,1616,1617,1618,1619,1620,1621,1622,1623,1624,1625,1626,1627,1628,1629,1630,1631,1632,1633,1634,1635,1636,1637,1638,1639,1640,1641,1642,1643,1644,1645,1646,1647,1648,1649,1650,1651,1652,1653,1654,1655,1656,1657,1658,1659,1660" + }, + { + "examine": "A pile of bricks.", + "ids": "1661,1662,1663,1664,1665,1666,1667,1668,1669,1670,1671,1672,1673,1674,1675,1676,1677,1678,1679,1680,1681,1682,1683,1684,1685,1686,1687,1688,1689,1690,1691,1692,1693,1694,1695,1696,1697,1698,1699,1700,1701,1702,1703,1704,1705,1706,1707,1708,1709,1710,1711,1712,1713,1714,1715,1716,1717,1718,1719,1720,1721" + }, + { + "examine": "I can climb these stairs.", + "ids": "1722,36791" + }, + { + "examine": "They go down.", + "ids": "1723" + }, + { + "examine": "I can climb down these stairs.", + "ids": "1724" + }, + { + "examine": "I can climb up this.", + "ids": "1725,36768,36771" + }, + { + "examine": "I can climb down this.", + "ids": "1726,1727,1728" + }, + { + "examine": "I can climb this.", + "ids": "1729,36347,36363,36644" + }, + { + "examine": "Dare I go up?", + "ids": "1730" + }, + { + "examine": "These stairs look spooky!", + "ids": "1731,1732" + }, + { + "examine": "I can use these stairs to climb down.", + "ids": "1733" + }, + { + "examine": "I can climb these stairs.", + "ids": "1734" + }, + { + "examine": "A rickety old staircase.", + "ids": "1735" + }, + { + "examine": "I can climb down these stairs.", + "ids": "1736" + }, + { + "examine": "I can climb up these stairs.", + "ids": "1737,1738" + }, + { + "examine": "I can climb up or go down these stairs.", + "ids": "1739" + }, + { + "examine": "I can climb down these stairs.", + "ids": "1740,1741" + }, + { + "examine": "I can climb up these stairs.", + "ids": "1742" + }, + { + "examine": "I can climb up or go down these stairs.", + "ids": "1743" + }, + { + "examine": "I can climb down these stairs.", + "ids": "1744,1745" + }, + { + "examine": "I can climb down this.", + "ids": "1746" + }, + { + "examine": "I can climb this.", + "ids": "1747,1748" + }, + { + "examine": "I can climb down this.", + "ids": "1749" + }, + { + "examine": "I can climb this.", + "ids": "1750,1751" + }, + { + "examine": "I can't climb this.", + "ids": "1752" + }, + { + "examine": "It's useless.", + "ids": "1753" + }, + { + "examine": "I can climb down this.", + "ids": "1754" + }, + { + "examine": "I can climb this.", + "ids": "1755" + }, + { + "examine": "I can climb down this.", + "ids": "1756" + }, + { + "examine": "I can climb this.", + "ids": "1757" + }, + { + "examine": "Not much use really.", + "ids": "1758" + }, + { + "examine": "This leads downwards.", + "ids": "1759" + }, + { + "examine": "These can be useful.", + "ids": "1760" + }, + { + "examine": "Steps made from natural rock.", + "ids": "1761" + }, + { + "examine": "A rope hangs here.", + "ids": "1762,1763,1764" + }, + { + "examine": "I can climb down this.", + "ids": "1765" + }, + { + "examine": "I can climb this.", + "ids": "1766" + }, + { + "examine": "I can climb down this.", + "ids": "1767" + }, + { + "examine": "I can climb this.", + "ids": "1768,1769,1770,1771,1772,1773,1774,1775,1776,1777" + }, + { + "examine": "These huge stone discs grind grain to make flour.", + "ids": "1778" + }, + { + "examine": "These sails use the wind to drive the windmill.", + "ids": "1779,1780,1781" + }, + { + "examine": "I'll need an empty pot so I can collect my flour.", + "ids": "1782,1783,1784,1785,1786,1787,1788,1789,1790,1791,1792,1793,1794,1795,1796" + }, + { + "examine": "Some very hard rocks, I wouldn't want to fall on those.", + "ids": "1797,1798,1799,1800,1801,1802,1803" + }, + { + "examine": "This door requires a key.", + "ids": "1804" + }, + { + "examine": "The door to the Champions' Guild.", + "ids": "1805,1806,1807,1808,1809" + }, + { + "examine": "Here be spiders!", + "ids": "1810" + }, + { + "examine": "I can walk through this tattered web.", + "ids": "1811" + }, + { + "examine": "A magical border of teleportation.", + "ids": "1812" + }, + { + "examine": "For putting things on.", + "ids": "1813" + }, + { + "examine": "I wonder what this does...", + "ids": "1814,1815,1816,1817,1818,1819,1820,1821,1822,1823,1824,1825,1826,1827,1828,1829,1830,1831,1832,1833,1834,1835,1836,1837,1838,1839,1840,1841,1842,1843,1844,1845,1846,1847,1848,1849,1850,1851" + }, + { + "examine": "This lets in more light.", + "ids": "1852,1853,1854,1855,1856,1857,1858,1859,1860,1861,1862,1863" + }, + { + "examine": "These obviously mean keep out!", + "ids": "1864,1865,1866,1867,1868,1869,1870,1871,1872,1873,1874,1875" + }, + { + "examine": "I shudder to think what has taken place here.", + "ids": "1876,1877,1878,1879,1880,1881,1882,1883,1884,1885,1886,1887,1888,1889,1890,1891,1892,1893,1894,1895,32289" + }, + { + "examine": "This hasn't seen a duster for a while.", + "ids": "1896" + }, + { + "examine": "Not as nice as some.", + "ids": "1897" + }, + { + "examine": "This needs dusting before I'll sit on it.", + "ids": "1898,1899" + }, + { + "examine": "This could do with a bit of a spit and polish.", + "ids": "1900" + }, + { + "examine": "This clearly isn't used for dining very often.", + "ids": "1901,1902,1903,1904,1905,1906,1907,1908,1909,1910,1911,1912,1913,1914,1915,1916,1917,1918,1919,1920,1921,1922,1923,1924,1925,1926,1927,1928,1929,1930,1931,1932,1933,1934,1935,1936,1937,1938" + }, + { + "examine": "A tower.", + "ids": "1939,1940,1941,1942,1943,1944,1945,1946" + }, + { + "examine": "It looks like I might be able to climb over this piece of the wall...", + "ids": "1947,1948" + }, + { + "examine": "A pile of bricks.", + "ids": "1949,1950,1951,1952,1953,1954,1955,1956,1957,1958,1959,1960,1961,1962,1963,1964,1965,1966" + }, + { + "examine": "A grand door for a grand tree.", + "ids": "1967,1968,1969,1970,1971,1972,1973,1974,1975,1976,1977,1978,1979,1980,1981,1982,1983,1984" + }, + { + "examine": "A large root.", + "ids": "1985,1986" + }, + { + "examine": "A primitive looking boat.", + "ids": "1987" + }, + { + "examine": "Oops!", + "ids": "1988" + }, + { + "examine": "A good source of books!", + "ids": "1989" + }, + { + "examine": "A wooden crate for storage.", + "ids": "1990" + }, + { + "examine": "Solid bars of iron.", + "ids": "1991" + }, + { + "examine": "There is an indent the size of a pebble in the stone's centre.", + "ids": "1992" + }, + { + "examine": "A stone tomb surrounded by flowers.", + "ids": "1993" + }, + { + "examine": "I wonder what's inside.", + "ids": "1994,37016,37015" + }, + { + "examine": "Perhaps I should search it.", + "ids": "1995" + }, + { + "examine": "I should be safe if I can reach this.", + "ids": "1996,1997" + }, + { + "examine": "Wet rope.", + "ids": "1998" + }, + { + "examine": "A wooden crate for storage.", + "ids": "1999" + }, + { + "examine": "An elf-fashioned door.", + "ids": "2000,2001,2002,2003" + }, + { + "examine": "The pillar has a rune shaped dent in it.", + "ids": "2004" + }, + { + "examine": "A statue of Baxtorian chiselled in stone.", + "ids": "2005" + }, + { + "examine": "A statue of Glarial chiselled in stone.", + "ids": "2006,2007,2008,2009" + }, + { + "examine": "A ledge.", + "ids": "2010,2011,2012" + }, + { + "examine": "Known commonly as Red worm vine.", + "ids": "2013" + }, + { + "examine": "A magically elevated chalice full of tears.", + "ids": "2014" + }, + { + "examine": "A magically elevated chalice full of ash.", + "ids": "2015,2016,2017,2018" + }, + { + "examine": "A whirlpool.", + "ids": "2019" + }, + { + "examine": "It's too wet for firewood.", + "ids": "2020,2021" + }, + { + "examine": "A wooden barrel, maybe a way off this rock.", + "ids": "2022" + }, + { + "examine": "An interesting tree with long straight branches.", + "ids": "2023" + }, + { + "examine": "A large bubbling cauldron, smells... Ugh!", + "ids": "2024" + }, + { + "examine": "The door is closed.", + "ids": "2025" + }, + { + "examine": "I can see fish swimming in the water.", + "ids": "2026,2027,2028,2029,2030,2031" + }, + { + "examine": "It's closed.", + "ids": "2032" + }, + { + "examine": "It's open.", + "ids": "2033" + }, + { + "examine": "It's closed.", + "ids": "2034" + }, + { + "examine": "It's open.", + "ids": "2035" + }, + { + "examine": "It's closed.", + "ids": "2036" + }, + { + "examine": "It's open.", + "ids": "2037" + }, + { + "examine": "I've met less intelligent conversationalists.", + "ids": "2038" + }, + { + "examine": "It's closed.", + "ids": "2039,2040,2041,2042" + }, + { + "examine": "Something's bubbling away in it.", + "ids": "2043" + }, + { + "examine": "Like an animal dinner table.", + "ids": "2044,2045,2046,2047" + }, + { + "examine": "It's a door.", + "ids": "2048,2049" + }, + { + "examine": "A wooden gate.", + "ids": "2050,2051,2052,2053" + }, + { + "examine": "It's a door.", + "ids": "2054,2055" + }, + { + "examine": "It's closed.", + "ids": "2056" + }, + { + "examine": "It's open.", + "ids": "2057" + }, + { + "examine": "It's closed.", + "ids": "2058,2059,2060,2061,2062" + }, + { + "examine": "It's open.", + "ids": "2063" + }, + { + "examine": "For storage.", + "ids": "2064" + }, + { + "examine": "Used for climbing.", + "ids": "2065" + }, + { + "examine": "A wall.", + "ids": "2066" + }, + { + "examine": "A watchtower.", + "ids": "2067" + }, + { + "examine": "A fence.", + "ids": "2068" + }, + { + "examine": "A closed door.", + "ids": "2069,2070" + }, + { + "examine": "Used for storage.", + "ids": "2071,2072" + }, + { + "examine": "Grows weird yellow fruit.", + "ids": "2073,2074,2075,2076,2077,2078" + }, + { + "examine": "I wonder what's inside?", + "ids": "2079,2080" + }, + { + "examine": "Handy for boarding boats.", + "ids": "2081,2082,2083,2084,2085,2086,2087,2088" + }, + { + "examine": "Ornamental.", + "ids": "2089" + }, + { + "examine": "A rocky outcrop.", + "ids": "2090,2091,2092,2093,2094,2095,2096,2097,2098,2099,2100,2101,2102,2103,2104,2105,2106,2107,2108,2109,2110,2111" + }, + { + "examine": "The door is closed.", + "ids": "2112" + }, + { + "examine": "I can climb down this.", + "ids": "2113" + }, + { + "examine": "This transports coal!", + "ids": "2114" + }, + { + "examine": "The left hand side of the gate.", + "ids": "2115" + }, + { + "examine": "The right hand side of the gate.", + "ids": "2116" + }, + { + "examine": "It's an old wall.", + "ids": "2117" + }, + { + "examine": "Lots of water swirling around", + "ids": "2118" + }, + { + "examine": "A rocky outcrop.", + "ids": "2119,2120,2121,2122,2123,2124,2125,2126,2127,2128,2129,2130,2131,2132,2133,2134,2135,2136,2137,2138,2139,2140" + }, + { + "examine": "An open chest.", + "ids": "2141" + }, + { + "examine": "An eerie glow permeates the cauldron.", + "ids": "2142" + }, + { + "examine": "Looks secure.", + "ids": "2143,2144" + }, + { + "examine": "Ooooh! Spooky!", + "ids": "2145,2146" + }, + { + "examine": "Going down?", + "ids": "2147" + }, + { + "examine": "Going up?", + "ids": "2148" + }, + { + "examine": "An imposing stone structure.", + "ids": "2149" + }, + { + "examine": "A column of elemental power.", + "ids": "2150,2151,2152,2153,29415" + }, + { + "examine": "A wrought iron gate.", + "ids": "2154,2155" + }, + { + "examine": "A magical portal of teleportation.", + "ids": "2156,2157,2158" + }, + { + "examine": "It's a floating barrel.", + "ids": "2159,2160,2161" + }, + { + "examine": "Smells like fish.", + "ids": "2162,2163,2164,2165,2166" + }, + { + "examine": "Water is pouring in through the hole.", + "ids": "2167" + }, + { + "examine": "A patch of swamp tar has bunged up the hole.", + "ids": "2168" + }, + { + "examine": "There's a strong wind whipping up the sea.", + "ids": "2169,2170,2171" + }, + { + "examine": "A huge net to catch little fish.", + "ids": "2172,2173" + }, + { + "examine": "The upper deck can be accessed with this ladder.", + "ids": "2174" + }, + { + "examine": "Back down to the main deck.", + "ids": "2175" + }, + { + "examine": "This old trawler has seen better days.", + "ids": "2176,2177" + }, + { + "examine": "Handy for boarding boats.", + "ids": "2178,2179" + }, + { + "examine": "It's a war machine.", + "ids": "2180,2181" + }, + { + "examine": "It can't hurt to just have a look, can it?", + "ids": "2182" + }, + { + "examine": "I wonder what is inside...", + "ids": "2183" + }, + { + "examine": "The door is closed.", + "ids": "2184" + }, + { + "examine": "This wall has seen better days.", + "ids": "2185" + }, + { + "examine": "Hmmm... I wonder if it's loose enough to get through.", + "ids": "2186" + }, + { + "examine": "I can climb down this ladder.", + "ids": "2187" + }, + { + "examine": "I can climb up this ladder.", + "ids": "2188,2189" + }, + { + "examine": "I can climb down this ladder.", + "ids": "2190" + }, + { + "examine": "I wonder what's inside?", + "ids": "2191,2192,2193" + }, + { + "examine": "Perhaps I should search it.", + "ids": "2194,2195,2196" + }, + { + "examine": "I wonder what's inside?", + "ids": "2197" + }, + { + "examine": "Perhaps I should search it.", + "ids": "2198" + }, + { + "examine": "An old gate for locking up undesirables.", + "ids": "2199,2200,2201,2202,2203,2204,2205,2206,2207,2208,2209" + }, + { + "examine": "Looking through it makes far off things look closer!", + "ids": "2210" + }, + { + "examine": "A weathered old gravestone.", + "ids": "2211" + }, + { + "examine": "Looks like fun.", + "ids": "2212" + }, + { + "examine": "The bank teller will serve you from here.", + "ids": "2213" + }, + { + "examine": "This booth is for private customers only.", + "ids": "2214,34205" + }, + { + "examine": "This booth is closed.", + "ids": "2215" + }, + { + "examine": "This looks like it's being used to block entrance to the village.", + "ids": "2216" + }, + { + "examine": "Something seems to be buried under this.", + "ids": "2217" + }, + { + "examine": "A narrow fissure in the ground.", + "ids": "2218,2219" + }, + { + "examine": "A pile of rubble.", + "ids": "2220" + }, + { + "examine": "A stone with some carvings on it.", + "ids": "2221" + }, + { + "examine": "A pile of loose rocks.", + "ids": "2222" + }, + { + "examine": "Probably nothing useful in these.", + "ids": "2223" + }, + { + "examine": "A rotten and barely standing set of gallows.", + "ids": "2224" + }, + { + "examine": "Wet rocks, it looks like you might be able to climb them.", + "ids": "2225" + }, + { + "examine": "This table has seen better days.", + "ids": "2226" + }, + { + "examine": "A crudely constructed raft.", + "ids": "2227,2228" + }, + { + "examine": "A statue to mark Tai Bwo Wannai sacred grounds.", + "ids": "2229" + }, + { + "examine": "A sturdy cart for travelling in.", + "ids": "2230" + }, + { + "examine": "A rocky outcrop.", + "ids": "2231,2232,2233" + }, + { + "examine": "Rocks that have been stacked at regular intervals.", + "ids": "2234" + }, + { + "examine": "An ancient construct for supporting the bones of the deceased.", + "ids": "2235" + }, + { + "examine": "I can climb the rocky outcrop.", + "ids": "2236" + }, + { + "examine": "An exotic looking tree.", + "ids": "2237" + }, + { + "examine": "Large doors set into the hillside.", + "ids": "2238,2239" + }, + { + "examine": "These doors must have been hidden here for years.", + "ids": "2240,2241" + }, + { + "examine": "Perhaps you should give them a push.", + "ids": "2242,2243" + }, + { + "examine": "Commonly found in these parts.", + "ids": "2244" + }, + { + "examine": "A leafy fern.", + "ids": "2245" + }, + { + "examine": "Large carved tomb doors, they look terrifying.", + "ids": "2246,2247,2248,2249,2250,2251,2252" + }, + { + "examine": "Perhaps you should give them a push.", + "ids": "2253,2254" + }, + { + "examine": "An ancient metal gate, but still pretty secure.", + "ids": "2255,2256" + }, + { + "examine": "A rocky outcrop.", + "ids": "2257" + }, + { + "examine": "An ancient construct for supporting the bones of the deceased.", + "ids": "2258" + }, + { + "examine": "The gate is closed.", + "ids": "2259,2260,2261,2262,2263,2264" + }, + { + "examine": "A sturdy cart for travelling in.", + "ids": "2265" + }, + { + "examine": "The door is closed.", + "ids": "2266,2267" + }, + { + "examine": "This leads up to the sleeping area.", + "ids": "2268" + }, + { + "examine": "This leads downwards.", + "ids": "2269" + }, + { + "examine": "A jungle plant.", + "ids": "2270" + }, + { + "examine": "I wonder what's inside?", + "ids": "2271" + }, + { + "examine": "It's open.", + "ids": "2272" + }, + { + "examine": "An odd-looking rock with a rope tied to it.", + "ids": "2273,2274" + }, + { + "examine": "An odd-looking rock formation.", + "ids": "2275,2276,2277,2278" + }, + { + "examine": "Holds the rope up. Hopefuly.", + "ids": "2279,2280,2281" + }, + { + "examine": "Use this to swing over crevices.", + "ids": "2282,2283" + }, + { + "examine": "This must be climbed over.", + "ids": "2284,2285,2286" + }, + { + "examine": "It's hollow...", + "ids": "2289" + }, + { + "examine": "A slippery log I can walk across.", + "ids": "2294,2295,2296,2297" + }, + { + "examine": "The irregular surface can be climbed.", + "ids": "2298,2299,2300" + }, + { + "examine": "Tread carefully!", + "ids": "2301,2302" + }, + { + "examine": "I can just about edge across here.", + "ids": "2303" + }, + { + "examine": "Pointy!", + "ids": "2304,2305,2306" + }, + { + "examine": "A wrought iron gate.", + "ids": "2307,2308" + }, + { + "examine": "Solid bars of iron.", + "ids": "2309" + }, + { + "examine": "This tree has been cut down.", + "ids": "2310" + }, + { + "examine": "I can jump from this stepping stone.", + "ids": "2311" + }, + { + "examine": "I can balance on this rope.", + "ids": "2312" + }, + { + "examine": "I can climb up this.", + "ids": "2313" + }, + { + "examine": "I can climb down here.", + "ids": "2314,2315" + }, + { + "examine": "I can climb up these stairs.", + "ids": "2316,36776" + }, + { + "examine": "I can climb up these rocks to another cave.", + "ids": "2317" + }, + { + "examine": "I can climb down these rocks to another cave.", + "ids": "2318" + }, + { + "examine": "I can traverse these.", + "ids": "2319,2320,2321,12573,12574,12575,29375" + }, + { + "examine": "Use this to swing across gaps.", + "ids": "2322,2323,2324" + }, + { + "examine": "I can swing on this tree.", + "ids": "2325" + }, + { + "examine": "A branch protrudes here.", + "ids": "2326" + }, + { + "examine": "This tree has an unusually long branch on it.", + "ids": "2327" + }, + { + "examine": "A rocky outcrop.", + "ids": "2328,2329,2330,2331" + }, + { + "examine": "A nearly rotten wooden log that crosses the river.", + "ids": "2332" + }, + { + "examine": "A rocky outcrop from the running water.", + "ids": "2333,2334,2335" + }, + { + "examine": "You can see a cauldron directly below.", + "ids": "2336" + }, + { + "examine": "This door is very sturdy looking.", + "ids": "2337" + }, + { + "examine": "This door is closed.", + "ids": "2338" + }, + { + "examine": "This door is very sturdy looking.", + "ids": "2339,2340" + }, + { + "examine": "There is something strange about this wall...", + "ids": "2341" + }, + { + "examine": "Looks like a ventilation grill.", + "ids": "2342" + }, + { + "examine": "A large stone block.", + "ids": "2343,2344,2345,2346,2347,2348,2349" + }, + { + "examine": "Used to move earth to, and from, the dig shaft.", + "ids": "2350,2351" + }, + { + "examine": "This leads back up the dig shaft.", + "ids": "2352,2353" + }, + { + "examine": "Yep, they're sacks!", + "ids": "2354,2355,2356" + }, + { + "examine": "A leafy bush.", + "ids": "2357,2358" + }, + { + "examine": "A sealed barrel with a warning sign on it.", + "ids": "2359" + }, + { + "examine": "I wonder what's inside...", + "ids": "2360" + }, + { + "examine": "A sturdy chest to keep things in.", + "ids": "2361" + }, + { + "examine": "A large stone block.", + "ids": "2362" + }, + { + "examine": "A place where you can pan for gold.", + "ids": "2363" + }, + { + "examine": "A wooden container.", + "ids": "2364,2365" + }, + { + "examine": "A signpost!", + "ids": "2366,2367,2368,2369,2370,2371" + }, + { + "examine": "Shelves filled with interesting books.", + "ids": "2372" + }, + { + "examine": "A cupboard.", + "ids": "2373,2374" + }, + { + "examine": "Used to keep specimens on.", + "ids": "2375" + }, + { + "examine": "Soil. Dug up!", + "ids": "2376,2377,2378" + }, + { + "examine": "Technically a bed.", + "ids": "2379" + }, + { + "examine": "I wonder what's inside...", + "ids": "2380" + }, + { + "examine": "Swampy dirt.", + "ids": "2381,2382,2383,2384,2385,2386,2387,2388,2389,2390" + }, + { + "examine": "A very solid looking gate.", + "ids": "2391,2392" + }, + { + "examine": "Aim for the goal!", + "ids": "2393" + }, + { + "examine": "A gate to the Gnomeball pitch.", + "ids": "2394,2395" + }, + { + "examine": "Distinctly feminine.", + "ids": "2396" + }, + { + "examine": "A solid looking door.", + "ids": "2397,2398,2399" + }, + { + "examine": "Might be worth searching.", + "ids": "2400,2401" + }, + { + "examine": "A good source of books!", + "ids": "2402" + }, + { + "examine": "Might be worth searching.", + "ids": "2403,2404" + }, + { + "examine": "I can climb this.", + "ids": "2405" + }, + { + "examine": "The door is closed.", + "ids": "2406,2407" + }, + { + "examine": "I can climb down this.", + "ids": "2408,36693,36694" + }, + { + "examine": "A commonly found tree.", + "ids": "2409" + }, + { + "examine": "I can climb this.", + "ids": "2410" + }, + { + "examine": "The door is closed.", + "ids": "2411" + }, + { + "examine": "Handy for boarding the ship.", + "ids": "2412,2413,2414,2415" + }, + { + "examine": "Pull me!", + "ids": "2416" + }, + { + "examine": "Place party drop items here.", + "ids": "2417,2418,2419,2420" + }, + { + "examine": "This lever is down.", + "ids": "2421" + }, + { + "examine": "This lever is up.", + "ids": "2422" + }, + { + "examine": "This lever is down.", + "ids": "2423" + }, + { + "examine": "This lever is up.", + "ids": "2424" + }, + { + "examine": "This lever is down.", + "ids": "2425" + }, + { + "examine": "This lever is up.", + "ids": "2426" + }, + { + "examine": "This door is closed by an unknown mechanism.", + "ids": "2427,2428,2429,2430,2431" + }, + { + "examine": "This gate is closed shut.", + "ids": "2432,2433" + }, + { + "examine": "This may be worth opening.", + "ids": "2434,2435" + }, + { + "examine": "I wonder what's inside.", + "ids": "2436,2437" + }, + { + "examine": "A wooden gate.", + "ids": "2438,2439" + }, + { + "examine": "Wonder what this pillar is for?", + "ids": "2440,2441,2442,2443" + }, + { + "examine": "I wonder what's under it?", + "ids": "2444,2445" + }, + { + "examine": "This leads to somewhere...but where?", + "ids": "2446" + }, + { + "examine": "I reckon I could climb that!", + "ids": "2447,2448" + }, + { + "examine": "Some magical rocks.", + "ids": "2449,2450" + }, + { + "examine": "There's something behind these roots.", + "ids": "2451,2452,2453,2454,2455,2456,2457,2458,2459,2460,2461,2462,2463,2464" + }, + { + "examine": "A portal from this mystical place.", + "ids": "2465,2466,2467,2468,2469,2470,2471,2472,2473,2474,2475,2476,2477" + }, + { + "examine": "A mysterious power emanates from this shrine.", + "ids": "2478,2479,2480,2481,2482,2483,2484,2485,2486,2487,2488,2489,2490" + }, + { + "examine": "The source of all Rune Stones.", + "ids": "2491" + }, + { + "examine": "A portal from this mystical place.", + "ids": "2492" + }, + { + "examine": "A part of an old temple.", + "ids": "2493,2494,2495,2496" + }, + { + "examine": "Unusual energy is gathered here.", + "ids": "2497,2498,2499,2500,2501,2502" + }, + { + "examine": "An old crumbled pillar.", + "ids": "2503,2504,2505,2506,2507" + }, + { + "examine": "Broken parts of an old temple.", + "ids": "2508,2509,2510" + }, + { + "examine": "This leads to the practice tower.", + "ids": "2511" + }, + { + "examine": "This leads back down to the guild.", + "ids": "2512" + }, + { + "examine": "I wonder if I can hit a bullseye?", + "ids": "2513" + }, + { + "examine": "The door to the Ranging Guild.", + "ids": "2514" + }, + { + "examine": "I hope it doesn't sink.", + "ids": "2515" + }, + { + "examine": "It's sinking!", + "ids": "2516" + }, + { + "examine": "Going up?", + "ids": "2517" + }, + { + "examine": "Typical shoddy workmanship.", + "ids": "2518" + }, + { + "examine": "Crates of packed fish.", + "ids": "2519" + }, + { + "examine": "It's used for loading and unloading fishing boats.", + "ids": "2520,2521" + }, + { + "examine": "It's a flight of stairs.", + "ids": "2522,2523" + }, + { + "examine": "I wonder what's inside?", + "ids": "2524" + }, + { + "examine": "It's open.", + "ids": "2525" + }, + { + "examine": "The door of a small prison.", + "ids": "2526,2527" + }, + { + "examine": "The door is closed.", + "ids": "2528" + }, + { + "examine": "A door.", + "ids": "2529" + }, + { + "examine": "Used for storage.", + "ids": "2530" + }, + { + "examine": "Looks like someone's tried digging here.", + "ids": "2531,2532" + }, + { + "examine": "A pile of what is hopefully mud.", + "ids": "2533" + }, + { + "examine": "There's black cross on the door.", + "ids": "2534" + }, + { + "examine": "The door is closed.", + "ids": "2535" + }, + { + "examine": "A door.", + "ids": "2536" + }, + { + "examine": "The door is closed.", + "ids": "2537" + }, + { + "examine": "A door.", + "ids": "2538" + }, + { + "examine": "A flight of stairs.", + "ids": "2539,2540" + }, + { + "examine": "An outlet to the sewer.", + "ids": "2541,2542" + }, + { + "examine": "There's a cover over this manhole.", + "ids": "2543" + }, + { + "examine": "How dangerous, someone has left this manhole open.", + "ids": "2544" + }, + { + "examine": "This is supposed to stop people falling down the manhole.", + "ids": "2545" + }, + { + "examine": "A door.", + "ids": "2546,2547,2548,2549" + }, + { + "examine": "A secure door.", + "ids": "2550,2551" + }, + { + "examine": "A metal gate bars your way.", + "ids": "2552,2553" + }, + { + "examine": "A secure door.", + "ids": "2554,2555,2556,2557,2558,2559" + }, + { + "examine": "Fine silk woven by experts.", + "ids": "2560" + }, + { + "examine": "This stall smells great.", + "ids": "2561" + }, + { + "examine": "Precious stones from around the world.", + "ids": "2562" + }, + { + "examine": "All manner of animal clothing.", + "ids": "2563" + }, + { + "examine": "Spices to tingle your taste buds.", + "ids": "2564" + }, + { + "examine": "Fine silver items are for sale here.", + "ids": "2565" + }, + { + "examine": "I wonder what's inside it.", + "ids": "2566,2567,2568,2569,2570,2571,2572,2573,2574" + }, + { + "examine": "A marshy jungle vine.", + "ids": "2575,2576" + }, + { + "examine": "A tall palm tree with some plants growing at its stem.", + "ids": "2577" + }, + { + "examine": "A tall palm tree.", + "ids": "2578" + }, + { + "examine": "The burnt ground has a plant growing on it.", + "ids": "2579" + }, + { + "examine": "The ground has been burnt here by a fire.", + "ids": "2580" + }, + { + "examine": "A rock with green moss growing on it.", + "ids": "2581" + }, + { + "examine": "A rock, it looks like something was growing here.", + "ids": "2582" + }, + { + "examine": "It looks as if it is covered in some fungus.", + "ids": "2583" + }, + { + "examine": "A collection of rocks over what looks like a depression.", + "ids": "2584" + }, + { + "examine": "Rocky walls, you may be able to climb it.", + "ids": "2585" + }, + { + "examine": "It's closed.", + "ids": "2586" + }, + { + "examine": "I wonder what's inside?", + "ids": "2587" + }, + { + "examine": "It's open.", + "ids": "2588" + }, + { + "examine": "This ship's not getting far with that.", + "ids": "2589" + }, + { + "examine": "Takes me into the ship.", + "ids": "2590,2591" + }, + { + "examine": "Takes me back on deck.", + "ids": "2592" + }, + { + "examine": "Handy for boarding the ship.", + "ids": "2593,2594" + }, + { + "examine": "It's closed.", + "ids": "2595" + }, + { + "examine": "A blood-red door.", + "ids": "2596" + }, + { + "examine": "A lurid orange door.", + "ids": "2597" + }, + { + "examine": "A sickly yellow door.", + "ids": "2598" + }, + { + "examine": "A gloomy blue door.", + "ids": "2599" + }, + { + "examine": "A groovy magenta door.", + "ids": "2600" + }, + { + "examine": "A putrid green door.", + "ids": "2601" + }, + { + "examine": "Probably the nicest door in this ghastly place.", + "ids": "2602" + }, + { + "examine": "It's closed.", + "ids": "2603" + }, + { + "examine": "It's open.", + "ids": "2604" + }, + { + "examine": "It's a ladder.", + "ids": "2605" + }, + { + "examine": "There is something strange about this wall...", + "ids": "2606" + }, + { + "examine": "It's closed.", + "ids": "2607,2608" + }, + { + "examine": "A collection of rocks over what looks like a depression.", + "ids": "2609" + }, + { + "examine": "A rope hangs here that I can climb.", + "ids": "2610" + }, + { + "examine": "It's a ladder.", + "ids": "2611" + }, + { + "examine": "Wonder what's in here...", + "ids": "2612" + }, + { + "examine": "Smells kind of funny...", + "ids": "2613" + }, + { + "examine": "Looks comfortable...", + "ids": "2615" + }, + { + "examine": "Looks spooky...", + "ids": "2616" + }, + { + "examine": "Phew, an exit!", + "ids": "2617" + }, + { + "examine": "The fence is broken at this point.", + "ids": "2618" + }, + { + "examine": "A wooden barrel for storage.", + "ids": "2619" + }, + { + "examine": "An old crate for storage.", + "ids": "2620" + }, + { + "examine": "It's a door.", + "ids": "2621,2622" + }, + { + "examine": "It's a gate.", + "ids": "2623" + }, + { + "examine": "The entrance to the Hero's Guild.", + "ids": "2624,2625" + }, + { + "examine": "It's a door.", + "ids": "2626,2627,2628" + }, + { + "examine": "There is something unusual about this wall...", + "ids": "2629" + }, + { + "examine": "I can see eels swimming in the lava.", + "ids": "2630" + }, + { + "examine": "It's a door.", + "ids": "2631" + }, + { + "examine": "I wonder what's inside?", + "ids": "2632" + }, + { + "examine": "It's open.", + "ids": "2633" + }, + { + "examine": "Rocks that contain nothing interesting, but block the way.", + "ids": "2634" + }, + { + "examine": "I wonder what's inside?", + "ids": "2635" + }, + { + "examine": "It's open.", + "ids": "2636,2637" + }, + { + "examine": "A source of pure water.", + "ids": "2638,2639" + }, + { + "examine": "A shrine for the faithful to worship at.", + "ids": "2640" + }, + { + "examine": "I can climb this.", + "ids": "2641" + }, + { + "examine": "Used for fashioning clay items.", + "ids": "2642" + }, + { + "examine": "Bake your clay items in here.", + "ids": "2643" + }, + { + "examine": "Used for spinning thread.", + "ids": "2644" + }, + { + "examine": "A tray of sand.", + "ids": "2645" + }, + { + "examine": "A plant cultivated for fibres.", + "ids": "2646" + }, + { + "examine": "The door to the Crafting Guild.", + "ids": "2647,2648,2649" + }, + { + "examine": "A pile of smelly rotting waste.", + "ids": "2650" + }, + { + "examine": "A sturdy home for bees.", + "ids": "2651" + }, + { + "examine": "Looks like this is where waste from the kitchen comes out.", + "ids": "2652" + }, + { + "examine": "It looks like a spiders' nest to me.", + "ids": "2653" + }, + { + "examine": "This fountain suits the garden.", + "ids": "2654" + }, + { + "examine": "It's the Sinclair Family coat of arms.", + "ids": "2655" + }, + { + "examine": "Looks like this is where Anna keeps her stuff.", + "ids": "2656" + }, + { + "examine": "Looks like this is where Bob keeps his stuff.", + "ids": "2657" + }, + { + "examine": "Looks like this is where Carol keeps her stuff.", + "ids": "2658" + }, + { + "examine": "Looks like this is where David keeps his stuff.", + "ids": "2659" + }, + { + "examine": "Looks like this is where Elizabeth keeps her stuff.", + "ids": "2660" + }, + { + "examine": "Looks like this is where Frank keeps his stuff.", + "ids": "2661" + }, + { + "examine": "Looks like this is where the cook stores flour.", + "ids": "2662" + }, + { + "examine": "Some sacks of general garden items.", + "ids": "2663" + }, + { + "examine": "Luckily it seems able to keep that vicious dog inside.", + "ids": "2664,2665" + }, + { + "examine": "Looks like the killer smashed this to leave the mansion.", + "ids": "2666" + }, + { + "examine": "Slaves are using this to pull up barrels of rocks from down below.", + "ids": "2667" + }, + { + "examine": "Slaves are placing barrels on this to haul them to the surface.", + "ids": "2668,2669" + }, + { + "examine": "A succulent cactus.", + "ids": "2670" + }, + { + "examine": "A less-than-succulent succulent.", + "ids": "2671" + }, + { + "examine": "I can try to make new items on this.", + "ids": "2672" + }, + { + "examine": "A solid looking gate.", + "ids": "2673,2674" + }, + { + "examine": "Large doors made of solid oak.", + "ids": "2675,2676" + }, + { + "examine": "A solid looking chest, it belongs to Captain Siad.", + "ids": "2677" + }, + { + "examine": "A selection of Captain Siad's Books.", + "ids": "2678" + }, + { + "examine": "A sturdy looking desk on which the Captain works.", + "ids": "2679" + }, + { + "examine": "A barrel containing rocks and mining debris.", + "ids": "2680" + }, + { + "examine": "An empty mining barrel.", + "ids": "2681" + }, + { + "examine": "The cart which takes barrels of rocks from the mining encampment to Al-Kharid.", + "ids": "2682" + }, + { + "examine": "Gives a lovely view of the desert, complete with metalic bars.", + "ids": "2683" + }, + { + "examine": "It seems to be used for moving rocks into and out of this area.", + "ids": "2684" + }, + { + "examine": "A solid looking gate.", + "ids": "2685,2686,2687,2688" + }, + { + "examine": "There's no getting around it, it's a fairly sturdy prison cell door.", + "ids": "2689" + }, + { + "examine": "Large solid, thick set oak doors", + "ids": "2690,2691" + }, + { + "examine": "It looks fairly sturdy.", + "ids": "2692" + }, + { + "examine": "This is used by Shantay and his men to take items to the bank on your behalf.", + "ids": "2693" + }, + { + "examine": "A rocky rock.", + "ids": "2694,2695,2696,2697" + }, + { + "examine": "A cave which has been mined out.", + "ids": "2698,2699" + }, + { + "examine": "The entrance to the tent.", + "ids": "2700,2701" + }, + { + "examine": "Tracks in the sand.", + "ids": "2702,2703" + }, + { + "examine": "Rocky!", + "ids": "2704" + }, + { + "examine": "It's a door.", + "ids": "2705" + }, + { + "examine": "A nicely fitted door.", + "ids": "2706" + }, + { + "examine": "A wooden crate for storage.", + "ids": "2707,2708" + }, + { + "examine": "I wonder what's inside?", + "ids": "2709" + }, + { + "examine": "It's open.", + "ids": "2710" + }, + { + "examine": "It's a flight of stairs.", + "ids": "2711" + }, + { + "examine": "The door is closed.", + "ids": "2712" + }, + { + "examine": "Grain goes in here.", + "ids": "2713,2714,2715,2716,2717" + }, + { + "examine": "These control the flow of grain from the hopper to the millstones.", + "ids": "2718,2719,2720,2721,2722" + }, + { + "examine": "A spicy meat kebab is cooking here.", + "ids": "2723" + }, + { + "examine": "A fire burns brightly here.", + "ids": "2724" + }, + { + "examine": "A grand old fireplace.", + "ids": "2725,2726" + }, + { + "examine": "Something is cooking nicely here.", + "ids": "2727" + }, + { + "examine": "Ideal for cooking on.", + "ids": "2728,2729,2730,2731,3039,9682,12102,36973,40110" + }, + { + "examine": "Hot!", + "ids": "2732,2733,2734,2735,2736,2737,2738,2739,2740,2741,2742,2743,2744,2745,2746,2747,2748,2749,2750,2751,2752,2753,2754,2755,2756,2757,2758,2759,2760,2761,2762,2763,2764,2765,2766,2767,2768,2769,2770,2771,2772,2773,2774,2775,2776,2777,2778,2779,2780" + }, + { + "examine": "A hot place for forging things in.", + "ids": "2781" + }, + { + "examine": "It says \"Property of Doric the dwarf.\" on the side.", + "ids": "2782" + }, + { + "examine": "Used for fashioning metal items.", + "ids": "2783" + }, + { + "examine": "Various implements for working with metal.", + "ids": "2784" + }, + { + "examine": "A hot place for forging things in.", + "ids": "2785" + }, + { + "examine": "An entrance to Gu'Tanoth.", + "ids": "2786,2787,2788,2789" + }, + { + "examine": "I wonder what's inside it.", + "ids": "2790" + }, + { + "examine": "A counter made from a stone block.", + "ids": "2791,2792,2876,3800,29356" + }, + { + "examine": "An ogre is selling cakes here.", + "ids": "2793" + }, + { + "examine": "A lever for activating something.", + "ids": "2794,2795" + }, + { + "examine": "This leads to the watchtower.", + "ids": "2796" + }, + { + "examine": "This leads downwards.", + "ids": "2797" + }, + { + "examine": "A leafy bush.", + "ids": "2798,2799,2800,2801,2802,2803" + }, + { + "examine": "I think I can squeeze through here...", + "ids": "2804,2805,2806,2807,2808,2809,2810,2811" + }, + { + "examine": "This leads downwards.", + "ids": "2812" + }, + { + "examine": "I think I can squeeze through here...", + "ids": "2813" + }, + { + "examine": "The gate has been locked shut.", + "ids": "2814,2815" + }, + { + "examine": "A strange looking rock...", + "ids": "2816" + }, + { + "examine": "I think I can get out here...", + "ids": "2817,2818,2819,2820,2821,2822" + }, + { + "examine": "A hole.", + "ids": "2823" + }, + { + "examine": "A hole", + "ids": "2824" + }, + { + "examine": "I hope this leads the way out.", + "ids": "2825" + }, + { + "examine": "I wonder what's inside it?", + "ids": "2826,2827,2828,2829" + }, + { + "examine": "You can probably jump over from here.", + "ids": "2830,2831" + }, + { + "examine": "A low wall is blocking your path.", + "ids": "2832" + }, + { + "examine": "This goes up!", + "ids": "2833" + }, + { + "examine": "A low wall is blocking your path.", + "ids": "2834" + }, + { + "examine": "Looks hard.", + "ids": "2835,2836,2837,2838,2839,2840,2841" + }, + { + "examine": "It has a special magical quality.", + "ids": "2842" + }, + { + "examine": "This drain leads from the sink to the sewers below.", + "ids": "2843" + }, + { + "examine": "This looks like it can be turned.", + "ids": "2844,2845,2846,2847,2848" + }, + { + "examine": "A rudimentary type of boat.", + "ids": "2849" + }, + { + "examine": "It's closed.", + "ids": "2850" + }, + { + "examine": "It's open.", + "ids": "2851" + }, + { + "examine": "I can probably squeeze my way inside there.", + "ids": "2852" + }, + { + "examine": "It's a flight of stairs.", + "ids": "2853" + }, + { + "examine": "Made of wood.", + "ids": "2854,2855" + }, + { + "examine": "I wonder what's inside?", + "ids": "2856" + }, + { + "examine": "It's open.", + "ids": "2857" + }, + { + "examine": "Used for storage.", + "ids": "2858" + }, + { + "examine": "A hot range, where some soup is bubbling nicely.", + "ids": "2859" + }, + { + "examine": "Very ominous.", + "ids": "2860" + }, + { + "examine": "It's a door.", + "ids": "2861,2862" + }, + { + "examine": "The door is closed.", + "ids": "2863" + }, + { + "examine": "A water feature.", + "ids": "2864" + }, + { + "examine": "It's a gate.", + "ids": "2865,2866" + }, + { + "examine": "Very decorative!", + "ids": "2867" + }, + { + "examine": "It's a cupboard.", + "ids": "2868,2869" + }, + { + "examine": "The mouse equivalent of a door.", + "ids": "2870" + }, + { + "examine": "I can climb down this.", + "ids": "2871" + }, + { + "examine": "I can climb this.", + "ids": "2872" + }, + { + "examine": "What a good likeness!", + "ids": "2873" + }, + { + "examine": "A depiction that chills one to the bone.", + "ids": "2874" + }, + { + "examine": "I wonder how accurate a representation this is.", + "ids": "2875" + }, + { + "examine": "A barrel full of staffs...", + "ids": "2877" + }, + { + "examine": "Patterns of light dance hypnotically across the pool's surface.", + "ids": "2878,2879" + }, + { + "examine": "There seems to be some sort of magical field here.", + "ids": "2880" + }, + { + "examine": "It's closed.", + "ids": "2881" + }, + { + "examine": "The toll gate from Lumbridge to Al-Kharid.", + "ids": "2882,2883" + }, + { + "examine": "I can climb this.", + "ids": "2884" + }, + { + "examine": "An antique by anyone's standards.", + "ids": "2885" + }, + { + "examine": "An antique by anyone's standards, however, it might have something interesting in it.", + "ids": "2886" + }, + { + "examine": "Looks good for logging.", + "ids": "2887" + }, + { + "examine": "A leafy jungle palm, dense foliage.", + "ids": "2888" + }, + { + "examine": "Home to many unusual creatures.", + "ids": "2889" + }, + { + "examine": "A leafy tree.", + "ids": "2890" + }, + { + "examine": "This tree has been cut down.", + "ids": "2891" + }, + { + "examine": "A jungle bush, quite common to these areas.", + "ids": "2892,2893" + }, + { + "examine": "A jungle bush that has been chopped down.", + "ids": "2894,2895" + }, + { + "examine": "A door to the Legends Guild.", + "ids": "2896,2897,2898,2899" + }, + { + "examine": "Looks slippery!", + "ids": "2900,2901" + }, + { + "examine": "Stoney!", + "ids": "2902" + }, + { + "examine": "A rather shadowy cavern entrance.", + "ids": "2903,2904" + }, + { + "examine": "An old crate for storage.", + "ids": "2905" + }, + { + "examine": "Useful for putting things on.", + "ids": "2906" + }, + { + "examine": "I guess I could sleep in it if I was really tired.", + "ids": "2907" + }, + { + "examine": "A wall of magic fire.", + "ids": "2908,2909" + }, + { + "examine": "Rickety bamboo tables that are lashed together to make a desk.", + "ids": "2910" + }, + { + "examine": "Bamboo storage!", + "ids": "2911" + }, + { + "examine": "This gate has a horribly complex locking mechanism.", + "ids": "2912,2913,2914,2915" + }, + { + "examine": "A dark cave entrance leading to the surface.", + "ids": "2916,2917" + }, + { + "examine": "A large crack in the wall.", + "ids": "2918" + }, + { + "examine": "A huge lump of rock.", + "ids": "2919,2920,2921" + }, + { + "examine": "A heavily constructed, cast-iron, ancient gateway.", + "ids": "2922,2923,2924,2925" + }, + { + "examine": "A high wall made up of rocks with sharp edges.", + "ids": "2926" + }, + { + "examine": "It looks like ancient graffiti.", + "ids": "2927" + }, + { + "examine": "An ornately carved rock with a pointed receptacle.", + "ids": "2928" + }, + { + "examine": "A half buried skeleton, probably dwarven remains.", + "ids": "2929" + }, + { + "examine": "A huge, strangely constructed doorway, not sure how this opens.", + "ids": "2930" + }, + { + "examine": "It looks like a magical portal of some kind, who knows where it leads?", + "ids": "2931" + }, + { + "examine": "Strangely, there's a locked barrel here, I wonder what's inside.", + "ids": "2932,2933" + }, + { + "examine": "A large scaffold platform most likely used for lifting and lowering heavy items.", + "ids": "2934" + }, + { + "examine": "Used to move earth to, and from, the dig shaft. A rope has been thrown over it.", + "ids": "2935" + }, + { + "examine": "A sculpted trunk of wood.", + "ids": "2936,2937,2938,2939" + }, + { + "examine": "A wonderfully dressed table.", + "ids": "2940" + }, + { + "examine": "Sparkling sacred water straight from the source.", + "ids": "2941" + }, + { + "examine": "A sparkling, babbling flow of water from an underground source.", + "ids": "2942" + }, + { + "examine": "Disgusting filthy quagmire that oozes from the ground.", + "ids": "2943" + }, + { + "examine": "Found near the water's edge.", + "ids": "2944" + }, + { + "examine": "A baby Yommi tree, it has a mystical aura.", + "ids": "2945" + }, + { + "examine": "An adolescent-looking Yommi tree, it has a mystical aura.", + "ids": "2946" + }, + { + "examine": "A dead Yommi tree sapling, you'll need a tough axe to remove this.", + "ids": "2947" + }, + { + "examine": "A fully grown Yommi tree, it won't get much taller than this.", + "ids": "2948" + }, + { + "examine": "A dead fully grown Yommi tree, you'll need a tough, sharp axe to remove this.", + "ids": "2949" + }, + { + "examine": "A felled adult Yommi tree, perhaps you should trim those branches?", + "ids": "2950" + }, + { + "examine": "A rotten felled Yommi tree, it was left too long in the damp jungle.", + "ids": "2951" + }, + { + "examine": "A trimmed Yommi tree log, perfect for sculpting into a totem pole.", + "ids": "2952" + }, + { + "examine": "A rotten Yommi tree log, it was left too long in the damp jungle air.", + "ids": "2953" + }, + { + "examine": "A beautifully crafted totem pole carved from the trunk of the sacred Yommi tree.", + "ids": "2954" + }, + { + "examine": "A rotten totem pole, it was left to rot in the jungle.", + "ids": "2955" + }, + { + "examine": "This earth is particularly fertile.", + "ids": "2956" + }, + { + "examine": "This earth is damaged by cultivation, time will restore the fertility.", + "ids": "2957" + }, + { + "examine": "A rope hangs here.", + "ids": "2958" + }, + { + "examine": "A dangerous path onwards.", + "ids": "2959,2960,2961" + }, + { + "examine": "Stoney!", + "ids": "2962,2963,2964" + }, + { + "examine": "Looks slippery!", + "ids": "2965" + }, + { + "examine": "A hot place for forging things in.", + "ids": "2966,2967,2968" + }, + { + "examine": "It looks like a strangely shaped depression in the rock.", + "ids": "2969" + }, + { + "examine": "This recess has a glowing heart shaped crystal in it.", + "ids": "2970" + }, + { + "examine": "This looks like some sort of shimmering surface.", + "ids": "2971" + }, + { + "examine": "A huge lump of rock.", + "ids": "2972,2973,2974" + }, + { + "examine": "This tree is particularly leafy.", + "ids": "2975,2976" + }, + { + "examine": "A large pile of sand", + "ids": "2977" + }, + { + "examine": "A medium pile of sand", + "ids": "2978" + }, + { + "examine": "A small pile of sand", + "ids": "2979" + }, + { + "examine": "Some beautiful flowers.", + "ids": "2980,2981,2982,2983,2984,2985,2986,2987,2988" + }, + { + "examine": "Known commonly as Red worm vine.", + "ids": "2989,2990,2991,2992,2993,2994" + }, + { + "examine": "I wonder what's inside.", + "ids": "2995,2996" + }, + { + "examine": "The door is closed.", + "ids": "2997" + }, + { + "examine": "The door is open.", + "ids": "2998,2999" + }, + { + "examine": "These obviously mean keep out!", + "ids": "3000,3001,3002,3003,3004,3005,3006,3007,3008,3009,3010,3011,3012,3013" + }, + { + "examine": "A nicely fitted door.", + "ids": "3014" + }, + { + "examine": "A wooden gate.", + "ids": "3015,3016" + }, + { + "examine": "A nicely fitted door.", + "ids": "3017,3018,3019" + }, + { + "examine": "A wrought iron gate.", + "ids": "3020,3021,3022,3023" + }, + { + "examine": "A closed door.", + "ids": "3024,3025,3026,3027" + }, + { + "examine": "I can climb this.", + "ids": "3028" + }, + { + "examine": "I can climb down this.", + "ids": "3029" + }, + { + "examine": "I can climb this.", + "ids": "3030" + }, + { + "examine": "I can climb down this.", + "ids": "3031" + }, + { + "examine": "I can see fish swimming in the water.", + "ids": "3032" + }, + { + "examine": "One of the most common trees in 2009Scape.", + "ids": "3033,3034,3035,3036" + }, + { + "examine": "A beautiful old oak.", + "ids": "3037" + }, + { + "examine": "Hot!", + "ids": "3038" + }, + { + "examine": "It's closed.", + "ids": "3040" + }, + { + "examine": "It's open.", + "ids": "3041" + }, + { + "examine": "A rocky outcrop.", + "ids": "3042,3043" + }, + { + "examine": "A hot place for forging things in.", + "ids": "3044" + }, + { + "examine": "The bank teller will serve you from here.", + "ids": "3045" + }, + { + "examine": "These obviously mean keep out!", + "ids": "3046,3047,3048,3049,3050,3051,3052,3053,3054,3055,3056,3057,3058,3059,3060,3061,3062,3063,3064,3065,3066,3067,3068,3069,3070,3071,3072,3073,3074,3075,3076" + }, + { + "examine": "Lean against the wall to get a better view!", + "ids": "3077,3078,3079,3080,3081,3082,3083,3084,3085,3086,3087,3088,3089,3090,3091,3092,3093,3094,3095,3096,3097,3098,3099,3100,3101,3102,3103,3104,3105,3106,3107" + }, + { + "examine": "Flags marking the entrance to the arena.", + "ids": "3108,3109,3110,3111,3112,3113,3114,3115,3116,3117,3118,3119,3120,3121,3122,3123,3124,3125,3126,3127,3128,3129,3130,3131,3132,3133,3134,3135,3136,3137,3138,3139,3140,3141,3142,3143,3144,3145,3146,3147,3148,3149,3150,3151,3152,3153,3154,3155,3156,3157,3158" + }, + { + "examine": "Beats the operating table.", + "ids": "3159,3160,3161,3162,3163,3164,3165,3166,3167,3168,3169,3170,3171,3172,3173,3174,3175,3176,3177,3178,3179,3180,3181" + }, + { + "examine": "Wait here for a nurse.", + "ids": "3182" + }, + { + "examine": "Storage for drugs and bandages.", + "ids": "3183,3184,3185" + }, + { + "examine": "I don't really want to end up here...", + "ids": "3186,3187,3188,3189" + }, + { + "examine": "These open and close!", + "ids": "3190" + }, + { + "examine": "This may be worth searching.", + "ids": "3191" + }, + { + "examine": "You can see the last 50 fights on here.", + "ids": "3192" + }, + { + "examine": "Used to store players' items whilst they duel.", + "ids": "3193" + }, + { + "examine": "Use for quick access to your bank.", + "ids": "3194" + }, + { + "examine": "Smells pretty bad!", + "ids": "3195" + }, + { + "examine": "Not much use for anything except scrap.", + "ids": "3196" + }, + { + "examine": "Entrance to the Duel Arena.", + "ids": "3197,3198" + }, + { + "examine": "A wooden double bed.", + "ids": "3199,3200,3201,3202" + }, + { + "examine": "Access to the duel arena.", + "ids": "3203,3204" + }, + { + "examine": "I can climb down this.", + "ids": "3205" + }, + { + "examine": "A barrel full of staffs...", + "ids": "3206,3207,3208" + }, + { + "examine": "A strange crack cuts into the wall.", + "ids": "3209,3210,3211,3212,29360,29362" + }, + { + "examine": "It looks like I can squeeze through here.", + "ids": "3213" + }, + { + "examine": "The easy way out...", + "ids": "3214,3215" + }, + { + "examine": "A pile of mud.", + "ids": "3216" + }, + { + "examine": "I can go through here.", + "ids": "3217" + }, + { + "examine": "Dark and intimidating.", + "ids": "3218,3219" + }, + { + "examine": "That skull's looking at me....", + "ids": "3220,3221" + }, + { + "examine": "I can climb down these.", + "ids": "3222" + }, + { + "examine": "I can climb up these.", + "ids": "3223" + }, + { + "examine": "I can go through here.", + "ids": "3224,3225,3226" + }, + { + "examine": "Best not to get caught!", + "ids": "3227" + }, + { + "examine": "Best avoided.", + "ids": "3228,3229" + }, + { + "examine": "Looks suspicious.", + "ids": "3230" + }, + { + "examine": "A plank.", + "ids": "3231" + }, + { + "examine": "Formed over many years.", + "ids": "3232" + }, + { + "examine": "Best avoided.", + "ids": "3233" + }, + { + "examine": "Looks suspicious.", + "ids": "3234" + }, + { + "examine": "I can open the grill from this side.", + "ids": "3235" + }, + { + "examine": "Maybe I can cross that.", + "ids": "3238" + }, + { + "examine": "It looks like only the guide ropes are holding the bridge up.", + "ids": "3239" + }, + { + "examine": "A bridge.", + "ids": "3240" + }, + { + "examine": "This lever can be operated.", + "ids": "3241,3242" + }, + { + "examine": "The base of a platform.", + "ids": "3243,3244,3245,3246" + }, + { + "examine": "A bridge.", + "ids": "3247,3248,3249,3250,3251,3252,3253" + }, + { + "examine": "I can't get past that very easily...", + "ids": "3254,3255,3256" + }, + { + "examine": "A platform.", + "ids": "3257" + }, + { + "examine": "A bridge.", + "ids": "3258,3259,3260,3261,3262" + }, + { + "examine": "This area may not be safe...", + "ids": "3263" + }, + { + "examine": "A well of nastiness.", + "ids": "3264" + }, + { + "examine": "I can climb this pile of rocks...", + "ids": "3265" + }, + { + "examine": "Usually used for storing living things...", + "ids": "3266,3267,3268,3269" + }, + { + "examine": "The door is closed.", + "ids": "3270" + }, + { + "examine": "The door is open.", + "ids": "3271" + }, + { + "examine": "I wonder what's inside.", + "ids": "3272,3273,3274,3275" + }, + { + "examine": "A stone bridge.", + "ids": "3276,3277,3278,3279,3280,3281,3282,3283,3284,3285,3286,3287,3288,3289,3290,3291,3292,3293" + }, + { + "examine": "A hot place for forging things in.", + "ids": "3294" + }, + { + "examine": "It's covered in strange writing.", + "ids": "3295,3296,3297,3298,3299,3300,3301,3302" + }, + { + "examine": "You won't be able to lift that.", + "ids": "3303" + }, + { + "examine": "A portcullis.", + "ids": "3304" + }, + { + "examine": "It doesn't look like water in there...", + "ids": "3305,3306" + }, + { + "examine": "A pile of rocks.", + "ids": "3307" + }, + { + "examine": "The boulder has smashed through the cage.", + "ids": "3308" + }, + { + "examine": "A deposit of rocks.", + "ids": "3309,3310,3311,3312,3313,3314,3315,3316,3317,3318,3319,3320,3321,3322,3323,3324,3325,3326" + }, + { + "examine": "Intimidating!", + "ids": "3327" + }, + { + "examine": "A depiction of a great dwarf miner.", + "ids": "3328,3329,3330,3331" + }, + { + "examine": "A temple door.", + "ids": "3332" + }, + { + "examine": "A very big door.", + "ids": "3333,3334,3335,3336" + }, + { + "examine": "This lever can be operated.", + "ids": "3337" + }, + { + "examine": "Why would a log be hung up there?", + "ids": "3338" + }, + { + "examine": "Looks suspicious.", + "ids": "3339" + }, + { + "examine": "Looks like the rope is holding the bridge up.", + "ids": "3340" + }, + { + "examine": "Looks like the other rope is holding the bridge up.", + "ids": "3341,3342" + }, + { + "examine": "A pile of rocks.", + "ids": "3343" + }, + { + "examine": "It's got dwarf brew in it.", + "ids": "3344,3345,3346,3347" + }, + { + "examine": "Lord Iban's Throne.", + "ids": "3348,3349,3350" + }, + { + "examine": "I'm glad I'm on this side of those bars.", + "ids": "3351,3352" + }, + { + "examine": "I don't much like the look of that...", + "ids": "3353,3354,3355,3356,3357,3358" + }, + { + "examine": "Well of the damned.", + "ids": "3359" + }, + { + "examine": "A wooden crate for storage.", + "ids": "3360" + }, + { + "examine": "A magical sphere that glimmers within.", + "ids": "3361" + }, + { + "examine": "A window.", + "ids": "3362,3363" + }, + { + "examine": "An odd looking rock formation.", + "ids": "3364" + }, + { + "examine": "Looks like I can climb these.", + "ids": "3365" + }, + { + "examine": "Makes you cry.", + "ids": "3366" + }, + { + "examine": "Steel bars that are locked securely.", + "ids": "3367,3368,3369,3370" + }, + { + "examine": "An Achey tree stump.", + "ids": "3371" + }, + { + "examine": "Useful for ogre dinners.", + "ids": "3372,3373,3374,3375" + }, + { + "examine": "An ogre bench, useful for taking all that weight off their legs.", + "ids": "3376" + }, + { + "examine": "Hmmm, a rock for a lock....", + "ids": "3377" + }, + { + "examine": "Some stealthy thief must have picked the ogre lock!", + "ids": "3378" + }, + { + "examine": "The entrance to Rantz's cave", + "ids": "3379" + }, + { + "examine": "Exit this way for fresh air and daylight.", + "ids": "3380,3381" + }, + { + "examine": "Useful for ogre dinners.", + "ids": "3382,3383,3384,3385,3386,3387,3388" + }, + { + "examine": "A good source of books!", + "ids": "3389" + }, + { + "examine": "A strange crack cuts into the wall.", + "ids": "3390,3391,3392,3393" + }, + { + "examine": "A wooden crate for storage.", + "ids": "3394,3395" + }, + { + "examine": "A pile of boxes for storage.", + "ids": "3396,3397" + }, + { + "examine": "A wooden crate for storage.", + "ids": "3398,3399,3400,3401" + }, + { + "examine": "Used for fashioning metal items.", + "ids": "3402" + }, + { + "examine": "A pile of Elemental rock.", + "ids": "3403" + }, + { + "examine": "A valve to start and stop the flow of water.", + "ids": "3404,3405" + }, + { + "examine": "This lever can be operated.", + "ids": "3406" + }, + { + "examine": "It spins.", + "ids": "3407,3408" + }, + { + "examine": "This lever can be operated.", + "ids": "3409" + }, + { + "examine": "Big bellows.", + "ids": "3410,3411,3412" + }, + { + "examine": "A furnace with an air blast pipe.", + "ids": "3413" + }, + { + "examine": "A small trough full of lava.", + "ids": "3414" + }, + { + "examine": "I can climb down these stairs.", + "ids": "3415" + }, + { + "examine": "I can climb up these stairs.", + "ids": "3416" + }, + { + "examine": "This lever can be operated.", + "ids": "3417,3418,3419,3420,3421,3422,3423,3424,3425,3426,3427,3428" + }, + { + "examine": "Water powered machinery.", + "ids": "3429,3430" + }, + { + "examine": "Stoney!", + "ids": "3431" + }, + { + "examine": "I wonder what's under it?", + "ids": "3432" + }, + { + "examine": "I can see a holy barrier at the bottom.", + "ids": "3433,3434,3435,3436,3437,3438,3439" + }, + { + "examine": "They let you walk up them!", + "ids": "3440" + }, + { + "examine": "They let you walk down them!", + "ids": "3441,3442" + }, + { + "examine": "A holy barrier blocking evil forces.", + "ids": "3443" + }, + { + "examine": "A sturdy metal gate.", + "ids": "3444,3445,3446,3447,3448,3449,3450,3451,3452,3453,3454,3455,3456,3457,3458,3459,3460,3461,3462" + }, + { + "examine": "A hastily constructed yet sturdy prison door.", + "ids": "3463,3464,3465" + }, + { + "examine": "Dead animal parts dangling!", + "ids": "3466" + }, + { + "examine": "So how long has this been dead, then?", + "ids": "3467,3468,3469,3470,3471,3472,3473,3474,3475,3476,3477,3478" + }, + { + "examine": "A statue honouring Saradomin.", + "ids": "3479" + }, + { + "examine": "An ornately decorated coffin. Something seems to be alive inside.", + "ids": "3480,3481,3482,3483,3484" + }, + { + "examine": "An ornately carved well that draws water from the river Salve.", + "ids": "3485,3486,3487,3488" + }, + { + "examine": "Sturdy looking door.", + "ids": "3489,3490,3491,3492" + }, + { + "examine": "A monument to a fallen priest.", + "ids": "3493,3494,3495,3496,3497,3498,3499" + }, + { + "examine": "With skill I can play this.", + "ids": "3500,3501,3502,3503,3504,3505" + }, + { + "examine": "A wrought iron gate.", + "ids": "3506,3507" + }, + { + "examine": "Not sure if I should sit on that.", + "ids": "3508,3509" + }, + { + "examine": "Not sure if that's any use.", + "ids": "3510,3511" + }, + { + "examine": "It'll probably die soon.", + "ids": "3512,3513" + }, + { + "examine": "Not sure if I should stand under that.", + "ids": "3514,3515" + }, + { + "examine": "A dark dank entrance to below.", + "ids": "3516" + }, + { + "examine": "A large tree thriving where trees normally die.", + "ids": "3517,3518,3519" + }, + { + "examine": "Special grotto area.", + "ids": "3520" + }, + { + "examine": "A grotto transformed into an altar of nature.", + "ids": "3521" + }, + { + "examine": "It's a bridge.", + "ids": "3522" + }, + { + "examine": "An old bench, probably made from wood in this swamp.", + "ids": "3523,3524" + }, + { + "examine": "The door.", + "ids": "3525" + }, + { + "examine": "The green door.", + "ids": "3526" + }, + { + "examine": "A roughly hewn stone with some sort of symbol on it.", + "ids": "3527,3528,3529,3530,3531,3532,3533,3534,3535,3536,3537,3538,3539,3540,3541,3542,3543,3544,3545" + }, + { + "examine": "There is a rope leading to the bottom of this well.", + "ids": "3546,3547,3548,3549,3550" + }, + { + "examine": "I can balance on this rope.", + "ids": "3551,3552" + }, + { + "examine": "I can balance on this log.", + "ids": "3553,3554,3555,3556,3557,3558" + }, + { + "examine": "Tread carefully!", + "ids": "3559,3560,3561,3562" + }, + { + "examine": "Now, I'm the king of the swingers, oh, the jungle VIP.", + "ids": "3563,3564" + }, + { + "examine": "It looks like I can clamber over this.", + "ids": "3565" + }, + { + "examine": "Use this to swing over to the next platform.", + "ids": "3566" + }, + { + "examine": "I might want to avoid this nasty blade.", + "ids": "3567,3568,3569" + }, + { + "examine": "Walk the plank! Ya land lubber!", + "ids": "3570,3571,3572,3573,3574,3575,3576,3577" + }, + { + "examine": "It's a small step for a player, a giant leap for player kind.", + "ids": "3578,3579" + }, + { + "examine": "Makes sliced human.", + "ids": "3580" + }, + { + "examine": "Releases a ticket when the flashing arrow is above it.", + "ids": "3581" + }, + { + "examine": "Makes human colanders.", + "ids": "3582" + }, + { + "examine": "I can use these to climb across to the other side.", + "ids": "3583,3584" + }, + { + "examine": "Looks suspiciously like a pressure pad to me.", + "ids": "3585,3586,3587,3588,3589,3590,3591,3592,3593,3594,3595,3596,3597,3598,3599,3600,3601,3602,3603,3604,3605,3606,3607" + }, + { + "examine": "Releases a ticket when the flashing arrow is above it.", + "ids": "3608,3609" + }, + { + "examine": "I can use this rope to climb back to the top.", + "ids": "3610,3611,3612,3613,3614,3615,3616" + }, + { + "examine": "Leads down into the Agility Arena.", + "ids": "3617" + }, + { + "examine": "Leads back to Brimhaven.", + "ids": "3618,3619,3620,3621,3622,3623,3624,3625" + }, + { + "examine": "It looks very sturdy.", + "ids": "3626,3627,3628,3629,3630,3631,3632,3633" + }, + { + "examine": "A shrine of the gods!", + "ids": "3634" + }, + { + "examine": "I wonder what's inside...", + "ids": "3635" + }, + { + "examine": "It looks empty.", + "ids": "3636,3637,3638,3639,3640,3641,3642,3643" + }, + { + "examine": "That's really bright!", + "ids": "3644,3645,3646,3647,3648,3649,3650,3651,3652,3653,3654,3655,3656,3657,3658,3659,3660,3661" + }, + { + "examine": "Smells more like \"innocent villager\" stew to me...", + "ids": "3662,3663,3664" + }, + { + "examine": "Troll leftovers...", + "ids": "3665,3666,3667,3668,3669,3670,3671,3672,3673,3674,3675" + }, + { + "examine": "A stone mechanism that unlocks the equipment room.", + "ids": "3676,3677,3678" + }, + { + "examine": "A standard of Asgarnia.", + "ids": "3679" + }, + { + "examine": "The flag of Asgarnia.", + "ids": "3680" + }, + { + "examine": "Town of Burthorpe", + "ids": "3681,3682,3683,3684" + }, + { + "examine": "A pile of boxes for storage.", + "ids": "3685,3686,3687,3688,3689,3690,3691" + }, + { + "examine": "Some of the Sherpa's climbing rope.", + "ids": "3692,3693" + }, + { + "examine": "Looks like the Imperial Guard's supply of Dual Claws.", + "ids": "3694,3695" + }, + { + "examine": "The Imperial Guard's ceremonial armour.", + "ids": "3696" + }, + { + "examine": "A barrel full of swords...", + "ids": "3697,3698,3699,3700,3701,3702,3703,3704,3705,3706,3707,3708,3709,3710,3711,3712,3713,3714,3715,3716,3717,3718,3719,3720,3721" + }, + { + "examine": "A rocky outcrop.", + "ids": "3722,3723,3724" + }, + { + "examine": "A wooden gate.", + "ids": "3725,3726,3727,3728,3729" + }, + { + "examine": "I can climb over the fence with this.", + "ids": "3730,3731,3732,3733,3734" + }, + { + "examine": "Looks like a small cave.", + "ids": "3735" + }, + { + "examine": "The exit to the outside.", + "ids": "3736,3737,3738,3739,3740" + }, + { + "examine": "No solicitors!", + "ids": "3741" + }, + { + "examine": "Danger", + "ids": "3742" + }, + { + "examine": "A sturdy wooden door.", + "ids": "3743,3744" + }, + { + "examine": "The door is closed.", + "ids": "3745,3746" + }, + { + "examine": "A nicely fitted door.", + "ids": "3747" + }, + { + "examine": "A rocky outcrop.", + "ids": "3748,3749,3750,3751" + }, + { + "examine": "Unusual energy is gathered here.", + "ids": "3752,3753,3754,3755,3756" + }, + { + "examine": "Looks like a small cave.", + "ids": "3757" + }, + { + "examine": "The way out.", + "ids": "3758" + }, + { + "examine": "Looks like a small cave.", + "ids": "3759" + }, + { + "examine": "The way out.", + "ids": "3760" + }, + { + "examine": "The back way out.", + "ids": "3761" + }, + { + "examine": "The back way into the stronghold.", + "ids": "3762" + }, + { + "examine": "The door is closed.", + "ids": "3763" + }, + { + "examine": "The door is open.", + "ids": "3764" + }, + { + "examine": "The door to Mad Eadgar's cell.", + "ids": "3765,3766" + }, + { + "examine": "The door to Godric's cell.", + "ids": "3767,3768" + }, + { + "examine": "Hot!", + "ids": "3769" + }, + { + "examine": "This window looks down onto the Troll Camp.", + "ids": "3770" + }, + { + "examine": "The entrance to the Troll Stronghold.", + "ids": "3771" + }, + { + "examine": "The way out of the Troll Stronghold.", + "ids": "3772,3773,3774" + }, + { + "examine": "Looks like stew of some kind...", + "ids": "3775" + }, + { + "examine": "A door in the Stronghold.", + "ids": "3776,3777,3778,3779" + }, + { + "examine": "The door to the prison.", + "ids": "3780,3781" + }, + { + "examine": "The entrance to the Troll Arena.", + "ids": "3782,3783,3784" + }, + { + "examine": "The exit to the Troll Arena.", + "ids": "3785,3786,3787" + }, + { + "examine": "I can climb these stairs.", + "ids": "3788" + }, + { + "examine": "They go down.", + "ids": "3789" + }, + { + "examine": "A rocky outcrop.", + "ids": "3790,3791,3792,3793" + }, + { + "examine": "Looks tasty! If you're a goat, that is.", + "ids": "3794,3795,3796" + }, + { + "examine": "Not so good for sitting on.", + "ids": "3802" + }, + { + "examine": "A rocky outcrop.", + "ids": "3803,3804" + }, + { + "examine": "They don't seem to roll.", + "ids": "3805" + }, + { + "examine": "They're troll eggs. Or perhaps rocks.", + "ids": "3806" + }, + { + "examine": "These make great pets.", + "ids": "3807" + }, + { + "examine": "It's a troll! Run! No, wait, it's just a rock.", + "ids": "3808,3809" + }, + { + "examine": "The door to the storeroom.", + "ids": "3810,3811,3812" + }, + { + "examine": "It probably hasn't got anything interesting inside.", + "ids": "3813" + }, + { + "examine": "They probably haven't got anything interesting inside.", + "ids": "3814,3815" + }, + { + "examine": "They're closed.", + "ids": "3816" + }, + { + "examine": "They're open.", + "ids": "3817,3818,3819" + }, + { + "examine": "It doesn't contain anything particularly appetising.", + "ids": "3820" + }, + { + "examine": "Makes you taller.", + "ids": "3821" + }, + { + "examine": "It's full of dried goutweed.", + "ids": "3822" + }, + { + "examine": "Welcome to Mad Eadgar's! If I'm not in, I've probably been captured again.", + "ids": "3823" + }, + { + "examine": "I don't want to look too closely at what's cooking in there...", + "ids": "3824" + }, + { + "examine": "A limestone ceiling growth.", + "ids": "3825" + }, + { + "examine": "A tooth shaped rock formation protruding from the floor.", + "ids": "3826" + }, + { + "examine": "How am I going to get down there?", + "ids": "3827,3828" + }, + { + "examine": "I hope this holds!", + "ids": "3829" + }, + { + "examine": "How am I going to get down there?", + "ids": "3830,3831" + }, + { + "examine": "I hope this holds!", + "ids": "3832" + }, + { + "examine": "It's moving...", + "ids": "3833,3834,3835,3836,3837,3838,3839,3840,3841,3842,3843,3844,3845,3846,3847,3848,3849,3850,3851,3852,3853,3854,3855" + }, + { + "examine": "It's a half buried crate.", + "ids": "3856,3857" + }, + { + "examine": "It's stuck in the sand.", + "ids": "3858,3859" + }, + { + "examine": "It's full of brightly coloured fish.", + "ids": "3860,3861" + }, + { + "examine": "It's a pile of burning bones.", + "ids": "3862" + }, + { + "examine": "The tribal statue of Tai Bwo Wannai Village.", + "ids": "3863,3864,3865,3866,3867,3868,3869,3870,3871,3872,3873,3874,3875,3876,3877,3878" + }, + { + "examine": "A tree.", + "ids": "3879" + }, + { + "examine": "It's a tree stump.", + "ids": "3880" + }, + { + "examine": "A tree.", + "ids": "3881,3882,3883" + }, + { + "examine": "It's a tree stump.", + "ids": "3884" + }, + { + "examine": "A tree.", + "ids": "3885,3886,3887,3888,3889,3890,3891,3892,3893,3894,3895,3896,3897,3898,3899,3900" + }, + { + "examine": "A rare flower.", + "ids": "3901" + }, + { + "examine": "Don't flowers make you feel better?", + "ids": "3902" + }, + { + "examine": "A rare flower.", + "ids": "3903" + }, + { + "examine": "Don't flowers make you feel better?", + "ids": "3904" + }, + { + "examine": "A rare flower.", + "ids": "3905" + }, + { + "examine": "Don't flowers make you feel better?", + "ids": "3906,3907,3908,3909,3910,3911" + }, + { + "examine": "Fungal growth.", + "ids": "3912" + }, + { + "examine": "Poisonous no doubt.", + "ids": "3913,3914" + }, + { + "examine": "Fungal growth.", + "ids": "3915" + }, + { + "examine": "Poisonous no doubt.", + "ids": "3916,3917" + }, + { + "examine": "The lamp has a glowing crystal at its core.", + "ids": "3918" + }, + { + "examine": "It's a trap!", + "ids": "3919,3920" + }, + { + "examine": "A tripwire.", + "ids": "3921" + }, + { + "examine": "An odd-looking group of tied sticks.", + "ids": "3922" + }, + { + "examine": "A pile of leaves.", + "ids": "3923,3924,3925,3926" + }, + { + "examine": "Looks like I can climb these.", + "ids": "3927" + }, + { + "examine": "It's a tree.", + "ids": "3928" + }, + { + "examine": "I can balance on this log.", + "ids": "3929,3930,3931,3932,3933,3934,3935,3936" + }, + { + "examine": "There are some broken twigs here.", + "ids": "3937" + }, + { + "examine": "It looks as if the grass here has been flattened.", + "ids": "3938" + }, + { + "examine": "You notice the leaf litter here has been disturbed.", + "ids": "3939,3940" + }, + { + "examine": "Tracks in the soil.", + "ids": "3941,3942,3943" + }, + { + "examine": "You'd need a big siege engine to force that.", + "ids": "3944,3945,3946,3947,3948,3949,3950,3951,3952,3953,3954,3955,3956,3957,3958,3959,3960,3961" + }, + { + "examine": "A yellow crystal structure.", + "ids": "3962,3963,3964,3965,3966" + }, + { + "examine": "A tree", + "ids": "3967,3968" + }, + { + "examine": "Disturbing but tidy.", + "ids": "3969" + }, + { + "examine": "I don't even want to think about what did that...", + "ids": "3970" + }, + { + "examine": "I don't wanna fall in that!", + "ids": "3975" + }, + { + "examine": "Good for smashing city walls.", + "ids": "3976" + }, + { + "examine": "There's a winch on this side.", + "ids": "3977" + }, + { + "examine": "There's a lever on this side.", + "ids": "3978,3979" + }, + { + "examine": "A way to get into the tent.", + "ids": "3980,3981,3982" + }, + { + "examine": "A tent.", + "ids": "3983,3984,3985,3986" + }, + { + "examine": "A small barrel.", + "ids": "3987,3988,3989,3990,3991" + }, + { + "examine": "A standard of Kandarin.", + "ids": "3992,3993" + }, + { + "examine": "A small furnace.", + "ids": "3994" + }, + { + "examine": "A tent wall.", + "ids": "3995" + }, + { + "examine": "A way to get into the tent.", + "ids": "3996" + }, + { + "examine": "A tent wall.", + "ids": "3997" + }, + { + "examine": "It looks as if the grass here has been flattened.", + "ids": "3998" + }, + { + "examine": "There are some broken twigs here.", + "ids": "3999" + }, + { + "examine": "A tent roof.", + "ids": "4000" + }, + { + "examine": "A tent wall.", + "ids": "4001" + }, + { + "examine": "The charred remains of a tent pole.", + "ids": "4002,4003" + }, + { + "examine": "Well of voyage.", + "ids": "4004,4005" + }, + { + "examine": "It looks like I can squeeze through here.", + "ids": "4006" + }, + { + "examine": "The exit to the outside.", + "ids": "4007" + }, + { + "examine": "Shrine to the glory of Saradomin.", + "ids": "4008,4009,4010,4011,4012,4013,4014,4015,4016,4017,4018,4019,4020,4021,4022,4023" + }, + { + "examine": "A barrel.", + "ids": "4024,4025" + }, + { + "examine": "A still for fractionalizing oils.", + "ids": "4026" + }, + { + "examine": "A pile of lime rock.", + "ids": "4027,4028,4029,4030" + }, + { + "examine": "Looks like a stone doorway to me.", + "ids": "4031,4032,4033,4034" + }, + { + "examine": "These clean Druid's robes are drying off.", + "ids": "4035,4036,4037,4038" + }, + { + "examine": "It's full of dirty robes.", + "ids": "4039,4040,4041,4042" + }, + { + "examine": "Presumably the hatch the zookeeper feeds the parrots through.", + "ids": "4043" + }, + { + "examine": "A red standard.", + "ids": "4044,4045,4046,4047" + }, + { + "examine": "It doesn't look healthy...", + "ids": "4051" + }, + { + "examine": "It's covered in slime.", + "ids": "4052" + }, + { + "examine": "It doesn't look healthy...", + "ids": "4053,4054" + }, + { + "examine": "These fat fungi take up so much room.", + "ids": "4055,4056,4057" + }, + { + "examine": "I can balance on this rope.", + "ids": "4059" + }, + { + "examine": "It's hollow...", + "ids": "4060" + }, + { + "examine": "This tree has been cut down.", + "ids": "4061" + }, + { + "examine": "Strange items are stored here.", + "ids": "4062" + }, + { + "examine": "This table has seen better days.", + "ids": "4064" + }, + { + "examine": "It looks very ornamental in a practical 'solid rock' way.", + "ids": "4065" + }, + { + "examine": "Welcome to Mort'ton", + "ids": "4066" + }, + { + "examine": "Danger! Sickness and affliction... stay away!", + "ids": "4067" + }, + { + "examine": "Looks like a pile of ancient rubble.", + "ids": "4068" + }, + { + "examine": "The starting of a wall.", + "ids": "4069,4070,4071,4072,4073,4074,4075,4076" + }, + { + "examine": "It's nearly a wall.", + "ids": "4077" + }, + { + "examine": "A rebuilt wall.", + "ids": "4078" + }, + { + "examine": "The broken wall of a desecrated temple.", + "ids": "4079" + }, + { + "examine": "The partially repaired wall of a desecrated temple.", + "ids": "4080,4081,4082,4083,4084,4085,4086,4087" + }, + { + "examine": "The nearly repaired wall of a desecrated temple.", + "ids": "4088" + }, + { + "examine": "The repaired wall of a temple.", + "ids": "4089" + }, + { + "examine": "A flaming Fire altar.", + "ids": "4090" + }, + { + "examine": "An ancient Fire altar.", + "ids": "4091" + }, + { + "examine": "An ancient, totally desecrated, broken down fire altar.", + "ids": "4092" + }, + { + "examine": "A place to cremate the dead. Needs some wood.", + "ids": "4093" + }, + { + "examine": "A place to cremate the dead. Needs a body.", + "ids": "4094,4095,4096,4097,4098,4099" + }, + { + "examine": "A place to cremate the dead. Needs a light.", + "ids": "4100,4101,4102,4103,4104,4105" + }, + { + "examine": "Heavy metal!", + "ids": "4106,4107,4108,4109,4110" + }, + { + "examine": "A strangely decorated bronze chest, the lock is painted blood red.", + "ids": "4111" + }, + { + "examine": "A strangely decorated chest, the lock is painted brown.", + "ids": "4112" + }, + { + "examine": "A strangely decorated chest, the lock is painted crimson.", + "ids": "4113" + }, + { + "examine": "A strangely decorated chest, the lock is painted black.", + "ids": "4114" + }, + { + "examine": "A strangely decorated chest, the lock is painted purple.", + "ids": "4115" + }, + { + "examine": "A strangely decorated steel chest, the lock is painted blood red.", + "ids": "4116" + }, + { + "examine": "A strangely decorated steel chest, the lock is painted brown.", + "ids": "4117" + }, + { + "examine": "A strangely decorated steel chest, the lock is painted crimson.", + "ids": "4118" + }, + { + "examine": "A strangely decorated steel chest, the lock is painted black.", + "ids": "4119" + }, + { + "examine": "A strangely decorated steel chest, the lock is painted purple.", + "ids": "4120" + }, + { + "examine": "A strangely decorated black chest, the lock is painted blood red.", + "ids": "4121" + }, + { + "examine": "A strangely decorated black chest, the lock is painted brown.", + "ids": "4122" + }, + { + "examine": "A strangely decorated black chest, the lock is painted crimson.", + "ids": "4123" + }, + { + "examine": "A strangely decorated black chest, the lock is painted black.", + "ids": "4124" + }, + { + "examine": "A strangely decorated black chest, the lock is painted purple.", + "ids": "4125" + }, + { + "examine": "A strangely decorated silver chest, the lock is painted blood red.", + "ids": "4126" + }, + { + "examine": "A strangely decorated silver chest, the lock is painted brown.", + "ids": "4127" + }, + { + "examine": "A strangely decorated silver chest, the lock is painted crimson.", + "ids": "4128" + }, + { + "examine": "A strangely decorated silver chest, the lock is painted black.", + "ids": "4129" + }, + { + "examine": "A strangely decorated silver chest, the lock is painted purple.", + "ids": "4130" + }, + { + "examine": "A strangely decorated bronze chest, the open lock is painted blood red.", + "ids": "4131" + }, + { + "examine": "This tells you which way is which.", + "ids": "4132,4133,4134,4135" + }, + { + "examine": "These doors look very ominous. A sign says 'To the tombs'.", + "ids": "4136,4137" + }, + { + "examine": "Items are for sale here.", + "ids": "4138" + }, + { + "examine": "Entrance to the Duel Arena.", + "ids": "4139,4140" + }, + { + "examine": "This seems to be some kind of shrine.", + "ids": "4141" + }, + { + "examine": "The wind makes a musical sound as it blows through it...", + "ids": "4142" + }, + { + "examine": "Danger", + "ids": "4143" + }, + { + "examine": "Those golden fruit look good enough to eat!", + "ids": "4144,4145,4146" + }, + { + "examine": "This must be Lalli's home.", + "ids": "4147" + }, + { + "examine": "Allows performers backstage at the Longhall.", + "ids": "4148" + }, + { + "examine": "It smells pretty good actually.", + "ids": "4149" + }, + { + "examine": "A portal from this mystical place.", + "ids": "4150,4151,4152,4153,4154,4155,4156,4157" + }, + { + "examine": "Takes me into the maze.", + "ids": "4158" + }, + { + "examine": "Takes me out of the maze.", + "ids": "4159,4160,4161" + }, + { + "examine": "A thin metal pipe, presumably for rainwater to run through.", + "ids": "4162" + }, + { + "examine": "I can climb this.", + "ids": "4163,4164" + }, + { + "examine": "Keeps the wind out.", + "ids": "4165,4166" + }, + { + "examine": "I wonder what's inside?", + "ids": "4167,4168" + }, + { + "examine": "Brrrrrr!", + "ids": "4169" + }, + { + "examine": "There is some kind of balancing mechanism as a lock.", + "ids": "4170" + }, + { + "examine": "A good source of books!", + "ids": "4171" + }, + { + "examine": "An appliance for cooking with.", + "ids": "4172" + }, + { + "examine": "I wonder what's down there?", + "ids": "4173" + }, + { + "examine": "I wonder what's under it?", + "ids": "4174" + }, + { + "examine": "Kind of funny smelling...", + "ids": "4175" + }, + { + "examine": "Water comes out of it.", + "ids": "4176" + }, + { + "examine": "This may be worth opening.", + "ids": "4177" + }, + { + "examine": "This may be worth searching.", + "ids": "4178" + }, + { + "examine": "A very unusual piece of artwork...", + "ids": "4179,4180" + }, + { + "examine": "Alas poor unicorn, I knew him well.", + "ids": "4181" + }, + { + "examine": "Looks like the bull lost.", + "ids": "4182" + }, + { + "examine": "A pile of boxes for storage.", + "ids": "4183,4184" + }, + { + "examine": "A wooden crate for storage.", + "ids": "4185" + }, + { + "examine": "An old crate for storage.", + "ids": "4186" + }, + { + "examine": "I can climb this.", + "ids": "4187" + }, + { + "examine": "This leads upwards.", + "ids": "4188" + }, + { + "examine": "This leads downwards.", + "ids": "4189,4190,4191,4192,4193,4194,4195,4196,4197,4198,4199,4200,4201,4202,4203,4204,4205,4206,4207,4208,4209,4210,4211,4212,4213,4214,4215,4216,4217,4218,4219,4220,4221,4222,4223,4224,4225,4226,4227,4228,4229,4230,4231,4232,4233,4234,4235,4236,4237,4238,4239,4240,4241,4242,4243,4244,4245,4246" + }, + { + "examine": "Keeps the cold winds out.", + "ids": "4247" + }, + { + "examine": "Doesn't keep the wind out if it's open!", + "ids": "4248,4249" + }, + { + "examine": "I'm sure the animal is glad its fur was put to good use.", + "ids": "4250,4251" + }, + { + "examine": "I wonder what's inside?", + "ids": "4252,4253,4254,4255,4256,4257,4258,4259,4260,4261,4262,4263,4264" + }, + { + "examine": "Toasty.", + "ids": "4265" + }, + { + "examine": "Hot!", + "ids": "4266" + }, + { + "examine": "Finger licking good!", + "ids": "4267,4268" + }, + { + "examine": "It's a long wooden table.", + "ids": "4269" + }, + { + "examine": "It's a table with candles on.", + "ids": "4270" + }, + { + "examine": "Generally used for sitting.", + "ids": "4271" + }, + { + "examine": "Generally used for putting things on.", + "ids": "4272" + }, + { + "examine": "Actually, I could do with a drink...", + "ids": "4273" + }, + { + "examine": "For leaning against...", + "ids": "4274" + }, + { + "examine": "A wooden barrel containing lots of fish.", + "ids": "4275" + }, + { + "examine": "Always a source of good bargains.", + "ids": "4276" + }, + { + "examine": "There's something fishy about this stall.", + "ids": "4277" + }, + { + "examine": "Around here, this is where you buy new doors.", + "ids": "4278,4279,4280,4281,4282" + }, + { + "examine": "Has a peculiar odour.", + "ids": "4283,4284" + }, + { + "examine": "Water comes out of this.", + "ids": "4285" + }, + { + "examine": "It's kind of like a barrel.", + "ids": "4286" + }, + { + "examine": "Looks pretty comfy.", + "ids": "4287" + }, + { + "examine": "I guess I could sleep in it if I was really tired.", + "ids": "4288,4289,4290,4291,4292,4293,4294,4295" + }, + { + "examine": "Yup, looks like this neighbourhood is perfectly safe for travellers...", + "ids": "4296" + }, + { + "examine": "A pile of boxes for storage.", + "ids": "4297,4298,4299" + }, + { + "examine": "A wooden crate for storage.", + "ids": "4300" + }, + { + "examine": "An old crate for storage.", + "ids": "4301,4302,4303" + }, + { + "examine": "A hot place for forging things in.", + "ids": "4304,4305" + }, + { + "examine": "Used for fashioning metal items.", + "ids": "4306" + }, + { + "examine": "Various implements for working with metal.", + "ids": "4307" + }, + { + "examine": "Bake your clay pots in here.", + "ids": "4308" + }, + { + "examine": "Used for spinning thread.", + "ids": "4309" + }, + { + "examine": "Used for fashioning clay items.", + "ids": "4310" + }, + { + "examine": "A wooden gate.", + "ids": "4311,4312,4313,4314,4315,4316,4317,4318,4319,4320,4321,4322,4323,4324,4325,4326,4327" + }, + { + "examine": "This tree has been cut down.", + "ids": "4328,4329,4330,4331,4332,4333,4334,4335,4336,4337,4338,4339,4340,4341,4342,4343,4344,4345,4346,4347" + }, + { + "examine": "Best left on the beach.", + "ids": "4348" + }, + { + "examine": "This once belonged to a sea animal.", + "ids": "4349" + }, + { + "examine": "Best left for the crabs.", + "ids": "4350" + }, + { + "examine": "I can hear the sea with this.", + "ids": "4351" + }, + { + "examine": "A half-buried bowl.", + "ids": "4352,4353,4354,4355,4356,4357,4358,4359,4360,4361,4362,4363,4364,4365" + }, + { + "examine": "An empty shelf...", + "ids": "4366,4367" + }, + { + "examine": "There are some pots and pans here.", + "ids": "4368" + }, + { + "examine": "There are some tankards here.", + "ids": "4369" + }, + { + "examine": "A shelf with a bucket on it.", + "ids": "4370" + }, + { + "examine": "There are a few books on this shelf.", + "ids": "4371" + }, + { + "examine": "It's a small table.", + "ids": "4372" + }, + { + "examine": "A tray of sand.", + "ids": "4373,4374,4375,4376" + }, + { + "examine": "There should be a standard here!", + "ids": "4377,4378,4379" + }, + { + "examine": "I could climb this if I wanted.", + "ids": "4380" + }, + { + "examine": "It's a war machine.", + "ids": "4381,4382" + }, + { + "examine": "I could climb this if I wanted.", + "ids": "4383,4384" + }, + { + "examine": "The catapult is damaged.", + "ids": "4385,4386" + }, + { + "examine": "A portal to join the Saradomin team.", + "ids": "4387" + }, + { + "examine": "A portal to join the Zamorak team.", + "ids": "4388" + }, + { + "examine": "A portal to leave the Saradomin team.", + "ids": "4389" + }, + { + "examine": "A portal to leave the Zamorak team.", + "ids": "4390,4391,4392,4393,4394,4395,4396,4397,4398,4399,4400,4401,4402,4403,4404,4405" + }, + { + "examine": "A portal to leave the Saradomin team.", + "ids": "4406" + }, + { + "examine": "A portal to leave the Zamorak team.", + "ids": "4407" + }, + { + "examine": "A portal to join a random team.", + "ids": "4408,4409,4410" + }, + { + "examine": "A very slippery stepping stone", + "ids": "4411" + }, + { + "examine": "I could climb this if I wanted.", + "ids": "4412,4413" + }, + { + "examine": "A rickety old staircase.", + "ids": "4414" + }, + { + "examine": "A solid stone staircase.", + "ids": "4415,4416,4417,4418,4419,4420,36480,36481,36484,36495,36521,36523,36532,36540" + }, + { + "examine": "A spiky barricade.", + "ids": "4421,4422" + }, + { + "examine": "A large broken door.", + "ids": "4431,4432,4433,4434,4435,4436" + }, + { + "examine": "We could use our pickaxes to get past these...", + "ids": "4437" + }, + { + "examine": "We can almost get past these...", + "ids": "4438,4439,4440,4441,4442,4443" + }, + { + "examine": "Should be long enough to scale castle walls.", + "ids": "4444,4445" + }, + { + "examine": "Maybe I could tie a rope to this...", + "ids": "4446,4447" + }, + { + "examine": "It doesn't look very stable...", + "ids": "4448" + }, + { + "examine": "A solid stone staircase.", + "ids": "4449,4450,4451,4452,4453,4454,4455,4456,4457" + }, + { + "examine": "There are some bandages on this table.", + "ids": "4458" + }, + { + "examine": "There are some toolboxes on this table.", + "ids": "4459" + }, + { + "examine": "There's some rock I can use with the catapult here.", + "ids": "4460" + }, + { + "examine": "There are some barricades here.", + "ids": "4461" + }, + { + "examine": "There is some rope here.", + "ids": "4462" + }, + { + "examine": "There are some explosive potions here.", + "ids": "4463" + }, + { + "examine": "There are some pickaxes on this table.", + "ids": "4464" + }, + { + "examine": "An elf-fashioned door.", + "ids": "4465,4466" + }, + { + "examine": "The door is closed.", + "ids": "4467" + }, + { + "examine": "The door is open.", + "ids": "4468" + }, + { + "examine": "Only the Saradomin team may pass.", + "ids": "4469" + }, + { + "examine": "Only the Zamorak team may pass.", + "ids": "4470" + }, + { + "examine": "I wonder what's under it?", + "ids": "4471,4472,4473,4474,4475,4476,4477,4478,4479,4480,4481" + }, + { + "examine": "Water comes out of this.", + "ids": "4482" + }, + { + "examine": "It's open.", + "ids": "4483" + }, + { + "examine": "Keep track of which team has the most victories.", + "ids": "4484" + }, + { + "examine": "I could climb this if I wanted.", + "ids": "4485,4486" + }, + { + "examine": "A big wooden door.", + "ids": "4487,4488,4489,4490,4491,4492" + }, + { + "examine": "I can climb these stairs.", + "ids": "4493" + }, + { + "examine": "They go down.", + "ids": "4494" + }, + { + "examine": "I can climb these stairs.", + "ids": "4495" + }, + { + "examine": "They go down.", + "ids": "4496" + }, + { + "examine": "I can climb these stairs.", + "ids": "4497" + }, + { + "examine": "They go down.", + "ids": "4498" + }, + { + "examine": "Wow", + "ids": "4499" + }, + { + "examine": "This leads back to the cruel world above.", + "ids": "4500,4501,4502,4503,4504,4505,4506,4507,4508,4509,4510,4511,4512" + }, + { + "examine": "I doubt that was built to last...", + "ids": "4513,4514,4515,4516,4517" + }, + { + "examine": "How do you make a skeleton laugh?", + "ids": "4518" + }, + { + "examine": "Tickle his funny bone.", + "ids": "4519" + }, + { + "examine": "Clearly has been relaxing too long....", + "ids": "4520,4521,4522,4523,4524,4525,4526,4527,4528,4529,4530,4531,4532,4533,4534,4535,4536,4537,4538,4539,4540" + }, + { + "examine": "Did that thing just twitch?", + "ids": "4541,4542" + }, + { + "examine": "A strange wall with objects engraved upon it.", + "ids": "4543,4544" + }, + { + "examine": "A strange wall that appears to be hinged.", + "ids": "4545,4546,4547,4548,4549" + }, + { + "examine": "I can jump off this one.", + "ids": "4550,4551,4552,4553,4554,4555,4556,4557,4558,4559,4560,4561,4562,4563,4564,4565,4566,4567" + }, + { + "examine": "I can climb up these stairs.", + "ids": "4568" + }, + { + "examine": "I can climb up or go down these stairs.", + "ids": "4569,36777" + }, + { + "examine": "I can climb down these stairs.", + "ids": "4570,4571,4572,4573,4574,4575,4576" + }, + { + "examine": "Lets you walk through walls!", + "ids": "4577,4578,4579,4580,4581,4582,4583,4584,4585,4586" + }, + { + "examine": "It turns the light around.", + "ids": "4587" + }, + { + "examine": "It looks broken.", + "ids": "4588" + }, + { + "examine": "Part of the Lighthouse's lighting mechanism.", + "ids": "4589" + }, + { + "examine": "Part of the lighthouse Light mechanism.", + "ids": "4590,4591,4592,4593,4594,4595,4596,4597,4598,4599,4600,4601,4602,4603,4604,4605,4606,4607,4608,4609" + }, + { + "examine": "Best left on the beach.", + "ids": "4610" + }, + { + "examine": "This once belonged to a sea animal.", + "ids": "4611" + }, + { + "examine": "Best left for the crabs.", + "ids": "4612" + }, + { + "examine": "I can hear the sea with this.", + "ids": "4613" + }, + { + "examine": "It is a buried bowl.", + "ids": "4614" + }, + { + "examine": "I can jump off this one.", + "ids": "4615,4616" + }, + { + "examine": "Shelves filled with interesting books.", + "ids": "4617" + }, + { + "examine": "A nice and cosy fire.", + "ids": "4618,4619" + }, + { + "examine": "They go down.", + "ids": "4620,4621" + }, + { + "examine": "They go up.", + "ids": "4622,4623" + }, + { + "examine": "They go down.", + "ids": "4624,4625" + }, + { + "examine": "They go up.", + "ids": "4626,4627,4628" + }, + { + "examine": "An elf-fashioned door.", + "ids": "4636,4637,4638,4639,4640" + }, + { + "examine": "Mmm...beer!", + "ids": "4641" + }, + { + "examine": "Has some board games news on it.", + "ids": "4642" + }, + { + "examine": "The ladder to the Runelink challenge room for experienced players.", + "ids": "4643" + }, + { + "examine": "The ladder back to the Runelink challenge room.", + "ids": "4644" + }, + { + "examine": "The ladder to the Draughts challenge room for experienced players.", + "ids": "4645" + }, + { + "examine": "The ladder back to the Draughts challenge room.", + "ids": "4646" + }, + { + "examine": "The ladder back up to the Toad and Chicken.", + "ids": "4647" + }, + { + "examine": "Leads down to the Burthorpe Games Rooms.", + "ids": "4648,4649" + }, + { + "examine": "A nice and cosy fire.", + "ids": "4650" + }, + { + "examine": "A table for board games.", + "ids": "4651" + }, + { + "examine": "A game of draughts is being played on this table.", + "ids": "4652" + }, + { + "examine": "A game of Runelink is being played on this table.", + "ids": "4653,4654,4655" + }, + { + "examine": "A comfy stool.", + "ids": "4656,4657" + }, + { + "examine": "Draughts challenge room.", + "ids": "4658" + }, + { + "examine": "Runelink challenge room.", + "ids": "4659" + }, + { + "examine": "Draughts challenge room for experienced players.", + "ids": "4660" + }, + { + "examine": "Runelink challenge room for experienced players.", + "ids": "4661,4662,4663,4664,4665,4666,4667,4668" + }, + { + "examine": "A statue of Arrav (the Fountain of Heroes has moved downstairs.)", + "ids": "4669" + }, + { + "examine": "A statue of Camorra (the Fountain of Heroes has moved downstairs.)", + "ids": "4670" + }, + { + "examine": "A good source of books!", + "ids": "4671" + }, + { + "examine": "The door into the throne room.", + "ids": "4672,4673" + }, + { + "examine": "I bet this makes good syrup!", + "ids": "4674" + }, + { + "examine": "Scented herbs.", + "ids": "4675" + }, + { + "examine": "A rocky outcrop.", + "ids": "4676" + }, + { + "examine": "Scented herbs.", + "ids": "4677,4678,4679,4680,4681,4682" + }, + { + "examine": "A large harp.", + "ids": "4683" + }, + { + "examine": "Good for shooting fish in.", + "ids": "4684" + }, + { + "examine": "This old tree is rotting away", + "ids": "4685" + }, + { + "examine": "This old tree is rotting away.", + "ids": "4686,4687,4688,4689" + }, + { + "examine": "Fancy.", + "ids": "4690,4691" + }, + { + "examine": "Flag, pole...Yep, it's a flagpole.", + "ids": "4692,4693,4694,4695" + }, + { + "examine": "The door is closed.", + "ids": "4696" + }, + { + "examine": "The door is open.", + "ids": "4697,4698,4699,4700" + }, + { + "examine": "Keeps the cold winds out.", + "ids": "4701" + }, + { + "examine": "A nicely carved wooden chair.", + "ids": "4702" + }, + { + "examine": "A wooden double bed. For sleeping in...", + "ids": "4703,4704" + }, + { + "examine": "There's something fishy about this stall.", + "ids": "4705" + }, + { + "examine": "You should eat your greens!", + "ids": "4706" + }, + { + "examine": "There's something fishy about this stall.", + "ids": "4707" + }, + { + "examine": "You should eat your greens!", + "ids": "4708,4709" + }, + { + "examine": "A doorway made from bamboo.", + "ids": "4710,4711" + }, + { + "examine": "It's a trapdoor.", + "ids": "4712" + }, + { + "examine": "It's an open trapdoor.", + "ids": "4713" + }, + { + "examine": "A wooden crate for storage.", + "ids": "4714" + }, + { + "examine": "This crate is making chattering sounds.", + "ids": "4715" + }, + { + "examine": "This crate smells slightly nauseous.", + "ids": "4716" + }, + { + "examine": "This crate says 'Property of Hamab' on its side.", + "ids": "4717,4718" + }, + { + "examine": "This crate says 'Property of Ifaba' on its side.", + "ids": "4719" + }, + { + "examine": "This crate says 'Property of Daga' on its side.", + "ids": "4720,4721" + }, + { + "examine": "This crate smells slightly of banana.", + "ids": "4722,4723" + }, + { + "examine": "This crate says 'Property of Hamab' on its side.", + "ids": "4724" + }, + { + "examine": "This crate says 'Property of Ifaba' on its side.", + "ids": "4725,4726,4727" + }, + { + "examine": "I can climb up this.", + "ids": "4728" + }, + { + "examine": "A dried up bush, void of life.", + "ids": "4729,4730,4731,4732,4733,4734,4735,4736,4737,4738,4739,4740,4741,4742" + }, + { + "examine": "It's a bamboo ladder.", + "ids": "4743,4744" + }, + { + "examine": "Looks good for jumping off.", + "ids": "4745" + }, + { + "examine": "This crate is marked 'Deliver to Glough'...", + "ids": "4746,4747,4748" + }, + { + "examine": "It's a banana tree, full of bananas.", + "ids": "4749" + }, + { + "examine": "It's a banana tree, with lots of bananas.", + "ids": "4750" + }, + { + "examine": "It's a banana tree, with many bananas.", + "ids": "4751" + }, + { + "examine": "It's a banana tree, with a few bananas.", + "ids": "4752" + }, + { + "examine": "It's a banana tree, with but one banana.", + "ids": "4753" + }, + { + "examine": "It's a banana tree, with no more bananas left.", + "ids": "4754" + }, + { + "examine": "They go down.", + "ids": "4755" + }, + { + "examine": "They go up.", + "ids": "4756,4757,4758,4759,4760,4761,4762,4763" + }, + { + "examine": "It's a bamboo stool.", + "ids": "4764" + }, + { + "examine": "It's a sheer wall of fire, rising as high as you can see.", + "ids": "4765,4766" + }, + { + "examine": "The contents of this pyre are rapidly bubbling and burning.", + "ids": "4767" + }, + { + "examine": "It's a wall of bricks.", + "ids": "4768" + }, + { + "examine": "It's a pile of bricks.", + "ids": "4769,4770" + }, + { + "examine": "A rather dapper little monkey sitting on a throne.", + "ids": "4771" + }, + { + "examine": "It's a bamboo ladder.", + "ids": "4772,4773,4774,4775,4776,4777,4778,4779,4780,4781,4782,4783,4784,4785" + }, + { + "examine": "A plant in a bamboo pot.", + "ids": "4786" + }, + { + "examine": "It's an absolutely huge bamboo gate.", + "ids": "4787,4788,4789,4790" + }, + { + "examine": "It's a big comfy bed, made of strips of bamboo.", + "ids": "4791,4792,4793" + }, + { + "examine": "It's a pot made out of bamboo.", + "ids": "4794" + }, + { + "examine": "They are pots made out of bamboo.", + "ids": "4795,4796" + }, + { + "examine": "Bamboo strips have been lashed together to make this rickety desk.", + "ids": "4797" + }, + { + "examine": "It's a bookcase made out of bamboo.", + "ids": "4798" + }, + { + "examine": "It's a bamboo door with a large iron padlock.", + "ids": "4799,4800,4801,4802,4803,4804,4805,4806" + }, + { + "examine": "It's a door made from bamboo.", + "ids": "4807,4808,4809,4810,4811" + }, + { + "examine": "Looks good for hiding in...", + "ids": "4812,4813,4814" + }, + { + "examine": "Looks good for hiding in.", + "ids": "4815" + }, + { + "examine": "This is a fairly tall tree with sparse foliage.", + "ids": "4816" + }, + { + "examine": "A jungle palm with dense foliage.", + "ids": "4817" + }, + { + "examine": "This is a fairly tall tree with sparse foliage.", + "ids": "4818" + }, + { + "examine": "This was a fairly tall tree with sparse foliage.", + "ids": "4819" + }, + { + "examine": "A leafy tree.", + "ids": "4820" + }, + { + "examine": "This was a fairly tall tree with sparse foliage.", + "ids": "4821" + }, + { + "examine": "This tree has been cut down.", + "ids": "4822" + }, + { + "examine": "This flower is found only in jungle areas.", + "ids": "4823" + }, + { + "examine": "A very rare and exotic flower.", + "ids": "4824" + }, + { + "examine": "A small fernlike plant.", + "ids": "4825" + }, + { + "examine": "Leaves a nasty mark.", + "ids": "4826" + }, + { + "examine": "Looks spiky.", + "ids": "4827" + }, + { + "examine": "This has broad leaves.", + "ids": "4828" + }, + { + "examine": "A type of jungle fern.", + "ids": "4829" + }, + { + "examine": "A large waxy jungle plant.", + "ids": "4830" + }, + { + "examine": "Commonly found in these parts.", + "ids": "4831" + }, + { + "examine": "The tendrils of a creeping plant.", + "ids": "4832" + }, + { + "examine": "A jungle bush, quite common to these areas.", + "ids": "4833,4834" + }, + { + "examine": "A jungle bush that has been chopped down.", + "ids": "4835,4836,4837,4838,4839,4840,4841,4842,4843,4844" + }, + { + "examine": "A terribly tall tropical tree.", + "ids": "4845,4846,4847" + }, + { + "examine": "Leaves of a tropical tree.", + "ids": "4848" + }, + { + "examine": "This tree no doubt contains dangerous insects.", + "ids": "4849,4850,4851" + }, + { + "examine": "This old tree is rotting away.", + "ids": "4852" + }, + { + "examine": "A gnarly old tree root.", + "ids": "4853" + }, + { + "examine": "The roots of this tree are exposed.", + "ids": "4854" + }, + { + "examine": "I hope I don't trip over any of these.", + "ids": "4855" + }, + { + "examine": "It's a small patch of glowing fungus.", + "ids": "4856" + }, + { + "examine": "It's a medium patch of glowing fungus.", + "ids": "4857" + }, + { + "examine": "It's an absolutely colossal statue of some kind of gorilla.", + "ids": "4858" + }, + { + "examine": "It's a huge statue of some kind of gorilla.", + "ids": "4859,4860" + }, + { + "examine": "It's a huge statue of some kind of monkey.", + "ids": "4861" + }, + { + "examine": "It's a large patch of glowing fungus.", + "ids": "4862" + }, + { + "examine": "Legs of this watchtower.", + "ids": "4863,4864" + }, + { + "examine": "It's the middle of this watchtower.", + "ids": "4865" + }, + { + "examine": "It's a deactivated military Gnome glider.", + "ids": "4866" + }, + { + "examine": "It's an activated military Gnome glider.", + "ids": "4867" + }, + { + "examine": "It's some kind of Gnome teleportation device.", + "ids": "4868,4869,4870" + }, + { + "examine": "This is the panel controlling the hangar reinitialisation.", + "ids": "4871" + }, + { + "examine": "There must be an exit nearby.", + "ids": "4872" + }, + { + "examine": "It's probably too risky to try pulling this.", + "ids": "4873" + }, + { + "examine": "This table has crafting paraphernalia on it.", + "ids": "4874" + }, + { + "examine": "This table has ripe bananas on show.", + "ids": "4875" + }, + { + "examine": "This table has items of a general nature on it.", + "ids": "4876" + }, + { + "examine": "This table has runes on display.", + "ids": "4877" + }, + { + "examine": "This table has a scimitar on it.", + "ids": "4878" + }, + { + "examine": "It's a trapdoor.", + "ids": "4879" + }, + { + "examine": "It's an open trapdoor.", + "ids": "4880" + }, + { + "examine": "I can climb up this.", + "ids": "4881" + }, + { + "examine": "Looks suspicious.", + "ids": "4882,4883" + }, + { + "examine": "A plank.", + "ids": "4884" + }, + { + "examine": "Formed over many years.", + "ids": "4885" + }, + { + "examine": "Human sieve creation.", + "ids": "4886" + }, + { + "examine": "Looks suspicious.", + "ids": "4887" + }, + { + "examine": "It's a trapdoor.", + "ids": "4888" + }, + { + "examine": "I can climb up this.", + "ids": "4889,4890,4891,4892,4893,4894,4895,4896,4897,4898,4899" + }, + { + "examine": "The Saradomin Team Standard.", + "ids": "4900" + }, + { + "examine": "The Zamorak Team Standard.", + "ids": "4901" + }, + { + "examine": "The Saradomin Team Standard.", + "ids": "4902" + }, + { + "examine": "The Zamorak Team Standard.", + "ids": "4903" + }, + { + "examine": "It's on fire!", + "ids": "4904,4905,4906,4907,4908,4909" + }, + { + "examine": "A wooden barrel for storage.", + "ids": "4910" + }, + { + "examine": "I can climb down this.", + "ids": "4911,4912,36349,36365" + }, + { + "examine": "It looks cramped and dark.", + "ids": "4913,4914,4915,4916,4917" + }, + { + "examine": "This cart is blocking the way up the ridge.", + "ids": "4918" + }, + { + "examine": "These stairs seem to have been hewn out of the rock itself.", + "ids": "4919" + }, + { + "examine": "It looks cramped and dark.", + "ids": "4920,4921,4922" + }, + { + "examine": "These stairs seem to have been hewn out of the rock itself.", + "ids": "4923" + }, + { + "examine": "A valve to start and stop the flow of water.", + "ids": "4924,4925" + }, + { + "examine": "Shiny!", + "ids": "4926,4927,4928" + }, + { + "examine": "It looks cramped and dark.", + "ids": "4929" + }, + { + "examine": "It's blocking the tunnel, but it looks dark down there anyway.", + "ids": "4930,4931" + }, + { + "examine": "A bizarre fungus. It emits a pale blue light.", + "ids": "4932,4933,4934" + }, + { + "examine": "If that wasn't there I'd probably be a lot flatter now.", + "ids": "4935" + }, + { + "examine": "It prevents the wall unceremoniously squashing people.", + "ids": "4936" + }, + { + "examine": "It looks like it's water powered.", + "ids": "4937,4938,4939,4940,4941" + }, + { + "examine": "It's a little waterlogged. I hope it still works.", + "ids": "4942,4943" + }, + { + "examine": "It doesn't look very watertight. Any contents will be ruined.", + "ids": "4944" + }, + { + "examine": "A sunken mine cart, how useful.", + "ids": "4945,4946,4947,4948" + }, + { + "examine": "This displays information on how the points on this level are set.", + "ids": "4949" + }, + { + "examine": "It has the letter 'B' inscribed on the end.", + "ids": "4950" + }, + { + "examine": "It has the letter 'A' inscribed on the end.", + "ids": "4951" + }, + { + "examine": "It has the letter 'C' inscribed on the end.", + "ids": "4952" + }, + { + "examine": "It has the letter 'D' inscribed on the end.", + "ids": "4953" + }, + { + "examine": "It has the letter 'E' inscribed on the end.", + "ids": "4954" + }, + { + "examine": "It has the letter 'I' inscribed on the end.", + "ids": "4955" + }, + { + "examine": "It has the letter 'J' inscribed on the end.", + "ids": "4956" + }, + { + "examine": "It has the letter 'K' inscribed on the end.", + "ids": "4957" + }, + { + "examine": "I think this changes one of the sets of points.", + "ids": "4958" + }, + { + "examine": "It has the letter 'F' inscribed on the end.", + "ids": "4959" + }, + { + "examine": "It has the letter 'G' inscribed on the end.", + "ids": "4960" + }, + { + "examine": "It has the letter 'H' inscribed on the end.", + "ids": "4961" + }, + { + "examine": "The door is closed.", + "ids": "4962" + }, + { + "examine": "I can climb down this.", + "ids": "4965" + }, + { + "examine": "I can climb this.", + "ids": "4966" + }, + { + "examine": "I can climb down this.", + "ids": "4967" + }, + { + "examine": "I can climb this.", + "ids": "4968" + }, + { + "examine": "I can climb down this.", + "ids": "4969" + }, + { + "examine": "I can climb this.", + "ids": "4970" + }, + { + "examine": "These stairs seem to have been hewn out of the rock itself.", + "ids": "4971,4972,4973" + }, + { + "examine": "Useful for moving items around the mine.", + "ids": "4974" + }, + { + "examine": "An old crate for storage.", + "ids": "4975" + }, + { + "examine": "A distinctive layer in the rock strata.", + "ids": "4976,4977,4978,4979,4980,4981,4982,4983,4984,4985,4986,4987,4988,4989,4990,4991,4992,4993,4994,4995,4996,4997,4998,4999,5000" + }, + { + "examine": "This cave has been boarded up.", + "ids": "5001" + }, + { + "examine": "Useful for passing over inaccessible areas.", + "ids": "5002" + }, + { + "examine": "It's old and pretty broken.", + "ids": "5003" + }, + { + "examine": "A well used tree.", + "ids": "5004,5005" + }, + { + "examine": "These flowers only grow in one place in the mountains.", + "ids": "5006" + }, + { + "examine": "Looks like small cave.", + "ids": "5007" + }, + { + "examine": "Looks dark...", + "ids": "5008,5009,5010,5011,5012,5013,5014" + }, + { + "examine": "It's too dangerous to go down here by foot...", + "ids": "5015,5016,5017,5018,5019,5020,5021,5022,5023,5024" + }, + { + "examine": "A split in the cave wall...", + "ids": "5025,5026,5027,5028,5029,5030,5031,5032,5033,5034,5035,5036" + }, + { + "examine": "A large ice covered boulder.", + "ids": "5037" + }, + { + "examine": "An ice covered boulder.", + "ids": "5038" + }, + { + "examine": "A small ice covered boulder.", + "ids": "5039,5040,5041,5042" + }, + { + "examine": "A huge ice gate.", + "ids": "5043,5044" + }, + { + "examine": "An interesting-looking tree.", + "ids": "5045" + }, + { + "examine": "A small cave entrance.", + "ids": "5046" + }, + { + "examine": "Limestone ceiling growth.", + "ids": "5047" + }, + { + "examine": "A limestone ceiling growth.", + "ids": "5048" + }, + { + "examine": "A tooth shaped rock formation protruding from the floor.", + "ids": "5049" + }, + { + "examine": "Tooth shaped rock formations protruding from the floor.", + "ids": "5050" + }, + { + "examine": "A dirty little swamp boat.", + "ids": "5051" + }, + { + "examine": "If it had paint on it, you'd probably watch it dry.", + "ids": "5052,5053" + }, + { + "examine": "I can climb this.", + "ids": "5054" + }, + { + "examine": "I wonder what that's there for...", + "ids": "5055" + }, + { + "examine": "These doors look very ominous.", + "ids": "5056,5057" + }, + { + "examine": "Large doors set into the hillside.", + "ids": "5058,5059" + }, + { + "examine": "These doors seem to lead into the underground.", + "ids": "5060,5061" + }, + { + "examine": "Large doors set into the hillside.", + "ids": "5062,5063,5064,5065,5066,5067,5068,5069,5070,5071" + }, + { + "examine": "A Large Pillar", + "ids": "5072,5073,5074,5075,5076,5077,5078,5079,5080,5081" + }, + { + "examine": "An overgrown dungeon entrance.", + "ids": "5082" + }, + { + "examine": "A closed overgrown dungeon entrance.", + "ids": "5083" + }, + { + "examine": "The way to go when I get scared.", + "ids": "5084,5085,5086,5087" + }, + { + "examine": "I hope I don't fall off this.", + "ids": "5088,5089,5090,5091,5092,5093" + }, + { + "examine": "These stairs seem to have been hewn out of the rock itself.", + "ids": "5094,5095,5096,5097,5098" + }, + { + "examine": "Thick vines blocking your way.", + "ids": "5103,5104,5105,5106,5107,5108,5109" + }, + { + "examine": "I can jump from this stepping stone.", + "ids": "5110,5111" + }, + { + "examine": "Not good for eating.", + "ids": "5112" + }, + { + "examine": "I doubt that's edible.", + "ids": "5113,5114,5115" + }, + { + "examine": "A statue of a big monster.", + "ids": "5116,5117,5118,5119,5120,5121" + }, + { + "examine": "A tall wooden door.", + "ids": "5126" + }, + { + "examine": "A tall wooden door.", + "ids": "5128,5129" + }, + { + "examine": "Looks like whoever uses this has claws on their hands.", + "ids": "5130" + }, + { + "examine": "I wonder what's under it?", + "ids": "5131" + }, + { + "examine": "I wonder what's down there?", + "ids": "5132" + }, + { + "examine": "A hurdle.", + "ids": "5133,5134,5135" + }, + { + "examine": "A climbing wall made from skulls.", + "ids": "5136,5137" + }, + { + "examine": "A very slippery stepping stone.", + "ids": "5138" + }, + { + "examine": "A scary zip line for teeth??", + "ids": "5139,5140,5141,5142,5143,5144,5145" + }, + { + "examine": "A goal.", + "ids": "5146,5147,5148,5149,5150,5151" + }, + { + "examine": "This may be worth opening.", + "ids": "5156" + }, + { + "examine": "This may be worth searching.", + "ids": "5157" + }, + { + "examine": "A pile of garden canes.", + "ids": "5158" + }, + { + "examine": "There's no way to cross this bridge.", + "ids": "5159,5160" + }, + { + "examine": "An old grandfather clock.", + "ids": "5161" + }, + { + "examine": "A closed chest.", + "ids": "5162" + }, + { + "examine": "An open chest.", + "ids": "5163" + }, + { + "examine": "There is a note pinned to the signpost.", + "ids": "5164" + }, + { + "examine": "It looks like it needs a good sweep out.", + "ids": "5165" + }, + { + "examine": "Bookish.", + "ids": "5166" + }, + { + "examine": "A large, elaborately ornamented memorial stone.", + "ids": "5167" + }, + { + "examine": "A grave, marked by an ostentatious memorial stone.", + "ids": "5168" + }, + { + "examine": "A poor grave marked by a simple, wooden cross.", + "ids": "5169" + }, + { + "examine": "The entrance to an extravagantly decorated mausoleum.", + "ids": "5170,5171" + }, + { + "examine": "The door to the Tower.", + "ids": "5172,5173" + }, + { + "examine": "The door to the garden shed.", + "ids": "5174,5175" + }, + { + "examine": "At some point the lightning conductor has broken, rendering it useless.", + "ids": "5176" + }, + { + "examine": "A shocking piece of kit.", + "ids": "5177" + }, + { + "examine": "Mmm.. scented candles.", + "ids": "5178,5179" + }, + { + "examine": "I wouldn't eat there!", + "ids": "5180,5181,5182" + }, + { + "examine": "Looks wooden. Feels wooden. I wonder is it wooden?", + "ids": "5183,5184,5185,5186,5187,5188,5189,5190,5191,5192,5193,5194,5195,5196,5197,5198,5199,5200,5201" + }, + { + "examine": "Dangerous, someone could trip on them.", + "ids": "5202,5203,5204,5205" + }, + { + "examine": "I can climb these stairs.", + "ids": "5206" + }, + { + "examine": "They go down.", + "ids": "5207,5208,5209,5210,5211,5212,5213,5214,5215,5216,5217,5218,5219,5220,5221,5222,5223,5224,5225,5226,5227" + }, + { + "examine": "Formed over many years of dripping limestone.", + "ids": "5228,5229,5230" + }, + { + "examine": "A tooth shaped rock formation protruding from the floor.", + "ids": "5231,5232,5233,5234,5235,5236,5237,5238,5239,5240,5241,5242,5243" + }, + { + "examine": "Looks a bit tatty...", + "ids": "5244,5245" + }, + { + "examine": "A well slept in bed.", + "ids": "5246,5247" + }, + { + "examine": "It looks like a tree made of crystal.", + "ids": "5248" + }, + { + "examine": "Looks to me like a quickly built fire.", + "ids": "5249" + }, + { + "examine": "I can climb down this.", + "ids": "5250" + }, + { + "examine": "I can climb this.", + "ids": "5251" + }, + { + "examine": "A recently extinguished fire.", + "ids": "5252" + }, + { + "examine": "I wish I could sting other people.", + "ids": "5253" + }, + { + "examine": "Probably feels like a mild bee sting.", + "ids": "5254" + }, + { + "examine": "I wouldn't like to get stung.", + "ids": "5255" + }, + { + "examine": "Dock leaves at the ready.", + "ids": "5256" + }, + { + "examine": "Nettles sting my leggies.", + "ids": "5257" + }, + { + "examine": "These may hurt.", + "ids": "5258" + }, + { + "examine": "A ghostly barrier.", + "ids": "5259,5260,5261" + }, + { + "examine": "These stairs were carved out of the rock of the cavern.", + "ids": "5262,5263" + }, + { + "examine": "I can climb this.", + "ids": "5264" + }, + { + "examine": "I can climb up here.", + "ids": "5265" + }, + { + "examine": "I can go below decks with this ladder.", + "ids": "5266" + }, + { + "examine": "I wonder what's under it.", + "ids": "5267" + }, + { + "examine": "I wonder what's down there.", + "ids": "5268" + }, + { + "examine": "I can't see a rock!", + "ids": "5269" + }, + { + "examine": "I wonder what's inside.", + "ids": "5270,5271,5272" + }, + { + "examine": "Perhaps I should search it.", + "ids": "5273" + }, + { + "examine": "High above here is a tattered flag, blowing in the wind.", + "ids": "5274" + }, + { + "examine": "An appliance for cooking with.", + "ids": "5275" + }, + { + "examine": "The bank teller will serve you from here.", + "ids": "5276" + }, + { + "examine": "This booth is closed.", + "ids": "5277" + }, + { + "examine": "The resting place of Necrovarus' mortal body.", + "ids": "5278,5279" + }, + { + "examine": "I can climb these stairs.", + "ids": "5280" + }, + { + "examine": "They go down.", + "ids": "5281" + }, + { + "examine": "A ghastly fountain filled with slime and bones, the source of Necrovarus' power.", + "ids": "5282" + }, + { + "examine": "It's a small Ectofuntus.", + "ids": "5283" + }, + { + "examine": "A big grinding thing.", + "ids": "5284" + }, + { + "examine": "The tatty gangplank of a tatty ship.", + "ids": "5285,5286" + }, + { + "examine": "Seen better days.", + "ids": "5287,5288,5289,5290,5291,5292,5293,5294,5295,5296,5297,5298,5299,5300,5301,5302,5303,5304,5305" + }, + { + "examine": "A wooden rowing boat.", + "ids": "5306,5307,5308,5309,5310,5311,5312,5313,5314,5315,5316,5317,5318,5319,5320,5321,5322,5323,5324,5325,5326,5327,5328,5329" + }, + { + "examine": "A pile of boxes for storage.", + "ids": "5330" + }, + { + "examine": "A leafy fern.", + "ids": "5331" + }, + { + "examine": "A small bushy plant.", + "ids": "5332" + }, + { + "examine": "A leafy shrub.", + "ids": "5333,5334,5335,5336,5337,5338,5339,5340,5341,5342,5343,5344" + }, + { + "examine": "This needs dusting before I'll sit on it.", + "ids": "5346,5347" + }, + { + "examine": "Not so good for sitting on.", + "ids": "5348" + }, + { + "examine": "Generally used for putting things on.", + "ids": "5349" + }, + { + "examine": "Actually, I could do with a drink...", + "ids": "5350" + }, + { + "examine": "For leaning against...", + "ids": "5351" + }, + { + "examine": "One horsepower; wooden suspension: a beauty.", + "ids": "5352" + }, + { + "examine": "A wooden wheelbarrow.", + "ids": "5353" + }, + { + "examine": "Animal feeder.", + "ids": "5354" + }, + { + "examine": "It probably hasn't got anything interesting inside.", + "ids": "5355" + }, + { + "examine": "They probably haven't got anything interesting inside.", + "ids": "5356,5357" + }, + { + "examine": "Looks like he's been dead a while now...", + "ids": "5358" + }, + { + "examine": "I don't think he'd mind us checking for his wallet now...", + "ids": "5359" + }, + { + "examine": "I'm sure he died of natural causes. Like a massive dragon or something...", + "ids": "5360,5361,5362,5363,5364,5365,5366,5367,5368,5369,5370,5371,5372,5373,5374,5375,5376,5377,5378,5379,5380,5381,5382,5383,5384,5385,5386,5387,5388,5389,5390,5391,5392,5393,5394,5395,5396" + }, + { + "examine": "This figure brings luck to those who sail.", + "ids": "5397,5398,5399,5400,5401,5402" + }, + { + "examine": "Without this I'm going around in circles.", + "ids": "5403" + }, + { + "examine": "Holds up the sails.", + "ids": "5404,5405,5406,5407,5408,5409,5410,5411,5412,5413,5414" + }, + { + "examine": "Allows access to other parts of the ship.", + "ids": "5415,5416,5417,5418,5419,5420,5421,5422,5423,5424,5425,5426,5427,5428" + }, + { + "examine": "It's a table with candles on.", + "ids": "5429" + }, + { + "examine": "Doesn't look too good...", + "ids": "5430" + }, + { + "examine": "Looks a bit empty.", + "ids": "5431,5432,5433,5434,5435,5436,5437,5438" + }, + { + "examine": "It's been knocked off its hinges.", + "ids": "5439,5440,5441,5442,5443,5444,5445,5446,5447,5448,5449,5450,5451,5452" + }, + { + "examine": "It's a door.", + "ids": "5453,5454,5455,5456,5457,5458,5459,5460" + }, + { + "examine": "A subterranean pool of ectoplasm.", + "ids": "5461,5462,5463,5464,5465,5466,5467,5468,5469,5470,5471,5472,5473,5474,5475,5476,5477,5478,5479,5480,5481,5482,5483,5484,5485,5486,5487" + }, + { + "examine": "I can climb this.", + "ids": "5488" + }, + { + "examine": "The finest rings.", + "ids": "5489" + }, + { + "examine": "I wonder what's under it?", + "ids": "5490" + }, + { + "examine": "I wonder what's down there?", + "ids": "5491,5492" + }, + { + "examine": "I can climb this.", + "ids": "5493" + }, + { + "examine": "A crude torch stuck in the ground.", + "ids": "5494" + }, + { + "examine": "I guess I could sleep in it if I was really tired.", + "ids": "5495,5496" + }, + { + "examine": "A well slept in bed.", + "ids": "5497,5498" + }, + { + "examine": "Hot!", + "ids": "5499,5500" + }, + { + "examine": "Stops people getting out.", + "ids": "5501,5502,5503,5504,5505,5506,5507" + }, + { + "examine": "It's a lectern.", + "ids": "5508,5509,5510,5511,5512,5513,5514,5515,5516,5517,5518,5519,5520,5521,5522,5523,5524,5525,5526,5527,5528,5529,5530,5531,5532,5533,5534,5535,5536,5537" + }, + { + "examine": "Makes you cry.", + "ids": "5538" + }, + { + "examine": "Found near the water's edge.", + "ids": "5539,5540,5541,5542" + }, + { + "examine": "Isn't Heather a girls' name?", + "ids": "5543" + }, + { + "examine": "Smells lovely!", + "ids": "5544" + }, + { + "examine": "Who is this Heather girl?", + "ids": "5545" + }, + { + "examine": "A purple haze of delight.", + "ids": "5546" + }, + { + "examine": "The colour purple on stems.", + "ids": "5547" + }, + { + "examine": "I ponder... Why is it purple?", + "ids": "5548" + }, + { + "examine": "I wonder why it's purple?", + "ids": "5549" + }, + { + "examine": "A cure for nettle stings.", + "ids": "5550" + }, + { + "examine": "A droopy tree.", + "ids": "5551" + }, + { + "examine": "These trees are found near water.", + "ids": "5552,5553" + }, + { + "examine": "This is what is left of a willow tree.", + "ids": "5554" + }, + { + "examine": "I don't know art, but I like it!", + "ids": "5555,5556,5557" + }, + { + "examine": "Aggie's cooking something, probably best not to think what...", + "ids": "5558,9736" + }, + { + "examine": "Trinkets and stuff.", + "ids": "5559" + }, + { + "examine": "Looking good!", + "ids": "5560" + }, + { + "examine": "Aggie's broomstick.", + "ids": "5561" + }, + { + "examine": "Aggie has already dyed this cloth.", + "ids": "5562,5563" + }, + { + "examine": "A thoroughly used bed.", + "ids": "5564" + }, + { + "examine": "A lovely comfy-looking big bed.", + "ids": "5565,5566,5567,5568" + }, + { + "examine": "The remains of a stone wall.", + "ids": "5569,5570" + }, + { + "examine": "An empty home for chickens.", + "ids": "5571" + }, + { + "examine": "A lovely bare chicken coop.", + "ids": "5572,5573" + }, + { + "examine": "Full of animal feed.", + "ids": "5574" + }, + { + "examine": "Animal feeder.", + "ids": "5575,5576,5577" + }, + { + "examine": "A traveller's companion.", + "ids": "5578" + }, + { + "examine": "Loaded with hay and ready to roll.", + "ids": "5579" + }, + { + "examine": "A wooden wheelbarrow.", + "ids": "5580" + }, + { + "examine": "Someone's been chopping logs.", + "ids": "5581,5582" + }, + { + "examine": "Baby bread.", + "ids": "5583,5584,5585,5586,5587,5588" + }, + { + "examine": "The river makes it spin.", + "ids": "5589,5590,5591,5592,5593" + }, + { + "examine": "I'd better not get my hands trapped in that.", + "ids": "5594" + }, + { + "examine": "Diango's Toy Stall.", + "ids": "5595" + }, + { + "examine": "Doesn't look too good...", + "ids": "5596" + }, + { + "examine": "Shows which way the wind blows.", + "ids": "5597" + }, + { + "examine": "A barrel for collecting rain water.", + "ids": "5598,5599,5600,5601,5602,5603" + }, + { + "examine": "A rock.", + "ids": "5604" + }, + { + "examine": "A small rock.", + "ids": "5605" + }, + { + "examine": "Some rock.", + "ids": "5606,5607" + }, + { + "examine": "This fire is already in use, I wouldn't mess with it if I were you...", + "ids": "5608" + }, + { + "examine": "They could do with a wash.", + "ids": "5609,5610,5611,5612" + }, + { + "examine": "It smells like the rats aren't washing often enough.", + "ids": "5613" + }, + { + "examine": "Sit back and relax...", + "ids": "5615" + }, + { + "examine": "This tells you which way is which.", + "ids": "5616,5617" + }, + { + "examine": "These open and close!", + "ids": "5618" + }, + { + "examine": "This may be worth searching.", + "ids": "5619,5620" + }, + { + "examine": "An elegant ceramic pot tarnished with the dirt of a hundred years.", + "ids": "5621" + }, + { + "examine": "I wonder what's inside...", + "ids": "5622" + }, + { + "examine": "It smells a bit stuffy.", + "ids": "5623" + }, + { + "examine": "It smells funny in there.", + "ids": "5624" + }, + { + "examine": "Ned is making some rope here.", + "ids": "5625,5626" + }, + { + "examine": "A blue standard.", + "ids": "5627" + }, + { + "examine": "A standard of Lumbridge Castle.", + "ids": "5628,5629,5630,36925" + }, + { + "examine": "Glowing embers.", + "ids": "5631,5632,5633,5634,5635,5636,5637,5638,5639,5640,5641,5642,5643,5644,5645,5646,5647,5648,5649,5650,5651,5652,5653,5654,5655,5656,5657,5658,5659,5660,5661,5662,5663,5664,5665,5666,5667,5668,5669,5670,5671,5672,5673,5674,5675,5676,5677,5678,5679,5680,5681,5682,5683,5684,5685,5686,5687,5688,5689,5690,5691,5692,5693,5694,5695,5696,5697,5698,5699,5700,5701,5702,5703,5704,5705,5706,5707,5708,5709,5710,5711,5712,5713,5714,5715,5716,5717,5718,5719,5720,5721,5722,5723,5724,5725,5726,5727,5728,5729,5730,5731,5732,5733,5734,5735,5736,5737,5738,5739,5740,5741,5742,5743,5744,5745,5746,5747,5748,5749,5750,5751,5752,5753,5754,5755,5756,5757,5758,5759,5760,5761,5762,5763,5764,5765,5766,5767,5768,5769,5770,5771,5772,5773,5774,5775,5776,5777,5778,5779,5780,5781,5782,5783,5784,5785,5786,5787" + }, + { + "examine": "The sort of bench you get in churches.", + "ids": "5788" + }, + { + "examine": "An expertly carved statue of a former King of Misthalin.", + "ids": "5789,5790" + }, + { + "examine": "A carving of a figure from the history of 2009Scape.", + "ids": "5791,36749,36751" + }, + { + "examine": "When I've ground some flour, I'll be able to collect it here.", + "ids": "5792" + }, + { + "examine": "It's a large crack in the wall.", + "ids": "5793,5794,5795,5796,5797,5798" + }, + { + "examine": "It's a trapdoor.", + "ids": "5799,5800,5801,5802" + }, + { + "examine": "It's an open trapdoor.", + "ids": "5803,5804,5805,5806,5807" + }, + { + "examine": "An incredibly detailed stone sculpture.", + "ids": "5808" + }, + { + "examine": "Helps the Seers predict the weather when it's working.", + "ids": "5809" + }, + { + "examine": "Helps the Seers predict the weather.", + "ids": "5810,5811" + }, + { + "examine": "I can climb this.", + "ids": "5812" + }, + { + "examine": "I can climb down this.", + "ids": "5813,5814" + }, + { + "examine": "A candle, a lens and some sort of crystal all precariously balanced together.", + "ids": "5815" + }, + { + "examine": "A beacon so gnome gliders can safely land.", + "ids": "5816,5817,5818,5819,5820,5821,5822,5823,5824" + }, + { + "examine": "Fly Gnome Air.", + "ids": "5825" + }, + { + "examine": "This shop deals in antique swords.", + "ids": "5826,5827,5828,5829,5830" + }, + { + "examine": "Shop counter.", + "ids": "5831,5832,5833,5834" + }, + { + "examine": "Don't want to close this, I might not be able to get back down.", + "ids": "5835,5836,5837,5838,5839,5840,5841" + }, + { + "examine": "It overlooks the path below. Let's hope it won't fall on your head.", + "ids": "5842" + }, + { + "examine": "Someone is climbing down there! Looks dangerous.", + "ids": "5843" + }, + { + "examine": "Placed in a perfect position for stumbling over.", + "ids": "5844" + }, + { + "examine": "There is a rope going over it.", + "ids": "5845" + }, + { + "examine": "Someone is climbing down the rope.", + "ids": "5846" + }, + { + "examine": "You will need to climb over it.", + "ids": "5847" + }, + { + "examine": "The tree stands tall at the edge of the pool.", + "ids": "5848" + }, + { + "examine": "You can't stand on them, but maybe something can be wedged into there.", + "ids": "5849" + }, + { + "examine": "Something put on top of this wouldn't fall off, it's quite smooth and flat.", + "ids": "5850,5851" + }, + { + "examine": "Someone put a plank on top of the stone! Clever...", + "ids": "5852,5853,5854" + }, + { + "examine": "The pool looks very peaceful. You can also hear faint singing coming from it.", + "ids": "5855" + }, + { + "examine": "The legendary White Pearl fruit is growing on these thorny bushes!", + "ids": "5856" + }, + { + "examine": "There's a nasty stench coming from the cave.", + "ids": "5857" + }, + { + "examine": "Faint rays of daylight shine through.", + "ids": "5858" + }, + { + "examine": "It's very dark down there.", + "ids": "5859" + }, + { + "examine": "Very pointy, very sharp.", + "ids": "5860,5861" + }, + { + "examine": "This is the place where you buried Asleif.", + "ids": "5862" + }, + { + "examine": "Asleif was given a proper burial on this spot.", + "ids": "5863,5864,5865,5866,5867,5868,5869,5870,5871,5872,5873,5874,5875,5876,5877" + }, + { + "examine": "It's a long wooden table.", + "ids": "5878" + }, + { + "examine": "Generally used for putting things on.", + "ids": "5879" + }, + { + "examine": "A crude torch stuck in the ground.", + "ids": "5881,5882" + }, + { + "examine": "Sticky, dirty mud.", + "ids": "5883" + }, + { + "examine": "This stinks...", + "ids": "5884" + }, + { + "examine": "The roots go down into the mud.", + "ids": "5885" + }, + { + "examine": "Sticky, dirty roots covered in sticky, dirty mud.", + "ids": "5886" + }, + { + "examine": "It's barely a door, really.", + "ids": "5887,5888,5889,5890" + }, + { + "examine": "The entry to a special tent in the camp.", + "ids": "5891,5892,5893,5894" + }, + { + "examine": "It's just a big stone, really.", + "ids": "5895" + }, + { + "examine": "Uh oh, someone is going to be in trouble!", + "ids": "5896" + }, + { + "examine": "The pool looks very peaceful. You can also hear faint singing coming from it.", + "ids": "5897,5898,5899,5900,5901" + }, + { + "examine": "It's only useful for hiding behind now.", + "ids": "5902,5903,5904" + }, + { + "examine": "This tree has been cut down.", + "ids": "5905,5906,5907,5908" + }, + { + "examine": "A still for making lamp oil.", + "ids": "5909" + }, + { + "examine": "The still has oil in.", + "ids": "5910,5911,5912,5913,5914,5915,5916" + }, + { + "examine": "Noxious fumes bubble up from the bowels of the earth.", + "ids": "5917,5918,5919,5920,5921,5922,5923,5924,5925,5926,5927,5928,5929,5930,5931,5932,5933,5934,5935,5936,5937,5938,5939,5940,5941,5942,5943,5944,5945" + }, + { + "examine": "You see a circle of light at the top.", + "ids": "5946" + }, + { + "examine": "An entrance to the dark caves.", + "ids": "5947" + }, + { + "examine": "I can jump from this stepping stone.", + "ids": "5948,5949,5950,5951,5952,5953,5954,5955,5956,5957,5958" + }, + { + "examine": "I wonder what this does...", + "ids": "5959,5960,5961,5962,5963" + }, + { + "examine": "Flying in mid-air!", + "ids": "5964,5965" + }, + { + "examine": "A blocked passage.", + "ids": "5966" + }, + { + "examine": "I'd better leave his expensive dwarven balls alone.", + "ids": "5967,5968,5969,5970,5971,5972" + }, + { + "examine": "A small cave entrance.", + "ids": "5973,5974" + }, + { + "examine": "A powerful ranging device that fires metal balls.", + "ids": "5975,5976" + }, + { + "examine": "It's a sheer wall of fire, rising as high as you can see.", + "ids": "5977,5978,5979,5980" + }, + { + "examine": "Lighting for the caves.", + "ids": "5981,5982,5983,5984" + }, + { + "examine": "A rock.", + "ids": "5985" + }, + { + "examine": "A small rock.", + "ids": "5986" + }, + { + "examine": "A rock.", + "ids": "5987,5988" + }, + { + "examine": "A mineral vein that looks distinctly like gold.", + "ids": "5989,5990,5991,5992,5993,5994,5995,5996,5997" + }, + { + "examine": "Functions like an open door...", + "ids": "5998,5999,6000,6001,6002,6003,6004,6005,6006,6007,6008" + }, + { + "examine": "It's a tiny little blue flame. Is this the essence of the Arzinian Being?", + "ids": "6009,6010,6011,6012,6013,6014,6015,6016,6017,6018,6019,6020,6021,6022,6023,6024,6025,6026,6027,6028,6029,6030,6031" + }, + { + "examine": "Powers the boat.", + "ids": "6032,6033,6034,6035" + }, + { + "examine": "Allows access to other parts of the ship.", + "ids": "6036,6037" + }, + { + "examine": "Without this I'm going around in circles.", + "ids": "6038,6039,6040,6041,6042" + }, + { + "examine": "Powers the boat.", + "ids": "6043,6044" + }, + { + "examine": "You can 'cart' things around on this.", + "ids": "6045,6046,6047,6048,6049,6050,6051,6052,6053,6054,6055,6056,6057,6058,6059,6060,6061,6062,6063" + }, + { + "examine": "A stand for hats.", + "ids": "6064" + }, + { + "examine": "Some dwarf clothes that are obviously too small for me!", + "ids": "6065" + }, + { + "examine": "An empty weapon rack.", + "ids": "6066" + }, + { + "examine": "A weapon rack.", + "ids": "6067,6068,6069" + }, + { + "examine": "A method of dwarf storage", + "ids": "6070" + }, + { + "examine": "A method of dwarf storage.", + "ids": "6071,6072,6073,6074" + }, + { + "examine": "Useful for a dwarf.", + "ids": "6075" + }, + { + "examine": "A big desk, for a dwarf!", + "ids": "6076,6077,6078,6079" + }, + { + "examine": "Spins yarn.", + "ids": "6080" + }, + { + "examine": "Banking transactions are processed here.", + "ids": "6081" + }, + { + "examine": "Banking transactions are recorded here.", + "ids": "6082,37159" + }, + { + "examine": "This booth is closed.", + "ids": "6083" + }, + { + "examine": "The bank teller will serve you from here.", + "ids": "6084" + }, + { + "examine": "A way upwards.", + "ids": "6085" + }, + { + "examine": "A way down.", + "ids": "6086" + }, + { + "examine": "A way upwards.", + "ids": "6087" + }, + { + "examine": "A way down.", + "ids": "6088" + }, + { + "examine": "A way upwards.", + "ids": "6089" + }, + { + "examine": "A way down.", + "ids": "6090" + }, + { + "examine": "A treasure trove of knowledge.", + "ids": "6091,6092" + }, + { + "examine": "A lovely place to cook meat.", + "ids": "6093,6094,6095" + }, + { + "examine": "A great place to cook meat.", + "ids": "6096" + }, + { + "examine": "A good source of water.", + "ids": "6097,6098,6099" + }, + { + "examine": "The door is closed.", + "ids": "6100" + }, + { + "examine": "The door is open.", + "ids": "6101" + }, + { + "examine": "The door is closed.", + "ids": "6102" + }, + { + "examine": "The door is open.", + "ids": "6103" + }, + { + "examine": "The door is closed.", + "ids": "6104" + }, + { + "examine": "The door is open.", + "ids": "6105" + }, + { + "examine": "The door is closed.", + "ids": "6106" + }, + { + "examine": "The door is open.", + "ids": "6107" + }, + { + "examine": "The door is closed.", + "ids": "6108" + }, + { + "examine": "The door is open.", + "ids": "6109" + }, + { + "examine": "The door is closed.", + "ids": "6110" + }, + { + "examine": "The door is open.", + "ids": "6111" + }, + { + "examine": "The door is closed.", + "ids": "6112" + }, + { + "examine": "The door is open.", + "ids": "6113" + }, + { + "examine": "The door is closed.", + "ids": "6114" + }, + { + "examine": "The door is open.", + "ids": "6115,6116,6117,6118,6119,6120,6121,6122,6123,6124,6125,6126,6127,6128,6129,6130,6131,6132,6133,6134,6135,6136,6137,6138,6139,6140,6141,6142,6143,6144,6145" + }, + { + "examine": "Useful for keeping birds.", + "ids": "6146" + }, + { + "examine": "Tower of rock.", + "ids": "6147,6148,6149" + }, + { + "examine": "Useful for making weapons.", + "ids": "6150" + }, + { + "examine": "Used for getting water.", + "ids": "6151" + }, + { + "examine": "Used for getting drunk.", + "ids": "6152,6153" + }, + { + "examine": "Used for storage.", + "ids": "6154,6155,6156,6157" + }, + { + "examine": "Not good for eating.", + "ids": "6158,6159,6160,6161" + }, + { + "examine": "Finest precious stones.", + "ids": "6162" + }, + { + "examine": "Bread and cakes are spread out over it.", + "ids": "6163" + }, + { + "examine": "Finely wrought wares of silver.", + "ids": "6164" + }, + { + "examine": "I can get clothes made up from this stall.", + "ids": "6165" + }, + { + "examine": "A whole lot of tools for crafting.", + "ids": "6166,6167,6168,6169,6170,6171,6172" + }, + { + "examine": "A fine piece of sculpting.", + "ids": "6173,6174,6175" + }, + { + "examine": "Oblong boxes. You hope there isn't anything other than salt inside.", + "ids": "6176" + }, + { + "examine": "Big mysterious crates. You wonder what could be inside.", + "ids": "6177" + }, + { + "examine": "Wooden crates, contents unknown.", + "ids": "6178" + }, + { + "examine": "They could do with a wash.", + "ids": "6179,6180" + }, + { + "examine": "Dead animal parts dangling!", + "ids": "6181" + }, + { + "examine": "Dead meat. Dangling from the wall. Looks delicious.", + "ids": "6182" + }, + { + "examine": "It looks as hard as a rock, not very inviting.", + "ids": "6183" + }, + { + "examine": "A smelly old mattress.", + "ids": "6184" + }, + { + "examine": "Metal plating to protect the dwarf.", + "ids": "6185,6186" + }, + { + "examine": "Useful... for a dwarf!", + "ids": "6187" + }, + { + "examine": "Various implements for working with metal.", + "ids": "6188" + }, + { + "examine": "A hot place for forging things in.", + "ids": "6189,6190" + }, + { + "examine": "Being repaired.", + "ids": "6191,6192" + }, + { + "examine": "I look shorter, but not necessarily sweeter!", + "ids": "6193" + }, + { + "examine": "Used for sitting.", + "ids": "6194,6195" + }, + { + "examine": "Useful for a dwarf.", + "ids": "6196,6197,6198,6199" + }, + { + "examine": "Fit for a dwarven feast!", + "ids": "6200,6201" + }, + { + "examine": "Gives out light, but then you knew that already.", + "ids": "6202,6203" + }, + { + "examine": "A simple place to sleep.", + "ids": "6204" + }, + { + "examine": "A good dwarven bed. Too small for me!", + "ids": "6205" + }, + { + "examine": "Many important meetings are held here...", + "ids": "6206" + }, + { + "examine": "Draped in cloth.", + "ids": "6207" + }, + { + "examine": "A beautiful seat, fit for a King.", + "ids": "6208,6209,6210" + }, + { + "examine": "A dwarf table with chopping board.", + "ids": "6211" + }, + { + "examine": "This tree has been cut down.", + "ids": "6212" + }, + { + "examine": "A barrel full of ranging equipment...", + "ids": "6213,6214,6215,6216,6217,6218,6219,6220,6221,6222,6223,6224,6225,6226,6227,6228,6229" + }, + { + "examine": "I suppose he wants my money.", + "ids": "6230" + }, + { + "examine": "A lovely table.", + "ids": "6231" + }, + { + "examine": "An expensive water feature.", + "ids": "6232,6233,6234,6235" + }, + { + "examine": "Stop for what, food?", + "ids": "6236" + }, + { + "examine": "Yellow blossom, lovely.", + "ids": "6237" + }, + { + "examine": "Closed.", + "ids": "6238" + }, + { + "examine": "Open.", + "ids": "6239" + }, + { + "examine": "Closed.", + "ids": "6240" + }, + { + "examine": "Open.", + "ids": "6241" + }, + { + "examine": "A stone staircase.", + "ids": "6242,6243,6244,6245" + }, + { + "examine": "Has upon it a beer, which I will not take for moral reasons.", + "ids": "6246,6247,6248" + }, + { + "examine": "No this is not a mirage!", + "ids": "6249" + }, + { + "examine": "It's a goldfish! No, wait, it's just a bed.", + "ids": "6250,6251,6252,6253,6254" + }, + { + "examine": "Animal feeder.", + "ids": "6255,6256" + }, + { + "examine": "Lovely... Fresh.", + "ids": "6257" + }, + { + "examine": "Dry dung.", + "ids": "6258" + }, + { + "examine": "Smelly.", + "ids": "6259" + }, + { + "examine": "I can climb down this.", + "ids": "6260" + }, + { + "examine": "I can climb this.", + "ids": "6261,6262" + }, + { + "examine": "Useful for pets.", + "ids": "6263" + }, + { + "examine": "Useful for keeping birds.", + "ids": "6264" + }, + { + "examine": "Bird cage.", + "ids": "6265,6266" + }, + { + "examine": "An empty cage, maybe the owner let the creature free... I do hope so.", + "ids": "6267" + }, + { + "examine": "Useful for pets.", + "ids": "6268,6269,6270,6271,6272,6273" + }, + { + "examine": "Lovely comfy looking big bed.", + "ids": "6274" + }, + { + "examine": "Laden with heaps of paper.", + "ids": "6275" + }, + { + "examine": "I don't know much about art, but I like this.", + "ids": "6276" + }, + { + "examine": "Look at the size of this cactus.", + "ids": "6277" + }, + { + "examine": "Don't you open that trapdoor!", + "ids": "6278" + }, + { + "examine": "There is a rope leading to the bottom of this smoke filled well.", + "ids": "6279" + }, + { + "examine": "I can climb this.", + "ids": "6280,6281" + }, + { + "examine": "A portal to another land?", + "ids": "6282" + }, + { + "examine": "Weird looking pillar.", + "ids": "6283,6284,6285,6286,6287,6288,6289,6290,6291" + }, + { + "examine": "Shelves filled with interesting books.", + "ids": "6292,6293" + }, + { + "examine": "A locked display case for valuable artefacts.", + "ids": "6294" + }, + { + "examine": "One of the sculptures is missing. Oh yes, that was me!", + "ids": "6295" + }, + { + "examine": "It looks like the demon didn't survive after all.", + "ids": "6296" + }, + { + "examine": "He looks old, older than me anyway.", + "ids": "6297" + }, + { + "examine": "I don't think he's going to make it.", + "ids": "6298" + }, + { + "examine": "I don't understand, why didn't he go back to Lumby?", + "ids": "6299,6300" + }, + { + "examine": "A throne encrusted with sparkling gems.", + "ids": "6301" + }, + { + "examine": "A throne from which you have removed the gems.", + "ids": "6302,6303,6304,6305,6306" + }, + { + "examine": "A statuette of a golem, facing right.", + "ids": "6307" + }, + { + "examine": "A statuette of a golem, facing left.", + "ids": "6308" + }, + { + "examine": "The statuette is missing from this alcove.", + "ids": "6309,6310" + }, + { + "examine": "Not good for eating.", + "ids": "6311" + }, + { + "examine": "I can climb this.", + "ids": "6312" + }, + { + "examine": "I can climb down this.", + "ids": "6313,6314,6315,6316,6317,6318,6319,6320,6321,6322" + }, + { + "examine": "A broken clay arm.", + "ids": "6323" + }, + { + "examine": "A clay foot.", + "ids": "6324" + }, + { + "examine": "Half a golem smashed and broken.", + "ids": "6325" + }, + { + "examine": "Smashed and half buried.", + "ids": "6326" + }, + { + "examine": "A device once used for making pottery.", + "ids": "6327" + }, + { + "examine": "Once upon a time this was used to make pottery.", + "ids": "6328" + }, + { + "examine": "Once upon a time this made clay hard.", + "ids": "6329" + }, + { + "examine": "There was a lot of pottery made here a long time ago.", + "ids": "6330" + }, + { + "examine": "A statue of a guy with a hammer.", + "ids": "6331" + }, + { + "examine": "A weathered old statue.", + "ids": "6332" + }, + { + "examine": "A reclining lady.", + "ids": "6333" + }, + { + "examine": "This statue has been tampered with.", + "ids": "6334" + }, + { + "examine": "Contains a statue of a woman.", + "ids": "6335,6336,6337" + }, + { + "examine": "Empty.", + "ids": "6338,6339,6340,6341,6342,6343,6344,6345,6346,6347,6348,6349,6350,6351,6352,6353,6354,6355,6356,6357,6358,6359,6360,6361,6362" + }, + { + "examine": "A very heavy stone door.", + "ids": "6363" + }, + { + "examine": "A door to a demon's lair?", + "ids": "6364,6365,6366,6367,6368,6369,6370,6371" + }, + { + "examine": "A stone staircase.", + "ids": "6372,6373,6374,6375,6376,6377,6378,6379,6380" + }, + { + "examine": "A source of water for the river Elid.", + "ids": "6381" + }, + { + "examine": "Maybe I could swing on this somehow...", + "ids": "6382,6383,6384,6385,6386,6387,6388,6389,6390,6391,6392,6393,6394,6395,6396,6397,6398,6399,6400,6401" + }, + { + "examine": "A limestone ceiling growth.", + "ids": "6402" + }, + { + "examine": "A tooth shaped rock formation protruding from the floor.", + "ids": "6403" + }, + { + "examine": "An old mystical torch.", + "ids": "6404,6405,6406,6407,6408,6409,6410,6411,6412,6413,6414,6415,6416,6417" + }, + { + "examine": "I can climb this.", + "ids": "6418,6419" + }, + { + "examine": "I wonder what's inside?", + "ids": "6420,6421,6422" + }, + { + "examine": "A magical aura seems to shimmer over the glass...", + "ids": "6423,6424,6425,6426,6427,6428,6429,6430,6431,6432,6433" + }, + { + "examine": "I wonder what that's there for...", + "ids": "6434,6435" + }, + { + "examine": "I can climb this.", + "ids": "6436" + }, + { + "examine": "An ancient looking tomb.", + "ids": "6437,6438" + }, + { + "examine": "Climb this rope to go up.", + "ids": "6439,6440" + }, + { + "examine": "Looks like a small cave.", + "ids": "6441" + }, + { + "examine": "Blocked by an icicle.", + "ids": "6442" + }, + { + "examine": "Blocked by two icicles.", + "ids": "6443" + }, + { + "examine": "Blocked by three icicles.", + "ids": "6444" + }, + { + "examine": "Blocked by four icicles.", + "ids": "6445" + }, + { + "examine": "Blocked by five icicles.", + "ids": "6446" + }, + { + "examine": "Looks like a small cave.", + "ids": "6447" + }, + { + "examine": "It looks very sturdy.", + "ids": "6448,6449" + }, + { + "examine": "I can climb this.", + "ids": "6450" + }, + { + "examine": "A wrought iron gate.", + "ids": "6451,6452,6453" + }, + { + "examine": "Even rocks could freeze in this cold!", + "ids": "6454" + }, + { + "examine": "Looks slippery.", + "ids": "6455,6456,6457,6458,6459,6460" + }, + { + "examine": "An ice gate.", + "ids": "6461,6462,6463,6464,6465,6466,6467,6468,6469,6470,6471" + }, + { + "examine": "Chunky pieces of ice.", + "ids": "6472,6473,6474,6475,6476,6477,6478,6479,6480" + }, + { + "examine": "A mysterious tunnel-like structure.", + "ids": "6481,6482" + }, + { + "examine": "You can feel a mysterious power emanating from it...", + "ids": "6483,6484,6485,6486,6487,6488,6489,6490,6491,6492,6493" + }, + { + "examine": "This door is sealed by an ancient mystical power...", + "ids": "6494,6495,6496" + }, + { + "examine": "I can climb down this.", + "ids": "6497,6498,6499,6500" + }, + { + "examine": "I can climb this.", + "ids": "6501,6502,6503,6504,6505,6506,6507,6508,6509,6510,6511" + }, + { + "examine": "A fancy name for a coffin.", + "ids": "6512" + }, + { + "examine": "A strange thing to leave lying around...", + "ids": "6513" + }, + { + "examine": "I hope this is just ornamental...", + "ids": "6514,6515,6516,6517,6518,6519,6520" + }, + { + "examine": "Uh-oh!", + "ids": "6521,6522" + }, + { + "examine": "This leads downwards.", + "ids": "6523" + }, + { + "examine": "You can see a small fissure in the ground here.", + "ids": "6524,6525,6526,6527,6528,6529,6530,6531,6532,6533,6534,6535,6536,6537" + }, + { + "examine": "The body of a lion, the head of a man?", + "ids": "6538,6539,6540,6541,6542,6543,6544" + }, + { + "examine": "A smooth, sandstone door that is slightly warm to the touch.", + "ids": "6545,6546,6547,6548" + }, + { + "examine": "A well down into the pyramid.", + "ids": "6549,6550" + }, + { + "examine": "A portal that leads you out of the pyramid.", + "ids": "6551" + }, + { + "examine": "A mysterious ancient altar to some forgotten god...", + "ids": "6552" + }, + { + "examine": "Opens into another area.", + "ids": "6553,6554,6555,6556,6557,6558,6559,6560" + }, + { + "examine": "A ladder that's almost not there at all...", + "ids": "6561,6562,6563,6564,6565" + }, + { + "examine": "Gate like?", + "ids": "6566,6567" + }, + { + "examine": "Garments for the discerning.", + "ids": "6568" + }, + { + "examine": "Gone-off bread, cakes and pastries.", + "ids": "6569" + }, + { + "examine": "Finest precious stones.", + "ids": "6570" + }, + { + "examine": "These will keep you warm.", + "ids": "6571" + }, + { + "examine": "The spice is right.", + "ids": "6572" + }, + { + "examine": "An empty market stall.", + "ids": "6573" + }, + { + "examine": "Fine brews from exotic regions.", + "ids": "6574" + }, + { + "examine": "Best used with a horse.", + "ids": "6575,6576,6577" + }, + { + "examine": "Grows a yellow fruit.", + "ids": "6578,6579,6580" + }, + { + "examine": "A way to get in the tent.", + "ids": "6581,6582,6583,6584,6585,6586,6587,6588,6589,6590,6591,6592,6593,6594,6595,6596,6597,6598,6599,6600,6601,6602,6603,6604" + }, + { + "examine": "Wet and salty.", + "ids": "6605" + }, + { + "examine": "The focus of the suntrap.", + "ids": "6606" + }, + { + "examine": "A shiny mirror.", + "ids": "6607,6608,6609,6610,6611,6612,6613" + }, + { + "examine": "A large door with a hieroglyph of a cat.", + "ids": "6614" + }, + { + "examine": "Gate like?", + "ids": "6615,6616,6617,6618,6619" + }, + { + "examine": "It looks like a hole in the wall.", + "ids": "6620,6621" + }, + { + "examine": "Rocky.", + "ids": "6622" + }, + { + "examine": "An entrance into a tunnel. I wonder where it leads to.", + "ids": "6623" + }, + { + "examine": "It looks like a door.", + "ids": "6624" + }, + { + "examine": "Hmm. A door.", + "ids": "6625" + }, + { + "examine": "A big wooden door.", + "ids": "6626,6627,6628" + }, + { + "examine": "That could hurt.", + "ids": "6629" + }, + { + "examine": "A strange thing to leave lying around...", + "ids": "6630,6631" + }, + { + "examine": "I can't see the bottom.", + "ids": "6632,6633,6634" + }, + { + "examine": "Has a lid shaped like a man. I think it contains someone's liver. Yuck.", + "ids": "6635,6636" + }, + { + "examine": "Has a lid shaped like a crocodile. Yuck, I think there are lungs inside.", + "ids": "6637,6638" + }, + { + "examine": "Has a lid shaped like a bug. Disgusting! I think there's a stomach inside.", + "ids": "6639,6640" + }, + { + "examine": "Has a lid shaped like an ape. Eeew! I think it contains someone's intestines.", + "ids": "6641" + }, + { + "examine": "Doorway*Opens into another area, come on, I know this.", + "ids": "6642" + }, + { + "examine": "Useful for putting things on.", + "ids": "6644" + }, + { + "examine": "A ladder!! Never seen one of those before.", + "ids": "6645" + }, + { + "examine": "I wonder what's inside.", + "ids": "6646" + }, + { + "examine": "Perhaps I should search it.", + "ids": "6647" + }, + { + "examine": "I wonder where this goes?", + "ids": "6648" + }, + { + "examine": "They go down.", + "ids": "6649" + }, + { + "examine": "Phew!! That's one big bridge.", + "ids": "6650" + }, + { + "examine": "A big bridge over the river.", + "ids": "6651,6652" + }, + { + "examine": "Wow. More bridge. Awesome.", + "ids": "6653,6654" + }, + { + "examine": "Oops.", + "ids": "6655" + }, + { + "examine": "Rolls of colourful cloth.", + "ids": "6656" + }, + { + "examine": "An ancient giant serpent.", + "ids": "6657" + }, + { + "examine": "A tunnel leading upwards.", + "ids": "6658" + }, + { + "examine": "A tunnel leading into the depths of the earth.", + "ids": "6659" + }, + { + "examine": "A rock wall infused with the power of Guthix.", + "ids": "6660" + }, + { + "examine": "The wall is weeping blue tears.", + "ids": "6661" + }, + { + "examine": "The wall is weeping green tears.", + "ids": "6662" + }, + { + "examine": "The wall is not weeping at the moment.", + "ids": "6663,6664" + }, + { + "examine": "The wall is weeping blue tears.", + "ids": "6665" + }, + { + "examine": "The wall is weeping green tears.", + "ids": "6666" + }, + { + "examine": "The wall is not weeping at the moment.", + "ids": "6667,6668" + }, + { + "examine": "Stone with blue veins.", + "ids": "6669,6670,6671" + }, + { + "examine": "They don't look too easy to climb.", + "ids": "6672" + }, + { + "examine": "I could climb these.", + "ids": "6673,6674,6675,6676,6677,6678,6679,6680,6681,6682,6683,6684,6685,6686,6687,6688,6689,6690,6691,6692,6693,6694,6695,6696,6697,6698,6699,6700,6701" + }, + { + "examine": "I can climb these stairs.", + "ids": "6702,6703,6704,6705,6706,6707" + }, + { + "examine": "I can climb this.", + "ids": "6708,6709,6710,6711,6712" + }, + { + "examine": "I wonder what is awaiting me on the other side?", + "ids": "6713,6714,6715,6716,6717,6718,6719,6720,6721,6722,6723,6724,6725,6726,6727,6728,6729,6730,6731" + }, + { + "examine": "I wonder what awaits me on the other side?", + "ids": "6732,6733,6734,6735,6736,6737,6738,6739,6740,6741,6742,6743,6744,6745,6746,6747,6748,6749,6750,6751,6752,6753,6754,6755,6756,6757,6758,6759,6760,6761,6762,6763,6764,6765,6766" + }, + { + "examine": "A crude torch stuck in the ground.", + "ids": "6767,6768,6769,6770" + }, + { + "examine": "A large stone coffin.", + "ids": "6771,6772,6773" + }, + { + "examine": "A large stone chest.", + "ids": "6774,6775" + }, + { + "examine": "Looks like he's been dead a while now...", + "ids": "6776" + }, + { + "examine": "I don't think he'd mind us checking for his wallet now...", + "ids": "6777" + }, + { + "examine": "I'm sure he died of natural causes. Like a massive dragon or something...", + "ids": "6778,6779,6780,6781,6782,6783,6784,6785,6786,6787,6788,6789,6790" + }, + { + "examine": "The groundskeeper's bed.", + "ids": "6791,6792,6793,6794,6795,6796,6797,6798,6799,6800,6801,6802,6803,6804,6805,6806,6807,6808,6809,6810,6811,6812,6813,6814,6815,6816,6817,6818,6819,6820" + }, + { + "examine": "A large stone coffin.", + "ids": "6821,6822,6823" + }, + { + "examine": "It's locked.", + "ids": "6824,6825,6826" + }, + { + "examine": "It might still work...", + "ids": "6827,6828,6829,6830,6831,6832,6833,6834" + }, + { + "examine": "Danger... weak surface beyond gate. Digging may lead to cave-ins.", + "ids": "6835" + }, + { + "examine": "Sturdy metal bars.", + "ids": "6836,6837,6838" + }, + { + "examine": "Smells pretty bad!", + "ids": "6839" + }, + { + "examine": "It looks as this is where some wall fungus used to be.", + "ids": "6840" + }, + { + "examine": "Some crude stone steps.", + "ids": "6841,6842,6843" + }, + { + "examine": "An old crude tomb.", + "ids": "6844,6845" + }, + { + "examine": "It's damaged.", + "ids": "6846" + }, + { + "examine": "A note says, 'Please ring for attention.'", + "ids": "6847" + }, + { + "examine": "An old crude tomb.", + "ids": "6848" + }, + { + "examine": "'Leave da dead-uns boxes 'lone or else ya goes down da 'ole'", + "ids": "6849" + }, + { + "examine": "An old crude tomb.", + "ids": "6850" + }, + { + "examine": "This coffin is spilt over the floor.", + "ids": "6851" + }, + { + "examine": "This coffin is open.", + "ids": "6852" + }, + { + "examine": "An old crude tomb.", + "ids": "6853" + }, + { + "examine": "This coffin is spilt over the floor.", + "ids": "6854" + }, + { + "examine": "This coffin is open.", + "ids": "6855" + }, + { + "examine": "A barricade made from skulls and bones.", + "ids": "6856,6857,6858,6859,6860,6861,6862,6863,6864" + }, + { + "examine": "Not very high.", + "ids": "6865" + }, + { + "examine": "Hot stuff.", + "ids": "6866" + }, + { + "examine": "Ogres bang these to make noise.", + "ids": "6867,6868,6869,6870" + }, + { + "examine": "A bulky door made from solid rock.", + "ids": "6871,6872,6873,6874" + }, + { + "examine": "These open and close!", + "ids": "6875" + }, + { + "examine": "This may be worth opening.", + "ids": "6876" + }, + { + "examine": "I wonder what this item contains.", + "ids": "6877,6878,6879" + }, + { + "examine": "A barricade made of skulls and bones.", + "ids": "6880" + }, + { + "examine": "A barricade made of skulls and bones which has been crushed.", + "ids": "6881,6882" + }, + { + "examine": "An old crude tomb.", + "ids": "6883,6884,6885,6886,6887" + }, + { + "examine": "A sick, frail old man.", + "ids": "6888" + }, + { + "examine": "A sick, frail old man", + "ids": "6889" + }, + { + "examine": "An old crude tomb.", + "ids": "6890,6891,6892" + }, + { + "examine": "I don't think he'd mind us checking for his wallet now...", + "ids": "6893" + }, + { + "examine": "A good source of books!", + "ids": "6894,6895" + }, + { + "examine": "A crude torch stuck in the ground.", + "ids": "6896" + }, + { + "examine": "A strange ogre plinth, this must be where the artifacts are stored.", + "ids": "6897,6898,6899,6900,6901,6902" + }, + { + "examine": "It looks like the hole in the wall has been blocked with rubble.", + "ids": "6903" + }, + { + "examine": "How exciting, some shelves.", + "ids": "6904" + }, + { + "examine": "A hole in the wall.", + "ids": "6905,6906,6907,6908" + }, + { + "examine": "A rock wall.", + "ids": "6909" + }, + { + "examine": "It has a letter 'S' on the lock.", + "ids": "6910" + }, + { + "examine": "Used for storage.", + "ids": "6911" + }, + { + "examine": "A narrow hole in the wall.", + "ids": "6912,6913,6914" + }, + { + "examine": "Rubble is blocking the passage.", + "ids": "6915" + }, + { + "examine": "A good source of books!", + "ids": "6916,6917,6918" + }, + { + "examine": "A heavy portal decorated with bone.", + "ids": "6919,6920" + }, + { + "examine": "A symbol is carved into the wall here.", + "ids": "6921,6922,6923,6924,6925,6926" + }, + { + "examine": "I don't think I can get through this way!", + "ids": "6927" + }, + { + "examine": "Looks like its no longer operational.", + "ids": "6928" + }, + { + "examine": "Big bones are being used to prop up the wall.", + "ids": "6929,6930" + }, + { + "examine": "It's a bit like walking through a giant rib cage.", + "ids": "6931,6932,6933,6934,6935,6936,6937,6938" + }, + { + "examine": "This arch is broken. I hope the ceiling doesn't come down!", + "ids": "6939,6940,6941,6942" + }, + { + "examine": "A rocky outcrop.", + "ids": "6943,6944,6945,6946,6947,6948,6949" + }, + { + "examine": "I dont think i can get through this way.", + "ids": "6950" + }, + { + "examine": "An eye-wrenching nexus of utter negation!", + "ids": "6951,6952,6953,6954,6955,6956,6957,6958,6959,6960,6961,6962,6963,6964,6965,6966,6967,6968" + }, + { + "examine": "A dirty little swamp boat.", + "ids": "6969,6970" + }, + { + "examine": "It looks dark down there.", + "ids": "6971" + }, + { + "examine": "A book sits on top.", + "ids": "6972,6973,6974" + }, + { + "examine": "The door is closed.", + "ids": "6975" + }, + { + "examine": "The door is open.", + "ids": "6976" + }, + { + "examine": "The door is closed.", + "ids": "6977" + }, + { + "examine": "The door is open.", + "ids": "6978,6979,6980,6981,6982,6983" + }, + { + "examine": "Empty market stall.", + "ids": "6984" + }, + { + "examine": "A steam powered crushing machine.", + "ids": "6985,6986,6987,6988,6989,6990,6991,6992,6993,6994,6995,6996,6997,6998,6999,7000,7001" + }, + { + "examine": "A dwarven statue crumbling away from old age.", + "ids": "7002" + }, + { + "examine": "It's crumbling away from old age, it's hardly recognizable as a dwarf.", + "ids": "7003" + }, + { + "examine": "This stone dwarf must be guarding the way into a dwarven area!", + "ids": "7004,7005" + }, + { + "examine": "Big. For a dwarf!", + "ids": "7006,7007" + }, + { + "examine": "A work in progress.", + "ids": "7008,7009" + }, + { + "examine": "A work that has yet to begin.", + "ids": "7010" + }, + { + "examine": "An underground limpwurt plant.", + "ids": "7011,7012" + }, + { + "examine": "Insect eating plant.", + "ids": "7013,7014,7015" + }, + { + "examine": "A stone carved Pillar.", + "ids": "7016,7017" + }, + { + "examine": "Dwarf storage.", + "ids": "7018" + }, + { + "examine": "Used for keeping beer or glasses.", + "ids": "7019,7020,7021" + }, + { + "examine": "Tracks for the carts to run over.", + "ids": "7022,7023,7024,7025,7026" + }, + { + "examine": "A steam powered cart.", + "ids": "7027,7028,7029,7030,7031" + }, + { + "examine": "A fine piece of sculpting.", + "ids": "7032,7033,7034,7035,7036,7037,7038,7039,7040,7041,7042,7043" + }, + { + "examine": "Keeps mine carts from rolling away.", + "ids": "7044,7045,7046,7047,7048" + }, + { + "examine": "A wooden gate.", + "ids": "7049,7050,7051,7052" + }, + { + "examine": "Lots of seeds here.", + "ids": "7053,7054,7055" + }, + { + "examine": "I can climb down these stairs.", + "ids": "7056" + }, + { + "examine": "I can climb up these stairs.", + "ids": "7057" + }, + { + "examine": "Filled to the brim with knowledge.", + "ids": "7058,7059,7060,7061,7062,7063,7064,7065,7066,7067,7068,7069,7070,7071,7072,7073,7074,7075,7076,7077,7078,7079,7080,7081,7082,7083,7084,7085,7086,7087,7088,7089" + }, + { + "examine": "'You are here.'", + "ids": "7090" + }, + { + "examine": "Lots of hard study has been done here.", + "ids": "7091" + }, + { + "examine": "A telescope pointing southwards...", + "ids": "7092,7093,7094,7095" + }, + { + "examine": "A map of some ancient land.", + "ids": "7096" + }, + { + "examine": "There are plenty of shelves", + "ids": "7097" + }, + { + "examine": "Maybe it shows the location of buried treasure?", + "ids": "7098" + }, + { + "examine": "Old songs, old stories...", + "ids": "7099" + }, + { + "examine": "Armour of a Saradominist warrior. Decorative, but still effective.", + "ids": "7100" + }, + { + "examine": "A cape from Saradomin, suitable for a battle-mage.", + "ids": "7101" + }, + { + "examine": "A staff as used by Saradominist magi.", + "ids": "7102" + }, + { + "examine": "There is a powerful presence about these ruins...", + "ids": "7103,7104,7105,7106,7107,7108,7109,7110,7111,7112,7113,7114,7115,7116,7117,7118,7119,7120,7121,7122,7123,7124,7125,7126,7127,7128" + }, + { + "examine": "A tear in the dimensional weave of the Abyss.", + "ids": "7129,7130,7131,7132,7133,7134,7135,7136,7137,7138,7139,7140,7141,7142,7143,7144,7145,7146,7147,7148,7149,7150,7151,7152,7153" + }, + { + "examine": "A tunnel through the abyss.", + "ids": "7154,7155" + }, + { + "examine": "This seems to be blocking the exit...", + "ids": "7156,7157" + }, + { + "examine": "I could probably break this up with a pickaxe.", + "ids": "7158" + }, + { + "examine": "I could probably break this up with a pickaxe. Oh wait, I just did.", + "ids": "7159" + }, + { + "examine": "Pickaxe power!", + "ids": "7160" + }, + { + "examine": "They don't look that solid, an axe could help me chop them down.", + "ids": "7161,7162" + }, + { + "examine": "I cannot tell a lie. I chopped them down.", + "ids": "7163" + }, + { + "examine": "If I'm agile enough I might be able to squeeze through...", + "ids": "7164" + }, + { + "examine": "I could probably burn this away with a tinderbox.", + "ids": "7165" + }, + { + "examine": "I could probably burn this with fire.", + "ids": "7166" + }, + { + "examine": "Burnt open.", + "ids": "7167" + }, + { + "examine": "I could probably distract these with thievery.", + "ids": "7168,7169,7170" + }, + { + "examine": "An unstable portal across the dimensions...", + "ids": "7171,7172,7173,7174,7175,7176,7177,7178,7179,7180,7181,7182,7183,7184,7185,7186,7187,7188" + }, + { + "examine": "Abyssal Tendrils.", + "ids": "7189,7190,7191,7192,7193,7194,7195,7196,7197,7198,7199,7200,7201,7202,7203,7204,7205" + }, + { + "examine": "An opening into the crumbling wall.", + "ids": "7219,7220" + }, + { + "examine": "This leads downwards.", + "ids": "7221" + }, + { + "examine": "This way to the viewing gallery.", + "ids": "7222,7223" + }, + { + "examine": "I'll never be able to dodge that!", + "ids": "7224" + }, + { + "examine": "It's a wall...", + "ids": "7225,7226" + }, + { + "examine": "It's the floor...", + "ids": "7227" + }, + { + "examine": "It's a wall...", + "ids": "7228,7229" + }, + { + "examine": "It's the floor...", + "ids": "7230" + }, + { + "examine": "Not your average door...", + "ids": "7231,7232,7233,7234,7235" + }, + { + "examine": "I wonder what's inside.", + "ids": "7236,7237,7238" + }, + { + "examine": "It's a long way down...", + "ids": "7239,7240" + }, + { + "examine": "That's going to hurt if it hits me!", + "ids": "7241" + }, + { + "examine": "If only I knew Karate...", + "ids": "7242,7243,7244" + }, + { + "examine": "It's the floor...", + "ids": "7245" + }, + { + "examine": "Locked.", + "ids": "7246,7247" + }, + { + "examine": "It's a wall...", + "ids": "7248,7249" + }, + { + "examine": "It's the floor...", + "ids": "7250" + }, + { + "examine": "Bend your way through.", + "ids": "7251" + }, + { + "examine": "That could really hurt!", + "ids": "7252" + }, + { + "examine": "I must not fear, fear is the little death that brings total oblivion.", + "ids": "7253" + }, + { + "examine": "Blocking my way back.", + "ids": "7254,7255,7256" + }, + { + "examine": "I wonder where it leads.", + "ids": "7257" + }, + { + "examine": "An opening into the crumbling wall.", + "ids": "7258" + }, + { + "examine": "This way to exit.", + "ids": "7259,7260,7261,7262,7263,7264,7265,7266,7267,7268,7269,7270,7271" + }, + { + "examine": "A mystical teleport.", + "ids": "7272,7273" + }, + { + "examine": "Lets me walk through walls...", + "ids": "7274,7275,7276" + }, + { + "examine": "He looks hungry, but I don't think he'll do anything while I'm here.", + "ids": "7277" + }, + { + "examine": "He's no longer looks hungry, although perhaps a little guilty-looking.", + "ids": "7278,7279,7280" + }, + { + "examine": "He's looking at the grain...", + "ids": "7281,7282,7283" + }, + { + "examine": "A sack full of grain.", + "ids": "7284" + }, + { + "examine": "I think the chicken enjoyed his meal...", + "ids": "7285" + }, + { + "examine": "It looks pretty rickety...", + "ids": "7286,7287" + }, + { + "examine": "A mystical teleport.", + "ids": "7288,7289,7290,7291,7292,7293,7294,7295,7296,7297,7298,7299,7300,7301" + }, + { + "examine": "Lets me walk through walls...", + "ids": "7302" + }, + { + "examine": "A gold statue of a famous White Knight.", + "ids": "7303" + }, + { + "examine": "A silver statue of a famous White Knight.", + "ids": "7304" + }, + { + "examine": "A bronze statue of a famous White Knight.", + "ids": "7305" + }, + { + "examine": "A gold statue of an ancient warrior.", + "ids": "7306" + }, + { + "examine": "A silver statue of an ancient warrior.", + "ids": "7307" + }, + { + "examine": "A bronze statue of an ancient warrior.", + "ids": "7308" + }, + { + "examine": "A gold statue of a famous warrior.", + "ids": "7309" + }, + { + "examine": "A silver statue of a famous warrior.", + "ids": "7310" + }, + { + "examine": "A bronze statue of a famous warrior.", + "ids": "7311" + }, + { + "examine": "A gold statue of an ancient White Knight.", + "ids": "7312" + }, + { + "examine": "A silver statue of an ancient White Knight.", + "ids": "7313" + }, + { + "examine": "A bronze statue of an ancient White Knight.", + "ids": "7314" + }, + { + "examine": "A mystical teleport.", + "ids": "7315,7316" + }, + { + "examine": "Lets me walk through walls...", + "ids": "7317" + }, + { + "examine": "A mystical teleport.", + "ids": "7318,7319" + }, + { + "examine": "Lets me walk through walls...", + "ids": "7320" + }, + { + "examine": "A mystical teleport.", + "ids": "7321,7322" + }, + { + "examine": "Lets me walk through walls...", + "ids": "7323" + }, + { + "examine": "A mystical teleport.", + "ids": "7324,7325" + }, + { + "examine": "Lets me walk through walls...", + "ids": "7326" + }, + { + "examine": "Filled to the brim with knowledge.", + "ids": "7327,7328,7329,7330" + }, + { + "examine": "Generally used for putting things on.", + "ids": "7331" + }, + { + "examine": "A table with a Bunsen burner on it.", + "ids": "7332" + }, + { + "examine": "There are some containers of chemicals here.", + "ids": "7333,7334,7335,7336,7337,7338,7339" + }, + { + "examine": "There's an empty vial here.", + "ids": "7340,7341,7342" + }, + { + "examine": "There's a small hole in the centre.", + "ids": "7343" + }, + { + "examine": "The spade is stuck in the hole.", + "ids": "7344" + }, + { + "examine": "The spade opened the door.", + "ids": "7345" + }, + { + "examine": "It's chained to the wall.", + "ids": "7346" + }, + { + "examine": "For storage.", + "ids": "7347,7348,7349" + }, + { + "examine": "I wonder what's inside.", + "ids": "7350" + }, + { + "examine": "Perhaps I should search it.", + "ids": "7351" + }, + { + "examine": "A mystical teleport.", + "ids": "7352,7353" + }, + { + "examine": "Lets me walk through walls...", + "ids": "7354" + }, + { + "examine": "Bridge will support a person carrying no more than 5 kg.", + "ids": "7355,7356,7357,7358,7359,7360,7361,7362,7363,7364,7365,7366,7367,7368,7369,7370,7371,7372" + }, + { + "examine": "Lets me walk through walls...", + "ids": "7373,7374,7375,7376,7377,7378,7379,7380,7381,7382,7383,7384" + }, + { + "examine": "Sit back and relax...", + "ids": "7388,7389" + }, + { + "examine": "Designed specifically to ruin your health.", + "ids": "7390" + }, + { + "examine": "A rolled up magic carpet.", + "ids": "7391" + }, + { + "examine": "A pile of rolled up magic carpets.", + "ids": "7392" + }, + { + "examine": "A little shaded area.", + "ids": "7393" + }, + { + "examine": "A magic carpet.", + "ids": "7394,7395" + }, + { + "examine": "The infamous carpet of '76.", + "ids": "7396" + }, + { + "examine": "A leafy tree.", + "ids": "7397,7398" + }, + { + "examine": "This is what is left of a willow tree.", + "ids": "7399" + }, + { + "examine": "This is what is left of a maple tree.", + "ids": "7400" + }, + { + "examine": "This is what is left of a magic tree.", + "ids": "7401" + }, + { + "examine": "This is what is left of a yew tree.", + "ids": "7402" + }, + { + "examine": "An empty barrel.", + "ids": "7403" + }, + { + "examine": "A barrel full of mushed apples.", + "ids": "7404,7405" + }, + { + "examine": "This tap runs from the apple crushing barrel.", + "ids": "7406" + }, + { + "examine": "An empty ale barrel.", + "ids": "7407" + }, + { + "examine": "A barrel of bad ale.", + "ids": "7408" + }, + { + "examine": "A barrel of unfermented liquid.", + "ids": "7409" + }, + { + "examine": "A barrel of bad cider.", + "ids": "7410" + }, + { + "examine": "A barrel of Dwarven Stout.", + "ids": "7411" + }, + { + "examine": "A barrel of mature Dwarven Stout.", + "ids": "7412" + }, + { + "examine": "A barrel of Asgarnian Ale.", + "ids": "7413" + }, + { + "examine": "A barrel of mature Asgarnian Ale.", + "ids": "7414" + }, + { + "examine": "A barrel of Greenmans Ale.", + "ids": "7415" + }, + { + "examine": "A barrel of mature Greenmans Ale.", + "ids": "7416" + }, + { + "examine": "A barrel of Wizards Mind Bomb.", + "ids": "7417" + }, + { + "examine": "A barrel of mature Wizards Mind Bomb.", + "ids": "7418" + }, + { + "examine": "A barrel of Dragon Bitter.", + "ids": "7419" + }, + { + "examine": "A barrel of mature Dragon Bitter.", + "ids": "7420" + }, + { + "examine": "A barrel of Moonlight Mead.", + "ids": "7421" + }, + { + "examine": "A barrel of mature Moonlight Mead.", + "ids": "7422" + }, + { + "examine": "A barrel of Axeman's Folly.", + "ids": "7423" + }, + { + "examine": "A barrel of mature Axeman's Folly.", + "ids": "7424" + }, + { + "examine": "A barrel of Chef's Delight.", + "ids": "7425" + }, + { + "examine": "A barrel of mature Chef's Delight.", + "ids": "7426" + }, + { + "examine": "A barrel of Slayer's Respite.", + "ids": "7427" + }, + { + "examine": "A barrel of mature Slayer's Respite.", + "ids": "7428" + }, + { + "examine": "A barrel of Cider.", + "ids": "7429" + }, + { + "examine": "A barrel of mature Cider.", + "ids": "7430,7431,7432" + }, + { + "examine": "Goes up and down!", + "ids": "7433" + }, + { + "examine": "I wonder what's under it?", + "ids": "7434" + }, + { + "examine": "I wonder what's down there?", + "ids": "7435" + }, + { + "examine": "A wooden barrel.", + "ids": "7436" + }, + { + "examine": "This vat is empty.", + "ids": "7437" + }, + { + "examine": "This vat is filled with water.", + "ids": "7438" + }, + { + "examine": "This vat is filled with bad ale.", + "ids": "7439" + }, + { + "examine": "This vat is filled with bad cider.", + "ids": "7440" + }, + { + "examine": "This vat contains a mixture of water and barley malt.", + "ids": "7441" + }, + { + "examine": "This controls the flow of ale to the barrel.", + "ids": "7442,7443" + }, + { + "examine": "This vat contains a mixture of water, barley malt, and Hammerstone hops.", + "ids": "7444" + }, + { + "examine": "Dwarven Stout is fermenting in this vat.", + "ids": "7445,7446" + }, + { + "examine": "This vat is filled with Dwarven Stout.", + "ids": "7447" + }, + { + "examine": "This vat is filled with mature Dwarven Stout.", + "ids": "7448" + }, + { + "examine": "This vat contains a mixture of water, barley malt, and Asgarnian hops.", + "ids": "7449" + }, + { + "examine": "Asgarnian Ale is fermenting in this vat.", + "ids": "7450,7451" + }, + { + "examine": "This vat is filled with Asgarnian Ale.", + "ids": "7452" + }, + { + "examine": "This vat is filled with mature Asgarnian Ale.", + "ids": "7453" + }, + { + "examine": "This vat contains a mixture of water, barley malt, and Harralander.", + "ids": "7454" + }, + { + "examine": "Greenmans Ale is fermenting in this vat.", + "ids": "7455,7456" + }, + { + "examine": "This vat is filled with Greenmans Ale.", + "ids": "7457" + }, + { + "examine": "This vat is filled with mature Greenmans Ale.", + "ids": "7458" + }, + { + "examine": "This vat contains a mixture of water, barley malt, and Yanillian hops.", + "ids": "7459" + }, + { + "examine": "Wizards Mind Bomb is fermenting in this vat.", + "ids": "7460,7461" + }, + { + "examine": "This vat is filled with Wizards Mind Bomb.", + "ids": "7462" + }, + { + "examine": "This vat is filled with mature Wizards Mind Bomb.", + "ids": "7463" + }, + { + "examine": "This vat contains a mixture of water, barley malt, and Krandorian hops.", + "ids": "7464" + }, + { + "examine": "Dragon Bitter is fermenting in this vat.", + "ids": "7465,7466" + }, + { + "examine": "This vat is filled with Dragon Bitter.", + "ids": "7467" + }, + { + "examine": "This vat is filled with mature Dragon Bitter.", + "ids": "7468" + }, + { + "examine": "This vat contains a mixture of water, barley malt, and Bittercap mushrooms.", + "ids": "7469" + }, + { + "examine": "Moonlight Mead is fermenting in this vat.", + "ids": "7470,7471" + }, + { + "examine": "This vat is filled with Moonlight Mead.", + "ids": "7472" + }, + { + "examine": "This vat is filled with mature Moonlight Mead.", + "ids": "7473" + }, + { + "examine": "This vat contains a mixture of water, barley malt, and oak roots.", + "ids": "7474" + }, + { + "examine": "Axeman's Folly is fermenting in this vat.", + "ids": "7475,7476" + }, + { + "examine": "This vat is filled with Axeman's Folly.", + "ids": "7477" + }, + { + "examine": "This vat is filled with mature Axeman's Folly.", + "ids": "7478" + }, + { + "examine": "This vat contains a mixture of water, barley malt, and chocolate dust.", + "ids": "7479" + }, + { + "examine": "Chef's Delight is fermenting in this vat.", + "ids": "7480,7481" + }, + { + "examine": "This vat is filled with Chef's Delight.", + "ids": "7482" + }, + { + "examine": "This vat is filled with mature Chef's Delight.", + "ids": "7483" + }, + { + "examine": "This vat contains a mixture of water, barley malt, and Wildblood hops.", + "ids": "7484" + }, + { + "examine": "Slayer's Respite is fermenting in this vat.", + "ids": "7485,7486" + }, + { + "examine": "This vat is filled with Slayer's Respite.", + "ids": "7487" + }, + { + "examine": "This vat is filled with mature Slayer's Respite.", + "ids": "7488" + }, + { + "examine": "This vat contains some apple mush.", + "ids": "7489" + }, + { + "examine": "Cider is fermenting in this vat.", + "ids": "7490,7491" + }, + { + "examine": "This vat is filled with cider.", + "ids": "7492" + }, + { + "examine": "This vat is filled with mature cider.", + "ids": "7493,7494,7495" + }, + { + "examine": "Items are for sale here.", + "ids": "7496,7497" + }, + { + "examine": "They're empty.", + "ids": "7498" + }, + { + "examine": "Farming stock is kept here.", + "ids": "7499,7500,7501,7502,7503" + }, + { + "examine": "For sitting.", + "ids": "7504,7505" + }, + { + "examine": "They're empty.", + "ids": "7506" + }, + { + "examine": "Farming stock is kept here.", + "ids": "7507,7508,7509,7510,7511" + }, + { + "examine": "A pair of sacks.", + "ids": "7512" + }, + { + "examine": "For storage.", + "ids": "7513,7514,7515" + }, + { + "examine": "A farmer's spade and rake.", + "ids": "7516,7517,7518,7519,7520,7521,7522,7523,7524,7525,7526" + }, + { + "examine": "I can climb over the fence with this.", + "ids": "7527" + }, + { + "examine": "For fermenting beer.", + "ids": "7528,7529,7530" + }, + { + "examine": "An ale barrel.", + "ids": "7531" + }, + { + "examine": "This controls the flow of ale to the barrel.", + "ids": "7532,7533,7534,7535,7536,7537,7538,7539,7540,7541,7542,7543,7544,7545,7546,7547,7548,7549,7550,7551,7552,7553,7554,7555,7556" + }, + { + "examine": "You can grow Deadly Nightshade in this Farming patch.", + "ids": "7557,7558,7559,7560" + }, + { + "examine": "Deadly Nightshade has been sown in this farming patch.", + "ids": "7561" + }, + { + "examine": "Deadly Nightshade is growing in this farming patch.", + "ids": "7562,7563,7564" + }, + { + "examine": "I wouldn't pick this with my bare hands.", + "ids": "7565" + }, + { + "examine": "This Deadly Nightshade has become diseased.", + "ids": "7566,7567,7568" + }, + { + "examine": "This Deadly Nightshade has died.", + "ids": "7569,7570,7571,7572" + }, + { + "examine": "You can grow bushes in this Farming patch.", + "ids": "7573,7574,7575,7576,7577,7578,7579,7580" + }, + { + "examine": "A cadavaberry bush is growing in this Farming patch.", + "ids": "7581,7582,7583,7584,7585,7586" + }, + { + "examine": "A fully grown cadavaberry bush.", + "ids": "7587,7588,7589,7590,7591,7592" + }, + { + "examine": "This diseased cadavaberry bush needs pruning.", + "ids": "7593,7594,7595,7596,7597,7598" + }, + { + "examine": "This cadavaberry bush has died.", + "ids": "7599,7600,7601,7602,7603,7604" + }, + { + "examine": "A dwellberry bush is growing in this Farming patch.", + "ids": "7605,7606,7607,7608,7609,7610,7611" + }, + { + "examine": "A fully grown dwellberry bush.", + "ids": "7612,7613,7614,7615,7616,7617" + }, + { + "examine": "This diseased dwellberry bush needs pruning.", + "ids": "7618,7619,7620,7621,7622,7623,7624" + }, + { + "examine": "This dwellberry bush has died.", + "ids": "7625,7626,7627,7628,7629,7630,7631" + }, + { + "examine": "A jangerberry bush is growing in this Farming patch.", + "ids": "7632,7633,7634,7635,7636,7637,7638,7639" + }, + { + "examine": "A fully grown jangerberry bush.", + "ids": "7640,7641,7642,7643,7644,7645" + }, + { + "examine": "This diseased jangerberry bush needs pruning.", + "ids": "7646,7647,7648,7649,7650,7651,7652,7653" + }, + { + "examine": "This jangerberry bush has died.", + "ids": "7654,7655,7656,7657,7658,7659,7660,7661" + }, + { + "examine": "A Poison Ivy bush is growing in this Farming patch.", + "ids": "7662,7663,7664,7665,7666,7667,7668,7669" + }, + { + "examine": "A fully grown Poison Ivy bush.", + "ids": "7670,7671,7672,7673,7674,7675" + }, + { + "examine": "This diseased Poison Ivy bush needs pruning.", + "ids": "7676,7677,7678,7679,7680,7681,7682,7683" + }, + { + "examine": "This Poison Ivy bush has died.", + "ids": "7684,7685,7686,7687,7688,7689,7690,7691" + }, + { + "examine": "A redberry bush is growing in this Farming patch.", + "ids": "7692,7693,7694,7695,7696" + }, + { + "examine": "A fully grown redberry bush.", + "ids": "7697,7698,7699,7700,7701,7702" + }, + { + "examine": "This diseased redberry bush needs pruning.", + "ids": "7703,7704,7705,7706,7707" + }, + { + "examine": "This redberry bush has died.", + "ids": "7708,7709,7710,7711,7712" + }, + { + "examine": "A whiteberry bush is growing in this Farming patch.", + "ids": "7713,7714,7715,7716,7717,7718,7719,7720" + }, + { + "examine": "A fully grown whiteberry bush.", + "ids": "7721,7722,7723,7724,7725,7726" + }, + { + "examine": "This diseased whiteberry bush needs pruning.", + "ids": "7727,7728,7729,7730,7731,7732,7733,7734" + }, + { + "examine": "This whiteberry bush has died.", + "ids": "7735,7736,7737,7738,7739,7740,7741,7742" + }, + { + "examine": "You can grow a Cactus in this Farming patch.", + "ids": "7743,7744,7745,7746" + }, + { + "examine": "Cactus seeds have been planted in this patch.", + "ids": "7747" + }, + { + "examine": "A cactus is growing in this patch.", + "ids": "7748,7749,7750,7751,7752,7753" + }, + { + "examine": "A fully-grown cactus.", + "ids": "7754,7755,7756,7757,7758" + }, + { + "examine": "This cactus has become diseased.", + "ids": "7759,7760,7761,7762,7763,7764" + }, + { + "examine": "This cactus has died.", + "ids": "7765,7766,7767,7768,7769,7770,7771" + }, + { + "examine": "You can grow a Calquat Tree in this Farming patch.", + "ids": "7772,7773,7774,7775" + }, + { + "examine": "A Calquat tree is growing in this Farming patch.", + "ids": "7776,7777,7778,7779,7780,7781,7782,7783" + }, + { + "examine": "A fully grown Calquat tree stands in this Farming patch.", + "ids": "7784,7785,7786,7787,7788,7789,7790,7791" + }, + { + "examine": "This diseased Calquat tree needs pruning.", + "ids": "7792,7793,7794,7795,7796,7797,7798" + }, + { + "examine": "This Calquat tree has died.", + "ids": "7799,7800,7801,7802,7803,7804,7805" + }, + { + "examine": "A Calquat tree stump.", + "ids": "7806,7807" + }, + { + "examine": "Turns vegetation into compost.", + "ids": "7808" + }, + { + "examine": "This compost bin contains compostable items.", + "ids": "7809" + }, + { + "examine": "This compost bin is full of compostable items.", + "ids": "7810" + }, + { + "examine": "This compost bin contains supercompostable items.", + "ids": "7811" + }, + { + "examine": "This compost bin is full of supercompostable items.", + "ids": "7812" + }, + { + "examine": "Turns vegetation into compost.", + "ids": "7813" + }, + { + "examine": "This compost bin contains compost.", + "ids": "7814" + }, + { + "examine": "This compost bin is full of compost.", + "ids": "7815" + }, + { + "examine": "This compost bin contains super compost.", + "ids": "7816" + }, + { + "examine": "This compost bin is full of super compost.", + "ids": "7817" + }, + { + "examine": "Turns vegetation into compost.", + "ids": "7818" + }, + { + "examine": "This compost bin contains compostable items.", + "ids": "7819" + }, + { + "examine": "This compost bin is full of compostable items.", + "ids": "7820" + }, + { + "examine": "This compost bin contains supercompostable items.", + "ids": "7821" + }, + { + "examine": "This compost bin is full of supercompostable items.", + "ids": "7822" + }, + { + "examine": "Turns vegetation into compost.", + "ids": "7823" + }, + { + "examine": "This compost bin contains compost.", + "ids": "7824" + }, + { + "examine": "This compost bin is full of compost.", + "ids": "7825" + }, + { + "examine": "This compost bin contains super compost.", + "ids": "7826" + }, + { + "examine": "This compost bin is full of super compost.", + "ids": "7827" + }, + { + "examine": "This compost bin contains tomatoes.", + "ids": "7828" + }, + { + "examine": "This compost bin is full of tomatoes.", + "ids": "7829" + }, + { + "examine": "This compost bin contains rotten tomatoes.", + "ids": "7830" + }, + { + "examine": "This compost bin is full of rotten tomatoes.", + "ids": "7831" + }, + { + "examine": "This compost bin contains tomatoes.", + "ids": "7832" + }, + { + "examine": "This compost bin is full of tomatoes.", + "ids": "7833" + }, + { + "examine": "This compost bin contains rotten tomatoes.", + "ids": "7834" + }, + { + "examine": "This compost bin is full of rotten tomatoes.", + "ids": "7835,7836,7837,7838,7839" + }, + { + "examine": "You can grow flowers in this Farming patch.", + "ids": "7840,7841,7842,7843,7844,7845,7846,7847,7848,7849,7850" + }, + { + "examine": "A limpwurt plant is growing in this patch.", + "ids": "7851,7852,7853,7854" + }, + { + "examine": "A fully grown limpwurt plant.", + "ids": "7855" + }, + { + "examine": "A limpwurt plant is growing in this patch.", + "ids": "7856,7857,7858,7859" + }, + { + "examine": "This limpwurt plant has become diseased.", + "ids": "7860,7861,7862" + }, + { + "examine": "This limpwurt plant has died while growing.", + "ids": "7863,7864,7865" + }, + { + "examine": "This limpwurt plant has died.", + "ids": "7866" + }, + { + "examine": "A marigold is growing in this patch.", + "ids": "7867,7868,7869,7870" + }, + { + "examine": "A fully grown marigold.", + "ids": "7871" + }, + { + "examine": "A marigold is growing in this patch.", + "ids": "7872,7873,7874,7875" + }, + { + "examine": "This marigold has become diseased.", + "ids": "7876,7877,7878" + }, + { + "examine": "This marigold has died while growing.", + "ids": "7879,7880,7881" + }, + { + "examine": "This marigold has died.", + "ids": "7882" + }, + { + "examine": "A nasturtium is growing in this patch.", + "ids": "7883,7884,7885,7886" + }, + { + "examine": "A fully grown nasturtium.", + "ids": "7887" + }, + { + "examine": "A nasturtium is growing in this patch.", + "ids": "7888,7889,7890,7891" + }, + { + "examine": "This nasturtium has become diseased.", + "ids": "7892,7893,7894" + }, + { + "examine": "This nasturtium has died while growing.", + "ids": "7895,7896,7897" + }, + { + "examine": "This nasturtium has died.", + "ids": "7898" + }, + { + "examine": "A rosemary is growing in this patch.", + "ids": "7899,7900,7901,7902" + }, + { + "examine": "A fully grown rosemary.", + "ids": "7903" + }, + { + "examine": "A rosemary is growing in this patch.", + "ids": "7904,7905,7906,7907" + }, + { + "examine": "This rosemary has become diseased.", + "ids": "7908,7909,7910" + }, + { + "examine": "This rosemary has died while growing.", + "ids": "7911,7912,7913" + }, + { + "examine": "This rosemary has died.", + "ids": "7914" + }, + { + "examine": "Should scare off the birds...", + "ids": "7915,7916,7917,7918" + }, + { + "examine": "A woad plant is growing in this patch.", + "ids": "7919,7920,7921,7922" + }, + { + "examine": "A fully grown woad plant.", + "ids": "7923" + }, + { + "examine": "A woad plant is growing in this patch.", + "ids": "7924,7925,7926,7927" + }, + { + "examine": "This woad plant has become diseased.", + "ids": "7928,7929,7930" + }, + { + "examine": "This woad plant has died while growing.", + "ids": "7931,7932,7933" + }, + { + "examine": "This woad plant has died.", + "ids": "7934" + }, + { + "examine": "An apple tree sapling has been planted in this fruit tree patch.", + "ids": "7935" + }, + { + "examine": "An apple tree is growing in this fruit tree patch.", + "ids": "7936,7937,7938,7939,7940" + }, + { + "examine": "A fully grown apple tree.", + "ids": "7941" + }, + { + "examine": "There is a single apple on this apple tree.", + "ids": "7942" + }, + { + "examine": "There are two apples on this apple tree.", + "ids": "7943" + }, + { + "examine": "There are three apples on this apple tree.", + "ids": "7944" + }, + { + "examine": "There are four apples on this apple tree.", + "ids": "7945" + }, + { + "examine": "There are five apples on this apple tree.", + "ids": "7946" + }, + { + "examine": "There are six apples on this apple tree.", + "ids": "7947" + }, + { + "examine": "A fully grown apple tree.", + "ids": "7948" + }, + { + "examine": "This diseased tree looks like it needs pruning with secateurs.", + "ids": "7949,7950,7951,7952,7953,7954" + }, + { + "examine": "This apple tree has become diseased and died.", + "ids": "7955,7956,7957,7958,7959,7960" + }, + { + "examine": "This apple tree has been cut down.", + "ids": "7961,7962,7963,7964,7965" + }, + { + "examine": "A pineapple plant has been planted in this fruit tree patch.", + "ids": "7966" + }, + { + "examine": "A pineapple plant is growing in this fruit tree patch.", + "ids": "7967,7968,7969,7970,7971" + }, + { + "examine": "A fully grown pineapple plant.", + "ids": "7972" + }, + { + "examine": "There is a single pineapple on this pineapple plant.", + "ids": "7973" + }, + { + "examine": "There are two pineapples on this pineapple plant.", + "ids": "7974" + }, + { + "examine": "There are three pineapples on this pineapple plant.", + "ids": "7975" + }, + { + "examine": "There are four pineapples on this pineapple plant.", + "ids": "7976" + }, + { + "examine": "There are five pineapples on this pineapple plant.", + "ids": "7977" + }, + { + "examine": "There are six pineapples on this pineapple plant.", + "ids": "7978" + }, + { + "examine": "A fully grown pineapple plant.", + "ids": "7979" + }, + { + "examine": "This pineapple plant looks like it could do with pruning with secateurs.", + "ids": "7980,7981,7982,7983,7984,7985" + }, + { + "examine": "This pineapple plant has become diseased and died.", + "ids": "7986,7987,7988,7989,7990,7991" + }, + { + "examine": "This pineapple plant has been cut down.", + "ids": "7992" + }, + { + "examine": "A banana tree sapling has been planted in this fruit tree patch.", + "ids": "7993" + }, + { + "examine": "A banana tree is growing in this fruit tree patch.", + "ids": "7994,7995,7996,7997,7998" + }, + { + "examine": "A fully grown banana tree.", + "ids": "7999,8000" + }, + { + "examine": "There is a single banana on this banana tree.", + "ids": "8001" + }, + { + "examine": "There are two bananas on this banana tree.", + "ids": "8002" + }, + { + "examine": "There are three bananas on this banana tree.", + "ids": "8003" + }, + { + "examine": "There are four bananas on this banana tree.", + "ids": "8004" + }, + { + "examine": "There are five bananas on this banana tree.", + "ids": "8005" + }, + { + "examine": "There are six bananas on this banana tree.", + "ids": "8006" + }, + { + "examine": "This banana looks like it could do with pruning with secateurs.", + "ids": "8007,8008,8009,8010,8011,8012" + }, + { + "examine": "This banana tree has become diseased and died.", + "ids": "8013,8014,8015,8016,8017,8018" + }, + { + "examine": "This banana tree has been cut down.", + "ids": "8019" + }, + { + "examine": "A curry tree sapling has been planted in this fruit tree patch.", + "ids": "8020" + }, + { + "examine": "A curry tree is growing in this fruit tree patch.", + "ids": "8021,8022,8023,8024,8025" + }, + { + "examine": "A fully grown curry tree.", + "ids": "8026" + }, + { + "examine": "There is a single curry leaf on this curry tree.", + "ids": "8027" + }, + { + "examine": "There are two curry leaves on this curry tree.", + "ids": "8028" + }, + { + "examine": "There are three curry leaves on this curry tree.", + "ids": "8029" + }, + { + "examine": "There are four curry leaves on this curry tree.", + "ids": "8030" + }, + { + "examine": "There are five curry leaves on this curry tree.", + "ids": "8031" + }, + { + "examine": "There are six curry leaves on this curry tree.", + "ids": "8032" + }, + { + "examine": "A fully grown curry tree.", + "ids": "8033" + }, + { + "examine": "This curry tree looks like it could do with pruning with secateurs.", + "ids": "8034,8035,8036,8037,8038,8039" + }, + { + "examine": "This curry tree has become diseased and died.", + "ids": "8040,8041,8042,8043,8044,8045" + }, + { + "examine": "This curry tree has been cut down.", + "ids": "8046" + }, + { + "examine": "You can grow Fruit Trees in this Farming patch.", + "ids": "8047,8048,8049,8050" + }, + { + "examine": "An orange tree sapling has been planted in this fruit tree patch.", + "ids": "8051" + }, + { + "examine": "An orange tree is growing in this fruit tree patch.", + "ids": "8052,8053,8054,8055,8056" + }, + { + "examine": "A fully grown orange tree.", + "ids": "8057" + }, + { + "examine": "There is a single orange on this orange tree.", + "ids": "8058" + }, + { + "examine": "There are two oranges on this orange tree.", + "ids": "8059" + }, + { + "examine": "There are three oranges on this orange tree.", + "ids": "8060" + }, + { + "examine": "There are four oranges on this orange tree.", + "ids": "8061" + }, + { + "examine": "There are five oranges on this orange tree.", + "ids": "8062" + }, + { + "examine": "There are six oranges on this orange tree.", + "ids": "8063" + }, + { + "examine": "A fully grown orange tree.", + "ids": "8064" + }, + { + "examine": "This orange tree looks like it could do with pruning with secateurs.", + "ids": "8065,8066,8067,8068,8069,8070" + }, + { + "examine": "This orange tree has become diseased and died.", + "ids": "8071,8072,8073,8074,8075,8076" + }, + { + "examine": "This orange tree has been cut down.", + "ids": "8077" + }, + { + "examine": "A palm tree sapling has been planted in this fruit tree patch.", + "ids": "8078" + }, + { + "examine": "A palm tree is growing in this fruit tree patch.", + "ids": "8079,8080,8081,8082,8083" + }, + { + "examine": "A fully grown palm tree.", + "ids": "8084" + }, + { + "examine": "There is a single coconut on this palm tree.", + "ids": "8085" + }, + { + "examine": "There are two coconuts on this palm tree.", + "ids": "8086" + }, + { + "examine": "There are three coconuts on this palm tree.", + "ids": "8087" + }, + { + "examine": "There are four coconuts on this palm tree.", + "ids": "8088" + }, + { + "examine": "There are five coconuts on this palm tree.", + "ids": "8089" + }, + { + "examine": "There are six coconuts on this palm tree.", + "ids": "8090" + }, + { + "examine": "A fully grown palm tree.", + "ids": "8091" + }, + { + "examine": "This palm tree looks like it could do with pruning with secateurs.", + "ids": "8092,8093,8094,8095,8096,8097" + }, + { + "examine": "This palm tree has become diseased and died.", + "ids": "8098,8099,8100,8101,8102,8103" + }, + { + "examine": "This palm tree has been cut down.", + "ids": "8104" + }, + { + "examine": "A papaya tree sapling has been planted in this fruit tree patch.", + "ids": "8105" + }, + { + "examine": "A papaya tree is growing in this fruit tree patch.", + "ids": "8106,8107,8108,8109,8110" + }, + { + "examine": "A fully grown papaya tree", + "ids": "8111" + }, + { + "examine": "There is a single papaya fruit on this tree.", + "ids": "8112" + }, + { + "examine": "There are two papaya fruits on this tree.", + "ids": "8113" + }, + { + "examine": "There are three papaya fruits on this tree.", + "ids": "8114" + }, + { + "examine": "There are four papaya fruits on this tree.", + "ids": "8115" + }, + { + "examine": "There are five papaya fruits on this tree.", + "ids": "8116" + }, + { + "examine": "There are six papaya fruits on this tree.", + "ids": "8117" + }, + { + "examine": "A fully grown papaya tree.", + "ids": "8118" + }, + { + "examine": "This papaya tree looks like it could do with pruning with secateurs.", + "ids": "8119,8120,8121,8122,8123,8124" + }, + { + "examine": "This papaya tree has become diseased and died.", + "ids": "8125,8126,8127,8128,8129,8130" + }, + { + "examine": "This papaya tree has been cut down.", + "ids": "8131" + }, + { + "examine": "You can grow herbs in this Farming patch.", + "ids": "8132,8133,8134,8135,8136,8137,8138" + }, + { + "examine": "Some herb seeds have been sown in this patch.", + "ids": "8139" + }, + { + "examine": "A herb is growing in this patch.", + "ids": "8140,8141,8142" + }, + { + "examine": "A fully grown herb.", + "ids": "8143" + }, + { + "examine": "These herbs have become diseased.", + "ids": "8144,8145,8146" + }, + { + "examine": "These herbs have become diseased and died.", + "ids": "8147,8148,8149,8150,8151,8152,8153" + }, + { + "examine": "Asgarnian hop seeds have been sown in this farming patch.", + "ids": "8154" + }, + { + "examine": "Asgarnian hops are growing in this farming patch.", + "ids": "8155,8156,8157,8158" + }, + { + "examine": "These are fully grown Asgarnian Hops.", + "ids": "8159" + }, + { + "examine": "Asgarnian hop seeds have been sown in this farming patch.", + "ids": "8160" + }, + { + "examine": "Asgarnian hops are growing in this farming patch.", + "ids": "8161,8162,8163,8164" + }, + { + "examine": "These Asgarnian Hop plants are diseased.", + "ids": "8165,8166,8167,8168" + }, + { + "examine": "These Asgarnian Hop plants have died from disease.", + "ids": "8169,8170,8171,8172,8173,8174,8175,8176" + }, + { + "examine": "Hammerstone Hop seeds have been sown in this farming patch.", + "ids": "8177" + }, + { + "examine": "Hammerstone Hops are growing in this farming patch.", + "ids": "8178,8179,8180" + }, + { + "examine": "These are fully grown Hammerstone Hops.", + "ids": "8181" + }, + { + "examine": "Hammerstone Hop seeds have been sown in this farming patch.", + "ids": "8182" + }, + { + "examine": "Hammerstone Hops are growing in this farming patch.", + "ids": "8183,8184,8185" + }, + { + "examine": "These Hammerstone Hops are diseased.", + "ids": "8186,8187,8188" + }, + { + "examine": "These Hammerstone Hops have died from disease.", + "ids": "8189,8190,8191" + }, + { + "examine": "Barley seeds have been sown in this farming patch.", + "ids": "8192" + }, + { + "examine": "Barley is growing in this farming patch.", + "ids": "8193,8194,8195" + }, + { + "examine": "This patch is full of Barley.", + "ids": "8196" + }, + { + "examine": "Barley seeds have been sown in this farming patch.", + "ids": "8197" + }, + { + "examine": "Barley is growing in this farming patch.", + "ids": "8198,8199,8200" + }, + { + "examine": "This Barley is diseased.", + "ids": "8201,8202,8203" + }, + { + "examine": "This Barley has died from disease.", + "ids": "8204,8205,8206" + }, + { + "examine": "You can grow hops in this Farming patch.", + "ids": "8207,8208,8209,8210" + }, + { + "examine": "Krandorian Hop seeds have been planted in this farming patch.", + "ids": "8211" + }, + { + "examine": "Krandorian Hops are growing in this farming patch.", + "ids": "8212,8213,8214,8215,8216,8217" + }, + { + "examine": "These are fully grown Krandorian Hops.", + "ids": "8218" + }, + { + "examine": "Krandorian Hop seeds have been planted in this farming patch.", + "ids": "8219" + }, + { + "examine": "Krandorian Hops are growing in this farming patch.", + "ids": "8220,8221,8222,8223,8224,8225" + }, + { + "examine": "These Krandorian Hops are diseased.", + "ids": "8226,8227,8228,8229,8230,8231" + }, + { + "examine": "These Krandorian Hops have died from disease.", + "ids": "8232,8233,8234,8235,8236,8237" + }, + { + "examine": "Jute seeds have been sown in this farming patch.", + "ids": "8238" + }, + { + "examine": "Jute plants are growing in this farming patch.", + "ids": "8239,8240,8241,8242" + }, + { + "examine": "These are fully grown Jute plants.", + "ids": "8243" + }, + { + "examine": "Jute seeds have been sown in this farming patch.", + "ids": "8244" + }, + { + "examine": "Jute plants are growing in this farming patch.", + "ids": "8245,8246,8247,8248" + }, + { + "examine": "These Jute plants are diseased.", + "ids": "8249,8250,8251,8252" + }, + { + "examine": "These Jute plants have died from disease.", + "ids": "8253,8254,8255,8256" + }, + { + "examine": "Wildblood hop seeds have been planted in this farming patch.", + "ids": "8257" + }, + { + "examine": "Wildblood Hops are growing in this farming patch.", + "ids": "8258,8259,8260,8261,8262,8263,8264" + }, + { + "examine": "These are fully grown Wildblood Hops.", + "ids": "8265" + }, + { + "examine": "Wildblood hop seeds have been planted in this farming patch.", + "ids": "8266" + }, + { + "examine": "Wildblood Hops are growing in this farming patch.", + "ids": "8267,8268,8269,8270,8271,8272,8273" + }, + { + "examine": "These Wildblood hops are diseased.", + "ids": "8274,8275,8276,8277,8278,8279,8280" + }, + { + "examine": "These Wildblood Hops have died from disease.", + "ids": "8281,8282,8283,8284,8285,8286,8287" + }, + { + "examine": "Yanillian Hop seeds have been sown in this farming patch.", + "ids": "8288" + }, + { + "examine": "Yanillian Hops are growing in this farming patch.", + "ids": "8289,8290,8291,8292,8293" + }, + { + "examine": "These are fully grown Yanillian Hops.", + "ids": "8294" + }, + { + "examine": "Yanillian Hop seeds have been sown in this farming patch.", + "ids": "8295" + }, + { + "examine": "Yanillian Hops are growing in this farming patch.", + "ids": "8296,8297,8298,8299,8300" + }, + { + "examine": "These Yanillian Hops are diseased.", + "ids": "8301,8302,8303,8304,8305" + }, + { + "examine": "These Yanillian Hops have died from disease.", + "ids": "8306,8307,8308,8309,8310" + }, + { + "examine": "You can grow Bittercap mushrooms in this Farming patch.", + "ids": "8311,8312,8313,8314" + }, + { + "examine": "Bittercap mushroom spores have been sown in this farming patch.", + "ids": "8315" + }, + { + "examine": "Bittercap mushrooms are growing in this farming patch.", + "ids": "8316,8317,8318,8319,8320" + }, + { + "examine": "A patch of Bittercap Mushrooms.", + "ids": "8321,8322,8323,8324,8325,8326" + }, + { + "examine": "These Bittercap mushrooms have become diseased.", + "ids": "8327,8328,8329,8330,8331" + }, + { + "examine": "These Bittercap mushrooms have become diseased and died.", + "ids": "8332,8333,8334,8335,8336,8337,8338" + }, + { + "examine": "You can grow a Spirit Tree in this Farming patch.", + "ids": "8339,8340,8341,8342" + }, + { + "examine": "A Spirit Tree.", + "ids": "8343,8344,8345,8346,8347,8348,8349,8350,8351,8352,8353,8354,8355,8356" + }, + { + "examine": "A Spirit Tree stump.", + "ids": "8357" + }, + { + "examine": "Needs pruning before it dies.", + "ids": "8358,8359,8360,8361,8362,8363,8364,8365,8366,8367,8368,8369" + }, + { + "examine": "Oh dear, your spirit tree has died.", + "ids": "8370,8371,8372,8373,8374,8375,8376,8377,8378,8379,8380,8381,8382,8383,8384,8385,8386,8387,8388,8389,8390,8391" + }, + { + "examine": "You can grow trees in this Farming patch.", + "ids": "8392,8393,8394,8395" + }, + { + "examine": "A Magic Tree sapling has been planted in this tree patch.", + "ids": "8396" + }, + { + "examine": "A Magic Tree is growing in this tree patch.", + "ids": "8397,8398,8399,8400,8401,8402,8403,8404,8405,8406,8407" + }, + { + "examine": "A fully grown Magic Tree.", + "ids": "8408,8409" + }, + { + "examine": "You can uproot this stump with a spade.", + "ids": "8410" + }, + { + "examine": "To remove all signs of disease, prune the tree with secateurs.", + "ids": "8411,8412,8413,8414,8415,8416,8417,8418,8419,8420,8421,8422" + }, + { + "examine": "This Magic Tree has become diseased and died.", + "ids": "8423,8424,8425,8426,8427,8428,8429,8430,8431,8432,8433,8434" + }, + { + "examine": "A Maple tree sapling has been planted in this tree patch.", + "ids": "8435" + }, + { + "examine": "A Maple tree is growing in this tree patch.", + "ids": "8436,8437,8438,8439,8440,8441,8442" + }, + { + "examine": "A fully grown Maple tree.", + "ids": "8443,8444" + }, + { + "examine": "You can uproot this stump with a spade.", + "ids": "8445" + }, + { + "examine": "To remove all signs of disease, prune the tree with secateurs.", + "ids": "8446,8447,8448,8449,8450,8451,8452,8453" + }, + { + "examine": "This Maple tree has become diseased and died.", + "ids": "8454,8455,8456,8457,8458,8459,8460,8461" + }, + { + "examine": "An Oak sapling has been planted in this tree patch.", + "ids": "8462" + }, + { + "examine": "An Oak tree is growing in this tree patch.", + "ids": "8463,8464,8465" + }, + { + "examine": "A fully grown Oak tree.", + "ids": "8466,8467" + }, + { + "examine": "You can uproot this stump with a spade.", + "ids": "8468,8469,8470,8471,8472" + }, + { + "examine": "To remove all signs of disease, prune the tree with secateurs.", + "ids": "8473,8474,8475,8476" + }, + { + "examine": "This Oak tree has become diseased and died.", + "ids": "8477,8478,8479,8480" + }, + { + "examine": "A Willow sapling has been planted in this tree patch.", + "ids": "8481" + }, + { + "examine": "A Willow tree is growing in this tree patch.", + "ids": "8482,8483,8484,8485,8486" + }, + { + "examine": "A fully grown Willow tree.", + "ids": "8487,8488" + }, + { + "examine": "You can uproot this stump with a spade.", + "ids": "8489" + }, + { + "examine": "To remove all signs of disease, prune the tree with secateurs.", + "ids": "8490,8491,8492,8493,8494,8495" + }, + { + "examine": "This Willow tree has become diseased and died.", + "ids": "8496,8497,8498,8499,8500,8501" + }, + { + "examine": "A Yew sapling has been planted in this tree patch.", + "ids": "8502" + }, + { + "examine": "A Yew tree is growing in this tree patch.", + "ids": "8503,8504,8505,8506,8507,8508,8509,8510,8511" + }, + { + "examine": "A fully grown Yew tree.", + "ids": "8512,8513" + }, + { + "examine": "You can uproot this tree stump with a spade.", + "ids": "8514" + }, + { + "examine": "To remove all signs of disease, prune the tree with secateurs.", + "ids": "8515,8516,8517,8518,8519,8520,8521,8522,8523,8524" + }, + { + "examine": "This Yew tree has become diseased and died.", + "ids": "8525,8526,8527,8528,8529,8530,8531,8532,8533,8534" + }, + { + "examine": "Cabbage seeds have been sown in this allotment.", + "ids": "8535" + }, + { + "examine": "Cabbages are growing in this allotment.", + "ids": "8536,8537,8538" + }, + { + "examine": "These cabbages could do with harvesting.", + "ids": "8539" + }, + { + "examine": "Cabbages are growing in this allotment.", + "ids": "8540,8541,8542,8543" + }, + { + "examine": "These cabbages have become diseased and need tending.", + "ids": "8544,8545,8546" + }, + { + "examine": "These cabbages have become diseased and died.", + "ids": "8547,8548,8549,8550,8551,8552,8553,8554,8555,8556,8557" + }, + { + "examine": "Potato seeds have been planted in this allotment.", + "ids": "8558" + }, + { + "examine": "Potato plants are growing in this allotment.", + "ids": "8559,8560,8561" + }, + { + "examine": "These potato plants are fully grown.", + "ids": "8562" + }, + { + "examine": "Potato seeds have been planted in this allotment.", + "ids": "8563" + }, + { + "examine": "Potato plants are growing in this allotment.", + "ids": "8564,8565,8566" + }, + { + "examine": "These potato plants are diseased.", + "ids": "8567,8568,8569" + }, + { + "examine": "These potato plants are dead.", + "ids": "8570,8571,8572" + }, + { + "examine": "You can grow fruit and vegetables here.", + "ids": "8573,8574,8575,8576,8577,8578,8579" + }, + { + "examine": "Some onion seeds have sown in this allotment.", + "ids": "8580" + }, + { + "examine": "Some onion plants are growing in this allotment.", + "ids": "8581,8582,8583" + }, + { + "examine": "There are some fully grown onions in this allotment.", + "ids": "8584" + }, + { + "examine": "Some onion seeds have sown in this allotment.", + "ids": "8585" + }, + { + "examine": "Some onion plants are growing in this allotment.", + "ids": "8586,8587,8588" + }, + { + "examine": "These onions have become diseased.", + "ids": "8589,8590,8591" + }, + { + "examine": "These onions have become diseased and died.", + "ids": "8592,8593,8594" + }, + { + "examine": "Strawberry seeds have been sown in this allotment.", + "ids": "8595" + }, + { + "examine": "Strawberry plants are growing in this allotment.", + "ids": "8596,8597,8598,8599,8600" + }, + { + "examine": "These strawberry plants are fully grown.", + "ids": "8601" + }, + { + "examine": "Strawberry seeds have been sown in this allotment.", + "ids": "8602" + }, + { + "examine": "Strawberry plants are growing in this allotment.", + "ids": "8603,8604,8605,8606,8607" + }, + { + "examine": "These strawberry plants have become diseased.", + "ids": "8608,8609,8610,8611,8612" + }, + { + "examine": "These strawberry plants have become diseased and died.", + "ids": "8613,8614,8615,8616,8617" + }, + { + "examine": "Some sweetcorn seeds have been sown in this allotment.", + "ids": "8618" + }, + { + "examine": "Some sweetcorn plants are growing in this allotment.", + "ids": "8619,8620,8621,8622,8623" + }, + { + "examine": "These sweetcorn plants are fully grown.", + "ids": "8624" + }, + { + "examine": "Some sweetcorn seeds have been sown in this allotment.", + "ids": "8625" + }, + { + "examine": "Some sweetcorn plants are growing in this allotment.", + "ids": "8626,8627,8628,8629,8630" + }, + { + "examine": "These sweetcorn plants have been attacked by crows.", + "ids": "8631,8632,8633,8634,8635" + }, + { + "examine": "These sweetcorn plants have become diseased and died.", + "ids": "8636,8637,8638,8639,8640" + }, + { + "examine": "Tomato seeds have been sown in this allotment.", + "ids": "8641" + }, + { + "examine": "Tomato plants are growing in this allotment.", + "ids": "8642,8643,8644" + }, + { + "examine": "These tomato plants are fully grown.", + "ids": "8645" + }, + { + "examine": "Tomato seeds have been sown in this allotment.", + "ids": "8646" + }, + { + "examine": "Tomato plants are growing in this allotment.", + "ids": "8647,8648,8649" + }, + { + "examine": "These tomato plants have become diseased.", + "ids": "8650,8651,8652" + }, + { + "examine": "These tomato plants have become diseased and died.", + "ids": "8653,8654,8655" + }, + { + "examine": "Watermelon seeds have been sown in this allotment.", + "ids": "8656" + }, + { + "examine": "Watermelons are growing in this allotment.", + "ids": "8657,8658,8659,8660,8661,8662,8663" + }, + { + "examine": "These watermelons could do with harvesting.", + "ids": "8664" + }, + { + "examine": "Watermelon seeds have been sown in this allotment.", + "ids": "8665" + }, + { + "examine": "Watermelons are growing in this allotment.", + "ids": "8666,8667,8668,8669,8670,8671,8672" + }, + { + "examine": "These watermelons have become diseased and need tending.", + "ids": "8673,8674,8675,8676,8677,8678,8679" + }, + { + "examine": "These watermelon plants have become diseased and died.", + "ids": "8680" + }, + { + "examine": "These watermelons have become diseased and died.", + "ids": "8681,8682,8683,8684,8685,8686,8687" + }, + { + "examine": "The perfect accompaniment to a bedroom.", + "ids": "8688" + }, + { + "examine": "Fit for milking.", + "ids": "8689" + }, + { + "examine": "Each full of milk no doubt.", + "ids": "8690,8691,8692,8693,8694" + }, + { + "examine": "The door is closed.", + "ids": "8695" + }, + { + "examine": "The door is open.", + "ids": "8696,8697,8698" + }, + { + "examine": "After working with livestock, why not wash your hands?", + "ids": "8699" + }, + { + "examine": "For putting things on.", + "ids": "8700" + }, + { + "examine": "Someone's been preparing meat.", + "ids": "8701" + }, + { + "examine": "A barrel for collecting rain water.", + "ids": "8702,8703,8704,8705,8706,8707,8708,8709,8710,8711" + }, + { + "examine": "A grand old fireplace.", + "ids": "8712" + }, + { + "examine": "I bet there's a needle in it somewhere.", + "ids": "8713,8714,8715,8716" + }, + { + "examine": "A loom.", + "ids": "8717,8718,8719,8720,8721,8722,8723,8724" + }, + { + "examine": "A little rock.", + "ids": "8725" + }, + { + "examine": "A small chunk of rock.", + "ids": "8726" + }, + { + "examine": "They're not floating, even though it may look like they are!", + "ids": "8727" + }, + { + "examine": "A deposit of rocks.", + "ids": "8728,8729,8730,8731,8732,8733,8734,8735,8736" + }, + { + "examine": "This tap runs from the apple crushing barrel.", + "ids": "8737" + }, + { + "examine": "You can walk through these doors.", + "ids": "8738,8739,8740,8741" + }, + { + "examine": "An odd looking tree.", + "ids": "8742,8743" + }, + { + "examine": "I can climb this.", + "ids": "8744,8745" + }, + { + "examine": "I can climb down this.", + "ids": "8746" + }, + { + "examine": "A local water source.", + "ids": "8747" + }, + { + "examine": "Used for spinning thread.", + "ids": "8748" + }, + { + "examine": "A Shrine to the glory of Seren.", + "ids": "8749" + }, + { + "examine": "I can cook here.", + "ids": "8750" + }, + { + "examine": "A nice sturdy looking table.", + "ids": "8751" + }, + { + "examine": "A good source of books!", + "ids": "8752,8753,8754,8755,8756,8757,8758,8759,8760,8761,8762,8763,8764,8765,8766" + }, + { + "examine": "The lamp has a glowing crystal at its core.", + "ids": "8767" + }, + { + "examine": "A table.", + "ids": "8768,8769" + }, + { + "examine": "A chair.", + "ids": "8770" + }, + { + "examine": "A painting of an elf standing in some woodland.", + "ids": "8771" + }, + { + "examine": "Sit back and relax...", + "ids": "8772" + }, + { + "examine": "A useful ranging device.", + "ids": "8773,8774" + }, + { + "examine": "Use these with bows.", + "ids": "8775" + }, + { + "examine": "Tailor-made for needlework supplies.", + "ids": "8776,8777" + }, + { + "examine": "I'm guessing it's for making elven clothes.", + "ids": "8778" + }, + { + "examine": "Helps make elf clothing.", + "ids": "8779,8780,8781,8782" + }, + { + "examine": "I wonder what's under it?", + "ids": "8783,8784" + }, + { + "examine": "I can climb this.", + "ids": "8785" + }, + { + "examine": "The door is closed.", + "ids": "8786,8787,8788,8789" + }, + { + "examine": "The door is open.", + "ids": "8790,8791,8792,8793,8794" + }, + { + "examine": "Makes gnomes taller.", + "ids": "8795" + }, + { + "examine": "Makes creatures taller.", + "ids": "8796" + }, + { + "examine": "I wonder what's inside.", + "ids": "8797" + }, + { + "examine": "Perhaps I should search it.", + "ids": "8798" + }, + { + "examine": "The desk of the head mourner.", + "ids": "8799" + }, + { + "examine": "I wonder what's inside.", + "ids": "8800" + }, + { + "examine": "A sack full of grain.", + "ids": "8801,8802,8803" + }, + { + "examine": "These have grain in them.", + "ids": "8804,8805,8806" + }, + { + "examine": "An empty barrel.", + "ids": "8807" + }, + { + "examine": "A barrel full of mushed apples.", + "ids": "8808" + }, + { + "examine": "A pile of rotten apples!", + "ids": "8809" + }, + { + "examine": "A wooden gate.", + "ids": "8810,8811,8812,8813" + }, + { + "examine": "A well slept in bed.", + "ids": "8814,8815,8816,8817" + }, + { + "examine": "The door is closed.", + "ids": "8818" + }, + { + "examine": "The door is open.", + "ids": "8819" + }, + { + "examine": "Solid iron bars.", + "ids": "8820,8821,8822,8823,8824,8825,8826,8827" + }, + { + "examine": "Heavy.", + "ids": "8828,8829,8830" + }, + { + "examine": "You can 'cart' things around on this.", + "ids": "8831,8832,8833,8834,8835,8836,8837,8838,8839" + }, + { + "examine": "I feel the need to throw a rotten cabbage!", + "ids": "8840,8841" + }, + { + "examine": "Nothing growing on this tree at the moment...", + "ids": "8842" + }, + { + "examine": "Mmmmm, nice juicy apples!", + "ids": "8843,8844,8845,8846,8847,8848,8849,8850,8851,8852,8853,8854,8855,8856,8857,8858,8859,8860" + }, + { + "examine": "This is a special hops patch.", + "ids": "8861,8862,8863,8864" + }, + { + "examine": "Kelda Hop seeds have been sown in this farming patch.", + "ids": "8865" + }, + { + "examine": "Kelda Hops are growing in this farming patch.", + "ids": "8866,8867,8868" + }, + { + "examine": "These are fully grown Kelda Hops.", + "ids": "8869" + }, + { + "examine": "A barrel of Kelda Stout.", + "ids": "8870" + }, + { + "examine": "This vat contains Kelda hops.", + "ids": "8871" + }, + { + "examine": "Kelda Stout is fermenting in this vat.", + "ids": "8872,8873" + }, + { + "examine": "This vat contains Kelda Stout.", + "ids": "8874,8875,8876,8877" + }, + { + "examine": "Some bizarre mixture between rocks and machinery. Definitely dwarven.", + "ids": "8878" + }, + { + "examine": "A strange box of some kind.", + "ids": "8879" + }, + { + "examine": "A strange box of some kind. It's open.", + "ids": "8880" + }, + { + "examine": "A small cave entrance.", + "ids": "8881,8882,8883,8884,8885" + }, + { + "examine": "Keeps mine carts from rolling away.", + "ids": "8886" + }, + { + "examine": "Cart tracks.", + "ids": "8887,8888,8889,8890,8891,8892,8893,8894,8895,8896,8897,8898" + }, + { + "examine": "A support for the tracks.", + "ids": "8899,8900,8901,8902,8903,8904,8905,8906,8907,8908,8909" + }, + { + "examine": "These books contain all sorts of data on the Red Axe.", + "ids": "8910" + }, + { + "examine": "Big mysterious crates. You wonder what could be inside.", + "ids": "8911" + }, + { + "examine": "Wooden crates with metal edges, contents unknown.", + "ids": "8912" + }, + { + "examine": "Big mysterious crates. There are some papers on top.", + "ids": "8913,8914,8915,8916,8917" + }, + { + "examine": "A symbol of the Red Axe.", + "ids": "8918,8919,8920,8921,8922,8923" + }, + { + "examine": "A steam powered cart.", + "ids": "8924,8925" + }, + { + "examine": "A short long boat!", + "ids": "8926" + }, + { + "examine": "Best used with a bucket.", + "ids": "8927,8928" + }, + { + "examine": "A deep and terrifying cave.", + "ids": "8929" + }, + { + "examine": "It looks cold in there.", + "ids": "8930,8931,8932,8933,8934,8935,8936,8937,8938,8939,8940,8941,8942,8943,8944,8945,8946,8947,8948,8949" + }, + { + "examine": "A big slimy lump of rock.", + "ids": "8950" + }, + { + "examine": "A slimy lump of rock.", + "ids": "8951" + }, + { + "examine": "A slippery looking rock.", + "ids": "8952,8953" + }, + { + "examine": "A tall flag blowing in the wind.", + "ids": "8954,8955" + }, + { + "examine": "I could climb this if I wanted.", + "ids": "8956,8957" + }, + { + "examine": "There must be some trick to opening this...", + "ids": "8958,8959,8960" + }, + { + "examine": "It's opening...", + "ids": "8961" + }, + { + "examine": "Apparently there was some trick to opening it!", + "ids": "8962" + }, + { + "examine": "Not as difficult to walk through as it was a minute ago.", + "ids": "8963,8964,8965" + }, + { + "examine": "Steps*Leads to the surface.", + "ids": "1337" + }, + { + "examine": "A sturdy looking door, propped shut with a support.", + "ids": "8967,8968,8969,8970,8971" + }, + { + "examine": "A portal back to the real world...", + "ids": "8972" + }, + { + "examine": "One of the most common trees in 2009Scape.", + "ids": "8973" + }, + { + "examine": "A commonly found tree.", + "ids": "8974,8975,8976,8977,8978,8979,8980,8981,8982,8983,8984" + }, + { + "examine": "Steam seems to be condensing into the pot. Neat trick!", + "ids": "8985" + }, + { + "examine": "I can see fish swimming in the water. Well, they sort of look like fish...", + "ids": "8986" + }, + { + "examine": "A portal that leads... somewhere?", + "ids": "8987" + }, + { + "examine": "I wonder what's inside...", + "ids": "8988" + }, + { + "examine": "Someone's looking through the chest.", + "ids": "8989,8990,8991,8992,8993,8994,8995,8996,8997" + }, + { + "examine": "An appendage for activating something.", + "ids": "8998,8999,9000,9001,9002,9003,9004,9005" + }, + { + "examine": "A place to cremate the dead. Needs a body.", + "ids": "9006,9007" + }, + { + "examine": "A place to cremate the dead. Needs a light.", + "ids": "9008,9009" + }, + { + "examine": "This has broad leaves.", + "ids": "9010,9011,9012,9013" + }, + { + "examine": "This has been chopped away.", + "ids": "9014" + }, + { + "examine": "This has broad leaves.", + "ids": "9015,9016,9017,9018" + }, + { + "examine": "This has been chopped away.", + "ids": "9019" + }, + { + "examine": "This has broad leaves.", + "ids": "9020,9021,9022,9023" + }, + { + "examine": "This has been chopped away.", + "ids": "9024" + }, + { + "examine": "A damaged wooden fence.", + "ids": "9025,9026,9027,9028" + }, + { + "examine": "A wooden fence.", + "ids": "9029" + }, + { + "examine": "Gems encrusted in stone.", + "ids": "9030,9031,9032" + }, + { + "examine": "Many rare plants such as this usually have exotic tubers.", + "ids": "9033" + }, + { + "examine": "A beautiful old mahogany tree.", + "ids": "9034" + }, + { + "examine": "This once was a beautiful tree.", + "ids": "9035" + }, + { + "examine": "A beautiful old teak tree.", + "ids": "9036" + }, + { + "examine": "This tree has been cut down.", + "ids": "9037" + }, + { + "examine": "A set of large, sturdy wooden doors.", + "ids": "9038,9039,9040,9041,9042,9043" + }, + { + "examine": "Some goutweed is growing in this patch.", + "ids": "9044,9045,9046,9047" + }, + { + "examine": "Some fully grown goutweed.", + "ids": "9048" + }, + { + "examine": "This goutweed has become diseased.", + "ids": "9049,9050,9051" + }, + { + "examine": "This goutweed has become diseased and died.", + "ids": "9052,9053,9054,9055,9056,9057" + }, + { + "examine": "He's not stocking much.", + "ids": "9058" + }, + { + "examine": "He's stocking rune caskets.", + "ids": "9059" + }, + { + "examine": "He's stocking blackjacks.", + "ids": "9060" + }, + { + "examine": "He's stocking fez hats.", + "ids": "9061" + }, + { + "examine": "He's stocking rune caskets.", + "ids": "9062" + }, + { + "examine": "He's stocking colourful clothes.", + "ids": "9063" + }, + { + "examine": "A wooden crate.", + "ids": "9064,9065" + }, + { + "examine": "A wooden crate containing caskets.", + "ids": "9066,9067" + }, + { + "examine": "A wooden crate containing Blackjacks.", + "ids": "9068,9069" + }, + { + "examine": "A wooden crate containing fez hats.", + "ids": "9070" + }, + { + "examine": "A wooden crate containing clothes.", + "ids": "9071" + }, + { + "examine": "Boxy.", + "ids": "9072,9073" + }, + { + "examine": "boxy", + "ids": "9074,9075" + }, + { + "examine": "This cloth has been dyed.", + "ids": "9076" + }, + { + "examine": "Mmmm pretty!", + "ids": "9077,9078" + }, + { + "examine": "These dyed fabrics are drying off.", + "ids": "9079,9080,9081" + }, + { + "examine": "Items for making clothes are kept on here.", + "ids": "9082" + }, + { + "examine": "Pots full of dye.", + "ids": "9083" + }, + { + "examine": "A way down.", + "ids": "9084" + }, + { + "examine": "There's not much coke in the stove.", + "ids": "9085" + }, + { + "examine": "There's a fair amount of coke in the stove.", + "ids": "9086" + }, + { + "examine": "There's lots of coke in the stove.", + "ids": "9087" + }, + { + "examine": "A big pile of refined coal.", + "ids": "9088" + }, + { + "examine": "You can read the furnace temperature here.", + "ids": "9089" + }, + { + "examine": "Used to pump hot air through the furnace.", + "ids": "9090" + }, + { + "examine": "Bars come out of the blast furnace here.", + "ids": "9091,9092" + }, + { + "examine": "Your bars will come out here.", + "ids": "9093,9094" + }, + { + "examine": "The bars are glowing hot!", + "ids": "9095" + }, + { + "examine": "Your bars are ready to take.", + "ids": "9096" + }, + { + "examine": "They power the conveyor belt.", + "ids": "9097" + }, + { + "examine": "The foreman refers to it as 'Bertha'.", + "ids": "9098" + }, + { + "examine": "It shows that the furnace is working.", + "ids": "9099" + }, + { + "examine": "Ore rides this into the blast furnace.", + "ids": "9100,9101" + }, + { + "examine": "It keeps the conveyor belt running.", + "ids": "9102" + }, + { + "examine": "Fix it, quick!", + "ids": "9103" + }, + { + "examine": "They keep the conveyor belt running.", + "ids": "9104" + }, + { + "examine": "Fix them, quick!", + "ids": "9105" + }, + { + "examine": "It keeps the conveyor belt turning.", + "ids": "9106,9107" + }, + { + "examine": "They keep the conveyor belt turning.", + "ids": "9108,9109,9110,9111,9112,9113,9114" + }, + { + "examine": "It shows that the furnace is working.", + "ids": "9115" + }, + { + "examine": "Hot air circulates through these.", + "ids": "9116" + }, + { + "examine": "Quick, fix them!", + "ids": "9117,9118,9119" + }, + { + "examine": "Hot air circulates through these.", + "ids": "9120" + }, + { + "examine": "Quick, fix them!", + "ids": "9121,9122" + }, + { + "examine": "It shows the furnace is working.", + "ids": "9123,9124,9125,9126,9127,9128,9129,9130,9131,9132,9133,9134,9135,9136,9137" + }, + { + "examine": "A way upwards.", + "ids": "9138,9139" + }, + { + "examine": "The gate is closed.", + "ids": "9140,9141" + }, + { + "examine": "The gate is open.", + "ids": "9142" + }, + { + "examine": "Used for getting water.", + "ids": "9143" + }, + { + "examine": "Some kind of jewellery is dangling from this ornament.", + "ids": "9144" + }, + { + "examine": "Someone's showing off their wealth!", + "ids": "9145" + }, + { + "examine": "Filled to the brim with knowledge.", + "ids": "9146,9147" + }, + { + "examine": "A nicely carved wooden chair.", + "ids": "9148" + }, + { + "examine": "An expensive privacy aid!", + "ids": "9149" + }, + { + "examine": "An old wall.", + "ids": "9150" + }, + { + "examine": "Security breach!", + "ids": "9151" + }, + { + "examine": "A patched up hole.", + "ids": "9152,9153,9154" + }, + { + "examine": "'You are here.'", + "ids": "9155" + }, + { + "examine": "An elegant desk with a curious ornament on it.", + "ids": "9156" + }, + { + "examine": "Someone's gold-trimmed this Saradomin armour!", + "ids": "9157,9158" + }, + { + "examine": "Lit to remember the souls of the departed.", + "ids": "9159,9160,9161,9162,9163,9164,9165" + }, + { + "examine": "You can grow delphiniums in this Farming patch.", + "ids": "9166,9167,9168,9169" + }, + { + "examine": "Delphinium seeds have been sown in this farming patch.", + "ids": "9170" + }, + { + "examine": "Beautiful.", + "ids": "9171,9172" + }, + { + "examine": "These delphiniums are fully grown.", + "ids": "9173,9174,9175,9176" + }, + { + "examine": "You can grow a pink rose bush in this patch.", + "ids": "9177,9178,9179,9180" + }, + { + "examine": "You can grow a white rose bush in this patch.", + "ids": "9181,9182,9183,9184" + }, + { + "examine": "You can grow a red rose bush in this patch.", + "ids": "9185,9186,9187,9188" + }, + { + "examine": "A rose bush.", + "ids": "9189,9190,9191" + }, + { + "examine": "This white rosebush is fully grown.", + "ids": "9192" + }, + { + "examine": "A rose bush.", + "ids": "9193" + }, + { + "examine": "This red rosebush is fully grown.", + "ids": "9194" + }, + { + "examine": "A pink rosebush.", + "ids": "9195" + }, + { + "examine": "This pink rosebush is fully grown.", + "ids": "9196,9197,9198" + }, + { + "examine": "A plantpot of pink orchids.", + "ids": "9199,9200,9201" + }, + { + "examine": "These pink orchids are fully grown.", + "ids": "9202" + }, + { + "examine": "An empty plantpot.", + "ids": "9203" + }, + { + "examine": "A plantpot filled with soil.", + "ids": "9204" + }, + { + "examine": "A plantpot of yellow orchids.", + "ids": "9205,9206,9207" + }, + { + "examine": "These yellow orchids are fully grown.", + "ids": "9208,9209" + }, + { + "examine": "You can grow a White Tree in this patch.", + "ids": "9210,9211,9212,9213" + }, + { + "examine": "A White Tree sapling has been planted in this patch.", + "ids": "9214" + }, + { + "examine": "A White Tree is growing in this patch.", + "ids": "9215,9216,9217" + }, + { + "examine": "This White Tree is fully grown.", + "ids": "9218" + }, + { + "examine": "This White Tree bears a single fruit.", + "ids": "9219" + }, + { + "examine": "This White Tree bears two fruits.", + "ids": "9220" + }, + { + "examine": "This White Tree bears three fruits.", + "ids": "9221" + }, + { + "examine": "This White Tree bears four fruits.", + "ids": "9222,9223" + }, + { + "examine": "You can grow snowdrops in this Farming patch.", + "ids": "9224,9225,9226,9227" + }, + { + "examine": "A patch of snowdrops.", + "ids": "9228,9229,9230" + }, + { + "examine": "These snowdrops are fully grown.", + "ids": "9231,9232" + }, + { + "examine": "You can grow Burthorpe Vine in this patch.", + "ids": "9233" + }, + { + "examine": "You can grow Burthorpe Vines in this patch.", + "ids": "9234,9235,9236" + }, + { + "examine": "Burthorpe vines are growing in this patch.", + "ids": "9237,9238,9239" + }, + { + "examine": "These Burthorpe vines are fully grown.", + "ids": "9240" + }, + { + "examine": "An empty plinth for a statue.", + "ids": "9241,9242" + }, + { + "examine": "What a good likeness!", + "ids": "9243" + }, + { + "examine": "An empty plinth for a statue.", + "ids": "9244" + }, + { + "examine": "An expertly carved statue of a former King of Misthalin.", + "ids": "9245" + }, + { + "examine": "An empty plinth for a statue.", + "ids": "9246" + }, + { + "examine": "What a good likeness!", + "ids": "9247" + }, + { + "examine": "An empty plinth for a statue.", + "ids": "9248" + }, + { + "examine": "An expertly carved statue of a former King of Misthalin.", + "ids": "9249,9250,9251,9252,9253,9254" + }, + { + "examine": "These grapevines look much healthier now.", + "ids": "9255" + }, + { + "examine": "These grapevines are suffering from some strange disease.", + "ids": "9256" + }, + { + "examine": "Some wild-looking grass.", + "ids": "9257,9258,9259" + }, + { + "examine": "Some red roses.", + "ids": "9260" + }, + { + "examine": "Some pink roses.", + "ids": "9261" + }, + { + "examine": "Some white roses.", + "ids": "9262" + }, + { + "examine": "A White Tree.", + "ids": "9263,9264,9265,9266,9267,9268,9269,9270,9271,9272,9273,9274,9275,9276,9277,9278,9279,9280,9281,9282,9283,9284,9285,9286,9287,9288,9289,9290" + }, + { + "examine": "Sit back and enjoy the view.", + "ids": "9291" + }, + { + "examine": "An expertly carved statue of a former Queen of Misthalin.", + "ids": "9292" + }, + { + "examine": "Funny looking holes that don't look too inviting.", + "ids": "9294" + }, + { + "examine": "A rocky outcrop.", + "ids": "9296,9297,9298" + }, + { + "examine": "Ornate railing.", + "ids": "9299" + }, + { + "examine": "Wooden fencing.", + "ids": "9300" + }, + { + "examine": "A well constructed castle wall.", + "ids": "9301" + }, + { + "examine": "A rather strategically placed hole, which appears to be in the ground.", + "ids": "9302" + }, + { + "examine": "A rocky outcrop.", + "ids": "9303,9304,9305,9306" + }, + { + "examine": "A well weathered wall.", + "ids": "9307,9308" + }, + { + "examine": "A tunnel leading under the wall.", + "ids": "9309,9310" + }, + { + "examine": "An underwall tunnel.", + "ids": "9311,9312" + }, + { + "examine": "Looks suspicious.", + "ids": "9313" + }, + { + "examine": "A wall jutting out into the path.", + "ids": "9314" + }, + { + "examine": "I can jump from this stepping stone.", + "ids": "9315" + }, + { + "examine": "A rocky outcrop.", + "ids": "9316,9317,9318" + }, + { + "examine": "A chain rope", + "ids": "9319,9320" + }, + { + "examine": "A few rocks short of a wall", + "ids": "9321" + }, + { + "examine": "The foam from the river makes this log very slippy.", + "ids": "9322,9323,9324" + }, + { + "examine": "Just another crack in the wall.", + "ids": "9325" + }, + { + "examine": "Funny looking holes that don't look too inviting.", + "ids": "9326" + }, + { + "examine": "They seem to fit in the with the rocky surroundings, so as not to stick out.", + "ids": "9327" + }, + { + "examine": "A slippery well worn log.", + "ids": "9328,9329,9330" + }, + { + "examine": "A rocky outcrop.", + "ids": "9331,9332,9333" + }, + { + "examine": "Used to be ornate, now it's a little bit vandalised.", + "ids": "9334" + }, + { + "examine": "A rocky outcrop.", + "ids": "9335,9336" + }, + { + "examine": "Used to be ornate, now it's a little bit vandalised.", + "ids": "9337" + }, + { + "examine": "Should scare off the birds...", + "ids": "9338,9339,9340,9341,9342,9343,9344,9345,9346,9347,9348,9349,9350,9351,9352,9353" + }, + { + "examine": "This looks like the way out.", + "ids": "9354" + }, + { + "examine": "A cave deep into the volcano.", + "ids": "9355" + }, + { + "examine": "A cave deeper into the volcano.", + "ids": "9356,9357" + }, + { + "examine": "A cave deep into the volcano.", + "ids": "9358" + }, + { + "examine": "This looks like the way out.", + "ids": "9359,9360,9361,9362,9363,9364,9365" + }, + { + "examine": "The barrier of heat is down.", + "ids": "9366" + }, + { + "examine": "A barrier of heat.", + "ids": "9367,9368,9369,9370,9371,9372,9373" + }, + { + "examine": "Hot enough to cook your breakfast on.", + "ids": "9374,9375,9376" + }, + { + "examine": "An egg incubated in the lava.", + "ids": "9377,9378,9379" + }, + { + "examine": "Who's the man?", + "ids": "9380" + }, + { + "examine": "A wooden crate.", + "ids": "9381" + }, + { + "examine": "Some wooden crates.", + "ids": "9382,9383,9384,9385,9386,9387,9388,9389" + }, + { + "examine": "A natural forge using volcanic heat.", + "ids": "9390" + }, + { + "examine": "I spy with my little eye...", + "ids": "9391,9392,9393,9394,9395,9396,9397" + }, + { + "examine": "Lets you put items into your bank.", + "ids": "9398,9399,26969,36788" + }, + { + "examine": "Sparse weeds.", + "ids": "9400" + }, + { + "examine": "Weeds.", + "ids": "9401" + }, + { + "examine": "Thick weeds.", + "ids": "9402" + }, + { + "examine": "This is Unferth's patch for growing potatos.", + "ids": "9403" + }, + { + "examine": "You say Potato, I say Poh-tar-to.", + "ids": "9404,9405,9406,9407" + }, + { + "examine": "Looks like these potatoes have fully grown.", + "ids": "9408,9409,9410,9411,9412,9413,9414,9415,9416,9417,9418,9419,9420,9421,9422,9423,9424,9425,9426,9427,9428,9429" + }, + { + "examine": "A nice sturdy bare table.", + "ids": "9430" + }, + { + "examine": "A nice sturdy table.", + "ids": "9431" + }, + { + "examine": "A table with milk.", + "ids": "9432" + }, + { + "examine": "A table with cake.", + "ids": "9433" + }, + { + "examine": "A hearty meal for Unferth.", + "ids": "9434,9435" + }, + { + "examine": "Great for sleeping in.", + "ids": "9436" + }, + { + "examine": "Not so great for sleeping in, it's not made.", + "ids": "9437,9438" + }, + { + "examine": "A fire burns brightly here.", + "ids": "9439" + }, + { + "examine": "An empty fire place.", + "ids": "9440" + }, + { + "examine": "An unlit fire place.", + "ids": "9441,9442" + }, + { + "examine": "A good source of books!", + "ids": "9443,9444,9445,9446,9447,9448,9449,9450,9451,9452,9453,9454,9455,9456,9457,9458,9459,9460,9461,9462,9463,9464,9465,9466,9467,9468,9469" + }, + { + "examine": "I can climb these stairs.", + "ids": "9470" + }, + { + "examine": "They go down.", + "ids": "9471" + }, + { + "examine": "What could be down here?", + "ids": "9472,9473,9474,9475,9476,9477,9478,9479,9480,9481,9482,9483,9484,9485,9486,9487,9488,9489,9490,9491,9492,9493,9494,9495,9496,9497" + }, + { + "examine": "A small plant, suitable for sandy soil.", + "ids": "9498" + }, + { + "examine": "A decorative plant.", + "ids": "9499" + }, + { + "examine": "A fairly small plant.", + "ids": "9500" + }, + { + "examine": "Another plant.", + "ids": "9501,9502,9503,9504,9505,9506,9507" + }, + { + "examine": "Perfect for snoozing in the sun.", + "ids": "9508" + }, + { + "examine": "Lovely comfy-looking big bed.", + "ids": "9509" + }, + { + "examine": "East to Draynor Village :: South to Rimmington :: South-east to Port Sarim.", + "ids": "9510,9511,9512,9513" + }, + { + "examine": "Betty's chair.", + "ids": "9514" + }, + { + "examine": "I wonder what she's making?", + "ids": "9515" + }, + { + "examine": "Betty's counter.", + "ids": "9516,9517,9518" + }, + { + "examine": "A wooden barrel for storage.", + "ids": "9519" + }, + { + "examine": "A wooden barrel containing lots of fish.", + "ids": "9520" + }, + { + "examine": "A wooden barrel for storage.", + "ids": "9521" + }, + { + "examine": "How much does this weigh?", + "ids": "9522" + }, + { + "examine": "A case. With books.", + "ids": "9523" + }, + { + "examine": "A mooring chain.", + "ids": "9524" + }, + { + "examine": "One horsepower; wooden suspension: a beauty.", + "ids": "9525" + }, + { + "examine": "Betty keeps some rune objects here.", + "ids": "9526,9527,9528,9529" + }, + { + "examine": "A sinister fungus.", + "ids": "9530" + }, + { + "examine": "Sit back and relax...", + "ids": "9531" + }, + { + "examine": "Sit back and enjoy the view.", + "ids": "9532" + }, + { + "examine": "A wooden crate.", + "ids": "9533,9534" + }, + { + "examine": "Some wooden crates.", + "ids": "9535" + }, + { + "examine": "Some wooden boxes.", + "ids": "9536" + }, + { + "examine": "It's used for loading and unloading fishing boats.", + "ids": "9537" + }, + { + "examine": "I hope it doesn't sink.", + "ids": "9538,9539,9540,9541,9542,9543,9544,9545,9546,9547" + }, + { + "examine": "A bucket full of red hot coals.", + "ids": "9548,9549,9550,9551,9552,9553,9554,9555,9556,9557" + }, + { + "examine": "It leads up.", + "ids": "9558" + }, + { + "examine": "I can climb down this.", + "ids": "9559,9560" + }, + { + "examine": "I guess I could sleep in it if I were really tired.", + "ids": "9561" + }, + { + "examine": "A prison cell door.", + "ids": "9562" + }, + { + "examine": "A locked prison cell door.", + "ids": "9563" + }, + { + "examine": "A prison cell door.", + "ids": "9564" + }, + { + "examine": "Stops people getting out.", + "ids": "9565,9566" + }, + { + "examine": "Ewww!", + "ids": "9567" + }, + { + "examine": "En-suite facilities in every cell!", + "ids": "9568,9569,9570,9571,9572,9573,9574,9575,9576,9577,9578,9579,9580,9581" + }, + { + "examine": "I can climb up these stairs.", + "ids": "9582,9583" + }, + { + "examine": "I can climb down these stairs.", + "ids": "9584,9585,9586,9587,9588,9589,9590,9591,9592,9593,9594,9595,9596,9597,9598,9599,9600,9601,9602,9603" + }, + { + "examine": "A leafy plant.", + "ids": "9604" + }, + { + "examine": "A leafy fern.", + "ids": "9605" + }, + { + "examine": "A leafy shrub.", + "ids": "9606" + }, + { + "examine": "A case. With books.", + "ids": "9607,9608,9609" + }, + { + "examine": "An artist's easel.", + "ids": "9610" + }, + { + "examine": "A good source of books!", + "ids": "9611" + }, + { + "examine": "The Make-over Mage's bed.", + "ids": "9612" + }, + { + "examine": "A nice sturdy looking table.", + "ids": "9613" + }, + { + "examine": "Generally used for putting things on.", + "ids": "9614" + }, + { + "examine": "A small wooden table.", + "ids": "9615" + }, + { + "examine": "Items are for sale here.", + "ids": "9616" + }, + { + "examine": "All-purpose storage.", + "ids": "9617,9618,9619,9620" + }, + { + "examine": "For sitting.", + "ids": "9621" + }, + { + "examine": "Fancy.", + "ids": "9622,9623" + }, + { + "examine": "It's like a land rudder.", + "ids": "9624" + }, + { + "examine": "A wooden wheelbarrow.", + "ids": "9625,9626,9627,9628,9629,9630,9631,9632,9633,9634,9635,9636,9637,9638,9639,9640,9641,9642,9643,9644,9645,9646,9647,9648,9649,9650,9651,9652,9653,9654,9655,9656,9657,9658,9659,9660" + }, + { + "examine": "This tree has been cut down.", + "ids": "9661" + }, + { + "examine": "Popular with farmers and treasure hunters.", + "ids": "9662" + }, + { + "examine": "This tree has fallen to the ground.", + "ids": "9663" + }, + { + "examine": "A gnarly old tree root.", + "ids": "9664" + }, + { + "examine": "The roots of a tree are exposed.", + "ids": "9665" + }, + { + "examine": "I hope I don't trip over any of these.", + "ids": "9666" + }, + { + "examine": "Disturbingly man-like.", + "ids": "9667" + }, + { + "examine": "Its eyes stare off into the distance...", + "ids": "9668,9669,9670,9671,9672,9673,9674,9675,9676,9677,9678,9679,9680,9681" + }, + { + "examine": "Expels smoke from the range.", + "ids": "9683" + }, + { + "examine": "Wash your hands!", + "ids": "9684" + }, + { + "examine": "Generally used for putting things on.", + "ids": "9685" + }, + { + "examine": "Some fabric ready for clothing.", + "ids": "9686" + }, + { + "examine": "I'm guessing it's for making women's clothes.", + "ids": "9687,9688" + }, + { + "examine": "Looks like it's for making men's clothes.", + "ids": "9689" + }, + { + "examine": "I think this one's for making men's clothes.", + "ids": "9690,9691,9692,9693" + }, + { + "examine": "Some helpful people have placed notes on here, how nice.", + "ids": "9694" + }, + { + "examine": "This notice board is full of scrolls and charts.", + "ids": "9695" + }, + { + "examine": "I wonder what's inside ?", + "ids": "9696" + }, + { + "examine": "A nice sturdy looking table.", + "ids": "9697,9698,9699,9700,9701" + }, + { + "examine": "This clearly isn't used for dining very often.", + "ids": "9702" + }, + { + "examine": "Not as nice as some.", + "ids": "9703" + }, + { + "examine": "This needs dusting before I'll sit on it.", + "ids": "9704,9705" + }, + { + "examine": "This must let me in to the arena somehow...", + "ids": "9706" + }, + { + "examine": "This must let me out of the arena somehow...", + "ids": "9707" + }, + { + "examine": "A rocky outcrop.", + "ids": "9708,9709,9710,9711,9712,9713,9714,9715,9716,9717,9718,9719,9720,9721,9722,9723,9724,9725,9726,9727,9728,9729,9730,9731,9732,9733,9734,9735,9737" + }, + { + "examine": "An old crumbled pillar.", + "ids": "9738,9739,9740" + }, + { + "examine": "Smells like fish.", + "ids": "9741,9742,9743" + }, + { + "examine": "I can climb up here.", + "ids": "9744" + }, + { + "examine": "I can go below decks with this ladder.", + "ids": "9745,9746,9747" + }, + { + "examine": "A collection point.", + "ids": "9748" + }, + { + "examine": "A Lever.", + "ids": "9749,9750" + }, + { + "examine": "A crystal that was broken a long time ago.", + "ids": "9751" + }, + { + "examine": "A repowered crystal.", + "ids": "9752" + }, + { + "examine": "Perhaps I should search it.", + "ids": "9753" + }, + { + "examine": "I wonder what's inside.", + "ids": "9754" + }, + { + "examine": "Perhaps I should search it.", + "ids": "9755" + }, + { + "examine": "I wonder what's inside.", + "ids": "9756" + }, + { + "examine": "Perhaps I should search it.", + "ids": "9757" + }, + { + "examine": "I wonder what's inside.", + "ids": "9758" + }, + { + "examine": "Perhaps I should search it.", + "ids": "9759" + }, + { + "examine": "I wonder what's inside.", + "ids": "9760" + }, + { + "examine": "Perhaps I should search it.", + "ids": "9761" + }, + { + "examine": "I wonder what's inside.", + "ids": "9762" + }, + { + "examine": "A recently killed guard.", + "ids": "9763,9764,9765" + }, + { + "examine": "A recently killed slave.", + "ids": "9766,9767" + }, + { + "examine": "A door of pure light!", + "ids": "9768,9769,9770,9771,9772,9773,9774,9775,9776,9777,9778,9779,9780,9781,9782,9783,9784,9785,9786,9787,9788,9789,9790,9791,9792,9793,9794,9795,9796,9797,9798,9799,9800,9801,9802,9803,9804,9805,9806,9807,9808,9809,9810,9811,9812,9813,9814,9815,9816,9817,9818,9819,9820,9821,9822,9823,9824,9825,9826,9827,9828,9829,9830,9831,9832,9833,9834,9835,9836,9837,9838,9839,9840,9841,9842,9843,9844,9845,9846,9847,9848,9849,9850,9851,9852,9853,9854,9855,9856,9857,9858,9859,9860,9861,9862,9863,9864,9865,9866,9867,9868,9869,9870,9871,9872,9873,9874,9875,9876,9877,9878,9879,9880,9881,9882,9883,9884,9885,9886,9887,9888,9889,9890,9891,9892,9893,9894,9895,9896,9897" + }, + { + "examine": "There are holes passing through this pillar.", + "ids": "9898,9899,9900,9901,9902,9903,9904,9905,9906,9907,9908,9909,9910,9911,9912,9913,9914,9915,9916,9917,9918,9919,9920,9921,9922,9923,9924,9925,9926,9927,9928,9929,9930,9931,9932,9933,9934,9935,9936,9937,9938,9939,9940,9941,9942,9943,9944,9945,9946,9947,9948,9949,9950,9951,9952,9953,9954,9955,9956,9957,9958,9959,9960,9961,9962,9963,9964,9965,9966,9967,9968,9969,9970,9971,9972,9973,9974" + }, + { + "examine": "I can climb down these.", + "ids": "9975" + }, + { + "examine": "A cave wall.", + "ids": "9976" + }, + { + "examine": "I wonder where this goes?", + "ids": "9977" + }, + { + "examine": "A ladder carved into the wall.", + "ids": "9978,9979" + }, + { + "examine": "A good place for light to merge.", + "ids": "9980" + }, + { + "examine": "A good place for a light crystal.", + "ids": "9981,9982,9983,9984,9985,9986,9987" + }, + { + "examine": "A broken pillar.", + "ids": "9988,9989,9990,9991,9992,9993,9994,9995,9996,9997,9998,9999,10000,10001" + }, + { + "examine": "An ancient elvish light doorway.", + "ids": "10002,10003,10004,10005,10006,10007,10008,10009,10010,10011,10012,10013" + }, + { + "examine": "A source of great power.", + "ids": "10014" + }, + { + "examine": "I can climb up these stairs.", + "ids": "10015" + }, + { + "examine": "I can climb down these stairs.", + "ids": "10016" + }, + { + "examine": "I can climb up these stairs.", + "ids": "10017,10018" + }, + { + "examine": "An Octagonal Pillar.", + "ids": "10019,10020,10021,10022,10023,10024,10025,10026,10027,10028,10029,10030,10031,10032" + }, + { + "examine": "I could hang off this.", + "ids": "10033" + }, + { + "examine": "An ancient trap.", + "ids": "10034" + }, + { + "examine": "An ancient blockage.", + "ids": "10035" + }, + { + "examine": "A way down.", + "ids": "10036,10037" + }, + { + "examine": "A way up.", + "ids": "10038,10039,10040" + }, + { + "examine": "The legs probably aren't a natural feature of the tree.", + "ids": "10041,10042,10043,10044,10045,10046,10047,10048,10049,10050,10051,10052,10053" + }, + { + "examine": "Sounds like there's liquid inside.", + "ids": "10054" + }, + { + "examine": "I won't be leaving that way then.", + "ids": "10055,10056" + }, + { + "examine": "Flag, pole... Yep, it's a flagpole.", + "ids": "10057,10058,10059,10060,10061" + }, + { + "examine": "This must be climbed over.", + "ids": "10062" + }, + { + "examine": "A mat for exercises.", + "ids": "10076,10077,10078,10079" + }, + { + "examine": "I wonder if I can hit a bullseye?", + "ids": "10080" + }, + { + "examine": "One of the most common trees in 2009Scape.", + "ids": "10081" + }, + { + "examine": "A commonly found tree.", + "ids": "10082" + }, + { + "examine": "A beautiful old oak.", + "ids": "10083" + }, + { + "examine": "Hay There.", + "ids": "10084" + }, + { + "examine": "A pile of straw.", + "ids": "10085" + }, + { + "examine": "Some hay.", + "ids": "10086" + }, + { + "examine": "It looks like an ordinary fishing spot, just infinitely more sinister...", + "ids": "10087,10088,10089" + }, + { + "examine": "Danger..Mudskippers!", + "ids": "10090" + }, + { + "examine": "A fish-filled water tank in the floor.", + "ids": "10091,10092" + }, + { + "examine": "Turns milk into other dairy products.", + "ids": "10093,10094,10095,10096,25270,34800,35931" + }, + { + "examine": "Weedy.", + "ids": "10097" + }, + { + "examine": "Less weedy.", + "ids": "10098" + }, + { + "examine": "Almost clear.", + "ids": "10099" + }, + { + "examine": "Free from weeds.", + "ids": "10100" + }, + { + "examine": "Something is growing here.", + "ids": "10101" + }, + { + "examine": "Fully grown Blindweed.", + "ids": "10102" + }, + { + "examine": "Weedy, wrecked and infertile.", + "ids": "10103,10104" + }, + { + "examine": "A stagnant lake.", + "ids": "10105,10106,10107,10108,10109,10110,10111,10112,10113,10114,10115,10116,10117,10118,10119,10120,10121,10122,10123,10124,10125,10126,10127,10128" + }, + { + "examine": "A very large pipe.", + "ids": "10129,10130,10131,10132,10133,10134,10135" + }, + { + "examine": "Rickety.", + "ids": "10136,10137" + }, + { + "examine": "I hope it doesn't sink.", + "ids": "10138" + }, + { + "examine": "It's a palm tree.", + "ids": "10139,10140,10141" + }, + { + "examine": "This controls the entire brewery.", + "ids": "10142" + }, + { + "examine": "A frothing, spinning, possessed control panel.", + "ids": "10143" + }, + { + "examine": "Chugging away nicely.", + "ids": "10144" + }, + { + "examine": "A large brass brewing vat.", + "ids": "10145,10146,10147" + }, + { + "examine": "The brass seems to be eaten away around the edge...", + "ids": "10148,10149,10150,10151,10152,10153,10154,10155,10156" + }, + { + "examine": "Racks of barrels.", + "ids": "10157" + }, + { + "examine": "Round, oaken, barrel-shaped.", + "ids": "10158" + }, + { + "examine": "A wooden crate.", + "ids": "10159" + }, + { + "examine": "Some wooden crates.", + "ids": "10160" + }, + { + "examine": "Some wooden boxes.", + "ids": "10161" + }, + { + "examine": "Probably where the farming kit is stored.", + "ids": "10162" + }, + { + "examine": "Ah! Definitely where the farming kit is stored.", + "ids": "10163,10164" + }, + { + "examine": "Throw the lever! Mwuhahahaha!", + "ids": "10165" + }, + { + "examine": "This lever can't be operated right now.", + "ids": "10166" + }, + { + "examine": "It leads up.", + "ids": "10167" + }, + { + "examine": "I can climb down this.", + "ids": "10168,10169" + }, + { + "examine": "This is where the brewing ingredients go.", + "ids": "10170" + }, + { + "examine": "An ominously stained barrel.", + "ids": "10171" + }, + { + "examine": "This gate is closed.", + "ids": "10172,10173" + }, + { + "examine": "The blood-chilling flag of the Inebriated.", + "ids": "10174" + }, + { + "examine": "'Please remember te wash yer hook'. Sound advice for the hygienic pirate.", + "ids": "10175,10176" + }, + { + "examine": "I could climb this if I wanted.", + "ids": "10177" + }, + { + "examine": "An unlit torch.", + "ids": "10178" + }, + { + "examine": "A lit torch.", + "ids": "10179,10180,10181,10182,10183,10184,10185,10186,10187,10188,10189,10190,10191,10192" + }, + { + "examine": "A sturdy iron frame, for climbing up and down.", + "ids": "10193,10194,10195,10196,10197,10198,10199,10200,10201,10202,10203,10204,10205,10206,10207,10208,10209,10210,10211,10212,10213,10214,10215,10216,10217,10218,10219,10220,10221,10222,10223,10224,10225,10226,10227,10228,10229,10230,10231,10232,10233,10234,10235,10236,10237,10238,10239,10240,10241,10242,10243,10244,10245" + }, + { + "examine": "Once upon a time this was used to make pottery.", + "ids": "10246" + }, + { + "examine": "Once upon a time this made clay hard.", + "ids": "10247" + }, + { + "examine": "There was a lot of pottery made here a long time ago.", + "ids": "10248,10249" + }, + { + "examine": "Eric's been killed by stones falling from the ceiling!", + "ids": "10250" + }, + { + "examine": "It looks like the magic is failing!", + "ids": "10251" + }, + { + "examine": "A temporary portal to the demon plane.", + "ids": "10252" + }, + { + "examine": "A standard.", + "ids": "10253,10254" + }, + { + "examine": "Technically a bed.", + "ids": "10255" + }, + { + "examine": "There are some books here.", + "ids": "10256" + }, + { + "examine": "There are some pots and pans here.", + "ids": "10257" + }, + { + "examine": "It's a small table.", + "ids": "10258" + }, + { + "examine": "Generally used for sitting.", + "ids": "10259" + }, + { + "examine": "The door is closed.", + "ids": "10260" + }, + { + "examine": "The door is open.", + "ids": "10261" + }, + { + "examine": "The door is closed.", + "ids": "10262" + }, + { + "examine": "The door is open.", + "ids": "10263" + }, + { + "examine": "The door is closed.", + "ids": "10264" + }, + { + "examine": "The door is open.", + "ids": "10265,10266" + }, + { + "examine": "A battle-weathered shield.", + "ids": "10267,10268" + }, + { + "examine": "A display of various relics.", + "ids": "10269,10270,10271,10272" + }, + { + "examine": "A collection of rare books.", + "ids": "10273" + }, + { + "examine": "Some sacks here...", + "ids": "10274,10275,10276,10277" + }, + { + "examine": "Looks like it's been out of use for some time.", + "ids": "10278" + }, + { + "examine": "It's some crates.", + "ids": "10279,10280" + }, + { + "examine": "It's a crate.", + "ids": "10281" + }, + { + "examine": "It's some crates.", + "ids": "10282" + }, + { + "examine": "Maybe I can swim across here!", + "ids": "10283,10284,10285" + }, + { + "examine": "Looks like this grain has been eaten by rats!", + "ids": "10286" + }, + { + "examine": "A way upwards.", + "ids": "10287" + }, + { + "examine": "A way down.", + "ids": "10288,10289" + }, + { + "examine": "A device for imposing human nature's arrogant will.", + "ids": "10290,10291" + }, + { + "examine": "A device for imposing human-nature's arrogant will.", + "ids": "10292" + }, + { + "examine": "A wooden barrel full of beer.", + "ids": "10293" + }, + { + "examine": "A wooden barrel full of stale beer.", + "ids": "10294" + }, + { + "examine": "Actually, I could do with a drink...", + "ids": "10295" + }, + { + "examine": "Too dirty to sit on.", + "ids": "10296,10297" + }, + { + "examine": "Some wooden crates.", + "ids": "10298" + }, + { + "examine": "Opens the rat door.", + "ids": "10299" + }, + { + "examine": "Contains many rats.", + "ids": "10300" + }, + { + "examine": "Contains rats.", + "ids": "10301" + }, + { + "examine": "Empty.", + "ids": "10302,10303" + }, + { + "examine": "A pair of sacks.", + "ids": "10304" + }, + { + "examine": "Rat infested.", + "ids": "10305" + }, + { + "examine": "Full of rat food.", + "ids": "10306" + }, + { + "examine": "Emits photons of light.", + "ids": "10307" + }, + { + "examine": "I can climb down this.", + "ids": "10308" + }, + { + "examine": "I can climb this.", + "ids": "10309" + }, + { + "examine": "Contains rats.", + "ids": "10310" + }, + { + "examine": "Opens the rat door.", + "ids": "10311" + }, + { + "examine": "Contains many rats.", + "ids": "10312" + }, + { + "examine": "A pair of sacks.", + "ids": "10313" + }, + { + "examine": "Rat infested.", + "ids": "10314" + }, + { + "examine": "Full of rat food.", + "ids": "10315" + }, + { + "examine": "Empty.", + "ids": "10316" + }, + { + "examine": "Contains rats.", + "ids": "10317" + }, + { + "examine": "Ornate metal gates.", + "ids": "10318" + }, + { + "examine": "Handy piece of garden decor.", + "ids": "10319" + }, + { + "examine": "Big enough for a cat to get in.", + "ids": "10320" + }, + { + "examine": "How dangerous, someone has left this manhole open.", + "ids": "10321" + }, + { + "examine": "I can climb down this.", + "ids": "10322" + }, + { + "examine": "I could climb up this.", + "ids": "10323" + }, + { + "examine": "I could climb down this.", + "ids": "10324" + }, + { + "examine": "A magical device that enables one to walk through walls.", + "ids": "10325" + }, + { + "examine": "A locked door.", + "ids": "10326" + }, + { + "examine": "A magical device that enables one to walk through walls.", + "ids": "10327,10328,10329,10330,10331,10332,10333,10334" + }, + { + "examine": "Observe the rats.", + "ids": "10335,10336,10337,10338,10339,10340,10341,10342,10343,10344,10345" + }, + { + "examine": "A rats home.", + "ids": "10346,10347,10348,10349,10350,10351,10352,10353,10354,10355,10356,10357" + }, + { + "examine": "Lovely comfy-looking big bed.", + "ids": "10358" + }, + { + "examine": "A drab-looking bed.", + "ids": "10359" + }, + { + "examine": "A pile of rolled up magic carpets.", + "ids": "10360" + }, + { + "examine": "A wonderful device that enables one to walk through walls.", + "ids": "10361" + }, + { + "examine": "I bet there's a needle in it somewhere.", + "ids": "10362,10363,10364,10365,10366,10367,10368,10369,10370" + }, + { + "examine": "A wooden barrel, probably for storing things.", + "ids": "10371,10372,10373" + }, + { + "examine": "Securely sealed crates that seem to be full of farming equipment.", + "ids": "10374" + }, + { + "examine": "Someone's been storing assorted tools in here.", + "ids": "10375" + }, + { + "examine": "I could just go for a choc-ice about now.", + "ids": "10376" + }, + { + "examine": "A clay oven for cooking with.", + "ids": "10377" + }, + { + "examine": "Cheaper than using a chest for storage.", + "ids": "10378" + }, + { + "examine": "Produced by the Karamja Box Company.", + "ids": "10379" + }, + { + "examine": "Small wooden boxes.", + "ids": "10380" + }, + { + "examine": "For storage.", + "ids": "10381" + }, + { + "examine": "For storing junk in.", + "ids": "10382" + }, + { + "examine": "There are some books and a box here.", + "ids": "10383" + }, + { + "examine": "For storing junk in.", + "ids": "10384" + }, + { + "examine": "There are some books and a box here.", + "ids": "10385" + }, + { + "examine": "It's empty.", + "ids": "10386,10387,10388,10389,10390,10391,10392,10393,10394,10395,10396,10397,10398,10399,10400,10401" + }, + { + "examine": "It looks like water once ran here.", + "ids": "10402,10403" + }, + { + "examine": "The water is flowing again.", + "ids": "10404" + }, + { + "examine": "It looks like water once ran here.", + "ids": "10405" + }, + { + "examine": "The water is flowing again.", + "ids": "10406" + }, + { + "examine": "It looks like water once ran here.", + "ids": "10407" + }, + { + "examine": "The water is flowing again.", + "ids": "10408" + }, + { + "examine": "It looks like water once ran here.", + "ids": "10409" + }, + { + "examine": "The water is flowing again.", + "ids": "10410,10411" + }, + { + "examine": "A strange hole carefully made in the ground.", + "ids": "10412" + }, + { + "examine": "Looks like the Genie's bed.", + "ids": "10413" + }, + { + "examine": "Generally used for putting things on.", + "ids": "10414" + }, + { + "examine": "A pile of rolled up carpets.", + "ids": "10415" + }, + { + "examine": "I'm not going down there without a rope.", + "ids": "10416" + }, + { + "examine": "This leads back to the waterfall outside.", + "ids": "10417" + }, + { + "examine": "A wooden door.", + "ids": "10418,10419,10420,10421,10422,10423,10424,10425,10426,10427,10428,10429,10430,10431,10432" + }, + { + "examine": "A bit bluer than I usually like my fires.", + "ids": "10433" + }, + { + "examine": "I can climb back to the surface.", + "ids": "10434,10435" + }, + { + "examine": "Nardah's main water supply.", + "ids": "10436" + }, + { + "examine": "There's no water here.", + "ids": "10437" + }, + { + "examine": "There should be a statue here.", + "ids": "10438" + }, + { + "examine": "The Elidinis Statuette is back in it's place.", + "ids": "10439" + }, + { + "examine": "A sitting stone.", + "ids": "10440,10441,10442,10443,10444,10445,10446,10447,10448,10449,10450,10451,10452,10453,10454,10455,10456" + }, + { + "examine": "Ali's cart, with his supply of water.", + "ids": "10457" + }, + { + "examine": "One of Ali's water barrels.", + "ids": "10458,10459,10460,10461,10462,10463,10464,10465,10466,10467,10468,10469,10470,10471,10472,10473,10474,10475,10476,10477,10478,10479,10480,10481,10482,10483,10484" + }, + { + "examine": "Items are for sale here.", + "ids": "10485,10486" + }, + { + "examine": "Various implements for working with metal.", + "ids": "10487,10488" + }, + { + "examine": "Metal plating for protection.", + "ids": "10489" + }, + { + "examine": "Generally used for putting things on.", + "ids": "10490" + }, + { + "examine": "I can climb this.", + "ids": "10493" + }, + { + "examine": "I can climb down this.", + "ids": "10494" + }, + { + "examine": "A small potted plant.", + "ids": "10499" + }, + { + "examine": "Someone has planted this.", + "ids": "10500" + }, + { + "examine": "A nicely potted fern.", + "ids": "10501" + }, + { + "examine": "Better than weeding.", + "ids": "10502" + }, + { + "examine": "Not the most inspired architectural design.", + "ids": "10503" + }, + { + "examine": "They could do with a wash.", + "ids": "10504,10505" + }, + { + "examine": "There are some pots and pans here.", + "ids": "10506,10507" + }, + { + "examine": "Some stone temple seating.", + "ids": "10508" + }, + { + "examine": "Some old looking scrolls sit here.", + "ids": "10509" + }, + { + "examine": "A case. With books.", + "ids": "10510" + }, + { + "examine": "A drab looking bed.", + "ids": "10511" + }, + { + "examine": "Lovely comfy looking big bed.", + "ids": "10512" + }, + { + "examine": "Contains equipment for growing herbs.", + "ids": "10513" + }, + { + "examine": "Herb stock is kept here.", + "ids": "10514,10515" + }, + { + "examine": "A wooden wheelbarrow.", + "ids": "10516" + }, + { + "examine": "The bank teller will serve you from here.", + "ids": "10517" + }, + { + "examine": "This booth is closed.", + "ids": "10518,10519,10520,34206" + }, + { + "examine": "The antique chalice seems to be attached to the wall.", + "ids": "10521" + }, + { + "examine": "This old tapestry depicts a bright light shining at a woman's arms.", + "ids": "10522,10523,10524" + }, + { + "examine": "I can climb these stairs.", + "ids": "10525" + }, + { + "examine": "They go down.", + "ids": "10526" + }, + { + "examine": "A tall wooden door.", + "ids": "10527,10528,10529,10530,10531,10532,10533,10534,10535,10536,10537,10538,10539,10540" + }, + { + "examine": "Flags flying the Human colours.", + "ids": "10541,10542" + }, + { + "examine": "Flags flying the Dwarf colours.", + "ids": "10543,10544" + }, + { + "examine": "Flags flying the Elf colours.", + "ids": "10545,10546" + }, + { + "examine": "Flags flying the Gnome colours.", + "ids": "10547,10548" + }, + { + "examine": "Flags flying the Werewolf colours.", + "ids": "10549,10550" + }, + { + "examine": "Flags flying the TzHaar colours.", + "ids": "10551,10552" + }, + { + "examine": "A metal portcullis.", + "ids": "10553" + }, + { + "examine": "I can climb this.", + "ids": "10554,10555" + }, + { + "examine": "There's a trapdoor in its base.", + "ids": "10556" + }, + { + "examine": "There's an open trapdoor in its base.", + "ids": "10557" + }, + { + "examine": "I wonder what's under it?", + "ids": "10558" + }, + { + "examine": "I wonder what's down there?", + "ids": "10559" + }, + { + "examine": "I can climb this.", + "ids": "10560,10561" + }, + { + "examine": "It's open.", + "ids": "10562,10563" + }, + { + "examine": "A banner proclaiming your victory over the Earth Warrior Champion!", + "ids": "10564,10565" + }, + { + "examine": "A banner proclaiming your victory over the Ghoul Champion!", + "ids": "10566,10567" + }, + { + "examine": "A banner proclaiming your victory over the Giant Champion!", + "ids": "10568,10569" + }, + { + "examine": "A banner proclaiming your victory over the Goblin Champion!", + "ids": "10570,10571" + }, + { + "examine": "A banner proclaiming your victory over the Hobgoblin Champion!", + "ids": "10572,10573" + }, + { + "examine": "A banner proclaiming your victory over the Imp Champion!", + "ids": "10574,10575" + }, + { + "examine": "A banner proclaiming your victory over the Jogre Champion!", + "ids": "10576,10577" + }, + { + "examine": "A banner proclaiming your victory over the Lesser Demon Champion!", + "ids": "10578,10579" + }, + { + "examine": "A banner proclaiming your victory over the Skeleton Champion!", + "ids": "10580,10581" + }, + { + "examine": "A banner proclaiming your victory over the Zombie Champion!", + "ids": "10582" + }, + { + "examine": "A rocky outcrop.", + "ids": "10583,10584,10585,10586,10587,10588,10589,10590,10591,10592,10593,10594" + }, + { + "examine": "Emergency exit.", + "ids": "10595" + }, + { + "examine": "Enter if you dare...", + "ids": "10596,10597,10598,10599,10600,10601,10602,10603,10604" + }, + { + "examine": "Danger", + "ids": "10605" + }, + { + "examine": "Bronze Chest*A strangely decorated chest, the open lock is painted brown.", + "ids": "10606" + }, + { + "examine": "A strangely decorated chest, the open lock is painted crimson.", + "ids": "10608" + }, + { + "examine": "A strangely decorated chest, the open lock is painted black.", + "ids": "10609" + }, + { + "examine": "A strangely decorated chest, the open lock is painted purple.", + "ids": "10610" + }, + { + "examine": "A strangely decorated steel chest, open the lock is painted blood red.", + "ids": "10611" + }, + { + "examine": "A strangely decorated steel chest, the open lock is painted brown.", + "ids": "10612" + }, + { + "examine": "A strangely decorated steel chest, the open lock is painted crimson.", + "ids": "10613" + }, + { + "examine": "A strangely decorated steel chest, the open lock is painted black.", + "ids": "10614" + }, + { + "examine": "A strangely decorated steel chest, the open lock is painted purple.", + "ids": "10615" + }, + { + "examine": "A strangely decorated black chest, the open lock is painted blood red.", + "ids": "10616" + }, + { + "examine": "A strangely decorated black chest, the open lock is painted brown.", + "ids": "10617" + }, + { + "examine": "A strangely decorated black chest, the open lock is painted crimson.", + "ids": "10618" + }, + { + "examine": "A strangely decorated black chest, the open lock is painted black.", + "ids": "10619" + }, + { + "examine": "A strangely decorated black chest, the open lock is painted purple.", + "ids": "10620" + }, + { + "examine": "A strangely decorated silver chest, the open lock is painted blood red.", + "ids": "10621" + }, + { + "examine": "A strangely decorated silver chest, the open lock is painted brown.", + "ids": "10622" + }, + { + "examine": "A strangely decorated silver chest, the open lock is painted crimson.", + "ids": "10623" + }, + { + "examine": "A strangely decorated silver chest, the open lock is painted black.", + "ids": "10624" + }, + { + "examine": "A strangely decorated silver chest, the open lock is painted purple.", + "ids": "10625,10626,10627,10628,10629,10630,10631,10632,10633,10634,10635,10636,10637,10638" + }, + { + "examine": "Shrine to the glory of Saradomin.", + "ids": "10639,10640" + }, + { + "examine": "Used for sharpening blades.", + "ids": "10641,10642,10643,10644,10645,10646,10647,10648,10649,10650,10651" + }, + { + "examine": "A large tree.", + "ids": "10652" + }, + { + "examine": "A decorated tree.", + "ids": "10653,10654" + }, + { + "examine": "A large evergreen tree.", + "ids": "10655" + }, + { + "examine": "A decorated tree.", + "ids": "10656,10657,10658,10659,10660,10661,10662,10663" + }, + { + "examine": "A tall Trollweiss Spruce. An engraving on the trunk reads, 'Ug loves Aga'.", + "ids": "10664" + }, + { + "examine": "Boxes containing stuff.", + "ids": "10665,10666,10667,10668,10669,10670" + }, + { + "examine": "Only sawdust...", + "ids": "10671" + }, + { + "examine": "Reclaim your lost puppets!", + "ids": "10672" + }, + { + "examine": "Equipment for colouring items.", + "ids": "10673,10674,10675" + }, + { + "examine": "A puppet is being constructed here.", + "ids": "10676,10677,10678" + }, + { + "examine": "A box containing unpainted decorations.", + "ids": "10679,10680,10681,10682,10683,10684,10685" + }, + { + "examine": "Box containing blue puppet heads.", + "ids": "10686" + }, + { + "examine": "Box containing blue puppet torsos.", + "ids": "10687" + }, + { + "examine": "Box containing blue puppet arms.", + "ids": "10688" + }, + { + "examine": "Box containing blue puppet legs.", + "ids": "10689" + }, + { + "examine": "Box containing red puppet heads.", + "ids": "10690" + }, + { + "examine": "Box containing red puppet torsos.", + "ids": "10691" + }, + { + "examine": "Box containing red puppet arms.", + "ids": "10692" + }, + { + "examine": "Box containing red puppet legs.", + "ids": "10693" + }, + { + "examine": "Box containing green puppet heads.", + "ids": "10694" + }, + { + "examine": "Box containing green puppet torsos.", + "ids": "10695" + }, + { + "examine": "Box containing green puppet arms.", + "ids": "10696" + }, + { + "examine": "Box containing green puppet legs.", + "ids": "10697" + }, + { + "examine": "What could be down here?", + "ids": "10698" + }, + { + "examine": "You can climb up these.", + "ids": "10699,10700" + }, + { + "examine": "A blue crate. Probably containing puppets.", + "ids": "10701" + }, + { + "examine": "A green crate. Probably containing puppets.", + "ids": "10702" + }, + { + "examine": "A red crate. Probably containing puppets.", + "ids": "10703" + }, + { + "examine": "A large crate. More puppets?", + "ids": "10704" + }, + { + "examine": "Some large wooden crates.", + "ids": "10705" + }, + { + "examine": "A large box full of wood chippings..", + "ids": "10706" + }, + { + "examine": "A wooden ladder.", + "ids": "10707,10708,10709" + }, + { + "examine": "Pots full of paint.", + "ids": "10710,10711,10712,10713,10714,10715,10716,10717,10718,10719,10720" + }, + { + "examine": "A doorway made of light.", + "ids": "10721" + }, + { + "examine": "Filled to the brim with knowledge.", + "ids": "10722,10723" + }, + { + "examine": "A nicely carved wooden chair.", + "ids": "10724" + }, + { + "examine": "A pile of animal Bones.", + "ids": "10725,10726,10727,10728,10729,10730,10731,10732" + }, + { + "examine": "Hidden away, I wonder where it goes?", + "ids": "10733" + }, + { + "examine": "Somewhere to put money.", + "ids": "10734" + }, + { + "examine": "Somewhere to offer food.", + "ids": "10735" + }, + { + "examine": "A statue.", + "ids": "10736,10737" + }, + { + "examine": "A statue representing water.", + "ids": "10738" + }, + { + "examine": "A statue representing air.", + "ids": "10739,10740,10741,10742,10743,10744,10745,10746,10747,10748,10749,10750,10751,10752,10753,10754,10755,10756,10757,10758,10759,10760,10761,10762,10763,10764,10765,10766,10767" + }, + { + "examine": "A place to put your money.", + "ids": "10768,10769,10770" + }, + { + "examine": "Stairs.", + "ids": "10771,10772,10773,10774,10775,10776,10777" + }, + { + "examine": "A teleport to the Telekinetic Theatre.", + "ids": "10778" + }, + { + "examine": "A teleport to the Enchanting Chamber.", + "ids": "10779" + }, + { + "examine": "A teleport to the Alchemists' Playground.", + "ids": "10780" + }, + { + "examine": "A teleport to the Creature Graveyard.", + "ids": "10781" + }, + { + "examine": "A teleport to the Entrance hall.", + "ids": "10782" + }, + { + "examine": "This may be worth opening.", + "ids": "10783,10784,10785,10786,10787,10788,10789,10790,10791,10792,10793,10794,10795,10796,10797,10798" + }, + { + "examine": "Some simple cubes.", + "ids": "10799" + }, + { + "examine": "A pile of cylindrical shapes.", + "ids": "10800" + }, + { + "examine": "A pile of Icosahedrons.", + "ids": "10801" + }, + { + "examine": "A pile of pentamids.", + "ids": "10802" + }, + { + "examine": "A hole the perfect shape for spheres", + "ids": "10803" + }, + { + "examine": "Perhaps the pixies will be back next year.", + "ids": "10804" + }, + { + "examine": "Sandy's desk is piled high with paperwork towers.", + "ids": "10805,10806" + }, + { + "examine": "A large steaming mug of the finest Karamja Coffee.", + "ids": "10807" + }, + { + "examine": "Looks useful for putting things on.", + "ids": "10808" + }, + { + "examine": "A bin full of paper.", + "ids": "10809,10810,10811,10812" + }, + { + "examine": "Betty's counter. There is a vial standing on it.", + "ids": "10813" + }, + { + "examine": "It's very sandy.", + "ids": "10814,10815,10816" + }, + { + "examine": "Pull me!", + "ids": "10817" + }, + { + "examine": "Doesn't look like the way out.", + "ids": "10818,10819" + }, + { + "examine": "A glowing barrier of energy prevents your escape.", + "ids": "10820,10821,10822,10823" + }, + { + "examine": "Oh for a marshmallow on a stick!", + "ids": "10824,10825,10826" + }, + { + "examine": "An ornate fountain.", + "ids": "10827" + }, + { + "examine": "Smells like fish.", + "ids": "10828,10829,10830,10831,10832,10833,10834,10835,10836,10837,10838,10839,10840,10841,10842,10843,10844,10845,10846,10847" + }, + { + "examine": "This leads to a tunnel too steep for me to scale.", + "ids": "10848,10849,10850" + }, + { + "examine": "I can climb this rocky outcrop.", + "ids": "10851" + }, + { + "examine": "A rocky outcrop.", + "ids": "10852,10853,10854" + }, + { + "examine": "The doorway leads down into the pyramid.", + "ids": "10855,10856" + }, + { + "examine": "I can climb these stairs.", + "ids": "10857" + }, + { + "examine": "I can climb down these.", + "ids": "10858" + }, + { + "examine": "A gap.", + "ids": "10859" + }, + { + "examine": "A narrow ledge.", + "ids": "10860" + }, + { + "examine": "A gap.", + "ids": "10861,10862,10863,10864" + }, + { + "examine": "It looks like I can clamber over this.", + "ids": "10865,10866" + }, + { + "examine": "A wooden plank.", + "ids": "10867,10868,10869,10870,10871,10872,10873,10874" + }, + { + "examine": "A stone block.", + "ids": "10875,10876,10877,10878,10879,10880,10881" + }, + { + "examine": "A gap.", + "ids": "10882,10883,10884,10885" + }, + { + "examine": "A narrow ledge.", + "ids": "10886,10887,10888,10889,10890,10891,10892,10893,10894,10895,10896,10897,10898,10899,10900,10901,10902,10903,10904,10905,10906,10907,10908,10909,10910,10911,10912,10913,10914,10915,10916,10917,10918,10919,10920,10921,10922,10923,10924,10925,10926,10927,10928,10929,10930,10931,10932,10933,10934,10935,10936,10937,10938,10939,10940,10941,10942,10943" + }, + { + "examine": "A rocky outcrop.", + "ids": "10944,10945,10946,10947,10948,10949" + }, + { + "examine": "Looks sturdy enough to climb!", + "ids": "10950,10951,10952" + }, + { + "examine": "Something heavy must have made this.", + "ids": "10953" + }, + { + "examine": "The perfect place for a picnic.", + "ids": "10954" + }, + { + "examine": "A large statue made of sandstone.", + "ids": "10955,10956,10957" + }, + { + "examine": "Made of sandstone and granite.", + "ids": "10958,10959,10960,10961" + }, + { + "examine": "A large statue.", + "ids": "10962,10963,10964,10965,10966,10967,10968,10969,10970" + }, + { + "examine": "It has no limbs.", + "ids": "10971" + }, + { + "examine": "It has a left arm.", + "ids": "10972" + }, + { + "examine": "It has a right arm.", + "ids": "10973" + }, + { + "examine": "It has a left leg.", + "ids": "10974" + }, + { + "examine": "It has a right leg.", + "ids": "10975" + }, + { + "examine": "It has a left arm and right arm.", + "ids": "10976" + }, + { + "examine": "It has a left arm and left leg.", + "ids": "10977" + }, + { + "examine": "It has a left arm and right leg.", + "ids": "10978" + }, + { + "examine": "It has a right arm and left leg.", + "ids": "10979" + }, + { + "examine": "It has a right arm and right leg.", + "ids": "10980" + }, + { + "examine": "It has a left leg and right leg.", + "ids": "10981" + }, + { + "examine": "It has a left arm, right arm and left leg.", + "ids": "10982" + }, + { + "examine": "It has a left arm, right arm and right leg.", + "ids": "10983" + }, + { + "examine": "It has a left arm, left leg and right leg.", + "ids": "10984" + }, + { + "examine": "It has a right arm, left leg and right leg.", + "ids": "10985" + }, + { + "examine": "It has all its limbs still attached.", + "ids": "10986,10987" + }, + { + "examine": "There's a recess on the top shaped like a head.", + "ids": "10988" + }, + { + "examine": "There's a stone head in a recess on the top.", + "ids": "10989" + }, + { + "examine": "The blood globe is lit.", + "ids": "10990" + }, + { + "examine": "The ice globe is lit.", + "ids": "10991" + }, + { + "examine": "The shadow globe is lit.", + "ids": "10992" + }, + { + "examine": "The smoke globe is lit.", + "ids": "10993" + }, + { + "examine": "The blood and ice globes are lit.", + "ids": "10994" + }, + { + "examine": "The blood and shadow globes are lit.", + "ids": "10995" + }, + { + "examine": "The blood and smoke globes are lit.", + "ids": "10996" + }, + { + "examine": "The ice and shadow globes are lit.", + "ids": "10997" + }, + { + "examine": "The ice and smoke globes are lit.", + "ids": "10998" + }, + { + "examine": "The shadow and smoke globes are lit.", + "ids": "10999" + }, + { + "examine": "The ice, shadow and smoke globes are lit.", + "ids": "11000" + }, + { + "examine": "The blood, shadow and smoke globes are lit.", + "ids": "11001" + }, + { + "examine": "The blood, ice and smoke globes are lit.", + "ids": "11002" + }, + { + "examine": "The blood, ice and shadow globes are lit.", + "ids": "11003" + }, + { + "examine": "All the globes", + "ids": "11004" + }, + { + "examine": "It's made of a magical force.", + "ids": "11005,11006" + }, + { + "examine": "This fountain is frozen solid.", + "ids": "11007,11008" + }, + { + "examine": "It's blocked and is spewing out smoke.", + "ids": "11009" + }, + { + "examine": "A hot place for forging things in.", + "ids": "11010,11011,11012,11013,11014,11015,11016" + }, + { + "examine": "Something burned in here long ago.", + "ids": "11017,11018,11019" + }, + { + "examine": "Something's burning here.", + "ids": "11020,11021,11022,11023,11024,11025,11026,11027" + }, + { + "examine": "A finished wall.", + "ids": "11028,11029,11030,11031" + }, + { + "examine": "A nearly finished wall.", + "ids": "11032,11033" + }, + { + "examine": "A half finished wall.", + "ids": "11034,11035" + }, + { + "examine": "It needs much more repair.", + "ids": "11036,11037" + }, + { + "examine": "A ruined wall.", + "ids": "11038,11039" + }, + { + "examine": "A pile of bricks dislodged from the wall nearby.", + "ids": "11040" + }, + { + "examine": "I can climb this.", + "ids": "11041" + }, + { + "examine": "What's down there?", + "ids": "11042" + }, + { + "examine": "I can climb this.", + "ids": "11043,11044,11045,11046,11047,11048" + }, + { + "examine": "I wonder what's under it?", + "ids": "11049" + }, + { + "examine": "I wonder what's down there?", + "ids": "11050" + }, + { + "examine": "There's a recess in it in the shape of a Z.", + "ids": "11051,11052" + }, + { + "examine": "There's a recess in it in the shape of an M.", + "ids": "11053,11054" + }, + { + "examine": "There's a recess in it in the shape of an R.", + "ids": "11055,11056" + }, + { + "examine": "There's a recess in it in the shape of a K.", + "ids": "11057,11058" + }, + { + "examine": "There's a recess on the top shaped like a head.", + "ids": "11059" + }, + { + "examine": "There's a sigil on it shaped like a Z.", + "ids": "11060" + }, + { + "examine": "There's a sigil on it shaped like an M.", + "ids": "11061" + }, + { + "examine": "There's a sigil on it shaped like an R.", + "ids": "11062" + }, + { + "examine": "There's a sigil on it shaped like a K.", + "ids": "11063" + }, + { + "examine": "There's a recess in it in the shape of a left arm.", + "ids": "11064,11065" + }, + { + "examine": "There's a recess in it in the shape of a right arm.", + "ids": "11066,11067" + }, + { + "examine": "There's a recess in it in the shape of a left leg.", + "ids": "11068,11069" + }, + { + "examine": "There's a recess in it in the shape of a right leg.", + "ids": "11070,11071" + }, + { + "examine": "Looks like there was once a building here.", + "ids": "11072,11073,11074,11075,11076,11077,11078" + }, + { + "examine": "There's a hole in the roof!", + "ids": "11079" + }, + { + "examine": "An old-looking bit of scaffolding.", + "ids": "11080" + }, + { + "examine": "An old-looking ladder.", + "ids": "11081" + }, + { + "examine": "A wooden wheelbarrow.", + "ids": "11082,11083,11084,11085,11086,11087,11088,11089,11090,11091,11092,11093,11094,11095,11096" + }, + { + "examine": "A rock with a pickaxe.", + "ids": "11097" + }, + { + "examine": "A rock.", + "ids": "11098,11099,11100,11101,11102,11103,11104,11105,11106,11107,11108,11109,11110,11111" + }, + { + "examine": "This tree has long been dead.", + "ids": "11112" + }, + { + "examine": "A dried up bush, void of life.", + "ids": "11113,11114,11115,11116,11117,11118,11119,11120,11121,11122,11123,11124,11125,11126,11127,11128,11129,11130,11131,11132,11133,11134,11135,11136,11137,11138,11139,11140" + }, + { + "examine": "He's been trapped in there for a long time.", + "ids": "11141,11142,11143,11144,11145,11146,11147,11148,11149,11150" + }, + { + "examine": "There's a recess in it in the shape of an arm.", + "ids": "11151" + }, + { + "examine": "There's a recess in it in the shape of a leg.", + "ids": "11152" + }, + { + "examine": "A simple stone pedestal.", + "ids": "11153,11154,11155,11156,11157,11158,11159,11160,11161" + }, + { + "examine": "A big grinding thing.", + "ids": "11162,11163,11164" + }, + { + "examine": "A rocky outcrop.", + "ids": "11165,11166,11167,11168,11169,11170,11171,11172,11173,11174,11175,11176,11177,11178,11179,11180,11181,11182,11183,11184,11185,11186,11187,11188,11189,11190,11191,11192,11193,11194,11195" + }, + { + "examine": "An elf-fashioned door.", + "ids": "11196,11197" + }, + { + "examine": "The ladder to the Runeversi challenge room for experienced players.", + "ids": "11198" + }, + { + "examine": "The ladder back to the Runeversi challenge room.", + "ids": "11199" + }, + { + "examine": "The ladder to the Runesquares challenge room for experienced players.", + "ids": "11200" + }, + { + "examine": "The ladder back to the Runesquares challenge room.", + "ids": "11201" + }, + { + "examine": "A game of runesquares is being played on this table.", + "ids": "11202" + }, + { + "examine": "A game of runeversi is being played on this table.", + "ids": "11203" + }, + { + "examine": "Runesquares challenge room.", + "ids": "11204" + }, + { + "examine": "Runeversi challenge room.", + "ids": "11205" + }, + { + "examine": "Runesquares challenge room for experienced players.", + "ids": "11206" + }, + { + "examine": "Runeversi challenge room for experienced players.", + "ids": "11207" + }, + { + "examine": "Looks comfortable...", + "ids": "11208" + }, + { + "examine": "Permission to board?", + "ids": "11209,11210,11211,11212,11213" + }, + { + "examine": "Ready...aim...fire!", + "ids": "11214" + }, + { + "examine": "Not likely to work with that hole in it.", + "ids": "11215" + }, + { + "examine": "Where did the barrel go?", + "ids": "11216" + }, + { + "examine": "Ready to fire.", + "ids": "11217,11218" + }, + { + "examine": "If I can't destroy this we're sunk.", + "ids": "11219" + }, + { + "examine": "Let's hope they don't repair it.", + "ids": "11220,11221,11222,11223,11224,11225,11226,11227" + }, + { + "examine": "Useful for transportation of valuable items.", + "ids": "11228,11229,11230" + }, + { + "examine": "I wonder what's inside.", + "ids": "11231" + }, + { + "examine": "Perhaps I should search it.", + "ids": "11232,11233" + }, + { + "examine": "A wooden barrel for storage.", + "ids": "11234,11235" + }, + { + "examine": "For the storage of plunder.", + "ids": "11236,11237" + }, + { + "examine": "Warning! Contents may explode!", + "ids": "11238" + }, + { + "examine": "I wouldn't be surprised if bits land over in Lumbridge.", + "ids": "11239" + }, + { + "examine": "Rigged to blow.", + "ids": "11240,11241,11242,11243" + }, + { + "examine": "I can climb down here.", + "ids": "11244" + }, + { + "examine": "Full of gunpowder. I'd best be careful.", + "ids": "11245" + }, + { + "examine": "Stores repair items.", + "ids": "11246,11247" + }, + { + "examine": "Cannons. Lots of cannons.", + "ids": "11248,11249,11250,11251,11252,11253,11254,11255,11256,11257,11258,11259,11260,11261,11262,11263,11264,11265,11266,11267,11268,11269,11270,11271,11272,11273,11274,11275" + }, + { + "examine": "Holds up the sails.", + "ids": "11276,11277,11278,11279" + }, + { + "examine": "Useful if there is any wind.", + "ids": "11280" + }, + { + "examine": "Useful for making ships move.", + "ids": "11281,11282" + }, + { + "examine": "Useful for making ships move", + "ids": "11283,11284,11285,11286" + }, + { + "examine": "This figure brings luck to those who sail.", + "ids": "11287,11288" + }, + { + "examine": "Allows access to other parts of the ship.", + "ids": "11289,11290" + }, + { + "examine": "Useful for making ships move.", + "ids": "11291" + }, + { + "examine": "A conveniently rolled sail.", + "ids": "11292,11293,11294,11295,11296,11297,11298,11299,11300,11301" + }, + { + "examine": "Useful for making ships move.", + "ids": "11302" + }, + { + "examine": "A conveniently rolled sail.", + "ids": "11303,11304" + }, + { + "examine": "A wooden barrel for storage.", + "ids": "11305" + }, + { + "examine": "Without this I'm going around in circles.", + "ids": "11306" + }, + { + "examine": "How much does this weigh?", + "ids": "11307" + }, + { + "examine": "I can climb up here.", + "ids": "11308" + }, + { + "examine": "I can go below decks with this ladder.", + "ids": "11309" + }, + { + "examine": "The only way to get up the mast.", + "ids": "11310" + }, + { + "examine": "For swinging on.", + "ids": "11311" + }, + { + "examine": "This isn't currently usable.", + "ids": "11312,11313,11314" + }, + { + "examine": "This is rigged to blow!", + "ids": "11315" + }, + { + "examine": "You can light this.", + "ids": "11316" + }, + { + "examine": "That water can't be good.", + "ids": "11317,11318" + }, + { + "examine": "That's plugged it.", + "ids": "11319" + }, + { + "examine": "A wooden barrel for storage.", + "ids": "11320,11321,11322" + }, + { + "examine": "For storing plunder.", + "ids": "11323" + }, + { + "examine": "This seems to stand out.", + "ids": "11324,11325,11326,11327,11328,11329" + }, + { + "examine": "A wooden crate.", + "ids": "11330,11331" + }, + { + "examine": "A security gate.", + "ids": "11332,11333,11334" + }, + { + "examine": "Bamboo strips have been lashed together to make this rickety desk.", + "ids": "11335,11336,11337" + }, + { + "examine": "The bank teller will serve you from here.", + "ids": "11338" + }, + { + "examine": "Shake that booty!", + "ids": "11339,11340" + }, + { + "examine": "An old storage chest.", + "ids": "11341" + }, + { + "examine": "Stores items for the journey.", + "ids": "11342,11343,11344,11345,11346,11347,11348,11349,11350,11351,11352,11353" + }, + { + "examine": "Who knows where it may lead?", + "ids": "11354,11355" + }, + { + "examine": "A gateway back to 2009Scape.", + "ids": "11356" + }, + { + "examine": "The Professor's been at it again!", + "ids": "11357" + }, + { + "examine": "I can climb up these stairs.", + "ids": "11358,11359" + }, + { + "examine": "This stall smells great.", + "ids": "11360" + }, + { + "examine": "It's a raw chompybird on a spit.", + "ids": "11361" + }, + { + "examine": "It's a raw Rabbit on a spit.", + "ids": "11362" + }, + { + "examine": "It's an iron spit.", + "ids": "11363" + }, + { + "examine": "A stone pillar that looks like Bob the Cat.", + "ids": "11364" + }, + { + "examine": "A stone pillar that looks like Zamorak.", + "ids": "11365" + }, + { + "examine": "A stone pillar that looks like Guthix.", + "ids": "11366" + }, + { + "examine": "A stone pillar that looks like Saradomin.", + "ids": "11367,11368,11369,11370,11371,11372,11373,11374,11375,11376,11377,11378" + }, + { + "examine": "A large church door.", + "ids": "11379,11380,11381,11382" + }, + { + "examine": "A stone pillar that looks like Saradomin.", + "ids": "11383,11384,11385" + }, + { + "examine": "A stone pillar that looks like Guthix.", + "ids": "11386,11387,11388" + }, + { + "examine": "A stone pillar that looks like Zamorak.", + "ids": "11389,11390,11391" + }, + { + "examine": "A stone pillar that looks like Bob the Cat.", + "ids": "11392,11393,11394" + }, + { + "examine": "A candle in a holder.", + "ids": "11395" + }, + { + "examine": "A melted candle.", + "ids": "11396" + }, + { + "examine": "A candle flame.", + "ids": "11397" + }, + { + "examine": "Interface surround.", + "ids": "11398" + }, + { + "examine": "Interface button up.", + "ids": "11399" + }, + { + "examine": "Interface button down.", + "ids": "11400" + }, + { + "examine": "Interface button left.", + "ids": "11401" + }, + { + "examine": "Interface button right.", + "ids": "11402" + }, + { + "examine": "Interface button ignite.", + "ids": "11403" + }, + { + "examine": "Hot!", + "ids": "11404,11405,11406,11407,11408" + }, + { + "examine": "It's a sewer pipe with some rope tied to it.", + "ids": "11409,11410" + }, + { + "examine": "A bit of rope.", + "ids": "11411" + }, + { + "examine": "A section of rope.", + "ids": "11412" + }, + { + "examine": "A bit of rope.", + "ids": "11413,11414,11415,11416" + }, + { + "examine": "You can climb down here.", + "ids": "11417" + }, + { + "examine": "Hard to notice, but this mud looks disturbed.", + "ids": "11418,11419,11420,11421,11422" + }, + { + "examine": "It's a grill.", + "ids": "11423" + }, + { + "examine": "A rocky outcrop.", + "ids": "11424,11425,11426,11427,11428,11429,11430,11431,11432,11433,11434,11435,11436,11437,11438,11439,11440,11441,11442,11443,11444,11445,11446,11447,11448" + }, + { + "examine": "This door is locked.", + "ids": "11449" + }, + { + "examine": "The door is slightly ajar.", + "ids": "11450" + }, + { + "examine": "A lever pointing upwards.", + "ids": "11451" + }, + { + "examine": "A lever pointing downwards.", + "ids": "11452" + }, + { + "examine": "A lever pointing upwards.", + "ids": "11453" + }, + { + "examine": "A lever pointing downwards.", + "ids": "11454" + }, + { + "examine": "A lever pointing upwards.", + "ids": "11455" + }, + { + "examine": "A lever pointing downwards.", + "ids": "11456" + }, + { + "examine": "A lever pointing upwards.", + "ids": "11457" + }, + { + "examine": "A lever pointing downwards.", + "ids": "11458" + }, + { + "examine": "A lever pointing upwards.", + "ids": "11459" + }, + { + "examine": "A lever pointing downwards.", + "ids": "11460" + }, + { + "examine": "A lever pointing upwards.", + "ids": "11461" + }, + { + "examine": "A lever pointing downwards.", + "ids": "11462,11463,11464,11465,11466,11467" + }, + { + "examine": "Handy that they're already lit.", + "ids": "11468" + }, + { + "examine": "Disturbingly its eyes look everywhere in the room except at you.", + "ids": "11469" + }, + { + "examine": "The door is closed.", + "ids": "11470" + }, + { + "examine": "The door is not closed.", + "ids": "11471" + }, + { + "examine": "Little candles flickering.", + "ids": "11472,11473,11474,11475,11476,11477,11478,11479,11480,11481,11482" + }, + { + "examine": "It's closed.", + "ids": "11483" + }, + { + "examine": "A wooden barrel for storage.", + "ids": "11484" + }, + { + "examine": "A wooden crate.", + "ids": "11485" + }, + { + "examine": "Some wooden crates.", + "ids": "11486" + }, + { + "examine": "Some wooden boxes.", + "ids": "11487" + }, + { + "examine": "For storage.", + "ids": "11488" + }, + { + "examine": "Do I dare sit on this?", + "ids": "11490" + }, + { + "examine": "A nice sturdy looking table.", + "ids": "11491" + }, + { + "examine": "Not so good for sitting on.", + "ids": "11492" + }, + { + "examine": "Looks a bit shabby...", + "ids": "11493" + }, + { + "examine": "An enigmatic cabbage.", + "ids": "11494" + }, + { + "examine": "Not your average garden feature...", + "ids": "11495" + }, + { + "examine": "Did that chair just move?", + "ids": "11496" + }, + { + "examine": "Disturbingly its eyes look everywhere in the room except at you.", + "ids": "11497" + }, + { + "examine": "Dare I go up?", + "ids": "11498" + }, + { + "examine": "These stairs look spooky!", + "ids": "11499" + }, + { + "examine": "A filthy but sturdy looking table.", + "ids": "11500" + }, + { + "examine": "I'm not eating off that.", + "ids": "11501,11502,11503,11504,11505,11506,11507,11508,11509" + }, + { + "examine": "This tree has long been dead.", + "ids": "11510" + }, + { + "examine": "I can climb up these stairs.", + "ids": "11511,11512,11513,11514,11515,11516,11517,11518,11519,11520,11521,11522,11523,11524,11525,11526,11527,11528,11529,11530,11531,11532,11533,11534,11535,11536,11537,11538,11539,11540,11541,11542,11543,11544,11545" + }, + { + "examine": "It's a strange machine.", + "ids": "11546,11547,11548,11549,11550" + }, + { + "examine": "It's a table for putting objects on.", + "ids": "11551" + }, + { + "examine": "A rocky outcrop.", + "ids": "11552,11553,11554,11555,11556,11557,11558,11559,11560,11561,11562,11563,11564,11565,11566,11567,11568,11569,11570,11571,11572,11573,11574,11575,11576,11577,11578,11579,11580,11581,11582,11583,11584,11585,11586,11587,11588" + }, + { + "examine": "A wooden barrel for storage.", + "ids": "11589,11590,11591,11592,11593,11594,11595,11596,11597,11598,29333" + }, + { + "examine": "A wooden crate.", + "ids": "11599" + }, + { + "examine": "Convenient for storage.", + "ids": "11600" + }, + { + "examine": "Bake your clay pots in here.", + "ids": "11601,11602" + }, + { + "examine": "A wooden stool.", + "ids": "11603,11604,11605" + }, + { + "examine": "A simple torch stuck in the ground.", + "ids": "11606,11607,11608,11609,11610,11611,11612,11613" + }, + { + "examine": "A barbarian flag.", + "ids": "11614,11615" + }, + { + "examine": "Keeps the wind out.", + "ids": "11616" + }, + { + "examine": "It would keep the wind out better if it were closed.", + "ids": "11617,11618" + }, + { + "examine": "Generally used for putting things on.", + "ids": "11619" + }, + { + "examine": "The entrance to the barbarians' longhall.", + "ids": "11620,11621,11622,11623,11624,11625" + }, + { + "examine": "Items are for sale here.", + "ids": "11626" + }, + { + "examine": "A small wooden table.", + "ids": "11627,11628" + }, + { + "examine": "A rocky outcrop that looks rather crumbly.", + "ids": "11629" + }, + { + "examine": "This tells you which way is which.", + "ids": "11630,11631,11632,11633" + }, + { + "examine": "A rock.", + "ids": "11634,11635,11636,11637,11638,11639" + }, + { + "examine": "Keeps unwelcome folk out of Falador.", + "ids": "11640,11641,11642,11643,11644,11645,11646,11647,11648,11649,11650,11651,11652,11653,11654,11655,11656" + }, + { + "examine": "A rack for displaying fine maces.", + "ids": "11657" + }, + { + "examine": "Shelves for maces.", + "ids": "11658" + }, + { + "examine": "A barrel of maces.", + "ids": "11659" + }, + { + "examine": "A table bearing a fine selection of maces.", + "ids": "11660" + }, + { + "examine": "A handy source of water.", + "ids": "11661" + }, + { + "examine": "Fine gems for sale!", + "ids": "11662" + }, + { + "examine": "Precious stones for sale.", + "ids": "11663,11664,11665" + }, + { + "examine": "A hot furnace.", + "ids": "11666,11667,11668,11669,11670,11671,11672,11673,36956" + }, + { + "examine": "Rising Sun Tavern.", + "ids": "11674" + }, + { + "examine": "Rising Sun Tavern, Falador.", + "ids": "11675,11676" + }, + { + "examine": "Powers the spinning pole outside.", + "ids": "11677" + }, + { + "examine": "The traditional sign of a barber.", + "ids": "11678,11679,11680,11681" + }, + { + "examine": "A small wooden table.", + "ids": "11682,11683,11684,11685,11686,11687,11688,11689,11690,11691,11692" + }, + { + "examine": "A statue of a famous White Knight.", + "ids": "11693,11694,11695,11696,11697" + }, + { + "examine": "Filled to the brim with knowledge.", + "ids": "11698" + }, + { + "examine": "The flag of Asgarnia.", + "ids": "11699" + }, + { + "examine": "I thought he'd be bigger than that.", + "ids": "11700" + }, + { + "examine": "Big beard, robes. Yeah, that's Saradomin.", + "ids": "11701,11702,11703,11704,11705" + }, + { + "examine": "Nicely planted.", + "ids": "11706" + }, + { + "examine": "The door is closed.", + "ids": "11707" + }, + { + "examine": "The door is open.", + "ids": "11708" + }, + { + "examine": "The door is closed.", + "ids": "11709" + }, + { + "examine": "The door is open.", + "ids": "11710" + }, + { + "examine": "The door is closed.", + "ids": "11711" + }, + { + "examine": "The door is open.", + "ids": "11712" + }, + { + "examine": "The door is close.", + "ids": "11713" + }, + { + "examine": "The door is closed.", + "ids": "11714" + }, + { + "examine": "The door is open.", + "ids": "11715" + }, + { + "examine": "A grand door.", + "ids": "11716,11717,11718,11719,11720,11721,11722,11723" + }, + { + "examine": "I can climb up these stairs.", + "ids": "11724" + }, + { + "examine": "I can climb down these stairs.", + "ids": "11725,11726" + }, + { + "examine": "I can climb this.", + "ids": "11727" + }, + { + "examine": "I can climb down this.", + "ids": "11728" + }, + { + "examine": "I can climb up these stairs.", + "ids": "11729,11730" + }, + { + "examine": "I can climb down these stairs.", + "ids": "11731" + }, + { + "examine": "I can climb up these stairs.", + "ids": "11732" + }, + { + "examine": "I can climb down these stairs.", + "ids": "11733" + }, + { + "examine": "I can climb these stairs.", + "ids": "11734" + }, + { + "examine": "They go down.", + "ids": "11735" + }, + { + "examine": "I can climb these stairs.", + "ids": "11736" + }, + { + "examine": "They go down.", + "ids": "11737" + }, + { + "examine": "A nice sturdy-looking table.", + "ids": "11738" + }, + { + "examine": "Allows access to above level.", + "ids": "11739,11740" + }, + { + "examine": "Allows access to level below.", + "ids": "11741,11742" + }, + { + "examine": "A nice sturdy looking table.", + "ids": "11743" + }, + { + "examine": "Small wooden boxes.", + "ids": "11744" + }, + { + "examine": "Wooden crates.", + "ids": "11745" + }, + { + "examine": "A wooden stool.", + "ids": "11746" + }, + { + "examine": "A basic bed.", + "ids": "11747" + }, + { + "examine": "Nice banquet table.", + "ids": "11748" + }, + { + "examine": "A sturdy-looking round table.", + "ids": "11749,11750,11751,11752" + }, + { + "examine": "Armour of a White Knight. Decorative, but still effective.", + "ids": "11753,11754" + }, + { + "examine": "'Concerned about theft? Set a Bank PIN today!'", + "ids": "11755" + }, + { + "examine": "'Customers are reminded NEVER to tell ANYONE their password.'", + "ids": "11756" + }, + { + "examine": "This chest contains an impressive amount of Gold!!", + "ids": "11757" + }, + { + "examine": "The bank teller will serve you from here.", + "ids": "11758" + }, + { + "examine": "Hope springs eternal.", + "ids": "11759" + }, + { + "examine": "A carving of a figure from the history of 2009Scape.", + "ids": "11761" + }, + { + "examine": "A source of foamy neurotoxin.", + "ids": "11762" + }, + { + "examine": "Where drunkards may be found.", + "ids": "11763" + }, + { + "examine": "So clean you could eat your dinner off it.", + "ids": "11764" + }, + { + "examine": "I'd really hate to drink anything that had been in here.", + "ids": "11765" + }, + { + "examine": "Smells alcoholic.", + "ids": "11766" + }, + { + "examine": "Dusty old books.", + "ids": "11767" + }, + { + "examine": "What ancient rites were performed here?", + "ids": "11782,11783,11784,11785,11786,11787,11788" + }, + { + "examine": "Weathered rocks.", + "ids": "11789,11790,11791,11792" + }, + { + "examine": "Best used with a bucket.", + "ids": "11793" + }, + { + "examine": "Ready for a quick snip?", + "ids": "11794" + }, + { + "examine": "Put your head in my hands...", + "ids": "11795" + }, + { + "examine": "Ooh", + "ids": "11796,11797,11798" + }, + { + "examine": "Makes your hair stay curly.", + "ids": "11799,11800,11801,11802,11803,11804,11805,11806,11807,11808,11809,11810,11811" + }, + { + "examine": "Running water", + "ids": "11812" + }, + { + "examine": "Might be handy for a workman.", + "ids": "11813,11814,11815,11816,11817,11818,11819,11820,11821,11822,11823,11824,11825,11826,11827,11828,11829,11830,11831,11832,11833,11834,11835,11836,11837,11838,11839" + }, + { + "examine": "A pile of bricks.", + "ids": "11840,11841,11842,11843" + }, + { + "examine": "It looks like I might be able to climb over this piece of the wall...", + "ids": "11844,11845,11846,11847" + }, + { + "examine": "An attractively laid out collection of ranging weapons.", + "ids": "11848" + }, + { + "examine": "Contains washing items.", + "ids": "11849,11850,11851,11852,11853,11854,11855,11856,11857,11858,11859,11860" + }, + { + "examine": "A dwarven flag.", + "ids": "11861" + }, + { + "examine": "A tin bath big enough for dwarfs, but too small for humans.", + "ids": "11862" + }, + { + "examine": "For bringing ore out of the mines.", + "ids": "11863,11864,11865,11866" + }, + { + "examine": "I wonder what's down there?", + "ids": "11867" + }, + { + "examine": "A powerful ranging device that fires metal balls.", + "ids": "11868" + }, + { + "examine": "A pile of parts for building a multicannon.", + "ids": "11869,11870,11871,11872" + }, + { + "examine": "A crate containing parts for building a multicannon.", + "ids": "11873,11874" + }, + { + "examine": "Used for detecting dangerous gases in the mine.", + "ids": "11875" + }, + { + "examine": "Various implements for working with metal.", + "ids": "11876" + }, + { + "examine": "A simple place for a simple dwarf to sleep and dream of gold.", + "ids": "11877,11878,11879,11880,11881,11882,11883,11884,11885,11886,11887" + }, + { + "examine": "I can climb up these stairs.", + "ids": "11888" + }, + { + "examine": "I can climb these stairs.", + "ids": "11889" + }, + { + "examine": "I can climb down these stairs.", + "ids": "11890" + }, + { + "examine": "Who knows what the dark wizards store in here?", + "ids": "11891" + }, + { + "examine": "A filthy but sturdy table.", + "ids": "11892" + }, + { + "examine": "Books of dark magic for dark wizards.", + "ids": "11893,11894" + }, + { + "examine": "Vicious thorns.", + "ids": "11895" + }, + { + "examine": "These could make a fine mess of my legs.", + "ids": "11896" + }, + { + "examine": "Not suitable for sitting on.", + "ids": "11897,11898,11899,11900,11901,11902,11903,11904,11905,11906,11907,11908,11909" + }, + { + "examine": "I hope I never meet one of those.", + "ids": "11910" + }, + { + "examine": "A dead bush.", + "ids": "11911,11912,11913,11914" + }, + { + "examine": "A rocky outcrop.", + "ids": "11915,11916,11917,11918,11919,11920,11921,11922,11923,11924,11925,11926,11927,11928,11929,11930,11931,11932,11933,11934,11935,11936,11937,11938,11939,11940,11941,11942,11943,11944,11945,11946,11947,11948,11949,11950,11951,11952,11953,11954,11955,11956,11957,11958,11959,11960,11961,11962,11963,11964,11965,11966,11967,11968,11969,11970,11971,11972,11973,11974,11975,11976,11977,11978,11979,11980,11981,11982,11983,11984,11985,11986,11987,11988,11989,11990,11991,11992" + }, + { + "examine": "The door is closed.", + "ids": "11993" + }, + { + "examine": "The door is open.", + "ids": "11994,11995,11996,11997,11998,11999,12000,12001,12002" + }, + { + "examine": "Better not eat them!", + "ids": "12003,12128" + }, + { + "examine": "It's going to be a tight squeeze!", + "ids": "12004" + }, + { + "examine": "Illuminating!", + "ids": "12005,12006,12007,12008,12009,12010,12011,12012,12013,12014,12015,12016,12017,12018,12019,12020,12021,12022,12023,12024,12025,12026,12027,12028,12029,12030,12031,12032,12033,12034,12035,12036,12037,12038,12039,12040" + }, + { + "examine": "It'll be a tight squeeze.", + "ids": "12041" + }, + { + "examine": "All tangled up!", + "ids": "12042,12043,12044" + }, + { + "examine": "A magic door.", + "ids": "12045,12046,12047,12048,12049,12050,12051,12052,12053,12054,12055,12056,12057,12058,12059" + }, + { + "examine": "Shelves of colourful potion gourds!", + "ids": "12060,12061" + }, + { + "examine": "A shelf of colourful potion gourds!", + "ids": "12062,12063" + }, + { + "examine": "Fairy Nuff passed healing 101!", + "ids": "12064" + }, + { + "examine": "It says Nuff is a healer.", + "ids": "12065,12066,12067" + }, + { + "examine": "An assortment of colourful bubbling and smoking potions!", + "ids": "12068,12069,12070,12071,12072,12073,12074,12075,12076,12077,12078,12079,12080,12081,12082,12083,12084,12085,12086,12087,12088" + }, + { + "examine": "A beautiful fairy fountain!", + "ids": "12089" + }, + { + "examine": "She doesn't look like she's breathing!", + "ids": "12090" + }, + { + "examine": "Fit for a fairy.", + "ids": "12091" + }, + { + "examine": "Sure looks comfy.", + "ids": "12092" + }, + { + "examine": "A shrine to the evil chicken.", + "ids": "12093" + }, + { + "examine": "Better not eat them!", + "ids": "12094,12095,12096,12097,12098,12099,14121" + }, + { + "examine": "A hot furnace.", + "ids": "12100,12101" + }, + { + "examine": "For storage.", + "ids": "12103" + }, + { + "examine": "Some wooden crates.", + "ids": "12104" + }, + { + "examine": "A wooden crate.", + "ids": "12105" + }, + { + "examine": "Generally used for putting things on.", + "ids": "12106" + }, + { + "examine": "A wooden barrel for storage.", + "ids": "12107" + }, + { + "examine": "A nice sturdy looking table.", + "ids": "12108" + }, + { + "examine": "Its a wall.", + "ids": "12109" + }, + { + "examine": "A banner for Group of Advanced Gardeners.", + "ids": "12110" + }, + { + "examine": "Fit for milking.", + "ids": "12111" + }, + { + "examine": "I can climb this.", + "ids": "12112,12113" + }, + { + "examine": "She likes the exercise.", + "ids": "12114" + }, + { + "examine": "Full of Grain.", + "ids": "12115,12116,12117,12118,12119" + }, + { + "examine": "I wonder what's inside.", + "ids": "12120" + }, + { + "examine": "Perhaps I should search it.", + "ids": "12121" + }, + { + "examine": "Filled with tepid water.", + "ids": "12122,12123,12124" + }, + { + "examine": "Here lies Guy, he told a lie, so we swung him from the gallows high.", + "ids": "12125" + }, + { + "examine": "Looks suspicious.", + "ids": "12126" + }, + { + "examine": "A wall jutting out into the path.", + "ids": "12127,12129,12130" + }, + { + "examine": "Spooky.", + "ids": "12131,12132" + }, + { + "examine": "Probably not dead. Although Romeo is none the wiser.", + "ids": "12133" + }, + { + "examine": "Contains dead people.", + "ids": "12134,12135,12136" + }, + { + "examine": "A wild cadava berry bush.", + "ids": "12137" + }, + { + "examine": "A wild red berry bush.", + "ids": "12138" + }, + { + "examine": "A perfectly appointed rosebush.", + "ids": "12139" + }, + { + "examine": "The sort of bench you get in churches.", + "ids": "12140,12141,12142,12143" + }, + { + "examine": "You can create a canoe here.", + "ids": "12144,12145,12146,12147,12148,12149,12150,12151,12152,12153,12154,12155,12156,12157,12158" + }, + { + "examine": "Glug glug glug", + "ids": "12159,12160,12161,12162,12163,12164,12165,12166,12167" + }, + { + "examine": "canoe", + "ids": "12168,12169,12170,12171,12172,12173,12174,12175,12176,12177,12178,12179,12180,12181,12182,12183,12184,12185,12186,12187,12188,12189,12190,12191,12192,12193,12194,12195,12196,12197,12198,12199,12200" + }, + { + "examine": "A well, it is not safe to climb down.", + "ids": "12201" + }, + { + "examine": "A mole hill.", + "ids": "12202" + }, + { + "examine": "There's a hole in the roof.", + "ids": "12203,12204,12205,12206,12207,12208,12209,12210,12211,12212,12213,12214,12215,12216,12217,12218,12219,12220,12221,12222,12223,12224,12225,12226,12227,12228,12229" + }, + { + "examine": "I can climb out of this cave from here.", + "ids": "12230,12231" + }, + { + "examine": "A place to keep all your clothes & equipment.", + "ids": "12232" + }, + { + "examine": "A trophy of a mighty slayer!", + "ids": "12233,12234,12235" + }, + { + "examine": "A trophy of a master fisher.", + "ids": "12236,12237,12238" + }, + { + "examine": "It's a Vanilla Planifolia of the Orchidaceae family.", + "ids": "12239" + }, + { + "examine": "The remains of an ancient beast.", + "ids": "12240" + }, + { + "examine": "Very dead I hope.", + "ids": "12241" + }, + { + "examine": "Remains of yesterday's dinner.", + "ids": "12242" + }, + { + "examine": "That must be one hungry chicken.", + "ids": "12243" + }, + { + "examine": "This one's not very fresh.", + "ids": "12244" + }, + { + "examine": "Alas poor Yojllik, I knew him backwards.", + "ids": "12245" + }, + { + "examine": "A tall, skinny.", + "ids": "12246" + }, + { + "examine": "He fell foul of the fowl.", + "ids": "12247" + }, + { + "examine": "The chicken's pecked him clean.", + "ids": "12248,12249,12250,12251,12252" + }, + { + "examine": "How am I going to get down there?", + "ids": "12253" + }, + { + "examine": "I guess I need to climb down.", + "ids": "12254" + }, + { + "examine": "I hope this holds!", + "ids": "12255" + }, + { + "examine": "Will those eggs become baby chicks?", + "ids": "12256" + }, + { + "examine": "Must have been laid by one of those dragons.", + "ids": "12257" + }, + { + "examine": "Hot!", + "ids": "12258" + }, + { + "examine": "The nest of evil!", + "ids": "12259" + }, + { + "examine": "Will this take me home?", + "ids": "12260,12261" + }, + { + "examine": "It probably leads to some sort of cellar.", + "ids": "12262" + }, + { + "examine": "What mysteries lie below?", + "ids": "12263" + }, + { + "examine": "An oak ladder.", + "ids": "12264" + }, + { + "examine": "Old wooden steps.", + "ids": "12265,12266" + }, + { + "examine": "What evil lurks below?", + "ids": "12267" + }, + { + "examine": "Rickety wooden steps lead down into the lair of evil.", + "ids": "12268" + }, + { + "examine": "Hmmmm...home cooking.", + "ids": "12269,12270,12271,12272,12273,12274,12275,12276,12277,12278" + }, + { + "examine": "Wash your hands!", + "ids": "12279" + }, + { + "examine": "A nice sturdy looking table.", + "ids": "12280" + }, + { + "examine": "A small wooden table.", + "ids": "12281" + }, + { + "examine": "How to be evil and influence people.", + "ids": "12282,12283,12284,12285,12286,12287,12288,12289,12290,12291,12292" + }, + { + "examine": "Tick tock.", + "ids": "12293,12294,12295,12296,12297,12298,12299,12300" + }, + { + "examine": "Little candles flickering.", + "ids": "12301,12302,12303,12304,12305,12306,12307,12308" + }, + { + "examine": "It's open.", + "ids": "12309" + }, + { + "examine": "Someone should be sitting here.", + "ids": "12310,12311" + }, + { + "examine": "Suitable for one.", + "ids": "12312,12313" + }, + { + "examine": "A very large banquet table stacked with food.", + "ids": "12314,12315,12316,12317" + }, + { + "examine": "It's a seat!", + "ids": "12318,12319" + }, + { + "examine": "He's been frozen in time.", + "ids": "12320,12321,12322,12323,12324,12325,12326,12327,12328,12329,12330,12331,12332,12333,12334,12335,12336,12337,12338,12339,12340,12341,12342,12343,12344,12345,12346,12347" + }, + { + "examine": "An ornate-fashioned door.", + "ids": "12348" + }, + { + "examine": "Some kind of strange time barrier.", + "ids": "12351,12352,12353,12354" + }, + { + "examine": "A portal to a mystical place...", + "ids": "12355" + }, + { + "examine": "A portal out of this mystical place...", + "ids": "12356,12357,12358,12359,12360,12361,12362,12363,12364,12365,12366,12367,12368,12369,12370,12371,12372,12373,12374,12375,12376,12377,12378,12379,12380,12381,12382,12383,12384,12385" + }, + { + "examine": "A large crudely built table.", + "ids": "12386" + }, + { + "examine": "Definite proof that cooking and gunpowder don't mix.", + "ids": "12387" + }, + { + "examine": "A large table now covered in soot.", + "ids": "12388" + }, + { + "examine": "What horrors lie below?", + "ids": "12389" + }, + { + "examine": "It's the ladder I came in here by.", + "ids": "12390" + }, + { + "examine": "Fortunately this has survived better than most of the kitchen.", + "ids": "12391" + }, + { + "examine": "I'm not sure I want to know what goblins keep in their kitchens.", + "ids": "12392" + }, + { + "examine": "They're covered in a thick layer of soot.", + "ids": "12393" + }, + { + "examine": "Stacks and stacks of sacks.", + "ids": "12394" + }, + { + "examine": "Stacks and stacks of soot covered sacks.", + "ids": "12395" + }, + { + "examine": "A large empty sack.", + "ids": "12396,12397,12398" + }, + { + "examine": "It's empty, apart from the explosion debris covering everything now.", + "ids": "12399" + }, + { + "examine": "The bottom of this cauldron is suprisingly blackened, even for a cauldron.", + "ids": "12400" + }, + { + "examine": "I don't think Cauldrons are supposed to bounce around like that.", + "ids": "12401" + }, + { + "examine": "This could be considered to be a bad thing!", + "ids": "12402" + }, + { + "examine": "These shelves are suprisingly tidy for a goblin. It can't last.", + "ids": "12403" + }, + { + "examine": "They're not going to be very useful for keeping things on now.", + "ids": "12404" + }, + { + "examine": "The doors don't seem to stay shut properly.", + "ids": "12405" + }, + { + "examine": "When I got there the cupboard was bare. Even the doors had been blown off.", + "ids": "12406" + }, + { + "examine": "A little three legged stool.", + "ids": "12407" + }, + { + "examine": "It's a two legged stool now. Apparently it doesn't work very well.", + "ids": "12408,12409" + }, + { + "examine": "A pan with a stereotype. I'm sure it could be used for other things.", + "ids": "12410" + }, + { + "examine": "Mmmm, soot flavoured sauce. Lovely!", + "ids": "12411" + }, + { + "examine": "It's not rolling, it's just sitting there.", + "ids": "12412" + }, + { + "examine": "It would probably crumble if you tried to roll anything with it.", + "ids": "12413" + }, + { + "examine": "Cutlery with an identity crisis.", + "ids": "12414,12415,12416,12417,12418,12419,12420,12421,12422,12423,12424,12425,12426,12427,12428,12429,12430,12431,12432,12433" + }, + { + "examine": "An empty wooden barrel.", + "ids": "12434,12435,12436,12437,12438,12439" + }, + { + "examine": "A large wooden box.", + "ids": "12442" + }, + { + "examine": "A neatly stacked pair of crates.", + "ids": "12443" + }, + { + "examine": "The door is closed.", + "ids": "12444" + }, + { + "examine": "The door is open.", + "ids": "12445" + }, + { + "examine": "A rough wooden table.", + "ids": "12450" + }, + { + "examine": "I wonder what's inside?", + "ids": "12451,12452" + }, + { + "examine": "It's not quite the same as flower arranging.", + "ids": "12453,12454,12455,12456,12457,12458,12459" + }, + { + "examine": "Ze underwater cave entrance. I ask myself, where will it lead?", + "ids": "12460,12461" + }, + { + "examine": "Ze underwater cave exit, leading me to another underwater adventure.", + "ids": "12462,12463,12464,12465,12466" + }, + { + "examine": "Ze pen door, a wonderful example of ze underwater craftsmanship.", + "ids": "12467,12468,12469,12470,12471,12472,12473" + }, + { + "examine": "It looks slippy but I think you can climb this.", + "ids": "12474,12475" + }, + { + "examine": "Ze anchor chain, linking me with zis underwater paradise.", + "ids": "12476" + }, + { + "examine": "Those leaves look useful!", + "ids": "12477,12478" + }, + { + "examine": "The perfect place for coral to grow.", + "ids": "12479,12480,12481,12482,12483,12484,12485,12486,12487,12488" + }, + { + "examine": "This is called Elkhorn Coral.", + "ids": "12489,12490,12491,12492,12493,12494,12495,12496,12497,12498" + }, + { + "examine": "A type of lace coral.", + "ids": "12499,12500,12501,12502,12503,12504,12505,12506,12507,12508" + }, + { + "examine": "Coral is made up of millions of organisms.", + "ids": "12509,12510,12511,12512,12513,12514,12515,12516,12517,12518" + }, + { + "examine": "Bonaire-Flower Coral...It's rare!", + "ids": "12519" + }, + { + "examine": "Pollution is rapidly destroying coral reefs.", + "ids": "12520,12521,12522,12523,12524,12525,12526,12527,12528,12529" + }, + { + "examine": "I bet the boats gone missing...", + "ids": "12530" + }, + { + "examine": "Precious oxygen...escaping...", + "ids": "12531,12532,12533,12534,12535" + }, + { + "examine": "I can climb up these stairs.", + "ids": "12536" + }, + { + "examine": "I can climb these stairs.", + "ids": "12537" + }, + { + "examine": "I can climb down these stairs.", + "ids": "12538" + }, + { + "examine": "A good source of books!", + "ids": "12539,12540" + }, + { + "examine": "For putting things on.", + "ids": "12541,12542" + }, + { + "examine": "A nice sturdy-looking table.", + "ids": "12543" + }, + { + "examine": "A small wooden table.", + "ids": "12544" + }, + { + "examine": "Small wooden boxes.", + "ids": "12545" + }, + { + "examine": "A wooden crate.", + "ids": "12546,12547" + }, + { + "examine": "Some wooden crates.", + "ids": "12548,12549" + }, + { + "examine": "A large old tree.", + "ids": "12550,12551" + }, + { + "examine": "A large old tree, pushed over by Rantz.", + "ids": "12552" + }, + { + "examine": "A large old tree that's been felled, with the roots cut off.", + "ids": "12553" + }, + { + "examine": "A very crude boat, made from an old tree.", + "ids": "12554" + }, + { + "examine": "The roots of a large old tree.", + "ids": "12555" + }, + { + "examine": "The rock the inflated toad was tied to.", + "ids": "12556,12557,12558" + }, + { + "examine": "A small palm tree.", + "ids": "12559" + }, + { + "examine": "A small palm tree with an ogre arrow in it.", + "ids": "12560" + }, + { + "examine": "Useful for ogre dinners.", + "ids": "12561,12562,12563" + }, + { + "examine": "A pile of rock.", + "ids": "12564,12565,12566,12567" + }, + { + "examine": "A very slippery stepping stone.", + "ids": "12568,12569" + }, + { + "examine": "A terribly tall tropical tree.", + "ids": "12570,12571,12572" + }, + { + "examine": "A climbing wall made from skulls.", + "ids": "12576,12577" + }, + { + "examine": "For swinging on.", + "ids": "12578" + }, + { + "examine": "A terribly tall tropical tree.", + "ids": "12579,12580" + }, + { + "examine": "A vine-choked hole.", + "ids": "12581,12582,12583,12584,12585,12586,12587,12588" + }, + { + "examine": "A Rock.", + "ids": "12589,12590,12591,12592,12593" + }, + { + "examine": "A Snake.", + "ids": "12594,12595,12596" + }, + { + "examine": "A hole.", + "ids": "12597" + }, + { + "examine": "A Snake.", + "ids": "12598,12599,12600" + }, + { + "examine": "There's a hole in the roof!", + "ids": "12601" + }, + { + "examine": "A hole in the ground.", + "ids": "12602" + }, + { + "examine": "This bush seems to glow in the dim light of the cave.", + "ids": "12603" + }, + { + "examine": "This banana tree has a strange reddish hue on the leaves.", + "ids": "12604" + }, + { + "examine": "This thin shaft of light is all the Tchiki Monkey Nut bush needs to grow.", + "ids": "12605" + }, + { + "examine": "A Banana Tree.", + "ids": "12606,12607,12608,12609,12610,12611,12612,12613,12614" + }, + { + "examine": "A Bush with monkey nuts growing on it.", + "ids": "12615" + }, + { + "examine": "I can see the surface.", + "ids": "12616" + }, + { + "examine": "A way out.", + "ids": "12617" + }, + { + "examine": "A terribly tall tropical tree.", + "ids": "12618,12619,12620,12621" + }, + { + "examine": "A vine.", + "ids": "12622,12623,12624,12625,12626" + }, + { + "examine": "A terribly tall tropical tree.", + "ids": "12627,12628,12629,12630,12631,12632,12633" + }, + { + "examine": "It's a long, hot rock.", + "ids": "12634" + }, + { + "examine": "It's a rock with a dead snake on.", + "ids": "12635" + }, + { + "examine": "It's a rock with a dead, burnt snake on.", + "ids": "12636" + }, + { + "examine": "It's a rock with a cooked snake on. Smells good...", + "ids": "12637,12638,12639,12640,12641,12642,12643,12644,12645,12646,12647,12648,12649,12650,12651,12652,12653,12654,12655,12656" + }, + { + "examine": "I can get out this way.", + "ids": "12657,12658,12659,12660" + }, + { + "examine": "Entrance to the monkey agility arena.", + "ids": "12661,12662,12663,12664,12665,12666,12667,12668,12669,12670,12671,12672,12673,12674,12675,12676,12677,12678,12679,12680,12681,12682" + }, + { + "examine": "Bridge Corner", + "ids": "12683,12684,12685,12686,12687,12688,12689,12690,12691,12692,12693,12694,12695,12696,12697,12698,12699,12700,12701,12702,12703,12704,12705,12706,12707,12708,12709,12710" + }, + { + "examine": "A recently filled in grave.", + "ids": "12711,12712,12713,12714,12715" + }, + { + "examine": "This will show me who is supposed to go here.", + "ids": "12716,12717,12718,12719,12720" + }, + { + "examine": "A grave with a coffin in.", + "ids": "12721,12722,12723,12724,12725" + }, + { + "examine": "An empty grave.", + "ids": "12726,12727,12728,12729,12730" + }, + { + "examine": "Not the best place to live.", + "ids": "12731" + }, + { + "examine": "This tree has long been dead.", + "ids": "12732" + }, + { + "examine": "This tree has been cut down.", + "ids": "12733" + }, + { + "examine": "Rickety table with signs of recent gambling among the remains of past meals.", + "ids": "12734" + }, + { + "examine": "I wonder what's inside.", + "ids": "12735" + }, + { + "examine": "Perhaps I should search it.", + "ids": "12736" + }, + { + "examine": "A broken down wall.", + "ids": "12737,12738" + }, + { + "examine": "This rubble is covering a trapdoor.", + "ids": "12739,12740" + }, + { + "examine": "A fallen down wall.", + "ids": "12741" + }, + { + "examine": "Broken parts of an old wall.", + "ids": "12742,12743" + }, + { + "examine": "I wonder what's under it?", + "ids": "12744" + }, + { + "examine": "I wonder what's down there?", + "ids": "12745" + }, + { + "examine": "A pile of rubble.", + "ids": "12746" + }, + { + "examine": "Just a bit pile of rubble, probably from the fallen down building which surrounds you.", + "ids": "12747" + }, + { + "examine": "I can climb this.", + "ids": "12748" + }, + { + "examine": "Looks like the locals dump their rubble here.", + "ids": "12749" + }, + { + "examine": "You seem to make out some writing.", + "ids": "12750,12751,12752,12753,12754,12755,12756,12757,12758,12759,12760" + }, + { + "examine": "A rotten looking door.", + "ids": "12761,12762" + }, + { + "examine": "Where does this go?", + "ids": "12763" + }, + { + "examine": "I can climb this.", + "ids": "12764" + }, + { + "examine": "I wonder where this goes.", + "ids": "12765" + }, + { + "examine": "A collection of rare books.", + "ids": "12766,12767" + }, + { + "examine": "I wonder what's inside.", + "ids": "12768" + }, + { + "examine": "Perhaps I should search it.", + "ids": "12769" + }, + { + "examine": "A small cave entrance.", + "ids": "12770,12771,12772" + }, + { + "examine": "This cave has been boarded up.", + "ids": "12773" + }, + { + "examine": "A rock under the surface of the sea.", + "ids": "12774" + }, + { + "examine": "A bed-ridden man.", + "ids": "12775" + }, + { + "examine": "Looks slightly lower than the rest, perhaps you can jump it?", + "ids": "12776" + }, + { + "examine": "A wooden trapdoor.", + "ids": "12777" + }, + { + "examine": "This leads to the basement.", + "ids": "12778" + }, + { + "examine": "I can climb this.", + "ids": "12779" + }, + { + "examine": "A wooden ladder.", + "ids": "12780,12781" + }, + { + "examine": "This is the source of the leak.", + "ids": "12782" + }, + { + "examine": "Hopefully this should stop the leak.", + "ids": "12783" + }, + { + "examine": "It's catching the leaking water from the roof.", + "ids": "12784,12785" + }, + { + "examine": "This wall has been repaired with wood.", + "ids": "12786" + }, + { + "examine": "This wall really needs repairing.", + "ids": "12787" + }, + { + "examine": "An empty wooden crate.", + "ids": "12788,12789,12790,12791" + }, + { + "examine": "There are some tinderboxes on these shelves.", + "ids": "12792" + }, + { + "examine": "There are some axes on these shelves.", + "ids": "12793" + }, + { + "examine": "There are some snails on these shelves.", + "ids": "12794,12795" + }, + { + "examine": "Come bask in the fire's warm glowing warming glow.", + "ids": "12796,12797" + }, + { + "examine": "This bank booth has been recently repaired.", + "ids": "12798" + }, + { + "examine": "This bank booth could probably be repaired.", + "ids": "12799" + }, + { + "examine": "This bank booth is too damaged to use.", + "ids": "12800,12801" + }, + { + "examine": "The resting place of an ancient warrior of Morytania.", + "ids": "12802,12803" + }, + { + "examine": "It looks a tad bloody...", + "ids": "12804,12805" + }, + { + "examine": "An old and broken furnace, there is a huge hole in the steel hood.", + "ids": "12806" + }, + { + "examine": "This furnace has been repaired with some steel panels, but it has no fuel.", + "ids": "12807" + }, + { + "examine": "The furnace has been repaired and has some coal in it.", + "ids": "12808" + }, + { + "examine": "A repaired furnace, hot and ready for action.", + "ids": "12809,12810,12811" + }, + { + "examine": "Hardened earth, with bits of rock in it, not easy to move.", + "ids": "12812" + }, + { + "examine": "Hardened earth, with bits of rock in it, not easy to move, slightly broken up.", + "ids": "12813" + }, + { + "examine": "Hardened earth, with bits of rock in it, not easy to move, partially broken up.", + "ids": "12814" + }, + { + "examine": "Hard rubble reduced to small pieces, it's quite dusty and not easy to move.", + "ids": "12815" + }, + { + "examine": "A wooden gate.", + "ids": "12816,12817,12818,12819" + }, + { + "examine": "A path leading out of this swampy dead end.", + "ids": "12820,12821,12822,12823,12824,12825,12826,12827,12828,12829,12830,12831,12832,12833,12834,12835,12836,12837,12838,12839,12840,12841,12842,12843" + }, + { + "examine": "A veritable pile of bricks.", + "ids": "12844,12845,12846,12847,12848,12849,12850,12851,12852,12853,12854" + }, + { + "examine": "It's a bit broken.", + "ids": "12855" + }, + { + "examine": "A door barely hanging onto it's hinges.", + "ids": "12856" + }, + { + "examine": "Actually, I could do with a drink...never mind...I wasn't thirsty anyway.", + "ids": "12857,12858,12859,12860,12861,12862,12863,12864,12865,12866,12867,12868,12869,12870,12871" + }, + { + "examine": "Where does this go?", + "ids": "12872" + }, + { + "examine": "A collection of rare books.", + "ids": "12873" + }, + { + "examine": "A wooden crate.", + "ids": "12874" + }, + { + "examine": "A wooden wheelbarrow.", + "ids": "12875" + }, + { + "examine": "For storage.", + "ids": "12876" + }, + { + "examine": "Some wooden crates.", + "ids": "12877" + }, + { + "examine": "Some wooden boxes.", + "ids": "12878" + }, + { + "examine": "A wooden crate.", + "ids": "12879" + }, + { + "examine": "It's a bed!", + "ids": "12880" + }, + { + "examine": "A rotten and decrepid book case.", + "ids": "12881,12882" + }, + { + "examine": "Theres nothing here.", + "ids": "12883" + }, + { + "examine": "Generally used for putting things on.", + "ids": "12884" + }, + { + "examine": "This needs dusting before I'll sit on it.", + "ids": "12887,12888" + }, + { + "examine": "Not so good for sitting on.", + "ids": "12889" + }, + { + "examine": "A wooden barrel for storage.", + "ids": "12890,12891" + }, + { + "examine": "A small wooden table.", + "ids": "12892" + }, + { + "examine": "There's nothing on these shelves.", + "ids": "12893" + }, + { + "examine": "Cut down to feed the furnace.", + "ids": "12894" + }, + { + "examine": "It doesn't look healthy...", + "ids": "12895,12896" + }, + { + "examine": "It smells stagnant.", + "ids": "12897,12898,12899,12900,12901,12902,12903,12904,12905" + }, + { + "examine": "A wooden ladder.", + "ids": "12906,12907,12908,12909,12910,12911,12912,12913,12914,12915,12916,12917,12918,12919,12920,12921,12922,12923,12924,12925,12926,12927,12928,12929,12930,12931,12932" + }, + { + "examine": "Items are for sale here.", + "ids": "12933,12934,12935,12936,12937,12938,12939,12940" + }, + { + "examine": "A distinctive layer in the rock strata.", + "ids": "12941,12942,12943" + }, + { + "examine": "It's not a schooner, it's a sailboat.", + "ids": "12944,12945,12946,12947,12948,12949,12950,12951,12952,12953,12954,12955,12956,12957,12958,12959,12960" + }, + { + "examine": "A wooden crate.", + "ids": "12961" + }, + { + "examine": "A table.", + "ids": "12962" + }, + { + "examine": "A wooden crate.", + "ids": "12963" + }, + { + "examine": "I can climb this.", + "ids": "12964,12965" + }, + { + "examine": "I can climb down this.", + "ids": "12966" + }, + { + "examine": "A wooden barrel for storage.", + "ids": "12967,12968" + }, + { + "examine": "Something is cooking nicely here.", + "ids": "12969" + }, + { + "examine": "A well slept in bed.", + "ids": "12970" + }, + { + "examine": "A table.", + "ids": "12971" + }, + { + "examine": "It's a small table.", + "ids": "12972" + }, + { + "examine": "After working with livestock, why not wash your hands?", + "ids": "12974,12975,12976" + }, + { + "examine": "A wooden crate.", + "ids": "12977,12978" + }, + { + "examine": "This chair rocks", + "ids": "12979" + }, + { + "examine": "A stand for hats!", + "ids": "12981" + }, + { + "examine": "I can climb over the fence with this.", + "ids": "12982,12983,12984,12985" + }, + { + "examine": "A wooden gate.", + "ids": "12986,12987,12988,12989,12990,12991,12992,12993,12994,12995,12996,12997,12998,12999,13000" + }, + { + "examine": "The door is closed.", + "ids": "13001" + }, + { + "examine": "The door is open.", + "ids": "13002" + }, + { + "examine": "I wonder what's inside.", + "ids": "13003" + }, + { + "examine": "Perhaps I should search it.", + "ids": "13004,13005,29399" + }, + { + "examine": "A desert door.", + "ids": "13006,13007,13008,13009,13010,13011,13012,13013,13014" + }, + { + "examine": "A timber door.", + "ids": "13015,13016,13017,13018,13019,13020,13021,13022,13023,13024,13025,13026,13027,13028,13029,13030,13031,13032,13033,13034,13035,13036,13037,13038,13039,13040,13041,13042,13043,13044,13045,13046,13047,13048,13049,13050,13051,13052,13053,13054,13055,13056,13057,13058,13059,13060,13061,13062,13063,13064,13065,13066,13067,13068,13069,13070,13071,13072,13073,13074,13075,13076,13077,13078,13079,13080,13081,13082,13083,13084,13085,13086,13087,13088,13089,13090,13091,13092,13093" + }, + { + "examine": "A way in to the house.", + "ids": "13100,13101,13102,13103,13104,13105,13106" + }, + { + "examine": "I'm sure the animal is glad its fur was put to good use.", + "ids": "13107,13108,13109,13110,13111,13112,13113,13114,13115,13116,13117" + }, + { + "examine": "A posh door.", + "ids": "13118,13119,13120,13121,13122,13123,13124,13125" + }, + { + "examine": "A place to train unarmed combat with your friends.", + "ids": "13126,13127,13128,13129,13130,13131,13132" + }, + { + "examine": "A place to train weapon skills with your friends.", + "ids": "13133,13134,13135,13136" + }, + { + "examine": "Anything-goes combat in here!", + "ids": "13137,13138,13139,13140" + }, + { + "examine": "There's nothing there", + "ids": "13141" + }, + { + "examine": "You should try to knock someone off.", + "ids": "13142,13143,13144" + }, + { + "examine": "To stop you from stepping out of the ranging spot.", + "ids": "13145,13146" + }, + { + "examine": "Stand here to fight with projectiles or spells.", + "ids": "13147" + }, + { + "examine": "Great for sleeping in.", + "ids": "13148,13149,13150,13151,13152,13153,13154" + }, + { + "examine": "A place to keep your shoes.", + "ids": "13155" + }, + { + "examine": "A place to keep all your clothes.", + "ids": "13156,13157,13158,13159,13160,13161" + }, + { + "examine": "To get a close look at your chin.", + "ids": "13162" + }, + { + "examine": "To help you shave.", + "ids": "13163" + }, + { + "examine": "To help you do your hair.", + "ids": "13164,13165,13166,13167,13168" + }, + { + "examine": "No little mouse to be seen.", + "ids": "13169,13170,13171" + }, + { + "examine": "The holy symbol of the god of light.", + "ids": "13172" + }, + { + "examine": "The holy symbol of the god of chaos.", + "ids": "13173" + }, + { + "examine": "The holy symbol of the god of balance.", + "ids": "13174" + }, + { + "examine": "The golden star reminds you of the glory of Saradomin.", + "ids": "13175" + }, + { + "examine": "A fitting symbol of the bloodthirsty Zamorak!", + "ids": "13176" + }, + { + "examine": "A serene icon to the lord of balance.", + "ids": "13177" + }, + { + "examine": "An icon of the mysterious Bob.", + "ids": "13178" + }, + { + "examine": "An oak altar with a symbol of Saradomin.", + "ids": "13179" + }, + { + "examine": "An oak altar with a symbol of Zamorak.", + "ids": "13180" + }, + { + "examine": "An oak altar with a symbol of Guthix.", + "ids": "13181" + }, + { + "examine": "A teak altar with a symbol of Saradomin.", + "ids": "13182" + }, + { + "examine": "A teak altar with a symbol of Zamorak.", + "ids": "13183" + }, + { + "examine": "A teak altar with a symbol of Guthix.", + "ids": "13184" + }, + { + "examine": "A cloth-covered teak altar with a symbol of Saradomin.", + "ids": "13185" + }, + { + "examine": "A cloth-covered teak altar with a symbol of Zamorak.", + "ids": "13186" + }, + { + "examine": "A cloth-covered teak altar with a symbol of Guthix.", + "ids": "13187" + }, + { + "examine": "A mahogany altar with a symbol of Saradomin.", + "ids": "13188" + }, + { + "examine": "A mahogany altar with a symbol of Zamorak.", + "ids": "13189" + }, + { + "examine": "A mahogany altar with a symbol of Guthix.", + "ids": "13190" + }, + { + "examine": "A limestone altar with a symbol of Saradomin.", + "ids": "13191" + }, + { + "examine": "A limestone altar with a symbol of Zamorak.", + "ids": "13192" + }, + { + "examine": "A limestone altar with a symbol of Guthix.", + "ids": "13193" + }, + { + "examine": "A marble altar with a symbol of Saradomin.", + "ids": "13194" + }, + { + "examine": "A marble altar with a symbol of Zamorak.", + "ids": "13195" + }, + { + "examine": "A marble altar with a symbol of Guthix.", + "ids": "13196" + }, + { + "examine": "A gilded marble altar with a symbol of Saradomin.", + "ids": "13197" + }, + { + "examine": "A gilded marble altar with a symbol of Zamorak.", + "ids": "13198" + }, + { + "examine": "A gilded marble altar with a symbol of Guthix.", + "ids": "13199" + }, + { + "examine": "The smoke goes up to the gods.", + "ids": "13200,13201,13202,13203,13204,13205,13206,13207,13208,13209,13210,13211,13212,13213" + }, + { + "examine": "They tinkle delightfully.", + "ids": "13214" + }, + { + "examine": "Oh, from out the sounding cells, what a gush of euphony voluminously wells!", + "ids": "13215" + }, + { + "examine": "A delightful sound.", + "ids": "13216" + }, + { + "examine": "A basic chapel window.", + "ids": "13217" + }, + { + "examine": "What nice shapes you can make out of glass!", + "ids": "13218" + }, + { + "examine": "It fills the room with coloured light.", + "ids": "13219" + }, + { + "examine": "What nice shapes you can make out of glass!", + "ids": "13220" + }, + { + "examine": "It fills the room with coloured light.", + "ids": "13221" + }, + { + "examine": "What nice shapes you can make out of glass!", + "ids": "13222" + }, + { + "examine": "It fills the room with coloured light.", + "ids": "13223" + }, + { + "examine": "What nice shapes you can make out of glass!", + "ids": "13224" + }, + { + "examine": "It fills the room with coloured light.", + "ids": "13225" + }, + { + "examine": "A basic chapel window.", + "ids": "13226" + }, + { + "examine": "What nice shapes you can make out of glass!", + "ids": "13227" + }, + { + "examine": "It fills the room with coloured light.", + "ids": "13228" + }, + { + "examine": "What nice shapes you can make out of glass!", + "ids": "13229" + }, + { + "examine": "It fills the room with coloured light.", + "ids": "13230" + }, + { + "examine": "What nice shapes you can make out of glass!", + "ids": "13231" + }, + { + "examine": "It fills the room with coloured light.", + "ids": "13232" + }, + { + "examine": "What nice shapes you can make out of glass!", + "ids": "13233" + }, + { + "examine": "It fills the room with coloured light.", + "ids": "13234" + }, + { + "examine": "A basic chapel window.", + "ids": "13235" + }, + { + "examine": "What nice shapes you can make out of glass!", + "ids": "13236" + }, + { + "examine": "It fills the room with coloured light.", + "ids": "13237" + }, + { + "examine": "What nice shapes you can make out of glass!", + "ids": "13238" + }, + { + "examine": "It fills the room with coloured light.", + "ids": "13239" + }, + { + "examine": "What nice shapes you can make out of glass!", + "ids": "13240" + }, + { + "examine": "It fills the room with coloured light.", + "ids": "13241" + }, + { + "examine": "What nice shapes you can make out of glass!", + "ids": "13242" + }, + { + "examine": "It fills the room with coloured light.", + "ids": "13243" + }, + { + "examine": "A basic chapel window.", + "ids": "13244" + }, + { + "examine": "What nice shapes you can make out of glass!", + "ids": "13245" + }, + { + "examine": "It fills the room with coloured light.", + "ids": "13246" + }, + { + "examine": "What nice shapes you can make out of glass!", + "ids": "13247" + }, + { + "examine": "It fills the room with coloured light.", + "ids": "13248" + }, + { + "examine": "What nice shapes you can make out of glass!", + "ids": "13249" + }, + { + "examine": "It fills the room with coloured light.", + "ids": "13250" + }, + { + "examine": "What nice shapes you can make out of glass!", + "ids": "13251" + }, + { + "examine": "It fills the room with coloured light.", + "ids": "13252" + }, + { + "examine": "A basic chapel window.", + "ids": "13253" + }, + { + "examine": "What nice shapes you can make out of glass!", + "ids": "13254" + }, + { + "examine": "It fills the room with coloured light.", + "ids": "13255" + }, + { + "examine": "What nice shapes you can make out of glass!", + "ids": "13256" + }, + { + "examine": "It fills the room with coloured light.", + "ids": "13257" + }, + { + "examine": "What nice shapes you can make out of glass!", + "ids": "13258" + }, + { + "examine": "It fills the room with coloured light.", + "ids": "13259" + }, + { + "examine": "What nice shapes you can make out of glass!", + "ids": "13260" + }, + { + "examine": "It fills the room with coloured light.", + "ids": "13261" + }, + { + "examine": "A basic chapel window.", + "ids": "13262" + }, + { + "examine": "What nice shapes you can make out of glass!", + "ids": "13263" + }, + { + "examine": "It fills the room with coloured light.", + "ids": "13264" + }, + { + "examine": "What nice shapes you can make out of glass!", + "ids": "13265" + }, + { + "examine": "It fills the room with coloured light.", + "ids": "13266" + }, + { + "examine": "What nice shapes you can make out of glass!", + "ids": "13267" + }, + { + "examine": "It fills the room with coloured light.", + "ids": "13268" + }, + { + "examine": "What nice shapes you can make out of glass!", + "ids": "13269" + }, + { + "examine": "It fills the room with coloured light.", + "ids": "13270" + }, + { + "examine": "A saint of Saradomin from the days of old.", + "ids": "13271" + }, + { + "examine": "One of Saradomin's holy angels.", + "ids": "13272" + }, + { + "examine": "Saradomin, Lord of Light.", + "ids": "13273" + }, + { + "examine": "A saint of Guthix from the days of old.", + "ids": "13274" + }, + { + "examine": "One of Guthix's nature spirits.", + "ids": "13275" + }, + { + "examine": "Guthix, Lord of Balance.", + "ids": "13276" + }, + { + "examine": "A mighty saint of Zamorak.", + "ids": "13277" + }, + { + "examine": "One of Zamorak's unholy demons.", + "ids": "13278" + }, + { + "examine": "Zamorak, Lord of Chaos.", + "ids": "13279" + }, + { + "examine": "A small statue of Bob as a kitten.", + "ids": "13280" + }, + { + "examine": "OMG it's Bob the Jagex Cat!", + "ids": "13281" + }, + { + "examine": "The great Bob, Lord of Cats.", + "ids": "13282" + }, + { + "examine": "Is there treasure inside?", + "ids": "13283,13284" + }, + { + "examine": "Perhaps there is treasure inside!", + "ids": "13285,13286" + }, + { + "examine": "There might possibly be treasure inside!", + "ids": "13287,13288" + }, + { + "examine": "There must surely be treasure in a chest this expensive!", + "ids": "13289,13290" + }, + { + "examine": "Could the magic be guarding some treasure?", + "ids": "13291,13292" + }, + { + "examine": "A basic wooden dining table.", + "ids": "13293" + }, + { + "examine": "A basic oak dining table.", + "ids": "13294" + }, + { + "examine": "A nicely carved oak dining table.", + "ids": "13295" + }, + { + "examine": "A teak dining table.", + "ids": "13296" + }, + { + "examine": "A nicely carved teak dining table.", + "ids": "13297" + }, + { + "examine": "An expensive mahogany table.", + "ids": "13298" + }, + { + "examine": "Marble and mahogany, ooh.", + "ids": "13299" + }, + { + "examine": "A basic wooden dining bench.", + "ids": "13300" + }, + { + "examine": "A basic oak dining bench.", + "ids": "13301" + }, + { + "examine": "A nice oak dining bench.", + "ids": "13302" + }, + { + "examine": "A teak dining bench.", + "ids": "13303" + }, + { + "examine": "A nice teak dining bench.", + "ids": "13304" + }, + { + "examine": "A mahogany dining bench.", + "ids": "13305" + }, + { + "examine": "A very expensive dining bench.", + "ids": "13306" + }, + { + "examine": "Can summon your servant.", + "ids": "13307,13308,13309" + }, + { + "examine": "A rather macabre decoration.", + "ids": "13310" + }, + { + "examine": "It doesn't go anywhere, it's just for show.", + "ids": "13311" + }, + { + "examine": "Nothing makes a dungeon look ominous like some dried blood.", + "ids": "13312" + }, + { + "examine": "Sturdy oak bars to keep prisoners in.", + "ids": "13313,13314,13315" + }, + { + "examine": "Oak and steel bars to keep prisoners in.", + "ids": "13316,13317,13318" + }, + { + "examine": "Steel bars to keep prisoners in.", + "ids": "13319,13320,13321" + }, + { + "examine": "Steel bars with spikes!", + "ids": "13322,13323,13324" + }, + { + "examine": "A cage of bones. How delightfully macabre.", + "ids": "13325,13326,13327" + }, + { + "examine": "An oak ladder.", + "ids": "13328" + }, + { + "examine": "A teak ladder.", + "ids": "13329" + }, + { + "examine": "A mahogany ladder.", + "ids": "13330" + }, + { + "examine": "Yuck!", + "ids": "13331,13332,13333" + }, + { + "examine": "Ouch!", + "ids": "13334,13335,13336" + }, + { + "examine": "Not very pleasant", + "ids": "13337" + }, + { + "examine": "Invisible?", + "ids": "13338,13339,13340" + }, + { + "examine": "Even a dungeon needs light!", + "ids": "13341,13342,13343" + }, + { + "examine": "A sturdy oak door.", + "ids": "13344,13345" + }, + { + "examine": "A formidable steel door.", + "ids": "13346,13347" + }, + { + "examine": "Could anyone get through a solid marble door?", + "ids": "13348,13349" + }, + { + "examine": "A sturdy oak door.", + "ids": "13350,13351" + }, + { + "examine": "A formidable steel door.", + "ids": "13352,13353" + }, + { + "examine": "Could anyone get through a solid marble door?", + "ids": "13354,13355" + }, + { + "examine": "Watch out!", + "ids": "13356,13357,13358,13359,13360,13361,13362,13363,13364,13365" + }, + { + "examine": "A pet skeleton!", + "ids": "13366" + }, + { + "examine": "Beware of the dog!", + "ids": "13367" + }, + { + "examine": "He doesn't look very welcoming.", + "ids": "13368" + }, + { + "examine": "A pet Troll!", + "ids": "13369" + }, + { + "examine": "No spider could get that big! It's unrealistic!", + "ids": "13370" + }, + { + "examine": "Good doggie...", + "ids": "13371" + }, + { + "examine": "Young but still dangerous.", + "ids": "13372" + }, + { + "examine": "He's full of pent-up aggression.", + "ids": "13373" + }, + { + "examine": "I don't think insect repellent will work...", + "ids": "13374" + }, + { + "examine": "Its scales are made of steel.", + "ids": "13375" + }, + { + "examine": "A darkened horror from the ocean depths...", + "ids": "13376" + }, + { + "examine": "I don't like the look of those spines...", + "ids": "13377" + }, + { + "examine": "A demon.", + "ids": "13378" + }, + { + "examine": "Rub the mushroom's head and see what pops out!", + "ids": "13379,13380" + }, + { + "examine": "A place to hang your boxing gloves.", + "ids": "13381" + }, + { + "examine": "Some equipment for practicing combat.", + "ids": "13382" + }, + { + "examine": "Lots of equipment for practicing combat.", + "ids": "13383" + }, + { + "examine": "Is there a prize?", + "ids": "13384" + }, + { + "examine": "Is there a prize inside?", + "ids": "13385" + }, + { + "examine": "Is there a prize?", + "ids": "13386" + }, + { + "examine": "Is there a prize inside?", + "ids": "13387" + }, + { + "examine": "Is there a prize?", + "ids": "13388" + }, + { + "examine": "Is there a prize inside?", + "ids": "13389" + }, + { + "examine": "A private jester.", + "ids": "13390,13391" + }, + { + "examine": "See how much damage you can do to it!", + "ids": "13392,13393,13394" + }, + { + "examine": "You can practice your magic here.", + "ids": "13395,13396,13397" + }, + { + "examine": "You can try to get a hoop over this.", + "ids": "13398" + }, + { + "examine": "Someone hooped it!", + "ids": "13399" + }, + { + "examine": "More humane than using an actual bull's eye.", + "ids": "13400,13401" + }, + { + "examine": "Can you hit it?", + "ids": "13402,13403" + }, + { + "examine": "A letter-guessing game with a subtext of death.", + "ids": "13404" + }, + { + "examine": "Use this to leave the house.", + "ids": "13405" + }, + { + "examine": "Rocky!", + "ids": "13406" + }, + { + "examine": "A home for tiny fish and frogs.", + "ids": "13407" + }, + { + "examine": "What a naughty little imp!", + "ids": "13408" + }, + { + "examine": "What horrors lurk below?", + "ids": "13409,13410" + }, + { + "examine": "One of the most common trees in 2009Scape.", + "ids": "13411,13412" + }, + { + "examine": "A beautiful oak tree.", + "ids": "13413" + }, + { + "examine": "A lovely addition to the garden.", + "ids": "13414,13415,13416" + }, + { + "examine": "The tree shimmers with a magical force.", + "ids": "13417" + }, + { + "examine": "A lovely addition to the garden.", + "ids": "13418,13419,13420,13421,13422,13423" + }, + { + "examine": "A fully grown Willow tree.", + "ids": "13424" + }, + { + "examine": "A plant.", + "ids": "13425,13426,13427,13428,13429,13430,13431,13432,13433,13434,13435,13436" + }, + { + "examine": "A little orange flower.", + "ids": "13437" + }, + { + "examine": "Lonely as a cloud.", + "ids": "13438" + }, + { + "examine": "The bluebells are coming!", + "ids": "13439" + }, + { + "examine": "A little orange flower.", + "ids": "13440" + }, + { + "examine": "Lonely as a cloud.", + "ids": "13441" + }, + { + "examine": "The bluebells are coming!", + "ids": "13442" + }, + { + "examine": "A great big sunny flower.", + "ids": "13443" + }, + { + "examine": "Lovely flowers.", + "ids": "13444" + }, + { + "examine": "They smell lovely.", + "ids": "13445" + }, + { + "examine": "Great big sunny flowers.", + "ids": "13446" + }, + { + "examine": "Lovely flowers.", + "ids": "13447" + }, + { + "examine": "They smell lovely.", + "ids": "13448" + }, + { + "examine": "They mark a square.", + "ids": "13449" + }, + { + "examine": "Would probably not stop a charging rhinoceros.", + "ids": "13450" + }, + { + "examine": "Very rural.", + "ids": "13451" + }, + { + "examine": "A little bleak.", + "ids": "13452" + }, + { + "examine": "Marks the boundary of the garden.", + "ids": "13453" + }, + { + "examine": "Just like in Varrock palace!", + "ids": "13454" + }, + { + "examine": "Very posh!", + "ids": "13455" + }, + { + "examine": "Like a living wall.", + "ids": "13456,13457,13458,13459,13460,13461,13462,13463,13464,13465,13466,13467,13468,13469,13470,13471,13472,13473,13474,13475,13476" + }, + { + "examine": "Run for it! It's a gazebo!", + "ids": "13477" + }, + { + "examine": "Like a tiny private waterfall.", + "ids": "13478" + }, + { + "examine": "A sculpture of flowing water.", + "ids": "13479" + }, + { + "examine": "Two little fishes forever spew water into the pond.", + "ids": "13480" + }, + { + "examine": "A trophy of a mighty slayer!", + "ids": "13481,13482,13483,13484,13485" + }, + { + "examine": "A trophy of a mighty dragon-slayer!", + "ids": "13486" + }, + { + "examine": "A trophy of a mighty kalphite slayer!", + "ids": "13487" + }, + { + "examine": "A trophy of a master fisher.", + "ids": "13488,13489,13490" + }, + { + "examine": "The work of a master smith.", + "ids": "13491,13492" + }, + { + "examine": "Only the finest smiths can work runite.", + "ids": "13493" + }, + { + "examine": "Armour won by a great Castle Wars player.", + "ids": "13494,13495,13496" + }, + { + "examine": "I can climb these stairs.", + "ids": "13497" + }, + { + "examine": "They go down.", + "ids": "13498" + }, + { + "examine": "I can climb these stairs.", + "ids": "13499" + }, + { + "examine": "They go down.", + "ids": "13500" + }, + { + "examine": "I can climb these stairs.", + "ids": "13501" + }, + { + "examine": "They go down.", + "ids": "13502" + }, + { + "examine": "I can climb up or go down these stairs.", + "ids": "13503" + }, + { + "examine": "I can climb down these stairs.", + "ids": "13504" + }, + { + "examine": "I can climb up or go down these stairs.", + "ids": "13505" + }, + { + "examine": "I can climb down these stairs.", + "ids": "13506" + }, + { + "examine": "Elemental runes made by a skilled runecrafter.", + "ids": "13507" + }, + { + "examine": "Body, Cosmic, Chaos and Nature runes made by a skilled runecrafter.", + "ids": "13508" + }, + { + "examine": "Law, Blood, Soul and Death runes made by a great runecrafter.", + "ids": "13509" + }, + { + "examine": "A portrait of King Arthur.", + "ids": "13510" + }, + { + "examine": "A portrait of Elena.", + "ids": "13511" + }, + { + "examine": "A painting of the statue of King Alvis of Keldagrim.", + "ids": "13512" + }, + { + "examine": "A portrait of Prince Brand and Princess Astrid of Miscellania.", + "ids": "13513" + }, + { + "examine": "The deserts of Kharidian.", + "ids": "13514" + }, + { + "examine": "The exotic land of the Elves.", + "ids": "13515" + }, + { + "examine": "The tropical coast of Karamja.", + "ids": "13516" + }, + { + "examine": "Oxtable's famous painting of the Lumbridge water mill.", + "ids": "13517" + }, + { + "examine": "A painting of the spooky forests of Morytania.", + "ids": "13518" + }, + { + "examine": "The great demon-slaying sword that killed Delrith.", + "ids": "13519" + }, + { + "examine": "The great demon-slaying sword that killed Delrith and Agrith Naar.", + "ids": "13520" + }, + { + "examine": "The magical sword of King Arthur.", + "ids": "13521" + }, + { + "examine": "This shield protected a hero from the flames of the dragon Elvarg.", + "ids": "13522" + }, + { + "examine": "An Amulet of Glory, symbol of a member of the Heroes Guild.", + "ids": "13523" + }, + { + "examine": "The pleated white cape of a member of the Legends Guild.", + "ids": "13524" + }, + { + "examine": "A map of Misthalin and Asgarnia.", + "ids": "13525" + }, + { + "examine": "A map of 2009Scape.", + "ids": "13526" + }, + { + "examine": "A map of 2009Scape including major cave systems.", + "ids": "13527" + }, + { + "examine": "A basic cooking fire.", + "ids": "13528" + }, + { + "examine": "A cooking fire.", + "ids": "13529" + }, + { + "examine": "A cooking fire with a kettle.", + "ids": "13530" + }, + { + "examine": "A cooking fire with a pot.", + "ids": "13531" + }, + { + "examine": "The pot and kettle get along fine.", + "ids": "13532" + }, + { + "examine": "You can bake bread here.", + "ids": "13533,13534,13535" + }, + { + "examine": "You can cook pizza here.", + "ids": "13536,13537,13538" + }, + { + "examine": "You can cook here.", + "ids": "13539,13540,13541,13542,13543,13544" + }, + { + "examine": "Shelves full of kitchen utensils.", + "ids": "13545,13546,13547,13548,13549,13550,13551" + }, + { + "examine": "Shelves full of plates and tea cups.", + "ids": "13552,13553,13554,13555,13556,13557,13558" + }, + { + "examine": "Running water in your own home! Luxury!", + "ids": "13559,13560,13561,13562,13563,13564" + }, + { + "examine": "A wooden larder to keep food cool.", + "ids": "13565" + }, + { + "examine": "An oak larder to keep food cool.", + "ids": "13566" + }, + { + "examine": "A nicely carved oak larder to keep food cool.", + "ids": "13567" + }, + { + "examine": "It's got beer in it.", + "ids": "13568,13569" + }, + { + "examine": "An oak barrel of Asgarnian ale.", + "ids": "13570" + }, + { + "examine": "An oak barrel of Greenman's ale.", + "ids": "13571" + }, + { + "examine": "An oak barrel of Dragon Bitter.", + "ids": "13572" + }, + { + "examine": "An oak barrel of Chef's Delight.", + "ids": "13573" + }, + { + "examine": "A place for your pet to sleep.", + "ids": "13574" + }, + { + "examine": "Your pet would love to sleep here.", + "ids": "13575" + }, + { + "examine": "A luxurious sleeping place for your pet.", + "ids": "13576" + }, + { + "examine": "A basic wooden dining table.", + "ids": "13577" + }, + { + "examine": "A basic oak dining table.", + "ids": "13578" + }, + { + "examine": "A nice teak dining table.", + "ids": "13579" + }, + { + "examine": "A place for your pet to sleep.", + "ids": "13580" + }, + { + "examine": "It's not the best chair but you think it would take your weight.", + "ids": "13581" + }, + { + "examine": "It's an ugly rug, but better than a bare floor.", + "ids": "13588,13589,13590" + }, + { + "examine": "The handkerchief of giants!", + "ids": "13591,13592,13593" + }, + { + "examine": "An opulent rug woven with gold leaf.", + "ids": "13594,13595,13596" + }, + { + "examine": "A good source of books!", + "ids": "13597,13598,13599" + }, + { + "examine": "A good source of scrolls!", + "ids": "13600,13601,13602" + }, + { + "examine": "The curtain is open.", + "ids": "13603,13604,13605" + }, + { + "examine": "???", + "ids": "13606,13607" + }, + { + "examine": "Your house logo in mahogany.", + "ids": "13608" + }, + { + "examine": "You can light a fire here.", + "ids": "13609" + }, + { + "examine": "A fire burns cosily in the grate.", + "ids": "13610" + }, + { + "examine": "You can light a fire here.", + "ids": "13611" + }, + { + "examine": "A fire burns cosily in the grate.", + "ids": "13612" + }, + { + "examine": "You can light a fire here.", + "ids": "13613" + }, + { + "examine": "A fire burns cosily in the grate.", + "ids": "13614" + }, + { + "examine": "A gateway to Varrock", + "ids": "13615" + }, + { + "examine": "A gateway to Lumbridge", + "ids": "13616" + }, + { + "examine": "A gateway to Falador", + "ids": "13617" + }, + { + "examine": "A gateway to Camelot", + "ids": "13618" + }, + { + "examine": "A gateway to Ardougne", + "ids": "13619" + }, + { + "examine": "A gateway to the Yanille watchtower", + "ids": "13620" + }, + { + "examine": "A gateway to Trollheim", + "ids": "13621" + }, + { + "examine": "A gateway to Varrock", + "ids": "13622" + }, + { + "examine": "A gateway to Lumbridge", + "ids": "13623" + }, + { + "examine": "A gateway to Falador", + "ids": "13624" + }, + { + "examine": "A gateway to Camelot", + "ids": "13625" + }, + { + "examine": "A gateway to Ardougne", + "ids": "13626" + }, + { + "examine": "A gateway to the Yanille watchtower", + "ids": "13627" + }, + { + "examine": "A gateway to Trollheim", + "ids": "13628" + }, + { + "examine": "A gateway to Varrock", + "ids": "13629" + }, + { + "examine": "A gateway to Lumbridge", + "ids": "13630" + }, + { + "examine": "A gateway to Falador", + "ids": "13631" + }, + { + "examine": "A gateway to Camelot", + "ids": "13632" + }, + { + "examine": "A gateway to Ardougne", + "ids": "13633" + }, + { + "examine": "A gateway to the Yanille watchtower", + "ids": "13634" + }, + { + "examine": "A gateway to Trollheim", + "ids": "13635" + }, + { + "examine": "An un-directed teak portal frame.", + "ids": "13636" + }, + { + "examine": "An un-directed mahogany portal frame.", + "ids": "13637" + }, + { + "examine": "An un-directed marble portal frame.", + "ids": "13638" + }, + { + "examine": "It harnesses the power of something or other!", + "ids": "13639" + }, + { + "examine": "It controls the portals.", + "ids": "13640,13641" + }, + { + "examine": "A book full of arcane knowledge.", + "ids": "13642,13643,13644,13645,13646,13647,13648" + }, + { + "examine": "A wooden planet of your very own.", + "ids": "13649,13650,13651,13652,13653" + }, + { + "examine": "A wooden solar system of your very own.", + "ids": "13654,13655" + }, + { + "examine": "Used for observing heavenly bodies.", + "ids": "13656,13657,13658" + }, + { + "examine": "Use an elemental staff on it.", + "ids": "13659,13660,13661" + }, + { + "examine": "If there's a recipe for the philosopher's stone there, you can't see it.", + "ids": "13662" + }, + { + "examine": "If you want to look at the stars during the daytime, you can see them here!", + "ids": "13663" + }, + { + "examine": "A spotter's guide to demons.", + "ids": "13664" + }, + { + "examine": "Sit here and rule all you survey.", + "ids": "13665,13666,13667,13668,13669,13670,13671" + }, + { + "examine": "Pull this to activate your machinery of doom!", + "ids": "13672,13673,13674" + }, + { + "examine": "Go through this oak trapdoor to see the pit below your throne room.", + "ids": "13675" + }, + { + "examine": "Go through this teak trapdoor to see the pit below your throne room.", + "ids": "13676" + }, + { + "examine": "Go through this mahogany trapdoor to see the pit below your throne room.", + "ids": "13677" + }, + { + "examine": "Go through this oak trapdoor to see the pit below your throne room.", + "ids": "13678" + }, + { + "examine": "Go through this teak trapdoor to see the pit below your throne room.", + "ids": "13679" + }, + { + "examine": "Go through this mahogany trapdoor to see the pit below your throne room.", + "ids": "13680" + }, + { + "examine": "Keeps your victims in place.", + "ids": "13681" + }, + { + "examine": "Keeps your victims trapped.", + "ids": "13682,13683" + }, + { + "examine": "What could happen on this spot?", + "ids": "13684,13685,13686,13687,13688,13689" + }, + { + "examine": "An elengant cloth hanging.", + "ids": "13690" + }, + { + "examine": "An opulent gold-and-mahogany decoration.", + "ids": "13691" + }, + { + "examine": "A magnificent gold-and-marble decoration.", + "ids": "13692" + }, + { + "examine": "A splendid stained-glass decoration.", + "ids": "13693" + }, + { + "examine": "A nice teak ding bench.", + "ids": "13694" + }, + { + "examine": "A mahogany bench.", + "ids": "13695" + }, + { + "examine": "A very expensive bench.", + "ids": "13696" + }, + { + "examine": "An eye-wrenching nexus of utter negation!", + "ids": "13697" + }, + { + "examine": "An important looking chair.", + "ids": "13698" + }, + { + "examine": "Hammer, chisel, saw and shears.", + "ids": "13699" + }, + { + "examine": "Bucket, spade, tinderbox and knife.", + "ids": "13700" + }, + { + "examine": "Needle, apron and glassblowing pipe.", + "ids": "13701" + }, + { + "examine": "A selection of jewellery moulds.", + "ids": "13702" + }, + { + "examine": "Farming tools.", + "ids": "13703" + }, + { + "examine": "You can make furniture here.", + "ids": "13704,13705,13706,13707,13708" + }, + { + "examine": "You can do delicate crafting here.", + "ids": "13709,13710,13711,13712" + }, + { + "examine": "You can repair broken staffs and arrows here.", + "ids": "13713" + }, + { + "examine": "You can sharpen rusty swords here.", + "ids": "13714" + }, + { + "examine": "You can repair armour here.", + "ids": "13715" + }, + { + "examine": "You can add a plume to your helmet here.", + "ids": "13716" + }, + { + "examine": "You can paint your logo onto your heraldic shield here.", + "ids": "13717" + }, + { + "examine": "You can make a banner with your logo on here.", + "ids": "13718" + }, + { + "examine": "A wooden stool.", + "ids": "13719" + }, + { + "examine": "An oak stool.", + "ids": "13720" + }, + { + "examine": "There's nothing there", + "ids": "13721,13722,13723,13724,13725" + }, + { + "examine": "A private jester.", + "ids": "13726,13727,13728,13729,13730,13731,13732,13733" + }, + { + "examine": "A shield with the symbol of Arrav.", + "ids": "13734" + }, + { + "examine": "A shield with the symbol of Asgarnia.", + "ids": "13735" + }, + { + "examine": "A shield with the symbol of the Dorgeshuun.", + "ids": "13736" + }, + { + "examine": "A shield with a dragon on it.", + "ids": "13737" + }, + { + "examine": "A shield with a fairy on it.", + "ids": "13738" + }, + { + "examine": "A shield with the symbol of Guthix.", + "ids": "13739" + }, + { + "examine": "A shield with the symbol of the HAM cult.", + "ids": "13740" + }, + { + "examine": "A shield with a picture of a mythical 'horse'.", + "ids": "13741" + }, + { + "examine": "A shield with a picture of a Jungle Ogre.", + "ids": "13742" + }, + { + "examine": "A shield with the symbol of Kandarin.", + "ids": "13743" + }, + { + "examine": "A shield with the symbol of Misthalin.", + "ids": "13744" + }, + { + "examine": "A shield with a picture of a money bag.", + "ids": "13745" + }, + { + "examine": "A shield with the symbol of Saradomin.", + "ids": "13746" + }, + { + "examine": "A shield with a picture of a skull.", + "ids": "13747" + }, + { + "examine": "A shield with the symbol of Varrock.", + "ids": "13748" + }, + { + "examine": "A shield with the symbol of Zamorak.", + "ids": "13749" + }, + { + "examine": "A shield with the symbol of Arrav.", + "ids": "13750" + }, + { + "examine": "A shield with the symbol of Asgarnia.", + "ids": "13751" + }, + { + "examine": "A shield with the symbol of the Dorgeshuun.", + "ids": "13752" + }, + { + "examine": "A shield with a picture of a dragon.", + "ids": "13753" + }, + { + "examine": "A shield with a picture of a fairy.", + "ids": "13754" + }, + { + "examine": "A shield with the symbol of Guthix.", + "ids": "13755" + }, + { + "examine": "A shield with the symbol of the HAM cult.", + "ids": "13756" + }, + { + "examine": "A shield with a picture of the mythical 'horse'.", + "ids": "13757" + }, + { + "examine": "A shield with a picture of a Jungle Ogre.", + "ids": "13758" + }, + { + "examine": "A shield with the symbol of Kandarin.", + "ids": "13759" + }, + { + "examine": "A shield with the symbol of Misthalin.", + "ids": "13760" + }, + { + "examine": "A shield with a picture of a money bag.", + "ids": "13761" + }, + { + "examine": "A shield with the symbol of Saradomin.", + "ids": "13762" + }, + { + "examine": "A shield with a picture of a skull.", + "ids": "13763" + }, + { + "examine": "A shield with the symbol of Varrock.", + "ids": "13764" + }, + { + "examine": "A shield with the symbol of Zamorak.", + "ids": "13765" + }, + { + "examine": "A shield with the symbol of Arrav.", + "ids": "13766" + }, + { + "examine": "A shield with the symbol of Asgarnia.", + "ids": "13767" + }, + { + "examine": "A shield with the symbol of the Dorgeshuun/", + "ids": "13768" + }, + { + "examine": "A shield with a picture of a dragon.", + "ids": "13769" + }, + { + "examine": "A shield with a picture of a fairy.", + "ids": "13770" + }, + { + "examine": "A shield with the symbol of Guthix.", + "ids": "13771" + }, + { + "examine": "A shield with the symbol of the HAM cult.", + "ids": "13772" + }, + { + "examine": "A shield with a picture of the mythical 'horse'.", + "ids": "13773" + }, + { + "examine": "A shield with a picture of a Jungle Ogre.", + "ids": "13774" + }, + { + "examine": "A shield with the symbol of Kandarin.", + "ids": "13775" + }, + { + "examine": "A shield with the symbol of Misthalin.", + "ids": "13776" + }, + { + "examine": "A shield with a picture of a money bag.", + "ids": "13777" + }, + { + "examine": "A shield with the symbol of Saradomin.", + "ids": "13778" + }, + { + "examine": "A shield with a picture of a skull.", + "ids": "13779" + }, + { + "examine": "A shield with the symbol of Varrock.", + "ids": "13780" + }, + { + "examine": "A shield with the symbol of Zamorak.", + "ids": "13781" + }, + { + "examine": "The symbol of Arrav.", + "ids": "13782" + }, + { + "examine": "The symbol of Asgarnia.", + "ids": "13783" + }, + { + "examine": "The symbol of the Dorgeshuun.", + "ids": "13784" + }, + { + "examine": "A picture of a dragon.", + "ids": "13785" + }, + { + "examine": "A picture of a fairy.", + "ids": "13786" + }, + { + "examine": "The symbol of Guthix.", + "ids": "13787" + }, + { + "examine": "The symbol of the HAM cult.", + "ids": "13788" + }, + { + "examine": "A picture of the mythical 'horse'.", + "ids": "13789" + }, + { + "examine": "A picture of a Jungle Ogre.", + "ids": "13790" + }, + { + "examine": "The symbol of Kandarin.", + "ids": "13791" + }, + { + "examine": "The symbol of Misthalin.", + "ids": "13792" + }, + { + "examine": "A picture of a bag of money.", + "ids": "13793" + }, + { + "examine": "The symbol of Saradomin.", + "ids": "13794" + }, + { + "examine": "A picture of a skull.", + "ids": "13795" + }, + { + "examine": "The symbol of Varrock.", + "ids": "13796" + }, + { + "examine": "The symbol of Zamorak.", + "ids": "13797" + }, + { + "examine": "The symbol of Arrav.", + "ids": "13798" + }, + { + "examine": "The symbol of Asgarnia.", + "ids": "13799" + }, + { + "examine": "The symbol of the Dorgeshuun.", + "ids": "13800" + }, + { + "examine": "A picture of a dragon.", + "ids": "13801" + }, + { + "examine": "A picture of a fairy.", + "ids": "13802" + }, + { + "examine": "The symbol of Guthix.", + "ids": "13803" + }, + { + "examine": "The symbol of the HAM cult.", + "ids": "13804" + }, + { + "examine": "A picture of the mythical 'horse'.", + "ids": "13805" + }, + { + "examine": "A picture of a Jungle Ogre.", + "ids": "13806" + }, + { + "examine": "The symbol of Kandarin.", + "ids": "13807" + }, + { + "examine": "The symbol of Misthalin.", + "ids": "13808" + }, + { + "examine": "A picture of a money bag.", + "ids": "13809" + }, + { + "examine": "The symbol of Saradomin.", + "ids": "13810" + }, + { + "examine": "A picture of a skull.", + "ids": "13811" + }, + { + "examine": "The symbol of Varrock.", + "ids": "13812" + }, + { + "examine": "The symbol of Zamorak.", + "ids": "13813" + }, + { + "examine": "The symbol of Arrav.", + "ids": "13814" + }, + { + "examine": "The symbol of Asgarnia.", + "ids": "13815" + }, + { + "examine": "The symbol of the Dorgeshuun.", + "ids": "13816" + }, + { + "examine": "A picture of a dragon.", + "ids": "13817" + }, + { + "examine": "A picture of a fairy.", + "ids": "13818" + }, + { + "examine": "The symbol of Guthix.", + "ids": "13819" + }, + { + "examine": "The symbol of the HAM cult.", + "ids": "13820" + }, + { + "examine": "A picture of the mythical 'horse'.", + "ids": "13821" + }, + { + "examine": "A picture of a Jungle Ogre.", + "ids": "13822" + }, + { + "examine": "The symbol of Kandarin.", + "ids": "13823" + }, + { + "examine": "The symbol of Misthalin.", + "ids": "13824" + }, + { + "examine": "A picture of a money bag.", + "ids": "13825" + }, + { + "examine": "The symbol of Saradomin.", + "ids": "13826" + }, + { + "examine": "A picture of a skull.", + "ids": "13827" + }, + { + "examine": "The symbol of Varrock.", + "ids": "13828" + }, + { + "examine": "The symbol of Zamorak.", + "ids": "13829" + }, + { + "examine": "This should have resolved!", + "ids": "13830" + }, + { + "examine": "A path leading out of this swampy dead end.", + "ids": "13831,13832" + }, + { + "examine": "A path leading out of Mort Myre, you'll be running away if you go down here.", + "ids": "13833" + }, + { + "examine": "I could mend this if I had some wood...", + "ids": "13834" + }, + { + "examine": "This bridge is partially broken.", + "ids": "13835" + }, + { + "examine": "This bridge is slightly broken.", + "ids": "13836" + }, + { + "examine": "This bridge can be traversed safely.", + "ids": "13837" + }, + { + "examine": "Gloopy, sticky, muddy bog...", + "ids": "13838,13839" + }, + { + "examine": "A bush made up of long slender branches.", + "ids": "13840" + }, + { + "examine": "I hope it doesn't sink.", + "ids": "13841" + }, + { + "examine": "Ripples.", + "ids": "13842" + }, + { + "examine": "Big swamp tree base.", + "ids": "13843" + }, + { + "examine": "Big swamp tree top.", + "ids": "13844" + }, + { + "examine": "Big swamp tree branch.", + "ids": "13845" + }, + { + "examine": "A long vine hanging from a branch.", + "ids": "13846" + }, + { + "examine": "Small swamp tree with vines.", + "ids": "13847" + }, + { + "examine": "Small swamp tree.", + "ids": "13848,13849,13850,13851,13852,13853,13854,13855,13856,13857,13858,13859,13860,13861,13862,13863" + }, + { + "examine": "It's our transport across the swamp.", + "ids": "13864,13865" + }, + { + "examine": "A path leading out of this swampy dead end.", + "ids": "13866,13867,13868,13869,13870" + }, + { + "examine": "A path leading out of this swampy dead end, you'll be running away if you go down here.", + "ids": "13871" + }, + { + "examine": "An old backpack, it seems to be falling apart.", + "ids": "13872" + }, + { + "examine": "There's something written here...", + "ids": "13873,13874,13875,13876,13877" + }, + { + "examine": "I think it's the way out.", + "ids": "13878" + }, + { + "examine": "Get me out of here!", + "ids": "13879,13880" + }, + { + "examine": "Very hot!", + "ids": "13881" + }, + { + "examine": "To the next area!", + "ids": "13882,13883,13884,13885,13886,13887,13888,13889,13890" + }, + { + "examine": "A creepy hole.", + "ids": "13891,13892,13893,13894,13895,13896,13897,13898" + }, + { + "examine": "There's no way I'm going in there!", + "ids": "13899" + }, + { + "examine": "Doesn't look so scary now.", + "ids": "13900" + }, + { + "examine": "My way back to the surface.", + "ids": "13901,13902,13903" + }, + { + "examine": "The exit to the surface.", + "ids": "13904,13905,13906,13907,13908,13909,13910,13911,13912" + }, + { + "examine": "Where does it lead?", + "ids": "13913,13914,13915,13916,13917,13918,13919,13920,13921,13922,13923,13924" + }, + { + "examine": "What's that?", + "ids": "13925,13926,13927,13928,13929,13930,13931" + }, + { + "examine": "I think it's the way out.", + "ids": "13932" + }, + { + "examine": "I think it's the forward.", + "ids": "13933,13934,13935,13936,13937" + }, + { + "examine": "Does that really exist?", + "ids": "13938,13939,13940,13941,13942,13943,13944,13945,13946,13947,13948,13949,13950,13951,13952,13953,13954,13955,13956,13957,13958,13959,13960,13961,13962,13963,13964,13965,13966" + }, + { + "examine": "Should I go down there?", + "ids": "13967,13968,13969" + }, + { + "examine": "I can use that rope now.", + "ids": "13970" + }, + { + "examine": "Should I go down there?", + "ids": "13971,13972,13973,13974,13975,13976,13977,13978,13979,13980,13981,13982,13983,13984,13985,13986,13987,13988,13989,13990,13991,13992,13993" + }, + { + "examine": "Oooo, sharp, pointy things!", + "ids": "13994,13995,13996,13997,13998" + }, + { + "examine": "This will take me back to the surface.", + "ids": "13999,14000,14001" + }, + { + "examine": "A sign warning of danger.", + "ids": "14002" + }, + { + "examine": "Why do I never take time to look at the grass?", + "ids": "14003" + }, + { + "examine": "Well, I have the logs in place, now to get something to boil.", + "ids": "14005" + }, + { + "examine": "Covered in a thick layer of grease.", + "ids": "14006" + }, + { + "examine": "I'm glad this isn't for dinner.", + "ids": "14007" + }, + { + "examine": "This smells so very, very bad...", + "ids": "14008" + }, + { + "examine": "It seems to have all boiled away.", + "ids": "14009" + }, + { + "examine": "Stop examining signs! You're in the Wilderness now!", + "ids": "14503" + }, + { + "examine": "Danger, Wilderness up ahead. Last chance to turn back...", + "ids": "14504" + }, + { + "examine": "Danger, Wilderness up ahead. Watch out for the Beast!", + "ids": "14505" + }, + { + "examine": "Danger, Wilderness up ahead. Beware of stray magma.", + "ids": "14506" + }, + { + "examine": "Danger, Wilderness up ahead. Almost certain death!", + "ids": "14507" + }, + { + "examine": "Home sweet home?", + "ids": "15477" + }, + { + "examine": "Home sweet home?", + "ids": "15480" + }, + { + "examine": "Home sweet home?", + "ids": "15748" + }, + { + "examine": "Danger - Possibly deadly creatures below!", + "ids": "16083,16151,16117" + }, + { + "examine": "Large urn.", + "ids": "17362" + }, + { + "examine": "A large fish.", + "ids": "18482" + }, + { + "examine": "A sign on a cactus.", + "ids": "18876" + }, + { + "examine": "Dead and half-buried.", + "ids": "19996" + }, + { + "examine": "Dead animal head. Lovely.", + "ids": "19997" + }, + { + "examine": "Might be worth opening?", + "ids": "21299" + }, + { + "examine": "A sturdy metal door.", + "ids": "21400,21402,21399" + }, + { + "examine": "I can climb this.", + "ids": "21395,29355" + }, + { + "examine": "A closed, sturdy metal door.", + "ids": "21403,21405" + }, + { + "examine": "An open, sturdy metal door.", + "ids": "21404" + }, + { + "examine": "A display case, full of axes.", + "ids": "21437" + }, + { + "examine": "A display case, full of swords.", + "ids": "21438" + }, + { + "examine": "A table, displaying swords.", + "ids": "21439" + }, + { + "examine": "A table for preparing fish.", + "ids": "21441" + }, + { + "examine": "A container for storing mineral ores.", + "ids": "21442" + }, + { + "examine": "A table for working with ores.", + "ids": "21443" + }, + { + "examine": "A pile of raw mineral ores.", + "ids": "21444" + }, + { + "examine": "A shield display.", + "ids": "21445,21446" + }, + { + "examine": "A shelf, displaying armour.", + "ids": "21447" + }, + { + "examine": "I can climb down these stairs.", + "ids": "21455" + }, + { + "examine": "A sturdy-looking throne.", + "ids": "21464" + }, + { + "examine": "A stone torch.", + "ids": "21465" + }, + { + "examine": "A chair made from stone.", + "ids": "21607" + }, + { + "examine": "A table with swords on it.", + "ids": "21608" + }, + { + "examine": "A bed to sleep in.", + "ids": "21611" + }, + { + "examine": "A stone crate with some stuff in it.", + "ids": "21612" + }, + { + "examine": "A table with plates and mugs on it.", + "ids": "21609,21610" + }, + { + "examine": "A shelf with some cups on it.", + "ids": "21614,21615" + }, + { + "examine": "A Fremennik flag.", + "ids": "21637" + }, + { + "examine": "A short longboat!", + "ids": "21834" + }, + { + "examine": "Contains traces of summoning energy.", + "ids": "29939,29943,29944,29945,29947,29951,29952,29953,29954" + }, + { + "examine": "An interesting sign.", + "ids": "31297,31298,31299,31300,31301" + }, + { + "examine": "I wonder what this spooky contains.", + "ids": "37051" + }, + { + "examine": "The mine has collapsed.", + "ids": "37634" + }, + { + "examine": "It really was this big!", + "ids": "40043" + }, + { + "examine": "It really was this big!", + "ids": "40042" + }, + { + "examine": "A wooden barrel for storage.", + "ids": "40018" + }, + { + "examine": "A wooden barrel containing lots of fish.", + "ids": "40019" + }, + { + "examine": "A nice sturdy looking table.", + "ids": "40044" + }, + { + "examine": "A wooden crate.", + "ids": "40021" + }, + { + "examine": "Some wooden crates.", + "ids": "40022" + }, + { + "examine": "A large potted plant.", + "ids": "40111" + }, + { + "examine": "Tick-tock, it's a clock.", + "ids": "40029" + }, + { + "examine": "I wonder what's inside.", + "ids": "29400,32010,40093" + }, + { + "examine": "Useful for putting things on.", + "ids": "40031" + }, + { + "examine": "Items are for sale here.", + "ids": "40028" + }, + { + "examine": "I can climb this.", + "ids": "40026" + }, + { + "examine": "Some wooden crates.", + "ids": "15032" + }, + { + "examine": "A wooden crate.", + "ids": "15030" + }, + { + "examine": "A wooden crate.", + "ids": "15031" + }, + { + "examine": "A sealed barrel with a warning sign on it.", + "ids": "17296" + }, + { + "examine": "A barrel with a warning sign on it.", + "ids": "17297" + }, + { + "examine": "A beautiful landscape.", + "ids": "24184" + }, + { + "examine": "These open and close!", + "ids": "40050" + }, + { + "examine": "A case. With books.", + "ids": "40033" + }, + { + "examine": "A drab looking bed.", + "ids": "40035" + }, + { + "examine": "I can climb down this.", + "ids": "40027,20987,29358" + }, + { + "examine": "These open and close!", + "ids": "40052" + }, + { + "examine": "The perfect place to store things.", + "ids": "40054" + }, + { + "examine": "Break glass in case in case of emergency.", + "ids": "40076" + }, + { + "examine": "I can climb up these stairs.", + "ids": "40057" + }, + { + "examine": "Trinkets and stuff.", + "ids": "40075" + }, + { + "examine": "Looking good!", + "ids": "40065" + }, + { + "examine": "It looks slightly different from the rest.", + "ids": "30532" + }, + { + "examine": "'Here lies...' is all I can read.", + "ids": "30671,30672" + }, + { + "examine": "The inscription is worn away and unreadable.", + "ids": "30667,30669" + }, + { + "examine": "Whoever bought this must have really cared for the inhabitant.", + "ids": "30668" + }, + { + "examine": "Make a wish.", + "ids": "28715" + }, + { + "examine": "Contains no summoning energy.", + "ids": "28720,28721" + }, + { + "examine": "Glowing with barely-suppressed energies.", + "ids": "28719" + }, + { + "examine": "Looks kind of like a man made of metal.", + "ids": "32292" + }, + { + "examine": "Technically a bed.", + "ids": "32031" + }, + { + "examine": "Now that's what I call slimline!", + "ids": "32072" + }, + { + "examine": "A really bad portrait of the King.", + "ids": "32326" + }, + { + "examine": "A tatty old standard.", + "ids": "32295" + }, + { + "examine": "I can climb this.", + "ids": "32015" + }, + { + "examine": "An old crate for storage.", + "ids": "29351,29352,31137,31140" + }, + { + "examine": "A wooden barrel for storage.", + "ids": "17308,31136,36798" + }, + { + "examine": "A home for baby creatures.", + "ids": "32312" + }, + { + "examine": "Must have been laid by a huge bird.", + "ids": "32313" + }, + { + "examine": "Stops bits of building falling on me.", + "ids": "37451" + }, + { + "examine": "I wonder what's under it?", + "ids": "26933" + }, + { + "examine": "I wonder what's down there?", + "ids": "26934,36687" + }, + { + "examine": "A strong metal door.", + "ids": "29315,29316,29317,29318,29319,29320,29321,29322" + }, + { + "examine": "The body of a Dwarf savaged by Goblins.", + "ids": "15596" + }, + { + "examine": "I don't know art, but I like it!", + "ids": "36809" + }, + { + "examine": "The wood burning here must be full of salt.", + "ids": "14169" + }, + { + "examine": "Sturdy looking.", + "ids": "21176" + }, + { + "examine": "Doesn't look like it'll be sailing again.", + "ids": "14173" + }, + { + "examine": "Looks a bit damp.", + "ids": "14174" + }, + { + "examine": "Those druids certainly make the best of natural resources.", + "ids": "28588,28589" + }, + { + "examine": "Sit back and relax...", + "ids": "28636,18488" + }, + { + "examine": "One horsepower; wooden suspension: a beauty.", + "ids": "34376" + }, + { + "examine": "I don't even want to think about what did that...", + "ids": "32071" + }, + { + "examine": "It's a door.", + "ids": "31838" + }, + { + "examine": "Wooden crates for storage.", + "ids": "31138,31139" + }, + { + "examine": "These may have something in them.", + "ids": "32049,36929" + }, + { + "examine": "Probably looked better mounted on the dragon's neck.", + "ids": "15564" + }, + { + "examine": "A magical wall decoration.", + "ids": "32324,32325" + }, + { + "examine": "Perhaps I should search this.", + "ids": "32009" + }, + { + "examine": "The door is closed.", + "ids": "31808" + }, + { + "examine": "The door is open.", + "ids": "31809" + }, + { + "examine": "The bank teller will serve you from here.", + "ids": "36786" + }, + { + "examine": "Closed for business.", + "ids": "36787" + }, + { + "examine": "Banking transactions are processed here.", + "ids": "36789,37158" + }, + { + "examine": "This will give me a bit more information.", + "ids": "29461,29462,29463,29464" + }, + { + "examine": "I can climb over the fence using this.", + "ids": "29460" + }, + { + "examine": "It looks slightly rickety.", + "ids": "29468" + }, + { + "examine": "These probably contain Farming supplies.", + "ids": "29471" + }, + { + "examine": "It could hold a gnome, but probably not a human.", + "ids": "29472" + }, + { + "examine": "Contains gnome clothes.", + "ids": "29473" + }, + { + "examine": "I wonder what's buried here.", + "ids": "29476,29477,29478" + }, + { + "examine": "So small only a rabbit could squeeze down.", + "ids": "29533" + }, + { + "examine": "Gnome sweet gnome?", + "ids": "29534" + }, + { + "examine": "Potentially hot!", + "ids": "25464" + }, + { + "examine": "A goblin fire. Looks fierce.", + "ids": "25465" + }, + { + "examine": "A wooden crate for storage.", + "ids": "18506" + }, + { + "examine": "A pile of crates for storage.", + "ids": "18508" + }, + { + "examine": "I wonder where they will take me.", + "ids": "25432" + }, + { + "examine": "'Pay back all your debts by borrowing more money from us!' Clever.", + "ids": "23924" + }, + { + "examine": "The bank teller will serve you from here.", + "ids": "11402" + }, + { + "examine": "I can climb up these stairs.", + "ids": "24349" + }, + { + "examine": "A handy place for filling in forms and paperwork.", + "ids": "23928" + }, + { + "examine": "Where people may put themselves.", + "ids": "17462" + }, + { + "examine": "For keeping things in.", + "ids": "24924" + }, + { + "examine": "Contains quite a lot of someone else's property.", + "ids": "23925" + }, + { + "examine": "This chest looks strong.", + "ids": "23926" + }, + { + "examine": "They say money can't buy happiness.", + "ids": "23929" + }, + { + "examine": "A gilt sculpture of a monarch.", + "ids": "23930" + }, + { + "examine": "Cave exit.", + "ids": "15812" + }, + { + "examine": "A flag on a pole.", + "ids": "37335" + }, + { + "examine": "I can climb down these stairs.", + "ids": "36775,36778" + }, + { + "examine": "Jump here.", + "ids": "23271" + }, + { + "examine": "Popular on sandy beaches where fruity cocktails may be found.", + "ids": "18856" + }, + { + "examine": "Looks like part of the entrance is blocked by rubble.", + "ids": "15767" + }, + { + "examine": "They know how much that dog in the window is.", + "ids": "28351" + }, + { + "examine": "Lots of things for a growing fish.", + "ids": "28355" + }, + { + "examine": "It's a basket for dogs.", + "ids": "28338" + }, + { + "examine": "Enough baskets for any dog's needs.", + "ids": "28339" + }, + { + "examine": "Made by the A. Wilson Company.", + "ids": "28345" + }, + { + "examine": "Sure it's gilded, but would you want to live in it?", + "ids": "28335" + }, + { + "examine": "It's covered in hairs.", + "ids": "28361" + }, + { + "examine": "It's good for bedding and stuffing.", + "ids": "28343" + }, + { + "examine": "Lots of little fishies.", + "ids": "28340" + }, + { + "examine": "Fetch!", + "ids": "28360" + }, + { + "examine": "It's a basket for cats.", + "ids": "28337" + }, + { + "examine": "It seems to be sat happily on the counter.", + "ids": "28356" + }, + { + "examine": "Lots of things for a growing pup.", + "ids": "28353" + }, + { + "examine": "Lots of things for a growing kitten.", + "ids": "28354" + }, + { + "examine": "Lots of things for a growing pup/kitten/fish.", + "ids": "28357" + }, + { + "examine": "Things are cheaper by the pound.", + "ids": "28344" + }, + { + "examine": "It incubates eggs.", + "ids": "28336" + }, + { + "examine": "There are a lot of pet supplies here.", + "ids": "28357,28358,28363,28364" + }, + { + "examine": "Keeps the puppies out of trouble.", + "ids": "28341" + }, + { + "examine": "Warning! Danger of death.", + "ids": "29373" + }, + { + "examine": "There are some toolboxes on this table.", + "ids": "36573,36580" + }, + { + "examine": "There's some rock I can use with the catapult here.", + "ids": "36574,36581" + }, + { + "examine": "There are some barricades here.", + "ids": "36575,36582" + }, + { + "examine": "There is some rope here.", + "ids": "36576,36583" + }, + { + "examine": "There are some explosive potions here.", + "ids": "36577,36584" + }, + { + "examine": "There are some pickaxes on this table.", + "ids": "36578,36585" + }, + { + "examine": "There are some bandages on this table.", + "ids": "36579,36586" + }, + { + "examine": "Rough but adequate.", + "ids": "14918" + } +] \ No newline at end of file diff --git a/Server/data/configs/ranged_weapon_configs.json b/Server/data/configs/ranged_weapon_configs.json new file mode 100644 index 0000000..335c9f0 --- /dev/null +++ b/Server/data/configs/ranged_weapon_configs.json @@ -0,0 +1,1550 @@ +[ + { + "itemId": "732", + "name": "Holy water", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "385", + "drop_ammo": "true", + "ammunition": "732" + }, + { + "itemId": "767", + "name": "Phoenix crossbow", + "ammo_slot": "13", + "weapon_type": "1", + "animation": "4230", + "drop_ammo": "true", + "ammunition": "877,878,6061,6062,879,9236" + }, + { + "itemId": "800", + "name": "Bronze thrownaxe", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "800" + }, + { + "itemId": "801", + "name": "Iron thrownaxe", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "801" + }, + { + "itemId": "802", + "name": "Steel thrownaxe", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "802" + }, + { + "itemId": "803", + "name": "Mithril thrownaxe", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "803" + }, + { + "itemId": "804", + "name": "Adamant thrownaxe", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "804" + }, + { + "itemId": "805", + "name": "Rune thrownaxe", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "805" + }, + { + "itemId": "806", + "name": "Bronze dart", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "6600", + "drop_ammo": "true", + "ammunition": "806" + }, + { + "itemId": "807", + "name": "Iron dart", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "6600", + "drop_ammo": "true", + "ammunition": "807" + }, + { + "itemId": "808", + "name": "Steel dart", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "6600", + "drop_ammo": "true", + "ammunition": "808" + }, + { + "itemId": "809", + "name": "Mithril dart", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "6600", + "drop_ammo": "true", + "ammunition": "809" + }, + { + "itemId": "810", + "name": "Adamant dart", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "6600", + "drop_ammo": "true", + "ammunition": "810" + }, + { + "itemId": "811", + "name": "Rune dart", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "6600", + "drop_ammo": "true", + "ammunition": "811" + }, + { + "itemId": "812", + "name": "Bronze dart(p)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "6600", + "drop_ammo": "true", + "ammunition": "812" + }, + { + "itemId": "813", + "name": "Iron dart(p)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "6600", + "drop_ammo": "true", + "ammunition": "813" + }, + { + "itemId": "814", + "name": "Steel dart(p)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "6600", + "drop_ammo": "true", + "ammunition": "814" + }, + { + "itemId": "815", + "name": "Mithril dart(p)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "6600", + "drop_ammo": "true", + "ammunition": "815" + }, + { + "itemId": "816", + "name": "Adamant dart(p)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "6600", + "drop_ammo": "true", + "ammunition": "816" + }, + { + "itemId": "817", + "name": "Rune dart(p)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "6600", + "drop_ammo": "true", + "ammunition": "817" + }, + { + "itemId": "825", + "name": "Bronze javelin", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "825" + }, + { + "itemId": "826", + "name": "Iron javelin", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "826" + }, + { + "itemId": "827", + "name": "Steel javelin", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "827" + }, + { + "itemId": "828", + "name": "Mithril javelin", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "828" + }, + { + "itemId": "829", + "name": "Adamant javelin", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "829" + }, + { + "itemId": "830", + "name": "Rune javelin", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "830" + }, + { + "itemId": "831", + "name": "Bronze javelin(p)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "831" + }, + { + "itemId": "832", + "name": "Iron javelin(p)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "832" + }, + { + "itemId": "833", + "name": "Steel javelin(p)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "833" + }, + { + "itemId": "834", + "name": "Mithril javelin(p)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "834" + }, + { + "itemId": "835", + "name": "Adamant javelin(p)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "835" + }, + { + "itemId": "836", + "name": "Rune javelin(p)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "836" + }, + { + "itemId": "837", + "name": "Crossbow", + "ammo_slot": "13", + "weapon_type": "1", + "animation": "4230", + "drop_ammo": "true", + "ammunition": "877,878,6061,6062,879,9236" + }, + { + "itemId": "839", + "name": "Longbow", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "426", + "drop_ammo": "true", + "ammunition": "882,883,5616,5622,598,884,885,5617,5623,2532" + }, + { + "itemId": "841", + "name": "Shortbow", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "426", + "drop_ammo": "true", + "ammunition": "882,883,5616,5622,598,884,885,5617,5623,2532" + }, + { + "itemId": "843", + "name": "Oak shortbow", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "426", + "drop_ammo": "true", + "ammunition": "882,883,5616,5622,598,884,885,5617,5623,2532,886,887,5618,5624,2534" + }, + { + "itemId": "845", + "name": "Oak longbow", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "426", + "drop_ammo": "true", + "ammunition": "882,883,5616,5622,598,884,885,5617,5623,2532,886,887,5618,5624,2534" + }, + { + "itemId": "847", + "name": "Willow longbow", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "426", + "drop_ammo": "true", + "ammunition": "882,883,5616,5622,598,884,885,5617,5623,2532,886,887,5618,5624,2534,888,889,5619,5625,2536" + }, + { + "itemId": "849", + "name": "Willow shortbow", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "426", + "drop_ammo": "true", + "ammunition": "882,883,5616,5622,598,884,885,5617,5623,2532,886,887,5618,5624,2534,888,889,5619,5625,2536" + }, + { + "itemId": "851", + "name": "Maple longbow", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "426", + "drop_ammo": "true", + "ammunition": "882,883,5616,5622,598,884,885,5617,5623,2532,886,887,5618,5624,2534,888,889,5619,5625,2536,890,891,5620,5626,2538" + }, + { + "itemId": "853", + "name": "Maple shortbow", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "426", + "drop_ammo": "true", + "ammunition": "882,883,5616,5622,598,884,885,5617,5623,2532,886,887,5618,5624,2534,888,889,5619,5625,2536,890,891,5620,5626,2538" + }, + { + "itemId": "855", + "name": "Yew longbow", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "426", + "drop_ammo": "true", + "ammunition": "882,883,5616,5622,598,884,885,5617,5623,2532,886,887,5618,5624,2534,888,889,5619,5625,2536,890,891,5620,5626,2538,892,893,5621,5627,2540,78" + }, + { + "itemId": "857", + "name": "Yew shortbow", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "426", + "drop_ammo": "true", + "ammunition": "882,883,5616,5622,598,884,885,5617,5623,2532,886,887,5618,5624,2534,888,889,5619,5625,2536,890,891,5620,5626,2538,892,893,5621,5627,2540,78" + }, + { + "itemId": "859", + "name": "Magic longbow", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "426", + "drop_ammo": "true", + "ammunition": "882,883,5616,5622,598,884,885,5617,5623,2532,886,887,5618,5624,2534,888,889,5619,5625,2536,890,891,5620,5626,2538,892,893,5621,5627,2540,78,4160" + }, + { + "itemId": "861", + "name": "Magic shortbow", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "426", + "drop_ammo": "true", + "ammunition": "882,883,5616,5622,598,884,885,5617,5623,2532,886,887,5618,5624,2534,888,889,5619,5625,2536,890,891,5620,5626,2538,892,893,5621,5627,2540,78,4160" + }, + { + "itemId": "863", + "name": "Iron knife", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "863" + }, + { + "itemId": "864", + "name": "Bronze knife", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "864" + }, + { + "itemId": "865", + "name": "Steel knife", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "865" + }, + { + "itemId": "866", + "name": "Mithril knife", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "866" + }, + { + "itemId": "867", + "name": "Adamant knife", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "867" + }, + { + "itemId": "868", + "name": "Rune knife", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "868" + }, + { + "itemId": "869", + "name": "Black knife", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "869" + }, + { + "itemId": "870", + "name": "Bronze knife(p)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "870" + }, + { + "itemId": "871", + "name": "Iron knife(p)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "871" + }, + { + "itemId": "872", + "name": "Steel knife(p)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "872" + }, + { + "itemId": "873", + "name": "Mithril knife(p)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "873" + }, + { + "itemId": "874", + "name": "Black knife(p)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "874" + }, + { + "itemId": "875", + "name": "Adamant knife(p)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "875" + }, + { + "itemId": "876", + "name": "Rune knife(p)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "876" + }, + { + "itemId": "2883", + "name": "Ogre bow", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "426", + "drop_ammo": "true", + "ammunition": "2866" + }, + { + "itemId": "3093", + "name": "Black dart", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "6600", + "drop_ammo": "true", + "ammunition": "3093" + }, + { + "itemId": "3094", + "name": "Black dart(p)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "6600", + "drop_ammo": "true", + "ammunition": "3094" + }, + { + "itemId": "4212", + "name": "New crystal bow", + "ammo_slot": "3", + "weapon_type": "4", + "animation": "426", + "drop_ammo": "0", + "ammunition": "4212" + }, + { + "itemId": "4214", + "name": "Crystal bow full", + "ammo_slot": "3", + "weapon_type": "4", + "animation": "426", + "drop_ammo": "0", + "ammunition": "4214" + }, + { + "itemId": "4215", + "name": "Crystal bow 9/10", + "ammo_slot": "3", + "weapon_type": "4", + "animation": "426", + "drop_ammo": "0", + "ammunition": "4215" + }, + { + "itemId": "4216", + "name": "Crystal bow 8/10", + "ammo_slot": "3", + "weapon_type": "4", + "animation": "426", + "drop_ammo": "0", + "ammunition": "4216" + }, + { + "itemId": "4217", + "name": "Crystal bow 7/10", + "ammo_slot": "3", + "weapon_type": "4", + "animation": "426", + "drop_ammo": "0", + "ammunition": "4217" + }, + { + "itemId": "4218", + "name": "Crystal bow 6/10", + "ammo_slot": "3", + "weapon_type": "4", + "animation": "426", + "drop_ammo": "0", + "ammunition": "4218" + }, + { + "itemId": "4219", + "name": "Crystal bow 5/10", + "ammo_slot": "3", + "weapon_type": "4", + "animation": "426", + "drop_ammo": "0", + "ammunition": "4219" + }, + { + "itemId": "4220", + "name": "Crystal bow 4/10", + "ammo_slot": "3", + "weapon_type": "4", + "animation": "426", + "drop_ammo": "0", + "ammunition": "4220" + }, + { + "itemId": "4221", + "name": "Crystal bow 3/10", + "ammo_slot": "3", + "weapon_type": "4", + "animation": "426", + "drop_ammo": "0", + "ammunition": "4221" + }, + { + "itemId": "4222", + "name": "Crystal bow 2/10", + "ammo_slot": "3", + "weapon_type": "4", + "animation": "426", + "drop_ammo": "0", + "ammunition": "4222" + }, + { + "itemId": "4223", + "name": "Crystal bow 1/10", + "ammo_slot": "3", + "weapon_type": "4", + "animation": "426", + "drop_ammo": "0", + "ammunition": "4223" + }, + { + "itemId": "4734", + "name": "Karil\\'s crossbow", + "ammo_slot": "13", + "weapon_type": "1", + "animation": "2075", + "drop_ammo": "0", + "ammunition": "4740" + }, + { + "itemId": "4827", + "name": "Comp ogre bow", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "426", + "drop_ammo": "true", + "ammunition": "2866,4773,4778,4783,4788,4793,4798,4803" + }, + { + "itemId": "4934", + "name": "Karil\\'s x-bow 100", + "ammo_slot": "13", + "weapon_type": "1", + "animation": "2075", + "drop_ammo": "0", + "ammunition": "4740" + }, + { + "itemId": "4935", + "name": "Karil\\'s x-bow 75", + "ammo_slot": "13", + "weapon_type": "1", + "animation": "2075", + "drop_ammo": "0", + "ammunition": "4740" + }, + { + "itemId": "4936", + "name": "Karil\\'s x-bow 50", + "ammo_slot": "13", + "weapon_type": "1", + "animation": "2075", + "drop_ammo": "0", + "ammunition": "4740" + }, + { + "itemId": "4937", + "name": "Karil\\'s x-bow 25", + "ammo_slot": "13", + "weapon_type": "1", + "animation": "2075", + "drop_ammo": "0", + "ammunition": "4740" + }, + { + "itemId": "5628", + "name": "Bronze dart(p+)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "6600", + "drop_ammo": "true", + "ammunition": "5628" + }, + { + "itemId": "5629", + "name": "Iron dart(p+)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "6600", + "drop_ammo": "true", + "ammunition": "5629" + }, + { + "itemId": "5630", + "name": "Steel dart(p+)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "6600", + "drop_ammo": "true", + "ammunition": "5630" + }, + { + "itemId": "5631", + "name": "Black dart(p+)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "6600", + "drop_ammo": "true", + "ammunition": "5631" + }, + { + "itemId": "5632", + "name": "Mithril dart(p+)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "6600", + "drop_ammo": "true", + "ammunition": "5632" + }, + { + "itemId": "5633", + "name": "Adamant dart(p+)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "6600", + "drop_ammo": "true", + "ammunition": "5633" + }, + { + "itemId": "5634", + "name": "Rune dart(p+)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "6600", + "drop_ammo": "true", + "ammunition": "5634" + }, + { + "itemId": "5635", + "name": "Bronze dart(p++)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "6600", + "drop_ammo": "true", + "ammunition": "5635" + }, + { + "itemId": "5636", + "name": "Iron dart(p++)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "6600", + "drop_ammo": "true", + "ammunition": "5636" + }, + { + "itemId": "5637", + "name": "Steel dart(p++)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "6600", + "drop_ammo": "true", + "ammunition": "5637" + }, + { + "itemId": "5638", + "name": "Black dart(p++)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "6600", + "drop_ammo": "true", + "ammunition": "5638" + }, + { + "itemId": "5639", + "name": "Mithril dart(p++)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "6600", + "drop_ammo": "true", + "ammunition": "5639" + }, + { + "itemId": "5640", + "name": "Adamant dart(p++)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "6600", + "drop_ammo": "true", + "ammunition": "5640" + }, + { + "itemId": "5641", + "name": "Rune dart(p++)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "6600", + "drop_ammo": "true", + "ammunition": "5641" + }, + { + "itemId": "5642", + "name": "Bronze javelin(p+)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "5642" + }, + { + "itemId": "5643", + "name": "Iron javelin(p+)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "5643" + }, + { + "itemId": "5644", + "name": "Steel javelin(p+)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "5644" + }, + { + "itemId": "5645", + "name": "Mithril javelin(p+)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "5645" + }, + { + "itemId": "5646", + "name": "Adamant javelin(p+)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "5646" + }, + { + "itemId": "5647", + "name": "Rune javelin(p+)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "5647" + }, + { + "itemId": "5648", + "name": "Bronze jav\\'n(p++)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "5648" + }, + { + "itemId": "5649", + "name": "Iron javelin(p++)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "5649" + }, + { + "itemId": "5650", + "name": "Steel javelin(p++)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "5650" + }, + { + "itemId": "5651", + "name": "Mithril javelin(p++)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "5651" + }, + { + "itemId": "5652", + "name": "Adamant javelin(p++)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "5652" + }, + { + "itemId": "5653", + "name": "Rune javelin(p++)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "5653" + }, + { + "itemId": "5654", + "name": "Bronze knife(p+)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "5654" + }, + { + "itemId": "5655", + "name": "Iron knife(p+)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "5655" + }, + { + "itemId": "5656", + "name": "Steel knife(p+)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "5656" + }, + { + "itemId": "5657", + "name": "Mithril knife(p+)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "5657" + }, + { + "itemId": "5658", + "name": "Black knife(p+)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "5658" + }, + { + "itemId": "5659", + "name": "Adamant knife(p+)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "5659" + }, + { + "itemId": "5660", + "name": "Rune knife(p+)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "5660" + }, + { + "itemId": "5661", + "name": "Bronze knife(p++)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "5661" + }, + { + "itemId": "5662", + "name": "Iron knife(p++)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "5662" + }, + { + "itemId": "5663", + "name": "Steel knife(p++)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "5663" + }, + { + "itemId": "5664", + "name": "Mithril knife(p++)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "5664" + }, + { + "itemId": "5665", + "name": "Black knife(p++)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "5665" + }, + { + "itemId": "5666", + "name": "Adamant knife(p++)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "5666" + }, + { + "itemId": "5667", + "name": "Rune knife(p++)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "929", + "drop_ammo": "true", + "ammunition": "5667" + }, + { + "itemId": "6522", + "name": "Toktz-xil-ul", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "2614", + "drop_ammo": "true", + "ammunition": "6522" + }, + { + "itemId": "6724", + "name": "Seercull", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "426", + "drop_ammo": "true", + "ammunition": "882,883,5616,5622,598,884,885,5617,5623,2532,886,887,5618,5624,2534,888,889,5619,5625,2536,890,891,5620,5626,2538,892,893,5621,5627,2540,78,4160" + }, + { + "itemId": "8880", + "name": "Dorgeshuun c\\'bow", + "ammo_slot": "13", + "weapon_type": "1", + "animation": "4230", + "drop_ammo": "true", + "ammunition": "8882,877,878,6061,6062,879,9236,9139,9286,9293,9300,9140,9287,9294,9237,9145,9301,9292,9299,9306,9335,880,9238" + }, + { + "itemId": "9174", + "name": "Bronze crossbow", + "ammo_slot": "13", + "weapon_type": "1", + "animation": "4230", + "drop_ammo": "true", + "ammunition": "877,878,6061,6062,879,9236" + }, + { + "itemId": "9176", + "name": "Blurite crossbow", + "ammo_slot": "13", + "weapon_type": "1", + "animation": "4230", + "drop_ammo": "true", + "ammunition": "877,878,6061,6062,879,9139,9236,9286,9293,9300,9335,9237" + }, + { + "itemId": "9177", + "name": "Iron crossbow", + "ammo_slot": "13", + "weapon_type": "1", + "animation": "4230", + "drop_ammo": "true", + "ammunition": "877,878,6061,6062,879,9236,9139,9140,9287,9294,9301,880,9238,9145,9286,9293,9300,9292,9299,9306,9335,9237" + }, + { + "itemId": "9179", + "name": "Steel crossbow", + "ammo_slot": "13", + "weapon_type": "1", + "animation": "4230", + "drop_ammo": "true", + "ammunition": "877,878,6061,6062,879,9139,9140,9236,9141,9288,9295,9302,9336,9239,9145,9286,9293,9300,9287,9294,9301,9292,9299,9306,9335,9237,880,9238" + }, + { + "itemId": "9181", + "name": "Mith crossbow", + "ammo_slot": "13", + "weapon_type": "1", + "animation": "4230", + "drop_ammo": "true", + "ammunition": "877,878,6061,6062,879,9236,9141,9288,9295,9302,9336,9239,13083,13084,13085,13086,9142,9289,9296,9303,9337,9240,9338,9145,9139,9140,9241,9286,9293,9300,9140,9287,9294,9301,9292,9299,9306,9335,9237,880,9238,13083,13084,13085,13086" + }, + { + "itemId": "9183", + "name": "Adamant crossbow", + "ammo_slot": "13", + "weapon_type": "1", + "animation": "4230", + "drop_ammo": "true", + "ammunition": "877,878,6061,6062,879,9236,9139,9141,9288,9295,9302,9336,9239,13083,13084,13085,13086,9142,9289,9296,9303,9337,9240,9338,9241,9145,9143,9290,9297,9304,9339,9242,9340,9243,9286,9293,9300,9140,9287,9294,9301,9292,9299,9306,9335,9237,880,9238,13083,13084,13085,13086" + }, + { + "itemId": "9185", + "name": "Rune crossbow", + "ammo_slot": "13", + "weapon_type": "1", + "animation": "4230", + "drop_ammo": "true", + "ammunition": "877,878,6061,6062,879,9236,9139,9141,9288,9295,9302,9336,9239,9236,9237,9238,9239,9240,9241,9242,9243,9244,9245,9145,13083,13084,13085,13086,9142,9289,9296,9303,9337,9240,9338,9241,9143,9290,9297,9304,9339,9242,9340,9243,9144,9291,9298,9305,9341,9244,9342,9245,9140,13280,9139,9286,9293,9300,9287,9294,9301,9292,9299,9306,9335,9237,880,13083,13084,13085,13086" + }, + { + "itemId": "9705", + "name": "Training bow", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "426", + "drop_ammo": "true", + "ammunition": "9706" + }, + { + "itemId": "10033", + "name": "Chinchompa", + "ammo_slot": "3", + "weapon_type": "6", + "animation": "2779", + "drop_ammo": "0", + "ammunition": "10033" + }, + { + "itemId": "10034", + "name": "Red chinchompa", + "ammo_slot": "3", + "weapon_type": "6", + "animation": "2779", + "drop_ammo": "0", + "ammunition": "10034" + }, + { + "itemId": "10156", + "name": "Hunters\\' crossbow", + "ammo_slot": "13", + "weapon_type": "1", + "animation": "4230", + "drop_ammo": "true", + "ammunition": "10158,10159" + }, + { + "itemId": "10280", + "name": "Willow comp bow", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "426", + "drop_ammo": "true", + "ammunition": "882,883,5616,5622,598,884,885,5617,5623,2532,886,887,5618,5624,2534,888,889,5619,5625,2536" + }, + { + "itemId": "10282", + "name": "Yew comp bow", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "426", + "drop_ammo": "true", + "ammunition": "882,883,5616,5622,598,884,885,5617,5623,2532,886,887,5618,5624,2534,888,889,5619,5625,2536,890,891,5620,5626,2538,892,893,5621,5627,2540,78" + }, + { + "itemId": "10284", + "name": "Magic comp bow", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "426", + "drop_ammo": "true", + "ammunition": "882,883,5616,5622,598,884,885,5617,5623,2532,886,887,5618,5624,2534,888,889,5619,5625,2536,890,891,5620,5626,2538,892,893,5621,5627,2540,78,4160" + }, + { + "itemId": "11165", + "name": "Phoenix crossbow", + "ammo_slot": "13", + "weapon_type": "1", + "animation": "4230", + "drop_ammo": "true", + "ammunition": "877,878,6061,6062,879,9236,13280" + }, + { + "itemId": "11167", + "name": "Phoenix crossbow", + "ammo_slot": "13", + "weapon_type": "1", + "animation": "4230", + "drop_ammo": "true", + "ammunition": "877,878,6061,6062,879,9236,13280" + }, + { + "itemId": "11230", + "name": "Dragon dart", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "6600", + "drop_ammo": "true", + "ammunition": "11230" + }, + { + "itemId": "11231", + "name": "Dragon dart(p)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "6600", + "drop_ammo": "true", + "ammunition": "11231" + }, + { + "itemId": "11233", + "name": "Dragon dart(p+)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "6600", + "drop_ammo": "true", + "ammunition": "11233" + }, + { + "itemId": "11234", + "name": "Dragon dart(p++)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "6600", + "drop_ammo": "true", + "ammunition": "11234" + }, + { + "itemId": "11235", + "name": "Dark bow", + "ammo_slot": "13", + "weapon_type": "2", + "animation": "426", + "drop_ammo": "true", + "ammunition": "882,883,5616,5622,598,884,885,5617,5623,2532,886,887,5618,5624,2534,888,889,5619,5625,2536,890,891,5620,5626,2538,892,893,5621,5627,2540,11212,11227,11228,11229,11217,78,4160" + }, + { + "itemId": "13081", + "name": "Black crossbow", + "ammo_slot": "13", + "weapon_type": "1", + "animation": "4230", + "drop_ammo": "true", + "ammunition": "877,878,6061,6062,879,9139,9140,9236,9141,9288,9295,9302,9336,9239,9145,9286,9293,9300,9287,9294,9301,9292,9299,9306,9335,9237,880,9238,13083,13084,13085,13086" + }, + { + "itemId": "13405", + "name": "Dark bow", + "ammo_slot": "13", + "weapon_type": "2", + "animation": "426", + "drop_ammo": "true", + "ammunition": "882,883,5616,5622,598,884,885,5617,5623,2532,886,887,5618,5624,2534,888,889,5619,5625,2536,890,891,5620,5626,2538,892,893,5621,5627,2540,11212,11227,11228,11229,11217,78,4160" + }, + { + "itemId": "13523", + "name": "Maple longbow", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "426", + "drop_ammo": "true", + "ammunition": "882,883,5616,5622,598,884,885,5617,5623,2532,886,887,5618,5624,2534,888,889,5619,5625,2536,890,891,5620,5626,2538" + }, + { + "itemId": "13524", + "name": "Maple shortbow", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "426", + "drop_ammo": "true", + "ammunition": "882,883,5616,5622,598,884,885,5617,5623,2532,886,887,5618,5624,2534,888,889,5619,5625,2536,890,891,5620,5626,2538" + }, + { + "itemId": "13525", + "name": "Yew longbow", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "426", + "drop_ammo": "true", + "ammunition": "882,883,5616,5622,598,884,885,5617,5623,2532,886,887,5618,5624,2534,888,889,5619,5625,2536,890,891,5620,5626,2538,892,893,5621,5627,2540,78" + }, + { + "itemId": "13526", + "name": "Yew shortbow", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "426", + "drop_ammo": "true", + "ammunition": "882,883,5616,5622,598,884,885,5617,5623,2532,886,887,5618,5624,2534,888,889,5619,5625,2536,890,891,5620,5626,2538,892,893,5621,5627,2540,78" + }, + { + "itemId": "13527", + "name": "Magic longbow", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "426", + "drop_ammo": "true", + "ammunition": "882,883,5616,5622,598,884,885,5617,5623,2532,886,887,5618,5624,2534,888,889,5619,5625,2536,890,891,5620,5626,2538,892,893,5621,5627,2540,78,4160" + }, + { + "itemId": "13528", + "name": "Magic shortbow", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "426", + "drop_ammo": "true", + "ammunition": "882,883,5616,5622,598,884,885,5617,5623,2532,886,887,5618,5624,2534,888,889,5619,5625,2536,890,891,5620,5626,2538,892,893,5621,5627,2540,78,4160" + }, + { + "itemId": "13529", + "name": "Seercull", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "426", + "drop_ammo": "true", + "ammunition": "882,883,5616,5622,598,884,885,5617,5623,2532,886,887,5618,5624,2534,888,889,5619,5625,2536,890,891,5620,5626,2538,892,893,5621,5627,2540,78,4160" + }, + { + "itemId": "13530", + "name": "Rune crossbow", + "ammo_slot": "13", + "weapon_type": "1", + "animation": "4230", + "drop_ammo": "true", + "ammunition": "877,878,6061,6062,879,9236,9237,9238,9239,9240,9241,9242,9243,9244,9245,9141,9288,9295,9302,9336,9239,13083,13084,13085,13086,9142,9289,9296,9303,9337,9240,9338,9241,9143,9290,9297,9304,9339,9242,9340,9243,9144,9291,9298,9305,9341,9244,9342,9245,13280" + }, + { + "itemId": "13541", + "name": "Willow comp bow", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "426", + "drop_ammo": "true", + "ammunition": "882,883,5616,5622,598,884,885,5617,5623,2532,886,887,5618,5624,2534,888,889,5619,5625,2536" + }, + { + "itemId": "13542", + "name": "Yew comp bow", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "426", + "drop_ammo": "true", + "ammunition": "882,883,5616,5622,598,884,885,5617,5623,2532,886,887,5618,5624,2534,888,889,5619,5625,2536,890,891,5620,5626,2538,892,893,5621,5627,2540,78" + }, + { + "itemId": "13543", + "name": "Magic comp bow", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "426", + "drop_ammo": "true", + "ammunition": "882,883,5616,5622,598,884,885,5617,5623,2532,886,887,5618,5624,2534,888,889,5619,5625,2536,890,891,5620,5626,2538,892,893,5621,5627,2540,78,4160" + }, + { + "itemId": "13879", + "name": "Morrigan\\'s javelin", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "10501", + "drop_ammo": "true", + "ammunition": "13879" + }, + { + "itemId": "13880", + "name": "Morrigan\\'s javelin(p)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "10501", + "drop_ammo": "true", + "ammunition": "13880" + }, + { + "itemId": "13881", + "name": "Morrigan\\'s javelin(p+)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "10501", + "drop_ammo": "true", + "ammunition": "13881" + }, + { + "itemId": "13882", + "name": "Morrigan\\'s javelin(p++)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "10501", + "drop_ammo": "true", + "ammunition": "13882" + }, + { + "itemId": "13883", + "name": "Morrigan\\'s throwing axe", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "10504", + "drop_ammo": "true", + "ammunition": "13883" + }, + { + "itemId": "13953", + "name": "Corrupt morrigan\\'s javelin", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "10501", + "drop_ammo": "true", + "ammunition": "13953" + }, + { + "itemId": "13954", + "name": "C. morrigan\\'s javelin (p)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "10501", + "drop_ammo": "true", + "ammunition": "13954" + }, + { + "itemId": "13955", + "name": "C. morrigan\\'s javelin (p+)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "10501", + "drop_ammo": "true", + "ammunition": "13955" + }, + { + "itemId": "13956", + "name": "C. morrigan\\'s javelin (p++)", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "10501", + "drop_ammo": "true", + "ammunition": "13956" + }, + { + "itemId": "13957", + "name": "C. morrigan\\'s throwing axe", + "ammo_slot": "3", + "weapon_type": "3", + "animation": "10504", + "drop_ammo": "true", + "ammunition": "13957" + }, + { + "itemId": "14121", + "name": "Sacred clay bow", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "426", + "drop_ammo": "true", + "ammunition": "882,883,5616,5622,598,884,885,5617,5623,2532,886,887,5618,5624,2534,888,889,5619,5625,2536,890,891,5620,5626,2538,892,893,5621,5627,2540,78,4160" + }, + { + "itemId": "14192", + "name": "Bow (class 1)", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "426", + "drop_ammo": "true", + "ammunition": "14202,14203,14204,14205,14206" + }, + { + "itemId": "14194", + "name": "Bow (class 2)", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "426", + "drop_ammo": "true", + "ammunition": "14202,14203,14204,14205,14206" + }, + { + "itemId": "14196", + "name": "Bow (class 3)", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "426", + "drop_ammo": "true", + "ammunition": "14202,14203,14204,14205,14206" + }, + { + "itemId": "14198", + "name": "Bow (class 4)", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "426", + "drop_ammo": "true", + "ammunition": "14202,14203,14204,14205,14206" + }, + { + "itemId": "14200", + "name": "Bow (class 5)", + "ammo_slot": "13", + "weapon_type": "0", + "animation": "426", + "drop_ammo": "true", + "ammunition": "14202,14203,14204,14205,14206" + } +] diff --git a/Server/data/configs/shared_tables/ASDT.xml b/Server/data/configs/shared_tables/ASDT.xml new file mode 100644 index 0000000..bc11f62 --- /dev/null +++ b/Server/data/configs/shared_tables/ASDT.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/Server/data/configs/shared_tables/CELEDT.xml b/Server/data/configs/shared_tables/CELEDT.xml new file mode 100644 index 0000000..e7d8bc5 --- /dev/null +++ b/Server/data/configs/shared_tables/CELEDT.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/Server/data/configs/shared_tables/GDT.xml b/Server/data/configs/shared_tables/GDT.xml new file mode 100644 index 0000000..e10dd5b --- /dev/null +++ b/Server/data/configs/shared_tables/GDT.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/Server/data/configs/shared_tables/HDT.xml b/Server/data/configs/shared_tables/HDT.xml new file mode 100644 index 0000000..d8f0223 --- /dev/null +++ b/Server/data/configs/shared_tables/HDT.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/Server/data/configs/shared_tables/RDT.xml b/Server/data/configs/shared_tables/RDT.xml new file mode 100644 index 0000000..78ed522 --- /dev/null +++ b/Server/data/configs/shared_tables/RDT.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Server/data/configs/shared_tables/RSDT.xml b/Server/data/configs/shared_tables/RSDT.xml new file mode 100644 index 0000000..58bf5ad --- /dev/null +++ b/Server/data/configs/shared_tables/RSDT.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Server/data/configs/shared_tables/USDT.xml b/Server/data/configs/shared_tables/USDT.xml new file mode 100644 index 0000000..105e742 --- /dev/null +++ b/Server/data/configs/shared_tables/USDT.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Server/data/configs/shops.json b/Server/data/configs/shops.json new file mode 100644 index 0000000..a84aedd --- /dev/null +++ b/Server/data/configs/shops.json @@ -0,0 +1,2199 @@ +[ + { + "npcs": "5198,5199", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "1", + "title": "Ava's Odds and Ends", + "stock": "{314,1000,100}-{884,40,100}-{886,10,100}-{40,30,100}-{41,20,100}" + }, + { + "npcs": "528,529", + "high_alch": "0", + "currency": "995", + "general_store": "true", + "id": "2", + "title": "Edgeville General Store", + "stock": "{1931,30,100}-{1935,30,100}-{1735,10,100}-{1925,10,100}-{1923,10,100}-{1887,10,100}-{590,10,100}-{1755,10,100}-{2347,10,100}-{550,10,100}-{9003,10,100}" + }, + { + "npcs": "525,524", + "high_alch": "0", + "currency": "995", + "general_store": "true", + "id": "3", + "title": "Al Kharid General Store", + "stock": "{1931,30,100}-{1935,30,100}-{1735,10,100}-{1925,10,100}-{1923,10,100}-{1887,10,100}-{590,10,100}-{1755,10,100}-{2347,10,100}-{550,10,100}-{9003,10,100}" + }, + { + "npcs": "3799", + "high_alch": "0", + "currency": "995", + "general_store": "true", + "id": "4", + "title": "Void Knight General Store", + "stock": "{1931,30,100}-{1935,30,100}-{1735,10,100}-{1925,10,100}-{1923,10,100}-{1887,10,100}-{590,10,100}-{1755,10,100}-{2347,10,100}-{550,10,100}-{9003,10,100}-{7934,25,100}" + }, + { + "npcs": "1436", + "high_alch": "0", + "currency": "995", + "general_store": "true", + "id": "5", + "title": "Ifaba's General Store", + "stock": "{1931,30,100}-{1935,30,100}-{1735,10,100}-{1925,10,100}-{1923,10,100}-{1887,10,100}-{590,10,100}-{1755,10,100}-{2347,10,100}-{550,10,100}-{9003,10,100}" + }, + { + "npcs": "590,591", + "high_alch": "0", + "currency": "995", + "general_store": "true", + "id": "6", + "title": "Aemad's Adventuring Supplies", + "stock": "{227,10,100}-{1265,10,100}-{1349,10,100}-{2142,10,100}-{590,10,100}-{1759,100,100}-{882,1000,100}-{954,10,100}-{970,10,100}-{946,10,100}-{1935,10,100}" + }, + { + "npcs": "971", + "high_alch": "0", + "currency": "995", + "general_store": "true", + "id": "8", + "title": "West Ardougne General Store", + "stock": "{1931,10,100}-{954,10,100}-{1265,10,100}-{1925,30,100}-{590,10,100}-{2347,10,100}-{1061,10,100}-{841,10,100}-{882,100,100}-{329,10,100}-{2327,10,100}-{2309,10,100}-{2142,10,100}" + }, + { + "npcs": "1917", + "high_alch": "0", + "currency": "995", + "general_store": "true", + "id": "9", + "title": "Bandit Bargains", + "stock": "{1823,5,100}-{1831,5,100}-{1937,5,100}-{1921,5,100}-{1929,5,100}-{1935,5,100}-{1923,5,100}-{1925,5,100}-{1837,5,100}-{1833,5,100}-{1835,5,100}-{946,5,100}" + }, + { + "npcs": "597", + "high_alch": "1", + "currency": "995", + "general_store": "true", + "id": "10", + "title": "Bandit Duty Free", + "stock": "{1931,30,100}-{1935,30,100}-{1735,10,100}-{1925,10,100}-{1923,10,100}-{1887,10,100}-{590,10,100}-{1755,10,100}-{2347,10,100}-{550,10,100}-{9003,10,100}" + }, + { + "npcs": "1083", + "high_alch": "0", + "currency": "995", + "general_store": "true", + "id": "11", + "title": "Burthorpe Supplies", + "stock": "{1931,30,100}-{1935,30,100}-{1735,10,100}-{1925,10,100}-{1923,10,100}-{1887,10,100}-{590,10,100}-{1755,10,100}-{2347,10,100}-{550,10,100}-{9003,10,100}" + }, + { + "npcs": "3541,7396", + "high_alch": "0", + "currency": "995", + "general_store": "true", + "id": "12", + "title": "Aurel's Supplies", + "stock": "{1931,30,100}-{1935,30,100}-{1735,10,100}-{1925,10,100}-{1923,10,100}-{1887,10,100}-{590,10,100}-{1755,10,100}-{2347,10,100}-{550,10,100}-{9003,10,100}" + }, + { + "npcs": "1040", + "high_alch": "0", + "currency": "995", + "general_store": "true", + "id": "13", + "title": "General Store (Canifis)", + "stock": "{1931,30,100}-{1935,30,100}-{1735,10,100}-{1925,10,100}-{1923,10,100}-{1887,10,100}-{590,10,100}-{1755,10,100}-{2347,10,100}-{550,10,100}-{9003,10,100}-{3377,10,100}" + }, + { + "npcs": "563", + "high_alch": "0", + "currency": "995", + "general_store": "true", + "id": "14", + "title": "Arhein's Store", + "stock": "{1931,30,100}-{1935,30,100}-{1735,10,100}-{1925,10,100}-{1923,10,100}-{1887,10,100}-{590,10,100}-{1755,10,100}-{2347,10,100}-{550,10,100}-{9003,10,100}" + }, + { + "npcs": "5798", + "high_alch": "0", + "currency": "995", + "general_store": "true", + "id": "15", + "title": "Dorgesh-Kaan General Supplies", + "stock": "{1931,30,100}-{1935,30,100}-{1735,10,100}-{1925,10,100}-{1923,10,100}-{1887,10,100}-{590,10,100}-{1755,10,100}-{2347,10,100}-{550,10,100}-{9003,10,100}" + }, + { + "npcs": "582", + "high_alch": "0", + "currency": "995", + "general_store": "true", + "id": "16", + "title": "Dwarven Shopping Store", + "stock": "{1931,30,100}-{1935,30,100}-{1735,10,100}-{1925,10,100}-{1923,10,100}-{1887,10,100}-{590,10,100}-{1755,10,100}-{2347,10,100}-{550,10,100}-{9003,10,100}" + }, + { + "npcs": "526,527", + "high_alch": "0", + "currency": "995", + "general_store": "true", + "id": "17", + "title": "Falador General Store", + "stock": "{1931,30,100}-{1935,30,100}-{1735,10,100}-{1925,10,100}-{1923,10,100}-{1887,10,100}-{590,10,100}-{1755,10,100}-{2347,10,100}-{550,10,100}-{9003,10,100}" + }, + { + "npcs": "873", + "high_alch": "0", + "currency": "995", + "general_store": "true", + "id": "18", + "title": "Dal's General Ogre Supplies", + "stock": "{1931,30,100}-{1935,30,100}-{1735,10,100}-{1925,10,100}-{1923,10,100}-{1887,10,100}-{590,10,100}-{1755,10,100}-{2347,10,100}-{550,10,100}-{9003,10,100}" + }, + { + "npcs": "532,533", + "high_alch": "0", + "currency": "995", + "general_store": "true", + "id": "19", + "title": "Karamja General Store", + "stock": "{1931,30,100}-{1935,30,100}-{1735,10,100}-{1925,10,100}-{1923,10,100}-{1887,10,100}-{590,10,100}-{1755,10,100}-{2347,10,100}-{550,10,100}-{9003,10,100}" + }, + { + "npcs": "568", + "high_alch": "0", + "currency": "995", + "general_store": "true", + "id": "20", + "title": "Karamja Wines, Spirits, and Beers", + "stock": "{1917,3,100}-{431,3,100}-{1993,1,100}" + }, + { + "npcs": "2154", + "high_alch": "0", + "currency": "995", + "general_store": "true", + "id": "21", + "title": "Gunslik's Assorted Items", + "stock": "{1931,30,100}-{1935,30,100}-{1735,10,100}-{1925,10,100}-{1923,10,100}-{1887,10,100}-{590,10,100}-{1755,10,100}-{2347,10,100}-{550,10,100}-{9003,10,100}" + }, + { + "npcs": "1334", + "high_alch": "0", + "currency": "995", + "general_store": "true", + "id": "22", + "title": "The Lighthouse Store", + "stock": "{1931,30,100}-{1935,30,100}-{1735,10,100}-{1925,10,100}-{1923,10,100}-{1887,10,100}-{590,10,100}-{1755,10,100}-{2347,10,100}-{550,10,100}-{9003,10,100}" + }, + { + "npcs": "2352", + "high_alch": "0", + "currency": "995", + "general_store": "true", + "id": "23", + "title": "Lletya General Store", + "stock": "{1931,10,100}-{954,10,100}-{1265,10,100}-{1925,30,100}-{590,10,100}-{2347,10,100}-{1061,10,100}-{841,10,100}-{882,100,100}-{329,10,100}-{2327,10,100}-{2309,10,100}-{2142,10,100}" + }, + { + "npcs": "4516", + "high_alch": "0", + "currency": "995", + "general_store": "true", + "id": "24", + "title": "Moon Clan General Store", + "stock": "{1931,30,100}-{1935,10,100}-{1735,10,100}-{1925,30,100}-{1923,10,100}-{1887,10,100}-{590,10,100}-{1755,10,100}-{2347,10,100}-{9003,10,100}-{229,1000,100}" + }, + { + "npcs": "520,521", + "high_alch": "0", + "currency": "995", + "general_store": "true", + "id": "25", + "title": "Lumbridge General Store", + "stock": "{1931,30,100}-{1935,30,100}-{1735,10,100}-{1925,10,100}-{1923,10,100}-{1887,10,100}-{590,10,100}-{1755,10,100}-{2347,10,100}-{550,10,100}-{9003,10,100}" + }, + { + "npcs": "4716", + "high_alch": "0", + "currency": "995", + "general_store": "true", + "id": "26", + "title": "Trader Sven's Black Market Goods", + "stock": "{1931,30,100}-{1935,30,100}-{1735,10,100}-{1925,10,100}-{1923,10,100}-{1887,10,100}-{590,10,100}-{1755,10,100}-{2347,10,100}-{550,10,100}-{9003,10,100}" + }, + { + "npcs": "3922", + "high_alch": "0", + "currency": "995", + "general_store": "true", + "id": "27", + "title": "Miscellanian General Store", + "stock": "{1931,30,100}-{1935,30,100}-{1735,10,100}-{1925,10,100}-{1923,10,100}-{1887,10,100}-{590,10,100}-{1755,10,100}-{2347,10,100}-{550,10,100}-{9003,10,100}" + }, + { + "npcs": "1254", + "high_alch": "0", + "currency": "995", + "general_store": "true", + "id": "28", + "title": "Razmire General Store", + "stock": "{1931,30,100}-{1935,30,100}-{1735,10,100}-{1925,10,100}-{1923,10,100}-{1887,10,100}-{590,10,100}-{1755,10,100}-{2347,10,100}-{550,10,100}-{9003,10,100}" + }, + { + "npcs": "3039", + "high_alch": "0", + "currency": "995", + "general_store": "true", + "id": "29", + "title": "Nardah General Store", + "stock": "{1931,30,100}-{1935,30,100}-{1735,10,100}-{1925,10,100}-{1923,10,100}-{1887,10,100}-{590,10,100}-{1755,10,100}-{2347,10,100}-{550,10,100}-{9003,10,100}" + }, + { + "npcs": "3824", + "high_alch": "0", + "currency": "995", + "general_store": "true", + "id": "30", + "title": "Arnold's Eclectic Supplies", + "stock": "{303,10,100}-{311,10,100}-{7944,0,100}-{7946,0,100}-{2309,10,100}-{1931,30,100}-{1927,10,100}-{1733,10,100}-{1734,1000,100}-{1755,10,100}-{1917,10,100}-{1785,10,100}-{946,10,100}" + }, + { + "npcs": "1866", + "high_alch": "0", + "currency": "995", + "general_store": "true", + "id": "31", + "title": "Pollnivneach General Store", + "stock": "{1931,30,100}-{1935,30,100}-{1735,10,100}-{1925,10,100}-{1923,10,100}-{1887,10,100}-{590,10,100}-{1755,10,100}-{2347,10,100}-{550,10,100}-{9003,10,100}" + }, + { + "npcs": "1699", + "high_alch": "0", + "currency": "995", + "general_store": "true", + "id": "33", + "title": "Port Phasmatys General Store", + "stock": "{1931,30,100}-{1935,30,100}-{1735,10,100}-{1925,10,100}-{1923,10,100}-{1887,10,100}-{590,10,100}-{1755,10,100}-{2347,10,100}-{550,10,100}-{9003,10,100}" + }, + { + "npcs": "530,531", + "high_alch": "0", + "currency": "995", + "general_store": "true", + "id": "34", + "title": "Rimmington General Store", + "stock": "{1931,30,100}-{1935,30,100}-{1735,10,100}-{1925,10,100}-{1923,10,100}-{1887,10,100}-{590,10,100}-{1755,10,100}-{2347,10,100}-{550,10,100}-{9003,10,100}" + }, + { + "npcs": "836", + "high_alch": "0", + "currency": "995", + "general_store": "true", + "id": "35", + "title": "Shantay Pass Shop", + "stock": "{1823,30,100}-{1831,30,100}-{1937,10,100}-{1921,10,100}-{1929,10,100}-{946,10,100}-{1833,10,100}-{1835,10,100}-{1837,10,100}-{2349,0,100}-{314,1000,100}-{2347,10,100}-{1925,30,100}-{1923,10,100}-{1935,10,100}-{1854,300,100}-{954,100,100}" + }, + { + "npcs": "516", + "high_alch": "0", + "currency": "995", + "general_store": "true", + "id": "36", + "title": "Obli's General Store", + "stock": "{590,10,100}-{229,1000,100}-{233,10,100}-{1931,30,100}-{1351,10,100}-{1265,10,100}-{1349,10,100}-{1129,10,100}-{1059,10,100}-{1061,10,100}-{2142,10,100}-{2309,10,100}-{952,10,100}-{36,10,100}-{596,10,100}-{1755,10,100}-{2347,10,100}-{970,10,100}-{973,10,100}-{227,1000,100}-{975,10,100}-{954,10,100}" + }, + { + "npcs": "560", + "high_alch": "0", + "currency": "995", + "general_store": "true", + "id": "37", + "title": "Jiminua's Jungle Store", + "stock": "{590,10,100}-{36,10,100}-{596,10,100}-{1931,30,100}-{954,10,100}-{1129,10,100}-{1059,10,100}-{1061,10,100}-{2142,10,100}-{2309,10,100}-{227,300,100}-{233,10,100}-{175,10,100}-{970,10,100}-{973,10,100}-{946,10,100}-{2347,10,100}-{975,10,100}-{1755,10,100}-{952,10,100}-{1351,10,100}-{1265,10,100}-{1349,10,100}-{229,300,100}" + }, + { + "npcs": "471", + "high_alch": "0", + "currency": "995", + "general_store": "true", + "id": "38", + "title": "Bolkoy's Village Shop", + "stock": "{1931,30,100}-{1935,30,100}-{1735,10,100}-{1925,10,100}-{1923,10,100}-{1887,10,100}-{590,10,100}-{1755,10,100}-{2347,10,100}-{550,10,100}-{9003,10,100}" + }, + { + "npcs": "1208", + "high_alch": "0", + "currency": "995", + "general_store": "true", + "id": "39", + "title": "Quartermaster's Stores", + "stock": "{1931,30,100}-{1935,10,100}-{1735,10,100}-{590,10,100}-{2309,10,100}-{3190,10,100}-{3192,10,100}-{3194,10,100}-{3196,10,100}-{3198,10,100}-{3200,10,100}-{3202,10,100}-{3204,10,100}" + }, + { + "npcs": "522,523", + "high_alch": "0", + "currency": "995", + "general_store": "true", + "id": "40", + "title": "Varrock General Store", + "stock": "{1931,30,100}-{1935,30,100}-{1735,10,100}-{1925,10,100}-{1923,10,100}-{1887,10,100}-{590,10,100}-{1755,10,100}-{2347,10,100}-{550,10,100}-{9003,10,100}" + }, + { + "npcs": "4651,4652,4653,4654,4655,4656,4650", + "high_alch": "0", + "currency": "995", + "general_store": "true", + "id": "41", + "title": "Trader Stan's Trading Post", + "stock": "{1931,30,100}-{1935,10,100}-{1735,10,100}-{1925,30,100}-{1923,10,100}-{1887,10,100}-{590,10,100}-{1755,10,100}-{2347,10,100}-{550,10,100}-{9003,10,100}-{954,10,100}-{946,10,100}-{2114,0,100}-{1963,10,100}-{2108,0,100}-{1785,10,100}-{1783,0,100}-{401,0,100}-{1781,0,100}-{301,10,100}-{307,10,100}-{1941,10,100}-{9629,10,100}-{3226,10,100}-{1025,10,100}" + }, + { + "npcs": "534,535", + "high_alch": "0", + "currency": "995", + "general_store": "true", + "id": "42", + "title": "Zanaris General Store", + "stock": "{1931,30,100}-{1935,30,100}-{1735,10,100}-{1925,10,100}-{1923,10,100}-{1887,10,100}-{590,10,100}-{1755,10,100}-{2347,10,100}-{550,10,100}-{9003,10,100}" + }, + { + "npcs": "588", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "43", + "title": "Davon's Amulet Store", + "stock": "{1718,0,100}-{1727,0,100}-{1729,0,100}-{1725,0,100}-{1731,0,100}" + }, + { + "npcs": "2356", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "44", + "title": "Lletya Archery Shop", + "stock": "{884,1000,100}-{886,300,100}-{888,100,100}-{890,100,100}-{892,30,100}-{877,1000,100}-{843,10,100}-{837,10,100}-{849,10,100}" + }, + { + "npcs": "3796", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "45", + "title": "Void Knight Archery Store", + "stock": "{825,300,100}-{826,300,100}-{827,100,100}-{828,100,100}-{829,250,100}-{830,10,100}-{39,100,100}-{40,100,100}-{41,100,100}-{42,30,100}-{43,30,100}-{44,10,100}" + }, + { + "npcs": "1860", + "high_alch": "1", + "currency": "995", + "general_store": "false", + "id": "46", + "title": "Brian's Archery Supplies", + "stock": "{886,100,100}-{888,30,100}-{890,0,100}-{843,10,100}-{845,10,100}-{849,10,100}-{847,10,100}-{853,10,100}-{851,10,100}" + }, + { + "npcs": "550", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "47", + "title": "Lowe's Archery Emporium", + "stock": "{882,1000,100}-{884,100,100}-{886,100,100}-{888,100,100}-{890,30,100}-{877,300,100}-{841,10,100}-{843,10,100}-{849,10,100}-{853,10,100}-{837,10,100}-{839,10,100}-{845,10,100}-{847,10,100}-{851,10,100}" + }, + { + "npcs": "575", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "48", + "title": "Hickton's Archery Emporium", + "stock": "{877,300,100}-{882,1000,100}-{884,100,100}-{886,0,100}-{888,0,100}-{890,0,100}-{892,0,100}-{4773,0,100}-{4778,0,100}-{4783,0,100}-{4788,0,100}-{4793,0,100}-{4798,0,100}-{4803,0,100}-{841,10,100}-{837,10,100}-{843,10,100}-{4827,10,100}-{1133,10,100}-{1097,10,100}" + }, + { + "npcs": "683", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "49", + "title": "Dargaud's Bows And Arrows", + "stock": "{52,1000,100}-{39,1000,100}-{40,300,100}-{41,300,100}-{42,100,100}-{43,100,100}-{44,100,100}-{882,1000,100}-{884,300,100}-{886,300,100}-{888,100,100}-{890,100,100}-{892,100,100}-{4773,0,100}-{4778,0,100}-{4783,0,100}-{4788,0,100}-{4793,0,100}-{4798,0,100}-{4803,0,100}-{841,10,100}-{843,10,100}-{849,10,100}-{839,20,100}-{845,20,100}-{847,20,100}-{4827,10,100}" + }, + { + "npcs": "682", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "50", + "title": "Aaron's Archery Appendages", + "stock": "{1129,10,100}-{1131,10,100}-{1133,10,100}-{1095,10,100}-{1097,10,100}-{1169,10,100}-{1167,10,100}-{1063,10,100}" + }, + { + "npcs": "4563", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "51", + "title": "Crossbow Shop (dwarven Mine)", + "stock": "{9440,10,100}-{9442,10,100}-{9444,10,100}-{9446,10,100}-{9448,10,100}-{9450,10,100}-{9452,0,100}-{9420,10,100}-{9423,10,100}-{9425,10,100}-{9427,10,100}-{9429,10,100}-{9431,0,100}" + }, + { + "npcs": "4558", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "52", + "title": "Crossbow Shop (keldagrim)", + "stock": "{9440,10,100}-{9442,10,100}-{9444,10,100}-{9446,10,100}-{9448,10,100}-{9450,10,100}-{9452,0,100}-{9420,10,100}-{9423,10,100}-{9425,10,100}-{9427,10,100}-{9429,10,100}-{9431,0,100}" + }, + { + "npcs": "4559", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "53", + "title": "Crossbow Shop (white Wolf Mountain)", + "stock": "{9440,10,100}-{9442,10,100}-{9444,10,100}-{9446,10,100}-{9448,10,100}-{9450,10,100}-{9452,0,100}-{9420,10,100}-{9423,10,100}-{9425,10,100}-{9427,10,100}-{9429,10,100}-{9431,0,100}" + }, + { + "npcs": "519", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "54", + "title": "Bob's Brilliant Axes", + "stock": "{1265,10,100}-{1351,10,100}-{1349,10,100}-{1353,10,100}-{1363,10,100}-{1365,10,100}-{1369,10,100}" + }, + { + "npcs": "559", + "high_alch": "1", + "currency": "995", + "general_store": "false", + "id": "55", + "title": "Brian's Battleaxe Bazaar", + "stock": "{1375,4,100}-{1363,3,100}-{1365,2,100}-{1367,1,100}-{1369,1,100}-{1371,1,100}" + }, + { + "npcs": "562", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "56", + "title": "Candle Shop", + "stock": "{36,10,100}-{38,10,100}" + }, + { + "npcs": "562", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "57", + "title": "Candle Shop", + "stock": "{36,10,100}" + }, + { + "npcs": "581", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "58", + "title": "Wayne's Chains", + "stock": "{1103,3,100}-{1101,2,100}-{1105,1,100}-{1107,1,100}-{1109,1,100}-{1111,1,100}" + }, + { + "npcs": "554", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "59", + "title": "Fancy Clothes Store", + "stock": "{1949,0,100}-{579,10,100}-{1023,10,100}-{958,10,100}-{948,10,100}-{1733,10,100}-{1734,1000,100}-{1059,30,100}-{1061,10,100}-{428,10,100}-{426,10,100}-{1757,10,100}-{1013,10,100}-{1015,10,100}-{1011,10,100}-{1007,10,100}-{1025,10,100}-{10088,0,100}-{10090,0,100}-{10091,0,100}-{10089,0,100}-{10087,0,100}-{11525,0,100}" + }, + { + "npcs": "548", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "60", + "title": "Thessalia's Fine Clothes", + "stock": "{1005,10,100}-{1129,10,100}-{1059,10,100}-{1061,10,100}-{1757,10,100}-{1013,10,100}-{1015,10,100}-{1011,10,100}-{1007,10,100}-{950,10,100}-{426,10,100}-{428,10,100}" + }, + { + "npcs": "601", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "61", + "title": "Fine Fashions", + "stock": "{646,5,100}-{648,5,100}-{650,5,100}-{652,5,100}-{654,5,100}-{656,5,100}-{658,5,100}-{660,5,100}-{662,5,100}-{664,5,100}-{636,5,100}-{638,5,100}-{640,5,100}-{642,5,100}-{644,5,100}-{626,5,100}-{628,5,100}-{630,30,100}-{632,30,100}-{634,30,100}" + }, + { + "npcs": "1301", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "62", + "title": "Yrsa's Accoutrements", + "stock": "{3775,10,100}-{3773,10,100}-{3767,10,100}-{3769,10,100}-{3771,10,100}-{3793,10,100}-{3795,10,100}-{3797,10,100}-{3791,10,100}-{3799,10,100}-{3759,10,100}-{3761,10,100}-{3765,10,100}-{3763,10,100}-{3777,10,100}-{3779,10,100}-{3781,10,100}-{3783,10,100}-{3785,10,100}-{3787,10,100}-{3789,10,100}" + }, + { + "npcs": "1039", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "63", + "title": "Barker's Haberdashery", + "stock": "{2894,5,100}-{2896,5,100}-{2898,5,100}-{2900,5,100}-{2902,5,100}-{2904,5,100}-{2906,5,100}-{2908,5,100}-{2910,5,100}-{2912,5,100}-{2914,5,100}-{2916,5,100}-{2918,5,100}-{2920,5,100}-{2922,5,100}-{2924,5,100}-{2926,5,100}-{2928,5,100}-{2930,5,100}-{2932,5,100}-{2934,5,100}-{2936,5,100}-{2938,5,100}-{2940,5,100}-{2942,5,100}-{1007,5,100}-{1023,5,100}-{1019,5,100}-{1021,5,100}-{1027,5,100}" + }, + { + "npcs": "2353", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "64", + "title": "Lletya Seamstress", + "stock": "{1734,1000,100}-{1733,10,100}-{1759,100,100}-{1763,10,100}-{1765,10,100}-{1767,10,100}-{1769,10,100}-{1771,10,100}-{1773,10,100}" + }, + { + "npcs": "3166", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "65", + "title": "Dodgy Mikes Second-hand Clothing", + "stock": "{7114,10,100}-{7122,10,100}-{7128,10,100}-{7134,10,100}-{7110,10,100}-{7126,10,100}-{7132,10,100}-{7138,10,100}-{7116,10,100}-{7124,10,100}-{7130,10,100}-{7112,10,100}-{7136,10,100}" + }, + { + "npcs": "2161", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "66", + "title": "Agmundi Quality Clothes", + "stock": "" + }, + { + "npcs": "2162", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "67", + "title": "Vermundi's Clothes Stall", + "stock": "{950,10,100}" + }, + { + "npcs": "600", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "68", + "title": "Grand Tree Groceries", + "stock": "{2171,10,100}-{2128,10,100}-{1933,10,100}-{2169,10,100}-{1957,10,100}-{1942,10,100}-{1965,10,100}-{1982,10,100}-{1985,10,100}-{2120,10,100}-{2108,10,100}-{2102,10,100}-{2114,10,100}-{2126,10,100}-{2025,10,100}-{1973,10,100}-{1975,10,100}-{2130,10,100}-{1927,10,100}-{946,10,100}-{2167,10,100}-{2164,10,100}-{2165,10,100}-{2166,10,100}" + }, + { + "npcs": "593", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "69", + "title": "Frenita's Cookery Shop.", + "stock": "{2313,5,100}-{1955,2,100}-{1887,2,100}-{1923,2,100}-{1942,5,100}-{590,4,100}-{1935,1,100}-{1931,8,100}-{1973,2,100}-{1933,8,100}-{1980,20,100}" + }, + { + "npcs": "545", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "70", + "title": "Dommik's Crafting Store", + "stock": "{1755,10,100}-{1592,10,100}-{1597,10,100}-{1595,10,100}-{1733,10,100}-{1734,1000,100}-{1599,10,100}-{2976,10,100}-{5523,10,100}-{9434,10,100}-{11065,10,100}" + }, + { + "npcs": "585", + "high_alch": "1", + "currency": "995", + "general_store": "false", + "id": "71", + "title": "Rommik's Crafty Supplies", + "stock": "{1755,10,100}-{1592,10,100}-{1597,10,100}-{1595,10,100}-{1733,10,100}-{1734,1000,100}-{1599,10,100}-{2976,10,100}-{5523,10,100}-{9434,10,100}-{11065,10,100}" + }, + { + "npcs": "5268", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "72", + "title": "Jamila's Craft Stall", + "stock": "{1755,10,100}-{1592,10,100}-{1597,10,100}-{1595,10,100}-{1733,10,100}-{1734,1000,100}-{1599,10,100}-{2976,10,100}-{5523,10,100}-{11065,10,100}" + }, + { + "npcs": "2305", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "73", + "title": "Vanessa's Farming Shop", + "stock": "{5376,10,100}-{6032,300,100}-{5418,10,100}-{6036,10,100}-{5350,100,100}-{5341,10,100}-{5329,10,100}-{5343,10,100}-{952,10,100}-{5325,10,100}-{1925,100,100}-{5331,30,100}-{12622,10,100}-{5996,0,100}-{6006,0,100}-{1965,0,100}-{5994,0,100}-{5931,0,100}-{6000,0,100}-{1957,0,100}-{5504,0,100}-{5986,0,100}-{1982,0,100}-{5982,0,100}-{6002,0,100}-{5998,0,100}" + }, + { + "npcs": "2307", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "74", + "title": "Alice's Farming Shop", + "stock": "{5376,10,100}-{6032,300,100}-{5418,10,100}-{6036,10,100}-{5350,100,100}-{5341,10,100}-{5329,10,100}-{5343,10,100}-{952,10,100}-{5325,10,100}-{1925,100,100}-{5331,30,100}-{12622,10,100}-{5996,0,100}-{6006,0,100}-{1965,0,100}-{5994,0,100}-{5931,0,100}-{6000,0,100}-{1957,0,100}-{5504,0,100}-{5986,0,100}-{1982,0,100}-{5982,0,100}-{6002,0,100}-{5998,0,100}" + }, + { + "npcs": "2304", + "high_alch": "1", + "currency": "995", + "general_store": "false", + "id": "75", + "title": "Sarah's Farming Shop", + "stock": "{5376,10,100}-{6032,300,100}-{5418,10,100}-{6036,10,100}-{5350,100,100}-{5341,10,100}-{5329,10,100}-{5343,10,100}-{952,10,100}-{5325,10,100}-{1925,100,100}-{5331,30,100}-{12622,10,100}-{5996,0,100}-{6006,0,100}-{1965,0,100}-{5994,0,100}-{5931,0,100}-{6000,0,100}-{1957,0,100}-{5504,0,100}-{5986,0,100}-{1982,0,100}-{5982,0,100}-{6002,0,100}-{5998,0,100}" + }, + { + "npcs": "2306", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "76", + "title": "Richard's Farming Shop", + "stock": "{5376,10,100}-{6032,300,100}-{5418,10,100}-{6036,10,100}-{5350,100,100}-{5341,10,100}-{5329,10,100}-{5343,10,100}-{952,10,100}-{5325,10,100}-{1925,100,100}-{5331,30,100}-{12622,10,100}-{5996,0,100}-{6006,0,100}-{1965,0,100}-{5994,0,100}-{5931,0,100}-{6000,0,100}-{1957,0,100}-{5504,0,100}-{5986,0,100}-{1982,0,100}-{5982,0,100}-{6002,0,100}-{5998,0,100}" + }, + { + "npcs": "557", + "high_alch": "1", + "currency": "995", + "general_store": "false", + "id": "77", + "title": "Wydin's Food Store", + "stock": "{1933,500,100}-{2132,10,100}-{2138,10,100}-{1965,10,100}-{1963,0,100}-{1951,0,100}-{2309,10,100}-{1973,10,100}-{1985,10,100}-{1982,10,100}-{1550,10,100}" + }, + { + "npcs": "1038", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "78", + "title": "Rufus's Meat Emporium", + "stock": "{2132,100,100}-{2138,30,100}-{2134,10,100}-{2136,10,100}-{335,0,100}-{349,0,100}-{331,0,100}-{383,0,100}" + }, + { + "npcs": "1433", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "79", + "title": "Solihib's Consumables Stall", + "stock": "{4012,10,100}-{1963,10,100}-{4016,10,100}-{4014,10,100}" + }, + { + "npcs": "7054", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "80", + "title": "Fresh Meat", + "stock": "{2134,10,100}-{2132,300,100}-{2136,10,100}-{2142,10,100}-{2138,10,100}-{2140,10,100}-{3226,100,100}-{7224,0,100}-{7223,0,100}-{3228,10,100}-{2876,0,100}-{7230,0,100}-{2878,0,100}-{7566,0,100}-{2337,0,100}-{9978,100,100}-{9984,0,100}-{9980,0,100}-{9986,0,100}-{9992,0,100}-{9988,0,100}" + }, + { + "npcs": "571", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "81", + "title": "Ardougne Baker's Stall", + "stock": "{2309,10,100}-{1891,10,100}-{1973,100,100}" + }, + { + "npcs": "5487", + "high_alch": "1", + "currency": "995", + "general_store": "false", + "id": "82", + "title": "Keepa Kettilon's store", + "stock": "{361,20,100}-{329,20,100}-{339,20,100}-{379,10,100}-{373,0,100}-{385,0,100}" + }, + { + "npcs": "851", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "83", + "title": "Gianne's Restaurant", + "stock": "{2223,10,100}-{2225,10,100}-{2221,10,100}-{2219,10,100}-{2227,10,100}-{2233,10,100}-{2231,10,100}-{2235,10,100}-{2229,10,100}-{2241,10,100}-{2243,10,100}-{2239,10,100}-{2237,10,100}" + }, + { + "npcs": "4294", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "84", + "title": "Warriors' Guild Potion Shop", + "stock": "{115,10,100}-{121,10,100}-{133,10,100}" + }, + { + "npcs": "4293", + "high_alch": "1", + "currency": "995", + "general_store": "false", + "id": "85", + "title": "Warriors' Guild Food Shop", + "stock": "{333,10,100}-{365,10,100}-{2289,10,100}-{6705,10,100}-{2003,10,100}" + }, + { + "npcs": "4295", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "86", + "title": "Warriors' Guild Armoury", + "stock": "{1363,10,100}-{1365,10,100}-{1369,10,100}-{1277,10,100}-{1279,10,100}-{1281,10,100}-{1283,10,100}-{1285,10,100}-{1287,10,100}-{1307,10,100}-{1309,10,100}-{1311,10,100}-{1313,10,100}-{1315,10,100}-{1317,10,100}-{1211,10,100}-{1301,10,100}-{1297,10,100}" + }, + { + "npcs": "584", + "high_alch": "1", + "currency": "995", + "general_store": "false", + "id": "87", + "title": "Herquin's Gems", + "stock": "{1623,0,100}-{1621,0,100}-{1619,0,100}-{1617,0,100}-{1607,0,100}-{1605,0,100}-{1603,0,100}-{1601,0,100}" + }, + { + "npcs": "570", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "88", + "title": "Ardougne Gem Stall", + "stock": "{1623,0,100}-{1621,0,100}-{1619,0,100}-{1617,0,100}-{1607,0,100}-{1605,0,100}-{1603,0,100}-{1601,0,100}" + }, + { + "npcs": "2157", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "89", + "title": "Green Gemstone Gem", + "stock": "{1607,0,100}-{1605,0,100}-{1603,0,100}-{1601,0,100}" + }, + { + "npcs": "540", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "90", + "title": "Gem Trader (stall)", + "stock": "{1623,0,100}-{1621,0,100}-{1619,0,100}-{1617,0,100}-{1607,0,100}-{1605,0,100}-{1603,0,100}-{1601,0,100}" + }, + { + "npcs": "540", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "91", + "title": "Gem Trader (stall)", + "stock": "{1623,0,100}-{1621,0,100}-{1619,0,100}-{1617,0,100}-{1607,0,100}-{1605,0,100}-{1603,0,100}-{1601,0,100}" + }, + { + "npcs": "2157", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "92", + "title": "Gem Store", + "stock": "{1623,1,100}-{1621,1,100}-{1619,0,100}-{1617,0,100}" + }, + { + "npcs": "", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "93", + "title": "Pelters' Veg Stall", + "stock": "{2518,100,100}" + }, + { + "npcs": "569", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "94", + "title": "Ardougne Silver Stall", + "stock": "{1714,10,100}-{442,0,100}-{2355,0,100}" + }, + { + "npcs": "572", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "95", + "title": "Ardougne Spice Stall", + "stock": "{2007,10,100}-{946,10,100}-{1550,10,100}" + }, + { + "npcs": "958", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "96", + "title": "Shop of Distate", + "stock": "{2518,1,100}" + }, + { + "npcs": "573", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "97", + "title": "Ardougne Fur Stall", + "stock": "{948,10,100}-{958,10,100}-{10117,0,100}-{10121,0,100}-{10119,0,100}-{10123,0,100}-{10093,0,100}-{10095,0,100}-{10097,0,100}-{10099,0,100}-{10101,0,100}-{10103,0,100}" + }, + { + "npcs": "538", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "98", + "title": "Peksa's Helmet Shop", + "stock": "{1139,5,100}-{1137,3,100}-{1141,3,100}-{1143,1,100}-{1145,1,100}-{1155,4,100}-{1153,3,100}-{1157,2,100}-{1159,1,100}-{1161,1,100}" + }, + { + "npcs": "1303", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "99", + "title": "Skulgrimen's Battle Gear", + "stock": "{1337,10,100}-{1335,10,100}-{1339,10,100}-{1341,10,100}-{1343,10,100}-{1347,0,100}-{3749,10,100}-{3751,10,100}-{3753,10,100}-{3755,10,100}" + }, + { + "npcs": "595", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "100", + "title": "Tea Shop", + "stock": "{712,10,100}" + }, + { + "npcs": "704", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "102", + "title": "Grud's Herblore Stall.", + "stock": "{229,10,100}-{233,10,100}-{221,10,100}" + }, + { + "npcs": "587", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "103", + "title": "Jatix's Herblore Shop", + "stock": "{229,300,480}-{233,10,100}-{221,1000,100}" + }, + { + "npcs": "5110", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "104", + "title": "Aleck's Hunter Emporium", + "stock": "{10010,10,100}-{10012,300,100}-{10025,300,100}-{10150,10,100}-{10006,30,100}-{10008,30,100}-{10029,10,100}-{596,10,100}-{10031,30,100}-{12539,0,100}" + }, + { + "npcs": "5109", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "105", + "title": "Nardah Hunter Shop", + "stock": "{10010,10,100}-{10012,300,100}-{10025,300,100}-{10150,10,100}-{10006,30,100}-{10008,30,100}-{10029,10,100}-{596,10,100}-{10031,30,100}-{12539,0,100}" + }, + { + "npcs": "556", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "106", + "title": "Grum's Gold Exchange", + "stock": "{1635,0,100}-{1637,0,100}-{1639,0,100}-{1641,0,100}-{1643,0,100}-{1654,0,100}-{1656,0,100}-{1658,0,100}-{1660,0,100}-{1662,0,100}-{1692,0,100}-{1694,0,100}-{1696,0,100}-{1698,0,100}-{1700,0,100}-{11069,0,100}-{11072,0,100}-{11076,0,100}-{11085,0,100}-{11092,0,100}" + }, + { + "npcs": "1862", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "107", + "title": "Ali's Discount Wares", + "stock": "{1931,30,100}-{1935,10,100}-{1825,10,100}-{1833,10,100}-{1837,10,100}-{1925,30,100}-{4593,10,100}-{4591,10,100}-{970,1,100}-{946,10,100}-{590,10,100}-{1265,10,100}-{2138,10,100}" + }, + { + "npcs": "1865", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "108", + "title": "Ali the Kebab Seller", + "stock": "{1971,10,100}" + }, + { + "npcs": "543", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "109", + "title": "Karim", + "stock": "{1971,10,100}" + }, + { + "npcs": "2198", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "110", + "title": "Kjut's KEbabs", + "stock": "{1971,10,100}" + }, + { + "npcs": "580", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "111", + "title": "Flynn's Mace Market", + "stock": "{1422,5,100}-{1420,4,100}-{1424,4,100}-{1428,3,100}-{1430,2,100}" + }, + { + "npcs": "1862", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "112", + "title": "Ali's Discount Wares#runes", + "stock": "{1931,30,100}-{1935,10,100}-{1833,10,100}-{1837,10,100}-{1925,10,100}-{4593,10,100}-{4591,10,100}-{970,10,100}-{946,10,100}-{590,10,100}-{1265,10,100}-{2138,10,100}-{6416,10,100}-{4600,10,100}-{556,300,100}-{555,300,100}-{557,300,100}-{554,300,100}-{561,300,100}-{563,300,100}-{562,300,100}-{560,300,100}-{558,300,100}-{559,300,100}-{565,100,100}-{564,300,100}-{566,100,100}-{6382,30,100}-{6388,30,100}-{6390,30,100}-{1835,30,100}" + }, + { + "npcs": "583", + "high_alch": "1", + "currency": "995", + "general_store": "false", + "id": "113", + "title": "Betty's Magic Emporium", + "stock": "{554,300,100}-{555,300,100}-{556,300,100}-{557,300,100}-{558,100,100}-{559,100,100}-{562,30,100}-{560,10,100}-{221,100,100}-{579,10,100}-{1017,10,100}" + }, + { + "npcs": "553", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "114", + "title": "Aubury's Rune Shop", + "stock": "{554,5000,100}-{555,5000,100}-{556,5000,100}-{557,5000,100}-{558,5000,100}-{559,5000,100}-{562,500,100}-{560,500,100}" + }, + { + "npcs": "461", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "115", + "title": "Magic Guild Store", + "stock": "{556,5000,100}-{555,5000,100}-{557,5000,100}-{554,5000,100}-{558,5000,100}-{559,5000,100}-{562,250,100}-{561,250,100}-{560,250,100}-{563,250,100}-{565,250,100}-{566,250,100}-{1391,5,100}-{1387,2,100}-{1383,2,100}-{1381,2,100}-{1385,2,100}" + }, + { + "npcs": "4513", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "116", + "title": "Baba Yaga's Magic Shop", + "stock": "{556,1000,100}-{555,1000,100}-{557,1000,100}-{554,1000,100}-{558,1000,100}-{559,1000,100}-{562,300,100}-{561,300,100}-{560,300,100}-{563,100,100}-{565,100,100}-{566,100,100}-{9075,100,100}-{1391,20,100}-{1387,10,100}-{1383,10,100}-{1381,10,100}-{1385,10,100}-{9078,10,100}" + }, + { + "npcs": "3097", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "117", + "title": "Mage Training Arena#rewards", + "stock": "" + }, + { + "npcs": "903", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "118", + "title": "Lundail's Arena-side Rune Shop", + "stock": "{554,1000,100}-{555,1000,100}-{556,1000,100}-{557,1000,100}-{558,1000,100}-{559,1000,100}-{561,300,100}-{562,300,100}-{563,100,100}-{564,300,100}-{560,300,100}" + }, + { + "npcs": "1435", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "119", + "title": "Tutab's Magical Market", + "stock": "{554,1000,100}-{555,1000,100}-{556,1000,100}-{557,1000,100}-{563,100,100}-{4009,10,100}-{4006,10,100}-{4023,10,100}" + }, + { + "npcs": "3798", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "120", + "title": "Void Knight Magic Store", + "stock": "{554,1000,100}-{555,1000,100}-{556,1000,100}-{557,1000,100}-{558,1000,100}-{559,1000,100}-{562,300,100}-{560,300,100}" + }, + { + "npcs": "2623", + "high_alch": "0", + "currency": "6529", + "general_store": "false", + "id": "121", + "title": "Tzhaar-mej-roh's Rune Store", + "stock": "{554,1000,100}-{555,1000,100}-{557,1000,100}-{556,1000,100}-{558,1000,100}-{559,1000,100}-{562,300,100}-{560,100,100}" + }, + { + "npcs": "2622", + "high_alch": "0", + "currency": "6529", + "general_store": "false", + "id": "122", + "title": "Tzhaar-Hur-Lek's Ore and Gem Store.", + "stock": "{438,5,100}-{436,5,100}-{440,2,100}-{442,0,100}-{453,0,100}-{444,0,100}-{447,0,100}-{449,0,100}-{451,0,100}-{1623,1,100}-{1621,1,100}-{1619,0,100}-{1617,0,100}-{1631,0,100}-{6571,1,100}-{9194,50,100}" + }, + { + "npcs": "1658", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "123", + "title": "Magic Guild Store", + "stock": "{4089,1000,100}-{4091,1000,100}-{4093,1000,100}-{4095,1000,100}-{4097,1000,100}" + }, + { + "npcs": "594", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "124", + "title": "Nurmof's Pickaxe Shop", + "stock": "{1265,10,100}-{1267,10,100}-{1269,10,100}-{1273,10,100}-{1271,10,100}-{1275,10,100}" + }, + { + "npcs": "579", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "125", + "title": "Drogo's Mining Emporium", + "stock": "{2347,10,100}-{1265,10,100}-{436,0,100}-{438,0,100}-{440,0,100}-{453,0,100}-{2349,0,100}-{2351,0,100}-{2357,0,100}" + }, + { + "npcs": "2160", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "126", + "title": "Pickaxe-Is-Mine", + "stock": "{1265,10,100}-{1269,10,100}-{1273,10,100}-{1271,10,100}-{1275,10,100}" + }, + { + "npcs": "6750,6898,6893", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "127", + "title": "Pet Shop", + "stock": "{12130,10,100}-{12125,1000,100}-{12127,10,100}-{12183,125000,100}" + }, + { + "npcs": "589", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "128", + "title": "Zenesha's Platebody Shop", + "stock": "{1117,10,100}-{1115,10,100}-{1119,10,100}-{1125,10,100}-{1121,10,100}" + }, + { + "npcs": "549", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "129", + "title": "Horvik's Armour Shop", + "stock": "{1103,10,100}-{1101,10,100}-{1173,10,100}-{1175,10,100}-{1075,10,100}-{1067,10,100}-{1087,10,100}-{1081,10,100}-{1117,10,100}-{1115,10,100}-{1119,10,100}-{1125,10,100}-{1121,10,100}-{1097,10,100}-{1133,10,100}" + }, + { + "npcs": "5485", + "high_alch": "1", + "currency": "995", + "general_store": "false", + "id": "130", + "title": "Armour Shop", + "stock": "{1109,4,100}-{1143,4,100}-{1159,4,100}-{1181,4,100}-{1197,4,100}-{1071,4,100}-{1085,4,100}-{1121,4,100}" + }, + { + "npcs": "542", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "131", + "title": "Louie's Armoured Legs Bazaar", + "stock": "{1075,10,100}-{1067,10,100}-{1069,10,100}-{1077,10,100}-{1071,10,100}-{1073,10,100}" + }, + { + "npcs": "549", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "132", + "title": "Horvik's Armour Shop", + "stock": "{1103,10,100}-{1101,10,100}-{1173,10,100}-{1175,10,100}-{1075,10,100}-{1067,10,100}-{1087,10,100}-{1081,10,100}-{1117,10,100}-{1115,10,100}-{1119,10,100}-{1125,10,100}-{1121,10,100}-{1097,10,100}-{1133,10,100}" + }, + { + "npcs": "3038", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "133", + "title": "Seddus Adventurers Store", + "stock": "{1093,10,100}-{1079,10,100}-{1113,10,100}-{1099,10,100}-{1193,10,100}" + }, + { + "npcs": "544", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "134", + "title": "Ranael's Super Skirt Store", + "stock": "{1087,10,100}-{1081,10,100}-{1083,10,100}-{1089,10,100}-{1085,10,100}-{1091,10,100}" + }, + { + "npcs": "541", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "135", + "title": "Zeke's Superior Scimitars", + "stock": "{1321,10,100}-{1323,10,100}-{1325,10,100}-{1329,10,100}" + }, + { + "npcs": "1434", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "136", + "title": "Daga's Scimitar Smithy", + "stock": "{1321,10,100}-{1323,10,100}-{1325,10,100}-{1329,10,100}-{4587,10,100}" + }, + { + "npcs": "577", + "high_alch": "1", + "currency": "995", + "general_store": "false", + "id": "137", + "title": "Cassie's Shield Shop", + "stock": "{1171,5,100}-{1173,3,100}-{1189,3,100}-{1175,2,100}-{1191,0,100}-{1177,0,100}-{1193,0,100}-{1181,0,100}" + }, + { + "npcs": "209", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "138", + "title": "Multicannon parts for sale", + "stock": "{6,5,100}-{8,5,100}-{10,5,100}-{12,5,100}-{5,5,100}-{4,5,100}" + }, + { + "npcs": "1980", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "139", + "title": "The Spice Is Right", + "stock": "{1931,30,100}-{2169,10,100}-{5970,0,100}-{175,10,100}" + }, + { + "npcs": "546", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "140", + "title": "Staff Shop", + "stock": "{1379,10,100}-{1389,10,100}-{1381,10,100}-{1383,10,100}-{1385,10,100}-{1387,10,100}" + }, + { + "npcs": "6971", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "141", + "title": "Pikkupstix's Summoning Shop", + "stock": "{12204,10,100}-{12207,10,100}-{12210,10,100}-{12213,10,100}-{12216,10,100}-{12219,10,100}-{12222,10,100}-{12183,125000,100}-{12155,5000,100}" + }, + { + "npcs": "4472", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "142", + "title": "Bogrog's Summoning Shop", + "stock": "{12204,10,100}-{12207,10,100}-{12210,0,100}-{12213,0,100}-{12216,0,100}-{12219,0,100}-{12222,0,100}-{12183,65000,100}-{12155,5000,100}" + }, + { + "npcs": "3671", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "143", + "title": "Fortunato's Fine Wine", + "stock": "{1993,10,100}-{7810,10,100}-{7919,10,100}-{1935,10,100}" + }, + { + "npcs": "558", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "144", + "title": "Gerrant's Fishy Business", + "stock": "{303,10,100}-{307,10,100}-{309,10,100}-{311,30,100}-{301,10,100}-{13431,10,100}-{313,1000,100}-{314,1000,100}-{317,0,100}-{327,10,100}-{345,0,100}-{321,0,100}-{335,0,100}-{349,0,100}-{331,0,100}-{359,0,100}-{377,0,100}-{371,0,100}" + }, + { + "npcs": "576", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "145", + "title": "Harry's Fishing Shop", + "stock": "{303,10,100}-{307,10,100}-{311,1000,100}-{301,10,100}-{313,100,100}-{305,10,100}-{317,0,100}-{327,0,100}-{345,0,100}-{353,0,100}-{341,0,100}-{321,0,100}-{359,0,100}-{377,0,100}-{363,0,100}-{371,0,100}-{383,0,100}-{7810,1000,100}" + }, + { + "npcs": "5266", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "146", + "title": "Blades By Urbi", + "stock": "{1205,10,100}-{1203,10,100}-{1207,10,100}-{1217,0,100}-{1209,10,100}-{1211,10,100}-{1213,10,100}-{1215,0,100}-{1321,10,100}-{1323,10,100}-{1325,10,100}" + }, + { + "npcs": "586", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "147", + "title": "Gaius' Two Handed Shop.", + "stock": "{1307,4,100}-{1309,3,100}-{1311,2,100}-{1313,1,100}-{1315,1,100}-{1317,1,100}" + }, + { + "npcs": "602", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "148", + "title": "Gulluck And Sons", + "stock": "{882,1000,100}-{877,300,100}-{880,0,100}-{841,10,100}-{837,10,100}-{1363,10,100}-{1365,10,100}-{1369,10,100}-{1307,10,100}-{1309,10,100}-{1311,10,100}-{1313,10,100}-{1315,10,100}-{1317,10,100}" + }, + { + "npcs": "552,551", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "149", + "title": "Varrock Sword Shop", + "stock": "{1277,10,100}-{1279,10,100}-{1281,10,100}-{1283,10,100}-{1285,10,100}-{1287,10,100}-{1291,10,100}-{1293,10,100}-{1295,10,100}-{1297,10,100}-{1299,10,100}-{1301,10,100}-{1205,10,100}-{1203,10,100}-{1207,10,100}-{1217,10,100}-{1209,10,100}-{1211,10,100}" + }, + { + "npcs": "541", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "150", + "title": "Zeke's Superior Scimitars", + "stock": "{1321,10,100}-{1323,10,100}-{1325,10,100}-{1329,10,100}" + }, + { + "npcs": "692", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "151", + "title": "Authentic Throwing Weapons", + "stock": "{825,1000,100}-{826,1000,100}-{827,1000,100}-{828,300,100}-{829,100,100}-{830,100,100}-{800,900,100}-{801,800,100}-{802,700,100}-{803,600,100}-{804,500,100}-{805,400,100}" + }, + { + "npcs": "797", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "152", + "title": "Happy Heroes Hemporium", + "stock": "{1377,1,100}-{1434,1,100}" + }, + { + "npcs": "564", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "153", + "title": "Jukat's Dragon Sword Shop", + "stock": "{1305,2,100}-{1215,2,100}" + }, + { + "npcs": "4312", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "154", + "title": "Nardok's Bone Weapons", + "stock": "{5018,10,100}-{5016,10,100}-{8872,10,100}-{8880,10,100}-{8882,25000,100}" + }, + { + "npcs": "2152", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "155", + "title": "Quality Weapons Shop", + "stock": "{1365,10,100}-{1369,10,100}-{1285,10,100}-{1287,10,100}-{1325,10,100}-{1297,10,100}-{1303,10,100}-{853,10,100}-{888,100,100}-{890,100,100}" + }, + { + "npcs": "1208", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "156", + "title": "Quartermaster's Stores", + "stock": "{1931,30,100}-{1935,10,100}-{1735,10,100}-{590,10,100}-{2309,10,100}-{3190,10,100}-{3192,10,100}-{3194,10,100}-{3196,10,100}-{3198,10,100}-{3200,10,100}-{3202,10,100}-{3204,10,100}" + }, + { + "npcs": "2572,2233", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "157", + "title": "Draynor Seed Market", + "stock": "{5318,20,100}-{5319,10,100}-{5324,10,100}-{5322,0,100}-{5320,0,100}-{5323,0,100}-{5321,0,100}-{5305,20,100}-{5306,5,100}-{5097,20,100}-{5096,20,100}-{5307,20,100}-{5308,10,100}-{5309,5,100}-{5310,0,100}-{5311,0,100}" + }, + { + "npcs": "3205", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "158", + "title": "Romily Weaklax Pie's", + "stock": "{2323,1,100}-{2325,1,100}-{2327,1,100}-{7178,1,100}-{7188,1,100}-{7198,1,100}" + }, + { + "npcs": "70,1598,1596,1597,1599,8274,8275,8276,8277,8273,8271,8270,2253,7780", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "159", + "title": "Slayer Equipment", + "stock": "{4155,50,100}-{4156,50,100}-{4158,50,100}-{4160,50000,100}-{4161,5000,100}-{4162,50,100}-{4164,50,100}-{4166,50,100}-{4168,50,100}-{4170,50,100}-{4551,50,100}-{6664,5000,100}-{6696,3000,100}-{6720,50,100}-{7051,50,100}-{7159,50,100}-{7421,50,100}-{7432,50,100}-{8923,50,100}-{10952,50,100}-{13279,5000,100}-{13278,3000,100}" + }, + { + "npcs": "2257,2258,2259", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "160", + "title": "Battle Runes", + "stock": "{554,100,100}-{555,100,100}-{556,100,100}-{557,100,100}-{558,100,100}-{559,100,100}-{562,30,100}-{560,30,100}" + }, + { + "npcs": "3162", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "161", + "title": "Smithing Smiths Shop", + "stock": "{1321,10,100}-{1323,10,100}-{1325,10,100}-{1329,10,100}-{2347,10,100}" + }, + { + "npcs": "1167", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "162", + "title": "Tamayu's Spear Stall", + "stock": "{3188,10,100}" + }, + { + "npcs": "2620", + "high_alch": "0", + "currency": "6529", + "general_store": "false", + "id": "163", + "title": "Tzhaar-hur-tel's Equipment Store", + "stock": "{6522,500,100}-{6525,1,100}-{6523,1,100}-{6524,1,100}-{6526,1,100}-{6527,1,100}-{6528,1,100}-{6568,1,100}" + }, + { + "npcs": "2151", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "164", + "title": "Vigr's Warhammers", + "stock": "{1337,10,100}-{1335,10,100}-{1339,10,100}-{1341,10,100}-{1343,10,100}" + }, + { + "npcs": "5486", + "high_alch": "1", + "currency": "995", + "general_store": "false", + "id": "165", + "title": "Weapons galore", + "stock": "{1299,4,100}-{1343,4,100}-{1369,4,100}-{3099,4,100}-{1315,4,100}" + }, + { + "npcs": "4250", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "166", + "title": "Construction supplies", + "stock": "{8794,10,100}-{8790,300,100}-{4819,300,100}-{4820,300,100}-{1539,300,100}" + }, + { + "npcs": "1079,1357,1358", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "167", + "title": "The Toad and Chicken", + "stock": "{1905,12,100}-{1907,12,100}-{1913,12,100}" + }, + { + "npcs": "2270", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "168", + "title": "Martin Thwait's Lost and Found.", + "stock": "{954,50,100}-{1523,25,100}-{1755,30,100}-{946,20,100}-{5560,25,100}-{864,15,100}-{863,10,100}-{865,5,100}-{3095,3,100}-{3096,2,100}-{3097,1,100}" + }, + { + "npcs": "970", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "169", + "title": "Diango's Toy Store", + "stock": "{2526,10,100}-{2520,10,100}-{2522,10,100}-{2524,10,100}-{4613,10,100}-{12844,10,100}" + }, + { + "npcs": "793", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "170", + "title": "The Shrimp and Parrot", + "stock": "{347,5,100}-{339,5,100}-{379,3,100}-{373,2,100}-{3144,3,100}" + }, + { + "npcs": "747", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "171", + "title": "Oziach's Armour", + "stock": "{1127,2,100}-{1135,2,100}" + }, + { + "npcs": "537", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "172", + "title": "Scavvo's Rune Store", + "stock": "{1093,1,100}-{1079,1,100}-{1432,1,100}-{1113,1,100}-{1303,1,100}-{1289,1,100}-{1099,1,100}-{1065,1,100}-{1169,2,100}" + }, + { + "npcs": "536", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "173", + "title": "Valaine's Shop of Champions.", + "stock": "{1021,2,100}-{1165,1,100}-{1077,1,100}-{1123,1,100}" + }, + { + "npcs": "833", + "high_alch": "0", + "currency": "995", + "general_store": "true", + "id": "174", + "title": "Bebadin Village Bartering", + "stock": "{1823,30,100}-{1831,30,100}-{1937,10,100}-{1921,10,100}-{1929,10,100}-{946,10,100}-{2347,10,100}" + }, + { + "npcs": "566", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "175", + "title": "Irksol", + "stock": "{1641,5,100}" + }, + { + "npcs": "904", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "176", + "title": "Mage Arena Staffs", + "stock": "{2415,5,100}-{2416,5,100}-{2417,5,100}" + }, + { + "npcs": "", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "177", + "title": "Culinaromancer's Chest", + "stock": "{1973,50,100}-{1982,50,100}-{1987,9,100}-{2283,1,100}-{1927,50,100}-{6697,50,100}-{2313,50,100}-{1923,50,100}-{1931,50,100}-{1925,50,100}-{1985,50,100}-{1955,50,100}-{1933,50,100}-{1944,50,100}-{2130,50,100}-{2007,50,100}-{1887,50,100}-{1935,50,100}-{1980,50,100}" + }, + { + "npcs": "", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "178", + "title": "Culinaromancer's Chest", + "stock": "{7453,5,100}-{7454,5,100}-{7455,5,100}-{7456,5,100}-{7457,5,100}-{7458,5,100}-{7459,5,100}-{7460,5,100}-{7461,5,100}-{7462,5,100}-{7433,5,100}-{7435,5,100}-{7437,5,100}-{7439,5,100}-{7441,5,100}-{7443,5,100}-{7445,5,100}-{7447,5,100}-{7449,5,100}-{7451,5,100}" + }, + { + "npcs": "2290", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "179", + "title": "Sir Tiffy Cashien", + "stock": "{5574,10,100}-{5576,10,100}-{5575,10,100}-{9672,10,100}-{9676,10,100}-{9674,10,100}-{9678,10,100}" + }, + { + "npcs": "933", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "180", + "title": "Legends' Guild Shop of Useful Items", + "stock": "{299,100,100}-{1542,5,100}-{1590,3,100}-{1052,1,100}-{2368,3,100}" + }, + { + "npcs": "4518", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "181", + "title": "MoonClan Fine Clothes", + "stock": "{9068,10,100}-{9069,10,100}-{9070,10,100}-{9071,10,100}-{9072,10,100}-{9073,10,100}-{9074,10,100}-{1733,50,100}-{1734,500,100}" + }, + { + "npcs": "", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "182", + "title": "Delicious Goods", + "stock": "{2436,150000,100}-{2440,150000,100}-{2442,150000,100}-{2444,150000,100}-{3040,150000,100}-{2434,150000,100}-{3024,150000,100}-{2452,150000,100}-{6685,150000,100}-{9739,150000,100}-{385,150000,100}-{3144,150000,100}-{391,150000,100}-{7060,150000,100}-{7946,150000,100}-{379,150000,100}-{7218,150000,100}-{2301,150000,100}" + }, + { + "npcs": "", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "183", + "title": "Armour & Supplies", + "stock": "{5698,150000,100}-{1305,150000,100}-{4587,150000,100}-{1377,150000,100}-{1434,150000,100}-{7158,150000,100}-{3204,150000,100}-{4151,150000,100}-{4153,150000,100}-{6528,150000,100}-{1333,150000,100}-{1319,150000,100}-{10887,150000,100}-{5574,150000,100}-{5575,150000,100}-{5576,150000,100}-{9672,150000,100}-{9674,150000,100}-{9676,150000,100}-{1067,150000,100}-{1115,150000,100}-{1153,150000,100}-{1079,150000,100}-{1127,150000,100}-{1163,150000,100}-{6107,150000,100}-{6109,150000,100}-{6108,150000,100}-{6524,150000,100}-{10828,150000,100}-{3751,150000,100}-{3753,150000,100}-{3105,150000,100}-{7460,150000,100}" + }, + { + "npcs": "", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "184", + "title": "Range Supplies", + "stock": "{9241,150000,100}-{9243,150000,100}-{9242,150000,100}-{9244,150000,100}-{9245,150000,100}-{9144,150000,100}-{9305,150000,100}-{868,150000,100}-{11230,150000,100}-{6522,150000,100}-{892,150000,100}-{2491,150000,100}-{2497,150000,100}-{2503,150000,100}-{6328,150000,100}-{3749,150000,100}-{861,150000,100}-{9185,150000,100}-{4214,150000,100}-{1169,150000,100}-{1129,150000,100}-{10034,150000,100}" + }, + { + "npcs": "", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "185", + "title": "Magic Emporium", + "stock": "{554,150000,100}-{555,150000,100}-{556,150000,100}-{557,150000,100}-{558,150000,100}-{559,150000,100}-{560,150000,100}-{561,150000,100}-{562,150000,100}-{563,150000,100}-{564,150000,100}-{565,150000,100}-{566,150000,100}-{9075,150000,100}-{4089,150000,100}-{4091,150000,100}-{4093,150000,100}-{4095,150000,100}-{4097,150000,100}-{4099,150000,100}-{4101,150000,100}-{4103,150000,100}-{4105,150000,100}-{4107,150000,100}-{4109,150000,100}-{4111,150000,100}-{4113,150000,100}-{4115,150000,100}-{4117,150000,100}-{6912,150000,100}-{3840,150000,100}-{3842,150000,100}-{3844,150000,100}-{1540,150000,100}-{2412,150000,100}-{2413,150000,100}-{2414,150000,100}-{4675,150000,100}-{2415,150000,100}-{2416,150000,100}-{2417,150000,100}-{577,150000,100}-{579,150000,100}-{2579,150000,100}" + }, + { + "npcs": "5509", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "186", + "title": "Neitiznot Supplies", + "stock": "{946,10,100}-{2347,10,100}-{1734,1000,100}-{1733,10,100}-{1351,10,100}-{1759,1000,100}-{4819,1000,100}" + }, + { + "npcs": "1778", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "187", + "title": "William's Wilderness Cape Shop", + "stock": "{4315,100,100}-{4335,100,100}-{4355,100,100}-{4375,100,100}-{4395,100,100}" + }, + { + "npcs": "1779", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "188", + "title": "Ian's Wilderness Cape Shop", + "stock": "{4317,100,100}-{4337,100,100}-{4357,100,100}-{4377,100,100}-{4397,100,100}" + }, + { + "npcs": "1780", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "189", + "title": "Larry's Wilderness Cape Shop", + "stock": "{4319,100,100}-{4339,100,100}-{4359,100,100}-{4379,100,100}-{4399,100,100}" + }, + { + "npcs": "1781", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "190", + "title": "Darren's Wilderness Cape Shop", + "stock": "{4321,100,100}-{4341,100,100}-{4361,100,100}-{4381,100,100}-{4401,100,100}" + }, + { + "npcs": "1782", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "191", + "title": "Edward's Wilderness Cape Shop", + "stock": "{4323,100,100}-{4343,100,100}-{4363,100,100}-{4383,100,100}-{4403,100,100}" + }, + { + "npcs": "1783", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "192", + "title": "Richard's Wilderness Cape Shop", + "stock": "{4325,100,100}-{4345,100,100}-{4365,100,100}-{4385,100,100}-{4405,100,100}" + }, + { + "npcs": "1784", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "193", + "title": "Neil's Wilderness Cape Shop", + "stock": "{4327,100,100}-{4347,100,100}-{4367,100,100}-{4387,100,100}-{4407,100,100}" + }, + { + "npcs": "1785", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "194", + "title": "Edmond's Wilderness Cape Shop", + "stock": "{4329,100,100}-{4349,100,100}-{4369,100,100}-{4389,100,100}-{4409,100,100}" + }, + { + "npcs": "1786", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "195", + "title": "Simon's Wilderness Cape Shop", + "stock": "{4331,100,100}-{4351,100,100}-{4371,100,100}-{4391,100,100}-{4411,100,100}" + }, + { + "npcs": "1787", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "196", + "title": "Sam's Wilderness Cape Shop", + "stock": "{4333,100,100}-{4353,100,100}-{4373,100,100}-{4393,100,100}-{4413,100,100}" + }, + { + "npcs": "", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "198", + "title": "Candle Shop", + "stock": "{36,10,100}-{38,10,100}" + }, + { + "npcs": "", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "200", + "title": "The Teleporter's Tabs", + "stock": "{8007,100,100}-{8008,100,100}-{8009,100,100}-{8010,100,100}-{8011,100,100}-{8012,100,100}" + }, + { + "npcs": "", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "201", + "title": "The Fairy's Culinary Goods", + "stock": "{330,10000000,100}-{6706,10000000,100}-{380,10000000,100}-{7219,10000000,100}-{2290,10000000,100}-{2302,10000000,100}-{1892,10000000,100}-{229,10000000,100}" + }, + { + "npcs": "1369", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "209", + "title": "Holy Wares", + "stock": "{6746,1,100}-{732,100,100}" + }, + { + "npcs": "694", + "high_alch": "0", + "currency": "1464", + "general_store": "false", + "id": "210", + "title": "Ranging Guild Ticket Exchange", + "stock": "{47,10000000,100}-{1133,10000000,100}-{892,10000000,100}-{1169,10000000,100}-{1135,10000000,100}-{829,10000000,100}" + }, + { + "npcs": "3045", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "211", + "title": "Rok's Choc Box", + "stock": "{6794,30,100}-{1973,25,100}" + }, + { + "npcs": "1688", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "212", + "title": "Ak-haranu's Exotic Goods", + "stock": "{4740,100000,100}" + }, + { + "npcs": "4251", + "high_alch": "1", + "currency": "995", + "general_store": "false", + "id": "213", + "title": "The Garden Centre", + "stock": "{8417,10,100}-{8419,10,100}-{8421,10,100}-{8423,10,100}-{8425,10,100}-{8427,10,100}-{8429,10,100}-{8431,1000,100}-{8433,10,100}-{8435,10,100}-{8451,10,100}-{8453,10,100}-{8455,10,100}-{8457,10,100}-{8459,10,100}-{8461,10,100}-{8437,10,100}-{8439,10,100}-{8441,10,100}-{8443,10,100}-{8445,10,100}-{8447,10,100}-{8449,10,100}" + }, + { + "npcs": "1972", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "214", + "title": "Rasolo's Goods", + "stock": "{1969,2,100}-{2023,4,100}-{740,10,100}-{1215,1,100}-{550,1,100}-{583,2,100}-{1941,10,100}-{970,1,100}-{975,1,100}-{1599,1,100}-{2976,1,100}-{1823,1,100}-{1837,1,100}-{1864,5,100}-{2520,1,100}-{3377,1,100}-{626,1,100}-{1909,1,100}-{3787,1,100}-{3711,1,100}-{3678,1,100}-{3424,5,100}-{3420,1,100}-{5,1,100}" + }, + { + "npcs": "592", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "215", + "title": "Fishing Guild Shop.", + "stock": "{313,1000,100}-{314,1000,100}-{341,0,100}-{353,0,100}-{363,0,100}-{359,0,100}-{377,0,100}-{371,0,100}-{339,0,100}-{355,0,100}-{365,0,100}-{361,0,100}-{379,0,100}-{373,0,100}" + }, + { + "npcs": "5483", + "high_alch": "1", + "currency": "995", + "general_store": "false", + "id": "216", + "title": "Ore Store", + "stock": "{436,10,100}-{438,10,100}-{440,0,100}-{442,0,100}-{453,0,100}-{444,0,100}-{447,0,100}-{449,0,100}" + }, + { + "npcs": "596", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "217", + "title": "Tony's Pizza Bases", + "stock": "{2283,10,100}" + }, + { + "npcs": "2159", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "218", + "title": "Silver Cog Silver Stall", + "stock": "{1714,2,100}-{442,1,100}-{2355,1,100}" + }, + { + "npcs": "2158", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "219", + "title": "Carefree Crafting Stall", + "stock": "{1755,2,100}-{1592,4,100}-{1597,2,100}-{1733,3,100}-{1734,100,100}-{1759,100,100}" + }, + { + "npcs": "2156", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "220", + "title": "Keldagrim's Best Bread", + "stock": "{2309,10,100}-{1891,3,100}-{1901,8,100}" + }, + { + "npcs": "2153", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "221", + "title": "Quality Armour Shop", + "stock": "{1105,3,100}-{1109,1,100}-{1107,1,100}-{1111,1,100}-{1141,3,100}-{1143,1,100}-{1145,1,100}-{1177,0,100}-{1195,0,100}" + }, + { + "npcs": "2564", + "force_shared": "true", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "222", + "title": "Ore Shop\b", + "stock": "{436,0,0}-{438,0,0}-{440,0,0}-{442,0,0}-{444,0,0}-{447,0,0}-{453,0,0}" + }, + { + "npcs": "603", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "223", + "title": "Funch's Fine Groceries", + "stock": "{2021,10,100}-{2019,10,100}-{2015,10,100}-{2017,10,100}-{2114,10,100}-{2128,20,100}-{2108,20,100}-{2102,20,100}-{2126,5,100}-{2025,10,100}-{1973,20,100}-{1975,10,100}-{2130,5,100}-{1927,5,100}-{946,5,100}-{2026,20,100}" + }, + { + "npcs": "578", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "224", + "title": "Frincos' Fabulous Herb Store.", + "stock": "{229,10,100}-{233,10,100}-{221,10,100}" + }, + { + "npcs": "555", + "high_alch": "0", + "currency": "995", + "general_store": "true", + "id": "225", + "title": "Port Khazard General Store", + "stock": "{1941,200,10}-{954,10,10}-{583,10,100}-{1931,30,100}-{1935,10,100}-{1735,10,100}-{1925,10,100}-{1923,10,100}-{1887,10,100}-{590,10,100}-{1755,10,100}-{2347,10,100}-{550,10,100}-{9003,10,100}" + }, + { + "npcs": "", + "high_alch": "0", + "currency": "6306", + "general_store": "false", + "id": "226", + "title": "Gabooty's Tai Bwo Wannai Cooperative", + "stock": "{6341,10,100}-{6343,10,100}-{6345,10,100}-{6347,10,100}-{6349,10,100}-{6313,10,100}-{6315,10,100}-{6317,10,100}-{6351,10,100}-{6353,10,100}-{6355,10,100}-{6357,10,100}-{6359,10,100}-{1625,0,100}-{1627,0,100}-{1629,0,100}-{6361,10,100}-{6363,10,100}-{6365,10,100}-{6367,10,100}-{6369,10,100}-{1609,0,100}-{1611,0,100}-{1613,0,100}-{6371,10,100}-{6373,10,100}-{6375,10,100}-{6377,10,100}-{6379,10,100}-{6311,0,100}" + }, + { + "npcs": "2161", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "227", + "title": "Agmundi Quality Clothes", + "stock": "{5050,3,100}-{5052,3,100}-{5038,3,100}-{5040,3,100}-{5044,3,100}-{5046,3,100}-{5026,3,100}-{5028,3,100}-{5032,3,100}-{5034,3,100}" + }, + { + "npcs": "517", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "228", + "title": "Fernahei's Fishing Hut", + "stock": "{307,10,100}-{309,10,100}-{313,1000,100}-{314,1000,100}-{335,0,100}-{349,0,100}-{331,0,100}" + }, + { + "npcs": "2357", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "229", + "title": "Lletya Food Store", + "stock": "{2309,10,100}-{379,10,100}-{1993,10,100}-{1985,10,100}-{1891,10,100}" + }, + { + "npcs": "2356", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "230", + "title": "Lletya Archery Shop", + "stock": "{884,2000,100}-{886,500,100}-{888,500,100}-{890,450,100}-{892,400,100}-{877,1500,100}-{843,5,100}-{845,5,100}-{837,5,100}-{849,5,100}-{847,5,100}" + }, + { + "npcs": "1282", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "232", + "title": "Sigmund the Merchant", + "stock": "{590,10,100}-{954,10,100}-{1931,30,100}-{2142,10,100}-{2309,10,100}-{952,10,100}-{36,10,100}-{1755,10,100}-{229,310,100}-{227,310,100}-{1925,30,100}-{1944,10,100}-{1942,10,100}-{233,10,100}-{2347,10,100}-{1929,10,100}" + }, + { + "npcs": "1315", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "233", + "title": "Fremennik Fishmonger", + "stock": "{303,5,100}-{307,5,100}-{309,5,100}-{311,2,100}-{301,2,100}-{313,1000,100}-{314,1000,100}-{305,5,100}-{317,10,100}-{327,10,100}-{345,0,100}-{353,0,100}-{341,0,100}-{321,0,100}-{335,0,100}-{331,0,100}-{359,0,100}-{377,0,100}-{363,0,100}-{371,0,100}-{383,0,100}" + }, + { + "npcs": "1300", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "234", + "title": "Rellekka Longhall Bar", + "stock": "{1917,10,100}-{3803,10,100}-{3711,10,100}" + }, + { + "npcs": "7420", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "235", + "title": "Gnomic Supplies", + "stock": "{1931,100,100}-{1929,100,100}-{1937,100,100}-{2313,100,100}-{1887,100,100}-{590,100,100}-{1735,100,100}-{1951,100,100}-{1969,100,100}-{1949,100,100}" + }, + { + "npcs": "4248", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "236", + "title": "Keldagrim Stonemason", + "stock": "{3420,500,100}-{8786,30,100}-{8784,30,100}-{8788,30,100}" + }, + { + "npcs": "4856", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "237", + "title": "Lovecraft's Tackle", + "stock": "{303,10,100}-{307,10,100}-{309,10,100}-{311,1000,100}-{301,10,100}-{313,1000,100}-{314,1000,100}-{317,0,100}-{327,10,100}-{345,0,100}-{321,0,100}-{335,0,100}-{349,0,100}-{331,0,100}-{359,0,100}-{377,0,100}-{371,0,100}" + }, + { + "npcs": "5484", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "238", + "title": "Flosi's Fishmongers", + "stock": "{377,5,100}-{359,20,100}-{331,20,100}-{341,20,100}-{383,0,100}" + }, + { + "npcs": "5495", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "239", + "title": "Contraband yak produce.", + "stock": "{10818,25,100}-{10816,50,100}-{10814,50,100}-{10820,10,100}" + }, + { + "npcs": "1163,1164", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "240", + "title": "Tiadeche's Karambwan Stall", + "stock": "{3142,10,100}-{3157,10,100}" + }, + { + "npcs": "", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "241", + "title": "Wishing Well", + "stock": "{12204,10,100}-{12207,10,100}-{12210,0,100}-{12213,0,100}-{12216,0,100}-{12219,0,100}-{12222,0,100}-{12183,65000,100}-{12155,5000,100}" + }, + { + "npcs": "4965", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "242", + "title": "Leprechaun Larry's Farming Supplies.", + "stock": "{5341,10,100}-{5343,10,100}-{5329,10,100}-{952,10,100}-{5325,10,100}-{5331,10,100}-{1925,10,100}-{6036,10,100}-{2026,10,100}-{1480,10,100}" + }, + { + "npcs": "849", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "243", + "title": "Blurberry Bar", + "stock": "{2028,10,100}-{2030,10,100}-{2032,10,100}-{2034,10,100}-{2036,10,100}-{2038,10,100}-{2040,10,100}" + }, + { + "npcs": "2565", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "244", + "title": "The Armour Store", + "stock": "{1147,0,100}-{1163,0,100}-{1127,0,100}-{1093,0,100}-{1185,0,100}-{1201,0,100}-{1113,0,100}-{1079,0,100}-{1145,0,100}-{1161,0,100}-{1123,0,100}-{1091,0,100}-{1183,0,100}-{1199,0,100}-{1111,0,100}-{1073,0,100}-{1143,0,100}-{1159,0,100}-{1121,0,100}-{1085,0,100}-{1181,0,100}-{1197,0,100}-{1109,0,100}-{1071,0,100}" + }, + { + "npcs": "7048", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "245", + "title": "Gift Shop", + "stock": "{590,10,100}-{2866,100,100}-{2878,10,100}-{314,1000,100}-{1351,10,100}-{954,10,100}-{1931,30,100}-{1925,30,100}-{2347,10,100}-{946,10,100}-{12561,10,100}-{12563,10,100}-{12565,0,100}-{12567,0,100}-{12568,0,100}-{12559,0,100}-{12570,0,100}" + }, + { + "npcs": "3923", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "246", + "title": "Miscellanian Food Shop", + "stock": "{2309,5,100}-{1985,5,100}-{1965,5,100}-{1942,5,100}-{1957,5,100}-{1933,5,100}-{1973,5,100}-{1927,5,100}" + }, + { + "npcs": "3920", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "247", + "title": "The Esoterican Arms", + "stock": "{1917,10,100}-{5763,10,100}-{1993,5,100}-{1798,5,100}" + }, + { + "npcs": "1383,3921", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "248", + "title": "Miscellanian Clothes Shop", + "stock": "{3767,5,100}-{3769,5,100}-{3771,5,100}-{3773,5,100}-{3775,5,100}-{3795,5,100}-{5050,3,100}-{5052,3,100}-{5038,3,100}-{5040,3,100}-{5044,3,100}-{5046,3,100}-{5026,3,100}-{5028,3,100}-{5032,3,100}-{5034,3,100}" + }, + { + "npcs": "1393", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "249", + "title": "Island Fishmonger", + "stock": "{303,5,100}-{307,5,100}-{309,5,100}-{311,2,100}-{301,2,100}-{313,1500,100}-{314,1000,100}-{305,5,100}-{317,0,100}-{325,200,100}-{345,0,100}-{353,0,100}-{341,0,100}-{321,0,100}-{335,0,100}-{349,0,100}-{331,0,100}-{359,0,100}-{377,0,100}-{363,0,100}-{371,0,100}-{383,0,100}" + }, + { + "npcs": "1394", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "250", + "title": "Greengrocer of Miscellania", + "stock": "{1965,10,100}-{1942,10,100}-{1957,10,100}-{1982,10,100}-{1550,2,100}" + }, + { + "npcs": "932", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "251", + "title": "Legends Guild General Store", + "stock": "{373,20,100}-{2323,5,100}-{121,3,100}-{886,500,100}" + }, + { + "npcs": "3161", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "252", + "title": "Two Feet Charley's Fish Shop", + "stock": "{317,10,100}-{327,10,100}-{345,10,100}-{353,10,100}-{341,10,100}-{321,10,100}-{359,0,100}-{377,0,100}-{363,0,100}" + }, + { + "npcs": "1316", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "253", + "title": "Fremennik Fur Trader", + "stock": "{948,10,100}-{958,10,100}-{10117,0,100}-{10121,0,100}-{10119,0,100}-{10123,0,100}-{10093,0,100}-{10095,0,100}-{10097,0,100}-{10099,0,100}-{10101,0,100}-{10103,0,100}" + }, + { + "npcs": "", + "high_alch": "0", + "currency": "6306", + "general_store": "false", + "id": "254", + "title": "Gabooty's Tai Bwo Wannai Drinky Store", + "stock": "{2084,0,100}-{2092,0,100}-{2048,0,100}-{2054,0,100}-{2064,0,100}-{2074,0,100}" + }, + { + "npcs": "1526", + "high_alch": "0", + "currency": "4067", + "general_store": "false", + "id": "255", + "title": "Castle Wars Ticket Exchange", + "stock": "{4068,1,100}-{4069,1,100}-{4070,1,100}-{4071,1,100}-{4072,1,100}-{4503,1,100}-{4504,1,100}-{4505,1,100}-{4506,1,100}-{4507,1,100}-{4508,1,100}-{4509,1,100}-{4510,1,100}-{4511,1,100}-{4512,1,100}-{4513,1,100}-{4514,1,100}-{4515,1,100}-{4516,1,100}" + }, + { + "npcs": "5111", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "256", + "title": "Leon's Prototype Crossbow", + "stock": "{10156,2,100}" + }, + { + "npcs": "2039", + "high_alch": "0", + "currency": "995", + "general_store": "false", + "id": "256", + "title": "Uglug's Stuffsies", + "stock": "{4844,100,10}-{10927,0,100}-{2862,100,100}-{1777,10,200}-{2876,0,500}-{2878,10,100}-{4850,0,100}-{946,5,100}-{4773,0,1000}-{4778,0,1000}-{4783,0,1000}-{4788,0,1500}-{4793,0,2000}-{4798,0,3000}-{4803,0,4000}-{4827,0,2000}" + } +] \ No newline at end of file diff --git a/Server/data/configs/varbit_definitions.json b/Server/data/configs/varbit_definitions.json new file mode 100644 index 0000000..720b167 --- /dev/null +++ b/Server/data/configs/varbit_definitions.json @@ -0,0 +1,19 @@ +[ + { + "description": "Bank insert mode", + + "varpId": "304", + "varbitId": "7000", + "startBit": "0", + "endBit": "0" + }, + + { + "description": "Bank note mode", + + "varpId": "115", + "varbitId": "7001", + "startBit": "0", + "endBit": "0" + } +] \ No newline at end of file diff --git a/Server/data/configs/xteas.json b/Server/data/configs/xteas.json new file mode 100644 index 0000000..5b8de21 --- /dev/null +++ b/Server/data/configs/xteas.json @@ -0,0 +1,4492 @@ +{ + "xteas": [ + { + "regionId": "6234", + "keys": "-1591922206,-1429764510,-1087339341,1592935185" + }, + { + "regionId": "6473", + "keys": "-895585464,-461480444,-1851545592,-837241102" + }, + { + "regionId": "6475", + "keys": "779607549,1253385498,-2146148208,-1240685073" + }, + { + "regionId": "6483", + "keys": "14881828,-6662814,58238456,146761213" + }, + { + "regionId": "6487", + "keys": "-844708758,693908396,-1724237422,-2131620302" + }, + { + "regionId": "6488", + "keys": "-285330291,1051990177,205476286,1929287225" + }, + { + "regionId": "6489", + "keys": "1563065045,-1659976681,-1630140039,908238605" + }, + { + "regionId": "6722", + "keys": "1365340377,429184662,-767507159,-1766554953" + }, + { + "regionId": "6725", + "keys": "-798347038,29419308,-1054119992,193134650" + }, + { + "regionId": "6726", + "keys": "-3492110,65044555,1450623668,-483811536" + }, + { + "regionId": "6741", + "keys": "-1634995791,710519356,-47126463,-1180416882" + }, + { + "regionId": "6743", + "keys": "-1239303400,-1604922847,-1532369005,982307785" + }, + { + "regionId": "6744", + "keys": "-496944733,-779028234,-230846664,150558918" + }, + { + "regionId": "6745", + "keys": "365190378,-1767339898,2011432030,276148826" + }, + { + "regionId": "6985", + "keys": "1193572731,-1288765743,-386862979,351599890" + }, + { + "regionId": "6989", + "keys": "-891749173,-113432144,-1228601828,695082558" + }, + { + "regionId": "6991", + "keys": "-1448188175,626198836,1985989165,-1062391664" + }, + { + "regionId": "6992", + "keys": "793817707,983201574,1970817843,1370732667" + }, + { + "regionId": "6993", + "keys": "-932618963,243797238,-1433505613,-236523555" + }, + { + "regionId": "6994", + "keys": "1970708736,-245310471,1179446032,-620283247" + }, + { + "regionId": "6995", + "keys": "-1227889203,-199624313,2143494494,531356102" + }, + { + "regionId": "7001", + "keys": "170738852,2045755396,-1580637869,-1933392334" + }, + { + "regionId": "7236", + "keys": "570290255,-1513898184,-1269691884,782850050" + }, + { + "regionId": "7238", + "keys": "-853120516,1697831503,-12188711,770411534" + }, + { + "regionId": "7244", + "keys": "796665731,1335649913,758227393,585095755" + }, + { + "regionId": "7247", + "keys": "-122734679,-1029771956,1633683499,846700218" + }, + { + "regionId": "7248", + "keys": "-339349863,-706006976,1444664020,-668854242" + }, + { + "regionId": "7249", + "keys": "104968959,1007983047,-1342360496,1832152849" + }, + { + "regionId": "7250", + "keys": "497663526,-1258315657,-785166329,-999527877" + }, + { + "regionId": "7492", + "keys": "417150556,1135530200,2139696777,-742314409" + }, + { + "regionId": "7494", + "keys": "-1653750072,103282771,384178856,1122166637" + }, + { + "regionId": "7496", + "keys": "-1890766195,-149577199,919306397,-954784877" + }, + { + "regionId": "7499", + "keys": "-2007696984,-1215288615,-1572330641,-2125382604" + }, + { + "regionId": "7500", + "keys": "-1797612105,-469426862,-1728147007,-646639650" + }, + { + "regionId": "7501", + "keys": "2127797097,-994429649,-35298241,-1340339542" + }, + { + "regionId": "7502", + "keys": "1592232730,1693978666,-878012906,867925201" + }, + { + "regionId": "7503", + "keys": "-895717823,-2040871288,1280251884,-1205523998" + }, + { + "regionId": "7504", + "keys": "-1824142464,-1651867367,-1541058541,-1034512274" + }, + { + "regionId": "7505", + "keys": "-1177354806,-1864641630,23736540,750869235" + }, + { + "regionId": "7507", + "keys": "-1476331852,1093075535,-2003580146,734573751" + }, + { + "regionId": "7508", + "keys": "1640963123,1896768721,879048302,-1776414657" + }, + { + "regionId": "7509", + "keys": "-1575412129,-1725410171,-2003328048,1050396588" + }, + { + "regionId": "7510", + "keys": "2073894230,-553352720,274325814,-1461052837" + }, + { + "regionId": "7511", + "keys": "14881828,-6662814,58238456,146761213" + }, + { + "regionId": "7513", + "keys": "1066375195,548376104,-1771348528,1096433429" + }, + { + "regionId": "7745", + "keys": "1212560091,-662504525,-1213494614,-1245629284" + }, + { + "regionId": "7748", + "keys": "-850453392,-249468744,1635462867,100471784" + }, + { + "regionId": "7749", + "keys": "369356966,-1038198212,282112206,802717032" + }, + { + "regionId": "7752", + "keys": "1894158557,20416613,-1434347651,-1209846311" + }, + { + "regionId": "7753", + "keys": "2071150318,-1033460657,638407631,1622436805" + }, + { + "regionId": "7754", + "keys": "-1095536942,-1766628646,-829395519,716805082" + }, + { + "regionId": "7755", + "keys": "251339001,946355543,-1190230098,1528548224" + }, + { + "regionId": "7756", + "keys": "906056473,-2135922837,-855754671,-503357515" + }, + { + "regionId": "7757", + "keys": "-103936636,-6150806,-1262632665,1507740731" + }, + { + "regionId": "7758", + "keys": "1989884300,237012546,22566346,1351365126" + }, + { + "regionId": "7759", + "keys": "645523546,1835996818,-892497478,-366414132" + }, + { + "regionId": "7760", + "keys": "2042192998,743878512,-1804236758,-1160501924" + }, + { + "regionId": "7763", + "keys": "14881828,-6662814,58238456,146761213" + }, + { + "regionId": "7769", + "keys": "560280774,910095015,871073102,263015376" + }, + { + "regionId": "8001", + "keys": "690512367,1578449236,-1443501555,546253393" + }, + { + "regionId": "8002", + "keys": "1597309277,469931771,1619035792,663887748" + }, + { + "regionId": "8004", + "keys": "609107948,-755432209,-723012522,1175820911" + }, + { + "regionId": "8005", + "keys": "1334074196,-652454149,1601317454,469562426" + }, + { + "regionId": "8006", + "keys": "-148570664,-1136658706,-1902631968,-1188445291" + }, + { + "regionId": "8008", + "keys": "-997738189,-1761742229,-1676854941,-885390031" + }, + { + "regionId": "8009", + "keys": "-1466175704,351054294,-1150290302,-1555608739" + }, + { + "regionId": "8010", + "keys": "-120476958,772788582,297461207,-245665438" + }, + { + "regionId": "8011", + "keys": "1990004495,747113508,324107547,-123628033" + }, + { + "regionId": "8012", + "keys": "-207206478,596983639,-1721843709,-1184583849" + }, + { + "regionId": "8013", + "keys": "1846865793,1272334140,-253842269,-2073715507" + }, + { + "regionId": "8014", + "keys": "-1279878558,-211098870,431176504,-1619319528" + }, + { + "regionId": "8015", + "keys": "305015825,-634097708,865786116,-1850059578" + }, + { + "regionId": "8017", + "keys": "959968310,-363819769,-1402232275,-1678358818" + }, + { + "regionId": "8019", + "keys": "-1512999074,1064201012,2143076355,-1937376726" + }, + { + "regionId": "8021", + "keys": "-297039986,-1011877372,-1763869337,-900998253" + }, + { + "regionId": "8022", + "keys": "14881828,-6662814,58238456,146761213" + }, + { + "regionId": "8025", + "keys": "400525614,1883669529,-440182999,-357730578" + }, + { + "regionId": "8240", + "keys": "2101719552,-225162086,293186389,-162955969" + }, + { + "regionId": "8241", + "keys": "-320813650,-1654452876,-352291520,-290946896" + }, + { + "regionId": "8242", + "keys": "347990635,-1017326068,-1600504696,1565374916" + }, + { + "regionId": "8243", + "keys": "-107199068,-843304946,910528064,-626516712" + }, + { + "regionId": "8251", + "keys": "1142567601,1650263019,49659607,-899246535" + }, + { + "regionId": "8252", + "keys": "-428244729,-903477551,-931984389,-583689232" + }, + { + "regionId": "8253", + "keys": "1274757849,1788985771,-1066826733,223495957" + }, + { + "regionId": "8254", + "keys": "-2072640345,1256455304,497449669,1898688910" + }, + { + "regionId": "8256", + "keys": "-591763830,-48757057,1738175039,232723115" + }, + { + "regionId": "8260", + "keys": "-357122149,-546918388,1659548066,2023267334" + }, + { + "regionId": "8261", + "keys": "14881828,-6662814,58238456,146761213" + }, + { + "regionId": "8262", + "keys": "937196178,1968517712,1697292009,-2036678778" + }, + { + "regionId": "8263", + "keys": "-1251027771,-846995999,1156602771,-1922080053" + }, + { + "regionId": "8264", + "keys": "-1819872894,1038324305,1342314979,-1220415324" + }, + { + "regionId": "8265", + "keys": "1850912058,-559075374,924054405,-1595809620" + }, + { + "regionId": "8266", + "keys": "-1571771132,-1956678912,-454057689,65399733" + }, + { + "regionId": "8267", + "keys": "-474856962,-1295973639,789657650,-1769058462" + }, + { + "regionId": "8269", + "keys": "-497435078,2028988145,486156819,-1178938803" + }, + { + "regionId": "8270", + "keys": "832265044,-1682160790,1376131373,1516015571" + }, + { + "regionId": "8271", + "keys": "2011499665,-1820626075,-1349106171,1373054648" + }, + { + "regionId": "8272", + "keys": "-279193034,-753054903,626747605,-1887843183" + }, + { + "regionId": "8273", + "keys": "978831670,664328414,1943273766,-1823800887" + }, + { + "regionId": "8280", + "keys": "-1615836970,1947387796,2141672540,-333423400" + }, + { + "regionId": "8282", + "keys": "981025536,812353111,-688221351,-284141633" + }, + { + "regionId": "8496", + "keys": "-1397271211,-1829692174,-1138445890,-1384844481" + }, + { + "regionId": "8497", + "keys": "2127424498,1622469596,-1889017351,-1927651722" + }, + { + "regionId": "8498", + "keys": "-1323684593,-1102390619,1456317314,-2027993898" + }, + { + "regionId": "8499", + "keys": "1158999293,2131770333,-861122128,1149793504" + }, + { + "regionId": "8506", + "keys": "-1227747958,1491928866,1293676120,2065870654" + }, + { + "regionId": "8507", + "keys": "1765022148,-80255262,-725852452,-1286377093" + }, + { + "regionId": "8508", + "keys": "-2081560462,-761421769,-880257396,-1678043286" + }, + { + "regionId": "8509", + "keys": "1177709231,-1828086540,-860279535,2071959242" + }, + { + "regionId": "8510", + "keys": "-1808638230,-1458952839,-798099535,1502725514" + }, + { + "regionId": "8514", + "keys": "-860052712,1822870800,-1847449751,-1914055926" + }, + { + "regionId": "8518", + "keys": "2036940233,1361257283,-1629264154,-858326595" + }, + { + "regionId": "8519", + "keys": "-2051430502,-746663069,-593970049,379050420" + }, + { + "regionId": "8520", + "keys": "76118065,2000660952,-1441067939,-1293828961" + }, + { + "regionId": "8521", + "keys": "-118666576,-7617915,708835107,-449427634" + }, + { + "regionId": "8522", + "keys": "-1916075284,1880898106,-1618113268,464036603" + }, + { + "regionId": "8523", + "keys": "-1203368702,359745318,-2127031319,-1802364988" + }, + { + "regionId": "8524", + "keys": "37036095,-259799144,-1679313180,74723020" + }, + { + "regionId": "8525", + "keys": "1128073531,987906789,1511073840,455662935" + }, + { + "regionId": "8526", + "keys": "17223090,-1297369957,1547271072,-1038573542" + }, + { + "regionId": "8527", + "keys": "1802043449,1098466035,-1011563733,-1036725278" + }, + { + "regionId": "8528", + "keys": "-1141049958,1626814655,206252937,924426084" + }, + { + "regionId": "8529", + "keys": "2008179575,1983086010,22167022,2114412614" + }, + { + "regionId": "8530", + "keys": "-1466808210,962381183,-1581244207,-457271917" + }, + { + "regionId": "8532", + "keys": "1553260654,1996107908,-2124357970,1441816370" + }, + { + "regionId": "8534", + "keys": "1712031920,299813553,484205392,-939092911" + }, + { + "regionId": "8752", + "keys": "238354066,1687454525,1494747147,1911377137" + }, + { + "regionId": "8753", + "keys": "-2045400446,-157254916,-1938039698,1143548881" + }, + { + "regionId": "8754", + "keys": "576590945,726748596,-159128087,905509251" + }, + { + "regionId": "8755", + "keys": "-1165798584,772244190,-402783978,541755309" + }, + { + "regionId": "8761", + "keys": "1760753095,-1427813077,266675077,-255782653" + }, + { + "regionId": "8762", + "keys": "-1868090282,-1544166661,-731821081,1736861342" + }, + { + "regionId": "8763", + "keys": "1119677832,690614046,2050117701,105876696" + }, + { + "regionId": "8764", + "keys": "1880374454,1213514336,-2078057600,-2021473694" + }, + { + "regionId": "8765", + "keys": "1948979312,134066799,-78879371,-323055687" + }, + { + "regionId": "8766", + "keys": "1244410566,-1397143615,-1848205088,-1435723900" + }, + { + "regionId": "8767", + "keys": "-368125809,-1805271492,-400403765,697149536" + }, + { + "regionId": "8768", + "keys": "-517024281,-1363386333,227729042,-1950025355" + }, + { + "regionId": "8769", + "keys": "2044453226,-2064473213,1306128347,784973817" + }, + { + "regionId": "8770", + "keys": "2057744615,1697537962,528178774,-1047470804" + }, + { + "regionId": "8771", + "keys": "353086160,838307611,374264785,-686519866" + }, + { + "regionId": "8774", + "keys": "1016149511,-1118500660,-968978308,486472340" + }, + { + "regionId": "8775", + "keys": "-147836833,971452977,1498176968,-231259499" + }, + { + "regionId": "8776", + "keys": "-1754587844,664188970,-1128425220,59583193" + }, + { + "regionId": "8777", + "keys": "-137310003,1329143043,-669559936,-1913927786" + }, + { + "regionId": "8778", + "keys": "2142407721,-1514375765,1855937572,220818342" + }, + { + "regionId": "8779", + "keys": "-1680845199,-1149954104,-1177525481,-576614197" + }, + { + "regionId": "8781", + "keys": "-2133721491,843228961,1706232103,-934369964" + }, + { + "regionId": "8782", + "keys": "-1567987347,-2104385976,443181406,-256058951" + }, + { + "regionId": "8783", + "keys": "412947427,-974210888,817804533,712249271" + }, + { + "regionId": "8784", + "keys": "-460994736,1511026573,402950670,-6026193" + }, + { + "regionId": "8785", + "keys": "1543774040,-487517297,-1630373503,102220753" + }, + { + "regionId": "8787", + "keys": "1791798624,-1711313280,166719404,-1487207913" + }, + { + "regionId": "8790", + "keys": "230755787,-1139640838,-21592892,49661984" + }, + { + "regionId": "9008", + "keys": "2084752401,-1394447522,2084945842,1474596929" + }, + { + "regionId": "9009", + "keys": "898432013,1464425485,1479297637,1732705669" + }, + { + "regionId": "9010", + "keys": "1362096653,746663700,338872870,9791230" + }, + { + "regionId": "9011", + "keys": "-135370293,700991137,-1302596410,-1183796338" + }, + { + "regionId": "9012", + "keys": "1204696185,-486414605,-1016110497,134649113" + }, + { + "regionId": "9016", + "keys": "-1274221467,730617286,-1448054569,427043430" + }, + { + "regionId": "9017", + "keys": "-518439975,-1388520826,203536985,1155539914" + }, + { + "regionId": "9018", + "keys": "-116231890,2037305449,-518154118,43034164" + }, + { + "regionId": "9019", + "keys": "-1293726217,-1696419000,-859948399,1059527576" + }, + { + "regionId": "9020", + "keys": "-1906040194,849367381,2098246444,1605043698" + }, + { + "regionId": "9021", + "keys": "-665917952,-432697139,-602494723,-2097936281" + }, + { + "regionId": "9022", + "keys": "1910381678,352194237,836248,347278834" + }, + { + "regionId": "9024", + "keys": "-785865296,-520648067,-1207176889,-441641818" + }, + { + "regionId": "9025", + "keys": "1812159970,1795526437,1172074678,289074337" + }, + { + "regionId": "9026", + "keys": "-788500037,-1522730757,-651789033,304659146" + }, + { + "regionId": "9027", + "keys": "-2144855461,-75930625,1875031025,-2116300819" + }, + { + "regionId": "9032", + "keys": "-828656936,1072022787,-640768629,-1761240236" + }, + { + "regionId": "9033", + "keys": "-1516886192,1081198982,-1267611367,-339961975" + }, + { + "regionId": "9034", + "keys": "1874260326,1014701729,745849790,-1354790160" + }, + { + "regionId": "9035", + "keys": "1525685385,1372975156,-2010144170,-1594192581" + }, + { + "regionId": "9038", + "keys": "-473165893,2110570897,-1726275929,806180444" + }, + { + "regionId": "9044", + "keys": "1541894861,-2145670115,-138793212,-921922364" + }, + { + "regionId": "9045", + "keys": "1041036316,-2144924275,-1062048066,755505347" + }, + { + "regionId": "9046", + "keys": "1823337636,645784236,428459555,987429760" + }, + { + "regionId": "9048", + "keys": "-2078486774,831084557,-1515890598,-396794300" + }, + { + "regionId": "9049", + "keys": "1865420136,1880907821,-543917600,1097363521" + }, + { + "regionId": "9050", + "keys": "-1725663967,1678055280,1100896300,706957861" + }, + { + "regionId": "9113", + "keys": "-570298090,-864625293,-668545435,8389096" + }, + { + "regionId": "9114", + "keys": "-962790446,-1706163576,82969599,310163719" + }, + { + "regionId": "9262", + "keys": "-1327237404,-257519940,-1398355053,-970581711" + }, + { + "regionId": "9263", + "keys": "-1896898351,81121501,787229912,-904856097" + }, + { + "regionId": "9264", + "keys": "1517876710,1288106006,-319745194,1340771706" + }, + { + "regionId": "9265", + "keys": "1050111381,-276500917,1975172977,329246991" + }, + { + "regionId": "9266", + "keys": "2007797925,-1715573299,642190072,-662957526" + }, + { + "regionId": "9267", + "keys": "1811361377,-1208567174,103788086,-225339394" + }, + { + "regionId": "9268", + "keys": "1897267086,556470475,-1130589672,-743996492" + }, + { + "regionId": "9269", + "keys": "-1228579055,-1634436411,181074707,1831294115" + }, + { + "regionId": "9270", + "keys": "-1224224741,1755403824,128170045,498510702" + }, + { + "regionId": "9271", + "keys": "-875378602,-1077772187,594715960,-738079672" + }, + { + "regionId": "9272", + "keys": "-1755813275,373737884,1517748428,738184348" + }, + { + "regionId": "9273", + "keys": "-503076140,-319114908,-1349219228,1465453758" + }, + { + "regionId": "9274", + "keys": "1831263162,2092992846,-1206288816,831074245" + }, + { + "regionId": "9275", + "keys": "-350994118,-585442377,-1041480219,-1986244402" + }, + { + "regionId": "9276", + "keys": "-1624253043,1426176358,210641208,773759029" + }, + { + "regionId": "9277", + "keys": "272801923,1797149371,-131972865,1265002008" + }, + { + "regionId": "9278", + "keys": "-1782196006,1021278723,887209787,-1016997291" + }, + { + "regionId": "9279", + "keys": "-841578670,318269186,-353500843,-932268603" + }, + { + "regionId": "9280", + "keys": "727010382,181752242,1033156911,1262921484" + }, + { + "regionId": "9285", + "keys": "1742241898,-1564206342,-460725435,1614032789" + }, + { + "regionId": "9287", + "keys": "-272431907,639665846,-1633276264,1645937141" + }, + { + "regionId": "9288", + "keys": "1322101455,-912043509,-514354639,-977254423" + }, + { + "regionId": "9289", + "keys": "-1520212935,995884312,481657690,-9846292" + }, + { + "regionId": "9290", + "keys": "702687456,43635181,-1983533012,-319469910" + }, + { + "regionId": "9293", + "keys": "-810831340,-1857428683,-892017185,249052010" + }, + { + "regionId": "9294", + "keys": "990154613,2143262288,2039829180,-2089104408" + }, + { + "regionId": "9295", + "keys": "224580924,-858933614,-432602901,-1433710083" + }, + { + "regionId": "9297", + "keys": "-1667110403,-655319123,-2124588845,-262291671" + }, + { + "regionId": "9300", + "keys": "644587156,-605721698,681391959,1688865408" + }, + { + "regionId": "9304", + "keys": "14881828,-6662814,58238456,146761213" + }, + { + "regionId": "9305", + "keys": "14881828,-6662814,58238456,146761213" + }, + { + "regionId": "9306", + "keys": "1213624565,1443323179,2068217235,-1098243446" + }, + { + "regionId": "9362", + "keys": "-253025041,376209206,1663580032,1115549308" + }, + { + "regionId": "9364", + "keys": "1350964684,-1141243546,-158288919,1853454502" + }, + { + "regionId": "9365", + "keys": "591308830,1667019329,-1039629756,738471651" + }, + { + "regionId": "9366", + "keys": "-1691974727,-1591730841,1506117200,822346809" + }, + { + "regionId": "9368", + "keys": "-911562498,-1433720091,257702084,1652121807" + }, + { + "regionId": "9369", + "keys": "404061599,492688035,-1416873270,2021546702" + }, + { + "regionId": "9370", + "keys": "1867571226,-1557589414,74894252,-1402573358" + }, + { + "regionId": "9371", + "keys": "-1625040094,1138785379,-41923493,400034327" + }, + { + "regionId": "9372", + "keys": "1005996231,-569567890,-1578994771,-1136932414" + }, + { + "regionId": "9377", + "keys": "-1671261866,-750153286,1731026368,-1501269926" + }, + { + "regionId": "9518", + "keys": "-557639005,398566091,-133936467,-850662847" + }, + { + "regionId": "9519", + "keys": "2045915867,843943848,1479393319,61248459" + }, + { + "regionId": "9520", + "keys": "-1534254084,-142177068,838351559,798595528" + }, + { + "regionId": "9521", + "keys": "-1756008730,1701620533,-579278885,1205797104" + }, + { + "regionId": "9522", + "keys": "1252542168,-1448059709,1122042436,-1636001244" + }, + { + "regionId": "9523", + "keys": "-1310187207,-834726064,-1799766719,1699616161" + }, + { + "regionId": "9524", + "keys": "-1209775078,-1209251210,-1747509150,90457302" + }, + { + "regionId": "9525", + "keys": "273717513,1026318281,-1648631650,-2024237038" + }, + { + "regionId": "9526", + "keys": "-946191110,746761324,810538817,107990300" + }, + { + "regionId": "9527", + "keys": "1148278078,-266468530,-243084816,-1561247930" + }, + { + "regionId": "9528", + "keys": "2102113094,1056838948,-1779359269,700318930" + }, + { + "regionId": "9529", + "keys": "727060780,-652255702,-1555170272,-2145386007" + }, + { + "regionId": "9530", + "keys": "-932232860,436123389,-658931046,2094924060" + }, + { + "regionId": "9531", + "keys": "-1745155259,444744719,2018327862,2021464472" + }, + { + "regionId": "9532", + "keys": "-1164282027,-620126230,1487448896,565185597" + }, + { + "regionId": "9533", + "keys": "1393307887,646464303,-1582337843,2048412434" + }, + { + "regionId": "9534", + "keys": "-2072244370,1114739695,-1096608867,-1932870993" + }, + { + "regionId": "9535", + "keys": "-1107428972,531677783,-1575581308,1343828898" + }, + { + "regionId": "9536", + "keys": "679931979,-1660801436,-1184954844,-1006016912" + }, + { + "regionId": "9539", + "keys": "-96476891,-1518725637,-1983538368,1621232019" + }, + { + "regionId": "9540", + "keys": "-489788621,2021133858,244677479,1058347252" + }, + { + "regionId": "9541", + "keys": "1352006827,1096305726,805420370,-1426885864" + }, + { + "regionId": "9543", + "keys": "1852273964,-104833248,-2069080639,-188650169" + }, + { + "regionId": "9544", + "keys": "-2013112418,-1715158159,1261185685,1357880927" + }, + { + "regionId": "9545", + "keys": "1322297584,105544016,-1148309508,-574484176" + }, + { + "regionId": "9546", + "keys": "-257183655,-1481577287,-431332303,-242811730" + }, + { + "regionId": "9547", + "keys": "-1998382641,30700550,1548517068,-855708219" + }, + { + "regionId": "9549", + "keys": "-1648136735,1402264941,639592027,348907048" + }, + { + "regionId": "9550", + "keys": "795472733,-1836130665,-1594549016,884470590" + }, + { + "regionId": "9551", + "keys": "-355590781,-1549463073,-46968616,648246695" + }, + { + "regionId": "9552", + "keys": "1925832709,39840626,683796237,-766329117" + }, + { + "regionId": "9553", + "keys": "-1873675730,-1930195432,759400017,-1395479956" + }, + { + "regionId": "9556", + "keys": "-300312374,-1152515846,-863452271,-1500855067" + }, + { + "regionId": "9558", + "keys": "1245928204,-1892089406,-1321168410,-1108146443" + }, + { + "regionId": "9560", + "keys": "-628764335,1585475717,2036165620,-1921088167" + }, + { + "regionId": "9561", + "keys": "1291655395,-1426986127,1894534662,-1705749378" + }, + { + "regionId": "9562", + "keys": "-1047298777,1197811918,663745433,-2098029011" + }, + { + "regionId": "9620", + "keys": "1941157140,-1630547377,-1114648519,87057467" + }, + { + "regionId": "9621", + "keys": "-1420915988,2069137101,1981379143,-252845225" + }, + { + "regionId": "9622", + "keys": "124513614,453662882,-154905102,-2103796118" + }, + { + "regionId": "9623", + "keys": "496891811,1091959696,690916089,588310866" + }, + { + "regionId": "9624", + "keys": "-1327451949,-476085243,-125348987,634827214" + }, + { + "regionId": "9625", + "keys": "632876038,913599309,1089335965,728823985" + }, + { + "regionId": "9626", + "keys": "-1411729186,1049744836,-1608961973,-1681145313" + }, + { + "regionId": "9631", + "keys": "1266963397,269916041,734658458,725243574" + }, + { + "regionId": "9632", + "keys": "1023657558,-2001662423,-46679010,2064543607" + }, + { + "regionId": "9772", + "keys": "-1742165439,-1273697376,2055229018,901215817" + }, + { + "regionId": "9773", + "keys": "465644643,-503279415,-1368947935,-1293998544" + }, + { + "regionId": "9774", + "keys": "-969323176,1775448370,1827500666,-2138545804" + }, + { + "regionId": "9775", + "keys": "1009031775,1977305970,-699602333,1802690745" + }, + { + "regionId": "9776", + "keys": "2000999142,205577043,-1417782040,-218453463" + }, + { + "regionId": "9777", + "keys": "821512120,-1253173249,-1078446427,-122269601" + }, + { + "regionId": "9778", + "keys": "85368686,-1059751721,-1008551161,-454427033" + }, + { + "regionId": "9779", + "keys": "-1158828855,-293580830,713180736,762257070" + }, + { + "regionId": "9780", + "keys": "-2067572823,-571539672,-976614369,-2016221403" + }, + { + "regionId": "9781", + "keys": "-2124931990,-1174347052,-1107047767,-1503661911" + }, + { + "regionId": "9782", + "keys": "963803363,-1625577381,-1515560012,797000049" + }, + { + "regionId": "9783", + "keys": "1785268065,-1215473770,1311222217,-1445453250" + }, + { + "regionId": "9784", + "keys": "1874487660,1635569708,-1949316626,-1920350613" + }, + { + "regionId": "9785", + "keys": "-65486938,-1485596203,-1327236566,408455718" + }, + { + "regionId": "9786", + "keys": "-2073791326,-155318773,-116282245,-1424900475" + }, + { + "regionId": "9787", + "keys": "218097749,1242681128,-2014981896,1175992711" + }, + { + "regionId": "9788", + "keys": "432135203,92254316,-1619550296,76065412" + }, + { + "regionId": "9789", + "keys": "-620749099,528872615,1976629038,667155751" + }, + { + "regionId": "9791", + "keys": "-2105683947,1913166182,-1697741730,-25818496" + }, + { + "regionId": "9792", + "keys": "1500471532,1729075639,-304984137,1117230148" + }, + { + "regionId": "9794", + "keys": "1788083183,2097372895,1633476682,-589223611" + }, + { + "regionId": "9796", + "keys": "517509106,-2019799796,1066150754,-676371780" + }, + { + "regionId": "9797", + "keys": "672333395,-284721288,262558790,-344798491" + }, + { + "regionId": "9799", + "keys": "181886191,758691911,810524169,1456599388" + }, + { + "regionId": "9800", + "keys": "1230198769,708911105,-539692192,1126153482" + }, + { + "regionId": "9801", + "keys": "-1411921732,1651102545,-1826113310,-859079982" + }, + { + "regionId": "9802", + "keys": "209485096,602940753,2048389198,1202197220" + }, + { + "regionId": "9803", + "keys": "-1262437179,-1086288107,1393145472,-1318086655" + }, + { + "regionId": "9804", + "keys": "-439033034,-361310510,37875158,-1700152748" + }, + { + "regionId": "9805", + "keys": "-2114807953,-1293116867,-1013807366,-1068548578" + }, + { + "regionId": "9806", + "keys": "368995667,940146211,957819918,-761335591" + }, + { + "regionId": "9808", + "keys": "308766586,-214665927,-1255727041,-1034716346" + }, + { + "regionId": "9809", + "keys": "-128763363,653932339,-1040336001,-372452691" + }, + { + "regionId": "9810", + "keys": "-752844904,1782384595,1054043870,282233468" + }, + { + "regionId": "9811", + "keys": "-929935426,1005492936,-2143736251,386758357" + }, + { + "regionId": "9812", + "keys": "50571970,-1762921782,-1667424270,524742325" + }, + { + "regionId": "9814", + "keys": "-34428628,1940609264,-1638642159,-295486604" + }, + { + "regionId": "9874", + "keys": "-1211069631,-930191762,-1989737435,-1798369704" + }, + { + "regionId": "9875", + "keys": "991829915,-192761962,1424546941,2003334283" + }, + { + "regionId": "9876", + "keys": "1133268311,-1303891370,1138954157,-1069688346" + }, + { + "regionId": "9877", + "keys": "727463922,-941540275,874446728,-1678669133" + }, + { + "regionId": "9878", + "keys": "-664032051,-488667648,685343368,-1970848496" + }, + { + "regionId": "9879", + "keys": "921274725,1426716778,-1067082627,-1824724" + }, + { + "regionId": "9880", + "keys": "38957255,666017454,671177307,-803617279" + }, + { + "regionId": "9881", + "keys": "21755694,-1408974145,1341158791,-1638315086" + }, + { + "regionId": "9882", + "keys": "-440130527,495078969,2058162871,-510883365" + }, + { + "regionId": "9883", + "keys": "472234846,1198089044,500187071,239458328" + }, + { + "regionId": "9886", + "keys": "1515209815,-1457146379,-146402808,-1454274033" + }, + { + "regionId": "10027", + "keys": "1491811841,1724263915,-1397066186,1733646819" + }, + { + "regionId": "10029", + "keys": "203145796,-773666188,-569831878,-1510455793" + }, + { + "regionId": "10030", + "keys": "1533193920,-157056689,-1706395009,2060884310" + }, + { + "regionId": "10031", + "keys": "-1239300919,1798229092,-1044578379,493913447" + }, + { + "regionId": "10032", + "keys": "-855251381,1871716645,1835777659,2032052033" + }, + { + "regionId": "10033", + "keys": "1902138469,-641202141,715430361,2060827965" + }, + { + "regionId": "10034", + "keys": "-1435464304,-836439389,-788586899,1579582706" + }, + { + "regionId": "10036", + "keys": "689954852,-1377739344,-847433475,-1883927289" + }, + { + "regionId": "10037", + "keys": "914357934,960797390,753237255,-1274576207" + }, + { + "regionId": "10038", + "keys": "-10852366,551587390,-821401504,-1151814286" + }, + { + "regionId": "10039", + "keys": "2005404778,-1913619257,-2029034667,-276727853" + }, + { + "regionId": "10040", + "keys": "-691368982,1823514267,-284316500,-1573696560" + }, + { + "regionId": "10041", + "keys": "1187862613,-117754960,130411769,-1192628982" + }, + { + "regionId": "10042", + "keys": "-1666575192,2084626585,2023809342,-1587593937" + }, + { + "regionId": "10043", + "keys": "1912880022,-1723964516,2062562401,-1162129761" + }, + { + "regionId": "10044", + "keys": "1044974347,726311355,-917896013,-1659516255" + }, + { + "regionId": "10045", + "keys": "-1429464298,1580360509,-1936477065,-337842786" + }, + { + "regionId": "10046", + "keys": "1579643227,-1819574910,1035634488,-1469908551" + }, + { + "regionId": "10047", + "keys": "1248461784,913422340,-928862457,-1858877253" + }, + { + "regionId": "10048", + "keys": "-1457016886,349941309,-400267403,-1711584223" + }, + { + "regionId": "10055", + "keys": "-813287484,-1417786621,-1794468339,578992617" + }, + { + "regionId": "10056", + "keys": "799806902,-1359852248,484436692,-1205184204" + }, + { + "regionId": "10057", + "keys": "1308484583,-2063649066,898275176,-860496835" + }, + { + "regionId": "10058", + "keys": "-504878866,1988421643,-1036984650,513341227" + }, + { + "regionId": "10059", + "keys": "1185163869,-1047826729,-1461057337,139139001" + }, + { + "regionId": "10061", + "keys": "1683880127,1851133137,-567572662,-1477799312" + }, + { + "regionId": "10062", + "keys": "2024717410,-1807032706,1106507805,1426160484" + }, + { + "regionId": "10064", + "keys": "1978019309,1433546802,-1989346624,-1611361553" + }, + { + "regionId": "10065", + "keys": "924349786,-326314365,-2042125189,1066401699" + }, + { + "regionId": "10066", + "keys": "105954939,-1741244981,-1491777272,207112205" + }, + { + "regionId": "10068", + "keys": "-452138979,-1929816521,364996963,-1315825295" + }, + { + "regionId": "10069", + "keys": "-1669561589,-1287976882,1220187974,434661979" + }, + { + "regionId": "10070", + "keys": "337024788,-2037667137,-1229192681,72559338" + }, + { + "regionId": "10071", + "keys": "917431355,-1337694006,-1242762433,-1310804996" + }, + { + "regionId": "10073", + "keys": "-381328476,-448982838,1680944624,-2015809073" + }, + { + "regionId": "10074", + "keys": "-212532394,882343988,2089679345,-303180169" + }, + { + "regionId": "10075", + "keys": "14881828,-6662814,58238456,146761213" + }, + { + "regionId": "10129", + "keys": "-1418181074,-681458464,2135343677,-1473942322" + }, + { + "regionId": "10130", + "keys": "-672924254,-1112220382,1225279473,1100576994" + }, + { + "regionId": "10131", + "keys": "2085292062,228024419,1890298036,1347089957" + }, + { + "regionId": "10132", + "keys": "-1019838423,-1536669319,-512064293,-1039678504" + }, + { + "regionId": "10133", + "keys": "1646350825,-289900492,-802244012,-1058372697" + }, + { + "regionId": "10134", + "keys": "-1343151186,-867897862,-1265011615,-389855656" + }, + { + "regionId": "10135", + "keys": "-642848772,814056528,923267823,-1753006596" + }, + { + "regionId": "10136", + "keys": "512428922,-1090392188,-1855405299,-966311133" + }, + { + "regionId": "10137", + "keys": "-1946240135,-1871060363,1675566259,-1820554947" + }, + { + "regionId": "10138", + "keys": "1254633881,-1405578656,1660494880,-748797494" + }, + { + "regionId": "10139", + "keys": "1226915855,1002704314,-440823591,-129555587" + }, + { + "regionId": "10140", + "keys": "-104825447,-1092637213,-105814713,-2129567531" + }, + { + "regionId": "10142", + "keys": "1872120942,-765842959,449655176,-1168971827" + }, + { + "regionId": "10144", + "keys": "265530509,2033515489,-2022406749,-591072091" + }, + { + "regionId": "10280", + "keys": "-1245893544,-118079793,-1624599660,-626968532" + }, + { + "regionId": "10281", + "keys": "2129832996,-1542613289,-1612399066,-323592936" + }, + { + "regionId": "10282", + "keys": "667792020,292003472,-998896147,7080342" + }, + { + "regionId": "10283", + "keys": "-2133080221,1327669620,173304076,-151662318" + }, + { + "regionId": "10285", + "keys": "-1317120534,1321149083,-1700628824,1028203235" + }, + { + "regionId": "10286", + "keys": "-1040445688,-7408505,807695839,226589344" + }, + { + "regionId": "10287", + "keys": "105887361,-945638691,1922834114,961561887" + }, + { + "regionId": "10288", + "keys": "-642909559,1719566555,1831536672,-1910524848" + }, + { + "regionId": "10289", + "keys": "-1592029672,503478145,-1207378954,-1502774843" + }, + { + "regionId": "10290", + "keys": "-587752684,-318735232,336724431,-1931735346" + }, + { + "regionId": "10292", + "keys": "933507835,1135929795,-1932059890,1492191263" + }, + { + "regionId": "10293", + "keys": "-867083397,-512358173,1502490725,560653474" + }, + { + "regionId": "10294", + "keys": "1880113662,-767344332,-1364117989,-1128121945" + }, + { + "regionId": "10295", + "keys": "-1920480496,-1423914110,951774544,-1419269290" + }, + { + "regionId": "10296", + "keys": "-1699964827,1784080353,113260638,1213918121" + }, + { + "regionId": "10297", + "keys": "548003786,2085747240,921073357,127574933" + }, + { + "regionId": "10298", + "keys": "-233124901,1236532280,1418961777,2055047860" + }, + { + "regionId": "10299", + "keys": "-1615885118,-995676641,-1525013344,1823957481" + }, + { + "regionId": "10300", + "keys": "-988516294,-1280976850,904135114,1435032921" + }, + { + "regionId": "10301", + "keys": "-158146381,1698585677,-910760378,815929788" + }, + { + "regionId": "10302", + "keys": "639277786,-1909940120,130074677,491844814" + }, + { + "regionId": "10303", + "keys": "187236989,-1452229648,1948816476,-1775249280" + }, + { + "regionId": "10304", + "keys": "697091890,424251437,-890570835,-1490213215" + }, + { + "regionId": "10305", + "keys": "-1704965642,953513170,-906801121,1590671819" + }, + { + "regionId": "10307", + "keys": "-808294570,-945302681,-1122362002,76670054" + }, + { + "regionId": "10309", + "keys": "1853022849,1563769590,-839166,1806219482" + }, + { + "regionId": "10310", + "keys": "-1472463766,1824686108,888673126,2074633489" + }, + { + "regionId": "10311", + "keys": "-1976059860,922032078,-1950673483,394409071" + }, + { + "regionId": "10312", + "keys": "-736431800,2013006475,1225434861,59504107" + }, + { + "regionId": "10313", + "keys": "1731455740,156777644,-1031599999,799430192" + }, + { + "regionId": "10314", + "keys": "-2020182865,-861201399,1793241744,-541294677" + }, + { + "regionId": "10315", + "keys": "-1034094191,1810212216,618808107,1905492210" + }, + { + "regionId": "10317", + "keys": "216403117,1910251124,144162918,224240414" + }, + { + "regionId": "10318", + "keys": "1053988597,-2121917140,1730755899,1549334321" + }, + { + "regionId": "10321", + "keys": "1996825886,-1552231723,1721080145,-869420516" + }, + { + "regionId": "10322", + "keys": "1773602876,-1410394076,-239593243,148286798" + }, + { + "regionId": "10324", + "keys": "-1670587478,-401532783,1705875521,995683837" + }, + { + "regionId": "10326", + "keys": "-375687378,472100528,-288941184,523344380" + }, + { + "regionId": "10329", + "keys": "1531226404,988304083,811017843,293412250" + }, + { + "regionId": "10330", + "keys": "654539047,-1306492503,-1808115050,768495826" + }, + { + "regionId": "10331", + "keys": "990721395,1603319590,-1050453751,-2054660152" + }, + { + "regionId": "10386", + "keys": "1123418142,-1191190798,-67920748,-964540310" + }, + { + "regionId": "10387", + "keys": "883942538,-1316327739,-409646311,1715503465" + }, + { + "regionId": "10388", + "keys": "1161495838,-228210135,405156354,-1914329414" + }, + { + "regionId": "10389", + "keys": "1232449212,-728763227,1729853683,-1383669718" + }, + { + "regionId": "10390", + "keys": "1529348981,363265179,-529329077,-1258205924" + }, + { + "regionId": "10391", + "keys": "1697636321,993503902,1432113433,-1040062313" + }, + { + "regionId": "10392", + "keys": "2130459982,-1301889773,1900862262,8338171" + }, + { + "regionId": "10393", + "keys": "-1385824102,-1224106775,2052804935,-259720956" + }, + { + "regionId": "10394", + "keys": "201272072,-1622948650,613159689,479293860" + }, + { + "regionId": "10395", + "keys": "-22365676,-607864450,1375198454,1650832425" + }, + { + "regionId": "10396", + "keys": "-1878072140,1648991920,1054624070,333445417" + }, + { + "regionId": "10400", + "keys": "-1656816922,1318311812,-811481661,1625916625" + }, + { + "regionId": "10536", + "keys": "349537117,1202512092,-698870718,-2083455397" + }, + { + "regionId": "10537", + "keys": "-1212814675,-1832622210,1483740828,1060911198" + }, + { + "regionId": "10538", + "keys": "-2091844157,-1013393743,1806920513,-1464143404" + }, + { + "regionId": "10539", + "keys": "-1468645226,1809562421,-1594801223,389468972" + }, + { + "regionId": "10540", + "keys": "1624468108,-1439095387,1193987877,1292402073" + }, + { + "regionId": "10541", + "keys": "1436392581,-334805062,1155918987,-305555465" + }, + { + "regionId": "10542", + "keys": "49999111,1615631158,-1317472464,893160897" + }, + { + "regionId": "10543", + "keys": "-1329281012,-1688960186,1798967251,1154324972" + }, + { + "regionId": "10544", + "keys": "1385633495,-1924761002,1040853985,475919579" + }, + { + "regionId": "10545", + "keys": "-1415752673,-1618131779,2102457954,-2055391607" + }, + { + "regionId": "10546", + "keys": "192659093,263441429,29086759,670094037" + }, + { + "regionId": "10548", + "keys": "-1157394711,-1306553144,2105373539,798383108" + }, + { + "regionId": "10549", + "keys": "1318595669,-1886528715,150090497,1821415700" + }, + { + "regionId": "10550", + "keys": "-795923963,-1523185883,-1632108091,-59699166" + }, + { + "regionId": "10551", + "keys": "-50853484,-2121251994,717523561,-1277392698" + }, + { + "regionId": "10552", + "keys": "1638763153,-1813807494,-2075537642,109524290" + }, + { + "regionId": "10553", + "keys": "-177114588,-1502279412,1150652747,-2041470332" + }, + { + "regionId": "10554", + "keys": "1188457126,-1729374406,-799893645,1217674507" + }, + { + "regionId": "10555", + "keys": "298183408,-1907842333,1235195826,110456069" + }, + { + "regionId": "10556", + "keys": "1209135093,-27999571,778897676,-513558195" + }, + { + "regionId": "10557", + "keys": "-807815903,958215082,-647601710,1350072419" + }, + { + "regionId": "10558", + "keys": "1337729793,1717973268,-1721269042,-65511201" + }, + { + "regionId": "10559", + "keys": "905435949,206096000,694415949,384719862" + }, + { + "regionId": "10560", + "keys": "761635027,-136268132,1896585946,-1863372135" + }, + { + "regionId": "10564", + "keys": "1279522133,380240348,604239496,1759916207" + }, + { + "regionId": "10566", + "keys": "221004409,1368318650,-1237341956,25411913" + }, + { + "regionId": "10567", + "keys": "-542823457,1281716081,-1533620503,-1571738600" + }, + { + "regionId": "10568", + "keys": "-1256077768,23520063,733929571,440341343" + }, + { + "regionId": "10569", + "keys": "1088282039,955053277,-1112053231,-1883141767" + }, + { + "regionId": "10570", + "keys": "14881828,-6662814,58238456,146761213" + }, + { + "regionId": "10571", + "keys": "2044310497,1377055114,-357355629,1279109029" + }, + { + "regionId": "10572", + "keys": "-1375061166,-1411427241,-294467489,-2106748278" + }, + { + "regionId": "10574", + "keys": "-1609693854,991245740,148787249,-1011766477" + }, + { + "regionId": "10575", + "keys": "434036980,-780702800,-1042242727,-354464628" + }, + { + "regionId": "10577", + "keys": "824897954,-1807466644,2079017570,1299975025" + }, + { + "regionId": "10578", + "keys": "809464329,-292434275,-2009994217,1859510721" + }, + { + "regionId": "10579", + "keys": "-123618550,684067223,486273630,-1103816964" + }, + { + "regionId": "10583", + "keys": "14881828,-6662814,58238456,146761213" + }, + { + "regionId": "10638", + "keys": "616415398,-1155981361,-1520230064,482531809" + }, + { + "regionId": "10639", + "keys": "1174910426,137692025,-576373115,754439009" + }, + { + "regionId": "10640", + "keys": "811726333,-842125498,1799462193,-1151360401" + }, + { + "regionId": "10642", + "keys": "658277839,1898856178,-1037196236,1620289692" + }, + { + "regionId": "10643", + "keys": "1834436817,1391913024,-500731515,1550481150" + }, + { + "regionId": "10644", + "keys": "1308400341,760027142,1015620386,-1917480553" + }, + { + "regionId": "10645", + "keys": "573801874,1064182706,1692837876,-2084731388" + }, + { + "regionId": "10646", + "keys": "-180468483,-1085034165,1731369422,-1353138557" + }, + { + "regionId": "10647", + "keys": "-1503343410,-1634708207,-1757301917,-2003987513" + }, + { + "regionId": "10648", + "keys": "1512581514,-1121623940,-1861238740,1459885224" + }, + { + "regionId": "10649", + "keys": "1423886987,-1654331043,-678242006,1738009197" + }, + { + "regionId": "10650", + "keys": "-908578223,-911827513,1137573080,-419444146" + }, + { + "regionId": "10652", + "keys": "1580722385,609745227,1407021351,1098485033" + }, + { + "regionId": "10653", + "keys": "570189753,-1700559836,2108215671,-701775893" + }, + { + "regionId": "10792", + "keys": "-125671574,254943715,1343095705,-1965171670" + }, + { + "regionId": "10793", + "keys": "-918820648,-575477272,1826808974,1583566620" + }, + { + "regionId": "10794", + "keys": "-62638721,-2055205851,-488702423,1198245579" + }, + { + "regionId": "10795", + "keys": "1763600957,-365178279,1448589605,-1883563545" + }, + { + "regionId": "10796", + "keys": "-1834928370,1352649164,765865015,1708785419" + }, + { + "regionId": "10797", + "keys": "1162623334,1082199860,2059929131,-2132110355" + }, + { + "regionId": "10798", + "keys": "487791818,49811808,-1421313612,1181040843" + }, + { + "regionId": "10799", + "keys": "1217726924,398085963,-1594428602,886790463" + }, + { + "regionId": "10800", + "keys": "1040846845,257923177,-1680471073,-1533314482" + }, + { + "regionId": "10801", + "keys": "850125851,1199386038,-1494136472,-1487577933" + }, + { + "regionId": "10803", + "keys": "-1028081880,964144306,174845257,1906118817" + }, + { + "regionId": "10804", + "keys": "2044023784,-1099109846,-1909401127,-1304331091" + }, + { + "regionId": "10805", + "keys": "-1168385071,683797418,469816742,1479779110" + }, + { + "regionId": "10806", + "keys": "-1998000009,766783746,1340848604,-610487829" + }, + { + "regionId": "10807", + "keys": "-1978433603,-211738714,1401562605,-1310990578" + }, + { + "regionId": "10808", + "keys": "-1264729881,1766238888,-244541987,-605351538" + }, + { + "regionId": "10809", + "keys": "1586374012,-258505553,-528210036,1595850453" + }, + { + "regionId": "10810", + "keys": "-2030061920,-333031845,-792169278,597648394" + }, + { + "regionId": "10811", + "keys": "-1788784737,-1830208994,935346396,517118750" + }, + { + "regionId": "10812", + "keys": "90198727,258723745,748197903,-426406231" + }, + { + "regionId": "10813", + "keys": "78604466,-1582607088,691011324,-1155733133" + }, + { + "regionId": "10814", + "keys": "707246869,541333062,-986248348,-171063894" + }, + { + "regionId": "10815", + "keys": "2102925673,1133406202,-1885710196,165240951" + }, + { + "regionId": "10816", + "keys": "-1909517714,218137505,744896894,831968418" + }, + { + "regionId": "10819", + "keys": "-904401587,-2054970579,55120674,-1889562804" + }, + { + "regionId": "10820", + "keys": "1391829934,487584817,397681771,-2002250378" + }, + { + "regionId": "10821", + "keys": "547864979,703484266,-571616416,-1277862770" + }, + { + "regionId": "10822", + "keys": "147390427,1823879919,432432207,-1107512174" + }, + { + "regionId": "10823", + "keys": "-626951011,-1729338061,-758591782,439072305" + }, + { + "regionId": "10824", + "keys": "-1104875422,66393069,-739286658,-254408159" + }, + { + "regionId": "10825", + "keys": "-1671459541,1278917254,1363778127,979691919" + }, + { + "regionId": "10826", + "keys": "14881828,-6662814,58238456,146761213" + }, + { + "regionId": "10827", + "keys": "1032543297,-526372126,1157124086,-623019107" + }, + { + "regionId": "10828", + "keys": "1665018619,-1607107877,-1997272567,1342325223" + }, + { + "regionId": "10830", + "keys": "-608096960,58771202,1174291927,-1613596249" + }, + { + "regionId": "10831", + "keys": "-1576700407,-806518664,-901641004,-573449068" + }, + { + "regionId": "10832", + "keys": "-644307702,-424113333,1143257020,1132671603" + }, + { + "regionId": "10833", + "keys": "-2021761641,-2091050426,1623160087,-1674608487" + }, + { + "regionId": "10834", + "keys": "-1640569486,-512141704,-1179536382,720004469" + }, + { + "regionId": "10836", + "keys": "1637505449,619992365,-1935536269,-1526242295" + }, + { + "regionId": "10838", + "keys": "1678881362,-952862831,-1804688659,-1247653912" + }, + { + "regionId": "10839", + "keys": "-885801393,-721089484,-1671928660,-391245118" + }, + { + "regionId": "10840", + "keys": "-2112185519,-1346264110,624078956,-426600771" + }, + { + "regionId": "10841", + "keys": "1553036338,2006573090,816979270,1677882458" + }, + { + "regionId": "10842", + "keys": "89140380,-204251076,-1595945414,1904801559" + }, + { + "regionId": "10893", + "keys": "-645277901,-963804189,-1583950082,1158107798" + }, + { + "regionId": "10894", + "keys": "344355193,729779647,-822390098,-250999551" + }, + { + "regionId": "10895", + "keys": "1704525734,-123453856,-2038510951,229741613" + }, + { + "regionId": "10896", + "keys": "1622301889,-1463258766,228869805,-1761890776" + }, + { + "regionId": "10897", + "keys": "-532884907,-856360437,-1856255648,-108994584" + }, + { + "regionId": "10898", + "keys": "1997981354,1569532835,1920365312,579258114" + }, + { + "regionId": "10899", + "keys": "889615956,-1979547812,1134305624,56186568" + }, + { + "regionId": "10900", + "keys": "-1475778003,1161941178,-130498235,-281971512" + }, + { + "regionId": "10901", + "keys": "675683066,1081382157,224642530,-1939264495" + }, + { + "regionId": "10902", + "keys": "1363034505,1752486270,-64629826,1887223207" + }, + { + "regionId": "10903", + "keys": "-1670827594,1280370415,789868677,2002317267" + }, + { + "regionId": "10904", + "keys": "-275061067,1527943046,1660873402,-995392725" + }, + { + "regionId": "10905", + "keys": "-1326091047,1551722893,1309735056,613553820" + }, + { + "regionId": "10906", + "keys": "-1078751493,160151975,937918565,-1173346878" + }, + { + "regionId": "10907", + "keys": "1703225431,-1175749730,1842579622,-1861290070" + }, + { + "regionId": "10908", + "keys": "-1924304925,-2143417334,-291856580,1774510860" + }, + { + "regionId": "10909", + "keys": "1594286276,-309059362,519622640,-2072561673" + }, + { + "regionId": "10910", + "keys": "-872445206,510847548,-334876446,355059661" + }, + { + "regionId": "10911", + "keys": "948965123,-545528654,-459191491,-860302360" + }, + { + "regionId": "11049", + "keys": "-621090199,-1004888612,-749707219,2052444337" + }, + { + "regionId": "11050", + "keys": "467286343,-1173584329,1828950249,-347448684" + }, + { + "regionId": "11051", + "keys": "-296929555,609763351,-2080091577,-1042760897" + }, + { + "regionId": "11052", + "keys": "288578281,-2129494488,774599960,-1782292467" + }, + { + "regionId": "11053", + "keys": "280137623,-2139580445,-1330319011,-597364950" + }, + { + "regionId": "11054", + "keys": "-1668355981,-1569925814,-994250231,-2107802880" + }, + { + "regionId": "11055", + "keys": "374763347,-681855601,109012867,-1743182199" + }, + { + "regionId": "11056", + "keys": "-406501477,-543853643,1541426156,232589767" + }, + { + "regionId": "11057", + "keys": "-1133710777,-906783679,-1659353497,-298313847" + }, + { + "regionId": "11058", + "keys": "-721937224,-607011472,-1902697586,959894629" + }, + { + "regionId": "11059", + "keys": "-1379234654,-567015201,-213396057,-1450244676" + }, + { + "regionId": "11060", + "keys": "1341887290,-1539014214,-2027023574,329166812" + }, + { + "regionId": "11061", + "keys": "-803679875,-723408908,1383151372,-1231504848" + }, + { + "regionId": "11062", + "keys": "-555568759,1453374289,-14801609,96233628" + }, + { + "regionId": "11063", + "keys": "-64230628,1920227716,1652611857,-856220145" + }, + { + "regionId": "11064", + "keys": "564384282,-709585243,1613220025,-1038354302" + }, + { + "regionId": "11065", + "keys": "1933481202,893646018,1177862990,1245692325" + }, + { + "regionId": "11066", + "keys": "291008624,-1992710142,-1831766032,1925022398" + }, + { + "regionId": "11067", + "keys": "1192664190,-341042618,-820464572,602716622" + }, + { + "regionId": "11068", + "keys": "1956851882,1582504141,-1090835806,1413275925" + }, + { + "regionId": "11069", + "keys": "281072607,-1791037221,-1221626554,801634958" + }, + { + "regionId": "11070", + "keys": "1991482486,-631240020,-1616896556,-496223621" + }, + { + "regionId": "11071", + "keys": "1897069040,1886820064,-149588823,-386960868" + }, + { + "regionId": "11075", + "keys": "-822254379,1979001089,-222309885,1224296165" + }, + { + "regionId": "11077", + "keys": "-1820943973,1377081160,541237698,877059643" + }, + { + "regionId": "11078", + "keys": "368703258,1379906464,-1472415010,289347299" + }, + { + "regionId": "11079", + "keys": "506641326,1963199125,229965472,-982593319" + }, + { + "regionId": "11080", + "keys": "-1110513411,181454781,-448189547,-1724524157" + }, + { + "regionId": "11081", + "keys": "197573217,-913745315,648860964,1604781836" + }, + { + "regionId": "11082", + "keys": "-1048566284,-1888694855,1387988701,1385807517" + }, + { + "regionId": "11083", + "keys": "1255503855,-674022312,-807132804,-1287799121" + }, + { + "regionId": "11085", + "keys": "327229160,-1433790638,1944433240,234034136" + }, + { + "regionId": "11088", + "keys": "-1943123304,1713176080,-1524844090,-445387865" + }, + { + "regionId": "11090", + "keys": "2089067081,828176382,-1112393031,-1452165920" + }, + { + "regionId": "11091", + "keys": "977844365,-245927723,99303766,-735341354" + }, + { + "regionId": "11093", + "keys": "-379710910,-2088433559,1180928189,-54938349" + }, + { + "regionId": "11094", + "keys": "1496438748,-566742834,585189704,2074216180" + }, + { + "regionId": "11095", + "keys": "-1020136454,1747944725,1987554618,-1828989591" + }, + { + "regionId": "11096", + "keys": "-592943404,1816311621,-1394660709,-627674752" + }, + { + "regionId": "11097", + "keys": "475166922,1503166866,-1819732882,2126974237" + }, + { + "regionId": "11098", + "keys": "79370033,-1930799782,2111330013,1328665449" + }, + { + "regionId": "11149", + "keys": "-673407424,-459515480,-1880462863,2096963221" + }, + { + "regionId": "11150", + "keys": "685385874,67618271,-450250419,-2086862875" + }, + { + "regionId": "11151", + "keys": "712251572,-97105648,-615552291,-1419987674" + }, + { + "regionId": "11152", + "keys": "110595890,-685885763,1230390297,1617167138" + }, + { + "regionId": "11153", + "keys": "1133518437,1160845567,1259706301,-190274103" + }, + { + "regionId": "11154", + "keys": "-1390672245,-294524193,1901848082,-1240329686" + }, + { + "regionId": "11155", + "keys": "740691311,-158757873,133181481,775561317" + }, + { + "regionId": "11156", + "keys": "-122332432,-2135770681,826741763,-578793086" + }, + { + "regionId": "11157", + "keys": "-1366388735,-378058761,-1560378292,-1001591092" + }, + { + "regionId": "11158", + "keys": "160361538,733169435,1244326761,1681727551" + }, + { + "regionId": "11161", + "keys": "-1713920755,1291269906,320754968,741637543" + }, + { + "regionId": "11162", + "keys": "-2108680437,-1260585402,-1400451285,2023092270" + }, + { + "regionId": "11163", + "keys": "-1890796698,-611617711,-1429163994,-740772710" + }, + { + "regionId": "11164", + "keys": "1046978961,-977367474,1204218608,554630994" + }, + { + "regionId": "11165", + "keys": "1783387115,1062643659,254207637,-280202231" + }, + { + "regionId": "11166", + "keys": "1534808050,-1895827266,489865723,1605171942" + }, + { + "regionId": "11167", + "keys": "-1735216162,2141149053,57787230,-1263840909" + }, + { + "regionId": "11305", + "keys": "-1429346525,-118378130,1002549662,1383588995" + }, + { + "regionId": "11306", + "keys": "-215265871,-2043332955,304105107,1443631953" + }, + { + "regionId": "11307", + "keys": "-530572214,1137382838,1524205137,-1364477332" + }, + { + "regionId": "11308", + "keys": "313027206,-1690946376,-43334224,216984734" + }, + { + "regionId": "11309", + "keys": "480918720,-1760104027,-1096191521,-1751168810" + }, + { + "regionId": "11310", + "keys": "581450375,550120818,-1633145086,862987872" + }, + { + "regionId": "11311", + "keys": "2122993198,-483099438,-1947019175,453102954" + }, + { + "regionId": "11312", + "keys": "-1046696594,1468533694,2085200066,-828502933" + }, + { + "regionId": "11313", + "keys": "910266570,2031866974,-1478026252,-1294052037" + }, + { + "regionId": "11314", + "keys": "1798320089,-1598590173,-1563649785,173183318" + }, + { + "regionId": "11315", + "keys": "669874829,-776374692,-285442682,-2063742845" + }, + { + "regionId": "11316", + "keys": "-2133481275,1183956887,-282614520,-1763887981" + }, + { + "regionId": "11317", + "keys": "-607461440,-208518302,-1370277091,1586835768" + }, + { + "regionId": "11318", + "keys": "-214781882,-1242534505,308650486,1398014950" + }, + { + "regionId": "11319", + "keys": "-561547561,-1342850556,-903509942,-570987704" + }, + { + "regionId": "11320", + "keys": "-346856430,-716818566,-1629533789,-835719555" + }, + { + "regionId": "11321", + "keys": "699352627,-565777108,-1385571111,636180354" + }, + { + "regionId": "11322", + "keys": "-1539862936,-1377050431,1392963326,-711921559" + }, + { + "regionId": "11323", + "keys": "-1710808226,725482732,1863997544,5983834" + }, + { + "regionId": "11326", + "keys": "1862093150,1696245244,1320714102,1241887579" + }, + { + "regionId": "11329", + "keys": "1852262545,929814037,831292048,-138159629" + }, + { + "regionId": "11331", + "keys": "630464144,-872867374,2001047906,-12413476" + }, + { + "regionId": "11332", + "keys": "-936631483,-1093055133,-161202591,-1476364681" + }, + { + "regionId": "11335", + "keys": "-133492081,-915358326,-714649892,-2093709476" + }, + { + "regionId": "11339", + "keys": "140118336,-1920268877,-1967576060,-1437209189" + }, + { + "regionId": "11341", + "keys": "-1219163353,-1635920416,-2124217842,-1318908036" + }, + { + "regionId": "11343", + "keys": "1857048515,-1771448269,265497055,1368981799" + }, + { + "regionId": "11345", + "keys": "-1311889529,-1925291147,-1246770062,-343643022" + }, + { + "regionId": "11346", + "keys": "-750575261,-297404295,354820348,2031661388" + }, + { + "regionId": "11347", + "keys": "-122396964,-1996200666,-585000602,-863390951" + }, + { + "regionId": "11350", + "keys": "-1365557009,-1350738529,-1074800707,-446118748" + }, + { + "regionId": "11351", + "keys": "-1227666214,990739070,758255446,-410679401" + }, + { + "regionId": "11352", + "keys": "-76693830,-865206807,384409960,1285997763" + }, + { + "regionId": "11353", + "keys": "1903451400,172495816,-26951355,-2020198034" + }, + { + "regionId": "11354", + "keys": "-104997214,-1634014788,-392797186,-941769095" + }, + { + "regionId": "11356", + "keys": "2033204014,1416145849,-1721330996,2134394884" + }, + { + "regionId": "11406", + "keys": "375301159,353365492,-940259891,-223647771" + }, + { + "regionId": "11409", + "keys": "1937092760,-1545935537,29954084,-1081016062" + }, + { + "regionId": "11410", + "keys": "1509299526,-892391942,1485831814,1255407038" + }, + { + "regionId": "11412", + "keys": "-1379772393,621580805,-316850307,1026773740" + }, + { + "regionId": "11413", + "keys": "1488866121,-484754573,-1471688962,-511348808" + }, + { + "regionId": "11414", + "keys": "1377762353,1699445159,1913215037,1606010259" + }, + { + "regionId": "11415", + "keys": "1136524726,-1672016136,-1498346497,-1411607834" + }, + { + "regionId": "11416", + "keys": "1424707743,282141552,464542584,1000633084" + }, + { + "regionId": "11417", + "keys": "1581021494,-1994945510,-177217961,455201014" + }, + { + "regionId": "11418", + "keys": "161282524,-561691741,-293028043,-1466220307" + }, + { + "regionId": "11419", + "keys": "-1254692109,-721963897,1982559036,2090401358" + }, + { + "regionId": "11420", + "keys": "1847735585,-1694492924,1127165320,-479409843" + }, + { + "regionId": "11421", + "keys": "986943416,-2110784934,1490597490,1999343527" + }, + { + "regionId": "11422", + "keys": "-843901847,-337979146,-867731076,-342235410" + }, + { + "regionId": "11423", + "keys": "437777194,-1226666437,1806502066,2032844071" + }, + { + "regionId": "11424", + "keys": "807879302,-1555822450,-271595686,-1725049162" + }, + { + "regionId": "11559", + "keys": "16777217,1717961767,50359296,1634336841" + }, + { + "regionId": "11561", + "keys": "-591558979,1108648192,1263458446,2058484886" + }, + { + "regionId": "11562", + "keys": "1623115614,841254570,365391355,629444052" + }, + { + "regionId": "11563", + "keys": "-2086554592,-933774380,-1450605238,-515013992" + }, + { + "regionId": "11564", + "keys": "1353274200,1339785802,-1572198107,1935847233" + }, + { + "regionId": "11565", + "keys": "-137041923,-1569836238,18743223,-1472669397" + }, + { + "regionId": "11566", + "keys": "575328672,-285813481,-1608888020,-1018793466" + }, + { + "regionId": "11567", + "keys": "-1044081427,53182148,606084353,909523725" + }, + { + "regionId": "11568", + "keys": "90223196,-1877968085,962102514,1727463305" + }, + { + "regionId": "11569", + "keys": "1995103132,954046526,-736090037,-1261975818" + }, + { + "regionId": "11570", + "keys": "1764463961,-1394011513,841104317,1009452619" + }, + { + "regionId": "11571", + "keys": "555412042,1365420838,-819421250,-281395793" + }, + { + "regionId": "11572", + "keys": "892185929,686162443,1793819023,-992991976" + }, + { + "regionId": "11574", + "keys": "-1406155502,13961326,1071473330,1528558089" + }, + { + "regionId": "11575", + "keys": "-388816502,637165039,-1660550531,1252748078" + }, + { + "regionId": "11576", + "keys": "-653186907,1743653193,1590707166,841079490" + }, + { + "regionId": "11577", + "keys": "1283493672,1550135524,-1621670256,769418438" + }, + { + "regionId": "11579", + "keys": "-719996638,-1831948234,494156672,1684753309" + }, + { + "regionId": "11582", + "keys": "602331327,-1036793753,1702673112,-1107214996" + }, + { + "regionId": "11585", + "keys": "-2002677198,-1770151217,-1572915128,2094989518" + }, + { + "regionId": "11586", + "keys": "925071192,-1288796869,51183037,-115462507" + }, + { + "regionId": "11587", + "keys": "1618637156,924324919,-706966841,209620280" + }, + { + "regionId": "11588", + "keys": "-519511661,-159682581,-172209167,-816666339" + }, + { + "regionId": "11589", + "keys": "39678032,469576041,-1878694956,-1720799345" + }, + { + "regionId": "11591", + "keys": "1300749474,-912770362,-1665451776,480747745" + }, + { + "regionId": "11593", + "keys": "14881828,-6662814,58238456,146761213" + }, + { + "regionId": "11594", + "keys": "477395683,539436779,-1560356372,-1102990030" + }, + { + "regionId": "11595", + "keys": "-1497259084,-1208341848,874209282,-1950133061" + }, + { + "regionId": "11597", + "keys": "-824244627,-1750674106,-2032396270,-451550546" + }, + { + "regionId": "11599", + "keys": "-1124938025,110281395,-1121479364,68953473" + }, + { + "regionId": "11601", + "keys": "722657934,1495340205,-437272583,-1331954618" + }, + { + "regionId": "11602", + "keys": "-1830335785,-544748254,-190875166,1866682430" + }, + { + "regionId": "11603", + "keys": "-254635141,-1757221941,-2072225761,-752948578" + }, + { + "regionId": "11605", + "keys": "57037316,1119657363,2040370510,801474589" + }, + { + "regionId": "11606", + "keys": "-1790275662,-1050505330,-1496410655,679769180" + }, + { + "regionId": "11608", + "keys": "248039728,1861834308,1335200688,317723667" + }, + { + "regionId": "11609", + "keys": "-1581925228,-215021003,-1695323698,-1853661356" + }, + { + "regionId": "11612", + "keys": "-1751954695,954770889,-337304771,986015401" + }, + { + "regionId": "11664", + "keys": "1190807823,1104329472,374421371,1684960233" + }, + { + "regionId": "11665", + "keys": "1421755107,-1753781642,148994094,-1190683420" + }, + { + "regionId": "11666", + "keys": "-341360024,-822905169,-778532221,-885891559" + }, + { + "regionId": "11667", + "keys": "-1991130334,-1460099297,758552332,1913132025" + }, + { + "regionId": "11668", + "keys": "-257024301,-661941375,-687408097,-1243612535" + }, + { + "regionId": "11669", + "keys": "-2019291079,1299725119,2078401543,-99676412" + }, + { + "regionId": "11670", + "keys": "549318992,1085934989,710708603,-1635474946" + }, + { + "regionId": "11671", + "keys": "141459802,-808095674,779257961,-1662929599" + }, + { + "regionId": "11672", + "keys": "-1845806596,1811189482,329650354,-628982335" + }, + { + "regionId": "11673", + "keys": "-1063593336,-1597944673,1273002319,-1348952650" + }, + { + "regionId": "11674", + "keys": "1210448615,-1069893745,1849844672,-2020497288" + }, + { + "regionId": "11675", + "keys": "-1885801977,-74559034,1670696344,449082888" + }, + { + "regionId": "11676", + "keys": "-497232340,-1339196313,-2027479925,-368682937" + }, + { + "regionId": "11677", + "keys": "536395294,1131483635,-2029771861,-1394887559" + }, + { + "regionId": "11678", + "keys": "-804330631,-1574570644,457636469,-2078367975" + }, + { + "regionId": "11679", + "keys": "538734781,-438496848,-1620632820,1342830944" + }, + { + "regionId": "11680", + "keys": "1628843011,-904651047,841205079,-2056142962" + }, + { + "regionId": "11817", + "keys": "740863947,-1459447536,-1272357052,-1730407126" + }, + { + "regionId": "11818", + "keys": "-2034608097,1147002393,-720701760,-1045127369" + }, + { + "regionId": "11819", + "keys": "-1632272271,-1134214079,-1204220834,-1633494895" + }, + { + "regionId": "11820", + "keys": "1770850144,-166786106,-684161481,-1708595579" + }, + { + "regionId": "11821", + "keys": "-707628647,-1786826314,1726639607,1329014754" + }, + { + "regionId": "11822", + "keys": "-1814853584,-1136244468,-411716523,-1293542025" + }, + { + "regionId": "11823", + "keys": "-1467961870,-332715907,828094751,497688107" + }, + { + "regionId": "11824", + "keys": "-1116727390,-659788658,307002260,354360287" + }, + { + "regionId": "11827", + "keys": "379001889,1835230493,1861106702,338991847" + }, + { + "regionId": "11828", + "keys": "-483956226,1333559890,409484157,259080419" + }, + { + "regionId": "11829", + "keys": "201013583,-1953655991,-1314566361,-531272086" + }, + { + "regionId": "11830", + "keys": "1371203331,1456322164,1830551817,1881701938" + }, + { + "regionId": "11831", + "keys": "2070834186,89622912,-2093327347,-1499870034" + }, + { + "regionId": "11832", + "keys": "912914769,1794955235,953692213,833376694" + }, + { + "regionId": "11833", + "keys": "-1650041704,120707908,795850411,-1243236268" + }, + { + "regionId": "11834", + "keys": "-1469717920,-822155319,1177768019,987379908" + }, + { + "regionId": "11835", + "keys": "1706086657,-184799142,1874207624,-980291727" + }, + { + "regionId": "11836", + "keys": "-1380985244,-357598195,-1439932150,1526942363" + }, + { + "regionId": "11837", + "keys": "-1038342108,2043521930,585928227,-2111003977" + }, + { + "regionId": "11838", + "keys": "-1244353559,318399250,-531450733,1472599251" + }, + { + "regionId": "11842", + "keys": "-1217922297,-1739467375,1236768219,-519170083" + }, + { + "regionId": "11843", + "keys": "-970160562,776045252,188992499,588376278" + }, + { + "regionId": "11844", + "keys": "46502425,-1301719099,-1597781617,1434487073" + }, + { + "regionId": "11851", + "keys": "-516358140,791692293,-1663509747,1243508195" + }, + { + "regionId": "11854", + "keys": "311566497,-486013229,1351929142,744327317" + }, + { + "regionId": "11855", + "keys": "770787544,-1305958539,670684335,208100825" + }, + { + "regionId": "11857", + "keys": "150488681,419659968,-1871963555,1031596369" + }, + { + "regionId": "11862", + "keys": "2071521092,797384499,364423664,-1286422461" + }, + { + "regionId": "11863", + "keys": "-117384431,428352610,-41119857,1227430828" + }, + { + "regionId": "11864", + "keys": "415237490,-1571743714,-1596630690,-846850340" + }, + { + "regionId": "11865", + "keys": "-1962002904,26354278,-969232265,1948165207" + }, + { + "regionId": "11866", + "keys": "1586054337,290394491,-979194848,-573910165" + }, + { + "regionId": "11920", + "keys": "-1502792287,1854795762,2014359664,-757683160" + }, + { + "regionId": "11921", + "keys": "-1190097358,-717950981,1892307569,1647143186" + }, + { + "regionId": "11922", + "keys": "1588123970,2064849194,1386289019,-716346213" + }, + { + "regionId": "11924", + "keys": "1085111846,-1815997315,216841486,2022451249" + }, + { + "regionId": "11925", + "keys": "-989523453,913815552,345668487,-1351819941" + }, + { + "regionId": "11926", + "keys": "-501586879,235710413,-1122707717,-354940885" + }, + { + "regionId": "11928", + "keys": "-445378710,-788377286,1363332226,627739779" + }, + { + "regionId": "11929", + "keys": "747285535,375064048,-1156931456,-126201237" + }, + { + "regionId": "11930", + "keys": "1436132147,-902725534,590285278,2018675988" + }, + { + "regionId": "11934", + "keys": "-854127330,1609124159,-999989310,-734721734" + }, + { + "regionId": "11935", + "keys": "-1453725493,-1575973068,1979334907,1130399929" + }, + { + "regionId": "11937", + "keys": "-1518927827,1819850502,-992647105,299958470" + }, + { + "regionId": "12076", + "keys": "193939514,-115011236,-1406304015,-1626342231" + }, + { + "regionId": "12077", + "keys": "1638808709,1254156985,809776183,-1544950482" + }, + { + "regionId": "12078", + "keys": "-525973296,-1548155792,-1385110219,-1985763988" + }, + { + "regionId": "12079", + "keys": "-1011045091,-936937530,315153197,1186727635" + }, + { + "regionId": "12080", + "keys": "-871039166,671466658,-1667543860,-2035538436" + }, + { + "regionId": "12081", + "keys": "1035017991,592263100,-1547948034,1792058205" + }, + { + "regionId": "12082", + "keys": "-503983849,469781652,-1875993426,1605772035" + }, + { + "regionId": "12083", + "keys": "-359077405,-975212733,-1032910232,80337581" + }, + { + "regionId": "12084", + "keys": "1719212980,-270023138,175706506,-308924243" + }, + { + "regionId": "12085", + "keys": "-1262595098,-465048704,-1463905457,1372729353" + }, + { + "regionId": "12086", + "keys": "1720662391,1428111249,873760745,-580366661" + }, + { + "regionId": "12087", + "keys": "-1019515374,-1885024451,-1336165534,1322614963" + }, + { + "regionId": "12088", + "keys": "-2139185262,-1806601505,1536573357,72818727" + }, + { + "regionId": "12089", + "keys": "-1047505229,1482518318,895541409,-1048492631" + }, + { + "regionId": "12090", + "keys": "120066737,434314789,-2139665893,-8665118" + }, + { + "regionId": "12091", + "keys": "1479001755,2119142088,-653624921,702014943" + }, + { + "regionId": "12092", + "keys": "1834140299,801520697,152435624,2017368659" + }, + { + "regionId": "12093", + "keys": "-1609567378,-1639522221,1730303123,-248179982" + }, + { + "regionId": "12094", + "keys": "2120437359,222442049,41777842,-509732529" + }, + { + "regionId": "12097", + "keys": "-862465947,2109948185,583246321,-850147469" + }, + { + "regionId": "12100", + "keys": "1852910519,712916664,1670787779,1294835477" + }, + { + "regionId": "12105", + "keys": "1153497516,-449169462,-635419798,-1471828315" + }, + { + "regionId": "12106", + "keys": "38647587,1522565828,-949257419,1943032512" + }, + { + "regionId": "12107", + "keys": "790028083,952090857,-1393754794,1896821277" + }, + { + "regionId": "12108", + "keys": "-31531459,-1804597772,712452096,1915359882" + }, + { + "regionId": "12109", + "keys": "1939715187,-796094750,-1071860977,-1024683065" + }, + { + "regionId": "12110", + "keys": "808144600,-616213476,2026296096,1539298914" + }, + { + "regionId": "12111", + "keys": "-746445771,1759120362,1253848335,1433199232" + }, + { + "regionId": "12113", + "keys": "-1749952613,1569535680,1900425482,-1993748284" + }, + { + "regionId": "12115", + "keys": "2146362785,1996258091,-613445101,539756591" + }, + { + "regionId": "12117", + "keys": "-97063310,1962833557,-849078816,-1560293275" + }, + { + "regionId": "12118", + "keys": "714042847,-1192681674,-1453080351,-88273278" + }, + { + "regionId": "12119", + "keys": "-873110513,-162095225,-381892128,-346588457" + }, + { + "regionId": "12120", + "keys": "-774739481,1496283218,893257461,-1168642419" + }, + { + "regionId": "12121", + "keys": "1557445081,682103339,1577593678,-1850587643" + }, + { + "regionId": "12122", + "keys": "-2014648814,571564491,-1983897919,-612605198" + }, + { + "regionId": "12180", + "keys": "1388683192,-872219469,437507075,812232152" + }, + { + "regionId": "12181", + "keys": "-995343774,-1071540200,1667841236,1318274883" + }, + { + "regionId": "12182", + "keys": "-499997333,1910872683,-234510566,-361238419" + }, + { + "regionId": "12184", + "keys": "-1993918550,1977224805,-1048356116,-1578331413" + }, + { + "regionId": "12185", + "keys": "-733095133,-1797134669,1813691911,-117267989" + }, + { + "regionId": "12186", + "keys": "-259674875,-949495016,1835821953,1740556829" + }, + { + "regionId": "12188", + "keys": "22801476,-1237575758,2139201694,-163382547" + }, + { + "regionId": "12189", + "keys": "-626419958,-861781849,-400257621,465575053" + }, + { + "regionId": "12193", + "keys": "1013552068,-364826455,4137749,729786125" + }, + { + "regionId": "12333", + "keys": "372281878,-809369100,-1989039261,-980074402" + }, + { + "regionId": "12334", + "keys": "-208871238,397971218,827338731,-602814995" + }, + { + "regionId": "12335", + "keys": "-932235881,-440697769,-2073934211,-1071764865" + }, + { + "regionId": "12336", + "keys": "-1452500433,-1602128254,-1629750057,1243308175" + }, + { + "regionId": "12337", + "keys": "-1376987128,-85363217,1977650657,-2129657037" + }, + { + "regionId": "12338", + "keys": "-983999026,1403872391,385102350,-194124711" + }, + { + "regionId": "12339", + "keys": "518441298,1531173904,430682398,595384049" + }, + { + "regionId": "12340", + "keys": "1946410965,-211089460,-1145931943,-92341347" + }, + { + "regionId": "12341", + "keys": "2121187294,1555327396,-2072187998,-1348805114" + }, + { + "regionId": "12342", + "keys": "-1082588441,1243176731,-1284334046,-1428935477" + }, + { + "regionId": "12343", + "keys": "-609214795,980135617,-695357998,-160803647" + }, + { + "regionId": "12344", + "keys": "-1265758544,1128006461,-466859463,-1851036690" + }, + { + "regionId": "12345", + "keys": "-134733709,151853724,-1437846337,335319448" + }, + { + "regionId": "12346", + "keys": "-657476809,-1958794621,-573708398,1064135013" + }, + { + "regionId": "12347", + "keys": "-1599627156,201181799,-1978827396,-76735331" + }, + { + "regionId": "12348", + "keys": "1498945330,-1007588865,989046743,-1246005481" + }, + { + "regionId": "12349", + "keys": "1690287681,1306543027,-1953379158,1167181646" + }, + { + "regionId": "12350", + "keys": "1136900728,1196784066,-231560317,20860732" + }, + { + "regionId": "12353", + "keys": "1632384552,-1909179432,-618653336,-1612279868" + }, + { + "regionId": "12354", + "keys": "1499391996,1113335840,1679448224,-1743073054" + }, + { + "regionId": "12355", + "keys": "2068164694,1652405742,-1354799119,-2005137631" + }, + { + "regionId": "12356", + "keys": "-1201681208,106398334,-2123418385,1010672418" + }, + { + "regionId": "12367", + "keys": "-2006617355,-1390093250,-1950318553,1842364433" + }, + { + "regionId": "12369", + "keys": "-891954120,1710352781,-1883639556,-1461026236" + }, + { + "regionId": "12374", + "keys": "1620519366,-1309341299,68411383,1308746010" + }, + { + "regionId": "12376", + "keys": "1918934265,1530066885,-1991367516,1783839145" + }, + { + "regionId": "12377", + "keys": "-1926215959,-398085479,-1931593602,-1073869938" + }, + { + "regionId": "12378", + "keys": "-369504798,1961362499,749656660,-356368606" + }, + { + "regionId": "12434", + "keys": "-1419269744,1750656375,119876026,1040224763" + }, + { + "regionId": "12436", + "keys": "-2138826728,1169519405,-411858931,491428" + }, + { + "regionId": "12437", + "keys": "1402191614,1606631666,-257071195,939962410" + }, + { + "regionId": "12438", + "keys": "-634183085,122332197,2063223083,1861049708" + }, + { + "regionId": "12439", + "keys": "-128537652,-667417558,998246693,-1147655385" + }, + { + "regionId": "12440", + "keys": "2053762285,-354590835,1580877387,-2123860710" + }, + { + "regionId": "12441", + "keys": "-1858539590,267273914,-776577096,-1251026502" + }, + { + "regionId": "12442", + "keys": "1883167946,191149821,-1270401415,-126025128" + }, + { + "regionId": "12444", + "keys": "1576354846,-1768236409,821965805,-861456742" + }, + { + "regionId": "12589", + "keys": "1981659006,1591583400,1958084245,667979721" + }, + { + "regionId": "12590", + "keys": "-755814299,1579260481,892984208,577453947" + }, + { + "regionId": "12591", + "keys": "351660323,1292140128,-1256148041,78535482" + }, + { + "regionId": "12592", + "keys": "-1630268797,-1503112818,1383264816,1705116684" + }, + { + "regionId": "12593", + "keys": "-1653558720,2119901478,-1449369788,-1829505468" + }, + { + "regionId": "12594", + "keys": "1150282919,572626783,-257791473,2031745700" + }, + { + "regionId": "12595", + "keys": "690344167,598639865,1375558029,1809058157" + }, + { + "regionId": "12596", + "keys": "1570322737,1165043749,1246435002,1408253611" + }, + { + "regionId": "12597", + "keys": "306679611,1182603714,427243016,1648062434" + }, + { + "regionId": "12598", + "keys": "1874555134,-1535151559,1145435834,-578461761" + }, + { + "regionId": "12599", + "keys": "1053581692,-982140470,419327673,-163055372" + }, + { + "regionId": "12600", + "keys": "-649213147,1195379532,134339031,1178706012" + }, + { + "regionId": "12601", + "keys": "1770077800,-625870452,1753986528,1205115023" + }, + { + "regionId": "12602", + "keys": "1289058435,-2013760918,1538318852,396639740" + }, + { + "regionId": "12603", + "keys": "-1135486565,-470016325,1594745611,161611213" + }, + { + "regionId": "12604", + "keys": "-1812120898,-1662909112,-1432124543,571589094" + }, + { + "regionId": "12605", + "keys": "-1547116565,1817338996,-1727020832,2025648539" + }, + { + "regionId": "12606", + "keys": "1621768314,2112223568,-739546935,1952137045" + }, + { + "regionId": "12609", + "keys": "-352333436,1298769242,715602788,55374575" + }, + { + "regionId": "12610", + "keys": "923086085,-1676713919,-1072336340,1600346998" + }, + { + "regionId": "12611", + "keys": "-2099572651,-2127878366,1782860351,-1451326946" + }, + { + "regionId": "12614", + "keys": "1621048325,1179863793,357058137,-1896311701" + }, + { + "regionId": "12616", + "keys": "1951523008,-2131232747,-381301931,2007660709" + }, + { + "regionId": "12617", + "keys": "-2118850546,-2021217761,-713637260,-1661397318" + }, + { + "regionId": "12619", + "keys": "1922733696,773456556,-1923866275,-1305839916" + }, + { + "regionId": "12621", + "keys": "1619333755,-1869146576,77302288,-937694202" + }, + { + "regionId": "12623", + "keys": "-369583241,545715110,-134871454,1404138108" + }, + { + "regionId": "12625", + "keys": "-260562230,1208275247,436993278,30028881" + }, + { + "regionId": "12628", + "keys": "1557696523,1576331159,-2104822183,-309564623" + }, + { + "regionId": "12629", + "keys": "-992807501,-2062158526,-154775275,804488735" + }, + { + "regionId": "12630", + "keys": "-1108090696,710523517,2082926636,107778168" + }, + { + "regionId": "12631", + "keys": "693308333,-269450306,-924437218,309489139" + }, + { + "regionId": "12688", + "keys": "1861636222,1638403446,-649444098,2131977195" + }, + { + "regionId": "12689", + "keys": "-1177832090,806845610,-2074522350,793591882" + }, + { + "regionId": "12690", + "keys": "-1658567313,-1665136661,638517615,-2091981200" + }, + { + "regionId": "12691", + "keys": "-998717750,-178246764,973015517,-1732934591" + }, + { + "regionId": "12693", + "keys": "1339198001,799729854,-750687990,1703141753" + }, + { + "regionId": "12694", + "keys": "631068451,-510806123,2026757696,207332608" + }, + { + "regionId": "12696", + "keys": "690970369,-466418236,-666391415,1091047140" + }, + { + "regionId": "12697", + "keys": "1764668344,-101513352,-710472869,-1014452411" + }, + { + "regionId": "12698", + "keys": "-161912285,-1949783111,790481303,987975274" + }, + { + "regionId": "12699", + "keys": "-1844552510,896294306,973094427,-653509731" + }, + { + "regionId": "12700", + "keys": "-1802430094,1220107446,-1897971895,-1437873968" + }, + { + "regionId": "12843", + "keys": "-203885401,22803731,234561826,140244374" + }, + { + "regionId": "12844", + "keys": "226013993,-442175197,1072280142,-2076608354" + }, + { + "regionId": "12845", + "keys": "993041158,1401235448,1282019826,44639213" + }, + { + "regionId": "12846", + "keys": "1813291988,-1182316575,55462006,-1149391696" + }, + { + "regionId": "12847", + "keys": "1632239854,-1407430240,1205200323,-60923789" + }, + { + "regionId": "12848", + "keys": "-830415762,-1655127901,1335930534,2043180488" + }, + { + "regionId": "12849", + "keys": "183396243,-461663209,-212681663,-266126212" + }, + { + "regionId": "12854", + "keys": "-648789394,672092351,713515997,1153393095" + }, + { + "regionId": "12855", + "keys": "1344813934,973665164,454507197,-840789600" + }, + { + "regionId": "12856", + "keys": "1867506737,-1154362361,691839047,840600959" + }, + { + "regionId": "12857", + "keys": "-1061890019,-1503652546,838153390,-1952904011" + }, + { + "regionId": "12858", + "keys": "-503936065,-153634959,2139131102,1736317222" + }, + { + "regionId": "12859", + "keys": "-885548568,-1406566619,-1095540548,-463966144" + }, + { + "regionId": "12860", + "keys": "1143684881,-2095747982,-392775805,1095955025" + }, + { + "regionId": "12861", + "keys": "1816963481,-496926322,1214068433,1190940799" + }, + { + "regionId": "12862", + "keys": "-362546063,986809728,-732925351,-437970150" + }, + { + "regionId": "12865", + "keys": "-1217194532,-1442060965,1622194497,-675929760" + }, + { + "regionId": "12866", + "keys": "-545091180,1146916512,-1890387271,553903087" + }, + { + "regionId": "12867", + "keys": "1462732309,395803116,803023666,-1139113006" + }, + { + "regionId": "12869", + "keys": "14881828,-6662814,58238456,146761213" + }, + { + "regionId": "12870", + "keys": "14881828,-6662814,58238456,146761213" + }, + { + "regionId": "12879", + "keys": "-1368673067,915871651,-1626507432,1807642543" + }, + { + "regionId": "12880", + "keys": "1048762260,1169103285,187905242,-483193099" + }, + { + "regionId": "12884", + "keys": "219137432,-588958221,643827879,166439179" + }, + { + "regionId": "12885", + "keys": "-295659180,1892042068,-983165209,-765523083" + }, + { + "regionId": "12886", + "keys": "-1441695147,730261545,-221502328,1839243995" + }, + { + "regionId": "12887", + "keys": "-1781165696,2082501875,1317465410,954416699" + }, + { + "regionId": "12944", + "keys": "-1975958933,-1193334151,-159998783,-193649368" + }, + { + "regionId": "12945", + "keys": "-901643304,-529015531,-696518247,1093695083" + }, + { + "regionId": "12946", + "keys": "2090546911,-1557720051,696207620,-406031091" + }, + { + "regionId": "12947", + "keys": "721381121,1046071497,646740952,1074713668" + }, + { + "regionId": "12948", + "keys": "-847695159,115342539,-986683415,833544368" + }, + { + "regionId": "12949", + "keys": "-824331278,-1926121844,1635081242,1203632017" + }, + { + "regionId": "12950", + "keys": "-231438779,-295053046,17143297,-1148893582" + }, + { + "regionId": "12951", + "keys": "-1979754927,574273135,-1414539851,-766497717" + }, + { + "regionId": "12952", + "keys": "-1425997721,-1885862885,-1157108098,1841563038" + }, + { + "regionId": "12953", + "keys": "-1250188060,-1799181120,779026206,758487113" + }, + { + "regionId": "12954", + "keys": "1661321273,-1954068524,82368798,1528722778" + }, + { + "regionId": "12955", + "keys": "2001176320,-515563756,-1019109153,347995784" + }, + { + "regionId": "12956", + "keys": "-1383918319,-1190517730,-1037058957,534994622" + }, + { + "regionId": "13099", + "keys": "919393388,-1011543647,454982828,-809340931" + }, + { + "regionId": "13100", + "keys": "284097754,-1500159810,-705437259,-939519544" + }, + { + "regionId": "13101", + "keys": "-381920894,-806030125,-1295289124,905654937" + }, + { + "regionId": "13102", + "keys": "376149710,553132983,-1519502826,1450133972" + }, + { + "regionId": "13103", + "keys": "560689103,-372924587,1002681194,-1313254694" + }, + { + "regionId": "13104", + "keys": "-421493992,1381068261,1710426242,2142500778" + }, + { + "regionId": "13107", + "keys": "-1161498786,-880845643,1588242926,2124040528" + }, + { + "regionId": "13108", + "keys": "-762783054,-1655608106,1991658602,-817463829" + }, + { + "regionId": "13109", + "keys": "-349563312,1574791115,-229143592,422091049" + }, + { + "regionId": "13110", + "keys": "1594041118,976656639,1899969266,-1424829001" + }, + { + "regionId": "13111", + "keys": "-956338858,1803589973,-1931845203,844602202" + }, + { + "regionId": "13112", + "keys": "-1779719436,779690941,517280009,1427658886" + }, + { + "regionId": "13113", + "keys": "1359701469,1140178566,1020850677,-502692445" + }, + { + "regionId": "13114", + "keys": "-1724578067,1811021965,-703977777,-1144440338" + }, + { + "regionId": "13115", + "keys": "135594186,-1586061714,1570753800,1382701347" + }, + { + "regionId": "13116", + "keys": "343282082,-57441829,-10906049,1340555326" + }, + { + "regionId": "13117", + "keys": "-798152548,75895015,1520035830,-1236244245" + }, + { + "regionId": "13118", + "keys": "1803456807,778621268,1763810696,-1674740332" + }, + { + "regionId": "13123", + "keys": "-1731332675,1372380814,1360357859,-476783265" + }, + { + "regionId": "13124", + "keys": "1112524398,1364561637,-1050280898,-561068804" + }, + { + "regionId": "13126", + "keys": "1732039952,536833573,-81136437,1031070663" + }, + { + "regionId": "13131", + "keys": "-1234145533,479347649,1835828804,1685593501" + }, + { + "regionId": "13133", + "keys": "-1026003062,917176839,-84576515,-1037395862" + }, + { + "regionId": "13135", + "keys": "425723212,580084357,1788364975,1608414630" + }, + { + "regionId": "13138", + "keys": "14881828,-6662814,58238456,146761213" + }, + { + "regionId": "13140", + "keys": "-1757870261,1824774693,-1461099709,1915501139" + }, + { + "regionId": "13141", + "keys": "1705435594,233219482,279736542,2096923137" + }, + { + "regionId": "13142", + "keys": "2062386940,-24765133,-1126233768,475032842" + }, + { + "regionId": "13143", + "keys": "1411276783,-169287799,-1924979618,-1103634209" + }, + { + "regionId": "13199", + "keys": "413099653,-805662108,320157580,923467388" + }, + { + "regionId": "13200", + "keys": "-384958441,757681189,-1060421200,1710552745" + }, + { + "regionId": "13201", + "keys": "-777242905,1490139407,-62422504,1747570013" + }, + { + "regionId": "13202", + "keys": "-1507613907,-934138926,557937275,2130611737" + }, + { + "regionId": "13203", + "keys": "-1342258113,-2106603709,395365404,-973258459" + }, + { + "regionId": "13205", + "keys": "1250202258,-2009534633,1981493488,10068968" + }, + { + "regionId": "13206", + "keys": "1456157358,1036496685,-1478577110,-1039552689" + }, + { + "regionId": "13209", + "keys": "-441828435,-1834839387,-1652863357,1161715526" + }, + { + "regionId": "13210", + "keys": "-1843718280,1703682437,-955823154,-1545029718" + }, + { + "regionId": "13211", + "keys": "1293288083,1390574804,1838161452,887056395" + }, + { + "regionId": "13354", + "keys": "-697361682,-1108068736,-491371566,-1750045046" + }, + { + "regionId": "13355", + "keys": "1045096887,204321120,-803556278,-865381665" + }, + { + "regionId": "13356", + "keys": "-1202647115,-2077370353,-776213042,-208608901" + }, + { + "regionId": "13357", + "keys": "1828573590,-917113205,880280264,133645860" + }, + { + "regionId": "13358", + "keys": "41136211,1469481233,1950303317,-915910893" + }, + { + "regionId": "13359", + "keys": "231092921,-248629409,1012469199,966196096" + }, + { + "regionId": "13360", + "keys": "-1860635048,-1994403194,-261420877,899213732" + }, + { + "regionId": "13361", + "keys": "1581119671,589912019,-953848433,669787750" + }, + { + "regionId": "13362", + "keys": "647685229,1735122662,202525670,-1430696427" + }, + { + "regionId": "13363", + "keys": "-1437683143,1313459135,-572808465,628532614" + }, + { + "regionId": "13364", + "keys": "271092435,-91354012,450005855,1673700762" + }, + { + "regionId": "13365", + "keys": "550472972,-90477551,1424060678,-500359242" + }, + { + "regionId": "13366", + "keys": "1555883756,1714912813,693854980,605793741" + }, + { + "regionId": "13367", + "keys": "1443888340,40258892,-827546717,-1706190544" + }, + { + "regionId": "13368", + "keys": "-922499048,1143654396,1593518953,1160947087" + }, + { + "regionId": "13369", + "keys": "-854229759,-1850773237,-273243753,151474217" + }, + { + "regionId": "13370", + "keys": "-1866559281,-1693659798,-1335114197,1185838193" + }, + { + "regionId": "13371", + "keys": "-172414174,1775715954,1436041524,-90862670" + }, + { + "regionId": "13372", + "keys": "1523911372,351024518,1404660376,-1833782282" + }, + { + "regionId": "13373", + "keys": "-1762860860,2070816046,-1848056827,538155683" + }, + { + "regionId": "13374", + "keys": "-2094243426,-1792618509,-1562985614,633233826" + }, + { + "regionId": "13385", + "keys": "-1844924042,1501923681,2039827392,1750236728" + }, + { + "regionId": "13386", + "keys": "897729617,1760669580,-1691319896,1585388050" + }, + { + "regionId": "13387", + "keys": "50769406,1445159687,1657343198,-1977600563" + }, + { + "regionId": "13393", + "keys": "14881828,-6662814,58238456,146761213" + }, + { + "regionId": "13456", + "keys": "-476100316,-1682296770,133855524,112315923" + }, + { + "regionId": "13457", + "keys": "377761737,-478773092,2106772372,2013273184" + }, + { + "regionId": "13458", + "keys": "-528778477,1188068801,-831895341,-843066318" + }, + { + "regionId": "13459", + "keys": "-1539823334,1488607814,-1446817557,887877521" + }, + { + "regionId": "13460", + "keys": "1351713069,1605558913,1016270393,-1439479852" + }, + { + "regionId": "13461", + "keys": "460291665,970577463,-987694183,1332083960" + }, + { + "regionId": "13462", + "keys": "-1293267774,-1055869460,-1910211914,-1862132200" + }, + { + "regionId": "13463", + "keys": "1800919536,-447254446,-1090413707,-1023788925" + }, + { + "regionId": "13464", + "keys": "761967717,-1170068472,1138080117,-622709482" + }, + { + "regionId": "13465", + "keys": "-1620975981,842688962,1124919019,1534496149" + }, + { + "regionId": "13466", + "keys": "-460228398,-76181685,2062962515,1167974062" + }, + { + "regionId": "13610", + "keys": "-1259340500,2094890289,-1255134464,1578867778" + }, + { + "regionId": "13611", + "keys": "-2074654953,2114352944,-1715482214,786241055" + }, + { + "regionId": "13612", + "keys": "1485341915,-607675942,-37541602,-1009921417" + }, + { + "regionId": "13613", + "keys": "1215281736,-1131653641,-2080246040,1849397312" + }, + { + "regionId": "13614", + "keys": "987461267,1277137633,-383892538,1924229470" + }, + { + "regionId": "13615", + "keys": "-1386012819,-1667483384,235442560,2108663059" + }, + { + "regionId": "13616", + "keys": "-2043312890,38355965,-1115381550,-1284493932" + }, + { + "regionId": "13617", + "keys": "778193894,-1569947064,1574720047,1996357073" + }, + { + "regionId": "13618", + "keys": "-710010520,-1679541351,-1318048442,1911381340" + }, + { + "regionId": "13619", + "keys": "-2066053329,414750452,-672870734,-712334802" + }, + { + "regionId": "13620", + "keys": "-2036291738,1473612575,9834035,-1983739737" + }, + { + "regionId": "13621", + "keys": "-1291167236,-1205011126,-1949699235,1530879202" + }, + { + "regionId": "13623", + "keys": "-1700397822,-1427942931,1638091118,438962861" + }, + { + "regionId": "13624", + "keys": "2111564081,-1121458759,1205557925,-386058131" + }, + { + "regionId": "13625", + "keys": "-1688194808,-751145145,-64310690,-9400824" + }, + { + "regionId": "13626", + "keys": "2091552269,-19993197,919014338,-2088295508" + }, + { + "regionId": "13627", + "keys": "341129543,405594157,-935930552,1362472171" + }, + { + "regionId": "13628", + "keys": "83847925,-1748584368,-1828230097,915424426" + }, + { + "regionId": "13629", + "keys": "-1526659316,194744161,-1617203167,1822755797" + }, + { + "regionId": "13630", + "keys": "-1632016999,-2015192780,-2137722473,477794767" + }, + { + "regionId": "13641", + "keys": "-1254291903,557840049,-1132517830,-721853650" + }, + { + "regionId": "13642", + "keys": "1339676474,261360204,1438006333,-388997930" + }, + { + "regionId": "13643", + "keys": "1113875885,-236852397,193142585,-854043613" + }, + { + "regionId": "13650", + "keys": "-1281992532,-252178835,-207196406,32900092" + }, + { + "regionId": "13712", + "keys": "1182236806,-2109123887,1909535742,814317528" + }, + { + "regionId": "13713", + "keys": "676853493,-1887443315,-998811191,1947183065" + }, + { + "regionId": "13716", + "keys": "-913580283,340446282,893998558,589419388" + }, + { + "regionId": "13717", + "keys": "1559468575,-1513642990,42449462,-1614119576" + }, + { + "regionId": "13718", + "keys": "1236641739,1389287026,-557291512,739408472" + }, + { + "regionId": "13719", + "keys": "869116958,119952924,524051369,-980103253" + }, + { + "regionId": "13720", + "keys": "1147506557,-1510069284,-691462718,-1314001105" + }, + { + "regionId": "13721", + "keys": "-1188425330,1307846097,888707126,-1843934128" + }, + { + "regionId": "13723", + "keys": "-310574621,110640497,1685108265,-1931806505" + }, + { + "regionId": "13866", + "keys": "1975204579,1739471741,-609874514,-809721138" + }, + { + "regionId": "13867", + "keys": "249804189,-1087394076,-1963925587,-493571779" + }, + { + "regionId": "13868", + "keys": "255205616,-1585903009,-1371243067,-264891948" + }, + { + "regionId": "13872", + "keys": "-865041276,1374390842,-909885942,30088570" + }, + { + "regionId": "13873", + "keys": "-2072799260,1290574946,-1228463084,1431541780" + }, + { + "regionId": "13874", + "keys": "301169312,1180543257,595363434,555835168" + }, + { + "regionId": "13875", + "keys": "1853922477,1565380766,632797823,-2047432156" + }, + { + "regionId": "13876", + "keys": "-1056000495,1278886569,-1666375011,492887698" + }, + { + "regionId": "13877", + "keys": "1498185652,2064367906,152992439,585271079" + }, + { + "regionId": "13879", + "keys": "-2101514338,-1139447054,51825149,-512907347" + }, + { + "regionId": "13880", + "keys": "-672032867,-104766980,-780173326,-1476119873" + }, + { + "regionId": "13897", + "keys": "313069291,-285427198,720562158,55799827" + }, + { + "regionId": "13898", + "keys": "-975892323,-614503529,1538650880,-1348349880" + }, + { + "regionId": "13899", + "keys": "-2117805741,-268051413,-733527930,471010998" + }, + { + "regionId": "13905", + "keys": "14881828,-6662814,58238456,146761213" + }, + { + "regionId": "13968", + "keys": "-620062336,-1110235330,-1095431209,-470716307" + }, + { + "regionId": "13972", + "keys": "1266294685,1139088638,1514900183,-1389022839" + }, + { + "regionId": "13974", + "keys": "1384510929,1857691725,-293821029,-1219099456" + }, + { + "regionId": "13975", + "keys": "715007080,565579966,-981729179,-1644711038" + }, + { + "regionId": "13976", + "keys": "-2067573994,1313918283,-503877523,-561145139" + }, + { + "regionId": "13977", + "keys": "-2103542752,-239401853,-1270017944,-346347052" + }, + { + "regionId": "13978", + "keys": "605186559,-2092944993,404136076,399569943" + }, + { + "regionId": "13979", + "keys": "-1418903263,-1115529276,-670759508,770213401" + }, + { + "regionId": "13980", + "keys": "-12957944,-743456598,2041601862,618819565" + }, + { + "regionId": "14128", + "keys": "1907787432,-241593923,1152767085,-541422403" + }, + { + "regionId": "14129", + "keys": "1656428349,-1031219549,1014397898,274724415" + }, + { + "regionId": "14130", + "keys": "415779481,-1959726011,1999247323,1438983993" + }, + { + "regionId": "14131", + "keys": "-489058667,-1946048627,826928526,-193826197" + }, + { + "regionId": "14132", + "keys": "-602589023,1702162086,-1444941032,1758850020" + }, + { + "regionId": "14133", + "keys": "61264177,326475438,1849288713,-191758257" + }, + { + "regionId": "14134", + "keys": "-1102558063,817524163,-892019492,-1799662614" + }, + { + "regionId": "14135", + "keys": "-1676933435,2078032557,110306649,-960667243" + }, + { + "regionId": "14136", + "keys": "-1104533465,1792124817,-1564247177,79706641" + }, + { + "regionId": "14157", + "keys": "-852479713,1901063521,-1097484894,1013793379" + }, + { + "regionId": "14161", + "keys": "14881828,-6662814,58238456,146761213" + }, + { + "regionId": "14167", + "keys": "-1398455,-469478596,190482870,-1233173597" + }, + { + "regionId": "14230", + "keys": "-453901412,-2074594443,-809419406,1774073603" + }, + { + "regionId": "14231", + "keys": "-1716965138,-1451197740,-1942368593,-900089071" + }, + { + "regionId": "14232", + "keys": "-154845838,1035699282,361824423,-776192310" + }, + { + "regionId": "14233", + "keys": "1754401715,23594529,1369802619,1852247641" + }, + { + "regionId": "14234", + "keys": "1142480925,-261960203,-1951671560,-1615735123" + }, + { + "regionId": "14235", + "keys": "-264565085,233987061,-1946292625,1978910655" + }, + { + "regionId": "14236", + "keys": "816141215,-2114312227,1578950035,1471842311" + }, + { + "regionId": "14380", + "keys": "1663518625,-107913441,-1625821936,330353351" + }, + { + "regionId": "14381", + "keys": "-534048527,1614741928,-469012711,1064350100" + }, + { + "regionId": "14382", + "keys": "-1852773504,1082744219,-1346163454,554948186" + }, + { + "regionId": "14383", + "keys": "2130321690,-902060426,334275700,1881115024" + }, + { + "regionId": "14384", + "keys": "1875853789,1099975670,-125982769,-1614539446" + }, + { + "regionId": "14385", + "keys": "14881828,-6662814,58238456,146761213" + }, + { + "regionId": "14386", + "keys": "454702874,-889424896,1044373821,1857098733" + }, + { + "regionId": "14387", + "keys": "-1786083312,-89773863,-203660164,1188286162" + }, + { + "regionId": "14388", + "keys": "2048238173,2003642395,1658667134,411519881" + }, + { + "regionId": "14390", + "keys": "-1631704360,1281079278,-1549067757,-2034268623" + }, + { + "regionId": "14391", + "keys": "-1092656394,771935864,-1698940035,222468187" + }, + { + "regionId": "14392", + "keys": "993603906,-1477196579,593064486,166369140" + }, + { + "regionId": "14486", + "keys": "-131982139,-1189975142,-1667401999,-1794787704" + }, + { + "regionId": "14487", + "keys": "-330478679,11506767,395036194,-971774384" + }, + { + "regionId": "14490", + "keys": "1578682567,-1175551739,170259358,-1972709096" + }, + { + "regionId": "14491", + "keys": "1131750208,-969132110,-1692936039,708031851" + }, + { + "regionId": "14492", + "keys": "420310205,1004898846,889537686,13961361" + }, + { + "regionId": "14636", + "keys": "-1554034534,-545576842,-416921234,1887723532" + }, + { + "regionId": "14637", + "keys": "112774068,-1867270219,-442076728,-1436438131" + }, + { + "regionId": "14638", + "keys": "139650389,-1351993356,-191474863,1802091532" + }, + { + "regionId": "14639", + "keys": "303035230,-26013293,2131971123,-1774131228" + }, + { + "regionId": "14640", + "keys": "-95254230,-1094148730,-1768319507,105210786" + }, + { + "regionId": "14641", + "keys": "-310201697,1724559662,90126688,-664432561" + }, + { + "regionId": "14646", + "keys": "-2069357113,-2117603296,1620573021,-239596308" + }, + { + "regionId": "14647", + "keys": "727908174,1305814331,1158279049,-671924266" + }, + { + "regionId": "14648", + "keys": "-1757352130,-1996516705,263017190,1647356258" + }, + { + "regionId": "14746", + "keys": "2081288932,-143900986,-1978370486,-544919360" + }, + { + "regionId": "14747", + "keys": "-1578483383,-20501195,-1713759865,-1923019830" + }, + { + "regionId": "14891", + "keys": "-1481978705,1351387379,139803217,1691844424" + }, + { + "regionId": "14892", + "keys": "989249908,1611912325,-656482965,739987970" + }, + { + "regionId": "14893", + "keys": "-102394113,1484262111,933695487,-283213546" + }, + { + "regionId": "14894", + "keys": "1977203476,853289993,-2077288740,253834425" + }, + { + "regionId": "14895", + "keys": "1294223700,778677766,-2141486577,1402077049" + }, + { + "regionId": "14896", + "keys": "548765086,801664009,-1716752945,-1492954302" + }, + { + "regionId": "14902", + "keys": "1158948283,-12013143,1242958376,-1265402384" + }, + { + "regionId": "14903", + "keys": "-1111240831,1790345264,-366658712,-331374702" + }, + { + "regionId": "14904", + "keys": "-1967472485,-192437954,1186759929,-2078112945" + }, + { + "regionId": "14994", + "keys": "413330323,-1806118667,1556971780,2103428744" + }, + { + "regionId": "14995", + "keys": "958328498,239876404,608758325,933929091" + }, + { + "regionId": "15147", + "keys": "-423978185,359589519,280220972,-1608470374" + }, + { + "regionId": "15149", + "keys": "-1200628316,15132614,-465260385,-1525542932" + }, + { + "regionId": "15150", + "keys": "14881828,-6662814,58238456,146761213" + }, + { + "regionId": "15151", + "keys": "867970623,-1689124083,1669326780,1599898304" + }, + { + "regionId": "15152", + "keys": "608495786,-1850745649,1481459068,44047411" + }, + { + "regionId": "15158", + "keys": "-974248920,-1426940984,-551894435,1783499939" + }, + { + "regionId": "15159", + "keys": "777796740,816768733,590882478,-1949779286" + }, + { + "regionId": "15160", + "keys": "-553466395,-1372948696,-1385390322,710626387" + }, + { + "regionId": "15248", + "keys": "552557289,1687845482,-1717041637,1667279986" + }, + { + "regionId": "15251", + "keys": "-1712638393,-327927536,168969136,485363494" + }, + { + "regionId": "15403", + "keys": "858832565,1542433274,-759104113,425400841" + }, + { + "regionId": "15404", + "keys": "1359247125,-1375693391,-1964404624,-1289877028" + }, + { + "regionId": "15405", + "keys": "1745315296,704015968,-1726703759,250744336" + }, + { + "regionId": "15406", + "keys": "900232781,1037303290,2099698517,-1839409134" + }, + { + "regionId": "15407", + "keys": "-1139819812,165771634,462281145,-1626973480" + }, + { + "regionId": "15408", + "keys": "1024233955,-1429048064,1595885074,-1194249874" + }, + { + "regionId": "15414", + "keys": "918566284,-159243781,471949969,-1198041007" + }, + { + "regionId": "15415", + "keys": "-1274724478,1165018389,2048231360,2009587731" + }, + { + "regionId": "15416", + "keys": "-1802759876,1171188898,1330028340,1790091100" + } + ] +} \ No newline at end of file diff --git a/Server/data/eco/.gitignore b/Server/data/eco/.gitignore new file mode 100644 index 0000000..5e7d273 --- /dev/null +++ b/Server/data/eco/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore diff --git a/Server/db_exports/global.sql b/Server/db_exports/global.sql new file mode 100644 index 0000000..255acee --- /dev/null +++ b/Server/db_exports/global.sql @@ -0,0 +1,127 @@ +CREATE DATABASE global; + +USE global; + +-- phpMyAdmin SQL Dump +-- version 5.0.2 +-- https://www.phpmyadmin.net/ +-- +-- Host: 127.0.0.1 +-- Generation Time: Sep 23, 2020 at 08:45 PM +-- Server version: 10.4.14-MariaDB +-- PHP Version: 7.4.9 + +SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; +START TRANSACTION; +SET time_zone = "+00:00"; + + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8mb4 */; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `members` +-- + +CREATE TABLE `members` ( + `UID` int(11) UNSIGNED NOT NULL, + `email` varchar(50) NOT NULL DEFAULT '', + `username` varchar(15) DEFAULT NULL, + `password` varchar(100) DEFAULT NULL, + `salt` varchar(35) DEFAULT NULL, + `rights` int(1) NOT NULL DEFAULT 0, + `email_activated` int(1) NOT NULL DEFAULT 0, + `lastActive` timestamp NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(), + `donatorType` int(2) NOT NULL DEFAULT -1, + `donationTotal` double(10,2) NOT NULL DEFAULT 0.00, + `credits` int(5) NOT NULL DEFAULT 0, + `icon` int(2) NOT NULL DEFAULT 0, + `perks` varchar(500) NOT NULL DEFAULT '', + `ip` longtext DEFAULT NULL, + `mac` longtext DEFAULT NULL, + `serial` longtext DEFAULT NULL, + `computerName` varchar(2000) NOT NULL DEFAULT '', + `monthlyVotes` int(11) NOT NULL DEFAULT 0, + `netWorth` bigint(200) NOT NULL DEFAULT 0, + `forumUID` int(11) NOT NULL DEFAULT -1, + `ironManMode` varchar(15) NOT NULL DEFAULT 'NONE', + `bank` longtext DEFAULT NULL, + `inventory` longtext DEFAULT NULL, + `equipment` longtext DEFAULT NULL, + `ge` longtext DEFAULT NULL, + `muteTime` bigint(20) NOT NULL DEFAULT -1, + `banTime` bigint(20) NOT NULL DEFAULT -1, + `profileImage` varchar(300) DEFAULT NULL, + `contacts` longtext DEFAULT NULL, + `blocked` longtext DEFAULT NULL, + `clanName` varchar(15) NOT NULL DEFAULT '', + `currentClan` varchar(15) DEFAULT NULL, + `clanReqs` varchar(10) NOT NULL DEFAULT '1,0,8,9', + `disconnectTime` bigint(20) NOT NULL DEFAULT 0, + `lastWorld` int(3) NOT NULL DEFAULT -1, + `chatSettings` varchar(10) NOT NULL DEFAULT '0,0,0', + `timePlayed` bigint(20) DEFAULT 0, + `lastLogin` bigint(20) NOT NULL DEFAULT 0, + `lastGameIp` varchar(15) DEFAULT '', + `countryCode` int(11) NOT NULL DEFAULT 0, + `birthday` date DEFAULT NULL, + `online` tinyint(1) NOT NULL DEFAULT 0, + `signature` longtext DEFAULT NULL, + `joined_date` timestamp NULL DEFAULT NULL, + `posts` int(11) NOT NULL DEFAULT 0 +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +-- +-- Table structure for table `worlds` +-- + +CREATE TABLE `worlds` ( + `world` int(2) UNSIGNED NOT NULL, + `ip` varchar(20) NOT NULL DEFAULT '127.0.0.1', + `players` int(5) NOT NULL DEFAULT 0, + `country` int(1) NOT NULL DEFAULT 0, + `member` int(11) NOT NULL, + `revision` int(3) NOT NULL DEFAULT 530, + `lastResponse` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp() +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +-- +-- Dumping data for table `worlds` +-- + +INSERT INTO `worlds` (`world`, `ip`, `players`, `country`, `member`, `revision`, `lastResponse`) VALUES +(1, '127.0.0.1', 0, 22, 1, 530, '2020-09-23 18:27:05'); + +-- +-- Indexes for dumped tables +-- + +-- +-- Indexes for table `members` +-- +ALTER TABLE `members` + ADD PRIMARY KEY (`UID`); + +-- +-- Indexes for table `worlds` +-- +ALTER TABLE `worlds` + ADD PRIMARY KEY (`world`); + +-- +-- AUTO_INCREMENT for dumped tables +-- + +-- +-- AUTO_INCREMENT for table `members` +-- +ALTER TABLE `members` + MODIFY `UID` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4; + +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; diff --git a/Server/db_exports/grafana-dashboard.json b/Server/db_exports/grafana-dashboard.json new file mode 100644 index 0000000..5d4b68c --- /dev/null +++ b/Server/db_exports/grafana-dashboard.json @@ -0,0 +1,539 @@ +{ + "__inputs": [ + { + "name": "DS_SQLITE", + "label": "SQLite", + "description": "", + "type": "datasource", + "pluginId": "frser-sqlite-datasource", + "pluginName": "SQLite" + } + ], + "__elements": {}, + "__requires": [ + { + "type": "datasource", + "id": "frser-sqlite-datasource", + "name": "SQLite", + "version": "3.3.0" + }, + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "10.0.1" + }, + { + "type": "panel", + "id": "timeseries", + "name": "Time series", + "version": "" + } + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": null, + "links": [], + "liveNow": false, + "panels": [ + { + "datasource": { + "type": "frser-sqlite-datasource", + "uid": "${DS_SQLITE}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "misc_pulses" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "purple", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "other" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-red", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "packet_incoming" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "super-light-red", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 9, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 1, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "10.0.1", + "targets": [ + { + "datasource": { + "type": "frser-sqlite-datasource", + "uid": "${DS_SQLITE}" + }, + "queryText": "SELECT * FROM tick_lengths", + "queryType": "table", + "rawQueryText": "SELECT * FROM tick_lengths", + "refId": "A", + "timeColumns": [ + "ts" + ] + } + ], + "title": "Tick Time", + "type": "timeseries" + }, + { + "datasource": { + "type": "frser-sqlite-datasource", + "uid": "${DS_SQLITE}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 13, + "w": 13, + "x": 0, + "y": 9 + }, + "id": 2, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "10.0.1", + "targets": [ + { + "datasource": { + "type": "frser-sqlite-datasource", + "uid": "${DS_SQLITE}" + }, + "queryText": "select * from top_pulses;", + "queryType": "table", + "rawQueryText": "select * from top_pulses;", + "refId": "A", + "timeColumns": [ + "time", + "ts" + ] + } + ], + "title": "Tick Time By Pulse (Total)", + "transformations": [ + { + "id": "extractFields", + "options": { + "format": "json", + "jsonPaths": [ + { + "path": "pulses" + } + ], + "keepTime": false, + "replace": false, + "source": "pulse_info" + } + }, + { + "id": "extractFields", + "options": { + "source": "pulses" + } + } + ], + "type": "timeseries" + }, + { + "datasource": { + "type": "frser-sqlite-datasource", + "uid": "${DS_SQLITE}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 9, + "w": 11, + "x": 13, + "y": 9 + }, + "id": 4, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "frser-sqlite-datasource", + "uid": "${DS_SQLITE}" + }, + "queryText": "SELECT * FROM high_volume_pulses;", + "queryType": "table", + "rawQueryText": "SELECT * FROM high_volume_pulses;", + "refId": "A", + "timeColumns": [ + "time", + "ts" + ] + } + ], + "title": "High Volume Pulses", + "transformations": [ + { + "id": "extractFields", + "options": { + "format": "json", + "source": "pulse_info" + } + }, + { + "id": "extractFields", + "options": { + "source": "pulses" + } + } + ], + "type": "timeseries" + }, + { + "datasource": { + "type": "frser-sqlite-datasource", + "uid": "${DS_SQLITE}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "stepBefore", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 11, + "x": 13, + "y": 18 + }, + "id": 3, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "frser-sqlite-datasource", + "uid": "${DS_SQLITE}" + }, + "queryText": "SELECT * FROM bot_counts;", + "queryType": "table", + "rawQueryText": "SELECT * FROM bot_counts;", + "refId": "A", + "timeColumns": [ + "time", + "ts" + ] + } + ], + "title": "Bot Population", + "type": "timeseries" + } + ], + "refresh": "1h", + "schemaVersion": 38, + "style": "dark", + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-5m", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Main", + "uid": "ffccf845-00a2-46f2-b0c0-a8b88032c701", + "version": 10, + "weekStart": "" +} \ No newline at end of file diff --git a/Server/db_exports/testuser.sql b/Server/db_exports/testuser.sql new file mode 100644 index 0000000..d9d7521 --- /dev/null +++ b/Server/db_exports/testuser.sql @@ -0,0 +1,2 @@ +CREATE USER IF NOT EXISTS 2009scapetest@localhost IDENTIFIED BY '2009scapetest'; +GRANT ALL PRIVILEGES ON global.* TO 2009scapetest@localhost; \ No newline at end of file diff --git a/Server/detekt.yml b/Server/detekt.yml new file mode 100644 index 0000000..706aec9 --- /dev/null +++ b/Server/detekt.yml @@ -0,0 +1,713 @@ +build: + maxIssues: 0 + excludeCorrectable: false + weights: + # complexity: 2 + # LongParameterList: 1 + # style: 1 + # comments: 1 + +config: + validation: true + warningsAsErrors: false + # when writing own rules with new properties, exclude the property path e.g.: 'my_rule_set,.*>.*>[my_property]' + excludes: '' + +processors: + active: true + exclude: + - 'DetektProgressListener' + # - 'KtFileCountProcessor' + # - 'PackageCountProcessor' + # - 'ClassCountProcessor' + # - 'FunctionCountProcessor' + # - 'PropertyCountProcessor' + # - 'ProjectComplexityProcessor' + # - 'ProjectCognitiveComplexityProcessor' + # - 'ProjectLLOCProcessor' + # - 'ProjectCLOCProcessor' + # - 'ProjectLOCProcessor' + # - 'ProjectSLOCProcessor' + # - 'LicenseHeaderLoaderExtension' + +console-reports: + active: true + exclude: + - 'ProjectStatisticsReport' + - 'ComplexityReport' + - 'NotificationReport' + - 'FindingsReport' + - 'FileBasedFindingsReport' + # - 'LiteFindingsReport' + +output-reports: + active: true + exclude: + # - 'TxtOutputReport' + # - 'XmlOutputReport' + # - 'HtmlOutputReport' + # - 'MdOutputReport' + +comments: + active: true + AbsentOrWrongFileLicense: + active: false + licenseTemplateFile: 'license.template' + licenseTemplateIsRegex: false + CommentOverPrivateFunction: + active: false + CommentOverPrivateProperty: + active: false + DeprecatedBlockTag: + active: false + EndOfSentenceFormat: + active: false + endOfSentenceFormat: '([.?!][ \t\n\r\f<])|([.?!:]$)' + KDocReferencesNonPublicProperty: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + OutdatedDocumentation: + active: false + matchTypeParameters: true + matchDeclarationsOrder: true + allowParamOnConstructorProperties: false + UndocumentedPublicClass: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + searchInNestedClass: true + searchInInnerClass: true + searchInInnerObject: true + searchInInnerInterface: true + UndocumentedPublicFunction: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + UndocumentedPublicProperty: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + +complexity: + active: true + ComplexCondition: + active: false + threshold: 4 + ComplexInterface: + active: false + threshold: 10 + includeStaticDeclarations: false + includePrivateDeclarations: false + ComplexMethod: + active: false + threshold: 15 + ignoreSingleWhenExpression: false + ignoreSimpleWhenEntries: false + ignoreNestingFunctions: false + nestingFunctions: + - 'also' + - 'apply' + - 'forEach' + - 'isNotNull' + - 'ifNull' + - 'let' + - 'run' + - 'use' + - 'with' + LabeledExpression: + active: false + ignoredLabels: [] + LargeClass: + active: false + threshold: 600 + LongMethod: + active: false + threshold: 60 + LongParameterList: + active: false + functionThreshold: 6 + constructorThreshold: 7 + ignoreDefaultParameters: false + ignoreDataClasses: true + ignoreAnnotatedParameter: [] + MethodOverloading: + active: false + threshold: 6 + NamedArguments: + active: false + threshold: 3 + ignoreArgumentsMatchingNames: false + NestedBlockDepth: + active: false + threshold: 4 + NestedScopeFunctions: + active: false + threshold: 1 + functions: + - 'kotlin.apply' + - 'kotlin.run' + - 'kotlin.with' + - 'kotlin.let' + - 'kotlin.also' + ReplaceSafeCallChainWithRun: + active: false + StringLiteralDuplication: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + threshold: 3 + ignoreAnnotation: true + excludeStringsWithLessThan5Characters: true + ignoreStringsRegex: '$^' + TooManyFunctions: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + thresholdInFiles: 11 + thresholdInClasses: 11 + thresholdInInterfaces: 11 + thresholdInObjects: 11 + thresholdInEnums: 11 + ignoreDeprecated: false + ignorePrivate: false + ignoreOverridden: false + +coroutines: + active: true + GlobalCoroutineUsage: + active: false + InjectDispatcher: + active: true + dispatcherNames: + - 'IO' + - 'Default' + - 'Unconfined' + RedundantSuspendModifier: + active: true + SleepInsteadOfDelay: + active: true + SuspendFunWithCoroutineScopeReceiver: + active: false + SuspendFunWithFlowReturnType: + active: true + +empty-blocks: + active: false + EmptyCatchBlock: + active: true + allowedExceptionNameRegex: '_|(ignore|expected).*' + EmptyClassBlock: + active: true + EmptyDefaultConstructor: + active: true + EmptyDoWhileBlock: + active: true + EmptyElseBlock: + active: true + EmptyFinallyBlock: + active: true + EmptyForBlock: + active: true + EmptyFunctionBlock: + active: true + ignoreOverridden: false + EmptyIfBlock: + active: true + EmptyInitBlock: + active: true + EmptyKtFile: + active: true + EmptySecondaryConstructor: + active: true + EmptyTryBlock: + active: true + EmptyWhenBlock: + active: true + EmptyWhileBlock: + active: true + +exceptions: + active: true + ExceptionRaisedInUnexpectedLocation: + active: true + methodNames: + - 'equals' + - 'finalize' + - 'hashCode' + - 'toString' + InstanceOfCheckForException: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + NotImplementedDeclaration: + active: false + ObjectExtendsThrowable: + active: false + PrintStackTrace: + active: false + RethrowCaughtException: + active: true + ReturnFromFinally: + active: true + ignoreLabeled: false + SwallowedException: + active: false + ignoredExceptionTypes: + - 'InterruptedException' + - 'MalformedURLException' + - 'NumberFormatException' + - 'ParseException' + allowedExceptionNameRegex: '_|(ignore|expected).*' + ThrowingExceptionFromFinally: + active: true + ThrowingExceptionInMain: + active: false + ThrowingExceptionsWithoutMessageOrCause: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + exceptions: + - 'ArrayIndexOutOfBoundsException' + - 'Exception' + - 'IllegalArgumentException' + - 'IllegalMonitorStateException' + - 'IllegalStateException' + - 'IndexOutOfBoundsException' + - 'NullPointerException' + - 'RuntimeException' + - 'Throwable' + ThrowingNewInstanceOfSameException: + active: true + TooGenericExceptionCaught: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + exceptionNames: + - 'ArrayIndexOutOfBoundsException' + - 'Error' + - 'Exception' + - 'IllegalMonitorStateException' + - 'IndexOutOfBoundsException' + - 'NullPointerException' + - 'RuntimeException' + - 'Throwable' + allowedExceptionNameRegex: '_|(ignore|expected).*' + TooGenericExceptionThrown: + active: false + exceptionNames: + - 'Error' + - 'Exception' + - 'RuntimeException' + - 'Throwable' + +naming: + active: true + BooleanPropertyNaming: + active: false + allowedPattern: '^(is|has|are)' + ignoreOverridden: true + ClassNaming: + active: false + classPattern: '[A-Z][a-zA-Z0-9]*' + ConstructorParameterNaming: + active: false + parameterPattern: '[a-z][A-Za-z0-9]*' + privateParameterPattern: '[a-z][A-Za-z0-9]*' + excludeClassPattern: '$^' + ignoreOverridden: true + EnumNaming: + active: true + enumEntryPattern: '[A-Z][_a-zA-Z0-9]*' + ForbiddenClassName: + active: false + forbiddenName: [] + FunctionMaxLength: + active: false + maximumFunctionNameLength: 30 + FunctionMinLength: + active: false + minimumFunctionNameLength: 3 + FunctionNaming: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + functionPattern: '[a-z][a-zA-Z0-9]*' + excludeClassPattern: '$^' + ignoreOverridden: true + FunctionParameterNaming: + active: false + parameterPattern: '[a-z][A-Za-z0-9]*' + excludeClassPattern: '$^' + ignoreOverridden: true + InvalidPackageDeclaration: + active: false + rootPackage: '' + requireRootInDeclaration: false + LambdaParameterNaming: + active: false + parameterPattern: '[a-z][A-Za-z0-9]*|_' + MatchingDeclarationName: + active: false + mustBeFirst: true + MemberNameEqualsClassName: + active: false + ignoreOverridden: true + NoNameShadowing: + active: true + NonBooleanPropertyPrefixedWithIs: + active: false + ObjectPropertyNaming: + active: true + constantPattern: '[A-Za-z][_A-Za-z0-9]*' + propertyPattern: '[A-Za-z][_A-Za-z0-9]*' + privatePropertyPattern: '(_)?[A-Za-z][_A-Za-z0-9]*' + PackageNaming: + active: false + packagePattern: '[a-z]+(\.[a-z][A-Za-z0-9]*)*' + TopLevelPropertyNaming: + active: false + constantPattern: '[A-Z][_A-Z0-9]*' + propertyPattern: '[A-Za-z][_A-Za-z0-9]*' + privatePropertyPattern: '_?[A-Za-z][_A-Za-z0-9]*' + VariableMaxLength: + active: false + maximumVariableNameLength: 64 + VariableMinLength: + active: false + minimumVariableNameLength: 1 + VariableNaming: + active: false + variablePattern: '[a-z][A-Za-z0-9]*' + privateVariablePattern: '(_)?[a-z][A-Za-z0-9]*' + excludeClassPattern: '$^' + ignoreOverridden: true + +performance: + active: true + ArrayPrimitive: + active: false + CouldBeSequence: + active: false + threshold: 3 + ForEachOnRange: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + SpreadOperator: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + UnnecessaryTemporaryInstantiation: + active: true + +potential-bugs: + active: true + AvoidReferentialEquality: + active: true + forbiddenTypePatterns: + - 'kotlin.String' + CastToNullableType: + active: false + Deprecation: + active: false + DontDowncastCollectionTypes: + active: false + DoubleMutabilityForCollection: + active: true + mutableTypes: + - 'kotlin.collections.MutableList' + - 'kotlin.collections.MutableMap' + - 'kotlin.collections.MutableSet' + - 'java.util.ArrayList' + - 'java.util.LinkedHashSet' + - 'java.util.HashSet' + - 'java.util.LinkedHashMap' + - 'java.util.HashMap' + DuplicateCaseInWhenExpression: + active: true + ElseCaseInsteadOfExhaustiveWhen: + active: false + EqualsAlwaysReturnsTrueOrFalse: + active: true + EqualsWithHashCodeExist: + active: true + ExitOutsideMain: + active: false + ExplicitGarbageCollectionCall: + active: false + HasPlatformType: + active: true + IgnoredReturnValue: + active: true + restrictToAnnotatedMethods: true + returnValueAnnotations: + - '*.CheckResult' + - '*.CheckReturnValue' + - 'com.google.errorprone.annotations.CheckReturnValue' + ignoreReturnValueAnnotations: + - '*.CanIgnoreReturnValue' + ignoreFunctionCall: [] + ImplicitDefaultLocale: + active: false + ImplicitUnitReturnType: + active: false + allowExplicitReturnType: true + InvalidRange: + active: true + IteratorHasNextCallsNextMethod: + active: true + IteratorNotThrowingNoSuchElementException: + active: true + LateinitUsage: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + ignoreOnClassesPattern: '' + MapGetWithNotNullAssertionOperator: + active: true + MissingPackageDeclaration: + active: false + excludes: ['**/*.kts'] + MissingWhenCase: + active: true + allowElseExpression: true + NullCheckOnMutableProperty: + active: false + NullableToStringCall: + active: false + RedundantElseInWhen: + active: true + UnconditionalJumpStatementInLoop: + active: false + UnnecessaryNotNullOperator: + active: true + UnnecessarySafeCall: + active: true + UnreachableCatchBlock: + active: true + UnreachableCode: + active: true + UnsafeCallOnNullableType: + active: true + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + UnsafeCast: + active: true + UnusedUnaryOperator: + active: true + UselessPostfixExpression: + active: false + WrongEqualsTypeParameter: + active: true + +style: + active: true + CanBeNonNullable: + active: false + CascadingCallWrapping: + active: false + includeElvis: true + ClassOrdering: + active: false + CollapsibleIfStatements: + active: false + DataClassContainsFunctions: + active: false + conversionFunctionPrefix: 'to' + DataClassShouldBeImmutable: + active: false + DestructuringDeclarationWithTooManyEntries: + active: true + maxDestructuringEntries: 3 + EqualsNullCall: + active: true + EqualsOnSignatureLine: + active: false + ExplicitCollectionElementAccessMethod: + active: false + ExplicitItLambdaParameter: + active: false + ExpressionBodySyntax: + active: false + includeLineWrapping: false + ForbiddenComment: + active: false + values: + - 'FIXME:' + - 'STOPSHIP:' + - 'TODO:' + allowedPatterns: '' + customMessage: '' + ForbiddenImport: + active: false + imports: [] + forbiddenPatterns: '' + ForbiddenMethodCall: + active: false + methods: + - 'kotlin.io.print' + - 'kotlin.io.println' + ForbiddenPublicDataClass: + active: true + excludes: ['**'] + ignorePackages: + - '*.internal' + - '*.internal.*' + ForbiddenSuppress: + active: false + rules: [] + ForbiddenVoid: + active: true + ignoreOverridden: false + ignoreUsageInGenerics: false + FunctionOnlyReturningConstant: + active: false + ignoreOverridableFunction: true + ignoreActualFunction: true + excludedFunctions: '' + LibraryCodeMustSpecifyReturnType: + active: true + excludes: ['**'] + LibraryEntitiesShouldNotBePublic: + active: true + excludes: ['**'] + LoopWithTooManyJumpStatements: + active: false + maxJumpCount: 1 + MagicNumber: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**', '**/*.kts'] + ignoreNumbers: + - '-1' + - '0' + - '1' + - '2' + ignoreHashCodeFunction: true + ignorePropertyDeclaration: false + ignoreLocalVariableDeclaration: false + ignoreConstantDeclaration: true + ignoreCompanionObjectPropertyDeclaration: true + ignoreAnnotation: false + ignoreNamedArgument: true + ignoreEnums: false + ignoreRanges: false + ignoreExtensionFunctions: true + MandatoryBracesIfStatements: + active: false + MandatoryBracesLoops: + active: false + MaxChainedCallsOnSameLine: + active: false + maxChainedCalls: 5 + MaxLineLength: + active: false + maxLineLength: 120 + excludePackageStatements: true + excludeImportStatements: true + excludeCommentStatements: false + MayBeConst: + active: false + ModifierOrder: + active: false + MultilineLambdaItParameter: + active: false + NestedClassesVisibility: + active: true + NewLineAtEndOfFile: + active: false + NoTabs: + active: false + NullableBooleanCheck: + active: false + ObjectLiteralToLambda: + active: true + OptionalAbstractKeyword: + active: false + OptionalUnit: + active: false + OptionalWhenBraces: + active: false + PreferToOverPairSyntax: + active: false + ProtectedMemberInFinalClass: + active: true + RedundantExplicitType: + active: false + RedundantHigherOrderMapUsage: + active: true + RedundantVisibilityModifierRule: + active: false + ReturnCount: + active: false + max: 2 + excludedFunctions: 'equals' + excludeLabeled: false + excludeReturnFromLambda: true + excludeGuardClauses: false + SafeCast: + active: true + SerialVersionUIDInSerializableClass: + active: true + SpacingBetweenPackageAndImports: + active: false + ThrowsCount: + active: false + max: 2 + excludeGuardClauses: false + TrailingWhitespace: + active: false + UnderscoresInNumericLiterals: + active: false + acceptableLength: 4 + allowNonStandardGrouping: false + UnnecessaryAbstractClass: + active: true + UnnecessaryAnnotationUseSiteTarget: + active: false + UnnecessaryApply: + active: true + UnnecessaryBackticks: + active: false + UnnecessaryFilter: + active: true + UnnecessaryInheritance: + active: true + UnnecessaryInnerClass: + active: false + UnnecessaryLet: + active: false + UnnecessaryParentheses: + active: false + UntilInsteadOfRangeTo: + active: false + UnusedImports: + active: false + UnusedPrivateClass: + active: false + UnusedPrivateMember: + active: false + allowedNames: '(_|ignored|expected|serialVersionUID)' + UseAnyOrNoneInsteadOfFind: + active: true + UseArrayLiteralsInAnnotations: + active: true + UseCheckNotNull: + active: true + UseCheckOrError: + active: false + UseDataClass: + active: false + allowVars: false + UseEmptyCounterpart: + active: false + UseIfEmptyOrIfBlank: + active: false + UseIfInsteadOfWhen: + active: false + UseIsNullOrEmpty: + active: true + UseOrEmpty: + active: true + UseRequire: + active: false + UseRequireNotNull: + active: false + UselessCallOnNotNull: + active: true + UtilityClassWithPublicConstructor: + active: false + VarCouldBeVal: + active: true + ignoreLateinitVar: false + WildcardImport: + active: false + excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/jsTest/**', '**/iosTest/**'] + excludeImports: + - 'java.util.*' diff --git a/Server/libs/ConstLib-1.4.jar b/Server/libs/ConstLib-1.4.jar new file mode 100644 index 0000000..0e94862 Binary files /dev/null and b/Server/libs/ConstLib-1.4.jar differ diff --git a/Server/libs/PrimitiveExtensions-1.0.jar b/Server/libs/PrimitiveExtensions-1.0.jar new file mode 100644 index 0000000..d26128c Binary files /dev/null and b/Server/libs/PrimitiveExtensions-1.0.jar differ diff --git a/Server/mvnw b/Server/mvnw new file mode 100755 index 0000000..b7f0646 --- /dev/null +++ b/Server/mvnw @@ -0,0 +1,287 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Apache Maven Wrapper startup batch script, version 3.1.1 +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /usr/local/etc/mavenrc ] ; then + . /usr/local/etc/mavenrc + fi + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + JAVA_HOME="`/usr/libexec/java_home`"; export JAVA_HOME + else + JAVA_HOME="/Library/Java/Home"; export JAVA_HOME + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`\\unset -f command; \\command -v java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + printf '%s' "$(cd "$basedir"; pwd)" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=$(find_maven_basedir "$(dirname $0)") +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar" + else + wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar" + fi + while IFS="=" read key value; do + case "$key" in (wrapperUrl) wrapperUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $wrapperUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + fi + + if command -v wget > /dev/null; then + QUIET="--quiet" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + QUIET="" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" + else + wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" + fi + [ $? -eq 0 ] || rm -f "$wrapperJarPath" + elif command -v curl > /dev/null; then + QUIET="--silent" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + QUIET="" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L + else + curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L + fi + [ $? -eq 0 ] || rm -f "$wrapperJarPath" + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaSource="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaSource=`cygpath --path --windows "$javaSource"` + javaClass=`cygpath --path --windows "$javaClass"` + fi + if [ -e "$javaSource" ]; then + if [ ! -e "$javaClass" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaSource") + fi + if [ -e "$javaClass" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + $MAVEN_DEBUG_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/Server/mvnw.cmd b/Server/mvnw.cmd new file mode 100644 index 0000000..474c9d6 --- /dev/null +++ b/Server/mvnw.cmd @@ -0,0 +1,187 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Apache Maven Wrapper startup batch script, version 3.1.1 +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* +if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar" + +FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %WRAPPER_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% ^ + %JVM_CONFIG_MAVEN_PROPS% ^ + %MAVEN_OPTS% ^ + %MAVEN_DEBUG_OPTS% ^ + -classpath %WRAPPER_JAR% ^ + "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ + %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" +if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%"=="on" pause + +if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% + +cmd /C exit /B %ERROR_CODE% diff --git a/Server/pom.xml b/Server/pom.xml new file mode 100644 index 0000000..f3cc5f0 --- /dev/null +++ b/Server/pom.xml @@ -0,0 +1,331 @@ + + + 4.0.0 + org.rs09 + server + 1.0.0 + + core.Server + true + 1.8.20 + 11 + 5.7.0 + 11 + 11 + + + + org.jetbrains.kotlin + kotlin-stdlib + ${kotlin.version} + compile + + + com.googlecode.json-simple + json-simple + 1.1.1 + compile + + + org.jetbrains.kotlin + kotlin-reflect + 1.5.20 + compile + + + org.jetbrains.kotlinx + kotlinx-coroutines-core-jvm + 1.4.2 + compile + + + com.moandjiezana.toml + toml4j + 0.7.2 + compile + + + org.junit.jupiter + junit-jupiter-api + ${junit.version} + test + + + org.junit.jupiter + junit-jupiter-engine + ${junit.version} + test + + + org.rs09.consts + ConstLib + [1.4.0,) + compile + + + mysql + mysql-connector-java + 8.0.29 + + + io.github.classgraph + classgraph + 4.8.146 + + + org.xerial + sqlite-jdbc + 3.36.0.3 + compile + + + com.github.ajalt.mordant + mordant-jvm + 2.0.0-beta6 + compile + + + com.google.errorprone + error_prone_annotations + 2.9.0 + compile + + + + + src/main + src/test + + + + + org.apache.maven.plugins + maven-install-plugin + 3.0.1 + + + install-consts + clean + + ${project.basedir}/libs/ConstLib-1.4.jar + default + org.rs09 + consts + 1.4 + jar + true + + + install-file + + + + install-extends + clean + + ${project.basedir}/libs/PrimitiveExtensions-1.0.jar + default + org.rs09 + primextends + 1.0 + jar + true + + + install-file + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + 3.4.2 + + + + jar-with-dependencies + + + ${project.mainClassName} + + + + + + make-assembly + package + + single + + + + + + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} + + + compile + + compile + + + + ${project.basedir}/src/main + + + + + test-compile + test-compile + + + ${project.basedir}/src/test/kotlin + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.10.1 + + 2048m + false + + -XDcompilePolicy=simple + + + + + com.google.errorprone + error_prone_core + 2.9.0 + + + + + + + + default-compile + none + + + + default-testCompile + none + + + java-compile + compile + + compile + + + + java-test-compile + test-compile + + testCompile + + + + + + maven-surefire-plugin + + false + false + + 2.22.0 + + + maven-failsafe-plugin + 2.22.0 + + + + org.codehaus.mojo + exec-maven-plugin + 1.2.1 + + core.Server + + + + org.apache.maven.plugins + maven-antrun-plugin + 1.8 + + + + detekt + verify + + + + + + + + + + + + + + + + run + + + + + io.gitlab.arturbosch.detekt + detekt-cli + 1.21.0 + + + + + + + + maven_central + Maven Central + https://repo.maven.apache.org/maven2/ + + + gitlab-maven + https://gitlab.com/api/v4/projects/32237206/packages/maven + + + + + gitlab-maven + https://gitlab.com/api/v4/projects/32237206/packages/maven + + + + gitlab-maven + https://gitlab.com/api/v4/projects/32237206/packages/maven + + + diff --git a/Server/src/main/content/data/BossKillCounter.java b/Server/src/main/content/data/BossKillCounter.java new file mode 100644 index 0000000..e6d8656 --- /dev/null +++ b/Server/src/main/content/data/BossKillCounter.java @@ -0,0 +1,172 @@ +package content.data; + +import core.game.node.entity.player.Player; + +/** + * The BossKillcounter keeps track of the amount of bosses the player has slain. + * addtoKillcount(player, npcId) should be added in the finalizeDeath() method of the combat handler for the boss. + * @author Splinter + */ +public enum BossKillCounter { + + + /* ORDINAL BOUND */ + KING_BLACK_DRAGON(new int[] { 50 }, "King Black Dragon", 14649), + BORK(new int[] { 7133, 7134 }, "Bork", -1), + DAGANNOTH_SUPREME(new int[] { 2881 }, "Dagannoth Supreme", 14639), + DAGANNOTH_PRIME(new int[] { 2882 }, "Dagannoth Prime", 14640), + DAGANNOTH_REX(new int[] { 2883 }, "Dagannoth Rex", 14641), + CHAOS_ELEMENTAL(new int[] { 3200 }, "Chaos Elemental", 14638), + GIANT_MOLE(new int[] { 3340 }, "Giant Mole", 14642), + SARADOMIN(new int[] { 6247 }, "Commander Zilyana", 14647), + ZAMORAK(new int[] { 6203 }, "K'ril Tsutsaroth", 14648), + BANDOS(new int[] { 6260 }, "General Graardor", 14646), + ARMADYL(new int[] { 6222 }, "Kree'arra", 14645), + JAD(new int[] { 2745 }, "Tz-Tok Jad", 14828), + KALPHITE_QUEEN(new int[] { 1160 }, "Kalphite Queen", 14650), + CORPOREAL_BEAST(new int[] { 8133 }, "Corporeal Beast", 14653), + TORMENTED_DEMONS(new int[] { + 8349, 8350, 8351, 8352, 8353, 8354, + 8355, 8356, 8357, 8358, 8359, 8360, + 8361, 8362, 8363, 8364, 8365, 8366, + }, "Tormented demon", -1), + + + ; + + /** + * The npcs that can increase the killcounter + */ + private final int[] npc; + + /** + * The name of the NPC, to be displayed as a sendMessage + */ + private final String name; + + /** + * The item ID of the pet relating to the boss. + */ + private final int petId; + + /** + * Constructs a new {@code BossKillCounter} {@code Object}. + * @param npc the npc. + * @param name the npc's string name + */ + BossKillCounter(final int[] npc, final String name, final int petId) { + this.npc = npc; + this.name = name; + this.petId = petId; + } + + /** + * Gets the npc. + * @return The npc. + */ + public int[] getNpc() { + return npc; + } + + /** + * Gets the NPC's name + * @return their name + */ + public String getName() { + return name; + } + + /** + * Gets the petId + * @return The petId + */ + public int getPetId() { + return petId; + } + + /** + * Gets the type for the npc. + * @param npc the npc. + * @return the BossKillcounter + */ + public static BossKillCounter forNPC(final int npc) { + for (BossKillCounter kc : BossKillCounter.values()) { + for (int i : kc.getNpc()) { + if (npc == i) { + return kc; + } + } + } + return null; + } + + /** + * Adds to the player's killcount for that particular boss. + * @param killer The player who killed the npc + * @param npcid the ID of the npc that just died + */ + public static void addtoKillcount(Player killer, int npcid) { + if (killer == null) { + return; + } + BossKillCounter boss = BossKillCounter.forNPC(npcid); + if (boss == null) { + return; + } + killer.getSavedData().getGlobalData().getBossCounters()[boss.ordinal()]++; + killer.getPacketDispatch().sendMessage("Your " + boss.getName() + " killcount is now: " + killer.getSavedData().getGlobalData().getBossCounters()[boss.ordinal()] + "."); +// addBossPet(killer, npcid, boss); + } + +// /** +// * Gives the player the pet if they killed a certain boss. +// * The chance by default is 1/5000. This rate lowers to 1/2200 if the for Boss Pets is active. +// * Note: Not all bosses have pet versions of themselves. +// */ +// private static void addBossPet(Player killer, int npcid, BossKillCounter boss){ +// if(boss.getPetId() == -1){ //The boss does not have a pet version. +// return; +// } +// int number = 5000; +// if (npcid == 2745) { +// number = 200; +// if (killer.getSlayer().getTask() == Tasks.JAD) { +// number = 100; +// } +// } else if (npcid == 3200) { +// number = 300; +// } +// int rand = number; +// if(rand == 10){ +// for (int i = 0; i < killer.getFamiliarManager().getInsuredPets().size(); i++) { +// if (killer.getFamiliarManager().getInsuredPets().get(i).getBabyItemId() == boss.getPetId()) { +// return; +// } +// } +// if(killer.getFamiliarManager().hasFamiliar() && killer.getInventory().freeSlots() < 1){ +// return; +// } +// if(!killer.getFamiliarManager().hasFamiliar()){ +// killer.getFamiliarManager().summon(new Item(boss.getPetId()), true); +// killer.sendNotificationMessage("You have a funny feeling like you're being followed."); +// } else if (killer.getInventory().freeSlots() > 0){ +// killer.getInventory().add(new Item(boss.getPetId(), 1)); +// killer.sendNotificationMessage("You feel something weird sneaking into your backpack."); +// } +// Repository.sendNews(killer.getUsername()+" now commands a miniature "+(boss.equals(CORPOREAL_BEAST) ? "Dark core" : boss.getName())+"!"); +// } +// } + + /** + * Increments the player's Barrows chest counter. + * @param player the player + */ + public static void addtoBarrowsCount(Player player) { + if (player == null) { + return; + } + player.getSavedData().getGlobalData().setBarrowsLoots(player.getSavedData().getGlobalData().getBarrowsLoots() + 1); + player.getPacketDispatch().sendMessage("Your Barrows chest count is: " + player.getSavedData().getGlobalData().getBarrowsLoots() + "."); + } + +} diff --git a/Server/src/main/content/data/ChargedItem.kt b/Server/src/main/content/data/ChargedItem.kt new file mode 100644 index 0000000..06f3d40 --- /dev/null +++ b/Server/src/main/content/data/ChargedItem.kt @@ -0,0 +1,80 @@ +package content.data + +import core.api.toIntArray +import core.cache.def.impl.ItemDefinition +import org.rs09.consts.Items + +/** + * Represents a distinct charged item, i.e. items with (#). + * Not to be confused with items with internal charge, like degradation. + * @author RiL + */ +enum class ChargedItem(val ids: IntArray) { + AMULET_OF_GLORY((Items.AMULET_OF_GLORY4_1712 downTo Items.AMULET_OF_GLORY_1704 step 2).toIntArray()), + RING_OF_DUELLING((Items.RING_OF_DUELLING8_2552..Items.RING_OF_DUELLING1_2566 step 2).toIntArray()), + GAMES_NECKLACE((Items.GAMES_NECKLACE8_3853..Items.GAMES_NECKLACE1_3867 step 2).toIntArray()), + BROODOO_SHIELDA((Items.BROODOO_SHIELD_10_6215..Items.BROODOO_SHIELD_6235 step 2).toIntArray()), + BROODOO_SHIELDB((Items.BROODOO_SHIELD_10_6237..Items.BROODOO_SHIELD_6257 step 2).toIntArray()), + BROODOO_SHIELDC((Items.BROODOO_SHIELD_10_6259..Items.BROODOO_SHIELD_6279 step 2).toIntArray()), + ROD_OF_IVANDIS((Items.ROD_OF_IVANDIS10_7639..Items.ROD_OF_IVANDIS1_7648).toIntArray()), + BLACK_MASK((Items.BLACK_MASK_10_8901..Items.BLACK_MASK_8921 step 2).toIntArray()), + AMULET_OF_GLORYT((Items.AMULET_OF_GLORYT4_10354..Items.AMULET_OF_GLORYT_10362 step 2).toIntArray()), + CASTLEWAR_BRACE((Items.CASTLEWAR_BRACE3_11079..Items.CASTLEWAR_BRACE1_11083 step 2).toIntArray()), + FORINTHRY_BRACE((Items.FORINTHRY_BRACE5_11095..Items.FORINTHRY_BRACE1_11103 step 2).toIntArray()), + SKILLS_NECKLACE((Items.SKILLS_NECKLACE4_11105..Items.SKILLS_NECKLACE_11113 step 2).toIntArray()), + COMBAT_BRACELET((Items.COMBAT_BRACELET4_11118..Items.COMBAT_BRACELET_11126 step 2).toIntArray()), + DIGSITE_PENDANT((Items.DIGSITE_PENDANT_5_11194 downTo Items.DIGSITE_PENDANT_1_11190).toIntArray()), + VOID_SEAL((Items.VOID_SEAL8_11666..Items.VOID_SEAL1_11673).toIntArray()), + AMULET_OF_FARMING((Items.AMULET_OF_FARMING8_12622 downTo Items.AMULET_OF_FARMING1_12608 step 2).toIntArray()), + IVANDIS_FLAIL((Items.IVANDIS_FLAIL_30_13117..Items.IVANDIS_FLAIL_1_13146).toIntArray()), + RING_OF_SLAYING((Items.RING_OF_SLAYING8_13281..Items.RING_OF_SLAYING1_13288).toIntArray()), + RING_OF_WEALTH((Items.RING_OF_WEALTH4_14646 downTo Items.RING_OF_WEALTH_14638 step 2).toIntArray()); + + /** + * Get the item id for a specific [charge]. + * If [charge] is outside the valid range, return the item id with the closest charge. + */ + fun forCharge(charge: Int): Int { + return ids[maxCharge() - if (charge < 1) 1 + maxCharge() - ids.size else if (charge > maxCharge()) maxCharge() else charge] + } + + /** + * Get the max charge of this ChargedItem. + */ + fun maxCharge(): Int = maxCharges[ordinal] + + companion object { + private val CHARGE_REGEX = Regex("""\(\D?(\d+)\)""") + private val idMap = HashMap() + private val maxCharges = IntArray(values().size) + + init { + values().forEach { chargedItem -> + maxCharges[chargedItem.ordinal] = getMaxCharge(chargedItem) + chargedItem.ids.forEach { idMap[it] = chargedItem } + } + } + + private fun getMaxCharge(chargedItem: ChargedItem): Int { + return CHARGE_REGEX.find(ItemDefinition.forId(chargedItem.ids.first()).name)!!.groups[1]!!.value.toInt() + } + + /** + * Check if the item id is a charged item. + */ + fun contains(id: Int): Boolean = idMap.containsKey(id) + + /** + * Get the ChargedItem enum for an item id, or null if it's not a charged item. + */ + fun forId(id: Int): ChargedItem? = idMap[id] + + /** + * Get the charge value of an item id, or null if it's not a charged item. + */ + fun getCharge(id: Int): Int? { + val chargedItem = forId(id) ?: return null + return chargedItem.maxCharge() - chargedItem.ids.indexOf(id) + } + } +} diff --git a/Server/src/main/content/data/Dyes.java b/Server/src/main/content/data/Dyes.java new file mode 100644 index 0000000..79c508f --- /dev/null +++ b/Server/src/main/content/data/Dyes.java @@ -0,0 +1,54 @@ +package content.data; + +import core.game.node.item.Item; + +/** + * Represents a dye. + * @author Vexia + */ +public enum Dyes { + BLACK(new Item(4622)), + RED(new Item(1763)), + YELLOW(new Item(1765)), + BLUE(new Item(1767)), + ORANGE(new Item(1769)), + GREEN(new Item(1771)), + PURPLE(new Item(1773)), + PINK(new Item(6955)); + + /** + * The dye item. + */ + private final Item item; + + /** + * Constructs a new {@code Dyes} {@code Object}. + * @param item the item. + */ + Dyes(Item item) { + this.item = item; + } + + /** + * Gets the dye for the item. + * @param item the item. + * @return the dye. + */ + public static Dyes forItem(Item item) { + for (Dyes d : values()) { + if (d.getItem().getId() == item.getId()) { + return d; + } + } + return null; + } + + /** + * Gets the item. + * @return The item. + */ + public Item getItem() { + return item; + } + +} diff --git a/Server/src/main/content/data/EnchantedJewellery.kt b/Server/src/main/content/data/EnchantedJewellery.kt new file mode 100644 index 0000000..c34a0ff --- /dev/null +++ b/Server/src/main/content/data/EnchantedJewellery.kt @@ -0,0 +1,364 @@ +package content.data + +import content.global.skill.magic.TeleportMethod +import content.global.skill.slayer.SlayerManager.Companion.getInstance +import content.global.skill.slayer.SlayerUtils +import core.ServerConstants +import core.api.* +import core.game.event.TeleportEvent +import core.game.interaction.QueueStrength +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.TeleportManager +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import org.rs09.consts.Items +import core.game.world.GameWorld.Pulser +import org.rs09.consts.Sounds +import java.util.* + +/** + * Represents an enchanted jewellery. + * @author Vexia, downthecrop, Player Name + */ +enum class EnchantedJewellery( + + val options: Array, + val locations: Array, crumble: Boolean, vararg val ids: Int) { + RING_OF_SLAYING( + arrayOf( + "Sumona in Pollnivneach.", + "Morytania Slayer Tower.", + "Rellekka Slayer Caves.", + "Nowhere. Give me a slayer update." + ), + arrayOf( + Location.create(3361, 2994, 0), + Location.create(3428, 3535, 0), + Location.create(2792, 3615, 0), + ), + true, + Items.RING_OF_SLAYING8_13281, + Items.RING_OF_SLAYING7_13282, + Items.RING_OF_SLAYING6_13283, + Items.RING_OF_SLAYING5_13284, + Items.RING_OF_SLAYING4_13285, + Items.RING_OF_SLAYING3_13286, + Items.RING_OF_SLAYING2_13287, + Items.RING_OF_SLAYING1_13288 + ), + + RING_OF_DUELING( + arrayOf( + "Al Kharid Duel Arena.", + "Castle Wars Arena.", + "Fist of Guthix", "Nowhere." + ), + arrayOf( + Location.create(3314, 3235, 0), + Location.create(2442, 3089, 0), + Location.create(1693, 5600, 0) + ), + true, + Items.RING_OF_DUELLING8_2552, + Items.RING_OF_DUELLING7_2554, + Items.RING_OF_DUELLING6_2556, + Items.RING_OF_DUELLING5_2558, + Items.RING_OF_DUELLING4_2560, + Items.RING_OF_DUELLING3_2562, + Items.RING_OF_DUELLING2_2564, + Items.RING_OF_DUELLING1_2566 + ), + AMULET_OF_GLORY( + arrayOf( + "Edgeville.", + "Karamja.", + "Draynor Village.", + "Al-Kharid.", + "Nowhere." + ), + arrayOf( + Location.create(3087, 3495, 0), + Location.create(2919, 3175, 0), + Location.create(3104, 3249, 0), + Location.create(3304, 3124, 0) + ), + Items.AMULET_OF_GLORY4_1712, + Items.AMULET_OF_GLORY3_1710, + Items.AMULET_OF_GLORY2_1708, + Items.AMULET_OF_GLORY1_1706, + Items.AMULET_OF_GLORY_1704 + ), + AMULET_OF_GLORY_T( + AMULET_OF_GLORY.options, + AMULET_OF_GLORY.locations, + Items.AMULET_OF_GLORYT4_10354, + Items.AMULET_OF_GLORYT3_10356, + Items.AMULET_OF_GLORYT2_10358, + Items.AMULET_OF_GLORYT1_10360, + Items.AMULET_OF_GLORYT_10362 + ), + GAMES_NECKLACE( + arrayOf( + "Burthorpe Games Room.", + "Barbarian Outpost.", + "Clan Wars.", + "Wilderness Volcano.", + "Corporeal Beast." + ), + arrayOf( + Location.create(2899, 3563, 0), + Location.create(2520, 3571, 0), + Location.create(3266, 3686, 0), + Location.create(3179, 3685, 0), + Location.create(2885, 4372, 2) + ), + true, + Items.GAMES_NECKLACE8_3853, + Items.GAMES_NECKLACE7_3855, + Items.GAMES_NECKLACE6_3857, + Items.GAMES_NECKLACE5_3859, + Items.GAMES_NECKLACE4_3861, + Items.GAMES_NECKLACE3_3863, + Items.GAMES_NECKLACE2_3865, + Items.GAMES_NECKLACE1_3867 + ), + DIGSITE_PENDANT(arrayOf(), + arrayOf( + Location.create(3342, 3445, 0) + ), + true, + Items.DIGSITE_PENDANT_5_11194, + Items.DIGSITE_PENDANT_4_11193, + Items.DIGSITE_PENDANT_3_11192, + Items.DIGSITE_PENDANT_2_11191, + Items.DIGSITE_PENDANT_1_11190 + ), + COMBAT_BRACELET( + arrayOf( + "Champions' Guild.", + "Monastery.", + "Ranging Guild.", + "Warriors' Guild.", + "Nowhere." + ), + arrayOf( + Location.create(3191, 3365, 0), + Location.create(3052, 3472, 0), + Location.create(2657, 3439, 0), + Location.create(2878, 3546, 0) + ), + Items.COMBAT_BRACELET4_11118, + Items.COMBAT_BRACELET3_11120, + Items.COMBAT_BRACELET2_11122, + Items.COMBAT_BRACELET1_11124, + Items.COMBAT_BRACELET_11126 + ), + SKILLS_NECKLACE( + arrayOf( + "Fishing Guild.", + "Mining Guild.", + "Crafting Guild.", + "Cooking Guild.", + "Nowhere." + ), + arrayOf( + Location.create(2611, 3392, 0), + Location.create(3016, 3338, 0), + Location.create(2933, 3290, 0), + Location.create(3143, 3442, 0) + ), + Items.SKILLS_NECKLACE4_11105, + Items.SKILLS_NECKLACE3_11107, + Items.SKILLS_NECKLACE2_11109, + Items.SKILLS_NECKLACE1_11111, + Items.SKILLS_NECKLACE_11113 + ), + RING_OF_WEALTH( + arrayOf( + "Grand Exchange.", + "Nowhere." + ), + arrayOf( + Location.create(3163, 3464, 0) + ), + Items.RING_OF_WEALTH4_14646, + Items.RING_OF_WEALTH3_14644, + Items.RING_OF_WEALTH2_14642, + Items.RING_OF_WEALTH1_14640, + Items.RING_OF_WEALTH_14638 + ), + RING_OF_LIFE(arrayOf(), + arrayOf( + Location.create(ServerConstants.HOME_LOCATION) + ), + true, + Items.RING_OF_LIFE_2570 + ); + + val isCrumble: Boolean = crumble + + /** + * Constructs a new `EnchantedJewelleryPlugin` `Object`. + * @param options the dialogue options. + * @param locations the teleport locations. + * @param ids the ordered item ids. + */ + constructor(options: Array, locations: Array, vararg ids: Int) : this(options, locations, false, *ids) + + /** + * Method used when the player "Use"s the jewellery piece. + * @param player the player. + * @param item the used jewellery item. + * @param buttonID the button id. + * @param isEquipped If the player is operating. + */ + fun use(player: Player, item: Item, buttonID: Int, isEquipped: Boolean) { + if (buttonID > locations.size - 1) { + if (isSlayerRing(item)) { + slayerProgressDialogue(player) + } + return + } + attemptTeleport(player, item, buttonID, isEquipped) + } + + /** + * Method used to actually teleport the player to the desired location. + * @param player the player. + * @param item the used jewellery item. + * @param buttonID the button id. + * @param isEquipped If the player is operating. + */ + fun attemptTeleport(player: Player, item: Item, buttonID: Int, isEquipped: Boolean): Boolean { + val itemIndex = getItemIndex(item) + val nextJewellery = Item(getNext(itemIndex)) + if (!canTeleport(player, nextJewellery)) { + return false + } + Pulser.submit(object : Pulse(0) { + private var count = 0 + private var location = getLocation(buttonID) + override fun pulse(): Boolean { + when (count) { + 0 -> { + lock(player,4) + visualize(player, ANIMATION, GRAPHICS) + playGlobalAudio(player.location, Sounds.TELEPORT_ALL_200) + player.impactHandler.disabledTicks = 4 + closeInterface(player) + } + 3 -> { + teleport(player,location) + resetAnimator(player) + if (isLastItemIndex(itemIndex)) { + if (isCrumble) crumbleJewellery(player, item, isEquipped) + } else { + replaceJewellery(player, item, nextJewellery, isEquipped) + } + unlock(player) + player.dispatch(TeleportEvent(TeleportManager.TeleportType.NORMAL, TeleportMethod.JEWELRY, item, location)) + return true + } + } + count += 1 + return false + } + }) + return true + } + + private fun replaceJewellery(player: Player, item: Item, nextJewellery: Item, isEquipped: Boolean) { + if (isEquipped) { + replaceSlot(player, item.slot, nextJewellery, item, Container.EQUIPMENT) + } else { + replaceSlot(player, item.slot, nextJewellery) + } + } + + private fun crumbleJewellery(player: Player, item: Item, isEquipped: Boolean) { + if (isEquipped) { + removeItem(player, item, Container.EQUIPMENT) + } else { + removeItem(player, item) + } + if (isSlayerRing(item)) { + queueScript(player, 1, QueueStrength.SOFT) { + addItemOrDrop(player, Items.ENCHANTED_GEM_4155) + sendMessage(player, "Your Ring of Slaying reverts back into a regular enchanted gem.") + return@queueScript stopExecuting(player) + } + } + } + + private fun isSlayerRing(item: Item): Boolean { + return (item.id in RING_OF_SLAYING.ids) + } + + private fun slayerProgressDialogue(player: Player) { + val slayerManager = getInstance(player) + if (!slayerManager.hasTask()) { + sendNPCDialogue(player, slayerManager.master!!.npc, "You need something new to hunt. Come and " + + "see me when you can and I'll give you a new task.", core.game.dialogue.FacialExpression.HALF_GUILTY) + return + } + sendNPCDialogue(player, slayerManager.master!!.npc, "You're currently " + + "assigned to kill ${SlayerUtils.pluralise(getSlayerTaskName(player))} " + + "only ${getSlayerTaskKillsRemaining(player)} more to go.", core.game.dialogue.FacialExpression.FRIENDLY) + // Slayer tracker UI + setVarp(player, 2502, slayerManager.flags.taskFlags shr 4) + } + + private fun canTeleport(player: Player, item: Item): Boolean { + return player.zoneMonitor.teleport(1, item) + } + + private fun getNext(index: Int): Int { + val i = index + 1 + if (i > ids.size - 1) { + return ids[ids.size - 1] + } + return ids[i] + } + + private fun getLocation(index: Int): Location { + if (index > locations.size - 1) { + return locations[locations.size - 1] + } + return locations[index] + } + + fun getJewelleryName(item: Item): String { + return item.name.replace(""" ?\(t?[0-9]?\)""".toRegex(), "") + } + + fun getJewelleryType(item: Item): String { + return when { + this == GAMES_NECKLACE -> "games necklace" + this == DIGSITE_PENDANT -> "necklace" + this == COMBAT_BRACELET -> "bracelet" + this == SKILLS_NECKLACE -> "necklace" + else -> item.name.split(" ")[0].lowercase(Locale.getDefault()) + } + } + + fun isLastItemIndex(index: Int): Boolean = index == ids.size - 1 + + fun getItemIndex(item: Item): Int { + return ids.indexOf(item.id) + } + + companion object { + private val ANIMATION = Animation(714) + private val GRAPHICS = Graphics(308, 100, 50) + val idMap = HashMap() + + init { + values().forEach { entry -> + entry.ids.forEach { idMap[it] = entry } + } + } + } +} diff --git a/Server/src/main/content/data/GodBook.java b/Server/src/main/content/data/GodBook.java new file mode 100644 index 0000000..92029b4 --- /dev/null +++ b/Server/src/main/content/data/GodBook.java @@ -0,0 +1,247 @@ +package content.data; + +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +import static core.api.ContentAPIKt.hasRequirement; + +/** + * A god book. + * @author Vexia + */ +public enum GodBook { + HOLY_BOOK("Holy Book of Saradomin", new Item(3840), new Item(3839), new Item[] { new Item(1718) }, new Item(3827), new Item(3828), new Item(3829), new Item(3830)), BOOK_OF_BALANCE("Guthix's Book of Balance", new Item(3844), new Item(3843), new Item[] { new Item(1718), new Item(1724) }, new Item(3835), new Item(3836), new Item(3837), new Item(3838)), UNHOLY_BOOK("Unholy Book of Zamorak", new Item(3842), new Item(3841), new Item[] { new Item(1724) }, new Item(3831), new Item(3832), new Item(3833), new Item(3834)); + + /** + * The books name. + */ + private final String name; + + /** + * The god book. + */ + private final Item book; + + /** + * The damaged book. + */ + private final Item damagedBook; + + /** + * The items the book can bless. + */ + private final Item[] blessItems; + + /** + * The pages of items. + */ + private final Item[] pages; + + /** + * Constructs a new {@code GodBook} {@code Object} + * @param book the book. + * @param damagedBook the damged book. + * @param name the name of the book. + * @param pages the pages. + */ + private GodBook(String name, Item book, Item damagedBook, Item[] blessedItems, Item... pages) { + this.book = book; + this.damagedBook = damagedBook; + this.name = name; + this.blessItems = blessedItems; + this.pages = pages; + } + + /** + * Gets the god book for the item. + * @param item the item. + * @param damaged Flagged for the damaged book. + * @return {@code GodBook} the god book. + */ + public static GodBook forItem(Item item, boolean damaged) { + for (GodBook book : values()) { + if ((!damaged ? book.getBook().getId() : book.getDamagedBook().getId()) == item.getId()) { + return book; + } + } + return null; + } + + /** + * Checks if the player has this god book. + * @param player the player. + * @param both if we are checking for the damaged/good. + * @return {@code True} if so. + */ + public boolean hasGodBook(Player player, boolean both) { + return player.getInventory().containsItems(both ? new Item[] { book, damagedBook } : new Item[] { book }); + } + + /** + * Gets a good book based on the page id. + * @param page the page. + * @return the respective god book. + */ + public static GodBook forPage(Item page) { + for (GodBook book : values()) { + for (Item i : book.getPages()) { + if (i.getId() == page.getId()) { + return book; + } + } + } + return null; + } + + /** + * Inserts a page into the book. + * @param player the player. + * @param book the book. + * @param page the page. + */ + public void insertPage(Player player, Item book, Item page) { + if (!hasRequirement(player, Quests.HORROR_FROM_THE_DEEP)) + return; + if (hasPage(player, book, page)) { + player.sendMessage("The book already has that page."); + return; + } + if (player.getInventory().remove(new Item(page.getId(), 1))) { + setPageHash(player, book, getPageIndex(page)); + player.sendMessage("You add the page to the book..."); + if (isComplete(player, book)) { + player.getSavedData().getGlobalData().setGodPages(new boolean[4]); + player.getSavedData().getGlobalData().setGodBook(-1); + player.getInventory().replace(this.book, book.getSlot()); + player.getSavedData().getGlobalData().setGodBook(this); + player.sendMessage("The book is now complete!"); + String message = this == UNHOLY_BOOK ? "unholy symbols" : this == HOLY_BOOK ? "holy symbols" : "unblessed holy symbols"; + player.sendMessage("You can now use it to bless " + (message) + "!"); + } + } + } + + /** + * Checks if this item is a page of the book. + * @param asItem the item. + * @return {@code True} if so. + */ + public boolean isPage(Item asItem) { + for (Item item : pages) { + if (item.getId() == asItem.getId()) { + return true; + } + } + return false; + } + + /** + * Checks if a book is complete. + * @param book the book. + * @return {@code True} if so. + */ + public boolean isComplete(Player player, Item book) { + for (int i = 0; i < 4; i++) { + if (!hasPage(player, book, i + 1)) { + return false; + } + } + return true; + } + + /** + * Checks if there is a page in a book. + * @param book the book. + * @param page the page. + * @return {@code True} if so. + */ + public boolean hasPage(Player player, Item book, Item page) { + return hasPage(player, book, getPageIndex(page)); + } + + /** + * Sets a page hash. + * @param book the book. + * @param pageId the page Id. + */ + public void setPageHash(Player player, Item book, int pageId) { + // int hash = getHash(book); + // hash |= hash | (1 << pageId); + // book.setCharge(1000 + hash); + player.getSavedData().getGlobalData().getGodPages()[pageId - 1] = true; + } + + /** + * Checks if the book has a page. + * @param book the book. + * @param pageId the id of the page. + * @return {@code True} if so. + */ + public boolean hasPage(Player player, Item book, int pageId) { + // return (getHash(book) & (1 << pageId)) != 0; + return player.getSavedData().getGlobalData().getGodPages()[pageId - 1]; + } + + /** + * Gets the hash. + * @param book the book. + * @return the hash. + */ + public int getHash(Item book) { + return book.getCharge() - 1000; + } + + /** + * Gets the page index. + * @param page the page. + * @return the index. + */ + public int getPageIndex(Item page) { + for (int i = 0; i < pages.length; i++) { + if (pages[i].getId() == page.getId()) { + return i + 1; + } + } + return -1; + } + + /** + * Gets the name of the god book. + * @return the name. + */ + public String getName() { + return name; + } + + /** + * Gets the book. + * @return the book + */ + public Item getBook() { + return book; + } + + /** + * Gets the damagedBook. + * @return the damagedBook + */ + public Item getDamagedBook() { + return damagedBook; + } + + /** + * Gets the pages. + * @return the pages + */ + public Item[] getPages() { + return pages; + } + + /** + * Gets the blessItem. + * @return the blessItem + */ + public Item[] getBlessItem() { + return blessItems; + } +} diff --git a/Server/src/main/content/data/GodType.java b/Server/src/main/content/data/GodType.java new file mode 100644 index 0000000..2b8ce7e --- /dev/null +++ b/Server/src/main/content/data/GodType.java @@ -0,0 +1,235 @@ +package content.data; + +import core.game.dialogue.DialogueAction; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItem; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.tools.StringUtils; + +/** + * A god type. + * @author Vexia + */ +public enum GodType { + SARADOMIN(new Item(2412), new Item(2415), 2873, 913, "The cape disappears in a flash of light as it touches the ground."), GUTHIX(new Item(2413), new Item(2416), 2875, 914, "The cape disintegrates as it touches the earth."), ZAMORAK(new Item(2414), new Item(2417), 2874, 912, "The cape ignites and burns up as it touches the ground."); + + /** + * The cape. + */ + private final Item cape; + + /** + * The staff. + */ + private final Item staff; + + /** + * The statue id. + */ + private final int statueId; + + /** + * The npc id. + */ + private final int npcId; + + /** + * The drop message. + */ + private final String dropMessage; + + /** + * Constructs a new {@code GodCape} {@code Object}. + * @param cape the cape. + * @param staff the staff. + * @param statueId the id. + */ + private GodType(Item cape, Item staff, int statueId, int npcId, String dropMessage) { + this.cape = cape; + this.staff = staff; + this.statueId = statueId; + this.npcId = npcId; + this.dropMessage = dropMessage; + } + + /** + * Prays at a statue. + * @param player the player. + * @param statue the statue. + */ + public void pray(final Player player, final Scenery statue) { + if (hasAny(player)) { + player.lock(3); + player.animate(Animation.create(645)); + player.sendMessages("You kneel and begin to chant to " + getName() + "...", "...but there is no response."); + return; + } + player.getDialogueInterpreter().sendDialogue("You kneel and begin to chant to " + getName() + "..."); + player.getDialogueInterpreter().addAction(new DialogueAction() { + + @Override + public void handle(final Player player, int buttonId) { + player.lock(); + player.animate(Animation.create(645)); + GameWorld.getPulser().submit(new Pulse(3, player) { + @Override + public boolean pulse() { + Location loc = statue.getLocation().transform(0, -1, 0); + GroundItem g = GroundItemManager.get(cape.getId(), loc, player); + if (g == null) { + GroundItemManager.create(cape, loc, player); + } + player.getPacketDispatch().sendPositionedGraphic(86, 0, 0, loc); + player.unlock(); + return true; + } + }); + } + + }); + } + + /** + * Gets the god type by the statue id. + * @param object the object. + * @return the type. + */ + public static GodType forObject(int object) { + for (GodType type : values()) { + if (type.getStatueId() == object) { + return type; + } + } + return null; + } + + /** + * Checks if they have a god cape & which one. + * @param player the player. + * @param invyOnly if invy check only. + * @return {@code GodCape} the cape. + */ + public static GodType getCape(Player player, boolean invyOnly) { + for (GodType cape : values()) { + if (invyOnly ? player.getInventory().containsItems(cape.getCape()) : (player.getEquipment().containsItem(cape.getCape()) || player.getInventory().containsItems(cape.getCape()))) { + return cape; + } + } + return null; + } + + /** + * Checks if they have a god cape. + * @param player the player. + * @return the cape. + */ + public static GodType getCape(Player player) { + return getCape(player, false); + } + + /** + * Gets a god cape type by the id. + * @param cape the cape. + * @return the cape. + */ + public static GodType forCape(final Item cape) { + for (GodType g : values()) { + if (g.getCape().getId() == cape.getId()) { + return g; + } + } + return null; + } + + /** + * Checks if the player is friendly. + * @param player the player. + * @return {@code True} if so. + */ + public boolean isFriendly(Player player) { + return player.getEquipment().containsItem(cape); + } + + /** + * Gets the mage type. + * @param id the id. + * @return te type. + */ + public static GodType forId(int id) { + for (GodType type : values()) { + if (type.getNpcId() == id) { + return type; + } + } + return null; + } + + /** + * Checks if the player has any capes. + * @param player the player. + * @return {@code True} if so. + */ + public static boolean hasAny(Player player) { + for (GodType t : values()) { + if (player.hasItem(t.getCape())) { + return true; + } + } + return false; + } + + /** + * Gets the cape. + * @return The cape. + */ + public Item getCape() { + return cape; + } + + /** + * Gets the staff. + * @return The staff. + */ + public Item getStaff() { + return staff; + } + + /** + * Gets the statueId. + * @return The statueId. + */ + public int getStatueId() { + return statueId; + } + + /** + * Gets the dropMessage. + * @return The dropMessage. + */ + public String getDropMessage() { + return dropMessage; + } + + /** + * Gets the npcId. + * @return The npcId. + */ + public int getNpcId() { + return npcId; + } + + /** + * Gets the name. + * @return the name. + */ + public String getName() { + return StringUtils.formatDisplayName(name().toLowerCase()); + } + +} diff --git a/Server/src/main/content/data/Lamps.java b/Server/src/main/content/data/Lamps.java new file mode 100644 index 0000000..9dc150b --- /dev/null +++ b/Server/src/main/content/data/Lamps.java @@ -0,0 +1,113 @@ +package content.data; + +import core.game.node.item.Item; + +/** + * Represents an experience lamp. + * @author Vexia + */ +public enum Lamps { + GENIE_LAMP(new Item(2528), 10), + STRONGHOLD_LAMP(new Item(4447), 500), + + K_ACHIEVEMENT_1(new Item(11137), 1000, 30), + K_ACHIEVEMENT_2(new Item(11139), 5000, 40), + K_ACHIEVEMENT_3(new Item(11141), 10000, 50), + + V_ACHIEVEMENT_1(new Item(11753), 1000, 30), + V_ACHIEVEMENT_2(new Item(11754), 5000, 40), + V_ACHIEVEMENT_3(new Item(11755), 10000, 50), + + L_ACHIEVEMENT_1(new Item(11185), 500, 1), + L_ACHIEVEMENT_2(new Item(11186), 1000, 30), + L_ACHIEVEMENT_3(new Item(11187), 1500, 35), + + MYSTERIOUS_LAMP(new Item(13227), 10000, 30), + + FALLY_ACHIEVEMENT_1(new Item(14580), 1000, 30), + FALLY_ACHIEVEMENT_2(new Item(14581), 5000, 40), + FALLY_ACHIEVEMENT_3(new Item(14582), 10000, 50), + + FREM_ACHIEVEMENT_1(new Item(14574), 5000, 30), + FREM_ACHIEVEMENT_2(new Item(14575), 10000, 40), + FREM_ACHIEVEMENT_3(new Item(14576), 15000, 50), + + SEERS_ACHIEVEMENT_1(new Item(14633), 1000, 30), + SEERS_ACHIEVEMENT_2(new Item(14634), 5000, 40), + SEERS_ACHIEVEMENT_3(new Item(14635), 10000, 50); + + /** + * The item id. + */ + private final Item item; + + /** + * The experience gained. + */ + private final int experience; + + /** + * The level requirement. + */ + private final int levelRequirement; + + /** + * Constructs a new {@code Lamps} {@code Object} + * @param item the item. + * @param experience the exp. + * @param levelRequirement the level requirement to meet. + */ + Lamps(Item item, int experience, int levelRequirement) { + this.item = item; + this.experience = experience; + this.levelRequirement = levelRequirement; + } + + /** + * Constructs a new {@code Lamps} {@code Object} + * @param item the item. + * @param experience the exp. + */ + Lamps(Item item, int experience) { + this(item, experience, 0); + } + + /** + * Gets the lamp by the item. + * @param item the item. + * @return the lamp. + */ + public static Lamps forItem(Item item) { + for (Lamps l : values()) { + if (l.getItem().getId() == item.getId()) { + return l; + } + } + return null; + } + + /** + * Gets the item. + * @return the item + */ + public Item getItem() { + return item; + } + + /** + * Gets the mod. + * @return the mod + */ + public int getExp() { + return experience; + } + + /** + * Gets the levelRequirement. + * @return the levelRequirement + */ + public int getLevelRequirement() { + return levelRequirement; + } + +} diff --git a/Server/src/main/content/data/LightSource.java b/Server/src/main/content/data/LightSource.java new file mode 100644 index 0000000..118cb49 --- /dev/null +++ b/Server/src/main/content/data/LightSource.java @@ -0,0 +1,202 @@ +package content.data; + +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import org.rs09.consts.Components; + +import static org.rs09.consts.Items.*; + + +/** + * Represents a light source. + * @author Vexia + * @author Emperor + */ +public enum LightSource { + CANDLE(1, new Item(CANDLE_36, 1), new Item(LIT_CANDLE_33, 1), true, Components.DARKNESS_MEDIUM_98), + BLACK_CANDLE(1, new Item(BLACK_CANDLE_38, 1), new Item(LIT_BLACK_CANDLE_32, 1), true, Components.DARKNESS_MEDIUM_98), + TORCH(1, new Item(UNLIT_TORCH_596, 1), new Item(LIT_TORCH_594, 1), true, Components.DARKNESS_MEDIUM_98), + CANDLE_LANTERN(4, new Item(CANDLE_LANTERN_4527, 1), new Item(CANDLE_LANTERN_4531, 1), false, Components.DARKNESS_MEDIUM_98), + OIL_LAMP(12, new Item(OIL_LAMP_4522, 1), new Item(OIL_LAMP_4524, 1), true, Components.DARKNESS_LIGHT_97), + OIL_LANTERN(26, new Item(OIL_LANTERN_4535, 1), new Item(OIL_LANTERN_4539, 1), false, Components.DARKNESS_LIGHT_97), + BULLSEYE_LANTERN(49, new Item(BULLSEYE_LANTERN_4548, 1), new Item(BULLSEYE_LANTERN_4550, 1), false, -1), + SAPPHIRE_LANTERN(49, new Item(SAPPHIRE_LANTERN_4701, 1), new Item(SAPPHIRE_LANTERN_4702, 1), false, -1), + EMERALD_LANTERN(49, new Item(EMERALD_LANTERN_9064, 1), new Item(EMERALD_LANTERN_9065, 1), false, -1), + MINING_HELMET(65, new Item(MINING_HELMET_5014, 1), new Item(MINING_HELMET_5013, 1), false, Components.DARKNESS_LIGHT_97); + + /** + * Represents the level required. + */ + private int level; + + /** + * Represents the raw item. + */ + private Item raw; + + /** + * Represents the product. + */ + private Item product; + + /** + * If the light source is open (eg. candles, torches, ...). + */ + private final boolean open; + + /** + * The interface id. + */ + private final int interfaceId; + + /** + * Constructs a new {@code LightSource} {@code Object}. + * @param level the level. + * @param raw the raw. + * @param product the product. + * @param open If it's an open light source. + * @param interfaceId The overlay interface id to display. + */ + LightSource(int level, Item raw, Item product, boolean open, int interfaceId) { + this.level = level; + this.raw = raw; + this.product = product; + this.open = open; + this.interfaceId = interfaceId; + } + + /** + * Checks if the player has a lit light source. + * @param player The player. + * @return {@code True} if so. + */ + public static boolean hasActiveLightSource(Player player) { + return getActiveLightSource(player) != null; + } + + /** + * Gets the light source used by the player. + * @param player The player. + * @return The light source object, or null if the player didn't have any + * light source. + */ + public static LightSource getActiveLightSource(Player player) { + LightSource source; + for (Item item : player.getInventory().toArray()) { + if (item != null && (source = forProductId(item.getId())) != null) { + return source; + } + } + for (Item item : player.getEquipment().toArray()) { + if (item != null && (source = forProductId(item.getId())) != null) { + return source; + } + } + return null; + } + + /** + * Gets the light source by the id. + * @param id the id. + * @return the source. + */ + public static LightSource forId(int id) { + for (LightSource light : LightSource.values()) { + if (light.raw.getId() == id) { + return light; + } + } + return null; + } + + /** + * Gets the light souce by the product id. + * @param id the id. + * @return the light source. + */ + public static LightSource forProductId(int id) { + for (LightSource light : LightSource.values()) { + if (light.product.getId() == id) { + return light; + } + } + return null; + } + + /** + * Gets the strength of the light source (1=dim, 2=medium, 3=bright). + * @return The strength. + */ + public int getStrength() { + switch (interfaceId) { + case Components.DARKNESS_LIGHT_97: + return 1; + case Components.DARKNESS_MEDIUM_98: + return 2; + case -1: + return 3; + } + return 0; + } + + /** + * Gets the name of the light source. + * @return The name. + */ + public String getName() { + return super.name().toLowerCase().replaceAll("_", " "); + } + + /** + * Gets the raw item. + * @return the raw. + */ + public Item getRaw() { + return raw; + } + + /** + * Gets the product. + * @return the product. + */ + public Item getProduct() { + return product; + } + + /** + * Gets the level. + * @return the level. + */ + public int getLevel() { + return level; + } + + /** + * Gets the open. + * @return The open. + */ + public boolean isOpen() { + return open; + } + + /** + * Gets the interfaceId. + * @return The interfaceId. + */ + public int getInterfaceId() { + return interfaceId; + } + + /** + * Gets the ids of the raw items. + * @return The raw item ids. + */ + public static int[] getRawIds() { + int array[] = new int[LightSource.values().length]; + for (int i = 0; i < LightSource.values().length -1; i++) { + array[i] = LightSource.values()[i].getRaw().getId(); + } + return array; + } + +} \ No newline at end of file diff --git a/Server/src/main/content/data/Meat.kt b/Server/src/main/content/data/Meat.kt new file mode 100644 index 0000000..714b240 --- /dev/null +++ b/Server/src/main/content/data/Meat.kt @@ -0,0 +1,51 @@ +package content.data + +enum class MeatState { + INEDIBLE_RAW, + INEDIBLE_BURNT, + INEDIBLE_SPECIAL, // could be a quest item + EDIBLE_COOKED, +} + +enum class Meat(val id: Int, val state: MeatState) { + ENCHANTED_BEEF(522, MeatState.INEDIBLE_SPECIAL), + ENCHANTED_RAT_MEAT(523, MeatState.INEDIBLE_SPECIAL), + ENCHANTED_BEAR_MEAT(524, MeatState.INEDIBLE_SPECIAL), + ENCHANTED_CHICKEN(525, MeatState.INEDIBLE_SPECIAL), + RAW_UGTHANKI_MEAT(1859, MeatState.INEDIBLE_RAW), + UGTHANKI_MEAT(1861, MeatState.EDIBLE_COOKED), + RAW_BEEF(2132, MeatState.INEDIBLE_RAW), + RAW_RAT_MEAT(2134, MeatState.INEDIBLE_RAW), + RAW_BEAR_MEAT(2136, MeatState.INEDIBLE_RAW), + RAW_CHICKEN(2138, MeatState.INEDIBLE_RAW), + COOKED_CHICKEN(2140, MeatState.EDIBLE_COOKED), + BURNT_CHICKEN(2140, MeatState.INEDIBLE_BURNT), + COOKED_MEAT(2142, MeatState.EDIBLE_COOKED), + BURNT_MEAT(2146, MeatState.INEDIBLE_BURNT), + THIN_SNAIL_MEAT(3369, MeatState.EDIBLE_COOKED), + LEAN_SNAIL_MEAT(3371, MeatState.EDIBLE_COOKED), + FAT_SNAIL_MEAT(3373, MeatState.EDIBLE_COOKED), + RAW_BEEF_UNDEAD(4287, MeatState.INEDIBLE_RAW), + RAW_CHICKEN_UNDEAD(4289, MeatState.INEDIBLE_RAW), + COOKED_CHICKEN_UNDEAD(4291, MeatState.EDIBLE_COOKED), + COOKED_MEAT_UNDEAD(4293, MeatState.EDIBLE_COOKED), + RAW_CRAB_MEAT(7518, MeatState.INEDIBLE_RAW), + BURNT_CRAB_MEAT(7520, MeatState.INEDIBLE_BURNT), + COOKED_CRAB_MEAT_5(7521, MeatState.EDIBLE_COOKED), + COOKED_CRAB_MEAT_4(7523, MeatState.EDIBLE_COOKED), + COOKED_CRAB_MEAT_3(7524, MeatState.EDIBLE_COOKED), + COOKED_CRAB_MEAT_2(7525, MeatState.EDIBLE_COOKED), + COOKED_CRAB_MEAT_1(7526, MeatState.EDIBLE_COOKED), + GROUND_CRAB_MEAT(7527, MeatState.INEDIBLE_RAW), + LOCUST_MEAT(9052, MeatState.EDIBLE_COOKED), + RAW_BIRD_MEAT(9978, MeatState.INEDIBLE_RAW), + ROAST_BIRD_MEAT(9980, MeatState.EDIBLE_COOKED), + BURNT_BIRD_MEAT(9982, MeatState.INEDIBLE_BURNT), + SKEWERED_BIRD_MEAT(9982, MeatState.INEDIBLE_RAW), + RAW_BEAST_MEAT(9986, MeatState.INEDIBLE_RAW), + ROAST_BEAST_MEAT(9988, MeatState.EDIBLE_COOKED), + BURNT_BEAST_MEAT(9990, MeatState.INEDIBLE_BURNT), + RAW_YAK_MEAT(10816, MeatState.INEDIBLE_RAW), + RAW_PAWYA_MEAT(12535, MeatState.INEDIBLE_RAW), + ENCHANTED_PAWYA_MEAT(12546, MeatState.INEDIBLE_SPECIAL); +} \ No newline at end of file diff --git a/Server/src/main/content/data/Quests.kt b/Server/src/main/content/data/Quests.kt new file mode 100644 index 0000000..190cf20 --- /dev/null +++ b/Server/src/main/content/data/Quests.kt @@ -0,0 +1,158 @@ +package content.data + +enum class Quests(val questName: String) { + MYTHS_OF_THE_WHITE_LANDS("Myths of the White Lands"), + BLACK_KNIGHTS_FORTRESS("Black Knights' Fortress"), + COOKS_ASSISTANT("Cook's Assistant"), + DEMON_SLAYER("Demon Slayer"), + DORICS_QUEST("Doric's Quest"), + DRAGON_SLAYER("Dragon Slayer"), + ERNEST_THE_CHICKEN("Ernest the Chicken"), + GOBLIN_DIPLOMACY("Goblin Diplomacy"), + IMP_CATCHER("Imp Catcher"), + THE_KNIGHTS_SWORD("The Knight's Sword"), + PIRATES_TREASURE("Pirate's Treasure"), + PRINCE_ALI_RESCUE("Prince Ali Rescue"), + THE_RESTLESS_GHOST("The Restless Ghost"), + ROMEO_JULIET("Romeo & Juliet"), + RUNE_MYSTERIES("Rune Mysteries"), + SHEEP_SHEARER("Sheep Shearer"), + SHIELD_OF_ARRAV("Shield of Arrav"), + VAMPIRE_SLAYER("Vampire Slayer"), + WITCHS_POTION("Witch's Potion"), + ANIMAL_MAGNETISM("Animal Magnetism"), + BETWEEN_A_ROCK("Between a Rock..."), + BIG_CHOMPY_BIRD_HUNTING("Big Chompy Bird Hunting"), + BIOHAZARD("Biohazard"), + CABIN_FEVER("Cabin Fever"), + CLOCK_TOWER("Clock Tower"), + CONTACT("Contact!"), + ZOGRE_FLESH_EATERS("Zogre Flesh Eaters"), + CREATURE_OF_FENKENSTRAIN("Creature of Fenkenstrain"), + DARKNESS_OF_HALLOWVALE("Darkness of Hallowvale"), + DEATH_TO_THE_DORGESHUUN("Death to the Dorgeshuun"), + DEATH_PLATEAU("Death Plateau"), + DESERT_TREASURE("Desert Treasure"), + DEVIOUS_MINDS("Devious Minds"), + THE_DIG_SITE("The Dig Site"), + DRUIDIC_RITUAL("Druidic Ritual"), + DWARF_CANNON("Dwarf Cannon"), + EADGARS_RUSE("Eadgar's Ruse"), + EAGLES_PEAK("Eagles' Peak"), + ELEMENTAL_WORKSHOP_I("Elemental Workshop I"), + ELEMENTAL_WORKSHOP_II("Elemental Workshop II"), + ENAKHRAS_LAMENT("Enakhra's Lament"), + ENLIGHTENED_JOURNEY("Enlightened Journey"), + THE_EYES_OF_GLOUPHRIE("The Eyes of Glouphrie"), + FAIRYTALE_I_GROWING_PAINS("Fairytale I - Growing Pains"), + FAIRYTALE_II_CURE_A_QUEEN("Fairytale II - Cure a Queen"), + FAMILY_CREST("Family Crest"), + THE_FEUD("The Feud"), + FIGHT_ARENA("Fight Arena"), + FISHING_CONTEST("Fishing Contest"), + FORGETTABLE_TALE("Forgettable Tale..."), + THE_FREMENNIK_TRIALS("The Fremennik Trials"), + WATERFALL_QUEST("Waterfall Quest"), + GARDEN_OF_TRANQUILITY("Garden of Tranquility"), + GERTRUDES_CAT("Gertrude's Cat"), + GHOSTS_AHOY("Ghosts Ahoy"), + THE_GIANT_DWARF("The Giant Dwarf"), + THE_GOLEM("The Golem"), + THE_GRAND_TREE("The Grand Tree"), + THE_HAND_IN_THE_SAND("The Hand in the Sand"), + HAUNTED_MINE("Haunted Mine"), + HAZEEL_CULT("Hazeel Cult"), + HEROES_QUEST("Heroes' Quest"), + HOLY_GRAIL("Holy Grail"), + HORROR_FROM_THE_DEEP("Horror from the Deep"), + ICTHLARINS_LITTLE_HELPER("Icthlarin's Little Helper"), + IN_AID_OF_THE_MYREQUE("In Aid of the Myreque"), + IN_SEARCH_OF_THE_MYREQUE("In Search of the Myreque"), + JUNGLE_POTION("Jungle Potion"), + LEGENDS_QUEST("Legend's Quest"), + LOST_CITY("Lost City"), + THE_LOST_TRIBE("The Lost Tribe"), + LUNAR_DIPLOMACY("Lunar Diplomacy"), + MAKING_HISTORY("Making History"), + MERLINS_CRYSTAL("Merlin's Crystal"), + MONKEY_MADNESS("Monkey Madness"), + MONKS_FRIEND("Monk's Friend"), + MOUNTAIN_DAUGHTER("Mountain Daughter"), + MOURNINGS_END_PART_I("Mourning's End Part I"), + MOURNINGS_END_PART_II("Mourning's End Part II"), + MURDER_MYSTERY("Murder Mystery"), + MY_ARMS_BIG_ADVENTURE("My Arm's Big Adventure"), + NATURE_SPIRIT("Nature Spirit"), + OBSERVATORY_QUEST("Observatory Quest"), + ONE_SMALL_FAVOUR("One Small Favour"), + PLAGUE_CITY("Plague City"), + PRIEST_IN_PERIL("Priest in Peril"), + RAG_AND_BONE_MAN("Rag and Bone Man"), + RATCATCHERS("Ratcatchers"), + RECIPE_FOR_DISASTER("Recipe for Disaster"), + RECRUITMENT_DRIVE("Recruitment Drive"), + REGICIDE("Regicide"), + ROVING_ELVES("Roving Elves"), + ROYAL_TROUBLE("Royal Trouble"), + RUM_DEAL("Rum Deal"), + SCORPION_CATCHER("Scorpion Catcher"), + SEA_SLUG("Sea Slug"), + THE_SLUG_MENACE("The Slug Menace"), + SHADES_OF_MORTTON("Shades of Mort'ton"), + SHADOW_OF_THE_STORM("Shadow of the Storm"), + SHEEP_HERDER("Sheep Herder"), + SHILO_VILLAGE("Shilo Village"), + A_SOULS_BANE("A Soul's Bane"), + SPIRITS_OF_THE_ELID("Spirits of the Elid"), + SWAN_SONG("Swan Song"), + TAI_BWO_WANNAI_TRIO("Tai Bwo Wannai Trio"), + A_TAIL_OF_TWO_CATS("A Tail of Two Cats"), + TEARS_OF_GUTHIX("Tears of Guthix"), + TEMPLE_OF_IKOV("Temple of Ikov"), + THRONE_OF_MISCELLANIA("Throne of Miscellania"), + THE_TOURIST_TRAP("The Tourist Trap"), + WITCHS_HOUSE("Witch's House"), + TREE_GNOME_VILLAGE("Tree Gnome Village"), + TRIBAL_TOTEM("Tribal Totem"), + TROLL_ROMANCE("Troll Romance"), + TROLL_STRONGHOLD("Troll Stronghold"), + UNDERGROUND_PASS("Underground Pass"), + WANTED("Wanted!"), + WATCHTOWER("Watchtower"), + COLD_WAR("Cold War"), + THE_FREMENNIK_ISLES("The Fremennik Isles"), + TOWER_OF_LIFE("Tower of Life"), + THE_GREAT_BRAIN_ROBBERY("The Great Brain Robbery"), + WHAT_LIES_BELOW("What Lies Below"), + OLAFS_QUEST("Olaf's Quest"), + ANOTHER_SLICE_OF_HAM("Another Slice of H.A.M"), + DREAM_MENTOR("Dream Mentor"), + GRIM_TALES("Grim Tales"), + KINGS_RANSOM("King's Ransom"), + THE_PATH_OF_GLOUPHRIE("The Path of Glouphrie"), + BACK_TO_MY_ROOTS("Back to my Roots"), + LAND_OF_THE_GOBLINS("Land of the Goblins"), + DEALING_WITH_SCABARAS("Dealing with Scabaras"), + WOLF_WHISTLE("Wolf Whistle"), + AS_A_FIRST_RESORT("As a First Resort..."), + CATAPULT_CONSTRUCTION("Catapult Construction"), + KENNITHS_CONCERNS("Kennith's Concerns"), + LEGACY_OF_SEERGAZE("Legacy of Seergaze"), + PERILS_OF_ICE_MOUNTAIN("Perils of Ice Mountain"), + TOKTZ_KET_DILL("TokTz-Ket-Dill"), + SMOKING_KILLS("Smoking Kills"), + ROCKING_OUT("Rocking Out"), + SPIRIT_OF_SUMMER("Spirit of Summer"), + MEETING_HISTORY("Meeting History"), + ALL_FIRED_UP("All Fired Up"), + SUMMERS_END("Summer's End"), + DEFENDER_OF_VARROCK("Defender of Varrock"), + SWEPT_AWAY("Swept Away"), + WHILE_GUTHIX_SLEEPS("While Guthix Sleeps"), + IN_PYRE_NEED("In Pyre Need"), + TEST_QUEST("Test Quest"); + + override fun toString(): String { + return questName + } +} diff --git a/Server/src/main/content/data/RepairItem.java b/Server/src/main/content/data/RepairItem.java new file mode 100644 index 0000000..3ab25a4 --- /dev/null +++ b/Server/src/main/content/data/RepairItem.java @@ -0,0 +1,87 @@ +package content.data; + +import core.game.node.item.Item; + +/** + * Represents the repair item type. + * @author Vexia + */ +public enum RepairItem { + BRONZE_HATCHET(new Item(494, 1), new Item(1351, 1), 0), + BRONZE_PICKAXE(new Item(468, 1), new Item(1265, 1), 0), + IRON_HATCHET(new Item(496, 1), new Item(1349, 1), 0), + IRON_PICKAXE(new Item(470, 1), new Item(1267, 1), 0), + STEEL_HATCHET(new Item(498, 1), new Item(1353, 1), 0), + STEEL_PICKAXE(new Item(472, 1), new Item(1269, 1), 14), + BLACK_HATCHET(new Item(500, 1), new Item(1361, 1), 10), + MITHRIL_HATCHET(new Item(502, 1), new Item(1355, 1), 18), + MITHRIL_PICKAXE(new Item(474, 1), new Item(1273, 1), 43), + ADAMANT_HATCHET(new Item(504, 1), new Item(1357, 1), 43), + ADAMANT_PICKAXE(new Item(476, 1), new Item(1271, 1), 107), + RUNE_HATCHET(new Item(506, 1), new Item(1359, 1), 427), + RUNE_PICKAXE(new Item(478, 1), new Item(1275, 1), 1100), + DRAGON_HATCHET(new Item(6741, 1), new Item(6739, 1), 1800); + + /** + * The item id. + */ + private final Item item; + + /** + * The product item. + */ + private final Item product; + + /** + * The cost of the money to repair. + */ + private final int cost; + + /** + * Constructs a new {@code BobRepairItem} {@code Object}. + * @param item the item. + * @param product the product. + * @param cost the cost. + */ + RepairItem(Item item, Item product, int cost) { + this.item = item; + this.product = product; + this.cost = cost; + } + + /** + * Gets the item. + * @return The item. + */ + public Item getItem() { + return item; + } + + /** + * Gets the product. + * @return The product. + */ + public Item getProduct() { + return product; + } + + /** + * Gets the cost. + * @return The cost. + */ + public int getCost() { + return cost; + } + + /** + * Gets the reapir item by the id. + * @param id the id. + * @return the repair item. + */ + public static RepairItem forId(int id) { + for (RepairItem item : RepairItem.values()) + if (item.item.getId() == id) + return item; + return null; + } +} \ No newline at end of file diff --git a/Server/src/main/content/data/consumables/Consumables.java b/Server/src/main/content/data/consumables/Consumables.java new file mode 100644 index 0000000..82c6650 --- /dev/null +++ b/Server/src/main/content/data/consumables/Consumables.java @@ -0,0 +1,421 @@ +package content.data.consumables; + +import content.data.consumables.effects.*; +import core.game.consumable.*; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.entity.skill.Skills; +import core.game.world.update.flag.context.Animation; +import org.rs09.consts.Items; + +import java.util.ArrayList; +import java.util.HashMap; + +import static core.tools.TickUtilsKt.minutesToTicks; +import static core.tools.TickUtilsKt.secondsToTicks; + +/** + * Represents a repository of active consumables in the framework. + */ +public enum Consumables { + + /** Meats */ + COOKED_MEAT(new Food(new int[] {2142}, new HealingEffect(3))), + SHRIMPS(new Food(new int[] {315}, new HealingEffect(3))), + COOKED_CHICKEN(new Food(new int[] {2140}, new HealingEffect(3))), + COOKED_RABBIT(new Food(new int[] {3228}, new HealingEffect(5))), + ANCHOVIES(new Food(new int[] {319}, new HealingEffect(1))), + SARDINE(new Food(new int[] {325}, new HealingEffect(4))), + POISON_KARAMBWAN(new Food(new int[] {3146}, new PoisonKarambwanEffect())), + UGTHANKI_MEAT(new Food(new int[] {1861}, new HealingEffect(3))), + HERRING(new Food(new int[] {347}, new HealingEffect(5))), + MACKEREL(new Food(new int[] {355}, new HealingEffect(6))), + ROAST_BIRD_MEAT(new Food(new int[] {9980}, new HealingEffect(6))), + THIN_SNAIL(new Food(new int[] {3369}, new RandomHealthEffect(5, 7))), + TROUT(new Food(new int[] {333}, new HealingEffect(7))), + SPIDER_ON_STICK(new Food(new int[] {6297, 6305}, new RandomHealthEffect(7, 11))), + SPIDER_ON_SHAFT(new Food(new int[] {6299}, new HealingEffect(7))), + ROAST_RABBIT(new Food(new int[] {7223}, new HealingEffect(7))), + LEAN_SNAIL(new Food(new int[] {3371}, new RandomHealthEffect(6, 8))), + COD(new Food(new int[] {339}, new HealingEffect(7))), + PIKE(new Food(new int[] {351}, new HealingEffect(8))), + ROAST_BEAST_MEAT(new Food(new int[] {9988}, new HealingEffect(8))), + COOKED_CRAB_MEAT(new Food(new int[] {7521, 7523, 7524, 7525, 7526}, new HealingEffect(2))), + FAT_SNAIL(new Food(new int[] {3373}, new RandomHealthEffect(7, 9))), + SALMON(new Food(new int[] {329}, new HealingEffect(9))), + SLIMY_EEL(new Food(new int[] {3381}, new RandomHealthEffect(6, 10))), + TUNA(new Food(new int[] {361}, new HealingEffect(10))), + COOKED_KARAMBWAN(new Food(new int[] {3144}, new HealingEffect(18)), true), + COOKED_CHOMPY(new Food(new int[] {2878}, new HealingEffect(10))), + RAINBOW_FISH(new Food(new int[] {10136}, new HealingEffect(11))), + CAVE_EEL(new Food(new int[] {5003}, new RandomHealthEffect(8, 12))), + LOBSTER(new Food(new int[] {379}, new HealingEffect(12))), + COOKED_JUBBLY(new Food(new int[] {7568}, new HealingEffect(15))), + BASS(new Food(new int[] {365}, new HealingEffect(13))), + SWORDFISH(new Food(new int[] {373}, new HealingEffect(14))), + LAVA_EEL(new Food(new int[] {2149}, new HealingEffect(11))), + MONKFISH(new Food(new int[] {7946}, new HealingEffect(16))), + SHARK(new Food(new int[] {385}, new HealingEffect(20))), + SEA_TURTLE(new Food(new int[] {397}, new HealingEffect(21))), + MANTA_RAY(new Food(new int[] {391}, new HealingEffect(22))), + KARAMBWANJI(new Food(new int[] {3151}, new HealingEffect(3))), + STUFFED_SNAKE(new Food(new int[] {7579}, new HealingEffect(20), "You eat the stuffed snake-it's quite a meal! It tastes like chicken.")), + CRAYFISH(new Food(new int[] {13433}, new HealingEffect(1))), + GIANT_FROG_LEGS(new Food(new int [] {4517}, new HealingEffect(6))), + + /** Breads */ + BREAD(new Food(new int[] {2309}, new HealingEffect(5))), + BAGUETTE(new Food(new int[] {6961}, new HealingEffect(6))), + + /** Sandwiches */ + TRIANGLE_SANDWICH(new Food(new int[] {6962}, new HealingEffect(6))), + SQUARE_SANDWICH(new Food(new int[] {6965}, new HealingEffect(6))), + SEAWEED_SANDWICH(new FakeConsumable(3168, new String[] {"You really, really do not want to eat that."})), + FROGBURGER(new Food(new int[] {10962}, new HealingEffect(2))), + + /** Kebabs */ + UGTHANKI_KEBAB(new Food(new int[] {1883}, new UgthankiKebabEffect())), + UGTHANKI_KEBAB_SMELLING(new Food(new int[] {1885}, new SmellingUgthankiKebabEffect())), + KEBAB(new Food(new int[] {1971}, new KebabEffect())), + SUPER_KEBAB(new Food(new int[] {4608}, new SuperKebabEffect())), + + /** Pies */ + REDBERRY_PIE(new HalfableFood(new int[] {2325, 2333, 2313}, new HealingEffect(5))), + MEAT_PIE(new HalfableFood(new int[] {2327, 2331, 2313}, new HealingEffect(6))), + APPLE_PIE(new HalfableFood(new int[] {2323, 2335, 2313}, new HealingEffect(7))), + GARDEN_PIE(new HalfableFood(new int[] {7178, 7180, 2313}, new MultiEffect(new HealingEffect(6), new SkillEffect(Skills.FARMING, 3, 0)))), + FISH_PIE(new HalfableFood(new int[] {7188, 7190, 2313}, new MultiEffect(new HealingEffect(6), new SkillEffect(Skills.FISHING, 3, 0)))), + ADMIRAL_PIE(new HalfableFood(new int[] {7198, 7200, 2313}, new MultiEffect(new HealingEffect(8), new SkillEffect(Skills.FISHING, 5, 0)))), + WILD_PIE(new HalfableFood(new int[] {7208, 7210, 2313}, new MultiEffect(new SkillEffect(Skills.SLAYER, 5, 0), new SkillEffect(Skills.RANGE, 4, 0), new HealingEffect(11)))), + SUMMER_PIE(new HalfableFood(new int[] {7218, 7220, 2313}, new MultiEffect(new HealingEffect(11), new SkillEffect(Skills.AGILITY, 5, 0), new EnergyEffect(10)))), + + /** Stews */ + STEW(new Food(new int[] {2003, 1923}, new HealingEffect(11))), + SPICY_STEW(new Food(new int[] {7479, 1923}, new HealingEffect(11))), + CURRY(new Food(new int[] {2011, 1923}, new HealingEffect(19))), + BANANA_STEW(new Food(new int[] {4016, 1923}, new HealingEffect(11))), + + /** Pizzas */ + PLAIN_PIZZA(new HalfableFood(new int[] {2289, 2291}, new HealingEffect(7))), + MEAT_PIZZA(new HalfableFood(new int[] {2293, 2295}, new HealingEffect(8))), + ANCHOVY_PIZZA(new HalfableFood(new int[] {2297, 2299}, new HealingEffect(9))), + PINEAPPLE_PIZZA(new HalfableFood(new int[] {2301, 2303}, new HealingEffect(11))), + + /** Cakes */ + CAKE(new Cake(new int[] {1891, 1893, 1895}, new HealingEffect(4), "You eat part of the cake.", "You eat some more cake.", "You eat the slice of cake.")), + CHOCOLATE_CAKE(new Cake(new int[] {1897, 1899, 1901}, new HealingEffect(5), "You eat part of the chocolate cake.", "You eat some more of the chocolate cake.", "You eat the slice of cake.")), + ROCK_CAKE(new Food(new int[] {2379}, new RockCakeEffect(), "The rock cake resists all attempts to eat it.")), + DWARVEN_ROCK_CAKE(new Food(new int[] {7510, 7510}, new DwarvenRockCakeEffect(), "Ow! You nearly broke a tooth!", "The rock cake resists all attempts to eat it.")), + HOT_DWARVEN_ROCK_CAKE(new Food(new int[] {7509, 7509}, new DwarvenRockCakeEffect(), "Ow! You nearly broke a tooth!", "The rock cake resists all attempts to eat it.")), + COOKED_FISHCAKE(new Food(new int[] {7530}, new HealingEffect(11))), + MINT_CAKE(new Food(new int[] {9475}, new EnergyEffect(50))), + + /** Vegetables */ + POTATO(new Food(new int[] {1942}, new HealingEffect(1), "You eat the potato. Yuck!")), + BAKED_POTATO(new Food(new int[] {6701}, new HealingEffect(4))), + SPICY_SAUCE(new Food(new int[] {7072, 1923}, new HealingEffect(2))), + CHILLI_CON_CARNE(new Food(new int[] {7062, 1923}, new HealingEffect(5))), + SCRAMBLED_EGG(new Food(new int[] {7078, 1923}, new HealingEffect(5))), + EGG_AND_TOMATO(new Food(new int[] {7064, 1923}, new HealingEffect(8))), + SWEET_CORN(new Food(new int[] {5988}, new MultiEffect(new HealingEffect(1), new PercentageHealthEffect(10)))), + SWEETCORN_BOWL(new Food(new int[] {7088, 1923}, new MultiEffect(new HealingEffect(1), new PercentageHealthEffect(10)))), + POTATO_WITH_BUTTER(new Food(new int[] {6703}, new HealingEffect(7))), + CHILLI_POTATO(new Food(new int[] {7054}, new HealingEffect(14))), + FRIED_ONIONS(new Food(new int[] {7084, 1923}, new HealingEffect(5))), + FRIED_MUSHROOMS(new Food(new int[] {7082, 1923}, new HealingEffect(5))), + POTATO_WITH_CHEESE(new Food(new int[] {6705}, new HealingEffect(16))), + EGG_POTATO(new Food(new int[] {7056}, new HealingEffect(11))), + MUSHROOMS_AND_ONIONS(new Food(new int[] {7066, 1923}, new HealingEffect(11))), + MUSHROOM_POTATO(new Food(new int[] {7058}, new HealingEffect(20))), + TUNA_AND_CORN(new Food(new int[] {7068, 1923}, new HealingEffect(13))), + TUNA_POTATO(new Food(new int[] {7060}, new HealingEffect(22))), + ONION(new Food(new int[] {1957}, new HealingEffect(1), "It's always sad to see a grown man/woman cry.")), + CABBAGE(new Food(new int[] {1965}, new HealingEffect(1), "You eat the cabbage. Yuck!")), + DRAYNOR_CABBAGE(new Food(new int[] {1967}, new DraynorCabbageEffect(), "You eat the cabbage.", "It seems to taste nicer than normal.")), + EVIL_TURNIP(new Food(new int[] {12134, 12136, 12138}, new HealingEffect(6))), + SPINACH_ROLL(new Food(new int[] {1969}, new HealingEffect(2))), + + /** Dairies */ + POT_OF_CREAM(new Food(new int[] {2130}, new HealingEffect(1))), + CHEESE(new Food(new int[] {1985}, new HealingEffect(2))), + CHOCOLATEY_MILK(new Drink(new int[] {1977, 1925}, new HealingEffect(4))), + + /** Fruits */ + BANANA(new Food(new int[] {1963}, new HealingEffect(2))), + SLICED_BANANA(new Food(new int[] {3162}, new HealingEffect(2))), + RED_BANANA(new Food(new int[] {7572}, new HealingEffect(5), "You eat the red banana. It's tastier than your average banana.")), + SLICED_RED_BANANA(new Food(new int[] {7574}, new HealingEffect(5), "You eat the sliced red banana. Yum.")), + ORANGE(new Food(new int[] {2108}, new HealingEffect(2))), + ORANGE_CHUNKS(new Food(new int[] {2110}, new HealingEffect(2))), + ORANGE_SLICES(new Food(new int[] {2112}, new HealingEffect(2))), + PAPAYA_FRUIT(new Food(new int[] {5972}, new MultiEffect(new EnergyEffect(5), new HealingEffect(8)))), + TENTI_PINEAPPLE(new FakeConsumable(1851, new String[] {"Try using a knife to slice it into pieces."})), + PINEAPPLE(new FakeConsumable(2114, new String[] {"Try using a knife to slice it into pieces."})), + PINEAPPLE_CHUNKS(new Food(new int[] {2116}, new HealingEffect(2))), + PINEAPPLE_RING(new Food(new int[] {2118}, new HealingEffect(2))), + DWELLBERRIES(new Food(new int[] {2126}, new HealingEffect(2))), + JANGERBERRIES(new Food(new int[] {247}, new MultiEffect(new SkillEffect(Skills.ATTACK, 2, 0), new SkillEffect(Skills.STRENGTH, 1, 0), new PrayerEffect(1, 0), new SkillEffect(Skills.DEFENCE, -1, 0)), "You eat the jangerberries.", "They taste very bitter.")), + STRAWBERRY(new Food(new int[] {5504}, new MultiEffect(new HealingEffect(1), new PercentageHealthEffect(6)))), + TOMATO(new Food(new int[] {1982}, new HealingEffect(2))), + WATERMELON(new FakeConsumable(5982, new String[] {"You can't eat it whole; maybe you should cut it up."})), + WATERMELON_SLICE(new Food(new int[] {5984}, new PercentageHealthEffect(5))), + LEMON(new Food(new int[] {2102}, new HealingEffect(2))), + LEMON_CHUNKS(new Food(new int[] {2104}, new HealingEffect(2))), + LEMON_SLICES(new Food(new int[] {2106}, new HealingEffect(2))), + LIME(new Food(new int[] {2120}, new HealingEffect(2))), + LIME_CHUNKS(new Food(new int[] {2122}, new HealingEffect(2))), + LIME_SLICES(new Food(new int[] {2124}, new HealingEffect(2))), + PEACH(new Food(new int[] {6883}, new HealingEffect(8))), + WHITE_TREE_FRUIT(new Food(new int[] {6469}, new MultiEffect(new RandomEnergyEffect(5, 10), new HealingEffect(3)))), + STRANGE_FRUIT(new Food(new int[] {464}, new MultiEffect(new RemoveTimerEffect("poison"), new EnergyEffect(30)))), + + /** Gnome Cooking */ + TOAD_CRUNCHIES(new Food(new int[] {2217}, new HealingEffect(8))), + PREMADE_TD_CRUNCH(new Food(new int[] {2243}, new HealingEffect(8))), + SPICY_CRUNCHIES(new Food(new int[] {2213}, new HealingEffect(7))), + PREMADE_SY_CRUNCH(new Food(new int[] {2241}, new HealingEffect(7))), + WORM_CRUNCHIES(new Food(new int[] {2205}, new HealingEffect(8))), + PREMADE_WM_CRUNC(new Food(new int[] {2237}, new HealingEffect(8))), + CHOCCHIP_CRUNCHIES(new Food(new int[] {2209}, new HealingEffect(7))), + PREMADE_CH_CRUNCH(new Food(new int[] {2239}, new HealingEffect(7))), + FRUIT_BATTA(new Food(new int[] {2277}, new HealingEffect(11))), + PREMADE_FRT_BATTA(new Food(new int[] {2225}, new HealingEffect(11))), + TOAD_BATTA(new Food(new int[] {2255}, new HealingEffect(11))), + PREMADE_TD_BATTA(new Food(new int[] {2221}, new HealingEffect(11))), + WORM_BATTA(new Food(new int[] {2253}, new HealingEffect(11))), + PREMADE_WM_BATTA(new Food(new int[] {2219}, new HealingEffect(11))), + VEGETABLE_BATTA(new Food(new int[] {2281}, new HealingEffect(11))), + PREMADE_VEG_BATTA(new Food(new int[] {2227}, new HealingEffect(11))), + CHEESE_AND_TOMATOES_BATTA(new Food(new int[] {2259}, new HealingEffect(11))), + PREMADE_CT_BATTA(new Food(new int[] {2223}, new HealingEffect(11))), + WORM_HOLE(new Food(new int[] {2191}, new HealingEffect(12))), + PREMADE_WORM_HOLE(new Food(new int[] {2233}, new HealingEffect(12))), + VEG_BALL(new Food(new int[] {2195}, new HealingEffect(12))), + PREMADE_VEG_BALL(new Food(new int[] {2235}, new HealingEffect(12))), + TANGLED_TOADS_LEGS(new Food(new int[] {2187}, new HealingEffect(15))), + PREMADE_TTL(new Food(new int[] {2231}, new HealingEffect(15))), + CHOCOLATE_BOMB(new Food(new int[] {2195}, new HealingEffect(15))), + PREMADE_CHOC_BOMB(new Food(new int[] {2229}, new HealingEffect(15))), + TOAD_LEGS(new Food(new int[] {2152}, new HealingEffect(3))), + KING_WORM(new Food(new int[] {2162}, new HealingEffect(2))), + + /** Ales */ + ASGOLDIAN_ALE(new FakeConsumable(7508, new String[] {"I don't think I'd like gold in beer thanks. Leave it for the dwarves."})), + ASGARNIAN_ALE(new Drink(new int[] {1905, 1919}, new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.STRENGTH, 2, 0), new SkillEffect(Skills.ATTACK, -4, 0)), "You drink the ale. You feel slightly reinvigorated...", "...and slightly dizzy too.")), + ASGARNIAN_ALE_KEG(new Drink(new int[] {5785, 5783, 5781, 5779, 5769}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 2, 0), new SkillEffect(Skills.ATTACK, -4, 0)), new Animation(2289), "You drink the ale. You feel slightly reinvigorated...", "...and slightly dizzy too.")), + ASGARNIAN_ALE_M(new Drink(new int[] {5739, 1919}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 3, 0), new SkillEffect(Skills.ATTACK, -6, 0)))), + ASGARNIAN_ALE_M_KEG(new Drink(new int[] {5865, 5863, 5861, 5859, 5769}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 3, 0), new SkillEffect(Skills.ATTACK, -6, 0)), new Animation(2289))), + AXEMANS_FOLLY(new Drink(new int[] {5751, 1919}, new MultiEffect(new SkillEffect(Skills.WOODCUTTING, 1, 0), new HealingEffect(1), new SkillEffect(Skills.STRENGTH, -3, 0), new SkillEffect(Skills.ATTACK, -3, 0)))), + AXEMANS_FOLLY_KEG(new Drink(new int[] {5825, 5823, 5821, 5819, 5769}, new MultiEffect(new SkillEffect(Skills.WOODCUTTING, 1, 0), new HealingEffect(1), new SkillEffect(Skills.STRENGTH, -3, 0), new SkillEffect(Skills.ATTACK, -3, 0)), new Animation(2289))), + AXEMANS_FOLLY_M(new Drink(new int[] {5753, 1919}, new MultiEffect(new SkillEffect(Skills.WOODCUTTING, 2, 0), new HealingEffect(2), new SkillEffect(Skills.STRENGTH, -4, 0), new SkillEffect(Skills.ATTACK, -4, 0)))), + AXEMANS_FOLLY_M_KEG(new Drink(new int[] {5905, 5903, 5901, 5899, 5769}, new MultiEffect(new SkillEffect(Skills.WOODCUTTING, 2, 0), new HealingEffect(2), new SkillEffect(Skills.STRENGTH, -4, 0), new SkillEffect(Skills.ATTACK, -4, 0)), new Animation(2289))), + BANDITS_BREW(new Drink(new int[] {4627, 1919}, new MultiEffect(new SkillEffect(Skills.THIEVING, 1, 0), new SkillEffect(Skills.ATTACK, 1, 0), new SkillEffect(Skills.STRENGTH, -1, 0), new SkillEffect(Skills.DEFENCE, -6, 0), new HealingEffect(1)), "You drink the beer. You feel slightly reinvigorated...", "...and slightly dizzy too.")), + BEER(new Drink(new int[] {1917, 1919}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.STRENGTH, 0, 0.04), new SkillEffect(Skills.ATTACK, 0, -0.07)), "You drink the beer. You feel slightly reinvigorated...", "...and slightly dizzy too.")), + BEER_TANKARD(new Drink(new int[] {3803, 3805}, new MultiEffect(new SkillEffect(Skills.ATTACK, -9, 0), new SkillEffect(Skills.STRENGTH, 4, 0)), "You quaff the beer. You feel slightly reinvigorated...", "...but very dizzy too.")), + KEG_OF_BEER(new Drink(new int[] {3801}, new KegOfBeerEffect(), new Animation(1330), "You chug the keg. You feel reinvigorated...", "...but extremely drunk too.")), + CHEFS_DELIGHT(new Drink(new int[] {5755, 1919}, new MultiEffect(new SkillEffect(Skills.COOKING, 1, 0.05), new HealingEffect(1), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)))), + CHEFS_DELIGHT_KEG(new Drink(new int[] {5833, 5831, 5829, 5827, 5769}, new MultiEffect(new SkillEffect(Skills.COOKING, 1, 0.05), new HealingEffect(1), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)), new Animation(2289))), + CHEFS_DELIGHT_M(new Drink(new int[] {5757, 1919}, new MultiEffect(new SkillEffect(Skills.COOKING, 2, 0.05), new HealingEffect(2), new SkillEffect(Skills.ATTACK, -3, 0), new SkillEffect(Skills.STRENGTH, -3, 0)))), + CHEFS_DELIGHT_M_KEG(new Drink(new int[] {5913, 5911, 5909, 5907, 5769}, new MultiEffect(new SkillEffect(Skills.COOKING, 2, 0.05), new HealingEffect(2), new SkillEffect(Skills.ATTACK, -3, 0), new SkillEffect(Skills.STRENGTH, -3, 0)), new Animation(2289))), + CIDER(new Drink(new int[] {5763, 1919}, new MultiEffect(new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.FARMING, 1, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0))))), + CIDER_KEG(new Drink(new int[] {5849, 5847, 5845, 5843, 5769}, new MultiEffect(new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.FARMING, 1, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0))), new Animation(2289))), + MATURE_CIDER(new Drink(new int[] {5765, 1919}, new MultiEffect(new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.FARMING, 2, 0), new SkillEffect(Skills.ATTACK, -5, 0), new SkillEffect(Skills.STRENGTH, -5, 0))))), + CIDER_M_KEG(new Drink(new int[] {5929, 5927, 5925, 5923, 5769}, new MultiEffect(new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.FARMING, 2, 0), new SkillEffect(Skills.ATTACK, -5, 0), new SkillEffect(Skills.STRENGTH, -5, 0))), new Animation(2289))), + DRAGON_BITTER(new Drink(new int[] {1911, 1919}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.STRENGTH, 2, 0), new SkillEffect(Skills.ATTACK, -4, 0)))), + DRAGON_BITTER_KEG(new Drink(new int[] {5809, 5807, 5805, 5803, 5769}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.STRENGTH, 2, 0), new SkillEffect(Skills.ATTACK, -4, 0)), new Animation(2289))), + DRAGON_BITTER_M(new Drink(new int[] {5745, 1919}, new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.STRENGTH, 3, 0), new SkillEffect(Skills.ATTACK, -6, 0)))), + DRAGON_BITTER_M_KEG(new Drink(new int[] {5889, 5887, 5885, 5883, 5769}, new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.STRENGTH, 3, 0), new SkillEffect(Skills.ATTACK, -6, 0)), new Animation(2289))), + DWARVEN_STOUT(new Drink(new int[] {1913, 1919}, new MultiEffect(new SkillEffect(Skills.MINING, 1, 0), new SkillEffect(Skills.SMITHING, 1 ,0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0), new SkillEffect(Skills.DEFENCE, -2, 0), new HealingEffect(1)), "You drink the Dwarven Stout. It tastes foul.", "It tastes pretty strong too.")), + DWARVEN_STOUT_KEG(new Drink(new int[] {5777, 5775, 5773, 5771, 5769}, new MultiEffect(new SkillEffect(Skills.MINING, 1, 0), new SkillEffect(Skills.SMITHING, 1 ,0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0), new SkillEffect(Skills.DEFENCE, -2, 0), new HealingEffect(1)), new Animation(2289), "You drink the Dwarven Stout. It tastes foul.", "It tastes pretty strong too.")), + DWARVEN_STOUT_M(new Drink(new int[] {5747, 1919}, new MultiEffect(new SkillEffect(Skills.MINING, 2, 0), new SkillEffect(Skills.SMITHING, 2 ,0), new SkillEffect(Skills.ATTACK, -7, 0), new SkillEffect(Skills.STRENGTH, -7, 0), new SkillEffect(Skills.DEFENCE, -7, 0), new HealingEffect(1)))), + DWARVEN_STOUT_M_KEG(new Drink(new int[] {5857, 5855, 5853, 5851, 5769}, new MultiEffect(new SkillEffect(Skills.MINING, 2, 0), new SkillEffect(Skills.SMITHING, 2 ,0), new SkillEffect(Skills.ATTACK, -7, 0), new SkillEffect(Skills.STRENGTH, -7, 0), new SkillEffect(Skills.DEFENCE, -7, 0), new HealingEffect(1)), new Animation(2289))), + GREENMANS_ALE(new Drink(new int[] {1909, 1919}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.HERBLORE, 1, 0), new SkillEffect(Skills.ATTACK, -3, 0), new SkillEffect(Skills.STRENGTH, -3, 0), new SkillEffect(Skills.DEFENCE, -3, 0)))), + GREENMANS_ALE_KEG(new Drink(new int[] {5793, 5791, 5789, 5787, 5769}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.HERBLORE, 1, 0), new SkillEffect(Skills.ATTACK, -3, 0), new SkillEffect(Skills.STRENGTH, -3, 0), new SkillEffect(Skills.DEFENCE, -3, 0)), new Animation(2289))), + GREENMANS_ALE_M(new Drink(new int[] {5743, 1919}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.HERBLORE, 2, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)))), + GREENMANS_ALE_M_KEG(new Drink(new int[] {5873, 5871, 5869, 5867, 5769}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.HERBLORE, 2, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)), new Animation(2289))), + GROG(new Drink(new int[] {1915, 1919}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 3, 0), new SkillEffect(Skills.ATTACK, -6, 0)))), + MOONLIGHT_MEAD(new Drink(new int[] {2955, 1919}, new HealingEffect(4), "It tastes like something just died in your mouth.")), + MOONLIGHT_MEAD_KEG(new Drink(new int[] {5817, 5815, 5813, 5811, 5769}, new HealingEffect(4), new Animation(2289), "It tastes like something just died in your mouth.")), + MOONLIGHT_MEAD_M(new Drink(new int[] {5749, 1919}, new HealingEffect(6))), + MOONLIGHT_MEAD_M_KEG(new Drink(new int[] {5897, 5895, 5893, 5891, 5769}, new HealingEffect(6), new Animation(2289))), + SLAYERS_RESPITE(new Drink(new int[] {5759, 1919}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.SLAYER, 2, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)))), + SLAYERS_RESPITE_KEG(new Drink(new int[] {5841, 5839, 5837, 5835, 5769}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.SLAYER, 2, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)), new Animation(2289))), + SLAYERS_RESPITE_M(new Drink(new int[] {5761, 1919}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.SLAYER, 4, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)))), + SLAYERS_RESPITE_M_KEG(new Drink(new int[] {5841, 5839, 5837, 5835, 5769}, new MultiEffect(new HealingEffect(1), new SkillEffect(Skills.SLAYER, 4, 0), new SkillEffect(Skills.ATTACK, -2, 0), new SkillEffect(Skills.STRENGTH, -2, 0)), new Animation(2289))), + WIZARDS_MIND_BOMB(new Drink(new int[] {1907, 1919}, new WizardsMindBombEffect(), "You drink the Wizard's Mind Bomb.", "You feel very strange.")), + MATURE_WMB(new Drink(new int[] {5741, 1919}, new MatureWmbEffect())), + + /** Cocktails */ + FRUIT_BLAST(new Drink(new int[] {2084, 2026}, new HealingEffect(9))), + PREMADE_FR_BLAST(new Drink(new int[] {2034, 2026}, new HealingEffect(9))), + CRAFTED_FR_BLAST(new Drink(new int[] {9514, 2026}, new HealingEffect(9))), + PINEAPPLE_PUNCH(new Drink(new int[] {2048, 2026}, new HealingEffect(9), "You drink the cocktail. It tastes great.")), + PREMADE_P_PUNCH(new Drink(new int[] {2036, 2026}, new HealingEffect(9), "You drink the cocktail. It tastes great.")), + CRAFTED_P_PUNCH(new Drink(new int[] {9512, 2026}, new HealingEffect(9))), + WIZARD_BLIZZARD(new Drink(new int[] {2054, 2026}, new MultiEffect(new HealingEffect(5), new SkillEffect(Skills.STRENGTH, 6, 0), new SkillEffect(Skills.ATTACK, -4, 0)))), + PREMADE_WIZ_BLZD(new Drink(new int[] {2040, 2026}, new MultiEffect(new HealingEffect(5), new SkillEffect(Skills.STRENGTH, 6, 0), new SkillEffect(Skills.ATTACK, -4, 0)))), + CRAFTED_WIZ_BLZD(new Drink(new int[]{9508, 2026}, new MultiEffect(new HealingEffect(5), new SkillEffect(Skills.STRENGTH, 6, 0),new SkillEffect(Skills.ATTACK, -4, 0 )))), + SHORT_GREEN_GUY(new Drink(new int[] {2080, 2026}, new MultiEffect(new HealingEffect(5), new SkillEffect(Skills.STRENGTH, 4, 0), new SkillEffect(Skills.ATTACK, -3, 0)))), + PREMADE_SGG(new Drink(new int[] {2038, 2026}, new MultiEffect(new HealingEffect(5), new SkillEffect(Skills.STRENGTH, 4, 0), new SkillEffect(Skills.ATTACK, -3, 0)))), + CRAFTED_SGG(new Drink(new int[]{9510, 2026}, new MultiEffect(new HealingEffect(5), new SkillEffect(Skills.STRENGTH, 4, 0), new SkillEffect(Skills.ATTACK, -3,0)))), + DRUNK_DRAGON(new Drink(new int[] {2092, 2026}, new MultiEffect(new HealingEffect(5), new SkillEffect(Skills.STRENGTH, 7, 0), new SkillEffect(Skills.ATTACK, -4, 0)))), + PREMADE_DR_DRAGON(new Drink(new int[] {2032, 2026}, new MultiEffect(new HealingEffect(5), new SkillEffect(Skills.STRENGTH, 7, 0), new SkillEffect(Skills.ATTACK, -4, 0)))), + CRAFTED_DR_DRAGON(new Drink(new int[] {9516, 2026}, new MultiEffect(new HealingEffect(5), new SkillEffect(Skills.STRENGTH, 7, 0), new SkillEffect(Skills.ATTACK, -4,0)))), + CHOC_SATURDAY(new Drink(new int[] {2074, 2026}, new MultiEffect(new HealingEffect(5), new SkillEffect(Skills.STRENGTH, 7, 0), new SkillEffect(Skills.ATTACK, -4, 0)))), + PREMADE_CHOC_SDY(new Drink(new int[] {2030, 2026}, new MultiEffect(new HealingEffect(5), new SkillEffect(Skills.STRENGTH, 7, 0), new SkillEffect(Skills.ATTACK, -4, 0)))), + CRAFTED_CHOC_SDY(new Drink(new int[] {9518, 2026}, new MultiEffect(new HealingEffect(5), new SkillEffect(Skills.STRENGTH, 7,0), new SkillEffect(Skills.ATTACK, -4,0)))), + BLURBERRY_SPECIAL(new Drink(new int[] {2064, 2026}, new MultiEffect(new HealingEffect(6), new SkillEffect(Skills.STRENGTH, 6, 0), new SkillEffect(Skills.ATTACK, -4, 0)))), + PREMADE_BLURB_SP(new Drink(new int[] {2028, 2026}, new MultiEffect(new HealingEffect(6), new SkillEffect(Skills.STRENGTH, 6, 0), new SkillEffect(Skills.ATTACK, -4, 0)))), + CRAFTED_BLURB_SP(new Drink(new int[] {9520, 2026}, new MultiEffect(new HealingEffect(6), new SkillEffect(Skills.STRENGTH,6,0), new SkillEffect(Skills.ATTACK, -4,0)))), + + /** Bottled Drinks */ + KARAMJAN_RUM(new Drink(new int[] {431}, new MultiEffect(new HealingEffect(5), new SkillEffect(Skills.STRENGTH, 5, 0), new SkillEffect(Skills.ATTACK, -4, 0)))), + BRAINDEATH_RUM(new Drink(new int[] {7157}, new MultiEffect(new SkillEffect(Skills.DEFENCE, 0, -0.1), new SkillEffect(Skills.ATTACK, 0, -0.05), new SkillEffect(Skills.PRAYER, 0, -0.05), new SkillEffect(Skills.RANGE, 0, -0.05), new SkillEffect(Skills.MAGIC, 0, -0.05), new SkillEffect(Skills.HERBLORE, 0, -0.05), new SkillEffect(Skills.STRENGTH, 3, 0), new SkillEffect(Skills.MINING, 1, 0)), "With a sense of impending doom you drink the 'rum'. You try very hard not to die.")), + RUM_TROUBLE_BREWING_RED(new Drink(new int[] {8940, 8940}, new TroubleBrewingRumEffect("Oh gods! It tastes like burning!"), new Animation(9605))), + RUM_TROUBLE_BREWING_BLUE(new Drink(new int[] {8941, 8941}, new TroubleBrewingRumEffect("My Liver! My Liver is melting!"), new Animation(9604))), + VODKA(new Drink(new int[] {2015}, new MultiEffect(new HealingEffect(2), new SkillEffect(Skills.ATTACK, -4, 0), new SkillEffect(Skills.STRENGTH, 4, 0)))), + GIN(new Drink(new int[] {2019}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 1, 0), new SkillEffect(Skills.ATTACK, 4, 0), new RandomHealthEffect(3, 4)))), + BRANDY(new Drink(new int[] {2021}, new MultiEffect(new HealingEffect(5), new SkillEffect(Skills.ATTACK, 4, 0)))), + WHISKY(new Drink(new int[] {2017}, new MultiEffect(new HealingEffect(5), new SkillEffect(Skills.STRENGTH, 3, 0), new SkillEffect(Skills.ATTACK, -4, 0)))), + BOTTLE_OF_WINE(new Drink(new int[] {7919, 7921}, new MultiEffect(new HealingEffect(14), new SkillEffect(Skills.ATTACK, -3, 0)))), + + /** Wine */ + JUG_OF_WINE(new Drink(new int[] {1993, 1935}, new MultiEffect(new HealingEffect(11), new SkillEffect(Skills.ATTACK, -2, 0)))), + HALF_FULL_WINE_JUG(new Drink(new int[] {1989, 1935}, new HealingEffect(7))), + JUG_OF_BAD_WINE(new Drink(new int[] {1991,1935}, new SkillEffect(Skills.ATTACK, -3, 0))), + + /** Tea */ + CUP_OF_TEA(new Drink(new int[] {712, 1980}, new MultiEffect(new HealingEffect(3), new SkillEffect(Skills.ATTACK, 3, 0)), "Aaah, nothing like a nice cuppa tea!")), + CUP_OF_TEA_NETTLE(new Drink(new int[] {4242, 1980}, new EnergyEffect(10))), + CUP_OF_TEA_MILKY_NETTLE(new Drink(new int[] {4243, 1980}, new EnergyEffect(10))), + NETTLE_TEA(new Drink(new int[] {4239, 1923}, new NettleTeaEffect())), + NETTLE_TEA_MILKY(new Drink(new int[] {4240, 1980}, new NettleTeaEffect())), + CUP_OF_TEA_CLAY(new Drink(new int[] {7730, 7728}, new SkillEffect(Skills.CONSTRUCTION, 1, 0), "You feel refreshed and ready for more building.")), + CUP_OF_TEA_CLAY_MILKY(new Drink(new int[] {7731, 7728}, new SkillEffect(Skills.CONSTRUCTION, 1, 0))), + CUP_OF_TEA_WHITE(new Drink(new int[] {7733, 7732}, new SkillEffect(Skills.CONSTRUCTION, 2, 0), "You feel refreshed and ready for more building.")), + CUP_OF_TEA_WHITE_MILKY(new Drink(new int[] {7734, 7732}, new SkillEffect(Skills.CONSTRUCTION, 2, 0))), + CUP_OF_TEA_GOLD(new Drink(new int[] {7736, 7735}, new SkillEffect(Skills.CONSTRUCTION, 3, 0), "You feel refreshed and ready for more building.")), + CUP_OF_TEA_GOLD_MILKY(new Drink(new int[] {7737, 7735}, new SkillEffect(Skills.CONSTRUCTION, 3, 0))), + + /** Miscellaneous */ + CHOCOLATE_BAR(new Food(new int[] {1973}, new HealingEffect(3))), + PURPLE_SWEETS(new Food(new int[] {4561}, new HealingEffect(0))), + PURPLE_SWEETS_STACKABLE(new Food(new int[] {10476}, new MultiEffect(new EnergyEffect(10), new RandomHealthEffect(1, 3)), "The sugary goodness heals some energy.", "The sugary goodness is yummy.")), + FIELD_RATION(new Food(new int[] {7934}, new HealingEffect(10))), + ROLL(new Food(new int[] {6963}, new HealingEffect(6))), + TCHIKI_MONKEY_NUTS(new Food(new int[] {7573}, new HealingEffect(5), "You eat the Tchiki monkey nuts. They taste nutty.")), + TCHIKI_MONKEY_PASTE(new Food(new int[] {7575}, new HealingEffect(5), "You eat the Tchiki monkey nut paste. It sticks to the roof of your mouth.")), + OOMLIE_WRAP(new Food(new int[] {Items.COOKED_OOMLIE_WRAP_2343}, new MultiEffect(new HealingEffect(14), new AchievementEffect(DiaryType.KARAMJA, 2, 2)))), + ROE(new Food(new int[]{11324}, new HealingEffect(3))), + EQUA_LEAVES(new Food(new int[]{2128}, new HealingEffect(1))), + CHOC_ICE(new Food(new int[]{6794}, new HealingEffect(7))), + EDIBLE_SEAWEED(new Food(new int[] {403}, new HealingEffect(4))), + FROG_SPAWN(new Food(new int[] {5004}, new RandomHealthEffect(3, 7), "You eat the frogspawn. Yuck.")), + + /** Special Events */ + PUMPKIN(new Food(new int[] {1959}, new HealingEffect(14))), + EASTER_EGG(new Food(new int[] {1961}, new HealingEffect(14))), + + /** Potions */ + STRENGTH(new Potion(new int[] {113, 115, 117, 119}, new SkillEffect(Skills.STRENGTH, 3, 0.1))), + ATTACK(new Potion(new int[] {2428, 121, 123, 125}, new SkillEffect(Skills.ATTACK, 3, 0.1))), + DEFENCE(new Potion(new int[] {2432, 133, 135, 137}, new SkillEffect(Skills.DEFENCE, 3, 0.1))), + RANGING(new Potion(new int[] {2444, 169, 171, 173}, new SkillEffect(Skills.RANGE, 4, 0.1))), + MAGIC(new Potion(new int[] {3040, 3042, 3044, 3046}, new SkillEffect(Skills.MAGIC, 4, 0))), + SUPER_STRENGTH(new Potion(new int[] {2440, 157, 159, 161}, new SkillEffect(Skills.STRENGTH, 5, 0.15))), + SUPER_ATTACK(new Potion(new int[] {2436, 145, 147, 149}, new SkillEffect(Skills.ATTACK, 5, 0.15))), + SUPER_DEFENCE(new Potion(new int[] {2442, 163, 165, 167}, new SkillEffect(Skills.DEFENCE, 5, 0.15))), + ANTIPOISON(new Potion(new int[] {2446, 175, 177, 179}, new AddTimerEffect("poison:immunity", secondsToTicks(90)))), + ANTIPOISON_(new Potion(new int[] {5943, 5945, 5947, 5949}, new AddTimerEffect("poison:immunity", minutesToTicks(9)))), + ANTIPOISON__(new Potion(new int[] {5952, 5954, 5956, 5958}, new AddTimerEffect("poison:immunity", minutesToTicks(12)))), + SUPER_ANTIP(new Potion(new int[] {2448, 181, 183, 185}, new AddTimerEffect("poison:immunity", minutesToTicks(6)))), + RELICYM(new Potion(new int[] {4842, 4844, 4846, 4848}, new CureDiseaseEffect())), + AGILITY(new Potion(new int[] {3032, 3034, 3036, 3038}, new SkillEffect(Skills.AGILITY, 3, 0))), + HUNTER(new Potion(new int[] {9998, 10000, 10002, 10004}, new SkillEffect(Skills.HUNTER, 3, 0))), + RESTORE(new Potion(new int[] {2430, 127, 129, 131}, new RestoreEffect(10, 0.3))), + SARA_BREW(new Potion(new int[] {6685, 6687, 6689, 6691}, new MultiEffect(new PercentHeal(0, .15), new SkillEffect(Skills.ATTACK, 0, -0.10), new SkillEffect(Skills.STRENGTH, 0, -0.10), new SkillEffect(Skills.MAGIC, 0, -0.10), new SkillEffect(Skills.RANGE, 0, -0.10), new SkillEffect(Skills.DEFENCE, 0, 0.25)))), + SUMMONING(new Potion(new int[] {12140, 12142, 12144, 12146}, new MultiEffect(new RestoreSummoningSpecial(), new SummoningEffect(7, 0.25)))), + COMBAT(new Potion(new int[] {9739, 9741, 9743, 9745}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 3, .1), new SkillEffect(Skills.ATTACK, 3, .1)))), + ENERGY(new Potion(new int[] {3008, 3010, 3012, 3014}, new EnergyEffect(10))), + FISHING(new Potion(new int[] {2438, 151, 153, 155}, new SkillEffect(Skills.FISHING, 3, 0))), + PRAYER(new Potion(new int[] {2434, 139, 141, 143}, new PrayerEffect(7, 0.25))), + SUPER_RESTO(new Potion(new int[] {3024, 3026, 3028, 3030}, new RestoreEffect(8, 0.25, true))), + ZAMMY_BREW(new Potion(new int[] {2450, 189, 191, 193}, new MultiEffect(new DamageEffect(10, true), new SkillEffect(Skills.ATTACK, 0, 0.25), new SkillEffect(Skills.STRENGTH, 0, 0.15), new SkillEffect(Skills.DEFENCE, 0, -0.1)))), + ANTIFIRE(new Potion(new int[] {2452, 2454, 2456, 2458}, new AddTimerEffect("dragonfire:immunity", 600, true))), + GUTH_REST(new Potion(new int[] {4417, 4419, 4421, 4423}, new MultiEffect(new RemoveTimerEffect("poison"), new EnergyEffect(5), new HealingEffect(5)))), + MAGIC_ESS(new Potion(new int[] {11491, 11489}, new SkillEffect(Skills.MAGIC,3,0))), + SANFEW(new Potion(new int[] {10925, 10927, 10929, 10931}, new MultiEffect(new RestoreEffect(8,0.25, true), new AddTimerEffect("poison:immunity", secondsToTicks(90)), new RemoveTimerEffect("disease")))), + SUPER_ENERGY(new Potion(new int[] {3016, 3018, 3020, 3022}, new EnergyEffect(20))), + BLAMISH_OIL(new FakeConsumable(1582, new String[] {"You know... I'd really rather not."})), + + /** Barbarian Mixes */ + PRAYERMIX(new BarbarianMix(new int[] {11465, 11467}, new MultiEffect(new PrayerEffect(7, 0.25), new HealingEffect(6)))), + ZAMMY_MIX(new BarbarianMix(new int[] {11521, 11523}, new MultiEffect(new DamageEffect(10, true), new SkillEffect(Skills.ATTACK, 0, 0.15), new SkillEffect(Skills.STRENGTH, 0, 0.25), new SkillEffect(Skills.DEFENCE, 0, -0.1)))), + ATT_MIX(new BarbarianMix(new int[] {11429, 11431}, new MultiEffect(new SkillEffect(Skills.ATTACK, 3, 0.1), new HealingEffect(3)))), + ANTIP_MIX(new BarbarianMix(new int[] {11433, 11435}, new MultiEffect(new AddTimerEffect("poison:immunity", secondsToTicks(90)), new HealingEffect(3)))), + RELIC_MIX(new BarbarianMix(new int[] {11437, 11439}, new MultiEffect(new CureDiseaseEffect(), new HealingEffect(3)))), + STR_MIX(new BarbarianMix(new int[] {11443, 11441}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 3, 0.1), new HealingEffect(3)))), + RESTO_MIX(new BarbarianMix(new int[] {11449, 11451}, new MultiEffect(new RestoreEffect(10, 0.3), new HealingEffect(3)))), + SUPER_RESTO_MIX(new BarbarianMix(new int [] {11493, 11495}, new MultiEffect(new RestoreEffect(8,0.25), new PrayerEffect(8, 0.25), new SummoningEffect(8, 0.25), new HealingEffect(6)))), + ENERGY_MIX(new BarbarianMix(new int[] {11453, 11455}, new MultiEffect(new EnergyEffect(10), new HealingEffect(3)))), + DEF_MIX(new BarbarianMix(new int[] {11457, 11459}, new MultiEffect(new SkillEffect(Skills.DEFENCE, 3, 0.1), new HealingEffect(6)))), + AGIL_MIX(new BarbarianMix(new int[] {11461, 11463}, new MultiEffect(new SkillEffect(Skills.AGILITY, 3, 0), new HealingEffect(6)))), + COMBAT_MIX(new BarbarianMix(new int[] {11445, 11447}, new MultiEffect(new SkillEffect(Skills.ATTACK, 3, 0.1), new SkillEffect(Skills.STRENGTH, 3, 0.1), new HealingEffect(6)))), + SUPER_ATT_MIX(new BarbarianMix(new int[] {11469, 11471}, new MultiEffect(new SkillEffect(Skills.ATTACK, 5, 0.15), new HealingEffect(6)))), + FISH_MIX(new BarbarianMix(new int[] {11477, 11479}, new MultiEffect(new SkillEffect(Skills.FISHING, 3, 0), new HealingEffect(6)))), + SUPER_ENERGY_MIX(new BarbarianMix(new int[] {11481, 11483}, new MultiEffect(new EnergyEffect(20), new HealingEffect(6)))), + HUNTING_MIX(new BarbarianMix(new int[] {11517, 11519}, new MultiEffect(new SkillEffect(Skills.HUNTER, 3, 0), new HealingEffect(6)))), + SUPER_STR_MIX(new BarbarianMix(new int[] {11485, 11487}, new MultiEffect(new SkillEffect(Skills.STRENGTH, 5, 0.15), new HealingEffect(6)))), + ANTIDOTE_PLUS_MIX(new BarbarianMix(new int[] {11501, 11503}, new MultiEffect(new AddTimerEffect("poison:immunity", minutesToTicks(9)), new RandomHealthEffect(3, 7)))), + ANTIP_SUPERMIX(new BarbarianMix(new int[] {11473, 11475}, new MultiEffect(new AddTimerEffect("poison:immunity", minutesToTicks(6)), new RandomHealthEffect(3, 7)))), + ANTIFIRE_MIX(new BarbarianMix(new int[] {11505, 11507}, new MultiEffect(new AddTimerEffect("dragonfire:immunity", 600, true), new RandomHealthEffect(3, 7)))), + + /** Stealing creation potions */ + SC_PRAYER(new Potion(new int[] {14207, 14209, 14211, 14213, 14215}, new PrayerEffect(7, 0.25))), + SC_ENERGY(new Potion(new int[] {14217, 14219, 14221, 14223, 14225}, new EnergyEffect(20))), + SC_ATTACK(new Potion(new int[] {14227, 14229, 14231, 14233, 14235}, new SkillEffect(Skills.ATTACK, 3, 0.2))), + SC_STRENGTH(new Potion(new int[] {14237, 14239, 14241, 14243, 14245}, new SkillEffect(Skills.STRENGTH, 3, 0.2))), + SC_RANGE(new Potion(new int[] {14247, 14249, 14251, 14253, 14255}, new SkillEffect(Skills.RANGE, 3, 0.1))), + SC_DEFENCE(new Potion(new int[] {14257, 14259, 14261, 14263, 14265}, new SkillEffect(Skills.DEFENCE, 3, 0.1))), + SC_MAGIC(new Potion(new int[] {14267, 14269, 14271, 14273, 14275}, new SkillEffect(Skills.MAGIC, 3, 0.1))), + SC_SUMMONING(new Potion(new int[] {14277, 14279, 14281, 14283, 14285}, new SummoningEffect(7, 0.25))); + + public static HashMap consumables = new HashMap<>(); + + public static ArrayList potions = new ArrayList<>(); + + private final Consumable consumable; + public boolean isIgnoreMainClock = false; + + Consumables(Consumable consumable) { + this.consumable = consumable; + } + Consumables(Consumable consumable, boolean isIgnoreMainClock) {this.consumable = consumable; this.isIgnoreMainClock = isIgnoreMainClock;} + + public Consumable getConsumable() { + return consumable; + } + + public static Consumables getConsumableById(final int itemId) { + return consumables.get(itemId); + } + + public static void add(final Consumables consumable) { + for (int id : consumable.consumable.getIds()) { + consumables.putIfAbsent(id, consumable); + } + } + + /* + Static modifier used to populate search engine lists. + */ + static { + for (Consumables consumable : Consumables.values()) { + add(consumable); + if (consumable.consumable instanceof Potion) { + for (int pot : consumable.consumable.getIds()) { + potions.add(pot); + } + } + } + } +} diff --git a/Server/src/main/content/data/consumables/effects/AchievementEffect.java b/Server/src/main/content/data/consumables/effects/AchievementEffect.java new file mode 100644 index 0000000..402e0b5 --- /dev/null +++ b/Server/src/main/content/data/consumables/effects/AchievementEffect.java @@ -0,0 +1,21 @@ +package content.data.consumables.effects; + +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.consumable.ConsumableEffect; + +public class AchievementEffect extends ConsumableEffect { + private final DiaryType diary; + private final int level; + private final int task; + public AchievementEffect(DiaryType diary, int level, int task) { + this.diary = diary; + this.level = level; + this.task = task; + } + + @Override + public void activate(Player p) { + p.getAchievementDiaryManager().finishTask(p, diary, level, task); + } +} diff --git a/Server/src/main/content/data/consumables/effects/AddTimerEffect.kt b/Server/src/main/content/data/consumables/effects/AddTimerEffect.kt new file mode 100644 index 0000000..d219851 --- /dev/null +++ b/Server/src/main/content/data/consumables/effects/AddTimerEffect.kt @@ -0,0 +1,15 @@ +package content.data.consumables.effects + +import core.api.registerTimer +import core.api.removeTimer +import core.api.spawnTimer +import core.game.consumable.ConsumableEffect +import core.game.node.entity.player.Player + +class AddTimerEffect (val identifier: String, vararg val args: Any) : ConsumableEffect() { + override fun activate (p: Player) { + removeTimer (p, identifier) + val timer = spawnTimer (identifier, *args) ?: return + registerTimer (p, timer) + } +} diff --git a/Server/src/main/content/data/consumables/effects/CureDiseaseEffect.kt b/Server/src/main/content/data/consumables/effects/CureDiseaseEffect.kt new file mode 100644 index 0000000..4c63c6e --- /dev/null +++ b/Server/src/main/content/data/consumables/effects/CureDiseaseEffect.kt @@ -0,0 +1,21 @@ +package content.data.consumables.effects + +import core.api.* +import core.game.consumable.ConsumableEffect +import core.game.node.entity.player.Player +import core.game.system.timer.impl.Disease + +class CureDiseaseEffect () : ConsumableEffect() { + override fun activate (p: Player) { + val existingTimer = getTimer(p) + if (existingTimer != null) { + existingTimer.hitsLeft -= 9 + if (existingTimer.hitsLeft <= 0) { + sendMessage(p, "The disease has been cured.") + removeTimer(p) + }else{ + sendMessage(p,"You feel slightly better.") + } + } + } +} diff --git a/Server/src/main/content/data/consumables/effects/DamageEffect.java b/Server/src/main/content/data/consumables/effects/DamageEffect.java new file mode 100644 index 0000000..c457330 --- /dev/null +++ b/Server/src/main/content/data/consumables/effects/DamageEffect.java @@ -0,0 +1,30 @@ +package content.data.consumables.effects; + +import core.game.consumable.ConsumableEffect; +import core.game.node.entity.combat.ImpactHandler; +import core.game.node.entity.player.Player; + +public class DamageEffect extends ConsumableEffect { + final double amt; + final boolean isPercent; + + public DamageEffect(double amt,boolean isPercent){ + this.amt = amt; + this.isPercent = isPercent; + } + + @Override + public void activate(Player p) { + p.getImpactHandler().manualHit(p,-getHealthEffectValue(p), ImpactHandler.HitsplatType.NORMAL); + } + + @Override + public int getHealthEffectValue(Player player) { + double amount = amt; + if (isPercent) { + amount /= 100; + return (int) -(amount * player.getSkills().getLifepoints()); + } + return (int) -amt; + } +} diff --git a/Server/src/main/content/data/consumables/effects/DraynorCabbageEffect.java b/Server/src/main/content/data/consumables/effects/DraynorCabbageEffect.java new file mode 100644 index 0000000..a58794c --- /dev/null +++ b/Server/src/main/content/data/consumables/effects/DraynorCabbageEffect.java @@ -0,0 +1,19 @@ +package content.data.consumables.effects; + +import core.game.node.entity.player.Player; +import core.game.consumable.ConsumableEffect; +import core.game.node.entity.skill.Skills; + +public class DraynorCabbageEffect extends ConsumableEffect { + + @Override + public void activate(Player p) { + final HealingEffect effect = new HealingEffect(getHealthEffectValue(p)); + effect.activate(p); + } + + @Override + public int getHealthEffectValue(Player player) { + return player.getSkills().getLevel(Skills.DEFENCE) > 50 ? 3 : 4; + } +} diff --git a/Server/src/main/content/data/consumables/effects/DwarvenRockCakeEffect.java b/Server/src/main/content/data/consumables/effects/DwarvenRockCakeEffect.java new file mode 100644 index 0000000..90febe9 --- /dev/null +++ b/Server/src/main/content/data/consumables/effects/DwarvenRockCakeEffect.java @@ -0,0 +1,21 @@ +package content.data.consumables.effects; + +import core.game.consumable.ConsumableEffect; +import core.game.node.entity.player.Player; + +public class DwarvenRockCakeEffect extends ConsumableEffect { + + private static final DamageEffect effect = new DamageEffect(1, false); + + @Override + public void activate(Player p) { + if (p.getSkills().getLifepoints() > 2) { + effect.activate(p); + } + } + + @Override + public int getHealthEffectValue(Player player) { + return player.getSkills().getLifepoints() > 2 ? -1 : 0; + } +} diff --git a/Server/src/main/content/data/consumables/effects/EnergyEffect.java b/Server/src/main/content/data/consumables/effects/EnergyEffect.java new file mode 100644 index 0000000..75e23b4 --- /dev/null +++ b/Server/src/main/content/data/consumables/effects/EnergyEffect.java @@ -0,0 +1,15 @@ +package content.data.consumables.effects; + +import core.game.consumable.ConsumableEffect; +import core.game.node.entity.player.Player; + +public class EnergyEffect extends ConsumableEffect { + double amt; + public EnergyEffect(int amt){ + this.amt = amt; + } + @Override + public void activate(Player p) { + p.getSettings().updateRunEnergy(-amt); + } +} diff --git a/Server/src/main/content/data/consumables/effects/HealingEffect.java b/Server/src/main/content/data/consumables/effects/HealingEffect.java new file mode 100644 index 0000000..96512e6 --- /dev/null +++ b/Server/src/main/content/data/consumables/effects/HealingEffect.java @@ -0,0 +1,20 @@ +package content.data.consumables.effects; + +import core.game.node.entity.player.Player; +import core.game.consumable.ConsumableEffect; + +public class HealingEffect extends ConsumableEffect { + int amt; + public HealingEffect(int amount){ + this.amt = amount; + } + @Override + public void activate(Player p) { + p.getSkills().heal(amt); + } + + @Override + public int getHealthEffectValue(Player player) { + return amt; + } +} diff --git a/Server/src/main/content/data/consumables/effects/KebabEffect.java b/Server/src/main/content/data/consumables/effects/KebabEffect.java new file mode 100644 index 0000000..6b4f5c3 --- /dev/null +++ b/Server/src/main/content/data/consumables/effects/KebabEffect.java @@ -0,0 +1,62 @@ +package content.data.consumables.effects; + +import core.game.consumable.ConsumableEffect; +import core.game.node.entity.player.Player; +import core.tools.RandomFunction; +import core.game.node.entity.skill.Skills; + +/** + * According to the OSRS wiki, a kebab has the following possible outcomes: + * 66% chance to heal 10% of total Hitpoints level, rounded down. Accompanied with the message "It heals some health." + * 21% chance to heal 10–20 Hitpoints. Accompanied with the message "That was a good kebab. You feel a lot better." + * 9% chance to heal nothing. Accompanied with the message "That kebab didn't seem to do a lot." + * In addition, there is a chance that a non-combat skill is lowered by 3 (with the message "That tasted a bit dodgy. You feel a bit ill."), or that melee skills are lowered by 3 (with the message "That tasted very dodgy. You feel very ill."). + * 4% chance to heal 30 Hitpoints and gain 1–3 levels in Attack, Strength and Defence. Accompanied with the message "Wow, that was an amazing kebab! You feel really invigorated." + */ +public class KebabEffect extends ConsumableEffect { + + @Override + public void activate(Player p) { + final int randomNumber = RandomFunction.nextInt(100); + ConsumableEffect effect; + String message; + if (randomNumber < 66) { + effect = new PercentageHealthEffect(10); + final int initialLifePoints = p.getSkills().getLifepoints(); + effect.activate(p); + if (p.getSkills().getLifepoints() > initialLifePoints) { + message = "It heals some health."; + p.getPacketDispatch().sendMessage(message); + } + } else if (randomNumber < 87) { + effect = new RandomHealthEffect(10, 20); + effect.activate(p); + message = "That was a good kebab. You feel a lot better."; + p.getPacketDispatch().sendMessage(message); + } else if (randomNumber < 96) { + if (RandomFunction.nextInt(100) < 50) { // As the probability of lowering by 3 a non-combat skill or all melee skills is not specified, 50% is the percentage that was chosen. + final int affectedSkillSlot = RandomFunction.nextInt(Skills.NUM_SKILLS - 1); + switch (affectedSkillSlot) { + case Skills.ATTACK: + case Skills.DEFENCE: + case Skills.STRENGTH: + effect = new MultiEffect(new SkillEffect(Skills.ATTACK, -3, 0), new SkillEffect(Skills.DEFENCE, -3, 0), new SkillEffect(Skills.STRENGTH, -3, 0)); + break; + default: + effect = new SkillEffect(affectedSkillSlot, -3, 0); + } + message = "That tasted a bit dodgy. You feel a bit ill."; + p.getPacketDispatch().sendMessage(message); + effect.activate(p); + } else { + message = "That kebab didn't seem to do a lot."; + p.getPacketDispatch().sendMessage(message); + } + } else { + effect = new MultiEffect(new HealingEffect(30), new RandomSkillEffect(Skills.ATTACK, 1, 3), new RandomSkillEffect(Skills.DEFENCE, 1, 3), new RandomSkillEffect(Skills.STRENGTH, 1, 3)); + effect.activate(p); + message = "Wow, that was an amazing kebab! You feel really invigorated."; + p.getPacketDispatch().sendMessage(message); + } + } +} diff --git a/Server/src/main/content/data/consumables/effects/KegOfBeerEffect.kt b/Server/src/main/content/data/consumables/effects/KegOfBeerEffect.kt new file mode 100644 index 0000000..89232ab --- /dev/null +++ b/Server/src/main/content/data/consumables/effects/KegOfBeerEffect.kt @@ -0,0 +1,15 @@ +package content.data.consumables.effects + +import core.game.consumable.ConsumableEffect +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills + + +class KegOfBeerEffect : ConsumableEffect() { + + override fun activate(p: Player?) { + val effect = MultiEffect(HealingEffect(15), SkillEffect(Skills.STRENGTH, 10.0, 0.0), SkillEffect(Skills.ATTACK, -40.0, 0.0)) + effect.activate(p) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/data/consumables/effects/MatureWmbEffect.java b/Server/src/main/content/data/consumables/effects/MatureWmbEffect.java new file mode 100644 index 0000000..d2c5a98 --- /dev/null +++ b/Server/src/main/content/data/consumables/effects/MatureWmbEffect.java @@ -0,0 +1,22 @@ +package content.data.consumables.effects; + +import core.game.consumable.ConsumableEffect; +import core.game.node.entity.player.Player; +import core.game.node.entity.skill.Skills; + +public class MatureWmbEffect extends ConsumableEffect { + + private final static int healing = 1; + + @Override + public void activate(Player p) { + final int magicLevelBoost = p.getSkills().getLevel(Skills.MAGIC) > 50 ? 4 : 3; + final MultiEffect effect = new MultiEffect(new SkillEffect(Skills.MAGIC, magicLevelBoost, 0), new HealingEffect(healing), new SkillEffect(Skills.ATTACK, -5, 0), new SkillEffect(Skills.STRENGTH, -5, 0), new SkillEffect(Skills.DEFENCE, -5, 0)); + effect.activate(p); + } + + @Override + public int getHealthEffectValue(Player player) { + return healing; + } +} diff --git a/Server/src/main/content/data/consumables/effects/MultiEffect.java b/Server/src/main/content/data/consumables/effects/MultiEffect.java new file mode 100644 index 0000000..228c7fa --- /dev/null +++ b/Server/src/main/content/data/consumables/effects/MultiEffect.java @@ -0,0 +1,26 @@ +package content.data.consumables.effects; + +import core.game.consumable.ConsumableEffect; +import core.game.node.entity.player.Player; + +public class MultiEffect extends ConsumableEffect { + private ConsumableEffect[] effects; + public MultiEffect(ConsumableEffect... effects){ + this.effects = effects; + } + @Override + public void activate(Player p) { + for(ConsumableEffect e : effects){ + e.activate(p); + } + } + + @Override + public int getHealthEffectValue(Player player) { + int healing = 0; + for (ConsumableEffect effect : effects) { + healing += effect.getHealthEffectValue(player); + } + return healing; + } +} diff --git a/Server/src/main/content/data/consumables/effects/NettleTeaEffect.java b/Server/src/main/content/data/consumables/effects/NettleTeaEffect.java new file mode 100644 index 0000000..8f20e8c --- /dev/null +++ b/Server/src/main/content/data/consumables/effects/NettleTeaEffect.java @@ -0,0 +1,20 @@ +package content.data.consumables.effects; + +import core.game.consumable.ConsumableEffect; +import core.game.node.entity.player.Player; + +public class NettleTeaEffect extends ConsumableEffect { + + private final static int healing = 3; + + @Override + public void activate(Player p) { + final ConsumableEffect effect = p.getSkills().getLifepoints() < p.getSkills().getMaximumLifepoints() ? new MultiEffect(new HealingEffect(3), new EnergyEffect(5)) : new HealingEffect(3); + effect.activate(p); + } + + @Override + public int getHealthEffectValue(Player player) { + return healing; + } +} diff --git a/Server/src/main/content/data/consumables/effects/PercentHeal.java b/Server/src/main/content/data/consumables/effects/PercentHeal.java new file mode 100644 index 0000000..d1d3614 --- /dev/null +++ b/Server/src/main/content/data/consumables/effects/PercentHeal.java @@ -0,0 +1,23 @@ +package content.data.consumables.effects; + +import core.game.consumable.ConsumableEffect; +import core.game.node.entity.player.Player; + +public class PercentHeal extends ConsumableEffect { + int base = 0; + double percent = 0.0; + + public PercentHeal(int base, double percent){ + this.base = base; + this.percent = percent; + } + + @Override + public void activate(Player p) { + int maxHp = p.getSkills().getMaximumLifepoints(); + int curHp = p.getSkills().getLifepoints(); + int amount = (int) Math.floor(maxHp * percent); + amount = base + Math.min(amount, (int)((1.0 + percent) * (double)maxHp - (double)curHp)); + p.getSkills().healNoRestrictions(amount); + } +} diff --git a/Server/src/main/content/data/consumables/effects/PercentageHealthEffect.java b/Server/src/main/content/data/consumables/effects/PercentageHealthEffect.java new file mode 100644 index 0000000..cd39cb5 --- /dev/null +++ b/Server/src/main/content/data/consumables/effects/PercentageHealthEffect.java @@ -0,0 +1,24 @@ +package content.data.consumables.effects; + +import core.game.node.entity.player.Player; +import core.game.consumable.ConsumableEffect; + +public class PercentageHealthEffect extends ConsumableEffect { + + private final double percentage; + + public PercentageHealthEffect(final int percentage) { + this.percentage = percentage * 0.01; + } + + @Override + public void activate(Player p) { + final HealingEffect effect = new HealingEffect(getHealthEffectValue(p)); + effect.activate(p); + } + + @Override + public int getHealthEffectValue(Player player) { + return (int) (player.getSkills().getMaximumLifepoints() * percentage); + } +} diff --git a/Server/src/main/content/data/consumables/effects/PoisonEffect.java b/Server/src/main/content/data/consumables/effects/PoisonEffect.java new file mode 100644 index 0000000..82adbeb --- /dev/null +++ b/Server/src/main/content/data/consumables/effects/PoisonEffect.java @@ -0,0 +1,24 @@ +package content.data.consumables.effects; + +import core.game.consumable.ConsumableEffect; +import core.game.node.entity.combat.ImpactHandler; +import core.game.node.entity.player.Player; + +public class PoisonEffect extends ConsumableEffect { + + private final int amount; + + public PoisonEffect(final int amount) { + this.amount = amount; + } + + @Override + public void activate(Player p) { + p.getImpactHandler().manualHit(p, amount, ImpactHandler.HitsplatType.POISON); + } + + @Override + public int getHealthEffectValue(Player player) { + return -amount; + } +} diff --git a/Server/src/main/content/data/consumables/effects/PoisonKarambwanEffect.java b/Server/src/main/content/data/consumables/effects/PoisonKarambwanEffect.java new file mode 100644 index 0000000..ceea780 --- /dev/null +++ b/Server/src/main/content/data/consumables/effects/PoisonKarambwanEffect.java @@ -0,0 +1,21 @@ +package content.data.consumables.effects; + +import core.game.consumable.ConsumableEffect; +import core.game.node.entity.player.Player; + +public class PoisonKarambwanEffect extends ConsumableEffect { + + private final PoisonEffect effect = new PoisonEffect(5); + + @Override + public void activate(Player p) { + if (p.getSkills().getLifepoints() > 5) { + effect.activate(p); + } + } + + @Override + public int getHealthEffectValue(Player player) { + return -5; + } +} diff --git a/Server/src/main/content/data/consumables/effects/PrayerEffect.kt b/Server/src/main/content/data/consumables/effects/PrayerEffect.kt new file mode 100644 index 0000000..9f636bc --- /dev/null +++ b/Server/src/main/content/data/consumables/effects/PrayerEffect.kt @@ -0,0 +1,20 @@ +package content.data.consumables.effects + +import core.api.* +import core.game.consumable.ConsumableEffect +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import org.rs09.consts.Items +import kotlin.math.floor + +class PrayerEffect(var base: Double, var bonus: Double) : ConsumableEffect() { + override fun activate(player: Player?) { + if(player == null) return + val level = getStatLevel(player, Skills.PRAYER) + var b = bonus + if(inInventory(player, Items.HOLY_WRENCH_6714)) + b += 0.02 // Leaving this in for futureproofing. Current update is for properly rounding down. + val amount = floor(base + (level * b)) + modPrayerPoints(player, amount) + } +} \ No newline at end of file diff --git a/Server/src/main/content/data/consumables/effects/RandomEnergyEffect.java b/Server/src/main/content/data/consumables/effects/RandomEnergyEffect.java new file mode 100644 index 0000000..cab047a --- /dev/null +++ b/Server/src/main/content/data/consumables/effects/RandomEnergyEffect.java @@ -0,0 +1,21 @@ +package content.data.consumables.effects; + +import core.game.consumable.ConsumableEffect; +import core.game.node.entity.player.Player; +import core.tools.RandomFunction; + +public class RandomEnergyEffect extends ConsumableEffect { + + private final int a, b; + + public RandomEnergyEffect(final int a, final int b) { + this.a = a; + this.b = b; + } + + @Override + public void activate(Player p) { + final EnergyEffect effect = new EnergyEffect(RandomFunction.random(a, b)); + effect.activate(p); + } +} diff --git a/Server/src/main/content/data/consumables/effects/RandomHealthEffect.java b/Server/src/main/content/data/consumables/effects/RandomHealthEffect.java new file mode 100644 index 0000000..76e4c65 --- /dev/null +++ b/Server/src/main/content/data/consumables/effects/RandomHealthEffect.java @@ -0,0 +1,32 @@ +package content.data.consumables.effects; + +import core.game.consumable.ConsumableEffect; +import core.game.node.entity.player.Player; +import core.tools.RandomFunction; + +public class RandomHealthEffect extends ConsumableEffect { + + private final int a, b; + + public RandomHealthEffect(final int a, final int b) { + this.a = a; + this.b = b; + } + + @Override + public void activate(Player p) { + ConsumableEffect effect; + final int healthEffectValue = getHealthEffectValue(p); + if (healthEffectValue > 0) { + effect = new HealingEffect(healthEffectValue); + } else { + effect = new DamageEffect(healthEffectValue, false); + } + effect.activate(p); + } + + @Override + public int getHealthEffectValue(Player player) { + return RandomFunction.random(a, b); + } +} diff --git a/Server/src/main/content/data/consumables/effects/RandomPrayerEffect.java b/Server/src/main/content/data/consumables/effects/RandomPrayerEffect.java new file mode 100644 index 0000000..0d669a4 --- /dev/null +++ b/Server/src/main/content/data/consumables/effects/RandomPrayerEffect.java @@ -0,0 +1,21 @@ +package content.data.consumables.effects; + +import core.game.node.entity.player.Player; +import core.tools.RandomFunction; +import core.game.consumable.ConsumableEffect; + +public class RandomPrayerEffect extends ConsumableEffect { + + private final int a, b; + + public RandomPrayerEffect(final int a, final int b) { + this.a = a; + this.b = b; + } + + @Override + public void activate(Player p) { + final PrayerEffect effect = new PrayerEffect(RandomFunction.random(a, b), 0); + effect.activate(p); + } +} diff --git a/Server/src/main/content/data/consumables/effects/RandomSkillEffect.java b/Server/src/main/content/data/consumables/effects/RandomSkillEffect.java new file mode 100644 index 0000000..3c7c11c --- /dev/null +++ b/Server/src/main/content/data/consumables/effects/RandomSkillEffect.java @@ -0,0 +1,22 @@ +package content.data.consumables.effects; + +import core.game.consumable.ConsumableEffect; +import core.game.node.entity.player.Player; +import core.tools.RandomFunction; + +public class RandomSkillEffect extends ConsumableEffect { + + private final int skillSlot, a, b; + + public RandomSkillEffect(final int skillSlot, final int a, final int b) { + this.skillSlot = skillSlot; + this.a = a; + this.b = b; + } + + @Override + public void activate(Player p) { + final SkillEffect effect = new SkillEffect(skillSlot, RandomFunction.random(a, b), 0); + effect.activate(p); + } +} diff --git a/Server/src/main/content/data/consumables/effects/RemoveTimerEffect.kt b/Server/src/main/content/data/consumables/effects/RemoveTimerEffect.kt new file mode 100644 index 0000000..6d45c35 --- /dev/null +++ b/Server/src/main/content/data/consumables/effects/RemoveTimerEffect.kt @@ -0,0 +1,11 @@ +package content.data.consumables.effects + +import core.api.* +import core.game.consumable.ConsumableEffect +import core.game.node.entity.player.Player + +class RemoveTimerEffect (val identifier: String) : ConsumableEffect() { + override fun activate (p: Player) { + removeTimer (p, identifier) + } +} diff --git a/Server/src/main/content/data/consumables/effects/RestoreEffect.java b/Server/src/main/content/data/consumables/effects/RestoreEffect.java new file mode 100644 index 0000000..ba9b3ea --- /dev/null +++ b/Server/src/main/content/data/consumables/effects/RestoreEffect.java @@ -0,0 +1,42 @@ +package content.data.consumables.effects; + +import core.game.node.entity.player.Player; +import core.game.consumable.ConsumableEffect; +import core.game.node.entity.skill.Skills; + +public class RestoreEffect extends ConsumableEffect { + double base,bonus; + boolean all_skills; // Except for hitpoints + public RestoreEffect(double base, double bonus){ + this.base = base; + this.bonus = bonus; + this.all_skills = false; + } + + public RestoreEffect(double base, double bonus, boolean all_skills){ + this.base = base; + this.bonus = bonus; + this.all_skills = all_skills; + } + final int[] SKILLS = new int[] { Skills.DEFENCE, Skills.ATTACK, Skills.STRENGTH, Skills.MAGIC, Skills.RANGE }; + final int[] ALL_SKILLS = new int[]{ + Skills.ATTACK,Skills.DEFENCE, Skills.STRENGTH,Skills.RANGE,Skills.PRAYER,Skills.MAGIC, Skills.COOKING, + Skills.WOODCUTTING,Skills.FLETCHING,Skills.FISHING,Skills.FIREMAKING,Skills.CRAFTING,Skills.SMITHING, + Skills.MINING,Skills.HERBLORE,Skills.AGILITY,Skills.THIEVING,Skills.SLAYER,Skills.FARMING, + Skills.RUNECRAFTING,Skills.HUNTER,Skills.CONSTRUCTION,Skills.SUMMONING }; + @Override + public void activate(Player p) { + Skills sk = p.getSkills(); + int[] skills = this.all_skills ? ALL_SKILLS : SKILLS; + for(int skill : skills){ + int statL = sk.getStaticLevel(skill); + int boost = (int) (base + (statL * bonus)); + int curL = sk.getLevel(skill); + if(curL < statL){ + p.getSkills().updateLevel(skill, boost, statL); + } + if (skill == Skills.PRAYER) + p.getSkills().incrementPrayerPoints(boost); + } + } +} diff --git a/Server/src/main/content/data/consumables/effects/RestoreSummoningSpecial.kt b/Server/src/main/content/data/consumables/effects/RestoreSummoningSpecial.kt new file mode 100644 index 0000000..51b727d --- /dev/null +++ b/Server/src/main/content/data/consumables/effects/RestoreSummoningSpecial.kt @@ -0,0 +1,11 @@ +package content.data.consumables.effects + +import core.game.consumable.ConsumableEffect +import core.game.node.entity.player.Player + +class RestoreSummoningSpecial : ConsumableEffect(){ + override fun activate(p: Player) { + val f = p.familiarManager.familiar + f?.updateSpecialPoints(-15) + } +} \ No newline at end of file diff --git a/Server/src/main/content/data/consumables/effects/RockCakeEffect.java b/Server/src/main/content/data/consumables/effects/RockCakeEffect.java new file mode 100644 index 0000000..eb2ed36 --- /dev/null +++ b/Server/src/main/content/data/consumables/effects/RockCakeEffect.java @@ -0,0 +1,21 @@ +package content.data.consumables.effects; + +import core.game.consumable.ConsumableEffect; +import core.game.node.entity.player.Player; + +public class RockCakeEffect extends ConsumableEffect { + + private static final DamageEffect effect = new DamageEffect(10, true); + + @Override + public void activate(Player p) { + if (p.getSkills().getLifepoints() > 1) { + effect.activate(p); + } + } + + @Override + public int getHealthEffectValue(Player player) { + return (int) (player.getSkills().getLifepoints() * -0.1); + } +} diff --git a/Server/src/main/content/data/consumables/effects/SetAttributeEffect.java b/Server/src/main/content/data/consumables/effects/SetAttributeEffect.java new file mode 100644 index 0000000..b002961 --- /dev/null +++ b/Server/src/main/content/data/consumables/effects/SetAttributeEffect.java @@ -0,0 +1,37 @@ +package content.data.consumables.effects; + +import core.game.consumable.ConsumableEffect; +import core.game.node.entity.player.Player; +import core.game.world.GameWorld; + +public class SetAttributeEffect extends ConsumableEffect { + String attrString; + Object attrValue; + boolean isTicks; + + public SetAttributeEffect(String attr, Object value, boolean isTicks){ + this.attrString = attr; + this.attrValue = value; + this.isTicks = isTicks; + } + + public SetAttributeEffect(String attr, Object value){ + this.attrString = attr; + this.attrValue = value; + if (value instanceof Integer){ + this.isTicks = true; + } else { + this.isTicks = false; + } + } + + @Override + public void activate(Player p) { + if(isTicks){ + int val = (Integer) attrValue + GameWorld.getTicks(); + p.setAttribute(attrString,val); + return; + } + p.setAttribute(attrString,attrValue); + } +} diff --git a/Server/src/main/content/data/consumables/effects/SkillEffect.java b/Server/src/main/content/data/consumables/effects/SkillEffect.java new file mode 100644 index 0000000..56c6b59 --- /dev/null +++ b/Server/src/main/content/data/consumables/effects/SkillEffect.java @@ -0,0 +1,23 @@ +package content.data.consumables.effects; + +import core.game.consumable.ConsumableEffect; +import core.game.node.entity.player.Player; +import core.game.node.entity.skill.Skills; + +public class SkillEffect extends ConsumableEffect { + private final int skill_slot; + private final double base; + private final double bonus; + public SkillEffect(int skill_slot, double base, double bonus){ + this.skill_slot = skill_slot; + this.base = base; + this.bonus = bonus; + } + @Override + public void activate(Player p) { + Skills skills = p.getSkills(); + int slevel = skills.getStaticLevel(skill_slot); + int delta = (int)(base + (bonus * slevel)); + skills.updateLevel(skill_slot, delta, delta >= 0 ? slevel + delta : 0); + } +} diff --git a/Server/src/main/content/data/consumables/effects/SmellingUgthankiKebabEffect.java b/Server/src/main/content/data/consumables/effects/SmellingUgthankiKebabEffect.java new file mode 100644 index 0000000..ab0f073 --- /dev/null +++ b/Server/src/main/content/data/consumables/effects/SmellingUgthankiKebabEffect.java @@ -0,0 +1,30 @@ +package content.data.consumables.effects; + +import core.game.consumable.ConsumableEffect; +import core.game.node.entity.player.Player; +import core.tools.RandomFunction; + +/** + * According to the OSRS wiki, the smelling ugthanki kebab will usually heal nothing when eaten, but sometimes heals for 9. + * As the chances of healing are unknown, the percentage is set to 10%. + */ +public class SmellingUgthankiKebabEffect extends ConsumableEffect { + + private static final int percentage = 10; + + private static final int healing = 9; + + private static final HealingEffect effect = new HealingEffect(healing); + + @Override + public void activate(Player p) { + if (RandomFunction.nextInt(100) < percentage) { + effect.activate(p); + } + } + + @Override + public int getHealthEffectValue(Player player) { + return RandomFunction.nextInt(100) < percentage ? healing : 0; + } +} diff --git a/Server/src/main/content/data/consumables/effects/SummoningEffect.java b/Server/src/main/content/data/consumables/effects/SummoningEffect.java new file mode 100644 index 0000000..be7d0b0 --- /dev/null +++ b/Server/src/main/content/data/consumables/effects/SummoningEffect.java @@ -0,0 +1,19 @@ +package content.data.consumables.effects; + +import core.game.consumable.ConsumableEffect; +import core.game.node.entity.player.Player; +import core.game.node.entity.skill.Skills; + +public class SummoningEffect extends ConsumableEffect { + double base, bonus; + public SummoningEffect(double base, double bonus){ + this.base = base; + this.bonus = bonus; + } + @Override + public void activate(Player p) { + int level = p.getSkills().getStaticLevel(Skills.SUMMONING); + double amt = base + (level * bonus); + p.getSkills().updateLevel(Skills.SUMMONING, (int)amt, level); + } +} diff --git a/Server/src/main/content/data/consumables/effects/SuperKebabEffect.java b/Server/src/main/content/data/consumables/effects/SuperKebabEffect.java new file mode 100644 index 0000000..79f8005 --- /dev/null +++ b/Server/src/main/content/data/consumables/effects/SuperKebabEffect.java @@ -0,0 +1,28 @@ +package content.data.consumables.effects; + +import core.game.consumable.ConsumableEffect; +import core.game.node.entity.player.Player; +import core.tools.RandomFunction; +import core.game.node.entity.skill.Skills; + + +public class SuperKebabEffect extends ConsumableEffect { + + private static final MultiEffect healingEffect = new MultiEffect(new HealingEffect(3), new PercentageHealthEffect(7)); + + @Override + public void activate(Player p) { + if (RandomFunction.nextInt(8) < 5) { + healingEffect.activate(p); + } + if (RandomFunction.nextInt(32) < 1) { + final SkillEffect effect = new SkillEffect(RandomFunction.nextInt(Skills.NUM_SKILLS), -1, 0); + effect.activate(p); + } + } + + @Override + public int getHealthEffectValue(Player player) { + return RandomFunction.nextInt(8) < 5 ? (int) (3 + (player.getSkills().getMaximumLifepoints() * 0.07)) : 0; + } +} diff --git a/Server/src/main/content/data/consumables/effects/TroubleBrewingRumEffect.java b/Server/src/main/content/data/consumables/effects/TroubleBrewingRumEffect.java new file mode 100644 index 0000000..56cd91a --- /dev/null +++ b/Server/src/main/content/data/consumables/effects/TroubleBrewingRumEffect.java @@ -0,0 +1,37 @@ +package content.data.consumables.effects; + +import core.game.consumable.ConsumableEffect; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.map.Location; + +public class TroubleBrewingRumEffect extends ConsumableEffect { + + private static final Location TROUBLE_BREWING_MINIGAME = new Location(3813, 3022); + + private final String forceChatMessage; + + public TroubleBrewingRumEffect(final String forceChatMessage) { + this.forceChatMessage = forceChatMessage; + } + + @Override + public void activate(Player p) { + final Pulse teleportation = new Pulse(6) { + @Override + public boolean pulse() { + p.teleport(TROUBLE_BREWING_MINIGAME); + return true; + } + }; + final Pulse mainPulse = new Pulse(4) { + @Override + public boolean pulse() { + p.sendChat(forceChatMessage); + p.getPulseManager().run(teleportation); + return true; + } + }; + p.getPulseManager().run(mainPulse); + } +} diff --git a/Server/src/main/content/data/consumables/effects/UgthankiKebabEffect.java b/Server/src/main/content/data/consumables/effects/UgthankiKebabEffect.java new file mode 100644 index 0000000..dd8e35d --- /dev/null +++ b/Server/src/main/content/data/consumables/effects/UgthankiKebabEffect.java @@ -0,0 +1,24 @@ +package content.data.consumables.effects; + +import core.game.consumable.ConsumableEffect; +import core.game.node.entity.player.Player; + +public class UgthankiKebabEffect extends ConsumableEffect { + + private static final int healing = 19; + + private static final HealingEffect effect = new HealingEffect(healing); + + @Override + public void activate(Player p) { + if (p.getSkills().getLifepoints() < p.getSkills().getMaximumLifepoints()) { + p.sendChat("Yum!"); + } + effect.activate(p); + } + + @Override + public int getHealthEffectValue(Player player) { + return healing; + } +} diff --git a/Server/src/main/content/data/consumables/effects/WizardsMindBombEffect.java b/Server/src/main/content/data/consumables/effects/WizardsMindBombEffect.java new file mode 100644 index 0000000..52a0e42 --- /dev/null +++ b/Server/src/main/content/data/consumables/effects/WizardsMindBombEffect.java @@ -0,0 +1,22 @@ +package content.data.consumables.effects; + +import core.game.consumable.ConsumableEffect; +import core.game.node.entity.player.Player; +import core.game.node.entity.skill.Skills; + +public class WizardsMindBombEffect extends ConsumableEffect { + + private final static int healing = 1; + + @Override + public void activate(Player p) { + final int magicLevelBoost = p.getSkills().getLevel(Skills.MAGIC) > 50 ? 3 : 2; + final MultiEffect effect = new MultiEffect(new SkillEffect(Skills.MAGIC, magicLevelBoost, 0), new HealingEffect(healing), new SkillEffect(Skills.ATTACK, -3, 0), new SkillEffect(Skills.STRENGTH, -4, 0), new SkillEffect(Skills.DEFENCE, -4, 0)); + effect.activate(p); + } + + @Override + public int getHealthEffectValue(Player player) { + return healing; + } +} diff --git a/Server/src/main/content/data/skill/SkillcapePerks.java b/Server/src/main/content/data/skill/SkillcapePerks.java new file mode 100644 index 0000000..d9109a1 --- /dev/null +++ b/Server/src/main/content/data/skill/SkillcapePerks.java @@ -0,0 +1,59 @@ +package content.data.skill; + +/** + * Handles the skillcape perks. + * @author Empathy + * + */ +public enum SkillcapePerks { + + ATTACK(9747, 9748), + STRENGTH(9750, 9751), + DEFENCE(9753, 9754), + RANGING(9756, 9757), + PRAYER(9759, 9760), + MAGIC(9762, 9763), + RUNECRAFTING(9765, 9766), + HITPOINTS(9768, 9769), + AGILITY(9771, 9772), + HERBLORE(9774, 9775), + THIEVEING(9777, 9778), + CRAFTING(9780, 9781), + FLETCHING(9783, 9784), + SLAYER(9786, 9787), + CONSTRUCTION(9789, 9790), + MINING(9792, 9793), + SMITHING(9795, 9796), + FISHING(9798, 9799), + COOKING(9801, 9802), + FIREMAKING(9804, 9805), + WOODCUTTING(9807, 9808), + FARMING(9810, 9811), + HUNTING(9948, 9949), + SUMMONING(12169,12170), + MAX_CAPE(14831, 14833, 14835, 14839, 14840) + ; + + /** + * The skillcape Ids. + */ + private final int[] skillcapeIds; + + + /** + * + * Constructs a new {@code SkillcapePerks} object. + * @param skillcapeIds + */ + SkillcapePerks(int... skillcapeIds) { + this.skillcapeIds = skillcapeIds; + } + + /** + * The skillcapeIds. + * @return the skillcape ids. + */ + public int[] getSkillcapeIds() { + return skillcapeIds; + } +} diff --git a/Server/src/main/content/data/skill/SkillingPets.java b/Server/src/main/content/data/skill/SkillingPets.java new file mode 100644 index 0000000..4ea03ed --- /dev/null +++ b/Server/src/main/content/data/skill/SkillingPets.java @@ -0,0 +1,103 @@ +package content.data.skill; + +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.repository.Repository; + +/** + * Represents the skilling pets obtained randomly. + * @author Empathy + * + */ +public enum SkillingPets { + + BABY_RED_CHINCHOMPA(new Item(14823), "Baby Chinchompa", Skills.HUNTER), + BABY_GREY_CHINCHOMPA(new Item(14824), "Baby Chinchompa", Skills.HUNTER), + BEAVER(new Item(14821), "Beaver", Skills.WOODCUTTING), + GOLEM(new Item(14822), "Rock Golem", Skills.MINING), + HERON(new Item(14827), "Heron", Skills.FISHING); + + /** + * The pet item drop. + */ + private final Item pet; + + /** + * The name. + */ + private final String name; + + /** + * The skill. + */ + private final int skill; + + /** + * Constructs a new {@code SkillingPets} object. + * @param skill The skill id. + * @param pet The pet item. + */ + SkillingPets(Item pet, String name, int skill) { + this.pet = pet; + this.name = name; + this.skill = skill; + } + + /** + * Checks the pet drop. + * @param player The player. + * @param pet The pet drop to check. + */ + public static void checkPetDrop(Player player, SkillingPets pet) { + if (pet == null) { + return; + } + int defaultChance = 15000; + int newChance = (defaultChance / player.getSkills().getStaticLevel(pet.getSkill()) * 55); + int outOf = (newChance > defaultChance ? defaultChance : newChance); + int getChance = outOf; + if (getChance != 1) { + return; + } + if (player.hasItem(pet.getPet())) { + return; + } + if (player.getFamiliarManager().hasFamiliar() && player.getInventory().isFull()) { + return; + } + if (player.getFamiliarManager().hasFamiliar()) { + if (player.getFamiliarManager().getFamiliar().getName().equalsIgnoreCase(pet.getName())) { + return; + } + player.getInventory().add(pet.getPet()); + player.sendNotificationMessage("You feel something weird sneaking into your backpack."); + } else { + player.getFamiliarManager().summon(pet.getPet(), true); + player.sendNotificationMessage("You have a funny feeling like you're being followed."); + } + Repository.sendNews(player.getUsername() + " has found a " + pet.getPet().getName() + "!"); + } + + + /** + * @return the pet + */ + public Item getPet() { + return pet; + } + + /** + * @return the pet name. + */ + public String getName() { + return name; + } + + /** + * @return the skill. + */ + public int getSkill() { + return skill; + } +} diff --git a/Server/src/main/content/data/skill/SkillingTool.java b/Server/src/main/content/data/skill/SkillingTool.java new file mode 100644 index 0000000..cb0b756 --- /dev/null +++ b/Server/src/main/content/data/skill/SkillingTool.java @@ -0,0 +1,330 @@ +package content.data.skill; + +import core.game.node.entity.player.Player; +import core.game.node.entity.skill.Skills; +import core.game.world.update.flag.context.Animation; +import org.rs09.consts.Items; + +/** + * Represents a skilling tool (such as knife, axe, needle, ...) + * @author Emperor + */ +public enum SkillingTool { + /** + * Represents a bronze axe (woodcutting). + */ + BRONZE_AXE(1351, 1, 0.05D, new Animation(879)), + + /** + * Represents an iron axe (woodcutting). + */ + IRON_AXE(1349, 1, 0.1D, new Animation(877)), + + /** + * Represents a steel axe (woodcutting). + */ + STEEL_AXE(1353, 6, 0.2D, new Animation(875)), + + /** + * Represents a black axe (woodcutting). + */ + BLACK_AXE(1361, 6, 0.25D, new Animation(873)), + + /** + * Represents a mithril axe (woodcutting). + */ + MITHRIL_AXE(1355, 21, 0.30D, new Animation(871)), + + /** + * Represents an adamant axe (woodcutting). + */ + ADAMANT_AXE(1357, 31, 0.45D, new Animation(869)), + + /** + * Represents a rune axe (woodcutting). + */ + RUNE_AXE(1359, 41, 0.65D, new Animation(867)), + + /** + * Represents a dragon axe (woodcutting). + */ + DRAGON_AXE(6739, 61, 0.85D, new Animation(2846)), + + /** + * Represents a bronze pickaxe (mining). + */ + BRONZE_PICKAXE(1265, 1, 0.05D, new Animation(625)), + + /** + * Represents an iron pickaxe (mining). + */ + IRON_PICKAXE(1267, 1, 0.1D, new Animation(626)), + + /** + * Represents a steel pickaxe (mining). + */ + STEEL_PICKAXE(1269, 6, 0.2D, new Animation(627)), + + /** + * Represents a mithril pickaxe (mining). + */ + MITHRIL_PICKAXE(1273, 21, 0.30D, new Animation(629)), + + /** + * Represents an adamant pickaxe (mining). + */ + ADAMANT_PICKAXE(1271, 31, 0.45D, new Animation(628)), + + /** + * Represents a rune pickaxe (mining). + */ + RUNE_PICKAXE(1275, 41, 0.65D, new Animation(624)), + + /** + * Represents the Inferno Adze (woodcutting) + */ + INFERNO_ADZE(13661, 61, 0.85D, new Animation(10251)), + + /** + * Represents the Inferno Adze (mining) + */ + INFERNO_ADZE2(13661, 61, 1.0D, new Animation(10222)), + + HATCHET_CLASS1(Items.HATCHET_CLASS_1_14132, 1, 0.1, new Animation(10603)), + HATCHET_CLASS2(Items.HATCHET_CLASS_2_14134, 20, 0.3, new Animation(10604)), + HATCHET_CLASS3(Items.HATCHET_CLASS_3_14136, 40, 0.65, new Animation(10605)), + HATCHET_CLASS4(Items.HATCHET_CLASS_4_14138, 60, 0.85, new Animation(10606)), + HATCHET_CLASS5(Items.HATCHET_CLASS_5_14140, 80, 1.0, new Animation(10607)), + PICKAXE_CLASS1(Items.PICKAXE_CLASS_1_14122, 1, 0.1, new Animation(10608)), + PICKAXE_CLASS2(Items.PICKAXE_CLASS_2_14124, 20, 0.3, new Animation(10609)), + PICKAXE_CLASS3(Items.PICKAXE_CLASS_3_14126, 40, 0.65, new Animation(10610)), + PICKAXE_CLASS4(Items.PICKAXE_CLASS_4_14128, 60, 0.85, new Animation(10611)), + PICKAXE_CLASS5(Items.PICKAXE_CLASS_5_14130, 80, 1.0, new Animation(10612)), + HARPOON_CLASS1(Items.HARPOON_CLASS_1_14142, 1, 0.1, new Animation(10613)), + HARPOON_CLASS2(Items.HARPOON_CLASS_2_14144, 20, 0.3, new Animation(10614)), + HARPOON_CLASS3(Items.HARPOON_CLASS_3_14146, 40, 0.65, new Animation(10615)), + HARPOON_CLASS4(Items.HARPOON_CLASS_4_14148, 60, 0.85, new Animation(10616)), + HARPOON_CLASS5(Items.HARPOON_CLASS_5_14150, 80, 1.0, new Animation(10617)), + BUTTERFLY_NET_CLASS1(Items.BUTTERFLY_NET_CLASS_1_14152, 1, 0.1, new Animation(10618)), + BUTTERFLY_NET_CLASS2(Items.BUTTERFLY_NET_CLASS_2_14154, 20, 0.3, new Animation(10619)), + BUTTERFLY_NET_CLASS3(Items.BUTTERFLY_NET_CLASS_3_14156, 40, 0.65, new Animation(10620)), + BUTTERFLY_NET_CLASS4(Items.BUTTERFLY_NET_CLASS_4_14158, 60, 0.85, new Animation(10621)), + BUTTERFLY_NET_CLASS5(Items.BUTTERFLY_NET_CLASS_5_14160, 80, 1.0, new Animation(10622)); + + + /** + * The tool id. + */ + private final int id; + + /** + * The level required. + */ + private final int level; + + /** + * The ratio. + */ + private final double ratio; + + /** + * The animation. + */ + private final Animation animation; + + /** + * Constructs a new {@code SkillingTool} {@code Object}. + * @param id The tool item id. + * @param level The level required to use this. + * @param ratio The ratio. + * @param animation The animation. + */ + private SkillingTool(int id, int level, double ratio, Animation animation) { + this.id = id; + this.level = level; + this.ratio = ratio; + this.animation = animation; + } + + /** + * Gets the tool by the item id. + * @param itemId The item id. + * @return The skilling tool, or {@code null} if the tool wasn't found. + */ + public static SkillingTool forId(int itemId) { + for (SkillingTool tool : SkillingTool.values()) { + if (tool.id == itemId) { + return tool; + } + } + return null; + } + + /** + * Gets the hatchet used by the player. + * @param player The player. + * @return The hatchet. + */ + public static SkillingTool getHatchet(Player player) { + SkillingTool tool = null; + SkillingTool[] hatchetPriority = new SkillingTool[] { + SkillingTool.HATCHET_CLASS5, + SkillingTool.HATCHET_CLASS4, + SkillingTool.DRAGON_AXE, + SkillingTool.HATCHET_CLASS3, + SkillingTool.RUNE_AXE, + SkillingTool.ADAMANT_AXE, + SkillingTool.HATCHET_CLASS2, + SkillingTool.MITHRIL_AXE, + SkillingTool.BLACK_AXE, + SkillingTool.STEEL_AXE, + SkillingTool.HATCHET_CLASS1, + SkillingTool.IRON_AXE, + SkillingTool.BRONZE_AXE + }; + for(SkillingTool hatchet : hatchetPriority) { + if (checkTool(player, Skills.WOODCUTTING, hatchet)) { + tool = hatchet; + break; + } + } + if (checkTool(player, Skills.WOODCUTTING, SkillingTool.INFERNO_ADZE)) { + if(player.getSkills().getLevel(Skills.FIREMAKING) >= 92) { + tool = SkillingTool.INFERNO_ADZE; + } + } + return tool; + } + + /** + * Gets the pickaxe used by the player. + * @param player The player. + * @return The hatchet. + */ + public static SkillingTool getPickaxe(Player player) { + SkillingTool tool = null; + SkillingTool[] pickaxePriority = new SkillingTool[] { + SkillingTool.PICKAXE_CLASS5, + SkillingTool.PICKAXE_CLASS4, + SkillingTool.RUNE_PICKAXE, + SkillingTool.PICKAXE_CLASS3, + SkillingTool.ADAMANT_PICKAXE, + SkillingTool.PICKAXE_CLASS2, + SkillingTool.MITHRIL_PICKAXE, + SkillingTool.STEEL_PICKAXE, + SkillingTool.PICKAXE_CLASS1, + SkillingTool.IRON_PICKAXE, + SkillingTool.BRONZE_PICKAXE, + }; + for(SkillingTool pickaxe : pickaxePriority) { + if (checkTool(player, Skills.MINING, pickaxe)) { + tool = pickaxe; + break; + } + } + if (checkTool(player, Skills.MINING, SkillingTool.INFERNO_ADZE2)) { + if (player.getSkills().getLevel(Skills.FIREMAKING) >= 92) { + tool = SkillingTool.INFERNO_ADZE2; + } + } + return tool; + } + + public static SkillingTool getHarpoon(Player player) { + SkillingTool tool = null; + SkillingTool[] harpoonPriority = new SkillingTool[] { + SkillingTool.BUTTERFLY_NET_CLASS5, + SkillingTool.BUTTERFLY_NET_CLASS4, + SkillingTool.BUTTERFLY_NET_CLASS3, + SkillingTool.BUTTERFLY_NET_CLASS2, + SkillingTool.BUTTERFLY_NET_CLASS1, + }; + for(SkillingTool harpoon : harpoonPriority) { + if (checkTool(player, Skills.FISHING, harpoon)) { + tool = harpoon; + break; + } + } + return tool; + } + + public static SkillingTool getButterflyNet(Player player) { + SkillingTool tool = null; + SkillingTool[] butterflyNetPriority = new SkillingTool[] { + SkillingTool.BUTTERFLY_NET_CLASS5, + SkillingTool.BUTTERFLY_NET_CLASS4, + SkillingTool.BUTTERFLY_NET_CLASS3, + SkillingTool.BUTTERFLY_NET_CLASS2, + SkillingTool.BUTTERFLY_NET_CLASS1, + }; + for(SkillingTool butterflyNet : butterflyNetPriority) { + if (checkTool(player, Skills.HUNTER, butterflyNet)) { + tool = butterflyNet; + break; + } + } + return tool; + } + + public static SkillingTool getToolForSkill(Player player, int skill) { + switch(skill) { + case Skills.MINING: + return getPickaxe(player); + case Skills.WOODCUTTING: + return getHatchet(player); + case Skills.FISHING: + return getHarpoon(player); + case Skills.HUNTER: + return getButterflyNet(player); + default: + return null; + } + } + + /** + * Checks if the player has a tool and if he can use it. + * @param tool The tool. + * @return {@code True} if the tool is usable. + */ + public static boolean checkTool(Player player, int skillId, SkillingTool tool) { + if (player.getSkills().getStaticLevel(skillId) < tool.getLevel()) { + return false; + } + if (player.getEquipment().getNew(3).getId() == tool.getId()) { + return true; + } + return player.getInventory().contains(tool.getId(), 1); + } + + /** + * Gets the id. + * @return The id. + */ + public int getId() { + return id; + } + + /** + * Gets the level. + * @return The level. + */ + public int getLevel() { + return level; + } + + /** + * Gets the ratio. + * @return The ratio. + */ + public double getRatio() { + return ratio; + } + + /** + * Gets the animation. + * @return The animation. + */ + public Animation getAnimation() { + return animation; + } +} diff --git a/Server/src/main/content/data/tables/AllotmentSeedDropTable.java b/Server/src/main/content/data/tables/AllotmentSeedDropTable.java new file mode 100644 index 0000000..01b6f3f --- /dev/null +++ b/Server/src/main/content/data/tables/AllotmentSeedDropTable.java @@ -0,0 +1,94 @@ +package content.data.tables; + +import core.api.StartupListener; +import core.game.node.item.Item; +import core.game.node.item.WeightedChanceItem; +import core.tools.Log; +import core.tools.RandomFunction; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import core.ServerConstants; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import static core.api.ContentAPIKt.log; + +/** + * Handles the allotment seed drop table. + * @author Von Hresvelg + */ +public final class AllotmentSeedDropTable implements StartupListener { + + /** + * The item id of the item representing the allotment seed drop table slot in a drop + * table. + */ + public static final int SLOT_ITEM_ID = 14430; + + /** + * The allotment seed drop table. + */ + private static final List TABLE = new ArrayList<>(20); + + + /** + * Initialize needed objects for xml reading/writing + */ + static DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + static DocumentBuilder builder; + + static { + try { + builder = factory.newDocumentBuilder(); + } catch (ParserConfigurationException e) { + e.printStackTrace(); + } + } + + public AllotmentSeedDropTable() throws ParserConfigurationException {} + + @Override + public void startup() { + if(ServerConstants.ASDT_DATA_PATH != null && !new File(ServerConstants.ASDT_DATA_PATH).exists()){ + log(this.getClass(), Log.ERR, "Can't locate ASDT file at " + ServerConstants.ASDT_DATA_PATH); + return; + } + parse(ServerConstants.ASDT_DATA_PATH); + log(this.getClass(), Log.FINE, "Initialized Allotment Seed Drop Table from " + ServerConstants.ASDT_DATA_PATH); + } + + /** + * Parses the xml file for the allotment seed drop table. + * @param file the .xml file containing the allotment seed drop table. + */ + public static void parse(String file){ + try { + Document doc = builder.parse(file); + + NodeList itemNodes = doc.getElementsByTagName("item"); + for(int i = 0; i < itemNodes.getLength(); i++){ + Node itemNode = itemNodes.item(i); + if(itemNode.getNodeType() == Node.ELEMENT_NODE){ + Element item = (Element) itemNode; + int itemId = Integer.parseInt(item.getAttribute("id")); + int minAmt = Integer.parseInt(item.getAttribute("minAmt")); + int maxAmt = Integer.parseInt(item.getAttribute("maxAmt")); + int weight = Integer.parseInt(item.getAttribute("weight")); + + TABLE.add(new WeightedChanceItem(itemId,minAmt,maxAmt,weight)); + } + } + } catch (Exception e){ + e.printStackTrace(); + } + } + + public static Item retrieve() {return RandomFunction.rollWeightedChanceTable(TABLE);} +} \ No newline at end of file diff --git a/Server/src/main/content/data/tables/BirdNest.java b/Server/src/main/content/data/tables/BirdNest.java new file mode 100644 index 0000000..0552daa --- /dev/null +++ b/Server/src/main/content/data/tables/BirdNest.java @@ -0,0 +1,181 @@ +package content.data.tables; + +import org.rs09.consts.Items; +import core.game.node.entity.npc.drop.NPCDropTables; +import core.game.node.entity.player.Player; +import core.game.node.item.ChanceItem; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.tools.RandomFunction; +import core.tools.StringUtils; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playAudio; + +/** + * Represents a birds nest. + * @author Vexia + */ +public enum BirdNest { + SEED(new ChanceItem(5073, 1, 65), + new ChanceItem(Items.ACORN_5312, 1, NPCDropTables.DROP_RATES[0]), + new ChanceItem(Items.APPLE_TREE_SEED_5283, 1, NPCDropTables.DROP_RATES[0]), + new ChanceItem(Items.WILLOW_SEED_5313, 1, NPCDropTables.DROP_RATES[0]), + new ChanceItem(Items.BANANA_TREE_SEED_5284, 1, NPCDropTables.DROP_RATES[0]), + new ChanceItem(Items.ORANGE_TREE_SEED_5285, 1, NPCDropTables.DROP_RATES[0]), + new ChanceItem(Items.CURRY_TREE_SEED_5286, 1, NPCDropTables.DROP_RATES[0]), + new ChanceItem(Items.MAPLE_SEED_5314, 1, NPCDropTables.DROP_RATES[1]), + new ChanceItem(Items.PINEAPPLE_SEED_5287, 1, NPCDropTables.DROP_RATES[1]), + new ChanceItem(Items.PAPAYA_TREE_SEED_5288, 1, NPCDropTables.DROP_RATES[1]), + new ChanceItem(Items.YEW_SEED_5315, 1, NPCDropTables.DROP_RATES[2]), + new ChanceItem(Items.PALM_TREE_SEED_5289, 1, NPCDropTables.DROP_RATES[2]), + new ChanceItem(Items.CALQUAT_TREE_SEED_5290, 1, NPCDropTables.DROP_RATES[2]), + new ChanceItem(Items.SPIRIT_SEED_5317, 1, NPCDropTables.DROP_RATES[3]), + new ChanceItem(Items.MAGIC_SEED_5316, 1, NPCDropTables.DROP_RATES[3])), + RING(new ChanceItem(5074, 1, 30), + new ChanceItem(Items.GOLD_RING_1635, 1, NPCDropTables.DROP_RATES[0]), + new ChanceItem(Items.SAPPHIRE_RING_1637, 1, NPCDropTables.DROP_RATES[0]), + new ChanceItem(Items.EMERALD_RING_1639, 1, NPCDropTables.DROP_RATES[0]), + new ChanceItem(Items.RUBY_RING_1641, 1, NPCDropTables.DROP_RATES[0]), + new ChanceItem(Items.DIAMOND_RING_1643, 1, NPCDropTables.DROP_RATES[2])), + RED(new ChanceItem(5070, 1, 5), new ChanceItem(5076)), + GREEN(new ChanceItem(5071, 1, 5), new ChanceItem(5078)), + BLUE(new ChanceItem(5072, 1, 5), new ChanceItem(5077)), + RAVEN(new ChanceItem(11966, 1, 5), new ChanceItem(11964)), + + WYSON(new ChanceItem(7413, 1, 1), + new ChanceItem(Items.POTATO_SEED_5318, 14, NPCDropTables.DROP_RATES[0]), + new ChanceItem(Items.SWEETCORN_SEED_5320, 3, NPCDropTables.DROP_RATES[0]), + new ChanceItem(Items.TOMATO_SEED_5322, 6, NPCDropTables.DROP_RATES[0]), + new ChanceItem(Items.CABBAGE_SEED_5324, 9, NPCDropTables.DROP_RATES[0]), + new ChanceItem(Items.LIMPWURT_SEED_5100, 2, NPCDropTables.DROP_RATES[0]), + new ChanceItem(Items.ONION_SEED_5319, 11, NPCDropTables.DROP_RATES[0]), + new ChanceItem(Items.STRAWBERRY_SEED_5323, 3, NPCDropTables.DROP_RATES[0]), + new ChanceItem(Items.WATERMELON_SEED_5321, 2, NPCDropTables.DROP_RATES[0]), + new ChanceItem(Items.ACORN_5312, 1, NPCDropTables.DROP_RATES[2]), + new ChanceItem(Items.RANARR_SEED_5295, 1, NPCDropTables.DROP_RATES[2]), + new ChanceItem(Items.WILLOW_SEED_5313, 1, NPCDropTables.DROP_RATES[2]), + new ChanceItem(Items.MAPLE_SEED_5314, 1, NPCDropTables.DROP_RATES[2]), + new ChanceItem(Items.YEW_SEED_5315, 1, NPCDropTables.DROP_RATES[2]), + new ChanceItem(Items.MAGIC_SEED_5316, 1, NPCDropTables.DROP_RATES[3]), + new ChanceItem(Items.SPIRIT_SEED_5317, 1, NPCDropTables.DROP_RATES[3])); + + /** + * The random nest items. + */ + private static final ChanceItem[] NESTS = new ChanceItem[6]; + + /** + * The empty birds nest item. + */ + private static final Item EMPTY = new Item(5075); + + /** + * The birds nest item. + */ + private final ChanceItem nest; + + /** + * The loot item from the nest. + */ + private final ChanceItem[] loot; + + /** + * Constructs a new {@code BirdNest} {@code Object}. + * @param nest the nest. + * @param loot the loot. + */ + private BirdNest(final ChanceItem nest, final ChanceItem... loot) { + this.nest = nest; + this.loot = loot; + } + + /** + * Drops a birds nest. + * @param player the player. + */ + public static void drop(final Player player) { + final BirdNest nest = getRandomNest(false); + playAudio(player, Sounds.CUCKOO_1_1997); + GroundItemManager.create(nest.getNest(), player); + player.getPacketDispatch().sendMessage("A bird's nest falls out of the tree."); + } + + /** + * Searches a bird nest. + * @param player the player. + * @param item the item searched. + */ + public void search(final Player player, Item item) { + if (player.getInventory().freeSlots() < 1) { + player.getPacketDispatch().sendMessage("You don't have enough inventory space."); + return; + } + final ChanceItem loot = ordinal() > 1 && this != WYSON ? getLoot()[0] : RandomFunction.getChanceItem(getLoot()); + final String name = loot.getName().toLowerCase(); + final String input = (StringUtils.isPlusN(name) ? "an" : "a") + " " + name; + player.lock(1); + player.getInventory().add(loot); + player.getInventory().replace(EMPTY, item.getSlot()); + player.getPacketDispatch().sendMessage("You take " + input + " out of the bird's nest."); + } + + /** + * Gets the random nest. + * @return the nest. + */ + public static BirdNest getRandomNest(boolean wyson) { + ChanceItem item = RandomFunction.getChanceItem(NESTS); + for (BirdNest n : BirdNest.values()) { + if (n.getNest() == item) { + if (wyson && n == SEED) { + return WYSON; + } else if (!wyson && n == WYSON) { + return SEED; + } + return n; + } + } + return null; + } + + /** + * Gets the nest by the id. + * @param nest the nest. + * @return the nest. + */ + public static BirdNest forNest(final Item nest) { + for (BirdNest n : values()) { + if (n.getNest().getId() == nest.getId()) { + return n; + } + } + return null; + } + + /** + * Gets the nest. + * @return The nest. + */ + public ChanceItem getNest() { + return nest; + } + + /** + * Gets the loot. + * @return The loot. + */ + public ChanceItem[] getLoot() { + return loot; + } + + /** + * static-block to add nests. + */ + static { + for (int i = 0; i < NESTS.length; i++) { + NESTS[i] = values()[i].getNest(); + } + } + +} diff --git a/Server/src/main/content/data/tables/CELEMinorTable.java b/Server/src/main/content/data/tables/CELEMinorTable.java new file mode 100644 index 0000000..13313bc --- /dev/null +++ b/Server/src/main/content/data/tables/CELEMinorTable.java @@ -0,0 +1,96 @@ +package content.data.tables; + +import core.api.StartupListener; +import core.ServerConstants; +import core.game.node.item.Item; +import core.game.node.item.WeightedChanceItem; +import core.tools.Log; +import core.tools.RandomFunction; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import static core.api.ContentAPIKt.log; + +/** + * Handles the Chaos Elemental's minor drop table. It is supposed to roll this table alongside its standard major drops on the main table. + * @author Crash + */ +public final class CELEMinorTable implements StartupListener { + + /** + * The item id of the item representing the C. Ele minor drop table slot in a drop + * table. + */ + public static final int SLOT_ITEM_ID = 799; // Crash: Item ID 799 is currently a null, blank paper note object. Unsure if used for cutscene/cutscene items, but hijacking this as C.Ele's item container as it'll never be dropped or obtained in normal gameplay. + + /** + * The rare drop table. + */ + private static final List TABLE = new ArrayList<>(20); + + + /** + * Initialize needed objects for xml reading/writing + */ + static DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + static DocumentBuilder builder; + + static { + try { + builder = factory.newDocumentBuilder(); + } catch (ParserConfigurationException e) { + e.printStackTrace(); + } + } + + public CELEMinorTable() throws ParserConfigurationException {} + + @Override + public void startup() { + if(ServerConstants.CELEDT_DATA_PATH != null && !new File(ServerConstants.CELEDT_DATA_PATH).exists()){ + log(this.getClass(), Log.ERR, "Can't locate CELEDT file at " + ServerConstants.CELEDT_DATA_PATH); + return; + } + parse(ServerConstants.CELEDT_DATA_PATH); + log(this.getClass(), Log.FINE, "Loaded up Chaos Elemental drop table from " + ServerConstants.CELEDT_DATA_PATH); + } + + /** + * Parses the xml file for the CELEDT. + * @param file the .xml file containing the CELEDT. + */ + public static void parse(String file){ + try { + Document doc = builder.parse(file); + + NodeList itemNodes = doc.getElementsByTagName("item"); + for(int i = 0; i < itemNodes.getLength(); i++){ + Node itemNode = itemNodes.item(i); + if(itemNode.getNodeType() == Node.ELEMENT_NODE){ + Element item = (Element) itemNode; + int itemId = Integer.parseInt(item.getAttribute("id")); + int minAmt = Integer.parseInt(item.getAttribute("minAmt")); + int maxAmt = Integer.parseInt(item.getAttribute("maxAmt")); + int weight = Integer.parseInt(item.getAttribute("weight")); + + TABLE.add(new WeightedChanceItem(itemId,minAmt,maxAmt,weight)); + } + } + } catch (Exception e){ + e.printStackTrace(); + } + } + + public static Item retrieve(){ + return RandomFunction.rollWeightedChanceTable(TABLE); + } +} \ No newline at end of file diff --git a/Server/src/main/content/data/tables/GemDropTable.java b/Server/src/main/content/data/tables/GemDropTable.java new file mode 100644 index 0000000..e9b486d --- /dev/null +++ b/Server/src/main/content/data/tables/GemDropTable.java @@ -0,0 +1,96 @@ +package content.data.tables; + +import core.api.StartupListener; +import core.game.node.item.Item; +import core.game.node.item.WeightedChanceItem; +import core.tools.Log; +import core.tools.RandomFunction; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import core.ServerConstants; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import static core.api.ContentAPIKt.log; + +/** + * Handles the gem drop table. + * @author Von Hresvelg + */ +public final class GemDropTable implements StartupListener { + + /** + * The item id of the item representing the gem drop table slot in a drop + * table. + */ + public static final int SLOT_ITEM_ID = 14426; + + /** + * The gem drop table. + */ + private static final List TABLE = new ArrayList<>(20); + + + /** + * Initialize needed objects for xml reading/writing + */ + static DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + static DocumentBuilder builder; + + static { + try { + builder = factory.newDocumentBuilder(); + } catch (ParserConfigurationException e) { + e.printStackTrace(); + } + } + + public GemDropTable() throws ParserConfigurationException {} + + @Override + public void startup() { + if(ServerConstants.GDT_DATA_PATH != null && !new File(ServerConstants.GDT_DATA_PATH).exists()){ + log(this.getClass(), Log.ERR, "Can't locate GDT file at " + ServerConstants.GDT_DATA_PATH); + return; + } + parse(ServerConstants.GDT_DATA_PATH); + log(this.getClass(), Log.FINE, "Initialized Gem Drop Table from " + ServerConstants.GDT_DATA_PATH); + } + + /** + * Parses the xml file for the gem drop table. + * @param file the .xml file containing the gem drop table. + */ + public static void parse(String file){ + try { + Document doc = builder.parse(file); + + NodeList itemNodes = doc.getElementsByTagName("item"); + for(int i = 0; i < itemNodes.getLength(); i++){ + Node itemNode = itemNodes.item(i); + if(itemNode.getNodeType() == Node.ELEMENT_NODE){ + Element item = (Element) itemNode; + int itemId = Integer.parseInt(item.getAttribute("id")); + int minAmt = Integer.parseInt(item.getAttribute("minAmt")); + int maxAmt = Integer.parseInt(item.getAttribute("maxAmt")); + int weight = Integer.parseInt(item.getAttribute("weight")); + + TABLE.add(new WeightedChanceItem(itemId,minAmt,maxAmt,weight)); + } + } + } catch (Exception e){ + e.printStackTrace(); + } + } + + public static Item retrieve(){ + return RandomFunction.rollWeightedChanceTable(TABLE); + } +} \ No newline at end of file diff --git a/Server/src/main/content/data/tables/HerbDropTable.java b/Server/src/main/content/data/tables/HerbDropTable.java new file mode 100644 index 0000000..efd03da --- /dev/null +++ b/Server/src/main/content/data/tables/HerbDropTable.java @@ -0,0 +1,96 @@ +package content.data.tables; + +import core.api.StartupListener; +import core.game.node.item.Item; +import core.game.node.item.WeightedChanceItem; +import core.tools.Log; +import core.tools.RandomFunction; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import core.ServerConstants; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import static core.api.ContentAPIKt.log; + +/** + * Handles the herb drop table. + * @author Von Hresvelg + */ +public final class HerbDropTable implements StartupListener { + + /** + * The item id of the item representing the herb drop table slot in a drop + * table. + */ + public static final int SLOT_ITEM_ID = 14424; + + /** + * The herb drop table. + */ + private static final List TABLE = new ArrayList<>(20); + + + /** + * Initialize needed objects for xml reading/writing + */ + static DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + static DocumentBuilder builder; + + static { + try { + builder = factory.newDocumentBuilder(); + } catch (ParserConfigurationException e) { + e.printStackTrace(); + } + } + + public HerbDropTable() throws ParserConfigurationException {} + + @Override + public void startup() { + if(ServerConstants.HDT_DATA_PATH != null && !new File(ServerConstants.HDT_DATA_PATH).exists()){ + log(this.getClass(), Log.ERR, "Can't locate HDT file at " + ServerConstants.HDT_DATA_PATH); + return; + } + parse(ServerConstants.HDT_DATA_PATH); + log(this.getClass(), Log.FINE, "Initialized Herb Drop Table from " + ServerConstants.HDT_DATA_PATH); + } + + /** + * Parses the xml file for the herb drop table. + * @param file the .xml file containing the herb drop table. + */ + public static void parse(String file){ + try { + Document doc = builder.parse(file); + + NodeList itemNodes = doc.getElementsByTagName("item"); + for(int i = 0; i < itemNodes.getLength(); i++){ + Node itemNode = itemNodes.item(i); + if(itemNode.getNodeType() == Node.ELEMENT_NODE){ + Element item = (Element) itemNode; + int itemId = Integer.parseInt(item.getAttribute("id")); + int minAmt = Integer.parseInt(item.getAttribute("minAmt")); + int maxAmt = Integer.parseInt(item.getAttribute("maxAmt")); + int weight = Integer.parseInt(item.getAttribute("weight")); + + TABLE.add(new WeightedChanceItem(itemId,minAmt,maxAmt,weight)); + } + } + } catch (Exception e){ + e.printStackTrace(); + } + } + + public static Item retrieve(){ + return RandomFunction.rollWeightedChanceTable(TABLE); + } +} \ No newline at end of file diff --git a/Server/src/main/content/data/tables/RareDropTable.kt b/Server/src/main/content/data/tables/RareDropTable.kt new file mode 100644 index 0000000..253fc52 --- /dev/null +++ b/Server/src/main/content/data/tables/RareDropTable.kt @@ -0,0 +1,114 @@ +package content.data.tables + +import core.ServerConstants +import core.api.StartupListener +import core.api.log +import core.api.shouldRemoveNothings +import core.api.utils.WeightBasedTable +import core.api.utils.WeightedItem +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.tools.Log +import core.tools.RandomFunction +import org.rs09.consts.Items +import org.w3c.dom.Element +import org.w3c.dom.Node +import java.io.File +import javax.xml.parsers.DocumentBuilder +import javax.xml.parsers.DocumentBuilderFactory +import javax.xml.parsers.ParserConfigurationException + +/** + * Handles the rare drop table. + * @author Ceikry + */ +class RareDropTable : StartupListener { + override fun startup() { + if (ServerConstants.RDT_DATA_PATH != null && !File(ServerConstants.RDT_DATA_PATH).exists()) { + log(this::class.java, Log.ERR, "Can't locate RDT file at " + ServerConstants.RDT_DATA_PATH) + return + } + parse(ServerConstants.RDT_DATA_PATH) + log(this::class.java, Log.FINE, "Initialized Rare Drop Table from " + ServerConstants.RDT_DATA_PATH) + } + + companion object { + private val TABLE: WeightBasedTable = object : WeightBasedTable() { + override fun roll(receiver: Entity?): ArrayList { + val items = ArrayList(guaranteedItems) + var effectiveWeight = totalWeight + val p = if (receiver is Player) receiver else null + if (p != null && shouldRemoveNothings(p)) + effectiveWeight -= nothingWeight + + if (this.size == 1) { + items.add(get(0)) + } else if (!this.isEmpty()) { + var rngWeight = RandomFunction.randomDouble(effectiveWeight) + for (item in this.shuffled()) { + if (item.id == Items.DWARF_REMAINS_0) continue + rngWeight -= item.weight + if (rngWeight <= 0) { + items.add(item) + break + } + } + } + return convertWeightedItems(items, receiver) + } + + private val nothingWeight: Double + get() { + var sum = 0.0 + for (i in this) { + if (i.id == Items.DWARF_REMAINS_0) + sum += i.weight + } + return sum + } + } + + /** + * Initialize needed objects for xml reading/writing + */ + var factory = DocumentBuilderFactory.newInstance() + var builder: DocumentBuilder? = null + + init { + try { + builder = factory.newDocumentBuilder() + } catch (e: ParserConfigurationException) { + e.printStackTrace() + } + } + + /** + * Parses the xml file for the RDT. + * @param file the .xml file containing the RDT. + */ + fun parse(file: String?) { + try { + val doc = builder!!.parse(file) + val itemNodes = doc.getElementsByTagName("item") + for (i in 0 until itemNodes.length) { + val itemNode = itemNodes.item(i) + if (itemNode.nodeType == Node.ELEMENT_NODE) { + val item = itemNode as Element + val itemId = item.getAttribute("id").toInt() + val minAmt = item.getAttribute("minAmt").toInt() + val maxAmt = item.getAttribute("maxAmt").toInt() + val weight = item.getAttribute("weight").toInt() + TABLE.add(WeightedItem(itemId, minAmt, maxAmt, weight.toDouble(), false)) + } + } + } catch (e: Exception) { + e.printStackTrace() + } + } + + fun retrieve(receiver: Entity?): Item? { + return TABLE.roll(receiver).getOrNull(0) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/data/tables/RareSeedDropTable.java b/Server/src/main/content/data/tables/RareSeedDropTable.java new file mode 100644 index 0000000..0b89227 --- /dev/null +++ b/Server/src/main/content/data/tables/RareSeedDropTable.java @@ -0,0 +1,96 @@ +package content.data.tables; + +import core.api.StartupListener; +import core.game.node.item.Item; +import core.game.node.item.WeightedChanceItem; +import core.tools.Log; +import core.tools.RandomFunction; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import core.ServerConstants; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import static core.api.ContentAPIKt.log; + +/** + * Handles the rare seed drop table. + * @author Von Hresvelg + */ +public final class RareSeedDropTable implements StartupListener { + + /** + * The item id of the item representing the rare seed drop table slot in a drop + * table. + */ + public static final int SLOT_ITEM_ID = 14428; + + /** + * The rare seed drop table. + */ + private static final List TABLE = new ArrayList<>(20); + + + /** + * Initialize needed objects for xml reading/writing + */ + static DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + static DocumentBuilder builder; + + static { + try { + builder = factory.newDocumentBuilder(); + } catch (ParserConfigurationException e) { + e.printStackTrace(); + } + } + + public RareSeedDropTable() throws ParserConfigurationException {} + + @Override + public void startup() { + if(ServerConstants.RSDT_DATA_PATH != null && !new File(ServerConstants.RSDT_DATA_PATH).exists()){ + log(this.getClass(), Log.ERR, "Can't locate RSDT file at " + ServerConstants.RSDT_DATA_PATH); + return; + } + parse(ServerConstants.RSDT_DATA_PATH); + log(this.getClass(), Log.FINE, "Initialized Rare Seed Drop Table from " + ServerConstants.RSDT_DATA_PATH); + } + + /** + * Parses the xml file for the rare seed drop table. + * @param file the .xml file containing the rare seed drop table. + */ + public static void parse(String file){ + try { + Document doc = builder.parse(file); + + NodeList itemNodes = doc.getElementsByTagName("item"); + for(int i = 0; i < itemNodes.getLength(); i++){ + Node itemNode = itemNodes.item(i); + if(itemNode.getNodeType() == Node.ELEMENT_NODE){ + Element item = (Element) itemNode; + int itemId = Integer.parseInt(item.getAttribute("id")); + int minAmt = Integer.parseInt(item.getAttribute("minAmt")); + int maxAmt = Integer.parseInt(item.getAttribute("maxAmt")); + int weight = Integer.parseInt(item.getAttribute("weight")); + + TABLE.add(new WeightedChanceItem(itemId,minAmt,maxAmt,weight)); + } + } + } catch (Exception e){ + e.printStackTrace(); + } + } + + public static Item retrieve(){ + return RandomFunction.rollWeightedChanceTable(TABLE); + } +} \ No newline at end of file diff --git a/Server/src/main/content/data/tables/UncommonSeedDropTable.java b/Server/src/main/content/data/tables/UncommonSeedDropTable.java new file mode 100644 index 0000000..1c76ca5 --- /dev/null +++ b/Server/src/main/content/data/tables/UncommonSeedDropTable.java @@ -0,0 +1,96 @@ +package content.data.tables; + +import core.api.StartupListener; +import core.game.node.item.Item; +import core.game.node.item.WeightedChanceItem; +import core.tools.Log; +import core.tools.RandomFunction; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import core.ServerConstants; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import static core.api.ContentAPIKt.log; + +/** + * Handles the uncommon seed drop table. + * @author Von Hresvelg + */ +public final class UncommonSeedDropTable implements StartupListener { + + /** + * The item id of the item representing the uncommon seed drop table slot in a drop + * table. + */ + public static final int SLOT_ITEM_ID = 14422; + + /** + * The uncommon seed drop table. + */ + private static final List TABLE = new ArrayList<>(20); + + + /** + * Initialize needed objects for xml reading/writing + */ + static DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + static DocumentBuilder builder; + + static { + try { + builder = factory.newDocumentBuilder(); + } catch (ParserConfigurationException e) { + e.printStackTrace(); + } + } + + public UncommonSeedDropTable() throws ParserConfigurationException {} + + @Override + public void startup() { + if(ServerConstants.USDT_DATA_PATH != null && !new File(ServerConstants.USDT_DATA_PATH).exists()){ + log(this.getClass(), Log.ERR, "Can't locate USDT file at " + ServerConstants.USDT_DATA_PATH); + return; + } + parse(ServerConstants.USDT_DATA_PATH); + log(this.getClass(), Log.FINE, "Initialized Uncommon Seed Drop Table from " + ServerConstants.USDT_DATA_PATH); + } + + /** + * Parses the xml file for the uncommon seed drop table. + * @param file the .xml file containing the uncommon seed drop table. + */ + public static void parse(String file){ + try { + Document doc = builder.parse(file); + + NodeList itemNodes = doc.getElementsByTagName("item"); + for(int i = 0; i < itemNodes.getLength(); i++){ + Node itemNode = itemNodes.item(i); + if(itemNode.getNodeType() == Node.ELEMENT_NODE){ + Element item = (Element) itemNode; + int itemId = Integer.parseInt(item.getAttribute("id")); + int minAmt = Integer.parseInt(item.getAttribute("minAmt")); + int maxAmt = Integer.parseInt(item.getAttribute("maxAmt")); + int weight = Integer.parseInt(item.getAttribute("weight")); + + TABLE.add(new WeightedChanceItem(itemId,minAmt,maxAmt,weight)); + } + } + } catch (Exception e){ + e.printStackTrace(); + } + } + + public static Item retrieve(){ + return RandomFunction.rollWeightedChanceTable(TABLE); + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/activity/cchallange/ChampionChallengeListener.kt b/Server/src/main/content/global/activity/cchallange/ChampionChallengeListener.kt new file mode 100644 index 0000000..e1e2cd6 --- /dev/null +++ b/Server/src/main/content/global/activity/cchallange/ChampionChallengeListener.kt @@ -0,0 +1,229 @@ +package content.global.activity.cchallange + +import content.global.activity.cchallange.npc.EarthWarriorChampionNPC.Companion.spawnEarthWarriorChampion +import content.global.activity.cchallange.npc.GhoulChampionNPC.Companion.spawnGhoulChampion +import content.global.activity.cchallange.npc.GiantChampionNPC.Companion.spawnGiantChampion +import content.global.activity.cchallange.npc.GoblinChampionNPC.Companion.spawnGoblinChampion +import content.global.activity.cchallange.npc.HobgoblinChampionNPC.Companion.spawnHobgoblinChampion +import content.global.activity.cchallange.npc.ImpChampionNPC.Companion.spawnImpChampion +import content.global.activity.cchallange.npc.JogreChampionNPC.Companion.spawnJogreChampion +import content.global.activity.cchallange.npc.LesserDemonChampionNPC.Companion.spawnLesserDemonChampion +import content.global.activity.cchallange.npc.SkeletonChampionNPC.Companion.spawnSkeletonChampion +import content.global.activity.cchallange.npc.ZombieChampionNPC.Companion.spawnZombieChampion +import core.api.* +import core.game.global.action.DoorActionHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import core.game.world.map.zone.ZoneRestriction +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +/** + * Represents the Champion challenge. + */ + +class ChampionChallengeListener : InteractionListener, MapArea { + + val EARTH_WARRIOR_SCROLL = Items.CHAMPION_SCROLL_6798 + val GHOUL_SCROLL = Items.CHAMPION_SCROLL_6799 + val GIANT_SCROLL = Items.CHAMPION_SCROLL_6800 + val GOBLIN_SCROLL = Items.CHAMPION_SCROLL_6801 + val HOBGOBLIN_SCROLL = Items.CHAMPION_SCROLL_6802 + val IMP_SCROLL = Items.CHAMPION_SCROLL_6803 + val JOGRE_SCROLL = Items.CHAMPION_SCROLL_6804 + val LESSER_DEMON_SCROLL = Items.CHAMPION_SCROLL_6805 + val SKELETON_SCROLL = Items.CHAMPION_SCROLL_6806 + val ZOMBIE_SCROLL = Items.CHAMPION_SCROLL_6807 + + val MESSAGE_SCROLL = 222 + + private val IMP_SCROLL_TEXT = arrayOf( + "How about picking on someone your own size? I'll", + "see you at the Champion's Guild.", + "", + "Champion of Imps" + ) + + private val GOBLIN_SCROLL_TEXT = arrayOf( + "Fight me if you think you can human, I'll wait", + "for you in the Champion's Guild.", + "", + "Champion of Goblins" + ) + + private val SKELETON_SCROLL_TEXT = arrayOf( + "I'll be waiting at the Champions' Guild to", + "collect your bones.", + "", + "Champion of Skeletons" + ) + + private val ZOMBIE_SCROLL_TEXT = arrayOf( + "You come to Champions' Guild, you fight me,", + "I squish you, I get brains!", + "", + "Champion of Zombies" + ) + + private val GIANT_SCROLL_TEXT = arrayOf( + "Get yourself to the Champions' Guild, if you", + "dare to face me puny human.", + "", + "Champion of Giants" + ) + + private val HOBGOBLIN_SCROLL_TEXT = arrayOf( + "You won't defeat me, though you're welcome to", + "try at the Champions' Guild.", + "", + "Champion of Hobgoblins" + ) + + private val GHOUL_SCROLL_TEXT = arrayOf( + "Come and duel me at the Champions' Guild, I'll", + "make sure nothing goes to waste.", + "", + "Champion of Ghouls" + ) + + private val EARTH_WARRIOR_TEXT = arrayOf( + "I challenge you to a duel, come to the arena beneath", + "the Champion's Guild and fight me if you dare.", + "", + "Champion of Earth Warriors" + ) + + private val JOGRE_SCROLL_TEXT = arrayOf( + "You think you can defeat me? Come to the", + "Champion's Guild and prove it!", + "", + "Champion of Jogres" + ) + + private val LESSER_DEMON_SCROLL_TEXT = arrayOf( + "Come to the Champion's Guild so I can banish", + "you mortal!", + "", + "Champion of Lesser Demons" + ) + + private val PORTCULLIS = Scenery.PORTCULLIS_10553 + private val CHAMPION_STATUE_CLOSED = Scenery.CHAMPION_STATUE_10556 + private val CHAMPION_STATUE_OPEN = Scenery.CHAMPION_STATUE_10557 + private val TRAPDOOR_CLOSED = Scenery.TRAPDOOR_10558 + private val TRAPDOOR_OPEN = Scenery.TRAPDOOR_10559 + private val LARXUS = NPCs.LARXUS_3050 + + private val ARENA_ZONE = 12696 + + override fun defineListeners() { + // Champion's Guild Basement Ladder to Main Floor + addClimbDest(Location(3190, 9758, 0), Location(3190, 3356, 0)) + // Champion Statue Ladder to Arena + addClimbDest(Location(3184, 9758, 0), Location(3182, 9758, 0)) + // Arena Ladder to Champion's Guild Basement + addClimbDest(Location(3183, 9758, 0), Location(3185, 9758, 0)) + + on(LARXUS, IntType.NPC, "talk-to") { player, _ -> + openDialogue(player, LarxusDialogue(false)) + return@on true + } + + on(ChampionScrollsDropHandler.SCROLLS, IntType.ITEM, "read") { player, node -> + updateAndReadScroll(player, node.asItem()) + return@on true + } + + onUseWith(IntType.NPC, ChampionScrollsDropHandler.SCROLLS, NPCs.LARXUS_3050) { player, _, _ -> + openDialogue(player, LarxusDialogue(true)) + return@onUseWith true + } + + on(TRAPDOOR_CLOSED, IntType.SCENERY, "open") { _, node -> + replaceScenery(node.asScenery(), TRAPDOOR_OPEN, 100, node.location) + return@on true + } + + on(TRAPDOOR_OPEN, IntType.SCENERY, "close") { _, node -> + replaceScenery(node.asScenery(), TRAPDOOR_CLOSED, -1, node.location) + return@on true + } + + on(CHAMPION_STATUE_CLOSED, IntType.SCENERY, "open") { _, node -> + replaceScenery(node.asScenery(), CHAMPION_STATUE_OPEN, 100, node.location) + return@on true + } + + on(PORTCULLIS, IntType.SCENERY, "open") { player, node -> + if (player.getAttribute("championsarena:start", false) == false) { + sendNPCDialogue(player, NPCs.LARXUS_3050, "You need to arrange a challenge with me before you enter the arena.") + } else { + lock(player, 3) + submitWorldPulse(object : Pulse() { + var counter = 0 + override fun pulse(): Boolean { + when (counter++) { + 1 -> { + player.familiarManager.dismiss() + } + 2 -> DoorActionHandler.handleDoor(player, node.asScenery()) + 3 -> when{ + removeItem(player, IMP_SCROLL) -> spawnImpChampion(player) + removeItem(player, GOBLIN_SCROLL) -> spawnGoblinChampion(player) + removeItem(player, SKELETON_SCROLL) -> spawnSkeletonChampion(player) + removeItem(player, ZOMBIE_SCROLL) -> spawnZombieChampion(player) + removeItem(player, GIANT_SCROLL) -> spawnGiantChampion(player) + removeItem(player, HOBGOBLIN_SCROLL) -> spawnHobgoblinChampion(player) + removeItem(player, GHOUL_SCROLL) -> spawnGhoulChampion(player) + removeItem(player, EARTH_WARRIOR_SCROLL) -> { + spawnEarthWarriorChampion(player) + player.prayer.reset() + } + removeItem(player, JOGRE_SCROLL) -> spawnJogreChampion(player) + removeItem(player, LESSER_DEMON_SCROLL) -> spawnLesserDemonChampion(player) + } + } + return false + } + }) + } + return@on true + } + } + + private fun updateAndReadScroll(player: Player, item: Item) { + val id = item.id + openInterface(player, MESSAGE_SCROLL).also { + when (id) { + IMP_SCROLL -> setInterfaceText(player, IMP_SCROLL_TEXT.joinToString("
"), MESSAGE_SCROLL, 4) + GOBLIN_SCROLL -> setInterfaceText(player, GOBLIN_SCROLL_TEXT.joinToString("
"), MESSAGE_SCROLL, 4) + SKELETON_SCROLL -> setInterfaceText(player, SKELETON_SCROLL_TEXT.joinToString("
"), MESSAGE_SCROLL, 4) + ZOMBIE_SCROLL -> setInterfaceText(player, ZOMBIE_SCROLL_TEXT.joinToString("
"), MESSAGE_SCROLL, 4) + GIANT_SCROLL -> setInterfaceText(player, GIANT_SCROLL_TEXT.joinToString("
"), MESSAGE_SCROLL, 4) + HOBGOBLIN_SCROLL -> setInterfaceText(player, HOBGOBLIN_SCROLL_TEXT.joinToString("
"), MESSAGE_SCROLL, 4) + GHOUL_SCROLL -> setInterfaceText(player, GHOUL_SCROLL_TEXT.joinToString("
"), MESSAGE_SCROLL, 4) + EARTH_WARRIOR_SCROLL -> setInterfaceText(player, EARTH_WARRIOR_TEXT.joinToString("
"), MESSAGE_SCROLL, 4) + JOGRE_SCROLL -> setInterfaceText(player, JOGRE_SCROLL_TEXT.joinToString("
"), MESSAGE_SCROLL, 4) + LESSER_DEMON_SCROLL -> setInterfaceText(player, LESSER_DEMON_SCROLL_TEXT.joinToString("
"), MESSAGE_SCROLL, 4) + } + } + } + + override fun defineAreaBorders(): Array { + return arrayOf(getRegionBorders(ARENA_ZONE)) + } + + override fun getRestrictions(): Array { + return arrayOf( + ZoneRestriction.CANNON, + ZoneRestriction.FIRES, + ZoneRestriction.RANDOM_EVENTS + ) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/activity/cchallange/ChampionScrollsDropHandler.kt b/Server/src/main/content/global/activity/cchallange/ChampionScrollsDropHandler.kt new file mode 100644 index 0000000..02b3b2b --- /dev/null +++ b/Server/src/main/content/global/activity/cchallange/ChampionScrollsDropHandler.kt @@ -0,0 +1,279 @@ +package content.global.activity.cchallange + +import core.api.sendMessage +import core.api.sendNews +import core.game.event.NPCKillEvent +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import core.tools.* +import core.game.world.GameWorld +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +/** + * Handles the drop for champion challenge. + * @authors Phil, Skelsoft, Ceikry + */ + +class ChampionScrollsDropHandler : ChampionScrollsEventHookBase() { + companion object { + + private val IMPS = intArrayOf( + NPCs.IMP_708, NPCs.IMP_709, NPCs.IMP_1531, NPCs.IMP_6211 + ) + + private val GOBLINS = intArrayOf( + NPCs.GOBLIN_100, NPCs.GOBLIN_101, NPCs.GOBLIN_102, NPCs.GOBLIN_444, NPCs.GOBLIN_445, + + NPCs.GOBLIN_1769, NPCs.GOBLIN_1770, NPCs.GOBLIN_1771, NPCs.GOBLIN_1772, NPCs.GOBLIN_1773, + NPCs.GOBLIN_1774, NPCs.GOBLIN_1775, NPCs.GOBLIN_1776, NPCs.GOBLIN_2274, NPCs.GOBLIN_2275, + NPCs.GOBLIN_2276, NPCs.GOBLIN_2277, NPCs.GOBLIN_2278, NPCs.GOBLIN_2279, NPCs.GOBLIN_2280, + NPCs.GOBLIN_2281, NPCs.GOBLIN_2678, NPCs.GOBLIN_2679, NPCs.GOBLIN_2680, NPCs.GOBLIN_2681, + NPCs.GOBLIN_3264, NPCs.GOBLIN_3265, NPCs.GOBLIN_3266, NPCs.GOBLIN_3267, NPCs.GOBLIN_3726, + NPCs.GOBLIN_4261, NPCs.GOBLIN_4262, NPCs.GOBLIN_4263, NPCs.GOBLIN_4264, NPCs.GOBLIN_4265, + NPCs.GOBLIN_4266, NPCs.GOBLIN_4267, NPCs.GOBLIN_4268, NPCs.GOBLIN_4269, NPCs.GOBLIN_4270, + NPCs.GOBLIN_4271, NPCs.GOBLIN_4272, NPCs.GOBLIN_4273, NPCs.GOBLIN_4274, NPCs.GOBLIN_4275, + NPCs.GOBLIN_4276, NPCs.GOBLIN_4407, NPCs.GOBLIN_4408, NPCs.GOBLIN_4409, NPCs.GOBLIN_4410, + NPCs.GOBLIN_4411, NPCs.GOBLIN_4412, NPCs.GOBLIN_4479, NPCs.GOBLIN_4480, NPCs.GOBLIN_4481, + NPCs.GOBLIN_4482, NPCs.GOBLIN_4483, NPCs.GOBLIN_4484, NPCs.GOBLIN_4485, NPCs.GOBLIN_4486, + NPCs.GOBLIN_4487, NPCs.GOBLIN_4488, NPCs.GOBLIN_4489, NPCs.GOBLIN_4490, NPCs.GOBLIN_4491, + NPCs.GOBLIN_4492, NPCs.GOBLIN_4499, NPCs.GOBLIN_4633, NPCs.GOBLIN_4634, NPCs.GOBLIN_4635, + NPCs.GOBLIN_4636, NPCs.GOBLIN_4637, NPCs.GOBLIN_5855, NPCs.GOBLIN_5856, NPCs.GOBLIN_6125, + NPCs.GOBLIN_6126, NPCs.GOBLIN_6132, NPCs.GOBLIN_6133, NPCs.GOBLIN_6279, NPCs.GOBLIN_6280, + NPCs.GOBLIN_6281, NPCs.GOBLIN_6282, NPCs.GOBLIN_6283, NPCs.GOBLIN_6284, NPCs.GOBLIN_6402, + NPCs.GOBLIN_6403, NPCs.GOBLIN_6404, NPCs.GOBLIN_6405, NPCs.GOBLIN_6406, NPCs.GOBLIN_6407, + NPCs.GOBLIN_6408, NPCs.GOBLIN_6409, NPCs.GOBLIN_6410, NPCs.GOBLIN_6411, NPCs.GOBLIN_6412, + NPCs.GOBLIN_6413, NPCs.GOBLIN_6414, NPCs.GOBLIN_6415, NPCs.GOBLIN_6416, NPCs.GOBLIN_6417, + NPCs.GOBLIN_6418, NPCs.GOBLIN_6419, NPCs.GOBLIN_6420, NPCs.GOBLIN_6421, NPCs.GOBLIN_6422, + NPCs.GOBLIN_6423, NPCs.GOBLIN_6424, NPCs.GOBLIN_6425, NPCs.GOBLIN_6426, NPCs.GOBLIN_6427, + NPCs.GOBLIN_6428, NPCs.GOBLIN_6429, NPCs.GOBLIN_6430, NPCs.GOBLIN_6431, NPCs.GOBLIN_6432, + NPCs.GOBLIN_6433, NPCs.GOBLIN_6434, NPCs.GOBLIN_6435, NPCs.GOBLIN_6436, NPCs.GOBLIN_6437, + NPCs.GOBLIN_6438, NPCs.GOBLIN_6439, NPCs.GOBLIN_6440, NPCs.GOBLIN_6441, NPCs.GOBLIN_6442, + NPCs.GOBLIN_6443, NPCs.GOBLIN_6444, NPCs.GOBLIN_6445, NPCs.GOBLIN_6446, NPCs.GOBLIN_6447, + NPCs.GOBLIN_6448, NPCs.GOBLIN_6449, NPCs.GOBLIN_6450, NPCs.GOBLIN_6451, NPCs.GOBLIN_6452, + NPCs.GOBLIN_6453, NPCs.GOBLIN_6454, NPCs.GOBLIN_6455, NPCs.GOBLIN_6456, NPCs.GOBLIN_6457, + NPCs.GOBLIN_6458, NPCs.GOBLIN_6459, NPCs.GOBLIN_6460, NPCs.GOBLIN_6461, NPCs.GOBLIN_6462, + NPCs.GOBLIN_6463, NPCs.GOBLIN_6464, NPCs.GOBLIN_6465, NPCs.GOBLIN_6466, NPCs.GOBLIN_6467, + NPCs.GOBLIN_6490, NPCs.GOBLIN_6491, NPCs.GOBLIN_6492, NPCs.GOBLIN_6493, NPCs.GOBLIN_6494, + NPCs.GOBLIN_6495, NPCs.GOBLIN_7964, NPCs.GOBLIN_7965, + + NPCs.CAVE_GOBLIN_1822, NPCs.CAVE_GOBLIN_1823, NPCs.CAVE_GOBLIN_1824, NPCs.CAVE_GOBLIN_1825, + NPCs.CAVE_GOBLIN_5752, NPCs.CAVE_GOBLIN_5753, NPCs.CAVE_GOBLIN_5754, NPCs.CAVE_GOBLIN_5755, + NPCs.CAVE_GOBLIN_5756, NPCs.CAVE_GOBLIN_5757, NPCs.CAVE_GOBLIN_5758, NPCs.CAVE_GOBLIN_5759, + NPCs.CAVE_GOBLIN_5760, NPCs.CAVE_GOBLIN_5761, NPCs.CAVE_GOBLIN_5762, NPCs.CAVE_GOBLIN_5763, + NPCs.CAVE_GOBLIN_5764, NPCs.CAVE_GOBLIN_5765, NPCs.CAVE_GOBLIN_5766, NPCs.CAVE_GOBLIN_5767, + NPCs.CAVE_GOBLIN_5768, NPCs.CAVE_GOBLIN_5769, NPCs.CAVE_GOBLIN_5783, NPCs.CAVE_GOBLIN_5785, + NPCs.CAVE_GOBLIN_5873, NPCs.CAVE_GOBLIN_5874, NPCs.CAVE_GOBLIN_5875, NPCs.CAVE_GOBLIN_5876, + NPCs.CAVE_GOBLIN_5877, NPCs.CAVE_GOBLIN_5878, NPCs.CAVE_GOBLIN_8451, + + NPCs.CAVE_GOBLIN_GUARD_2073, NPCs.CAVE_GOBLIN_GUARD_2074, + + NPCs.GOBLIN_GUARD_489, NPCs.GOBLIN_GUARD_6496, NPCs.GOBLIN_GUARD_6497, + NPCs.SERGEANT_GRIMSPIKE_6265, + NPCs.SERGEANT_STEELWILL_6263, + NPCs.SERGEANT_STRONGSTACK_6261 + ) + + private val SKELETONS = intArrayOf( + NPCs.SKELETON_90, NPCs.SKELETON_91, NPCs.SKELETON_92, NPCs.SKELETON_93, + + NPCs.SKELETON_459, + + NPCs.SKELETON_1471, NPCs.SKELETON_2036, NPCs.SKELETON_2037, NPCs.SKELETON_2715, + NPCs.SKELETON_3151, NPCs.SKELETON_3152, NPCs.SKELETON_3291, NPCs.SKELETON_3581, + NPCs.SKELETON_4384, NPCs.SKELETON_4385, NPCs.SKELETON_4386, NPCs.SKELETON_5332, + NPCs.SKELETON_5333, NPCs.SKELETON_5334, NPCs.SKELETON_5335, NPCs.SKELETON_5336, + NPCs.SKELETON_5337, NPCs.SKELETON_5338, NPCs.SKELETON_5339, NPCs.SKELETON_5340, + NPCs.SKELETON_5341, NPCs.SKELETON_5365, NPCs.SKELETON_5366, NPCs.SKELETON_5367, + NPCs.SKELETON_5368, NPCs.SKELETON_5381, NPCs.SKELETON_5385, NPCs.SKELETON_5386, + NPCs.SKELETON_5387, NPCs.SKELETON_5388, NPCs.SKELETON_5389, NPCs.SKELETON_5390, + NPCs.SKELETON_5391, NPCs.SKELETON_5392, NPCs.SKELETON_5411, NPCs.SKELETON_5412, + NPCs.SKELETON_5422, NPCs.SKELETON_5423, NPCs.SKELETON_6091, NPCs.SKELETON_6092, + NPCs.SKELETON_6093, NPCs.SKELETON_6764, NPCs.SKELETON_6765, NPCs.SKELETON_6766, + NPCs.SKELETON_6767, NPCs.SKELETON_6768, NPCs.SKELETON_7774, NPCs.SKELETON_7775, + NPCs.SKELETON_7776, NPCs.SKELETON_7777, NPCs.SKELETON_7778, NPCs.SKELETON_7779, + NPCs.SKELETON_7788, NPCs.SKELETON_7815, NPCs.GIANT_SKELETON_1973, + + NPCs.GIANT_SKELETON_5359, NPCs.GIANT_SKELETON_5384, NPCs.SKELETON_HELLHOUND_1575, + + NPCs.SKELETON_MAGE_94, NPCs.SKELETON_MAGE_2717, NPCs.SKELETON_MAGE_3844, + + NPCs.SKELETON_MAGE_3850, NPCs.SKELETON_MAGE_3851, + + NPCs.SKELETON_HERO_6103, NPCs.SKELETON_BRUTE_6104, NPCs.SKELETON_WARLORD_6105, + + NPCs.SKELETON_HEAVY_6106, NPCs.SKELETON_THUG_6107, + NPCs.NAZASTAROOL_508, + + NPCs.UNDEAD_ONE_5353, NPCs.UNDEAD_ONE_5354, NPCs.UNDEAD_ONE_5355, + NPCs.UNDEAD_ONE_5356, NPCs.UNDEAD_ONE_5357, NPCs.UNDEAD_ONE_5358, + ) + + private val ZOMBIES = intArrayOf( + NPCs.ZOMBIE_73, NPCs.ZOMBIE_74, NPCs.ZOMBIE_75, NPCs.ZOMBIE_76, NPCs.ZOMBIE_419, + NPCs.ZOMBIE_420, NPCs.ZOMBIE_421, NPCs.ZOMBIE_422, NPCs.ZOMBIE_423, NPCs.ZOMBIE_424, + + NPCs.ZOMBIE_1826, NPCs.ZOMBIE_2714, NPCs.ZOMBIE_2863, NPCs.ZOMBIE_2866, NPCs.ZOMBIE_2869, + NPCs.ZOMBIE_2878, NPCs.ZOMBIE_3622, NPCs.ZOMBIE_3623, NPCs.ZOMBIE_4392, NPCs.ZOMBIE_4393, + NPCs.ZOMBIE_4394, NPCs.ZOMBIE_5293, NPCs.ZOMBIE_5294, NPCs.ZOMBIE_5295, NPCs.ZOMBIE_5296, + NPCs.ZOMBIE_5297, NPCs.ZOMBIE_5298, NPCs.ZOMBIE_5299, NPCs.ZOMBIE_5300, NPCs.ZOMBIE_5301, + NPCs.ZOMBIE_5302, NPCs.ZOMBIE_5303, NPCs.ZOMBIE_5304, NPCs.ZOMBIE_5305, NPCs.ZOMBIE_5306, + NPCs.ZOMBIE_5307, NPCs.ZOMBIE_5308, NPCs.ZOMBIE_5309, NPCs.ZOMBIE_5310, NPCs.ZOMBIE_5311, + NPCs.ZOMBIE_5312, NPCs.ZOMBIE_5313, NPCs.ZOMBIE_5314, NPCs.ZOMBIE_5315, NPCs.ZOMBIE_5316, + NPCs.ZOMBIE_5317, NPCs.ZOMBIE_5318, NPCs.ZOMBIE_5319, NPCs.ZOMBIE_5320, NPCs.ZOMBIE_5321, + NPCs.ZOMBIE_5322, NPCs.ZOMBIE_5323, NPCs.ZOMBIE_5324, NPCs.ZOMBIE_5325, NPCs.ZOMBIE_5326, + NPCs.ZOMBIE_5327, NPCs.ZOMBIE_5328, NPCs.ZOMBIE_5329, NPCs.ZOMBIE_5330, NPCs.ZOMBIE_5331, + NPCs.ZOMBIE_5375, NPCs.ZOMBIE_5376, NPCs.ZOMBIE_5377, NPCs.ZOMBIE_5378, NPCs.ZOMBIE_5379, + NPCs.ZOMBIE_5380, NPCs.ZOMBIE_5393, NPCs.ZOMBIE_5394, NPCs.ZOMBIE_5395, NPCs.ZOMBIE_5396, + NPCs.ZOMBIE_5397, NPCs.ZOMBIE_5398, NPCs.ZOMBIE_5399, NPCs.ZOMBIE_5400, NPCs.ZOMBIE_5401, + NPCs.ZOMBIE_5402, NPCs.ZOMBIE_5403, NPCs.ZOMBIE_5404, NPCs.ZOMBIE_5405, NPCs.ZOMBIE_5406, + NPCs.ZOMBIE_5407, NPCs.ZOMBIE_5408, NPCs.ZOMBIE_5409, NPCs.ZOMBIE_5410, NPCs.ZOMBIE_6099, + NPCs.ZOMBIE_6100, NPCs.ZOMBIE_6131, NPCs.ZOMBIE_7789, NPCs.ZOMBIE_7790, NPCs.ZOMBIE_7791, + NPCs.ZOMBIE_7792, NPCs.ZOMBIE_7817, NPCs.ZOMBIE_7818, NPCs.ZOMBIE_7819, NPCs.ZOMBIE_7820, + NPCs.ZOMBIE_8142, NPCs.ZOMBIE_8143, NPCs.ZOMBIE_8144, NPCs.ZOMBIE_8145, + + NPCs.ZOMBIE_PIRATE_2837, NPCs.ZOMBIE_PIRATE_2838, NPCs.ZOMBIE_PIRATE_2839, + NPCs.ZOMBIE_PIRATE_2840, NPCs.ZOMBIE_PIRATE_2841, NPCs.ZOMBIE_PIRATE_2842, + NPCs.ZOMBIE_PIRATE_5629, NPCs.ZOMBIE_PIRATE_5630, NPCs.ZOMBIE_PIRATE_5631, + NPCs.ZOMBIE_PIRATE_5632, NPCs.ZOMBIE_PIRATE_5633, NPCs.ZOMBIE_PIRATE_5634, + NPCs.ZOMBIE_PIRATE_5635, NPCs.ZOMBIE_PIRATE_5636, NPCs.ZOMBIE_PIRATE_5637, + NPCs.ZOMBIE_PIRATE_5638, NPCs.ZOMBIE_PIRATE_5639, NPCs.ZOMBIE_PIRATE_5640, + NPCs.ZOMBIE_PIRATE_5641, NPCs.ZOMBIE_PIRATE_5642, NPCs.ZOMBIE_PIRATE_5643, + NPCs.ZOMBIE_PIRATE_5644, NPCs.ZOMBIE_PIRATE_5645, NPCs.ZOMBIE_PIRATE_5646, + NPCs.ZOMBIE_PIRATE_5647, NPCs.ZOMBIE_PIRATE_5648, NPCs.ZOMBIE_PIRATE_5649, + NPCs.ZOMBIE_PIRATE_5650, NPCs.ZOMBIE_PIRATE_5651, NPCs.ZOMBIE_PIRATE_5652, + NPCs.ZOMBIE_PIRATE_5653, NPCs.ZOMBIE_PIRATE_5654, NPCs.ZOMBIE_PIRATE_5655, + NPCs.ZOMBIE_PIRATE_5656, NPCs.ZOMBIE_PIRATE_5657, NPCs.ZOMBIE_PIRATE_5658, + NPCs.ZOMBIE_PIRATE_5659, NPCs.ZOMBIE_PIRATE_5660, NPCs.ZOMBIE_PIRATE_5661, + NPCs.ZOMBIE_PIRATE_5662, NPCs.ZOMBIE_PIRATE_5663, NPCs.ZOMBIE_PIRATE_5664, + NPCs.ZOMBIE_PIRATE_5665, + + NPCs.ZOMBIE_SWAB_2843, NPCs.ZOMBIE_SWAB_2845, + NPCs.ZOMBIE_SWAB_2846, NPCs.ZOMBIE_SWAB_2847, + NPCs.ZOMBIE_SWAB_2848, + NPCs.NAZASTAROOL_507, + + NPCs.SLASH_BASH_2060, NPCs.SOREBONES_5627, NPCs.SOREBONES_5628, + + NPCs.UNDEAD_LUMBERJACK_1524, + + NPCs.UNDEAD_ONE_502, NPCs.UNDEAD_ONE_503, NPCs.UNDEAD_ONE_504, NPCs.UNDEAD_ONE_505, + + NPCs.ZOGRE_2044, NPCs.ZOGRE_2045, NPCs.ZOGRE_2046, NPCs.ZOGRE_2047, NPCs.ZOGRE_2048, + NPCs.ZOGRE_2049, NPCs.ZOGRE_2051, NPCs.ZOGRE_2052, NPCs.ZOGRE_2053, NPCs.ZOGRE_2054, + NPCs.ZOGRE_2055, + NPCs.UNDEAD_LUMBERJACK_1524, NPCs.UNDEAD_LUMBERJACK_1525, NPCs.UNDEAD_LUMBERJACK_5678, + NPCs.UNDEAD_LUMBERJACK_5679, NPCs.UNDEAD_LUMBERJACK_5680, NPCs.UNDEAD_LUMBERJACK_5681, + NPCs.UNDEAD_LUMBERJACK_5682, NPCs.UNDEAD_LUMBERJACK_5683, NPCs.UNDEAD_LUMBERJACK_5684, + NPCs.UNDEAD_LUMBERJACK_5685, NPCs.UNDEAD_LUMBERJACK_5686, NPCs.UNDEAD_LUMBERJACK_5687, + NPCs.UNDEAD_LUMBERJACK_5688, NPCs.UNDEAD_LUMBERJACK_5689, NPCs.UNDEAD_LUMBERJACK_5690, + NPCs.UNDEAD_LUMBERJACK_5691, NPCs.UNDEAD_LUMBERJACK_5692, NPCs.UNDEAD_LUMBERJACK_5693, + NPCs.UNDEAD_LUMBERJACK_5694, NPCs.UNDEAD_LUMBERJACK_5695, NPCs.UNDEAD_LUMBERJACK_5696, + NPCs.UNDEAD_LUMBERJACK_5697, NPCs.UNDEAD_LUMBERJACK_5698, NPCs.UNDEAD_LUMBERJACK_5699, + NPCs.UNDEAD_LUMBERJACK_5700, NPCs.UNDEAD_LUMBERJACK_5701, NPCs.UNDEAD_LUMBERJACK_5702, + NPCs.UNDEAD_LUMBERJACK_5703, NPCs.UNDEAD_LUMBERJACK_5704, NPCs.UNDEAD_LUMBERJACK_5705, + NPCs.UNDEAD_LUMBERJACK_5706, NPCs.UNDEAD_LUMBERJACK_5707, NPCs.UNDEAD_LUMBERJACK_5708, + NPCs.UNDEAD_LUMBERJACK_5709, NPCs.UNDEAD_LUMBERJACK_5710, NPCs.UNDEAD_LUMBERJACK_5711, + NPCs.UNDEAD_LUMBERJACK_5712, NPCs.UNDEAD_LUMBERJACK_5713, NPCs.UNDEAD_LUMBERJACK_5714, + NPCs.UNDEAD_LUMBERJACK_5715, NPCs.UNDEAD_LUMBERJACK_5716, NPCs.UNDEAD_LUMBERJACK_5717, + NPCs.UNDEAD_LUMBERJACK_5718, NPCs.UNDEAD_LUMBERJACK_5719, NPCs.UNDEAD_LUMBERJACK_5720, + NPCs.UNDEAD_LUMBERJACK_5721, NPCs.UNDEAD_LUMBERJACK_5722, NPCs.UNDEAD_LUMBERJACK_5723, + NPCs.UNDEAD_LUMBERJACK_5724, NPCs.UNDEAD_LUMBERJACK_5725, NPCs.UNDEAD_LUMBERJACK_5726, + NPCs.UNDEAD_LUMBERJACK_5727, NPCs.UNDEAD_LUMBERJACK_5728, NPCs.UNDEAD_LUMBERJACK_5729, + NPCs.UNDEAD_LUMBERJACK_5730, NPCs.UNDEAD_LUMBERJACK_5731, NPCs.UNDEAD_LUMBERJACK_5732, + NPCs.UNDEAD_LUMBERJACK_5733, NPCs.UNDEAD_LUMBERJACK_5734, NPCs.UNDEAD_LUMBERJACK_5735, + NPCs.UNDEAD_LUMBERJACK_5736, NPCs.UNDEAD_LUMBERJACK_5737, NPCs.UNDEAD_LUMBERJACK_5738, + NPCs.UNDEAD_LUMBERJACK_5739, NPCs.UNDEAD_LUMBERJACK_5740, NPCs.UNDEAD_LUMBERJACK_5741, + NPCs.UNDEAD_LUMBERJACK_5742, NPCs.UNDEAD_LUMBERJACK_5743, NPCs.UNDEAD_LUMBERJACK_5744, + NPCs.UNDEAD_LUMBERJACK_5745, NPCs.UNDEAD_LUMBERJACK_5746, NPCs.UNDEAD_LUMBERJACK_5747, + ) + + private val GIANTS = intArrayOf( + NPCs.HILL_GIANT_117, NPCs.HILL_GIANT_4689, NPCs.HILL_GIANT_4690, NPCs.HILL_GIANT_4691, + NPCs.HILL_GIANT_4692, NPCs.HILL_GIANT_4693, + + NPCs.FIRE_GIANT_110, NPCs.FIRE_GIANT_1582, NPCs.FIRE_GIANT_1583, NPCs.FIRE_GIANT_1584, + NPCs.FIRE_GIANT_1585, NPCs.FIRE_GIANT_1586, NPCs.FIRE_GIANT_7003, NPCs.FIRE_GIANT_7004, + + NPCs.MOSS_GIANT_112, NPCs.MOSS_GIANT_1587, NPCs.MOSS_GIANT_1588, NPCs.MOSS_GIANT_1681, + NPCs.MOSS_GIANT_4534, NPCs.MOSS_GIANT_4688, NPCs.MOSS_GIANT_4706, + + NPCs.ICE_GIANT_111, NPCs.ICE_GIANT_3072, NPCs.ICE_GIANT_4685, NPCs.ICE_GIANT_4686, + NPCs.ICE_GIANT_4687, + NPCs.BLACK_KNIGHT_TITAN_221, + + NPCs.CYCLOPS_116, NPCs.CYCLOPS_4291, NPCs.CYCLOPS_4292, NPCs.CYCLOPS_6078, + NPCs.CYCLOPS_6079, NPCs.CYCLOPS_6080, NPCs.CYCLOPS_6081, NPCs.CYCLOPS_6082, + NPCs.CYCLOPS_6083, NPCs.CYCLOPS_6269, NPCs.CYCLOPS_6270, + ) + + private val HOBGOBLINS = intArrayOf( + NPCs.HOBGOBLIN_122, NPCs.HOBGOBLIN_123, NPCs.HOBGOBLIN_2685, NPCs.HOBGOBLIN_2686, + NPCs.HOBGOBLIN_2687, NPCs.HOBGOBLIN_2688, NPCs.HOBGOBLIN_3583, NPCs.HOBGOBLIN_4898, + NPCs.HOBGOBLIN_6275, + ) + + private val GHOUL = NPCs.GHOUL_1218 + private val EARTH_WARRIOR = NPCs.EARTH_WARRIOR_124 + + private val JOGRES = intArrayOf(NPCs.JOGRE_113, NPCs.JOGRE_6268) + + private val LESSER_DEMONS = intArrayOf( + NPCs.LESSER_DEMON_82, NPCs.LESSER_DEMON_4694, NPCs.LESSER_DEMON_4695, + NPCs.LESSER_DEMON_4696, NPCs.LESSER_DEMON_4697, NPCs.LESSER_DEMON_6101, + ) + + private val ZAKLN = NPCs.ZAKLN_GRITCH_6206 + + val SCROLLS = intArrayOf( + Items.CHAMPION_SCROLL_6803, Items.CHAMPION_SCROLL_6801, Items.CHAMPION_SCROLL_6806, + Items.CHAMPION_SCROLL_6807, Items.CHAMPION_SCROLL_6800, Items.CHAMPION_SCROLL_6802, + Items.CHAMPION_SCROLL_6799, Items.CHAMPION_SCROLL_6798, Items.CHAMPION_SCROLL_6804, + Items.CHAMPION_SCROLL_6805 + ) + + val idMap = HashMap() + + init { + for (id in IMPS) + idMap[id] = 0 + for (id in GOBLINS) + idMap[id] = 1 + for (id in SKELETONS) + idMap[id] = 2 + for (id in ZOMBIES) + idMap[id] = 3 + for (id in GIANTS) + idMap[id] = 4 + for (id in HOBGOBLINS) + idMap[id] = 5 + for (id in JOGRES) + idMap[id] = 8 + for (id in LESSER_DEMONS) + idMap[id] = 9 + + idMap[GHOUL] = 6 + idMap[EARTH_WARRIOR] = 7 + } + } + + override fun onNpcKilled(player: Player, event: NPCKillEvent) { + if (player.isArtificial) return + if (player.questRepository.points >= 32) { + val scrollType = idMap[event.npc.id] ?: return + rollForScroll (player, scrollType, event.npc) + } + } + + private fun rollForScroll(player: Player, scroll: Int, npc: NPC) { + val scrollID = SCROLLS[scroll] + val roll = RandomFunction.roll(if (GameWorld.settings!!.isDevMode) 5 else 5000) + if (roll) { + GroundItemManager.create(Item(scrollID), npc.location, player) + sendMessage(player, colorize("%RA Champion's scroll falls to the ground as you slay your opponent.")) + } + } + +} diff --git a/Server/src/main/content/global/activity/cchallange/ChampionScrollsEventHookBase.kt b/Server/src/main/content/global/activity/cchallange/ChampionScrollsEventHookBase.kt new file mode 100644 index 0000000..12f8260 --- /dev/null +++ b/Server/src/main/content/global/activity/cchallange/ChampionScrollsEventHookBase.kt @@ -0,0 +1,39 @@ +package content.global.activity.cchallange + +import core.api.LoginListener +import core.game.event.Event +import core.game.event.EventHook +import core.game.event.NPCKillEvent +import core.game.node.entity.Entity +import core.game.node.entity.player.Player + +/** + * Manages the champion scrolls drop. + * @authors Phil, Skelsoft. + */ + +abstract class ChampionScrollsEventHookBase : LoginListener { + + protected companion object { + private fun forEligibleEntityDo(entity: Entity, event: T, handler: (Player, T) -> Unit) { + if (entity !is Player) return + if (entity.isArtificial) return + handler(entity, event) + } + } + + class EventHandler( + private val owner: ChampionScrollsEventHookBase, + private val handler: (Player, T) -> Unit) : EventHook { + override fun process(entity: Entity, event: T) { + forEligibleEntityDo(entity, event, handler) + } + } + + final override fun login(player: Player) { + player.hook(core.api.Event.NPCKilled, EventHandler(this, ::onNpcKilled)) + } + + protected open fun onNpcKilled(player: Player, event: NPCKillEvent) {} + +} \ No newline at end of file diff --git a/Server/src/main/content/global/activity/cchallange/LarxusDialogue.kt b/Server/src/main/content/global/activity/cchallange/LarxusDialogue.kt new file mode 100644 index 0000000..6ec919b --- /dev/null +++ b/Server/src/main/content/global/activity/cchallange/LarxusDialogue.kt @@ -0,0 +1,72 @@ +package content.global.activity.cchallange + +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +/** + * Represents the dialogue plugin used for the larxus npc. + * @author 'Vexia + * @version 1.1 + */ + +@Initializable +class LarxusDialogue(val ChallengeStart: Boolean = false) : DialogueFile() { + + override fun handle(componentID: Int, buttonID: Int) { + val scrolls = intArrayOf(Items.CHAMPION_SCROLL_6798, Items.CHAMPION_SCROLL_6799, Items.CHAMPION_SCROLL_6800, Items.CHAMPION_SCROLL_6801, Items.CHAMPION_SCROLL_6802, Items.CHAMPION_SCROLL_6803, Items.CHAMPION_SCROLL_6804, Items.CHAMPION_SCROLL_6805, Items.CHAMPION_SCROLL_6806, Items.CHAMPION_SCROLL_6807,) + npc = NPC(NPCs.LARXUS_3050) + if (ChallengeStart) { + when (stage) { + 0 -> { + face(findNPC(NPCs.LARXUS_3050)!!, player!!, 1) + for (i in scrolls)when{ + inInventory(player!!,Items.CHAMPION_SCROLL_6798) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're not allowed to use prayer's. Do you still want to proceed?").also { stage = 1 } + inInventory(player!!,Items.CHAMPION_SCROLL_6799) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're allowed to use only weapons. Do you still want to proceed?").also { stage = 1 } + inInventory(player!!,Items.CHAMPION_SCROLL_6800) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're allowed to use only melee combat skill. Do you still want to proceed?").also { stage = 1 } + inInventory(player!!,Items.CHAMPION_SCROLL_6801) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're allowed to use only magic skill. Do you still want to proceed?").also { stage = 1 } + inInventory(player!!,Items.CHAMPION_SCROLL_6802) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're not allowed to use melee combat skills. Do you still want to proceed?").also { stage = 1 } + inInventory(player!!,Items.CHAMPION_SCROLL_6803) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're not allowed to use weapons with special attack. Do you still want to proceed?").also { stage = 1 } + inInventory(player!!,Items.CHAMPION_SCROLL_6804) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're not allowed to use ranged skill. Do you still want to proceed?").also { stage = 1 } + inInventory(player!!,Items.CHAMPION_SCROLL_6805) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're allowed to use only equipment. Do you still want to proceed?").also { stage = 1 } + inInventory(player!!,Items.CHAMPION_SCROLL_6806) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're allowed to use only ranged skill. Do you still want to proceed?").also { stage = 1 } + inInventory(player!!,Items.CHAMPION_SCROLL_6807) -> npcl("So you want to accept the challenge huh? Well there are some specific rules for these Champion fights. For this fight you're not allowed to use magic skill. Do you still want to proceed?").also { stage = 1 } + else -> { + sendMessage(player!!, "Nothing interesting happens.").also { stage = END_DIALOGUE } } + } + } + 1 -> options("Yes, let me at him!", "No, thanks I'll pass.").also { stage = 2 } + 2 -> when (buttonID) { + 1 -> playerl("Yes, let me at him!").also { stage = 3 } + 2 -> playerl("No, thanks I'll pass.").also { stage = END_DIALOGUE } + } + 3 -> npcl("Your challenger is ready, please go down through the trapdoor when you're ready.").also { stage = 4 } + 4 -> { + end() + setAttribute(player!!, "championsarena:start", true) + } + } + } else { + when (stage) { + START_DIALOGUE -> { + face(findNPC(NPCs.LARXUS_3050)!!, player!!, 1) + npcl(FacialExpression.NEUTRAL, "Is there something I can help you with?").also { stage = 1 } + } + 1 -> options("I was given a challenge, what now?", "What is this place?", "Nothing thanks.").also { stage = 2 } + 2 -> when (buttonID) { + 1 -> playerl("I was given a challenge, what now?").also { stage = 3 } + 2 -> playerl("What is this place?").also { stage = 4 } + 3 -> playerl("Nothing thanks.").also { stage = END_DIALOGUE } + } + 3 -> npcl("Well pass it here and we'll get you started.").also { stage = END_DIALOGUE } + 4 -> npcl("This is the champions' arena, the champions of various, races use it to duel those they deem worthy of the, honour.").also { stage = END_DIALOGUE } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/activity/cchallange/npc/EarthWarriorChampionNPC.kt b/Server/src/main/content/global/activity/cchallange/npc/EarthWarriorChampionNPC.kt new file mode 100644 index 0000000..ea868cc --- /dev/null +++ b/Server/src/main/content/global/activity/cchallange/npc/EarthWarriorChampionNPC.kt @@ -0,0 +1,114 @@ +package content.global.activity.cchallange.npc + +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.system.task.Pulse +import core.game.world.GameWorld +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +/** + * Represents the Earth warrior champion NPC for Champions challenge. + */ + +@Initializable +class EarthWarriorChampionNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id, location) { + var clearTime = 0 + override fun construct(id: Int, location: Location, vararg objects: Any): AbstractNPC { + return EarthWarriorChampionNPC(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.EARTH_WARRIOR_CHAMPION_3057) + } + + override fun handleTickActions() { + super.handleTickActions() + if (clearTime++ > 288) poofClear(this) + } + + companion object { + fun spawnEarthWarriorChampion(player: Player) { + val champion = EarthWarriorChampionNPC(NPCs.EARTH_WARRIOR_CHAMPION_3057) + champion.location = location(3170, 9758, 0) + champion.isWalks = true + champion.isAggressive = true + champion.isActive = false + + if (champion.asNpc() != null && champion.isActive) { + champion.properties.teleportLocation = champion.properties.spawnLocation + } + + champion.isActive = true + GameWorld.Pulser.submit(object : Pulse(0, champion) { + override fun pulse(): Boolean { + val prayerItems = intArrayOf( + Items.PRAYER_POTION1_143, Items.PRAYER_POTION1_144, + Items.PRAYER_POTION2_141, Items.PRAYER_POTION2_142, + Items.PRAYER_POTION3_139, Items.PRAYER_POTION3_140, + Items.PRAYER_POTION4_2434, Items.PRAYER_POTION4_2435, + + Items.SUPER_RESTORE1_3030, Items.SUPER_RESTORE1_3031, + Items.SUPER_RESTORE2_3028, Items.SUPER_RESTORE2_3029, + Items.SUPER_RESTORE3_3026, Items.SUPER_RESTORE3_3027, + Items.SUPER_RESTORE4_3024, Items.SUPER_RESTORE4_3025, + + Items.PRAYER_CAPE_9759, Items.PRAYER_CAPET_9760, + Items.PRAYER_HOOD_9761, Items.PRAYER_CAPE_10643, + + Items.PRAYER_POTION4_14209, Items.PRAYER_POTION4_14210, + Items.PRAYER_POTION3_14211, Items.PRAYER_POTION3_14212, + Items.PRAYER_POTION2_14213, Items.PRAYER_POTION2_14214, + Items.PRAYER_POTION1_14215, Items.PRAYER_POTION1_14216, + + Items.FALADOR_SHIELD_1_14577, Items.FALADOR_SHIELD_2_14578, + Items.FALADOR_SHIELD_3_14579, + + Items.PRAYER_MIX1_11467, Items.PRAYER_MIX1_11468, + Items.PRAYER_MIX2_11465, Items.PRAYER_MIX2_11466, + + Items.SUP_RESTORE_MIX1_11495, Items.SUP_RESTORE_MIX1_11496, + Items.SUP_RESTORE_MIX2_11493, Items.SUP_RESTORE_MIX2_11494, + ) + if (player.inventory.containsAtLeastOneItem(prayerItems) || player.equipment.containsAtLeastOneItem( + prayerItems + ) + ) { + sendNPCDialogue(player, NPCs.LARXUS_3050, "For this fight you're not allowed to use prayers!") + teleport(player, Location.create(3182, 9758, 0)) // Behind Doors. + } else { + champion.init() + registerHintIcon(player, champion) + champion.attack(player) + } + return true + } + }) + } + } + + override fun finalizeDeath(killer: Entity?) { + if (killer is Player) { + lock(killer, 2) + runTask(killer, 1) { + openInterface(killer, 63) + setInterfaceText(killer, "Well done, you defeated the Earth Warrior Champion!", 63, 2) + killer.packetDispatch.sendItemZoomOnInterface(Items.CHAMPION_SCROLL_6798, 260, 63, 3) + setInterfaceText(killer, "432 Slayer Xp", 63, 6) + setInterfaceText(killer, "432 Hitpoint Xp", 63, 7) + } + setVarbit(killer, 1452, 1, true) + rewardXP(killer, Skills.HITPOINTS, 432.0) + rewardXP(killer, Skills.SLAYER, 432.0) + removeAttribute("championsarena:start") + clearHintIcon(killer) + } + clear() + super.finalizeDeath(killer) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/activity/cchallange/npc/GhoulChampionNPC.kt b/Server/src/main/content/global/activity/cchallange/npc/GhoulChampionNPC.kt new file mode 100644 index 0000000..a6421a8 --- /dev/null +++ b/Server/src/main/content/global/activity/cchallange/npc/GhoulChampionNPC.kt @@ -0,0 +1,105 @@ +package content.global.activity.cchallange.npc + +import core.api.* +import core.game.container.impl.EquipmentContainer +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.system.config.ItemConfigParser +import core.game.system.task.Pulse +import core.game.world.GameWorld +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +/** + * Represents the Ghoul champion NPC for Champions challenge. + */ + +@Initializable +class GhoulChampionNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id, location) { + var clearTime = 0 + override fun construct(id: Int, location: Location, vararg objects: Any): AbstractNPC { + return GhoulChampionNPC(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.GHOUL_CHAMPION_3059) + } + + override fun handleTickActions() { + super.handleTickActions() + if (clearTime++ > 288) poofClear(this) + } + + companion object { + fun spawnGhoulChampion(player: Player) { + val champion = GhoulChampionNPC(NPCs.GHOUL_CHAMPION_3059) + champion.location = location(3170, 9758, 0) + champion.isWalks = true + champion.isAggressive = true + champion.isActive = false + + if (champion.asNpc() != null && champion.isActive) { + champion.properties.teleportLocation = champion.properties.spawnLocation + } + champion.isActive = true + GameWorld.Pulser.submit(object : Pulse(0, champion) { + override fun pulse(): Boolean { + champion.init() + registerHintIcon(player, champion) + champion.attack(player) + return true + } + }) + } + } + + override fun checkImpact(state: BattleState) { + super.checkImpact(state) + val player = state.attacker + if (player is Player) { + val i: Item = player.equipment[EquipmentContainer.SLOT_WEAPON].id.asItem() + if (i.definition.getConfiguration(ItemConfigParser.TWO_HANDED, false) == true && state.style == CombatStyle.MELEE) { + state.neutralizeHits() + state.estimatedHit = state.maximumHit + } + if (state.style == CombatStyle.MAGIC) { + sendMessage(player, "You can use only weapons in this challenge.") + if (state.estimatedHit > -1) { + state.estimatedHit = 0 + return + } + if (state.secondaryHit > -1) { + state.secondaryHit = 0 + return + } + } + } + } + + override fun finalizeDeath(killer: Entity?) { + if (killer is Player) { + lock(killer, 2) + runTask(killer, 1) { + openInterface(killer, 63) + setInterfaceText(killer, "Well done, you defeated the Ghoul Champion!", 63, 2) + killer.packetDispatch.sendItemZoomOnInterface(Items.CHAMPION_SCROLL_6799, 260, 63, 3) + setInterfaceText(killer, "400 Slayer Xp", 63, 6) + setInterfaceText(killer, "400 Hitpoint Xp", 63, 7) + } + setVarbit(killer, 1453, 1, true) + rewardXP(killer, Skills.HITPOINTS, 400.0) + rewardXP(killer, Skills.SLAYER, 400.0) + removeAttribute("championsarena:start") + clearHintIcon(killer) + } + clear() + super.finalizeDeath(killer) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/activity/cchallange/npc/GiantChampionNPC.kt b/Server/src/main/content/global/activity/cchallange/npc/GiantChampionNPC.kt new file mode 100644 index 0000000..3309be7 --- /dev/null +++ b/Server/src/main/content/global/activity/cchallange/npc/GiantChampionNPC.kt @@ -0,0 +1,103 @@ +package content.global.activity.cchallange.npc + +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.system.task.Pulse +import core.game.world.GameWorld +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +/** + * Represents the Giant champion NPC for Champions challenge. + */ + +@Initializable +class GiantChampionNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id, location) { + var clearTime = 0 + override fun construct(id: Int, location: Location, vararg objects: Any): AbstractNPC { + return GiantChampionNPC(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.GIANT_CHAMPION_3058) + + } + + override fun handleTickActions() { + super.handleTickActions() + if (clearTime++ > 288) poofClear(this) + } + + companion object { + fun spawnGiantChampion(player: Player) { + val champion = GiantChampionNPC(NPCs.GIANT_CHAMPION_3058) + champion.location = location(3170, 9758, 0) + champion.isWalks = true + champion.isAggressive = true + champion.isActive = false + + if (champion.asNpc() != null && champion.isActive) { + champion.properties.teleportLocation = champion.properties.spawnLocation + } + + champion.isActive = true + GameWorld.Pulser.submit(object : Pulse(0, champion) { + override fun pulse(): Boolean { + champion.init() + registerHintIcon(player, champion) + champion.attack(player) + return true + } + }) + } + } + + override fun checkImpact(state: BattleState) { + super.checkImpact(state) + val player = state.attacker + if (player is Player) { + if (state.style == CombatStyle.MELEE) { + state.neutralizeHits() + state.estimatedHit = state.maximumHit + } + if (state.style == CombatStyle.RANGE || state.style == CombatStyle.MAGIC) { + sendMessage(player, "You can use only melee in this challenge.") + if (state.estimatedHit > -1) { + state.estimatedHit = 0 + return + } + if (state.secondaryHit > -1) { + state.secondaryHit = 0 + return + } + } + } + } + + override fun finalizeDeath(killer: Entity?) { + if (killer is Player) { + lock(killer, 2) + runTask(killer, 1) { + openInterface(killer, 63) + setInterfaceText(killer, "Well done, you defeated the Giant Champion!", 63, 2) + killer.packetDispatch.sendItemZoomOnInterface(Items.CHAMPION_SCROLL_6800, 260, 63, 3) + setInterfaceText(killer, "280 Slayer Xp", 63, 6) + setInterfaceText(killer, "280 Hitpoint Xp", 63, 7) + } + setVarbit(killer, 1454, 1, true) + rewardXP(killer, Skills.HITPOINTS, 280.0) + rewardXP(killer, Skills.SLAYER, 280.0) + removeAttribute("championsarena:start") + clearHintIcon(killer) + } + clear() + super.finalizeDeath(killer) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/activity/cchallange/npc/GoblinChampionNPC.kt b/Server/src/main/content/global/activity/cchallange/npc/GoblinChampionNPC.kt new file mode 100644 index 0000000..8612878 --- /dev/null +++ b/Server/src/main/content/global/activity/cchallange/npc/GoblinChampionNPC.kt @@ -0,0 +1,101 @@ +package content.global.activity.cchallange.npc + +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.system.task.Pulse +import core.game.world.GameWorld +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +/** + * Represents the Goblin champion NPC for Champions challenge. + */ + +@Initializable +class GoblinChampionNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id, location) { + var clearTime = 0 + override fun construct(id: Int, location: Location, vararg objects: Any): AbstractNPC { + return GoblinChampionNPC(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.GOBLIN_CHAMPION_3060) + } + + override fun handleTickActions() { + super.handleTickActions() + if (clearTime++ > 288) poofClear(this) + } + + companion object { + fun spawnGoblinChampion(player: Player) { + val champion = GoblinChampionNPC(NPCs.GOBLIN_CHAMPION_3060) + champion.location = location(3170, 9758, 0) + champion.isWalks = true + champion.isAggressive = true + champion.isActive = false + + if (champion.asNpc() != null && champion.isActive) { + champion.properties.teleportLocation = champion.properties.spawnLocation + } + champion.isActive = true + GameWorld.Pulser.submit(object : Pulse(0, champion) { + override fun pulse(): Boolean { + champion.init() + registerHintIcon(player, champion) + champion.attack(player) + return true + } + }) + } + } + + override fun checkImpact(state: BattleState) { + super.checkImpact(state) + val player = state.attacker + if (player is Player) { + if (state.style == CombatStyle.MAGIC) { + state.neutralizeHits() + state.estimatedHit = state.maximumHit + } + if (state.style == CombatStyle.MELEE || state.style == CombatStyle.RANGE) { + sendMessage(player, "You can use only spells in this challenge.") + if (state.estimatedHit > -1) { + state.estimatedHit = 0 + return + } + if (state.secondaryHit > -1) { + state.secondaryHit = 0 + return + } + } + } + } + + override fun finalizeDeath(killer: Entity?) { + if (killer is Player) { + lock(killer, 2) + runTask(killer, 1) { + openInterface(killer, 63) + setInterfaceText(killer, "Well done, you defeated the Goblin Champion!", 63, 2) + killer.packetDispatch.sendItemZoomOnInterface(Items.CHAMPION_SCROLL_6801, 260, 63, 3) + setInterfaceText(killer, "128 Slayer Xp", 63, 6) + setInterfaceText(killer, "128 Hitpoint Xp", 63, 7) + } + setVarbit(killer, 1455, 1, true) + rewardXP(killer, Skills.HITPOINTS, 128.0) + rewardXP(killer, Skills.SLAYER, 128.0) + removeAttribute("championsarena:start") + clearHintIcon(killer) + } + clear() + super.finalizeDeath(killer) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/activity/cchallange/npc/HobgoblinChampionNPC.kt b/Server/src/main/content/global/activity/cchallange/npc/HobgoblinChampionNPC.kt new file mode 100644 index 0000000..01d0ffa --- /dev/null +++ b/Server/src/main/content/global/activity/cchallange/npc/HobgoblinChampionNPC.kt @@ -0,0 +1,103 @@ +package content.global.activity.cchallange.npc + +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.system.task.Pulse +import core.game.world.GameWorld +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +/** + * Represents the Hobgoblin champion NPC for Champions challenge. + */ + +@Initializable +class HobgoblinChampionNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id, location) { + var clearTime = 0 + override fun construct(id: Int, location: Location, vararg objects: Any): AbstractNPC { + return HobgoblinChampionNPC(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.HOBGOBLIN_CHAMPION_3061) + } + + + override fun handleTickActions() { + super.handleTickActions() + if (clearTime++ > 288) poofClear(this) + } + + companion object { + fun spawnHobgoblinChampion(player: Player) { + val champion = HobgoblinChampionNPC(NPCs.HOBGOBLIN_CHAMPION_3061) + champion.location = location(3170, 9758, 0) + champion.isWalks = true + champion.isAggressive = true + champion.isActive = false + + if (champion.asNpc() != null && champion.isActive) { + champion.properties.teleportLocation = champion.properties.spawnLocation + } + champion.isActive = true + GameWorld.Pulser.submit(object : Pulse(0, champion) { + override fun pulse(): Boolean { + champion.init() + registerHintIcon(player, champion) + champion.attack(player) + return true + } + }) + } + } + + override fun checkImpact(state: BattleState) { + super.checkImpact(state) + val player = state.attacker + if (player is Player) { + if (state.style == CombatStyle.MAGIC || state.style == CombatStyle.RANGE) { + state.neutralizeHits() + state.estimatedHit = state.maximumHit + } + + if (state.style == CombatStyle.MELEE) { + sendMessage(player, "You cannot use melee in this challenge.") + if (state.estimatedHit > -1) { + state.estimatedHit = 0 + return + } + if (state.secondaryHit > -1) { + state.secondaryHit = 0 + return + } + } + } + } + + override fun finalizeDeath(killer: Entity?) { + if (killer is Player) { + lock(killer, 2) + runTask(killer, 1) { + openInterface(killer, 63) + setInterfaceText(killer, "Well done, you defeated the Hobgoblin Champion!", 63, 2) + killer.packetDispatch.sendItemZoomOnInterface(Items.CHAMPION_SCROLL_6802, 260, 63, 3) + setInterfaceText(killer, "232 Slayer Xp", 63, 6) + setInterfaceText(killer, "232 Hitpoint Xp", 63, 7) + } + setVarbit(killer, 1456, 1, true) + rewardXP(killer, Skills.HITPOINTS, 232.0) + rewardXP(killer, Skills.SLAYER, 232.0) + removeAttribute("championsarena:start") + clearHintIcon(killer) + } + clear() + super.finalizeDeath(killer) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/activity/cchallange/npc/ImpChampionNPC.kt b/Server/src/main/content/global/activity/cchallange/npc/ImpChampionNPC.kt new file mode 100644 index 0000000..4a81fc0 --- /dev/null +++ b/Server/src/main/content/global/activity/cchallange/npc/ImpChampionNPC.kt @@ -0,0 +1,104 @@ +package content.global.activity.cchallange.npc + +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.combat.equipment.WeaponInterface +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.system.task.Pulse +import core.game.world.GameWorld +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +/** + * Represents the Imp champion NPC for Champions challenge. + */ + +@Initializable +class ImpChampionNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id, location) { + var clearTime = 0 + override fun construct(id: Int, location: Location, vararg objects: Any): AbstractNPC { + return ImpChampionNPC(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.IMP_CHAMPION_3062) + } + + override fun handleTickActions() { + super.handleTickActions() + if (clearTime++ > 288) poofClear(this) + } + + companion object { + fun spawnImpChampion(player: Player) { + val champion = ImpChampionNPC(NPCs.IMP_CHAMPION_3062) + champion.location = location(3170, 9758, 0) + champion.isWalks = true + champion.isAggressive = true + champion.isActive = false + + if (champion.asNpc() != null && champion.isActive) { + champion.properties.teleportLocation = champion.properties.spawnLocation + } + + champion.isActive = true + GameWorld.Pulser.submit(object : Pulse(0, champion) { + override fun pulse(): Boolean { + champion.init() + registerHintIcon(player, champion) + champion.attack(player) + return true + } + }) + } + } + + override fun checkImpact(state: BattleState) { + super.checkImpact(state) + val player = state.attacker + if (player is Player) { + val w = player.getExtension(WeaponInterface::class.java) + if (state.style == CombatStyle.MELEE || state.style == CombatStyle.MAGIC || state.style == CombatStyle.RANGE) { + state.neutralizeHits() + state.estimatedHit = state.maximumHit + } + if (w.weaponInterface.interfaceId == 10) { + sendMessage(player, "You cannot use special attack in this challenge.") + if (state.estimatedHit > -1) { + state.estimatedHit = 0 + return + } + if (state.secondaryHit > -1) { + state.secondaryHit = 0 + return + } + } + } + } + + override fun finalizeDeath(killer: Entity?) { + if (killer is Player) { + lock(killer, 2) + runTask(killer, 1) { + openInterface(killer, 63) + setInterfaceText(killer, "Well done, you defeated the Imp Champion!", 63, 2) + killer.packetDispatch.sendItemZoomOnInterface(Items.CHAMPION_SCROLL_6803, 260, 63, 3) + setInterfaceText(killer, "160 Slayer Xp", 63, 6) + setInterfaceText(killer, "160 Hitpoint Xp", 63, 7) + } + setVarbit(killer, 1457, 1, true) + rewardXP(killer, Skills.HITPOINTS, 160.0) + rewardXP(killer, Skills.SLAYER, 160.0) + removeAttribute("championsarena:start") + clearHintIcon(killer) + } + clear() + super.finalizeDeath(killer) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/activity/cchallange/npc/JogreChampionNPC.kt b/Server/src/main/content/global/activity/cchallange/npc/JogreChampionNPC.kt new file mode 100644 index 0000000..ad6889e --- /dev/null +++ b/Server/src/main/content/global/activity/cchallange/npc/JogreChampionNPC.kt @@ -0,0 +1,102 @@ +package content.global.activity.cchallange.npc + +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.combat.equipment.Weapon +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.system.task.Pulse +import core.game.world.GameWorld +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +/** + * Represents the Jogre champion NPC for Champions challenge. + */ + +@Initializable +class JogreChampionNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id, location) { + var clearTime = 0 + override fun construct(id: Int, location: Location, vararg objects: Any): AbstractNPC { + return JogreChampionNPC(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.JOGRE_CHAMPION_3063) + } + + override fun handleTickActions() { + super.handleTickActions() + if (clearTime++ > 288) poofClear(this) + } + + companion object { + fun spawnJogreChampion(player: Player) { + val champion = JogreChampionNPC(NPCs.JOGRE_CHAMPION_3063) + champion.location = location(3170, 9758, 0) + champion.isWalks = true + champion.isAggressive = true + champion.isActive = false + + if (champion.asNpc() != null && champion.isActive) { + champion.properties.teleportLocation = champion.properties.spawnLocation + } + champion.isActive = true + GameWorld.Pulser.submit(object : Pulse(0, champion) { + override fun pulse(): Boolean { + champion.init() + registerHintIcon(player, champion) + champion.attack(player) + return true + } + }) + } + } + + override fun checkImpact(state: BattleState) { + super.checkImpact(state) + val player = state.attacker + if (player is Player) { + if (state.style == CombatStyle.MAGIC || state.style == CombatStyle.MELEE) { + state.neutralizeHits() + state.estimatedHit = state.maximumHit + } + if (state.weapon.type == Weapon.WeaponType.DEGRADING || state.style == CombatStyle.RANGE) { + sendMessage(player, "You cannot use ranged weapons.") + if (state.estimatedHit > -1) { + state.estimatedHit = 0 + return + } + if (state.secondaryHit > -1) { + state.secondaryHit = 0 + return + } + } + } + } + + override fun finalizeDeath(killer: Entity?) { + if (killer is Player) { + lock(killer, 2) + runTask(killer, 1) { + openInterface(killer, 63) + setInterfaceText(killer, "Well done, you defeated the Jogre Champion!", 63, 2) + killer.packetDispatch.sendItemZoomOnInterface(Items.CHAMPION_SCROLL_6804, 260, 63, 3) + setInterfaceText(killer, "480 Slayer Xp", 63, 6) + setInterfaceText(killer, "480 Hitpoint Xp", 63, 7) + } + setVarbit(killer, 1458, 1, true) + rewardXP(killer, Skills.HITPOINTS, 480.0) + rewardXP(killer, Skills.SLAYER, 480.0) + removeAttribute("championsarena:start") + clearHintIcon(killer) + } + clear() + super.finalizeDeath(killer) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/activity/cchallange/npc/LesserDemonChampionNPC.kt b/Server/src/main/content/global/activity/cchallange/npc/LesserDemonChampionNPC.kt new file mode 100644 index 0000000..e62f73b --- /dev/null +++ b/Server/src/main/content/global/activity/cchallange/npc/LesserDemonChampionNPC.kt @@ -0,0 +1,102 @@ +package content.global.activity.cchallange.npc + +import core.api.* +import core.game.container.impl.EquipmentContainer +import core.game.global.action.EquipHandler +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.system.task.Pulse +import core.game.world.GameWorld +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +/** + * Represents the Lesser demon champion NPC for Champions challenge. + */ + +@Initializable +class LesserDemonChampionNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id, location) { + var clearTime = 0 + override fun construct(id: Int, location: Location, vararg objects: Any): AbstractNPC { + return LesserDemonChampionNPC(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.LESSER_DEMON_CHAMPION_3064) + } + + override fun handleTickActions() { + super.handleTickActions() + if (clearTime++ > 288) poofClear(this) + } + + companion object { + fun spawnLesserDemonChampion(player: Player) { + val champion = LesserDemonChampionNPC(NPCs.LESSER_DEMON_CHAMPION_3064) + champion.location = location(3170, 9758, 0) + champion.isWalks = true + champion.isAggressive = true + champion.isActive = false + + if (champion.asNpc() != null && champion.isActive) { + champion.properties.teleportLocation = champion.properties.spawnLocation + } + champion.isActive = true + GameWorld.Pulser.submit(object : Pulse(0, champion) { + override fun pulse(): Boolean { + champion.init() + registerHintIcon(player, champion) + champion.attack(player) + return true + } + }) + } + } + + override fun checkImpact(state: BattleState) { + super.checkImpact(state) + val player = state.attacker + if (player is Player) { + if (!player.equipment[3].hasItemPlugin()) { + state.neutralizeHits() + state.estimatedHit = state.maximumHit + } else { + EquipHandler.unequip(player, EquipmentContainer.SLOT_WEAPON, id) + sendMessage(player, "You cannot use weapons in this challenge.") + if (state.estimatedHit > -1) { + state.estimatedHit = 0 + return + } + if (state.secondaryHit > -1) { + state.secondaryHit = 0 + return + } + } + } + } + + override fun finalizeDeath(killer: Entity?) { + if (killer is Player) { + lock(killer, 2) + runTask(killer, 1) { + openInterface(killer, 63) + setInterfaceText(killer, "Well done, you defeated the Lesser Demon Champion!", 63, 2) + killer.packetDispatch.sendItemZoomOnInterface(Items.CHAMPION_SCROLL_6805, 260, 63, 3) + setInterfaceText(killer, "592 Slayer Xp", 63, 6) + setInterfaceText(killer, "592 Hitpoint Xp", 63, 7) + } + setVarbit(killer, 1459, 1, true) + rewardXP(killer, Skills.HITPOINTS, 592.0) + rewardXP(killer, Skills.SLAYER, 592.0) + removeAttribute("championsarena:start") + clearHintIcon(killer) + } + clear() + super.finalizeDeath(killer) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/activity/cchallange/npc/SkeletonChampionNPC.kt b/Server/src/main/content/global/activity/cchallange/npc/SkeletonChampionNPC.kt new file mode 100644 index 0000000..40a33a4 --- /dev/null +++ b/Server/src/main/content/global/activity/cchallange/npc/SkeletonChampionNPC.kt @@ -0,0 +1,103 @@ +package content.global.activity.cchallange.npc + +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.combat.equipment.Weapon +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.system.task.Pulse +import core.game.world.GameWorld +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +/** + * Represents the Skeleton champion NPC for Champions challenge. + */ + +@Initializable +class SkeletonChampionNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id, location) { + var clearTime = 0 + override fun construct(id: Int, location: Location, vararg objects: Any): AbstractNPC { + return SkeletonChampionNPC(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.SKELETON_CHAMPION_3065) + } + + override fun handleTickActions() { + super.handleTickActions() + if (clearTime++ > 288) poofClear(this) + } + + companion object { + fun spawnSkeletonChampion(player: Player) { + val champion = SkeletonChampionNPC(NPCs.SKELETON_CHAMPION_3065) + champion.location = location(3170, 9758, 0) + champion.isWalks = true + champion.isAggressive = true + champion.isActive = false + + if (champion.asNpc() != null && champion.isActive) { + champion.properties.teleportLocation = champion.properties.spawnLocation + } + champion.isActive = true + GameWorld.Pulser.submit(object : Pulse(0, champion) { + override fun pulse(): Boolean { + champion.init() + animate(champion, 259, true) + registerHintIcon(player, champion) + champion.attack(player) + return true + } + }) + } + } + + override fun checkImpact(state: BattleState) { + super.checkImpact(state) + val player = state.attacker + if (player is Player) { + if (state.style == CombatStyle.RANGE && state.weapon.type == Weapon.WeaponType.DEGRADING && state.weapon.type == Weapon.WeaponType.DOUBLE_SHOT) { + state.neutralizeHits() + state.estimatedHit = state.maximumHit + } + if (state.style == CombatStyle.MAGIC || state.style == CombatStyle.MELEE) { + sendMessage(player, "You can use only ranged weapons in this challenge.") + if (state.estimatedHit > -1) { + state.estimatedHit = 0 + return + } + if (state.secondaryHit > -1) { + state.secondaryHit = 0 + return + } + } + } + } + + override fun finalizeDeath(killer: Entity?) { + if (killer is Player) { + lock(killer, 2) + runTask(killer, 1) { + openInterface(killer, 63) + setInterfaceText(killer, "Well done, you defeated the Skeleton Champion!", 63, 2) + killer.packetDispatch.sendItemZoomOnInterface(Items.CHAMPION_SCROLL_6806, 260, 63, 3) + setInterfaceText(killer, "232 Slayer Xp", 63, 6) + setInterfaceText(killer, "232 Hitpoint Xp", 63, 7) + } + setVarbit(killer, 1460, 1, true) + rewardXP(killer, Skills.HITPOINTS, 232.0) + rewardXP(killer, Skills.SLAYER, 232.0) + removeAttribute("championsarena:start") + clearHintIcon(killer) + } + clear() + super.finalizeDeath(killer) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/activity/cchallange/npc/ZombieChampionNPC.kt b/Server/src/main/content/global/activity/cchallange/npc/ZombieChampionNPC.kt new file mode 100644 index 0000000..0be9eeb --- /dev/null +++ b/Server/src/main/content/global/activity/cchallange/npc/ZombieChampionNPC.kt @@ -0,0 +1,102 @@ +package content.global.activity.cchallange.npc + +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.system.task.Pulse +import core.game.world.GameWorld +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +/** + * Represents the Zombie champion NPC for Champions challenge. + */ + +@Initializable +class ZombieChampionNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id, location) { + var clearTime = 0 + override fun construct(id: Int, location: Location, vararg objects: Any): AbstractNPC { + return ZombieChampionNPC(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.ZOMBIES_CHAMPION_3066) + } + + override fun handleTickActions() { + super.handleTickActions() + if (clearTime++ > 288) poofClear(this) + } + + companion object { + fun spawnZombieChampion(player: Player) { + val champion = ZombieChampionNPC(NPCs.ZOMBIES_CHAMPION_3066) + champion.location = location(3170, 9758, 0) + champion.isWalks = true + champion.isAggressive = true + champion.isActive = false + + if (champion.asNpc() != null && champion.isActive) { + champion.properties.teleportLocation = champion.properties.spawnLocation + } + + champion.isActive = true + GameWorld.Pulser.submit(object : Pulse(0, champion) { + override fun pulse(): Boolean { + champion.init() + registerHintIcon(player, champion) + champion.attack(player) + return true + } + }) + } + } + + override fun checkImpact(state: BattleState) { + super.checkImpact(state) + val player = state.attacker + if (player is Player) { + if (state.style == CombatStyle.MELEE || state.style == CombatStyle.RANGE) { + state.estimatedHit = state.maximumHit + state.neutralizeHits() + } + if (state.style == CombatStyle.MAGIC) { + sendMessage(player, "You cannot use spells in this challenge.") + if (state.estimatedHit > -1) { + state.estimatedHit = 0 + return + } + if (state.secondaryHit > -1) { + state.secondaryHit = 0 + return + } + } + } + } + + override fun finalizeDeath(killer: Entity?) { + if (killer is Player) { + lock(killer, 2) + runTask(killer, 1) { + openInterface(killer, 63) + setInterfaceText(killer, "Well done, you defeated the Zombie Champion!", 63, 2) + killer.packetDispatch.sendItemZoomOnInterface(Items.CHAMPION_SCROLL_6807, 260, 63, 3) + setInterfaceText(killer, "240 Slayer Xp", 63, 6) + setInterfaceText(killer, "240 Hitpoint Xp", 63, 7) + } + setVarbit(killer, 1461, 1, true) + rewardXP(killer, Skills.HITPOINTS, 240.0) + rewardXP(killer, Skills.SLAYER, 240.0) + removeAttribute("championsarena:start") + clearHintIcon(killer) + } + clear() + super.finalizeDeath(killer) + } +} diff --git a/Server/src/main/content/global/activity/jobs/CheckJobDialogueFile.kt b/Server/src/main/content/global/activity/jobs/CheckJobDialogueFile.kt new file mode 100644 index 0000000..fc3a2e5 --- /dev/null +++ b/Server/src/main/content/global/activity/jobs/CheckJobDialogueFile.kt @@ -0,0 +1,174 @@ +package content.global.activity.jobs + +import content.global.activity.jobs.impl.BoneBuryingJobs +import content.global.activity.jobs.impl.CombatJobs +import content.global.activity.jobs.impl.ProductionJobs +import core.api.addItem +import core.api.amountInInventory +import core.api.hasAnItem +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.dialogue.IfTopic +import core.game.dialogue.Topic +import core.game.node.entity.npc.NPC +import core.game.node.item.Item +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import core.tools.StringUtils +import org.rs09.consts.Items + +/** + * The dialogue file to handle a player asking about work with the employer that assigned them + * their current job. + */ +class CheckJobDialogueFile : DialogueFile() { + companion object { + const val TURN_IN_ITEMS_1 = 1 + const val TURN_IN_ITEMS_2 = 2 + const val TURN_IN_ITEMS_3 = 3 + const val TURN_IN_ITEMS_4 = 4 + const val TURN_IN_ITEMS_5 = 5 + const val REMIND_JOB = 101 + const val GET_TASK_LIST = 201 + const val GET_NEW_JOB_1 = 301 + const val GET_NEW_JOB_2 = 302 + const val GET_NEW_JOB_3 = 303 + const val GET_NEW_JOB_4 = 304 + const val GET_NEW_JOB_5 = 305 + const val GET_NEW_JOB_NONE = 306 + const val GET_NEW_JOB_REACHED_LIMIT = 307 + } + + override fun handle(componentID: Int, buttonID: Int) { + val playerJobManager: JobManager = JobManager.getInstance(player!!) + val job = playerJobManager.job ?: return + val originalAmount = playerJobManager.jobOriginalAmount + + when (stage) { + START_DIALOGUE -> showTopics( + IfTopic( + FacialExpression.HAPPY, + "I have the items you wanted.", + TURN_IN_ITEMS_1, + (job.type == JobType.PRODUCTION && amountInInventory(player!!, (job as ProductionJobs).itemId) > 0) + ), Topic( + FacialExpression.HALF_ASKING, "Can you remind me what job you gave me?", REMIND_JOB + ), Topic( + FacialExpression.HALF_ASKING, "Can I have a task list to remind me of my job?", GET_TASK_LIST + ), Topic( + FacialExpression.HALF_GUILTY, "I'd like a new job please.", GET_NEW_JOB_1 + ) + ) + + TURN_IN_ITEMS_1 -> { + job as ProductionJobs + val itemName = Item(job.itemId).name.lowercase() + val itemNamePluralized = if (playerJobManager.jobAmount > 1) StringUtils.plusS(itemName) else itemName + npcl("Splendid! Now, I needed $originalAmount $itemNamePluralized.") + stage = TURN_IN_ITEMS_2 + } + + TURN_IN_ITEMS_2 -> { + if (playerJobManager.jobAmount == originalAmount) { + npcl("So far, you haven't brought me any, so I'm waiting for ${playerJobManager.jobAmount}.") + } else { + npcl("So far, you have brought me ${originalAmount - playerJobManager.jobAmount}, so I'm waiting for ${playerJobManager.jobAmount}.") + } + stage = TURN_IN_ITEMS_3 + } + + TURN_IN_ITEMS_3 -> { + if (amountInInventory(player!!, (job as ProductionJobs).itemId) >= playerJobManager.jobAmount) { + npcl("I can see that you have plenty, would you like to hand some over to complete your job?") + } else { + npcl("I can see that you have some, would you like to hand them over?") + } + stage = TURN_IN_ITEMS_4 + } + + TURN_IN_ITEMS_4 -> showTopics( + Topic("Yes, I'll give you what I have.", TURN_IN_ITEMS_5, skipPlayer = true), + Topic("No, I'll keep hold of it for now.", END_DIALOGUE, skipPlayer = true) + ) + + TURN_IN_ITEMS_5 -> { + playerJobManager.turnInItems() + + if (playerJobManager.jobAmount == 0) { + playerJobManager.rewardPlayer() + npcl("There you go, thanks for your help. You're quite a skilled worker!") + } else { + npcl("Thanks for your help. Come back when you've got more!") + } + stage = END_DIALOGUE + } + + REMIND_JOB -> { + when (job.type) { + JobType.PRODUCTION -> { + job as ProductionJobs + val itemName = Item(job.itemId).name.lowercase() + val itemNamePluralized = + if (playerJobManager.jobAmount > 1) StringUtils.plusS(itemName) else itemName + npcl("You still need to gather ${playerJobManager.jobAmount} more $itemNamePluralized.") + } + + JobType.BONE_BURYING -> { + job as BoneBuryingJobs + val boneName = Item(job.boneIds.first()).name.lowercase() + val boneNamePluralized = + if (playerJobManager.jobAmount > 1) StringUtils.plusS(boneName) else boneName + npcl("You still need to bury ${playerJobManager.jobAmount} more $boneNamePluralized in the ${job.buryArea.title}.") + } + + JobType.COMBAT -> { + job as CombatJobs + val monsterName = NPC(job.monsterIds.first()).name.lowercase() + val monsterNamePluralized = + if (playerJobManager.jobAmount > 1) StringUtils.plusS(monsterName) else monsterName + npcl("You still need to kill ${playerJobManager.jobAmount} more $monsterNamePluralized.") + } + } + stage = END_DIALOGUE + } + + GET_TASK_LIST -> { + if (hasAnItem(player!!, Items.TASK_LIST_13464).exists()) { + npcl("You already have one of those!") + } else { + when (addItem(player!!, Items.TASK_LIST_13464)) { + true -> npcl("Here you go then.") + false -> dialogue("You don't have enough space in your inventory.") + } + } + + stage = END_DIALOGUE + } + + GET_NEW_JOB_1 -> npcl("Let me see if I've got any work for you.").also { + if (playerJobManager.hasReachedJobLimit()) { + stage = GET_NEW_JOB_REACHED_LIMIT + } else { + playerJobManager.generate(npc!!) + stage = if (playerJobManager.hasJob()) GET_NEW_JOB_2 else GET_NEW_JOB_NONE + } + } + + GET_NEW_JOB_2 -> npcl(playerJobManager.getAssignmentMessage()).also { stage = GET_NEW_JOB_3 } + // Historically, the player would also have the option to ask for an easier task + GET_NEW_JOB_3 -> playerl("Okay, off I go!").also { stage = GET_NEW_JOB_4 } + GET_NEW_JOB_4 -> npcl("There, I've updated your task list to show your new job. Best of luck!").also { + stage = GET_NEW_JOB_5 + } + + GET_NEW_JOB_5 -> playerl("Thanks.").also { stage = END_DIALOGUE } + GET_NEW_JOB_NONE -> npcl("I'm sorry, I don't currently have any jobs that you're qualified for.").also { + stage = END_DIALOGUE + } + + GET_NEW_JOB_REACHED_LIMIT -> npcl("You've hit your limit for the day. Come back tomorrow!").also { + stage = END_DIALOGUE + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/activity/jobs/Job.kt b/Server/src/main/content/global/activity/jobs/Job.kt new file mode 100644 index 0000000..f455832 --- /dev/null +++ b/Server/src/main/content/global/activity/jobs/Job.kt @@ -0,0 +1,23 @@ +package content.global.activity.jobs + +import content.global.activity.jobs.impl.Employers +import core.tools.RandomFunction + +/** + * The interface for a job that a player can be assigned. + * + * TODO: Once player data is stored in a database with support for migrations, implement a per-player field to store + * the player's current employer, so that multiple employers can assign the same job, but the player will only be + * able to turn the job into the employer that assigned it to them. + */ +interface Job { + val type: JobType + val lower: Int + val upper: Int + + val employer: Employers + + fun getAmount(): Int { + return RandomFunction.random(lower, upper + 1) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/activity/jobs/JobManager.kt b/Server/src/main/content/global/activity/jobs/JobManager.kt new file mode 100644 index 0000000..001aeae --- /dev/null +++ b/Server/src/main/content/global/activity/jobs/JobManager.kt @@ -0,0 +1,215 @@ +package content.global.activity.jobs + +import content.global.activity.jobs.impl.BoneBuryingJobs +import content.global.activity.jobs.impl.CombatJobs +import content.global.activity.jobs.impl.ProductionJobs +import core.ServerStore +import core.ServerStore.Companion.getInt +import core.api.* +import core.game.event.BoneBuryEvent +import core.game.event.EventHook +import core.game.event.JobAssignmentEvent +import core.game.event.NPCKillEvent +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.tools.StringUtils +import org.json.simple.JSONObject +import org.rs09.consts.Items +import java.lang.Integer.min + +/** + * Manages the player's job data & progression. + * + * @source https://runescape.wiki/w/Jobs?oldid=831782 + */ +class JobManager(val player: Player? = null) : LoginListener, PersistPlayer { + var job: Job? = null + var jobAmount: Int = 0 + var jobOriginalAmount: Int = 0 + + private fun hasLevelRequirement(job: ProductionJobs): Boolean { + if (player == null) return false + if (player.isArtificial) return false + + return getStatLevel(player, job.skill) >= job.lvlReq + } + + fun hasJob(): Boolean = this.job != null + + // Historically the job limit would be 6 jobs per hour of play-time, using 3 per day for balance purposes + fun hasReachedJobLimit(): Boolean = player?.let { getStoreFile().getInt(it.username.lowercase()) >= 3 } ?: false + + fun generate(npc: NPC) { + if (player == null) return + if (player.isArtificial) return + + val instance = getInstance(player) + + // Create a list of jobs that the player can do and are given by the NPC being interacted with + val potentialJobs: List = ( + ProductionJobs.values().filter { hasLevelRequirement(it) } + + BoneBuryingJobs.values() + + CombatJobs.values() + ) + .filter { job -> job.employer.npcId == npc.id } + + val job = potentialJobs.randomOrNull() ?: return + + instance.job = job + this.jobAmount = job.getAmount() + this.jobOriginalAmount = instance.jobAmount + + player.dispatch(JobAssignmentEvent(job.type, npc)) + getStoreFile()[player.username.lowercase()] = getStoreFile().getInt(player.username.lowercase()) + 1 + } + + fun getAssignmentMessage(): String? { + if (player == null) return null + if (player.isArtificial) return null + + val instance = getInstance(player) + val job = instance.job ?: return null + + return when (job.type) { + JobType.PRODUCTION -> { + job as ProductionJobs + val itemName = Item(job.itemId).name.lowercase() + val itemNamePluralized = if (this.jobAmount > 1) StringUtils.plusS(itemName) else itemName + "Okay, your job is to bring me ${this.jobAmount} $itemNamePluralized." + } + + JobType.BONE_BURYING -> { + job as BoneBuryingJobs + val boneName = Item(job.boneIds.first()).name.lowercase() + val boneNamePluralized = if (this.jobAmount > 1) StringUtils.plusS(boneName) else boneName + "Okay, your job is to bury ${this.jobAmount} $boneNamePluralized in the ${job.buryArea.title}." + } + + JobType.COMBAT -> { + job as CombatJobs + val monsterName = NPC(job.monsterIds.first()).name.lowercase() + val monsterNamePluralized = if (this.jobAmount > 1) StringUtils.plusS(monsterName) else monsterName + "Okay, your job is to kill ${this.jobAmount} $monsterNamePluralized." + } + } + } + + /** + * TODO: Allow players to turn-in noted items (authentic to 2009) + */ + fun turnInItems() { + if (player == null) return + if (player.isArtificial) return + + val instance = getInstance(player) + val job = instance.job ?: return + if (job.type != JobType.PRODUCTION) return + + val itemId = (job as ProductionJobs).itemId + val amountHeld = amountInInventory(player, itemId) + val amountToTurnIn = min(amountHeld, instance.jobAmount) + removeItem(player, Item(itemId, amountToTurnIn)) + instance.jobAmount -= amountToTurnIn + } + + fun rewardPlayer() { + if (player == null) return + if (player.isArtificial) return + + val instance = getInstance(player) + + addItemOrDrop(player, Items.COINS_995, 250 * instance.jobOriginalAmount) + + instance.job = null + instance.jobAmount = -1 + instance.jobOriginalAmount = -1 + } + + override fun login(player: Player) { + if (player.isArtificial) return + + val jobManager = JobManager(player) + setAttribute(player, "job-manager", jobManager) + + player.hook(Event.BoneBuried, object : EventHook { + override fun process(entity: Entity, event: BoneBuryEvent) { + if (entity !is Player) return + if (entity.isArtificial) return + + val instance = getInstance(entity) + + if (!instance.hasJob()) return + if (instance.job?.type != JobType.BONE_BURYING) return + if (instance.jobAmount == 0) return + + val job = (instance.job as BoneBuryingJobs) + if (inBorders(entity, job.buryArea.zoneBorder) && event.boneId in job.boneIds) { + instance.jobAmount-- + } + } + }) + player.hook(Event.NPCKilled, object : EventHook { + override fun process(entity: Entity, event: NPCKillEvent) { + if (entity !is Player) return + if (entity.isArtificial) return + + val instance = getInstance(entity) + + if (!instance.hasJob()) return + if (instance.job?.type != JobType.COMBAT) return + if (instance.jobAmount == 0) return + + val job = (instance.job as CombatJobs) + if (event.npc.id in job.monsterIds) { + instance.jobAmount-- + } + } + }) + } + + // TODO: Implement proper saving of job data to JSONObject once player save migration is possible + override fun savePlayer(player: Player, save: JSONObject) { + val instance = getInstance(player) + val jobId: Int = instance.job?.let { + when (it.type) { + JobType.PRODUCTION -> ProductionJobs.values().indexOf(it) + JobType.COMBAT -> CombatJobs.values().indexOf(it) + JobType.BONE_BURYING -> BoneBuryingJobs.values().indexOf(it) + } + } ?: -1 + + setAttribute(player, "/save:jobs:id", jobId) + setAttribute(player, "/save:jobs:type", instance.job?.type?.ordinal ?: -1) + setAttribute(player, "/save:jobs:amount", instance.jobAmount) + setAttribute(player, "/save:jobs:original_amount", instance.jobOriginalAmount) + } + + // TODO: Implement proper loading of job data from JSONObject once player save migration is possible + override fun parsePlayer(player: Player, data: JSONObject) { + val instance = getInstance(player) + val jobId = getAttribute(player, "jobs:id", -1) + val jobType = getAttribute(player, "jobs:type", -1) + + instance.job = when (JobType.values().getOrNull(jobType)) { + JobType.PRODUCTION -> ProductionJobs.values().getOrNull(jobId) + JobType.COMBAT -> CombatJobs.values().getOrNull(jobId) + JobType.BONE_BURYING -> BoneBuryingJobs.values().getOrNull(jobId) + else -> null + } + instance.jobAmount = getAttribute(player, "jobs:amount", -1) + instance.jobOriginalAmount = getAttribute(player, "jobs:original_amount", -1) + } + + companion object { + @JvmStatic + fun getInstance(player: Player): JobManager { + return player.getAttribute("job-manager", JobManager(player)) + } + + fun getStoreFile(): JSONObject { + return ServerStore.getArchive("daily-jobs-tracking") + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/activity/jobs/JobType.kt b/Server/src/main/content/global/activity/jobs/JobType.kt new file mode 100644 index 0000000..c34a678 --- /dev/null +++ b/Server/src/main/content/global/activity/jobs/JobType.kt @@ -0,0 +1,13 @@ +package content.global.activity.jobs + +/** + * An enum of the different types of jobs that a player can be assigned. + * + * Note: Due to how player save files keep track of the player's current job, it is essential that + * new entries are only appended to the end of this enum, and the ordering of existing entries is not changed. + */ +enum class JobType { + PRODUCTION, + COMBAT, + BONE_BURYING +} \ No newline at end of file diff --git a/Server/src/main/content/global/activity/jobs/StartJobDialogueFile.kt b/Server/src/main/content/global/activity/jobs/StartJobDialogueFile.kt new file mode 100644 index 0000000..b431663 --- /dev/null +++ b/Server/src/main/content/global/activity/jobs/StartJobDialogueFile.kt @@ -0,0 +1,139 @@ +package content.global.activity.jobs + +import content.global.activity.jobs.impl.BoneBuryingJobs +import content.global.activity.jobs.impl.CombatJobs +import content.global.activity.jobs.impl.ProductionJobs +import core.api.addItem +import core.api.hasAnItem +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.npc.NPC +import core.game.node.item.Item +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import core.tools.StringUtils +import org.rs09.consts.Items + +/** + * The dialogue file to handle a player asking about work with any employer which they aren't currently working for. + */ +class StartJobDialogueFile : DialogueFile() { + companion object { + const val GET_TASK_LIST_1 = 1 + const val GET_TASK_LIST_2 = 2 + const val GET_TASK_LIST_YES = 3 + const val GET_JOB_1 = 101 + const val GET_JOB_2 = 102 + const val GET_JOB_3 = 103 + const val GET_JOB_4 = 104 + const val GET_JOB_5 = 105 + const val GET_JOB_NONE = 201 + const val GET_JOB_EMPLOYED_1 = 301 + const val GET_JOB_EMPLOYED_2 = 302 + const val GET_JOB_LIMIT_REACHED = 401 + } + + override fun handle(componentID: Int, buttonID: Int) { + val playerJobManager: JobManager = JobManager.getInstance(player!!) + + when (stage) { + START_DIALOGUE -> playerl(FacialExpression.ASKING, "Do you have any jobs for me?").also { + stage = if (hasAnItem(player!!, Items.TASK_LIST_13464).exists()) { + if (playerJobManager.hasJob()) { + GET_JOB_EMPLOYED_1 + } else { + GET_JOB_1 + } + } else { + GET_TASK_LIST_1 + } + } + + GET_TASK_LIST_1 -> npcl("Well, first of all, I can see that you don't have a task list to remind you about your current job. Would you like a task list now?").also { + stage = GET_TASK_LIST_2 + } + + GET_TASK_LIST_2 -> showTopics( + Topic("Yes, please.", GET_TASK_LIST_YES), + Topic("No, thanks.", if (playerJobManager.hasJob()) GET_JOB_EMPLOYED_1 else GET_JOB_1) + ) + + GET_TASK_LIST_YES -> { + when (addItem(player!!, Items.TASK_LIST_13464)) { + true -> npcl("Here you go then.").also { + stage = if (playerJobManager.hasJob()) GET_JOB_EMPLOYED_1 else GET_JOB_1 + } + + false -> dialogue("You don't have enough space in your inventory.").also { stage = END_DIALOGUE } + } + } + + GET_JOB_1 -> npcl("Let me see if I've got any work for you.").also { + if (playerJobManager.hasReachedJobLimit()) { + stage = GET_JOB_LIMIT_REACHED + } else { + playerJobManager.generate(npc!!) + stage = if (playerJobManager.hasJob()) GET_JOB_2 else GET_JOB_NONE + } + } + + GET_JOB_2 -> npcl(playerJobManager.getAssignmentMessage()).also { stage = GET_JOB_3 } + // Historically, the player would also have the option to ask for an easier task + GET_JOB_3 -> playerl("Okay, off I go!").also { stage = GET_JOB_4 } + GET_JOB_4 -> npcl("There, I've updated your task list to show your new job. Best of luck!").also { + stage = GET_JOB_5 + } + + GET_JOB_5 -> playerl("Thanks.").also { stage = END_DIALOGUE } + GET_JOB_EMPLOYED_1 -> { + val job = playerJobManager.job ?: return + val employerName = NPC(job.employer.npcId).name + val amount = playerJobManager.jobAmount + val originalAmount = playerJobManager.jobOriginalAmount + + if (amount == 0) { + npcl("Hang about. Aren't you working for $employerName? It looks like you've complete their job, return to them for your reward.") + stage = END_DIALOGUE + } else { + when (job.type) { + JobType.PRODUCTION -> { + job as ProductionJobs + val itemName = Item(job.itemId).name.lowercase() + val itemNamePluralized = if (originalAmount > 1) StringUtils.plusS(itemName) else itemName + npcl("Hang about. Aren't you working for $employerName? You were asked for $originalAmount $itemNamePluralized and still have $amount more to go.") + } + + JobType.BONE_BURYING -> { + job as BoneBuryingJobs + val boneName = Item(job.boneIds.first()).name.lowercase() + val boneNamePluralized = if (originalAmount > 1) StringUtils.plusS(boneName) else boneName + npcl("Hang about. Aren't you working for $employerName? You were asked to bury $originalAmount $boneNamePluralized in the ${job.buryArea.title} and still have $amount more to go.") + } + + JobType.COMBAT -> { + job as CombatJobs + val monsterName = NPC(job.monsterIds.first()).name.lowercase() + val monsterNamePluralized = if (originalAmount > 1) StringUtils.plusS(monsterName) else monsterName + npcl("Hang about. Aren't you working for $employerName? You were asked to kill $originalAmount $monsterNamePluralized and still have $amount more to go.") + } + } + stage = GET_JOB_EMPLOYED_2 + } + } + + GET_JOB_EMPLOYED_2 -> showTopics( + Topic("Oh yes. I better go and finish their job first.", END_DIALOGUE), + Topic("I'd like a new job instead, please.", GET_JOB_1) + ) + + GET_JOB_NONE -> npcl("I'm sorry, I don't currently have any jobs that you're qualified for.").also { + stage = END_DIALOGUE + } + + GET_JOB_LIMIT_REACHED -> npcl("You've hit your limit for the day. Come back tomorrow!").also { + stage = END_DIALOGUE + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/activity/jobs/TaskListReadListener.kt b/Server/src/main/content/global/activity/jobs/TaskListReadListener.kt new file mode 100644 index 0000000..2e3c06d --- /dev/null +++ b/Server/src/main/content/global/activity/jobs/TaskListReadListener.kt @@ -0,0 +1,70 @@ +package content.global.activity.jobs + +import content.global.activity.jobs.impl.BoneBuryingJobs +import content.global.activity.jobs.impl.CombatJobs +import content.global.activity.jobs.impl.ProductionJobs +import core.api.sendDialogue +import core.api.sendItemDialogue +import core.api.sendNPCDialogue +import core.game.interaction.InteractionListener +import core.game.node.entity.npc.NPC +import core.game.node.item.Item +import core.tools.StringUtils +import org.rs09.consts.Items + +/** + * Handles the read option of the Task List item. + */ +class TaskListReadListener : InteractionListener { + override fun defineListeners() { + on(Items.TASK_LIST_13464, ITEM, "read") { player, _ -> + val playerJobManager: JobManager = JobManager.getInstance(player) + val job = playerJobManager.job + val amount = playerJobManager.jobAmount + + if (job == null) { + sendDialogue(player, "I have not been assigned a job!") + return@on false + } + + if(amount == 0) { + sendDialogue( + player, "I have completed my job. I should return to ${NPC(job.employer.npcId).name} for my reward." + ) + return@on true + } + + when (job.type) { + JobType.PRODUCTION -> { + job as ProductionJobs + val itemName = Item(job.itemId).name.lowercase() + val itemNamePluralized = if (amount > 1) StringUtils.plusS(itemName) else itemName + sendItemDialogue( + player, job.itemId, "My job is to gather $amount more $itemNamePluralized." + ) + } + + JobType.BONE_BURYING -> { + job as BoneBuryingJobs + val boneName = Item(job.boneIds.first()).name.lowercase() + val boneNamePluralized = if (amount > 1) StringUtils.plusS(boneName) else boneName + sendItemDialogue( + player, + job.boneIds.first(), + "My job is to bury $amount more $boneNamePluralized in the ${job.buryArea.title}." + ) + } + + JobType.COMBAT -> { + job as CombatJobs + val monsterName = NPC(job.monsterIds.first()).name.lowercase() + val monsterNamePluralized = if (amount > 1) StringUtils.plusS(monsterName) else monsterName + sendNPCDialogue( + player, job.monsterIds.first(), "My job is to kill $amount more $monsterNamePluralized." + ) + } + } + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/activity/jobs/WorkForInteractionListener.kt b/Server/src/main/content/global/activity/jobs/WorkForInteractionListener.kt new file mode 100644 index 0000000..8d09d7d --- /dev/null +++ b/Server/src/main/content/global/activity/jobs/WorkForInteractionListener.kt @@ -0,0 +1,45 @@ +package content.global.activity.jobs + +import content.global.activity.jobs.impl.Employers +import core.api.openDialogue +import core.api.sendNPCDialogue +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.npc.NPC + +/** + * Handles the work-for actions for the NPCs + * @author Ceikry + * @author vddCore + */ +class WorkForInteractionListener : InteractionListener { + override fun defineListeners() { + on( + Employers.values().map { employer -> employer.npcId }.toIntArray(), + IntType.NPC, + "work-for" + ) { player, node -> + val playerJobManager = JobManager.getInstance(player) + val job = playerJobManager.job + + // Check if the player is talking to the NPC that gave them their job + if (job != null && job.employer.npcId == node.id) { + if (playerJobManager.jobAmount == 0) { + playerJobManager.rewardPlayer() + sendNPCDialogue( + player, + job.employer.npcId, + "There you go, thanks for your help. You're quite a skilled worker!" + ) + } else { + openDialogue(player, CheckJobDialogueFile(), node as NPC) + } + + return@on true + } + + openDialogue(player, StartJobDialogueFile(), node as NPC) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/activity/jobs/impl/BoneBuryingJobs.kt b/Server/src/main/content/global/activity/jobs/impl/BoneBuryingJobs.kt new file mode 100644 index 0000000..fad0448 --- /dev/null +++ b/Server/src/main/content/global/activity/jobs/impl/BoneBuryingJobs.kt @@ -0,0 +1,30 @@ +package content.global.activity.jobs.impl + +import content.global.activity.jobs.Job +import content.global.activity.jobs.JobType +import core.game.world.map.zone.ZoneBorders +import org.rs09.consts.Items + +/** + * An enum of the possible bone-burying jobs that can be assigned to a player. + * + * Note: Due to how player save files keep track of the player's current job, it is essential that + * new entries are only appended to the end of this enum, and the ordering of existing entries is not changed. + */ +enum class BoneBuryingJobs(val buryArea: BuryArea, val boneIds: List, override val employer: Employers) : Job { + BURY_DRAYNOR(BuryArea.DRAYNOR_WHEAT_FIELD, Bones.BONES, Employers.PRAYER_TUTOR), + BURY_LUMBRIDGE_GRAVEYARD(BuryArea.LUMBRIDGE_GRAVEYARD, Bones.BONES, Employers.PRAYER_TUTOR); + + override val type = JobType.BONE_BURYING + override val lower = 22 + override val upper = 26 + + enum class BuryArea(val zoneBorder: ZoneBorders, val title: String) { + DRAYNOR_WHEAT_FIELD(ZoneBorders(3107, 3265, 3132, 3293), "wheat field east of Draynor Village"), + LUMBRIDGE_GRAVEYARD(ZoneBorders(3238, 3191, 3252, 3204), "Lumbridge Graveyard"); + } + + object Bones { + val BONES = listOf(Items.BONES_526, Items.BONES_2530) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/activity/jobs/impl/CombatJobs.kt b/Server/src/main/content/global/activity/jobs/impl/CombatJobs.kt new file mode 100644 index 0000000..cfe444f --- /dev/null +++ b/Server/src/main/content/global/activity/jobs/impl/CombatJobs.kt @@ -0,0 +1,209 @@ +package content.global.activity.jobs.impl + +import content.global.activity.jobs.Job +import content.global.activity.jobs.JobType +import org.rs09.consts.NPCs + +/** + * An enum of the possible combat jobs that can be assigned to a player. + * + * Note: Due to how player save files keep track of the player's current job, it is essential that + * new entries are only appended to the end of this enum, and the ordering of existing entries is not changed. + */ +enum class CombatJobs(val monsterIds: List, override val employer: Employers) : Job { + CHICKENS(Monsters.CHICKENS, Employers.RANGED_TUTOR), + COWS(Monsters.COWS, Employers.MAGIC_TUTOR), + GIANT_SPIDERS(Monsters.GIANT_SPIDERS, Employers.MAGIC_TUTOR), + SCORPIONS(Monsters.SCORPIONS, Employers.MELEE_TUTOR), + GOBLINS(Monsters.GOBLINS, Employers.MELEE_TUTOR); + + override val type = JobType.COMBAT + override val lower = 22 + override val upper = 28 + + object Monsters { + val GIANT_SPIDERS = listOf(NPCs.GIANT_SPIDER_59, NPCs.GIANT_SPIDER_60) + val SCORPIONS = listOf(NPCs.SCORPION_107, NPCs.SCORPION_1477, NPCs.SCORPION_4402, NPCs.SCORPION_4403) + val GOBLINS = listOf( + NPCs.GOBLIN_100, + NPCs.GOBLIN_101, + NPCs.GOBLIN_102, + NPCs.GOBLIN_1769, + NPCs.GOBLIN_1770, + NPCs.GOBLIN_1771, + NPCs.GOBLIN_1772, + NPCs.GOBLIN_1773, + NPCs.GOBLIN_1774, + NPCs.GOBLIN_1775, + NPCs.GOBLIN_1776, + NPCs.GOBLIN_2274, + NPCs.GOBLIN_2275, + NPCs.GOBLIN_2276, + NPCs.GOBLIN_2277, + NPCs.GOBLIN_2278, + NPCs.GOBLIN_2279, + NPCs.GOBLIN_2280, + NPCs.GOBLIN_2281, + NPCs.GOBLIN_2678, + NPCs.GOBLIN_2679, + NPCs.GOBLIN_2680, + NPCs.GOBLIN_2681, + NPCs.GOBLIN_3264, + NPCs.GOBLIN_3265, + NPCs.GOBLIN_3266, + NPCs.GOBLIN_3267, + NPCs.GOBLIN_3726, + NPCs.GOBLIN_4261, + NPCs.GOBLIN_4262, + NPCs.GOBLIN_4263, + NPCs.GOBLIN_4264, + NPCs.GOBLIN_4265, + NPCs.GOBLIN_4266, + NPCs.GOBLIN_4267, + NPCs.GOBLIN_4268, + NPCs.GOBLIN_4269, + NPCs.GOBLIN_4270, + NPCs.GOBLIN_4271, + NPCs.GOBLIN_4272, + NPCs.GOBLIN_4273, + NPCs.GOBLIN_4274, + NPCs.GOBLIN_4275, + NPCs.GOBLIN_4276, + NPCs.GOBLIN_4407, + NPCs.GOBLIN_4408, + NPCs.GOBLIN_4409, + NPCs.GOBLIN_4410, + NPCs.GOBLIN_4411, + NPCs.GOBLIN_4412, + NPCs.GOBLIN_444, + NPCs.GOBLIN_445, + NPCs.GOBLIN_4479, + NPCs.GOBLIN_4480, + NPCs.GOBLIN_4481, + NPCs.GOBLIN_4482, + NPCs.GOBLIN_4483, + NPCs.GOBLIN_4484, + NPCs.GOBLIN_4485, + NPCs.GOBLIN_4486, + NPCs.GOBLIN_4487, + NPCs.GOBLIN_4488, + NPCs.GOBLIN_4489, + NPCs.GOBLIN_4490, + NPCs.GOBLIN_4491, + NPCs.GOBLIN_4492, + NPCs.GOBLIN_4499, + NPCs.GOBLIN_4633, + NPCs.GOBLIN_4634, + NPCs.GOBLIN_4635, + NPCs.GOBLIN_4636, + NPCs.GOBLIN_4637, + NPCs.GOBLIN_5855, + NPCs.GOBLIN_5856, + NPCs.GOBLIN_6125, + NPCs.GOBLIN_6126, + NPCs.GOBLIN_6132, + NPCs.GOBLIN_6133, + NPCs.GOBLIN_6279, + NPCs.GOBLIN_6280, + NPCs.GOBLIN_6281, + NPCs.GOBLIN_6282, + NPCs.GOBLIN_6283, + NPCs.GOBLIN_6284, + NPCs.GOBLIN_6402, + NPCs.GOBLIN_6403, + NPCs.GOBLIN_6404, + NPCs.GOBLIN_6405, + NPCs.GOBLIN_6406, + NPCs.GOBLIN_6407, + NPCs.GOBLIN_6408, + NPCs.GOBLIN_6409, + NPCs.GOBLIN_6410, + NPCs.GOBLIN_6411, + NPCs.GOBLIN_6412, + NPCs.GOBLIN_6413, + NPCs.GOBLIN_6414, + NPCs.GOBLIN_6415, + NPCs.GOBLIN_6416, + NPCs.GOBLIN_6417, + NPCs.GOBLIN_6418, + NPCs.GOBLIN_6419, + NPCs.GOBLIN_6420, + NPCs.GOBLIN_6421, + NPCs.GOBLIN_6422, + NPCs.GOBLIN_6423, + NPCs.GOBLIN_6424, + NPCs.GOBLIN_6425, + NPCs.GOBLIN_6426, + NPCs.GOBLIN_6427, + NPCs.GOBLIN_6428, + NPCs.GOBLIN_6429, + NPCs.GOBLIN_6430, + NPCs.GOBLIN_6431, + NPCs.GOBLIN_6432, + NPCs.GOBLIN_6433, + NPCs.GOBLIN_6434, + NPCs.GOBLIN_6435, + NPCs.GOBLIN_6436, + NPCs.GOBLIN_6437, + NPCs.GOBLIN_6438, + NPCs.GOBLIN_6439, + NPCs.GOBLIN_6440, + NPCs.GOBLIN_6441, + NPCs.GOBLIN_6442, + NPCs.GOBLIN_6443, + NPCs.GOBLIN_6444, + NPCs.GOBLIN_6445, + NPCs.GOBLIN_6446, + NPCs.GOBLIN_6447, + NPCs.GOBLIN_6448, + NPCs.GOBLIN_6449, + NPCs.GOBLIN_6450, + NPCs.GOBLIN_6451, + NPCs.GOBLIN_6452, + NPCs.GOBLIN_6453, + NPCs.GOBLIN_6454, + NPCs.GOBLIN_6455, + NPCs.GOBLIN_6456, + NPCs.GOBLIN_6457, + NPCs.GOBLIN_6458, + NPCs.GOBLIN_6459, + NPCs.GOBLIN_6460, + NPCs.GOBLIN_6461, + NPCs.GOBLIN_6462, + NPCs.GOBLIN_6463, + NPCs.GOBLIN_6464, + NPCs.GOBLIN_6465, + NPCs.GOBLIN_6466, + NPCs.GOBLIN_6467, + NPCs.GOBLIN_6490, + NPCs.GOBLIN_6491, + NPCs.GOBLIN_6492, + NPCs.GOBLIN_6493, + NPCs.GOBLIN_6494, + NPCs.GOBLIN_6495, + NPCs.GOBLIN_7964, + NPCs.GOBLIN_7965 + ) + val COWS = listOf( + NPCs.COW_81, + NPCs.COW_397, + NPCs.COW_955, + NPCs.COW_1767, + NPCs.COW_3309, + NPCs.COW_CALF_1766, + NPCs.COW_CALF_1768, + NPCs.COW_CALF_2310 + ) + val CHICKENS = listOf( + NPCs.CHICKEN_1017, + NPCs.CHICKEN_1401, + NPCs.CHICKEN_1402, + NPCs.CHICKEN_2313, + NPCs.CHICKEN_2314, + NPCs.CHICKEN_2315, + NPCs.CHICKEN_288, + NPCs.CHICKEN_41, + NPCs.CHICKEN_951, + ) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/activity/jobs/impl/Employers.kt b/Server/src/main/content/global/activity/jobs/impl/Employers.kt new file mode 100644 index 0000000..2d1fc16 --- /dev/null +++ b/Server/src/main/content/global/activity/jobs/impl/Employers.kt @@ -0,0 +1,24 @@ +package content.global.activity.jobs.impl + +import org.rs09.consts.NPCs + +/** + * An enum of NPCs that can assign the player a job. + * + * TODO: Add the rest of the era-correct employers + */ +enum class Employers(val npcId: Int) { + WOODCUTTING_TUTOR(NPCs.WOODCUTTING_TUTOR_4906), + MAGIC_TUTOR(NPCs.MAGIC_TUTOR_4707), + MELEE_TUTOR(NPCs.MELEE_TUTOR_705), + RANGED_TUTOR(NPCs.RANGED_TUTOR_1861), + COOKING_TUTOR(NPCs.COOKING_TUTOR_4899), + CRAFTING_TUTOR(NPCs.CRAFTING_TUTOR_4900), + FISHING_TUTOR(NPCs.FISHING_TUTOR_4901), + MINING_TUTOR(NPCs.MINING_TUTOR_4902), + SMELTING_TUTOR(NPCs.SMELTING_TUTOR_4904), + PRAYER_TUTOR(NPCs.PRAYER_TUTOR_4903), + HANS(NPCs.HANS_0), + GILLIE_GROATS(NPCs.GILLIE_GROATS_3807), + AGGIE(NPCs.AGGIE_922); +} \ No newline at end of file diff --git a/Server/src/main/content/global/activity/jobs/impl/ProductionJobs.kt b/Server/src/main/content/global/activity/jobs/impl/ProductionJobs.kt new file mode 100644 index 0000000..04bdd54 --- /dev/null +++ b/Server/src/main/content/global/activity/jobs/impl/ProductionJobs.kt @@ -0,0 +1,80 @@ +package content.global.activity.jobs.impl + +import content.global.activity.jobs.Job +import content.global.activity.jobs.JobType +import core.game.node.entity.skill.Skills + +/** + * An enum of the possible production jobs that can be assigned to a player. + * + * Note: Due to how player save files keep track of the player's current job, it is essential that + * new entries are only appended to the end of this enum, and the ordering of existing entries is not changed. + */ +enum class ProductionJobs( + override val lower: Int, + override val upper: Int, + val lvlReq: Int, + val itemId: Int, + val skill: Int, + override val employer: Employers +) : Job { + LOG(20, 28, 1, 1511, Skills.WOODCUTTING, Employers.WOODCUTTING_TUTOR), + COWHIDES(20, 28, 1, 1739, 0, Employers.HANS), + OAK(22, 28, 15, 1521, Skills.WOODCUTTING, Employers.WOODCUTTING_TUTOR), + WATER_RUNE(20, 28, 5, 555, Skills.RUNECRAFTING, Employers.HANS), + EARTH_RUNE(20, 28, 9, 557, Skills.RUNECRAFTING, Employers.AGGIE), + FIRE_RUNE(20, 28, 14, 554, Skills.RUNECRAFTING, Employers.AGGIE), + AIR_RUNE(20, 28, 1, 556, Skills.RUNECRAFTING, Employers.HANS), + RUNE_ESS(20, 28, 1, 1436, Skills.MINING, Employers.MINING_TUTOR), + BALL_OF_WOOL(20, 28, 1, 1759, Skills.CRAFTING, Employers.GILLIE_GROATS), + LEATHER_GLOVE(20, 28, 1, 1059, Skills.CRAFTING, Employers.GILLIE_GROATS), + WILLOW(22, 28, 30, 1519, Skills.WOODCUTTING, Employers.WOODCUTTING_TUTOR), + LEATHER_BOOT(24, 24, 1, 1061, Skills.CRAFTING, Employers.HANS), + BRONZE_DAGGER(24, 24, 1, 1205, Skills.SMITHING, Employers.SMELTING_TUTOR), + BRONZE_HELMS(22, 22, 1, 1139, Skills.SMITHING, Employers.SMELTING_TUTOR), + BRONZE_FULL_HELM(10, 10, 7, 1155, Skills.SMITHING, Employers.SMELTING_TUTOR), + BRONZE_CHAINBODY(10, 10, 11, 1103, Skills.SMITHING, Employers.SMELTING_TUTOR), + BRONZE_2H(10, 10, 14, 1307, Skills.SMITHING, Employers.SMELTING_TUTOR), + BRONZE_SCIM(10, 10, 5, 1321, Skills.SMITHING, Employers.SMELTING_TUTOR), + BRONZE_PLATEBODY(9, 10, 18, 1117, Skills.SMITHING, Employers.SMELTING_TUTOR), + BRONZE_PLATELEGS(9, 10, 16, 1075, Skills.SMITHING, Employers.SMELTING_TUTOR), + BRONZE_PLATESKIRTS(9, 10, 16, 1087, Skills.SMITHING, Employers.SMELTING_TUTOR), + BRONZE_WARHAMMER(9, 9, 9, 1337, Skills.SMITHING, Employers.SMELTING_TUTOR), + IRON_DAGGER(13, 13, 15, 1203, Skills.SMITHING, Employers.SMELTING_TUTOR), + IRON_CHAINBODY(10, 10, 26, 1101, Skills.SMITHING, Employers.SMELTING_TUTOR), + IRON_2H(9, 9, 29, 1309, Skills.SMITHING, Employers.SMELTING_TUTOR), + STEEL_BATTLEAXE(9, 9, 40, 1365, Skills.SMITHING, Employers.SMELTING_TUTOR), + STEEL_SCIMITAR(9, 9, 35, 1325, Skills.SMITHING, Employers.SMELTING_TUTOR), + STEEL_PLATEBODY(9, 10, 48, 1119, Skills.SMITHING, Employers.SMELTING_TUTOR), + STEEL_WARHAMMER(9, 10, 39, 1339, Skills.SMITHING, Employers.SMELTING_TUTOR), + LEATHER_CHAPS(22, 28, 18, 1095, Skills.CRAFTING, Employers.CRAFTING_TUTOR), + LEATHER_BODY(22, 28, 14, 1129, Skills.CRAFTING, Employers.CRAFTING_TUTOR), + LEATHER_COWL(22, 28, 9, 1167, Skills.CRAFTING, Employers.CRAFTING_TUTOR), + LEATHER_COIF(22, 28, 38, 1169, Skills.CRAFTING, Employers.CRAFTING_TUTOR), + RAW_SHRIMP(22, 28, 1, 317, Skills.FISHING, Employers.FISHING_TUTOR), + COOKED_SHRIMP(22, 28, 1, 315, Skills.COOKING, Employers.COOKING_TUTOR), + RAW_CRAYFISH(22, 28, 1, 13435, Skills.FISHING, Employers.FISHING_TUTOR), + COOKED_CRAYFISH(22, 28, 1, 13433, Skills.COOKING, Employers.COOKING_TUTOR), + RAW_TROUT(22, 28, 20, 335, Skills.FISHING, Employers.FISHING_TUTOR), + COOKED_TROUT(22, 28, 15, 333, Skills.COOKING, Employers.COOKING_TUTOR), + RAW_SALMON(22, 28, 30, 331, Skills.FISHING, Employers.FISHING_TUTOR), + COOKED_SALMON(22, 28, 25, 329, Skills.COOKING, Employers.COOKING_TUTOR), + CAKE(12, 16, 40, 1891, Skills.COOKING, Employers.GILLIE_GROATS), + MEAT_PIE(12, 16, 20, 2327, Skills.COOKING, Employers.COOKING_TUTOR), + PLAIN_PIZZA(12, 16, 35, 2289, Skills.COOKING, Employers.COOKING_TUTOR), + MEAT_PIZZA(12, 16, 45, 2293, Skills.COOKING, Employers.COOKING_TUTOR), + ANCHOVY_PIZZA(12, 16, 55, 2297, Skills.COOKING, Employers.COOKING_TUTOR), + REDBERRY_PIE(12, 16, 10, 2325, Skills.COOKING, Employers.GILLIE_GROATS), + COPPER_ORE(22, 28, 1, 436, Skills.MINING, Employers.MINING_TUTOR), + TIN_ORE(23, 26, 1, 438, Skills.MINING, Employers.MINING_TUTOR), + IRON_ORE(24, 24, 15, 440, Skills.MINING, Employers.MINING_TUTOR), + SILVER_ORE(22, 28, 20, 442, Skills.MINING, Employers.PRAYER_TUTOR), + COAL(22, 26, 30, 453, Skills.MINING, Employers.MINING_TUTOR), + GOLD_ORE(22, 24, 40, 444, Skills.MINING, Employers.MINING_TUTOR), + BRONZE_BAR(10, 12, 1, 2349, Skills.SMITHING, Employers.SMELTING_TUTOR), + IRON_BAR(22, 28, 15, 2351, Skills.SMITHING, Employers.SMELTING_TUTOR), + STEEL_BAR(22, 28, 30, 2353, Skills.SMITHING, Employers.SMELTING_TUTOR), + ASHES(26, 26, 1, 592, 0, Employers.AGGIE); + + override val type = JobType.PRODUCTION +} \ No newline at end of file diff --git a/Server/src/main/content/global/activity/penguinhns/LarryHandler.kt b/Server/src/main/content/global/activity/penguinhns/LarryHandler.kt new file mode 100644 index 0000000..4a4b3ba --- /dev/null +++ b/Server/src/main/content/global/activity/penguinhns/LarryHandler.kt @@ -0,0 +1,88 @@ +package content.global.activity.penguinhns + +import core.api.* +import core.game.component.Component +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.tools.END_DIALOGUE + +class LarryHandler(player: Player? = null) : core.game.dialogue.DialoguePlugin(player){ + override fun open(vararg args: Any?): Boolean { + options("Can I have a spy notebook?","Can I have a hint?","I'd like to turn in my points.").also { stage = 0; return true } + } + + override fun newInstance(player: Player?): core.game.dialogue.DialoguePlugin { + return LarryHandler(player) + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + class HintPulse : Pulse(){ + override fun pulse(): Boolean { + val hint = Penguin.values()[PenguinManager.penguins.random()].hint + player.sendMessage("Here, I know one is...") + player.sendMessage(hint) + return true + } + } + when(stage){ + 0 -> when(buttonId){ + 1 -> player("Can I have a spy notebook?").also { stage++ } + 2 -> player("Can I have a hint?").also { stage = 10 } + 3 -> player("I'd like to turn in my points.").also { stage = 20 } + } + + //Spy notebook + 1 -> npc("Sure!").also { player.inventory.add(Item(13732));stage = 1000 } + + //Hint + 10 -> npc("Yes, give me just one moment...").also { stage++ } + + 11 -> { + val hint = Penguin.values()[PenguinManager.penguins.random()].hint + npcl(core.game.dialogue.FacialExpression.FRIENDLY, "One is $hint") + stage = END_DIALOGUE + } + + //Point turn-in + 20 -> if(player.getAttribute("phns:points",0) > 0) npc("Sure thing, what would you like to be","rewarded with?").also { stage++ } else npc("Uh, you don't have any points","to turn in.").also{stage = 1000} + + 21 -> options("Coins","Experience").also { stage++ } + 22 -> when(buttonId){ + 1 -> player.inventory.add(Item(995, 6500 * player.getAttribute("phns:points",0))).also { player("Thanks!"); player.removeAttribute("phns:points");stage = 1000 } + 2 -> { + player.setAttribute("caller",this) + player.interfaceManager.open(Component(134).setCloseEvent { player1: Player?, c: Component? -> + player.interfaceManager.openDefaultTabs() + player.removeAttribute("lamp") + player.unlock() + true + }).also { end() } + } + } + + 1000 -> end() + } + return true + } + + override fun handleSelectionCallback(skill: Int, player: Player) { + val points = player.getAttribute("phns:points",0) + if(points == 0){ + player.sendMessage("Sorry, but you have no points to redeem.") + return + } + + val level = getStatLevel(player, skill) + + val expGained = points?.toDouble()?.times((level * 25)) + System.out.print("exp: $expGained") + player.skills.addExperience(skill,expGained!!) + player.setAttribute("/save:phns:points",0) + } + + override fun getIds(): IntArray { + return intArrayOf(5424) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/activity/penguinhns/NotebookHandler.kt b/Server/src/main/content/global/activity/penguinhns/NotebookHandler.kt new file mode 100644 index 0000000..15462ee --- /dev/null +++ b/Server/src/main/content/global/activity/penguinhns/NotebookHandler.kt @@ -0,0 +1,21 @@ +package content.global.activity.penguinhns + +import core.cache.def.impl.ItemDefinition +import core.game.interaction.OptionHandler +import core.game.node.Node +import core.game.node.entity.player.Player +import core.plugin.Plugin + +class NotebookHandler : OptionHandler(){ + override fun handle(player: Player?, node: Node?, option: String?): Boolean { + val total = player?.getAttribute("phns:points",0) + player?.dialogueInterpreter?.sendDialogue("Total points: $total") + return true + } + + override fun newInstance(arg: Any?): Plugin { + ItemDefinition.forId(13732).handlers["option:read"] = this + return this + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/activity/penguinhns/PenguinHNSEvent.kt b/Server/src/main/content/global/activity/penguinhns/PenguinHNSEvent.kt new file mode 100644 index 0000000..39bc241 --- /dev/null +++ b/Server/src/main/content/global/activity/penguinhns/PenguinHNSEvent.kt @@ -0,0 +1,26 @@ +package content.global.activity.penguinhns + +import core.ServerStore +import core.api.StartupListener +import core.api.log +import core.plugin.ClassScanner +import core.tools.Log +import org.json.simple.JSONObject + +class PenguinHNSEvent : StartupListener { + val manager = PenguinManager() + + override fun startup() { + manager.rebuildVars() + ClassScanner.definePlugins(LarryHandler(), NotebookHandler()) + log(this::class.java, Log.FINE, "Penguin HNS initialized.") + } + + companion object { + @JvmStatic + fun getStoreFile() : JSONObject { + return ServerStore.getArchive("weekly-penguinhns") + } + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/activity/penguinhns/PenguinManager.kt b/Server/src/main/content/global/activity/penguinhns/PenguinManager.kt new file mode 100644 index 0000000..c284214 --- /dev/null +++ b/Server/src/main/content/global/activity/penguinhns/PenguinManager.kt @@ -0,0 +1,69 @@ +package content.global.activity.penguinhns + +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.tools.SystemLogger +import core.game.world.map.Location +import org.json.simple.JSONArray +import org.json.simple.JSONObject +import core.ServerStore.Companion.toJSONArray +import core.api.log +import core.tools.Log +import java.util.* + +class PenguinManager{ + companion object { + var penguins: MutableList = ArrayList() + var npcs = ArrayList() + val spawner = PenguinSpawner() + var tagMapping: MutableMap = HashMap() + + fun registerTag(player: Player, location: Location){ + val ordinal = Penguin.forLocation(location)?.ordinal ?: -1 + val list = tagMapping[ordinal] ?: JSONArray() + list.add(player.username.toLowerCase()) + tagMapping[ordinal] = list + updateStoreFile() + } + + fun hasTagged(player: Player, location: Location): Boolean{ + return tagMapping[Penguin.forLocation(location)?.ordinal]?.contains(player.username.toLowerCase()) ?: false + } + + private fun updateStoreFile(){ + val jsonTags = JSONArray() + tagMapping.filter { it.value.isNotEmpty() }.forEach { (ordinal,taggers) -> + log(this::class.java, Log.FINE, "$ordinal - ${taggers.first()}") + val tag = JSONObject() + tag["ordinal"] = ordinal + tag["taggers"] = taggers + jsonTags.add(tag) + } + + PenguinHNSEvent.getStoreFile()["tag-mapping"] = jsonTags + } + } + + fun rebuildVars() { + if(!PenguinHNSEvent.getStoreFile().containsKey("spawned-penguins")) { + penguins = spawner.spawnPenguins(10) + PenguinHNSEvent.getStoreFile()["spawned-penguins"] = penguins.toJSONArray() + tagMapping.clear() + for (p in penguins) { + tagMapping.put(p, JSONArray()) + } + updateStoreFile() + } else { + val spawnedOrdinals = (PenguinHNSEvent.getStoreFile()["spawned-penguins"] as JSONArray).map { it.toString().toInt() } + spawner.spawnPenguins(spawnedOrdinals) + + val storedTags = (PenguinHNSEvent.getStoreFile()["tag-mapping"] as? JSONArray)?.map { jRaw -> + val jObj = jRaw as JSONObject + jObj["ordinal"].toString().toInt() to (jObj["taggers"] as JSONArray) + }?.toMap()?.toMutableMap() ?: HashMap() + + tagMapping = storedTags + penguins = spawnedOrdinals.toMutableList() + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/activity/penguinhns/PenguinSpawner.kt b/Server/src/main/content/global/activity/penguinhns/PenguinSpawner.kt new file mode 100644 index 0000000..d19b9a8 --- /dev/null +++ b/Server/src/main/content/global/activity/penguinhns/PenguinSpawner.kt @@ -0,0 +1,67 @@ +package content.global.activity.penguinhns + +import core.game.node.entity.npc.NPC +import core.game.world.map.Location +import org.rs09.consts.NPCs +import core.game.worldevents.WorldEvents + +class PenguinSpawner { + + fun spawnPenguins(amount: Int): ArrayList { + var counter = 0 + val availableOrdinals = (0 until Penguin.values().size).toMutableList() + val spawnedOrdinals = ArrayList() + while(counter < amount){ + val peng = Penguin.values()[availableOrdinals.random()] + availableOrdinals.remove(peng.ordinal) + spawnedOrdinals.add(peng.ordinal) + NPC(peng.id,peng.location) + .also { PenguinManager.npcs.add(it);it.isNeverWalks = true; it.isWalks = false}.init() + counter++ + } + return spawnedOrdinals + } + + fun spawnPenguins(ordinals: List){ + ordinals.forEach { + val peng = Penguin.values()[it] + NPC(peng.id,peng.location) + .also { PenguinManager.npcs.add(it); it.isNeverWalks = true; it.isWalks = false }.init() + } + } +} + +enum class Penguin(val id: Int, val hint: String, val location: Location){ + CACTUS_1(NPCs.CACTUS_8107,"located in the northern desert.", Location(3310, 3157, 0)), + CACTUS_2(NPCs.CACTUS_8107,"located in the southern desert.",Location.create(3259, 3052, 0)), + BUSH_1(NPCs.BUSH_8105,"located between Fremennik and barbarians.",Location.create(2532, 3588, 0)), + BUSH_2(NPCs.BUSH_8105,"located where banana smugglers dwell.",Location.create(2740, 3233, 0)), + BUSH_3(NPCs.BUSH_8105,"located south of Ardougne.",Location.create(2456, 3092, 0)), + BUSH_4(NPCs.BUSH_8105,"located deep in the jungle.",Location.create(2832, 3053, 0)), + BUSH_5(NPCs.BUSH_8105,"located where eagles fly.",Location.create(2326, 3516, 0)), + BUSH_6(NPCs.BUSH_8105,"located south of Ardougne.",Location.create(2513, 3154, 0)), + BUSH_7(NPCs.BUSH_8105,"located near a big tree surrounded by short people.",Location.create(2387, 3451, 0)), + BUSH_8(NPCs.BUSH_8105,"located in the kingdom of Asgarnia.",Location.create(2951, 3511, 0)), + BUSH_9(NPCs.BUSH_8105,"located in the northern desert.",Location.create(3350, 3311, 0)), + BUSH_10(NPCs.BUSH_8105,"located somewhere in the kingdom of Kandarin.",Location.create(2633, 3501, 0)), + BUSH_11(NPCs.BUSH_8105,"located south of Ardougne.",Location.create(2440, 3206, 0)), + BUSH_12(NPCs.BUSH_8105,"located where wizards study.",Location.create(3112, 3149, 0)), + ROCK_1(NPCs.ROCK_8109,"located where the Imperial Guard train.",Location.create(2852, 3578, 0)), + ROCK_2(NPCs.ROCK_8109,"located in the kingdom of Misthalin.",Location.create(3356, 3416, 0)), + ROCK_3(NPCs.ROCK_8109,"located near some ogres.",Location.create(2631, 2980, 0)), + ROCK_4(NPCs.ROCK_8109,"located in the Kingdom of Asgarnia.",Location.create(3013, 3501, 0)), + ROCK_5(NPCs.ROCK_8109,"located between Fremennik and barbarians.",Location.create(2532, 3630, 0)), + CRATE_1(NPCs.CRATE_8108,"located in the kingdom of Misthalin.",Location.create(3112, 3332, 0)), + CRATE_2(NPCs.CRATE_8108,"located in the Kingdom of Misthalin.",Location.create(3305, 3508, 0)), + BARREL_1(NPCs.CRATE_8108,"located where no weapons may go.",Location.create(2806, 3383, 0)), + TOADSTOOL_1(NPCs.TOADSTOOL_8110,"located in the kingdom of Misthalin.",Location.create(3156, 3178, 0)), + TOADSTOOL_2(NPCs.TOADSTOOL_8110,"located in the fairy realm.",Location.create(2409, 4462, 0)); + + companion object { + private val locationMap = values().map { it.location.toString() to it }.toMap() + + fun forLocation(location: Location): Penguin?{ + return locationMap[location.toString()] + } + } +} diff --git a/Server/src/main/content/global/activity/penguinhns/PenguinSpyingHandler.kt b/Server/src/main/content/global/activity/penguinhns/PenguinSpyingHandler.kt new file mode 100644 index 0000000..3862200 --- /dev/null +++ b/Server/src/main/content/global/activity/penguinhns/PenguinSpyingHandler.kt @@ -0,0 +1,53 @@ +package content.global.activity.penguinhns + +import core.api.* +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.system.task.Pulse +import core.game.world.GameWorld +import core.game.world.update.flag.context.Animation +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +class PenguinSpyingHandler : InteractionListener { + + override fun defineListeners() { + on(PENGUINS, IntType.NPC, "spy-on"){ player, node -> + val npc = node.asNpc() + if(PenguinManager.hasTagged(player, npc.location)){ + player.sendMessage("You've already tagged this penguin.") + } else { + GameWorld.submit(SpyPulse(player, npc)) + playJingle(player, 345) + } + return@on true + } + } + + val PENGUINS = intArrayOf(8104,8105,8107,8108,8109,8110) + + class SpyPulse(val player: Player, val npc: NPC) : Pulse() { + var stage = 0 + val curPoints = player.getAttribute("phns:points",0) + + val ANIMATION = Animation(10355) + + override fun pulse(): Boolean { + when(stage++){ + 0 -> player.lock().also { player.animator.animate(ANIMATION) } + 1 -> player.sendMessage("You manage to spy on the penguin.").also { + player.setAttribute("/save:phns:points",curPoints + 1) + PenguinManager.registerTag(player, npc.location) + player.unlock() + } + 2 -> return true + } + return false + } + + override fun stop() { + super.stop() + player.unlock() + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/activity/shootingstar/ShootingStar.kt b/Server/src/main/content/global/activity/shootingstar/ShootingStar.kt new file mode 100644 index 0000000..9432ea0 --- /dev/null +++ b/Server/src/main/content/global/activity/shootingstar/ShootingStar.kt @@ -0,0 +1,234 @@ +package content.global.activity.shootingstar + +import core.game.node.scenery.Scenery +import core.game.node.scenery.SceneryBuilder +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.ServerStore.Companion.getBoolean +import core.ServerStore.Companion.getInt +import core.ServerStore.Companion.getString + +import content.global.bots.ShootingStarBot +import core.game.world.repository.Repository +import core.tools.RandomFunction + +/** + * Represents a shooting star object (Only ever initialized once) (ideally) + * @author Ceikry + */ +class ShootingStar(var level: ShootingStarType = ShootingStarType.values().random()) { + val crash_locations = mapOf( + "East of Dark Wizards' Tower" to Location.create(2925, 3339, 0), // East of Dark Wizards' Tower + "Crafting Guild" to Location.create(2940, 3280, 0), // Crafting Guild Mine + "Falador East Bank" to Location.create(3030, 3349, 0), // Falador East Bank + "Rimmington mining site" to Location.create(2974, 3240, 0), // Rimmington Mine 2974, 3240, 0) + "Karamja northwestern mining site" to Location.create(2737, 3223, 0), // Karamja northwestern mining site/Brimhaven gold rocks + "Brimhaven mining site" to Location.create(2743, 3143, 0), // Brimhaven mining site + "South Crandor mining site" to Location.create(2822, 3239, 0), // South Crandor mining site (requires Dragon Slayer) + "Karamja mining site" to Location.create(2854, 3032, 0), // Karamja mining site + "Shilo Village mining site" to Location.create(2826, 2997, 0), // Shilo Village mining site/Gem rocks (requires Shilo Village prereqs) + "Relleka mining site" to Location.create(2682, 3700, 0), // Rellekka mining site + "Jatizso mine" to Location.create(2393, 3815, 0), //Jatiszo mining site (requires Fremennik Isles prereqs) + "Lunar Isle mine" to Location.create(2140, 3939, 0), // Lunar Isle mine (requires Lunar Diplomacy prereqs) + "Miscellania coal mine" to Location.create(2529, 3887, 0), // Miscellania coal mine (requires The Fremennik Trials) + //"Neitiznot runite mine" to Location.create(2376, 3835, 0), // Near the Neitiznot runite mine (requires Fremennik Isles prereqs) currently inaccessible as bridge does not work + "Ardougne mining site" to Location.create(2600, 3232, 0), // Ardougne mining site (Monastery) + "Ardougne eastern mine" to Location.create(2706, 3334, 0), // Ardougne mining site (Legends Guild) + "Kandarin Coal trucks" to Location.create(2589, 3485, 0), // Kandarin Coal trucks + "Yanille Bank" to Location.create(2603, 3087, 0), // Yanille Bank (Wizards' Guild) + "Port Khazard mine" to Location.create(2626, 3140, 0), // Mining spot north-east of Yanille / Port Khazard mine + "Al Kharid bank" to Location.create(3276, 3176, 0), // Al Kharid bank + "Al Kharid mining site" to Location.create(3296, 3297, 0), // Al Kharid mine (Scorpion mine) + "Duel Arena bank chest" to Location.create(3342, 3267, 0), // Duel Arena bank chest + "Kharidian Desert clay mine" to Location.create(3426, 3159, 0), // Desert clay mine / Ruins of Uzer mine + "Nardah mining site" to Location.create(3320, 2872, 0), // Kharidian Desert gold mine / Vulture mine + "Nardah bank" to Location.create(3434, 2888, 0), // Nardah bank + "Granite and sandstone quarry" to Location.create(3170, 2913, 0), // Granite and sandstone quarry / Quarry on map + "South-east Varrock mine" to Location.create(3292, 3353, 0), // South-east Varrock mine + "South-west Varrock mine" to Location.create(3176, 3362, 0), // South-west Varrock mine / Champion's Guild mine + "Varrock east bank" to Location.create(3259, 3407, 0), // Varrock east bank / Rune shop + "Lumbridge Swamp south-east mine" to Location.create(3227, 3150, 0), // Lumbridge Swamp south-east mine + //"Burgh de Rott bank" to Location.create(3500, 3219, 0), // Burgh de Rott bank (requires quest to enter) + "Canifis Bank" to Location.create(3504, 3487, 0), // Canifis bank + "Mos Le'Harmless bank" to Location.create(3687, 2969, 0), // Mos Le'Harmless bank (requires quest to enter but is currently accessible for Slayer) + "Gnome stronghold Bank" to Location.create(2460, 3432, 0), // Gnome stronghold bank + "Lletya bank" to Location.create(2329, 3163, 0), // Lletya bank (requires MEP1 prereqs) + "Piscatoris mining site" to Location.create(2336, 3636, 0), // Piscatoris mining site + "North Edgeville mining site" to Location.create(3101, 3569, 0), // Wilderness Steel mine / Zamorak mage mine + "Southern wilderness mine" to Location.create(3025, 3591, 0), // Wilderness skeleton mine + "Wilderness Volcano bank" to Location.create(3188, 3695, 0), // Wilderness Volcano bank + "Wilderness hobgoblin mine" to Location.create(3020, 3809, 0), // Wilderness hobgoblin mine + "Pirates' Hideout mine" to Location.create(3059, 3940, 0), // Pirates' Hideout mine + "Lava Maze mining site" to Location.create(3062, 3885, 0), // Wilderness rune mine + "Mage Arena bank" to Location.create(3093, 3962, 0) // Mage Arena bank + ) + val starSprite = NPC(8091) + var location = "Canifis Bank" + var maxDust = level.totalStardust + var dustLeft = level.totalStardust + var starObject = Scenery(level.objectId, crash_locations.get(location)) + var isDiscovered = false + var ticks = 0 + var isSpawned = false + var spriteSpawned = false + var firstStar = true + var selfBots = ArrayList() + var activePlayers = HashSet() + + /** + * Degrades a ShootingStar (or removes the starObject and spawns a Star Sprite if it's the last star) + */ + fun degrade() { + if(level.ordinal == 0) { + spawnSprite() + return + } + level = getNextType() + maxDust = level.totalStardust + dustLeft = level.totalStardust + ShootingStarPlugin.getStoreFile()["level"] = level.ordinal + ShootingStarPlugin.getStoreFile()["dustLeft"] = dustLeft + + val newStar = Scenery(level.objectId, starObject.location) + SceneryBuilder.replace(starObject, newStar) + starObject = newStar + } + + private fun getNextType(): ShootingStarType { + return ShootingStarType.values()[level.ordinal - 1] + } + + /** + * Fires the shooting star (spawns a new one). Only used when spawning new shooting stars, not for downgrading existing ones. + */ + fun fire() { + SceneryBuilder.remove(starObject) + clearSprite() + SceneryBuilder.add(starObject) + if(!isSpawned) { + (0..2).forEach { + selfBots.add(ShootingStarBot.new()) + } + } + if (level.ordinal + 1 > 5) { + selfBots.filter { it.isIdle() }.forEach { it.activate(true) } + } + isSpawned = true + Repository.sendNews("A shooting star level ${level.ordinal + 1} just crashed near ${location}!") + ShootingStarPlugin.getStoreFile()["level"] = level.ordinal + ShootingStarPlugin.getStoreFile()["location"] = location + ShootingStarPlugin.getStoreFile()["isDiscovered"] = isDiscovered + ShootingStarPlugin.getStoreFile()["dustLeft"] = dustLeft + } + + /** + * Rebuilds some of the variables with new information. + */ + fun rebuildVars(){ + // Defaults + var levelOrd = RandomFunction.random(9) + level = ShootingStarType.values()[levelOrd] + location = crash_locations.entries.random().key + isDiscovered = false + dustLeft = level.totalStardust + ticks = 0 + spriteSpawned = false + + if (firstStar && ShootingStarPlugin.getStoreFile().isNotEmpty()) { + // Replace default with stored values, if any + levelOrd = ShootingStarPlugin.getStoreFile().getInt("level", levelOrd) + level = ShootingStarType.values()[levelOrd] + location = ShootingStarPlugin.getStoreFile().getString("location", location) + isDiscovered = ShootingStarPlugin.getStoreFile().getBoolean("isDiscovered", false) + dustLeft = ShootingStarPlugin.getStoreFile().getInt("dustLeft", dustLeft) + ticks = ShootingStarPlugin.getStoreFile().getInt("ticks", ticks) + spriteSpawned = ShootingStarPlugin.getStoreFile().getBoolean("spriteSpawned", false) + } + + maxDust = level.totalStardust + starObject = Scenery(level.objectId, crash_locations.get(location)) + } + + fun spawnSprite() { + selfBots.filter { it.isMining() }.forEach { it.sleep() } + SceneryBuilder.remove(starObject) + isSpawned = false + starSprite.location = starObject.location + starSprite.init() + spriteSpawned = true + ShootingStarPlugin.getStoreFile()["spriteSpawned"] = spriteSpawned + } + + fun clearSprite() { + starSprite.clear() + spriteSpawned = false + ShootingStarPlugin.getStoreFile()["spriteSpawned"] = spriteSpawned + } + + /** + * Decrement the amount of dust left in the current star and degrade it if the amount left is 0 or less. + */ + fun decDust() { + if(--dustLeft <= 0) degrade() + ShootingStarPlugin.getStoreFile()["dustLeft"] = dustLeft + } + + /** + * Proxy method for starting to mine a shooting star + */ + fun mine(player: Player) { + player.pulseManager.run(ShootingStarMiningPulse(player, starObject, this)) + } + + /** + * Prospecting shooting stars. + */ + fun prospect(player: Player) { + player.dialogueInterpreter.sendDialogue("This is a size " + (level.ordinal + 1) + " star. A Mining level of at least " + miningLevel + " is", "required to mine this layer. There is $dustLeft stardust remaining", "until the next layer.") + } + + /** + * Notifies the star when a player begins mining it + */ + fun notifyNewPlayer(player: Player) { + if(activePlayers.size < 3){ + val leavingBot = selfBots.firstOrNull { it.isMining() } + leavingBot?.sleep() + } + activePlayers.add(player) + } + + /** + * Notifies the star when a player stops mining it + */ + fun notifyPlayerLeave(player: Player) { + activePlayers.remove(player) + if (activePlayers.size < 3){ + val newBot = selfBots.firstOrNull() { it.isIdle() } + newBot?.activate(true) + } + } + + /** + * Gets the mining level required based on the star's current level ordinal. + */ + val miningLevel: Int + get() = (level.ordinal + 1) * 10 +} + +/** + * Various levels of shooting stars + * @author Ceikry + */ +enum class ShootingStarType(val objectId: Int, val exp: Int, val totalStardust: Int,val rate: Double) { + LEVEL_1(38668, 14, 1200, 0.05), + LEVEL_2(38667, 25, 700, 0.1), + LEVEL_3(38666, 29, 439, 0.3), + LEVEL_4(38665, 32, 250, 0.4), + LEVEL_5(38664, 47, 175, 0.5), + LEVEL_6(38663, 71, 80, 0.70), + LEVEL_7(38662, 114, 40, 0.80), + LEVEL_8(38661, 145, 25, 0.85), + LEVEL_9(38660, 210, 15, 0.95); +} diff --git a/Server/src/main/content/global/activity/shootingstar/ShootingStarMiningPulse.kt b/Server/src/main/content/global/activity/shootingstar/ShootingStarMiningPulse.kt new file mode 100644 index 0000000..5f5ee36 --- /dev/null +++ b/Server/src/main/content/global/activity/shootingstar/ShootingStarMiningPulse.kt @@ -0,0 +1,148 @@ +package content.global.activity.shootingstar + +import core.api.* +import core.game.node.scenery.Scenery +import core.game.node.entity.player.Player +import core.game.node.entity.skill.SkillPulse +import core.game.node.entity.skill.Skills +import content.data.skill.SkillingTool +import core.game.node.item.Item +import core.tools.RandomFunction +import org.rs09.consts.Items +import core.game.world.GameWorld +import core.game.world.repository.Repository +import core.tools.colorize + +/** + * The pulse used to handle mining shooting stars. + */ +class ShootingStarMiningPulse(player: Player?, node: Scenery?, val star: ShootingStar) : SkillPulse(player, node) { + /** + * The amount of ticks it takes to get star dust. + */ + private var ticks = 0 + override fun start() { + if(!star.isSpawned) return + + if(!player.isArtificial) { + star.notifyNewPlayer(player) + } + super.start() + } + + override fun stop() { + super.stop() + + if(!player.isArtificial){ + star.notifyPlayerLeave(player) + } + } + + override fun checkRequirements(): Boolean { + tool = SkillingTool.getPickaxe(player) + if (!star.starObject.isActive || !star.isSpawned) { + return false + } + //checks if the star has been discovered and if not, awards the bonus xp. Xp can be awarded regardless of mining level as per the wiki. + if (!star.isDiscovered && !player.isArtificial) { + val bonusXp = 75 * player.skills.getStaticLevel(Skills.MINING) + player.incrementAttribute("/save:shooting-star:bonus-xp", bonusXp) + Repository.sendNews(player.username + " is the discoverer of the crashed star near " + star.location + "!") + player.sendMessage("You have ${player.skills.experienceMultiplier * player.getAttribute("shooting-star:bonus-xp", 0).toDouble()} bonus xp towards mining stardust.") + ShootingStarPlugin.submitScoreBoard(player) + star.isDiscovered = true + ShootingStarPlugin.getStoreFile()["isDiscovered"] = star.isDiscovered + return player.skills.getLevel(Skills.MINING) >= star.miningLevel + } + + if (player.skills.getLevel(Skills.MINING) < star.miningLevel) { + player.dialogueInterpreter.sendDialogue("You need a Mining level of at least " + star.miningLevel + " in order to mine this layer.") + return false + } + if (tool == null) { + player.packetDispatch.sendMessage("You do not have a pickaxe to use.") + return false + } + if (player.inventory.freeSlots() < 1 && !player.inventory.contains(ShootingStarPlugin.STAR_DUST, 1)) { + player.dialogueInterpreter.sendDialogue("Your inventory is too full to hold any more stardust.") + return false + } + return true + } + + override fun animate() { + player.animate(tool.animation) + } + + override fun reward(): Boolean { + if (++ticks % 4 != 0) { + return false + } + if (!checkReward()) { + return false + } + if (GameWorld.settings?.isDevMode == true) { + star.dustLeft = 1 + } + + val bonusXp = player.getAttribute("shooting-star:bonus-xp", 0).toDouble() + var xp = star.level.exp.toDouble() + if(bonusXp > 0) { + val delta = Math.min(bonusXp, xp) + player.incrementAttribute("/save:shooting-star:bonus-xp", (-delta).toInt()) + xp += delta + if(player.getAttribute("shooting-star:bonus-xp", 0) <= 0) { + player.sendMessage("You have obtained all of your bonus xp from the star.") + } + } + + player.skills.addExperience(Skills.MINING, xp) + if (ShootingStarPlugin.getStarDust(player) < 200) { + player.inventory.add(Item(ShootingStarPlugin.STAR_DUST, 1)) + } + if(!inInventory(player, Items.ANCIENT_BLUEPRINT_14651) && !inBank(player, Items.ANCIENT_BLUEPRINT_14651)){ + rollBlueprint(player) + } + + star.decDust() + return false + } + + fun rollBlueprint(player: Player){ + val chance = when(star.level){ + ShootingStarType.LEVEL_9 -> 250 + ShootingStarType.LEVEL_8 -> 500 + ShootingStarType.LEVEL_7 -> 750 + ShootingStarType.LEVEL_6 -> 1000 + ShootingStarType.LEVEL_5 -> 2000 + ShootingStarType.LEVEL_4 -> 3000 + ShootingStarType.LEVEL_3 -> 4000 + ShootingStarType.LEVEL_2 -> 5000 + ShootingStarType.LEVEL_1 -> 10000 + } + + if(RandomFunction.roll(chance)){ + addItemOrDrop(player, Items.ANCIENT_BLUEPRINT_14651, 1) + sendMessage(player, colorize("%RWhile mining the star you find an ancient-looking blueprint.")) + sendNews("${player.username} found an Ancient Blueprint while mining a shooting star!") + } + } + + override fun message(type: Int) { + when (type) { + 0 -> player.packetDispatch.sendMessage("You swing your pickaxe at the rock...") + } + } + + /** + * Checks if the player gets rewarded. + * @return `True` if so. + */ + private fun checkReward(): Boolean { + val skill = Skills.MINING + val level = 1 + player.skills.getLevel(skill) + player.familiarManager.getBoost(skill) + val hostRatio: Double = Math.random() * (100.0 * star.level.rate) + val clientRatio: Double = Math.random() * ((level - star.miningLevel) * (1.0 + tool.ratio)) + return hostRatio < clientRatio + } +} diff --git a/Server/src/main/content/global/activity/shootingstar/ShootingStarPlugin.kt b/Server/src/main/content/global/activity/shootingstar/ShootingStarPlugin.kt new file mode 100644 index 0000000..1e993e1 --- /dev/null +++ b/Server/src/main/content/global/activity/shootingstar/ShootingStarPlugin.kt @@ -0,0 +1,190 @@ +package content.global.activity.shootingstar + +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.TeleportManager +import core.game.node.entity.skill.Skills +import org.json.simple.JSONObject +import org.rs09.consts.Items +import org.rs09.consts.Scenery +import core.ServerStore +import core.ServerStore.Companion.getBoolean +import core.game.dialogue.DialogueFile +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.game.system.command.Privilege +import core.game.world.GameWorld +import core.tools.Log +import core.tools.secondsToTicks +import content.data.Quests + +class ShootingStarPlugin : LoginListener, InteractionListener, TickListener, Commands, StartupListener { + override fun login(player: Player) { + if(star.isSpawned && !star.spriteSpawned) + sendMessage(player, "News: A shooting star (Level ${star.level.ordinal + 1}) has just crashed near the ${star.location}!") + } + + override fun tick() { + ++star.ticks + + // Check if the current star sprite should expire + val maxDelay = tickDelay + (tickDelay / 3) + if(star.ticks > maxDelay && star.spriteSpawned){ + star.clearSprite() + } + + if (star.firstStar && !star.isSpawned && !star.spriteSpawned) { + // Apparently, the server has only just booted + star.rebuildVars() + if (star.spriteSpawned) { + star.spawnSprite() + } else { + star.fire() + } + star.firstStar = false + } + + // Check if it's time to fire a new one + if (star.ticks >= tickDelay && !star.spriteSpawned) { + star.rebuildVars() + star.fire() + } + + getStoreFile()["ticks"] = star.ticks + } + + override fun defineListeners() { + on(Scenery.SHOOTING_STAR_NOTICEBOARD_38669, IntType.SCENERY, "read") { player, _ -> + var index = 0 + scoreboardEntries.forEach { entry -> + val timeElapsed = secondsToTicks(GameWorld.ticks - entry.time) / 60 + setInterfaceText(player, "$timeElapsed minutes ago", scoreboardIface, index + 6) + setInterfaceText(player, entry.player, scoreboardIface, index + 11) + ++index + } + openInterface(player, scoreboardIface) + return@on true + } + + on(SHOOTING_STARS, IntType.SCENERY, "mine"){ player, _ -> + star.mine(player) + return@on true + } + + on(SHOOTING_STARS, IntType.SCENERY, "prospect"){ player, _ -> + star.prospect(player) + return@on true + } + + on(RING, IntType.ITEM, "rub", "operate"){ player, node -> + if(getRingStoreFile().getBoolean(player.username.toLowerCase())){ + sendDialogue(player, "The ring is still recharging.") + return@on true + } + + class RingDialogue(val star: ShootingStar) : DialogueFile() { + val shouldWarn = when (star.location) { + "North Edgeville mining site", + "Southern wilderness mine", + "Wilderness hobgoblin mine", + "Pirates' Hideout mine", + "Lava Maze mining site", + "Mage Arena bank" -> true + else -> false + } + + override fun handle(componentID: Int, buttonID: Int) { + fun teleportToStar(player: Player) { + val condition: (p: Player) -> Boolean = when (star.location.toLowerCase()) { + "canifis bank" -> {p -> requireQuest(p, Quests.PRIEST_IN_PERIL, "to access this.")} + //"burgh de rott bank" -> {p -> hasRequirement(p, Quests.IN_AID_OF_THE_MYREQUE)} //disabled: crash + "crafting guild" -> {p -> hasLevelStat(p, Skills.CRAFTING, 40)} + "lletya bank" -> {p -> hasRequirement(p, Quests.MOURNINGS_END_PART_I)} + "jatizso mine" -> {p -> hasRequirement(p, Quests.THE_FREMENNIK_ISLES)} + "south crandor mining site" -> {p -> hasRequirement(p, Quests.DRAGON_SLAYER)} + "shilo village mining site" -> {p -> hasRequirement(p, Quests.SHILO_VILLAGE)} + "mos le'harmless bank" -> {p -> hasRequirement(p, Quests.CABIN_FEVER)} //needs to be updated to check for completion when the quest releases; https://runescape.wiki/w/Mos_Le%27Harmless?oldid=913025 + "lunar isle mine" -> {p -> hasRequirement(p, Quests.LUNAR_DIPLOMACY)} + "miscellania coal mine" -> {p -> requireQuest(p, Quests.THE_FREMENNIK_TRIALS, "to access this.")} + //"neitiznot runite mine" -> {p -> hasRequirement(p, Quests.THE_FREMENNIK_ISLES)} //disabled: currently not reachable + else -> {_ -> true} + } + if (!condition.invoke(player)) { + sendDialogue(player,"Magical forces prevent your teleportation.") + } else if (teleport(player, star.crash_locations[star.location]!!.transform(0, -1, 0), TeleportManager.TeleportType.MINIGAME)) { + getRingStoreFile()[player.username.toLowerCase()] = true + } + } + when (stage) { + 0 -> dialogue(if (star.spriteSpawned) "The star sprite has already been freed." else "The star sprite is still trapped.").also { if (shouldWarn) stage++ else stage += 2 } + 1 -> dialogue("WARNING: The star is located in the wilderness.").also { stage++ } + 2 -> player.dialogueInterpreter.sendOptions("Teleport to the star?", "Yes", "No").also { stage++ } + 3 -> when (buttonID) { + 1 -> end().also { teleportToStar(player) } + 2 -> end() + } + } + } + } + + openDialogue(player, RingDialogue(star)) + return@on true + } + } + + override fun defineCommands() { + define("tostar", Privilege.ADMIN) { player, _ -> + teleport(player, star.starObject.location.transform(1,1,0)) + } + + define("submit", Privilege.ADMIN) { _, _ -> + star.rebuildVars() + star.fire() + } + + define("resetsprite", Privilege.ADMIN) { player, _ -> + player.savedData.globalData.starSpriteDelay = 0L + } + } + + override fun startup() { + log(this::class.java, Log.FINE, "Shooting Stars initialized.") + } + + private data class ScoreboardEntry(val player: String, val time: Int) + + companion object { + private val star = ShootingStar() + private val tickDelay = if(GameWorld.settings?.isDevMode == true) 200 else 25000 + private val scoreboardEntries = ArrayList() + private val scoreboardIface = 787 + val SHOOTING_STARS = ShootingStarType.values().map(ShootingStarType::objectId).toIntArray() + val STAR_DUST = Items.STARDUST_13727 + val RING = Items.RING_OF_THE_STAR_SPRITE_14652 + + + @JvmStatic fun submitScoreBoard(player: Player) + { + if(scoreboardEntries.size == 5) + scoreboardEntries.removeAt(0) + scoreboardEntries.add(ScoreboardEntry(player.username, GameWorld.ticks)) + } + + @JvmStatic fun getStar(): ShootingStar + { + return star + } + + @JvmStatic fun getStoreFile() : JSONObject { + return ServerStore.getArchive("shooting-star") + } + + @JvmStatic fun getRingStoreFile() : JSONObject { + return ServerStore.getArchive("daily-star-ring") + } + + fun getStarDust(player: Player): Int { + return player.inventory.getAmount(STAR_DUST) + player.bank.getAmount(STAR_DUST) + } + } +} diff --git a/Server/src/main/content/global/activity/shootingstar/StarBonus.kt b/Server/src/main/content/global/activity/shootingstar/StarBonus.kt new file mode 100644 index 0000000..d0c764e --- /dev/null +++ b/Server/src/main/content/global/activity/shootingstar/StarBonus.kt @@ -0,0 +1,28 @@ +package content.global.activity.shootingstar + +import core.api.* +import core.game.system.timer.* +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import org.json.simple.* + +class StarBonus : PersistTimer (1, "shootingstar:bonus") { + var ticksLeft = 1500 + + override fun save (root: JSONObject, entity: Entity) { + root["ticksLeft"] = ticksLeft.toString() + } + + override fun parse (root: JSONObject, entity: Entity) { + ticksLeft = root["ticksLeft"].toString().toInt() + } + + override fun run (entity: Entity) : Boolean { + if (entity is Player && ticksLeft == 500) { + entity.sendMessage("You have 5 minutes of your mining bonus left") + } else if (entity is Player && ticksLeft == 0) { + entity.sendMessage("Your mining bonus has run out!") + } + return ticksLeft-- > 0 + } +} diff --git a/Server/src/main/content/global/activity/shootingstar/StarChartPlugin.java b/Server/src/main/content/global/activity/shootingstar/StarChartPlugin.java new file mode 100644 index 0000000..9ab9778 --- /dev/null +++ b/Server/src/main/content/global/activity/shootingstar/StarChartPlugin.java @@ -0,0 +1,51 @@ +package content.global.activity.shootingstar; + +import core.cache.def.impl.SceneryDefinition; +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.plugin.Plugin; +import core.plugin.ClassScanner; +import core.plugin.PluginManifest; + +@PluginManifest(name="ShootingStars") +public class StarChartPlugin extends ComponentPlugin { + private Component iface = new Component(104); + private int index= 19; + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + + return true; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ClassScanner.definePlugin(new StarChartOptions()); + ComponentDefinition.forId(iface.getId()).setPlugin(this); + return this; + } + + public class StarChartOptions extends OptionHandler{ + + @Override + public boolean handle(Player player, Node node, String option) { + player.getInterfaceManager().open(iface); + return true; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(25582).getHandlers().put("option:look-at",this); + SceneryDefinition.forId(25581).getHandlers().put("option:look-at",this); + SceneryDefinition.forId(25580).getHandlers().put("option:look-at",this); + SceneryDefinition.forId(25583).getHandlers().put("option:look-at",this); + SceneryDefinition.forId(25579).getHandlers().put("option:look-at",this); + SceneryDefinition.forId(25578).getHandlers().put("option:look-at",this); + return this; + } + } +} diff --git a/Server/src/main/content/global/activity/shootingstar/StarSpriteDialogue.kt b/Server/src/main/content/global/activity/shootingstar/StarSpriteDialogue.kt new file mode 100644 index 0000000..7eebc66 --- /dev/null +++ b/Server/src/main/content/global/activity/shootingstar/StarSpriteDialogue.kt @@ -0,0 +1,283 @@ +package content.global.activity.shootingstar + +import core.api.Container +import core.api.* +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import core.tools.RandomFunction +import org.json.simple.JSONObject +import org.rs09.consts.Items +import core.ServerStore +import core.ServerStore.Companion.getBoolean +import core.tools.END_DIALOGUE +import core.tools.secondsToTicks +import core.tools.colorize +import java.util.concurrent.TimeUnit + +/** + * Dialogue for the star sprite. + */ +@Initializable +class StarSpriteDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin(player) { + + /** + * The cosmic rune item id. + */ + val COSMIC_RUNE = 564 + + /** + * The astral rune item id. + */ + val ASTRAL_RUNE = 9075 + + /** + * The gold ore item id. + */ + val GOLD_ORE = 445 + + /** + * The coins id. + */ + val COINS = 995 + + /** + * The amplifier amount. + */ + val AMPLIFIER = 1.0 + + + /** + * Constructs the star sprite dialogue. + */ + fun StarSpriteDialogue() { + /* + * empty. + */ + } + + override fun newInstance(player: Player?): core.game.dialogue.DialoguePlugin? { + return StarSpriteDialogue(player) + } + + override fun open(vararg args: Any): Boolean { + npc = args[0] as NPC + if (inInventory(player, Items.ANCIENT_BLUEPRINT_14651) && !getAttribute(player, "star-ring:bp-shown", false)) { + npcl(core.game.dialogue.FacialExpression.NEUTRAL, "I see you got ahold of a blueprint of those silly old rings we used to make.") + stage = 1000 + } else if (inInventory(player, Items.ANCIENT_BLUEPRINT_14651) && getAttribute(player, "star-ring:bp-shown", false)) { + playerl(core.game.dialogue.FacialExpression.HALF_ASKING, "So about those rings...") + stage = 2000 + } else if (getStoreFile().getBoolean(player.username.toLowerCase()) || !player.getInventory().contains(ShootingStarPlugin.STAR_DUST, 1)) { + npc("Hello, strange creature.") + stage = 0 + } else { + npc("Thank you for helping me out of here.") + stage = 50 + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> { + npc("I'm a star sprite! I was in my star in the sky, when it", "lost control and crashed into the ground. With half my", "star sticking into the ground, I became stuck.", "Fortunately, I was mined out by the kind creatures of") + stage++ + } + 1 -> { + npc("your race.") + stage++ + } + 2 -> { + options("What's a star sprite?", "What are you going to do without your star?", "I thought stars were huge balls of burning gas.", "Well, I'm glad you're okay.") + stage++ + } + 3 -> when (buttonId) { + 1 -> { + player("What's a star sprite?") + stage = 10 + } + 2 -> { + player("What are you going to do without your star?") + stage = 20 + } + 3 -> { + player("I thought stars were huge balls of burning gas.") + stage = 30 + } + 4 -> { + player("Well, I'm glad you're okay.") + stage = 40 + } + } + 10 -> { + npc("We're what makes the stars in the sky shine. I made", "this star shine when it was in the sky.") + stage++ + } + 11 -> { + options("What are you going to do without your star?", "I thought stars were huge balls of burning gas.", "Well, I'm glad you're okay.") + stage++ + } + 12 -> when (buttonId) { + 1 -> { + player("What are you going to do without your star?") + stage = 20 + } + 2 -> { + player("I thought stars were huge balls of burning gas.") + stage = 30 + } + 3 -> { + player("Well, I'm glad you're okay.") + stage = 40 + } + } + 20 -> { + npc("Don't worry about me. I'm sure I'll find some good", "rocks around here and get back up into the sky in no", "time.") + stage++ + } + 21 -> { + options("What's a star sprite?", "I thought stars were huge balls of burning gas.", "Well, I'm glad you're okay.") + stage++ + } + 22 -> when (buttonId) { + 1 -> { + player("What's a star sprite?") + stage = 10 + } + 2 -> { + player("I thought stars were huge balls of burning gas.") + stage = 30 + } + 3 -> { + player("Well, I'm glad you're okay.") + stage = 40 + } + } + 30 -> { + npc("Most of them are, but a lot of shooting stars on this", "plane of the multiverse are rocks with star sprites in", "them.") + stage++ + } + 31 -> { + options("What's a star sprite?", "What are you going to do without your star?", "Well, I'm glad you're okay.") + stage++ + } + 32 -> when (buttonId) { + 1 -> { + player("What's a star sprite?") + stage = 10 + } + 2 -> { + player("What are you going to do without your star?") + stage = 20 + } + 3 -> { + player("Well, I'm glad you're okay.") + stage = 40 + } + } + 40 -> { + npc("Thank you.") + stage++ + } + 41 -> end() + 50 -> { + val wearingRing = inEquipment(player, Items.RING_OF_THE_STAR_SPRITE_14652) + val dust = if (player.getInventory().getAmount(ShootingStarPlugin.STAR_DUST) > 200) 200 else player.getInventory().getAmount(ShootingStarPlugin.STAR_DUST) + if (player.getInventory().remove(Item(ShootingStarPlugin.STAR_DUST, dust))) { + val cosmicRunes = (Math.ceil(0.76 * dust) * AMPLIFIER).toInt() + val astralRunes = (Math.ceil(0.26 * dust) * AMPLIFIER).toInt() + val goldOre = (Math.ceil(0.1 * dust) * AMPLIFIER).toInt() + val coins = (Math.ceil(250.0 * dust) * AMPLIFIER).toInt() // limits the amount of gp per turn-in to 90k, same as 2009 rs, and minimum from all stardust from a level 1 star works out to 50k, same as rs in 2009 + player.getInventory().add(Item(COSMIC_RUNE, cosmicRunes), player) + player.getInventory().add(Item(ASTRAL_RUNE, astralRunes), player) + player.getInventory().add(Item(GOLD_ORE, goldOre), player) + player.getInventory().add(Item(COINS, coins), player) + npc("I have rewarded you by making it so you can mine", "extra ore for the next 15 minutes. Also, have $cosmicRunes", "cosmic runes, $astralRunes astral runes, $goldOre gold ore and $coins", "coins.") + + getStoreFile()[player.username.toLowerCase()] = true //flag daily as completed + + val timer = getOrStartTimer (player) + timer.ticksLeft = 1500 + + if(wearingRing){ + val item = intArrayOf(Items.COSMIC_RUNE_564, Items.ASTRAL_RUNE_9075, Items.GOLD_ORE_445, Items.COINS_995).random() + val amount = when(item){ + Items.COSMIC_RUNE_564 -> cosmicRunes + Items.ASTRAL_RUNE_9075 -> astralRunes + Items.GOLD_ORE_445 -> goldOre + Items.COINS_995 -> coins + else -> 0 + } + rollForRingBonus(player, item, amount) + } + } + + if(!inInventory(player, Items.ANCIENT_BLUEPRINT_14651) && !inBank(player, Items.ANCIENT_BLUEPRINT_14651) && RandomFunction.roll(500)){ + addItemOrDrop(player, Items.ANCIENT_BLUEPRINT_14651, 1) + sendMessage(player, colorize("%RThe Star Sprite dropped what looks like some ancient piece of paper and you pick it up.")) + sendNews("${player.username} found an Ancient Blueprint while mining a shooting star!") + } + stage = 52 + } + 52 -> end() + + //Inauthentic ring-based dialogue + 1000 -> playerl(core.game.dialogue.FacialExpression.ASKING, "Oh, you mean this?").also { stage++ } + 1001 -> player.dialogueInterpreter.sendItemMessage(Items.ANCIENT_BLUEPRINT_14651, "You show the blueprint to the Star Sprite.").also { stage++ } + 1002 -> npcl(core.game.dialogue.FacialExpression.ASKING, "Yeah, that's the one, alright!").also { stage++ } + 1003 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "I'll tell you what.. if you can get ahold of the resources needed to make one, I'm sure me or one of my kin would craft it for you.").also { stage++ } + 1004 -> playerl(core.game.dialogue.FacialExpression.ASKING, "You'd just do that for me? For free?").also { stage++ } + 1005 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "I don't see why not. We used to make these for fun and hand them out to adventurers all the time.").also { stage++ } + 1006 -> playerl(core.game.dialogue.FacialExpression.ASKING, "Well, thanks! So.. what do we need to make one?").also { stage++ } + 1007 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "Looking at the blueprint here...").also { stage++ } + 1008 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "Yes, it seems we need a ring mould, a silver bar, a cut dragonstone and 200 stardust. Oh, and make sure to bring this blueprint with you.").also { stage++ } + 1009 -> playerl(core.game.dialogue.FacialExpression.FRIENDLY, "Thanks, I'll get right on it!").also { stage++ } + 1010 -> playerl(core.game.dialogue.FacialExpression.ASKING, "So just to make sure I've got it right, I need a ring mould, a silver bar, a cut dragonstone and 200 stardust, as well as this blueprint?").also { stage++ } + 1011 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "Yeah, you've got it, human. Any of my kin should be able to do this for you.").also { stage++; setAttribute(player, "/save:star-ring:bp-shown", true) } + 1012 -> playerl(core.game.dialogue.FacialExpression.FRIENDLY, "Thanks!").also { stage = END_DIALOGUE } + + 2000 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "Yes, did you bring the components to make it, human?").also { stage++ } + 2001 -> if(inInventory(player, Items.DRAGONSTONE_1615,1) && inInventory(player, Items.RING_MOULD_1592, 1) && inInventory(player, Items.STARDUST_13727, 200) && inInventory(player, Items.SILVER_BAR_2355, 1)){ + playerl(core.game.dialogue.FacialExpression.FRIENDLY, "Yes, I have them right here, friend.").also { stage++ } + } else { + playerl(core.game.dialogue.FacialExpression.HALF_GUILTY, "I'm afraid not, what did I need again?").also { stage = 2100 } + } + 2002 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "Excellent, give me just a moment here...").also { stage++ } + 2003 -> sendDialogue("You watch as the Star Sprite casts some strange spell.").also { stage++ } + 2004 -> if(removeItem(player, Items.SILVER_BAR_2355, Container.INVENTORY) && removeItem(player, Items.DRAGONSTONE_1615, Container.INVENTORY) && removeItem(player, Item(Items.STARDUST_13727, 200), Container.INVENTORY)){ + addItem(player, Items.RING_OF_THE_STAR_SPRITE_14652) + player.dialogueInterpreter.sendItemMessage(Items.RING_OF_THE_STAR_SPRITE_14652, "The Star Sprite hands you a strange ring.").also { stage++ } + } else end() + 2005 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "There you go, I hope you enjoy it!").also { stage++ } + 2006 -> playerl(core.game.dialogue.FacialExpression.FRIENDLY, "Thank you!").also { stage = END_DIALOGUE } + + 2100 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "A ring mould, a cut dragonstone, a silver bar and 200 stardust.").also { stage = END_DIALOGUE } + } + return true + } + + override fun getIds(): IntArray? { + return intArrayOf(8091) + } + + fun rollForRingBonus(player: Player, bonusId: Int, bonusBaseAmt: Int){ + if(RandomFunction.roll(3)){ + var bonus = getOrStartTimer (player) + bonus.ticksLeft += 500 + sendMessage(player, colorize("%RYour ring shines dimly as if imbued with energy.")) + } else if(RandomFunction.roll(5)){ + addItem(player, bonusId, bonusBaseAmt) + sendMessage(player, colorize("%RYour ring shines brightly as if surging with energy and then fades out.")) + } else if(RandomFunction.roll(25)){ + getStoreFile()[player.username.toLowerCase()] = false //flag daily as uncompleted + sendMessage(player, colorize("%RYour ring vibrates briefly as if surging with power, and then stops.")) + } + } + + fun getStoreFile(): JSONObject{ + return ServerStore.getArchive("daily-shooting-star") + } + +} diff --git a/Server/src/main/content/global/activity/ttrail/ClueLevel.java b/Server/src/main/content/global/activity/ttrail/ClueLevel.java new file mode 100644 index 0000000..91a9ef0 --- /dev/null +++ b/Server/src/main/content/global/activity/ttrail/ClueLevel.java @@ -0,0 +1,197 @@ +package content.global.activity.ttrail; + +import core.game.component.Component; +import core.game.container.access.InterfaceContainer; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import org.rs09.consts.Items; +import core.game.world.GameWorld; +import core.tools.RandomFunction; + +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.List; + +import core.api.IfaceSettingsBuilder; + +import core.game.system.config.ClueRewardParser; + +import static core.api.ContentAPIKt.addItemOrDrop; + +/** + * A clue scroll level. + */ +public enum ClueLevel { + EASY(Items.CASKET_2714, 1, 5), + MEDIUM(Items.CASKET_2717, 1, 6), + HARD(Items.CASKET_2720, 1, 8), + UNKNOWN(0, 0, 0) + ; + + public int casketId, minSteps, maxSteps; + + private ClueLevel(int casketId, int minSteps, int maxSteps) { + this.casketId = casketId; + this.minSteps = minSteps; + this.maxSteps = maxSteps; + } + + private static ClueLevel getLevelForCasket(Item casket) { + switch (casket.getId()) { + case Items.CASKET_2714: + return ClueLevel.EASY; + case Items.CASKET_2717: + return ClueLevel.MEDIUM; + case Items.CASKET_2720: + return ClueLevel.HARD; + } + + return ClueLevel.UNKNOWN; + } + + public static void open(Player player, Item casket) { + if (casket == null || !player.getInventory().containsItem(casket)) { + return; + } + + TreasureTrailManager playerTrails = TreasureTrailManager.getInstance(player); + + boolean trailCompleted = playerTrails.isCompleted(); + boolean isDevMode = GameWorld.getSettings().isDevMode(); + + ClueLevel clueLevel = getLevelForCasket(casket); + + if (trailCompleted || isDevMode) { + List rewards = rollLoot(player, clueLevel); + + player.getInterfaceManager().open(new Component(364)); + + if (player.getInventory().remove(casket)) { + long rewardValue = 0L; + + for (Item reward : rewards) { + addItemOrDrop(player, reward.getId(), reward.getAmount()); + rewardValue += reward.getValue(); + } + + playerTrails.incrementClues(clueLevel); + playerTrails.clearTrail(); + + player.sendMessage("Well done, you've completed the Treasure Trail!"); + player.sendMessage( + getChatColor(clueLevel) + + "You have completed " + + playerTrails.getCompletedClues(clueLevel) + + " " + + clueLevel.getName().toLowerCase() + + " clues." + ); + + player.sendMessage( + "Your clue is worth approximately " + + NumberFormat.getInstance().format(rewardValue) + + " coins!" + ); + + int clueIfaceSettings = new IfaceSettingsBuilder().enableAllOptions().build(); + player.getPacketDispatch().sendIfaceSettings(clueIfaceSettings, 4, 364, 0, 6); + InterfaceContainer.generateItems( + player, + rewards.toArray(new Item[] {}), + new String[] {""}, + 364, 4, 3, 3 + ); + } + return; + } + + Item newClue = ClueScrollPlugin.getClue(clueLevel); + + if (casket != null && player.getInventory().remove(casket, casket.getSlot(), true)) { + player.getInventory().replace(newClue, casket.getSlot()); + } else { + player.getInventory().add(newClue); + } + + playerTrails.setClueId(newClue.getId()); + player.getDialogueInterpreter().sendItemMessage(newClue, "You've found another clue!"); + } + + public static List rollLoot(Player player, ClueLevel level) { + ArrayList loot = new ArrayList(); + int itemCount = RandomFunction.random(1,6); + + if (level == ClueLevel.HARD) { + itemCount = Math.max(itemCount, RandomFunction.random(4,6)); + } + + for (; itemCount > 0; itemCount--) { + switch (level) { + case EASY: + loot.addAll(ClueRewardParser.getEasyTable().roll(player)); + break; + case MEDIUM: + loot.addAll(ClueRewardParser.getMedTable().roll(player)); + break; + case HARD: + loot.addAll(ClueRewardParser.getHardTable().roll(player)); + break; + } + } + + if (level == ClueLevel.HARD && RandomFunction.random(100) == 50) { + loot.addAll(ClueRewardParser.getRareTable().roll(player)); + } + + return loot; + } + + /** + * Gets the Chat color to send on completed clues. + * @param level The clue level. + * @return the chat color. + */ + public static String getChatColor(ClueLevel level) { + if (level == ClueLevel.HARD) { + return ""; + } + if (level == ClueLevel.MEDIUM) { + return ""; + } + return ""; + } + /** + * Gets the maximum length. + * + * @return the length. + */ + public int getMaximumLength() { + return maxSteps; + } + + /** + * Gets the minimum length. + * + * @return the length. + */ + public int getMinimumLength() { + return minSteps; + } + + /** + * Gets the bcasket. + * + * @return the casket + */ + public Item getCasket() { + return new Item(casketId); + } + + /** + * Gets the name of the clue level. + * @return the name. + */ + public String getName() { + return toString(); + } +} diff --git a/Server/src/main/content/global/activity/ttrail/ClueScrollPlugin.java b/Server/src/main/content/global/activity/ttrail/ClueScrollPlugin.java new file mode 100644 index 0000000..13efad3 --- /dev/null +++ b/Server/src/main/content/global/activity/ttrail/ClueScrollPlugin.java @@ -0,0 +1,236 @@ +package content.global.activity.ttrail; + +import core.game.component.Component; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.tools.Log; +import core.tools.SystemLogger; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneBuilder; +import core.plugin.Plugin; +import core.tools.RandomFunction; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static core.api.ContentAPIKt.log; + +/** + * Represents a clue scroll plugin. + * @author Vexia + */ +public abstract class ClueScrollPlugin extends MapZone implements Plugin { + + /** + * The wilderness cape ids. + */ + protected static final int[] WILDY_CAPES = new int[] { 4315, 4316, 4317, 4318, 4319, 4320, 4321, 4322, 4323, 4324, 4325, 4326, 4327, 4328, 4329, 4330, 4331, 4332, 4333, 4334, 4335, 4336, 4337, 4338, 4339, 4340, 4341, 4342, 4343, 4344, 4345, 4346, 4347, 4348, 4349, 4350, 4351, 4352, 4353, 4354, 4355, 4356, 4357, 4358, 4359, 4360, 4361, 4362, 4363, 4364, 4365, 4366, 4367, 4368, 4369, 4370, 4371, 4372, 4373, 4374, 4375, 4376, 4377, 4378, 4379, 4380, 4381, 4382, 4383, 4384, 4385, 4386, 4387, 4388, 4389, 4390, 4391, 4392, 4393, 4394, 4395, 4396, 4397, 4398, 4399, 4400, 4401, 4402, 4403, 4404, 4405, 4406, 4407, 4408, 4409, 4410, 4411, 4412, 4413, 4414, 10638 }; + + /** + * The mapping of clue scrolls. + */ + private static final Map CLUE_SCROLLS = new HashMap<>(); + + /** + * A map of pre organized clue scrolls. + */ + private static final Map> ORGANIZED = new HashMap<>(); + + /** + * The id of the clue scroll. + */ + protected final int clueId; + + /** + * The clue scroll level. + */ + protected final ClueLevel level; + + /** + * The interface id of the clue. + */ + protected final int interfaceId; + + /** + * The zone borders. + */ + protected final ZoneBorders[] borders; + + /** + * Constructs a new {@Code ClueScrollPlugin} {@Code Object} + * @param clueId the id. + * @param level the level. + * @param interfaceId the id. + */ + public ClueScrollPlugin(final String name, final int clueId, ClueLevel level, final int interfaceId, final ZoneBorders... borders) { + super(name, true); + this.clueId = clueId; + this.level = level; + this.interfaceId = interfaceId; + this.borders = borders; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + /** + * Rewards the player with a casket. + * @param player the player. + * @param casket if we give a casket. + */ + public void reward(Player player, boolean casket) { + Item clue = player.getInventory().getItem(new Item(getClueId())); + if (clue == null) { + return; + } + nextStage(player, clue); + if (casket) { + player.getInventory().replace(level.getCasket(), clue.getSlot()); + } else { + player.getInventory().remove(clue); + } + } + + /** + * Rewards the player. + * @param player the player. + */ + public void reward(Player player) { + reward(player, true); + } + + /** + * Increments the next stage of the clue. + * @param player the player. + * @param clue the clue. + */ + public void nextStage(Player player, Item clue) { + if (!TreasureTrailManager.getInstance(player).hasTrail() || TreasureTrailManager.getInstance(player).hasTrail() && clue.getId() != TreasureTrailManager.getInstance(player).getClueId()) { + TreasureTrailManager.getInstance(player).startTrail(this); + } + int currentStage = TreasureTrailManager.getInstance(player).getTrailStage(); + if (currentStage >= TreasureTrailManager.getInstance(player).getTrailLength()) { + TreasureTrailManager.getInstance(player).clearTrail(); + } else { + TreasureTrailManager.getInstance(player).incrementStage(); + } + } + + /** + * Reads a clue scroll. + * @param player the player. + */ + public void read(Player player) { + if (player.getInterfaceManager().isOpened()) { + player.sendMessage("Please finish what you're doing first."); + return; + } + player.getInterfaceManager().open(new Component(interfaceId)); + } + + /** + * Reigsters a clue scroll into the repository. + * @param clue the plugin. + */ + public void register(ClueScrollPlugin clue) { + if(clue.getClueId() == 2681) + return; + if (CLUE_SCROLLS.containsKey(clue.getClueId())) { + log(this.getClass(), Log.ERR, "Error! Plugin already registered with clue id - " + clue.getClueId() + ", trying to register " + clue.getClass().getCanonicalName() + " the real plugin using the id is " + CLUE_SCROLLS.get(clue.getClueId()).getClass().getCanonicalName() + "!"); + return; + } + List organized = (List) ORGANIZED.get(clue.getLevel()); + if (organized == null) { + organized = new ArrayList<>(20); + } + organized.add(clue); + ZoneBuilder.configure(clue); + CLUE_SCROLLS.put(clue.getClueId(), clue); + ORGANIZED.put(clue.getLevel(), organized); + } + + @Override + public void configure() { + if (borders == null) { + return; + } + for (ZoneBorders border : borders) { + register(border); + } + } + + /** + * Gets a clue item. + * @param clueLevel the level. + * @return the item. + */ + public static Item getClue(ClueLevel clueLevel) { + List clues = ORGANIZED.get(clueLevel); + if (clues == null) { + log(ClueScrollPlugin.class, Log.ERR, "Error! There are no clues for level " + clueLevel + "!"); + return null; + } + ClueScrollPlugin clue = clues.get(RandomFunction.random(clues.size())); + return new Item(clue.getClueId()); + } + + /** + * Checks if the player has equipment. + * @param player the player. + * @param equipment the equipment. + * @return {@code True} if so. + */ + public boolean hasEquipment(Player player, int[][] equipment) { + if (equipment == null || equipment.length == 0) { + return true; + } + int hasAmt = 0; + for (int i = 0; i < equipment.length; i++) { + for (int k = 0; k < equipment[i].length; k++) { + if (player.getEquipment().contains(equipment[i][k], 1)) { + hasAmt++; + break; + } + } + } + return hasAmt == equipment.length; + } + + /** + * Gets the bclueId. + * @return the clueId + */ + public int getClueId() { + return clueId; + } + + /** + * Gets the blevel. + * @return the level + */ + public ClueLevel getLevel() { + return level; + } + + /** + * Gets the bclueScrolls. + * @return the clueScrolls + */ + public static Map getClueScrolls() { + return CLUE_SCROLLS; + } + + /** + * Gets the binterfaceId. + * @return the interfaceId + */ + public int getInterfaceId() { + return interfaceId; + } + +} diff --git a/Server/src/main/content/global/activity/ttrail/CoordinateCluePlugin.java b/Server/src/main/content/global/activity/ttrail/CoordinateCluePlugin.java new file mode 100644 index 0000000..b09067d --- /dev/null +++ b/Server/src/main/content/global/activity/ttrail/CoordinateCluePlugin.java @@ -0,0 +1,100 @@ +package content.global.activity.ttrail; + +import core.game.world.map.Location; +import core.plugin.Plugin; + +/** + * Initializes the coordinate clues. + * @author Vexia + */ +public final class CoordinateCluePlugin extends CoordinateClueScroll { + + /** + * Constructs a new {@code CoordinateCluePlugin} {@code Object} + */ + public CoordinateCluePlugin() { + this(null, -1, null, null, null); + } + + /** + * Constructs a new {@code CoordinateCluePlugin} {@code Object} + * @param name the name. + * @param clueId the clue id. + * @param level the level. + * @param location the location. + * @param clue the clue. + */ + public CoordinateCluePlugin(String name, int clueId, ClueLevel level, Location location, String clue) { + super(name, clueId, level, location, clue); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + register(new CoordinateCluePlugin("tree-gnome-coord", 2807, ClueLevel.MEDIUM, new Location(2478, 3158, 0), "00 degrees 05 minutes south
01 degrees 13 minutes east")); + register(new CoordinateCluePlugin("karamja-coord", 2809, ClueLevel.MEDIUM, new Location(2888, 3153, 0), "00 degrees 13 minutes south
13 degrees 58 minutes east")); + register(new CoordinateCluePlugin("brimhaven-coord", 2811, ClueLevel.MEDIUM, new Location(2743, 3151, 0), "00 degrees 18 minutes south
09 degrees 28 minutes east")); + register(new CoordinateCluePlugin("lumbridge-swamp-coord", 2813, ClueLevel.MEDIUM, new Location(3183, 3151, 0), "00 degrees 20 minutes south
23 degrees 15 minutes east")); + register(new CoordinateCluePlugin("zanaris-shed-coord", 2815, ClueLevel.MEDIUM, new Location(3217, 3178, 0), "00 degrees 30 minutes north
24 degrees 16 minutes east")); + register(new CoordinateCluePlugin("port-sarim-coord", 2817, ClueLevel.MEDIUM, new Location(3007, 3145, 0), "00 degrees 31 minutes south
17 degrees 43 minutes east")); + register(new CoordinateCluePlugin("musa-point-coord", 2819, ClueLevel.MEDIUM, new Location(2896, 3119, 0), "01 degrees 18 minutes south
14 degrees 15 minutes east")); + register(new CoordinateCluePlugin("moss-giant-coord", 2821, ClueLevel.MEDIUM, new Location(2696, 3206, 0), "01 degrees 26 minutes north
08 degrees 01 minutes east")); + register(new CoordinateCluePlugin("hazelmere-coord", 2823, ClueLevel.MEDIUM, new Location(2680, 3111, 0), "01 degrees 35 minutes south
07 degrees 28 minutes east")); + register(new CoordinateCluePlugin("uzer-coord", 2825, ClueLevel.MEDIUM, new Location(3510, 3075, 0), "02 degrees 43 minutes south
33 degrees 26 minutes east")); + register(new CoordinateCluePlugin("ham-coord", 2827, ClueLevel.MEDIUM, new Location(3161, 3251, 0), "02 degrees 48 minutes north
22 degrees 30 minutes east")); + register(new CoordinateCluePlugin("ardy-zoo-coord", 2829, ClueLevel.MEDIUM, new Location(2644, 3251, 0), "02 degrees 50 minutes north
06 degrees 20 minutes east")); + register(new CoordinateCluePlugin("nature-altar-coord", 2831, ClueLevel.HARD, new Location(2874, 3047, 0), "03 degrees 35 minutes south
13 degrees 35 minutes east")); + register(new CoordinateCluePlugin("shilo-mine-coord", 2833, ClueLevel.MEDIUM, new Location(2849, 3033, 0), "04 degrees 00 minutes south
12 degrees 46 minutes east")); + register(new CoordinateCluePlugin("bedapin-camp-coord", 2835, ClueLevel.HARD, new Location(3168, 3041, 0), "03 degrees 45 minutes south
22 degrees 45 minutes east")); + // register(new CoordinateCluePlugin("gorad-coord", 2837, + // ClueLevel.HARD, new Location(2580, 3029, 0), + // "04 degrees 05 minutes south
04 degrees 24 minutes east")); + register(new CoordinateCluePlugin("crandor-coord", 2839, ClueLevel.MEDIUM, new Location(2848, 3297, 0), "04 degrees 13 minutes north
12 degrees 45 minutes east")); + register(new CoordinateCluePlugin("champions-guild-coord", 2841, ClueLevel.MEDIUM, new Location(3179, 3343, 0), "05 degrees 43 minutes north
23 degrees 05 minutes east")); + register(new CoordinateCluePlugin("cairn-island-coord", 2843, ClueLevel.HARD, new Location(2764, 2974, 0), "05 degrees 50 minutes south
10 degrees 05 minutes east")); + register(new CoordinateCluePlugin("bandit-camp-coord", 2845, ClueLevel.HARD, new Location(3139, 2969, 0), "06 degrees 00 minutes south
21 degrees 48 minutes east")); + // register(new CoordinateCluePlugin("east-karamja-coord", 2847, + // ClueLevel.HARD, new Location(2924, 2963, 0), + // "06 degrees 11 minutes south
15 degrees 07 minutes east")); + register(new CoordinateCluePlugin("three-ponds-coord", 2849, ClueLevel.MEDIUM, new Location(2383, 3369, 0), "06 degrees 31 minutes north
01 degrees 46 minutes west")); + register(new CoordinateCluePlugin("draynor-manor-coord", 2851, ClueLevel.MEDIUM, new Location(3120, 3384, 0), "06 degrees 58 minutes north
21 degrees 16 minutes east")); + register(new CoordinateCluePlugin("nature-spirit-coord", 2853, ClueLevel.MEDIUM, new Location(3430, 3388, 0), "07 degrees 05 minutes north
30 degrees 56 minutes east")); + register(new CoordinateCluePlugin("southeast-taverly-coord", 2855, ClueLevel.MEDIUM, new Location(2920, 3404, 0), "07 degrees 33 minutes north
15 degrees 00 minutes east")); + register(new CoordinateCluePlugin("swamp-coord", 2856, ClueLevel.HARD, new Location(3441, 3419, 0), "08 degrees 03 minutes north
31 degrees 16 minutes east")); + register(new CoordinateCluePlugin("feldip-coord", 2857, ClueLevel.MEDIUM, new Location(2593, 2899, 0), "08 degrees 11 minutes south
4 degrees 48 minutes east")); + register(new CoordinateCluePlugin("gnome-terribirds-coord", 2858, ClueLevel.MEDIUM, new Location(2387, 3435, 0), "08 degrees 33 minutes north
01 degrees 39 minutes west")); + register(new CoordinateCluePlugin("north-gnome-terribirds-coord", 3490, ClueLevel.MEDIUM, new Location(2382, 3467, 0), "09 degrees 35 minutes north
01 degrees 50 minutes west")); + register(new CoordinateCluePlugin("ice-mountain-coord", 3491, ClueLevel.MEDIUM, new Location(3006, 3475, 0), "09 degrees 48 minutes north
17 degrees 39 minutes east")); + register(new CoordinateCluePlugin("coal-line-coord", 3492, ClueLevel.MEDIUM, new Location(2585, 3505, 0), "10 degrees 45 minutes north
04 degrees 31 minutes east")); + register(new CoordinateCluePlugin("slayer-tower-coord", 3493, ClueLevel.MEDIUM, new Location(3442, 3515, 0), "11 degrees 03 minutes north
31 degrees 20 minutes east")); + register(new CoordinateCluePlugin("gnome-stronghold-coord", 3494, ClueLevel.MEDIUM, new Location(2416, 3515, 0), "11 degrees 05 minutes north
00 degrees 45 minutes west")); + register(new CoordinateCluePlugin("eagles-peak-coord", 3495, ClueLevel.MEDIUM, new Location(2362, 3531, 0), "11 degrees 33 minutes north
02 degrees 24 minutes west")); + register(new CoordinateCluePlugin("burthorpe-coord", 3496, ClueLevel.MEDIUM, new Location(2920, 3534, 0), "11 degrees 41 minutes north
14 degrees 58 minutes east")); + register(new CoordinateCluePlugin("fenkenstrain-castle-coord", 3497, ClueLevel.MEDIUM, new Location(3548, 3559, 0), "12 degrees 28 minutes north
34 degrees 37 minutes east")); + register(new CoordinateCluePlugin("lvl-11-wildy-coord", 3498, ClueLevel.HARD, new Location(3113, 3602, 0), "13 degrees 46 minutes north
21 degrees 01 minutes east")); + register(new CoordinateCluePlugin("swaying-tree-coord", 3499, ClueLevel.MEDIUM, new Location(2735, 3639, 0), "14 degrees 54 minutes north
9 degrees 13 minutes east")); + register(new CoordinateCluePlugin("rellekka-coord", 3500, ClueLevel.MEDIUM, new Location(2680, 3652, 0), "15 degrees 22 minutes north
07 degrees 31 minutes east")); + register(new CoordinateCluePlugin("trollheim-coord", 3501, ClueLevel.HARD, new Location(2892, 3674, 0), "16 degrees 03 minutes north
14 degrees 07 minutes east")); + register(new CoordinateCluePlugin("graveyard-wildy-coord", 3502, ClueLevel.HARD, new Location(3229, 3687, 0), "16 degrees 07 minutes north
22 degrees 45 minutes east")); + // not sure if this is accessible + register(new CoordinateCluePlugin("troll-stronghold-coord", 3503, ClueLevel.HARD, new Location(2853, 3689, 0), "16 degrees 31 minutes north
12 degrees 54 minutes east")); + register(new CoordinateCluePlugin("level-22-wildy-coord", 3504, ClueLevel.HARD, new Location(3304, 3692, 0), "16 degrees 35 minutes north
27 degrees 01 minutes east")); + register(new CoordinateCluePlugin("bandit-camp-coord", 3505, ClueLevel.HARD, new Location(3055, 3696, 0), "16 degrees 43 minutes north
19 degrees 13 minutes east")); + register(new CoordinateCluePlugin("level-23-wildy-coord", 3506, ClueLevel.HARD, new Location(3302, 3696, 0), "16 degrees 43 minutes north
26 degrees 56 minutes east")); + register(new CoordinateCluePlugin("northeast-rellekka-coord", 3507, ClueLevel.HARD, new Location(2711, 3732, 0), "17 degrees 50 minutes north
08 degrees 30 minutes east")); + register(new CoordinateCluePlugin("level-29-wildy-coord", 3508, ClueLevel.HARD, new Location(2970, 3749, 0), "18 degrees 22 minutes north
16 degrees 33 minutes east")); + register(new CoordinateCluePlugin("level-31-wildy-coord", 3509, ClueLevel.HARD, new Location(3034, 3804, 0), "18 degrees 50 minutes north
20 degrees 26 minutes east")); + register(new CoordinateCluePlugin("level-35-wildy-coord", 3510, ClueLevel.HARD, new Location(3244, 3792, 0), "19 degrees 43 minutes north
25 degrees 07 minutes east")); + register(new CoordinateCluePlugin("level-36-wildy-coord", 3512, ClueLevel.HARD, new Location(3139, 3803, 0), "20 degrees 05 minutes north
21 degrees 52 minutes east")); + register(new CoordinateCluePlugin("kbd-wildy-coord", 3513, ClueLevel.HARD, new Location(3014, 3847, 0), "21 degrees 24 minutes north
17 degrees 54 minutes east")); + register(new CoordinateCluePlugin("chaos-temple-wildy-coord", 3514, ClueLevel.HARD, new Location(2946, 3818, 0), "20 degrees 33 minutes north
15 degrees 48 minutes east")); + register(new CoordinateCluePlugin("rune-rocks-wildy-coord", 3515, ClueLevel.HARD, new Location(3059, 3884, 0), "22 degrees 35 minutes north
19 degrees 18 minutes east")); + register(new CoordinateCluePlugin("demonic-ruins-wildy-coord", 3516, ClueLevel.HARD, new Location(3290, 3889, 0), "22 degrees 45 minutes north
26 degrees 33 minutes east")); + register(new CoordinateCluePlugin("rogues-castle-coord", 3518, ClueLevel.HARD, new Location(3285, 3943, 0), "24 degrees 24 minutes north
26 degrees 24 minutes east")); + register(new CoordinateCluePlugin("wildy-lever-coord", 3520, ClueLevel.HARD, new Location(3158, 3958, 0), "24 degrees 56 minutes north
22 degrees 28 minutes east")); + register(new CoordinateCluePlugin("pirates-hideout-coord", 3522, ClueLevel.HARD, new Location(3040, 3961, 0), "24 degrees 58 minutes north
18 degrees 43 minutes east")); + register(new CoordinateCluePlugin("agility-wildy-coord", 3524, ClueLevel.HARD, new Location(2987, 3964, 0), "25 degrees 03 minutes north
17 degrees 05 minutes east")); + register(new CoordinateCluePlugin("axe-hut-coord", 3525, ClueLevel.HARD, new Location(3190, 3963, 0), "25 degrees 03 minutes north
23 degrees 24 minutes east")); + return this; + } + +} diff --git a/Server/src/main/content/global/activity/ttrail/CoordinateClueScroll.java b/Server/src/main/content/global/activity/ttrail/CoordinateClueScroll.java new file mode 100644 index 0000000..b3c43a1 --- /dev/null +++ b/Server/src/main/content/global/activity/ttrail/CoordinateClueScroll.java @@ -0,0 +1,101 @@ +package content.global.activity.ttrail; + +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Graphics; + +/** + * Represents a coordinate clue scroll. + * @author Vexia + */ +public abstract class CoordinateClueScroll extends MapClueScroll { + + /** + * The sextant item. + */ + public static final Item SEXTANT = new Item(2574); + + /** + * The watch item. + */ + public static final Item WATCH = new Item(2575); + + /** + * The chart item. + */ + public static final Item CHART = new Item(2576); + + /** + * The clock tower location. + */ + public static final Location CLOCK_TOWER = new Location(2440, 3161, 0); + + /** + * The clue message. + */ + private final String clue; + + /** + * Constructs a new {@code CoordinateClueScroll} {@code Object} + * @param name the name. + * @param clueId the clue id. + * @param level the level. + * @param location the location. + * @param clue the clue. + */ + public CoordinateClueScroll(String name, int clueId, ClueLevel level, Location location, String clue) { + super(name, clueId, level, 345, location, 0); + this.clue = clue; + } + + @Override + public void read(Player player) { + for (int i = 1; i < 9; i++) { + player.getPacketDispatch().sendString("", interfaceId, i); + } + super.read(player); + player.getPacketDispatch().sendString("




" + clue.replace("
", "

"), interfaceId, 1); + } + + @Override + public void dig(Player player) { + int killedWizardClueId = player.getAttribute("killed-wizard", -1); + if (getLevel() == ClueLevel.HARD && (killedWizardClueId == -1 || killedWizardClueId != getClueId())) { + NPC wizard = player.getAttribute("t-wizard", null); + if (wizard != null && wizard.isActive()) { + return; + } + spawnWizard(player); + return; + } + super.dig(player); + player.removeAttribute("killed-wizard"); + } + + /** + * Spawns a zamorak or saradomin wizard. + * @param player the player. + */ + private void spawnWizard(Player player) { + int id = !player.getSkullManager().isWilderness() ? 1264 : 1007; + final NPC wizard = NPC.create(id, player.getLocation().transform(1, 0, 0)); + player.setAttribute("t-wizard", wizard); + wizard.setAttribute("clue", this); + wizard.setAttribute("player", player); + wizard.init(); + wizard.graphics(Graphics.create(86)); + wizard.faceTemporary(player, 1); + wizard.sendChat(id == 1264 ? "For Saradomin!" : "Die human!"); + wizard.getProperties().getCombatPulse().attack(player); + } + + /** + * Gets the clue. + * @return the clue + */ + public String getClue() { + return clue; + } +} diff --git a/Server/src/main/content/global/activity/ttrail/EmoteCluePlugin.java b/Server/src/main/content/global/activity/ttrail/EmoteCluePlugin.java new file mode 100644 index 0000000..afcb760 --- /dev/null +++ b/Server/src/main/content/global/activity/ttrail/EmoteCluePlugin.java @@ -0,0 +1,152 @@ +package content.global.activity.ttrail; + +import core.game.node.entity.player.link.emote.Emotes; +import core.game.world.map.zone.ZoneBorders; +import core.plugin.Plugin; +import core.plugin.ClassScanner; + +/** + * Initializes the emote clue plugins. + * @author Vexia + */ +public final class EmoteCluePlugin extends EmoteClueScroll { + + /** + * Constructs a new {@Code EmoteCluePlugin} {@Code Object} + */ + public EmoteCluePlugin() { + super(null, -1, null, null, null, null, null); + } + + /** + * Constructs a new {@Code EmoteCluePlugin} {@Code Object} + * @param name the name. + * @param clueId the clue id. + * @param level the level. + * @param emote the Emotes. + * @param commenceEmote the commence Emotes. + * @param equipment the equipment. + * @param clue the clue. + * @param borders the borders. + */ + public EmoteCluePlugin(String name, int clueId, ClueLevel level, Emotes emote, Emotes commenceEmote, int[][] equipment, String clue, ZoneBorders... borders) { + super(name, clueId, level, emote, commenceEmote, equipment, clue, borders); + } + + /** + * Constructs a new {@Code EmoteCluePlugin} {@Code Object} + * @param name the name. + * @param clueId the clue id. + * @param level the level. + * @param emote the Emotes. + * @param equipment the equipment. + * @param clue the clue. + * @param borders the borders. + */ + public EmoteCluePlugin(String name, int clueId, ClueLevel level, Emotes emote, int[][] equipment, String clue, ZoneBorders... borders) { + super(name, clueId, level, emote, null, equipment, clue, borders); + } + + // register(new EmoteCluePlugin(clue, clueId, level, commenceEmote, + // commenceEmote, equipment, clue, borders)); + // register(new EmoteCluePlugin(clue, clueId, level, commenceEmote, + // equipment, clue, borders)); + // register(new EmoteCluePlugin()); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + Emotes emote = Emotes.BECKON; + register(new EmoteCluePlugin("digsite-beckon", 2677, ClueLevel.MEDIUM, emote, Emotes.BOW, new int[][] { { 6328 }, { 1267 }, { 658 } }, "Beckon in the Digsite, near the
eastern winch. Bow or curtsy
before you talk to me.
Equip a green gnome hat,
snakeskin boots and an
iron pickaxe.", new ZoneBorders(3368, 3425, 3371, 3429))); + register(new EmoteCluePlugin("tai-bwo-beckon", 2678, ClueLevel.MEDIUM, emote, Emotes.CLAP, new int[][] { { 1099 }, { 2552, 2554, 2556, 2558, 2560, 2562, 2564, 2566, 2568 }, { 1143 } }, "Beckon in Tai Bwo
Wannai. Clap before
you talk to me.
Equip green
dragonhide chaps, a
ring of dueling and a
mithril medium helmet.", new ZoneBorders(2771, 3053, 2814, 3074))); + emote = Emotes.BLOW_KISS; + //register(new EmoteCluePlugin("shilo-kiss", 2681, ClueLevel.HARD, emote, new int[][] { { 4089 }, { 5016 }, { 1127 } }, "Blow a kiss between
the tables in Shilo
Village bank. Beware
of double agents!
Equip a blue mystic
hat, bone spear and
rune plate body.", new ZoneBorders(2849, 2950, 2855, 2957))); + emote = Emotes.BOW; + register(new EmoteCluePlugin("legends-guild", 2682, ClueLevel.EASY, emote, new int[][] { { 1067 }, { 1696 }, { 845 } }, "Bow outside the entrance
to the Legends' Guild.
Equip iron platelegs, an
emerald amulet and an oak
longbow.", new ZoneBorders(2726, 3346, 2731, 3349))); + emote = Emotes.RASPBERRY; + register(new EmoteCluePlugin("monkey-cage", 2679, ClueLevel.EASY, emote, new int[][] { { 1133 }, { 1075 }, { 1379 } }, "Blow a raspberry at the
monkey cage in
Ardougne Zoo.
Equip a studded
leather body, bronze
platelegs and a normal
staff with no orb.", new ZoneBorders(2597, 3274, 2609, 3284))); + register(new EmoteCluePlugin("keep-le-faye", 2680, ClueLevel.EASY, emote, new int[][] { { 1169 }, { 1115 }, { 1059 } }, "Blow raspberries out
the entrance to Keep Le
Faye.
Equip a coif, an iron
platebody and leather
gloves.", new ZoneBorders(2759, 3401, 2762, 3403))); + // register(new EmoteCluePlugin("fishing-guild-blow", 2683, + // ClueLevel.HARD, emote, new int[][] {{2890}, {2493}, {1347}}, + // "Blow a raspberry in the
Fighing Guild bank. Beware
of double agents!
Equip and elemental shield
,blue dragonhide chaps
and a rune warhammer.", + // new ZoneBorders(2586, 3418, 2590, 3422))); + emote = Emotes.CHEER; + register(new EmoteCluePlugin("druid-circle-cheer", 2684, ClueLevel.EASY, emote, new int[][] { { 4310 }, { 579 }, { 1307 } }, "Cheer at the Druids'
Circle.
Equip a blue wizard
hat, a bronze
two-handed sword and
HAM boots.", new ZoneBorders(2920, 3478, 2930, 3940))); + register(new EmoteCluePlugin("games-room-cheer", 2685, ClueLevel.EASY, emote, new int[][] {}, "Cheer at the games
room.
Have nothing equipped
at all when you do.", new ZoneBorders(2194, 4946, 2221, 4973))); + register(new EmoteCluePlugin("barb-agility-cheer", 2686, ClueLevel.MEDIUM, emote, new int[][] { { 1119 }, { 853 }, { 4315, 4316, 4317, 4318, 4319, 4320, 4321, 4322, 4323, 4324, 4325, 4326, 4327, 4328, 4329, 4330, 4331, 4332, 4333, 4334, 4335, 4336, 4337, 4338, 4339, 4340, 4341, 4342, 4343, 4344, 4345, 4346, 4347, 4348, 4349, 4350, 4351, 4352, 4353, 4354, 4355, 4356, 4357, 4358, 4359, 4360, 4361, 4362, 4363, 4364, 4365, 4366, 4367, 4368, 4369, 4370, 4371, 4372, 4373, 4374, 4375, 4376, 4377, 4378, 4379, 4380, 4381, 4382, 4383, 4384, 4385, 4386, 4387, 4388, 4389, 4390, 4391, 4392, 4393, 4394, 4395, 4396, 4397, 4398, 4399, 4400, 4401, 4402, 4403, 4404, 4405, 4406, 4407, 4408, 4409, 4410, 4411, 4412, 4413, 4414, 10638 } }, "Cheer in the Barbarian
Agility Arena.
Headbang before you
talk to me.
Equip a steel plate
body, maple shortbow, and a wilderness
cape.", new ZoneBorders(2550, 3556, 2553, 3559), new ZoneBorders(2529, 3542, 2553, 3559))); + register(new EmoteCluePlugin("edge-gen-cheer", 2687, ClueLevel.MEDIUM, emote, Emotes.DANCE, new int[][] { { 1757 }, { 1061 }, { 1059 } }, "Cheer in the Edgeville general
store. Dance
before you talk to me.
Equip a brown apron,
leather boots and
leather gloves.", new ZoneBorders(3076, 3507, 3084, 3513))); + register(new EmoteCluePlugin("ogre-pen-cheer", 2688, ClueLevel.MEDIUM, emote, Emotes.ANGRY, new int[][] { { 1135 }, { 1099 }, { 1177 } }, "Cheer in the Ogre Pen
in the Training Camp.
Show you are angry
before you talk to me.
Equip a green
dragonhide body and
chaps and a steel
square shield.", new ZoneBorders(2523, 3373, 2533, 3377))); + emote = Emotes.CLAP; + register(new EmoteCluePlugin("exam-room-clap", 2689, ClueLevel.EASY, emote, new int[][] { { 1005 }, { 628 }, { 1059 } }, "Clap in the main exam room
in the Exam Centre.
Equip a white apron, green
gnome boots and leather
gloves.", new ZoneBorders(3357, 3332, 3367, 3348))); + register(new EmoteCluePlugin("wizard-tower-clap", 2690, ClueLevel.EASY, emote, new int[][] { { 1137 }, { 1639 }, { 1005 } }, "Clap on the causeway to the
Wizards' Tower.
Equip an iron medium
helmet, emerald ring and a
white apron.", new ZoneBorders(3112, 3173, 3115, 3206))); + // 2nd plane for ardy mill + register(new EmoteCluePlugin("ardgoune-mill-clap", 2691, ClueLevel.EASY, emote, new int[][] { { 640 }, { 4300 }, { 5525 } }, "Clap on the top level of the
mill, north of East Ardougne.
Equip a blue gnome robe top,
HAM robe bottom and an
unenchanted tiara.", new ZoneBorders(2628, 3382, 2636, 3390, 2))); + register(new EmoteCluePlugin("seers-court-clap", 2692, ClueLevel.MEDIUM, emote, Emotes.SPIN, new int[][] { { 3200 }, { 4093 }, { 1643 } }, "Clap in Seers court house.
Spin before you talk to me.
Equip an adamant halberd,
blue mystic robe bottom and
a diamond ring.", new ZoneBorders(2732, 3467, 2739, 3471))); + //Fix clue remove vexia + //emote = Emotes.CRY; + register(new EmoteCluePlugin("catherby-range-cry", 2693, ClueLevel.MEDIUM, Emotes.CRY, Emotes.BOW, new int[][] { { 630 }, { 1131 }, { 2961 } }, "Cry in the Catherby
Ranging shop. Bow before you talk to me.
Equip blue gnome
boots, a hard leather
body and an
unblessed silver
sickle.", new ZoneBorders(2821, 3441, 2825, 3445))); + register(new EmoteCluePlugin("catherby-shore-cry", 2694, ClueLevel.MEDIUM, Emotes.CRY, Emotes.LAUGH, new int[][] { { 1183 }, { 8872 }, { 1121 } }, "Cry on the shore of
Catherby beach.
Laugh before you talk to me.
Equip an adamant sq
shield, a bone dagger
and mithril platebody.", new ZoneBorders(2849, 3423, 2857, 3430), new ZoneBorders(2845, 3428, 2852, 3430))); + emote = Emotes.DANCE; + register(new EmoteCluePlugin("draynor-cross-dance", 2695, ClueLevel.EASY, emote, new int[][] { { 1101 }, { 1637 }, { 839 } }, "Dance at the
crossroads north of
Draynor.
Equip an iron chain
body, a sapphire ring
and a longbow.", new ZoneBorders(3109, 3293, 3110, 3296), new ZoneBorders(3108, 3294, 3111, 3295))); + register(new EmoteCluePlugin("fally-party-dance", 2696, ClueLevel.EASY, emote, new int[][] { { 1157 }, { 1119 }, { 1081 } }, "Dance in the Party
Room.
Equip a steel full
helmet, steel
platebody and an iron
plateskirt.", new ZoneBorders(3041, 3372, 3050, 3384), new ZoneBorders(3051, 3371, 3054, 3385), new ZoneBorders(3073, 3371, 3040, 3385))); + register(new EmoteCluePlugin("fish-guild-jig", 2697, ClueLevel.EASY, Emotes.JIG, new int[][] { { 1639 }, { 1694 }, { 1103 } }, "Dance a jig by the
entrance to the
Fishing Guild.
Equip an emerald ring,
a sapphire amulet,
and a bronze chain
body.", new ZoneBorders(2610, 3392, 2612, 3393))); + register(new EmoteCluePlugin("lumb-shack-dance", 2698, ClueLevel.EASY, emote, new int[][] { { 1205 }, { 1153 }, { 1635 } }, "Dance in
the shack in Lumbridge Swamp.
Equip a bronze
dagger, iron full helmet
and a gold ring.", new ZoneBorders(3202, 3167, 3205, 3170))); + register(new EmoteCluePlugin("lumb-cave-dance", 2699, ClueLevel.MEDIUM, emote, Emotes.BLOW_KISS, new int[][] { { 1381 }, { 1155 }, { 1731 } }, "Dance in the dark
cave beneath
Lumbridge Swamp.
Blow a kiss before
you talk to me.
Equip an air staff,
bronze full helm and
an amulet of power.", new ZoneBorders(3139, 9534, 3260, 9587))); + register(new EmoteCluePlugin("shantay-guild-jig", 2700, ClueLevel.MEDIUM, Emotes.JIG, Emotes.BOW, new int[][] { { 3343 }, { 1381 }, { 1173 } }, "Dance a jig under
Shantay's Awning.
Bow before you talk to
me.
Equip a pointed blue
snail helmet, an air
staff and a bronze
square shield.", new ZoneBorders(3302, 3122, 3305, 3125))); + register(new EmoteCluePlugin("cat-entrance-dance", 2701, ClueLevel.HARD, emote, new int[][] { { 2570 }, { 1704 }, { 1317 } }, "Dance at the
cat doored pyramid in
Sophanem. Beware of double agents!
Equip a ring of life
an uncharged amulet of glory
and an adamant two handed sword.", new ZoneBorders(3293, 2781, 3296, 2782))); + emote = Emotes.HEADBANG; + register(new EmoteCluePlugin("al-kharid-headbang", 2702, ClueLevel.EASY, emote, new int[][] { { 1833 }, { 1059 }, { 1061 } }, "Headbang in the mine north of Al
Kharid.
Equip a desert shirt, leather gloves and
leather boots.", new ZoneBorders(3297, 3286, 3301, 3316))); + //Removed Vexia code that bricked emotes for certain clues. + //Fixed JFJ and Laugh Clues + //When Vexia emote is removed below. + //emote = Emotes.JUMP_FOR_JOY; + register(new EmoteCluePlugin("beehive-jump", 2703, ClueLevel.EASY, Emotes.JUMP_FOR_JOY, new int[][] { { 1833 }, { 648 }, { 1353 } }, "Jump for joy at the beehives.
Equip a desert shirt, green
gnome robe bottoms and a
steel axe.", new ZoneBorders(2752, 3437,2766, 3450))); + // And emote, is replaced with what it is shortcutting Emotes.JUMP_FOR_JOY + // the clues work perfect. It seems to only be a problem with multiple emote clues. + // If you look around EmoteCluePlugin you will see there are multiple emote, shortcuts + // I do not know what should be done as there are so many. + register(new EmoteCluePlugin("yanille-jump", 2704, ClueLevel.MEDIUM, Emotes.JUMP_FOR_JOY, Emotes.JIG, new int[][] { { 1757 }, { 1145 }, { 6324 } }, "Jump for joy in Yanille
bank. Dance a jig before you
talk to me.
Equip a brown apron,
adamantite medium helmet
and snakeskin chaps.", new ZoneBorders(2609, 3088, 2614, 3097))); + register(new EmoteCluePlugin("tzhaar-jump", 2705, ClueLevel.MEDIUM, Emotes.JUMP_FOR_JOY, Emotes.SHRUG, new int[][] { { 1295 }, { 2499 }, { 4095 } }, "Jump for joy in the TzHaar
sword shop. Shrug before you
talk to me.
Equip a Steel longsword,
Blue D'hide body and blue
mystic gloves.", new ZoneBorders(2477, 5144, 2480, 5147))); + //Removed Vexia code that bricked emotes for certain clues. + register(new EmoteCluePlugin("jokul-tent-laugh", 2706, ClueLevel.HARD, Emotes.LAUGH, new int[][] { { 1163 }, { 2493 }, { 1393 } }, "Laugh in the Jokul's tent in the
Mountain Camp.
Beware of double agents! Equip a
rune full helmet, blue dragonhide
chaps and a fire battlestaff.", new ZoneBorders(2811, 3678, 2813, 3682))); + emote = Emotes.PANIC; + register(new EmoteCluePlugin("limestone-mine-panic", 2707, ClueLevel.EASY, emote, new int[][] { { 1075 }, { 1269 }, { 1141 } }, "Panic in the
Limestone Mine.
Equip bronze
platelegs, a steel
pickaxe and a steel
medium helmet.", new ZoneBorders(3368, 3496, 3374, 3505))); + register(new EmoteCluePlugin("fish-trawler-panic", 2708, ClueLevel.EASY, emote, new int[][] {}, "Panic on the pier
where you catch the
Fishing trawler.
Have nothing equipped
at all when you do.", new ZoneBorders(2675, 3162, 2677, 3175))); + emote = Emotes.SALUTE; + // vexia make banana saulte so it won't work if u are wearing anything + // on chest or legs + register(new EmoteCluePlugin("banana-salute", 2710, ClueLevel.HARD, emote, new int[][] { { 1643 }, { 1731 } }, "Salute in the banana
plantation. Beware of
double agents!
Equip a diamond ring,
amulet of power, and nothing on
your chest and legs.", new ZoneBorders(2911, 3156, 2935, 3175))); + emote = Emotes.SHRUG; + register(new EmoteCluePlugin("rimmington-shrug", 2711, ClueLevel.EASY, emote, new int[][] { { 1654 }, { 1635 }, { 1237 } }, "Shrug in the mine near
Rimmington.
Equip a gold
necklace, a gold ring
and a bronze spear.", new ZoneBorders(2970, 3230, 2987, 3251))); + register(new EmoteCluePlugin("catherby-shrug", 2712, ClueLevel.MEDIUM, emote, Emotes.YAWN, new int[][] { { 851 }, { 1099 }, { 1137 } }, "Shrug in Catherby
bank. Yawn before
you talk to me.
Equip a maple
longbow, green d'hide
chaps and an iron
med helm.", new ZoneBorders(2806, 3438, 2812, 3442))); + register(new EmoteCluePlugin("zammy-altar-shrug", 2713, ClueLevel.HARD, emote, new int[][] { { 1079 }, { 1115 }, { 2487 } }, "Shrug in the Zamorak
temple found in the
Eastern Wilderness.
Beware of double
agents!
Equip rune plate legs,
an iron plate body and
blue dragonhide
vambraces.", new ZoneBorders(3233, 3603, 3246, 3614))); + emote = Emotes.SPIN; + register(new EmoteCluePlugin("rimmington-cross-spin", 2716, ClueLevel.EASY, emote, new int[][] { { 658 }, { 642 }, { 1095 } }, "Spin at the crossroads
north of Rimmington.
Equip a green gnome
hat, cream gnome top
and leather chaps.", new ZoneBorders(2979, 3275, 2985, 3279))); + register(new EmoteCluePlugin("draynor-manor-spin", 2719, ClueLevel.EASY, emote, new int[][] { { 1115 }, { 1097 }, { 1155 } }, "Spin in the Draynor
Manor by the fountain.
Equip an iron
platebody, studded
leather chaps and a
bronze full helmet.", new ZoneBorders(3085, 3332, 3090, 3337))); + register(new EmoteCluePlugin("varrock-court-spin", 2722, ClueLevel.EASY, emote, new int[][] { { 1361 }, { 1169 }, { 1641 } }, "Spin in the Varrock
Castle courtyard.
Equip a black axe, a
coif and a ruby ring.", new ZoneBorders(3202, 3459, 3223, 3468))); + register(new EmoteCluePlugin("barb-bridge-spin", 2723, ClueLevel.MEDIUM, emote, Emotes.SALUTE, new int[][] { { 2942 }, { 1193 }, { 1159 } }, "Spin on the bridge by
the Barbarian Village.
Salute before you talk
to me.
Equip purple gloves, a
steel kiteshield and a
mithril full helmet.", new ZoneBorders(3102, 3419, 3108, 3422))); + emote = Emotes.THINK; + register(new EmoteCluePlugin("lumb-wheat-think", 2725, ClueLevel.EASY, emote, new int[][] { { 640 }, { 654 }, { 843 } }, "Think in middle of the
wheat field by the
lumbridge mill.
Equip a blue gnome
robetop, a turquoise
gnome robe bottom
and an oak shortbow.", new ZoneBorders(3157, 3298, 3159, 3300))); + // register(new EmoteCluePlugin("observatory-think", 2727, + // ClueLevel.MEDIUM, emote, Emotes.SPIN, new int[][] {{1109}, {1099}, + // {1698}}, + // "Think in the centre of
the Observatory. Spin
before you talk to me.
Equip a mithril chain
body, green
dragonhide chaps and
a ruby amulet.", + // new ZoneBorders(2439, 3160, 2442, 3163))); + emote = Emotes.WAVE; + register(new EmoteCluePlugin("lumber-wave", 2729, ClueLevel.EASY, emote, new int[][] { { 1131 }, { 1095 }, { 1351 } }, "Wave along the south fence of
the Lumber Yard.
Equip a hard leather body,
leather chaps and a
bronze axe.", new ZoneBorders(3306, 3490, 3309, 3492))); + register(new EmoteCluePlugin("fally-gem-wave", 2731, ClueLevel.EASY, emote, new int[][] { { 1273 }, { 1125 }, { 1191 } }, "Wave in the Falador
gem store.
Equip a Mithril pickaxe,
Black platebody and
an Iron Kiteshield.", new ZoneBorders(2944, 3332, 2946, 3337))); + register(new EmoteCluePlugin("mudskipper-wave", 2733, ClueLevel.EASY, emote, new int[][] { { 1019 }, { 1095 }, { 1424 } }, "Wave on Mudskipper Point.
Equip a black cape, leather
chaps and a steel mace.", new ZoneBorders(2979, 3105, 3008, 3115))); + emote = Emotes.YAWN; + register(new EmoteCluePlugin("varrock-library-yawn", 2735, ClueLevel.EASY, emote, new int[][] { { 638 }, { 4300 }, { 1335 } }, "Yawn in the Varrock
library.
Equip a green gnome
robe top, HAM robe
bottom and an iron
warhammer.", new ZoneBorders(3207, 3490, 3214, 3497), new ZoneBorders(3214, 3494, 3217, 3497))); + register(new EmoteCluePlugin("draynor-market-yawn", 2737, ClueLevel.EASY, emote, new int[][] { { 1097 }, { 1191 }, { 1295 } }, "Yawn in Draynor
Marketplace.
Equip studded leather
chaps, an iron
kiteshield and a steel
longsword.", new ZoneBorders(3075, 3245, 3086, 3255))); + register(new EmoteCluePlugin("castle-wars-yawn", 2739, ClueLevel.MEDIUM, emote, Emotes.SHRUG, new int[][] { { 1698 }, { 1329 }, WILDY_CAPES }, "Yawn in the Castle
Wars lobby. Shrug
before you talk to me.
Equip ruby amulet, a
mithril scimitar and a
Wilderness cape.", new ZoneBorders(2434, 3061, 2464, 3102))); + register(new EmoteCluePlugin("rogue-gen-yawn", 2741, ClueLevel.HARD, emote, new int[][] { { 1183 }, { 2487 }, { 1275 } }, "Yawn in the rogues'
general store. Beware
of double agents!
Equip an adamant
square shield, blue
dragon vambraces
and a rune pickaxe.", new ZoneBorders(3024, 3699, 3027, 3704))); + ClassScanner.definePlugin(new UriNPC()); + return this; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + +} diff --git a/Server/src/main/content/global/activity/ttrail/EmoteClueScroll.java b/Server/src/main/content/global/activity/ttrail/EmoteClueScroll.java new file mode 100644 index 0000000..e4e9100 --- /dev/null +++ b/Server/src/main/content/global/activity/ttrail/EmoteClueScroll.java @@ -0,0 +1,152 @@ +package content.global.activity.ttrail; + +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.emote.Emotes; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.update.flag.context.Graphics; + +/** + * Handles an emote clue scroll. + * @author Vexia + */ +public abstract class EmoteClueScroll extends ClueScrollPlugin { + + /** + * The emote id. + */ + private final Emotes emote; + + /** + * The commening emote. + */ + private final Emotes commenceEmote; + + /** + * The equipment ids. + */ + private final int[][] equipment; + + /** + * The clue message. + */ + private final String clue; + + /** + * Constructs a new {@Code EmoteClueScroll} {@Code Object} + * @param name the name. + * @param clueId the clue id. + * @param level the level. + * @param emote the emote. + * @param commenceEmote the emote. + * @param equipment the equipment. + * @param clue the clue. + * @param borders the borders. + */ + public EmoteClueScroll(String name, int clueId, ClueLevel level, Emotes emote, Emotes commenceEmote, int[][] equipment, final String clue, ZoneBorders... borders) { + super(name, clueId, level, 345, borders); + this.emote = emote; + this.commenceEmote = commenceEmote; + this.equipment = equipment; + this.clue = clue; + } + + @Override + public boolean actionButton(Player player, int interfaceId, int buttonId, int slot, int itemId, int opcode) { + if (!player.getInventory().contains(clueId, 1)) { + return false; + } + final Emotes emote = Emotes.forId(buttonId); + if (emote == null) { + return false; + } + if (emote == this.emote) { + NPC oldUri = player.getAttribute("uri", null); + if (oldUri != null && oldUri.isActive()) { + return false; + } + spawnUri(player); + } else if (emote == commenceEmote) { + player.setAttribute("commence-emote", true); + } + if(this.emote == emote) { + return super.actionButton(player, interfaceId, buttonId, slot, itemId, opcode); + } else { + return false; + } + } + + @Override + public void read(Player player) { + for (int i = 1; i < 9; i++) { + player.getPacketDispatch().sendString("", interfaceId, i); + } + super.read(player); + player.getPacketDispatch().sendString(clue.replace("
", "

"), interfaceId, 1); + } + + /** + * Spawns the uri npc for the player. + * @param player the player. + */ + public void spawnUri(Player player) { + boolean doubleAgent = level == ClueLevel.HARD && player.getAttribute("killed-agent", 0) != clueId; + //changed this + int id = 5141; + if (doubleAgent) { + boolean wilderness = player.getSkullManager().isWilderness(); + if (wilderness) { + id = 5141; + doubleAgent = false; + } else { + id = 5145; + } + } + final NPC uri = NPC.create(id, player.getLocation().transform(1, 0, 0)); + player.setAttribute("uri", uri); + player.removeAttribute("commence-emote"); + uri.setAttribute("double-agent", doubleAgent); + uri.setAttribute("player", player); + uri.setAttribute("clue", this); + uri.init(); + uri.graphics(Graphics.create(86)); + uri.faceTemporary(player, 1); + if (doubleAgent) { + uri.sendChat("I expect you to die!"); + uri.getProperties().getCombatPulse().attack(player); + } + } + + /** + * Checks if a commence emote is needed. + * @return {@code True} if so. + */ + public boolean hasCommencEmote() { + return commenceEmote != null; + } + + /** + * Gets the emote. + * @return the emote. + */ + public Emotes getEmote() { + return emote; + } + + /** + * Gets the bequipment. + * @return the equipment + */ + public int[][] getEquipment() { + return equipment; + } + + /** + * Gets the bcommenceEmote. + * @return the commenceEmote + */ + public Emotes getCommenceEmote() { + return commenceEmote; + } + +} diff --git a/Server/src/main/content/global/activity/ttrail/MapCluePlugin.java b/Server/src/main/content/global/activity/ttrail/MapCluePlugin.java new file mode 100644 index 0000000..b1713ff --- /dev/null +++ b/Server/src/main/content/global/activity/ttrail/MapCluePlugin.java @@ -0,0 +1,74 @@ +package content.global.activity.ttrail; + +import core.game.world.map.Location; +import core.game.world.map.zone.ZoneBorders; +import core.plugin.Plugin; + +/** + * Initializes the map clues. + * @author Vexia + */ +public final class MapCluePlugin extends MapClueScroll { + + /** + * Constructs a new {@Code MapCluePlugin} {@Code Object} + */ + public MapCluePlugin() { + this(null, -1, null, -1, null); + } + + /** + * Constructs a new {@Code MapCluePlugin} {@Code Object} + * @param name the name. + * @param clueId the clue id. + * @param level the level. + * @param interfaceId the interface id. + * @param location the location. + */ + public MapCluePlugin(String name, int clueId, ClueLevel level, int interfaceId, Location location) { + super(name, clueId, level, interfaceId, location); + } + + /** + * Constructs a new {@Code MapCluePlugin} {@Code Object} + * @param name the name. + * @param clueId the clue id. + * @param level the level. + * @param interfaceId the interface id. + * @param location the location. + * @param object the object. + * @param borders the borders. + */ + public MapCluePlugin(String name, int clueId, ClueLevel level, int interfaceId, Location location, int object, ZoneBorders... borders) { + super(name, clueId, level, interfaceId, location, object, borders); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + register(new MapCluePlugin("mc-grubber-crate", 2743, ClueLevel.MEDIUM, 355, Location.create(2658, 3488, 0), 357, new ZoneBorders(2657, 3487, 2660, 3489))); + register(new MapCluePlugin("ardy-crate", 2747, ClueLevel.MEDIUM, 361, Location.create(2565, 3248, 0), 354, new ZoneBorders(2564, 3247, 2566, 3249))); + register(new MapCluePlugin("wildy-crate", 2773, ClueLevel.HARD, 359, Location.create(3026, 3628, 0), 354, new ZoneBorders(3025, 3627, 3027, 3629))); + register(new MapCluePlugin("goblin-crate", 2774, ClueLevel.HARD, 358, Location.create(2457, 3182, 0), 18506, new ZoneBorders(2456, 3181, 2458, 3183))); + register(new MapCluePlugin("miscellania-dig", 2776, ClueLevel.MEDIUM, 340, Location.create(2536, 3865, 0))); + register(new MapCluePlugin("crafting-guild-dig", 2778, ClueLevel.MEDIUM, 352, Location.create(2906, 3294, 0))); + register(new MapCluePlugin("wizard-tower-dig", 2745, ClueLevel.EASY, 356, Location.create(3110, 3152, 0))); + register(new MapCluePlugin("east-dig", 2805, ClueLevel.EASY, 360, Location.create(2651, 3231, 0))); + register(new MapCluePlugin("rimmington", 2780, ClueLevel.MEDIUM, 362, Location.create(2924, 3209, 0))); + register(new MapCluePlugin("west-ardy", 2782, ClueLevel.HARD, 357, Location.create(2488, 3308, 0))); + register(new MapCluePlugin("yanille", 2783, ClueLevel.HARD, 353, Location.create(2616, 3077, 0))); + register(new MapCluePlugin("mcgrubber", 2785, ClueLevel.EASY, 354, Location.create(2611, 3481, 0))); + register(new MapCluePlugin("falador-stone", 2786, ClueLevel.EASY, 351, Location.create(3043, 3399, 0))); + register(new MapCluePlugin("champion's-guild", 2788, ClueLevel.EASY, 346, Location.create(3166, 3360, 0))); + register(new MapCluePlugin("falador-statue", 2790, ClueLevel.EASY, 337, Location.create(2970, 3415, 0))); + register(new MapCluePlugin("varrock-mine", 2792, ClueLevel.EASY, 347, Location.create(3289, 3373, 0))); + register(new MapCluePlugin("khazard-altar", 2793, ClueLevel.MEDIUM, 342, Location.create(2455, 3230, 0))); + register(new MapCluePlugin("light-house", 2794, ClueLevel.MEDIUM, 343, Location.create(2578, 3597, 0))); + register(new MapCluePlugin("north-seers", 2796, ClueLevel.MEDIUM, 344, Location.create(2666, 3562, 0))); + register(new MapCluePlugin("legends-guild", 2797, ClueLevel.HARD, 339, Location.create(2723, 3338, 0))); + register(new MapCluePlugin("wilderness", 2799, ClueLevel.HARD, 338, Location.create(3021, 3911, 0))); + register(new MapCluePlugin("draynor", 2801, ClueLevel.MEDIUM, 348, Location.create(3092, 3227, 0))); + register(new MapCluePlugin("abandoned-mine", 2803, ClueLevel.MEDIUM, 341, Location.create(3434, 3266, 0))); + return this; + } + +} diff --git a/Server/src/main/content/global/activity/ttrail/MapClueScroll.java b/Server/src/main/content/global/activity/ttrail/MapClueScroll.java new file mode 100644 index 0000000..2b772e8 --- /dev/null +++ b/Server/src/main/content/global/activity/ttrail/MapClueScroll.java @@ -0,0 +1,128 @@ +package content.global.activity.ttrail; + +import core.game.global.action.DigAction; +import core.game.global.action.DigSpadeHandler; +import core.game.interaction.Option; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.game.world.map.zone.ZoneBorders; + +/** + * A map clue scroll. + * @author Vexia + */ +public abstract class MapClueScroll extends ClueScrollPlugin { + + /** + * The location of the x spot. + */ + private final Location location; + + /** + * The object id. + */ + private final int object; + + /** + * Constructs a new {@Code MapClueScroll} {@Code Object} + * @param name the name. + * @param clueId the clue id. + * @param level the level. + * @param interfaceId the interface id. + * @param location the location. + * @param object the object. + */ + public MapClueScroll(String name, int clueId, ClueLevel level, int interfaceId, Location location, final int object, ZoneBorders... borders) { + super(name, clueId, level, interfaceId, borders); + this.location = location; + this.object = object; + } + + /** + * Constructs a new {@Code MapClueScroll} {@Code Object} + * @param name the name. + * @param clueId the clue id. + * @param level the level. + * @param interfaceId the interface id. + * @param location the location. + */ + public MapClueScroll(String name, int clueId, ClueLevel level, int interfaceId, Location location) { + this(name, clueId, level, interfaceId, location, 0); + } + + @Override + public boolean interact(Entity e, Node target, Option option) { + if (e instanceof Player) { + Player p = e.asPlayer(); + if (target.getId() == object && option.getName().equals("Search")) { + if (!p.getInventory().contains(clueId, 1) || !target.getLocation().equals(location)) { + p.sendMessage("Nothing interesting happens."); + return false; + } + reward(p); + return true; + } + } + return super.interact(e, target, option); + } + + @Override + public void configure() { + DigSpadeHandler.register(getLocation(), new MapDigAction()); + super.configure(); + } + + /** + * The dig method called when the player digs. + * @param player the player. + */ + public void dig(Player player) { + reward(player); + player.getDialogueInterpreter().sendItemMessage(405, "You've found a casket!"); + } + + /** + * Handles the map digging reward. + * @author Vexia + */ + public final class MapDigAction implements DigAction { + + @Override + public void run(Player player) { + if (!hasRequiredItems(player)) { + player.sendMessage("Nothing interesting happens."); + return; + } + dig(player); + } + + } + + /** + * Checks if the player has the required items. + * @param player the player. + * @return {@code True} if so. + */ + public boolean hasRequiredItems(Player player) { + return player.getInventory().contains(clueId, 1); + } + + /** + * Gets the blocation. + * @return the location + */ + public Location getLocation() { + return location; + } + + /** + * Gets the bobject. + * @return the object + */ + public int getObject() { + return object; + } + +} diff --git a/Server/src/main/content/global/activity/ttrail/SaradominWizardNPC.java b/Server/src/main/content/global/activity/ttrail/SaradominWizardNPC.java new file mode 100644 index 0000000..b2b3576 --- /dev/null +++ b/Server/src/main/content/global/activity/ttrail/SaradominWizardNPC.java @@ -0,0 +1,178 @@ +package content.global.activity.ttrail; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.spell.CombatSpell; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.equipment.SwitchAttack; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.plugin.Plugin; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.node.entity.combat.MultiSwingHandler; + +/** + * Handles saradomin npc. + * @author Vexia + */ +public final class SaradominWizardNPC extends AbstractNPC { + + /** + * The combat handler to use. + */ + private static final MultiSwingHandler COMBAT_HANDLER = new MultiSwingHandler(new SwitchAttack(CombatStyle.MELEE).setUseHandler(true), new SwitchAttack(CombatStyle.MAGIC).setUseHandler(true)); + + /** + * The npc ids. + */ + private static final int[] IDS = new int[] { 1264 }; + + /** + * The clue scroll. + */ + private ClueScrollPlugin clueScroll; + + /** + * The player. + */ + private Player player; + + /** + * Constructs a new {@code SaradominWizardNPC} {@code Object} + */ + public SaradominWizardNPC() { + super(0, null); + } + + /** + * Constructs a new {@Code SaradominWizardNPC} {@Code Object} + * @param id the id. + * @param location the location. + */ + public SaradominWizardNPC(int id, Location location) { + super(id, location, false); + this.setRespawn(false); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new SaradominWizardNPC(id, location); + } + + @Override + public void init() { + Player player = getAttribute("player", null); + ClueScrollPlugin clueScroll = getAttribute("clue", null); + if (player != null) { + this.player = player; + } + if (clueScroll != null) { + this.clueScroll = clueScroll; + } + if (player != null) { + location = RegionManager.getSpawnLocation(player, this); + if (location == null) { + location = player.getLocation(); + } + } + super.init(); + getProperties().setSpell((CombatSpell) SpellBook.MODERN.getSpell(41)); + getProperties().setAutocastSpell((CombatSpell) SpellBook.MODERN.getSpell(41)); + } + + @Override + public void finalizeDeath(Entity killer) { + if (killer instanceof Player) { + Player p = killer.asPlayer(); + if (p == player) { + p.setAttribute("killed-wizard", clueScroll.getClueId()); + } + } + super.finalizeDeath(killer); + } + + @Override + public void handleTickActions() { + super.handleTickActions(); + if (player != null) { + if (player.getLocation().getDistance(getLocation()) > 10 || !player.isActive()) { + clear(); + } + if (!getProperties().getCombatPulse().isAttacking()) { + getProperties().getCombatPulse().attack(player); + } + } + } + + @Override + public CombatSwingHandler getSwingHandler(boolean swing) { + return COMBAT_HANDLER; + } + + @Override + public boolean canAttack(Entity entity) { + if (!(entity instanceof Player)) { + return false; + } + if (player != null) { + Player p = entity.asPlayer(); + return p == player; + } + return super.canAttack(entity); + } + + @Override + public boolean isAttackable(Entity entity, CombatStyle style, boolean message) { + if (!(entity instanceof Player)) { + return false; + } + if (player != null) { + Player p = entity.asPlayer(); + return p == player; + } + return super.isAttackable(entity, style, message); + } + + @Override + public boolean canSelectTarget(Entity target) { + return target == player; + + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + return super.newInstance(arg); + } + + @Override + public int[] getIds() { + return IDS; + } + + /** + * Gets the bplayer. + * @return the player + */ + public Player getPlayer() { + return player; + } + + /** + * Sets the baplayer. + * @param player the player to set. + */ + public void setPlayer(Player player) { + this.player = player; + } + + /** + * Gets the bclueScroll. + * @return the clueScroll + */ + public ClueScrollPlugin getClueScroll() { + return clueScroll; + } + +} diff --git a/Server/src/main/content/global/activity/ttrail/TreasureTrailManager.java b/Server/src/main/content/global/activity/ttrail/TreasureTrailManager.java new file mode 100644 index 0000000..e9a68dd --- /dev/null +++ b/Server/src/main/content/global/activity/ttrail/TreasureTrailManager.java @@ -0,0 +1,294 @@ +package content.global.activity.ttrail; + +import core.api.LoginListener; +import core.api.PersistPlayer; +import core.game.node.entity.player.Player; + +import core.tools.RandomFunction; +import org.jetbrains.annotations.NotNull; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; + +/** + * Handles the treasure trail of a player. + * @author Vexia + */ +public final class TreasureTrailManager implements LoginListener, PersistPlayer { + + /** + * The ids of the clues. + */ + private static final int[] IDS = new int[] { 2677, 2678, 2679, 2680, 2682, 2683, 2684, 2685, 2686, 2687, 2688, 2689, 2690, 2691, 2692, 2693, 2694, 2695, 2696, 2697, 2698, 2699, 2700, 2701, 2702, 2703, 2704, 2705, 2706, 2707, 2708, 2709, 2710, 2711, 2712, 2713, 2716, 2719, 2722, 2723, 2725, 2727, 2729, 2731, 2733, 2735, 2737, 2739, 2741, 2743, 2745, 2747, 2773, 2774, 2776, 2778, 2780, 2782, 2783, 2785, 2786, 2788, 2790, 2792, 2793, 2794, 2796, 2797, 2799, 2801, 2803, 2805, 2807, 2809, 2811, 2813, 2815, 2817, 2819, 2821, 2823, 2825, 2827, 2829, 2831, 2833, 2835, 2837, 2839, 2841, 2843, 2845, 2847, 2848, 2849, 2851, 2853, 2855, 2856, 2857, 2858, 3490, 3491, 3492, 3493, 3494, 3495, 3496, 3497, 3498, 3499, 3500, 3501, 3502, 3503, 3504, 3505, 3506, 3507, 3508, 3509, 3510, 3512, 3513, 3514, 3515, 3516, 3518, 3520, 3522, 3524, 3525, 3526, 3528, 3530, 3532, 3534, 3536, 3538, 3540, 3542, 3544, 3546, 3548, 3550, 3552, 3554, 3556, 3558, 3560, 3562, 3564, 3566, 3568, 3570, 3572, 3573, 3574, 3575, 3577, 3579, 3580, 3582, 3584, 3586, 3588, 3590, 3592, 3594, 3596, 3598, 3599, 3601, 3602, 3604, 3605, 3607, 3609, 3610, 3611, 3612, 3613, 3614, 3615, 3616, 3617, 3618, 7236, 7238, 7239, 7241, 7243, 7245, 7247, 7248, 7249, 7250, 7251, 7252, 7253, 7254, 7255, 7256, 7258, 7260, 7262, 7264, 7266, 7268, 7270, 7272, 7274, 7276, 7278, 7280, 7282, 7284, 7286, 7288, 7290, 7292, 7294, 7296, 7298, 7300, 7301, 7303, 7304, 7305, 7307, 7309, 7311, 7313, 7315, 7317, 10180, 10182, 10184, 10186, 10188, 10190, 10192, 10194, 10196, 10198, 10200, 10202, 10204, 10206, 10208, 10210, 10212, 10214, 10216, 10218, 10220, 10222, 10224, 10226, 10228, 10230, 10232, 10234, 10236, 10238, 10240, 10242, 10244, 10246, 10248, 10250, 10252, 10254, 10256, 10258, 10260, 10262, 10264, 10266, 10268, 10270, 10272, 10274, 10276, 10278, 13010, 13012, 13014, 13016, 13018, 13020, 13022, 13024, 13026, 13028, 13030, 13032, 13034, 13036, 13038, 13040, 13041, 13042, 13044, 13046, 13048, 13049, 13050, 13051, 13053, 13055, 13056, 13058, 13060, 13061, 13063, 13065, 13067, 13068, 13069, 13070, 13071, 13072, 13074, 13075, 13076, 13078, 13079, 13080 }; + + /** + * The player. + */ + private final Player player; + + /** + * The current clue id. + */ + private int clueId; + + /** + * The clue level. + */ + private ClueLevel level; + + /** + * The trail stage. + */ + private int trailStage; + + /** + * The current length of the trail. + */ + private int trailLength; + + /** + * The amount of completed clues. + */ + private final int[] completedClues = new int[3]; + + /** + * Constructs a new {@Code TreasureTrailManager} {@Code + * Object} + * @param player the player. + */ + public TreasureTrailManager(Player player) { + this.player = player; + } + + public TreasureTrailManager() {this.player = null;} + + @Override + public void login(@NotNull Player player) { + TreasureTrailManager instance = new TreasureTrailManager(player); + player.setAttribute("tt-manager", instance); + } + + @Override + public void parsePlayer(@NotNull Player player, @NotNull JSONObject data) { + TreasureTrailManager instance = getInstance(player); + JSONObject ttData = (JSONObject) data.get("treasureTrails"); + if(ttData == null) return; + JSONArray cc = (JSONArray) ttData.get("completedClues"); + for(int i = 0; i < cc.size(); i++) + { + instance.completedClues[i] = Integer.parseInt(cc.get(i).toString()); + } + if(ttData.containsKey("trail")) + { + JSONObject trail = (JSONObject) ttData.get("trail"); + instance.clueId = Integer.parseInt(trail.get("clueId").toString()); + instance.trailLength = Integer.parseInt(trail.get("length").toString()); + instance.trailStage = Integer.parseInt(trail.get("stage").toString()); + } + } + + @Override + public void savePlayer(@NotNull Player player, @NotNull JSONObject save) { + TreasureTrailManager instance = getInstance(player); + JSONObject treasureTrailManager = new JSONObject(); + if(instance.hasTrail()){ + JSONObject trail = new JSONObject(); + trail.put("clueId", Integer.toString(instance.clueId)); + trail.put("length", Integer.toString(instance.trailLength)); + trail.put("stage", Integer.toString(instance.trailStage)); + treasureTrailManager.put("trail",trail); + } + JSONArray completedClues = new JSONArray(); + for(int clue : instance.completedClues) + { + completedClues.add(Integer.toString(clue)); + } + treasureTrailManager.put("completedClues",completedClues); + save.put("treasureTrails",treasureTrailManager); + } + + public void parse(JSONObject data){ + JSONArray cc = (JSONArray) data.get("completedClues"); + for(int i = 0; i < cc.size(); i++){ + completedClues[i] = Integer.parseInt(cc.get(i).toString()); + } + + if(data.containsKey("trail")){ + JSONObject trail = (JSONObject) data.get("trail"); + clueId = Integer.parseInt(trail.get("clueId").toString()); + trailLength = Integer.parseInt(trail.get("length").toString()); + trailStage = Integer.parseInt(trail.get("stage").toString()); + } + } + + /** + * Starts a treasure trail. + * @param clue the clue. + */ + public void startTrail(ClueScrollPlugin clue) { + setClue(clue); + trailLength = RandomFunction.random(clue.getLevel().getMinimumLength(), clue.getLevel().getMaximumLength()); + trailStage = 0; + } + + /** + * Clears the trail. + */ + public void clearTrail() { + clueId = 0; + level = null; + trailLength = 0; + trailStage = 0; + } + + /** + * Sets the current clue. + * @param clue the clue. + */ + public void setClue(ClueScrollPlugin clue) { + clueId = clue.getClueId(); + level = clue.getLevel(); + } + + /** + * Checks if the player has a clue. + * @return {@code True} if so. + */ + public boolean hasClue() { + if (player == null) { + return true; + } + if (player.hasItem(ClueLevel.EASY.getCasket()) || player.hasItem(ClueLevel.MEDIUM.getCasket()) || player.hasItem(ClueLevel.HARD.getCasket())) { + return true; + } + for (int id : IDS) { + if (player.getInventory().contains(id, 1) || player.getBank().contains(id, 1)) { + return true; + } + } + return false; + } + + /** + * Increments a trail stage. + */ + public void incrementStage() { + trailStage += 1; + } + + /** + * Checks if the trail is completed. + * @return {@code True} if so. + */ + public boolean isCompleted() { + return trailStage != 0 && trailLength != 0 && trailStage >= trailLength; + } + + /** + * Checks if the player has an active trail. + * @return the trail. + */ + public boolean hasTrail() { + return clueId != 0 && level != null & trailLength != 0 && trailStage != 0; + } + + /** + * Incremented the clues. + */ + public void incrementClues(ClueLevel level) { + completedClues[level.ordinal()]++; + } + + /** + * Gets the amount of completed clues for the level. + * @param level the level. + * @return the amount. + */ + public int getCompletedClues(ClueLevel level) { + return completedClues[level.ordinal()]; + } + + /** + * Gets the completed clue amount. + * @return the completed clues. + */ + public int[] getCompletedClues() { + return completedClues; + } + + /** + * Gets the bclueId. + * @return the clueId + */ + public int getClueId() { + return clueId; + } + + /** + * Sets the baclueId. + * @param clueId the clueId to set. + */ + public void setClueId(int clueId) { + this.clueId = clueId; + } + + /** + * Gets the blevel. + * @return the level + */ + public ClueLevel getLevel() { + return level; + } + + /** + * Sets the balevel. + * @param level the level to set. + */ + public void setLevel(ClueLevel level) { + this.level = level; + } + + /** + * Gets the bplayer. + * @return the player + */ + public Player getPlayer() { + return player; + } + + /** + * Gets the btrailLength. + * @return the trailLength + */ + public int getTrailLength() { + return trailLength; + } + + /** + * Sets the batrailLength. + * @param trailLength the trailLength to set. + */ + public void setTrailLength(int trailLength) { + this.trailLength = trailLength; + } + + /** + * Gets the btrailStage. + * @return the trailStage + */ + public int getTrailStage() { + return trailStage; + } + + /** + * Sets the batrailStage. + * @param trailStage the trailStage to set. + */ + public void setTrailStage(int trailStage) { + this.trailStage = trailStage; + } + + public static TreasureTrailManager getInstance(Player player) + { + return player.getAttribute("tt-manager", new TreasureTrailManager()); + } +} diff --git a/Server/src/main/content/global/activity/ttrail/TreasureTrailPlugin.java b/Server/src/main/content/global/activity/ttrail/TreasureTrailPlugin.java new file mode 100644 index 0000000..607eb16 --- /dev/null +++ b/Server/src/main/content/global/activity/ttrail/TreasureTrailPlugin.java @@ -0,0 +1,184 @@ +package content.global.activity.ttrail; + +import core.cache.def.impl.ItemDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import content.global.skill.agility.AgilityHandler; +import core.game.node.item.GroundItem; +import core.game.node.item.Item; +import core.game.node.item.ItemPlugin; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.plugin.ClassScanner; + +/** + * Handles the clue scroll options. + * @author Vexia + */ +@Initializable +public final class TreasureTrailPlugin extends OptionHandler { + + /** + * The ids of the clues. + */ + private static final int[] IDS = new int[] { 2677, 2678, 2679, 2680, 2682, 2683, 2684, 2685, 2686, 2687, 2688, 2689, 2690, 2691, 2692, 2693, 2694, 2695, 2696, 2697, 2698, 2699, 2700, 2701, 2702, 2703, 2704, 2705, 2706, 2707, 2708, 2709, 2710, 2711, 2712, 2713, 2716, 2719, 2722, 2723, 2725, 2727, 2729, 2731, 2733, 2735, 2737, 2739, 2741, 2743, 2745, 2747, 2773, 2774, 2776, 2778, 2780, 2782, 2783, 2785, 2786, 2788, 2790, 2792, 2793, 2794, 2796, 2797, 2799, 2801, 2803, 2805, 2807, 2809, 2811, 2813, 2815, 2817, 2819, 2821, 2823, 2825, 2827, 2829, 2831, 2833, 2835, 2837, 2839, 2841, 2843, 2845, 2847, 2848, 2849, 2851, 2853, 2855, 2856, 2857, 2858, 3490, 3491, 3492, 3493, 3494, 3495, 3496, 3497, 3498, 3499, 3500, 3501, 3502, 3503, 3504, 3505, 3506, 3507, 3508, 3509, 3510, 3512, 3513, 3514, 3515, 3516, 3518, 3520, 3522, 3524, 3525, 3526, 3528, 3530, 3532, 3534, 3536, 3538, 3540, 3542, 3544, 3546, 3548, 3550, 3552, 3554, 3556, 3558, 3560, 3562, 3564, 3566, 3568, 3570, 3572, 3573, 3574, 3575, 3577, 3579, 3580, 3582, 3584, 3586, 3588, 3590, 3592, 3594, 3596, 3598, 3599, 3601, 3602, 3604, 3605, 3607, 3609, 3610, 3611, 3612, 3613, 3614, 3615, 3616, 3617, 3618, 7236, 7238, 7239, 7241, 7243, 7245, 7247, 7248, 7249, 7250, 7251, 7252, 7253, 7254, 7255, 7256, 7258, 7260, 7262, 7264, 7266, 7268, 7270, 7272, 7274, 7276, 7278, 7280, 7282, 7284, 7286, 7288, 7290, 7292, 7294, 7296, 7298, 7300, 7301, 7303, 7304, 7305, 7307, 7309, 7311, 7313, 7315, 7317, 10180, 10182, 10184, 10186, 10188, 10190, 10192, 10194, 10196, 10198, 10200, 10202, 10204, 10206, 10208, 10210, 10212, 10214, 10216, 10218, 10220, 10222, 10224, 10226, 10228, 10230, 10232, 10234, 10236, 10238, 10240, 10242, 10244, 10246, 10248, 10250, 10252, 10254, 10256, 10258, 10260, 10262, 10264, 10266, 10268, 10270, 10272, 10274, 10276, 10278, 13010, 13012, 13014, 13016, 13018, 13020, 13022, 13024, 13026, 13028, 13030, 13032, 13034, 13036, 13038, 13040, 13041, 13042, 13044, 13046, 13048, 13049, 13050, 13051, 13053, 13055, 13056, 13058, 13060, 13061, 13063, 13065, 13067, 13068, 13069, 13070, 13071, 13072, 13074, 13075, 13076, 13078, 13079, 13080 }; + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (int id : IDS) { + ItemDefinition.forId(id).getHandlers().put("option:read", this); + } + for (ClueLevel level : ClueLevel.values()) { + ItemDefinition.forId(level.getCasket().getId()).getHandlers().put("option:open", this); + } + ItemDefinition.forId(CoordinateClueScroll.SEXTANT.getId()).getHandlers().put("option:look through", this); + ClassScanner.definePlugin(new MapCluePlugin()); + ClassScanner.definePlugin(new ClueItemPlugin()); + ClassScanner.definePlugin(new EmoteCluePlugin()); + ClassScanner.definePlugin(new TTrailOptionHandler()); + ClassScanner.definePlugin(new SextantComponentPlugin()); + ClassScanner.definePlugin(new CoordinateCluePlugin()); + ClassScanner.definePlugin(new SaradominWizardNPC()); + ClassScanner.definePlugin(new ZamorakWizardNPC()); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + player.lock(1); + switch (option) { + case "read": + final ClueScrollPlugin plugin = ClueScrollPlugin.getClueScrolls().get(node.getId()); + if (plugin == null) { + player.sendMessage("Unused clue scroll item! Removed."); + player.getInventory().remove((Item) node); + return false; + } + plugin.read(player); + break; + case "open": + if (!player.getInventory().containsItem(node.asItem())) { + return true; + } + ClueLevel.open(player, (Item) node); + break; + case "look through": + player.getInterfaceManager().open(new Component(365)); + return true; + } + return true; + } + + @Override + public boolean isWalk() { + return false; + } + + /** + * Handles options related to treasure trails. + * @author Vexia + */ + public static final class TTrailOptionHandler extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(19171).getHandlers().put("option:squeeze-through", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + switch (node.getId()) { + case 19171: + Location start = player.getLocation().getX() <= 2522 ? node.getLocation() : node.getLocation().transform(1, 0, 0); + player.lock(1); + AgilityHandler.forceWalk(player, -1, start, start.transform(player.getLocation().getX() <= 2522 ? 1 : -1, 0, 0), Animation.create(2240), 5, 1, null, 0); + break; + } + return true; + } + + } + + /** + * Represents a clue scroll item. + * @author Vexia + */ + public final class ClueItemPlugin extends ItemPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + register(IDS); + return this; + } + + @Override + public boolean canPickUp(Player player, GroundItem item, int type) { + if (hasClue(player)) { + player.sendMessage("A magical force prevents you from picking the clue scroll up."); + return false; + } + return true; + } + + @Override + public boolean createDrop(Item item, Player player, NPC npc, Location l) { + return !hasClue(player); + } + + @Override + public Item getItem(Item item, NPC npc) { + return item; + } + + /** + * Checks if the player has a clue. + * @param player the player. + * @return {@code True} if so. + */ + private boolean hasClue(Player player) { + return TreasureTrailManager.getInstance(player).hasClue(); + } + + } + + /** + * Handles the sextant interface. + * @author Vexia + */ + public class SextantComponentPlugin extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.forId(365).setPlugin(this); + return this; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + switch (button) { + case 5:// horizon up + break; + case 4:// horizon down + break; + case 6:// sun down + break; + case 7:// sun up + break; + case 11: + player.sendMessage("You need to get the horizon in the middle of the eye piece."); + break; + } + return true; + } + + } +} diff --git a/Server/src/main/content/global/activity/ttrail/UriNPC.java b/Server/src/main/content/global/activity/ttrail/UriNPC.java new file mode 100644 index 0000000..64f1b7a --- /dev/null +++ b/Server/src/main/content/global/activity/ttrail/UriNPC.java @@ -0,0 +1,266 @@ +package content.global.activity.ttrail; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.plugin.Plugin; +import core.plugin.ClassScanner; +import core.tools.RandomFunction; + +/** + * Handles the uri npc. + * @author Vexia + */ +public final class UriNPC extends AbstractNPC { + + /** + * The npc ids. + */ + private static final int[] IDS = new int[] { 5141, 5142, 5143, 5144, 5145 }; + + /** + * The clue scroll. + */ + private ClueScrollPlugin clueScroll; + + /** + * The player. + */ + private Player player; + + /** + * Constructs a new {@Code UriNPC} {@Code Object} + */ + public UriNPC() { + super(0, null); + } + + /** + * Constructs a new {@Code UriNPC} {@Code Object} + * @param id the id. + * @param location the location. + */ + public UriNPC(int id, Location location) { + super(id, location, false); + this.setRespawn(false); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new UriNPC(id, location); + } + + @Override + public void init() { + Player player = getAttribute("player", null); + ClueScrollPlugin clueScroll = getAttribute("clue", null); + if (player != null) { + this.player = player; + } + if (clueScroll != null) { + this.clueScroll = clueScroll; + } + if (player != null) { + location = RegionManager.getSpawnLocation(player, this); + if (location == null) { + location = player.getLocation(); + } + } + super.init(); + } + + @Override + public void finalizeDeath(Entity killer) { + if (killer instanceof Player) { + Player p = killer.asPlayer(); + if (p == player && isDoubleAgent()) { + p.setAttribute("killed-agent", clueScroll.getClueId()); + } + } + super.finalizeDeath(killer); + } + + @Override + public void handleTickActions() { + super.handleTickActions(); + if (player != null) { + if (player.getLocation().getDistance(getLocation()) > 10 || !player.isActive()) { + clear(); + } + if (isDoubleAgent()) { + if (!getProperties().getCombatPulse().isAttacking()) { + getProperties().getCombatPulse().attack(player); + } + } + } + } + + @Override + public boolean isAttackable(Entity entity, CombatStyle style, boolean message) { + if (!(entity instanceof Player)) { + return false; + } + if (player != null) { + Player p = entity.asPlayer(); + return p == player; + } + return super.isAttackable(entity, style, message); + } + + @Override + public boolean canSelectTarget(Entity target) { + return target == player; + + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ClassScanner.definePlugin(new UriDialogue()); + return super.newInstance(arg); + } + + @Override + public int[] getIds() { + return IDS; + } + + /** + * Checks if uri is a double agent. + * @return {@code True} if so. + */ + public boolean isDoubleAgent() { + return getAttribute("double-agent", false); + } + + /** + * Gets the bplayer. + * @return the player + */ + public Player getPlayer() { + return player; + } + + /** + * Sets the baplayer. + * @param player the player to set. + */ + public void setPlayer(Player player) { + this.player = player; + } + + /** + * Gets the bclueScroll. + * @return the clueScroll + */ + public ClueScrollPlugin getClueScroll() { + return clueScroll; + } + + /** + * Handles the uri dialogue. + * @author Vexia + */ + public static final class UriDialogue extends DialoguePlugin { + + /** + * The quotes uri says. + */ + private static final String[] QUOTES = new String[] { "Once, I was a poor man, but then I found a party hat.", "There were three goblins in a bar, which one left first?", "Would you like to buy a pewter spoon?", "In the end, only the three-legged survive.", "I heard that the tall man fears only strong winds.", "In Canifis the men are known for eating much spam.", "I am the egg man, are you one of the egg men?", "I believe that it is very rainy in Varrock.", "The slowest of fishermen catch the swiftest of fish.", "It is quite easy being green.", "Don't forget to find the jade monkey.", "Don't forget to find the jade monkey.", "Do you want ants? Because that's how you get ants.", "I once named a duck after a girl. Big mistake.", "Loser says what.", "I'm looking for a girl named Molly. I can't find her.", "Guys, let's lake dive!", "I gave you what you needed; not what you think you needed.", "Want to see me bend a spoon?", "Is that Deziree?", "This is the last night you'll spend alone.", "(Breathing intensifies)", "Init doe. Lyk, I hope yer reward iz goodd aye?" }; + + /** + * Constructs a new {@Code UriDialogue} {@Code Object} + */ + public UriDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@Code UriDialogue} {@Code Object} + * @param player + */ + public UriDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new UriDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + if (!canSpeak()) { + npc("I do not believe we have any business, Comrade."); + stage = -1; + return true; + } + npc(RandomFunction.getRandomElement(QUOTES)); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case -1: + end(); + break; + case 0: + player("What?"); + asUri().getClueScroll().reward(player); + stage++; + break; + case 1: + interpreter.sendItemMessage(405, "You've been given a casket!"); + stage++; + break; + case 2: + end(); + break; + } + return true; + } + + @Override + public boolean close() { + if (stage >= 1) { + npc.clear(); + player.removeAttribute("killed-agent"); + } + return super.close(); + } + + /** + * Checks if the player can speak to the npc. + * @return {@code True} if so. + */ + public boolean canSpeak() { + EmoteClueScroll scroll = (EmoteClueScroll) asUri().getClueScroll(); + if (asUri().getPlayer() != player || !player.getAttribute("commence-emote", !scroll.hasCommencEmote())) { + return false; + } + return scroll.hasEquipment(player, scroll.getEquipment()); + } + + /** + * Casts to the uri npc. + * @return the npc. + */ + public UriNPC asUri() { + return (UriNPC) npc; + } + + @Override + public int[] getIds() { + return IDS; + } + + } +} diff --git a/Server/src/main/content/global/activity/ttrail/ZamorakWizardNPC.java b/Server/src/main/content/global/activity/ttrail/ZamorakWizardNPC.java new file mode 100644 index 0000000..3b1dae9 --- /dev/null +++ b/Server/src/main/content/global/activity/ttrail/ZamorakWizardNPC.java @@ -0,0 +1,165 @@ +package content.global.activity.ttrail; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.spell.CombatSpell; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.plugin.Plugin; + +/** + * Handles saradomin npc. + * @author Vexia + */ +public final class ZamorakWizardNPC extends AbstractNPC { + + /** + * The npc ids. + */ + private static final int[] IDS = new int[] { 1007 }; + + /** + * The clue scroll. + */ + private ClueScrollPlugin clueScroll; + + /** + * The player. + */ + private Player player; + + /** + * Constructs a new {@code SaradominWizardNPC} {@code Object} + */ + public ZamorakWizardNPC() { + super(0, null); + } + + /** + * Constructs a new {@Code SaradominWizardNPC} {@Code Object} + * @param id the id. + * @param location the location. + */ + public ZamorakWizardNPC(int id, Location location) { + super(id, location, false); + this.setRespawn(false); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new ZamorakWizardNPC(id, location); + } + + @Override + public void init() { + Player player = getAttribute("player", null); + ClueScrollPlugin clueScroll = getAttribute("clue", null); + if (player != null) { + this.player = player; + } + if (clueScroll != null) { + this.clueScroll = clueScroll; + } + if (player != null) { + location = RegionManager.getSpawnLocation(player, this); + if (location == null) { + location = player.getLocation(); + } + } + super.init(); + getProperties().setSpell((CombatSpell) SpellBook.MODERN.getSpell(43)); + getProperties().setAutocastSpell((CombatSpell) SpellBook.MODERN.getSpell(43)); + } + + @Override + public void finalizeDeath(Entity killer) { + if (killer instanceof Player) { + Player p = killer.asPlayer(); + if (p == player) { + p.setAttribute("killed-wizard", clueScroll.getClueId()); + } + } + super.finalizeDeath(killer); + } + + @Override + public void handleTickActions() { + super.handleTickActions(); + if (player != null) { + if (player.getLocation().getDistance(getLocation()) > 10 || !player.isActive()) { + clear(); + } + if (!getProperties().getCombatPulse().isAttacking()) { + getProperties().getCombatPulse().attack(player); + } + } + } + + @Override + public boolean isAttackable(Entity entity, CombatStyle style, boolean message) { + if (!(entity instanceof Player)) { + return false; + } + if (player != null) { + Player p = entity.asPlayer(); + return p == player; + } + return super.isAttackable(entity, style, message); + } + + @Override + public boolean canAttack(Entity entity) { + if (!(entity instanceof Player)) { + return false; + } + if (player != null) { + Player p = entity.asPlayer(); + return p == player; + } + return super.canAttack(entity); + } + + @Override + public boolean canSelectTarget(Entity target) { + return target == player; + + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + return super.newInstance(arg); + } + + @Override + public int[] getIds() { + return IDS; + } + + /** + * Gets the bplayer. + * @return the player + */ + public Player getPlayer() { + return player; + } + + /** + * Sets the baplayer. + * @param player the player to set. + */ + public void setPlayer(Player player) { + this.player = player; + } + + /** + * Gets the bclueScroll. + * @return the clueScroll + */ + public ClueScrollPlugin getClueScroll() { + return clueScroll; + } + +} diff --git a/Server/src/main/content/global/ame/KidnapHelper.kt b/Server/src/main/content/global/ame/KidnapHelper.kt new file mode 100644 index 0000000..2efc90f --- /dev/null +++ b/Server/src/main/content/global/ame/KidnapHelper.kt @@ -0,0 +1,23 @@ +package content.global.ame + +import core.ServerConstants +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.TeleportManager.TeleportType +import core.game.world.map.Location + +fun kidnapPlayer(player: Player, loc: Location, type: TeleportType) { + setAttribute(player, "kidnapped-by-random", true) + if (getAttribute(player, "/save:original-loc", null) == null) { + setAttribute(player, "/save:original-loc", player.location) + } + teleport(player, loc, type) +} + +fun returnPlayer(player: Player) { + player.locks.unlockTeleport() + val destination = getAttribute(player, "/save:original-loc", ServerConstants.HOME_LOCATION ?: Location.create(3222, 3218, 0)) + teleport(player, destination) + unlock(player) + removeAttributes(player, "/save:original-loc", "kidnapped-by-random") +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/RandomEventNPC.kt b/Server/src/main/content/global/ame/RandomEventNPC.kt new file mode 100644 index 0000000..716420e --- /dev/null +++ b/Server/src/main/content/global/ame/RandomEventNPC.kt @@ -0,0 +1,147 @@ +package content.global.ame + +import content.global.ame.events.MysteriousOldManNPC +import core.api.playGlobalAudio +import core.api.poofClear +import core.api.sendMessage +import core.api.utils.WeightBasedTable +import core.game.interaction.MovementPulse +import core.game.node.entity.Entity +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.impl.PulseType +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.agg.AggressiveBehavior +import core.game.node.entity.npc.agg.AggressiveHandler +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.world.map.Location +import core.game.world.map.RegionManager +import core.game.world.map.path.Pathfinder +import core.game.world.update.flag.context.Graphics +import core.integrations.discord.Discord +import core.tools.secondsToTicks +import core.tools.ticksToCycles +import org.rs09.consts.Sounds +import kotlin.math.ceil +import kotlin.math.min +import kotlin.random.Random +import kotlin.reflect.full.createInstance + +abstract class RandomEventNPC(id: Int) : NPC(id) { + lateinit var player: Player + abstract var loot: WeightBasedTable? + var spawnLocation: Location? = null + val SMOKE_GRAPHICS = Graphics(86) + var initialized = false + var finalized = false + var timerPaused = false + var ticksLeft = secondsToTicks(180) + + open fun create(player: Player, loot: WeightBasedTable? = null, type: String = ""): RandomEventNPC { + val event = this::class.createInstance() + if (event is MysteriousOldManNPC) event.type = type + event.loot = loot + event.player = player + event.spawnLocation = RegionManager.getSpawnLocation(player, this) + return event + } + + open fun terminate() { + pulseManager.clear(PulseType.STANDARD) + if (initialized && !finalized) { + poofClear(this) + playGlobalAudio(this.location, Sounds.SMOKEPUFF_1930, ticksToCycles(1)) + } + finalized = true + } + + open fun follow() { + pulseManager.run((object : MovementPulse(this, player, Pathfinder.DUMB) { + override fun pulse(): Boolean { + face(player) + return false + } + }), PulseType.STANDARD) + } + + override fun tick() { + super.tick() + if(player.getAttribute("re-npc", null) != this){ + terminate() + return + } + if (!player.getAttribute("random:pause", false)) { + ticksLeft-- + } + if (!pulseManager.hasPulseRunning() && !finalized) { + follow() + } + if (!player.isActive || !player.location.withinDistance(location, 10)) { + terminate() + } + if (ticksLeft <= 0 && initialized) { + onTimeUp() + initialized = false + } + } + + override fun init() { + initialized = true + finalized = false + timerPaused = false + spawnLocation ?: terminate() + location = spawnLocation + player.setAttribute("re-npc", this) + super.init() + super.aggressiveHandler = AggressiveHandler(this, object : AggressiveBehavior() { + override fun canSelectTarget(entity: Entity, target: Entity): Boolean { + return target == player + } + }) + } + + open fun onTimeUp() { + noteAndTeleport() + terminate() + } + + fun noteAndTeleport() { + player.pulseManager.clear() + for (item in player.inventory.toArray()) { + if (item == null) continue + if (item.definition.isUnnoted) { + player.inventory.remove(item) + player.inventory.add(Item(item.noteChange, item.amount)) + } + } + if (Random.nextBoolean()) { + player.properties.teleportLocation = Location.create(3197, 3223, 0) + } else { + player.properties.teleportLocation = Location.create(3212, 9620, 0) + } + player.graphics(SMOKE_GRAPHICS) + Discord.postPlayerAlert(player.username, "Ignored Random") + } + + override fun clear() { + super.clear() + if(player.getAttribute("re-npc", null) == this) player.removeAttribute("re-npc") + } + + abstract fun talkTo(npc: NPC) + + override fun isAttackable(entity: Entity, style: CombatStyle, message: Boolean): Boolean { + if (entity != player) { + if (entity is Player) { + sendMessage(entity, "It isn't interested in fighting you.") //TODO authentic message + } + return false + } + return super.isAttackable(entity, style, message) + } + + fun idForCombatLevel(ids: List, player: Player): Int { + val index = min(ids.size, ceil(player.properties.currentCombatLevel / 20.0).toInt()) - 1 + return ids[index] + } +} diff --git a/Server/src/main/content/global/ame/RandomEvents.kt b/Server/src/main/content/global/ame/RandomEvents.kt new file mode 100644 index 0000000..49bac51 --- /dev/null +++ b/Server/src/main/content/global/ame/RandomEvents.kt @@ -0,0 +1,95 @@ +package content.global.ame + +import org.rs09.consts.Items +import content.global.ame.events.MysteriousOldManNPC +import content.global.ame.events.certer.CerterNPC +import content.global.ame.events.drilldemon.SergeantDamienNPC +import content.global.ame.events.drunkendwarf.DrunkenDwarfNPC +import content.global.ame.events.evilbob.EvilBobNPC +import content.global.ame.events.evilchicken.EvilChickenNPC +import content.global.ame.events.freakyforester.FreakyForesterNPC +import content.global.ame.events.maze.MazeNPC +import content.global.ame.events.genie.GenieNPC +import content.global.ame.events.pillory.PilloryNPC +import content.global.ame.events.rickturpentine.RickTurpentineNPC +import content.global.ame.events.rivertroll.RiverTrollRENPC +import content.global.ame.events.rockgolem.RockGolemRENPC +import content.global.ame.events.quizmaster.QuizMasterNPC +import content.global.ame.events.sandwichlady.SandwichLadyRENPC +import content.global.ame.events.shade.ShadeRENPC +import content.global.ame.events.strangeplant.StrangePlantNPC +import content.global.ame.events.swarm.SwarmNPC +import content.global.ame.events.treespirit.TreeSpiritRENPC +import content.global.ame.events.zombie.ZombieRENPC + +import core.api.utils.WeightBasedTable +import core.api.utils.WeightedItem +import core.game.node.entity.skill.Skills + +enum class RandomEvents(val npc: RandomEventNPC, val loot: WeightBasedTable? = null, val skillIds: IntArray = intArrayOf(), val type: String = "") { + SANDWICH_LADY(npc = SandwichLadyRENPC()), + GENIE(npc = GenieNPC()), + CERTER(npc = CerterNPC(), loot = WeightBasedTable.create( + WeightedItem(Items.UNCUT_SAPPHIRE_1623,1,1,3.4), + WeightedItem(Items.KEBAB_1971,1,1,1.7), + WeightedItem(Items.UNCUT_EMERALD_1621,1,1,1.7), + WeightedItem(Items.SPINACH_ROLL_1969,1,1,1.5), + WeightedItem(Items.COINS_995,80,80,1.1), + WeightedItem(Items.COINS_995,160,160,1.1), + WeightedItem(Items.COINS_995,320,320,1.1), + WeightedItem(Items.COINS_995,480,480,1.1), + WeightedItem(Items.COINS_995,640,640,1.1), + WeightedItem(Items.UNCUT_RUBY_1619,1,1,0.86), + WeightedItem(Items.COINS_995,240,240,0.65), + WeightedItem(Items.COSMIC_TALISMAN_1454,1,1,0.43), + WeightedItem(Items.UNCUT_DIAMOND_1617,1,1,0.22), + WeightedItem(Items.TOOTH_HALF_OF_A_KEY_985,1,1,0.1), + WeightedItem(Items.LOOP_HALF_OF_A_KEY_987,1,1,0.1) + )), + MAZE(npc = MazeNPC()), + DRILL_DEMON(npc = SergeantDamienNPC()), + EVIL_CHICKEN(npc = EvilChickenNPC()), + STRANGE_PLANT(npc = StrangePlantNPC()), + SWARM(npc = SwarmNPC()), + EVIL_BOB(npc = EvilBobNPC(), skillIds = intArrayOf(Skills.FISHING, Skills.MAGIC)), + DRUNKEN_DWARF(npc = DrunkenDwarfNPC()), + RICK_TURPENTINE(npc = RickTurpentineNPC(), loot = CERTER.loot), + SURPRISE_EXAM(npc = MysteriousOldManNPC(), type = "sexam"), + FREAKY_FORESTER(npc = FreakyForesterNPC(), skillIds = intArrayOf(Skills.WOODCUTTING)), + PILLORY(npc = PilloryNPC(), skillIds = intArrayOf(Skills.THIEVING)), + TREE_SPIRIT(npc = TreeSpiritRENPC(), skillIds = intArrayOf(Skills.WOODCUTTING)), + QUIZ_MASTER(npc = QuizMasterNPC()), + RIVER_TROLL(RiverTrollRENPC(), skillIds = intArrayOf(Skills.FISHING)), + ROCK_GOLEM(RockGolemRENPC(), skillIds = intArrayOf(Skills.MINING)), + SHADE(ShadeRENPC(), skillIds = intArrayOf(Skills.PRAYER)), + ZOMBIE(ZombieRENPC(), skillIds = intArrayOf(Skills.PRAYER)); + + companion object { + @JvmField + val randomIDs = values().map { it.npc.id }.toList() + val skillMap = HashMap>() + val nonSkillList = ArrayList() + + init { populateMappings() } + + fun getSkillBasedRandomEvent (skill: Int) : RandomEvents? { + return skillMap[skill]?.random() + } + + fun getNonSkillRandom() : RandomEvents { + return nonSkillList.random() + } + + private fun populateMappings() { + for (event in values()) { + for (id in event.skillIds) { + val list = skillMap[id] ?: ArrayList().also { skillMap[id] = it } + list.add (event) + } + if (event.skillIds.isEmpty()) + nonSkillList.add (event) + } + } + } + +} diff --git a/Server/src/main/content/global/ame/events/HostileRandomEventBehavior.kt b/Server/src/main/content/global/ame/events/HostileRandomEventBehavior.kt new file mode 100644 index 0000000..37083b0 --- /dev/null +++ b/Server/src/main/content/global/ame/events/HostileRandomEventBehavior.kt @@ -0,0 +1,19 @@ +package content.global.ame.events + +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import org.rs09.consts.NPCs + +class HostileRandomEventBehavior : NPCBehavior( + NPCs.EVIL_CHICKEN_2463, NPCs.EVIL_CHICKEN_2464, NPCs.EVIL_CHICKEN_2465, NPCs.EVIL_CHICKEN_2466, NPCs.EVIL_CHICKEN_2467, NPCs.EVIL_CHICKEN_2468, + NPCs.RIVER_TROLL_391, NPCs.RIVER_TROLL_392, NPCs.RIVER_TROLL_393, NPCs.RIVER_TROLL_394, NPCs.RIVER_TROLL_395, NPCs.RIVER_TROLL_396, + NPCs.ROCK_GOLEM_413, NPCs.ROCK_GOLEM_414, NPCs.ROCK_GOLEM_415, NPCs.ROCK_GOLEM_416, NPCs.ROCK_GOLEM_417, NPCs.ROCK_GOLEM_418, + NPCs.SHADE_425, NPCs.SHADE_426, NPCs.SHADE_427, NPCs.SHADE_428, NPCs.SHADE_429, NPCs.SHADE_430, NPCs.SHADE_431, + NPCs.TREE_SPIRIT_438, NPCs.TREE_SPIRIT_439, NPCs.TREE_SPIRIT_440, NPCs.TREE_SPIRIT_441, NPCs.TREE_SPIRIT_442, NPCs.TREE_SPIRIT_443, + NPCs.ZOMBIE_419, NPCs.ZOMBIE_420, NPCs.ZOMBIE_421, NPCs.ZOMBIE_422, NPCs.ZOMBIE_423, NPCs.ZOMBIE_424 +) { + override fun getXpMultiplier(self: NPC, attacker: Entity): Double { + return super.getXpMultiplier(self, attacker) / 16.0 + } +} diff --git a/Server/src/main/content/global/ame/events/certer/CerterDialogue.kt b/Server/src/main/content/global/ame/events/certer/CerterDialogue.kt new file mode 100644 index 0000000..27f72a3 --- /dev/null +++ b/Server/src/main/content/global/ame/events/certer/CerterDialogue.kt @@ -0,0 +1,60 @@ +package content.global.ame.events.certer + +import core.api.addItemOrDrop +import core.game.component.Component +import core.game.node.entity.impl.PulseType +import core.game.node.entity.player.link.emote.Emotes +import core.game.dialogue.DialogueFile +import core.game.system.timer.impl.AntiMacro +import core.tools.END_DIALOGUE + +class CerterDialogue(val initial: Boolean) : DialogueFile() { + val CERTER_INTERFACE = 184 + override fun handle(componentID: Int, buttonID: Int) { + if (initial && !player!!.getAttribute("certer:reward", false)) { + when (stage) { + 0 -> npc("Ah, hello, ${player!!.username.capitalize()}. Could you", "please help me identify this?").also { stage++ } + 1 -> { + end() + player!!.interfaceManager.open(Component(CERTER_INTERFACE)) + } + } + } else { + player!!.setAttribute("random:pause", true) + val isCorrect = player!!.getAttribute("certer:correct", false) + val receivedReward = player!!.getAttribute("certer:reward", false) + if (receivedReward == true) { + stage = 1 + } + when (stage) { + 0 -> if (!isCorrect) { + npc("Sorry, I don't think so.").also { + player!!.setAttribute("certer:reward", true) + stage = END_DIALOGUE + AntiMacro.terminateEventNpc(player!!) + } + } else { + npc("Thank you, I hope you like your present. I must be", "leaving now though.").also { + player!!.setAttribute("certer:reward", true) + stage = END_DIALOGUE + AntiMacro.rollEventLoot(player!!).forEach { addItemOrDrop(player!!, it.id, it.amount) } + } + } + } + } + } + + override fun end() { + super.end() + if (player!!.getAttribute("certer:reward", false)) { + // Remove movement pulse to stop following player + npc!!.pulseManager.clear(PulseType.STANDARD) + // Wave goodbye + npc!!.animate(Emotes.WAVE.animation) + // Terminate the event + AntiMacro.terminateEventNpc(player!!) + } else { + player!!.setAttribute("random:pause", false) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/certer/CerterEventInterface.kt b/Server/src/main/content/global/ame/events/certer/CerterEventInterface.kt new file mode 100644 index 0000000..96d8f31 --- /dev/null +++ b/Server/src/main/content/global/ame/events/certer/CerterEventInterface.kt @@ -0,0 +1,85 @@ +package content.global.ame.events.certer + +import core.game.node.entity.player.Player +import core.game.node.item.Item +import org.rs09.consts.Items +import core.game.interaction.InterfaceListener +import core.game.system.timer.impl.AntiMacro + +class CerterEventInterface : InterfaceListener { + val CERTER_INTERFACE = 184 + val OPTION_A_CHILD = 1 + val OPTION_B_CHILD = 2 + val OPTION_C_CHILD = 3 + val ITEM_CHILD = 7 + val items = mapOf( + /* + * NOTE: We use these "NULL" items to get their model id + zoom values. + * These were the actual items used by this random event before they + * decided to swap over to using model ids instead. + */ + Items.BOWL_1923 to "A bowl.", + Items.NULL_6189 to "A fish.", + Items.NULL_6190 to "A bass.", + Items.NULL_6191 to "A sword.", + Items.NULL_6192 to "A battleaxe.", + Items.NULL_6193 to "A helmet.", + Items.NULL_6194 to "A kiteshield.", + Items.NULL_6195 to "A pair of shears.", + Items.NULL_6196 to "A shovel.", + Items.NULL_6197 to "A ring.", + Items.NULL_6198 to "A necklace." + ) + val falseOptions = arrayOf("An axe.", "An arrow.", "A pair of boots.", "A pair of gloves.", "A staff.", "A bow.", "A feather.", "The disenfrachaised youth of 1940's Columbia.") + override fun defineInterfaceListeners() { + on(CERTER_INTERFACE) { player, _, _, buttonID, _, _ -> + val answer = buttonID - 7 + val correctAnswer = player.getAttribute("certer:correctIndex", 0) + player.setAttribute("certer:correct", correctAnswer == answer) + player.interfaceManager.close() + player.dialogueInterpreter.open(CerterDialogue(false), AntiMacro.getEventNpc(player)) + return@on true + } + + onOpen(CERTER_INTERFACE) { player, _ -> + generateOptions(player) + return@onOpen true + } + + onClose(CERTER_INTERFACE) { player, _ -> + player.setAttribute("random:pause", false) + return@onClose true + } + } + + fun generateOptions(player: Player) { + val correct = items.keys.random() + val indexes = arrayListOf(1, 2, 3) + val correctIndex = indexes.random() + val correctItem = Item(correct).definition + val iFaceModelId = correctItem.interfaceModelId + val iFaceZoom = correctItem.modelZoom + indexes.remove(correctIndex) + player.setAttribute("certer:correctIndex", correctIndex) + + player.packetDispatch.sendString(items[correct], CERTER_INTERFACE, optionFromIndex(correctIndex)) + + val tempOptions = falseOptions.toMutableList() + val false1 = tempOptions.random() + tempOptions.remove(false1) + val false2 = tempOptions.random() + + player.packetDispatch.sendString(false1, CERTER_INTERFACE, optionFromIndex(indexes[0])) + player.packetDispatch.sendString(false2, CERTER_INTERFACE, optionFromIndex(indexes[1])) + player.packetDispatch.sendModelOnInterface(iFaceModelId, CERTER_INTERFACE, ITEM_CHILD, iFaceZoom) + } + + fun optionFromIndex(index: Int): Int { + return when (index) { + 1 -> OPTION_A_CHILD + 2 -> OPTION_B_CHILD + 3 -> OPTION_C_CHILD + else -> OPTION_A_CHILD + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/certer/CerterNPC.kt b/Server/src/main/content/global/ame/events/certer/CerterNPC.kt new file mode 100644 index 0000000..daf3bc8 --- /dev/null +++ b/Server/src/main/content/global/ame/events/certer/CerterNPC.kt @@ -0,0 +1,50 @@ +package content.global.ame.events.certer + +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.link.emote.Emotes +import core.tools.RandomFunction +import org.rs09.consts.NPCs +import content.global.ame.RandomEventNPC +import core.api.animate +import core.api.utils.WeightBasedTable + +class CerterNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.GILES_2538) { + lateinit var pName: String + lateinit var phrases: Array + + override fun tick() { + // Don't speak if we have the interface opened + if (!timerPaused) { + // Over allotted time phrase + if (ticksLeft <= 2) { + player.lock(2) + sendChat(phrases[4]) + + // Say a phrase every 20 ticks starting at 280 ticks + // as to not interfere with the init chat phrase + } else if (ticksLeft <= 280 && ticksLeft % 20 == 0) { + sendChat(phrases[RandomFunction.random(1, 3)]) + } + } + super.tick() + } + + override fun talkTo(npc: NPC) { + player.setAttribute("random:pause", true) + player.dialogueInterpreter.open(CerterDialogue(true),npc) + } + + override fun init() { + super.init() + pName = player.username.capitalize() + phrases = arrayOf("Greetings $pName, I need your help.", + "ehem... Hello $pName, please talk to me!", + "Hello, are you there $pName?", + "It's really rude to ignore someone, $pName!", + "No-one ignores me!") + player.setAttribute("random:pause", false) + player.setAttribute("certer:reward", false) + sendChat(phrases[0]) + animate(this, Emotes.BOW.animation, true) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/drilldemon/DrillDemonListeners.kt b/Server/src/main/content/global/ame/events/drilldemon/DrillDemonListeners.kt new file mode 100644 index 0000000..2287de3 --- /dev/null +++ b/Server/src/main/content/global/ame/events/drilldemon/DrillDemonListeners.kt @@ -0,0 +1,93 @@ +package content.global.ame.events.drilldemon + +import core.api.* +import core.game.node.entity.npc.NPC +import org.rs09.consts.NPCs +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.game.interaction.QueueStrength +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.world.map.zone.ZoneBorders +import core.game.world.map.zone.ZoneRestriction +import core.tools.secondsToTicks + +import org.rs09.consts.Sounds + +class DrillDemonListeners : InteractionListener, MapArea { + val MATS = intArrayOf(10076,10077,10078,10079) + override fun defineListeners() { + + on(DrillDemonUtils.DD_NPC, IntType.NPC, "talk-to") { player, _ -> + if (inBorders(player, DrillDemonUtils.DD_AREA)) { + openDialogue(player, SeargentDamienDialogue(isCorrect = true), DrillDemonUtils.DD_NPC) + } else { + sendMessage(player, "They aren't interested in talking to you.") + } + return@on true + } + + on(MATS, IntType.SCENERY, "use") { player, node -> + val correctTask = getAttribute(player, DrillDemonUtils.DD_KEY_TASK, -1) + if (correctTask == -1) { + sendMessage(player,"You can't do that right now.") + return@on true + } + + val task = DrillDemonUtils.getMatTask(node.id, player) + val npc = NPC(NPCs.SERGEANT_DAMIEN_2790) + val anim = DrillDemonUtils.animationForTask(task) + + lock(player, secondsToTicks(30)) + player.walkingQueue.reset() + player.walkingQueue.addPath(node.location.x,4820) + queueScript(player, 0, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + player.faceLocation(player.location.transform(0, -1, 0)) + return@queueScript delayScript(player, 2) + } + 1 -> { + animate(player, DrillDemonUtils.animationForTask(task)) + when (task) { + DrillDemonUtils.DD_SIGN_JOG -> playAudio(player, Sounds.RUNONSPOT_2484, 0, 5) + DrillDemonUtils.DD_SIGN_SITUP -> playAudio(player, Sounds.SITUPS_2486, 40, 5) + DrillDemonUtils.DD_SIGN_PUSHUP -> playAudio(player, Sounds.PRESSUPS_2481, 25, 5) + DrillDemonUtils.DD_SIGN_JUMP -> playAudio(player, Sounds.STAR_JUMP_2492, 0, 5) + } + return@queueScript delayScript(player, anim.duration + 2) + } + 2 -> { + DrillDemonUtils.changeSignsAndAssignTask(player) + if (task == correctTask) { + player.incrementAttribute(DrillDemonUtils.DD_CORRECT_COUNTER) + openDialogue(player, SeargentDamienDialogue(true), npc) + } else { + openDialogue(player, SeargentDamienDialogue(false), npc) + } + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + return@on true + } + } + + override fun defineAreaBorders(): Array { + return arrayOf(DrillDemonUtils.DD_AREA) + } + + override fun getRestrictions(): Array { + return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS, ZoneRestriction.OFF_MAP) + } + + override fun areaEnter(entity: Entity) { + if (entity is Player) { + entity.asPlayer().interfaceManager.closeDefaultTabs() + entity.locks.lockTeleport(1000000) + setComponentVisibility(entity.asPlayer(), 548, 69, true) + setComponentVisibility(entity.asPlayer(), 746, 12, true) + } + } +} diff --git a/Server/src/main/content/global/ame/events/drilldemon/DrillDemonUtils.kt b/Server/src/main/content/global/ame/events/drilldemon/DrillDemonUtils.kt new file mode 100644 index 0000000..a6638fe --- /dev/null +++ b/Server/src/main/content/global/ame/events/drilldemon/DrillDemonUtils.kt @@ -0,0 +1,99 @@ +package content.global.ame.events.drilldemon + +import content.global.ame.kidnapPlayer +import content.global.ame.returnPlayer +import core.api.* +import core.game.interaction.QueueStrength +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.TeleportManager +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +object DrillDemonUtils { + val DD_KEY_TASK = "/save:drilldemon:task" + val DD_SIGN_VARP = 531 + val DD_SIGN_JOG = 0 + val DD_SIGN_SITUP = 1 + val DD_SIGN_PUSHUP = 2 + val DD_SIGN_JUMP = 3 + val DD_CORRECT_OFFSET = "/save:drilldemon:offset" + val DD_CORRECT_COUNTER = "/save:drilldemon:numcorrect" + val DD_AREA = ZoneBorders(3158, 4817, 3168, 4823) + val DD_NPC = NPCs.SERGEANT_DAMIEN_2790 + + fun teleport(player: Player) { + kidnapPlayer(player, Location.create(3163, 4819, 0), TeleportManager.TeleportType.INSTANT) + player.interfaceManager.closeDefaultTabs() + setComponentVisibility(player, 548, 69, true) + setComponentVisibility(player, 746, 12, true) + } + + fun changeSignsAndAssignTask(player: Player) { + setVarp(player, DD_SIGN_VARP, 0) + val tempList = arrayListOf(DD_SIGN_JOG, DD_SIGN_JUMP, DD_SIGN_PUSHUP, DD_SIGN_SITUP).shuffled().toMutableList() + val tempOffsetList = arrayListOf(1335, 1336, 1337, 1338).shuffled().toMutableList() + val task = tempList.random() + val taskOffset = tempOffsetList.random() + + setAttribute(player, DD_KEY_TASK, task) + setAttribute(player, DD_CORRECT_OFFSET, taskOffset) + + tempList.remove(task) + tempOffsetList.remove(taskOffset) + setVarbit(player, taskOffset, task) + for (i in 0 until tempList.size) { + setVarbit(player, tempOffsetList[i], tempList[i], true) + } + } + + fun getVarbitForId(id: Int): Int { + return when (id) { + 10076 -> 1335 + 10077 -> 1336 + 10078 -> 1337 + 10079 -> 1338 + else -> 0 + } + } + + fun getMatTask(id: Int, player: Player): Int { + return getVarbit(player, getVarbitForId(id)) + } + + fun cleanup(player: Player) { + returnPlayer(player) + removeAttributes(player, DD_KEY_TASK, DD_CORRECT_OFFSET, DD_CORRECT_COUNTER) + player.interfaceManager.openDefaultTabs() + setComponentVisibility(player, 548, 69, false) + setComponentVisibility(player, 746, 12, false) + } + + fun animationForTask(task: Int): Animation { + return when (task) { + DD_SIGN_SITUP -> Animation(2763) + DD_SIGN_PUSHUP -> Animation(2762) + DD_SIGN_JUMP -> Animation(2761) + DD_SIGN_JOG -> Animation(2764) + else -> Animation(-1) + } + } + + fun reward(player: Player) { + queueScript(player, 2, QueueStrength.SOFT) { + val hasHat = hasAnItem(player, Items.CAMO_HELMET_6656).container != null + val hasShirt = hasAnItem(player, Items.CAMO_TOP_6654).container != null + val hasPants = hasAnItem(player, Items.CAMO_BOTTOMS_6655).container != null + when { + !hasHat -> addItemOrDrop(player, Items.CAMO_HELMET_6656) + !hasShirt -> addItemOrDrop(player, Items.CAMO_TOP_6654) + !hasPants -> addItemOrDrop(player, Items.CAMO_BOTTOMS_6655) + else -> addItemOrDrop(player, Items.COINS_995, 500) + } + return@queueScript stopExecuting(player) + } + + } +} diff --git a/Server/src/main/content/global/ame/events/drilldemon/SeargentDamienDialogue.kt b/Server/src/main/content/global/ame/events/drilldemon/SeargentDamienDialogue.kt new file mode 100644 index 0000000..d9bff58 --- /dev/null +++ b/Server/src/main/content/global/ame/events/drilldemon/SeargentDamienDialogue.kt @@ -0,0 +1,55 @@ +package content.global.ame.events.drilldemon + +import core.api.getAttribute +import core.api.sendItemDialogue +import core.api.unlock +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class SeargentDamienDialogue(var isCorrect: Boolean = false, var eventStart: Boolean = false) : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + npc = NPC(NPCs.SERGEANT_DAMIEN_2790) + val correctCounter = player!!.getAttribute(DrillDemonUtils.DD_CORRECT_COUNTER,0) + when(stage) { + 0 -> { + if (correctCounter >= 4) { + npcl(FacialExpression.OLD_NORMAL, "Well I'll be, you actually did it private. Now take this and get yourself out of my sight.") + stage = 100 + } else if (eventStart) { + npcl(FacialExpression.OLD_NORMAL, "Move yourself private! Follow my orders and you may, just may, leave here in a fit state for my corps!") + DrillDemonUtils.changeSignsAndAssignTask(player!!) + stage = 0 + eventStart = false + } else { + npcl(FacialExpression.OLD_NORMAL, when (getAttribute(player!!, DrillDemonUtils.DD_KEY_TASK, -1)) { + DrillDemonUtils.DD_SIGN_JOG -> if (!isCorrect) "Wrong exercise, worm! Get yourself over there and jog on that mat private!" else "Get yourself over there and jog on that mat private!" + DrillDemonUtils.DD_SIGN_JUMP -> if (!isCorrect) "Wrong exercise, worm! I want to see you on that mat doing star jumps private!" else "I want to see you on that mat doing star jumps private!" + DrillDemonUtils.DD_SIGN_PUSHUP -> if (!isCorrect) "Wrong exercise, worm! Drop and give me push ups on that mat private!" else "Drop and give me push ups on that mat private!" + DrillDemonUtils.DD_SIGN_SITUP -> if (!isCorrect) "Wrong exercise, worm! Get on that mat and give me sit ups private!" else "Get on that mat and give me sit ups private!" + else -> "REEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" + }) + stage = 1 + unlock(player!!) + } + } + 1 -> { + when (getAttribute(player!!, DrillDemonUtils.DD_KEY_TASK, -1)) { + DrillDemonUtils.DD_SIGN_JOG -> sendItemDialogue(player!!, Items.RUN_10947, "Go to this mat and jog on the spot!") + DrillDemonUtils.DD_SIGN_JUMP -> sendItemDialogue(player!!, Items.STARJUMP_10949, "Go to this mat and do some starjumps!") + DrillDemonUtils.DD_SIGN_PUSHUP -> sendItemDialogue(player!!, Items.PUSHUP_10946, "Go to this mat and do some pushups!") + DrillDemonUtils.DD_SIGN_SITUP -> sendItemDialogue(player!!, Items.SITUP_10948, "Go to this mat and do some sit ups!") + } + stage = END_DIALOGUE + } + 100 -> { + end() + DrillDemonUtils.cleanup(player!!) + DrillDemonUtils.reward(player!!) + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/drilldemon/SergeantDamienBehavior.kt b/Server/src/main/content/global/ame/events/drilldemon/SergeantDamienBehavior.kt new file mode 100644 index 0000000..c52c17e --- /dev/null +++ b/Server/src/main/content/global/ame/events/drilldemon/SergeantDamienBehavior.kt @@ -0,0 +1,22 @@ +package content.global.ame.events.drilldemon + +import core.api.inBorders +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.world.map.Location +import org.rs09.consts.NPCs + +class SeargentDamienBehavior: NPCBehavior(NPCs.SERGEANT_DAMIEN_2790) { + + override fun onCreation(self: NPC) { + + // Sergeant Damien is supposed to walk around the perimeter of the exercise mats + if (inBorders(self, DrillDemonUtils.DD_AREA)) { + val movementPath = arrayOf(Location.create(3167, 4822, 0), Location.create(3167, 4818, 0), Location.create(3159, 4818, 0), Location.create(3159, 4822, 0)) + self.configureMovementPath(*movementPath) + self.isWalks = true + } + } + + +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/drilldemon/SergeantDamienNPC.kt b/Server/src/main/content/global/ame/events/drilldemon/SergeantDamienNPC.kt new file mode 100644 index 0000000..af4e8fe --- /dev/null +++ b/Server/src/main/content/global/ame/events/drilldemon/SergeantDamienNPC.kt @@ -0,0 +1,38 @@ +package content.global.ame.events.drilldemon + +import core.game.node.entity.npc.NPC +import org.rs09.consts.NPCs +import content.global.ame.RandomEventNPC +import core.api.* +import core.api.utils.WeightBasedTable + +import core.game.interaction.QueueStrength +import core.game.system.timer.impl.AntiMacro +import core.tools.secondsToTicks + +class SergeantDamienNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.SERGEANT_DAMIEN_2790) { + + override fun init() { + super.init() + sendChat(player.username+ "! Drop and give me 20!") + queueScript(player, 4, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + lock(player, secondsToTicks(30)) + DrillDemonUtils.teleport(player) + AntiMacro.terminateEventNpc(player) + return@queueScript delayScript(player, 2) + } + 1 -> { + openDialogue(player, SeargentDamienDialogue(isCorrect = true, eventStart = true), NPCs.SERGEANT_DAMIEN_2790) + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + } + + override fun talkTo(npc: NPC) { + openDialogue(player, SeargentDamienDialogue(), npc) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/drunkendwarf/DrunkenDwarfBehavior.kt b/Server/src/main/content/global/ame/events/drunkendwarf/DrunkenDwarfBehavior.kt new file mode 100644 index 0000000..a92c554 --- /dev/null +++ b/Server/src/main/content/global/ame/events/drunkendwarf/DrunkenDwarfBehavior.kt @@ -0,0 +1,14 @@ +package content.global.ame.events.drunkendwarf + +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.tools.RandomFunction +import org.rs09.consts.NPCs + +class DrunkenDwarfBehavior : NPCBehavior(NPCs.DRUNKEN_DWARF_956) { + override fun beforeAttackFinalized(self: NPC, victim: Entity, state: BattleState) { + state.estimatedHit = RandomFunction.getRandom(3) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/drunkendwarf/DrunkenDwarfDialogue.kt b/Server/src/main/content/global/ame/events/drunkendwarf/DrunkenDwarfDialogue.kt new file mode 100644 index 0000000..010f5c3 --- /dev/null +++ b/Server/src/main/content/global/ame/events/drunkendwarf/DrunkenDwarfDialogue.kt @@ -0,0 +1,21 @@ +package content.global.ame.events.drunkendwarf + +import core.api.addItemOrDrop +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.system.timer.impl.AntiMacro +import org.rs09.consts.Items + +class DrunkenDwarfDialogue : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> npcl(FacialExpression.OLD_DRUNK_RIGHT, "I 'new it were you matey! 'Ere, have some ob the good stuff!").also { stage++ } + 1 -> { + addItemOrDrop(player!!, Items.BEER_1917) + addItemOrDrop(player!!, Items.KEBAB_1971) + AntiMacro.terminateEventNpc(player!!) + end() + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/drunkendwarf/DrunkenDwarfNPC.kt b/Server/src/main/content/global/ame/events/drunkendwarf/DrunkenDwarfNPC.kt new file mode 100644 index 0000000..1485dd8 --- /dev/null +++ b/Server/src/main/content/global/ame/events/drunkendwarf/DrunkenDwarfNPC.kt @@ -0,0 +1,50 @@ +package content.global.ame.events.drunkendwarf + +import content.global.ame.RandomEventNPC +import core.api.* +import core.api.utils.WeightBasedTable +import core.game.node.entity.npc.NPC +import core.tools.RandomFunction +import org.rs09.consts.NPCs +import org.rs09.consts.Sounds + +class DrunkenDwarfNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.DRUNKEN_DWARF_956) { + private val phrases = arrayOf("Oi, are you der @name!","Dunt ignore your matey!","Aww comeon, talk to ikle me @name!") + private var attackPhrase = false + private var attackDelay = 0 + private var lastPhraseTime = 0 + + private fun sendPhrases() { + if (getWorldTicks() > lastPhraseTime + 5) { + playGlobalAudio(this.location, Sounds.DWARF_WHISTLE_2297) + sendChat(this, phrases.random().replace("@name",player.username.capitalize())) + this.face(player) + lastPhraseTime = getWorldTicks() + } + } + + override fun init() { + super.init() + playGlobalAudio(this.location, Sounds.DWARF_WHISTLE_2297) + sendChat(this, "'Ello der ${player.username.capitalize()}! *hic*") + } + + override fun tick() { + if (RandomFunction.roll(20) && !attackPhrase) + sendPhrases() + if (ticksLeft <= 10) { + ticksLeft = 10 + if (!attackPhrase) + sendChat("I hates you, ${player.username.capitalize()}!").also { attackPhrase = true } + if (attackDelay <= getWorldTicks()) + this.attack(player) + } + super.tick() + } + + override fun talkTo(npc: NPC) { + attackDelay = getWorldTicks() + 10 + this.pulseManager.clear() + openDialogue(player, DrunkenDwarfDialogue(), this.asNpc()) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/evilbob/EvilBobDialogue.kt b/Server/src/main/content/global/ame/events/evilbob/EvilBobDialogue.kt new file mode 100644 index 0000000..f8d132a --- /dev/null +++ b/Server/src/main/content/global/ame/events/evilbob/EvilBobDialogue.kt @@ -0,0 +1,113 @@ +package content.global.ame.events.evilbob + +import content.global.ame.events.evilbob.EvilBobUtils.giveEventFishingSpot +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.skill.Skills +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class EvilBobDialogue(val rewardDialogue: Boolean = false, val rewardXpSkill: Int = Skills.FISHING) : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + npc = NPC(NPCs.EVIL_BOB_2479) + if (getAttribute(player!!, EvilBobUtils.assignedFishingZone, "none") == "none") giveEventFishingSpot(player!!) + when (stage) { + 0 -> { + if (rewardDialogue) { + sendPlayerDialogue(player!!, "That was the strangest dream I've ever had! Assuming it was a dream...", FacialExpression.HALF_ASKING) + stage = if (rewardXpSkill == Skills.FISHING) 900 else 901 + } else if (getAttribute(player!!, EvilBobUtils.eventComplete, false)) { + sendDialogue(player!!, "Evil Bob appears to be sleeping, best not to wake him up.").also { stage = END_DIALOGUE } + } else if (removeItem(player!!, Items.RAW_FISHLIKE_THING_6200)) { + playerl(FacialExpression.NEUTRAL, "Here, I've brought you some fish.").also { stage = 500 } + } else if (removeItem(player!!, Items.RAW_FISHLIKE_THING_6204)) { + setAttribute(player!!, EvilBobUtils.attentive, true) + setAttribute(player!!, EvilBobUtils.attentiveNewSpot, true) + playerl(FacialExpression.NEUTRAL, "Here, I've brought you some fish.").also { stage = 600 } + } else if (inInventory(player!!, Items.FISHLIKE_THING_6202) || inInventory(player!!, Items.FISHLIKE_THING_6206)) { + npcl(FacialExpression.CHILD_NORMAL, "What, are you giving me cooked fish? What am I going to do with that? Uncook it first!").also { stage = 700 } + } else if (!getAttribute(player!!, EvilBobUtils.startingDialogueSeen, false)) { + playerl(FacialExpression.ASKING, "Huh?").also { stage = 800 } + setAttribute(player!!, EvilBobUtils.startingDialogueSeen, true) + } else playerl(FacialExpression.ANNOYED, "Let me out of here!").also { stage++ } + } + 1 -> npcl(FacialExpression.CHILD_NORMAL, "I will never let you go, ${player!!.username}!").also { stage++ } + 2 -> options("Why not?", "What's it all about?", "How is it possible that you're talking?", "What did you do to Bob?").also { stage++ } + 3 -> when (buttonID) { + 1 -> playerl(FacialExpression.ASKING, "Why not?").also { stage = 100 } + 2 -> playerl(FacialExpression.ASKING, "What's it all about?").also { stage = 200 } + 3 -> playerl(FacialExpression.ASKING, "How is it possible that you're talking?").also { stage = 300 } + 4 -> playerl(FacialExpression.ASKING, "What did you do to Bob?").also { stage = 400 } + } + + 100 -> npcl(FacialExpression.CHILD_NORMAL, "Uhm...").also { stage++ } + 101 -> npcl(FacialExpression.CHILD_NORMAL, "Because I say so! And because I can never have enough servants!").also { stage++ } + 102 -> npcl(FacialExpression.CHILD_NORMAL, "Now catch me some fish, I'm hungry.").also { stage++ } + 103 -> playerl(FacialExpression.ASKING, "What fish, where?").also { stage++ } + 104 -> npcl(FacialExpression.CHILD_NORMAL, "Talk to my other servants, and hurry it up!").also { stage = END_DIALOGUE } + + 200 -> npcl(FacialExpression.CHILD_NORMAL, "Sit down and I'll tell you. It's a question of servant shortage.").also { stage++ } + 201 -> playerl(FacialExpression.NEUTRAL, "Go on.").also { stage++ } + 202 -> npcl(FacialExpression.CHILD_NORMAL, "You are a skilled worker. A human like you is worth a great deal as a slave.").also { stage++ } + 203 -> playerl(FacialExpression.ANGRY, "A slave?? I will have nothing to do with you. Is that clear? Absolutely nothing.").also { stage++ } + 204 -> npcl(FacialExpression.CHILD_NORMAL, "Now be reasonable little human. It's just a matter of time before you will do everything I ask you to. Play along and this can be a very nice place.").also { stage++ } + 205 -> playerl(FacialExpression.ANGRY, "I will not make any deals with you. I'm a human. I will not be pushed, numbered, meowed at, teleported or enslaved. My life is my own.").also { stage++ } + 206 -> npcl(FacialExpression.CHILD_NORMAL, "Is it?").also { stage++ } + 207 -> playerl(FacialExpression.ANNOYED, "Yes. You won't hold me.").also { stage++ } + 208 -> npcl(FacialExpression.CHILD_NORMAL, "Won't I?").also { stage++ } + 209 -> npcl(FacialExpression.CHILD_NORMAL, "Let me assure you there's no way out.").also { stage++ } + 210 -> npcl(FacialExpression.CHILD_NORMAL, "Just ask my servants!").also { stage = END_DIALOGUE } + + 300 -> npcl(FacialExpression.CHILD_NORMAL, "How is it possible that you're not meowing?").also { stage++ } + 301 -> playerl(FacialExpression.HALF_ASKING, "Meowing?? Why would I be meowing?").also { stage++ } + 302 -> npcl(FacialExpression.CHILD_NORMAL, "Most humans do, that's why I'm wearing this amulet of Man speak... but I do try to train my staff in civilised speech.").also { stage++ } + 303 -> npcl(FacialExpression.CHILD_NORMAL, "Ah, but I suppose things are slightly different in your world... what a dreadful place that must be.").also { stage++ } + 304 -> playerl(FacialExpression.NEUTRAL, "I think I'm getting a headache...").also { stage = END_DIALOGUE } + + 400 -> npcl(FacialExpression.CHILD_NORMAL, "Bob? I am Bob!").also { stage++ } + 401 -> npcl(FacialExpression.CHILD_NORMAL, "Oh, you mean the Bob in your world? Nothing. I am an incarnation of Bob here on Scape2009.").also { stage++ } + 402 -> playerl(FacialExpression.NEUTRAL, "What, you mean this is... like some kind of mirror land?").also { stage++ } + 403 -> npcl(FacialExpression.CHILD_NORMAL, " Something like that... somewhere in Scape2009 there must be a human servant called ${player!!.username}.").also { stage++ } + 404 -> npcl(FacialExpression.CHILD_NORMAL, "But you work just as well for me! Now get to work, human! Fish for me!").also { stage = END_DIALOGUE } + + 500 ->{ + if (getAttribute(player!!, EvilBobUtils.attentive , false)) stage = 505 else stage++ + npcl(FacialExpression.CHILD_NORMAL, "Mmm, mmm...that's delicious.") + } + 501 -> npcl(FacialExpression.CHILD_NORMAL, "Now, let me take...a little...catnap.").also { stage++ } + 502 -> { + end() + setAttribute(player!!, EvilBobUtils.eventComplete, true) + findNPC(NPCs.EVIL_BOB_2479)!!.sendChat("ZZZzzz") + } + 505 -> { + setAttribute(player!!, EvilBobUtils.attentive , false) + setAttribute(player!!, EvilBobUtils.attentiveNewSpot , true) + giveEventFishingSpot(player!!) + npcl(FacialExpression.CHILD_NORMAL, "Now get me another, you no-good human.").also { stage++ } + } + 506 -> sendDialogue(player!!, "Evil Bob seems slightly less attentive of you.").also { stage = END_DIALOGUE } + + 600 -> npcl(FacialExpression.CHILD_NORMAL, "What was this? That was absolutely disgusting!").also { stage++ } + 601 -> npcl(FacialExpression.CHILD_NORMAL, "Don't you know what kind of fish I like? Talk to my other servants for some advice.").also { stage++ } + 602 -> sendDialogue(player!!, "Evil Bob seems more attentive of you.").also { stage = END_DIALOGUE } + + 700 -> playerl(FacialExpression.HALF_ASKING, "Errr... Uncook it?").also { stage++ } + 701 -> npcl(FacialExpression.CHILD_NORMAL,"You heard me! There's the cold fire, by the trees, now get uncooking!").also { stage = END_DIALOGUE } + + 800 -> playerl(FacialExpression.ANGRY, "Where am I?").also { stage++ } + 801 -> npcl(FacialExpression.CHILD_NORMAL, "On my island.").also { stage++ } + 802 -> playerl(FacialExpression.ANGRY, "Who brought me here?").also { stage++ } + 803 -> npcl(FacialExpression.CHILD_NORMAL, "That would be telling.").also { stage++ } + 804 -> playerl(FacialExpression.ANGRY, "Take me to your leader!").also { stage++ } + 805 -> npcl(FacialExpression.CHILD_NORMAL,"I am your leader, you are but a slave.").also { stage++ } + 806 -> playerl(FacialExpression.ANGRY, "I am not a slave, I am a free man!").also { stage++ } + 807 -> npcl(FacialExpression.CHILD_NORMAL, "Ah-ha-ha-ha-ha-ha!").also { stage = END_DIALOGUE } + 900 -> sendDialogue(player!!, "You feel somehow that you've become better at fishing.").also { stage = END_DIALOGUE } + 901 -> sendDialogue(player!!, "You feel somehow that you've become better at magic.").also { stage = END_DIALOGUE } + } + } +} diff --git a/Server/src/main/content/global/ame/events/evilbob/EvilBobListeners.kt b/Server/src/main/content/global/ame/events/evilbob/EvilBobListeners.kt new file mode 100644 index 0000000..f2a3e91 --- /dev/null +++ b/Server/src/main/content/global/ame/events/evilbob/EvilBobListeners.kt @@ -0,0 +1,148 @@ +package content.global.ame.events.evilbob + +import content.global.ame.returnPlayer +import core.ServerConstants +import core.api.* +import core.game.dialogue.FacialExpression +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength +import core.game.node.entity.Entity +import core.game.node.entity.player.link.emote.Emotes +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import core.game.world.map.zone.ZoneRestriction +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Sounds + +class EvilBobListeners : InteractionListener, MapArea { + + override fun defineListeners() { + on(EvilBobUtils.evilBob, IntType.NPC, "talk-to") { player, node -> + openDialogue(player, EvilBobDialogue(), node.asNpc()) + return@on true + } + + on(EvilBobUtils.servant, IntType.NPC, "talk-to") { player, node -> + openDialogue(player, ServantDialogue(), node.asNpc()) + return@on true + } + + on(EvilBobUtils.fishingSpot, IntType.SCENERY, "net") { player, _ -> + if (getAttribute(player!!, EvilBobUtils.attentiveNewSpot, false) || getAttribute(player!!, EvilBobUtils.eventComplete, false)) { + sendDialogue(player, "You don't know if this is a good place to go fishing. Perhaps you should ask someone, like one of the human servants.") + } else if (!inInventory(player, Items.SMALL_FISHING_NET_303)) { + sendNPCDialogue(player, NPCs.SERVANT_2481, "You'll need a fishing net. There are plenty scattered around the beach.", FacialExpression.SAD) + } else if (freeSlots(player) == 0) { + sendDialogue(player, "You don't have enough space in your inventory.") + } else if (inInventory(player, Items.FISHLIKE_THING_6202) || inInventory(player, Items.FISHLIKE_THING_6206) || + inInventory(player, Items.RAW_FISHLIKE_THING_6200) || inInventory(player, Items.RAW_FISHLIKE_THING_6204)) { + sendNPCDialogue(player, NPCs.SERVANT_2481, "You've already got a fish. Come over here to uncook it, then serve it to Evil Bob.", FacialExpression.SAD) + } else { + lock(player, 6) + animate(player, EvilBobUtils.fishAnim) + sendMessage(player, "You cast out your net...") + runTask(player, 6) { + when (getAttribute(player, EvilBobUtils.assignedFishingZone, EvilBobUtils.northFishingZone.toString())) { + EvilBobUtils.northFishingZone.toString() -> { + if (inBorders(player, EvilBobUtils.northFishingZone)) { + addItem(player, Items.FISHLIKE_THING_6202) + } else addItem(player, Items.FISHLIKE_THING_6206) + } + EvilBobUtils.southFishingZone.toString() -> { + if (inBorders(player, EvilBobUtils.southFishingZone)) { + addItem(player, Items.FISHLIKE_THING_6202) + } else addItem(player, Items.FISHLIKE_THING_6206) + } + EvilBobUtils.eastFishingZone.toString() -> { + if (inBorders(player, EvilBobUtils.eastFishingZone)) { + addItem(player, Items.FISHLIKE_THING_6202) + } else addItem(player, Items.FISHLIKE_THING_6206) + } + EvilBobUtils.westFishingZone.toString() -> { + if (inBorders(player, EvilBobUtils.westFishingZone)) { + addItem(player, Items.FISHLIKE_THING_6202) + } else addItem(player, Items.FISHLIKE_THING_6206) + } + } + sendItemDialogue(player, Items.FISHLIKE_THING_6202, "You catch a... what is this?? Is this a fish?? And it's cooked already??") + resetAnimator(player) + } + } + return@on true + } + + onUseWith(IntType.SCENERY, EvilBobUtils.fishlikeThings, EvilBobUtils.uncookingPot) { player, _, _ -> + lock(player, 2) + animate(player, EvilBobUtils.cookAnim) + playAudio(player, Sounds.UNCOOKING_2322) + if (removeItem(player, Items.FISHLIKE_THING_6202)) addItem(player, Items.RAW_FISHLIKE_THING_6200) + if (removeItem(player, Items.FISHLIKE_THING_6206)) addItem(player, Items.RAW_FISHLIKE_THING_6204) + return@onUseWith true + } + + onUseWith(IntType.NPC, EvilBobUtils.fishlikeThings, EvilBobUtils.evilBob) { player, _, _ -> + openDialogue(player, EvilBobDialogue(), NPCs.EVIL_BOB_2479) + return@onUseWith true + } + + onUseWith(IntType.NPC, EvilBobUtils.rawFishlikeThings, EvilBobUtils.evilBob) { player, _, _ -> + openDialogue(player, EvilBobDialogue(), NPCs.EVIL_BOB_2479) + return@onUseWith true + } + + on(EvilBobUtils.fishlikeThings, IntType.ITEM, "Eat") { player, _ -> + sendMessage(player, "It looks vile and smells even worse. You're not eating that!") + return@on true + } + + on(EvilBobUtils.exitPortal, IntType.SCENERY, "enter") { player, portal -> + if (getAttribute(player, EvilBobUtils.eventComplete, false)) { + lock(player, 12) + queueScript(player, 0, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + forceMove(player, player.location, portal.location, 0, 50, null, 819) + return@queueScript delayScript(player, 3) + } + 1 -> { + player.faceLocation(Location.create(3421, 4777, 0)) + emote(player, Emotes.RASPBERRY) + sendChat(player, "Be seeing you!") + return@queueScript delayScript(player,2) + } + 2 -> { + animate(player, EvilBobUtils.teleAnim) + player.graphics(EvilBobUtils.telegfx) + playAudio(player, Sounds.TELEPORT_ALL_200) + return@queueScript delayScript(player, 2) + } + 3 -> { + sendMessage(player, "Welcome back to ${ServerConstants.SERVER_NAME}.") + returnPlayer(player) + EvilBobUtils.reward(player) + EvilBobUtils.cleanup(player) + resetAnimator(player) + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + } else sendNPCDialogue(player, NPCs.EVIL_BOB_2479, "You're going nowhere, human!", FacialExpression.CHILD_NEUTRAL) + return@on true + } + } + override fun defineAreaBorders(): Array { + return arrayOf(ZoneBorders(3400, 4762, 3443, 4793)) + } + + override fun getRestrictions(): Array { + return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS, ZoneRestriction.OFF_MAP) + } + + override fun areaEnter(entity: Entity) { + entity.locks.lockTeleport(1000000) + } + +} diff --git a/Server/src/main/content/global/ame/events/evilbob/EvilBobNPC.kt b/Server/src/main/content/global/ame/events/evilbob/EvilBobNPC.kt new file mode 100644 index 0000000..fc0fe28 --- /dev/null +++ b/Server/src/main/content/global/ame/events/evilbob/EvilBobNPC.kt @@ -0,0 +1,44 @@ +package content.global.ame.events.evilbob + +import content.global.ame.RandomEventNPC +import core.api.* +import core.api.utils.WeightBasedTable +import core.game.interaction.QueueStrength +import core.game.node.entity.npc.NPC +import core.game.system.timer.impl.AntiMacro +import org.rs09.consts.NPCs +import org.rs09.consts.Sounds + +class EvilBobNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.EVIL_BOB_2478) { + + override fun init() { + super.init() + sendChat("meow") + queueScript(player, 4, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + lock(player, 6) + sendChat(player, "No... what? Nooooooooooooo!") + animate(player, EvilBobUtils.teleAnim) + player.graphics(EvilBobUtils.telegfx) + playAudio(player, Sounds.TELEPORT_ALL_200) + EvilBobUtils.giveEventFishingSpot(player) + return@queueScript delayScript(player, 3) + } + 1 -> { + sendMessage(player, "Welcome to Scape2009.") + EvilBobUtils.teleport(player) + resetAnimator(player) + openDialogue(player, EvilBobDialogue(), NPCs.EVIL_BOB_2479) + AntiMacro.terminateEventNpc(player) + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + } + + override fun talkTo(npc: NPC) { + openDialogue(player, EvilBobDialogue(), this.asNpc()) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/evilbob/EvilBobUtils.kt b/Server/src/main/content/global/ame/events/evilbob/EvilBobUtils.kt new file mode 100644 index 0000000..d70eab9 --- /dev/null +++ b/Server/src/main/content/global/ame/events/evilbob/EvilBobUtils.kt @@ -0,0 +1,90 @@ +package content.global.ame.events.evilbob + +import content.global.ame.kidnapPlayer +import content.global.ame.returnPlayer +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.TeleportManager +import core.game.node.entity.skill.Skills +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import core.tools.RandomFunction +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +object EvilBobUtils { + const val eventComplete = "/save:evilbob:eventcomplete" + const val assignedFishingZone = "/save:evilbob:fishingzone" + const val attentive = "/save:evilbob:attentive" + const val servantHelpDialogueSeen = "/save:evilbob:servantdialogeseen" + const val attentiveNewSpot = "/save:evilbob:attentivenewspot" + const val startingDialogueSeen = "/save:evilbob:startingdialogueseen" + + const val evilBob = NPCs.EVIL_BOB_2479 + const val servant = NPCs.SERVANT_2481 + const val exitPortal = Scenery.PORTAL_8987 + + const val uncookingPot = Scenery.UNCOOKING_POT_8985 + const val fishingSpot = 8986 + + val fishlikeThings = intArrayOf(Items.FISHLIKE_THING_6202, Items.FISHLIKE_THING_6206) + val rawFishlikeThings = intArrayOf(Items.RAW_FISHLIKE_THING_6200, Items.RAW_FISHLIKE_THING_6204) + + val cookAnim = Animation(897) + val fishAnim = Animation(620) + val teleAnim = Animation(714) + val telegfx = Graphics(308, 100, 50) + + val northFishingZone = ZoneBorders(3421, 4789, 3427, 4792) + val eastFishingZone = ZoneBorders(3437, 4774, 3440, 4780) + val southFishingZone = ZoneBorders(3419, 4763, 3426, 4765) + val westFishingZone = ZoneBorders(3405, 4773, 3408, 4779) + + fun giveEventFishingSpot(player: Player) { + when (RandomFunction.getRandom(3)) { + 0 -> setAttribute(player, assignedFishingZone, northFishingZone.toString()) + 1 -> setAttribute(player, assignedFishingZone, southFishingZone.toString()) + 2 -> setAttribute(player, assignedFishingZone, eastFishingZone.toString()) + 3 -> setAttribute(player, assignedFishingZone, westFishingZone.toString()) + else -> setAttribute(player, assignedFishingZone, northFishingZone.toString()) + } + } + + fun teleport(player: Player) { + kidnapPlayer(player, Location.create(3419, 4776, 0), TeleportManager.TeleportType.INSTANT) + } + + fun cleanup(player: Player) { + removeAttributes(player, assignedFishingZone, eventComplete, attentive, servantHelpDialogueSeen, attentiveNewSpot, startingDialogueSeen) + removeAll(player, Items.FISHLIKE_THING_6202) + removeAll(player, Items.FISHLIKE_THING_6202, Container.BANK) + removeAll(player, Items.FISHLIKE_THING_6206) + removeAll(player, Items.FISHLIKE_THING_6206, Container.BANK) + removeAll(player, Items.RAW_FISHLIKE_THING_6200) + removeAll(player, Items.RAW_FISHLIKE_THING_6200, Container.BANK) + removeAll(player, Items.RAW_FISHLIKE_THING_6204) + removeAll(player, Items.RAW_FISHLIKE_THING_6204, Container.BANK) + } + + fun reward(player: Player) { + val experience = 650.0 + if (getStatLevel(player, Skills.MAGIC) > 50 ) { + when (RandomFunction.getRandom(1)) { + 0 -> { + player.skills.addExperience(Skills.FISHING, experience) + openDialogue(player, EvilBobDialogue(rewardDialogue = true, rewardXpSkill = Skills.FISHING), NPCs.EVIL_BOB_2479) + } + 1 -> { + player.skills.addExperience(Skills.MAGIC, experience) + openDialogue(player, EvilBobDialogue(rewardDialogue = true, rewardXpSkill = Skills.MAGIC), NPCs.EVIL_BOB_2479) + } + } + } else { + player.skills.addExperience(Skills.FISHING, experience) + openDialogue(player, EvilBobDialogue(rewardDialogue = true, rewardXpSkill = Skills.FISHING), NPCs.EVIL_BOB_2479) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/evilbob/ServantCutscene.kt b/Server/src/main/content/global/ame/events/evilbob/ServantCutscene.kt new file mode 100644 index 0000000..db54e0d --- /dev/null +++ b/Server/src/main/content/global/ame/events/evilbob/ServantCutscene.kt @@ -0,0 +1,150 @@ +package content.global.ame.events.evilbob + +import core.api.* +import core.game.activity.Cutscene +import core.game.node.entity.player.Player + +class ServantCutsceneN(player: Player) : Cutscene(player) { + + override fun setup() { + setExit(player.location.transform(0, 0, 0)) + loadRegion(13642) + } + + override fun runStage(stage: Int) { + when (stage) { + 0 -> { + fadeToBlack() + timedUpdate(4) + } + 1 -> { + teleport(player, 29, 41) + moveCamera(30, 43) // +7 from statue + openInterface(player, 186) + timedUpdate(2) + } + 2 -> { + timedUpdate(2) + rotateCamera(30, 51, 300, 100) // the statue loc + fadeFromBlack() + } + 3 -> { + timedUpdate(9) + moveCamera(30, 46, 300, 2) // +4 from statue + } + 4 -> { + end{ player.locks.lockTeleport(1000000) } + closeInterface(player) + } + } + } +} + +class ServantCutsceneS(player: Player) : Cutscene(player) { + + override fun setup() { + setExit(player.location.transform(0, 0, 0)) + loadRegion(13642) + } + + override fun runStage(stage: Int) { + when (stage) { + 0 -> { + fadeToBlack() + timedUpdate(4) + } + 1 -> { + teleport(player, 29, 41) + moveCamera(29, 38) // +7 from statue + openInterface(player, 186) + timedUpdate(2) + } + 2 -> { + timedUpdate(2) + rotateCamera(29, 30, 300, 100) // the statue loc + fadeFromBlack() + } + 3 -> { + timedUpdate(9) + moveCamera(29, 35, 300, 2) // +4 from statue + } + 4 -> { + end{ player.locks.lockTeleport(1000000) } + closeInterface(player) + } + } + } +} + +class ServantCutsceneE(player: Player) : Cutscene(player) { + + override fun setup() { + setExit(player.location.transform(0, 0, 0)) + loadRegion(13642) + } + + override fun runStage(stage: Int) { + when (stage) { + 0 -> { + fadeToBlack() + timedUpdate(4) + } + 1 -> { + teleport(player, 29, 41) + moveCamera(35, 41) // +7 from statue + openInterface(player, 186) + timedUpdate(2) + } + 2 -> { + timedUpdate(2) + rotateCamera(43, 41, 300, 100) // the statue loc + fadeFromBlack() + } + 3 -> { + timedUpdate(9) + moveCamera(38, 41, 300, 2) // +4 from statue + } + 4 -> { + end{ player.locks.lockTeleport(1000000) } + closeInterface(player) + } + } + } +} + +class ServantCutsceneW(player: Player) : Cutscene(player) { + + override fun setup() { + setExit(player.location.transform(0, 0, 0)) + loadRegion(13642) + } + + override fun runStage(stage: Int) { + when (stage) { + 0 -> { + fadeToBlack() + timedUpdate(4) + } + 1 -> { + teleport(player, 29, 41) + moveCamera(25, 40) // +7 from statue + openInterface(player, 186) + timedUpdate(2) + } + 2 -> { + timedUpdate(2) + rotateCamera(18, 40, 300, 100) // the statue loc + fadeFromBlack() + } + 3 -> { + timedUpdate(9) + moveCamera(22, 40, 300, 2) // +4 from statue + } + 4 -> { + end{ player.locks.lockTeleport(1000000) } + closeInterface(player) + } + + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/evilbob/ServantDialogue.kt b/Server/src/main/content/global/ame/events/evilbob/ServantDialogue.kt new file mode 100644 index 0000000..c177f8d --- /dev/null +++ b/Server/src/main/content/global/ame/events/evilbob/ServantDialogue.kt @@ -0,0 +1,58 @@ +package content.global.ame.events.evilbob + +import core.ServerConstants +import core.api.getAttribute +import core.api.setAttribute +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +class ServantDialogue : DialogueFile() { + + override fun handle(componentID: Int, buttonID: Int) { + npc = NPC(NPCs.SERVANT_2481) + when (stage) { + 0 -> { + if (getAttribute(player!!, EvilBobUtils.eventComplete, false)) { + playerl(FacialExpression.NEUTRAL, "Evil Bob has fallen asleep, come quickly!").also { stage = 2 } + } else if (!getAttribute(player!!, EvilBobUtils.servantHelpDialogueSeen, false)) { + playerl(FacialExpression.ANGRY, "I need help, I've been kidnapped by an evil cat!").also { stage = 200 } + } else if (getAttribute(player!!, EvilBobUtils.attentiveNewSpot, false)) { + npcl(FacialExpression.SAD, "Look... over t-t-there! That fishing spot c-c-contains the f-f-f-fish he likes.").also { stage = 1 } + } else npcl(FacialExpression.SAD, "F-f-f-fish... give him the f-f-f-fish he likes and he might f- f-f-fall asleep.").also { stage = END_DIALOGUE } + + } + 1 -> { + end() + setAttribute(player!!, EvilBobUtils.attentiveNewSpot, false) + when (getAttribute(player!!, EvilBobUtils.assignedFishingZone, EvilBobUtils.northFishingZone.toString())) { + EvilBobUtils.northFishingZone.toString() -> ServantCutsceneN(player!!).start() + EvilBobUtils.southFishingZone.toString() -> ServantCutsceneS(player!!).start() + EvilBobUtils.eastFishingZone.toString() -> ServantCutsceneE(player!!).start() + EvilBobUtils.westFishingZone.toString() -> ServantCutsceneW(player!!).start() + } + } + 2 -> npcl(FacialExpression.SAD, "Come? Come where?").also { stage++ } + 3 -> playerl(FacialExpression.FRIENDLY, "Away from this place! To ${ServerConstants.SERVER_NAME} proper!").also { stage++ } + 4 -> npcl(FacialExpression.SAD, "You go, ${player!!.username}, I don't belong there... I belong here, in Scape2009. This is the only place I can ever go...").also { stage++ } + 5 -> options("But I love you!", "Oh alright then.").also { stage++ } + 6 -> when(buttonID) { + 1 -> playerl(FacialExpression.SAD, "But I love you!").also { stage = 100 } + 2 -> playerl(FacialExpression.NEUTRAL, "Oh, alright then, I'll be off! See you around!").also { stage = END_DIALOGUE} + } + + 100 -> npcl(FacialExpression.NEUTRAL, "Our love can never be, sweet ${player!!.username}.").also { stage++ } + 101 -> npcl(FacialExpression.NEUTRAL, "Go now! Go, and don't look back!").also { stage = END_DIALOGUE } + + 200 -> npcl(FacialExpression.SAD, "Meow! Errr... I c-c-c-can't help you... He'll kill us all!").also { stage++ } + 201 -> playerl(FacialExpression.ANGRY, "Now you listen to me! He's just a little cat! There must be something I can do!").also { stage++ } + 202 -> npcl(FacialExpression.SAD, "F-f-f-fish... give him the f-f-f-fish he likes and he might f- f-f-fall asleep.").also { stage++ } + 203 -> { + npcl(FacialExpression.SAD, "Look... over t-t-there! That fishing spot c-c-contains the f-f-f-fish he likes.").also { stage = 1 } + setAttribute(player!!, EvilBobUtils.servantHelpDialogueSeen, true) + } + } + } +} diff --git a/Server/src/main/content/global/ame/events/evilchicken/EvilChickenNPC.kt b/Server/src/main/content/global/ame/events/evilchicken/EvilChickenNPC.kt new file mode 100644 index 0000000..5b065f5 --- /dev/null +++ b/Server/src/main/content/global/ame/events/evilchicken/EvilChickenNPC.kt @@ -0,0 +1,43 @@ +package content.global.ame.events.evilchicken + +import core.api.getWorldTicks +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import core.tools.RandomFunction +import org.rs09.consts.Items +import content.global.ame.RandomEventNPC +import core.api.utils.WeightBasedTable + +val ids = (2463..2468).toList() + +class EvilChickenNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(2463) { + val phrases = arrayOf("Bwuk","Bwuk bwuk bwuk","Flee from me, @name!","Begone, @name!","Bwaaaauuuk bwuk bwuk","MUAHAHAHAHAAA!") + override fun talkTo(npc: NPC) {} + + override fun init() { + super.init() + val id = idForCombatLevel(ids, player) + this.transform(id) + this.attack(player) + sendChat(phrases.random().replace("@name",player.username.capitalize())) + this.isRespawn = false + } + + override fun finalizeDeath(killer: Entity?) { + super.finalizeDeath(killer) + GroundItemManager.create(Item(Items.FEATHER_314, RandomFunction.random(50,300)), this.dropLocation, player) + } + + override fun tick() { + if(!player.location.withinDistance(this.location,8)){ + this.terminate() + } + if(getWorldTicks() % 10 == 0){ + sendChat(phrases.random().replace("@name",player.username.capitalize())) + } + super.tick() + if(!player.viewport.currentPlane.npcs.contains(this)) this.clear() + } +} diff --git a/Server/src/main/content/global/ame/events/freakyforester/FreakListeners.kt b/Server/src/main/content/global/ame/events/freakyforester/FreakListeners.kt new file mode 100644 index 0000000..8754a8d --- /dev/null +++ b/Server/src/main/content/global/ame/events/freakyforester/FreakListeners.kt @@ -0,0 +1,66 @@ +package content.global.ame.events.freakyforester + +import core.api.* +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.Entity +import core.game.system.task.Pulse +import core.game.world.map.zone.ZoneBorders +import core.game.world.map.zone.ZoneRestriction +import org.rs09.consts.Items + +class FreakListeners : InteractionListener, MapArea { + + private val exitPortal = Scenery.PORTAL_8972 + private val freakNpc = NPCs.FREAKY_FORESTER_2458 + private val pheasants = intArrayOf(NPCs.PHEASANT_2459,NPCs.PHEASANT_2460,NPCs.PHEASANT_2461,NPCs.PHEASANT_2462) + override fun defineListeners() { + on(freakNpc,IntType.NPC,"talk-to") { player, node -> + if (inBorders(player, FreakUtils.freakArea)) { + if (getAttribute(player, FreakUtils.freakTask, -1) == -1) FreakUtils.giveFreakTask(player) + openDialogue(player, FreakyForesterDialogue(), node.asNpc()) + } else { + sendMessage(player, "They aren't interested in talking to you.") + } + return@on true + } + + on(pheasants,IntType.NPC,"attack") { player, node -> + if (getAttribute(player,FreakUtils.freakComplete, false)) { + sendMessage(player,"You don't need to attack any more pheasants. You're allowed to leave.") + } else if (inInventory(player, Items.RAW_PHEASANT_6178) || inInventory(player, Items.RAW_PHEASANT_6179) || getAttribute(player, FreakUtils.pheasantKilled, false)){ + sendMessage(player,"You don't need to attack any more pheasants.") + } else { + player.attack(node.asNpc()) + } + return@on true + } + + on(exitPortal,IntType.SCENERY,"enter") { player, _ -> + if (getAttribute(player,FreakUtils.freakComplete,false)) { + FreakUtils.cleanup(player) + submitWorldPulse(object : Pulse(2) { + override fun pulse(): Boolean { + FreakUtils.reward(player) + return true + } + }) + return@on true + } else sendMessage(player,"A supernatural force prevents you from leaving.") + return@on true + } + } + override fun defineAreaBorders(): Array { + return arrayOf(FreakUtils.freakArea) + } + + override fun getRestrictions(): Array { + return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS, ZoneRestriction.OFF_MAP) + } + + override fun areaEnter(entity: Entity) { + entity.locks.lockTeleport(1000000) + } +} diff --git a/Server/src/main/content/global/ame/events/freakyforester/FreakUtils.kt b/Server/src/main/content/global/ame/events/freakyforester/FreakUtils.kt new file mode 100644 index 0000000..e247bfe --- /dev/null +++ b/Server/src/main/content/global/ame/events/freakyforester/FreakUtils.kt @@ -0,0 +1,59 @@ +package content.global.ame.events.freakyforester + +import content.global.ame.kidnapPlayer +import content.global.ame.returnPlayer +import core.api.* +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.TeleportManager +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import core.tools.RandomFunction + +object FreakUtils{ + const val freakNpc = NPCs.FREAKY_FORESTER_2458 + const val freakTask = "/save:freakyf:task" + const val freakComplete = "/save:freakyf:complete" + const val pheasantKilled = "freakyf:killed" + val freakArea = ZoneBorders(2587, 4758, 2616, 4788) + fun giveFreakTask(player: Player) { + when(RandomFunction.getRandom(4)) { + 0 -> setAttribute(player, freakTask, NPCs.PHEASANT_2459) + 1 -> setAttribute(player, freakTask, NPCs.PHEASANT_2460) + 2 -> setAttribute(player, freakTask, NPCs.PHEASANT_2461) + 3 -> setAttribute(player, freakTask, NPCs.PHEASANT_2462) + else -> setAttribute(player, freakTask, NPCs.PHEASANT_2459) + } + player.dialogueInterpreter.open(FreakyForesterDialogue(), freakNpc) + } + + fun teleport(player: Player) { + kidnapPlayer(player, Location.create(2599, 4777 ,0), TeleportManager.TeleportType.INSTANT) + } + + fun cleanup(player: Player) { + returnPlayer(player) + removeAttributes(player, freakTask, freakComplete, pheasantKilled) + removeAll(player, Items.RAW_PHEASANT_6178) + removeAll(player, Items.RAW_PHEASANT_6178, Container.BANK) + removeAll(player, Items.RAW_PHEASANT_6179) + removeAll(player, Items.RAW_PHEASANT_6179, Container.BANK) + } + + fun reward(player: Player){ + val hasHat = hasAnItem(player, Items.LEDERHOSEN_HAT_6182).container != null + val hasTop = hasAnItem(player, Items.LEDERHOSEN_TOP_6180).container != null + val hasShort = hasAnItem(player, Items.LEDERHOSEN_SHORTS_6181).container != null + sendNPCDialogue(player, freakNpc, "You get a lederhosen item as a reward for your help, many thanks!") + when{ + (!hasHat) -> addItemOrDrop(player, Items.LEDERHOSEN_HAT_6182, 1) + (!hasTop) -> addItemOrDrop(player, Items.LEDERHOSEN_TOP_6180, 1) + (!hasShort) -> addItemOrDrop(player, Items.LEDERHOSEN_SHORTS_6181, 1) + else ->{ + sendNPCDialogue(player, freakNpc, "You get some money for your help, many thanks!") + addItemOrDrop(player, Items.COINS_995, 500) + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/freakyforester/FreakyForesterDialogue.kt b/Server/src/main/content/global/ame/events/freakyforester/FreakyForesterDialogue.kt new file mode 100644 index 0000000..c9ff3cc --- /dev/null +++ b/Server/src/main/content/global/ame/events/freakyforester/FreakyForesterDialogue.kt @@ -0,0 +1,27 @@ +package content.global.ame.events.freakyforester + +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class FreakyForesterDialogue : DialogueFile(){ + + override fun handle(componentID: Int, buttonID: Int) { + if (removeItem(player!!, Items.RAW_PHEASANT_6179) && !getAttribute(player!!, FreakUtils.freakComplete, false)) { + npcl(FacialExpression.NEUTRAL, "That's not the right one.").also { stage = END_DIALOGUE } + setAttribute(player!!, FreakUtils.pheasantKilled, false) + } else if (removeItem(player!!, Items.RAW_PHEASANT_6178) || getAttribute(player!!, FreakUtils.freakComplete, false)) { + npcl(FacialExpression.NEUTRAL, "Thanks, ${player!!.username}, you may leave the area now.").also { stage = END_DIALOGUE } + sendChat(findNPC(FreakUtils.freakNpc)!!, "Thanks, ${player!!.username}, you may leave the area now.") + setAttribute(player!!, FreakUtils.freakComplete, true) + } else when (getAttribute(player!!, FreakUtils.freakTask, -1)) { + NPCs.PHEASANT_2459 -> sendNPCDialogue(player!!, FreakUtils.freakNpc, "Hey there ${player!!.username}. Can you kill the one tailed pheasant please. Bring me the raw pheasant when you're done.").also { stage = END_DIALOGUE } + NPCs.PHEASANT_2460 -> sendNPCDialogue(player!!, FreakUtils.freakNpc, "Hey there ${player!!.username}. Can you kill the two tailed pheasant please. Bring me the raw pheasant when you're done.").also { stage = END_DIALOGUE } + NPCs.PHEASANT_2461 -> sendNPCDialogue(player!!, FreakUtils.freakNpc, "Hey there ${player!!.username}. Can you kill the three tailed pheasant please. Bring me the raw pheasant when you're done.").also { stage = END_DIALOGUE } + NPCs.PHEASANT_2462 -> sendNPCDialogue(player!!, FreakUtils.freakNpc, "Hey there ${player!!.username}. Can you kill the four tailed pheasant please. Bring me the raw pheasant when you're done.").also { stage = END_DIALOGUE } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/freakyforester/FreakyForesterNPC.kt b/Server/src/main/content/global/ame/events/freakyforester/FreakyForesterNPC.kt new file mode 100644 index 0000000..4b03662 --- /dev/null +++ b/Server/src/main/content/global/ame/events/freakyforester/FreakyForesterNPC.kt @@ -0,0 +1,43 @@ +package content.global.ame.events.freakyforester + +import content.global.ame.RandomEventNPC +import core.api.* +import org.rs09.consts.NPCs +import core.api.utils.WeightBasedTable +import core.game.interaction.QueueStrength +import core.game.node.entity.npc.NPC +import core.game.system.timer.impl.AntiMacro +import core.game.world.update.flag.context.Graphics +import org.rs09.consts.Sounds + +class FreakyForesterNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.FREAKY_FORESTER_2458) { + + override fun init() { + super.init() + sendChat("Ah, ${player.username}, just the person I need!") + queueScript(player, 4, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + lock(player, 6) + sendGraphics(Graphics(308, 100, 50), player.location) + animate(player,714) + playAudio(player, Sounds.TELEPORT_ALL_200) + return@queueScript delayScript(player, 3) + } + 1 -> { + FreakUtils.teleport(player) + FreakUtils.giveFreakTask(player) + AntiMacro.terminateEventNpc(player) + openDialogue(player, FreakyForesterDialogue(), FreakUtils.freakNpc) + resetAnimator(player) + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + } + + override fun talkTo(npc: NPC) { + player.dialogueInterpreter.open(FreakyForesterDialogue(),npc) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/freakyforester/PheasantBehavior.kt b/Server/src/main/content/global/ame/events/freakyforester/PheasantBehavior.kt new file mode 100644 index 0000000..ad49212 --- /dev/null +++ b/Server/src/main/content/global/ame/events/freakyforester/PheasantBehavior.kt @@ -0,0 +1,37 @@ +package content.global.ame.events.freakyforester + +import core.api.getAttribute +import core.api.sendMessage +import core.api.sendNPCDialogue +import core.api.setAttribute +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import core.game.node.item.Item +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class PheasantBehavior : NPCBehavior(NPCs.PHEASANT_2459, NPCs.PHEASANT_2460, NPCs.PHEASANT_2461, NPCs.PHEASANT_2462) { + override fun onDropTableRolled(self: NPC, killer: Entity, drops: ArrayList) { + val assignedPheasant = getAttribute(killer, FreakUtils.freakTask, -1) + if (assignedPheasant == -1) return + drops.removeLast() + if (assignedPheasant == self.id) { + drops.add(Item (Items.RAW_PHEASANT_6178)) + } else { + drops.add(Item (Items.RAW_PHEASANT_6179)) + } + setAttribute(killer, FreakUtils.pheasantKilled, true) + } + + override fun beforeDamageReceived(self: NPC, attacker: Entity, state: BattleState) { + state.estimatedHit = 5 + state.secondaryHit = 0 + } + + override fun getXpMultiplier(self: NPC, attacker: Entity): Double { + return 0.0 + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/genie/GenieDialogue.kt b/Server/src/main/content/global/ame/events/genie/GenieDialogue.kt new file mode 100644 index 0000000..7bcaa3c --- /dev/null +++ b/Server/src/main/content/global/ame/events/genie/GenieDialogue.kt @@ -0,0 +1,20 @@ +package content.global.ame.events.genie + +import core.api.* +import core.game.dialogue.FacialExpression +import core.game.dialogue.DialogueFile +import core.game.system.timer.impl.AntiMacro +import org.rs09.consts.Items + +class GenieDialogue() : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> npcl(FacialExpression.NEUTRAL, "Ah, so you are there, ${player!!.username.capitalize()}. I'm so glad you summoned me. Please take this lamp and make your wish."). also { stage++ } + 1 -> { + end() + addItemOrDrop(player!!, Items.LAMP_2528) + AntiMacro.terminateEventNpc(player!!) + } + } + } +} diff --git a/Server/src/main/content/global/ame/events/genie/GenieNPC.kt b/Server/src/main/content/global/ame/events/genie/GenieNPC.kt new file mode 100644 index 0000000..6f3cf39 --- /dev/null +++ b/Server/src/main/content/global/ame/events/genie/GenieNPC.kt @@ -0,0 +1,30 @@ +package content.global.ame.events.genie + +import core.game.node.entity.npc.NPC +import core.tools.RandomFunction +import org.rs09.consts.NPCs +import content.global.ame.RandomEventNPC +import core.api.playAudio +import core.api.utils.WeightBasedTable +import org.rs09.consts.Sounds + +class GenieNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.GENIE_409) { + val phrases = arrayOf("Greetings, @name!","Ehem... Master @name?","Are you there, Master @name?","No one ignores me!") + + override fun tick() { + if(RandomFunction.random(1,15) == 5){ + sendChat(phrases.random().replace("@name",player.username.capitalize())) + } + super.tick() + } + + override fun init() { + super.init() + playAudio(player, Sounds.GENIE_APPEAR_2301) + sendChat(phrases.random().replace("@name",player.username.capitalize())) + } + + override fun talkTo(npc: NPC) { + player.dialogueInterpreter.open(GenieDialogue(),npc) + } +} diff --git a/Server/src/main/content/global/ame/events/maze/MazeInterface.kt b/Server/src/main/content/global/ame/events/maze/MazeInterface.kt new file mode 100644 index 0000000..108d456 --- /dev/null +++ b/Server/src/main/content/global/ame/events/maze/MazeInterface.kt @@ -0,0 +1,277 @@ +package content.global.ame.events.maze + +import content.global.ame.returnPlayer +import core.api.* +import core.api.utils.WeightBasedTable +import core.api.utils.WeightedItem +import core.game.event.EventHook +import core.game.event.TickEvent +import core.game.global.action.DoorActionHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.system.task.Pulse +import core.game.world.GameWorld.Pulser +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import core.game.world.map.zone.ZoneRestriction +import core.game.world.update.flag.context.Graphics +import org.rs09.consts.* + +class MazeInterface : InteractionListener, EventHook, MapArea { + companion object { + const val MAZE_TIMER_INTERFACE = Components.MAZETIMER_209 + const val MAZE_TIMER_VARP = 531 // Interface 209 child 2 config: [531, 0] + const val MAZE_ATTRIBUTE_TICKS_LEFT = "maze:percent-ticks-left" + const val MAZE_ATTRIBUTE_CHESTS_OPEN = "/save:maze:chests-opened" + + val STARTING_POINTS = arrayOf( + Location(2928, 4553, 0), + Location(2917, 4553, 0), + Location(2908, 4555, 0), + Location(2891, 4589, 0), + Location(2891, 4595, 0), + Location(2891, 4595, 0), + Location(2926, 4597, 0), + Location(2931, 4597, 0), + // There's 2 more, but there isn't a door for them... + ) + + val REWARD_ITEM = intArrayOf( + Items.COINS_995, + Items.FEATHER_314, + Items.IRON_ARROW_884, + Items.CHAOS_RUNE_562, + Items.STEEL_ARROW_886, + Items.DEATH_RUNE_560, + Items.COAL_454, + Items.NATURE_RUNE_561, + Items.MITHRIL_ORE_448 + ) + + val ITEM_DIVISOR = arrayOf( + 1.0, + 2.0, + 3.0, + 9.0, + 12.0, + 18.0, + 45.0, + 162.0, + 180.0, + ) + + val CHEST_REWARDS = WeightBasedTable.create( + WeightedItem(Items.AIR_RUNE_556,15,15,1.0), + WeightedItem(Items.WATER_RUNE_555,10,10,1.0), + WeightedItem(Items.EARTH_RUNE_557,10,10,1.0), + WeightedItem(Items.FIRE_RUNE_554,10,10,1.0), + WeightedItem(Items.BRONZE_ARROW_882,20,20,1.0), + WeightedItem(Items.BRONZE_BOLTS_877,10,10,1.0), + WeightedItem(Items.IRON_ARROW_884,15,15,1.0), + WeightedItem(Items.ATTACK_POTION2_123,1,1,1.0), + WeightedItem(Items.STRENGTH_POTION2_117,1,1,1.0), + WeightedItem(Items.DEFENCE_POTION2_135,1,1,1.0), + ) + + fun initMaze(player: Player) { + setAttribute(player, MAZE_ATTRIBUTE_TICKS_LEFT, 300) + setVarp(player, MAZE_TIMER_VARP, (getAttribute(player, MAZE_ATTRIBUTE_TICKS_LEFT, 0) / 3),false) + openOverlay(player, MAZE_TIMER_INTERFACE) + sendMessage(player, "You need to reach the maze center, then you'll be returned to where you were.") + sendNPCDialogue(player, NPCs.MYSTERIOUS_OLD_MAN_410, "You need to reach the maze center, then you'll be returned to where you were.") + } + + fun calculateLoot(player: Player) { + val randomNumber = (0..8).random() + val totalLevel = player.getSkills().totalLevel.toDouble() + val rewardPotential = getAttribute(player, MAZE_ATTRIBUTE_TICKS_LEFT, 0).toDouble() / 300.0 + val itemDivisor = ITEM_DIVISOR[randomNumber] + val itemQuantity = (totalLevel * rewardPotential * 3.33) / itemDivisor + // sendMessage(player, "Maze reward calculation: $totalLevel * $rewardPotential * 3.33 / $itemDivisor = $itemQuantity") + if (itemQuantity.toInt() > 0) { + addItemOrDrop(player, REWARD_ITEM[randomNumber], itemQuantity.toInt()) + } + } + + /** + * Chest Location to rotation mapping. + * This is needed as it is impossible to obtain the underlying chest scenery for the rotation. + * 0: Facing North, 1: Facing East, 2: Facing South, 3: Facing West + */ + val chestLocationRotationMap = mapOf( + Location(2930, 4595, 0).toString() to 2, + Location(2924, 4572, 0).toString() to 2, + Location(2925, 4573, 0).toString() to 0, + Location(2900, 4578, 0).toString() to 2, + Location(2901, 4560, 0).toString() to 1, + Location(2890, 4599, 0).toString() to 2, + Location(2896, 4591, 0).toString() to 2, + Location(2895, 4592, 0).toString() to 1, + Location(2901, 4560, 0).toString() to 3, + Location(2918, 4590, 0).toString() to 1, + Location(2917, 4590, 0).toString() to 3, + ) + + /** + * Chest Interaction workaround + * + * The issue here is that the walls(3626) of the Maze are overlapping some(not all) chest sceneries. + * + * The types for the wallScenery: + * Type 0 - flat panel | + * Type 2 - right angle panel with rotation 0:r 1:7 2:> 3:L + * Type 3 - corner post . for angle edges of walls + */ + fun overrideScenery(wallScenery: core.game.node.scenery.Scenery, chestSceneryId: Int): core.game.node.scenery.Scenery { + if (wallScenery.id == chestSceneryId) { + replaceScenery(wallScenery, Scenery.CHEST_3636, 30) + wallScenery.isActive = true + return wallScenery // Return the chest scenery as the wallScenery isn't there. + } + + addScenery(Scenery.CHEST_3636, wallScenery.location, chestLocationRotationMap[wallScenery.location.toString()] ?: 0, 10) + addScenery(wallScenery) + // replaceScenery(newChestScenery, Scenery.CHEST_3636, 3) // didn't work for an underlying scenery + // I did a world pulse since everyone will get to see the chest open. + Pulser.submit(object : Pulse(30) { + override fun pulse(): Boolean { + addScenery(Scenery.CHEST_3635, wallScenery.location, chestLocationRotationMap[wallScenery.location.toString()] ?: 0, 10) + addScenery(wallScenery) + return true + } + }) + // Return the chest scenery to replace PacketProcessor so that MISMATCH will not happen. + return core.game.node.scenery.Scenery( + chestSceneryId, + wallScenery.location, + chestLocationRotationMap[wallScenery.location.toString()] ?: 0 + ) + } + } + + override fun defineListeners() { + + // This somehow doesn't trigger as the scenery.id != objId (3626 != 3635) + on(Scenery.CHEST_3635, IntType.SCENERY, "open") { player, node -> + if (getAttribute(player, MAZE_ATTRIBUTE_TICKS_LEFT, 0) > 0 && getAttribute(player, MAZE_ATTRIBUTE_CHESTS_OPEN, 0) < 10) { + animate(player, 536) + // val actualScenery = RegionManager.getObject(node.location.z, node.location.x, node.location.y, 3626) + val tableRoll = CHEST_REWARDS.roll() + addItemOrBank(player, tableRoll[0].id) + when (tableRoll[0].id){ + Items.AIR_RUNE_556 -> sendItemDialogue(player, Items.AIR_RUNE_556, "You've found some air runes!") + Items.WATER_RUNE_555 -> sendItemDialogue(player, Items.WATER_RUNE_555, "You've found some water runes!") + Items.EARTH_RUNE_557 -> sendItemDialogue(player, Items.EARTH_RUNE_557, "You've found some earth runes!") + Items.FIRE_RUNE_554 -> sendItemDialogue(player, Items.FIRE_RUNE_554, "You've found some fire runes!") + Items.BRONZE_ARROW_882 -> sendItemDialogue(player, Items.BRONZE_ARROW_882, "You've found some bronze arrows!") + Items.BRONZE_BOLTS_877 -> sendItemDialogue(player, Items.BRONZE_BOLTS_877, "You've found some bronze bolts!") + Items.IRON_ARROW_884 -> sendItemDialogue(player, Items.IRON_ARROW_884, "You've found some iron arrows!") + Items.ATTACK_POTION2_123 -> sendItemDialogue(player, Items.ATTACK_POTION2_123, "You've found an attack potion!") + Items.STRENGTH_POTION2_117 -> sendItemDialogue(player, Items.STRENGTH_POTION2_117, "You've found a strength potion!") + Items.DEFENCE_POTION2_135 -> sendItemDialogue(player, Items.DEFENCE_POTION2_135, "You've found a defence potion!") + } + setAttribute(player, MAZE_ATTRIBUTE_CHESTS_OPEN, getAttribute(player, MAZE_ATTRIBUTE_CHESTS_OPEN, 0)) + } else { + sendMessage(player,"You find nothing of interest.") + } + return@on true + } + + on(Scenery.CHEST_3636, SCENERY, "search") { player, node -> + sendMessage(player,"You find nothing of interest.") + return@on true + } + + on(Scenery.WALL_3626, IntType.SCENERY, "open") { player, node -> + sendMessage(player, "That bit doesn't open.") // 0xBrLo9woIY + return@on true + } + + on(Scenery.WALL_3628, IntType.SCENERY, "open") { player, node -> + // Door opening workaround + // Ignore 3629(WALL_3629) and 3630(WALL_3630) in handleAutowalkDoor ignoreSecondDoor + DoorActionHandler.handleAutowalkDoor(player, node as core.game.node.scenery.Scenery) + return@on true + } + + on(Scenery.STRANGE_SHRINE_3634, IntType.SCENERY, "touch") { player, node -> + player.unhook(this) + closeOverlay(player) + queueScript(player, 0, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + lock(player, 6) + sendGraphics(Graphics(86, 0, 3), player.location) + animate(player,862) + return@queueScript delayScript(player, 6) + } + 1 -> { + lock(player, 6) + sendGraphics(Graphics(1576, 0, 0), player.location) + animate(player,8939) + playAudio(player, Sounds.TELEPORT_ALL_200) + return@queueScript delayScript(player, 3) + } + 2 -> { + returnPlayer(player) + sendGraphics(Graphics(1577, 0, 0), player.location) + animate(player,8941) + closeOverlay(player) + return@queueScript delayScript(player, 1) + } + 3 -> { + calculateLoot(player) + removeAttribute(player, MAZE_ATTRIBUTE_TICKS_LEFT) + removeAttribute(player, MAZE_ATTRIBUTE_CHESTS_OPEN) + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + + return@on true + } + } + + override fun process(entity: Entity, event: TickEvent) { + if (entity is Player) { + if (getAttribute(entity, MAZE_ATTRIBUTE_TICKS_LEFT, 0) > 0) { + setAttribute(entity, MAZE_ATTRIBUTE_TICKS_LEFT, getAttribute(entity, MAZE_ATTRIBUTE_TICKS_LEFT, 0) - 1) + } + setVarp(entity, MAZE_TIMER_VARP, (getAttribute(entity, MAZE_ATTRIBUTE_TICKS_LEFT, 0) / 3), false) + } + } + + override fun defineAreaBorders(): Array { + return arrayOf(getRegionBorders(11591)) + } + + override fun getRestrictions(): Array { + return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS, ZoneRestriction.TELEPORT, ZoneRestriction.OFF_MAP) + } + + override fun areaEnter(entity: Entity) { + if (entity is Player) { + sendMessage(entity, "Head for the center of the maze.") + entity.interfaceManager.removeTabs(0, 1, 2, 3, 4, 5, 6, 12) + openOverlay(entity, MAZE_TIMER_INTERFACE) + } + } + + override fun areaLeave(entity: Entity, logout: Boolean) { + if (entity is Player) { + entity.interfaceManager.restoreTabs() + closeOverlay(entity) + entity.unhook(this) + } + } + override fun entityStep(entity: Entity, location: Location, lastLocation: Location) { + if (entity is Player) { + entity.hook(Event.Tick, this) + } + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/maze/MazeNPC.kt b/Server/src/main/content/global/ame/events/maze/MazeNPC.kt new file mode 100644 index 0000000..e4befe0 --- /dev/null +++ b/Server/src/main/content/global/ame/events/maze/MazeNPC.kt @@ -0,0 +1,57 @@ +package content.global.ame.events.maze + +import content.global.ame.RandomEventNPC +import content.global.ame.kidnapPlayer +import core.api.* +import core.api.utils.WeightBasedTable +import core.game.interaction.QueueStrength +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.link.TeleportManager +import core.game.system.timer.impl.AntiMacro +import core.game.world.map.Location +import core.game.world.map.build.DynamicRegion +import core.game.world.update.flag.context.Graphics +import org.rs09.consts.NPCs +import org.rs09.consts.Sounds + +class MazeNPC(var type: String = "", override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.MYSTERIOUS_OLD_MAN_410) { + + override fun init() { + super.init() + sendChat("Aha, you'll do ${player.username}!") + face(player) + queueScript(player, 4, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + lock(player, 6) + sendGraphics(Graphics(1576, 0, 0), player.location) + animate(player,8939) + playAudio(player, Sounds.TELEPORT_ALL_200) + return@queueScript delayScript(player, 3) + } + 1 -> { + MazeInterface.initMaze(player) + // Note: This event is NOT instanced: + // Sources: + // https://youtu.be/2gpzn9oNdy0 (2007) + // https://youtu.be/Tni1HURgnxg (2008) + // https://youtu.be/igdwDZOv9LU (2008) + // https://youtu.be/0oBCkLArUmc (2011 - even with personal Mysterious Old Man) - "Sorry, this is not the old man you are looking for." + // https://youtu.be/FMuKZm-Ikgs (2011) + // val region = DynamicRegion.create(11591) + kidnapPlayer(player, MazeInterface.STARTING_POINTS.random(), TeleportManager.TeleportType.INSTANT) // 10 random spots + AntiMacro.terminateEventNpc(player) + sendGraphics(Graphics(1577, 0, 0), player.location) + animate(player,8941) + removeAttribute(player, MazeInterface.MAZE_ATTRIBUTE_CHESTS_OPEN) + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + } + + override fun talkTo(npc: NPC) { + // Do nothing. + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/pillory/PilloryInterface.kt b/Server/src/main/content/global/ame/events/pillory/PilloryInterface.kt new file mode 100644 index 0000000..f48fc76 --- /dev/null +++ b/Server/src/main/content/global/ame/events/pillory/PilloryInterface.kt @@ -0,0 +1,219 @@ +package content.global.ame.events.pillory + +import content.global.ame.RandomEvents +import content.global.ame.returnPlayer +import core.api.* +import core.game.dialogue.FacialExpression +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.game.interaction.InterfaceListener +import core.game.interaction.QueueStrength +import core.game.node.entity.Entity +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import core.game.world.map.zone.ZoneRestriction +import core.game.world.update.flag.context.Graphics +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery +import org.rs09.consts.Sounds + +/** + * Pillory Unlocking Interface PILLORY_189 + * + * https://www.youtube.com/watch?v=caWn7pE2mkE + * https://www.youtube.com/watch?v=TMVR5cZZwZ0 + * https://www.youtube.com/watch?v=Ym9LCDP-Q74 + * https://www.youtube.com/watch?v=_vn0QZTtI6U (Failure) + * https://www.youtube.com/watch?v=zmXDikQIua4 + * + * Child IDs + * 4 - Rotating Lock Model + * 5 6 7 - Swinging Keys Models + * 8 9 10 - Buttons for the Swinging Keys Models + * 11 12 13 14 15 16 - Padlocks at the Top + * 17 18 19 20 21 22 - Padlocks stars? Model 15272, Anim 4135 + * + * Model IDs + * Using the amazeballs ::listifmodels + * 9749, 9750, 9751, 9752 - Swinging Keys Models + * 9753, 9754, 9755, 9756 - Rotating Lock Models + * 9757 9758 locked unlock + */ +class PilloryInterface : InterfaceListener, InteractionListener, MapArea { + companion object { + const val PILLORY_LOCK_INTERFACE = 189 + const val PILLORY_ATTRIBUTE_EVENT_KEYS = "pillory:event-keys" + const val PILLORY_ATTRIBUTE_EVENT_LOCK = "pillory:event-lock" + const val PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT = "/save:pillory:target-correct" + const val PILLORY_ATTRIBUTE_CORRECT_COUNTER = "/save:pillory:num-correct" + + val LOCATIONS = arrayOf( + // Varrock Cages + Location(3226, 3407, 0), + Location(3228, 3407, 0), + Location(3230, 3407, 0), + // Seers Village Cages + Location(2681, 3489, 0), + Location(2683, 3489, 0), + Location(2685, 3489, 0), + // Yannile Cages + Location(2604, 3105, 0), + Location(2606, 3105, 0), + Location(2608, 3105, 0), + ) + + fun initPillory(player: Player) { + setAttribute(player, PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT, 3) + setAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, 0) + player.dialogueInterpreter.sendPlainMessage(true, "", "Solve the pillory puzzle to be returned to where you came from.") + } + + fun randomPillory(player: Player) { + // Shuffle all 4 kinds of keys in, pick 3 for the keys, pick 1 from the 3 as the lock. + val keys = (0..3).toIntArray().let{ keys -> keys.shuffle(); return@let keys } + val lock = intArrayOf(keys[1], keys[2], keys[3]).random() // Last 3 as there are 4 keys. key[0] is fallback. + + setAttribute(player, PILLORY_ATTRIBUTE_EVENT_KEYS, keys) + setAttribute(player, PILLORY_ATTRIBUTE_EVENT_LOCK, lock) + + player.packetDispatch.sendModelOnInterface(9753 + lock, PILLORY_LOCK_INTERFACE, 4, 0) + player.packetDispatch.sendModelOnInterface(9749 + keys[1], PILLORY_LOCK_INTERFACE, 5, 0) + player.packetDispatch.sendModelOnInterface(9749 + keys[2], PILLORY_LOCK_INTERFACE, 6, 0) + player.packetDispatch.sendModelOnInterface(9749 + keys[3], PILLORY_LOCK_INTERFACE, 7, 0) + + val numberToGetCorrect = getAttribute(player, PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT, 3) + val correctCount = getAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, 0) + for (i in 1.. 6) { + // Set if lock is red or green. + if (i <= correctCount) { + player.packetDispatch.sendModelOnInterface(9758, PILLORY_LOCK_INTERFACE, 10 + i, 0) + } else { + player.packetDispatch.sendModelOnInterface(9757, PILLORY_LOCK_INTERFACE, 10 + i, 0) + } + // Set if hide or show lock. + player.packetDispatch.sendInterfaceConfig(PILLORY_LOCK_INTERFACE, 10 + i, i > numberToGetCorrect) + } + } + + fun selectedKey(player: Player, buttonID: Int) { + val keys = getAttribute(player, PILLORY_ATTRIBUTE_EVENT_KEYS, intArrayOf(0, 0, 0)) + val lock = getAttribute(player, PILLORY_ATTRIBUTE_EVENT_LOCK, -1) + if (keys[buttonID] == lock) { + // CORRECT ANSWER + setAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, getAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, 0) + 1) + if (getAttribute(player, PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT, 3) <= getAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, -1)) { + player.dialogueInterpreter.sendPlainMessage(true, "", "You've escaped!") + sendMessage(player, "You've escaped!") + removeAttribute(player, PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT) + removeAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER) + closeInterface(player) + queueScript(player, 0, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + lock(player, 6) + sendGraphics(Graphics(1576, 0, 0), player.location) + animate(player,8939) + playAudio(player, Sounds.TELEPORT_ALL_200) + return@queueScript delayScript(player, 3) + } + 1 -> { + val loot = RandomEvents.CERTER.loot!!.roll(player)[0] + addItemOrDrop(player, loot.id, loot.amount) + returnPlayer(player) + sendGraphics(Graphics(1577, 0, 0), player.location) + animate(player,8941) + closeInterface(player) + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + return + } + randomPillory(player) + player.dialogueInterpreter.sendPlainMessage( + true, + "", + "Correct!", + "" + getAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, 0) + " down, " + + (getAttribute(player, PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT, 3) - getAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, 0)) + " to go!") + // Animation for the star, but it doesn't work. + player.packetDispatch.sendInterfaceConfig(PILLORY_LOCK_INTERFACE, 16 + getAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, 1), false) + sendAnimationOnInterface(player, 4135, PILLORY_LOCK_INTERFACE, 16 + getAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, 1)) + } else { + // WRONG ANSWER + player.dialogueInterpreter.close() + player.dialogueInterpreter.sendDialogues(NPCs.TRAMP_2794 , FacialExpression.OLD_ANGRY1, "Bah, that's not right.","Use the key that matches the hole", "in the spinning lock.") + if (getAttribute(player, PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT, 0) < 6) { + setAttribute(player, PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT, getAttribute(player, PILLORY_ATTRIBUTE_NEEDED_TO_GET_CORRECT, 0) + 1) + } + setAttribute(player, PILLORY_ATTRIBUTE_CORRECT_COUNTER, 0) + closeInterface(player) + } + } + } + + override fun defineInterfaceListeners() { + on(PILLORY_LOCK_INTERFACE){ player, component, opcode, buttonID, slot, itemID -> + when (buttonID) { + 8 -> selectedKey(player, 1) + 9 -> selectedKey(player, 2) + 10 -> selectedKey(player, 3) + } + return@on true + } + + onOpen(PILLORY_LOCK_INTERFACE){ player, component -> + return@onOpen true + } + } + + override fun defineListeners() { + on(Scenery.CAGE_6836, IntType.SCENERY, "unlock") { player, node -> + if (player.location in LOCATIONS) { // When you aren't inside. + randomPillory(player) + openInterface(player, PILLORY_LOCK_INTERFACE) + player.dialogueInterpreter.sendPlainMessage(true, "", "Pick the swinging key that matches the", "hole in the spinning lock.") + } else { + sendMessage(player, "You can't unlock the pillory, you'll let all the prisoners out!") + } + return@on true + } + } + + override fun defineAreaBorders(): Array { + return arrayOf( + // Varrock Cages + ZoneBorders(3226, 3407, 3226, 3407), + ZoneBorders(3228, 3407, 3228, 3407), + ZoneBorders(3230, 3407, 3230, 3407), + // Seers Village Cages + ZoneBorders(2681, 3489, 2681, 3489), + ZoneBorders(2683, 3489, 2683, 3489), + ZoneBorders(2685, 3489, 2685, 3489), + // Yannile Cages + ZoneBorders(2604, 3105, 2604, 3105), + ZoneBorders(2606, 3105, 2606, 3105), + ZoneBorders(2608, 3105, 2608, 3105), + ) + } + + override fun getRestrictions(): Array { + return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS, ZoneRestriction.TELEPORT, ZoneRestriction.OFF_MAP) + } + + override fun areaEnter(entity: Entity) { + if (entity is Player) { + entity.interfaceManager.removeTabs(0, 1, 2, 3, 4, 5, 6, 12) + } + } + + override fun areaLeave(entity: Entity, logout: Boolean) { + if (entity is Player) { + entity.interfaceManager.restoreTabs() + } + } + + +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/pillory/PilloryNPC.kt b/Server/src/main/content/global/ame/events/pillory/PilloryNPC.kt new file mode 100644 index 0000000..f833d9c --- /dev/null +++ b/Server/src/main/content/global/ame/events/pillory/PilloryNPC.kt @@ -0,0 +1,50 @@ +package content.global.ame.events.pillory + +import content.global.ame.RandomEventNPC +import content.global.ame.kidnapPlayer +import core.api.* +import core.api.utils.WeightBasedTable +import core.game.interaction.QueueStrength +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.link.TeleportManager +import core.game.system.timer.impl.AntiMacro +import core.game.world.map.Location +import core.game.world.update.flag.context.Graphics +import org.rs09.consts.NPCs +import org.rs09.consts.Sounds + +// "::revent [-p] player name [-e event name]" +class PilloryNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.PILLORY_GUARD_2791) { + + override fun init() { + super.init() + sendChat("${player.username}, you're under arrest!") + face(player) + player.dialogueInterpreter.sendPlainMessage(true, "", "Solve the pillory puzzle to be returned to where you came from.") + queueScript(player, 4, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + lock(player, 6) + sendGraphics(Graphics(1576, 0, 0), player.location) + animate(player,8939) + playAudio(player, Sounds.TELEPORT_ALL_200) + return@queueScript delayScript(player, 3) + } + 1 -> { + PilloryInterface.initPillory(player) + val dest = PilloryInterface.LOCATIONS.random() //9 random spots! + kidnapPlayer(player, dest, TeleportManager.TeleportType.INSTANT) + AntiMacro.terminateEventNpc(player) + sendGraphics(Graphics(1577, 0, 0), player.location) + animate(player,8941) + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + } + + override fun talkTo(npc: NPC) { + //player.dialogueInterpreter.open(FreakyForesterDialogue(),npc) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/quizmaster/QuizMasterBorders.kt b/Server/src/main/content/global/ame/events/quizmaster/QuizMasterBorders.kt new file mode 100644 index 0000000..860d4d7 --- /dev/null +++ b/Server/src/main/content/global/ame/events/quizmaster/QuizMasterBorders.kt @@ -0,0 +1,37 @@ +package content.global.ame.events.quizmaster + +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import core.game.world.map.zone.ZoneRestriction +import org.rs09.consts.NPCs + +class QuizMasterBorders : MapArea { + override fun defineAreaBorders(): Array { + return arrayOf(getRegionBorders(7754)) + } + + override fun getRestrictions(): Array { + return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS, ZoneRestriction.TELEPORT, ZoneRestriction.OFF_MAP) + } + + override fun areaEnter(entity: Entity) { + if (entity is Player) { + entity.interfaceManager.removeTabs(0, 1, 2, 3, 4, 5, 6, 12) + face(entity, Location(1952, 4768, 1)) + animate(entity,2378) + openDialogue(entity, QuizMasterDialogueFile(), NPC(NPCs.QUIZ_MASTER_2477)) + } + } + + override fun areaLeave(entity: Entity, logout: Boolean) { + if (entity is Player) { + entity.interfaceManager.restoreTabs() + //closeOverlay(entity) + } + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/quizmaster/QuizMasterDialogueFile.kt b/Server/src/main/content/global/ame/events/quizmaster/QuizMasterDialogueFile.kt new file mode 100644 index 0000000..4790a85 --- /dev/null +++ b/Server/src/main/content/global/ame/events/quizmaster/QuizMasterDialogueFile.kt @@ -0,0 +1,129 @@ +package content.global.ame.events.quizmaster + +import content.global.ame.returnPlayer +import core.ServerConstants +import core.api.* +import core.api.utils.WeightBasedTable +import core.api.utils.WeightedItem +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.interaction.QueueStrength +import core.game.node.entity.player.Player +import core.tools.END_DIALOGUE +import org.rs09.consts.Components +import org.rs09.consts.Items + +class QuizMasterDialogueFile : DialogueFile() { + companion object { + const val QUIZMASTER_INTERFACE = Components.MACRO_QUIZSHOW_191 + const val QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT = "/save:quizmaster:questions-correct" + const val QUIZMASTER_ATTRIBUTE_RANDOM_ANSWER = "quizmaster:random-answer" + + /* + // Golden Models: + 8828 ADAMANT_BATTLEAXE_1371 + 8829 SALMON_329 + 8830 TROUT_333 + 8831 NECKLACE + 8832 WOODEN_SHIELD_1171 + 8833 BRONZE_MED_HELM_1139 + 8834 RING + 8835 SECATEURS_5329 + 8836 BRONZE_SWORD_1277 + 8837 GARDENING_TROWEL_5325 + */ + val sets = arrayOf( + intArrayOf(8828, 8829, 8829), + intArrayOf(8831, 8837, 8835), + intArrayOf(8830, 8832, 8833), + intArrayOf(8835, 8834, 8831), + intArrayOf(8837, 8836, 8828), + ) + + fun randomQuestion(player: Player): Int { + val randomSet = intArrayOf(*sets.random()) + val answer = intArrayOf(*randomSet)[0] + randomSet.shuffle() + val correctButton = randomSet.indexOf(answer) + 2 // buttons are 3,4,5 + + player.packetDispatch.sendModelOnInterface(randomSet[0], QUIZMASTER_INTERFACE, 6, 512) + player.packetDispatch.sendModelOnInterface(randomSet[1], QUIZMASTER_INTERFACE, 7, 512) + player.packetDispatch.sendModelOnInterface(randomSet[2], QUIZMASTER_INTERFACE, 8, 512) + player.packetDispatch.sendAngleOnInterface(QUIZMASTER_INTERFACE, 6, 512,0,0) + player.packetDispatch.sendAngleOnInterface(QUIZMASTER_INTERFACE, 7, 512,0,0) + player.packetDispatch.sendAngleOnInterface(QUIZMASTER_INTERFACE, 8, 512,0,0) + + return correctButton + } + + // Random Item should be "Mystery Box", but the current MYSTERY_BOX_6199 is already inauthentically used by Giftmas. + val tableRoll = WeightBasedTable.create( + WeightedItem(Items.LAMP_2528, 1, 1, 1.0, false), + WeightedItem(Items.CABBAGE_1965, 1, 1, 1.0, false), + WeightedItem(Items.DIAMOND_1601, 1, 1, 1.0, false), + WeightedItem(Items.BUCKET_1925, 1, 1, 1.0, false), + WeightedItem(Items.FLIER_956, 1, 1, 1.0, false), + WeightedItem(Items.OLD_BOOT_685, 1, 1, 1.0, false), + WeightedItem(Items.BODY_RUNE_559, 1, 1, 1.0, false), + WeightedItem(Items.ONION_1957, 1, 1, 1.0, false), + WeightedItem(Items.MITHRIL_SCIMITAR_1329, 1, 1, 1.0, false), + WeightedItem(Items.CASKET_405, 1, 1, 1.0, false), + WeightedItem(Items.STEEL_PLATEBODY_1119, 1, 1, 1.0, false), + WeightedItem(Items.NATURE_RUNE_561, 20, 20, 1.0, false), + ) + } + + + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> npc(FacialExpression.FRIENDLY,"WELCOME to the GREATEST QUIZ SHOW in the", "whole of ${ServerConstants.SERVER_NAME}:", "O D D O N E O U T").also { stage++ } + 1 -> player(FacialExpression.THINKING, "I'm sure I didn't ask to take part in a quiz show...").also { stage++ } + 2 -> npc(FacialExpression.FRIENDLY,"Please welcome our newest contestant:", "${player?.username}!", "Just pick the O D D O N E O U T.", "Four questions right, and then you win!").also { stage++ } + 3 -> { + setAttribute(player!!, QUIZMASTER_ATTRIBUTE_RANDOM_ANSWER, randomQuestion(player!!)) + player!!.interfaceManager.openChatbox(QUIZMASTER_INTERFACE) + stage++ + } + 4-> { + if (buttonID == getAttribute(player!!, QUIZMASTER_ATTRIBUTE_RANDOM_ANSWER, 0)) { + // Correct Answer + setAttribute(player!!, QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, getAttribute(player!!, QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, 0) + 1) + if (getAttribute(player!!, QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, 0) >= 4) { + npc(FacialExpression.FRIENDLY,"CONGRATULATIONS!", "You are a WINNER!", "Please choose your PRIZE!") + stage = 5 + } else { + npc(FacialExpression.FRIENDLY,"Wow, you're a smart one!", "You're absolutely RIGHT!", "Okay, next question!") + stage = 3 + } + } else { + // Wrong Answer + npc(FacialExpression.FRIENDLY,"WRONG!", "That's just WRONG!", "Okay, next question!") + stage = 3 + } + } + // Random Item should be "Mystery Box", but the current MYSTERY_BOX_6199 is already inauthentically used by Giftmas. + 5 -> options("1000 Coins", "Random Item").also { stage++ } + 6 -> { + resetAnimator(player!!) + returnPlayer(player!!) + when (buttonID) { + 1 -> { + queueScript(player!!, 0, QueueStrength.SOFT) { stage: Int -> + addItemOrDrop(player!!, Items.COINS_995, 1000) + return@queueScript stopExecuting(player!!) + } + } + 2 -> { + queueScript(player!!, 0, QueueStrength.SOFT) { stage: Int -> + addItemOrDrop(player!!, tableRoll.roll()[0].id) + return@queueScript stopExecuting(player!!) + } + } + } + removeAttributes(player!!, QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, QUIZMASTER_ATTRIBUTE_RANDOM_ANSWER) + stage = END_DIALOGUE + end() + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/quizmaster/QuizMasterNPC.kt b/Server/src/main/content/global/ame/events/quizmaster/QuizMasterNPC.kt new file mode 100644 index 0000000..26407a1 --- /dev/null +++ b/Server/src/main/content/global/ame/events/quizmaster/QuizMasterNPC.kt @@ -0,0 +1,65 @@ +package content.global.ame.events.quizmaster + +import content.global.ame.RandomEventNPC +import content.global.ame.kidnapPlayer +import core.api.* +import core.api.utils.WeightBasedTable +import core.game.interaction.QueueStrength +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.link.TeleportManager +import core.game.system.timer.impl.AntiMacro +import core.game.world.map.Location +import core.game.world.update.flag.context.Graphics +import org.rs09.consts.NPCs +import org.rs09.consts.Sounds + +/** + * Quiz Master NPC: + * + * https://www.youtube.com/watch?v=EFAWSiPTfcM + * https://www.youtube.com/watch?v=caWn7pE2mkE + * https://www.youtube.com/watch?v=Bc1gAov2o4w + * https://www.youtube.com/watch?v=oHU8-MUarxE + * https://www.youtube.com/watch?v=wvjYiF4v9tI + * https://www.youtube.com/watch?v=dC6rlSnXEfw + */ +class QuizMasterNPC(var type: String = "", override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.QUIZ_MASTER_2477) { + override fun init() { + super.init() + sendChat("Hey ${player.username}! It's your lucky day!") + queueScript(player, 4, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + lock(player, 6) + sendGraphics(Graphics(1576, 0, 0), player.location) + animate(player,8939) + playAudio(player, Sounds.TELEPORT_ALL_200) + return@queueScript delayScript(player, 3) + } + 1 -> { + kidnapPlayer(player, Location(1952, 4764, 1), TeleportManager.TeleportType.INSTANT) + setAttribute(player, QuizMasterDialogueFile.QUIZMASTER_ATTRIBUTE_QUESTIONS_CORRECT, 0) + AntiMacro.terminateEventNpc(player) + sendGraphics(Graphics(1577, 0, 0), player.location) + animate(player,8941) + sendMessage(player, "Answer four questions correctly in a row to be teleported back where you came from.") + sendMessage(player, "You will need to relog in if you lose the quiz dialog.") // Inauthentic, but there to notify the player in case. + return@queueScript delayScript(player, 6) + } + 2 -> { + face(player, Location(1952, 4768, 1)) + animate(player,2378) + // This is not needed as when you enter the QuizMasterBorders, it should fire off the dialogue + // openDialogue(player, QuizMasterDialogueFile(), this.asNpc()) + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + + } + } + + override fun talkTo(npc: NPC) { + openDialogue(player, QuizMasterDialogueFile(), this.asNpc()) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/rickturpentine/RickTurpentineBehavior.kt b/Server/src/main/content/global/ame/events/rickturpentine/RickTurpentineBehavior.kt new file mode 100644 index 0000000..dbf6a86 --- /dev/null +++ b/Server/src/main/content/global/ame/events/rickturpentine/RickTurpentineBehavior.kt @@ -0,0 +1,14 @@ +package content.global.ame.events.rickturpentine + +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.tools.RandomFunction +import org.rs09.consts.NPCs + +class RickTurpentineBehavior : NPCBehavior(NPCs.RICK_TURPENTINE_2476) { + override fun beforeAttackFinalized(self: NPC, victim: Entity, state: BattleState) { + state.estimatedHit = RandomFunction.getRandom(3) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/rickturpentine/RickTurpentineDialogue.kt b/Server/src/main/content/global/ame/events/rickturpentine/RickTurpentineDialogue.kt new file mode 100644 index 0000000..0b24b3e --- /dev/null +++ b/Server/src/main/content/global/ame/events/rickturpentine/RickTurpentineDialogue.kt @@ -0,0 +1,19 @@ +package content.global.ame.events.rickturpentine + +import core.api.addItemOrDrop +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.system.timer.impl.AntiMacro + +class RickTurpentineDialogue : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> npcl(FacialExpression.NEUTRAL, "Today is your lucky day, " + (if (player!!.isMale) "sirrah!" else "madam!") + " I am donating to the victims of crime to atone for my past actions!").also { stage++ } + 1 -> { + AntiMacro.rollEventLoot(player!!).forEach { addItemOrDrop(player!!, it.id, it.amount) } + AntiMacro.terminateEventNpc(player!!) + end() + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/rickturpentine/RickTurpentineNPC.kt b/Server/src/main/content/global/ame/events/rickturpentine/RickTurpentineNPC.kt new file mode 100644 index 0000000..ba731de --- /dev/null +++ b/Server/src/main/content/global/ame/events/rickturpentine/RickTurpentineNPC.kt @@ -0,0 +1,31 @@ +package content.global.ame.events.rickturpentine + +import content.global.ame.RandomEventNPC +import core.api.* +import core.api.utils.WeightBasedTable +import core.game.node.entity.npc.NPC +import org.rs09.consts.NPCs + +class RickTurpentineNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.RICK_TURPENTINE_2476) { + private var attackDelay = 0 + + override fun init() { + super.init() + sendChat("Good day to you, " + (if(player.isMale) "milord " else "milady ") + player.username.capitalize() + ".") + } + + override fun tick() { + if (ticksLeft <= 10) { + ticksLeft = 10 + if (attackDelay <= getWorldTicks()) + this.attack(player) + } + super.tick() + } + + override fun talkTo(npc: NPC) { + attackDelay = getWorldTicks() + 10 + this.pulseManager.clear() + openDialogue(player, RickTurpentineDialogue(), this.asNpc()) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/rivertroll/RiverTrollRENPC.kt b/Server/src/main/content/global/ame/events/rivertroll/RiverTrollRENPC.kt new file mode 100644 index 0000000..dff28d7 --- /dev/null +++ b/Server/src/main/content/global/ame/events/rivertroll/RiverTrollRENPC.kt @@ -0,0 +1,30 @@ +package content.global.ame.events.rivertroll + +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import content.global.ame.RandomEventNPC +import core.api.utils.WeightBasedTable + +val ids = (391..396).toList() + +class RiverTrollRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(391){ + override fun talkTo(npc: NPC) {} + override fun init() { + super.init() + val id = idForCombatLevel(ids, player) + this.transform(id) + this.attack(player) + sendChat("Fishies be mine, leave dem fishies!") + this.isRespawn = false + } + override fun finalizeDeath(killer: Entity?) { + super.finalizeDeath(killer) + } + override fun tick() { + if(!player.location.withinDistance(this.location,8)){ + this.terminate() + } + super.tick() + if(!player.viewport.currentPlane.npcs.contains(this)) this.clear() + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/rockgolem/RockGolemRENPC.kt b/Server/src/main/content/global/ame/events/rockgolem/RockGolemRENPC.kt new file mode 100644 index 0000000..eb33996 --- /dev/null +++ b/Server/src/main/content/global/ame/events/rockgolem/RockGolemRENPC.kt @@ -0,0 +1,30 @@ +package content.global.ame.events.rockgolem + +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import content.global.ame.RandomEventNPC +import core.api.utils.WeightBasedTable + +val ids = (413..418).toList() + +class RockGolemRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(413){ + override fun talkTo(npc: NPC) {} + override fun init() { + super.init() + val id = idForCombatLevel(ids, player) + this.transform(id) + this.attack(player) + sendChat("Raarrrgghh! Flee human!") + this.isRespawn = false + } + override fun finalizeDeath(killer: Entity?) { + super.finalizeDeath(killer) + } + override fun tick() { + if(!player.location.withinDistance(this.location,8)){ + this.terminate() + } + super.tick() + if(!player.viewport.currentPlane.npcs.contains(this)) this.clear() + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/sandwichlady/SandwichLadyDialogue.kt b/Server/src/main/content/global/ame/events/sandwichlady/SandwichLadyDialogue.kt new file mode 100644 index 0000000..8374daf --- /dev/null +++ b/Server/src/main/content/global/ame/events/sandwichlady/SandwichLadyDialogue.kt @@ -0,0 +1,42 @@ +package content.global.ame.events.sandwichlady + +import core.cache.def.impl.ItemDefinition +import core.game.component.Component +import core.game.node.entity.combat.ImpactHandler +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import core.game.dialogue.DialogueFile +import core.game.system.timer.impl.AntiMacro +import core.tools.END_DIALOGUE + +class SandwichLadyDialogue(val isChoice: Boolean) : DialogueFile() { + val SANDWICH_INTERFACE = 297 + override fun handle(componentID: Int, buttonID: Int) { + val assigned = player!!.getAttribute("sandwich-lady:item",0) + val choice = player!!.getAttribute("sandwich-lady:choice",0) + if(!isChoice) { + when (stage) { + 0 -> npc("Have a ${ItemDefinition.forId(assigned).name.toLowerCase()}, dear.").also { stage++ } + 1 -> { + end() + player!!.interfaceManager.open(Component(SANDWICH_INTERFACE)) + } + } + } else { + when(stage){ + 0 -> if(choice != assigned){ + npc!!.sendChat("That's not what I said you could have!") + player!!.impactHandler.manualHit(npc,3,ImpactHandler.HitsplatType.NORMAL) + AntiMacro.terminateEventNpc(player!!) + } else { + npc("Here you are, dear. I hope you enjoy it!") + if(!player!!.inventory.add(Item(assigned))){ + GroundItemManager.create(Item(assigned),player) + } + AntiMacro.terminateEventNpc(player!!) + stage = END_DIALOGUE + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/sandwichlady/SandwichLadyInterface.kt b/Server/src/main/content/global/ame/events/sandwichlady/SandwichLadyInterface.kt new file mode 100644 index 0000000..c0d4773 --- /dev/null +++ b/Server/src/main/content/global/ame/events/sandwichlady/SandwichLadyInterface.kt @@ -0,0 +1,44 @@ +package content.global.ame.events.sandwichlady + +import core.game.node.item.Item +import org.rs09.consts.Items +import core.game.interaction.InterfaceListener +import core.game.system.timer.impl.AntiMacro + +class SandwichLadyInterface : InterfaceListener { + + val SANDWICH_INTERFACE = 297 + val baguette = Items.BAGUETTE_6961 + val triangle_sandwich = Items.TRIANGLE_SANDWICH_6962 + val sandwich = Items.SQUARE_SANDWICH_6965 + val roll = Items.ROLL_6963 + val pie = Items.MEAT_PIE_2327 + val kebab = Items.KEBAB_1971 + val chocobar = Items.CHOCOLATE_BAR_1973 + + override fun defineInterfaceListeners() { + on(SANDWICH_INTERFACE){player, _, _, buttonID, _, _ -> + val event = AntiMacro.getEventNpc(player) + if (event == null) { + player.interfaceManager.close() + return@on true + } + val item = + when(buttonID) { + 7 -> {Item(baguette)} + 8 -> {Item(triangle_sandwich)} + 9 -> {Item(sandwich)} + 10 -> {Item(roll)} + 11 -> {Item(pie)} + 12 -> {Item(kebab)} + 13 -> {Item(chocobar)} + else -> {Item(baguette)} + } + + player.setAttribute("sandwich-lady:choice",item.id) + player.interfaceManager.close() + player.dialogueInterpreter.open(SandwichLadyDialogue(true), event) + return@on true + } + } +} diff --git a/Server/src/main/content/global/ame/events/sandwichlady/SandwichLadyRENPC.kt b/Server/src/main/content/global/ame/events/sandwichlady/SandwichLadyRENPC.kt new file mode 100644 index 0000000..1c5a149 --- /dev/null +++ b/Server/src/main/content/global/ame/events/sandwichlady/SandwichLadyRENPC.kt @@ -0,0 +1,36 @@ +package content.global.ame.events.sandwichlady + +import core.game.node.entity.npc.NPC +import core.tools.RandomFunction +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import content.global.ame.RandomEventNPC +import core.api.utils.WeightBasedTable + +class SandwichLadyRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.SANDWICH_LADY_3117) { + val phrases = arrayOf("Hello, @name, can you hear me?","Sandwiches, @name!","Are you ignoring me, @name??","Yoohoo! Sandwiches, @name!","Hello, @name?", "Come get your sandwiches, @name!", "How could you ignore me like this, @name?!", "Do you even want your sandwiches, @name?") + var assigned_item = 0 + val items = arrayOf(Items.BAGUETTE_6961,Items.TRIANGLE_SANDWICH_6962,Items.SQUARE_SANDWICH_6965,Items.ROLL_6963,Items.MEAT_PIE_2327,Items.KEBAB_1971,Items.CHOCOLATE_BAR_1973) + + override fun tick() { + if(RandomFunction.random(1,15) == 5){ + sendChat(phrases.random().replace("@name",player.username.capitalize())) + } + super.tick() + } + + override fun init() { + super.init() + assignItem() + sendChat(phrases.random().replace("@name",player.username.capitalize())) + } + + fun assignItem(){ + assigned_item = items.random() + player.setAttribute("sandwich-lady:item",assigned_item) + } + + override fun talkTo(npc: NPC) { + player.dialogueInterpreter.open(SandwichLadyDialogue(false),npc) + } +} diff --git a/Server/src/main/content/global/ame/events/shade/ShadeRENPC.kt b/Server/src/main/content/global/ame/events/shade/ShadeRENPC.kt new file mode 100644 index 0000000..60a0f57 --- /dev/null +++ b/Server/src/main/content/global/ame/events/shade/ShadeRENPC.kt @@ -0,0 +1,29 @@ +package content.global.ame.events.shade + +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import content.global.ame.RandomEventNPC +import core.api.utils.WeightBasedTable + +class ShadeRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(425){ + val ids = (425..430).toList() + override fun talkTo(npc: NPC) {} + override fun init() { + super.init() + val id = idForCombatLevel(ids, player) + this.transform(id) + this.attack(player) + sendChat("Leave this place!") + this.isRespawn = false + } + override fun finalizeDeath(killer: Entity?) { + super.finalizeDeath(killer) + } + override fun tick() { + if(!player.location.withinDistance(this.location,8)){ + this.terminate() + } + super.tick() + if(!player.viewport.currentPlane.npcs.contains(this)) this.clear() + } +} diff --git a/Server/src/main/content/global/ame/events/strangeplant/StrangePlantBehavior.kt b/Server/src/main/content/global/ame/events/strangeplant/StrangePlantBehavior.kt new file mode 100644 index 0000000..0491e01 --- /dev/null +++ b/Server/src/main/content/global/ame/events/strangeplant/StrangePlantBehavior.kt @@ -0,0 +1,39 @@ +package content.global.ame.events.strangeplant + +import core.api.applyPoison +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import core.game.system.timer.impl.AntiMacro +import core.tools.RandomFunction +import org.rs09.consts.NPCs + +class StrangePlantBehavior() : NPCBehavior(NPCs.STRANGE_PLANT_408) { + override fun canBeAttackedBy(self: NPC, attacker: Entity, style: CombatStyle, shouldSendMessage: Boolean): Boolean { + return !(attacker !is Player || AntiMacro.getEventNpc(attacker.asPlayer()) != self) + } + + override fun beforeAttackFinalized(self: NPC, victim: Entity, state: BattleState) { + state.estimatedHit = RandomFunction.getRandom(3) + if (RandomFunction.roll(10)) + applyPoison(victim, self, 10) + } + + override fun beforeDamageReceived(self: NPC, attacker: Entity, state: BattleState) { + if (state.estimatedHit > 3) + state.estimatedHit = RandomFunction.getRandom(3) + if (state.secondaryHit > 3) + state.secondaryHit = RandomFunction.getRandom(3) + } + + override fun onDeathStarted(self: NPC, killer: Entity) { + AntiMacro.terminateEventNpc(killer.asPlayer()) + } + + override fun getXpMultiplier(self: NPC, attacker: Entity): Double { + return super.getXpMultiplier(self, attacker) / 16.0 + } +} diff --git a/Server/src/main/content/global/ame/events/strangeplant/StrangePlantListener.kt b/Server/src/main/content/global/ame/events/strangeplant/StrangePlantListener.kt new file mode 100644 index 0000000..be182fd --- /dev/null +++ b/Server/src/main/content/global/ame/events/strangeplant/StrangePlantListener.kt @@ -0,0 +1,33 @@ +package content.global.ame.events.strangeplant + +import core.api.addItemOrDrop +import core.api.getAttribute +import core.api.sendMessage +import core.api.setAttribute +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.system.timer.impl.AntiMacro +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class StrangePlantListener : InteractionListener { + override fun defineListeners() { + on(NPCs.STRANGE_PLANT_407, IntType.NPC, "pick") { player, node -> + if (AntiMacro.getEventNpc(player) != node) { + sendMessage(player, "This isn't your strange plant.") + return@on true + } + + if (!getAttribute(node.asNpc(), "fruit-grown", false)) { + sendMessage(player, "The fruit isn't ready to be picked.") + return@on true + } + + if (!getAttribute(node.asNpc(), "fruit-picked", false)) { + setAttribute(node.asNpc(), "fruit-picked", true) + addItemOrDrop(player, Items.STRANGE_FRUIT_464) + } + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/strangeplant/StrangePlantNPC.kt b/Server/src/main/content/global/ame/events/strangeplant/StrangePlantNPC.kt new file mode 100644 index 0000000..a1eca2f --- /dev/null +++ b/Server/src/main/content/global/ame/events/strangeplant/StrangePlantNPC.kt @@ -0,0 +1,85 @@ +package content.global.ame.events.strangeplant + +import content.global.ame.RandomEventNPC +import core.api.* +import core.api.utils.WeightBasedTable +import core.game.interaction.QueueStrength +import core.game.node.entity.npc.NPC +import core.game.world.update.flag.context.Animation +import core.tools.minutesToTicks +import core.tools.secondsToTicks +import org.rs09.consts.NPCs + +class StrangePlantNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.STRANGE_PLANT_407) { + private val strangePlantGrowAnim = Animation(348) + private val strangePlantTransformAnim = Animation(351) + private val strangePlantPickedAnim = Animation(350) + private var fruitPicked = false + private var transformed = false + private var attacking = false + + override fun init() { + spawnLocation = getPathableCardinal(player, player.location) + super.init() + ticksLeft = minutesToTicks(1) + animate(this, strangePlantGrowAnim) + queueScript(this, strangePlantGrowAnim.duration + 2, QueueStrength.SOFT) { + setAttribute(this, "fruit-grown", true) + return@queueScript stopExecuting(this) + } + } + + override fun tick() { + super.tick() + if (getAttribute(this, "fruit-picked", false) && !fruitPicked) { + fruitPicked = true + ticksLeft = secondsToTicks(60) + queueScript(this, 1, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + this.animate(strangePlantPickedAnim) + return@queueScript delayScript(this, strangePlantPickedAnim.duration - 1) + } + 1 -> { + this.isInvisible = true + terminate() + return@queueScript stopExecuting(this) + } + else -> return@queueScript stopExecuting(this) + } + } + } + if (ticksLeft <= secondsToTicks(10)) { + ticksLeft = secondsToTicks(10) + if (!attacking) { + attacking = true + queueScript(this, 1, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + animate(this, strangePlantTransformAnim) + return@queueScript delayScript(this, strangePlantTransformAnim.duration) + } + 1 -> { + this.transform(NPCs.STRANGE_PLANT_408) + this.behavior = StrangePlantBehavior() + this.attack(player) + transformed = true + return@queueScript stopExecuting(this) + } + else -> return@queueScript stopExecuting(this) + } + } + } + if (transformed && !this.inCombat()) + this.attack(player) + } + } + + override fun follow() { + if (transformed) + super.follow() + } + + override fun talkTo(npc: NPC) { + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/surpriseexam/MordautDialogue.kt b/Server/src/main/content/global/ame/events/surpriseexam/MordautDialogue.kt new file mode 100644 index 0000000..d3bd04a --- /dev/null +++ b/Server/src/main/content/global/ame/events/surpriseexam/MordautDialogue.kt @@ -0,0 +1,65 @@ +package content.global.ame.events.surpriseexam + +import core.game.component.Component +import core.game.dialogue.FacialExpression +import core.game.dialogue.DialogueFile +import core.tools.END_DIALOGUE + +class MordautDialogue(val examComplete: Boolean, val questionCorrect: Boolean = false, val fromInterface: Boolean = false) : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + if(examComplete){ + if(player!!.getAttribute(SurpriseExamUtils.SE_DOOR_KEY,-1) == -1){ + SurpriseExamUtils.pickRandomDoor(player!!) + } + val door = player!!.getAttribute(SurpriseExamUtils.SE_DOOR_KEY,-1) + val doortext = when(door){ + 2188 -> "red cross" + 2189 -> "blue star" + 2192 -> "purple circle" + 2193 -> "green square" + else -> "REEEEEEEEEEEEEEEE" + } + + npc("Please exit through the $doortext door.") + stage = END_DIALOGUE + } else if(fromInterface){ + + if(questionCorrect){ + if(player!!.getAttribute(SurpriseExamUtils.SE_KEY_CORRECT,0) == 3){ + player!!.dialogueInterpreter.open(MordautDialogue(true),npc) + } else { + when(stage++){ + 0 -> npc("Excellent work!") + 1 -> npc("Now for another...") + 2 -> { + end() + player!!.interfaceManager.open(Component(SurpriseExamUtils.INTERFACE)) + } + } + } + } else { + when(stage++){ + 0 -> npc("I'm afraid that isn't correct.") + 1 -> npc("Now for another...") + 2 -> { + end() + player!!.interfaceManager.open(Component(SurpriseExamUtils.INTERFACE)) + } + } + } + + } else { + when(stage++){ + 0 -> npc("Please answer these questions for me.") + 1 -> { + end() + player!!.interfaceManager.open(Component(SurpriseExamUtils.INTERFACE)) + } + } + } + } + + override fun npc(vararg messages: String?): Component? { + return super.npc(FacialExpression.OLD_NORMAL,*messages) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/surpriseexam/MysteriousOldManDialogue.kt b/Server/src/main/content/global/ame/events/surpriseexam/MysteriousOldManDialogue.kt new file mode 100644 index 0000000..1415317 --- /dev/null +++ b/Server/src/main/content/global/ame/events/surpriseexam/MysteriousOldManDialogue.kt @@ -0,0 +1,41 @@ +package content.global.ame.events + +import core.game.node.entity.player.Player +import content.global.ame.events.surpriseexam.SurpriseExamUtils +import core.game.dialogue.DialogueFile +import core.game.system.timer.impl.AntiMacro + +class MysteriousOldManDialogue(val type: String) : DialogueFile() { + + val CHOICE_STAGE = 50000 + + override fun handle(componentID: Int, buttonID: Int) { + + if(type == "sexam" && stage < CHOICE_STAGE){ + npc("Would you like to come do a surprise exam?") + stage = CHOICE_STAGE + } + + else if(stage >= CHOICE_STAGE){ + when(stage) { + CHOICE_STAGE -> options("Yeah, sure!", "No, thanks.").also { stage++ } + CHOICE_STAGE.substage(1) -> when(buttonID){ + 1 -> { + end() + teleport(player!!,type) + AntiMacro.terminateEventNpc(player!!) + } + 2 -> { + end() + AntiMacro.terminateEventNpc(player!!) + } + } + } + } + } + fun teleport(player: Player,type: String){ + when(type){ + "sexam" -> SurpriseExamUtils.teleport(player) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/surpriseexam/MysteriousOldManNPC.kt b/Server/src/main/content/global/ame/events/surpriseexam/MysteriousOldManNPC.kt new file mode 100644 index 0000000..3ed7289 --- /dev/null +++ b/Server/src/main/content/global/ame/events/surpriseexam/MysteriousOldManNPC.kt @@ -0,0 +1,31 @@ +package content.global.ame.events + +import content.global.ame.RandomEventNPC +import core.game.node.entity.npc.NPC +import core.tools.RandomFunction +import org.rs09.consts.NPCs +import core.api.utils.WeightBasedTable + +class MysteriousOldManNPC(var type: String = "", override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.MYSTERIOUS_OLD_MAN_410) { + override fun init() { + super.init() + sayLine() + } + + override fun tick() { + super.tick() + if(RandomFunction.random(1,10) == 5) sayLine() + } + + fun sayLine() { + when(type){ + "sexam" -> sendChat("Surprise exam, ${player.username.capitalize()}!") + } + } + + override fun talkTo(npc: NPC) { + when(type){ + "sexam" -> player.dialogueInterpreter.open(MysteriousOldManDialogue("sexam"),this.asNpc()) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/surpriseexam/SEDoorDialogue.kt b/Server/src/main/content/global/ame/events/surpriseexam/SEDoorDialogue.kt new file mode 100644 index 0000000..221f4b4 --- /dev/null +++ b/Server/src/main/content/global/ame/events/surpriseexam/SEDoorDialogue.kt @@ -0,0 +1,16 @@ +package content.global.ame.events.surpriseexam + +import core.game.dialogue.DialogueFile +import core.tools.END_DIALOGUE + +class SEDoorDialogue(val preExam: Boolean) : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + stage = if(preExam){ + dialogue("I should probably speak with Mr. Mordaut first.") + END_DIALOGUE + } else { + dialogue("The door won't budge. Perhaps I should","ask for directions.") + END_DIALOGUE + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/surpriseexam/SEPatternInterface.kt b/Server/src/main/content/global/ame/events/surpriseexam/SEPatternInterface.kt new file mode 100644 index 0000000..3ba12a8 --- /dev/null +++ b/Server/src/main/content/global/ame/events/surpriseexam/SEPatternInterface.kt @@ -0,0 +1,36 @@ +package content.global.ame.events.surpriseexam + +import core.game.node.entity.npc.NPC +import org.rs09.consts.Components +import org.rs09.consts.NPCs +import core.game.interaction.InterfaceListener + +class SEPatternInterface : InterfaceListener { + + val COMPONENT = Components.PATTERN_NEXT_103 + + override fun defineInterfaceListeners() { + + on(COMPONENT){player, component, opcode, buttonID, slot, itemID -> + val index = buttonID - 10 + val correctIndex = player.getAttribute(SurpriseExamUtils.SE_KEY_INDEX,0) + player.interfaceManager.close() + + if(index == correctIndex){ + player.incrementAttribute(SurpriseExamUtils.SE_KEY_CORRECT) + val done = player.getAttribute(SurpriseExamUtils.SE_KEY_CORRECT,0) == 3 + player.dialogueInterpreter.open(MordautDialogue(examComplete = done,questionCorrect = true,fromInterface = true), NPC(NPCs.MR_MORDAUT_6117)) + } else { + player.dialogueInterpreter.open(MordautDialogue(examComplete = false,questionCorrect = false,fromInterface = true),NPC(NPCs.MR_MORDAUT_6117)) + } + return@on true + } + + onOpen(COMPONENT){player, component -> + SurpriseExamUtils.generateInterface(player) + return@onOpen true + } + + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/surpriseexam/SupriseExamListeners.kt b/Server/src/main/content/global/ame/events/surpriseexam/SupriseExamListeners.kt new file mode 100644 index 0000000..6d8ad6b --- /dev/null +++ b/Server/src/main/content/global/ame/events/surpriseexam/SupriseExamListeners.kt @@ -0,0 +1,71 @@ +package content.global.ame.events.surpriseexam + +import core.game.component.Component +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.world.map.Location +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import content.global.handlers.iface.ExperienceInterface +import core.api.MapArea +import core.api.removeItem +import core.game.world.map.zone.ZoneBorders +import core.game.world.map.zone.ZoneRestriction + +class SupriseExamListeners : InteractionListener, MapArea { + override fun defineListeners() { + + on(NPCs.MR_MORDAUT_6117, IntType.NPC, "talk-to") { player, node -> + player.faceLocation(Location.create(1886, 5024, 0)) + val examComplete = player.getAttribute(SurpriseExamUtils.SE_KEY_CORRECT, 0) == 3 + player.dialogueInterpreter.open(MordautDialogue(examComplete), node.asNpc()) + return@on true + } + + on(SurpriseExamUtils.SE_DOORS, IntType.SCENERY, "open") { player, node -> + val correctDoor = player.getAttribute(SurpriseExamUtils.SE_DOOR_KEY,-1) + + if(correctDoor == -1){ + player.dialogueInterpreter.open(SEDoorDialogue(true)) + return@on true + } + + if(node.id == correctDoor){ + SurpriseExamUtils.cleanup(player) + return@on true + } + + player.dialogueInterpreter.open(SEDoorDialogue(false)) + return@on true + } + + on(Items.BOOK_OF_KNOWLEDGE_11640, IntType.ITEM, "read") { player, _ -> + player.setAttribute("caller") { skill: Int, p: Player -> + if (removeItem(p, Items.BOOK_OF_KNOWLEDGE_11640)) { + val level = p.skills.getStaticLevel(skill) + val experience = level * 15.0 + p.skills.addExperience(skill, experience) + } + } + player.interfaceManager.open(Component(ExperienceInterface.COMPONENT_ID)) + return@on true + } + + } + + override fun defineDestinationOverrides() { + setDest(IntType.NPC, NPCs.MR_MORDAUT_6117) { _, _ -> + return@setDest Location.create(1886, 5025, 0) + } + } + + override fun defineAreaBorders(): Array { + return arrayOf(ZoneBorders.forRegion(7502)) + } + + override fun getRestrictions(): Array { + return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS, ZoneRestriction.OFF_MAP) + } +} diff --git a/Server/src/main/content/global/ame/events/surpriseexam/SurpriseExamUtils.kt b/Server/src/main/content/global/ame/events/surpriseexam/SurpriseExamUtils.kt new file mode 100644 index 0000000..01a7223 --- /dev/null +++ b/Server/src/main/content/global/ame/events/surpriseexam/SurpriseExamUtils.kt @@ -0,0 +1,70 @@ +package content.global.ame.events.surpriseexam + +import content.global.ame.kidnapPlayer +import content.global.ame.returnPlayer +import core.api.* +import core.game.node.entity.impl.PulseType +import core.game.node.entity.player.Player +import core.game.system.task.Pulse +import core.game.world.map.Location +import org.rs09.consts.Components +import org.rs09.consts.Items +import core.game.node.entity.player.link.TeleportManager + +object SurpriseExamUtils { + val SE_KEY_INDEX = "supexam:index" + val SE_DOOR_KEY = "supexam:door" + val INTER_PATTERN_CHILDS = intArrayOf(6,7,8) + val INTER_OPTION_CHILDS = intArrayOf(10,11,12,13) + val SE_DOORS = intArrayOf(2188,2189,2192,2193) + val INTERFACE = Components.PATTERN_NEXT_103 + val SE_KEY_CORRECT = "supexam:correct" + val sets = arrayOf( + intArrayOf(Items.GARDENING_TROWEL_5325,Items.SECATEURS_5329,Items.SEED_DIBBER_5343,Items.RAKE_5341), + intArrayOf(Items.SALMON_329,Items.SHARK_385,Items.TROUT_333,Items.SHRIMPS_315), + intArrayOf(Items.BRONZE_SWORD_1277,Items.WOODEN_SHIELD_1171,Items.BRONZE_MED_HELM_1139,Items.ADAMANT_BATTLEAXE_1371), + intArrayOf(Items.FLY_FISHING_ROD_309,Items.BARBARIAN_ROD_11323,Items.SMALL_FISHING_NET_303,Items.HARPOON_311) + ) + + fun teleport(player: Player) { + kidnapPlayer(player, Location.create(1886, 5025, 0), TeleportManager.TeleportType.INSTANT) + } + + fun cleanup(player: Player){ + returnPlayer(player) + removeAttributes(player, SE_KEY_INDEX, SE_KEY_CORRECT) + player.pulseManager.run(object : Pulse(2){ + override fun pulse(): Boolean { + addItemOrDrop(player, Items.BOOK_OF_KNOWLEDGE_11640) + return true + } + }, PulseType.CUSTOM_1) + } + + fun generateInterface(player: Player){ + val set = sets.random() + val setIndex = sets.indexOf(set) + + val tempList = set.toList().shuffled().toMutableList() + val correctOpt = tempList.random() + val optIndex = tempList.indexOf(correctOpt) + + tempList.remove(correctOpt) + for(i in INTER_PATTERN_CHILDS.indices) player.packetDispatch.sendItemOnInterface(tempList[i],1, INTERFACE, INTER_PATTERN_CHILDS[i]) + for(i in INTER_OPTION_CHILDS.indices){ + if(i == optIndex) player.packetDispatch.sendItemOnInterface(correctOpt,1, INTERFACE, INTER_OPTION_CHILDS[i]) + else player.packetDispatch.sendItemOnInterface(getFalseSet(setIndex)[i],1, INTERFACE, INTER_OPTION_CHILDS[i]) + } + player.setAttribute(SE_KEY_INDEX,optIndex) + } + + fun getFalseSet(trueSetIndex: Int): IntArray{ + val tempSets = sets.toMutableList() + tempSets.removeAt(trueSetIndex) + return tempSets.random() + } + + fun pickRandomDoor(player: Player){ + player.setAttribute(SE_DOOR_KEY, SE_DOORS.random()) + } +} diff --git a/Server/src/main/content/global/ame/events/swarm/SwarmNPC.kt b/Server/src/main/content/global/ame/events/swarm/SwarmNPC.kt new file mode 100644 index 0000000..30b2981 --- /dev/null +++ b/Server/src/main/content/global/ame/events/swarm/SwarmNPC.kt @@ -0,0 +1,28 @@ +package content.global.ame.events.swarm + +import content.global.ame.RandomEventNPC +import core.api.playGlobalAudio +import core.api.utils.WeightBasedTable +import core.game.node.entity.npc.NPC +import core.tools.minutesToTicks +import org.rs09.consts.NPCs +import org.rs09.consts.Sounds + +class SwarmNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(NPCs.SWARM_411) { + override fun init() { + super.init() + this.setAttribute("no-spawn-return", true) + this.attack(player) + playGlobalAudio(this.location, Sounds.SWARM_APPEAR_818) + this.ticksLeft = minutesToTicks(60) + } + + override fun tick() { + super.tick() + if (!this.inCombat()) + this.attack(player) + } + + override fun talkTo(npc: NPC) { + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/swarm/SwarmNPCBehavior.kt b/Server/src/main/content/global/ame/events/swarm/SwarmNPCBehavior.kt new file mode 100644 index 0000000..3cf3907 --- /dev/null +++ b/Server/src/main/content/global/ame/events/swarm/SwarmNPCBehavior.kt @@ -0,0 +1,14 @@ +package content.global.ame.events.swarm + +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.tools.RandomFunction +import org.rs09.consts.NPCs + +class SwarmNPCBehavior : NPCBehavior(NPCs.SWARM_411) { + override fun beforeAttackFinalized(self: NPC, victim: Entity, state: BattleState) { + state.estimatedHit = RandomFunction.getRandom(1) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/treespirit/TreeSpiritRENPC.kt b/Server/src/main/content/global/ame/events/treespirit/TreeSpiritRENPC.kt new file mode 100644 index 0000000..3b00339 --- /dev/null +++ b/Server/src/main/content/global/ame/events/treespirit/TreeSpiritRENPC.kt @@ -0,0 +1,30 @@ +package content.global.ame.events.treespirit + +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import content.global.ame.RandomEventNPC +import core.api.utils.WeightBasedTable + +val ids = (438..443).toList() + +class TreeSpiritRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(438){ + override fun talkTo(npc: NPC) {} + override fun init() { + super.init() + val id = idForCombatLevel(ids, player) + this.transform(id) + this.attack(player) + sendChat("Leave these woods and never return!") + this.isRespawn = false + } + override fun finalizeDeath(killer: Entity?) { + super.finalizeDeath(killer) + } + override fun tick() { + if(!player.location.withinDistance(this.location,8)){ + this.terminate() + } + super.tick() + if(!player.viewport.currentPlane.npcs.contains(this)) this.clear() + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/ame/events/zombie/ZombieRENPC.kt b/Server/src/main/content/global/ame/events/zombie/ZombieRENPC.kt new file mode 100644 index 0000000..6b43d54 --- /dev/null +++ b/Server/src/main/content/global/ame/events/zombie/ZombieRENPC.kt @@ -0,0 +1,29 @@ +package content.global.ame.events.zombie + +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import content.global.ame.RandomEventNPC +import core.api.utils.WeightBasedTable + +class ZombieRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(419){ + val ids = (419..424).toList() + override fun talkTo(npc: NPC) {} + override fun init() { + super.init() + val id = idForCombatLevel(ids, player) + this.transform(id) + this.attack(player) + sendChat("Brainsssss!") + this.isRespawn = false + } + override fun finalizeDeath(killer: Entity?) { + super.finalizeDeath(killer) + } + override fun tick() { + if(!player.location.withinDistance(this.location,8)){ + this.terminate() + } + super.tick() + if(!player.viewport.currentPlane.npcs.contains(this)) this.clear() + } +} diff --git a/Server/src/main/content/global/bots/Adventurer.kt b/Server/src/main/content/global/bots/Adventurer.kt new file mode 100644 index 0000000..9165039 --- /dev/null +++ b/Server/src/main/content/global/bots/Adventurer.kt @@ -0,0 +1,724 @@ +package content.global.bots + +import core.game.interaction.DestinationFlag +import core.game.interaction.MovementPulse +import core.game.node.scenery.Scenery +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.game.world.GameWorld +import core.game.world.map.Location +import core.game.world.map.RegionManager +import core.game.world.map.zone.ZoneBorders +import core.game.world.update.flag.* +import org.json.simple.JSONArray +import org.json.simple.JSONObject +import core.ServerConstants +import core.api.log +import core.game.bots.AIRepository +import core.game.bots.CombatBotAssembler +import core.game.bots.Script +import core.game.interaction.IntType +import core.game.interaction.InteractionListeners +import core.tools.Log +import java.io.File +import java.io.FileReader +import java.time.LocalDateTime +import java.time.format.DateTimeFormatter +import kotlin.random.Random + + +/** + * A bot script for Adventurers who explore the world! + * @param counter used in the bots random idling function. + * @param random is used to generate random number. + * @param city determines the home city of the bot. + * @param freshspawn determines if the bot has just been spawned. + * @param random_city is the list of cities that can be randomly chosen as the home city. + * @param tree_list is the list of trees that a bot can start cutting randomly. + * @author Sir Kermit + * @author Ceikry + */ + +// Adventure Bots v1.1.0 : Expansion Edition (Previously v4.0.0) +// Super Grand Exchange Update +class Adventurer(val style: CombatStyle): Script() { + + var city: Location = lumbridge + var poiloc: Location = karamja + var geSocialLoc: Location = getRandomGESocialLocation() + var geClerkLoc: Location = getRandomGELocation() + var geClerksloc: Location = neGEClerk + + var freshspawn: Boolean = true + var sold: Boolean = false + var poi: Boolean = false + + val chance: Int = if (cityLocationsGE.contains(city)) 3500 else 3000 + var ticks: Int = 0 + var counter: Int = 0 + val waitTotal: Int = 8 + var returnToAdventure: Int = 0 + var geWait: Int = 0 + var geLongWait: Int = 0 + + val type = when(style){ + CombatStyle.MELEE -> CombatBotAssembler.Type.MELEE + CombatStyle.MAGIC -> CombatBotAssembler.Type.MAGE + CombatStyle.RANGE -> CombatBotAssembler.Type.RANGE + } + + init { + skills[Skills.AGILITY] = 99 + inventory.add(Item(1359))//Rune Axe + skills[Skills.WOODCUTTING] = 95 + inventory.add(Item(590))//Tinderbox + skills[Skills.FISHING] = 90 + inventory.add(Item(1271))//Addy Pickaxe + skills[Skills.MINING] = 90 + skills[Skills.SLAYER] = 90 + } + + override fun toString(): String { + return "${bot.username} is an Adventurer bot " + + "at ${bot.location}! " + + "State: $state - " + + "City: $city - " + + "Ticks: $ticks - " + + "Freshspawn: $freshspawn - " + + "Sold: $sold - " + + "Counter: $counter" + } + + var state = State.START + + private fun getRandomCity(): Location{ + return cities.random() + } + + private fun getRandomPoi(): Location{ + return pois.random() + } + + private fun getRandomGESocialLocation(): Location{ + return socialLocationsGE.random() + } + + private fun getRandomGELocation(): Location { + return cityLocationsGE.random() + } + + private fun randomNumberFromOne(maxInt: Int): Int { + return Random.nextInt(0, maxInt) + } + + private fun otherPlayersNearby(): Boolean { + val localPlayers = RegionManager.getLocalPlayers(bot) + val otherPlayers = localPlayers.filter { it.name != bot.name } + return otherPlayers.isNotEmpty() + } + + private fun checkNearBank() { + if(bankMap[city] == null){ + scriptAPI.teleport(getRandomCity().also { city = it }) + } else { + if(bankMap[city]?.insideBorder(bot) == true){ + state = State.FIND_BANK + } else { + bankMap[city]?.let { scriptAPI.walkTo(it.randomLoc) } + } + } + } + + private fun checkCounter(maxCounter: Int) { + if (counter++ >= maxCounter) { + state = State.TELEPORTING + } + } + + private fun teleportToRandomCity() { + city = getRandomCity() + when (city) { + neGEClerk -> { scriptAPI.teleport(scriptAPI.randomizeLocationInRanges(city,-3,2,0,1,0)) } + swGEClerk -> { scriptAPI.teleport(scriptAPI.randomizeLocationInRanges(city,-2,3,-1,0,0)) } + nwGEBanker -> { scriptAPI.teleport(scriptAPI.randomizeLocationInRanges(city,-2,0,-3,2,0)) } + seGEBanker -> { scriptAPI.teleport(scriptAPI.randomizeLocationInRanges(city,0,2,-2,3,0)) } + else -> { scriptAPI.teleport(scriptAPI.randomizeLocationInRanges(city,-1,1,-1,1,0)) } + } + } + + val resources = listOf( + "Rocks","Tree","Oak","Willow", + "Maple tree","Yew","Magic tree", + "Teak","Mahogany") + + //TODO: Optimise and adjust how bots handle picking up ground items further. + fun immerse() { + if (counter++ >= Random.nextInt(150,300)) { state = State.TELEPORTING } + val items = AIRepository.groundItems[bot] + if (Random.nextBoolean()) { + if (items.isNullOrEmpty()) { + scriptAPI.attackNpcsInRadius(bot, 8) + state = State.LOOT_DELAY + } + if (bot.inventory.isFull) { + checkNearBank() + } + + } else { + if (bot.inventory.isFull){ + checkNearBank() + } else { + val resource = scriptAPI.getNearestNodeFromList(resources,true) + if(resource != null){ + if(resource.name.contains("ocks")) InteractionListeners.run(resource.id, + IntType.SCENERY,"mine",bot,resource) + else InteractionListeners.run(resource.id, IntType.SCENERY,"chop down",bot,resource) + } + } + } + return + } + + fun refresh() { +// log(this::class.java, Log.WARN, "${bot.username} refreshed from $state at $city with $ticks and $counter counter.") + scriptAPI.teleport(lumbridge) + state = State.START + } + + //Adventure Bots Actual Code STARTS HERE!!! + // 100 ticks = 60 seconds + override fun tick() { + ticks++ + // Hard refresh + if (ticks >= 1000) { + ticks = 0 + refresh() + return + } + + // zoneborder checker + if(ticks % 30 == 0){ + for((zone, resolution) in common_stuck_locations){ + if(zone.insideBorder(bot)){ + resolution(this) + return + } + } + } + + when(state){ + + State.LOOT_DELAY -> { + bot.pulseManager.run(object : Pulse() { + var counter1 = 0 + override fun pulse(): Boolean { + when (counter1++) { + 7 -> return true.also { state = State.LOOT } + } + return false + } + }) + } + + State.LOOT -> { + val items = AIRepository.groundItems[bot] + if (items?.isNotEmpty() == true && !bot.inventory.isFull) { + items.toTypedArray().forEach { + scriptAPI.takeNearestGroundItem(it.id) + } + return + } else { + state = State.ADVENTURE + } + } + + State.START -> { + if (freshspawn) { + freshspawn = false + scriptAPI.randomWalkTo(lumbridge, randomNumberFromOne(25)) + } else { + state = State.TELEPORTING + } + } + + State.TELEPORTING -> { + if (freshspawn){ freshspawn = false } + teleportToRandomCity() + poi = false + sold = false + ticks = 0 + counter = 0 + state = State.ADVENTURE + return + } + + State.ADVENTURE -> { + checkCounter(800) + if (randomNumberFromOne(chance) <= 10) { + if (otherPlayersNearby()) { + ticks = 0 + dialogue() + } + } + + if (!poi && randomNumberFromOne(1000) <= 75) { + val roamDistance = if (!cityLocationsGE.contains(city)) 225 else randomNumberFromOne(5) + if (cityLocationsGE.contains(city) && randomNumberFromOne(100) < 90) { + if (!bot.bank.isEmpty) { + state = State.FIND_GE + } + return + } + scriptAPI.randomWalkTo(city, roamDistance) + return + } + + if (poi && randomNumberFromOne(1000) <= 100){ + immerse() + return + } + + if (poi && randomNumberFromOne(1000) <= 25){ + dialogue() + } + + if (poi && randomNumberFromOne(1000) <= 50){ + val roamDistancePoi = when(poiloc){ + gemrocks, chaosnpc, chaosnpc2 -> 1 + magics, coalTrucks -> 7 + miningguild, teakfarm, crawlinghands -> 5 + varLumberYard -> 20 + keldagrimout, teak1 -> 30 + eaglespeek, isafdar -> 40 + treegnome -> 50 + else -> 60 + } + scriptAPI.randomWalkTo(poiloc,roamDistancePoi) + return + } + + if (randomNumberFromOne(1000) <= 75) { + if (!cityLocationsGE.contains(city)) { + ticks = 0 + immerse() + return + } else if (randomNumberFromOne(chance) <= 55 && otherPlayersNearby()) { + ticks = 0 + dialogue() + } + } + + if (cityLocationsGE.contains(city) && randomNumberFromOne(1000) <= 50) { + state = State.IDLE_GE + } + + if (!poi && randomNumberFromOne(1000) <= 5) { + poiloc = getRandomPoi() + city = teak1 + poi = true + scriptAPI.teleport(poiloc) + return + } + + if (cityLocationsGE.contains(city) && randomNumberFromOne(1000) <= 100) { + state = State.TELEPORTING + return + } + + if (cityLocationsGE.contains(city)) { + return + } + + if (poi && randomNumberFromOne(1000) <= 20){ + state = State.TELEPORTING + return + } + + if (counter++ >= 750 && randomNumberFromOne(100) <= 50) { +// log(this::class.java, Log.FINE, "${bot.username} has moved on to a different city at $ticks ticks and $counter counter.") + city = getRandomCity() + if (randomNumberFromOne(100) % 2 == 0) { + state = State.TELEPORTING + } else { + if (citygroupA.contains(city)) { + city = citygroupA.random() + } else { + city = citygroupB.random() + } + counter = 0 + ticks = 0 + state = State.FIND_CITY + } + counter = 0 + return + } + return + } + + State.IDLE_GE -> { + returnToAdventure = Random.nextInt(350, 750) + if (counter++ >= returnToAdventure){ + if (randomNumberFromOne(100) <= 25){ + ticks = 0 + counter = 0 + poiloc = getRandomPoi() + city = teak1 + poi = true + scriptAPI.teleport(poiloc) + state = State.ADVENTURE + return + } else { + counter = 0 + ticks = 0 + state = State.TELEPORTING + return + } + } + if (cityLocationsGE.contains(city)){ + if (randomNumberFromOne(1000) <= 5) { + ticks = 0 + geSocialLoc = scriptAPI.randomizeLocationInRanges(getRandomGESocialLocation(),-1,1,-1,1,0) + } else if (randomNumberFromOne(1000) <= 10) { + ticks = 0 + scriptAPI.randomWalkTo(geSocialLoc, randomNumberFromOne(5)) + return + } + if (randomNumberFromOne(1000) <= 5 && otherPlayersNearby()){ + ticks = 0 + dialogue() + } else if (randomNumberFromOne(1000) <= 250){ + return + } + } + return + } + + State.FIND_GE -> { + sold = false + val ge: Scenery? = scriptAPI.getNearestNode("Desk", true) as Scenery? + if (ge == null || bot.bank.isEmpty) state = State.ADVENTURE + class GEPulse : MovementPulse(bot, ge, DestinationFlag.OBJECT) { + override fun pulse(): Boolean { + bot.faceLocation(ge?.location) + return true.also { state = State.GE } + } + } + if (ge == null || bot.bank.isEmpty) state = State.ADVENTURE + if (ge != null && !bot.bank.isEmpty) { + if (randomNumberFromOne(1000) <= 25 && otherPlayersNearby()){ + dialogue() + scriptAPI.randomWalkTo(geSocialLoc, randomNumberFromOne(5)) + } else if (randomNumberFromOne(500) <= 50) { + GameWorld.Pulser.submit(GEPulse()) + } + } + checkCounter(500) + return + } + + State.GE -> { + geClerksloc = clerkLocationsGe.random() + geWait = Random.nextInt(35, 100) + geLongWait = Random.nextInt(350, 750) + if (!sold) { + if (randomNumberFromOne(500) <= 25){ scriptAPI.randomWalkTo(geClerksloc, randomNumberFromOne(4))} + if (counter++ >= geWait) { + scriptAPI.randomWalkTo(geClerksloc, randomNumberFromOne(1)) + sold = true + counter = 0 + ticks = 0 + scriptAPI.sellAllOnGeAdv() + state = State.TELEPORTING + return + } + } else if (counter++ >= geLongWait) { + state = State.TELEPORTING + return + } + checkCounter(1000) + return + } + + State.FIND_BANK -> { + val bank: Scenery? = scriptAPI.getNearestNode("Bank booth", true) as Scenery? + if (bank == null) { state = State.TELEPORTING } + if (bank != null && randomNumberFromOne(100) <= 5) { + scriptAPI.depositAtBank() + } else if (bank != null && randomNumberFromOne(100) <= 5){ + scriptAPI.randomWalkTo(bank.location,3) + } + checkCounter(500) + return + } + + + State.FIND_CITY -> { + if (counter++ >= 500 || cityLocationsGE.contains(city)){ + scriptAPI.teleport(getRandomCity().also { city = it }) + state = State.ADVENTURE + } + if (bot.location.equals(city)) { + state = State.ADVENTURE + } else { + scriptAPI.randomWalkTo(city, randomNumberFromOne(10)) + } + checkCounter(600) + return + } + + } + + } + + fun dialogue() { + val until = 1225 - dateCode + val lineStd = dialogue.getLines("standard").rand() + var lineAlt = "" + + when { + //Celebrates Halloween! + dateCode == 1031 -> lineAlt = dialogue.getLines("halloween").rand() + + //Celebrates lead up to Christmas! + until in 2..23 -> lineAlt = dialogue.getLines("approaching_christmas").rand() + + //Celebrates Christmas Day! + dateCode == 1225 -> lineAlt = dialogue.getLines("christmas_day").rand() + + //Celebrates Christmas Eve + dateCode == 1224 -> lineAlt = dialogue.getLines("christmas_eve").rand() + + //New years eve + dateCode == 1231 -> lineAlt = dialogue.getLines("new_years_eve").rand() + + //New years + dateCode == 101 -> lineAlt = dialogue.getLines("new_years").rand() + + //Valentines + dateCode == 214 -> lineAlt = dialogue.getLines("valentines").rand() + + //Easter + dateCode == 404 -> lineAlt = dialogue.getLines("easter").rand() + } + + var localPlayers = RegionManager.getLocalPlayers(bot) + if (localPlayers.isNotEmpty()) { + val localPlayer = localPlayers + .filter { it.name != bot.name } + .randomOrNull() + if (localPlayer != null) { + val chat = if (lineAlt.isNotEmpty() && Random.nextBoolean()) { lineAlt } else { lineStd } + .replace("@name", localPlayer.username) + .replace("@timer", until.toString()) + scriptAPI.sendChat(chat) + } else { + val chat = if (lineAlt.isNotEmpty() && Random.nextBoolean()) { lineAlt } else { lineStd } + scriptAPI.sendChat(chat) + } + } + } + + enum class State{ + START, + ADVENTURE, + FIND_BANK, + FIND_CITY, + IDLE_GE, + GE, + TELEPORTING, + LOOT, + LOOT_DELAY, + FIND_GE + } + + + override fun newInstance(): Script { + val script = Adventurer(style) + script.state = State.START + val tier = CombatBotAssembler.Tier.MED + if (type == CombatBotAssembler.Type.RANGE) + script.bot = CombatBotAssembler().RangeAdventurer(tier, bot.startLocation) + else + script.bot = CombatBotAssembler().MeleeAdventurer(tier, bot.startLocation) + return script + } + + companion object { + // Start Cities + val yanille: Location = Location.create(2615, 3104, 0) + val ardougne: Location = Location.create(2662, 3304, 0) + val seers: Location = Location.create(2726, 3485, 0) + val edgeville: Location = Location.create(3088, 3486, 0) + val catherby: Location = Location.create(2809, 3435, 0) + val falador: Location = Location.create(2965, 3380, 0) + val varrock: Location = Location.create(3213, 3428, 0) + val draynor: Location = Location.create(3080, 3250, 0) + val rimmington: Location = Location.create(2977, 3239, 0) + val lumbridge: Location = Location.create(3222, 3219, 0) + val karamja: Location = Location.create(2849, 3033, 0) + val alkharid: Location = Location.create(3297, 3219, 0) + + // Start POI + val feldiphills: Location = Location.create(2535, 2919, 0) + val isafdar: Location = Location.create(2241, 3217, 0) + val eaglespeek: Location = Location.create(2333, 3579, 0) + val canafis: Location = Location.create(3492, 3485, 0) + val treegnome: Location = Location.create(2437, 3441, 0) + val teak1: Location = Location.create(2334, 3048, 0) + val teakfarm: Location = Location.create(2825, 3085, 0) + val keldagrimout: Location = Location.create(2724,3692, 0) + val miningguild: Location = Location.create(3046,9740, 0) + val magics: Location = Location.create(2285,3146, 0) + val coalTrucks: Location = Location.create(2581,3481, 0) + val crawlinghands: Location = Location.create(3422,3548, 0) + val gemrocks: Location = Location.create(2825,2997, 0) + val chaosnpc: Location = Location.create(2612,9484, 0) + val chaosnpc2: Location = Location.create(2586, 9501, 0) + val varLumberYard: Location = Location.create(3289, 3482, 0) + val taverly: Location = Location.create(2909, 3436, 0) + + val swGEClerk: Location = Location.create(3164, 3487, 0) + val neGEClerk: Location = Location.create(3165, 3492, 0) + val nwGEBanker: Location = Location.create(3162, 3490, 0) + val seGEBanker: Location = Location.create(3167, 3489, 0) + + val badedge = ZoneBorders(3094, 3494, 3096, 3497) + val badedge2: Location = Location.create(3094, 3492, 0) + val badedge3: Location = Location.create(3094, 3490, 0) + val badedge4: Location = Location.create(3094, 3494, 0) + + var citygroupA = listOf(falador, varrock, draynor, rimmington, lumbridge, edgeville) + var citygroupB = listOf(yanille, ardougne, seers, catherby) + + val cities = listOf( + swGEClerk, neGEClerk, nwGEBanker, seGEBanker, + yanille, ardougne, seers, catherby, + falador, varrock, draynor, rimmington, + lumbridge, edgeville + ) + + val pois = listOf( + karamja, karamja, alkharid, + alkharid, feldiphills, feldiphills, + isafdar, eaglespeek, eaglespeek, + canafis, treegnome, treegnome, + teak1, teakfarm, keldagrimout, + miningguild, coalTrucks, crawlinghands, + magics, gemrocks, chaosnpc, chaosnpc, + chaosnpc2, taverly, + varLumberYard) + + val cityLocationsGE = listOf(swGEClerk, neGEClerk, nwGEBanker, seGEBanker) + + val socialLocationsGE = listOf( + Location.create(3158, 3483, 0), + Location.create(3165, 3480, 0), + Location.create(3172, 3483, 0), + Location.create(3174, 3489, 0), + Location.create(3171, 3497, 0), + Location.create(3164, 3499, 0), + Location.create(3157, 3497, 0), + Location.create(3155, 3489, 0), + Location.create(3167, 3492, 0), + Location.create(3162, 3492, 0), + Location.create(3162, 3487, 0), + Location.create(3167, 3487, 0) + ) + + val clerkLocationsGe = listOf( + Location.create(3165, 3492, 0), + Location.create(3164, 3492, 0), + Location.create(3164, 3487, 0), + Location.create(3165, 3487, 0) + ) + + var bankMap = mapOf( + falador to ZoneBorders(2950, 3374, 2943, 3368), + varrock to ZoneBorders(3182, 3435, 3189, 3446), + draynor to ZoneBorders(3092, 3240, 3095, 3246), + edgeville to ZoneBorders(3093, 3498, 3092, 3489), + yanille to ZoneBorders(2610, 3089, 2613, 3095), + ardougne to ZoneBorders(2649, 3281, 2655, 3286), + seers to ZoneBorders(2729, 3493, 2722, 3490), + catherby to ZoneBorders(2807, 3438, 2811, 3441) + ) + + private val whiteWolfMountainTop = Location(2850, 3496, 0) + private val catherbyToTopOfWhiteWolf = arrayOf(Location(2856, 3442, 0), Location(2848, 3455, 0), Location(2848, 3471, 0), Location(2848, 3487, 0)) + private val tavleryToTopOfWhiteWolf = arrayOf(Location(2872, 3425, 0), Location(2863, 3440, 0), Location(2863, 3459, 0), Location(2854, 3475, 0), Location(2859, 3488, 0)) + + val common_stuck_locations = mapOf( + // South of Tavlery dungeon + ZoneBorders(2878, 3386, 2884, 3395) to { it: Adventurer -> + it.scriptAPI.walkArray(tavleryToTopOfWhiteWolf + whiteWolfMountainTop + catherbyToTopOfWhiteWolf.reversedArray()) + }, + // West of Tavlery dungeon + ZoneBorders(2874, 3390, 2880, 3401) to { it: Adventurer -> + it.scriptAPI.walkArray(tavleryToTopOfWhiteWolf + whiteWolfMountainTop + catherbyToTopOfWhiteWolf.reversedArray()) + }, + // South of White Wolf Mountain in Tavlery + ZoneBorders(2865,3408,2874,3423) to { it: Adventurer -> + it.scriptAPI.walkArray(tavleryToTopOfWhiteWolf + whiteWolfMountainTop + catherbyToTopOfWhiteWolf.reversedArray()) + }, + // On beginning of White Wolf Mountain in Tavlery + ZoneBorders(2855, 3454, 2852, 3450) to { it: Adventurer -> + it.scriptAPI.walkArray(tavleryToTopOfWhiteWolf + whiteWolfMountainTop + catherbyToTopOfWhiteWolf.reversedArray()) + }, + // South of White Wolf Mountain in Catherby + ZoneBorders(2861,3425,2867, 3432) to { it: Adventurer -> + it.scriptAPI.walkArray(catherbyToTopOfWhiteWolf + whiteWolfMountainTop + tavleryToTopOfWhiteWolf.reversedArray()) + }, + // On beginning of White Wolf Mountain in Catherby + ZoneBorders(2863, 3441, 2859, 3438) to { it: Adventurer -> + it.scriptAPI.walkArray(catherbyToTopOfWhiteWolf + whiteWolfMountainTop + tavleryToTopOfWhiteWolf.reversedArray()) + }, + // At the Crumbling Wall in Falador + ZoneBorders(2937,3356,2936,3353) to { it: Adventurer -> + // Interact with the Crumbling Wall + val wall = it.scriptAPI.getNearestNode("Crumbling wall", true) + if (wall == null) { + it.refresh() + it.ticks = 0 + return@to + } + it.scriptAPI.interact(it.bot, wall, "Climb-over") + }, + // Northwest corner of Draynor Bank + ZoneBorders(3092, 3246, 3091, 3247) to { it: Adventurer -> + // Walk into Draynor Bank + it.scriptAPI.walkTo(Location(3093, 3243, 0)) + }, + // West of GE, stuck in the corner south of the outlaw place + ZoneBorders(3140, 3468, 3140, 3468) to { it: Adventurer -> + // Walk to Barbarian village + it.scriptAPI.walkArray(arrayOf(Location.create(3135, 3516, 0), Location.create(3103, 3489, 0), Location.create(3082, 3423, 0))) + }, + ) + + val dialogue: JSONObject + val dateCode: Int + + init { + val reader = FileReader(ServerConstants.BOT_DATA_PATH + File.separator + "bot_dialogue.json") + val parser = org.json.simple.parser.JSONParser() + val data = parser.parse(reader) as JSONObject + + dialogue = data + + val formatter = DateTimeFormatter.ofPattern("MMdd") + val current = LocalDateTime.now() + val formatted: String = current.format(formatter) + dateCode = formatted.toInt() + } + + private fun JSONObject.getLines(category: String): JSONArray { + return this[category] as JSONArray + } + + private fun JSONArray.rand(): String { + return this.random() as String + } + } +} diff --git a/Server/src/main/content/global/bots/CannonballSmelter.kt b/Server/src/main/content/global/bots/CannonballSmelter.kt new file mode 100644 index 0000000..8ac77f7 --- /dev/null +++ b/Server/src/main/content/global/bots/CannonballSmelter.kt @@ -0,0 +1,277 @@ +package content.global.bots + +import content.global.skill.gather.mining.MiningNode +import content.global.skill.smithing.smelting.Bar +import content.global.skill.smithing.smelting.SmeltingPulse +import core.api.* +import core.game.bots.* +import core.game.ge.GrandExchange +import core.game.interaction.DestinationFlag +import core.game.interaction.MovementPulse +import core.game.node.Node +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import org.rs09.consts.Items +import content.data.Quests + +@PlayerCompatible +@ScriptName("Falador Cannonball Smelter") +@ScriptDescription("Start in Falador East Bank with a pick equipped","or in your inventory.") +@ScriptIdentifier("fally_cballs") +class CannonballSmelter : Script() { + var state = State.INIT + val bottomLadder = ZoneBorders(3016,9736,3024,9742) + val topLadder = ZoneBorders(3016,3336,3022,3342) + val coalMine = ZoneBorders(3027,9733,3054,9743) + //val coalMine = ZoneBorders(3056, 9729, 3018, 9758) + val ironMine = ZoneBorders(3052,9768,3035,9777) + val northMineEntrance = ZoneBorders(3062, 3375, 3058, 3381) + val bank = ZoneBorders(3009,3355,3018,3358) + var overlay: ScriptAPI.BottingOverlay? = null + var coalAmount = 0 + + override fun tick() { + when(state){ + + State.INIT -> { + overlay = scriptAPI.getOverlay() + overlay!!.init() + overlay!!.setTitle("Mining") + overlay!!.setTaskLabel("Coal Mined:") + overlay!!.setAmount(0) + + if (coalMine.insideBorder(bot)){ + state = State.MINING + } else { + state = State.TO_BANK + } + } + + State.MINING -> { + bot.interfaceManager.close() + if(bot.inventory.freeSlots() == 0){ + state = State.TO_BANK + } else if(amountInInventory(bot, Items.COAL_453) >= 18) { + state = State.TO_IRONMINE + } else if(!coalMine.insideBorder(bot)){ + scriptAPI.walkTo(coalMine.randomLoc) + } else { + val rock = scriptAPI.getNearestObjectByPredicate({node -> node?.name?.equals("rocks", true)!! && MiningNode.forId(node?.id!!).reward == Items.COAL_453 }) + if(rock != null) { + scriptAPI.interact(bot, rock, "mine") + } else { + scriptAPI.walkTo(coalMine.randomLoc) + } + } + overlay!!.setAmount(amountInInventory(bot, Items.COAL_453)) + } + State.MINING_IRON -> { + bot.interfaceManager.close() + if(bot.inventory.freeSlots() == 0 || amountInInventory(bot, Items.IRON_ORE_440) >= 9) { + state = State.TO_BANK + } else if(!ironMine.insideBorder(bot)){ + var loc = ironMine.randomLoc + scriptAPI.walkTo(loc) + } else { + val rock = scriptAPI.getNearestObjectByPredicate({node -> node?.name?.equals("rocks", true)!! && MiningNode.forId(node?.id!!).reward == Items.IRON_ORE_440 }) + //rock?.let { InteractionListeners.run(rock.id, IntType.SCENERY,"mine",bot,rock) } + if(rock != null) { + scriptAPI.interact(bot, rock, "mine") + } else { + scriptAPI.walkTo(ironMine.randomLoc) + } + } + overlay!!.setAmount(amountInInventory(bot, Items.IRON_ORE_440)) + } + + State.TO_BANK -> { + if(bank.insideBorder(bot)){ + val bank = scriptAPI.getNearestNode("bank booth",true) + if(bank != null) { + state = State.BANKING + bot.pulseManager.run(object : BankingPulse(this, bank){ + override fun pulse(): Boolean { + return super.pulse() + } + }) + } + } else { + if(bot.location.y > 3400) { + if(bot.location.y < 9757) { + val ladder = scriptAPI.getNearestNode(30941, true) + //ladder ?: scriptAPI.walkTo(bottomLadder.randomLoc).also { return } + //ladder?.interaction?.handle(bot, ladder.interaction[0]).also { ladderSwitch = true } + scriptAPI.interact(bot, ladder, "climb-up") + } else { + val stairs = scriptAPI.getNearestNode(30943, true) + scriptAPI.interact(bot, stairs, "climb-up") + + } + } else { + if(northMineEntrance.insideBorder(bot)) { + val door = scriptAPI.getNearestNode(11714, true) + if(door != null) { + scriptAPI.interact(bot, door, "open") + } else { + scriptAPI.walkTo(bank.randomLoc) + } + } else { + scriptAPI.walkTo(bank.randomLoc) + } + } + } + } + + State.BANKING -> { + scriptAPI.bankAll({ + if(amountInBank(bot, Items.CANNONBALL_2) >= 500) { + val total = GrandExchange.getBotstockForId(Items.CANNONBALL_2) + bot.interfaceManager.close() + if(total < 5000) { + state = State.TO_GE + } + } + if(state != State.TO_GE) { + if(amountInBank(bot, Items.IRON_ORE_440) >= 9 && amountInBank(bot, Items.COAL_453) >= 18) { + scriptAPI.withdraw(Items.IRON_ORE_440, 9) + scriptAPI.withdraw(Items.COAL_453, 18) + scriptAPI.withdraw(Items.AMMO_MOULD_4, 1) + state = State.TO_FURNACE + bot.interfaceManager.close() + } else { + state = State.TO_MINE + } + } + }) + } + + State.TO_FURNACE -> { + if(bot.location.x > 2978) { + scriptAPI.walkTo(Location.create(2974, 3369, 0)) + } else if(amountInInventory(bot, Items.STEEL_BAR_2353) < 9) { + val furnace = scriptAPI.getNearestNode(11666, true) + scriptAPI.interact(bot, furnace, "smelt") + // TODO: should bots use real interfaces? + bot.pulseManager.run(SmeltingPulse(bot, null, Bar.STEEL, 9)) + } else { + state = State.SMELTING_CBALLS + } + } + + State.SMELTING_CBALLS -> { + if(amountInInventory(bot, Items.STEEL_BAR_2353) > 0) { + val furnace = scriptAPI.getNearestNode(11666, true) + scriptAPI.useWith(bot, Items.STEEL_BAR_2353, furnace) + if(bot.dialogueInterpreter.dialogue != null) { + bot.dialogueInterpreter.handle(309, 32) + } + } else { + state = State.TO_BANK + } + } + + State.TO_MINE -> { + if(bot.location.y < 3400) { + bot.interfaceManager.close() + if(!topLadder.insideBorder(bot.location)){ + scriptAPI.walkTo(topLadder.randomLoc) + } else { + val ladder = scriptAPI.getNearestNode("Ladder",true) + if(ladder != null){ + ladder.interaction.handle(bot,ladder.interaction[0]) + } else { + scriptAPI.walkTo(topLadder.randomLoc) + } + } + } else { + if(!coalMine.insideBorder(bot)){ + scriptAPI.walkTo(coalMine.randomLoc) + } else { + state = State.MINING + } + } + } + + State.TO_IRONMINE -> { + if(ironMine.insideBorder(bot.location)) { + state = State.MINING_IRON + } else if(bot.location.y < 9757) { + if (bot.location.regionId == ((47 shl 8) or 152)) { + val door = scriptAPI.getNearestNode(2112,true) + if(door != null) { + scriptAPI.interact(bot, door, "open") + } else { + scriptAPI.walkTo(Location.create(3046, 9756, 0)) + } + } else { + scriptAPI.walkTo(Location.create(3046, 9756, 0)) + } + } else { + scriptAPI.walkTo(ironMine.randomLoc) + } + } + + State.TO_GE -> { + scriptAPI.teleportToGE() + state = State.SELLING + } + + State.SELLING -> { + scriptAPI.sellOnGE(Items.CANNONBALL_2) + state = State.GO_BACK + } + + State.GO_BACK -> { + scriptAPI.teleport(bank.randomLoc) + state = State.TO_MINE + } + } + } + + open class BankingPulse(val script: Script, val bank: Node) : MovementPulse(script.bot,bank, DestinationFlag.OBJECT){ + override fun pulse(): Boolean { + script.bot.faceLocation(bank.location) + return true + } + } + + override fun newInstance(): Script { + val script = CannonballSmelter() + script.bot = SkillingBotAssembler().produce(SkillingBotAssembler.Wealth.POOR,bot.startLocation) + return script + } + + enum class State { + MINING, + TO_MINE, + TO_BANK, + TO_FURNACE, + SMELTING_CBALLS, + BANKING, + TO_GE, + SELLING, + GO_BACK, + TO_IRONMINE, + MINING_IRON, + INIT + } + + init { + equipment.add(Item(Items.RUNE_PICKAXE_1275)) + inventory.add(Item(Items.AMMO_MOULD_4)) + if(false) { + // spawn initial iron/coal to debug smelting + inventory.add(Item(Items.COAL_453, 18)) + inventory.add(Item(Items.IRON_ORE_440, 9)) + } + skills.put(Skills.ATTACK,40) + skills.put(Skills.STRENGTH,60) + skills.put(Skills.MINING,75) + skills.put(Skills.HITPOINTS,99) + skills.put(Skills.DEFENCE,99) + skills.put(Skills.SMITHING,35) + quests.add(Quests.DWARF_CANNON) + } +} diff --git a/Server/src/main/content/global/bots/ChickenKiller.kt b/Server/src/main/content/global/bots/ChickenKiller.kt new file mode 100644 index 0000000..ee81757 --- /dev/null +++ b/Server/src/main/content/global/bots/ChickenKiller.kt @@ -0,0 +1,112 @@ +package content.global.bots + +import core.game.bots.* +import core.game.node.item.Item +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import org.rs09.consts.Items + +@PlayerCompatible +@ScriptName("Chicken Killer") +@ScriptDescription("Kills chickens and loots feathers. Start in any chicken area.") +@ScriptIdentifier("chicken_killer") +class ChickenKiller : Script(){ + var state = State.INIT + var chickenCounter = 0 + var overlay: ScriptAPI.BottingOverlay? = null + var startLocation = Location(0,0,0) + var timer = 3 + var lootFeathers = false + var featherNearby = false + var currentFeathers = 0 + val chickenPen = ZoneBorders(3231,3300,3235,3287) + + override fun tick() { + when(state){ + State.CONFIG -> {} + State.INIT -> { + overlay = scriptAPI.getOverlay() + overlay!!.init() + overlay!!.setTitle("Chickens") + overlay!!.setTaskLabel("Chickens KO'd:") + overlay!!.setAmount(0) + state = State.CONFIG + bot.dialogueInterpreter.sendOptions("Loot Feathers and bury bones?","Yes","No") + bot.dialogueInterpreter.addAction{player,button -> + lootFeathers = button == 2 + state = State.KILLING + } + startLocation = bot.location + } + + State.KILLING -> { + val chicken = scriptAPI.getNearestNode("Chicken") + if(chicken == null){ + scriptAPI.randomWalkTo(startLocation,3) + } else { + scriptAPI.attackNpcInRadius(bot,"Chicken",10) + if(lootFeathers) { + state = State.IDLE + timer = 4 + } + chickenCounter++ + overlay!!.setAmount(chickenCounter) + } + } + + State.IDLE -> { + if(timer-- <= 0){ + featherNearby = scriptAPI.takeNearestGroundItem(Items.FEATHER_314) + currentFeathers = 0 + if (featherNearby) { + state = State.LOOTFEATHER + }else{ + state = State.LOOTBONES + } + } + } + + State.LOOTFEATHER -> { + timer = 1 + if(timer-- >= 0) { + currentFeathers = bot.inventory.getAmount(Items.FEATHER_314) + scriptAPI.takeNearestGroundItem(Items.FEATHER_314) + featherNearby = false + } + state = State.LOOTBONES + } + + State.LOOTBONES -> { + timer = 1 + if(timer-- >= 0){ + scriptAPI.takeNearestGroundItem(Items.BONES_526) + } + state = State.BURYBONES + } + + State.BURYBONES -> { + timer = 1 + var hasBone = bot.hasItem(Item(Items.BONES_526)) + var bone = bot.inventory.getItem(Item(Items.BONES_526)) + if (hasBone) { + bone.interaction.handleItemOption(bot,bone.interaction.get(0),bot.inventory) + } + state = State.KILLING + } + } + } + + override fun newInstance(): Script { + return this + } + + enum class State { + IDLE, + INIT, + KILLING, + CONFIG, + LOOTFEATHER, + LOOTBONES, + BURYBONES + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/bots/CoalMiner.kt b/Server/src/main/content/global/bots/CoalMiner.kt new file mode 100644 index 0000000..9bbf13b --- /dev/null +++ b/Server/src/main/content/global/bots/CoalMiner.kt @@ -0,0 +1,160 @@ +package content.global.bots + + +import core.game.interaction.DestinationFlag +import core.game.interaction.MovementPulse +import core.game.node.Node +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.world.map.zone.ZoneBorders +import org.rs09.consts.Items +import core.game.interaction.IntType +import core.game.interaction.InteractionListeners +import core.api.* +import core.game.bots.* + +@PlayerCompatible +@ScriptName("Falador Coal Miner") +@ScriptDescription("Start in Falador East Bank with a pick equipped","or in your inventory.") +@ScriptIdentifier("fally_coal") +class CoalMiner : Script() { + var state = State.INIT + var ladderSwitch = false + val bottomLadder = ZoneBorders(3016,9736,3024,9742) + val topLadder = ZoneBorders(3016,3336,3022,3342) + val mine = ZoneBorders(3027,9733,3054,9743) + val bank = ZoneBorders(3009,3355,3018,3358) + var overlay: ScriptAPI.BottingOverlay? = null + var coalAmount = 0 + + override fun tick() { + when(state){ + + State.INIT -> { + overlay = scriptAPI.getOverlay() + ladderSwitch = true + overlay!!.init() + overlay!!.setTitle("Mining") + overlay!!.setTaskLabel("Coal Mined:") + overlay!!.setAmount(0) + + if (mine.insideBorder(bot)){ + ladderSwitch = false + state = State.MINING + } else { + state = State.TO_MINE + } + } + + State.MINING -> { + bot.interfaceManager.close() + if(bot.inventory.freeSlots() == 0){ + state = State.TO_BANK + } + if(!mine.insideBorder(bot)){ + scriptAPI.walkTo(mine.randomLoc) + } else { + val rock = scriptAPI.getNearestNode("rocks",true) + rock?.let { InteractionListeners.run(rock.id, IntType.SCENERY,"mine",bot,rock) } + } + overlay!!.setAmount(amountInInventory(bot, Items.COAL_453) + coalAmount) + } + + State.TO_BANK -> { + if(bank.insideBorder(bot)){ + val bank = scriptAPI.getNearestNode("bank booth",true) + if(bank != null) { + bot.pulseManager.run(object : BankingPulse(this, bank){ + override fun pulse(): Boolean { + state = State.BANKING + return super.pulse() + } + }) + } + + } else { + if(!ladderSwitch) { + val ladder = scriptAPI.getNearestNode(30941, true) + ladder ?: scriptAPI.walkTo(bottomLadder.randomLoc).also { return } + ladder?.interaction?.handle(bot, ladder.interaction[0]).also { ladderSwitch = true } + } else { + if (!bank.insideBorder(bot)) scriptAPI.walkTo(bank.randomLoc).also { return } + } + } + } + + State.BANKING -> { + coalAmount += bot.inventory.getAmount(Items.COAL_453) + scriptAPI.bankAll() + state = State.TO_MINE + } + + State.TO_MINE -> { + if(ladderSwitch){ + bot.interfaceManager.close() + if(!topLadder.insideBorder(bot.location)){ + scriptAPI.walkTo(topLadder.randomLoc) + } else { + val ladder = scriptAPI.getNearestNode("Ladder",true) + if(ladder != null){ + ladder.interaction.handle(bot,ladder.interaction[0]) + ladderSwitch = false + } else { + scriptAPI.walkTo(topLadder.randomLoc) + } + } + } else { + if(!mine.insideBorder(bot)){ + scriptAPI.walkTo(mine.randomLoc) + } else { + state = State.MINING + } + } + } + + State.TO_GE -> { + scriptAPI.teleportToGE() + state = State.SELLING + } + + State.SELLING -> { + scriptAPI.sellOnGE(Items.COAL_453) + state = State.GO_BACK + } + + State.GO_BACK -> { + scriptAPI.teleport(bank.randomLoc) + state = State.TO_MINE + } + } + } + + open class BankingPulse(val script: Script, val bank: Node) : MovementPulse(script.bot,bank, DestinationFlag.OBJECT){ + override fun pulse(): Boolean { + script.bot.faceLocation(bank.location) + return true + } + } + + override fun newInstance(): Script { + val script = CoalMiner() + script.bot = SkillingBotAssembler().produce(SkillingBotAssembler.Wealth.POOR,bot.startLocation) + return script + } + + enum class State { + MINING, + TO_MINE, + TO_BANK, + BANKING, + TO_GE, + SELLING, + GO_BACK, + INIT + } + + init { + equipment.add(Item(Items.IRON_PICKAXE_1267)) + skills.put(Skills.MINING,75) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/bots/CosmicCrafter.kt b/Server/src/main/content/global/bots/CosmicCrafter.kt new file mode 100644 index 0000000..911dc2b --- /dev/null +++ b/Server/src/main/content/global/bots/CosmicCrafter.kt @@ -0,0 +1,181 @@ +package content.global.bots + +import content.global.skill.runecrafting.MysteriousRuin +import core.cache.def.impl.SceneryDefinition +import core.game.bots.* +import core.game.node.item.Item +import core.game.node.scenery.Scenery +import core.game.world.map.Location +import core.game.world.map.RegionManager +import core.game.world.map.zone.ZoneBorders +import core.net.packet.PacketProcessor +import org.rs09.consts.Items + + +@PlayerCompatible +@ScriptName("Cosmic Rune Crafter") +@ScriptDescription("Crafts cosmic runes. Start in Zanaris w/ cosmic tiara.") +@ScriptIdentifier("cosmic_crafter") +class CosmicCrafter : Script() { + var state = State.INIT + var runeCounter = 0 + var overlay: ScriptAPI.BottingOverlay? = null + var startLocation = Location(0,0,0) + var timer = 0 + var bank_deposit = true + var bank = Location(2384, 4457) + var squeezeZone = ZoneBorders(2413, 4400, 2416, 4406) + var endZone = ZoneBorders(2405, 4392, 2410, 4397) + var agility_part = 0 + + + var ruinsZone = ZoneBorders(2400, 4370, 2410, 4385) + var cosmicZone = ZoneBorders(2160, 4830, 2170, 4840) + + var ruinPoint = Location(2407, 4379, 0) + var agility2ExitPoint = Location(2408, 4394, 0) + var agility2EntryPoint = Location(2408, 4396, 0) + var agility1ExitPoint = Location(2415, 4401, 0) + var agility1EntryPoint = Location(2415, 4403, 0) + + override fun tick() { + if (timer-- > 0) { + return + } + if (bot.settings.runEnergy > 10.0) { + bot.settings.isRunToggled = true + } + + when(state){ + State.INIT -> { + if (!bot.equipment.containsAtLeastOneItem(Items.COSMIC_TIARA_5539)) { + bot.sendMessage("Please equip a cosmic tiara first.") + state = State.INVALID + } else { + overlay = scriptAPI.getOverlay() + overlay!!.init() + overlay!!.setTitle("Cosmic Runes") + overlay!!.setTaskLabel("Runes Crafted:") + overlay!!.setAmount(0) + startLocation = bot.location + state = State.BANKING + } + } + + State.BANKING -> { + if(bot.location != bank) { + scriptAPI.walkTo(bank) + return + } + val runes = bot.inventory.getAmount(Item(Items.COSMIC_RUNE_564)) + if (runes > 0) { + runeCounter += runes + overlay!!.setAmount(runeCounter) + bot.sendMessage("You have crafted a total of: $runeCounter runes.") + scriptAPI.bankItem(Items.COSMIC_RUNE_564) + } else { + scriptAPI.withdraw(Items.PURE_ESSENCE_7936, 28) + state = State.FIRST_AGILITY + } + } + + State.FIRST_AGILITY -> { + val squeezeWall = scriptAPI.getNearestNode(12127, true) + if (agility_part == 0) { + if (!squeezeZone.insideBorder(bot)) + scriptAPI.walkTo(agility1EntryPoint) + else { + scriptAPI.interact(bot, squeezeWall, "squeeze-past") + agility_part = 1 + timer = 6 + } + } else if (agility_part == 1) { + if (!endZone.insideBorder(bot)) + scriptAPI.walkTo(agility2EntryPoint) + else { + scriptAPI.interact(bot, squeezeWall, "squeeze-past") + state = State.RUNNING_TO_ALTER + timer = 6 + } + } + } + + State.RUNNING_TO_ALTER -> { + if (cosmicZone.insideBorder(bot)) + state = State.CRAFTING + + val ruins = scriptAPI.getNearestNode(2458,true) + if (!ruinsZone.insideBorder(bot)) { + scriptAPI.walkTo(ruinPoint) + } else if (ruins != null && ruins.location.withinDistance(bot.location, 20)) { + if (!bot.equipment.containsAtLeastOneItem(Items.COSMIC_TIARA_5539)) { + bot.sendMessage("Please equip a cosmic tiara first.") + state = State.INVALID + } else { + val ruinsChild = (ruins as Scenery).getChild(bot) + scriptAPI.interact(bot, ruinsChild, "enter") + timer = 4 + } + } + } + + State.CRAFTING -> { + val alter = scriptAPI.getNearestNode(2484,true) + scriptAPI.interact(bot, alter, "craft-rune") + if(bot.inventory.containsAtLeastOneItem(Item(Items.COSMIC_RUNE_564))) + state = State.LEAVING_ALTER + } + + State.LEAVING_ALTER -> { + var portalOut = scriptAPI.getNearestNode(2471, true) + scriptAPI.interact(bot, portalOut, "use") + if (ruinsZone.insideBorder(bot)) { + state = State.RETURN_AGILITY + timer = 2 + } + } + + State.RETURN_AGILITY -> { + val squeezeWall = scriptAPI.getNearestNode(12127, true) + if (agility_part == 1) { + if (!endZone.insideBorder(bot)) + scriptAPI.walkTo(agility2ExitPoint) + else { + scriptAPI.interact(bot, squeezeWall, "squeeze-past") + agility_part = 0 + timer = 6 + } + } else if (agility_part == 0) { + if (!squeezeZone.insideBorder(bot)) + scriptAPI.walkTo(agility1ExitPoint) + else { + scriptAPI.interact(bot, squeezeWall, "squeeze-past") + state = State.BANKING + timer = 6 + } + } + } + + State.INVALID -> { + timer = 25 + state = State.INIT + } + } + } + + override fun newInstance(): Script { + return this + } + + enum class State { + INIT, + BANKING, + FIRST_AGILITY, + RETURN_AGILITY, + RUNNING_TO_ALTER, + CRAFTING, + LEAVING_ALTER, + INVALID + } + +} diff --git a/Server/src/main/content/global/bots/CowKiller.kt b/Server/src/main/content/global/bots/CowKiller.kt new file mode 100644 index 0000000..ac15edb --- /dev/null +++ b/Server/src/main/content/global/bots/CowKiller.kt @@ -0,0 +1,155 @@ +package content.global.bots + +import core.game.interaction.DestinationFlag +import core.game.interaction.MovementPulse +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import org.rs09.consts.Items +import core.game.bots.CombatBotAssembler +import core.game.bots.Script + +class CowKiller : Script() { + var state = State.KILLING + var spawnZone = ZoneBorders(3254,3255,3264,3281) + var cowZone = ZoneBorders(3242, 3254,3265, 3296) + val bankZone = ZoneBorders(3208, 3217,3210, 3220) + init { + cowZone.addException(ZoneBorders(3242,3254,3252,3277)) + cowZone.addException(ZoneBorders(3242,3277,3242,3296)) + cowZone.addException(ZoneBorders(3253, 3267,3253, 3267)) + } + + override fun tick() { + when(state){ + State.KILLING -> { + scriptAPI.attackNpcInRadius(bot,"Cow",10) + state = State.LOOTING + } + + State.LOOTING -> { + bot.pulseManager.run(object: Pulse(4){ + override fun pulse(): Boolean { + state = State.KILLING + scriptAPI.takeNearestGroundItem(Items.COWHIDE_1739) + state = if(bot.inventory.getAmount(Items.COWHIDE_1739) > 22){ + State.TO_BANK + } else { + State.KILLING + } + return true + } + }) + } + + State.TO_BANK -> { + if(cowZone.insideBorder(bot)) + scriptAPI.walkTo(Location.create(3253, 3267, 0)) + else{ + val closedGate = scriptAPI.getNearestNode(15516,true) + if(closedGate != null && closedGate.location.withinDistance(bot.location,2)){ + closedGate.interaction.handle(bot,closedGate.interaction[0]) + } else { + when (bot.location) { + Location.create(3212, 3227, 0) -> { + val stairs = scriptAPI.getNearestGameObject(bot.location, 36776) + stairs?.interaction?.handle(bot, stairs.interaction[0]) + } + Location.create(3206, 3229, 1) -> { + val stairs = scriptAPI.getNearestNode(36777, true) + stairs?.interaction?.handle(bot, stairs.interaction[1]) + } + Location.create(3206, 3229, 2) -> { + scriptAPI.walkTo(bankZone.randomLoc) + state = State.BANKING + } + else -> scriptAPI.walkTo(Location.create(3212, 3227, 0)) + } + } + } + } + + State.BANKING -> { + if(bankZone.insideBorder(bot)) { + val bank = scriptAPI.getNearestNode(36786, true) + bot.pulseManager.run(object : MovementPulse(bot, bank, DestinationFlag.OBJECT) { + override fun pulse(): Boolean { + scriptAPI.bankItem(Items.COWHIDE_1739) + if (bot.bank.getAmount(Items.COWHIDE_1739) > 75) { + scriptAPI.teleportToGE() + state = State.TELE_GE + } else { + state = State.BACK_TO_COWS + } + return true + } + }) + } + } + + + State.BACK_TO_COWS -> { + if (bankZone.insideBorder(bot)) + scriptAPI.walkTo(Location.create(3206, 3229, 2)) + else { + when (bot.location) { + Location.create(3206, 3229, 2) -> { + val stairs = scriptAPI.getNearestNode(36778, true) + stairs?.interaction?.handle(bot, stairs.interaction[0]) + } + Location.create(3206, 3229, 1) -> { + val stairs = scriptAPI.getNearestNode(36777, true) + stairs?.interaction?.handle(bot, stairs.interaction[2]) + } + Location.create(3252, 3267, 0) -> { + val closedGate = scriptAPI.getNearestNode(15516, true) + if (closedGate != null && closedGate.location.withinDistance(bot.location, 2)) { + closedGate.interaction.handle(bot, closedGate.interaction[0]) + } else { + scriptAPI.walkTo(cowZone.randomLoc) + state = State.KILLING + } + } + else -> scriptAPI.walkTo(Location.create(3252, 3267, 0)) + } + } + } + + + State.TELE_GE -> { + if(bot.location == Location.create(3165, 3482, 0)) + state = State.SELL_GE + else + scriptAPI.walkTo(Location.create(3165, 3482, 0)) + } + + State.SELL_GE -> { + state = State.TELE_LUM + scriptAPI.sellOnGE(Items.COWHIDE_1739) + } + + State.TELE_LUM -> { + state = State.BACK_TO_COWS + scriptAPI.teleport(Location.create(3222, 3218, 0)) + } + } + } + + enum class State { + KILLING, + LOOTING, + BANKING, + TO_BANK, + BACK_TO_COWS, + SELL_GE, + TELE_GE, + TELE_LUM + } + + override fun newInstance(): Script { + val script = CowKiller() + script.bot = CombatBotAssembler().produce(CombatBotAssembler.Type.values().random(), CombatBotAssembler.Tier.LOW,spawnZone.randomLoc) + script.state = State.KILLING + return script + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/bots/DoublingMoney.kt b/Server/src/main/content/global/bots/DoublingMoney.kt new file mode 100644 index 0000000..785fd86 --- /dev/null +++ b/Server/src/main/content/global/bots/DoublingMoney.kt @@ -0,0 +1,377 @@ +package content.global.bots + +import core.game.container.Container +import core.game.interaction.Option._P_TRADE +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.request.trade.TradeModule +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.world.map.Location +import core.game.world.map.RegionManager +import core.game.world.update.flag.context.ChatMessage +import core.game.world.update.flag.* +import core.integrations.discord.Discord +import org.json.simple.JSONArray +import org.json.simple.JSONObject +import org.json.simple.parser.JSONParser +import org.rs09.consts.Items +import core.ServerConstants +import core.game.bots.AIRepository +import content.global.bots.Adventurer.Companion.lumbridge +import core.game.bots.Script +import core.game.interaction.IntType +import core.game.interaction.InteractionListeners +import core.game.world.ImmerseWorld +import java.io.File +import java.io.FileReader +import java.util.Random +import kotlin.math.min + +/** + * A bot that doubles money + * 30% chance to double money, 70% chance to scam + * @author dginovker + */ +class DoublingMoney : Script() { + /** + * If we're in ScamMode, we will never trade away any more coins + */ + private var scamMode = false + + /** + * Whether the bot has run its setup (gotten appearance made/etc.) + */ + private var setup = false + + /** + * Player who most recently traded with this bot + */ + var victim: Player? = null + + /** + * Player who the bot took money from + */ + private var playerOwed: Player? = null + + /** + * Whether we sent a trade request to the player we owe yet + */ + private var sentTradeRequest = false + + /** + * Amount the bot owes the player (2x the amount the player gave the bot) + */ + private var debtOwed: Int = 0 + + /** + * How many ticks the bot has run for + */ + var ticks = 0 + + /** + * Duration for how long the bot will take a nap + */ + private var sleepTime = 0 + + /** + * Debug information about what state the bot is in + */ + private var stateString = "init" + + /** + * How long the bot will stay around for + */ + private val maxTicks = (400..750).random() + + enum class Effort { + LOW, + HIGH, + VERY_HIGH + } + + /** + * Characteristics about how hard the bot will work + * Most likely to be LOW, small chance to be HIGH, very small chance to be VERY_HIGH + */ + private val effort = when (Random().nextInt(100)) { + in 0..90 -> Effort.LOW + in 90..98 -> Effort.HIGH + else -> Effort.VERY_HIGH + } + + // Priority calculation -> Execute method mapping. Priority calculation with the highest return value is executed + var states = mapOf( + fun(): Int { + if (setup) return -1 + return 250 + } to { + stateString = "Putting on my outfit.." + var appearance = if (Math.random() < 0.5) "noob" else "intermediate" + if (effort == Effort.VERY_HIGH && Math.random() < 0.5) appearance = "veteran" + val appearancesArray = botAppearances[appearance] as JSONArray + scriptAPI.loadAppearanceAndEquipment(appearancesArray.random() as JSONObject) + setup = true + }, + fun(): Int { + val botTradeModule = TradeModule.getExtension(bot) + if (botTradeModule != null) return -1 + return 0 + } to { + stateString = "Doing nothing" + }, + fun(): Int { + return 1 + } to { + stateString = "Saying Doubling money" + when (effort) { + Effort.LOW -> { + scriptAPI.sendChat("Doubling money") + sleepTime = 7 + } + Effort.HIGH -> { + val message = arrayOf("Doubling Money", "Doubling Money", "Doubling Money!", "Doubling moneyy").random() + val messageEffect = arrayOf(0, 256).random() + val ctx = ChatMessage(bot, message, messageEffect, message.length) + bot.updateMasks.register(EntityFlag.Chat, ctx) + sleepTime = 8 + } + Effort.VERY_HIGH -> { + val message = arrayOf("Doubling money!", "Doubling money").random() + val messageEffect = arrayOf(771, 2818, 2562, 768, 512, 2304, 2560, 769, 1792).random() + val ctx = ChatMessage(bot, message, messageEffect, message.length) + bot.updateMasks.register(EntityFlag.Chat, ctx) + sleepTime = 9 + } + } + }, + fun(): Int { + if (victim == null) return -1 + return 10 + } to { + stateString = "Accepting trade request" + // Send trade request back to victim + InteractionListeners.run(-1, IntType.PLAYER, "trade with", bot, victim!!) + victim = null + sleepTime = 3 + }, + fun(): Int { + if (debtOwed >= 0) return -1 + val botTradeModule = TradeModule.getExtension(bot) ?: return -1 + val playerTradeModule = TradeModule.getExtension(botTradeModule.target) ?: return -1 + if (!playerTradeModule.container!!.containsAtLeastOneItem(Items.COINS_995)) return 15 + return -1 + } to { + val botTradeModule = TradeModule.getExtension(bot) + stateString = "Waiting for ${botTradeModule!!.target} to post money" + sleepTime = 5 + }, + fun(): Int { + // If we have debt and are in the trade screen with the player who we owe, but have not put up coins, put up coins + if (debtOwed == 0) return -1 + val botTradeModule = TradeModule.getExtension(bot) ?: return -1 + if (botTradeModule.target != playerOwed) return -1 + if (!botTradeModule.container!!.containsAtLeastOneItem(Items.COINS_995)) return 150 + return -1 + } to { + stateString = "Paying off ${playerOwed!!.username} $debtOwed coins" + val botTradeModule = TradeModule.getExtension(bot) + val coinSlot = bot.inventory.getSlot(Item(Items.COINS_995)) + botTradeModule!!.container!!.offer(coinSlot, debtOwed) + debtOwed = 0 + playerOwed = null + }, + fun(): Int { + val botTradeModule = TradeModule.getExtension(bot) ?: return -1 + val playerTradeModule = TradeModule.getExtension(botTradeModule.target) ?: return -1 + if (botTradeModule.container!!.containsAtLeastOneItem(Items.COINS_995)) return 200 + if (playerTradeModule.container!!.containsAtLeastOneItem(Items.COINS_995)) return 200 + return -1 + } to { + stateString = "Accepting any trade screen that has coins put up" + val botTradeModule = TradeModule.getExtension(bot) + val playerTradeModule = TradeModule.getExtension(botTradeModule!!.target) + if (botTradeModule.isAccepted) return@to + + sleepTime = (1..if (botTradeModule.getInterface() == TradeModule.MAIN_INTERFACE) 2 else 5).random() + + val coinsFromBot = botTradeModule.container!!.getAmount(Items.COINS_995) + if (botTradeModule.getInterface() == TradeModule.ACCEPT_INTERFACE && coinsFromBot > 0 && effort == Effort.VERY_HIGH) { + val message = "Payed ${(if (coinsFromBot < 1000) "${coinsFromBot}gp" else "${coinsFromBot / 1000}k")}" + val ctx = ChatMessage(bot, message, 512, message.length) + bot.updateMasks.register(EntityFlag.Chat, ctx) + + sleepTime = 7 + } + if (botTradeModule.getInterface() == TradeModule.ACCEPT_INTERFACE && Math.random() < 0.2 && effort == Effort.HIGH && coinsFromBot > 0) { + scriptAPI.sendChat("Enjoy") + sleepTime += 4 + } + + if (botTradeModule.getInterface() == TradeModule.MAIN_INTERFACE && scamMode) { + sleepTime = maxOf(3, sleepTime) + } + + if (botTradeModule.getInterface() == TradeModule.ACCEPT_INTERFACE) { + val player = botTradeModule.target + var playerNetPoL = player!!.getAttribute("double-money-net-pol", "0").toInt() + playerNetPoL += coinsFromBot + playerNetPoL -= playerTradeModule!!.container!!.getAmount(Items.COINS_995) + player.setAttribute("double-money-net-pol", playerNetPoL.toString()) + // if playerNetPoL > 100k, send a Discord notification + if (playerNetPoL > 100_000) { + Discord.postPlayerAlert(player.username, "Made too much off Doubling Money bots: ${playerNetPoL / 1000}k") + } + } + // If we're in scamMode, we cannot actually setAccepted to true if we're giving away coins! (Gotta fake em out ;) + if (scamMode && botTradeModule.getInterface() == TradeModule.ACCEPT_INTERFACE && coinsFromBot > 0) { + botTradeModule.decline() + } else { + botTradeModule.setAccepted(true, update = true) + } + sentTradeRequest = false + }, + fun(): Int { + if (sentTradeRequest) return 50 + return -1 + } to { + // Wait for the other player to accept + }, + fun(): Int { + if (TradeModule.getExtension(bot) == null && debtOwed > 0 && playerOwed != null) return 25 + return -1 + } to { + // Scam over 200k payout or 70% chance + if (Math.random() < 0.7 || debtOwed > 200_000) { + stateString = "Scamming" + scamMode = true + if (effort != Effort.VERY_HIGH || Math.random() < 0.5) { + // At high scam effort, there's a chance we fake giving them coins back to keep milking + // with scamMode = true, we will never accept giving coins away at the second trade screen again + terminate() + } + } + stateString = "Sending trade request to ${playerOwed!!.name} to give them $debtOwed coins" + playerOwed!!.interaction.handle(bot, _P_TRADE) + InteractionListeners.run(-1, IntType.PLAYER, "trade with", bot, playerOwed!!) + sentTradeRequest = true + }, + fun(): Int { + // If we're not near a doubling loc, or another doubling bot is on our loc, walk to random one + var minDist = 1000.0 + for (loc in doublingLocs) { + minDist = min(minDist, loc.getDistance(bot.location)) + } + if (minDist > 1) return 2 + RegionManager.forId(bot.location.regionId).planes[bot.location.z].players.forEach { + if (AIRepository.PulseRepository[it?.username?.lowercase()]?.botScript is DoublingMoney + && it != bot + && it.location.getDistance(bot.location) <= 1) { + return 2 + } + } + return -1 + } to { + stateString = "Walking to doubling location" + val loc = doublingLocs.random() + scriptAPI.walkTo(loc) + sleepTime = 5 + }, + fun(): Int { + // If we're past the max ticks, log out + if (ticks > maxTicks) return 30 + return -1 + } to { + stateString = "Logging out" + terminate() + }, + fun(): Int { + // If we're past 1,000 ticks, force terminate + if (ticks > 1000) return 1_000_000 + return -1 + } to { + stateString = "Force terminating" + terminate() + } + ) + + override fun toString(): String { + return "stateString: $stateString, sleepTime: $sleepTime, ticks: $ticks, maxTicks: $maxTicks, debtOwed: $debtOwed, playerOwed: $playerOwed, victim: $victim, effort: $effort, scamMode: $scamMode" + } + + override fun tick() { + if(!bot.isActive){ + running = false + return + } + ticks ++ + if (sleepTime > 0) { + sleepTime -- + return + } + + // Execute the priority calculations, then execute the method of the one which returned highest + states.maxByOrNull { it.key() }?.value?.invoke() + } + + fun tradeReceived(p: Player) { + victim = p + } + + fun itemsReceived(p: Player, container: Container?) { + if (container == null) return + val coins: Item = container.get(Item(Items.COINS_995)) ?: return + playerOwed = p + debtOwed = coins.amount * 2 + if (effort == Effort.VERY_HIGH) { + val message = "Received ${(if (coins.amount < 1000) "${coins.amount}gp" else "${coins.amount / 1000}k")}" + val ctx = ChatMessage(bot, message, 256, message.length) + bot.updateMasks.register(EntityFlag.Chat, ctx) + } + } + + fun terminate() { + scriptAPI.teleport(lumbridge) + debtOwed = 0 + bot.isActive = false + sleepTime = 500 + AIRepository.PulseRepository.remove(bot.username.lowercase()) + + ImmerseWorld.spawnDoubleMoneyBot(true) + } + + override fun newInstance(): Script? { + // this straight doesn't get called.... + return null + } + + init { + skills[Skills.AGILITY] = 99 + inventory.add(Item(Items.COINS_995, 1_000_000)) + } + + companion object { + val startingLocs = arrayOf(Location.create(3184, 3488, 0), + Location.create(3167, 3461, 0), + Location.create(3170, 3444, 0), + Location.create(3165, 3487, 0), + Location.create(3167, 3489, 0), + Location.create(3162, 3491, 0)) + + val doublingLocs = arrayOf(Location.create(3159, 3492, 0), + Location.create(3164, 3484, 0), + Location.create(3169, 3486, 0), + Location.create(3172, 3489, 0), + Location.create(3168, 3483, 0), + Location.create(3166, 3493, 0), + Location.create(3157, 3498, 0), + Location.create(3157, 3485, 0) + ) + + // load from data/botdata/ge_bot_appearances_and_equipment.json + private val jsonFilePath = "${ServerConstants.BOT_DATA_PATH}/ge_bot_appearances_and_equipment.json" + private val jsonFile = File(jsonFilePath) + private val parser = JSONParser() + val botAppearances = parser.parse(FileReader(jsonFile)) as JSONObject + } + +} diff --git a/Server/src/main/content/global/bots/DraynorFisher.kt b/Server/src/main/content/global/bots/DraynorFisher.kt new file mode 100644 index 0000000..79a9bee --- /dev/null +++ b/Server/src/main/content/global/bots/DraynorFisher.kt @@ -0,0 +1,73 @@ +package content.global.bots + +import core.game.interaction.DestinationFlag +import core.game.interaction.MovementPulse +import core.game.node.item.Item +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import org.rs09.consts.Items +import core.game.bots.SkillingBotAssembler +import core.game.bots.Script +import core.game.interaction.IntType +import core.game.interaction.InteractionListeners + +class DraynorFisher : Script() { + val fishingZone = ZoneBorders(3085, 3223,3089, 3233) + val bankZone = ZoneBorders(3092, 3240,3094, 3246) + + + var state = State.FISHING + override fun tick() { + when(state){ + State.FISHING -> { + if(!fishingZone.insideBorder(bot)) + scriptAPI.walkTo(fishingZone.randomLoc) + else { + val spot = scriptAPI.getNearestNode(316,false) + if (spot != null) { + InteractionListeners.run(spot.id, IntType.NPC,"net",bot,spot) + } else { + scriptAPI.walkTo(fishingZone.randomLoc) + } + if(bot.inventory.getMaximumAdd(Item(4151)) < 5) + state = State.BANKING + } + } + + State.BANKING -> { + if(!bankZone.insideBorder(bot)) + scriptAPI.walkTo(bankZone.randomLoc) + else { + val bank = scriptAPI.getNearestNode("Bank booth") + if (bank != null){ + bot.pulseManager.run(object : MovementPulse(bot,bank, DestinationFlag.OBJECT){ + override fun pulse(): Boolean { + bot.inventory.clear() + state = State.FISHING + bot.inventory.add(Item(Items.SMALL_FISHING_NET_303)) + return true + } + }) + } + } + } + + + } + } + + override fun newInstance(): Script { + val script = DraynorFisher() + script.bot = SkillingBotAssembler().produce(SkillingBotAssembler.Wealth.POOR, Location.create(3094, 3242, 0)) + return script + } + + init { + inventory.add(Item(Items.SMALL_FISHING_NET_303)) + } + + enum class State { + FISHING, + BANKING + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/bots/DraynorWillows.kt b/Server/src/main/content/global/bots/DraynorWillows.kt new file mode 100644 index 0000000..67d2366 --- /dev/null +++ b/Server/src/main/content/global/bots/DraynorWillows.kt @@ -0,0 +1,92 @@ +package content.global.bots +import core.game.bots.* +import core.game.component.Component +import core.game.interaction.DestinationFlag +import core.game.interaction.MovementPulse +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.world.map.zone.ZoneBorders +import org.rs09.consts.Items +import core.game.interaction.IntType +import core.game.interaction.InteractionListeners +import core.tools.colorize + +@PlayerCompatible +@ScriptName("Draynor Willows") +@ScriptDescription("Start in Draynor with an axe equipped or in inventory.") +@ScriptIdentifier("draynor_trees") +class DraynorWillows : Script(){ + val willowZone = ZoneBorders(3084, 3225,3091, 3239) + val bankZone = ZoneBorders(3092, 3245,3092, 3242) + var state = State.INIT + var logCount = 0 + + override fun tick() { + when(state){ + State.INIT -> { + if(true){ + bot.interfaceManager.openOverlay(Component(195)) + bot.packetDispatch.sendString("Woodcutting",195,7) + bot.packetDispatch.sendString(colorize("%BLogs Chopped:"),195,8) + bot.packetDispatch.sendString(colorize("%B0"),195,9) + bot.packetDispatch.sendInterfaceConfig(195,5,true) + } + state = State.CHOPPING + } + + State.CHOPPING -> { + if (!willowZone.insideBorder(bot)) + scriptAPI.walkTo(willowZone.randomLoc) + else { + val willowtree = scriptAPI.getNearestNode("willow", true) + bot.interfaceManager.close() + willowtree?.let { InteractionListeners.run(willowtree.id, + IntType.SCENERY,"Chop down",bot,willowtree) } + if (bot.inventory.isFull) + state = State.BANKING + } + + bot.packetDispatch.sendString(colorize("%B${logCount + bot.inventory.getAmount(Items.WILLOW_LOGS_1519)}"), 195, 9) + } + + State.BANKING -> { + if(!bankZone.insideBorder(bot)) + scriptAPI.walkTo(bankZone.randomLoc) + else{ + val bank = scriptAPI.getNearestNode("Bank Booth",true) + if(bank != null){ + bot.pulseManager.run(object : MovementPulse(bot,bank, DestinationFlag.OBJECT){ + override fun pulse(): Boolean { + val logs = bot.inventory.getAmount(Item(Items.WILLOW_LOGS_1519)) + logCount += logs + bot.inventory.remove(Item(Items.WILLOW_LOGS_1519,logs)) + bot.bank.add(Item(Items.WILLOW_LOGS_1519,logs)) + state = State.CHOPPING + return true + } + }) + } + } + } + + + + } + } + + init { + inventory.add(Item(Items.ADAMANT_AXE_1357)) + skills[Skills.WOODCUTTING] = 35 + } + + override fun newInstance(): Script { + val script = DraynorWillows() + return script + } + + enum class State { + CHOPPING, + BANKING, + INIT + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/bots/FarmerThiever.kt b/Server/src/main/content/global/bots/FarmerThiever.kt new file mode 100644 index 0000000..bf3deb1 --- /dev/null +++ b/Server/src/main/content/global/bots/FarmerThiever.kt @@ -0,0 +1,72 @@ +package content.global.bots +import core.game.world.map.zone.ZoneBorders +import core.game.bots.SkillingBotAssembler +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import core.game.bots.Script +import core.game.interaction.IntType +import core.game.interaction.InteractionListeners + +class FarmerThiever : Script() { + val pickpocketZone = ZoneBorders(3074,3245,3086,3255) + val bankZone = ZoneBorders(3092, 3245,3092, 3242) + val food = Items.JUG_OF_WINE_1993 + val foodAmount = 10 + var state = State.PICKPOCKETING + + + override fun tick() { + when(state) { + + State.PICKPOCKETING -> { + if (!pickpocketZone.insideBorder(bot)) + scriptAPI.walkTo(pickpocketZone.randomLoc) + if (bot.inventory.isFull) + state = State.BANKING + else { + val farmer = scriptAPI.getNearestNode(NPCs.MASTER_FARMER_2234, false) + bot.interfaceManager.close() + scriptAPI.eat(food) + if (farmer != null) { + InteractionListeners.run(farmer.id, IntType.NPC, "Pickpocket", bot, farmer) + } + } + } + State.BANKING -> { + val bank = scriptAPI.getNearestNode("Bank Booth",true) + bank ?: return + if (!bankZone.insideBorder(bot)) + scriptAPI.walkTo(bankZone.randomLoc) + else { + bot.faceLocation(bank.location) + bot.inventory.clear() + bot.inventory.add(Item(food, foodAmount)) + state = State.PICKPOCKETING + } + } + } + } + + + + + override fun newInstance(): Script { + val script = FarmerThiever() + script.bot = SkillingBotAssembler().produce(SkillingBotAssembler.Wealth.POOR,bot.startLocation) + return script + } + enum class State { + BANKING, + PICKPOCKETING + } + + init { + inventory.add(Item(food,foodAmount)) + skills[Skills.THIEVING] = 80 + skills[Skills.HITPOINTS] = 10 + } + + +} \ No newline at end of file diff --git a/Server/src/main/content/global/bots/FletchingBankstander.kt b/Server/src/main/content/global/bots/FletchingBankstander.kt new file mode 100644 index 0000000..201dd6f --- /dev/null +++ b/Server/src/main/content/global/bots/FletchingBankstander.kt @@ -0,0 +1,45 @@ +package content.global.bots + +import core.game.node.entity.skill.Skills +import content.global.skill.fletching.Fletching +import content.global.skill.fletching.FletchingPulse +import core.game.node.item.Item +import org.rs09.consts.Items +import core.game.bots.SkillingBotAssembler +import core.game.bots.Script + +class FletchingBankstander : Script(){ + var state = State.FLETCHING + override fun tick() { + val bank = scriptAPI.getNearestNode("Bank booth") + bot.faceLocation(bank?.location) + state = when(state){ + State.FLETCHING -> { + bot.inventory.add(Item(Items.KNIFE_946)) + bot.inventory.add(Item(Items.LOGS_1511,27)) + bot.pulseManager.run(FletchingPulse(bot, Item(Items.LOGS_1511),27, Fletching.FletchingItems.ARROW_SHAFT)) + State.BANKING + } + + State.BANKING -> { + bot.inventory.clear() + State.FLETCHING + } + } + } + + init { + skills[Skills.FLETCHING] = 99 + } + + override fun newInstance(): Script { + val script = FletchingBankstander() + script.bot = SkillingBotAssembler().produce(SkillingBotAssembler.Wealth.AVERAGE,bot.startLocation) + return script + } + + enum class State { + FLETCHING, + BANKING + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/bots/GenericSlayerBot.kt b/Server/src/main/content/global/bots/GenericSlayerBot.kt new file mode 100644 index 0000000..5b4a7e3 --- /dev/null +++ b/Server/src/main/content/global/bots/GenericSlayerBot.kt @@ -0,0 +1,255 @@ +package content.global.bots + +import core.game.interaction.DestinationFlag +import core.game.interaction.MovementPulse +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import core.tools.RandomFunction +import org.rs09.consts.Items +import core.game.bots.AIRepository +import core.game.bots.Script + +/** + * A bot that does various random slayer tasks throughout the game and sells the loot on the GE. + * @author Ceikry + */ +class GenericSlayerBot : Script() { + var state = State.GETTING_TASK + var task = Task.CAVE_CRAWLER //default value to ensure non-nullability + var assignment = Assignment("",0) //same as above + var teleportFlag = false //have we teleported? + val FOOD_ID = Items.LOBSTER_379 + val varrockBankBorders = ZoneBorders(3184, 3435,3187, 3441) + + + + /** + * Per-tick actions (they don't run if the bot already has a pulse running, such as moving or combat.) + */ + override fun tick() { + scriptAPI.eat(FOOD_ID) //try to eat every tick (does nothing if health isn't low enough) + + when(state){ + + /** + * State that handles getting a new task + */ + State.GETTING_TASK -> { + populateTaskAndAssignment() + state = State.GOING_TO_HUB //switch states + } + + /** + * State that handles going to the "hub" for the task. Such as fremmy slayer cave or slayer tower. + */ + State.GOING_TO_HUB -> { + when(task.hub){ + + TaskHub.FREMENNIK_CAVE -> { + if(!teleportFlag) { + scriptAPI.teleport(Location.create(2781, 3615, 0)) //tele -> fremennik fairy ring + teleportFlag = !teleportFlag //teleportFlag -> true + } + else { + val entrance = scriptAPI.getNearestNode(4499,true) //returns the object if within render distance, null if not. + if(entrance == null || !entrance.location.withinDistance(bot.location,2)) { + scriptAPI.walkTo(Location.create(2796, 3615, 0)) + } else { + entrance.interaction.handle(bot,entrance.interaction[0]) //bot -> use interaction [0] of cave object + teleportFlag = !teleportFlag //teleportFlag -> false + state = State.KILLING_ENEMY //switch states + } + } + } + else -> {} + } + } + + + /** + * State used for combat. Handles moving the bot back into the zone for the monster and looting as well. + */ + State.KILLING_ENEMY -> { + val items = AIRepository.groundItems.get(bot) //retrieve drops that belong to this bot + if(items != null && items.isNotEmpty()){ //if we have loot... + if(bot.inventory.freeSlots() == 0){ + if(bot.inventory.contains(FOOD_ID,1)){ + scriptAPI.forceEat(FOOD_ID) + return + } + } + scriptAPI.takeNearestGroundItem(items.get(0).id) + if(bot.inventory.getAmount(Item(FOOD_ID)) == 0){ + state = State.GOING_TO_BANK + } + return + } + + if(assignment.amount > 0) { + if (task.borders.insideBorder(bot)) { //make sure bot is within the borders of the task's zone. + scriptAPI.attackNpcInRadius(bot, task.npc_name, 20) //attack nearest NPC with given task name within radius. + assignment.amount-- + } else { + scriptAPI.walkTo(task.borders.randomLoc) + } + } else { + state = State.GOING_TO_BANK //switch states and bank. + } + } + + /** + * State used to handle traveling to a bank. Due to the dynamic nature of where these bots might be + * in this state, they simply teleport to Varrock and then walk to the west bank to bank. + */ + State.GOING_TO_BANK -> { + if(!teleportFlag){ + scriptAPI.teleport(Location.create(3213, 3426, 0)) + teleportFlag = !teleportFlag + } else { + if(!varrockBankBorders.insideBorder(bot)) { + scriptAPI.walkTo(varrockBankBorders.randomLoc) + } else { + val bank = scriptAPI.getNearestNode("Bank Booth",true) + bank ?: return + /** + * Run a pulse that moves the bot to the bank booth and then faces it, and then swaps to the actual banking state + */ + bot.pulseManager.run(object: MovementPulse(bot,bank, DestinationFlag.OBJECT){ + override fun pulse(): Boolean { + bot.faceLocation(bank.location) + state = State.BANKING + teleportFlag = !teleportFlag + return true + } + }) + } + } + } + + /** + * State used to handle banking itself. Runs a pulse with a delay of 10 (to make it look like the bot is idling at the bank booth a bit.) + * the pulse adds every item in the bot's inventory to its bank and then clears the bot's inventory. Re-adds lobsters to the inventory afterwords. + */ + State.BANKING -> { + bot.pulseManager.run(object: Pulse(10){ + override fun pulse(): Boolean { + for(item in bot.inventory.toArray()){ + item ?: continue + if(item.checkIgnored()) continue + bot.bank.add(item) + } + bot.inventory.clear() + for(item in inventory) + bot.inventory.add(item) + scriptAPI.withdraw(Items.LOBSTER_379,10) + bot.fullRestore() + + if(assignment.amount <= 0){ + state = State.GOING_TO_GE + } else { + state = State.GOING_TO_HUB + } + + return true + } + }) + } + + + /** + * State used to handle travelling to the GE. + */ + State.GOING_TO_GE -> { + if(bot.location != Location.create(3165, 3487, 0)) { + scriptAPI.walkTo(Location.create(3165, 3487, 0)) + } else { + state = State.SELLING + } + } + + /** + * State used to handle selling items on the GE + */ + State.SELLING -> { + scriptAPI.sellAllOnGe() + state = State.GETTING_TASK + } + + } + } + + + /** + * Called when a bot needs to be regenerated, like when a bot dies. + */ + override fun newInstance(): Script { + TODO("Not yet implemented") + } + + /** + * Populate task and assignment vars + */ + fun populateTaskAndAssignment() { + task = Task.values().random() //get a new random task from the enum + assignment = Assignment(task.npc_name, RandomFunction.random(task.minAmt, task.maxAmt + 1)) //produce a new Assignment class with values from our Task. + } + + + /** + * Item extension function to check for ignored items when banking. + */ + fun Item.checkIgnored(): Boolean { + if(name.toLowerCase().contains("charm")) return true + if(name.toLowerCase().contains("lobster")) return true + if(name.toLowerCase().contains("clue")) return true + if(!definition.isTradeable) return true + return when(id){ + Items.BONES_2530 -> true + 995 -> true + else -> false + } + } + + /** + * The state enums + */ + enum class State { + GETTING_TASK, + GOING_TO_HUB, + KILLING_ENEMY, + GOING_TO_BANK, + BANKING, + GOING_TO_GE, + SELLING + } + + /** + * Assign default skills and initial inventory + */ + init { + skills[Skills.SLAYER] = 99 + inventory.add(Item(Items.LOBSTER_379,10)) + + } + + /** + * List of tasks that this bot can receive + */ + enum class Task(val npc_name: String, val minAmt: Int, val maxAmt: Int, val hub: TaskHub, val borders: ZoneBorders) { + CAVE_CRAWLER("Cave crawler",20,100, TaskHub.FREMENNIK_CAVE, ZoneBorders(2778, 9988,2798, 10002)) + } + + /** + * The task hubs + */ + enum class TaskHub { + FREMENNIK_CAVE, + SLAYER_TOWER, + TAVERLY_DUNGEON + } + + class Assignment(val npc_name: String, var amount: Int) //class used to keep track of current assignment and how many are left. +} \ No newline at end of file diff --git a/Server/src/main/content/global/bots/GlassBlowingBankstander.kt b/Server/src/main/content/global/bots/GlassBlowingBankstander.kt new file mode 100644 index 0000000..2e9e636 --- /dev/null +++ b/Server/src/main/content/global/bots/GlassBlowingBankstander.kt @@ -0,0 +1,45 @@ +package content.global.bots + +import content.global.skill.crafting.glass.GlassCraftingPulse +import content.global.skill.crafting.glass.GlassProduct +import core.game.bots.Script +import core.game.bots.SkillingBotAssembler +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import org.rs09.consts.Items + +class GlassBlowingBankstander : Script(){ + var state = State.BLOWING + override fun tick() { + val bank = scriptAPI.getNearestNode("Bank booth") + bot.faceLocation(bank?.location) + state = when(state){ + State.BLOWING -> { + bot.inventory.add(Item(Items.GLASSBLOWING_PIPE_1785)) + bot.inventory.add(Item(Items.MOLTEN_GLASS_1775,27)) + bot.pulseManager.run(GlassCraftingPulse(bot, GlassProduct.ORB, 27)) + State.BANKING + } + + State.BANKING -> { + bot.inventory.clear() + State.BLOWING + } + } + } + + override fun newInstance(): Script { + val script = GlassBlowingBankstander() + script.bot = SkillingBotAssembler().produce(SkillingBotAssembler.Wealth.AVERAGE,bot.startLocation) + return script + } + + init { + skills[Skills.CRAFTING] = 99 + } + + enum class State { + BLOWING, + BANKING + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/bots/GnomeAgility.kt b/Server/src/main/content/global/bots/GnomeAgility.kt new file mode 100644 index 0000000..7341ff4 --- /dev/null +++ b/Server/src/main/content/global/bots/GnomeAgility.kt @@ -0,0 +1,163 @@ +package content.global.bots + +import core.game.bots.* +import core.game.world.map.zone.ZoneBorders + + +@PlayerCompatible +@ScriptName("Gnome Agility Course Script") +@ScriptDescription("Start the script while standing front of the balancing log") +@ScriptIdentifier("gnome_agility") +class GnomeAgility : Script() { + + var state = State.INIT + val startzone = ZoneBorders(2473,3436,2475,3437,0) + val afterlog = ZoneBorders(2474,3429,2474,3429,0) + val beforefirstnet = ZoneBorders(2473,3426,2474,3427,0) + val afterfirstnet = ZoneBorders(2471,3424,2476,3424,1) + val beforebranchup = ZoneBorders(2473,3423,2473,3423,1) + val afterbranchup = ZoneBorders(2473,3420,2473,3420,2) + val beforerope = ZoneBorders(2477,3420,2477,3420,2) + val afterrope = ZoneBorders(2483,3420,2483,3420,2) + val beforebranchdown = ZoneBorders(2485,3419,2486,3420,2) + val afterbranchdown = ZoneBorders(2487,3420,2487,3420,0) + val beforesecondnet = ZoneBorders(2483,3425,2488,3425,0) + val aftersecondnet = ZoneBorders(2483,3427,2488,3427,0) + val beforepipe = ZoneBorders(2484,3430,2487,3430,0) + val afterpipe = ZoneBorders(2484,3437,2487,3437,0) + var overlay: ScriptAPI.BottingOverlay? = null + var totalLaps = 0 + + override fun tick() { + + when (state) { + + State.INIT -> { + overlay = scriptAPI.getOverlay() + overlay!!.init() + overlay!!.setTitle("Agility Course") + overlay!!.setTaskLabel("Laps Run") + overlay!!.setAmount(0) + + state = State.START + } + + State.START -> { + if(!startzone.insideBorder(bot)){ + scriptAPI.walkTo(startzone.randomLoc) + } + if(startzone.insideBorder(bot)){ + state = State.LOG + } + } + + State.LOG -> { + val log = scriptAPI.getNearestNode("log balance",true) + if(startzone.insideBorder(bot)) { + scriptAPI.interact(bot, log, "walk-across") + } + if(afterlog.insideBorder(bot)){ + state = State.FIRSTNET + } + } + + State.FIRSTNET -> { + val firstnet = scriptAPI.getNearestNode("obstacle net",true) + if(!beforefirstnet.insideBorder(bot)){ + scriptAPI.walkTo(beforefirstnet.randomLoc) + } + if(beforefirstnet.insideBorder(bot)) { + scriptAPI.interact(bot, firstnet, "climb-over") + } + if(afterfirstnet.insideBorder(bot)){ + state = State.BRANCHUP + } + } + + State.BRANCHUP -> { + val branchup = scriptAPI.getNearestNode("tree branch", true) + if(!beforebranchup.insideBorder(bot) && !afterbranchup.insideBorder(bot)){ + scriptAPI.walkTo(beforebranchup.randomLoc) + } + else if(beforebranchup.insideBorder(bot)){ + scriptAPI.interact(bot,branchup,"climb") + } + else if(afterbranchup.insideBorder(bot)){ + state = State.ROPE + } + } + + State.ROPE -> { + val rope = scriptAPI.getNearestNode("balancing rope",true) + if(!beforerope.insideBorder(bot) && !afterrope.insideBorder(bot)){ + scriptAPI.walkTo(beforerope.randomLoc) + } + else if(beforerope.insideBorder(bot)){ + scriptAPI.interact(bot,rope,"walk-on") + } + else if(afterrope.insideBorder(bot)){ + state = State.BRANCHDOWN + } + } + + State.BRANCHDOWN -> { + val branchdown = scriptAPI.getNearestNode("tree branch",true) + if(!beforebranchdown.insideBorder(bot) && !afterbranchdown.insideBorder(bot)){ + scriptAPI.walkTo(beforebranchdown.randomLoc) + } + else if(beforebranchdown.insideBorder(bot)){ + scriptAPI.interact(bot,branchdown,"climb-down") + } + else if(afterbranchdown.insideBorder(bot)){ + state = State.SECONDNET + } + } + + State.SECONDNET -> { + val secondnet = scriptAPI.getNearestNode("obstacle net",true) + if(!beforesecondnet.insideBorder(bot) && !aftersecondnet.insideBorder(bot)){ + scriptAPI.walkTo(beforesecondnet.randomLoc) + } + else if(beforesecondnet.insideBorder(bot)){ + scriptAPI.interact(bot,secondnet,"climb-over") + } + else if(aftersecondnet.insideBorder(bot)){ + state = State.PIPE + } + } + + State.PIPE -> { + val pipe = scriptAPI.getNearestNode("obstacle pipe",true) + if(!beforepipe.insideBorder(bot) && !afterpipe.insideBorder(bot)){ + scriptAPI.walkTo((beforepipe.randomLoc)) + } + if(beforepipe.insideBorder(bot)){ + scriptAPI.interact(bot,pipe,"squeeze-through") + } + if(afterpipe.insideBorder(bot)){ + totalLaps += 1 + overlay!!.setAmount(totalLaps) + state = State.START + } + } + } + } + + override fun newInstance(): Script { + val script = GnomeAgility() + script.bot = SkillingBotAssembler().produce(SkillingBotAssembler.Wealth.POOR,bot.startLocation) + return script + } + + enum class State { + START, + LOG, + FIRSTNET, + BRANCHUP, + ROPE, + BRANCHDOWN, + SECONDNET, + PIPE, + INIT + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/bots/GnomeBowstring.kt b/Server/src/main/content/global/bots/GnomeBowstring.kt new file mode 100644 index 0000000..a835aa3 --- /dev/null +++ b/Server/src/main/content/global/bots/GnomeBowstring.kt @@ -0,0 +1,175 @@ +package content.global.bots + +import core.api.* +import core.game.interaction.DestinationFlag +import core.game.interaction.MovementPulse +import content.global.skill.crafting.spinning.SpinningItem +import content.global.skill.crafting.spinning.SpinningPulse +import core.game.bots.* +import core.game.node.item.Item +import core.game.world.map.Location +import core.game.world.map.path.Pathfinder +import core.game.world.map.zone.ZoneBorders +import org.rs09.consts.Items + +@PlayerCompatible +@ScriptName("Gnome Stronghold Bowstring") +@ScriptDescription("Start in Gnome Stronghold, South of the Agility Course") +@ScriptIdentifier("gnome_bowstring") +class GnomeBowstring : Script() { + var state = State.PICKING + var stage = 0 + var bLadderSwitch = false + var sLadderSwitch = false + val flaxzone = ZoneBorders(2457,3391,2493,3413,0) + val bankbottomLadder = ZoneBorders(2444, 3413, 2445, 3414, 0) + val banktopLadder = ZoneBorders(2445, 3415, 2446, 3414, 1) + val spinnerbottomLadder = ZoneBorders (2475, 3400, 2476, 3399, 0) + val spinnertopLadder = ZoneBorders (2474, 3397, 2476, 3399, 1) + val pick = ZoneBorders(2478, 3394, 339, 9) + val bank = ZoneBorders(2447, 3415, 2444, 3434) + var overlay: ScriptAPI.BottingOverlay? = null + override fun tick() { + + when(state){ + + State.INIT -> { + overlay = scriptAPI.getOverlay() + overlay!!.init() + overlay!!.setTitle("Picking") + overlay!!.setTaskLabel("Flax Picked") + overlay!!.setAmount(0) + } + + State.PICKING -> { + bot.interfaceManager.close() + if(!flaxzone.insideBorder(bot)){ + scriptAPI.walkTo(flaxzone.randomLoc) + } else if(flaxzone.insideBorder(bot)) { + var flax = scriptAPI.getNearestNode(2646, true) + scriptAPI.interact(bot,flax,"pick") + } + if(bot.inventory.getAmount(Items.FLAX_1779) > 27){ + sLadderSwitch = true + state = State.TO_SPINNER + } + } + + State.TO_SPINNER -> { + if(sLadderSwitch){ + if(!spinnerbottomLadder.insideBorder(bot.location)){ + scriptAPI.walkTo(spinnerbottomLadder.randomLoc) + } else { + val ladder = scriptAPI.getNearestNode("Staircase", true) + if(ladder != null){ + ladder.interaction.handle(bot, ladder.interaction[0]) + sLadderSwitch = false + } else { + scriptAPI.walkTo(spinnerbottomLadder.randomLoc) + } + } + } + if(stage == 0) + Pathfinder.find(bot, Location.create(2475,3399, 1)).walk(bot).also { stage++ } + when(bot.location){ + Location.create(2475,3399, 1) -> Pathfinder.find(bot, Location.create(2477, 3399,1)).walk(bot) + Location.create(2477,3399, 1) -> Pathfinder.find(bot, Location.create(2477,3398, 1)).walk(bot) + Location.create(2477,3398, 1) -> Pathfinder.find(bot, Location.create(2476,3398, 1)).walk(bot) + Location.create(2476,3398, 1) -> { + val spinner = scriptAPI.getNearestNode(2644, true) + bot.faceLocation(spinner?.location) + bot.pulseManager.run(object: MovementPulse(bot,spinner, DestinationFlag.OBJECT){ + override fun pulse(): Boolean { + bot.faceLocation(spinner?.location) + state = State.SPINNING + return true + } + }) + } + } + } + + State.SPINNING -> { + bot.pulseManager.run(SpinningPulse(bot, Item(Items.FLAX_1779),bot.inventory.getAmount(Items.FLAX_1779), SpinningItem.FLAX)) + sLadderSwitch = true + state = State.FIND_BANK + } + + State.FIND_BANK -> { + if(sLadderSwitch){ + val ladder = scriptAPI.getNearestNode("staircase", true) + if(ladder != null){ + ladder.interaction.handle(bot, ladder.interaction[0]) + sLadderSwitch = false + } + } + if(!bankbottomLadder.insideBorder(bot.location) && !spinnertopLadder.insideBorder(bot)){ + scriptAPI.walkTo(bankbottomLadder.randomLoc) + }else if(bankbottomLadder.insideBorder(bot)){ + bLadderSwitch = true + } + if(bLadderSwitch){ + val ladder = scriptAPI.getNearestNode("staircase", true) + if(ladder != null){ + ladder.interaction.handle(bot, ladder.interaction[0]) + bLadderSwitch = false + } + } + if(banktopLadder.insideBorder(bot)){ + state = State.BANKING + } + } + + State.BANKING -> { + val bank = scriptAPI.getNearestNode(2213, true) + if(bank != null) { + bot.pulseManager.run(object : MovementPulse(bot, bank, DestinationFlag.OBJECT) { + override fun pulse(): Boolean { + bot.faceLocation(bank.location) + scriptAPI.bankItem(Items.BOW_STRING_1777) + return true + } + }) + } + if(freeSlots(bot) > 27){ + bLadderSwitch = true + state = State.RETURN_TO_FLAX + } + } + + State.RETURN_TO_FLAX -> { + if(!banktopLadder.insideBorder(bot.location) && bLadderSwitch){ + scriptAPI.walkTo(banktopLadder.randomLoc) + } else if(bLadderSwitch){ + val ladder = scriptAPI.getNearestNode("Staircase", true) + if(ladder != null){ + ladder.interaction.handle(bot, ladder.interaction[0]) + bLadderSwitch = false + } else { + scriptAPI.walkTo(banktopLadder.randomLoc) + } + } + if(!flaxzone.insideBorder(bot)){ + scriptAPI.walkTo(flaxzone.randomLoc) + } else if(flaxzone.insideBorder(bot)){ + state = State.PICKING + } + } + + else -> {} + } + } + override fun newInstance(): Script { + TODO("Not yet implemented") + } +} +enum class State { + PICKING, + MINING, + SPINNING, + TO_SPINNER, + FIND_BANK, + RETURN_TO_FLAX, + BANKING, + INIT +} diff --git a/Server/src/main/content/global/bots/GreenDragonKiller.kt b/Server/src/main/content/global/bots/GreenDragonKiller.kt new file mode 100644 index 0000000..740fb7c --- /dev/null +++ b/Server/src/main/content/global/bots/GreenDragonKiller.kt @@ -0,0 +1,286 @@ +package content.global.bots + +import content.global.skill.prayer.BoneBuryListener +import core.api.submitIndividualPulse +import core.game.interaction.DestinationFlag +import core.game.interaction.MovementPulse +import core.game.node.entity.Entity +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.combat.InteractionType +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.map.RegionManager +import core.game.world.map.zone.ZoneBorders +import core.game.world.map.zone.impl.WildernessZone +import core.tools.RandomFunction +import org.rs09.consts.Items +import core.game.bots.AIRepository +import core.game.bots.CombatBotAssembler +import core.game.bots.Script +import core.game.interaction.IntType +import core.game.interaction.InteractionListeners +import core.game.node.Node +import core.game.node.entity.combat.CombatSwingHandler +import core.game.node.entity.combat.MeleeSwingHandler +import kotlin.random.Random + +/** + * A bot script for killing green dragons in the wilderness.. Capable of banking, selling on ge, eating, trash talking, buries bones when fleeing and more. + * @param style The combat style the bot is going to use. + * @param area (optional) What area the bot tries to kill dragons in. + * @author Ceikry + */ +class GreenDragonKiller(val style: CombatStyle, area: ZoneBorders? = null) : Script() { + companion object { + val westDragons = ZoneBorders(2971,3606,2991,3628) + val wildernessLine = ZoneBorders(3078,3523,3096,3523) + val edgevilleLine = ZoneBorders(3078,3520,3096,3520) + val bankZone = ZoneBorders(3092,3489,3094,3493) + val trashTalkLines = arrayOf("Bro, seriously?", "Ffs.", "Jesus christ.", "????", "Friendly!", "Get a life dude", "Do you mind??? lol", "Lol.", "Kek.", "One sec burying all the bones.", "Yikes.", "Yeet", "Ah shit, here we go again.", "Cmonnnn", "Plz", "Do you have nothing better to do?", "Cmon bro pls", "I just need to get my prayer up bro jesus", "Reeeeeee", "I cant believe you've done this", "Really m8", "Zomg", "Aaaaaaaaaaaaaaaaaaaaa", "Rofl.", "Oh god oh fuck oh shit", "....", ":|", "A q p", "Hcim btw", "I hope the revenants kill your mum", "Wrap your ass titties", "Why do this", "Bruh", "Straight sussin no cap fr fr", "This ain't bussin dawg", "Really bro?") + } + var state = State.TO_BANK + var handler: CombatSwingHandler? = null + var lootDelay = 0 + var offerMade = false + var trashTalkDelay = 0 + + var food = if (Random.nextBoolean()){ + Items.LOBSTER_379 + } else if(Random.nextBoolean()){ + Items.SWORDFISH_373 + } else { + Items.SHARK_385 + } + + var myBorders: ZoneBorders? = null + val type = CombatBotAssembler.Type.MELEE + + override fun tick() { + if(!bot.isActive){ + running = false + return + } + + checkFoodStockAndEat() + + when(state){ + + State.KILLING -> { + bot.properties.combatPulse.temporaryHandler = handler + scriptAPI.attackNpcInRadius(bot,"Green dragon",20) + state = State.LOOT_DELAYER + } + + State.LOOT_DELAYER -> { + if(lootDelay < 3) + lootDelay++ + else + state = State.LOOTING + } + + + State.RUNNING -> { + val players = RegionManager.getLocalPlayers(bot.location) + if(players.isEmpty()){ + state = State.TO_DRAGONS + } else { + if(bot.skullManager.level < 21){ + if (scriptAPI.teleportToGE()) + state = State.REFRESHING + return + } + sendTrashTalk() + attemptToBuryBone() + scriptAPI.walkTo(WildernessZone.getInstance().borders.random().randomLoc) + } + } + + State.LOOTING -> { + lootDelay = 0 + val items = AIRepository.groundItems.get(bot) + if(items.isNullOrEmpty()) {state = State.KILLING; return} + if(bot.inventory.isFull) { + if(bot.inventory.containsItem(Item(food))){ + scriptAPI.forceEat(food) + } else { + state = State.TO_BANK + } + return + } + items.toTypedArray().forEach {it: Item -> scriptAPI.takeNearestGroundItem(it.id)} + } + + State.TO_BANK -> { + if(!wildernessLine.insideBorder(bot) && bot.location.y > 3521) + scriptAPI.walkTo(wildernessLine.randomLoc) + if(wildernessLine.insideBorder(bot)){ + val ditch = scriptAPI.getNearestNode("Wilderness Ditch",true) + ditch ?: return + ditch.interaction.handle(bot,ditch.interaction[0]) + } + if(!bankZone.insideBorder(bot)) + scriptAPI.walkTo(bankZone.randomLoc) + if(bankZone.insideBorder(bot)){ + val bank = scriptAPI.getNearestNode("Bank Booth",true) + bank ?: return + bot.pulseManager.run(object: MovementPulse(bot,bank, DestinationFlag.OBJECT){ + override fun pulse(): Boolean { + bot.faceLocation(bank.location) + state = State.BANKING + return true + } + }) + } + } + + State.BANKING -> { + bot.pulseManager.run(object: Pulse(25){ + override fun pulse(): Boolean { + for(item in bot.inventory.toArray()){ + item ?: continue + if(item.name.toLowerCase().contains("lobster") || item.name.toLowerCase().contains("swordfish") || item.name.toLowerCase().contains("shark")) continue + if(item.id == 995) continue + bot.bank.add(item) + } + bot.inventory.clear() + state = if(bot.bank.getAmount(food) < 10) + State.TO_GE + else + State.TO_DRAGONS + for(item in inventory) + bot.inventory.add(item) + scriptAPI.withdraw(food,10) + bot.fullRestore() + return true + } + }) + } + + State.BUYING_FOOD -> { + state = State.TO_DRAGONS + bot.bank.add(Item(food,50)) + bot.bank.refresh() + scriptAPI.withdraw(food, 10) + } + + State.TO_DRAGONS -> { + offerMade = false + if(bot.location.x >= 3143){ + if(bot.location != Location.create(3144, 3514, 0)) + scriptAPI.walkTo(Location.create(3144, 3514, 0)) + else { + val shortcut = scriptAPI.getNearestNode("Underwall Tunnel",true) + shortcut ?: return + InteractionListeners.run(shortcut.id, IntType.SCENERY, "climb-into", bot, shortcut) + } + } else { + if (!edgevilleLine.insideBorder(bot) && bot.location.y < 3520) { + scriptAPI.walkTo(edgevilleLine.randomLoc) + return + } + if (edgevilleLine.insideBorder(bot)) { + val ditch = scriptAPI.getNearestNode("Wilderness Ditch", true) + ditch ?: return + ditch.interaction.handle(bot, ditch.interaction[0]).also { return } + } + if (bot.location.y > 3520 && !myBorders!!.insideBorder(bot)) + scriptAPI.walkTo(myBorders!!.randomLoc).also { return } + if (myBorders!!.insideBorder(bot)) + state = State.KILLING + } + } + + State.TO_GE -> { + if(bot.location.x < 3143) { + if(bot.location == Location.create(3136, 3517, 0)){ + val shortcut = scriptAPI.getNearestNode("Underwall Tunnel",true) + shortcut ?: return + InteractionListeners.run(shortcut.id, IntType.SCENERY, "climb-into", bot, shortcut) + } else { + scriptAPI.walkTo(Location.create(3136, 3517, 0)) + } + return + } + if(bot.location != Location.create(3165, 3487, 0)) { + scriptAPI.walkTo(Location.create(3165, 3487, 0)) + } else { + state = State.SELL_GE + } + } + + State.SELL_GE -> { + scriptAPI.sellAllOnGe() + state = State.BUYING_FOOD + } + + State.REFRESHING -> { + running = false + return + } + + } + } + + private fun attemptToBuryBone() { + if (bot.inventory.containsAtLeastOneItem(Items.DRAGON_BONES_536)) { + InteractionListeners.run(Items.DRAGON_BONES_536, IntType.ITEM, "bury", bot, bot.inventory.get(Item(Items.DRAGON_BONES_536))) + } + } + + private fun checkFoodStockAndEat() { + if (bot.inventory.getAmount(food) < 3 && state == State.KILLING) + state = State.TO_BANK + scriptAPI.eat(food) + } + + private fun sendTrashTalk() { + if (trashTalkDelay-- == 0) + scriptAPI.sendChat(trashTalkLines.random()) + else + trashTalkDelay = RandomFunction.random(10, 30) + } + + override fun newInstance(): Script { + val script = GreenDragonKiller(style) + val tier = CombatBotAssembler.Tier.MED + script.bot = CombatBotAssembler().assembleMeleeDragonBot(tier, bot.startLocation) + return script + } + + enum class State { + KILLING, + RUNNING, + LOOTING, + LOOT_DELAYER, + BANKING, + TO_BANK, + TO_DRAGONS, + TO_GE, + SELL_GE, + REFRESHING, + BUYING_FOOD + + } + + init { + handler = MeleeSwinger(this) + equipment.add(Item(Items.ANTI_DRAGON_SHIELD_1540)) + myBorders = westDragons + skills[Skills.AGILITY] = 99 + bankZone.addException(ZoneBorders(3094, 3492,3094, 3492)) + bankZone.addException(ZoneBorders(3094, 3490,3094, 3490)) + } + + internal class MeleeSwinger(val script: GreenDragonKiller) : MeleeSwingHandler() { + override fun canSwing(entity: Entity, victim: Entity): InteractionType? { + if(victim is Player || victim.name.contains("revenant", ignoreCase = true)) { + script.state = State.RUNNING + script.bot.pulseManager.clear() + } + return super.canSwing(entity, victim) + } + } +} diff --git a/Server/src/main/content/global/bots/Idler.kt b/Server/src/main/content/global/bots/Idler.kt new file mode 100644 index 0000000..684f424 --- /dev/null +++ b/Server/src/main/content/global/bots/Idler.kt @@ -0,0 +1,12 @@ +package content.global.bots + +import core.game.bots.Script + +class Idler : Script(){ + override fun tick() { + } + + override fun newInstance(): Script { + return this + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/bots/LawCrafter.kt b/Server/src/main/content/global/bots/LawCrafter.kt new file mode 100644 index 0000000..16ff4a5 --- /dev/null +++ b/Server/src/main/content/global/bots/LawCrafter.kt @@ -0,0 +1,210 @@ +package content.global.bots + +import content.global.travel.ship.Ships +import core.cache.def.impl.ItemDefinition +import core.game.bots.* +import core.game.node.item.Item +import core.game.node.scenery.Scenery +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import org.rs09.consts.Items + + +@PlayerCompatible +@ScriptName("Law Rune Crafter") +@ScriptDescription("Crafts law runes. Start near Draynor bank w/ law tiara.") +@ScriptIdentifier("law_crafter") +class LawCrafter : Script() { + var state = State.INIT + var runeCounter = 0 + var overlay: ScriptAPI.BottingOverlay? = null + var startLocation = Location(0,0,0) + var timer = 0 + var bank = ZoneBorders(3092, 3242, 3092, 3245) + var boatNPC = Location(3047, 3234, 0) + var ruinsZone = ZoneBorders(2850, 3375, 2860, 3382) + var ruinPoint = Location(2857, 3380, 0) + var onBoat = ZoneBorders(2824, 3328, 2840, 3333) + var offBoat = ZoneBorders(2827, 3335, 2836, 3336) + var lawLocation = Location(2464, 4830, 0) + var lawZone = ZoneBorders(2439, 4808, 2488, 4855) + var returnNPC = Location(2835, 3335, 0) + var halfBank = Location(3069, 3275, 0) + + override fun tick() { + if (timer-- > 0) { + return + } + if (bot.settings.runEnergy > 10.0) { + bot.settings.isRunToggled = true + } + + when(state){ + State.INIT -> { + if (!bot.equipment.containsAtLeastOneItem(Items.LAW_TIARA_5545) || !ItemDefinition.canEnterEntrana(bot)) { + bot.sendMessage("Please equip a law tiara first.") + bot.sendMessage("AND REMOVE ALL WEAPONS AND ARMOR.") + state = State.INVALID + } else { + overlay = scriptAPI.getOverlay() + overlay!!.init() + overlay!!.setTitle("Law Runes") + overlay!!.setTaskLabel("Runes Crafted:") + overlay!!.setAmount(0) + startLocation = bot.location + state = State.BANKING + } + } + + State.BANKING -> { + endDialogue = true + bot.interfaceManager.closeChatbox() + bot.interfaceManager.openChatbox(137) + bot.interfaceManager.closeChatbox() + bot.dialogueInterpreter.close() + if(!bank.insideBorder(bot)) { + scriptAPI.walkTo(bank.randomLoc) + return + } + val runes = bot.inventory.getAmount(Item(Items.LAW_RUNE_563)) + if (runes > 0) { + runeCounter += runes + overlay!!.setAmount(runeCounter) + bot.sendMessage("You have crafted a total of: $runeCounter runes.") + scriptAPI.bankItem(Items.LAW_RUNE_563) + } else { + scriptAPI.withdraw(Items.PURE_ESSENCE_7936, 28) + state = State.HALF_BANK + } + } + + State.TO_BOAT_GUY -> { + var boatGuy = scriptAPI.getNearestNode(2729, false) + if (boatGuy != null){ + if (boatGuy.location.withinDistance(bot.location,2)) { + if (ItemDefinition.canEnterEntrana(bot)) { + endDialogue = false + Ships.PORT_SARIM_TO_ENTRANA.sail(bot) + state = State.CROSS_GANGPLANK + } else { + state = State.INVALID + } + } else { + scriptAPI.walkTo(boatGuy.location) + } + + } else { + scriptAPI.walkTo(boatNPC) + } + } + + State.CROSS_GANGPLANK -> { + if (onBoat.insideBorder(bot)) { + var gangplank = scriptAPI.getNearestNode(2415, true) + if (gangplank != null) { + scriptAPI.interact(bot, gangplank, "cross") + } + } else if (offBoat.insideBorder(bot)) { + state = State.RUNNING_TO_ALTER + endDialogue = true + } + } + + State.RUNNING_TO_ALTER -> { + if (lawZone.insideBorder(bot)) + state = State.CRAFTING + + val ruins = scriptAPI.getNearestNode(2459,true) + if (!ruinsZone.insideBorder(bot)) { + scriptAPI.walkTo(ruinPoint) + } else if (ruins != null && ruins.location.withinDistance(bot.location, 20)) { + val ruinsChild = (ruins as Scenery).getChild(bot) + scriptAPI.interact(bot, ruinsChild, "enter") + timer = 4 + } + } + + State.CRAFTING -> { + if (!lawZone.insideBorder(bot)) { + return + } + + if (bot.location != lawLocation) { + scriptAPI.walkTo(lawLocation) + } + + val alter = scriptAPI.getNearestNode(2485,true) + scriptAPI.interact(bot, alter, "craft-rune") + if(bot.inventory.containsAtLeastOneItem(Item(Items.LAW_RUNE_563))) + state = State.LEAVING_ALTER + } + + State.LEAVING_ALTER -> { + var portalOut = scriptAPI.getNearestNode(2472, true) + scriptAPI.interact(bot, portalOut, "use") + if (ruinsZone.insideBorder(bot)) { + state = State.RETURN_TO_BOAT_GUY + timer = 2 + } + } + + State.RETURN_TO_BOAT_GUY -> { + var boatGuy = scriptAPI.getNearestNode(2730, false) + if (boatGuy != null){ + if (boatGuy.location.withinDistance(bot.location,2)) { + endDialogue = false + Ships.ENTRANA_TO_PORT_SARIM.sail(bot) + state = State.HALF_BANK + } else { + scriptAPI.walkTo(boatGuy.location) + } + + } else { + scriptAPI.walkTo(returnNPC) + } + } + + // Splits up the journey into two parts. + // This is because the dialogue can't be ended until you are safely on the + // mainland side. But new chunks won't load while dialogue is still displayed. + State.HALF_BANK -> { + if (bot.inventory.containsAtLeastOneItem(Items.PURE_ESSENCE_7936)) { + if ( (bot.location.x - 2) > halfBank.x) { + scriptAPI.walkTo(halfBank) + } else { + state = State.TO_BOAT_GUY + } + } else { + if ( (bot.location.x + 2) < halfBank.x) { + scriptAPI.walkTo(halfBank) + } else { + state = State.BANKING + } + } + } + + State.INVALID -> { + timer = 25 + state = State.INIT + } + } + } + + override fun newInstance(): Script { + return this + } + + enum class State { + INIT, + BANKING, + TO_BOAT_GUY, + CROSS_GANGPLANK, + RUNNING_TO_ALTER, + CRAFTING, + LEAVING_ALTER, + RETURN_TO_BOAT_GUY, + HALF_BANK, + INVALID + } + +} diff --git a/Server/src/main/content/global/bots/LobsterCatcher.kt b/Server/src/main/content/global/bots/LobsterCatcher.kt new file mode 100644 index 0000000..9661d41 --- /dev/null +++ b/Server/src/main/content/global/bots/LobsterCatcher.kt @@ -0,0 +1,197 @@ +package content.global.bots + +import core.game.bots.* +import core.game.interaction.DestinationFlag +import core.game.interaction.MovementPulse +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.map.path.Pathfinder +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import core.tools.RandomFunction +import org.rs09.consts.Items +import core.game.interaction.IntType +import core.game.interaction.InteractionListeners +import core.game.world.GameWorld +import kotlin.random.Random + +@PlayerCompatible +@ScriptName("Catherby Lobs") +@ScriptDescription("Start in Catherby bank with a lobster pot in your inventory.") +@ScriptIdentifier("cath_lobs") +class LobsterCatcher : Script() { + private val ANIMATION = Animation(714) + val offers = HashMap() + val limit = 2000 + var myCounter = 0 + /** + * Represents the graphics to use. + */ + private val GRAPHICS = Graphics(308, 100, 50) + internal enum class Sets(val equipment: List) { + SET_1(listOf(Item(2643), Item(9470), Item(10756), Item(10394), Item(88), Item(9793))), + SET_2(listOf(Item(2643), Item(6585), Item(10750), Item(10394), Item(88), Item(9793))), + SET_3(listOf(Item(9472), Item(9470), Item(10750), Item(10394), Item(88), Item(9786))), + SET_4(listOf(Item(2639), Item(6585), Item(10752), Item(10394), Item(88), Item(9786))), + SET_5(listOf(Item(2639), Item(9470), Item(10750), Item(10394), Item(88), Item(9784))), + SET_6(listOf(Item(2639), Item(6585), Item(10750), Item(10394), Item(88), Item(9784))); + + } + + private var bots = 0 + private var lobstopper = false + var overlay: ScriptAPI.BottingOverlay?= null + var fishCounter = 0 + + private var state = State.INIT + private var tick = 0 + override fun tick() { + when(state){ + + State.INIT -> { + overlay = scriptAPI.getOverlay() + overlay!!.init() + overlay!!.setTitle("Fishing") + overlay!!.setTaskLabel("Lobs Caught:") + overlay!!.setAmount(0) + state = State.FIND_SPOT + } + + + State.BANKING -> { + fishCounter += bot.inventory.getAmount(Items.RAW_LOBSTER_377) + scriptAPI.bankItem(Items.RAW_LOBSTER_377) + state = State.IDLE + } + + + State.FISHING -> { + bot.interfaceManager.close() + val spot = scriptAPI.getNearestNode(333, false) + if(spot == null){ + state = State.IDLE + } else { + InteractionListeners.run(spot.id, IntType.NPC,"cage",bot,spot) + } + if(bot.inventory.isFull){ + state = State.FIND_BANK + } + overlay!!.setAmount(fishCounter + bot.inventory.getAmount(Items.RAW_LOBSTER_377)) + } + + State.IDLE -> { + if (Random.nextBoolean()){ + state = State.FIND_SPOT + } + else if(myCounter++ >= RandomFunction.random(1,25)){ + state = State.FIND_SPOT + } + } + + State.FIND_SPOT -> { + val spot = scriptAPI.getNearestNode(333, false) + if (spot != null) { + bot.walkingQueue.reset() + state = State.FISHING + } else { + if (bot.location.x < 2837) { + scriptAPI.walkTo(Location.create(2837, 3435, 0)) + } else { + scriptAPI.walkTo(Location.create(2854, 3427, 0)) + } + } + } + + + State.FIND_BANK -> { + val bank = scriptAPI.getNearestGameObject(bot.location, 2213) + class BankingPulse : MovementPulse(bot, bank, DestinationFlag.OBJECT) { + override fun pulse(): Boolean { + bot.faceLocation(bank!!.location) + state = State.BANKING + return true + } + } + if(bank != null){ + bot.pulseManager.run(BankingPulse()) + } else { + if (bot.location.x > 2837) { + Pathfinder.find(bot, Location.create(2837, 3435, 0)).walk(bot) + } else if (bot.location.x > 2821) { + Pathfinder.find(bot, Location.create(2821, 3435, 0)).walk(bot) + } else if (bot.location.x > 2809){ + Pathfinder.find(bot,Location.create(2809, 3436, 0)).walk(bot) + } + } + } + + + State.TELEPORT_GE -> { + scriptAPI.teleportToGE() + state = State.SELL_GE + } + + + State.SELL_GE -> { + scriptAPI.sellOnGE(Items.RAW_LOBSTER_377) + state = State.TELE_CATH + } + + State.TELE_CATH -> { + if(tick++ == 10) { + bot.lock() + bot.visualize(ANIMATION, GRAPHICS) + bot.impactHandler.disabledTicks = 4 + val location = Location.create(2819, 3437, 0) + GameWorld.Pulser.submit(object : Pulse(4, bot) { + override fun pulse(): Boolean { + bot.unlock() + bot.properties.teleportLocation = location + bot.animator.reset() + state = State.IDLE + return true + } + }) + } + } + + + } + } + + + init { + val setUp = RandomFunction.random(Sets.values().size) + equipment.addAll(Sets.values()[setUp].equipment) + inventory.add(Item(301)) + skills[Skills.FISHING] = 40 + } + + enum class State{ + FISHING, + BANKING, + FIND_BANK, + FIND_SPOT, + TELEPORT_GE, + SELL_GE, + TELE_CATH, + IDLE, + INIT + } + + override fun newInstance(): Script { + if (!lobstopper && bots <= 0) { + val script = LobsterCatcher() + script.bot = AIPlayer(bot.startLocation) + script.state = State.FIND_SPOT + bots = 1 + return script + }else if (tick++ == 6000 && lobstopper) { + tick = 0 + lobstopper = false + } + return newInstance() + } +} diff --git a/Server/src/main/content/global/bots/ManThiever.kt b/Server/src/main/content/global/bots/ManThiever.kt new file mode 100644 index 0000000..25a2638 --- /dev/null +++ b/Server/src/main/content/global/bots/ManThiever.kt @@ -0,0 +1,27 @@ +package content.global.bots + +import core.game.node.item.Item +import core.game.bots.SkillingBotAssembler +import core.game.bots.Script +import core.game.interaction.IntType +import core.game.interaction.InteractionListeners +import java.util.* + +class ManThiever : Script() { + override fun tick() { + val man = scriptAPI.getNearestNode("Man") + bot.interfaceManager.close() + man?.let { InteractionListeners.run(man.id, + IntType.NPC,"Pickpocket",bot,man) } + } + + override fun newInstance(): Script? { + val script = ManThiever() + script.bot = SkillingBotAssembler().produce(SkillingBotAssembler.Wealth.POOR, bot.startLocation) + return script + } + + init { + equipment.addAll(Arrays.asList(Item(1103), Item(1139), Item(1265))) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/bots/NatureCrafter.kt b/Server/src/main/content/global/bots/NatureCrafter.kt new file mode 100644 index 0000000..02f8248 --- /dev/null +++ b/Server/src/main/content/global/bots/NatureCrafter.kt @@ -0,0 +1,173 @@ +package content.global.bots + +import content.global.skill.runecrafting.MysteriousRuin +import core.api.teleport +import core.game.bots.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListeners +import core.game.node.entity.player.link.TeleportManager +import core.game.node.item.Item +import core.game.node.scenery.Scenery +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import org.rs09.consts.Items + + +@PlayerCompatible +@ScriptName("Nature Rune Crafter") +@ScriptDescription("Crafts nat runes. Start in Zanaris w/ dramen staff + Nat tiara.") +@ScriptIdentifier("nature_crafter") +class NatureCrafter : Script() { + var state = State.INIT + var runeCounter = 0 + var overlay: ScriptAPI.BottingOverlay? = null + var startLocation = Location(0,0,0) + var timer = 0 + var teleWaitTime = 16 // 18 ticks needed to rotate the clocks, 2 to teleport + var bank = Location(2384, 4457) + var ruinsZone = ZoneBorders(2866, 3017, 2873, 3022) + var faeRingDestination = Location(2412, 4435, 0) // You don't walk to the fae rings + // you can only walk next to them. so path to the nearest point that isn't in the ring. + var faeRingCenter = Location(2412, 4434, 0) + var karamjaRingDestination = Location(2801, 3002, 0) + var karamjaRingCenter = Location(2801, 3003, 0) + var natureZone = ZoneBorders(2387, 4828, 2416, 4856) + override fun tick() { + if (timer-- > 0) { + return + } + if (bot.settings.runEnergy > 10.0) { + bot.settings.isRunToggled = true + } + + when(state){ + State.INIT -> { + if (checkValid()) { + overlay = scriptAPI.getOverlay() + overlay!!.init() + overlay!!.setTitle("Nature Runes") + overlay!!.setTaskLabel("Runes Crafted:") + overlay!!.setAmount(0) + startLocation = bot.location + state = State.BANKING + } + } + + State.BANKING -> { + if(bot.location != bank) { + scriptAPI.walkTo(bank) + return + } + val runes = bot.inventory.getAmount(Item(Items.NATURE_RUNE_561)) + if (runes > 0) { + runeCounter += runes + overlay!!.setAmount(runeCounter) + bot.sendMessage("You have crafted a total of: $runeCounter runes.") + scriptAPI.bankItem(Items.NATURE_RUNE_561) + } else { + scriptAPI.withdraw(Items.PURE_ESSENCE_7936, 28) + state = State.RUNNING_TO_TELE + } + } + + State.RUNNING_TO_TELE -> { + if (bot.location != faeRingDestination) { + scriptAPI.walkTo(faeRingDestination) + } else { + if (checkValid()) { + timer = teleWaitTime + state = State.TELE_WAIT + bot.sendMessage("Entering Fairy Ring Codes. Please wait...") + } + } + } + + State.TELE_WAIT -> { + teleport(bot, karamjaRingCenter, TeleportManager.TeleportType.FAIRY_RING) + state = State.RUNNING_TO_ALTER + // tele takes 4 ticks so wait that long. + timer = 4 + } + + State.RETURN_WAIT -> { + teleport(bot, faeRingCenter, TeleportManager.TeleportType.FAIRY_RING) + state = State.BANKING + } + + State.RUNNING_TO_ALTER -> { + val ruins = scriptAPI.getNearestNode(2460,true) + if (natureZone.insideBorder(bot)) + state = State.CRAFTING + + if (!ruinsZone.insideBorder(bot)) { + scriptAPI.walkTo(ruinsZone.randomLoc) + } else if (ruins != null && ruins.location.withinDistance(bot.location, 20) && checkValid()) { + val ruinsChild = (ruins as Scenery).getChild(bot) + scriptAPI.interact(bot, ruinsChild, "enter") + timer = 4 + } + } + + State.CRAFTING -> { + val alter = scriptAPI.getNearestNode(2486,true) + scriptAPI.interact(bot, alter, "craft-rune") + if(bot.inventory.containsAtLeastOneItem(Item(Items.NATURE_RUNE_561))) + state = State.LEAVING_ALTER + } + + State.LEAVING_ALTER -> { + var portalOut = scriptAPI.getNearestNode(2473, true) + scriptAPI.interact(bot, portalOut, "use") + if (ruinsZone.insideBorder(bot)) + state = State.RETURNING_TO_TELE + } + + State.RETURNING_TO_TELE -> { + if (bot.location != karamjaRingDestination) { + scriptAPI.walkTo(karamjaRingDestination) + } else { + if (checkValid()) { + var portalOut = scriptAPI.getNearestNode(14130, true) + portalOut?.interaction?.handle(bot, portalOut.interaction[0]) + timer = 4 + state = State.RETURN_WAIT + } + } + } + + State.INVALID -> { + timer = 25 + state = State.INIT + } + } + } + + + // Terminates if you have invalid inventory to avoid cheating + private fun checkValid(): Boolean { + if (!bot.equipment.containsAtLeastOneItem(Items.DRAMEN_STAFF_772) or !bot.equipment.containsAtLeastOneItem(Items.NATURE_TIARA_5541)) { + bot.sendMessage("Please equip a dramen staff and nature tiara first.") + state = State.INVALID + return false + } + return true + } + + override fun newInstance(): Script { + return this + } + + enum class State { + INIT, + BANKING, + RUNNING_TO_TELE, + TELE_WAIT, + RUNNING_TO_ALTER, + CRAFTING, + LEAVING_ALTER, + RETURNING_TO_TELE, + RETURN_WAIT, + INVALID + } + +} diff --git a/Server/src/main/content/global/bots/NonBankingMiner.kt b/Server/src/main/content/global/bots/NonBankingMiner.kt new file mode 100644 index 0000000..909d0a4 --- /dev/null +++ b/Server/src/main/content/global/bots/NonBankingMiner.kt @@ -0,0 +1,41 @@ +package content.global.bots + +import core.api.produceGroundItem +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import org.rs09.consts.Items +import core.game.bots.SkillingBotAssembler +import core.game.bots.Script +import core.game.interaction.IntType +import core.game.interaction.InteractionListeners + +class NonBankingMiner : Script() { + override fun tick() { + val rock = scriptAPI.getNearestNode(11957,true) + if(rock != null && !bot.inventory.isFull){ + InteractionListeners.run(rock.id, IntType.SCENERY,"mine",bot,rock) + } + //checks if the bot has tin ore in his inventory and drops it if he does + if(bot.inventory.containsAtLeastOneItem(Items.TIN_ORE_438)){ + produceGroundItem(bot,438,1,bot.location) + bot.inventory.remove(Item(Items.TIN_ORE_438,1)) + } + //The following is to prevent lucky bots from breaking by having a full inventory of gems + if(bot.inventory.isFull && (!bot.inventory.containsAtLeastOneItem(Items.TIN_ORE_438))){ + bot.inventory.clear() + bot.inventory.add(Item(Items.MITHRIL_PICKAXE_1273)) + } + } + + override fun newInstance(): Script { + val script = NonBankingMiner() + script.bot = SkillingBotAssembler().produce(SkillingBotAssembler.Wealth.POOR,bot.startLocation) + return script + } + + init { + skills[Skills.ATTACK] = 99 + inventory.add(Item(Items.MITHRIL_PICKAXE_1273)) + skills[Skills.MINING] = 50 + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/bots/SeersFlax.kt b/Server/src/main/content/global/bots/SeersFlax.kt new file mode 100644 index 0000000..d399420 --- /dev/null +++ b/Server/src/main/content/global/bots/SeersFlax.kt @@ -0,0 +1,155 @@ +package content.global.bots + +import core.game.interaction.DestinationFlag +import core.game.interaction.MovementPulse +import core.game.node.entity.skill.Skills +import content.global.skill.crafting.spinning.SpinningItem +import content.global.skill.crafting.spinning.SpinningPulse +import core.game.node.item.Item +import core.game.world.map.Location +import core.game.world.map.path.Pathfinder +import org.rs09.consts.Items +import core.game.bots.SkillingBotAssembler +import core.game.bots.Script + +class SeersFlax : Script(){ + var state = State.PICKING + var stage = 0 + var doorOpen = false + override fun tick() { + + when(state){ + + State.PICKING -> { + val flax = scriptAPI.getNearestNode(2646,true) + flax?.interaction?.handle(bot,flax.interaction[1]) + if(bot.inventory.getAmount(Items.FLAX_1779) > 25){ + state = State.TO_SPINNER + } + } + + State.TO_SPINNER -> { + if(stage == 0) + Pathfinder.find(bot, Location.create(2736, 3442, 0)).walk(bot).also { stage++ } + when(bot.location){ + Location.create(2736, 3442, 0) -> Pathfinder.find(bot,Location.create(2722, 3456, 0)).walk(bot) + Location.create(2722, 3456, 0) -> Pathfinder.find(bot,Location.create(2716, 3472, 0)).walk(bot) + Location.create(2716, 3472, 0) -> { + val door = scriptAPI.getNearestNode(25819,true) + if(door != null && door.location?.withinDistance(bot.location,2)!!){ + door.interaction?.handle(bot, door.interaction[0]) + doorOpen = true + } else { + val ladder = scriptAPI.getNearestNode(25938,true) + ladder?.interaction?.handle(bot,ladder.interaction[0]) } + } + Location.create(2714, 3470, 1) -> { + val spinner = scriptAPI.getNearestNode(25824,true) + bot.faceLocation(spinner?.location) + bot.pulseManager.run(object: MovementPulse(bot,spinner, DestinationFlag.OBJECT){ + override fun pulse(): Boolean { + bot.faceLocation(spinner?.location) + state = State.SPINNING.also { stage = 0; doorOpen = false } + return true + } + }) + } + } + } + + State.SPINNING -> { + bot.pulseManager.run(SpinningPulse(bot, Item(Items.FLAX_1779),bot.inventory.getAmount(Items.FLAX_1779), SpinningItem.FLAX)) + state = State.FIND_BANK + } + + State.FIND_BANK -> { + when(bot.location){ + Location.create(2711, 3471, 1) -> { + val ladder = scriptAPI.getNearestNode(25939,true) ?: return + ladder.interaction?.handle(bot,ladder.interaction[0]) + } + Location.create(2714, 3470, 0) -> Pathfinder.find(bot,Location.create(2715, 3472, 0)).walk(bot) + Location.create(2715, 3472, 0) -> { + val door = scriptAPI.getNearestNode(25819,true) + if(door != null && door.location?.withinDistance(bot.location,2)!!){ + door.interaction?.handle(bot, door.interaction[0]) + doorOpen = true + } else { + Pathfinder.find(bot,Location.create(2726, 3481, 0)).walk(bot) + } + } + Location.create(2726, 3481, 0) -> Pathfinder.find(bot,Location.create(2724, 3491, 0)).walk(bot) + Location.create(2724, 3491, 0) -> state = State.BANKING + } + } + + State.BANKING -> { + val bank = scriptAPI.getNearestNode(25808,true) + if(bank != null) + bot.pulseManager.run(object: MovementPulse(bot,bank, DestinationFlag.OBJECT){ + override fun pulse(): Boolean { + bot.faceLocation(bank.location) + scriptAPI.bankItem(Items.BOW_STRING_1777) + if(bot.bank.getAmount(Items.BOW_STRING_1777) > 500){ + state = State.TELE_GE + return true + } + state = State.RETURN_TO_FLAX + return true + } + }) + } + + State.RETURN_TO_FLAX -> { + if(bot.location == Location.create(2756, 3478, 0)) + Pathfinder.find(bot,Location.create(2726, 3486, 0)).walk(bot) + if(stage == 0) + Pathfinder.find(bot,Location.create(2726, 3486, 0)).walk(bot).also { stage++ } + when(bot.location){ + Location.create(2726, 3486, 0) -> Pathfinder.find(bot,Location.create(2729, 3469, 0)).walk(bot) + Location.create(2729, 3469, 0) -> Pathfinder.find(bot,Location.create(2734, 3447, 0)).walk(bot) + Location.create(2734, 3447, 0) -> state = State.PICKING.also { stage = 0 } + } + } + + State.TELE_GE -> { + scriptAPI.teleportToGE() + state = State.SELL_GE + } + + State.SELL_GE -> { + scriptAPI.sellOnGE(Items.BOW_STRING_1777) + state = State.TELE_CAMELOT + } + + State.TELE_CAMELOT -> { + scriptAPI.teleport(Location.create(2756, 3478, 0)) + stage = 0 + state = State.RETURN_TO_FLAX + } + + } + } + + enum class State { + PICKING, + SPINNING, + TO_SPINNER, + FIND_BANK, + BANKING, + TELE_GE, + SELL_GE, + RETURN_TO_FLAX, + TELE_CAMELOT + } + + init { + skills[Skills.CRAFTING] = 10 + } + + override fun newInstance(): Script { + val script = SeersFlax() + script.bot = SkillingBotAssembler().produce(SkillingBotAssembler.Wealth.POOR,bot.startLocation) + return script + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/bots/SeersMagicTrees.kt b/Server/src/main/content/global/bots/SeersMagicTrees.kt new file mode 100644 index 0000000..c3e3384 --- /dev/null +++ b/Server/src/main/content/global/bots/SeersMagicTrees.kt @@ -0,0 +1,118 @@ +package content.global.bots + +import core.game.bots.* +import core.game.interaction.DestinationFlag +import core.game.interaction.MovementPulse +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import core.tools.RandomFunction +import org.rs09.consts.Items +import core.game.interaction.IntType +import core.game.interaction.InteractionListeners + +@PlayerCompatible +@ScriptName("Seers Magics") +@ScriptDescription("Start in Seers Bank with an axe equipped or in your inventory.") +@ScriptIdentifier("seers_magics") +class SeersMagicTrees : Script(){ + var state = State.INIT + var stage = 0 + val bankZone = ZoneBorders(2722,3490,2727,3493) + val magicsZone = ZoneBorders(2700, 3396,2704, 3399) + var overlay: ScriptAPI.BottingOverlay? = null + var logCounter = 0 + + override fun tick() { + when(state){ + + State.INIT -> { + overlay = scriptAPI.getOverlay() + overlay!!.init() + overlay!!.setTitle("Woodcutting") + overlay!!.setTaskLabel("Logs cut:") + overlay!!.setAmount(0) + state = State.RETURN_TO_TREES + } + + State.CHOPPING -> { + val tree = scriptAPI.getNearestNode(1306,true) + bot.interfaceManager.close() + tree?.let { InteractionListeners.run(tree.id, IntType.SCENERY,"Chop down",bot,tree) } + if(bot.inventory.isFull){ + state = State.FIND_BANK + } + overlay!!.setAmount(logCounter + bot.inventory.getAmount(Items.MAGIC_LOGS_1513)) + } + + State.FIND_BANK -> { + if(!bankZone.insideBorder(bot)){ + scriptAPI.walkTo(bankZone.randomLoc) + } else { + state = State.BANKING + } + } + + State.BANKING -> { + val bank = scriptAPI.getNearestNode(25808,true) + if(bank != null) + bot.pulseManager.run(object: MovementPulse(bot,bank, DestinationFlag.OBJECT){ + override fun pulse(): Boolean { + bot.faceLocation(bank.location) + logCounter += bot.inventory.getAmount(Items.MAGIC_LOGS_1513) + scriptAPI.bankItem(Items.MAGIC_LOGS_1513) + state = State.RETURN_TO_TREES + return true + } + }) + } + + State.RETURN_TO_TREES -> { + bot.interfaceManager.close() + if(!magicsZone.insideBorder(bot)){ + scriptAPI.walkTo(magicsZone.randomLoc) + } else { + state = State.CHOPPING + } + } + + State.TELE_GE -> { + state = State.SELL_GE + scriptAPI.teleportToGE() + } + + State.SELL_GE -> { + state = State.TELE_SEERS + scriptAPI.sellOnGE(Items.MAGIC_LOGS_1513) + } + + State.TELE_SEERS -> { + state = State.RETURN_TO_TREES + scriptAPI.teleport(Location.create(2756, 3478, 0)) + } + } + } + + init { + inventory.add(Item(Items.RUNE_AXE_1359)) + skills[Skills.WOODCUTTING] = RandomFunction.random(75,99) + } + + enum class State { + CHOPPING, + FIND_BANK, + BANKING, + RETURN_TO_TREES, + TELE_GE, + SELL_GE, + TELE_SEERS, + INIT + } + + override fun newInstance(): Script { + val script = SeersMagicTrees() + script.bot = SkillingBotAssembler().produce(SkillingBotAssembler.Wealth.AVERAGE,bot.startLocation) + return script + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/bots/SharkCatcher.kt b/Server/src/main/content/global/bots/SharkCatcher.kt new file mode 100644 index 0000000..f7fa50e --- /dev/null +++ b/Server/src/main/content/global/bots/SharkCatcher.kt @@ -0,0 +1,223 @@ +package content.global.bots + +import core.game.bots.* +import core.game.interaction.DestinationFlag +import core.game.interaction.MovementPulse +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.world.map.Location +import core.tools.RandomFunction +import org.rs09.consts.Items +import core.game.interaction.IntType +import core.game.interaction.InteractionListeners +import kotlin.random.Random + +/* +Grabs all amounts in GE +val offers = HashMap() +for (offer in GEOfferDispatch.offerMapping.values) { + val item = offer.itemId + val amount = offer.amount - offer.completedAmount + if (offers[item] == null) { offers[item] = amount } + else { offers[item] = offers[item]!!.plus(amount) } + + if (offers[383]!!.plus(amount) >= 1000) { +*/ +/* +Grabs just one offer +for (offer in GEOfferDispatch.offerMapping.values) { +if (offer.itemId == 383 && offer.amount >= 1000) { +*/ +/** + * A bot script for fishing sharks in the Fishing Guild - Fishes, Banks, Sells. + * @param mycounter used in the bots random idling function. + * @param pause is currently not used. + * @param limit is the number of Raw Sharks in the GE the bots will sleep at. + * @author Sir Kermit + * Training Wheel Manufacturer @Ceikry + * Very slight ge modifications by @Angle + */ +@PlayerCompatible +@ScriptName("Guild Sharks") +@ScriptDescription("Start in the fishing guild with a harpoon","in your inventory.") +@ScriptIdentifier("guild_sharks") +class SharkCatcher : Script() { + //val shark = Items.RAW_SHARK + val pause = (1000..3000) + val limit = 5000 + var myCounter = 0 + //val fishzone = ZoneBorders(2597, 3410, 2612, 3426) + internal enum class Sets(val equipment: List) { + SET_1(listOf(Item(10721), Item(8283), Item(10412), Item(10414), Item(88), Item(1007))), + SET_2(listOf(Item(10721), Item(8283), Item(10412), Item(10414), Item(88), Item(1007))), + SET_3(listOf(Item(10721), Item(8283), Item(10412), Item(10414), Item(88), Item(1019))), + SET_4(listOf(Item(10721), Item(8283), Item(10412), Item(10414), Item(88), Item(1019))), + SET_5(listOf(Item(10721), Item(8283), Item(10412), Item(10414), Item(88), Item(3765))), + SET_6(listOf(Item(10721), Item(8283), Item(10412), Item(10414), Item(88), Item(3765))); + + } + private var state = State.INIT + private var tick = 0 + var fishCounter = 0 + var overlay: ScriptAPI.BottingOverlay?= null + + override fun tick() { + val fishguild = Location.create(2596, 3410, 0) + if (tick++ >= 500){ + scriptAPI.teleport(fishguild) + state = State.FIND_SPOT + return + } + when(state){ + + State.INIT -> { + overlay = scriptAPI.getOverlay() + overlay!!.init() + overlay!!.setTitle("Fishing") + overlay!!.setTaskLabel("Sharks Caught:") + overlay!!.setAmount(0) + state = State.FIND_SPOT + } + + State.BANKING -> { + fishCounter += bot.inventory.getAmount(Items.RAW_SHARK_383) + scriptAPI.bankItem(Items.RAW_SHARK_383) + state = State.FIND_SPOT + } + + State.STOP -> { + val botAmount = bot.bank.getAmount(Items.RAW_SHARK_383) + 1 + var geAmount = 0//OfferManager.getQuantitySoldForItem(Items.RAW_SHARK_383) + val totalAmount = (geAmount + botAmount) + 1 + if((totalAmount > limit) && myCounter++ == 300){ + bot.randomWalk(5,5) + myCounter = 0 + return + } else if (myCounter++ == 300){ + myCounter = 0 + State.TELE_FISH + } + return + + } + + State.IDLE -> { + if (Random.nextBoolean()){ + state = State.FIND_SPOT + } + else if(myCounter++ >= RandomFunction.random(1,25)){ + myCounter = 0 + state = State.FIND_SPOT + } + } + + State.FISHING -> { + bot.interfaceManager.close() + if (Random.nextBoolean()) { + tick = 0 + val spot = scriptAPI.getNearestNode(334, false) + spot?.let { InteractionListeners.run(spot.id, IntType.NPC,"harpoon",bot,spot) } + if(bot.inventory.isFull){ + state = State.FIND_BANK + } else { + state = State.IDLE + } + } + else{ + state = State.IDLE + } + overlay!!.setAmount(fishCounter + bot.inventory.getAmount(Items.RAW_SHARK_383)) + } + + State.FIND_SPOT -> { + val spot = scriptAPI.getNearestNode(334, false) + if (spot != null) { + bot.walkingQueue.reset() + state = State.FISHING + } else { + if(bot.location.x < 2591) { + scriptAPI.walkTo(Location.create(2604, 3421, 0)) + } else { + scriptAPI.walkTo(Location.create(2608, 3414, 0)) + } + } + } + + State.FIND_BANK -> { + val bank = scriptAPI.getNearestGameObject(bot.location, 2213) + class BankingPulse : MovementPulse(bot, bank, DestinationFlag.OBJECT) { + override fun pulse(): Boolean { + bot.faceLocation(bank!!.location) + state = State.BANKING + return true + } + } + if(bank != null){ + bot.pulseManager.run(BankingPulse()) + } else { + if (bot.location.x != 2596) { + scriptAPI.walkTo(Location.create(2596, 3415, 0)) + } else if (bot.location.x < 2591) { + scriptAPI.walkTo(Location.create(2591, 3415, 0)) + } else if (bot.location.x < 2587){ + scriptAPI.walkTo(Location.create(2587, 3420, 0)) + } + } + } + + State.TELEPORT_GE -> { + scriptAPI.teleportToGE() + state = State.SELL_GE + } + + State.SELL_GE -> { + val botAmount = bot.bank.getAmount(Items.RAW_SHARK_383) + 1 + var geAmount = 0//OfferManager.getQuantitySoldForItem(Items.RAW_SHARK_383) + val totalAmount = (geAmount + botAmount) + 1 + if(totalAmount > limit){ + scriptAPI.walkTo(Location.create(3164, 3487, 0)) + scriptAPI.sellOnGE(Items.RAW_SHARK_383) + state = State.STOP//.also { println("STOPPING") } + } else { + scriptAPI.walkTo(Location.create(3164, 3487, 0)) + scriptAPI.sellOnGE(Items.RAW_SHARK_383) + state = State.TELE_FISH + } + } + + State.TELE_FISH -> { + scriptAPI.teleport(fishguild) + state = State.FIND_SPOT + } + + + } + } + + + init { + val setUp = RandomFunction.random(Sets.values().size) + equipment.addAll(Sets.values()[setUp].equipment) + inventory.add(Item(311)) + skills[Skills.FISHING] = 90 + } + + enum class State{ + FISHING, + BANKING, + FIND_BANK, + FIND_SPOT, + TELEPORT_GE, + SELL_GE, + TELE_FISH, + IDLE, + STOP, + INIT + } + override fun newInstance(): Script { + val script = SharkCatcher() + script.bot = AIPlayer(bot.startLocation) + script.state = State.FIND_SPOT + return script + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/bots/ShootingStarBot.kt b/Server/src/main/content/global/bots/ShootingStarBot.kt new file mode 100644 index 0000000..5e990b8 --- /dev/null +++ b/Server/src/main/content/global/bots/ShootingStarBot.kt @@ -0,0 +1,95 @@ +package content.global.bots + +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.world.map.Location +import core.tools.RandomFunction +import org.rs09.consts.Items +import core.game.bots.GeneralBotCreator +import content.global.activity.shootingstar.ShootingStarPlugin +import core.game.bots.Script +import core.game.interaction.IntType +import core.game.interaction.InteractionListeners + +class ShootingStarBot : Script() { + private var state = State.FULL_IDLE + private var timerCountdown = 0 + val star = ShootingStarPlugin.getStar() + + override fun tick() { + bot.fullRestore() + + if(timerCountdown > 0) { + --timerCountdown + return + } + + when(state) { + State.FULL_IDLE -> {} + + State.TELEPORT_TO -> { + scriptAPI.teleport(star.crash_locations[star.location]!!.transform(0, -1, 0)) + state = State.MINING + timerCountdown = 15 + } + + State.MINING -> { + InteractionListeners.run(star.starObject.id, IntType.SCENERY, "mine", bot, star.starObject) + } + + State.TELEPORT_BACK -> { + scriptAPI.teleport(spawnLoc) + timerCountdown = 15 + } + } + } + + init { + skills[Skills.ATTACK] = 41 + skills[Skills.RANGE] = RandomFunction.random(30,99) + skills[Skills.MINING] = 99 + skills[Skills.HITPOINTS] = 99 + skills[Skills.DEFENCE] = 99 + skills[Skills.SUMMONING] = 99 + skills[Skills.PRAYER] = 99 + inventory.add(Item(Items.RUNE_PICKAXE_1275)) + } + + override fun newInstance(): Script { + return ShootingStarBot() + } + + fun activate(instant: Boolean) { + state = State.TELEPORT_TO + if(!instant) + timerCountdown = RandomFunction.random(500) + } + + fun sleep() { + state = State.TELEPORT_BACK + } + + fun isMining() : Boolean { + return state == State.MINING + } + + fun isIdle() : Boolean { + return state == State.FULL_IDLE + } + + internal enum class State { + FULL_IDLE, + TELEPORT_TO, + MINING, + TELEPORT_BACK + } + + companion object { + val spawnLoc = Location.create(2230, 3339, 0) + fun new() : ShootingStarBot { + val script = ShootingStarBot() + GeneralBotCreator(script, spawnLoc) + return script + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/bots/VarrockEssenceMiner.kt b/Server/src/main/content/global/bots/VarrockEssenceMiner.kt new file mode 100644 index 0000000..39ce02c --- /dev/null +++ b/Server/src/main/content/global/bots/VarrockEssenceMiner.kt @@ -0,0 +1,121 @@ +package content.global.bots + +import core.game.bots.* +import core.game.interaction.DestinationFlag +import core.game.interaction.IntType +import core.game.interaction.InteractionListeners +import core.game.interaction.MovementPulse +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import org.rs09.consts.Items + +@PlayerCompatible +@ScriptDescription("Start in varrock bank with rune mysteries complete and a pickaxe equipped/in inventory") +@ScriptName("Varrock Essence Miner") +@ScriptIdentifier("essence_miner") +class VarrockEssenceMiner : Script(){ + + var state = State.TO_ESSENCE + val auburyZone = ZoneBorders(3252, 3398, 3254, 3402) + val bankZone = ZoneBorders(3251, 3420,3254, 3422) + // Used for automatic failure prevention eg from levelup + override fun tick() { + + when(state){ + State.TO_ESSENCE -> { + bot.interfaceManager.close() + if(!auburyZone.insideBorder(bot)) + scriptAPI.walkTo(auburyZone.randomLoc) + else { + val aubury = scriptAPI.getNearestNode("Aubury") + aubury?.interaction?.handle(bot,aubury.interaction[3]) + state = State.MINING + } + /*val bank = scriptAPI.getNearestNode("Bank booth",true) + if(bank != null && bank.location?.withinDistance(bot.location,2) == true){ + Pathfinder.find(bot, Location.create(3259, 3405, 0)).walk(bot) + } else { + when(bot.location){ + Location.create(3165, 3487, 0) -> scriptAPI.teleport(Location.create(3254, 3421, 0)) + Location.create(3259, 3405, 0) -> Pathfinder.find(bot,Location.create(3253, 3400, 0)).walk(bot) + Location.create(3253, 3400, 0) -> { + val aubury = scriptAPI.getNearestNode("Aubury") + aubury?.interaction?.handle(bot,aubury.interaction[3]) + } + Location.create(2922, 4820, 0) -> { + state = State.MINING + } + } + }*/ + } + + State.MINING -> { + if(bot.inventory.isFull) { + state = State.TO_BANK + } + else { + val essence = scriptAPI.getNearestNode(2491,true) + essence?.let { InteractionListeners.run(essence.id, IntType.SCENERY,"mine",bot,essence) } + } + } + + State.TO_BANK -> { + val portal = scriptAPI.getNearestNode("Portal",true) + if(portal != null && portal.location.withinDistance(bot.location,20)) + portal.interaction.handle(bot,portal.interaction[0]) + else { + if(!bankZone.insideBorder(bot)){ + scriptAPI.walkTo(bankZone.randomLoc) + } else { + state = State.BANKING + } + } + } + + State.BANKING -> { + val bank = scriptAPI.getNearestNode("bank booth",true) + val item = + if(bot.inventory.getAmount(Items.RUNE_ESSENCE_1436) > 0) Items.RUNE_ESSENCE_1436 else Items.PURE_ESSENCE_7936 + if(bank != null){ + bot.pulseManager.run(object : MovementPulse(bot,bank, DestinationFlag.OBJECT){ + override fun pulse(): Boolean { + bot.faceLocation(bank.location) + scriptAPI.bankItem(item) + state = State.TO_ESSENCE + return true + } + }) + } + } + + State.TELE_GE -> { + if(bot.location != Location.create(3165, 3482, 0)) + scriptAPI.walkTo(Location.create(3165, 3482, 0)) + else + state = State.SELL_GE + } + + State.SELL_GE -> { + scriptAPI.sellOnGE(Items.PURE_ESSENCE_7936) + state = State.TO_ESSENCE + } + + } + + } + + enum class State{ + TO_ESSENCE, + TO_BANK, + MINING, + BANKING, + TELE_GE, + SELL_GE + } + + override fun newInstance(): Script { + val script = VarrockEssenceMiner() + script.bot = SkillingBotAssembler().produce(SkillingBotAssembler.Wealth.POOR,bot.startLocation) + return script + } +} diff --git a/Server/src/main/content/global/bots/VarrockSmither.kt b/Server/src/main/content/global/bots/VarrockSmither.kt new file mode 100644 index 0000000..0d25250 --- /dev/null +++ b/Server/src/main/content/global/bots/VarrockSmither.kt @@ -0,0 +1,67 @@ +package content.global.bots + +import core.game.interaction.DestinationFlag +import core.game.interaction.MovementPulse +import core.game.node.entity.skill.Skills +import content.global.skill.smithing.Bars +import content.global.skill.smithing.SmithingPulse +import core.game.node.item.Item +import core.game.world.map.Location +import core.tools.RandomFunction +import org.rs09.consts.Items +import core.game.bots.SkillingBotAssembler +import core.game.bots.Script + +class VarrockSmither : Script() { + var state = State.SMITHING + override fun tick() { + when(state) { + State.SMITHING -> { + for (i in inventory) { + bot.inventory.add(i) + } + val anvil = scriptAPI.getNearestNode("anvil", true) + if (anvil != null) { + bot.pulseManager.run(object : MovementPulse(bot, anvil, DestinationFlag.OBJECT) { + override fun pulse(): Boolean { + bot.faceLocation(anvil.location) + bot.pulseManager.run(SmithingPulse(bot, Item(2353), Bars.STEEL_ARROW_TIPS, 27)) + state = State.BANKING + return true + } + }) + } + } + + State.BANKING -> { + val bank = scriptAPI.getNearestNode("Bank booth") + if(bank != null) + bot.pulseManager.run(object: MovementPulse(bot,bank, DestinationFlag.OBJECT){ + override fun pulse(): Boolean { + bot.faceLocation(bank.location) + bot.inventory.clear() + state = State.SMITHING + return true + } + }) + } + } + } + + override fun newInstance(): Script { + val script = VarrockSmither() + script.bot = SkillingBotAssembler().produce(SkillingBotAssembler.Wealth.RICH, Location.create(3189, 3436, 0)) + return script + } + + init { + skills[Skills.SMITHING] = RandomFunction.random(33,99) + inventory.add(Item(Items.HAMMER_2347)) + inventory.add(Item(Items.STEEL_BAR_2353,27)) + } + + enum class State { + SMITHING, + BANKING + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/dialogue/BankDepositDialogue.kt b/Server/src/main/content/global/dialogue/BankDepositDialogue.kt new file mode 100644 index 0000000..add6358 --- /dev/null +++ b/Server/src/main/content/global/dialogue/BankDepositDialogue.kt @@ -0,0 +1,55 @@ +package content.global.dialogue + +import core.api.dumpBeastOfBurden +import core.api.dumpContainer +import core.api.sendMessage +import core.game.dialogue.DialogueFile +import core.tools.START_DIALOGUE + +/** + * Represents the dialogue shown when the user presses + * "Deposit Beast of Burden" button on the Bank Interface. + * + * @author vddCore + */ +class BankDepositDialogue : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + START_DIALOGUE -> options( + "Deposit Inventory", + "Deposit Worn Equipment", + "Deposit Beast of Burden", + "Cancel" + ).also { stage++ } + + 1 -> when (buttonID) { + 1 -> player?.let { + end() + + if (it.inventory.isEmpty) { + sendMessage(it, "You have nothing in your inventory that you can deposit.") + } else { + dumpContainer(it, it.inventory) + } + } + + 2 -> player?.let { + end() + + if (it.equipment.isEmpty) { + sendMessage(it, "You have no equipment that you can deposit.") + } else { + dumpContainer(it, it.equipment) + } + } + + 3 -> player?.let { + end() + dumpBeastOfBurden(it) + } + + 4 -> end() + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/dialogue/BankHelpDialogue.kt b/Server/src/main/content/global/dialogue/BankHelpDialogue.kt new file mode 100644 index 0000000..ca8c645 --- /dev/null +++ b/Server/src/main/content/global/dialogue/BankHelpDialogue.kt @@ -0,0 +1,57 @@ +package content.global.dialogue + +import core.api.openInterface +import core.api.sendDialogue +import core.api.sendItemDialogue +import core.game.node.item.Item +import org.rs09.consts.Components +import org.rs09.consts.Items +import core.game.dialogue.DialogueFile +import core.tools.START_DIALOGUE + +/** + * Represents the dialogue shown when the user presses + * the "?" button on the Bank Interface. + * + * @author vddCore + */ +class BankHelpDialogue : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + START_DIALOGUE -> options( + "Check Bank Value", + "Banking Assistance", + "Close" + ).also { stage++ } + + 1 -> when (buttonID) { + 1 -> player?.let { + end() + + val wealth = it.bank.wealth + + if (wealth > 0) { + val word = if (wealth != 1) "coins" else "coin" + + sendItemDialogue( + it, + Item(Items.COINS_995, wealth), + "
Your bank is worth ${wealth} ${word}." + ) + } else { + sendDialogue(it, "You have no valuables in your bank.") + } + } + + 2 -> player?.let { + end() + + it.bank.close() + openInterface(it, Components.BANK_V2_HELP_767) + } + + 3 -> end() + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/dialogue/BankerDialogue.kt b/Server/src/main/content/global/dialogue/BankerDialogue.kt new file mode 100644 index 0000000..e913ce4 --- /dev/null +++ b/Server/src/main/content/global/dialogue/BankerDialogue.kt @@ -0,0 +1,181 @@ +package content.global.dialogue + +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.IronmanMode +import core.plugin.Initializable +import core.game.dialogue.IfTopic +import core.game.dialogue.Topic +import content.global.handlers.npc.BankerNPC +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE + +@Initializable +class BankerDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + START_DIALOGUE -> when { + hasIronmanRestriction(player, IronmanMode.ULTIMATE) -> { + npcl( + core.game.dialogue.FacialExpression.ANNOYED, + "My apologies, dear ${if (player.isMale) "sir" else "madam"}, " + + "our services are not available for Ultimate ${if (player.isMale) "Ironmen" else "Ironwomen"}" + ).also { stage = END_DIALOGUE } + } + + else -> { + npcl( + core.game.dialogue.FacialExpression.FRIENDLY, + "Good day, how may I help you?" + ).also { + if (hasAwaitingGrandExchangeCollections(player)) { + stage++ + } else { + stage += 2 + } + } + } + } + + 1 -> npcl( + core.game.dialogue.FacialExpression.FRIENDLY, + "Before we go any further, I should inform you that you " + + "have items ready for collection from the Grand Exchange." + ).also { stage++ } + + 2 -> showTopics( + Topic(core.game.dialogue.FacialExpression.FRIENDLY, "I'd like to access my bank account, please.", 10), + IfTopic( + core.game.dialogue.FacialExpression.FRIENDLY, + "I'd like to switch to my ${getBankAccountName(player, true)} bank account.", + 13, + hasActivatedSecondaryBankAccount(player) + ), + IfTopic( + core.game.dialogue.FacialExpression.FRIENDLY, + "I'd like to open a secondary bank account.", + 20, + !hasActivatedSecondaryBankAccount(player) + ), + Topic(core.game.dialogue.FacialExpression.FRIENDLY, "I'd like to check my PIN settings.", 11), + Topic(core.game.dialogue.FacialExpression.FRIENDLY, "I'd like to collect items.", 12), + Topic(core.game.dialogue.FacialExpression.ASKING, "What is this place?", 3), + ) + + 3 -> npcl( + core.game.dialogue.FacialExpression.FRIENDLY, + "This is a branch of the Bank of Gielinor. We have branches in many towns." + ).also { stage++ } + + 4 -> playerl( + core.game.dialogue.FacialExpression.ASKING, + "And what do you do?" + ).also { stage++ } + + 5 -> npcl( + core.game.dialogue.FacialExpression.FRIENDLY, + "We will look after your items and money for you. " + + "Leave your valuables with us if you want to keep them safe." + ).also { stage = END_DIALOGUE } + + 10 -> { + openBankAccount(player) + end() + } + + 11 -> { + openBankPinSettings(player) + end() + } + + 12 -> { + openGrandExchangeCollectionBox(player) + end() + } + + 13 -> { + toggleBankAccount(player) + + npcl( + core.game.dialogue.FacialExpression.FRIENDLY, + "Your active bank account has been switched. " + + "You can now access your ${getBankAccountName(player)} account." + ).also { stage = 2 } + } + + 20 -> npcl( + core.game.dialogue.FacialExpression.FRIENDLY, + "Certainly. We offer secondary accounts to all our customers." + ).also { stage++ } + + 21 -> npcl( + core.game.dialogue.FacialExpression.FRIENDLY, + "The secondary account comes with a standard fee of 5,000,000 coins. The fee is non-refundable " + + "and account activation is permanent." + ).also { stage++ } + + 22 -> npcl( + core.game.dialogue.FacialExpression.FRIENDLY, + "If your inventory does not contain enough money to cover the costs, we will complement " + + "the amount with the money inside your primary bank account." + ).also { stage++ } + + 23 -> npcl( + core.game.dialogue.FacialExpression.ASKING, + "Knowing all this, would you like to proceed with opening your secondary bank account?" + ).also { stage++ } + + 24 -> showTopics( + Topic(core.game.dialogue.FacialExpression.HAPPY, "Yes, I am still interested.", 25), + Topic(core.game.dialogue.FacialExpression.ANNOYED, "Actually, I've changed my mind.", 26) + ) + + 25 -> { + when (activateSecondaryBankAccount(player)) { + SecondaryBankAccountActivationResult.ALREADY_ACTIVE -> { + npcl( + core.game.dialogue.FacialExpression.FRIENDLY, + "Your bank account was already activated, there is no need to pay twice." + ).also { stage = END_DIALOGUE } + } + + SecondaryBankAccountActivationResult.INTERNAL_FAILURE -> { + npcl( + core.game.dialogue.FacialExpression.ANNOYED, + "I must apologize, the transaction was not successful. Please check your " + + "primary bank account and your inventory - if there's money missing, please " + + "screenshot your chat box and contact the game developers." + ).also { stage = END_DIALOGUE } + } + + SecondaryBankAccountActivationResult.NOT_ENOUGH_MONEY -> { + npcl( + core.game.dialogue.FacialExpression.ANNOYED, + "It appears that you do not have the money necessary to cover the costs " + + "associated with opening a secondary bank account. I will be waiting here " + + "until you do." + ).also { stage = END_DIALOGUE } + } + + SecondaryBankAccountActivationResult.SUCCESS -> { + npcl( + core.game.dialogue.FacialExpression.FRIENDLY, + "Your secondary bank account has been opened and can be accessed through any " + + "of the Bank of Gielinor's employees. Thank you for choosing our services." + ).also { stage = END_DIALOGUE } + } + } + } + + 26 -> npcl( + core.game.dialogue.FacialExpression.FRIENDLY, + "Very well. Should you decide a secondary bank account is needed, do not hesitate to " + + "contact any of the Bank of Gielinor's stationary employees. We will be happy to help." + ).also { stage = END_DIALOGUE } + } + + return true + } + + override fun getIds(): IntArray = BankerNPC.NPC_IDS +} diff --git a/Server/src/main/content/global/dialogue/GardenerDialoguePlugin.kt b/Server/src/main/content/global/dialogue/GardenerDialoguePlugin.kt new file mode 100644 index 0000000..6c19297 --- /dev/null +++ b/Server/src/main/content/global/dialogue/GardenerDialoguePlugin.kt @@ -0,0 +1,233 @@ +package content.global.dialogue + +import content.global.skill.farming.FarmerPayOptionDialogue +import content.global.skill.farming.Farmers +import content.global.skill.farming.FarmingPatch +import content.global.skill.farming.PatchType +import core.api.* +import core.game.dialogue.FacialExpression +import core.game.dialogue.IfTopic +import core.game.dialogue.Topic +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import org.rs09.consts.Items +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE + +@Initializable +class GardenerDialoguePlugin(player: Player? = null) : core.game.dialogue.DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + val patches = Farmers.forId(npc.id)!!.patches + when (stage) { + // TODO: Can fruit trees be chopped down by the gardener too? + START_DIALOGUE -> { + val patch = patches[0].getPatchFor(player) + showTopics( + IfTopic( + FacialExpression.ASKING, + "Would you chop my tree down for me?", + 1000, + patch.patch.type == PatchType.TREE_PATCH && patch.plantable != null && patch.isGrown() + ), + IfTopic( + FacialExpression.ASKING, + "Would you look after my crops for me?", + 10, + !(patch.patch.type == PatchType.TREE_PATCH && patch.plantable != null && patch.isGrown()) + ), + Topic(FacialExpression.ASKING, "Can you give me any farming advice?", 2000), + Topic(FacialExpression.ASKING, "Can you sell me something?", 30), + Topic(FacialExpression.NEUTRAL, "That's all, thanks.", END_DIALOGUE) + ) + } + + 10 -> { + if (patches.size > 1) { + npc("I might. Which one were you thinking of?").also { stage = 20 } + } else { + openPayGardenerDialogue(player, patches[0]) + } + } + + 20 -> when (npc.id) { + Farmers.ELSTAN.id, Farmers.LYRA.id -> showTopics( + Topic(FacialExpression.NEUTRAL, "The north-western allotment.", 21), + Topic(FacialExpression.NEUTRAL, "The south-eastern allotment.", 22) + ) + Farmers.DANTAERA.id, Farmers.KRAGEN.id -> showTopics( + Topic(FacialExpression.NEUTRAL, "The northern allotment.", 21), + Topic(FacialExpression.NEUTRAL, "The southern allotment.", 22) + ) + } + 21 -> openPayGardenerDialogue(player, patches[0]) + 22 -> openPayGardenerDialogue(player, patches[1]) + + 30 -> npc(FacialExpression.NEUTRAL, "That depends on whether I have it to sell. What is it", "that you're looking for?").also { stage++ } + 31 -> showTopics( + Topic(FacialExpression.NEUTRAL, "Some plant cure.", 100), + Topic(FacialExpression.NEUTRAL, "A bucket of compost.", 200), + Topic(FacialExpression.NEUTRAL, "A rake.", 300), + Topic("(See more items)", 32, true) + ) + 32 -> showTopics( + Topic(FacialExpression.NEUTRAL, "A watering can.", 400), + Topic(FacialExpression.NEUTRAL, "A gardening trowel.", 500), + Topic(FacialExpression.NEUTRAL, "A seed dibber.", 600), + Topic("(See previous items)", 31, true), + Topic(FacialExpression.NEUTRAL, "Forget it.", 40, true) + ) + + 40 -> player("Forget it, you don't have anything I need.").also { stage = END_DIALOGUE } + + 100 -> npc("Plant cure, eh? I might have some put aside for myself.", "Tell you what. I'll sell you some plant cure for 25 gp if", "you like.").also { stage++ } + 101 -> options("Yes, that sounds like a fair price.", "No thanks, I can get that much cheaper elsewhere.").also { stage++ } + 102 -> when (buttonId) { + 1 -> { + player(FacialExpression.HAPPY, "Yes, that sounds like a fair price.").also { stage = END_DIALOGUE } + if (removeItem(player, Item(Items.COINS_995, 25))) { + addItemOrDrop(player, Items.PLANT_CURE_6036) + } else { + sendMessage(player, "You need 25 gp to pay for that.") + } + } + 2 -> player("No thanks, I can get that much cheaper elsewhere.").also { stage = END_DIALOGUE } + } + + 200 -> npc("A bucket of compost, eh? I might have one spare...", "tell you what, I'll sell it to you for 35 gp if you like.").also { stage++ } + 201 -> options("Yes, that sounds like a fair price.", "No thanks, I can get that much cheaper elsewhere.").also { stage++ } + 202 -> when (buttonId) { + 1 -> { + player("Yes, that sounds like a fair price.").also { stage = END_DIALOGUE } + if (removeItem(player, Item(Items.COINS_995, 35))) { + addItemOrDrop(player, Items.COMPOST_6032) + } else { + sendMessage(player, "You need 35 gp to pay for that.") + } + } + 2 -> player("No thanks, I can get that much cheaper elsewhere.").also { stage = END_DIALOGUE } + } + + 300 -> npc("A rake, eh? I might have one spare...", "tell you what, I'll sell it to you for 15 gp if you like.").also { stage++ } + 301 -> options("Yes, that sounds like a fair price.", "No thanks, I can get that much cheaper elsewhere.").also { stage++ } + 302 -> when (buttonId) { + 1 -> { + player("Yes, that sounds like a fair price.").also { stage = END_DIALOGUE } + if (removeItem(player, Item(Items.COINS_995, 15))) { + addItemOrDrop(player, Items.RAKE_5341) + } else { + sendMessage(player, "You need 15 gp to pay for that.") + } + } + 2 -> player("No thanks, I can get that much cheaper elsewhere.").also { stage = END_DIALOGUE } + } + + 400 -> npc("A watering can, eh? I might have one spare...", "tell you what, I'll sell it to you for 25 gp if you like.").also { stage++ } + 401 -> options("Yes, that sounds like a fair price.", "No thanks, I can get that much cheaper elsewhere.").also { stage++ } + 402 -> when(buttonId){ + 1 -> { + player("Yes, that sounds like a fair price.").also { stage = END_DIALOGUE } + if (removeItem(player, Item(Items.COINS_995, 25))) { + addItemOrDrop(player, Items.WATERING_CAN8_5340) + } else { + sendMessage(player, "You need 25 gp to pay for that.") + } + } + 2 -> player("No thanks, I can get that much cheaper elsewhere.").also { stage = END_DIALOGUE } + } + + 500 -> npc("A gardening trowel, eh? I might have one spare...", "tell you what, I'll sell it to you for 15 gp if you like.").also { stage++ } + 501 -> options("Yes, that sounds like a fair price.", "No thanks, I can get that much cheaper elsewhere.").also { stage++ } + 502 -> when (buttonId) { + 1 -> { + player("Yes, that sounds like a fair price.").also { stage = END_DIALOGUE } + if (removeItem(player, Item(Items.COINS_995, 15))) { + addItemOrDrop(player, Items.GARDENING_TROWEL_5325) + } else { + sendMessage(player, "You need 15 gp to pay for that.") + } + } + 2 -> player("No thanks, I can get that much cheaper elsewhere.").also { stage = END_DIALOGUE } + } + + 600 -> npc("A seed dibber, eh? I might have one spare...", "tell you what, I'll sell it to you for 15 gp if you like.").also { stage++ } + 601 -> options("Yes, that sounds like a fair price.", "No thanks, I can get that much cheaper elsewhere.").also { stage++ } + 602 -> when (buttonId) { + 1 -> { + player("Yes, that sounds like a fair price.").also { stage = END_DIALOGUE } + if (removeItem(player, Item(Items.COINS_995, 15))) { + addItemOrDrop(player, Items.SEED_DIBBER_5343) + } else { + sendMessage(player, "You need 15 gp to pay for that.") + } + } + 2 -> player("No thanks, I can get that much cheaper elsewhere.").also { stage = END_DIALOGUE } + } + + // Note: This dialogue changes slightly in April 2009, and significantly in December 2009 + 1000 -> npc(FacialExpression.THINKING, "Why? You look like you could chop it down yourself!").also { stage++ } + 1001 -> showTopics( + Topic(FacialExpression.NEUTRAL, "Yes, you're right - I'll do it myself.", END_DIALOGUE), + Topic(FacialExpression.NEUTRAL, "I can't be bothered - I'd rather pay you to do it.", 1020) + ) + + 1020 -> npc(FacialExpression.NEUTRAL, "Well, it's a lot of hard work - if you pay me 200 GP", "I'll chop it down for you.").also { stage++ } + 1021 -> { + if (inInventory(player, Items.COINS_995, 200)) { + showTopics( + Topic(FacialExpression.NEUTRAL, "Here's 200GP - chop my tree down please.", 1022), + Topic(FacialExpression.NEUTRAL, "I don't want to pay that much, sorry.", END_DIALOGUE) + ) + } else { + player("I don't have that much money on me.").also { stage = END_DIALOGUE } // not authentic + } + } + 1022 -> { + end() + if (removeItem(player, Item(Items.COINS_995, 200))) { + patches[0].getPatchFor(player).clear() + } + } + + 2000 -> { + val advice = arrayOf( + "There are four main Farming areas - Elstan looks after an area south of Falador, Dantaera has one to the north of Catherby, Kragen has one near Ardougne, and Lyra looks after a place in north Morytania.", + "If you want to grow fruit trees you could try a few places: Catherby and Brimhaven have a couple of fruit tree patches, and I hear that the gnomes are big on that sort of thing.", + "Bittercap mushrooms can only be grown in a special patch in Morytania, near the Mort Myre swamp. There the ground is especially dank and suited to growing poisonous fungi.", + "There is a special patch for growing Belladonna - I believe it's somewhere near Draynor Manor, where the ground is a tad 'unblessed'.", + + "Don't just throw away your weeds after you've raked a patch - put them in a compost bin and make some compost.", + "Applying compost to a patch will not only reduce the chance that your crops will get diseased, but you will also grow more crops to harvest.", + "Supercompost is far better than normal compost, but more expensive to make. You need to rot the right type of item; show me an item, and I'll tell you if it's super-compostable or not.", + + "Tree seeds must be grown in a plantpot of soil into a sapling, and then transferred to a tree patch to continue growing to adulthood.", + "You don't have to buy all your plantpots you know, you can make them yourself on a pottery wheel. If you're a good enough ${if (player!!.isMale) "craftsman" else "craftswoman"}, that is.", + "You can fill plantpots with soil from Farming patches, if you have a gardening trowel.", + + "Vegetables, hops and flowers are far more likely to grow healthily if you water them periodically.", + "The only way to cure a bush or tree of disease is to prune away the diseased leaves with a pair of secateurs. For all other crops I would just apply some plant-cure.", + "If you need to be rid of your fruit trees for any reason, all you have to do is chop them down and then dig up the stump.", + + "You can put up to ten potatoes, cabbages or onions in vegetable sacks, although you can't have a mix in the same sack.", + "You can put up to five tomatoes, strawberries, apples, bananas or oranges into a fruit basket, although you can't have a mix in the same basket.", + "If you want to make your own sacks and baskets you'll need to use the loom that's near the Farming shop in Falador. If you're a good enough ${if (player!!.isMale) "craftsman" else "craftswoman"}, that is.", + "You can buy all the farming tools from farming shops, which can be found close to the allotments.", + + "Hops are good for brewing ales. I believe there's a brewery up in Keldagrim somewhere, and I've heard rumours that a place called Phasmatys used to be good for that type of thing. 'Fore they all died, of course.", + ) + npcl(FacialExpression.NEUTRAL, advice.random()).also { stage = START_DIALOGUE } + } + } + return true + } + + fun openPayGardenerDialogue(player: Player, fPatch: FarmingPatch) { + end() + openDialogue(player, FarmerPayOptionDialogue(fPatch.getPatchFor(player)), npc) + } + + override fun getIds(): IntArray { + return Farmers.values().map(Farmers::id).toIntArray() + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/dialogue/ManDialoguePlugin.java b/Server/src/main/content/global/dialogue/ManDialoguePlugin.java new file mode 100644 index 0000000..aeff88b --- /dev/null +++ b/Server/src/main/content/global/dialogue/ManDialoguePlugin.java @@ -0,0 +1,117 @@ +package content.global.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.plugin.Initializable; +import org.rs09.consts.Items; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.item.Item; +import core.tools.RandomFunction; + +/** + * Handles the man dialogues. + * + * @author 'Vexia + */ +@Initializable +public class ManDialoguePlugin extends DialoguePlugin { + private static final Item CIDER = new Item(Items.CIDER_5763); + + /** + * The NPC ids that use this dialogue plugin. + */ + private static final int[] NPC_IDS = {1, 2, 3, 4, 5, 6, 16, 24, 25, 170, 1086, 2675, 2776, 3224, 3225, 3227, 5923, 5924,}; + + public ManDialoguePlugin() { + } + + public ManDialoguePlugin(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new ManDialoguePlugin(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + if (npc == null) + return false; + if (args.length > 1 + && args[1] instanceof Item + && ((Item) args[1]).equals(CIDER) + && player.getInventory().remove(CIDER)) { + + // Seers achievement diary + if (!player.getAchievementDiaryManager().getDiary(DiaryType.SEERS_VILLAGE).isComplete(0, 6)) { + if (player.getAttribute("diary:seers:pub-cider", 0) >= 4) { + player.setAttribute("/save:diary:seers:pub-cider", 5); + player.getAchievementDiaryManager().getDiary(DiaryType.SEERS_VILLAGE).updateTask(player, 0, 6, true); + } else { + player.setAttribute("/save:diary:seers:pub-cider", player.getAttribute("diary:seers:pub-cider", 0) + 1); + } + } + + npc("Ah, a glass of cider, that's very generous of you. I", "don't mind if I do. Thanks!"); + stage = 999; + return true; + } + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello, how's it going?"); + stage = RandomFunction.random(0, 5); + if (stage == 1) { + stage = 0; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I'm very well thank you."); + stage = 999; + break; + case 999: + end(); + break; + case 2: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Who are you?"); + stage = 20; + break; + case 3: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I'm fine, how are you?"); + stage = 30; + break; + case 4: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "No, I don't want to buy anything!"); + stage = 999; + break; + case 5: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I think we need a new king. The one we've got isn't", "very good."); + stage = 999; + break; + case 20: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'm a bold adventurer."); + stage = 21; + break; + case 21: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ah, a very noble profession."); + stage = 999; + break; + case 30: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Very well thank you."); + stage = 999; + break; + } + return true; + } + + @Override + public int[] getIds() { + return NPC_IDS; + } +} diff --git a/Server/src/main/content/global/dialogue/TownCrierDialogue.java b/Server/src/main/content/global/dialogue/TownCrierDialogue.java new file mode 100644 index 0000000..e740fbf --- /dev/null +++ b/Server/src/main/content/global/dialogue/TownCrierDialogue.java @@ -0,0 +1,237 @@ +package content.global.dialogue; + +import content.global.handlers.item.book.GeneralRuleBook; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.tools.RandomFunction; + +/** + * Represents the town crier dialogue plugin. + * @author 'Vexia + */ +@Initializable +public final class TownCrierDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code TownCrierDialogue} {@code Object}. + */ + public TownCrierDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code TownCrierDialogue} {@code Object}. + * @param player the player. + */ + public TownCrierDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new TownCrierDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + npc("Hear ye! Hear ye! Player Moderators massive help to ", GameWorld.getSettings().getName().substring(0, GameWorld.getSettings().getName().length() - 3) + "-"); + stage = 1; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + + switch (stage) { + case 1: + npc("Oh, hello citizen. Are you here to find out about Player", "Moderators? Or perhaps would you like to know about the", "laws of the land?"); + stage = 2; + break; + case 2: + options("Tell me about Player Moderators.", "Tell me about the Rules of " + GameWorld.getSettings().getName() + ".", "Can you give me a handy tip please?", "Bye!"); + stage = 3; + break; + case 3: + switch (buttonId) { + case 1: + player("Tell me about Player Moderators."); + stage = 50; + break; + case 2: + player("Tell me about the Rules of " + GameWorld.getSettings().getName() + "."); + stage = 70; + break; + case 3: + player("Can you give me a handy tip please?"); + stage = 100; + break; + case 4: + player("Bye!"); + stage = 400; + break; + } + break; + case 400: + npc("Nice meeting you."); + stage = 401; + break; + case 401: + end(); + break; + case 50: + npc("Of course. What would you like to know?"); + stage = 51; + break; + case 51: + options("What is a Player Moderator?", "What can Player Moderators do?", "How do I become a Player Moderator?", "What can Player Moderators not do?"); + stage = 52; + break; + case 52: + + switch (buttonId) { + case 1: + player(" What is a Player Moderator?"); + stage = 150; + break; + case 2: + npc("What can Player Moderators do?"); + stage = 160; + break; + case 3: + player("How do I become a Player Moderator?"); + stage = 170; + break; + case 4: + player("What can Player Moderators not do?"); + stage = 180; + break; + } + break; + case 70: + player.lock(4); + npc("At once. Take a look at my book here."); + npc.animate(new Animation(6866)); + GameWorld.getPulser().submit(new Pulse(4) { + @Override + public boolean pulse() { + GeneralRuleBook.Companion.openBook(player); + return true; + } + }); + // Find out about the Rules of Conduct from the Draynor

Town Crier + if (npc.getId() == 6136) { + player.getAchievementDiaryManager().finishTask(player, DiaryType.LUMBRIDGE, 0, 10); + } + stage = 71; + break; + case 71: + end(); + break; + + case 100: + int rand = RandomFunction.random(1, 5); + switch (rand) { + case 1: + npc("If the chat window is moving too quickly to report a", "player accurately, run to a quiet spot and review the chat", "at your leisure!"); + stage = 2; + break; + case 2: + npc("If you're lost and have no idea where to go, use the Home", "Teleporter spell for free!"); + stage = 2; + break; + case 3: + npc("Make your recovery questions and answers hard to guess", "but easy to remember."); + stage = 2; + break; + case 4: + npc("Beware of players trying to lue you into the wilderness.", "Your items cannot be returned if you lose them!"); + stage = 2; + break; + default: + npc("" + GameWorld.getSettings().getName() + " will never email you asking for your log-in details."); + stage = 2; + break; + } + break; + case 150: + npc("Player Moderators are normal players of the game, just", "like you. However, since they have shown themselves to be", "trustworthy and active reporters, they have been invited", "by Jagex to monitor the game and take appropriate"); + stage = 151; + break; + case 151: + npc("reward when they see rule breaking. You can spot a Player", "Moderator in game by looking at the chat screen - when a", "Player Moderator speaks, a silver crown appears to the", "left of their name. Remember, if there's no silver crown"); + stage = 152; + break; + case 152: + npc("there, they are not a Player Moderator! You can check", "out the website if you'd like more information."); + stage = 153; + break; + case 153: + player("Thanks!"); + stage = 154; + break; + case 154: + npc("Is there anything else you'd like to know?"); + stage = 51; + break; + case 160: + npc("Player Moderators, or 'P-mods', have the ability to mute", "rule breakers and " + GameWorld.getSettings().getName() + " view their reports as a priority so", "that reward is taken as quickly as possible. P-Mods also", "have acces to the Player Moderator Centre. Within the"); + stage = 161; + break; + case 161: + npc("Centre are tools to help them Moderate " + GameWorld.getSettings().getName() + ".", "These tools include dedicated forums, the Player", "Moderator Guidelines and the Player Moderator Code of", "Conduct."); + stage = 153; + break; + case 170: + npc("" + GameWorld.getSettings().getName() + " picks players who spend their time and effort to", "help better the " + GameWorld.getSettings().getName() + " community. To increase your", "chances of becoming a Player Moderator:"); + stage = 171; + break; + case 171: + npc("Keep your account secure! This is very important, as a", "player with poor security will never be a P-Mod. Read our", "Security Tips for more information."); + stage = 173; + break; + case 173: + npc("Play by the rules! The rules of " + GameWorld.getSettings().getName() + " are enforced", "for a reason, to make the game a fair and enjoyable", "environment for all."); + stage = 174; + break; + case 174: + npc("Report accuratley! When " + GameWorld.getSettings().getName() + " consider an account for", "review they look for quality, not quantity. Ensure your", "reports are of a high quality by following the report", "guidelines."); + stage = 175; + break; + case 175: + npc("Be nice to each other! Treat others as you would", "want to be treated yourself. Respect your fellow player.", "More information can be found on the website."); + stage = 153; + break; + case 180: + npc("P-Mods cannot ban your account - they can only report", "offences. " + GameWorld.getSettings().getName() + " then take reward based on the evidence", "received. If you lose your password or get scamme dby", "another player, P_Mods cannot help you get your account"); + stage = 181; + break; + case 181: + npc("back. All they can do is recommend you to go to Player", "Support. They cannot retrieve any items you may have", "lost and they certainly do not recieve any free items", "from " + GameWorld.getSettings().getName() + " for moderating the game. They are players"); + stage = 182; + break; + case 182: + npc("who give their all to help the community, out of the", "goodness of their hearts! P-mods do not work for " + GameWorld.getSettings().getName() + "", "and so cannot make you a Moderator, or recommend", "other accounts to become Moderators. If you wish yo"); + stage = 183; + break; + case 183: + npc("become a Moderator, feel free to ask me!"); + stage = 153; + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 6135, 6136, 6137, 6138, 6139 }; + } +} diff --git a/Server/src/main/content/global/handlers/iface/AgilityTicketInterface.java b/Server/src/main/content/global/handlers/iface/AgilityTicketInterface.java new file mode 100644 index 0000000..368849e --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/AgilityTicketInterface.java @@ -0,0 +1,116 @@ +package content.global.handlers.iface; + +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Plugin; +import core.tools.StringUtils; + +/** + * Represents the plugin used to handle the agility ticket interface. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class AgilityTicketInterface extends ComponentPlugin { + + /** + * Represents the pirate hook item. + */ + private static final Item PIRATE_HOOK = new Item(2997); + + /** + * Represents the toadflax item. + */ + private static final Item TOADFLAX = new Item(2998); + + /** + * Represents the snapdragon item. + */ + private static final Item SNAPDRAGON = new Item(3000); + + /** + * Represents the aerna ticket. + */ + private static final int ARENA_TICKET = 2996; + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.forId(6).setPlugin(this); + return this; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + Item reward = null; + double experience = 0; + int tickets = 0; + switch (button) { + case 21:// 1 exp + experience = 240; + tickets = 1; + break; + case 22:// 10 exp. + experience = 2480; + tickets = 10; + break; + case 23:// 25 exp. + experience = 6500; + tickets = 25; + break; + case 24:// 100 exp. + experience = 28000; + tickets = 100; + break; + case 25:// 1000 exp. + experience = 320000; + tickets = 1000; + break; + case 8:// toadflax. + reward = TOADFLAX; + tickets = 3; + break; + case 9:// snap dragon. + reward = SNAPDRAGON; + tickets = 10; + break; + case 10:// pirates hook. + reward = PIRATE_HOOK; + tickets = 800; + break; + } + if (experience > 0 && !player.getInventory().contains(ARENA_TICKET, tickets)) { + player.getPacketDispatch().sendMessage("This Agility experience costs " + tickets + " tickets."); + } + if (reward != null && !player.getInventory().contains(ARENA_TICKET, tickets)) { + player.getPacketDispatch().sendMessage(StringUtils.formatDisplayName(reward.getName().replace("Clean", "").trim()) + " costs " + tickets + " tickets."); + } + if (!player.getInventory().contains(ARENA_TICKET, tickets)) { + return true; + } + if (experience > 0) { + if (!player.getInventory().containsItem(new Item(ARENA_TICKET, tickets))) { + return false; + } + if (player.getInventory().remove(new Item(ARENA_TICKET, tickets))) { + if (player.getAchievementDiaryManager().getKaramjaGlove() >= 1) { + experience *= 1.1; + } + player.getSkills().addExperience(Skills.AGILITY, experience); + player.getPacketDispatch().sendMessage("You have been granted some Agility experience!"); + } + } + if (reward != null) { + if (player.getInventory().remove(new Item(ARENA_TICKET, tickets))) { + player.getInventory().add(reward); + player.getPacketDispatch().sendMessage("You have been granted a " + StringUtils.formatDisplayName(reward.getName().replace("Clean", "").trim()) + "."); + } + } + return true; + } + +} diff --git a/Server/src/main/content/global/handlers/iface/AutocastSelectPlugin.java b/Server/src/main/content/global/handlers/iface/AutocastSelectPlugin.java new file mode 100644 index 0000000..a010c7b --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/AutocastSelectPlugin.java @@ -0,0 +1,42 @@ +package content.global.handlers.iface; + +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the auto casting component plugin. + * @author Emperor + * + */ +@Initializable +public final class AutocastSelectPlugin extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.forId(797).setPlugin(this); + ComponentDefinition.forId(319).setPlugin(this); + ComponentDefinition.forId(310).setPlugin(this); + ComponentDefinition.forId(406).setPlugin(this); + return this; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + if (!player.getAttribute("autocast_select", false)) { + return true; + } + player.removeAttribute("autocast_select"); + final WeaponInterface w = player.getExtension(WeaponInterface.class); + if (w != null) { + w.selectAutoSpell(button, true); + player.getInterfaceManager().openTab(w); + } + return true; + } + +} diff --git a/Server/src/main/content/global/handlers/iface/BoltEnchantingInterface.java b/Server/src/main/content/global/handlers/iface/BoltEnchantingInterface.java new file mode 100644 index 0000000..5d4a567 --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/BoltEnchantingInterface.java @@ -0,0 +1,247 @@ +package content.global.handlers.iface; + +import core.api.ContentAPIKt; +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.combat.spell.MagicStaff; +import core.game.node.entity.combat.spell.Runes; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Plugin; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playAudio; + +/** + * Represents the component plugin used to handle the bolt enchanting interface. + * @author Emperor + * @author SonicForce41 + */ +@Initializable +public final class BoltEnchantingInterface extends ComponentPlugin { + + /** + * Represents the graphics to use. + */ + private static final Graphics GRAPHICS = new Graphics(759); + + /** + * Represents the animation to use. + */ + private static final Animation ANIMATION = new Animation(4462); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.put(432, this); + return this; + } + + @Override + public boolean handle(final Player player, Component component, int opcode, int button, int slot, int itemId) { + final Bolts bolts = Bolts.forId(button); + if (bolts != null) { + player.getInterfaceManager().close(); + if (player.getSkills().getLevel(Skills.MAGIC) < bolts.getLevel()) { + player.getPacketDispatch().sendMessage("You need a level of " + bolts.getLevel() + " to cast this spell."); + return true; + } + for (Item item : bolts.getRunes()) { + if (!player.getInventory().containsItem(item) && !usingStaff(player, item.getId())) { + player.getPacketDispatch().sendMessage("You do not have enough runes to cast this spell."); + return true; + } + } + final int amount = player.getInventory().getAmount(new Item(bolts.getBolt(), 1)); + if (amount < 1) { + player.getPacketDispatch().sendMessage("You don't have any bolts to enchant."); + return true; + } + final Item add = new Item(bolts.getEnchanted()); + if (amount > 10 && !player.getInventory().hasSpaceFor(add)) { + player.getPacketDispatch().sendMessage("Not enough space in your inventory!"); + return true; + } + player.graphics(GRAPHICS); + player.animate(ANIMATION); + player.getPulseManager().run(new Pulse(1) { + @Override + public boolean pulse() { + int enchant = amount; + if (enchant > 10) { + enchant = 10; + } + add.setAmount(enchant); + player.getInventory().remove(new Item(bolts.getBolt(), enchant)); + player.getInventory().add(add); + for (Item item : bolts.getRunes()) { + boolean staff = usingStaff(player, item.getId()); + if (!player.getInventory().containsItem(item) && !staff) { + player.getPacketDispatch().sendMessage("You do not have enough " + item.getName() + "s to cast this spell."); + return true; + } + if (!staff) { + player.getInventory().remove(item); + } + } + player.getSkills().addExperience(Skills.MAGIC, bolts.getExp(), true); + player.getPacketDispatch().sendMessage("The magic of the runes coaxes out the true nature of the gem tips."); + playAudio(player, Sounds.ENCHANTED_TIPPING_2921); + return true; + } + }); + return true; + } + return false; + } + + /** + * Checks if the player is holding the staff that will be used instead of + * the rune. + * @param p The player. + * @param rune The rune item id. + * @return {@code True} if the player is wearing the correct staff for this + * rune. + */ + public boolean usingStaff(Player p, int rune) { + Item weapon = p.getEquipment().get(3); + if (weapon == null) { + return false; + } + MagicStaff staff = MagicStaff.forId(rune); + if (staff == null) { + return false; + } + int[] staves = staff.getStaves(); + for (int id : staves) { + if (weapon.getId() == id) { + return true; + } + } + return false; + } + + /** + * Represents the enumeration of bolts. + * @author SonicForce41 + * @version 1 + */ + public enum Bolts { + OPAL(14, 879, 4, new Item[] { new Item(Runes.COSMIC_RUNE.getId(), 1), new Item(Runes.AIR_RUNE.getId(), 2) }, 9, 9236), SAPPHIRE(29, 9337, 7, new Item[] { new Item(Runes.COSMIC_RUNE.getId(), 1), new Item(Runes.MIND_RUNE.getId(), 1), new Item(Runes.WATER_RUNE.getId(), 1) }, 17, 9240), JADE(18, 9335, 14, new Item[] { new Item(Runes.COSMIC_RUNE.getId(), 1), new Item(Runes.EARTH_RUNE.getId(), 2) }, 19, 9237), PEARL(22, 880, 24, new Item[] { new Item(Runes.COSMIC_RUNE.getId(), 1), new Item(Runes.WATER_RUNE.getId(), 2) }, 29, 9238), EMERALD(32, 9338, 27, new Item[] { new Item(Runes.NATURE_RUNE.getId(), 1), new Item(Runes.COSMIC_RUNE.getId(), 1), new Item(Runes.AIR_RUNE.getId(), 3) }, 37, 9241), RED_TOPAZ(26, 9336, 29, new Item[] { new Item(Runes.COSMIC_RUNE.getId(), 1), new Item(Runes.FIRE_RUNE.getId(), 2) }, 33, 9239), RUBY(35, 9339, 49, new Item[] { new Item(Runes.BLOOD_RUNE.getId(), 1), new Item(Runes.COSMIC_RUNE.getId(), 1), new Item(Runes.FIRE_RUNE.getId(), 5) }, 59, 9242), DIAMOND(38, 9340, 57, new Item[] { new Item(Runes.LAW_RUNE.getId(), 2), new Item(Runes.COSMIC_RUNE.getId(), 1), new Item(Runes.EARTH_RUNE.getId(), 10) }, 67, 9243), DRAGONSTONE(41, 9341, 68, new Item[] { new Item(Runes.SOUL_RUNE.getId(), 1), new Item(Runes.COSMIC_RUNE.getId(), 1), new Item(Runes.EARTH_RUNE.getId(), 15) }, 78, 9244), ONYX(44, 9342, 87, new Item[] { new Item(Runes.DEATH_RUNE.getId(), 1), new Item(Runes.COSMIC_RUNE.getId(), 1), new Item(Runes.FIRE_RUNE.getId(), 20) }, 97, 9245); + + /** + * The button + */ + private int button; + + /** + * The actual bolt + */ + private int bolt; + + /** + * The level + */ + private int level; + + /** + * The runes required + */ + private Item[] runes; + + /** + * The exp gained + */ + private double exp; + + /** + * The enchanted bolt + */ + private int enchanted; + + /** + * Constructs a new {@code BoltEnchantingInterface} {@code Object}. + * @param button the button. + * @param bolt the bolt. + * @param level the level. + * @param runes the runes. + * @param exp the exp. + * @param enchanted the enchanted. + */ + Bolts(int button, int bolt, int level, Item[] runes, double exp, int enchanted) { + this.button = button; + this.bolt = bolt; + this.level = level; + this.runes = runes; + this.exp = exp; + this.enchanted = enchanted; + } + + /** + * Gets the button. + * @return The button. + */ + public int getButton() { + return button; + } + + /** + * Gets the bolt. + * @return The bolt. + */ + public int getBolt() { + return bolt; + } + + /** + * Gets the level. + * @return The level. + */ + public int getLevel() { + return level; + } + + /** + * Gets the runes. + * @return The runes. + */ + private Item[] getRunes() { + return runes; + } + + /** + * Gets the exp. + * @return The exp. + */ + public double getExp() { + return exp; + } + + /** + * Gets the enchanted. + * @return The enchanted. + */ + public int getEnchanted() { + return enchanted; + } + + /** + * Gets the bolt by the id. + * @param button the button. + * @return the bolt. + */ + public static Bolts forId(int button) { + for (Bolts bolts : Bolts.values()) { + if (bolts.getButton() == button) + return bolts; + } + return null; + } + } + +} diff --git a/Server/src/main/content/global/handlers/iface/BookInterface.kt b/Server/src/main/content/global/handlers/iface/BookInterface.kt new file mode 100644 index 0000000..070b83e --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/BookInterface.kt @@ -0,0 +1,233 @@ +package content.global.handlers.iface + +import core.api.closeInterface +import core.api.getAttribute +import core.api.openInterface +import core.api.setAttribute +import core.game.interaction.InterfaceListener +import core.game.node.entity.player.Player + +/** + * Interface listener for Books + * Use this to listen and interact with buttons on book interfaces. + * + * This will handle component(26), component(27) and component(49) globally. + * DO NOT extend this class or override on(26), on(27), on(49) for defineInterfaceListeners. + * + * Instead, simply call BookInterface.openBook(...) in the listener and set the following attributes: + * bookInterfaceCallback - callback function for the page to display(player: Player, pageNum: Int, buttonID: Int) : Boolean + * You must create that display() function so that can be passed in the callback and display contents of each page. + * + * You may at any time after pageSetup, + * - call any functions below + * - call player.packetDispatch.sendInterfaceConfig + * - call player.packetDispatch.sendString + * + * @see content.region.desert.quest.thegolem.VarmensNotes for a quest-like example. + * @see content.global.handlers.item.book.GeneralRuleBook for an interactive page-jumping book. + * + * @author ovenbreado + */ +class BookInterface : InterfaceListener { + + companion object { + const val CALLBACK_ATTRIBUTE = "bookInterfaceCallback" + const val CURRENT_PAGE_ATTRIBUTE = "bookInterfaceCurrentPage" + + /* These should be in org.rs09.consts.Components but currently are not. */ + const val FANCY_BOOK_26 = 26 // This is a 15-Lines per page book. + const val FANCY_BOOK_2_27 = 27 // This is a 15-Lines per page book with index and row clickable listeners. + const val FANCY_BOOK_3_49 = 49 // This is an 11-Lines per page book. + + /* Book Lines. [Title, Left button text, Right button text, ...lines 1 to X] */ + val FANCY_BOOK_26_LINE_IDS = arrayOf(101, 65, 66, 97, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96) + val FANCY_BOOK_2_27_LINE_IDS = arrayOf(163, 5, 6, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67) + val FANCY_BOOK_3_49_LINE_IDS = arrayOf(6, 77, 78, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76) + + /* Button IDs. [Left button, Right button, (opt)index button, ...(opt)click lines 1 to X] */ + val FANCY_BOOK_26_BUTTON_IDS = arrayOf(61, 63) + val FANCY_BOOK_2_27_BUTTON_IDS = arrayOf(1, 3, 159, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158) + val FANCY_BOOK_3_49_BUTTON_IDS = arrayOf(51, 53) + + /* Image IDs. [...lines 1 to X] */ + val FANCY_BOOK_2_27_IMAGE_ENABLE_DRAW_IDS = arrayOf(9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97) + val FANCY_BOOK_2_27_IMAGE_DRAW_IDS = arrayOf(10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98) + + /** Opens the book interface. Call this only once in the defineListeners() at the start of opening a book. */ + fun openBook(player: Player, bookComponent: Int, displayCallback: (player: Player, pageNum: Int, buttonId: Int) -> Boolean) { + closeInterface(player) // Important: Closes the previous interface. + setAttribute(player, CURRENT_PAGE_ATTRIBUTE, 0) // Resets the book to the first page. + setAttribute(player, CALLBACK_ATTRIBUTE, displayCallback) // Sets the display callback + if (bookComponent == FANCY_BOOK_26) { + openInterface(player, FANCY_BOOK_26) // Important: Opens the current interface. + } else if (bookComponent == FANCY_BOOK_2_27) { + openInterface(player, FANCY_BOOK_2_27) // Important: Opens the current interface. + } else if (bookComponent == FANCY_BOOK_3_49) { + openInterface(player, FANCY_BOOK_3_49) // Important: Opens the current interface. + } + displayCallback.invoke(player, 0, 0) + } + + /** Sets up title, pagination and content. Call this in the display callback every time the page changes. */ + fun pageSetup(player: Player, bookComponent: Int, title: String, contents: Array, hasPagination: Boolean = true) { + val currentPage = getAttribute(player, CURRENT_PAGE_ATTRIBUTE, 0) + if (bookComponent == FANCY_BOOK_26) { + clearBookLines(player, FANCY_BOOK_26, FANCY_BOOK_26_LINE_IDS) + clearButtons(player, FANCY_BOOK_26, FANCY_BOOK_26_BUTTON_IDS) + setTitle(player, FANCY_BOOK_26, FANCY_BOOK_26_LINE_IDS, title) + if (hasPagination) { + setPagination(player, FANCY_BOOK_26, FANCY_BOOK_26_LINE_IDS, FANCY_BOOK_26_BUTTON_IDS, currentPage, contents.size, contents[currentPage].pages.size == 1) + } + setPageContent(player, FANCY_BOOK_26, FANCY_BOOK_26_LINE_IDS, FANCY_BOOK_26_BUTTON_IDS, currentPage, contents) + } else if (bookComponent == FANCY_BOOK_2_27) { + clearBookLines(player, FANCY_BOOK_2_27, FANCY_BOOK_2_27_LINE_IDS) + clearButtons(player, FANCY_BOOK_2_27, FANCY_BOOK_2_27_BUTTON_IDS) + setTitle(player, FANCY_BOOK_2_27, FANCY_BOOK_2_27_LINE_IDS, title) + if (hasPagination) { + setPagination(player, FANCY_BOOK_2_27, FANCY_BOOK_2_27_LINE_IDS, FANCY_BOOK_2_27_BUTTON_IDS, currentPage, contents.size, contents[currentPage].pages.size == 1) + } + setPageContent(player, FANCY_BOOK_2_27, FANCY_BOOK_2_27_LINE_IDS, FANCY_BOOK_2_27_BUTTON_IDS, currentPage, contents) + } else if (bookComponent == FANCY_BOOK_3_49) { + clearBookLines(player, FANCY_BOOK_3_49, FANCY_BOOK_3_49_LINE_IDS) + clearButtons(player, FANCY_BOOK_3_49, FANCY_BOOK_3_49_BUTTON_IDS) + setTitle(player, FANCY_BOOK_3_49, FANCY_BOOK_3_49_LINE_IDS, title) + if (hasPagination) { + setPagination(player, FANCY_BOOK_3_49, FANCY_BOOK_3_49_LINE_IDS, FANCY_BOOK_3_49_BUTTON_IDS, currentPage, contents.size, contents[currentPage].pages.size == 1) + } + setPageContent(player, FANCY_BOOK_3_49, FANCY_BOOK_3_49_LINE_IDS, FANCY_BOOK_3_49_BUTTON_IDS, currentPage, contents) + } + } + + /** Clear all lines rather than leaving "Line X" on all visible rows. */ + fun clearBookLines(player: Player, componentId: Int, bookLineIds: Array) { + openInterface(player, componentId) // Important: Opens the current interface. + for (i in bookLineIds) { + player.packetDispatch.sendString("", componentId, i) + } + } + + /** Clear all buttons rather than leaving invisible button rows. */ + fun clearButtons(player: Player, componentId: Int, bookButtonIds: Array) { + for (i in bookButtonIds) { + player.packetDispatch.sendInterfaceConfig(componentId, i, true) + } + } + + /** Set title of book. */ + fun setTitle(player: Player, componentId: Int, bookLineIds: Array, title: String) { + player.packetDispatch.sendString(title, componentId, bookLineIds[0]) + } + + /** Set pagination numbers of current page in book. CurrentPage is 0 index. */ + fun setPagination(player: Player, componentId: Int, bookLineIds: Array, bookButtonIds: Array, currentPage: Int, totalPages: Int, hasRightPage: Boolean) { + player.packetDispatch.sendInterfaceConfig(componentId, bookButtonIds[0], currentPage <= 0) + player.packetDispatch.sendInterfaceConfig(componentId, bookButtonIds[1], currentPage >= totalPages - 1) + player.packetDispatch.sendString("" + (currentPage * 2 + 1), componentId, bookLineIds[1]) + player.packetDispatch.sendString("" + (currentPage * 2 + 2), componentId, bookLineIds[2]) + if (hasRightPage) { + // If there's no right side page, remove the page number. Usually for odd paged books. + if (componentId == FANCY_BOOK_26) { + player.packetDispatch.sendString("", componentId, FANCY_BOOK_26_LINE_IDS[2]) + } else if (componentId == FANCY_BOOK_2_27) { + player.packetDispatch.sendString("", componentId, FANCY_BOOK_2_27_LINE_IDS[2]) + } else if (componentId == FANCY_BOOK_3_49) { + player.packetDispatch.sendString("", componentId, FANCY_BOOK_3_49_LINE_IDS[2]) + } + } + } + + /** Set text contents of book. CurrentPage is 0 index. */ + fun setPageContent(player: Player, componentId: Int, bookLineIds: Array, bookButtonIds: Array, currentPage: Int, contents: Array) { + for (page in contents[currentPage].pages) { + for (line in page.lines) { + // This is to prevent error child lines being set and crashing the client. + if (bookLineIds.contains(line.child)) { + player.packetDispatch.sendString(line.message, componentId, line.child) + } + if (bookButtonIds.contains(line.child)) { + player.packetDispatch.sendInterfaceConfig(componentId, line.child, false) + player.packetDispatch.sendString(line.message, componentId, line.child) + } + } + + } + } + + /** Sets models(pictures) on lineId of pageSet (0 index). Call this in the display function after pageSetup. */ + fun setModelOnPage(player: Player, pageSet: Int, modelId: Int, componentId: Int, enableLineId: Int, drawLineId: Int, zoom: Int, pitch: Int, yaw: Int) { + if (pageSet == getAttribute(player, CURRENT_PAGE_ATTRIBUTE, 0)) { + player.packetDispatch.sendInterfaceConfig(componentId, enableLineId, false) + player.packetDispatch.sendModelOnInterface(modelId, componentId, drawLineId, 0) + player.packetDispatch.sendAngleOnInterface(componentId, drawLineId, zoom, pitch, yaw) + } else { + player.packetDispatch.sendInterfaceConfig(componentId, enableLineId, true) + } + } + + /** Function to check if player read to the last page. For quest triggers. */ + fun isLastPage(pageNum: Int, totalPages: Int): Boolean { + return pageNum == totalPages - 1 + } + + /** PRIVATE: Increments the current page and invokes the callback function. */ + private fun changePageAndCallback(player: Player, increment: Int, buttonId: Int) { + val callback: ((player: Player, pageNum: Int, buttonId: Int) -> Boolean)? = + getAttribute(player, CALLBACK_ATTRIBUTE, null) + val currentPage = getAttribute(player, CURRENT_PAGE_ATTRIBUTE, 0) + setAttribute(player, CURRENT_PAGE_ATTRIBUTE, currentPage + increment) + + callback?.invoke(player, currentPage + increment, buttonId) + } + } + + override fun defineInterfaceListeners() { + on(FANCY_BOOK_26) { player, _, _, buttonID, _, _ -> + when (buttonID) { + FANCY_BOOK_26_BUTTON_IDS[0] -> { changePageAndCallback(player, -1, buttonID) } + FANCY_BOOK_26_BUTTON_IDS[1] -> { changePageAndCallback(player, 1, buttonID) } + else -> (changePageAndCallback(player, 0, buttonID)) + } + return@on true + } + on(FANCY_BOOK_2_27) { player, _, _, buttonID, _, _ -> + when (buttonID) { + FANCY_BOOK_2_27_BUTTON_IDS[0] -> { changePageAndCallback(player, -1, buttonID) } + FANCY_BOOK_2_27_BUTTON_IDS[1] -> { changePageAndCallback(player, 1, buttonID) } + else -> (changePageAndCallback(player, 0, buttonID)) + } + return@on true + } + on(FANCY_BOOK_3_49) { player, _, _, buttonID, _, _ -> + when (buttonID) { + FANCY_BOOK_3_49_BUTTON_IDS[0] -> { changePageAndCallback(player, -1, buttonID) } + FANCY_BOOK_3_49_BUTTON_IDS[1] -> { changePageAndCallback(player, 1, buttonID) } + else -> (changePageAndCallback(player, 0, buttonID)) + } + return@on true + } + } +} + +/** Constructs a new PageSet object. */ +class PageSet(vararg pages: Page) { + val pages: Array + + init { + this.pages = pages as Array + } +} + +/** Constructs a new Page object. */ +class Page(vararg lines: BookLine) { + val lines: Array + + init { + this.lines = lines as Array + } +} + +/** Constructs a new BookLine object. */ +class BookLine( + val message: String, + val child: Int +) diff --git a/Server/src/main/content/global/handlers/iface/CharacterDesignInterface.java b/Server/src/main/content/global/handlers/iface/CharacterDesignInterface.java new file mode 100644 index 0000000..62c8657 --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/CharacterDesignInterface.java @@ -0,0 +1,34 @@ +package content.global.handlers.iface; + +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import content.region.misc.tutisland.handlers.iface.CharacterDesign; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents a component plugin to handle the character design interface. + * @author 'Vexia + * @version 1.9 + */ +@Initializable +public final class CharacterDesignInterface extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.put(771, this); + return this; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + switch (opcode) { + case 155: + CharacterDesign.handleButtons(player, button); + break; + } + return true; + } +} diff --git a/Server/src/main/content/global/handlers/iface/ChocatriceIncubationInterface.kt b/Server/src/main/content/global/handlers/iface/ChocatriceIncubationInterface.kt new file mode 100644 index 0000000..d086cd9 --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/ChocatriceIncubationInterface.kt @@ -0,0 +1,35 @@ +package content.global.handlers.iface + +import core.game.component.Component +import core.game.component.ComponentDefinition +import core.game.component.ComponentPlugin +import core.game.node.entity.player.Player +import core.plugin.Plugin + +/** + * I found a bunch of varps for this interface so I've documented them here. + * to set, for example, COLD/HOT bar height, you need to send player.configmanager.set(GAUGE_VARP, (height shl COLD_OFFSET) or (height shl HOT_OFFSET)) + * bar gauges go up to 12 + * heat gauge at the top goes a full 360, though the edge is at roughly 160 + * @author Ceikry + */ +private const val GAUGE_UPDATE_SCRIPT = 894 +private const val COLD_OFFSET = 22 +private const val HOT_OFFSET = 18 +private const val GAUGE_OFFSET = 15 +private const val GAUGE_VARP = 1205 +private const val METER_VARP = 1201 +private const val BUTTON_ADD_COLD = 16 +private const val BUTTON_ADD_HOT = 18 + +class IncubationInterface : ComponentPlugin() { + + override fun handle(player: Player?, component: Component?, opcode: Int, button: Int, slot: Int, itemId: Int): Boolean { + TODO("Not yet implemented") + } + + override fun newInstance(arg: Any?): Plugin { + ComponentDefinition.put(717, this) + return this + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/iface/ClanInterfacePlugin.java b/Server/src/main/content/global/handlers/iface/ClanInterfacePlugin.java new file mode 100644 index 0000000..5003507 --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/ClanInterfacePlugin.java @@ -0,0 +1,159 @@ +package content.global.handlers.iface; + +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.RunScript; +import core.game.system.communication.ClanRank; +import core.game.system.communication.ClanRepository; +import core.net.amsc.MSPacketRepository; +import core.net.amsc.WorldCommunicator; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.tools.StringUtils; +import kotlin.Unit; + +import static core.api.ContentAPIKt.sendInputDialogue; +import static core.api.ContentAPIKt.setInterfaceText; + +/** + * Represents the plugin used to handle the clan interfaces. + * @author Vexia + */ +@Initializable +public final class ClanInterfacePlugin extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.put(590, this); + ComponentDefinition.put(589, this); + return this; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + switch (component.getId()) { + case 589: + switch (button) { + case 9: + if (player.getInterfaceManager().getComponent(590) != null) { + player.getPacketDispatch().sendMessage("Please close the interface you have open before using 'Clan Setup'"); + return true; + } + ClanRepository.openSettings(player); + return true; + case 14: + if (player.getIronmanManager().checkRestriction()) { + return false; + } + player.getDetails().getCommunication().toggleLootshare(player); + return true; + } + + break; + case 590: + final ClanRepository clan = ClanRepository.get(player.getName(), true); + switch (button) { + case 23: + if (opcode == 155) { + clan.setJoinRequirement(ClanRank.NONE); + } else { + clan.setJoinRequirement(getRank(opcode)); + } + player.getDetails().getCommunication().setJoinRequirement(clan.getJoinRequirement()); + MSPacketRepository.setClanSetting(player, 0, clan.getJoinRequirement()); + player.getPacketDispatch().sendString(clan.getJoinRequirement().getInfo(), 590, 23); + break; + case 24: + clan.setMessageRequirement(getRank(opcode)); + player.getDetails().getCommunication().setMessageRequirement(clan.getMessageRequirement()); + MSPacketRepository.setClanSetting(player, 1, clan.getMessageRequirement()); + player.getPacketDispatch().sendString(clan.getMessageRequirement().getInfo(), 590, 24); + break; + case 25: + clan.setKickRequirement(getRank(opcode)); + player.getDetails().getCommunication().setKickRequirement(clan.getKickRequirement()); + MSPacketRepository.setClanSetting(player, 2, clan.getKickRequirement()); + player.getPacketDispatch().sendString(clan.getKickRequirement().getInfo(), 590, 25); + clan.update(); + break; + case 26: + if (opcode == 230) { + clan.setLootRequirement(ClanRank.ADMINISTRATOR); + } else { + clan.setLootRequirement(getRank(opcode)); + } + player.getDetails().getCommunication().setLootRequirement(clan.getLootRequirement()); + MSPacketRepository.setClanSetting(player, 3, clan.getLootRequirement()); + player.getPacketDispatch().sendString(clan.getLootRequirement().getInfo(), 590, 26); + break; + case 22: + switch (opcode) { + case 196: + clan.setName("Chat disabled"); + player.getCommunication().setClanName(""); + player.getPacketDispatch().sendString(clan.getName(), 590, 22); + if (WorldCommunicator.isEnabled()) { + MSPacketRepository.sendClanRename(player, ""); + break; + } + clan.clean(true); + break; + default: + sendInputDialogue(player, false, "Enter clan prefix:", (value) -> { + String name = StringUtils.formatDisplayName((String) value); + setInterfaceText(player, name, 590, 22); + if(WorldCommunicator.isEnabled()){ + MSPacketRepository.sendClanRename(player, name); + clan.setName(name); + return Unit.INSTANCE; + } + if (clan.getName().equals("Chat disabled")) { + player.getPacketDispatch().sendMessage("Your clan channel has now been enabled!"); + player.getPacketDispatch().sendMessage("Join your channel by clicking 'Join Chat' and typing: " + player.getUsername()); + } + clan.setName(name); + player.getCommunication().setClanName(name); + clan.update(); + return Unit.INSTANCE; + }); + break; + } + break; + } + break; + } + return true; + } + + /** + * Gets the value to set. + * @param opcode the opcode. + * @return the value. + */ + public static ClanRank getRank(int opcode) { + switch (opcode) { + case 155: + return ClanRank.NONE; + case 196: + return ClanRank.FRIEND; + case 124: + return ClanRank.RECRUIT; + case 199: + return ClanRank.CORPORAL; + case 234: + return ClanRank.SERGEANT; + case 168: + return ClanRank.LIEUTENANT; + case 166: + return ClanRank.CAPTAIN; + case 64: + return ClanRank.GENERAL; + case 53: + return ClanRank.OWNER; + } + return ClanRank.NONE; + } + +} diff --git a/Server/src/main/content/global/handlers/iface/CombatTabInterface.java b/Server/src/main/content/global/handlers/iface/CombatTabInterface.java new file mode 100644 index 0000000..bd3938d --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/CombatTabInterface.java @@ -0,0 +1,103 @@ +package content.global.handlers.iface; + +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.combat.equipment.WeaponInterface.WeaponInterfaces; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the combat tab interface. + * @author Emperor + * @author Vexia' + * @version 1.0 + */ +@Initializable +public class CombatTabInterface extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (WeaponInterfaces inter : WeaponInterfaces.values()) { + ComponentDefinition.put(inter.getInterfaceId(), this); + } + ComponentDefinition.put(92, this); + return this; + } + + @Override + public boolean handle(final Player p, Component component, int opcode, int button, int slot, int itemId) { + switch (button) { + case 7: + case 9: + case 24: + case 26: + case 27: + GameWorld.getPulser().submit(new Pulse(1, p) { + @Override + public boolean pulse() { + p.getSettings().toggleRetaliating(); + return true; + } + }); + break; + case 11: + case 10: + case 8: + case 85: + GameWorld.getPulser().submit(new Pulse(1, p) { + @Override + public boolean pulse() { + WeaponInterface inter = p.getExtension(WeaponInterface.class); + if (inter != null && inter.isSpecialBar()) { + p.getSettings().toggleSpecialBar(); + if (p.getSettings().isSpecialToggled()) { + CombatSwingHandler handler; + if ((handler = CombatStyle.MELEE.getSwingHandler().getSpecial(p.getEquipment().getNew(3).getId())) != null) { + @SuppressWarnings("unchecked") + Plugin plugin = (Plugin) ((Object) handler); + if (plugin.fireEvent("instant_spec", p) == Boolean.TRUE) { + handleInstantSpec(p, handler, plugin); + } + } + } + } + return true; + } + }); + break; + case 0: + default: + WeaponInterface inter = p.getExtension(WeaponInterface.class); + if (inter == null) { + return false; + } + if (inter.setAttackStyle(button)) { + if (button == 4 || button == 5) { + inter.openAutocastSelect(); + } else if (p.getProperties().getAutocastSpell() != null) { + inter.selectAutoSpell(-1, false); + } + return true; + } + return false; + } + return true; + } + + /** + * Method used to handle an instance special attack. + * @param p the player. + * @param handler the handler. + * @param plugin the plugin. + */ + private static void handleInstantSpec(Player p, CombatSwingHandler handler, Plugin plugin) { + handler.swing(p, p.getProperties().getCombatPulse().getVictim(), null); + } +} diff --git a/Server/src/main/content/global/handlers/iface/CreditShopInterface.kt b/Server/src/main/content/global/handlers/iface/CreditShopInterface.kt new file mode 100644 index 0000000..e45f3ef --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/CreditShopInterface.kt @@ -0,0 +1,80 @@ +package content.global.handlers.iface + +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.item.Item +import org.rs09.consts.Components +import org.rs09.consts.Items +import core.game.interaction.InterfaceListener + +class CreditShopInterface : InterfaceListener { + + val CREDIT_SHOP = Components.CREDIT_SHOP + val TEXT_CHILD = 39 + + override fun defineInterfaceListeners() { + on(CREDIT_SHOP){player, component, opcode, buttonID, slot, itemID -> + val item = getItem(buttonID) + + if(opcode == 155){ + sendDialogue(player, "This item costs ${item.price} credits.") + return@on true + } + + if(buttonID == 14 || buttonID == 21){ + val specific = when(opcode){ + 196 -> if(buttonID == 14) Items.RED_PARTYHAT_1038 else Items.RED_HWEEN_MASK_1057 + 124 -> if(buttonID == 14) Items.GREEN_PARTYHAT_1044 else Items.GREEN_HWEEN_MASK_1053 + 199 -> if(buttonID == 14) Items.BLUE_PARTYHAT_1042 else Items.BLUE_HWEEN_MASK_1055 + 234 -> Items.YELLOW_PARTYHAT_1040 + 168 -> Items.PURPLE_PARTYHAT_1046 + 166 -> Items.WHITE_PARTYHAT_1048 + else -> Items.DWARF_WEED_SEED_5303 + } + attemptPurchase(player,specific,item.price) + } else { + attemptPurchase(player,item.id,item.price) + } + return@on true + } + + onOpen(CREDIT_SHOP){player, component -> + sendCredits(player) + return@onOpen true + } + } + + private fun getItem(buttonID: Int): ShopItem { + return when(buttonID){ + 14 -> ShopItem(Items.BLUE_PARTYHAT_1042,75) + 18 -> ShopItem(Items.SCYTHE_1419,100) + 20 -> ShopItem(Items.JANGLES_THE_MONKEY_14648,200) + 17 -> ShopItem(Items.CHRISTMAS_CRACKER_962,65) + 21 -> ShopItem(Items.BLUE_HWEEN_MASK_1055,65) + 16 -> ShopItem(Items.SANTA_HAT_1050,65) + 19 -> ShopItem(Items.BUNNY_EARS_1037,150) + 15 -> ShopItem(Items.EASTER_RING_7927,100) + else -> ShopItem(0,0) + } + } + + fun sendCredits(player: Player){ + setInterfaceText(player, "You have ${player.details.credits} credits to spend.", CREDIT_SHOP, TEXT_CHILD) + } + + fun attemptPurchase(player: Player, item: Int, price: Int){ + if(player.details.credits < price){ + sendDialogue(player, "You don't have enough credits for that.") + return + } + + if(player.inventory.add(Item(item))){ + player.details.credits -= price + } else { + sendDialogue(player, "You don't have enough inventory space for that.") + } + sendCredits(player) + } + + internal class ShopItem(val id: Int, val price: Int) +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/iface/CrystalKeyChestPlugin.java b/Server/src/main/content/global/handlers/iface/CrystalKeyChestPlugin.java new file mode 100644 index 0000000..852eb49 --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/CrystalKeyChestPlugin.java @@ -0,0 +1,50 @@ +package content.global.handlers.iface; + +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; + +@Initializable +public class CrystalKeyChestPlugin extends ComponentPlugin { + + private final Integer CHEST_INTERFACE = 501; + + private Player player; + + public CrystalKeyChestPlugin() { + /* + * Empty + */ + } + + public CrystalKeyChestPlugin(Player player) { + this.player = player; + } + + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.put(CHEST_INTERFACE, this); + return this; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + return false; + } + + public void constructInterface(Player player) { + Integer[] hiddenChildren = new Integer[] { 3, 4, 5, 6, 7}; + Component component = new Component(CHEST_INTERFACE); + for (int i = 3; i < hiddenChildren.length; i++) { + player.getPacketDispatch().sendInterfaceConfig(CHEST_INTERFACE, i, true); + } + player.getPacketDispatch().sendItemOnInterface(989, 1, CHEST_INTERFACE, hiddenChildren[2]); + player.getInterfaceManager().open(component); + this.player = player; + } + +} diff --git a/Server/src/main/content/global/handlers/iface/DeathInterfacePlugin.java b/Server/src/main/content/global/handlers/iface/DeathInterfacePlugin.java new file mode 100644 index 0000000..5b57c30 --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/DeathInterfacePlugin.java @@ -0,0 +1,32 @@ +package content.global.handlers.iface; + +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Handles the death interface. + * @author Vexia + */ +@Initializable +public final class DeathInterfacePlugin extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.forId(153).setPlugin(this); + return this; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + if (button == 1) { + player.getSavedData().getGlobalData().setDisableDeathScreen(true); + player.getInterfaceManager().close(); + } + return true; + } + +} diff --git a/Server/src/main/content/global/handlers/iface/EmoteTabInterface.java b/Server/src/main/content/global/handlers/iface/EmoteTabInterface.java new file mode 100644 index 0000000..7506f5f --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/EmoteTabInterface.java @@ -0,0 +1,30 @@ +package content.global.handlers.iface; + +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.emote.Emotes; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Handles the emote tab interface. + * @author Vexia + * + */ +@Initializable +public final class EmoteTabInterface extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.put(464, this); + return this; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + Emotes.handle(player, button); + return true; + } +} diff --git a/Server/src/main/content/global/handlers/iface/EquipmentInterface.java b/Server/src/main/content/global/handlers/iface/EquipmentInterface.java new file mode 100644 index 0000000..f8cfa26 --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/EquipmentInterface.java @@ -0,0 +1,231 @@ +package content.global.handlers.iface; + +import content.global.skill.summoning.familiar.BurdenBeast; +import core.api.ContentAPIKt; +import core.cache.def.impl.ItemDefinition; +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.container.Container; +import core.game.container.ContainerEvent; +import core.game.container.ContainerListener; +import core.game.container.access.InterfaceContainer; +import core.game.container.impl.EquipmentContainer; +import core.game.interaction.OptionHandler; +import core.game.node.entity.combat.DeathTask; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.prayer.PrayerType; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.net.packet.PacketRepository; +import core.net.packet.context.ContainerContext; +import core.net.packet.out.ContainerPacket; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.game.global.action.EquipHandler; +import core.game.interaction.IntType; +import core.game.interaction.InteractionListeners; +import core.game.world.GameWorld; +import core.tools.Log; + +/** + * Represents the equipment interface. + * @author Emperor + * + */ +@Initializable +public final class EquipmentInterface extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.put(102, this); + ComponentDefinition.put(387, this); + ComponentDefinition.put(667, this); + ComponentDefinition.put(670, this); + return this; + } + + @Override + public boolean handle(final Player p, Component component, int opcode, int button, final int slot, final int itemId) { + if (component.getId() == 667) { + if (button != 14) { + return false; + } + switch (opcode) { + case 155: + p.getPulseManager().clear(); + GameWorld.getPulser().submit(new Pulse(1, p) { + @Override + public boolean pulse() { + EquipHandler.unequip(p, slot, itemId); + return true; + } + }); + return true; + case 9: + p.sendMessage(p.getEquipment().get(slot).getDefinition().getExamine()); + return true; + case 196: + GameWorld.getPulser().submit(new Pulse(1, p) { + @Override + public boolean pulse() { + operate(p, slot, itemId); + return true; + } + }); + return true; + } + return false; + } + else if (component.getId() == 670) { + switch (opcode) { + case 155: + p.getPulseManager().clear(); + final Item item = p.getInventory().get(slot); + GameWorld.getPulser().submit(new Pulse(1, p) { + @Override + public boolean pulse() { + if (item == null) return true; + InteractionListeners.run(item.getId(), IntType.ITEM,"equip",p, item); + return true; + } + }); + return true; + case 9: + p.sendMessage(p.getInventory().get(slot).getDefinition().getExamine()); + return true; + } + } + switch (opcode) { + case 206: + if (button != 28) { + return false; + } + GameWorld.getPulser().submit(new Pulse(1, p) { + @Override + public boolean pulse() { + operate(p, slot, itemId); + return true; + } + }); + return true; + default: + switch (button) { + case 52: + if (p.getInterfaceManager().isOpened() && p.getInterfaceManager().getOpened().getId() == 102) { + return true; + } + + // (Highlight white items are auto destroyed on death Enum#616 (Items kept on death interface) TODO: Parse server sided + // SCRIPT 118 - Items kept on death interface CS + // ARG 0: Safe location check Takes: 0 Safe Area/2 in POH/3 in Castle Wars/4 in Trouble Brewing/5 in Barbass + int zoneType = p.getZoneMonitor().getType(); + // ARG 1: Amount of items kept on death Takes: 0/1/3/4 + Container[] itemArray = DeathTask.getContainers(p); + Container kept = itemArray[0]; + int amtKeptOnDeath = kept.itemCount(); + if (amtKeptOnDeath > 4 && zoneType == 0) { + ContentAPIKt.log(this.getClass(), Log.ERR, "Items kept on death interface should not contain more than 4 items when not in a safe zone!"); + } + // ARG 2: Item kept on death slot 0 + int slot0 = kept.getId(0); + // ARG 3: Item kept on death slot 1 + int slot1 = kept.getId(1); + // ARG 4: Item kept on death slot 2 + int slot2 = kept.getId(2); + // ARG 5: Item kept on death slot 3 + int slot3 = kept.getId(3); + // ARG 6: Player skulled Takes: 0 not skulled/1 skulled + int skulled = p.getSkullManager().isSkulled() ? 1 : 0; + // ARG 7: Player has summoning creature out Takes: 0 not out/1 Creature summoned + int hasBoB; + if (p.getFamiliarManager().hasFamiliar()) { + if (p.getFamiliarManager().getFamiliar().isBurdenBeast()) { + hasBoB = ((BurdenBeast) p.getFamiliarManager().getFamiliar()).getContainer().isEmpty() ? 0 : 1; + } else { + hasBoB = 0; + } + } else { + hasBoB = 0; + } + // ARG 8: String for effect: + // if (arg1 == 0) arg8 + " This reduces the items you keep from three to zero!" + // if (arg1 == 1) arg8 + " This reduces the items you keep from three to zero!" + "
" + "
" + "However, you also have the " + "" + "Protect Items" + "" + " prayer active, which saves you one extra item!"); + Object[] params = new Object[] { hasBoB, skulled, slot3, slot2, slot1, slot0, amtKeptOnDeath, zoneType, "You are skulled." }; + p.getPacketDispatch().sendRunScript(118, "siiooooii", params); + + p.getInterfaceManager().openComponent(102); + break; + case 28: + if (opcode == 81) { + p.getPulseManager().clear(); + GameWorld.getPulser().submit(new Pulse(1, p) { + @Override + public boolean pulse() { + EquipHandler.unequip(p, slot, itemId); + return true; + } + }); + return true; + } + break; + case 55: + if (p.getInterfaceManager().isOpened() && p.getInterfaceManager().getOpened().getId() == 667) { + return true; + } + final ContainerListener listener = new ContainerListener() { + @Override + public void update(Container c, ContainerEvent e) { + PacketRepository.send(ContainerPacket.class, new ContainerContext(p, -1, -1, 98, e.getItems(), false, e.getSlots())); + } + + @Override + public void refresh(Container c) { + PacketRepository.send(ContainerPacket.class, new ContainerContext(p, -1, -1, 98, c, false)); + } + }; + p.getInterfaceManager().openComponent(667).setCloseEvent((player, c) -> { + player.removeAttribute("equip_stats_open"); + player.getInterfaceManager().closeSingleTab(); + player.getInventory().getListeners().remove(listener); + return true; + }); + p.setAttribute("equip_stats_open", true); + EquipmentContainer.update(p); + p.getInterfaceManager().openSingleTab(new Component(670)); + InterfaceContainer.generateItems(p, p.getInventory().toArray(), new String[] { "Equip" }, 670, 0, 7, 4, 93); + p.getInventory().getListeners().add(listener); + p.getInventory().refresh(); + ItemDefinition.statsUpdate(p); + p.getPacketDispatch().sendIfaceSettings(1278, 14, 667, 0, 13); + break; + } + } + return true; + } + + /** + * Operates an item. + * @param player The player. + * @param slot The container slot. + * @param itemId The item id. + */ + public void operate(Player player, int slot, int itemId) { + if (slot < 0 || slot > 13) { + return; + } + Item item = player.getEquipment().get(slot); + if (item == null) { + return; + } + if(InteractionListeners.run(item.getId(),IntType.ITEM,"operate",player,item)){ + return; + } + OptionHandler handler = item.getOperateHandler(); + if (handler != null && handler.handle(player, item, "operate")) { + return; + } + player.getPacketDispatch().sendMessage("You can't operate that."); + } + +} diff --git a/Server/src/main/content/global/handlers/iface/ExperienceInterface.kt b/Server/src/main/content/global/handlers/iface/ExperienceInterface.kt new file mode 100644 index 0000000..c7003ea --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/ExperienceInterface.kt @@ -0,0 +1,101 @@ +package content.global.handlers.iface + +import core.api.* +import core.game.component.Component +import core.game.component.ComponentDefinition +import core.game.component.ComponentPlugin +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import core.plugin.Plugin +import core.tools.Log +import org.rs09.consts.Sounds +import content.data.Quests + +/** + * Represents the experience interface. + * @author Ceikry + */ +@Initializable +class ExperienceInterface() : ComponentPlugin() { + + @Throws(Throwable::class) + override fun newInstance(arg: Any?): Plugin { + ComponentDefinition.put(COMPONENT_ID, this) + return this + } + + override fun handle(player: Player, component: Component, opcode: Int, button: Int, slot: Int, itemId: Int): Boolean { + if(button == 2){ + val confirmedSkill = player.getAttribute("exp_interface:skill",-1) + if(confirmedSkill == -1){ + player.sendMessage("You must first select a skill.") + } else { + player.removeAttribute("exp_interface:skill") + when(confirmedSkill){ + Skills.HERBLORE -> if(!checkHerblore(player)) player.sendMessage("You need to have completed Druidic Ritual for this.").also { return true } + Skills.RUNECRAFTING -> if(!checkRunecrafting(player)) player.sendMessage("You need to have completed Rune Mysteries for this.").also { return true } + Skills.SUMMONING -> if(!checkSummoning(player)) player.sendMessage("You need to have completed Wolf Whistle for this.").also { return true } + } + val caller = player.attributes["caller"] + caller ?: return true + if(caller is Plugin<*>) + caller.handleSelectionCallback(confirmedSkill, player) + else (caller as (Int,Player) -> Unit).invoke(confirmedSkill,player) + playAudio(player, SOUND) + closeInterface(player) + } + } else { + val skill = when (button) { + 29 -> Skills.ATTACK + 30 -> Skills.STRENGTH + 31 -> Skills.DEFENCE + 32 -> Skills.RANGE + 35 -> Skills.MAGIC + 39 -> Skills.CRAFTING + 34 -> Skills.HITPOINTS + 33 -> Skills.PRAYER + 36 -> Skills.AGILITY + 37 -> Skills.HERBLORE + 38 -> Skills.THIEVING + 43 -> Skills.FISHING + 47 -> Skills.RUNECRAFTING + 48 -> Skills.SLAYER + 50 -> Skills.FARMING + 41 -> Skills.MINING + 42 -> Skills.SMITHING + 49 -> Skills.HUNTER + 52 -> Skills.SUMMONING + 45 -> Skills.COOKING + 44 -> Skills.FIREMAKING + 46 -> Skills.WOODCUTTING + 40 -> Skills.FLETCHING + 51 -> Skills.CONSTRUCTION + else -> Skills.SLAYER.also { log(this::class.java, Log.WARN, "EXP_INTERFACE: Invalid SKILL CHOICE BUTTON: $button") } + } + player.setAttribute("exp_interface:skill",skill) + } + return true + } + + private fun checkHerblore(player: Player): Boolean{ + return (player.questRepository.isComplete(Quests.DRUIDIC_RITUAL)) + } + + private fun checkSummoning(player: Player): Boolean{ + return player.questRepository.isComplete(Quests.WOLF_WHISTLE) + } + + private fun checkRunecrafting(player: Player): Boolean{ + return player.questRepository.isComplete(Quests.RUNE_MYSTERIES) + } + + companion object { + /** + * Represents the sound to send. + */ + private val SOUND = Sounds.TBCU_FINDGEM_1270 + @JvmField + public val COMPONENT_ID = 134 + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/iface/FairyRingInterface.kt b/Server/src/main/content/global/handlers/iface/FairyRingInterface.kt new file mode 100644 index 0000000..69bba13 --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/FairyRingInterface.kt @@ -0,0 +1,230 @@ +package content.global.handlers.iface + +import core.api.* +import core.game.event.FairyRingDialEvent +import core.game.interaction.InterfaceListener +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.TeleportManager +import core.game.system.task.Pulse +import core.game.world.GameWorld +import core.game.world.map.Location +import core.game.world.map.RegionManager +import core.tools.RandomFunction +import content.data.Quests + +/** + * Handles the fairy ring interface + * @author Ceikry + */ +class FairyRingInterface : InterfaceListener { + companion object { + const val RINGS_IFACE = 734 + const val LOG_IFACE_ID = 735 + const val VARP_F_RING = 816 + const val VB_LOG_SORT_ORDER = 4618 + const val VB_RING_1 = 2341 + const val VB_RING_2 = 2342 + const val VB_RING_3 = 2343 + val RING_1 = arrayOf('a','d','c','b') + val RING_2 = arrayOf('i','l','k','j') + val RING_3 = arrayOf('p','s','r','q') + } + + override fun defineInterfaceListeners() { + + onOpen(RINGS_IFACE){ player, _ -> + openSingleTab(player, LOG_IFACE_ID) + saveVarp(player, VARP_F_RING) + return@onOpen true + } + + onOpen(LOG_IFACE_ID){ player, _ -> + drawLog(player) + return@onOpen true + } + + onClose(RINGS_IFACE){ player, _ -> + closeTabInterface(player) + return@onClose true + } + + on(RINGS_IFACE){ player, _, _, buttonID, _, _ -> + when(buttonID){ + 23 -> increment(player,1) + 25 -> increment(player,2) + 27 -> increment(player,3) + 24 -> decrement(player,1) + 26 -> decrement(player,2) + 28 -> decrement(player,3) + 21 -> confirm(player) + } + return@on true + } + + on(LOG_IFACE_ID,12){ player, _, _, _, _, _ -> + toggleSortOrder(player) + return@on true + } + + } + + /** + * Draws the travel log interface + * Currently, the visited logs is a bool array in globalData. Someone should migrate this to prefs or something at some point. + * On transmit of Varp 816, which all used varbits are part of here, the CS2 is invoked to populate the codes in the log and sort them correctly. + * @param player The player to draw the interface for + */ + private fun drawLog (player: Player) + { + for (i in FairyRing.values().indices) { + if (!player.savedData.globalData.hasTravelLog(i)) { + continue + } + val ring = FairyRing.values()[i] + if (ring.childId == -1) { + continue + } + setInterfaceText(player, "
${ring.tip}", LOG_IFACE_ID, ring.childId) + } + } + + private fun toggleSortOrder(player: Player) { + val curSort = getVarbit(player, VB_LOG_SORT_ORDER) == 0 + setVarbit(player, VB_LOG_SORT_ORDER, if (curSort) 1 else 0) + drawLog(player) + } + + fun increment(player: Player,ring: Int) { + val vbit = when(ring) { + 1 -> VB_RING_1 + 2 -> VB_RING_2 + 3 -> VB_RING_3 + else -> return + } + val curIndex = getVarbit(player, vbit) + val nextIndex: Int = if(curIndex == 3) 0 + else curIndex + 1 + setVarbit(player, vbit, nextIndex) + } + + fun decrement(player: Player,ring: Int){ + val vbit = when(ring) { + 1 -> VB_RING_1 + 2 -> VB_RING_2 + 3 -> VB_RING_3 + else -> return + } + val curIndex = getVarbit(player, vbit) + val nextIndex: Int = if(curIndex == 0) 3 + else curIndex - 1 + setVarbit(player, vbit, nextIndex) + } + + private fun confirm(player: Player){ + val ring1index = getVarbit(player, VB_RING_1) + val ring2index = getVarbit(player, VB_RING_2) + val ring3index = getVarbit(player, VB_RING_3) + val code = "${RING_1[ring1index]}${RING_2[ring2index]}${RING_3[ring3index]}" + val ring: FairyRing? = try { + FairyRing.valueOf(code.uppercase()) + } catch (e: Exception) { null } + + var tile = ring?.tile + if(ring?.checkAccess(player) != true){ + sendDialogue(player, "The ring seems to reject you.") + tile = null + } + if (ring == null || tile == null) { + val center = Location(2412, 4434, 0) + tile = if (RandomFunction.random(2) == 1) { + center.transform(RandomFunction.random(2, 6), RandomFunction.random(2, 6), 0) + } else { + center.transform(RandomFunction.random(-2, -6), RandomFunction.random(-2, -6), 0) + } + if (!RegionManager.isTeleportPermitted(tile) || RegionManager.getObject(tile) != null) { + tile = Location.create(2412, 4431, 0) + } + GameWorld.Pulser.submit(object : Pulse(4, player) { + override fun pulse(): Boolean { + sendPlayerDialogue(player, "Wow, fairy magic sure is useful, I hardly moved at all!", core.game.dialogue.FacialExpression.AMAZED) + return true + } + }) + } else { + if (!player.savedData.globalData.hasTravelLog(ring.ordinal)) { + player.savedData.globalData.setTravelLog(ring.ordinal) + } + } + closeInterface(player) + + ring.let { + if (it == null) { + return@let + } + + player.dispatch(FairyRingDialEvent(it)) + teleport(player, tile!!, TeleportManager.TeleportType.FAIRY_RING) + } + } +} + +enum class FairyRing(val tile: Location?, val tip: String = "", val childId: Int = -1) { + AIQ(Location.create(2996, 3114, 0), "Asgarnia: Mudskipper Point", 15), + AIR(Location.create(2700, 3247, 0), "Islands: South of Witchaven", 16), + AJQ(Location.create(2735, 5221, 0), "Dungeons: Dark cave south of Dorgesh-Kaann", 19), + ALR(Location.create(3059, 4875, 0), "Other realms: Abyssal Area", 28), + AJR(Location.create(2780, 3613, 0), "Kandarin: Slayer cave south-east of Rellekka", 20), + AJS(Location.create(2500, 3896, 0), "Islands: Penguins near Miscellania", 21), + AKQ(Location.create(2319, 3619, 0), "Kandarin: Piscatoris Hunter area", 23), + AKS(Location.create(2571, 2956, 0), "Feldip Hills: Jungle Hunter area", 25), + ALQ(Location.create(3597, 3495, 0), "Morytania: Haunted Woods east of Canifis", 27) { + override fun checkAccess(player: Player) : Boolean { + return requireQuest(player, Quests.PRIEST_IN_PERIL, "to use this ring.") + } + }, + ALS(Location.create(2644, 3495, 0), "Kandarin: McGrubor's Wood", 29), + BIP(Location.create(3410, 3324, 0), "Islands: River Salve", 30), + BIQ(Location.create(3251, 3095, 0), "Kharidian Desert: Near Kalphite hive", 31), + BIS(Location.create(2635, 3266, 0), "Kandarin: Ardougne Zoo unicorns", 33), + BJR(null, "Other Realms: Realm of the Fisher King", 36), + BKP(Location.create(2385, 3035, 0), "Feldip Hills: South of Castle Wars", 38), + BKQ(Location.create(3041, 4532, 0), "Other realms: Enchanted Valley", 39), + BKR(Location.create(3469, 3431, 0), "Morytania: Mort Myre, south of Canifis", 40) { + override fun checkAccess(player: Player) : Boolean { + return requireQuest(player, Quests.PRIEST_IN_PERIL, "to use this ring.") + } + }, + BLP(Location.create(2437, 5126, 0), "Dungeons: TzHaar area", 42), + BLQ(null, "Yu'biusk", 43),//Location.create(2229, 4244, 1) + BLR(Location.create(2740, 3351, 0), "Kandarin: Legends' Guild", 44), + CIP(Location.create(2513, 3884, 0), "Islands: Miscellania", 46) { + override fun checkAccess(player: Player): Boolean { + return requireQuest(player, Quests.THE_FREMENNIK_TRIALS, "to use this ring.") + } + }, + CIQ(Location.create(2528, 3127, 0), "Kandarin: North-west of Yanille", 47), + CJR(Location.create(2705, 3576, 0), "Kandarin: Sinclair Mansion", 52), + CKP(Location.create(2075, 4848, 0), "Other realms: Cosmic Entity's plane", 54), + CKR(Location.create(2801, 3003, 0), "Karamja: South of Tai Bwo Wannai Village", 56), + CKS(Location.create(3447, 3470, 0), "Morytania: Canifis", 57) { + override fun checkAccess(player: Player) : Boolean { + return requireQuest(player, Quests.PRIEST_IN_PERIL, "to use this ring.") + } + }, + CLP(Location.create(3082, 3206, 0), "Islands: South of Draynor Village", 58), + CLS(Location.create(2682, 3081, 0), "Islands: Jungle spiders near Yanille", 61), + DIR(Location.create(3038, 5348, 0), "Other realms: Goraks' Plane", 64), + DIS(Location.create(3108, 3149, 0), "Misthalin: Wizards' Tower", 65), + DJP(Location.create(2658, 3230, 0), "Kandarin: Tower of Life", 66), + DJR(Location.create(2676, 3587, 0), "Kandarin: Sinclair Mansion (west)", 68), + DKP(Location.create(2900, 3111, 0), "Karamja: South of Musa Point", 70), + DKR(Location.create(3129, 3496, 0), "Misthalin: Edgeville", 72), + DKS(Location.create(2744, 3719, 0), "Kandarin: Snowy Hunter area", 73), + DLQ(Location.create(3423, 3016, 0), "Kharidian Desert: North of Nardah", 75), + DLR(Location.create(2213, 3099, 0), "Islands: Poison Waste south of Isafdar", 76), + AIS(null), AIP(null), AKP(null), FAIRY_HOME(Location.create(2412, 4434, 0)); + + open fun checkAccess(player: Player) : Boolean { + return true + } +} diff --git a/Server/src/main/content/global/handlers/iface/FurClothingInterface.kt b/Server/src/main/content/global/handlers/iface/FurClothingInterface.kt new file mode 100644 index 0000000..c395840 --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/FurClothingInterface.kt @@ -0,0 +1,199 @@ +package content.global.handlers.iface + +import core.api.* +import core.game.component.Component +import core.game.component.ComponentDefinition +import core.game.component.ComponentPlugin +import core.game.container.access.InterfaceContainer +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import core.plugin.Plugin +import core.tools.colorize +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch + +private const val FUR_CLOTHING_COMPONENT_ID = 477 + +//Polar Kebbit +private val POLAR_CAMO_TOP = Item(10065) +private val POLAR_CAMO_LEGS = Item(10067) + +//COMMON/WOOD CAMO +private val WOOD_CAMO_TOP = Item(10053) +private val WOOD_CAMO_LEGS = Item(10055) + +//FELDIP/JUNGLE CAMO +private val JUNGLE_CAMO_TOP = Item(10057) +private val JUNGLE_CAMO_LEGS = Item(10059) + +//DESERT CAMO +private val DESERT_CAMO_TOP = Item(10061) +private val DESERT_CAMO_LEGS = Item(10063) + + +//Larupia +private val LARUPIA_HAT = Item(10045) +private val LARUPIA_TOP = Item(10043) +private val LARUPIA_LEGS = Item(10041) + +//Graahk +private val GRAAHK_HEADDRESS = Item(10051) +private val GRAAHK_TOP = Item(10049) +private val GRAAHK_LEGS = Item(10047) + +//KYATT +private val KYATT_HAT = Item(10039) +private val KYATT_TOP = Item(10037) +private val KYATT_LEGS = Item(10035) + +//SPECIAL +private val GLOVES_OF_SILENCE = Item(10075) +private val SPOTTED_CAPE = Item(10069) +private val SPOTTIER_CAPE = Item(10071) + + +private val OPTIONS = arrayOf("Buy 10","Buy 5","Buy 1","Value") + +//I just want to say that this monolith of fuckery ACTUALLY SEEMS TO BE THE WAY +//J*GEX HANDLED THIS. This is THEIR packet this is being sent in! The spacing lines up 1:1! +//Like holy what the fuck j*gex +private val ITEMS = arrayOf( + null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null, + null, POLAR_CAMO_TOP, null,null, POLAR_CAMO_LEGS,null,null,null,null, + null, WOOD_CAMO_TOP, null,null, WOOD_CAMO_LEGS,null,null,null, + null, JUNGLE_CAMO_TOP,null,null, JUNGLE_CAMO_LEGS,null,null,null, + null, DESERT_CAMO_TOP,null,null, DESERT_CAMO_LEGS,null,null,null,null, + null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null, + null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null, + null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null, + LARUPIA_HAT,null,null, LARUPIA_TOP,null,null, LARUPIA_LEGS,null,null,null,null, + GRAAHK_HEADDRESS,null,null, GRAAHK_TOP,null,null, GRAAHK_LEGS,null,null,null,null,null, + KYATT_HAT,null,null, KYATT_TOP,null,null, KYATT_LEGS, null,null,null, + null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null, + null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null, + null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null, + null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null, + null,null,null, GLOVES_OF_SILENCE,null,null,null,null,null,null,null, + null,null,null, SPOTTED_CAPE,null,null,null,null,null,null,null,null, + null,null,null, SPOTTIER_CAPE,null) + +/** + * Interface for custom fur clothing that is a 1:1 matchup in functionality and appearance to OSRS's. + * It's got a fuckhuge hideous monolith and I'm okay with that, it seems to be AUTHENTIC. + * @author Ceikry + */ +@Initializable +class FurClothingInterface : ComponentPlugin(){ + override fun open(player: Player?, component: Component?) { + super.open(player, component) + player ?: return + //Send the monolith of fuckery to the client to deal with + InterfaceContainer.generateItems(player, ITEMS, OPTIONS, FUR_CLOTHING_COMPONENT_ID, 26,12,33,5000) + + //Highlight the names of groups that contain a craftable item + //Running in a crouton because why the hell not. + GlobalScope.launch { + val checkedFurs = arrayListOf() + for(CLOTHING in FUR_CLOTHING.values()){ + if(checkedFurs.contains(CLOTHING.textContent)) continue + if(inInventory(player, CLOTHING.requiredFur.id, CLOTHING.requiredFur.amount)){ + setInterfaceText(player, colorize("%G${CLOTHING.textContent}"), FUR_CLOTHING_COMPONENT_ID, CLOTHING.textChildID) + checkedFurs.add(CLOTHING.textContent) + } + } + } + } + + override fun handle(player: Player?, component: Component?, opcode: Int, button: Int, slot: Int, itemId: Int): Boolean { + player ?: return false + + val clothingItem: FUR_CLOTHING? = when(slot){ + 34 -> FUR_CLOTHING.POLAR_KEBBIT_TOP + 37 -> FUR_CLOTHING.POLAR_KEBBIT_BOT + 43 -> FUR_CLOTHING.COMMON_KEBBIT_TOP + 46 -> FUR_CLOTHING.COMMON_KEBBIT_BOT + 51 -> FUR_CLOTHING.FELDIP_WEASEL_TOP + 54 -> FUR_CLOTHING.FELDIP_WEASEL_BOT + 59 -> FUR_CLOTHING.DESERT_DEVIL_TOP + 62 -> FUR_CLOTHING.DESERT_DEVIL_BOT + 166 -> FUR_CLOTHING.LARUPIA_HEAD + 169 -> FUR_CLOTHING.LARUPIA_CHEST + 172 -> FUR_CLOTHING.LARUPIA_BOT + 177 -> FUR_CLOTHING.GRAAHK_HEAD + 180 -> FUR_CLOTHING.GRAAHK_CHEST + 183 -> FUR_CLOTHING.GRAAHK_BOT + 189 -> FUR_CLOTHING.KYATT_HEAD + 192 -> FUR_CLOTHING.KYATT_CHEST + 195 -> FUR_CLOTHING.KYATT_BOT + 334 -> FUR_CLOTHING.GLOVES_SILENCE + 345 -> FUR_CLOTHING.SPOT_CAPE + 357 -> FUR_CLOTHING.DASH_CAPE + else -> null + } + + clothingItem ?: return false + + when(opcode){ + 196 -> buy(player,clothingItem,1) + 124 -> buy(player,clothingItem,5) + 199 -> buy(player,clothingItem,10) + 155 -> value(player,clothingItem) + } + return true + } + + private fun value(player: Player, clothing: FUR_CLOTHING){ + sendMessage(player,"${clothing.product.name} requires ${clothing.requiredFur.amount} ${clothing.requiredFur.name.toLowerCase()} and costs ${clothing.price} coins.") + } + + private fun buy(player: Player, clothing: FUR_CLOTHING, amount: Int){ + val coins = Item(995,clothing.price * amount) + val amtFurRequired = clothing.requiredFur.amount * amount + val requiredFur = Item(clothing.requiredFur.id,amtFurRequired) + + if(!inInventory(player, requiredFur.id, requiredFur.amount)){ + sendDialogue(player, "You don't have enough fur for that.") + return + } + + if(!inInventory(player, coins.id, coins.amount)){ + sendDialogue(player,"You can't afford that.") + return + } + + removeItem(player, requiredFur, Container.INVENTORY) + removeItem(player, coins, Container.INVENTORY) + addItem(player, clothing.product.id, amount) + } + + override fun newInstance(arg: Any?): Plugin { + ComponentDefinition.put(FUR_CLOTHING_COMPONENT_ID,this) + return this + } + + + //Enum for the various pieces, requirements, etc. + internal enum class FUR_CLOTHING(val requiredFur: Item, val price: Int, val product: Item, val textChildID: Int, val textContent: String){ + POLAR_KEBBIT_TOP(Item(10117,2),20, POLAR_CAMO_TOP,18,"Polar kebbit"), + POLAR_KEBBIT_BOT(Item(10117,2),20, POLAR_CAMO_LEGS,18,"Polar kebbit"), + COMMON_KEBBIT_TOP(Item(10121,2),20, WOOD_CAMO_TOP,19,"Common kebbit"), + COMMON_KEBBIT_BOT(Item(10121,2),20, WOOD_CAMO_LEGS,19,"Common kebbit"), + FELDIP_WEASEL_TOP(Item(10119,2),20, JUNGLE_CAMO_TOP,20,"Feldip weasel"), + FELDIP_WEASEL_BOT(Item(10119,2),20, JUNGLE_CAMO_LEGS,20,"Feldip weasel"), + DESERT_DEVIL_TOP(Item(10123,2),20, DESERT_CAMO_TOP,21,"Desert devil"), + DESERT_DEVIL_BOT(Item(10123,2),20, DESERT_CAMO_LEGS, 21, "Desert devil"), + LARUPIA_HEAD(Item(10095),500, LARUPIA_HAT,15,"Larupia"), + LARUPIA_CHEST(Item(10095),100, LARUPIA_TOP,15,"Larupia"), + LARUPIA_BOT(Item(10095),100, LARUPIA_LEGS,15,"Larupia"), + GRAAHK_HEAD(Item(10099),750, GRAAHK_HEADDRESS,16,"Graahk"), + GRAAHK_CHEST(Item(10099),150, GRAAHK_TOP,16,"Graahk"), + GRAAHK_BOT(Item(10099),150, GRAAHK_LEGS,16,"Graahk"), + KYATT_HEAD(Item(10103),1000, KYATT_HAT,17,"Kyatt"), + KYATT_CHEST(Item(10103),200, KYATT_TOP,17,"Kyatt"), + KYATT_BOT(Item(10103),200, KYATT_LEGS,17,"Kyatt"), + GLOVES_SILENCE(Item(10115,2),600, GLOVES_OF_SILENCE,22,"Dark kebbit"), + SPOT_CAPE(Item(10125,2),400, SPOTTED_CAPE,23,"Spotted kebbit"), + DASH_CAPE(Item(10127,2),800, SPOTTIER_CAPE,24,"Dashing kebbit") + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/iface/GameInterface.java b/Server/src/main/content/global/handlers/iface/GameInterface.java new file mode 100644 index 0000000..0c8754f --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/GameInterface.java @@ -0,0 +1,185 @@ +package content.global.handlers.iface; + +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.plugin.Initializable; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.combat.equipment.WeaponInterface.WeaponInterfaces; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.info.Rights; +import core.game.world.GameWorld; +import core.plugin.Plugin; + +/** + * Represents the component plugin used for the game interface. + * @author Vexia + * + */ +@Initializable +public final class GameInterface extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.put(740, this); + return this; + } + + @Override + public boolean handle(final Player player, Component component, int opcode, int button, int slot, int itemId) { + switch (component.getId()) { + case 740: + switch (button){ + case 3: + player.getInterfaceManager().closeChatbox(); + break; + } + return true; + case 746: + switch (button){ + case 12: + player.getPacketDispatch().sendString("When you have finished playing " + GameWorld.getSettings().getName() + ", always use the button below to logout safely. ", 182, 0); + break; + case 49: + player.getPacketDispatch().sendString("Friends List - " + GameWorld.getSettings().getName() + " " + GameWorld.getSettings().getWorldId(), 550, 3); + break; + case 110: + configureWorldMap(player); + break; + } + return true; + case 548: + if (button >= 38 && button<= 44 || button >= 20 && button <= 26) { + player.getInterfaceManager().setCurrentTabIndex(getTabIndex(button)); + } + //Interface buttons that advance the Tutorial Island stages + switch (button) { + case 21://Friends Tab + player.getPacketDispatch().sendString("Friends List -" + GameWorld.getSettings().getName() + " " + GameWorld.getSettings().getWorldId(), 550, 3); + break; + case 22://Ignore Tab + break; + case 24://Settings Tab + break; + case 25://Emotes Tab + break; + case 26://Music Tab + break; + case 38://Attack Tab + if (player.getExtension(WeaponInterface.class) == WeaponInterfaces.STAFF) { + final Component c = new Component(WeaponInterfaces.STAFF.getInterfaceId()); + player.getInterfaceManager().openTab(0, c); + final WeaponInterface inter = player.getExtension(WeaponInterface.class); + inter.updateInterface(); + } + break; + case 39://Skill Tab + break; + case 40://Quest Tab + /*if (GameWorld.isEconomyWorld()) { + player.getQuestRepository().syncronizeTab(player); + } else { + player.getSavedData().getSpawnData().drawStatsTab(player); + }*/ + + player.getQuestRepository().syncronizeTab(player); + break; + case 41://Inventory Tab + player.getInventory().refresh(); + break; + case 42://Worn Equipment Tab + break; + case 43://Prayer Tab + break; + case 44://Magic Tab + break; + case 66://World map + case 110: + configureWorldMap(player); + break; + case 69://Logout + player.getPacketDispatch().sendString("When you have finished playing " + GameWorld.getSettings().getName() + ", always use the button below to logout safely. ", 182, 0); + break; + } + return true; + case 750: + switch (opcode) { + case 155: + switch (button) { + case 1: + player.getSettings().toggleRun(); + break; + } + break; + } + return true; + case 751: + switch (opcode) { + case 155: + switch (button) { + case 27: + openReport(player); + break; + } + break; + } + return true; + } + return true; + } + + /** + * World map + * Thanks, Snickerize! + */ + private void configureWorldMap(Player player) { + if (player.inCombat()) { + player.getPacketDispatch().sendMessage("It wouldn't be very wise opening the world map during combat."); + return; + } + if(player.getLocks().isInteractionLocked() || player.getLocks().isMovementLocked()){ + player.getPacketDispatch().sendMessage("You can't do this right now."); + return; + } + player.getInterfaceManager().openWindowsPane(new Component(755)); + int posHash = (player.getLocation().getZ() << 28) | (player.getLocation().getX() << 14) | player.getLocation().getY(); + player.getPacketDispatch().sendScriptConfigs(622, posHash, "", 0); + player.getPacketDispatch().sendScriptConfigs(674, posHash, "", 0); + } + + /** + * Method used to open the report interface. + * @param player the player. + */ + public static void openReport(final Player player) { + player.getInterfaceManager().open(new Component(553)).setCloseEvent((player1, c) -> { + player1.getPacketDispatch().sendRunScript(80, ""); + player1.getPacketDispatch().sendRunScript(137, ""); + return true; + }); + player.getPacketDispatch().sendRunScript(508, ""); + if (player.getDetails().getRights() != Rights.REGULAR_PLAYER) { + for (int i = 0; i < 18; i++) { + player.getPacketDispatch().sendInterfaceConfig(553, i, false); + } + } + } + + /** + * Gets the tab index. + * @param button The button id. + * @return The tab index. + */ + private static int getTabIndex(int button) { + int tabIndex = button - 38; + if (button < 27) { + tabIndex = (button - 20) + 7; + } + return tabIndex; + } + + /** + * Configures the world map for a player. + * @param player The player. + */ +} diff --git a/Server/src/main/content/global/handlers/iface/GenericItemSelect.kt b/Server/src/main/content/global/handlers/iface/GenericItemSelect.kt new file mode 100644 index 0000000..beb2a29 --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/GenericItemSelect.kt @@ -0,0 +1,67 @@ +package content.global.handlers.iface + +import core.api.* +import core.tools.* +import core.game.interaction.* +import core.game.system.task.Pulse +import core.game.node.entity.player.Player + +class GenericItemSelect : InterfaceListener { + val GENERIC_ITEM_SELECT_IFACE = 12 + + override fun defineInterfaceListeners() { + onOpen(GENERIC_ITEM_SELECT_IFACE) {player, _ -> + player.pulseManager.run(object : Pulse() { + override fun pulse() : Boolean { + return false + } + override fun stop() { + super.stop() + player.interfaceManager.closeSingleTab() + } + }) + return@onOpen true + } + + on(GENERIC_ITEM_SELECT_IFACE){player, _, opcode, buttonID, slot, _ -> + processResponse(player, opcode, slot) + return@on true + } + + onClose(GENERIC_ITEM_SELECT_IFACE) {player, _ -> + removeAttribute(player, "itemselect-callback") + removeAttribute(player, "itemselect-keepalive") + return@onClose true + } + } + + private fun processResponse (player: Player, opcode: Int, slot: Int) { + val callback = getAttribute<((Int, Int) -> Unit)?>(player, "itemselect-callback", null) + if (callback == null) { + log (this::class.java, Log.WARN, "${player.name} is trying to use an item select prompt with no callback!") + return + } + + val optionIndex = when (opcode) { + 155 -> 0 + 196 -> 1 + 124 -> 2 + 199 -> 3 + 234 -> 4 + 9 -> 10 + else -> -1 + } + if (optionIndex == -1) { + log (this::class.java, Log.WARN, "${player.name} is clicking a right-click index that we don't know the opcode for yet, lol. Here's the opcode: $opcode") + return + } + + callback.invoke(slot, optionIndex) + + if (!getAttribute(player, "itemselect-keepalive", false)) { + removeAttribute (player, "itemselect-callback") + removeAttribute (player, "itemselect-keepalive") + player.interfaceManager.closeSingleTab() + } + } +} diff --git a/Server/src/main/content/global/handlers/iface/GliderInterface.java b/Server/src/main/content/global/handlers/iface/GliderInterface.java new file mode 100644 index 0000000..08459ce --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/GliderInterface.java @@ -0,0 +1,37 @@ +package content.global.handlers.iface; + +import static core.api.ContentAPIKt.*; +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import content.global.travel.glider.GliderPulse; +import content.global.travel.glider.Gliders; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the glider interface component. + * @author Emperor + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class GliderInterface extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.put(138, this); + return this; + } + + @Override + public boolean handle(final Player player, Component component, int opcode, int button, int slot, int itemId) { + final Gliders glider = Gliders.forId(button); + if (glider == null) { + return true; + } + submitWorldPulse(new GliderPulse(1, player, glider)); + return true; + } +} diff --git a/Server/src/main/content/global/handlers/iface/HairDresserInterface.kt b/Server/src/main/content/global/handlers/iface/HairDresserInterface.kt new file mode 100644 index 0000000..b1750ae --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/HairDresserInterface.kt @@ -0,0 +1,277 @@ +package content.global.handlers.iface + +import core.api.* +import core.game.component.Component +import core.game.component.ComponentDefinition +import core.game.component.ComponentPlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import core.plugin.Plugin + +/** + * Handles the reworked hairdresser interface with full functionality + * @author Ceikry + */ +private const val HAIRDRESSER_MALE_COMPONENT_ID = 596 +private const val HAIRDRESSER_FEMALE_COMPONENT_ID = 592 + +private val HAIR_COLORS = intArrayOf(20, 19, 10, 18, 4, 5, 15, 7, 0, 6, 21, 9, 22, 17, 8, 16, 11, 24, 23, 3, 2, 1, 14, 13, 12) +private val maleColorButtonRange = (229..253) +private val femaleColorButtonRange = (73..97) + +//Female Styles 45-54 +private const val F_BALD = 45 +private const val F_BUN = 46 +private const val F_DREAD = 47 +private const val F_LONG = 48 +private const val F_SHORT = 49 +private const val F_PIGTAILS = 50 +private const val F_CREW = 51 +private const val F_CLOSE_CROP = 52 +private const val F_WILD_SPIKE = 53 +private const val F_SPIKE = 54 +//Female Styles 135-146 +private const val F_SIDE_PONY = 135 +private const val F_CURLS = 136 +private const val F_WIND_BRAIDS = 137 +private const val F_PONYTAIL = 138 +private const val F_RING_BRAIDS = 139 +private const val F_FOUR_PONIES = 140 +private const val F_FLIP = 141 +private const val F_LAYERED_FLIP = 142 +private const val F_STRAIGHT = 143 +private const val F_LONG_BRAIDS = 144 +private const val F_CURTAINS = 145 +//Female Hair Styles 242 & 269-280 +private const val F_EARMUFFS = 242 +private const val F_FRINGE = 269 +private const val F_PINNED_UP = 270 +private const val F_LAYERED = 271 +private const val F_TOP_KNOT = 272 +private const val F_PINNED_BUN = 273 +private const val F_PONYTAIL_SPIKED = 274 +private const val F_PIXIE = 275 +private const val F_ODANGO = 276 +private const val F_BUN_WITH_FRINGE = 277 +private const val F_PIGTAILS_WITH_FRINGE = 278 +private const val F_FRENCH_TWIST = 279 +private const val F_PRINCESS = 280 + +//An array of female hairstyles in the same order as the interface +val FEMALE_HAIR_STYLES = intArrayOf(F_BALD, F_BUN, F_DREAD, F_LONG, F_SHORT, F_PIGTAILS, F_CREW, F_CLOSE_CROP, F_WILD_SPIKE, F_SPIKE, F_SIDE_PONY, F_CURLS, F_WIND_BRAIDS, F_PONYTAIL, F_RING_BRAIDS, F_FOUR_PONIES, F_FLIP, F_LAYERED_FLIP, F_STRAIGHT, F_LONG_BRAIDS, F_CURTAINS, F_EARMUFFS, F_FRINGE, F_PINNED_UP, F_LAYERED, F_TOP_KNOT, F_PINNED_BUN, F_PONYTAIL_SPIKED, F_PIXIE, F_ODANGO, F_BUN_WITH_FRINGE, F_PIGTAILS_WITH_FRINGE, F_FRENCH_TWIST, F_PRINCESS) + +//Male Styles +private const val M_BALD = 0 +private const val M_DREAD = 1 +private const val M_LONG = 2 +private const val M_MEDIUM = 3 +private const val M_MONK = 4 +private const val M_SHORT = 5 +private const val M_CLOSE_CROP = 6 +private const val M_WILD_SPIKE = 7 +private const val M_SPIKE = 8 +private const val M_MOHAWK = 91 +private const val M_WIND_BRAID = 92 +private const val M_QUIFF = 93 +private const val M_SAMURAI = 94 +private const val M_PRINCE = 95 +private const val M_CURTAINS = 96 +private const val M_LONG_CURTAINS = 97 +private const val M_SIDE_PART_SPIKE = 246 +private const val M_TOP_KNOT = 262 +private const val M_PONYTAIL_SPIKEY = 251 +private const val M_LONG_SWEPT_FRINGE = 265 +private const val M_EVANSTYLE = 252 +private const val M_DRAGON = 257 +private const val M_WARRIOR_CURTAINS = 247 +private const val M_COMB_OVER = 253 + + +//Array of male hairstyles in the same order as the interface +val MALE_HAIR_STYLES = intArrayOf(M_BALD, M_DREAD, M_LONG, M_MEDIUM, M_MONK, M_SHORT, M_CLOSE_CROP, M_WILD_SPIKE, M_SPIKE, M_MOHAWK, M_WIND_BRAID, M_QUIFF, M_SAMURAI, M_PRINCE, M_CURTAINS, M_LONG_CURTAINS, M_SIDE_PART_SPIKE, M_TOP_KNOT, M_PONYTAIL_SPIKEY, M_LONG_SWEPT_FRINGE, M_EVANSTYLE, M_DRAGON, M_WARRIOR_CURTAINS, M_COMB_OVER) + + +//Male Facial Hairs +private const val MF_GOATEE = 10 +private const val MF_LONG_BEARD = 11 +private const val MF_MEDIUM_BEARD = 12 +private const val MF_MOUSTACHE = 13 +private const val MF_CLEAN_SHAVEN = 14 +private const val MF_SHORT_BEARD = 15 +private const val MF_SHORT_FULL = 16 +private const val MF_SPLIT_BEARD = 17 +private const val MF_HANDLEBAR = 98 +private const val MF_MUTTON = 99 +private const val MF_FULL_MUTTON = 100 +private const val MF_FULL_MOUSTACHE = 101 +private const val MF_WAXED = 102 +private const val MF_DALI = 103 +private const val MF_VIZIER = 104 +private const val MF_HALF_GOATEE = 305 +private const val MF_SIDEBURNS = 306 +private const val MF_IMPERIAL = 307 +private const val MF_SENSEI = 308 + +//Array of male facial hairstyles in the same order as interface +val MALE_FACIAL_STYLES = intArrayOf(MF_GOATEE, MF_LONG_BEARD, MF_MEDIUM_BEARD, MF_MOUSTACHE, MF_CLEAN_SHAVEN, MF_SHORT_BEARD, MF_SHORT_FULL, MF_SPLIT_BEARD, MF_HANDLEBAR, MF_MUTTON, MF_FULL_MUTTON, MF_FULL_MOUSTACHE, MF_WAXED, MF_DALI, MF_VIZIER, MF_HALF_GOATEE, MF_SIDEBURNS, MF_IMPERIAL, MF_SENSEI) + +private val maleStyleButtonRange = (65..90) +private val femaleStyleButtonRange = (148..181) + +private val COINS = Item(995,2000) + +@Initializable +class HairDresserInterface : ComponentPlugin(){ + override fun open(player: Player?, component: Component?) { + player ?: return + super.open(player, component) + player.setAttribute("original-hair",player.appearance.hair.look) + player.setAttribute("original-beard",player.appearance.beard.look) + player.setAttribute("original-color",player.appearance.hair.color) + val usedInterface = if(player.isMale) HAIRDRESSER_MALE_COMPONENT_ID else HAIRDRESSER_FEMALE_COMPONENT_ID + //17 + val player_model_child = when(usedInterface){ + HAIRDRESSER_FEMALE_COMPONENT_ID -> 17 + HAIRDRESSER_MALE_COMPONENT_ID -> 62 + else -> 0 + } + val player_head_child = when(usedInterface){ + HAIRDRESSER_FEMALE_COMPONENT_ID -> 146 + HAIRDRESSER_MALE_COMPONENT_ID -> 61 + else -> 0 + } + sendPlayerOnInterface(player, usedInterface, player_model_child) + sendPlayerOnInterface(player, usedInterface, player_head_child) + sendAnimationOnInterface(player, FacialExpression.HAPPY.animationId, usedInterface, player_head_child) + player.toggleWardrobe(true) + + component?.setCloseEvent{pl,_ -> + player.toggleWardrobe(false) + player.setAttribute("beard-setting",false) + if(!pl.getAttribute("hairdresser-paid",false)){ + val original_hair = player.getAttribute("original-hair",0) + val original_beard = player.getAttribute("original_beard",-1) + val original_color = player.getAttribute("original_color",0) + pl.appearance.hair.changeLook(original_hair) + pl.appearance.hair.changeColor(original_color) + if(original_beard != -1) { + pl.appearance.beard.changeLook(original_beard) + } + pl.appearance.sync() + } + pl.removeAttribute("hairdresser-paid") + true + } + syncAppearance(player) + } + + override fun handle(player: Player?, component: Component?, opcode: Int, button: Int, slot: Int, itemId: Int): Boolean { + player ?: return false + val isBeard = player.getAttribute("beard-setting",false) + + when(button){ + 199 -> player.setAttribute("beard-setting",false) + 200 -> player.setAttribute("beard-setting",true) + 68,196,274 -> pay(player) + else -> when(component?.id){ + 592 -> { //Female + if(femaleColorButtonRange.contains(button)){ + updateColor(player,button) + } + if(femaleStyleButtonRange.contains(button)){ + updateHair(player,button) + } + } + 596 -> { //Male + //Handle beard options + if(isBeard && !maleColorButtonRange.contains(button)){ + updateBeard(player,button) + return true + } + if(maleColorButtonRange.contains(button)){ + updateColor(player,button) + return true + } + if(maleStyleButtonRange.contains(button)){ + updateHair(player,button) + } + } + } + } + return true + } + + override fun newInstance(arg: Any?): Plugin { + ComponentDefinition.put(HAIRDRESSER_MALE_COMPONENT_ID,this) + ComponentDefinition.put(HAIRDRESSER_FEMALE_COMPONENT_ID, this) + return this + } + + fun pay(player: Player){ + if(player.inventory.containsItem(COINS)){ + player.inventory.remove(COINS) + player.setAttribute("hairdresser-paid",true) + player.interfaceManager.close() + } else { + player.dialogueInterpreter.sendDialogue("You can not afford that.") + } + } + + fun updateBeard(player: Player, button: Int){ + var subtractor = 105 + when(button){ //why the fuck jagex (they skipped button ids for no reason) + 123 -> subtractor += 2 + 126 -> subtractor += 4 + 129 -> subtractor += 6 + } + player.appearance.beard.changeLook(MALE_FACIAL_STYLES[button - subtractor]) + syncAppearance(player) + } + + fun updateHair(player: Player, button: Int){ + val usedInterface = if(player.isMale) HAIRDRESSER_MALE_COMPONENT_ID else HAIRDRESSER_FEMALE_COMPONENT_ID + + //Since hair styles are arranged in an array above, we can get the style for a specific + //button by subtracting the id of the first style's button in an interface from the + //current button. + var subtractor = when(usedInterface){ + HAIRDRESSER_MALE_COMPONENT_ID -> 65 //first color male buttonId = 229 + HAIRDRESSER_FEMALE_COMPONENT_ID -> 148 //first color female buttonId = 73 + else -> 0 + } + + val hairArray = when(usedInterface){ + HAIRDRESSER_MALE_COMPONENT_ID -> MALE_HAIR_STYLES + HAIRDRESSER_FEMALE_COMPONENT_ID -> FEMALE_HAIR_STYLES + else -> intArrayOf(0) + } + + when(button){ //why the fuck jagex (they skipped button ids for no reason) + 89,90 -> subtractor += 2 + } + + player.appearance.hair.changeLook(hairArray[button - subtractor]) + syncAppearance(player) + } + + fun updateColor(player: Player, button: Int){ + val usedInterface = if(player.isMale) HAIRDRESSER_MALE_COMPONENT_ID else HAIRDRESSER_FEMALE_COMPONENT_ID + + //Since hair colors are arranged in an array above, we can get the color for a specific + //button by subtracting the id of the first color's button in an interface from the + //current button. + var subtractor = when(usedInterface){ + HAIRDRESSER_MALE_COMPONENT_ID -> 229 //first color male buttonId = 229 + HAIRDRESSER_FEMALE_COMPONENT_ID -> 73 //first color female buttonId = 73 + else -> 0 + } + player.appearance.hair.changeColor(HAIR_COLORS[button - subtractor]) + syncAppearance(player) + } + + fun syncAppearance(player: Player){ + player.appearance.sync() + } +} diff --git a/Server/src/main/content/global/handlers/iface/JewelleryInterface.java b/Server/src/main/content/global/handlers/iface/JewelleryInterface.java new file mode 100644 index 0000000..11eb234 --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/JewelleryInterface.java @@ -0,0 +1,198 @@ +package content.global.handlers.iface; + +import static core.api.ContentAPIKt.*; + +import content.global.skill.slayer.SlayerManager; +import core.cache.def.impl.ItemDefinition; +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.node.entity.skill.Skills; +import content.global.skill.crafting.jewellery.JewelleryCrafting; +import content.global.skill.crafting.jewellery.JewelleryCrafting.JewelleryItem; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Plugin; +import core.plugin.Initializable; +import core.tools.StringUtils; +import kotlin.Unit; + +/** + * Represents the interface plugin used for jewellery crafting. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class JewelleryInterface extends ComponentPlugin { + + /** + * Represents constants of useful items. + */ + public static final int RING_MOULD = 1592, AMULET_MOULD = 1595, NECKLACE_MOULD = 1597, BRACELET_MOULD = 11065, GOLD_BAR = 2357, SAPPHIRE = 1607, EMERALD = 1605, RUBY = 1603, DIAMOND = 1601, DRAGONSTONE = 1615, ONYX = 6573; + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.put(446, this); + return this; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + int amount = 0; + JewelleryItem data = null; + switch(button){ + case 20: + data = JewelleryItem.GOLD_RING; + break; + case 22: + data = JewelleryItem.SAPPIRE_RING; + break; + case 24: + data = JewelleryItem.EMERALD_RING; + break; + case 26: + data = JewelleryItem.RUBY_RING; + break; + case 28: + data = JewelleryItem.DIAMOND_RING; + break; + case 30: + data = JewelleryItem.DRAGONSTONE_RING; + break; + case 32: + data = JewelleryItem.ONYX_RING; + break; + case 35: + data = JewelleryItem.SLAYER_RING; + break; + } + switch (button - 3) { + case 39: + data = JewelleryItem.GOLD_NECKLACE; + break; + case 41: + data = JewelleryItem.SAPPHIRE_NECKLACE; + break; + case 43: + data = JewelleryItem.EMERALD_NECKLACE; + break; + case 45: + data = JewelleryItem.RUBY_NECKLACE; + break; + case 47: + data = JewelleryItem.DIAMOND_NECKLACE; + break; + case 49: + data = JewelleryItem.DRAGONSTONE_NECKLACE; + break; + case 51: + data = JewelleryItem.ONYX_NECKLACE; + break; + case 58: + data = JewelleryItem.GOLD_AMULET; + break; + case 60: + data = JewelleryItem.SAPPHIRE_AMULET; + break; + case 62: + data = JewelleryItem.EMERALD_AMULET; + break; + case 64: + data = JewelleryItem.RUBY_AMULET; + break; + case 66: + data = JewelleryItem.DIAMOND_AMULET; + break; + case 68: + data = JewelleryItem.DRAGONSTONE_AMULET; + break; + case 70: + data = JewelleryItem.ONYX_AMULET; + break; + case 77: + data = JewelleryItem.GOLD_BRACELET; + break; + case 79: + data = JewelleryItem.SAPPHIRE_BRACELET; + break; + case 81: + data = JewelleryItem.EMERALD_BRACELET; + break; + case 83: + data = JewelleryItem.RUBY_BRACELET; + break; + case 85: + data = JewelleryItem.DIAMOND_BRACELET; + break; + case 87: + data = JewelleryItem.DRAGONSTONE_BRACELET; + break; + case 89: + data = JewelleryItem.ONYX_BRACELET; + break; + } + if (data == null) { + return true; + } + if (player.getSkills().getLevel(Skills.CRAFTING) < data.getLevel()) { + String an = StringUtils.isPlusN(ItemDefinition.forId(data.getSendItem()).getName().toLowerCase()) ? "an" : "a"; + player.getPacketDispatch().sendMessage("You need a crafting level of " + data.getLevel() + " to craft " + an + " " + ItemDefinition.forId(data.getSendItem()).getName().toLowerCase() + "."); + return true; + } + String name = ItemDefinition.forId(data.getSendItem()).getName().toLowerCase(); + boolean flag = false; + if (name.contains("ring") && !player.getInventory().contains(RING_MOULD, 1)) { + flag = true; + } + if (name.contains("necklace") && !player.getInventory().contains(NECKLACE_MOULD, 1)) { + flag = true; + } + if (name.contains("amulet") && !player.getInventory().contains(AMULET_MOULD, 1)) { + flag = true; + } + if (name.contains("bracelet") && !player.getInventory().contains(BRACELET_MOULD, 1)) { + flag = true; + } + if (flag) { + player.getPacketDispatch().sendMessage("You don't have the required mould to make this."); + return flag; + } + switch (opcode) { + case 155: + amount = 1; + break; + case 196: + amount = 5; + break; + case 124: + if (data.name().contains("GOLD")) { + amount = player.getInventory().getAmount(new Item(GOLD_BAR)); + } else { + int first = player.getInventory().getAmount(new Item(data.getItems()[0])); + int second = player.getInventory().getAmount(new Item(data.getItems()[1])); + if (first == second) { + amount = first; + } else if (first > second) { + amount = second; + } else { + amount = first; + } + } + break; + case 199: + final JewelleryItem d = data; + sendInputDialogue(player, true, "Enter the amount:", (value) -> { + JewelleryCrafting.make(player, d, (int) value); + return Unit.INSTANCE; + }); + return true; + } + if(!SlayerManager.getInstance(player).flags.isRingUnlocked() && data.equals(JewelleryItem.SLAYER_RING)){ + player.sendMessages("You don't know how to make this. Talk to any Slayer master in order to learn the", "ability that creates Slayer rings."); + return true; + } + JewelleryCrafting.make(player, data, amount); + return true; + } + +} diff --git a/Server/src/main/content/global/handlers/iface/LeatherCraftInterface.java b/Server/src/main/content/global/handlers/iface/LeatherCraftInterface.java new file mode 100644 index 0000000..e4b700a --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/LeatherCraftInterface.java @@ -0,0 +1,56 @@ +package content.global.handlers.iface; + +import static core.api.ContentAPIKt.*; +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import content.global.skill.crafting.armour.LeatherCrafting; +import content.global.skill.crafting.armour.SoftCraftPulse; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.Plugin; +import kotlin.Unit; + +/** + * Represents the leather crafting interface. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class LeatherCraftInterface extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.put(154, this); + return this; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + int amount = 0; + final LeatherCrafting.SoftLeather soft = LeatherCrafting.SoftLeather.forButton(button); + if (soft == null) { + return true; + } + switch (opcode) { + case 155: + amount = 1; + break; + case 196: + amount = 5; + break; + case 124: + amount = player.getInventory().getAmount(new Item(LeatherCrafting.LEATHER)); + break; + case 199: + sendInputDialogue(player, true, "Enter the amount:", (value) -> { + submitIndividualPulse(player, new SoftCraftPulse(player, new Item(LeatherCrafting.LEATHER), soft, (int) value)); + return Unit.INSTANCE; + }); + return true; + } + player.getPulseManager().run(new SoftCraftPulse(player, null, soft, amount)); + return true; + } +} diff --git a/Server/src/main/content/global/handlers/iface/LeatherCraftPlugin.java b/Server/src/main/content/global/handlers/iface/LeatherCraftPlugin.java new file mode 100644 index 0000000..e0b2978 --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/LeatherCraftPlugin.java @@ -0,0 +1,42 @@ +package content.global.handlers.iface; + +import core.plugin.Initializable; +import content.global.skill.crafting.armour.LeatherCrafting; +import content.global.skill.crafting.armour.LeatherCrafting.SoftLeather; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.plugin.Plugin; + +/** + * Represents the plugin used for crafting leather. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class LeatherCraftPlugin extends UseWithHandler { + + /** + * Constructs a new {@code LeatherCraftPlugin} {@code Object}. + */ + public LeatherCraftPlugin() { + super(LeatherCrafting.LEATHER, LeatherCrafting.HARD_LEATHER, LeatherCrafting.GREEN_LEATHER, LeatherCrafting.BLUE_LEATHER, LeatherCrafting.RED_LEATHER, LeatherCrafting.BLACK_LEATHER); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(LeatherCrafting.NEEDLE, ITEM_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + if (event.getBaseItem().getId() == LeatherCrafting.LEATHER || event.getUsedItem().getId() == LeatherCrafting.LEATHER) { + SoftLeather.open(event.getPlayer()); + } else if (event.getBaseItem().getId() == LeatherCrafting.HARD_LEATHER || event.getUsedItem().getId() == LeatherCrafting.HARD_LEATHER) { + event.getPlayer().getDialogueInterpreter().open(48923, "hard"); + } else { + event.getPlayer().getDialogueInterpreter().open(48923, "dragon", event.getUsedItem().getId()); + } + return true; + } +} diff --git a/Server/src/main/content/global/handlers/iface/LoginInterfacePlugin.java b/Server/src/main/content/global/handlers/iface/LoginInterfacePlugin.java new file mode 100644 index 0000000..f91a300 --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/LoginInterfacePlugin.java @@ -0,0 +1,51 @@ +package content.global.handlers.iface; + +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.info.login.LoginConfiguration; +import core.game.system.task.Pulse; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the plugin used for the login interface. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class LoginInterfacePlugin extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.put(378, this); + return null; + } + + @Override + public boolean handle(final Player player, Component component, int opcode, int button, int slot, int itemId) { + switch (button) { + case 140: + if (player.getLocks().isLocked("login")) { + return true; + } + player.getLocks().lock("login", 2); + player.getInterfaceManager().close(); + player.getPulseManager().run(new Pulse(1) { + @Override + public boolean pulse() { + LoginConfiguration.configureGameWorld(player); + return true; + } + }); + break; + case 145://credits + break; + case 204://message centre + break; + } + return true; + } + +} diff --git a/Server/src/main/content/global/handlers/iface/LogoutInterface.java b/Server/src/main/content/global/handlers/iface/LogoutInterface.java new file mode 100644 index 0000000..d3a7c9c --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/LogoutInterface.java @@ -0,0 +1,42 @@ +package content.global.handlers.iface; + +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.node.entity.player.Player; +import core.game.world.GameWorld; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.game.world.repository.Repository; + +/** + * Represents the interface used to logout of the game. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class LogoutInterface extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.put(182, this); + return this; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + if (!player.getZoneMonitor().canLogout()) { + return true; + } + if (player.inCombat()) { + player.getPacketDispatch().sendMessage("You can't log out until 10 seconds after the end of combat."); + return true; + } + if (player.isTeleporting()) { + player.sendMessage("Please finish your teleport before logging out."); + return true; + } + Repository.getDisconnectionQueue().add(player); + return true; + } +} diff --git a/Server/src/main/content/global/handlers/iface/MagicBookInterface.java b/Server/src/main/content/global/handlers/iface/MagicBookInterface.java new file mode 100644 index 0000000..af5c87b --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/MagicBookInterface.java @@ -0,0 +1,50 @@ +package content.global.handlers.iface; + +import content.global.skill.magic.SpellListener; +import content.global.skill.magic.SpellListeners; +import content.global.skill.magic.SpellUtils; +import core.game.event.SpellCastEvent; +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.plugin.Initializable; +import core.game.node.entity.combat.spell.MagicSpell; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.world.GameWorld; +import core.plugin.Plugin; + +/** + * Represents the magic book interface handling of non-combat spells. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class MagicBookInterface extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.put(192, this); + ComponentDefinition.put(193, this); + ComponentDefinition.put(430, this); + return this; + } + + @Override + public boolean handle(final Player player, Component component, int opcode, int button, int slot, int itemId) { + if (GameWorld.getTicks() < player.getAttribute("magic:delay", -1)) { + return true; + } + + SpellBook spellBook = component.getId() == 192 + ? SpellBook.MODERN + : component.getId() == 193 + ? SpellBook.ANCIENT + : SpellBook.LUNAR; + + SpellListeners.run(button, SpellListener.NONE, SpellUtils.getBookFromInterface(component.getId()),player,null); + boolean result = MagicSpell.castSpell(player, spellBook, button, player); + + return result; + } +} diff --git a/Server/src/main/content/global/handlers/iface/MainGameInterface.kt b/Server/src/main/content/global/handlers/iface/MainGameInterface.kt new file mode 100644 index 0000000..243337f --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/MainGameInterface.kt @@ -0,0 +1,111 @@ +package content.global.handlers.iface + +import core.api.* +import core.game.component.CloseEvent +import core.game.component.Component +import core.game.node.entity.combat.equipment.WeaponInterface +import core.game.node.entity.combat.equipment.WeaponInterface.WeaponInterfaces +import core.game.node.entity.player.Player +import core.game.node.entity.player.info.Rights +import org.rs09.consts.Components +import core.game.interaction.InterfaceListener +import core.game.world.GameWorld.settings + +class MainGameInterface : InterfaceListener { + val TOPLEVEL = Components.TOPLEVEL_548 + val TOPLEVEL_FS = Components.TOPLEVEL_FULLSCREEN_746 + val RUN_BUTTON = Components.TOPSTAT_RUN_750 + val FILTER_BUTTONS = Components.FILTERBUTTONS_751 + val REPORT_ABUSE = Components.SNAPSHOT_MAIN_553 + + override fun defineInterfaceListeners() { + on(FILTER_BUTTONS){player, _, _, buttonID, _, _ -> + if(buttonID == 27) + openReport(player) + return@on true + } + + on(RUN_BUTTON){player, _, _, _, _, _ -> + player.settings.toggleRun() + return@on true + } + + on(TOPLEVEL_FS){player, _, _, buttonID, _, _ -> + when (buttonID) { + 12 -> setInterfaceText(player, + "When you have finished playing " + settings!!.name + ", always use the button below to logout safely. ", + 182, + 0 + ) + 49 -> setInterfaceText(player, + "Friends List - " + settings!!.name + " " + settings!!.worldId, + 550, + 3 + ) + 110 -> configureWorldMap(player) + } + return@on true + } + + + on(TOPLEVEL){player, _, _, buttonID, _, _ -> + when (buttonID) { + 21 -> { + player.packetDispatch.sendString( + "Friends List -" + settings!!.name + " " + settings!!.worldId, + 550, + 3 + ) + } + 38 -> { + if (player.getExtension(WeaponInterface::class.java) === WeaponInterfaces.STAFF) { + val c = Component(WeaponInterfaces.STAFF.interfaceId) + player.interfaceManager.openTab(0, c) + val inter = player.getExtension(WeaponInterface::class.java) + inter.updateInterface() + } + } + 40 -> player.questRepository.syncronizeTab(player) + 41 -> player.inventory.refresh() + 66, 110 -> configureWorldMap(player) + 69 -> player.packetDispatch.sendString( + "When you have finished playing " + settings!!.name + ", always use the button below to logout safely. ", + 182, + 0 + ) + } + return@on true + } + } + + fun openReport(player: Player) { + player.interfaceManager.open(Component(REPORT_ABUSE)).closeEvent = + CloseEvent { player1: Player, c: Component? -> + player1.packetDispatch.sendRunScript(80, "") + player1.packetDispatch.sendRunScript(137, "") + true + } + player.packetDispatch.sendRunScript(508, "") + if (player.details.rights !== Rights.REGULAR_PLAYER) { + for (i in 0..17) { + player.packetDispatch.sendInterfaceConfig(553, i, false) + } + } + } + + private fun configureWorldMap(player: Player) { + if (player.inCombat()) { + player.packetDispatch.sendMessage("It wouldn't be very wise opening the world map during combat.") + return + } + if (player.locks.isInteractionLocked || player.locks.isMovementLocked) { + player.packetDispatch.sendMessage("You can't do this right now.") + return + } + player.interfaceManager.close() + player.interfaceManager.openWindowsPane(Component(755)) + val posHash = player.location.z shl 28 or (player.location.x shl 14) or player.location.y + player.packetDispatch.sendScriptConfigs(622, posHash, "", 0) + player.packetDispatch.sendScriptConfigs(674, posHash, "", 0) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/iface/MakeOverInterface.kt b/Server/src/main/content/global/handlers/iface/MakeOverInterface.kt new file mode 100644 index 0000000..58aaea1 --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/MakeOverInterface.kt @@ -0,0 +1,126 @@ +package content.global.handlers.iface + +import core.game.component.Component +import core.game.component.ComponentDefinition +import core.game.component.ComponentPlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.appearance.Gender +import core.game.node.item.Item +import core.plugin.Initializable +import core.plugin.Plugin +import org.rs09.consts.Items + +//child IDs for components of interest on the interface +private const val MALE_CHILD_ID = 90 +private const val FEMALE_CHILD_ID = 92 +private const val TEXT_CHILD = 88 + +//skin color buttons +private val skincolorButtons = (93..100) + +/** + * Fully authentic and functional makeover interface + * @author Ceikry + */ +@Initializable +class MakeOverInterface : ComponentPlugin(){ + override fun open(player: Player?, component: Component?) { + component ?: return + player ?: return + super.open(player, component) + //Send NPC chat heads to interface + player.packetDispatch.sendNpcOnInterface(1,component.id, MALE_CHILD_ID) + player.packetDispatch.sendNpcOnInterface(5,component.id, FEMALE_CHILD_ID) + //Send chathead animations to interface + player.packetDispatch.sendAnimationInterface(FacialExpression.SILENT.animationId,component.id, MALE_CHILD_ID) + player.packetDispatch.sendAnimationInterface(FacialExpression.SILENT.animationId,component.id, FEMALE_CHILD_ID) + + //Check for makeover voucher and then change interface text if it's there + if(player.inventory.containsAtLeastOneItem(Items.MAKEOVER_VOUCHER_5606)){ + player.packetDispatch.sendString("USE MAKEOVER VOUCHER",component.id, TEXT_CHILD) + } + + //Automatically hide the button representing the player's current skin color + val currentSkin = player.appearance.skin.color + player.setAttribute("mm-previous",currentSkin) + player.packetDispatch.sendInterfaceConfig(component.id, skincolorButtons.first + currentSkin, true) + + player.toggleWardrobe(true) + + component.setCloseEvent{pl,_ -> + pl.toggleWardrobe(false) + if(player.getAttribute("mm-paid",false)){ + val newColor = player.getAttribute("mm-previous",-1) + val newGender = player.getAttribute("mm-gender",-1) + if(newColor > -1){ + player.appearance.skin.changeColor(newColor) + } + if(newGender > -1){ + player.appearance.changeGender(Gender.values()[newGender]) + player.appearance.skin.changeColor(newColor) + } + player.appearance.sync() + player.removeAttribute("mm-paid") + } + pl.removeAttribute("mm-previous") + pl.removeAttribute("mm-gender") + true + } + } + + override fun handle(player: Player?, component: Component?, opcode: Int, button: Int, slot: Int, itemId: Int): Boolean { + player ?: return false + if(skincolorButtons.contains(button)){ + updateInterfaceConfigs(player,button) + return true + } + when(button){ + 113,101 -> updateGender(player,true) + 114,103 -> updateGender(player,false) + 88 -> pay(player) + } + + return true + } + + fun updateGender(player: Player, male: Boolean){ + player.setAttribute("mm-gender",if(male) Gender.MALE.ordinal else Gender.FEMALE.ordinal) + } + + fun pay(player: Player){ + val newColor = player.getAttribute("mm-previous",player.appearance.skin.color) + val newGender = player.getAttribute("mm-gender",player.appearance.gender.ordinal) + + //Don't charge if they didn't change anything + if(newColor == player.appearance.skin.color && Gender.values()[newGender] == player.appearance.gender){ + player.interfaceManager.close() + } else { + val currency = if(player.inventory.containsAtLeastOneItem(Items.MAKEOVER_VOUCHER_5606)){ + Item(Items.MAKEOVER_VOUCHER_5606,1) + } else Item(995,3000) + + if(player.inventory.containsItem(currency)){ + player.setAttribute("mm-paid",true) + player.inventory.remove(currency) + player.interfaceManager.close() + } else { + player.dialogueInterpreter.sendDialogue("You can not afford that.") + } + } + } + + fun updateInterfaceConfigs(player: Player,button: Int){ + val old = player.getAttribute("mm-previous",0) + player.setAttribute("mm-previous",button - skincolorButtons.first) + player.packetDispatch.sendInterfaceConfig(205,old + skincolorButtons.first,false) + player.packetDispatch.sendInterfaceConfig(205,button,true) + + } + + override fun newInstance(arg: Any?): Plugin { + ComponentDefinition.put(205,this) + return this + } + +} diff --git a/Server/src/main/content/global/handlers/iface/MusicTabInterface.java b/Server/src/main/content/global/handlers/iface/MusicTabInterface.java new file mode 100644 index 0000000..579607f --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/MusicTabInterface.java @@ -0,0 +1,57 @@ +package content.global.handlers.iface; + +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.info.Rights; +import core.game.node.entity.player.link.music.MusicEntry; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Handles the interface tab buttons. + * @author Emperor + */ +@Initializable +public final class MusicTabInterface extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.put(187, this); + return this; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + switch (opcode) { + case 155: + switch (button) { + case 11: + player.getMusicPlayer().toggleLooping(); + return true; + case 1: + MusicEntry entry = player.getMusicPlayer().getUnlocked().get(slot); + if (entry == null) { + if(player.getRights().equals(Rights.ADMINISTRATOR)){ + for(MusicEntry ent : MusicEntry.getSongs().values()){ + if(ent.getIndex() == slot){ + player.getMusicPlayer().unlock(ent.getId()); + break; + } + } + } else { + player.getPacketDispatch().sendMessage("You have not unlocked this piece of music yet!"); + } + return true; + } + player.getMusicPlayer().setPlaying(false); + player.getMusicPlayer().play(entry); + return true; + } + break; + } + return false; + } + +} diff --git a/Server/src/main/content/global/handlers/iface/MysticStaffEnchantingPlugin.java b/Server/src/main/content/global/handlers/iface/MysticStaffEnchantingPlugin.java new file mode 100644 index 0000000..c8d7521 --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/MysticStaffEnchantingPlugin.java @@ -0,0 +1,95 @@ +package content.global.handlers.iface; + +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import org.rs09.consts.Items; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Plugin; +import core.plugin.Initializable; +import core.tools.StringUtils; + +import java.util.HashMap; + +/** + * Represents the plugin used to handle the agility ticket interface. + * @author afaroutdude + */ +@Initializable +public final class MysticStaffEnchantingPlugin extends ComponentPlugin { + + private final Component COMPONENT = new Component(332); + + protected enum EnchantedStaff { + AIR(Items.MYSTIC_AIR_STAFF_1405, Items.AIR_BATTLESTAFF_1397, 21), + WATER(Items.MYSTIC_WATER_STAFF_1403, Items.WATER_BATTLESTAFF_1395, 22), + EARTH(Items.MYSTIC_EARTH_STAFF_1407, Items.EARTH_BATTLESTAFF_1399, 23), + FIRE(Items.MYSTIC_FIRE_STAFF_1401, Items.FIRE_BATTLESTAFF_1393, 24), + LAVA(Items.MYSTIC_LAVA_STAFF_3054, Items.LAVA_BATTLESTAFF_3053, 25), + MUD(Items.MYSTIC_MUD_STAFF_6563, Items.MUD_BATTLESTAFF_6562, 26), + STEAM(Items.MYSTIC_STEAM_STAFF_11738, Items.STEAM_BATTLESTAFF_11736, 27); + + public final int enchanted; + public final int basic; + public final int child; + + private static final HashMap basicToEnchanted = new HashMap<>(); + private static final HashMap childToBasic = new HashMap<>(); + + static { + for (EnchantedStaff staff : EnchantedStaff.values()) { + basicToEnchanted.put(staff.basic, staff.enchanted); + childToBasic.put(staff.child, staff.basic); + } + } + + EnchantedStaff(int enchantedId, int basicId, int childId) { + this.enchanted = enchantedId; + this.basic = basicId; + this.child = childId; + } + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.forId(332).setPlugin(this); + return this; + } + + @Override + public void open(Player player, Component component) { + super.open(player, component); + // zoom doesn't work, but based on https://youtu.be/qxxhhCdxBsQ?t=75 seems correct anyway + for (EnchantedStaff staff : EnchantedStaff.values()) { + player.getPacketDispatch().sendItemZoomOnInterface(staff.basic, 240, COMPONENT.getId(), staff.child); + } + } + + @Override + public boolean handle(Player player, Component component, int opcode, int buttonId, int slot, int itemId) { + + if (EnchantedStaff.childToBasic.containsKey(buttonId)) { + Item basicStaff = new Item(EnchantedStaff.childToBasic.get(buttonId)); + Item enchantedStaff = new Item(EnchantedStaff.basicToEnchanted.get(basicStaff.getId())); + + if (!player.getInventory().containsItem(basicStaff)) { + player.getPacketDispatch().sendMessage("You don't have a" + (StringUtils.isPlusN(basicStaff.getName()) ? "n " : " ") + basicStaff.getName() + " to enchant."); + return true; + } + int cost = player.getEquipment().contains(Items.SEERS_HEADBAND_14631, 1)? 27000 : 40000; + if (!player.getInventory().contains(995, cost)) { + player.getInterfaceManager().close(); + player.getDialogueInterpreter().sendDialogues(389, null, "I need " + String.format("%,d", cost) + " coins for materials. Come", "back when you have the money!"); + return true; + } + if (player.getInventory().remove(basicStaff, new Item(995, cost))) { + player.getInterfaceManager().close(); + player.getDialogueInterpreter().sendDialogues(389, null, "Just a moment... hang on... hocus pocus abra-", "cadabra... there you go! Enjoy your enchanted staff!"); + player.getInventory().add(enchantedStaff); + } + } + + return true; + } +} diff --git a/Server/src/main/content/global/handlers/iface/NPCContactInterface.kt b/Server/src/main/content/global/handlers/iface/NPCContactInterface.kt new file mode 100644 index 0000000..ebe4a6d --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/NPCContactInterface.kt @@ -0,0 +1,91 @@ +package content.global.handlers.iface + +import core.game.node.entity.npc.NPC +import core.game.world.map.Location +import core.tools.RandomFunction +import org.rs09.consts.NPCs +import core.game.dialogue.DialogueFile +import core.game.interaction.InterfaceListener + +class NPCContactInterface : InterfaceListener { + val contactNPCs = arrayOf(NPCs.HONEST_JIMMY_4362, NPCs.BERT_3108, NPCs.ADVISOR_GHRIM_1375, NPCs.TURAEL_8273, NPCs.LANTHUS_1526, NPCs.SUMONA_7780, NPCs.MAZCHNA_8274, NPCs.DURADEL_8275, NPCs.VANNAKA_1597, NPCs.DARK_MAGE_2262, NPCs.CHAELDAR_1598, NPCs.CYRISUS_432, NPCs.LARRY_5424) + val DialogueFiles = arrayOf( + /*TODO("Honest Jimmy"), + TODO("Bert"), + TODO("ADVISOR GHRIM"), + TODO("Turael"), + TODO("LANTHUS"), + TODO("Sumona"), + TODO("Mazchna"), + TODO("Duradel"), + TODO("Vannaka"), + TODO("Murphy"), + TODO("Chaeldar"), + TODO("Cyrisus"), + TODO("Larry")*/ + ) + val INTER = 429 + override fun defineInterfaceListeners() { + + //Remove a bunch of the buttons/heads so that people don't + //waste runes on spells that aren't implemented + //TODO: Re-enable NPCs as their respective content gets added + onOpen(INTER){player, component -> + //Honest Jimmy: Trouble Brewing + player.packetDispatch.sendInterfaceConfig(429,10,true) + player.packetDispatch.sendInterfaceConfig(429,38,true) + + //Bert the Sandman: Hand in the Sand quest + player.packetDispatch.sendInterfaceConfig(429,11,true) + player.packetDispatch.sendInterfaceConfig(429,39,true) + + //Advisor Ghrim: Kingdoms of Miscellania + player.packetDispatch.sendInterfaceConfig(429,12,true) + player.packetDispatch.sendInterfaceConfig(429,40,true) + + //Lanthus: Castle Wars + player.packetDispatch.sendInterfaceConfig(429,17,true) + player.packetDispatch.sendInterfaceConfig(429,43,true) + + //Sumona: Completion of Smoking Kills + player.packetDispatch.sendInterfaceConfig(429,27,true) + player.packetDispatch.sendInterfaceConfig(429,42,true) + + // Replace Murphy's icon with the Abyss's Dark Mage + player.packetDispatch.sendNpcOnInterface(NPCs.DARK_MAGE_2262, 429, 30) + player.packetDispatch.sendString("Dark mage", 429, 47) + + return@onOpen true + } + + on(INTER){player, _, _, buttonID, _, _ -> + var index = when(buttonID){ + 10,38 -> 0 + 11,39 -> 1 + 12,40 -> 2 + 13,41 -> 3 + 17,43 -> 4 + 27,42 -> 5 + 18,44 -> 6 + 23,45 -> 7 + 28,46 -> 8 + 30,47 -> 9 + 29,48 -> 10 + 32,33 -> 11 + 34,49 -> 12 + else -> -1 + } + if(index == -1) index = RandomFunction.random(contactNPCs.size) + val dialogueFile = DialogueFiles.getOrNull(index) + player.getAttribute<() -> Unit>("contact-caller")?.invoke() + player.interfaceManager.close() + if(dialogueFile != null){ + player.dialogueInterpreter.open(dialogueFile, NPC(contactNPCs[index])) + } else { + player.dialogueInterpreter.open(contactNPCs[index], NPC(contactNPCs[index], Location(0, 0))) + } + return@on true + } + + } +} diff --git a/Server/src/main/content/global/handlers/iface/PrayerTabInterface.java b/Server/src/main/content/global/handlers/iface/PrayerTabInterface.java new file mode 100644 index 0000000..2c31b11 --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/PrayerTabInterface.java @@ -0,0 +1,39 @@ +package content.global.handlers.iface; + +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.prayer.PrayerType; +import core.plugin.Initializable; +import core.plugin.Plugin; + +import static core.api.ContentAPIKt.hasRequirement; +import content.data.Quests; + +/** + * Represents the prayer interface. + * @author 'Vexia + */ +@Initializable +public final class PrayerTabInterface extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.put(271, this); + return this; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + final PrayerType type = PrayerType.get(button); + if (type == PrayerType.CHIVALRY || type == PrayerType.PIETY) + if (!hasRequirement(player, Quests.KINGS_RANSOM)) + return true; + if (type == null) { + return true; + } + player.getPrayer().toggle(type); + return true; + } +} diff --git a/Server/src/main/content/global/handlers/iface/PuppyInterfacePlugin.kt b/Server/src/main/content/global/handlers/iface/PuppyInterfacePlugin.kt new file mode 100644 index 0000000..3df8d0c --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/PuppyInterfacePlugin.kt @@ -0,0 +1,54 @@ +package content.global.handlers.iface + +import core.game.component.Component +import core.game.component.ComponentDefinition +import core.game.component.ComponentPlugin +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import core.plugin.Plugin +import core.tools.RandomFunction + +/** + * Represents the puppy interface plugin. + * @author Ceikry + */ +@Initializable +class PuppyInterfacePlugin : ComponentPlugin() { + override fun newInstance(arg: Any?): Plugin? { + ComponentDefinition.put(668, this) + return this + } + + override fun handle(player: Player, component: Component, opcode: Int, button: Int, slot: Int, itemId: Int): Boolean { + val index = when(button){ + 8 -> 0 + 3 -> 1 + 4 -> 2 + 5 -> 3 + 6 -> 4 + 7 -> 5 + else -> 0 + } + player.dialogueInterpreter.open(6893, NAMES[index], PUPPIES[index][RandomFunction.random(PUPPIES[index].size)]) + return true + } + + companion object { + /** + * Represents the names of the puppys. + */ + private val NAMES = arrayOf("labrador", "bulldog", "dalmatian", "greyhound", "terrier", "sheepdog") + + /** + * Represents the puppies. + */ + private val PUPPIES = arrayOf( + arrayOf(Item(12516), Item(12708), Item(12710)), //Labrador + arrayOf(Item(12522), Item(12720), Item(12722)), //Bulldog + arrayOf(Item(12518), Item(12712), Item(12714)), //Dalmatian + arrayOf(Item(12514), Item(12704), Item(12706)), //Greyhound + arrayOf(Item(12512), Item(12700), Item(12702)), //Terrier + arrayOf(Item(12520), Item(12716), Item(12718))) //Sheepdog + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/iface/QuestTabInterface.java b/Server/src/main/content/global/handlers/iface/QuestTabInterface.java new file mode 100644 index 0000000..90d580a --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/QuestTabInterface.java @@ -0,0 +1,71 @@ +package content.global.handlers.iface; + +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.AchievementDiary; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.entity.player.link.quest.Quest; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Handles the quest tab reward buttons. + * @author Emperor + * @author Vexia + */ +@Initializable +public class QuestTabInterface extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.put(274, this); // Quests + ComponentDefinition.put(259, this); // Achievement diary + return this; + } + + @Override + public boolean handle(Player p, Component component, int opcode, int button, int slot, int itemId) { + p.getPulseManager().clear(); + switch (component.getId()) { + case 274: +// if (!GameWorld.isEconomyWorld()) { +// p.getSavedData().getSpawnData().handleButton(p, button); +// } + switch (button) { + case 3: + p.getAchievementDiaryManager().openTab(); + return true; + case 10: + break; + default: +// if (GameWorld.isEconomyWorld()) { + + Quest quest = p.getQuestRepository().forButtonId(button); + if (quest != null) { + p.getInterfaceManager().open(new Component(275)); + quest.drawJournal(p, quest.getStage(p)); + return true; + } else QuestTabUtils.showRequirementsInterface(p, button); +// } + return false; + } + break; + case 259: + switch (button) { + case 8: + p.getInterfaceManager().openTab(2, new Component(274)); + return true; + default: + AchievementDiary diary = p.getAchievementDiaryManager().getDiary(DiaryType.forChild(button)); + if (diary != null) { + diary.open(p); + } + return true; + } + } + return true; + } + +} diff --git a/Server/src/main/content/global/handlers/iface/QuestTabUtils.kt b/Server/src/main/content/global/handlers/iface/QuestTabUtils.kt new file mode 100644 index 0000000..3af1844 --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/QuestTabUtils.kt @@ -0,0 +1,245 @@ +package content.global.handlers.iface + +import core.game.requirement.* +import core.api.* +import core.tools.* +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills + +import kotlin.math.* +import java.util.* + +import org.rs09.consts.* +import content.data.Quests + +object QuestTabUtils { + @JvmStatic + fun showRequirementsInterface(player: Player, button: Int) { + val questName = getNameForButton(button) + val questReq = QuestRequirements.values().filter { it.quest.questName == questName }.firstOrNull() ?: return + var (isMet, unmetReqs) = QuestReq(questReq).evaluate(player) + + var messageList = ArrayList() + + val statMap = HashMap() + val questList = HashSet() + var maxQpReq = 0 + var qpPenalty = 0 + closeInterface(player) + for (req in unmetReqs) { + if (req is QuestReq) + questList.add(req.questReq.quest.questName) + else if (req is SkillReq) { + if (statMap[req.skillId] == null || (statMap[req.skillId] != null && statMap[req.skillId]!! < req.level)) + statMap[req.skillId] = req.level + } + else if (req is QPReq && req.amount > maxQpReq) + maxQpReq = req.amount + else if (req is QPCumulative) + qpPenalty += req.amount + } + + messageList.add(colorize("%B[Quests Needed]")) + messageList.addAll(questList.map { "Completion of $it" }) + + messageList.add(" ") + messageList.add(colorize("%B[Skills Needed]")) + + for ((skillId, level) in statMap) { + val name = Skills.SKILL_NAME[skillId] + messageList.add("$level $name") + } + + messageList.add(" ") + messageList.add(colorize("%B[Other Reqs]")) + + val totalQpRequirement = QPReq(min(max(maxQpReq, qpPenalty), player.questRepository.getAvailablePoints())) + val (meetsQp, _) = totalQpRequirement.evaluate(player) + isMet = isMet && meetsQp + + if (isMet) + messageList.add(colorize("%GCongratulations! You've earned this one.")) + + if (!meetsQp) messageList.add("A total of ${totalQpRequirement.amount} Quest Points.") + + messageList.add("") + messageList.add(colorize("%BDISCLAIMER: If you're seeing this screen, this quest is not")) + messageList.add(colorize("%Bimplemented yet. These are the requirements that you need in order")) + messageList.add(colorize("%Bto access implemented content that would normally require this quest")) + messageList.add("") + messageList.add("If you want to see more quests enter the game, consider") + messageList.add("contributing dialogue transcripts!") + + + setInterfaceText(player, questName, Components.QUESTJOURNAL_SCROLL_275, 2) + var lineId = 11 + for(i in 0..299) { + val entry = messageList.elementAtOrNull(i) + if (entry != null) + setInterfaceText(player, entry, Components.QUESTJOURNAL_SCROLL_275, lineId++) + else + setInterfaceText(player, "", Components.QUESTJOURNAL_SCROLL_275, lineId++) + } + openInterface(player, Components.QUESTJOURNAL_SCROLL_275) + } + + private fun getNameForButton(button: Int) : String { + val quest = when (button) { + 10 -> Quests.MYTHS_OF_THE_WHITE_LANDS.questName + 11 -> Quests.MYTHS_OF_THE_WHITE_LANDS.questName + 12 -> "Free Quests" + 13 -> Quests.BLACK_KNIGHTS_FORTRESS.questName + 14 -> Quests.COOKS_ASSISTANT.questName + 15 -> Quests.DEMON_SLAYER.questName + 16 -> Quests.DORICS_QUEST.questName + 17 -> Quests.DRAGON_SLAYER.questName + 18 -> Quests.ERNEST_THE_CHICKEN.questName + 19 -> Quests.GOBLIN_DIPLOMACY.questName + 20 -> Quests.IMP_CATCHER.questName + 21 -> Quests.THE_KNIGHTS_SWORD.questName + 22 -> Quests.PIRATES_TREASURE.questName + 23 -> Quests.PRINCE_ALI_RESCUE.questName + 24 -> Quests.THE_RESTLESS_GHOST.questName + 25 -> Quests.ROMEO_JULIET.questName + 26 -> Quests.RUNE_MYSTERIES.questName + 27 -> Quests.SHEEP_SHEARER.questName + 28 -> Quests.SHIELD_OF_ARRAV.questName + 29 -> Quests.VAMPIRE_SLAYER.questName + 30 -> Quests.WITCHS_POTION.questName + 31 -> "Members' Quests" + 32 -> Quests.ANIMAL_MAGNETISM.questName + 33 -> Quests.BETWEEN_A_ROCK.questName + 34 -> Quests.BIG_CHOMPY_BIRD_HUNTING.questName + 35 -> Quests.BIOHAZARD.questName + 36 -> Quests.CABIN_FEVER.questName + 37 -> Quests.CLOCK_TOWER.questName + 38 -> Quests.CONTACT.questName + 39 -> Quests.ZOGRE_FLESH_EATERS.questName + 40 -> Quests.CREATURE_OF_FENKENSTRAIN.questName + 41 -> Quests.DARKNESS_OF_HALLOWVALE.questName + 42 -> Quests.DEATH_TO_THE_DORGESHUUN.questName + 43 -> Quests.DEATH_PLATEAU.questName + 44 -> Quests.DESERT_TREASURE.questName + 45 -> Quests.DEVIOUS_MINDS.questName + 46 -> Quests.THE_DIG_SITE.questName + 47 -> Quests.DRUIDIC_RITUAL.questName + 48 -> Quests.DWARF_CANNON.questName + 49 -> Quests.EADGARS_RUSE.questName + 50 -> Quests.EAGLES_PEAK.questName + 51 -> Quests.ELEMENTAL_WORKSHOP_I.questName + 52 -> Quests.ELEMENTAL_WORKSHOP_II.questName + 53 -> Quests.ENAKHRAS_LAMENT.questName + 54 -> Quests.ENLIGHTENED_JOURNEY.questName + 55 -> Quests.THE_EYES_OF_GLOUPHRIE.questName + 56 -> Quests.FAIRYTALE_I_GROWING_PAINS.questName + 57 -> Quests.FAIRYTALE_II_CURE_A_QUEEN.questName + 58 -> Quests.FAMILY_CREST.questName + 59 -> Quests.THE_FEUD.questName + 60 -> Quests.FIGHT_ARENA.questName + 61 -> Quests.FISHING_CONTEST.questName + 62 -> Quests.FORGETTABLE_TALE.questName + 63 -> Quests.THE_FREMENNIK_TRIALS.questName + 64 -> Quests.WATERFALL_QUEST.questName + 65 -> Quests.GARDEN_OF_TRANQUILITY.questName + 66 -> Quests.GERTRUDES_CAT.questName + 67 -> Quests.GHOSTS_AHOY.questName + 68 -> Quests.THE_GIANT_DWARF.questName + 69 -> Quests.THE_GOLEM.questName + 70 -> Quests.THE_GRAND_TREE.questName + 71 -> Quests.THE_HAND_IN_THE_SAND.questName + 72 -> Quests.HAUNTED_MINE.questName + 73 -> Quests.HAZEEL_CULT.questName + 74 -> Quests.HEROES_QUEST.questName + 75 -> Quests.HOLY_GRAIL.questName + 76 -> Quests.HORROR_FROM_THE_DEEP.questName + 77 -> Quests.ICTHLARINS_LITTLE_HELPER.questName + 78 -> Quests.IN_AID_OF_THE_MYREQUE.questName + 79 -> Quests.IN_SEARCH_OF_THE_MYREQUE.questName + 80 -> Quests.JUNGLE_POTION.questName + 81 -> Quests.LEGENDS_QUEST.questName + 82 -> Quests.LOST_CITY.questName + 83 -> Quests.THE_LOST_TRIBE.questName + 84 -> Quests.LUNAR_DIPLOMACY.questName + 85 -> Quests.MAKING_HISTORY.questName + 86 -> Quests.MERLINS_CRYSTAL.questName + 87 -> Quests.MONKEY_MADNESS.questName + 88 -> Quests.MONKS_FRIEND.questName + 89 -> Quests.MOUNTAIN_DAUGHTER.questName + 90 -> Quests.MOURNINGS_END_PART_I.questName + 91 -> Quests.MOURNINGS_END_PART_II.questName + 92 -> Quests.MURDER_MYSTERY.questName + 93 -> Quests.MY_ARMS_BIG_ADVENTURE.questName + 94 -> Quests.NATURE_SPIRIT.questName + 95 -> Quests.OBSERVATORY_QUEST.questName + 96 -> Quests.ONE_SMALL_FAVOUR.questName + 97 -> Quests.PLAGUE_CITY.questName + 98 -> Quests.PRIEST_IN_PERIL.questName + 99 -> Quests.RAG_AND_BONE_MAN.questName + 100 -> Quests.RATCATCHERS.questName + 101 -> Quests.RECIPE_FOR_DISASTER.questName + 102 -> Quests.RECRUITMENT_DRIVE.questName + 103 -> Quests.REGICIDE.questName + 104 -> Quests.ROVING_ELVES.questName + 105 -> Quests.ROYAL_TROUBLE.questName + 106 -> Quests.RUM_DEAL.questName + 107 -> Quests.SCORPION_CATCHER.questName + 108 -> Quests.SEA_SLUG.questName + 109 -> Quests.THE_SLUG_MENACE.questName + 110 -> Quests.SHADES_OF_MORTTON.questName + 111 -> Quests.SHADOW_OF_THE_STORM.questName + 112 -> Quests.SHEEP_HERDER.questName + 113 -> Quests.SHILO_VILLAGE.questName + 114 -> Quests.A_SOULS_BANE.questName + 115 -> Quests.SPIRITS_OF_THE_ELID.questName + 116 -> Quests.SWAN_SONG.questName + 117 -> Quests.TAI_BWO_WANNAI_TRIO.questName + 118 -> Quests.A_TAIL_OF_TWO_CATS.questName + 119 -> Quests.TEARS_OF_GUTHIX.questName + 120 -> Quests.TEMPLE_OF_IKOV.questName + 121 -> Quests.THRONE_OF_MISCELLANIA.questName + 122 -> Quests.THE_TOURIST_TRAP.questName + 123 -> Quests.WITCHS_HOUSE.questName + 124 -> Quests.TREE_GNOME_VILLAGE.questName + 125 -> Quests.TRIBAL_TOTEM.questName + 126 -> Quests.TROLL_ROMANCE.questName + 127 -> Quests.TROLL_STRONGHOLD.questName + 128 -> Quests.UNDERGROUND_PASS.questName + 129 -> Quests.WANTED.questName + 130 -> Quests.WATCHTOWER.questName + 131 -> Quests.COLD_WAR.questName + 132 -> Quests.THE_FREMENNIK_ISLES.questName + 133 -> Quests.TOWER_OF_LIFE.questName + 134 -> Quests.THE_GREAT_BRAIN_ROBBERY.questName + 135 -> Quests.WHAT_LIES_BELOW.questName + 136 -> Quests.OLAFS_QUEST.questName + 137 -> Quests.ANOTHER_SLICE_OF_HAM.questName + 138 -> Quests.DREAM_MENTOR.questName + 139 -> Quests.GRIM_TALES.questName + 140 -> Quests.KINGS_RANSOM.questName + 141 -> Quests.THE_PATH_OF_GLOUPHRIE.questName + 142 -> Quests.BACK_TO_MY_ROOTS.questName + 143 -> Quests.LAND_OF_THE_GOBLINS.questName + 144 -> Quests.DEALING_WITH_SCABARAS.questName + 145 -> Quests.WOLF_WHISTLE.questName + 146 -> Quests.AS_A_FIRST_RESORT.questName + 147 -> Quests.CATAPULT_CONSTRUCTION.questName + 148 -> Quests.KENNITHS_CONCERNS.questName + 149 -> Quests.LEGACY_OF_SEERGAZE.questName + 150 -> Quests.PERILS_OF_ICE_MOUNTAIN.questName + 151 -> Quests.TOKTZ_KET_DILL.questName + 152 -> Quests.SMOKING_KILLS.questName + 153 -> Quests.ROCKING_OUT.questName + 154 -> Quests.SPIRIT_OF_SUMMER.questName + 155 -> Quests.MEETING_HISTORY.questName + 156 -> Quests.ALL_FIRED_UP.questName + 157 -> Quests.SUMMERS_END.questName + 158 -> Quests.DEFENDER_OF_VARROCK.questName + 159 -> Quests.SWEPT_AWAY.questName + 160 -> Quests.WHILE_GUTHIX_SLEEPS.questName + 161 -> Quests.IN_PYRE_NEED.questName + 162 -> Quests.MYTHS_OF_THE_WHITE_LANDS.questName + else -> "" + } + return quest as String + } +} diff --git a/Server/src/main/content/global/handlers/iface/RequestAssistInterface.java b/Server/src/main/content/global/handlers/iface/RequestAssistInterface.java new file mode 100644 index 0000000..952a0bf --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/RequestAssistInterface.java @@ -0,0 +1,65 @@ +package content.global.handlers.iface; + +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.request.assist.AssistSession; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * @author 'Vexia + */ +@Initializable +public class RequestAssistInterface extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.put(301, this); + return this; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + final AssistSession session = AssistSession.getExtension(player); + if (session == null) { + return true; + } + if (player != session.getPlayer()) { + return true; + } + switch (button) { + case 15: + session.toggleButton((byte) 0); + break; + case 20: + session.toggleButton((byte) 1); + break; + case 25: + session.toggleButton((byte) 2); + break; + case 30: + session.toggleButton((byte) 3); + break; + case 35: + session.toggleButton((byte) 4); + break; + case 40: + session.toggleButton((byte) 5); + break; + case 45: + session.toggleButton((byte) 6); + break; + case 50: + session.toggleButton((byte) 7); + break; + case 55: + session.toggleButton((byte) 8); + break; + } + session.refresh(); + return true; + } + +} diff --git a/Server/src/main/content/global/handlers/iface/RulesAndInfo.kt b/Server/src/main/content/global/handlers/iface/RulesAndInfo.kt new file mode 100644 index 0000000..420c70d --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/RulesAndInfo.kt @@ -0,0 +1,67 @@ +package content.global.handlers.iface + +import core.api.* +import core.game.node.entity.player.Player +import core.tools.RandomFunction +import core.game.interaction.InterfaceListener + +object RulesAndInfo { + val RULES = arrayOf( + "1. Be respectful to your fellow players.", + " -No harassment, etc.", + " -Keep arguments private.", + "2. Do not exploit bugs.", + " -Zero tolerance. Can result in account deletion.", + " -If you discover a bug, report it on our Gitlab.", + "3. Do not discuss or advertise other servers.", + " -Discussion of the live jagex games is fine.", + " -Discussion of open source projects is fine.", + "4. No unfair advantages.", + " -This includes autoclickers, autohotkey, etc.", + " -Exception: 1-to-1 inputs, such as mousekeys.", + " -Includes training methods that bypass AFK limits." + ) + val SEPARATOR = " " + val INFO = arrayOf( + "Join the forums! forum.2009scape.org " + ) + + @JvmStatic + fun openFor(player: Player) + { + if(getAttribute(player, "rules:confirmed", false) || !getAttribute(player, "tutorial:complete", false)) + return + val pin = getAttribute(player, "rules:pin", RandomFunction.random(1000,9999)) + setAttribute(player, "/save:rules:pin", pin) + + var ln = setBaseRulesAndInfo(player) + + setInterfaceText(player, "If you agree to the above, type ::confirmrules $pin", 384, ln++) + setInterfaceText(player, "", 384, ln) + player.packetDispatch.sendInterfaceConfig(384, 17, true) + openInterface(player, 384) + player.lock() + } + + @JvmStatic + fun setBaseRulesAndInfo(player: Player): Int { + var ln = 1 + for(line in INFO) setInterfaceText(player, INFO[ln - 1], 384, ln++) + setInterfaceText(player, SEPARATOR, 384, ln++) + val newIndex = ln + for(line in RULES) setInterfaceText(player, RULES[ln - newIndex], 384, ln++) + setInterfaceText(player, "", 384, ln) + return ln + } +} + +class RulesListener : InterfaceListener +{ + override fun defineInterfaceListeners() { + onClose(384){player, _ -> + if(!getAttribute(player, "rules:confirmed", false)) + runTask(player, 1) { RulesAndInfo.openFor(player); sendDialogue(player, "Please read the rules.") } + return@onClose true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/iface/SawmillPlankInterface.java b/Server/src/main/content/global/handlers/iface/SawmillPlankInterface.java new file mode 100644 index 0000000..0095753 --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/SawmillPlankInterface.java @@ -0,0 +1,175 @@ +package content.global.handlers.iface; + +import static core.api.ContentAPIKt.*; +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.RunScript; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.Plugin; +import kotlin.Unit; + +/** + * Represents the component handler for the interface 403. + * @author 'Vexia + * @date Oct 8, 2013 + */ +@Initializable +public class SawmillPlankInterface extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.put(403, this); + return this; + } + + @Override + public boolean handle(final Player player, Component component, int opcode, int button, int slot, int itemId) { + Plank plank = null; + if (button > 101 && button < 108) { + plank = Plank.WOOD; + } else if (button > 108 && button < 114) { + plank = Plank.OAK; + } else if (button > 114 && button < 120) { + plank = Plank.TEAK; + } else if (button > 120 && button < 126) { + plank = Plank.MAHOGANY; + } + int amount = -1; + int fullIndex = plank == Plank.WOOD ? 107 : plank == Plank.OAK ? 113 : plank == Plank.TEAK ? 119 : 125; + // 107, 105, 104, 103, 102 + int difference = -1; + if (plank != Plank.WOOD) { + difference = fullIndex - button; + } else { + difference = fullIndex - button - (button != 107 ? 1 : 0); + } + switch (difference) { + case 0: + amount = 1; + break; + case 1: + amount = 5; + break; + case 2: + amount = 10; + break; + case 3: + amount = 69; + break; + case 4: + amount = player.getInventory().getAmount(plank.getLog()); + break; + } + if (amount == 69) { + final Plank plankk = plank; + sendInputDialogue(player, true, "Enter the amount:", (value) -> { + create(player, plankk, (int) value); + return Unit.INSTANCE; + }); + return true; + } + if (plank != null) { + create(player, plank, amount); + } + return true; + } + + /** + * Method used to create a plank from a log. + * @param player the player. + * @param plank the plank. + * @param amount the amount. + */ + public final void create(final Player player, final Plank plank, int amount) { + player.getInterfaceManager().close(); + if (amount > player.getInventory().getAmount(plank.getLog())) { + amount = player.getInventory().getAmount(plank.getLog()); + } + if (!player.getInventory().containsItem(new Item(plank.getLog().getId()))) { + player.getDialogueInterpreter().sendDialogues(4250, null, "You'll need to bring me some more logs."); + return; + } + if (!player.getInventory().contains(995, plank.getPrice() * amount)) { + player.getDialogueInterpreter().sendDialogues(player, null, "Sorry, I don't have enough coins to pay for that."); + return; + } + if (player.getInventory().remove(new Item(995, plank.getPrice() * amount))) { + // Make a plank at the sawmill + if (plank == Plank.WOOD) { + player.getAchievementDiaryManager().finishTask(player, DiaryType.VARROCK, 0, 3); + } + // Buy twenty mahogany planks from the Sawmill Operator in one

transaction + if (plank == Plank.MAHOGANY && amount >= 20) { + player.getAchievementDiaryManager().finishTask(player, DiaryType.VARROCK, 1, 15); + } + Item remove = plank.getLog(); + remove.setAmount(amount); + if (player.getInventory().remove(remove)) { + Item planks = plank.getPlank(); + planks.setAmount(amount); + player.getInventory().add(planks); + } + } + } + + /** + * Represents an enum of planks to be boughten. + * @author 'Vexia + * @date Oct 8, 2013 + */ + public enum Plank { + WOOD(new Item(1511), new Item(960), 100), OAK(new Item(1521), new Item(8778), 250), TEAK(new Item(6333), new Item(8780), 500), MAHOGANY(new Item(6332), new Item(8782), 1500); + + /** + * Constructs a new {@code SawmillPlankInterface} {@code Object}. + * @param log the log. + * @param plank the plank. + * @param price the price. + */ + Plank(Item log, Item plank, int price) { + this.log = log; + this.plank = plank; + this.price = price; + } + + /** + * Represents the item needed. + */ + private final Item log; + + /** + * Represents the item given. + */ + private final Item plank; + + /** + * Represents the price of the plank. + */ + private final int price; + + /** + * @return the log. + */ + public Item getLog() { + return log; + } + + /** + * @return the plank. + */ + public Item getPlank() { + return plank; + } + + /** + * @return the price. + */ + public int getPrice() { + return price; + } + } +} diff --git a/Server/src/main/content/global/handlers/iface/ScrollInterface.kt b/Server/src/main/content/global/handlers/iface/ScrollInterface.kt new file mode 100644 index 0000000..5e9bfc2 --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/ScrollInterface.kt @@ -0,0 +1,47 @@ +package content.global.handlers.iface + +import core.api.closeInterface +import core.api.openInterface +import core.game.node.entity.player.Player +import org.rs09.consts.Components + +/** + * Interface listener for Scrolls + * Use this to set up a simple scroll display. + * + * Currently, scrolls do not happen to have any button interactions, so no listeners are here yet. + * This is generally a helper class until certain scrolls require interactions. + * + * @author ovenbreado + */ +class ScrollInterface { + + companion object { + /** This is a 15-Lines scroll */ + private val MESSAGESCROLL_220_LINE_IDS = arrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15) + + fun scrollSetup(player: Player, scrollComponent: Int, contents: Array) { + closeInterface(player) // Important: Close previous interfaces. + if (scrollComponent == Components.MESSAGESCROLL_220) { + openInterface(player, Components.MESSAGESCROLL_220) + setPageContent(player, Components.MESSAGESCROLL_220, MESSAGESCROLL_220_LINE_IDS, contents) + } + } + + /** Set text contents of scroll */ + fun setPageContent(player: Player, componentId: Int, scrollLineIds: Array, contents: Array) { + for (line in contents) { + // This is to prevent error child lines being set and crashing the client. + if (scrollLineIds.contains(line.child)) { + player.packetDispatch.sendString(line.message, componentId, line.child) + } + } + } + } +} + +/** Constructs a new ScrollLine object. */ +class ScrollLine( + val message: String, + val child: Int +) \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/iface/SettingTabInterface.java b/Server/src/main/content/global/handlers/iface/SettingTabInterface.java new file mode 100644 index 0000000..c8bac8c --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/SettingTabInterface.java @@ -0,0 +1,89 @@ +package content.global.handlers.iface; + +import static core.api.ContentAPIKt.*; + +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; +import core.plugin.Plugin; + +/** + * @author 'Vexia + */ +@Initializable +public class SettingTabInterface extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.put(261, this); + return this; + } + + @Override + public boolean handle(Player p, Component component, int opcode, int button, int slot, int itemId) { + switch (button) { + case 10:// brightness + int brightness = button - 7; + p.getSettings().setBrightness(brightness); + break; + case 11: + case 12: + case 13: + case 14: + case 15:// music + int volume = 15 - button; + p.getSettings().setMusicVolume(volume); + break; + case 16://530 settings + /* if (TutorialSession.getExtension(p).getStage() != TutorialSession.MAX_STAGE) { + p.sendMessage("You must finish the tutorial before opening the graphic settings."); + break; + }*/ + p.getInterfaceManager().open(new Component(742)); + break; + case 18://530 settings + p.getInterfaceManager().open(new Component(743)); + break; + case 17: + case 19: + case 20:// sonund + int volume1 = 20 - button; + p.getSettings().setSoundEffectVolume(volume1); + break; + case 29: + case 30: + case 31: + case 32: + case 33:// all sound + int volume11 = 33 - button; + p.getSettings().setAreaSoundVolume(volume11); + break; + case 6:// mouse + p.getSettings().toggleMouseButton(); + break; + case 4:// effects + p.getSettings().toggleChatEffects(); + break; + case 5:// private chat + p.getSettings().toggleSplitPrivateChat(); + break; + case 7:// aid + if (p.getIronmanManager().checkRestriction()) { + return true; + } + p.getSettings().toggleAcceptAid(); + break; + case 3:// run + p.getSettings().toggleRun(); + break; + case 8:// house + p.getInterfaceManager().close(); + setVarp(p, 261, getVarp(p, 261) & 0x1); + p.getInterfaceManager().openSingleTab(new Component(398)); + break; + } + return true; + } +} diff --git a/Server/src/main/content/global/handlers/iface/ShoppingPlugin.java b/Server/src/main/content/global/handlers/iface/ShoppingPlugin.java new file mode 100644 index 0000000..175f20f --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/ShoppingPlugin.java @@ -0,0 +1,151 @@ +/* +package core.game.interaction.inter; + +import static core.api.ContentAPIKt.*; +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.container.Container; +import core.game.content.global.shop.ShopViewer; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.RunScript; +import core.game.node.item.Item; +import core.net.packet.in.ExaminePacket; +import core.plugin.Initializable; +import core.plugin.Plugin; +import kotlin.Unit; +import kotlin.jvm.functions.Function1; + +*/ +/** + * Represents the plugin used to handle the shopping interface. + * @author 'Vexia + * @version 1.0 + *//* + +@Initializable +public final class ShoppingPlugin extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.forId(620).setPlugin(this); + ComponentDefinition.forId(621).setPlugin(this); + return this; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + final ShopViewer viewer = player.getExtension(ShopViewer.class); + if (player.getAttributes().containsKey("spawning_items")) { + switch (opcode) { + case 155: + switch (button) { + case 23: + case 24: + case 0: + viewer.getShop().give(player, slot, 1, viewer.getTabIndex()); + break; + } + break; + } + return true; + } + if (viewer == null) { + + return true; + } + final Container container = button == 0 ? player.getInventory() : viewer.getShop().getContainer(viewer.getTabIndex()); + switch (opcode) { + case 155: + switch (button) { + case 23: + case 24: + case 0: + value(player, viewer, container.get(slot), component.getId() == 621); + break; + case 25: + case 26: + viewer.showStock(button == 26 ? 1 : 0); + break; + } + break; + case 9: + int id = container.getId(slot); + if (id == -1) { + return true; + } + player.getPacketDispatch().sendMessage(ExaminePacket.getItemExamine(id)); + break; + case 196: + case 199: + case 124: + case 234: + final int amount = getAmount(opcode); + if (player.getAttribute("shop-delay", 0L) > System.currentTimeMillis()) { + return true; + } + player.setAttribute("shop-delay", System.currentTimeMillis() + 500); + if (amount == -1) { + player.setAttribute("runscript", getRunScript(viewer, slot, component.getId())); + player.getDialogueInterpreter().sendInput(false, "Enter the amount:"); + break; + } + if (component.getId() == 620) { + viewer.getShop().buy(player, slot, amount, viewer.getTabIndex()); + } else { + viewer.getShop().sell(player, slot, amount, viewer.getTabIndex()); + } + break; + } + return true; + } + + */ +/** + * Method used to value an item. + * @param player the player. + * @param viewer the viewer. + * @param item the item. + * @param sell the sell. + *//* + + private void value(final Player player, final ShopViewer viewer, final Item item, final boolean sell) { + if (item == null) { + return; + } + viewer.getShop().value(player, viewer, item, sell); + } + + */ +/** + * Gets the run script for selling an item. + * @return the script. + * @param slot the slot. + *//* + + private Function1 getRunScript(final ShopViewer viewer, final int slot, final int componentId) { + return (value) -> { + switch (componentId){ + case 620: + viewer.getShop().buy(viewer.getPlayer(), slot, (int) value, viewer.getTabIndex()); + break; + case 621: + viewer.getShop().sell(viewer.getPlayer(), slot, (int) value, viewer.getTabIndex()); + break; + } + return Unit.INSTANCE; + }; + } + + */ +/** + * Gets the amount by the opcode. + * @param opcode the opcode. + * @return the amount. + *//* + + private int getAmount(int opcode) { + return opcode == 196 ? 1 : opcode == 124 ? 5 : opcode == 199 ? 10 : -1; + } +} +*/ diff --git a/Server/src/main/content/global/handlers/iface/SkillInterface.java b/Server/src/main/content/global/handlers/iface/SkillInterface.java new file mode 100644 index 0000000..a0ac47d --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/SkillInterface.java @@ -0,0 +1,32 @@ +package content.global.handlers.iface; + +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; + +import static core.api.ContentAPIKt.*; + +/** + * Represents the plugin used for the skilling interface. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class SkillInterface extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.put(499, this); + return this; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + setVarbit(player, 3288, player.getAttribute("skillMenu", -1)); + setVarbit(player, 3289, button - 10); + return true; + } +} diff --git a/Server/src/main/content/global/handlers/iface/SkillTabInterface.java b/Server/src/main/content/global/handlers/iface/SkillTabInterface.java new file mode 100644 index 0000000..9dba587 --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/SkillTabInterface.java @@ -0,0 +1,162 @@ +package content.global.handlers.iface; + +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.node.entity.skill.LevelUp; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.world.GameWorld; +import core.plugin.Initializable; +import core.plugin.Plugin; + +import static core.api.ContentAPIKt.*; + +/** + * Represents the plugin used to handle the skilling tab. + * @author Vexia + * @author Splinter + * @version 1.1 + */ +@Initializable +public final class SkillTabInterface extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.put(320, this); + return this; + } + + @Override + public boolean handle(Player p, Component component, int opcode, int button, int slot, int itemId) { + final SkillConfig config = SkillConfig.forId(button); + if (config == null) { + return true; + } + if (!GameWorld.getSettings().isPvp()) { + if (p.getAttribute("levelup:" + config.getSkillId(), false)) { + p.removeAttribute("levelup:" + config.getSkillId()); + LevelUp.sendFlashingIcons(p, -1); + setVarp(p, 1230, ADVANCE_CONFIGS[config.getSkillId()]); + p.getInterfaceManager().open(new Component(741)); + } else { + p.getPulseManager().clear(); + p.getInterfaceManager().open(new Component(499)); + setVarp(p, 965, config.getConfig()); + p.getAttributes().put("skillMenu", config.getConfig()); + } + } else { + if (config.getSkillId() > 6) { + p.getPacketDispatch().sendMessage("You cannot set a target level for this skill."); + return false; + } + if (p.canSpawn()) { + p.sendMessage("You must be inside Edgeville bank to set levels."); + return false; + } + } + return true; + } + + /** + * Holds all the config values of the skill advances. + */ + public static final int[] ADVANCE_CONFIGS = { + 9, 40, 17, 49, + 25, 57, 33, 641, + 659, 664, 121, 649, + 89, 114, 107, 72, + 64, 80, 673, 680, + 99, 698, 689, 705, + }; + + public enum SkillConfig { + ATTACK(125, 1, Skills.ATTACK), + STRENGTH(126, 2, Skills.STRENGTH), + DEFENCE(127, 5, Skills.DEFENCE), + RANGE(128, 3, Skills.RANGE), + PRAYER(129, 7, Skills.PRAYER), + MAGIC(130, 4, Skills.MAGIC), + RUNECRAFTING(131, 12, Skills.RUNECRAFTING), + HITPOINTS(133, 6, Skills.HITPOINTS), + AGILITY(134, 8, Skills.AGILITY), + HERBLORE(135, 9, Skills.HERBLORE), + THIEVING(136, 10, Skills.THIEVING), + CRAFTING(137, 11, Skills.CRAFTING), + FLETCHING(138, 19, Skills.FLETCHING), + SLAYER(139, 20, Skills.SLAYER), + MINING(141, 13, Skills.MINING), + SMITHING(142, 14, Skills.SMITHING), + FISHING(143, 15, Skills.FISHING), + COOKING(144, 16, Skills.COOKING), + FIREMAKING(145, 17, Skills.FIREMAKING), + WOODCUTTING(146, 18, Skills.WOODCUTTING), + FARMING(147, 21, Skills.FARMING), + CONSTRUCTION(132, 22, Skills.CONSTRUCTION), + HUNTER(140, 23, Skills.HUNTER), + SUMMONING(148, 24, Skills.SUMMONING); + + /** + * Constructs a new {@code SkillConfig} {@code Object}. + * @param button the button. + * @param config the config. + */ + SkillConfig(int button, int config, int skillId) { + this.button = button; + this.config = config; + this.skillId = skillId; + } + + /** + * Represents the button. + */ + private int button; + + /** + * Represents the config. + */ + private int config; + + /** + * The skill id. + */ + private int skillId; + + /** + * Gets the skill config. + * @param id the id. + * @return the skill config. + */ + public static SkillConfig forId(int id) { + for (SkillConfig config : SkillConfig.values()) { + if (config.button == id) + return config; + } + return null; + } + + /** + * Gets the button. + * @return the button. + */ + public int getButton() { + return button; + } + + /** + * Gets the config. + * @return the config. + */ + public int getConfig() { + return config; + } + + /** + * Gets the skill id. + * @return The skill id. + */ + public int getSkillId() { + return skillId; + } + } +} diff --git a/Server/src/main/content/global/handlers/iface/SmeltingInterface.java b/Server/src/main/content/global/handlers/iface/SmeltingInterface.java new file mode 100644 index 0000000..4032ff5 --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/SmeltingInterface.java @@ -0,0 +1,115 @@ +package content.global.handlers.iface; + +import static core.api.ContentAPIKt.*; +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.plugin.Initializable; +import content.global.skill.smithing.smelting.Bar; +import content.global.skill.smithing.smelting.SmeltingPulse; +import core.game.node.entity.player.Player; +import core.plugin.Plugin; +import kotlin.Unit; + +/** + * @author 'Vexia + */ +@Initializable +public class SmeltingInterface extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.put(311, this); + return this; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + final BarButton barType = BarButton.forId(button); + if (barType == null) { + return true; + } + if (barType.getAmount() == -1) { + player.getInterfaceManager().closeChatbox(); + sendInputDialogue(player, true, "Enter the amount:", (value) -> { + if (value instanceof String) { + submitIndividualPulse(player, new SmeltingPulse(player, null, barType.getBar(), Integer.parseInt((String) value))); + } else { + submitIndividualPulse(player, new SmeltingPulse(player, null, barType.getBar(), (int) value)); + } + return Unit.INSTANCE; + }); + } else { + player.getPulseManager().run(new SmeltingPulse(player, null, barType.getBar(), barType.getAmount())); + } + return true; + } + + /** + * @author 'Vexia + */ + public enum BarButton { + BRONZE_1(16, Bar.BRONZE, 1), BRONZE_5(15, Bar.BRONZE, 5), BRONZE_10(14, Bar.BRONZE, 10), BRONZE_X(13, Bar.BRONZE, -1), BLURITE_1(20, Bar.BLURITE, 1), BLURITE_5(19, Bar.BLURITE, 5), BLURITE_10(18, Bar.BLURITE, 10), BLURITE_X(17, Bar.BLURITE, -1), IRON_1(24, Bar.IRON, 1), IRON_5(23, Bar.IRON, 5), IRON_10(22, Bar.IRON, 10), IRON_X(21, Bar.IRON, -1), SILVER_1(28, Bar.SILVER, 1), SILVER_5(27, Bar.SILVER, 5), SILVER_10(26, Bar.SILVER, 10), SILVER_X(25, Bar.SILVER, -1), STEEL_1(32, Bar.STEEL, 1), STEEL_5(31, Bar.STEEL, 5), STEEL_10(30, Bar.STEEL, 10), STEEL_X(29, Bar.STEEL, -1), GOLD_1(36, Bar.GOLD, 1), GOLD_5(35, Bar.GOLD, 5), GOLD_10(34, Bar.GOLD, 10), GOLD_X(33, Bar.GOLD, -1), MITHRIL_1(40, Bar.MITHRIL, 1), MITHRIL_5(39, Bar.MITHRIL, 5), MITHRIL_10(38, Bar.MITHRIL, 10), MITHRIL_X(37, Bar.MITHRIL, -1), ADAMANT_1(44, Bar.ADAMANT, 1), ADAMANT_5(43, Bar.ADAMANT, 5), ADAMANT_10(42, Bar.ADAMANT, 10), ADAMANT_X(41, Bar.ADAMANT, -1), RUNE_1(48, Bar.RUNITE, 1), RUNE_5(47, Bar.RUNITE, 5), RUNE_10(46, Bar.RUNITE, 10), RUNE_X(45, Bar.RUNITE, -1); + + /** + * Constructs a new {@code BarButton} {@code Object}. + * @param button the button. + * @param bar the bar. + * @param amount the amt. + */ + BarButton(int button, Bar bar, int amount) { + this.button = button; + this.bar = bar; + this.amount = amount; + } + + /** + * The button. + */ + private int button; + + /** + * The bar. + */ + private Bar bar; + + /** + * The ammount. + */ + private int amount; + + /** + * @param id + * @return + */ + public static BarButton forId(int id) { + for (BarButton button : BarButton.values()) { + if (button.getButton() == id) { + return button; + } + } + return null; + } + + /** + * @return the button. + */ + public int getButton() { + return button; + } + + /** + * @return the bar. + */ + public Bar getBar() { + return bar; + } + + /** + * @return the amount. + */ + public int getAmount() { + return amount; + } + } +} diff --git a/Server/src/main/content/global/handlers/iface/SmithingInterface.java b/Server/src/main/content/global/handlers/iface/SmithingInterface.java new file mode 100644 index 0000000..3256736 --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/SmithingInterface.java @@ -0,0 +1,49 @@ +package content.global.handlers.iface; + +import static core.api.ContentAPIKt.*; +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.plugin.Initializable; +import content.global.skill.smithing.BarType; +import content.global.skill.smithing.Bars; +import content.global.skill.smithing.SmithingPulse; +import content.global.skill.smithing.SmithingType; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Plugin; +import kotlin.Unit; + +/** + * @author 'Vexia + */ +@Initializable +public class SmithingInterface extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.put(300, this); + return this; + } + + @Override + public boolean handle(final Player p, Component component, int opcode, int button, int slot, int itemId) { + final int item = Bars.getItemId(button, (BarType) p.getGameAttributes().getAttribute("smith-type")); + final Bars bar = Bars.forId(item); + if (bar == null) { + return true; + } + int amount = SmithingType.forButton(p, bar, button, bar.getBarType().getBarType()); + p.getGameAttributes().setAttribute("smith-bar", bar); + p.getGameAttributes().setAttribute("smith-item", item); + if (amount == -1) { + sendInputDialogue(p, true, "Enter the amount:", (value) -> { + p.getPulseManager().run(new SmithingPulse(p, new Item((int) p.getGameAttributes().getAttribute("smith-item"), (int) value), (Bars) p.getGameAttributes().getAttribute("smith-bar"), (int) value)); + return Unit.INSTANCE; + }); + return true; + } + p.getPulseManager().run(new SmithingPulse(p, new Item(item, amount), Bars.forId(item), amount)); + return true; + } +} diff --git a/Server/src/main/content/global/handlers/iface/SpinningInterface.java b/Server/src/main/content/global/handlers/iface/SpinningInterface.java new file mode 100644 index 0000000..8ee642e --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/SpinningInterface.java @@ -0,0 +1,63 @@ +package content.global.handlers.iface; + +import static core.api.ContentAPIKt.*; +import core.cache.def.impl.ItemDefinition; +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import content.global.skill.crafting.spinning.SpinningItem; +import content.global.skill.crafting.spinning.SpinningPulse; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.Plugin; +import kotlin.Unit; + +@Initializable +public class SpinningInterface extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.put(459, this); + return this; + } + + @Override + public boolean handle(final Player p, Component component, int opcode, int button, int slot, int itemId) { + final SpinningItem spin = SpinningItem.forId(button); + if (spin == null) { + return true; + } + if (!p.getInventory().contains(spin.getNeed(), 1)) { + p.getPacketDispatch().sendMessage("You need "+ ItemDefinition.forId(spin.getNeed()).getName().toLowerCase() + " to make this."); + return true; + } + int amt = -1; + switch (opcode) { + case 155: + amt = 1; + break; + case 196: + amt = 5; + break; + case 124: + amt = p.getInventory().getAmount(new Item(spin.getNeed())); + break; + case 199: + sendInputDialogue(p, true, "Enter the amount:", (value) -> { + if (value instanceof String) { + submitIndividualPulse(p, new SpinningPulse(p, new Item(spin.getNeed(), 1), Integer.parseInt((String) value), spin)); + } else { + submitIndividualPulse(p, new SpinningPulse(p, new Item(spin.getNeed(), 1), (int) value, spin)); + } + return Unit.INSTANCE; + }); + break; + } + if (opcode == 199) { + return true; + } + p.getPulseManager().run(new SpinningPulse(p, new Item(spin.getNeed(), 1), amt, spin)); + return true; + } +} diff --git a/Server/src/main/content/global/handlers/iface/TanningInterface.java b/Server/src/main/content/global/handlers/iface/TanningInterface.java new file mode 100644 index 0000000..aa15e4b --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/TanningInterface.java @@ -0,0 +1,90 @@ +package content.global.handlers.iface; + +import static core.api.ContentAPIKt.*; +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import content.global.skill.crafting.TanningProduct; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.Plugin; +import kotlin.Unit; + +/** + * @author Vexia + * @version 1.2 + */ +@Initializable +public class TanningInterface extends ComponentPlugin { + + /** + * Method used to create a new instance. + * @param arg + * @return + * @throws Throwable + */ + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.put(324, this); + return this; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + TanningProduct def = null; + switch (button) { + case 1: + def = TanningProduct.SOFT_LEATHER; + break; + case 2: + def = TanningProduct.HARD_LEATHER; + break; + case 3: + def = TanningProduct.SNAKESKIN; + break; + case 4: + def = TanningProduct.SNAKESKIN2; + break; + case 5: + def = TanningProduct.GREEN_DHIDE; + break; + case 6: + def = TanningProduct.BLUEDHIDE; + break; + case 7: + def = TanningProduct.REDDHIDE; + break; + case 8: + def = TanningProduct.BLACKDHIDE; + break; + } + if (def == null) { + return true; + } + int amount = 0; + final TanningProduct deff = def; + switch (opcode){ + case 155: + amount = 1; + break; + case 196: + amount = 5; + break; + case 124: + amount = 10; + case 199: + sendInputDialogue(player, true, "Enter the amount:", (value) -> { + TanningProduct.tan(player, (int) value, deff); + return Unit.INSTANCE; + }); + break; + case 234: + amount = player.getInventory().getAmount(new Item(def.getItem(), 1)); + break; + } + TanningProduct.tan(player, amount, def); + return true; + } + +} diff --git a/Server/src/main/content/global/handlers/iface/TeleotherInterface.kt b/Server/src/main/content/global/handlers/iface/TeleotherInterface.kt new file mode 100644 index 0000000..051bc04 --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/TeleotherInterface.kt @@ -0,0 +1,23 @@ +package content.global.handlers.iface + +import core.game.node.entity.player.link.TeleportManager.TeleportType +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import org.rs09.consts.Components +import core.game.interaction.InterfaceListener + +class TeleotherInterface : InterfaceListener { + val IFACE = Components.TELEPORT_OTHER_326 + + override fun defineInterfaceListeners() { + on(IFACE){player, _, _, button, _, _ -> + if(button == 5){ + player.lock(2) + if (player.teleporter.send(player.getAttribute("t-o_location", player.location), TeleportType.TELE_OTHER)) { + player.visualize(Animation.create(1816), Graphics.create(342)) + } + } + player.interfaceManager.close() + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/iface/ThessaliaInterface.kt b/Server/src/main/content/global/handlers/iface/ThessaliaInterface.kt new file mode 100644 index 0000000..4c98f7e --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/ThessaliaInterface.kt @@ -0,0 +1,250 @@ +package content.global.handlers.iface + +import core.api.playJingle +import core.game.component.Component +import core.game.component.ComponentDefinition +import core.game.component.ComponentPlugin +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import core.plugin.Plugin + +/** + * Fully accurate and functional thessalia interface handling + * @author Ceikry + */ + +private const val THESSALIA_MALE_COMPONENT = 591 +private const val THESSALIA_FEMALE_COMPONENT = 594 +private const val PLAYER_MODEL_CHILD_ID = 59 + +private val legColors = intArrayOf(24, 23, 3, 22, 13, 12, 7, 19, 5, 1, 10, 14, 25, 9, 0, 26, 21, 8, 20, 15, 11, 28, 27, 4, 6, 18, 17, 2, 16) +private val torsoColors = intArrayOf(24, 23, 2, 22, 12, 11, 6, 19, 4, 0, 9, 13, 25, 8, 15, 26, 21, 7, 20, 14, 10, 28, 27, 3, 5, 18, 17, 1, 16) + +private val maleTorsoButtonRange = (185..198) +private val maleArmsButtonRange = (199..210) +private val maleLegsButtonRange = (211..221) +private val maleColorButtonRange = (252..280) + +private val femaleTorsoButtonRange = (186..196) +private val femaleArmsButtonRange = (197..207) +private val femaleLegsButtonRange = (208..222) +private val femaleColorButtonRange = (253..281) + +//Male Torso +private const val M_STRIPED_SWEATER = 111 +private const val M_WOOLLEN_VEST = 113 +private const val M_PRINCELY_VEST = 114 +private const val M_TATTERED_WAISTCOAT = 115 +private const val M_FINE_SHIRT = 21 +private const val M_WAISTCOAT = 116 +private const val M_PLAIN_TOP = 18 +private const val M_LIGHT_BUTTONS = 19 +private const val M_DARK_BUTTONS = 20 +private const val M_JACKET = 112 +private const val M_SHIRT = 24 +private const val M_STITCHING = 23 +private const val M_RAGGED_TOP = 24 +private const val M_TWO_TONED = 25 + +private val maleTorsoIDs = intArrayOf(M_STRIPED_SWEATER, M_WOOLLEN_VEST, M_PRINCELY_VEST, M_TATTERED_WAISTCOAT, M_FINE_SHIRT, M_WAISTCOAT, M_PLAIN_TOP, M_LIGHT_BUTTONS, M_DARK_BUTTONS, M_JACKET, M_SHIRT, M_STITCHING, M_RAGGED_TOP, M_TWO_TONED) + +//Male Sleeves +private const val M_STRIPED_ARMS = 107 +private const val M_PRINCELY_SLEEVES = 108 +private const val M_FINE_CUFFS = 29 +private const val M_WOOLLEN_SLEEVES = 106 +private const val M_RAGGED_ARMS = 110 +private const val M_TATTERED_SLEEVES = 109 +private const val M_LOOSE_SLEEVED = 28 +private const val M_REGULAR = 26 +private const val M_MUSCLEBOUND = 27 +private const val M_LARGE_CUFFED = 105 +private const val M_THIN_SLEEVED = 30 +private const val M_SHOULDER_PADS = 31 + +private val maleSleeveIDs = intArrayOf(M_STRIPED_ARMS, M_PRINCELY_SLEEVES, M_FINE_CUFFS, M_WOOLLEN_SLEEVES, M_RAGGED_ARMS, M_TATTERED_SLEEVES, M_LOOSE_SLEEVED, M_REGULAR, M_MUSCLEBOUND, M_LARGE_CUFFED, M_THIN_SLEEVED, M_SHOULDER_PADS) + +//Male Leg IDs +private const val M_PLAIN_TROUSERS = 36 +private const val M_PRINCELY_BREECHES = 85 +private const val M_SHORTS = 37 +private const val M_RAGGED_BREECHES = 40 +private const val M_TATTERED_BREECHES = 89 +private const val M_TORN_TROUSERS = 90 +private const val M_BREECHES = 86 +private const val M_STRIPED_TROUSERS = 88 +private const val M_TURN_UPS = 39 +private const val M_FLARES = 38 +private const val M_FINE_BREECHES = 87 + +private val maleLegIDs = intArrayOf(M_PLAIN_TROUSERS, M_PRINCELY_BREECHES, M_SHORTS, M_RAGGED_BREECHES, M_TATTERED_BREECHES, M_TORN_TROUSERS, M_BREECHES, M_STRIPED_TROUSERS, M_TURN_UPS, M_FLARES, M_FINE_BREECHES) + +//Female Torso +private const val F_STRIPED_SWEATER = 153 +private const val F_WOOLLEN_VEST = 155 +private const val F_FRILLED_BLOUSE = 156 +private const val F_BODICE = 157 +private const val F_FINE_SHIRT = 154 +private const val F_RAGGED_TOP = 158 +private const val F_PLAIN_TOP = 56 +private const val F_CROP_TOP = 57 +private const val F_SIMPLE = 58 +private const val F_POLO_NECK = 59 +private const val F_TORN = 60 + +private val femaleTopIDs = intArrayOf(F_STRIPED_SWEATER, F_WOOLLEN_VEST, F_FRILLED_BLOUSE, F_BODICE, F_FINE_SHIRT, F_RAGGED_TOP, F_PLAIN_TOP, F_CROP_TOP, F_SIMPLE, F_POLO_NECK, F_TORN) + +//Female Arms +private const val F_STRIPED_ARMS = 149 +private const val F_FRILLED_SLEEVES = 150 +private const val F_FINE_CUFFS = 65 +private const val F_WOOLLEN_ARMS = 148 +private const val F_RAGGED_SLEEVES = 151 +private const val F_TATTERED_SLEEVES = 152 +private const val F_LONG_SLEEVES = 64 +private const val F_SHORT_SLEEVES = 61 +private const val F_MUSCLY = 63 +private const val F_LARGE_CUFFS = 147 +private const val F_BARE_ARMS = 62 + +private val femaleArmIDs = intArrayOf(F_STRIPED_ARMS, F_FRILLED_SLEEVES, F_FINE_CUFFS, F_WOOLLEN_ARMS, F_RAGGED_SLEEVES, F_TATTERED_SLEEVES, F_LONG_SLEEVES, F_SHORT_SLEEVES, F_MUSCLY, F_LARGE_CUFFS, F_BARE_ARMS) + +//Female Legs +private const val F_FINE_SKIRT = 129 +private const val F_FRILLED_SKIRT = 130 +private const val F_LAYERED_SKIRT = 128 +private const val F_LONG_NARROW_SKIRT = 74 +private const val F_RAGGED_SKIRT = 133 +private const val F_TATTERED_SKIRT = 134 +private const val F_SHORT_SKIRT = 71 +private const val F_SASHED_SKIRT = 131 +private const val F_FITTED_SKIRT = 132 +private const val F_TORN_TROUSERS = 75 +private const val F_LONG_SKIRT = 73 +private const val F_TURN_UPS = 76 +private const val F_FLARES = 72 +private const val F_PLAIN_TROUSERS = 70 +private const val F_SHORTS = 77 + +private val femaleLegIDs = intArrayOf(F_FINE_SKIRT, F_FRILLED_SKIRT, F_LAYERED_SKIRT, F_LONG_NARROW_SKIRT, F_RAGGED_SKIRT, F_TATTERED_SKIRT, F_SHORT_SKIRT, F_SASHED_SKIRT, F_FITTED_SKIRT, F_TORN_TROUSERS, F_LONG_SKIRT, F_TURN_UPS, F_FLARES, F_FLARES, F_PLAIN_TROUSERS, F_SHORTS) + +private val COINS = Item(995,1000) + +@Initializable +class ThessaliaInterface : ComponentPlugin(){ + enum class colorType{ + TORSO, + ARMS, + LEGS + } + + override fun open(player: Player?, component: Component?) { + super.open(player, component) + component ?: return + player?.toggleWardrobe(true) + player?.setAttribute("orig-torso",player.appearance.torso.look) + player?.setAttribute("orig-torso-color",player.appearance.torso.color) + player?.setAttribute("orig-arms",player.appearance.arms.look) + player?.setAttribute("orig-arms-color",player.appearance.arms.color) + player?.setAttribute("orig-legs",player.appearance.legs.look) + player?.setAttribute("orig-legs-color",player.appearance.legs.color) + player?.packetDispatch?.sendPlayerOnInterface(component.id, PLAYER_MODEL_CHILD_ID) + + + component.setCloseEvent{pl,_ -> + pl?.toggleWardrobe(false) + pl.attributes.remove("thes-type") + playJingle(pl, 266) + if(!pl.getAttribute("thes-paid",false)){ + pl.appearance.torso.changeLook(pl.getAttribute("orig-torso",0)) + pl.appearance.torso.changeColor(pl.getAttribute("orig-torso-color",0)) + pl.appearance.arms.changeLook(pl.getAttribute("orig-arms",0)) + pl.appearance.arms.changeColor(pl.getAttribute("orig-arms-color",0)) + pl.appearance.legs.changeLook(pl.getAttribute("orig-legs",0)) + pl.appearance.legs.changeColor(pl.getAttribute("orig-legs-color",0)) + pl.appearance.sync() + } + pl.removeAttribute("thes-paid") + true + } + } + override fun handle(player: Player?, component: Component?, opcode: Int, button: Int, slot: Int, itemId: Int): Boolean { + player ?: return false + when(button){ + 181,180,297 -> pay(player) + else -> when(component?.id){ + THESSALIA_MALE_COMPONENT -> { + when(button){ + 182 -> player.setAttribute("thes-type", colorType.TORSO) + 183 -> player.setAttribute("thes-type", colorType.ARMS) + 184 -> player.setAttribute("thes-type", colorType.LEGS) + } + if(maleArmsButtonRange.contains(button)) updateArms(player,button,true) + if(maleTorsoButtonRange.contains(button)) updateTop(player,button,true) + if(maleLegsButtonRange.contains(button)) updateLegs(player,button,true) + if(maleColorButtonRange.contains(button)) updateColor(player,button,true,player.getAttribute("thes-type", colorType.TORSO)) + } + THESSALIA_FEMALE_COMPONENT -> { + when(button){ + 183 -> player.setAttribute("thes-type", colorType.TORSO) + 184 -> player.setAttribute("thes-type", colorType.ARMS) + 185 -> player.setAttribute("thes-type", colorType.LEGS) + } + if(femaleArmsButtonRange.contains(button)) updateArms(player,button,false) + if(femaleTorsoButtonRange.contains(button)) updateTop(player,button,false) + if(femaleLegsButtonRange.contains(button)) updateLegs(player,button,false) + if(femaleColorButtonRange.contains(button)) updateColor(player,button,false,player.getAttribute("thes-type", colorType.TORSO)) + } + } + } + return true + } + + fun pay(player: Player){ + if(player.inventory.containsItem(COINS)){ + player.inventory.remove(COINS) + player.setAttribute("thes-paid",true) + player.interfaceManager.close() + } else { + player.dialogueInterpreter.sendDialogue("You can not afford that.") + } + } + + fun updateTop(player: Player,button: Int,male: Boolean){ + val usedArray = if(male) maleTorsoIDs else femaleTopIDs + val subtractor = if(male) maleTorsoButtonRange.first else femaleTorsoButtonRange.first + player.appearance.torso.changeLook(usedArray[button - subtractor]) + player.appearance.sync() + } + + fun updateLegs(player: Player, button: Int, male: Boolean){ + val usedArray = if(male) maleLegIDs else femaleLegIDs + val subtractor = if(male) maleLegsButtonRange.first else femaleLegsButtonRange.first + player.appearance.legs.changeLook(usedArray[button - subtractor]) + player.appearance.sync() + } + + fun updateArms(player: Player, button: Int, male: Boolean){ + val usedArray = if(male) maleSleeveIDs else femaleArmIDs + val subtractor = if(male) maleArmsButtonRange.first else femaleArmsButtonRange.first + player.appearance.arms.changeLook(usedArray[button - subtractor]) + player.appearance.sync() + } + + fun updateColor(player: Player, button: Int, male: Boolean, type: colorType){ + val subtractor = if(male) maleColorButtonRange.first else femaleColorButtonRange.first + when(type){ + colorType.ARMS -> player.appearance.torso.changeColor(torsoColors[button - subtractor]) + colorType.LEGS -> player.appearance.legs.changeColor(legColors[button - subtractor]) + colorType.TORSO -> player.appearance.torso.changeColor(torsoColors[button - subtractor]) + } + player.appearance.sync() + } + + override fun newInstance(arg: Any?): Plugin { + ComponentDefinition.put(THESSALIA_MALE_COMPONENT,this) + ComponentDefinition.put(THESSALIA_FEMALE_COMPONENT,this) + return this + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/iface/TradeInterfacePlugin.java b/Server/src/main/content/global/handlers/iface/TradeInterfacePlugin.java new file mode 100644 index 0000000..1d35687 --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/TradeInterfacePlugin.java @@ -0,0 +1,123 @@ +package content.global.handlers.iface; + +import static core.api.ContentAPIKt.*; +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.RunScript; +import core.game.node.entity.player.link.request.trade.TradeModule; +import core.plugin.Initializable; +import core.plugin.Plugin; +import kotlin.Unit; + +/** + * Represents the interface plugin used to handle all trade related functions. + * @author 'Vexia + */ +@Initializable +public final class TradeInterfacePlugin extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.put(334, this); + ComponentDefinition.put(335, this); + ComponentDefinition.put(336, this); + return this; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, final int slot, int itemId) { + final TradeModule module = TradeModule.getExtension(player); + if (module == null) { + return true; + } + switch (component.getId()) { + case 334:// second accept screen + switch (button) { + case 20:// acept + module.setAccepted(true, true); + break; + case 21:// decline + module.decline(); + break; + } + break; + case 335:// main accept interface + switch (opcode) { + case 155: + switch (button) { + case 16:// accept + module.setAccepted(true, true); + break; + case 18:// decline + module.decline(); + break; + case 30:// withdraw one + module.getContainer().withdraw(slot, 1); + break; + } + break; + case 196: + module.getContainer().withdraw(slot, 5); + break; + case 124: + module.getContainer().withdraw(slot, 10); + break; + case 199: + module.getContainer().withdraw(slot, module.getContainer().getAmount(module.getContainer().get(slot))); + break; + case 234: + sendInputDialogue(player, false, "Enter the amount:", (value) -> { + String s = value.toString(); + s = s.replace("k","000"); + s = s.replace("K","000"); + s = s.replace("m","000000"); + s = s.replace("M","000000"); + int val = Integer.parseInt(s); + module.getContainer().withdraw(slot, val); + return Unit.INSTANCE; + }); + break; + case 9:// examine. + if (TradeModule.getExtension(button == 32 ? module.getTarget() : player) == null) { + return true; + } + player.getPacketDispatch().sendMessage(TradeModule.getExtension(button == 32 ? module.getTarget() : player).getContainer().get(slot).getDefinition().getExamine()); + break; + } + break; + case 336:// overlay interface + switch (opcode) { + case 155: + module.getContainer().offer(slot, 1); + break; + case 196: + module.getContainer().offer(slot, 5); + break; + case 124: + module.getContainer().offer(slot, 10); + break; + case 199: + module.getContainer().offer(slot, player.getInventory().getAmount(player.getInventory().get(slot))); + break; + case 234: + sendInputDialogue(player, false, "Enter the amount:", (value) -> { + String s = value.toString(); + s = s.replace("k","000"); + s = s.replace("K","000"); + int val = Integer.parseInt(s); + module.getContainer().offer(slot, val); + return Unit.INSTANCE; + }); + break; + case 9: + player.getPacketDispatch().sendMessage(player.getInventory().get(slot).getDefinition().getExamine()); + break; + } + break; + } + return true; + } + +} diff --git a/Server/src/main/content/global/handlers/iface/WorldMapInterface.java b/Server/src/main/content/global/handlers/iface/WorldMapInterface.java new file mode 100644 index 0000000..113c28b --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/WorldMapInterface.java @@ -0,0 +1,39 @@ +package content.global.handlers.iface; + +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Handles the world map interface. + * @author Emperor + * + */ +@Initializable +public final class WorldMapInterface extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.forId(755).setPlugin(this); + return this; + } + + //Thanks snicker! + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + switch (button) { + case 3: + player.getInterfaceManager().openWindowsPane(new Component(player.getInterfaceManager().isResizable() ? 746 : 548), 2); + player.getPacketDispatch().sendRunScript(1187, "ii", 0, 0); + player.updateSceneGraph(true); + return true; + default: + //log(this.getClass(), Log.ERR, "World map: buttonid: " + button + ", opcode: " + opcode + ", slot: " + slot); + return true; + } + } + +} diff --git a/Server/src/main/content/global/handlers/iface/bank/BankChargeInterface.kt b/Server/src/main/content/global/handlers/iface/bank/BankChargeInterface.kt new file mode 100644 index 0000000..cdf582f --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/bank/BankChargeInterface.kt @@ -0,0 +1,98 @@ +package content.global.handlers.iface.bank + +import core.api.* +import core.game.component.Component +import core.game.node.entity.player.Player +import core.game.node.item.Item +import org.rs09.consts.Components +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import core.game.interaction.InterfaceListener + +/** + * Handles bank charge interface for Eniola at ZMI altar. + * @author vddCore + */ +class BankChargeInterface : InterfaceListener { + companion object { + private const val BUTTON_AIR_RUNE = 28 + private const val BUTTON_MIND_RUNE = 29 + private const val BUTTON_WATER_RUNE = 30 + private const val BUTTON_EARTH_RUNE = 31 + private const val BUTTON_FIRE_RUNE = 32 + private const val BUTTON_BODY_RUNE = 33 + private const val BUTTON_COSMIC_RUNE = 34 + private const val BUTTON_CHAOS_RUNE = 35 + private const val BUTTON_ASTRAL_RUNE = 36 + private const val BUTTON_LAW_RUNE = 37 + private const val BUTTON_DEATH_RUNE = 38 + private const val BUTTON_BLOOD_RUNE = 39 + private const val BUTTON_NATURE_RUNE = 40 + private const val BUTTON_SOUL_RUNE = 41 + + private val RUNE_BUTTONS = intArrayOf( + BUTTON_AIR_RUNE, BUTTON_MIND_RUNE, BUTTON_WATER_RUNE, BUTTON_EARTH_RUNE, + BUTTON_FIRE_RUNE, BUTTON_BODY_RUNE, BUTTON_COSMIC_RUNE, BUTTON_CHAOS_RUNE, + BUTTON_ASTRAL_RUNE, BUTTON_LAW_RUNE, BUTTON_DEATH_RUNE, BUTTON_BLOOD_RUNE, + BUTTON_NATURE_RUNE, BUTTON_SOUL_RUNE + ) + + private val BUTTON_TO_RUNE = hashMapOf( + BUTTON_AIR_RUNE to Items.AIR_RUNE_556, + BUTTON_MIND_RUNE to Items.MIND_RUNE_558, + BUTTON_WATER_RUNE to Items.WATER_RUNE_555, + BUTTON_EARTH_RUNE to Items.EARTH_RUNE_557, + BUTTON_FIRE_RUNE to Items.FIRE_RUNE_554, + BUTTON_BODY_RUNE to Items.BODY_RUNE_559, + BUTTON_COSMIC_RUNE to Items.COSMIC_RUNE_564, + BUTTON_CHAOS_RUNE to Items.CHAOS_RUNE_562, + BUTTON_ASTRAL_RUNE to Items.ASTRAL_RUNE_9075, + BUTTON_LAW_RUNE to Items.LAW_RUNE_563, + BUTTON_DEATH_RUNE to Items.DEATH_RUNE_560, + BUTTON_BLOOD_RUNE to Items.BLOOD_RUNE_565, + BUTTON_NATURE_RUNE to Items.NATURE_RUNE_561, + BUTTON_SOUL_RUNE to Items.SOUL_RUNE_566 + ) + } + + private fun handleButtonClick( + player: Player, + component: Component, + opcode: Int, + buttonID: Int, + slot: Int, + itemID: Int + ): Boolean { + if (buttonID !in RUNE_BUTTONS) return true + + val runeItemId = BUTTON_TO_RUNE[buttonID] + + runeItemId?.let { + if (amountInInventory(player, it) < 20) { + sendNPCDialogue( + player, + NPCs.ENIOLA_6362, + "I'm afraid you don't have the necessary runes with you at this time, so " + + "I can't allow you to access your account. Please bring 20 runes of one type " + + "and you'll be able to open your bank.", + core.game.dialogue.FacialExpression.NEUTRAL + ) + + return true + } + + if (removeItem(player, Item(it, 20))) { + when (getAttribute(player, "zmi:bankaction", "")) { + "open" -> openBankAccount(player) + "collect" -> openGrandExchangeCollectionBox(player) + } + } + } + + return true + } + + override fun defineInterfaceListeners() { + on(Components.BANK_CHARGE_ZMI_619, ::handleButtonClick) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/iface/bank/BankDepositBoxInterface.kt b/Server/src/main/content/global/handlers/iface/bank/BankDepositBoxInterface.kt new file mode 100644 index 0000000..e190a8d --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/bank/BankDepositBoxInterface.kt @@ -0,0 +1,76 @@ +package content.global.handlers.iface.bank + +import core.api.animate +import core.api.dumpBeastOfBurden +import core.api.runWorldTask +import core.api.sendMessage +import core.game.component.Component +import core.game.node.entity.player.Player +import org.rs09.consts.Animations +import org.rs09.consts.Components +import core.game.interaction.InterfaceListener + +/** + * Allows the user to interact with the + * Bank Deposit Box interface + * + * @author vddCore + */ +class BankDepositBoxInterface : InterfaceListener { + companion object { + private const val BUTTON_DEPOSIT_BOB = 13 + + private const val MENU_ELEMENT = 11 + private const val OP_AMOUNT_ONE = 155 + private const val OP_AMOUNT_FIVE = 196 + private const val OP_AMOUNT_TEN = 124 + private const val OP_AMOUNT_ALL = 199 + private const val OP_AMOUNT_X = 234 + private const val OP_EXAMINE = 168 + } + + private fun handleDepositBoxMenu(player: Player, component: Component, opcode: Int, buttonID: Int, slot: Int, itemID: Int): Boolean { + val item = player.inventory.get(slot) + ?: return true + + if (opcode == OP_EXAMINE) { + sendMessage(player, item.definition.examine) + return true + } + + runWorldTask { + when (opcode) { + OP_AMOUNT_ONE -> player.bank.addItem(slot, 1) + OP_AMOUNT_FIVE -> player.bank.addItem(slot, 5) + OP_AMOUNT_TEN -> player.bank.addItem(slot, 10) + OP_AMOUNT_X -> BankUtils.transferX( + player, + slot, + false, + // Needs to have a callback here because the depositing moment is independent from the world task. + player.bank::refreshDepositBoxInterface + ) + OP_AMOUNT_ALL -> player.bank.addItem( + slot, + player.inventory.getAmount(item) + ) + else -> player.debug("Unknown deposit box menu opcode $opcode") + } + + player.bank.refreshDepositBoxInterface() + animate(player, Animations.HUMAN_BANK_DEPOSIT_BOX_834) + } + + return true + } + + override fun defineInterfaceListeners() { + on(Components.BANK_DEPOSIT_BOX_11, ::handleDepositBoxMenu) + on( + Components.BANK_DEPOSIT_BOX_11, + BUTTON_DEPOSIT_BOB + ) { player, _, _, _, _, _ -> + dumpBeastOfBurden(player); true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/iface/bank/BankInterface.kt b/Server/src/main/content/global/handlers/iface/bank/BankInterface.kt new file mode 100644 index 0000000..d6d0bd1 --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/bank/BankInterface.kt @@ -0,0 +1,198 @@ +package content.global.handlers.iface.bank + +import content.global.dialogue.BankDepositDialogue +import content.global.dialogue.BankHelpDialogue +import core.ServerConstants +import core.api.* +import core.game.component.Component +import core.game.container.Container +import core.game.interaction.InterfaceListener +import core.game.node.entity.player.Player +import org.rs09.consts.Components +import org.rs09.consts.Items + +/** + * Allows the user to interact with the Bank Interface. + * + * @author vddCore + */ +class BankInterface : InterfaceListener { + companion object { + private const val MAIN_BUTTON_CLOSE = 10 + private const val MAIN_BUTTON_INSERT_MODE = 14 + private const val MAIN_BUTTON_NOTE_MODE = 16 + private const val MAIN_BUTTON_BOB_DEPOSIT = 18 + private const val MAIN_BUTTON_SEARCH_BANK = 20 + private const val MAIN_BUTTON_HELP = 23 + + private const val MENU_ELEMENT = 73 + private const val OP_AMOUNT_ONE = 155 + private const val OP_AMOUNT_FIVE = 196 + private const val OP_AMOUNT_TEN = 124 + private const val OP_AMOUNT_LAST_X = 199 + private const val OP_AMOUNT_X = 234 + private const val OP_AMOUNT_ALL = 168 + private const val OP_AMOUNT_ALL_BUT_ONE = 166 + private const val OP_EXAMINE = 9 + + private const val BANK_TAB_1 = 41 + private const val BANK_TAB_2 = 39 + private const val BANK_TAB_3 = 37 + private const val BANK_TAB_4 = 35 + private const val BANK_TAB_5 = 33 + private const val BANK_TAB_6 = 31 + private const val BANK_TAB_7 = 29 + private const val BANK_TAB_8 = 27 + private const val BANK_TAB_9 = 25 + + private val BANK_TABS = intArrayOf( + BANK_TAB_1, BANK_TAB_2, BANK_TAB_3, + BANK_TAB_4, BANK_TAB_5, BANK_TAB_6, + BANK_TAB_7, BANK_TAB_8, BANK_TAB_9 + ) + + private const val OP_SET_TAB = 155 + private const val OP_COLLAPSE_TAB = 196 + + private const val THRESHOLD_TO_DISPLAY_EXACT_QUANTITY_ON_EXAMINE = 100000 + } + + private fun onBankInterfaceOpen(player: Player, component: Component): Boolean { + val settings = IfaceSettingsBuilder() + .enableAllOptions() + .enableSlotSwitch() + .setInterfaceEventsDepth(2) + .build() + + player.packetDispatch.sendIfaceSettings( + settings, + 73, + Components.BANK_V2_MAIN_762, + 0, + ServerConstants.BANK_SIZE + ) + + resetSearch(player) + return false + } + + private fun handleTabInteraction(player: Player, component: Component, opcode: Int, buttonID: Int, slot: Int, itemID: Int): Boolean { + resetSearch(player) + val clickedTabIndex = -((buttonID - 41) / 2) + + when (opcode) { + OP_SET_TAB -> { + if (player.bank.tabIndex != clickedTabIndex) { + player.bank.tabIndex = clickedTabIndex + } + } + + OP_COLLAPSE_TAB -> { + player.bank.collapseTab(clickedTabIndex) + } + } + + return true + } + + private fun handleBankMenu(player: Player, component: Component, opcode: Int, buttonID: Int, slot: Int, itemID: Int): Boolean { + val item = player.bank.get(slot) + ?: return true + resetSearch(player) + + when (opcode) { + OP_AMOUNT_ONE -> player.bank.takeItem(slot, 1) + OP_AMOUNT_FIVE -> player.bank.takeItem(slot, 5) + OP_AMOUNT_TEN -> player.bank.takeItem(slot, 10) + OP_AMOUNT_LAST_X -> player.bank.takeItem(slot, player.bank.lastAmountX) + OP_AMOUNT_X -> BankUtils.transferX(player, slot, true) + OP_AMOUNT_ALL -> player.bank.takeItem(slot, player.bank.getAmount(item)) + OP_AMOUNT_ALL_BUT_ONE -> player.bank.takeItem(slot, player.bank.getAmount(item) - 1) + OP_EXAMINE -> { + var examineText = item.definition.examine + val id = item.definition.id + val bank = player.bank + if (isCoinOverrideNeeded(id, bank)) { + examineText = "" + bank.getAmount(id) + " x " + item.definition.name + "." + } + sendMessage(player, examineText) + } + else -> player.debug("Unknown bank menu opcode $opcode") + } + + return true + } + + private fun handleInventoryMenu(player: Player, component: Component, opcode: Int, buttonID: Int, slot: Int, itemID: Int): Boolean { + val item = player.inventory.get(slot) + ?: return true + resetSearch(player) + + when (opcode) { + OP_AMOUNT_ONE -> player.bank.addItem(slot, 1) + OP_AMOUNT_FIVE -> player.bank.addItem(slot, 5) + OP_AMOUNT_TEN -> player.bank.addItem(slot, 10) + OP_AMOUNT_LAST_X -> player.bank.addItem(slot, player.bank.lastAmountX) + OP_AMOUNT_X -> BankUtils.transferX(player, slot, false) + OP_AMOUNT_ALL -> player.bank.addItem(slot, player.inventory.getAmount(item)) + OP_EXAMINE -> { + var examineText = item.definition.examine + val id = item.definition.id + val inventory = player.inventory + if (isCoinOverrideNeeded(id, inventory)) { + examineText = "" + inventory.getAmount(id) + " x " + item.definition.name + "." + } + sendMessage(player, examineText) + } + else -> player.debug("Unknown inventory menu opcode $opcode") + } + + return true + } + + override fun defineInterfaceListeners() { + onOpen(Components.BANK_V2_MAIN_762, ::onBankInterfaceOpen) + + on(Components.BANK_V2_MAIN_762) { player, component, opcode, buttonID, slot, itemID -> + when (buttonID) { + MAIN_BUTTON_HELP -> openDialogue(player, BankHelpDialogue()) + MAIN_BUTTON_BOB_DEPOSIT -> openDialogue(player, BankDepositDialogue()) + MAIN_BUTTON_INSERT_MODE -> player.bank.isInsertItems = !player.bank.isInsertItems + MAIN_BUTTON_NOTE_MODE -> player.bank.isNoteItems = !player.bank.isNoteItems + MAIN_BUTTON_SEARCH_BANK -> setAttribute(player, "search", true) + MENU_ELEMENT -> handleBankMenu(player, component, opcode, buttonID, slot, itemID) + in BANK_TABS -> handleTabInteraction(player, component, opcode, buttonID, slot, itemID) + } + + return@on true + } + + on(Components.BANK_V2_HELP_767) { player, component, opcode, buttonID, slot, itemID -> + when (buttonID) { + MAIN_BUTTON_CLOSE -> openBankAccount(player) + } + + return@on true + } + + on(Components.BANK_V2_SIDE_763, ::handleInventoryMenu) + } + + private fun isCoinOverrideNeeded(id: Int, container: Container): Boolean { + val amount = container.getAmount(id) + + // Only COINS_995 are obtainable and bankable by player + if (id == Items.COINS_995 && amount >= THRESHOLD_TO_DISPLAY_EXACT_QUANTITY_ON_EXAMINE) { + return true + } + + return false + } + + private fun resetSearch (player: Player) + { + val lastTab = getAttribute(player, "bank:lasttab", 0) + player.bank.tabIndex = lastTab + setVarc(player, 190, 1) //re-enable "Search" right-click option on search button. + } +} diff --git a/Server/src/main/content/global/handlers/iface/bank/BankPinInterface.java b/Server/src/main/content/global/handlers/iface/bank/BankPinInterface.java new file mode 100644 index 0000000..7c70b88 --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/bank/BankPinInterface.java @@ -0,0 +1,69 @@ +package content.global.handlers.iface.bank; + +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.BankPinManager; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Handles the bank pin interfaces. + * @author Vexia + */ +@Initializable +public class BankPinInterface extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.forId(13).setPlugin(this); + ComponentDefinition.forId(14).setPlugin(this); + return this; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + BankPinManager manager = player.getBankPinManager(); + switch (component.getId()) { + case 14:// setting + switch (button) { + case 60: + case 62: + if (!manager.hasPin()) { + manager.toggleConfirmInterface(button == 60); + } else { + manager.setChangingState(1); + manager.openPin(); + } + break; + case 63: + manager.toggleConfirmInterface(true); + break; + case 65: + manager.cancelPin("The PIN has been cancelled", "and will NOT be set.", "", "You still do not have a Bank", "PIN."); + break; + case 89: + case 91: + manager.handleConfirmInterface(button); + break; + case 61: + case 64: + manager.switchRecovery(); + break; + } + break; + case 13:// pin + switch (button) { + case 30: + break; + default: + player.getBankPinManager().updateTempPin(button - 1); + break; + } + break; + } + return true; + } + +} diff --git a/Server/src/main/content/global/handlers/iface/bank/BankUtils.kt b/Server/src/main/content/global/handlers/iface/bank/BankUtils.kt new file mode 100644 index 0000000..2a056fe --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/bank/BankUtils.kt @@ -0,0 +1,22 @@ +package content.global.handlers.iface.bank + +import core.api.InputType +import core.api.sendInputDialogue +import core.game.node.entity.player.Player + +object BankUtils { + fun transferX(player: Player, slot: Int, withdraw: Boolean, after: (() -> Unit)? = null) { + sendInputDialogue(player, InputType.AMOUNT, "Enter the amount:") { value -> + val number = Integer.parseInt(value.toString()) + + if (withdraw) { + player.bank.takeItem(slot, number) + } else { + player.bank.addItem(slot, number) + } + + player.bank.updateLastAmountX(number) + after?.let { it() } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/iface/ge/ExchangeItemSets.kt b/Server/src/main/content/global/handlers/iface/ge/ExchangeItemSets.kt new file mode 100644 index 0000000..8547bf3 --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/ge/ExchangeItemSets.kt @@ -0,0 +1,79 @@ +package content.global.handlers.iface.ge + +import core.api.getAttribute +import core.api.openInterface +import core.api.setAttribute +import core.game.component.Component +import core.game.container.Container +import core.game.container.ContainerEvent +import core.game.container.ContainerListener +import core.game.container.access.InterfaceContainer +import core.game.ge.GEItemSet +import core.game.node.entity.player.Player +import org.rs09.consts.Components +import core.game.interaction.InterfaceListener + +class ExchangeItemSets : InterfaceListener { + override fun defineInterfaceListeners() { + onClose(Components.EXCHANGE_ITEMSETS_645){player, _ -> + val listener = getAttribute(player, "ge-listener", null) + player.inventory.listeners.remove(listener) + player.interfaceManager.closeSingleTab() + player.removeAttribute("container-key") + player.removeAttribute("ge-listener") + return@onClose true + } + } + + companion object { + @JvmStatic + fun openFor(player: Player) + { + openInterface(player, Components.EXCHANGE_ITEMSETS_645) + player.interfaceManager.openSingleTab(Component(Components.EXCHANGE_SETS_SIDE_644)) + val listener: InventoryListener + setAttribute(player, "ge-listener", InventoryListener(player).also { listener = it }) + player.inventory.listeners.add(listener) + } + } + + private class InventoryListener(val player: Player) : ContainerListener { + init { + createContainers(player) + } + + override fun update(c: Container?, event: ContainerEvent?) + { + createContainers(player) + } + + override fun refresh(c: Container?) { + createContainers(player) + } + + private fun createContainers(player: Player) + { + setAttribute(player, "container-key", + InterfaceContainer.generateItems( + player, + player.inventory.toArray(), + arrayOf("Examine", "Exchange", "Components"), + Components.EXCHANGE_SETS_SIDE_644, + 0, + 7, + 4 + ) + ) + + InterfaceContainer.generateItems( + player, + GEItemSet.getItemArray(), + arrayOf("Examine", "Exchange", "Components"), + Components.EXCHANGE_ITEMSETS_645, + 16, + 15, + 10 + ) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/iface/ge/GrandExchangeInterface.java b/Server/src/main/content/global/handlers/iface/ge/GrandExchangeInterface.java new file mode 100644 index 0000000..9b615b3 --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/ge/GrandExchangeInterface.java @@ -0,0 +1,230 @@ +package content.global.handlers.iface.ge; + +import core.cache.def.impl.CS2Mapping; +import core.cache.def.impl.ItemDefinition; +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.ge.GEGuidePrice; +import core.game.ge.GEItemSet; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.net.packet.PacketRepository; +import core.net.packet.context.ContainerContext; +import core.net.packet.out.ContainerPacket; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.game.ge.GrandExchangeOffer; +import core.game.ge.GrandExchangeRecords; +import core.game.world.GameWorld; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playAudio; + +/** + * Handles the Grand Exchange interface options. + * @author Emperor + * @version 1.0 + */ +@Initializable +public class GrandExchangeInterface extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + //ComponentDefinition.put(105, this); // Main interface + //ComponentDefinition.put(107, this); // Selling tab + ComponentDefinition.put(109, this); // Collection interface + ComponentDefinition.put(389, this); // Search interface + ComponentDefinition.put(644, this); // Item sets inventory interface + ComponentDefinition.put(645, this); // Item sets interface + ComponentDefinition.put(642, this); // Guide Prices interface. + return this; + } + + @Override + public boolean handle(final Player player, final Component component, final int opcode, final int button, final int slot, final int itemId) { + GameWorld.getPulser().submit(new Pulse(1, player) { + @Override + public boolean pulse() { + switch (component.getId()) { + case 644: + case 645: + handleItemSet(player, component, opcode, button, slot, itemId); + return true; + case 389: + handleSearchInterface(player, opcode, button, slot, itemId); + return true; + case 109: + handleCollectionBox(player, opcode, button, slot, itemId); + return true; + case 642: + handleGuidePrice(player, opcode, button, slot, itemId); + return true; + } + return true; + } + }); + return true; + } + + /** + * Handles the search interface options. + * @param player The player. + * @param opcode The packet opcode. + * @param button The button id. + * @param slot The slot. + * @param itemId The item id. + * @return {@code true} if the option got handled. + */ + public boolean handleSearchInterface(final Player player, int opcode, int button, int slot, int itemId) { + switch (button) { + case 10: + player.getInterfaceManager().closeChatbox(); + return true; + } + return false; + } + + /** + * Handles the selling tab interface options. + * @param player The player. + * @param opcode The packet opcode. + * @param button The button id. + * @param slot The slot. + * @param itemId The item id. + * @return {@code true} if the option got handled. + */ + public boolean handleCollectionBox(final Player player, int opcode, int button, int slot, int itemId) { + int index = -1; + switch (button) { + case 18: + case 23: + case 28: + index = (button - 18) >> 2; + break; + case 36: + case 44: + case 52: + index = 3 + ((button - 36) >> 3); + break; + } + GrandExchangeOffer offer; + GrandExchangeRecords records = GrandExchangeRecords.getInstance(player); + if (index > -1 && (offer = records.getOffer(records.getOfferRecords()[index])) != null) { + StockMarket.withdraw(player, offer, slot >> 1, opcode); + } + return true; + } + + /** + * Handles the item set. + * @param player The player. + * @param opcode The opcode. + * @param button The button. + * @param slot The slot. + * @param itemId The item id. + */ + private void handleItemSet(Player player, Component component, int opcode, int button, int slot, int itemId) { + if (button != 16 && button != 0) { + return; + } + boolean inventory = component.getId() == 644; + if (slot < 0 || slot >= (inventory ? 28 : GEItemSet.values().length)) { + return; + } + + Item item; + GEItemSet set; + if (inventory) { + item = player.getInventory().get(slot); + if (item == null) return; + set = GEItemSet.forId(item.getId()); + if (set == null) return; + } else { + set = GEItemSet.values()[slot]; + item = new Item(set.getItemId()); + } + + if (opcode != 127 && inventory && set == null) { + player.getPacketDispatch().sendMessage("This isn't a set item."); + return; + } + switch (opcode) { + case 124: + player.getPacketDispatch().sendMessage(item.getDefinition().getExamine()); + break; + case 196: + if (inventory) { + if (player.getInventory().freeSlots() < set.getComponents().length - 1) { + player.getPacketDispatch().sendMessage("You don't have enough inventory space for the component parts."); + return; + } + if (!player.getInventory().remove(item, false)) { + return; + } + for (int id : set.getComponents()) { + player.getInventory().add(new Item(id, 1)); + } + player.getInventory().refresh(); + player.getPacketDispatch().sendMessage("You successfully traded your set for its component items!"); + } else { + if (!player.getInventory().containItems(set.getComponents())) { + player.getPacketDispatch().sendMessage("You don't have the parts that make up this set."); + break; + } + for (int id : set.getComponents()) { + player.getInventory().remove(new Item(id, 1), false); + } + player.getInventory().add(item); + player.getInventory().refresh(); + player.getPacketDispatch().sendMessage("You successfully traded your item components for a set!"); + } + playAudio(player, Sounds.GE_TRADE_OK_4044); + PacketRepository.send(ContainerPacket.class, new ContainerContext(player, -1, -2, player.getAttribute("container-key", 93), player.getInventory(), false)); + break; + case 155: + CS2Mapping mapping = CS2Mapping.forId(1089); + if (mapping != null && set != null) { + player.getPacketDispatch().sendMessage((String) mapping.getMap().get(set.getItemId())); + } + break; + } + } + + /*** + * Method used to handle the guide price opcode. + * @param player the player. + * @param opcode the opcode. + * @param buttonId the buttonId. + * @param slot the slot. + * @param itemId the itemId. + */ + private void handleGuidePrice(final Player player, final int opcode, final int buttonId, final int slot, final int itemId) { + switch (opcode) { + case 155: + GEGuidePrice.GuideType type = player.getAttribute("guide-price", null); + if (type == null) { + return; + } + int subtract = 0; + if (buttonId >= 15 && buttonId <= 23) { + subtract = 15; + } + if (buttonId >= 43 && buttonId <= 57) { + subtract = 43; + } + if (buttonId >= 89 && buttonId <= 103) { + subtract = 89; + } + if (buttonId >= 135 && buttonId <= 144) { + subtract = 135; + } + if (buttonId >= 167 && buttonId <= 182) { + subtract = 167; + } + player.getPacketDispatch().sendMessage(ItemDefinition.forId(type.getItems()[buttonId - subtract].getItem()).getExamine()); + break; + } + } +} diff --git a/Server/src/main/content/global/handlers/iface/ge/StockMarket.kt b/Server/src/main/content/global/handlers/iface/ge/StockMarket.kt new file mode 100644 index 0000000..eba0a24 --- /dev/null +++ b/Server/src/main/content/global/handlers/iface/ge/StockMarket.kt @@ -0,0 +1,412 @@ +package content.global.handlers.iface.ge + +import core.api.* +import core.game.component.Component +import core.game.ge.OfferState +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.net.packet.PacketRepository +import core.net.packet.context.ConfigContext +import core.net.packet.context.ContainerContext +import core.net.packet.out.Config +import core.net.packet.out.ContainerPacket +import org.rs09.consts.Components +import core.game.ge.GrandExchange +import core.game.ge.GrandExchangeOffer +import core.game.ge.GrandExchangeRecords +import core.game.ge.PriceIndex +import core.game.interaction.InterfaceListener +import core.tools.Log +import core.tools.SystemLogger +import org.rs09.consts.Sounds +import kotlin.math.min + +/** + * Handles the grand exchange interface (Stock Market) + * @author Ceikry + */ +class StockMarket : InterfaceListener { + override fun defineInterfaceListeners() { + onOpen(Components.STOCKMARKET_105){player, _ -> + player.packetDispatch.sendInterfaceConfig(105, 193, true) + player.packetDispatch.sendIfaceSettings(6, 211, 105, -1, -1) + player.packetDispatch.sendIfaceSettings(6, 209, 105, -1, -1) + setVarp(player, 1112, -1) + return@onOpen true + } + + onClose(Components.STOCKMARKET_105){player, _ -> + player.packetDispatch.sendRunScript(571, "") + player.interfaceManager.closeChatbox() + player.interfaceManager.closeSingleTab() + } + + onOpen(Components.OBJDIALOG_389){player, _ -> + player.packetDispatch.sendRunScript(570, "s", "Grand Exchange Item Search") + return@onOpen true + } + + onClose(Components.OBJDIALOG_389){player, _ -> + player.packetDispatch.sendRunScript(5781, "") + return@onClose true + } + + on(Components.STOCKSIDE_107){ player, _, op, button, slot, _ -> + if (button != 18 || slot < 0 || slot > 27) { + return@on false + } + val item = player.inventory[slot] ?: return@on false + when (op) { + 196 -> player.packetDispatch.sendMessage(item.definition.examine) + 155 -> { + val offer = getAttribute(player, "ge-temp", GrandExchangeOffer()) + val index = getAttribute(player, "ge-index", -1) + if(item.id == 995) + { + sendMessage(player, "You can't sell money!") + return@on true + } + var id = item.id + if(!item.definition.isUnnoted) + id = item.noteChange + if(!PriceIndex.canTrade(id)) + { + sendMessage(player, "This item can't be sold on the Grand Exchange.") + return@on true + } + offer.itemID = id + offer.sell = true + offer.player = player + offer.offeredValue = GrandExchange.getRecommendedPrice(id) + offer.amount = item.amount + offer.index = index + updateVarbits(player, offer, index, true) + setAttribute(player, "ge-temp", offer) + player.packetDispatch.sendString(GrandExchange.getOfferStats(id, true), 105, 142) + } + } + return@on true + } + + on(Components.STOCKMARKET_105){player, _, op, button, _, _ -> + val tempOffer = getAttribute(player, "ge-temp", GrandExchangeOffer()) + var openedIndex = getAttribute(player, "ge-index", -1) + var openedOffer = GrandExchangeRecords.getInstance(player).getOffer(openedIndex) + + when(button) + { + 209,211 -> if (openedOffer == null){ + SystemLogger.logGE("[WARN] Player tried to withdraw item with null openedOffer!") + return@on false + } else withdraw(player, openedOffer, (button - 209) shr 1, op) + 190 -> confirmOffer(player, tempOffer, openedIndex).also { return@on true } + 194 -> player.interfaceManager.openChatbox(Components.OBJDIALOG_389) + 203 -> abortOffer(player, openedOffer) + 18,34,50,69,88,107 -> { + openedIndex = (button - 18) shr 4 + openedOffer = GrandExchangeRecords.getInstance(player).getOffer(openedIndex) + if(op == 205) abortOffer(player, openedOffer) + else updateVarbits(player, openedOffer, openedIndex) + if(openedOffer != null) { + player.packetDispatch.sendString(GrandExchange.getOfferStats(openedOffer.itemID, openedOffer.sell), 105, 142) + } + } + 30,46,62,81,100,119 -> { + openedIndex = (button - 30) shr 4 + openedOffer = GrandExchangeRecords.getInstance(player).getOffer(openedIndex) + updateVarbits(player, openedOffer, openedIndex) + player.interfaceManager.openChatbox(Components.OBJDIALOG_389) + } + 31,47,63,82,101,120 -> { + openedIndex = (button - 31) shr 4 + openedOffer = GrandExchangeRecords.getInstance(player).getOffer(openedIndex) + updateVarbits(player, openedOffer, openedIndex, true) + player.interfaceManager.openSingleTab(Component(Components.STOCKSIDE_107)).open(player) + player.packetDispatch.sendRunScript( + 149, "IviiiIsssss", "", "", "", "Examine", "Offer", + -1, 0, 7, 4, 93, 7012370 + ) + val settings = IfaceSettingsBuilder().enableOptions(0, 1).build() + player.packetDispatch.sendIfaceSettings(settings, 18, 107, 0, 27) + } + 157 -> updateOfferAmount(player, tempOffer, tempOffer.amount - 1) + 159 -> updateOfferAmount(player, tempOffer, tempOffer.amount + 1) + 162 -> updateOfferAmount(player, tempOffer, if(tempOffer.sell) 1 else tempOffer.amount + 1) + 164 -> updateOfferAmount(player, tempOffer, if(tempOffer.sell) 10 else tempOffer.amount + 10) + 166 -> updateOfferAmount(player, tempOffer, if(tempOffer.sell) 100 else tempOffer.amount + 100) + 168 -> { + val amt = + if(tempOffer.sell) + getInventoryAmount(player, tempOffer.itemID) + else + tempOffer.amount + 1000 + + updateOfferAmount(player, tempOffer, amt) + } + 170 -> sendInputDialogue(player, false, "Enter the amount:") { value -> + if (player.interfaceManager.chatbox.id == 389) { + player.interfaceManager.openChatbox(Components.OBJDIALOG_389) + } + var s = value.toString() + s = s.replace("k", "000") + s = s.replace("K", "000") + s = s.replace("m", "000000") + s = s.replace("M", "000000") + updateOfferAmount(player, tempOffer, s.toInt()) + setAttribute(player, "ge-temp", tempOffer) + } + 180 -> updateOfferValue(player, tempOffer, GrandExchange.getRecommendedPrice(tempOffer.itemID)) + 177 -> updateOfferValue(player, tempOffer, (GrandExchange.getRecommendedPrice(tempOffer.itemID) * 0.95).toInt()) + 183 -> updateOfferValue(player, tempOffer, (GrandExchange.getRecommendedPrice(tempOffer.itemID) * 1.05).toInt()) + 171 -> updateOfferValue(player, tempOffer, tempOffer.offeredValue - 1) + 173 -> updateOfferValue(player, tempOffer, tempOffer.offeredValue + 1) + 185 -> sendInputDialogue(player, InputType.AMOUNT, "Enter the amount:"){value -> + if (player.interfaceManager.chatbox.id == 389) { + player.interfaceManager.openChatbox(Components.OBJDIALOG_389) + } + var s = value.toString() + updateOfferValue(player, tempOffer, s.toInt()) + setAttribute(player, "ge-temp", tempOffer) + } + 195 -> closeInterface(player) + 127 -> { + player.interfaceManager.closeSingleTab() + player.interfaceManager.closeChatbox() + } + } + + setAttribute(player, "ge-index", openedIndex) + setAttribute(player, "ge-temp", tempOffer) + return@on true + } + } + + fun updateOfferValue(player: Player, offer: GrandExchangeOffer, newAmt: Int) + { + offer.offeredValue = newAmt + setVarp(player, 1111, newAmt) + } + + fun updateOfferAmount(player: Player, offer: GrandExchangeOffer, newAmt: Int) + { + offer.amount = newAmt + setVarp(player, 1110, newAmt) + } + + fun abortOffer(player: Player, offer: GrandExchangeOffer?) + { + if(offer == null) + { + log(this::class.java, Log.WARN, "Opened offer was null and was attempted to be aborted!") + return + } + sendMessage(player, "Abort request acknowledged. Please be aware that your offer may") + sendMessage(player, "have already been completed.") + + if(!offer.isActive) + { + log(this::class.java, Log.WARN, "Offer ${offer.uid}[${offer.index}]: ${if(offer.sell) "s" else "b"} ${offer.itemID}x ${offer.amount} was NO LONGER active when abort attempted") + return + } + offer.offerState = OfferState.ABORTED + if(offer.sell) + offer.addWithdrawItem(offer.itemID, offer.amountLeft) + else + offer.addWithdrawItem(995, offer.amountLeft * offer.offeredValue) + offer.update() + offer.visualize(player) + } + + enum class OfferConfirmResult { + Success, + ZeroCoins, + TooManyCoins, + NotEnoughItemsOrCoins, + ItemRemovalFailure, + OfferPlacementError + } + + fun confirmOffer(player: Player, offer: GrandExchangeOffer, index: Int) : OfferConfirmResult + { + if(offer.offeredValue < 1) + { + playAudio(player, Sounds.GE_TRADE_ERROR_4039) + sendMessage(player, "You can't make an offer for 0 coins.") + return OfferConfirmResult.ZeroCoins + } + if(offer.amount > Int.MAX_VALUE / offer.offeredValue) + { + playAudio(player, Sounds.GE_TRADE_ERROR_4039) + sendMessage(player, "You can't ${if(offer.sell) "sell" else "buy"} this much!") + return OfferConfirmResult.TooManyCoins + } + offer.index = index + if(offer.sell) + { + val maxAmt = getInventoryAmount(player, offer.itemID) + if(offer.amount > maxAmt) + { + playAudio(player, Sounds.GE_TRADE_ERROR_4039) + sendMessage(player, "You do not have enough of this item in your inventory to cover the") + sendMessage(player, "offer.") + return OfferConfirmResult.NotEnoughItemsOrCoins + } + val amountUnnoted = min(amountInInventory(player, offer.itemID), offer.amount) + val amountLeft = offer.amount - amountUnnoted + val removedUnnoted = if (amountUnnoted > 0) removeItem(player, Item(offer.itemID, amountUnnoted)) else true + val removeNoted = if (amountLeft > 0) removeItem(player, Item(itemDefinition(offer.itemID).noteId, amountLeft)) else true + if (!removedUnnoted || !removeNoted) return OfferConfirmResult.ItemRemovalFailure + if(GrandExchange.dispatch(player, offer)) + { + player.removeAttribute("ge-temp") + } + else + { + if (amountUnnoted > 0) + addItem(player, offer.itemID, offer.amount - amountLeft) + if (amountLeft > 0) + addItem(player, itemDefinition(offer.itemID).noteId, amountLeft) + sendMessage(player, "Unable to place GE offer. Please try again.") + return OfferConfirmResult.OfferPlacementError + } + } + else + { + val total = offer.amount * offer.offeredValue + if(!inInventory(player, 995, total)) + { + playAudio(player, Sounds.GE_TRADE_ERROR_4039) + sendMessage(player, "You do not have enough coins to cover the offer.") + return OfferConfirmResult.NotEnoughItemsOrCoins + } + if(GrandExchange.dispatch(player, offer) && removeItem(player, Item(995, total))) + { + player.removeAttribute("ge-temp") + } + } + playAudio(player, Sounds.GE_PLACE_ITEM_4043) + offer.visualize(player) + toMainInterface(player) + return OfferConfirmResult.Success + } + + fun getInventoryAmount(player: Player, itemId: Int): Int { + val item = Item(itemId) + var amount = player.inventory.getAmount(item) + if (item.definition.noteId > -1) { + amount += player.inventory.getAmount(Item(item.definition.noteId)) + } + return amount + } + + companion object { + @JvmStatic + fun openFor(player: Player) + { + if(player.ironmanManager.checkRestriction()) + return + if(!player.bankPinManager.isUnlocked) + { + player.bankPinManager.openType(4) + return + } + + openInterface(player, Components.STOCKMARKET_105) + } + + @JvmStatic + fun updateVarbits(player: Player, offer: GrandExchangeOffer?, index: Int, sale: Boolean? = null) + { + val isSale = sale ?: offer?.sell ?: false + var lowPrice = 0 + var highPrice = 0 + val recommendedPrice = GrandExchange.getRecommendedPrice(offer?.itemID ?: 0) + if (PriceIndex.canTrade(offer?.itemID ?: 0)) { + lowPrice = (recommendedPrice * 0.95).toInt() + highPrice = (recommendedPrice * 1.05).toInt() + } + setVarp(player, 1109, offer?.itemID ?: -1) + setVarp(player, 1110, offer?.amount ?: 0) + setVarp(player, 1111, offer?.offeredValue ?: 0) + setVarp(player, 1112, index) + setVarp(player, 1113, if (isSale) 1 else 0) + setVarp(player, 1114, recommendedPrice) + setVarp(player, 1115, lowPrice) + setVarp(player, 1116, highPrice) + if (offer != null) { + PacketRepository.send( + ContainerPacket::class.java, + ContainerContext(player, -1, -1757, 523 + offer.index, offer.withdraw, false) + ) + } + } + + @JvmStatic + fun withdraw(player: Player, offer: GrandExchangeOffer, index: Int, op: Int) + { + val item = offer.withdraw[index] + if(item == null) + { + log(this::class.java, Log.WARN, "Offer withdraw[$index] is null!") + return + } + + when (op) { + // withdraw notes + 155 -> { + val note = item.noteChange + if (note == -1) { + sendMessage(player, "This item cannot be noted") + return + } + if (hasSpaceFor(player, Item(note, item.amount))) { + addItem(player, note, item.amount) + } else { + playAudio(player, Sounds.GE_TRADE_ERROR_4039) + sendMessage(player, "You do not have enough room in your inventory.") + return + } + } + // withdraw items + 196 -> { + if (hasSpaceFor(player, item)) { + addItem(player, item.id, item.amount) + } else { + playAudio(player, Sounds.GE_TRADE_ERROR_4039) + sendMessage(player, "You do not have enough room in your inventory.") + return + } + } + } + + offer.withdraw[index] = null + if (!offer.isActive && offer.withdraw[0] == null && offer.withdraw[1] == null) + { + offer.offerState = OfferState.REMOVED + if(offer.completedAmount > 0) + { + val newHistory = arrayOfNulls(5) + newHistory[0] = offer + System.arraycopy(GrandExchangeRecords.getInstance(player).history, 0, newHistory, 1, 4) + GrandExchangeRecords.getInstance(player).history = newHistory + } + GrandExchangeRecords.getInstance(player).offerRecords[offer.index] = null + toMainInterface(player) + } + offer.update() + offer.visualize(player) + } + + /** + * Returns to the main interface. + */ + fun toMainInterface(player: Player) { + PacketRepository.send(Config::class.java, ConfigContext(player, 1112, -1)) + PacketRepository.send(Config::class.java, ConfigContext(player, 1112, -1)) + player.interfaceManager.closeChatbox() + player.interfaceManager.closeSingleTab() + player.setAttribute("ge-index", -1) + } + + } +} diff --git a/Server/src/main/content/global/handlers/item/BirdNestPlugin.java b/Server/src/main/content/global/handlers/item/BirdNestPlugin.java new file mode 100644 index 0000000..5499ba6 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/BirdNestPlugin.java @@ -0,0 +1,36 @@ +package content.global.handlers.item; + +import content.data.tables.BirdNest; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Handles the searching of a bird nest item. + * @author Vexia + */ +public final class BirdNestPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (BirdNest nest : BirdNest.values()) { + nest.getNest().getDefinition().getHandlers().put("option:search", this); + } + return null; + } + + @Override + public boolean handle(Player player, Node node, String option) { + final Item item = (Item) node; + BirdNest.forNest(item).search(player, item); + return true; + } + + @Override + public boolean isWalk() { + return false; + } +} diff --git a/Server/src/main/content/global/handlers/item/BirdNestScript.kt b/Server/src/main/content/global/handlers/item/BirdNestScript.kt new file mode 100644 index 0000000..fb34fb6 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/BirdNestScript.kt @@ -0,0 +1,22 @@ +package content.global.handlers.item + +import content.data.tables.BirdNest +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.Node +import core.game.node.entity.player.Player +import core.game.node.item.Item + +class BirdNestScript : InteractionListener { + val nestIds = BirdNest.values().map { it.nest.id }.toIntArray() + + override fun defineListeners() { + on(nestIds, IntType.ITEM, "search", handler = ::handleNest) + } + + private fun handleNest(player: Player, node: Node) : Boolean { + val nest = BirdNest.forNest(node as? Item ?: return false) + nest.search(player, node as? Item ?: return false) + return true + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/BraceletOfClayPlugin.kt b/Server/src/main/content/global/handlers/item/BraceletOfClayPlugin.kt new file mode 100644 index 0000000..26fd230 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/BraceletOfClayPlugin.kt @@ -0,0 +1,24 @@ +package content.global.handlers.item + +import core.api.* +import org.rs09.consts.Items +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +/** + * Handles the bracelet of clay operate option. + * @author Ceikry + */ +class BraceletOfClayPlugin : InteractionListener { + + override fun defineListeners() { + + on(Items.BRACELET_OF_CLAY_11074, IntType.ITEM, "operate"){ player, node -> + var charge = getCharge(node) + if (charge > 28) setCharge(node, 28).also { charge = 28 } + sendMessage(player, "You have $charge uses left.") + return@on true + } + + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/CadavaPotionListener.kt b/Server/src/main/content/global/handlers/item/CadavaPotionListener.kt new file mode 100644 index 0000000..35c3fa4 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/CadavaPotionListener.kt @@ -0,0 +1,26 @@ +package rs09.game.interaction.`object` + +import core.api.sendItemDialogue +import org.rs09.consts.Items +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +/** + * @author bushtail + */ + +class CadavaPotionListener : InteractionListener { + + var POTION = Items.CADAVA_POTION_756 + + override fun defineListeners() { + on(POTION, IntType.ITEM, "drink") { player, node -> + sendItemDialogue(player, POTION, "You dare not drink.") + return@on true + } + on(POTION, IntType.ITEM, "look-at") { player, node -> + sendItemDialogue(player, POTION, "This looks very colourful.") + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/CasketListener.kt b/Server/src/main/content/global/handlers/item/CasketListener.kt new file mode 100644 index 0000000..78d7d99 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/CasketListener.kt @@ -0,0 +1,43 @@ +package content.global.handlers.item + +import core.api.* +import core.api.utils.WeightBasedTable +import core.api.utils.WeightedItem +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.item.Item +import core.tools.StringUtils +import org.rs09.consts.Items +import java.util.* +import kotlin.collections.ArrayList + +class CasketListener : InteractionListener { + companion object { + val loot = WeightBasedTable.create( + WeightedItem(Items.COINS_995, 20, 640, 55.0, false), + WeightedItem(Items.UNCUT_SAPPHIRE_1623, 1, 1, 32.0, false), + WeightedItem(Items.UNCUT_EMERALD_1621, 1, 1, 16.0, false), + WeightedItem(Items.UNCUT_RUBY_1619, 1, 1, 9.0, false), + WeightedItem(Items.UNCUT_DIAMOND_1617, 1, 1, 2.0, false), + WeightedItem(Items.COSMIC_TALISMAN_1454, 1, 1, 8.0, false), + WeightedItem(Items.LOOP_HALF_OF_A_KEY_987, 1, 1, 1.0, false), + WeightedItem(Items.TOOTH_HALF_OF_A_KEY_985, 1, 1, 1.0, false) + ) + } + + override fun defineListeners() { + on(Items.CASKET_405, IntType.ITEM, "open"){ player, node -> + val casket = node.asItem() + + if(removeItem(player, casket, Container.INVENTORY)) { + val finalLoot : ArrayList = loot.roll() + finalLoot.forEach { player.inventory.add(it) } + player.dialogueInterpreter.sendItemMessage(finalLoot[0], + "You open the casket. Inside you find " + + (if (finalLoot[0].amount > 1) "some" else if (StringUtils.isPlusN(finalLoot[0].name)) "an" else "a") + + " " + finalLoot[0].name.lowercase(Locale.getDefault()) + ".") + } + return@on true + } + } +} diff --git a/Server/src/main/content/global/handlers/item/ConsumableListener.kt b/Server/src/main/content/global/handlers/item/ConsumableListener.kt new file mode 100644 index 0000000..e1da664 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/ConsumableListener.kt @@ -0,0 +1,51 @@ +package content.global.handlers.item + +import content.data.consumables.Consumables +import core.api.delayAttack +import core.api.getUsedOption +import core.api.getWorldTicks +import core.api.stopExecuting +import core.game.interaction.Clocks +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.Node +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.world.GameWorld + +class ConsumableListener : InteractionListener { + override fun defineListeners() { + on(IntType.ITEM, "eat", "drink", handler = ::handleConsumable) + } + + private fun handleConsumable(player: Player, node: Node) : Boolean { + val consumable = Consumables.getConsumableById(node.id) ?: return true + + val food = getUsedOption(player) == "eat" + val isIgnoreMainClock = consumable.isIgnoreMainClock + + if (food) { + if (isIgnoreMainClock && player.clocks[Clocks.NEXT_CONSUME] < GameWorld.ticks) { + consumable.consumable.consume(node as? Item ?: return true, player) + player.clocks[Clocks.NEXT_CONSUME] = getWorldTicks() + 2 + player.clocks[Clocks.NEXT_EAT] = getWorldTicks() + 2 + delayAttack(player, 3) + } else if (player.clocks[Clocks.NEXT_CONSUME] < getWorldTicks() && player.clocks[Clocks.NEXT_EAT] < getWorldTicks()) { + consumable.consumable.consume(node as? Item ?: return true, player) + player.clocks[Clocks.NEXT_EAT] = getWorldTicks() + 2 + delayAttack(player, 3) + } + } else { + if (isIgnoreMainClock && player.clocks[Clocks.NEXT_CONSUME] < getWorldTicks()) { + consumable.consumable.consume(node as? Item ?: return true, player) + player.clocks[Clocks.NEXT_CONSUME] = getWorldTicks() + 1 + player.clocks[Clocks.NEXT_DRINK] = getWorldTicks() + 1 + } else if (player.clocks[Clocks.NEXT_CONSUME] < getWorldTicks() && player.clocks[Clocks.NEXT_DRINK] < getWorldTicks()) { + consumable.consumable.consume(node as? Item ?: return true, player) + player.clocks[Clocks.NEXT_DRINK] = getWorldTicks() + 1 + } + } + + return true + } +} diff --git a/Server/src/main/content/global/handlers/item/ConsumableOptionPlugin.java b/Server/src/main/content/global/handlers/item/ConsumableOptionPlugin.java new file mode 100644 index 0000000..3b74cd8 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/ConsumableOptionPlugin.java @@ -0,0 +1,66 @@ +package content.global.handlers.item; + +import core.cache.def.impl.ItemDefinition; +import core.game.consumable.Consumable; +import content.data.consumables.Consumables; +import core.game.consumable.Potion; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the plugin used to consume a consumable item. + * @author 'Vexia + * @author Emperor + * @version 1.0 + */ +public final class ConsumableOptionPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ItemDefinition.setOptionHandler("eat", this); + ItemDefinition.setOptionHandler("drink", this); + return this; + } + + /** + * The last item that was recently eaten. + * Used for Karambwan "1-ticking" + */ + int lastEaten = -1; + + @Override + public boolean handle(final Player player, final Node node, final String option) { +/* if (player.getLocks().isLocked(option)) { + return true; + } + boolean food = option.equals("eat"); + if(node.asItem().getId() != 3144 || (node.asItem().getId() == 3144 && lastEaten == 3144)){ + player.getLocks().lock(option, 3); + } + if (!food) { + player.getLocks().lock("eat", 2); + } + Item item = (Item) node; + if (player.getInventory().get(item.getSlot()) != item) { + return false; + } + Consumable consumable = Consumables.getConsumableById(item.getId()); + if (consumable instanceof Potion) { + consumable.consume((Item) node, player); + return true; + } + if (consumable == null) { + return false; + } + consumable.consume(((Item) node), player); + if (food) { + player.getProperties().getCombatPulse().delayNextAttack(3); + } + lastEaten = node.asItem().getId();*/ + return true; + } +} diff --git a/Server/src/main/content/global/handlers/item/DragonfireShieldListener.kt b/Server/src/main/content/global/handlers/item/DragonfireShieldListener.kt new file mode 100644 index 0000000..c195a6f --- /dev/null +++ b/Server/src/main/content/global/handlers/item/DragonfireShieldListener.kt @@ -0,0 +1,147 @@ +package content.global.handlers.item + +import content.global.handlers.item.equipment.special.DragonfireSwingHandler +import core.ServerConstants +import core.api.* +import core.game.container.impl.EquipmentContainer +import core.game.global.action.DropListener +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.combat.CombatPulse.Companion.swing +import core.game.node.entity.combat.InteractionType +import core.game.node.entity.combat.equipment.SwitchAttack +import core.game.node.entity.impl.Projectile +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.node.item.ItemPlugin +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import core.plugin.Initializable +import core.plugin.Plugin +import core.tools.minutesToTicks +import core.tools.secondsToTicks +import org.rs09.consts.Items +import org.rs09.consts.Sounds + +/** + * Handles the dragonfire shield options. + */ + +class DragonfireShieldListener: InteractionListener { + + val dragonfireShields = intArrayOf(Items.DRAGONFIRE_SHIELD_11283, Items.DRAGONFIRE_SHIELD_11284) + val dfsEmptyAnim = 6700 + val dfsEmptyGfx = 1160 + val dfsRecharge = if (ServerConstants.BETTER_DFS) secondsToTicks(30) else minutesToTicks(2) + + override fun defineListeners() { + + on(dragonfireShields, IntType.ITEM, "operate") { player, node -> + val usingAttack = !getAttribute(player, "dfs_spec", false) + if (!usingAttack) { + if (!player.settings.isSpecialToggled) { + setVarp(player, 301, 0) + } + player.removeAttribute("dfs_spec") + player.properties.combatPulse.temporaryHandler = null + return@on true + } + val notCharged = node.asItem().id == Items.DRAGONFIRE_SHIELD_11284 || node.asItem().charge < 20 + if (notCharged) { + sendMessage(player, "Your shield has no charges left.") + return@on true + } + if (player.locks.isLocked("dfs_recharge")) { + sendMessage(player, "Your dragonfire shield is recharging.") + return@on true + } + setVarp(player, 301, 1) + player.setAttribute("dfs_spec", true) + val attack = SwitchAttack(null, Animation.create(6696), Graphics.create(1165), Graphics(1167, 96), Projectile.create(player, null, 1166, 36, 36, 80, 70, 0, 11)) + val handler: DragonfireSwingHandler = object : DragonfireSwingHandler(false, 25, attack, true) { + override fun swing(entity: Entity?, victim: Entity?, state: BattleState?): Int { + if (entity is Player) { + if (!player.settings.isSpecialToggled) { + setVarp(player, 301, 0) + } + removeAttribute(player, "dfs_spec") + val shield = player.equipment[EquipmentContainer.SLOT_SHIELD] + if (shield == null || shield.id != Items.DRAGONFIRE_SHIELD_11283) { + return -1 + } + playGlobalAudio(entity.getLocation(), Sounds.DRAGONSLAYER_SHIELDFIRE_3761) + delayEntity(player, 3) + shield.charge -= 20 + if (shield.charge < 20 && node.asItem().slot == EquipmentContainer.SLOT_SHIELD) { + replaceSlot(player, node.asItem().slot, Item(Items.DRAGONFIRE_SHIELD_11284), Item(Items.DRAGONFIRE_SHIELD_11283), Container.EQUIPMENT) + } + EquipmentContainer.updateBonuses(player) + player.locks.lock("dfs_recharge", dfsRecharge) + } + return super.swing(entity, victim, state) + } + + override fun visualizeImpact(entity: Entity?, victim: Entity?, state: BattleState?) { + playGlobalAudio(victim!!.location, Sounds.FIRESTRIKE_HIT_161, 20) + super.visualizeImpact(entity, victim, state) + } + } + attack.handler = handler + val victim = player.properties.combatPulse.getVictim() + if (player.properties.combatPulse.isAttacking && handler.canSwing(player, victim!!) == InteractionType.STILL_INTERACT) { + swing(player, victim, handler) + return@on true + } + player.properties.combatPulse.temporaryHandler = handler + return@on true + } + + on(dragonfireShields, IntType.ITEM, "empty") { player, node -> + replaceSlot(player, node.asItem().slot, Item(Items.DRAGONFIRE_SHIELD_11284), Item(Items.DRAGONFIRE_SHIELD_11283)) + visualize(player, dfsEmptyAnim, dfsEmptyGfx) + sendMessage(player, "You release the charges.") + playGlobalAudio(player.location, Sounds.DRAGONSLAYER_SHIELD_EMPTY_3760) + return@on true + } + + on(dragonfireShields, IntType.ITEM, "inspect") { player, node -> + if (node.asItem().id == Items.DRAGONFIRE_SHIELD_11284) { + sendMessage(player, "The shield has no charges.") + return@on true + } + sendMessage(player, "The shield has " + node.asItem().charge / 20 + " charges.") + return@on true + } + + on(dragonfireShields, IntType.ITEM, "drop") { player, node -> + var shield = node.asItem() + val slot = shield.slot + if (shield.id == Items.DRAGONFIRE_SHIELD_11283) { + replaceSlot(player, shield.slot, Item(Items.DRAGONFIRE_SHIELD_11284), Item(Items.DRAGONFIRE_SHIELD_11283)) + shield = player.inventory.get(slot) + } + DropListener.drop(player, shield) + return@on true + } + } +} + +/** + * Drops the uncharged dragonfire shield item id on death. + */ + +@Initializable +class DFSItemPlugin : ItemPlugin() { + + @Throws(Throwable::class) + override fun newInstance(arg: Any?): Plugin { + register(Items.DRAGONFIRE_SHIELD_11283) + return this + } + + override fun getDeathItem(item: Item?): Item { + return Item(Items.DRAGONFIRE_SHIELD_11284) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/DrinkBlamishOilListener.kt b/Server/src/main/content/global/handlers/item/DrinkBlamishOilListener.kt new file mode 100644 index 0000000..0e6c423 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/DrinkBlamishOilListener.kt @@ -0,0 +1,16 @@ +package content.global.handlers.item + +import core.api.* +import org.rs09.consts.Items +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +class DrinkBlamishOilListener : InteractionListener { + + override fun defineListeners() { + on(Items.BLAMISH_OIL_1582, IntType.ITEM, "drink"){ player, _ -> + sendPlayerDialogue(player, "You know... I'd really rather not.") + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/EctophialListener.kt b/Server/src/main/content/global/handlers/item/EctophialListener.kt new file mode 100644 index 0000000..111db96 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/EctophialListener.kt @@ -0,0 +1,75 @@ +package content.global.handlers.item + +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.TeleportManager.TeleportType +import core.game.node.item.Item +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import org.rs09.consts.Items +import org.rs09.consts.Scenery +import org.rs09.consts.Sounds +import content.data.Quests + +@Suppress("unused") +class EctophialListener : InteractionListener { + private val fillAnimation = Animation(832) + private val emptyAnimation = Animation(9609) + private val emptyGraphics = Graphics(1688) + + private fun refillEctophial(player: Player) { + delayEntity(player, fillAnimation.duration) + animate(player, fillAnimation) + playAudio(player, Sounds.FILL_ECTOPLASM_1132) + if (removeItem(player, Items.ECTOPHIAL_4252)) { + addItem(player, Items.ECTOPHIAL_4251) + sendMessage(player, "You refill the ectophial from the Ectofuntus.") + } + } + + override fun defineListeners() { + onUseWith(IntType.SCENERY, Items.ECTOPHIAL_4252, Scenery.ECTOFUNTUS_5282) { player, _, _ -> + refillEctophial(player) + return@onUseWith true + } + + on(Items.ECTOPHIAL_4251, IntType.ITEM, "empty") { player, node -> + if (!hasRequirement(player, Quests.GHOSTS_AHOY)) + return@on true + + if (player.isTeleBlocked) { + sendMessage(player, "A magical force has stopped you from teleporting.") + return@on true + } + delayEntity(player, 10) + closeAllInterfaces(player) + queueScript(player, 0, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + sendMessage(player, "You empty the ectoplasm onto the ground around your feet...") + playAudio(player, 4580) + visualize(player, emptyAnimation, emptyGraphics) + replaceSlot(player, node.asItem().slot, Item(Items.ECTOPHIAL_4252), Item(Items.ECTOPHIAL_4251)) + return@queueScript delayScript(player, emptyAnimation.duration) + } + 1 -> { + teleport(player, Location.create(3658, 3517, 0), TeleportType.ECTOPHIAL) + sendMessage(player, "...and the world changes around you.") + return@queueScript delayScript(player, 9) + } + 2 -> { + face(player, Location(3659, 3519, 0)) + refillEctophial(player) + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + return@on true + } + } +} diff --git a/Server/src/main/content/global/handlers/item/EmptyOptionListener.kt b/Server/src/main/content/global/handlers/item/EmptyOptionListener.kt new file mode 100644 index 0000000..12771ec --- /dev/null +++ b/Server/src/main/content/global/handlers/item/EmptyOptionListener.kt @@ -0,0 +1,91 @@ +package content.global.handlers.item + +import core.api.* +import core.cache.def.impl.ItemDefinition +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.item.Item +import org.rs09.consts.Items +import org.rs09.consts.Sounds +import java.util.* + +/** + * Handles items with "empty" options + */ +class EmptyOptionListener : InteractionListener { + + override fun defineListeners() { + + on(EmptyItem.emptyItemList.toIntArray(), IntType.ITEM, "empty", "empty bowl", "empty dish") { player, node -> + if (node.name.contains("brew") || node.name.contains("potion") || node.name.lowercase(Locale.getDefault()).contains("poison") || node.name.lowercase(Locale.getDefault()).contains("serum") || node.name.contains("cure") || node.name.contains("mix") || node.name.contains("balm")) { + replaceSlot(player, node.asItem().slot, Item(EmptyItem.getEmpty(Items.POTION_195)!!), node.asItem()) + playAudio(player, EmptyItem.getEmptyAudio(Items.POTION_195)!!) + return@on true + } + if (EmptyItem.emptyItemMap[node.id] != null) { + replaceSlot(player, node.asItem().slot, Item(EmptyItem.getEmpty(node.id)!!), node.asItem()) + if (EmptyItem.getEmptyAudio(node.id) != -1) playAudio(player, EmptyItem.getEmptyAudio(node.id)!!) + EmptyItem.getEmptyMessage(node.id)?.let { sendMessage(player, it) } + } + return@on true + } + } + + enum class EmptyItem(var fullId: Int, var emptyId: Int, var emptyMessage: String, var audioId: Int = -1) { + POT_OF_FLOUR(Items.POT_OF_FLOUR_1933, Items.EMPTY_POT_1931, "You empty the contents of the pot onto the floor."), + POT_OF_CORNFLOUR(Items.POT_OF_CORNFLOUR_7468, Items.EMPTY_POT_1931, "You empty the contents of the pot onto the floor."), + BONE_MEAL(Items.BONEMEAL_4255, Items.EMPTY_POT_1931, "You empty the pot of crushed bones."), + BUCKET_OF_SAND(Items.BUCKET_OF_SAND_1783, Items.BUCKET_1925, "You empty the contents of the bucket onto the floor.", Sounds.SAND_BUCKET_2584), + BUCKET_OF_MILK(Items.BUCKET_OF_MILK_1927, Items.BUCKET_1925, "You empty the contents of the bucket onto the floor.", Sounds.LIQUID_2401), + BUCKET_OF_WATER(Items.BUCKET_OF_WATER_1929, Items.BUCKET_1925, "You empty the contents of the bucket on the floor.", Sounds.LIQUID_2401), + BUCKET_OF_COMPOST(Items.COMPOST_6032, Items.BUCKET_1925, "You empty the bucket of compost."), + BUCKET_OF_SUPERCOMPOST(Items.SUPERCOMPOST_6034, Items.BUCKET_1925, "You empty the bucket of supercompost."), + BUCKET_OF_SLIME(Items.BUCKET_OF_SLIME_4286, Items.BUCKET_1925, "You empty the contents of the bucket on the floor.", Sounds.LIQUID_2401), + VIAL_OF_WATER(Items.VIAL_OF_WATER_227, Items.VIAL_229, "You empty the vial.", Sounds.LIQUID_2401), + BOWL_OF_WATER(Items.BOWL_OF_WATER_1921, Items.BOWL_1923, "You empty the contents of the bowl onto the floor.", Sounds.LIQUID_2401), + JUG_OF_WATER(Items.JUG_OF_WATER_1937, Items.JUG_1935, "You empty the contents of the jug onto the floor.", Sounds.LIQUID_2401), + BURNT_PIE(Items.BURNT_PIE_2329, Items.PIE_DISH_2313, "You empty the pie dish."), + POTION(Items.POTION_195, Items.VIAL_229, "You empty the vial.", Sounds.LIQUID_2401), + BURNT_STEW(Items.BURNT_STEW_2005, Items.BOWL_1923, "You empty the contents of the bowl onto the floor.", Sounds.LIQUID_2401), + NETTLE_TEA(Items.NETTLE_TEA_4239, Items.BOWL_1923, "You empty the contents of the bowl onto the floor.", Sounds.LIQUID_2401), + NETTLE_WATER(Items.NETTLE_WATER_4237, Items.BOWL_1923, "You empty the contents of the bowl onto the floor.", Sounds.LIQUID_2401), + NETTLE_TEA_MILKY(Items.NETTLE_TEA_4240, Items.BOWL_1923, "You empty the contents of the bowl onto the floor.", Sounds.LIQUID_2401), + BURNT_CURRY(Items.BURNT_CURRY_2013, Items.BOWL_1923, "You empty the contents of the bowl onto the floor.", Sounds.LIQUID_2401), + BURNT_GNOMEBOWL(Items.BURNT_GNOMEBOWL_2175, Items.GNOMEBOWL_MOULD_2166, "You empty the contents of the gnomebowl onto the floor."), + BURNT_EGG(Items.BURNT_EGG_7090, Items.BOWL_1923, "You empty the contents of the bowl onto the floor."), + BURNT_ONION(Items.BURNT_ONION_7092, Items.BOWL_1923, "You empty the contents of the bowl onto the floor."), + BURNT_MUSHROOM(Items.BURNT_MUSHROOM_7094, Items.BOWL_1923, "You empty the contents of the bowl onto the floor."); + + companion object { + var emptyItemMap = HashMap() + var emptyMessageMap = HashMap() + var emptyAudioMap = HashMap() + var emptyItemList = ArrayList() + + init { + for (item in values()) { + emptyItemMap.putIfAbsent(item.fullId, item.emptyId) + emptyMessageMap.putIfAbsent(item.fullId, item.emptyMessage) + emptyAudioMap.putIfAbsent(item.fullId, item.audioId) + emptyItemList.add(item.fullId) + } + for (item in ItemDefinition.getDefinitions().values) + if (item.name.contains("potion") || item.name.contains("brew") || item.name.contains("poison") || item.name.lowercase(Locale.getDefault()).contains("serum") || item.name.contains("cure") || item.name.contains("mix") || item.name.contains("balm")) { + emptyItemList.add(item.id) + } + } + + fun getEmpty(id: Int): Int? { + return emptyItemMap[id] + } + + fun getEmptyMessage(id: Int): String? { + return emptyMessageMap[id] + } + + fun getEmptyAudio(id: Int): Int? { + return emptyAudioMap[id] + } + } + } +} diff --git a/Server/src/main/content/global/handlers/item/EnchantJewelleryTabListener.kt b/Server/src/main/content/global/handlers/item/EnchantJewelleryTabListener.kt new file mode 100644 index 0000000..1a31d30 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/EnchantJewelleryTabListener.kt @@ -0,0 +1,86 @@ +package content.global.handlers.item + +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength +import org.rs09.consts.Items +import org.rs09.consts.Sounds + +class EnchantJewelleryTabListener : InteractionListener { + + private val LVL_1_ENCHANT = mapOf( + Items.SAPPHIRE_RING_1637 to Items.RING_OF_RECOIL_2550, + Items.SAPPHIRE_NECKLACE_1656 to Items.GAMES_NECKLACE8_3853, + Items.SAPPHIRE_AMULET_1694 to Items.AMULET_OF_MAGIC_1727, + Items.SAPPHIRE_BRACELET_11072 to Items.BRACELET_OF_CLAY_11074 + ) + private val LVL_2_ENCHANT = mapOf( + Items.EMERALD_RING_1639 to Items.RING_OF_DUELLING8_2552, + Items.EMERALD_NECKLACE_1658 to Items.BINDING_NECKLACE_5521, + Items.EMERALD_AMULET_1696 to Items.AMULET_OF_DEFENCE_1729, + Items.EMERALD_BRACELET_11076 to Items.CASTLEWAR_BRACE3_11079 + ) + + private val LVL_3_ENCHANT = mapOf( + Items.RUBY_RING_1641 to Items.RING_OF_FORGING_2568, + Items.RUBY_NECKLACE_1660 to Items.DIGSITE_PENDANT_5_11194, + Items.RUBY_AMULET_1698 to Items.AMULET_OF_STRENGTH_1725, + Items.RUBY_BRACELET_11085 to Items.INOCULATION_BRACE_11088 + ) + + private val LVL_4_ENCHANT = mapOf( + Items.DIAMOND_RING_1643 to Items.RING_OF_LIFE_2570, + Items.DIAMOND_NECKLACE_1662 to Items.PHOENIX_NECKLACE_11090, + Items.DIAMOND_AMULET_1700 to Items.AMULET_OF_POWER_1731, + Items.DIAMOND_BRACELET_11092 to Items.FORINTHRY_BRACE5_11095 + ) + + private val LVL_5_ENCHANT = mapOf( + Items.DRAGONSTONE_RING_1645 to Items.RING_OF_WEALTH4_14646, + Items.DRAGON_NECKLACE_1664 to Items.SKILLS_NECKLACE4_11105, + Items.DRAGONSTONE_AMMY_1702 to Items.AMULET_OF_GLORY4_1712, + Items.DRAGON_BRACELET_11115 to Items.COMBAT_BRACELET4_11118 + ) + + private val LVL_6_ENCHANT = mapOf( + Items.ONYX_RING_6575 to Items.RING_OF_STONE_6583, + Items.ONYX_NECKLACE_6577 to Items.BERSERKER_NECKLACE_11128, + Items.ONYX_AMULET_6581 to Items.AMULET_OF_FURY_6585, + Items.ONYX_BRACELET_11130 to Items.REGEN_BRACELET_11133 + ) + + override fun defineListeners() { + on(IntType.ITEM, "break") {player, node -> + closeAllInterfaces(player) + delayEntity(player, 1) + queueScript(player, strength = QueueStrength.SOFT) { + + val items = when (node.id) { + 8016 -> LVL_1_ENCHANT //Sapphire + 8017 -> LVL_2_ENCHANT + 8018 -> LVL_3_ENCHANT + 8019 -> LVL_4_ENCHANT + 8020 -> LVL_5_ENCHANT + 8021 -> LVL_6_ENCHANT + else -> return@queueScript stopExecuting(player) + } + + if (inInventory(player, node.id)) { + for (item in player.inventory.toArray()) { + if (item == null) continue + val product = items[item.id] ?: continue + if (removeItem(player, node.id) && (removeItem(player, item.id))) { + addItem(player, product) + playAudio(player, Sounds.POH_TABLET_BREAK_979) + animate(player, 4069, true) + break + } + } + } + return@queueScript stopExecuting(player) + } + return@on true + } + } +} diff --git a/Server/src/main/content/global/handlers/item/EnchantedGemListener.kt b/Server/src/main/content/global/handlers/item/EnchantedGemListener.kt new file mode 100644 index 0000000..252dbe2 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/EnchantedGemListener.kt @@ -0,0 +1,68 @@ +package content.global.handlers.item + +import content.global.skill.slayer.SlayerUtils +import core.api.* +import content.global.skill.slayer.Tasks +import org.rs09.consts.Items +import core.game.dialogue.DialogueFile +import core.game.dialogue.IfTopic +import core.game.dialogue.Topic +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.tools.END_DIALOGUE + +class EnchantedGemListener : InteractionListener { + override fun defineListeners() { + on(Items.ENCHANTED_GEM_4155, IntType.ITEM, "activate") { player, _ -> + openDialogue(player, EnchantedGemDialogue()) + return@on true + } + } +} + +class EnchantedGemDialogue() : DialogueFile() { + var firstRun = true + override fun handle(interfaceId: Int, buttonId: Int) { + npc = getSlayerMaster(player!!) + when(stage) { + 0 -> npcl(core.game.dialogue.FacialExpression.FRIENDLY, "Hello there ${player!!.username}, what can I help you with?").also { stage++ } + 1 -> showTopics( + Topic(core.game.dialogue.FacialExpression.ASKING, "How am I doing so far?", 100), + Topic(core.game.dialogue.FacialExpression.HALF_ASKING, "Who are you?", 200), + Topic(core.game.dialogue.FacialExpression.HALF_ASKING, "Where are you?", 300), + Topic(core.game.dialogue.FacialExpression.FRIENDLY, "Got any tips for me?", 400), + IfTopic(core.game.dialogue.FacialExpression.FRIENDLY, "Nothing really.", END_DIALOGUE, firstRun), + IfTopic(core.game.dialogue.FacialExpression.HAPPY, "That's all thanks.", END_DIALOGUE, !firstRun) + ) + 100 -> { + firstRun = false + if(!hasSlayerTask(player!!)) { + npcl(core.game.dialogue.FacialExpression.HALF_THINKING, "You need something new to hunt. Come and see me when you can and I'll give you a new task.").also { stage = 1 } + } else { + if(getSlayerTask(player!!) == Tasks.JAD) { + npcl(core.game.dialogue.FacialExpression.FRIENDLY, "You're currently assigned to kill TzTok-Jad!") + } else { + npcl(core.game.dialogue.FacialExpression.FRIENDLY, "You're currently assigned to kill ${SlayerUtils.pluralise( + getSlayerTaskName(player!!))}; only ${getSlayerTaskKillsRemaining(player!!)} more to go.") + } + setVarp(player!!, 2502, getSlayerTaskFlags(player!!) shr 4) + stage = 1 + } + } + 200 -> { + firstRun = false + npcl(core.game.dialogue.FacialExpression.HAPPY, "My name's ${getSlayerMaster(player!!).name}, I'm the Slayer Master best able to train you.").also { stage = 1 } + } + 300 -> { + firstRun = false + npcl(core.game.dialogue.FacialExpression.HAPPY, "You'll find me in ${getSlayerMasterLocation(player!!)}, I'll be here when you need a new task.").also { stage = 1 } + } + 400 -> { + firstRun = false + npc(core.game.dialogue.FacialExpression.FRIENDLY, *getSlayerTip(player!!)) + stage++ + } + 401 -> player(core.game.dialogue.FacialExpression.HAPPY, "Great, thanks!").also { stage = 1 } + } + } +} diff --git a/Server/src/main/content/global/handlers/item/EnchantedJewelleryListener.kt b/Server/src/main/content/global/handlers/item/EnchantedJewelleryListener.kt new file mode 100644 index 0000000..2878628 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/EnchantedJewelleryListener.kt @@ -0,0 +1,68 @@ +package content.global.handlers.item + +import core.api.openDialogue +import core.api.sendMessage +import core.game.node.Node +import core.game.node.entity.impl.PulseType +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.dialogue.DialogueFile +import content.data.EnchantedJewellery +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.tools.START_DIALOGUE +import org.rs09.consts.Items + +/** + * Listener for enchanted jewellery options + * @author Ceikry, downthecrop, Player Name + */ +class EnchantedJewelleryListener : InteractionListener { + + val ids = EnchantedJewellery.idMap.keys.toIntArray() + + override fun defineListeners() { + on(ids, IntType.ITEM, "operate") { player, node -> + handle(player, node, true) + return@on true + } + on(ids, IntType.ITEM, "rub") { player, node -> + handle(player, node, false) + return@on true + } + } + private fun handle(player: Player, node: Node, isEquipped: Boolean) { + player.pulseManager.clear(PulseType.STANDARD) + val item = node.asItem() + if (item.id == Items.RING_OF_LIFE_2570) { + sendMessage(player, "You can't operate that.") + return + } + val jewellery = EnchantedJewellery.idMap[item.id] + if (jewellery != null) { + if (jewellery.isLastItemIndex(jewellery.getItemIndex(item)) && !jewellery.isCrumble) { + sendMessage(player, "The ${jewellery.getJewelleryType(item)} has lost its charge.") + sendMessage(player, "It will need to be recharged before you can use it again.") + return + } + sendMessage(player, "You rub the ${jewellery.getJewelleryType(item)}...") + if (jewellery.options.isEmpty()) { + jewellery.use(player, item, 0, isEquipped) + return + } + openDialogue(player,EnchantedJewelleryDialogueFile(jewellery,item,isEquipped)) + } + } + + class EnchantedJewelleryDialogueFile(val jewellery: EnchantedJewellery, val item: Item, val isEquipped: Boolean) : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + START_DIALOGUE -> { + interpreter!!.sendOptions("Where would you like to go?", *jewellery.options) + stage++ + } + 1 -> end().also { jewellery.use(player!!, item, buttonID - 1, isEquipped) } + } + } + } +} diff --git a/Server/src/main/content/global/handlers/item/ExplorersRingPlugin.kt b/Server/src/main/content/global/handlers/item/ExplorersRingPlugin.kt new file mode 100644 index 0000000..5869675 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/ExplorersRingPlugin.kt @@ -0,0 +1,102 @@ +package content.global.handlers.item + +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.TeleportManager.TeleportType +import core.game.node.entity.skill.Skills +import core.game.world.map.Location +import org.json.simple.JSONObject +import org.rs09.consts.Items +import core.ServerStore +import core.ServerStore.Companion.getInt +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import content.global.skill.magic.modern.ModernListeners + +class ExplorersRingPlugin : InteractionListener { + + val RINGS = intArrayOf(Items.EXPLORERS_RING_1_13560, Items.EXPLORERS_RING_2_13561, Items.EXPLORERS_RING_3_13562) + val CABBAGE_PORT = Location.create(3051, 3291, 0) + + + override fun defineListeners() { + on(RINGS, IntType.ITEM, "run-replenish"){ player, node -> + val charges = getStoreFile().getInt(player.username.toLowerCase() + ":run") + if (charges >= getRingLevel(node.id)) { + sendDialogue(player,"Your ring appears to have no more run energy recharges left for today.") + return@on true + } + if (player.settings.runEnergy == 100.0) { + sendMessage(player, "You are fully rested. You do not need to use the ring's power for the moment.") + return@on true + } + player.settings.updateRunEnergy(-50.0) + playAudio(player, 5035) + + getStoreFile()[player.username.toLowerCase() + ":run"] = charges + 1 + + sendMessage(player,"You feel refreshed as the ring revitalises you and a charge is used up.") + visualize(player, 9988, 1733) + return@on true + } + + //Sources Used + // - https://www.youtube.com/watch?v=PEA0fkRK0-A&t=64s&pp=ygUcMjAwOSBydW5lc2NhcGUgZXhwbG9yZXIgcmluZw%3D%3D + // - https://runescape.wiki/w/Explorer%27s_ring?oldid=899927 + on(RINGS, IntType.ITEM, "low-alchemy"){ player, _ -> + if (!hasLevelStat(player, Skills.MAGIC, 21)) { + sendMessage(player,"You need a Magic level of 21 in order to do that.") + return@on true + } + val remaining = getStoreFile().getInt(player.username.lowercase() + ":alchs", 30) + if (remaining <= 0) { + sendMessage(player, "You have used up all of your charges for the day.") + return@on true + } + sendDialogue(player, "Choose the item that you wish to convert to coins.") + addDialogueAction (player) {_,_ -> + sendItemSelect (player, "Choose") { slot, optionIndex -> + val item = player.inventory[slot] + if (item == null) + return@sendItemSelect + if (!ModernListeners().alchemize(player, item, false, explorersRing = true)) + return@sendItemSelect + getStoreFile()[player.username.lowercase() + ":alchs"] = remaining - 1 + } + } + return@on true + } + + on(RINGS, IntType.ITEM, "cabbage-port"){ player, node -> + teleport(player) + return@on true + } + + on(RINGS, IntType.ITEM, "operate", "rub"){ player, node -> + if(getRingLevel(node.id) < 3){ + sendMessage(player, "This item can not be operated.") + return@on true + } + + teleport(player) + return@on true + } + } + + fun teleport(player: Player){ + teleport(player, CABBAGE_PORT, TeleportType.CABBAGE) + } + + fun getRingLevel(id: Int): Int{ + return when(id){ + Items.EXPLORERS_RING_1_13560 -> 1 + Items.EXPLORERS_RING_2_13561 -> 2 + Items.EXPLORERS_RING_3_13562 -> 3 + else -> -1 + } + } + + fun getStoreFile(): JSONObject{ + return ServerStore.getArchive("daily-explorer-ring") + } +} diff --git a/Server/src/main/content/global/handlers/item/FaladorShieldPlugin.java b/Server/src/main/content/global/handlers/item/FaladorShieldPlugin.java new file mode 100644 index 0000000..4cebc31 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/FaladorShieldPlugin.java @@ -0,0 +1,105 @@ +package content.global.handlers.item; + +import java.util.concurrent.TimeUnit; + +import core.cache.def.impl.ItemDefinition; +import core.game.node.entity.Entity; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import content.data.consumables.effects.PrayerEffect; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Handles the Falador Shields. + * @author afaroutdude + * + */ +@Initializable +public class FaladorShieldPlugin extends OptionHandler { + final static int ANIM_EMOTE = 11012; + final static int[] GFX_EMOTE = {1966,1965,1965}; + final static int[] GFX_PRAYER_RESTORE = {1962,1963,1964}; + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ItemDefinition.forId(14577).getHandlers().put("option:operate",this); + ItemDefinition.forId(14578).getHandlers().put("option:operate",this); + ItemDefinition.forId(14579).getHandlers().put("option:operate",this); + + ItemDefinition.forId(14577).getHandlers().put("option:prayer-restore",this); + ItemDefinition.forId(14578).getHandlers().put("option:prayer-restore",this); + ItemDefinition.forId(14579).getHandlers().put("option:prayer-restore",this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + final Item item = (Item) node; + int level = getLevel(item.getId()); + switch (option) { + case "prayer-restore": + Long attrTime = player.getAttribute("diary:falador:shield-restore-time"); + if (attrTime != null && attrTime > System.currentTimeMillis()) { + player.sendMessage("You have no charges left today."); + } else { + // TODO should ask if sure you with to recharge, see https://www.youtube.com/watch?v=ZW9k1922Ggk interpreter.sendOptions("Are you sure you wish to recharge?"); + final PrayerEffect effect = new PrayerEffect(0, level == 0 ? 0.25 : level == 1 ? 0.5 : 1.0); + effect.activate(player); + player.graphics(new Graphics(GFX_PRAYER_RESTORE[level])); + player.setAttribute("/save:diary:falador:shield-restore-time", System.currentTimeMillis() + TimeUnit.DAYS.toMillis(1)); + player.sendMessage("You restore " + (level < 2 ? "some" : "your") + " prayer points."); + } + return true; + case "operate": + GameWorld.getPulser().submit(getPulse(player, level)); + break; + } + return true; + } + + /** + * Gets the level of the falador shield. + * @param itemId The item id. + * @return The level. + */ + private int getLevel(int itemId) { + switch (itemId) { + case 14577: + return 0; + case 14578: + return 1; + case 14579: + return 2; + } + return -1; + } + + private Pulse getPulse(final Entity entity, final int level) { + return new Pulse(1) { + int delay = 0; + + @Override + public boolean pulse() { + if (delay == 0) { + entity.lock(); + entity.animate(new Animation(ANIM_EMOTE)); + entity.graphics(new Graphics(GFX_EMOTE[level])); + } else if (delay == 3) { + entity.getAnimator().forceAnimation(Animation.RESET); + entity.unlock(); + return true; + } + delay++; + return false; + } + }; + } + +} diff --git a/Server/src/main/content/global/handlers/item/FishbowlPlugin.java b/Server/src/main/content/global/handlers/item/FishbowlPlugin.java new file mode 100644 index 0000000..09cbfb5 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/FishbowlPlugin.java @@ -0,0 +1,296 @@ +package content.global.handlers.item; + +import core.Util; +import core.cache.def.impl.ItemDefinition; +import core.cache.def.impl.SceneryDefinition; +import org.rs09.consts.Items; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.OptionHandler; +import core.game.interaction.UseWithHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.item.Item; +import core.game.node.item.WeightedChanceItem; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.plugin.ClassScanner; +import core.tools.RandomFunction; +import core.game.dialogue.DialogueInterpreter; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.skill.Skills; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.*; + +// Sources: +// https://www.youtube.com/watch?v=xu7Err9YUgw +// https://www.youtube.com/watch?v=7XSVFKnUM9Y&t=683s +// https://2007rshelp.com/misc.php?id=3#7 +// https://oldschool2009scape.fandom.com/wiki/Fishbowl_(pet) + +@Initializable +public class FishbowlPlugin extends OptionHandler { + private final static int FISHBOWL_EMPTY = Items.FISHBOWL_6667; + private final static int FISHBOWL_WATER = Items.FISHBOWL_6668; + private final static int FISHBOWL_SEAWEED = Items.FISHBOWL_6669; + + private final static int FISHBOWL_BLUE = Items.FISHBOWL_6670; + private final static int FISHBOWL_GREEN = Items.FISHBOWL_6671; + private final static int FISHBOWL_SPINE = Items.FISHBOWL_6672; + + private final static int TINY_NET = Items.TINY_NET_6674; + + private final static Animation ANIM_TALK = new Animation(2782); + private final static Animation ANIM_PLAY = new Animation(2780); + private final static Animation ANIM_FEED = new Animation(2781); + + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ItemDefinition.forId(FISHBOWL_WATER).getHandlers().put("option:empty", this); + ItemDefinition.forId(FISHBOWL_SEAWEED).getHandlers().put("option:empty", this); + for (int id : new int[] {FISHBOWL_BLUE, FISHBOWL_GREEN, FISHBOWL_SPINE}) { + ItemDefinition def = ItemDefinition.forId(id); + def.getHandlers().put("option:talk-at", this); + def.getHandlers().put("option:play-with", this); + def.getHandlers().put("option:feed", this); + def.getHandlers().put("option:drop", this); + } + ClassScanner.definePlugin(new FishbowlDialogue()); + ClassScanner.definePlugin(new FeedPetFishHandler()); + new AquariumPlugin().newInstance(arg); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + if (node instanceof Item) { + Item item = node.asItem(); + switch (item.getId()) { + case FISHBOWL_WATER: + case FISHBOWL_SEAWEED: + if (player.getInventory().remove(item)) { + player.lock(2); + player.getInventory().add(new Item(FISHBOWL_EMPTY)); + playAudio(player, Sounds.LIQUID_2401); + player.getPacketDispatch().sendMessage("You empty the contents of the fishbowl onto the ground."); + } + break; + case FISHBOWL_BLUE: + case FISHBOWL_GREEN: + case FISHBOWL_SPINE: + switch (option) { + case "talk-at": + player.lock(ANIM_TALK.getDuration()); + player.animate(ANIM_TALK); + return player.getDialogueInterpreter().open("fishbowl-options", option); + case "play-with": + player.lock(ANIM_PLAY.getDuration()); + player.animate(ANIM_PLAY); + return player.getDialogueInterpreter().open("fishbowl-options", option); + case "feed": + return player.getDialogueInterpreter().open("fishbowl-options", option); + case "drop": + return player.getDialogueInterpreter().open("fishbowl-options", option, item); + } + break; + } + } + + return true; + } + + private final class FeedPetFishHandler extends UseWithHandler { + public FeedPetFishHandler() { + super(Items.FISH_FOOD_272); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(FISHBOWL_BLUE, ITEM_TYPE, this); + addHandler(FISHBOWL_GREEN, ITEM_TYPE, this); + addHandler(FISHBOWL_SPINE, ITEM_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + return event.getPlayer().getDialogueInterpreter().open("fishbowl-options", "feed"); + } + } + + public final class FishbowlDialogue extends DialoguePlugin { + private Item fishbowl; + private String option; + + public FishbowlDialogue() {} + + public FishbowlDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new FishbowlDialogue(player); + } + + @Override + public boolean open(Object... args) { + for (Object arg : args) { + if (arg instanceof Item) { + this.fishbowl = (Item) arg; + } else if (arg instanceof String) { + this.option = (String) arg; + } + } + switch (option) { + case "talk-at": + player("Good fish. Just keep swimming... swimming... swimming..."); + stage = 1; + break; + case "play-with": + player("Jump! 'Cmon " + (player.isMale() ? "girl": "boy") + ", jump!"); + stage = 2; + break; + case "feed": + if (player.getInventory().containsAtLeastOneItem(Items.FISH_FOOD_272) && player.getInventory().remove(new Item(Items.FISH_FOOD_272))) { + player.getInventory().add(new Item(Items.AN_EMPTY_BOX_6675)); + player.lock(ANIM_FEED.getDuration()); + player.animate(ANIM_FEED); + player.getPacketDispatch().sendMessage("You feed your fish."); + } else if (player.getInventory().containsAtLeastOneItem(Items.POISONED_FISH_FOOD_274)) { + player.getPacketDispatch().sendMessage("You can't poison your own pet!"); + } else { + player.getPacketDispatch().sendMessage("You don't have any fish food."); + } + break; + case "drop": + sendDialogue("If you drop your fishbowl it will break!"); + stage = 4; + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 999: + end(); + break; + case 1: + sendDialogue("The fish swims. It is clearly an obedient fish."); + stage = 999; + break; + case 2: + sendDialogue("The fish bumps into the side of the fishbowl. Then it swims some", "more."); + stage++; + break; + case 3: + player("Good fish..."); + stage = 999; + break; + case 4: + options("Drop it regardless", "Keep hold"); + stage++; + break; + case 5: + switch(buttonId) { + case 1: + sendDialogue("The fishbowl shatters on the ground."); + player.getInventory().remove(fishbowl); + stage = 999; + break; + case 2: + sendDialogue("You keep a hold of it for now."); + stage = 999; + break; + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { DialogueInterpreter.getDialogueKey("fishbowl-options") }; + } + } + + + public static final class AquariumPlugin extends OptionHandler { + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(10091).getHandlers().put("option:fish-in", this); + ClassScanner.definePlugin(new TinyNetHandler()); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + return getFish(player); + } + + public boolean getFish(final Player player) { + if (!player.getInventory().containsAtLeastOneItem(TINY_NET)) { + player.getPacketDispatch().sendMessage("You see some tiny fish swimming around... but how to catch them?"); + return true; + } + else if (player.getInventory().remove(new Item(FISHBOWL_SEAWEED))) { + player.getPacketDispatch().sendMessage("You wave the net around..."); + player.getSkills().addExperience(Skills.FISHING, 1., true); + int level = player.getSkills().getLevel(Skills.FISHING); + int blueChance = (int) Math.round(Util.clamp(-0.6667 * (double) level + 106., 40, 60)); + int greenChance = (int) Math.round(Util.clamp(0.2941 * (double) level + 19.7059, 20, 40)); + int spineChance = (int) Math.round(Util.clamp(0.6667 * (double) level - 46., 0, 20)); + + WeightedChanceItem[] fishChance = new WeightedChanceItem[] { + new WeightedChanceItem(FISHBOWL_BLUE, 1, blueChance), + new WeightedChanceItem(FISHBOWL_GREEN, 1, greenChance), + new WeightedChanceItem(FISHBOWL_SPINE, 1, spineChance) + }; + + Item fish = RandomFunction.rollWeightedChanceTable(fishChance); + player.getInventory().add(fish); + String msg = "[ REPORT BUG ON GITLAB ]"; + switch(fish.getId()) { + case FISHBOWL_BLUE: + msg = "Bluefish"; + break; + case FISHBOWL_GREEN: + msg = "Greenfish"; + break; + case FISHBOWL_SPINE: + msg = "Spinefish"; + break; + } + player.getPacketDispatch().sendMessage("...and you catch a Tiny " + msg + "!"); + player.getAchievementDiaryManager().finishTask(player, DiaryType.SEERS_VILLAGE, 1, 10); + return true; + } + else { + player.getPacketDispatch().sendMessage("You need something to put your catch in!"); + return true; + } + } + + private final class TinyNetHandler extends UseWithHandler { + public TinyNetHandler() { + super(TINY_NET); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(10091, OBJECT_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + return getFish(event.getPlayer()); + } + } + } +} diff --git a/Server/src/main/content/global/handlers/item/GnomeCopterPlugin.java b/Server/src/main/content/global/handlers/item/GnomeCopterPlugin.java new file mode 100644 index 0000000..f3522b2 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/GnomeCopterPlugin.java @@ -0,0 +1,40 @@ +package content.global.handlers.item; + +import core.cache.def.impl.ItemDefinition; +import core.game.container.impl.EquipmentContainer; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Handles the gnome copter plugin. + * @author Vexia + */ +@Initializable +public final class GnomeCopterPlugin implements Plugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ItemDefinition.forId(12842).getHandlers().put("equipment", this); + return this; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + final Player player = (Player) args[0]; + final Item item = (Item) args[1]; + switch (identifier) { + case "equip": + break; + case "unequip": + if (item.getId() == 12842) { + player.getEquipment().remove(item, EquipmentContainer.SLOT_WEAPON, true); + return false; + } + break; + } + return false; + } + +} diff --git a/Server/src/main/content/global/handlers/item/GnomecopterTicket.java b/Server/src/main/content/global/handlers/item/GnomecopterTicket.java new file mode 100644 index 0000000..4907585 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/GnomecopterTicket.java @@ -0,0 +1,38 @@ +package content.global.handlers.item; + +import core.cache.def.impl.ItemDefinition; +import core.game.component.Component; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.plugin.Plugin; +import core.plugin.Initializable; +import core.tools.RandomFunction; + +/** + * The gnomecopter ticket handling plugin. + * @author Emperor + */ +@Initializable +public final class GnomecopterTicket extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ItemDefinition.forId(12843).getHandlers().put("option:read", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + player.getInterfaceManager().open(new Component(729)); + String info = "Gnomecopter ticket:"; + info += "
" + "Castle Wars"; // Destination + info += "
" + "Ref. #000"; + for (int i = 3; i < 8; i++) { + info += RandomFunction.randomize(10); + } + player.getPacketDispatch().sendString(info, 729, 2); + return true; + } + +} diff --git a/Server/src/main/content/global/handlers/item/GodBookListeners.kt b/Server/src/main/content/global/handlers/item/GodBookListeners.kt new file mode 100644 index 0000000..764190e --- /dev/null +++ b/Server/src/main/content/global/handlers/item/GodBookListeners.kt @@ -0,0 +1,162 @@ +package content.global.handlers.item + +import core.api.* +import core.game.node.entity.player.Player +import core.game.system.task.Pulse +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items +import core.game.dialogue.DialogueFile +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.game.node.Node +import core.game.node.entity.skill.Skills +import core.game.node.item.Item + +class GodBookListeners : InteractionListener { + + val GB_SARADOMIN = Items.HOLY_BOOK_3840 + val GB_ZAMORAK = Items.UNHOLY_BOOK_3842 + val GB_GUTHIX = Items.BOOK_OF_BALANCE_3844 + + override fun defineListeners() { + on(GB_SARADOMIN, IntType.ITEM, "preach"){ player, _ -> + openDialogue(player, HOLY_DIALOGUE(BOOK.SARA)) + return@on true + } + on(GB_ZAMORAK, IntType.ITEM, "preach"){ player, _ -> + openDialogue(player, HOLY_DIALOGUE(BOOK.ZAM)) + return@on true + } + on(GB_GUTHIX, IntType.ITEM, "preach"){ player, _ -> + openDialogue(player, HOLY_DIALOGUE(BOOK.GUTHIX)) + return@on true + } + + fun bless(player: Player, node: Node, product: Int) { + if (player.skills.getStaticLevel(Skills.PRAYER) < 50) { + sendMessage(player, "You need a Prayer level of at least 50 in order to do this.") + } else if (player.skills.prayerPoints < 4) { + sendMessage(player, "You need at least 4 prayer points in order to do this.") + } else { + sendMessage(player, "You bless the ${node.asItem().name.lowercase()}.") + player.skills.decrementPrayerPoints(4.0) + replaceSlot(player, node.asItem().slot, Item(product), node.asItem()) + } + } + onUseWith(IntType.ITEM, GB_SARADOMIN, Items.UNBLESSED_SYMBOL_1716) { player, _, symbol -> + bless(player, symbol, Items.HOLY_SYMBOL_1718) + return@onUseWith true + } + onUseWith(IntType.ITEM, GB_ZAMORAK, Items.UNPOWERED_SYMBOL_1722) { player, _, symbol -> + bless(player, symbol, Items.UNHOLY_SYMBOL_1724) + return@onUseWith true + } + onUseWith(IntType.ITEM, GB_GUTHIX, Items.UNBLESSED_SYMBOL_1716) { player, _, symbol -> + bless(player, symbol, Items.HOLY_SYMBOL_1718) + return@onUseWith true + } + onUseWith(IntType.ITEM, GB_GUTHIX, Items.UNPOWERED_SYMBOL_1722) { player, _, symbol -> + bless(player, symbol, Items.UNHOLY_SYMBOL_1724) + return@onUseWith true + } + } + + internal enum class BOOK { + SARA, + GUTHIX, + ZAM + } + + internal class HOLY_DIALOGUE(val book: BOOK) : DialogueFile(){ + + val WEDDINGS = arrayOf( + "In the name of Saradomin, protector of us all, I now join you in the eyes of Saradomin.", + "Light and dark, day and night, balance arises from contrast. I unify thee in the name of Guthix.", + "Two great warriors, joined by hand, to spread destruction across the land. In Zamorak's name, now two are one." + ) + + val LAST_RITES = arrayOf( + "Thy cause was false, thy skills did lack; See you in Lumbridge when you get back.", + "Thy death was not in vain, for it brought some balance to the world. May Guthix bring you rest.", + "The weak deserve to die, so the strong may flourish. This is the creed of Zamorak." + ) + + val BLESSINGS = arrayOf( + "Go in peace in the name of Saradomin; may his glory shine upon you like the sun.", + "May you walk the path, and never fall, for Guthix walks beside thee on thy journey. May Guthix bring you peace.", + "May your bloodthirst never be sated, and may all your battles be glorious. Zamorak bring you strength." + ) + + val PREACHINGS = arrayOf( + arrayOf( + "Protect your self, protect your friends. Mine is the glory that never ends.", + "The darkness in life may be avoided, by the light of wisdom shining.", + "Show love to your friends, and mercy to your enemies, and know that the wisdom of Saradomin will follow. ", + "A fight begun, when the cause is just, will prevail over all others.", + "The currency of goodness is honour; It retains its value through scarcity." + ), + arrayOf( + "All things must end, as all begin; Only Guthix knows the role thou must play.", + "In life, in death, in joy, in sorrow: May thine experience show thee balance.", + "Thou must do as thou must, no matter what. Thine actions bring balance to this world.", + "he river flows, the sun ignites, May you stand with Guthix in thy fights.", + "A journey of a single step, May take thee over a thousand miles." + ), + arrayOf( + "There is no opinion that cannot be proven true...by crushing those who choose to disagree with it.", + "Battles are not lost and won; They simply remove the weak from the equation.", + "Those who fight, then run away, shame Zamorak with their cowardice.", + "Battle is by those who choose to disagree with it.", + "Strike fast, strike hard, strike true: The strength of Zamorak will be with you." + ) + ) + + val PREACH_SARA_AMEN = "This is Saradomin's Wisdom." + val PREACH_ZAM_AMEN = "Zamorak give me strength!" + val PREACH_GUTH_AMEN = "May Guthix bring you balance." + + override fun handle(componentID: Int, buttonID: Int) { + when(stage){ + 0 -> options("Weddings","Last Rites","Blessings","Preaching").also { stage++ } + 1 -> when(buttonID){ + 1 -> say(player!!, WEDDINGS[book.ordinal], book, false) + 2 -> say(player!!, LAST_RITES[book.ordinal], book, false) + 3 -> say(player!!, BLESSINGS[book.ordinal], book, false) + 4 -> say(player!!, PREACHINGS[book.ordinal].random(), book, true) + else -> {} + }.also { end() } + } + } + + private fun say(player: Player, message: String, book: BOOK, preach: Boolean){ + val animation = when(book){ + BOOK.SARA -> Animation(1335) + BOOK.ZAM -> Animation(1336) + BOOK.GUTHIX -> Animation(1337) + } + + val preachText = when(book){ + BOOK.SARA -> PREACH_SARA_AMEN + BOOK.ZAM -> PREACH_ZAM_AMEN + BOOK.GUTHIX -> PREACH_GUTH_AMEN + } + + val lastTick = animationDuration(animation) + + lock(player, 100) + animate(player, animation) + + submitIndividualPulse(player, object : Pulse() { + var counter = 0 + override fun pulse(): Boolean { + when(counter++){ + 0 -> sendChat(player, message) + lastTick - 1 -> if(preach) sendChat(player, preachText) + lastTick -> unlock(player).also { return true } + } + return false + } + }) + } + } +} diff --git a/Server/src/main/content/global/handlers/item/GodBookPlugin.java b/Server/src/main/content/global/handlers/item/GodBookPlugin.java new file mode 100644 index 0000000..9f955de --- /dev/null +++ b/Server/src/main/content/global/handlers/item/GodBookPlugin.java @@ -0,0 +1,124 @@ +package content.global.handlers.item; + +import core.game.dialogue.DialogueAction; +import content.data.GodBook; +import core.game.node.entity.skill.Skills; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.OptionHandler; +import core.game.interaction.UseWithHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItem; +import core.game.node.item.Item; +import core.game.node.item.ItemPlugin; +import core.plugin.Plugin; +import core.plugin.Initializable; +import core.plugin.ClassScanner; + +/** + * Handles the god books. + * @author Vexia + */ +@Initializable +public class GodBookPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (GodBook book : GodBook.values()) { + book.getDamagedBook().getDefinition().getHandlers().put("option:check", this); + } + ClassScanner.definePlugins(new PageHandler(), new GodBookItem()); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + GodBook book = GodBook.forItem(node.asItem(), option.equalsIgnoreCase("check")); + if (book != null) { + switch (option) { + case "check": + String[] messages = new String[4]; + for (int i = 0; i < messages.length; i++) { + messages[i] = book.hasPage(player, node.asItem(), i + 1) ? "The " + getNumberName(i + 1) + " page is in the book." : "The " + getNumberName(i + 1) + " page is missing."; + } + player.getDialogueInterpreter().sendDialogue(messages); + return true; + case "preach": + player.getDialogueInterpreter().open("god-book", book); + return true; + } + } + return true; + } + + /** + * A god book item. + * @author Vexia + */ + public class GodBookItem extends ItemPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (GodBook book : GodBook.values()) { + register(book.getDamagedBook().getId()); + } + return this; + } + + @Override + public boolean canPickUp(Player player, GroundItem item, int type) { + if (player.hasItem(item.asItem())) { + player.sendMessage("You do not need more than one incomplete book."); + return false; + } + return true; + } + + } + + /** + * The page handler. + * @author Vexia + */ + public class PageHandler extends UseWithHandler { + + /** + * Constructs a new {@code PageHandler} {@code Object} + */ + public PageHandler() { + super(3839, 3841, 3843); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (GodBook book : GodBook.values()) { + for (Item i : book.getPages()) { + addHandler(i.getId(), ITEM_TYPE, this); + } + } + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + GodBook book = GodBook.forItem(event.getUsedItem(), true); + Player player = event.getPlayer(); + if (book != null && book.isPage(event.getUsedWith().asItem())) { + book.insertPage(player, event.getUsedItem(), event.getUsedWith().asItem()); + return true; + } + return false; + } + + } + + /** + * Gets the number name. + * @param i the integer to check. + * @return the number name. + */ + private String getNumberName(int i) { + return i == 1 ? "first" : i == 2 ? "second" : i == 3 ? "third" : "fourth"; + } + +} diff --git a/Server/src/main/content/global/handlers/item/GodswordDismantlePlugin.java b/Server/src/main/content/global/handlers/item/GodswordDismantlePlugin.java new file mode 100644 index 0000000..64655e1 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/GodswordDismantlePlugin.java @@ -0,0 +1,55 @@ +package content.global.handlers.item; + +import core.cache.def.impl.ItemDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the godsword dismantle plugin. + * @author Emperor + * @version 1.0 + */ +@Initializable +public final class GodswordDismantlePlugin extends OptionHandler { + + /** + * Represents the godsword blade item. + */ + private static final Item BLADE = new Item(11690); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ItemDefinition.forId(11694).getHandlers().put("option:dismantle", this); + ItemDefinition.forId(11696).getHandlers().put("option:dismantle", this); + ItemDefinition.forId(11698).getHandlers().put("option:dismantle", this); + ItemDefinition.forId(11700).getHandlers().put("option:dismantle", this); + return this; + } + + @Override + public boolean handle(final Player player, Node node, String option) { + final Item item = (Item) node; + if (item.getSlot() < 0 || player.getInventory().getNew(item.getSlot()).getId() != item.getId()) { + return true; + } + final int freeSlot = player.getInventory().freeSlot(); + if (freeSlot == -1) { + player.getPacketDispatch().sendMessage("Not enough space in your inventory!"); + return true; + } + player.getPacketDispatch().sendMessage("You detach the hilt from the blade."); + player.getInventory().replace(null, item.getSlot(), false); + player.getInventory().add(BLADE, new Item(11702 + (item.getId() - 11694))); + return true; + } + + @Override + public boolean isWalk() { + return false; + } + +} diff --git a/Server/src/main/content/global/handlers/item/GrandSeedPodHandler.kt b/Server/src/main/content/global/handlers/item/GrandSeedPodHandler.kt new file mode 100644 index 0000000..992d100 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/GrandSeedPodHandler.kt @@ -0,0 +1,97 @@ +package content.global.handlers.item + +import content.global.travel.glider.GliderPulse +import content.global.travel.glider.Gliders +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.net.packet.PacketRepository +import core.net.packet.context.MinimapStateContext +import core.net.packet.out.MinimapState +import org.rs09.consts.Items + +private const val SQUASH_GRAPHICS_BEGIN = 767 +private const val SQUASH_GRAPHICS_END = 769 +private const val SQUASH_ANIM_BEGIN = 4544 +private const val SQUASH_ANIM_END = 4546 +private const val LAUNCH_GRAPHICS = 768 +private const val LAUNCH_ANIMATION = 4547 + +/** + * Handles the grand tree pod options + * @author Ceikry + */ +class GrandSeedPodHandler : InteractionListener { + + override fun defineListeners() { + on(intArrayOf(Items.GRAND_SEED_POD_9469), IntType.ITEM, "squash", "launch") { player, _ -> + val opt = getUsedOption(player) + if (!removeItem(player, Items.GRAND_SEED_POD_9469)) return@on false + if (opt == "launch") { + visualize(player, LAUNCH_ANIMATION, LAUNCH_GRAPHICS) + delayEntity(player, 7) + queueScript(player, 3, QueueStrength.SOFT) {stage: Int -> + if (stage == 0) { + rewardXP(player, Skills.FARMING, 100.0) + openOverlay(player, 115) + return@queueScript keepRunning(player) + } + + if (stage == 1) { + PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 2)) + return@queueScript delayScript(player, 3) + } + + if (stage == 2) { + teleport(player, Gliders.TA_QUIR_PRIW.location) + return@queueScript delayScript(player, 2) + } + + if (stage == 3) { + closeOverlay(player) + PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 0)) + } + + return@queueScript stopExecuting(player) + } + } + + if (opt == "squash") { + closeAllInterfaces(player) + visualize(player, SQUASH_ANIM_BEGIN, SQUASH_GRAPHICS_BEGIN) + delayEntity(player, 12) + queueScript(player, 3, QueueStrength.SOFT) {stage: Int -> + if (stage == 0) { + animate(player, 1241, true) + return@queueScript keepRunning(player) + } + + if (stage == 1) { + teleport(player, Location.create(2464, 3494, 0)) + return@queueScript keepRunning(player) + } + + if (stage == 2) { + visualize(player, 1241, SQUASH_GRAPHICS_END) + return@queueScript delayScript(player, 2) + } + + if (stage == 3) { + animate(player, SQUASH_ANIM_END, true) + adjustLevel(player, Skills.FARMING, -5) + return@queueScript keepRunning(player) + } + + return@queueScript stopExecuting(player) + } + } + + return@on true + } + } +} diff --git a/Server/src/main/content/global/handlers/item/HerbBoxPlugin.java b/Server/src/main/content/global/handlers/item/HerbBoxPlugin.java new file mode 100644 index 0000000..1f2758f --- /dev/null +++ b/Server/src/main/content/global/handlers/item/HerbBoxPlugin.java @@ -0,0 +1,85 @@ +package content.global.handlers.item; + +import core.cache.def.impl.ItemDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.ChanceItem; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.tools.RandomFunction; + +import java.util.ArrayList; +import java.util.List; + +/** + * Handles the herb box item. + * @author Vexia + * + */ +@Initializable +public class HerbBoxPlugin extends OptionHandler { + + /** + * The herbs to recieve. + */ + private static final ChanceItem[] HERBS = new ChanceItem[] {new ChanceItem(199, 1, 25), new ChanceItem(201, 1, 18), new ChanceItem(203, 1, 13), new ChanceItem(205, 1, 11), new ChanceItem(207, 1, 8), new ChanceItem(209, 1, 6), new ChanceItem(211, 1, 4), new ChanceItem(213, 1, 5), new ChanceItem(215, 1, 3), new ChanceItem(2485, 1, 3), new ChanceItem(217, 1, 3)}; + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ItemDefinition.forId(14810).getHandlers().put("option:bank-all", this); + ItemDefinition.forId(14810).getHandlers().put("option:take-one", this); + ItemDefinition.forId(14810).getHandlers().put("option:check", this); + return null; + } + + @Override + public boolean handle(Player player, Node node, String option) { + Item box = node.asItem(); + int herbs = 10 - (1000 - box.getCharge()); + if (herbs < 0 || herbs > 10) { + player.getInventory().remove(box, box.getSlot(), true); + return true; + } + player.lock(1); + switch (option) { + case "bank-all": + if (player.getBank().freeSlots() < herbs) { + player.sendMessage("You don't have enough bank space to bank all those herbs."); + break; + } + List herbList = new ArrayList<>(5); + for (int i = 0; i < herbs; i++) { + herbList.add(RandomFunction.getChanceItem(HERBS)); + } + if (player.getInventory().remove(box, box.getSlot(), true)) { + player.getBank().add(herbList.toArray(new ChanceItem[] {})); + player.sendMessage(herbs + " herbs have been deposited into your bank."); + } + break; + case "take-one": + if (player.getInventory().freeSlots() < 1) { + player.sendMessage("You don't have enough space in your inventory."); + break; + } + ChanceItem herb = RandomFunction.getChanceItem(HERBS); + player.getInventory().add(herb.getRandomItem()); + box.setCharge(box.getCharge() - 1); + if (box.getCharge() <= 990) { + player.getInventory().remove(box, box.getSlot(), true); + } + player.sendMessage("You take a herb from the box."); + break; + case "check": + player.sendMessage("The herb box contains " + herbs + " herbs."); + break; + } + return true; + } + + @Override + public boolean isWalk() { + return false; + } +} diff --git a/Server/src/main/content/global/handlers/item/HouseTeleTabOptionListener.kt b/Server/src/main/content/global/handlers/item/HouseTeleTabOptionListener.kt new file mode 100644 index 0000000..61ac1b0 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/HouseTeleTabOptionListener.kt @@ -0,0 +1,31 @@ +package content.global.handlers.item + +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.link.TeleportManager +import core.game.node.item.Item + +class HouseTeleTabOptionListener : InteractionListener { + override fun defineListeners() { + val homeTabID = 8013 + on(homeTabID, IntType.ITEM, "break") {player, node -> + var hasHouse = player.houseManager.location.exitLocation != null + if (!hasHouse) { + sendMessage( player, "You must have a house to teleport to before attempting that.") + return@on false + } + closeInterface(player) + lock(player, 5) + if (inInventory(player, node.id)) { + player.houseManager.preEnter(player, false) + val location = player.houseManager.getEnterLocation() + if (teleport(player, location, TeleportManager.TeleportType.TELETABS)) { + removeItem(player, Item(node.id, 1)) + player.houseManager.postEnter(player, false) + } + } + return@on true + } + } +} diff --git a/Server/src/main/content/global/handlers/item/ImplingJarListener.kt b/Server/src/main/content/global/handlers/item/ImplingJarListener.kt new file mode 100644 index 0000000..66158c7 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/ImplingJarListener.kt @@ -0,0 +1,264 @@ +package content.global.handlers.item + +import core.api.Container +import core.api.* +import org.rs09.consts.Items +import core.api.utils.WeightBasedTable +import core.api.utils.WeightedItem +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +class ImplingJarListener : InteractionListener { + + val JARS = ImplingLoot.values().map { it.jarId }.toIntArray() + + override fun defineListeners() { + on(JARS, IntType.ITEM, "loot"){ player, node -> + val jar = node.asItem() + + val loot = ImplingLoot.forId(jar.id)?.roll()?.firstOrNull() ?: return@on false + + if(removeItem(player, jar, Container.INVENTORY)) { + addItemOrDrop(player, loot.id, loot.amount) + addItemOrDrop(player, Items.IMPLING_JAR_11260, 1) + } + + return@on true + } + } +} + + +enum class ImplingLoot(val jarId: Int, val table: WeightBasedTable){ + BABY_IMPLING(Items.BABY_IMPLING_JAR_11238, WeightBasedTable.create( + WeightedItem(Items.CHISEL_1755, 1, 1, 10.0), + WeightedItem(Items.THREAD_1734, 1, 1, 10.0), + WeightedItem(Items.NEEDLE_1733, 1, 1, 10.0), + WeightedItem(Items.KNIFE_946,1, 1, 10.0), + WeightedItem(Items.CHEESE_1985, 1, 1, 10.0), + WeightedItem(Items.HAMMER_2347, 1, 1, 10.0), + WeightedItem(Items.BALL_OF_WOOL_1759, 1, 1, 10.0), + WeightedItem(Items.ANCHOVIES_319, 1, 1, 10.0), + WeightedItem(0, 1, 1, 10.0), + WeightedItem(Items.SPICE_2007, 1, 1, 1.0), + WeightedItem(Items.FLAX_1779, 1, 1, 1.0), + WeightedItem(Items.MUD_PIE_7170, 1, 1, 1.0), + WeightedItem(Items.SEAWEED_401, 1, 1, 1.0), + WeightedItem(Items.AIR_TALISMAN_1438, 1, 1, 1.0), + WeightedItem(Items.SILVER_BAR_2355, 1, 1, 1.0), + WeightedItem(Items.SAPPHIRE_1607, 1, 1, 1.0), + WeightedItem(Items.HARD_LEATHER_1743, 1, 1, 1.0), + WeightedItem(Items.LOBSTER_379, 1, 1, 1.0), + ).insertEasyClue(1.0)), + + YOUNG_IMPLING(Items.YOUNG_IMPLING_JAR_11240, WeightBasedTable.create( + WeightedItem(Items.STEEL_NAILS_1539, 5, 5, 10.0), + WeightedItem(Items.LOCKPICK_1523, 1, 1, 10.0), + WeightedItem(Items.PURE_ESSENCE_7936, 1, 1, 10.0), + WeightedItem(Items.TUNA_361, 1, 1, 10.0), + WeightedItem(Items.CHOCOLATE_SLICE_1901, 1, 1, 10.0), + WeightedItem(Items.STEEL_AXE_1353, 1, 1, 10.0), + WeightedItem(Items.MEAT_PIZZA_2293, 1, 1, 10.0), + WeightedItem(Items.COAL_453, 1, 1, 10.0), + WeightedItem(Items.BOW_STRING_1777, 1, 1, 10.0), + WeightedItem(Items.SNAPE_GRASS_231, 1, 1, 1.0), + WeightedItem(Items.SOFT_CLAY_1761, 1, 1, 1.0), + WeightedItem(Items.STUDDED_CHAPS_1097, 1, 1, 1.0), + WeightedItem(Items.STEEL_FULL_HELM_1157, 1, 1, 1.0), + WeightedItem(Items.OAK_PLANK_8778, 1, 1, 1.0), + WeightedItem(Items.DEFENCE_POTION3_133, 1, 1, 1.0), + WeightedItem(Items.MITHRIL_BAR_2359, 1, 1, 1.0), + WeightedItem(Items.YEW_LONGBOW_855, 1, 1, 1.0), + WeightedItem(Items.GARDEN_PIE_7178, 1, 1, 1.0), + WeightedItem(Items.JANGERBERRIES_247, 1, 1, 1.0) + ).insertEasyClue(2.0)), + + GOURMET_IMPLING(Items.GOURM_IMPLING_JAR_11242, WeightBasedTable.create( + WeightedItem(Items.TUNA_361, 1, 1, 20.0), + WeightedItem(Items.BASS_365, 1, 1, 10.0), + WeightedItem(Items.CURRY_2011, 1, 1, 10.0), + WeightedItem(Items.MEAT_PIE_2327, 1, 1, 10.0), + WeightedItem(Items.CHOCOLATE_CAKE_1897, 1, 1, 10.0), + WeightedItem(Items.FROG_SPAWN_5004, 1, 1, 10.0), + WeightedItem(Items.SPICE_2007, 1, 1, 10.0), + WeightedItem(Items.CURRY_LEAF_5970, 1, 1, 10.0), + WeightedItem(Items.UGTHANKI_KEBAB_1883, 1, 1, 1.0), + WeightedItem(Items.LOBSTER_380, 4, 4, 1.0), + WeightedItem(Items.SHARK_386, 3, 3, 1.0), + WeightedItem(Items.FISH_PIE_7188, 1, 1, 1.0), + WeightedItem(Items.CHEFS_DELIGHT4_5833, 1, 1, 1.0), + WeightedItem(Items.RAINBOW_FISH_10137, 5, 5, 1.0), + WeightedItem(Items.GARDEN_PIE_7179, 6, 6, 1.0), + WeightedItem(Items.SWORDFISH_374, 3, 3, 1.0), + WeightedItem(Items.STRAWBERRIES5_5406, 1, 1, 1.0), + WeightedItem(Items.COOKED_KARAMBWAN_3145, 2, 2, 1.0), + ).insertEasyClue(4.0)), + + EARTH_IMPLING(Items.EARTH_IMPLING_JAR_11244, WeightBasedTable.create( + WeightedItem(Items.FIRE_TALISMAN_1442, 1, 1, 10.0), + WeightedItem(Items.EARTH_TALISMAN_1440, 1, 1, 10.0), + WeightedItem(Items.EARTH_TIARA_5535, 1, 1, 10.0), + WeightedItem(Items.EARTH_RUNE_557, 32, 32, 10.0), + WeightedItem(Items.MITHRIL_ORE_447, 1, 1, 10.0), + WeightedItem(Items.BUCKET_OF_SAND_1784, 4, 4, 10.0), + WeightedItem(Items.UNICORN_HORN_237, 1, 1, 10.0), + WeightedItem(Items.COMPOST_6033, 6, 6, 10.0), + WeightedItem(Items.GOLD_ORE_444, 1, 1, 10.0), + WeightedItem(Items.STEEL_BAR_2353, 1, 1, 1.0), + WeightedItem(Items.MITHRIL_PICKAXE_1273, 1, 1, 1.0), + WeightedItem(Items.WILDBLOOD_SEED_5311, 2, 2, 1.0), + WeightedItem(Items.JANGERBERRY_SEED_5104, 2, 2, 1.0), + WeightedItem(Items.SUPERCOMPOST_6035, 2, 2, 1.0), + WeightedItem(Items.MITHRIL_ORE_448, 3, 3, 1.0), + WeightedItem(Items.HARRALANDER_SEED_5294, 2, 2, 1.0), + WeightedItem(Items.COAL_454, 6, 6, 1.0), + WeightedItem(Items.EMERALD_1606, 2, 2, 1.0), + WeightedItem(Items.RUBY_1603, 1, 1, 1.0) + ).insertMediumClue(1.0)), + + ESSENCE_IMPLING(Items.ESS_IMPLING_JAR_11246, WeightBasedTable.create( + WeightedItem(Items.PURE_ESSENCE_7937, 20, 20, 10.0), + WeightedItem(Items.WATER_RUNE_555, 30, 30, 10.0), + WeightedItem(Items.AIR_RUNE_556, 30, 30, 10.0), + WeightedItem(Items.FIRE_RUNE_554, 50, 50, 10.0), + WeightedItem(Items.MIND_RUNE_558, 25, 25, 10.0), + WeightedItem(Items.BODY_RUNE_559, 28, 28, 10.0), + WeightedItem(Items.CHAOS_RUNE_562, 4, 4, 10.0), + WeightedItem(Items.COSMIC_RUNE_564, 4, 4, 10.0), + WeightedItem(Items.MIND_TALISMAN_1448, 1, 1, 10.0), + WeightedItem(Items.PURE_ESSENCE_7937, 35, 35, 1.0), + WeightedItem(Items.LAVA_RUNE_4699, 4, 4, 1.0), + WeightedItem(Items.MUD_RUNE_4698, 4, 4, 1.0), + WeightedItem(Items.SMOKE_RUNE_4697, 4, 4, 1.0), + WeightedItem(Items.STEAM_RUNE_4694, 4, 4, 1.0), + WeightedItem(Items.DEATH_RUNE_560, 13, 13, 1.0), + WeightedItem(Items.LAW_RUNE_563, 13, 13, 1.0), + WeightedItem(Items.BLOOD_RUNE_565, 7, 7, 1.0), + WeightedItem(Items.SOUL_RUNE_566, 11, 11, 1.0), + WeightedItem(Items.NATURE_RUNE_561, 13, 13, 1.0) + ).insertMediumClue(2.0)), + + ECLECTIC_IMPLING(Items.ECLECTIC_IMPLING_JAR_11248, WeightBasedTable.create( + WeightedItem(Items.MITHRIL_PICKAXE_1273, 1, 1, 10.0), + WeightedItem(Items.CURRY_LEAF_5970, 1, 1, 10.0), + WeightedItem(Items.SNAPE_GRASS_231, 1, 1, 10.0), + WeightedItem(Items.AIR_RUNE_556, 30, 58, 10.0), + WeightedItem(Items.OAK_PLANK_8779, 4, 4, 10.0), + WeightedItem(Items.CANDLE_LANTERN_4527, 1, 1, 10.0), + WeightedItem(Items.GOLD_ORE_444, 1, 1, 10.0), + WeightedItem(Items.GOLD_BAR_2358, 5, 5, 10.0), + WeightedItem(Items.UNICORN_HORN_237, 1, 1, 10.0), + WeightedItem(Items.ADAMANT_KITESHIELD_1199, 1, 1, 1.0), + WeightedItem(Items.BLUE_DHIDE_CHAPS_2493, 1, 1, 1.0), + WeightedItem(Items.RED_SPIKY_VAMBS_10083, 1, 1, 1.0), + WeightedItem(Items.RUNE_DAGGER_1213, 1, 1, 1.0), + WeightedItem(Items.BATTLESTAFF_1391, 1, 1, 1.0), + WeightedItem(Items.ADAMANTITE_ORE_450, 10, 10, 1.0), + WeightedItem(Items.SLAYERS_RESPITE4_5842, 2, 2, 1.0), + WeightedItem(Items.WILD_PIE_7208, 1, 1, 1.0), + WeightedItem(Items.WATERMELON_SEED_5321, 3, 3, 1.0), + WeightedItem(Items.DIAMOND_1601, 1, 1, 1.0) + ).insertMediumClue(4.0)), + + NATURE_IMPLING(Items.NATURE_IMPLING_JAR_11250, WeightBasedTable.create( + WeightedItem(Items.LIMPWURT_SEED_5100, 1, 1, 10.0), + WeightedItem(Items.JANGERBERRY_SEED_5104, 1, 1, 10.0), + WeightedItem(Items.BELLADONNA_SEED_5281, 1, 1, 10.0), + WeightedItem(Items.HARRALANDER_SEED_5294, 1, 1, 10.0), + WeightedItem(Items.CACTUS_SPINE_6016, 1, 1, 10.0), + WeightedItem(Items.MAGIC_LOGS_1513, 1, 1, 10.0), + WeightedItem(Items.CLEAN_TARROMIN_254, 4, 4, 10.0), + WeightedItem(Items.COCONUT_5974, 1, 1, 10.0), + WeightedItem(Items.IRIT_SEED_5297, 1, 1, 10.0), + WeightedItem(Items.CURRY_TREE_SEED_5286, 1, 1, 1.0), + WeightedItem(Items.ORANGE_TREE_SEED_5285, 1, 1, 1.0), + WeightedItem(Items.CLEAN_SNAPDRAGON_3000, 1, 1, 1.0), + WeightedItem(Items.KWUARM_SEED_5299, 1, 1, 1.0), + WeightedItem(Items.AVANTOE_SEED_5298, 5, 5, 1.0), + WeightedItem(Items.WILLOW_SEED_5313, 1, 1, 1.0), + WeightedItem(Items.TORSTOL_SEED_5304, 1, 1, 1.0), + WeightedItem(Items.RANARR_SEED_5295, 1, 1, 1.0), + WeightedItem(Items.CLEAN_TORSTOL_270, 2, 2, 1.0), + WeightedItem(Items.DWARF_WEED_SEED_5303, 1, 1, 1.0) + ).insertHardClue(1.0)), + + MAGPIE_IMPLING(Items.MAGPIE_IMPLING_JAR_11252, WeightBasedTable.create( + WeightedItem(Items.BLACK_DRAGONHIDE_1748, 6, 6, 10.0), + WeightedItem(Items.DIAMOND_AMULET_1701, 3, 3, 5.0), + WeightedItem(Items.AMULET_OF_POWER_1732, 3, 3, 5.0), + WeightedItem(Items.RING_OF_FORGING_2569, 3, 3, 5.0), + WeightedItem(Items.SPLITBARK_GAUNTLETS_3391, 1, 1, 5.0), + WeightedItem(Items.MYSTIC_BOOTS_4097, 1, 1, 5.0), + WeightedItem(Items.MYSTIC_GLOVES_4095, 1, 1, 5.0), + WeightedItem(Items.RUNE_WARHAMMER_1347, 1, 1, 5.0), + WeightedItem(Items.RING_OF_LIFE_2571, 4, 4, 5.0), + WeightedItem(Items.RUNE_SQ_SHIELD_1185, 1, 1, 5.0), + WeightedItem(Items.DRAGON_DAGGER_1215, 1, 1, 5.0), + WeightedItem(Items.NATURE_TIARA_5541, 1, 1, 5.0), + WeightedItem(Items.RUNITE_BAR_2364, 2, 2, 5.0), + WeightedItem(Items.DIAMOND_1602, 4, 4, 5.0), + WeightedItem(Items.PINEAPPLE_SEED_5287, 1, 1, 5.0), + WeightedItem(Items.LOOP_HALF_OF_A_KEY_987, 1, 1, 5.0), + WeightedItem(Items.TOOTH_HALF_OF_A_KEY_985, 1, 1, 5.0), + WeightedItem(Items.SNAPDRAGON_SEED_5300, 1, 1, 5.0), + WeightedItem(Items.SINISTER_KEY_993, 1, 1, 5.0) + ).insertHardClue(2.0)), + + NINJA_IMPLING(Items.NINJA_IMPLING_JAR_11254, WeightBasedTable.create( + WeightedItem(Items.SNAKESKIN_BOOTS_6328, 1, 1, 1.65), + WeightedItem(Items.SPLITBARK_HELM_3385, 1, 1, 1.65), + WeightedItem(Items.MYSTIC_BOOTS_4098, 1, 1, 1.65), + WeightedItem(Items.RUNE_CHAINBODY_1113, 1, 1, 1.65), + WeightedItem(Items.MYSTIC_GLOVES_4095, 1, 1, 1.65), + WeightedItem(Items.OPAL_MACHETE_6313, 1, 1, 1.65), + WeightedItem(Items.RUNE_CLAWS_3101, 1, 1, 1.65), + WeightedItem(Items.RUNE_SCIMITAR_1333, 1, 1, 1.65), + WeightedItem(Items.DRAGON_DAGGERP_PLUS_5680, 1, 1, 1.65), + WeightedItem(Items.RUNE_ARROW_892, 70, 70, 1.65), + WeightedItem(Items.RUNE_DART_811, 70, 70, 1.65), + WeightedItem(Items.RUNE_KNIFE_868, 40, 40, 1.65), + WeightedItem(Items.RUNE_THROWNAXE_805, 50, 50, 1.65), + WeightedItem(Items.ONYX_BOLTS_9342, 2, 2, 1.65), + WeightedItem(Items.ONYX_BOLT_TIPS_9194, 4, 4, 1.65), + WeightedItem(Items.BLACK_DRAGONHIDE_1748, 10, 10, 1.65), + WeightedItem(Items.PRAYER_POTION3_140, 4, 4, 1.65), + WeightedItem(Items.WEAPON_POISON_PLUS_5938, 4, 4, 1.65), + WeightedItem(Items.DAGANNOTH_HIDE_6156, 3, 3, 1.65) + ).insertHardClue(1.0)), + + DRAGON_IMPLING(Items.DRAGON_IMPLING_JAR_11256, WeightBasedTable.create( + WeightedItem(Items.DRAGON_BOLT_TIPS_9193, 10, 30, 2.0), + WeightedItem(Items.DRAGON_BOLT_TIPS_9193, 36, 36, 2.0), + WeightedItem(Items.MYSTIC_ROBE_BOTTOM_4093, 1, 1, 2.0), + WeightedItem(Items.AMULET_OF_GLORY_1705, 3, 3, 2.0), + WeightedItem(Items.DRAGONSTONE_AMMY_1703, 2, 2, 2.0), + WeightedItem(Items.DRAGON_ARROW_11212, 100, 250, 2.0), + WeightedItem(Items.DRAGON_BOLTS_9341, 10, 40, 2.0), + WeightedItem(Items.DRAGON_LONGSWORD_1305, 1, 1, 2.0), + WeightedItem(Items.DRAGON_DAGGERP_PLUS_PLUS_5699, 3, 3, 2.0), + WeightedItem(Items.DRAGON_DART_11230, 100, 250, 2.0), + WeightedItem(Items.DRAGONSTONE_1616, 3, 3, 2.0), + WeightedItem(Items.DRAGON_DART_TIP_11232, 100, 350, 2.0), + WeightedItem(Items.DRAGON_ARROWTIPS_11237, 100, 350, 2.0), + WeightedItem(Items.BABYDRAGON_BONES_535, 100, 300, 2.0), + WeightedItem(Items.DRAGON_BONES_537, 50, 100, 2.0), + WeightedItem(Items.MAGIC_SEED_5316, 1, 1, 2.0), + WeightedItem(Items.SNAPDRAGON_SEED_5300, 6, 6, 2.0), + WeightedItem(Items.SUMMER_PIE_7219, 15, 15, 2.0) + ).insertHardClue(1.0)); + + companion object{ + + val jarMap = HashMap() + + init { + for(impling in values()){ + jarMap[impling.jarId] = impling.table + } + } + + fun forId(id: Int): WeightBasedTable?{ + return jarMap[id] + } + } +} diff --git a/Server/src/main/content/global/handlers/item/ItemQuestRequirementListener.kt b/Server/src/main/content/global/handlers/item/ItemQuestRequirementListener.kt new file mode 100644 index 0000000..8acaa69 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/ItemQuestRequirementListener.kt @@ -0,0 +1,236 @@ +package content.global.handlers.item + +import core.api.* +import core.game.node.entity.player.link.quest.QuestRepository +import org.rs09.consts.Items +import core.game.interaction.InteractionListener +import content.data.Quests + +class ItemQuestRequirementListener : InteractionListener { + + private val fremennikIslesEquipment = intArrayOf(Items.HELM_OF_NEITIZNOT_10828, Items.HELM_OF_NEITIZNOT_E_12680, Items.HELM_OF_NEITIZNOT_CHARGED_12681) + private val fremennikTrialsEquipment = intArrayOf(Items.BERSERKER_HELM_3751, Items.BERSERKER_HELM_13408, Items.BERSERKER_HELM_E_12674, Items.BERSERKER_HELM_CHARGED_12675, + Items.FREMENNIK_HELM_3748, Items.WARRIOR_HELM_3753, Items.WARRIOR_HELM_13409, Items.WARRIOR_HELM_CHARGED_12677, Items.WARRIOR_HELM_E_12676, + Items.ARCHER_HELM_3749, Items.ARCHER_HELM_13407, Items.ARCHER_HELM_CHARGED_12673, Items.ARCHER_HELM_E_12672, + Items.ROCK_SHELL_HELM_6128, Items.ROCK_SHELL_HELM_10613, Items.ROCK_SHELL_HELM_13411, + Items.ROCK_SHELL_LEGS_6130, Items.ROCK_SHELL_LEGS_13413, + Items.ROCK_SHELL_PLATE_6129, Items.ROCK_SHELL_PLATE_13412, + Items.ROCK_SHELL_BOOTS_6145, Items.ROCK_SHELL_BOOTS_13421, + Items.ROCK_SHELL_GLOVES_6151, Items.ROCK_SHELL_GLOVES_13424, + Items.SPINED_HELM_6131, Items.SPINED_HELM_10614, Items.SPINED_HELM_13414, + Items.SPINED_BODY_6133, Items.SPINED_BODY_13415, + Items.SPINED_CHAPS_6135, Items.SPINED_CHAPS_13416, + Items.SPINED_GLOVES_6149, Items.SPINED_GLOVES_13423, + Items.SPINED_BOOTS_6143, Items.SPINED_BOOTS_13420, + Items.SKELETAL_HELM_6137, Items.SKELETAL_HELM_10604, Items.SKELETAL_HELM_13417, + Items.SKELETAL_TOP_6139, Items.SKELETAL_TOP_13418, + Items.SKELETAL_BOTTOMS_6141, Items.SKELETAL_BOTTOMS_13419, + Items.SKELETAL_GLOVES_6153, Items.SKELETAL_GLOVES_13425, + Items.SKELETAL_BOOTS_6147, Items.SKELETAL_BOOTS_13422, + Items.FREMENNIK_HAT_3798, Items.FREMENNIK_ROBE_3793, Items.FREMENNIK_SKIRT_3795, Items.GLOVES_3799, Items.FREMENNIK_BOOTS_3791, + Items.FREMENNIK_CLOAK_3759, Items.FREMENNIK_CLOAK_3761, Items.FREMENNIK_CLOAK_3763, Items.FREMENNIK_CLOAK_3765, Items.FREMENNIK_CLOAK_3777, Items.FREMENNIK_CLOAK_3779, + Items.FREMENNIK_CLOAK_3781, Items.FREMENNIK_CLOAK_3783, Items.FREMENNIK_CLOAK_3785, Items.FREMENNIK_CLOAK_3787, Items.FREMENNIK_CLOAK_3789, + Items.FREMENNIK_SHIRT_3767, Items.FREMENNIK_SHIRT_3769, Items.FREMENNIK_SHIRT_3771, Items.FREMENNIK_SHIRT_3773, Items.FREMENNIK_SHIRT_3775, + Items.FREMENNIK_BLADE_3757, Items.FREMENNIK_SHIELD_3758) + + private val fremennikIslesDuringQuestEquipment = intArrayOf(Items.YAK_HIDE_ARMOUR_10822, Items.YAK_HIDE_ARMOUR_10824, Items.FREMENNIK_ROUND_SHIELD_10826) + + private val avasBackpacks = intArrayOf(Items.AVAS_ACCUMULATOR_10499, Items.AVAS_ATTRACTOR_10498) + + private val lostCityWeapons = intArrayOf( + Items.DRAGON_DAGGER_1215, + Items.DRAGON_DAGGERP_1231, + Items.DRAGON_DAGGERP_PLUS_5680, + Items.DRAGON_DAGGERP_PLUS_PLUS_5698, + Items.DRAGON_LONGSWORD_1305 + ) + + private val crystalEquipment = intArrayOf( + Items.NEW_CRYSTAL_BOW_4212, + Items.CRYSTAL_BOW_FULL_4214, + Items.CRYSTAL_BOW_9_10_4215, + Items.CRYSTAL_BOW_8_10_4216, + Items.CRYSTAL_BOW_7_10_4217, + Items.CRYSTAL_BOW_6_10_4218, + Items.CRYSTAL_BOW_5_10_4219, + Items.CRYSTAL_BOW_4_10_4220, + Items.CRYSTAL_BOW_3_10_4221, + Items.CRYSTAL_BOW_2_10_4222, + Items.CRYSTAL_BOW_1_10_4223, + Items.NEW_CRYSTAL_SHIELD_4224, + Items.CRYSTAL_SHIELD_FULL_4225, + Items.CRYSTAL_SHIELD_9_10_4226, + Items.CRYSTAL_SHIELD_8_10_4227, + Items.CRYSTAL_SHIELD_7_10_4228, + Items.CRYSTAL_SHIELD_6_10_4229, + Items.CRYSTAL_SHIELD_5_10_4230, + Items.CRYSTAL_SHIELD_4_10_4231, + Items.CRYSTAL_SHIELD_3_10_4232, + Items.CRYSTAL_SHIELD_2_10_4233, + Items.CRYSTAL_SHIELD_1_10_4234 + ) + + //As per the source (https://runescape.wiki/w/Dragon_Slayer?oldid=895396), + //dragon slayer should only restrict green d'hide bodies, not the higher tiers. + private val dragonSlayerEquipment = intArrayOf( + Items.RUNE_PLATEBODY_1127, + Items.RUNE_PLATEBODY_G_10798, + Items.RUNE_PLATEBODY_G_2615, + Items.RUNE_PLATEBODY_G_13800, + Items.RUNE_PLATEBODY_T_10800, + Items.RUNE_PLATEBODY_T_13805, + Items.RUNE_PLATEBODY_T_2623, + Items.ZAMORAK_PLATEBODY_2653, + Items.SARADOMIN_PLATEBODY_2661, + Items.GUTHIX_PLATEBODY_2669, + Items.GREEN_DHIDE_BODY_1135, + Items.DHIDE_BODYG_7370, //Green (g) + Items.DHIDE_BODY_T_7372 //Green (t) + ) + + private val questCapes = intArrayOf(9813,9814) + + private val godBooks = intArrayOf ( + Items.HOLY_BOOK_3840, + Items.UNHOLY_BOOK_3842 + ) + + private val pharaohScepters = (9044..9051).toIntArray() + + private val initiateArmour = (5574..5576).toIntArray() + + private val proselyteArmour = (9672..9678).toIntArray() + + private val spiritShields = (13734..13745).toIntArray() + + override fun defineListeners() { + + /* + onEquip(fremennikIslesEquipment) { player, _ -> + if (!isQuestComplete(player, Quests.THE_FREMENNIK_ISLES)) { + sendMessage(player, "You must have completed The Fremennik Isles to equip this.") + return@onEquip false + } + return@onEquip true + } + + onEquip(fremennikIslesDuringQuestEquipment){ player, _ -> + if (questStage(player, Quests.THE_FREMENNIK_ISLES) > 0) { + sendMessage(player, "You must have started The Fremennik Isles to equip this.") + return@onEquip false + } + return@onEquip true + } + */ + + onEquip(fremennikTrialsEquipment) { player, _ -> + return@onEquip hasRequirement(player, Quests.THE_FREMENNIK_TRIALS) + } + + onEquip(fremennikIslesEquipment) {player, _ -> + return@onEquip hasRequirement(player, Quests.THE_FREMENNIK_ISLES) + } + + onEquip(avasBackpacks){ player, _ -> + return@onEquip hasRequirement(player, Quests.ANIMAL_MAGNETISM) + } + + onEquip(lostCityWeapons){ player, _ -> + return@onEquip hasRequirement(player, Quests.LOST_CITY) + } + + onEquip(Items.CAPE_OF_LEGENDS_1052) { player, _ -> + return@onEquip hasRequirement(player, Quests.LEGENDS_QUEST) + } + + onEquip(questCapes) { player, _ -> + val maxQP = QuestRepository.getQuests().values.sumBy { it.questPoints } + if (player.questRepository.points < maxQP) { + player.packetDispatch.sendMessage("You cannot equip the Quest cape without completing all available quests.") + return@onEquip false + } + return@onEquip true + } + + onEquip(Items.WOLFBANE_2952){ player, _ -> + return@onEquip hasRequirement(player, Quests.PRIEST_IN_PERIL) + } + + onEquip(Items.ANCIENT_MACE_11061){ player, _ -> + return@onEquip hasRequirement(player, Quests.ANOTHER_SLICE_OF_HAM) + } + + onEquip(Items.ANCIENT_STAFF_4675){ player, _ -> + return@onEquip hasRequirement(player, Quests.DESERT_TREASURE) + } + + onEquip(Items.ELEMENTAL_SHIELD_2890) { player, _ -> + return@onEquip hasRequirement(player, Quests.ELEMENTAL_WORKSHOP_I) + } + + onEquip(crystalEquipment){ player, _ -> + return@onEquip hasRequirement(player, Quests.ROVING_ELVES) + } + + onEquip(dragonSlayerEquipment) {player, _ -> + return@onEquip hasRequirement(player, Quests.DRAGON_SLAYER) + } + + onEquip(Items.DRAGON_SCIMITAR_4587) {player, _ -> + return@onEquip hasRequirement(player, Quests.MONKEY_MADNESS) + } + + onEquip(Items.GLOVES_7462) {player, _ -> + return@onEquip hasRequirement(player, Quests.RECIPE_FOR_DISASTER) + } + + onEquip(Items.SLAYER_HELMET_13263) {player, _ -> + return@onEquip hasRequirement(player, Quests.SMOKING_KILLS) + } + + onEquip (Items.DRAGON_HALBERD_3204) {player, _ -> + return@onEquip hasRequirement(player, Quests.REGICIDE) + } + + onEquip (Items.CLIMBING_BOOTS_3105) {player, _ -> + return@onEquip hasRequirement(player, Quests.DEATH_PLATEAU) + } + + onEquip (godBooks) {player, _ -> + return@onEquip hasRequirement(player, Quests.HORROR_FROM_THE_DEEP) + } + + onEquip (pharaohScepters) {player, _ -> + return@onEquip hasRequirement(player, Quests.ICTHLARINS_LITTLE_HELPER) + } + + onEquip (Items.DRAGON_SQ_SHIELD_1187) {player, _ -> + //because I know people won't believe it: https://runescape.wiki/w/Dragon_sq_shield?oldid=899636 + return@onEquip hasRequirement(player, Quests.LEGENDS_QUEST) + } + + onEquip (initiateArmour) {player, _ -> + return@onEquip hasRequirement(player, Quests.RECRUITMENT_DRIVE) + } + + onEquip (proselyteArmour) {player, _ -> + return@onEquip hasRequirement(player, Quests.THE_SLUG_MENACE) + } + + onEquip (spiritShields) {player, _ -> + return@onEquip hasRequirement(player, Quests.SUMMERS_END) + } + + onEquip (Items.DRAGON_MACE_1434) {player, _ -> + return@onEquip hasRequirement(player, Quests.HEROES_QUEST) + } + + onEquip (Items.DRAGON_BATTLEAXE_1377) {player, _ -> + return@onEquip hasRequirement(player, Quests.HEROES_QUEST) + } + + onEquip (Items.DARKLIGHT_6746) {player, _ -> + return@onEquip hasRequirement(player, Quests.SHADOW_OF_THE_STORM) + } + } +} diff --git a/Server/src/main/content/global/handlers/item/LampPlugin.java b/Server/src/main/content/global/handlers/item/LampPlugin.java new file mode 100644 index 0000000..32a091c --- /dev/null +++ b/Server/src/main/content/global/handlers/item/LampPlugin.java @@ -0,0 +1,64 @@ +package content.global.handlers.item; + +import core.game.component.Component; +import content.data.Lamps; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.game.node.entity.skill.Skills; + +/** + * Represents the plugin used for an experience lamp. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class LampPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (Lamps lamp : Lamps.values()) { + lamp.getItem().getDefinition().getHandlers().put("option:rub", this); + } + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + player.setAttribute("lamp", node); + player.setAttribute("caller",this); + player.getInterfaceManager().open(new Component(134).setCloseEvent((player1, c) -> { + player.getInterfaceManager().openDefaultTabs(); + player.removeAttribute("lamp"); + player.unlock(); + return true; + })); + player.getInterfaceManager().removeTabs(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13); + return true; + } + @Override + public void handleSelectionCallback(int skill, Player player){ + Lamps lamp = Lamps.forItem(player.getAttribute("lamp",new Item(2528))); + if(player.getSkills().getStaticLevel(skill) < lamp.getLevelRequirement()){ + player.sendMessage("You need at least " + lamp.getLevelRequirement() + " " + Skills.SKILL_NAME[skill] + " to do this."); + return; + } else { + if(player.getInventory().remove((Item) player.getAttribute("lamp"))) { + if (lamp == Lamps.GENIE_LAMP) { + player.getSkills().addExperience(skill, player.getSkills().getStaticLevel(skill) * 10); + } else { + player.getSkills().addExperience(skill, lamp.getExp()); + } + } + } + } + + @Override + public boolean isWalk() { + return false; + } + +} diff --git a/Server/src/main/content/global/handlers/item/MiningHelmetListener.kt b/Server/src/main/content/global/handlers/item/MiningHelmetListener.kt new file mode 100644 index 0000000..755a1cb --- /dev/null +++ b/Server/src/main/content/global/handlers/item/MiningHelmetListener.kt @@ -0,0 +1,17 @@ +package content.global.handlers.item + +import core.api.* +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import org.rs09.consts.Items + +class MiningHelmetListener : InteractionListener { + override fun defineListeners() { + on(Items.MINING_HELMET_5013, IntType.ITEM, "drop") { player, _ -> + val removed = removeItem(player, Items.MINING_HELMET_5013) + if (removed) produceGroundItem(player, Items.MINING_HELMET_5014) + sendMessage(player, "The helmet goes out as you drop it.") + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/MorphItemPlugin.java b/Server/src/main/content/global/handlers/item/MorphItemPlugin.java new file mode 100644 index 0000000..672de38 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/MorphItemPlugin.java @@ -0,0 +1,113 @@ +package content.global.handlers.item; + +import core.cache.def.impl.ItemDefinition; +import core.game.component.CloseEvent; +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.GameWorld; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.plugin.ClassScanner; +import core.tools.RandomFunction; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playAudio; + +/** + * Handles a morph item. + * @author Vexia + */ +@Initializable +public class MorphItemPlugin implements Plugin { + + /** + * The easter egg ids. + */ + protected static final int[] EASTER_EGG_IDS = new int[] { 3689, 3690, 3691, 3692, 3693, 3694 }; + + /** + * The morph component. + */ + private static final Component COMPONENT = new Component(375).setCloseEvent(new CloseEvent() { + + @Override + public boolean close(Player player, Component c) { + unmorph(player); + return true; + } + + }); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ItemDefinition.forId(7927).getHandlers().put("equipment", this); + ItemDefinition.forId(6583).getHandlers().put("equipment", this); + ClassScanner.definePlugin(new MorphInterfacePlugin()); + return this; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + final Player player = (Player) args[0]; + final Item item = (Item) args[1]; + switch (identifier) { + case "equip": + morph(player, item); + return false; + } + return true; + } + + /** + * Morphs the player. + * @param player the player. + * @param item the item. + */ + private void morph(Player player, Item item) { + int morphId = item.getId() == 6583 ? 2626 : EASTER_EGG_IDS[RandomFunction.random(EASTER_EGG_IDS.length)]; + playAudio(player, 1520); + player.getInterfaceManager().close(); + player.getAppearance().transformNPC(morphId); + player.getInterfaceManager().removeTabs(0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14); + player.getLocks().lockMovement(GameWorld.getTicks() + 900000000); + player.getLocks().lockInteractions(GameWorld.getTicks() + 90000000); + player.getLocks().lockTeleport(GameWorld.getTicks() + 900000000); + player.getInterfaceManager().openSingleTab(COMPONENT); + player.getAppearance().sync(); + player.getWalkingQueue().reset(); + } + + /** + * Unmorphs the player. + * @param player the player. + */ + private static void unmorph(Player player) { + player.getAppearance().transformNPC(-1); + player.unlock(); + player.getInterfaceManager().restoreTabs(); + } + + /** + * Handles the morph interface plugin. + * @author Vexia + */ + public class MorphInterfacePlugin extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.forId(375).setPlugin(this); + return this; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + player.getInterfaceManager().closeSingleTab(); + return true; + } + + } + +} diff --git a/Server/src/main/content/global/handlers/item/NewComerMapPlugin.java b/Server/src/main/content/global/handlers/item/NewComerMapPlugin.java new file mode 100644 index 0000000..cf1cd01 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/NewComerMapPlugin.java @@ -0,0 +1,35 @@ +package content.global.handlers.item; + +import core.cache.def.impl.ItemDefinition; +import core.game.component.Component; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Handles the new comper map. + * @author 'Vexia + */ +@Initializable +public class NewComerMapPlugin extends OptionHandler { + + @Override + public boolean handle(Player player, Node node, String option) { + player.getInterfaceManager().open(new Component(270)); + return true; + } + + @Override + public boolean isWalk() { + return false; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ItemDefinition.forId(550).getHandlers().put("option:read", this); + return this; + } + +} diff --git a/Server/src/main/content/global/handlers/item/NewspaperListener.kt b/Server/src/main/content/global/handlers/item/NewspaperListener.kt new file mode 100644 index 0000000..bb32667 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/NewspaperListener.kt @@ -0,0 +1,80 @@ +package content.global.handlers.item + +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import org.rs09.consts.Items + +/** + * Interaction and interface listener for the Varrock newspaper. + * This handles component(530) globally. + * youtu.be/ePVNOiSzOS4 + */ +class NewspaperListener : InteractionListener { + companion object { + + const val NEWSPAPER_INTERFACE_530 = 530 /* Should be in org.rs09.consts.Components but isn't. */ + + val leftPage = "" + + "Varrock gets " + + "Makeover" + + "

" + + "The city of Varrock " + + "is the latest recipient " + + "of a complete " + + "makeover. When " + + "interviewed, King " + + "Roald said, 'In order " + + "to keep visitors " + + "coming to see the " + + "sights of our " + + "beautiful capital, we " + + "felt that tidying-up " + + "the city would be " + + "more effective than " + + "just issuing a decree " + + "- make sure you visit " + + "the new museum " + + "while you are here.'" + + val rightPage = "" + + "Obituaries " + + "

" + + "Goblin-Died
" + + "Giant Rat-Died
" + + "Unicorn-Died
" + + "Varrock Guard-Died
" + + "Varrock Guard-Died
" + + "Varrock Guard-Died
" + + "Bear-Died." + + "

" + + "Classifieds" + + "

" + + "Lowe's Archery " + + "Emporium for the " + + "finest ranging " + + "weapons in town!" + + "

" + + "Time to party! Visit " + + "the Fancy Dress " + + "Shop for all your " + + "party outfits." + + "

" + + "The Dancing " + + "Donkey - cold beer " + + "always in stock." + } + override fun defineListeners() { + on(Items.NEWSPAPER_11169, IntType.ITEM, "read") { player, _ -> + openInterface(player, NEWSPAPER_INTERFACE_530) + setInterfaceText(player, leftPage ,NEWSPAPER_INTERFACE_530, 7) + setInterfaceText(player, rightPage ,NEWSPAPER_INTERFACE_530, 8) + return@on true + } + + on(Items.AL_KHARID_FLYER_7922, IntType.ITEM, "read") { player, _ -> + sendDialogueLines(player, "Come to the Al Kharid Market place! High quality", "produce at low, low prices! Show this flyer to a", "merchant for money off your next purchase,", "courtesy of Ali Morrisane!") + return@on true + } + } +} diff --git a/Server/src/main/content/global/handlers/item/OysterPlugin.java b/Server/src/main/content/global/handlers/item/OysterPlugin.java new file mode 100644 index 0000000..179072a --- /dev/null +++ b/Server/src/main/content/global/handlers/item/OysterPlugin.java @@ -0,0 +1,41 @@ +package content.global.handlers.item; + +import core.cache.def.impl.ItemDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Plugin; +import core.plugin.Initializable; +import core.tools.RandomFunction; + +/** + * Represents an oyster plugin handler. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class OysterPlugin extends OptionHandler { + + /** + * Represents the oyster items. + */ + private static final Item[] OYSTERS = new Item[] { new Item(409), new Item(411), new Item(413) }; + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ItemDefinition.forId(407).getHandlers().put("option:open", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + player.getInventory().replace(RandomFunction.random(5) < 3 ? OYSTERS[RandomFunction.random(OYSTERS.length - 1)] : OYSTERS[RandomFunction.random(OYSTERS.length)], ((Item) node).getSlot()); + return true; + } + + @Override + public boolean isWalk() { + return false; + } +} diff --git a/Server/src/main/content/global/handlers/item/PetRock.kt b/Server/src/main/content/global/handlers/item/PetRock.kt new file mode 100644 index 0000000..355ea37 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/PetRock.kt @@ -0,0 +1,66 @@ +package content.global.handlers.item + +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength +import core.game.node.entity.impl.Projectile.getLocation +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.tools.END_DIALOGUE +import org.rs09.consts.Items + +class PetRockListener : InteractionListener { + override fun defineListeners() { + on(Items.PET_ROCK_3695, IntType.ITEM, "interact") { player, _ -> + openDialogue(player, PetRockDialogue()) + return@on true + } + } +} + +class PetRockDialogue : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when(stage) { + 0 -> options("Talk", "Stroke", "Feed", "Fetch", "Stay").also { stage++ } + 1 -> when(buttonID) { + 1 -> { + sendPlayerDialogue(player!!, "Who's a good rock, then? Yes, you are! You're such a good rock. Ooga booga googa.", FacialExpression.FRIENDLY) + sendMessage(player!!, "Your rock seems a little happier.") + stage = END_DIALOGUE + } + 2 -> { + end() + sendMessage(player!!, "You stroke your pet rock.") + animate(player!!, 1333, false) + //waits for the animation to finish before sending the message + queueScript(player!!, animationDuration(Animation(1333)), QueueStrength.SOFT) { + sendMessage(player!!, "Your rock seems much happier.") + return@queueScript stopExecuting(player!!) + } + } + 3 -> { + end() + sendMessage(player!!, "You try and feed the rock.") + sendMessage(player!!, "Your rock doesn't seem hungry.") + } + 4 -> { + sendPlayerDialogue(player!!, "Want to fetch the stick, rock? Of course you do.", FacialExpression.FRIENDLY) + face(player!!, Location.getRandomLocation(getLocation(player), 2, true)) + visualize(player!!, 6665, 1157) + spawnProjectile(getLocation(player), Location.getRandomLocation(getLocation(player), 5, true), 1158, 40, 0,150, 250, 25) + stage = END_DIALOGUE + } + 5 -> { + face(player!!, Location.getRandomLocation(getLocation(player), 2, true)) + sendPlayerDialogue(player!!, "Be a good rock...", FacialExpression.FRIENDLY) + sendMessage(player!!, "You wait a few seconds and pick your rock back up and pet it.") + visualize(player!!, anim = 6664, gfx = 1156) + stage = END_DIALOGUE + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/PickupPlugin.java b/Server/src/main/content/global/handlers/item/PickupPlugin.java new file mode 100644 index 0000000..e04d3ed --- /dev/null +++ b/Server/src/main/content/global/handlers/item/PickupPlugin.java @@ -0,0 +1,42 @@ +package content.global.handlers.item; + +import core.cache.def.impl.ItemDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItem; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.game.global.action.PickupHandler; + +/** + * Represents the option handler used for ground items. + * @author Vexia + * @author Emperor + */ +@Initializable +public final class PickupPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ItemDefinition.setOptionHandler("take", this); + return this; + } + + @Override + public boolean handle(final Player player, Node node, String option) { + if (player.getAttributes().containsKey("pickup")) + return false; + //player.setAttribute("pickup", "true"); + boolean handleResult = PickupHandler.take(player, (GroundItem) node); + player.removeAttribute("pickup"); + return handleResult; + } + + @Override + public Location getDestination(Node node, Node item) { + return null; + } + +} diff --git a/Server/src/main/content/global/handlers/item/PlayerPeltables.kt b/Server/src/main/content/global/handlers/item/PlayerPeltables.kt new file mode 100644 index 0000000..931a39e --- /dev/null +++ b/Server/src/main/content/global/handlers/item/PlayerPeltables.kt @@ -0,0 +1,115 @@ +package content.global.handlers.item + +import core.api.* +import core.game.interaction.* +import core.game.node.Node +import core.game.node.entity.impl.Projectile +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.game.world.map.path.Pathfinder +import core.game.world.update.flag.context.Graphics +import org.rs09.consts.Items + + +class PlayerPeltables : InteractionListener { + companion object { + private const val PROJECTILE_DELAY = 41 + private const val PROJECTILE_SPEED = 60 + private const val PROJECTILE_TIME_CONST = .02857 + private const val PROJECTILE_DISTANCE_MULT = 5 + private val PELTABLES = intArrayOf(Items.ROTTEN_TOMATO_2518, Items.SNOWBALL_11951) + } + + + override fun defineListeners() { + onEquip(PELTABLES, ::setPlayerOps) + onUnequip(PELTABLES, ::removePlayerOps) + + on("pelt", IntType.PLAYER, ::handlePeltInteraction) + onUseWithPlayer(*PELTABLES) { player, used, with -> handlePeltInteraction(player, with, used) } + flagInstant() + } + + private fun setPlayerOps(player: Player, _node: Node) : Boolean { + player.interaction.set(Option("Pelt", 0)) + return true + } + + private fun removePlayerOps(player: Player, _node: Node) : Boolean { + InteractPlugin.sendOption(player, 0, "null") + return true + } + + private fun handlePeltInteraction(player: Player, node: Node, usedPeltable: Node? = null) : Boolean { + val peltable = usedPeltable?.asItem() ?: getPeltable(player) ?: return removePlayerOps(player, node) + val gfx = getPeltableGfx(peltable.id) + + val other = node.asPlayer() + + if (!Pathfinder.find(player, other, false, Pathfinder.PROJECTILE).isSuccessful) { + sendDialogue(player, "You can't reach them!") + return true + } + + val distance = player.location.getDistance(other.location) + val projectileSpeed = PROJECTILE_DELAY + PROJECTILE_SPEED + distance * PROJECTILE_DISTANCE_MULT + val hitDelay = (projectileSpeed * PROJECTILE_TIME_CONST).toInt() + + if (removeItem(player, peltable, Container.INVENTORY) || removeItem(player, peltable, Container.EQUIPMENT)) { + lock(player, hitDelay) + submitWorldPulse(PeltingPulse(player, other, gfx, hitDelay, peltable.id)) + } + + return true + } + + class PeltingPulse(val player: Player, val other: Player, val gfx: IntArray, val hitDelay: Int, val peltable: Int) : Pulse() { + private val throwAnimation = getPeltableAnim(peltable) + private var ticks = 0 + override fun pulse(): Boolean { + when (ticks++) { + 0 -> { + player.face(other) + visualize(player, throwAnimation, gfx[0]) + } + 1 -> { + Projectile.create(player, other, gfx[1], 30, 10).send() + face(player, player) //reset face flag lel + unlock(player) + } + hitDelay -> { + if (gfx[2] != -1) other.graphics(Graphics(gfx[2])) + sendMessage(other, "${player.username} has hit you with a ${getItemName(peltable).toLowerCase()}.") + return true + } + } + return false + } + + private fun getPeltableAnim(id: Int) : Int { + return when (id) { + Items.SNOWBALL_11951 -> 7530 + Items.ROTTEN_TOMATO_2518 -> 385 + else -> -1 + } + } + } + + private fun getPeltableGfx(id: Int): IntArray { + return when (id) { + Items.SNOWBALL_11951 -> intArrayOf(-1, 861, 1282) + Items.ROTTEN_TOMATO_2518 -> intArrayOf(-1, 29, 31) + else -> IntArray(3) {-1} + } + } + + private fun getPeltable(player: Player): Item? { + val equipped = getItemFromEquipment(player, EquipmentSlot.WEAPON) ?: return null + val id = equipped.id + + if (id !in PELTABLES) return null + + return equipped + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/RingUnchargePlugin.java b/Server/src/main/content/global/handlers/item/RingUnchargePlugin.java new file mode 100644 index 0000000..7a5140b --- /dev/null +++ b/Server/src/main/content/global/handlers/item/RingUnchargePlugin.java @@ -0,0 +1,57 @@ +package content.global.handlers.item; + +import core.cache.def.impl.ItemDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Handles the uncharging of the four imbued rings. + * @author Splinter + */ +@Initializable +public final class RingUnchargePlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ItemDefinition.forId(14807).getHandlers().put("option:uncharge", this); + ItemDefinition.forId(14808).getHandlers().put("option:uncharge", this); + ItemDefinition.forId(14809).getHandlers().put("option:uncharge", this); + ItemDefinition.forId(14810).getHandlers().put("option:uncharge", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + if(node == null || player == null){ + return true; + } + if(player.getInventory().remove(new Item(node.asItem().getId()))){ + player.getInventory().add(new Item(getReward(node.asItem().getId()), 1)); + } + return true; + } + + /** + * The reward to give. + * @param node + * @return an item ID + */ + private final int getReward(int node){ + switch(node){ + case 14810: + return 6737; + case 14808: + return 6733; + case 14809: + return 6735; + case 14807: + return 6731; + } + return -1; + } + +} diff --git a/Server/src/main/content/global/handlers/item/RunePackPlugin.java b/Server/src/main/content/global/handlers/item/RunePackPlugin.java new file mode 100644 index 0000000..767aa94 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/RunePackPlugin.java @@ -0,0 +1,64 @@ +package content.global.handlers.item; + +import core.cache.def.impl.ItemDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Handles the new OSRS rune packs. + * @author Splinter + */ +@Initializable +public final class RunePackPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ItemDefinition.forId(14730).getHandlers().put("option:open", this); + ItemDefinition.forId(14732).getHandlers().put("option:open", this); + ItemDefinition.forId(14734).getHandlers().put("option:open", this); + ItemDefinition.forId(14736).getHandlers().put("option:open", this); + ItemDefinition.forId(14738).getHandlers().put("option:open", this); + ItemDefinition.forId(14740).getHandlers().put("option:open", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + if(node == null || player == null){ + return true; + } + player.lock(1); + if(player.getInventory().remove(new Item(node.asItem().getId()))){ + player.getInventory().add(new Item(getReward(node.asItem().getId()), 100)); + } + return true; + } + + /** + * The reward to give. + * @param node + * @return an item ID + */ + private final int getReward(int node){ + switch(node){ + case 14730: + return 556; + case 14732: + return 555; + case 14734: + return 557; + case 14736: + return 554; + case 14738: + return 558; + case 14740: + return 562; + } + return 556; + } + +} diff --git a/Server/src/main/content/global/handlers/item/SilverSicklePlugin.java b/Server/src/main/content/global/handlers/item/SilverSicklePlugin.java new file mode 100644 index 0000000..e7529d6 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/SilverSicklePlugin.java @@ -0,0 +1,43 @@ +package content.global.handlers.item; + +import static core.api.ContentAPIKt.*; +import core.cache.def.impl.ItemDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; +import content.region.morytania.quest.naturespirit.NSUtils; +import content.data.Quests; + +/** + * Handles the Silver Sickle (b) to collect Mort Myre Fungus. + * @author Splinter + */ +@Initializable +public final class SilverSicklePlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ItemDefinition.forId(2963).getHandlers().put("option:operate", this); + ItemDefinition.forId(2963).getHandlers().put("option:cast bloom", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + switch (option) { + case "operate": + case "cast bloom": + if(player.getQuestRepository().getQuest(Quests.NATURE_SPIRIT).getStage(player) >= 75) { + player.getPacketDispatch().sendAnimation(9021); + NSUtils.castBloom(player); + } else { + sendDialogue(player, "You must complete Nature Spirit to use this."); + } + return true; + } + return false; + } + +} diff --git a/Server/src/main/content/global/handlers/item/SkullSceptreOption.java b/Server/src/main/content/global/handlers/item/SkullSceptreOption.java new file mode 100644 index 0000000..b2ed703 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/SkullSceptreOption.java @@ -0,0 +1,57 @@ +package content.global.handlers.item; + +import core.cache.def.impl.ItemDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.TeleportManager; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.item.Item; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Handles the skull sceptre options. + * @author 'Vexia + */ +@Initializable +public class SkullSceptreOption extends OptionHandler { + + @Override + public boolean handle(Player player, Node node, String option) { + Item item = (Item) node; + switch (option) { + case "invoke": + if (player.getTeleporter().send(Location.create(3081, 3421, 0), TeleportManager.TeleportType.NORMAL, 1)) { + player.getAchievementDiaryManager().finishTask(player, DiaryType.VARROCK, 2, 12); + item.setCharge(item.getCharge() - 200); + if (item.getCharge() < 1) { + player.getInventory().remove(item); + player.getPacketDispatch().sendMessage("Your staff crumbles to dust as you use its last charge."); + } + } + break; + case "divine": + if (item.getCharge() < 1) { + player.getPacketDispatch().sendMessage("You don't have enough charges left."); + return true; + } + player.getPacketDispatch().sendMessage("Concentrating deeply, you divine that the sceptre has " + (item.getCharge() / 200) + " charges left."); + break; + } + return true; + } + + @Override + public boolean isWalk() { + return false; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ItemDefinition.forId(9013).getHandlers().put("option:invoke", this); + ItemDefinition.forId(9013).getHandlers().put("option:divine", this); + return this; + } +} diff --git a/Server/src/main/content/global/handlers/item/SpadeDigListener.kt b/Server/src/main/content/global/handlers/item/SpadeDigListener.kt new file mode 100644 index 0000000..4d9bad6 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/SpadeDigListener.kt @@ -0,0 +1,21 @@ +package content.global.handlers.item + +import core.game.node.entity.player.Player +import core.game.world.map.Location + +object SpadeDigListener { + val listeners = HashMap Unit>() + + fun registerListener(location: Location, method: (Player) -> Unit){ + listeners.putIfAbsent(location,method) + } + + @JvmStatic + fun runListener(location: Location,player: Player): Boolean { + if(listeners.containsKey(location)){ + listeners[location]?.invoke(player) + return true + } + return false + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/SpadeDigOptionPlugin.java b/Server/src/main/content/global/handlers/item/SpadeDigOptionPlugin.java new file mode 100644 index 0000000..70d478f --- /dev/null +++ b/Server/src/main/content/global/handlers/item/SpadeDigOptionPlugin.java @@ -0,0 +1,42 @@ +package content.global.handlers.item; + +import core.cache.def.impl.ItemDefinition; +import core.game.global.action.DigSpadeHandler; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playAudio; + +/** + * Represents the plugin used to handle the dig option on a spade. + * @author 'Vexia + * @author Emperor + */ +@Initializable +public class SpadeDigOptionPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ItemDefinition.forId(952).getHandlers().put("option:dig", this); + return null; + } + + @Override + public boolean handle(final Player player, Node node, String option) { + playAudio(player, Sounds.DIGSPADE_1470); + if (!DigSpadeHandler.dig(player)) { + player.sendMessage("You dig but find nothing."); + } + return true; + } + + @Override + public boolean isWalk() { + return false; + } + +} diff --git a/Server/src/main/content/global/handlers/item/StaffOfTheRaven.kt b/Server/src/main/content/global/handlers/item/StaffOfTheRaven.kt new file mode 100644 index 0000000..90c2e7f --- /dev/null +++ b/Server/src/main/content/global/handlers/item/StaffOfTheRaven.kt @@ -0,0 +1,71 @@ +package content.global.handlers.item + +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.world.update.flag.context.Graphics +import core.game.dialogue.DialogueFile +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.tools.END_DIALOGUE + +/** + * Handles the Staff of the Raven's (2021 Hween Reward) Recolor Transformation + */ +class StaffOfTheRaven : InteractionListener { + val ids = intArrayOf(14654, 14655, 14656) + override fun defineListeners() { + on(ids, IntType.ITEM, "recolor", "operate"){ player, node -> + val hasUnlocked = player.getAttribute("sotr:purchased",false) + val hasRecolorA = player.getAttribute("sotr:recolor1", false) + val hasRecolorB = player.getAttribute("sotr:recolor2", false) + val isBase = node.id == 14654 + val isOperate = getUsedOption(player) == "operate" + + if(!hasUnlocked){ + //Remove the item if the player has not purchased it. Just in case. + switchStaff(player, null, isOperate, node.asItem()) + return@on true + } + + if(!isBase){ + switchStaff(player, 14654, isOperate, node.asItem()) + return@on true + } + + player.dialogueInterpreter.open(object : DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + if(!hasRecolorA && !hasRecolorB){ + dialogue("You do not have any recolors unlocked.") + stage = END_DIALOGUE + } else if(hasRecolorA && !hasRecolorB){ + switchStaff(player, 14655, isOperate, node.asItem()) + } else if(hasRecolorB && !hasRecolorA){ + switchStaff(player, 14656, isOperate, node.asItem()) + } else { + when (stage) { + 0 -> options("Purple", "Orange").also { stage++ } + 1 -> when (buttonID) { + 1 -> switchStaff(player, 14655, isOperate, node.asItem()) + 2 -> switchStaff(player, 14656, isOperate, node.asItem()) + else -> { } + }.also { end() } + } + } + } + }) + return@on true + } + } + + fun switchStaff(player: Player, to: Int?, equipped: Boolean, original: Item){ + player.graphics(Graphics(1119)) + val item: Item? = if(to != null) Item(to) else to + + if(equipped){ + player.equipment.replace(item, original.slot) + } else { + player.inventory.replace(item, original.slot) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/StarterPackPlugin.java b/Server/src/main/content/global/handlers/item/StarterPackPlugin.java new file mode 100644 index 0000000..152b12e --- /dev/null +++ b/Server/src/main/content/global/handlers/item/StarterPackPlugin.java @@ -0,0 +1,53 @@ +package content.global.handlers.item; + +import core.cache.def.impl.ItemDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * The plugin used for the free to play starter pack item + * @author Splinter + * + */ +@Initializable +public final class StarterPackPlugin extends OptionHandler { + + /** + * The item from the starter pack. + */ + private static final Item[] ITEMS = { new Item(558, 50), new Item(556, 50), new Item(1379, 1), new Item(740, 1), new Item(882, 100), new Item(1167, 1), new Item(1129, 1), new Item(1095, 1), new Item(1063, 1), new Item(1363, 1), new Item(1323, 1), new Item(1267, 1), new Item(1349, 1), new Item(1153, 1), new Item(1101, 1), new Item(1067, 1), new Item(1175, 1), new Item(841, 1)}; + + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ItemDefinition.forId(14775).getHandlers().put("option:open", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + switch (option) { + case "open": + if(player.getInventory().freeSlots() >= ITEMS.length){ + if (player.getInventory().remove((Item) node)) { + player.getInventory().add(ITEMS); + return true; + } + } else { + player.sendMessage("You need "+(ITEMS.length - player.getInventory().freeSlots())+" more free inventory slot(s) to open the box."); + return true; + } + break; + } + return true; + } + + @Override + public boolean isWalk() { + return false; + } +} diff --git a/Server/src/main/content/global/handlers/item/TeleTabsListener.kt b/Server/src/main/content/global/handlers/item/TeleTabsListener.kt new file mode 100644 index 0000000..9cc72f6 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/TeleTabsListener.kt @@ -0,0 +1,69 @@ +package content.global.handlers.item + +import content.region.kandarin.ardougne.quest.plaguecity.PlagueCityListeners.Companion.ARDOUGNE_TELE_ATTRIBUTE +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.TeleportManager +import core.game.node.item.Item +import core.game.world.map.Location + +class TeleTabsListener : InteractionListener { + + enum class TeleTabs(val item: Int, val location: Location, val exp: Double, val requirementCheck: (Player) -> Boolean = { true }) { + ADDOUGNE_TELEPORT(8011, Location.create(2662, 3307, 0), 61.0, { + player -> getAttribute(player, ARDOUGNE_TELE_ATTRIBUTE, false) + }), + AIR_ALTAR_TELEPORT(13599, Location.create(2978, 3296, 0), 0.0), + ASTRAL_ALTAR_TELEPORT(13611, Location.create(2156, 3862, 0), 0.0), + BLOOD_ALTAR_TELEPORT(13610, Location.create(3559, 9778, 0), 0.0), + BODY_ALTAR_TELEPORT(13604, Location.create(3055, 3443, 0), 0.0), + CAMELOT_TELEPORT(8010, Location.create(2757, 3477, 0), 55.5), + CHAOS_ALTAR_TELEPORT(13606, Location.create(3058, 3593, 0), 0.0), + COSMIC_ALTAR_TELEPORT(13605, Location.create(2411, 4380, 0), 0.0), + DEATH_ALTAR_TELEPORT(13609, Location.create(1863, 4639, 0), 0.0), + EARTH_ALTAR_TELEPORT(13602, Location.create(3304, 3472, 0), 0.0), + FALADOR_TELEPORT(8009, Location.create(2966, 3380, 0), 47.0), + FIRE_ALTAR_TELEPORT(13603, Location.create(3311, 3252, 0), 0.0), + LAW_ALTAR_TELEPORT(13608, Location.create(2857, 3378, 0), 0.0), + LUMBRIDGE_TELEPORT(8008, Location.create(3222, 3218, 0), 41.0), + MIND_ALTAR_TELEPORT(13600, Location.create(2979, 3510, 0), 0.0), + NATURE_ALTAR_TELEPORT(13607, Location.create(2868, 3013, 0), 0.0), + VARROCK_TELEPORT(8007, Location.create(3212, 3423, 0), 35.00), + WATCH_TOWER_TELEPORT(8012, Location.create(2548, 3114, 0), 68.00), + WATER_ALTAR_TELEPORT(13601, Location.create(3182, 3162, 0), 0.0); + + companion object { + val idMap = values().map { it.item to it }.toMap() + fun forId(id: Int): TeleTabs? { + return idMap[id] + } + } + } + + override fun defineListeners() { + val tabIDs = TeleTabs.values().map { it.item }.toIntArray() + on(tabIDs, IntType.ITEM, "break") {player, node -> + val tab = node.id + val tabEnum = TeleTabs.forId(tab) + if (tabEnum != null && inInventory(player,tab)) { + val tabloc = tabEnum.location + if (inInventory(player, tab)) { + if (tabEnum.requirementCheck(player)){ + if (teleport(player, tabloc, TeleportManager.TeleportType.TELETABS)) { + removeItem(player, Item(node.id, 1)) + } + } + else { + when (tabEnum){ + TeleTabs.ADDOUGNE_TELEPORT -> sendMessage(player, "You need to complete Plague City to use this tablet.") + else -> sendMessage(player, "You do not have the requirements to use this tablet.") + } + } + } + } + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/TeleportCrystalPlugin.java b/Server/src/main/content/global/handlers/item/TeleportCrystalPlugin.java new file mode 100644 index 0000000..5bbda0f --- /dev/null +++ b/Server/src/main/content/global/handlers/item/TeleportCrystalPlugin.java @@ -0,0 +1,151 @@ +package content.global.handlers.item; + +import core.cache.def.impl.ItemDefinition; +import core.plugin.Initializable; +import core.game.dialogue.DialoguePlugin; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.TeleportManager.TeleportType; +import core.game.node.item.Item; +import core.game.world.map.Location; +import core.game.world.map.zone.impl.WildernessZone; +import core.plugin.Plugin; + +import static core.api.ContentAPIKt.hasRequirement; +import content.data.Quests; + +/** + * Represents the rotten potato plugin. + * @author 'Vexia + */ +@Initializable +public final class TeleportCrystalPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ItemDefinition.forId(6099).getHandlers().put("option:activate", this); + ItemDefinition.forId(6100).getHandlers().put("option:activate", this); + ItemDefinition.forId(6101).getHandlers().put("option:activate", this); + ItemDefinition.forId(6102).getHandlers().put("option:activate", this); + new TeleportCrystalDialogue().init(); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + if (!hasRequirement(player, Quests.MOURNINGS_END_PART_I)) + return true; + if (!WildernessZone.checkTeleport(player, 20)) { + player.getPacketDispatch().sendMessage("The crystal is unresponsive."); + return true; + } + player.getDialogueInterpreter().open(TeleportCrystalDialogue.ID, 1, node.asItem().getId()); + //degrade(player, node.asItem()); + return true; + } + + + @Override + public boolean isWalk() { + return false; + } + + + + /** + * Represents the rotten potato dialogue. + * @author 'Vexia + * @version 1.0 + */ + public static final class TeleportCrystalDialogue extends DialoguePlugin { + + /** + * Represents the rotten potato dialogue id. + */ + public static final int ID = 3999111; + private Integer itemId; + + /** + * Constructs a new {@code RottenPotatoDialogue} {@code Object}. + */ + public TeleportCrystalDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code RottenPotatoDialogue} {@code Object}. + * @param player the player. + */ + public TeleportCrystalDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new TeleportCrystalDialogue(player); + } + + @Override + public boolean open(Object... args) { + itemId = (Integer) args[1]; + switch ((Integer) args[0]) { + case 1: + interpreter.sendOptions("Select an Option", "Teleport to Lletya", "Cancel"); + stage = 100; + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + NPC npc = new NPC(2376); + NPC billTeach = new NPC(3155); + switch (stage) { + case 100: + switch(buttonId) { + case 1: + player.getTeleporter().send(new Location(2329, 3172), TeleportType.NORMAL); + degrade(player, new Item(itemId)); + break; + case 2: + end(); + break; + } + break; + } + return true; + } + + + /** + * Degrades the crystal from use. + * @param p the player + * @param item the crystal used + */ + private static void degrade(Player p, Item item) { + int id = item.getId(); + int newItem = item.getId() + 1; + if (id < 6102) { + p.getInventory().remove(new Item(id, 1)); + p.getInventory().add(new Item(newItem, 1)); + p.getPacketDispatch().sendMessage("Your teleportation crystal has degraded from use."); + } else { + p.getInventory().remove(new Item(id, 1)); + p.getInventory().add(new Item(newItem, 1)); + p.getPacketDispatch().sendMessages("Your teleportation crystal has degraded to a tiny elf crystal,", "Eluned can re-enchant it."); + } + } + + @Override + public int[] getIds() { + return new int[] { ID }; + } + + } + +} diff --git a/Server/src/main/content/global/handlers/item/ToyHorseyListener.kt b/Server/src/main/content/global/handlers/item/ToyHorseyListener.kt new file mode 100644 index 0000000..e16a39e --- /dev/null +++ b/Server/src/main/content/global/handlers/item/ToyHorseyListener.kt @@ -0,0 +1,41 @@ +package content.global.handlers.item + +import core.api.animate +import core.api.sendChat +import core.api.stopWalk +import org.rs09.consts.Animations +import org.rs09.consts.Items +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +/** + * Interaction listener for the Toy Horsey item + * @author Woah + */ +class ToyHorseListener : InteractionListener { + + // Map of horse item ids to their correct emote + val HORSEY_MAP = mapOf( + Items.TOY_HORSEY_2520 to Animations.HUMAN_PLAY_WITH_BROWN_HORSE_918, + Items.TOY_HORSEY_2522 to Animations.HUMAN_PLAY_WITH_WHITE_HORSE_919, + Items.TOY_HORSEY_2524 to Animations.HUMAN_PLAY_WITH_BLACK_HORSE_920, + Items.TOY_HORSEY_2526 to Animations.HUMAN_PLAY_WITH_GRAY_HORSE_921 + ) + + // Array of phrases used during the interaction + val PHRASES = arrayOf( + "Come-on Dobbin, we can win the race!", + "Hi-ho Silver, and away", + "Neaahhhyyy! Giddy-up horsey!" + ) + + override fun defineListeners() { + on(HORSEY_MAP.keys.toIntArray(), IntType.ITEM, "play-with") { player, node -> + // "high-priority" interaction, so movement is stopped + stopWalk(player) + animate(player, HORSEY_MAP.get(node.id)) + sendChat(player, PHRASES.random()) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/ToyListeners.kt b/Server/src/main/content/global/handlers/item/ToyListeners.kt new file mode 100644 index 0000000..edf14fa --- /dev/null +++ b/Server/src/main/content/global/handlers/item/ToyListeners.kt @@ -0,0 +1,136 @@ +package content.global.handlers.item + +import core.api.* +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import org.rs09.consts.Items +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import kotlinx.coroutines.delay +import org.rs09.consts.Sounds +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking + + + +class ToyListeners : InteractionListener { + companion object { + val MARIONETTES = intArrayOf(Items.RED_MARIONETTE_6867, Items.GREEN_MARIONETTE_6866, Items.BLUE_MARIONETTE_6865) + private val MARIONETTE_JUMP = Animation(3003) + private val MARIONETTE_WALK = Animation(3004) + private val MARIONETTE_BOW = Animation(3005) + private val MARIONETTE_DANCE = Animation(3006) + private val MARIONETTE_GFX = + arrayOf(intArrayOf(507, 508, 509, 510), intArrayOf(511, 512, 513, 514), intArrayOf(515, 516, 517, 518)) + private val SNOWGLOBE_SHAKE = Animation(7535) //Initial Shake + private val SNOWGLOBE_HOLDFACE = Animation(7536) //Immediately after shake, player holds the snow globe to face + private val SNOWGLOBE_INTERFACE = + 659 //After HOLDFACE this interface is displayed, player either clicks 'continue' for inv of snowballs, or 'close' for no snowballs + private val SNOWGLOBE_DOWNFAST = Animation(7537) //Used when player hit 'close' on the interface + private val SNOWGLOBE_DOWNSLOW = Animation(7538) //Used when the player hit 'continue' on the interface + private val SNOWGLOBE_STOMP = Animation(7528) //When player hits continue this animation plays + private val SNOWGLOBE_SNOW = Graphics(1284) //When Animation STOMP is playing this gfx also plays + private val SPINNING_PLATE_SPIN = Animation(1902) + private val SPINNING_PLATE_PUT_DOWN = Animation(1904) + private val TOY_KITE_FLY = Animation(8990) + val YOYO_PLAY = Animation(1457) + val YOYO_LOOP = Animation(1458) + val YOYO_WALK = Animation(1459) + val YOYO_CRAZY = Animation(1460) + val ZOMBIE_HEAD_TALK_AT = Animation(2840) + val ZOMBIE_HEAD_DISPLAY = Animation(2844) + } + + override fun defineListeners() { + on(Items.CHOCATRICE_CAPE_12645, IntType.ITEM, "operate") { player, _ -> + lockInteractions(player, 2) + visualize(player, 8903, 1566) + return@on true + } + + on(MARIONETTES, IntType.ITEM, "jump", "walk", "bow", "dance") { player, marionette -> + val index = MARIONETTES.indexOf(marionette.id) + + lockInteractions(player, 2) + when (getUsedOption(player)) { + "jump" -> visualize(player, MARIONETTE_JUMP, MARIONETTE_GFX[index][0]) + "walk" -> visualize(player, MARIONETTE_WALK, MARIONETTE_GFX[index][1]) + "bow" -> visualize(player, MARIONETTE_BOW, MARIONETTE_GFX[index][2]) + "dance" -> visualize(player, MARIONETTE_DANCE, MARIONETTE_GFX[index][3]) + } + return@on true + } + + on(Items.REINDEER_HAT_10507, IntType.ITEM, "operate") { player, _ -> + lockInteractions(player, 2) + visualize(player, 5059, 859) + return@on true + } + + on(Items.SNOW_GLOBE_11949, IntType.ITEM, "shake") { player, _ -> + lockInteractions(player, 2) + animate(player, SNOWGLOBE_SHAKE) + runTask(player, 3) { + animate(player, SNOWGLOBE_HOLDFACE) + runTask(player) { + openInterface(player, SNOWGLOBE_INTERFACE) + } + } + return@on true + } + + on(Items.SPINNING_PLATE_4613, IntType.ITEM, "spin") { player, _ -> + lockInteractions(player, 2) + animate(player, SPINNING_PLATE_SPIN) + runTask(player, 2) { + animate(player, SPINNING_PLATE_PUT_DOWN) + } + return@on true + } + + on(Items.TOY_KITE_12844, IntType.ITEM, "fly","operate") { player, _ -> + lockInteractions(player, 2) + animate(player, TOY_KITE_FLY) + return@on true + } + + on(Items.YO_YO_4079, IntType.ITEM, "play", "loop", "walk", "crazy") { player, _ -> + val option = getUsedOption(player) + + lockInteractions(player, 2) + when (option) { + "play" -> animate(player, YOYO_PLAY) + "loop" -> animate(player, YOYO_LOOP) + "walk" -> animate(player, YOYO_WALK) + "crazy" -> animate(player, YOYO_CRAZY) + } + return@on true + } + + on(Items.ZOMBIE_HEAD_6722, IntType.ITEM, "talk-at", "display", "question") { player, _ -> + val option = getUsedOption(player) + + lockInteractions(player, 2) + when (option) { + "talk-at" -> { + animate(player, ZOMBIE_HEAD_TALK_AT) + sendChat(player, "Alas!") + } + + "display" -> { + animate(player, ZOMBIE_HEAD_DISPLAY) + sendChat(player, "MWAHAHAHAHAHAHAH") + } + } + return@on true + } + on(Items.RUBBER_CHICKEN_4566, IntType.ITEM, "operate", "Dance") { player, _ -> + lockInteractions(player, 2) + visualize(player, 1835, -1) + playJingle(player, 99); + playAudio(player, 355, 100); + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/book/GeneralRuleBook.kt b/Server/src/main/content/global/handlers/item/book/GeneralRuleBook.kt new file mode 100644 index 0000000..12a6be0 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/book/GeneralRuleBook.kt @@ -0,0 +1,209 @@ +package content.global.handlers.item.book + +import content.global.handlers.iface.BookInterface +import content.global.handlers.iface.BookLine +import content.global.handlers.iface.Page +import content.global.handlers.iface.PageSet +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.game.world.GameWorld +import org.rs09.consts.Items + +/** + * General Rule Book + * This is not an item book, but opened when asking a Town Crier for the Rules + * @author ovenbreado + * @author 'Vexia + */ +class GeneralRuleBook { + companion object { + private const val BLUE = "" + private val SERVER_NAME = GameWorld.settings!!.name + private val TITLE = "$SERVER_NAME Rules" + private val CONTENTS = arrayOf( + PageSet( + Page( + BookLine("Rules", 38), + BookLine("1 - Offensive Language", 104), + BookLine("2 - Item Scamming", 106), + BookLine("3 - Password Scamming", 108), + BookLine("4 - Cheating/Bug Abuse", 110), + BookLine("5 - Staff Impersonation", 112), + BookLine("6 - Account Sharing/Trading", 114), + BookLine("7 - Using Third Party", 116), + BookLine("Software", 118), + BookLine("8 - Multi Logging-in", 120), + BookLine("9 - Encouraging Others to", 122), + BookLine("Break Rules", 124), + BookLine("10 - False Representation", 126), + BookLine("11 - Website Advertising", 128) + ), + Page( + BookLine("12 - Read World Item", 134), + BookLine("Trading", 136), + BookLine("13 - Asking For Personal", 138), + BookLine("Details", 140), + BookLine("14 - Misuse of Official", 142), + BookLine("Forums", 144), + BookLine("15 - Advert Blocking", 146) + ) + ), + PageSet( + Page( + BookLine(BLUE + "1 - Offensive Language", 38), + BookLine("You must not use any", 40), + BookLine("language which is offensive,", 41), + BookLine("racist or obscene. Remember,", 42), + BookLine("it's nice to be nice!", 43) + ), Page( + BookLine(BLUE + "2 - Item Scamming", 53 ), + BookLine("You must not scam or", 55), + BookLine("deceive other players. This", 56), + BookLine("includes claiming that items", 57), + BookLine("are rare when they are not,", 58), + BookLine("team scamming or telling", 59), + BookLine("players that you can", 60), + BookLine("upgrade' their armour in", 61), + BookLine("any way!", 62) + ) + ), + PageSet( + Page( + BookLine(BLUE + "3 - Password Scamming", 38), + BookLine("Asking for - or trying to", 40), + BookLine("obtain - another player's", 41), + BookLine("password in any way will not", 42), + BookLine("be tolerated, even in jest!", 43) + ), Page( + BookLine(BLUE + "4 - Cheating/Bug Abuse", 53), + BookLine("A bug is a technical glitch", 55), + BookLine("found in the game. You", 56), + BookLine("must not use or attempt to", 57), + BookLine("use any cheats or errors that", 58), + BookLine("you find in our software.", 59), + BookLine("Any bugs found must be", 60), + BookLine("reported to " + SERVER_NAME, 61), + BookLine("immediately, by clicking the", 62), + BookLine("'Report a bug/fault' link", 63), + BookLine("found on the main page.", 64) + ) + ), + PageSet( + Page( + BookLine(BLUE + "5 - Staff Impersonation", 38), + BookLine("You should not attempt to", 40), + BookLine("impersonate " + SERVER_NAME + " staff in", 41), + BookLine("any way.", 42) + ), Page( + BookLine(BLUE + "6 - Account Sharing/Trading", 53), + BookLine("Each account should only be", 55), + BookLine("used by ONE person and", 56), + BookLine("ONE person alone.", 57), + BookLine("Remember that trying to", 58), + BookLine("buy, sell, borrow or give", 59), + BookLine("away an account is against", 60), + BookLine("the rules and will land you in", 61), + BookLine("trouble when caught!", 62) + ) + ), + PageSet( + Page( + BookLine( + BLUE + "7 - Using Third Party
" + BLUE + "Software

You must not use other
programs to gain an unfair
advantage in the game.", + 38 + ) + ), Page( + BookLine( + BLUE + "8 - Multi Logging-in

If you create more than one
" + SERVER_NAME + " account, they
must not interact. This
includes giving items to a
friend to transfer to another
account you own.", + 53 + ) + ) + ), + PageSet( + Page( + BookLine( + BLUE + "9 - Encouraging Others to
" + BLUE + "Break Rules

You must not encourage
others to break any of the
" + SERVER_NAME + " rules.", + 38 + ), BookLine( + BLUE + "10 - False Representation

You must not misuse
" + SERVER_NAME + " Customer
Support.Trying to get
another player into trouble
by reporting them for no
reason or framing them is an
abuse of the Customer
Support Team's service.
want to help as many
players as possible and so the
Customer Support Team's
service must be used
appropriately and treated with", + 53 + ) + ) + ), + PageSet( + Page( + BookLine("respect at all times.", 38), + BookLine( + BLUE + "11 - Website Advertising

You are not allowed to
actively advertise any
websites, fan-sites, IRC
channels or product
anywhere in " + SERVER_NAME + ",
including the " + SERVER_NAME + "
forums.", + 53 + ) + ), Page() + ), + PageSet( + Page( + BookLine( + BLUE + "12 - Real World Item
" + BLUE + "Trading

" + SERVER_NAME + " items must only
be exchanged for other items
or service within the game.
Buying or selling items
outside of the " + SERVER_NAME + "
environment is not in the
spirit of the game and is easy
for " + SERVER_NAME + " to trace!", + 38 + ), BookLine( + BLUE + "13 - Asking for Personal
" + BLUE + "Details

To protect player's safety
and privacy, you must not
ask for personal details. This
includes full names, phone
numbers, MSN, AIM, email
and home/school addresses!", + 53 + ) + ) + ), + PageSet( + Page( + BookLine( + BLUE + "14 - Misuse of Official
" + BLUE + "Forums

Forums must be used in
accordance with the Forum
Code of Conduct and treated
with respect at all times.", + 38 + ), BookLine( + BLUE + "15 - Advert Blocking

Blocking the adverts in the
free to play version of
" + SERVER_NAME + " is against the
rules.", + 53 + ) + ) + ) + ) + private fun display(player: Player, pageNum: Int, buttonID: Int) : Boolean { + if (pageNum == 0) { + when (buttonID) { + 104 -> setAttribute(player, "bookInterfaceCurrentPage", 1) + 106 -> setAttribute(player, "bookInterfaceCurrentPage", 1) + 108 -> setAttribute(player, "bookInterfaceCurrentPage", 2) + 110 -> setAttribute(player, "bookInterfaceCurrentPage", 2) + 112 -> setAttribute(player, "bookInterfaceCurrentPage", 3) + 114 -> setAttribute(player, "bookInterfaceCurrentPage", 3) + 116 -> setAttribute(player, "bookInterfaceCurrentPage", 4) + 118 -> setAttribute(player, "bookInterfaceCurrentPage", 4) + 120 -> setAttribute(player, "bookInterfaceCurrentPage", 4) + 122 -> setAttribute(player, "bookInterfaceCurrentPage", 5) + 124 -> setAttribute(player, "bookInterfaceCurrentPage", 5) + 126 -> setAttribute(player, "bookInterfaceCurrentPage", 5) + 128 -> setAttribute(player, "bookInterfaceCurrentPage", 6) + 134 -> setAttribute(player, "bookInterfaceCurrentPage", 7) + 136 -> setAttribute(player, "bookInterfaceCurrentPage", 7) + 138 -> setAttribute(player, "bookInterfaceCurrentPage", 7) + 140 -> setAttribute(player, "bookInterfaceCurrentPage", 7) + 142 -> setAttribute(player, "bookInterfaceCurrentPage", 8) + 144 -> setAttribute(player, "bookInterfaceCurrentPage", 8) + 146 -> setAttribute(player, "bookInterfaceCurrentPage", 8) + } + } else { + when (buttonID) { + 159 -> setAttribute(player, "bookInterfaceCurrentPage", 0) + } + } + BookInterface.pageSetup(player, BookInterface.FANCY_BOOK_2_27, TITLE, CONTENTS) + if (getAttribute(player,"bookInterfaceCurrentPage", 0) != 0) { + player.packetDispatch.sendInterfaceConfig(BookInterface.FANCY_BOOK_2_27, 159, false) + player.packetDispatch.sendString("Index", BookInterface.FANCY_BOOK_2_27, 159) + } + return true + } + + /** Since the Town Crier shows you the book, there is no item here. */ + fun openBook(player: Player) { + BookInterface.openBook(player, BookInterface.FANCY_BOOK_2_27, ::display) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/book/GoblinBook.kt b/Server/src/main/content/global/handlers/item/book/GoblinBook.kt new file mode 100644 index 0000000..5f9661f --- /dev/null +++ b/Server/src/main/content/global/handlers/item/book/GoblinBook.kt @@ -0,0 +1,252 @@ +package content.global.handlers.item.book + +import content.global.handlers.iface.BookInterface +import content.global.handlers.iface.BookLine +import content.global.handlers.iface.Page +import content.global.handlers.iface.PageSet +import core.ServerConstants +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import org.rs09.consts.Items + +/** + * Goblin Book + * https://youtu.be/6tdNqNa4zGw?t=155 April 23, 2009 + * @author ovenbreado + */ +class GoblinBook : InteractionListener { + companion object { + private const val RED = "" + private val TITLE = "The Book of the Big High War God" + private val CONTENTS = arrayOf( + PageSet( + Page( + BookLine(RED + "The Creation of the Goblins", 97), + BookLine("", 68), + BookLine("In beginning all gods have", 69), + BookLine("big war. Each god find army", 70), + BookLine("to fight for him.", 71), + BookLine("", 72), + BookLine("Big High War God not have", 73), + BookLine("army. Big High War God go", 74), + BookLine("to beardy-short-people and", 75), + BookLine("ask, Will you fight in my", 76), + BookLine("army? But beardy-short-", 77), + BookLine("people say, No, we fight for", 78), + BookLine("God of Shiny Light.", 79), + BookLine("", 80), + BookLine("Then Big High War God go", 81), + ), + Page( + BookLine("to demons and ask, Will you", 82), + BookLine("fight in my army? But", 83), + BookLine("demons say, No, we fight for", 84), + BookLine("God of Dark Fire.", 85), + BookLine("", 86), + BookLine("Then Big High War God go", 87), + BookLine("to tall people with keen blades", 88), + BookLine("and say, Will you fight in", 89), + BookLine("my army? But tall people", 90), + BookLine("with keen blades say, No,", 91), + BookLine("some of us fight for God of", 92), + BookLine("Shiny Light and some of us", 93), + BookLine("fight for God of Dark Fire,", 94), + BookLine("but none of us fight for you!", 95), + BookLine("", 96), + ), + ), + PageSet( + Page( + BookLine("Big High War God very sad.", 97), + BookLine("He travel east and west,", 68), + BookLine("north and south, across land", 69), + BookLine("looking for army to fight for", 70), + BookLine("him.", 71), + BookLine("", 72), + BookLine("Then goblins say, We fight", 73), + BookLine("for you! At that time goblins", 74), + BookLine("very weak, very small, soft", 75), + BookLine("skin. Not like goblins today!", 76), + BookLine("But Big High War God say,", 77), + BookLine("I will make you my army.", 78), + BookLine("So Big High War God train", 79), + BookLine("goblins so they very strong.", 80), + BookLine("He give them good armour", 81), + ), + Page( + BookLine("so they not be harmed. He", 82), + BookLine("make them strong in spirit so", 83), + BookLine("they not afraid of battle. He", 84), + BookLine("give them commanders so", 85), + BookLine("they know which way to go.", 86), + BookLine("He divide goblins into twelve", 87), + BookLine("tribes and send them into", 88), + BookLine("battle!", 89), + BookLine("", 90), + BookLine("Goblin armies fight very", 91), + BookLine("good! When other gods see", 92), + BookLine("this, they very jealous. So", 93), + BookLine("they say, We want goblins to", 94), + BookLine("fight for us too! So Big High", 95), + BookLine("War God take some tribes", 96), + ), + ), + PageSet( + Page( + BookLine("and sell them, one to God of", 97), + BookLine("Shiny Light and one to God", 68), + BookLine("of Dark Fire, and other", 69), + BookLine("tribes to other gods. But", 70), + BookLine("most still worship Big High", 71), + BookLine("War God who created them!", 72), + BookLine("", 73), + BookLine("", 74), + BookLine("", 75), + BookLine("", 76), + BookLine("", 77), + BookLine("", 78), + BookLine("", 79), + BookLine("", 80), + BookLine("", 81), + ), + Page( + BookLine(RED + "The Several Commandments", 82), + BookLine("", 83), + BookLine("These are commands of Big", 84), + BookLine("High War God! Obey all", 85), + BookLine("commands all time or Big", 86), + BookLine("High War God kill you very", 87), + BookLine("bad!", 88), + BookLine("", 89), + BookLine("Always to slay enemies of", 90), + BookLine("Big High War God. Enemies", 91), + BookLine("must die!", 92), + BookLine("", 93), + BookLine("Not to run from battle.", 94), + BookLine("Cowards must die!", 95), + BookLine("", 96), + ), + ), + PageSet( + Page( + BookLine("Not to show mercy. Merciful", 97), + BookLine("must die!", 68), + BookLine("", 69), + BookLine("Not to doubt Big High War", 70), + BookLine("God. Doubters must die!", 71), + BookLine("", 72), + BookLine("Not to make own plans.", 73), + BookLine("Thinkers must die!", 74), + BookLine("", 75), + BookLine("", 76), + BookLine("", 77), + BookLine("", 78), + BookLine("", 79), + BookLine("", 80), + BookLine("", 81), + ), + Page( + BookLine(RED + "The end of the war and the", 82), + BookLine(RED + "prophecy", 83), + BookLine("", 84), + BookLine("The war of gods last many", 85), + BookLine("lifetimes. Battle is glorious", 86), + BookLine("and many heroes live and", 87), + BookLine("die! Then all gods leave", 88), + BookLine("world, leave their armies", 89), + BookLine("behind. But goblins still", 90), + BookLine("soldiers, still fight! Goblins", 91), + BookLine("fight against tall people with", 92), + BookLine("keen blades. But tall people", 93), + BookLine("build cities with walls, they", 94), + BookLine("not want to fight. They not", 95), + BookLine("true soldiers like goblins! But", 96), + ), + ), + PageSet( + Page( + BookLine("now goblins not have enough", 97), + BookLine("to eat, and have no", 68), + BookLine("commanders to tell them who", 69), + BookLine("to fight. So goblin tribes fight", 70), + BookLine("one another.", 71), + BookLine("", 72), + BookLine("At last all goblin tribes have", 73), + BookLine("big battle on plain of mud.", 74), + BookLine("Battle last many days and", 75), + BookLine("many goblins die, battle is", 76), + BookLine("glorious! But goblin corpses", 77), + BookLine("cover the ground and it look", 78), + BookLine("like all die. ", 79), + BookLine("", 80), + BookLine("Then Hopespear of the", 81), + ), + Page( + BookLine("Narogoshunn tribe have", 82), + BookLine("vision of Big High War God.", 83), + BookLine("In night while soldiers rest he", 84), + BookLine("call leaders of all tribes", 85), + BookLine("together to give them", 86), + BookLine("message.", 87), + BookLine("", 88), + BookLine("This is the word of Big High", 89), + BookLine("War God: Battle is indeed", 90), + BookLine("glorious and goblins are", 91), + BookLine("soldiers but if there too", 92), + BookLine("much battle all goblins die!", 93), + BookLine("No more must goblin fight", 94), + BookLine("against goblin or tribe against", 95), + BookLine("tribe. Goblins must find other", 96), + ), + ), + PageSet( + Page( + BookLine("enemies to fight, but not fight", 97), + BookLine("each other!", 68), + BookLine("", 69), + BookLine("And this is the word of Big", 70), + BookLine("High War God: Today I", 71), + BookLine("cannot lead you, but", 72), + BookLine("someday I will send a new", 73), + BookLine("Commander to lead you.", 74), + BookLine("Under new Commander", 75), + BookLine("goblins will conquer all of", 76), + BookLine(ServerConstants.SERVER_NAME + ", every race and", 77), + BookLine("every god! And then Big", 78), + BookLine("High War God will return", 79), + BookLine("and sit on throne of bronze", 80), + BookLine("and rule over all. War will", 81), + ), + Page( + BookLine("end in victory and victory", 82), + BookLine("will last forever!", 83), + BookLine("", 84), + BookLine("So leaders of tribes stop", 85), + BookLine("battle. And on plain of mud", 86), + BookLine("all tribes build temple to Big", 87), + BookLine("High War God and offer", 88), + BookLine("sacrifices.", 89), + BookLine("", 90), + BookLine("", 91), + BookLine("", 92), + BookLine("", 93), + BookLine("", 94), + BookLine("", 95), + BookLine("", 96), + ), + ), + ) + private fun display(player: Player, pageNum: Int, buttonID: Int) : Boolean { + BookInterface.pageSetup(player, BookInterface.FANCY_BOOK_26, TITLE, CONTENTS) + return true + } + } + + override fun defineListeners() { + on(Items.GOBLIN_BOOK_10999, IntType.ITEM, "read") { player, _ -> + BookInterface.openBook(player, BookInterface.FANCY_BOOK_26, ::display) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/book/GrimDiary.kt b/Server/src/main/content/global/handlers/item/book/GrimDiary.kt new file mode 100644 index 0000000..1567391 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/book/GrimDiary.kt @@ -0,0 +1,139 @@ +package content.global.handlers.item.book + +import content.global.handlers.iface.BookInterface +import content.global.handlers.iface.BookLine +import content.global.handlers.iface.Page +import content.global.handlers.iface.PageSet +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import org.rs09.consts.Items + +/** + * Grim Diary Book + * https://www.youtube.com/watch?v=Vhmm_Gg0584 + * @author ovenbreado + * @author Vexia + */ +class GrimDiary : InteractionListener { + companion object { + private const val RED = "" + private const val LEFT_PAGE_CHILD = 97 + private const val RIGHT_PAGE_CHILD = 82 + private const val TITLE = "Diary of Death" + private val CONTENTS = arrayOf( + PageSet( + Page( + BookLine( + "My Diary

by Grim

" + RED + "'''''''''''''''''''''''''''''''
" + RED + "''''12th Bennath
" + RED + "'''''''''''''''''''''''''''''''
I had such a busy day
dealing out death today
It's not as easy being grim.
Realised that Alfonse is
such a good servant. He





", + LEFT_PAGE_CHILD + ) + ), + Page( + BookLine( + "seems to have the house
in full working order. I
shall have to congratulate
him tomorrow. Spent
some well-deserved time
sharpening my scythe -
Alfonse kindly reminded
me to put the sharpener
back in the cabinet. Such
a good chap.", + RIGHT_PAGE_CHILD + ) + ) + ), + PageSet( + Page( + BookLine( + "

" + RED + "'''''''''''''''''''''''''''''''
" + RED + "'''13th Bennath
" + RED + "'''''''''''''''''''''''''''''''
Went to the Wilderness
today. Plenty of foolish
people surrendering their
lives to me without
thought. My back is
killing me from all the
standing around waiting.", + LEFT_PAGE_CHILD + ) + ), + Page( + BookLine( + "Must get that seen to.
Got my robes stained
from one victim. Simply
ruined! I decided to
throw them in the
fireplace - will light the
fire soon. Oh, and I must
remember to call mother.", + RIGHT_PAGE_CHILD + ) + ) + ), + PageSet( + Page( + BookLine( + "

" + RED + "'''''''''''''''''''''''''''''''
" + RED + "'''14th Bennath
" + RED + "'''''''''''''''''''''''''''''''
A tragic day. Alfonse and
I were in the garden
looking at the state of the
spider nest. I patted my
trusty servant on the
back in thanks for all his
hard work. Sadly, my
touch of death killed him", + LEFT_PAGE_CHILD + ) + ), Page(BookLine("instantly. Feel quite guilty.", RIGHT_PAGE_CHILD)) + ), + PageSet( + Page( + BookLine( + "

" + RED + "'''''''''''''''''''''''''''''''
" + RED + "'''20th Bennath
" + RED + "'''''''''''''''''''''''''''''''
House is getting into
quite a state without
Alfonse - things strewn all
over the place. Almost
trod on the eye of my
mentor, eww. I put the
eye back on the shelf so
he can watch over me", + LEFT_PAGE_CHILD + ) + ), + Page( + BookLine( + "and make sure I stay
true to his teachings.
Went into Varrock to
buy some new robes -
people kept running away
in fear, so it was difficult
to find a sale.", + RIGHT_PAGE_CHILD + ) + ) + ), + PageSet( + Page( + BookLine( + "

" + RED + "'''''''''''''''''''''''''''''''
" + RED + "'''21st Bennath
" + RED + "'''''''''''''''''''''''''''''''
Decided to spend a bit of
time tidying today - it
really isn't an easy job.
In my activities I found
my old 'Voice of Doom'
potion on the bookcase -
perfect for giving people a
good scare. Oh, I do love", + LEFT_PAGE_CHILD + ) + ), + Page( + BookLine( + "my job.


" + RED + "'''''''''''''''''''''''''''''''
" + RED + "'''22nd Bennath
" + RED + "'''''''''''''''''''''''''''''''
Ordered a new servant
today from the agency
and got a 10% discount
for getting past the
1000th servant mark.", + RIGHT_PAGE_CHILD + ) + ) + ), + PageSet( + Page( + BookLine( + "Woo hoo! The agency
sent me his Last Will and
Testement. Shall have to
sit on that for a while.

" + RED + "'''''''''''''''''''''''''''''''
" + RED + "'''23rd Bennath
" + RED + "'''''''''''''''''''''''''''''''
Aquired some bones
today. Muncher should
appreciate them as a treat", + LEFT_PAGE_CHILD + ) + ), + Page( + BookLine( + "the next time he behaves.
The problem is there
aren't many barriers he
can't devour, so I decided
to lock the bones up in
the chest.

" + RED + "'''''''''''''''''''''''''''''''" + RED + "
" + RED + "''''24th Bennath
" + RED + "'''''''''''''''''''''''''''''''
My plan to make undead", + RIGHT_PAGE_CHILD + ) + ) + ), + PageSet( + Page( + BookLine( + "fish is going quite well. I
managed to obtain a
resurrection hourglass
today,so have added that
to the fishtank to finish
off the process. It's so
difficult to have pets when
everything you touch dies
horrifically. I remember
having a rabbit once that
exploded when I fed it a", + LEFT_PAGE_CHILD + ) + ), + Page( + BookLine( + "carrot!

" + RED + "'''''''''''''''''''''''''''''''
" + RED + "'''25th Bennath
" + RED + "'''''''''''''''''''''''''''''''
Got back home today to
find Muncher has run
around the house
creating havok - he even
ate the postman! I", + RIGHT_PAGE_CHILD + ) + ) + ), + PageSet( + Page( + BookLine( + "scolded him. So hopefully
he won't do it again
anytime soon. All my
things are in such a
mess. I'm surely going to
have to find someone to
tidy things up before my
new servant arrives.
Don't want to seem
totally incapable of looking
after myself.", + LEFT_PAGE_CHILD + ) + ) + ) + ) + private fun display(player:Player, pageNum: Int, buttonID: Int) : Boolean { + BookInterface.pageSetup(player, BookInterface.FANCY_BOOK_26, TITLE, CONTENTS) + return true + } + } + + override fun defineListeners() { + on(Items.THE_GRIM_REAPERS_DIARY_11780, IntType.ITEM, "read") { player, _ -> + BookInterface.openBook(player, BookInterface.FANCY_BOOK_26, ::display) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/book/SecurityBookPlugin.kt b/Server/src/main/content/global/handlers/item/book/SecurityBookPlugin.kt new file mode 100644 index 0000000..4813fed --- /dev/null +++ b/Server/src/main/content/global/handlers/item/book/SecurityBookPlugin.kt @@ -0,0 +1,134 @@ +package content.global.handlers.item.book + +import content.global.handlers.iface.BookInterface +import content.global.handlers.iface.BookLine +import content.global.handlers.iface.Page +import content.global.handlers.iface.PageSet +import core.api.setAttribute +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.game.world.GameWorld +import org.rs09.consts.Items + +/** + * Security Book + * https://www.youtube.com/watch?v=yXyRUXYafO0 + * @author ovenbreado + */ +class SecurityBookPlugin : InteractionListener { + companion object { + private const val BLUE = "" + private val TITLE = "" + GameWorld.settings!!.name + " Account Security" + private val CONTENTS = arrayOf( + PageSet( + Page( + BookLine("Chapters", 38), + BookLine("

" + BLUE + "Password Tips

", 40), + BookLine("

" + BLUE + "Recovery Questions

", 41), + BookLine("

" + BLUE + "Other Security Tips

", 42), + BookLine("

" + BLUE + "Stringhold of Security

", 43) + ), + Page( + BookLine("

" + BLUE + "Password Tips

", 53), + BookLine("A good password should be", 54), + BookLine("easily remembered by", 55), + BookLine("yourself but not easily", 56), + BookLine("guessed by anyone else.", 57), + BookLine("Choose a password that has", 59), + BookLine("both letters and numbers in", 60), + BookLine("it for the best security but", 61), + BookLine("don't make it so hard that", 62), + BookLine("you'll forget it!", 63), + BookLine("Never write your password", 65), + BookLine("down or leave it in a text file", 66), + BookLine("on your computer, someone", 67) + ) + ), + PageSet( + Page( + BookLine("could find it easily!", 38), + BookLine("Never tell anyone your", 40), + BookLine("password in " + GameWorld.settings!!.name + ", not", 41), + BookLine("even a Moderator of any", 42), + BookLine("kind.", 43) + ), + Page( + BookLine("

" + BLUE + "Recovery Questions

", 53), + BookLine("Ideally your recovery", 54), + BookLine("questions should be easily", 55), + BookLine("remembered by you but not", 56), + BookLine("guessable by anyone who", 57), + BookLine("may know you or given", 58), + BookLine("away in conversation. Choose", 59), + BookLine("things that do not change,", 60), + BookLine("like dates or names but don't", 61), + BookLine("choose obvious ones like your", 62), + BookLine("birthday and your sister or", 63), + BookLine("bother's name because lots", 64), + BookLine("of people will know that.", 65) + ) + ), + PageSet( + Page( + BookLine("

" + BLUE + "Recovery Questions

", 38), + BookLine("Bear in mind that recovery", 39), + BookLine("questions will take 14 days to", 40), + BookLine("become active after you have", 41), + BookLine("applied for them to be", 42), + BookLine("changed. This is to protect", 43), + BookLine("your account from hijackers", 44), + BookLine("who may change them.", 45), + BookLine("Never give your password to", 47), + BookLine("ANYONE. This includes", 48), + BookLine("your friends, family, and", 49), + BookLine("moderators in game.", 50), + BookLine("Never leave your account", 52) + ), + Page( + BookLine("logged on if you are away", 53), + BookLine("from the computer, it only", 54), + BookLine("takes 5 seconds to steal your", 55), + BookLine("account!", 56) + ) + ), + PageSet( + Page( + BookLine("

" + BLUE + "Stronghold of Security

", 38), + BookLine("Location: The Stronghold of", 39), + BookLine("Security, as we call it, is", 40), + BookLine("located under the village filled", 41), + BookLine("with Barbarians. It was", 42), + BookLine("found after they moved their", 43), + BookLine("mining operations and a", 44), + BookLine("miner fell through. The", 45), + BookLine("Stronghold contains many", 46), + BookLine("challenges. Both for those", 47), + BookLine("who enjoy combat and those", 48), + BookLine("who enjoy challenges of the", 49), + BookLine("mind. This book will be very", 50), + BookLine("useful to you in your travels", 51), + BookLine("there.", 52) + ), + Page( + BookLine("You can find the Stronghold", 53), + BookLine("of Security by looking for a", 54), + BookLine("hole in Barbarian Village.", 55), + BookLine("Be sure to take your combat", 56), + BookLine("equipment though!", 57) + ) + ) + ) + private fun display(player: Player, pageNum: Int, buttonID: Int) : Boolean { + BookInterface.pageSetup(player, BookInterface.FANCY_BOOK_2_27, TITLE, CONTENTS) + return true + } + } + + override fun defineListeners() { + on(Items.SECURITY_BOOK_9003, IntType.ITEM, "read") { player, _ -> + BookInterface.openBook(player, BookInterface.FANCY_BOOK_2_27, ::display) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/book/StrongholdNotes.kt b/Server/src/main/content/global/handlers/item/book/StrongholdNotes.kt new file mode 100644 index 0000000..4a67ee9 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/book/StrongholdNotes.kt @@ -0,0 +1,136 @@ +package content.global.handlers.item.book + +import content.global.handlers.iface.BookInterface +import content.global.handlers.iface.BookLine +import content.global.handlers.iface.Page +import content.global.handlers.iface.PageSet +import core.api.setAttribute +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import org.rs09.consts.Items + +/** + * Stronghold Notes Book + * https://www.youtube.com/watch?v=gX1jCcfY0l8 + * @author ovenbreado + */ +class StrongholdNotes : InteractionListener { + companion object { + private const val BLUE = "" + private const val TITLE = "Stronghold of Security - Notes" + private val CONTENTS = arrayOf( + PageSet( + Page( + BookLine( + "Chapters

" + BLUE + "Description
" + BLUE + "Level 1
" + BLUE + "Level 2
" + BLUE + "Level 3
" + BLUE + "Level 4
" + BLUE + "Navigation
" + BLUE + "Diary









", + 38 + ) + ), Page( + BookLine( + BLUE + "Description
This stronghold was
unearthed by a miner
prospecting for new ores
around the Barbarian Village.
After gathering some
equipment he ventured into
the maze of tunnels and was
missing for a long time. He
finally emerged along with
copious notes refarding the
new beasts and strange
experiences which had befallen
him. He also mentioned that
there was treasure to be had,", + 53 + ) + ) + ), + PageSet( + Page( + BookLine( + "but no one has been able to
wring a word from him about
this, he simply flapped his
arms and slapped his head.
This book details his notes
and my diary of exploration.
I am exploring to see if I
can find out more...", + 38 + ) + ), Page( + BookLine( + BLUE + "Level 1
As well as goblins, creatures
like a man but also like a cow
infest this place! I have never
seen anything like this before.
The area itself is reminiscent
of frontline castles, with
many walls, doors and
skeletons of dead enemies.
I'm sure I hear voices in my
head each time I pass
through the gates. I have
dubbed this level War as it
seems like an eternal
battleground. I found only", + 53 + ) + ) + ), + PageSet( + Page(BookLine("one small peaceful area here.", 38)), + Page( + BookLine( + BLUE + "Level 2
My supplies are running low
and I find myself in barren
passages with seemingly
endless malnourished beasts
attacking me, revenous for
food. Nothing appears to be
able to grow, many
adventurers have died
through lack of food and the
very air appears to suck
vitality from me. I've come to
call this place famine.", + 53 + ) + ) + ), + PageSet( + Page( + BookLine( + BLUE + "Level 3
Just breathing in this place
makes me shudder at the
thought of what foul disease I
may contract. The walls and
floor ooze and pulsate like
something pox ridden. There
is a very strange beast whom
I narrowly escaped from. At
first I thought it to be a
cross between a cow and a
sheep, something
domesticated... but when it
looked up at me I was
overcome with weakness and", + 38 + ) + ), + Page( + BookLine( + "barely got way with my life!
Luckily I found a small place
where I could heal myself
and rest a while. I have
named this area pestilence for
it reeks with decay.", + 53 + ) + ) + ), + PageSet( + Page( + BookLine( + BLUE + "Level 4
On my first escapade into
this place I was utterly
shocked. The adventurers
who had come before me
must have made up a tiny
proportion of the skeletons of
the dead. Nothing truely
alive exists here, even those
beings who do wander the
halls are not alive as such,
but they do know that I am
and I get the distinct
impression that were they to
have their way, I would not", + 38 + ) + ), + Page( + BookLine( + "be for long! Death is
everywhere and thus I shall
name this place. There is one
small place of life, which was
gladdening to find and very
worth my while!", + 53 + ) + ) + ), + PageSet( + Page( + BookLine( + BLUE + "Navigation
After getting lost several
times I finally worked out the
key to all the ladders and
chains around this death
infested place. All ropes and
chains will take you to the
start of the level that you are
on. However most ladders will
simply take you to the level
above. The one esception is
the ladder in the bottom level
treasure room, which appears
to lead through several
extremely twisty passages.", + 38 + ) + ), + Page( + BookLine( + "and eventually takes you out
of the dungeon completely.
The portals may be used if
you are of sufficient level or
have already claimed your
reward from the treasure
room.", + 38 + ) + ) + ), + PageSet( + Page( + BookLine( + BLUE + "Diary
Day 1
Today I set out to find out
more about this place. From
my research I knew about
the sentient doors, imbued by
some unkown force to talk
to you and ask questions
before they will let you pass.
I have so far passed these
doors without incident, giving
the correct answer seems to
work a treat.

Day 2", + 38 + ) + ), + Page( + BookLine( + "I have fought my way
through the fearsome beasts
on the first level and am
preparing myself to journey
deeper. I hope that things are
not too difficult further on as
I am already sick of bread
and cheese for dinner.

Day 3
I ventured down into the
famine level today... I was
wounded and have returned
to the relative safety of the
level above. I am going to", + 53 + ) + ) + ), + PageSet( + Page( + BookLine( + "try to make my way out
through the goblins and
mancow things... I hope I
make it.....", + 38 + ) + ) + ) + ) + + private fun display(player: Player, pageNum: Int, buttonID: Int) : Boolean { + BookInterface.pageSetup(player, BookInterface.FANCY_BOOK_2_27, TITLE, CONTENTS) + return true + } + } + + override fun defineListeners() { + on(Items.STRONGHOLD_NOTES_9004, IntType.ITEM, "read") { player, _ -> + BookInterface.openBook(player, BookInterface.FANCY_BOOK_2_27, ::display) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/equipment/BarrowsEquipmentRegister.kt b/Server/src/main/content/global/handlers/item/equipment/BarrowsEquipmentRegister.kt new file mode 100644 index 0000000..d7e57ab --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/BarrowsEquipmentRegister.kt @@ -0,0 +1,76 @@ +package content.global.handlers.item.equipment + +import core.plugin.Initializable +import core.plugin.Plugin + +@Initializable +class BarrowsEquipmentRegister : Plugin{ + public companion object { + // Barrows equipment lasts for 15 hours of combat, and each piece has 4 stages of degredation + @JvmField + public val TICKS = (15 * 6000) / 4 + } + + val DHAROK_HELM = arrayOf(4716,4880,4881,4882,4883,4884) + val DHAROK_AXE = arrayOf(4718,4886,4887,4888,4889,4890) + val DHAROK_BODY = arrayOf(4720,4892,4893,4894,4895,4896) + val DHAROK_LEGS = arrayOf(4722,4898,4899,4900,4901,4902) + + val GUTHAN_HELM = arrayOf(4724,4904,4905,4906,4907,4908) + val GUTHAN_SPEAR = arrayOf(4726,4910,4911,4912,4913,4914) + val GUTHAN_BODY = arrayOf(4728,4916,4917,4918,4919,4920) + val GUTHAN_SKIRT = arrayOf(4730,4922,4923,4924,4925,4926) + + val TORAG_HELM = arrayOf(4745,4952,4953,4954,4955,4956) + val TORAG_HAMMER = arrayOf(4747,4958,4959,4960,4961,4962) + val TORAG_BODY = arrayOf(4749,4964,4965,4966,4967,4968) + val TORAG_LEGS = arrayOf(4751,4970,4971,4972,4973,4974) + + val VERAC_HELM = arrayOf(4753,4976,4977,4978,4979,4980) + val VERAC_FLAIL = arrayOf(4755,4982,4983,4984,4985,4986) + val VERAC_BRASS = arrayOf(4757,4988,4989,4990,4991,4992) + val VERAC_SKIRT = arrayOf(4759,4994,4995,4996,4997,4998) + + val AHRIM_HOOD = arrayOf(4708,4856,4857,4858,4859,4860) + val AHRIM_STAFF = arrayOf(4710,4862,4863,4864,4865,4866) + val AHRIM_TOP = arrayOf(4712,4868,4869,4870,4871,4872) + val AHRIM_SKIRT = arrayOf(4714,4874,4875,4876,4877,4878) + + val KARIL_COIF = arrayOf(4732,4928,4929,4930,4931,4932) + val KARIL_CBOW = arrayOf(4734,4934,4935,4936,4937,4938) + val KARIL_TOP = arrayOf(4736,4940,4941,4942,4943,4944) + val KARIL_SKIRT = arrayOf(4738,4946,4947,4948,4949,4950) + + override fun newInstance(arg: Any?): Plugin { + EquipmentDegrader.registerSet(TICKS, AHRIM_HOOD) + EquipmentDegrader.registerSet(TICKS, AHRIM_STAFF) + EquipmentDegrader.registerSet(TICKS, AHRIM_TOP) + EquipmentDegrader.registerSet(TICKS, AHRIM_SKIRT) + EquipmentDegrader.registerSet(TICKS, KARIL_COIF) + EquipmentDegrader.registerSet(TICKS, KARIL_CBOW) + EquipmentDegrader.registerSet(TICKS, KARIL_TOP) + EquipmentDegrader.registerSet(TICKS, KARIL_SKIRT) + EquipmentDegrader.registerSet(TICKS, DHAROK_HELM) + EquipmentDegrader.registerSet(TICKS, DHAROK_AXE) + EquipmentDegrader.registerSet(TICKS, DHAROK_BODY) + EquipmentDegrader.registerSet(TICKS, DHAROK_LEGS) + EquipmentDegrader.registerSet(TICKS, GUTHAN_HELM) + EquipmentDegrader.registerSet(TICKS, GUTHAN_SPEAR) + EquipmentDegrader.registerSet(TICKS, GUTHAN_BODY) + EquipmentDegrader.registerSet(TICKS, GUTHAN_SKIRT) + EquipmentDegrader.registerSet(TICKS, TORAG_HELM) + EquipmentDegrader.registerSet(TICKS, TORAG_HAMMER) + EquipmentDegrader.registerSet(TICKS, TORAG_BODY) + EquipmentDegrader.registerSet(TICKS, TORAG_LEGS) + EquipmentDegrader.registerSet(TICKS, VERAC_HELM) + EquipmentDegrader.registerSet(TICKS, VERAC_FLAIL) + EquipmentDegrader.registerSet(TICKS, VERAC_BRASS) + EquipmentDegrader.registerSet(TICKS, VERAC_SKIRT) + return this + } + + override fun fireEvent(identifier: String?, vararg args: Any?): Any { + return Unit + } + +} diff --git a/Server/src/main/content/global/handlers/item/equipment/CrystalEquipmentRegister.kt b/Server/src/main/content/global/handlers/item/equipment/CrystalEquipmentRegister.kt new file mode 100644 index 0000000..2bb7bb4 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/CrystalEquipmentRegister.kt @@ -0,0 +1,13 @@ +package content.global.handlers.item.equipment + +import core.api.StartupListener +import org.rs09.consts.Items + +class CrystalEquipmentRegister : StartupListener { + val shield: Array = arrayOf(Items.NEW_CRYSTAL_SHIELD_4224, Items.CRYSTAL_SHIELD_FULL_4225, Items.CRYSTAL_SHIELD_9_10_4226, Items.CRYSTAL_SHIELD_8_10_4227, Items.CRYSTAL_SHIELD_7_10_4228, Items.CRYSTAL_SHIELD_6_10_4229, Items.CRYSTAL_SHIELD_5_10_4230, Items.CRYSTAL_SHIELD_4_10_4231, Items.CRYSTAL_SHIELD_3_10_4232, Items.CRYSTAL_SHIELD_2_10_4233, Items.CRYSTAL_SHIELD_1_10_4234, Items.CRYSTAL_SEED_4207) + val bow: Array = arrayOf(Items.NEW_CRYSTAL_BOW_4212, Items.CRYSTAL_BOW_FULL_4214, Items.CRYSTAL_BOW_9_10_4215, Items.CRYSTAL_BOW_8_10_4216, Items.CRYSTAL_BOW_7_10_4217, Items.CRYSTAL_BOW_6_10_4218, Items.CRYSTAL_BOW_5_10_4219, Items.CRYSTAL_BOW_4_10_4220, Items.CRYSTAL_BOW_3_10_4221, Items.CRYSTAL_BOW_2_10_4222, Items.CRYSTAL_BOW_1_10_4223, Items.CRYSTAL_SEED_4207) + override fun startup() { + EquipmentDegrader.registerSet(250, shield) + EquipmentDegrader.registerSet(250, bow) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/equipment/EquipmentDegrader.kt b/Server/src/main/content/global/handlers/item/equipment/EquipmentDegrader.kt new file mode 100644 index 0000000..2da19f4 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/EquipmentDegrader.kt @@ -0,0 +1,95 @@ +package content.global.handlers.item.equipment + +import core.api.addItemOrDrop +import core.api.getNext +import core.api.isLast +import core.api.isNextLast +import core.game.node.entity.player.Player +import core.game.node.item.Item + +/** + * Handles equipment degrading + * @author ceik + */ +class EquipmentDegrader{ + + companion object StaticDegrader { //Use a static companion object for lists and registers so they persist across instances + val itemList = arrayListOf() + val setList = arrayListOf>() + val itemCharges = hashMapOf() + fun register(charges: Int, item: Int){ + itemList.add(item) + itemCharges.put(item, charges) + } + + fun registerSet(charges: Int, items: Array){ + setList.add(ArrayList(items.map { item -> item.also { register(charges, item) } })) + } + } + + + + var p: Player? = null + + fun Int.canDegrade(): Boolean { //extension function that checks if an item can degrade + return itemList.contains(this) + } + + fun checkArmourDegrades(player: Player?){ //loops the player slots and if the item in that slot is non-null, checks if it can degrade etc + p = player + for(slot in 0..12){ + if(slot == 3){ + continue + } + player?.equipment?.get(slot)?.let { if(it.id.canDegrade()) it.degrade(slot) } + } + } + + fun checkWeaponDegrades(player: Player?){ + p = player + player?.equipment?.get(3)?.let { if(it.id.canDegrade()) it.degrade(3) } + } + + fun Item.degrade(slot: Int){ //extension function that degrades items + val set = getDegradableSet(this.id) + val charges = itemCharges.getOrElse(this.id) {1000} + if (this.charge > charges) + charge = charges + this.charge-- + if(set?.indexOf(this.id) == 0 && !this.name.contains("100")){ + charge = 0 + } + if(this.charge <= 0) { + val charges = itemCharges.getOrElse(this.id) { 1000 } + if (set?.size!! > 2) { + p?.equipment?.remove(this) + p?.sendMessage("Your $name has degraded.") + if (set.isNextLast(this.id)) { + p?.let { addItemOrDrop(it, set.getNext(this.id)) } + p?.sendMessage("Your $name has broken.") + } else { + p?.equipment?.add(Item(set.getNext(this.id), 1, charges), slot, false, false) + p?.equipment?.refresh() + } + } else if (set.size == 2) { + if(set.isLast(this.id)){ + p?.equipment?.remove(this) + p?.sendMessage("Your $name degrades into dust.") + } else { + p?.equipment?.remove(this) + p?.sendMessage("Your $name has degraded.") + p?.equipment?.add(Item(set.getNext(this.id), 1, charges), slot, false, false) + p?.equipment?.refresh() + } + } + } + } + + private fun getDegradableSet(item: Int): ArrayList?{ //gets the set of items this item belongs to + for(set in setList){ + if(set.contains(item)) + return set + } + return null + } +} diff --git a/Server/src/main/content/global/handlers/item/equipment/PVPEquipmentRegister.kt b/Server/src/main/content/global/handlers/item/equipment/PVPEquipmentRegister.kt new file mode 100644 index 0000000..81d9576 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/PVPEquipmentRegister.kt @@ -0,0 +1,54 @@ +package content.global.handlers.item.equipment + +import core.plugin.Initializable +import core.plugin.Plugin + +@Initializable +class PVPEquipmentRegister : Plugin { + // PVP equipment lasts for 1 hour of combat, which is 6000 ticks + val TICKS = 6000 + + val VESTA_BODY = arrayOf(13887,13889) + val VESTA_SKIRT = arrayOf(13893,13895) + val VESTA_SWORD = arrayOf(13899,13901) + val VESTA_SPEAR = arrayOf(13905,13907) + + val STATIUS_BODY = arrayOf(13884,13886) + val STATIUS_LEGS = arrayOf(13890,13892) + val STATIUS_HELM = arrayOf(13896,13898) + val STATIUS_HAMMER = arrayOf(13902,13904) + + val ZURIEL_TOP = arrayOf(13858,13860) + val ZUREL_BOTTOM = arrayOf(13861,13863) + val ZURIEL_HOOD = arrayOf(13864,13866) + val ZURIEL_STAFF = arrayOf(13867, 13869) + + val MORRIGAN_BODY = arrayOf(13870,13872) + val MORRIGAN_CHAP = arrayOf(13873,13875) + val MORRIGAN_COIF = arrayOf(13876,13878) + + + override fun newInstance(arg: Any?): Plugin { + EquipmentDegrader.registerSet(TICKS, VESTA_BODY) + EquipmentDegrader.registerSet(TICKS, VESTA_SKIRT) + EquipmentDegrader.registerSet(TICKS, VESTA_SWORD) + EquipmentDegrader.registerSet(TICKS, VESTA_SPEAR) + EquipmentDegrader.registerSet(TICKS, STATIUS_BODY) + EquipmentDegrader.registerSet(TICKS, STATIUS_HAMMER) + EquipmentDegrader.registerSet(TICKS, STATIUS_HELM) + EquipmentDegrader.registerSet(TICKS, STATIUS_LEGS) + EquipmentDegrader.registerSet(TICKS, ZUREL_BOTTOM) + EquipmentDegrader.registerSet(TICKS, ZURIEL_HOOD) + EquipmentDegrader.registerSet(TICKS, ZURIEL_STAFF) + EquipmentDegrader.registerSet(TICKS, ZURIEL_TOP) + EquipmentDegrader.registerSet(TICKS, MORRIGAN_BODY) + EquipmentDegrader.registerSet(TICKS, MORRIGAN_CHAP) + EquipmentDegrader.registerSet(TICKS, MORRIGAN_COIF) + return this + } + + override fun fireEvent(identifier: String?, vararg args: Any?): Any { + return Unit + } + +} diff --git a/Server/src/main/content/global/handlers/item/equipment/brawling_gloves/BrawlingGloves.java b/Server/src/main/content/global/handlers/item/equipment/brawling_gloves/BrawlingGloves.java new file mode 100644 index 0000000..6f09426 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/brawling_gloves/BrawlingGloves.java @@ -0,0 +1,72 @@ +package content.global.handlers.item.equipment.brawling_gloves; + +import core.cache.def.impl.ItemDefinition; +import core.game.node.entity.skill.Skills; + +import java.util.HashMap; + +/** + * Represents brawling gloves + * @author ceik + */ +public enum BrawlingGloves { + MELEE (13845, "melee", 500, 1, Skills.ATTACK), + RANGED (13846,"ranged", 500, 2, Skills.RANGE), + MAGIC (13847,"magic", 500, 3, Skills.MAGIC), + PRAYER (13848,"prayer", 450, 4, Skills.PRAYER), + AGILITY (13849,"agility", 450, 5, Skills.AGILITY), + WOODCUTTING(13850,"wc", 450, 6, Skills.WOODCUTTING), + FIREMAKING (13851,"fm", 450, 7, Skills.FIREMAKING), + MINING (13852,"mining", 450, 8, Skills.MINING), + HUNTER (13853,"hunter", 450, 9, Skills.HUNTER), + THIEVING (13854,"thieving",450, 10, Skills.THIEVING), + SMITHING (13855,"smithing",450, 11, Skills.SMITHING), + FISHING (13856,"fishing", 450, 12, Skills.FISHING), + COOKING (13857,"cooking", 450, 13, Skills.COOKING); + + private final int id; + private final String name; + private final int charges; + private final int indicator; + private int skillSlot; + + BrawlingGloves(int id, String name, int charges, int indicator, int skillSlot){ + this.id = id; + this.name = ItemDefinition.forId(id).getName(); + this.charges = charges; + this.indicator = indicator; + this.skillSlot = skillSlot; + } + + public static HashMap glovesMap = new HashMap<>(); + public static HashMap skillMap = new HashMap<>(); + public static HashMap indicatorMap = new HashMap<>(); + + static { + for(BrawlingGloves gloves : BrawlingGloves.values()){ + glovesMap.putIfAbsent(gloves.id, gloves); + skillMap.putIfAbsent(gloves.skillSlot,gloves); + indicatorMap.putIfAbsent(gloves.indicator,gloves); + } + } + + + + public static BrawlingGloves forId(int id){ + return glovesMap.get(id); + } + + public static BrawlingGloves forIndicator(int indicator){ + return indicatorMap.get(indicator); + } + + public static BrawlingGloves forSkill(int skillSlot){ + return skillMap.get(skillSlot); + } + + public int getId(){return id;} + public int getCharges(){return charges;} + public int getIndicator(){return indicator;} + public String getName(){return name;} + public int getSkillSlot() {return skillSlot;} +} diff --git a/Server/src/main/content/global/handlers/item/equipment/brawling_gloves/BrawlingGlovesManager.java b/Server/src/main/content/global/handlers/item/equipment/brawling_gloves/BrawlingGlovesManager.java new file mode 100644 index 0000000..8623ca4 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/brawling_gloves/BrawlingGlovesManager.java @@ -0,0 +1,102 @@ +package content.global.handlers.item.equipment.brawling_gloves; + +import core.api.LoginListener; +import core.api.PersistPlayer; +import core.cache.def.impl.ItemDefinition; +import core.game.node.entity.player.Player; + +import core.game.node.item.Item; +import org.jetbrains.annotations.NotNull; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; + +import java.util.HashMap; +import java.util.Objects; + +/** + * Manages brawling gloves for a player + * @author ceik + */ +public class BrawlingGlovesManager implements LoginListener, PersistPlayer { + final Player player; + public HashMap GloveCharges = new HashMap(); + + public BrawlingGlovesManager(Player player){this.player = player;} + public BrawlingGlovesManager(){this.player = null;} + + @Override + public void login(@NotNull Player player) { + BrawlingGlovesManager instance = new BrawlingGlovesManager(player); + player.setAttribute("bg-manager", instance); + } + + @Override + public void parsePlayer(@NotNull Player player, @NotNull JSONObject data) { + BrawlingGlovesManager instance = getInstance(player); + if(data.containsKey("brawlingGloves")) + { + JSONArray bgData = (JSONArray) data.get("brawlingGloves"); + for (Object bg : bgData) { + JSONObject glove = (JSONObject) bg; + instance.registerGlove(BrawlingGloves.forIndicator(Integer.parseInt(glove.get("gloveId").toString())).getId(), Integer.parseInt(glove.get("charges").toString())); + } + } + } + + @Override + public void savePlayer(@NotNull Player player, @NotNull JSONObject save) { + if(getInstance(player).GloveCharges.size() > 0){ + JSONArray brawlingGloves = new JSONArray(); + getInstance(player).GloveCharges.entrySet().forEach(glove -> { + JSONObject bGlove = new JSONObject(); + bGlove.put("gloveId", Integer.toString(BrawlingGloves.forId(glove.getKey()).getIndicator())); + bGlove.put("charges", Integer.toString(glove.getValue())); + brawlingGloves.add(bGlove); + }); + save.put("brawlingGloves", brawlingGloves); + } + } + + public void registerGlove(int id) { + try { + registerGlove(id, Objects.requireNonNull(BrawlingGloves.forId(id)).getCharges()); + } catch (Exception e){ + e.printStackTrace(); + } + } + public void registerGlove(int id, int charges) {GloveCharges.putIfAbsent(id,charges);} + + + public void updateCharges(int glove, int charges){ + if(GloveCharges.get(glove) != null){ + if(GloveCharges.get(glove) - charges <= 0) { + GloveCharges.remove(glove); + player.getEquipment().remove(new Item(glove)); + player.getPacketDispatch().sendMessage("You use the last charge of your " + ItemDefinition.forId(glove).getName() + " and they vanish."); + return; + } + int currentCharges = GloveCharges.get(glove); + GloveCharges.replace(glove,currentCharges - charges); + player.debug("Glove charges: " + (currentCharges - 1)); + if((currentCharges - 1) % 50 == 0) { + player.getPacketDispatch().sendMessage("Your " + ItemDefinition.forId(glove).getName() + " have " + GloveCharges.get(glove) + " charges left."); + } + } + } + + public double getExperienceBonus(){ + double bonus; + int level = player.getSkullManager().getLevel(); + if(level > 0){ + bonus = 3.0; + }else{ + bonus = 0.5; + } + return bonus; + } + + public static BrawlingGlovesManager getInstance(Player player) + { + return player.getAttribute("bg-manager", new BrawlingGlovesManager()); + } +} diff --git a/Server/src/main/content/global/handlers/item/equipment/fistofguthixgloves/FOGGlovesListener.kt b/Server/src/main/content/global/handlers/item/equipment/fistofguthixgloves/FOGGlovesListener.kt new file mode 100644 index 0000000..9b0166e --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/fistofguthixgloves/FOGGlovesListener.kt @@ -0,0 +1,23 @@ +package content.global.handlers.item.equipment.fistofguthixgloves + +import core.api.toIntArray +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import org.rs09.consts.Items +import kotlin.math.min + +private val FOG_GLOVES = (Items.IRIT_GLOVES_12856..Items.EARTH_RUNECRAFTING_GLOVES_12865).toIntArray() +private val MAX_CHARGES = intArrayOf(100, 100, 100, 100, 1000, 1000, 1000, 1000, 1000, 1000) + +/** + * Listener for Fist of Guthix gloves inspect option. + * @author RiL + */ +class FOGGlovesListener : InteractionListener { + override fun defineListeners() { + on(FOG_GLOVES, IntType.ITEM, "inspect") { player, node -> + player.sendMessage("${node.name}: ${min(node.asItem().charge, MAX_CHARGES[node.id - Items.IRIT_GLOVES_12856])} charge left.") + return@on true + } + } +} diff --git a/Server/src/main/content/global/handlers/item/equipment/fistofguthixgloves/FOGGlovesManager.kt b/Server/src/main/content/global/handlers/item/equipment/fistofguthixgloves/FOGGlovesManager.kt new file mode 100644 index 0000000..768013c --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/fistofguthixgloves/FOGGlovesManager.kt @@ -0,0 +1,37 @@ +package content.global.handlers.item.equipment.fistofguthixgloves + +import core.api.Container +import core.api.EquipmentSlot +import core.api.getItemFromEquipment +import core.api.removeItem +import core.game.node.entity.player.Player +import core.tools.colorize +import org.rs09.consts.Items +import kotlin.math.min + +private val MAX_CHARGES = intArrayOf(100, 100, 100, 100, 1000, 1000, 1000, 1000, 1000, 1000) + +/** + * Manager to help updating Fist of Guthix glove charges. + * @author RiL + */ +class FOGGlovesManager { + companion object{ + /** + * Reduces the charge of the hand equip by [charges]. + * Return the number of used charges. + */ + @JvmStatic + fun updateCharges(player: Player, charges: Int = 1): Int { + val gloves = getItemFromEquipment(player, EquipmentSlot.HANDS) ?: return 0 + gloves.charge = min(gloves.charge, MAX_CHARGES[gloves.id - Items.IRIT_GLOVES_12856]) + if (gloves.charge - charges <= 0) { + removeItem(player, gloves, Container.EQUIPMENT) + player.sendMessage(colorize("%RThe charges in your gloves have been used up and they crumble to dust.")) + return gloves.charge + } + gloves.charge -= charges + return charges + } + } +} diff --git a/Server/src/main/content/global/handlers/item/equipment/special/AncientMaceSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/AncientMaceSpecialHandler.java new file mode 100644 index 0000000..9c04d99 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/special/AncientMaceSpecialHandler.java @@ -0,0 +1,81 @@ +package content.global.handlers.item.equipment.special; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.MeleeSwingHandler; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.Player; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Plugin; +import core.plugin.Initializable; +import core.tools.RandomFunction; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playGlobalAudio; + +/** + * Handles the ancient mace special attack "Favour of the War God". + * @author Emperor + * @version 1.0 + */ +@Initializable +public final class AncientMaceSpecialHandler extends MeleeSwingHandler implements Plugin { + + /** + * The special energy required. + */ + private static final int SPECIAL_ENERGY = 100; + + /** + * The attack animation. + */ + private static final Animation ANIMATION = new Animation(6147, Priority.HIGH); + + /** + * The graphic. + */ + private static final Graphics GRAPHIC = new Graphics(1052); + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + CombatStyle.MELEE.getSwingHandler().register(11061, this); + return this; + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + if (!((Player) entity).getSettings().drainSpecial(SPECIAL_ENERGY)) { + return -1; + } + state.setStyle(CombatStyle.MELEE); + int hit = 0; + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.1, 0.98)) { + hit = RandomFunction.random(calculateHit(entity, victim, 1) + 1); + if (entity.getSkills().getPrayerPoints() < entity.getSkills().getStaticLevel(5)) { + entity.getSkills().setPrayerPoints(entity.getSkills().getPrayerPoints() + hit); + } + victim.getSkills().decrementPrayerPoints(hit); + } + state.setEstimatedHit(hit); + return 1; + } + + @Override + protected int getFormattedHit(Entity entity, Entity victim, BattleState state, int hit) { + // Disables protection prayers. + return formatHit(victim, hit); + } + + @Override + public void visualize(Entity entity, Entity victim, BattleState state) { + playGlobalAudio(entity.getLocation(), Sounds.GOBLIN_MACE_3592); + entity.visualize(ANIMATION, GRAPHIC); + } +} diff --git a/Server/src/main/content/global/handlers/item/equipment/special/BackstabSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/BackstabSpecialHandler.java new file mode 100644 index 0000000..2baaab9 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/special/BackstabSpecialHandler.java @@ -0,0 +1,76 @@ +package content.global.handlers.item.equipment.special; + +import core.game.node.entity.skill.Skills; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.MeleeSwingHandler; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.Player; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Plugin; +import core.plugin.Initializable; +import core.tools.RandomFunction; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playGlobalAudio; + +/** + * Handles the Bone dagger special attack "Backstab". + * @author Emperor + */ +@Initializable +public final class BackstabSpecialHandler extends MeleeSwingHandler implements Plugin { + + /** + * The special energy required. + */ + private static final int SPECIAL_ENERGY = 75; + + /** + * The attack animation. + */ + private static final Animation ANIMATION = new Animation(4198, Priority.HIGH); + + /** + * The graphic. + */ + private static final Graphics GRAPHIC = new Graphics(704); + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + CombatStyle.MELEE.getSwingHandler().register(8872, this); + CombatStyle.MELEE.getSwingHandler().register(8874, this); + CombatStyle.MELEE.getSwingHandler().register(8876, this); + CombatStyle.MELEE.getSwingHandler().register(8878, this); + return this; + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + if (!((Player) entity).getSettings().drainSpecial(SPECIAL_ENERGY)) { + return -1; + } + state.setStyle(CombatStyle.MELEE); + int hit = 0; + if (!victim.getProperties().getCombatPulse().isAttacking() || isAccurateImpact(entity, victim, CombatStyle.MELEE)) { + hit = RandomFunction.random(calculateHit(entity, victim, 1.0) + 1); + if (victim.getSkills().getStaticLevel(Skills.DEFENCE) >= victim.getSkills().getDynamicLevels()[Skills.DEFENCE]) + victim.getSkills().updateLevel(Skills.DEFENCE, -hit, 0); + } + state.setEstimatedHit(hit); + return 1; + } + + @Override + public void visualize(Entity entity, Entity victim, BattleState state) { + playGlobalAudio(entity.getLocation(), Sounds.DTTD_BONE_DAGGER_STAB_1084); + entity.visualize(ANIMATION, GRAPHIC); + } +} diff --git a/Server/src/main/content/global/handlers/item/equipment/special/ChainhitSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/ChainhitSpecialHandler.java new file mode 100644 index 0000000..b3e276d --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/special/ChainhitSpecialHandler.java @@ -0,0 +1,198 @@ +package content.global.handlers.item.equipment.special; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.*; +import core.game.node.entity.combat.ImpactHandler.HitsplatType; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.tools.RandomFunction; +import core.game.world.GameWorld; +import core.game.world.repository.Repository; +import org.rs09.consts.Sounds; + +import java.util.Iterator; +import java.util.List; + +import static core.api.ContentAPIKt.playGlobalAudio; + +/** + * Handles the Rune throwing axe special attack "Chain-hit". + * @author Emperor + */ +@Initializable +public final class ChainhitSpecialHandler extends RangeSwingHandler implements Plugin { + + /** + * Constructs a new {@code ChainhitSpecialHandler} {@code Object}. + */ + public ChainhitSpecialHandler() { + super(SwingHandlerFlag.IGNORE_PRAYER_BOOSTS_DAMAGE); + } + + /** + * The sp::ecial energy required. + */ + private static final int SPECIAL_ENERGY = 10; + + /** + * The attack animation. + */ + private static final Animation ANIMATION = new Animation(1068, Priority.HIGH); + + /** + * The graphic. + */ + private static final Graphics GRAPHIC = new Graphics(257, 96); + + /** + * The door support locations. + */ + private static final Location[] DOOR_SUPPORTS = new Location[] { Location.create(2545, 10145, 0), Location.create(2545, 10141, 0),Location.create(2543, 10143, 0) }; + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + CombatStyle.RANGE.getSwingHandler().register(805, this); + return this; + } + + @Override + public int swing(Entity entity, final Entity victim, BattleState state) { + if (entity.getAttribute("chain-hit_v") != null) { + ((Player) entity).getPacketDispatch().sendMessage("You're already using the chain-hit special attack."); + ((Player) entity).getSettings().toggleSpecialBar(); + return -1; + } + if (!((Player) entity).getSettings().drainSpecial(SPECIAL_ENERGY)) { + return -1; + } + state.setStyle(CombatStyle.RANGE); + if (victim instanceof NPC) { + NPC npc = victim.asNpc(); + if (npc.getId() == 2440) { + for (Location l : DOOR_SUPPORTS) { + final NPC n = Repository.findNPC(l); + if (n == null) { + continue; + } + if (DeathTask.isDead(n) || n.getId() != n.getOriginalId()) { + continue; + } + int speed = (int) (32 + (victim.getLocation().getDistance(n.getLocation()) * 5)); + Projectile.create(victim, n, 258, 40, 36, 32, speed, 5, 11).send(); + n.getSkills().heal(100); + GameWorld.getPulser().submit(new Pulse(3) { + + @Override + public boolean pulse() { + n.getImpactHandler().manualHit(victim, 1, HitsplatType.NORMAL); + return true; + } + + }); + } + } + } + return super.swing(entity, victim, state); + } + + @Override + public void visualize(Entity entity, Entity victim, BattleState state) { + playGlobalAudio(entity.getLocation(), Sounds.CHAINSHOT_2528); + entity.visualize(ANIMATION, GRAPHIC); + int speed = (int) (32 + (entity.getLocation().getDistance(victim.getLocation()) * 5)); + Projectile.create(entity, victim, 258, 40, 36, 32, speed, 5, 11).send(); + } + + @Override + public void visualizeImpact(Entity entity, Entity victim, BattleState state) { + handleHit(entity, victim, (Player) entity, state); + super.visualizeImpact(entity, victim, state); + } + + @Override + public void impact(Entity entity, Entity victim, BattleState state) { + // Empty. + } + + /** + * Handles a hit. + * @param entity The entity. + * @param victim The victim. + * @param player The player. + * @param state The battle state. + */ + public void handleHit(final Entity entity, final Entity victim, final Player player, final BattleState state) { + GameWorld.getPulser().submit(new Pulse(1, player, victim) { + @Override + public boolean pulse() { + ChainhitSpecialHandler.super.onImpact(player, victim, state); + ChainhitSpecialHandler.super.impact(entity, victim, state); + return true; + } + }); + if (victim.getId() == 2440 || victim.getId() == 2446 || victim.getId() == 2443) { + return; + } + if (victim.getProperties().isMultiZone() && player.getSettings().getSpecialEnergy() >= SPECIAL_ENERGY) { + List list = getVictimsList(player, victim); + for (Iterator it = list.iterator(); it.hasNext();) { + final Entity e = it.next(); + it.remove(); + if (!e.isAttackable(player, CombatStyle.RANGE, false) || !e.getProperties().isMultiZone()) { + continue; + } + double distance = victim.getLocation().getDistance(e.getLocation()); + int speed = (int) (32 + (distance * 5)); + Projectile.create(victim, e, 258, 40, 36, 32, speed, 5, 11).send(); + GameWorld.getPulser().submit(new Pulse((int) (distance / 3), entity, victim, e) { + @Override + public boolean pulse() { + BattleState bs = new BattleState(entity, e); + bs.setMaximumHit(calculateHit(player, e, 1.0)); + bs.setEstimatedHit(RandomFunction.random(bs.getMaximumHit() + 1)); + handleHit(victim, e, player, bs); + ChainhitSpecialHandler.super.visualizeImpact(player, e, bs); + return true; + } + }); + player.getSettings().setSpecialEnergy(player.getSettings().getSpecialEnergy() - SPECIAL_ENERGY); + return; + } + } + player.removeAttribute("chain-hit_v"); + } + + /** + * Gets the victims list. + * @param e The attacking entity. + * @return The victims list. + */ + private List getVictimsList(Entity e, Entity victim) { + List list = e.getAttribute("chain-hit_v"); + if (list == null) { + int distance = 5; + if (victim instanceof NPC) { + e.setAttribute("chain-hit_v", list = RegionManager.getLocalNpcs(e, distance)); + } else { + e.setAttribute("chain-hit_v", list = RegionManager.getLocalPlayers(e, distance)); + } + list.remove(e); + list.remove(victim); + } + return list; + } +} diff --git a/Server/src/main/content/global/handlers/item/equipment/special/ChinchompaSwingHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/ChinchompaSwingHandler.java new file mode 100644 index 0000000..0bd2e6d --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/special/ChinchompaSwingHandler.java @@ -0,0 +1,148 @@ +package content.global.handlers.item.equipment.special; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.*; +import core.game.node.entity.combat.equipment.Ammunition; +import core.game.node.entity.combat.equipment.RangeWeapon; +import core.game.node.entity.combat.equipment.Weapon; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.skill.Skills; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Graphics; +import core.tools.RandomFunction; + +import java.util.List; + +/** + * Handles a combat swing using red chinchompas. + * @author Emperor + */ +public final class ChinchompaSwingHandler extends RangeSwingHandler { + + /** + * The instance. + */ + private static final ChinchompaSwingHandler INSTANCE = new ChinchompaSwingHandler(); + + /** + * The impact graphic. + */ + private static final Graphics END_GRAPHIC = new Graphics(157, 96); + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + boolean multi = entity.getProperties().isMultiZone() && victim.getProperties().isMultiZone(); + state.setStyle(CombatStyle.RANGE); + if (!multi) { + int ticks = super.swing(entity, victim, state); + state.setTargets(new BattleState[] { state }); + return ticks; + } + Player p = (Player) entity; + RangeWeapon rw = RangeWeapon.get(p.getEquipment().getNew(3).getId()); + if (rw == null) { + return -1; + } + Weapon w = new Weapon(p.getEquipment().get(3), rw.getAmmunitionSlot(), p.getEquipment().getNew(rw.getAmmunitionSlot())); + w.setType(rw.getWeaponType()); + state.setRangeWeapon(rw); + state.setAmmunition(Ammunition.get(w.getAmmunition().getId())); + state.setWeapon(w); + if (!Companion.hasAmmo(entity, state)) { + entity.getProperties().getCombatPulse().stop(); + return -1; + } + @SuppressWarnings("rawtypes") + List list = victim instanceof NPC ? RegionManager.getSurroundingNPCs(victim, 14, entity) : RegionManager.getSurroundingPlayers(victim, 14, entity); + BattleState[] targets = new BattleState[list.size()]; + int count = 0; + for (Object o : list) { + Entity e = (Entity) o; + if (canSwing(entity, e) != InteractionType.NO_INTERACT) { + BattleState s = targets[count++] = new BattleState(entity, e); + s.setStyle(CombatStyle.RANGE); + int hit = 0; + if (isAccurateImpact(entity, e, CombatStyle.RANGE)) { + hit = RandomFunction.random(calculateHit(entity, e, 1.0) + 1); + } + s.setEstimatedHit(hit); + } + } + state.setTargets(targets); + Companion.useAmmo(entity, state, null); + return 2 + (int) Math.ceil(entity.getLocation().getDistance(victim.getLocation()) * 0.3); + } + + @Override + public void adjustBattleState(Entity entity, Entity victim, BattleState state) { + for (BattleState s : state.getTargets()) { + if (s != null) { + super.adjustBattleState(entity, s.getVictim(), s); + } + } + } + + @Override + public void addExperience(Entity entity, Entity victim, BattleState state) { + int hit = 0; + for (BattleState s : state.getTargets()) { + if (s != null && s.getEstimatedHit() > 0) { + hit += s.getEstimatedHit(); + } + } + entity.getSkills().addExperience(Skills.HITPOINTS, hit * 1.33, true); + if (entity.getProperties().getAttackStyle().getStyle() == WeaponInterface.STYLE_DEFENSIVE) { + entity.getSkills().addExperience(Skills.RANGE, hit * 2, true); + entity.getSkills().addExperience(Skills.DEFENCE, hit * 2, true); + } else { + entity.getSkills().addExperience(Skills.RANGE, hit * 4, true); + } + } + + @Override + public void visualize(Entity entity, Entity victim, BattleState state) { + Graphics start = null; + if (state.getAmmunition() != null && state.getAmmunition().getProjectile() != null) { + start = state.getAmmunition().getStartGraphics(); + if (victim != null) { + state.getAmmunition().getProjectile().copy(entity, victim, 5).send(); + } + } + RangeWeapon weapon; + int anim = entity.getProperties().getAttackAnimation().getId(); + if ((anim == 422 || anim == 423) && state.getWeapon().getId() > 0 && (weapon = RangeWeapon.get(state.getWeapon().getId())) != null) { + entity.visualize(weapon.getAnimation(), start); + return; + } + entity.visualize(entity.getProperties().getAttackAnimation(), start); + } + + @Override + public void impact(final Entity entity, final Entity victim, final BattleState state) { + for (BattleState s : state.getTargets()) { + if (s != null) { + super.impact(entity, s.getVictim(), s); + } + } + } + + @Override + public void visualizeImpact(Entity entity, Entity victim, BattleState state) { + victim.graphics(END_GRAPHIC); + for (BattleState s : state.getTargets()) { + if (s != null) { + s.getVictim().animate(s.getVictim().getProperties().getDefenceAnimation()); + } + } + } + + /** + * Gets the ChinchompaSwingHandler instance. + * @return The instance. + */ + public static ChinchompaSwingHandler getInstance() { + return INSTANCE; + } +} diff --git a/Server/src/main/content/global/handlers/item/equipment/special/CleaveSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/CleaveSpecialHandler.java new file mode 100644 index 0000000..f728dba --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/special/CleaveSpecialHandler.java @@ -0,0 +1,72 @@ +package content.global.handlers.item.equipment.special; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.MeleeSwingHandler; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.Player; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.tools.RandomFunction; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playGlobalAudio; + +/** + * Represents the cleave special handler. + * @author Emperor + * @version 1.0 + */ +@Initializable +public final class CleaveSpecialHandler extends MeleeSwingHandler implements Plugin { + + /** + * The special energy required. + */ + private static final int SPECIAL_ENERGY = 25; + + /** + * The attack animation. + */ + private static final Animation ANIMATION = new Animation(1058, Priority.HIGH); + + /** + * The graphic. + */ + private static final Graphics GRAPHIC = new Graphics(248, 96); + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + if (CombatStyle.MELEE.getSwingHandler().register(1305, this) && CombatStyle.MELEE.getSwingHandler().register(13475, this)) + ; + return this; + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + if (!((Player) entity).getSettings().drainSpecial(SPECIAL_ENERGY)) { + return -1; + } + state.setStyle(CombatStyle.MELEE); + int hit = 0; + if (isAccurateImpact(entity, victim, CombatStyle.MELEE)) { + hit = RandomFunction.random(calculateHit(entity, victim, 1.25) + 1); + } + state.setEstimatedHit(hit); + return 1; + } + + @Override + public void visualize(Entity entity, Entity victim, BattleState state) { + playGlobalAudio(entity.getLocation(), Sounds.CLEAVE_2529); + entity.visualize(ANIMATION, GRAPHIC); + } +} diff --git a/Server/src/main/content/global/handlers/item/equipment/special/ClobberSpecialHandler.kt b/Server/src/main/content/global/handlers/item/equipment/special/ClobberSpecialHandler.kt new file mode 100644 index 0000000..3162918 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/special/ClobberSpecialHandler.kt @@ -0,0 +1,114 @@ +package content.global.handlers.item.equipment.special + +import core.ServerConstants +import core.api.playAudio +import core.game.container.impl.EquipmentContainer +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.combat.MeleeSwingHandler +import core.game.node.entity.combat.equipment.Weapon +import core.game.node.entity.impl.Animator.Priority +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.audio.Audio +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import core.plugin.Initializable +import core.plugin.Plugin +import core.tools.RandomFunction +import org.rs09.consts.Items +import org.rs09.consts.Sounds + + +/** + * Handles the Dragon axe special attack. + * The OSRS special attack can be used instead by setting dragon_axe_use_osrs_spec server constant to true + * @author Crash + */ +@Initializable +class ClobberSpecialHandler : MeleeSwingHandler(), Plugin { + override fun newInstance(arg: Any?): Plugin { + CombatStyle.MELEE.swingHandler.register(ITEM.id, this) + return this + } + + override fun fireEvent(identifier: String, vararg args: Any): Any { + return if (ServerConstants.DRAGON_AXE_USE_OSRS_SPEC && identifier == "instant_spec") true else Unit + } + + override fun visualize(entity: Entity, victim: Entity?, state: BattleState?) { + entity.visualize(ANIMATION, GRAPHIC) + } + + override fun swing(entity: Entity?, victim: Entity?, state: BattleState?): Int { + return if (ServerConstants.DRAGON_AXE_USE_OSRS_SPEC) { + swingOSRS(entity) + } else { + swingAuthentic(entity, victim, state) + } + } + + /** + * https://runescape.wiki/w/Dragon_hatchet?oldid=1107166 + */ + private fun swingAuthentic(entity: Entity?, victim: Entity?, state: BattleState?): Int { + val player = entity as? Player ?: return -1 + if (victim == null) return -1 + if (state == null) return -1 + if (!player.settings.drainSpecial(SPECIAL_ENERGY)) return -1 + + state.style = CombatStyle.MELEE + state.weapon = Weapon(player.equipment[EquipmentContainer.SLOT_WEAPON]) + var hit = 0 + if (isAccurateImpact(entity, victim, CombatStyle.MELEE)) { + val max = calculateHit(entity, victim, 1.0) + state.maximumHit = max + hit = RandomFunction.random(max + 1) + } + state.estimatedHit = hit + + victim.skills.updateLevel(Skills.DEFENCE, -hit, 0) + victim.skills.updateLevel(Skills.MAGIC, -hit, 0) + + playAudio(player, Sounds.CLOBBER_2531, 20) + return 1 + } + + /** + * https://oldschool.runescape.wiki/w/Dragon_axe + */ + private fun swingOSRS(entity: Entity?): Int { + val player = entity as? Player ?: return -1 + if (!player.settings.drainSpecial(SPECIAL_ENERGY)) return -1 + + player.sendChat("Chop chop!") + player.skills.updateLevel(Skills.WOODCUTTING, 3, player.skills.getStaticLevel(Skills.WOODCUTTING) + 3) + visualize(player, null, null) + playAudio(player, Sounds.CLOBBER_2531, 20) + return -1 + } + + companion object { + /** + * The special energy required. + */ + private const val SPECIAL_ENERGY = 100 + + /** + * The attack animation. + */ + private val ANIMATION = Animation(2876, Priority.HIGH) + + /** + * The graphic. + */ + private val GRAPHIC = Graphics(479, 96) + + /** + * The item. + */ + private val ITEM = Item(Items.DRAGON_AXE_6739) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/equipment/special/DescentOfDarknessSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/DescentOfDarknessSpecialHandler.java new file mode 100644 index 0000000..75ae1f8 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/special/DescentOfDarknessSpecialHandler.java @@ -0,0 +1,152 @@ +package content.global.handlers.item.equipment.special; + +import core.cache.def.impl.ItemDefinition; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.equipment.Ammunition; +import core.game.node.entity.combat.equipment.RangeWeapon; +import core.game.node.entity.combat.equipment.Weapon; +import core.game.node.entity.combat.equipment.Weapon.WeaponType; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.player.Player; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.tools.RandomFunction; +import core.game.node.entity.combat.RangeSwingHandler; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playGlobalAudio; + +/** + * Represents the descent of darkness sepcial handler. + * @author Emperor + * @version 1.0 + */ +@Initializable +public final class DescentOfDarknessSpecialHandler extends RangeSwingHandler implements Plugin { + + /** + * The special energy required. + */ + private static final int SPECIAL_ENERGY = 55; + + /** + * The descent of dragons projectile. + */ + private static final Projectile DRAGON_PROJECTILE = Projectile.create((Entity) null, null, 1099, 40, 36, 41, 46, 5, 11); + + /** + * The descent of dragons secondary projectile. + */ + private static final Projectile DRAGON_PROJECTILE_1 = Projectile.create((Entity) null, null, 1099, 40, 36, 41, 55, 25, 11); + + /** + * The descent of darkness projectile. + */ + private static final Projectile DARKNESS_PROJECTILE = Projectile.create((Entity) null, null, 1101, 40, 36, 41, 46, 5, 11); + + /** + * The descent of darkness secondary projectile. + */ + private static final Projectile DARKNESS_PROJECTILE_1 = Projectile.create((Entity) null, null, 1101, 40, 36, 41, 55, 25, 11); + + /** + * The descent of dragons impact graphic. + */ + private static final Graphics DRAGON_IMPACT = new Graphics(1100, 96); + + /** + * The descent of darkness impact graphic. + */ + private static final Graphics DARKNESS_IMPACT = new Graphics(1103, 96); + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + if (CombatStyle.RANGE.getSwingHandler().register(11235, this) && CombatStyle.RANGE.getSwingHandler().register(13405, this) && CombatStyle.RANGE.getSwingHandler().register(14803, this) && CombatStyle.RANGE.getSwingHandler().register(14804, this) && CombatStyle.RANGE.getSwingHandler().register(14805, this) && CombatStyle.RANGE.getSwingHandler().register(14806, this)) + ; + return this; + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + Player p = (Player) entity; + RangeWeapon rw = RangeWeapon.get(p.getEquipment().getNew(3).getId()); + if (rw == null) { + return -1; + } + Weapon w = new Weapon(p.getEquipment().get(3), rw.getAmmunitionSlot(), p.getEquipment().getNew(rw.getAmmunitionSlot())); + w.setType(rw.getWeaponType()); + state.setStyle(CombatStyle.RANGE); + state.setRangeWeapon(rw); + state.setAmmunition(Ammunition.get(w.getAmmunition().getId())); + state.setWeapon(w); + if (!Companion.hasAmmo(entity, state)) { + entity.getProperties().getCombatPulse().stop(); + p.getSettings().toggleSpecialBar(); + return -1; + } + if (!((Player) entity).getSettings().drainSpecial(SPECIAL_ENERGY)) { + return -1; + } + state.setFrozen(ItemDefinition.forId(state.getAmmunition().getItemId()).getName().contains("ragon arrow")); + double mod = state.isFrozen() ? 1.5 : 1.3; + int minDamage = state.isFrozen() ? 8 : 5; + int max = calculateHit(entity, victim, mod); + state.setMaximumHit(max); + int hit = minDamage; + if (isAccurateImpact(entity, victim, CombatStyle.RANGE, 1.15, 1.0)) { + hit += RandomFunction.random(max - minDamage + 1); + } + state.setEstimatedHit(hit); + if (w.getType() == WeaponType.DOUBLE_SHOT) { + hit = minDamage; + if (isAccurateImpact(entity, victim, CombatStyle.RANGE, 1.15, 1.0)) { + hit += RandomFunction.random(max - minDamage + 1); + } + state.setSecondaryHit(hit); + } + Companion.useAmmo(entity, state, victim.getLocation()); + return 1 + (int) Math.ceil(entity.getLocation().getDistance(victim.getLocation()) * 0.3); + } + + @Override + public void visualize(Entity entity, Entity victim, BattleState state) { + Graphics start = null; + if (state.getAmmunition() != null) { + start = state.getAmmunition().getStartGraphics(); + if (state.isFrozen()) { + if (entity instanceof Player) { + } + DRAGON_PROJECTILE.copy(entity, victim, 5).send(); + } else { + state.getAmmunition().getProjectile().copy(entity, victim, 5).send(); + DARKNESS_PROJECTILE.copy(entity, victim, 5).send(); + } + if (state.getWeapon().getType() == WeaponType.DOUBLE_SHOT && state.getAmmunition().getDarkBowGraphics() != null) { + start = state.getAmmunition().getDarkBowGraphics(); + if (state.isFrozen()) { + DRAGON_PROJECTILE_1.copy(entity, victim, 10).send(); + } else { + int speed = (int) (55 + (entity.getLocation().getDistance(victim.getLocation()) * 10)); + Projectile.create(entity, victim, state.getAmmunition().getProjectile().getProjectileId(), 40, 36, 41, speed, 25).send(); + DARKNESS_PROJECTILE_1.copy(entity, victim, 10).send(); + } + } + } + entity.visualize(entity.getProperties().getAttackAnimation(), start); + } + + @Override + public void visualizeImpact(Entity entity, Entity victim, BattleState state) { + playGlobalAudio(victim.getLocation(), Sounds.DARKBOW_SHADOW_ATTACK_3736, 20); + playGlobalAudio(victim.getLocation(), Sounds.DARKBOW_SHADOW_IMPACT_3737, 40); + victim.visualize(victim.getProperties().getDefenceAnimation(), state.isFrozen() ? DRAGON_IMPACT : DARKNESS_IMPACT); + } +} diff --git a/Server/src/main/content/global/handlers/item/equipment/special/DragonfireSwingHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/DragonfireSwingHandler.java new file mode 100644 index 0000000..0497836 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/special/DragonfireSwingHandler.java @@ -0,0 +1,209 @@ +package content.global.handlers.item.equipment.special; + +import core.game.container.impl.EquipmentContainer; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.node.entity.combat.InteractionType; +import core.game.node.entity.combat.equipment.SwitchAttack; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.GameWorld; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.tools.RandomFunction; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.*; + +/** + * Handles dragonfire combat. + * @author Emperor + */ +public class DragonfireSwingHandler extends CombatSwingHandler { + + /** + * If the NPC has to be in melee range. + */ + private boolean meleeRange; + + /** + * The maximum hit. + */ + private int maximumHit; + + /** + * The attack data. + */ + private SwitchAttack attack; + + /** + * IF the dragon attack is firey or icey. + */ + private boolean fire; + + /** + * Constructs a new {@code DragonfireSwingHandler} {@code Object}. + * @param meleeRange If the NPC has to be in melee range. + * @param maximumHit The maximum hit. + * @param fire if firey. + */ + public DragonfireSwingHandler(boolean meleeRange, int maximumHit, SwitchAttack attack, boolean fire) { + super(CombatStyle.MAGIC); + this.meleeRange = meleeRange; + this.maximumHit = maximumHit; + this.attack = attack; + this.fire = fire; + } + + /** + * Gets the switch attack instance for a dragonfire attack. + * @param meleeRange If the attack is melee range. + * @param maximumHit The maximum hit. + * @param animation The animation. + * @param startGraphic The start graphic. + * @param endGraphic The end graphic. + * @param projectile The projectile. + * @return The switch attack instance. + */ + public static SwitchAttack get(boolean meleeRange, int maximumHit, Animation animation, Graphics startGraphic, Graphics endGraphic, Projectile projectile) { + SwitchAttack attack = new SwitchAttack(null, animation, startGraphic, endGraphic, projectile).setUseHandler(true); + attack.setHandler(new DragonfireSwingHandler(meleeRange, maximumHit, attack, true)); + return attack; + } + + /** + * Gets the switch attack instance for a dragonfire attack. + * @param meleeRange If the attack is melee range. + * @param maximumHit The maximum hit. + * @param animation The animation. + * @param startGraphic The start graphic. + * @param endGraphic The end graphic. + * @param projectile The projectile. + * @return The switch attack instance. + */ + public static SwitchAttack get(boolean meleeRange, int maximumHit, Animation animation, Graphics startGraphic, Graphics endGraphic, Projectile projectile, boolean fire) { + SwitchAttack attack = new SwitchAttack(null, animation, startGraphic, endGraphic, projectile).setUseHandler(true); + attack.setHandler(new DragonfireSwingHandler(meleeRange, maximumHit, attack, fire)); + return attack; + } + + @Override + public InteractionType canSwing(Entity entity, Entity victim) { + if (meleeRange) { + return CombatStyle.MELEE.getSwingHandler().canSwing(entity, victim); + } + return CombatStyle.MAGIC.getSwingHandler().canSwing(entity, victim); + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + int max = calculateHit(entity, victim, 1.0); + int hit = RandomFunction.random(max + 1); + assert state != null; + state.setMaximumHit(max); + state.setStyle(CombatStyle.MAGIC); + state.setEstimatedHit(hit); + if (meleeRange) { + return 1; + } + int ticks = 2 + (int) Math.floor(entity.getLocation().getDistance(victim.getLocation()) * 0.5); + entity.setAttribute("fireBreath", GameWorld.getTicks() + (ticks + 2)); + return ticks; + } + + @Override + public void visualize(Entity entity, Entity victim, BattleState state) { + entity.visualize(attack.getAnimation(), attack.getStartGraphic()); + if (attack.getProjectile() != null) { + attack.getProjectile().copy(entity, victim, 5).send(); + } + } + + @Override + public void visualizeImpact(Entity entity, Entity victim, BattleState state) { + if (entity instanceof NPC && victim instanceof Player) { + Player p = (Player) victim; + Item shield = p.getEquipment().get(EquipmentContainer.SLOT_SHIELD); + if (shield != null && (shield.getId() == 11283 || shield.getId() == 11284)) { + if (shield.getId() == 11284) { + p.getEquipment().replace(new Item(11283), EquipmentContainer.SLOT_SHIELD); + shield = p.getEquipment().get(EquipmentContainer.SLOT_SHIELD); + shield.setCharge(0); + } + if (shield.getCharge() < 1000) { + shield.setCharge(shield.getCharge() + 20); + EquipmentContainer.updateBonuses(p); + p.getPacketDispatch().sendMessage("Your dragonfire shield glows more brightly."); + playAudio(p, Sounds.DRAGONSLAYER_ABSORB_FIRE_3740); + p.faceLocation(entity.getCenterLocation()); + victim.visualize(Animation.create(6695), Graphics.create(1163)); + } else { + p.getPacketDispatch().sendMessage("Your dragonfire shield is already fully charged."); + } + return; + } + } + if (!fire && !hasTimerActive(victim, "frozen:immunity") && RandomFunction.random(4) == 2) { + registerTimer(victim, spawnTimer("frozen", 16, true)); + victim.graphics(Graphics.create(502)); + } + Graphics graphic = attack != null ? attack.getEndGraphic() : null; + victim.visualize(victim.getProperties().getDefenceAnimation(), graphic); + } + + @Override + public void impact(Entity entity, Entity victim, BattleState state) { + assert state != null; + int hit = state.getEstimatedHit(); + if (hit > -1) { + victim.getImpactHandler().handleImpact(entity, hit, CombatStyle.MAGIC, state); + } + hit = state.getSecondaryHit(); + if (hit > -1) { + victim.getImpactHandler().handleImpact(entity, hit, CombatStyle.MAGIC, state); + } + } + + @Override + public void adjustBattleState(Entity entity, Entity victim, BattleState state) { + if (victim.isPlayer() && !fire) { + Item item = victim.asPlayer().getEquipment().get(EquipmentContainer.SLOT_SHIELD); + if (item != null && (item.getId() == 2890 || item.getId() == 9731) && state.getEstimatedHit() > 10) { + state.setEstimatedHit(RandomFunction.random(10)); + } + } + CombatStyle style = state.getStyle(); + super.adjustBattleState(entity, victim, state); + state.setStyle(style); + } + + @Override + protected int getFormattedHit(Entity entity, Entity victim, BattleState state, int hit) { + return formatHit(victim, hit); + } + + @Override + public int calculateAccuracy(Entity entity) { + return 4000; + } + + @Override + public int calculateHit(Entity entity, Entity victim, double modifier) { + return calculateDragonfireMaxHit(victim, maximumHit, !fire, 0, true); + } + + @Override + public int calculateDefence(Entity victim, Entity attacker) { + return CombatStyle.MAGIC.getSwingHandler().calculateDefence(victim, attacker); + } + + @Override + public double getSetMultiplier(Entity e, int skillId) { + return 1.0; + } + +} diff --git a/Server/src/main/content/global/handlers/item/equipment/special/EnergyDrainSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/EnergyDrainSpecialHandler.java new file mode 100644 index 0000000..4686eb2 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/special/EnergyDrainSpecialHandler.java @@ -0,0 +1,77 @@ +package content.global.handlers.item.equipment.special; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.MeleeSwingHandler; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.audio.Audio; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.tools.RandomFunction; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playGlobalAudio; + +/** + * Handles the Abyssal whip's Energy drain special attack. + * @author Emperor + * @version 1.0 + */ +@Initializable +public final class EnergyDrainSpecialHandler extends MeleeSwingHandler implements Plugin { + + /** + * The special energy required. + */ + private static final int SPECIAL_ENERGY = 50; + + /** + * The attack animation. + */ + private static final Animation ANIMATION = new Animation(1658, Priority.HIGH); + + /** + * The graphic. + */ + private static final Graphics GRAPHIC = new Graphics(341, 96); + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + CombatStyle.MELEE.getSwingHandler().register(4151, this); + return this; + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + if (!((Player) entity).getSettings().drainSpecial(SPECIAL_ENERGY)) { + return -1; + } + state.setStyle(CombatStyle.MELEE); + int hit = 0; + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.25, 1.0)) { + hit = RandomFunction.random(calculateHit(entity, victim, 1) + 1); + } + if (victim instanceof Player) { + ((Player) victim).getSettings().updateRunEnergy(10); + ((Player) entity).getSettings().updateRunEnergy(-10); + } + state.setEstimatedHit(hit); + return 1; + } + + @Override + public void visualize(Entity entity, Entity victim, BattleState state) { + playGlobalAudio(entity.getLocation(), Sounds.ENERGYDRAIN_2713); + entity.animate(ANIMATION); + victim.graphics(GRAPHIC); + } +} diff --git a/Server/src/main/content/global/handlers/item/equipment/special/ExcaliburSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/ExcaliburSpecialHandler.java new file mode 100644 index 0000000..3ba8c99 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/special/ExcaliburSpecialHandler.java @@ -0,0 +1,80 @@ +package content.global.handlers.item.equipment.special; + +import core.game.container.impl.EquipmentContainer; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.MeleeSwingHandler; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.Player; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.plugin.Plugin; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.*; + +/** + * Handles the excalibur special attack. + * + * @author Emperor + * @version 1.0 + */ +@Initializable +public final class ExcaliburSpecialHandler extends MeleeSwingHandler implements Plugin { + + /** + * The special energy required. + */ + private static final int SPECIAL_ENERGY = 100; + + /** + * The attack animation. + */ + private static final Animation ANIMATION = new Animation(1057, Priority.HIGH); + + /** + * The graphic. + */ + private static final Graphics GRAPHIC = new Graphics(247); + + @Override + public Object fireEvent(String identifier, Object... args) { + switch (identifier) { + case "instant_spec": + case "ncspec": + return true; + } + return null; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + CombatStyle.MELEE.getSwingHandler().register(35, this); + CombatStyle.MELEE.getSwingHandler().register(14632, this); + return this; + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + Player p = (Player) entity; + if (!p.getSettings().drainSpecial(SPECIAL_ENERGY)) + return -1; + p.sendChat("For Camelot!"); + playAudio(entity.asPlayer(), Sounds.SANCTUARY_2539); + p.visualize(ANIMATION, GRAPHIC); + switch(p.getEquipment().get(EquipmentContainer.SLOT_WEAPON).getId()) { + case 35: // Regular ol' excalibur + p.getSkills().updateLevel(Skills.DEFENCE, 8, p.getSkills().getStaticLevel(Skills.DEFENCE) + 8); + break; + case 14632: // enhanced excalibur + registerTimer(p, spawnTimer("healovertime", 3, 20, 4)); + p.getSkills().updateLevel(Skills.DEFENCE, + (int)(p.getSkills().getStaticLevel(Skills.DEFENCE)*0.15), + (int)(p.getSkills().getStaticLevel(Skills.DEFENCE)*1.15)); + } + return -1; + } +} diff --git a/Server/src/main/content/global/handlers/item/equipment/special/FeintSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/FeintSpecialHandler.java new file mode 100644 index 0000000..b859627 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/special/FeintSpecialHandler.java @@ -0,0 +1,68 @@ +package content.global.handlers.item.equipment.special; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.MeleeSwingHandler; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.Player; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.tools.RandomFunction; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playGlobalAudio; + +/** + * Handles Vesta's Longsword special attack, feint. + * @author Splinter + * @version 1.0 + */ +@Initializable +public final class FeintSpecialHandler extends MeleeSwingHandler implements Plugin { + + /** + * The special energy required. + */ + private static final int SPECIAL_ENERGY = 25; + + /** + * The attack animation. + */ + private static final Animation ANIMATION = new Animation(10502, Priority.HIGH); + + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + if (CombatStyle.MELEE.getSwingHandler().register(13899, this) && CombatStyle.MELEE.getSwingHandler().register(13901, this)) + ; + return this; + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + if (!((Player) entity).getSettings().drainSpecial(SPECIAL_ENERGY)) { + return -1; + } + state.setStyle(CombatStyle.MELEE); + int hit = 0; + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.0, 0.25)) { + int minDamage = calculateHit(entity, victim, 0.2); + hit = minDamage + RandomFunction.random(calculateHit(entity, victim, 1.0) + 1); + } + state.setEstimatedHit(hit); + return 1; + } + + @Override + public void visualize(Entity entity, Entity victim, BattleState state) { + playGlobalAudio(entity.getLocation(), Sounds.CLEAVE_2529); + entity.animate(ANIMATION); + } +} diff --git a/Server/src/main/content/global/handlers/item/equipment/special/HamstringSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/HamstringSpecialHandler.java new file mode 100644 index 0000000..6a89af4 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/special/HamstringSpecialHandler.java @@ -0,0 +1,71 @@ +package content.global.handlers.item.equipment.special; + +import core.api.ContentAPIKt; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.ImpactHandler; +import core.game.node.entity.combat.RangeSwingHandler; +import core.game.node.entity.player.Player; +import core.game.system.timer.RSTimer; +import core.game.system.timer.TimerFlag; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.tools.RandomFunction; +import org.rs09.consts.Items; + +@Initializable +public final class HamstringSpecialHandler extends RangeSwingHandler implements Plugin { + private static final int SPECIAL_ENERGY = 50; + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + CombatStyle.RANGE.getSwingHandler().register(Items.MORRIGANS_THROWING_AXE_13883, this); + return this; + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + Player p = (Player) entity; + configureRangeData(p, state); + if (state.getWeapon() == null || !Companion.hasAmmo(entity, state)) { + entity.getProperties().getCombatPulse().stop(); + p.getSettings().toggleSpecialBar(); + return -1; + } + if (!((Player) entity).getSettings().drainSpecial(SPECIAL_ENERGY)) { + return -1; + } + state.setStyle(CombatStyle.RANGE); + int max = calculateHit(entity, victim, 1.2); + state.setMaximumHit(max); + int hit = 0; + if (isAccurateImpact(entity, victim)) { + int minDamage = calculateHit(entity, victim, 0.2); + hit = minDamage + RandomFunction.random(calculateHit(entity, victim, 1.0) + 1); + } + state.setEstimatedHit(hit); + Companion.useAmmo(entity, state, victim.getLocation()); + ContentAPIKt.registerTimer(victim, new RSTimer(100, "hamstrung", true, false, new TimerFlag[] { TimerFlag.ClearOnDeath } ) { + @Override + public void onRegister(Entity entity) { + if(entity instanceof Player) { + ((Player)entity).sendMessage("You've been hamstrung! For the next minute, your run energy will drain 4x faster."); + } + } + + @Override + public boolean run(Entity entity) { + return false; + } + + }); + return 1 + (int) Math.ceil(entity.getLocation().getDistance(victim.getLocation()) * 0.3); + } +} + diff --git a/Server/src/main/content/global/handlers/item/equipment/special/HealingBladeSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/HealingBladeSpecialHandler.java new file mode 100644 index 0000000..5589c48 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/special/HealingBladeSpecialHandler.java @@ -0,0 +1,83 @@ +package content.global.handlers.item.equipment.special; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.MeleeSwingHandler; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.Player; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Plugin; +import core.plugin.Initializable; +import core.tools.RandomFunction; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playGlobalAudio; + +/** + * Handles the healing blade special attack. + * @author Emperor + * @version 1.0 + */ +@Initializable +public final class HealingBladeSpecialHandler extends MeleeSwingHandler implements Plugin { + + /** + * The special energy required. + */ + private static final int SPECIAL_ENERGY = 50; + + /** + * The attack animation. + */ + private static final Animation ANIMATION = new Animation(7071, Priority.HIGH); + + /** + * The graphic. + */ + private static final Graphics GRAPHIC = new Graphics(1220); + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + CombatStyle.MELEE.getSwingHandler().register(11698, this); + CombatStyle.MELEE.getSwingHandler().register(13452, this); + return this; + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + if (!((Player) entity).getSettings().drainSpecial(SPECIAL_ENERGY)) { + return -1; + } + state.setStyle(CombatStyle.MELEE); + int hit = 0; + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 2.0, 1.0)) { + hit = RandomFunction.random(calculateHit(entity, victim, 1.1) + 1); + int healthRestore = hit / 2; + double prayerRestore = hit * 0.25; + if (healthRestore < 10) { + healthRestore = 10; + } + if (prayerRestore < 5) { + prayerRestore = 5; + } + entity.getSkills().heal(healthRestore); + entity.getSkills().incrementPrayerPoints(prayerRestore); + } + state.setEstimatedHit(hit); + return 1; + } + + @Override + public void visualize(Entity entity, Entity victim, BattleState state) { + playGlobalAudio(entity.getLocation(), Sounds.GODWARS_SARADOMIN_SPECIAL_3857); + entity.visualize(ANIMATION, GRAPHIC); + } + +} diff --git a/Server/src/main/content/global/handlers/item/equipment/special/IceCleaveSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/IceCleaveSpecialHandler.java new file mode 100644 index 0000000..83c1e4a --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/special/IceCleaveSpecialHandler.java @@ -0,0 +1,81 @@ +package content.global.handlers.item.equipment.special; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.MeleeSwingHandler; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.Player; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Plugin; +import core.plugin.Initializable; +import core.tools.RandomFunction; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.*; + +/** + * Handles the Ice cleave special attack. + * @author Emperor + * @version 1.0 + */ +@Initializable +public final class IceCleaveSpecialHandler extends MeleeSwingHandler implements Plugin { + + /** + * The special energy required. + */ + private static final int SPECIAL_ENERGY = 60; + + /** + * The attack animation. + */ + private static final Animation ANIMATION = new Animation(7070, Priority.HIGH); + + /** + * The graphic. + */ + private static final Graphics GRAPHIC = new Graphics(1221); + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + CombatStyle.MELEE.getSwingHandler().register(11700, this); + CombatStyle.MELEE.getSwingHandler().register(13453, this); + return this; + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + if (!((Player) entity).getSettings().drainSpecial(SPECIAL_ENERGY)) { + return -1; + } + state.setStyle(CombatStyle.MELEE); + int hit = 0; + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 2.0, 1.0)) { + hit = RandomFunction.random(calculateHit(entity, victim, 1.1) + 1); + } + state.setEstimatedHit(hit); + return 1; + } + + @Override + public void adjustBattleState(Entity entity, Entity victim, BattleState state) { + super.adjustBattleState(entity, victim, state); + if (state.getEstimatedHit() > 0) { + registerTimer(victim, spawnTimer("frozen", 33, true)); + victim.graphics(Graphics.create(369)); + } + } + + @Override + public void visualize(Entity entity, Entity victim, BattleState state) { + playGlobalAudio(entity.getLocation(), Sounds.GODWARS_GODSWORD_SLASH_3846); + entity.visualize(ANIMATION, GRAPHIC); + } +} diff --git a/Server/src/main/content/global/handlers/item/equipment/special/ImpaleSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/ImpaleSpecialHandler.java new file mode 100644 index 0000000..2e0ff5a --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/special/ImpaleSpecialHandler.java @@ -0,0 +1,77 @@ +package content.global.handlers.item.equipment.special; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.MeleeSwingHandler; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.info.Rights; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Plugin; +import core.plugin.Initializable; +import core.tools.RandomFunction; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playGlobalAudio; + +/** + * Handles the Rune claws special attack "Impale". + * @author Emperor + * @version 1.0 + */ +@Initializable +public final class ImpaleSpecialHandler extends MeleeSwingHandler implements Plugin { + + /** + * The special energy required. + */ + private static final int SPECIAL_ENERGY = 25; + + /** + * The attack animation. + */ + private static final Animation ANIMATION = new Animation(923, Priority.HIGH); + + /** + * The graphic. + */ + private static final Graphics GRAPHIC = new Graphics(274, 96); + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + CombatStyle.MELEE.getSwingHandler().register(3101, this); + return this; + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + Player player = (Player) entity; + if (!player.getSettings().drainSpecial(SPECIAL_ENERGY)) { + return -1; + } + state.setStyle(CombatStyle.MELEE); + int hit = 0; + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.1, 0.98)) { + hit = RandomFunction.random(calculateHit(entity, victim, 1.1) + 1); + } + state.setEstimatedHit(hit); + return 1; + } + + @Override + public void visualize(Entity entity, Entity victim, BattleState state) { + playGlobalAudio(entity.getLocation(), Sounds.IMPALE_2534); + if (((Player) entity).getDetails().getRights() == Rights.ADMINISTRATOR) { + entity.animate(Animation.create(2068)); + return; + } + entity.visualize(ANIMATION, GRAPHIC); + } +} diff --git a/Server/src/main/content/global/handlers/item/equipment/special/JudgementSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/JudgementSpecialHandler.java new file mode 100644 index 0000000..abdb00c --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/special/JudgementSpecialHandler.java @@ -0,0 +1,72 @@ +package content.global.handlers.item.equipment.special; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.MeleeSwingHandler; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.Player; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.tools.RandomFunction; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playGlobalAudio; + +/** + * Handles the Judgement special attack. + * @author Emperor + * @version 1.0 + */ +@Initializable +public final class JudgementSpecialHandler extends MeleeSwingHandler implements Plugin { + + /** + * The special energy required. + */ + private static final int SPECIAL_ENERGY = 50; + + /** + * The attack animation. + */ + private static final Animation ANIMATION = new Animation(7074, Priority.HIGH); + + /** + * The graphic. + */ + private static final Graphics GRAPHIC = new Graphics(1222); + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + if (CombatStyle.MELEE.getSwingHandler().register(11694, this) && CombatStyle.MELEE.getSwingHandler().register(13450, this)) + ; + return this; + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + if (!((Player) entity).getSettings().drainSpecial(SPECIAL_ENERGY)) { + return -1; + } + state.setStyle(CombatStyle.MELEE); + int hit = 0; + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 2.0, 1.0)) { + hit = RandomFunction.random((int) (calculateHit(entity, victim, 1.1) * 1.25) + 1); + } + state.setEstimatedHit(hit); + return 1; + } + + @Override + public void visualize(Entity entity, Entity victim, BattleState state) { + playGlobalAudio(entity.getLocation(), Sounds.GODWARS_GODSWORD_SPECIAL_ATTACK_3865); + entity.visualize(ANIMATION, GRAPHIC); + } +} diff --git a/Server/src/main/content/global/handlers/item/equipment/special/LiquefySpecialHandler.kt b/Server/src/main/content/global/handlers/item/equipment/special/LiquefySpecialHandler.kt new file mode 100644 index 0000000..0cf2591 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/special/LiquefySpecialHandler.kt @@ -0,0 +1,27 @@ +package content.global.handlers.item.equipment.special + +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.combat.MeleeSwingHandler +import core.plugin.Initializable +import core.plugin.Plugin + +@Initializable +class LiquefySpecialHandler : MeleeSwingHandler(), Plugin { + override fun newInstance(arg: Any?): Plugin { + CombatStyle.MELEE.swingHandler.register(11037,this) + return this + } + + override fun fireEvent(identifier: String?, vararg args: Any?): Any { + return Unit + } + + override fun swing(entity: Entity?, victim: Entity?, state: BattleState?): Int { + entity?.asPlayer()?.sendMessage("You need to be underwater to use this special attack.") + entity?.asPlayer()?.settings?.isSpecialToggled = false + return super.swing(entity, victim, state) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/equipment/special/PhantomStrikeSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/PhantomStrikeSpecialHandler.java new file mode 100644 index 0000000..82f5b3e --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/special/PhantomStrikeSpecialHandler.java @@ -0,0 +1,82 @@ +package content.global.handlers.item.equipment.special; + +import core.api.ContentAPIKt; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.ImpactHandler; +import core.game.node.entity.combat.RangeSwingHandler; +import core.game.node.entity.player.Player; +import core.game.system.timer.RSTimer; +import core.game.system.timer.TimerFlag; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.tools.RandomFunction; +import org.rs09.consts.Items; + +@Initializable +public final class PhantomStrikeSpecialHandler extends RangeSwingHandler implements Plugin { + private static final int SPECIAL_ENERGY = 50; + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + CombatStyle.RANGE.getSwingHandler().register(Items.MORRIGANS_JAVELIN_13879, this); + CombatStyle.RANGE.getSwingHandler().register(Items.MORRIGANS_JAVELINP_13880, this); + CombatStyle.RANGE.getSwingHandler().register(Items.MORRIGANS_JAVELINP_PLUS_13881, this); + CombatStyle.RANGE.getSwingHandler().register(Items.MORRIGANS_JAVELINP_PLUS_PLUS_13882, this); + return this; + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + Player p = (Player) entity; + configureRangeData(p, state); + if (state.getWeapon() == null || !Companion.hasAmmo(entity, state)) { + entity.getProperties().getCombatPulse().stop(); + p.getSettings().toggleSpecialBar(); + return -1; + } + if (!((Player) entity).getSettings().drainSpecial(SPECIAL_ENERGY)) { + return -1; + } + state.setStyle(CombatStyle.RANGE); + int max = calculateHit(entity, victim, 1.0); + state.setMaximumHit(max); + int hit = 0; + if (isAccurateImpact(entity, victim)) { + hit = RandomFunction.random(max + 1); + } + state.setEstimatedHit(hit); + Companion.useAmmo(entity, state, victim.getLocation()); + final Entity attacker = entity; + final int initialDamage = hit; + ContentAPIKt.registerTimer(victim, new RSTimer(3, "phantom-strike", true, false, new TimerFlag[] { TimerFlag.ClearOnDeath } ) { + int remainingDamage = initialDamage; + + @Override + public void onRegister(Entity entity) { + if(entity instanceof Player) { + ((Player)entity).sendMessage("You start to bleed as the result of the javelin strike."); + } + } + + @Override + public boolean run(Entity entity) { + if(entity instanceof Player) { + ((Player)entity).sendMessage("You continue to bleed as the result of the javelin strike."); + } + int tickDamage = Math.min(remainingDamage, 5); + remainingDamage -= tickDamage; + entity.getImpactHandler().manualHit(attacker, tickDamage, ImpactHandler.HitsplatType.NORMAL); + return remainingDamage > 0; + } + + }); + return 1 + (int) Math.ceil(entity.getLocation().getDistance(victim.getLocation()) * 0.3); + } +} diff --git a/Server/src/main/content/global/handlers/item/equipment/special/PowershotSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/PowershotSpecialHandler.java new file mode 100644 index 0000000..4fe5e5f --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/special/PowershotSpecialHandler.java @@ -0,0 +1,72 @@ +package content.global.handlers.item.equipment.special; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.player.Player; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.tools.RandomFunction; +import core.game.node.entity.combat.RangeSwingHandler; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playGlobalAudio; + +/** + * Handles the Magic longbow special attack "Powershot". + * @author Emperor + */ +@Initializable +public final class PowershotSpecialHandler extends RangeSwingHandler implements Plugin { + + /** + * The special energy required. + */ + private static final int SPECIAL_ENERGY = 35; + + /** + * The graphic. + */ + private static final Graphics GRAPHIC = new Graphics(250, 96); + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + CombatStyle.RANGE.getSwingHandler().register(859, this); + CombatStyle.RANGE.getSwingHandler().register(10284, this); + return this; + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + Player p = (Player) entity; + configureRangeData(p, state); + if (state.getWeapon() == null || !Companion.hasAmmo(entity, state)) { + entity.getProperties().getCombatPulse().stop(); + p.getSettings().toggleSpecialBar(); + return -1; + } + if (!((Player) entity).getSettings().drainSpecial(SPECIAL_ENERGY)) { + return -1; + } + state.setStyle(CombatStyle.RANGE); + int hit = RandomFunction.random(calculateHit(entity, victim, 1.0) + 1); + state.setEstimatedHit(hit); + Companion.useAmmo(entity, state, victim.getLocation()); + return 1 + (int) Math.ceil(entity.getLocation().getDistance(victim.getLocation()) * 0.3); + } + + @Override + public void visualize(Entity entity, Entity victim, BattleState state) { + playGlobalAudio(entity.getLocation(), Sounds.POWERSHOT_2536); + entity.visualize(state.getRangeWeapon().getAnimation(), GRAPHIC); + int speed = (int) (46 + (entity.getLocation().getDistance(victim.getLocation()) * 5)); + Projectile.create(entity, victim, 249, 40, 36, 45, speed, 5, 11).send(); + } +} diff --git a/Server/src/main/content/global/handlers/item/equipment/special/PowerstabSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/PowerstabSpecialHandler.java new file mode 100644 index 0000000..172ca03 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/special/PowerstabSpecialHandler.java @@ -0,0 +1,116 @@ +package content.global.handlers.item.equipment.special; + +import java.util.List; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.InteractionType; +import core.game.node.entity.combat.MeleeSwingHandler; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Plugin; +import core.plugin.Initializable; +import core.tools.RandomFunction; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playGlobalAudio; + +/** + * Handles the Powerstab special attack. + * @author Emperor + */ +@Initializable +public final class PowerstabSpecialHandler extends MeleeSwingHandler implements Plugin { + + /** + * The special energy required. + */ + private static final int SPECIAL_ENERGY = 60; + + /** + * The attack animation. + */ + private static final Animation ANIMATION = new Animation(3157, Priority.HIGH); + + /** + * The graphic. + */ + private static final Graphics GRAPHIC = new Graphics(1225); + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public void impact(Entity entity, Entity victim, BattleState state) { + if (state.getTargets() != null) { + for (BattleState s : state.getTargets()) { + if (s != null) { + s.getVictim().getImpactHandler().handleImpact(entity, s.getEstimatedHit(), CombatStyle.MELEE, s); + } + } + return; + } + victim.getImpactHandler().handleImpact(entity, state.getEstimatedHit(), CombatStyle.MELEE, state); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + CombatStyle.MELEE.getSwingHandler().register(7158, this); + return this; + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + if (!((Player) entity).getSettings().drainSpecial(SPECIAL_ENERGY)) { + return -1; + } + boolean multi = entity.getProperties().isMultiZone(); + if (!multi) { + return super.swing(entity, victim, state); + } + @SuppressWarnings("rawtypes") + List list = victim instanceof NPC ? RegionManager.getSurroundingNPCs(entity, 9, entity) : RegionManager.getSurroundingPlayers(entity, 9, entity); + BattleState[] targets = new BattleState[list.size()]; + int count = 0; + for (Object o : list) { + Entity e = (Entity) o; + if (CombatStyle.RANGE.getSwingHandler().canSwing(entity, e) != InteractionType.NO_INTERACT) { + BattleState s = targets[count++] = new BattleState(entity, e); + int hit = 0; + if (isAccurateImpact(entity, e)) { + hit = RandomFunction.random(calculateHit(entity, e, 1.0) + 1); + } + s.setStyle(CombatStyle.MELEE); + s.setEstimatedHit(hit); + } + } + state.setTargets(targets); + return 1; + } + + @Override + public void visualize(Entity entity, Entity victim, BattleState state) { + playGlobalAudio(entity.getLocation(), Sounds.DRAGON_AXE_THUNDER_2530); + entity.visualize(ANIMATION, GRAPHIC); + } + + @Override + public void visualizeImpact(Entity entity, Entity victim, BattleState state) { + if (state.getTargets() != null) { + for (BattleState s : state.getTargets()) { + if (s != null) { + s.getVictim().animate(victim.getProperties().getDefenceAnimation()); + } + } + return; + } + victim.animate(victim.getProperties().getDefenceAnimation()); + } +} diff --git a/Server/src/main/content/global/handlers/item/equipment/special/PunctureSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/PunctureSpecialHandler.java new file mode 100644 index 0000000..b5fc335 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/special/PunctureSpecialHandler.java @@ -0,0 +1,83 @@ +package content.global.handlers.item.equipment.special; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.MeleeSwingHandler; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.Player; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.tools.RandomFunction; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playGlobalAudio; + +/** + * Handles the puncture special attack combat swing. + * @author Emperor + */ +@Initializable +public final class PunctureSpecialHandler extends MeleeSwingHandler implements Plugin { + + /** + * The special energy required. + */ + private static final int SPECIAL_ENERGY = 25; + + /** + * The attack animation. + */ + private static final Animation ANIMATION = new Animation(1062, Priority.HIGH); + + /** + * The graphic. + */ + private static final Graphics GRAPHIC = new Graphics(252, 96); + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public void impact(Entity entity, Entity victim, BattleState state) { + victim.getImpactHandler().handleImpact(entity, state.getEstimatedHit(), CombatStyle.MELEE, state); + victim.getImpactHandler().handleImpact(entity, state.getSecondaryHit(), CombatStyle.MELEE, state, null, true); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + if (CombatStyle.MELEE.getSwingHandler().register(1215, this) && CombatStyle.MELEE.getSwingHandler().register(1231, this) && CombatStyle.MELEE.getSwingHandler().register(5680, this) && CombatStyle.MELEE.getSwingHandler().register(5698, this) && CombatStyle.MELEE.getSwingHandler().register(13465, this) && CombatStyle.MELEE.getSwingHandler().register(13466, this) && CombatStyle.MELEE.getSwingHandler().register(13467, this) && CombatStyle.MELEE.getSwingHandler().register(13468, this)) + ; + return this; + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + if (!((Player) entity).getSettings().drainSpecial(SPECIAL_ENERGY)) { + return -1; + } + state.setStyle(CombatStyle.MELEE); + int hit = 0; + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.15, 1.0)) { + hit = RandomFunction.random(calculateHit(entity, victim, 1.15) + 1); + } + state.setEstimatedHit(hit); + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.15, 1.0)) { + hit = RandomFunction.random(calculateHit(entity, victim, 1.15) + 1); + } else { + hit = 0; + } + state.setSecondaryHit(hit); + return 1; + } + + @Override + public void visualize(Entity entity, Entity victim, BattleState state) { + playGlobalAudio(entity.getLocation(), Sounds.PUNCTURE_2537); + entity.visualize(ANIMATION, GRAPHIC); + } +} diff --git a/Server/src/main/content/global/handlers/item/equipment/special/QuickSmashSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/QuickSmashSpecialHandler.java new file mode 100644 index 0000000..e1d043c --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/special/QuickSmashSpecialHandler.java @@ -0,0 +1,96 @@ +package content.global.handlers.item.equipment.special; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.DeathTask; +import core.game.node.entity.combat.MeleeSwingHandler; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.prayer.PrayerType; +import core.game.world.GameWorld; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.tools.RandomFunction; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playGlobalAudio; + +/** + * Handles the granite maul special attack. + * @author Emperor + */ +@Initializable +public final class QuickSmashSpecialHandler extends MeleeSwingHandler implements Plugin { + + /** + * The special energy required. + */ + private static final int SPECIAL_ENERGY = 50; + + /** + * The attack animation. + */ + private static final Animation ANIMATION = new Animation(1667, Priority.HIGH); + + /** + * The graphic. + */ + private static final Graphics GRAPHIC = new Graphics(340, 96); + + @Override + public Object fireEvent(String identifier, Object... args) { + switch (identifier) { + case "instant_spec": + return true; + } + return null; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + CombatStyle.MELEE.getSwingHandler().register(4153, this); + CombatStyle.MELEE.getSwingHandler().register(14792, this); + return this; + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + Player p = (Player) entity; + if (victim == null) { + victim = p.getProperties().getCombatPulse().getLastVictim(); + if (victim == null || GameWorld.getTicks() - p.getAttribute("combat-stop", -1) > 2 || !MeleeSwingHandler.Companion.canMelee(p, victim, 1)) { + p.getPacketDispatch().sendMessage("Warning: Since the maul's special is an instant attack, it will be wasted when used "); + p.getPacketDispatch().sendMessage("on a first strike."); + return -1; + } + } + if (DeathTask.isDead(victim)) { + return -1; + } + if (!p.getSettings().drainSpecial(SPECIAL_ENERGY)) { + return -1; + } + visualize(entity, victim, null); + int hit = 0; + if (isAccurateImpact(entity, victim)) { + hit = RandomFunction.random(calculateHit(entity, victim, 1.0) + 1); + } + if (victim.hasProtectionPrayer(CombatStyle.MELEE)) + hit *= (victim instanceof Player) ? 0.6 : 0; + BattleState b = new BattleState(); + b.setEstimatedHit(victim.getImpactHandler().handleImpact(entity, hit, CombatStyle.MELEE).getAmount()); + addExperience(entity, victim, b); + return 1; + } + + @Override + public void visualize(Entity entity, Entity victim, BattleState state) { + playGlobalAudio(entity.getLocation(), Sounds.QUICKSMASH_2715); + entity.visualize(ANIMATION, GRAPHIC); + victim.animate(victim.getProperties().getDefenceAnimation()); + } + +} diff --git a/Server/src/main/content/global/handlers/item/equipment/special/RampageSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/RampageSpecialHandler.java new file mode 100644 index 0000000..2e70ab9 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/special/RampageSpecialHandler.java @@ -0,0 +1,80 @@ +package content.global.handlers.item.equipment.special; + +import core.game.node.entity.skill.Skills; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.MeleeSwingHandler; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.audio.Audio; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.plugin.Plugin; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playAudio; + +/** + * Handles the Rampage special attack. + * @author Emperor + */ +@Initializable +public final class RampageSpecialHandler extends MeleeSwingHandler implements Plugin { + + /** + * The special energy required. + */ + private static final int SPECIAL_ENERGY = 100; + + /** + * The attack animation. + */ + private static final Animation ANIMATION = new Animation(1056, Priority.HIGH); + + /** + * The graphic. + */ + private static final Graphics GRAPHIC = new Graphics(246); + + @Override + public Object fireEvent(String identifier, Object... args) { + switch (identifier) { + case "instant_spec": + case "ncspec": + return true; + } + return null; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + CombatStyle.MELEE.getSwingHandler().register(1377, this); + return this; + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + Player p = (Player) entity; + if (!p.getSettings().drainSpecial(SPECIAL_ENERGY)) { + return -1; + } + p.sendChat("Raarrrrrgggggghhhhhhh!"); + playAudio(entity.asPlayer(), Sounds.RAMPAGE_2538); + p.visualize(ANIMATION, GRAPHIC); + @SuppressWarnings("unused") + int boost = 0; + for (int i = 0; i < 7; i++) { + if (i == Skills.ATTACK || i == Skills.DEFENCE || i == Skills.RANGE || i == Skills.MAGIC) { + int drain = (int) (p.getSkills().getLevel(i) * 0.1); + boost += drain; + p.getSkills().updateLevel(i, -drain, 0); + } + } + boost = 10 + (boost / 4); + p.getSkills().updateLevel(Skills.STRENGTH, boost, Math.max(p.getSkills().getStaticLevel(Skills.STRENGTH) + boost, p.getSkills().getLevel(Skills.STRENGTH))); + return -1; + } + +} diff --git a/Server/src/main/content/global/handlers/item/equipment/special/SalamanderSwingHandler.kt b/Server/src/main/content/global/handlers/item/equipment/special/SalamanderSwingHandler.kt new file mode 100644 index 0000000..a0c5f69 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/special/SalamanderSwingHandler.kt @@ -0,0 +1,237 @@ +package content.global.handlers.item.equipment.special + +import core.api.EquipmentSlot +import core.api.getItemFromEquipment +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.combat.CombatSwingHandler +import core.game.node.entity.combat.InteractionType +import core.game.node.entity.combat.equipment.Weapon +import core.game.node.entity.combat.equipment.WeaponInterface +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import core.tools.RandomFunction +import org.rs09.consts.Items +import org.rs09.consts.Animations +import kotlin.math.ceil +import kotlin.math.floor + +/** + * Handles a combat swing using a salamander. + * @author Vexia + * @author itsmedoggo + */ +class SalamanderSwingHandler(private var style: CombatStyle) : CombatSwingHandler(style) { + override fun canSwing(entity: Entity, victim: Entity): InteractionType? { + checkStyle(entity) + if (!isProjectileClipped(entity, victim, false)) { + return InteractionType.NO_INTERACT + } + var distance = 1 + var goodRange = victim.centerLocation.withinDistance(entity.centerLocation, getCombatDistance(entity, victim, distance)) + var type = InteractionType.STILL_INTERACT + if (victim.walkingQueue.isMoving && !goodRange) { + goodRange = victim.centerLocation.withinDistance(entity.centerLocation, getCombatDistance(entity, victim, ++distance)) + type = InteractionType.MOVE_INTERACT + } + if (goodRange && super.canSwing(entity, victim) != InteractionType.NO_INTERACT) { + if (type == InteractionType.STILL_INTERACT) { + entity.walkingQueue.reset() + } + return type + } + return InteractionType.NO_INTERACT + } + + override fun swing(entity: Entity?, victim: Entity?, state: BattleState?): Int { + state!!.style = style + if (entity is Player) { + state.weapon = Weapon(entity.equipment[3]) + } + if (state!!.weapon == null || !hasAmmo(entity, state)) { + entity!!.properties.combatPulse.stop() + return -1 + } + var hit = 0 + if (isAccurateImpact(entity, victim, style)) { + val max = calculateHit(entity, victim, 1.0) + state.maximumHit = max + hit = RandomFunction.random(max + 1) + } + state.estimatedHit = hit + if (entity == null || victim!!.location == null) { + return -1 + } + if(state.estimatedHit > victim.skills.lifepoints) state.estimatedHit = victim.skills.lifepoints + useAmmo(entity, state) + return 1 + } + + override fun impact(entity: Entity?, victim: Entity?, state: BattleState?) { + style.swingHandler.impact(entity, victim, state) + } + + override fun visualize(entity: Entity, victim: Entity?, state: BattleState?) { + entity.visualize(Animation.create(5247), Graphics(952, 100)) + } + + override fun visualizeImpact(entity: Entity?, victim: Entity?, state: BattleState?) { + style.swingHandler.visualizeImpact(entity, victim, state) + } + + override fun calculateAccuracy(entity: Entity?): Int { + //Checking style is necessary for ::calc_accuracy to function after changing attack style but before attacking + checkStyle(entity) + return style.swingHandler.calculateAccuracy(entity) + } + + override fun calculateHit(entity: Entity?, victim: Entity?, modifier: Double): Int { + entity ?: return 0 + + //Checking style is necessary for ::calcmaxhit to function after changing attack style but before attacking + checkStyle(entity) + if (style == CombatStyle.MAGIC) { + val level = entity!!.skills.getLevel(Skills.MAGIC, true) + var bonus = entity.properties.bonuses[13] + if (entity is Player) { + bonus += getSalamanderMagicDamageBonus(entity.equipment[3].id) + } + var cumulativeStr = level.toDouble() + cumulativeStr *= getSetMultiplier(entity, Skills.MAGIC) + cumulativeStr *= (bonus + 64) + return floor((0.5 + (ceil(cumulativeStr) / 640.0)) * modifier).toInt() + } + return style.swingHandler.calculateHit(entity, victim, modifier) + } + + override fun addExperience(entity: Entity?, victim: Entity?, state: BattleState?) { + entity!!.skills.addExperience(Skills.HITPOINTS, state!!.estimatedHit * 1.33, true) + if (state.style == CombatStyle.MAGIC) { + entity.skills.addExperience(Skills.MAGIC, state.estimatedHit * 2.toDouble(), true) + } + if (state.style == CombatStyle.RANGE) { + entity.skills.addExperience(Skills.RANGE, state.estimatedHit * 4.toDouble(), true) + } + if (state.style == CombatStyle.MELEE) { + entity.skills.addExperience(Skills.STRENGTH, state.estimatedHit * 4.toDouble(), true) + } + } + + override fun calculateDefence(victim: Entity?, attacker: Entity?): Int { + return style.swingHandler.calculateDefence(victim, attacker) + } + + override fun getSetMultiplier(e: Entity?, skillId: Int): Double { + return style.swingHandler.getSetMultiplier(e, skillId) + } + + /** + * Sets the local style + * @param e The entity + */ + private fun checkStyle(e: Entity?) { + val index = e!!.properties.attackStyle.style + style = when(index) { + WeaponInterface.STYLE_DEFENSIVE_CAST -> CombatStyle.MAGIC + WeaponInterface.STYLE_RANGE_ACCURATE -> CombatStyle.RANGE + else -> CombatStyle.MELEE + } + } + + companion object { + /** + * The instance for the swing handler. + */ + val INSTANCE = SalamanderSwingHandler(CombatStyle.RANGE) + + /** + * Gets the id of the tar used by a salamander. + * @param id The salamander id. + * @return The tar id. + */ + fun getAmmoId(id: Int): Int { + when (id) { + Items.SWAMP_LIZARD_10149 -> { + return Items.GUAM_TAR_10142 + } + Items.ORANGE_SALAMANDER_10146 -> { + return Items.MARRENTILL_TAR_10143 + } + Items.RED_SALAMANDER_10147 -> { + return Items.TARROMIN_TAR_10144 + } + Items.BLACK_SALAMANDER_10148 -> { + return Items.HARRALANDER_TAR_10145 + } + else -> { + return -1 + } + } + } + + /** + * Gets the magic damage bonus of a salamander. + * @param id The salamander id. + * @return The magic damage bonus. + */ + fun getSalamanderMagicDamageBonus(id: Int): Int { + when (id) { + Items.SWAMP_LIZARD_10149 -> { + return 56 + } + Items.ORANGE_SALAMANDER_10146 -> { + return 59 + } + Items.RED_SALAMANDER_10147 -> { + return 77 + } + Items.BLACK_SALAMANDER_10148 -> { + return 92 + } + else -> { + return 0 + } + } + } + + /** + * Checks if the entity has the ammunition needed to proceed. + * @param e The entity. + * @param state The battle state. + * @return `True` if so. + */ + fun hasAmmo(e: Entity?, state: BattleState?): Boolean { + if (e !is Player) { + return true + } + val ammo = getItemFromEquipment(e, EquipmentSlot.AMMO) + if (ammo == null) { + e.packetDispatch.sendMessage("You do not have enough ammo left.") + return false + } + if (ammo.id == (getAmmoId(state!!.weapon.id))) { + return true + } + e.packetDispatch.sendMessage("You can't use this type of ammunition with this salamander.") + return false + } + + /** + * Uses the ammunition for the range weapon. + * @param e The entity. + * @param state The battle state. + * @param location The drop location. + */ + fun useAmmo(e: Entity, state: BattleState) { + if (e !is Player) { + return + } + e.equipment.remove(Item(getAmmoId(state!!.weapon.id), 1)) + } + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/equipment/special/SaradominsLightningHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/SaradominsLightningHandler.java new file mode 100644 index 0000000..9e672f4 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/special/SaradominsLightningHandler.java @@ -0,0 +1,88 @@ +package content.global.handlers.item.equipment.special; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.MeleeSwingHandler; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.Player; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Plugin; +import core.plugin.Initializable; +import core.tools.RandomFunction; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playGlobalAudio; + +/** + * Handles the Saradomin sword special attack. + * @author Emperor + */ +@Initializable +public final class SaradominsLightningHandler extends MeleeSwingHandler implements Plugin { + + /** + * The special energy required. + */ + private static final int SPECIAL_ENERGY = 100; + + /** + * The attack animation. + */ + private static final Animation ANIMATION = new Animation(7072, Priority.HIGH); + + /** + * The graphic. + */ + private static final Graphics GRAPHIC = new Graphics(1224); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + CombatStyle.MELEE.getSwingHandler().register(11730, this); + return this; + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + if (!((Player) entity).getSettings().drainSpecial(SPECIAL_ENERGY)) { + return -1; + } + // TODO: target states to make the first hit melee and the second hit magic + state.setStyle(CombatStyle.MAGIC); + int hit = 0; + int secondary = 0; + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.10, 1.0)) { + hit = RandomFunction.random(calculateHit(entity, victim, 1.1) + 1); + secondary = 1 + RandomFunction.random(16); + } + state.setEstimatedHit(hit); + state.setSecondaryHit(secondary); + return 1; + } + + @Override + public void impact(Entity entity, Entity victim, BattleState s) { + int hit = s.getEstimatedHit(); + if (hit > -1) { + victim.getImpactHandler().handleImpact(entity, hit, CombatStyle.MELEE, s); + } + hit = s.getSecondaryHit(); + if (hit > -1) { + victim.graphics(Graphics.create(1194)); + victim.getImpactHandler().handleImpact(entity, hit, CombatStyle.MAGIC, s); + } + } + + @Override + public void visualize(Entity entity, Entity victim, BattleState state) { + playGlobalAudio(entity.getLocation(), Sounds.GODWARS_SARADOMIN_MAGIC_IMPACT_3853); + entity.visualize(ANIMATION, GRAPHIC); + } + + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } +} diff --git a/Server/src/main/content/global/handlers/item/equipment/special/SeercullSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/SeercullSpecialHandler.java new file mode 100644 index 0000000..b4a374d --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/special/SeercullSpecialHandler.java @@ -0,0 +1,90 @@ +package content.global.handlers.item.equipment.special; + +import core.game.node.entity.combat.SwingHandlerFlag; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.RangeSwingHandler; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.player.Player; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Plugin; +import core.plugin.Initializable; +import core.tools.RandomFunction; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playGlobalAudio; + +/** + * Represents the Seercull's special attack which lowers the opponent's magic + * level. + * @author Splinter + * @version 1.0 + */ +@Initializable +public final class SeercullSpecialHandler extends RangeSwingHandler implements Plugin { + + /** + * Constructs a new {@code SeercullSpecialHandler} {@code Object}. + */ + public SeercullSpecialHandler() { + super(SwingHandlerFlag.IGNORE_PRAYER_BOOSTS_DAMAGE); + } + + /** + * The special energy required. + */ + private static final int SPECIAL_ENERGY = 100; + + /** + * The attack animation. + */ + private static final Graphics DRAWBACK_GFX = new Graphics(472, 96); + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + CombatStyle.RANGE.getSwingHandler().register(6724, this); + return this; + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + Player p = (Player) entity; + configureRangeData(p, state); + if (state.getWeapon() == null || !Companion.hasAmmo(entity, state)) { + entity.getProperties().getCombatPulse().stop(); + p.getSettings().toggleSpecialBar(); + return -1; + } + if (!((Player) entity).getSettings().drainSpecial(SPECIAL_ENERGY)) { + return -1; + } + int hit = RandomFunction.random(calculateHit(entity, victim, 1.0) + 1); + if (victim.getSkills().getLevel(Skills.MAGIC) >= victim.getSkills().getStaticLevel(Skills.MAGIC)) + victim.getSkills().updateLevel(Skills.MAGIC, -hit, 0); + Companion.useAmmo(entity, state, victim.getLocation()); + state.setEstimatedHit(hit); + return 1; + } + + @Override + public void visualize(Entity entity, Entity victim, BattleState state) { + playGlobalAudio(entity.getLocation(), Sounds.SOULSHOT_2546); + victim.graphics(new Graphics(474)); + int speed = (int) (35 + (entity.getLocation().getDistance(victim.getLocation()) * 10)); + entity.visualize(entity.getProperties().getAttackAnimation(), DRAWBACK_GFX); + Projectile.create(entity, victim, 473, 40, 40, 40, speed, 15, 11).send(); + } + + @Override + public void impact(final Entity entity, final Entity victim, final BattleState state) { + int hit = state.getEstimatedHit(); + victim.getImpactHandler().handleImpact(entity, hit, CombatStyle.RANGE, state); + } +} diff --git a/Server/src/main/content/global/handlers/item/equipment/special/SeverSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/SeverSpecialHandler.java new file mode 100644 index 0000000..eb8419c --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/special/SeverSpecialHandler.java @@ -0,0 +1,86 @@ +package content.global.handlers.item.equipment.special; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.MeleeSwingHandler; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.prayer.PrayerType; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Plugin; +import core.plugin.Initializable; +import core.tools.RandomFunction; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playGlobalAudio; + +/** + * Handles the Sever special attack. + * @author Emperor + */ +@Initializable +public final class SeverSpecialHandler extends MeleeSwingHandler implements Plugin { + + /** + * The special energy required. + */ + private static final int SPECIAL_ENERGY = 55; + + /** + * The attack animation. + */ + private static final Animation ANIMATION = new Animation(1872, Priority.HIGH); + + /** + * The graphic. + */ + private static final Graphics GRAPHIC = new Graphics(347, 96); + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + if (CombatStyle.MELEE.getSwingHandler().register(4587, this) && CombatStyle.MELEE.getSwingHandler().register(13477, this)) + ; + return this; + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + if (!((Player) entity).getSettings().drainSpecial(SPECIAL_ENERGY)) + return -1; + state.setStyle(CombatStyle.MELEE); + int hit = 0; + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.25, 1.0)) { + hit = RandomFunction.random(calculateHit(entity, victim, 1.0) + 1); + if (victim instanceof Player) { + Player p = (Player) victim; + if (p.getPrayer().get(PrayerType.PROTECT_FROM_MAGIC)) { + p.getPrayer().toggle(PrayerType.PROTECT_FROM_MAGIC); + } + if (p.getPrayer().get(PrayerType.PROTECT_FROM_MELEE)) { + p.getPrayer().toggle(PrayerType.PROTECT_FROM_MELEE); + } + if (p.getPrayer().get(PrayerType.PROTECT_FROM_MISSILES)) { + p.getPrayer().toggle(PrayerType.PROTECT_FROM_MISSILES); + } + if (p.getPrayer().get(PrayerType.PROTECT_FROM_SUMMONING)) { + p.getPrayer().toggle(PrayerType.PROTECT_FROM_SUMMONING); + } + } + } + state.setEstimatedHit(hit); + return 1; + } + + @Override + public void visualize(Entity entity, Entity victim, BattleState state) { + playGlobalAudio(entity.getLocation(), Sounds.SEVER_2540); + entity.visualize(ANIMATION, GRAPHIC); + } +} diff --git a/Server/src/main/content/global/handlers/item/equipment/special/ShatterSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/ShatterSpecialHandler.java new file mode 100644 index 0000000..1b226c3 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/special/ShatterSpecialHandler.java @@ -0,0 +1,71 @@ +package content.global.handlers.item.equipment.special; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.MeleeSwingHandler; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.Player; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.tools.RandomFunction; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playGlobalAudio; + +/** + * Handles the Shatter special attack. + * @author Emperor + */ +@Initializable +public final class ShatterSpecialHandler extends MeleeSwingHandler implements Plugin { + + /** + * The special energy required. + */ + private static final int SPECIAL_ENERGY = 25; + + /** + * The attack animation. + */ + private static final Animation ANIMATION = new Animation(1060, Priority.HIGH); + + /** + * The graphic. + */ + private static final Graphics GRAPHIC = new Graphics(251, 96); + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + CombatStyle.MELEE.getSwingHandler().register(1434, this); + CombatStyle.MELEE.getSwingHandler().register(13479, this); + return this; + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + if (!((Player) entity).getSettings().drainSpecial(SPECIAL_ENERGY)) { + return -1; + } + state.setStyle(CombatStyle.MELEE); + int hit = 0; + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.25, 1.0)) { + hit = RandomFunction.random(calculateHit(entity, victim, 1.5) + 1); + } + state.setEstimatedHit(hit); + return 1; + } + + @Override + public void visualize(Entity entity, Entity victim, BattleState state) { + playGlobalAudio(entity.getLocation(), Sounds.SHATTER_2541); + entity.visualize(ANIMATION, GRAPHIC); + } +} diff --git a/Server/src/main/content/global/handlers/item/equipment/special/ShoveSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/ShoveSpecialHandler.java new file mode 100644 index 0000000..12d9274 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/special/ShoveSpecialHandler.java @@ -0,0 +1,125 @@ +package content.global.handlers.item.equipment.special; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.MeleeSwingHandler; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.Player; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.Point; +import core.game.world.map.path.Pathfinder; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.plugin.Plugin; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.*; + +/** + * Handles the dragon spear special attack. + * @author Emperor + */ +@Initializable +public final class ShoveSpecialHandler extends MeleeSwingHandler implements Plugin { + + /** + * The special energy required. + */ + private static final int SPECIAL_ENERGY = 25; + + /** + * The attack animation. + */ + private static final Animation ANIMATION = new Animation(1064, Priority.HIGH); + + /** + * The graphic. + */ + private static final Graphics GRAPHIC = new Graphics(253, 96); + + /** + * The stun animation. + */ + private static Animation STUN_ANIM = new Animation(424); + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + CombatStyle.MELEE.getSwingHandler().register(1249, this); + CombatStyle.MELEE.getSwingHandler().register(1263, this); + CombatStyle.MELEE.getSwingHandler().register(3176, this); + CombatStyle.MELEE.getSwingHandler().register(5716, this); + CombatStyle.MELEE.getSwingHandler().register(5730, this); + CombatStyle.MELEE.getSwingHandler().register(11716, this); + CombatStyle.MELEE.getSwingHandler().register(14662, this); + return this; + } + + @Override + public int swing(Entity entity, final Entity victim, BattleState state) { + if (victim.size() > 1) { + ((Player) entity).getPacketDispatch().sendMessage("That creature is too large to knock back!"); + ((Player) entity).getSettings().toggleSpecialBar(); + return -1; + } + if (!((Player) entity).getSettings().drainSpecial(SPECIAL_ENERGY)) { + return -1; + } + state.setEstimatedHit(-1); + Direction dir = null; + int vx = victim.getLocation().getX(); + int vy = victim.getLocation().getY(); + int sx = entity.getLocation().getX(); + int sy = entity.getLocation().getY(); + if (vx == sx && vy > sy) { + dir = Direction.NORTH; + } else if (vx == sx && vy < sy) { + dir = Direction.SOUTH; + } else if (vx > sx && vy == sy) { + dir = Direction.EAST; + } else if (vx < sx && vy == sy) { + dir = Direction.WEST; + } else if (vx > sx && vy > sy) { + dir = Direction.NORTH_EAST; + } else if (vx < sx && vy > sy) { + dir = Direction.NORTH_WEST; + } else if (vx > sx && vy < sy) { + dir = Direction.SOUTH_EAST; + } else if (vx < sx && vy < sy) { + dir = Direction.SOUTH_WEST; + } + victim.getWalkingQueue().reset(); + victim.getPulseManager().clear(); + stun(victim, 5); + if (dir != null) { + Point p = Direction.getWalkPoint(dir); + Location dest = victim.getLocation().transform(p.getX(), p.getY(), 0); + if (Pathfinder.find(victim, dest, false, Pathfinder.DUMB).isSuccessful()) { + victim.getWalkingQueue().addPath(dest.getX(), dest.getY()); + } + } + return 1; + } + + @Override + public void visualize(Entity entity, Entity victim, BattleState state) { + playGlobalAudio(entity.getLocation(), Sounds.SHOVE_2544); + entity.visualize(ANIMATION, GRAPHIC); + } + + @Override + public void visualizeImpact(Entity entity, Entity victim, BattleState state) { + } + + @Override + public void impact(Entity entity, Entity victim, BattleState state) { + } + +} diff --git a/Server/src/main/content/global/handlers/item/equipment/special/SliceAndDiceSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/SliceAndDiceSpecialHandler.java new file mode 100644 index 0000000..9f75528 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/special/SliceAndDiceSpecialHandler.java @@ -0,0 +1,111 @@ +package content.global.handlers.item.equipment.special; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.MeleeSwingHandler; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.Player; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.tools.RandomFunction; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playGlobalAudio; + +/** + * Handles the Dragon claws special attack "Slice and Dice". + * @author Emperor + * + */ +@Initializable +public final class SliceAndDiceSpecialHandler extends MeleeSwingHandler implements Plugin { + + /** + * The special energy required. + */ + private static final int SPECIAL_ENERGY = 50; + + /** + * The attack animation. + */ + private static final Animation ANIMATION = new Animation(10961, Priority.HIGH); + + /** + * The graphic. + */ + private static final Graphics GRAPHIC = new Graphics(1950); + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + CombatStyle.MELEE.getSwingHandler().register(14484, this); + CombatStyle.MELEE.getSwingHandler().register(14486, this); + return this; + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + if (!((Player) entity).getSettings().drainSpecial(SPECIAL_ENERGY)) { + return -1; + } + int maximum = calculateHit(entity, victim, 1.0); + int[] hits; + int hit = getHit(entity, victim, maximum - 1, maximum / 2); + if (hit > 0) { + hits = new int[] {hit, hit / 2, (hit / 2) / 2, (hit / 2) / 2 + 1}; + } else { + hit = getHit(entity, victim, maximum * 7 / 8, maximum * 3 / 8); + if (hit > 0) { + hits = new int[] {0, hit, hit / 2, hit / 2 + 1}; + } else { + hit = getHit(entity, victim, maximum * 3 / 4, maximum / 4); + if (hit > 0) { + hits = new int[] {0, 0, hit, hit + 1}; + } else { + hit = getHit(entity, victim, maximum * 5 / 4, maximum / 4); + if (hit > 0) { + hits = new int[] {0, 0, 0, hit}; + } else { + hit = RandomFunction.random(2); + hits = new int[] {0, 0, hit, hit}; + } + } + } + } + BattleState[] states = new BattleState[hits.length]; + for (int i = 0; i < hits.length; i++) { + BattleState s = states[i] = new BattleState(entity, victim); + s.setStyle(CombatStyle.MELEE); + s.setEstimatedHit(hits[i]); + } + state.setTargets(states); + return 1; + } + + /** + * Gets the current hit. + * @param entity The attacking entity. + * @param victim The victim. + * @param maximum The maximum hit. + * @return The hit. + */ + private int getHit(Entity entity, Entity victim, int maximum, int minimum) { + if (isAccurateImpact(entity, victim, CombatStyle.MELEE)) { + return RandomFunction.random(minimum, maximum + 1); + } + return 0; + } + + @Override + public void visualize(Entity entity, Entity victim, BattleState state) { + playGlobalAudio(entity.getLocation(), Sounds.PUNCTURE_2537); + entity.visualize(ANIMATION, GRAPHIC); + } +} diff --git a/Server/src/main/content/global/handlers/item/equipment/special/SmashSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/SmashSpecialHandler.java new file mode 100644 index 0000000..ba4989e --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/special/SmashSpecialHandler.java @@ -0,0 +1,76 @@ +package content.global.handlers.item.equipment.special; + +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.MeleeSwingHandler; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.Player; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Plugin; +import core.tools.RandomFunction; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playGlobalAudio; + +/** + * Handles Statius' Warhammer special attack - Smash. + * @author Splinter + * @version 1.0 + */ +@Initializable +public final class SmashSpecialHandler extends MeleeSwingHandler implements Plugin { + + /** + * The special energy required. + */ + private static final int SPECIAL_ENERGY = 35; + + /** + * The attack animation. + */ + private static final Animation ANIMATION = new Animation(10501, Priority.HIGH); + + /** + * The gfx + */ + private static final Graphics GRAPHIC = new Graphics(1840, 0, 16); + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + if (CombatStyle.MELEE.getSwingHandler().register(13902, this) && CombatStyle.MELEE.getSwingHandler().register(13904, this)) + ; + return this; + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + if (!((Player) entity).getSettings().drainSpecial(SPECIAL_ENERGY)) { + return -1; + } + state.setStyle(CombatStyle.MELEE); + int hit = 0; + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.0, 1.0)) { + int max = calculateHit(entity, victim, 1.0); + hit = max / 4 + RandomFunction.random(max + 1); + int lower = (int) (victim.getSkills().getLevel(Skills.DEFENCE) * 0.30); + victim.getSkills().updateLevel(Skills.DEFENCE, -lower, 0); + } + state.setEstimatedHit(hit); + return 1; + } + + @Override + public void visualize(Entity entity, Entity victim, BattleState state) { + playGlobalAudio(entity.getLocation(), Sounds.TZHAAR_KET_OM_CRUSH_2520); + entity.visualize(ANIMATION, GRAPHIC); + } +} diff --git a/Server/src/main/content/global/handlers/item/equipment/special/SnapshotSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/SnapshotSpecialHandler.java new file mode 100644 index 0000000..618a0f4 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/special/SnapshotSpecialHandler.java @@ -0,0 +1,120 @@ +package content.global.handlers.item.equipment.special; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.SwingHandlerFlag; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.tools.RandomFunction; +import core.game.node.entity.combat.RangeSwingHandler; +import core.game.world.GameWorld; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playGlobalAudio; + +/** + * Handles the magic shortbow special attack "Snapshot". + * @author Emperor + */ +@Initializable +public final class SnapshotSpecialHandler extends RangeSwingHandler implements Plugin { + + /** + * Constructs a new {@code SnapshotSpecialHandler} {@code Object}. + */ + public SnapshotSpecialHandler() { + super(SwingHandlerFlag.IGNORE_PRAYER_BOOSTS_DAMAGE); + } + + /** + * The special energy required. + */ + private static final int SPECIAL_ENERGY = 55; + + /** + * The attack animation. + */ + private static final Animation ANIMATION = new Animation(1074, Priority.HIGH); + + /** + * The graphic. + */ + private static final Graphics GRAPHIC = new Graphics(249, 96); + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + CombatStyle.RANGE.getSwingHandler().register(861, this); + return this; + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + Player p = (Player) entity; + configureRangeData(p, state); + if (state.getWeapon() == null || !Companion.hasAmmo(entity, state)) { + entity.getProperties().getCombatPulse().stop(); + p.getSettings().toggleSpecialBar(); + return -1; + } + if (!((Player) entity).getSettings().drainSpecial(SPECIAL_ENERGY)) { + return -1; + } + state.setStyle(CombatStyle.RANGE); + int max = calculateHit(entity, victim, 1.0); + state.setMaximumHit(max); + int hit = 0; + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.43, 1.0)) { + hit = RandomFunction.random(max + 1); + } + state.setEstimatedHit(hit); + hit = 0; + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.43, 1.0)) { + hit = RandomFunction.random(max + 1); + } + state.setSecondaryHit(hit); + Companion.useAmmo(entity, state, victim.getLocation()); + return 1 + (int) Math.ceil(entity.getLocation().getDistance(victim.getLocation()) * 0.3); + } + + @Override + public void impact(final Entity entity, final Entity victim, final BattleState state) { + int hit = state.getEstimatedHit(); + victim.getImpactHandler().handleImpact(entity, hit, CombatStyle.RANGE, state); + if (state.getSecondaryHit() > -1) { + final int hitt = state.getSecondaryHit(); + if (victim.getLocation().withinDistance(entity.getLocation(), 2)) { + victim.getImpactHandler().handleImpact(entity, hitt, CombatStyle.RANGE, state); + return; + } + GameWorld.getPulser().submit(new Pulse(1, victim) { + @Override + public boolean pulse() { + victim.getImpactHandler().handleImpact(entity, hitt, CombatStyle.RANGE, state); + return true; + } + }); + } + } + + @Override + public void visualize(Entity entity, Entity victim, BattleState state) { + playGlobalAudio(entity.getLocation(), Sounds.SNAPSHOT_2545); + entity.visualize(ANIMATION, GRAPHIC); + int speed = (int) (27 + (entity.getLocation().getDistance(victim.getLocation()) * 5)); + Projectile.create(entity, victim, 249, 40, 36, 20, speed, 15, 11).send(); + speed = (int) (32 + (entity.getLocation().getDistance(victim.getLocation()) * 10)); + Projectile.create(entity, victim, 249, 40, 36, 50, speed, 15, 11).send(); + } +} diff --git a/Server/src/main/content/global/handlers/item/equipment/special/SnipeSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/SnipeSpecialHandler.java new file mode 100644 index 0000000..4d5b666 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/special/SnipeSpecialHandler.java @@ -0,0 +1,79 @@ +package content.global.handlers.item.equipment.special; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.player.Player; +import core.game.node.entity.skill.Skills; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.tools.RandomFunction; +import core.game.node.entity.combat.RangeSwingHandler; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playGlobalAudio; + +/** + * Represents the Dorgeshuun crossbow's special attack - snipe. + * @author Splinter + * @version 1.0 + */ +@Initializable +public final class SnipeSpecialHandler extends RangeSwingHandler implements Plugin { + + /** + * The special energy required. + */ + private static final int SPECIAL_ENERGY = 75; + + /** + * The attack animation. TODO: This is techically the wrong animation. The + * real one is incredibly similiar but I can't find it anywhere. + */ + private static final Animation ANIMATION = new Animation(4230, Priority.HIGH); + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + CombatStyle.RANGE.getSwingHandler().register(8880, this); + return this; + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + Player p = (Player) entity; + configureRangeData(p, state); + if (state.getWeapon() == null || !Companion.hasAmmo(entity, state)) { + entity.getProperties().getCombatPulse().stop(); + p.getSettings().toggleSpecialBar(); + return -1; + } + if (!((Player) entity).getSettings().drainSpecial(SPECIAL_ENERGY)) { + return -1; + } + state.setStyle(CombatStyle.RANGE); + int hit = 0; + if (!victim.getProperties().getCombatPulse().isAttacking() || isAccurateImpact(entity, victim, CombatStyle.RANGE)) { + hit = RandomFunction.random(calculateHit(entity, victim, 1.0) + 1); + if (victim.getSkills().getStaticLevel(Skills.DEFENCE) >= victim.getSkills().getDynamicLevels()[Skills.DEFENCE]) + victim.getSkills().updateLevel(Skills.DEFENCE, -hit, 0); + } + Companion.useAmmo(entity, state, victim.getLocation()); + state.setEstimatedHit(hit); + return 1; + } + + @Override + public void visualize(Entity entity, Entity victim, BattleState state) { + playGlobalAudio(entity.getLocation(), Sounds.DTTD_BONE_CROSSBOW_SA_1080); + entity.animate(ANIMATION); + Projectile.create(entity, victim, 698, 36, 25, 35, 72).send(); + } +} diff --git a/Server/src/main/content/global/handlers/item/equipment/special/SpearWallSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/SpearWallSpecialHandler.java new file mode 100644 index 0000000..c83d2fd --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/special/SpearWallSpecialHandler.java @@ -0,0 +1,116 @@ +package content.global.handlers.item.equipment.special; + +import java.util.List; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.InteractionType; +import core.game.node.entity.combat.MeleeSwingHandler; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Plugin; +import core.plugin.Initializable; +import core.tools.RandomFunction; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playGlobalAudio; + +/** + * Handles Vesta's Spear special attack - Spear Wall. + * @author Splinter + */ +@Initializable +public final class SpearWallSpecialHandler extends MeleeSwingHandler implements Plugin { + + /** + * The special energy required. + */ + private static final int SPECIAL_ENERGY = 50; + + /** + * The attack animation. + */ + private static final Animation ANIMATION = new Animation(10499, Priority.HIGH); + + /** + * The graphic. + */ + private static final Graphics GRAPHIC = new Graphics(1835); + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public void impact(Entity entity, Entity victim, BattleState state) { + if (state.getTargets() != null) { + for (BattleState s : state.getTargets()) { + if (s != null) { + s.getVictim().getImpactHandler().handleImpact(entity, s.getEstimatedHit(), CombatStyle.MELEE, s); + } + } + return; + } + victim.getImpactHandler().handleImpact(entity, state.getEstimatedHit(), CombatStyle.MELEE, state); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + CombatStyle.MELEE.getSwingHandler().register(13905, this); + CombatStyle.MELEE.getSwingHandler().register(13907, this); + return this; + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + if (!((Player) entity).getSettings().drainSpecial(SPECIAL_ENERGY)) { + return -1; + } + boolean multi = entity.getProperties().isMultiZone(); + if (!multi) { + return super.swing(entity, victim, state); + } + @SuppressWarnings("rawtypes") + List list = victim instanceof NPC ? RegionManager.getSurroundingNPCs(entity, 9, entity) : RegionManager.getSurroundingPlayers(entity, 9, entity); + BattleState[] targets = new BattleState[list.size()]; + int count = 0; + for (Object o : list) { + Entity e = (Entity) o; + if (CombatStyle.RANGE.getSwingHandler().canSwing(entity, e) != InteractionType.NO_INTERACT) { + BattleState s = targets[count++] = new BattleState(entity, e); + int hit = 0; + hit = RandomFunction.random(calculateHit(entity, e, 1.0) + 1); + s.setStyle(CombatStyle.MELEE); + s.setEstimatedHit(hit); + } + } + state.setTargets(targets); + return 1; + } + + @Override + public void visualize(Entity entity, Entity victim, BattleState state) { + playGlobalAudio(entity.getLocation(), Sounds.CLEAVE_2529); + entity.visualize(ANIMATION, GRAPHIC); + } + + @Override + public void visualizeImpact(Entity entity, Entity victim, BattleState state) { + if (state.getTargets() != null) { + for (BattleState s : state.getTargets()) { + if (s != null) { + s.getVictim().animate(victim.getProperties().getDefenceAnimation()); + } + + } + return; + } + victim.animate(victim.getProperties().getDefenceAnimation()); + } +} diff --git a/Server/src/main/content/global/handlers/item/equipment/special/SweepSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/SweepSpecialHandler.java new file mode 100644 index 0000000..3ef8ce0 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/special/SweepSpecialHandler.java @@ -0,0 +1,166 @@ +package content.global.handlers.item.equipment.special; + +import java.util.ArrayList; +import java.util.List; + +import core.plugin.Initializable; +import content.global.skill.summoning.familiar.Familiar; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.MeleeSwingHandler; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Plugin; +import core.tools.RandomFunction; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playGlobalAudio; + +/** + * Handles the Dragon halberd special attack. + * @author Emperor + */ +@Initializable +public final class SweepSpecialHandler extends MeleeSwingHandler implements Plugin { + + /** + * The special energy required. + */ + private static final int SPECIAL_ENERGY = 30; + + /** + * The attack animation. + */ + private static final Animation ANIMATION = new Animation(1203, Priority.HIGH); + + /** + * The graphic. + */ + private static final Graphics GRAPHIC = new Graphics(282, 96); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + CombatStyle.MELEE.getSwingHandler().register(3204, this); + return this; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + if (!((Player) entity).getSettings().drainSpecial(SPECIAL_ENERGY)) { + return -1; + } + BattleState[] targets = getTargets(entity, victim, state); + state.setTargets(targets); + for (BattleState s : targets) { + s.setStyle(CombatStyle.MELEE); + int hit = 0; + if (isAccurateImpact(entity, s.getVictim(), CombatStyle.MELEE)) { + hit = RandomFunction.random(calculateHit(entity, s.getVictim(), 1.1) + 1); + } + s.setEstimatedHit(hit); + if (s.getVictim().size() > 1) { + hit = 0; + if (isAccurateImpact(entity, s.getVictim(), CombatStyle.MELEE, 0.75, 1.0)) { + hit = RandomFunction.random(calculateHit(entity, s.getVictim(), 1.1) + 1); + } + s.setSecondaryHit(hit); + } + } + return 1; + } + + /** + * Gets the targets. + * @param entity The entity. + * @param victim The victim. + * @param state The battle state. + * @return The targets array. + */ + private BattleState[] getTargets(Entity entity, Entity victim, BattleState state) { + if (!entity.getProperties().isMultiZone() || !victim.getProperties().isMultiZone()) { + return new BattleState[] { state }; + } + Location vl = victim.getLocation(); + int x = vl.getX(); + int y = vl.getY(); + Direction dir = Direction.getDirection(x - entity.getLocation().getX(), y - entity.getLocation().getY()); + List l = new ArrayList<>(20); + l.add(new BattleState(entity, victim)); + for (Entity n : victim instanceof NPC ? RegionManager.getSurroundingNPCs(victim, 9, entity, victim) : RegionManager.getSurroundingPlayers(victim, 9, entity, victim)) { + if (n instanceof Familiar) { + continue; + } + if (n.getLocation().equals(vl.transform(dir.getStepY(), dir.getStepX(), 0)) || n.getLocation().equals(vl.transform(-dir.getStepY(), -dir.getStepX(), 0))) { + l.add(new BattleState(entity, n)); + if (l.size() >= 3) { + break; + } + } + } + return l.toArray(new BattleState[l.size()]); + } + + @Override + public void adjustBattleState(Entity entity, Entity victim, BattleState state) { + if (state.getTargets() != null) { + for (BattleState s : state.getTargets()) { + if (s != null) { + super.adjustBattleState(entity, s.getVictim(), s); + } + } + return; + } + super.adjustBattleState(entity, victim, state); + } + + @Override + public void impact(Entity entity, Entity victim, BattleState state) { + if (state.getTargets() != null) { + for (BattleState s : state.getTargets()) { + if (s != null) { + s.getVictim().getImpactHandler().handleImpact(entity, s.getEstimatedHit(), CombatStyle.MELEE, s); + if (s.getSecondaryHit() > -1) { + s.getVictim().getImpactHandler().handleImpact(entity, s.getSecondaryHit(), CombatStyle.MELEE, s); + } + } + } + return; + } + victim.getImpactHandler().handleImpact(entity, state.getEstimatedHit(), CombatStyle.MELEE, state); + if (state.getSecondaryHit() > -1) { + victim.getImpactHandler().handleImpact(entity, state.getSecondaryHit(), CombatStyle.MELEE, state); + } + } + + @Override + public void visualizeImpact(Entity entity, Entity victim, BattleState state) { + if (state.getTargets() != null) { + for (BattleState s : state.getTargets()) { + if (s != null) { + s.getVictim().animate(victim.getProperties().getDefenceAnimation()); + } + } + return; + } + victim.animate(victim.getProperties().getDefenceAnimation()); + } + + @Override + public void visualize(Entity entity, Entity victim, BattleState state) { + playGlobalAudio(entity.getLocation(), Sounds.HALBERD_SWIPE_2533); + entity.visualize(ANIMATION, GRAPHIC); + } + +} diff --git a/Server/src/main/content/global/handlers/item/equipment/special/WarstrikeSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/WarstrikeSpecialHandler.java new file mode 100644 index 0000000..177769d --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/special/WarstrikeSpecialHandler.java @@ -0,0 +1,91 @@ +package content.global.handlers.item.equipment.special; + +import core.game.node.entity.skill.Skills; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.MeleeSwingHandler; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.Player; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Plugin; +import core.plugin.Initializable; +import core.tools.RandomFunction; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playGlobalAudio; + +/** + * Handles the Warstrike special attack. + * @author Emperor + */ +@Initializable +public final class WarstrikeSpecialHandler extends MeleeSwingHandler implements Plugin { + + /** + * The special energy required. + */ + private static final int SPECIAL_ENERGY = 100; + + /** + * The attack animation. + */ + private static final Animation ANIMATION = new Animation(7073, Priority.HIGH); + + /** + * The graphic. + */ + private static final Graphics GRAPHIC = new Graphics(1223); + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + CombatStyle.MELEE.getSwingHandler().register(11696, this); + CombatStyle.MELEE.getSwingHandler().register(13451, this); + return this; + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + if (!((Player) entity).getSettings().drainSpecial(SPECIAL_ENERGY)) { + return -1; + } + state.setStyle(CombatStyle.MELEE); + int hit = 0; + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 2.0, 1.0)) { + hit = RandomFunction.random((int) (calculateHit(entity, victim, 1.1) * 1.1) + 1); + } + state.setEstimatedHit(hit); + if (victim instanceof Player) { + ((Player) victim).getPacketDispatch().sendMessage("You have been drained."); + } + int left = -victim.getSkills().updateLevel(Skills.DEFENCE, -hit, 0); + if (left > 0) { + left = -victim.getSkills().updateLevel(Skills.STRENGTH, -left, 0); + if (left > 0) { + left = (int) -(victim.getSkills().getPrayerPoints() + left); + victim.getSkills().decrementPrayerPoints(left); + if (left > 0) { + left = -victim.getSkills().updateLevel(Skills.ATTACK, -left, 0); + if (left > 0) { + left = -victim.getSkills().updateLevel(Skills.MAGIC, -left, 0); + if (left > 0) + victim.getSkills().updateLevel(Skills.RANGE, -left, 0); + } + } + } + } + return 1; + } + + @Override + public void visualize(Entity entity, Entity victim, BattleState state) { + playGlobalAudio(entity.getLocation(), Sounds.GODWARS_SARADOMIN_MAGIC_CASTANDFIRE_3834); + entity.visualize(ANIMATION, GRAPHIC); + } +} diff --git a/Server/src/main/content/global/handlers/item/equipment/special/WeakenSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/WeakenSpecialHandler.java new file mode 100644 index 0000000..b8f45d9 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/equipment/special/WeakenSpecialHandler.java @@ -0,0 +1,81 @@ +package content.global.handlers.item.equipment.special; + +import core.game.node.entity.skill.Skills; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.MeleeSwingHandler; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.Player; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Plugin; +import core.plugin.Initializable; +import core.tools.RandomFunction; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playGlobalAudio; + +/** + * Handles Darklight's special attack, Weaken. + * @author Crash, based on Emperor's code for other special attacks + */ +@Initializable +public final class WeakenSpecialHandler extends MeleeSwingHandler implements Plugin { + + /** + * The special energy required. + */ + private static final int SPECIAL_ENERGY = 50; + + /** + * The attack animation. + */ + private static final Animation ANIMATION = new Animation(2890, Priority.HIGH); + + /** + * The graphic. + */ + private static final Graphics GRAPHIC = new Graphics(483); + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + CombatStyle.MELEE.getSwingHandler().register(6746, this); + return this; + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + if (!((Player) entity).getSettings().drainSpecial(SPECIAL_ENERGY)) { + return -1; + } + state.setStyle(CombatStyle.MELEE); + int hit = 0; + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.0, 1.0)) { + hit = RandomFunction.random(calculateHit(entity, victim, 1.0) + 1); + if (victim instanceof Player) { + ((Player) victim).getPacketDispatch().sendMessage("You have been drained."); + } + // TODO 10% drain to demons + int lower = (int) (victim.getSkills().getStaticLevel(Skills.DEFENCE) * 0.05) + 1; + victim.getSkills().updateLevel(Skills.DEFENCE, -lower, 0); + lower = (int) (victim.getSkills().getStaticLevel(Skills.ATTACK) * 0.05) + 1; + victim.getSkills().updateLevel(Skills.ATTACK, -lower, 0); + lower = (int) (victim.getSkills().getStaticLevel(Skills.STRENGTH) * 0.05) + 1; + victim.getSkills().updateLevel(Skills.STRENGTH, -lower, 0); + } + state.setEstimatedHit(hit); + return hit; + } + + @Override + public void visualize(Entity entity, Entity victim, BattleState state) { + entity.visualize(ANIMATION, GRAPHIC); + playGlobalAudio(entity.getLocation(), Sounds.DARKLIGHT_WEAKEN_225); + } +} diff --git a/Server/src/main/content/global/handlers/item/toys/DiangoOptionHandler.java b/Server/src/main/content/global/handlers/item/toys/DiangoOptionHandler.java new file mode 100644 index 0000000..545aa25 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/toys/DiangoOptionHandler.java @@ -0,0 +1,23 @@ +package content.global.handlers.item.toys; + +import core.cache.def.impl.NPCDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; + +@Initializable +public class DiangoOptionHandler extends OptionHandler { + @Override + public Plugin newInstance(Object arg) throws Throwable { + NPCDefinition.forId(970).getHandlers().put("option:holiday-items",this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + DiangoReclaimInterface.open(player); + return true; + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/toys/DiangoReclaimInterface.java b/Server/src/main/content/global/handlers/item/toys/DiangoReclaimInterface.java new file mode 100644 index 0000000..4fda74d --- /dev/null +++ b/Server/src/main/content/global/handlers/item/toys/DiangoReclaimInterface.java @@ -0,0 +1,99 @@ +package content.global.handlers.item.toys; + +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.container.access.InterfaceContainer; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.Plugin; +import org.rs09.consts.Items; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +import static core.api.ContentAPIKt.inEquipment; +import static core.api.ContentAPIKt.inInventory; + + +/** + * Handles diango's item reclaiming interface + * @author ceik, for the interface, and for most of the holiday items/toys + */ +@Initializable +public class DiangoReclaimInterface extends ComponentPlugin { + private static final int COMPONENT_ID = 468; + public static final List ITEMS = new ArrayList<>(20); + public static final Item[] HOLIDAY_ITEMS = {new Item(Items.YO_YO_4079), new Item(Items.REINDEER_HAT_10507), new Item(Items.WINTUMBER_TREE_10508), new Item(Items.RUBBER_CHICKEN_4566),new Item(Items.ZOMBIE_HEAD_6722), new Item(6857), new Item(6856), new Item(6858), new Item(6859), new Item(6860), new Item(6861), new Item(6862), new Item(6863), new Item(9920), new Item(9921),new Item(9922), new Item(9923), new Item(9924), new Item(9925), new Item(11019), new Item(11020), new Item(11021), new Item(11022), new Item(11789), new Item(11949), new Item(12645), new Item(14076), new Item(14077), new Item(14081),new Item(14595), new Item(14602), new Item(14603), new Item(14605), new Item(14654), new Item(Items.ICE_AMULET_14596), new Item(Items.RED_MARIONETTE_6867), new Item(Items.GREEN_MARIONETTE_6866), new Item(Items.BLUE_MARIONETTE_6865)}; + + //initialize the plugin, add lists of items to the ITEMS list... + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.put(COMPONENT_ID,this); + ITEMS.addAll(Arrays.asList(HOLIDAY_ITEMS)); + return this; + } + + public static void open(Player player){ + //close any currently open interfaces + Component curOpen = player.getInterfaceManager().getOpened(); + if(curOpen != null){ + curOpen.close(player); + } + Item[] reclaimables = getEligibleItems(player); + player.setAttribute("diango-reclaimables", reclaimables); + + //filter out items the player already has in their bank, inventory, or equipped + + //only send items if there are some to send + if(reclaimables.length > 0) { + InterfaceContainer.generateItems(player, reclaimables, new String[]{"Examine", "Take"}, 468, 2, 8, 8); + } + //open the interface + player.getInterfaceManager().open(new Component(468)); + } + + //refresh the interface + public static void refresh(Player player){ + player.getInterfaceManager().close(); + open(player); + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + Item[] reclaimables = player.getAttribute("diango-reclaimables", null); + if (reclaimables == null) + reclaimables = getEligibleItems(player); + + Item reclaimItem = reclaimables[slot]; + if (reclaimItem == null) { + player.sendMessage("Something went wrong there. Please try again."); + return true; + } + + switch(opcode){ + case 155: //interface item option 1 == take + //add the clicked item to the player's inventory and refresh the interface + player.getInventory().add(reclaimItem); + refresh(player); + break; + case 196: //interface item option 2 == examine + //send the examine text for the item to the player + player.getPacketDispatch().sendMessage(reclaimItem.getDefinition().getExamine()); + break; + } + return false; + } + + public static Item[] getEligibleItems (Player player) { + return ITEMS.stream().filter(Objects::nonNull) + .filter(item -> !player.getEquipment().containsItem(item) && !player.getInventory().containsItem(item) && !player.getBank().containsItem(item) + && (item.getId() != 14654 + || (!(inInventory(player, 14655, 1) || inEquipment(player, 14656, 1)) && player.getAttribute("sotr:purchased",false)) + )) + .toArray(Item[]::new); + } +} diff --git a/Server/src/main/content/global/handlers/item/toys/SnowGlobePlugin.java b/Server/src/main/content/global/handlers/item/toys/SnowGlobePlugin.java new file mode 100644 index 0000000..7061980 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/toys/SnowGlobePlugin.java @@ -0,0 +1,62 @@ +package content.global.handlers.item.toys; + +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.plugin.ClassScanner; + +@Initializable +public class SnowGlobePlugin extends OptionHandler { + private static final Component INTERFACE = new Component(659);//After HOLDFACE this interface is displayed, player either clicks 'continue' for inv of snowballs, or 'close' for no snowballs + private final Animation DOWNFAST = new Animation(7537);//Used when player hit 'close' on the interface + private final Animation DOWNSLOW = new Animation(7538);//Used when the player hit 'continue' on the interface + private final Animation STOMP = new Animation(7528);//When player hits continue this animation plays + private final Graphics SNOW = new Graphics(1284);//When Animation STOMP is playing this gfx also plays + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ClassScanner.definePlugin(new SnowGlobeInterface()); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + return true; + } + + public class SnowGlobeInterface extends ComponentPlugin{ + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.put(INTERFACE.getId(),this); + return this; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + if(button == 2){ + player.getInterfaceManager().close(); + player.getAnimator().animate(DOWNSLOW); + player.getPulseManager().run(new Pulse(1) { + @Override + public boolean pulse() { + player.getAnimator().animate(STOMP,SNOW); + player.getInventory().add(new Item(11951,player.getInventory().freeSlots())); + return true; + } + }); + return true; + } + player.getAnimator().animate(DOWNFAST); + return true; + } + } +} diff --git a/Server/src/main/content/global/handlers/item/withitem/CapeDyer.kt b/Server/src/main/content/global/handlers/item/withitem/CapeDyer.kt new file mode 100644 index 0000000..941b993 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withitem/CapeDyer.kt @@ -0,0 +1,75 @@ +package content.global.handlers.item.withitem + +import content.data.Dyes +import core.game.interaction.NodeUsageEvent +import core.game.interaction.UseWithHandler +import core.game.node.item.Item +import core.plugin.Initializable +import core.plugin.Plugin +import org.rs09.consts.Items + +private val CAPES = arrayOf(1019,1007,1021,1023,1027,1029,1031,6959) +private val DYES = Dyes.values().map { it -> it.item.id }.toIntArray() + +@Initializable +//For the super constructor we have to use all but the very last cape because its ID is higher than the ID of all dyes +class CapeDyer : UseWithHandler(*CAPES.copyOfRange(0,CAPES.size - 1).toIntArray()) { + override fun newInstance(arg: Any?): Plugin { + for(dye in DYES){ + addHandler(dye, ITEM_TYPE,this) + } + addHandler(6959, ITEM_TYPE,this) //Pink cape has to be here because higher ID than others + return this + } + + override fun handle(event: NodeUsageEvent?): Boolean { + event ?: return false + val player = event.player + val used = event.used.id + val with = event.usedWith.id + var cape: Item + var dye: Item + + if(CAPES.contains(used) && DYES.contains(with)){ + cape = event.used.asItem() + dye = event.used.asItem() + } else if (DYES.contains(used) && CAPES.contains(with)){ + cape = event.usedWith.asItem() + dye = event.used.asItem() + } else { + return false + } + + val product = Cape.forDye(dye.id) ?: return false + + if(player.inventory.remove(dye) && player.inventory.remove(cape)){ + player.inventory.add(product.product) + player.inventory.add(Item(Items.VIAL_229)) + player.sendMessage("You dye the cape.") + } + return true + } + + internal enum class Cape(val dye : Dyes, val product : Item) { + BLACK(Dyes.BLACK, Item(1019)), + RED(Dyes.RED, Item(1007)), + BLUE(Dyes.BLUE, Item(1021)), + YELLOW(Dyes.YELLOW, Item(1023)), + GREEN(Dyes.GREEN, Item(1027)), + PURPLE(Dyes.PURPLE, Item(1029)), + ORANGE(Dyes.ORANGE, Item(1031)), + PINK(Dyes.PINK, Item(6959)); + + companion object { + fun forDye(dye: Int): Cape? { + for (cape in values()) { + if (cape.dye.item.id == dye) { + return cape + } + } + return null + } + } + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/withitem/CrystalKeyCreateListener.kt b/Server/src/main/content/global/handlers/item/withitem/CrystalKeyCreateListener.kt new file mode 100644 index 0000000..207102b --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withitem/CrystalKeyCreateListener.kt @@ -0,0 +1,33 @@ +package content.global.handlers.item.withitem + +import core.api.addItem +import core.api.removeItem +import core.api.sendMessage +import org.rs09.consts.Items +import core.game.interaction.IntType +import core.game.interaction.InteractionListener + +/** + * Listener for creating a crystal key + * @author Byte + */ +@Suppress("unused") +class CrystalKeyCreateListener : InteractionListener { + + override fun defineListeners() { + onUseWith(IntType.ITEM, Items.LOOP_HALF_OF_A_KEY_987, Items.TOOTH_HALF_OF_A_KEY_985) { player, used, with -> + if (!removeItem(player, used)) { + return@onUseWith false + } + + if (!removeItem(player, with)) { + return@onUseWith false + } + + addItem(player, Items.CRYSTAL_KEY_989) + sendMessage(player, "You join the loop half of a key and the tooth half of a key to make a crystal key.") + + return@onUseWith true + } + } +} diff --git a/Server/src/main/content/global/handlers/item/withitem/DarkBowDyePlugin.java b/Server/src/main/content/global/handlers/item/withitem/DarkBowDyePlugin.java new file mode 100644 index 0000000..548b236 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withitem/DarkBowDyePlugin.java @@ -0,0 +1,121 @@ +package content.global.handlers.item.withitem; +import core.game.dialogue.DialogueAction; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Plugin; +import core.plugin.Initializable; +import core.plugin.ClassScanner; + +/** + * The plugin used to dye a dark bow into a more one. + * @author Splinter + * @version 1.0 + */ +@Initializable +public final class DarkBowDyePlugin extends UseWithHandler { + + + /** + * Constructs a new {@code DarkBowDyePlugin} {@code Object}. + */ + public DarkBowDyePlugin() { + super(11235); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(14795, ITEM_TYPE, this); + addHandler(14797, ITEM_TYPE, this); + addHandler(14799, ITEM_TYPE, this); + addHandler(14801, ITEM_TYPE, this); + ClassScanner.definePlugin(new DarkBowCleanPlugin()); + return this; + } + + @Override + public boolean handle(final NodeUsageEvent event) { + final Player player = event.getPlayer(); + player.getDialogueInterpreter().sendOptions("Apply "+event.getUsedItem().getName().replace("dark bow paint", "paint?").toLowerCase(), "Yes", "No"); + player.getDialogueInterpreter().addAction(new DialogueAction() { + + @Override + public void handle(Player player, int buttonId) { + switch (buttonId) { + case 2: + if (player.getInventory().remove(event.getBaseItem()) && player.getInventory().remove(event.getUsedItem())) { + player.getInventory().add(getResult(event.getUsedItem().getId())); + player.sendMessage("You dye the bow into a more fashionable version."); + } + break; + } + } + + }); + return true; + } + + /** + * Gets the resulting colored dark bow. + * @return the item + */ + private Item getResult(int dyeId){ + switch(dyeId){ + case 14797: + return new Item(14803, 1); + case 14795: + return new Item(14804, 1); + case 14799: + return new Item(14805, 1); + case 14801: + return new Item(14806, 1); + } + return null; + } + + /** + * Cleans the dark bow and removes the paint. + * @author Andrew + */ + public final class DarkBowCleanPlugin extends UseWithHandler { + + /** + * Constructs a new {@code DarkBowCleanPlugin} {@code Object}. + */ + public DarkBowCleanPlugin() { + super(3188); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(14803, ITEM_TYPE, this); + addHandler(14804, ITEM_TYPE, this); + addHandler(14805, ITEM_TYPE, this); + addHandler(14806, ITEM_TYPE, this); + return this; + } + + @Override + public boolean handle(final NodeUsageEvent event) { + final Player player = event.getPlayer(); + player.getDialogueInterpreter().sendOptions("Wipe the paint off?", "Yes", "No"); + player.getDialogueInterpreter().addAction(new DialogueAction() { + + @Override + public void handle(Player player, int buttonId) { + switch (buttonId) { + case 2: + if (player.getInventory().remove(event.getBaseItem()) && player.getInventory().remove(event.getUsedItem())) { + player.getInventory().add(new Item(11235, 1)); + player.sendMessage("You wipe the paint off with the cleaning cloth, then toss it away."); + } + break; + } + } + + }); + return true; + } + } +} diff --git a/Server/src/main/content/global/handlers/item/withitem/FirelighterPlugin.java b/Server/src/main/content/global/handlers/item/withitem/FirelighterPlugin.java new file mode 100644 index 0000000..4e088be --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withitem/FirelighterPlugin.java @@ -0,0 +1,105 @@ +package content.global.handlers.item.withitem; + +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the plugin used to turn regular logs into a different colour. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public class FirelighterPlugin extends UseWithHandler { + + /** + * Represents the logs item. + */ + private static final Item LOGS = new Item(1511); + + /** + * Constructs a new {@code FirelighterPlugin} {@code Object}. + */ + public FirelighterPlugin() { + super(1511); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (FireLighter lighter : FireLighter.values()) { + addHandler(lighter.getLighter().getId(), ITEM_TYPE, this); + } + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + final FireLighter lighter = FireLighter.forLighter(event.getUsedItem().getId() == 1511 ? event.getBaseItem() : event.getUsedItem()); + if (player.getInventory().remove(lighter.getLighter(), LOGS)) { + player.getInventory().add(lighter.getLog()); + } + return true; + } + + /** + * Represents a fire lighter. + * @author 'Vexia + * @date 28/12/2013 + */ + public enum FireLighter { + RED(new Item(7329), new Item(7404)), GREEN(new Item(7330), new Item(7405)), BLUE(new Item(7331), new Item(7406)), PURPLE(new Item(10326), new Item(10329)), WHITE(new Item(10327), new Item(10328)); + + /** + * Represents the fire lighter. + */ + private final Item lighter; + + /** + * Represents the log to turn into. + */ + private final Item log; + + /** + * Constructs a new {@code FirelighterPlugin.java} {@code Object}. + * @param lighter the lighter. + * @param log the log. + */ + FireLighter(Item lighter, Item log) { + this.lighter = lighter; + this.log = log; + } + + /** + * Gets the lighter. + * @return The lighter. + */ + public Item getLighter() { + return lighter; + } + + /** + * Gets the log. + * @return The log. + */ + public Item getLog() { + return log; + } + + /** + * Gets the fire lighter from the lighter used. + * @return the fire lighter data. + */ + public static FireLighter forLighter(final Item item) { + for (FireLighter lighter : values()) { + if (lighter.getLighter().getId() == item.getId()) { + return lighter; + } + } + return null; + } + } +} diff --git a/Server/src/main/content/global/handlers/item/withitem/FishfoodPlugin.java b/Server/src/main/content/global/handlers/item/withitem/FishfoodPlugin.java new file mode 100644 index 0000000..a73f3cf --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withitem/FishfoodPlugin.java @@ -0,0 +1,117 @@ +package content.global.handlers.item.withitem; + +import org.rs09.consts.Items; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; + +import java.util.Arrays; + +/** + * Represents the poison fish food making plugin. + * @author afaroutdude, fixed by Ceikry + */ +@Initializable +public final class FishfoodPlugin extends UseWithHandler { + + /** + * Represents the poisoned fish food item. + */ + private static final int FISH_FOOD = Items.FISH_FOOD_272; + private static final int POISON = Items.POISON_273; + private static final int POISONED_FISH_FOOD = Items.POISONED_FISH_FOOD_274; + + protected enum FishFoodUses{ + POISONED(POISON, FISH_FOOD, POISONED_FISH_FOOD, "You poison the fish food."), + GUAMBOX(Items.GROUND_GUAM_6681, Items.AN_EMPTY_BOX_6675, Items.GUAM_IN_A_BOX_6677, "You put the ground Guam into the box."), + SEAWEEDBOX(Items.GROUND_SEAWEED_6683, Items.AN_EMPTY_BOX_6675, Items.SEAWEED_IN_A_BOX_6679, "You put the ground Seaweed into the box."), + FOOD1(Items.GROUND_SEAWEED_6683, Items.GUAM_IN_A_BOX_6677, FISH_FOOD, "You put the ground Seaweed into the box and make Fish Food."), + FOOD2(Items.GROUND_GUAM_6681, Items.SEAWEED_IN_A_BOX_6679, FISH_FOOD, "You put the ground Guam into the box and make Fish Food."), + FISHBOWL(Items.FISHBOWL_6668, Items.SEAWEED_401, Items.FISHBOWL_6669, "You place the seaweed in the bowl."); + + + private final int used; + private final int with; + private final int product; + private final String msg; + + static protected int[] usables = Arrays.stream(FishFoodUses.values()) + .mapToInt(v -> v.used) + .toArray(); + + FishFoodUses(int used, int with, int product, String msg) { + this.used = used; + this.with = with; + this.product = product; + this.msg = msg; + } + + protected static Item productFor(int used, int with) { + for (FishFoodUses value : values()) { + if (value.used == used && value.with == with) { + return new Item(value.product); + } + } + return null; + } + + protected static String msgFor(int used, int with) { + for (FishFoodUses value : values()) { + if (value.used == used && value.with == with) { + return value.msg; + } + } + return null; + } + } + + + /** + * Constructs a new {@code FishfoodPlugin} {@code Object}. + */ + public FishfoodPlugin() { + super(FishFoodUses.usables); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (FishFoodUses value : FishFoodUses.values()) { + addHandler(value.with, ITEM_TYPE, this); + } + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + int used = event.getUsedItem().getId(); + int with = event.getBaseItem().getId(); + Item product = FishFoodUses.productFor(used, with); + + player.getPulseManager().run(new Pulse(1, player) { + @Override + public boolean pulse() { + if (player.getInventory().remove(new Item(with),new Item(used))) { + player.animate(new Animation(1309)); + player.getPacketDispatch().sendMessage(FishFoodUses.msgFor(used, with)); + player.getInventory().add(product); + player.lock(2); + } + return true; + } + + @Override + public void stop() { + super.stop(); + } + }); + + return true; + } + +} diff --git a/Server/src/main/content/global/handlers/item/withitem/FruitCutting.kt b/Server/src/main/content/global/handlers/item/withitem/FruitCutting.kt new file mode 100644 index 0000000..ca6db90 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withitem/FruitCutting.kt @@ -0,0 +1,87 @@ +package content.global.handlers.item.withitem + +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.item.Item +import core.game.world.update.flag.context.Animation +import core.tools.START_DIALOGUE +import org.rs09.consts.Items + +class FruitCuttingListener : InteractionListener { + val anim = Animation(1192) // TODO Add fruit cutting animation to ConstLib + + enum class Fruit(val fruit: Int, val chunk: Int, val slice: Item) { + PINEAPPLE(Items.PINEAPPLE_2114, Items.PINEAPPLE_CHUNKS_2116, Item(Items.PINEAPPLE_RING_2118, 4)), + BANANA(Items.BANANA_1963, -1, Item(Items.SLICED_BANANA_3162)), + LEMON(Items.LEMON_2102, Items.LEMON_CHUNKS_2104, Item(Items.LEMON_SLICES_2106)), + LIME(Items.LIME_2120, Items.LIME_CHUNKS_2122, Item(Items.LIME_SLICES_2124)), + ORANGE(Items.ORANGE_2108, Items.ORANGE_CHUNKS_2110, Item(Items.ORANGE_SLICES_2112)); + + companion object { + val productOfChunk = values().associate { it.fruit to it.chunk } + val productOfSlice = values().associate { it.fruit to it.slice } + val cutable = intArrayOf(PINEAPPLE.fruit, BANANA.fruit, LEMON.fruit, LIME.fruit, ORANGE.fruit) + + fun forChunkId(id: Int) : Int { + return productOfChunk[id]!! + } + + fun forSliceId(id: Int) : Item { + return productOfSlice[id]!! + } + } + } + + override fun defineListeners() { + onUseWith(IntType.ITEM, Fruit.cutable, Items.KNIFE_946) { player, used, _ -> + openDialogue( + player, + FruitCuttingDialogue(used.id, Fruit.forChunkId(used.id), Fruit.forSliceId(used.id)) + ) + return@onUseWith true + } + } +} + +class FruitCuttingDialogue(val fruit: Int, val chunk: Int, val slice: Item) : DialogueFile() { + val anim = Animation(1192) + override fun handle(componentID: Int, buttonID: Int) { + when(stage) { + START_DIALOGUE -> { + if(chunk == -1) { + if(removeItem(player!!, fruit) && addItem(player!!, slice.id)) { + animate(player!!, anim, true) + sendMessage(player!!, "You deftly chop the ${getItemName(fruit).lowercase()} into slices.") + } + } else { + setInterfaceText(player!!, "Would you like to...", 140, 4) + sendItemOnInterface(player!!, 140, 6, chunk, 1) + sendItemOnInterface(player!!, 140, 5, slice.id, 1) + setInterfaceText(player!!, "Slice the ${getItemName(fruit).lowercase()}", 140, 2) + setInterfaceText(player!!, "Dice the ${getItemName(fruit).lowercase()}", 140, 3) + openInterface(player!!, 140) + when(buttonID) { + 1 -> { + closeInterface(player!!) + if(removeItem(player!!, fruit) && addItem(player!!, slice.id, slice.amount)) { + animate(player!!, anim, true) + sendMessage(player!!, "You cut the ${getItemName(fruit).lowercase()} into slices.") + } + } + 2 -> { + closeInterface(player!!) + if(removeItem(player!!, fruit) && addItem(player!!, chunk)) { + animate(player!!, anim, true) + sendMessage(player!!, "You cut the ${getItemName(fruit).lowercase()} into chunks.") + } + } + + } + } + } + } + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/withitem/GodswordHiltAttachPlugin.java b/Server/src/main/content/global/handlers/item/withitem/GodswordHiltAttachPlugin.java new file mode 100644 index 0000000..2e0522b --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withitem/GodswordHiltAttachPlugin.java @@ -0,0 +1,61 @@ +package content.global.handlers.item.withitem; + +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Plugin; +import core.plugin.Initializable; +import core.tools.StringUtils; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playAudio; + +/** + * Handles the attaching of a hilt on the godsword blade. + * @author Emperor + * @version 1.0 + */ +@Initializable +public final class GodswordHiltAttachPlugin extends UseWithHandler { + + /** + * Constructs a new {@code GodswordHiltAttachPlugin} {@code Object}. + */ + public GodswordHiltAttachPlugin() { + super(11702, 11704, 11706, 11708); + } + + @Override + public boolean handle(NodeUsageEvent event) { + Item item = event.getUsedItem(); + if (item == null) + return false; + Item baseItem = event.getBaseItem(); + Player player = event.getPlayer(); + if (!player.getInventory().containsItem(item) || !player.getInventory().containsItem(baseItem)) { + return false; + } + if (player.getInventory().replace(null, item.getSlot(), false) != item || player.getInventory().replace(null, baseItem.getSlot(), false) != baseItem) { + player.getInventory().update(); + return false; + } + item = new Item(item.getId() - 8); + player.getInventory().add(item); + String name = item.getDefinition().getName(); + playAudio(player, Sounds.GODWARS_GODSWORD_FIX_3889); + player.getPacketDispatch().sendMessage("You attach the hilt to the blade and make a" + (StringUtils.isPlusN(name) ? "n " : " ") + name + "."); + return true; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + // In case of item-on-item: register the lowest item id - in this case + // godsword blade) + // (eg. if one item is 1521 and the other is 842 -> 842 should be + // registered) + addHandler(11690, ITEM_TYPE, this); + return this; + } + +} diff --git a/Server/src/main/content/global/handlers/item/withitem/GraniteMaulPlugin.java b/Server/src/main/content/global/handlers/item/withitem/GraniteMaulPlugin.java new file mode 100644 index 0000000..6ba753d --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withitem/GraniteMaulPlugin.java @@ -0,0 +1,100 @@ +package content.global.handlers.item.withitem; + +import core.cache.def.impl.ItemDefinition; +import core.plugin.Initializable; +import core.game.dialogue.DialogueAction; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.OptionHandler; +import core.game.interaction.UseWithHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Plugin; +import core.plugin.ClassScanner; + +/** + * The plugin used to make the granite maul into the ornamental version. + * @author Splinter + * @version 1.0 + */ +@Initializable +public final class GraniteMaulPlugin extends UseWithHandler { + + + /** + * Constructs a new {@code GraniteMaulPlugin} {@code Object}. + */ + public GraniteMaulPlugin() { + super(4153); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ClassScanner.definePlugin(new GraniteMaulRevertHandler()); + addHandler(14793, ITEM_TYPE, this); + return this; + } + + @Override + public boolean handle(final NodeUsageEvent event) { + final Player player = event.getPlayer(); + player.getDialogueInterpreter().sendOptions("Attach the clamp?", "Yes", "No"); + player.getDialogueInterpreter().addAction(new DialogueAction() { + + @Override + public void handle(Player player, int buttonId) { + switch (buttonId) { + case 2: + if (player.getInventory().remove(event.getBaseItem()) && player.getInventory().remove(event.getUsedItem())) { + player.getInventory().add(new Item(14792, 1)); + player.sendMessage("You attach the clamp to the granite maul, making it slightly more fashionable."); + } + break; + } + } + + }); + return true; + } + + /** + * Handles the removal of the ornamental kit. + * @author Splinter + */ + public final class GraniteMaulRevertHandler extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ItemDefinition.forId(14792).getHandlers().put("option:revert", this); + return null; + } + + @Override + public boolean handle(Player player, Node node, String option) { + final Item item = (Item) node; + player.getDialogueInterpreter().sendOptions("Remove the clamp?", "Yes", "No"); + player.getDialogueInterpreter().addAction(new DialogueAction() { + + @Override + public void handle(Player player, int buttonId) { + switch (buttonId) { + case 2: + if(player.getInventory().remove(item)){ + player.getInventory().add(new Item(4153, 1)); + player.sendMessage("You remove the clamp from your maul, and in the process, it is destroyed."); + } + break; + } + } + + }); + return true; + } + + @Override + public boolean isWalk() { + return false; + } + } + +} diff --git a/Server/src/main/content/global/handlers/item/withitem/GraniteSplittingPlugin.java b/Server/src/main/content/global/handlers/item/withitem/GraniteSplittingPlugin.java new file mode 100644 index 0000000..951bb6b --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withitem/GraniteSplittingPlugin.java @@ -0,0 +1,64 @@ +package content.global.handlers.item.withitem; + +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Used to handle the reward of splitting granite with a chisel in to smaller + * pieces. + * @author Splinter + */ +@Initializable +public class GraniteSplittingPlugin extends UseWithHandler { + + public GraniteSplittingPlugin() { + super(1755); + } + + /** + * Represents the 5kg granite + */ + private static final Item FIVE_KG = new Item(6983, 1); + + /** + * Represents the 2kg granite + */ + private static final Item TWO_KG = new Item(6981, 1); + + @Override + public boolean handle(NodeUsageEvent event) { + if (event.getUsedItem().getId() == 6981) { + if (event.getPlayer().getInventory().freeSlots() < 4) { + event.getPlayer().getPacketDispatch().sendMessage("You need four inventory slots to split this."); + } else { + if (event.getPlayer().getInventory().remove(TWO_KG)) { + event.getPlayer().getInventory().add(new Item(6979, 4)); + event.getPlayer().getPacketDispatch().sendMessage("You chisel the 2kg granite into four smaller pieces."); + } + } + } + if (event.getUsedItem().getId() == 6983) { + if (event.getPlayer().getInventory().freeSlots() < 4) { + event.getPlayer().getPacketDispatch().sendMessage("You need four inventory slots to split this."); + } else { + if (event.getPlayer().getInventory().remove(FIVE_KG)) { + event.getPlayer().getInventory().add(new Item(6981, 2)); + event.getPlayer().getInventory().add(new Item(6979, 2)); + event.getPlayer().getPacketDispatch().sendMessage("You chisel the 5kg granite into four smaller pieces."); + } + } + } + return true; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(6981, ITEM_TYPE, this); + addHandler(6983, ITEM_TYPE, this); + return this; + } + +} diff --git a/Server/src/main/content/global/handlers/item/withitem/HaySackOnSpear.kt b/Server/src/main/content/global/handlers/item/withitem/HaySackOnSpear.kt new file mode 100644 index 0000000..a954ca1 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withitem/HaySackOnSpear.kt @@ -0,0 +1,23 @@ +package content.global.handlers.item.withitem + +import core.api.Container +import core.api.* +import org.rs09.consts.Items +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +class HaySackOnSpear : InteractionListener { + val HAYSACK = Items.HAY_SACK_6057 + val SPEAR = Items.BRONZE_SPEAR_1237 + + override fun defineListeners() { + onUseWith(IntType.ITEM, HAYSACK, SPEAR){ player, used, _ -> + if(removeItem(player, used.asItem(), Container.INVENTORY)){ + addItem(player, Items.HAY_SACK_6058, 1) + sendMessage(player, "You stab the hay sack with a bronze spear") + removeItem(player, SPEAR, Container.INVENTORY) + } + return@onUseWith true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/withitem/ImpJarCreatePlugin.java b/Server/src/main/content/global/handlers/item/withitem/ImpJarCreatePlugin.java new file mode 100644 index 0000000..e6d61a6 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withitem/ImpJarCreatePlugin.java @@ -0,0 +1,163 @@ +package content.global.handlers.item.withitem; + +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.plugin.Initializable; +import core.plugin.Plugin; + +import static core.api.ContentAPIKt.*; + +/** + * Handles the creating of an imp jar. + * @author Vexia + */ +@Initializable +public final class ImpJarCreatePlugin extends UseWithHandler { + + /** + * The flower ids. + */ + private static final int[] FLOWERS = new int[] { 2460, 2461, 2462, 2463, 2464, 2465, 2466, 2467, 2468, 2469, 2470, 2471, 2472, 2473, 2474, 2475, 2476, 2477 }; + + /** + * Constructs a new {@code ImpJarCreatePlugin} {@code Object}. + */ + public ImpJarCreatePlugin() { + super(6097, 11264, 1939, 4525, 4535, 4546, 4700, 11262, 10012); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(11266, ITEM_TYPE, this); + for (int i : FLOWERS) { + addHandler(i, ITEM_TYPE, this); + } + for (int i : getValidChildren(5908)) { + addHandler(i, OBJECT_TYPE, this); + } + addHandler(5909, OBJECT_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + Player player = event.getPlayer(); + if (event.getUsedWith() instanceof Scenery) { + if ((event.getUsedItem().getId() >= 4525 && event.getUsedItem().getId() <= 4700) || event.getUsedItem().getId() == 1939 || event.getUsedItem().getId() == 11262 || event.getUsedItem().getId() == 10012) { + fillOilStill(player, event.getUsedItem()); + } + return true; + } + if (((Item) event.getUsedWith()).getId() == 6097) { + makeOil(player); + } else if (event.getUsedItem().getId() == 11264) { + makeRepellent(player, event.getUsedItem(), (Item) event.getUsedWith()); + } + return true; + } + + /** + * Fills the oil still. + * @param player the player. + */ + private void fillOilStill(Player player, Item used) { + int configValue = getVarp(player, 425); + if (used.getId() == 11262 || used.getId() == 10012) { + if (configValue == 0 && used.getId() == 11262) { + player.getInventory().replace(new Item(229), used.getSlot()); + player.sendMessage("You refine some imp repellent."); + setVarp(player, 425, 64, true); + return; + } else if (configValue == 32) { + player.sendMessage("There is already lamp oil in the still."); + return; + } else if (configValue == 64) { + if (used.getId() == 11262) { + player.sendMessage("There is already imp repellent in the still."); + } else { + player.getInventory().replace(new Item(11260), used.getSlot()); + setVarp(player, 425, 0, true); + player.sendMessage("You turn the butterfly jar into an impling jar."); + } + return; + } + player.sendMessage("There is no refined imp repellent in the still."); + return; + } + if (configValue == 64) { + player.sendMessage("There is already imp repellent in the still."); + return; + } + if (configValue == 32 && used.getId() == 1939) { + player.sendMessage("There is already lamp oil in the still."); + return; + } + if (used.getId() == 1939) { + if (player.getInventory().remove(new Item(1939))) { + setVarp(player, 425, 32, true); + player.sendMessage("You refine some swamp tar into lamp oil."); + } + } else { + if (configValue == 0) { + player.sendMessage("There is no oil in the still."); + } else { + if (player.getInventory().contains(4525, 1) || player.getInventory().contains(4535, 1) || player.getInventory().contains(4546, 1) || player.getInventory().contains(4700, 1)) { + Item replace = new Item(used.getId() == 4525 ? 4522 : used.getId() == 4535 ? 4537 : used.getId() == 4546 ? 4548 : 4701); + player.getInventory().replace(replace, used.getSlot()); + setVarp(player, 425, 0, true); + player.sendMessage("You fill the item with oil."); + } + } + } + } + + /** + * Makes imp repellent. + * @param player the player. + * @param usedWith the used item. + */ + private void makeRepellent(Player player, Item oil, Item usedWith) { + if (isFlower(usedWith.getId())) { + if (player.getInventory().remove(usedWith)) { + player.getInventory().replace(new Item(11262), oil.getSlot()); + player.sendMessage("You mix the flower petals with the anchovy oil to make a very strange-smelling concoction."); + ; + } + } + } + + /** + * Makes anchovy oil. + * @param player the player. + */ + private void makeOil(Player player) { + if (!player.getInventory().contains(229, 1)) { + player.sendMessage("You need an empty vial to put your anchovy oil into."); + return; + } + if (!player.getInventory().contains(11266, 8)) { + player.sendMessage("You need 8 anchovy paste's in order to make anchovy oil."); + return; + } + if (player.getInventory().remove(new Item(11266, 8), new Item(229))) { + player.getInventory().add(new Item(11264)); + } + } + + /** + * Checks if the id is a flower. + * @param id the id. + * @return {@code True} if so. + */ + private boolean isFlower(int id) { + for (int i : FLOWERS) { + if (i == id) { + return true; + } + } + return false; + } +} diff --git a/Server/src/main/content/global/handlers/item/withitem/KaramjanSilkPlugin.java b/Server/src/main/content/global/handlers/item/withitem/KaramjanSilkPlugin.java new file mode 100644 index 0000000..5c6154d --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withitem/KaramjanSilkPlugin.java @@ -0,0 +1,51 @@ +package content.global.handlers.item.withitem; + +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the karamjan silk plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class KaramjanSilkPlugin extends UseWithHandler { + + /** + * Represents the cloth item. + */ + private static final Item CLOTH = new Item(3188); + + /** + * Represents the silk item. + */ + private static final Item SILK = new Item(950); + + /** + * Constructs a new {@code KaramjanSilkPlugin} {@code Object}. + */ + public KaramjanSilkPlugin() { + super(950); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(431, ITEM_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + if (player.getInventory().remove(SILK)) { + player.getInventory().add(CLOTH); + player.getPacketDispatch().sendMessage("You pour some of the Karamjan rum over the silk."); + } + return true; + } + +} diff --git a/Server/src/main/content/global/handlers/item/withitem/LavaScalePlugin.java b/Server/src/main/content/global/handlers/item/withitem/LavaScalePlugin.java new file mode 100644 index 0000000..656bd36 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withitem/LavaScalePlugin.java @@ -0,0 +1,105 @@ +package content.global.handlers.item.withitem; + +import core.game.node.entity.skill.Skills; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; +import core.plugin.ClassScanner; +import core.plugin.Initializable; +import core.tools.RandomFunction; + +/** + * Handles the grinding of Lava Scales. + * @author Splinter + * @version 1.0 + */ +@Initializable +public final class LavaScalePlugin extends UseWithHandler { + + /** + * Constructs a new {@code LavaScalePlugin} {@code Object}. + */ + public LavaScalePlugin() { + super(14695); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(233, ITEM_TYPE, this); + ClassScanner.definePlugin(new AntifireMakePlugin()); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + Player player = event.getPlayer(); + if(player.getInventory().remove(new Item(14695))){ + player.getInventory().add(new Item(14768, RandomFunction.random(3, 6))); + player.animate(new Animation(364)); + player.sendMessage("You grind the scales into fine shards."); + } + return true; + } + + /** + * Handles the making of the Extended antifire potion. + * It's apparently not made like regular potions. + * @author Splinter + * @version 1.0 + */ + public final class AntifireMakePlugin extends UseWithHandler { + + /** + * Constructs a new {@code LavaScalePlugin} {@code Object}. + */ + public AntifireMakePlugin() { + super(2454, 2456, 2458, 2452); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(14768, ITEM_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + Player player = event.getPlayer(); + int count = player.getInventory().getAmount(event.getUsedWith().asItem()); + int total = count * getReq(event.getUsedWith().asItem().getId()); + if(player.getInventory().contains(14768, total)){ + player.getInventory().remove(new Item(14768, total), new Item(event.getUsedWith().getId(), count)); + player.getInventory().add(new Item(event.getUsedWith().getId() + 12301, count)); + player.animate(new Animation(363)); + player.getSkills().addExperience(Skills.HERBLORE, 27.5 * total); + player.sendMessages("You drop a total of "+(total)+" lava scales in the potions and upgrade all of the", "potions of the same dose into extended antifire potions."); + } else { + player.sendMessage("You don't have enough shards to upgrade all your potions of that dose."); + } + return true; + } + + } + + /** + * Get the required amount of shards. + * @return + */ + public int getReq(int id){ + switch(id){ + case 2452: + return 4; + case 2454: + return 3; + case 2456: + return 2; + case 2458: + return 1; + } + return 4; + } + +} diff --git a/Server/src/main/content/global/handlers/item/withitem/OilFishingRodListener.kt b/Server/src/main/content/global/handlers/item/withitem/OilFishingRodListener.kt new file mode 100644 index 0000000..1dcd15c --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withitem/OilFishingRodListener.kt @@ -0,0 +1,50 @@ +package content.global.handlers.item.withitem + +import core.api.* +import core.game.system.task.Pulse +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +class OilFishingRodListener : InteractionListener { + override fun defineListeners() { + onUseWith(IntType.ITEM, Items.BLAMISH_OIL_1582, Items.FISHING_ROD_307) { player, used, with -> + player.pulseManager.run(object : Pulse() { + var counter = 0 + override fun pulse(): Boolean { + when (counter++) { + 1 -> { + removeItem(player, used.asItem()) && removeItem(player, with.asItem()) + addItem(player, Items.VIAL_229) + addItem(player, Items.OILY_FISHING_ROD_1585) + sendMessage(player, "You rub the oil into the fishing rod.") + } + } + return false + } + }) + return@onUseWith true + } + + onUseWith(IntType.ITEM, Items.THIN_SNAIL_3363, Items.PESTLE_AND_MORTAR_233) { player, used, with -> + if (player.inventory.contains(Items.SAMPLE_BOTTLE_3377, 1)) { + player.pulseManager.run(object : Pulse() { + var counter = 0 + override fun pulse(): Boolean { + when (counter++) { + 0 -> player.animator.animate(Animation(364)) + 3 -> { + removeItem(player, Items.THIN_SNAIL_3363) + removeItem(player, Items.SAMPLE_BOTTLE_3377) + addItem(player, Items.BLAMISH_SNAIL_SLIME_1581) + } + } + return false + } + }) + } + return@onUseWith true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/withitem/PoisonedWeaponListeners.kt b/Server/src/main/content/global/handlers/item/withitem/PoisonedWeaponListeners.kt new file mode 100644 index 0000000..c3b6816 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withitem/PoisonedWeaponListeners.kt @@ -0,0 +1,113 @@ +package content.global.handlers.item.withitem + +import core.api.* +import core.game.node.item.Item +import org.rs09.consts.Items +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import kotlin.collections.toIntArray +import kotlin.math.min + +class PoisonedWeaponListeners : InteractionListener { + override fun defineListeners() { + val poisons = intArrayOf(Items.WEAPON_POISON_187, Items.WEAPON_POISON_PLUS_5937, Items.WEAPON_POISON_PLUS_PLUS_5940) + val poisonableItems = PoisonSets.itemMap.keys.toIntArray() + val poisonedItems = PoisonSets.itemMap.values.toIntArray() + + onUseWith(IntType.ITEM, poisons, *poisonableItems){ player, used, with -> + val index = poisons.indexOf(used.id) + val product = PoisonSets.itemMap[with.id]!![index] + val amt = min(5, with.asItem().amount) + + if(removeItem(player, Item(with.id, amt))) { + removeItem(player, used.id) //Mico's Code. See: https://gitlab.com/skelsoft/redwings/-/issues/13 + addItemOrDrop(player, product, amt) + addItemOrDrop(player, Items.VIAL_229) + sendMessage(player, "You poison the ${with.name.toLowerCase()}.") + } + return@onUseWith true + } + + onUseWith(IntType.ITEM, Items.CLEANING_CLOTH_3188, *poisonedItems) { player, _, with -> + val base = PoisonSets.getBase(with.id) ?: return@onUseWith false + val amt = min(5, with.asItem().amount) + removeItem(player, Item(with.id, amt)) + addItemOrDrop(player, base, amt) + return@onUseWith true + } + } + + //below enum copied from old file, some data is probably wrong. + internal enum class PoisonSets(val base: Int, val p: Int, val pp: Int, val ppp: Int){ + BRONZE_ARROW(882, 883, 5616, 5622), + IRON_ARROW(884, 885, 5617, 5623), + STEEL_ARROW(886, 887, 5618, 5624), + MITHRIL_ARROW(888, 889, 5619, 5625), + ADAMANT_ARROW(890, 891, Items.ADAMANT_ARROWP_PLUS_5620, 5626), + RUNE_ARROW(892, 893, 5621, 5627), + + IRON_KNIFE(863, 871, 5655, 5662), + BRONZE_KNIFE(864, 870, 5654, 5661), + STEEL_KNIFE(865, 872, 5656, 5663), + MITHRIL_KNIFE(866, 873, 5657, 5664), + ADAMANT_KNIFE(867, 875, 5659, 5666), + RUNE_KNIFE(868, 876, 5660, 5667), + BLACK_KNIFE(869, 874, 5658, 5665), + + BRONZE_DART(806, 812, 5628, 5635), + IRON_DART(807, 813, 5629, 5636), + STEEL_DART(808, 814, 5630, 5637), + BLACK_DART(3093, 3094, 5631, 5638), + MITHRIL_DART(809, 815, 5632, 5639), + ADAMANT_DART(810, 816, 5633, 5640), + + BRONZE_BOLT(877, 878, 6061, 6062), + BLURITE_BOLT(9139, 9286, 9293, 9300), + IRON_BOLT(9140, 9287, 9294, 9301), + STEEL_BOLT(9141, 9288, 9295, 9302), + BLACK_BOLT(13083, 13084, 13085, 13086), + MITHRIL_BOLT(9142, 9289, 9296, 9303), + ADAMANT_BOLT(9143, 9290, 9297, 9304), + RUNE_BOLT(9144, 9291, 9298, 9305), + SILVER_BOLT(9145, 9292, 9299, 9306), + + RUNE_DART(811, 817, 5634, 5641), + IRON_JAVELIN(825, 831, Items.IRON_JAVELINP_PLUS_5643, 5648), + BRONZE_JAVELIN(826, 832, Items.BRONZE_JAVELINP_PLUS_5642, 5649), + STEEL_JAVELIN(827, 833, Items.STEEL_JAVELINP_PLUS_5644, 5650), + MITHRIL_JAVELIN(828, 834, Items.MITHRIL_JAVELINP_PLUS_5645, 5651), + ADAMANT_JAVELIN(829, 835, Items.ADAMANT_JAVELINP_PLUS_5646, 5652), + RUNE_JAVELIN(830, 836, Items.RUNE_JAVELINP_PLUS_5647, 5653), + MORRIGAN_JAVELIN(13879, 13880, 13881, 13882), + + IRON_DAGGER(1203, 1219, 5668, 5686), + BRONZE_DAGGER(1205, 1221, 5670, 5688), + STEEL_DAGGER(1207, 1223, 5672, 5690), + MITHRIL_DAGGER(1209, 1225, 5674, 5692), + ADAMANT_DAGGER(1211, 1227, 5676, 5694), + RUNE_DAGGER(1213, 1229, 5678, 5696), + DRAGON_DAGGER(1215, 1231, 5680, 5698), + BLACK_DAGGER(1217, 1233, 5682, 5700), + BONE_DAGGER(8872, 8874, 8876, 8878), + + BRONZE_SPEAR(1237, 1251, 5704, Items.BRONZE_SPEARP_PLUS_PLUS_5718), + IRON_SPEAR(1239, 1253, 5706, Items.IRON_SPEARP_PLUS_PLUS_5720), + STEEL_SPEAR(1241, 1255, 5708, 5722), + MITHRIL_SPEAR(1243, 1257, 5710, 5724), + ADAMANT_SPEAR(1245, 1259, 5712, 5726), + RUNE_SPEAR(1247, 1261, 5714, 5728), + DRAGON_SPEAR(1249, 1263, 5716, 5730), + BLACK_SPEAR(4580, 4582, 5734, 5736); + + companion object { + val itemMap = values().map { it.base to intArrayOf(it.p,it.pp,it.ppp) }.toMap() + + fun getBase(poisoned: Int) : Int? { + for ((base,set) in itemMap.entries) { + if (set.contains(poisoned)) return base + } + return null + } + } + } +} diff --git a/Server/src/main/content/global/handlers/item/withitem/SeasonedSardinePlugin.java b/Server/src/main/content/global/handlers/item/withitem/SeasonedSardinePlugin.java new file mode 100644 index 0000000..a109666 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withitem/SeasonedSardinePlugin.java @@ -0,0 +1,46 @@ +package content.global.handlers.item.withitem; + +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the plugin to make seasoned sardines. + * @author 'Vexia + * @date Oct 6, 2013 + */ +@Initializable +public class SeasonedSardinePlugin extends UseWithHandler { + + /** + * Represents the seasoned sardine. + */ + private final Item SEASONED_SARDINE = new Item(1552); + + /** + * Constructs a new {@code SeasonedSardinePlugina} {@code Object}. + */ + public SeasonedSardinePlugin() { + super(327); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(1573, ITEM_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + if (player.getInventory().remove(event.getUsedItem()) && player.getInventory().remove(event.getBaseItem())) { + player.getDialogueInterpreter().sendDialogue("You rub the doogle leaves over the sardine."); + player.getInventory().add(SEASONED_SARDINE); + } + return true; + } + +} diff --git a/Server/src/main/content/global/handlers/item/withitem/SkullSceptrePlugin.java b/Server/src/main/content/global/handlers/item/withitem/SkullSceptrePlugin.java new file mode 100644 index 0000000..e7b8c6a --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withitem/SkullSceptrePlugin.java @@ -0,0 +1,53 @@ +package content.global.handlers.item.withitem; + +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * @author 'Vexia + */ +@Initializable +public class SkullSceptrePlugin extends UseWithHandler { + + public SkullSceptrePlugin() { + super(9008, 9009, 9011); + } + + @Override + public boolean handle(NodeUsageEvent event) { + if (event.getUsedItem().getId() == 9008 && ((Item) event.getUsedWith()).getId() == 9007) { + event.getPlayer().getInventory().remove(new Item(9008, 1)); + event.getPlayer().getInventory().remove(new Item(9007, 1)); + event.getPlayer().getInventory().add(new Item(9009, 1)); + event.getPlayer().getDialogueInterpreter().open(78489); + return true; + } + if (event.getUsedItem().getId() == 9011 && ((Item) event.getUsedWith()).getId() == 9010) { + event.getPlayer().getInventory().remove(new Item(9010, 1)); + event.getPlayer().getInventory().remove(new Item(9011, 1)); + event.getPlayer().getInventory().add(new Item(9012, 1)); + event.getPlayer().getDialogueInterpreter().open(78489, true); + return true; + } + if (event.getUsedItem().getId() == 9012 && ((Item) event.getUsedWith()).getId() == 9009) { + event.getPlayer().getInventory().remove(new Item(9009, 1)); + event.getPlayer().getInventory().remove(new Item(9012, 1)); + event.getPlayer().getInventory().add(new Item(9013, 1)); + event.getPlayer().getDialogueInterpreter().open(78489, true, true); + return true; + } + return true; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(9007, ITEM_TYPE, this); + addHandler(9010, ITEM_TYPE, this); + addHandler(9012, ITEM_TYPE, this); + return this; + } + +} diff --git a/Server/src/main/content/global/handlers/item/withitem/SoftclayPlugin.java b/Server/src/main/content/global/handlers/item/withitem/SoftclayPlugin.java new file mode 100644 index 0000000..37ff465 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withitem/SoftclayPlugin.java @@ -0,0 +1,147 @@ +package content.global.handlers.item.withitem; + +import core.game.node.entity.player.link.diary.DiaryType; +import core.plugin.Initializable; +import org.rs09.consts.Items; +import core.game.dialogue.SkillDialogueHandler; +import core.game.dialogue.SkillDialogueHandler.SkillDialogue; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.plugin.Plugin; +import java.util.Objects; + +/** + * Represents the plugin used to make soft clay. + * @author 'Vexia + * @date 1/14/14 + */ +@Initializable +public final class SoftclayPlugin extends UseWithHandler { + + /** + * Represents the clay item. + */ + private static final Item CLAY = new Item(Items.CLAY_434); + + /** + * Represents the soft clay item. + */ + private static final Item SOFT_CLAY = new Item(Items.SOFT_CLAY_1761); + + /** + * Represents the bowl of water item. + */ + private static final Item BOWL_OF_WATER = new Item(Items.BOWL_OF_WATER_1921); + + /** + * Represents the empty bowl item. + */ + private static final Item BOWL = new Item(Items.BOWL_1923); + + /** + * Represents the empty bucket item. + */ + private static final Item BUCKET = new Item(Items.BUCKET_1925); + + /** + * Represents the bucket of water item. + */ + private static final Item BUCKET_OF_WATER = new Item(Items.BUCKET_OF_WATER_1929); + + /** + * Represents the jug item. + */ + private static final Item JUG = new Item(Items.JUG_1935); + + /** + * Represents the jug of water item. + */ + private static final Item JUG_OF_WATER = new Item(Items.JUG_OF_WATER_1937); + + /** + * Constructs a new {@code SoftclayPlugin} {@code Object}. + */ + public SoftclayPlugin() { + super(434); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(1921, ITEM_TYPE, this); + addHandler(1929, ITEM_TYPE, this); + addHandler(1937, ITEM_TYPE, this); + return this; + } + + @Override + public boolean handle(final NodeUsageEvent event) { + final Player player = event.getPlayer(); + SkillDialogueHandler handler = new SkillDialogueHandler(player, SkillDialogue.ONE_OPTION, SOFT_CLAY) { + @Override + public void create(final int amount, int index) { + player.getPulseManager().run(new Pulse(2, player) { + int count; + + @Override + public boolean pulse() { + if (!SoftclayPlugin.this.create(player, event)) { + return true; + } + return ++count >= amount; + } + }); + } + + @Override + public int getAll(int index) { + return player.getInventory().getAmount(CLAY); + } + }; + if (player.getInventory().getAmount(CLAY) == 1) { + create(player, event); + } else { + handler.open(); + } + return true; + } + + /** + * Creates a soft clay. + * @param player the player. + * @param event the event. + * @return {@code True} if so. + */ + private boolean create(final Player player, NodeUsageEvent event) { + Item removeItem = null; + Item returnItem = null; + if (event.getUsedItem().getId() == Items.BUCKET_OF_WATER_1929 || event.getBaseItem().getId() == Items.BUCKET_OF_WATER_1929) { + removeItem = BUCKET_OF_WATER; + returnItem = BUCKET; + } + if (event.getUsedItem().getId() == Items.BOWL_OF_WATER_1921 || event.getBaseItem().getId() == Items.BOWL_OF_WATER_1921) { + removeItem = BOWL_OF_WATER; + returnItem = BOWL; + } + if (event.getUsedItem().getId() == Items.JUG_OF_WATER_1937 || event.getBaseItem().getId() == Items.JUG_OF_WATER_1937) { + removeItem = JUG_OF_WATER; + returnItem = JUG; + } + + if (player.getInventory().containsItem(CLAY) && player.getInventory().containsItem(Objects.requireNonNull(removeItem))) { + player.getInventory().remove(removeItem); + player.getInventory().remove(CLAY); + player.getPacketDispatch().sendMessage("You mix the clay and water. You now have some soft, workable clay."); + player.getInventory().add(SOFT_CLAY); + player.getInventory().add(returnItem); + if (!player.getAchievementDiaryManager().hasCompletedTask(DiaryType.LUMBRIDGE, 0, 6) && player.getViewport().getRegion().getId() == 12341) { + player.getAchievementDiaryManager().finishTask(player, DiaryType.LUMBRIDGE, 0, 6); + } + return true; + } else { + return false; + } + } +} diff --git a/Server/src/main/content/global/handlers/item/withitem/TOTTHelmOnCape.kt b/Server/src/main/content/global/handlers/item/withitem/TOTTHelmOnCape.kt new file mode 100644 index 0000000..eabd9ee --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withitem/TOTTHelmOnCape.kt @@ -0,0 +1,42 @@ +package content.global.handlers.item.withitem + +import core.api.Container +import core.api.* +import org.rs09.consts.Items +import core.game.dialogue.DialogueFile +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.tools.END_DIALOGUE + +class TOTTHelmOnCape : InteractionListener { + override fun defineListeners() { + onUseWith(IntType.ITEM, Items.SLAYER_HELMET_13263, Items.SLAYER_CAPE_9786, Items.SLAYER_CAPET_9787){ player, used, with -> + val alreadyHasHelm = getAttribute(player, "cape_perks:tott:helmet-stored", false) + + if(alreadyHasHelm){ + sendDialogue(player, "You've already stored the components of a helmet in this cape.") + } else { + openDialogue(player, object : DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + when(stage){ + 0 -> dialogue("This will destroy your helmet permanently.").also { stage++ } + 1 -> interpreter!!.sendOptions("Continue?", "Yes", "No").also { stage++ } + 2 -> when(buttonID){ + 1 -> { + if(removeItem(player, Items.SLAYER_HELMET_13263, Container.INVENTORY)) { + dialogue(*splitLines("You disassemble the helmet and place the components into their respective pockets on your cape.")) + setAttribute(player, "/save:cape_perks:tott:helmet-stored", true) + stage = END_DIALOGUE + } + } + 2 -> end() + } + } + } + }) + } + + return@onUseWith true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/withitem/WaterSkinPlugin.java b/Server/src/main/content/global/handlers/item/withitem/WaterSkinPlugin.java new file mode 100644 index 0000000..39848ea --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withitem/WaterSkinPlugin.java @@ -0,0 +1,57 @@ +package content.global.handlers.item.withitem; + +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the water skin refilling plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class WaterSkinPlugin extends UseWithHandler { + + /** + * Represents the full skill item. + */ + private final Item FULL_SKIN = new Item(1823); + + /** + * Represents data of water skin filling vessils. + */ + private final int[][] data = new int[][] { { 1937, 1935 }, { 1929, 1925 }, { 1921, 1923 }, { 227, 229 } }; + + /** + * Constructs a new {@code WaterSkinPlugin} {@code Object}. + */ + public WaterSkinPlugin() { + super(1825, 1827, 1829, 1831); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (int i = 0; i < data.length; i++) { + addHandler(data[i][0], ITEM_TYPE, this); + } + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Item waterSkin = event.getUsedItem().getName().contains("skin") ? event.getUsedItem() : event.getBaseItem(); + final Item vessil = !event.getUsedItem().getName().contains("skin") ? event.getUsedItem() : event.getBaseItem(); + if (event.getPlayer().getInventory().remove(waterSkin)) { + event.getPlayer().getInventory().add(vessil.getId() == 227 ? new Item(waterSkin.getId() - 2) : FULL_SKIN); + for (int i = 0; i < data.length; i++) { + if (data[i][0] == vessil.getId() && event.getPlayer().getInventory().remove(vessil)) { + event.getPlayer().getInventory().add(new Item(data[i][1])); + } + } + } + return true; + } + +} diff --git a/Server/src/main/content/global/handlers/item/withitem/WatermelonOnSack.kt b/Server/src/main/content/global/handlers/item/withitem/WatermelonOnSack.kt new file mode 100644 index 0000000..da829ed --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withitem/WatermelonOnSack.kt @@ -0,0 +1,28 @@ +package content.global.handlers.item.withitem + +import core.api.Container +import core.api.* +import core.game.node.entity.skill.Skills +import org.rs09.consts.Items +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +class WatermelonOnSack : InteractionListener { + val SACK = Items.HAY_SACK_6058 + val WATERMELON = Items.WATERMELON_5982 + + override fun defineListeners() { + onUseWith(IntType.ITEM, SACK, WATERMELON){ player, used, _ -> + if(getStatLevel(player, Skills.FARMING) >= 23){ + removeItem(player,SACK, Container.INVENTORY) + removeItem(player,WATERMELON,Container.INVENTORY) + addItem(player, Items.SCARECROW_6059) + rewardXP(player, Skills.FARMING, 25.0) + sendMessage(player, "You stab the watermelon on top of the spear, finishing your scarecrow") + }else{ + sendMessage(player, "Your Farming level is not high enough to do this") + } + return@onUseWith true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/withnpc/BonesOnStrayDog.kt b/Server/src/main/content/global/handlers/item/withnpc/BonesOnStrayDog.kt new file mode 100644 index 0000000..e6e7fd0 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withnpc/BonesOnStrayDog.kt @@ -0,0 +1,84 @@ +package content.global.handlers.item.withnpc + +import core.api.removeItem +import core.api.sendChat +import core.api.sendMessage +import content.global.skill.prayer.Bones +import core.game.node.entity.npc.NPC +import core.game.node.item.Item +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +class BonesOnStrayDog : InteractionListener { + override fun defineListeners() { + val bones = Bones.array + + val dogs = intArrayOf( + NPCs.STRAY_DOG_4766, + NPCs.STRAY_DOG_4767, + NPCs.STRAY_DOG_5917, + NPCs.STRAY_DOG_5918 + ) + + onUseWith(IntType.NPC, bones, *dogs) { player, used, with -> + used as Item; with as NPC + + var woof = "Woof" + + if (removeItem(player, used)) { + sendMessage( + player, + "You feed the ${with.definition.name.lowercase()} your ${used.definition.name.lowercase()}." + ) + + when (used.id) { + Items.BURNT_BONES_528 -> { + sendMessage( + player, + "The dog looks at you, disappointed, but takes the bones anyway." + ) + + woof = "Woof..." + } + + Items.FAYRG_BONES_4830, + Items.RAURG_BONES_4832, + Items.OURG_BONES_4834 -> { + sendMessage( + player, + "The dog looks at you, confused, but takes the bones anyway." + ) + + woof = "Woof..?" + } + + Items.BABYDRAGON_BONES_534, + Items.BIG_BONES_532 -> { + sendMessage( + player, + "The dog seems to be very happy." + ) + + woof = "Woof!" + } + + Items.WYVERN_BONES_6812, + Items.DRAGON_BONES_536 -> { + sendMessage( + player, + "The dog seems to be extremely overjoyed." + ) + + woof = "WOOF!" + } + } + + sendChat(with, woof) + } + + return@onUseWith true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/withnpc/CatOnArdougneCivilian.kt b/Server/src/main/content/global/handlers/item/withnpc/CatOnArdougneCivilian.kt new file mode 100644 index 0000000..e69de29 diff --git a/Server/src/main/content/global/handlers/item/withnpc/CiderOnForester.kt b/Server/src/main/content/global/handlers/item/withnpc/CiderOnForester.kt new file mode 100644 index 0000000..31cb872 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withnpc/CiderOnForester.kt @@ -0,0 +1,57 @@ +package content.global.handlers.item.withnpc + +import core.api.inBorders +import core.api.sendNPCDialogue +import core.game.node.entity.player.link.diary.DiaryType +import core.game.node.item.Item +import org.rs09.consts.Items +import core.game.dialogue.DialogueFile +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +class CiderOnForester : InteractionListener { + override fun defineListeners() { + val ids = intArrayOf(1,2,3,4,5) + + onUseWith(IntType.NPC, Items.CIDER_5763, *ids){ player, used, with -> + if(inBorders(player, 2689, 3488, 2700, 3498)){ + player.dialogueInterpreter.open(CiderOnForesterDialogue(),with) + return@onUseWith true + } + return@onUseWith false + } + } +} + +class CiderOnForesterDialogue : DialogueFile() { + var init = true + override fun handle(componentID: Int, buttonID: Int) { + + if(init) stage = 0; init = false + + when(stage){ + 0 -> sendNPCDialogue(player!!, this.npc!!.id,"Ah, a glass of cider, Don't mind if I do!").also { stage = 1 } + 1 -> { + sendNPCDialogue(player!!,this.npc!!.id,"Thanks!") + player!!.inventory.remove(Item(Items.CIDER_5763,1)) + stage = 3 + } + 3 -> { + if(player!!.getAttribute("seersCiderPub",-1) == 4){ + player!!.achievementDiaryManager?.finishTask(player,DiaryType.SEERS_VILLAGE,0,6) + player!!.removeAttribute("seersCiderPub") + end() + } + else if(player!!.getAttribute("seersCiderPub",-1) !in 0..3 && !player!!.achievementDiaryManager.hasCompletedTask(DiaryType.SEERS_VILLAGE,0,6)){ + player!!.setAttribute("seersCiderPub",0) + end() + }else if(player!!.getAttribute("seersCiderPub",-1) in 0..3){ + player!!.incrementAttribute("seersCiderPub",1) + end() + }else end() + } + } + } + + +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/withnpc/FeedFaladorSheepdog.kt b/Server/src/main/content/global/handlers/item/withnpc/FeedFaladorSheepdog.kt new file mode 100644 index 0000000..3d32a2e --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withnpc/FeedFaladorSheepdog.kt @@ -0,0 +1,51 @@ +package content.global.handlers.item.withnpc + +import core.api.* +import content.global.skill.prayer.Bones +import content.data.Meat +import content.data.MeatState +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Animations +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +class FeedFaladorSheepdog : InteractionListener { + companion object { + private const val SHEEP_DOG_NPC = NPCs.SHEEPDOG_2311 + private val FEED_ANIMATION = Animation(Animations.HUMAN_BURYING_BONES_827) + private val CONSUMABLE_BONES = Bones.array + .filter { it != Items.BURNT_BONES_528 } + .toHashSet() + private val CONSUMABLE_MEATS = Meat.values() + .filter { it.state == MeatState.INEDIBLE_RAW || it.state == MeatState.EDIBLE_COOKED } + .map { it.id } + .toHashSet() + } + + override fun defineListeners() { + onUseAnyWith(IntType.NPC, SHEEP_DOG_NPC) { player, used, with -> + if (CONSUMABLE_BONES.contains(used.id)) { + if (!removeItem(player, used.asItem())) { + return@onUseAnyWith true + } + sendDialogue(player, "You give the dog some nice ${used.name.toLowerCase()}. It happily gnaws on them.") + } else if (CONSUMABLE_MEATS.contains(used.id)) { + if (!removeItem(player, used.asItem())) { + return@onUseAnyWith true + } + sendDialogue(player, "You give the dog a nice piece of meat. It gobbles it up.") + } else { + sendMessage(player, "The dog doesn't seem interested in that.") + sendChat(with.asNpc(), "Grrrr!") + return@onUseAnyWith true + } + + animate(player, FEED_ANIMATION) + sendChat(with.asNpc(), "Woof woof!") + + return@onUseAnyWith true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/withnpc/GCItemOnCat.kt b/Server/src/main/content/global/handlers/item/withnpc/GCItemOnCat.kt new file mode 100644 index 0000000..0b54ccf --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withnpc/GCItemOnCat.kt @@ -0,0 +1,77 @@ +package content.global.handlers.item.withnpc + +import core.api.* +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.map.path.Path +import core.game.world.map.path.Pathfinder +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.game.world.GameWorld.Pulser +import content.data.Quests + +class GCItemOnCat : InteractionListener { + override fun defineListeners() { + val BEND_DOWN = 827 + + onUseWith(IntType.NPC, Items.BUCKET_OF_MILK_1927, NPCs.GERTRUDES_CAT_2997) { player, used, with -> + if(getQuestStage(player, Quests.GERTRUDES_CAT) == 20 && removeItem(player, used.asItem())){ + addItem(player, Items.BUCKET_1925) + animate(player, BEND_DOWN) //bend down + sendChat(with.asNpc(), "Mew!") + setQuestStage(player, Quests.GERTRUDES_CAT, 30) + } + return@onUseWith true + } + + onUseWith(IntType.NPC, Items.DOOGLE_SARDINE_1552, NPCs.GERTRUDES_CAT_2997){ player, used, with -> + if(getQuestStage(player, Quests.GERTRUDES_CAT) == 30 && removeItem(player, used.asItem())){ + animate(player, BEND_DOWN) + sendChat(with.asNpc(), "Mew!") + setQuestStage(player, Quests.GERTRUDES_CAT, 40) + } + return@onUseWith true + } + + onUseWith(IntType.NPC, Items.RAW_SARDINE_327, NPCs.GERTRUDES_CAT_2997){ player, _, _ -> + sendMessage(player, "The cat doesn't seem interested in that.") + return@onUseWith true + } + + onUseWith(IntType.NPC, Items.THREE_LITTLE_KITTENS_13236, NPCs.GERTRUDES_CAT_2997){ player, used, with -> + if(removeItem(player, used.asItem())){ + setQuestStage(player, Quests.GERTRUDES_CAT, 60) + //below copied verbatim from original, I don't like it. + Pulser.submit(object : Pulse(1) { + var count = 0 + val kitten = core.game.node.entity.npc.NPC.create(761, player.location) + override fun pulse(): Boolean { + when (count) { + 0 -> { + kitten.init() + kitten.face(with.asNpc()) + with.asNpc().face(kitten) + with.asNpc().sendChat("Pur...") + kitten.sendChat("Pur...") + val path: Path = Pathfinder.find(with.asNpc(), Location(3310, 3510, 1)) + path.walk(with.asNpc()) + val pathh = Pathfinder.find(kitten, Location(3310, 3510, 1)) + pathh.walk(kitten) + } + 5 -> { + kitten.clear() + player.setAttribute("hidefluff", System.currentTimeMillis() + 60000) + } + } + count++ + return count == 6 + } + }) + } + + return@onUseWith true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/withnpc/GertrudeCatUsePlugin.java b/Server/src/main/content/global/handlers/item/withnpc/GertrudeCatUsePlugin.java new file mode 100644 index 0000000..efddb3b --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withnpc/GertrudeCatUsePlugin.java @@ -0,0 +1,107 @@ +package content.global.handlers.item.withnpc; + +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.path.Path; +import core.game.world.map.path.Pathfinder; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; +import content.data.Quests; + +/** + * Represents the plugin used to handle the use with interactions. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class GertrudeCatUsePlugin extends UseWithHandler { + + /** + * Represents the animation of bending down. + */ + private static final Animation BEND_DOWN = Animation.create(827); + + /** + * Represents the empty bucket. + */ + private static final Item EMPTY_BUCKET = new Item(1925); + + /** + * Constructs a new {@code GertrudeCatUsePlugin} {@code Object}. + */ + public GertrudeCatUsePlugin() { + super(1927, 1552, 327, 13236); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(2997, NPC_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + final NPC npc = ((NPC) event.getUsedWith()); + final Quest quest = player.getQuestRepository().getQuest(Quests.GERTRUDES_CAT); + if (event.getUsedItem().getId() == 1927 && quest.getStage(player) == 20) { + if (player.getInventory().remove(event.getUsedItem())) { + player.getInventory().add(EMPTY_BUCKET); + player.animate(BEND_DOWN); + npc.sendChat("Mew!"); + quest.setStage(player, 30); + } + } else if (event.getUsedItem().getId() == 1552 && quest.getStage(player) == 30) { + if (player.getInventory().remove(event.getUsedItem())) { + player.animate(BEND_DOWN); + npc.sendChat("Mew!"); + quest.setStage(player, 40); + } + } else if (event.getUsedItem().getId() == 327 && quest.getStage(player) == 50) { + player.getDialogueInterpreter().sendDialogue("The cat doesn't seem interested in that."); + } else if (event.getUsedItem().getId() == 13236) { + if (player.getInventory().remove(event.getUsedItem())) { + quest.setStage(player, 60); + player.lock(5); + GameWorld.getPulser().submit(new Pulse(1) { + int count = 0; + final NPC kitten = NPC.create(761, player.getLocation()); + + @Override + public boolean pulse() { + switch (count) { + case 0: + kitten.init(); + kitten.face(npc); + npc.face(kitten); + npc.sendChat("Pur..."); + kitten.sendChat("Pur..."); + final Path path = Pathfinder.find(npc, new Location(3310, 3510, 1)); + path.walk(npc); + final Path pathh = Pathfinder.find(kitten, new Location(3310, 3510, 1)); + pathh.walk(kitten); + break; + case 5: + kitten.clear(); + player.setAttribute("hidefluff", System.currentTimeMillis() + 60000); + break; + } + count++; + return count == 6; + } + + }); + } + } + return true; + } + +} diff --git a/Server/src/main/content/global/handlers/item/withnpc/HatEasterEgg.kt b/Server/src/main/content/global/handlers/item/withnpc/HatEasterEgg.kt new file mode 100644 index 0000000..4e41d8d --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withnpc/HatEasterEgg.kt @@ -0,0 +1,51 @@ +package content.global.handlers.item.withnpc + +import core.game.node.entity.npc.NPC +import core.game.node.item.Item +import core.game.world.update.flag.context.Graphics +import org.rs09.consts.Items +import core.game.dialogue.DialogueFile +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +val graphics = 482 +class HatEasterEgg : InteractionListener { + + val MACHINE = 20040 + val WIZ_HAT = Items.WIZARD_HAT_579 + val NEW_HAT = 14650 + + override fun defineListeners() { + onUseWith(IntType.SCENERY,WIZ_HAT,MACHINE){ player, used, with -> + player.dialogueInterpreter.open(HatDialogue(), NPC(872)) + return@onUseWith true + } + } + +} + +class HatDialogue : DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + when(stage++){ + 0 -> { + npc("WHAT HAVE YOU DONE?") + player!!.graphics(Graphics(graphics)) + } + 1 -> player(core.game.dialogue.FacialExpression.AFRAID,"What do you mean?!") + 2 -> npc("You've disjointed the fabric assimilation matrix!") + 3 -> player(core.game.dialogue.FacialExpression.THINKING,"W-what...?") + 4 -> npc("You've put us at risk of ripping Gielinor apart!") + 5 -> player(core.game.dialogue.FacialExpression.HALF_GUILTY,"I.. I just wanted a hat...") + 6 -> npc("Damn you and damn your hat! You could kill us all!") + 7 -> player("I... I'm sorry....") + 8 -> npc("*sigh* I've managed to stabilize the flux material inductors.") + 9 -> npc("You may just be safe, yet.") + 10 -> npc("Here, take your damn hat and get out of here.") + 11 -> { + end() + player!!.inventory.remove(Item(Items.WIZARD_HAT_579)) + player!!.inventory.add(Item(14650)) + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/withnpc/MistagEasterEgg.kt b/Server/src/main/content/global/handlers/item/withnpc/MistagEasterEgg.kt new file mode 100644 index 0000000..10d7aa1 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withnpc/MistagEasterEgg.kt @@ -0,0 +1,73 @@ +package content.global.handlers.item.withnpc + +import core.game.component.Component +import core.game.node.item.Item +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import core.game.dialogue.DialogueFile +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.game.world.update.flag.context.Animation +import core.tools.END_DIALOGUE +import core.api.* + +class MistagEasterEgg : InteractionListener { + val DIAMOND = Items.DIAMOND_1601 + val MISTAG = NPCs.MISTAG_2084 + val ZANIK_RING = 14649 + val DRUNK_RENDER = 982 + + override fun defineListeners() { + onUseWith(IntType.NPC,DIAMOND,MISTAG){ player, _, with -> + val alreadyHasRing = player.inventory.contains(ZANIK_RING,1) || player.bank.contains(ZANIK_RING,1) || player.equipment.contains(ZANIK_RING,1) + player.dialogueInterpreter.open(MistagEasterEggDialogue(alreadyHasRing),with.asNpc()) + return@onUseWith true + } + + onEquip(ZANIK_RING){player,_ -> + player.appearance.transformNPC(NPCs.ZANIK_3712) + return@onEquip true + } + + onUnequip(ZANIK_RING){player, _ -> + player.appearance.transformNPC(-1) + return@onUnequip true + } + + onEquip(Items.BEER_1917){player, _ -> + setAttribute(player, "render-anim-override", DRUNK_RENDER) + return@onEquip true + } + + onUnequip(Items.BEER_1917){player, _ -> + removeAttribute(player, "render-anim-override") + player.appearance.setDefaultAnimations() + player.appearance.sync() + return@onUnequip true + } + } +} + +class MistagEasterEggDialogue(val hasRing: Boolean): DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + + if(hasRing){ + npc("Lovely gem, adventurer, but I have nothing for you.").also { stage = END_DIALOGUE } + return + } + + when(stage++){ + 0 -> npc("Well thank you adventurer! Here, take this.") + 1 -> { + end() + if(player!!.inventory.remove(Item(Items.DIAMOND_1601))){ + player!!.inventory.add(Item(14649)) + } + } + } + } + + override fun npc(vararg messages: String?): Component? { + return super.npc(core.game.dialogue.FacialExpression.OLD_HAPPY,*messages) + } +} diff --git a/Server/src/main/content/global/handlers/item/withnpc/PoisonChaliceOnKingArthur.kt b/Server/src/main/content/global/handlers/item/withnpc/PoisonChaliceOnKingArthur.kt new file mode 100644 index 0000000..e8bd4fe --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withnpc/PoisonChaliceOnKingArthur.kt @@ -0,0 +1,52 @@ +package content.global.handlers.item.withnpc + +import core.game.node.item.Item +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import core.game.dialogue.DialogueFile +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.tools.END_DIALOGUE + +class PoisonChaliceOnKingArthur : InteractionListener { + override fun defineListeners() { + onUseWith(IntType.NPC, Items.POISON_CHALICE_197, NPCs.KING_ARTHUR_251) { player, _, with -> + player.dialogueInterpreter.open(PoisonChaliceOnKingArthurDialogue(), with) + return@onUseWith true + } + } +} + +class PoisonChaliceOnKingArthurDialogue : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> npcl( + core.game.dialogue.FacialExpression.SAD, + "You have chosen poorly." + ).also { stage++ } + + 1 -> playerl( + core.game.dialogue.FacialExpression.ANNOYED, + "Excuse me?" + ).also { stage++ } + + 2 -> npcl( + core.game.dialogue.FacialExpression.FRIENDLY, + "Sorry, I meant to say 'thank you'. Most refreshing." + ).also { stage++ } + + 3 -> playerl( + core.game.dialogue.FacialExpression.DISGUSTED_HEAD_SHAKE, + "Are you sure that stuff is safe to drink?" + ).also { stage++ } + + 4 -> npcl( + core.game.dialogue.FacialExpression.HAPPY, + "Oh yes, Stankers' creations may be dangerous for those with weak constitutions, but, personally. I find them rather invigorating." + ).also { + player!!.inventory.remove(Item(197, 1)) + stage = END_DIALOGUE + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/withnpc/RopeOnLadyKeli.kt b/Server/src/main/content/global/handlers/item/withnpc/RopeOnLadyKeli.kt new file mode 100644 index 0000000..3dbd34a --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withnpc/RopeOnLadyKeli.kt @@ -0,0 +1,27 @@ +package content.global.handlers.item.withnpc + +import core.api.* +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import content.data.Quests + +class RopeOnLadyKeli : InteractionListener { + override fun defineListeners() { + onUseWith(IntType.NPC, Items.ROPE_954, NPCs.LADY_KELI_919) { player, used, with -> + if(getQuestStage(player, Quests.PRINCE_ALI_RESCUE) in 40..50 && getAttribute(player, "guard-drunk", false)){ + if(removeItem(player, used.asItem())){ + sendDialogue(player, "You overpower Keli, tie her up, and put her in a cupboard.") + setQuestStage(player, Quests.PRINCE_ALI_RESCUE, 50) + setAttribute(player, "keli-gone", getWorldTicks() + 350) + } + } else { + if (getQuestStage(player, Quests.PRINCE_ALI_RESCUE) == 40){ + sendMessage(player, "You need to do something about the guard first.") + } + } + return@onUseWith true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/withnpc/ZooknockListener.kt b/Server/src/main/content/global/handlers/item/withnpc/ZooknockListener.kt new file mode 100644 index 0000000..297740e --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withnpc/ZooknockListener.kt @@ -0,0 +1,28 @@ +package content.global.handlers.item.withnpc + +import content.region.misc.apeatoll.dialogue.dungeon.ZooknockDialogueFile +import core.api.openDialogue +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +open class ZooknockListener() : InteractionListener { + val goldBar = Items.GOLD_BAR_2357 + val monkeyAmuletMould = Items.MAMULET_MOULD_4020 + val monkeyDentures = Items.MONKEY_DENTURES_4006 + + + val items = intArrayOf(goldBar, monkeyDentures, monkeyAmuletMould) + + val zooknock = NPCs.ZOOKNOCK_1425 + + val lol = arrayOf(Items) + + override fun defineListeners() { + onUseWith(IntType.NPC, items, zooknock) { + player, used, with -> openDialogue(player, ZooknockDialogueFile(used.id)) + return@onUseWith false + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/withobject/AmmoMouldOnFurnace.kt b/Server/src/main/content/global/handlers/item/withobject/AmmoMouldOnFurnace.kt new file mode 100644 index 0000000..0d5929d --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withobject/AmmoMouldOnFurnace.kt @@ -0,0 +1,89 @@ +package content.global.handlers.item.withobject + +import content.data.Quests +import core.api.* +import core.game.node.Node +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.system.task.Pulse +import org.rs09.consts.Items +import core.game.dialogue.SkillDialogueHandler +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import org.rs09.consts.Sounds + +class AmmoMouldOnFurnace : InteractionListener { + private val furnaces = intArrayOf(4304, 6189, 11010, 11666, 12100, 12809, 18497, 26814, 30021, 30510, 36956, 37651) // abstract when smelting converted to kotlin + private val levelRequirement = 35 + + private fun cannonBallOnUseWithHandler(player: Player, used: Node, with: Node): Boolean { + face(player, with.centerLocation) + + if(!isQuestComplete(player, Quests.DWARF_CANNON)) { + sendDialogue(player, "You need to complete the ${Quests.DWARF_CANNON} quest in order to do this.") + return true + } + if (getDynLevel(player, Skills.SMITHING) < levelRequirement) { + sendDialogue(player,"You need a Smithing level of at least $levelRequirement in order to do this.") + return true + } + if (!inInventory(player, Items.AMMO_MOULD_4)) { + sendDialogue(player,"You need an ammo mould in order to make a cannon ball.") + return true + } + + val cannonBallPulse = object : Pulse() { + private var tick = 0 + var amount = 0 + override fun pulse(): Boolean { + when(tick++){ + 0 -> { + sendMessage(player,"You heat the steel bar into a liquid state.") + animate(player, 3243) // 899 would be preferable but the arms spaz out + playAudio(player, Sounds.FURNACE_2725) + } + 3 -> { + sendMessage(player,"You pour the molten metal into your cannonball mould.") + animate(player, 827) + } + 4 -> { + sendMessage(player,"The molten metal cools slowly to form 4 cannonballs.") + } + 7 -> { + if (removeItem(player, used.asItem())) { + addItem(player, Items.CANNONBALL_2, 4) + rewardXP(player, Skills.SMITHING, 25.6) + } + animate(player, 827) + } + 10 -> { + if (--amount == 0 || !inInventory(player, Items.STEEL_BAR_2353)) { + return true + } + tick = 0 + } + } + return false + } + } + + val itemUsed = used.asItem() + + val dialogue: SkillDialogueHandler = object : SkillDialogueHandler(player, SkillDialogue.ONE_OPTION, itemUsed) { + override fun create(amount: Int, index: Int) { + cannonBallPulse.amount = amount + submitIndividualPulse(player, cannonBallPulse) + } + + override fun getAll(index: Int): Int { + return amountInInventory(player, itemUsed.id) + } + } + openDialogue(player, dialogue) + return true + } + + override fun defineListeners() { + onUseWith(IntType.SCENERY, Items.STEEL_BAR_2353, *furnaces, handler = ::cannonBallOnUseWithHandler) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/withobject/AxeOnTree.kt b/Server/src/main/content/global/handlers/item/withobject/AxeOnTree.kt new file mode 100644 index 0000000..b9e89f6 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withobject/AxeOnTree.kt @@ -0,0 +1,20 @@ +package content.global.handlers.item.withobject + +import core.api.* +import content.global.skill.gather.woodcutting.WoodcuttingNode +import content.global.skill.gather.woodcutting.WoodcuttingSkillPulse +import org.rs09.consts.Items +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +class AxeOnTree : InteractionListener { + val axes = intArrayOf(Items.BRONZE_AXE_1351, Items.MITHRIL_AXE_1355, Items.IRON_AXE_1349, Items.BLACK_AXE_1361, Items.STEEL_AXE_1353, Items.ADAMANT_AXE_1357, Items.RUNE_AXE_1359, Items.DRAGON_AXE_6739, Items.INFERNO_ADZE_13661) + val trees = WoodcuttingNode.values().map { it.id }.toIntArray() + + override fun defineListeners() { + onUseWith(IntType.SCENERY, axes, *trees){ player, _, with -> + submitIndividualPulse(player, WoodcuttingSkillPulse(player, with.asScenery())) + return@onUseWith true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/withobject/CauldronOfThunderListener.kt b/Server/src/main/content/global/handlers/item/withobject/CauldronOfThunderListener.kt new file mode 100644 index 0000000..d33edf3 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withobject/CauldronOfThunderListener.kt @@ -0,0 +1,45 @@ +package content.global.handlers.item.withobject + +import core.api.addItem +import core.api.animate +import core.api.removeItem +import core.api.sendMessage +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items +import org.rs09.consts.Scenery +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import java.util.* + +/** + * Listener for Cauldron of Thunder interaction + * @author Byte + */ +@Suppress("unused") +class CauldronOfThunderListener : InteractionListener { + + companion object { + private val ANIMATION = Animation(833) + + private val ITEM_MAP = mapOf( + Items.RAW_BEEF_2132 to Items.ENCHANTED_BEEF_522, + Items.RAW_RAT_MEAT_2134 to Items.ENCHANTED_RAT_MEAT_523, + Items.RAW_BEAR_MEAT_2136 to Items.ENCHANTED_BEAR_MEAT_524, + Items.RAW_CHICKEN_2138 to Items.ENCHANTED_CHICKEN_525 + ) + } + + override fun defineListeners() { + onUseWith(IntType.SCENERY, ITEM_MAP.keys.toIntArray(), Scenery.CAULDRON_OF_THUNDER_2142) { player, used, _ -> + if (!removeItem(player, used)) { + return@onUseWith false + } + + animate(player, ANIMATION) + addItem(player, ITEM_MAP[used.id]!!) + sendMessage(player, "You dip the " + used.name.lowercase(Locale.getDefault()) + " in the cauldron.") + + return@onUseWith true + } + } +} diff --git a/Server/src/main/content/global/handlers/item/withobject/ChestKeyListener.kt b/Server/src/main/content/global/handlers/item/withobject/ChestKeyListener.kt new file mode 100644 index 0000000..a64638f --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withobject/ChestKeyListener.kt @@ -0,0 +1,35 @@ +package content.global.handlers.item.withobject + +import core.api.addItem +import core.api.removeItem +import core.api.replaceScenery +import core.api.sendMessage +import org.rs09.consts.Items +import org.rs09.consts.Scenery +import core.game.interaction.IntType +import core.game.interaction.InteractionListener + +/** + * Listener for using key on pirate chest in Blue Moon Inn + * @author Byte + */ +@Suppress("unused") +class ChestKeyListener : InteractionListener { + + override fun defineListeners() { + onUseWith(IntType.SCENERY, Items.CHEST_KEY_432, Scenery.CHEST_2079) { player, used, with -> + if (!removeItem(player, used)) { + return@onUseWith false + } + + replaceScenery(with as core.game.node.scenery.Scenery, 2080, 3) + + addItem(player, Items.PIRATE_MESSAGE_433) + sendMessage(player, "You unlock the chest.") + sendMessage(player, "All that's in the chest is a message...") + sendMessage(player, "You take the message from the chest.") + + return@onUseWith true + } + } +} diff --git a/Server/src/main/content/global/handlers/item/withobject/CoalTruckListener.kt b/Server/src/main/content/global/handlers/item/withobject/CoalTruckListener.kt new file mode 100644 index 0000000..c2fef6e --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withobject/CoalTruckListener.kt @@ -0,0 +1,76 @@ +package content.global.handlers.item.withobject + +import core.api.* +import core.game.node.item.Item +import org.rs09.consts.Items +import org.rs09.consts.Scenery +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +/** + * Handles coal truck interactions + * @author ceik + * @author vddCore + */ +class CoalTruckListener : InteractionListener { + companion object { + private const val ATTRIBUTE_COAL_TRUCK_INVENTORY = "coal-truck-inventory" + } + + override fun defineListeners() { + on(Scenery.COAL_TRUCK_2114, IntType.SCENERY, "remove-coal") { player, node -> + var coalInTruck = getAttribute(player, ATTRIBUTE_COAL_TRUCK_INVENTORY, 0) + + if (coalInTruck == 0) { + sendDialogue(player, "The coal truck is empty.") + return@on true + } + + var toRemove = freeSlots(player) + + if (toRemove > coalInTruck) { + toRemove = coalInTruck + } + + if (addItem(player, Items.COAL_453, toRemove)) { + coalInTruck -= toRemove + setAttribute(player, "/save:$ATTRIBUTE_COAL_TRUCK_INVENTORY", coalInTruck) + } + + return@on true + } + + on(Scenery.COAL_TRUCK_2114, IntType.SCENERY, "investigate") { player, _ -> + val coalInTruck = getAttribute(player, ATTRIBUTE_COAL_TRUCK_INVENTORY, 0) + + sendDialogue( + player, + "There is currently $coalInTruck coal in the truck. " + + "The truck has space for " + (120 - coalInTruck) + " more coal." + ) + return@on true + } + + onUseWith(IntType.SCENERY, Items.COAL_453, Scenery.COAL_TRUCK_2114) { player, _, _ -> + var coalInTruck = getAttribute(player, ATTRIBUTE_COAL_TRUCK_INVENTORY, 0) + var coalInInventory = amountInInventory(player, Items.COAL_453) + + if (coalInInventory + coalInTruck >= 120) { + coalInInventory = 120 - coalInTruck + sendMessage(player, "You have filled up the coal truck.") + } + + if (removeItem(player, Item(Items.COAL_453, coalInInventory))) { + coalInTruck += coalInInventory + + setAttribute( + player, + "/save:$ATTRIBUTE_COAL_TRUCK_INVENTORY", + coalInTruck + ) + } + + return@onUseWith true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/withobject/DragonPlatebody.java b/Server/src/main/content/global/handlers/item/withobject/DragonPlatebody.java new file mode 100644 index 0000000..b8f3d60 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withobject/DragonPlatebody.java @@ -0,0 +1,5 @@ +package content.global.handlers.item.withobject; + +public class DragonPlatebody { + +} diff --git a/Server/src/main/content/global/handlers/item/withobject/FishEasterEgg.kt b/Server/src/main/content/global/handlers/item/withobject/FishEasterEgg.kt new file mode 100644 index 0000000..c5e1869 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withobject/FishEasterEgg.kt @@ -0,0 +1,26 @@ +package content.global.handlers.item.withobject + +import core.api.* +import content.global.skill.gather.woodcutting.WoodcuttingNode +import org.rs09.consts.Items +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +class FishEasterEgg : InteractionListener { + val TREE_IDs = WoodcuttingNode.values().map { it.id }.toIntArray() + + val fish = intArrayOf(Items.RAW_HERRING_345, Items.HERRING_347) + val doors = intArrayOf(1967,1968) + + override fun defineListeners() { + onUseWith(IntType.SCENERY, fish, *TREE_IDs){ player, _, _ -> + sendMessage(player, "This is not the mightiest tree in the forest.") + return@onUseWith true + } + + onUseWith(IntType.SCENERY, fish, *doors){ player, _, _ -> + sendMessage(player, "It can't be done!") + return@onUseWith true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/withobject/GWDEntranceRopeListener.kt b/Server/src/main/content/global/handlers/item/withobject/GWDEntranceRopeListener.kt new file mode 100644 index 0000000..3243649 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withobject/GWDEntranceRopeListener.kt @@ -0,0 +1,28 @@ +package content.global.handlers.item.withobject + +import core.api.removeItem +import core.api.setVarbit +import org.rs09.consts.Items +import org.rs09.consts.Scenery +import core.game.interaction.IntType +import core.game.interaction.InteractionListener + +/** + * Listener for using a rope directly on the GWD entrance hole + * @author Byte + */ +@Suppress("unused") +class GWDEntranceRopeListener : InteractionListener { + + override fun defineListeners() { + onUseWith(IntType.SCENERY, Items.ROPE_954, Scenery.HOLE_26340) { player, used, _ -> + if (!removeItem(player, used)) { + return@onUseWith false + } + + setVarbit(player, 3932, 1, true) + + return@onUseWith true + } + } +} diff --git a/Server/src/main/content/global/handlers/item/withobject/HairdresserCheeseListener.kt b/Server/src/main/content/global/handlers/item/withobject/HairdresserCheeseListener.kt new file mode 100644 index 0000000..0606f65 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withobject/HairdresserCheeseListener.kt @@ -0,0 +1,37 @@ +package content.global.handlers.item.withobject + +import core.api.* +import core.game.node.entity.player.link.diary.DiaryType +import org.rs09.consts.Items +import org.rs09.consts.Scenery +import core.game.interaction.IntType +import core.game.interaction.InteractionListener + +/** + * Listener for using cheese on Ridgeley on the treadmill + * @author Byte + */ +@Suppress("unused") +class HairdresserCheeseListener : InteractionListener { + + override fun defineListeners() { + onUseWith(IntType.SCENERY, Items.CHEESE_1985, Scenery.TREADMILL_11677) { player, used, _ -> + lock(player, 5) + + var isTaskSuccessful = false + runTask(player,3,1) { + if (!removeItem(player, used)) { + return@runTask + } + + sendMessage(player,"You throw the cheese to Ridgeley, for which he appears grateful.") + player.achievementDiaryManager.finishTask(player, DiaryType.FALADOR, 0, 6) + unlock(player) + + isTaskSuccessful = true + } + + return@onUseWith isTaskSuccessful + } + } +} diff --git a/Server/src/main/content/global/handlers/item/withobject/HatStand.kt b/Server/src/main/content/global/handlers/item/withobject/HatStand.kt new file mode 100644 index 0000000..91205e5 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withobject/HatStand.kt @@ -0,0 +1,20 @@ +package content.global.handlers.item.withobject + +import core.api.* +import core.api.EquipmentSlot +import core.cache.def.impl.ItemDefinition +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +class HatStand : InteractionListener { + + val hats = ItemDefinition.getDefinitions().values.filter { it.getConfiguration("equipment_slot",0) == EquipmentSlot.HEAD.ordinal }.map { it.id }.toIntArray() + val hat_stand = 374 + + override fun defineListeners() { + onUseWith(IntType.SCENERY, hats, hat_stand){ player, used, with -> + sendDialogue(player, "It'd probably fall off if I tried to do that.") + return@onUseWith true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/withobject/KaramjaBananaCrateListener.kt b/Server/src/main/content/global/handlers/item/withobject/KaramjaBananaCrateListener.kt new file mode 100644 index 0000000..6db716b --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withobject/KaramjaBananaCrateListener.kt @@ -0,0 +1,128 @@ +package content.global.handlers.item.withobject + +import core.api.* +import core.game.node.item.Item +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items +import org.rs09.consts.Scenery +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import kotlin.math.min + +/** + * Listener for Karamja banana crate interaction + * @author Byte + */ +@Suppress("unused") +class KaramjaBananaCrateListener : InteractionListener { + + companion object { + private const val CRATE_CAPACITY = 10 + + private val ANIMATION = Animation(832) + } + + override fun defineListeners() { + onUseWith(IntType.SCENERY, Items.KARAMJAN_RUM_431, Scenery.CRATE_2072) { player, used, _ -> + if (!player.savedData.globalData.isLuthasTask) { + sendMessage(player, "I don't know what goes in there.") + return@onUseWith true + } + + if (getAttribute(player, "stashed-rum", false)) { + sendMessage(player, "There's already some rum in here...") + return@onUseWith true + } + + if (!removeItem(player, used)) { + return@onUseWith false + } + + lock(player, 2) + animate(player, ANIMATION) + sendDialogue(player, "You stash the rum in the crate.") + setAttribute(player, "/save:stashed-rum", true) + + return@onUseWith true + } + + onUseWith(IntType.SCENERY, Items.BANANA_1963, Scenery.CRATE_2072) { player, used, _ -> + if (!player.savedData.globalData.isLuthasTask) { + sendMessage(player, "I don't know what goes in there.") + return@onUseWith true + } + + val currNumBananasInCrate = player.savedData.globalData.karamjaBananas + + if (currNumBananasInCrate >= CRATE_CAPACITY) { + sendMessage(player, "The crate is already full.") + return@onUseWith true + } + + if (!removeItem(player, used)) { + return@onUseWith false + } + + lock(player, 2) + animate(player, ANIMATION) + sendDialogue(player, "You pack a banana into the crate.") + player.savedData.globalData.setKaramjaBannanas(currNumBananasInCrate + 1) + + return@onUseWith true + } + + on(Scenery.CRATE_2072, IntType.SCENERY, "search") { player, _ -> + if (!player.savedData.globalData.isLuthasTask) { + sendMessage(player, "I don't know what goes in there.") + return@on true + } + + val currNumBananasInCrate = player.savedData.globalData.karamjaBananas + + if (currNumBananasInCrate == 0) { + sendMessage(player, "The crate is completely empty.") + return@on true + } + + if (currNumBananasInCrate >= CRATE_CAPACITY) { + sendMessage(player, "The crate is full of bananas.") + return@on true + } + + sendMessage(player, "The crate has " + currNumBananasInCrate + " banana" + (if (currNumBananasInCrate > 1) "s" else "") + " inside.") + + return@on true + } + + on(Scenery.CRATE_2072, IntType.SCENERY, "fill") { player, _ -> + if (!player.savedData.globalData.isLuthasTask) { + sendMessage(player, "I don't know what goes in there.") + return@on true + } + + val numBananas = amountInInventory(player, Items.BANANA_1963) + val currNumBananasInCrate = player.savedData.globalData.karamjaBananas + val bananasToBeAdded = min(numBananas, CRATE_CAPACITY - player.savedData.globalData.karamjaBananas) + + if (numBananas == 0) { + return@on true + } + + if (currNumBananasInCrate >= CRATE_CAPACITY) { + sendMessage(player, "The crate is already full.") + return@on true + } + + if (!removeItem(player, Item(Items.BANANA_1963, bananasToBeAdded))) { + return@on false + } + + lock(player, 2) + animate(player, ANIMATION) + sendMessage(player, "You pack all your bananas into the crate.") + player.savedData.globalData.setKaramjaBannanas(player.savedData.globalData.karamjaBananas + bananasToBeAdded) + + return@on true + } + } +} diff --git a/Server/src/main/content/global/handlers/item/withobject/PoisonFountainListener.kt b/Server/src/main/content/global/handlers/item/withobject/PoisonFountainListener.kt new file mode 100644 index 0000000..efb5a85 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withobject/PoisonFountainListener.kt @@ -0,0 +1,56 @@ +package content.global.handlers.item.withobject + +import core.api.* +import core.game.system.task.Pulse +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items +import org.rs09.consts.Scenery +import core.game.interaction.IntType +import core.game.interaction.InteractionListener + +/** + * Listener for using poisoned fish food on Draynor Manor fountain + * @author Byte + */ +@Suppress("unused") +class PoisonFountainListener : InteractionListener { + + companion object { + private val ANIMATION = Animation(881) + } + + override fun defineListeners() { + onUseWith(IntType.SCENERY, Items.POISONED_FISH_FOOD_274, Scenery.FOUNTAIN_153) { player, used, _ -> + if (getAttribute(player, "piranhas-killed", false)) { + sendMessage(player, "The piranhas are dead already.") + return@onUseWith true + } + + if (!removeItem(player, used)) { + return@onUseWith false + } + + lock(player, 5) + animate(player, ANIMATION) + sendMessage(player, "You pour the poisoned fish food into the fountain.") + setAttribute(player, "/save:piranhas-killed", true) + + submitIndividualPulse(player, object : Pulse(1) { + var counter = 0 + override fun pulse(): Boolean { + when (counter++) { + 1 -> sendMessage(player, "The piranhas start eating the food...") + 2 -> { + sendMessage(player, "... then die and float to the surface.") + unlock(player) + return true + } + } + return false + } + }) + + return@onUseWith true + } + } +} diff --git a/Server/src/main/content/global/handlers/item/withobject/SackOnHay.kt b/Server/src/main/content/global/handlers/item/withobject/SackOnHay.kt new file mode 100644 index 0000000..0b942e6 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withobject/SackOnHay.kt @@ -0,0 +1,22 @@ +package content.global.handlers.item.withobject + +import core.api.Container +import core.api.* +import org.rs09.consts.Items +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +class SackOnHay : InteractionListener { + val SACK = Items.EMPTY_SACK_5418 + val HAY = intArrayOf(36892, 36894, 36896, 300, 34593, 298, 299) + + override fun defineListeners() { + onUseWith(IntType.SCENERY, SACK, *HAY){ player, used, _ -> + if(removeItem(player, used.asItem(), Container.INVENTORY)){ + addItem(player, Items.HAY_SACK_6057, 1) + sendMessage(player, "You fill the sack with hay.") + } + return@onUseWith true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/item/withobject/SandSourceListener.kt b/Server/src/main/content/global/handlers/item/withobject/SandSourceListener.kt new file mode 100644 index 0000000..7990846 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withobject/SandSourceListener.kt @@ -0,0 +1,48 @@ +package content.global.handlers.item.withobject + +import core.api.* +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items +import org.rs09.consts.Scenery +import core.game.interaction.IntType +import core.game.interaction.InteractionListener + +/** + * Listener for collecting buckets of sand from a sand pit + * @author Byte + */ +@Suppress("unused") +class SandSourceListener : InteractionListener { + + companion object { + private val ANIMATION = Animation(895) + + private val SAND_PITS = intArrayOf( + Scenery.SAND_PIT_2645, + Scenery.SAND_PIT_4373, + Scenery.SANDPIT_10814 + ) + } + + override fun defineListeners() { + onUseWith(IntType.SCENERY, Items.BUCKET_1925, *SAND_PITS) { player, used, _ -> + val numEmptyBuckets = amountInInventory(player, used.id) + + var animationTrigger = 0 + runTask(player, 2, numEmptyBuckets) { + if (removeItem(player, used)) { + if (animationTrigger % 2 == 0) { + animate(player, ANIMATION) + } + + sendMessage(player, "You fill the bucket with sand.") + addItem(player, Items.BUCKET_OF_SAND_1783) + } + + animationTrigger++ + } + + return@onUseWith true + } + } +} diff --git a/Server/src/main/content/global/handlers/item/withobject/SapCollectListener.kt b/Server/src/main/content/global/handlers/item/withobject/SapCollectListener.kt new file mode 100644 index 0000000..3607fda --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withobject/SapCollectListener.kt @@ -0,0 +1,88 @@ +package content.global.handlers.item.withobject + +import core.api.* +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Animations +import org.rs09.consts.Items +import org.rs09.consts.Scenery +import core.game.interaction.IntType +import core.game.interaction.InteractionListener + +/** + * Listener for collecting buckets of sap from trees + * @author Byte + */ +@Suppress("unused") +class SapCollectListener : InteractionListener { + + companion object { + private val ANIMATION = Animation(Animations.HUMAN_FILL_BUCKET_WITH_SAP_2009) + + private val TREES = intArrayOf( + Scenery.TREE_1276, + Scenery.TREE_1277, + Scenery.TREE_1278, + Scenery.TREE_1280, + Scenery.EVERGREEN_1315, + Scenery.EVERGREEN_1316, + Scenery.EVERGREEN_1318, + Scenery.EVERGREEN_1319, + Scenery.TREE_1330, + Scenery.TREE_1331, + Scenery.TREE_1332, + Scenery.TREE_3033, + Scenery.TREE_3034, + Scenery.TREE_3035, + Scenery.TREE_3036, + Scenery.TREE_3879, + Scenery.TREE_3881, + Scenery.TREE_3882, + Scenery.TREE_3883, + Scenery.TREE_10041, + Scenery.TREE_14308, + Scenery.TREE_14309, + Scenery.TREE_30132, + Scenery.TREE_30133, + Scenery.TREE_37477, + Scenery.TREE_37478, + Scenery.TREE_37652 + ) + } + + override fun defineListeners() { + onUseWith(IntType.SCENERY, Items.KNIFE_946, *TREES) { player, _, _ -> + if (!inInventory(player, Items.BUCKET_1925)) { + sendMessage(player, "You need a bucket to do that.") + } + + submitIndividualPulse(player, object : Pulse(2) { + override fun pulse(): Boolean { + if (removeItem(player, Items.BUCKET_1925)) { + animate(player, ANIMATION) + sendMessage(player, "You cut the tree and allow its sap to drip down into your bucket.") + addItem(player, Items.BUCKET_OF_SAP_4687) + return true + } + return false + } + }) + + return@onUseWith true + } + + on(Items.BUCKET_OF_SAP_4687, IntType.ITEM, "empty") { player, node -> + val item = node as Item + + if (item.slot < 0) { + return@on false + } + + replaceSlot(player, item.slot, Item(Items.BUCKET_1925)) + sendMessage(player, "You empty the contents of the bucket on the floor.") + + return@on true + } + } +} diff --git a/Server/src/main/content/global/handlers/item/withobject/SmithingPlugin.java b/Server/src/main/content/global/handlers/item/withobject/SmithingPlugin.java new file mode 100644 index 0000000..e9ef946 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withobject/SmithingPlugin.java @@ -0,0 +1,139 @@ +package content.global.handlers.item.withobject; + +import content.global.skill.skillcapeperks.SkillcapePerks; +import core.cache.def.impl.SceneryDefinition; +import core.game.node.entity.skill.Skills; +import content.global.skill.smithing.SmithingBuilder; +import content.global.skill.smithing.smelting.Bar; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.OptionHandler; +import core.game.interaction.UseWithHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.plugin.Plugin; +import core.plugin.Initializable; +import core.plugin.ClassScanner; +import content.data.Quests; + +/** + * Represents the option handler used for smithing. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class SmithingPlugin extends UseWithHandler { + + /** + * The hammer item. + */ + private static final Item HAMMER = new Item(2347); + + /** + * Constructs a new {@code SmithingPlugin} {@code Object}. + */ + public SmithingPlugin() { + super(2349, 2351, 2353, 2359, 2361, 2363, 2366, 2368, 9467, 11286, 1540, 11710, 11712, 11714, 11686, 11688, 11692); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(2782, OBJECT_TYPE, this); + addHandler(2783, OBJECT_TYPE, this); + addHandler(4306, OBJECT_TYPE, this); + addHandler(6150, OBJECT_TYPE, this); + addHandler(22725, OBJECT_TYPE, this); + addHandler(26817, OBJECT_TYPE, this); + addHandler(26822, OBJECT_TYPE, this); + addHandler(37622, OBJECT_TYPE, this); + addHandler(42027, OBJECT_TYPE, this); + ClassScanner.definePlugin(new OptionHandler() { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(42027).getHandlers().put("option:smith", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + SmithingPlugin.this.handle(new NodeUsageEvent(player, 10, HAMMER, node)); + return true; + } + + }); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + if (((Scenery) event.getUsedWith()).getId() == 2782 && !player.getQuestRepository().isComplete(Quests.DORICS_QUEST)) { + player.getDialogueInterpreter().sendDialogue("Property of Doric the Dwarf."); + return true; + } + if (!player.getInventory().contains(2347, 1) && !SkillcapePerks.isActive(SkillcapePerks.BAREFISTED_SMITHING,player)) { + player.getDialogueInterpreter().sendDialogue("You need a hammer to work the metal with."); + return true; + } else { + if (event.getUsedItem().getId() == 2366 || event.getUsedItem().getId() == 2368) { + if (player.getSkills().getLevel(Skills.SMITHING) < 60) { + player.getDialogueInterpreter().sendDialogue("You need a smithing level of 60 to smith this."); + return true; + } + if (!player.getInventory().contains(2366, 1) && !player.getInventory().contains(2368, 1)) { + player.getDialogueInterpreter().sendDialogue("You need a shield left half and a shield right half."); + return true; + } + player.getDialogueInterpreter().open(82127843, 1, event.getUsedItem().getId()); + return true; + } + if (event.getUsedItem().getId() == 11286 || event.getUsedItem().getId() == 1540) { + if (player.getSkills().getLevel(Skills.SMITHING) < 90) { + player.getDialogueInterpreter().sendDialogue("You need a smithing level of 90 to smith this."); + return true; + } + if (!player.getInventory().contains(1540, 1) && !player.getInventory().contains(11286, 1)) { + player.getDialogueInterpreter().sendDialogue("You need a draconic visage and a anti-dragon shield."); + return true; + } + player.getDialogueInterpreter().open(82127843, 2, event.getUsedItem().getId()); + return true; + } + if (event.getUsedItem().getId() == 11710 || event.getUsedItem().getId() == 11712 || event.getUsedItem().getId() == 11714 || event.getUsedItem().getId() == 11686 || event.getUsedItem().getId() == 11688 || event.getUsedItem().getId() == 11692) { + if (player.getSkills().getLevel(Skills.SMITHING) < 80) { + player.getDialogueInterpreter().sendDialogue("You need a smithing level of 80 to smith this."); + return true; + } + player.getDialogueInterpreter().open(62362, event.getUsedItem().getId()); + return true; + } + Bar bar = Bar.forId(event.getUsedItem().getId()); + Item item = event.getUsedItem(); + if (event.getUsedItem().getId() == HAMMER.getId()) { + for (Item i : player.getInventory().toArray()) { + if (i == null) { + continue; + } + bar = Bar.forId(i.getId()); + if (bar != null) { + item = i; + break; + } + } + } + if (bar == null) { + return true; + } + if (player.getSkills().getLevel(Skills.SMITHING) < bar.getLevel()) { + player.getDialogueInterpreter().sendDialogue("You need a smithing level of at least " + bar.getLevel() + " to work " + bar.getProduct().getName().toLowerCase() + "s."); + return true; + } + final SmithingBuilder builder = new SmithingBuilder(item); + builder.build(player); + } + return true; + } + +} diff --git a/Server/src/main/content/global/handlers/item/withobject/SpiritShieldBlessListener.kt b/Server/src/main/content/global/handlers/item/withobject/SpiritShieldBlessListener.kt new file mode 100644 index 0000000..45b0dad --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withobject/SpiritShieldBlessListener.kt @@ -0,0 +1,125 @@ +package content.global.handlers.item.withobject + +import core.api.* +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items +import org.rs09.consts.Scenery +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.world.repository.Repository.sendNews +import java.util.* + +/** + * Listener for blessing spirit shield and attaching sigils + * @author Byte + */ +@Suppress("unused") +class SpiritShieldBlessListener : InteractionListener { + + companion object { + private const val REQUIRED_PRAYER_LEVEL_TO_BLESS_SHIELD = 85 + private const val REQUIRED_PRAYER_LEVEL_TO_ATTACH_SIGIL = 90 + private const val REQUIRED_SMITHING_LEVEL_TO_ATTACH_SIGIL = 85 + + private val ANIMATION = Animation(898) + + private val COMPONENTS = intArrayOf( + Items.HOLY_ELIXIR_13754, + Items.SPIRIT_SHIELD_13734 + ) + + private val ALTARS = intArrayOf( + Scenery.ALTAR_409, + Scenery.ALTAR_2640, + Scenery.ALTAR_4008, + Scenery.ALTAR_18254, + Scenery.ALTAR_19145, + Scenery.ALTAR_24343, + Scenery.SARADOMIN_ALTAR_26287, + Scenery.ALTAR_27661, + Scenery.ALTAR_34616, + Scenery.ALTAR_36972, + Scenery.ALTAR_39842 + ) + + private val SIGILS_SHIELDS_MAP = mapOf( + Items.ARCANE_SIGIL_13746 to Items.ARCANE_SPIRIT_SHIELD_13738, + Items.DIVINE_SIGIL_13748 to Items.DIVINE_SPIRIT_SHIELD_13740, + Items.ELYSIAN_SIGIL_13750 to Items.ELYSIAN_SPIRIT_SHIELD_13742, + Items.SPECTRAL_SIGIL_13752 to Items.SPECTRAL_SPIRIT_SHIELD_13744 + ) + + private val ANVILS = intArrayOf( + Scenery.ANVIL_2782, + Scenery.ANVIL_2783, + Scenery.ANVIL_4306, + Scenery.ANVIL_6150, + Scenery.ANVIL_22725, + Scenery.LATHE_26817, + Scenery.ANVIL_26822, + Scenery.ANVIL_37622 + ) + } + + override fun defineListeners() { + onUseWith(IntType.SCENERY, COMPONENTS, *ALTARS) { player, _, _ -> + if (!inInventory(player, Items.HOLY_ELIXIR_13754) || !inInventory(player, Items.SPIRIT_SHIELD_13734)) { + sendMessage(player, "You need a holy elixir and an unblessed spirit shield in order to do this.") + return@onUseWith true + } + + if (!hasLevelDyn(player, Skills.PRAYER, REQUIRED_PRAYER_LEVEL_TO_BLESS_SHIELD)) { + sendMessage(player, "You need a Prayer level of $REQUIRED_PRAYER_LEVEL_TO_BLESS_SHIELD in order to bless the shield.") + } + + if (!removeItem(player, Items.HOLY_ELIXIR_13754)) { + return@onUseWith false + } + + if (!removeItem(player, Items.SPIRIT_SHIELD_13734)) { + return@onUseWith false + } + + addItem(player, Items.BLESSED_SPIRIT_SHIELD_13736) + sendMessage(player, "You successfully bless the shield using the holy elixir.") + + return@onUseWith true + } + + onUseWith(IntType.SCENERY, SIGILS_SHIELDS_MAP.keys.toIntArray(), *ANVILS) { player, used, _ -> + if (!inInventory(player, Items.BLESSED_SPIRIT_SHIELD_13736)) { + sendMessage(player, "You need a blessed spirit shield in order to continue.") + return@onUseWith true + } + + if (!hasLevelDyn(player, Skills.PRAYER, REQUIRED_PRAYER_LEVEL_TO_ATTACH_SIGIL) || !hasLevelDyn(player, Skills.SMITHING, REQUIRED_SMITHING_LEVEL_TO_ATTACH_SIGIL)) { + sendMessage(player, "You need a Prayer level of $REQUIRED_PRAYER_LEVEL_TO_ATTACH_SIGIL and a Smithing level of $REQUIRED_SMITHING_LEVEL_TO_ATTACH_SIGIL in order to attach the sigil.") + return@onUseWith true + } + + if (!inInventory(player, Items.HAMMER_2347)) { + sendMessage(player, "You need a hammer in order to do this.") + return@onUseWith true + } + + sendDialogueOptions(player, "Combine the two?", "Yes", "No") + addDialogueAction(player) { _, buttonId -> + when (buttonId) { + 2 -> { + if (removeItem(player, used) && removeItem(player, Items.BLESSED_SPIRIT_SHIELD_13736)) { + val product = Item(SIGILS_SHIELDS_MAP[used.id]!!) + addItem(player, product.id) + animate(player, ANIMATION) + sendItemDialogue(player, product.id, "You successfully attach the " + used.name.lowercase(Locale.getDefault()) + " to the blessed spirit shield.") + sendNews(player.username + " has just made the " + product.name + ".") + } + } + } + } + + return@onUseWith true + } + } +} diff --git a/Server/src/main/content/global/handlers/item/withobject/SwampHoleRopeListener.kt b/Server/src/main/content/global/handlers/item/withobject/SwampHoleRopeListener.kt new file mode 100644 index 0000000..020b50e --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withobject/SwampHoleRopeListener.kt @@ -0,0 +1,33 @@ +package content.global.handlers.item.withobject + +import core.api.* +import org.rs09.consts.Items +import org.rs09.consts.Scenery +import core.game.interaction.IntType +import core.game.interaction.InteractionListener + +/** + * Listener for using rope on Lumbridge swamp hole + * @author Byte + */ +@Suppress("unused") +class SwampHoleRopeListener : InteractionListener { + + override fun defineListeners() { + onUseWith(IntType.SCENERY, Items.ROPE_954, Scenery.DARK_HOLE_5947) { player, used, _ -> + if (player.savedData.globalData.hasTiedLumbridgeRope()) { + sendDialogue(player, "There is already a rope tied to the entrance.") + return@onUseWith true + } + + if (!removeItem(player, used)) { + return@onUseWith false + } + + sendItemDialogue(player, used, "You tie the rope to the top of the entrance and throw it down.") + player.savedData.globalData.setLumbridgeRope(true) + + return@onUseWith true + } + } +} diff --git a/Server/src/main/content/global/handlers/item/withobject/WaterSourceListener.kt b/Server/src/main/content/global/handlers/item/withobject/WaterSourceListener.kt new file mode 100644 index 0000000..59a8e20 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withobject/WaterSourceListener.kt @@ -0,0 +1,158 @@ +package content.global.handlers.item.withobject + +import core.api.* +import core.game.node.entity.player.link.diary.DiaryType +import core.game.system.task.Pulse +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.game.world.map.Location +import org.rs09.consts.Sounds + +/** + * Handles filling most water sources. + * @author Ceikry + */ +class WaterSourceListener : InteractionListener { + // NOTE '9695' should be removed from the array below once the sink object can be used directly, this is a temporary + // solution. + // this is ugly! + private val waterSources = intArrayOf(21355, 16302, 6827, 11661, 24160, 34577, 15936, 15937, 15938, 23920, 35469, 24265, 153, 879, 880, 2864, 6232, 10436, 10437, 10827, 11007, 11759, 21764, 22973, 24161, 24214, 24265, 28662, 30223, 30820, 34579, 36781, 873, 874, 4063, 6151, 8699, 9143, 9684, 9695, 10175, 12279, 12974, 13563, 13564, 14868, 14917, 14918, 15678, 16704, 16705, 20358, 22715, 24112, 24314, 25729, 25929, 26966, 29105, 33458, 34082, 34411, 34496, 34547, 34566, 35762, 36971, 37154, 37155, 878, 884, 3264, 3305, 3359, 4004, 4005, 6097, 6249, 6549, 8747, 8927, 11793, 12201, 12897, 24166, 26945, 31359, 32023, 32024, 34576, 35671, 40063, 13561, 13563, 13559, 12089) + + private val nonWellableMsg = "If I drop my @ down there, I don't think I'm likely to get it back." + private val animation = Animation(832) + + override fun defineListeners() + { + onUseWith(IntType.SCENERY, WaterVessel.getInputs(), *waterSources){ player, used, with -> + val vessel = WaterVessel.forId(used.id) ?: return@onUseWith false + + if(with.name.contains("well", ignoreCase = true) && !vessel.wellable) + { + sendMessage(player, formatMsgText(used.name, nonWellableMsg)) + return@onUseWith true + } + + if(with.id == 9695 && player.location.regionId != 11571) + { + return@onUseWith false + } + + //ugly achievement code, achievement system sux + if(vessel == WaterVessel.BUCKET && with.id == 11661) + { + if(!player.achievementDiaryManager.getDiary(DiaryType.FALADOR).isComplete(0,7)) + player.achievementDiaryManager.getDiary(DiaryType.FALADOR).updateTask(player, 0, 7, true) + } + + player.pulseManager.run(object : Pulse(1){ + override fun pulse(): Boolean { + if(removeItem(player, used.id)) + { + animate(player, animation) + sendMessage(player, formatMsgText(used.name, vessel.fillMsg)) + addItemOrDrop(player, vessel.output) + if(with.name.contains("well", ignoreCase = true)) { + playAudio(player, Sounds.WELL_FILL_2615) + } + else { + playAudio(player, Sounds.TAP_FILL_2609) + } + + } + return !vessel.autofill || amountInInventory(player, used.id) == 0 + } + }) + + return@onUseWith true + } + + // This is needed to make the crafting guild sink work, but technically it's wrong as it is the noticeboard and + // not the sink being used. This is a temporary solution until the sink object can be used directly. + setDest(IntType.SCENERY, intArrayOf(9695), "use") { player, node -> + if (player.location.regionId == 11571){ + return@setDest Location.create(2934, 3280, 0) + } + return@setDest node.location + } + } + + private fun formatMsgText(name: String, template: String): String + { + val sb = StringBuilder() + val templateChars = template.toCharArray() + val nameChars = name.toCharArray() + + for(tc in templateChars) + { + if(tc == '@'){ + for(nc in nameChars) + { + if (nc == '(') break + else sb.append(nc.toLowerCase()) + } + } + else sb.append(tc) + } + + return sb.toString() + } + + internal enum class WaterVessel(val inputs: IntArray, val output: Int, val wellable: Boolean = false, val autofill: Boolean = true, val fillMsg: String = "You fill the @.") + { + BUCKET( + inputs = intArrayOf(Items.BUCKET_1925), + output = Items.BUCKET_OF_WATER_1929, + wellable = true + ), + VIAL( + inputs = intArrayOf(Items.VIAL_229), + output = Items.VIAL_OF_WATER_227, + ), + JUG( + inputs = intArrayOf(Items.JUG_1935), + output = Items.JUG_OF_WATER_1937 + ), + BOWL( + inputs = intArrayOf(Items.BOWL_1923), + output = Items.BOWL_OF_WATER_1921 + ), + WATERING_CAN( + inputs = intArrayOf(Items.WATERING_CAN_5331,Items.WATERING_CAN1_5333, Items.WATERING_CAN2_5334, Items.WATERING_CAN3_5335, Items.WATERING_CAN4_5336, Items.WATERING_CAN5_5337, Items.WATERING_CAN6_5338, Items.WATERING_CAN7_5339), + output = Items.WATERING_CAN8_5340 + ), + WATER_SKIN( + inputs = intArrayOf(Items.WATERSKIN0_1831, Items.WATERSKIN1_1829, Items.WATERSKIN2_1827, Items.WATERSKIN3_1825), + output = Items.WATERSKIN4_1823 + ), + FISHBOWL( + inputs = intArrayOf(Items.FISHBOWL_6667), + output = Items.FISHBOWL_6668 + ); + + companion object + { + //map our input item IDs to their respective WaterVessel entry + private val itemMap = HashMap() + + init { + for(entry in values()) + { + entry.inputs.forEach { itemMap[it] = entry } + } + } + + //return a nice list of all the input IDs + fun getInputs(): IntArray + { + return itemMap.keys.toIntArray() + } + + fun forId(id: Int): WaterVessel? + { + return itemMap[id] + } + } + } +} diff --git a/Server/src/main/content/global/handlers/item/withplayer/ChristmasCrackerUsage.java b/Server/src/main/content/global/handlers/item/withplayer/ChristmasCrackerUsage.java new file mode 100644 index 0000000..de13eb8 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withplayer/ChristmasCrackerUsage.java @@ -0,0 +1,66 @@ +package content.global.handlers.item.withplayer; + +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.tools.RandomFunction; + +/** + * Handles the breaking of a christmas cracker on a player. + * @author Vexia + */ +@Initializable +public final class ChristmasCrackerUsage extends UseWithHandler { + + /** + * The party hat items. + */ + private static final Item[] HATS = new Item[] { new Item(1038), new Item(1040), new Item(1042), new Item(1044), new Item(1046), new Item(1048) }; + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(962, PLAYER_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + Player target = (Player) event.getUsedWith(); + if (target == null || !target.isActive() || target.getLocks().isInteractionLocked() || target.getInterfaceManager().getOpened() != null) { + event.getPlayer().getPacketDispatch().sendMessage("The other player is currently busy."); + return true; + } + if (target.getInventory().freeSlots() == 0) { + event.getPlayer().sendMessage("The other player doesn't have enough inventory space."); + return true; + } + Player player = event.getPlayer(); + if (player.getInventory().remove(event.getUsedItem())) { + player.faceTemporary(target, 2); + player.lock(3); + player.animate(Animation.create(451)); + player.graphics(Graphics.create(176)); + player.sendMessage("You pull a Christmas cracker..."); + boolean winner = RandomFunction.random(2) == 1; + player.sendMessage(winner ? "You get the prize from the cracker." : "The person you pull the cracker with gets the prize."); + if (winner) { + player.sendChat("Hey! I got the cracker!"); + } else { + target.sendChat("Hey! I got the cracker!"); + } + Item hat = RandomFunction.getRandomElement(HATS); + if (winner) { + player.getInventory().add(hat, player); + } else { + target.getInventory().add(hat, target); + } + } + return true; + } + +} diff --git a/Server/src/main/content/global/handlers/item/withplayer/FieldRationUsage.java b/Server/src/main/content/global/handlers/item/withplayer/FieldRationUsage.java new file mode 100644 index 0000000..0271f95 --- /dev/null +++ b/Server/src/main/content/global/handlers/item/withplayer/FieldRationUsage.java @@ -0,0 +1,40 @@ +package content.global.handlers.item.withplayer; + +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Handles using a field ration on a player. + * @author Emperor + */ +@Initializable +public final class FieldRationUsage extends UseWithHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(7934, PLAYER_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + Item item = (Item) event.getUsed(); + Player target = (Player) event.getUsedWith(); + if (target == null || !target.isActive() || target.getLocks().isInteractionLocked()) { + event.getPlayer().getPacketDispatch().sendMessage("The other player is currently busy."); + return true; + } + if (event.getPlayer().getInventory().remove(item)) { + target.getSkills().heal(12); + target.getPacketDispatch().sendMessage("You have been healed by a field ration."); + event.getPlayer().getPacketDispatch().sendMessage("You use the field ration to heal the other player."); + return true; + } + return false; + } + +} diff --git a/Server/src/main/content/global/handlers/npc/BankerNPC.kt b/Server/src/main/content/global/handlers/npc/BankerNPC.kt new file mode 100644 index 0000000..e59ac6b --- /dev/null +++ b/Server/src/main/content/global/handlers/npc/BankerNPC.kt @@ -0,0 +1,171 @@ +package content.global.handlers.npc + +import core.api.* +import core.game.node.Node +import core.game.node.entity.Entity +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.world.map.Direction +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.NPCs +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import content.global.handlers.scenery.BankBoothListener + +/** + * Provides dialogue tree for all generic banker NPCs as well as + * handles all the common interactions like 'bank' and 'collect'. + * + * @author vddCore + */ +@Initializable +class BankerNPC : AbstractNPC, InteractionListener { + companion object { + private const val LUNAR_ISLE_BANK_REGION = 8253 + + val SPECIAL_NPC_IDS = intArrayOf( + NPCs.SIRSAL_BANKER_4519, NPCs.FADLI_958, NPCs.BANK_TUTOR_4907, NPCs.JADE_4296, + NPCs.OGRESS_BANKER_7049, NPCs.OGRESS_BANKER_7050, NPCs.ARNOLD_LYDSPOR_3824, + + /* Maximillian Sackville - Near Wilderness bounty-hunter area. */ + NPCs.BANKER_6538 + ) + + val NPC_IDS = intArrayOf( + NPCs.BANKER_44, NPCs.BANKER_45, NPCs.BANKER_494, NPCs.BANKER_495, NPCs.BANKER_496, NPCs.BANKER_497, + NPCs.BANKER_498, NPCs.BANKER_499, NPCs.BANKER_1036, NPCs.BANKER_1360, NPCs.BANKER_2163, NPCs.BANKER_2164, + NPCs.BANKER_2354, NPCs.BANKER_2355, NPCs.BANKER_2568, NPCs.BANKER_2569, NPCs.BANKER_2570, NPCs.BANKER_3198, + NPCs.BANKER_3199, NPCs.BANKER_5258, NPCs.BANKER_5259, NPCs.BANKER_5260, NPCs.BANKER_5261, NPCs.BANKER_5776, + NPCs.BANKER_5777, NPCs.BANKER_5912, NPCs.BANKER_5913, NPCs.BANKER_6200, NPCs.BANKER_6532, NPCs.BANKER_6533, + NPCs.BANKER_6534, NPCs.BANKER_6535, NPCs.BANKER_7445, NPCs.BANKER_7446, NPCs.BANKER_7605, + NPCs.GUNDAI_902, + + NPCs.GHOST_BANKER_1702, NPCs.GNOME_BANKER_166, NPCs.NARDAH_BANKER_3046, NPCs.MAGNUS_GRAM_5488, NPCs.TZHAAR_KET_ZUH_2619, + ) + + private val ALL_BANKER_NPC_IDS = intArrayOf( + *SPECIAL_NPC_IDS, + *NPC_IDS + ) + + /** + * This is poorly named, but performs a few checks to see if the player + * is trying to access the bank on the Lunar Isle and returns a boolean + * controlling whether or not to pass the quick bank or collection use. + * + * TODO + * The location of this method is shit too. Find a better place for it? + */ + fun checkLunarIsleRestriction(player: Player, node: Node): Boolean { + if (node.location.regionId != LUNAR_ISLE_BANK_REGION) + return false + + if (!hasSealOfPassage(player)) { + return true + } + + return false + } + + fun attemptBank(player: Player, node: Node): Boolean { + val npc = node as NPC + + if (checkLunarIsleRestriction(player, node)) { + openDialogue(player, npc.id, npc) + return true + } + + npc.faceLocation(null) + openBankAccount(player) + + return true + } + + fun attemptCollect(player: Player, node: Node): Boolean { + val npc = node as NPC + + if (checkLunarIsleRestriction(player, node)) { + openDialogue(player, npc.id, npc) + return true + } + + npc.faceLocation(null) + openGrandExchangeCollectionBox(player) + + return true + } + } + + //Constructor spaghetti because Arios I guess + constructor() : super(0, null) + private constructor(id: Int, location: Location) : super(id, location) + + override fun construct(id: Int, location: Location, vararg objects: Any?): AbstractNPC { + return BankerNPC(id, location) + } + + private fun findAdjacentBankBoothLocation(): Pair? { + for (side in arrayOf(Direction.SOUTH, Direction.WEST, Direction.NORTH, Direction.EAST)) { + val boothLocation = location.transform(side) + val sceneryObject = getScenery(boothLocation) + + if (sceneryObject != null && sceneryObject.id in BankBoothListener.BANK_BOOTHS) { + return Pair(side, boothLocation.transform(side, 1)) + } + } + + return null + } + + private fun provideDestinationOverride(entity: Entity, node: Node): Location { + val npc = node as NPC + + return when(npc.id) { + /* Ogress bankers are 2x2 with their spawn being offset to south-western tile. */ + NPCs.OGRESS_BANKER_7049, + NPCs.OGRESS_BANKER_7050 -> npc.location.transform(3, 1, 0) + + NPCs.BANKER_6532, NPCs.BANKER_6533, + NPCs.BANKER_6534, NPCs.BANKER_6535 -> npc.location.transform(npc.direction, 1) + + /* Magnus has no bank booth nearby so we need to handle that edge case here. */ + NPCs.MAGNUS_GRAM_5488 -> npc.location.transform(Direction.NORTH, 2) + + else -> { + if (npc is BankerNPC) { + npc.findAdjacentBankBoothLocation()?.let { + return it.second + } + } + + return npc.location + } + } + } + + override fun defineListeners() { + on(ALL_BANKER_NPC_IDS, IntType.NPC, "bank", handler = Companion::attemptBank) + on(ALL_BANKER_NPC_IDS, IntType.NPC, "collect", handler = Companion::attemptCollect) + } + + override fun defineDestinationOverrides() { + setDest(IntType.NPC, ALL_BANKER_NPC_IDS, "bank", "collect", "talk-to", handler = ::provideDestinationOverride) + } + + override fun init() { + super.init() + + findAdjacentBankBoothLocation()?.let { + val (boothDirection, _) = it + + direction = boothDirection + isWalks = false + + setAttribute("facing_booth", true) + } + } + + override fun getIds(): IntArray = ALL_BANKER_NPC_IDS +} diff --git a/Server/src/main/content/global/handlers/npc/ChromaticDragonBehavior.kt b/Server/src/main/content/global/handlers/npc/ChromaticDragonBehavior.kt new file mode 100644 index 0000000..57c0fda --- /dev/null +++ b/Server/src/main/content/global/handlers/npc/ChromaticDragonBehavior.kt @@ -0,0 +1,43 @@ +package content.global.handlers.npc + +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.tools.RandomFunction +import org.rs09.consts.* +import kotlin.collections.ArrayList + +class ChromaticDragonBehavior : NPCBehavior(*greenDragons, *blueDragons, *redDragons, *blackDragons) +{ + override fun onDropTableRolled (self: NPC, killer: Entity, drops: ArrayList) { + val removeList = ArrayList() + for (item in drops) { + when (item.id) { + Items.BLACK_DRAGON_EGG_12480, + Items.RED_DRAGON_EGG_12477, + Items.BLUE_DRAGON_EGG_12478, + Items.GREEN_DRAGON_EGG_12479 -> removeList.add(item) + } + } + drops.removeAll(removeList) + + if (killer.skills.getStaticLevel(Skills.SUMMONING) >= 99 && RandomFunction.roll(EGG_RATE)) + drops.add(when(self.id) { + in greenDragons -> Item(Items.GREEN_DRAGON_EGG_12479) + in blueDragons -> Item(Items.BLUE_DRAGON_EGG_12478) + in redDragons -> Item(Items.RED_DRAGON_EGG_12477) + in blackDragons -> Item(Items.BLACK_DRAGON_EGG_12480) + else -> Item(Items.DRAGON_BONES_536) + }) + } + + companion object { + val greenDragons = intArrayOf (NPCs.GREEN_DRAGON_941, NPCs.GREEN_DRAGON_4677, NPCs.GREEN_DRAGON_4678, NPCs.GREEN_DRAGON_4679, NPCs.GREEN_DRAGON_4680) + val blueDragons = intArrayOf (NPCs.BLUE_DRAGON_55, NPCs.BLUE_DRAGON_4681, NPCs.BLUE_DRAGON_4682, NPCs.BLUE_DRAGON_4683, NPCs.BLUE_DRAGON_4684) + val redDragons = intArrayOf (NPCs.RED_DRAGON_53, NPCs.RED_DRAGON_4669, NPCs.RED_DRAGON_4670, NPCs.RED_DRAGON_4671, NPCs.RED_DRAGON_4672) + val blackDragons = intArrayOf (NPCs.BLACK_DRAGON_54, NPCs.BLACK_DRAGON_4673, NPCs.BLACK_DRAGON_4674, NPCs.BLACK_DRAGON_4675, NPCs.BLACK_DRAGON_4676) + var EGG_RATE = 1000 + } +} diff --git a/Server/src/main/content/global/handlers/npc/ChromaticDragonNPC.java b/Server/src/main/content/global/handlers/npc/ChromaticDragonNPC.java new file mode 100644 index 0000000..66121a2 --- /dev/null +++ b/Server/src/main/content/global/handlers/npc/ChromaticDragonNPC.java @@ -0,0 +1,73 @@ +package content.global.handlers.npc; + +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.equipment.SwitchAttack; +import content.global.handlers.item.equipment.special.DragonfireSwingHandler; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.npc.AbstractNPC; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.node.entity.combat.MultiSwingHandler; + +/** + * Handles a chromatic dragon (green, blue, red, ..). + * @author Emperor + */ +@Initializable +public final class ChromaticDragonNPC extends AbstractNPC { + + /** + * The dragonfire attack. + */ + private static final SwitchAttack DRAGONFIRE = DragonfireSwingHandler.get(true, 52, new Animation(81, Priority.HIGH), new Graphics(1, 64), null, null); + + /** + * Handles the combat. + */ + private final CombatSwingHandler combatAction = new MultiSwingHandler(false, new SwitchAttack(CombatStyle.MELEE.getSwingHandler(), new Animation(80, Priority.HIGH)), new SwitchAttack(CombatStyle.MELEE.getSwingHandler(), new Animation(91, Priority.HIGH)), DRAGONFIRE); + + /** + * Constructs a new {@code ChromaticDragonNPC} {@code Object}. + */ + public ChromaticDragonNPC() { + super(941, null); + } + + /** + * Constructs a new {@code ChromaticDragonNPC} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + public ChromaticDragonNPC(int id, Location location) { + super(id, location); + } + + @Override + public CombatSwingHandler getSwingHandler(boolean swing) { + return combatAction; + } + + @Override + public int getDragonfireProtection(boolean fire) { + return 0x2 | 0x4 | 0x8; + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new ChromaticDragonNPC(id, location); + } + + @Override + public int[] getIds() { + return new int[] { 941, 4677, 4678, 4679, 4680, // Green dragon + 55, 4681, 4682, 4683, 4684, // Blue dragon + 53, 4669, 4670, 4671, 4672, // Red dragon + 54, 4673, 4674, 4675, 4676, // Black dragon + 8629 //lava dragon + }; + } + +} diff --git a/Server/src/main/content/global/handlers/npc/CowMilkingPlugin.java b/Server/src/main/content/global/handlers/npc/CowMilkingPlugin.java new file mode 100644 index 0000000..833fea4 --- /dev/null +++ b/Server/src/main/content/global/handlers/npc/CowMilkingPlugin.java @@ -0,0 +1,123 @@ +package content.global.handlers.npc; + +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.OptionHandler; +import core.game.interaction.UseWithHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.system.task.Pulse; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; +import core.plugin.Initializable; +import core.plugin.ClassScanner; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.*; + +/** + * Represents the plugin used to milk a cow. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class CowMilkingPlugin extends OptionHandler { + + /** + * Represents the animation to use; + */ + private static final Animation ANIMATION = new Animation(2305); + + /** + * Represents the items related to cow milking plugin. + */ + private static final Item[] ITEMS = new Item[] { new Item(1925, 1), new Item(3727, 1), new Item(1927, 1) }; + + @Override + public boolean handle(final Player player, Node node, String option) { + if (option.equalsIgnoreCase("steal-cowbell")) { + player.getDialogueInterpreter().open(70099, "You need to have started the Cold War quest to attempt this."); + return true; + } + milk(player, (Scenery) node); + return true; + } + + /** + * Milks a cow. + * @param player the player. + * @param object the object. + * @return {@code True} if milked. + */ + public boolean milk(final Player player, final Scenery object) { + if (!player.getInventory().contains(1925, 1) && !player.getInventory().contains(3727, 1)) { + player.getDialogueInterpreter().open(3807, true, true); + return true; + } + + player.animate(ANIMATION); + playAudio(player, Sounds.MILK_COW_372); + player.getPulseManager().run(new Pulse(8, player) { + @Override + public boolean pulse() { + if (player.getInventory().remove(ITEMS[0]) || player.getInventory().remove(ITEMS[1])) { + player.getInventory().add(ITEMS[2]); + player.getPacketDispatch().sendMessage("You milk the cow."); + } + if (player.getInventory().contains(1925, 1) || player.getInventory().contains(3727, 1)) { + player.animate(ANIMATION); + playAudio(player, Sounds.MILK_COW_372); + return false; + } + return true; + } + + @Override + public void stop() { + super.stop(); + player.animate(new Animation(-1)); + } + }); + return true; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(8689).getHandlers().put("option:milk", this); + SceneryDefinition.forId(12111).getHandlers().put("option:milk", this); + SceneryDefinition.setOptionHandler("steal-cowbell", this); + ClassScanner.definePlugin(new BucketHandler()); + return this; + } + + /** + * The use with handler for buckets. + * @author Vexia + */ + public class BucketHandler extends UseWithHandler { + + /** + * Constructs a new {@code BucketHandler} {@code Object} + */ + public BucketHandler() { + super(1925); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(8689, OBJECT_TYPE, this); + addHandler(12111, OBJECT_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + milk(event.getPlayer(), (Scenery) event.getUsedWith()); + return true; + } + + } + +} diff --git a/Server/src/main/content/global/handlers/npc/CowNPC.java b/Server/src/main/content/global/handlers/npc/CowNPC.java new file mode 100644 index 0000000..9538395 --- /dev/null +++ b/Server/src/main/content/global/handlers/npc/CowNPC.java @@ -0,0 +1,55 @@ +package content.global.handlers.npc; + +import core.game.node.entity.npc.AbstractNPC; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.tools.RandomFunction; + +/** + * Represents the a cow npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class CowNPC extends AbstractNPC { + + /** + * Represents the force chat to use. + */ + private static final String FORCE_CHAT = "Moo"; + + /** + * Constructs a new {@code CowNPC} {@code Object}. + */ + public CowNPC() { + super(0, null, true); + } + + /** + * Constructs a new {@code CowNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + public CowNPC(int id, Location location) { + super(id, location, true); + } + + @Override + public void tick() { + if (RandomFunction.random(45) == 5 && this.getId() != 1766) { // calves don't moo + sendChat(FORCE_CHAT); + } + super.tick(); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new CowNPC(id, location); + } + + @Override + public int[] getIds() { + return new int[] { 81, 397, 955, 1766, 1767, 3309 }; + } + +} diff --git a/Server/src/main/content/global/handlers/npc/DarkWizardNPC.java b/Server/src/main/content/global/handlers/npc/DarkWizardNPC.java new file mode 100644 index 0000000..3124d80 --- /dev/null +++ b/Server/src/main/content/global/handlers/npc/DarkWizardNPC.java @@ -0,0 +1,109 @@ +package content.global.handlers.npc; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.spell.CombatSpell; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.tools.RandomFunction; + +/** + * Represents the abstract representation of a dark wizard. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class DarkWizardNPC extends AbstractNPC { + + /** + * Represents the NPC ids of NPCs using this plugin. + */ + private static final int[] ID = { 172, 174 }; + + /** + * Represents the spells to set. + */ + private static final int[][] SPELLS = new int[][] { { 6, 7 }, { 4, 2 } }; + + /** + * Constructs a new {@code DarkWizardNPC} {@code Object}. + */ + public DarkWizardNPC() { + super(0, null); + setAggressive(true); + } + + /** + * Constructs a new {@code DarkWizardNPC} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + private DarkWizardNPC(int id, Location location) { + super(id, location); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new DarkWizardNPC(id, location); + } + + @Override + public void init() { + super.init(); + getProperties().getCombatPulse().setStyle(CombatStyle.MAGIC); + setDefault(); + } + + @Override + public void onImpact(final Entity entity, BattleState state) { + super.onImpact(entity, state); + if (getAttribute("switched", false)) { + removeAttribute("switched"); + setDefault(); + return; + } + if (RandomFunction.random(6) > 4) { + setSpells(getSpells()); + setAttribute("switched", true); + } + } + + /** + * Sets the default spell. + */ + private void setDefault() { + getProperties().setAutocastSpell((CombatSpell) SpellBook.MODERN.getSpell(getId() == 172 ? 6 : 4)); + } + + /** + * Sets random spells. + * @param ids the ids. + */ + private void setSpells(int[] ids) { + getProperties().setAutocastSpell((CombatSpell) SpellBook.MODERN.getSpell(ids[RandomFunction.random(ids.length)])); + } + + /** + * Gets the spells. + * @return the spells. + */ + private int[] getSpells() { + int index = 0; + for (int i = 0; i < ID.length; i++) { + if (ID[i] == getId()) { + index = i; + break; + } + } + return SPELLS[index]; + } + + @Override + public int[] getIds() { + return ID; + } + +} diff --git a/Server/src/main/content/global/handlers/npc/DecantListener.kt b/Server/src/main/content/global/handlers/npc/DecantListener.kt new file mode 100644 index 0000000..9a63c78 --- /dev/null +++ b/Server/src/main/content/global/handlers/npc/DecantListener.kt @@ -0,0 +1,96 @@ +package content.global.handlers.npc + +import content.data.consumables.Consumables +import core.api.* +import core.game.consumable.Potion +import core.game.dialogue.DialogueFile +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.item.Item +import core.tools.END_DIALOGUE +import org.rs09.consts.Items + +class DecantListener : InteractionListener { + + companion object { + val potions = Consumables.potions.toIntArray() + } + + override fun defineListeners() { + on(IntType.NPC,"decant"){ player, node -> + val (toRemove, toAdd) = decantContainer(player.inventory) + for (item in toRemove) + removeItem(player, item) + for (item in toAdd) + addItem(player, item.id, item.amount) + player.dialogueInterpreter.open(DecantingDialogue(),node.asNpc()) + return@on true + } + + onUseWith(IntType.ITEM, potions, *potions) { player, used, with -> + if (used !is Item) return@onUseWith false + if (with !is Item) return@onUseWith false + + // Verify these are both the same potion types + val potionUsed = Consumables.getConsumableById(used.id)?.consumable as? Potion ?: return@onUseWith false + val potionWith = Consumables.getConsumableById(with.id)?.consumable as? Potion ?: return@onUseWith false + + if (potionUsed != potionWith) { + return@onUseWith false + } + + // Dosage math + val usedDose = potionUsed.getDose(used) + val withDose = potionWith.getDose(with) + + // Shouldn't be able to combine a 4 dose potion + if (usedDose == 4 || withDose == 4) { + return@onUseWith false + } + + val totalDosage = usedDose + withDose + val fullDoses = totalDosage / 4 + val leftoverDose = totalDosage % 4 + + // Replace the targeted potion item with a (4) dose potion + if (fullDoses != 0) { + replaceSlot(player, with.slot, Item(potionWith.ids.first()), with, Container.INVENTORY) + } + + // Replace the targeted potion item with the updated dosage amount + if (leftoverDose != 0 && fullDoses == 0) { + replaceSlot(player, with.slot, Item(potionUsed.ids[potionUsed.ids.size - totalDosage]), with, Container.INVENTORY) + + // Replace the used with potion item with the updated dosage amount + } else if (leftoverDose != 0) { + replaceSlot(player, used.slot, Item(potionUsed.ids[potionUsed.ids.size - leftoverDose]), used, Container.INVENTORY) + } + + // Replace the used with potion item with an empty vial + if (leftoverDose == 0 || fullDoses == 0) { + replaceSlot(player, used.slot, Item(Items.VIAL_229), used, Container.INVENTORY) + } + + // Send message/Play sound + val amountString = when { + totalDosage >= 4 -> "four" + totalDosage == 3 -> "three" + else -> "two" + } + + sendMessage(player, "You have combined the liquid into $amountString doses.") + playAudio(player, 2401) + + return@onUseWith true + } + } + + internal class DecantingDialogue : DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + when(stage++){ + 0 -> npc("There you go!") + 1 -> player("Thanks!").also { stage = END_DIALOGUE } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/npc/DuckNPC.java b/Server/src/main/content/global/handlers/npc/DuckNPC.java new file mode 100644 index 0000000..40bdd45 --- /dev/null +++ b/Server/src/main/content/global/handlers/npc/DuckNPC.java @@ -0,0 +1,55 @@ +package content.global.handlers.npc; + +import core.game.node.entity.npc.AbstractNPC; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.tools.RandomFunction; + +/** + * Represents the a duck npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class DuckNPC extends AbstractNPC { + + /** + * Represents the force chat to use. + */ + private static final String FORCE_CHAT = "Quack!"; + + /** + * Constructs a new {@code DuckNPC} {@code Object}. + */ + public DuckNPC() { + super(0, null); + } + + /** + * Constructs a new {@code DuckNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + public DuckNPC(int id, Location location) { + super(id, location, true); + } + + @Override + public void tick() { + if (RandomFunction.random(45) == 5) { + sendChat(FORCE_CHAT); + } + super.tick(); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new DuckNPC(id, location); + } + + @Override + public int[] getIds() { + return new int[] { 46, 2693, 6113 }; + } + +} diff --git a/Server/src/main/content/global/handlers/npc/DummyAttackPlugin.java b/Server/src/main/content/global/handlers/npc/DummyAttackPlugin.java new file mode 100644 index 0000000..8faf7ea --- /dev/null +++ b/Server/src/main/content/global/handlers/npc/DummyAttackPlugin.java @@ -0,0 +1,69 @@ +package content.global.handlers.npc; + +import core.cache.def.impl.SceneryDefinition; +import core.game.node.entity.skill.Skills; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the dummy attack plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class DummyAttackPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(2038).getHandlers().put("option:attack", this); + SceneryDefinition.forId(15624).getHandlers().put("option:attack", this); + SceneryDefinition.forId(15625).getHandlers().put("option:attack", this); + SceneryDefinition.forId(15626).getHandlers().put("option:attack", this); + SceneryDefinition.forId(15627).getHandlers().put("option:attack", this); + SceneryDefinition.forId(15628).getHandlers().put("option:attack", this); + SceneryDefinition.forId(15629).getHandlers().put("option:attack", this); + SceneryDefinition.forId(15630).getHandlers().put("option:attack", this); + SceneryDefinition.forId(18238).getHandlers().put("option:attack", this); + SceneryDefinition.forId(25648).getHandlers().put("option:attack", this); + SceneryDefinition.forId(28912).getHandlers().put("option:attack", this); + SceneryDefinition.forId(823).getHandlers().put("option:attack", this); + SceneryDefinition.forId(23921).getHandlers().put("option:attack", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + player.lock(3); + player.animate(player.getProperties().getAttackAnimation()); + if (player.getProperties().getCurrentCombatLevel() < 8) { + final Player p = player; + double experience = 5; + switch (p.getProperties().getAttackStyle().getStyle()) { + case WeaponInterface.STYLE_ACCURATE: + p.getSkills().addExperience(Skills.ATTACK, experience); + break; + case WeaponInterface.STYLE_AGGRESSIVE:// strength. + p.getSkills().addExperience(Skills.STRENGTH, experience); + break; + case WeaponInterface.STYLE_DEFENSIVE:// defence. + p.getSkills().addExperience(Skills.DEFENCE, experience); + break; + case WeaponInterface.STYLE_CONTROLLED:// shared. + experience /= 3; + p.getSkills().addExperience(Skills.ATTACK, experience); + p.getSkills().addExperience(Skills.STRENGTH, experience); + p.getSkills().addExperience(Skills.DEFENCE, experience); + break; + } + } else { + player.getPacketDispatch().sendMessage("You swing at the dummy..."); + player.getPacketDispatch().sendMessage("There is nothing more you can learn from hitting a dummy."); + } + return true; + } + +} diff --git a/Server/src/main/content/global/handlers/npc/GuardNPC.java b/Server/src/main/content/global/handlers/npc/GuardNPC.java new file mode 100644 index 0000000..ccdf7e1 --- /dev/null +++ b/Server/src/main/content/global/handlers/npc/GuardNPC.java @@ -0,0 +1,48 @@ +package content.global.handlers.npc; + +import core.game.node.entity.npc.AbstractNPC; +import core.plugin.Initializable; +import core.game.world.map.Location; + +/** + * Represents the abstract knight npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class GuardNPC extends AbstractNPC { + + /** + * The NPC ids of NPCs using this plugin. + */ + private static final int[] ID = { 9, 32, 163, 164, 196, 197, 206, 253, 254, 255, 256, 274, 275, 296, 298, 299, 447, 448, 449, 489, 609, 678, 799, 837, 842, 862, 870, 877, 917, 1200, 1203, 1204, 1317, 1710, 1711, 1712, 2073, 2074, 2134, 2135, 2136, 2236, 2571, 2699, 2700, 2701, 2702, 2703, 3228, 3229, 3230, 3231, 3232, 3233, 3241, 3407, 3408, 3715, 4257, 4258, 4259, 4260, 4307, 4308, 4309, 4310, 4311, 4336, 4375, 4603, 4604, 4605, 4606, 5800, 5801, 5919, 5920 }; + + /** + * Constructs a new {@code GuardNPC} {@code Object}. + */ + public GuardNPC() { + super(0, null, true); + this.setAggressive(false); + } + + /** + * Constructs a new {@code GuardNPC} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + private GuardNPC(int id, Location location) { + super(id, location, true); + this.setAggressive(false); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new GuardNPC(id, location); + } + + @Override + public int[] getIds() { + return ID; + } + +} diff --git a/Server/src/main/content/global/handlers/npc/HairCutPlugin.java b/Server/src/main/content/global/handlers/npc/HairCutPlugin.java new file mode 100644 index 0000000..a455e54 --- /dev/null +++ b/Server/src/main/content/global/handlers/npc/HairCutPlugin.java @@ -0,0 +1,31 @@ +package content.global.handlers.npc; + +import core.cache.def.impl.NPCDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the plugin used for the hairdresser. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class HairCutPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + NPCDefinition.forId(598).getHandlers().put("option:hair-cut", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + player.getDialogueInterpreter().open(598, ((NPC) node), true); + return true; + } + +} diff --git a/Server/src/main/content/global/handlers/npc/HighwayManNPC.java b/Server/src/main/content/global/handlers/npc/HighwayManNPC.java new file mode 100644 index 0000000..cc5157b --- /dev/null +++ b/Server/src/main/content/global/handlers/npc/HighwayManNPC.java @@ -0,0 +1,62 @@ +package content.global.handlers.npc; + +import core.game.node.entity.Entity; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.plugin.Initializable; +import core.game.world.map.Location; + +/** + * Represents the highway man npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class HighwayManNPC extends AbstractNPC { + + /** + * Constructs a new {@code HighwayManNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + public HighwayManNPC(int id, Location location) { + super(id, location); + } + + /** + * Constructs a new {@code HighwayManNPC} {@code Object}. + */ + public HighwayManNPC() { + super(0, null); + } + + @Override + public void finalizeDeath(Entity killer) { + super.finalizeDeath(killer); + if (getId() == 180) { + if (killer instanceof Player) { + final Player player = killer.asPlayer(); + if (!player.getAchievementDiaryManager().getDiary(DiaryType.FALADOR).isComplete(0, 10)) { + player.getAchievementDiaryManager().getDiary(DiaryType.FALADOR).updateTask(player, 0, 10, true); + } + } + } + } + + @Override + public void onAttack(Entity target) { + sendChat("Stand and deliver!"); + } + + @Override + public int[] getIds() { + return new int[] { 180, 2677 }; + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new HighwayManNPC(id, location); + } + +} diff --git a/Server/src/main/content/global/handlers/npc/IceGiantNPC.java b/Server/src/main/content/global/handlers/npc/IceGiantNPC.java new file mode 100644 index 0000000..999bf00 --- /dev/null +++ b/Server/src/main/content/global/handlers/npc/IceGiantNPC.java @@ -0,0 +1,54 @@ +package content.global.handlers.npc; + +import core.game.node.entity.Entity; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.world.map.Location; +import core.plugin.Initializable; + +/** + * Represents the a duck npc. + * @author afaroutdude + */ +@Initializable +public final class IceGiantNPC extends AbstractNPC { + + /** + * Constructs a new {@code IceGiantNPC} {@code Object}. + */ + public IceGiantNPC() { + super(0, null); + } + + /** + * Constructs a new {@code IceGiantNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + public IceGiantNPC(int id, Location location) { + super(id, location, true); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new IceGiantNPC(id, location); + } + + @Override + public void finalizeDeath(final Entity killer) { + super.finalizeDeath(killer); + if (killer instanceof Player) { + final Player player = killer.asPlayer(); + if (this.getLocation().withinDistance(new Location(3052, 9573, 0), 100) && !player.getAchievementDiaryManager().getDiary(DiaryType.FALADOR).isComplete(1, 4)) { + player.getAchievementDiaryManager().getDiary(DiaryType.FALADOR).updateTask(player, 1, 4, true); + } + } + } + + @Override + public int[] getIds() { + return new int[] { 111, 3072, 4685, 4686, 4687 }; + } + +} diff --git a/Server/src/main/content/global/handlers/npc/MetalDragonNPC.java b/Server/src/main/content/global/handlers/npc/MetalDragonNPC.java new file mode 100644 index 0000000..6884829 --- /dev/null +++ b/Server/src/main/content/global/handlers/npc/MetalDragonNPC.java @@ -0,0 +1,73 @@ +package content.global.handlers.npc; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.equipment.SwitchAttack; +import content.global.handlers.item.equipment.special.DragonfireSwingHandler; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.npc.AbstractNPC; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.node.entity.combat.MultiSwingHandler; + +/** + * Handles a metal dragon (bronze, iron, steel). + * @author Emperor + */ +@Initializable +public final class MetalDragonNPC extends AbstractNPC { + + /** + * The dragonfire attack. + */ + private static final SwitchAttack DRAGONFIRE = DragonfireSwingHandler.get(false, 52, new Animation(81, Priority.HIGH), null, null, Projectile.create((Entity) null, null, 54, 40, 36, 41, 46, 20, 255)); + + /** + * Handles the combat. + */ + private final CombatSwingHandler combatAction = new MultiSwingHandler(true, new SwitchAttack(CombatStyle.MELEE.getSwingHandler(), new Animation(80, Priority.HIGH)), new SwitchAttack(CombatStyle.MELEE.getSwingHandler(), new Animation(91, Priority.HIGH)), DRAGONFIRE); + + /** + * Constructs a new {@code MetalDragonNPC} {@code Object}. + */ + public MetalDragonNPC() { + super(1590, null); + } + + /** + * Constructs a new {@code MetalDragonNPC} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + public MetalDragonNPC(int id, Location location) { + super(id, location); + } + + @Override + public CombatSwingHandler getSwingHandler(boolean swing) { + return combatAction; + } + + @Override + public int getDragonfireProtection(boolean fire) { + return 0x2 | 0x4 | 0x8; + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new MetalDragonNPC(id, location); + } + + @Override + public int[] getIds() { + return new int[] { 1590, // Bronze dragon + 1591, // Iron dragon + 1592, // Steel dragon + 3590 // Steel dragon (POH) + }; + } + +} diff --git a/Server/src/main/content/global/handlers/npc/MonkNPC.java b/Server/src/main/content/global/handlers/npc/MonkNPC.java new file mode 100644 index 0000000..0daf3ac --- /dev/null +++ b/Server/src/main/content/global/handlers/npc/MonkNPC.java @@ -0,0 +1,74 @@ +package content.global.handlers.npc; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.node.entity.combat.MeleeSwingHandler; +import core.game.node.entity.npc.AbstractNPC; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.tools.RandomFunction; + +/** + * Handles a monk NPC. + * @author Emperor + */ +@Initializable +public final class MonkNPC extends AbstractNPC { + + /** + * The monk's combat reward. + */ + private static final CombatAction COMBAT = new CombatAction(); + + /** + * Constructs a new {@code MonkNPC} {@code Object}. + */ + public MonkNPC() { + this(7727, null); + } + + /** + * Constructs a new {@code MonkNPC} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + public MonkNPC(int id, Location location) { + super(id, location); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new MonkNPC(id, location); + } + + @Override + public CombatSwingHandler getSwingHandler(boolean swing) { + return COMBAT; + } + + @Override + public int[] getIds() { + return new int[] { 7727 }; + } + + /** + * Handles the combat reward. + * @author Emperor + */ + private static class CombatAction extends MeleeSwingHandler { + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + if (entity.getSkills().getLifepoints() != entity.getSkills().getMaximumLifepoints() && RandomFunction.randomize(10) < 2) { + entity.animate(Animation.create(709)); + entity.getSkills().heal(2); + entity.getProperties().getCombatPulse().setNextAttack(4); + return -1; + } + return super.swing(entity, victim, state); + } + } + +} diff --git a/Server/src/main/content/global/handlers/npc/NPCDepositListener.kt b/Server/src/main/content/global/handlers/npc/NPCDepositListener.kt new file mode 100644 index 0000000..31a928d --- /dev/null +++ b/Server/src/main/content/global/handlers/npc/NPCDepositListener.kt @@ -0,0 +1,28 @@ +package content.global.handlers.npc + +import core.api.anyInEquipment +import core.api.openDepositBox +import core.api.sendNPCDialogue +import core.api.setInterfaceText +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.tools.END_DIALOGUE + +class NPCDepositListener : InteractionListener { + + override fun defineListeners() { + on(NPCs.PEER_THE_SEER_1288, IntType.NPC, "deposit") { player, _ -> + if (anyInEquipment(player, Items.FREMENNIK_SEA_BOOTS_1_14571, Items.FREMENNIK_SEA_BOOTS_2_14572, Items.FREMENNIK_SEA_BOOTS_3_14573)) { + openDepositBox(player) + setInterfaceText(player, "Peer the Seer's Deposits", 11, 12) + } else { + sendNPCDialogue(player, NPCs.PEER_THE_SEER_1288, + "Do not pester me, outerlander! I will only deposit items into the banks of those who have earned Fremennik sea boots!", + core.game.dialogue.FacialExpression.ANNOYED).also { END_DIALOGUE } + } + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/npc/NPCDisturbPlugin.java b/Server/src/main/content/global/handlers/npc/NPCDisturbPlugin.java new file mode 100644 index 0000000..1810892 --- /dev/null +++ b/Server/src/main/content/global/handlers/npc/NPCDisturbPlugin.java @@ -0,0 +1,51 @@ +package content.global.handlers.npc; + +import core.cache.def.impl.NPCDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.npc.IdleAbstractNPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Handles the disturb option. + * @author Emperor + * + */ +@Initializable +public final class NPCDisturbPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + NPCDefinition.setOptionHandler("disturb", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + if (node instanceof IdleAbstractNPC) { + IdleAbstractNPC npc = (IdleAbstractNPC) node; + if (npc.canDisturb(player)) { + npc.disturb(player); + } + return true; + } + return false; + } + + @Override + public boolean isWalk(final Player player, final Node node) { + if (node instanceof IdleAbstractNPC) { + IdleAbstractNPC npc = (IdleAbstractNPC) node; + return !npc.inDisturbingRange(player); + } + return false; + } + + @Override + public boolean isWalk() { + return false; + } + +} diff --git a/Server/src/main/content/global/handlers/npc/NPCTalkListener.kt b/Server/src/main/content/global/handlers/npc/NPCTalkListener.kt new file mode 100644 index 0000000..5235fc8 --- /dev/null +++ b/Server/src/main/content/global/handlers/npc/NPCTalkListener.kt @@ -0,0 +1,82 @@ +package content.global.handlers.npc + +import core.api.sendMessage +import content.region.kandarin.barcrawl.BarcrawlManager +import content.region.kandarin.barcrawl.BarcrawlType +import content.global.ame.RandomEvents +import content.minigame.gnomecooking.* +import core.api.getAttribute +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.game.system.timer.impl.AntiMacro +import core.game.worldevents.holiday.HolidayRandomEventNPC +import core.game.worldevents.holiday.HolidayRandomEvents +import core.game.worldevents.holiday.HolidayRandoms + +/** + * Handles the NPC talk-to option. + * @author Ceikry + */ +class NPCTalkListener : InteractionListener { + + val barCrawlNPCs = intArrayOf(733,848,735,739,737,738,731,568,3217,736,734) + + override fun defineListeners() { + on(barCrawlNPCs, IntType.NPC, "talk-to", "talk"){ player, node -> + val type = BarcrawlType.forId(node.id) + val instance = BarcrawlManager.getInstance(player) + if (instance.isFinished || !instance.isStarted || instance.isCompleted(type!!.ordinal)) { + player.dialogueInterpreter.open(node.id, node) + } else { + player.dialogueInterpreter.open("barcrawl dialogue", node.id, type) + } + return@on true + } + + on(IntType.NPC,"talk-to","talk","talk to"){ player, node -> + val npc = node.asNpc() + if(RandomEvents.randomIDs.contains(node.id)){ + if(AntiMacro.getEventNpc(player) == null || AntiMacro.getEventNpc(player) != node.asNpc() || AntiMacro.getEventNpc(player)?.finalized == true) { + player.sendMessage("They aren't interested in talking to you.") + } else { + AntiMacro.getEventNpc(player)?.talkTo(node.asNpc()) + } + return@on true + } + if (HolidayRandomEvents.holidayRandomIDs.contains(node.id) && node is HolidayRandomEventNPC) { + if(HolidayRandoms.getEventNpc(player) == null || HolidayRandoms.getEventNpc(player) != node.asNpc() || HolidayRandoms.getEventNpc(player)?.finalized == true) { + player.sendMessage("They aren't interested in talking to you.") + } else { + HolidayRandoms.getEventNpc(player)?.talkTo(node.asNpc()) + } + return@on true + } + if (getAttribute(npc, "holiday_random_extra_npc", false) && HolidayRandoms.getEventNpc(player) != null) { + HolidayRandoms.getEventNpc(player)?.talkTo(node.asNpc()) + return@on true + } + if (!npc.getAttribute("facing_booth", false)) { + npc.faceLocation(player.location) + } + // ---------------- THESE DIALOGUES ARE INAUTHENTIC BUT ARE COPING FOR A CORE ISSUE ----------------------- + if (player.properties.combatPulse.getVictim() == npc) { + sendMessage(player, "I don't think they have any interest in talking to me right now!") + return@on true + } + if (npc.inCombat()) { + sendMessage(player, "They look a bit busy at the moment.") + return@on true + } + //--------------------------------------------------------------------------------------------------------- + //I'm sorry for this but it was honestly the best way to do this + if (player.getAttribute("$GC_BASE_ATTRIBUTE:$GC_JOB_ORDINAL", -1) != -1) { + val job = GnomeCookingJob.values()[player.getAttribute("$GC_BASE_ATTRIBUTE:$GC_JOB_ORDINAL", -1)] + if (node.getId() == job.npc_id && !player.getAttribute("$GC_BASE_ATTRIBUTE:$GC_JOB_COMPLETE", false)) { + player.dialogueInterpreter.open(GCCompletionDialogue(job)) + return@on true + } + } + return@on player.dialogueInterpreter.open(npc.id, npc) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/npc/RatNPC.java b/Server/src/main/content/global/handlers/npc/RatNPC.java new file mode 100644 index 0000000..f8a380d --- /dev/null +++ b/Server/src/main/content/global/handlers/npc/RatNPC.java @@ -0,0 +1,66 @@ +package content.global.handlers.npc; + +import core.game.node.entity.Entity; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.game.world.map.Location; +import content.data.Quests; + +/** + * Represents a rat npc. + * @author 'Vexia + */ +@Initializable +public class RatNPC extends AbstractNPC { + + /** + * The NPC ids of NPCs using this plugin. + */ + private static final int[] ID = { 47, 2682, 2980, 2981, 3007, 3008, 3009, 3010, 3011, 3012, 3013, 3014, 3015, 3016, 3017, 3018, 4396, 4415, 7202, 7204, 7417, 7461 }; + + /** + * Represents the rat tail item. + */ + private static final Item RAT_TAIL = new Item(300); + + /** + * Constructs a new {@code RatNPC} {@code Object}. + */ + public RatNPC() { + super(0, null); + } + + /** + * Constructs a new {@code RatNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + private RatNPC(int id, Location location) { + super(id, location, true); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new RatNPC(id, location); + } + + @Override + public void finalizeDeath(final Entity killer) { + super.finalizeDeath(killer); + if (killer instanceof Player) { + final Player p = ((Player) killer); + if (p.getQuestRepository().getQuest(Quests.WITCHS_POTION).isStarted(p)) { + GroundItemManager.create(RAT_TAIL, getLocation(), p); + } + } + } + + @Override + public int[] getIds() { + return ID; + } + +} diff --git a/Server/src/main/content/global/handlers/npc/SheepBehavior.kt b/Server/src/main/content/global/handlers/npc/SheepBehavior.kt new file mode 100644 index 0000000..b329d46 --- /dev/null +++ b/Server/src/main/content/global/handlers/npc/SheepBehavior.kt @@ -0,0 +1,139 @@ +package content.global.handlers.npc + +import content.region.misthalin.lumbridge.quest.sheepshearer.SheepShearer.Companion.ATTR_IS_PENGUIN_SHEEP_SHEARED +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.combat.DeathTask +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import core.game.system.task.Pulse +import core.game.world.GameWorld +import core.game.world.update.flag.context.Animation +import core.tools.RandomFunction +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Sounds +import core.game.world.map.Location +import core.game.world.map.Direction +import content.data.Quests + +private val sheepIds = intArrayOf( + NPCs.SHEEP_42, + NPCs.SHEEP_43, + NPCs.GOLDEN_SHEEP_1271, + NPCs.GOLDEN_SHEEP_1272, + NPCs.SHEEP_1529, + NPCs.SHEEP_1762, + NPCs.SHEEP_1763, + NPCs.SHEEP_1764, + NPCs.SHEEP_1765, + NPCs.SICK_LOOKING_SHEEP_1_2377, + NPCs.SICK_LOOKING_SHEEP_2_2378, + NPCs.SICK_LOOKING_SHEEP_3_2379, + NPCs.SICK_LOOKING_SHEEP_4_2380, + NPCs.SHEEP_3310, + NPCs.SHEEP_3311, + NPCs.SHEEP_3579, + NPCs.SHEEP_5148, + NPCs.SHEEP_5149, + NPCs.SHEEP_5150, + NPCs.SHEEP_5151, + NPCs.SHEEP_5152, + NPCs.SHEEP_5153, + NPCs.SHEEP_5154, + NPCs.SHEEP_5155, + NPCs.SHEEP_5156, + NPCs.SHEEP_5157, + NPCs.SHEEP_5158, + NPCs.SHEEP_5159, + NPCs.SHEEP_5160, + NPCs.SHEEP_5161, + NPCs.SHEEP_5162, + NPCs.SHEEP_5163, + NPCs.SHEEP_5164, + NPCs.SHEEP_5165, + NPCs.GOLDEN_SHEEP_5172, + NPCs.GOLDEN_SHEEP_5173 +) + +class SheepBehavior : NPCBehavior(*sheepIds), InteractionListener { + override fun tick(self: NPC): Boolean { + if (self.properties.combatPulse.isAttacking || DeathTask.isDead(self)) { + return true + } + if (RandomFunction.random(35) == 5) { + sendChat(self, "Baa!") + } + + return true + } + + override fun defineListeners() { + on(IntType.NPC, "shear") { player, node -> + val sheep = node as NPC + sheep.faceTemporary(player, 1) + if (sheep.id == NPCs.SHEEP_3579) { + if (player.questRepository.getQuest(Quests.SHEEP_SHEARER).isStarted(player)) { + setAttribute(player, ATTR_IS_PENGUIN_SHEEP_SHEARED, true) + } + animate(player, Animation(893)) + playAudio(player, Sounds.PENGUINSHEEP_ESCAPE_686) + animate(sheep, Animation(3570)) + + sheepBackAway(player, sheep, "The... whatever it is... manages to get away from you!") + return@on true + } + if (!inInventory(player, Items.SHEARS_1735)) { + sendMessage(player, "You need shears to shear a sheep.") + return@on true + } + if (hasOption(sheep, "attack")) { + sendMessage(player, "That one looks a little too violent to shear...") + return@on true + } + if (freeSlots(player) == 0) { + sendMessage(player, "You don't have enough space in your inventory to carry any wool you would shear.") + return@on true + } + lock(sheep, 3) + stopWalk(sheep) + animate(player, Animation(893)) + val random = RandomFunction.random(1, 5) + if (random != 4) { + sheep.locks.lockMovement(2) + sheep.transform(NPCs.SHEEP_5153) + playAudio(player, Sounds.SHEAR_SHEEP_761) + sendMessage(player, "You get some wool.") + addItem(player, Items.WOOL_1737) // 5160 + GameWorld.Pulser.submit(object : Pulse(80, sheep) { + override fun pulse(): Boolean { + sheep.reTransform() + return true + } + }) + } else { + sheepBackAway(player, sheep, "The sheep manages to get away from you!") + } + return@on true + } + } + + fun sheepBackAway(player: Player, sheep: NPC, messagePlayer: String) + { + val playerLocation = player.getLocation() + val sheepLocation = sheep.getLocation() + val sheepDirection = Direction.getDirection(sheepLocation, playerLocation) // Get direction sheep is facing, from the player's location + val sheepOppositeDirection = sheepDirection.getOpposite() // Switch to opposite direction + + val xWalkLocation = sheepLocation.getX() + (sheepOppositeDirection.getStepX() * 3) // Gets x location, if set, 3 steps away from player + val yWalkLocation = sheepLocation.getY() + (sheepOppositeDirection.getStepY() * 3) // Gets y location, if set, 3 steps away from player + val sheepWalkToLocation = Location(xWalkLocation, yWalkLocation, sheepLocation.getZ()); // New location for pathfinding + + sendMessage(player, messagePlayer) + + unlock(sheep) //Force unlock of entity movement, to allow moving away + forceWalk(sheep, sheepWalkToLocation, "dumb") + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/npc/ShopNPC.java b/Server/src/main/content/global/handlers/npc/ShopNPC.java new file mode 100644 index 0000000..2e352f5 --- /dev/null +++ b/Server/src/main/content/global/handlers/npc/ShopNPC.java @@ -0,0 +1,56 @@ +package content.global.handlers.npc; + +import core.game.node.entity.npc.AbstractNPC; +import core.plugin.Initializable; +import core.game.world.map.Location; + +/** + * Represents the abstract npc of a generic owner of a shop. + * @author 'Vexia + */ +@Initializable +public class ShopNPC extends AbstractNPC { + + /** + * The NPC ids of NPCs using this plugin. + */ + private static final int[] ID = { 410, 528, 529, 525, 524, 1436, 590, 591, 971, 1917, 597, 1083, 3541, 7396, 1040, 563, 5798, 582, 526, 527, 873, 532, 533, 568, 2154, 1334, 2352, 4516, 520, 521, 4716, 3922, 1254, 2086, 1866, 530, 531, 836, 516, 560, 471, 522, 523, 4651, 4652, 4653, 4654, 4655, 4656, 4650, 534, 588, 2356, 1860, 550, 575, 683, 682, 4563, 4558, 4559, 519, 559, 562, 581, 554, 601, 1301, 1039, 2353, 3166, 2161, 2162, 600, 593, 545, 585, 5268, 2305, 2307, 2304, 1783, 557, 1038, 1433, 7053, 571, 5487, 536, 4294, 4293, 584, 570, 540, 2157, 69669, 569, 572, 573, 1303, 595, 297, 704, 587, 5110, 5109, 556, 1865, 543, 2198, 580, 1862, 583, 553, 461, 4513, 3097, 903, 1435, 606, 2623, 594, 579, 2160, 6750, 6898, 6893, 589, 5485, 542, 549, 3038, 544, 1434, 209, 1980, 546, 6988, 558, 576, 5266, 586, 602, 552, 551, 541, 692, 797, 564, 2152, 1208, 2233, 3205, 70, 1598, 1596, 1597, 1599, 2259, 3162, 1167, 2620, 2151, 5486, 4250, 1079, 793, 2572 }; + + /** + * Constructs a new {@code ShopNPC} {@code Object}. + */ + public ShopNPC() { + super(0, null, true); + } + + /** + * Constructs a new {@code ShopNPC} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + private ShopNPC(int id, Location location) { + super(id, location, true); + } + + @Override + public void init() { + super.init(); + setWalks(true); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new ShopNPC(id, location); + } + + @Override + public int getWalkRadius() { + return 3; + } + + @Override + public int[] getIds() { + return ID; + } + +} diff --git a/Server/src/main/content/global/handlers/player/AttackOptionPlugin.java b/Server/src/main/content/global/handlers/player/AttackOptionPlugin.java new file mode 100644 index 0000000..328d52c --- /dev/null +++ b/Server/src/main/content/global/handlers/player/AttackOptionPlugin.java @@ -0,0 +1,42 @@ +package content.global.handlers.player; + +import core.cache.def.impl.NPCDefinition; +import core.game.interaction.Option; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the attack option plugin handler. + * @author Emperor + * @version 1.0 + */ +@Initializable +public final class AttackOptionPlugin extends OptionHandler { + + @Override + public boolean handle(Player player, Node node, String option) { + player.attack(node); + return true; + } + + @Override + public boolean isWalk() { + return false; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + Option._P_ATTACK.setHandler(this); + return this; + } + + @Override + public boolean isDelayed(Player player) { + return false; + } + +} diff --git a/Server/src/main/content/global/handlers/player/FollowOptionPlugin.java b/Server/src/main/content/global/handlers/player/FollowOptionPlugin.java new file mode 100644 index 0000000..a3cea3b --- /dev/null +++ b/Server/src/main/content/global/handlers/player/FollowOptionPlugin.java @@ -0,0 +1,45 @@ +package content.global.handlers.player; + +import core.game.interaction.DestinationFlag; +import core.game.interaction.MovementPulse; +import core.game.interaction.Option; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.impl.PulseType; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the plugin used to start following a node. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class FollowOptionPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + Option._P_FOLLOW.setHandler(this); + return this; + } + + @Override + public boolean handle(final Player player, Node node, String option) { + final Player target = ((Player) node); + player.getPulseManager().run(new MovementPulse(player, target, DestinationFlag.FOLLOW_ENTITY) { + @Override + public boolean pulse() { + player.face(target); + return false; + } + + @Override + public void stop() { + super.stop(); + mover.face(null); + } + }, PulseType.STANDARD); + return true; + } +} diff --git a/Server/src/main/content/global/handlers/player/LoginValidationPlugin.java b/Server/src/main/content/global/handlers/player/LoginValidationPlugin.java new file mode 100644 index 0000000..642d33f --- /dev/null +++ b/Server/src/main/content/global/handlers/player/LoginValidationPlugin.java @@ -0,0 +1,122 @@ +package content.global.handlers.player; + +import core.api.Container; +import core.game.activity.ActivityManager; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.system.SystemManager; +import core.game.world.GameWorld; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.plugin.PluginManifest; +import core.plugin.PluginType; +import org.rs09.consts.Items; + +import java.util.concurrent.TimeUnit; + +import static core.api.ContentAPIKt.*; + +/** + * Validates a player login. + * @author Emperor + * @author Vexia + * + */ +@PluginManifest(type = PluginType.LOGIN) +@Initializable +public final class LoginValidationPlugin implements Plugin { + + /** + * Represents the quest point items to remove. + */ + private static final Item[] QUEST_ITEMS = new Item[] { new Item(Items.QUEST_POINT_CAPE_9813), new Item(Items.QUEST_POINT_HOOD_9814)}; + + /** + * Constructs a new {@Code LoginValidationPlugin} {@Code Object} + */ + public LoginValidationPlugin() { + /* + * empty. + */ + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public Plugin newInstance(final Player player) throws Throwable { + player.unlock(); + if (player.isArtificial()) { + return this; + } + if (!SystemManager.getSystemConfig().validLogin(player)) { + return this; + } + if (GameWorld.getSettings().isDevMode()) { + player.toggleDebug(); + } + if (player.getAttribute("fc_wave", -1) > -1) { + ActivityManager.start(player, "fight caves", true); + } + if (player.getAttribute("falconry", false)) { + ActivityManager.start(player, "falconry", true); + } + if (player.getSavedData().getQuestData().getDragonSlayerAttribute("repaired")) { + setVarp(player, 177, 1967876); //lol? + } + if (player.getSavedData().getGlobalData().getLootShareDelay() < System.currentTimeMillis() && player.getSavedData().getGlobalData().getLootShareDelay() != 0L) { + player.getGlobalData().setLootSharePoints((int) (player.getGlobalData().getLootSharePoints() - player.getGlobalData().getLootSharePoints() * 0.10)); + } else { + player.getSavedData().getGlobalData().setLootShareDelay(System.currentTimeMillis() + TimeUnit.DAYS.toMillis(1)); + } + checkQuestPointsItems(player); + return this; + } + + /** + * Method used to check for the quest point cape items. + * @param player the player. + */ + private static void checkQuestPointsItems(final Player player) { + if (!player.getQuestRepository().hasCompletedAll() && anyInEquipment(player, Items.QUEST_POINT_CAPE_9813, Items.QUEST_POINT_HOOD_9814)) { + String location1 = null; + String location2 = null; + int item1 = 0; + int item2 = 0; + int amt = 0; + for (Item i : QUEST_ITEMS) { + if (removeItem(player, i, Container.EQUIPMENT)) { + amt++; + String location; + if (addItem(player, i.getId(), i.getAmount(), Container.INVENTORY)) { + location = "your inventory"; + } else if (addItem(player, i.getId(), i.getAmount(), Container.BANK)) { + location = "your bank"; + } else { + location = "the Wise Old Man"; + if (i.getId() == Items.QUEST_POINT_CAPE_9813) { + setAttribute(player, "/save:reclaim-qp-cape", true); + } else { + setAttribute(player, "/save:reclaim-qp-hood", true); + } + } + if (amt == 1) { + item1 = i.getId(); + location1 = location; + } + if (amt == 2) { + item2 = i.getId(); + location2 = location; + } + } + } + if (amt == 2) { + sendDoubleItemDialogue(player, item1, item2, "As you no longer have completed all the quests, your " + getItemName(item1) + " unequips itself to " + location1 + " and your " + getItemName(item2) + " unequips itself to " + location2 + "!"); + } else { + sendItemDialogue(player, item1, "As you no longer have completed all the quests, your " + getItemName(item1) + " unequips itself to " + location1 + "!"); + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/player/RequestOption.kt b/Server/src/main/content/global/handlers/player/RequestOption.kt new file mode 100644 index 0000000..33707b3 --- /dev/null +++ b/Server/src/main/content/global/handlers/player/RequestOption.kt @@ -0,0 +1,32 @@ +package content.global.handlers.player + +import core.game.interaction.Option._P_ASSIST +import core.game.interaction.Option._P_TRADE +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.request.RequestType +import core.plugin.Initializable +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.bots.* + +/** + * Represents the plugin used to handle the player option interacting. + * @author 'Vexia + * @author dginovker + * @version 2.0 + */ +@Initializable +class RequestOption : InteractionListener { + override fun defineListeners() { + on(_P_TRADE.name, IntType.PLAYER) { player, node -> + player.requestManager.request((node as Player), RequestType.TRADE) + return@on true + } + on(_P_ASSIST.name, IntType.PLAYER) { player, node -> + if (node is AIPlayer) + AIRepository.sendBotInfo(player, node) + player.requestManager.request((node as Player), RequestType.ASSIST) + return@on true + } + } +} diff --git a/Server/src/main/content/global/handlers/scenery/BankBoothListener.kt b/Server/src/main/content/global/handlers/scenery/BankBoothListener.kt new file mode 100644 index 0000000..b725c8c --- /dev/null +++ b/Server/src/main/content/global/handlers/scenery/BankBoothListener.kt @@ -0,0 +1,193 @@ +package content.global.handlers.scenery + +import core.api.* +import core.game.node.Node +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.IronmanMode +import core.game.node.item.Item +import core.game.world.map.Direction +import core.game.world.map.Location +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery +import core.ServerConstants +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import content.global.handlers.npc.BankerNPC +import core.game.world.repository.Repository + +/** + * Allows the user to interact with bank booths. + * + * @author vddCore + */ +class BankBoothListener : InteractionListener { + + companion object { + val INOPERABLE_BANK_BOOTHS = intArrayOf( + Scenery.BANK_BOOTH_12800, Scenery.BANK_BOOTH_12801, Scenery.BANK_BOOTH_36262, Scenery.BANK_BOOTH_35648 + ) + + val BANK_BOOTHS = intArrayOf( + Scenery.BANK_BOOTH_2213, Scenery.BANK_BOOTH_2214, Scenery.BANK_BOOTH_3045, Scenery.BANK_BOOTH_5276, + Scenery.BANK_BOOTH_6084, Scenery.BANK_BOOTH_10517, Scenery.BANK_BOOTH_11338, Scenery.BANK_BOOTH_11402, + Scenery.BANK_BOOTH_11758, Scenery.BANK_BOOTH_12798, Scenery.BANK_BOOTH_12799, Scenery.BANK_BOOTH_14367, + Scenery.BANK_BOOTH_14368, Scenery.BANK_BOOTH_16700, Scenery.BANK_BOOTH_18491, Scenery.BANK_BOOTH_19230, + Scenery.BANK_BOOTH_20325, Scenery.BANK_BOOTH_20326, Scenery.BANK_BOOTH_20327, Scenery.BANK_BOOTH_20328, + Scenery.BANK_BOOTH_22819, Scenery.BANK_BOOTH_24914, Scenery.BANK_BOOTH_25808, Scenery.BANK_BOOTH_26972, + Scenery.BANK_BOOTH_29085, Scenery.BANK_BOOTH_30015, Scenery.BANK_BOOTH_30016, Scenery.BANK_BOOTH_34205, + Scenery.BANK_BOOTH_34752, Scenery.BANK_BOOTH_35647, Scenery.BANK_BOOTH_36786, Scenery.BANK_BOOTH_37474 + ) + + public fun convertToNotes (used: Node, player: Player) { + val item = used as Item + + if (item.noteChange != item.id) { + if (item.definition.isUnnoted) { + val amount = amountInInventory(player, item.id) + if (removeItem(player, Item(item.id, amount))) { + addItem(player, item.noteChange, amount) + } + } else { + var amount = item.amount + val freeSlotCount = freeSlots(player) + + // If there is exactly one more note than free slots + // the note disappearing can be used as the last slot + if (amount > freeSlotCount && amount != freeSlotCount + 1) { + amount = freeSlotCount + } + + if (removeItem(player, Item(item.id, amount))) { + addItem(player, item.noteChange, amount) + } + } + + return + } + + sendMessage(player, "This item can't be noted.") + } + } + + /** + * Searches an area in the order described + * by each number with X being the location + * of node being interacted with. + * + * [1] + * [4][X][2] + * [3] + */ + private fun locateAdjacentBankerLinear(node: Node): NPC? { + for (dir in arrayOf(Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST)) { + Repository.findNPC(node.location.transform(dir))?.let { return it as? BankerNPC } + } + + return null + } + + /** + * If size is 1 then the following method + * searches a square area in the following + * order with X being the location of node + * that was interacted with. + * + * ->[ ] + * [ X ] + * [ ]-> + * + */ + private fun locateAdjacentBankerSquare(node: Node, size: Int = 1): NPC? { + for (y in (node.location.y - size)..(node.location.y + size)) { + for (x in (node.location.x - size)..(node.location.x + size)) { + Repository.findNPC(Location(x, y))?.let { return it as? BankerNPC } + } + } + + return null + } + + private fun tryInvokeBankerDialogue(player: Player, node: Node) { + /** + * First, we look for regular bankers that neatly stand in front of the bank booth. + * If that fails, we expand the search to a larger area. + */ + (locateAdjacentBankerLinear(node) ?: locateAdjacentBankerSquare(node, 2))?.let { + if (core.game.dialogue.DialogueInterpreter.contains(it.id)) { + it.faceLocation(node.location) + openDialogue(player, it.id, NPC(it.id, it.location)) + } else { + openDialogue(player, NPCs.BANKER_494) + } + } + } + + private fun quickBankBoothUse(player: Player, node: Node, state: Int): Boolean { + if (player.ironmanManager.checkRestriction(IronmanMode.ULTIMATE)) { + return true + } + + if (BankerNPC.checkLunarIsleRestriction(player, node)) { + tryInvokeBankerDialogue(player, node) + return true + } + + openBankAccount(player) + return true + } + + private fun regularBankBoothUse(player: Player, node: Node, state: Int): Boolean { + if (player.ironmanManager.checkRestriction(IronmanMode.ULTIMATE)) { + return true + } + + if (ServerConstants.BANK_BOOTH_QUICK_OPEN) { + return quickBankBoothUse(player, node, state) + } + + tryInvokeBankerDialogue(player, node) + return true + } + + private fun collectBankBoothUse(player: Player, node: Node, state: Int): Boolean { + if (BankerNPC.checkLunarIsleRestriction(player, node)) { + tryInvokeBankerDialogue(player, node) + return true + } + + openGrandExchangeCollectionBox(player) + return true + } + + private fun attemptToConvertItems(player: Player, used: Node, with: Node): Boolean { + if (!hasOption(with, "use")) { + sendMessage(player, "You shouldn't be able to do that with object ${with.id}.") + sendMessage(player, "Please screenshot this and report to the developers.") + + return true + } + + if (!ServerConstants.BANK_BOOTH_NOTE_UIM && player.ironmanManager.checkRestriction(IronmanMode.ULTIMATE)) { + return true + } + + if (BankerNPC.checkLunarIsleRestriction(player, with)) { + tryInvokeBankerDialogue(player, with) + return true + } + + convertToNotes (used, player) + return true + } + + override fun defineListeners() { + defineInteraction(IntType.SCENERY, BANK_BOOTHS, "use-quickly", "bank", handler = ::quickBankBoothUse) + defineInteraction(IntType.SCENERY, BANK_BOOTHS, "use", handler = ::regularBankBoothUse) + defineInteraction(IntType.SCENERY, BANK_BOOTHS, "collect", handler = ::collectBankBoothUse) + + if (ServerConstants.BANK_BOOTH_NOTE_ENABLED) { + onUseAnyWith(IntType.SCENERY, *BANK_BOOTHS, handler = ::attemptToConvertItems) + } + } +} diff --git a/Server/src/main/content/global/handlers/scenery/BankChestListener.kt b/Server/src/main/content/global/handlers/scenery/BankChestListener.kt new file mode 100644 index 0000000..9fb2683 --- /dev/null +++ b/Server/src/main/content/global/handlers/scenery/BankChestListener.kt @@ -0,0 +1,28 @@ +package content.global.handlers.scenery + +import core.api.openBankAccount +import org.rs09.consts.Scenery +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +private val BANK_CHESTS = intArrayOf( + Scenery.BANK_CHEST_3194, Scenery.BANK_CHEST_4483, + Scenery.BANK_CHEST_10562, Scenery.BANK_CHEST_14382, + Scenery.BANK_CHEST_16695, Scenery.BANK_CHEST_16696, + Scenery.BANK_CHEST_21301, Scenery.BANK_CHEST_27662, + Scenery.BANK_CHEST_27663 +) + +/** + * Allows the user to interact with Bank Chests. + * + * @author vddCore + */ +class BankChestListener : InteractionListener { + override fun defineListeners() { + defineInteraction(IntType.SCENERY, BANK_CHESTS, "bank", "use") {player, node, state -> + openBankAccount(player) + return@defineInteraction true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/scenery/BankDepositBoxListener.kt b/Server/src/main/content/global/handlers/scenery/BankDepositBoxListener.kt new file mode 100644 index 0000000..68579bf --- /dev/null +++ b/Server/src/main/content/global/handlers/scenery/BankDepositBoxListener.kt @@ -0,0 +1,60 @@ +package content.global.handlers.scenery + +import core.api.restrictForIronman +import core.game.component.CloseEvent +import core.game.component.Component +import core.game.container.access.InterfaceContainer +import core.game.node.Node +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.IronmanMode +import org.rs09.consts.Components +import org.rs09.consts.Scenery +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +private val BANK_DEPOSIT_BOXES = intArrayOf( + Scenery.BANK_DEPOSIT_BOX_9398, + Scenery.BANK_DEPOSIT_BOX_20228, + Scenery.BANK_DEPOSIT_BOX_25937, + Scenery.BANK_DEPOSIT_BOX_26969, + Scenery.BANK_DEPOSIT_BOX_34755, + Scenery.BANK_DEPOSIT_BOX_36788, + Scenery.BANK_DEPOSIT_BOX_39830 +) + +/** + * Allows the user to interact with bank deposit boxes. + * + * @author vddCore + */ +class BankDepositBoxListener : InteractionListener { + + private fun openDepositBox(player: Player, node: Node, state: Int) : Boolean { + restrictForIronman(player, IronmanMode.ULTIMATE) { + player.interfaceManager.open(Component(Components.BANK_DEPOSIT_BOX_11)).closeEvent = CloseEvent { p, _ -> + p.interfaceManager.openDefaultTabs() + return@CloseEvent true + } + + player.interfaceManager.removeTabs(0, 1, 2, 3, 4, 5, 6) + InterfaceContainer.generateItems( + player, + player.inventory.toArray(), + arrayOf( + "Examine", + "Deposit-X", + "Deposit-All", + "Deposit-10", + "Deposit-5", + "Deposit-1" + ), 11, 15, 5, 7 + ) + } + + return true + } + + override fun defineListeners() { + defineInteraction(IntType.SCENERY, BANK_DEPOSIT_BOXES, "deposit", handler = ::openDepositBox) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/scenery/DoogleLeafInteraction.kt b/Server/src/main/content/global/handlers/scenery/DoogleLeafInteraction.kt new file mode 100644 index 0000000..fdf7d98 --- /dev/null +++ b/Server/src/main/content/global/handlers/scenery/DoogleLeafInteraction.kt @@ -0,0 +1,24 @@ +package content.global.handlers.scenery + +import core.api.addItem +import core.api.sendMessage +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.Node +import core.game.node.entity.player.Player +import org.rs09.consts.Items + +class DoogleLeafInteraction : InteractionListener { + override fun defineListeners() { + defineInteraction(IntType.SCENERY, intArrayOf(31155), "pick-leaf", handler = ::handleDoogle) + } + + fun handleDoogle(player: Player, node: Node, state: Int) : Boolean { + if (!addItem(player, Items.DOOGLE_LEAVES_1573)) { + sendMessage(player, "You don't have enough space in your inventory.") + return true + } + sendMessage(player, "You pick some doogle leaves.") + return true + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/scenery/DoorManagingPlugin.java b/Server/src/main/content/global/handlers/scenery/DoorManagingPlugin.java new file mode 100644 index 0000000..b6d18c0 --- /dev/null +++ b/Server/src/main/content/global/handlers/scenery/DoorManagingPlugin.java @@ -0,0 +1,101 @@ +package content.global.handlers.scenery; + +import core.cache.def.impl.SceneryDefinition; +import core.game.global.action.DoorActionHandler; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.plugin.Initializable; +import core.plugin.Plugin; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.*; + +/** + * Plugin used for handling the opening/closing of (double) + * doors/gates/fences/... + * @author Emperor + */ +@Initializable +public final class DoorManagingPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.setOptionHandler("open", this); + SceneryDefinition.setOptionHandler("close", this); + SceneryDefinition.setOptionHandler("shut", this); + SceneryDefinition.setOptionHandler("go-through", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + Scenery object = (Scenery) node; + if (object.getType() != 9 && !player.getLocation().equals(node.getLocation()) && !player.getLocation().isNextTo(object) && object.getName().contains("cupboard")) { + return true; + } + String name = object.getName().toLowerCase(); + if (name.contains("drawers") || name.contains("wardrobe") || name.contains("cupboard")) { + switch(option) { + case "open": + if (name.contains("drawers")) { + playAudio(player, Sounds.DRAWER_OPEN_64); + } else if (name.contains("wardrobe")) { + animate(player, 545, false); + playAudio(player, Sounds.WARDROBE_OPEN_96); + } else if (name.contains("cupboard")) { + playAudio(player, Sounds.CUPBOARD_OPEN_58); + } + case "go-through": + if (object.isActive()) { + SceneryBuilder.replace(object, object.transform(object.getId() + 1), 80); + } + return true; + case "close": + case "shut": + if (name.contains("drawers")) { + playAudio(player, Sounds.DRAWER_CLOSE_63); + } else if (name.contains("wardrobe")) { + animate(player, 544, false); + playAudio(player, Sounds.WARDROBE_CLOSE_95); + } else if (name.contains("cupboard")) { + playAudio(player, Sounds.CUPBOARD_CLOSE_57); + } + SceneryBuilder.replace(object, object.transform(object.getId() - 1)); + return true; + } + return true; + } + if (name.contains("trapdoor") || name.contains("trap door")) { + Location destination = object.getLocation().transform(0, 6400, 0); + if (!RegionManager.isTeleportPermitted(destination)) { + player.getPacketDispatch().sendMessage("This doesn't seem to go anywhere."); + return true; + } + player.getProperties().setTeleportLocation(destination); + return true; + } + if (node.asScenery().getId() == 25341) {// Mithril door + return false; + } + if (!name.contains("door") && !name.contains("gate") && !name.contains("fence") && !name.contains("wall") && !name.contains("exit") && !name.contains("entrance")) { + return false; + } + DoorActionHandler.handleDoor(player, object); + return true; + } + + @Override + public Location getDestination(Node n, Node node) { + Scenery o = (Scenery) node; + if (o.getType() < 4 || o.getType() == 9) { + return DoorActionHandler.getDestination((Player) n, o); + } + return null; + } + +} diff --git a/Server/src/main/content/global/handlers/scenery/FieldPickingPlugin.java b/Server/src/main/content/global/handlers/scenery/FieldPickingPlugin.java new file mode 100644 index 0000000..1d0fa5c --- /dev/null +++ b/Server/src/main/content/global/handlers/scenery/FieldPickingPlugin.java @@ -0,0 +1,248 @@ +package content.global.handlers.scenery; + +import core.cache.def.impl.SceneryDefinition; +import core.game.container.impl.EquipmentContainer; +import core.game.event.ResourceProducedEvent; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.combat.ImpactHandler.HitsplatType; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; +import core.plugin.Initializable; +import core.tools.RandomFunction; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playAudio; + +/** + * Handles the pick option of interactive scenery (non-farming cabbages, + * potatoes, bananas, etc) + * @author Emperor + * @version 1.0 + */ +@Initializable +public final class FieldPickingPlugin extends OptionHandler { + + /** + * The picking animation to use. + */ + private static final Animation ANIMATION = new Animation(827); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for(PickingPlant p : PickingPlant.values()){ + SceneryDefinition.forId(p.objectId).getHandlers().put("option:pick",this); + } + SceneryDefinition.forId(3511).getHandlers().put("option:take-cutting",this); + return this; + } + + @Override + public boolean handle(final Player player, Node node, String option) { + if (player.getAttribute("delay:picking", -1) > GameWorld.getTicks()) { + return true; + } + final Scenery object = (Scenery) node; + final PickingPlant plant = PickingPlant.forId(object.getId()); + if (plant == null) { + return false; + } + if (!object.isActive()) { + return true; + } + final Item reward = new Item(plant == PickingPlant.POTATO && RandomFunction.random(10) == 0 ? 5318 : plant.reward); + if (!player.getInventory().hasSpaceFor(reward)) { + player.getPacketDispatch().sendMessage("Not enough space in your inventory!"); + return true; + } + if (player.getInventory().freeSlot() == -1) { + return true; + } + player.lock(1); + player.setAttribute("delay:picking", GameWorld.getTicks() + (plant == PickingPlant.FLAX ? 2 : 3)); + player.animate(ANIMATION); + playAudio(player, Sounds.PICK_2581, 30); + player.dispatch(new ResourceProducedEvent(reward.getId(), reward.getAmount(), node, -1)); + if (plant.name().startsWith("NETTLES") && (player.getEquipment().get(EquipmentContainer.SLOT_HANDS) == null || player.getEquipment().get(EquipmentContainer.SLOT_HANDS) != null && !player.getEquipment().get(EquipmentContainer.SLOT_HANDS).getName().contains("glove"))) { + player.getPacketDispatch().sendMessage("You have been stung by the nettles!"); + player.getImpactHandler().manualHit(player, 6, HitsplatType.POISON); + return true; + } + if (plant.respawn != -1 && plant != PickingPlant.FLAX) { + object.setActive(false); + } + GameWorld.getPulser().submit(new Pulse(1, player) { + @Override + public boolean pulse() { + if (!player.getInventory().add(reward)) { + player.getPacketDispatch().sendMessage("Not enough space in your inventory!"); + return true; + } + if (plant == PickingPlant.FLAX) { + handleFlaxPick(player, object, plant); + return true; + } + boolean banana = plant.name().startsWith("BANANA"); + Scenery full = null; + if (plant == PickingPlant.BANANA_TREE_4) { + full = object.transform(2073); + SceneryBuilder.replace(object, full); + } + boolean isBloomPlant = plant == PickingPlant.FUNGI_ON_LOG + || plant == PickingPlant.BUDDING_BRANCH + || plant == PickingPlant.GOLDEN_PEAR_BUSH; + if (isBloomPlant) { + full = object.transform(object.getId() - 1); + SceneryBuilder.replace(object, full); + } + if (!isBloomPlant) { + SceneryBuilder.replace(plant == PickingPlant.BANANA_TREE_4 ? full : object, object.transform(banana ? plant.respawn : 0), banana ? 300 : plant.respawn); + } + if (!plant.name().startsWith("NETTLES")) { + player.getPacketDispatch().sendMessage("You pick a " + reward.getName().toLowerCase() + "."); + } else { + player.getPacketDispatch().sendMessage("You pick a handful of nettles."); + } + return true; + } + }); + return true; + } + + /** + * Method used to handle the flax picking. + * @param player the player. + * @param object the object. + * @param plant the plank. + */ + private void handleFlaxPick(final Player player, final Scenery object, final PickingPlant plant) { + int charge = object.getCharge(); + playAudio(player, Sounds.PICK_2581); + player.getPacketDispatch().sendMessage("You pick some flax."); + + if (charge > 1000 + RandomFunction.random(2, 8)) { + object.setActive(false); + object.setCharge(1000); + SceneryBuilder.replace(object, object.transform(0), plant.respawn); + return; + } + object.setCharge(charge + 1); + } + + /** + * Represents a plant to be picked. + * @author Emperor + */ + private static enum PickingPlant { + POTATO(312, 1942, 30), + WHEAT_0(313, 1947, 30), + WHEAT_1(5583, 1947, 30), + WHEAT_2(5584, 1947, 30), + WHEAT_3(5585, 1947, 30), + WHEAT_4(15506, 1947, 30), + WHEAT_5(15507, 1947, 30), + WHEAT_6(15508, 1947, 30), + WHEAT_7(22300, 1947, 30), + WHEAT_8(22473, 1947, 30), + WHEAT_9(22474, 1947, 30), + WHEAT_10(22475, 1947, 30), + WHEAT_11(22476, 1947, 30), + CABBAGE_0(1161, 1965, 30), + CABBAGE_1(11494, 1967, 30), + CABBAGE_2(22301, 1965, 30), + NETTLES_0(1181, 4241, 30), + NETTLES_1(5253, 4241, 30), + NETTLES_2(5254, 4241, 30), + NETTLES_3(5255, 4241, 30), + NETTLES_4(5256, 4241, 30), + NETTLES_5(5257, 4241, 30), + NETTLES_6(5258, 4241, 30), + PINEAPPLE_PLANT_0(1408, 2114, 30), + PINEAPPLE_PLANT_1(1409, 2114, 30), + PINEAPPLE_PLANT_2(1410, 2114, 30), + PINEAPPLE_PLANT_3(1411, 2114, 30), + PINEAPPLE_PLANT_4(1412, 2114, 30), + PINEAPPLE_PLANT_5(1413, 2114, 30), + PINEAPPLE_PLANT_6(4827, 2114, 30), + BANANA_TREE_0(2073, 1963, 2074), + BANANA_TREE_1(2074, 1963, 2075), + BANANA_TREE_2(2075, 1963, 2076), + BANANA_TREE_3(2076, 1963, 2077), + BANANA_TREE_4(2077, 1963, 2078), + BANANA_TREE_5(12606, 1963, 2079), + BANANA_TREE_6(12607, 1963, 2080), + FLAX(2646, 1779, 30), + ONION_0(3366, 1957, 30), + ONION_1(5538, 1957, 30), + FUNGI_ON_LOG(3509, 2970, -1), + BUDDING_BRANCH(3511, 2972, -1), + GOLDEN_PEAR_BUSH(3513, 2974, -1), + GLOWING_FUNGUS_0(4932, 4075, 30), + GLOWING_FUNGUS_1(4933, 4075, 30), + RARE_FLOWERS(5006, 2460, 30), + BLACK_MUSHROOMS(6311, 4620, 30), + KELP(12478, 7516, 30), + RED_BANANA_TREE(12609, 7572, 30), + BUSH(12615, 7573, 30), + RED_FLOWERS(15846, 8938, 30), + BLUE_FLOWERS(15872, 8936, 30), + HARDY_GOUTWEED(18855, 3261, 30), + HERBS_0(21668, 199, 30), + HERBS_1(21669, 201, 30), + HERBS_2(21670, 203, 30), + HERBS_3(21671, 205, 30), + FEVER_GRASS(29113, 12574, 30), + LAVENDER(29114, 12572, 30), + TANSYMUM(29115, 12576, 30), + PRIMWEED(29116, 12588, 30), + STINKBLOOM(29117, 12590, 30), + TROLLWEISS_FLOWERS(37328, 4086, 30), + HOLLOW_LOG(37830, 10968, 30); + + /** + * The object id. + */ + final int objectId; + + /** + * The reward item id. + */ + final int reward; + + /** + * The respawn duration. + */ + final int respawn; + + /** + * Constructs a new {@code FieldPickingPlugin {@code Object}. + * @param objectId the object id. + * @param reward the reward. + * @param respawn the resapwn. + */ + private PickingPlant(int objectId, int reward, int respawn) { + this.objectId = objectId; + this.reward = reward; + this.respawn = respawn; + } + + /** + * Gets the picking plant by the id. + * @param objectId the id. + * @return the picking plant. + */ + static PickingPlant forId(int objectId) { + for (PickingPlant plant : values()) + if (plant.objectId == objectId) + return plant; + return null; + } + } +} diff --git a/Server/src/main/content/global/handlers/scenery/HaystackPlugin.java b/Server/src/main/content/global/handlers/scenery/HaystackPlugin.java new file mode 100644 index 0000000..793e89a --- /dev/null +++ b/Server/src/main/content/global/handlers/scenery/HaystackPlugin.java @@ -0,0 +1,66 @@ +package content.global.handlers.scenery; + +import core.cache.def.impl.SceneryDefinition; +import core.plugin.Initializable; +import core.game.dialogue.FacialExpression; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; +import core.tools.RandomFunction; + +/** + * Represents the haystack plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class HaystackPlugin extends OptionHandler { + + /** + * Represents the needle to give. + */ + private static final Item NEEDLE = new Item(1733); + + /** + * Represents the animation. + */ + private static final Animation ANIMATION = new Animation(827); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(298).getHandlers().put("option:search", this); + SceneryDefinition.forId(299).getHandlers().put("option:search", this); + SceneryDefinition.forId(300).getHandlers().put("option:search", this); + SceneryDefinition.forId(304).getHandlers().put("option:search", this); + SceneryDefinition.forId(36892).getHandlers().put("option:search", this); + SceneryDefinition.forId(36893).getHandlers().put("option:search", this); + SceneryDefinition.forId(36894).getHandlers().put("option:search", this); + SceneryDefinition.forId(36895).getHandlers().put("option:search", this); + SceneryDefinition.forId(36896).getHandlers().put("option:search", this); + SceneryDefinition.forId(36897).getHandlers().put("option:search", this); + SceneryDefinition.forId(36898).getHandlers().put("option:search", this); + SceneryDefinition.forId(36899).getHandlers().put("option:search", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + final Scenery object = ((Scenery) node); + final int rand = RandomFunction.random(50); + player.lock(2); + player.animate(ANIMATION); + player.getPacketDispatch().sendMessage("You search the " + object.getName().toLowerCase() + "..."); + if (rand == 1 && player.getInventory().freeSlots() > 0 || player.getInventory().containsItem(NEEDLE)) { + player.getInventory().add(NEEDLE); + player.getDialogueInterpreter().sendDialogues(player, FacialExpression.HALF_GUILTY, "Wow! A needle!", "Now what are the chances of finding that?"); + return true; + } + player.getPacketDispatch().sendMessage("You find nothing of interest."); + return true; + } + +} diff --git a/Server/src/main/content/global/handlers/scenery/JangerBerryPlugin.java b/Server/src/main/content/global/handlers/scenery/JangerBerryPlugin.java new file mode 100644 index 0000000..5a4d882 --- /dev/null +++ b/Server/src/main/content/global/handlers/scenery/JangerBerryPlugin.java @@ -0,0 +1,63 @@ +package content.global.handlers.scenery; + +import core.cache.def.impl.SceneryDefinition; +import core.plugin.Initializable; +import content.global.skill.agility.AgilityHandler; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.OptionHandler; +import core.game.interaction.UseWithHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; + +/** + * Handles the janger berry plugin. + * @author Vexia + */ +@Initializable +public class JangerBerryPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + UseWithHandler.addHandler(2326, UseWithHandler.OBJECT_TYPE, new UseWithHandler(954) { + @Override + public Plugin newInstance(Object arg) throws Throwable { + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + Scenery object = event.getUsedWith().asScenery(); + if (object.isActive()) + SceneryBuilder.replace(object, object.transform(2325)); + event.getPlayer().getInventory().remove(event.getUsedItem()); + return true; + } + + }); + SceneryDefinition.forId(2325).getHandlers().put("option:swing-on", this); + SceneryDefinition.forId(2324).getHandlers().put("option:swing-on", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + if (!player.getLocation().withinDistance(node.getLocation(), 2)) { + player.sendMessage("I can't reach that."); + return true; + } + Location end = node.getId() == 2325 ? new Location(2505, 3087, 0) : new Location(2511, 3096, 0); + player.getPacketDispatch().sendSceneryAnimation(node.asScenery(), Animation.create(497), true); + AgilityHandler.forceWalk(player, 0, player.getLocation(), end, Animation.create(751), 50, 22, "You skillfully swing across.", 1); + return true; + } + + @Override + public Location getDestination(Node node, Node n) { + return n.getId() == 2324 ? new Location(2511, 3092, 0) : new Location(2501, 3087, 0); + } +} diff --git a/Server/src/main/content/global/handlers/scenery/LadderManagingPlugin.java b/Server/src/main/content/global/handlers/scenery/LadderManagingPlugin.java new file mode 100644 index 0000000..9712fe7 --- /dev/null +++ b/Server/src/main/content/global/handlers/scenery/LadderManagingPlugin.java @@ -0,0 +1,42 @@ +package content.global.handlers.scenery; + +import core.cache.def.impl.SceneryDefinition; +import core.game.global.action.ClimbActionHandler; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the plugin used for managing ladders. + * @author Emperor + * @version 2.0 + */ +@Initializable +public final class LadderManagingPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.setOptionHandler("climb-up", this); + SceneryDefinition.setOptionHandler("climb-down", this); + SceneryDefinition.setOptionHandler("climb", this); + SceneryDefinition.setOptionHandler("walk-up", this); + SceneryDefinition.setOptionHandler("walk-down", this); + return this; + } + + @Override + public boolean handle(final Player player, Node node, final String option) { + ClimbActionHandler.climbLadder(player, (Scenery) node, option); + return true; + } + + @Override + public Location getDestination(Node n, Node object) { + return ClimbActionHandler.getDestination((Scenery) object); + } + +} diff --git a/Server/src/main/content/global/handlers/scenery/LookAtOptionPlugin.java b/Server/src/main/content/global/handlers/scenery/LookAtOptionPlugin.java new file mode 100644 index 0000000..c067e9d --- /dev/null +++ b/Server/src/main/content/global/handlers/scenery/LookAtOptionPlugin.java @@ -0,0 +1,27 @@ +package content.global.handlers.scenery; + +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; + +@Initializable +public class LookAtOptionPlugin extends OptionHandler { + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (int i = 18877; i <= 18900; i++) + { + SceneryDefinition.forId(i).getHandlers().put("option:look at", this); + } + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + player.getPacketDispatch().sendMessage("The " + node.getName().toLowerCase() + " seem to be going south-west."); + return true; + + } +} diff --git a/Server/src/main/content/global/handlers/scenery/MillingListener.kt b/Server/src/main/content/global/handlers/scenery/MillingListener.kt new file mode 100644 index 0000000..c61a8c8 --- /dev/null +++ b/Server/src/main/content/global/handlers/scenery/MillingListener.kt @@ -0,0 +1,101 @@ +package content.global.handlers.scenery + +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items +import org.rs09.consts.Scenery +import org.rs09.consts.Sounds + +private const val GRAIN = Items.GRAIN_1947 +private const val SWEETCORN = Items.SWEETCORN_5986 +private const val EMPTY_POT = Items.EMPTY_POT_1931 +private const val POT_OF_FLOUR = Items.POT_OF_FLOUR_1933 +private const val POT_OF_CORNFLOUR = Items.POT_OF_CORNFLOUR_7468 +private val HOPPERS = intArrayOf(Scenery.HOPPER_36881, Scenery.HOPPER_2717, Scenery.HOPPER_24071, Scenery.HOPPER_2716, Scenery.HOPPER_22422) +private val HOPPER_CONTROLS = intArrayOf(Scenery.HOPPER_CONTROLS_2718, Scenery.HOPPER_CONTROLS_2721, Scenery.HOPPER_CONTROLS_24072, Scenery.HOPPER_CONTROLS_2720, Scenery.LEVER_22424) +private val FLOUR_BINS = intArrayOf(Scenery.FLOUR_BIN_1782, Scenery.FLOUR_BIN_5792, Scenery.FLOUR_BIN_22420, Scenery.FLOUR_BIN_22421, Scenery.FLOUR_BIN_24070, Scenery.FLOUR_BIN_36878) +private const val VARP = 695 +private val ANIMATION = Animation(3571) +private val SOUND = Sounds.GIANT_ROC_APPROACHES_3189 + +/** + * Handles interactions with windmills + * @author itsmedoggo + */ +class MillingListener : InteractionListener { + override fun defineListeners() { + defineInteraction(IntType.SCENERY, HOPPER_CONTROLS, "operate", "pull") { player, _, _ -> + useHopperControl(player) + return@defineInteraction true + } + defineInteraction(IntType.SCENERY, FLOUR_BINS, "empty") {player, _, _ -> + fillPot(player) + return@defineInteraction true + } + onUseWith(SCENERY, intArrayOf(GRAIN, SWEETCORN), *HOPPERS) { player, used, _ -> + fillHopper(player, used.asItem()) + return@onUseWith true + } + onUseWith(SCENERY, EMPTY_POT, *FLOUR_BINS) { player, _, _ -> + fillPot(player) + return@onUseWith true + } + } + + private fun useHopperControl(player: Player) { + animate(player, ANIMATION) + val hopperContents = getAttribute(player, "milling:hopper", 0) + if (hopperContents == 0) { + sendMessage(player, "You operate the empty hopper. Nothing interesting happens.") + return + } + setAttribute(player, "/save:milling:hopper", 0) + when (hopperContents) { + GRAIN -> { + setAttribute(player, "/save:milling:grain", (getAttribute(player, "milling:grain", 0) + 1).coerceAtMost(30 - getAttribute(player, "milling:sweetcorn", 0))) + sendMessage(player, "You operate the hopper. The grain slides down the chute.") + } + SWEETCORN -> { + setAttribute(player, "/save:milling:sweetcorn", (getAttribute(player, "milling:sweetcorn", 0) + 1).coerceAtMost(30 - getAttribute(player, "milling:grain", 0))) + sendMessage(player, "You operate the hopper. The sweetcorn slides down the chute.") + } + } + playAudio(player, SOUND) + setVarp(player, VARP, 1, true) + } + + private fun fillHopper(player: Player, used: Item) { + if (getAttribute(player, "milling:hopper", 0) == 0 && removeItem(player, used)) { + setAttribute(player, "/save:milling:hopper", used.id) + sendMessage(player, "You put the " + used.name.lowercase() + " in the hopper.") + return + } + sendMessage(player, "There is already " + getItemName(getAttribute(player, "milling:hopper", 0)).lowercase() + " in the hopper.") + } + + private fun fillPot(player: Player) { + if (!inInventory(player, EMPTY_POT)) { + sendMessage(player, "I need an empty pot to hold the flour in.") + return + } + if (removeItem(player, EMPTY_POT)) { + if (getAttribute(player, "milling:sweetcorn", 0) > 0) { + setAttribute(player, "/save:milling:sweetcorn", (getAttribute(player, "milling:sweetcorn", 0) - 1)) + addItem(player, POT_OF_CORNFLOUR) + sendMessage(player, if (player.getAttribute("milling:sweetcorn", 0) > 0) "You fill a pot with cornflour from the bin." else "You fill a pot with the last of the cornflour in the bin.") + } + else if (getAttribute(player, "milling:grain", 0) > 0) { + setAttribute(player, "/save:milling:grain", (getAttribute(player, "milling:grain", 0) - 1)) + addItem(player, POT_OF_FLOUR) + sendMessage(player, if (player.getAttribute("milling:grain", 0) > 0) "You fill a pot with flour from the bin." else "You fill a pot with the last of the flour in the bin.") + } + if (getAttribute(player, "milling:sweetcorn", 0) + getAttribute(player, "milling:grain", 0) <= 0) { + setVarp(player, VARP, 0, true) + } + } + } +} diff --git a/Server/src/main/content/global/handlers/scenery/ModeratorObject.java b/Server/src/main/content/global/handlers/scenery/ModeratorObject.java new file mode 100644 index 0000000..c94f36a --- /dev/null +++ b/Server/src/main/content/global/handlers/scenery/ModeratorObject.java @@ -0,0 +1,45 @@ +package content.global.handlers.scenery; + +import core.cache.def.impl.SceneryDefinition; +import core.game.global.action.ClimbActionHandler; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.info.Rights; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the plugin used for the moderator objects in the p-mod room. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class ModeratorObject extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(26806).getHandlers().put("option:climb-up", this); + SceneryDefinition.forId(26807).getHandlers().put("option:j-mod options", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + switch (option) { + case "climb-up": + ClimbActionHandler.climb(player, new Animation(828), Location.create(3222, 3218, 0)); + break; + case "j-mod options": + if (player.getDetails().getRights() == Rights.REGULAR_PLAYER) { + return true; + } + player.sendMessage("Disabled..."); + break; + } + return true; + } + +} diff --git a/Server/src/main/content/global/handlers/scenery/SearchOptionPlugin.java b/Server/src/main/content/global/handlers/scenery/SearchOptionPlugin.java new file mode 100644 index 0000000..3b2144e --- /dev/null +++ b/Server/src/main/content/global/handlers/scenery/SearchOptionPlugin.java @@ -0,0 +1,92 @@ +package content.global.handlers.scenery; + +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Handles the search option. + * @author 'Vexia + */ +@Initializable +public class SearchOptionPlugin extends OptionHandler { + + /** + * Represents an object to search. + * @author 'Vexia + */ + public enum Search { + /** + * Represents a search. + */ + DEFAULT(-1, new Item(1059, 1)); + + public static Search forId(int id) { + for (Search search : Search.values()) { + if (search.getObject() == id) { + return search; + } + } + return null; + } + + /** + * The object id. + */ + private int object; + + /** + * The item rewarded. + */ + private Item item; + + /** + * Constructs a new {@code SearchOptionPlugin.java} + */ + Search(int object, Item item) { + this.object = object; + this.item = item; + } + + /** + * @return the item. + */ + public Item getItem() { + return item; + } + + /** + * @return the object. + */ + public int getObject() { + return object; + } + } + + @Override + public boolean handle(Player player, Node node, String option) { + if (node.getName().equals("Bookcase")) { + player.getPacketDispatch().sendMessage("You search the books..."); + player.getPacketDispatch().sendMessage("You find nothing of interest to you."); + return true; + } + if (node.getId() == 14743 && !player.getInventory().containItems(946) && !player.inCombat()) { + player.getPacketDispatch().sendMessage("You mindlessly reach into the sack labeled 'knives'..."); + player.getPacketDispatch().sendMessage("Against all odds you pull out a knife without hurting yourself.",2); + player.getInventory().add(new Item(946)); + return true; + } + player.getPacketDispatch().sendMessage("You search the " + node.getName().toLowerCase() + " but find nothing."); + return true; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.setOptionHandler("search", this); + return this; + } +} diff --git a/Server/src/main/content/global/handlers/scenery/SignpostListener.kt b/Server/src/main/content/global/handlers/scenery/SignpostListener.kt new file mode 100644 index 0000000..583aa25 --- /dev/null +++ b/Server/src/main/content/global/handlers/scenery/SignpostListener.kt @@ -0,0 +1,236 @@ +package content.global.handlers.scenery + +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.world.map.Location +import org.rs09.consts.Components +import org.rs09.consts.Scenery + +class SignpostListener : InteractionListener { + override fun defineListeners() { + on(Scenery.SIGNPOST_18493, IntType.SCENERY, "read") { player, node -> + if (node.asScenery().location.equals(Location(3235, 3228))) { + // Authentic + setInterfaceText(player, "Head north towards Fred's farm, and the windmill.", 135, 3) // North + setInterfaceText(player, "South to the swamps of Lumbridge.", 135, 9) // South + setInterfaceText(player, "Cross the bridge and head east to Al Kharid or north to Varrock.", 135, 8) // East + setInterfaceText(player, "West to the Lumbridge Castle and Draynor Village. Beware the goblins!", 135, 12) // West + openInterface(player, Components.AIDE_COMPASS_135) + } else if (node.asScenery().location.equals(Location(3261, 3230))) { + // Authentic + setInterfaceText(player, "North to farms and Varrock.", 135, 3) // North + setInterfaceText(player, "The River Lum lies to the south.", 135, 9) // South + setInterfaceText(player, "East to Al Kharid - toll gate; bring some money.", 135, 8) // East + setInterfaceText(player, "West to Lumbridge.", 135, 12) // West + openInterface(player, Components.AIDE_COMPASS_135) + } else if (node.asScenery().location.equals(Location(2983, 3278))) { + // Authentic + setInterfaceText(player, "North to the glorious White Knights' city of Falador.", 135, 3) // North + setInterfaceText(player, "South to Rimmington.", 135, 9) // South + setInterfaceText(player, "East to Port Sarim and Draynor Village.", 135, 8) // East + setInterfaceText(player, "West to the Crafting Guild.", 135, 12) // West + openInterface(player, Components.AIDE_COMPASS_135) + } else if (node.asScenery().location.equals(Location(3107, 3296))) { + setInterfaceText(player, "North to Draynor Manor.", 135, 3) // North + setInterfaceText(player, "South to Draynor Village and the Wizards' Tower.", 135, 9) // South + setInterfaceText(player, "East to Lumbridge.", 135, 8) // East + setInterfaceText(player, "West to Port Sarim.", 135, 12) // West + openInterface(player, Components.AIDE_COMPASS_135) + } else { + setInterfaceText(player, "North to unknown.", 135, 3) // North + setInterfaceText(player, "South to unknown.", 135, 9) // South + setInterfaceText(player, "East to unknown.", 135, 8) // East + setInterfaceText(player, "West to unknown.", 135, 12) // West + openInterface(player, Components.AIDE_COMPASS_135) + } + return@on true + } + on(Scenery.SIGNPOST_24263, IntType.SCENERY, "read") { player, node -> + if (node.asScenery().location.equals(Location(3268, 3332))) { + // Authentic + setInterfaceText(player, "Sheep lay this way.", 135, 3) // North + setInterfaceText(player, "South through farms to Al Kharid and Lumbridge.", 135, 9) // South + setInterfaceText(player, "East to Al Kharid mine and follow the path north to Varrock east gate.", 135, 8) // East + setInterfaceText(player, "West to Champion's Guild and Varrock south gate.", 135, 12) // West + openInterface(player, Components.AIDE_COMPASS_135) + } else if (node.asScenery().location.equals(Location(3283, 3333))) { + // Authentic + setInterfaceText(player, "North to Varrock mine and Varrock east gate.", 135, 3) // North + setInterfaceText(player, "South to large Mining area and Al Kharid.", 135, 9) // South + setInterfaceText(player, "Follow the path east to the Dig Site.", 135, 8) // East + setInterfaceText(player, "West to Champion's Guild and Varrock south gate.", 135, 12) // West + openInterface(player, Components.AIDE_COMPASS_135) + } else { + setInterfaceText(player, "North to unknown.", 135, 3) // North + setInterfaceText(player, "South to unknown.", 135, 9) // South + setInterfaceText(player, "East to unknown.", 135, 8) // East + setInterfaceText(player, "West to unknown.", 135, 12) // West + openInterface(player, Components.AIDE_COMPASS_135) + } + return@on true + } + on(Scenery.SIGNPOST_4132, IntType.SCENERY, "read") { player, node -> + if (node.asScenery().location.equals(Location(3223, 3427))) { + setInterfaceText(player, "North to Varrock Palace.", 135, 3) // North + setInterfaceText(player, "South to the Champion's Guild.", 135, 9) // South + setInterfaceText(player, "East to the Dig Site.", 135, 8) // East + setInterfaceText(player, "West to Barbarian Village and Falador.", 135, 12) // West + openInterface(player, Components.AIDE_COMPASS_135) + } else if (node.asScenery().location.equals(Location(3166, 3286))) { + setInterfaceText(player, "North to the windmill.", 135, 3) // North + setInterfaceText(player, "South to a fishing pond next to Fred's farm.", 135, 9) // South + setInterfaceText(player, "East to Lumbridge.", 135, 8) // East + setInterfaceText(player, "West to Port Sarim and Draynor Village.", 135, 12) // West + openInterface(player, Components.AIDE_COMPASS_135) + } else if (node.asScenery().location.equals(Location(3285, 3430))) { + setInterfaceText(player, "North to the Lumber Yard.", 135, 3) // North + setInterfaceText(player, "South to Al Kharid and Lumbridge.", 135, 9) // South + setInterfaceText(player, "East to the Dig Site.", 135, 8) // East + setInterfaceText(player, "West to Varrock.", 135, 12) // West + openInterface(player, Components.AIDE_COMPASS_135) + } else if (node.asScenery().location.equals(Location(2734, 3485))) { + setInterfaceText(player, "North to Sinclair Mansion.", 135, 3) // North + setInterfaceText(player, "South to the Courthouse.", 135, 9) // South + setInterfaceText(player, "East to Camelot Castle and Catherby.", 135, 8) // East + setInterfaceText(player, "Follow the path west to Ardougne.", 135, 12) // West + openInterface(player, Components.AIDE_COMPASS_135) + } else if (node.asScenery().location.equals(Location(2604, 3240))) { + setInterfaceText(player, "North to the Ardougne City Zoo.", 135, 3) // North + setInterfaceText(player, "South to the Monastery.", 135, 9) // South + setInterfaceText(player, "East to the Tower of Life.", 135, 8) // East + setInterfaceText(player, "West to the Clocktower.", 135, 12) // West + openInterface(player, Components.AIDE_COMPASS_135) + } else if (node.asScenery().location.equals(Location(2605, 3298))) { + setInterfaceText(player, "North to the Fishing Guild and Hemenster.", 135, 3) // North + setInterfaceText(player, "South to the Ardougne City Zoo.", 135, 9) // South + setInterfaceText(player, "East to Ardougne Market.", 135, 8) // East + setInterfaceText(player, "West to Ardougne Castle and West Ardougne.", 135, 12) // West + openInterface(player, Components.AIDE_COMPASS_135) + } else if (node.asScenery().location.equals(Location(2646, 3404))) { + setInterfaceText(player, "North to the Ranging Guild and Seer's Village.", 135, 3) // North + setInterfaceText(player, "South to the Ardougne City.", 135, 9) // South + setInterfaceText(player, "East to the Sorcerer's Tower.", 135, 8) // East + setInterfaceText(player, "West to the Fishing Guild.", 135, 12) // West + openInterface(player, Components.AIDE_COMPASS_135) + } else { + setInterfaceText(player, "North to unknown.", 135, 3) // North + setInterfaceText(player, "South to unknown.", 135, 9) // South + setInterfaceText(player, "East to unknown.", 135, 8) // East + setInterfaceText(player, "West to unknown.", 135, 12) // West + openInterface(player, Components.AIDE_COMPASS_135) + } + return@on true + } + on(Scenery.SIGNPOST_4134, IntType.SCENERY, "read") { player, node -> + if (node.asScenery().location.equals(Location(2651, 3606))) { + setInterfaceText(player, "North to Rellekka.", 135, 3) // North + setInterfaceText(player, "South to Seers' Village.", 135, 9) // South + setInterfaceText(player, "East to Death Plateau.", 135, 8) // East + setInterfaceText(player, "West to the Lighthouse.", 135, 12) // West + openInterface(player, Components.AIDE_COMPASS_135) + } else if (node.asScenery().location.equals(Location(3100, 3418))) { + setInterfaceText(player, "North to Edgeville.", 135, 3) // North + setInterfaceText(player, "South to Draynor Manor.", 135, 9) // South + setInterfaceText(player, "East to Varrock west gate.", 135, 8) // East + setInterfaceText(player, "West to Barbarian Village.", 135, 12) // West + openInterface(player, Components.AIDE_COMPASS_135) + } else { + setInterfaceText(player, "North to unknown.", 135, 3) // North + setInterfaceText(player, "South to unknown.", 135, 9) // South + setInterfaceText(player, "East to unknown.", 135, 8) // East + setInterfaceText(player, "West to unknown.", 135, 12) // West + openInterface(player, Components.AIDE_COMPASS_135) + } + return@on true + } + on(Scenery.SIGNPOST_4135, IntType.SCENERY, "read") { player, node -> + if (node.asScenery().location.equals(Location(3448, 3486))) { + setInterfaceText(player, "North to the Slayer Tower.", 135, 3) // North + setInterfaceText(player, "South to Mort Myre Swamp.", 135, 9) // South + setInterfaceText(player, "East to Canifis.", 135, 8) // East + setInterfaceText(player, "West to Varrock.", 135, 12) // West + openInterface(player, Components.AIDE_COMPASS_135) + } else { + setInterfaceText(player, "North to unknown.", 135, 3) // North + setInterfaceText(player, "South to unknown.", 135, 9) // South + setInterfaceText(player, "East to unknown.", 135, 8) // East + setInterfaceText(player, "West to unknown.", 135, 12) // West + openInterface(player, Components.AIDE_COMPASS_135) + } + return@on true + } + on(Scenery.SIGNPOST_31296, IntType.SCENERY, "read") { player, node -> + if (node.asScenery().location.equals(Location(3304, 3109))) { + // Authentic + setInterfaceText(player, "North to Al Kharid.", 135, 3) // North + setInterfaceText(player, "South to the Desert Mining Camp and Pollnivneach.", 135, 9) // South + setInterfaceText(player, "East and across the river to the Ruins of Uzer.", 135, 8) // East + setInterfaceText(player, "West to the Kalphite Lair.", 135, 12) // West + openInterface(player, Components.AIDE_COMPASS_135) + } else { + setInterfaceText(player, "North to unknown.", 135, 3) // North + setInterfaceText(player, "South to unknown.", 135, 9) // South + setInterfaceText(player, "East to unknown.", 135, 8) // East + setInterfaceText(player, "West to unknown.", 135, 12) // West + openInterface(player, Components.AIDE_COMPASS_135) + } + return@on true + } + on(Scenery.STONE_SIGNPOST_11630, IntType.SCENERY, "read") { player, node -> + // Authentic // https://youtu.be/vvHXKTOh_g4 + if (node.asScenery().location.equals(Location(2967, 3412))) { + setInterfaceText(player, "North to Goblin Village.", 135, 3) // North + setInterfaceText(player, "South to Falador.", 135, 9) // South + setInterfaceText(player, "East to Varrock.", 135, 8) // East + setInterfaceText(player, "West to Taverley.", 135, 12) // West + openInterface(player, Components.AIDE_COMPASS_135) + } else { + setInterfaceText(player, "North to unknown.", 135, 3) // North + setInterfaceText(player, "South to unknown.", 135, 9) // South + setInterfaceText(player, "East to unknown.", 135, 8) // East + setInterfaceText(player, "West to unknown.", 135, 12) // West + openInterface(player, Components.AIDE_COMPASS_135) + } + return@on true + } + } + /** + * Old handlers of Signpost. Not all should be opening the AIDE_COMPASS. + * + * @Override + * public Plugin newInstance(Object arg) throws Throwable { + * SceneryDefinition.forId(4132).getHandlers().put("option:read", this); + * SceneryDefinition.forId(4133).getHandlers().put("option:read", this); + * SceneryDefinition.forId(4134).getHandlers().put("option:read", this); + * SceneryDefinition.forId(4135).getHandlers().put("option:read", this); + * SceneryDefinition.forId(5164).getHandlers().put("option:read", this); + * SceneryDefinition.forId(10090).getHandlers().put("option:read", this); + * SceneryDefinition.forId(13873).getHandlers().put("option:read", this); + * SceneryDefinition.forId(15522).getHandlers().put("option:read", this); + * SceneryDefinition.forId(25397).getHandlers().put("option:read", this); + * SceneryDefinition.forId(30039).getHandlers().put("option:read", this); + * SceneryDefinition.forId(30040).getHandlers().put("option:read", this); + * SceneryDefinition.forId(31296).getHandlers().put("option:read", this); + * SceneryDefinition.forId(31298).getHandlers().put("option:read", this); + * SceneryDefinition.forId(31299).getHandlers().put("option:read", this); + * SceneryDefinition.forId(31300).getHandlers().put("option:read", this); + * // ObjectDefinition.forId(31301).getConfigurations().put("option:read", this);//goblin village + * return this; + * } + * + * Was technically supposed to hide the map + * @Override + * public boolean handle(Player player, Node node, String option) { + * PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 2)); + * player.getInterfaceManager().open(new Component(135)).setCloseEvent(new CloseEvent() { + * @Override + * public boolean close(Player player, Component c) { + * PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 0)); + * return true; + * } + * }); + * return true; + * } + */ +} \ No newline at end of file diff --git a/Server/src/main/content/global/handlers/scenery/SlashWebPlugin.java b/Server/src/main/content/global/handlers/scenery/SlashWebPlugin.java new file mode 100644 index 0000000..70ea510 --- /dev/null +++ b/Server/src/main/content/global/handlers/scenery/SlashWebPlugin.java @@ -0,0 +1,151 @@ +package content.global.handlers.scenery; + +import core.cache.def.impl.SceneryDefinition; +import core.game.container.Container; +import core.game.container.impl.EquipmentContainer; +import core.plugin.Initializable; +import org.rs09.consts.Items; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.combat.equipment.WeaponInterface.AttackStyle; +import core.game.node.entity.combat.equipment.WeaponInterface.WeaponInterfaces; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; +import core.tools.RandomFunction; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playAudio; + +/** + * Handles the slashing of a web object. + * @author Vexia + * @version 2.0 + */ +@Initializable +public final class SlashWebPlugin extends OptionHandler { + + /** + * Represents the object ids. + */ + private static final int[] IDS = new int[] { 733, 1810, 11400, 33237 }; + + /** + * Represents the animation of slashing a web. + */ + private static final Animation ANIMATION = new Animation(451); + + /** + * Represents the knife animation. + */ + private static final Animation KNIFE_ANIMATION = new Animation(911); + + /** + * Represents the knife item. + */ + private static final Item KNIFE = new Item(946); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (int objectId : IDS) { + SceneryDefinition.forId(objectId).getHandlers().put("option:slash", this); + } + SceneryDefinition.forId(27266).getHandlers().put("option:pass", this); + SceneryDefinition.forId(29354).getHandlers().put("option:pass", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + final Scenery object = (Scenery) node; + Item weapon = getWeapon(player, player.getEquipment()); + if (weapon == null) { + weapon = getWeapon(player, player.getInventory()); + if (weapon == null) { + if (!player.getInventory().containsItem(KNIFE)) { + player.getPacketDispatch().sendMessage("Only a sharp blade can cut through this sticky web."); + return true; + } + weapon = KNIFE; + } + } + final boolean success = RandomFunction.random(2) == 1; + player.lock(2); + playAudio(player, Sounds.STABSWORD_SLASH_2548); + player.animate(weapon == KNIFE ? KNIFE_ANIMATION : ANIMATION); + if (success) { + player.getPacketDispatch().sendMessage("You slash the web apart."); + SceneryBuilder.replace(object, object.getId() == 27266 || object.getId() == 29354 ? object.transform(734) : object.transform(object.getId() + 1), 100); + + // Venture through the cobwebbed corridor in Varrock Sewers + if (object.getId() == 29354) { + player.getAchievementDiaryManager().finishTask(player, DiaryType.VARROCK, 0, 17); + } + // Escape from the spider lair in Varrock Sewers with some red

spiders eggs + if (object.getId() == 29354 && player.getInventory().containsAtLeastOneItem(Items.RED_SPIDERS_EGGS_223) && player.getLocation().getY() <= 9897) { + player.getAchievementDiaryManager().finishTask(player, DiaryType.VARROCK, 1, 4); + } + } else { + player.getPacketDispatch().sendMessage("You fail to cut through it."); + } + return true; + } + + /** + * Gets the slashed weapon item. + * @param player the player. + * @param container the container. + * @return the item. + */ + private Item getWeapon(final Player player, final Container container) { + Item item = container instanceof EquipmentContainer ? container.get(EquipmentContainer.SLOT_WEAPON) : null; + if (container instanceof EquipmentContainer) { + return checkEquipmentWeapon(player, item); + } + for (Item i : container.toArray()) { + if (i == null) { + continue; + } + if (i.getDefinition().hasAction("wield") || i.getDefinition().hasAction("equip")) { + item = checkEquipmentWeapon(player, i); + if (item != null) { + return item; + } + } else { + continue; + } + } + return item; + } + + /** + * Checks an equipment weapon. + * @param player the player. + * @param item the item. + * @return {@code Item} the item. + */ + private Item checkEquipmentWeapon(final Player player, final Item item) { + if (item != null) { + WeaponInterfaces inter = WeaponInterface.getWeaponInterface(item); + if (inter == null) { + return null; + } + boolean success = false; + for (AttackStyle style : inter.getAttackStyles()) { + if (style.getBonusType() == WeaponInterface.BONUS_SLASH) { + return item; + } + } + if (!success) { + return null; + } + } + return item; + } + +} diff --git a/Server/src/main/content/global/handlers/scenery/SlayerDangerSignPlugin.java b/Server/src/main/content/global/handlers/scenery/SlayerDangerSignPlugin.java new file mode 100644 index 0000000..9bc9089 --- /dev/null +++ b/Server/src/main/content/global/handlers/scenery/SlayerDangerSignPlugin.java @@ -0,0 +1,28 @@ +package content.global.handlers.scenery; + +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * @author 'Vexia + */ +@Initializable +public class SlayerDangerSignPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(5127).getHandlers().put("option:read", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + player.getDialogueInterpreter().sendDialogue("WARNING!", "This area contains very dangerous creatures!", "Do not pass unless properly prepared!"); + return true; + } + +} diff --git a/Server/src/main/content/global/handlers/scenery/SpinSpinningWheelPlugin.java b/Server/src/main/content/global/handlers/scenery/SpinSpinningWheelPlugin.java new file mode 100644 index 0000000..3395518 --- /dev/null +++ b/Server/src/main/content/global/handlers/scenery/SpinSpinningWheelPlugin.java @@ -0,0 +1,45 @@ +package content.global.handlers.scenery; + +import core.cache.def.impl.SceneryDefinition; +import core.game.component.Component; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Handles the spining interface open. + * @author Adam + */ +@Initializable +public class SpinSpinningWheelPlugin extends OptionHandler { + + @Override + public boolean handle(Player player, Node node, String option) { + player.getInterfaceManager().open(new Component(459)); + return true; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(2644).getHandlers().put("option:spin", this); + SceneryDefinition.forId(4309).getHandlers().put("option:spin", this); + SceneryDefinition.forId(8748).getHandlers().put("option:spin", this); + SceneryDefinition.forId(20365).getHandlers().put("option:spin", this); + SceneryDefinition.forId(21304).getHandlers().put("option:spin", this); + SceneryDefinition.forId(25824).getHandlers().put("option:spin", this); + SceneryDefinition.forId(26143).getHandlers().put("option:spin", this); + SceneryDefinition.forId(34497).getHandlers().put("option:spin", this); + SceneryDefinition.forId(36970).getHandlers().put("option:spin", this); + SceneryDefinition.forId(37476).getHandlers().put("option:spin", this); + return this; + } + + @Override + public Location getDestination(Node node, Node n) { + return null; + } + +} diff --git a/Server/src/main/content/global/handlers/scenery/ThievingGuidePlugin.java b/Server/src/main/content/global/handlers/scenery/ThievingGuidePlugin.java new file mode 100644 index 0000000..71efac4 --- /dev/null +++ b/Server/src/main/content/global/handlers/scenery/ThievingGuidePlugin.java @@ -0,0 +1,189 @@ +package content.global.handlers.scenery; + +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.combat.ImpactHandler.HitsplatType; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.Player; +import core.game.node.entity.skill.Skills; +import core.game.node.item.ChanceItem; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.tools.RandomFunction; +import core.game.world.GameWorld; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Represents the thieving guide plugin. + * @author 'Vexia + * @date 16/11/2013 + */ +@Initializable +public class ThievingGuidePlugin extends OptionHandler { + + /** + * The coin looots. + */ + private static final ChanceItem[] COINS = new ChanceItem[] { new ChanceItem(995, 20, 20, 90), new ChanceItem(995, 40, 40, 80) }; + + /** + * The gem items. + */ + private static final ChanceItem[] GEMS = new ChanceItem[] { new ChanceItem(1623, 1, 1, 80), new ChanceItem(1621, 1, 1, 60), new ChanceItem(1619, 1, 1, 8), new ChanceItem(1617, 1, 1, 7) }; + + /** + * Represents the stethoscope item. + */ + private static final Item SETHOSCOPE = new Item(5560); + + /** + * Represents the required level to crack a safe. + */ + private static final int level = 50; + + /** + * Represents the experience gained. + */ + private static final double experience = 70; + + /** + * Represents the animations to use. + */ + private static final Animation[] animations = new Animation[] { new Animation(2247), new Animation(2248), new Animation(1113), new Animation(2244) }; + + /** + * Represents the cracked safe. + */ + private static final int CRACKED_SAFE = 7238; + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(7236).getHandlers().put("option:crack", this);// wall + // safe. + SceneryDefinition.forId(7227).getHandlers().put("option:disarm", this);// trap + SceneryDefinition.forId(7256).getHandlers().put("option:open", this); + return this; + } + + @Override + public boolean handle(final Player player, final Node node, String option) { + switch (option) { + case "open": + player.getDialogueInterpreter().sendDialogues(2266, null, "And where do you think you're going? A little too eager", "I think. Come and talk to me before you go wandering", "around in there."); + break; + case "crack": + if (player.getSkills().getLevel(Skills.THIEVING) < 50) { + player.getPacketDispatch().sendMessage("You need to be level " + level + " thief to crack this safe."); + return true; + } + if (player.getInventory().freeSlots() == 0) { + player.getPacketDispatch().sendMessage("Not enough inventory space."); + return true; + } + final boolean success = success(player, Skills.THIEVING); + player.lock(4); + player.getPacketDispatch().sendMessage("You start cracking the safe."); + player.animate(animations[success ? 1 : 0]); + GameWorld.getPulser().submit(new Pulse(3, player) { + @Override + public boolean pulse() { + if (success) { + handleSuccess(player, (Scenery) node); + return true; + } + final boolean trapped = RandomFunction.random(3) == 1; + if (trapped) { + player.getPacketDispatch().sendMessage("You slip and trigger a trap!"); + player.animate(animations[2]); + player.getImpactHandler().manualHit(player, RandomFunction.random(2, 6), HitsplatType.NORMAL); + GameWorld.getPulser().submit(new Pulse(1) { + @Override + public boolean pulse() { + player.animate(new Animation(-1, Priority.HIGH)); + return true; + } + }); + } + return true; + } + }); + break; + case "search": + player.animate(animations[3]); + player.getPacketDispatch().sendMessage("You temporarily disarm the trap!"); + break; + } + return true; + } + + /** + * Handles the success. + * @param player the player. + * @param object the object. + */ + public void handleSuccess(final Player player, final Scenery object) { + SceneryBuilder.replace(object, object.transform(CRACKED_SAFE), 1); + player.getPacketDispatch().sendMessage("You get some loot."); + player.getSkills().addExperience(Skills.THIEVING, experience, true); + addItem(player); + } + + /** + * Adds an item. + * @param player the player. + */ + private void addItem(Player player) { + ChanceItem[] l = RandomFunction.random(2) == 1 ? GEMS : COINS; + List chances = new ArrayList<>(20); + for (ChanceItem c : l) { + chances.add(c); + } + Collections.shuffle(chances); + int rand = RandomFunction.random(100); + Item item = null; + int tries = 0; + while (item == null) { + ChanceItem i = chances.get(0); + if (rand <= i.getChanceRate()) { + item = i; + break; + } + if (tries > chances.size()) { + if (i.getId() == 1617) { + item = COINS[0]; + break; + } + item = i; + break; + } + tries++; + } + player.getInventory().add(item); + } + + /** + * Method used to determine the success of a player when thieving. + * @param player the player. + * @return True if succesfull, False if not. + */ + public final boolean success(final Player player, final int skill) { + double level = player.getSkills().getLevel(skill); + double req = 50; + int mod = player.getInventory().containsItem(SETHOSCOPE) ? 8 : 17; + double successChance = Math.ceil((level * 50 - req * mod) / req / 3 * 4); + int roll = RandomFunction.random(99); + if (successChance >= roll) { + return true; + } + return false; + } +} diff --git a/Server/src/main/content/global/skill/AttackListener.kt b/Server/src/main/content/global/skill/AttackListener.kt new file mode 100644 index 0000000..cba5a7e --- /dev/null +++ b/Server/src/main/content/global/skill/AttackListener.kt @@ -0,0 +1,24 @@ +package content.global.skill + +import core.game.node.entity.combat.CombatStyle +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +class AttackListener : InteractionListener { + override fun defineListeners() { + flagInstant() + on(IntType.NPC, "attack"){ player, npc -> + //Makes sure player uses correct attack styles for lumbridge dummies + if (npc.id == 4474 && player.getSwingHandler(false).type != CombatStyle.MAGIC) { + player.sendMessage("You can only attack this with magic.") + return@on true + } + if (npc.id == 7891 && player.getSwingHandler(false).type != CombatStyle.MELEE) { + player.sendMessage("You must use the training sword to attack this.") + return@on true + } + player.attack(npc) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/agility/AgilityCourse.java b/Server/src/main/content/global/skill/agility/AgilityCourse.java new file mode 100644 index 0000000..9f914ae --- /dev/null +++ b/Server/src/main/content/global/skill/agility/AgilityCourse.java @@ -0,0 +1,158 @@ +package content.global.skill.agility; + +import core.game.node.entity.skill.Skills; +import core.game.interaction.OptionHandler; +import core.game.node.entity.player.Player; +import core.plugin.Plugin; + +/** + * Represents an agility course. + * @author Emperor + */ +public abstract class AgilityCourse extends OptionHandler { + + /** + * The player doing the agility course. + */ + private final Player player; + + /** + * The obstacles the player has already passed. + */ + private final boolean[] obstaclesPassed; + + /** + * The completion experience. + */ + private double completionExperience; + + /** + * Constructs a new {@code AgilityCourse} {@code Object}. + * @param player The player. + * @param size The amount of obstacles in the course. + * @param completionExperience The amount of experience to gain upon + * completing the course. + */ + public AgilityCourse(Player player, int size, double completionExperience) { + this.player = player; + this.obstaclesPassed = new boolean[size]; + this.completionExperience = completionExperience; + } + + @Override + public final Plugin newInstance(Object arg) throws Throwable { + if (arg == null) { + configure(); + return this; + } + return createInstance((Player) arg); + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + /** + * Configures the course. + */ + public abstract void configure(); + + /** + * Creates a new instance for the player. + * @param player The player. + * @return The agility course instance. + */ + public abstract AgilityCourse createInstance(Player player); + + /** + * Gets the agility course for the given player. If the player didn't have + * the course as an extension, an extension will be added. + * @param player The player. + * @return The agility course instance. + */ + public AgilityCourse getCourse(Player player) { + AgilityCourse course = player.getExtension(AgilityCourse.class); + if (course == null || course.getClass() != getClass()) { + try { + player.addExtension(AgilityCourse.class, course = createInstance(player)); + } catch (Throwable e) { + e.printStackTrace(); + } + } + return course; + } + + /** + * Finishes the lap by checking for completion and resetting. + */ + public void finish() { + if (isCompleted()) { + player.getSkills().addExperience(Skills.AGILITY, completionExperience, true); + } + reset(); + } + + /** + * Checks if the course has been completed. + * @return {@code True} if so. + */ + public boolean isCompleted() { + for (int i = 0; i < obstaclesPassed.length; i++) { + if (!obstaclesPassed[i]) { + return false; + } + } + return true; + } + + /** + * Resets the currently passed obstacles in the course. + */ + public void reset() { + for (int i = 0; i < obstaclesPassed.length; i++) { + obstaclesPassed[i] = false; + } + } + + /** + * Flags an obstacles as passed. + * @param index The obstacle index. + */ + public void flag(int index) { + obstaclesPassed[index] = true; + if (index == obstaclesPassed.length - 1) { + finish(); + } + } + + /** + * Gets the amount of damage to deal. + * @param player The player. + * @return The amount of damage. + */ + protected static int getHitAmount(Player player) { + int hit = player.getSkills().getLifepoints() / 12; + if (hit < 2) { + hit = 2; + } + return hit; + } + + /** + * Gets the player. + * @return The player. + */ + public Player getPlayer() { + return player; + } + + /** + * Gets the passed obstacles flags. + * @return The passed obstacles flags. + */ + public boolean[] getPassedObstacles() { + return obstaclesPassed; + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/agility/AgilityHandler.java b/Server/src/main/content/global/skill/agility/AgilityHandler.java new file mode 100644 index 0000000..722de4a --- /dev/null +++ b/Server/src/main/content/global/skill/agility/AgilityHandler.java @@ -0,0 +1,323 @@ +package content.global.skill.agility; + +import static core.api.ContentAPIKt.*; + +import core.game.node.entity.impl.PulseType; +import core.game.node.entity.player.link.TeleportManager; +import core.game.node.entity.skill.Skills; +import core.game.interaction.MovementPulse; +import core.game.node.entity.combat.ImpactHandler.HitsplatType; +import core.game.node.entity.impl.ForceMovement; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import kotlin.Unit; +import core.game.world.GameWorld; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; + +/** + * Holds agility-related utility methods. + * @author Emperor + */ +public final class AgilityHandler { + + /** + * Checks if the player has failed crossing an obstacle. + * @param player The player. + * @param level The level requirement for the obstacle. + * @param failChance The chance of failing (0.0 - 0.99). + * @return {@code True} if the player has failed. + */ + public static boolean hasFailed(Player player, int level, double failChance) { + int levelDiff = player.getSkills().getLevel(Skills.AGILITY) - level; + if (levelDiff > 69) { + return false; + } + double chance = (1 + levelDiff) * 0.01; + chance *= Math.random(); + return chance <= (Math.random() * failChance); + } + + /** + * Handles failing an obstacle (by using force movement). + * @param player The player. + * @param delay The amount of ticks before teleporting to the destination + * and hitting. + * @param start The start location. + * @param end The end location. + * @param dest The destination. + * @param anim The animation. + * @param hit The amount of damage to hit. + * @param message The message to send. + */ + public static ForceMovement failWalk(final Player player, int delay, Location start, Location end, final Location dest, Animation anim, int speed, final int hit, final String message, Direction direction) { + ForceMovement movement = new ForceMovement(player, start, end, anim, speed) { + @Override + public void stop() { + super.stop(); + player.getProperties().setTeleportLocation(dest); + if (hit > 0) { + player.getImpactHandler().setDisabledTicks(0); + impact(player, hit, HitsplatType.NORMAL); + } + if (message != null) { + player.getPacketDispatch().sendMessage(message); + } + } + }; + if (direction != null) { + movement.setDirection(direction); + } + movement.start(); + movement.setDelay(delay); + GameWorld.getPulser().submit(movement); + return movement; + } + + /** + * Handles failing an obstacle (by using force movement). + * @param player The player. + * @param delay The amount of ticks before teleporting to the destination + * and hitting. + * @param start The start location. + * @param end The end location. + * @param dest The destination. + * @param anim The animation. + * @param hit The amount of damage to hit. + * @param message The message to send. + */ + public static ForceMovement failWalk(final Player player, int delay, Location start, Location end, final Location dest, Animation anim, int speed, final int hit, final String message) { + return failWalk(player, delay, start, end, dest, anim, speed, hit, message, null); + } + + /** + * Handles failing an obstacle. + * @param player The player. + * @param delay The amount of ticks before teleporting to the destination + * and hitting. + * @param dest The destination. + * @param anim The animation. + * @param hit The amount of damage to hit. + * @param message The message to send. + */ + public static void fail(final Player player, int delay, final Location dest, Animation anim, final int hit, final String message) { + if (anim != null) { + animate(player, anim, true); + submitWorldPulse(new Pulse(animationDuration(anim), player) { + boolean dmg = false; + + @Override + public boolean pulse() { + teleport(player, dest, TeleportManager.TeleportType.INSTANT); + animate(player, Animation.RESET, true); + if (!dmg) { + if (hit > 0) { + player.getImpactHandler().setDisabledTicks(0); + impact(player, hit, HitsplatType.NORMAL); + } + if (message != null) { + sendMessage(player, message); + } + dmg = true; + } + setDelay(0); + return player.getLocation().equals(dest); + } + }); + } + } + + /** + * Walks across an obstacle using the force movement update mask. + * @param start The start location. + * @param end The end location. + * @param animation The animation. + * @param speed The force movement speed. + * @param experience The amount of agility experience to give as reward. + * @param message The message to send upon completion. + * @return The force movement instance, if force movement is used. + */ + public static ForceMovement forceWalk(final Player player, final int courseIndex, Location start, Location end, Animation animation, int speed, final double experience, final String message) { + player.logoutListeners.put("forcewalk", p -> { + p.setLocation(player.getLocation().transform(0,0,0)); + return Unit.INSTANCE; + }); + lock(player, ((int) start.getDistance(end)) * 3); + ForceMovement movement = new ForceMovement(player, start, end, animation, speed) { + @Override + public void stop() { + super.stop(); + if (message != null) { + player.getPacketDispatch().sendMessage(message); + } + if (experience > 0.0) { + player.getSkills().addExperience(Skills.AGILITY, experience, true); + } + setObstacleFlag(player, courseIndex); + player.logoutListeners.remove("forcewalk"); + } + }; + movement.start(); + GameWorld.getPulser().submit(movement); + return movement; + } + + /** + * Walks across an obstacle using the force movement update mask. + * @param start The start location. + * @param end The end location. + * @param animation The animation. + * @param speed The force movement speed. + * @param experience The amount of agility experience to give as reward. + * @param message The message to send upon completion. + * @return The force movement instance, if force movement is used. + */ + public static ForceMovement forceWalk(final Player player, final int courseIndex, Location start, Location end, Animation animation, int speed, final double experience, final String message, int delay) { + player.logoutListeners.put("forcewalk", p -> { + p.setLocation(player.getLocation().transform(0,0,0)); + return Unit.INSTANCE; + }); + lock(player, ((int) start.getDistance(end)) * 3); + if (delay < 1) { + return forceWalk(player, courseIndex, start, end, animation, speed, experience, message); + } + final ForceMovement movement = new ForceMovement(player, start, end, animation, speed) { + @Override + public void stop() { + super.stop(); + if (message != null) { + player.getPacketDispatch().sendMessage(message); + } + if (experience > 0.0) { + player.getSkills().addExperience(Skills.AGILITY, experience, true); + } + setObstacleFlag(player, courseIndex); + player.logoutListeners.remove("forcewalk"); + } + }; + GameWorld.getPulser().submit(new Pulse(delay, player) { + @Override + public boolean pulse() { + movement.start(); + GameWorld.getPulser().submit(movement); + return true; + } + }); + return movement; + } + + /** + * Executes the climbing reward. + * @param player The player. + * @param animation The climbing animation. + * @param destination The destination. + * @param experience The amount of agility experience to give as reward. + * @param message The message to send upon completion. + */ + public static void climb(final Player player, final int courseIndex, Animation animation, final Location destination, final double experience, final String message) { + climb(player, courseIndex, animation, destination, experience, message, 2); + } + + /** + * Executes the climbing reward. + * @param player The player. + * @param animation The climbing animation. + * @param destination The destination. + * @param experience The amount of agility experience to give as reward. + * @param message The message to send upon completion. + */ + public static void climb(final Player player, final int courseIndex, Animation animation, final Location destination, final double experience, final String message, int delay) { + player.lock(delay + 1); + player.animate(animation); + GameWorld.getPulser().submit(new Pulse(delay) { + @Override + public boolean pulse() { + if (message != null) { + player.getPacketDispatch().sendMessage(message); + } + if (experience > 0.0) { + player.getSkills().addExperience(Skills.AGILITY, experience, true); + } + player.getProperties().setTeleportLocation(destination); + setObstacleFlag(player, courseIndex); + return true; + } + }); + } + + public static void walk(final Player player, final int courseIndex, final Location start, final Location end, final Animation animation, final double experience, final String message){ + walk(player,courseIndex,start,end,animation,experience,message,false); + } + + /** + * Uses the walking queue to walk across an obstacle. + * @param player The player. + * @param courseIndex The obstacle index for the course, {@code -1} if no + * course. + * @param start The start location. + * @param end The end location. + * @param animation The animation. + * @param experience The agility experience. + * @param message The message to send upon completion. + */ + public static void walk(final Player player, final int courseIndex, final Location start, final Location end, final Animation animation, final double experience, final String message, final boolean infiniteRun) { + if (!player.getLocation().equals(start)) { + player.getPulseManager().run(new MovementPulse(player, start) { + @Override + public boolean pulse() { + walk(player, courseIndex, start, end, animation, experience, message, infiniteRun); + return true; + } + }, PulseType.STANDARD); + return; + } + player.getWalkingQueue().reset(); + player.getWalkingQueue().addPath(end.getX(), end.getY(), !infiniteRun); + int ticks = player.getWalkingQueue().getQueue().size(); + player.getImpactHandler().setDisabledTicks(ticks); + player.lock(1 + ticks); + player.logoutListeners.put("agility", p -> { + p.setLocation(start); + return Unit.INSTANCE; + }); + if (animation != null) { + player.getAppearance().setAnimations(animation); + } + player.getSettings().setRunEnergy(100.0); + GameWorld.getPulser().submit(new Pulse(ticks, player) { + @Override + public boolean pulse() { + if (animation != null) { + player.getAppearance().setAnimations(); + player.getAppearance().sync(); + } + if (message != null) { + player.getPacketDispatch().sendMessage(message); + } + if (experience > 0.0) { + player.getSkills().addExperience(Skills.AGILITY, experience, true); + } + setObstacleFlag(player, courseIndex); + player.logoutListeners.remove("agility"); + return true; + } + }); + } + + /** + * Sets the obstacle flag for the agility course. + * @param player The player. + * @param courseIndex The course index. + */ + public static void setObstacleFlag(Player player, int courseIndex) { + if (courseIndex < 0) { + return; + } + AgilityCourse course = player.getExtension(AgilityCourse.class); + if (course != null && courseIndex < course.getPassedObstacles().length) { + course.flag(courseIndex); + } + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/agility/AgilityShortcut.java b/Server/src/main/content/global/skill/agility/AgilityShortcut.java new file mode 100644 index 0000000..bd7fae7 --- /dev/null +++ b/Server/src/main/content/global/skill/agility/AgilityShortcut.java @@ -0,0 +1,228 @@ +package content.global.skill.agility; + +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.plugin.Plugin; +import core.game.node.entity.skill.Skills; + +/** + * Handles an agility shortcut. + * @author Woah + */ +public abstract class AgilityShortcut extends OptionHandler { + + /** + * The ids used for this shortcut. + */ + private final int[] ids; + + /** + * The level required. + */ + private final int level; + + /** + * The experience required. + */ + private final double experience; + + /** + * If the player can fail this shortcut. + */ + private final boolean canFail; + + /** + * The chance to fail. + */ + private double failChance; + + /** + * The options for the shortcut. + */ + private final String[] options; + + /** + * Constructs a new {@Code AgilityShortcut} {@Code Object} + * @param ids the ids. + * @param level the level. + * @param experience the experience. + * @param canFail if this shortcut can be failed. + * @param failChance the chance to fail + * @param options the options. + */ + public AgilityShortcut(int[] ids, int level, double experience, boolean canFail, double failChance, String... options) { + this.ids = ids; + this.level = level; + this.experience = experience; + this.canFail = canFail; + this.failChance = failChance; + this.options = options; + } + + /** + * Constructs a new {@Code AgilityShortcut} {@Code Object} + * @param ids the ids. + * @param level the level. + * @param experience the experience. + * @param options the options. + */ + public AgilityShortcut(int[] ids, int level, double experience, String... options) { + this(ids, level, experience, false, 0.0, options); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + configure(this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + if (!checkRequirements(player)) { + return true; + } + run(player, node.asScenery(), option, checkFail(player, node.asScenery(), option)); + return true; + } + + /** + * Runs the agility reward for the short cut. + * @param player the player. + * @param object the object. + * @param option the option. + * @param failed the shortcut failed. + */ + public abstract void run(Player player, Scenery object, String option, boolean failed); + + /** + * Checks the requirements for a player. + * @param player the player. + * @return {@code True} if so. + */ + public boolean checkRequirements(Player player) { + if (player.getSkills().getLevel(Skills.AGILITY) < level) { + player.getDialogueInterpreter().sendDialogue("You need an Agility level of at least " + level + " to negotiate this obstacle."); + return false; + } + return true; + } + + /** + * Checks if the player failed the shortcut. + * @param player the player. + * @param object the object. + * @param option2 the option. + * @return {@code True} if failed. + */ + private boolean checkFail(Player player, Scenery object, String option2) { + if (!canFail) { + return false; + } + return AgilityHandler.hasFailed(player, level, failChance); + } + + /** + * Configures this shortcut. + */ + public void configure(AgilityShortcut shortcut) { + for (int objectId : shortcut.ids) { + SceneryDefinition def = SceneryDefinition.forId(objectId); + for (String option : shortcut.options) { + def.getHandlers().put("option:" + option, shortcut); + } + } + } + + /** + * Gets the proper object direction. + * @param direction the direction. + * @return the direction. + */ + protected Direction getObjectDirection(Direction direction) { + return direction == Direction.NORTH ? Direction.EAST : direction == Direction.SOUTH ? Direction.WEST : direction == Direction.EAST ? Direction.NORTH : Direction.SOUTH; + } + + + public Location pipeDestination(Player player, Scenery object, int steps) { + player.faceLocation(object.getLocation()); + int diffX = object.getLocation().getX() - player.getLocation().getX(); + if (diffX < -1) { diffX = -1; } + if (diffX > 1) { diffX = 1; } + int diffY = object.getLocation().getY() - player.getLocation().getY(); + if (diffY < -1) { diffY = -1; } + if (diffY > 1) { diffX = 1; } + Location dest = player.getLocation().transform((diffX) * steps, (diffY) * steps, 0); + return dest; + } + + public Location agilityDestination(Player player, Scenery object, int steps) { + player.faceLocation(object.getLocation()); + int diffX = object.getLocation().getX() - player.getLocation().getX(); + int diffY = object.getLocation().getY() - player.getLocation().getY(); + Location dest = player.getLocation().transform((diffX) * steps, (diffY) * steps, 0); + return dest; + } + + + /** + * Gets the level. + * @return the level + */ + public int getLevel() { + return level; + } + + /** + * Gets the experience. + * @return the experience + */ + public double getExperience() { + return experience; + } + + /** + * Gets the canFail. + * @return the canFail + */ + public boolean isCanFail() { + return canFail; + } + + /** + * Gets the failChance. + * @return the failChance + */ + public double getFailChance() { + return failChance; + } + + /** + * Sets the bafailChance. + * @param failChance the failChance to set. + */ + public void setFailChance(double failChance) { + this.failChance = failChance; + } + + /** + * Gets the ids. + * @return the ids + */ + public int[] getIds() { + return ids; + } + + /** + * Gets the option. + * @return the option + */ + public String[] getOption() { + return options; + } + +} diff --git a/Server/src/main/content/global/skill/agility/BarbarianOutpostCourse.kt b/Server/src/main/content/global/skill/agility/BarbarianOutpostCourse.kt new file mode 100644 index 0000000..0e4a36f --- /dev/null +++ b/Server/src/main/content/global/skill/agility/BarbarianOutpostCourse.kt @@ -0,0 +1,343 @@ +package content.global.skill.agility + +import core.api.* +import core.cache.def.impl.ItemDefinition +import core.cache.def.impl.NPCDefinition +import core.cache.def.impl.SceneryDefinition +import content.region.kandarin.barcrawl.BarcrawlManager +import core.game.node.Node +import core.game.node.scenery.Scenery +import core.game.node.entity.combat.ImpactHandler.HitsplatType +import core.game.node.entity.player.Player +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import core.plugin.Initializable +import core.game.world.GameWorld +import core.plugin.ClassScanner + +/** + * Handles the barbarian outpost course. + * @author Woah + * + */ +@Initializable +class BarbarianOutpostCourse + +/** + * Constructs a new `BarbarianOutpostCourse` `Object`. + * @param player the player. + */ +@JvmOverloads constructor(player: Player? = null) : AgilityCourse(player, 6, 46.2) { + override fun createInstance(player: Player): AgilityCourse { + return BarbarianOutpostCourse(player) + } + + override fun handle(player: Player, node: Node, option: String): Boolean { + val id = node.id + getCourse(player) + when (id) { + 2115, 2116 -> if (!BarcrawlManager.getInstance(player).isFinished || BarcrawlManager.getInstance(player).isStarted) { + player.dialogueInterpreter.open(384) + } else { + core.game.global.action.DoorActionHandler.handleAutowalkDoor(player, node as Scenery) + } + 2282 -> handleRopeSwing(player, node as Scenery) + 2294 -> handleLogBalance(player, node as Scenery) + 2302 -> handleLedgeBalance(player, node as Scenery) + 20211 -> { + if (player.location.x < node.location.x) { + return true + } + AgilityHandler.climb(player, 2, core.game.global.action.ClimbActionHandler.CLIMB_UP, player.location.transform(-1, 0, 1), 8.0, "You climb the netting...") + } + 1948 -> { + if (player.location.x > node.location.x) { + player.packetDispatch.sendMessage("You cannot climb from this side.") + return true //who missed this return? lol. + } + val flag = if (node.location == Location(2536, 3553, 0)) 4 else if (node.location == Location(2539, 3553, 0)) 5 else 6 + sendMessage(player, "You climb the low wall...") + AgilityHandler.forceWalk(player, flag, node.location.transform(-1, 0, 0), node.location.transform(1, 0, 0), Animation.create(839), 10, 13.5, null) + } + 455 -> BarcrawlManager.getInstance(player).read() + 385 -> { + sendMessage(player, "The scorpion stings you!") + player.impactHandler.manualHit(player, 3, HitsplatType.NORMAL) + } + 386 -> { + sendMessage(player, "The scorpion stings you!") + player.impactHandler.manualHit(player, 3, HitsplatType.NORMAL) + } + 387 -> { + sendMessage(player, "The scorpion stings you!") + player.impactHandler.manualHit(player, 3, HitsplatType.NORMAL) + } + } + return true + } + + /** + * Handles the rope swing obstacle. + * @param player the player. + * @param object the object. + */ + private fun handleRopeSwing(player: Player, `object`: Scenery) { + if (player.location.y < 3554) { + sendMessage(player, "You cannot do that from here.") + return + } + if (ropeDelay > GameWorld.ticks) { + sendMessage(player, "The rope is being used.") + return + } + if (AgilityHandler.hasFailed(player, 1, 0.1)) { + AgilityHandler.fail(player, 0, Location.create(2549, 9951, 0), null, getHitAmount(player), "You slip and fall to the pit below.") + return + } + ropeDelay = GameWorld.ticks + 2 + player.packetDispatch.sendSceneryAnimation(`object`, Animation.create(497), true) + AgilityHandler.forceWalk(player, 0, player.location, Location.create(2551, 3549, 0), Animation.create(751), 50, 22.0, "You skillfully swing across.", 1) + } + + /** + * Handles the log balance obstacle. + * @param player the player. + * @param object the object. + */ + private fun handleLogBalance(player: Player, `object`: Scenery) { + val failed = AgilityHandler.hasFailed(player, 1, 0.5) + val end = if (failed) Location.create(2545, 3546, 0) else Location.create(2541, 3546, 0) + sendMessage(player, "You walk carefully across the slippery log...") + AgilityHandler.walk(player, if (failed) -1 else 1, Location.create(2551, 3546, 0), end, Animation.create(155), if (failed) 0.0 else 13.5, if (failed) null else "...You make it safely to the other side.") + if (failed) { + AgilityHandler.walk(player, -1, player.location, Location.create(2545, 3546, 0), Animation.create(155), 0.0, null) + GameWorld.Pulser.submit(getSwimPulse(player)) + return + } + } + + /** + * Gets the pulse used to swim when failing the log balance. + * @param player the player. + * @return `Pulse` the pulse. + */ + private fun getSwimPulse(player: Player): Pulse { + return object : Pulse(1, player) { + var counter = 0 + override fun pulse(): Boolean { + when (++counter) { + 6 -> { + player.animate(Animation.create(771)) + player.packetDispatch.sendMessages("...You loose your footing and fall into the water.", "Something in the water bites you.") + } + 7 -> { + player.graphics(Graphics.create(68)) + player.properties.teleportLocation = Location.create(2545, 3545, 0) + player.impactHandler.manualHit(player, getHitAmount(player), HitsplatType.NORMAL) + AgilityHandler.walk(player, -1, Location.create(2545, 3545, 0), Location.create(2545, 3543, 0), Animation.create(152), 0.0, null) + } + 11 -> { + player.properties.teleportLocation = Location.create(2545, 3542, 0) + return true + } + } + return false + } + } + } + + /** + * Handles the ledge balance obstacle. + * @param player the player. + * @param object the object. + */ + private fun handleLedgeBalance(player: Player, `object`: Scenery) { + val failed = AgilityHandler.hasFailed(player, 1, 0.3) + val end = if (failed) Location.create(2534, 3547, 1) else Location.create(2532, 3547, 1) + AgilityHandler.walk(player, if (failed) -1 else 3, Location.create(2536, 3547, 1), end, Animation.create(157), if (failed) 0.0 else 22.0, if (failed) null else "You skillfully edge across the gap.") + sendMessage(player, "You put your foot on the ledge and try to edge across..") + if (failed) { + AgilityHandler.fail(player, 3, Location.create(2534, 3545, 0), Animation(760), getHitAmount(player), "You slip and fall to the pit below.") + return + } + } + + override fun configure() { + SceneryDefinition.forId(2115).handlers["option:open"] = this + SceneryDefinition.forId(2116).handlers["option:open"] = this + SceneryDefinition.forId(2282).handlers["option:swing-on"] = this + SceneryDefinition.forId(2294).handlers["option:walk-across"] = this + SceneryDefinition.forId(20211).handlers["option:climb-over"] = this + SceneryDefinition.forId(2302).handlers["option:walk-across"] = this + SceneryDefinition.forId(1948).handlers["option:climb-over"] = this + ItemDefinition.forId(455).handlers["option:read"] = this + NPCDefinition.forId(385).handlers["option:pick-up"] = this + NPCDefinition.forId(386).handlers["option:pick-up"] = this + NPCDefinition.forId(387).handlers["option:pick-up"] = this + ClassScanner.definePlugin(BarbarianGuardDialogue()) + } + + override fun getDestination(node: Node, n: Node): Location? { + if (n is Scenery) { + when (n.getId()) { + 2282 -> return Location.create(2551, 3554, 0) + } + } + return null + } + + /** + * The barbarian guard dialogue plugin. + * @author Woah + */ + class BarbarianGuardDialogue : core.game.dialogue.DialoguePlugin { + /** + * Constructs a new `BarbarianGuardDialogue` `Object`. + */ + constructor() { + /** + * empty. + */ + } + + /** + * Constructs a new `BarbarianGuardDialogue` `Object`. + * @param player the player. + */ + constructor(player: Player?) : super(player) {} + + override fun newInstance(player: Player): core.game.dialogue.DialoguePlugin { + return BarbarianGuardDialogue(player) + } + + override fun open(vararg args: Any): Boolean { + if (!BarcrawlManager.getInstance(player).isStarted) { + npc("O, waddya want?") + } else if (BarcrawlManager.getInstance(player).isFinished && !BarcrawlManager.getInstance(player).isStarted) { + npc("'Ello friend.") + stage = 50 + } else { + npc("So, how's the Barcrawl coming along?") + stage = 20 + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> { + options("I want to come through this gate.", "I want some money.") + stage++ + } + 1 -> when (buttonId) { + 1 -> { + player("I want to come through this gate.") + stage = 5 + } + 2 -> { + player("I want some money.") + stage = 3 + } + } + 3 -> { + npc("Do I look like a bank to you?") + stage++ + } + 4 -> end() + 5 -> if (BarcrawlManager.getInstance(player).isFinished) { + npc("You may pass if you like. You are a true", "barbarian now.") + stage = 4 + } else { + npc("Barbarians only. Are you a barbarian? You don't look", "like one.") + stage++ + } + 6 -> { + options("Hmm, yep you've got me there.", "Looks can be deceiving, I am in fact a barbarian.") + stage++ + } + 7 -> when (buttonId) { + 1 -> { + player("Hmm, yep you've got me there.") + stage = 4 + } + 2 -> { + player("Looks can be deceiving, I am in fact a barbarian.") + stage++ + } + } + 8 -> { + npc("If you're a barbarian you need to be able to drink like", "one. We barbarians like a good drink.") + stage++ + } + 9 -> { + npc("I have the perfect challenge for you... the Alfred", "Grimhand Barcrawl! First completed by Alfred", "Grimhand.") + stage++ + } + 10 -> { + BarcrawlManager.getInstance(player).reset() + BarcrawlManager.getInstance(player).isStarted = true + player.inventory.add(BarcrawlManager.BARCRAWL_CARD, player) + interpreter.sendDialogue("The guard hands you a Barcrawl card.") + stage++ + } + 11 -> { + npc("Take that card to each of the bards named on it. The", "bartenders will know what it means. We're kinda well", "known.") + stage++ + } + 12 -> { + npc("They'll give you their strongest drink and sign your", "card. When you've done all that, we'll be happy to let", "you in.") + stage++ + } + 13 -> end() + 20 -> if (!BarcrawlManager.getInstance(player).hasCard()) { + player("I've lost my barcrawl card...") + stage = 23 + } else if (BarcrawlManager.getInstance(player).isFinished) { + player("I tink I jusht 'bout done dem all... but I losht count...") + stage = 24 + } else { + player("I haven't finished it yet.") + stage++ + } + 21 -> { + npc("Well come back when you have, you lightweight.") + stage++ + } + 22 -> end() + 23 -> { + npc("What are you like? You're gonna have to start all over", "now.") + stage = 10 + } + 24 -> { + if (!player.inventory.containsItem(BarcrawlManager.BARCRAWL_CARD)) { + end() + } + BarcrawlManager.getInstance(player).isStarted = false + player.bank.remove(BarcrawlManager.BARCRAWL_CARD) + player.inventory.remove(BarcrawlManager.BARCRAWL_CARD) + interpreter.sendDialogue("You give the card to the barbarian.") + stage++ + } + 25 -> { + npc("Yep that seems fine, you can come in now. I never", "learned to read, but you look like you've drunk plenty.") + stage = 22 + } + 50 -> end() + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(384) + } + } + + companion object { + /** + * The rope delay. + */ + private var ropeDelay = 0 + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/agility/GnomeStrongholdCourse.kt b/Server/src/main/content/global/skill/agility/GnomeStrongholdCourse.kt new file mode 100644 index 0000000..d34a40d --- /dev/null +++ b/Server/src/main/content/global/skill/agility/GnomeStrongholdCourse.kt @@ -0,0 +1,156 @@ +package content.global.skill.agility + +import core.api.* +import core.cache.def.impl.SceneryDefinition +import core.game.node.Node +import core.game.node.scenery.Scenery +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.plugin.Initializable +import core.game.world.GameWorld + +/** + * Handles the gnome stronghold agility course. + * @author Woah + */ +@Initializable +class GnomeStrongholdCourse +/** + * Constructs a new `GnomeStrongholdCourse` `Object`. + * @param player The player. + */ +/** + * Constructs a new `GnomeStrongholdCourse` `Object`. + */ +@JvmOverloads constructor(player: Player? = null) : AgilityCourse(player, 7, 39.0) { + override fun handle(player: Player, node: Node, option: String): Boolean { + getCourse(player) // Sets the extension. + val `object` = node as Scenery + when (`object`.id) { + 2295 -> { + TRAINERS[0]!!.sendChat("Okay get over that log, quick quick!") + sendMessage(player, "You walk carefully across the slippery log...") + AgilityHandler.walk(player, 0, Location.create(2474, 3436, 0), Location.create(2474, 3429, 0), Animation.create(155), 7.5, "...You make it safely to the other side.") + return true + } + 2285 -> { + TRAINERS[1]!!.sendChat("Move it, move it, move it!") + sendMessage(player, "You climb the netting...") + AgilityHandler.climb(player, 1, Animation.create(828), `object`.location.transform(0, -1, 1), 7.5, null) + return true + } + 35970 -> { + TRAINERS[2]!!.sendChat("That's it - straight up.") + sendMessage(player, "You climb the tree..") + AgilityHandler.climb(player, 2, Animation.create(828), Location.create(2473, 3420, 2), 5.0, "...To the platform above.") + return true + } + 2312 -> { + TRAINERS[3]!!.sendChat("Come on scaredy cat, get across that rope!") + sendMessage(player, "You carefully cross the tightrope.") + AgilityHandler.walk(player, 3, Location.create(2477, 3420, 2), Location.create(2483, 3420, 2), Animation.create(155), 7.5, null) + return true + } + 4059 -> { + sendMessage(player, "You can't do that from here.") + return true + } + 2314, 2315 -> { + sendMessage(player, "You climb down the tree..") + AgilityHandler.climb(player, 4, Animation.create(828), Location.create(2487, 3420, 0), 5.0, "You land on the ground.") + return true + } + 2286 -> { + TRAINERS[4]!!.sendChat("My Granny can move faster than you.") + player.faceLocation(player.location.transform(0, 2, 0)) + sendMessage(player, "You climb the netting...") + AgilityHandler.climb(player, 5, Animation.create(828), player.location.transform(0, 2, 0), 7.5, null) + return true + } + 4058, 154 -> { + val index = if (`object`.id == 154) 0 else 1 //If the player clicks on the left pipe, set index to 0, otherwise 1 + val x = 2484 + index * 3 //change the x coordinates for walking/animations depending on index multiplier + if (`object`.location.y == 3435) { + sendMessage(player, "You can't do that from here.") + return true + } + if (USED_PIPES[index] > GameWorld.ticks) { + sendMessage(player, "The pipe is being used.") + return true + } + USED_PIPES[index] = GameWorld.ticks + 10 + + player.lock() + //Animations and force walking + //X variable is determined by both index and x variables before + AgilityHandler.forceWalk(player, -1, Location.create(x, 3430, 0), Location.create(x, 3433, 0), Animation.create(10580), 10, 0.0, null) + player.lock() + AgilityHandler.forceWalk(player, -1, Location.create(x, 3433, 0), Location.create(x, 3435, 0), Animation.create(844), 10, 0.0, null, 5) + player.lock() + AgilityHandler.forceWalk(player, 6, Location.create(x, 3435, 0), Location.create(x, 3437, 0), Animation.create(10579), 20, 7.5, null, 8) + return true + } + } + return false + } + + override fun getDestination(node: Node, n: Node): Location? { + val `object` = n as Scenery + when (`object`.id) { + 2295 -> return Location.create(2474, 3436, 0) + 2286 -> { + var x = node.location.x + if (x < n.getLocation().x) { + x = n.getLocation().x + } else if (x > n.getLocation().x + 1) { + x = n.getLocation().x + 1 + } + return Location.create(x, n.getLocation().y - 1, 0) + } + 4058, 154 -> if (n.getLocation().y == 3431) { + return n.getLocation().transform(0, -1, 0) + } + } + return null + } + + override fun configure() { + TRAINERS[0] = NPC.create(162, Location.create(2473, 3438, 0)) + TRAINERS[1] = NPC.create(162, Location.create(2478, 3426, 0)) + TRAINERS[2] = NPC.create(162, Location.create(2474, 3422, 1)) + TRAINERS[3] = NPC.create(162, Location.create(2472, 3419, 2)) + TRAINERS[4] = NPC.create(162, Location.create(2489, 3425, 0)) + for (npc in TRAINERS) { + npc!!.init() + npc.walkRadius = 3 + } + SceneryDefinition.forId(2295).handlers["option:walk-across"] = this + SceneryDefinition.forId(2285).handlers["option:climb-over"] = this + SceneryDefinition.forId(35970).handlers["option:climb"] = this + SceneryDefinition.forId(2312).handlers["option:walk-on"] = this + SceneryDefinition.forId(4059).handlers["option:walk-on"] = this + SceneryDefinition.forId(2314).handlers["option:climb-down"] = this + SceneryDefinition.forId(2315).handlers["option:climb-down"] = this + SceneryDefinition.forId(2286).handlers["option:climb-over"] = this + SceneryDefinition.forId(4058).handlers["option:squeeze-through"] = this + SceneryDefinition.forId(154).handlers["option:squeeze-through"] = this + } + + override fun createInstance(player: Player): AgilityCourse { + return GnomeStrongholdCourse(player) + } + + companion object { + /** + * The pipes currently in usage. + */ + private val USED_PIPES = IntArray(2) + + /** + * The trainer NPCs. + */ + private val TRAINERS = arrayOfNulls(5) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/agility/WildernessCourse.kt b/Server/src/main/content/global/skill/agility/WildernessCourse.kt new file mode 100644 index 0000000..00f08cf --- /dev/null +++ b/Server/src/main/content/global/skill/agility/WildernessCourse.kt @@ -0,0 +1,260 @@ +package content.global.skill.agility + +import core.api.* +import core.cache.def.impl.SceneryDefinition +import core.game.node.Node +import core.game.node.scenery.Scenery +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.TeleportManager +import core.game.node.entity.skill.Skills +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.map.RegionManager +import core.game.world.update.flag.context.Animation +import core.plugin.Initializable +import core.game.world.GameWorld + +/** + * Handles the wilderness agility course. + * @author Woah + */ +@Initializable +class WildernessCourse + +/** + * Constructs a new `WildernessCourse` `Object`. + */ +@JvmOverloads constructor(player: Player? = null) : AgilityCourse(player, 5, 499.0) { + override fun handle(player: Player, node: Node, option: String): Boolean { + getCourse(player) // Sets the extension. + val `object` = node as Scenery + when (`object`.id) { + 2309 -> handleEntrance(player, `object`) + 2307, 2308 -> { + core.game.global.action.DoorActionHandler.handleAutowalkDoor(player, `object`) + handleEntranceObstacle(player, `object`) + } + 2288 -> handlePipe(player, `object`) + 2283 -> handleRopeSwing(player, `object`) + 37704 -> handleSteppingStones(player, `object`) + 2297 -> handleLogBalance(player, `object`) + 2328 -> handleRockClimb(player, `object`) + } + return true + } + + /** + * Handles the door entrance. + * @param player the player. + * @param object the object. + */ + private fun handleEntrance(player: Player, `object`: Scenery) { + if (player.location.y > 3916 || player.skills.getLevel(Skills.AGILITY) >= 52) { + core.game.global.action.DoorActionHandler.handleAutowalkDoor(player, `object`) + if (player.location.y <= 3916) { + handleEntranceObstacle(player, `object`) + } + } else { + player.dialogueInterpreter.sendDialogue("You need an Agility level of at least 52 to enter.") + } + } + + /** + * Handles the entrance obstacle. + * @param player the player. + * @param object the object. + */ + private fun handleEntranceObstacle(player: Player, `object`: Scenery) { + GameWorld.Pulser.submit(object : Pulse(1, player) { + var counter = 0 + val fail = AgilityHandler.hasFailed(player, 1, 0.3) + override fun pulse(): Boolean { + when (++counter) { + 2 -> { + val end = if (fail) Location.create(2998, 3924, 0) else if (`object`.id < 2309) Location.create(2998, 3917, 0) else Location.create(2998, 3930, 0) + val start = if (`object`.id < 2309) player.location else Location.create(2998, 3917, 0) + sendMessage(player, "You go through the gate and try to edge over the ridge...") + AgilityHandler.walk(player, -1, start, end, Animation.create(155), if (fail) 0.0 else 15.00, if (fail) "You lose your footing and fail into the wolf pit." else "You skillfully balance across the ridge...") + } + 9 -> { + if (fail) { + AgilityHandler.fail(player, 0, player.location.transform(if (`object`.id < 2309) -2 else 2, 0, 0), Animation.create(if (`object`.id < 2309) 771 else 771), getHitAmount(player), null) + } + return fail + } + 15 -> player.lock(3) + 16 -> { + val doorLoc = if (`object`.id < 2309) Location(2998, 3917, 0) else Location(2998, 3931, 0) + core.game.global.action.DoorActionHandler.handleAutowalkDoor(player, RegionManager.getObject(doorLoc)) + return true + } + } + return false + } + }) + } + + /** + * Handles the pipe obstacle. + * @param player the pipe. + * @param object the object. + */ + private fun handlePipe(player: Player, `object`: Scenery) { + if (`object`.location.y == 3948) { + sendMessage(player, "You can't do that from here.") + return + } + if (player.skills.getLevel(Skills.AGILITY) < 49) { + player.dialogueInterpreter.sendDialogue("You need an Agility level of at least 49 to do this.") + return + } + player.lock(10) + GameWorld.Pulser.submit(object : Pulse(1, player) { + var counter = 0 + override fun pulse(): Boolean { + val x = 3004 + when (counter++) { + 0 -> { + AgilityHandler.forceWalk(player, -1, Location.create(x, 3937, 0), Location.create(x, 3940, 0), Animation.create(10580), 15, 0.0, null, 1) //10 + player.teleporter.send(Location.create(3004, 3947, 0), TeleportManager.TeleportType.INSTANT, TeleportManager.WILDY_TELEPORT) + counter++ + AgilityHandler.forceWalk(player, 0, Location.create(x, 3948, 0), Location.create(x, 3950, 0), Animation.create(10579), 20, 12.5, null, 5) //20 + return true + } + 2 -> { + player.teleporter.send(Location.create(3004, 3947, 0), TeleportManager.TeleportType.INSTANT, TeleportManager.WILDY_TELEPORT) + counter++ + AgilityHandler.forceWalk(player, 0, Location.create(x, 3948, 0), Location.create(x, 3950, 0), Animation.create(10579), 20, 12.5, null, 5) + return true + } + 3 -> { + AgilityHandler.forceWalk(player, 0, Location.create(x, 3948, 0), Location.create(x, 3950, 0), Animation.create(10579), 20, 12.5, null, 5) + return true + } + } + return true + } + }) + } + + /** + * Handles the rope swing obstacle. + * @param player the player. + * @param object the object. + */ + private fun handleRopeSwing(player: Player, `object`: Scenery) { + if (player.location.y < 3554) { + sendMessage(player, "You cannot do that from here.") + return + } + if (ropeDelay > GameWorld.ticks) { + sendMessage(player, "The rope is being used.") + return + } + if (AgilityHandler.hasFailed(player, 1, 0.1)) { + AgilityHandler.fail(player, 0, Location.create(3005, 10357, 0), null, getHitAmount(player), "You slip and fall to the pit below.") + return + } + ropeDelay = GameWorld.ticks + 2 + player.packetDispatch.sendSceneryAnimation(`object`, Animation.create(497), true) + AgilityHandler.forceWalk(player, 1, player.location, Location.create(3005, 3958, 0), Animation.create(751), 50, 20.0, "You skillfully swing across.", 1) + } + + /** + * Handles the stepping stone obstacle. + * @param player the player. + * @param object the object. + */ + private fun handleSteppingStones(player: Player, `object`: Scenery) { + lock(player, 50) + val fail = AgilityHandler.hasFailed(player, 1, 0.3) + val origLoc = player.location + registerLogoutListener(player, "steppingstone"){p -> + player.location = origLoc + } + submitWorldPulse(object : Pulse(2, player){ + var counter = 0 + override fun pulse(): Boolean { + if (counter == 3 && fail) { + AgilityHandler.fail(player, -1, Location.create(3001, 3963, 0), Animation.create(771), (player.skills.lifepoints * 0.26).toInt(), "...You lose your footing and fall into the lava.") + return true + } + AgilityHandler.forceWalk(player, if (counter == 5) 2 else -1, player.location, player.location.transform(-1, 0, 0), Animation.create(741), 10, if (counter == 5) 20.0 else 0.0, if (counter != 0) null else "You carefully start crossing the stepping stones...") + if(++counter == 6){ + unlock(player) + clearLogoutListener(player, "steppingstone") + } + return counter == 6 + } + }) + } + + /** + * Handles the log balance obstacle. + * @param player the player. + * @param object the object. + */ + private fun handleLogBalance(player: Player, `object`: Scenery) { + val failed = AgilityHandler.hasFailed(player, 1, 0.5) + val end = if (failed) Location.create(2998, 3945, 0) else Location.create(2994, 3945, 0) + sendMessage(player, "You walk carefully across the slippery log...") + AgilityHandler.walk(player, if (failed) -1 else 3, player.location, end, Animation.create(155), if (failed) 0.0 else 20.0, if (failed) null else "You skillfully edge across the gap.") + if (failed) { + GameWorld.Pulser.submit(object : Pulse(5, player) { + override fun pulse(): Boolean { + player.faceLocation(Location.create(2998, 3944, 0)) + AgilityHandler.fail(player, 3, Location.create(2998, 10345, 0), Animation.create(770), getHitAmount(player), "You slip and fall onto the spikes below.") + return true + } + }) + return + } + } + + /** + * Handles the rock climbing obstacle. + * @param player the player. + * @param object the object. + */ + private fun handleRockClimb(player: Player, `object`: Scenery) { + AgilityHandler.forceWalk(player, 4, Location.create(2994, 3937, 0), Location.create(2994, 3933, 0), Animation.create(740), 8, 0.0, "You reach the top.") + GameWorld.Pulser.submit(object : Pulse(4, player) { + override fun pulse(): Boolean { + player.animator.reset() + return true + } + }) + } + + override fun getDestination(node: Node, n: Node): Location? { + when (n.id) { + 2283 -> return Location.create(3005, 3953, 0) + 37704 -> return Location.create(3002, 3960, 0) + 2297 -> return Location.create(3002, 3945, 0) + 2328 -> return n.location.transform(0, 1, 0) + } + return null + } + + override fun configure() { + SceneryDefinition.forId(2309).handlers["option:open"] = this + SceneryDefinition.forId(2308).handlers["option:open"] = this + SceneryDefinition.forId(2307).handlers["option:open"] = this + SceneryDefinition.forId(2288).handlers["option:squeeze-through"] = this + SceneryDefinition.forId(2283).handlers["option:swing-on"] = this + SceneryDefinition.forId(37704).handlers["option:cross"] = this + SceneryDefinition.forId(2297).handlers["option:walk-across"] = this + SceneryDefinition.forId(2328).handlers["option:climb"] = this + } + + override fun createInstance(player: Player): AgilityCourse { + return WildernessCourse(player) + } + + companion object { + /** + * The rope delay. + */ + private var ropeDelay = 0 + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/agility/brimhaven/BladeTrap.java b/Server/src/main/content/global/skill/agility/brimhaven/BladeTrap.java new file mode 100644 index 0000000..773cd99 --- /dev/null +++ b/Server/src/main/content/global/skill/agility/brimhaven/BladeTrap.java @@ -0,0 +1,56 @@ +package content.global.skill.agility.brimhaven; + +import content.global.skill.agility.AgilityHandler; +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.system.task.MovementHook; +import core.game.system.task.Pulse; +import kotlin.Unit; +import core.game.world.GameWorld; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; + +/** + * Handles the blade trap. + * @author Emperor + */ +public final class BladeTrap implements MovementHook { + + @Override + public boolean handle(Entity e, final Location l) { + if (BrimhavenArena.sawBladeActive) { + final Direction dir = e.getDirection(); + final Player player = (Player) e; + final Location start = l.transform(-dir.getStepX(), -dir.getStepY(), 0); + e.lock(5); + if(e.isPlayer()) + { + e.asPlayer().logoutListeners.put("blade-trap", p -> { + p.setLocation(start); + return Unit.INSTANCE; + }); + } + GameWorld.getPulser().submit(new Pulse(2, e) { + @Override + public boolean pulse() { + Direction direction = dir; + Direction d = Direction.get(direction.toInteger() + 2 & 3); + if (RegionManager.getObject(player.getLocation().transform(dir)) != null) { + Direction s = d; + d = direction; + direction = s; + } + Location loc = player.getLocation(); + AgilityHandler.failWalk(player, 1, loc, loc.transform(direction), loc.transform(direction), Animation.create(846), 10, 3, "You were hit by the saw blade!").setDirection(d); + player.logoutListeners.remove("blade-trap"); + return true; + } + }); + return false; + } + return true; + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/agility/brimhaven/BrimhavenArena.java b/Server/src/main/content/global/skill/agility/brimhaven/BrimhavenArena.java new file mode 100644 index 0000000..13a6a4a --- /dev/null +++ b/Server/src/main/content/global/skill/agility/brimhaven/BrimhavenArena.java @@ -0,0 +1,336 @@ +package content.global.skill.agility.brimhaven; + +import core.game.component.Component; +import core.game.global.action.ClimbActionHandler; +import core.game.interaction.Option; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.HintIconManager; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.item.GroundItem; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.MovementHook; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.*; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBuilder; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.tools.RandomFunction; + +import java.util.HashMap; +import java.util.Map; + +import static core.api.ContentAPIKt.*; + +/** + * Handles the Brimhaven agility arena zone. + * + * @author Emperor + */ +@Initializable +public final class BrimhavenArena extends MapZone implements Plugin { + + /** + * The location based traps. + */ + private static final Map LOCATION_TRAPS = new HashMap<>(); + + /** + * The overlay component. + */ + private static final Component OVERLAY = new Component(5); + + /** + * The ticket dispenser locations. + */ + private static final Location[] DISPENSERS = new Location[24]; + + /** + * The agility ticket reward item. + */ + private static final Item TICKET = new Item(2996); + + /** + * If the saw blade is currently active. + */ + public static boolean sawBladeActive; + + /** + * Constructs a new {@code BrimhavenArena} {@code Object}. + */ + public BrimhavenArena() { + super("Brimhaven agility arena", true); + } + + /** + * Sets the current ticket dispenser target. + * + * @param player The player. + */ + private void setDispenser(Player player) { + if (!player.getAttribute("brim-tagged", false)) { + player.setAttribute("brim-tagcount", 0); + } + player.setAttribute("brim-tagged", false); + setVarp(player, 309, 0); + int index = RandomFunction.randomize(DISPENSERS.length); + if (index == player.getAttribute("brim-tag", -1)) { + index = (index + 1) % DISPENSERS.length; + } + int iconSlot = player.getAttribute("brim-icon", -1); + if (iconSlot > -1) { + HintIconManager.removeHintIcon(player, iconSlot); + } + player.setAttribute("brim-tag", index); + player.setAttribute("brim-icon", HintIconManager.registerHeightHintIcon(player, DISPENSERS[index], 50)); + } + + @Override + public boolean enter(Entity entity) { + if (entity instanceof Player) { + Player player = (Player) entity; + player.getInterfaceManager().openOverlay(OVERLAY); + setDispenser(player); + } + return super.enter(entity); + } + + @Override + public boolean leave(Entity entity, boolean logout) { + if (entity instanceof Player && !logout) { + Player player = (Player) entity; + player.getInterfaceManager().closeOverlay(); + player.removeAttribute("brim-tag"); + player.removeAttribute("brim-tagcount"); + int iconSlot = player.getAttribute("brim-icon", -1); + if (iconSlot > -1) { + HintIconManager.removeHintIcon(player, iconSlot); + player.removeAttribute("brim-icon"); + } + } + return super.enter(entity); + } + + @Override + public boolean interact(Entity entity, Node node, Option option) { + if (node instanceof Scenery) { + Scenery object = (Scenery) node; + if (object.getId() == 3610) { + ClimbActionHandler.climb((Player) entity, Animation.create(828), object.getLocation().transform(0, 0, 3)); + return true; + } + if (object.getId() == 3608 || object.getId() == 3581) { + Player player = (Player) entity; + if (!object.getLocation().equals(DISPENSERS[player.getAttribute("brim-tag", 0)])) { + player.getPacketDispatch().sendMessage("Tag the pillar indicated by the yellow arrow to get an Agility ticket."); + return true; + } + if (player.getAttribute("brim-tagged", false)) { + player.getPacketDispatch().sendMessage("You have already tagged this pillar."); + return true; + } + player.setAttribute("brim-tagged", true); + int tags = player.getAttribute("brim-tagcount", 0) + 1; + player.setAttribute("brim-tagcount", tags); + setVarp(player, 309, 4); + if (tags > 1) { + int amount = 1; + if (!player.getInventory().add(new Item(TICKET.getId(), amount))) { + GroundItemManager.create(new GroundItem(new Item(TICKET.getId(), amount), player.getLocation(), player)); + } + player.getAchievementDiaryManager().finishTask(player, DiaryType.KARAMJA, 1, 0); + player.getDialogueInterpreter().sendItemMessage(TICKET.getId(), "You have received an Agility Arena Ticket!"); + player.getPacketDispatch().sendMessage("You have received an Agility Arena Ticket!"); + return true; + } + player.getPacketDispatch().sendMessage("You get tickets by tagging more than one pillar in a row, tag the next pillar!"); + player.getDialogueInterpreter().sendDialogue("You get tickets by tagging more than one pillar in a row. Tag the", "next pillar for a ticket!"); + return true; + } + } + return false; + } + + @Override + public boolean move(Entity e, Location loc, Location dest) { + if (!e.getLocks().isMovementLocked() && e instanceof Player) { + MovementHook hook = LOCATION_TRAPS.get(loc); + if (hook != null) { + e.setDirection(Direction.getLogicalDirection(loc, dest)); + return hook.handle(e, loc); + } + } + return super.move(e, loc, dest); + } + + @Override + public void locationUpdate(Entity e, Location last) { + if (!e.getLocks().isMovementLocked() && e instanceof Player) { + MovementHook hook = LOCATION_TRAPS.get(e.getLocation()); + if (hook != null) { + if (!hook.handle(e, e.getLocation())) { + if (e.getPulseManager().isMovingPulse()) { + e.getPulseManager().clear(); + } + e.getWalkingQueue().reset(); + } + } + } + } + + @Override + public void configure() { + registerRegion(11157); + PressurePad pad = new PressurePad(); + LOCATION_TRAPS.put(Location.create(2800, 9579, 3), pad); + LOCATION_TRAPS.put(Location.create(2799, 9579, 3), pad); + LOCATION_TRAPS.put(Location.create(2800, 9557, 3), pad); + LOCATION_TRAPS.put(Location.create(2799, 9557, 3), pad); + LOCATION_TRAPS.put(Location.create(2772, 9585, 3), pad); + LOCATION_TRAPS.put(Location.create(2772, 9584, 3), pad); + FloorSpikes spikes = new FloorSpikes(); + LOCATION_TRAPS.put(Location.create(2800, 9568, 3), spikes); + LOCATION_TRAPS.put(Location.create(2799, 9568, 3), spikes); + LOCATION_TRAPS.put(Location.create(2772, 9552, 3), spikes); + LOCATION_TRAPS.put(Location.create(2772, 9551, 3), spikes); + LOCATION_TRAPS.put(Location.create(2761, 9573, 3), spikes); + LOCATION_TRAPS.put(Location.create(2761, 9574, 3), spikes); + DartTrap dart = new DartTrap(); + LOCATION_TRAPS.put(Location.create(2788, 9557, 3), dart); + LOCATION_TRAPS.put(Location.create(2789, 9557, 3), dart); + LOCATION_TRAPS.put(Location.create(2794, 9573, 3), dart); + LOCATION_TRAPS.put(Location.create(2794, 9574, 3), dart); + LOCATION_TRAPS.put(Location.create(2777, 9568, 3), dart); + LOCATION_TRAPS.put(Location.create(2778, 9568, 3), dart); + SpinningBlades blade = new SpinningBlades(); + LOCATION_TRAPS.put(Location.create(2778, 9579, 3), blade); + LOCATION_TRAPS.put(Location.create(2783, 9574, 3), blade); + LOCATION_TRAPS.put(Location.create(2778, 9557, 3), blade); + BladeTrap trap = new BladeTrap(); + LOCATION_TRAPS.put(Location.create(2788, 9579, 3), trap); + LOCATION_TRAPS.put(Location.create(2789, 9579, 3), trap); + LOCATION_TRAPS.put(Location.create(2783, 9551, 3), trap); + LOCATION_TRAPS.put(Location.create(2783, 9552, 3), trap); + LOCATION_TRAPS.put(Location.create(2761, 9584, 3), trap); + LOCATION_TRAPS.put(Location.create(2761, 9585, 3), trap); + int index = 0; + for (int x = 2761; x < 2815; x += 11) { + for (int y = 9546; y < 9600; y += 11) { + if (x == 2805 && y == 9590) { + continue; + } + DISPENSERS[index++] = Location.create(x, y, 3); + } + } + GameWorld.getPulser().submit(new Pulse(1) { + @Override + public boolean pulse() { + Region r = RegionManager.forId(11157); + if (!r.isActive()) { + return false; + } + if (GameWorld.getTicks() % 100 == 0) { + for (RegionPlane plane : r.getPlanes()) { + for (Player player : plane.getPlayers()) { + setDispenser(player); + } + } + handlePlankSwitching(); + } + int ticks = 3; + if (GameWorld.getTicks() % ticks == 0) { + sawBladeActive = !sawBladeActive; + if (sawBladeActive) { + Scenery object = RegionManager.getObject(3, 2788, 9579); + SceneryBuilder.replace(object, object.transform(3567, object.getRotation(), 10), ticks); + object = RegionManager.getObject(3, 2789, 9579); + SceneryBuilder.replace(object, object.transform(0), ticks); + + object = RegionManager.getObject(3, 2783, 9551); + SceneryBuilder.replace(object, object.transform(3567, object.getRotation(), 10), ticks); + object = RegionManager.getObject(3, 2783, 9552); + SceneryBuilder.replace(object, object.transform(0), ticks); + + object = RegionManager.getObject(3, 2761, 9584); + SceneryBuilder.replace(object, object.transform(3567, object.getRotation(), 10), ticks); + object = RegionManager.getObject(3, 2761, 9585); + SceneryBuilder.replace(object, object.transform(0), ticks); + } + } + return false; + } + }); + } + + /** + * Switches the plank states. + */ + private static void handlePlankSwitching() { + boolean[] available = new boolean[3]; + for (int i = 0; i < 1 + RandomFunction.randomize(2); i++) { + available[RandomFunction.randomize(3)] = true; + } + for (int i = 0; i < 3; i++) { + boolean avail = available[i]; + for (PlankSet set : PlankSet.values()) { + Location l = set.entrance[i]; + for (int x = 1; x < set.exit[i].getX() - l.getX(); x++) { + Scenery object = RegionManager.getObject(l.transform(x, 0, 0)); + if(object != null) + SceneryBuilder.replace(object, object.transform(avail ? 3573 : 3576)); + } + RegionManager.getObject(set.entrance[i]).setCharge(avail ? 1000 : 500); + RegionManager.getObject(set.exit[i]).setCharge(avail ? 1000 : 500); + } + } + } + + /** + * The plank obstacles. + * + * @author Emperor + */ + private static enum PlankSet { + FIRST(new Location[]{Location.create(2797, 9591, 3), Location.create(2797, 9590, 3), Location.create(2797, 9589, 3)}, new Location[]{Location.create(2802, 9591, 3), Location.create(2802, 9590, 3), Location.create(2802, 9589, 3)}), SECOND(new Location[]{Location.create(2764, 9558, 3), Location.create(2764, 9557, 3), Location.create(2764, 9556, 3)}, new Location[]{Location.create(2769, 9558, 3), Location.create(2769, 9557, 3), Location.create(2769, 9556, 3)}); + + /** + * Constructs a new {@code PlankSet} {@code Object}. + * + * @param entrance The entrance locations for each plank. + * @param exit The exit locations for each plank. + */ + private PlankSet(Location[] entrance, Location[] exit) { + this.entrance = entrance; + this.exit = exit; + } + + /** + * The entrance location of the plank. + */ + Location[] entrance; + + /** + * The exit location of the plank. + */ + Location[] exit; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ZoneBuilder.configure(this); + return this; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + +} diff --git a/Server/src/main/content/global/skill/agility/brimhaven/BrimhavenCourse.java b/Server/src/main/content/global/skill/agility/brimhaven/BrimhavenCourse.java new file mode 100644 index 0000000..4fb8bdb --- /dev/null +++ b/Server/src/main/content/global/skill/agility/brimhaven/BrimhavenCourse.java @@ -0,0 +1,419 @@ +package content.global.skill.agility.brimhaven; + +import core.cache.def.impl.SceneryDefinition; +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import content.global.skill.agility.AgilityHandler; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.impl.ForceMovement; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.system.task.Pulse; +import kotlin.Unit; +import core.game.world.GameWorld; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; + +/** + * The brimhaven course handling plugin. + * @author Emperor + */ +@Initializable +public final class BrimhavenCourse extends OptionHandler { + + @Override + public boolean handle(final Player player, Node node, String option) { + final Scenery object = (Scenery) node; + Direction dir = object.getDirection(); + Location start = player.getLocation(); + switch (object.getId()) { + case 3566: + // Rope swing + start = object.getLocation().transform(dir.getStepX() << 1, dir.getStepY() << 1, 0); + Location end = object.getLocation().transform(-dir.getStepX() * 3, -dir.getStepY() * 3, 0); + if (AgilityHandler.hasFailed(player, 1, 0.1)) { + AgilityHandler.failWalk(player, 2, start, start.transform(-dir.getStepX(), -dir.getStepY(), 0), player.getLocation().transform(0, 0, -3), Animation.create(1105), 26, getHitAmount(player), "You missed the rope!").setEndAnimation(Animation.RESET); + return true; + } + AgilityHandler.forceWalk(player, -1, start, end, Animation.create(751), 25, getExp(player, 20.0), null); + GameWorld.getPulser().submit(new Pulse(1, player) { + boolean finish; + + @Override + public boolean pulse() { + if (!finish) { + player.getPacketDispatch().sendSceneryAnimation(object, Animation.create(1052)); + finish = true; + return false; + } + player.getPacketDispatch().sendSceneryAnimation(object, Animation.create(-1)); + return true; + } + }); + return true; + case 3578: + // Pillars + handlePillarObstacle(player, object); + return true; + case 3565: + // Low wall + dir = Direction.getLogicalDirection(player.getLocation(), object.getLocation()); + start = player.getLocation(); + if (AgilityHandler.hasFailed(player, 1, 0.05)) { + end = start.transform(dir); + AgilityHandler.failWalk(player, 2, start, end, end, Animation.create(1106), 15, getHitAmount(player), "You lost your balance!"); + AgilityHandler.forceWalk(player, -1, end, player.getLocation(), ForceMovement.WALK_ANIMATION, 10, 0.0, null, 4); + return true; + } + AgilityHandler.forceWalk(player, -1, start, start.transform(dir.getStepX() * 3, dir.getStepY() * 3, 0), Animation.create(1252), 6, getExp(player, 8.0), null); + return true; + case 3553: + case 3557: + handleLogBalance(player, object); + return true; + case 3570: + case 3571: + case 3572: + handlePlankObstacle(player, object); + return true; + case 3559: + case 3561: + handleBalancingLedge(player, object); + return true; + case 3564: + handleMonkeyBars(player, object); + return true; + case 3551: + handleBalancingRope(player, object); + return true; + case 3583: + handleHandHolds(player, object); + return true; + } + return false; + } + + /** + * Handles the hand holds obstacle. + * @param player The player. + * @param object The object. + */ + private static void handleHandHolds(final Player player, final Scenery object) { + if (player.getSkills().getLevel(Skills.AGILITY) < 20) { + player.getPacketDispatch().sendMessage("You need an agility of at least 20 to get past this obstacle!"); + return; + } + int mod = 0; + Direction direction = object.getDirection(); + int x = object.getLocation().getX(); + int y = object.getLocation().getY(); + if ((x == 2785 && y == 9544) || (x == 2759 && y == 9566) || (x == 2792 && y == 9592)) { + mod = 4; + direction = Direction.get(direction.toInteger() + 2 & 3); + } + final int m = mod; + player.lock(5); + final Direction dir = direction; + final Direction faceDirection = Direction.get(object.getDirection().toInteger() - 1 & 3); + final Location start = player.getLocation(); + player.getAppearance().setAnimations(Animation.create(1118 + m)); + player.getAppearance().sync(); + AgilityHandler.climb(player, -1, new Animation(1117 + m), start.transform(dir), 0.0, null); + player.logoutListeners.put("brimcourse", p -> { + p.setLocation(start); + return Unit.INSTANCE; + }); + GameWorld.getPulser().submit(new Pulse(3, player) { + Location last = start.transform(dir); + int count; + + @Override + public boolean pulse() { + if (++count == 1) { + if (AgilityHandler.hasFailed(player, 1, 0.15)) { + player.getAppearance().setAnimations(); + player.getAppearance().sync(); + AgilityHandler.fail(player, 2, last.transform(0, 0, -3), Animation.create(1119 + m), getHitAmount(player), "You missed a hand hold!"); + player.logoutListeners.remove("brimcourse"); + return true; + } + } else if (count == 6) { + player.getAppearance().setAnimations(); + player.getAppearance().sync(); + AgilityHandler.forceWalk(player, -1, last, last.transform(dir), Animation.create(1120 + m), 5, getExp(player, 22.0), null).setDirection(faceDirection); + player.logoutListeners.remove("brimcourse"); + return true; + } + player.logoutListeners.remove("brimcourse"); + AgilityHandler.forceWalk(player, -1, last, last = last.transform(dir), Animation.create(1118 + m), 5, 0.0, null).setDirection(faceDirection); + return false; + } + }); + } + + /** + * Handles the balancing rope obstacle. + * @param player The player. + * @param object The balancing rope object. + */ + private static void handleBalancingRope(final Player player, Scenery object) { + final Direction dir = object.getDirection(); + boolean failed = AgilityHandler.hasFailed(player, 1, 0.1); + if (failed) { + Location end = player.getLocation().transform(dir); + AgilityHandler.forceWalk(player, -1, player.getLocation(), end, Animation.create(762), 10, 0.0, null); + GameWorld.getPulser().submit(new Pulse(2, player) { + @Override + public boolean pulse() { + Direction d = Direction.get((dir.toInteger() + 3) % 4); + AgilityHandler.fail(player, 2, player.getLocation().transform(d.getStepX() << 1, d.getStepY() << 1, -3), Animation.create(764), getHitAmount(player), "You lost your balance!"); + return true; + } + }); + return; + } + AgilityHandler.walk(player, -1, player.getLocation(), player.getLocation().transform(dir.getStepX() * 7, dir.getStepY() * 7, 0), Animation.create(155), getExp(player, 10.0), null); + } + + /** + * Handles the monkey bars obstacle. + * @param player The player. + * @param object The object. + */ + private static void handleMonkeyBars(final Player player, Scenery object) { + player.lock(5); + final Direction dir = Direction.get((object.getDirection().toInteger() + 2) % 4); + player.getAppearance().setAnimations(Animation.create(745)); + final Location start = player.getLocation(); + ForceMovement.run(player, start.transform(dir), start.transform(dir.getStepX() << 1, dir.getStepY() << 1, 0), Animation.create(742), Animation.create(744)); + player.logoutListeners.put("brimcourse", p -> { + p.setLocation(start); + return Unit.INSTANCE; + }); + GameWorld.getPulser().submit(new Pulse(2, player) { + boolean failed; + int count; + + @Override + public boolean pulse() { + if (++count == 1) { + if (failed = AgilityHandler.hasFailed(player, 1, 0.15)) { + setDelay(1); + player.animate(Animation.create(743)); + return false; + } + setDelay(7); + AgilityHandler.walk(player, -1, player.getLocation().transform(dir), player.getLocation().transform(dir.getStepX() * 7, dir.getStepY() * 7, 0), Animation.create(662), 0.0, null); + } else if (count == 2) { + if (failed) { + player.getAppearance().setAnimations(); + player.getAppearance().sync(); + AgilityHandler.fail(player, 2, player.getLocation().transform(0, 0, -3), Animation.create(768), getHitAmount(player), "You missed a hand hold!"); + player.logoutListeners.remove("brimcourse"); + return true; + } + player.logoutListeners.remove("brimcourse"); + AgilityHandler.forceWalk(player, -1, player.getLocation(), player.getLocation().transform(dir), Animation.create(743), 10, getExp(player, 14.0), null); + return true; + } + return false; + } + }); + } + + /** + * Handles the balancing ledge obstacle. + * @param player The player. + * @param object The object. + */ + private static void handleBalancingLedge(final Player player, Scenery object) { + final int diff = object.getId() == 3561 ? 0 : 1; + Location start = player.getLocation(); + final Direction dir = Direction.getLogicalDirection(start, object.getLocation()); + Location end = object.getLocation(); + double xp = 0.0; + if (AgilityHandler.hasFailed(player, 1, 0.15)) { + player.lock(3); + GameWorld.getPulser().submit(new Pulse(2, player) { + @Override + public boolean pulse() { + Direction d = Direction.get((dir.toInteger() + 1) % 4); + AgilityHandler.fail(player, 1, player.getLocation().transform(d.getStepX(), d.getStepY(), -3), Animation.create(761 - diff), getHitAmount(player), "You lost your balance!"); + return true; + } + }); + } else { + xp = 16.0; + end = object.getLocation().transform(dir.getStepX() * 6, dir.getStepY() * 6, 0); + } + AgilityHandler.walk(player, -1, player.getLocation(), end, Animation.create(157 - diff), getExp(player, xp), null); + } + + /** + * Handles the plank obstacle. + * @param player The player. + * @param object The object. + */ + private static void handlePlankObstacle(final Player player, Scenery object) { + final Direction dir = Direction.getLogicalDirection(player.getLocation(), object.getLocation()); + final Location start = player.getLocation(); + Location end = start.transform(dir.getStepX() * 7, dir.getStepY() * 7, 0); + player.faceLocation(end); + if (object.getCharge() == 500) { // Plank is broken + player.lock(7); + AgilityHandler.walk(player, -1, start, start.transform(dir.getStepX() * 2, dir.getStepY() * 2, 0), new Animation(1426), 0.0, null); + GameWorld.getPulser().submit(new Pulse(3) { + boolean finish; + + @Override + public boolean pulse() { + if (!finish) { + setDelay(2); + AgilityHandler.fail(player, 1, player.getLocation().transform(0, 0, -3), Animation.create(189), getHitAmount(player), "You stepped on a broken piece of plank!"); + finish = true; + return false; + } + AgilityHandler.walk(player, -1, player.getLocation(), start.transform(dir), null, 0.0, null); + return true; + } + }); + return; + } + AgilityHandler.walk(player, -1, start, end, ForceMovement.WALK_ANIMATION, getExp(player, 6.0), null); + } + + /** + * Handles the pillars obstacle. + * @param player The player. + * @param object The object. + */ + private static void handlePillarObstacle(final Player player, Scenery object) { + final Direction dir = Direction.getLogicalDirection(player.getLocation(), object.getLocation()); + AgilityHandler.forceWalk(player, -1, player.getLocation(), object.getLocation(), Animation.create(741), 10, 0, null); + final Location start = player.getLocation(); + player.logoutListeners.put("brimcourse", p -> { + p.setLocation(start); + return Unit.INSTANCE; + }); + player.lock(12); + GameWorld.getPulser().submit(new Pulse(2, player) { + int count = 0; + + @Override + public boolean pulse() { + if (count == 0 && AgilityHandler.hasFailed(player, 1, 0.15)) { + Direction d = Direction.get((dir.toInteger() + 3) % 4); + player.unlock(); + player.lock(2); + AgilityHandler.fail(player, 2, player.getLocation().transform(d.getStepX() << 1, d.getStepY() << 1, -3), Animation.create(764), getHitAmount(player), "You lost your balance!"); + player.logoutListeners.remove("brimcourse"); + return true; + } + AgilityHandler.forceWalk(player, -1, player.getLocation(), player.getLocation().transform(dir), Animation.create(741), 10, count == 5 ? getExp(player, 18.0) : 0, null); + player.logoutListeners.remove("brimcourse"); + return ++count == 6; + } + }); + } + + /** + * Handles the log balance obstacle. + * @param player The player. + * @param object The log balance object. + */ + private static void handleLogBalance(final Player player, Scenery object) { + final Direction dir = Direction.getLogicalDirection(player.getLocation(), object.getLocation()); + boolean failed = AgilityHandler.hasFailed(player, 1, 0.1); + if (failed) { + Location end = player.getLocation().transform(dir); + AgilityHandler.forceWalk(player, -1, player.getLocation(), end, Animation.create(762), 10, 0.0, null); + GameWorld.getPulser().submit(new Pulse(2, player) { + @Override + public boolean pulse() { + Direction d = Direction.get((dir.toInteger() + 3) % 4); + AgilityHandler.fail(player, 2, player.getLocation().transform(d.getStepX() << 1, d.getStepY() << 1, -3), Animation.create(764), getHitAmount(player), "You lost your balance!"); + return true; + } + }); + return; + } + AgilityHandler.walk(player, -1, player.getLocation(), player.getLocation().transform(dir.getStepX() * 7, dir.getStepY() * 7, 0), Animation.create(155), getExp(player, 12.0), null); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(3566).getHandlers().put("option:swing-on", this); + SceneryDefinition.forId(3578).getHandlers().put("option:jump-on", this); + SceneryDefinition.forId(3565).getHandlers().put("option:climb-over", this); + SceneryDefinition.forId(3553).getHandlers().put("option:walk-on", this); + SceneryDefinition.forId(3557).getHandlers().put("option:walk-on", this); + SceneryDefinition.forId(3570).getHandlers().put("option:walk-on", this); + SceneryDefinition.forId(3571).getHandlers().put("option:walk-on", this); + SceneryDefinition.forId(3572).getHandlers().put("option:walk-on", this); + SceneryDefinition.forId(3559).getHandlers().put("option:walk-across", this); + SceneryDefinition.forId(3561).getHandlers().put("option:walk-across", this); + SceneryDefinition.forId(3564).getHandlers().put("option:swing-across", this); + SceneryDefinition.forId(3551).getHandlers().put("option:walk-on", this); + SceneryDefinition.forId(3583).getHandlers().put("option:climb-across", this); + return this; + } + + @Override + public Location getDestination(Node node, Node n) { + Scenery object = (Scenery) n; + Direction dir = object.getDirection(); + switch (object.getId()) { + case 3566: + return n.getLocation().transform(dir.getStepX() << 1, dir.getStepY() << 1, 0); + case 3564: + if (n.getLocation().getX() == 2771 && n.getLocation().getY() == 9570) { + return Location.create(2772, 9569, 3); + } + if (n.getLocation().getX() == 2771 && n.getLocation().getY() == 9577) { + return Location.create(2772, 9578, 3); + } + if (n.getLocation().getX() == 2793 && n.getLocation().getY() == 9566) { + return Location.create(2794, 9567, 3); + } + if (n.getLocation().getX() == 2793 && n.getLocation().getY() == 9559) { + return Location.create(2794, 9558, 3); + } + if (n.getLocation().getX() == 2781 && n.getLocation().getY() == 9545) { + return Location.create(2782, 9546, 3); + } + if (n.getLocation().getX() == 2774 && n.getLocation().getY() == 9545) { + return Location.create(2773, 9546, 3); + } + break; + case 3551: + return n.getLocation(); + } + return null; + } + + /** + * Gets the exp. + * @param player the player. + * @param exp the exp. + * @return the exp. + */ + private static double getExp(Player player, double exp) { + return player.getAchievementDiaryManager().getKaramjaGlove() > 1 ? exp + (exp * 0.10) : exp; + } + + /** + * Gets the amount of damage to deal. + * @param player The player. + * @return The amount of damage. + */ + private static int getHitAmount(Player player) { + int hit = player.getSkills().getLifepoints() / 12; + if (hit < 2) { + hit = 2; + } + return hit; + } +} diff --git a/Server/src/main/content/global/skill/agility/brimhaven/DartTrap.java b/Server/src/main/content/global/skill/agility/brimhaven/DartTrap.java new file mode 100644 index 0000000..086a595 --- /dev/null +++ b/Server/src/main/content/global/skill/agility/brimhaven/DartTrap.java @@ -0,0 +1,101 @@ +package content.global.skill.agility.brimhaven; + +import core.game.node.entity.skill.Skills; +import content.global.skill.agility.AgilityHandler; +import core.game.node.entity.Entity; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.player.Player; +import core.game.system.task.MovementHook; +import core.game.system.task.Pulse; +import kotlin.Unit; +import core.game.world.GameWorld; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.net.packet.PacketRepository; +import core.net.packet.context.CameraContext; +import core.net.packet.context.CameraContext.CameraType; +import core.net.packet.out.CameraViewPacket; +import core.tools.RandomFunction; + +/** + * Handles the darts trap. + * @author Emperor + */ +public final class DartTrap implements MovementHook { + + @Override + public boolean handle(Entity e, final Location l) { + final Direction dir = e.getDirection(); + final Player player = (Player) e; + final Location start = l.transform(-dir.getStepX(), -dir.getStepY(), 0); + e.lock(6); + if(e.isPlayer()) + { + e.asPlayer().logoutListeners.put("dart-trap", p -> { + p.setLocation(start); + return Unit.INSTANCE; + }); + } + final Location startProj = l.transform(dir.getStepX() * 5, dir.getStepY() * 5, 0); + GameWorld.getPulser().submit(new Pulse(2, e) { + boolean failed; + int count; + + @Override + public boolean pulse() { + if (++count == 1) { + if (failed = AgilityHandler.hasFailed(player, 40, 0.15)) { + if (player.getSkills().getLevel(Skills.AGILITY) < 40) { + player.getPacketDispatch().sendMessage("You need an agility of at least 40 to get past this trap!"); + } + Projectile.create(startProj, l, 270, 0, 10, 46, 85, 5, 11).send(); + setDelay(3); + } else { + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.POSITION, startProj.getX() + (dir.getStepX() * 4), startProj.getY() + (dir.getStepY() * 4), 350, 1, 100)); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.ROTATION, l.getX(), l.getY(), 350, 1, 100)); + Projectile.create(startProj, l.transform(-dir.getStepX() * 4, -dir.getStepY() * 4, 0), 270, 0, 0, 46, 200, 5, 11).send(); + } + } else if (count == 2) { + if (failed) { + int hit = player.getSkills().getLifepoints() / 12; + if (hit < 2) { + hit = 2; + } + setDelay(1); + AgilityHandler.failWalk(player, 1, l, start, start, Animation.create(1114), 10, hit, null).setDirection(dir); + } else { + if (dir.toInteger() % 2 != 0) { + int mod = dir == Direction.WEST ? -1 : 1; + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.POSITION, l.getX() - (5 * mod), l.getY() - (5 * mod), 400, 8, 6)); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.ROTATION, l.getX() + (2 * mod), l.getY(), 350, 8, 1)); + } else { + int mod = dir == Direction.SOUTH ? -1 : 1; + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.POSITION, l.getX() + (5 * mod), l.getY() - (5 * mod), 400, 8, 6)); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.ROTATION, l.getX(), l.getY() + (2 * mod), 350, 8, 1)); + } + player.lock(7); + player.animate(new Animation(1110, 20)); + setDelay(5); + } + } else if (count == 3) { + if (failed) { + player.getPacketDispatch().sendMessage("You were hit by some darts, something on them makes you feel dizzy!"); + player.getSkills().updateLevel(Skills.AGILITY, -(2 + RandomFunction.randomize(2)), 0); + player.logoutListeners.remove("dart-trap"); + return true; + } + setDelay(2); + AgilityHandler.walk(player, -1, l, l.transform(dir.getStepX() << 1, dir.getStepY() << 1, 0), null, 30.0, null); + } else if (count == 4) { + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.RESET, 0, 0, 0, 0, 0)); + player.logoutListeners.remove("dart-trap"); + return true; + } + return false; + } + }); + return false; + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/agility/brimhaven/FloorSpikes.java b/Server/src/main/content/global/skill/agility/brimhaven/FloorSpikes.java new file mode 100644 index 0000000..69111c6 --- /dev/null +++ b/Server/src/main/content/global/skill/agility/brimhaven/FloorSpikes.java @@ -0,0 +1,59 @@ +package content.global.skill.agility.brimhaven; + +import core.game.node.entity.skill.Skills; +import content.global.skill.agility.AgilityHandler; +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.system.task.MovementHook; +import core.game.system.task.Pulse; +import kotlin.Unit; +import core.game.world.GameWorld; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; + +/** + * Handles floor spikes trap. + * @author Emperor + */ +public final class FloorSpikes implements MovementHook { + + @Override + public boolean handle(Entity e, final Location l) { + final Direction dir = e.getDirection(); + final Player player = (Player) e; + final Location start = l.transform(-dir.getStepX(), -dir.getStepY(), 0); + e.lock(5); + if(e.isPlayer()) + { + ((Player) e).logoutListeners.put("floor-spikes", p -> { + p.setLocation(start); + return Unit.INSTANCE; + }); + } + GameWorld.getPulser().submit(new Pulse(3, e) { + @Override + public boolean pulse() { + player.getPacketDispatch().sendSceneryAnimation(RegionManager.getObject(l), Animation.create(1111)); + if (AgilityHandler.hasFailed(player, 20, 0.25)) { + if (player.getSkills().getLevel(Skills.AGILITY) < 20) { + player.getPacketDispatch().sendMessage("You need an agility of at least 20 to get past this trap!"); + } + int hit = player.getSkills().getLifepoints() / 12; + if (hit < 2) { + hit = 2; + } + AgilityHandler.failWalk(player, 1, player.getLocation(), start, start, Animation.create(1114), 10, hit, "You were hit by some floor spikes!").setDirection(dir); + ; + } else { + AgilityHandler.forceWalk(player, -1, l, l.transform(dir.getStepX() << 1, dir.getStepY() << 1, 0), Animation.create(1115), 20, 26, null); + } + player.logoutListeners.remove("floor-spikes"); + return true; + } + }); + return false; + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/agility/brimhaven/PressurePad.java b/Server/src/main/content/global/skill/agility/brimhaven/PressurePad.java new file mode 100644 index 0000000..a2bc07c --- /dev/null +++ b/Server/src/main/content/global/skill/agility/brimhaven/PressurePad.java @@ -0,0 +1,59 @@ +package content.global.skill.agility.brimhaven; + +import core.game.node.entity.skill.Skills; +import content.global.skill.agility.AgilityHandler; +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.system.task.MovementHook; +import core.game.system.task.Pulse; +import kotlin.Unit; +import core.game.world.GameWorld; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; + +/** + * Handles the pressure pad trap. + * @author Emperor + */ +public final class PressurePad implements MovementHook { + + @Override + public boolean handle(Entity e, final Location dest) { + final Direction dir = e.getDirection(); + final Player player = (Player) e; + final Location start = dest.transform(-dir.getStepX(), -dir.getStepY(), 0); + e.lock(5); + if(e.isPlayer()) + { + ((Player) e).logoutListeners.put("pressure-pad", p -> { + p.setLocation(start); + return Unit.INSTANCE; + }); + } + GameWorld.getPulser().submit(new Pulse(3, e) { + @Override + public boolean pulse() { + Graphics.send(Graphics.create(271), dest); + if (AgilityHandler.hasFailed(player, 20, 0.25)) { + if (player.getSkills().getLevel(Skills.AGILITY) < 20) { + player.getPacketDispatch().sendMessage("You need an agility of at least 20 to get past this trap!"); + } + int hit = player.getSkills().getLifepoints() / 12; + if (hit < 2) { + hit = 2; + } + AgilityHandler.failWalk(player, 1, player.getLocation(), start, start, Animation.create(1114), 10, hit, "You were hit by some falling rocks!").setDirection(dir); + ; + } else { + AgilityHandler.forceWalk(player, -1, dest, dest.transform(dir.getStepX() << 1, dir.getStepY() << 1, 0), Animation.create(1115), 20, 26, null); + } + player.logoutListeners.remove("pressure-pad"); + return true; + } + }); + return false; + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/agility/brimhaven/SpinningBlades.java b/Server/src/main/content/global/skill/agility/brimhaven/SpinningBlades.java new file mode 100644 index 0000000..a138157 --- /dev/null +++ b/Server/src/main/content/global/skill/agility/brimhaven/SpinningBlades.java @@ -0,0 +1,73 @@ +package content.global.skill.agility.brimhaven; + +import core.game.node.entity.skill.Skills; +import content.global.skill.agility.AgilityHandler; +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.system.task.MovementHook; +import core.game.system.task.Pulse; +import kotlin.Unit; +import core.game.world.GameWorld; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; + +/** + * Handles the spinning blades trap. + * @author Emperor + */ +public final class SpinningBlades implements MovementHook { + + @Override + public boolean handle(Entity e, final Location l) { + final Direction dir = e.getDirection(); + final Player player = (Player) e; + final Location start = l.transform(-dir.getStepX(), -dir.getStepY(), 0); + e.lock(5); + if(e.isPlayer()) + { + ((Player) e).logoutListeners.put("spin-blades", p -> { + p.setLocation(start); + return Unit.INSTANCE; + }); + } + GameWorld.getPulser().submit(new Pulse(3, e) { + @Override + public boolean pulse() { + sendObjectAnimation(player, l); + if (AgilityHandler.hasFailed(player, 40, 0.15)) { + if (player.getSkills().getLevel(Skills.AGILITY) < 40) { + player.getPacketDispatch().sendMessage("You need an agility of at least 40 to get past this trap!"); + } + int hit = player.getSkills().getLifepoints() / 12; + if (hit < 2) { + hit = 2; + } + AgilityHandler.failWalk(player, 1, player.getLocation(), start, start, Animation.create(1114), 10, hit, "You were hit by the spinning blades.").setDirection(dir); + } else { + AgilityHandler.forceWalk(player, -1, l, l.transform(dir.getStepX() << 1, dir.getStepY() << 1, 0), Animation.create(1115), 20, 26, null); + } + player.logoutListeners.remove("spin-blades"); + return true; + } + }); + return false; + } + + /** + * Sends the object animation for the spinning blades. + * @param player The player. + * @param l The location. + */ + private static void sendObjectAnimation(Player player, Location l) { + if (l.equals(Location.create(2778, 9579, 3))) { + l = Location.create(2777, 9580, 3); + } else if (l.equals(Location.create(2783, 9574, 3))) { + l = Location.create(2782, 9573, 3); + } else if (l.equals(Location.create(2778, 9557, 3))) { + l = Location.create(2777, 9556, 3); + } + player.getPacketDispatch().sendSceneryAnimation(RegionManager.getObject(l), Animation.create(1107)); + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/agility/pyramid/AgilityPyramidCourse.java b/Server/src/main/content/global/skill/agility/pyramid/AgilityPyramidCourse.java new file mode 100644 index 0000000..06cae7b --- /dev/null +++ b/Server/src/main/content/global/skill/agility/pyramid/AgilityPyramidCourse.java @@ -0,0 +1,575 @@ +package content.global.skill.agility.pyramid; + +import core.cache.def.impl.VarbitDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.game.global.action.ClimbActionHandler; +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import content.global.skill.agility.AgilityCourse; +import content.global.skill.agility.AgilityHandler; +import core.game.node.Node; +import core.game.node.entity.impl.ForceMovement; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.ClassScanner; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.*; + +/** + * Handles the agility pryamid course. + * @author Vexia + */ +@Initializable +public final class AgilityPyramidCourse extends AgilityCourse { + + /** + * The pyramid top item. + */ + private static final Item PYRAMID_TOP = new Item(6970); + + /** + * The config id to use. + */ + private static final int CONFIG_ID = 640; + + /** + * The jump gap location data. + */ + private static final Location[][] GAP_LOCATIONS = new Location[][] { { new Location(3356, 2847, 2), Location.create(3357, 2847, 2), Location.create(3356, 2846, 2), Location.create(3357, 2846, 2), Location.create(3356, 2849, 2), Location.create(3357, 2849, 2) }, { new Location(3364, 2833, 2), Location.create(3364, 2834, 2), Location.create(3366, 2834, 2), Location.create(3366, 2833, 2), Location.create(3363, 2834, 2), Location.create(3363, 2833, 2) }, { new Location(3370, 2841, 3), new Location(3371, 2841, 3), Location.create(3370, 2840, 3), Location.create(3371, 2840, 3), Location.create(3370, 2843, 3), Location.create(3371, 2843, 3) }, { new Location(3040, 4697, 2), Location.create(3041, 4697, 2), Location.create(3041, 4696, 2), Location.create(3040, 4696, 2), Location.create(3041, 4699, 2), Location.create(3040, 4699, 2) }, { new Location(3048, 4695, 2), Location.create(3049, 4695, 2), Location.create(3048, 4694, 2), Location.create(3049, 4694, 2), Location.create(3048, 4697, 2), Location.create(3049, 4697, 2) }, { Location.create(3046, 4697, 3), Location.create(3047, 4697, 3), Location.create(3046, 4696, 3), Location.create(3047, 4696, 3), Location.create(3046, 4699, 3), Location.create(3047, 4699, 3) } }; + + /** + * The ledge crossing location data. + */ + private static final Location[][] LEDGE_LOCATIONS = new Location[][] { { new Location(3366, 2851, 1), new Location(3364, 2851, 1), Location.create(3368, 2851, 1), Location.create(3363, 2851, 1), Location.create(3367, 2851, 1), Location.create(3364, 2851, 1) }, { new Location(3362, 2831, 1), new Location(3360, 2831, 1), Location.create(3364, 2832, 1), Location.create(3359, 2832, 1), Location.create(3360, 2832, 1), Location.create(3363, 2832, 1) }, { new Location(3372, 2837, 2), new Location(3372, 2839, 2), Location.create(3372, 2841, 2), Location.create(3372, 2836, 2), Location.create(3372, 2837, 2), Location.create(3372, 2840, 2) }, { new Location(3358, 2843, 3), new Location(3358, 2845, 3), Location.create(3359, 2842, 3), Location.create(3359, 2847, 3), Location.create(3359, 2846, 3), Location.create(3359, 2843, 3) } }; + + /** + * The gap crossing location data. + */ + private static final Location[][] GAP_CROSS_LOCATIONS = new Location[][] { { new Location(3368, 2831, 1), new Location(3370, 2831, 1), Location.create(3372, 2832, 1), Location.create(3367, 2832, 1), Location.create(3371, 2832, 1), Location.create(3368, 2832, 1) }, { new Location(3356, 2837, 2), new Location(3356, 2839, 2), Location.create(3357, 2841, 2), Location.create(3357, 2836, 2), Location.create(3357, 2840, 2), Location.create(3357, 2837, 2) }, { new Location(3360, 2849, 2), new Location(3362, 2849, 2), Location.create(3359, 2849, 2), Location.create(3364, 2849, 2), Location.create(3363, 2849, 2), Location.create(3360, 2849, 2) } }; + + /** + * Constructs a new {@code AgilityPyramidCourse} {@code Object}. + */ + public AgilityPyramidCourse() { + this(null); + } + + /** + * Constructs a new {@code AgilityPyramidCourse} {@code Object}. + * @param player the player. + */ + public AgilityPyramidCourse(Player player) { + super(player, 5, 0); + } + + @Override + public void configure() { + SceneryDefinition.forId(16535).getHandlers().put("option:climb", this); + SceneryDefinition.forId(16536).getHandlers().put("option:climb", this); + SceneryDefinition.forId(10851).getHandlers().put("option:climb", this); + SceneryDefinition.forId(10855).getHandlers().put("option:enter", this); + SceneryDefinition.forId(10856).getHandlers().put("option:enter", this); + SceneryDefinition.forId(10860).getHandlers().put("option:cross", this); + SceneryDefinition.forId(10861).getHandlers().put("option:cross", this); + SceneryDefinition.forId(10862).getHandlers().put("option:cross", this); + SceneryDefinition.forId(10863).getHandlers().put("option:cross", this); + SceneryDefinition.forId(10864).getHandlers().put("option:cross", this); + SceneryDefinition.forId(10868).getHandlers().put("option:cross", this); + SceneryDefinition.forId(10867).getHandlers().put("option:cross", this); + SceneryDefinition.forId(10882).getHandlers().put("option:cross", this); + SceneryDefinition.forId(10883).getHandlers().put("option:cross", this); + SceneryDefinition.forId(10884).getHandlers().put("option:cross", this); + SceneryDefinition.forId(10885).getHandlers().put("option:cross", this); + SceneryDefinition.forId(10886).getHandlers().put("option:cross", this); + SceneryDefinition.forId(10887).getHandlers().put("option:cross", this); + SceneryDefinition.forId(10888).getHandlers().put("option:cross", this); + SceneryDefinition.forId(10889).getHandlers().put("option:cross", this); + SceneryDefinition.forId(10859).getHandlers().put("option:jump", this); + SceneryDefinition.forId(10857).getHandlers().put("option:climb-up", this); + SceneryDefinition.forId(10858).getHandlers().put("option:climb-down", this); + SceneryDefinition.forId(10865).getHandlers().put("option:climb-over", this); + RollingBlock.BlockSets.values(); + ClassScanner.definePlugin(new MovingBlockNPC()); + ClassScanner.definePlugin(new AgilityPyramidZone()); + } + + @Override + public boolean handle(final Player player, Node node, String option) { + getCourse(player); // Sets the extension. + final Scenery object = (Scenery) node; + if (object.getLocation().getDistance(player.getLocation()) >= 3) { + player.getPacketDispatch().sendMessage("I can't reach that!"); + return true; + } + switch (object.getId()) { + case 16535: + case 16536: + handleRockClimb(player, object); + break; + case 10865: + handleLowWall(player, object); + break; + case 10888: + case 10889: + case 10860: + case 10886: + case 10887: + handleLedge(player, object); + break; + case 10868: + case 10867: + handlePlank(player, object); + break; + case 10882: + case 10883: + case 10884: + case 10885: + case 10861: + case 10862: + case 10863: + case 10864: + handleGapCross(player, object); + break; + case 10857: + case 10858: + handleStairs(player, object); + break; + case 10851: + handlePyramidTop(player, object); + break; + case 10859: + handleJumpGap(player, object); + break; + case 10855: + case 10856: + addConfig(player, 10869, 0, true); + if (getVarp(player, 640) == 505 || getVarp(player, 640) == 515) { + player.getSkills().addExperience(Skills.AGILITY, 300, true); + } + player.getDialogueInterpreter().sendDialogue("You climb down the steep passage. It leads to the base of the", "pyramid."); + player.getProperties().setTeleportLocation(Location.create(3364, 2830, 0)); + player.getSavedData().getActivityData().setTopGrabbed(false); + break; + } + return true; + } + + /** + * Handles the stairs. + * @param player the player. + * @param object the object. + */ + private void handleStairs(final Player player, final Scenery object) { + Direction dir = Direction.getLogicalDirection(player.getLocation(), object.getLocation()); + Location dest = null; + if (dir == Direction.NORTH) { + dest = object.getLocation().transform(0, 2, 1); + } else if (dir == Direction.SOUTH) { + dest = object.getLocation().transform(0, -1, -1); + } + if (object.getLocation().equals(Location.create(3360, 2837, 3))) { + dest = Location.create(3040, 4695, 2); + } else if (object.getLocation().equals(Location.create(3040, 4693, 2))) { + dest = Location.create(3360, 2836, 3); + } else if (object.getLocation().equals(new Location(3354, 2831, 0))) { + addConfig(player, 10869, 0, true); + } + ClimbActionHandler.climb(player, null, dest); + } + + /** + * Handles the rock climbing obstacle. + * @param player the player. + * @param object the object. + */ + private void handleRockClimb(final Player player, final Scenery object) { + final boolean scale = player.getLocation().getX() < object.getLocation().getX(); + final Location end = object.getLocation().transform(scale ? 2 : -2, 0, 0); + if (object.getId() == 16536 && player.getSkills().getStaticLevel(Skills.AGILITY) < 30) { + player.getPacketDispatch().sendMessage("You must be level 30 agility or higher to climb down the rocks."); + return; + } + playAudio(player, Sounds.CLIMBING_LOOP_2454, 0, 6); + if (!scale) { + ForceMovement.run(player, player.getLocation(), end, Animation.create(740), Animation.create(740), Direction.WEST, 13).setEndAnimation(Animation.RESET); + } else { + ForceMovement.run(player, player.getLocation(), end, Animation.create(1148), Animation.create(1148), Direction.WEST, 13).setEndAnimation(Animation.RESET); + } + } + + /** + * Handles the low wall obstacle. + * @param player the player. + * @param object the object. + */ + private void handleLowWall(final Player player, final Scenery object) { + Direction d = Direction.getDirection(player.getLocation(), object.getLocation()); + final boolean fail = player.getSkills().getLevel(Skills.AGILITY) >= 75 ? false : hasFailed(player) ; + if (player.getLocation().equals(Location.create(3355, 2848, 1)) || player.getLocation().equals(Location.create(3359, 2838, 3))) { + d = Direction.NORTH; + } else if (player.getLocation().equals(Location.create(3355, 2850, 1)) || player.getLocation().equals(Location.create(3359, 2840, 3))) { + d = Direction.SOUTH; + } else if (player.getLocation().equals(Location.create(3046, 4694, 2)) || player.getLocation().equals(Location.create(3355, 2850, 1)) || player.getLocation().equals(Location.create(3041, 4702, 2)) || player.getLocation().equals(new Location(3369, 2834, 2))) { + d = Direction.EAST; + } else if (player.getLocation().equals(Location.create(3048, 4694, 2)) || player.getLocation().equals(Location.create(3371, 2834, 2)) || player.getLocation().equals(Location.create(3043, 4702, 2))) { + d = Direction.WEST; + } + player.lock(4); + player.getPacketDispatch().sendMessage("You climb the low wall..."); + playAudio(player, Sounds.CLIMB_WALL_2453, 40); + if (fail) { + Location end = player.getLocation().transform(d, 1); + player.lock(3); + AgilityHandler.failWalk(player, 2, player.getLocation(), end, end, Animation.create(1106), 15, getHitAmount(player), "You lost your balance!"); + AgilityHandler.forceWalk(player, -1, end, player.getLocation(), ForceMovement.WALK_ANIMATION, 10, 0.0, null, 4); + return; + } + AgilityHandler.forceWalk(player, 0, player.getLocation(), player.getLocation().transform(d, 2), Animation.create(1252), 6, 8, "... and make it over."); + player.animate(Animation.RESET, 4); + } + + /** + * Handles the ledge crossing obstacle. + * @param player the player. + * @param object the object. + */ + private void handleLedge(final Player player, final Scenery object) { + Direction d = Direction.getLogicalDirection(player.getLocation(), getLedgeLocation(player, object)); + final Direction dir = d; + final int diff = object.getRotation() == 3 && dir == Direction.EAST ? 1 : object.getRotation() == 3 && dir == Direction.WEST ? 0 : d == Direction.EAST || (d == Direction.SOUTH && object.getRotation() != 0) || d == Direction.NORTH ? 0 : 1; + final boolean fail = player.getSkills().getLevel(Skills.AGILITY) < 75 && hasFailed(player); + final Location end = player.getLocation().transform(dir.getStepX() * (fail ? 3 : 5), dir.getStepY() * (fail ? 3 : 5), 0); + player.getPacketDispatch().sendMessage("You put your foot on the ledge and try to edge across..."); + playAudio(player, Sounds.BALANCING_LEDGE_2451, 0, 5); + if (fail) { + player.lock(4); + playAudio(player, Sounds.FALL_LAND_2455, 125); + AgilityHandler.walk(player, -1, player.getLocation(), end, Animation.create(157 - diff), 0.0, "You slip and fall to the level below."); + GameWorld.getPulser().submit(new Pulse(3, player) { + @Override + public boolean pulse() { + Location dest = end; + int x = 0, y = 0; + switch (dir) { + case NORTH: + case SOUTH: + if (object.getRotation() == 2) { + x = 2; + } else { + x = -2; + } + break; + case WEST: + case EAST: + if (object.getRotation() == 3) { + y = -2; + } else if (object.getRotation() == 1) { + y = 2; + } + break; + default: + break; + } + AgilityHandler.fail(player, 1, transformLevel(dest.transform(x, y, 0)), Animation.create(761 - diff), 10, null); + return true; + } + }); + return; + } + AgilityHandler.walk(player, 3, player.getLocation(), end, Animation.create(157 - diff), 52, "You skillfully edge across the gap."); + } + + /** + * Handles the plank crossin obstacle. + * @param player the player. + * @param object the object. + */ + private void handlePlank(final Player player, final Scenery object) { + final boolean custom = object.getLocation().equals(new Location(3365, 2835, 3)) || object.getLocation().equals(new Location(3370, 2835, 3)); + final Direction dir = custom ? Direction.EAST : Direction.getLogicalDirection(player.getLocation(), object.getLocation()); + final boolean fail = player.getSkills().getLevel(Skills.AGILITY) >= 75 ? false : hasFailed(player) ; + final Location end = object.getLocation().transform(object.getId() != 10868 ? dir : dir.getOpposite(), fail ? 2 : 5); + AgilityHandler.walk(player, fail ? -1 : 1, player.getLocation(), end, Animation.create(155), fail ? 0.0 : 56.4, fail ? null : "You walk carefully across the slippery plank..."); + playAudio(player, Sounds.PLANKWALK_2480, 0, 3); + if (fail) { + GameWorld.getPulser().submit(new Pulse(2, player) { + @Override + public boolean pulse() { + final Location dest = transformLevel(end.transform(!custom ? 2 : 0, custom ? -2 : 0, 0)); + playAudio(player, Sounds.FALL_LAND_2455, 50); + AgilityHandler.failWalk(player, 2, end, dest, dest, Animation.create(764), 10, 10, null); + return true; + } + }); + } + } + + /** + * Handles the gab crossing obstacle. + * @param player the player. + * @param object the object. + */ + private void handleJumpGap(Player player, Scenery object) { + final Direction dir = Direction.getDirection(player.getLocation(), getGapLocation(player, object)); + final boolean fail = player.getSkills().getLevel(Skills.AGILITY) >= 75 ? false : hasFailed(player) ; + player.getPacketDispatch().sendMessage("You jump the gap..."); + if (fail) { + final boolean regular = object.getRotation() == 0 || object.getRotation() == 3; + Location end = player.getLocation().transform(dir, 1); + Location dest = object.getLocation().transform(dir, 1); + if (!regular) { + dest = dest.transform(dir == Direction.NORTH || dir == Direction.SOUTH ? 2 : 0, dir == Direction.SOUTH ? 1 : 0, 0); + } else { + dest = dest.transform(dir == Direction.NORTH || dir == Direction.SOUTH ? -1 : dir == Direction.WEST ? 1 : 0, dir == Direction.SOUTH ? 1 : dir == Direction.WEST || dir == Direction.EAST ? -1 : 0, 0); + } + dest = transformLevel(dest); + player.lock(8); + playAudio(player, Sounds.JUMP_NO_LAND_2467, 30); + playAudio(player, Sounds.FALL_LAND_2455, 200); + AgilityHandler.forceWalk(player, -1, player.getLocation(), end, Animation.create(3068), 10, 0.0, "... and miss your footing."); + AgilityHandler.fail(player, 8, dest, Animation.create(3068), 8, null); + return; + } + playAudio(player, Sounds.JUMP2_2462, 30); + player.lock(4); + AgilityHandler.forceWalk(player, 2, player.getLocation(), player.getLocation().transform(dir, 3), Animation.create(3067), 20, 22, null); + } + + /** + * Handles the gap cross obstacle. + * @param player the player. + * @param object the object. + */ + private void handleGapCross(final Player player, final Scenery object) { + final Direction dir = Direction.getLogicalDirection(player.getLocation(), getGapCrossLocation(player, object)); + final boolean fail = player.getSkills().getLevel(Skills.AGILITY) >= 75 ? false : hasFailed(player) ; + final Location end = player.getLocation().transform(dir, fail ? 4 : 5); + final int rot = object.getRotation(); + int mod = player.getLocation().equals(new Location(3359, 2849, 2)) ? 0 : player.getLocation().equals(new Location(3357, 2841, 2)) ? 1 : player.getLocation().equals(new Location(3367, 2832, 1)) ? 1 : player.getLocation().equals(new Location(3372, 2832, 1)) ? 0 : object.getLocation().equals(new Location(3370, 2831, 1)) ? 0 : rot == 1 && dir == Direction.EAST ? 0 : rot == 3 && (dir == Direction.WEST || dir == Direction.EAST) ? 1 : rot == 0 && dir == Direction.SOUTH ? 1 : dir == Direction.WEST && rot != 3 || dir == Direction.EAST ? 1 : 0; + final Animation animation = Animation.create(387 - mod); + playAudio(player, Sounds.HANDHOLDS_GRAB_TO_SECOND_2450); + playAudio(player, Sounds.FALL_LAND_2455, 170); + if (fail) { + Location dest = object.getLocation().transform(dir, 1); + dest = rot == 1 && dir == Direction.EAST ? dest.transform(1, 2, 0) : rot == 1 && dir == Direction.WEST && player.getLocation().getY() < 2841 ? dest.transform(0, -2, 0) : rot == 1 && dir == Direction.WEST ? dest.transform(0, 2, 0): dest.transform(dir == Direction.NORTH || dir == Direction.SOUTH ? -1 : dir == Direction.WEST ? 1 : 0, dir == Direction.SOUTH ? 1 : dir == Direction.WEST || dir == Direction.EAST ? -1 : 0, 0); + AgilityHandler.walk(player, -1, player.getLocation(), end, animation, 10, null); + Location finalDest = dest; + GameWorld.getPulser().submit(new Pulse(3, player) { + @Override + public boolean pulse() { + AgilityHandler.fail(player, 3, transformLevel(finalDest), Animation.create(3056 - mod), 8, null); + player.getAppearance().setDefaultAnimations(); + player.getAppearance().sync(); + return true; + } + }); + return; + } + AgilityHandler.walk(player, 4, player.getLocation(), end, animation, 22, null); + } + + /** + * Handles the pyramid top obstacle. + * @param player the player. + * @param object the object. + */ + private void handlePyramidTop(final Player player, final Scenery object) { + if(player.getSavedData().getActivityData().isTopGrabbed() == true){ + player.getPacketDispatch().sendMessage("You've already claimed this!"); + return; + } else { + player.animate(Animation.create(3063)); + GameWorld.getPulser().submit(new Pulse(3, player) { + @Override + public boolean pulse() { + player.getSkills().addExperience(Skills.AGILITY, 1000); + if (getVarp(player, 640) == 505 || getVarp(player, 640) == 515) { + player.getPacketDispatch().sendMessage("You find nothing on top of the pyramid."); + return true; + } + addConfig(player, 10869, 1, true); + player.getSavedData().getActivityData().setTopGrabbed(true); + player.getInventory().add(PYRAMID_TOP, player); + player.getDialogueInterpreter().sendItemMessage(PYRAMID_TOP, "You find a golden pyramid!"); + playJingle(player, 151); + return true; + } + }); + } + } + + /** + * Transforms a pyramid level. + * @param location the location. + * @return the location. + */ + public static Location transformLevel(Location location) { + int xDiff = 320; + int yDiff = 1856; + if (location.getRegionId() == 12105 && location.getZ() == 2) { + return new Location(location.getX() + xDiff, location.getY() - yDiff, 3); + } + return location.transform(0, 0, -1); + } + + /** + * Gets the gap location. + * @param player the player. + * @param object the obejct. + * @return the location. + */ + private Location getGapLocation(Player player, Scenery object) { + final Location[] data = getLocationData(GAP_LOCATIONS, object.getLocation()); + return getClosest(new Location[] { data[0], data[1] }, player.getLocation()); + } + + /** + * Gets the gap cross location. + * @param player the player. + * @param object the obejct. + * @return the location. + */ + private Location getGapCrossLocation(Player player, Scenery object) { + final Location[] data = getLocationData(GAP_CROSS_LOCATIONS, object.getLocation()); + return getClosest(new Location[] { data[4], data[5] }, player.getLocation()); + } + + /** + * Gets the ledge location. + * @param player the player. + * @param object the object. + * @return the location. + */ + private Location getLedgeLocation(final Player player, final Scenery object) { + final Location[] data = getLocationData(LEDGE_LOCATIONS, object.getLocation()); + return getClosest(new Location[] { data[4], data[5] }, player.getLocation()); + } + + /** + * Gets the closest location. + * @param data the data. + * @param location the location. + * @return the closest location. + */ + private Location getClosest(Location[] data, Location location) { + Location closest = null; + for (Location l : data) { + if (closest == null || l.getDistance(location) < closest.getDistance(location)) { + closest = l; + } + } + return closest; + } + + /** + * Gets the location data. + * @param data the data. + * @param location the location. + * @return the data. + */ + private Location[] getLocationData(Location[][] data, Location location) { + for (int i = 0; i < data.length; i++) { + for (Location l : data[i]) { + if (l.equals(location)) { + return data[i]; + } + } + } + return null; + } + + /** + * Checks if the player has failed. + * @param player the player. + * @return {@code True} if so. + */ + private boolean hasFailed(final Player player) { + return hasFailed(player, 0.009000); + } + + /** + * Checks if the player has failed. + * @param player the player. + * @param mod the mod. + * @return {@code True} if so. + */ + private boolean hasFailed(final Player player, double mod) { + return AgilityHandler.hasFailed(player, 10, mod); + } + + /** + * Sets the config id. + * @param player the player. + * @param objectId the object. + * @param value the value. + */ + public static void addConfig(final Player player, final int objectId, final int value, boolean save) { + final VarbitDefinition definition = VarbitDefinition.forObjectID(SceneryDefinition.forId(objectId).getVarbitID()); + final int oldVal = (definition.getValue(player) << definition.getStartBit()); + final int newVal = (value << definition.getStartBit()); + setVarp(player, CONFIG_ID, (getVarp(player, CONFIG_ID) - oldVal) + newVal, save); + } + + /** + * Sets the config id. + * @param player the player. + * @param object the object. + * @param value the value. + * @param save if we save. + */ + public static void addConfig(final Player player, final Scenery object, final int value, boolean save) { + addConfig(player, object.getId(), value, save); + } + + @Override + public Location getDestination(Node node, Node n) { + switch (n.getId()) { + case 16535: + case 16536: + return n.getLocation().transform(node.getLocation().getX() < n.getLocation().getX() ? -1 : 1, 0, 0); + case 10865: + return null; + case 10857: + return n.getLocation().transform(0, -1, 0); + case 10858: + return n.getLocation().transform(0, 2, 0); + case 10859: + return getClosest(getLocationData(GAP_LOCATIONS, n.getLocation()), node.getLocation()); + case 10860: + case 10886: + case 10887: + case 10888: + case 10889: + return getClosest(getLocationData(LEDGE_LOCATIONS, n.getLocation()), node.getLocation()); + case 10868: + case 10867: + return n.getLocation(); + case 10882: + case 10883: + case 10884: + case 10885: + case 10861: + case 10862: + case 10863: + case 10864: + if (n.getId() == 10863 && n.getLocation().equals(new Location(3372, 2832, 1))) { + return Location.create(3372, 2832, 1); + } + return getClosest(getLocationData(GAP_CROSS_LOCATIONS, n.getLocation()), node.getLocation()); + } + return null; + } + + @Override + public AgilityCourse createInstance(Player player) { + return new AgilityPyramidCourse(player); + } + +} diff --git a/Server/src/main/content/global/skill/agility/pyramid/AgilityPyramidZone.java b/Server/src/main/content/global/skill/agility/pyramid/AgilityPyramidZone.java new file mode 100644 index 0000000..f3247e7 --- /dev/null +++ b/Server/src/main/content/global/skill/agility/pyramid/AgilityPyramidZone.java @@ -0,0 +1,73 @@ +package content.global.skill.agility.pyramid; + +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.system.task.MovementHook; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneBuilder; +import core.plugin.Plugin; + +import java.util.HashMap; +import java.util.Map; + +/** + * Represents the agility pyramid area. + * @author 'Vexia + * @version 1.0 + */ +public final class AgilityPyramidZone extends MapZone implements Plugin { + + /** + * The location based traps. + */ + public static final Map LOCATION_TRAPS = new HashMap<>(); + + /** + * Constructs a new {@code AgilityPyramid} {@code Object}. + */ + public AgilityPyramidZone() { + super("agility pyramid", true); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ZoneBuilder.configure(this); + return this; + } + + @Override + public boolean enter(Entity e) { + if (e instanceof Player) { + final Player player = (Player) e; + AgilityPyramidCourse.addConfig(player, 10872, 1, true); + AgilityPyramidCourse.addConfig(player, 10873, 3, true); + } + return super.enter(e); + } + + @Override + public boolean move(Entity e, Location loc, Location dest) { + if (!e.getLocks().isMovementLocked() && e instanceof Player) { + MovementHook hook = LOCATION_TRAPS.get(loc); + if (hook != null) { + e.setDirection(Direction.getLogicalDirection(loc, dest)); + return hook.handle(e, loc); + } + } + return super.move(e, loc, dest); + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public void configure() { + register(new ZoneBorders(3352, 2826, 3378, 2854)); + register(new ZoneBorders(3007, 4672, 3071, 4735)); + } +} diff --git a/Server/src/main/content/global/skill/agility/pyramid/MovingBlockNPC.java b/Server/src/main/content/global/skill/agility/pyramid/MovingBlockNPC.java new file mode 100644 index 0000000..984fd53 --- /dev/null +++ b/Server/src/main/content/global/skill/agility/pyramid/MovingBlockNPC.java @@ -0,0 +1,182 @@ +package content.global.skill.agility.pyramid; + +import content.global.skill.agility.AgilityHandler; +import core.game.node.entity.Entity; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.system.task.MovementHook; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playAudio; + +/** + * The moving block npc. + * @author 'Vexia + * @version 1.0 + */ +public final class MovingBlockNPC extends AbstractNPC { + + /** + * The tile locations. + */ + private static final Location[][] LOCATIONS = new Location[][] { { Location.create(3366, 2847, 3), Location.create(3367, 2847, 3), Location.create(3367, 2848, 3), Location.create(3366, 2848, 3), Location.create(3365, 2847, 3), Location.create(3365, 2848, 3), Location.create(3368, 2847, 3), Location.create(3368, 2848, 3) }, { Location.create(3374, 2847, 1), Location.create(3374, 2848, 1), Location.create(3375, 2848, 1), Location.create(3375, 2847, 1), Location.create(3374, 2849, 1), Location.create(3375, 2849, 1), Location.create(3374, 2846, 1), Location.create(3375, 2846, 1) } }; + + /** + * The next move delay. + */ + private int nextMove; + + /** + * If its moving. + */ + private boolean moving; + + /** + * Constructs a new {@code MovingBlockNPC} {@code Object}. + */ + public MovingBlockNPC() { + super(-1, null); + } + + /** + * Constructs a new {@code MovingBlockNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + public MovingBlockNPC(int id, Location location) { + super(id, location, false); + } + + @Override + public void tick() { + super.tick(); + if (nextMove < GameWorld.getTicks() && nextMove != -1) { + Direction dir = getId() == 3124 ? Direction.EAST : Direction.NORTH; + Location loc = getLocation().transform(dir, 2); + getWalkingQueue().reset(); + getWalkingQueue().addPath(loc.getX(), loc.getY()); + for (Player p : RegionManager.getLocalPlayers(getTileLocations()[0], 4)) { + checkBlock(p); + playAudio(p, Sounds.PYRAMID_BLOCK_1395, 30); + } + moving = true; + GameWorld.getPulser().submit(new Pulse(1, this) { + int counter; + + @Override + public boolean pulse() { + switch (++counter) { + case 1: + for (Player p : RegionManager.getLocalPlayers(getTileLocations()[0], 2)) { + checkBlock(p); + } + break; + case 3: + getWalkingQueue().reset(); + getWalkingQueue().addPath(getProperties().getSpawnLocation().getX(), getProperties().getSpawnLocation().getY()); + nextMove = GameWorld.getTicks() + 13; + break; + case 5: + moving = false; + return true; + } + return false; + } + }); + nextMove = -1; + } + } + + @Override + public void init() { + super.init(); + final MovingBlockTrap trap = new MovingBlockTrap(); + for (Location l : getTileLocations()) { + AgilityPyramidZone.LOCATION_TRAPS.put(l, trap); + } + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new MovingBlockNPC(id, location); + } + + /** + * Checks if a player is going to get hit by a block. + * @param player the player. + */ + public void checkBlock(final Player player) { + if (player.getAttribute("block-move", -1) > GameWorld.getTicks()) { + return; + } + Location[] locs = getTileLocations(); + for (int i = 0; i < 4; i++) { + if (locs[i].equals(player.getLocation())) { + GameWorld.getPulser().submit(new Pulse(1, player) { + @Override + public boolean pulse() { + boolean close = getProperties().getSpawnLocation().getDistance(player.getLocation()) > (getId() == 3124 ? 2 : 2.3); + Location dest = null; + if (getId() == 3124) { + if (player.getLocation().getY() == 2847) { + dest = Location.create(3376, 2847, 1); + } else if (player.getLocation().getY() == 2848) { + dest = Location.create(3376, 2848, 1); + } + } else { + if (player.getLocation().getX() == 3366) { + dest = Location.create(3366, 2849, 3); + } else if (player.getLocation().getX() == 3367) { + dest = Location.create(3367, 2849, 3); + } + } + player.lock(4); + playAudio(player, Sounds.LAND_FLAT_2469, 50); + player.setAttribute("block-move", GameWorld.getTicks() + 4); + if(dest != null) { + AgilityHandler.failWalk(player, close ? 1 : 3, player.getLocation(), dest, AgilityPyramidCourse.transformLevel(dest), Animation.create(3066), 10, 8, null, getId() == 3124 ? Direction.WEST : Direction.SOUTH); + } + return true; + } + }); + return; + } + } + } + + /** + * Gets the tile locations. + * @return the locations. + */ + public Location[] getTileLocations() { + return LOCATIONS[3125 - getId()]; + } + + @Override + public int[] getIds() { + return new int[] { 3124, 3125 }; + } + + /** + * The movement hook to handle a moving block. + * @author 'Vexia + * @version 1.0 + */ + public final class MovingBlockTrap implements MovementHook { + + @Override + public boolean handle(Entity e, Location l) { + if (moving) { + return false; + } + return true; + } + + } +} diff --git a/Server/src/main/content/global/skill/agility/pyramid/RollingBlock.java b/Server/src/main/content/global/skill/agility/pyramid/RollingBlock.java new file mode 100644 index 0000000..7573889 --- /dev/null +++ b/Server/src/main/content/global/skill/agility/pyramid/RollingBlock.java @@ -0,0 +1,175 @@ +package content.global.skill.agility.pyramid; + +import content.global.skill.agility.AgilityHandler; +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.system.task.MovementHook; +import core.game.system.task.Pulse; +import kotlin.Unit; +import core.game.world.GameWorld; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playAudio; + +/** + * Represents the rolling block obstacle. + * @author 'Vexia + * @version 1.0 + */ +public final class RollingBlock implements MovementHook { + + @Override + public boolean handle(final Entity e, final Location dest) { + final Player player = (Player) e; + final BlockSets set = BlockSets.forLocation(dest); + final Scenery stone = RegionManager.getObject(set.getBlockLocation()); + final boolean backwards = isBackwards(stone.getDirection(), player.getDirection(), stone.getRotation()); + final boolean fail = backwards || AgilityHandler.hasFailed(player, 2, 0.3); + player.lock(5); + AgilityPyramidCourse.addConfig(player, stone, 1, false); + playAudio(player, Sounds.PYRAMID_SCRAPE_1396); + playAudio(player, Sounds.LAND_FLAT_2469, 40); + + if(e.isPlayer()) + { + ((Player) e).logoutListeners.put("rolling-block", p -> { + p.setLocation(e.getLocation().transform(0,0,0)); + return Unit.INSTANCE; + }); + } + if (fail) { + GameWorld.getPulser().submit(new Pulse(1, player) { + int counter; + + @Override + public boolean pulse() { + switch (++counter) { + case 1: + final Location end = player.getLocation().transform(stone.getDirection(), -2); + final int hit = backwards ? 1 : 6; + if (set == BlockSets.FOUR) { + AgilityHandler.failWalk(player, 3, dest, end, AgilityPyramidCourse.transformLevel(end), Animation.create(1116), 10, hit, null); + } else { + AgilityHandler.failWalk(player, -1, dest, AgilityPyramidCourse.transformLevel(end), AgilityPyramidCourse.transformLevel(end), Animation.create(1116), 10, hit, null); + } + break; + case 3: + AgilityPyramidCourse.addConfig(player, stone, 0, true); + player.logoutListeners.remove("rolling-block"); + return true; + } + return false; + } + }); + return false; + } + AgilityHandler.forceWalk(player, -1, dest, dest.transform(player.getDirection(), 2), Animation.create(1115), 20, 12, null); + GameWorld.getPulser().submit(new Pulse(3, player) { + @Override + public boolean pulse() { + AgilityPyramidCourse.addConfig(player, stone, 0, true); + return true; + } + }); + return false; + } + + /** + * Checks if the player is going backwards. + * @param direction the object dir. + * @param dir the player dir. + * @return {@code True} if so. + */ + public boolean isBackwards(Direction direction, Direction dir, int rot) { + switch (direction) { + case NORTH: + break; + case SOUTH: + return rot == 2 & dir == Direction.WEST; + case EAST: + return rot == 1 && dir == Direction.SOUTH; + case WEST: + return rot == 3 && dir == Direction.NORTH; + default: + break; + } + return false; + } + + /** + * A block set. + * @author 'Vexia + */ + public enum BlockSets { + ONE(Location.create(3354, 2841, 0), Location.create(3354, 2842, 1), Location.create(3355, 2842, 1), Location.create(3355, 2841, 1), Location.create(3354, 2841, 1)), TWO(Location.create(3374, 2835, 0), Location.create(3374, 2835, 1), Location.create(3374, 2836, 1), Location.create(3375, 2836, 1), Location.create(3375, 2835, 1)), THREE(Location.create(3368, 2849, 1), Location.create(3368, 2849, 2), Location.create(3369, 2849, 2), Location.create(3369, 2850, 2), Location.create(3368, 2850, 2)), FOUR(Location.create(3048, 4699, 1), Location.create(3048, 4700, 2), Location.create(3049, 4700, 2), Location.create(3049, 4699, 2), Location.create(3048, 4699, 2)), FIVE(Location.create(3044, 4699, 2), Location.create(3044, 4700, 3), Location.create(3045, 4700, 3), Location.create(3045, 4699, 3), Location.create(3044, 4699, 3)); + + /** + * The block location. + */ + private final Location blockLocation; + + /** + * The tile locations. + */ + private final Location[] tiles; + + /** + * Constructs a new {@code BlockSets} {@code Object}. + * @param blockLocation the block location. + * @param tiles the tiles. + */ + private BlockSets(Location blockLocation, Location... tiles) { + this.blockLocation = blockLocation; + this.tiles = tiles; + } + + /** + * Gets the set for the location. + * @param location the location. + * @return the block sets. + */ + public static BlockSets forLocation(Location location) { + for (BlockSets set : values()) { + for (Location loc : set.getTiles()) { + if (loc.equals(location)) { + return set; + } + } + } + return null; + } + + /** + * Gets the blockLocation. + * @return The blockLocation. + */ + public Location getBlockLocation() { + return blockLocation; + } + + /** + * Gets the tiles. + * @return The tiles. + */ + public Location[] getTiles() { + return tiles; + } + + /** + * static-block to load block traps. + */ + static { + final RollingBlock block = new RollingBlock(); + for (BlockSets set : values()) { + for (Location l : set.getTiles()) { + AgilityPyramidZone.LOCATION_TRAPS.put(l, block); + } + } + } + } +} diff --git a/Server/src/main/content/global/skill/agility/shortcuts/AlKharidPitShortcut.java b/Server/src/main/content/global/skill/agility/shortcuts/AlKharidPitShortcut.java new file mode 100644 index 0000000..76ada4b --- /dev/null +++ b/Server/src/main/content/global/skill/agility/shortcuts/AlKharidPitShortcut.java @@ -0,0 +1,57 @@ +package content.global.skill.agility.shortcuts; + +import core.plugin.Initializable; +import content.global.skill.agility.AgilityShortcut; +import core.game.node.Node; +import core.game.node.entity.impl.ForceMovement; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; + +/** + * Handles the al kharid pit shortcut. + * @author adam + */ +@Initializable +public class AlKharidPitShortcut extends AgilityShortcut { + + /** + * Represents the scaling down anmation. + */ + private static final Animation ANIMATION = new Animation(1148); + + /** + * Represents the scaling animation. + */ + private static final Animation SCALE = new Animation(740); + + /** + * Constructs a new {@Code AlKharidPitShortcut} {@Code Object} + */ + public AlKharidPitShortcut() { + super(new int[] { 9331, 9332 }, 38, 0.0, "climb"); + } + + @Override + public void run(Player player, Scenery object, String option, boolean failed) { + switch (object.getId()) { + case 9331: + ForceMovement.run(player, player.getLocation(), Location.create(3303, 3315, 0), ANIMATION, ANIMATION, Direction.EAST, 13).setEndAnimation(Animation.RESET); + break; + case 9332: + ForceMovement.run(player, player.getLocation(), Location.create(3307, 3315, 0), SCALE, SCALE, Direction.EAST, 13).setEndAnimation(Animation.RESET); + break; + } + } + + @Override + public Location getDestination(Node node, Node n) { + final Scenery object = (Scenery) n; + if (object.getId() == 9331) { + return object.getLocation().transform(1, 0, 0); + } + return null; + } +} diff --git a/Server/src/main/content/global/skill/agility/shortcuts/BarSqueezeShortcut.java b/Server/src/main/content/global/skill/agility/shortcuts/BarSqueezeShortcut.java new file mode 100644 index 0000000..efe0f72 --- /dev/null +++ b/Server/src/main/content/global/skill/agility/shortcuts/BarSqueezeShortcut.java @@ -0,0 +1,71 @@ +package content.global.skill.agility.shortcuts; + +import content.global.skill.agility.AgilityShortcut; +import content.global.skill.agility.AgilityHandler; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; +import content.data.Quests; + +/** + * Handles the bar squeezing shortcut. + * @author Vexia + */ +@Initializable +public class BarSqueezeShortcut extends AgilityShortcut { + + /** + * Constructs a new {@Code BarSqueezeShortcut} {@Code Object} + */ + public BarSqueezeShortcut() { + super(new int[] { 9334, 9337 }, 66, 1, "squeeze-through"); + } + + /** + * Constructs a new {@Code BarSqueezeShortcut} {@Code Object} + * @param ids the ids. + * @param level the level. + * @param exp the exp. + * @param option the option. + */ + public BarSqueezeShortcut(int[] ids, int level, double exp, String option) { + super(ids, level, exp, option); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + configure(new BarSqueezeShortcut(new int[] { 2186 }, 1, 0.0, "squeeze-through")); + return super.newInstance(arg); + } + + @Override + public void run(Player player, Scenery object, String option, boolean failed) { + Direction dir = Direction.getLogicalDirection(player.getLocation(), object.getLocation()); + Location start = player.getLocation(); + if (object.getId() == 9334 && dir == Direction.NORTH) { + dir = Direction.WEST; + start = Location.create(3424, 3476, 0); + } else if (object.getId() == 9337 && dir == Direction.NORTH) { + dir = Direction.SOUTH; + if (player.getLocation().getY() < object.getLocation().getY()) { + dir = Direction.NORTH; + } + } else if (object.getId() == 2186 && player.getLocation().getY() >= 3161) { + dir = Direction.SOUTH; + } + AgilityHandler.forceWalk(player, -1, start, player.getLocation().transform(dir, 1), Animation.create(2240), 10, 0.0, null); + } + + @Override + public boolean checkRequirements(Player player) { + if (!player.getQuestRepository().isComplete(Quests.PRIEST_IN_PERIL) && !(player.getLocation().getY() >= 3159 && player.getLocation().getY() <= 3161)) { + player.getDialogueInterpreter().sendDialogue("You need to have completed Priest in Peril in order to do this."); + return false; + } + return super.checkRequirements(player); + } +} diff --git a/Server/src/main/content/global/skill/agility/shortcuts/BasaltRockShortcut.kt b/Server/src/main/content/global/skill/agility/shortcuts/BasaltRockShortcut.kt new file mode 100644 index 0000000..2bc1946 --- /dev/null +++ b/Server/src/main/content/global/skill/agility/shortcuts/BasaltRockShortcut.kt @@ -0,0 +1,201 @@ +package content.global.skill.agility.shortcuts + +import core.game.node.Node +import core.game.node.scenery.Scenery +import core.game.node.entity.player.Player +import content.global.skill.agility.AgilityHandler +import content.global.skill.agility.AgilityShortcut +import core.game.system.task.Pulse +import core.game.world.GameWorld +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.plugin.Initializable +import core.plugin.Plugin + +/** + * Handles the Basalt Rock shortcut. + * @author Woah + */ +@Initializable +class BasaltRockShortcut : AgilityShortcut { + + /** + * Constructs a new {@Code BasaltRockShortcut} {@Code Object} + */ + constructor() : super(intArrayOf(), 0, 0.0, "") + + val noJump = "I can't jump from here." + + /** + * Constructs a new {@Code BasaltRockShortcut} {@Code Object} + * + * @param ids the ids. + * @param level the level. + * @param experience the experience. + * @param options the options. + */ + constructor(ids: IntArray?, level: Int, experience: Double, vararg options: String?) : super(ids, level, experience, *options) + + /** + * Basalt Rock Index : Direction South (Barbarian Outpost) to North (Lighthouse) + * Beach -> Rock 1 -> Rock etc... -> Rocky Shore + * 2522, 3600 R1, 3601, 3602 R2 + */ + override fun newInstance(arg: Any?): Plugin { + configure(BasaltRockShortcut(intArrayOf(4550), 1, 0.0, "jump-to")) //Beach South* + configure(BasaltRockShortcut(intArrayOf(4551), 1, 0.0, "jump-across")) //Beach South Rock 1* + configure(BasaltRockShortcut(intArrayOf(4552), 1, 0.0, "jump-across")) //South Rock 2 + configure(BasaltRockShortcut(intArrayOf(4553), 1, 0.0, "jump-across")) //South Rock 2 (other side) + configure(BasaltRockShortcut(intArrayOf(4554), 1, 0.0, "jump-across")) //Middle Rock 3 + configure(BasaltRockShortcut(intArrayOf(4555), 1, 0.0, "jump-across")) //Middle Rock 3 (other side) + configure(BasaltRockShortcut(intArrayOf(4556), 1, 0.0, "jump-across")) //North Rock 4 + configure(BasaltRockShortcut(intArrayOf(4557), 1, 0.0, "jump-across")) //North Rock 4 (other side) + configure(BasaltRockShortcut(intArrayOf(4558), 1, 0.0, "jump-across")) //Rocky Shore North Rock 5* + configure(BasaltRockShortcut(intArrayOf(4559), 1, 0.0, "jump-to")) //Rocky Shore North* + return this + } + + /** + * This method enables users to jump across rocks by clicking on the one that they want to jump to + * instead of the rock below them + */ + override fun getDestination(n: Node?, node: Node): Location? { + val obj = node as Scenery + if (obj.id == 4550) { + return Location.create(2522, 3597, 0) //Beach South* + } else if (obj.id == 4551) { + return Location.create(2522, 3595, 0) //Beach South Rock 1* + } else if (obj.id == 4552) { + return Location.create(2522, 3602, 0) //South Rock 2 + } else if (obj.id == 4553) { + return Location.create(2522, 3600, 0) //South Rock 2 (other side) + } else if (obj.id == 4554) { + return Location.create(2516, 3611, 0) //Middle Rock 3 + } else if (obj.id == 4555) { + return Location.create(2518, 3611, 0) //Middle Rock 3 (other side) + } else if (obj.id == 4556) { + return Location.create(2514, 3615, 0) //North Rock 4 + } else if (obj.id == 4557) { + return Location.create(2514, 3613, 0) //North Rock 4 (other side) + } else if (obj.id == 4558) { + return Location.create(2514, 3619, 0) //Rocky Shore North Rock 5* + } else if (obj.id == 4559) { + return Location.create(2514, 3617, 0) //Rocky Shore North* + } + return super.getDestination(obj, node) + } + + override fun run(player: Player, obj: Scenery, option: String, failed: Boolean) { + GameWorld.Pulser.submit(object : Pulse(1, player) { + override fun pulse(): Boolean { + when (obj.id) { + + 4550 -> { + if (player.location.y <= 3596) { + player.sendMessage(noJump) + } else { + player.lock(3) + AgilityHandler.forceWalk(player, -1, Location.create(2522, 3597, 0), Location.create(2522, 3595, 0), Animation.create(769), 20, 0.0, null, 1) + } + return true + } + + 4551 -> { + if (player.location == Location.create(2522, 3597, 0)) { + player.sendMessage(noJump) + } else { + player.lock(3) + AgilityHandler.forceWalk(player, -1, Location.create(2522, 3595, 0), Location.create(2522, 3597, 0), Animation.create(769), 20, 0.0, null, 1) + } + return true + } + + 4552 -> { + if (player.location == Location.create(2522, 3600, 0)) { + player.sendMessage(noJump) + } else { + player.lock(3) + AgilityHandler.forceWalk(player, -1, Location.create(2522, 3602, 0), Location.create(2522, 3600, 0), Animation.create(769), 20, 0.0, null) + } + return true + } + + 4553 -> { + if (player.location == Location.create(2522, 3602, 0)) { + player.sendMessage(noJump) + } else { + player.lock(3) + AgilityHandler.forceWalk(player, -1, Location.create(2522, 3600, 0), Location.create(2522, 3602, 0), Animation.create(769), 20, 0.0, null) + } + return true + } + + 4554 -> { + if (player.location == Location.create(2518, 3611, 0)) { + player.sendMessage(noJump) + } else { + player.lock(3) + player.faceLocation(Location.create(2518, 3611, 0)) + AgilityHandler.forceWalk(player, -1, Location.create(2516, 3611, 0), Location.create(2518, 3611, 0), Animation.create(769), 20, 0.0, null, 1) + } + return true + } + + 4555 -> { + if (player.location == Location.create(2516, 3611, 0)) { + player.sendMessage(noJump) + } else { + player.lock(3) + player.faceLocation(Location.create(2516, 3611, 0)) + AgilityHandler.forceWalk(player, -1, Location.create(2518, 3611, 0), Location.create(2516, 3611, 0), Animation.create(769), 20, 0.0, null, 1) + } + return true + } + + 4556 -> { + if (player.location == Location.create(2514, 3613, 0)) { + player.sendMessage(noJump) + } else { + player.lock(3) + AgilityHandler.forceWalk(player, -1, Location.create(2514, 3615, 0), Location.create(2514, 3613, 0), Animation.create(769), 20, 0.0, null) + } + return true + } + + 4557 -> { + if (player.location == Location.create(2514, 3615, 0)) { + player.sendMessage(noJump) + } else { + player.lock(3) + AgilityHandler.forceWalk(player, -1, Location.create(2514, 3613, 0), Location.create(2514, 3615, 0), Animation.create(769), 20, 0.0, null) + } + return true + } + + 4558 -> { + if (player.location == Location.create(2514, 3617, 0)) { + player.sendMessage(noJump) + } else { + player.lock(3) + AgilityHandler.forceWalk(player, -1, Location.create(2514, 3619, 0), Location.create(2514, 3617, 0), Animation.create(769), 20, 0.0, null) + } + return true + } + + 4559 -> { + if (player.location.y >= 3618) { + player.sendMessage(noJump) + } else { + player.lock(3) + AgilityHandler.forceWalk(player, -1, Location.create(2514, 3617, 0), Location.create(2514, 3619, 0), Animation.create(769), 20, 0.0, null, 1) + } + return true + } + + + } + return false + } + }) + } +} diff --git a/Server/src/main/content/global/skill/agility/shortcuts/CrumblingWallShortcut.java b/Server/src/main/content/global/skill/agility/shortcuts/CrumblingWallShortcut.java new file mode 100644 index 0000000..bc730d1 --- /dev/null +++ b/Server/src/main/content/global/skill/agility/shortcuts/CrumblingWallShortcut.java @@ -0,0 +1,36 @@ +package content.global.skill.agility.shortcuts; + +import content.global.skill.agility.AgilityShortcut; +import core.game.node.entity.impl.ForceMovement; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; + +/** + * Handles a crumbling wall. + * @author Vexia + */ +@Initializable +public class CrumblingWallShortcut extends AgilityShortcut { + + /** + * Represents the locations used in this force movement. + */ + private static final Location[] LOCATIONS = new Location[] { new Location(2936, 3355, 0), new Location(2934, 3355, 0) }; + + /** + * Constructs a new {@Code CrumblingWallShortcut} {@Code + * Object} + */ + public CrumblingWallShortcut() { + super(new int[] { 11844 }, 5, 0.0, "climb-over"); + } + + @Override + public void run(Player player, Scenery object, String option, boolean failed) { + ForceMovement.run(player, player.getLocation().getX() >= 2936 ? LOCATIONS[0] : LOCATIONS[1], player.getLocation().getX() >= 2936 ? LOCATIONS[1] : LOCATIONS[0], Animation.create(839), 10); + } + +} diff --git a/Server/src/main/content/global/skill/agility/shortcuts/FenceJumpShortcut.java b/Server/src/main/content/global/skill/agility/shortcuts/FenceJumpShortcut.java new file mode 100644 index 0000000..f57c414 --- /dev/null +++ b/Server/src/main/content/global/skill/agility/shortcuts/FenceJumpShortcut.java @@ -0,0 +1,65 @@ +package content.global.skill.agility.shortcuts; + +import content.global.skill.agility.AgilityShortcut; +import core.game.node.Node; +import core.game.node.entity.impl.ForceMovement; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.scenery.Scenery; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; + +/** + * Handles the fence jump shortcut. + * @author Vexia + */ +@Initializable +public class FenceJumpShortcut extends AgilityShortcut { + + /** + * Represents the running animation. + */ + private static final Animation RUNNING_ANIM = new Animation(1995); + + /** + * Represents the jumping animation. + */ + private static final Animation JUMP_ANIM = new Animation(1603); + + /** + * Represents the related locations used in this shortcut. format: (start, + * start, end, end + */ + private static final Location[] LOCATIONS = new Location[] { new Location(3240, 3331, 0), new Location(3240, 3338, 0), Location.create(3240, 3334, 0), Location.create(3240, 3335, 0) }; + + /** + * Constructs a new {@Code FenceJumpShortcut} {@Code Object} + */ + public FenceJumpShortcut() { + super(new int[] { 9300 }, 13, 0.0, "jump-over"); + } + + @Override + public void run(final Player player, Scenery object, String option, boolean failed) { + player.faceLocation(object.getLocation()); + GameWorld.getPulser().submit(new Pulse(2, player) { + @Override + public boolean pulse() { + player.animate(JUMP_ANIM); + player.getAchievementDiaryManager().finishTask(player, DiaryType.VARROCK, 0, 5); + return true; + } + }); + ForceMovement.run(player, player.getLocation().getY() >= 3335 ? LOCATIONS[1] : LOCATIONS[0], player.getLocation().getY() >= 3335 ? LOCATIONS[2] : LOCATIONS[3], RUNNING_ANIM, 18); + } + + @Override + public Location getDestination(Node node, Node n) { + Player player = node.asPlayer(); + return player.getLocation().getY() >= 3335 ? LOCATIONS[1] : LOCATIONS[0]; + } + +} diff --git a/Server/src/main/content/global/skill/agility/shortcuts/LogBalanceShortcut.java b/Server/src/main/content/global/skill/agility/shortcuts/LogBalanceShortcut.java new file mode 100644 index 0000000..9bb3950 --- /dev/null +++ b/Server/src/main/content/global/skill/agility/shortcuts/LogBalanceShortcut.java @@ -0,0 +1,87 @@ +package content.global.skill.agility.shortcuts; + +import core.game.node.entity.player.link.diary.DiaryType; +import core.plugin.Initializable; +import content.global.skill.agility.AgilityHandler; +import content.global.skill.agility.AgilityShortcut; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; + +/** + * Handles the log balance shortcut. + * @author Vexia + */ +@Initializable +public class LogBalanceShortcut extends AgilityShortcut { + + /** + * The start and ending location. + */ + private Location start; + + /** + * The ending and start location. + */ + private Location end; + + /** + * Constructs a new {@Code LogBalanceShortcut} {@Code Object} + * @param ids the ids. + * @param level the level. + * @param experience the experience. + * @param options the options. + */ + public LogBalanceShortcut(int[] ids, int level, double experience, Location start, Location end, String... options) { + super(ids, level, experience, options); + this.start = start; + this.end = end; + } + + /** + * Constructs a new {@Code LogBalanceShortcut} {@Code Object} + */ + public LogBalanceShortcut() { + super(new int[] {}, 0, 0.0); + } + + @Override + public Plugin newInstance(Object arg) { + configure(new LogBalanceShortcut(new int[] { 2296 }, 20, 5, new Location(2598, 3477, 0), Location.create(2603, 3477, 0), "walk-across")); + // Sinclair mansion to Rellekka. 9324 is on the south side of the stream going north. + configure(new LogBalanceShortcut(new int[] { 9322, 9324 }, 48, 1, Location.create(2722, 3592, 0), Location.create(2722, 3596, 0), "walk-across")); + configure(new LogBalanceShortcut(new int[] { 35997, 35999 }, 33, 1, Location.create(2602, 3336, 0), Location.create(2598, 3336, 0), "walk-across")); + configure(new LogBalanceShortcut(new int[] { 2332 }, 1, 1, Location.create(2910, 3049, 0), Location.create(2906, 3049, 0), "cross")); + configure(new LogBalanceShortcut(new int[] { 3933 }, 45, 1, Location.create(2290, 3232, 0), Location.create(2290, 3239, 0), "cross")); + configure(new LogBalanceShortcut(new int[] { 3932 }, 45, 1, Location.create(2258, 3250, 0), Location.create(2264, 3250, 0), "cross")); + configure(new LogBalanceShortcut(new int[] { 3931 }, 45, 1, Location.create(2202, 3237, 0), Location.create(2196, 3237, 0), "cross")); + return this; + } + + @Override + public void run(Player player, Scenery object, String option, boolean failed) { + Location destination = start; + if (player.getLocation().getDistance(start) < player.getLocation().getDistance(end)) { + destination = end; + } + AgilityHandler.walk(player, -1, player.getLocation(), destination, Animation.create(155), getExperience(), null); + + // Seers Achievement Diary + if (destination.equals(new Location(2722,3596,0)) + && !player.getAchievementDiaryManager().getDiary(DiaryType.SEERS_VILLAGE).isComplete(1,0)) { + player.getAchievementDiaryManager().getDiary(DiaryType.SEERS_VILLAGE).updateTask(player,1,0,true); + } + } + + @Override + public Location getDestination(Node node, Node n) { + if (node.getLocation().getDistance(start) < node.getLocation().getDistance(end)) { + return start; + } + return end; + } + +} diff --git a/Server/src/main/content/global/skill/agility/shortcuts/MonkeyBarShortcut.java b/Server/src/main/content/global/skill/agility/shortcuts/MonkeyBarShortcut.java new file mode 100644 index 0000000..673d277 --- /dev/null +++ b/Server/src/main/content/global/skill/agility/shortcuts/MonkeyBarShortcut.java @@ -0,0 +1,130 @@ +package content.global.skill.agility.shortcuts; + +import core.plugin.Initializable; +import content.global.skill.agility.AgilityHandler; +import content.global.skill.agility.AgilityShortcut; +import core.game.node.Node; +import core.game.node.entity.impl.ForceMovement; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.system.task.Pulse; +import kotlin.Unit; +import core.game.world.GameWorld; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; +import core.tools.RandomFunction; + +/** + * Handles the monkey bar shortcut. + * @author Vexia + */ +@Initializable +public class MonkeyBarShortcut extends AgilityShortcut { + + /** + * Represents the location cache data for the monkey bars. + */ + private static final Location[][] MBAR_LOCATIONS = new Location[][] { { new Location(3120, 9969, 0), Location.create(3121, 9969, 0) }, { new Location(3119, 9969, 0), Location.create(3120, 9969, 0) }, { new Location(3120, 9964, 0), Location.create(3121, 9964, 0) }, { Location.create(3120, 9963, 0), Location.create(3120, 9964, 0) }, { new Location(2598, 9489, 0), new Location(2597, 9488, 0) }, { new Location(2598, 9489, 0), new Location(2600, 9488, 0) }, { new Location(2598, 9494, 0), new Location(2597, 9495, 0) }, { new Location(2599, 9494, 0), new Location(2600, 9495, 0) } }; + + /** + * Constructs a new {@Code MonkeyBarShortcut} {@Code Object} + */ + public MonkeyBarShortcut() { + super(new int[] { 29375 }, 1, 14.0, "swing across"); + } + + /** + * Constructs a new {@Code MonkeyBarShortcut} {@Code Object} + * @param ids the ids. + * @param level the level. + * @param experience the exp. + * @param option the option. + */ + public MonkeyBarShortcut(int[] ids, int level, double experience, String option) { + super(ids, level, experience, option); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + configure(new MonkeyBarShortcut(new int[] { 2321 }, 57, 20, "swing across")); + return super.newInstance(arg); + } + + @Override + public void run(final Player player, final Scenery object, String option, boolean failed) { + player.lock(5); + Direction direct = Direction.get((object.getDirection().toInteger() + 2) % 4); + if (object.getId() == 29375) { + if (direct == Direction.SOUTH && player.getLocation().getY() < 9969) { + direct = Direction.NORTH; + } else if (direct == Direction.NORTH && player.getLocation().getY() >= 9969) { + direct = Direction.SOUTH; + } + } else if (object.getId() == 2321) { + if (player.getLocation().getY() >= 9494) { + direct = Direction.SOUTH; + } else { + direct = Direction.NORTH; + } + } + player.getAppearance().setAnimations(Animation.create(745)); + final Location start = player.getLocation(); + final Direction dir = direct; + ForceMovement.run(player, start.transform(dir), start.transform(dir.getStepX() << 1, dir.getStepY() << 1, 0), Animation.create(742), Animation.create(744)); + player.logoutListeners.put("monkey-bar", p -> { + p.setLocation(start); + return Unit.INSTANCE; + }); + GameWorld.getPulser().submit(new Pulse(2, player) { + int count; + boolean failed; + + @Override + public boolean pulse() { + if (++count == 1) { + if (object.getId() == 2321 && (failed = AgilityHandler.hasFailed(player, 57, 0.01))) { + setDelay(1); + player.animate(Animation.create(743)); + return false; + } + setDelay(4); + AgilityHandler.walk(player, -1, player.getLocation().transform(dir), player.getLocation().transform(dir.getStepX() * 4, dir.getStepY() * 4, 0), Animation.create(662), 0.0, null); + } else if (count == 2) { + if (failed) { + player.getAppearance().setAnimations(); + player.getAppearance().sync(); + AgilityHandler.fail(player, 2, new Location(2599, 9564, 0), Animation.create(768), RandomFunction.random(1, 3), null); + player.logoutListeners.remove("monkey-bar"); + return true; + } + AgilityHandler.forceWalk(player, -1, player.getLocation(), player.getLocation().transform(dir), Animation.create(743), 10, getExperience(), null); + player.logoutListeners.remove("monkey-bar"); + return true; + } + return false; + } + }); + } + + @Override + public Location getDestination(Node n, Node node) { + if (node.getLocation().equals(new Location(2598, 9489, 0))) { + return new Location(2597, 9488, 0); + } else if (node.getLocation().equals(new Location(2598, 9494, 0))) { + return new Location(2597, 9495, 0); + } else if (node.getLocation().equals(new Location(2599, 9489, 0))) { + return new Location(2600, 9488, 0); + } + for (Location[] locations : MBAR_LOCATIONS) { + if (n.getLocation().equals(locations[0])) { + return locations[1]; + } + } + if (node.getLocation().equals(new Location(2598, 9489, 0)) || node.getLocation().equals(new Location(2599, 9489, 0))) { + return new Location(2600, 9495, 0); + } + return null; + } +} diff --git a/Server/src/main/content/global/skill/agility/shortcuts/PipeShortcut.kt b/Server/src/main/content/global/skill/agility/shortcuts/PipeShortcut.kt new file mode 100644 index 0000000..f120546 --- /dev/null +++ b/Server/src/main/content/global/skill/agility/shortcuts/PipeShortcut.kt @@ -0,0 +1,158 @@ +package content.global.skill.agility.shortcuts + +import core.game.node.scenery.Scenery +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.diary.DiaryType +import content.global.skill.agility.AgilityHandler +import content.global.skill.agility.AgilityShortcut +import core.game.system.task.Pulse +import core.game.world.GameWorld +import core.game.world.update.flag.context.Animation +import core.plugin.Initializable +import core.plugin.Plugin + +/** + * Handles a pipe shortcut. + * Quick overview of what's included: + * Pipe interactions, locations, animations + * Quick OBJ lookup for pipe shortcut (ps): + * ps2290, ps5099, ps5100, ps9293, ps20210, ps29370 + * Animations used: + * 10578: pipe enter(Due to tweening this one may cause issues, player standing up/it showing through the pipe, use 10580 instead) + * 10579: pipe exit, 10580: pipe enter + exit + * @author Woah + */ +@Initializable +class PipeShortcut : AgilityShortcut { + + /** + * Constructs a new {@Code PipeShortcut} {@Code Object} + */ + constructor() : super(intArrayOf(), 0, 0.0, "") + + /** + * Constructs a new {@Code PipeShortcut} {@Code Object} + * + * @param ids the ids. + * @param level the level. + * @param experience the experience. + * @param options the options. + */ + constructor(ids: IntArray?, level: Int, experience: Double, vararg options: String?) : super(ids, level, experience, *options) + + /** + * These are all the pipes that are deemed "Shortcuts" + * Note: Barbarian Outpost is included in this list because it is not apart of the + * Barbarian Outpost Agility Course. + */ + override fun newInstance(arg: Any?): Plugin { + configure(PipeShortcut(intArrayOf(2290), 49, 0.0, "squeeze-through")) //Yanille Dungeon + configure(PipeShortcut(intArrayOf(5099), 22, 8.5, "squeeze-through")) //Brimhaven Dungeon Pipe Red Dragons -> Black Demons + configure(PipeShortcut(intArrayOf(5100), 34, 10.0, "squeeze-through")) //Brimhaven Dungeon Pipe Moss Giants -> Moss Giants + configure(PipeShortcut(intArrayOf(9293), 70, 10.0, "squeeze-through")) //Taverley Dungeon + configure(PipeShortcut(intArrayOf(20210), 35, 10.0, "squeeze-through")) //Barbarian Outpost + configure(PipeShortcut(intArrayOf(29370), 51, 10.0, "squeeze-through")) //Edgeville Dungeon + return this + } + + /** + * Run for the main fire event + */ + override fun run(player: Player, obj: Scenery, option: String, failed: Boolean) { + + /** + * Pulse that starts the object interaction when clicked on one of these shortcuts + */ + GameWorld.Pulser.submit(object : Pulse(1, player) { + override fun pulse(): Boolean { + when (obj.id) { + + /** + * Quick breakdown of how Agility.forcewalk is used for pipe shortcuts: + * AgilityHandler.forceWalk(player, -1, player.location, pipeDestination(player, obj, 6), Animation.create(10580), 10, 0.0, null) + * + * player = player, the player that is being force-walked + * -1 = course index, should this be counted as an agility course +1? + * player.location, gets the player location (start of pipe) + * pipeDestination(player, obj, 6) = custom made for pipes, player = player, obj is getting the scenery location, 6 is the amount to move forward. || More info found in AgilityShortcut.java + * Animation.create(10580) = what animation we should play when the user is interacting with that object + * 10 = speed at which the player moves through the object + * 0.0 = experience that we should award the player on successful completion* SET EXPERIENCE IN METHOD newInstance + * null = message that should be displayed when entering the object + */ + + /** + * Yanille Dungeon pipe (Obj id: 2290) LOC: (2577, 9506, 0) + * Taverley Dungeon pipe (Obj id: 9293) LOC: (2887, 9799, 0) + * Diagram: + * This one is pretty standard, does not to have X/Y checks because the pipe is built into the wall + * Player lock (standard 5 ticks for a 7 long pipe) + * Plays the get into + crawl + jump out of pipe animation + */ + 2290, 9293 -> { + player.lock(7) + AgilityHandler.forceWalk(player, -1, player.location, pipeDestination(player, obj, 6), Animation.create(10580), 10, 0.0, null) + player.animate(Animation(844), 4) + player.animate(Animation(10579), 5) + return true + } + + /** + * //Brimhaven Dungeon Pipe Red Dragons -> Black Demons (Obj id: 5099) LOC: (2698, 9498, 0) + * //Brimhaven Dungeon Pipe Moss Giants -> Moss Giants (Obj id: 5100) LOC: (2655, 9567, 0) + * Diagram: + * This one is pretty standard, does not to have X/Y checks because the pipe is built into the wall + * Player lock (standard 5 ticks for a 7 long pipe) + * Plays the get into + crawl + jump out of pipe animation + */ + 5099, 5100 -> { + player.lock(5) + AgilityHandler.forceWalk(player, -1, player.location, pipeDestination(player, obj, 7), Animation.create(10580), 10, 0.0, null) + player.animate(Animation(844), 5) + player.animate(Animation(10579), 6) + return true + } + + /** + * Barbarian Outpost Pipe (Obj id: 20210) LOC: (2552, 3560, 0) + * Diagram: + * If statement checks to see if the player is on the same X Axis as the pipe, by not having this here a player could enter + * the pipe at an angle and would be shot through the walls (kinda funny to watch) + * Player lock (standard 3 ticks for a 3 long pipe) + * plays the all-in-one animation for getting into + out of pipe + */ + 20210 -> { + if (player.location.x != 2552) { + player.packetDispatch.sendMessage("I can't get into this pipe at that angle.") + return true + } + player.lock(3) + AgilityHandler.forceWalk(player, -1, player.location, pipeDestination(player, obj, 3), Animation.create(10580), 15, 0.0, null) + return true + } + + /** + * Edgeville Dungeon Pipe (Obj id: 29370) LOC: (3150, 9906, 0) + * Diagram: + * If statement checks to see if the player is on the same Y Axis as the pipe, by not having this here a player could enter + * the pipe at an angle and would be shot through the walls + * Player lock (standard 7 ticks for a 6 long pipe) + * Plays the get into + crawl + jump out of pipe animation + */ + 29370 -> { + if (player.location.y != 9906) { + player.packetDispatch.sendMessage("I can't get into this pipe at that angle.") + return true + } + player.lock(7) + AgilityHandler.forceWalk(player, -1, player.location, pipeDestination(player, obj, 6), Animation.create(10580), 10, 0.0, null) + player.animate(Animation(844), 4) + player.animate(Animation(10579), 5) + return true + } + } + return false + } + }) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/agility/shortcuts/RockClimbShortcut.kt b/Server/src/main/content/global/skill/agility/shortcuts/RockClimbShortcut.kt new file mode 100644 index 0000000..509023e --- /dev/null +++ b/Server/src/main/content/global/skill/agility/shortcuts/RockClimbShortcut.kt @@ -0,0 +1,126 @@ +package content.global.skill.agility.shortcuts + +import core.game.node.scenery.Scenery +import core.game.node.entity.impl.ForceMovement +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import content.global.skill.agility.AgilityShortcut +import core.game.world.map.Direction +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.plugin.Initializable + +/** + * Handles the rock climbing shortcut. + * @author Sir Kermit + */ +@Initializable +class RockClimbShortcut +/** + * Constructs a new {@Code RockClimbShortcut} {@Code Object} + */ + : AgilityShortcut(intArrayOf( + 9335, + 9336, + 2231, + 26327, + 26328, + 26324, + 26323, + 19849, + 9296, + 9297 + ), 1, 0.0, "climb") + +{ + override fun run(player: Player, `object`: Scenery, option: String, failed: Boolean) { + //Scaling down + val ANIMATION = Animation(1148) + //Scaling Up + val SCALE = Animation(740) + //Gets level for Arandar climbs + val req = if (player.location.equals(2346, 3300, 0) || player.location.equals(2344, 3294, 0)){ + 59 + }else if (player.location.equals(2338, 3281, 0) || player.location.equals(2338, 3286, 0)){ + 85 + }else if (player.location.equals(2332, 3252, 0) || player.location.equals(2338, 3253, 0)){ + 68 + }else{0} + + when (`object`.id) { + 2231 -> if (player.location.x <= 2791) { + ForceMovement.run(player, `object`.location, `object`.location.transform(3, 0, 0), SCALE, SCALE, Direction.WEST, 13).endAnimation = Animation.RESET + } else { + ForceMovement.run(player, `object`.location, `object`.location.transform(-3, 0, 0), ANIMATION, ANIMATION, Direction.WEST, 13).endAnimation = Animation.RESET + } + + //Eagles Peak + 19849 -> if (player.location.x <= 2322) { + if (player.skills.hasLevel(Skills.AGILITY, 25)) { + ForceMovement.run(player, player.location, Location.create(2324, 3497, 0), SCALE, SCALE, Direction.SOUTH, 13).endAnimation = Animation.RESET + } else { + player.dialogueInterpreter.sendDialogue("You need an Agility level of at least 25 to do this.") + } + } else { + if (player.skills.hasLevel(Skills.AGILITY, 25)) { + ForceMovement.run(player, player.location, Location.create(2322, 3502, 0), ANIMATION, ANIMATION, Direction.SOUTH, 13).endAnimation = Animation.RESET + } else { + player.dialogueInterpreter.sendDialogue("You need an Agility level of at least 25 to do this.") + } + } + + 9335 -> ForceMovement.run(player, player.location, Location.create(3427, 3478, 0), SCALE, SCALE, Direction.WEST, 13).endAnimation = Animation.RESET + + 9336 -> ForceMovement.run(player, player.location, Location.create(3424, 3476, 0), ANIMATION, ANIMATION, Direction.WEST, 13).endAnimation = Animation.RESET + + //GodWars Shortcut + 26327 -> if (player.skills.hasLevel(Skills.AGILITY, 60)) { + ForceMovement.run(player, player.location, Location.create(2942, 3768, 0), SCALE, SCALE, Direction.WEST, 13).endAnimation = Animation.RESET + } else { + player.dialogueInterpreter.sendDialogue("You need an Agility level of at least 60 to do this.") + } + + //GodWars Shortcut + 26328 -> if (player.skills.hasLevel(Skills.AGILITY, 60)) { + ForceMovement.run(player, player.location, Location.create(2950, 3767, 0), ANIMATION, ANIMATION, Direction.WEST, 13).endAnimation = Animation.RESET + } else { + player.dialogueInterpreter.sendDialogue("You need an Agility level of at least 60 to do this.") + } + + //GodWars Shortcut + 26324 -> if (player.skills.hasLevel(Skills.AGILITY, 60)) { + ForceMovement.run(player, player.location, Location.create(2928, 3757, 0), SCALE, SCALE, Direction.NORTH, 13).endAnimation = Animation.RESET + } else { + player.dialogueInterpreter.sendDialogue("You need an Agility level of at least 60 to do this.") + } + + //GodWars Shortcut + 26323 -> if (player.skills.hasLevel(Skills.AGILITY, 60)) { + ForceMovement.run(player, player.location, Location.create(2927, 3761, 0), ANIMATION, ANIMATION, Direction.NORTH, 13).endAnimation = Animation.RESET + } else { + player.dialogueInterpreter.sendDialogue("You need an Agility level of at least 60 to do this.") + } + + //Arandar + 9297 -> if (player.skills.hasLevel(Skills.AGILITY, 59) && req == 59) { + ForceMovement.run(player, player.location, Location.create(2346, 3300, 0), SCALE, SCALE, Direction.NORTH, 13).endAnimation = Animation.RESET + } else if (player.skills.hasLevel(Skills.AGILITY, 85) && req == 85) { + ForceMovement.run(player, player.location, Location.create(2338, 3281, 0), SCALE, SCALE, Direction.SOUTH, 13).endAnimation = Animation.RESET + } else if (player.skills.hasLevel(Skills.AGILITY, 68) && req == 68) { + ForceMovement.run(player, player.location, Location.create(2332, 3252, 0), SCALE, SCALE, Direction.WEST, 13).endAnimation = Animation.RESET + } else { + player.dialogueInterpreter.sendDialogue("You need an Agility level of at least $req to do this.") + } + //Arandar + 9296 -> if (player.skills.hasLevel(Skills.AGILITY, 59) && req == 59) { + ForceMovement.run(player, player.location, Location.create(2344, 3294, 0), ANIMATION, ANIMATION, Direction.NORTH, 13).endAnimation = Animation.RESET + } else if (player.skills.hasLevel(Skills.AGILITY, 85) && req == 85) { + ForceMovement.run(player, player.location, Location.create(2338, 3286, 0), ANIMATION, ANIMATION, Direction.SOUTH, 13).endAnimation = Animation.RESET + } else if (player.skills.hasLevel(Skills.AGILITY, 68) && req == 68) { + ForceMovement.run(player, player.location, Location.create(2338, 3253, 0), ANIMATION, ANIMATION, Direction.WEST, 13).endAnimation = Animation.RESET + } else { + player.dialogueInterpreter.sendDialogue("You need an Agility level of at least $req to do this.") + } + } + } + } \ No newline at end of file diff --git a/Server/src/main/content/global/skill/agility/shortcuts/RopeSwing.java b/Server/src/main/content/global/skill/agility/shortcuts/RopeSwing.java new file mode 100644 index 0000000..e6853fe --- /dev/null +++ b/Server/src/main/content/global/skill/agility/shortcuts/RopeSwing.java @@ -0,0 +1,45 @@ +package content.global.skill.agility.shortcuts; + +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; +import content.global.skill.agility.AgilityHandler; + +@Initializable +public class RopeSwing extends UseWithHandler { + @Override + public boolean handle(NodeUsageEvent event) { + + if(event.getUsedWith() instanceof Scenery){ + Scenery object = event.getUsedWith().asScenery(); + int objId = object.getId(); + + assert event.getUsedItem() != null; + int usedId = event.getUsedItem().getId(); + + Player player = event.getPlayer(); + + if(objId == 2327 && usedId == 954){ + if (!player.getLocation().withinDistance(object.getLocation(), 2)) { + player.sendMessage("I can't reach that."); + return true; + } + player.getPacketDispatch().sendSceneryAnimation(object, Animation.create(497), true); + AgilityHandler.forceWalk(player, 0, player.getLocation(), Location.create(2505, 3087, 0), Animation.create(751), 50, 22, "You skillfully swing across.", 1); + return true; + } + } + return false; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(2327,OBJECT_TYPE,this); + return this; + } +} diff --git a/Server/src/main/content/global/skill/agility/shortcuts/SteppingStoneShortcut.kt b/Server/src/main/content/global/skill/agility/shortcuts/SteppingStoneShortcut.kt new file mode 100644 index 0000000..035ed53 --- /dev/null +++ b/Server/src/main/content/global/skill/agility/shortcuts/SteppingStoneShortcut.kt @@ -0,0 +1,91 @@ +package content.global.skill.agility.shortcuts + +import core.api.* +import core.cache.def.impl.SceneryDefinition +import core.game.interaction.OptionHandler +import core.game.interaction.QueueStrength +import core.game.node.Node +import core.game.node.entity.impl.ForceMovement +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.plugin.Initializable +import core.plugin.Plugin + +/** + * Handles the stepping stone shortcut. + * @author Ceikry + */ +@Initializable +class SteppingStoneShortcut : OptionHandler() { + private val stones = HashMap() + internal class SteppingStoneInstance(val pointA: Location, val pointB: Location, val option: String, val levelReq: Int) + + override fun handle(player: Player?, node: Node?, option: String?): Boolean { + player ?: return false + val stone = stones[player.location] + stone ?: return false + + if(player.skills.getLevel(Skills.AGILITY) < stone.levelReq){ + player.sendMessage("You need an agility level of ${stone.levelReq} for this shortcut.") + return true + } + + val finalDest = when(player.location){ + stone.pointA -> stone.pointB + stone.pointB -> stone.pointA + else -> player.location + } + val offset = getOffset(player,finalDest) + player.debug("Offset: ${offset.first},${offset.second}") + closeAllInterfaces(player) + lock(player, 3) + player.locks.lockTeleport(3) + queueScript(player, 2, QueueStrength.SOFT) { + val there = player.location == finalDest + if (!there) { + lock(player, 3) + player.locks.lockTeleport(3) + ForceMovement.run(player,player.location,player.location.transform(offset.first,offset.second,0), ANIMATION,10) + return@queueScript delayScript(player, 2) + } + return@queueScript stopExecuting(player) + } + return true + } + + fun getOffset(player: Player, location: Location): Pair{ + var diffX = location.x - player.location.x + var diffY = location.y - player.location.y + if(diffX > 1) diffX = 1 + if(diffX < -1) diffX = -1 + if(diffY > 1) diffY = 1 + if(diffY < -1) diffY = -1 + return Pair(diffX,diffY) + } + + fun configure(objects: IntArray, pointA: Location, pointB: Location, option: String, levelReq: Int){ + val instance = SteppingStoneInstance(pointA,pointB, option, levelReq) + objects.forEach { + SceneryDefinition.forId(it).handlers["option:$option"] = this + } + stones.put(pointA,instance) + stones.put(pointB, instance) + } + + override fun newInstance(arg: Any?): Plugin { + configure(intArrayOf(2335,2333),Location.create(2925,2947,0),Location.create(2925,2951,0),"cross",30) + configure(intArrayOf(9315),Location.create(3149, 3363, 0),Location.create(3154, 3363, 0),"jump-onto",31) + + return this + } + + companion object { + /** + * Represents the animation to use. + */ + private val ANIMATION = Animation(741) + } +} diff --git a/Server/src/main/content/global/skill/agility/shortcuts/StileShortcut.kt b/Server/src/main/content/global/skill/agility/shortcuts/StileShortcut.kt new file mode 100644 index 0000000..e492b6b --- /dev/null +++ b/Server/src/main/content/global/skill/agility/shortcuts/StileShortcut.kt @@ -0,0 +1,79 @@ +package content.global.skill.agility.shortcuts + +import core.api.* +import core.api.utils.Vector +import core.game.activity.ActivityManager +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength +import core.game.node.entity.player.Player +import core.game.world.map.Direction +import core.game.world.map.Location + +class StileShortcut : InteractionListener { + val ids = intArrayOf(993, 3730, 7527, 12982, 19222, 22302, 29460, 33842, 34776, 39508, 39509, 39510) + val FALCONRY_STILE = 19222 + override fun defineListeners() { + on (ids, IntType.SCENERY, "climb-over") {p, n -> + val direction = Vector.betweenLocs(p.location, n.location).toDirection() + val startLoc = p.location.transform(direction, 1) + val endLoc = p.location.transform(direction, 2) + + closeAllInterfaces(p) + p.walkingQueue.reset() + p.walkingQueue.addPath(startLoc.x, startLoc.y) + forceMove(p, startLoc, endLoc, 0, animationCycles(839), direction, 839) + + queueScript(p, 5, QueueStrength.SOFT) {_ -> + val end = endLoc.transform(direction, 1) + p.walkingQueue.reset() + p.walkingQueue.addPath(end.x, end.y) + + if (n.id == FALCONRY_STILE) + handleFalconry(p, endLoc) + return@queueScript stopExecuting(p) + } + return@on true + } + + setDest(IntType.SCENERY, ids, "climb-over") {e, n -> + return@setDest getInteractLocation(e.location, n.location, getOrientation(n.direction)) + } + } + + + + companion object { + fun getInteractLocation (pLoc: Location, sLoc: Location, orientation: Orientation) : Location { + when (orientation) { + Orientation.Horizontal -> { + if (pLoc.x <= sLoc.x) return sLoc.transform(-1, 0, 0) + else return sLoc.transform(2, 0, 0) + } + Orientation.Vertical -> { + if (pLoc.y <= sLoc.y) return sLoc.transform(0, -1, 0) + else return sLoc.transform(0, 2, 0) + } + } + } + + fun getOrientation (rotation: Direction) : Orientation { + when (rotation) { + Direction.EAST, Direction.WEST -> return Orientation.Horizontal + else -> return Orientation.Vertical + } + } + + fun handleFalconry (p: Player, endLoc: Location) { + if (endLoc.y == 3619) + ActivityManager.start(p, "falconry", false) + else + ActivityManager.getActivity("falconry").leave(p, false) + } + } + + enum class Orientation { + Horizontal, + Vertical + } +} diff --git a/Server/src/main/content/global/skill/agility/shortcuts/StrangeFloorShortcut.java b/Server/src/main/content/global/skill/agility/shortcuts/StrangeFloorShortcut.java new file mode 100644 index 0000000..cf0d784 --- /dev/null +++ b/Server/src/main/content/global/skill/agility/shortcuts/StrangeFloorShortcut.java @@ -0,0 +1,78 @@ +package content.global.skill.agility.shortcuts; + +import core.cache.def.impl.SceneryDefinition; +import core.plugin.Initializable; +import core.plugin.Plugin; +import content.global.skill.agility.AgilityShortcut; +import core.game.node.Node; +import core.game.node.entity.impl.ForceMovement; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; + +/** + * Handles the strange floor shortcut. + * @author Vexia + */ +@Initializable +public class StrangeFloorShortcut extends AgilityShortcut { + + /** + * Represents the running animation. + */ + private static final Animation RUNNING_ANIM = new Animation(1995); + + /** + * Represents the jumping animation. + */ + private static final Animation JUMP_ANIM = new Animation(1603); + + /** + * Constructs a new {@Code StrangeFloorShortcut} {@Code + * Object} + */ + public StrangeFloorShortcut() { + super(new int[] { 9294 }, 80, 0.0, "jump-over"); + } + + @Override + public void run(final Player player, Scenery object, String option, boolean failed) { + GameWorld.getPulser().submit(new Pulse(1, player) { + @Override + public boolean pulse() { + player.getAnimator().forceAnimation(JUMP_ANIM); + return true; + } + }); + GameWorld.getPulser().submit(new Pulse(2, player) { + + @Override + public boolean pulse() { + player.getAnimator().forceAnimation(RUNNING_ANIM); + return true; + } + + }); + ForceMovement.run(player, player.getLocation().getX() >= 2880 ? Location.create(2881, 9813, 0) : Location.create(2877, 9813, 0), player.getLocation().getX() >= 2880 ? Location.create(2877, 9813, 0) : Location.create(2881, 9813, 0), RUNNING_ANIM, 13); + + } + + @Override + public Location getDestination(Node node, Node n) { + return node.getLocation().getX() >= 2880 ? Location.create(2881, 9813, 0) : Location.create(2877, 9813, 0); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + configure(this); + return this; + } + + @Override + public void configure(AgilityShortcut shortcut) { + SceneryDefinition.forId(getIds()[0]).getHandlers().put("option:jump-over",this); + } +} diff --git a/Server/src/main/content/global/skill/agility/shortcuts/TunnelShortcut.java b/Server/src/main/content/global/skill/agility/shortcuts/TunnelShortcut.java new file mode 100644 index 0000000..42cf77e --- /dev/null +++ b/Server/src/main/content/global/skill/agility/shortcuts/TunnelShortcut.java @@ -0,0 +1,142 @@ +package content.global.skill.agility.shortcuts; + +import core.game.node.entity.player.link.diary.DiaryType; +import content.global.skill.agility.AgilityShortcut; +import core.game.node.Node; +import core.game.node.entity.impl.ForceMovement; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; + +import static core.api.ContentAPIKt.hasRequirement; +import content.data.Quests; + +/** + * Handles a tunnel shortcut. + * @author Vexia + */ +@Initializable +public class TunnelShortcut extends AgilityShortcut { + + /** + * The climbing down animation. + */ + private static final Animation CLIMB_DOWN = Animation.create(2589); + + /** + * The crawling through animation. + */ + private static final Animation CRAWL_THROUGH = Animation.create(2590); + + /** + * The climbing up animation. + */ + private static final Animation CLIMB_UP = Animation.create(2591); + + /** + * The increment offset. + */ + private int offset; + + /** + * Constructs a new {@Code TunnelShortcut} {@Code Object} + */ + public TunnelShortcut() { + super(new int[] {}, 0, 0.0); + } + + /** + * Constructs a new {@Code TunnelShortcut} {@Code Object} + * @param ids the ids. + * @param level the level. + * @param experience the experience. + * @param options the options. + */ + public TunnelShortcut(int[] ids, int level, double experience, int offset, String... options) { + super(ids, level, experience, options); + this.offset = offset; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + configure(new TunnelShortcut(new int[] { 9309, 9310 }, 26, 0.0, 0, "climb-into")); + configure(new TunnelShortcut(new int[] { 9302, 9301 }, 16, 0.0, 1, "climb-into", "climb-under")); + configure(new TunnelShortcut(new int[] { 14922 }, 1, 0.0, 1, "enter")); + return this; + } + + @Override + public void run(final Player player, Scenery object, String option, boolean failed) { + if (object.getId() == 14922) { + if (!hasRequirement(player, Quests.SWAN_SONG)) + return; + } + player.lock(6); + final Scenery o = object; + final Location start = player.getLocation(); + final Direction dir = Direction.getDirection(start, o.getLocation()); + if (object.getLocation().getX() == 2575) { + offset = 1; + } + ForceMovement.run(player, start, o.getLocation(), CLIMB_DOWN, 8); + GameWorld.getPulser().submit(new Pulse(1, player) { + int count; + + @Override + public boolean pulse() { + switch (++count) { + case 2: + player.animate(CRAWL_THROUGH); + player.getProperties().setTeleportLocation(start.transform(dir, 2 + offset)); + break; + case 5: + ForceMovement.run(player, player.getLocation(), start.transform(dir, 4 + offset), CLIMB_UP, 19); + break; + case 6: + player.animate(ForceMovement.WALK_ANIMATION); + if ((object.getId() == 9309 || object.getId() == 9310) && !player.getAchievementDiaryManager().getDiary(DiaryType.FALADOR).isComplete(1,1)) { + player.getAchievementDiaryManager().getDiary(DiaryType.FALADOR).updateTask(player, 1, 1, true); + } + return true; + } + return false; + } + }); + } + + @Override + public Location getDestination(Node node, Node n) { + if (n.getId() == 14922) { + return n.getLocation().transform(getObjectDirection(n.asScenery().getDirection()), 1); + } + return getStart(n.getLocation(), n.getDirection()); + } + + /** + * Gets the start location. + * @param location the location. + * @param dir the dir. + * @return the location. + */ + public Location getStart(Location location, Direction dir) { + switch (dir) { + case NORTH: + break; + case SOUTH: + break; + case EAST: + return location.transform(0, location.getY() == 3111 ? 1 : -1, 0); + case WEST: + return location.transform(0, 1, 0); + default: + return location; + } + return location; + } +} diff --git a/Server/src/main/content/global/skill/agility/shortcuts/ZanarisSqueezeShortcut.java b/Server/src/main/content/global/skill/agility/shortcuts/ZanarisSqueezeShortcut.java new file mode 100644 index 0000000..b5a37c5 --- /dev/null +++ b/Server/src/main/content/global/skill/agility/shortcuts/ZanarisSqueezeShortcut.java @@ -0,0 +1,42 @@ +package content.global.skill.agility.shortcuts; + +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import content.global.skill.agility.AgilityShortcut; +import core.game.node.entity.impl.ForceMovement; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; + +/** + * Handles the zanaris cosmic altar shortcuts for runecrafters. + * @author Splinter + */ +@Initializable +public class ZanarisSqueezeShortcut extends AgilityShortcut { + + /** + * Represents the squeeze animation. + */ + private static final Animation ANIMATION = new Animation(2240); + + /** + * Constructs a new {@Code ZanarisSqueezeShortcut} {@Code Object} + */ + public ZanarisSqueezeShortcut() { + super(new int[] { 12127 }, 46, 0.0, "squeeze-past"); + } + + @Override + public void run(Player player, Scenery object, String option, boolean failed) { + if (player.getSkills().getLevel(Skills.AGILITY) < 66 && (object.getLocation().equals(new Location(2408, 4395)) || object.getLocation().equals(new Location(2415, 4402)))) { + player.getDialogueInterpreter().sendDialogue("You need an Agility level of at least 66 to negotiate this obstacle."); + return; + } + Location to = player.getLocation().getY() < object.getLocation().getY() ? object.getLocation().transform(0, 1, 0) : object.getLocation().transform(0, -1, 0); + Direction dir = player.getLocation().getY() < object.getLocation().getY() ? Direction.NORTH : Direction.SOUTH; + ForceMovement.run(player, player.getLocation(), to, ANIMATION, ANIMATION, dir, 13).setEndAnimation(Animation.RESET); + } +} diff --git a/Server/src/main/content/global/skill/agility/shortcuts/grapple/AbstractGrappleShortcut.kt b/Server/src/main/content/global/skill/agility/shortcuts/grapple/AbstractGrappleShortcut.kt new file mode 100644 index 0000000..d6672ef --- /dev/null +++ b/Server/src/main/content/global/skill/agility/shortcuts/grapple/AbstractGrappleShortcut.kt @@ -0,0 +1,136 @@ +package content.global.skill.agility.shortcuts.grapple + +import core.api.* +import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.scenery.Scenery +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items + +abstract class AbstractGrappleShortcut : InteractionListener { + /** + * Make sure that you have flagInstant in your listeners. + * If you do not the player will run and try to touch the grapple point + */ + private val VALID_CROSSBOWS = intArrayOf( + Items.MITH_CROSSBOW_9181, + Items.ADAMANT_CROSSBOW_9183, + Items.RUNE_CROSSBOW_9185, + Items.DORGESHUUN_CBOW_8880 + ) + + protected abstract val REQUIREMENTS: HashMap + + protected abstract val grappleStartLocation: Location + protected abstract val grappleEndLocation: Location + + // use lazy so that the skill requirements can be populated after the child builds them + private val requirementString1: String by lazy { + "You need at least " + + REQUIREMENTS[Skills.AGILITY] + " " + Skills.SKILL_NAME[Skills.AGILITY] + ", " + + REQUIREMENTS[Skills.RANGE] + " " + Skills.SKILL_NAME[Skills.RANGE] + "," + } + private val requirementString2: String by lazy { + "and " + + REQUIREMENTS[Skills.STRENGTH] + " " + Skills.SKILL_NAME[Skills.STRENGTH] + " to use this shortcut." + } + + + // What needs to have its model changed during a grapple + protected abstract val grappleScenery: List + + // What animation to use when getting the player across + protected abstract val animation: Animation + // How long should the animation last (in ticks) + protected abstract val animationDuration: Int + + protected abstract fun animation(animationStage: Int, player: Player): Boolean + + + // The message that can appear if there should be one after grappling + protected val message: String? = null + + private fun getRequirementString(): Array { + val requirementString = arrayOf(requirementString1, requirementString2) + return requirementString + } + + private fun doesPlayerHaveRequiredItemsEquipped(player: Player): Boolean { + return inEquipment(player, Items.MITH_GRAPPLE_9419) && anyInEquipment(player, *VALID_CROSSBOWS) + } + + private fun doesPlayerHaveRequiredLevels(player: Player): Boolean { + for ((skill, requiredLevel) in REQUIREMENTS) { + if (!hasLevelDyn(player, skill, requiredLevel)) { + return false + } + } + return true + } + + protected open fun isPlayerInRangeToGrapple(player: Player, startLoc: Location, range: Int): Boolean { + return inBorders(player, startLoc.x - range, startLoc.y - range, + startLoc.x + range, startLoc.y + range) + } + + /** + * See if the [player] is close enough to the [startLoc] (based on [range] to + * try and grapple. This will return false if the [player] is too far away, + * if the player does not have the right levels or if the player does not have + * the correct gear equipped. + */ + protected fun canGrapple(player: Player, startLoc: Location, range: Int): Boolean { + if (isPlayerInRangeToGrapple(player, startLoc, range)) { + forceWalk(player, startLoc, "smart") + } else { + // todo should this be "you are too far away" or something like that? + sendMessage(player, "Nothing interesting happens.") + return false + } + + if (!doesPlayerHaveRequiredItemsEquipped(player)) { + sendDialogue(player, "You need a Mithril crossbow and a Mithril grapple in order to do this.") + return false + } + + if (!doesPlayerHaveRequiredLevels(player)) { + sendDialogueLines(player, + *getRequirementString() + ) + return false + } + return true + } + + protected fun grapple(player: Player, message: String?): Boolean { + closeAllInterfaces(player) + lock(player, animationDuration) + // TODO is this right? should we force the player to cross? + queueScript(player, strength = QueueStrength.SOFT) { stage: Int -> + if (animation(stage, player)){ + // We're done with the animation + return@queueScript stopExecuting(player) + } + else{ + return@queueScript delayScript(player, 1) + } + } + + message?.let{ + player.sendMessage(message) + } + return true + } + + + /** + * If an achievement diary can be updated it should be done here + */ + protected open fun updateDiary(player: Player): Boolean{ + return false + } + +} diff --git a/Server/src/main/content/global/skill/agility/shortcuts/grapple/AbstractOneWayGrapple.kt b/Server/src/main/content/global/skill/agility/shortcuts/grapple/AbstractOneWayGrapple.kt new file mode 100644 index 0000000..7645b03 --- /dev/null +++ b/Server/src/main/content/global/skill/agility/shortcuts/grapple/AbstractOneWayGrapple.kt @@ -0,0 +1,39 @@ +package content.global.skill.agility.shortcuts.grapple + +import core.api.* +import core.game.node.entity.player.Player + +abstract class AbstractOneWayGrapple : AbstractGrappleShortcut() { + + + override fun animation(animationStage: Int, player: Player): Boolean { + when (animationStage) { + 1 -> { + // Point towards the grapple landing zone + face(player, grappleEndLocation) + // Start the grapple animation + animate(player, animation) + } + + 5 -> { + for (tgt in grappleScenery) { + // Add grapple effects to all scenery (for 10 ticks) + replaceScenery(tgt!!, tgt.id + 1, 10) + } + } + + 5 + animationDuration -> { + // After the animation is done teleport to the landing zone + teleport(player, grappleEndLocation) + } + + 5 + animationDuration + 1 -> { + // free the player + unlock(player) + updateDiary(player) + return true + } + } + return false + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/agility/shortcuts/grapple/AbstractTwoWayGrapple.kt b/Server/src/main/content/global/skill/agility/shortcuts/grapple/AbstractTwoWayGrapple.kt new file mode 100644 index 0000000..4cbb3aa --- /dev/null +++ b/Server/src/main/content/global/skill/agility/shortcuts/grapple/AbstractTwoWayGrapple.kt @@ -0,0 +1,16 @@ +package content.global.skill.agility.shortcuts.grapple + +import core.game.node.entity.player.Player +import core.game.world.map.Direction +import core.game.world.map.Location + +abstract class AbstractTwoWayGrapple : AbstractGrappleShortcut(){ + + abstract var direction: Direction? + + abstract var startLoc: Location? + abstract var endLoc: Location? + + protected abstract fun setStartEndSide(player: Player, margin: Int = 5) + protected abstract fun getGrappleScenery(direction: Direction): List +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/agility/shortcuts/grapple/AlKharidGrapple.kt b/Server/src/main/content/global/skill/agility/shortcuts/grapple/AlKharidGrapple.kt new file mode 100644 index 0000000..5f98b03 --- /dev/null +++ b/Server/src/main/content/global/skill/agility/shortcuts/grapple/AlKharidGrapple.kt @@ -0,0 +1,108 @@ +package content.global.skill.agility.shortcuts.grapple + +import core.api.* +import core.game.interaction.IntType +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.world.map.Direction +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Scenery + +class AlKharidGrapple : AbstractTwoWayGrapple(){ + + override val REQUIREMENTS: HashMap = hashMapOf(Skills.AGILITY to 8, Skills.RANGE to 37, Skills.STRENGTH to 19) + + // Lumbridge + override val grappleStartLocation: Location = Location(3246, 3179, 0) + + // Al Kharid + override val grappleEndLocation: Location = Location(3259, 3179, 0) + + override var direction: Direction? = null + override var startLoc: Location? = null + override var endLoc: Location? = null + + override var grappleScenery: List = listOf() + + override val animation: Animation = Animation(4230) + override val animationDuration: Int = 9 + override fun animation(animationStage: Int, player: Player): Boolean { + when (animationStage) { + 1 -> { + face(player, endLoc!!) + animate(player, animation) + } + + 5 -> { + for (tgt in grappleScenery) { + if ((tgt!!.id == 17068)) { + // This is the raft + continue + } + replaceScenery(tgt, tgt.id + 1, 10) + } + } + + 5 + animationDuration -> { + teleport(player, endLoc!!) + } + 5 + animationDuration + 1 -> { + unlock(player) + updateDiary(player) + return true + } + } + return false + } + + override fun defineListeners() { + flagInstant() // execute listeners instantly without determining path + + on(Scenery.BROKEN_RAFT_17068, IntType.SCENERY, "grapple") { player, target -> + // Check if we are on the east or the west of the broken raft + // East = Lum + setStartEndSide(player) + if (!canGrapple(player, startLoc!!, 2)){ + return@on true + } + grapple(player,message) + return@on true + } + } + + + override fun setStartEndSide(player: Player, margin: Int) { + if (player.location.x < grappleStartLocation.x + margin){ + // We're on the west side + direction = Direction.EAST // got to jump east + startLoc = grappleStartLocation + endLoc = grappleEndLocation + } + else { + // we're on the east side + direction = Direction.WEST // got to jump west + startLoc = grappleEndLocation + endLoc = grappleStartLocation + } + + grappleScenery = getGrappleScenery(direction!!) + } + + override fun getGrappleScenery(direction: Direction): List { + val lumbridgeTree = getScenery(Location(3244, 3179, 0)) + val alKharidTree = getScenery(Location(3260, 3178, 0)) + val startTree : core.game.node.scenery.Scenery? + val endTree : core.game.node.scenery.Scenery? + val raft = getScenery(Location(3252, 3179, 0)) + if (direction == Direction.EAST){ + startTree = lumbridgeTree + endTree = alKharidTree + } + else{ + startTree = alKharidTree + endTree = lumbridgeTree + } + return listOf(startTree,endTree, raft) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/agility/shortcuts/grapple/CatherbyGrappleShortcut.kt b/Server/src/main/content/global/skill/agility/shortcuts/grapple/CatherbyGrappleShortcut.kt new file mode 100644 index 0000000..e5bcd2a --- /dev/null +++ b/Server/src/main/content/global/skill/agility/shortcuts/grapple/CatherbyGrappleShortcut.kt @@ -0,0 +1,43 @@ +package content.global.skill.agility.shortcuts.grapple + +import core.api.* +import core.game.node.entity.skill.Skills +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Scenery +import core.game.interaction.IntType +import core.plugin.Initializable +import kotlin.collections.HashMap + + +@Initializable +class CatherbyGrappleShortcut : AbstractOneWayGrapple(){ + + override val REQUIREMENTS: HashMap = hashMapOf(Skills.AGILITY to 32, Skills.RANGE to 35, Skills.STRENGTH to 35) + + override val grappleStartLocation: Location = Location.create(2866, 3429, 0) + + override val grappleEndLocation: Location = Location.create(2869,3430,0) + + // todo this is the wrong animation + override val animation: Animation = Animation(4455) + + override val animationDuration: Int = 9 + + override val grappleScenery: List = listOf( + getScenery(Location.create(2869,3429, 0)) // rocks + ) + + override fun defineListeners() { + flagInstant() + + on(Scenery.ROCKS_17042, IntType.SCENERY, "grapple"){ player, _ -> + if (!canGrapple(player, grappleStartLocation, 1)) { + return@on true + } + grapple(player, message) + return@on true + } + } + +} diff --git a/Server/src/main/content/global/skill/agility/shortcuts/grapple/FaladorGrapple.kt b/Server/src/main/content/global/skill/agility/shortcuts/grapple/FaladorGrapple.kt new file mode 100644 index 0000000..58e8e2f --- /dev/null +++ b/Server/src/main/content/global/skill/agility/shortcuts/grapple/FaladorGrapple.kt @@ -0,0 +1,123 @@ +package content.global.skill.agility.shortcuts.grapple + +import core.api.* +import core.game.interaction.IntType +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.diary.DiaryType +import core.game.node.entity.skill.Skills +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import core.plugin.Initializable +import org.rs09.consts.Scenery + +abstract class AbstractFaladorGrapple(private var wallGrappleInterface: WallGrappleInterface = WallGrappleInterfaceImpl()): AbstractOneWayGrapple() { + + override val animation: Animation = Animation(4455) + + override val animationDuration: Int = 14 + + // There are no scenery items to hook so don't let children override this + final override val grappleScenery: List = listOf() + + protected fun jump(player: Player, destination: Location): Boolean { + return wallGrappleInterface.jump(player, destination) + } + + override fun animation(animationStage: Int, player: Player): Boolean { + when (animationStage) { + 1 -> { + player.faceLocation(grappleEndLocation) + visualize(player, animation, Graphics(760, 100)) + } + + 8 -> { + wallGrappleInterface.fadeToBlack(player) + } + + 13 -> teleport(player, grappleEndLocation) + 14 -> { + wallGrappleInterface.showGame(player) + unlock(player) + updateDiary(player) + return true + } + } + return false + } + +} +@Initializable +class FaladorGrappleNorth : AbstractFaladorGrapple() { + + override val REQUIREMENTS: HashMap = hashMapOf(Skills.AGILITY to 11, Skills.RANGE to 19, Skills.STRENGTH to 37) + + override val grappleStartLocation: Location = Location.create(3033, 3390, 0) + + + override val grappleEndLocation: Location = Location.create(3033, 3389, 1) + + override fun defineListeners() { + flagInstant() + on(Scenery.WALL_17049, IntType.SCENERY, "grapple") { player, _ -> + if(!canGrapple(player, grappleStartLocation, 4)) { + return@on true + } + grapple(player, message) + return@on true + } + + on(Scenery.WALL_17051, IntType.SCENERY, "jump"){ player, _ -> + jump(player, grappleStartLocation) + return@on true + } + } + + override fun isPlayerInRangeToGrapple(player: Player, startLoc: Location, range: Int): Boolean { + // Do not let the player grapple from the other side of the wall + return inBorders(player, startLoc.x - range, startLoc.y, + startLoc.x + range, startLoc.y + 2) + } + + override fun updateDiary(player: Player): Boolean { + player.achievementDiaryManager.finishTask(player, DiaryType.FALADOR, 1, 2) + return true + } +} + +@Initializable +class FaladorGrappleSouth : AbstractFaladorGrapple() { + + override val REQUIREMENTS: HashMap = hashMapOf(Skills.AGILITY to 11, Skills.RANGE to 19, Skills.STRENGTH to 37) + + override val grappleStartLocation: Location = Location.create(3032, 3388, 0) + + override val grappleEndLocation: Location = Location.create(3032, 3389, 1) + + override fun defineListeners() { + flagInstant() + on(Scenery.WALL_17050, IntType.SCENERY, "grapple") { player, _ -> + if(!canGrapple(player, grappleStartLocation, 4)) { + return@on true + } + grapple(player, message) + return@on true + } + + on(Scenery.WALL_17052, IntType.SCENERY, "jump"){ player, _ -> + jump(player, grappleStartLocation) + return@on true + } + } + + override fun isPlayerInRangeToGrapple(player: Player, startLoc: Location, range: Int): Boolean { + // Do not let the player grapple from the other side of the wall + return inBorders(player, startLoc.x - range, startLoc.y, + startLoc.x + range, startLoc.y - 2) + } + + override fun updateDiary(player: Player): Boolean { + player.achievementDiaryManager.finishTask(player, DiaryType.FALADOR, 1, 2) + return true + } +} diff --git a/Server/src/main/content/global/skill/agility/shortcuts/grapple/KaramjaGrapple.kt b/Server/src/main/content/global/skill/agility/shortcuts/grapple/KaramjaGrapple.kt new file mode 100644 index 0000000..96337db --- /dev/null +++ b/Server/src/main/content/global/skill/agility/shortcuts/grapple/KaramjaGrapple.kt @@ -0,0 +1,108 @@ +package content.global.skill.agility.shortcuts.grapple + +import core.api.* +import core.game.interaction.IntType +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.diary.DiaryType +import core.game.node.entity.skill.Skills +import core.game.world.map.Direction +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.plugin.Initializable +import org.rs09.consts.Scenery + +@Initializable +class KaramjaGrapple : AbstractTwoWayGrapple(){ + + override val REQUIREMENTS: HashMap = hashMapOf(Skills.AGILITY to 53, Skills.RANGE to 42, Skills.STRENGTH to 21) + + // South + override val grappleStartLocation: Location = Location.create(2874, 3127, 0) + + + // North + override val grappleEndLocation: Location = Location.create(2874,3142,0) + + override var direction: Direction? = null + override var startLoc: Location? = null + override var endLoc: Location? = null + + override var grappleScenery: List = listOf() + + override val animation: Animation = Animation(4230) + override val animationDuration: Int = 9 + + override fun animation(animationStage: Int, player: Player): Boolean { + when (animationStage) { + 1 -> { + face(player, endLoc!!) + animate(player, animation) + } + + 5 -> { + for (tgt in grappleScenery) { + replaceScenery(tgt!!, tgt.id + 1, 10) + } + } + + 5 + animationDuration -> { + teleport(player, endLoc!!) + } + 5 + animationDuration + 1 -> { + unlock(player) + updateDiary(player) + return true + } + } + return false + } + + override fun defineListeners() { + flagInstant() + + on(Scenery.STRONG_TREE_17074, IntType.SCENERY, "grapple"){ player, _ -> + setStartEndSide(player) + if(!canGrapple(player, startLoc!!, 1)){ + return@on true + } + grapple(player, message) + return@on true + } + + } + + override fun setStartEndSide(player: Player, margin: Int) { + if (player.location.y > grappleEndLocation.y - margin){ // we're on the north side + direction = Direction.SOUTH // got to jump south + startLoc = grappleEndLocation + endLoc = grappleStartLocation + } + else { + direction = Direction.NORTH // got to jump north + startLoc = grappleStartLocation + endLoc = grappleEndLocation + } + + grappleScenery = getGrappleScenery(direction!!) + } + + override fun getGrappleScenery(direction: Direction): List { + val startTree : core.game.node.scenery.Scenery? + val endTree : core.game.node.scenery.Scenery? + val islandTree = getScenery(Location(2873, 3134, 0)) + if (direction == Direction.NORTH){ + startTree = getScenery(Location(2874, 3144, 0)) + endTree = getScenery(Location(2873, 3125, 0)) + } + else{ + startTree = getScenery(Location(2874, 3144, 0)) + endTree = getScenery(Location(2873, 3125, 0)) + } + return listOf(startTree,endTree, islandTree) + } + + override fun updateDiary(player: Player): Boolean { + player.achievementDiaryManager.finishTask(player, DiaryType.KARAMJA, 2, 6) + return true + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/agility/shortcuts/grapple/WallGrappleInterface.kt b/Server/src/main/content/global/skill/agility/shortcuts/grapple/WallGrappleInterface.kt new file mode 100644 index 0000000..8eeadcf --- /dev/null +++ b/Server/src/main/content/global/skill/agility/shortcuts/grapple/WallGrappleInterface.kt @@ -0,0 +1,69 @@ +package content.global.skill.agility.shortcuts.grapple + +import core.api.* +import core.game.component.Component +import core.game.interaction.QueueStrength +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.net.packet.PacketRepository +import core.net.packet.context.MinimapStateContext +import core.net.packet.out.MinimapState + +interface WallGrappleInterface { + var tab: Component? + fun jump(player: Player, destination: Location): Boolean + fun fadeToBlack(player: Player): Component + fun showGame(player: Player): Boolean +} + + +class WallGrappleInterfaceImpl: WallGrappleInterface{ + override var tab: Component? = null + + override fun jump(player: Player, destination: Location): Boolean { + // todo this doesn't look great compared to what it used to look like + closeAllInterfaces(player) + forceWalk(player, destination,"smart" ) + face(player, destination) + // We're teleporting if we are animating so make the strength SOFT + queueScript(player, strength = QueueStrength.SOFT){ stage: Int -> + when (stage){ + 1 -> animate(player, Animation(7268)) + 2 ->{ + teleport(player, destination) + return@queueScript stopExecuting(player) + } + } + return@queueScript delayScript(player, 1) + + } + return true + } + + + override fun fadeToBlack(player: Player): Component { + // todo make this work. Right now the tab is always null + tab = player.interfaceManager.singleTab + player.interfaceManager.openOverlay(Component(115)) + PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 2)) + player.interfaceManager.removeTabs(0, 1, 2, 3, 4, 5, 6, 11, 12) + if (tab == null){ + println("Panic") + return Component(1) + } + return tab!! + } + + override fun showGame(player: Player): Boolean { + player.interfaceManager.restoreTabs() + if (tab != null) { + player.interfaceManager.openTab(tab) + } + PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 0)) + closeOverlay(player) + closeInterface(player) + return true + } + +} diff --git a/Server/src/main/content/global/skill/agility/shortcuts/grapple/WaterOrbGrapple.kt b/Server/src/main/content/global/skill/agility/shortcuts/grapple/WaterOrbGrapple.kt new file mode 100644 index 0000000..8fc2a21 --- /dev/null +++ b/Server/src/main/content/global/skill/agility/shortcuts/grapple/WaterOrbGrapple.kt @@ -0,0 +1,48 @@ +package content.global.skill.agility.shortcuts.grapple + +import core.api.getScenery +import core.game.interaction.IntType +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.diary.DiaryType +import core.game.node.entity.skill.Skills +import org.rs09.consts.Scenery +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.plugin.Initializable + +@Initializable +class WaterOrbGrapple : AbstractOneWayGrapple(){ + + override val REQUIREMENTS: HashMap = hashMapOf(Skills.AGILITY to 36, Skills.RANGE to 39, Skills.STRENGTH to 22) + + override val grappleStartLocation: Location = Location.create(2841, 3427, 0) + + override val grappleEndLocation: Location = Location.create(2841, 3433, 0) + + override val animation: Animation = Animation(4230) + + override val animationDuration: Int = 9 + + override val grappleScenery: List = listOf( + getScenery(Location.create(2841, 3426, 0)), // rock + getScenery(Location.create(2841, 3434, 0)) // tree + ) + + override fun defineListeners() { + flagInstant() + + on(Scenery.CROSSBOW_TREE_17062, IntType.SCENERY, "grapple"){ player, _ -> + if (!canGrapple(player, grappleStartLocation, 1)) { + return@on true + } + grapple(player, message) + return@on true + } + } + + override fun updateDiary(player: Player): Boolean { + player.achievementDiaryManager.finishTask(player, DiaryType.SEERS_VILLAGE, 2, 10) + return true + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/agility/shortcuts/grapple/YanilleGrapple.kt b/Server/src/main/content/global/skill/agility/shortcuts/grapple/YanilleGrapple.kt new file mode 100644 index 0000000..dc53512 --- /dev/null +++ b/Server/src/main/content/global/skill/agility/shortcuts/grapple/YanilleGrapple.kt @@ -0,0 +1,99 @@ +package content.global.skill.agility.shortcuts.grapple + +import core.api.inBorders +import core.api.teleport +import core.api.unlock +import core.api.visualize +import core.game.interaction.IntType +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.world.map.Direction +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import core.plugin.Initializable +import org.rs09.consts.Scenery + +@Initializable +class YanilleGrapple(private var wallGrappleInterface: WallGrappleInterface = WallGrappleInterfaceImpl()): AbstractTwoWayGrapple() { + + override val REQUIREMENTS: HashMap = hashMapOf(Skills.AGILITY to 11, Skills.RANGE to 19, Skills.STRENGTH to 37) + + override val grappleStartLocation: Location = Location.create(2556, 3072, 0) + + override val grappleEndLocation: Location = Location.create(2556, 3073, 1) + + override var direction: Direction? = null + override var startLoc: Location? = null + override var endLoc: Location? = null + override fun setStartEndSide(player: Player, margin: Int) { + // Start location is where you end after jumping in the opposite way + if (player.location.y > 3073 ){ + // We are north of the middle of the wall + startLoc = Location.create(2556, 3075, 0) // This is where you grapple from/land after jumping + endLoc = Location.create(2556, 3074, 1) // + } + else { + // We are south of the middle of the wall + startLoc = Location.create(2556, 3072, 0) + endLoc = Location.create(2556, 3073, 1) + } + } + + override fun getGrappleScenery(direction: Direction): List { + return emptyList() + } + + override var grappleScenery: List = listOf() + + override val animation: Animation = Animation(4455) + override val animationDuration: Int = 9 + override fun animation(animationStage: Int, player: Player): Boolean { + when (animationStage) { + 1 -> { + player.faceLocation(endLoc) + visualize(player, animation, Graphics(760, 100)) + } + + 8 -> { + wallGrappleInterface.fadeToBlack(player) + } + + 13 -> teleport(player, endLoc!!) + 14 -> { + wallGrappleInterface.showGame(player) + unlock(player) + updateDiary(player) + return true + } + } + return false + } + + + override fun defineListeners() { + // Do not use flagListeners here + // The player needs to be able to touch the target + on(Scenery.WALL_17047, IntType.SCENERY, "grapple") { player, _ -> + setStartEndSide(player, 0) + if(!canGrapple(player, startLoc!!, 4)){ + return@on true + } + grapple(player, message) + return@on true + } + + on(Scenery.WALL_17048, IntType.SCENERY, "jump") { player, _ -> + setStartEndSide(player, 0) + wallGrappleInterface.jump(player, startLoc!!) + return@on true + } + } + + override fun isPlayerInRangeToGrapple(player: Player, startLoc: Location, range: Int): Boolean { + // Do not let the player grapple from the other side of the wall + return inBorders( + player, startLoc.x - range, startLoc.y, + startLoc.x + range, startLoc.y - 2) + } +} diff --git a/Server/src/main/content/global/skill/construction/BuildHotspot.java b/Server/src/main/content/global/skill/construction/BuildHotspot.java new file mode 100644 index 0000000..c5ca6c8 --- /dev/null +++ b/Server/src/main/content/global/skill/construction/BuildHotspot.java @@ -0,0 +1,516 @@ +package content.global.skill.construction; + +import core.game.world.update.flag.context.Animation; + +import java.util.ArrayList; +import java.util.List; + + +/** + * Represents a building hotspot. + * @author Emperor + * + */ +public enum BuildHotspot { + + /** + * Low level garden hotspots. + */ + CENTREPIECE_1(15361, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.PORTAL, Decoration.ROCK, Decoration.POND, Decoration.IMP_STATUE, Decoration.SMALL_OBELISK, Decoration.DUNGEON_ENTRANCE), + BIG_TREE_1(15362, BuildHotspotType.INDIVIDUAL, BuildingUtils.PLANT_ANIM, Decoration.BIG_DEAD_TREE, Decoration.BIG_TREE, Decoration.BIG_OAK_TREE, Decoration.BIG_WILLOW_TREE, Decoration.BIG_MAPLE_TREE, Decoration.BIG_YEW_TREE, Decoration.BIG_MAGIC_TREE), + TREE_1(15363, BuildHotspotType.INDIVIDUAL, BuildingUtils.PLANT_ANIM, Decoration.DEAD_TREE, Decoration.TREE, Decoration.OAK_TREE, Decoration.WILLOW_TREE, Decoration.MAPLE_TREE, Decoration.YEW_TREE, Decoration.MAGIC_TREE), + BIG_PLANT_1(15364, BuildHotspotType.INDIVIDUAL, BuildingUtils.PLANT_ANIM, Decoration.FERN, Decoration.BUSH, Decoration.TALL_PLANT), + BIG_PLANT_2(15365, BuildHotspotType.INDIVIDUAL, BuildingUtils.PLANT_ANIM, Decoration.SHORT_PLANT, Decoration.LARGE_LEAF_PLANT, Decoration.HUGE_PLANT), + SMALL_PLANT_1(15366, BuildHotspotType.INDIVIDUAL, BuildingUtils.PLANT_ANIM, Decoration.PLANT, Decoration.SMALL_FERN, Decoration.FERN_SP), + SMALL_PLANT_2(15367, BuildHotspotType.INDIVIDUAL, BuildingUtils.PLANT_ANIM, Decoration.DOCK_LEAF, Decoration.THISTLE, Decoration.REEDS), + + /** + * Low level Parlor hotspots. + */ + CHAIRS_1(15410, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.CRUDE_CHAIR,Decoration.WOODEN_CHAIR, Decoration.ROCKING_CHAIR, Decoration.OAK_CHAIR, Decoration.OAK_ARMCHAIR, Decoration.TEAK_ARMCHAIR, Decoration.MAHOGANY_ARMCHAIR), + CHAIRS_2(15411, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.CRUDE_CHAIR, Decoration.WOODEN_CHAIR,Decoration.ROCKING_CHAIR, Decoration.OAK_CHAIR, Decoration.OAK_ARMCHAIR, Decoration.TEAK_ARMCHAIR, Decoration.MAHOGANY_ARMCHAIR), + CHAIRS_3(15412, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.CRUDE_CHAIR, Decoration.WOODEN_CHAIR,Decoration.ROCKING_CHAIR, Decoration.OAK_CHAIR, Decoration.OAK_ARMCHAIR, Decoration.TEAK_ARMCHAIR, Decoration.MAHOGANY_ARMCHAIR), + FIREPLACE(15418, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.CLAY_FIREPLACE, Decoration.STONE_FIREPLACE,Decoration.MARBLE_FIREPLACE), + FIREPLACE2(15267, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.CLAY_FIREPLACE, Decoration.STONE_FIREPLACE,Decoration.MARBLE_FIREPLACE), + CURTAINS(15419, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_MID_ANIM, Decoration.TORN_CURTAINS, Decoration.CURTAINS, Decoration.OPULENT_CURTAINS), + BOOKCASE(15416, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.WOODEN_BOOKCASE, Decoration.OAK_BOOKCASE, Decoration.MAHOGANY_BOOKCASE), + RUG(15415, BuildHotspotType.LINKED, BuildingUtils.BUILD_LOW_ANIM, Decoration.BROWN_RUG_CORNER, Decoration.RED_RUG_CORNER, Decoration.OPULENT_RUG_CORNER), + RUG2(15414, BuildHotspotType.LINKED, BuildingUtils.BUILD_LOW_ANIM, Decoration.BROWN_RUG_END, Decoration.RED_RUG_END, Decoration.OPULENT_RUG_END), + RUG3(15413, BuildHotspotType.LINKED, BuildingUtils.BUILD_LOW_ANIM, Decoration.BROWN_RUG_CENTER, Decoration.RED_RUG_CENTER, Decoration.OPULENT_RUG_CENTER), + + /** + * Low level Kitchen hotspots. + */ + LARDER(15403, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.WOODEN_LARDER, Decoration.OAK_LARDER,Decoration.TEAK_LARDER), + SINK(15404, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.PUMP_AND_DRAIN, Decoration.PUMP_AND_TUB, Decoration.SINK), + KITCHEN_TABLE(15405, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.KITCHEN_WOODEN_TABLE,Decoration.KITCHEN_OAK_TABLE, Decoration.KITCHEN_TEAK_TABLE), + CAT_BLANKET(15402, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.CAT_BLANKET, Decoration.CAT_BASKET,Decoration.CAST_BASKET_CUSHIONED), + STOVE(15398, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.BASIC_FIREPIT, Decoration.FIREPIT_WITH_HOOK, Decoration.FIREPIT_WITH_POT, Decoration.SMALL_OVEN, Decoration.LARGE_OVEN, Decoration.BASIC_RANGE, Decoration.FANCY_RANGE), + SHELVES(15400, BuildHotspotType.LINKED, BuildingUtils.BUILD_HIGH_ANIM, Decoration.WOODEN_SHELVES_1,Decoration.WOODEN_SHELVES_2, Decoration.WOODEN_SHELVES_3,Decoration.OAK_SHELVES_1, Decoration.OAK_SHELVES_2, Decoration.TEAK_SHELVES_1, Decoration.TEAK_SHELVES_2), + SHELVES_2(15399, BuildHotspotType.LINKED, BuildingUtils.BUILD_HIGH_ANIM, Decoration.WOODEN_SHELVES_1,Decoration.WOODEN_SHELVES_2, Decoration.WOODEN_SHELVES_3,Decoration.OAK_SHELVES_1, Decoration.OAK_SHELVES_2,Decoration.TEAK_SHELVES_1, Decoration.TEAK_SHELVES_2), + BARRELS(15401, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.BASIC_BEER_BARREL, Decoration.CIDER_BARREL,Decoration.ASGARNIAN_ALE_BARREL, Decoration.GREENMANS_ALE_BARREL,Decoration.DRAGON_BITTER_BARREL, Decoration.CHEFS_DELIGHT_BARREL), + + /** + * Low-level Dining hotspots. + */ + FIREPLACE_DINING(15301, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.CLAY_FIREPLACE, Decoration.STONE_FIREPLACE, Decoration.MARBLE_FIREPLACE), + DINING_TABLE(15298, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.DINING_TABLE_WOOD, Decoration.DINING_TABLE_OAK, Decoration.DINING_TABLE_CARVED_OAK, Decoration.DINING_TABLE_TEAK,Decoration.DINING_TABLE_CARVED_TEAK, Decoration.DINING_TABLE_MAHOGANY,Decoration.DINING_TABLE_OPULENT), + DINING_CURTAINS(15302, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_MID_ANIM, Decoration.TORN_CURTAINS, Decoration.CURTAINS, Decoration.OPULENT_CURTAINS), + DINING_BENCH_1(15300, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_MID_ANIM, Decoration.BENCH_WOODEN, Decoration.BENCH_OAK, Decoration.BENCH_CARVED_OAK, Decoration.BENCH_TEAK, Decoration.BENCH_CARVED_TEAK, Decoration.BENCH_MAHOGANY, Decoration.BENCH_GILDED), + DINING_BENCH_2(15299, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_MID_ANIM, Decoration.BENCH_WOODEN, Decoration.BENCH_OAK, Decoration.BENCH_CARVED_OAK, Decoration.BENCH_TEAK, Decoration.BENCH_CARVED_TEAK, Decoration.BENCH_MAHOGANY,Decoration.BENCH_GILDED), + ROPE_BELL_PULL(15304, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.ROPE_PULL, Decoration.BELL_PULL, Decoration.FANCY_BELL_PULL), + WALL_DECORATION(15303, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.OAK_DECORATION, Decoration.TEAK_DECORATION, Decoration.GILDED_DECORATION), + + /** + * Low-level Work shop hotspots. + */ + REPAIR(15448, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.REPAIR_BENCH, Decoration.WHETSTONE, Decoration.ARMOUR_STAND), + WORKBENCH(15439, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.WORKBENCH_WOODEN, Decoration.WORKBENCH_OAK,Decoration.WORKBENCH_STEEL_FRAME, Decoration.WORKBENCH_WITH_VICE,Decoration.WORKBENCH_WITH_LATHE), + CRAFTING(15441, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.CRAFTING_TABLE_1, Decoration.CRAFTING_TABLE_2,Decoration.CRAFTING_TABLE_3, Decoration.CRAFTING_TABLE_4), + TOOL1(15443, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.TOOL_STORE_1, Decoration.TOOL_STORE_2, Decoration.TOOL_STORE_3, Decoration.TOOL_STORE_4, Decoration.TOOL_STORE_5), + TOOL2(15444, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.TOOL_STORE_1, Decoration.TOOL_STORE_2,Decoration.TOOL_STORE_3, Decoration.TOOL_STORE_4,Decoration.TOOL_STORE_5), + TOOL3(15445, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.TOOL_STORE_1, Decoration.TOOL_STORE_2,Decoration.TOOL_STORE_3, Decoration.TOOL_STORE_4,Decoration.TOOL_STORE_5), + TOOL4(15446, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.TOOL_STORE_1, Decoration.TOOL_STORE_2,Decoration.TOOL_STORE_3, Decoration.TOOL_STORE_4,Decoration.TOOL_STORE_5), + TOOL5(15447, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.TOOL_STORE_1, Decoration.TOOL_STORE_2,Decoration.TOOL_STORE_3, Decoration.TOOL_STORE_4,Decoration.TOOL_STORE_5), + HERALDRY(15450, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.PLUMING_STAND, Decoration.SHIELD_EASEL,Decoration.BANNER_EASEL), + + /** + * Bedroom hotspots. + */ + BED(15260, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.WOODEN_BED, Decoration.OAK_BED, Decoration.LARGE_OAK_BED, Decoration.TEAK_BED, Decoration.LARGE_TEAK_BED, Decoration.FOUR_POSTER, Decoration.GILDED_FOUR_POSTER), + CLOCK(15268, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.OAK_CLOCK, Decoration.TEAK_CLOCK, Decoration.GILDED_CLOCK), + DRESSER(15262, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.SHAVING_STAND, Decoration.OAK_SHAVING_STAND, Decoration.OAK_DRESSER, Decoration.TEAK_DRESSER, Decoration.FANCY_TEAK_DRESSER, Decoration.MAHOGANY_DRESSER, Decoration.GILDED_DRESSER), + DRAWERS(15261, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.SHOE_BOX, Decoration.OAK_DRAWERS, Decoration.OAK_WARDROBE, Decoration.TEAK_DRAWERS, Decoration.TEAK_WARDROBE, Decoration.MAHOGANY_WARDROBE, Decoration.GILDED_WARDROBE), + BEDROOM_CURTAINS(15263, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_MID_ANIM, Decoration.TORN_CURTAINS, Decoration.CURTAINS, Decoration.OPULENT_CURTAINS), + BEDROOM_RUG(15264, BuildHotspotType.LINKED, BuildingUtils.BUILD_LOW_ANIM, Decoration.BROWN_RUG_CENTER, Decoration.RED_RUG_CENTER, Decoration.OPULENT_RUG_CENTER), + BEDROOM_RUG2(15265, BuildHotspotType.LINKED, BuildingUtils.BUILD_LOW_ANIM, Decoration.BROWN_RUG_END, Decoration.RED_RUG_END, Decoration.OPULENT_RUG_END), + BEDROOM_RUG3(15266, BuildHotspotType.LINKED, BuildingUtils.BUILD_LOW_ANIM, Decoration.BROWN_RUG_CORNER, Decoration.RED_RUG_CORNER, Decoration.OPULENT_RUG_CORNER), + + /** + * Skill hall hotspots. + */ + ARMOUR_SPACE(15385, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.MITHRIL_ARMOUR, Decoration.ADAMANT_ARMOUR, Decoration.RUNE_ARMOUR), + ARMOUR_SPACE2(15384, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.MITHRIL_ARMOUR, Decoration.ADAMANT_ARMOUR, Decoration.RUNE_ARMOUR), + HEAD_TROPHY(15382, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.CRAWLING_HAND, Decoration.COCKATRICE_HEAD, Decoration.BASILISK_HEAD, Decoration.KURASK_HEAD, Decoration.ABYSSAL_DEMON_HEAD, Decoration.KBD_HEAD, Decoration.KQ_HEAD), + RUNE_CASE(15386, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.RUNE_CASE1, Decoration.RUNE_CASE2), + FISHING_TROPHY(15383, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.MOUNTED_BASS, Decoration.MOUNTED_SWORDFISH, Decoration.MOUNTED_SHARK), + HALL_RUG(15377, BuildHotspotType.LINKED, BuildingUtils.BUILD_LOW_ANIM, Decoration.BROWN_RUG_CENTER, Decoration.RED_RUG_CENTER, Decoration.OPULENT_RUG_CENTER), + HALL_RUG2(15378, BuildHotspotType.LINKED, BuildingUtils.BUILD_LOW_ANIM, Decoration.BROWN_RUG_END, Decoration.RED_RUG_END, Decoration.OPULENT_RUG_END), + HALL_RUG3(15379, BuildHotspotType.LINKED, BuildingUtils.BUILD_LOW_ANIM, Decoration.BROWN_RUG_CORNER, Decoration.RED_RUG_CORNER, Decoration.OPULENT_RUG_CORNER), + + /** + * Games room hotspots. + */ + RANGING_GAME(15346, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.HOOP_AND_STICK, Decoration.DARTBOARD, Decoration.ARCHERY_TARGET), + ATTACK_STONE(15344, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.CLAY_STONE, Decoration.LIMESTONE_STONE, Decoration.MARBLE_STONE), + PRIZE_CHEST(15343, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.OAK_CHEST, Decoration.TEAK_CHEST, Decoration.MAHOGANY_CHEST), + ELEMENTAL_BALANCE(15345, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.BALANCE_1, Decoration.BALANCE_2, Decoration.BALANCE_3), + GAME_SPACE(15342, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.JESTER, Decoration.TREASURE_HUNT, Decoration.HANGMAN), + + /** + * Portal room hotspots. + */ + TELEPORT_FOCUS(15409, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.TELEPORT_FOCUS, Decoration.GREATER_TELEPORT_FOCUS, Decoration.SCRYING_POOL), + PORTAL1(15406, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.TEAK_PORTAL, Decoration.MAHOGANY_PORTAL, Decoration.MARBLE_PORTAL, + Decoration.TEAK_VARROCK_PORTAL, + Decoration.MAHOGANY_VARROCK_PORTAL, + Decoration.MARBLE_VARROCK_PORTAL, + Decoration.TEAK_LUMBRIDGE_PORTAL, + Decoration.MAHOGANY_LUMBRIDGE_PORTAL, + Decoration.MARBLE_LUMBRIDGE_PORTAL, + Decoration.TEAK_FALADOR_PORTAL, + Decoration.MAHOGANY_FALADOR_PORTAL, + Decoration.MARBLE_FALADOR_PORTAL, + Decoration.TEAK_CAMELOT_PORTAL, + Decoration.MAHOGANY_CAMELOT_PORTAL, + Decoration.MARBLE_CAMELOT_PORTAL, + Decoration.TEAK_ARDOUGNE_PORTAL, + Decoration.MAHOGANY_ARDOUGNE_PORTAL, + Decoration.MARBLE_ARDOUGNE_PORTAL, + Decoration.TEAK_YANILLE_PORTAL, + Decoration.MAHOGANY_YANILLE_PORTAL, + Decoration.MARBLE_YANILLE_PORTAL, + Decoration.TEAK_KHARYRLL_PORTAL, + Decoration.MAHOGANY_KHARYRLL_PORTAL, + Decoration.MARBLE_KHARYRLL_PORTAL), + PORTAL2(15407, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.TEAK_PORTAL, Decoration.MAHOGANY_PORTAL, Decoration.MARBLE_PORTAL, + Decoration.TEAK_VARROCK_PORTAL, + Decoration.MAHOGANY_VARROCK_PORTAL, + Decoration.MARBLE_VARROCK_PORTAL, + Decoration.TEAK_LUMBRIDGE_PORTAL, + Decoration.MAHOGANY_LUMBRIDGE_PORTAL, + Decoration.MARBLE_LUMBRIDGE_PORTAL, + Decoration.TEAK_FALADOR_PORTAL, + Decoration.MAHOGANY_FALADOR_PORTAL, + Decoration.MARBLE_FALADOR_PORTAL, + Decoration.TEAK_CAMELOT_PORTAL, + Decoration.MAHOGANY_CAMELOT_PORTAL, + Decoration.MARBLE_CAMELOT_PORTAL, + Decoration.TEAK_ARDOUGNE_PORTAL, + Decoration.MAHOGANY_ARDOUGNE_PORTAL, + Decoration.MARBLE_ARDOUGNE_PORTAL, + Decoration.TEAK_YANILLE_PORTAL, + Decoration.MAHOGANY_YANILLE_PORTAL, + Decoration.MARBLE_YANILLE_PORTAL, + Decoration.TEAK_KHARYRLL_PORTAL, + Decoration.MAHOGANY_KHARYRLL_PORTAL, + Decoration.MARBLE_KHARYRLL_PORTAL), + PORTAL3(15408, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.TEAK_PORTAL, Decoration.MAHOGANY_PORTAL, Decoration.MARBLE_PORTAL, + Decoration.TEAK_VARROCK_PORTAL, + Decoration.MAHOGANY_VARROCK_PORTAL, + Decoration.MARBLE_VARROCK_PORTAL, + Decoration.TEAK_LUMBRIDGE_PORTAL, + Decoration.MAHOGANY_LUMBRIDGE_PORTAL, + Decoration.MARBLE_LUMBRIDGE_PORTAL, + Decoration.TEAK_FALADOR_PORTAL, + Decoration.MAHOGANY_FALADOR_PORTAL, + Decoration.MARBLE_FALADOR_PORTAL, + Decoration.TEAK_CAMELOT_PORTAL, + Decoration.MAHOGANY_CAMELOT_PORTAL, + Decoration.MARBLE_CAMELOT_PORTAL, + Decoration.TEAK_ARDOUGNE_PORTAL, + Decoration.MAHOGANY_ARDOUGNE_PORTAL, + Decoration.MARBLE_ARDOUGNE_PORTAL, + Decoration.TEAK_YANILLE_PORTAL, + Decoration.MAHOGANY_YANILLE_PORTAL, + Decoration.MARBLE_YANILLE_PORTAL, + Decoration.TEAK_KHARYRLL_PORTAL, + Decoration.MAHOGANY_KHARYRLL_PORTAL, + Decoration.MARBLE_KHARYRLL_PORTAL), + + /** + * Quest Hall hotspots. + */ + GUILD_TROPHY(15394, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.ANTIDRAGON_SHIELD, Decoration.AMULET_OF_GLORY, Decoration.CAPE_OF_LEGENDS), + PORTRAIT(15392, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.KING_ARTHUR, Decoration.ELENA, Decoration.GIANT_DWARF, Decoration.MISCELLANIANS), + LANDSCAPE(15393, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.LUMBRIDGE, Decoration.THE_DESERT, Decoration.MORYTANIA, Decoration.KARAMJA, Decoration.ISAFDAR), + SWORD(15395, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.SILVERLIGHT, Decoration.EXCALIBUR, Decoration.DARKLIGHT), + MAP(15396, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.SMALL_MAP, Decoration.MEDIUM_MAP, Decoration.LARGE_MAP), + BOOKCASE2(15397, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.WOODEN_BOOKCASE, Decoration.OAK_BOOKCASE, Decoration.MAHOGANY_BOOKCASE), + + /** + * Combat room hotspots. + */ + WALL_DECORATION2(15297, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.OAK_DECORATION, Decoration.TEAK_DECORATION, Decoration.GILDED_DECORATION), + STORAGE_SPACE(15296, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.GLOVE_RACK, Decoration.WEAPONS_RACK, Decoration.EXTRA_WEAPONS_RACK), + CR_RING(15277, BuildHotspotType.LINKED, BuildingUtils.BUILD_MID_ANIM, Decoration.BOXING_RING, Decoration.FENCING_RING, Decoration.COMBAT_RING, Decoration.NOTHING, Decoration.NOTHING2), + CR_CORNER(15278, BuildHotspotType.LINKED, BuildingUtils.BUILD_MID_ANIM, Decoration.BOXING_RING, Decoration.FENCING_RING, Decoration.COMBAT_RING, Decoration.NOTHING, Decoration.NOTHING2), + CR_CORNER2(15279, BuildHotspotType.LINKED, BuildingUtils.BUILD_MID_ANIM, Decoration.BOXING_RING, Decoration.FENCING_RING, Decoration.COMBAT_RING, Decoration.NOTHING, Decoration.NOTHING2), + CR_RING3(15280, BuildHotspotType.LINKED, BuildingUtils.BUILD_MID_ANIM, Decoration.BOXING_RING, Decoration.FENCING_RING, Decoration.COMBAT_RING, Decoration.NOTHING, Decoration.MAGIC_BARRIER), + CR_CORNER3(15281, BuildHotspotType.LINKED, BuildingUtils.BUILD_MID_ANIM, Decoration.BOXING_RING, Decoration.FENCING_RING, Decoration.COMBAT_RING, Decoration.NOTHING, Decoration.NOTHING2), + CR_CORNER4(15282, BuildHotspotType.LINKED, BuildingUtils.BUILD_MID_ANIM, Decoration.BOXING_RING, Decoration.FENCING_RING, Decoration.COMBAT_RING, Decoration.NOTHING, Decoration.NOTHING2), + CR_INVISIBLE_WALL(15283, BuildHotspotType.LINKED, BuildingUtils.BUILD_MID_ANIM, Decoration.INVISIBLE_WALL, Decoration.INVISIBLE_WALL, Decoration.INVISIBLE_WALL, Decoration.INVISIBLE_WALL, Decoration.MAGIC_BARRIER), + CR_INVISIBLE_WALL2(15284, BuildHotspotType.LINKED, BuildingUtils.BUILD_MID_ANIM, Decoration.INVISIBLE_WALL2, Decoration.INVISIBLE_WALL2, Decoration.INVISIBLE_WALL2, Decoration.INVISIBLE_WALL2, Decoration.MAGIC_BARRIER), + CR_INVISIBLE_WALL3(15285, BuildHotspotType.LINKED, BuildingUtils.BUILD_MID_ANIM, Decoration.INVISIBLE_WALL3, Decoration.INVISIBLE_WALL3, Decoration.INVISIBLE_WALL3, Decoration.INVISIBLE_WALL3, Decoration.MAGIC_BARRIER), + CR_RING4(15286, BuildHotspotType.LINKED, BuildingUtils.BUILD_MID_ANIM, Decoration.BOXING_RING, Decoration.FENCING_RING, Decoration.COMBAT_RING, Decoration.NOTHING, Decoration.NOTHING2), + CR_RING2(15287, BuildHotspotType.LINKED, BuildingUtils.BUILD_MID_ANIM, Decoration.BOXING_RING, Decoration.FENCING_RING, Decoration.COMBAT_RING, Decoration.NOTHING, Decoration.MAGIC_BARRIER), + CR_FLOOR(15288, BuildHotspotType.LINKED, BuildingUtils.BUILD_MID_ANIM, Decoration.BOXING_MAT_SIDE, Decoration.FENCING_MAT_SIDE, Decoration.COMBAT_MAT_SIDE, Decoration.BALANCE_BEAM_CENTER, Decoration.NOTHING2), + CR_FLOOR2(15289, BuildHotspotType.LINKED, BuildingUtils.BUILD_MID_ANIM, Decoration.BOXING_MAT_CORNER, Decoration.FENCING_MAT_CORNER, Decoration.COMBAT_MAT_CORNER, Decoration.BALANCE_BEAM_RIGHT, Decoration.NOTHING2), + CR_FLOOR3(15290, BuildHotspotType.LINKED, BuildingUtils.BUILD_MID_ANIM, Decoration.BOXING_MAT_CORNER, Decoration.FENCING_MAT_CORNER, Decoration.COMBAT_MAT_CORNER, Decoration.BALANCE_BEAM_LEFT, Decoration.RANGING_PEDESTALS), + CR_FLOOR4(15291, BuildHotspotType.LINKED, BuildingUtils.BUILD_MID_ANIM, Decoration.BOXING_MAT_SIDE, Decoration.FENCING_MAT_SIDE, Decoration.COMBAT_MAT_SIDE, Decoration.NOTHING, Decoration.NOTHING2), + CR_FLOOR5(15292, BuildHotspotType.LINKED, BuildingUtils.BUILD_MID_ANIM, Decoration.BOXING_MAT, Decoration.FENCING_MAT, Decoration.COMBAT_MAT, Decoration.NOTHING, Decoration.NOTHING2), + CR_FLOOR6(15293, BuildHotspotType.LINKED, BuildingUtils.BUILD_MID_ANIM, Decoration.BOXING_MAT_SIDE, Decoration.FENCING_MAT_SIDE, Decoration.COMBAT_MAT_SIDE, Decoration.NOTHING, Decoration.NOTHING2), + CR_FLOOR7(15294, BuildHotspotType.LINKED, BuildingUtils.BUILD_MID_ANIM, Decoration.BOXING_MAT_CORNER, Decoration.FENCING_MAT_CORNER, Decoration.COMBAT_MAT_CORNER, Decoration.NOTHING, Decoration.NOTHING2), + CR_FLOOR8(15295, BuildHotspotType.LINKED, BuildingUtils.BUILD_MID_ANIM, Decoration.BOXING_MAT_CORNER, Decoration.FENCING_MAT_CORNER, Decoration.COMBAT_MAT_CORNER, Decoration.NOTHING, Decoration.RANGING_PEDESTALS), + + /** + * Quest hall hotspots. + */ + Q_HALL_RUG(15387, BuildHotspotType.LINKED, BuildingUtils.BUILD_LOW_ANIM, Decoration.BROWN_RUG_CENTER, Decoration.RED_RUG_CENTER, Decoration.OPULENT_RUG_CENTER), + Q_HALL_RUG2(15388, BuildHotspotType.LINKED, BuildingUtils.BUILD_LOW_ANIM, Decoration.BROWN_RUG_END, Decoration.RED_RUG_END, Decoration.OPULENT_RUG_END), + Q_HALL_RUG3(15389, BuildHotspotType.LINKED, BuildingUtils.BUILD_LOW_ANIM, Decoration.BROWN_RUG_CORNER, Decoration.RED_RUG_CORNER, Decoration.OPULENT_RUG_CORNER), + + + /** + * Study hotspots. + */ + GLOBE(15421, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.GLOBE, Decoration.ORNAMENTAL_GLOBE, Decoration.LUNAR_GLOBE, Decoration.CELESTIAL_GLOBE, Decoration.ARMILLARY_SPHERE, Decoration.SMALL_ORREY, Decoration.LARGE_ORREY), + LECTERN(15420, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.OAK_LECTERN, Decoration.EAGLE_LECTERN, Decoration.DEMON_LECTERN, Decoration.TEAK_EAGLE_LECTERN, Decoration.TEAK_DEMON_LECTERN, Decoration.MAHOGANY_EAGLE_LECTERN, Decoration.MAHOGANY_DEMON_LECTERN), + CRYSTAL_BALL(15422, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.CRYSTAL_BALL, Decoration.ELEMENTAL_SPHERE, Decoration.CRYSTAL_OF_POWER), + BOOKCASE3(15425, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.WOODEN_BOOKCASE, Decoration.OAK_BOOKCASE, Decoration.MAHOGANY_BOOKCASE), + WALL_CHART(15423, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.ALCHEMICAL_CHART, Decoration.ASTRONOMICAL_CHART, Decoration.INFERNAL_CHART), + TELESCOPE(15424, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.TELESCOPE1, Decoration.TELESCOPE2, Decoration.TELESCOPE3), + + /** + * Costume room hotspots. + */ + TREASURE_CHEST(18813, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.OAK_TREASURE_CHEST, Decoration.TEAK_TREASURE_CHEST, Decoration.MAHOGANY_TREASURE_CHEST), + ARMOUR_CASE(18815, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.OAK_ARMOUR_CASE, Decoration.TEAK_ARMOUR_CASE, Decoration.MGANY_ARMOUR_CASE), + MAGIC_WARDROBE(18811, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.OAK_MAGIC_WARDROBE, Decoration.C_OAK_MAGIC_WARDROBE, Decoration.TEAK_MAGIC_WARDROBE, Decoration.C_TEAK_MAGIC_WARDROBE, Decoration.MGANY_MAGIC_WARDROBE, Decoration.GILDED_MAGIC_WARDROBE, Decoration.MARBLE_MAGIC_WARDROBE), + CAPE_RACK(18810, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.OAK_CAPE_RACK, Decoration.TEAK_CAPE_RACK, Decoration.MGANY_CAPE_RACK, Decoration.GILDED_CAPE_RACK, Decoration.MARBLE_CAPE_RACK, Decoration.MAGIC_CAPE_RACK), + TOY_BOX(18812, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.OAK_TOY_BOX, Decoration.TEAK_TOY_BOX, Decoration.MAHOGANY_TOY_BOX), + COSTUME_BOX(18814, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.OAK_COSTUME_BOX, Decoration.TEAK_COSTUME_BOX, Decoration.MAHOGANY_COSTUME_BOX), + + /** + * Chapel hotspots. + */ + ALTAR(15270, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.OAK_ALTAR, Decoration.TEAK_ALTAR, Decoration.CLOTH_ALTAR, Decoration.MAHOGANY_ALTAR, Decoration.LIMESTONE_ALTAR, Decoration.MARBLE_ALTAR, Decoration.GILDED_ALTAR), + STATUE(15275, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_MID_ANIM, Decoration.SMALL_STATUE, Decoration.MEDIUM_STATUE, Decoration.LARGE_STATUE), + MUSICAL(15276, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.WINDCHIMES, Decoration.BELLS, Decoration.ORGAN), + ICON(15269, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.SARADOMIN_SYMBOL, Decoration.ZAMORAK_SYMBOL, Decoration.GUTHIX_SYMBOL, Decoration.SARADOMIN_ICON, Decoration.ZAMORAK_ICON, Decoration.GUTHIX_ICON, Decoration.ICON_OF_BOB), + BURNERS(15271, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_MID_ANIM, Decoration.STEEL_TORCHES, Decoration.WOODEN_TORCHES, Decoration.STEEL_CANDLESTICKS, Decoration.GOLD_CANDLESTICKS, Decoration.INCENSE_BURNERS, Decoration.MAHOGANY_BURNERS, Decoration.MARBLE_BURNERS), + CHAPEL_WINDOW(new int[] { 13730, 13728, 13732, 13729, 13733, 13731}, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.SHUTTERED_WINDOW, Decoration.DECORATIVE_WINDOW, Decoration.STAINED_GLASS), + CHAPEL_RUG(15273, BuildHotspotType.LINKED, BuildingUtils.BUILD_LOW_ANIM, Decoration.BROWN_RUG_END, Decoration.RED_RUG_END, Decoration.OPULENT_RUG_END), + CHAPEL_RUG2(15274, BuildHotspotType.LINKED, BuildingUtils.BUILD_LOW_ANIM, Decoration.BROWN_RUG_CORNER, Decoration.RED_RUG_CORNER, Decoration.OPULENT_RUG_CORNER), + + /** + * Formal garden hotspots. + */ + CENTREPIECE_2(15368, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.PORTAL, Decoration.GAZEBO, Decoration.DUNGEON_ENTRANCE, Decoration.SMALL_FOUNTAIN, Decoration.LARGE_FOUNTAIN, Decoration.POSH_FOUNTAIN), + FENCING(15369, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.BOUNDARY_STONES, Decoration.WOODEN_FENCE, Decoration.STONE_WALL, Decoration.IRON_RAILINGS, Decoration.PICKET_FENCE, Decoration.GARDEN_FENCE, Decoration.MARBLE_WALL), + SMALL_PLANT1(15375, BuildHotspotType.INDIVIDUAL, BuildingUtils.PLANT_ANIM, Decoration.SUNFLOWER, Decoration.MARIGOLDS, Decoration.ROSES), + BIG_PLANT1(15373, BuildHotspotType.INDIVIDUAL, BuildingUtils.PLANT_ANIM, Decoration.SUNFLOWER_BIG, Decoration.MARIGOLDS_BIG, Decoration.ROSES_BIG), + SMALL_PLANT2(15376, BuildHotspotType.INDIVIDUAL, BuildingUtils.PLANT_ANIM, Decoration.ROSEMARY, Decoration.DAFFODILS, Decoration.BLUEBELLS), + BIG_PLANT2(15374, BuildHotspotType.INDIVIDUAL, BuildingUtils.PLANT_ANIM, Decoration.ROSEMARY_BIG, Decoration.DAFFODILS_BIG, Decoration.BLUEBELLS_BIG), + HEDGE1(15370, BuildHotspotType.LINKED, BuildingUtils.PLANT_ANIM, Decoration.THORNY_HEDGE1, Decoration.NICE_HEDGE1, Decoration.SMALL_BOX_HEDGE1, Decoration.TOPIARY_HEDGE1, Decoration.FANCY_HEDGE1, Decoration.TALL_FANCY_HEDGE1, Decoration.TALL_BOX_HEDGE1), + HEDGE2(15371, BuildHotspotType.LINKED, BuildingUtils.PLANT_ANIM, Decoration.THORNY_HEDGE2, Decoration.NICE_HEDGE2, Decoration.SMALL_BOX_HEDGE2, Decoration.TOPIARY_HEDGE2, Decoration.FANCY_HEDGE2, Decoration.TALL_FANCY_HEDGE2, Decoration.TALL_BOX_HEDGE2), + HEDGE3(15372, BuildHotspotType.LINKED, BuildingUtils.PLANT_ANIM, Decoration.THORNY_HEDGE3, Decoration.NICE_HEDGE3, Decoration.SMALL_BOX_HEDGE3, Decoration.TOPIARY_HEDGE3, Decoration.FANCY_HEDGE3, Decoration.TALL_FANCY_HEDGE3, Decoration.TALL_BOX_HEDGE3), + + /** + * Throne room hotspots. + */ + THRONE(15426, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_MID_ANIM, Decoration.OAK_THRONE, Decoration.TEAK_THRONE, Decoration.MAHOGANY_THRONE, Decoration.GILDED_THRONE, Decoration.SKELETON_THRONE, Decoration.CRYSTAL_THRONE, Decoration.DEMONIC_THRONE), + LEVER(15435, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.OAK_LEVER, Decoration.TEAK_LEVER, Decoration.MAHOGANY_LEVER), + FLOOR(new int[] { 15427, 15428, 15429, 15430, 15431, 15432 }, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_LOW_ANIM, Decoration.FLOOR_DECORATION, Decoration.STEEL_CAGE, Decoration.FLOOR_TRAP, Decoration.MAGIC_CIRCLE, Decoration.MAGIC_CAGE), + SEATING1(15436, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_MID_ANIM, Decoration.CARVED_TEAK_BENCH, Decoration.MAHOGANY_BENCH, Decoration.GILDED_BENCH), + SEATING2(15437, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_MID_ANIM, Decoration.CARVED_TEAK_BENCH, Decoration.MAHOGANY_BENCH, Decoration.GILDED_BENCH), + TRAPDOOR(15438, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_LOW_ANIM, Decoration.OAK_TRAPDOOR, Decoration.TEAK_TRAPDOOR, Decoration.MAHOGANY_TRAPDOOR), + DECORATION(15434, BuildHotspotType.CREST, BuildingUtils.BUILD_HIGH_ANIM, Decoration.OAK_DECO, Decoration.TEAK_DECO, Decoration.GILDED_DECO, Decoration.ROUND_SHIELD, Decoration.SQUARE_SHIELD, Decoration.KITE_SHIELD), + + /** + * Oubliette hotspots. + */ + FLOOR_MID(15347, BuildHotspotType.LINKED, BuildingUtils.BUILD_LOW_ANIM, Decoration.SPIKES_MID, Decoration.TENTACLE_MID, Decoration.FP_FLOOR_MID, Decoration.ROCNAR_FLOOR_MID), + FLOOR_SIDE(15348, BuildHotspotType.LINKED, BuildingUtils.BUILD_LOW_ANIM, Decoration.SPIKES_SIDE, Decoration.TENTACLE_SIDE, Decoration.FP_FLOOR_SIDE, Decoration.ROCNAR_FLOOR_SIDE), + FLOOR_CORNER(15349, BuildHotspotType.LINKED, BuildingUtils.BUILD_LOW_ANIM, Decoration.SPIKES_CORNER, Decoration.TENTACLE_CORNER, Decoration.FP_FLOOR_CORNER, Decoration.ROCNAR_FLOOR_CORNER), + OUBLIETTE_FLOOR(15350, BuildHotspotType.LINKED, BuildingUtils.BUILD_LOW_ANIM, Decoration.SPIKES_FL, Decoration.TENTACLE_FL, Decoration.FLAME_PIT, Decoration.ROCNAR_FL), + OUBLIETTE_FLOOR_1(15351, BuildHotspotType.LINKED, BuildingUtils.BUILD_LOW_ANIM, Decoration.SPIKES_FL, Decoration.TENTACLE_FL, Decoration.FLAME_PIT, Decoration.ROCNAR), + PRISON(15352, BuildHotspotType.LINKED, BuildingUtils.BUILD_HIGH_ANIM, Decoration.OAK_CAGE, Decoration.OAK_STEEL_CAGE, Decoration.STEEL_CAGE_OU, Decoration.SPIKED_CAGE, Decoration.BONE_CAGE), + PRISON_DOOR(15353, BuildHotspotType.LINKED, BuildingUtils.BUILD_HIGH_ANIM, Decoration.OAK_CAGE_DOOR, Decoration.OAK_STEEL_CAGE_DOOR, Decoration.STEEL_CAGE_DOOR, Decoration.SPIKED_CAGE_DOOR, Decoration.BONE_CAGE_DOOR), + GUARD(15354, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.SKELETON_GUARD, Decoration.GUARD_DOG, Decoration.HOBGOBLIN, Decoration.BABY_RED_DRAGON, Decoration.HUGE_SPIDER, Decoration.TROLL, Decoration.HELLHOUND), + LADDER(15356, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.OAK_LADDER, Decoration.TEAK_LADDER, Decoration.MAHOGANY_LADDER), + OUBLIETTE_LIGHT(15355, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.CANDLE, Decoration.TORCH, Decoration.SKULL_TORCH), + + /** + * Corridor, junction, stairs, TODO: pit trap + */ + DUNGEON_DOOR_LEFT(15328, BuildHotspotType.LINKED, BuildingUtils.BUILD_HIGH_ANIM, Decoration.OAK_DOOR_LEFT, Decoration.STEEL_DOOR_LEFT, Decoration.MARBLE_DOOR_LEFT), + DUNGEON_DOOR_RIGHT(15329, BuildHotspotType.LINKED, BuildingUtils.BUILD_HIGH_ANIM, Decoration.OAK_DOOR_RIGHT, Decoration.STEEL_DOOR_RIGHT, Decoration.MARBLE_DOOR_RIGHT), + DUNGEON_DOOR_LEFT2(15326, BuildHotspotType.LINKED, BuildingUtils.BUILD_HIGH_ANIM, Decoration.OAK_DOOR_LEFT, Decoration.STEEL_DOOR_LEFT, Decoration.MARBLE_DOOR_LEFT), + DUNGEON_DOOR_RIGHT2(15327, BuildHotspotType.LINKED, BuildingUtils.BUILD_HIGH_ANIM, Decoration.OAK_DOOR_RIGHT, Decoration.STEEL_DOOR_RIGHT, Decoration.MARBLE_DOOR_RIGHT), + DUNGEON_DOOR_LEFT3(36672, BuildHotspotType.LINKED, BuildingUtils.BUILD_HIGH_ANIM, Decoration.OAK_DOOR_LEFT, Decoration.STEEL_DOOR_LEFT, Decoration.MARBLE_DOOR_LEFT), + DUNGEON_DOOR_RIGHT3(36675, BuildHotspotType.LINKED, BuildingUtils.BUILD_HIGH_ANIM, Decoration.OAK_DOOR_RIGHT, Decoration.STEEL_DOOR_RIGHT, Decoration.MARBLE_DOOR_RIGHT), + DUNGEON_TRAP(15324, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_LOW_ANIM, Decoration.SPIKE_TRAP, Decoration.MAN_TRAP, Decoration.TANGLE_TRAP, Decoration.MARBLE_TRAP, Decoration.TELEPORT_TRAP), + DUNGEON_TRAP2(15325, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_LOW_ANIM, Decoration.SPIKE_TRAP, Decoration.MAN_TRAP, Decoration.TANGLE_TRAP, Decoration.MARBLE_TRAP, Decoration.TELEPORT_TRAP), + DUNGEON_LIGHT(15330, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.CANDLE, Decoration.TORCH, Decoration.SKULL_TORCH), + DUNGEON_DECO(15331, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.DECORATIVE_BLOOD, Decoration.DECORATIVE_PIPE, Decoration.HANGING_SKELETON), + DUNGEON_GUARD(15323, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.SKELETON_GUARD, Decoration.GUARD_DOG, Decoration.HOBGOBLIN, Decoration.BABY_RED_DRAGON, Decoration.HUGE_SPIDER, Decoration.TROLL, Decoration.HELLHOUND), + DUNGEON_GUARD2(15336, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.SKELETON_GUARD, Decoration.GUARD_DOG, Decoration.HOBGOBLIN, Decoration.BABY_RED_DRAGON, Decoration.HUGE_SPIDER, Decoration.TROLL, Decoration.HELLHOUND), + DUNGEON_GUARD3(15337, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.SKELETON_GUARD, Decoration.GUARD_DOG, Decoration.HOBGOBLIN, Decoration.BABY_RED_DRAGON, Decoration.HUGE_SPIDER, Decoration.TROLL, Decoration.HELLHOUND), + DUNGEON_LIGHT2(34138, BuildHotspotType.RECURSIVE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.CANDLE, Decoration.TORCH, Decoration.SKULL_TORCH), + DUNGEON_PIT_GUARD(36676, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.PIT_DOG, Decoration.PIT_OGRE, Decoration.PIT_ROCK_PROTECTOR, Decoration.PIT_SCABARITE, Decoration.PIT_BLACK_DEMON, Decoration.PIT_IRON_DRAGON), + + /** + * Treasure room + */ + MONSTER(15257, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.DEMON, Decoration.KALPHITE_SOLDIER, Decoration.TOK_XIL, Decoration.DAGANNOTH, Decoration.STEEL_DRAGON), + TREASURE_CHEST1(15256, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_MID_ANIM, Decoration.WOODEN_CRATE, Decoration.OAK_T_CHEST, Decoration.TEAK_T_CHEST, Decoration.MGANY_T_CHEST, Decoration.MAGIC_CHEST), + WALL_DECORATION1(15259, BuildHotspotType.CREST, BuildingUtils.BUILD_HIGH_ANIM, Decoration.ROUND_SHIELD, Decoration.SQUARE_SHIELD, Decoration.KITE_SHIELD), + + /** + * Stairways. + */ + STAIRWAYS(15380, BuildHotspotType.STAIRCASE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.OAK_STAIRCASE, Decoration.TEAK_STAIRCASE, Decoration.SPIRAL_STAIRCASE, Decoration.MARBLE_STAIRCASE, Decoration.MARBLE_SPIRAL), + QUEST_STAIRWAYS(15390, BuildHotspotType.STAIRCASE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.OAK_STAIRCASE, Decoration.TEAK_STAIRCASE, Decoration.SPIRAL_STAIRCASE, Decoration.MARBLE_STAIRCASE, Decoration.MARBLE_SPIRAL), + STAIRWAYS_DUNGEON(new int[] { 15380, 15380, 15380, 15380, 15390, 15390}, BuildHotspotType.STAIRCASE, BuildingUtils.BUILD_HIGH_ANIM, Decoration.OAK_STAIRCASE, Decoration.TEAK_STAIRCASE, Decoration.SPIRAL_STAIRCASE, Decoration.MARBLE_STAIRCASE, Decoration.MARBLE_SPIRAL), + + /** + * Stairways. + */ + STAIRS_DOWN(15381, BuildHotspotType.STAIRCASE, BuildingUtils.BUILD_LOW_ANIM, Decoration.OAK_STAIRS_DOWN, Decoration.TEAK_STAIRS_DOWN, Decoration.SPIRAL_STAIRS_DOWN, Decoration.MARBLE_STAIRS_DOWN, Decoration.MARBLE_SPIRAL_DOWN), + STAIRS_DOWN2(15391, BuildHotspotType.STAIRCASE, BuildingUtils.BUILD_LOW_ANIM, Decoration.OAK_STAIRS_DOWN, Decoration.TEAK_STAIRS_DOWN, Decoration.SPIRAL_STAIRS_DOWN, Decoration.MARBLE_STAIRS_DOWN, Decoration.MARBLE_SPIRAL_DOWN), + + + /** + * Window hotspots. + */ + WINDOW(13830, BuildHotspotType.INDIVIDUAL, BuildingUtils.BUILD_HIGH_ANIM, Decoration.BASIC_WOOD_WINDOW, Decoration.BASIC_STONE_WINDOW, Decoration.WHITEWASHED_STONE_WINDOW, Decoration.FREMENNIK_WINDOW, Decoration.TROPICAL_WOOD_WINDOW, Decoration.FANCY_STONE_WINDOW), + ; + + /** + * The object id. + */ + private final int objectId; + + /** + * The object ids. + */ + private final int[] objectIds; + + /** + * The decorations to build on this hotspot. + */ + private final Decoration[] decorations; + + /** + * The hotspot type. + */ + private final BuildHotspotType type; + + /** + * The building animation. + */ + private final Animation buildingAnimation; + + /** + * The linked hotspots + */ + private static final List linkedHotspots = new ArrayList(); + + /** + * Configures hotspots. + */ + static { + linkedHotspots.add(new BuildHotspot[] { RUG, RUG2, RUG3 }); + linkedHotspots.add(new BuildHotspot[] { BEDROOM_RUG, BEDROOM_RUG2, BEDROOM_RUG3 }); + linkedHotspots.add(new BuildHotspot[] { HALL_RUG, HALL_RUG2, HALL_RUG3 }); + linkedHotspots.add(new BuildHotspot[] { CR_CORNER, CR_CORNER2, CR_CORNER3, CR_CORNER4, CR_RING, + CR_RING2, CR_RING3, CR_RING4, CR_FLOOR, CR_FLOOR2, CR_FLOOR3, CR_FLOOR4, CR_FLOOR5, + CR_FLOOR6, CR_FLOOR7, CR_FLOOR8, CR_INVISIBLE_WALL, CR_INVISIBLE_WALL2, CR_INVISIBLE_WALL3}); + linkedHotspots.add(new BuildHotspot[] { Q_HALL_RUG, Q_HALL_RUG2, Q_HALL_RUG3 }); + linkedHotspots.add(new BuildHotspot[] { CHAPEL_RUG, CHAPEL_RUG2 }); + linkedHotspots.add(new BuildHotspot[] { HEDGE1, HEDGE2, HEDGE3 }); + linkedHotspots.add(new BuildHotspot[] { FLOOR_MID, FLOOR_SIDE, FLOOR_CORNER, OUBLIETTE_FLOOR, OUBLIETTE_FLOOR_1 }); + linkedHotspots.add(new BuildHotspot[] { PRISON, PRISON_DOOR }); + linkedHotspots.add(new BuildHotspot[] { DUNGEON_DOOR_LEFT, DUNGEON_DOOR_RIGHT }); + linkedHotspots.add(new BuildHotspot[] { DUNGEON_DOOR_LEFT2, DUNGEON_DOOR_RIGHT2 }); + linkedHotspots.add(new BuildHotspot[] { SMALL_PLANT_1, SMALL_PLANT1 }); + linkedHotspots.add(new BuildHotspot[] { SHELVES, SHELVES_2 }); + } + + /** + * Constructs a new {@code BuildHotspot} {@code Object}. + * @param objectId The object id. + * @param buildingAnimation The building animation. + * @param decorations The decoration. + */ + private BuildHotspot(int objectId, BuildHotspotType type, Animation buildingAnimation, Decoration... decorations) { + this.objectId = objectId; + this.objectIds = null; + this.type = type; + this.buildingAnimation = buildingAnimation; + this.decorations = decorations; + } + + /** + * Constructs a new {@code BuildHotspot} {@code Object}. + * @param objectIds The objects ids. + * @param buildingAnimation The building animation. + * @param decorations The decoration. + */ + private BuildHotspot(int[] objectIds, BuildHotspotType type, Animation buildingAnimation, Decoration... decorations) { + this.objectId = objectIds[0]; + this.objectIds = objectIds; + this.type = type; + this.buildingAnimation = buildingAnimation; + this.decorations = decorations; + } + + /** + * Gets the building hotspot for the given object id. + * @param id The object id. + * @param style The housing style. + * @return The building hotspot. + */ + public static BuildHotspot forId(int id, HousingStyle style) { + for (BuildHotspot spot : values()) { + if (spot.getObjectId(style) == id) { + return spot; + } + } + return null; + } + + /** + * Gets the linked hotspots (if any) + * @param b - the buildhotspot to find linked hotspots + * @return BuildHotspot[] or null + */ + public static BuildHotspot[] getLinkedHotspots(BuildHotspot b) { + for (BuildHotspot[] list : linkedHotspots) { + for (BuildHotspot bh : list) { + if (bh == b) { + return list; + } + } + } + return null; + } + + /** + * Gets the decoration index. + * @param deco The decoration. + * @return The index. + */ + public int getDecorationIndex(Decoration deco) { + for (int i = 0; i < decorations.length; i++) { + if (decorations[i] == deco) { + return i; + } + } + return -1; + } + + /** + * Gets the objectId. + * @param style The current housing style. + * @return The objectId. + */ + public int getObjectId(HousingStyle style) { + if (objectIds != null) { + return objectIds[style.ordinal()]; + } + return objectId; + } + + /** + * Gets the objectId. + * @return The objectId. + */ + public int getObjectId() { + return objectId; + } + + /** + * Gets the type + * @return type + */ + public BuildHotspotType getType() { + return type; + } + + /** + * Gets the decorations. + * @return The decorations. + */ + public Decoration[] getDecorations() { + return decorations; + } + + /** + * Gets the objectIds value. + * @return The objectIds. + */ + public int[] getObjectIds() { + return objectIds; + } + + /** + * Gets the buildingAnimation value. + * @return The buildingAnimation. + */ + public Animation getBuildingAnimation() { + return buildingAnimation; + } + +} diff --git a/Server/src/main/content/global/skill/construction/BuildHotspotType.java b/Server/src/main/content/global/skill/construction/BuildHotspotType.java new file mode 100644 index 0000000..b477e82 --- /dev/null +++ b/Server/src/main/content/global/skill/construction/BuildHotspotType.java @@ -0,0 +1,20 @@ +package content.global.skill.construction; + +/** + * BuiltHotspotType + * @author Clayton Williams + * @date Jul 26, 2015 + */ +public enum BuildHotspotType { + + INDIVIDUAL, + RECURSIVE, + LINKED, + CREST, + STAIRCASE; + + BuildHotspotType() { + + } + +} diff --git a/Server/src/main/content/global/skill/construction/BuildOptionPlugin.java b/Server/src/main/content/global/skill/construction/BuildOptionPlugin.java new file mode 100644 index 0000000..69b0b14 --- /dev/null +++ b/Server/src/main/content/global/skill/construction/BuildOptionPlugin.java @@ -0,0 +1,184 @@ +package content.global.skill.construction; + + +import core.cache.def.impl.SceneryDefinition; +import core.game.component.Component; +import core.game.dialogue.DialogueInterpreter; +import core.game.dialogue.DialoguePlugin; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.tools.Log; +import core.tools.SystemLogger; +import core.plugin.ClassScanner; + +import static core.api.ContentAPIKt.log; + +/** + * The build option handling plugin. + * @author Emperor + * + */ +@Initializable +public final class BuildOptionPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.setOptionHandler("build", this); + SceneryDefinition.setOptionHandler("remove", this); + ClassScanner.definePlugin(new RemoveDialogue()); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + if (!player.getHouseManager().isBuildingMode()) { + player.getPacketDispatch().sendMessage("You have to be in building mode to do this."); + return true; + } + Scenery object = ((Scenery) node); + if (option.equals("remove")) { + Decoration decoration = Decoration.getDecoration(player, object); + if (decoration == null || !object.isActive()) { + return false; + } + player.getDialogueInterpreter().open("con:removedec", object); + return true; + } + player.setAttribute("con:hsobject", node); + if (BuildingUtils.isDoorHotspot(object)) { + int[] pos = BuildingUtils.roomExists(player, object); + if (pos != null) { + player.getDialogueInterpreter().open("con:remove", "room", pos); + return true; + } + if (player.getHouseManager().getRoomAmount() < player.getHouseManager().getMaximumRooms(player)) { + player.getInterfaceManager().open(new Component(402)); + + + } else { + player.getPacketDispatch().sendMessage("You currently have the maximum amount of rooms available."); + } + return true; + } + Hotspot hotspot = player.getHouseManager().getHotspot(object); + if (hotspot == null || !isBuildable(player, object, hotspot)) { + //log demoted from ERR to WARN June 16, 2023 -> It's the effect of an already-known issue. Reduced visibility to clean up server logs while still making the issue apparent in dev environs + log(this.getClass(), Log.WARN, "Construction (building): " + hotspot + " : " + object + " chunkX = " + object.getLocation().getChunkX() + ", chunkY = " + object.getLocation().getChunkY()); + return true; + } + + player.setAttribute("con:hotspot", hotspot); + BuildingUtils.openBuildInterface(player, hotspot.getHotspot()); + return true; + } + + /** + * Checks if the hotspot can be used. + * @param player The player. + * @param hotspot The hotspot. + * @return {@code True} if so. + */ + private static boolean isBuildable(Player player, Scenery object, Hotspot hotspot) { + Room room = player.getHouseManager().getRoom(object.getLocation()); + if (room == null) { + return false; + } + switch (hotspot.getHotspot()) { + case STAIRWAYS: + case STAIRS_DOWN: + case STAIRWAYS_DUNGEON: + if (room.isBuilt(BuildHotspot.HALL_RUG)) { + player.getPacketDispatch().sendMessage("You can't build a staircase on a rug."); + return false; + } + return true; + case HALL_RUG: + case HALL_RUG2: + case HALL_RUG3: + if (room.isBuilt(BuildHotspot.STAIRWAYS) || room.isBuilt(BuildHotspot.STAIRS_DOWN) || room.isBuilt(BuildHotspot.STAIRWAYS_DUNGEON)) { + player.getPacketDispatch().sendMessage("You can't build a rug under a staircase."); + return false; + } + return true; + case QUEST_STAIRWAYS: + case STAIRS_DOWN2: + if (room.isBuilt(BuildHotspot.Q_HALL_RUG)) { + player.getPacketDispatch().sendMessage("You can't build a staircase on a rug."); + return false; + } + return true; + case Q_HALL_RUG: + case Q_HALL_RUG2: + case Q_HALL_RUG3: + if (room.isBuilt(BuildHotspot.QUEST_STAIRWAYS) || room.isBuilt(BuildHotspot.STAIRS_DOWN2)) { + player.getPacketDispatch().sendMessage("You can't build a rug under a staircase."); + return false; + } + return true; + default: + return true; + } + } + + /** + * Handles the removing a decoration dialogue. + * @author Emperor + * + */ + private static class RemoveDialogue extends DialoguePlugin { + + /** + * The object. + */ + private Scenery object; + + /** + * Constructs a new {@code RemoveDialogue} {@code Object}. + */ + public RemoveDialogue() { + super(); + } + + /** + * Constructs a new {@code RemoveDialogue} {@code Object}. + * @param player The player. + */ + public RemoveDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new RemoveDialogue(player); + } + + @Override + public boolean open(Object... args) { + interpreter.sendOptions("Really remove it?", "Yes", "No"); + object = (Scenery) args[0]; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (buttonId) { + case 1: + BuildingUtils.removeDecoration(player, object); + break; + } + end(); + return true; + } + + @Override + public int[] getIds() { + return new int[] { DialogueInterpreter.getDialogueKey("con:removedec") }; + } + + } + +} diff --git a/Server/src/main/content/global/skill/construction/BuildRoomDialogue.java b/Server/src/main/content/global/skill/construction/BuildRoomDialogue.java new file mode 100644 index 0000000..b74e99c --- /dev/null +++ b/Server/src/main/content/global/skill/construction/BuildRoomDialogue.java @@ -0,0 +1,264 @@ +package content.global.skill.construction; + + +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.RegionChunk; +import core.plugin.Initializable; +import core.game.dialogue.DialogueInterpreter; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.skill.Skills; +import org.rs09.consts.Items; + +import java.awt.*; +import java.util.ArrayList; +import java.util.List; + +/** + * Handles the building a room dialogue. + * @author Emperor + * + */ +@Initializable +public final class BuildRoomDialogue extends DialoguePlugin { + + /** + * The door hotspot. + */ + private Scenery door; + + /** + * The direction. + */ + private Direction[] directions; + + /** + * The room exits. + */ + private boolean[] exits; + + /** + * The rotation index. + */ + private int index; + + /** + * The boundaries of the room to build. + */ + private List boundaries = new ArrayList<>(20); + + /** + * The room we're building. + */ + private Room room; + + /** + * The room x-coordinate. + */ + private int roomX; + + /** + * The room y-coordinate. + */ + private int roomY; + + /** + * The room z-coordinate (3 for dungeon). + */ + private int roomZ; + + /** + * Constructs a new {@code BuildRoomDialogue} {@code Object} + */ + public BuildRoomDialogue() { + super(); + } + + /** + * Constructs a new {@code BuildRoomDialogue} {@code Object} + * @param player The player. + */ + public BuildRoomDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new BuildRoomDialogue(player); + } + + @Override + public boolean open(Object... args) { + player.getInterfaceManager().close(); + RoomProperties props = (RoomProperties) args[0]; + if (player.getSkills().getStaticLevel(Skills.CONSTRUCTION) < props.getLevel()) { + interpreter.sendPlainMessage(false, "You need a Construction level of " + props.getLevel() + " to buy this room."); + stage = 2; + return true; + } + if (!player.getInventory().contains(995, props.getCost())) { + interpreter.sendPlainMessage(false, "You need " + props.getCost() + " coins to buy this room."); + stage = 2; + return true; + } + this.door = (Scenery) player.getAttribute("con:hsobject"); + int[] pos = BuildingUtils.getRoomPosition(player, door); + roomX = pos[0]; + roomY = pos[1]; + if (!inBounds()) { + interpreter.sendPlainMessage(false, "Your house is too large. TODO: correct message"); + stage = 2; + return true; + } + roomZ = player.getLocation().getZ(); + if (roomZ != 0) { + Room r = player.getHouseManager().getRooms()[roomZ - 1][roomX][roomY]; + if (r == null || r.getProperties().isLand()) { + interpreter.sendPlainMessage(false, "You can't build a room here, you need a room to build on."); + stage = 2; + return true; + } + } + if (HouseManager.isInDungeon(player)) { + if (props.isLand()) { + interpreter.sendPlainMessage(false, "You can't build this room inside your dungeon."); + stage = 2; + return true; + } + roomZ = 3; + } + else if (props.isDungeon()) { + interpreter.sendPlainMessage(false, "You can only build this room in your dungeon."); + stage = 2; + return true; + } + if (props.isLand() && roomZ != 0) { + interpreter.sendPlainMessage(false, "A garden can only be on ground floor."); + stage = 2; + return true; + } + this.room = Room.create(player, props); + this.exits = room.getExits(Direction.NORTH); + this.index = 0; + this.directions = BuildingUtils.getAvailableRotations(player, exits, roomZ, roomX, roomY); + while (directions[index] == null) { + if (++index == directions.length) { + interpreter.sendPlainMessage(false, "There's no space to build this room."); + stage = 2; + return true; + } + } + options("Rotate clockwise", "Rotate anticlockwise", "Build", "Cancel"); + stage = 1; + drawGhostRoom(); + return true; + } + + /** + * Checks if the room to be built is in the available boundaries of the house. + * @return The boundaries. + */ + private boolean inBounds() { + Rectangle bounds = player.getHouseManager().getBoundaries(); + int max = player.getHouseManager().getMaximumDimension(player); + if ((roomX < bounds.x || roomX >= bounds.x + bounds.width) && bounds.width >= max) { + return false; + } + if ((roomY < bounds.y || roomY >= bounds.y + bounds.height) && bounds.height >= max) { + return false; + } + return true; + } + + @Override + public boolean close() { + for (Scenery object : boundaries) { + SceneryBuilder.remove(object); + } + boundaries.clear(); + return super.close(); + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 1: + switch (buttonId) { + case 1: + case 2: + rotate(buttonId == 2); + options("Rotate clockwise", "Rotate anticlockwise", "Build", "Cancel"); + return true; + case 3: + if (player.getInventory().remove(new Item(Items.COINS_995, room.getProperties().getCost()))) { + room.setRotation(directions[index]); + boolean[] exit = new boolean[exits.length]; + for (int i = 0; i < exit.length; i++) { + exit[(i + index) % exit.length] = exits[i]; + } + BuildingUtils.buildRoom(player, room, roomZ, roomX, roomY, exit, true); + end(); + return true; + } + interpreter.sendPlainMessage(false, "You need " + room.getProperties().getCost() + " coins to buy this room."); + stage = 2; + return true; + case 4: + end(); + return true; + } + break; + case 2: + end(); + return true; + } + return false; + } + + /** + * Rotates the room. + * @param counter If we're rotating counter clockwise. + */ + private void rotate(boolean counter) { + Direction direction = null; + while ((direction = directions[index = (index + (counter ? 3 : 1)) % 4]) == null) { + + } + room.setRotation(direction); + drawGhostRoom(); + } + + /** + * Draws the current boundaries of the room to build. + */ + private void drawGhostRoom() { + for (Scenery object : boundaries) { + SceneryBuilder.remove(object); + } + int rotation = directions[index].toInteger(); + boundaries.clear(); + Location base = player.getViewport().getRegion().getBaseLocation().transform(roomX << 3, roomY << 3, player.getLocation().getZ()); + for (int x = 0; x < 8; x++) { + for (int y = 0; y < 8; y++) { + Scenery[] objects = room.getChunk().getObjects(x, y); + for (Scenery object : objects) { + if (object != null && object.getDefinition().hasAction("build")) { + int[] pos = RegionChunk.getRotatedPosition(x, y, object.getDefinition().getSizeX(), object.getDefinition().getSizeY(), object.getRotation(), rotation); + Scenery obj = object.transform(object.getId(), (object.getRotation() + rotation) % 4, base.transform(pos[0], pos[1], 0)); + boundaries.add(SceneryBuilder.add(obj)); + } + } + } + } + } + + @Override + public int[] getIds() { + return new int[] { DialogueInterpreter.getDialogueKey("con:room") }; + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/BuildingUtils.java b/Server/src/main/content/global/skill/construction/BuildingUtils.java new file mode 100644 index 0000000..02bfbd9 --- /dev/null +++ b/Server/src/main/content/global/skill/construction/BuildingUtils.java @@ -0,0 +1,679 @@ +package content.global.skill.construction; + +import core.cache.def.impl.ItemDefinition; +import core.game.component.Component; +import core.game.node.entity.player.Player; +import core.game.node.entity.skill.Skills; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.map.BuildRegionChunk; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.Region; +import core.game.world.update.flag.context.Animation; +import core.net.packet.PacketRepository; +import core.net.packet.context.ContainerContext; +import core.net.packet.out.ContainerPacket; +import core.tools.Log; +import org.jetbrains.annotations.NotNull; +import core.tools.SystemLogger; +import org.rs09.consts.Items; + +import java.util.ArrayList; +import java.util.Arrays; + +import static core.api.ContentAPIKt.*; + +/** + * Utility class for building. + * @author Emperor + * + */ +public final class BuildingUtils { + + /** + * The directions array. + */ + public static final Direction[] DIRECTIONS = { + Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST + }; + + /** + * The building a decoration animation. + */ + public static final Animation BUILD_LOW_ANIM = Animation.create(3683); + + /** + * The building a decoration animation. + */ + public static final Animation BUILD_MID_ANIM = Animation.create(3676); + + /** + * The building a decoration animation. + */ + public static final Animation BUILD_HIGH_ANIM = Animation.create(3684); + + /** + * The planting animation. + */ + public static final Animation PLANT_ANIM = Animation.create(3691); + + /** + * The removing a decoration animation. + */ + private static final Animation REMOVE_ANIMATION = Animation.create(3685); + + /** + * The plank item. + */ + public static final Item PLANK = new Item(Items.PLANK_960); + + /** + * The watering can(8) item id. + */ + public static final int WATERING_CAN = 5340; + + private static final int[] BUILD_INDEXES = { 0, 2, 4, 6, 1, 3, 5 }; + + /** + * Opens the building furniture interface. + * @param player The player. + * @param hotspot The hotspot. + */ + public static void openBuildInterface(Player player, BuildHotspot hotspot) { + player.getInterfaceManager().open(new Component(396)); + Item[] items = new Item[7]; + + int c261Value = 0; + + for (int menuIndex = 0; menuIndex < 7; menuIndex++) { + int itemsStringOffset = 97 + (menuIndex * 5); + + //97 + + if (menuIndex >= hotspot.getDecorations().length || (hotspot.getDecorations()[menuIndex] != null && hotspot.getDecorations()[menuIndex].isInvisibleNode())) { + for (int j = 0; j < 5; j++) { + player.getPacketDispatch().sendString("", 396, itemsStringOffset + j); + } + player.getPacketDispatch().sendString("", 396, 140 + menuIndex); + c261Value += (1 << (menuIndex + 1)); + continue; + } + + Decoration decoration = hotspot.getDecorations()[menuIndex]; + items[BUILD_INDEXES[menuIndex]] = new Item(decoration.getInterfaceItem()); + player.getPacketDispatch().sendString(ItemDefinition.forId(decoration.getInterfaceItem()).getName(), 396, itemsStringOffset); + boolean hasRequirements = player.getSkills().getLevel(Skills.CONSTRUCTION) >= decoration.getLevel(); + for (int j = 0; j < 4; j++) { + if (j >= decoration.getItems().length) { + if (j == decoration.getItems().length && decoration.getNailAmount() > 0) { + player.getPacketDispatch().sendString("Nails: " + decoration.getNailAmount(), 396, (itemsStringOffset + 1) + j); + } else { + player.getPacketDispatch().sendString("", 396, (itemsStringOffset + 1) + j); + } + } else { + Item item = decoration.getItems()[j]; + if (!player.getInventory().containsItem(item)) { + hasRequirements = false; + } + String s = item.getName() + ": " + item.getAmount(); + /*if (j > 1 && (decoration == Decoration.RUNE_CASE1 || decoration == Decoration.RUNE_CASE2)) { + if (j == 3) { + offset--; + item = decoration.getItems()[++j]; + s = item.getName() + ": " + item.getAmount(); + } + item = decoration.getItems()[j + 1]; + s += ", " + item.getName() + ": " + item.getAmount(); + player.getPacketDispatch().sendString(s, 396, 15 + offset + j); + continue; + }*/ + player.getPacketDispatch().sendString(s, 396, (itemsStringOffset + 1) + j); + } + } + if (hasRequirements) { + c261Value += (1 << (menuIndex + 1)); + } + setVarp(player, 1485 + menuIndex, hasRequirements || player.isStaff() ? 1 : 0); + player.getPacketDispatch().sendString("Level " + decoration.getLevel(), 396, 140 + menuIndex); + //player.getPacketDispatch().sendItemZoomOnInterface(items[i].protocol(), 50000, 396, 49 + i); + } + + setVarp(player, 261, c261Value); + PacketRepository.send(ContainerPacket.class, new ContainerContext(player, 396, 132, 8, items, false)); + } + + /** + * Checks if the object is a door hotspot. + * @param object The object. + * @return {@code True} if so. + */ + public static boolean isDoorHotspot(Scenery object) { + return object.getId() >= 15305 && object.getId() <= 15322; + } + + /** + * Builds a decoration object. + * @param player The player. + * @param deco The decoration. + * @param object The object. + */ + public static void buildDecoration(final Player player, final Hotspot hotspot, final Decoration deco, final Scenery object) { + final int nailAmount = deco.getNailAmount(); + final NailType type = nailAmount > 0 ? NailType.get(player, nailAmount) : null; + if (nailAmount > 0 && type == null) { + player.getPacketDispatch().sendMessage("You don't have the right materials."); + return; + } + int roomX = object.getLocation().getChunkX(); + int roomY = object.getLocation().getChunkY(); + int z = object.getLocation().getZ(); + Region region = player.getHouseManager().getHouseRegion(); + if (HouseManager.isInDungeon(player)) { + region = player.getHouseManager().getDungeonRegion(); + z = 3; + } + final Room room = player.getHouseManager().getRooms()[z][roomX][roomY]; + if (!canBuildDecoration(player, room, deco, object)) { + return; + } + player.lock(3); + player.animate(hotspot.getHotspot().getBuildingAnimation()); + final Region r = region; + player.getPulseManager().run(new Pulse(3, player, object) { + int nails = nailAmount; + NailType nail = type; + @Override + public boolean pulse() { + if (nails > 0) { + if (!type.isBend()) { + player.getPacketDispatch().sendMessage("You use a nail."); + nails--; + } else { + player.getPacketDispatch().sendMessage("You accidently bend a nail."); + } + player.animate(hotspot.getHotspot().getBuildingAnimation()); + if (!player.getInventory().remove(new Item(nail.getItemId(), 1))) { + return true; + } + if (nails > 0) { + player.lock(4); + return false; + } + } else if (deco.getTools()[0] == WATERING_CAN) { + for (int i = 7; i >= 0; i--) { + Item can = player.getInventory().getItem(new Item(WATERING_CAN - i, 1)); + if (can != null && can.getSlot() > -1) { + player.getInventory().replace(new Item(WATERING_CAN - (i == 7 ? i + 2 : i + 1), 1), can.getSlot()); + break; + } + } + } + if (player.getInventory().remove(deco.getItems()) || player.isAdmin()) { + setDecoration(player, r, room, hotspot, object, deco); + player.getSkills().addExperience(Skills.CONSTRUCTION, deco.getExperience(), true); + + if (getObjectIdsThatGiveFarmingExperience().contains(deco.getObjectId())) { + player.getSkills().addExperience(Skills.FARMING, deco.getExperience(), true); + } + player.unlock(); + } + return true; + } + + @NotNull + private ArrayList getObjectIdsThatGiveFarmingExperience() { + return new ArrayList<>( + // Garden big tree decorations. + Arrays.asList(13411, 13412, 13413, 13414, 13415, 13416, 13417, + // Garden tree decorations. + 13418, 13419, 13420, 13421, 13422, 13423, 13424, + // Garden big plant 1 decorations. + 13425, 13426, 13427, + // Garden big plant 2 decorations. + 13428, 13429, 13430, + // Garden small plant 1 decorations. + 13431, 13432, 13433, + // Garden small plant 2 decorations. + 13434, 13435, 13436)); + } + }); + } + + /** + * Sets a decoration for the given hotspot. + * @param player The player. + * @param region The region. + * @param room The room. + * @param hotspot The hotspot to set the decoration for. + * @param object The object representing the hotspot. + * @param deco The decoration to set. + */ + private static void setDecoration(Player player, Region region, Room room, Hotspot hotspot, Scenery object, Decoration deco) { + Location l = object.getLocation(); + HousingStyle style = player.getHouseManager().getStyle(); + int decIndex = hotspot.getHotspot().getDecorationIndex(deco); + switch(hotspot.getHotspot().getType()) { + case STAIRCASE: + int z = l.getZ(); + if (region == player.getHouseManager().getDungeonRegion()) { + z = 3; + } + for (int i = -1; i <= 1; i++) { + int plane = (z + (i == -1 ? 3 : i)) % 4; + Room r = player.getHouseManager().getRooms()[plane][l.getChunkX()][l.getChunkY()]; + if (r != null && r.getRotation() == room.getRotation() && !r.getProperties().isLand()) { + Hotspot h = r.getStairs(); + if (h != null) { + h.setDecorationIndex(decIndex); + Region reg = plane == 3 ? player.getHouseManager().getDungeonRegion() : player.getHouseManager().getHouseRegion(); + if (reg == null) { + continue; + } + BuildRegionChunk chunk = (BuildRegionChunk) reg.getPlanes()[plane % 3].getChunks()[l.getChunkX()][l.getChunkY()]; + Scenery[] objects = chunk.getObjects(h.getCurrentX(), h.getCurrentY()); + for (Scenery o : objects) { + if (o != null && o.getType() == object.getType()) { + SceneryBuilder.replace(o, o.transform(h.getHotspot().getDecorations()[decIndex].getObjectId(style))); + if (plane == 1) { + if (r.getProperties() == RoomProperties.SKILL_HALL) { + r.updateProperties(player, RoomProperties.SKILL_HALL_2); + } else if (r.getProperties() == RoomProperties.QUEST_HALL) { + r.updateProperties(player, RoomProperties.QUEST_HALL_2); + } + else { + break; + } + player.getHouseManager().reload(player, true); + } + break; + } + } + } else { + log(BuildingUtils.class, Log.ERR, "Couldn't find stairs! " + plane); + } + } + } + break; + case CREST: + SceneryBuilder.replace(object, object.transform(deco.getObjectId(style) + player.getHouseManager().getCrest().ordinal())); + hotspot.setDecorationIndex(decIndex); + break; + case INDIVIDUAL: + SceneryBuilder.replace(object, object.transform(deco.getObjectId(style))); + hotspot.setDecorationIndex(decIndex); + break; + case RECURSIVE: + BuildRegionChunk chunk = (BuildRegionChunk) region.getPlanes()[l.getZ()].getChunks()[l.getChunkX()][l.getChunkY()]; + for (int x = 0; x < 8; x++) { + for (int y = 0; y < 8; y++) { + Hotspot h = room.getHotspot(hotspot.getHotspot(), x, y); + if (h != null) { + h.setDecorationIndex(decIndex); + int objectId = hotspot.getHotspot().getObjectId(style); + Scenery o = chunk.get(x, y, chunk.getIndex(x, y, objectId)); + if (o != null && objectId == o.getId()) { + SceneryBuilder.replace(o, o.transform(hotspot.getHotspot().getDecorations()[decIndex].getObjectId(style))); + } + } + } + } + break; + case LINKED: + BuildHotspot[] linkedHotspots = BuildHotspot.getLinkedHotspots(hotspot.getHotspot()); + chunk = (BuildRegionChunk) region.getPlanes()[l.getZ()].getChunks()[l.getChunkX()][l.getChunkY()]; + for (int x = 0; x < 8; x++) { + for (int y = 0; y < 8; y++) { + for (BuildHotspot bh : linkedHotspots) { + Hotspot h = room.getHotspot(bh, x, y); + if (h != null) { + h.setDecorationIndex(decIndex); + int objectId = bh.getObjectId(style); + Scenery o = chunk.get(x, y, chunk.getIndex(x, y, objectId)); + if (o != null && objectId == o.getId()) { + SceneryBuilder.replace(o, o.transform(bh.getDecorations()[decIndex].getObjectId(style))); + } + } + } + } + } + break; + } + } + + /** + * Remove the decoration + * @param player the player + * @param object the object to remove + */ + public static void removeDecoration(Player player, Scenery object) { + if (object.getId() == Decoration.PORTAL.getObjectId() && player.getHouseManager().getPortalAmount() <= 1) { + sendMessage(player, "You need at least one portal, how else would you leave your house?"); + return; + } + Location l = object.getLocation(); + Room room = player.getHouseManager().getRooms()[l.getZ()][l.getChunkX()][l.getChunkY()]; + Region region = player.getHouseManager().getHouseRegion(); + if (HouseManager.isInDungeon(player)) { + region = player.getHouseManager().getDungeonRegion(); + room = player.getHouseManager().getRooms()[3][l.getChunkX()][l.getChunkY()]; + } + HousingStyle style = player.getHouseManager().getStyle(); + for (int i = 0; i < room.getHotspots().length; i++) { + Hotspot hotspot = room.getHotspots()[i]; + int objectId = hotspot.getDecorationIndex() < 0 ? -1 : hotspot.getHotspot().getDecorations()[hotspot.getDecorationIndex()].getObjectId(style); + if (hotspot.getHotspot().getType() == BuildHotspotType.CREST) { + objectId += player.getHouseManager().getCrest().ordinal(); + } + if (objectId == object.getId() && hotspot.getCurrentX() == l.getChunkOffsetX() && hotspot.getCurrentY() == l.getChunkOffsetY()) { + player.animate(REMOVE_ANIMATION); + removeDecoration(player, region, room, hotspot, object, style); + Decoration decoration = Decoration.forObjectId(object.getId()); + for (Item item : decoration.getRefundItems()) { + addItemOrDrop(player, item.getId(), item.getAmount()); + } + break; + } + } + } + + /** + * Removes the decoration. + * @param player The player. + * @param region The region. + * @param room The room. + * @param hotspot The hotspot to remove the decoration from. + * @param object The object. + * @param style The housing style. + */ + private static void removeDecoration(Player player, Region region, Room room, Hotspot hotspot, Scenery object, HousingStyle style) { + Location l = object.getLocation(); + switch (hotspot.getHotspot().getType()) { + case STAIRCASE: + int z = l.getZ(); + if (region == player.getHouseManager().getDungeonRegion()) { + z = 3; + } + for (int i = -1; i <= 1; i++) { + int plane = (z + (i == -1 ? 3 : i)) % 4; + Room r = player.getHouseManager().getRooms()[plane][l.getChunkX()][l.getChunkY()]; + if (r != null && r.getRotation() == room.getRotation()) { + Hotspot h = r.getStairs(); + if (h != null) { + h.setDecorationIndex(-1); + Region reg = plane == 3 ? player.getHouseManager().getDungeonRegion() : player.getHouseManager().getHouseRegion(); + if (reg == null) { + continue; + } + BuildRegionChunk chunk = (BuildRegionChunk) reg.getPlanes()[plane % 3].getChunks()[l.getChunkX()][l.getChunkY()]; + Scenery[] objects = chunk.getObjects(h.getCurrentX(), h.getCurrentY()); + for (Scenery o : objects) { + if (o != null && o.getType() == object.getType()) { + SceneryBuilder.replace(o, o.transform(h.getHotspot().getObjectId(style))); + break; + } + } + } else { + log(BuildingUtils.class, Log.ERR, "Couldn't find stairs! " + plane); + } + } + } + if (l.getZ() == 1) { + if (room.getProperties() == RoomProperties.SKILL_HALL_2) { + room.updateProperties(player, RoomProperties.SKILL_HALL); + } + else if (room.getProperties() == RoomProperties.QUEST_HALL_2) { + room.updateProperties(player, RoomProperties.QUEST_HALL); + } + else { + break; + } + player.getHouseManager().reload(player, true); + } + break; + case INDIVIDUAL: + case CREST: + SceneryBuilder.replace(object, object.transform(hotspot.getHotspot().getObjectId(style))); + hotspot.setDecorationIndex(-1); + break; + case RECURSIVE: + BuildRegionChunk chunk = (BuildRegionChunk) region.getPlanes()[l.getZ()].getChunks()[l.getChunkX()][l.getChunkY()]; + for (int x = 0; x < 8; x++) { + for (int y = 0; y < 8; y++) { + Hotspot h = room.getHotspot(hotspot.getHotspot(), x, y); + if (h != null) { + int objectId = hotspot.getHotspot().getDecorations()[h.getDecorationIndex()].getObjectId(style); + Scenery o = chunk.get(x, y, chunk.getIndex(x, y, objectId)); + h.setDecorationIndex(-1); + if (o != null && objectId == o.getId()) { + SceneryBuilder.replace(o, o.transform(hotspot.getHotspot().getObjectId(style))); + } + } + } + } + break; + case LINKED: + BuildHotspot[] linkedHotspots = BuildHotspot.getLinkedHotspots(hotspot.getHotspot()); + chunk = (BuildRegionChunk) region.getPlanes()[l.getZ()].getChunks()[l.getChunkX()][l.getChunkY()]; + for (int x = 0; x < 8; x++) { + for (int y = 0; y < 8; y++) { + for (BuildHotspot bh : linkedHotspots) { + Hotspot h = room.getHotspot(bh, x, y); + if (h != null) { + int objectId = bh.getDecorations()[h.getDecorationIndex()].getObjectId(style); + Scenery o = chunk.get(x, y, chunk.getIndex(x, y, objectId)); + h.setDecorationIndex(-1); + if (o != null && objectId == o.getId()) { + SceneryBuilder.replace(o, o.transform(bh.getObjectId(style))); + } + } + } + } + } + break; + } + } + + /** + * Checks if the decoration can be built. + * @param player The player. + * @param deco The decoration. + * @param object The object. + * @return {@code True} if so. + */ + private static boolean canBuildDecoration(Player player, Room room, Decoration deco, Scenery object) { + switch (deco) { + case TENTACLE_MID: + case TENTACLE_SIDE: + case TENTACLE_CORNER: + case TENTACLE_FL: + if (!room.isBuilt(BuildHotspot.PRISON)) { + player.getPacketDispatch().sendMessage("You can't build a tentacle pool without a cage."); + return false; + } + return true; + default: + return true; + } + } + + /** + * Checks if the decoration can be built. + * @param player The player. + * @param hotspot The hotspot. + * @param object The object. + * @return {@code True} if so. + */ + @SuppressWarnings("unused") + private static boolean setLinkedHotspot(Player player, Room room, Hotspot hotspot, int decorationIndex, Scenery object) { + Location l = object.getLocation(); + int z = l.getZ(); + switch (hotspot.getHotspot()) { + case STAIRWAYS: + case QUEST_STAIRWAYS: + case STAIRWAYS_DUNGEON: + BuildHotspot[] stairs = { BuildHotspot.STAIRS_DOWN, BuildHotspot.STAIRS_DOWN2, BuildHotspot.STAIRWAYS, BuildHotspot.QUEST_STAIRWAYS, BuildHotspot.STAIRWAYS_DUNGEON }; + for (int i = 0; i < 2; i++) { + int plane = (z + 1 + (i * 2)) % 4; + Room r = player.getHouseManager().getRooms()[plane][l.getChunkX()][l.getChunkY()]; + if (r != null) { + for (BuildHotspot h : stairs) { + Hotspot hs = r.getHotspot(h, hotspot.getCurrentX(), hotspot.getCurrentY()); + if (hs != null) { + hs.setDecorationIndex(decorationIndex); + SceneryBuilder.replace(object, object.transform(h.getDecorations()[decorationIndex].getObjectId(player.getHouseManager().getStyle()))); + break; + } + } + } + } + return true; + default: + return true; + } + } + + /** + * Builds a room. + * @param player The player. + * @param room The room to build. + * @param reload + */ + public static void buildRoom(Player player, Room room, int z, int x, int y, boolean[] exits, boolean reload) { + player.getHouseManager().getRooms()[z][x][y] = room; + player.getPacketDispatch().sendMessage("Building room " + room.getProperties() + "."); + if (z == 3) { + player.getHouseManager().setHasDungeon(true); + } + if (room.getProperties().isChamber() && z < 2) { + int count = 0; + int index = 0; + for (int i = 0; i < exits.length; i++) { + if (exits[i]) { + count++; + } else { + index = i; + } + } + //(0=east, 1=south, 2=west, 3=north). + + if (count == 4) { + room = Room.create(player, RoomProperties.ROOF_4_EXIT); + } + else if (count == 3) { + room = Room.create(player, RoomProperties.ROOF_3_EXIT); + } + else if ((exits[0] != exits[2]) || (exits[1] != exits[3])) { + room = Room.create(player, RoomProperties.ROOF_3_EXIT); + } else { + room = Room.create(player, RoomProperties.ROOF_2_EXIT); + } + player.getHouseManager().getRooms()[z + 1][x][y] = room; + } + if (reload) { + player.getHouseManager().reload(player, true); + } + } + + /** + * Checks of a room exists. + * @param player the player + * @param door the door hotspot the player is trying to build at + * @return true if the room is built already + */ + public static int[] roomExists(Player player, Scenery door) { + int[] location = getRoomPosition(player, door); + int z = player.getLocation().getZ(); + if (HouseManager.isInDungeon(player)) { + z = 3; + } + if (player.getHouseManager().hasRoomAt(z, location[0], location[1])) { + return location; + } + return null; + } + + /** + * Gets the room offset. + * @param door The door. + * @return The room offset [x, y]. + */ + public static int[] getRoomPosition(Player player, Scenery door) { + Location l = door.getLocation(); + int rotation = door.getRotation(); + if (player.getLocation().getChunkX() != l.getLocation().getChunkX() + || player.getLocation().getChunkY() != l.getLocation().getChunkY()) { + return new int[] { l.getChunkX(), l.getChunkY() }; + } + switch (rotation) { + case 0: //West + return new int[] { l.getChunkX() - 1, l.getChunkY() }; + case 1: //North + return new int[] { l.getChunkX(), l.getChunkY() + 1}; + case 2: //East + return new int[] { l.getChunkX() + 1, l.getChunkY() }; + case 3: //South + return new int[] { l.getChunkX(), l.getChunkY() - 1}; + } + return null; + } + + /** + * Gets the available rotations of the room to build. + * @param exits The exits of the room. + * @param z The plane + * @param roomX The room x-coordinate. + * @param roomY The room y-coordinate. + * @return The available rotations for the room [NORTH, EAST, SOUTH, WEST]. + */ + public static Direction[] getAvailableRotations(Player player, boolean[] exits, int z, int roomX, int roomY) { + Direction[] directions = new Direction[4]; + boolean[] exit = Arrays.copyOf(exits, exits.length); //(0=east, 1=south, 2=west, 3=north) + int[] info = getExitRequirements(player, z, roomX, roomY);//(0=west, 1=north, 2=east, 3=south) + // SystemLogger.logErr(BuildingUtils.class, "Available exits - [east=" + exit[0] + ", south=" + exit[1] + ", west=" + exit[2] + ", north=" + exit[3] + "]!"); + // SystemLogger.logErr(BuildingUtils.class, "Required exits - [east=" + info[0] + ", south=" + info[1] + ", west=" + info[2] + ", north=" + info[3] + "]!"); + for (int i = 0; i < 4; i++) { + boolean success = true; + for (int j = 0; j < 4; j++) { + if ((info[j] == 1 && !exit[j]) || (info[j] == -1 && exit[j])) { + success = false; + break; + } + } + if (success) { + directions[i] = DIRECTIONS[i]; + } + for (int j = 0; j < exit.length; j++) { + exit[(j + i + 1) % exit.length] = exits[j]; + } + } + return directions; + } + + /** + * Gets the exit requirements for the given room. + * @param roomX The room x-coordinate. + * @param roomY The room y-coordinate. + * @return The requirements on the exit indexes. -1 if exit must be absent, +1 if exit must be present. + */ + private static int[] getExitRequirements(Player player, int z, int roomX, int roomY) { + int[] exits = new int[4]; + int deltaX = roomX - player.getLocation().getChunkX(); + int deltaY = roomY - player.getLocation().getChunkY(); + if (deltaX > 0) { + // player is to our west + exits[2] = 1; + } else if (deltaX < 0) { + // player is to our east + exits[0] = 1; + } else if (deltaY > 0) { + // player is to our south + exits[1] = 1; + } else if (deltaY < 0) { + // player is to our north + exits[3] = 1; + } + return exits; + } +} diff --git a/Server/src/main/content/global/skill/construction/ConstructionGuideBook.kt b/Server/src/main/content/global/skill/construction/ConstructionGuideBook.kt new file mode 100644 index 0000000..a6c8bee --- /dev/null +++ b/Server/src/main/content/global/skill/construction/ConstructionGuideBook.kt @@ -0,0 +1,68 @@ +package content.global.skill.construction + +import core.api.sendMessage +import core.game.dialogue.DialogueInterpreter +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.item.Item +import core.game.world.GameWorld.settings +import org.rs09.consts.Items + +/** + * Construction Guide Book + * Used to be book:conguide? + * @author ovenbreado + * @author Emperor + */ + +class ConstructionGuideBook : InteractionListener { + companion object { + private val TITLE = "Construction guide book" + /** The resources used in beta. */ + private val RESOURCES = arrayOf( + Item(Items.SAW_8794), + Item(Items.HAMMER_2347), + Item(Items.BRONZE_NAILS_4819, 500000), + Item(Items.IRON_NAILS_4820, 500000), + Item(Items.STEEL_NAILS_1539, 500000), + Item(Items.BLACK_NAILS_4821, 500000), + Item(Items.MITHRIL_NAILS_4822, 500000), + Item(Items.ADAMANTITE_NAILS_4823, 500000), + Item(Items.RUNE_NAILS_4824, 500000), + Item(Items.PLANK_961, 500000), + Item(Items.OAK_PLANK_8779, 500000), + Item(Items.TEAK_PLANK_8781, 500000), + Item(Items.MAHOGANY_PLANK_8783, 500000), + Item(Items.BOLT_OF_CLOTH_8791, 500000), + Item(Items.GOLD_LEAF_8785, 500000), + Item(Items.MARBLE_BLOCK_8787, 500000), + Item(Items.MAGIC_STONE_8789, 500000), // 16 + Item(Items.BAGGED_DEAD_TREE_8418, 500000), + Item(Items.BAGGED_NICE_TREE_8420, 500000), + Item(Items.BAGGED_OAK_TREE_8422, 500000), + Item(Items.BAGGED_WILLOW_TREE_8424, 500000), + Item(Items.BAGGED_MAPLE_TREE_8426, 500000), + Item(Items.BAGGED_YEW_TREE_8428, 500000), + Item(Items.BAGGED_MAGIC_TREE_8430, 500000), + Item(Items.BAGGED_PLANT_1_8432, 500000), + Item(Items.BAGGED_PLANT_2_8434, 500000), + Item(Items.BAGGED_PLANT_3_8436, 500000) + ) + } + + override fun defineListeners() { + // There is supposedly a book here. + on(Items.CONSTRUCTION_GUIDE_8463, IntType.ITEM, "read") { player, _ -> + if (settings!!.isDevMode && settings!!.isBeta) { + for (item in RESOURCES) { + if (!player.inventory.contains(item.id, item.amount)) { + player.inventory.add(item, player) + } + } + } + sendMessage(player, "Upon reading the book you discover you're supposed to use these resources to test out construction. Report all bugs on the forums.") + return@on true + } + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/ConstructionInterface.java b/Server/src/main/content/global/skill/construction/ConstructionInterface.java new file mode 100644 index 0000000..a36b032 --- /dev/null +++ b/Server/src/main/content/global/skill/construction/ConstructionInterface.java @@ -0,0 +1,120 @@ +package content.global.skill.construction; + + +import core.cache.def.impl.ItemDefinition; +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.node.entity.player.Player; +import core.game.node.entity.skill.Skills; +import core.game.node.scenery.Scenery; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.tools.Log; +import core.tools.SystemLogger; + +import static core.api.ContentAPIKt.log; + +/** + * Handles the creating of a decoration object. + * @author Emperor + * + */ +@Initializable +public final class ConstructionInterface extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) { + ComponentDefinition.put(396, this); + ComponentDefinition.put(398, this); + ComponentDefinition.put(402, this); + return this; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + switch (component.getId()) { + case 396: + switch (button) { + case 132: + player.getInterfaceManager().close(); + Hotspot hotspot = player.getAttribute("con:hotspot"); + Scenery object = player.getAttribute("con:hsobject"); + if (hotspot == null || object == null) { + log(this.getClass(), Log.ERR, "Failed building decoration " + hotspot + " : " + object); + break; + } + slot = ((slot % 2 != 0) ? 4 : 0) + (slot >> 1); + if (slot >= hotspot.getHotspot().getDecorations().length) { + log(this.getClass(), Log.ERR, "Failed building decoration " + slot + "/" + hotspot.getHotspot().getDecorations().length); + break; + } + boolean debug = player.isStaff(); + Decoration deco = hotspot.getHotspot().getDecorations()[slot]; + if (!debug) { + if (player.getSkills().getLevel(Skills.CONSTRUCTION) < deco.getLevel()) { + player.sendMessage("You need to have a Construction level of " + deco.getLevel() + " to build that."); + return true; + } + if (!player.getInventory().containsItems(deco.getItems())) { + player.sendMessage("You don't have the right materials."); + return true; + } + for (int tool : deco.getTools()) { + if (tool == BuildingUtils.WATERING_CAN) { + boolean hasWateringCan = false; + for (int i = 0; i < 8; i++) { + if (player.getInventory().contains(tool - i, 1)) { + hasWateringCan = true; + break; + } + } + if (!hasWateringCan) { + player.sendMessage("You need a watering can to plant this."); + return true; + } + continue; + } + if (!player.getInventory().contains(tool, 1)) { + player.sendMessage("You need a " + ItemDefinition.forId(tool).getName() + " to build this."); + return true; + } + } + } + BuildingUtils.buildDecoration(player, hotspot, deco, object); + return true; + } + break; + case 398: + switch (button) { + case 14: + player.getHouseManager().toggleBuildingMode(player, true); + return true; + case 1: + player.getHouseManager().toggleBuildingMode(player, false); + return true; + case 15: + player.getHouseManager().expelGuests(player); + return true; + case 13: + if (!player.getHouseManager().isInHouse(player)) { + player.sendMessage("You can't do this outside of your house."); + return true; + } + HouseManager.leave(player); + return true; + } + break; + case 402: + int index = button - 160; + log(this.getClass(), Log.FINE, "BuildRoom Interface Index: " + index); + if (index > -1 && index < RoomProperties.values().length) { + player.getDialogueInterpreter().open("con:room", RoomProperties.values()[index]); + return true; + } + break; + } + return false; + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/CrestType.java b/Server/src/main/content/global/skill/construction/CrestType.java new file mode 100644 index 0000000..277c772 --- /dev/null +++ b/Server/src/main/content/global/skill/construction/CrestType.java @@ -0,0 +1,117 @@ +package content.global.skill.construction; + +import core.game.node.entity.player.Player; +import org.rs09.consts.Items; +import core.game.node.entity.skill.Skills; +import content.data.Quests; + +/** + * Family crest types. + * + * @author Emperor + * >ORDINAL BOUND< + */ +public enum CrestType implements CrestRequirement { + + ARRAV("the Shield of Arrav symbol") { // requires Shield of Arrav + + @Override + public boolean eligible(Player player) { + return player.getQuestRepository().isComplete(Quests.SHIELD_OF_ARRAV); + } + }, + ASGARNIA("the symbol of Asgarnia"), // no requirements + DORGESHUUN("the Dorgeshuun brooch") { // requires The Lost Tribe + + @Override + public boolean eligible(Player player) { + return player.getQuestRepository().isComplete(Quests.THE_LOST_TRIBE); + } + }, + DRAGON("a dragon") { // requires Dragon Slayer + + @Override + public boolean eligible(Player player) { + return player.getQuestRepository().isComplete(Quests.DRAGON_SLAYER); + } + }, + FAIRY("a fairy") { // requries Lost City + + @Override + public boolean eligible(Player player) { + return player.getQuestRepository().isComplete(Quests.LOST_CITY); + } + }, + GUTHIX("the symbol of Guthix") { // Requires 70+ Prayer + + @Override + public boolean eligible(Player player) { + return player.getSkills().hasLevel(Skills.PRAYER, 70); + } + }, + HAM("the symbol of the HAM cult."), // no requirements + HORSE("a horse") { // requires Toy Horsey in inventory + + @Override + public boolean eligible(Player player) { + return player.getInventory().containsAtLeastOneItem(new int[]{ + Items.TOY_HORSEY_2524, + Items.TOY_HORSEY_2520, + Items.TOY_HORSEY_2526, + Items.TOY_HORSEY_2522 + }); + } + }, + JOGRE("Jiggig"), // no requirements + KANDARIN("the symbol of Kandarin"), // no requirements + MISTHALIN("the symbol of Misthalin"), // no requirements + MONEY("a bag of money", 500000), // Costs 500k + SARADOMIN("the symbol of Saradomin") { // Requires 70+ Prayer + + @Override + public boolean eligible(Player player) { + return player.getSkills().hasLevel(Skills.PRAYER, 70); + } + }, + SKULL("a skull") { // requires Skulled while talking to Herald + + @Override + public boolean eligible(Player player) { + return player.getSkullManager().isSkulled(); + } + }, + VARROCK("the symbol of Varrock"), // no requirements + ZAMORAK("the symbol of Zamorak") { // Requires 70+ Prayer + + @Override + public boolean eligible(Player player) { + return player.getSkills().hasLevel(Skills.PRAYER, 70); + } + }; + + private String name; + private int cost; + + CrestType(String name, int cost) { + this.name = name; + this.cost = cost; + } + + CrestType(String name) { + this(name, 5000); + } + + public String getName() { + return this.name; + } + + public int getCost() { + return this.cost; + } +} + +interface CrestRequirement { + default boolean eligible(Player player) { + return true; + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/Decoration.java b/Server/src/main/content/global/skill/construction/Decoration.java new file mode 100644 index 0000000..6229dff --- /dev/null +++ b/Server/src/main/content/global/skill/construction/Decoration.java @@ -0,0 +1,1003 @@ +package content.global.skill.construction; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.world.map.Location; +import org.rs09.consts.Items; + +/** + * Represents the decorations. + * @author Emperor, Player Name + * + */ +public enum Decoration { + /** + * Garden centrepiece decorations. + */ + PORTAL (13405, 8168, 1, 100, new Item[] { new Item(Items.IRON_BAR_2351, 10) }), + ROCK (13406, 8169, 5, 100, new Item[] { new Item(Items.LIMESTONE_BRICK_3420, 5) }), + POND (13407, 8170, 10, 100, new Item[] { new Item(Items.SOFT_CLAY_1761, 10) }), + IMP_STATUE (13408, 8171, 15, 150, new Item[] { new Item(Items.LIMESTONE_BRICK_3420, 5), new Item(Items.SOFT_CLAY_1761, 5) }), + SMALL_OBELISK (42004, 14657, 41, 676, new Item[] { new Item(Items.MARBLE_BLOCK_8786), new Item(Items.SPIRIT_SHARDS_12183, 1000), new Item(Items.CRIMSON_CHARM_12160, 10), new Item(Items.BLUE_CHARM_12163, 10) }), + DUNGEON_ENTRANCE(13409, 8172, 70, 500, new Item[] { new Item(Items.MARBLE_BLOCK_8786) }), + + /** + * Garden big tree decorations. + */ + BIG_DEAD_TREE (13411, 8173, 5, 31, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_DEAD_TREE_8417) }), + BIG_TREE (13412, 8174, 10, 44, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_NICE_TREE_8419) }), + BIG_OAK_TREE (13413, 8175, 15, 70, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_OAK_TREE_8421) }), + BIG_WILLOW_TREE(13414, 8176, 30, 100, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_WILLOW_TREE_8423) }), + BIG_MAPLE_TREE (13415, 8177, 45, 122, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_MAPLE_TREE_8425) }), + BIG_YEW_TREE (13416, 8178, 60, 141, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_YEW_TREE_8427) }), + BIG_MAGIC_TREE (13417, 8179, 75, 223, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_MAGIC_TREE_8429) }), + + /** + * Garden tree decorations. + */ + DEAD_TREE (13418, 8173, 5, 31, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_DEAD_TREE_8417) }), + TREE (13419, 8174, 10, 44, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_NICE_TREE_8419) }), + OAK_TREE (13420, 8175, 15, 70, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_OAK_TREE_8421) }), + WILLOW_TREE(13421, 8176, 30, 100, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_WILLOW_TREE_8423) }), + MAPLE_TREE (13423, 8177, 45, 122, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_MAPLE_TREE_8425) }), + YEW_TREE (13422, 8178, 60, 141, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_YEW_TREE_8427) }), + MAGIC_TREE (13424, 8179, 75, 223, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_MAGIC_TREE_8429) }), + + /** + * Garden big plant 1 decorations. + */ + FERN (13425, 8186, 1, 31, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_PLANT_1_8431) }), + BUSH (13426, 8187, 6, 70, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_PLANT_2_8433) }), + TALL_PLANT(13427, 8188, 12, 100, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_PLANT_3_8435) }), + + /** + * Garden big plant 2 decorations. + */ + SHORT_PLANT (13428, 8189, 1, 31, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_PLANT_1_8431) }), + LARGE_LEAF_PLANT(13429, 8190, 6, 70, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_PLANT_2_8433) }), + HUGE_PLANT (13430, 8191, 12, 100, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_PLANT_3_8435) }), + + /** + * Garden small plant 1 decorations. + */ + PLANT (13431, 8180, 1, 31, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_PLANT_1_8431) }), + SMALL_FERN(13432, 8181, 6, 70, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_PLANT_2_8433) }), + FERN_SP (13433, 8182, 12, 100, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_PLANT_3_8435) }), + + /** + * Garden small plant 2 decorations. + */ + DOCK_LEAF(13434, 8183, 1, 31, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_PLANT_1_8431) }), + THISTLE (13435, 8184, 6, 70, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_PLANT_2_8433) }), + REEDS (13436, 8185, 12, 100, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_PLANT_3_8435) }), + + /** + * Parlour chair spot + */ + CRUDE_CHAIR (13581, 8309, 1, 58, new Item[] { new Item(Items.PLANK_960, 2) }), + WOODEN_CHAIR (13582, 8310, 8, 87, new Item[] { new Item(Items.PLANK_960, 3) }), + ROCKING_CHAIR (13583, 8311, 14, 87, new Item[] { new Item(Items.PLANK_960, 3) }), + OAK_CHAIR (13584, 8312, 19, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + OAK_ARMCHAIR (13585, 8313, 26, 180, new Item[] { new Item(Items.OAK_PLANK_8778, 3) }), + TEAK_ARMCHAIR (13586, 8314, 35, 180, new Item[] { new Item(Items.TEAK_PLANK_8780, 2) }), + MAHOGANY_ARMCHAIR(13587, 8315, 50, 280, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2) }), + + /** + * Rugs rugs rugs + */ + BROWN_RUG_CORNER (13588, 8316, 2, 30, new Item[] { new Item(Items.BOLT_OF_CLOTH_8790, 2) }), + RED_RUG_CORNER (13591, 8317, 13, 60, new Item[] { new Item(Items.BOLT_OF_CLOTH_8790, 4) }), + OPULENT_RUG_CORNER(13594, 8318, 65, 360, new Item[] { new Item(Items.BOLT_OF_CLOTH_8790, 4), new Item(Items.GOLD_LEAF_8784) }), + BROWN_RUG_END (13589, 8316, 2, 30, new Item[] { new Item(Items.BOLT_OF_CLOTH_8790, 2) }), + RED_RUG_END (13592, 8317, 13, 60, new Item[] { new Item(Items.BOLT_OF_CLOTH_8790, 4) }), + OPULENT_RUG_END (13595, 8318, 65, 360, new Item[] { new Item(Items.BOLT_OF_CLOTH_8790, 4), new Item(Items.GOLD_LEAF_8784) }), + BROWN_RUG_CENTER (13590, 8316, 2, 30, new Item[] { new Item(Items.BOLT_OF_CLOTH_8790, 2) }), + RED_RUG_CENTER (13593, 8317, 13, 60, new Item[] { new Item(Items.BOLT_OF_CLOTH_8790, 4) }), + OPULENT_RUG_CENTER(13596, 8318, 65, 360, new Item[] { new Item(Items.BOLT_OF_CLOTH_8790, 4), new Item(Items.GOLD_LEAF_8784) }), + + /** + * Parlour fireplaces + */ + CLAY_FIREPLACE (13609, 8325, 3, 30, new Item[] { new Item(Items.SOFT_CLAY_1761, 3) }), + STONE_FIREPLACE (13611, 8326, 33, 40, new Item[] { new Item(Items.LIMESTONE_BRICK_3420, 2) }), + MARBLE_FIREPLACE(13613, 8327, 63, 500, new Item[] { new Item(Items.MARBLE_BLOCK_8786) }), + + /** + * Parlour curtain spot + */ + TORN_CURTAINS (13603, 8322, 2, 132, new Item[] { new Item(Items.PLANK_960, 3), new Item(Items.BOLT_OF_CLOTH_8790, 3) }), + CURTAINS (13604, 8323, 18, 225, new Item[] { new Item(Items.OAK_PLANK_8778, 3), new Item(Items.BOLT_OF_CLOTH_8790, 3) }), + OPULENT_CURTAINS(13605, 8324, 40, 315, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.BOLT_OF_CLOTH_8790, 3) }), + + /** + * Bookcases + */ + WOODEN_BOOKCASE (13597, 8319, 4, 115, new Item[] { new Item(Items.PLANK_960, 4) }), + OAK_BOOKCASE (13598, 8320, 29, 180, new Item[] { new Item(Items.OAK_PLANK_8778, 3) }), + MAHOGANY_BOOKCASE(13599, 8321, 40, 420, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 3) }), + + /** + * Kitchen Beer Barrels + * TODO: These also require cooking levels! + * Basic: 1, Cider: 14, Asgarnian: 24, Greenman's: 29, D.Bitter: 39, Chef's: 54 + * + */ + BASIC_BEER_BARREL (13568, 8239, 7, 87, new Item[] { new Item(Items.PLANK_960, 3) }), + CIDER_BARREL (13569, 8240, 12, 91, new Item[] { new Item(Items.PLANK_960, 3), new Item(Items.CIDER_5763, 8) }), + ASGARNIAN_ALE_BARREL(13570, 8241, 18, 184, new Item[] { new Item(Items.OAK_PLANK_8778, 3), new Item(Items.ASGARNIAN_ALE_1905, 8) }), + GREENMANS_ALE_BARREL(13571, 8242, 26, 184, new Item[] { new Item(Items.OAK_PLANK_8778, 3), new Item(Items.GREENMANS_ALE_1909, 8) }), + DRAGON_BITTER_BARREL(13572, 8243, 36, 224, new Item[] { new Item(Items.OAK_PLANK_8778, 3), new Item(Items.DRAGON_BITTER_1911, 8), new Item(Items.STEEL_BAR_2353, 2) }), + CHEFS_DELIGHT_BARREL(13573, 8244, 48, 224, new Item[] { new Item(Items.OAK_PLANK_8778, 3), new Item(Items.CHEFS_DELIGHT_5755, 8), new Item(Items.STEEL_BAR_2353, 2) }), + + /** + * Kitchen Tables! + */ + KITCHEN_WOODEN_TABLE(13577, 8246, 12, 87, new Item[] { new Item(Items.PLANK_960, 3) }), + KITCHEN_OAK_TABLE (13578, 8247, 32, 180, new Item[] { new Item(Items.OAK_PLANK_8778, 3) }), + KITCHEN_TEAK_TABLE (13579, 8248, 52, 270, new Item[] { new Item(Items.TEAK_PLANK_8780, 3) }), + + /** + * Kitchen Stoves + */ + BASIC_FIREPIT (13528, 8216, 5, 40, new Item[] { new Item(Items.SOFT_CLAY_1761, 2), new Item(Items.STEEL_BAR_2353) }), + FIREPIT_WITH_HOOK(13529, 8217, 11, 60, new Item[] { new Item(Items.SOFT_CLAY_1761, 2), new Item(Items.STEEL_BAR_2353, 2) }), + FIREPIT_WITH_POT (13531, 8218, 17, 80, new Item[] { new Item(Items.SOFT_CLAY_1761, 2), new Item(Items.STEEL_BAR_2353, 3) }), + SMALL_OVEN (13533, 8219, 24, 80, new Item[] { new Item(Items.STEEL_BAR_2353, 4) }), + LARGE_OVEN (13536, 8220, 29, 100, new Item[] { new Item(Items.STEEL_BAR_2353, 5) }), + BASIC_RANGE (13539, 8221, 34, 120, new Item[] { new Item(Items.STEEL_BAR_2353, 6) }), + FANCY_RANGE (13542, 8222, 42, 160, new Item[] { new Item(Items.STEEL_BAR_2353, 8) }), + + /** + * Kitchen larders + */ + WOODEN_LARDER(13565, 8233, 9, 228, new Item[] { new Item(Items.PLANK_960, 8) }), + OAK_LARDER (13566, 8234, 33, 480, new Item[] { new Item(Items.OAK_PLANK_8778, 8) }), + TEAK_LARDER (13567, 8235, 43, 750, new Item[] { new Item(Items.TEAK_PLANK_8780, 8), new Item(Items.BOLT_OF_CLOTH_8790, 2) }), + + /** + * Kitchen shelves + */ + WOODEN_SHELVES_1(13545, 8223, 6, 87, new Item[] { new Item(Items.PLANK_960, 3) }), + WOODEN_SHELVES_2(13546, 8224, 12, 147, new Item[] { new Item(Items.PLANK_960, 3), new Item(Items.SOFT_CLAY_1761, 6) }), + WOODEN_SHELVES_3(13547, 8225, 23, 147, new Item[] { new Item(Items.PLANK_960, 3), new Item(Items.SOFT_CLAY_1761, 6) }), + OAK_SHELVES_1 (13548, 8226, 34, 240, new Item[] { new Item(Items.OAK_PLANK_8778, 3), new Item(Items.SOFT_CLAY_1761, 6) }), + OAK_SHELVES_2 (13549, 8227, 45, 240, new Item[] { new Item(Items.OAK_PLANK_8778, 3), new Item(Items.SOFT_CLAY_1761, 6) }), + TEAK_SHELVES_1 (13550, 8228, 56, 330, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.SOFT_CLAY_1761, 6) }), + TEAK_SHELVES_2 (13551, 8229, 67, 930, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.SOFT_CLAY_1761, 6), new Item(Items.GOLD_LEAF_8784, 2) }), + + /** + * Kitchen sinks + */ + PUMP_AND_DRAIN(13559, 8230, 7, 100, new Item[] { new Item(Items.STEEL_BAR_2353, 5) }), + PUMP_AND_TUB (13561, 8231, 27, 200, new Item[] { new Item(Items.STEEL_BAR_2353, 10) }), + SINK (13563, 8232, 47, 300, new Item[] { new Item(Items.STEEL_BAR_2353, 15) }), + + /** + * Kitchen cat baskets/blankets + */ + CAT_BLANKET (13574, 8236, 5, 15, new Item[] { new Item(Items.BOLT_OF_CLOTH_8790) }), + CAT_BASKET (13575, 8237, 19, 58, new Item[] { new Item(Items.PLANK_960, 2) }), + CAST_BASKET_CUSHIONED(13576, 8238, 33, 58, new Item[] { new Item(Items.PLANK_960, 2), new Item(Items.WOOL_1737, 2) }), + + /** + * Dining room tables + */ + DINING_TABLE_WOOD (13293, 8246, 10, 115, new Item[] { new Item(Items.PLANK_960, 4) }), + DINING_TABLE_OAK (13294, 8247, 22, 240, new Item[] { new Item(Items.OAK_PLANK_8778, 4) }), + DINING_TABLE_CARVED_OAK (13295, 8247, 31, 360, new Item[] { new Item(Items.OAK_PLANK_8778, 6) }), + DINING_TABLE_TEAK (13296, 8248, 38, 360, new Item[] { new Item(Items.TEAK_PLANK_8780, 4) }), + DINING_TABLE_CARVED_TEAK(13297, 8248, 45, 600, new Item[] { new Item(Items.TEAK_PLANK_8780, 6), new Item(Items.BOLT_OF_CLOTH_8790, 4) }), + DINING_TABLE_MAHOGANY (13298, 8120, 52, 840, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 6) }), + DINING_TABLE_OPULENT (13299, 8121, 72, 3100, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 6), new Item(Items.BOLT_OF_CLOTH_8790, 4), new Item(Items.GOLD_LEAF_8784, 4), new Item(Items.MARBLE_BLOCK_8786, 2) }), + + /** + * Dining room benches + */ + BENCH_WOODEN (13300, 8108, 10, 115, new Item[] { new Item(Items.PLANK_960, 4) }), + BENCH_OAK (13301, 8109, 22, 240, new Item[] { new Item(Items.OAK_PLANK_8778, 4) }), + BENCH_CARVED_OAK (13302, 8110, 31, 240, new Item[] { new Item(Items.OAK_PLANK_8778, 4) }), + BENCH_TEAK (13303, 8111, 38, 360, new Item[] { new Item(Items.TEAK_PLANK_8780, 4) }), + BENCH_CARVED_TEAK(13304, 8112, 44, 360, new Item[] { new Item(Items.TEAK_PLANK_8780, 4) }), + BENCH_MAHOGANY (13305, 8113, 52, 560, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 6) }), + BENCH_GILDED (13306, 8114, 61, 1760, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 4), new Item(Items.GOLD_LEAF_8784, 4) }), + + /** + * Dining room bell-pulls + */ + ROPE_PULL (13307, 8099, 5, 15, new Item[] { new Item(Items.ROPE_954), new Item(Items.OAK_PLANK_8778) }), + BELL_PULL (13308, 8100, 19, 58, new Item[] { new Item(Items.TEAK_PLANK_8780), new Item(Items.BOLT_OF_CLOTH_8790, 2) }), + FANCY_BELL_PULL(13309, 8101, 33, 58, new Item[] { new Item(Items.TEAK_PLANK_8780), new Item(Items.BOLT_OF_CLOTH_8790, 2), new Item(Items.GOLD_LEAF_8784) }), + + /** + * Workshop workbench + */ + WORKBENCH_WOODEN (13704, 8375, 17, 143, new Item[] { new Item(Items.PLANK_960, 5) }), + WORKBENCH_OAK (13705, 8376, 32, 300, new Item[] { new Item(Items.OAK_PLANK_8778, 5) }), + WORKBENCH_STEEL_FRAME(13706, 8377, 46, 440, new Item[] { new Item(Items.OAK_PLANK_8778, 6), new Item(Items.STEEL_BAR_2353, 4) }), + WORKBENCH_WITH_VICE (13707, 8378, 62, 750, new Item[] { new Item(Items.STEEL_FRAMED_BENCH_8377), new Item(Items.OAK_PLANK_8778, 2), new Item(Items.STEEL_BAR_2353) }), + WORKBENCH_WITH_LATHE (13708, 8379, 77, 1000, new Item[] { new Item(Items.OAK_WORKBENCH_8376), new Item(Items.OAK_PLANK_8778, 2), new Item(Items.STEEL_BAR_2353) }), + + /** + * Workshop repair benches/stands + */ + REPAIR_BENCH(13713, 8389, 15, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + WHETSTONE (13714, 8390, 35, 260, new Item[] { new Item(Items.OAK_PLANK_8778, 4), new Item(Items.LIMESTONE_BRICK_3420) }), + ARMOUR_STAND(13715, 8391, 55, 500, new Item[] { new Item(Items.OAK_PLANK_8778, 8), new Item(Items.LIMESTONE_BRICK_3420) }), + + /** + * Workshop easels + */ + PLUMING_STAND(13716, 8392, 16, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + SHIELD_EASEL (13717, 8393, 41, 240, new Item[] { new Item(Items.OAK_PLANK_8778, 4) }), + BANNER_EASEL (13718, 8394, 66, 510, new Item[] { new Item(Items.OAK_PLANK_8778, 8), new Item(Items.BOLT_OF_CLOTH_8790, 2) }), + + /** + * Workshop crafting tables + * TODO: These are upgradable hotspots, therefore crafting table 3 would require + * crafting table 2 to be already built in that spot. + */ + CRAFTING_TABLE_1(13709, 8380, 16, 240, new Item[] { new Item(Items.OAK_PLANK_8778, 4) }), + CRAFTING_TABLE_2(13710, 8381, 25, 1, new Item[] { new Item(Items.MOLTEN_GLASS_1775) }), + CRAFTING_TABLE_3(13711, 8382, 34, 2, new Item[] { new Item(Items.MOLTEN_GLASS_1775, 2) }), + CRAFTING_TABLE_4(13712, 8383, 42, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + + /** + * Workshop tool stores + * These are also upgradable just like the tables above. + */ + TOOL_STORE_1(13699, 8384, 15, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + TOOL_STORE_2(13700, 8385, 25, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + TOOL_STORE_3(13701, 8386, 35, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + TOOL_STORE_4(13702, 8387, 44, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + TOOL_STORE_5(13703, 8388, 55, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + + /** + * Wall-mounted decorations + */ + OAK_DECORATION (13606, 8102, 16, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + TEAK_DECORATION (13606, 8103, 36, 180, new Item[] { new Item(Items.TEAK_PLANK_8780, 2) }), + GILDED_DECORATION(13607, 8104, 56, 1020, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 3), new Item(Items.GOLD_LEAF_8784, 2) }), + + /** + * Staircases. + */ + OAK_STAIRCASE (13497, 8249, 27, 680, new Item[] { new Item(Items.OAK_PLANK_8778, 10), new Item(Items.STEEL_BAR_2353, 4) }), + TEAK_STAIRCASE (13499, 8252, 48, 980, new Item[] { new Item(Items.TEAK_PLANK_8780, 10), new Item(Items.STEEL_BAR_2353, 4) }), + SPIRAL_STAIRCASE(13503, 8258, 67, 1040, new Item[] { new Item(Items.TEAK_PLANK_8780, 10), new Item(Items.LIMESTONE_BRICK_3420, 7) }), + MARBLE_STAIRCASE(13501, 8257, 82, 3200, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 5), new Item(Items.MARBLE_BLOCK_8786, 5) }), + MARBLE_SPIRAL (13505, 8259, 97, 4400, new Item[] { new Item(Items.TEAK_PLANK_8780, 10), new Item(Items.MARBLE_BLOCK_8786, 7) }), + + /** + * Staircases going down. + */ + OAK_STAIRS_DOWN (13498, 8249, 27, 680, new Item[] { new Item(Items.OAK_PLANK_8778, 10), new Item(Items.STEEL_BAR_2353, 4) }), + TEAK_STAIRS_DOWN (13500, 8252, 48, 980, new Item[] { new Item(Items.TEAK_PLANK_8780, 10), new Item(Items.STEEL_BAR_2353, 4) }), + SPIRAL_STAIRS_DOWN(13504, 8258, 67, 1040, new Item[] { new Item(Items.TEAK_PLANK_8780, 10), new Item(Items.LIMESTONE_BRICK_3420, 7) }), + MARBLE_STAIRS_DOWN(13502, 8257, 82, 3200, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 5), new Item(Items.MARBLE_BLOCK_8786, 5) }), + MARBLE_SPIRAL_DOWN(13506, 8259, 97, 4400, new Item[] { new Item(Items.TEAK_PLANK_8780, 10), new Item(Items.MARBLE_BLOCK_8786, 7) }), + + /** + * Portal room decorations. + */ + TEAK_PORTAL (13636, 8328, 50, 270, new Item[] { new Item(Items.TEAK_PLANK_8780, 3) }), + MAHOGANY_PORTAL (13637, 8329, 65, 420, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 3) }), + MARBLE_PORTAL (13638, 8330, 80, 1500, new Item[] { new Item(Items.MARBLE_BLOCK_8786, 3) }), + TELEPORT_FOCUS (13640, 8331, 50, 40, new Item[] { new Item(Items.LIMESTONE_BRICK_3420, 2) }), + GREATER_TELEPORT_FOCUS (13641, 8332, 65, 500, new Item[] { new Item(Items.MARBLE_BLOCK_8786) }), + SCRYING_POOL (13639, 8333, 80, 2000, new Item[] { new Item(Items.MARBLE_BLOCK_8786, 4) }), + TEAK_VARROCK_PORTAL (13615, true), + MAHOGANY_VARROCK_PORTAL (13622, true), + MARBLE_VARROCK_PORTAL (13629, true), + TEAK_LUMBRIDGE_PORTAL (13616, true), + MAHOGANY_LUMBRIDGE_PORTAL(13623, true), + MARBLE_LUMBRIDGE_PORTAL (13630, true), + TEAK_FALADOR_PORTAL (13617, true), + MAHOGANY_FALADOR_PORTAL (13624, true), + MARBLE_FALADOR_PORTAL (13631, true), + TEAK_CAMELOT_PORTAL (13618, true), + MAHOGANY_CAMELOT_PORTAL (13625, true), + MARBLE_CAMELOT_PORTAL (13632, true), + TEAK_ARDOUGNE_PORTAL (13619, true), + MAHOGANY_ARDOUGNE_PORTAL (13626, true), + MARBLE_ARDOUGNE_PORTAL (13633, true), + TEAK_YANILLE_PORTAL (13620, true), + MAHOGANY_YANILLE_PORTAL (13627, true), + MARBLE_YANILLE_PORTAL (13634, true), + TEAK_KHARYRLL_PORTAL (13621, true), + MAHOGANY_KHARYRLL_PORTAL (13628, true), + MARBLE_KHARYRLL_PORTAL (13635, true), + + /** + * Skill hall decorations. + */ + MITHRIL_ARMOUR (13491, 8270, 28, 135, new Item[] { new Item(Items.OAK_PLANK_8778, 2), new Item(Items.MITHRIL_FULL_HELM_1159, 1), new Item(Items.MITHRIL_PLATEBODY_1121, 1), new Item(Items.MITHRIL_PLATESKIRT_1085, 1) }, new Item[] { new Item(Items.MITHRIL_FULL_HELM_1159, 1), new Item(Items.MITHRIL_PLATEBODY_1121, 1), new Item(Items.MITHRIL_PLATESKIRT_1085, 1) }), + ADAMANT_ARMOUR (13492, 8271, 28, 150, new Item[] { new Item(Items.OAK_PLANK_8778, 2), new Item(Items.ADAMANT_FULL_HELM_1161, 1), new Item(Items.ADAMANT_PLATEBODY_1123, 1), new Item(Items.ADAMANT_PLATESKIRT_1091, 1) }, new Item[] { new Item(Items.ADAMANT_FULL_HELM_1161, 1), new Item(Items.ADAMANT_PLATEBODY_1123, 1), new Item(Items.ADAMANT_PLATESKIRT_1091, 1) }), + RUNE_ARMOUR (13493, 8272, 28, 165, new Item[] { new Item(Items.OAK_PLANK_8778, 2), new Item(Items.RUNE_FULL_HELM_1163, 1), new Item(Items.RUNE_PLATEBODY_1127, 1), new Item(Items.RUNE_PLATESKIRT_1093, 1) }, new Item[] { new Item(Items.RUNE_FULL_HELM_1163, 1), new Item(Items.RUNE_PLATEBODY_1127, 1), new Item(Items.RUNE_PLATESKIRT_1093, 1) }), + CRAWLING_HAND (13481, 8260, 38, 211, new Item[] { new Item(Items.TEAK_PLANK_8780, 2), new Item(Items.CRAWLING_HAND_7982) }), + COCKATRICE_HEAD (13482, 8261, 38, 224, new Item[] { new Item(Items.TEAK_PLANK_8780, 2), new Item(Items.COCKATRICE_HEAD_7983) }), + BASILISK_HEAD (13483, 8262, 38, 243, new Item[] { new Item(Items.TEAK_PLANK_8780, 2), new Item(Items.BASILISK_HEAD_7984) }), + KURASK_HEAD (13484, 8263, 58, 357, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.KURASK_HEAD_7985) }), + ABYSSAL_DEMON_HEAD(13485, 8264, 58, 389, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.ABYSSAL_HEAD_7986) }), + KBD_HEAD (13486, 8265, 78, 1103, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.KBD_HEADS_7987) }), + KQ_HEAD (13487, 8266, 78, 1103, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.KQ_HEAD_7988) }), + MOUNTED_BASS (13488, 8267, 36, 151, new Item[] { new Item(Items.OAK_PLANK_8778, 2), new Item(Items.BIG_BASS_7990) }), + MOUNTED_SWORDFISH (13489, 8268, 56, 230, new Item[] { new Item(Items.TEAK_PLANK_8780, 2), new Item(Items.BIG_SWORDFISH_7992) }), + MOUNTED_SHARK (13490, 8269, 76, 350, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.BIG_SHARK_7994) }), + RUNE_CASE1 (13507, 8095, 41, 190, new Item[] { new Item(Items.TEAK_PLANK_8780, 2), new Item(Items.MOLTEN_GLASS_1775, 2), new Item(Items.FIRE_RUNE_554, 1), new Item(Items.AIR_RUNE_556, 1), new Item(Items.EARTH_RUNE_557, 1), new Item(Items.WATER_RUNE_555, 1) }), + RUNE_CASE2 (13508, 8095, 41, 212, new Item[] { new Item(Items.TEAK_PLANK_8780, 2), new Item(Items.MOLTEN_GLASS_1775, 2), new Item(Items.BODY_RUNE_559, 1), new Item(Items.COSMIC_RUNE_564, 1), new Item(Items.CHAOS_RUNE_562, 1), new Item(Items.NATURE_RUNE_561, 1) }), + + /** + * Games room decorations. + */ + CLAY_STONE (13392, 8153, 39, 100, new Item[] { new Item(Items.SOFT_CLAY_1761, 10) }), + LIMESTONE_STONE(13393, 8154, 59, 200, new Item[] { new Item(Items.LIMESTONE_BRICK_3420, 10) }), + MARBLE_STONE (13394, 8155, 79, 2000, new Item[] { new Item(Items.MARBLE_BLOCK_8786, 4) }), + HOOP_AND_STICK (13398, 8162, 30, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + DARTBOARD (13400, 8163, 54, 290, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.STEEL_BAR_2353) }), + ARCHERY_TARGET (13402, 8164, 81, 600, new Item[] { new Item(Items.TEAK_PLANK_8780, 6), new Item(Items.STEEL_BAR_2353, 3) }), + BALANCE_1 (13395, 8156, 37, 176, new Item[] { new Item(Items.FIRE_RUNE_554, 500), new Item(Items.AIR_RUNE_556, 500), new Item(Items.EARTH_RUNE_557, 500), new Item(Items.WATER_RUNE_555, 500) }), + BALANCE_2 (13396, 8157, 57, 252, new Item[] { new Item(Items.FIRE_RUNE_554, 1000), new Item(Items.AIR_RUNE_556, 1000), new Item(Items.EARTH_RUNE_557, 1000), new Item(Items.WATER_RUNE_555, 1000) }), + BALANCE_3 (13397, 8158, 77, 356, new Item[] { new Item(Items.FIRE_RUNE_554, 2000), new Item(Items.AIR_RUNE_556, 2000), new Item(Items.EARTH_RUNE_557, 2000), new Item(Items.WATER_RUNE_555, 2000) }), + OAK_CHEST (13385, 8165, 34, 240, new Item[] { new Item(Items.OAK_PLANK_8778, 4) }), + TEAK_CHEST (13387, 8166, 44, 660, new Item[] { new Item(Items.TEAK_PLANK_8780, 4), new Item(Items.GOLD_LEAF_8784) }), + MAHOGANY_CHEST (13389, 8167, 54, 860, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 4), new Item(Items.GOLD_LEAF_8784) }), + JESTER (13390, 8159, 39, 360, new Item[] { new Item(Items.TEAK_PLANK_8780, 4) }), + TREASURE_HUNT (13379, 8160, 49, 800, new Item[] { new Item(Items.TEAK_PLANK_8780, 8), new Item(Items.STEEL_BAR_2353, 4) }), + HANGMAN (13404, 8161, 59, 1200, new Item[] { new Item(Items.TEAK_PLANK_8780, 12), new Item(Items.STEEL_BAR_2353, 6) }), + + /** + * Combat room decorations. + */ + BOXING_RING (13129, 8023, 32, 570, new Item[] { new Item(Items.OAK_PLANK_8778, 6), new Item(Items.BOLT_OF_CLOTH_8790, 4) }), + FENCING_RING (13133, 8024, 41, 570, new Item[] { new Item(Items.OAK_PLANK_8778, 8), new Item(Items.BOLT_OF_CLOTH_8790, 6) }), + COMBAT_RING (13137, 8025, 51, 630, new Item[] { new Item(Items.TEAK_PLANK_8780, 6), new Item(Items.BOLT_OF_CLOTH_8790, 6) }), + BALANCE_BEAM_LEFT (13143, 8027, 81, 1000, new Item[] { new Item(Items.TEAK_PLANK_8780, 10), new Item(Items.STEEL_BAR_2353, 5) }), + BALANCE_BEAM_CENTER(13142, 8027, 81, 1000, new Item[] { new Item(Items.TEAK_PLANK_8780, 10), new Item(Items.STEEL_BAR_2353, 5) }), + BALANCE_BEAM_RIGHT (13144, 8027, 81, 1000, new Item[] { new Item(Items.TEAK_PLANK_8780, 10), new Item(Items.STEEL_BAR_2353, 5) }), + RANGING_PEDESTALS (13147, 8026, 71, 720, new Item[] { new Item(Items.TEAK_PLANK_8780, 8) }), + MAGIC_BARRIER (13145, 8026, 71, 720, new Item[] { new Item(Items.TEAK_PLANK_8780, 8) }), + NOTHING (13721, 8027, 81, 1000, new Item[] { new Item(Items.TEAK_PLANK_8780, 10), new Item(Items.STEEL_BAR_2353, 5) }), + NOTHING2 (13721, 8026, 71, 720, new Item[] { new Item(Items.TEAK_PLANK_8780, 8) }), + INVISIBLE_WALL (15283, 8023, 32, 570, new Item[] { new Item(Items.OAK_PLANK_8778, 6), new Item(Items.BOLT_OF_CLOTH_8790, 4) }), + INVISIBLE_WALL2 (15284, 8023, 32, 570, new Item[] { new Item(Items.OAK_PLANK_8778, 6), new Item(Items.BOLT_OF_CLOTH_8790, 4) }), + INVISIBLE_WALL3 (15285, 8023, 32, 570, new Item[] { new Item(Items.OAK_PLANK_8778, 6), new Item(Items.BOLT_OF_CLOTH_8790, 4) }), + GLOVE_RACK (13381, 8028, 34, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + WEAPONS_RACK (13382, 8029, 44, 180, new Item[] { new Item(Items.TEAK_PLANK_8780, 2) }), + EXTRA_WEAPONS_RACK (13383, 8030, 54, 440, new Item[] { new Item(Items.TEAK_PLANK_8780, 4), new Item(Items.STEEL_BAR_2353, 4) }), + BOXING_MAT_CORNER (13126, 8023, 32, 570, new Item[] { new Item(Items.OAK_PLANK_8778, 6), new Item(Items.BOLT_OF_CLOTH_8790, 4) }), + FENCING_MAT_CORNER (13135, 8024, 41, 570, new Item[] { new Item(Items.OAK_PLANK_8778, 8), new Item(Items.BOLT_OF_CLOTH_8790, 6) }), + COMBAT_MAT_CORNER (13138, 8025, 51, 630, new Item[] { new Item(Items.TEAK_PLANK_8780, 6), new Item(Items.BOLT_OF_CLOTH_8790, 6) }), + BOXING_MAT_SIDE (13128, 8023, 32, 570, new Item[] { new Item(Items.OAK_PLANK_8778, 6), new Item(Items.BOLT_OF_CLOTH_8790, 4) }), + FENCING_MAT_SIDE (13134, 8024, 41, 570, new Item[] { new Item(Items.OAK_PLANK_8778, 8), new Item(Items.BOLT_OF_CLOTH_8790, 6) }), + COMBAT_MAT_SIDE (13139, 8025, 51, 630, new Item[] { new Item(Items.TEAK_PLANK_8780, 6), new Item(Items.BOLT_OF_CLOTH_8790, 6) }), + BOXING_MAT (13127, 8023, 32, 570, new Item[] { new Item(Items.OAK_PLANK_8778, 6), new Item(Items.BOLT_OF_CLOTH_8790, 4) }), + FENCING_MAT (13136, 8024, 41, 570, new Item[] { new Item(Items.OAK_PLANK_8778, 8), new Item(Items.BOLT_OF_CLOTH_8790, 6) }), + COMBAT_MAT (13140, 8025, 51, 630, new Item[] { new Item(Items.TEAK_PLANK_8780, 6), new Item(Items.BOLT_OF_CLOTH_8790, 6) }), + + /** + * Formal garden decorations + */ + GAZEBO (13477, 8192, 65, 1200, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 8), new Item(Items.STEEL_BAR_2353, 4) }), + SMALL_FOUNTAIN (13478, 8193, 71, 500, new Item[] { new Item(Items.MARBLE_BLOCK_8786) }), + LARGE_FOUNTAIN (13479, 8194, 75, 1000, new Item[] { new Item(Items.MARBLE_BLOCK_8786, 2) }), + POSH_FOUNTAIN (13480, 8195, 81, 1500, new Item[] { new Item(Items.MARBLE_BLOCK_8786, 3) }), + SUNFLOWER (13446, 8213, 66, 70, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_SUNFLOWER_8457) }), + MARIGOLDS (13447, 8214, 71, 100, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_MARIGOLDS_8459) }), + ROSES (13448, 8215, 76, 122, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_ROSES_8461) }), + SUNFLOWER_BIG (13443, 8213, 66, 70, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_SUNFLOWER_8457) }), + MARIGOLDS_BIG (13444, 8214, 71, 100, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_MARIGOLDS_8459) }), + ROSES_BIG (13445, 8215, 76, 122, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_ROSES_8461) }), + ROSEMARY (13440, 8210, 66, 70, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_ROSEMARY_8451) }), + DAFFODILS (13441, 8211, 71, 100, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_DAFFODILS_8453) }), + BLUEBELLS (13442, 8212, 76, 122, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_BLUEBELLS_8455) }), + ROSEMARY_BIG (13437, 8210, 66, 70, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_ROSEMARY_8451) }), + DAFFODILS_BIG (13438, 8211, 71, 100, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_DAFFODILS_8453) }), + BLUEBELLS_BIG (13439, 8212, 76, 122, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.BAGGED_BLUEBELLS_8455) }), + THORNY_HEDGE1 (13456, 8203, 56, 70, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.THORNY_HEDGE_8437) }), + THORNY_HEDGE2 (13457, 8203, 56, 70, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.THORNY_HEDGE_8437) }), + THORNY_HEDGE3 (13458, 8203, 56, 70, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.THORNY_HEDGE_8437) }), + NICE_HEDGE1 (13459, 8204, 60, 100, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.NICE_HEDGE_8439) }), + NICE_HEDGE2 (13461, 8204, 60, 100, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.NICE_HEDGE_8439) }), + NICE_HEDGE3 (13460, 8204, 60, 100, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.NICE_HEDGE_8439) }), + SMALL_BOX_HEDGE1 (13462, 8205, 64, 122, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.SMALL_BOX_HEDGE_8441) }), + SMALL_BOX_HEDGE2 (13464, 8205, 64, 122, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.SMALL_BOX_HEDGE_8441) }), + SMALL_BOX_HEDGE3 (13463, 8205, 64, 122, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.SMALL_BOX_HEDGE_8441) }), + TOPIARY_HEDGE1 (13465, 8206, 68, 141, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.TOPIARY_HEDGE_8443) }), + TOPIARY_HEDGE2 (13467, 8206, 68, 141, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.TOPIARY_HEDGE_8443) }), + TOPIARY_HEDGE3 (13466, 8206, 68, 141, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.TOPIARY_HEDGE_8443) }), + FANCY_HEDGE1 (13468, 8207, 72, 158, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.FANCY_HEDGE_8445) }), + FANCY_HEDGE2 (13470, 8207, 72, 158, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.FANCY_HEDGE_8445) }), + FANCY_HEDGE3 (13469, 8207, 72, 158, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.FANCY_HEDGE_8445) }), + TALL_FANCY_HEDGE1(13471, 8208, 76, 223, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.TALL_FANCY_HEDGE_8447) }), + TALL_FANCY_HEDGE2(13473, 8208, 76, 223, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.TALL_FANCY_HEDGE_8447) }), + TALL_FANCY_HEDGE3(13472, 8208, 76, 223, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.TALL_FANCY_HEDGE_8447) }), + TALL_BOX_HEDGE1 (13474, 8209, 80, 316, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.TALL_BOX_HEDGE_8449) }), + TALL_BOX_HEDGE2 (13476, 8209, 80, 316, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.TALL_BOX_HEDGE_8449) }), + TALL_BOX_HEDGE3 (13475, 8209, 80, 316, new int[] { BuildingUtils.WATERING_CAN }, new Item[] { new Item(Items.TALL_BOX_HEDGE_8449) }), + BOUNDARY_STONES (13449, 8196, 55, 100, new Item[] { new Item(Items.SOFT_CLAY_1761, 10) }), + WOODEN_FENCE (13450, 8197, 59, 280, new Item[] { new Item(Items.PLANK_960, 10) }), + STONE_WALL (13451, 8198, 63, 200, new Item[] { new Item(Items.LIMESTONE_BRICK_3420, 10) }), + IRON_RAILINGS (13452, 8199, 67, 220, new Item[] { new Item(Items.IRON_BAR_2351, 10), new Item(Items.LIMESTONE_BRICK_3420, 6) }), + PICKET_FENCE (13453, 8200, 71, 640, new Item[] { new Item(Items.OAK_PLANK_8778, 10), new Item(Items.STEEL_BAR_2353, 2) }), + GARDEN_FENCE (13454, 8201, 75, 940, new Item[] { new Item(Items.TEAK_PLANK_8780, 10), new Item(Items.STEEL_BAR_2353, 2) }), + MARBLE_WALL (13455, 8202, 79, 4000, new Item[] { new Item(Items.MARBLE_BLOCK_8786, 10) }), + + /** + * Bedroom decorations. + */ + WOODEN_BED (13148, 8031, 20, 117, new Item[] { new Item(Items.PLANK_960, 3), new Item(Items.BOLT_OF_CLOTH_8790, 2) }), + OAK_BED (13149, 8032, 30, 210, new Item[] { new Item(Items.OAK_PLANK_8778, 3), new Item(Items.BOLT_OF_CLOTH_8790, 2) }), + LARGE_OAK_BED (13150, 8033, 34, 330, new Item[] { new Item(Items.OAK_PLANK_8778, 5), new Item(Items.BOLT_OF_CLOTH_8790, 2) }), + TEAK_BED (13151, 8034, 40, 300, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.BOLT_OF_CLOTH_8790, 2) }), + LARGE_TEAK_BED (13152, 8035, 45, 480, new Item[] { new Item(Items.TEAK_PLANK_8780, 5), new Item(Items.BOLT_OF_CLOTH_8790, 2) }), + FOUR_POSTER (13153, 8036, 53, 450, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 3), new Item(Items.BOLT_OF_CLOTH_8790, 2) }), + GILDED_FOUR_POSTER(13154, 8037, 60, 1330, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 5), new Item(Items.BOLT_OF_CLOTH_8790, 2), new Item(Items.GOLD_LEAF_8784, 2) }), + OAK_CLOCK (13169, 8052, 25, 142, new Item[] { new Item(Items.OAK_PLANK_8778, 2), new Item(Items.CLOCKWORK_8792) }), + TEAK_CLOCK (13170, 8053, 55, 202, new Item[] { new Item(Items.TEAK_PLANK_8780, 2), new Item(Items.CLOCKWORK_8792) }), + GILDED_CLOCK (13171, 8054, 85, 602, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.CLOCKWORK_8792), new Item(Items.GOLD_LEAF_8784) }), + SHAVING_STAND (13162, 8045, 21, 30, new Item[] { new Item(Items.PLANK_960), new Item(Items.MOLTEN_GLASS_1775) }), + OAK_SHAVING_STAND (13163, 8046, 29, 61, new Item[] { new Item(Items.OAK_PLANK_8778), new Item(Items.MOLTEN_GLASS_1775) }), + OAK_DRESSER (13164, 8047, 37, 121, new Item[] { new Item(Items.OAK_PLANK_8778, 2), new Item(Items.MOLTEN_GLASS_1775) }), + TEAK_DRESSER (13165, 8048, 46, 181, new Item[] { new Item(Items.TEAK_PLANK_8780, 2), new Item(Items.MOLTEN_GLASS_1775) }), + FANCY_TEAK_DRESSER(13166, 8049, 56, 182, new Item[] { new Item(Items.TEAK_PLANK_8780, 2), new Item(Items.MOLTEN_GLASS_1775, 2) }), + MAHOGANY_DRESSER (13167, 8050, 64, 281, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.MOLTEN_GLASS_1775) }), + GILDED_DRESSER (13168, 8051, 74, 582, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.MOLTEN_GLASS_1775, 2), new Item(Items.GOLD_LEAF_8784) }), + SHOE_BOX (13155, 8038, 20, 58, new Item[] { new Item(Items.PLANK_960, 2) }), + OAK_DRAWERS (13156, 8039, 27, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + OAK_WARDROBE (13157, 8040, 39, 180, new Item[] { new Item(Items.OAK_PLANK_8778, 3) }), + TEAK_DRAWERS (13158, 8041, 51, 180, new Item[] { new Item(Items.TEAK_PLANK_8780, 2) }), + TEAK_WARDROBE (13159, 8042, 63, 270, new Item[] { new Item(Items.TEAK_PLANK_8780, 3) }), + MAHOGANY_WARDROBE (13160, 8043, 75, 420, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2) }), + GILDED_WARDROBE (13161, 8044, 87, 720, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.GOLD_LEAF_8784) }), + + /** + * Quest hall decorations. + */ + ANTIDRAGON_SHIELD(13522, 8282, 47, 280, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.ANTI_DRAGON_SHIELD_1540) }, new Item[] { new Item(Items.ANTI_DRAGON_SHIELD_1540) }), + AMULET_OF_GLORY (13523, 8283, 47, 290, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.AMULET_OF_GLORY_1704) }, new Item[] { new Item(Items.AMULET_OF_GLORY_1704) }), + CAPE_OF_LEGENDS (13524, 8284, 47, 300, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.CAPE_OF_LEGENDS_1052) }, new Item[] { new Item(Items.CAPE_OF_LEGENDS_1052) }), + KING_ARTHUR (13510, 8285, 35, 211, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.ARTHUR_PORTRAIT_7995) }), + ELENA (13511, 8286, 35, 211, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.ELENA_PORTRAIT_7996) }), + GIANT_DWARF (13512, 8287, 35, 211, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.KELDAGRIM_PORTRAIT_7997) }), + MISCELLANIANS (13513, 8288, 35, 311, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.MISC_PORTRAIT_7998) }), + LUMBRIDGE (13517, 8289, 44, 314, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.LUMBRIDGE_PAINTING_8002) }), + THE_DESERT (13514, 8290, 44, 314, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.DESERT_PAINTING_7999) }), + MORYTANIA (13518, 8291, 44, 314, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.MORYTANIA_PAINTING_8003) }), + KARAMJA (13516, 8292, 65, 464, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 3), new Item(Items.KARAMJA_PAINTING_8001) }), + ISAFDAR (13515, 8293, 65, 464, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 3), new Item(Items.ISAFDAR_PAINTING_8000) }), + SILVERLIGHT (13519, 8279, 42, 187, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.SILVERLIGHT_2402) }, new Item[] { new Item(Items.SILVERLIGHT_2402) }), + EXCALIBUR (13521, 8280, 42, 194, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.EXCALIBUR_35) }, new Item[] { new Item(Items.EXCALIBUR_35) }), + DARKLIGHT (13520, 8281, 42, 202, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.DARKLIGHT_6746) }, new Item[] { new Item(Items.DARKLIGHT_6746) }), + SMALL_MAP (13525, 8294, 38, 211, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.SMALL_MAP_8004) }), + MEDIUM_MAP (13526, 8295, 58, 451, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 3), new Item(Items.MEDIUM_MAP_8005) }), + LARGE_MAP (13527, 8296, 78, 591, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 4), new Item(Items.LARGE_MAP_8006) }), + + /** + * Study decorations. + */ + GLOBE (13649, 8341, 41, 180, new Item[] { new Item(Items.OAK_PLANK_8778, 3) }), + ORNAMENTAL_GLOBE (13650, 8342, 50, 270, new Item[] { new Item(Items.TEAK_PLANK_8780, 3) }), + LUNAR_GLOBE (13651, 8343, 59, 570, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.GOLD_LEAF_8784) }), + CELESTIAL_GLOBE (13652, 8344, 68, 570, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.GOLD_LEAF_8784) }), + ARMILLARY_SPHERE (13653, 8345, 77, 960, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.GOLD_LEAF_8784, 2), new Item(Items.STEEL_BAR_2353, 4) }), + SMALL_ORREY (13654, 8346, 86, 1320, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 3), new Item(Items.GOLD_LEAF_8784, 3) }), + LARGE_ORREY (13655, 8347, 95, 1420, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 3), new Item(Items.GOLD_LEAF_8784, 5) }), + OAK_LECTERN (13642, 8334, 40, 60, new Item[] { new Item(Items.OAK_PLANK_8778) }), + EAGLE_LECTERN (13643, 8335, 47, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + DEMON_LECTERN (13644, 8336, 47, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + TEAK_EAGLE_LECTERN (13645, 8337, 57, 180, new Item[] { new Item(Items.TEAK_PLANK_8780, 2) }), + TEAK_DEMON_LECTERN (13646, 8338, 57, 180, new Item[] { new Item(Items.TEAK_PLANK_8780, 2) }), + MAHOGANY_EAGLE_LECTERN(13647, 8339, 67, 580, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.GOLD_LEAF_8784) }), + MAHOGANY_DEMON_LECTERN(13648, 8340, 67, 580, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.GOLD_LEAF_8784) }), + CRYSTAL_BALL (13659, 8351, 42, 280, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.UNPOWERED_ORB_567) }), + ELEMENTAL_SPHERE (13660, 8352, 54, 580, new Item[] { new Item(Items.TEAK_PLANK_8780, 3), new Item(Items.UNPOWERED_ORB_567), new Item(Items.GOLD_LEAF_8784) }), + CRYSTAL_OF_POWER (13661, 8353, 66, 890, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.UNPOWERED_ORB_567), new Item(Items.GOLD_LEAF_8784, 2) }), + ALCHEMICAL_CHART (13662, 8354, 43, 30, new Item[] { new Item(Items.BOLT_OF_CLOTH_8790, 2) }), + ASTRONOMICAL_CHART (13663, 8355, 63, 45, new Item[] { new Item(Items.BOLT_OF_CLOTH_8790, 3) }), + INFERNAL_CHART (13664, 8356, 83, 60, new Item[] { new Item(Items.BOLT_OF_CLOTH_8790, 4) }), + TELESCOPE1 (13656, 8348, 44, 121, new Item[] { new Item(Items.OAK_PLANK_8778, 2), new Item(Items.MOLTEN_GLASS_1775) }), + TELESCOPE2 (13657, 8349, 64, 181, new Item[] { new Item(Items.TEAK_PLANK_8780, 2), new Item(Items.MOLTEN_GLASS_1775) }), + TELESCOPE3 (13658, 8350, 84, 580, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2), new Item(Items.MOLTEN_GLASS_1775) }), + + /** + * Costume room decorations. + */ + OAK_TREASURE_CHEST (18804, 9839, 48, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + TEAK_TREASURE_CHEST (18806, 9840, 66, 180, new Item[] { new Item(Items.TEAK_PLANK_8780, 2) }), + MAHOGANY_TREASURE_CHEST(18808, 9841, 84, 280, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2) }), + OAK_ARMOUR_CASE (18778, 9826, 46, 180, new Item[] { new Item(Items.OAK_PLANK_8778, 3) }), + TEAK_ARMOUR_CASE (18780, 9827, 64, 270, new Item[] { new Item(Items.TEAK_PLANK_8780, 3) }), + MGANY_ARMOUR_CASE (18782, 9828, 82, 420, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 3) }), + OAK_MAGIC_WARDROBE (18784, 9829, 42, 240, new Item[] { new Item(Items.OAK_PLANK_8778, 4) }), + C_OAK_MAGIC_WARDROBE (18786, 9830, 51, 360, new Item[] { new Item(Items.OAK_PLANK_8778, 6) }), + TEAK_MAGIC_WARDROBE (18788, 9831, 60, 360, new Item[] { new Item(Items.TEAK_PLANK_8780, 4) }), + C_TEAK_MAGIC_WARDROBE (18790, 9832, 69, 540, new Item[] { new Item(Items.TEAK_PLANK_8780, 6) }), + MGANY_MAGIC_WARDROBE (18792, 9833, 78, 560, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 4) }), + GILDED_MAGIC_WARDROBE (18794, 9834, 87, 860, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 4), new Item(Items.GOLD_LEAF_8784) }), + MARBLE_MAGIC_WARDROBE (18796, 9835, 96, 500, new Item[] { new Item(Items.MARBLE_BLOCK_8786) }), + OAK_CAPE_RACK (18766, 9817, 54, 240, new Item[] { new Item(Items.OAK_PLANK_8778, 4) }), + TEAK_CAPE_RACK (18767, 9818, 63, 360, new Item[] { new Item(Items.TEAK_PLANK_8780, 4) }), + MGANY_CAPE_RACK (18768, 9819, 72, 560, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 4) }), + GILDED_CAPE_RACK (18769, 9820, 81, 860, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 4), new Item(Items.GOLD_LEAF_8784) }), + MARBLE_CAPE_RACK (18770, 9821, 90, 500, new Item[] { new Item(Items.MARBLE_BLOCK_8786) }), + MAGIC_CAPE_RACK (18771, 9822, 99, 1000, new Item[] { new Item(Items.MAGIC_STONE_8788) }), + OAK_TOY_BOX (18798, 9836, 50, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + TEAK_TOY_BOX (18800, 9837, 68, 180, new Item[] { new Item(Items.TEAK_PLANK_8780, 2) }), + MAHOGANY_TOY_BOX (18802, 9838, 86, 280, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2) }), + OAK_COSTUME_BOX (18772, 9823, 44, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + TEAK_COSTUME_BOX (18774, 9824, 62, 180, new Item[] { new Item(Items.TEAK_PLANK_8780, 2) }), + MAHOGANY_COSTUME_BOX (18776, 9825, 80, 280, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 2) }), + + /** + * Chapel decorations. + */ + OAK_ALTAR (13179, 8062, 45, 240, new Item[] { new Item(Items.OAK_PLANK_8778, 4) }), + TEAK_ALTAR (13182, 8063, 50, 360, new Item[] { new Item(Items.TEAK_PLANK_8780, 4) }), + CLOTH_ALTAR (13185, 8064, 56, 390, new Item[] { new Item(Items.TEAK_PLANK_8780, 4), new Item(Items.BOLT_OF_CLOTH_8790, 2) }), + MAHOGANY_ALTAR (13188, 8065, 60, 590, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 4), new Item(Items.BOLT_OF_CLOTH_8790, 2) }), + LIMESTONE_ALTAR (13191, 8066, 64, 910, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 6), new Item(Items.BOLT_OF_CLOTH_8790, 2), new Item(Items.LIMESTONE_BRICK_3420, 2) }), + MARBLE_ALTAR (13194, 8067, 70, 1030, new Item[] { new Item(Items.MARBLE_BLOCK_8786, 2), new Item(Items.BOLT_OF_CLOTH_8790, 2) }), + GILDED_ALTAR (13197, 8068, 75, 2230, new Item[] { new Item(Items.MARBLE_BLOCK_8786, 2), new Item(Items.BOLT_OF_CLOTH_8790, 2), new Item(Items.GOLD_LEAF_8784, 4) }), + SMALL_STATUE (13271, 8082, 49, 40, new Item[] { new Item(Items.LIMESTONE_BRICK_3420, 2) }), + MEDIUM_STATUE (13272, 8083, 69, 500, new Item[] { new Item(Items.MARBLE_BLOCK_8786) }), + LARGE_STATUE (13282, 8084, 89, 1500, new Item[] { new Item(Items.MARBLE_BLOCK_8786, 3) }), + WINDCHIMES (13214, 8079, 49, 323, new Item[] { new Item(Items.OAK_PLANK_8778, 4), new Item(Items.STEEL_BAR_2353, 4) }), + BELLS (13215, 8080, 58, 480, new Item[] { new Item(Items.TEAK_PLANK_8780, 4), new Item(Items.STEEL_BAR_2353, 6) }), + ORGAN (13216, 8081, 69, 680, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 4), new Item(Items.STEEL_BAR_2353, 6) }), + SARADOMIN_SYMBOL (13172, 8055, 48, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + ZAMORAK_SYMBOL (13173, 8056, 48, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + GUTHIX_SYMBOL (13174, 8057, 48, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + SARADOMIN_ICON (13175, 8058, 59, 960, new Item[] { new Item(Items.TEAK_PLANK_8780, 4), new Item(Items.GOLD_LEAF_8784, 2) }), + ZAMORAK_ICON (13176, 8059, 59, 960, new Item[] { new Item(Items.TEAK_PLANK_8780, 4), new Item(Items.GOLD_LEAF_8784, 2) }), + GUTHIX_ICON (13177, 8060, 59, 960, new Item[] { new Item(Items.TEAK_PLANK_8780, 4), new Item(Items.GOLD_LEAF_8784, 2) }), + ICON_OF_BOB (13178, 8061, 71, 1160, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 4), new Item(Items.GOLD_LEAF_8784, 2) }), + STEEL_TORCHES (13202, 8070, 45, 80, new Item[] { new Item(Items.STEEL_BAR_2353, 2) }), + WOODEN_TORCHES (13200, 8069, 49, 58, new Item[] { new Item(Items.PLANK_960, 2) }), + STEEL_CANDLESTICKS(13204, 8071, 53, 124, new Item[] { new Item(Items.STEEL_BAR_2353, 6), new Item(Items.CANDLE_36, 6) }), + GOLD_CANDLESTICKS (13206, 8072, 57, 46, new Item[] { new Item(Items.GOLD_BAR_2357, 6), new Item(Items.CANDLE_36, 6) }), + INCENSE_BURNERS (13208, 8073, 61, 280, new Item[] { new Item(Items.OAK_PLANK_8778, 4), new Item(Items.STEEL_BAR_2353, 2) }), + MAHOGANY_BURNERS (13210, 8074, 65, 600, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 4), new Item(Items.STEEL_BAR_2353, 2) }), + MARBLE_BURNERS (13212, 8075, 69, 1600, new Item[] { new Item(Items.MARBLE_BLOCK_8786, 2), new Item(Items.STEEL_BAR_2353, 2) }), + SHUTTERED_WINDOW (new int[] { 13253, 13226, 13235, 13244, 13217, 13262 }, 8076, 49, 228, new Item[] { new Item(Items.PLANK_960, 8) }), + DECORATIVE_WINDOW (new int[] { 13254, 13227, 13236, 13245, 13218, 13263 }, 8077, 69, 200, new Item[] { new Item(Items.MOLTEN_GLASS_1775, 8) }), + STAINED_GLASS (new int[] { 13255, 13228, 13237, 13246, 13219, 13264 }, 8078, 89, 400, new Item[] { new Item(Items.MOLTEN_GLASS_1775, 16) }), + + /** + * Throne room + */ + OAK_THRONE (13665, 8357, 60, 800, new Item[] { new Item(Items.OAK_PLANK_8778, 5), new Item(Items.MARBLE_BLOCK_8786) }), + TEAK_THRONE (13666, 8358, 67, 1450, new Item[] { new Item(Items.TEAK_PLANK_8780, 5), new Item(Items.MARBLE_BLOCK_8786, 2) }), + MAHOGANY_THRONE (13667, 8359, 74, 2200, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 5), new Item(Items.MARBLE_BLOCK_8786, 3) }), + GILDED_THRONE (13668, 8360, 81, 1700, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 5), new Item(Items.MARBLE_BLOCK_8786, 2), new Item(Items.GOLD_LEAF_8784, 3) }), + SKELETON_THRONE (13669, 8361, 88, 7003, new Item[] { new Item(Items.MAGIC_STONE_8788, 5), new Item(Items.MARBLE_BLOCK_8786, 4), new Item(Items.BONES_526, 5), new Item(Items.SKULL_964, 2) }), + CRYSTAL_THRONE (13670, 8362, 95, 15000, new Item[] { new Item(Items.MAGIC_STONE_8788, 15) }), + DEMONIC_THRONE (13671, 8363, 99, 25000, new Item[] { new Item(Items.MAGIC_STONE_8788, 25) }), + OAK_LEVER (13672, 8364, 68, 300, new Item[] { new Item(Items.OAK_PLANK_8778, 5) }), + TEAK_LEVER (13673, 8365, 78, 450, new Item[] { new Item(Items.TEAK_PLANK_8780, 5) }), + MAHOGANY_LEVER (13674, 8366, 88, 700, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 5) }), + FLOOR_DECORATION (new int[] { 13689, 13686, 13687, 13688, 13684, 13685 }, 8370, 61, 700, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 5) }), + STEEL_CAGE (new int[] { 13689, 13686, 13687, 13688, 13684, 13685 }, 8371, 68, 1100, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 5), new Item(Items.STEEL_BAR_2353, 20) }), + FLOOR_TRAP (new int[] { 13689, 13686, 13687, 13688, 13684, 13685 }, 8372, 74, 770, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 5), new Item(Items.CLOCKWORK_8792, 10) }), + MAGIC_CIRCLE (new int[] { 13689, 13686, 13687, 13688, 13684, 13685 }, 8373, 82, 2700, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 5), new Item(Items.MAGIC_STONE_8788, 2) }), + MAGIC_CAGE (new int[] { 13689, 13686, 13687, 13688, 13684, 13685 }, 8374, 89, 4700, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 5), new Item(Items.MAGIC_STONE_8788, 4) }), + OAK_TRAPDOOR (13675, 8367, 68, 300, new Item[] { new Item(Items.OAK_PLANK_8778, 5) }), + TEAK_TRAPDOOR (13676, 8368, 78, 450, new Item[] { new Item(Items.TEAK_PLANK_8780, 5) }), + MAHOGANY_TRAPDOOR(13677, 8369, 88, 700, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 5) }), + CARVED_TEAK_BENCH(13694, 8112, 44, 360, new Item[] { new Item(Items.TEAK_PLANK_8780, 4) }), + MAHOGANY_BENCH (13695, 8113, 52, 560, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 4) }), + GILDED_BENCH (13696, 8114, 61, 1760, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 4), new Item(Items.GOLD_LEAF_8784, 4) }), + OAK_DECO (13798, 8102, 16, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + TEAK_DECO (13814, 8103, 36, 180, new Item[] { new Item(Items.TEAK_PLANK_8780, 2) }), + GILDED_DECO (13782, 8104, 56, 1020, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 3), new Item(Items.GOLD_LEAF_8784, 2) }), + ROUND_SHIELD (13734, 8105, 66, 120, new Item[] { new Item(Items.OAK_PLANK_8778, 2) }), + SQUARE_SHIELD (13766, 8106, 76, 360, new Item[] { new Item(Items.TEAK_PLANK_8780, 4) }), + KITE_SHIELD (13750, 8107, 86, 420, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 3) }), + + /** + * Oubliette + */ + SPIKES_MID (13334, 8302, 65, 623, new Item[] { new Item(Items.STEEL_BAR_2353, 20), new Item(Items.COINS_995, 50000) }), + SPIKES_SIDE (13335, 8302, 65, 623, new Item[] { new Item(Items.STEEL_BAR_2353, 20), new Item(Items.COINS_995, 50000) }), + SPIKES_CORNER (13336, 8302, 65, 623, new Item[] { new Item(Items.STEEL_BAR_2353, 20), new Item(Items.COINS_995, 50000) }), + SPIKES_FL (13338, 8302, 65, 623, new Item[] { new Item(Items.STEEL_BAR_2353, 20), new Item(Items.COINS_995, 50000) }), + TENTACLE_MID (13331, 8303, 71, 326, new Item[] { new Item(Items.BUCKET_OF_WATER_1929, 20), new Item(Items.COINS_995, 100000) }), + TENTACLE_SIDE (13332, 8303, 71, 326, new Item[] { new Item(Items.BUCKET_OF_WATER_1929, 20), new Item(Items.COINS_995, 100000) }), + TENTACLE_CORNER (13333, 8303, 71, 326, new Item[] { new Item(Items.BUCKET_OF_WATER_1929, 20), new Item(Items.COINS_995, 100000) }), + TENTACLE_FL (13338, 8303, 71, 326, new Item[] { new Item(Items.BUCKET_OF_WATER_1929, 20), new Item(Items.COINS_995, 100000) }), + FP_FLOOR_MID (13371, 8304, 77, 357, new Item[] { new Item(Items.TINDERBOX_590, 20), new Item(Items.COINS_995, 125000) }), + FP_FLOOR_SIDE (13371, 8304, 77, 357, new Item[] { new Item(Items.TINDERBOX_590, 20), new Item(Items.COINS_995, 125000) }), + FP_FLOOR_CORNER (13371, 8304, 77, 357, new Item[] { new Item(Items.TINDERBOX_590, 20), new Item(Items.COINS_995, 125000) }), + FLAME_PIT (13337, 8304, 77, 357, new Item[] { new Item(Items.TINDERBOX_590, 20), new Item(Items.COINS_995, 125000) }), + ROCNAR_FLOOR_MID (13371, 8305, 83, 387, new Item[] { new Item(Items.COINS_995, 150000) }), + ROCNAR_FLOOR_SIDE (13371, 8305, 83, 387, new Item[] { new Item(Items.COINS_995, 150000) }), + ROCNAR_FLOOR_CORNER(13371, 8305, 83, 387, new Item[] { new Item(Items.COINS_995, 150000) }), + ROCNAR (13373, 8305, 83, 387, new Item[] { new Item(Items.COINS_995, 150000) }), + ROCNAR_FL (13338, 8305, 83, 387, new Item[] { new Item(Items.COINS_995, 150000) }), + OAK_CAGE (13313, 8297, 65, 640, new Item[] { new Item(Items.OAK_PLANK_8778, 10), new Item(Items.STEEL_BAR_2353, 2) }), + OAK_CAGE_DOOR (13314, 8297, 65, 640, new Item[] { new Item(Items.OAK_PLANK_8778, 10), new Item(Items.STEEL_BAR_2353, 2) }), + OAK_STEEL_CAGE (13316, 8298, 70, 800, new Item[] { new Item(Items.OAK_PLANK_8778, 10), new Item(Items.STEEL_BAR_2353, 10) }), + OAK_STEEL_CAGE_DOOR(13317, 8298, 70, 800, new Item[] { new Item(Items.OAK_PLANK_8778, 10), new Item(Items.STEEL_BAR_2353, 10) }), + STEEL_CAGE_OU (13319, 8299, 75, 400, new Item[] { new Item(Items.STEEL_BAR_2353, 20) }), + STEEL_CAGE_DOOR (13320, 8299, 75, 400, new Item[] { new Item(Items.STEEL_BAR_2353, 20) }), + SPIKED_CAGE (13322, 8300, 80, 500, new Item[] { new Item(Items.STEEL_BAR_2353, 25) }), + SPIKED_CAGE_DOOR (13323, 8300, 80, 500, new Item[] { new Item(Items.STEEL_BAR_2353, 25) }), + BONE_CAGE (13325, 8301, 85, 603, new Item[] { new Item(Items.OAK_PLANK_8778, 10), new Item(Items.BONES_526, 10) }), + BONE_CAGE_DOOR (13326, 8301, 85, 603, new Item[] { new Item(Items.OAK_PLANK_8778, 10), new Item(Items.BONES_526, 10) }), + SKELETON_GUARD (13366, 8131, 70, 223, new Item[] { new Item(Items.COINS_995, 50000) }), + GUARD_DOG (13367, 8132, 74, 273, new Item[] { new Item(Items.COINS_995, 75000) }), + HOBGOBLIN (13368, 8133, 78, 316, new Item[] { new Item(Items.COINS_995, 100000) }), + BABY_RED_DRAGON (13372, 8134, 82, 387, new Item[] { new Item(Items.COINS_995, 150000) }), + HUGE_SPIDER (13370, 8135, 86, 447, new Item[] { new Item(Items.COINS_995, 200000) }), + TROLL (13369, 8136, 90, 1000, new Item[] { new Item(Items.COINS_995, 1000000) }), + HELLHOUND (2715, 8137, 94, 2236, new Item[] { new Item(Items.COINS_995, 5000000) }), + OAK_LADDER (13328, 8306, 68, 300, new Item[] { new Item(Items.OAK_PLANK_8778, 5) }), + TEAK_LADDER (13329, 8307, 78, 450, new Item[] { new Item(Items.TEAK_PLANK_8780, 5) }), + MAHOGANY_LADDER (13330, 8308, 88, 700, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 5) }), + DECORATIVE_BLOOD (13312, 8125, 72, 4, new Item[] { new Item(Items.RED_DYE_1763, 4) }), + DECORATIVE_PIPE (13311, 8126, 83, 120, new Item[] { new Item(Items.STEEL_BAR_2353, 6) }), + HANGING_SKELETON (13310, 8127, 94, 3, new Item[] { new Item(Items.SKULL_964, 2), new Item(Items.BONES_526, 6) }), + CANDLE (13342, 8128, 72, 243, new Item[] { new Item(Items.OAK_PLANK_8778, 4), new Item(Items.LIT_CANDLE_33, 4) }), + TORCH (13341, 8129, 84, 244, new Item[] { new Item(Items.OAK_PLANK_8778, 4), new Item(Items.LIT_TORCH_594, 4) }), + SKULL_TORCH (13343, 8130, 94, 246, new Item[] { new Item(Items.OAK_PLANK_8778, 4), new Item(Items.LIT_TORCH_594, 4), new Item(Items.SKULL_964, 4) }), + + /** + * Dungeon corridor, junction, stairs & pit + */ + OAK_DOOR_LEFT (13344, 8122, 74, 600, new Item[] { new Item(Items.OAK_PLANK_8778, 10) }), + OAK_DOOR_RIGHT (13345, 8122, 74, 600, new Item[] { new Item(Items.OAK_PLANK_8778, 10) }), + STEEL_DOOR_LEFT (13346, 8123, 84, 800, new Item[] { new Item(Items.OAK_PLANK_8778, 10), new Item(Items.STEEL_BAR_2353, 10) }), + STEEL_DOOR_RIGHT (13347, 8123, 84, 800, new Item[] { new Item(Items.OAK_PLANK_8778, 10), new Item(Items.STEEL_BAR_2353, 10) }), + MARBLE_DOOR_LEFT (13348, 8124, 94, 2000, new Item[] { new Item(Items.MARBLE_BLOCK_8786, 4) }), + MARBLE_DOOR_RIGHT (13349, 8124, 94, 2000, new Item[] { new Item(Items.MARBLE_BLOCK_8786, 4) }), + SPIKE_TRAP (13356, 8143, 72, 223, new Item[] { new Item(Items.COINS_995, 50000) }), + MAN_TRAP (13357, 8144, 76, 273, new Item[] { new Item(Items.COINS_995, 75000) }), + TANGLE_TRAP (13358, 8145, 80, 316, new Item[] { new Item(Items.COINS_995, 100000) }), + MARBLE_TRAP (13359, 8146, 84, 387, new Item[] { new Item(Items.COINS_995, 150000) }), + TELEPORT_TRAP (13360, 8147, 88, 447, new Item[] { new Item(Items.COINS_995, 200000) }), + PIT_DOG (39260, 18791, 70, 200, new Item[] { new Item(Items.COINS_995, 40000) }), + PIT_OGRE (39261, 18792, 73, 234, new Item[] { new Item(Items.COINS_995, 55000) }), + PIT_ROCK_PROTECTOR(39262, 18793, 79, 300, new Item[] { new Item(Items.COINS_995, 90000) }), + PIT_SCABARITE (39263, 18794, 84, 387, new Item[] { new Item(Items.COINS_995, 150000) }), + PIT_BLACK_DEMON (39264, 18795, 89, 547, new Item[] { new Item(Items.COINS_995, 300000) }), + PIT_IRON_DRAGON (39265, 18796, 97, 2738, new Item[] { new Item(Items.COINS_995, 7500000) }), + + /** + * Treasure room + */ + DEMON (13378, 8138, 75, 707, new Item[] { new Item(Items.COINS_995, 500000) }), + KALPHITE_SOLDIER (13374, 8139, 80, 866, new Item[] { new Item(Items.COINS_995, 750000) }), + TOK_XIL (13377, 8140, 85, 2236, new Item[] { new Item(Items.COINS_995, 5000000) }), + DAGANNOTH (13376, 8141, 90, 2738, new Item[] { new Item(Items.COINS_995, 7500000) }), + STEEL_DRAGON (13375, 8142, 95, 3162, new Item[] { new Item(Items.COINS_995, 1000000) }), + WOODEN_CRATE (13283, 8148, 75, 143, new Item[] { new Item(Items.PLANK_960, 5) }), + OAK_T_CHEST (13285, 8149, 79, 340, new Item[] { new Item(Items.OAK_PLANK_8778, 5), new Item(Items.STEEL_BAR_2353, 2) }), + TEAK_T_CHEST (13287, 8150, 83, 530, new Item[] { new Item(Items.TEAK_PLANK_8780, 5), new Item(Items.STEEL_BAR_2353, 4) }), + MGANY_T_CHEST (13289, 8151, 87, 1000, new Item[] { new Item(Items.MAHOGANY_PLANK_8782, 5), new Item(Items.GOLD_LEAF_8784) }), + MAGIC_CHEST (13291, 8152, 91, 1000, new Item[] { new Item(Items.MAGIC_STONE_8788) }), + + /** + * Style related decoration. + */ + BASIC_WOOD_WINDOW (13099, -1, 1, 0), + BASIC_STONE_WINDOW (13091, -1, 1, 0), + WHITEWASHED_STONE_WINDOW (13005, -1, 1, 0), + FREMENNIK_WINDOW (13112, -1, 1, 0), + TROPICAL_WOOD_WINDOW (10816, -1, 1, 0), + FANCY_STONE_WINDOW (13117, -1, 1, 0), + ; + + /** + * The object id. + */ + private final int objectId; + + /** + * The item id for the interface. + */ + private final int interfaceItem; + + /** + * The level requirement. + */ + private final int level; + + /** + * The experience gained for building this decoration. + */ + private final int experience; + + /** + * The item required. + */ + private final Item[] items; + + /** + * The items that will be refunded. + */ + private final Item[] refundItems; + + /** + * The tools required. + */ + private final int[] tools; + + /** + * The object ids depending on styling. + */ + private final int[] objectIds; + + /** + * If this node should be invisible to user build options + */ + private boolean invisibleNode; + + /** + * Constructs a new object, no items, no tools, no refund items. + * @param objectId The object id. + * @param interfaceItem The item id for the building interface. + * @param level The level required. + * @param experience The experience gained. + */ + Decoration(int objectId, int interfaceItem, int level, int experience) { + this(objectId, interfaceItem, level, experience, new int[] { Items.HAMMER_2347, Items.SAW_8794 }, new Item[] {}, new Item[] {}); + } + + /** + * Constructs a new object, no tools, no refund items. + * @param objectId The object id. + * @param interfaceItem The item id for the building interface. + * @param level The level required. + * @param experience The experience gained. + * @param items The items required. + */ + Decoration(int objectId, int interfaceItem, int level, int experience, Item[] items) { + this(objectId, interfaceItem, level, experience, new int[] { Items.HAMMER_2347, Items.SAW_8794 }, items, new Item[] {}); + } + + /** + * Constructs a new object, no refund items. + * @param objectId The object id. + * @param interfaceItem The item id for the building interface. + * @param level The level required. + * @param experience The experience gained. + * @param tools The tools needed. + * @param items The items required. + */ + Decoration(int objectId, int interfaceItem, int level, int experience, int[] tools, Item[] items) { + this(objectId, interfaceItem, level, experience, tools, items, new Item[] {}); + } + + /** + * Constructs a new object, no tools. + * @param objectId The object id. + * @param interfaceItem The item id for the building interface. + * @param level The level required. + * @param experience The experience gained. + * @param items The items required. + * @param refundItems The items to be refunded when the item is removed. + */ + Decoration(int objectId, int interfaceItem, int level, int experience, Item[] items, Item[] refundItems) { + this(objectId, interfaceItem, level, experience, new int[] { Items.HAMMER_2347, Items.SAW_8794 }, items, refundItems); + } + + /** + * Constructs a new object. + * @param objectId The object id. + * @param interfaceItem The item id for the building interface. + * @param level The level required. + * @param experience The experience gained. + * @param tools The tools needed. + * @param items The items required. + * @param refundItems The items to be refunded when the item is removed. + */ + Decoration(int objectId, int interfaceItem, int level, int experience, int[] tools, Item[] items, Item[] refundItems) { + this.objectId = objectId; + this.objectIds = null; + this.interfaceItem = interfaceItem; + this.level = level; + this.experience = experience; + this.tools = tools; + this.items = items; + this.refundItems = refundItems; + } + + /** + * Decoration + * @param objectId + * @param invisibleNode + */ + Decoration(int objectId, boolean invisibleNode) { + this(objectId, -1, -1, -1); + this.invisibleNode = true; + } + + /** + * Constructs a new object, no tools, no refund items. + * @param objectIds The object id. + * @param interfaceItem The item id for the building interface. + * @param level The level required. + * @param experience The experience gained. + * @param items The items required. + */ + Decoration(int[] objectIds, int interfaceItem, int level, int experience, Item[] items) { + this(objectIds, interfaceItem, level, experience, new int[] { Items.HAMMER_2347, Items.SAW_8794 }, items, new Item[] {}); + } + /** + * Constructs a new object no refund items. + * @param objectIds The object id. + * @param interfaceItem The item id for the building interface. + * @param level The level required. + * @param experience The experience gained. + * @param tools The tools needed. + * @param items The items required. + */ + Decoration(int[] objectIds, int interfaceItem, int level, int experience, int[] tools, Item[] items) { + this(objectIds, interfaceItem, level, experience, tools, items, new Item[] {}); + } + + /** + * Constructs a new object. + * @param objectIds The object id. + * @param interfaceItem The item id for the building interface. + * @param level The level required. + * @param experience The experience gained. + * @param tools The tools needed. + * @param items The items required. + * @param refundItems The items to be refunded when the item is removed. + */ + Decoration(int[] objectIds, int interfaceItem, int level, int experience, int[] tools, Item[] items, Item[] refundItems) { + this.objectId = objectIds[0]; + this.objectIds = objectIds; + this.interfaceItem = interfaceItem; + this.level = level; + this.experience = experience; + this.tools = tools; + this.items = items; + this.refundItems = refundItems; + } + + /** + * Gets the decoration on the given location. + * @param player The player. + * @return The decoration. + */ + public static Decoration getDecoration(Player player, Scenery object) { + Location l = object.getLocation(); + int z = l.getZ(); + if (HouseManager.isInDungeon(player)) { + z = 3; + } + Room room = player.getHouseManager().getRooms()[z][l.getChunkX()][l.getChunkY()]; + for (Hotspot h : room.getHotspots()) { + if (h.getCurrentX() == l.getChunkOffsetX() && h.getCurrentY() == l.getChunkOffsetY()) { + if (h.getDecorationIndex() != -1) { + Decoration deco = h.getHotspot().getDecorations()[h.getDecorationIndex()]; + if (deco.getObjectId(player.getHouseManager().getStyle()) == object.getId()) { + return deco; + } + } + } + } + return null; + } + + /** + * Gets a decoration for the given object id + * @param objectId - the object id of the built object + * @return the decoration or null + */ + public static Decoration forObjectId(int objectId) { + for (Decoration d : Decoration.values()) { + if (d.getObjectId() == objectId) { + return d; + } + } + return null; + } + + public static Decoration forName(String name) { + for (Decoration d : Decoration.values()) { + if (d.name().equals(name)) { + return d; + } + } + return null; + } + + /** + * Gets the amount of nails required for this hotspot. + * @return The amount of nails. + */ + public int getNailAmount() { + for (Item item : items) { + if (item.getId() == 960) { //1 nail per normal plank required. + return item.getAmount(); + } + } + return 0; + } + + /** + * Gets the objectId. + * @param style The current housing style. + * @return The objectId. + */ + public int getObjectId(HousingStyle style) { + if (objectIds != null) { + return objectIds[style.ordinal()]; + } + return objectId; + } + + /** + * Gets the objectId. + * @return The objectId. + */ + public int getObjectId() { + return objectId; + } + + /** + * Gets the level. + * @return The level. + */ + public int getLevel() { + return level; + } + + /** + * Gets the experience. + * @return The experience. + */ + public int getExperience() { + return experience; + } + + /** + * Gets the items. + * @return The items. + */ + public Item[] getItems() { + return items; + } + + /** + * Gets the refund items. + * @return The refund items. + */ + public Item[] getRefundItems() { + return refundItems; + } + + /** + * Gets the tools. + * @return The tools. + */ + public int[] getTools() { + return tools; + } + + /** + * Gets the interfaceItem. + * @return the interfaceItem + */ + public int getInterfaceItem() { + return interfaceItem; + } + + /** + * Gets the objectIds value. + * @return The objectIds. + */ + public int[] getObjectIds() { + return objectIds; + } + + /** + * If this node should be invisible to user build options + * @return true if so. + */ + public boolean isInvisibleNode() { + return invisibleNode; + } +} diff --git a/Server/src/main/content/global/skill/construction/EstateAgentDialogue.kt b/Server/src/main/content/global/skill/construction/EstateAgentDialogue.kt new file mode 100644 index 0000000..efba1ad --- /dev/null +++ b/Server/src/main/content/global/skill/construction/EstateAgentDialogue.kt @@ -0,0 +1,466 @@ +package content.global.skill.construction + +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.diary.DiaryType +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.plugin.Initializable +import org.rs09.consts.Items +import core.game.world.GameWorld.settings +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE + +/** + * Represents the estate agent dialogue. + * + * @author Woah + */ +@Initializable +class EstateAgentDialogue : core.game.dialogue.DialoguePlugin { + + /** + * Constructs a new `EstateAgentDialogue` `Object`. + */ + constructor() { + /** + * empty. + */ + } + + /** + * Constructs a new `EstateAgentDialogue` `Object`. + * + * @param player the player. + */ + constructor(player: Player?) : super(player) + + override fun newInstance(player: Player): core.game.dialogue.DialoguePlugin { + return EstateAgentDialogue(player) + } + + override fun open(vararg args: Any): Boolean { + npc = args[0] as NPC + npc("Hello. Welcome to the " + settings!!.name + " Housing Agency! What", "can I do for you?") + stage = START_DIALOGUE + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + + START_DIALOGUE -> { + if (player.houseManager.hasHouse()) { + options( + "Can you move my house please?", + "Can you redecorate my house please?", + "Could I have a Construction guidebook?", + "Tell me about houses.", + "Tell me about that skillcape you're wearing.") + stage = 1 + } else { + options("How can I get a house?", "Tell me about houses.") + stage = 2 + } + } + + 1 -> when (buttonId) { + 1 -> { + player("Can you move my house please?") + stage = 10 + } + 2 -> { + player("Can you redecorate my house please?") + stage = 30 + } + 3 -> { + player("Could I have a Construction guidebook?") + stage = 50 + } + 4 -> { + player("Tell me about houses!") + stage = 60 + } + 5 -> { + player("Tell me about that skillcape you're wearing!") + stage = if (core.game.global.Skillcape.isMaster(player, Skills.CONSTRUCTION)) 102 else 100 + } + } + + 2 -> when (buttonId) { + 1 -> { + player("How can I get a house?") + stage = 3 + } + 2 -> { + player("Tell me about houses.") + stage = 60 + } + } + + 3 -> { + npc( + "I can sell you a starting house in Rimmington for", + "1000 coins. As you increase your construction skill you", + "will be able to have your house moved to other areas", + "and redecorated in other styles." + ) + stage++ + } + + 4 -> { + npc("Do you want to buy a starter house?") + stage++ + } + + 5 -> { + options("Yes please!", "No thanks.") + stage++ + } + + 6 -> when (buttonId) { + 1 -> { + player("Yes please!") + stage = 7 + } + 2 -> { + player("No thanks.") + stage = END_DIALOGUE + } + } + + 7 -> { + if (player.inventory.contains(995, 1000)) { + player.inventory.remove(Item(Items.COINS_995, 1000)) + player.houseManager.createNewHouseAt(HouseLocation.RIMMINGTON) + npc( + "Thank you. Go through the Rimmington house portal", + "and you will find your house ready for you to start", + "building in it." + ) + } else { + npc("You don't have enough money to buy a house,", "come back when you can afford one.") + } + stage = END_DIALOGUE + } + + 10 -> { + npc("Certainly. Where would you like it moved to?") + stage++ + } + + 11 -> { + options( + "Rimmington (5,000)", + "Taverley (5,000)", + "Pollnivneach (7,500)", + "Rellekka (10,000)", + "More..." ) + stage++ + } + + 12 -> when (buttonId) { + 1 -> { + player("To Rimmington please!") + stage = 15 + } + 2 -> { + player("To Taverly please!") + stage = 16 + } + 3 -> { + player("To Pollnivneach please!") + stage = 17 + } + 4 -> { + player("To Rellekka please!") + stage = 18 + } + 5 -> { + options("Brimhaven (15,000)", "Yanille (25,000)", "...Previous", "Back") + stage = 13 + } + } + + 13 -> when (buttonId) { + 1 -> { + player("To Brimhaven please!") + stage = 19 + } + 2 -> { + player("To Yanille please!") + stage = 20 + } + 3 -> { + options( + "Rimmington (5,000)", + "Taverley (5,000)", + "Pollnivneach (7,500)", + "Rellekka (10,000)", + "More..." + ) + stage = 12 + } + } + + 15 -> configureMove(HouseLocation.RIMMINGTON) + 16 -> configureMove(HouseLocation.TAVERLY) + 17 -> configureMove(HouseLocation.POLLNIVNEACH) + 18 -> configureMove(HouseLocation.RELLEKKA) + 19 -> configureMove(HouseLocation.BRIMHAVEN) + 20 -> configureMove(HouseLocation.YANILLE) + 30 -> { + npc( + "Certainly. My magic can rebuild the house in a", + "completely new style! What style would you like?" ) + stage++ + } + 31 -> { + options( + "Basic wood (5,000)", + "Basic stone (5,000)", + "Whitewashed stone (7,500)", + "Fremennik-style wood (10,000)", + "More..." + ) + stage++ + } + 32 -> when (buttonId) { + 1 -> { + player("Basic wood please!") + stage = 35 + } + 2 -> { + player("Basic stone please!") + stage = 36 + } + 3 -> { + player("Whitewashed stone please!") + stage = 37 + } + 4 -> { + player("Fremennik-style wood please!") + stage = 38 + } + 5 -> { + options("Tropical wood (15,000)", "Fancy stone (25,000)", "Previous...", "Back") + stage = 33 + } + } + 33 -> when (buttonId) { + 1 -> { + player("Tropical wood please!") + stage = 39 + } + 2 -> { + player("Fancy stone please!") + stage = 40 + } + 3 -> { + options( + "Basic wood (5,000)", + "Basic stone (5,000)", + "Whitewashed stone (7,500)", + "Fremennik-style wood (10,000)", + "More..." + ) + stage = 32 + } + } + + 35 -> redecorate(HousingStyle.BASIC_WOOD) + 36 -> redecorate(HousingStyle.BASIC_STONE) + 37 -> redecorate(HousingStyle.WHITEWASHED_STONE) + 38 -> redecorate(HousingStyle.FREMENNIK_STYLE_WOOD) + 39 -> redecorate(HousingStyle.TROPICAL_WOOD) + 40 -> redecorate(HousingStyle.FANCY_STONE) + + 50 -> { + if (player.hasItem(CONSTRUCTION_GUIDE_8463)) { + npc("You've already got one!") + } else { + npc("Certainly.") + player.inventory.add(CONSTRUCTION_GUIDE_8463) + } + stage = END_DIALOGUE + } + 60 -> { + npc( + "It all came out of the wizards' experiments. They found", + "a way to fold space, so that they could pack many", + "acres of land into an area only a foot across." + ) + stage++ + } + 61 -> { + npc( + "They created several folded-space regions across", + "" + settings!!.name + ". Each one contains hundreds of small plots", + "where people can build houses." + ) + stage++ + } + 62 -> { + player("Ah, so that's how everyone can have a house without", "them cluttering up the world!") + stage++ + } + 63 -> { + npc( + "Quite. The wizards didn't want to get bogged down", + "in the business side of things so they ", + "hired me to sell the houses." + ) + stage++ + } + 64 -> { + npc( + "There are various other people across " + settings!!.name + " who can", + "help you furnish your house. You should start buying", + "planks from the sawmill operator in Varrock." + ) + stage = END_DIALOGUE + } + 100 -> { + npc( + "As you may know, skillcapes are only available to masters", + "in a skill. I have spent my entire life building houses and", + "now I spend my time selling them! As a sign of my abilites", + "I wear this Skillcape of Construction. If you ever have" + ) + stage = 101 + } + 101 -> { + npc( + "enough skill to build a demonic throne, come and talk to", + "me and I'll sell you a skillcape like mine." + ) + stage = END_DIALOGUE + } + 102 -> { + interpreter.sendDialogues( + npc, + core.game.dialogue.FacialExpression.JOLLY, + "I see you have recently achieved 99 construction.", + "Would you like to buy a cape for 99,0000 gp?" + ) + stage++ + } + 103 -> { + options("Yes, I'll pay the 99k", "No thanks, maybe later.") + stage++ + } + 104 -> when (buttonId) { + 1 -> { + if (core.game.global.Skillcape.purchase(player, Skills.CONSTRUCTION)) { + npc("Here you go lad, enjoy!") + } + stage = END_DIALOGUE + } + 2 -> { + player("No thanks, maybe later.") + stage = END_DIALOGUE + } + } + END_DIALOGUE -> end() + } + return true + } + + /** + * Configures the move. + * + * @param location The house location. + */ + private fun configureMove(location: HouseLocation) { + //Achievement completion checks + val completedVarrockHouseMove = player.achievementDiaryManager.hasCompletedTask(DiaryType.VARROCK,0,11) + when { + //Player does not have required construction level + !location.hasLevel(player) -> { + npc( + "I'm afraid you don't have a high enough construction", + "level to move there. You need to have level " + location.levelRequirement + "." ) + stage = 11 + return + } + //Player's house location is already where they selected + location == player.houseManager.location -> { + npc("Your house is already there!") + stage = 11 + return + } + //Player does not have enough coins to buy a house move + !player.inventory.contains(Items.COINS_995, location.cost) -> { + npc("Hmph. Come back when you have " + location.cost + " coins.") + stage = END_DIALOGUE + return + } + //Player meets all above requirements + check for achievement unlocks + else -> { + player.inventory.remove(Item(Items.COINS_995, location.cost)) + player.houseManager.location = location + npc("Your house has been moved to " + location.getName() + ".") + + if (player.location.isInRegion(REGION_VARROCK_NE) && !completedVarrockHouseMove) { + + player.achievementDiaryManager.finishTask(player, DiaryType.VARROCK, 0, 11) + } + stage = END_DIALOGUE + } + } + } + + /** + * Redecorates the player's house. + * + * @param style The house style. + */ + private fun redecorate(style: HousingStyle) { + //Achievement completion checks + val completedVarrockHouseRedecorate = player.achievementDiaryManager.hasCompletedTask(DiaryType.VARROCK,2,7) + when { + //Player does not have required construction level + !style.hasLevel(player) -> { + npc("You need a Construction level of " + style.level + " to buy this style.") + stage = 31 + return + } + //Player's house location is already where they selected + style == player.houseManager.style -> { + npc("Your house is already in that style!") + stage = 31 + return + } + + //Player does not have enough coins to buy a house move + !player.inventory.contains(Items.COINS_995, style.cost) -> { + npc("Hmph. Come back when you have " + style.cost + " coins.") + stage = END_DIALOGUE + return + } + + //Player meets all above requirements + check for achievement unlocks + else -> { + player.inventory.remove(Item(Items.COINS_995, style.cost)) + player.houseManager.redecorate(style) + npc("Your house has been redecorated.") + + // Give your player-owned house a fancy stone or tropical wood

finish at the Varrock estate agent's + if (player.location.isInRegion(REGION_VARROCK_NE) && !completedVarrockHouseRedecorate) { + player.achievementDiaryManager.finishTask(player, DiaryType.VARROCK, 2, 7) + } + stage = END_DIALOGUE + } + } + } + + override fun getIds(): IntArray { + return intArrayOf(4247) + } + + //Items + private val CONSTRUCTION_GUIDE_8463 = Item(Items.CONSTRUCTION_GUIDE_8463, 1) + + //Region to check + private val REGION_VARROCK_NE = 12854 +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/Hotspot.kt b/Server/src/main/content/global/skill/construction/Hotspot.kt new file mode 100644 index 0000000..dd245e7 --- /dev/null +++ b/Server/src/main/content/global/skill/construction/Hotspot.kt @@ -0,0 +1,58 @@ +package content.global.skill.construction + +/** + * Represents a hotspot. + * @author Emperor + */ +class Hotspot (val hotspot: BuildHotspot, val chunkX: Int, val chunkY: Int, var chunkX2: Int, var chunkY2: Int) { + + constructor(hotspot: BuildHotspot, chunkX: Int, chunkY: Int) : this(hotspot,chunkX,chunkY,-1,-1) + + /** + * The current chunk x coordinate. + */ + var currentX: Int + /** + * Gets the currentY value. + * @return The currentY. + */ + /** + * Sets the currentY value. + * @param currentY The currentY to set. + */ + /** + * The chunk y coordinate. + */ + var currentY: Int + /** + * Gets the decorationIndex. + * @return The decorationIndex. + */ + /** + * Sets the decorationIndex. + * @param decorationIndex The decorationIndex to set. + */ + /** + * The current decoration index. + */ + var decorationIndex = -1 + + /** + * Copies the hotspot. + * @return The hotspot. + */ + fun copy(): Hotspot { + return Hotspot(hotspot, chunkX, chunkY, chunkX2, chunkY2) + } + + /** + * Constructs a new `Hotspot` `Object`. + * @param hotspot The hotspot. + * @param chunkX The chunk x-coordinate. + * @param chunkY The chunk y-coordinate. + */ + init { + currentX = chunkX + currentY = chunkY + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/HouseLocation.java b/Server/src/main/content/global/skill/construction/HouseLocation.java new file mode 100644 index 0000000..ac55b00 --- /dev/null +++ b/Server/src/main/content/global/skill/construction/HouseLocation.java @@ -0,0 +1,164 @@ +package content.global.skill.construction; + + +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.tools.StringUtils; + +/** + * The house locations. + * @author Emperor + */ +@SuppressWarnings("all") +public enum HouseLocation { + + //Nowhere is used for players who do not have a house + NOWHERE(-1, null, 0, 0), + + RIMMINGTON(15478, Location.create(2953, 3224, 0), 5000, 1), + + TAVERLY(15477, Location.create(2893, 3465, 0), 5000, 10), + + POLLNIVNEACH(15479, Location.create(3340, 3003, 0), 7500, 20), + + RELLEKKA(15480, Location.create(2670, 3631, 0), 10000, 30), + + BRIMHAVEN(15481, Location.create(2757, 3178, 0), 15000, 40), + + YANILLE(15482, Location.create(2544, 3096, 0), 25000, 50); + + //custom island thing that previous source users had. + //WHITERIDGE(43832, Location.create(3965, 3546, 0), 100_000, 60); + + /** + * The portal object id for this location. + */ + private final int portalId; + + /** + * The exit location. + */ + private final Location exitLocation; + + /** + * The cost to move + */ + private final int cost; + + /** + * Level requirement + */ + private final int levelRequirement; + + /** + * The house options + */ + //public static TabbedOption HOUSE_OPTIONS = new TabbedOption("House Locations", "Select an Option"); + + /** + * Sets up a page action tabbed option + */ + static { + /*int index = 0; + PageAction[] pageActions = new PageAction[5]; + for (HouseLocation hl : values()) { + if (hl == HouseLocation.NOWHERE || (hl == HouseLocation.WHITERIDGE && GameWorld.getSettings().isDeadmanMode())) + continue; + if (index > 4) { + index = 0; + HOUSE_OPTIONS.addPage(new Page(pageActions)); + pageActions = new PageAction[5]; + } + pageActions[index++] = new PageAction(hl.name() + " - " + hl.cost + "gp") { + @Override + public boolean run(Player player) { + if (player.getHouseManager().getLocation() == hl) { + player.sendMessage("Your house already resides in " + hl.name() + "!"); + return true; + } + if (player.getSkills().hasLevel(Skills.CONSTRUCTION, hl.levelRequirement)) { + if (player.getInventory().contains(995, hl.cost)) { + player.getInventory().remove(new Item(Items.COINS_995, hl.cost)); + player.getHouseManager().setLocation(hl); + player.sendMessage("You have changed your house location to " + hl.name() + "!"); + } else { + player.sendMessage("You need " + hl.cost + "gp in order to move there!"); + } + } else { + player.sendMessage("You need a construction level of " + hl.levelRequirement + " to move there!"); + } + return true; + } + }; + } + if (pageActions[0] != null) { + HOUSE_OPTIONS.addPage(new Page(pageActions)); + }*/ + } + + /** + * Checks if the player has the level. + * + * @param player the player. + * @return {@code True} if so. + */ + public boolean hasLevel(Player player) { + return player.getSkills().getStaticLevel(Skills.CONSTRUCTION) >= levelRequirement; + } + + /** + * Constructs a new {@code HouseLocation} {@code Object} + * @param portalId The portal id. + * @param exitLocation The exit location. + */ + private HouseLocation(int portalId, Location exitLocation, int cost, int levelRequirement) { + this.portalId = portalId; + this.exitLocation = exitLocation; + this.cost = cost; + this.levelRequirement = levelRequirement; + } + /** + * Gets the name formatted. + * + * @return the formatted name. + */ + public String getName() { + return StringUtils.formatDisplayName(name().toLowerCase()); + } + + + /** + * Gets the portalId. + * @return the portalId + */ + public int getPortalId() { + return portalId; + } + + /** + * Gets the exitLocation. + * @return the exitLocation + */ + public Location getExitLocation() { + return exitLocation; + } + + /** + * Gets the cost to move to here + * @return the cost + */ + public int getCost() { + return cost; + } + + /** + * Gets the level requirement to move to here + * @return the level requirement + */ + public int getLevelRequirement() { + return levelRequirement; + } + + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/HouseManager.java b/Server/src/main/content/global/skill/construction/HouseManager.java new file mode 100644 index 0000000..01a37f3 --- /dev/null +++ b/Server/src/main/content/global/skill/construction/HouseManager.java @@ -0,0 +1,855 @@ +package content.global.skill.construction; +import core.api.regionspec.RegionSpecification; +import core.api.regionspec.contracts.FillChunkContract; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.player.Player; +import core.game.node.entity.skill.Skills; +import core.game.node.scenery.Scenery; +import core.game.system.task.Pulse; +import core.game.world.map.*; +import core.game.world.map.build.DynamicRegion; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneBuilder; +import core.game.world.update.flag.context.Animation; +import core.tools.Log; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import core.game.world.GameWorld; +import org.rs09.consts.Sounds; + +import java.awt.*; + +import static core.api.ContentAPIKt.*; +import static core.api.regionspec.RegionSpecificationKt.fillWith; +import static core.api.regionspec.RegionSpecificationKt.using; + + +/** + * Manages the player's house. + * @author Emperor + * + */ +public final class HouseManager { + + /** + * The current region. + */ + private DynamicRegion houseRegion; + + /** + * The current region. + */ + private DynamicRegion dungeonRegion; + + /** + * The house location. + */ + private HouseLocation location = HouseLocation.NOWHERE; + + /** + * The house style. + */ + private HousingStyle style = HousingStyle.BASIC_WOOD; + + /** + * The house zone. + */ + private HouseZone zone = new HouseZone(this); + + /** + * The player's house rooms. + */ + private final Room[][][] rooms = new Room[4][8][8]; + + /** + * If building mode is enabled. + */ + private boolean buildingMode; + + /** + * If the player has used the portal to lock their house. + */ + private boolean locked; + + /** + * The player's servant. + */ + private Servant servant; + + /** + * If the house has a dungeon. + */ + private boolean hasDungeon; + + /** + * The player's crest. + */ + private CrestType crest = CrestType.ASGARNIA; + + /** + * Constructs a new {@code HouseManager} {@code Object}. + */ + public HouseManager() { + /* + * empty. + */ + } + + + public void parse(JSONObject data){ + location = HouseLocation.values()[Integer.parseInt( data.get("location").toString())]; + style = HousingStyle.values()[Integer.parseInt( data.get("style").toString())]; + Object servRaw = data.get("servant"); + if(servRaw != null){ + servant = Servant.parse((JSONObject) servRaw); + } + JSONArray rArray = (JSONArray) data.get("rooms"); + for(int i = 0; i < rArray.size(); i++){ + JSONObject rm = (JSONObject) rArray.get(i); + int z = Integer.parseInt(rm.get("z").toString()); + int x = Integer.parseInt(rm.get("x").toString()); + int y = Integer.parseInt(rm.get("y").toString()); + if(z == 3) + hasDungeon = true; + Room room = rooms[z][x][y] = new Room(RoomProperties.values()[Integer.parseInt(rm.get("properties").toString())]); + room.configure(style); + room.setRotation(Direction.get(Integer.parseInt(rm.get("rotation").toString()))); + JSONArray hotspots = (JSONArray) rm.get("hotspots"); + for(int j = 0; j < hotspots.size(); j++){ + JSONObject spot = (JSONObject) hotspots.get(j); + room.getHotspots()[Integer.parseInt(spot.get("hotspotIndex").toString())].setDecorationIndex(Integer.parseInt(spot.get("decorationIndex").toString())); + } + } + } + + /** + * Prepares for entering the player's house. + * @param player + * @param buildingMode + */ + public void preEnter(final Player player, boolean buildingMode) { + if (this.buildingMode != buildingMode || !isLoaded()) { + this.buildingMode = buildingMode; + construct(); + } + player.setAttribute("poh_entry", HouseManager.this); + player.setAttribute("/save:original-loc", location.getExitLocation()); + player.lock(1); + player.debug("House location: " + houseRegion.getBaseLocation() + ", entry: " + getEnterLocation()); + } + + /** + * Enters the player's house and plays the ding sound. + * @param player + * @param buildingMode + */ + public void enter(final Player player, boolean buildingMode) { + preEnter(player, buildingMode); + player.getProperties().setTeleportLocation(getEnterLocation()); + openLoadInterface(player); + postEnter(player, buildingMode); + } + + /** + * Performs post-house-enter administration. + * @param player + * @param buildingMode + */ + public void postEnter(final Player player, boolean buildingMode) { + checkForAndSpawnServant(player); + updateVarbits(player, buildingMode); + unlockMusicTrack(player); + } + + private void openLoadInterface(Player player) { + player.getInterfaceManager().openComponent(399); + playAudio(player, Sounds.POH_TELEPORT_984); + submitCloseLoadInterfacePulse(player); + } + + private void submitCloseLoadInterfacePulse(Player player) { + GameWorld.getPulser().submit(new Pulse(1, player) { + @Override + public boolean pulse() { + player.getInterfaceManager().close(); + return true; + } + }); + } + + private void checkForAndSpawnServant(Player player) { + if(!hasServant()) return; + + GameWorld.getPulser().submit(new Pulse(1, player) { + @Override + public boolean pulse() { + spawnServant(); + if (servant.isGreet()){ + player.getDialogueInterpreter().sendDialogues(servant.getType().getId(), servant.getType().getId() == 4243 ? FacialExpression.HAPPY : null, "Welcome."); + } + return true; + } + }); + } + + private void updateVarbits(Player player, boolean build) { + setVarp(player, 261, build ? 1 : 0); + setVarp(player, 262, getRoomAmount()); + } + + private void unlockMusicTrack(Player player) { + player.getMusicPlayer().unlock(454, true); + } + + /** + * Leaves this house through the portal. + * @param player The player leaving. + */ + public static void leave(Player player) { + HouseManager house = player.getAttribute("poh_entry", player.getHouseManager()); + if (house.getHouseRegion() == null){ + return; + } + if (house.isInHouse(player)) { + player.animate(Animation.RESET); + player.getProperties().setTeleportLocation(house.location.getExitLocation()); + } + } + + /** + * Toggles the building mode. + * @param player The house owner. + * @param enable If the building mode should be enabled. + */ + public void toggleBuildingMode(Player player, boolean enable) { + if (!isInHouse(player)) { + player.getPacketDispatch().sendMessage("Building mode really only helps if you're in a house."); + return; + } + if (buildingMode != enable) { + if (enable) { + expelGuests(player); + } + enter(player, enable); + player.getPacketDispatch().sendMessage("Building mode is now " + (buildingMode ? "on." : "off.")); + } + } + + /** + * Reloads the house. + * @param player The player. + * @param buildingMode If building mode should be enabled. + * NOTE: I think we should avoid this method, it might be causing some issues. It's actually really suspicious... + */ + public void reload(Player player, boolean buildingMode) { + int diffX = player.getLocation().getLocalX(); + int diffY = player.getLocation().getLocalY(); + int diffZ = player.getLocation().getZ(); + boolean inDungeon = player.getViewport().getRegion() == dungeonRegion; + this.buildingMode = buildingMode; + construct(); + Location newLoc = (dungeonRegion == null ? houseRegion : (inDungeon ? dungeonRegion : houseRegion)).getBaseLocation().transform(diffX,diffY,diffZ); + player.getProperties().setTeleportLocation(newLoc); + } + + /** + * Expels the guests from the house. + * @param player The house owner. + */ + public void expelGuests(Player player) { + if (isLoaded()) { + for (RegionPlane plane : houseRegion.getPlanes()) { + for (Player p : plane.getPlayers()) { + if (p != player) { + leave(p); + } + } + } + if (dungeonRegion != null) { + for (RegionPlane plane : dungeonRegion.getPlanes()) { + for (Player p : plane.getPlayers()) { + if (p != player) { + leave(p); + } + } + } + } + } + } + + /** + * Gets the entering location. + * @return The entering location. + */ + public Location getEnterLocation() { + if (houseRegion == null) { + log(this.getClass(), Log.ERR, "House wasn't constructed yet!"); + return null; + } + for (int x = 0; x < 8; x++) { + for (int y = 0; y < 8; y++) { + Room room = rooms[0][x][y]; + if (room != null && (room.getProperties() == RoomProperties.GARDEN || room.getProperties() == RoomProperties.FORMAL_GARDEN)) { + for (Hotspot h : room.getHotspots()) { + if (h.getDecorationIndex() > -1) { + Decoration d = h.getHotspot().getDecorations()[h.getDecorationIndex()]; + if (d == Decoration.PORTAL) { + return houseRegion.getBaseLocation().transform(x * 8 + h.getChunkX(), y * 8 + h.getChunkY() + 2, 0); + } + } + } + } + } + } + return null; + } + + /** + * Redecorates the house. + * @param style The new style. + */ + public void redecorate(HousingStyle style) { + this.style = style; + for (int z = 0; z < 4; z++) { + for (int x = 0; x < 8; x++) { + for (int y = 0; y < 8; y++) { + Room room = rooms[z][x][y]; + if (room != null) { + room.decorate(style); + } + } + } + } + } + + /** + * Clears all the rooms (Including portal room!). + */ + @Deprecated + public void clearRooms() { + for (int z = 0; z < 4; z++) { + for (int x = 0; x < 8; x++) { + for (int y = 0; y < 8; y++) { + rooms[z][x][y] = null; + } + } + } + } + + /** + * Creates the default house. + * @param location The house location. + */ + public void createNewHouseAt(HouseLocation location) { + clearRooms(); + Room room = rooms[0][4][3] = new Room(RoomProperties.GARDEN); + room.configure(style); + room.getHotspots()[0].setDecorationIndex(0); + this.location = location; + } + + /** + * Constructs the dynamic region for the house. + * @return The region. + */ + public DynamicRegion construct() { + houseRegion = getPreparedRegion(); + configureRoofs(); + prepareHouseChunks(style, houseRegion, buildingMode, rooms); + houseRegion.flagActive(); + + if (hasDungeon()) { + dungeonRegion = getPreparedRegion(); + prepareDungeonChunks(style, dungeonRegion, houseRegion, buildingMode, rooms[3]); + dungeonRegion.flagActive(); + } + + ZoneBuilder.configure(zone); + return houseRegion; + } + + private DynamicRegion getPreparedRegion() { + ZoneBorders borders = DynamicRegion.reserveArea(8,8); + DynamicRegion region = new DynamicRegion(-1, borders.getSouthWestX() >> 6, borders.getSouthWestY() >> 6); + region.setBorders(borders); + region.setUpdateAllPlanes(true); + region.setBuild(true); + RegionManager.addRegion(region.getId(), region); + return region; + } + + private class RoomLoadContract extends FillChunkContract { + Room[][][] rooms; + HouseManager manager; + boolean buildingMode; + + public RoomLoadContract(HouseManager manager, boolean buildingMode, Room[][][] rooms) { + this.rooms = rooms; + this.manager = manager; + this.buildingMode = buildingMode; + } + + @Override + public BuildRegionChunk getChunk(int x, int y, int plane, @NotNull DynamicRegion dyn) { + return rooms[plane][x][y].getChunk().copy(dyn.getPlanes()[plane]); + } + + @Override + public void afterSetting(@Nullable BuildRegionChunk chunk, int x, int y, int plane, @NotNull DynamicRegion dyn) { + rooms[plane][x][y].loadDecorations(dyn != manager.dungeonRegion ? plane : 3, chunk, manager); + } + } + + private void prepareHouseChunks(HousingStyle style, DynamicRegion target, boolean buildingMode, Room[][][] rooms) { + Region from = RegionManager.forId(style.getRegionId()); + Region.load(from, true); + RegionChunk defaultChunk = from.getPlanes()[style.getPlane()].getRegionChunk(1, 0); + RegionChunk defaultSkyChunk = from.getPlanes()[1].getRegionChunk(0,0); + + RoomLoadContract loadRooms = new RoomLoadContract(this, buildingMode, rooms); + RegionSpecification spec = new RegionSpecification( + using(target), + fillWith(defaultChunk) + .from(from) + .onPlanes(0), + fillWith(defaultSkyChunk) + .from(from) + .onPlanes(1,2,3), + loadRooms + .from(from) + .onPlanes(0,1,2) + .onCondition((destX,destY,plane) -> rooms[plane][destX][destY] != null) + ); + + spec.build(); + } + + private void prepareDungeonChunks(HousingStyle style, DynamicRegion target, DynamicRegion house, boolean buildingMode, Room[][] rooms) { + Region from = RegionManager.forId(style.getRegionId()); + Region.load(from, true); + RegionChunk defaultChunk = from.getPlanes()[style.getPlane()].getRegionChunk(3, 0); + + RoomLoadContract loadRooms = new RoomLoadContract(this, buildingMode, new Room[][][]{rooms}); + RegionSpecification spec = new RegionSpecification( + using(target), + fillWith((x,y,plane,region) -> buildingMode ? null : defaultChunk) + .from(from) + .onPlanes(0) + .onCondition((destX, destY, plane) -> rooms[destX][destY] == null), + loadRooms + .from(from) + .onPlanes(0) + .onCondition((destX, destY, plane) -> rooms[destX][destY] != null) + ); + + spec.build(); + house.link(target); + } + + /** + * Configures the rooftops. + */ + public void configureRoofs() { +// boolean[][][] roofs = new boolean[2][8][8]; +// for (int x = 0; x < 8; x++) { +// for (int y = 0; y < 8; y++) { +// Room room = rooms[0][x][y]; +// if (room != null && room.getProperties().isChamber()) { +// room = rooms[1][x][y]; +// int z = 1; +// if (room != null && room.getProperties().isChamber()) { +// z = 2; +// } +// if (x > 0 ) +// } +// } +// } + } + + /** + * Gets the current room plane. + * @param l The location. + * @return The plane of the room. + */ + public Room getRoom(Location l) { + int z = l.getZ(); + if (dungeonRegion != null && l.getRegionId() == dungeonRegion.getId()) { + z = 3; + } + return rooms[z][l.getChunkX()][l.getChunkY()]; + } + + /** + * Gets the hotspot for the given object. + * @param object The object. + * @return The hotspot. + */ + public Hotspot getHotspot(Scenery object) { + Room room = getRoom(object.getLocation()); + if (room == null) { + return null; + } + int chunkX = object.getLocation().getChunkOffsetX(); + int chunkY = object.getLocation().getChunkOffsetY(); + switch(room.getRotation()){ + case WEST: { + int tempChunk = chunkY; + chunkY = 7 - chunkX; + chunkX = tempChunk; + break; + } + case EAST: { + //x = y, y = x, x = 7 - y + int tempChunk = chunkX; + chunkX = 7 - chunkY; + chunkY = tempChunk; + break; + } + case SOUTH: { + chunkX = 7 - chunkX; + chunkY = 7 - chunkY; + break; + } + default: { + + } + } + for (Hotspot h : room.getHotspots()) { + if ((h.getChunkX() == chunkX || h.getChunkX2() == chunkX) && (h.getChunkY() == chunkY || h.getChunkY2() == chunkY) && h.getHotspot().getObjectId(style) == object.getId()) { + return h; + } + } + return null; + } + + /** + * Checks if a room exists on the given location. + * @param z The plane. + * @param roomX The room x-coordinate. + * @param roomY The room y-coordinate. + * @return {@code True} if so. + */ + public boolean hasRoomAt(int z, int roomX, int roomY) { + Room room = rooms[z][roomX][roomY]; + return room != null && !room.getProperties().isRoof(); + } + + /** + * Enters the dungeon. + * @param player The player. + */ + public void enterDungeon(Player player) { + if (!hasDungeon()) { + return; + } + int diffX = player.getLocation().getLocalX(); + int diffY = player.getLocation().getLocalY(); + player.getProperties().setTeleportLocation(dungeonRegion.getBaseLocation().transform(diffX, diffY, 0)); + } + + /** + * Checks if an exit exists on the given room. + * @param roomX The x-coordinate of the room. + * @param roomY The y-coordinate of the room. + * @param direction The exit direction. + * @return {@code True} if so. + */ + public boolean hasExit(int z, int roomX, int roomY, Direction direction) { + Room room = rooms[z][roomX][roomY]; + int index = (direction.toInteger() + 3) % 4; + return room != null && room.getExits()[index]; + } + + /** + * Gets the amount of rooms. + * @return The amount of rooms. + */ + public int getRoomAmount() { + int count = 0; + for (int z = 0; z < 4; z++) { + for (int x = 0; x < 8; x++) { + for (int y = 0; y < 8; y++) { + Room r = rooms[z][x][y]; + if (r != null && !r.getProperties().isRoof()) { + count++; + } + } + } + } + return count; + } + + /** + * Gets the amount of portals available. + * @return The amount of portals. + */ + public int getPortalAmount() { + int count = 0; + for (int x = 0; x < 8; x++) { + for (int y = 0; y < 8; y++) { + Room room = rooms[0][x][y]; + if (room != null && (room.getProperties() == RoomProperties.GARDEN + || room.getProperties() == RoomProperties.FORMAL_GARDEN) && room.getHotspots()[0].getDecorationIndex() == 0) { + count++; + } + } + } + return count; + } + + /** + * Gets the current house boundaries. + * @return The boundaries. + */ + public Rectangle getBoundaries() { + int startX = 99; + int startY = 99; + int endX = 0; + int endY = 0; + for (int x = 0; x < 8; x++) { + for (int y = 0; y < 8; y++) { + if (rooms[0][x][y] != null) { + if (x < startX) startX = x; + if (y < startY) startY = y; + if (x > endX) endX = x; + if (y > endY) endY = y; + } + } + } + return new Rectangle(startX, startY, (endX - startX) + 1, (endY - startY) + 1); + } + + /** + * Gets the maximum dimension for the house boundaries. + * @param player The player. + * @return The dimension value (value X value = dimension) + */ + public int getMaximumDimension(Player player) { + int level = player.getSkills().getStaticLevel(Skills.CONSTRUCTION); + if (level >= 60) { + return 7; + } + if (level >= 45) { + return 6; + } + if (level >= 30) { + return 5; + } + if (level >= 15) { + return 4; + } + return 3; + } + + /** + * Gets the maximum amount of rooms available for the player. + * @param player The player. + * @return The maximum amount of rooms. + */ + public int getMaximumRooms(Player player) { + int level = player.getSkills().getStaticLevel(Skills.CONSTRUCTION); + if (level >= 99) return 30; + if (level >= 96) return 29; + if (level >= 92) return 28; + if (level >= 86) return 27; + if (level >= 80) return 26; + if (level >= 74) return 25; + if (level >= 68) return 24; + if (level >= 62) return 23; + if (level >= 56) return 22; + if (level >= 50) return 21; + return 20; + } + + /** + * Spawns the servant inside the player's home. + */ + private void spawnServant(){ + servant.setLocation(getEnterLocation()); + servant.setWalkRadius(getRoomAmount() * 2); + servant.setWalks(true); + servant.init(); + } + + /** + * Checks if the player has a servant. + * @return {@code True} if so. + */ + public boolean hasServant() { + return servant != null; + } + + /** + * Checks if the player is in his own house (or dungeon). + * @param player The player. + * @return {@code True} if so. + */ + public boolean isInHouse(Player player) { + return isLoaded() && (player.getViewport().getRegion() == houseRegion || player.getViewport().getRegion() == dungeonRegion); + } + + /** + * Checks if the player is in his dungeon. + * @param player The player. + * @return {@code True} if so. + */ + public static boolean isInDungeon(Player player) { + return player.getViewport().getRegion() == player.getHouseManager().dungeonRegion; + } + + /** + * Checks if the house region was constructed and active. + * @return {@code True} if an active region for the house exists. + */ + //public boolean isLoaded() { + // return (houseRegion != null) || (dungeonRegion != null); + //} + public boolean isLoaded() { + return (houseRegion != null && houseRegion.isActive()) || (dungeonRegion != null && dungeonRegion.isActive()); + } + + /** + * Gets the hasHouse. + * @return The hasHouse. + */ + public boolean hasHouse() { + return location != HouseLocation.NOWHERE; + } + + /** + * Checks if the house has a dungeon. + * @return {@code True} if so. + */ + public boolean hasDungeon() { + return hasDungeon; + } + + /** + * Sets the has dungeon value. + * @param hasDungeon If the house has a dungeon. + */ + public void setHasDungeon(boolean hasDungeon) { + this.hasDungeon = hasDungeon; + } + + /** + * Gets the rooms. + * @return The rooms. + */ + public Room[][][] getRooms() { + return rooms; + } + + /** + * Gets the location. + * @return The location. + */ + public HouseLocation getLocation() { + return location; + } + + /** + * Sets the location. + * @param location The location to set. + */ + public void setLocation(HouseLocation location) { + this.location = location; + } + + /** + * Checks if the building mode is enabled. + * @return {@code True} if so. + */ + public boolean isBuildingMode() { + return buildingMode; + } + + /** + * Checks if the player has locked their house. + * @return {@code True} if so. + */ + public boolean isLocked() { + return locked; + } + + /** + * Sets the house to locked. + * @param locked true or false + */ + public void setLocked(boolean locked) { + this.locked = locked; + } + + /** + * Gets the region. + * @return The region. + */ + public DynamicRegion getHouseRegion() { + return houseRegion; + } + + /** + * Gets the dungeon region. + * @return The dungeon region. + */ + public Region getDungeonRegion() { + return dungeonRegion; + } + + /** + * Gets the style. + * @return the style + */ + public HousingStyle getStyle() { + return style; + } + + /** + * Sets the style. + * @param style the style to set. + */ + public void setStyle(HousingStyle style) { + this.style = style; + } + + /** + * Gets the player's servant + * @return the servant. + */ + public Servant getServant(){ + return servant; + } + + /** + * Sets the player's servant + * @param servant The servant to set. + */ + public void setServant(Servant servant){ + this.servant = servant; + } + + /** + * Gets the crest value. + * @return The crest. + */ + public CrestType getCrest() { + return crest; + } + + /** + * Sets the crest value. + * @param crest The crest to set. + */ + public void setCrest(CrestType crest) { + this.crest = crest; + } + + /** + * @return the zone + */ + public HouseZone getZone() { + return zone; + } +} diff --git a/Server/src/main/content/global/skill/construction/HouseZone.java b/Server/src/main/content/global/skill/construction/HouseZone.java new file mode 100644 index 0000000..ccd426c --- /dev/null +++ b/Server/src/main/content/global/skill/construction/HouseZone.java @@ -0,0 +1,124 @@ +package content.global.skill.construction; + + +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.world.map.build.DynamicRegion; +import core.game.world.map.zone.MapZone; +import core.game.world.map.RegionManager; +import core.game.world.map.Region; +import core.game.system.task.Pulse; +import core.game.world.map.zone.ZoneRestriction; + +import static core.api.ContentAPIKt.*; + +/** + * Handles the player owned house zone. + * + * @author Emperor + */ +public final class HouseZone extends MapZone { + + /** + * The house manager. + */ + private HouseManager house; + + /** + * The previous house region id. + */ + private int previousRegion = -1; + + /** + * The previous dungeon region id. + */ + private int previousDungeon = -1; + + /** + * Constructs the house zone object. + */ + public HouseZone(HouseManager house) { + super("poh-zone" + house, true); + this.house = house; + } + + @Override + public void configure() { + unregisterOldRegions(); + registerRegion(house.getHouseRegion().getId()); + if (house.getDungeonRegion() != null) { + registerRegion(house.getDungeonRegion().getId()); + } + } + + private void unregisterOldRegions() { + if (previousRegion != -1) { + unregisterRegion(previousRegion); + } + if (previousDungeon != -1) { + unregisterRegion(previousDungeon); + } + } + + @Override + public boolean enter(Entity e) { + if (e instanceof Player) { + Player pl = (Player) e; + if (house == pl.getHouseManager()) { + previousRegion = house.getHouseRegion().getId(); + if (house.getDungeonRegion() != null) + previousDungeon = house.getDungeonRegion().getId(); + } + registerLogoutListener(pl, "houselogout", (p) -> { + p.setLocation(house.getLocation().getExitLocation()); + return kotlin.Unit.INSTANCE; + }); + } + return super.enter(e); + } + + @Override + public boolean death(Entity e, Entity killer) { + if (e instanceof Player) { + Player p = (Player) e; + HouseManager.leave(p); + return true; + } + return super.death(e, killer); + } + + @Override + public boolean leave(Entity e, boolean logout) { + if (e instanceof Player) { + Player p = (Player) e; + // The below tears down the house if the owner was the one who left + if (house == p.getHouseManager()) { + house.expelGuests(p); + int toRemove = previousRegion; + int dungRemove = previousDungeon; + submitWorldPulse(new Pulse(2) { + public boolean pulse() { + Region r = RegionManager.forId(toRemove); + Region dr = dungRemove != -1 ? RegionManager.forId(dungRemove) : null; + RegionManager.removeRegion(toRemove); + unregisterRegion(toRemove); + r.setActive(false); + if (dungRemove != -1) { + RegionManager.removeRegion(dungRemove); + unregisterRegion(dungRemove); + dr.setActive(false); + } + return true; + } + }); + } + // Clear logout listener and original-loc (if appropriate) + clearLogoutListener(p, "houselogout"); + if (!getAttribute(p, "kidnapped-by-random", false)) { + removeAttribute(p, "/save:original-loc"); + } + return true; + } + return true; + } +} diff --git a/Server/src/main/content/global/skill/construction/HousingStyle.java b/Server/src/main/content/global/skill/construction/HousingStyle.java new file mode 100644 index 0000000..e4d59b9 --- /dev/null +++ b/Server/src/main/content/global/skill/construction/HousingStyle.java @@ -0,0 +1,152 @@ +package content.global.skill.construction; + +import core.game.node.entity.player.Player; +import core.game.node.entity.skill.Skills; + +/** + * The styles of houses. + * @author Emperor + * + */ +public enum HousingStyle { + + BASIC_WOOD (1, 5000, 7503, 0, 13100, 13101, 13098, Decoration.BASIC_WOOD_WINDOW), + BASIC_STONE (10, 5000, 7503, 1, 13094, 13096, 1902, Decoration.BASIC_STONE_WINDOW), + WHITEWASHED_STONE (20, 7500, 7503, 2, 13006, 13007, 1415, Decoration.WHITEWASHED_STONE_WINDOW), + FREMENNIK_STYLE_WOOD(30, 10000, 7503, 3, 13109, 13107, 13111, Decoration.FREMENNIK_WINDOW), + TROPICAL_WOOD (40, 15000, 7759, 0, 13016, 13015, 13011, Decoration.TROPICAL_WOOD_WINDOW), + FANCY_STONE (50, 25000, 7759, 1, 13119, 13118, 13116, Decoration.FANCY_STONE_WINDOW); + + /** + * The level required. + */ + private final int levelRequirement; + + /** + * The cost. + */ + private final int cost; + + /** + * The region id. + */ + private final int regionId; + + /** + * The plane. + */ + private final int plane; + + /** + * The door id. + */ + private final int doorId; + + /** + * The second door id. + */ + private final int secondDoorId; + + /** + * The wall id. + */ + private final int wallId; + + /** + * The window style + */ + private final Decoration window; + + /** + * Checks if the player has the level. + * + * @param player the player. + * @return {@code True} if so. + */ + public boolean hasLevel(Player player) { + return player.getSkills().getStaticLevel(Skills.CONSTRUCTION) >= levelRequirement; + } + + /** + * Constructs a new {@code HousingStyle} {@code Object} + * @param level The level required. + * @param cost The cost of the style. + * @param regionId The region id for this style. + * @param plane The plane for this style. + * @param doorId The door object id used in this style. + */ + private HousingStyle(int level, int cost, int regionId, int plane, int doorId, int secondDoorId, int wallId, Decoration window) { + this.levelRequirement = level; + this.cost = cost; + this.regionId = regionId; + this.plane = plane; + this.doorId = doorId; + this.secondDoorId = secondDoorId; + this.wallId = wallId; + this.window = window; + } + + /** + * Gets the level. + * @return the level + */ + public int getLevel() { + return levelRequirement; + } + + /** + * Gets the cost. + * @return the cost + */ + public int getCost() { + return cost; + } + + /** + * Gets the regionId. + * @return the regionId + */ + public int getRegionId() { + return regionId; + } + + /** + * Gets the plane. + * @return the plane + */ + public int getPlane() { + return plane; + } + + /** + * Gets the door used in this style. + * @return The door object id. + */ + public int getDoorId() { + return doorId; + } + + /** + * Gets the wall used in this style. + * @return The wall object id. + */ + public int getWallId() { + return wallId; + } + + /** + * Gets the window id for this style of house + * @return The windows object id + */ + public Decoration getWindowStyle() { + return window; + } + + /** + * Gets the secondDoorId value. + * @return The secondDoorId. + */ + public int getSecondDoorId() { + return secondDoorId; + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/NailType.java b/Server/src/main/content/global/skill/construction/NailType.java new file mode 100644 index 0000000..22ec100 --- /dev/null +++ b/Server/src/main/content/global/skill/construction/NailType.java @@ -0,0 +1,81 @@ +package content.global.skill.construction; + + +import core.game.node.entity.player.Player; +import core.tools.RandomFunction; + +/** + * Holds information of all nail types. + * @author Emperor + * + */ +public enum NailType { + + BRONZE(4819, 5), + IRON(4820, 7), + STEEL(1539, 10), + MITHRIL(4822, 13), + ADAMANT(4823, 15), + RUNE(4824, 20) + ; + + /** + * The nail item id. + */ + private final int itemId; + + /** + * The bend rate. + */ + private final int bendRate; + + /** + * Constructs a new {@code NailType} {@code Object}. + * @param itemId The item id. + * @param bendRate The bending rate. + */ + private NailType(int itemId, int bendRate) { + this.itemId = itemId; + this.bendRate = bendRate; + } + + /** + * Checks if the nail will bend. + * @return {@code True} if Random.nextInt(bendRate) equals 0. + */ + public boolean isBend() { + return RandomFunction.getRandom(bendRate) == 0; + } + + /** + * Gets the nail type used by the player. + * @param player The player. + * @param amount The nails required. + * @return The nail type used, or null if the player didn't have the nails. + */ + public static NailType get(Player player, int amount) { + for (int i = values().length - 1; i >= 0; i--) { + NailType type = values()[i]; + if (player.getInventory().contains(type.itemId, amount)) { + return type; + } + } + return null; + } + + /** + * Gets the itemId value. + * @return The itemId. + */ + public int getItemId() { + return itemId; + } + + /** + * Gets the bendRate value. + * @return The bendRate. + */ + public int getBendRate() { + return bendRate; + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/PortalOptionPlugin.java b/Server/src/main/content/global/skill/construction/PortalOptionPlugin.java new file mode 100644 index 0000000..23d951d --- /dev/null +++ b/Server/src/main/content/global/skill/construction/PortalOptionPlugin.java @@ -0,0 +1,165 @@ +package content.global.skill.construction; + + +import static core.api.ContentAPIKt.*; +import core.cache.def.impl.SceneryDefinition; +import core.game.dialogue.DialogueInterpreter; +import core.game.dialogue.DialoguePlugin; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.plugin.PluginManifest; +import core.plugin.PluginType; +import kotlin.Unit; +import core.game.world.repository.Repository; +import core.plugin.ClassScanner; + +/** + * Handles the house portal options. + * @author Emperor + * + */ +@Initializable +public final class PortalOptionPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (HouseLocation hl : HouseLocation.values()) { + SceneryDefinition.forId(hl.getPortalId()).getHandlers().put("option:enter", this); + } + SceneryDefinition.forId(13405).getHandlers().put("option:lock", this); + SceneryDefinition.forId(13405).getHandlers().put("option:enter", this); + ClassScanner.definePlugin(new PortalDialogue()); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + Scenery object = node.asScenery(); + if (object.getId() == 13405 && option.equals("enter")) { + HouseManager.leave(player); + return true; + } + if (option.equals("lock")) { + if (player.getHouseManager().isInHouse(player)) { + player.getHouseManager().setLocked(player.getHouseManager().isLocked() ? false : true); + player.sendMessage("Your house is now "+(player.getHouseManager().isLocked() ? "locked." : "unlocked." )); + return true; + } + player.sendMessage("This is not your house."); + return true; + } + player.setAttribute("con:portal", object.getId()); + player.getDialogueInterpreter().open("con:portal"); + return true; + } + + /** + * Handles the portal dialogue. + * @author Emperor + */ + @PluginManifest(type= PluginType.DIALOGUE) + private class PortalDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code PortalDialogue} {@code Object} + */ + public PortalDialogue() { + + } + + /** + * Constructs a new {@code PortalDialogue} {@code Object} + * @param player The player. + */ + public PortalDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new PortalDialogue(player); + } + + @Override + public boolean open(Object... args) { + + + + + options("Go to your house", "Go to your house (building mode)", "Go to a friend's house", "Never mind"); + stage = 1; + + + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + end(); + switch (stage) { + case 1: + switch (buttonId) { + case 1: + case 2: + //If the player does not have a house + if (!player.getHouseManager().hasHouse()) { + player.getPacketDispatch().sendMessage("You don't have a house, talk to an estate agent to purchase a house."); + break; + } + //If the Player has a house, but does not have their house moved to the portal they are interacting with + if (player.getHouseManager().getLocation().getPortalId() != player.getAttribute("con:portal", -1)) { + player.getPacketDispatch().sendMessage("Your house is in " + player.getHouseManager().getLocation().getName() + "."); + player.sendMessage("Speak with an estate agent to change your house location."); + break; + } + player.getHouseManager().enter(player, buttonId == 2); + break; + case 3: + if(player.getIronmanManager().isIronman()){ + end(); + sendMessage(player, "You can't do that as an ironman."); + return true; + } + sendInputDialogue(player, false, "Enter friend's name:", (value) -> { + Player p = Repository.getPlayerByName((String) value); + if (p == null || !p.isActive()) { + player.getPacketDispatch().sendMessage("This player is not online."); + return Unit.INSTANCE; + } + if (p.getUsername().equals(player.getUsername())) { + player.getPacketDispatch().sendMessage("You aren't a friend of yourself!"); + return Unit.INSTANCE; + } + if (!p.getHouseManager().isLoaded()) { + player.getPacketDispatch().sendMessage("This player is not at home right now."); + return Unit.INSTANCE; + } + if (p.getHouseManager().isBuildingMode()) { + player.getPacketDispatch().sendMessage("This player is in building mode."); + return Unit.INSTANCE; + } + if (p.getHouseManager().isLocked()) { + player.getPacketDispatch().sendMessage("The other player has locked their house."); + return Unit.INSTANCE; + } + p.setAttribute("poh_owner", (String) value); + p.getHouseManager().enter(player, false); + return Unit.INSTANCE; + }); + break; + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { DialogueInterpreter.getDialogueKey("con:portal") }; + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/RemovalDialogue.java b/Server/src/main/content/global/skill/construction/RemovalDialogue.java new file mode 100644 index 0000000..5b2a9f8 --- /dev/null +++ b/Server/src/main/content/global/skill/construction/RemovalDialogue.java @@ -0,0 +1,102 @@ +package content.global.skill.construction; + + +import core.game.dialogue.DialogueInterpreter; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; + +/** + * Removal dialogue for room & decorations in construction + * @author Clayton Williams + * @author Emperor + * @date Jun-30-2015 + */ +@Initializable +public final class RemovalDialogue extends DialoguePlugin { + + /** + * The room position. + */ + private int[] pos; + + /** + * The plane. + */ + private int plane; + + /** + * The room to remove. + */ + private Room room; + + /** + * Removal Dialogue + */ + public RemovalDialogue() { + super(); + } + + /** + * Removal Dialogue + * @param player + */ + public RemovalDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new RemovalDialogue(player); + } + + @Override + public boolean open(Object... args) { + pos = (int[]) args[1]; + plane = player.getLocation().getZ(); + if (HouseManager.isInDungeon(player)) { + plane = 3; + } + room = player.getHouseManager().getRooms()[plane][pos[0]][pos[1]]; + player.getDialogueInterpreter().sendOptions("Remove the " + (room != null ? room.getProperties().getName() : "room") + "?", "Yes", "No"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + if (stage == 0) { + if (buttonId == 1) { + if (plane == 0 && player.getHouseManager().hasRoomAt(1, pos[0], pos[1])) { + interpreter.sendPlainMessage(false, "You can't remove a room supporting another room."); + stage = 1; + return true; + } + if (room != null && room.getProperties().isLand()) { + Hotspot h = room.getHotspots()[0]; + if (h != null && h.getDecorationIndex() == 0 && player.getHouseManager().getPortalAmount() <= 1) { + interpreter.sendPlainMessage(false, "You can't remove the garden with your portal in it."); + stage = 1; + return true; + } + } + player.getHouseManager().getRooms()[plane][pos[0]][pos[1]] = null; + for (int i = plane; i < 3; i++) { + Room r = player.getHouseManager().getRooms()[i][pos[0]][pos[1]]; + if (r != null && r.getProperties().isRoof()) { + player.getHouseManager().getRooms()[i][pos[0]][pos[1]] = null; + } + } + player.getHouseManager().reload(player, true); + } + } + end(); + return true; + } + + @Override + public int[] getIds() { + return new int[]{ DialogueInterpreter.getDialogueKey("con:remove") }; + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/Room.java b/Server/src/main/content/global/skill/construction/Room.java new file mode 100644 index 0000000..883a477 --- /dev/null +++ b/Server/src/main/content/global/skill/construction/Room.java @@ -0,0 +1,426 @@ +package content.global.skill.construction; + + +import core.game.node.entity.player.Player; +import core.game.node.scenery.Constructed; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.world.map.*; +import core.tools.Log; + +import static core.api.ContentAPIKt.log; + +/** + * Represents a room. + * @author Emperor + * + */ +public final class Room { + + /** + * The default room type. + */ + public static final int CHAMBER = 0x0; + + /** + * The rooftop room type. + */ + public static final int ROOF = 0x1; + + /** + * The dungeon room type. + */ + public static final int DUNGEON = 0x2; + + /** + * The dungeon room type. + */ + public static final int LAND = 0x4; + + /** + * The room properties. + */ + private RoomProperties properties; + + /** + * The region chunk. + */ + private RegionChunk chunk; + + /** + * The hotspots. + */ + private Hotspot[] hotspots; + + /** + * The current rotation of the room. + */ + private Direction rotation = Direction.NORTH; + + /** + * Constructs a new {@code Room} {@code Object}. + * @param properties The room properties. + */ + public Room(RoomProperties properties) { + this.properties = properties; + } + + /** + * Creates a new room. + * @param player The player. + * @param properties The room properties. + * @return The room. + */ + public static Room create(Player player, RoomProperties properties) { + Room room = new Room(properties); + room.configure(player.getHouseManager().getStyle()); + return room; + } + + /** + * Configures the room. + */ + public void configure(HousingStyle style) { + this.hotspots = new Hotspot[properties.getHotspots().length]; + for (int i = 0; i < hotspots.length; i++) { + hotspots[i] = properties.getHotspots()[i].copy(); + } + decorate(style); + } + + /** + * Redecorates the room. + * @param style The house style. + */ + public void decorate(HousingStyle style) { + Region region = RegionManager.forId(style.getRegionId()); + Region.load(region, true); + chunk = region.getPlanes()[style.getPlane()].getRegionChunk(properties.getChunkX(), properties.getChunkY()); + } + + /** + * Gets the hotspot object for the given hotspot type. + * @param hotspot The hotspot type. + * @return The hotspot. + */ + public Hotspot getHotspot(BuildHotspot hotspot) { + for (Hotspot h : hotspots) { + if (h.getHotspot() == hotspot) { + return h; + } + } + return null; + } + + /** + * Checks if the building hotspot has been built. + * @param hotspot The building hotspot. + * @return {@code True} if so. + */ + public boolean isBuilt(BuildHotspot hotspot) { + Hotspot h = getHotspot(hotspot); + return h != null && h.getDecorationIndex() > -1; + } + + /** + * Loads all the decorations. + * @param housePlane The plane. + * @param chunk The chunk used in the dynamic region. + */ + public void loadDecorations(int housePlane, BuildRegionChunk chunk, HouseManager house) { + for (int i = 0; i < hotspots.length; i++) { + Hotspot spot = hotspots[i]; + int x = spot.getChunkX(); + int y = spot.getChunkY(); + if (spot.getHotspot() == null) { + continue; + } + int index = chunk.getIndex(x, y, spot.getHotspot().getObjectId(house.getStyle())); + Scenery[][] objects = chunk.getObjects(index); + Scenery object = objects[x][y]; + if (object != null && object.getId() == spot.getHotspot().getObjectId(house.getStyle())) { + if (spot.getDecorationIndex() > -1 && spot.getDecorationIndex() < spot.getHotspot().getDecorations().length) { + int id = spot.getHotspot().getDecorations()[spot.getDecorationIndex()].getObjectId(house.getStyle()); + if (spot.getHotspot().getType() == BuildHotspotType.CREST) { + id += house.getCrest().ordinal(); + } + SceneryBuilder.replace(object, object.transform(id, object.getRotation(), chunk.getCurrentBase().transform(x, y, 0))); + } + else if (object.getId() == BuildHotspot.WINDOW.getObjectId(house.getStyle()) || (!house.isBuildingMode() && object.getId() == BuildHotspot.CHAPEL_WINDOW.getObjectId(house.getStyle()))) { + chunk.add(object.transform(house.getStyle().getWindowStyle().getObjectId(house.getStyle()), object.getRotation(), object.getType())); + } + int[] pos = RegionChunk.getRotatedPosition(x, y, object.getSizeX(), object.getSizeY(), 0, rotation.toInteger()); + spot.setCurrentX(pos[0]); + spot.setCurrentY(pos[1]); + } + } + if (rotation != Direction.NORTH && chunk.getRotation() == 0) { + chunk.rotate(rotation); + } + if (!house.isBuildingMode()) { + placeDoors(housePlane, house, chunk); + removeHotspots(housePlane, house, chunk); + } + } + + /** + * Removes the building hotspots from the room. + * @param housePlane The room's plane in house. + * @param house The house manager. + * @param chunk The region chunk used. + */ + private void removeHotspots(int housePlane, HouseManager house, BuildRegionChunk chunk) { + if (properties.isRoof()) return; + for (int x = 0; x < 8; x++) { + for (int y = 0; y < 8; y++) { + for (int i = 0; i < BuildRegionChunk.ARRAY_SIZE; i++) { + Scenery object = chunk.get(x, y, i); + if (object != null) { + boolean isBuilt = object instanceof Constructed; + boolean isWall = object.getId() == 13065 || object.getId() == house.getStyle().getWallId(); + boolean isDoor = object.getId() == house.getStyle().getDoorId() || object.getId() == house.getStyle().getSecondDoorId(); + if (!isBuilt && !isWall && !isDoor) { + SceneryBuilder.remove(object); + chunk.remove(object); + } + } + } + } + } + } + + /** + * Replaces the door hotspots with doors, walls, or passageways as needed. + * TODO: it is believed that doors authentically remember their open/closed state for the usual duration (see e.g. https://www.youtube.com/watch?v=nRGux739h8s 1:00 vs 1:55), but this is not possible with the current HouseManager approach, which deallocates the instance as soon as the player leaves. + * @param housePlane The room's plane in house. + * @param house The house manager. + * @param chunk The region chunk used. + */ + private void placeDoors(int housePlane, HouseManager house, BuildRegionChunk chunk) { + Room[][][] rooms = house.getRooms(); + int rx = chunk.getCurrentBase().getChunkX(); + int ry = chunk.getCurrentBase().getChunkY(); + for (int i = 0; i < BuildRegionChunk.ARRAY_SIZE; i++) { + for (int x = 0; x < 8; x++) { + for (int y = 0; y < 8; y++) { + Scenery object = chunk.get(x, y, i); + if (object != null && BuildingUtils.isDoorHotspot(object)) { + boolean edge = false; + Room otherRoom = null; + switch (object.getRotation()) { + case 0: //east + edge = rx == 0; + otherRoom = edge ? null : rooms[housePlane][rx - 1][ry]; + break; + case 1: //south + edge = ry == 7; + otherRoom = edge ? null : rooms[housePlane][rx][ry + 1]; + break; + case 2: //west + edge = rx == 7; + otherRoom = edge ? null : rooms[housePlane][rx + 1][ry]; + break; + case 3: //north + edge = ry == 0; + otherRoom = edge ? null : rooms[housePlane][rx][ry - 1]; + break; + default: + log(this.getClass(), Log.ERR, "Impossible rotation when placing doors??"); + } + int replaceId = getReplaceId(housePlane, house, this, edge, otherRoom, object); + if (replaceId == -1) { + continue; + } + SceneryBuilder.replace(object, object.transform(replaceId)); + } + } + } + } + } + + /** + * Checks if rooms transition between inside<>outside the house and returns the appropriate door replacement. + * @param housePlane The room's plane in house. + * @param house The house manager. + * @param room The room the door is in. + * @param edge Whether the door is adjacent to an edge. + * @param otherRoom The room the door is adjacent to. + * @param object The door object itself. + */ + private int getReplaceId(int housePlane, HouseManager house, Room room, boolean edge, Room otherRoom, Scenery object) { + boolean thisOutside = !room.getProperties().isChamber(); + if (edge && thisOutside) { + // No door or wall + return -1; + } + if (!edge) { + boolean otherOutside = otherRoom == null || !otherRoom.getProperties().isChamber(); + if (thisOutside == otherOutside) { + // Free passage, unless the other room has a blind wall here + if (otherRoom == null) { + return -1; + } + boolean exit = otherRoom.getExits()[object.getRotation()]; + if (exit) { + return -1; + } + } + if (thisOutside != otherOutside && housePlane == 0) { + // Door if we are the inside room only + if (thisOutside) { + return -1; + } + return object.getId() % 2 != 0 ? house.getStyle().getDoorId() : house.getStyle().getSecondDoorId(); + } + } + return room.getProperties().isDungeon() ? 13065 : house.getStyle().getWallId(); + } + + /** + * Sets the decoration index for a group of object ids + * @param index The index. + * @param hs The building hotspot. + */ + public void setAllDecorationIndex(int index, BuildHotspot hs) { + for (int i = 0; i < hotspots.length; i++) { + Hotspot h = hotspots[i]; + if (h.getHotspot() == hs) { + h.setDecorationIndex(index); + } + } + } + + /** + * Gets the stairs hotspot for this room (or null if no stairs are available). + * @return The stairs. + */ + public Hotspot getStairs() { + for (Hotspot h : hotspots) { + if (h.getHotspot().getType() == BuildHotspotType.STAIRCASE + || h.getHotspot() == BuildHotspot.LADDER || h.getHotspot() == BuildHotspot.TRAPDOOR + || (h.getHotspot() == BuildHotspot.CENTREPIECE_1 && h.getDecorationIndex() == 4) + || (h.getHotspot() == BuildHotspot.CENTREPIECE_2 && h.getDecorationIndex() == 2)) { + return h; + } + } + return null; + } + + /** + * Gets the exit directions + * @return The exits information. + */ + public boolean[] getExits() { + return getExits(rotation); + } + + /** + * Gets the exit directions. + * @return The directions at which you can exit the room (0=east, 1=south, 2=west, 3=north). + */ + public boolean[] getExits(Direction rotation) { + boolean[] exits = properties.getExits(); + if (chunk.getRotation() != rotation.toInteger()) { + boolean[] exit = new boolean[exits.length]; + int offset = rotation.toInteger() - chunk.getRotation(); + for (int i = 0; i < 4; i++) { + exit[(i + offset) % 4] = exits[i]; + } + return exit; + } + return exits; + } + + /** + * Gets the hotspot for the given coordinates. + * @param build The build hotspot. + * @param x The x-coordinate. + * @param y The y-coordinate. + * @return The hotspot. + */ + public Hotspot getHotspot(BuildHotspot build, int x, int y) { + for (int i = 0; i < getHotspots().length; i++) { + Hotspot h = getHotspots()[i]; + if (h.getCurrentX() == x && h.getCurrentY() == y && h.getHotspot() == build) { + return h; + } + } + return null; + } + + /** + * Sets the properties. + * @param properties The properties. + */ + public void updateProperties(Player player, RoomProperties properties) { + this.properties = properties; + decorate(player.getHouseManager().getStyle()); + if (hotspots.length != properties.getHotspots().length) { + return; + } + for (int i = 0; i < hotspots.length; i++) { + Hotspot h = hotspots[i]; + Hotspot hs = hotspots[i] = properties.getHotspots()[i].copy(); + hs.setCurrentX(h.getCurrentX()); + hs.setCurrentY(h.getCurrentY()); + hs.setDecorationIndex(h.getDecorationIndex()); + } + } + + /** + * Gets the chunk. + * @return The chunk. + */ + public RegionChunk getChunk() { + return chunk; + } + + /** + * Sets the chunk. + * @param chunk The chunk to set. + */ + public void setChunk(RegionChunk chunk) { + this.chunk = chunk; + } + + /** + * Gets the hotspots. + * @return The hotspots. + */ + public Hotspot[] getHotspots() { + return hotspots; + } + + /** + * Sets the hotspots. + * @param hotspots The hotspots to set. + */ + public void setHotspots(Hotspot[] hotspots) { + this.hotspots = hotspots; + } + + /** + * Gets the properties. + * @return The properties. + */ + public RoomProperties getProperties() { + return properties; + } + + /** + * Sets the room rotation. + * @param rotation The rotation. + */ + public void setRotation(Direction rotation) { + this.rotation = rotation; + } + + /** + * Gets the rotation. + * @return The rotation. + */ + public Direction getRotation() { + return rotation; + } + +} diff --git a/Server/src/main/content/global/skill/construction/RoomProperties.java b/Server/src/main/content/global/skill/construction/RoomProperties.java new file mode 100644 index 0000000..80bc6e6 --- /dev/null +++ b/Server/src/main/content/global/skill/construction/RoomProperties.java @@ -0,0 +1,1019 @@ +package content.global.skill.construction; + + +import core.game.node.scenery.Scenery; +import core.game.world.map.Region; +import core.game.world.map.RegionChunk; +import core.game.world.map.RegionManager; + +/** + * Represents the room properties. + * @author Emperor, Player Name + * >ORDINAL BOUND< + */ +public enum RoomProperties { + /** + * The parlour. + */ + PARLOUR(1000, 1, 0, 0, 7, Room.CHAMBER, new Hotspot(BuildHotspot.BOOKCASE, 0, 1), + new Hotspot(BuildHotspot.WINDOW, 0, 2), + new Hotspot(BuildHotspot.WINDOW, 0, 5), + new Hotspot(BuildHotspot.WINDOW, 2, 0), + new Hotspot(BuildHotspot.WINDOW, 2, 7), + new Hotspot(BuildHotspot.WINDOW, 5, 0), + new Hotspot(BuildHotspot.WINDOW, 5, 7), + new Hotspot(BuildHotspot.WINDOW, 7, 2), + new Hotspot(BuildHotspot.WINDOW, 7, 5), + new Hotspot(BuildHotspot.CURTAINS, 2, 0), + new Hotspot(BuildHotspot.CURTAINS, 0, 2), + new Hotspot(BuildHotspot.CURTAINS, 0, 5), + new Hotspot(BuildHotspot.CURTAINS, 2, 7), + new Hotspot(BuildHotspot.CURTAINS, 5, 0), + new Hotspot(BuildHotspot.CURTAINS, 5, 7), + new Hotspot(BuildHotspot.CURTAINS, 7, 2), + new Hotspot(BuildHotspot.CURTAINS, 7, 5), + new Hotspot(BuildHotspot.RUG, 2, 2), + new Hotspot(BuildHotspot.RUG2, 2, 3), + new Hotspot(BuildHotspot.RUG2, 2, 4), + new Hotspot(BuildHotspot.RUG, 2, 5), + new Hotspot(BuildHotspot.RUG2, 3, 2), + new Hotspot(BuildHotspot.RUG3, 3, 3), + new Hotspot(BuildHotspot.RUG3, 3, 4), + new Hotspot(BuildHotspot.RUG2, 3, 5), + new Hotspot(BuildHotspot.RUG2, 4, 2), + new Hotspot(BuildHotspot.RUG3, 4, 3), + new Hotspot(BuildHotspot.RUG3, 4, 4), + new Hotspot(BuildHotspot.RUG2, 4, 5), + new Hotspot(BuildHotspot.RUG, 5, 2), + new Hotspot(BuildHotspot.RUG2, 5, 3), + new Hotspot(BuildHotspot.RUG2, 5, 4), + new Hotspot(BuildHotspot.RUG, 5, 5), + new Hotspot(BuildHotspot.CHAIRS_1, 2, 4), + new Hotspot(BuildHotspot.FIREPLACE, 3, 7, 4, 7), + new Hotspot(BuildHotspot.CHAIRS_3, 4, 3), + new Hotspot(BuildHotspot.CHAIRS_2, 5, 4), + new Hotspot(BuildHotspot.BOOKCASE, 7, 1)), + + /** + * The garden. (centrepiece has to be first!) + */ + GARDEN(1000, 1, 0, 0, 1, Room.LAND, new Hotspot(BuildHotspot.CENTREPIECE_1, 3, 3, 4, 4), + new Hotspot(BuildHotspot.BIG_PLANT_2, 0, 0, 1, 1), + new Hotspot(BuildHotspot.BIG_TREE_1, 1, 5, 2, 6), + new Hotspot(BuildHotspot.SMALL_PLANT_1, 3, 1), + new Hotspot(BuildHotspot.SMALL_PLANT_2, 4, 5), + new Hotspot(BuildHotspot.BIG_PLANT_1, 6, 0, 7, 1), + new Hotspot(BuildHotspot.TREE_1, 6, 6, 7, 7)), + + /** + * The kitchen. + */ + KITCHEN(5000, 5, 0, 2, 7, Room.CHAMBER, new Hotspot(BuildHotspot.CAT_BLANKET, 0, 0), + new Hotspot(BuildHotspot.WINDOW, 0, 2), + new Hotspot(BuildHotspot.WINDOW, 0, 5), + new Hotspot(BuildHotspot.WINDOW, 2, 0), + new Hotspot(BuildHotspot.WINDOW, 2, 7), + new Hotspot(BuildHotspot.WINDOW, 5, 0), + new Hotspot(BuildHotspot.WINDOW, 5, 7), + new Hotspot(BuildHotspot.WINDOW, 7, 2), + new Hotspot(BuildHotspot.WINDOW, 7, 5), + new Hotspot(BuildHotspot.BARRELS, 0, 6), + new Hotspot(BuildHotspot.KITCHEN_TABLE, 3, 3, 4, 4), + new Hotspot(BuildHotspot.STOVE, 3, 7, 4, 7), + new Hotspot(BuildHotspot.LARDER, 6, 0, 7, 1), + new Hotspot(BuildHotspot.SINK, 7, 3, 7, 4), + new Hotspot(BuildHotspot.SHELVES, 1, 7), + new Hotspot(BuildHotspot.SHELVES, 6, 7), + new Hotspot(BuildHotspot.SHELVES_2, 7, 6)), + + /** + * Dining room. + */ + DINING_ROOM(5000, 10, 0, 4, 7, Room.CHAMBER, new Hotspot(BuildHotspot.FIREPLACE_DINING, 3, 7, 4, 7), + new Hotspot(BuildHotspot.WINDOW, 0, 2), + new Hotspot(BuildHotspot.WINDOW, 0, 5), + new Hotspot(BuildHotspot.WINDOW, 2, 0), + new Hotspot(BuildHotspot.WINDOW, 5, 0), + new Hotspot(BuildHotspot.WINDOW, 7, 2), + new Hotspot(BuildHotspot.WINDOW, 7, 5), + new Hotspot(BuildHotspot.DINING_CURTAINS, 0, 2), + new Hotspot(BuildHotspot.DINING_CURTAINS, 0, 5), + new Hotspot(BuildHotspot.DINING_CURTAINS, 2, 0), + new Hotspot(BuildHotspot.DINING_CURTAINS, 5, 0), + new Hotspot(BuildHotspot.DINING_CURTAINS, 7, 2), + new Hotspot(BuildHotspot.DINING_CURTAINS, 7, 5), + new Hotspot(BuildHotspot.WALL_DECORATION, 2, 7), + new Hotspot(BuildHotspot.WALL_DECORATION, 5, 7), + new Hotspot(BuildHotspot.DINING_BENCH_2, 2, 5), + new Hotspot(BuildHotspot.DINING_BENCH_2, 3, 5), + new Hotspot(BuildHotspot.DINING_BENCH_2, 4, 5), + new Hotspot(BuildHotspot.DINING_BENCH_2, 5, 5), + new Hotspot(BuildHotspot.DINING_BENCH_1, 2, 2), + new Hotspot(BuildHotspot.DINING_BENCH_1, 3, 2), + new Hotspot(BuildHotspot.DINING_BENCH_1, 4, 2), + new Hotspot(BuildHotspot.DINING_BENCH_1, 5, 2), + new Hotspot(BuildHotspot.ROPE_BELL_PULL, 0, 0), + new Hotspot(BuildHotspot.DINING_TABLE, 2, 3, 5, 4)), + + /** + * Workshop. + */ + WORKSHOP(10000, 15, 0, 0, 5, Room.CHAMBER, new Hotspot(BuildHotspot.WORKBENCH, 3, 4, 4, 4), + new Hotspot(BuildHotspot.WINDOW, 0, 2), + new Hotspot(BuildHotspot.WINDOW, 0, 5), + new Hotspot(BuildHotspot.WINDOW, 2, 0), + new Hotspot(BuildHotspot.WINDOW, 5, 0), + new Hotspot(BuildHotspot.WINDOW, 7, 2), + new Hotspot(BuildHotspot.WINDOW, 7, 5), + new Hotspot(BuildHotspot.WINDOW, 2, 7), + new Hotspot(BuildHotspot.WINDOW, 5, 7), + new Hotspot(BuildHotspot.REPAIR, 7, 3, 7, 4), + new Hotspot(BuildHotspot.HERALDRY, 7, 6, 7, 7), + new Hotspot(BuildHotspot.CRAFTING, 0, 3, 0, 4), + new Hotspot(BuildHotspot.WORKBENCH, 3, 4), + new Hotspot(BuildHotspot.TOOL4, 7, 1), + new Hotspot(BuildHotspot.TOOL2, 6, 0), + new Hotspot(BuildHotspot.TOOL1, 1, 0), + new Hotspot(BuildHotspot.TOOL3, 0, 1), + new Hotspot(BuildHotspot.TOOL5, 0, 6)), + + /** + * Bedroom. + */ + BEDROOM(10000, 20, 0, 6, 7, Room.CHAMBER, new Hotspot(BuildHotspot.BED, 3, 6, 4, 7), + new Hotspot(BuildHotspot.FIREPLACE2, 7, 3, 7, 4), + new Hotspot(BuildHotspot.CLOCK, 7, 0), + new Hotspot(BuildHotspot.DRESSER, 0, 7, 1, 7), + new Hotspot(BuildHotspot.DRAWERS, 6, 7), + new Hotspot(BuildHotspot.WINDOW, 0, 2), + new Hotspot(BuildHotspot.WINDOW, 0, 5), + new Hotspot(BuildHotspot.WINDOW, 2, 0), + new Hotspot(BuildHotspot.WINDOW, 5, 0), + new Hotspot(BuildHotspot.WINDOW, 7, 2), + new Hotspot(BuildHotspot.WINDOW, 7, 5), + new Hotspot(BuildHotspot.WINDOW, 2, 7), + new Hotspot(BuildHotspot.WINDOW, 5, 7), + new Hotspot(BuildHotspot.BEDROOM_CURTAINS, 0, 2), + new Hotspot(BuildHotspot.BEDROOM_CURTAINS, 0, 5), + new Hotspot(BuildHotspot.BEDROOM_CURTAINS, 2, 0), + new Hotspot(BuildHotspot.BEDROOM_CURTAINS, 5, 0), + new Hotspot(BuildHotspot.BEDROOM_CURTAINS, 7, 2), + new Hotspot(BuildHotspot.BEDROOM_CURTAINS, 7, 5), + new Hotspot(BuildHotspot.BEDROOM_CURTAINS, 2, 7), + new Hotspot(BuildHotspot.BEDROOM_CURTAINS, 5, 7), + new Hotspot(BuildHotspot.BEDROOM_RUG, 2, 2), + new Hotspot(BuildHotspot.BEDROOM_RUG, 2, 3), + new Hotspot(BuildHotspot.BEDROOM_RUG, 3, 2), + new Hotspot(BuildHotspot.BEDROOM_RUG, 3, 3), + new Hotspot(BuildHotspot.BEDROOM_RUG, 4, 2), + new Hotspot(BuildHotspot.BEDROOM_RUG, 4, 3), + new Hotspot(BuildHotspot.BEDROOM_RUG, 5, 2), + new Hotspot(BuildHotspot.BEDROOM_RUG, 5, 3), + new Hotspot(BuildHotspot.BEDROOM_RUG2, 2, 1), + new Hotspot(BuildHotspot.BEDROOM_RUG2, 3, 1), + new Hotspot(BuildHotspot.BEDROOM_RUG2, 4, 1), + new Hotspot(BuildHotspot.BEDROOM_RUG2, 5, 1), + new Hotspot(BuildHotspot.BEDROOM_RUG2, 2, 4), + new Hotspot(BuildHotspot.BEDROOM_RUG2, 3, 4), + new Hotspot(BuildHotspot.BEDROOM_RUG2, 4, 4), + new Hotspot(BuildHotspot.BEDROOM_RUG2, 5, 4), + new Hotspot(BuildHotspot.BEDROOM_RUG2, 6, 2), + new Hotspot(BuildHotspot.BEDROOM_RUG2, 6, 3), + new Hotspot(BuildHotspot.BEDROOM_RUG2, 1, 2), + new Hotspot(BuildHotspot.BEDROOM_RUG2, 1, 3), + new Hotspot(BuildHotspot.BEDROOM_RUG2, 3, 2), + new Hotspot(BuildHotspot.BEDROOM_RUG2, 3, 5), + new Hotspot(BuildHotspot.BEDROOM_RUG2, 4, 5), + new Hotspot(BuildHotspot.BEDROOM_RUG2, 4, 2), + new Hotspot(BuildHotspot.BEDROOM_RUG3, 1, 1), + new Hotspot(BuildHotspot.BEDROOM_RUG3, 1, 4), + new Hotspot(BuildHotspot.BEDROOM_RUG3, 6, 1), + new Hotspot(BuildHotspot.BEDROOM_RUG3, 6, 4)), + + /** + * Skill hall. + */ + SKILL_HALL(15000, 25, 0, 1, 6, Room.CHAMBER, new Hotspot(BuildHotspot.STAIRWAYS, 3, 3, 4, 4), + new Hotspot(BuildHotspot.ARMOUR_SPACE, 2, 3), + new Hotspot(BuildHotspot.ARMOUR_SPACE2, 5, 3), + new Hotspot(BuildHotspot.HEAD_TROPHY, 6, 7), + new Hotspot(BuildHotspot.RUNE_CASE, 0, 6), + new Hotspot(BuildHotspot.FISHING_TROPHY, 1, 7), + new Hotspot(BuildHotspot.WINDOW, 0, 2), + new Hotspot(BuildHotspot.WINDOW, 0, 5), + new Hotspot(BuildHotspot.WINDOW, 2, 0), + new Hotspot(BuildHotspot.WINDOW, 5, 0), + new Hotspot(BuildHotspot.WINDOW, 7, 2), + new Hotspot(BuildHotspot.WINDOW, 7, 5), + new Hotspot(BuildHotspot.WINDOW, 2, 7), + new Hotspot(BuildHotspot.WINDOW, 5, 7), + new Hotspot(BuildHotspot.HALL_RUG, 2, 2), + new Hotspot(BuildHotspot.HALL_RUG, 3, 2), + new Hotspot(BuildHotspot.HALL_RUG, 4, 2), + new Hotspot(BuildHotspot.HALL_RUG, 5, 2), + new Hotspot(BuildHotspot.HALL_RUG, 2, 3), + new Hotspot(BuildHotspot.HALL_RUG, 3, 3), + new Hotspot(BuildHotspot.HALL_RUG, 4, 3), + new Hotspot(BuildHotspot.HALL_RUG, 5, 3), + new Hotspot(BuildHotspot.HALL_RUG, 2, 4), + new Hotspot(BuildHotspot.HALL_RUG, 3, 4), + new Hotspot(BuildHotspot.HALL_RUG, 4, 4), + new Hotspot(BuildHotspot.HALL_RUG, 5, 4), + new Hotspot(BuildHotspot.HALL_RUG, 2, 5), + new Hotspot(BuildHotspot.HALL_RUG, 3, 5), + new Hotspot(BuildHotspot.HALL_RUG, 4, 5), + new Hotspot(BuildHotspot.HALL_RUG, 5, 5), + new Hotspot(BuildHotspot.HALL_RUG2, 1, 2), + new Hotspot(BuildHotspot.HALL_RUG2, 1, 3), + new Hotspot(BuildHotspot.HALL_RUG2, 1, 4), + new Hotspot(BuildHotspot.HALL_RUG2, 1, 5), + new Hotspot(BuildHotspot.HALL_RUG2, 6, 2), + new Hotspot(BuildHotspot.HALL_RUG2, 6, 3), + new Hotspot(BuildHotspot.HALL_RUG2, 6, 4), + new Hotspot(BuildHotspot.HALL_RUG2, 6, 5), + new Hotspot(BuildHotspot.HALL_RUG2, 2, 1), + new Hotspot(BuildHotspot.HALL_RUG2, 3, 1), + new Hotspot(BuildHotspot.HALL_RUG2, 4, 1), + new Hotspot(BuildHotspot.HALL_RUG2, 5, 1), + new Hotspot(BuildHotspot.HALL_RUG2, 2, 6), + new Hotspot(BuildHotspot.HALL_RUG2, 3, 6), + new Hotspot(BuildHotspot.HALL_RUG2, 4, 6), + new Hotspot(BuildHotspot.HALL_RUG2, 5, 6), + new Hotspot(BuildHotspot.HALL_RUG3, 1, 1), + new Hotspot(BuildHotspot.HALL_RUG3, 1, 6), + new Hotspot(BuildHotspot.HALL_RUG3, 6, 1), + new Hotspot(BuildHotspot.HALL_RUG3, 6, 6)), + + /** + * Games room. + */ + GAMES_ROOM(25000, 30, 0, 5, 4, Room.CHAMBER, + new Hotspot(BuildHotspot.RANGING_GAME, 1, 0), + new Hotspot(BuildHotspot.ATTACK_STONE, 2, 4), + new Hotspot(BuildHotspot.PRIZE_CHEST, 3, 7), + new Hotspot(BuildHotspot.ELEMENTAL_BALANCE, 5, 4), + new Hotspot(BuildHotspot.GAME_SPACE, 6, 0, 7, 1), + new Hotspot(BuildHotspot.WINDOW, 0, 2), + new Hotspot(BuildHotspot.WINDOW, 0, 5), + new Hotspot(BuildHotspot.WINDOW, 2, 0), + new Hotspot(BuildHotspot.WINDOW, 5, 0), + new Hotspot(BuildHotspot.WINDOW, 7, 2), + new Hotspot(BuildHotspot.WINDOW, 7, 5), + new Hotspot(BuildHotspot.WINDOW, 2, 7), + new Hotspot(BuildHotspot.WINDOW, 5, 7)), + + /** + * Combat room. + */ + COMBAT_ROOM(25000, 32, 0, 3, 4, Room.CHAMBER, new Hotspot(BuildHotspot.STORAGE_SPACE, 3, 7), + new Hotspot(BuildHotspot.WALL_DECORATION2, 1, 7), + new Hotspot(BuildHotspot.WALL_DECORATION2, 6, 7), + new Hotspot(BuildHotspot.WINDOW, 0, 2), + new Hotspot(BuildHotspot.WINDOW, 0, 5), + new Hotspot(BuildHotspot.WINDOW, 2, 0), + new Hotspot(BuildHotspot.WINDOW, 5, 0), + new Hotspot(BuildHotspot.WINDOW, 7, 2), + new Hotspot(BuildHotspot.WINDOW, 7, 5), + new Hotspot(BuildHotspot.WINDOW, 2, 7), + new Hotspot(BuildHotspot.WINDOW, 5, 7), + new Hotspot(BuildHotspot.CR_CORNER, 6, 1), + new Hotspot(BuildHotspot.CR_CORNER2, 1, 1), + new Hotspot(BuildHotspot.CR_CORNER3, 1, 6), + new Hotspot(BuildHotspot.CR_CORNER4, 6, 6), + new Hotspot(BuildHotspot.CR_RING, 2, 1), + new Hotspot(BuildHotspot.CR_RING, 3, 1), + new Hotspot(BuildHotspot.CR_RING, 4, 1), + new Hotspot(BuildHotspot.CR_RING2, 5, 1), + new Hotspot(BuildHotspot.CR_RING, 1, 2), + new Hotspot(BuildHotspot.CR_RING, 1, 3), + new Hotspot(BuildHotspot.CR_RING, 1, 4), + new Hotspot(BuildHotspot.CR_RING3, 1, 5), + new Hotspot(BuildHotspot.CR_RING3, 2, 6), + new Hotspot(BuildHotspot.CR_RING4, 3, 6), + new Hotspot(BuildHotspot.CR_RING4, 4, 6), + new Hotspot(BuildHotspot.CR_RING4, 5, 6), + new Hotspot(BuildHotspot.CR_RING4, 6, 5), + new Hotspot(BuildHotspot.CR_RING, 6, 4), + new Hotspot(BuildHotspot.CR_RING, 6, 3), + new Hotspot(BuildHotspot.CR_RING2, 6, 2), + new Hotspot(BuildHotspot.CR_FLOOR7, 2, 2), + new Hotspot(BuildHotspot.CR_FLOOR4, 2, 3), + new Hotspot(BuildHotspot.CR_FLOOR4, 2, 4), + new Hotspot(BuildHotspot.CR_FLOOR3, 2, 5), + new Hotspot(BuildHotspot.CR_FLOOR6, 3, 2), + new Hotspot(BuildHotspot.CR_FLOOR5, 3, 3), + new Hotspot(BuildHotspot.CR_FLOOR5, 3, 4), + new Hotspot(BuildHotspot.CR_FLOOR, 3, 5), + new Hotspot(BuildHotspot.CR_FLOOR6, 4, 2), + new Hotspot(BuildHotspot.CR_FLOOR5, 4, 3), + new Hotspot(BuildHotspot.CR_FLOOR5, 4, 4), + new Hotspot(BuildHotspot.CR_FLOOR, 4, 5), + new Hotspot(BuildHotspot.CR_FLOOR8, 5, 2), + new Hotspot(BuildHotspot.CR_FLOOR4, 5, 3), + new Hotspot(BuildHotspot.CR_FLOOR4, 5, 4), + new Hotspot(BuildHotspot.CR_FLOOR2, 5, 5), + new Hotspot(BuildHotspot.CR_INVISIBLE_WALL2, 2, 4), + new Hotspot(BuildHotspot.CR_INVISIBLE_WALL, 3, 5), + new Hotspot(BuildHotspot.CR_INVISIBLE_WALL, 5, 3), + new Hotspot(BuildHotspot.CR_INVISIBLE_WALL, 4, 2)), + + /** + * Quest trophy hall. + */ + QUEST_HALL(25000, 35, 0, 5, 6, Room.CHAMBER, new Hotspot(BuildHotspot.QUEST_STAIRWAYS, 3, 3, 4, 4), + new Hotspot(BuildHotspot.MAP, 7, 1), + new Hotspot(BuildHotspot.SWORD, 7, 6), + new Hotspot(BuildHotspot.LANDSCAPE, 6, 7), + new Hotspot(BuildHotspot.PORTRAIT, 1, 7), + new Hotspot(BuildHotspot.GUILD_TROPHY, 0, 6), + new Hotspot(BuildHotspot.BOOKCASE2, 0, 1), + new Hotspot(BuildHotspot.WINDOW, 0, 2), + new Hotspot(BuildHotspot.WINDOW, 0, 5), + new Hotspot(BuildHotspot.WINDOW, 2, 0), + new Hotspot(BuildHotspot.WINDOW, 5, 0), + new Hotspot(BuildHotspot.WINDOW, 7, 2), + new Hotspot(BuildHotspot.WINDOW, 7, 5), + new Hotspot(BuildHotspot.WINDOW, 2, 7), + new Hotspot(BuildHotspot.WINDOW, 5, 7), + new Hotspot(BuildHotspot.Q_HALL_RUG, 2, 2), + new Hotspot(BuildHotspot.Q_HALL_RUG, 3, 2), + new Hotspot(BuildHotspot.Q_HALL_RUG, 4, 2), + new Hotspot(BuildHotspot.Q_HALL_RUG, 5, 2), + new Hotspot(BuildHotspot.Q_HALL_RUG, 2, 3), + new Hotspot(BuildHotspot.Q_HALL_RUG, 3, 3), + new Hotspot(BuildHotspot.Q_HALL_RUG, 4, 3), + new Hotspot(BuildHotspot.Q_HALL_RUG, 5, 3), + new Hotspot(BuildHotspot.Q_HALL_RUG, 2, 4), + new Hotspot(BuildHotspot.Q_HALL_RUG, 3, 4), + new Hotspot(BuildHotspot.Q_HALL_RUG, 4, 4), + new Hotspot(BuildHotspot.Q_HALL_RUG, 5, 4), + new Hotspot(BuildHotspot.Q_HALL_RUG, 2, 5), + new Hotspot(BuildHotspot.Q_HALL_RUG, 3, 5), + new Hotspot(BuildHotspot.Q_HALL_RUG, 4, 5), + new Hotspot(BuildHotspot.Q_HALL_RUG, 5, 5), + new Hotspot(BuildHotspot.Q_HALL_RUG2, 1, 2), + new Hotspot(BuildHotspot.Q_HALL_RUG2, 1, 3), + new Hotspot(BuildHotspot.Q_HALL_RUG2, 1, 4), + new Hotspot(BuildHotspot.Q_HALL_RUG2, 1, 5), + new Hotspot(BuildHotspot.Q_HALL_RUG2, 6, 2), + new Hotspot(BuildHotspot.Q_HALL_RUG2, 6, 3), + new Hotspot(BuildHotspot.Q_HALL_RUG2, 6, 4), + new Hotspot(BuildHotspot.Q_HALL_RUG2, 6, 5), + new Hotspot(BuildHotspot.Q_HALL_RUG2, 2, 1), + new Hotspot(BuildHotspot.Q_HALL_RUG2, 3, 1), + new Hotspot(BuildHotspot.Q_HALL_RUG2, 4, 1), + new Hotspot(BuildHotspot.Q_HALL_RUG2, 5, 1), + new Hotspot(BuildHotspot.Q_HALL_RUG2, 2, 6), + new Hotspot(BuildHotspot.Q_HALL_RUG2, 3, 6), + new Hotspot(BuildHotspot.Q_HALL_RUG2, 4, 6), + new Hotspot(BuildHotspot.Q_HALL_RUG2, 5, 6), + new Hotspot(BuildHotspot.Q_HALL_RUG3, 1, 1), + new Hotspot(BuildHotspot.Q_HALL_RUG3, 1, 6), + new Hotspot(BuildHotspot.Q_HALL_RUG3, 6, 1), + new Hotspot(BuildHotspot.Q_HALL_RUG3, 6, 6)), + + /** + * Study. + */ + STUDY_ROOM(50000, 40, 0, 4, 5, Room.CHAMBER, new Hotspot(BuildHotspot.GLOBE, 1, 4, 3, 6), + new Hotspot(BuildHotspot.LECTERN, 2, 2), + new Hotspot(BuildHotspot.CRYSTAL_BALL, 5, 2), + new Hotspot(BuildHotspot.BOOKCASE3, 3, 7, 3, 7), + new Hotspot(BuildHotspot.BOOKCASE3, 4, 7, 4, 7), + new Hotspot(BuildHotspot.WALL_CHART, 1, 7), + new Hotspot(BuildHotspot.WALL_CHART, 6, 7), + new Hotspot(BuildHotspot.WALL_CHART, 7, 1), + new Hotspot(BuildHotspot.WALL_CHART, 0, 1), + new Hotspot(BuildHotspot.TELESCOPE, 5, 7), + new Hotspot(BuildHotspot.WINDOW, 0, 2), + new Hotspot(BuildHotspot.WINDOW, 0, 5), + new Hotspot(BuildHotspot.WINDOW, 2, 0), + new Hotspot(BuildHotspot.WINDOW, 5, 0), + new Hotspot(BuildHotspot.WINDOW, 7, 2), + new Hotspot(BuildHotspot.WINDOW, 7, 5), + new Hotspot(BuildHotspot.WINDOW, 2, 7), + new Hotspot(BuildHotspot.WINDOW, 5, 7)), + + /** + * Costume room. + */ + COSTUME_ROOM(50000, 42, 0, 6, 1, Room.CHAMBER, new Hotspot(BuildHotspot.WINDOW, 0, 2), + new Hotspot(BuildHotspot.WINDOW, 0, 5), + new Hotspot(BuildHotspot.WINDOW, 2, 0), + new Hotspot(BuildHotspot.WINDOW, 5, 0), + new Hotspot(BuildHotspot.WINDOW, 7, 2), + new Hotspot(BuildHotspot.WINDOW, 7, 5), + new Hotspot(BuildHotspot.TREASURE_CHEST, 0, 3, 0, 4), + new Hotspot(BuildHotspot.ARMOUR_CASE, 2, 7), + new Hotspot(BuildHotspot.MAGIC_WARDROBE, 3, 7, 5, 7), + new Hotspot(BuildHotspot.CAPE_RACK, 6, 6), + new Hotspot(BuildHotspot.TOY_BOX, 7, 3, 7, 4), + new Hotspot(BuildHotspot.COSTUME_BOX, 3, 3, 4, 4)), + + /** + * Chapel room. + */ + CHAPEL(50000, 45, 0, 2, 5, Room.CHAMBER, + new Hotspot(BuildHotspot.ALTAR, 3, 5, 4, 5), + new Hotspot(BuildHotspot.STATUE, 7, 0), + new Hotspot(BuildHotspot.STATUE, 0, 0), + new Hotspot(BuildHotspot.ICON, 3, 7, 4, 7), + new Hotspot(BuildHotspot.MUSICAL, 7, 3, 7, 4), + new Hotspot(BuildHotspot.BURNERS, 1, 5), + new Hotspot(BuildHotspot.BURNERS, 6, 5), + new Hotspot(BuildHotspot.CHAPEL_RUG, 3, 1), + new Hotspot(BuildHotspot.CHAPEL_RUG, 4, 1), + new Hotspot(BuildHotspot.CHAPEL_RUG, 3, 2), + new Hotspot(BuildHotspot.CHAPEL_RUG, 4, 2), + new Hotspot(BuildHotspot.CHAPEL_RUG, 3, 3), + new Hotspot(BuildHotspot.CHAPEL_RUG, 4, 3), + new Hotspot(BuildHotspot.CHAPEL_RUG2, 3, 0), + new Hotspot(BuildHotspot.CHAPEL_RUG2, 4, 0), + new Hotspot(BuildHotspot.CHAPEL_RUG2, 3, 4), + new Hotspot(BuildHotspot.CHAPEL_RUG2, 4, 4), + new Hotspot(BuildHotspot.CHAPEL_WINDOW, 0, 2), + new Hotspot(BuildHotspot.CHAPEL_WINDOW, 0, 5), + new Hotspot(BuildHotspot.CHAPEL_WINDOW, 2, 7), + new Hotspot(BuildHotspot.CHAPEL_WINDOW, 5, 7), + new Hotspot(BuildHotspot.CHAPEL_WINDOW, 7, 5), + new Hotspot(BuildHotspot.CHAPEL_WINDOW, 7, 2)), + + /** + * Portal chamber. + */ + PORTAL_CHAMBER(100000, 50, 0, 1, 4, Room.CHAMBER, new Hotspot(BuildHotspot.TELEPORT_FOCUS, 3, 3, 4, 4), + new Hotspot(BuildHotspot.PORTAL1, 0, 3, 0, 4), + new Hotspot(BuildHotspot.PORTAL2, 3, 7, 4, 7), + new Hotspot(BuildHotspot.PORTAL3, 7, 3, 7, 4), + new Hotspot(BuildHotspot.WINDOW, 0, 2), + new Hotspot(BuildHotspot.WINDOW, 0, 5), + new Hotspot(BuildHotspot.WINDOW, 2, 0), + new Hotspot(BuildHotspot.WINDOW, 5, 0), + new Hotspot(BuildHotspot.WINDOW, 7, 2), + new Hotspot(BuildHotspot.WINDOW, 7, 5), + new Hotspot(BuildHotspot.WINDOW, 2, 7), + new Hotspot(BuildHotspot.WINDOW, 5, 7)), + + /** + * The formal garden. + * Centrepiece should be first! + */ + FORMAL_GARDEN(75000, 55, 0, 2, 1, Room.LAND, new Hotspot(BuildHotspot.CENTREPIECE_2, 3, 3, 4, 4), + new Hotspot(BuildHotspot.FENCING, 0, 0), + new Hotspot(BuildHotspot.FENCING, 1, 0), + new Hotspot(BuildHotspot.FENCING, 2, 0), + new Hotspot(BuildHotspot.FENCING, 5, 0), + new Hotspot(BuildHotspot.FENCING, 6, 0), + new Hotspot(BuildHotspot.FENCING, 7, 0), + new Hotspot(BuildHotspot.FENCING, 7, 1), + new Hotspot(BuildHotspot.FENCING, 7, 2), + new Hotspot(BuildHotspot.FENCING, 7, 5), + new Hotspot(BuildHotspot.FENCING, 7, 6), + new Hotspot(BuildHotspot.FENCING, 7, 7), + new Hotspot(BuildHotspot.FENCING, 6, 7), + new Hotspot(BuildHotspot.FENCING, 5, 7), + new Hotspot(BuildHotspot.FENCING, 2, 7), + new Hotspot(BuildHotspot.FENCING, 1, 7), + new Hotspot(BuildHotspot.FENCING, 0, 7), + new Hotspot(BuildHotspot.FENCING, 0, 6), + new Hotspot(BuildHotspot.FENCING, 0, 5), + new Hotspot(BuildHotspot.FENCING, 0, 2), + new Hotspot(BuildHotspot.FENCING, 0, 1), + new Hotspot(BuildHotspot.HEDGE3, 0, 0), + new Hotspot(BuildHotspot.HEDGE2, 1, 0), + new Hotspot(BuildHotspot.HEDGE1, 2, 0), + new Hotspot(BuildHotspot.HEDGE1, 5, 0), + new Hotspot(BuildHotspot.HEDGE2, 6, 0), + new Hotspot(BuildHotspot.HEDGE3, 7, 0), + new Hotspot(BuildHotspot.HEDGE2, 7, 1), + new Hotspot(BuildHotspot.HEDGE1, 7, 2), + new Hotspot(BuildHotspot.HEDGE1, 7, 5), + new Hotspot(BuildHotspot.HEDGE2, 7, 6), + new Hotspot(BuildHotspot.HEDGE3, 7, 7), + new Hotspot(BuildHotspot.HEDGE2, 6, 7), + new Hotspot(BuildHotspot.HEDGE1, 5, 7), + new Hotspot(BuildHotspot.HEDGE1, 2, 7), + new Hotspot(BuildHotspot.HEDGE2, 1, 7), + new Hotspot(BuildHotspot.HEDGE3, 0, 7), + new Hotspot(BuildHotspot.HEDGE2, 0, 6), + new Hotspot(BuildHotspot.HEDGE1, 0, 5), + new Hotspot(BuildHotspot.HEDGE1, 0, 2), + new Hotspot(BuildHotspot.HEDGE2, 0, 1), + new Hotspot(BuildHotspot.SMALL_PLANT2, 2, 1), + new Hotspot(BuildHotspot.SMALL_PLANT2, 1, 2), + new Hotspot(BuildHotspot.SMALL_PLANT2, 5, 6), + new Hotspot(BuildHotspot.SMALL_PLANT2, 6, 5), + new Hotspot(BuildHotspot.SMALL_PLANT2, 2, 6), + new Hotspot(BuildHotspot.SMALL_PLANT2, 1, 5), + new Hotspot(BuildHotspot.BIG_PLANT2, 1, 1), + new Hotspot(BuildHotspot.BIG_PLANT2, 6, 6), + new Hotspot(BuildHotspot.BIG_PLANT2, 1, 6), + new Hotspot(BuildHotspot.SMALL_PLANT1, 5, 1), + new Hotspot(BuildHotspot.SMALL_PLANT1, 6, 2), + new Hotspot(BuildHotspot.SMALL_PLANT1, 1, 5), + new Hotspot(BuildHotspot.SMALL_PLANT1, 2, 1), + new Hotspot(BuildHotspot.SMALL_PLANT1, 2, 6), + new Hotspot(BuildHotspot.BIG_PLANT1, 1, 6), + new Hotspot(BuildHotspot.BIG_PLANT1, 1, 1), + new Hotspot(BuildHotspot.BIG_PLANT1, 6, 1)), + + /** + * Throne room. + */ + THRONE_ROOM(150000, 60, 0, 6, 5, Room.CHAMBER, + new Hotspot(BuildHotspot.WINDOW, 0, 2), + new Hotspot(BuildHotspot.WINDOW, 0, 5), + new Hotspot(BuildHotspot.WINDOW, 2, 0), + new Hotspot(BuildHotspot.WINDOW, 5, 0), + new Hotspot(BuildHotspot.WINDOW, 7, 2), + new Hotspot(BuildHotspot.WINDOW, 7, 5), + new Hotspot(BuildHotspot.WINDOW, 2, 7), + new Hotspot(BuildHotspot.WINDOW, 5, 7), + new Hotspot(BuildHotspot.THRONE, 3, 6), + new Hotspot(BuildHotspot.THRONE, 4, 6), + new Hotspot(BuildHotspot.LEVER, 6, 6), + new Hotspot(BuildHotspot.FLOOR, 3, 3), + new Hotspot(BuildHotspot.FLOOR, 3, 4), + new Hotspot(BuildHotspot.FLOOR, 4, 4), + new Hotspot(BuildHotspot.FLOOR, 4, 3), + new Hotspot(BuildHotspot.TRAPDOOR, 1, 6), + new Hotspot(BuildHotspot.SEATING1, 0, 0), + new Hotspot(BuildHotspot.SEATING1, 0, 1), + new Hotspot(BuildHotspot.SEATING1, 0, 2), + new Hotspot(BuildHotspot.SEATING1, 0, 3), + new Hotspot(BuildHotspot.SEATING1, 0, 4), + new Hotspot(BuildHotspot.SEATING1, 0, 5), + new Hotspot(BuildHotspot.SEATING2, 7, 0), + new Hotspot(BuildHotspot.SEATING2, 7, 1), + new Hotspot(BuildHotspot.SEATING2, 7, 2), + new Hotspot(BuildHotspot.SEATING2, 7, 3), + new Hotspot(BuildHotspot.SEATING2, 7, 4), + new Hotspot(BuildHotspot.SEATING2, 7, 5), + new Hotspot(BuildHotspot.DECORATION, 3, 7), + new Hotspot(BuildHotspot.DECORATION, 4, 7)), + + /** + * Oubliette (dungeon). + */ + OUBILETTE(150000, 65, 0, 6, 3, Room.DUNGEON, + new Hotspot(BuildHotspot.FLOOR_CORNER, 2, 2), + new Hotspot(BuildHotspot.FLOOR_CORNER, 5, 2), + new Hotspot(BuildHotspot.FLOOR_CORNER, 5, 5), + new Hotspot(BuildHotspot.FLOOR_CORNER, 2, 5), + new Hotspot(BuildHotspot.FLOOR_SIDE, 3, 2), + new Hotspot(BuildHotspot.FLOOR_SIDE, 4, 2), + new Hotspot(BuildHotspot.FLOOR_SIDE, 2, 3), + new Hotspot(BuildHotspot.FLOOR_SIDE, 2, 4), + new Hotspot(BuildHotspot.FLOOR_SIDE, 5, 3), + new Hotspot(BuildHotspot.FLOOR_SIDE, 5, 4), + new Hotspot(BuildHotspot.FLOOR_SIDE, 3, 5), + new Hotspot(BuildHotspot.FLOOR_SIDE, 4, 5), + new Hotspot(BuildHotspot.FLOOR_MID, 3, 3), + new Hotspot(BuildHotspot.FLOOR_MID, 3, 4), + new Hotspot(BuildHotspot.FLOOR_MID, 4, 3), + new Hotspot(BuildHotspot.FLOOR_MID, 4, 4), + new Hotspot(BuildHotspot.OUBLIETTE_FLOOR, 2, 2), + new Hotspot(BuildHotspot.OUBLIETTE_FLOOR, 5, 2), + new Hotspot(BuildHotspot.OUBLIETTE_FLOOR, 5, 5), + new Hotspot(BuildHotspot.OUBLIETTE_FLOOR, 2, 5), + new Hotspot(BuildHotspot.OUBLIETTE_FLOOR, 3, 2), + new Hotspot(BuildHotspot.OUBLIETTE_FLOOR, 4, 2), + new Hotspot(BuildHotspot.OUBLIETTE_FLOOR, 2, 3), + new Hotspot(BuildHotspot.OUBLIETTE_FLOOR, 2, 4), + new Hotspot(BuildHotspot.OUBLIETTE_FLOOR, 5, 3), + new Hotspot(BuildHotspot.OUBLIETTE_FLOOR, 5, 4), + new Hotspot(BuildHotspot.OUBLIETTE_FLOOR, 3, 5), + new Hotspot(BuildHotspot.OUBLIETTE_FLOOR, 4, 5), + new Hotspot(BuildHotspot.OUBLIETTE_FLOOR, 3, 3), + new Hotspot(BuildHotspot.OUBLIETTE_FLOOR, 3, 4), + new Hotspot(BuildHotspot.OUBLIETTE_FLOOR_1, 4, 3), + new Hotspot(BuildHotspot.OUBLIETTE_FLOOR, 4, 4), + new Hotspot(BuildHotspot.GUARD, 0, 0), + new Hotspot(BuildHotspot.DUNGEON_DECO, 0, 2), + new Hotspot(BuildHotspot.DUNGEON_DECO, 2, 7), + new Hotspot(BuildHotspot.DUNGEON_DECO, 7, 5), + new Hotspot(BuildHotspot.DUNGEON_DECO, 5, 0), + new Hotspot(BuildHotspot.OUBLIETTE_LIGHT, 2, 0), + new Hotspot(BuildHotspot.OUBLIETTE_LIGHT, 7, 2), + new Hotspot(BuildHotspot.OUBLIETTE_LIGHT, 5, 7), + new Hotspot(BuildHotspot.OUBLIETTE_LIGHT, 0, 5), + new Hotspot(BuildHotspot.LADDER, 1, 6), + new Hotspot(BuildHotspot.PRISON, 2, 2), + new Hotspot(BuildHotspot.PRISON, 2, 5), + new Hotspot(BuildHotspot.PRISON, 2, 3), + new Hotspot(BuildHotspot.PRISON, 2, 4), + new Hotspot(BuildHotspot.PRISON, 5, 2), + new Hotspot(BuildHotspot.PRISON, 5, 5), + new Hotspot(BuildHotspot.PRISON, 3, 2), + new Hotspot(BuildHotspot.PRISON, 4, 2), + new Hotspot(BuildHotspot.PRISON, 5, 3), + new Hotspot(BuildHotspot.PRISON, 5, 4), + new Hotspot(BuildHotspot.PRISON, 4, 5), + new Hotspot(BuildHotspot.PRISON_DOOR, 3, 5)), + + /** + * Dungeon corridor. + */ + DUNGEON_CORRIDOR(7500, 70, 0, 4, 3, Room.DUNGEON, + new Hotspot(BuildHotspot.DUNGEON_DOOR_RIGHT, 3, 1), + new Hotspot(BuildHotspot.DUNGEON_DOOR_LEFT, 4, 1), + new Hotspot(BuildHotspot.DUNGEON_DOOR_LEFT2, 3, 6), + new Hotspot(BuildHotspot.DUNGEON_DOOR_RIGHT2, 4, 6), + new Hotspot(BuildHotspot.DUNGEON_LIGHT, 3, 1), + new Hotspot(BuildHotspot.DUNGEON_LIGHT, 4, 1), + new Hotspot(BuildHotspot.DUNGEON_TRAP2, 3, 2), + new Hotspot(BuildHotspot.DUNGEON_TRAP2, 4, 2), + new Hotspot(BuildHotspot.DUNGEON_GUARD, 3, 3), + new Hotspot(BuildHotspot.DUNGEON_DECO, 4, 3), + new Hotspot(BuildHotspot.DUNGEON_DECO, 3, 4), + new Hotspot(BuildHotspot.DUNGEON_TRAP, 3, 5), + new Hotspot(BuildHotspot.DUNGEON_TRAP, 4, 5), + new Hotspot(BuildHotspot.DUNGEON_LIGHT, 3, 6), + new Hotspot(BuildHotspot.DUNGEON_LIGHT, 4, 6)), + + /** + * Dungeon junction. + */ + DUNGEON_JUNCTION(7500, 70, 0, 0, 3, Room.DUNGEON, + new Hotspot(BuildHotspot.DUNGEON_DOOR_RIGHT, 3, 1), + new Hotspot(BuildHotspot.DUNGEON_DOOR_LEFT, 4, 1), + new Hotspot(BuildHotspot.DUNGEON_DOOR_LEFT2, 3, 6), + new Hotspot(BuildHotspot.DUNGEON_DOOR_RIGHT2, 4, 6), + new Hotspot(BuildHotspot.DUNGEON_LIGHT, 3, 1), + new Hotspot(BuildHotspot.DUNGEON_TRAP2, 3, 2), + new Hotspot(BuildHotspot.DUNGEON_TRAP2, 4, 2), + new Hotspot(BuildHotspot.DUNGEON_GUARD, 3, 3), + new Hotspot(BuildHotspot.DUNGEON_TRAP, 3, 5), + new Hotspot(BuildHotspot.DUNGEON_TRAP, 4, 5), + new Hotspot(BuildHotspot.DUNGEON_LIGHT, 4, 6), + new Hotspot(BuildHotspot.DUNGEON_DECO, 1, 3), + new Hotspot(BuildHotspot.DUNGEON_DECO, 6, 4), + new Hotspot(BuildHotspot.DUNGEON_LIGHT, 1, 4), + new Hotspot(BuildHotspot.DUNGEON_LIGHT, 6, 3)), + + /** + * Dungeon stairs. + */ + DUNGEON_STAIRS(7500, 70, 0, 2, 3, Room.DUNGEON, + new Hotspot(BuildHotspot.STAIRWAYS_DUNGEON, 3, 3), + new Hotspot(BuildHotspot.HALL_RUG, 3, 3), + new Hotspot(BuildHotspot.HALL_RUG, 4, 3), + new Hotspot(BuildHotspot.HALL_RUG, 3, 4), + new Hotspot(BuildHotspot.HALL_RUG, 4, 4), + new Hotspot(BuildHotspot.HALL_RUG2, 2, 3), + new Hotspot(BuildHotspot.HALL_RUG2, 2, 4), + new Hotspot(BuildHotspot.HALL_RUG2, 5, 3), + new Hotspot(BuildHotspot.HALL_RUG2, 5, 4), + new Hotspot(BuildHotspot.HALL_RUG2, 3, 2), + new Hotspot(BuildHotspot.HALL_RUG2, 4, 2), + new Hotspot(BuildHotspot.HALL_RUG2, 3, 5), + new Hotspot(BuildHotspot.HALL_RUG2, 4, 5), + new Hotspot(BuildHotspot.HALL_RUG3, 2, 2), + new Hotspot(BuildHotspot.HALL_RUG3, 2, 5), + new Hotspot(BuildHotspot.HALL_RUG3, 5, 2), + new Hotspot(BuildHotspot.HALL_RUG3, 5, 5), + new Hotspot(BuildHotspot.DUNGEON_DOOR_RIGHT, 3, 1), + new Hotspot(BuildHotspot.DUNGEON_DOOR_LEFT, 4, 1), + new Hotspot(BuildHotspot.DUNGEON_DOOR_LEFT2, 3, 6), + new Hotspot(BuildHotspot.DUNGEON_DOOR_RIGHT2, 4, 6), + new Hotspot(BuildHotspot.DUNGEON_LIGHT2, 2, 1), + new Hotspot(BuildHotspot.DUNGEON_LIGHT2, 5, 1), + new Hotspot(BuildHotspot.DUNGEON_LIGHT2, 2, 6), + new Hotspot(BuildHotspot.DUNGEON_LIGHT2, 5, 6), + new Hotspot(BuildHotspot.DUNGEON_GUARD3, 1, 1), + new Hotspot(BuildHotspot.DUNGEON_GUARD2, 5, 5), + new Hotspot(BuildHotspot.DUNGEON_DECO, 6, 1), + new Hotspot(BuildHotspot.DUNGEON_DECO, 1, 6)), + + /** + * Dungeon pit. + */ + DUNGEON_PIT(10000, 70, 0, 5, 2, Room.DUNGEON, + new Hotspot(BuildHotspot.DUNGEON_DOOR_RIGHT3, 3, 1), + new Hotspot(BuildHotspot.DUNGEON_DOOR_LEFT3, 4, 1), + new Hotspot(BuildHotspot.DUNGEON_DOOR_LEFT3, 3, 6), + new Hotspot(BuildHotspot.DUNGEON_DOOR_RIGHT3, 4, 6), + new Hotspot(BuildHotspot.DUNGEON_DOOR_RIGHT3, 1, 4), + new Hotspot(BuildHotspot.DUNGEON_DOOR_LEFT3, 1, 3), + new Hotspot(BuildHotspot.DUNGEON_DOOR_LEFT3, 6, 4), + new Hotspot(BuildHotspot.DUNGEON_DOOR_RIGHT3, 6, 3), + new Hotspot(BuildHotspot.DUNGEON_DECO, 5, 1), + new Hotspot(BuildHotspot.DUNGEON_DECO, 1, 6), + new Hotspot(BuildHotspot.DUNGEON_LIGHT2, 2, 1), + new Hotspot(BuildHotspot.DUNGEON_LIGHT, 2, 6), + new Hotspot(BuildHotspot.DUNGEON_LIGHT, 5, 1), + new Hotspot(BuildHotspot.DUNGEON_LIGHT2, 5, 6), + new Hotspot(BuildHotspot.DUNGEON_LIGHT, 1, 2), + new Hotspot(BuildHotspot.DUNGEON_LIGHT2, 1, 5), + new Hotspot(BuildHotspot.DUNGEON_LIGHT2, 6, 2), + new Hotspot(BuildHotspot.DUNGEON_LIGHT, 6, 5), + new Hotspot(BuildHotspot.DUNGEON_PIT_GUARD, 3, 3)), + + /** + * Treasure room. + */ + TREASURE_ROOM(250000, 75, 0, 7, 4, Room.DUNGEON, + new Hotspot(BuildHotspot.DUNGEON_DOOR_RIGHT2, 3, 1), + new Hotspot(BuildHotspot.DUNGEON_DOOR_LEFT2, 4, 1), + new Hotspot(BuildHotspot.DUNGEON_LIGHT, 2, 1), + new Hotspot(BuildHotspot.DUNGEON_LIGHT, 5, 1), + new Hotspot(BuildHotspot.DUNGEON_LIGHT, 1, 5), + new Hotspot(BuildHotspot.DUNGEON_LIGHT, 6, 5), + new Hotspot(BuildHotspot.DUNGEON_DECO, 1, 2), + new Hotspot(BuildHotspot.DUNGEON_DECO, 6, 2), + new Hotspot(BuildHotspot.MONSTER, 3, 3), + new Hotspot(BuildHotspot.TREASURE_CHEST1, 2, 6), + new Hotspot(BuildHotspot.WALL_DECORATION1, 3, 6), + new Hotspot(BuildHotspot.WALL_DECORATION1, 4, 6)), + + /** + * The roof top with 2 exits. + */ + ROOF_2_EXIT(0, 0, 0, 1, 2, Room.ROOF), + + /** + * The roof top with 3 exits. + */ + ROOF_3_EXIT(0, 0, 0, 3, 2, Room.ROOF), + + /** + * The roof top with 4 exits. + */ + ROOF_4_EXIT(0, 0, 0, 5, 2, Room.ROOF), + + /** + * Skill hall (upstairs) room. + */ + SKILL_HALL_2(0, 25, 0, 3, 6, Room.CHAMBER, new Hotspot(BuildHotspot.STAIRS_DOWN, 3, 3), + new Hotspot(BuildHotspot.ARMOUR_SPACE, 2, 3), + new Hotspot(BuildHotspot.ARMOUR_SPACE2, 5, 3), + new Hotspot(BuildHotspot.HEAD_TROPHY, 6, 7), + new Hotspot(BuildHotspot.RUNE_CASE, 0, 6), + new Hotspot(BuildHotspot.FISHING_TROPHY, 1, 7), + new Hotspot(BuildHotspot.WINDOW, 0, 2), + new Hotspot(BuildHotspot.WINDOW, 0, 5), + new Hotspot(BuildHotspot.WINDOW, 2, 0), + new Hotspot(BuildHotspot.WINDOW, 5, 0), + new Hotspot(BuildHotspot.WINDOW, 7, 2), + new Hotspot(BuildHotspot.WINDOW, 7, 5), + new Hotspot(BuildHotspot.WINDOW, 2, 7), + new Hotspot(BuildHotspot.WINDOW, 5, 7), + new Hotspot(BuildHotspot.HALL_RUG, 2, 2), + new Hotspot(BuildHotspot.HALL_RUG, 3, 2), + new Hotspot(BuildHotspot.HALL_RUG, 4, 2), + new Hotspot(BuildHotspot.HALL_RUG, 5, 2), + new Hotspot(BuildHotspot.HALL_RUG, 2, 3), + new Hotspot(BuildHotspot.HALL_RUG, 3, 3), + new Hotspot(BuildHotspot.HALL_RUG, 4, 3), + new Hotspot(BuildHotspot.HALL_RUG, 5, 3), + new Hotspot(BuildHotspot.HALL_RUG, 2, 4), + new Hotspot(BuildHotspot.HALL_RUG, 3, 4), + new Hotspot(BuildHotspot.HALL_RUG, 4, 4), + new Hotspot(BuildHotspot.HALL_RUG, 5, 4), + new Hotspot(BuildHotspot.HALL_RUG, 2, 5), + new Hotspot(BuildHotspot.HALL_RUG, 3, 5), + new Hotspot(BuildHotspot.HALL_RUG, 4, 5), + new Hotspot(BuildHotspot.HALL_RUG, 5, 5), + new Hotspot(BuildHotspot.HALL_RUG2, 1, 2), + new Hotspot(BuildHotspot.HALL_RUG2, 1, 3), + new Hotspot(BuildHotspot.HALL_RUG2, 1, 4), + new Hotspot(BuildHotspot.HALL_RUG2, 1, 5), + new Hotspot(BuildHotspot.HALL_RUG2, 6, 2), + new Hotspot(BuildHotspot.HALL_RUG2, 6, 3), + new Hotspot(BuildHotspot.HALL_RUG2, 6, 4), + new Hotspot(BuildHotspot.HALL_RUG2, 6, 5), + new Hotspot(BuildHotspot.HALL_RUG2, 2, 1), + new Hotspot(BuildHotspot.HALL_RUG2, 3, 1), + new Hotspot(BuildHotspot.HALL_RUG2, 4, 1), + new Hotspot(BuildHotspot.HALL_RUG2, 5, 1), + new Hotspot(BuildHotspot.HALL_RUG2, 2, 6), + new Hotspot(BuildHotspot.HALL_RUG2, 3, 6), + new Hotspot(BuildHotspot.HALL_RUG2, 4, 6), + new Hotspot(BuildHotspot.HALL_RUG2, 5, 6), + new Hotspot(BuildHotspot.HALL_RUG3, 1, 1), + new Hotspot(BuildHotspot.HALL_RUG3, 1, 6), + new Hotspot(BuildHotspot.HALL_RUG3, 6, 1), + new Hotspot(BuildHotspot.HALL_RUG3, 6, 6)), + + /** + * Quest trophy hall (upstairs). + */ + QUEST_HALL_2(25000, 35, 0, 7, 6, Room.CHAMBER, new Hotspot(BuildHotspot.STAIRS_DOWN2, 3, 3), + new Hotspot(BuildHotspot.MAP, 7, 1), + new Hotspot(BuildHotspot.SWORD, 7, 6), + new Hotspot(BuildHotspot.LANDSCAPE, 6, 7), + new Hotspot(BuildHotspot.PORTRAIT, 1, 7), + new Hotspot(BuildHotspot.GUILD_TROPHY, 0, 6), + new Hotspot(BuildHotspot.BOOKCASE2, 0, 1), + new Hotspot(BuildHotspot.WINDOW, 0, 2), + new Hotspot(BuildHotspot.WINDOW, 0, 5), + new Hotspot(BuildHotspot.WINDOW, 2, 0), + new Hotspot(BuildHotspot.WINDOW, 5, 0), + new Hotspot(BuildHotspot.WINDOW, 7, 2), + new Hotspot(BuildHotspot.WINDOW, 7, 5), + new Hotspot(BuildHotspot.WINDOW, 2, 7), + new Hotspot(BuildHotspot.WINDOW, 5, 7), + new Hotspot(BuildHotspot.Q_HALL_RUG, 2, 2), + new Hotspot(BuildHotspot.Q_HALL_RUG, 3, 2), + new Hotspot(BuildHotspot.Q_HALL_RUG, 4, 2), + new Hotspot(BuildHotspot.Q_HALL_RUG, 5, 2), + new Hotspot(BuildHotspot.Q_HALL_RUG, 2, 3), + new Hotspot(BuildHotspot.Q_HALL_RUG, 3, 3), + new Hotspot(BuildHotspot.Q_HALL_RUG, 4, 3), + new Hotspot(BuildHotspot.Q_HALL_RUG, 5, 3), + new Hotspot(BuildHotspot.Q_HALL_RUG, 2, 4), + new Hotspot(BuildHotspot.Q_HALL_RUG, 3, 4), + new Hotspot(BuildHotspot.Q_HALL_RUG, 4, 4), + new Hotspot(BuildHotspot.Q_HALL_RUG, 5, 4), + new Hotspot(BuildHotspot.Q_HALL_RUG, 2, 5), + new Hotspot(BuildHotspot.Q_HALL_RUG, 3, 5), + new Hotspot(BuildHotspot.Q_HALL_RUG, 4, 5), + new Hotspot(BuildHotspot.Q_HALL_RUG, 5, 5), + new Hotspot(BuildHotspot.Q_HALL_RUG2, 1, 2), + new Hotspot(BuildHotspot.Q_HALL_RUG2, 1, 3), + new Hotspot(BuildHotspot.Q_HALL_RUG2, 1, 4), + new Hotspot(BuildHotspot.Q_HALL_RUG2, 1, 5), + new Hotspot(BuildHotspot.Q_HALL_RUG2, 6, 2), + new Hotspot(BuildHotspot.Q_HALL_RUG2, 6, 3), + new Hotspot(BuildHotspot.Q_HALL_RUG2, 6, 4), + new Hotspot(BuildHotspot.Q_HALL_RUG2, 6, 5), + new Hotspot(BuildHotspot.Q_HALL_RUG2, 2, 1), + new Hotspot(BuildHotspot.Q_HALL_RUG2, 3, 1), + new Hotspot(BuildHotspot.Q_HALL_RUG2, 4, 1), + new Hotspot(BuildHotspot.Q_HALL_RUG2, 5, 1), + new Hotspot(BuildHotspot.Q_HALL_RUG2, 2, 6), + new Hotspot(BuildHotspot.Q_HALL_RUG2, 3, 6), + new Hotspot(BuildHotspot.Q_HALL_RUG2, 4, 6), + new Hotspot(BuildHotspot.Q_HALL_RUG2, 5, 6), + new Hotspot(BuildHotspot.Q_HALL_RUG3, 1, 1), + new Hotspot(BuildHotspot.Q_HALL_RUG3, 1, 6), + new Hotspot(BuildHotspot.Q_HALL_RUG3, 6, 1), + new Hotspot(BuildHotspot.Q_HALL_RUG3, 6, 6)), + ; + + /** + * The amount this room costs. + */ + private final int cost; + + /** + * The level required. + */ + private final int level; + + /** + * The chunk plane. + */ + private final int z; + + /** + * The chunk x-offset. + */ + private final int chunkX; + + /** + * The chunk y-offset. + */ + private final int chunkY; + + /** + * If doors should be placed. + */ + private final int configuration; + + /** + * The hotspots in this room. + */ + private final Hotspot[] hotspots; + + /** + * Constructs a new {@code RoomProperties} {@code Object}. + * @param cost The cost of building this room. + * @param level The construction level required. + * @param z The chunk plane. + * @param chunkX The chunk x-offset. + * @param chunkY The chunk y-offset. + * @param hotspots The hotspots. + */ + private RoomProperties(int cost, int level, int z, int chunkX, int chunkY, int configuration, Hotspot...hotspots) { + this.cost = cost; + this.level = level; + this.z = z; + this.chunkX = chunkX; + this.chunkY = chunkY; + this.configuration = configuration; + this.hotspots = hotspots; + } + + /** + * Gets the name of the room. + * @return The name. + */ + public String getName() { + return name().toLowerCase().replaceAll("_", " ").replaceAll("\\d", ""); + } + + /** + * Gets the available exits for the room. + * @return The exits. + */ + public boolean[] getExits() { + Region region = RegionManager.forId(7503); + Region.load(region, true); + RegionChunk chunk = region.getPlanes()[0].getRegionChunk(chunkX, chunkY); + return new boolean[] { isExit(chunk, 7, 3), isExit(chunk, 3, 0), isExit(chunk, 0, 3), isExit(chunk, 3, 7) }; + } + + /** + * Checks if the object on the given chunk coordinates is a door. + * @return {@code True} if so. + */ + private boolean isExit(RegionChunk chunk, int x, int y) { + for (Scenery object : chunk.getObjects(x, y)) { + if (object != null && (object.getId() == 15313 || object.getId() == 15314 || object.getId() == 15317)) { + return true; + } + } + return false; + } + + /** + * Checks if the room is a chamber inside the house (not a garden or roof). + * @return {@code True} if so. + */ + public boolean isChamber() { + return !isLand() && !isRoof(); //&& !isDungeon(); + } + + /** + * Checks if this room is used for landscape (garden). + * @return {@code True} if so. + */ + public boolean isLand() { + return (configuration & Room.LAND) != 0; + } + + /** + * Checks if the room is used for roofs. + * @return {@code True} if so. + */ + public boolean isRoof() { + return (configuration & Room.ROOF) != 0; + } + + /** + * Checks if the room is used for dungeons. + * @return {@code True} if so. + */ + public boolean isDungeon() { + return (configuration & Room.DUNGEON) != 0; + } + + /** + * Gets the z. + * @return The z. + */ + public int getZ() { + return z; + } + + /** + * Gets the chunkX. + * @return The chunkX. + */ + public int getChunkX() { + return chunkX; + } + + /** + * Gets the chunkY. + * @return The chunkY. + */ + public int getChunkY() { + return chunkY; + } + + /** + * Gets the hotspots. + * @return The hotspots. + */ + public Hotspot[] getHotspots() { + return hotspots; + } + + /** + * Gets the cost. + * @return the cost + */ + public int getCost() { + return cost; + } + + /** + * Gets the level. + * @return the level + */ + public int getLevel() { + return level; + } +} diff --git a/Server/src/main/content/global/skill/construction/RoomTemplate.kt b/Server/src/main/content/global/skill/construction/RoomTemplate.kt new file mode 100644 index 0000000..b1a6801 --- /dev/null +++ b/Server/src/main/content/global/skill/construction/RoomTemplate.kt @@ -0,0 +1,34 @@ +package content.global.skill.construction + +import content.global.skill.construction.RoomProperties + +class RoomTemplate(properties: RoomProperties) { + var hotspots: MutableList = ArrayList() + + init { + for(property in properties.hotspots){ + hotspots.add(Hotspot(property.hotspot,property.chunkX,property.chunkY,property.chunkX2,property.chunkY2)) + } + } + + fun rotate(clockwise: Boolean){ + hotspots = hotspots.map{ + if(!clockwise) { + val newChunkX = it.chunkY + val newChunkY = 7 - it.chunkX + val newChunkX2 = it.chunkY2 + val newChunkY2 = 7 - it.chunkX2 + Hotspot(it.hotspot,newChunkX,newChunkY,newChunkX2,newChunkY2) + } else { + val newChunkY = it.chunkX + val newChunkX = 7 - it.chunkY + val newChunkY2 = it.chunkX2 + val newChunkX2 = 7 - it.chunkY2 + Hotspot(it.hotspot,newChunkX,newChunkY,newChunkX2,newChunkY2) + } + }.toMutableList() + } + + + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/Servant.java b/Server/src/main/content/global/skill/construction/Servant.java new file mode 100644 index 0000000..a3527bd --- /dev/null +++ b/Server/src/main/content/global/skill/construction/Servant.java @@ -0,0 +1,116 @@ +package content.global.skill.construction; + + +import core.game.node.entity.npc.NPC; +import core.game.node.item.Item; +import org.json.simple.JSONObject; + +/** + * Represents a player's servant. + * @author Emperor + * + */ +public final class Servant extends NPC { + + /** + * The servant type. + */ + private final ServantType type; + + /** + * The item the servant is carrying. + */ + private Item item; + + /** + * The amount this servant has been used. + */ + private int uses; + + /** + * If the servant is greeting players entering the house. + */ + private boolean greet; + + /** + * Constructs a new {@code Servant} {@code Object}. + * @param type The servant type. + */ + public Servant(ServantType type) { + super(type.getId()); + this.type = type; + } + + /** + * Parses the servant from the save file. + * @return The servant. + */ + public static Servant parse(JSONObject data){ + int type = Integer.parseInt( data.get("type").toString()); + Servant servant = new Servant(ServantType.values()[type]); + servant.uses = Integer.parseInt( data.get("uses").toString()); + Object itemRaw = data.get("item"); + if(itemRaw != null){ + JSONObject item = (JSONObject) itemRaw; + servant.item = new Item(Integer.parseInt(item.get("id").toString()),Integer.parseInt(item.get("amount").toString())); + } + servant.greet = (boolean) data.get("greet"); + return servant; + } + + /** + * Gets the item value. + * @return The item. + */ + public Item getItem() { + return item; + } + + /** + * Sets the item value. + * @param item The item to set. + */ + public void setItem(Item item) { + this.item = item; + } + + /** + * Gets the uses value. + * @return The uses. + */ + public int getUses() { + return uses; + } + + /** + * Sets the uses value. + * @param uses The uses to set. + */ + public void setUses(int uses) { + this.uses = uses; + } + + /** + * Gets the greet value. + * @return The greet. + */ + public boolean isGreet() { + return greet; + } + + /** + * Sets the greet value. + * @param greet The greet to set. + */ + public void setGreet(boolean greet) { + this.greet = greet; + } + + /** + * Gets the type value. + * @return The type. + */ + public ServantType getType() { + return type; + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/ServantType.java b/Server/src/main/content/global/skill/construction/ServantType.java new file mode 100644 index 0000000..b505c6b --- /dev/null +++ b/Server/src/main/content/global/skill/construction/ServantType.java @@ -0,0 +1,124 @@ +package content.global.skill.construction; + + +import core.game.node.item.Item; +import org.rs09.consts.Items; + +/** + * Represents a type of servant + * @author Splinter + * @version 1.1 + */ +public enum ServantType { + NONE(-1, -1, -1, -1, -1), + RICK(4235, 500, 6, 20, 60), + MAID(4237, 1000, 10, 25, 50, new Item(Items.STEW_2003)), + COOK(4239, 3000, 16, 30, 17, new Item(Items.PINEAPPLE_PIZZA_2301), new Item(Items.CUP_OF_TEA_712)), + BUTLER(4241, 5000, 20, 40, 12, new Item(Items.CHOCOLATE_CAKE_1897), new Item(Items.CUP_OF_TEA_712)), + DEMON_BUTLER(4243, 10000, 26, 50, 7, new Item(Items.CURRY_2011)) + ; + + /** + * The ID of the npc. + */ + private int npcId; + + /** + * How much this servant costs. + */ + private int cost; + + /** + * How much this servant is able to bring back. + */ + private int capacity; + + /** + * The level the player must have before recruiting this servant. + */ + private int level; + + /** + * How long it takes this servant to return from their duties. + */ + private int timer; + + /** + * The food items the servant can cook. + */ + private Item[] food; + + /** + * Constructor + */ + private ServantType(int npcId, int cost, int capacity, int level, int timer, Item... food) { + this.npcId = npcId; + this.cost = cost; + this.capacity = capacity; + this.level = level; + this.timer = timer; + this.food = food; + } + + /** + * Gets a servant for the NPC id + * @param id The NPC id. + * @return The servant type. + */ + public static ServantType forId(int id){ + for (ServantType s : ServantType.values()){ + if (s.getId() == id){ + return s; + } + } + return null; + } + + /** + * Gets the NPC's id + * @return + */ + public int getId(){ + return npcId; + } + + /** + * Gets the initial cost + * @return + */ + public int getCost(){ + return cost; + } + + /** + * Gets the NPC's capacity + * @return + */ + public int getCapacity(){ + return capacity; + } + + /** + * Gets the level + * @return + */ + public int getLevel(){ + return level; + } + + /** + * Gets the timer + * @return + */ + public int getTimer(){ + return timer; + } + + /** + * Gets the food the servant can cook + * @return + */ + public Item[] getFood(){ + return food; + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/decoration/BeerBarrelPlugin.java b/Server/src/main/content/global/skill/construction/decoration/BeerBarrelPlugin.java new file mode 100644 index 0000000..dce9b7c --- /dev/null +++ b/Server/src/main/content/global/skill/construction/decoration/BeerBarrelPlugin.java @@ -0,0 +1,76 @@ +package content.global.skill.construction.decoration; + +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; +import org.rs09.consts.Items; + +/** + * Handles the Construction beer barrels. + * @author Splinter + */ +@Initializable +public class BeerBarrelPlugin extends UseWithHandler { + + /** + * The object ids + */ + private static final int[] OBJECTS = new int[] { + 13568, 13569, 13570, 13571, 13572, 13573 + }; + + /** + * Constructs a new {@Code BeerBarrelPlugin} {@Code Object} + */ + public BeerBarrelPlugin() { + super(1919); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (int id : OBJECTS) { + addHandler(id, OBJECT_TYPE, this); + } + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + Player player = event.getPlayer(); + final Scenery object = (Scenery) event.getUsedWith(); + + if (player.getInventory().remove(new Item(Items.BEER_GLASS_1919))) { + player.animate(Animation.create(833)); + player.sendMessage("You fill up your glass."); + player.getInventory().add(new Item(getReward(object.getId()), 1)); + } + return true; + } + + /** + * Get the beer reward based on the interaced barrel. + * @return the item to give. + */ + public int getReward(int barrelId) { + switch (barrelId) { + case 13568: + return 1917; + case 13569: + return 5763; + case 13570: + return 1905; + case 13571: + return 1909; + case 13572: + return 1911; + case 13573: + return 5755; + } + return 1917; + } +} diff --git a/Server/src/main/content/global/skill/construction/decoration/ChairBenchPlugin.java b/Server/src/main/content/global/skill/construction/decoration/ChairBenchPlugin.java new file mode 100644 index 0000000..87332a9 --- /dev/null +++ b/Server/src/main/content/global/skill/construction/decoration/ChairBenchPlugin.java @@ -0,0 +1,97 @@ +package content.global.skill.construction.decoration; + +import core.cache.def.impl.SceneryDefinition; +import content.global.skill.construction.Decoration; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.impl.ForceMovement; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.system.task.Pulse; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Handles chair and bench options. + * @author Emperor + * + */ +@Initializable +public final class ChairBenchPlugin extends OptionHandler { + + /** + * The decorations that can be seated on. + */ + private static final Object[][] CHAIRS = { + {Decoration.CRUDE_CHAIR, 4073, 4103}, + {Decoration.WOODEN_CHAIR, 4075, 4103}, + {Decoration.ROCKING_CHAIR, 4079, 4103}, + {Decoration.OAK_CHAIR, 4081, 4103}, + {Decoration.OAK_ARMCHAIR, 4083, 4103}, + {Decoration.TEAK_ARMCHAIR, 4085, 4103}, + {Decoration.MAHOGANY_ARMCHAIR, 4087, 4103}, + {Decoration.BENCH_WOODEN, 4089, 4104}, + {Decoration.BENCH_OAK, 4091, 4104}, + {Decoration.BENCH_CARVED_OAK, 4093, 4104}, + {Decoration.BENCH_TEAK, 4095, 4104}, + {Decoration.BENCH_CARVED_TEAK, 4097, 4104}, + {Decoration.BENCH_MAHOGANY, 4099, 4104}, + {Decoration.BENCH_GILDED, 4101, 4104}, + {Decoration.CARVED_TEAK_BENCH, 4097, 4104}, + {Decoration.MAHOGANY_BENCH, 4099, 4104}, + {Decoration.GILDED_BENCH, 4101, 4104}, + {Decoration.OAK_THRONE, 4111, 4103}, + {Decoration.TEAK_THRONE, 4112, 4103}, + {Decoration.MAHOGANY_THRONE, 4113, 4103}, + {Decoration.GILDED_THRONE, 4114, 4103}, + {Decoration.SKELETON_THRONE, 4115, 4103}, + {Decoration.CRYSTAL_THRONE, 4116, 4103}, + {Decoration.DEMONIC_THRONE, 4117, 4103}, + }; + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (Object[] data : CHAIRS) { + SceneryDefinition.forId(((Decoration) data[0]).getObjectId()).getHandlers().put("option:sit-on", this); + } + return this; + } + + @Override + public boolean handle(final Player player, Node node, String option) { + Scenery object = (Scenery) node; + int animId = -1; + int sitAnimId = -1; + for (Object[] data : CHAIRS) { + if (((Decoration) data[0]).getObjectId() == object.getId()) { + animId = (Integer) data[1]; + sitAnimId = (Integer) data[2]; + break; + } + } + if (object.getType() == 11) { + animId++; + } + final int animation = animId; + final int sitAnimation = sitAnimId; + ForceMovement.run(player, player.getLocation(), node.getLocation(), ForceMovement.WALK_ANIMATION, Animation.create(sitAnimation), object.getDirection().getOpposite(), ForceMovement.WALKING_SPEED, ForceMovement.WALKING_SPEED); + player.getLocks().lockInteractions(600000); + player.getPulseManager().run(new Pulse(2) { + @Override + public boolean pulse() { + player.animate(Animation.create(animation)); + return false; + } + + @Override + public void stop() { + super.stop(); + player.getLocks().unlockInteraction(); + player.animate(Animation.create(sitAnimation + 2)); + } + }); + return true; + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/decoration/ConstructionDoorPlugin.kt b/Server/src/main/content/global/skill/construction/decoration/ConstructionDoorPlugin.kt new file mode 100644 index 0000000..75a9e22 --- /dev/null +++ b/Server/src/main/content/global/skill/construction/decoration/ConstructionDoorPlugin.kt @@ -0,0 +1,83 @@ +package content.global.skill.construction.decoration + +import content.global.skill.construction.BuildHotspot +import content.global.skill.construction.HousingStyle +import core.cache.def.impl.SceneryDefinition +import core.game.global.action.DoorActionHandler +import core.game.interaction.OptionHandler +import core.game.node.Node +import core.game.node.entity.player.Player +import core.game.node.scenery.Scenery +import core.plugin.Initializable +import core.plugin.Plugin + +/** + * Handles Construction related doors. + * @author Emperor + */ +@Initializable +class ConstructionDoorPlugin : OptionHandler() { + + @Throws(Throwable::class) + override fun newInstance(arg: Any?): Plugin { + for (style in HousingStyle.values()) { + SceneryDefinition.forId(style.doorId).handlers["option:open"] = this + SceneryDefinition.forId(style.secondDoorId).handlers["option:open"] = this + } + for (deco in BuildHotspot.DUNGEON_DOOR_LEFT.decorations) { + SceneryDefinition.forId(deco.objectId).handlers["option:open"] = this + SceneryDefinition.forId(deco.objectId).handlers["option:pick-lock"] = this + SceneryDefinition.forId(deco.objectId).handlers["option:force"] = this + } + for (deco in BuildHotspot.DUNGEON_DOOR_RIGHT.decorations) { + SceneryDefinition.forId(deco.objectId).handlers["option:open"] = this + SceneryDefinition.forId(deco.objectId).handlers["option:pick-lock"] = this + SceneryDefinition.forId(deco.objectId).handlers["option:force"] = this + } + return this + } + + override fun handle(player: Player, node: Node, option: String): Boolean { + when (option) { + "pick-lock", "force" -> return false //TODO + } + val `object` = node as Scenery + val second = DoorActionHandler.getSecondDoor(`object`, player) + DoorActionHandler.open(`object`, second, getReplaceId(`object`), getReplaceId(second), true, 500, false) + return true + } + + /** + * Gets the replace id for the door. + * @param object The door. + * @return The replace object id. + */ + private fun getReplaceId(`object`: Scenery): Int { + for (data in REPLACEMENT) { + if (`object`.id == data[0]) { + return data[1] + } + } + return `object`.id + 6 + } + + companion object { + /** + * The replacement ids. + */ + val REPLACEMENT = arrayOf( + intArrayOf(13100, 13102), + intArrayOf(13101, 13103), + intArrayOf(13006, 13008), + intArrayOf(13007, 13008), + intArrayOf(13015, 13017), + intArrayOf(13016, 13018), + intArrayOf(13094, 13095), + intArrayOf(13096, 13097), + intArrayOf(13109, 13110), + intArrayOf(13107, 13108), + intArrayOf(13118, 13120), + intArrayOf(13119, 13121) + ) + } +} diff --git a/Server/src/main/content/global/skill/construction/decoration/FireplacePlugin.java b/Server/src/main/content/global/skill/construction/decoration/FireplacePlugin.java new file mode 100644 index 0000000..d6dad17 --- /dev/null +++ b/Server/src/main/content/global/skill/construction/decoration/FireplacePlugin.java @@ -0,0 +1,64 @@ +package content.global.skill.construction.decoration; + + +import core.cache.def.impl.SceneryDefinition; +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; +import org.rs09.consts.Items; + +/** + * Handles the various fireplaces that you may light in Construction. + * @author Splinter + * @author Emperor + */ +@Initializable +public final class FireplacePlugin extends OptionHandler { + + /** + * The animation. + */ + private static final Animation ANIMATION = Animation.create(3658); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(13609).getHandlers().put("option:light", this); + SceneryDefinition.forId(13611).getHandlers().put("option:light", this); + SceneryDefinition.forId(13613).getHandlers().put("option:light", this); + return this; + } + + @Override + public boolean handle(final Player player, Node node, String option) { + if (!player.getInventory().contains(1511, 1) || !player.getInventory().contains(590, 1)) { + player.sendMessage("You need some logs and a tinderbox in order to light the fireplace."); + return true; + } + final Scenery obj = (Scenery) node.asScenery(); + player.lock(2); + player.animate(ANIMATION); + GameWorld.getPulser().submit(new Pulse(2, player) { + @Override + public boolean pulse() { + if (!obj.isActive()) { + return true; + } + player.getInventory().remove(new Item(Items.LOGS_1511)); + player.getSkills().addExperience(Skills.FIREMAKING, 80); + SceneryBuilder.replace(new Scenery(obj.getId(), obj.getLocation()), new Scenery(obj.getId() + 1, obj.getLocation(), obj.getRotation()), 1000); + player.sendMessage("You light the fireplace."); + return true; + } + }); + return true; + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/decoration/StaircasePlugin.java b/Server/src/main/content/global/skill/construction/decoration/StaircasePlugin.java new file mode 100644 index 0000000..a1fe9ed --- /dev/null +++ b/Server/src/main/content/global/skill/construction/decoration/StaircasePlugin.java @@ -0,0 +1,439 @@ +package content.global.skill.construction.decoration; + +import content.global.skill.construction.*; +import core.cache.def.impl.SceneryDefinition; +import core.game.dialogue.DialogueInterpreter; +import core.game.dialogue.DialoguePlugin; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.game.world.GameWorld; +import core.plugin.ClassScanner; + +/** + * Handles construction staircases. + * @author Emperor + * + */ +@Initializable +public final class StaircasePlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ClassScanner.definePlugin(new BuildDialogue()); + ClassScanner.definePlugin(new ClimbPohLadder()); + for (int i = 13497; i < 13507; i++) { + SceneryDefinition.forId(i).getHandlers().put("option:climb", this); + SceneryDefinition.forId(i).getHandlers().put("option:climb-up", this); + SceneryDefinition.forId(i).getHandlers().put("option:climb-down", this); + SceneryDefinition.forId(i).getHandlers().put("option:remove-room", this); + } + SceneryDefinition.forId(13409).getHandlers().put("option:enter", this); + SceneryDefinition.forId(13409).getHandlers().put("option:remove-room", this); + for (int id = 13328; id < 13331; id++) { + SceneryDefinition.forId(id).getHandlers().put("option:climb", this); + SceneryDefinition.forId(id).getHandlers().put("option:remove-room", this); + } + for (int id = 13675; id <= 13680; id++) { + if (id < 13678) { + SceneryDefinition.forId(id).getHandlers().put("option:open", this); + } else { + SceneryDefinition.forId(id).getHandlers().put("option:go-down", this); + SceneryDefinition.forId(id).getHandlers().put("option:close", this); + } + SceneryDefinition.forId(id).getHandlers().put("option:remove-room", this); + } + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + HouseManager house = player.getAttribute("poh_entry", null); + if (house == null) { + player.getPacketDispatch().sendMessage("You're not in your house right now (REPORT)."); + return true; + } + Scenery object = (Scenery) node; + switch (option) { + case "open": + SceneryBuilder.replace(object, object.transform(object.getId() + 3), 200); + return true; + case "close": + SceneryBuilder.replace(object, object.transform(object.getId() - 3)); + return true; + case "remove-room": + if (player.getLocation().getZ() != 0) { + player.getPacketDispatch().sendMessage("The room below is supporting this room!"); + return true; + } + return false; + case "climb": + if (house.getDungeonRegion() == player.getViewport().getRegion()) { + climb(player, 1, house, object); + return true; + } + if (object.getLocation().getZ() > 0) { + climb(player, -1, house, object); + return true; + } + player.getDialogueInterpreter().open("con:climbdial", house, object); + return true; + case "climb-up": + climb(player, 1, house, object); + return true; + case "enter": + case "climb-down": + case "go-down": + climb(player, -1, house, object); + return true; + } + return false; + } + + /** + * Climbs the staircase. + * @param player The player. + * @param z The plane difference. + * @param house The house the player is currently in. + * @param object The object. + */ + private static void climb(Player player, int z, HouseManager house, Scenery object) { + Location l = player.getLocation(); + int plane = l.getZ() + z; + int roomX = l.getChunkX(); + int roomY = l.getChunkY(); + Room current = house.getRooms()[l.getZ()][roomX][roomY]; + if (plane < 0) { //Dungeon + plane = 3; + } + else if (player.getViewport().getRegion() == house.getDungeonRegion() && plane == 1) {//going up + plane = 0; + } + Room room = house.getRooms()[plane][roomX][roomY]; +// boolean stairs = room != null && room.getStairs() != null || room.get; + if (room == null || room.getProperties().isRoof()) { + if (player.getHouseManager().isInHouse(player) && player.getHouseManager().isBuildingMode()) { + player.getDialogueInterpreter().open("con:nfroom", plane, roomX, roomY, current, object); + } + else { + player.getPacketDispatch().sendMessage("This doesn't seem to lead anywhere."); + } + } else { + Location destination = l.transform(0, 0, z); + if (player.getViewport().getRegion() == house.getDungeonRegion()) { + destination = house.getHouseRegion().getBaseLocation().transform(l.getLocalX(), l.getLocalY(), 0); + } + else if (plane == 3) { + destination = house.getDungeonRegion().getBaseLocation().transform(l.getLocalX(), l.getLocalY(), 0); + } + Room r = house.getRoom(destination); + Hotspot h = r.getStairs(); + if (h != null && h.getDecorationIndex() > -1) { + player.getProperties().setTeleportLocation(destination); + } else { + player.getPacketDispatch().sendMessage("This doesn't seem to lead anywhere."); + } + } + } + + /** + * Handles the climbing dialogue. + * @author Emperor + */ + static final class ClimbPohLadder extends DialoguePlugin { + + /** + * Represents the object to use. + */ + private HouseManager house; + + /** + * The ladder. + */ + private Scenery ladder; + + /** + * Constructs a new {@code ClimbPohLadder} {@code Object}. + */ + public ClimbPohLadder() { + super(); + } + + /** + * Constructs a new {@code ClimbPohLadder} {@code Object}. + * @param player the player. + */ + public ClimbPohLadder(final Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new ClimbPohLadder(player); + } + + @Override + public boolean open(Object... args) { + house = (HouseManager) args[0]; + ladder = (Scenery) args[1]; + interpreter.sendOptions("What would you like to do?", "Climb Up.", "Climb Down."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + switch (buttonId) { + case 1: + player.lock(1); + GameWorld.getPulser().submit(new Pulse(1) { + @Override + public boolean pulse() { + climb(player, 1, house, ladder); + return true; + } + }); + end(); + break; + case 2: + player.lock(1); + GameWorld.getPulser().submit(new Pulse(1) { + @Override + public boolean pulse() { + climb(player, -1, house, ladder); + return true; + } + }); + end(); + break; + + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { DialogueInterpreter.getDialogueKey("con:climbdial") }; + } + + } + + /** + * Handles the creating a room on different floor dialogue. + * @author Emperor + */ + static final class BuildDialogue extends DialoguePlugin { + + /** + * The plane of the room to build. + */ + private int plane; + + /** + * The room x-coordinate. + */ + private int roomX; + + /** + * The room y-coordinate. + */ + private int roomY; + + /** + * The room we're building on. + */ + private Room room; + + /** + * The stairs object. + */ + private Scenery stairs; + + /** + * Constructs a new {@code BuildDialogue} {@code Object}. + */ + public BuildDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code BuildDialogue} {@code Object}. + * @param player the player. + */ + public BuildDialogue(final Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new BuildDialogue(player); + } + + @Override + public boolean open(Object... args) { + plane = (Integer) args[0]; + roomX = (Integer) args[1]; + roomY = (Integer) args[2]; + room = (Room) args[3]; + stairs = (Scenery) args[4]; + stage = 0; + if (stairs.getId() >= 13328 && stairs.getId() <= 13330) { + interpreter.sendPlainMessage(false, "These stairs don't seem to lead anywhere. Do you", "want to build a throne room upstairs?"); + stage = 5; + return true; + } + if (plane == 3) { + if (room.getProperties() == RoomProperties.THRONE_ROOM) { + interpreter.sendPlainMessage(false, "These stairs don't seem to lead anywhere. Do you", "want to build an Oubilette?"); + } else { + interpreter.sendPlainMessage(false, "These stairs don't seem to lead anywhere. Do you", "want to build a dungeon room?"); + } + return true; + } + interpreter.sendPlainMessage(false, "These stairs don't seem to lead anywhere. Do you", "want to build a room at the top?"); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + boolean dungeon = plane == 3; + switch (stage) { + case 0: + interpreter.sendOptions("Select an option", "Yes", "No"); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: //yes + if (room.getProperties() == RoomProperties.THRONE_ROOM) { + Room r = Room.create(player, RoomProperties.OUBILETTE); + Direction[] dirs = BuildingUtils.getAvailableRotations(player, r.getExits(), plane, roomX, roomY); + for (Direction d : dirs) { + if (d == room.getRotation()) { + r.setRotation(d); + Hotspot stairs = room.getStairs(); + int index = stairs != null ? stairs.getDecorationIndex() : -1; + BuildingUtils.buildRoom(player, r, plane, roomX, roomY, r.getExits(), true); + r.getStairs().setDecorationIndex(index); + end(); + return true; + } + } + interpreter.sendPlainMessage(false, "The room you're trying to build doesn't fit."); + stage = 4; + return true; + } + if (dungeon) { + interpreter.sendOptions("Select an option", "Skill Hall", "Quest Hall", "Dungeon Stairs"); + } else { + interpreter.sendOptions("Select an option", "Skill Hall", "Quest Hall"); + } + stage = 2; + return true; + } + end(); + return true; + case 2: + if (dungeon && buttonId == 3) { + stage = 3; + return handle(interfaceId, 1); + } + RoomProperties props = buttonId == 2 ? RoomProperties.QUEST_HALL_2 : RoomProperties.SKILL_HALL_2; + if (plane == 3) { + props = buttonId == 2 ? RoomProperties.QUEST_HALL : RoomProperties.SKILL_HALL; + } + Room r = Room.create(player, props); + Direction[] dirs = BuildingUtils.getAvailableRotations(player, r.getExits(), plane, roomX, roomY); + for (Direction d : dirs) { + if (d == room.getRotation()) { + r.setRotation(d); + Hotspot stairs = room.getStairs(); + int index = stairs != null ? stairs.getDecorationIndex() : -1; + r.getStairs().setDecorationIndex(index); + BuildingUtils.buildRoom(player, r, plane, roomX, roomY, r.getExits(), true); + end(); + return true; + } + } + interpreter.sendPlainMessage(false, "The room you're trying to build doesn't seem to fit."); + stage = 4; + return true; + case 3: + switch (buttonId) { + case 1: //yes + r = Room.create(player, RoomProperties.DUNGEON_STAIRS); + dirs = BuildingUtils.getAvailableRotations(player, r.getExits(), plane, roomX, roomY); + for (Direction d : dirs) { + if (d == room.getRotation()) { + r.setRotation(d); + Hotspot stairs = room.getStairs(); + int index = stairs != null ? stairs.getDecorationIndex() : -1; + BuildingUtils.buildRoom(player, r, plane, roomX, roomY, r.getExits(), true); + r.getStairs().setDecorationIndex(index); + end(); + return true; + } + } + interpreter.sendPlainMessage(false, "The room you're trying to build doesn't fit."); + stage = 4; + return true; + case 2: + end(); + return true; + } + return true; + case 4: + end(); + return true; + case 5: + interpreter.sendOptions("Select an option", "Yes", "No"); + stage = 6; + return true; + case 6: + switch (buttonId) { + case 1: //yes + r = Room.create(player, RoomProperties.THRONE_ROOM); + dirs = BuildingUtils.getAvailableRotations(player, r.getExits(), plane, roomX, roomY); + for (Direction d : dirs) { + if (d == room.getRotation()) { + r.setRotation(d); + Hotspot stairs = room.getStairs(); + int index = stairs != null ? stairs.getDecorationIndex() : -1; + BuildingUtils.buildRoom(player, r, plane, roomX, roomY, r.getExits(), true); + r.getStairs().setDecorationIndex(index); + end(); + return true; + } + } + interpreter.sendPlainMessage(false, "The room you're trying to build doesn't fit."); + stage = 4; + return true; + case 2: + end(); + return true; + } + return true; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { DialogueInterpreter.getDialogueKey("con:nfroom") }; + } + + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/decoration/bedroom/ClockPlugin.java b/Server/src/main/content/global/skill/construction/decoration/bedroom/ClockPlugin.java new file mode 100644 index 0000000..53c44bb --- /dev/null +++ b/Server/src/main/content/global/skill/construction/decoration/bedroom/ClockPlugin.java @@ -0,0 +1,52 @@ +package content.global.skill.construction.decoration.bedroom; + + +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.plugin.Initializable; +import core.plugin.Plugin; + +import java.text.SimpleDateFormat; +import java.util.Calendar; + +/** + * ClockPlugin.java + * @author Clayton Williams (hope) + * @date Oct 26, 2015 + */ +@Initializable +public class ClockPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(13169).getHandlers().put("option:read", this); + SceneryDefinition.forId(13170).getHandlers().put("option:read", this); + SceneryDefinition.forId(13171).getHandlers().put("option:read", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + Scenery object = node.asScenery(); + SimpleDateFormat format = new SimpleDateFormat("mm"); + int minuteDisplay = Integer.parseInt(format.format(Calendar.getInstance().getTime())); + StringBuilder sb = new StringBuilder("It's "); + if (minuteDisplay == 0) { + sb.append("Rune o'clock."); + } else if (minuteDisplay == 15) { + sb.append("a quarter past Rune."); + } else if (minuteDisplay > 0 && minuteDisplay < 30) { + sb.append(minuteDisplay + " past Rune."); + } else if (minuteDisplay == 45) { + sb.append("a quarter till Rune."); + } else { + sb.append((60 - minuteDisplay) + " till Rune."); + } + player.getDialogueInterpreter().sendItemMessage(object.getId() - 5117, sb.toString()); + return true; + } + +} diff --git a/Server/src/main/content/global/skill/construction/decoration/bedroom/ShavingStandHandler.kt b/Server/src/main/content/global/skill/construction/decoration/bedroom/ShavingStandHandler.kt new file mode 100644 index 0000000..9b93221 --- /dev/null +++ b/Server/src/main/content/global/skill/construction/decoration/bedroom/ShavingStandHandler.kt @@ -0,0 +1,31 @@ +package content.global.skill.construction.decoration.bedroom + +import core.cache.def.impl.SceneryDefinition +import core.game.component.Component +import core.game.interaction.OptionHandler +import core.game.node.Node +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.plugin.Plugin + +@Initializable +class ShavingStandHandler : OptionHandler() { + override fun newInstance(arg: Any?): Plugin { + SceneryDefinition.forId(13162).handlers["option:preen"] = this + SceneryDefinition.forId(13163).handlers["option:preen"] = this + SceneryDefinition.forId(13168).handlers["option:preen"] = this + return this + } + + override fun handle(player: Player?, node: Node?, option: String?): Boolean { + player ?: return false + node ?: return false + if(player.appearance.isMale){ + player.interfaceManager.open(Component(596)) + } else { + player.interfaceManager.open(Component(592)) + } + return true + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/decoration/bedroom/WardrobeHandler.kt b/Server/src/main/content/global/skill/construction/decoration/bedroom/WardrobeHandler.kt new file mode 100644 index 0000000..5cc89e1 --- /dev/null +++ b/Server/src/main/content/global/skill/construction/decoration/bedroom/WardrobeHandler.kt @@ -0,0 +1,31 @@ +package content.global.skill.construction.decoration.bedroom + +import core.cache.def.impl.SceneryDefinition +import core.game.component.Component +import core.game.interaction.OptionHandler +import core.game.node.Node +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.plugin.Plugin + +@Initializable +class WardrobeHandler : OptionHandler() { + override fun newInstance(arg: Any?): Plugin { + SceneryDefinition.forId(13155).handlers["option:change-clothes"] = this + SceneryDefinition.forId(13156).handlers["option:change-clothes"] = this + SceneryDefinition.forId(13161).handlers["option:change-clothes"] = this + return this + } + + override fun handle(player: Player?, node: Node?, option: String?): Boolean { + player ?: return false + node ?: return false + if(player.appearance.isMale){ + player.interfaceManager.open(Component(591)) + } else { + player.interfaceManager.open(Component(594)) + } + return true + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/decoration/chapel/BoneOfferPlugin.java b/Server/src/main/content/global/skill/construction/decoration/chapel/BoneOfferPlugin.java new file mode 100644 index 0000000..e681c86 --- /dev/null +++ b/Server/src/main/content/global/skill/construction/decoration/chapel/BoneOfferPlugin.java @@ -0,0 +1,182 @@ +package content.global.skill.construction.decoration.chapel; + + +import static core.api.ContentAPIKt.*; +import core.cache.def.impl.SceneryDefinition; +import content.global.skill.prayer.Bones; +import core.game.node.entity.skill.Skills; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.audio.Audio; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.system.task.Pulse; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.plugin.Plugin; +import org.rs09.consts.Sounds; + +/** + * Handles the offering of bones on an altar. + * @author Splinter + */ +@Initializable +public class BoneOfferPlugin extends UseWithHandler { + + /** + * The offer GFX. + */ + private final Graphics GFX = new Graphics(624); + + /** + * The offer Animation. + */ + private final Animation ANIM = new Animation(896); + + /** + * Constructor. + */ + public BoneOfferPlugin() { + super(526, 528, 530, 532, 534, 536, 2530, 2859, 3123, 3125, 3127, 3179, 3180, 3181, 3182, 3183, 3185, 3186, 3187, 4812, 4830, 4832, 4834, 6729, 6812); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(13185, OBJECT_TYPE, this); + addHandler(13188, OBJECT_TYPE, this); + addHandler(13191, OBJECT_TYPE, this); + addHandler(13194, OBJECT_TYPE, this); + addHandler(13197, OBJECT_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + Player player = event.getPlayer(); + Scenery left = null; + Scenery right = null; + if (event.getUsedWith().asScenery().getRotation() % 2 == 0) { + left = RegionManager.getObject(event.getUsedWith().getLocation().getZ(), event.getUsedWith().getLocation().getX() + 3, event.getUsedWith().getLocation().getY()); + right = RegionManager.getObject(event.getUsedWith().getLocation().getZ(), event.getUsedWith().getLocation().getX() - 2, event.getUsedWith().getLocation().getY()); + } else { + left = RegionManager.getObject(event.getUsedWith().getLocation().getZ(), event.getUsedWith().getLocation().getX(), event.getUsedWith().getLocation().getY() + 3); + right = RegionManager.getObject(event.getUsedWith().getLocation().getZ(), event.getUsedWith().getLocation().getX(), event.getUsedWith().getLocation().getY() - 2); + } + Bones b = Bones.forId(event.getUsedItem().getId()); + if (b != null) { + worship(player, event.getUsedWith().asScenery(), left, right, b); + } + return true; + } + + /** + * Worships the altar. + * @param player the player + * @param altar the altar object + * @param left the left brazier + * @param right the right brazier + * @param b the bone used + */ + private void worship(final Player player, final Scenery altar, final Scenery left, final Scenery right, final Bones b) { + if (player.getIronmanManager().isIronman() && !player.getHouseManager().isInHouse(player)) { + player.sendMessage("You cannot do this on someone else's altar."); + return; + } + final Location start = player.getLocation(); + + Location gfxLoc = player.getLocation().transform(player.getDirection(), 1); + + submitIndividualPulse(player, new Pulse(1) { + int counter = 0; + + @Override + public boolean pulse() { + counter++; + if (counter == 1 || counter % 5 == 0) { + if (player.getInventory().remove(new Item(b.getItemId()))) { + player.animate(ANIM); + playAudio(player, Sounds.POH_OFFER_BONES_958); + player.getPacketDispatch().sendPositionedGraphics(GFX, gfxLoc); + player.sendMessage(getMessage(isLit(left), isLit(right))); + player.getSkills().addExperience(Skills.PRAYER, b.getExperience() * getMod(altar, isLit(left), isLit(right))); + } + } + return !player.getLocation().equals(start) || !player.getInventory().containsItem(new Item(b.getItemId())); + + } + + }); + + } + + /** + * Checks if the burner is lit. + * @param obj the object. + */ + private boolean isLit(Scenery obj) { + return obj != null && obj.getId() != 15271 && SceneryDefinition.forId(obj.getId()).getOptions() != null && !SceneryDefinition.forId(obj.getId()).hasAction("Light"); + } + + /** + * Gets the base modifier of the altar. + * @param altar the altar object + * @return the base bonus. + */ + private double getBase(Scenery altar) { + double base = 150.0; + if (altar == null) { + return base; + } + switch (altar.getId()) { + case 13182: + base = 110.0; + break; + case 13185: + base = 125.0; + break; + case 13188: + base = 150.0; + break; + case 13191: + base = 175.0; + break; + case 13194: + base = 200.0; + break; + case 13197: + base = 250.0; + break; + } + return base; + } + + /** + * Gets the total experience modifier. + * @param isLeft if the left is lit. + * @param isRight if the right is lit. + * @return the mod. + */ + private double getMod(Scenery altar, boolean isLeft, boolean isRight) { + double total = getBase(altar); + if (isLeft) { + total += 50.0; + } + if (isRight) { + total += 50.0; + } + return (total / 100); + } + + /** + * Gets the proper message. + * @return the message. + */ + private String getMessage(boolean isLeft, boolean isRight) { + return isLeft && isRight ? "The gods are very pleased with your offering." : isLeft || isRight ? "The gods are pleased with your offering." : "The gods accept your offering."; + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/decoration/chapel/BurnerListener.kt b/Server/src/main/content/global/skill/construction/decoration/chapel/BurnerListener.kt new file mode 100644 index 0000000..a6c67fa --- /dev/null +++ b/Server/src/main/content/global/skill/construction/decoration/chapel/BurnerListener.kt @@ -0,0 +1,45 @@ +package content.global.skill.construction.decoration.chapel + +import core.game.node.scenery.Scenery +import core.game.node.scenery.SceneryBuilder +import core.game.node.item.Item +import core.game.world.update.flag.context.Animation +import core.tools.RandomFunction +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import org.rs09.consts.Items + +/** + * Handles the lighting of the torches of the Chapel. + * @author Splinter + */ +class BurnerListener : InteractionListener { + + val IDs = intArrayOf(13202,13203,13204,13205,13206,13207,13208,13209,13210,13211,13212,13213) + + override fun defineListeners() { + on(IDs, IntType.SCENERY, "light"){ player, node -> + if (player.ironmanManager.checkRestriction() && !player.houseManager.isInHouse(player)) { + return@on true + } + if (!player.inventory.containsItem(Item(Items.TINDERBOX_590)) || !player.inventory.containsItem(Item(Items.CLEAN_MARRENTILL_251))) { + player.dialogueInterpreter.sendDialogue( + "You'll need a tinderbox and a clean marrentill herb in order to", + "light the burner." + ) + return@on true + } + if (player.inventory.remove(Item(Items.CLEAN_MARRENTILL_251))) { + player.lock(1) + player.animate(Animation.create(3687)) + player.sendMessage("You burn some marrentill in the incense burner.") + SceneryBuilder.replace( + node.asScenery(), + Scenery(node.asScenery().id + 1, node.location), + RandomFunction.random(100, 175) + ) + } + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/decoration/chapel/ShieldBlessingPlugin.kt b/Server/src/main/content/global/skill/construction/decoration/chapel/ShieldBlessingPlugin.kt new file mode 100644 index 0000000..9a8e34c --- /dev/null +++ b/Server/src/main/content/global/skill/construction/decoration/chapel/ShieldBlessingPlugin.kt @@ -0,0 +1,48 @@ +package content.global.skill.construction.decoration.chapel + +import core.api.playAudio +import core.game.interaction.NodeUsageEvent +import core.game.interaction.UseWithHandler +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.world.update.flag.context.Animation +import core.plugin.Initializable +import core.plugin.Plugin +import org.rs09.consts.Items +import org.rs09.consts.Sounds + +const val HOLY_ELIXER = 13754 +const val SPIRIT_SHIELD = 13734 +@Initializable +/** + * Blesses shields + * @author Ceikry + */ +class ShieldBlessingPlugin : UseWithHandler(HOLY_ELIXER, SPIRIT_SHIELD) { + override fun newInstance(arg: Any?): Plugin { + for(i in arrayOf(13185, 13188, 13191, 13194, 13197)){ + addHandler(i, OBJECT_TYPE,this) + } + return this + } + + override fun handle(event: NodeUsageEvent?): Boolean { + val player = event?.player + player ?: return false + if (player.ironmanManager.isIronman && !player.houseManager.isInHouse(player)) { + player.sendMessage("You cannot do this on someone else's altar.") + return true + } + if(player.skills.getLevel(Skills.PRAYER) < 85){ + player.sendMessage("You need 85 prayer to do this.") + return true + } + + player.animator.animate(Animation(896)) + playAudio(player, Sounds.POH_OFFER_BONES_958) + + if(player.inventory.remove(Item(HOLY_ELIXER)) && player.inventory.remove(Item(SPIRIT_SHIELD))) + player.inventory.add(Item(Items.BLESSED_SPIRIT_SHIELD_13736)) + return true + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/decoration/combatroom/CombatRing.java b/Server/src/main/content/global/skill/construction/decoration/combatroom/CombatRing.java new file mode 100644 index 0000000..c2b135f --- /dev/null +++ b/Server/src/main/content/global/skill/construction/decoration/combatroom/CombatRing.java @@ -0,0 +1,32 @@ +package content.global.skill.construction.decoration.combatroom; + + +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Handles the combat ring. + * @author Emperor + * + */ +@Initializable +public final class CombatRing extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(13129).getHandlers().put("option:climb-over", this); //Boxing ring + SceneryDefinition.forId(13133).getHandlers().put("option:climb-over", this); //Fencing ring + SceneryDefinition.forId(13137).getHandlers().put("option:climb-over", this); //Combat ring + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + return false; + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/decoration/costume/ToyBoxPlugin.kt b/Server/src/main/content/global/skill/construction/decoration/costume/ToyBoxPlugin.kt new file mode 100644 index 0000000..86b5007 --- /dev/null +++ b/Server/src/main/content/global/skill/construction/decoration/costume/ToyBoxPlugin.kt @@ -0,0 +1,29 @@ +package content.global.skill.construction.decoration.costume + +import core.cache.def.impl.SceneryDefinition +import core.game.interaction.OptionHandler +import content.global.handlers.item.toys.DiangoReclaimInterface +import core.game.node.Node +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.plugin.Plugin + +/** + * Handles the Toy Box POH + * ToyBoxPlugin.java + * @author Lee + * @date 10/2/2017 + */ +@Initializable +class ToyBoxPlugin : OptionHandler() { + @Throws(Throwable::class) + override fun newInstance(arg: Any?): Plugin { + SceneryDefinition.forId(18802).handlers["option:open"] = this + return this + } + + override fun handle(player: Player, node: Node, option: String): Boolean { + DiangoReclaimInterface.open(player) + return true + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/decoration/kitchen/BeerBarrelPlugin.java b/Server/src/main/content/global/skill/construction/decoration/kitchen/BeerBarrelPlugin.java new file mode 100644 index 0000000..eb6b3fe --- /dev/null +++ b/Server/src/main/content/global/skill/construction/decoration/kitchen/BeerBarrelPlugin.java @@ -0,0 +1,77 @@ +package content.global.skill.construction.decoration.kitchen; + + +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; +import org.rs09.consts.Items; + +/** + * Handles the Construction beer barrels. + * @author Splinter + */ +@Initializable +public class BeerBarrelPlugin extends UseWithHandler { + + /** + * The object ids + */ + private static final int[] OBJECTS = new int[] { + 13568, 13569, 13570, 13571, 13572, 13573 + }; + + /** + * Constructs a new {@Code BeerBarrelPlugin} {@Code Object} + */ + public BeerBarrelPlugin() { + super(1919); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (int id : OBJECTS) { + addHandler(id, OBJECT_TYPE, this); + } + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + Player player = event.getPlayer(); + final Scenery object = (Scenery) event.getUsedWith(); + + if (player.getInventory().remove(new Item(Items.BEER_GLASS_1919))) { + player.animate(Animation.create(3661 + (object.getId() - 13569))); + player.sendMessage("You fill up your glass with " + object.getName().toLowerCase().replace("barrel", "").trim() + "."); + player.getInventory().add(new Item(getReward(object.getId()), 1)); + } + return true; + } + + /** + * Get the beer reward based on the interacted barrel. + * @return the item to give. + */ + public int getReward(int barrelId) { + switch (barrelId) { + case 13568: + return 1917; + case 13569: + return 5763; + case 13570: + return 1905; + case 13571: + return 1909; + case 13572: + return 1911; + case 13573: + return 5755; + } + return 1917; + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/decoration/kitchen/LarderPlugin.java b/Server/src/main/content/global/skill/construction/decoration/kitchen/LarderPlugin.java new file mode 100644 index 0000000..9c3289c --- /dev/null +++ b/Server/src/main/content/global/skill/construction/decoration/kitchen/LarderPlugin.java @@ -0,0 +1,149 @@ +package content.global.skill.construction.decoration.kitchen; + + +import core.cache.def.impl.SceneryDefinition; +import core.plugin.Initializable; +import core.game.dialogue.DialoguePlugin; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Plugin; +import core.plugin.ClassScanner; +import org.rs09.consts.Items; + +/** + * Handles the interactions for the three Larders. + * @author Splinter + */ +@Initializable +public final class LarderPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ClassScanner.definePlugin(new LarderDialogue()); + SceneryDefinition.forId(13565).getHandlers().put("option:search", this); + SceneryDefinition.forId(13566).getHandlers().put("option:search", this); + SceneryDefinition.forId(13567).getHandlers().put("option:search", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + player.getDialogueInterpreter().open(42048, node.getId()); + return true; + } + + /** + * Dialogue options for the Larders. + * @author Splinter + * @version 1.0 + */ + public final class LarderDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code LarderDialogue} {@code Object}. + */ + public LarderDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code LarderDialogue} {@code Object}. + * + * @param player + * the player. + */ + public LarderDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new LarderDialogue(player); + } + + @Override + public boolean open(Object... args) { + int id = (int) args[0]; + switch (id) { + case 13565: + interpreter.sendOptions("Select an Option", "Tea Leaves", "Bucket of Milk"); + stage = 1; + break; + case 13566: + interpreter.sendOptions("Select an Option", "Tea Leaves", "Bucket of Milk", "Eggs", "Pot of Flour"); + stage = 1; + break; + case 13567: + interpreter.sendOptions("Select an Option", "Tea Leaves", "Bucket of Milk", "Eggs", "Pot of Flour", "More Options"); + stage = 1; + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + if (player.getInventory().freeSlots() < 1) { + player.sendMessage("You need at least one free inventory space to take from the larder."); + end(); + return true; + } + switch (stage) { + case 1: + switch (buttonId) { + case 1: + player.getInventory().add(new Item(Items.TEA_LEAVES_7738, 1)); + end(); + break; + case 2: + player.getInventory().add(new Item(Items.BUCKET_OF_MILK_1927, 1)); + end(); + break; + case 3: + player.getInventory().add(new Item(Items.EGG_1944, 1)); + end(); + break; + case 4: + player.getInventory().add(new Item(Items.POT_OF_FLOUR_1933, 1)); + end(); + break; + case 5: + player.getDialogueInterpreter().sendOptions( + "Select an Option", "Potatoes", "Garlic", "Onions", "Cheese"); + stage = 2; + break; + } + break; + case 2: + switch (buttonId) { + case 1: + player.getInventory().add(new Item(Items.POTATO_1942, 1)); + end(); + break; + case 2: + player.getInventory().add(new Item(Items.GARLIC_1550, 1)); + end(); + break; + case 3: + player.getInventory().add(new Item(Items.ONION_1957, 1)); + end(); + break; + case 4: + player.getInventory().add(new Item(Items.CHEESE_1985, 1)); + end(); + break; + } + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 42048 }; + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/decoration/kitchen/ShelfPlugin.java b/Server/src/main/content/global/skill/construction/decoration/kitchen/ShelfPlugin.java new file mode 100644 index 0000000..9fed7eb --- /dev/null +++ b/Server/src/main/content/global/skill/construction/decoration/kitchen/ShelfPlugin.java @@ -0,0 +1,239 @@ +package content.global.skill.construction.decoration.kitchen; + + +import core.cache.def.impl.SceneryDefinition; +import core.game.dialogue.DialoguePlugin; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.plugin.ClassScanner; +import org.rs09.consts.Items; + +/** + * Handles the shelves in the kitchen room. + * @author Splinter + */ +@Initializable +public final class ShelfPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ClassScanner.definePlugin(new ShelfDialogue()); + for (int i = 13545; i < 13552; i++) { + SceneryDefinition.forId(i).getHandlers().put("option:search", this); + } + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + player.getDialogueInterpreter().open(778341, node.getId()); + return true; + } + + /** + * Dialogue options for the shelves, what a mess! + * @author Splinter + * @version 1.0 + */ + public final class ShelfDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code ShelfDialogue} {@code Object}. + */ + public ShelfDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code ShelfDialogue} {@code Object}. + * @param player the player. + */ + public ShelfDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new ShelfDialogue(player); + } + + @Override + public boolean open(Object... args) { + int id = (int) args[0]; + switch (id) { + case 13545:// wood 1 + interpreter.sendOptions("Select an Option", "Kettle", "Teapot", "Clay cup"); + stage = 1; + break; + case 13546:// wood 2 + interpreter.sendOptions("Select an Option", "Kettle", "Teapot", "Clay cup", "Empty beer glass"); + stage = 1; + break; + case 13547:// wood 3 + interpreter.sendOptions("Select an Option", "Kettle", "Teapot", "Clay cup", "Empty beer glass", "Cake tin"); + stage = 1; + break; + case 13548:// oak 1 + interpreter.sendOptions("Select an Option", "Kettle", "Teapot", "Clay cup", "Empty beer glass", "Bowl"); + stage = 2; + break; + case 13549:// oak 2 + interpreter.sendOptions("Select an Option", "Kettle", "Teapot", "Porcelain cup", "Empty beer glass", "More Options"); + stage = 3; + break; + case 13550:// teak 1 + case 13551: + interpreter.sendOptions("Select an Option", "Kettle", "Teapot", "Porcelain cup", "Empty beer glass", "More Options"); + stage = 5; + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + if (player.getInventory().freeSlots() < 1) { + player.sendMessage("You need at least one free inventory space to take from the shelves."); + end(); + return true; + } + switch (stage) { + case 1:// all wood shelves + switch (buttonId) { + case 1: + end(); + player.getInventory().add(new Item(Items.KETTLE_7688, 1)); + break; + case 2: + end(); + player.getInventory().add(new Item(Items.TEAPOT_7702, 1)); + break; + case 3: + end(); + player.getInventory().add(new Item(Items.EMPTY_CUP_7728, 1)); + break; + case 4: + end(); + player.getInventory().add(new Item(Items.BEER_GLASS_1919, 1)); + break; + case 5: + end(); + player.getInventory().add(new Item(Items.CAKE_TIN_1887, 1)); + break; + } + break; + case 2:// Oak shelf #1 + switch (buttonId) { + case 1: + end(); + player.getInventory().add(new Item(Items.KETTLE_7688, 1)); + break; + case 2: + end(); + player.getInventory().add(new Item(Items.TEAPOT_7702, 1)); + break; + case 3: + end(); + player.getInventory().add(new Item(Items.EMPTY_CUP_7728, 1)); + break; + case 4: + end(); + player.getInventory().add(new Item(Items.BEER_GLASS_1919, 1)); + break; + case 5: + end(); + player.getInventory().add(new Item(Items.BOWL_1923, 1)); + break; + } + break; + case 3:// Oak shelves #2 only + switch (buttonId) { + case 1: + end(); + player.getInventory().add(new Item(Items.KETTLE_7688, 1)); + break; + case 2: + end(); + player.getInventory().add(new Item(Items.TEAPOT_7702, 1)); + break; + case 3: + end(); + player.getInventory().add(new Item(Items.PORCELAIN_CUP_4244, 1)); + break; + case 4: + end(); + player.getInventory().add(new Item(Items.BEER_GLASS_1919, 1)); + break; + case 5: + interpreter.sendOptions("Select an Option", "Bowl", "Cake tin"); + stage = 4; + break; + } + break; + case 4:// Oak shelves #2 only + switch (buttonId) { + case 1: + end(); + player.getInventory().add(new Item(Items.BOWL_1923, 1)); + break; + case 2: + end(); + player.getInventory().add(new Item(Items.CAKE_TIN_1887, 1)); + break; + } + case 5:// teak shelves + switch (buttonId) { + case 1: + end(); + player.getInventory().add(new Item(Items.KETTLE_7688, 1)); + break; + case 2: + end(); + player.getInventory().add(new Item(Items.TEAPOT_7702, 1)); + break; + case 3: + end(); + player.getInventory().add(new Item(Items.PORCELAIN_CUP_7735, 1)); + break; + case 4: + end(); + player.getInventory().add(new Item(Items.BEER_GLASS_1919, 1)); + break; + case 5: + interpreter.sendOptions("Select an Option", "Bowl", "Pie dish", "Empty pot"); + stage = 6; + break; + } + break; + case 6:// teak shelves + switch (buttonId) { + case 1: + end(); + player.getInventory().add(new Item(Items.BOWL_1923, 1)); + break; + case 2: + end(); + player.getInventory().add(new Item(Items.PIE_DISH_2313, 1)); + break; + case 3: + end(); + player.getInventory().add(new Item(Items.EMPTY_POT_1931, 1)); + break; + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 778341 }; + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/decoration/portalchamber/PortalChamberDialogue.kt b/Server/src/main/content/global/skill/construction/decoration/portalchamber/PortalChamberDialogue.kt new file mode 100644 index 0000000..eeaf6e4 --- /dev/null +++ b/Server/src/main/content/global/skill/construction/decoration/portalchamber/PortalChamberDialogue.kt @@ -0,0 +1,51 @@ +package content.global.skill.construction.decoration.portalchamber + +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.player.Player +import content.global.skill.construction.decoration.portalchamber.PortalChamberPlugin +import core.plugin.Initializable + +/** + * Portal Chamber Dialogue go brrrrrr + * @author Ceikry + */ +@Initializable +class PortalChamberDialogue(player: Player? = null) : DialoguePlugin(player) { + var portal = "none" + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> when(buttonId){ + 1 -> directPortal("varrock") + 2 -> directPortal("lumbridge") + 3 -> directPortal("falador") + 4 -> options("Camelot Portal","Ardougne Portal","Yanille Portal","Kharyll Portal").also { stage++ } + } + 1 -> when(buttonId){ + 1 -> directPortal("camelot") + 2 -> directPortal("ardougne") + 3 -> directPortal("yanille") + 4 -> directPortal("kharyrll") + } + } + return true + } + + fun directPortal(portal: String){ + PortalChamberPlugin.direct(player,portal.toUpperCase()) + end() + } + + override fun open(vararg args: Any?): Boolean { + player.dialogueInterpreter.sendOptions("Select one.","Varrock Portal","Lumbridge Portal","Falador Portal","More...") + stage = 0 + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return PortalChamberDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(394857) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/decoration/portalchamber/PortalChamberPlugin.java b/Server/src/main/content/global/skill/construction/decoration/portalchamber/PortalChamberPlugin.java new file mode 100644 index 0000000..ad8c68d --- /dev/null +++ b/Server/src/main/content/global/skill/construction/decoration/portalchamber/PortalChamberPlugin.java @@ -0,0 +1,272 @@ +package content.global.skill.construction.decoration.portalchamber; + + +import content.global.skill.construction.Hotspot; +import content.global.skill.runecrafting.Rune; +import core.cache.def.impl.SceneryDefinition; +import core.game.dialogue.DialogueInterpreter; +import core.game.dialogue.DialoguePlugin; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import content.global.skill.construction.Decoration; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.plugin.ClassScanner; + +import static content.region.kandarin.ardougne.quest.plaguecity.PlagueCityListeners.ARDOUGNE_TELE_ATTRIBUTE; + +/** + * PortalChamberPlugin + * @author Clayton Williams + * @date Jan 2, 2016 + */ +@Initializable +public class PortalChamberPlugin extends OptionHandler { + + /** + * Locations + * @author Clayton Williams + * @date Jan 3, 2016 + */ + private static enum Locations { + + VARROCK(Location.create(3213, 3428, 0), new Item(Rune.FIRE.getRune().getId(), 100), new Item(Rune.AIR.getRune().getId(), 300), new Item(Rune.LAW.getRune().getId(), 100)), + LUMBRIDGE(Location.create(3222, 3217, 0), new Item(Rune.EARTH.getRune().getId(), 100), new Item(Rune.AIR.getRune().getId(), 300), new Item(Rune.LAW.getRune().getId(), 100)), + FALADOR(Location.create(2965, 3380, 0), new Item(Rune.WATER.getRune().getId(), 100), new Item(Rune.AIR.getRune().getId(), 300), new Item(Rune.LAW.getRune().getId(), 100)), + CAMELOT(Location.create(2730, 3485, 0), new Item(Rune.AIR.getRune().getId(), 500), new Item(Rune.LAW.getRune().getId(), 100)), + ARDOUGNE(Location.create(2663, 3305, 0), new Item(Rune.WATER.getRune().getId(), 200), new Item(Rune.LAW.getRune().getId(), 200)), + YANILLE(Location.create(2554, 3114, 0), new Item(Rune.EARTH.getRune().getId(), 200), new Item(Rune.LAW.getRune().getId(), 200)), + KHARYRLL(Location.create(3493, 3474, 0), new Item(Rune.BLOOD.getRune().getId(), 100), new Item(Rune.LAW.getRune().getId(), 200)); + + /** + * The location to teleport to + */ + private Location location; + + /** + * The rune requirements + */ + private Item[] runes; + + /** + * Locations + * @param location + * @param runes + */ + Locations(Location location, Item... runes) { + this.location = location; + this.runes = runes; + } + } + + /** + * Directs a portal + * @param player + * @param identifier + */ + public static void direct(Player player, String identifier) { + player.getInterfaceManager().closeSingleTab(); + int dpId = player.getAttribute("con:dp-id", 1); + Hotspot[] hotspots = player.getHouseManager().getRoom(player.getLocation()).getHotspots(); + for (int i = 0; i < hotspots.length; i++) { + Hotspot h = hotspots[i]; + if (h.getHotspot().name().equalsIgnoreCase("PORTAL" + dpId)) { + if (h.getDecorationIndex() == -1) { + player.sendMessage("You must build a portal frame first!"); + return; + } + Decoration previous = h.getHotspot().getDecorations()[h.getDecorationIndex()]; + String name = previous.name(); + String prefix = "TEAK"; + if (name.toLowerCase().contains("mahogany")) { + prefix = "MAHOGANY"; + } else if (name.toLowerCase().contains("marble")) { + prefix = "MARBLE"; + } + for (Locations l : Locations.values()) { + if (l.name().contains(identifier)) { + if (l == Locations.ARDOUGNE){ + if (player.getAttribute(ARDOUGNE_TELE_ATTRIBUTE, false)){ + player.sendMessage("You do not have the requirements to direct the portal there"); + return; + } + } + Item[] runes = l.runes; + if (!player.getInventory().containsItems(runes)) { + player.sendMessage("You do not have the required runes to build this portal"); + return; + } + player.getInventory().remove(runes); + break; + } + } + h.setDecorationIndex(h.getHotspot().getDecorationIndex(Decoration.forName(prefix + "_" + identifier + "_" + "PORTAL"))); + player.getHouseManager().reload(player, player.getHouseManager().isBuildingMode()); //TODO replace object live instead? + } + } + } + + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(13639).getHandlers().put("option:direct-portal", this); + SceneryDefinition.forId(13639).getHandlers().put("option:scry", this); + SceneryDefinition.forId(13640).getHandlers().put("option:direct-portal", this); + SceneryDefinition.forId(13641).getHandlers().put("option:direct-portal", this); + for (int i = 13615; i <= 13635; i++) { + SceneryDefinition.forId(i).getHandlers().put("option:enter", this); + } + ClassScanner.definePlugin(new DirectPortalDialogue()); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + Scenery object = node.asScenery(); + switch (option) { + case "direct-portal": + if (!player.getHouseManager().isBuildingMode()) { + player.sendMessage("You can currently only do this in building mode."); + return true; + } + player.getDialogueInterpreter().open(DialogueInterpreter.getDialogueKey("con:directportal")); + return true; + case "enter": + String objectName = object.getName(); + for (Locations l : Locations.values()) { + if (l == Locations.ARDOUGNE){ + if (player.getAttribute(ARDOUGNE_TELE_ATTRIBUTE, false)){ + player.sendMessage("You do not have the requirements to enter this portal."); + return false; + } + } + if (objectName.toLowerCase().contains(l.name().toLowerCase())) { + player.teleport(l.location); + if (player.getHouseManager().isInHouse(player) && node.getId() == 13635) { + //player.getAchievementDiaryManager().getDiary(DiaryType.MORYTANIA).updateTask(player, 2, 0, true); + } + break; + } + } + return true; + case "scry": + //wtf + return true; + } + return false; + } + + /** + * DirectPortalDialogue.java + * @author Clayton Williams + * @date Jan 2, 2016 + */ + private static final class DirectPortalDialogue extends DialoguePlugin { + + /** + * DirectPortalDialogue + */ + public DirectPortalDialogue() { + /** + * Empty + */ + } + + /** + * DirectPortalDialogue + * @param player + */ + public DirectPortalDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new DirectPortalDialogue(player); + } + + @Override + public boolean open(Object... args) { + interpreter.sendOptions("Select a portal", "Portal 1", "Portal 2", "Portal 3"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + player.setAttribute("con:dp-id", buttonId); + end(); + player.getDialogueInterpreter().open(394857); + return true; + } + + @Override + public int[] getIds() { + return new int[]{DialogueInterpreter.getDialogueKey("con:directportal")}; + } + + } + + /** + * The direct options build + */ + /*private final static TabbedOption DIRECT_OPTIONS = new TabbedOption("Direct Portal", "Select an option", + new Page( + new PageAction("Varrock Portal") { + @Override + public boolean run(Player player) { + PortalChamberPlugin.direct(player, "VARROCK"); + return true; + } + }, + new PageAction("Lumbridge Portal") { + @Override + public boolean run(Player player) { + PortalChamberPlugin.direct(player, "LUMBRIDGE"); + return true; + } + }, + new PageAction("Falador Portal") { + @Override + public boolean run(Player player) { + PortalChamberPlugin.direct(player, "FALADOR"); + return true; + } + }, + new PageAction("Camelot Portal") { + @Override + public boolean run(Player player) { + PortalChamberPlugin.direct(player, "CAMELOT"); + return true; + } + }, + new PageAction("Ardougne Portal") { + @Override + public boolean run(Player player) { + PortalChamberPlugin.direct(player, "ARDOUGNE"); + return true; + } + } + ), new Page( + new PageAction("Yanille Portal") { + @Override + public boolean run(Player player) { + PortalChamberPlugin.direct(player, "YANILLE"); + return true; + } + }, + new PageAction("Kharyrll Portal") { + @Override + public boolean run(Player player) { + PortalChamberPlugin.direct(player, "KHARYRLL"); + return true; + } + } + ) + );*/ + +} diff --git a/Server/src/main/content/global/skill/construction/decoration/questhall/MountedGlory.kt b/Server/src/main/content/global/skill/construction/decoration/questhall/MountedGlory.kt new file mode 100644 index 0000000..47051e4 --- /dev/null +++ b/Server/src/main/content/global/skill/construction/decoration/questhall/MountedGlory.kt @@ -0,0 +1,77 @@ +package content.global.skill.construction.decoration.questhall + +import core.api.playGlobalAudio +import core.api.teleport +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.Node +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.node.scenery.Scenery +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import org.rs09.consts.Items +import org.rs09.consts.Sounds +import java.util.concurrent.Executors +import java.util.concurrent.TimeUnit + +class MountedGlory : InteractionListener { + + val MOUNTED_GLORY = 13523 + + val TELEPORTS = arrayOf( + Location.create(3087, 3495, 0), + Location.create(2919, 3175, 0), + Location.create(3104, 3249, 0), + Location.create(3304, 3124, 0) + ) + + override fun defineListeners() { + on(MOUNTED_GLORY, IntType.SCENERY, "Edgeville") { player, `object` -> + mountedGloryAction(player, `object`, 0) + return@on true + } + + on(MOUNTED_GLORY, IntType.SCENERY, "Karamja") { player, `object` -> + mountedGloryAction(player, `object`, 1) + return@on true + } + + on(MOUNTED_GLORY, IntType.SCENERY, "Draynor Village") { player, `object` -> + mountedGloryAction(player, `object`, 2) + return@on true + } + + on(MOUNTED_GLORY, IntType.SCENERY, "Al Kharid") { player, `object` -> + mountedGloryAction(player, `object`, 3) + return@on true + } + } + private fun mountedGloryAction(player : Player, `object` : Node, int : Int) { + if (player.houseManager.isBuildingMode) { + player.dialogueInterpreter.open("con:removedec", `object` as Scenery) + return + } + if (!player.zoneMonitor.teleport(1, Item(Items.AMULET_OF_GLORY_1704))) { + return + } + Executors.newSingleThreadScheduledExecutor().schedule({ + player.pulseManager.run(object : Pulse() { + var counter = 0 + override fun pulse(): Boolean { + when (counter++) { + 1 -> { + player.lock(5) + player.visualize(Animation(714), Graphics(308, 100, 50)) + playGlobalAudio(player.location, Sounds.TELEPORT_ALL_200) + } + 4 -> player.animator.reset().also { teleport(player, TELEPORTS[int]) } + } + return false + } + }) + }, 0, TimeUnit.SECONDS) + } +} diff --git a/Server/src/main/content/global/skill/construction/decoration/questhall/MountedGloryPlugin.java b/Server/src/main/content/global/skill/construction/decoration/questhall/MountedGloryPlugin.java new file mode 100644 index 0000000..90d96eb --- /dev/null +++ b/Server/src/main/content/global/skill/construction/decoration/questhall/MountedGloryPlugin.java @@ -0,0 +1,98 @@ +package content.global.skill.construction.decoration.questhall; + + +import core.cache.def.impl.SceneryDefinition; +import core.game.dialogue.DialogueAction; +import core.game.dialogue.DialogueInterpreter; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.plugin.Plugin; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playGlobalAudio; + +/** + * Handles the POH Mounted Glory. + * @author Splinter + */ +@Initializable +public class MountedGloryPlugin extends OptionHandler { + + /** + * Represents the teleport animation. + */ + private static final Animation ANIMATION = new Animation(714); + + /** + * Represents the graphics to use. + */ + private static final Graphics GRAPHICS = new Graphics(308, 100, 50); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(13523).getHandlers().put("option:rub", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + DialogueInterpreter interpreter = player.getDialogueInterpreter(); + interpreter.sendOptions("Select a location.", "Edgeville", "Karamja", "Draynor Village", "Al-Kharid", "Nowhere."); + interpreter.addAction(new DialogueAction() { + + @Override + public void handle(Player player, int buttonId) { + switch (buttonId) { + case 2: + teleport(player, Location.create(3087, 3495, 0)); + break; + case 3: + teleport(player, Location.create(2919, 3175, 0)); + break; + case 4: + teleport(player, Location.create(3081, 3250, 0)); + break; + case 5: + teleport(player, Location.create(3304, 3124, 0)); + break; + } + } + + }); + return true; + } + + /** + * Method used to teleport to a location. + * @param player the player. + * @param location the location. + */ + private boolean teleport(final Player player, final Location location) { + if (player.isTeleBlocked()) { + player.sendMessage("A magical force has stopped you from teleporting."); + return false; + } + player.lock(); + player.visualize(ANIMATION, GRAPHICS); + playGlobalAudio(player.getLocation(), Sounds.TELEPORT_ALL_200); + player.getImpactHandler().setDisabledTicks(4); + GameWorld.getPulser().submit(new Pulse(4, player) { + @Override + public boolean pulse() { + player.unlock(); + player.getProperties().setTeleportLocation(location); + player.getAnimator().reset(); + return true; + } + }); + return true; + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/decoration/study/LecternPlugin.kt b/Server/src/main/content/global/skill/construction/decoration/study/LecternPlugin.kt new file mode 100644 index 0000000..eb4accf --- /dev/null +++ b/Server/src/main/content/global/skill/construction/decoration/study/LecternPlugin.kt @@ -0,0 +1,227 @@ +package content.global.skill.construction.decoration.study + +import content.global.handlers.item.TeleTabsListener +import core.api.* +import core.cache.def.impl.SceneryDefinition +import core.game.component.Component +import core.game.interaction.OptionHandler +import core.game.node.Node +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.diary.DiaryType +import core.game.node.entity.skill.Skills +import content.global.skill.construction.Decoration +import content.region.kandarin.ardougne.quest.plaguecity.PlagueCityListeners.Companion.ARDOUGNE_TELE_ATTRIBUTE +import core.game.node.entity.combat.spell.MagicStaff +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.game.world.update.flag.context.Animation +import core.plugin.Initializable +import core.plugin.Plugin +import core.game.world.GameWorld +import core.game.interaction.InterfaceListener +import org.rs09.consts.Items + +/** + * Handles the lectern + * LecternPlugin + * @author Ceikry + */ +@Initializable +class LecternPlugin : OptionHandler() { + /** + * TeleTabButton + */ + private enum class TeleTabButton( + /** + * The button id + */ + val buttonId: Int, + /** + * The level and xp + */ + val level: Int, + val xp: Double, + /** + * The item + */ + val tabItem: Item, + /** + * The required decoration (lectern) + */ + private val requiredDecorations: Array, vararg requiredItems: Item) { + ARDOUGNE(2, 51, 61.0, Item(TeleTabsListener.TeleTabs.ADDOUGNE_TELEPORT.item), arrayOf(Decoration.TEAK_EAGLE_LECTERN, Decoration.MAHOGANY_EAGLE_LECTERN), SOFT_CLAY, Item(Items.LAW_RUNE_563, 2), Item(Items.WATER_RUNE_555, 2)), + BONES_TO_BANANNAS(3, 15, 25.0, Item(Items.BONES_TO_BANANAS_8014), arrayOf(Decoration.DEMON_LECTERN, Decoration.TEAK_DEMON_LECTERN, Decoration.MAHOGANY_DEMON_LECTERN), SOFT_CLAY, Item(Items.NATURE_RUNE_561, 1), Item(Items.EARTH_RUNE_557, 2), Item(Items.WATER_RUNE_555, 2)), + BONES_TO_PEACHES(4, 60, 35.5, Item(Items.BONES_TO_PEACHES_8015), arrayOf(Decoration.MAHOGANY_DEMON_LECTERN), SOFT_CLAY, Item(Items.NATURE_RUNE_561, 2), Item(Items.EARTH_RUNE_557, 4), Item(Items.WATER_RUNE_555, 4)), + CAMELOT(5, 45, 55.5, Item(TeleTabsListener.TeleTabs.CAMELOT_TELEPORT.item), arrayOf(Decoration.TEAK_EAGLE_LECTERN, Decoration.MAHOGANY_EAGLE_LECTERN), SOFT_CLAY, Item(Items.LAW_RUNE_563), Item(Items.AIR_RUNE_556, 5)), + ENCHANT_DIAMOND(6, 57, 67.0, Item(Items.ENCHANT_DIAMOND_8019), arrayOf(Decoration.TEAK_DEMON_LECTERN, Decoration.MAHOGANY_DEMON_LECTERN), SOFT_CLAY, Item(Items.COSMIC_RUNE_564), Item(Items.EARTH_RUNE_557, 10)), + ENCHANT_DRAGONSTONE(7, 68, 78.0, Item(Items.ENCHANT_DRAGONSTN_8020), arrayOf(Decoration.MAHOGANY_DEMON_LECTERN), SOFT_CLAY, Item(Items.COSMIC_RUNE_564), Item(Items.EARTH_RUNE_557, 15), Item(Items.WATER_RUNE_555, 15)), + ENCHANT_EMERALD(8, 27, 37.0, Item(Items.ENCHANT_EMERALD_8017), arrayOf(Decoration.DEMON_LECTERN, Decoration.TEAK_DEMON_LECTERN, Decoration.MAHOGANY_DEMON_LECTERN), SOFT_CLAY, Item(Items.COSMIC_RUNE_564), Item(Items.AIR_RUNE_556, 3)), + ENCHANT_ONYX(9, 87, 97.0, Item(Items.ENCHANT_ONYX_8021), arrayOf(Decoration.MAHOGANY_DEMON_LECTERN), SOFT_CLAY, Item(Items.COSMIC_RUNE_564), Item(Items.EARTH_RUNE_557, 20), Item(Items.FIRE_RUNE_554, 20)), + ENCHANT_RUBY(10, 49, 59.0, Item(Items.ENCHANT_RUBY_8018), arrayOf(Decoration.TEAK_DEMON_LECTERN, Decoration.MAHOGANY_DEMON_LECTERN), SOFT_CLAY, Item(Items.COSMIC_RUNE_564), Item(Items.FIRE_RUNE_554, 5)), + ENCHANT_SAPPHIRE(11, 7, 17.5, Item(Items.ENCHANT_SAPPHIRE_8016), arrayOf(Decoration.OAK_LECTERN, Decoration.EAGLE_LECTERN, Decoration.TEAK_EAGLE_LECTERN, Decoration.MAHOGANY_EAGLE_LECTERN, Decoration.DEMON_LECTERN, Decoration.TEAK_DEMON_LECTERN, Decoration.MAHOGANY_DEMON_LECTERN), SOFT_CLAY, Item(Items.COSMIC_RUNE_564), Item(Items.WATER_RUNE_555)), + FALADOR(12, 37, 48.0, Item(TeleTabsListener.TeleTabs.FALADOR_TELEPORT.item), arrayOf(Decoration.EAGLE_LECTERN, Decoration.TEAK_EAGLE_LECTERN, Decoration.MAHOGANY_EAGLE_LECTERN), SOFT_CLAY, Item(Items.LAW_RUNE_563), Item(Items.WATER_RUNE_555), Item(Items.AIR_RUNE_556, 3)), + LUMBRIDGE(13, 31, 41.0, Item(TeleTabsListener.TeleTabs.LUMBRIDGE_TELEPORT.item), arrayOf(Decoration.EAGLE_LECTERN, Decoration.TEAK_EAGLE_LECTERN, Decoration.MAHOGANY_EAGLE_LECTERN), SOFT_CLAY, Item(Items.LAW_RUNE_563), Item(Items.EARTH_RUNE_557), Item(Items.AIR_RUNE_556, 3)), + HOUSE(14, 40, 30.0, Item(Items.TELEPORT_TO_HOUSE_8013), arrayOf(Decoration.MAHOGANY_EAGLE_LECTERN), SOFT_CLAY, Item(Items.LAW_RUNE_563), Item(Items.EARTH_RUNE_557), Item(Items.AIR_RUNE_556)), + VARROCK(15, 25, 35.0, Item(TeleTabsListener.TeleTabs.VARROCK_TELEPORT.item), arrayOf(Decoration.OAK_LECTERN, Decoration.EAGLE_LECTERN, Decoration.TEAK_EAGLE_LECTERN, Decoration.MAHOGANY_EAGLE_LECTERN, Decoration.DEMON_LECTERN, Decoration.TEAK_DEMON_LECTERN, Decoration.MAHOGANY_DEMON_LECTERN), SOFT_CLAY, Item(Items.LAW_RUNE_563), Item(Items.FIRE_RUNE_554), Item(Items.AIR_RUNE_556, 3)), + WATCHTOWER(16, 58, 68.0, Item(TeleTabsListener.TeleTabs.WATCH_TOWER_TELEPORT.item), arrayOf(Decoration.MAHOGANY_EAGLE_LECTERN), SOFT_CLAY, Item(Items.LAW_RUNE_563, 2), Item(Items.EARTH_RUNE_557, 2)); + + /** + * The required items + */ + val requiredItems: ArrayList = arrayListOf(*requiredItems) + + /** + * Checks if the player can make this tab + * @param player + * @return + */ + fun canMake(player: Player): Boolean { + val objectId = player.getAttribute("ttb:objectid") + if (player.skills.getLevel(Skills.MAGIC) < level && player.spellBookManager.spellBook == 192) { + player.sendMessage("You need a magic level of $level to make that!") + return false + } + if (this == BONES_TO_PEACHES && !player.savedData.activityData.isBonesToPeaches) { + player.sendMessages("You need the Bones to Peaches ability purchased from MTA before making these.", "This requirement doesn't apply to actually using the tabs.") + return false + } + if(this == ARDOUGNE && !getAttribute(player, ARDOUGNE_TELE_ATTRIBUTE, false)){ + sendMessage(player, "You need to unlock Ardougne teleport before you can make a tablet.") + return false + + } + var found = false + for (d in requiredDecorations) if (d.objectId == objectId) found = true + if (!found) { + player.sendMessage("You're unable to make this tab on this specific lectern.") + return false + } + for (item in requiredItems) { + val staff = MagicStaff.forId(item.id) + if (staff != null && player.equipment.containsAtLeastOneItem(staff.staves)) { + continue + } + if (!player.inventory.containsItem(item)) { + //TODO staffs + player.sendMessage("You don't have enough materials.") + return false + } + } + return true + } + + companion object { + /** + * Gets the button for the id + * @param id + * @return + */ + fun forId(id: Int): TeleTabButton? { + for (ttb in values()) { + if (ttb.buttonId == id) return ttb + } + return null + } + } + + } + + @Throws(Throwable::class) + override fun newInstance(arg: Any?): Plugin? { + for (i in 13642..13648) { + SceneryDefinition.forId(i).handlers["option:study"] = this + } + return this + } + + override fun handle(player: Player, node: Node, option: String): Boolean { + val id = node.asScenery().id + player.setAttribute("ttb:objectid", id) + GameWorld.Pulser.submit(object : Pulse(){ + var counter = 0 + override fun pulse(): Boolean { + when(counter++){ + 0 -> player.animator.animate(Animation(1894)).also { player.lock() } + 1 -> player.interfaceManager.open(Component(400)).also { player.unlock(); return true } + } + return false + } + }) + return true + } + + /** + * TeleTabInterface + * @author Ceikry + */ + class TeleTabInterface : InterfaceListener { + val decorationVarps = hashMapOf( + Decoration.OAK_LECTERN to Pair(0, 0), + Decoration.EAGLE_LECTERN to Pair(1, 0), + Decoration.DEMON_LECTERN to Pair(0, 1), + Decoration.TEAK_EAGLE_LECTERN to Pair(2, 0), + Decoration.TEAK_DEMON_LECTERN to Pair(0, 2), + Decoration.MAHOGANY_EAGLE_LECTERN to Pair(3, 0), + Decoration.MAHOGANY_DEMON_LECTERN to Pair(0, 3), + ) + override fun defineInterfaceListeners() { + onOpen(400) { player, component -> + val id = player.getAttribute("ttb:objectid", 0) + val deco = Decoration.forObjectId(id) + val values = decorationVarps[deco] ?: Pair(0, 0) + setVarp(player, 261, values.first) + setVarp(player, 262, values.second) + return@onOpen true + } + on(400) { player, _, _, buttonID, _, _ -> + val ttb = TeleTabButton.forId(buttonID) + if (ttb != null && ttb.canMake(player)) { + player.interfaceManager.close() + var requiredItemsCountingStaves = ttb.requiredItems.filter({ item -> + val staff = MagicStaff.forId(item.id) + !(staff != null && player.equipment.containsAtLeastOneItem(staff.staves)) + }).toTypedArray() + player.pulseManager.run(object : Pulse(1) { + var counter = 0 + override fun pulse(): Boolean { + when(counter++) { + 0 -> { + if (!ttb.canMake(player)) { + return true + } + //TODO Add correct lectern animation (should look like raising arms progressively higher 3 times). + player.animate(Animation(782)) + } + 2 -> { + if (player.inventory.remove(*requiredItemsCountingStaves)) { + // Should never drop, since soft clay was successfully removed + addItemOrDrop(player, ttb.tabItem.id) + player.skills.addExperience(Skills.MAGIC, ttb.xp, true) + if (ttb == TeleTabButton.VARROCK + && (player.getAttribute("ttb:objectid", 0) == Decoration.MAHOGANY_EAGLE_LECTERN.objectId + || player.getAttribute("ttb:objectid", 0) == Decoration.MAHOGANY_DEMON_LECTERN.objectId)) { + player.achievementDiaryManager.finishTask(player, DiaryType.VARROCK, 2, 8) + } + } else { + return true + } + } + } + counter %= 6 + return false + } + }) + } + player.animate(Animation(-1)) + return@on true + } + } + } + + companion object { + /** + * Soft clay + */ + private val SOFT_CLAY = Item(Items.SOFT_CLAY_1761, 1) + } +} diff --git a/Server/src/main/content/global/skill/construction/decoration/study/TelescopePlugin.kt b/Server/src/main/content/global/skill/construction/decoration/study/TelescopePlugin.kt new file mode 100644 index 0000000..ea1d8c7 --- /dev/null +++ b/Server/src/main/content/global/skill/construction/decoration/study/TelescopePlugin.kt @@ -0,0 +1,59 @@ +package content.global.skill.construction.decoration.study + +import core.cache.def.impl.SceneryDefinition +import core.game.component.Component +import core.game.interaction.OptionHandler +import core.game.node.Node +import core.game.node.scenery.Scenery +import core.game.node.entity.player.Player +import core.game.system.task.Pulse +import core.game.world.update.flag.context.Animation +import core.plugin.Initializable +import core.plugin.Plugin +import core.tools.RandomFunction +import content.global.activity.shootingstar.ShootingStarPlugin +import core.game.world.GameWorld.Pulser +import java.util.concurrent.TimeUnit + +@Initializable +class TelescopePlugin : OptionHandler() { + @Throws(Throwable::class) + override fun newInstance(arg: Any?): Plugin? { + SceneryDefinition.forId(13656).handlers["option:observe"] = this + SceneryDefinition.forId(13657).handlers["option:observe"] = this + SceneryDefinition.forId(13658).handlers["option:observe"] = this + return this + } + + override fun handle(player: Player?, node: Node?, option: String?): Boolean { + val obj = node?.asScenery() as Scenery + val star = ShootingStarPlugin.getStar() + val delay: Int = 25000 + (25000 / 3) + val timeLeft = delay - star.ticks + val window = when (obj.id) { + 13657 -> 9 + 13658 -> 2 + else -> 24 + } + val fakeTimeLeft = RandomFunction.random(-window, window+1) + TimeUnit.MILLISECONDS.toMinutes(timeLeft * 600L) + player?.lock() + player?.animate(ANIMATION) + player?.interfaceManager?.open(Component(782)).also { + player?.unlock() + Pulser.submit(object : Pulse(2, player) { + override fun pulse(): Boolean { + if (obj.isActive) { + player?.dialogueInterpreter?.sendDialogue("You see a shooting star! The star looks like it will land","in about $fakeTimeLeft minutes!") + return true + } + return true + } + }) + return true + } + } + + companion object { + private val ANIMATION = Animation.create(3649) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/decoration/workshop/ArmourStand.kt b/Server/src/main/content/global/skill/construction/decoration/workshop/ArmourStand.kt new file mode 100644 index 0000000..b30f862 --- /dev/null +++ b/Server/src/main/content/global/skill/construction/decoration/workshop/ArmourStand.kt @@ -0,0 +1,106 @@ +package content.global.skill.construction.decoration.workshop + +import core.game.dialogue.DialoguePlugin +import content.data.RepairItem +import core.game.interaction.NodeUsageEvent +import core.game.interaction.UseWithHandler +import content.region.misthalin.lumbridge.dialogue.BobDialogue.BarrowsEquipment +import content.region.misthalin.lumbridge.dialogue.BobDialogue.BarrowsEquipment.BarrowsFullEquipment +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.plugin.Initializable +import core.plugin.Plugin +import kotlin.math.ceil +import org.rs09.consts.Items + +@Initializable +class ArmourStand : UseWithHandler(494, 468, 496, 470, 498, 472, 500, 502, 474, 504, 476, 506, 478, 6741, 4856, 4857, 4858, 4859, 4860, 4862, 4863, 4864, 4865, 4866, 4868, 4869, 4870, 4871, 4872, 4874, 4875, 4876, 4877, 4878, 4880, 4881, 4882, 4883, 4884, 4886, 4887, 4888, 4889, 4890, 4892, 4893, 4894, 4895, 4896, 4898, 4899, 4900, 4901, 4902, 4904, 4905, 4906, 4907, 4908, 4910, 4911, 4912, 4913, 4914, 4916, 4917, 4918, 4919, 4920, 4922, 4923, 4924, 4925, 4926, 4928, 4929, 4930, 4931, 4932, 4934, 4935, 4936, 4937, 4938, 4940, 4941, 4942, 4943, 4944, 4946, 4947, 4948, 4949, 4950, 4952, 4953, 4954, 4955, 4956, 4958, 4959, 4960, 4961, 4962, 4964, 4965, 4966, 4967, 4968, 4970, 4971, 4972, 4973, 4974, 4976, 4977, 4978, 4979, 4980, 4982, 4983, 4984, 4985, 4986, 4988, 4989, 4990, 4991, 4992, 4994, 4995, 4996, 4997, 4998){ + override fun newInstance(arg: Any?): Plugin { + addHandler(13715, OBJECT_TYPE, this) + return this + } + + override fun handle(event: NodeUsageEvent?): Boolean { + event ?: return false + val player = event.player + val repairItem = RepairItem.forId(event.used.id) + + var baseCost = 0.0 + var product: Item? = null + + if(repairItem != null){ + baseCost = repairItem.cost * 1.0 + product = repairItem.product + } else if(BarrowsEquipment.isBarrowsItem(event.used.id)){ + //Begin terrible code thanks to Vexia + val type = BarrowsEquipment.formatedName(event.used.id) + val single = BarrowsEquipment.getSingleName(type) + val equipment = BarrowsEquipment.getEquipmentType(type) + val newString = type.toLowerCase().replace(single, "").trim { it <= ' ' }.replace("'s", "") + val newewString = StringBuilder() + newewString.append(newString).append(" $equipment") + val fullequip = BarrowsFullEquipment.forName(newewString.toString()) + baseCost = BarrowsEquipment.getFormatedCost(equipment,event.used.asItem()) * 1.0 + product = fullequip.full + //End terrible code thanks to Vexia + } + + if((repairItem == null && baseCost == 0.0)){ + player.sendMessage("That item can't be repaired.") + return true + } + + val cost: Int = ceil(((100.0 - (player.skills.getLevel(Skills.SMITHING) / 2.0) ) / 100.0) * baseCost).toInt() + + player.dialogueInterpreter.open(58824213,event.used,cost,product) + + return true + } + @Initializable + class RepairDialogue(player: Player? = null) : DialoguePlugin(player){ + override fun newInstance(player: Player?): DialoguePlugin { + return RepairDialogue(player) + } + var item: Item? = null + var cost: Int = 0 + var product: Item? = null + + override fun open(vararg args: Any?): Boolean { + item = args[0] as Item + cost = args[1] as Int + product = args[2] as Item + player.dialogueInterpreter.sendDialogue("Would you like to repair your ${(item as Item).name.toLowerCase()}","for $cost gp?") + stage = 0 + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + item ?: return false + product ?: return false + when(stage){ + 0 -> options("Yes, please","No, thanks").also{stage++} + 1 -> when(buttonId){ + 1 -> exchangeItems(item as Item,cost,product as Item).also { end() } + 2 -> end() + } + } + return true + } + + fun exchangeItems(item: Item, cost: Int, product: Item) { + val coins = Item(Items.COINS_995, cost) + if (player.inventory.containsItem(coins) && player.inventory.containsItem(item)) { + player.inventory.remove(item, coins) + player.inventory.add(product) + player.sendMessage("You repair your ${product.name.toLowerCase()} for $cost.") + } else { + player.sendMessage("You can't afford that.") + } + } + + override fun getIds(): IntArray { + return intArrayOf(58824213) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/decoration/workshop/ClockmakersBenchPlugin.java b/Server/src/main/content/global/skill/construction/decoration/workshop/ClockmakersBenchPlugin.java new file mode 100644 index 0000000..410f1a4 --- /dev/null +++ b/Server/src/main/content/global/skill/construction/decoration/workshop/ClockmakersBenchPlugin.java @@ -0,0 +1,236 @@ +package content.global.skill.construction.decoration.workshop; + + +import content.global.skill.construction.BuildingUtils; +import content.global.skill.construction.Decoration; +import core.cache.def.impl.ItemDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.game.dialogue.DialogueInterpreter; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.skill.Skills; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.plugin.ClassScanner; +import org.rs09.consts.Items; + +/** + * Handles the clockmakers bench in the workshop + * ClockmakersBenchPlugin.java + * @author Clayton Williams (hope) + * @date Oct 29, 2015 + */ +@Initializable +public class ClockmakersBenchPlugin extends OptionHandler { + + /** + * Stores data for things created by the clockmakers bench + * ClockmakersBenchPlugin.java + * @author Clayton Williams + * @date Oct 30, 2015 + */ + private enum Craftable { + + TOY_HORSEY(2520, 10, BuildingUtils.PLANK), + CLOCKWORK(8792, 8, new Item(Items.STEEL_BAR_2353)), + TOY_SOLDIER(7759, 13, BuildingUtils.PLANK, new Item(Items.CLOCKWORK_8792)), + TOY_DOLL(7763, 18, BuildingUtils.PLANK, new Item(Items.CLOCKWORK_8792)), + TOY_MOUSE(7767, 33, BuildingUtils.PLANK, new Item(Items.CLOCKWORK_8792)), + TOY_CAT(7771, 85, BuildingUtils.PLANK, new Item(Items.CLOCKWORK_8792)), + WATCH(2575, 28, new Item(Items.CLOCKWORK_8792), new Item(Items.STEEL_BAR_2353)), + SEXTANT(2574, 23, new Item(Items.STEEL_BAR_2353)); + + /** + * The itemId to give after making this + */ + private int itemId; + + /** + * The materials needed to make this + */ + private Item[] materials; + + /** + * The crafting level required to make this + */ + private int craftingLevel; + + /** + * Craftable + * @param itemId + * @param craftingLevel + * @param materials + */ + Craftable(int itemId, int craftingLevel, Item... materials) { + this.itemId = itemId; + this.craftingLevel = craftingLevel; + this.materials = materials; + } + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(13709).getHandlers().put("option:craft", this); + SceneryDefinition.forId(13710).getHandlers().put("option:craft", this); + SceneryDefinition.forId(13711).getHandlers().put("option:craft", this); + SceneryDefinition.forId(13712).getHandlers().put("option:craft", this); + ClassScanner.definePlugin(new ClockmakerBenchDialogue()); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + player.getDialogueInterpreter().open(DialogueInterpreter.getDialogueKey("con:clockbench"), node.asScenery()); + return true; + } + + /** + * Handles the dialogue for clock bench + * @author Clayton Williams + * @date Oct 29, 2015 + */ + private final class ClockmakerBenchDialogue extends DialoguePlugin { + + /** + * The crafting table decoration + */ + Decoration decoration; + + /** + * ClockmakerBenchDialogue + */ + public ClockmakerBenchDialogue() { + /** + * Empty + */ + } + + /** + * ClockmakerBenchDialogue + * @param player + */ + public ClockmakerBenchDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new ClockmakerBenchDialogue(player); + } + + @Override + public boolean open(Object... args) { + Scenery object = (Scenery) args[0]; + decoration = Decoration.forObjectId(object.getId()); + if (decoration != null) { + switch (decoration) { + case CRAFTING_TABLE_1: + interpreter.sendOptions("Select an Option", "Toy Horsey", "Nevermind"); + break; + case CRAFTING_TABLE_2: + interpreter.sendOptions("Select an Option", "Toy Horsey", "Clockwork Mechanism"); + break; + case CRAFTING_TABLE_3: + interpreter.sendOptions("Select an Option", "Toy Horsey", "Clockwork Mechanism", "Clockwork Devices"); + break; + case CRAFTING_TABLE_4: + interpreter.sendOptions("Select an Option", "Toy Horsey", "Clockwork Mechanism", "Clockwork Devices", "Watch", "Sextant"); + break; + default: + break; + } + } + stage = 1; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 1: + switch (buttonId) { + case 1: + case 2: + if (decoration == Decoration.CRAFTING_TABLE_1 && buttonId == 2) { + end(); + return true; + } + craftItem(buttonId == 1 ? Craftable.TOY_HORSEY : Craftable.CLOCKWORK); + stage = 3; + break; + case 3: + if (decoration == Decoration.CRAFTING_TABLE_3) { + interpreter.sendOptions("Select an Option", "Clockwork Soldier", "Clockwork Doll"); + } else if (decoration == Decoration.CRAFTING_TABLE_4) { + interpreter.sendOptions("Select an Option", "Clockwork Soldier", "Clockwork Doll", "Clockwork Mouse", "Clockwork Cat"); + } + stage = 2; + break; + case 4: + case 5: + craftItem(buttonId == 4 ? Craftable.WATCH : Craftable.SEXTANT); + stage = 3; + break; + } + break; + case 2: + switch (buttonId) { + case 1: + craftItem(Craftable.TOY_SOLDIER); + break; + case 2: + craftItem(Craftable.TOY_DOLL); + break; + case 3: + craftItem(Craftable.TOY_MOUSE); + break; + case 4: + craftItem(Craftable.TOY_CAT); + break; + } + stage = 3; + break; + case 3: + end(); + break; + } + return true; + } + + /** + * Attempts to craft an item + * @param c - the craftable to make + */ + private void craftItem(Craftable c) { + if (c != null) { + if (player.getSkills().getLevel(Skills.CRAFTING) < c.craftingLevel) { + interpreter.sendDialogue("You need level " + c.craftingLevel + " crafting to make that."); + return; + } + for (Item n : c.materials) { + if (!player.getInventory().containsItem(n)) { + interpreter.sendDialogue("You need a " + ItemDefinition.forId(n.getId()).getName() + " to make that!"); + return; + } + } + for (Item n : c.materials) { + n.setAmount(1); + player.getInventory().remove(n); + } + player.getSkills().addExperience(Skills.CRAFTING, 15); + player.getInventory().add(new Item(c.itemId, 1)); + player.animate(BuildingUtils.BUILD_MID_ANIM); + interpreter.sendDialogue("You made a " + ItemDefinition.forId(c.itemId).getName() + "!"); + } + } + + @Override + public int[] getIds() { + return new int[] { DialogueInterpreter.getDialogueKey("con:clockbench") }; + } + } +} diff --git a/Server/src/main/content/global/skill/construction/decoration/workshop/ToolsPlugin.java b/Server/src/main/content/global/skill/construction/decoration/workshop/ToolsPlugin.java new file mode 100644 index 0000000..2341c3a --- /dev/null +++ b/Server/src/main/content/global/skill/construction/decoration/workshop/ToolsPlugin.java @@ -0,0 +1,171 @@ +package content.global.skill.construction.decoration.workshop; + + +import core.cache.def.impl.ItemDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.plugin.Initializable; +import core.game.dialogue.DialogueInterpreter; +import core.game.dialogue.DialoguePlugin; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.plugin.Plugin; +import core.plugin.ClassScanner; + +import java.util.ArrayList; +import java.util.List; + +/** + * Handles the 5 types of tool stores + * ToolsPlugin.java + * @author Clayton Williams + * @date Oct 29, 2015 + * + */ +@Initializable +public class ToolsPlugin extends OptionHandler { + + /** + * The different tool stores + * @author Clayton Williams + * @date Oct 29, 2015 + */ + private enum ToolStore { + + TOOLSTORE_1(13699, 8794, 1755, 2347, 1735), + TOOLSTORE_2(13700, 1925, 952, 590), + TOOLSTORE_3(13701, 1757, 1785, 1733), + TOOLSTORE_4(13702, 1595, 1597, 1592, 1599, 5523), + TOOLSTORE_5(13703, 5341, 952, 676, 5343, 5331); + + /** + * The object id of the tool store + */ + private int objectId; + + /** + * The tools included + */ + private int[] tools; + + /** + * ToolStore + * @param objectId + * @param tools + */ + ToolStore(int objectId, int... tools) { + this.objectId = objectId; + this.tools = tools; + } + + /** + * Gets the toolstore from an object id + * @param objectId - the object id + * @return + */ + private static ToolStore forId(int objectId) { + for (ToolStore t : ToolStore.values()) { + if (t.objectId == objectId) { + return t; + } + } + return null; + } + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (ToolStore t : ToolStore.values()) { + SceneryDefinition.forId(t.objectId).getHandlers().put("option:search", this); + } + ClassScanner.definePlugin(new ToolDialogue()); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + Scenery object = node.asScenery(); + ToolStore ts = ToolStore.forId(object.getId()); + if (ts != null) { + player.getDialogueInterpreter().open(DialogueInterpreter.getDialogueKey("con:tools"), ts); + } + return true; + } + + /** + * Handles the tool dialogue + * @author Clayton Williams + * @date Oct 29, 2015 + */ + private final class ToolDialogue extends DialoguePlugin { + + /** + * The tool store being used + */ + private ToolStore toolStore; + + /** + * ToolDialogue + */ + private ToolDialogue() { + /** + * Empty + */ + } + + /** + * ToolDialogue + * @param player + */ + public ToolDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new ToolDialogue(player); + } + + @Override + public boolean open(Object... args) { + toolStore = (ToolStore) args[0]; + List itemNames = new ArrayList(); + for(int itemId : toolStore.tools) { + ItemDefinition n = ItemDefinition.forId(itemId); + itemNames.add(n.getName()); + } + interpreter.sendOptions("Select a Tool", itemNames.toArray(new String[itemNames.size()])); + stage = 1; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 1: + Item item = new Item(toolStore.tools[buttonId - 1], 1); + if (player.getInventory().freeSlots() <= 0) { + interpreter.sendDialogue("You have no space in your inventory."); + stage = 2; + return true; + } + player.getInventory().add(item); + end(); + return true; + case 2: + end(); + return true; + } + return false; + } + + @Override + public int[] getIds() { + return new int[] { DialogueInterpreter.getDialogueKey("con:tools") }; + } + + } + +} diff --git a/Server/src/main/content/global/skill/construction/npc/HouseServantDialogue.java b/Server/src/main/content/global/skill/construction/npc/HouseServantDialogue.java new file mode 100644 index 0000000..ddb967e --- /dev/null +++ b/Server/src/main/content/global/skill/construction/npc/HouseServantDialogue.java @@ -0,0 +1,569 @@ +package content.global.skill.construction.npc; + + +import content.global.skill.construction.HouseManager; +import content.global.skill.construction.ServantType; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.impl.PulseType; +import core.game.node.entity.skill.Skills; +import content.global.skill.construction.Servant; +import core.game.interaction.MovementPulse; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.IronmanMode; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.path.Pathfinder; +import content.global.handlers.iface.SawmillPlankInterface.Plank; +import org.rs09.consts.Items; + +/** + * Handles the Servant's dialogues. + * @author Splinter + * @date 9/23/2015 + * @version 0.98 (TODO: Missing a few dialogues) + */ +public class HouseServantDialogue extends DialoguePlugin { + + /** + * If using the sawmill. + */ + private boolean sawmill; + + /** + * The logs + */ + private Item logs; + + /** + * Constructs a new {@code ServantDialogue} {@code Object}. + */ + public HouseServantDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code ServantDialogue} {@code Object}. + * @param player the player. + */ + public HouseServantDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new HouseServantDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + HouseManager manager = player.getHouseManager(); + boolean inHouse = manager.isInHouse(player); + if (args.length > 1) { //Parse options from our "use-with" handler + sawmill = (boolean) args[1]; + logs = (Item) args[2]; + } + if (player.getIronmanManager().checkRestriction(IronmanMode.ULTIMATE)) { + player.sendMessage("Ultimate Ironmen cannot hire butlers."); + return true; + } + if (!manager.hasHouse() && inHouse) { + interpreter.sendDialogues(npc, npc.getId() == 4243 ? FacialExpression.HALF_GUILTY : null, "You don't have a house that I can work in.", "I'll be waiting here if you decide to buy a house."); + stage = 100; + return true; + } + if (!manager.hasServant()) { + ServantType type = ServantType.forId(npc.getId()); + if(player.getSkills().getLevel(Skills.CONSTRUCTION) >= type.getLevel()){ + interpreter.sendDialogues(npc, npc.getId() == 4243 ? FacialExpression.HALF_GUILTY : null, "You're not aristocracy, but I suppose you'd do. Do you", "want a good cook for " + type.getCost() + " coins?"); + stage = 0; + return true; + } + interpreter.sendDialogues(npc, npc.getId() == 4243 ? FacialExpression.HALF_GUILTY : null, "You need a Construction level of " + type.getLevel() + " and you must not", "currently have another person working for you", "in order to hire me."); + stage = 100; + return true; + } else { + Servant servant = manager.getServant(); + if(servant.getItem() == null){ + servant.setItem(new Item(0, 0)); + } + if (inHouse) { + follow(player, servant); + if (sawmill) { + interpreter.sendDialogues(servant, servant.getId() == 4243 ? FacialExpression.HALF_GUILTY : null, "Very well, I will take these logs to the mill and", "have them converted into planks."); + stage = 110; + return true; + } + if (servant.getItem().getAmount() > 0) { + if(player.getInventory().freeSlots() < 1){ + interpreter.sendDialogues(servant, servant.getId() == 4243 ? FacialExpression.HALF_GUILTY : null, "I have returned with what you asked me to", "retrieve. As I see your inventory is full, I shall wait", "with these " + servant.getItem().getAmount()+" items until you are ready."); + stage = 100; + return true; + } + interpreter.sendDialogues(servant, servant.getId() == 4243 ? FacialExpression.HALF_GUILTY : null, "I have returned with what you asked me to", "retrieve."); + stage = 150; + return true; + } + interpreter.sendDialogues(servant, servant.getId() == 4243 ? FacialExpression.HALF_GUILTY : null, "Yes, " + (player.getAppearance().isMale() ? "sir" : "ma'am") + "?", "You have " + (8 - servant.getUses()) + " uses of my services remaining."); + stage = 50; + } else if(npc.getId() != servant.getId()){ + interpreter.sendDialogues(npc, npc.getId() == 4243 ? FacialExpression.HALF_GUILTY : null, "You already have someone working for you.", "Fire them first before hiring me."); + stage = 100; + } + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + HouseManager manager = player.getHouseManager(); + Servant servant = manager.getServant(); + ServantType type = ServantType.forId(npc.getId()); + switch(stage) { + case 0: + options("What can you do?", "Tell me about your previous jobs.", "You're hired!"); + stage++; + break; + case 1: + switch(buttonId) { + case 1: //TODO: + break; + case 2: //TODO: + break; + case 3: + player("You're hired!"); + stage = 2; + break; + } + break; + case 2: + interpreter.sendDialogues(npc, npc.getId() == 4243 ? FacialExpression.HALF_GUILTY : null, "Alright, " + (player.getAppearance().isMale() ? "sir" : "ma'am") + ". I can start work immediately."); + stage++; + break; + case 3: + if (type != null && player.getInventory().getAmount(995) >= type.getCost() && player.getInventory().remove(new Item(Items.COINS_995, type.getCost()))) { + manager.setServant(new Servant(type)); + interpreter.sendDialogue("The servant heads to your house."); + stage = 100; + break; + } + interpreter.sendDialogue("You don't have enough money to pay the servant's hiring fee."); + stage = 100; + break; + case 50: + options("Go to the bank/sawmill...", "Misc...", "Stop following me.", "You're fired!"); + stage++; + break; + case 51: + type = servant.getType(); + switch(buttonId) { + case 1: + options(!servant.getAttributes().containsKey("con:lastfetch") ? "Repeat last fetch task" : "Fetch another " + (type.getCapacity() + " x " + ((Item) servant.getAttribute("con:lastfetch")).getName().toLowerCase()) + " (" + (servant.getAttribute("con:lastfetchtype")) + ")", "Go to the bank", "Go to the sawmill", "Pay wages (" + servant.getUses()+"/8 uses)"); + stage++; + break; + case 2: + options("Greet guests", "Cook me something"); + stage = 56; + break; + case 3: + player("Stop following me."); + if (servant.getPulseManager().isMovingPulse()) { + servant.getPulseManager().clear(PulseType.STANDARD); + } + stage = 100; + break; + case 4: + player("You're fired!"); + stage = 75; + break; + } + break; + case 52: + switch(buttonId){ + case 1: + if (!servant.getAttributes().containsKey("con:lastfetch")) { + interpreter.sendDialogues(servant, servant.getId() == 4243 ? FacialExpression.HALF_GUILTY : null, "I haven't recently fetched anything from the bank or", "sawmill for you."); + stage = 50; + break; + } else { + if (servant.getAttribute("con:lastfetchtype") == "bank") { + bankFetch(player, (Item) servant.getAttribute("con:lastfetch")); + return true; + } + end(); + sawmillRun(player, (Item) servant.getAttribute("con:lastfetch")); + } + break; + case 2: + options("Planks", "Oak planks", "Teak planks", "Mahogany planks", "More options"); + stage = 60; + break; + case 3: + if (type == ServantType.MAID || type == ServantType.RICK) { + interpreter.sendDialogues(servant, servant.getId() == 4243 ? FacialExpression.HALF_GUILTY : null, "I am unable to travel to the sawmill for you."); + stage = 100; + break; + } + interpreter.sendDialogues(servant, servant.getId() == 4243 ? FacialExpression.HALF_GUILTY : null, "Hand the logs to me and I will take them to the", "sawmill for you."); + stage = 100; + break; + case 4: + stage = 100; + if (servant.getUses() < 1) { + interpreter.sendDialogues(servant, servant.getId() == 4243 ? FacialExpression.HALF_GUILTY : null, "You have no need to pay me yet, I haven't performed", "any of my services for you."); + break; + } + if (!player.getInventory().containsItem(new Item(Items.COINS_995, type.getCost()))) { + interpreter.sendDialogues(servant, servant.getId() == 4243 ? FacialExpression.HALF_GUILTY : null, "Thanks for the kind gesture, but you don't have enough", "money to pay me. I require " + type.getCost() + " coins every eight uses", "of my services."); + break; + } + if (player.getInventory().remove(new Item(Items.COINS_995, type.getCost()))) { + interpreter.sendDialogues(servant, servant.getId() == 4243 ? FacialExpression.HALF_GUILTY : null, "Thank you very much."); + servant.setUses(0); + } + break; + } + break; + case 56: + switch(buttonId) { + case 1: + servant.setGreet(!servant.isGreet()); + player("Please " + (servant.isGreet() ? "greet" : "do not greet") + " all new guests upon arrival."); + stage++; + break; + case 2: + if (type.getFood() == null) { + interpreter.sendDialogues(servant, servant.getId() == 4243 ? FacialExpression.HALF_GUILTY : null, "I don't know any recipes."); + stage = 100; + break; + } + if (type.getFood().length > 1) { + options(type.getFood()[0].getName(), type.getFood()[1].getName(), "Nevermind."); + stage = 58; + } else { + options(type.getFood()[0].getName(), "Nevermind."); + stage = 59; + } + break; + } + break; + case 57: + interpreter.sendDialogues(servant, servant.getId() == 4243 ? FacialExpression.HALF_GUILTY : null, "Whatever you command."); + stage = 50; + break; + case 58: + if (player.getInventory().freeSlots() < 1) { + interpreter.sendDialogues(servant, servant.getId() == 4243 ? FacialExpression.HALF_GUILTY : null, "I would love to share my fine cooking with you,", "but your hands are currently full."); + stage = 100; + break; + } + if (!prereqs(player, null, false)) { + end(); + return true; + } + switch(buttonId) { + case 1: + player.getInventory().add(type.getFood()[0]); + stage = 50; + break; + case 2: + player.getInventory().add(type.getFood()[1]); + stage = 50; + break; + case 3: + player("Nevermind."); + stage = 100; + return true; + } + servant.setUses(servant.getUses() + 1); + interpreter.sendDialogues(servant, servant.getId() == 4243 ? FacialExpression.HALF_GUILTY : null, "Luckily for you, I already have some made. Here you", "go."); + stage = 50; + break; + case 59: + if (player.getInventory().freeSlots() < 1) { + interpreter.sendDialogues(servant, servant.getId() == 4243 ? FacialExpression.HALF_GUILTY : null, "I would love to share my fine cooking with", "you, but you have no space to take anything."); + stage = 50; + break; + } + if (!prereqs(player, null, false)) { + end(); + return true; + } + switch(buttonId) { + case 1: + player.getInventory().add(type.getFood()[0]); + stage = 100; + break; + case 2: + player("Nevermind."); + stage = 100; + return true; + } + servant.setUses(servant.getUses() + 1); + interpreter.sendDialogues(servant, servant.getId() == 4243 ? FacialExpression.HALF_GUILTY : null, "Luckily for you, I already have some made. Here you", "go."); + stage = 100; + break; + case 60: + switch(buttonId) { + case 1: //planks + bankFetch(player, new Item(Items.PLANK_960)); + stage = 100; + break; + case 2: //oak + bankFetch(player, new Item(Items.OAK_PLANK_8778)); + stage = 100; + break; + case 3: //teak + bankFetch(player, new Item(Items.TEAK_PLANK_8780)); + break; + case 4: //mahog + bankFetch(player, new Item(Items.MAHOGANY_PLANK_8782)); + break; + case 5: + options("Soft clay", "Limestone bricks", "Steel bars", "Cloth", "More options"); + stage++; + break; + } + break; + case 61: + switch(buttonId) { + case 1: //clay + bankFetch(player, new Item(Items.SOFT_CLAY_1761)); + break; + case 2: //lime + bankFetch(player, new Item(Items.LIMESTONE_BRICK_3420)); + break; + case 3: //steel bars + bankFetch(player, new Item(Items.STEEL_BAR_2353)); + break; + case 4: //cloth + bankFetch(player, new Item(Items.BOLT_OF_CLOTH_8790)); + break; + case 5: + options("Gold leaves", "Marble blocks", "Magic stones"); + stage++; + break; + } + break; + case 62: + switch(buttonId) { + case 1: //leaves + bankFetch(player, new Item(Items.GOLD_LEAF_4692)); + break; + case 2: //marble + bankFetch(player, new Item(Items.MARBLE_BLOCK_8786)); + break; + case 3: //magic stones + bankFetch(player, new Item(Items.MAGIC_STONE_8788)); + break; + } + break; + case 75: + interpreter.sendDialogues(servant, servant.getId() == 4243 ? FacialExpression.HALF_GUILTY : null, "Very well. I will return to the Guild of the Servants", "in Ardougne if you wish to re-hire me."); + stage++; + break; + case 76: + end(); + servant.getItem().setAmount(0); + servant.setUses(0); + servant.clear(); + servant.setLocation(new Location(0, 0)); + manager.setServant(null); + break; + case 100: + end(); + break; + case 110: + end(); + sawmillRun(player, logs); + break; + case 150: + if (servant.getItem()== null) { + end(); + return true; + } + int amtLeft = servant.getItem().getAmount(); + boolean flag = false; + if (amtLeft < 1 || servant.getItem() == null) { + interpreter.sendDialogues(servant, servant.getId() == 4243 ? FacialExpression.HALF_GUILTY : null, "I don't have any items left."); + stage = 100; + break; + } + if (amtLeft > player.getInventory().freeSlots()) { + amtLeft = player.getInventory().freeSlots(); + flag = true; + } + servant.getItem().setAmount(servant.getItem().getAmount() - amtLeft); + player.getInventory().add(new Item(servant.getItem().getId(), amtLeft)); + if (flag) { + interpreter.sendDialogues(servant, servant.getId() == 4243 ? FacialExpression.HALF_GUILTY : null, "I still have " + servant.getItem().getAmount() + " left for you to take from me."); + stage = 100; + } else{ + end(); + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 4235, 4237, 4239, 4241, 4243 }; + } + + /** + * Checks the pre-reqs for a sawmill run or a bank run. + * @param player + * @param item + * @return true or false if they have the requirements to use the servant. + */ + private boolean prereqs(final Player player, final Item item, boolean sawmill) { + HouseManager manager = player.getHouseManager(); + Servant servant = manager.getServant(); + if (!sawmill && player.getInventory().freeSlots() < 1) { + interpreter.sendDialogues(servant, servant.getId() == 4243 ? FacialExpression.HALF_GUILTY : null, "You don't have any space in your inventory."); + stage = 100; + return false; + } + if (servant.getUses() >= 8) { + player.sendMessage("The servant has left your service due to a lack of payment."); + servant.getItem().setAmount(0); + servant.setUses(0); + servant.clear(); + servant.setLocation(new Location(0, 0)); + manager.setServant(null); + end(); + return false; + } + if (servant.getItem().getAmount() > 0) { + interpreter.sendDialogues(servant, servant.getId() == 4243 ? FacialExpression.HALF_GUILTY : null, "You can't send me off again, I'm still holding some of", "your previous items."); + return false; + } + return true; + } + + /** + * Goes to the sawmill. + * @param player + * @param item + */ + private void sawmillRun(final Player player, final Item item) { + HouseManager manager = player.getHouseManager(); + final Servant servant = manager.getServant(); + final ServantType type = manager.getServant().getType(); + if (servant == null || item == null || !prereqs(player, item, true)) { + return; + } + if (type == ServantType.MAID || type == ServantType.RICK) { + interpreter.sendDialogues(servant, servant.getId() == 4243 ? FacialExpression.HALF_GUILTY : null, "I am unable to take planks to the sawmill."); + return; + } + int amt = player.getInventory().getAmount(item); + if (amt < 1) { + interpreter.sendDialogues(servant, servant.getId() == 4243 ? FacialExpression.HALF_GUILTY : null, "You don't have any more of that type of log."); + return; + } + for (Plank plank : Plank.values()) { + if (plank.getLog().getId() == item.getId()) { + if (amt > type.getCapacity()) { + amt = type.getCapacity(); + } + if (!player.getInventory().contains(995, plank.getPrice() * amt)) { + interpreter.sendDialogues(servant, servant.getId() == 4243 ? FacialExpression.HALF_GUILTY : null, "You don't have enough coins for me to do that.", "I can hold " + type.getCapacity() + " logs and each of this type of log", "costs " + plank.getPrice() + " coins each to convert into plank form."); + return; + } + end(); + if (player.getInventory().remove(new Item(item.getId(), amt)) && player.getInventory().remove(new Item(Items.COINS_995, amt * plank.getPrice()))) { + manager.getServant().setItem(new Item(plank.getPlank().getId(), amt)); + servant.setInvisible(true); + servant.getLocks().lockMovement(100); + GameWorld.getPulser().submit(new Pulse((int) (type.getTimer() / 0.6)){ + + @Override + public boolean pulse() { + servant.setInvisible(false); + servant.getLocks().unlockMovement(); + servant.setAttribute("con:lastfetch", new Item(item.getId(), 1)); + servant.setAttribute("con:lastfetchtype", "sawmill"); + interpreter.open(servant.getId(), servant); + return true; + } + }); + } + break; + } + } + } + + /** + * Gets items from the player's bank. + * @param player + * @param item + */ + private void bankFetch(final Player player, final Item item) { + final HouseManager manager = player.getHouseManager(); + final Servant servant = manager.getServant(); + final ServantType type = manager.getServant().getType(); + if (servant == null || item == null || !prereqs(player, item, false)) { + return; + } + if (!player.getBank().containsItem(item)) { + interpreter.sendDialogues(servant, servant.getId() == 4243 ? FacialExpression.HALF_GUILTY : null, "You don't seem to have any of those in the bank."); + stage = 100; + return; + } + end(); + servant.setInvisible(true); + servant.getLocks().lockMovement(100); + GameWorld.getPulser().submit(new Pulse((int) (type.getTimer() / 0.6)) { + + @Override + public boolean pulse() { + if (player == null || player.getHouseManager().getHouseRegion() != player.getViewport().getRegion()) { //TODO: Check if in dungeon? + return true; + } + int amt = player.getBank().getAmount(item.getId()); + if (amt < 1) { + return true; + } + if (amt > type.getCapacity()) { + amt = type.getCapacity(); + } + servant.setInvisible(false); + servant.getLocks().unlockMovement(); + Item fetch = new Item(item.getId(), amt); + if (player.getBank().remove(fetch)) { + manager.getServant().setItem(fetch); + interpreter.open(servant.getId(), servant); + } + servant.setAttribute("con:lastfetch", new Item(fetch.getId(), 1)); + servant.setAttribute("con:lastfetchtype", "bank"); + manager.getServant().setUses(manager.getServant().getUses() + 1); + follow(player, servant); + return true; + } + + }); + } + + /** + * Follows the person who is talking to them. + * @param player + * @param npc + */ + private void follow(Player player, NPC npc) { + npc.getPulseManager().run(new MovementPulse(npc, player, Pathfinder.SMART) { + + @Override + public boolean pulse() { + return false; + } + }, PulseType.STANDARD); + } +} diff --git a/Server/src/main/content/global/skill/construction/npc/HouseServantPlugin.java b/Server/src/main/content/global/skill/construction/npc/HouseServantPlugin.java new file mode 100644 index 0000000..68af649 --- /dev/null +++ b/Server/src/main/content/global/skill/construction/npc/HouseServantPlugin.java @@ -0,0 +1,55 @@ +package content.global.skill.construction.npc; + + +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.plugin.ClassScanner; + +/** + * Handles interaction with the house servant. + * @author Splinter + * @date 9/24/2015 + * @version 0.1 + * + * @see {@link HouseServantDialogue} + * For the other associated classes that deal with house servants. + * + */ +@Initializable +public class HouseServantPlugin extends UseWithHandler { + + /** + * The item IDS to use. + */ + final static int[] IDS = { 1511, 1521, 6333, 6332 }; + + /** + * Constructs a new {@code HouseServantPlugin} {@code Object}. + */ + public HouseServantPlugin() { + super(IDS); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(4235, NPC_TYPE, this); + addHandler(4237, NPC_TYPE, this); + addHandler(4239, NPC_TYPE, this); + addHandler(4241, NPC_TYPE, this); + addHandler(4243, NPC_TYPE, this); + ClassScanner.definePlugin(new HouseServantDialogue()); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + if (event.getUsedItem() == null || event.getUsedWith() == null) { + return true; + } + event.getPlayer().getDialogueInterpreter().open(event.getUsedWith().asNpc().getId(), event.getUsedWith().asNpc(), true, event.getUsedItem()); + return true; + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/construction/npc/StonemasonPlugin.java b/Server/src/main/content/global/skill/construction/npc/StonemasonPlugin.java new file mode 100644 index 0000000..b83bb59 --- /dev/null +++ b/Server/src/main/content/global/skill/construction/npc/StonemasonPlugin.java @@ -0,0 +1,76 @@ +package content.global.skill.construction.npc; + +import core.cache.def.impl.ItemDefinition; +import core.cache.def.impl.NPCDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Handles the Keldagrim Stonemason. + * @author Splinter + */ +@Initializable +public class StonemasonPlugin extends OptionHandler { +/* + *//** + * The store that sells supplies. + *//* + private static final SupplyStore STORE = new SupplyStore();*/ + + @Override + public Plugin newInstance(Object arg) throws Throwable { + NPCDefinition.forId(4248).getHandlers().put("option:trade", this); + NPCDefinition.forId(4248).getHandlers().put("option:talk-to", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + switch (option) { + case "trade": + case "talk-to": + break; + } + return true; + } +/* + *//** + * Stonemason's store. + * @author Splinter + *//* + public static class SupplyStore extends Shop { + + *//** + * Constructs a new {@Code SupplyStore} {@Code Object} + *//* + public SupplyStore() { + super("Keldagrim Stonemason", new Item[] { new Item(Items.LIMESTONE_BRICK_3420, 1000), new Item(Items.MARBLE_BLOCK_8786, 20), new Item(Items.GOLD_LEAF_8784, 20), new Item(Items.MAGIC_STONE_8788, 10) }, false); + } + + @Override + public boolean canSell(Player player, Item item, ItemDefinition def) { + player.sendMessage("You cannot sell items to this store."); + return false; + } + + @Override + public int getBuyPrice(Item item, Player player) { + switch (item.getId()) { + case 3420: + return 26; + case 8786: + return 325_000; + case 8784: + return 130_000; + case 8788: + return 975_000; + } + return -1; + } + }*/ + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/cooking/CakeMakingPlugin.java b/Server/src/main/content/global/skill/cooking/CakeMakingPlugin.java new file mode 100644 index 0000000..084abf4 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/CakeMakingPlugin.java @@ -0,0 +1,69 @@ +package content.global.skill.cooking; + +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the plugin used to make a cake. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class CakeMakingPlugin extends UseWithHandler { + + /** + * Represents the bucket of milk item. + */ + private static final Item BUCKET_OF_MILK = new Item(1927); + + /** + * Represents the egg item. + */ + private static final Item EGG = new Item(1944); + + /** + * Represents the cake tin item. + */ + private static final Item CAKE_TIN = new Item(1887); + + /** + * Represents the pot of flour item. + */ + private static final Item POT_OF_FLOUR = new Item(1933); + + /** + * Represents the uncooked cake item. + */ + private static final Item UNCOOKED_CAKE = new Item(1889); + + /** + * Constructs a new {@code CakeMakingPlugin} {@code Object}. + */ + public CakeMakingPlugin() { + super(1933); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(1887, ITEM_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + if (event.getUsedItem().getId() == 1887 && ((Item) event.getUsedWith()).getId() == 1933 || event.getUsedWith().getName().equalsIgnoreCase("cake tin") && ((Item) event.getUsedItem()).getName().equalsIgnoreCase("pot of flour")) { + if (event.getPlayer().getInventory().contains(1933, 1) && event.getPlayer().getInventory().contains(1927, 1) && event.getPlayer().getInventory().contains(1944, 1)) { + if (event.getPlayer().getInventory().remove(BUCKET_OF_MILK, EGG, CAKE_TIN, POT_OF_FLOUR)) { + event.getPlayer().getInventory().add(UNCOOKED_CAKE); + event.getPlayer().getPacketDispatch().sendMessage("You mix the milk, flour and egg together to make a raw cake mix."); + return true; + } + } + } + return false; + } + +} diff --git a/Server/src/main/content/global/skill/cooking/ChocolateBarCutter.kt b/Server/src/main/content/global/skill/cooking/ChocolateBarCutter.kt new file mode 100644 index 0000000..e2a5fc1 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/ChocolateBarCutter.kt @@ -0,0 +1,34 @@ +package content.global.skill.cooking + +import core.game.interaction.NodeUsageEvent +import core.game.interaction.UseWithHandler +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.game.world.update.flag.context.Animation +import core.plugin.Initializable +import core.plugin.Plugin +import org.rs09.consts.Items + +@Initializable +class ChocolateBarCutter : UseWithHandler(946){ + override fun newInstance(arg: Any?): Plugin { + addHandler(1973, ITEM_TYPE, this) + return this + } + + override fun handle(event: NodeUsageEvent?): Boolean { + event ?: return false + val player = event.player + player.pulseManager.run(object : Pulse(1){ + val cut_animation = Animation(1989) + override fun pulse(): Boolean { + super.setDelay(4) + val amount = player.inventory.getAmount(Items.CHOCOLATE_BAR_1973) + if(amount > 0) player.inventory.remove(Item(1973)).also { player.animator.animate(cut_animation); player.inventory.add(Item(1975)) } + return amount <= 0 + } + }) + return true + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/cooking/CoconutMakePlugin.java b/Server/src/main/content/global/skill/cooking/CoconutMakePlugin.java new file mode 100644 index 0000000..7520ff1 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/CoconutMakePlugin.java @@ -0,0 +1,56 @@ +package content.global.skill.cooking; + +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the plugin used to make a coconut. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class CoconutMakePlugin extends UseWithHandler { + + /** + * Represents the items related to coconut making plugin. + */ + private static final Item[] ITEMS = new Item[] { new Item(5974, 1), new Item(5976, 1), new Item(229), new Item(5935, 1), new Item(5978) }; + + /** + * Constructs a new {@code CoconutMakePlugin} {@code Object}. + */ + public CoconutMakePlugin() { + super(5974, 5976); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(2347, ITEM_TYPE, this); + addHandler(229, ITEM_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + final Item usedWith = (Item) event.getUsedWith(); + if (usedWith.getId() == 5974 && event.getUsedItem().getId() == 2347 || usedWith.getId() == 2347 && event.getUsedItem().getId() == 5974) { + player.getInventory().remove(ITEMS[0]); + player.getInventory().add(ITEMS[1]); + player.getPacketDispatch().sendMessage("You crush the coconut with a hammer."); + } + if (usedWith.getId() == 5976 && event.getUsedItem().getId() == 229 || usedWith.getId() == 229 && event.getUsedItem().getId() == 5976) { + player.getInventory().remove(ITEMS[1]); + player.getInventory().remove(ITEMS[2]); + player.getInventory().add(ITEMS[3]); + player.getInventory().add(ITEMS[4]); + player.getPacketDispatch().sendMessage("You overturn the coconut into a vial."); + } + return true; + } + +} diff --git a/Server/src/main/content/global/skill/cooking/CookableItems.java b/Server/src/main/content/global/skill/cooking/CookableItems.java new file mode 100644 index 0000000..cea0f35 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/CookableItems.java @@ -0,0 +1,172 @@ +package content.global.skill.cooking; + +import org.rs09.consts.Items; +import core.game.node.item.Item; + +import java.util.HashMap; + +public enum CookableItems { + // meats + CHICKEN(2140, 2138, 2144, 1, 30, 128, 512, 128, 512), + UGTHANKI(2140, 2138, 2144, 1, 40, 40, 252, 30, 253), + RABBIT(3228, 3226, 7222, 1, 30, 128, 512, 128, 512), + CRAB(7521, 7518, 7520, 21, 100, 57, 377, 57, 377), + CHOMPY(2878, 2876, 2880, 30, 100, 200, 255, 200, 255), + JUBBLY(7568, 7566, 7570, 41, 160, 195, 250, 195, 250), // Can burn at 99 cooking. Ballpark low/high. + + // fish + CRAYFISH(13433, 13435, 13437, 1, 30, 128, 512, 128, 512), + SHRIMP(315, 317, 7954, 1, 30, 128, 512, 128, 512), + KARAMBWANJI(3151, 3150, 592, 1, 10, 200, 400, 200, 400), + SARDINE(325, 327, 369, 1, 40, 118, 492, 118, 492), + ANCHOVIES(319, 321, 323, 1, 30, 128, 512, 128, 512), + HERRING(347, 345, 357, 5, 50, 108, 472, 108, 472), + MACKEREL(355, 353, 357, 10, 60, 98, 452, 98, 452), + TROUT(333, 335, 343, 15, 70, 88, 432, 88, 432), + COD(339, 341, 343, 18, 75, 83, 422, 88, 432), + PIKE(351, 349, 343, 20, 80, 78, 412, 78, 412), + SALMON(329, 331, 343, 25, 90, 68, 392, 68, 392), + SLIMY_EEL(3381, 3379, 3383, 28, 95, 63, 382, 63, 382), + TUNA(361, 359, 367, 30, 100, 58, 372, 58, 372), + RAINBOW_FISH(10136, 10138, 10140, 35, 110, 56, 370, 56, 370), + CAVE_EEL(5003, 5001, 5002, 38, 115, 38, 332, 38, 332), + LOBSTER(379, 377, 381, 40, 120, 38, 332, 38, 332), + BASS(365, 363, 367, 43, 130, 33, 312, 33, 312), + SWORDFISH(373, 371, 375, 45, 140, 18, 292, 30, 310), + LAVA_EEL(2149, 2148, 3383, 53, 30, 256, 256, 256, 256), // never burn + MONKFISH(7946, 7944, 7948, 62, 150, 11, 275, 13, 280), + SHARK(385, 383, 387, 80, 210, 1, 202, 1, 232), + SEA_TURTLE(397, 395, 399, 82, 212, 1, 202, 1, 222), + MANTA_RAY(391, 389, 393, 91, 216, 1, 202, 1, 222), + KARAMBWAN(3144, 3142, 3146, 30, 190, 70, 255, 70, 255), + + // snails + THIN_SNAIL(3369, 3363, 3375, 12, 70, 93, 444, 93, 444), + LEAN_SNAIL(3371, 3365, 3375, 17, 80, 85, 428, 93, 444), + FAT_SNAIL(3373, 3367, 3375, 22, 95, 73, 402, 73, 402), + + // bread + BREAD(2309, 2307, 2311, 1, 40, 118, 492, 118, 492), + PITTA_BREAD(1865, 1863, 1867, 58, 40,118, 492, 118, 492), + + // cake + CAKE(1891, 1889, 1903, 40, 180, 0, 0, 38, 332), + + // beef(s) (rat, bear, cow, yak) + BEEF(2142, 2132, 2146, 1, 30, 128, 512, 128, 512), + RAT_MEAT(2142, 2134, 2146, 1, 30, 128, 512, 128, 512), + BEAR_MEAT(2142, 2136, 2146, 1, 30, 128, 512, 128, 512), + YAK_MEAT(2142, 10816, 2146, 1, 30, 128, 512, 128, 512), + + // skewered foods + SKEWER_CHOMPY(2878, 7230, 2880, 30, 100, 200, 255, 200, 255), + SKEWER_ROAST_RABBIT(7223, 7224, 7222, 16, 72, 160, 255, 160, 255), + SKEWER_ROAST_BIRD(9980, 9984, 9982, 11, 62, 155, 255, 155, 255), + SKEWER_ROAST_BEAST(9988, 9992, 9990, 21, 82.5, 180, 255, 180, 255), + + // pies + REDBERRY_PIE(2325, 2321, 2329, 10, 78, 0, 0, 98, 452), + MEAT_PIE(2327, 2319, 2329, 20, 110, 0, 0, 78, 412), + MUD_PIE(7170, 7168, 2329, 29, 128, 0, 0, 58, 372), + APPLE_PIE(2323, 2317, 2329, 30, 130, 0, 0, 58, 372), + GARDEN_PIE(7178, 7176, 2329, 34, 138, 0, 0, 48, 352), + FISH_PIE(7188, 7186, 2329, 47, 164, 0, 0, 38, 332), + ADMIRAL_PIE(7198, 7196, 2329, 70, 210, 0, 0, 15, 270), + WILD_PIE(7208, 7206, 2329, 85, 240, 0, 0, 1, 222), + SUMMER_PIE(7218, 7216, 2329, 95, 260, 0, 0, 1, 212), + + // pizzas + PIZZA_PLAIN(2289, 2287, 2305, 35, 143, 0, 0, 48, 352), + + // bowl foods + BOWL_STEW(2003, 2001, 2005, 25, 117, 68, 392, 68, 392), + BOWL_CURRY(2011, 2009, 2013, 60, 280, 38, 332, 38, 332), + BOWL_NETTLE(4239, 4237, 4239, 20, 52, 78, 412, 78, 412), + BOWL_EGG(7078, 7076, 7090, 13, 50, 0, 0, 90, 438), + BOWL_ONION(7084, 1871, 7092, 43, 60, 36, 322, 36, 322), + BOWL_MUSHROOM(7082, 7080, 7094, 46, 60, 16, 282, 16, 282), + + // vegetables + BAKED_POTATO(6701, 1942, 6699, 7, 15, 0, 0, 108, 472), + SWEETCORN(5988, 5986, 5990, 28, 104, 78, 412, 78, 412), + + // miscellaneous + RAW_OOMLIE(Items.RAW_OOMLIE_2337, 0, Items.BURNT_OOMLIE_2426, 50, 0, 0, 0, 0, 0), // always burns + OOMLIE_WRAP(Items.COOKED_OOMLIE_WRAP_2343, Items.WRAPPED_OOMLIE_2341, Items.BURNT_OOMLIE_WRAP_2345, 50, 30, 106, 450, 112, 476), + SEAWEED(Items.SEAWEED_401, 0, Items.SODA_ASH_1781, 0, 0, 0, 0, 0, 0), + + /** + * Sinew gets overridden by BEEF in this enum, due to values being looked up by the items RAW id. + * This gets corrected in {@link SinewCookingPulse} + */ + SINEW(Items.SINEW_9436, Items.RAW_BEEF_2132, Items.SINEW_9436, 0, 3, 0, 0, 0, 0); + + public final static HashMap cookingMap = new HashMap<>(); + public final static HashMap intentionalBurnMap = new HashMap<>(); + public final static HashMap gauntletValues = new HashMap<>(); + public final static HashMap lumbridgeRangeValues = new HashMap<>(); + public final int cooked, raw, burnt, level, low, high, lowRange, highRange; + public final double experience; + + CookableItems(int cooked, int raw, int burnt, int level, double experience, int low, int high, int lowRange, int highRange) { + this.cooked = cooked; + this.raw = raw; + this.burnt = burnt; + this.level = level; + this.experience = experience; + this.low = low; + this.high = high; + this.lowRange = lowRange; + this.highRange = highRange; + } + + static { + for (CookableItems item : values()) { + cookingMap.putIfAbsent(item.raw, item); + intentionalBurnMap.putIfAbsent(item.cooked, item); + } + + gauntletValues.put(Items.RAW_LOBSTER_377, new int[]{55, 368}); + gauntletValues.put(Items.RAW_SWORDFISH_371, new int[]{30, 310}); + gauntletValues.put(Items.RAW_MONKFISH_7944, new int[]{24, 290}); + gauntletValues.put(Items.RAW_SHARK_383, new int[]{15, 270}); + + lumbridgeRangeValues.put(Items.BREAD_DOUGH_2307, new int[]{128, 512}); + lumbridgeRangeValues.put(Items.RAW_BEEF_2132, new int[]{138, 532}); + lumbridgeRangeValues.put(Items.RAW_RAT_MEAT_2134, new int[]{138, 532}); + lumbridgeRangeValues.put(Items.RAW_BEAR_MEAT_2136, new int[]{138, 532}); + lumbridgeRangeValues.put(Items.RAW_YAK_MEAT_10816, new int[]{138, 532}); + lumbridgeRangeValues.put(Items.RAW_CHICKEN_2138, new int[]{138, 532}); + lumbridgeRangeValues.put(Items.RAW_SHRIMPS_317, new int[]{138, 532}); + lumbridgeRangeValues.put(Items.RAW_ANCHOVIES_321, new int[]{138, 532}); + lumbridgeRangeValues.put(Items.RAW_SARDINE_327, new int[]{128, 512}); + lumbridgeRangeValues.put(Items.RAW_HERRING_345, new int[]{118, 492}); + lumbridgeRangeValues.put(Items.RAW_MACKEREL_353, new int[]{108, 472}); + lumbridgeRangeValues.put(Items.UNCOOKED_BERRY_PIE_2321, new int[]{108, 462}); + lumbridgeRangeValues.put(Items.THIN_SNAIL_3363, new int[]{103, 464}); + lumbridgeRangeValues.put(Items.RAW_TROUT_335, new int[]{98, 452}); + lumbridgeRangeValues.put(Items.LEAN_SNAIL_3365, new int[]{95, 448}); + lumbridgeRangeValues.put(Items.RAW_COD_341, new int[]{93, 442}); + lumbridgeRangeValues.put(Items.RAW_PIKE_349, new int[]{88, 432}); + lumbridgeRangeValues.put(Items.UNCOOKED_MEAT_PIE_2319, new int[]{88, 432}); + lumbridgeRangeValues.put(Items.FAT_SNAIL_3367, new int[]{83, 422}); + lumbridgeRangeValues.put(Items.UNCOOKED_STEW_2001, new int[]{78, 412}); + lumbridgeRangeValues.put(Items.RAW_SALMON_331, new int[]{78, 402}); + } + + public static CookableItems forId(int id) { + return cookingMap.get(id); + } + + public static Item getBurnt(int id) { + return new Item(cookingMap.get(id).burnt); + } + + public static boolean intentionalBurn(int id) { + return (intentionalBurnMap.get(id) != null); + } + + public static Item getIntentionalBurn(int id) { + return new Item(intentionalBurnMap.get(id).burnt); + } +} diff --git a/Server/src/main/content/global/skill/cooking/CookingDialogue.kt b/Server/src/main/content/global/skill/cooking/CookingDialogue.kt new file mode 100644 index 0000000..a560c80 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/CookingDialogue.kt @@ -0,0 +1,134 @@ +package content.global.skill.cooking + +import core.api.* +import core.cache.def.impl.ItemDefinition +import core.game.node.scenery.Scenery +import content.global.skill.cooking.CookingRewrite.Companion.cook +import core.net.packet.PacketRepository +import core.net.packet.context.ChildPositionContext +import core.net.packet.out.RepositionChild +import org.rs09.consts.Items +import core.game.dialogue.DialogueFile +import core.tools.START_DIALOGUE + +/** + * @author Ceikry + * @author bushtail - fixing it up + * @auther Woah - for more fixing up + */ + +class CookingDialogue(vararg val args: Any) : DialogueFile(){ + var initial = 0 + var product = 0 + var `object`: Scenery? = null + var sinew = false + var itemid = 0 + override fun handle(componentID: Int, buttonID: Int) { + when(stage){ + START_DIALOGUE -> { + when (args.size) { + 2 -> { + initial = args.get(0) as Int + if (CookableItems.intentionalBurn(initial)) { // checks intentional burning + product = CookableItems.getIntentionalBurn(initial).id + } else { + product = CookableItems.forId(initial).cooked + } + `object` = args.get(1) as Scenery + } + 5 -> { + initial = args.get(0) as Int + product = args.get(1) as Int + sinew = args.get(2) as Boolean + `object` = args.get(3) as Scenery + itemid = args.get(4) as Int + if (sinew) { + options( + "Dry the meat into sinew", + "Cook the meat" + ) + stage = if (amountInInventory(player!!, initial) > 1) 100 else 101 + return + } + } + } + display() + } + + 1 -> { + end() + val amount = getAmount(buttonID) + when (amount) { + -1 -> sendInputDialogue(player!!, true, "Enter the amount:") { value -> + if (value is String) { + cook(player!!, `object`, initial, product, value.toInt()) + } else { + cook(player!!, `object`, initial, product, value as Int) + } + } + + else -> { + end() + cook(player!!, `object`, initial, product, amount) + } + } + } + + 100 -> { + when (buttonID) { + 1 -> { + product = Items.SINEW_9436 + display() + } + 2 -> { + product = CookableItems.forId(initial).cooked + display() + } + } + } + + 101 -> { + when (buttonID) { + 1 -> { + end() + cook(player!!, `object`, initial, Items.SINEW_9436, 1) + } + 2 -> { + end() + cook(player!!, `object`, initial, CookableItems.forId(initial).cooked, 1) + } + } + } + } + } + + private fun getAmount(buttonId: Int): Int { + when (buttonId) { + 5 -> return 1 + 4 -> return 5 + 3 -> return -1 + 2 -> return player!!.inventory.getAmount(initial) + } + return -1 + } + + fun display() { + player!!.packetDispatch.sendItemZoomOnInterface(initial, 160, 307, 2) + player!!.packetDispatch.sendString("



${ItemDefinition.forId(initial).name}", 307, 6) + + // Re-format this interface because it is not formatted properly for the chat-box + // Swords + PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, 307, 0, 12, 15)) + PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, 307, 1, 431, 15)) + // "How many would you like to cook?" + PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, 307, 7, 0, 12)) + // Right click context menu boxes + PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, 307, 3, 58, 27)) + PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, 307, 4, 58, 27)) + PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, 307, 5, 58, 27)) + PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, 307, 6, 58, 27)) + + player!!.interfaceManager.openChatbox(307) + stage = 1 + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/cooking/CookingRecipePlugin.java b/Server/src/main/content/global/skill/cooking/CookingRecipePlugin.java new file mode 100644 index 0000000..9ef36bc --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/CookingRecipePlugin.java @@ -0,0 +1,132 @@ +package content.global.skill.cooking; + +import content.global.skill.cooking.recipe.Recipe; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.game.dialogue.SkillDialogueHandler.SkillDialogue; +import core.game.dialogue.SkillDialogueHandler; + +import java.util.ArrayList; +import java.util.List; + +/** + * Represents a cooking recipe plugin. This is used to handle the multiple + * recipes used in cooking these recipes can range from making a pizza or making + * a pie. + * @author 'Vexia + * @version 1.9 + */ +@Initializable +public final class CookingRecipePlugin extends UseWithHandler { + + /** + * Constructs a new {@code CookingRecipePlugin} {@code Object}. + */ + public CookingRecipePlugin() { + super(getAllowedNodes()); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (Recipe recipe : Recipe.RECIPES) { + for (Item ingredient : recipe.getIngredients()) { + addHandler(ingredient.getId(), ITEM_TYPE, this); + } + } + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + Recipe recipe = null; + // TODO: Transitioning to a Listener would save an O(n) pass through the recipes list on every use-with + for (Recipe temp : Recipe.RECIPES) { + if (temp.isSingular()) { + if (temp.getBase().getId() == event.getUsedItem().getId() || temp.getBase().getId() == event.getBaseItem().getId()) { + for (Item ingredient : temp.getIngredients()) { + if (ingredient.getId() == event.getBaseItem().getId() || ingredient.getId() == event.getUsedItem().getId()) { + recipe = temp; + break; + } + } + } + } else { + Item part = null; + Item ingredient = null; + for (int k = 0; k < temp.getParts().length; k++) { + for (int i = 0; i < temp.getIngredients().length; i++) { + part = temp.getParts()[k]; + ingredient = temp.getIngredients()[i]; + if (part.getId() == event.getUsedItem().getId() && ingredient.getId() == event.getBaseItem().getId() || part.getId() == event.getBaseItem().getId() && ingredient.getId() == event.getUsedItem().getId()) { + if (k == i) {// represents that this ingredient can + // mix with the other. + recipe = temp; + break; + } + } + } + } + } + } + if (recipe != null) { + final Player player = event.getPlayer(); + final Recipe recipe_ = recipe; + SkillDialogueHandler handler = new SkillDialogueHandler(player, SkillDialogue.ONE_OPTION, recipe.getProduct()) { + @Override + public void create(final int amount, int index) { + player.getPulseManager().run(new Pulse(2) { + int count = 0; + @Override + public boolean pulse() { + recipe_.mix(player, event); + return ++count >= amount; + } + }); + } + + @Override + public int getAll(int index) { + return player.getInventory().getAmount(recipe_.getBase()); + } + }; + if (player.getInventory().getAmount(recipe.getBase()) == 1) { + recipe_.mix(player, event); + } else { + handler.open(); + } + return true; + } + return false; + } + + /** + * Method used to get the allowed nodes for this plugin. + * @return the allowed nodes. + */ + private final static int[] getAllowedNodes() { + List bases = new ArrayList<>(10); + for (Recipe recipe : Recipe.RECIPES) { + for (Item base : recipe.getParts()) { + if (bases.contains(base.getId())) { + continue; + } + bases.add(base.getId()); + } + if (bases.contains(recipe.getBase().getId())) { + continue; + } + bases.add(recipe.getBase().getId()); + } + int[] baseArray = new int[bases.size()]; + for (int i = 0; i < bases.size(); i++) { + baseArray[i] = bases.get(i); + } + return baseArray; + } + +} diff --git a/Server/src/main/content/global/skill/cooking/CookingRewrite.kt b/Server/src/main/content/global/skill/cooking/CookingRewrite.kt new file mode 100644 index 0000000..7bc993a --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/CookingRewrite.kt @@ -0,0 +1,85 @@ +package content.global.skill.cooking + +import core.api.amountInInventory +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.node.scenery.Scenery +import org.rs09.consts.Items +import org.rs09.consts.Items.BREAD_DOUGH_2307 +import org.rs09.consts.Items.RAW_BEAR_MEAT_2136 +import org.rs09.consts.Items.RAW_BEEF_2132 +import org.rs09.consts.Items.SEAWEED_401 +import org.rs09.consts.Items.UNCOOKED_CAKE_1889 + +/** + * @author Ceikry + * @author bushtail - added bear meat for sinew making + * @author Woah - added single food cooking + */ +class CookingRewrite : InteractionListener { + + val RAW_FOODS: IntArray + + init { + val list = CookableItems.values().map { it.raw }.toMutableList() + list.add(Items.COOKED_MEAT_2142) + list.add(RAW_BEEF_2132) + list.add(RAW_BEAR_MEAT_2136) + list.add(SEAWEED_401) + RAW_FOODS = list.toIntArray() + } + + override fun defineListeners() { + + onUseWith(IntType.SCENERY,RAW_FOODS, *COOKING_OBJs){ player, used, with -> + val item = used.asItem() + val obj = with.asScenery() + val range = obj.name.toLowerCase().contains("range") + when (item.id) { + RAW_BEEF_2132, RAW_BEAR_MEAT_2136 -> if (range) { + player.dialogueInterpreter.open(CookingDialogue(item.id,9436,true,obj,item.id)) + return@onUseWith true + } + BREAD_DOUGH_2307, UNCOOKED_CAKE_1889 -> if (!range) { + player.packetDispatch.sendMessage("You need to cook this on a range.") + return@onUseWith false + } + } + + //cook a standard item + if (amountInInventory(player, item.id) > 1) { + player.dialogueInterpreter.open(CookingDialogue(item.id,obj)) + } else { + // Don't display dialogue if player only has *1* of the item + val product = if (CookableItems.intentionalBurn(item.id)) { // checks intentional burning + CookableItems.getIntentionalBurn(item.id).id + } else { + CookableItems.forId(item.id).cooked + } + cook(player, obj, item.id, product, 1) + } + return@onUseWith true + } + + } + + companion object { + val COOKING_OBJs = intArrayOf(24313,21302, 13528, 13529, 13533, 13531, 13536, 13539, 13542, 2728, 2729, 2730, 2731, 2732, 2859, 3038, 3039, 3769, 3775, 4265, 4266, 5249, 5499, 5631, 5632, 5981, 9682, 10433, 11404, 11405, 11406, 12102, 12796, 13337, 13881, 14169, 14919, 15156, 20000, 20001, 21620, 21792, 22713, 22714, 23046, 24283, 24284, 25155, 25156, 25465, 25730, 27297, 29139, 30017, 32099, 33500, 34495, 34546, 36973, 37597, 37629, 37726, 114, 4172, 5275, 8750, 16893, 22154, 34410, 34565, 114, 9085, 9086, 9087, 12269, 15398, 25440, 25441, 2724, 2725, 2726, 4618, 4650, 5165, 6093, 6094, 6095, 6096, 8712, 9374, 9439, 9440, 9441, 10824, 17640, 17641, 17642, 17643, 18039, 18170, 21795, 24285, 24329, 27251, 33498, 35449, 36815, 36816, 37426, 40110, 10377) + + @JvmStatic + fun cook(player: Player, `object`: Scenery?, initial: Int, product: Int, amount: Int) { + val food = Item(initial) + if (food.name.toLowerCase().contains("pizza")) { + player.pulseManager.run(PizzaCookingPulse(player, `object`, initial, product, amount)) + } else if (food.name.toLowerCase().contains("pie")) { + player.pulseManager.run(PieCookingPulse(player, `object`, initial, product, amount)) + } else if (CookableItems.intentionalBurn(initial)) { + player.pulseManager.run(IntentionalBurnPulse(player, `object`, initial, product, amount)) + } else { + player.pulseManager.run(StandardCookingPulse(player, `object`, initial, product, amount)) + } + } + } +} diff --git a/Server/src/main/content/global/skill/cooking/DoughMakingListener.kt b/Server/src/main/content/global/skill/cooking/DoughMakingListener.kt new file mode 100644 index 0000000..a60f89f --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/DoughMakingListener.kt @@ -0,0 +1,89 @@ +package content.global.skill.cooking + +import core.api.* +import core.game.event.ResourceProducedEvent +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import org.rs09.consts.Items +import core.game.dialogue.DialogueFile +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +class DoughMakingListener : InteractionListener { + companion object { + private val FULL_WATER_CONTAINERS_TO_EMPTY_CONTAINERS = hashMapOf( + Items.BUCKET_OF_WATER_1929 to Items.BUCKET_1925, + Items.BOWL_OF_WATER_1921 to Items.BOWL_1923, + Items.JUG_OF_WATER_1937 to Items.JUG_1935 + ) + } + + override fun defineListeners() { + onUseWith( + IntType.ITEM, + FULL_WATER_CONTAINERS_TO_EMPTY_CONTAINERS.keys.toIntArray(), + Items.POT_OF_FLOUR_1933 + ) { player, waterContainer, flourContainer -> + openDialogue(player, DoughMakeDialogue(waterContainer.asItem(), flourContainer.asItem())) + return@onUseWith true + } + } + + private class DoughMakeDialogue(val waterContainer: Item, val flourContainer: Item) : DialogueFile() { + companion object { + private const val STAGE_PRESENT_OPTIONS = 0 + private const val STAGE_PROCESS_OPTION = 1 + + private enum class DoughProduct(val itemId: Int, val itemName: String, val requiredCookingLevel: Int) { + BREAD_DOUGH(Items.BREAD_DOUGH_2307, getItemName(Items.BREAD_DOUGH_2307), 1), + PASTRY_DOUGH(Items.PASTRY_DOUGH_1953, getItemName(Items.PASTRY_DOUGH_1953), 1), + PIZZA_DOUGH(Items.PIZZA_BASE_2283, getItemName(Items.PIZZA_BASE_2283), 35), + PITTA_DOUGH(Items.PITTA_DOUGH_1863, getItemName(Items.PITTA_DOUGH_1863), 58), + } + } + + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + STAGE_PRESENT_OPTIONS -> { + player!!.dialogueInterpreter.sendOptions( + "What do you wish to make?", + *(DoughProduct.values().map { "${it.itemName}." }.toTypedArray()) + ).also { stage++ } + } + STAGE_PROCESS_OPTION -> runTask(player!!, 1) { + end() + val selectedDoughProduct = DoughProduct.values()[buttonID - 1] + if (hasLevelDyn(player!!, Skills.COOKING, selectedDoughProduct.requiredCookingLevel)) { + if (freeSlots(player!!) < 1) { + sendMessage( + player!!, + "Not enough space in your inventory." + ) + return@runTask + } + + if (removeItem(player!!, waterContainer) && removeItem(player!!, flourContainer)) { + addItem(player!!, selectedDoughProduct.itemId) + player!!.dispatch(ResourceProducedEvent(selectedDoughProduct.itemId, 1, player!!)) + + val emptyWaterContainerId = FULL_WATER_CONTAINERS_TO_EMPTY_CONTAINERS[waterContainer.id]!! + addItem(player!!, emptyWaterContainerId) + + addItem(player!!, Items.EMPTY_POT_1931) + + sendMessage( + player!!, + "You mix the flower and the water to make some ${selectedDoughProduct.itemName.toLowerCase()}." + ) + } + } else { + sendDialogue( + player!!, + "You need a Cooking level of at least ${selectedDoughProduct.requiredCookingLevel} in order to make ${selectedDoughProduct.itemName.toLowerCase()}." + ) + } + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/cooking/FireOptionPotteryPlugin.java b/Server/src/main/content/global/skill/cooking/FireOptionPotteryPlugin.java new file mode 100644 index 0000000..c0def77 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/FireOptionPotteryPlugin.java @@ -0,0 +1,34 @@ +package content.global.skill.cooking; + +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the plugin used for the fire pottery object. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class FireOptionPotteryPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(2643).getHandlers().put("option:fire", this); + SceneryDefinition.forId(4308).getHandlers().put("option:fire", this); + SceneryDefinition.forId(11601).getHandlers().put("option:fire", this); + SceneryDefinition.forId(34802).getHandlers().put("option:fire", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + player.faceLocation(node.getLocation()); + player.getDialogueInterpreter().open(99843, true, true); + return true; + } + +} diff --git a/Server/src/main/content/global/skill/cooking/IntentionalBurnPulse.java b/Server/src/main/content/global/skill/cooking/IntentionalBurnPulse.java new file mode 100644 index 0000000..051f5a1 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/IntentionalBurnPulse.java @@ -0,0 +1,58 @@ +package content.global.skill.cooking; + +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playAudio; + +public class IntentionalBurnPulse extends StandardCookingPulse { + int initial,product,amount; + Player player; + Scenery object; + IntentionalBurnPulse(Player player, Scenery object, int initial, int product, int amount){ + super(player,object,initial,product,amount); + this.initial = initial; + this.product = product; + this.amount = amount; + this.player = player; + this.object = object; + } + + @Override + public boolean checkRequirements() { + return object.isActive(); + } + + @Override + public boolean reward() { + if (getDelay() == 1) { + setDelay(object.getName().toLowerCase().equals("range") ? 5 : 4); + return false; + } + if(cook(player,null,false,initial,product)) { + amount--; + } else { + return true; + } + // we are always one off a normal cooking pulse because + // the first tick is handled outside of this class. + return amount <= 1; + } + + @Override + public boolean cook(Player player, Scenery object, boolean burned, int initial, int product) { + super.animate(); + Item initialItem = new Item(initial); + Item productItem = new Item(product); + + if (player.getInventory().remove(initialItem)) { + player.getInventory().add(productItem); + player.getPacketDispatch().sendMessage(getMessage(initialItem, productItem, burned)); + playAudio(player, Sounds.FRY_2577); + return true; + } + return false; + } +} diff --git a/Server/src/main/content/global/skill/cooking/MakeStewPlugin.java b/Server/src/main/content/global/skill/cooking/MakeStewPlugin.java new file mode 100644 index 0000000..33436f4 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/MakeStewPlugin.java @@ -0,0 +1,62 @@ +package content.global.skill.cooking; + +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the stew plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public class MakeStewPlugin extends UseWithHandler { + + /** + * Constructs a new {@code MakeStewPlugin} {@code Object}. + */ + public MakeStewPlugin() { + super(2001); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(114, OBJECT_TYPE, this); + addHandler(2728, OBJECT_TYPE, this); + addHandler(2729, OBJECT_TYPE, this); + addHandler(2730, OBJECT_TYPE, this); + addHandler(2731, OBJECT_TYPE, this); + addHandler(2859, OBJECT_TYPE, this); + addHandler(3039, OBJECT_TYPE, this); + addHandler(4172, OBJECT_TYPE, this); + addHandler(5275, OBJECT_TYPE, this); + addHandler(8750, OBJECT_TYPE, this); + addHandler(9682, OBJECT_TYPE, this); + addHandler(12102, OBJECT_TYPE, this); + addHandler(14919, OBJECT_TYPE, this); + addHandler(16893, OBJECT_TYPE, this); + addHandler(21792, OBJECT_TYPE, this); + addHandler(22154, OBJECT_TYPE, this); + addHandler(22713, OBJECT_TYPE, this); + addHandler(22714, OBJECT_TYPE, this); + addHandler(24283, OBJECT_TYPE, this); + addHandler(24284, OBJECT_TYPE, this); + addHandler(25730, OBJECT_TYPE, this); + addHandler(33500, OBJECT_TYPE, this); + addHandler(34410, OBJECT_TYPE, this); + addHandler(34495, OBJECT_TYPE, this); + addHandler(34546, OBJECT_TYPE, this); + addHandler(34565, OBJECT_TYPE, this); + addHandler(36973, OBJECT_TYPE, this); + addHandler(37629, OBJECT_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + event.getPlayer().getDialogueInterpreter().open(43989, event.getUsedItem().getId(), "stew"); + return true; + } + +} diff --git a/Server/src/main/content/global/skill/cooking/NettleTeaPlugin.java b/Server/src/main/content/global/skill/cooking/NettleTeaPlugin.java new file mode 100644 index 0000000..161c999 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/NettleTeaPlugin.java @@ -0,0 +1,61 @@ +package content.global.skill.cooking; + +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the plugin used to create nettle tea in a cup. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class NettleTeaPlugin extends UseWithHandler { + + /** + * Represents the empty cup item. + */ + private static final Item EMPTY_CUP = new Item(1980, 1); + + /** + * Represents the nettle tea item. + */ + private static final Item NETTLE_TEA = new Item(4239, 1); + + /** + * Represents the bowl item. + */ + private static final Item BOWL = new Item(1923); + + /** + * Represents the cup of tea item. + */ + private static final Item CUP_OF_TEA = new Item(4242, 1); + + /** + * Constructs a new {@code NettleTeaPlugin} {@code Object}. + */ + public NettleTeaPlugin() { + super(1980); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(4239, ITEM_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + if (player.getInventory().remove(EMPTY_CUP) && player.getInventory().remove(NETTLE_TEA)) { + player.getInventory().add(BOWL); + player.getInventory().add(CUP_OF_TEA); + } + return true; + } + +} diff --git a/Server/src/main/content/global/skill/cooking/NettleWaterPlugin.java b/Server/src/main/content/global/skill/cooking/NettleWaterPlugin.java new file mode 100644 index 0000000..e8dbeb3 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/NettleWaterPlugin.java @@ -0,0 +1,35 @@ +package content.global.skill.cooking; + +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * @author Adam + */ +@Initializable +public class NettleWaterPlugin extends UseWithHandler { + + public NettleWaterPlugin() { + super(1921); + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + player.getInventory().remove(new Item(1921, 1)); + player.getInventory().remove(new Item(4241, 1)); + player.getInventory().add(new Item(4237, 1)); + return true; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(4241, ITEM_TYPE, this); + return this; + } + +} diff --git a/Server/src/main/content/global/skill/cooking/PieCookingPulse.java b/Server/src/main/content/global/skill/cooking/PieCookingPulse.java new file mode 100644 index 0000000..633af58 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/PieCookingPulse.java @@ -0,0 +1,34 @@ +package content.global.skill.cooking; + +import core.cache.def.impl.ItemDefinition; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; + +public class PieCookingPulse extends StandardCookingPulse { + private Scenery object; + private Player player; + public PieCookingPulse(Player player, Scenery object, int initial, int product, int amount){ + super(player,object,initial,product,amount); + this.object = object; + this.player = player; + } + + @Override + public boolean checkRequirements() { + if(!object.getName().toLowerCase().contains("range")){ + player.getPacketDispatch().sendMessage("This can only be cooked on a range."); + return false; + } + return super.checkRequirements(); + } + + @Override + public String getMessage(Item food, Item product, boolean burned) { + if(burned){ + return "You accidentally burn the pie."; + } else { + return "You successfully bake a delicious " + ItemDefinition.forId(product.getId()).getName().toLowerCase() + "."; + } + } +} diff --git a/Server/src/main/content/global/skill/cooking/PieShellPlugin.java b/Server/src/main/content/global/skill/cooking/PieShellPlugin.java new file mode 100644 index 0000000..4278836 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/PieShellPlugin.java @@ -0,0 +1,56 @@ +package content.global.skill.cooking; + +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the pie shell making plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class PieShellPlugin extends UseWithHandler { + + /** + * Represents the pie sell item. + */ + private static final Item PIE_SHELL = new Item(2315, 1); + + /** + * Represents the pie dish item. + */ + private static final Item PIE_DISH = new Item(2313, 1); + + /** + * Represents the pastry dough item. + */ + private static final Item PASTRY_DOUGH = new Item(1953, 1); + + /** + * Constructs a new {@code PieMakingPlugin} {@code Object}. + */ + public PieShellPlugin() { + super(1953); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(2313, ITEM_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + if (player.getInventory().remove(PASTRY_DOUGH, PIE_DISH)) { + player.getInventory().add(PIE_SHELL); + player.getPacketDispatch().sendMessage("You put the pastry dough into the pie dish to make a pie shell."); + } + return true; + } + +} diff --git a/Server/src/main/content/global/skill/cooking/PizzaCookingPulse.java b/Server/src/main/content/global/skill/cooking/PizzaCookingPulse.java new file mode 100644 index 0000000..45653e5 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/PizzaCookingPulse.java @@ -0,0 +1,34 @@ +package content.global.skill.cooking; + +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; + +public class PizzaCookingPulse extends StandardCookingPulse { + Scenery object; + Player player; + + PizzaCookingPulse(Player player, Scenery object, int initial, int product, int amount){ + super(player,object,initial,product,amount); + this.object = object; + this.player = player; + } + + @Override + public boolean checkRequirements() { + if(!object.getName().toLowerCase().contains("range")){ + player.getPacketDispatch().sendMessage("This can only be cooked on a range."); + return false; + } + return super.checkRequirements(); + } + + @Override + public String getMessage(Item food, Item product, boolean burned) { + if(burned){ + return "You accidentally burn the pizza."; + } else { + return "You cook a delicious looking pizza."; + } + } +} diff --git a/Server/src/main/content/global/skill/cooking/SaucyKebabListener.kt b/Server/src/main/content/global/skill/cooking/SaucyKebabListener.kt new file mode 100644 index 0000000..fc22db0 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/SaucyKebabListener.kt @@ -0,0 +1,31 @@ +package content.global.skill.cooking + + +import core.api.* + +import org.rs09.consts.Items +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + + +/** + * @author bushtail + * That's-a spicy kebab! + */ +class SaucyKebabListener : InteractionListener { + val sauce = Items.RED_HOT_SAUCE_4610 + val kebabArr = intArrayOf( + Items.KEBAB_1971, + Items.UGTHANKI_KEBAB_1883, + Items.UGTHANKI_KEBAB_1885 + ) + + override fun defineListeners() { + onUseWith(IntType.ITEM, kebabArr, sauce) { player, used, with -> + if(removeItem(player, used.asItem()) && removeItem(player, with.asItem())) { + return@onUseWith addItem(player, Items.SUPER_KEBAB_4608) + } + return@onUseWith false + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/cooking/SinewCookingPulse.java b/Server/src/main/content/global/skill/cooking/SinewCookingPulse.java new file mode 100644 index 0000000..4f9e6be --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/SinewCookingPulse.java @@ -0,0 +1,32 @@ +package content.global.skill.cooking; + +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; + +/** + * Fixes the half assed previous implementation of cooking Sinew. + * @author Woah + */ +public class SinewCookingPulse extends StandardCookingPulse { + + public SinewCookingPulse(Player player, Scenery object, int initial, int product, int amount) { + super(player, object, initial, product, amount); + } + + @Override + public boolean checkRequirements() { + properties = CookableItems.SINEW; + return super.checkRequirements(); + } + + @Override + public boolean isBurned(Player player, Scenery object, int food) { + return false; + } + + @Override + public String getMessage(Item food, Item product, boolean burned) { + return "You dry a piece of beef and extract the sinew."; + } +} diff --git a/Server/src/main/content/global/skill/cooking/SkeweredFoodPlugin.java b/Server/src/main/content/global/skill/cooking/SkeweredFoodPlugin.java new file mode 100644 index 0000000..8f02bfc --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/SkeweredFoodPlugin.java @@ -0,0 +1,115 @@ +package content.global.skill.cooking; + +import core.game.node.entity.skill.Skills; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.Plugin; +import org.rs09.consts.Items; + +/** + * Represents the plugin used to make skwered items. + * @author 'Vexia + * @date 22/12/2013 + */ +@Initializable +public class SkeweredFoodPlugin extends UseWithHandler { + + /** + * Represents the level required. + */ + private final int LEVEL = 20; + + /** + * Constructs a new {@code SkeweredFoodPlugin} {@code Object}. + */ + public SkeweredFoodPlugin() { + super(7225); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (SkeweredSet set : SkeweredSet.values()) { + addHandler(set.getRaw().getId(), ITEM_TYPE, this); + } + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + if (player.getSkills().getLevel(Skills.FIREMAKING) < LEVEL) { + player.getPacketDispatch().sendMessage("You meed a Firemaking level of at least " + LEVEL + " in order to do this."); + return true; + } + final SkeweredSet set = SkeweredSet.forItem(event.getBaseItem().getId() == 7225 ? event.getUsedItem() : event.getBaseItem()); + if (player.getInventory().remove(event.getBaseItem()) && player.getInventory().remove(event.getUsedItem())) { + player.getInventory().add(set.getProduct()); + } + return true; + } + + /** + * Represents a set of skwered items. + * @author 'Vexia + * @date 22/12/2013 + */ + public enum SkeweredSet { + CHOMPY(new Item(Items.RAW_CHOMPY_2876), new Item(Items.SKEWERED_CHOMPY_7230)), + RABBIT(new Item(Items.RAW_RABBIT_3226), new Item(Items.SKEWERED_RABBIT_7224)), + BIRD(new Item(Items.RAW_BIRD_MEAT_9978), new Item(Items.SKEWERED_BIRD_MEAT_9984)), + BEAST(new Item(Items.RAW_BEAST_MEAT_9986), new Item(Items.SKEWERED_BEAST_9992)); + + /** + * Represents the raw item. + */ + private final Item raw; + + /** + * Represents the product item. + */ + private final Item product; + + /** + * Constructs a new {@code SkeweredFoodPlugin} {@code Object}. + * @param raw the raw item. + * @param product the product. + */ + private SkeweredSet(Item raw, Item product) { + this.raw = raw; + this.product = product; + } + + /** + * Gets the raw. + * @return The raw. + */ + public Item getRaw() { + return raw; + } + + /** + * Gets the product. + * @return The product. + */ + public Item getProduct() { + return product; + } + + /** + * Gets the skwered set. + * @param item the item. + * @return the set. + */ + public static SkeweredSet forItem(final Item item) { + for (SkeweredSet set : values()) { + if (set.getRaw().getId() == item.getId()) { + return set; + } + } + return null; + } + } +} diff --git a/Server/src/main/content/global/skill/cooking/StandardCookingPulse.java b/Server/src/main/content/global/skill/cooking/StandardCookingPulse.java new file mode 100644 index 0000000..d70856a --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/StandardCookingPulse.java @@ -0,0 +1,224 @@ +package content.global.skill.cooking; + +import content.global.skill.skillcapeperks.SkillcapePerks; +import core.game.event.ResourceProducedEvent; +import core.game.node.entity.impl.Animator; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.info.LogType; +import core.game.node.entity.player.info.PlayerMonitor; +import core.game.node.entity.player.link.audio.Audio; +import core.game.node.entity.skill.Skills; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.system.task.Pulse; +import core.game.world.update.flag.context.Animation; +import core.tools.RandomFunction; +import org.rs09.consts.Items; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.*; +import content.data.Quests; + +public class StandardCookingPulse extends Pulse { + //range animation + private static final Animation RANGE_ANIMATION = new Animation(883, Animator.Priority.HIGH); + + //fire animation + private static final Animation FIRE_ANIMATION = new Animation(897, Animator.Priority.HIGH); + + //Cooking sound + public static final Audio SOUND = new Audio(2577, 1, 1); + + private static final int LUMBRIDGE_RANGE = 114; + + private final int initial; + private final int product; + private int amount; + private final Scenery object; + private final Player player; + private double experience; + private boolean burned = false; + public CookableItems properties; + + private int initialAmount; + private int processedAmount; + + public StandardCookingPulse(Player player, Scenery object, int initial, int product, int amount) { + this.player = player; + this.object = object; + this.initial = initial; + this.product = product; + this.amount = amount; + this.initialAmount = amountInInventory(player, initial); + this.processedAmount = 0; + } + + @Override + public void start() { + properties = CookableItems.forId(initial); + if (checkRequirements()) { + super.start(); + cook(player, object, properties != null && burned, initial, product); + amount--; + } + } + + @Override + public boolean pulse() { + if (amount < 1 || !checkRequirements()) { + return true; + } + return reward(); + } + + public void animate() { + player.animate(getAnimation(object)); + } + + public boolean checkRequirements() { + this.experience = 0; + if (properties != null) { + // Handle Cook's Assistant range + if (object.getId() == LUMBRIDGE_RANGE && !player.getQuestRepository().isComplete(Quests.COOKS_ASSISTANT)) { + player.getPacketDispatch().sendMessage("You need to have completed the Cook's Assistant quest in order to use that range."); + return false; + } + + //check level + if (player.getSkills().getLevel(Skills.COOKING) < properties.level) { + player.getDialogueInterpreter().sendDialogue("You need a cooking level of " + properties.level + " to cook this."); + return false; + } + + this.experience = properties.experience; + this.burned = isBurned(player, object, initial); + } + if (amount < 1) { + return false; + } + + return object.isActive(); + } + + public boolean reward() { + if (getDelay() == 1) { + int delay = object.getName().toLowerCase().contains("range") ? 5 : 4; + if (SkillcapePerks.isActive(SkillcapePerks.HASTY_COOKING, player)) { + delay -= 1; + } + setDelay(delay); + return false; + } + + if (cook(player, object, burned, initial, product)) { + amount--; + } else { + return true; + } + return amount < 1; + } + + public boolean isBurned(final Player player, final Scenery object, int food) { + boolean hasGauntlets = player.getEquipment().containsItem(new Item(Items.COOKING_GAUNTLETS_775)); + int effectiveCookingLevel = player.getSkills().getLevel(Skills.COOKING); + if (SkillcapePerks.isActive(SkillcapePerks.HASTY_COOKING, player)) { + effectiveCookingLevel -= 5; + } + CookableItems item = CookableItems.forId(food); + int low; + int high; + if (hasGauntlets && CookableItems.gauntletValues.containsKey(food)) { + int[] successValues = CookableItems.gauntletValues.get(food); + low = successValues[0]; + high = successValues[1]; + } else if (object.getId() == LUMBRIDGE_RANGE) { + int[] successValues = CookableItems.lumbridgeRangeValues.getOrDefault(food, new int[]{item.lowRange, item.highRange}); + low = successValues[0]; + high = successValues[1]; + } else { + boolean isFire = object.getName().toLowerCase().contains("fire"); + low = isFire ? item.low : item.lowRange; + high = isFire ? item.high : item.highRange; + } + double host_ratio = RandomFunction.randomDouble(100.0); + double client_ratio = RandomFunction.getSkillSuccessChance(low, high, effectiveCookingLevel); + return host_ratio > client_ratio; + } + + public boolean cook(final Player player, final Scenery object, final boolean burned, final int initial, final int product) { + Item initialItem = new Item(initial); + Item productItem = new Item(product); + animate(); + + //handle special cooking results (spits, cake, etc) that don't justify separate plugin + switch (initial) { + case Items.SKEWERED_CHOMPY_7230: + case Items.SKEWERED_RABBIT_7224: + case Items.SKEWERED_BIRD_MEAT_9984: + case Items.SKEWERED_BEAST_9992: + case Items.IRON_SPIT_7225: + if (RandomFunction.random(15) == 5) { + player.getPacketDispatch().sendMessage("Your iron spit seems to have broken in the process."); + } else { + if (!player.getInventory().add(new Item(Items.IRON_SPIT_7225))) { + GroundItemManager.create(new Item(Items.IRON_SPIT_7225), player.getLocation(), player); + } + } + break; + case Items.UNCOOKED_CAKE_1889: //cake + if (!player.getInventory().add(new Item(Items.CAKE_TIN_1887))) { + GroundItemManager.create(new Item(Items.CAKE_TIN_1887), player); + } + break; + } + if (player.getInventory().remove(initialItem)) { + if (!burned) { + player.getInventory().add(productItem); + player.dispatch(new ResourceProducedEvent(productItem.getId(), 1, object, initialItem.getId())); + player.getSkills().addExperience(Skills.COOKING, experience, true); + processedAmount++; + if (processedAmount > initialAmount) { + PlayerMonitor.log(player, LogType.DUPE_ALERT, "cooked item (" + player.getName() + ", " + initialItem.getName() + "): initialAmount " + initialAmount + ", processedAmount " + processedAmount); + } + player.incrementAttribute("/save:stats_manager:food_cooked", 1); + } else { + player.dispatch(new ResourceProducedEvent(CookableItems.getBurnt(initial).getId(), 1, object, initialItem.getId())); + player.getInventory().add(CookableItems.getBurnt(initial)); + } + player.getPacketDispatch().sendMessage(getMessage(initialItem, productItem, burned)); + playAudio(player, Sounds.FRY_2577); + return true; + } + return false; + } + + public String getMessage(Item food, Item product, boolean burned) { + if (food.getId() == Items.RAW_OOMLIE_2337) { + return "The meat is far too delicate to cook like this. Perhaps you should wrap something around it to protect it from the heat."; + } + if (product.getId() == Items.SODA_ASH_1781) { + return "You burn the seaweed into soda ash."; + } + if (CookableItems.intentionalBurn(food.getId())) { + return "You deliberately burn the perfectly good piece of meat."; + } + + if (!burned && food.getName().startsWith("Raw")) { + return "You manage to cook some " + food.getName().replace("Raw ", "") + "."; + } else if (burned && food.getName().startsWith("Raw")) { + return "You accidentally burn some " + food.getName().replace("Raw ", "") + "."; + } + + if (!burned && food.getName().startsWith(("Uncooked"))) { + return "You manage to cook some " + food.getName().replace("Uncooked ", "") + "."; + } else if (burned && food.getName().startsWith(("Uncooked"))) { + return "You accidentally burn some " + food.getName().replace("Uncooked ", "") + "."; + } + return null; + } + + private Animation getAnimation(final Scenery object) { + return !object.getName().equalsIgnoreCase("fire") ? RANGE_ANIMATION : FIRE_ANIMATION; + } +} diff --git a/Server/src/main/content/global/skill/cooking/WatermelonSlicePlugin.java b/Server/src/main/content/global/skill/cooking/WatermelonSlicePlugin.java new file mode 100644 index 0000000..d827396 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/WatermelonSlicePlugin.java @@ -0,0 +1,59 @@ +package content.global.skill.cooking; + +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the plugin used to slice a watermelon. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class WatermelonSlicePlugin extends UseWithHandler { + + /** + * Represents the knife item. + */ + private static final Item KNIFE = new Item(946); + + /** + * Represents the watermelon item. + */ + private static final Item WATERMELON = new Item(5982); + + /** + * Represents the watermelon slice item. + */ + private static final Item WATERMELON_SLICE = new Item(5984); + + /** + * Constructs a new {@code WatermelonSlicePlugin.java} {@code Object}. + */ + public WatermelonSlicePlugin() { + super(KNIFE.getId()); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(5982, ITEM_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + if (event.getPlayer().getInventory().remove(WATERMELON)) { + for (int i = 0; i < 3; i++) { + if (!event.getPlayer().getInventory().add(WATERMELON_SLICE)) { + GroundItemManager.create(WATERMELON_SLICE, event.getPlayer()); + } + } + event.getPlayer().getPacketDispatch().sendMessage("You slice the watermelon into three slices."); + } + return true; + } + +} diff --git a/Server/src/main/content/global/skill/cooking/WineFermentPlugin.java b/Server/src/main/content/global/skill/cooking/WineFermentPlugin.java new file mode 100644 index 0000000..b2e9667 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/WineFermentPlugin.java @@ -0,0 +1,63 @@ +package content.global.skill.cooking; + +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import content.global.skill.cooking.fermenting.WineFermentingPulse; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.GameWorld; +import core.plugin.Plugin; + +/** + * Represents the plugin used to ferment wine. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class WineFermentPlugin extends UseWithHandler { + + /** + * Represents the grapes item. + */ + private static final Item GRAPES = new Item(1987, 1); + + /** + * Represents the jug of water item. + */ + private static final Item JUG_OF_WATER = new Item(1937, 1); + + /** + * Represents the unfermented wine item. + */ + private static final Item UNFERMENTED_WINE = new Item(1995, 1); + + /** + * Constructs a new {@code WineFermentPlugin} {@code Object}. + */ + public WineFermentPlugin() { + super(1937); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(1987, ITEM_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + if (player.getSkills().getLevel(Skills.COOKING) < 35) { + player.getPacketDispatch().sendMessage("You need a cooking level of 35 to do this."); + return true; + } + if (player.getInventory().remove(GRAPES, JUG_OF_WATER)) { + player.getInventory().add(UNFERMENTED_WINE); + GameWorld.getPulser().submit(new WineFermentingPulse(1, player)); + } + return true; + } + +} diff --git a/Server/src/main/content/global/skill/cooking/dairy/DairyChurnDialogue.java b/Server/src/main/content/global/skill/cooking/dairy/DairyChurnDialogue.java new file mode 100644 index 0000000..0c2b5e0 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/dairy/DairyChurnDialogue.java @@ -0,0 +1,106 @@ +package content.global.skill.cooking.dairy; + +import core.game.component.Component; +import core.game.dialogue.DialoguePlugin; +import core.plugin.Initializable; +import org.rs09.consts.Items; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +/** + * Represents the dairy churn dialogue. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class DairyChurnDialogue extends DialoguePlugin { + + /** + * Represents the item array. + */ + private static final Item[] ITEMS = new Item[] { + new Item(Items.BUCKET_OF_MILK_1927, 1), + new Item(Items.POT_OF_CREAM_2130, 1), + new Item(Items.PAT_OF_BUTTER_6697, 1) + }; + + /** + * Constructs a new {@code DairyChurnDialogue} {@code Object}. + */ + public DairyChurnDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code DairyChurnDialogue} {@code Object}. + * @param player the player. + */ + public DairyChurnDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new DairyChurnDialogue(player); + } + + @Override + public boolean open(Object... args) { + player.getInterfaceManager().openChatbox(new Component(74)); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + DairyProduct product = null; + int amount = 0; + switch (buttonId) { + case 6: + product = DairyProduct.POT_OF_CREAM; + amount = 1; + break; + case 5: + product = DairyProduct.POT_OF_CREAM; + amount = 5; + break; + case 4: + product = DairyProduct.POT_OF_CREAM; + amount = 10; + break; + case 9: + product = DairyProduct.PAT_OF_BUTTER; + amount = 1; + break; + case 8: + product = DairyProduct.PAT_OF_BUTTER; + amount = 5; + break; + case 7: + product = DairyProduct.PAT_OF_BUTTER; + amount = 10; + break; + case 12: + product = DairyProduct.CHEESE; + amount = 1; + break; + case 11: + product = DairyProduct.CHEESE; + amount = 5; + break; + case 10: + product = DairyProduct.CHEESE; + amount = 10; + break; + } + player.getPulseManager().run(new DairyChurnPulse(player, ITEMS[0], product, amount)); + return true; + } + + @Override + public int[] getIds() { + return new int[] { 984374 }; + } + +} diff --git a/Server/src/main/content/global/skill/cooking/dairy/DairyChurnOptionPlugin.java b/Server/src/main/content/global/skill/cooking/dairy/DairyChurnOptionPlugin.java new file mode 100644 index 0000000..1c87334 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/dairy/DairyChurnOptionPlugin.java @@ -0,0 +1,38 @@ +package content.global.skill.cooking.dairy; + +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the plugin used to handle dairy churning executing. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class DairyChurnOptionPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(10093).getHandlers().put("option:churn", this); + SceneryDefinition.forId(10094).getHandlers().put("option:churn", this); + SceneryDefinition.forId(25720).getHandlers().put("option:churn", this); + SceneryDefinition.forId(34800).getHandlers().put("option:churn", this); + SceneryDefinition.forId(35931).getHandlers().put("option:churn", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + if (!player.getInventory().contains(1927, 1) && !player.getInventory().contains(2130, 1) && !player.getInventory().contains(6697, 1)) { + player.getPacketDispatch().sendMessage("You need some milk, cream or butter to use in the churn."); + return true; + } + player.getDialogueInterpreter().open(984374); + return true; + } + +} diff --git a/Server/src/main/content/global/skill/cooking/dairy/DairyChurnPulse.java b/Server/src/main/content/global/skill/cooking/dairy/DairyChurnPulse.java new file mode 100644 index 0000000..f93e436 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/dairy/DairyChurnPulse.java @@ -0,0 +1,124 @@ +package content.global.skill.cooking.dairy; + +import content.region.fremennik.rellekka.handlers.RellekkaUtils; +import content.region.fremennik.rellekka.handlers.RellekkaZone; +import core.game.event.ResourceProducedEvent; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.entity.skill.SkillPulse; +import core.game.node.entity.skill.Skills; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.tools.StringUtils; +import org.rs09.consts.Items; + +import static core.api.ContentAPIKt.location; +import static core.api.ContentAPIKt.sendMessage; + +/** + * Represents the skill pulse used to make a dairy product. + * @author 'Vexia + */ +public final class DairyChurnPulse extends SkillPulse { + + /** + * Represents the animation. + */ + private static final Animation ANIMATION = new Animation(2793); + + /** + * Represents the bucket of milk item. + */ + private static final Item BUCKET_OF_MILK = new Item(1927, 1); + + /** + * Represents the bucket item. + */ + private static final Item BUCKET = new Item(1925, 1); + + /** + * Represents the dairy product we're making. + */ + private final DairyProduct dairy; + + /** + * Represent the amount to make. + */ + private int amount; + + /** + * Constructs a new {@code DairyChurnPulse} {@code Object}. + * @param player the player. + * @param item the item. + * @param product the product. + * @param amount the amount. + */ + public DairyChurnPulse(Player player, Item item, DairyProduct product, int amount) { + super(player, item); + super.setDelay(8); + this.amount = amount; + this.dairy = product; + } + + @Override + public boolean checkRequirements() { + player.getInterfaceManager().closeChatbox(); + boolean hasAnyInput = false; + for(Item input : dairy.getInputs()) { + if(player.getInventory().containsItem(input)) { + hasAnyInput = true; + node = input; + break; + } + } + if (!hasAnyInput) { + player.getPacketDispatch().sendMessage("You need a bucket of milk."); + return false; + } + if (player.getSkills().getLevel(Skills.COOKING) < dairy.getLevel()) { + player.getPacketDispatch().sendMessage("You need a cooking level of " + dairy.getLevel() + " to cook this."); + return false; + } + if (amount > player.getInventory().getAmount(node)) { + amount = player.getInventory().getAmount(node); + } + if (amount < 1) { + return false; + } + animate(); + return true; + } + + @Override + public void animate() { + player.animate(ANIMATION); + } + + @Override + public boolean reward() { + amount--; + for(Item input : dairy.getInputs()) { + if (player.getInventory().remove(input)) { + // Since we've just removed the input, there's always enough room for the primary output + player.getInventory().add(dairy.getProduct()); + // But if we were churning milk, we might need to drop the bucket on the floor if there isn't enough space + if(input.getId() == Items.BUCKET_OF_MILK_1927) { + if(!player.getInventory().add(BUCKET)) { + // https://runescape.wiki/w/Pat_of_butter?oldid=2043294 + // "using milk with a full inventory will auto-drop the buckets" + GroundItemManager.create(BUCKET, player); + } + } + player.getPacketDispatch().sendMessage("You make " + (StringUtils.isPlusN(dairy.getProduct().getName().toLowerCase()) ? "an" : "a") + " " + dairy.getProduct().getName().toLowerCase() + "."); + player.dispatch(new ResourceProducedEvent(dairy.getProduct().getId(), amount, node, BUCKET_OF_MILK.getId())); + player.getSkills().addExperience(Skills.COOKING, dairy.getExperience(), true); + break; + } + } + + return amount < 1; + } + +} diff --git a/Server/src/main/content/global/skill/cooking/dairy/DairyProduct.java b/Server/src/main/content/global/skill/cooking/dairy/DairyProduct.java new file mode 100644 index 0000000..0937601 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/dairy/DairyProduct.java @@ -0,0 +1,74 @@ +package content.global.skill.cooking.dairy; + +import java.util.Arrays; + +import core.game.node.item.Item; +import org.rs09.consts.Items; + +/** + * Represents an enumeration of dairy products. + * @author 'Vexia + */ +public enum DairyProduct { + POT_OF_CREAM(21, 18, new Item(Items.POT_OF_CREAM_2130, 1), new Integer[] { Items.BUCKET_OF_MILK_1927 }), + PAT_OF_BUTTER(38, 40.5, new Item(Items.PAT_OF_BUTTER_6697, 1), new Integer[] { Items.BUCKET_OF_MILK_1927, Items.POT_OF_CREAM_2130 }), + CHEESE(48, 64, new Item(Items.CHEESE_1985, 1), new Integer[] { Items.BUCKET_OF_MILK_1927, Items.POT_OF_CREAM_2130, Items.PAT_OF_BUTTER_6697 }); + + /** + * The prodct Item. + */ + private Item product; + + /** + * The level required. + */ + private int level; + + /** + * /** The experience gained. + */ + private double experience; + + /** + * The possible inputs for making this dairy product + */ + private Item[] inputs; + + /** + * Constructs a new {@code DairyProduct.java} {@code Object}. + * @param level + * @param experience + * @param product + */ + DairyProduct(int level, double experience, Item product, Integer[] inputs) { + this.level = level; + this.experience = experience; + this.product = product; + this.inputs = Arrays.stream(inputs).map(id -> new Item(id, 1)).toArray(len -> new Item[len]); + } + + /** + * @return the product. + */ + public Item getProduct() { + return product; + } + + /** + * @return the level. + */ + public int getLevel() { + return level; + } + + /** + * @return the experience. + */ + public double getExperience() { + return experience; + } + + public Item[] getInputs() { + return inputs; + } +} diff --git a/Server/src/main/content/global/skill/cooking/fermenting/WineFermentingPulse.java b/Server/src/main/content/global/skill/cooking/fermenting/WineFermentingPulse.java new file mode 100644 index 0000000..4f9dd7a --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/fermenting/WineFermentingPulse.java @@ -0,0 +1,80 @@ +package content.global.skill.cooking.fermenting; + +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.tools.RandomFunction; + +/** + * Represents a pulse used to ferment wine. + * @author 'Vexia + * @date 22/12/2013 + */ +public final class WineFermentingPulse extends Pulse { + + /** + * Represents the player instance. + */ + private final Player player; + + /** + * Represents a counter used to time when to ferment. + */ + private int count; + + /** + * Constructs a new {@code WineFermentingPulse} {@Code Object} + * @param delay the delay. + */ + public WineFermentingPulse(int delay, final Player player) { + super(delay); + this.player = player; + } + + @Override + public boolean pulse() { + if (count++ >= 16) { + int rand = RandomFunction.random(1, 3); + switch (rand) { + case 1: + if (player.getInventory().contains(1995, 1)) { + player.getInventory().replace(new Item(1991, 1), player.getInventory().getSlot(new Item(1995, 1))); + } else if (player.getBank().contains(1995, 1)) { + player.getBank().replace(new Item(1991, 1), player.getBank().getSlot(new Item(1995, 1))); + } + return true; + case 2: + if (player.getInventory().contains(1995, 1)) { + player.getInventory().replace(new Item(1993, 1), player.getInventory().getSlot(new Item(1995, 1))); + player.getSkills().addExperience(Skills.COOKING, 200, true); + } else if (player.getBank().contains(1995, 1)) { + player.getBank().replace(new Item(1993, 1), player.getBank().getSlot(new Item(1995, 1))); + player.getSkills().addExperience(Skills.COOKING, 200); + } + return true; + case 3: + if (player.getInventory().contains(1995, 1)) { + player.getInventory().replace(new Item(1993, 1), player.getInventory().getSlot(new Item(1995, 1))); + player.getSkills().addExperience(Skills.COOKING, 200); + } else if (player.getBank().contains(1995, 1)) { + player.getBank().replace(new Item(1993, 1), player.getBank().getSlot(new Item(1995, 1))); + player.getSkills().addExperience(Skills.COOKING, 200); + } + return true; + } + return true; + } + count++; + return false; + } + + /** + * Gets the player. + * @return the player. + */ + public Player getPlayer() { + return player; + } + +} diff --git a/Server/src/main/content/global/skill/cooking/recipe/HangoverRecipe.kt b/Server/src/main/content/global/skill/cooking/recipe/HangoverRecipe.kt new file mode 100644 index 0000000..063b85c --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/HangoverRecipe.kt @@ -0,0 +1,44 @@ +package content.global.skill.cooking.recipe + +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.skill.Skills +import org.rs09.consts.Items + +class HangoverRecipe : InteractionListener { + + companion object{ + private const val SNAPE_GRASS = Items.SNAPE_GRASS_231 + private const val HANGOVER_CURE = Items.HANGOVER_CURE_1504 + private const val BUCKET_OF_MILK = Items.BUCKET_OF_MILK_1927 + private const val CHOCOLATE_DUST = Items.CHOCOLATE_DUST_1975 + private const val CHOCOLATE_MILK = Items.CHOCOLATEY_MILK_1977 + } + + override fun defineListeners() { + onUseWith(IntType.ITEM, CHOCOLATE_DUST, BUCKET_OF_MILK) { player, _, _ -> + if(hasLevelDyn(player, Skills.COOKING, 4)){ + if(removeItem(player, CHOCOLATE_DUST) and removeItem(player, BUCKET_OF_MILK)){ + addItem(player, CHOCOLATE_MILK) + sendItemDialogue(player, CHOCOLATE_MILK, "You mix the chocolate into the bucket.") + } + } + else { + sendDialogue(player, "You need a Cooking level of at least 4 to make chocolate milk.") + } + return@onUseWith true + } + + onUseWith(IntType.ITEM, SNAPE_GRASS, CHOCOLATE_MILK) { player, _, _ -> + if (removeItem(player, SNAPE_GRASS) && removeItem(player, CHOCOLATE_MILK)) + { + sendItemDialogue(player, HANGOVER_CURE, "You mix the snape grass into the bucket.") + addItem(player, HANGOVER_CURE) + return@onUseWith true + } + return@onUseWith false + } + + } +} diff --git a/Server/src/main/content/global/skill/cooking/recipe/OomlieWrap.java b/Server/src/main/content/global/skill/cooking/recipe/OomlieWrap.java new file mode 100644 index 0000000..d5e8ee5 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/OomlieWrap.java @@ -0,0 +1,57 @@ +package content.global.skill.cooking.recipe; + +import org.rs09.consts.Items; +import core.game.node.entity.skill.Skills; +import core.game.interaction.NodeUsageEvent; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +/** + * @author afaroutdude + */ +public class OomlieWrap extends Recipe { + + private static final Item OOMLIE_WRAP = new Item(Items.WRAPPED_OOMLIE_2341); + private static final Item RAW_OOMLIE = new Item(Items.RAW_OOMLIE_2337); + private static final Item PALM_LEAF = new Item(Items.PALM_LEAF_2339); + + @Override + public void mix(final Player player, final NodeUsageEvent event) { + if (player.getSkills().getLevel(Skills.COOKING) < 50) { + player.getDialogueInterpreter().sendDialogue("You need a Cooking level of 50 in order to do that."); + return; + } + super.mix(player, event); + } + + @Override + public Item getBase() { + return RAW_OOMLIE; + } + + @Override + public Item getProduct() { + return OOMLIE_WRAP; + } + + @Override + public Item[] getIngredients() { + return new Item[] { PALM_LEAF }; + } + + @Override + public Item[] getParts() { + return new Item[] {}; + } + + @Override + public String getMixMessage(NodeUsageEvent event) { + return "You wrap the raw oomlie in the palm leaf."; + } + + @Override + public boolean isSingular() { + return true; + } + +} diff --git a/Server/src/main/content/global/skill/cooking/recipe/Recipe.java b/Server/src/main/content/global/skill/cooking/recipe/Recipe.java new file mode 100644 index 0000000..2402a97 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/Recipe.java @@ -0,0 +1,131 @@ +package content.global.skill.cooking.recipe; + +import content.global.skill.cooking.recipe.pie.impl.*; +import content.global.skill.cooking.recipe.pizza.impl.AnchovyPizza; +import content.global.skill.cooking.recipe.pizza.impl.MeatPizza; +import content.global.skill.cooking.recipe.pizza.impl.PineapplePizza; +import content.global.skill.cooking.recipe.pizza.impl.PlainPizza; +import content.global.skill.cooking.recipe.potato.impl.*; +import content.global.skill.cooking.recipe.stew.CurryRecipe; +import content.global.skill.cooking.recipe.stew.StewRecipe; +import content.global.skill.cooking.recipe.topping.impl.*; +import content.global.skill.cooking.recipe.cake.ChocolateCake; +import core.game.interaction.NodeUsageEvent; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +/** + * Represents a cooking recipe, this is dynamic that can range from a pie to a + * pizza. + * @author 'Vexia + * @date 21/12/2013 + */ +public abstract class Recipe { + + /** + * Represents the array of active recipes in 2009Scape. + */ + // TODO: + // - Making this an enum would drastically save on file/line count, since the recipes seem to mostly be plain-old-data classes + // - Making pie shells a recipe would make make-x for them just work + // - Making pineapple cutting a recipe would probably fix their make-x making all with any option + public static final Recipe[] RECIPES = new Recipe[] { + new RedberryPie(), new MeatPie(), new ApplePie(), new MudPie(), new GardenPie(), new FishPie(), new AdmiralPie(), new WildPie(), new SummerPie(), + new StewRecipe(), new CurryRecipe(), + new PlainPizza(), new MeatPizza(), new AnchovyPizza(), new PineapplePizza(), + new ChocolateCake(), + new ButterPotato(), new ChilliPotato(), new CheesePotato(), new EggPotato(), new MushroomPotato(), new TunaPotato(), + new SpicySauce(), new ChilliConCarne(), new UncookedEgg(), new EggAndTomato(), new MushroomAndOnion(), new ChoppedOnion(), new SlicedMushroom(), new ChoppedTuna(), new TunaAndCorn(), new OomlieWrap() + }; + + /** + * Method used to get the base item. + * @return the item. + */ + public abstract Item getBase(); + + /** + * Method used to get the product item. + * @return the product item. + */ + public abstract Item getProduct(); + + /** + * Method used to get the ingredients in this recipe. + * @return the ingredients. + */ + public abstract Item[] getIngredients(); + + /** + * Method used to get the part items made from ingredients. + * @return the part items. + */ + public abstract Item[] getParts(); + + /** + * Method used to get the mixing message. + * @param event the node usage event. + * @return the message used to mix. + */ + public abstract String getMixMessage(final NodeUsageEvent event); + + /** + * Method used to check if this is a singular one step recipe. + * @return True if so. + */ + public abstract boolean isSingular(); + + /** + * Method used to mix this recipes ingredients. + * @param player the player. + * @param event the event. + */ + public void mix(final Player player, final NodeUsageEvent event) { + if (getIngredients().length == 1) { + singleMix(player, event); + } else { + multipleMix(player, event); + } + } + + /** + * Method used to handle a single mixing. + * @param player the player. + * @param event the event. + */ + public void singleMix(final Player player, final NodeUsageEvent event) { + if (player.getInventory().remove(event.getBaseItem()) && player.getInventory().remove(event.getUsedItem())) { + player.getInventory().add(getProduct()); + String message = getMixMessage(event); + if (message != null) { + player.getPacketDispatch().sendMessage(message); + } + } + } + + /** + * Method used to handle mixing multiple item recipes. + * @param player the player. + * @param event the event. + */ + public void multipleMix(final Player player, final NodeUsageEvent event) { + Item item = null; + int index = -1; + for (int counter = 0; counter < getIngredients().length; counter++) { + item = getIngredients()[counter]; + if (item.getId() == event.getUsedItem().getId() || item.getId() == event.getBaseItem().getId()) { + index = counter; + break; + } + } + if (index != -1) { + if (player.getInventory().remove(event.getBaseItem()) && player.getInventory().remove(event.getUsedItem())) { + player.getInventory().add(getParts()[index + 1]); + String message = getMixMessage(event); + if (message != null) { + player.getPacketDispatch().sendMessage(message); + } + } + } + } +} diff --git a/Server/src/main/content/global/skill/cooking/recipe/cake/ChocolateCake.java b/Server/src/main/content/global/skill/cooking/recipe/cake/ChocolateCake.java new file mode 100644 index 0000000..97ef11d --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/cake/ChocolateCake.java @@ -0,0 +1,72 @@ +package content.global.skill.cooking.recipe.cake; + +import content.global.skill.cooking.recipe.Recipe; +import core.game.node.entity.skill.Skills; +import core.game.interaction.NodeUsageEvent; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +/** + * Represents the chocolate cake recipe. This recipe consists of adding a + * chocolate bar to a cake. + * @author 'Vexia + * @date 22/12/2013 + */ +public class ChocolateCake extends Recipe { + + /** + * Represents the cake item. + */ + private static final Item CAKE = new Item(1891); + + /** + * Represents the chocolate cake item. + */ + private static final Item CHOCOLATE_CAKE = new Item(1897); + + /** + * Represents the chocolate bar item. + */ + private static final Item CHOCOLATE_BAR = new Item(1973); + + @Override + public void mix(final Player player, final NodeUsageEvent event) { + if (player.getSkills().getLevel(Skills.COOKING) < 50) { + player.getDialogueInterpreter().sendDialogue("You need a Cooking level of 50 in order to do that."); + return; + } + super.mix(player, event); + player.getSkills().addExperience(Skills.COOKING, 30, true); + } + + @Override + public Item getBase() { + return CAKE; + } + + @Override + public Item getProduct() { + return CHOCOLATE_CAKE; + } + + @Override + public Item[] getIngredients() { + return new Item[] { CHOCOLATE_BAR }; + } + + @Override + public Item[] getParts() { + return new Item[] {}; + } + + @Override + public String getMixMessage(NodeUsageEvent event) { + return "You add chocolate to the cake."; + } + + @Override + public boolean isSingular() { + return true; + } + +} diff --git a/Server/src/main/content/global/skill/cooking/recipe/pie/PieRecipe.java b/Server/src/main/content/global/skill/cooking/recipe/pie/PieRecipe.java new file mode 100644 index 0000000..878a333 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/pie/PieRecipe.java @@ -0,0 +1,38 @@ +package content.global.skill.cooking.recipe.pie; + +import content.global.skill.cooking.recipe.Recipe; +import core.game.interaction.NodeUsageEvent; +import core.game.node.item.Item; + +/** + * Represents the generic recipe for a pie. + * @author 'Vexia + * @date 21/12/2013 + */ +public abstract class PieRecipe extends Recipe { + + /** + * Represents the pie shell item. + */ + protected static final Item PIE_SHELL = new Item(2315); + + @Override + public Item[] getParts() { + return new Item[] {}; + } + + @Override + public Item getBase() { + return PIE_SHELL; + } + + @Override + public String getMixMessage(final NodeUsageEvent event) { + return "You fill the pie with " + (event.getBaseItem().getId() == 2315 ? event.getUsedItem().getName().toLowerCase() : event.getBaseItem().getName().toLowerCase()) + "."; + } + + @Override + public boolean isSingular() { + return true; + } +} diff --git a/Server/src/main/content/global/skill/cooking/recipe/pie/impl/AdmiralPie.java b/Server/src/main/content/global/skill/cooking/recipe/pie/impl/AdmiralPie.java new file mode 100644 index 0000000..9cc6a98 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/pie/impl/AdmiralPie.java @@ -0,0 +1,64 @@ +package content.global.skill.cooking.recipe.pie.impl; + +import content.global.skill.cooking.recipe.pie.PieRecipe; +import core.game.node.item.Item; + +/** + * Represents the admiral pie recipe. This recipe conists of pixing a salmon, + * tuna and potato together. + * @author 'Vexia + * @date 21/12/2013 + */ +public class AdmiralPie extends PieRecipe { + + /** + * Represents the uncooked redberry pie. + */ + private static final Item UNCOOKED_PIE = new Item(7196); + + /** + * Represents the salmon ingredient item. + */ + private static final Item SALMON = new Item(329); + + /** + * Represents the tuna ingredient item. + */ + private static final Item TUNA = new Item(361); + + /** + * Represents the potato item. + */ + private static final Item POTATO = new Item(1942); + + /** + * Represents the part one pie item. + */ + private static final Item PART_ONE = new Item(7192); + + /** + * Represents the part two pie item. + */ + private static final Item PART_TWO = new Item(7194); + + @Override + public Item getProduct() { + return UNCOOKED_PIE; + } + + @Override + public Item[] getIngredients() { + return new Item[] { SALMON, TUNA, POTATO }; + } + + @Override + public Item[] getParts() { + return new Item[] { PIE_SHELL, PART_ONE, PART_TWO, UNCOOKED_PIE }; + } + + @Override + public boolean isSingular() { + return false; + } + +} diff --git a/Server/src/main/content/global/skill/cooking/recipe/pie/impl/ApplePie.java b/Server/src/main/content/global/skill/cooking/recipe/pie/impl/ApplePie.java new file mode 100644 index 0000000..e449174 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/pie/impl/ApplePie.java @@ -0,0 +1,34 @@ +package content.global.skill.cooking.recipe.pie.impl; + +import content.global.skill.cooking.recipe.pie.PieRecipe; +import core.game.node.item.Item; + +/** + * Represents the apple pie recipe. This recipe consists of cooking apples and a + * pie shell. + * @author 'Vexia + * @date 21/12/2013 + */ +public class ApplePie extends PieRecipe { + + /** + * Represents the uncooked redberry pie. + */ + private static final Item UNCOOKED_PIE = new Item(2317); + + /** + * Represents the cooking apple item. + */ + private static final Item COOKING_APPLE = new Item(1955); + + @Override + public Item getProduct() { + return UNCOOKED_PIE; + } + + @Override + public Item[] getIngredients() { + return new Item[] { COOKING_APPLE }; + } + +} diff --git a/Server/src/main/content/global/skill/cooking/recipe/pie/impl/FishPie.java b/Server/src/main/content/global/skill/cooking/recipe/pie/impl/FishPie.java new file mode 100644 index 0000000..7a1dad0 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/pie/impl/FishPie.java @@ -0,0 +1,64 @@ +package content.global.skill.cooking.recipe.pie.impl; + +import content.global.skill.cooking.recipe.pie.PieRecipe; +import core.game.node.item.Item; + +/** + * Represents the garden pie recipe. This pie consists of mixing, tomato, onion, + * and cabbage together. + * @author 'Vexia + * @date 21/12/2013 + */ +public class FishPie extends PieRecipe { + + /** + * Represents the uncooked redberry pie. + */ + private static final Item UNCOOKED_PIE = new Item(7186); + + /** + * Represents the trout item ingredient. + */ + private static final Item TROUT = new Item(333); + + /** + * Represents the cod item ingredient. + */ + private static final Item COD = new Item(339); + + /** + * Represents the potato item. + */ + private static final Item POTATO = new Item(1942); + + /** + * Represents the part one pie item. + */ + private static final Item PART_ONE = new Item(7182); + + /** + * Represents the part two pie item. + */ + private static final Item PART_TWO = new Item(7184); + + @Override + public Item getProduct() { + return UNCOOKED_PIE; + } + + @Override + public Item[] getIngredients() { + return new Item[] { TROUT, COD, POTATO }; + } + + @Override + public Item[] getParts() { + return new Item[] { PIE_SHELL, PART_ONE, PART_TWO, UNCOOKED_PIE }; + } + + @Override + public boolean isSingular() { + return false; + } + +} diff --git a/Server/src/main/content/global/skill/cooking/recipe/pie/impl/GardenPie.java b/Server/src/main/content/global/skill/cooking/recipe/pie/impl/GardenPie.java new file mode 100644 index 0000000..90fbe7e --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/pie/impl/GardenPie.java @@ -0,0 +1,64 @@ +package content.global.skill.cooking.recipe.pie.impl; + +import content.global.skill.cooking.recipe.pie.PieRecipe; +import core.game.node.item.Item; + +/** + * Represents the garden pie recipe. This pie consists of mixing, tomato, onion, + * and cabbage together. + * @author 'Vexia + * @date 21/12/2013 + */ +public class GardenPie extends PieRecipe { + + /** + * Represents the uncooked redberry pie. + */ + private static final Item UNCOOKED_PIE = new Item(7176); + + /** + * Represents the tomato ingredient item. + */ + private static final Item TOMATO = new Item(1982); + + /** + * Represents the onion ingredient item. + */ + private static final Item ONION = new Item(1957); + + /** + * Represents the cabbage ingredient item. + */ + private static final Item CABBAGE = new Item(1965); + + /** + * Represents the part one pie item. + */ + private static final Item PART_ONE = new Item(7172); + + /** + * Represents the part two pie item. + */ + private static final Item PART_TWO = new Item(7174); + + @Override + public Item getProduct() { + return UNCOOKED_PIE; + } + + @Override + public Item[] getIngredients() { + return new Item[] { TOMATO, ONION, CABBAGE }; + } + + @Override + public Item[] getParts() { + return new Item[] { PIE_SHELL, PART_ONE, PART_TWO, UNCOOKED_PIE }; + } + + @Override + public boolean isSingular() { + return false; + } + +} diff --git a/Server/src/main/content/global/skill/cooking/recipe/pie/impl/MeatPie.java b/Server/src/main/content/global/skill/cooking/recipe/pie/impl/MeatPie.java new file mode 100644 index 0000000..1edb223 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/pie/impl/MeatPie.java @@ -0,0 +1,58 @@ +package content.global.skill.cooking.recipe.pie.impl; + +import content.global.skill.cooking.recipe.pie.PieRecipe; +import core.game.interaction.NodeUsageEvent; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +/** + * Represents the meat pie recipe. + * @author 'Vexia + * @date 21/12/2013 + */ +public class MeatPie extends PieRecipe { + + /** + * Represents the uncooked redberry pie. + */ + private static final Item UNCOOKED_PIE = new Item(2319); + + /** + * Represents the cooked meat item. + */ + private static final Item COOKED_MEAT = new Item(2142); + + /** + * Represents the cooked chicken item. + */ + private static final Item COOKED_CHICKEN = new Item(2140); + + /** + * Represents the cooked rabbit. + */ + private static final Item COOKED_RABBIT = new Item(3228); + + @Override + public void mix(final Player player, final NodeUsageEvent event) { + if (player.getInventory().remove(event.getUsedItem()) && player.getInventory().remove(event.getBaseItem())) { + player.getInventory().add(getProduct()); + player.getPacketDispatch().sendMessage(getMixMessage(event)); + return; + } + } + + @Override + public Item getProduct() { + return UNCOOKED_PIE; + } + + @Override + public Item[] getIngredients() { + return new Item[] { COOKED_MEAT, COOKED_CHICKEN, COOKED_RABBIT }; + } + + @Override + public String getMixMessage(final NodeUsageEvent event) { + return "You fill the pie with meat."; + } +} diff --git a/Server/src/main/content/global/skill/cooking/recipe/pie/impl/MudPie.java b/Server/src/main/content/global/skill/cooking/recipe/pie/impl/MudPie.java new file mode 100644 index 0000000..64a542f --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/pie/impl/MudPie.java @@ -0,0 +1,64 @@ +package content.global.skill.cooking.recipe.pie.impl; + +import content.global.skill.cooking.recipe.pie.PieRecipe; +import core.game.node.item.Item; + +/** + * Represents the mud pie recipe. A mud pie consists of mixing compost, water + * and clay together. + * @author 'Vexia + * @date 21/12/2013 + */ +public class MudPie extends PieRecipe { + + /** + * Represents the uncooked redberry pie. + */ + private static final Item UNCOOKED_PIE = new Item(7168); + + /** + * Represents the compost item. + */ + private static final Item COMPOST = new Item(6032); + + /** + * Represents the bucket of water item. + */ + private static final Item BUCKET_OF_WATER = new Item(1929); + + /** + * Represents the clay item. + */ + private static final Item CLAY = new Item(434); + + /** + * Represents the part one pie item. + */ + private static final Item PART_ONE = new Item(7164); + + /** + * Represents the part two pie item. + */ + private static final Item PART_TWO = new Item(7166); + + @Override + public Item getProduct() { + return UNCOOKED_PIE; + } + + @Override + public Item[] getIngredients() { + return new Item[] { COMPOST, BUCKET_OF_WATER, CLAY }; + } + + @Override + public Item[] getParts() { + return new Item[] { PIE_SHELL, PART_ONE, PART_TWO, UNCOOKED_PIE }; + } + + @Override + public boolean isSingular() { + return false; + } + +} diff --git a/Server/src/main/content/global/skill/cooking/recipe/pie/impl/RedberryPie.java b/Server/src/main/content/global/skill/cooking/recipe/pie/impl/RedberryPie.java new file mode 100644 index 0000000..6ebbd04 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/pie/impl/RedberryPie.java @@ -0,0 +1,33 @@ +package content.global.skill.cooking.recipe.pie.impl; + +import content.global.skill.cooking.recipe.pie.PieRecipe; +import core.game.node.item.Item; + +/** + * Represents a redberry pie recipe. + * @author 'Vexia + * @date 21/12/2013 + */ +public class RedberryPie extends PieRecipe { + + /** + * Represents the uncooked redberry pie. + */ + private static final Item UNCOOKED_PIE = new Item(2321); + + /** + * Represents the redberries pie. + */ + private static final Item REDBERRIES = new Item(1951); + + @Override + public Item getProduct() { + return UNCOOKED_PIE; + } + + @Override + public Item[] getIngredients() { + return new Item[] { REDBERRIES }; + } + +} diff --git a/Server/src/main/content/global/skill/cooking/recipe/pie/impl/SummerPie.java b/Server/src/main/content/global/skill/cooking/recipe/pie/impl/SummerPie.java new file mode 100644 index 0000000..1499685 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/pie/impl/SummerPie.java @@ -0,0 +1,64 @@ +package content.global.skill.cooking.recipe.pie.impl; + +import content.global.skill.cooking.recipe.pie.PieRecipe; +import core.game.node.item.Item; + +/** + * Represents the summer pie recipe. This recipe consists of mixing stawberry, + * watermelon, and an apple. + * @author 'Vexia + * @date 21/12/2013 + */ +public class SummerPie extends PieRecipe { + + /** + * Represents the uncooked redberry pie. + */ + private static final Item UNCOOKED_PIE = new Item(7216); + + /** + * Represents the strawberry item. + */ + private static final Item STRAWBERRY = new Item(5504); + + /** + * Represents the watermelon item. + */ + private static final Item WATERMELON = new Item(5982); + + /** + * Represents the cooking apple item. + */ + private static final Item COOKING_APPLE = new Item(1955); + + /** + * Represents the part one pie item. + */ + private static final Item PART_ONE = new Item(7212); + + /** + * Represents the part two pie item. + */ + private static final Item PART_TWO = new Item(7214); + + @Override + public Item getProduct() { + return UNCOOKED_PIE; + } + + @Override + public Item[] getIngredients() { + return new Item[] { STRAWBERRY, WATERMELON, COOKING_APPLE }; + } + + @Override + public Item[] getParts() { + return new Item[] { PIE_SHELL, PART_ONE, PART_TWO, UNCOOKED_PIE }; + } + + @Override + public boolean isSingular() { + return false; + } + +} diff --git a/Server/src/main/content/global/skill/cooking/recipe/pie/impl/WildPie.java b/Server/src/main/content/global/skill/cooking/recipe/pie/impl/WildPie.java new file mode 100644 index 0000000..3b4deca --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/pie/impl/WildPie.java @@ -0,0 +1,64 @@ +package content.global.skill.cooking.recipe.pie.impl; + +import content.global.skill.cooking.recipe.pie.PieRecipe; +import core.game.node.item.Item; + +/** + * Represents the wild pie recipe. This recipe consists of mixing raw beat meat, + * raw chomp, and raw rabbit into a pie shell. + * @author 'Vexia + * @date 21/12/2013 + */ +public class WildPie extends PieRecipe { + + /** + * Represents the uncooked redberry pie. + */ + private static final Item UNCOOKED_PIE = new Item(7206); + + /** + * Represents the raw bear meat item. + */ + private static final Item BEAR_MEAT = new Item(2136); + + /** + * Represents the raw chompy meat item. + */ + private static final Item CHOMPY_MEAT = new Item(2876); + + /** + * Represents the raw rabbit meat item. + */ + private static final Item RABBIT_MEAT = new Item(3226); + + /** + * Represents the part one pie item. + */ + private static final Item PART_ONE = new Item(7202); + + /** + * Represents the part two pie item. + */ + private static final Item PART_TWO = new Item(7204); + + @Override + public Item getProduct() { + return UNCOOKED_PIE; + } + + @Override + public Item[] getIngredients() { + return new Item[] { BEAR_MEAT, CHOMPY_MEAT, RABBIT_MEAT }; + } + + @Override + public Item[] getParts() { + return new Item[] { PIE_SHELL, PART_ONE, PART_TWO, UNCOOKED_PIE }; + } + + @Override + public boolean isSingular() { + return false; + } + +} diff --git a/Server/src/main/content/global/skill/cooking/recipe/pizza/PizzaRecipe.java b/Server/src/main/content/global/skill/cooking/recipe/pizza/PizzaRecipe.java new file mode 100644 index 0000000..5a1385a --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/pizza/PizzaRecipe.java @@ -0,0 +1,63 @@ +package content.global.skill.cooking.recipe.pizza; + +import core.game.node.entity.skill.Skills; +import content.global.skill.cooking.recipe.Recipe; +import core.game.interaction.NodeUsageEvent; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +/** + * Represents the generic recipe for a pizza. + * @author ceikry + */ +public abstract class PizzaRecipe extends Recipe { + + /** + * Represents the plain pizza. + */ + protected static final Item PLAIN_PIZZA = new Item(2289); + + /** + * Method used to get the experience gained from adding the final + * ingredient. + * @return the experience. + */ + public abstract double getExperience(); + + /** + * Method used to get the level required. + * @return the level required. + */ + public abstract int getLevel(); + + @Override + public void mix(final Player player, final NodeUsageEvent event) { + if (player.getSkills().getLevel(Skills.COOKING) < getLevel()) { + player.getDialogueInterpreter().sendDialogue("You need a Cooking level of at least " + getLevel() + " in order to do this."); + return; + } + super.singleMix(player, event); + player.getSkills().addExperience(Skills.COOKING, getExperience(), true); + } + + @Override + public Item[] getParts() { + return new Item[] {}; + } + + @Override + public Item getBase() { + return PLAIN_PIZZA; + } + + @Override + public String getMixMessage(final NodeUsageEvent event) { + return "You add " + event.getBaseItem().getName().toLowerCase() + " to the pizza."; + } + + @Override + public boolean isSingular() { + return true; + } + +} diff --git a/Server/src/main/content/global/skill/cooking/recipe/pizza/impl/AnchovyPizza.java b/Server/src/main/content/global/skill/cooking/recipe/pizza/impl/AnchovyPizza.java new file mode 100644 index 0000000..4a70625 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/pizza/impl/AnchovyPizza.java @@ -0,0 +1,44 @@ +package content.global.skill.cooking.recipe.pizza.impl; + +import content.global.skill.cooking.recipe.pizza.PizzaRecipe; +import core.game.node.item.Item; + +/** + * Represents the anchovy pizza. This recipe consists of adding anchovies to a + * plain pizza. + * @author 'Vexia + * @date 22/12/2013 + */ +public class AnchovyPizza extends PizzaRecipe { + + /** + * Represents the anchovy pizza item. + */ + private static final Item ANCHOVY_PIZZA = new Item(2297); + + /** + * Represents the anchovies item. + */ + private static final Item ANCHOVIES = new Item(319); + + @Override + public double getExperience() { + return 39; + } + + @Override + public Item getProduct() { + return ANCHOVY_PIZZA; + } + + @Override + public Item[] getIngredients() { + return new Item[] { ANCHOVIES }; + } + + @Override + public int getLevel() { + return 55; + } + +} diff --git a/Server/src/main/content/global/skill/cooking/recipe/pizza/impl/MeatPizza.java b/Server/src/main/content/global/skill/cooking/recipe/pizza/impl/MeatPizza.java new file mode 100644 index 0000000..b790961 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/pizza/impl/MeatPizza.java @@ -0,0 +1,49 @@ +package content.global.skill.cooking.recipe.pizza.impl; + +import content.global.skill.cooking.recipe.pizza.PizzaRecipe; +import core.game.node.item.Item; + +/** + * Represents the meat pizza recipe. This recipe consists of adding cooked meat + * to a plain pizza. + * @author 'Vexia + * @date 22/12/2013 + */ +public class MeatPizza extends PizzaRecipe { + + /** + * Represents the meat pizza item. + */ + private static final Item MEAT_PIZZA = new Item(2293); + + /** + * Represents the cooked meat item. + */ + private static final Item COOKED_MEAT = new Item(2142); + + /** + * Represents the cooked chicken item. + */ + private static final Item COOKED_CHICKEN = new Item(2140); + + @Override + public double getExperience() { + return 26; + } + + @Override + public int getLevel() { + return 45; + } + + @Override + public Item getProduct() { + return MEAT_PIZZA; + } + + @Override + public Item[] getIngredients() { + return new Item[] { COOKED_MEAT, COOKED_CHICKEN }; + } + +} diff --git a/Server/src/main/content/global/skill/cooking/recipe/pizza/impl/PineapplePizza.java b/Server/src/main/content/global/skill/cooking/recipe/pizza/impl/PineapplePizza.java new file mode 100644 index 0000000..7e4746e --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/pizza/impl/PineapplePizza.java @@ -0,0 +1,55 @@ +package content.global.skill.cooking.recipe.pizza.impl; + +import content.global.skill.cooking.recipe.pizza.PizzaRecipe; +import core.game.interaction.NodeUsageEvent; +import core.game.node.item.Item; + +/** + * Represents the pineapple pizza recipe. This recipe consists of mixing either + * pineapple chunks or pineapple rings. + * @author 'Vexia + * @date 22/12/2013 + */ +public class PineapplePizza extends PizzaRecipe { + + /** + * Represents the pineapple pizza item. + */ + private static final Item PINEAPPLE_PIZZA = new Item(2301); + + /** + * Represents the pineapple ring item. + */ + private static final Item PINEAPPLE_RING = new Item(2118); + + /** + * Represents the pineapple chunk item. + */ + private static final Item PINEAPPLE_CHUNKS = new Item(2116); + + @Override + public double getExperience() { + return 52; + } + + @Override + public int getLevel() { + return 65; + } + + @Override + public Item getProduct() { + return PINEAPPLE_PIZZA; + } + + @Override + public Item[] getIngredients() { + return new Item[] { PINEAPPLE_CHUNKS, PINEAPPLE_RING }; + } + + @Override + public String getMixMessage(NodeUsageEvent event) { + return "You add the " + event.getBaseItem().getName().toLowerCase() + " to the pizza."; + } + +} diff --git a/Server/src/main/content/global/skill/cooking/recipe/pizza/impl/PlainPizza.java b/Server/src/main/content/global/skill/cooking/recipe/pizza/impl/PlainPizza.java new file mode 100644 index 0000000..8d624dc --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/pizza/impl/PlainPizza.java @@ -0,0 +1,81 @@ +package content.global.skill.cooking.recipe.pizza.impl; + +import core.game.node.entity.skill.Skills; +import content.global.skill.cooking.recipe.Recipe; +import core.game.interaction.NodeUsageEvent; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +/** + * Represents the plain pizza recipe. This recipe consists of mixing tomato, and + * cheese to a pizza base. + * @author 'Vexia + * @date 22/12/2013 + */ +public class PlainPizza extends Recipe { + + /** + * Represents the pizza base. + */ + private static final Item PIZZA_BASE = new Item(2283); + + /** + * Represents the uncooked pizza. + */ + private static final Item UNCOOKED_PIZZA = new Item(2287); + + /** + * Represents the incomplete pizza. + */ + private static final Item INCOMPLETE_PIZZA = new Item(2285); + + /** + * Represents the tomato ingredient item. + */ + private static final Item TOMATO = new Item(1982); + + /** + * Represents the cheese item. + */ + private static final Item CHEESE = new Item(1985); + + @Override + public void mix(final Player player, final NodeUsageEvent event) { + if (player.getSkills().getLevel(Skills.COOKING) < 35) { + player.getDialogueInterpreter().sendDialogue("You need a Cooking level of at least " + 35 + " in order to do this."); + return; + } + super.mix(player, event); + } + + @Override + public Item getBase() { + return PIZZA_BASE; + } + + @Override + public Item getProduct() { + return UNCOOKED_PIZZA; + } + + @Override + public Item[] getIngredients() { + return new Item[] { TOMATO, CHEESE }; + } + + @Override + public Item[] getParts() { + return new Item[] { PIZZA_BASE, INCOMPLETE_PIZZA, UNCOOKED_PIZZA }; + } + + @Override + public String getMixMessage(NodeUsageEvent event) { + return "You add the " + event.getBaseItem().getName().toLowerCase() + " to the pizza."; + } + + @Override + public boolean isSingular() { + return false; + } + +} diff --git a/Server/src/main/content/global/skill/cooking/recipe/potato/PotatoRecipe.java b/Server/src/main/content/global/skill/cooking/recipe/potato/PotatoRecipe.java new file mode 100644 index 0000000..c2640a8 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/potato/PotatoRecipe.java @@ -0,0 +1,76 @@ +package content.global.skill.cooking.recipe.potato; + +import core.game.node.entity.skill.Skills; +import content.global.skill.cooking.recipe.Recipe; +import core.game.interaction.NodeUsageEvent; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +/** + * Represents a generic potato topping recipe. + * @author 'Vexia + * @date 22/12/2013 + */ +public abstract class PotatoRecipe extends Recipe { + + /** + * Represents the potato with butter. + */ + private static final Item POTATO_WITH_BUTTER = new Item(6703); + + /** + * Represents the bowl item. + */ + protected static final Item BOWL = new Item(1923); + + @Override + public void mix(final Player player, final NodeUsageEvent event) { + if (player.getSkills().getLevel(Skills.COOKING) < getLevel()) { + player.getDialogueInterpreter().sendDialogue("You need a Cooking level of at least " + getLevel() + " in order to do this."); + return; + } + super.singleMix(player, event); + if (isTopping()) { + player.getInventory().add(BOWL); + } + player.getSkills().addExperience(Skills.COOKING, getExperience(), true); + } + + @Override + public Item getBase() { + return POTATO_WITH_BUTTER; + } + + @Override + public Item[] getParts() { + return new Item[] {}; + } + + @Override + public String getMixMessage(NodeUsageEvent event) { + return null; + } + + @Override + public boolean isSingular() { + return true; + } + + /** + * Method used to check if it is a topping recipe. + * @return True if it is a topping. + */ + public abstract boolean isTopping(); + + /** + * Method used to get the level required. + * @return the level. + */ + public abstract int getLevel(); + + /** + * Method used to get the experience gained. + * @return the experience. + */ + public abstract double getExperience(); +} diff --git a/Server/src/main/content/global/skill/cooking/recipe/potato/impl/ButterPotato.java b/Server/src/main/content/global/skill/cooking/recipe/potato/impl/ButterPotato.java new file mode 100644 index 0000000..b382a50 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/potato/impl/ButterPotato.java @@ -0,0 +1,72 @@ +package content.global.skill.cooking.recipe.potato.impl; + +import content.global.skill.cooking.recipe.Recipe; +import core.game.node.entity.skill.Skills; +import core.game.interaction.NodeUsageEvent; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +/** + * Represents the butter potato recipe. This recipe consists of adding a pat of + * butter to a potato. + * @author 'Vexia + * @date 22/12/2013 + */ +public class ButterPotato extends Recipe { + + /** + * Represents the baked potato. + */ + private static final Item BAKED_POTATO = new Item(6701); + + /** + * Represents the potato with butter. + */ + private static final Item POTATO_WITH_BUTTER = new Item(6703); + + /** + * Represents the pat of butter. + */ + private static final Item PAT_OF_BUTTER = new Item(6697); + + @Override + public void mix(final Player player, final NodeUsageEvent event) { + if (player.getSkills().getLevel(Skills.COOKING) < 39) { + player.getDialogueInterpreter().sendDialogue("You need a Cooking level of at least " + 39 + " in order to do this."); + return; + } + super.singleMix(player, event); + player.getSkills().addExperience(Skills.COOKING, 40.5, true); + } + + @Override + public Item getBase() { + return BAKED_POTATO; + } + + @Override + public Item getProduct() { + return POTATO_WITH_BUTTER; + } + + @Override + public Item[] getIngredients() { + return new Item[] { PAT_OF_BUTTER }; + } + + @Override + public Item[] getParts() { + return new Item[] {}; + } + + @Override + public String getMixMessage(NodeUsageEvent event) { + return "You add a pat of butter to the potato."; + } + + @Override + public boolean isSingular() { + return true; + } + +} diff --git a/Server/src/main/content/global/skill/cooking/recipe/potato/impl/CheesePotato.java b/Server/src/main/content/global/skill/cooking/recipe/potato/impl/CheesePotato.java new file mode 100644 index 0000000..f111ed9 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/potato/impl/CheesePotato.java @@ -0,0 +1,49 @@ +package content.global.skill.cooking.recipe.potato.impl; + +import content.global.skill.cooking.recipe.potato.PotatoRecipe; +import core.game.node.item.Item; + +/** + * Represents the cheese potato. This recipe consists of mixing cheese witha + * baked potato. + * @author 'Vexia + * @date 22/12/2013 + */ +public class CheesePotato extends PotatoRecipe { + + /** + * Represents the cheese potato. + */ + private static final Item CHEESE_POTATO = new Item(6705); + + /** + * Represents the cheese item. + */ + private static final Item CHEESE = new Item(1985); + + @Override + public Item getProduct() { + return CHEESE_POTATO; + } + + @Override + public Item[] getIngredients() { + return new Item[] { CHEESE }; + } + + @Override + public boolean isTopping() { + return false; + } + + @Override + public int getLevel() { + return 47; + } + + @Override + public double getExperience() { + return 10; + } + +} diff --git a/Server/src/main/content/global/skill/cooking/recipe/potato/impl/ChilliPotato.java b/Server/src/main/content/global/skill/cooking/recipe/potato/impl/ChilliPotato.java new file mode 100644 index 0000000..88c5ed1 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/potato/impl/ChilliPotato.java @@ -0,0 +1,49 @@ +package content.global.skill.cooking.recipe.potato.impl; + +import content.global.skill.cooking.recipe.potato.PotatoRecipe; +import core.game.node.item.Item; + +/** + * Represents the chilli potato recipe. This recipe consists of adding chilli + * con carne to a baked butter potato. + * @author 'Vexia + * @date 22/12/2013 + */ +public class ChilliPotato extends PotatoRecipe { + + /** + * Represents the chilli potato item. + */ + private static final Item CHILLI_POTATO = new Item(7054); + + /** + * Represents the chilli con carne item/ + */ + private static final Item CHILLI_CON_CARNE = new Item(7062); + + @Override + public Item getProduct() { + return CHILLI_POTATO; + } + + @Override + public Item[] getIngredients() { + return new Item[] { CHILLI_CON_CARNE }; + } + + @Override + public boolean isTopping() { + return true; + } + + @Override + public int getLevel() { + return 41; + } + + @Override + public double getExperience() { + return 10; + } + +} diff --git a/Server/src/main/content/global/skill/cooking/recipe/potato/impl/EggPotato.java b/Server/src/main/content/global/skill/cooking/recipe/potato/impl/EggPotato.java new file mode 100644 index 0000000..c616591 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/potato/impl/EggPotato.java @@ -0,0 +1,49 @@ +package content.global.skill.cooking.recipe.potato.impl; + +import content.global.skill.cooking.recipe.potato.PotatoRecipe; +import core.game.node.item.Item; + +/** + * Represents the egg potato recipe. This recipe consists of mixing a egg and a + * tomato. + * @author 'Vexia + * @date 22/12/2013 + */ +public class EggPotato extends PotatoRecipe { + + /** + * Represents the egg potato. + */ + private static final Item EGG_POTATO = new Item(7056); + + /** + * Represents the topping item. + */ + private static final Item TOPPING = new Item(7064); + + @Override + public Item getProduct() { + return EGG_POTATO; + } + + @Override + public Item[] getIngredients() { + return new Item[] { TOPPING }; + } + + @Override + public boolean isTopping() { + return true; + } + + @Override + public int getLevel() { + return 51; + } + + @Override + public double getExperience() { + return 10; + } + +} diff --git a/Server/src/main/content/global/skill/cooking/recipe/potato/impl/MushroomPotato.java b/Server/src/main/content/global/skill/cooking/recipe/potato/impl/MushroomPotato.java new file mode 100644 index 0000000..d7bfa1c --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/potato/impl/MushroomPotato.java @@ -0,0 +1,49 @@ +package content.global.skill.cooking.recipe.potato.impl; + +import content.global.skill.cooking.recipe.potato.PotatoRecipe; +import core.game.node.item.Item; + +/** + * Represents the mushrrom potato. This recipe consists of mixing a baked potato + * with mushroom and onion toppings. + * @author 'Vexia + * @date 22/12/2013 + */ +public class MushroomPotato extends PotatoRecipe { + + /** + * Represents the egg potato. + */ + private static final Item MUSHROOM_POTATO = new Item(7058); + + /** + * Represents the topping item. + */ + private static final Item TOPPING = new Item(7066); + + @Override + public Item getProduct() { + return MUSHROOM_POTATO; + } + + @Override + public Item[] getIngredients() { + return new Item[] { TOPPING }; + } + + @Override + public boolean isTopping() { + return true; + } + + @Override + public int getLevel() { + return 64; + } + + @Override + public double getExperience() { + return 10; + } + +} diff --git a/Server/src/main/content/global/skill/cooking/recipe/potato/impl/TunaPotato.java b/Server/src/main/content/global/skill/cooking/recipe/potato/impl/TunaPotato.java new file mode 100644 index 0000000..645d5ed --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/potato/impl/TunaPotato.java @@ -0,0 +1,49 @@ +package content.global.skill.cooking.recipe.potato.impl; + +import content.global.skill.cooking.recipe.potato.PotatoRecipe; +import core.game.node.item.Item; + +/** + * Represents the tuna potato recipe. This recipe consists of mixing tuna and + * corn toppings. + * @author 'Vexia + * @date 22/12/2013 + */ +public class TunaPotato extends PotatoRecipe { + + /** + * Represents the tuna potato. + */ + private static final Item TUNA_POTATO = new Item(7060); + + /** + * Represents the topping item. + */ + private static final Item TOPPING = new Item(7068); + + @Override + public Item getProduct() { + return TUNA_POTATO; + } + + @Override + public Item[] getIngredients() { + return new Item[] { TOPPING }; + } + + @Override + public boolean isTopping() { + return true; + } + + @Override + public int getLevel() { + return 68; + } + + @Override + public double getExperience() { + return 10; + } + +} diff --git a/Server/src/main/content/global/skill/cooking/recipe/stew/CurryRecipe.java b/Server/src/main/content/global/skill/cooking/recipe/stew/CurryRecipe.java new file mode 100644 index 0000000..4ea7882 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/stew/CurryRecipe.java @@ -0,0 +1,89 @@ +package content.global.skill.cooking.recipe.stew; + +import content.global.skill.cooking.recipe.Recipe; +import core.game.interaction.NodeUsageEvent; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +/** + * Represents the curry recipe. This recipe consists of mixing 3 curry leaves or + * a spice into a stew. + * @author 'Vexia + * @date 22/12/2013 + */ +public class CurryRecipe extends Recipe { + + /** + * Represents the uncooked curry item. + */ + private static final Item UNCOOKED_CURRY = new Item(2009); + + /** + * Represents the uncooked stew item. + */ + private static final Item UNCOOKED_STEW = new Item(2001); + + /** + * Represents the spice item. + */ + private static final Item SPICE = new Item(2007); + + /** + * Represents the curry leaf. + */ + private static final Item CURRY_LEAF = new Item(5970); + + @Override + public void mix(Player player, NodeUsageEvent event) { + if (event.getBaseItem().getId() == CURRY_LEAF.getId() || event.getUsedItem().getId() == CURRY_LEAF.getId()) { + Item stew = event.getBaseItem().getId() == UNCOOKED_STEW.getId() ? event.getBaseItem() : event.getUsedItem(); + if (stew.getCharge() == 1000) { + stew.setCharge(1); + } + int charge = stew.getCharge(); + if (charge < 3) { + player.getInventory().remove(CURRY_LEAF); + stew.setCharge(charge + 1); + } else { + if (player.getInventory().remove(stew) && player.getInventory().remove(CURRY_LEAF)) { + player.getInventory().add(UNCOOKED_CURRY); + } + } + return; + } + if (player.getInventory().remove(event.getBaseItem()) && player.getInventory().remove(event.getUsedItem())) { + player.getInventory().add(getProduct()); + } + } + + @Override + public Item getBase() { + return UNCOOKED_STEW; + } + + @Override + public Item getProduct() { + return UNCOOKED_CURRY; + } + + @Override + public Item[] getIngredients() { + return new Item[] { SPICE, CURRY_LEAF }; + } + + @Override + public Item[] getParts() { + return new Item[] { UNCOOKED_STEW }; + } + + @Override + public String getMixMessage(NodeUsageEvent event) { + return "You mix the spice with the stew."; + } + + @Override + public boolean isSingular() { + return true; + } + +} diff --git a/Server/src/main/content/global/skill/cooking/recipe/stew/StewRecipe.java b/Server/src/main/content/global/skill/cooking/recipe/stew/StewRecipe.java new file mode 100644 index 0000000..4073bcc --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/stew/StewRecipe.java @@ -0,0 +1,92 @@ +package content.global.skill.cooking.recipe.stew; + +import content.global.skill.cooking.recipe.Recipe; +import core.game.interaction.NodeUsageEvent; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +/** + * Represents the stew recipe. This recipe consists of mixing meat and a raw + * potato in a bowl of water. + * @author 'Vexia + * @date 22/12/2013 + */ +public class StewRecipe extends Recipe { + + /** + * Represents the uncooked stew item. + */ + private static final Item UNCOOKED_STEW = new Item(2001); + + /** + * Represents the bowl of water item. + */ + private static final Item BOWL_OF_WATER = new Item(1921); + + /** + * Represents the meat item. + */ + private static final Item MEAT = new Item(2142); + + /** + * Represents the potato item. + */ + private static final Item POTATO = new Item(1942); + + /** + * Represents the incomplete stew. + */ + private static final Item INCOMPLETE_STEW = new Item(1997); + + /** + * Represents the second incomplete stew. + */ + private static final Item INCOMPLETE_STEW2 = new Item(1999); + + @Override + public void mix(Player player, NodeUsageEvent event) { + Item first = event.getUsedItem(); + Item second = event.getBaseItem(); + if(first != null && second != null) { + if (player.getInventory().remove(first) && player.getInventory().remove(second)) { + if (first.getId() == BOWL_OF_WATER.getId() || second.getId() == BOWL_OF_WATER.getId()) { + player.getInventory().add(first.getId() == POTATO.getId() ? INCOMPLETE_STEW : first.getId() == MEAT.getId() ? INCOMPLETE_STEW2 : second.getId() == POTATO.getId() ? INCOMPLETE_STEW : second.getId() == MEAT.getId() ? INCOMPLETE_STEW2 : null); + } else { + player.getInventory().add(UNCOOKED_STEW); + } + player.getPacketDispatch().sendMessage(getMixMessage(event)); + } + } + } + + @Override + public Item getBase() { + return BOWL_OF_WATER; + } + + @Override + public Item getProduct() { + return UNCOOKED_STEW; + } + + @Override + public Item[] getIngredients() { + return new Item[] { MEAT, POTATO, MEAT, POTATO }; + } + + @Override + public Item[] getParts() { + return new Item[] { BOWL_OF_WATER, BOWL_OF_WATER, INCOMPLETE_STEW, INCOMPLETE_STEW2 }; + } + + @Override + public String getMixMessage(NodeUsageEvent event) { + return "You cut up the " + (event.getUsedItem().getName().toLowerCase().contains("incomplete") ? event.getBaseItem().getName().toLowerCase() : event.getUsedItem().getName().toLowerCase().replace("cooked", "").trim()) + " and put it into the stew."; + } + + @Override + public boolean isSingular() { + return false; + } + +} diff --git a/Server/src/main/content/global/skill/cooking/recipe/topping/ToppingRecipe.java b/Server/src/main/content/global/skill/cooking/recipe/topping/ToppingRecipe.java new file mode 100644 index 0000000..5c2cacb --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/topping/ToppingRecipe.java @@ -0,0 +1,58 @@ +package content.global.skill.cooking.recipe.topping; + +import core.game.node.entity.skill.Skills; +import content.global.skill.cooking.recipe.Recipe; +import core.game.interaction.NodeUsageEvent; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +/** + * Represents a generic topping recipe. + * @author 'Vexia + * @date 22/12/2013 + */ +public abstract class ToppingRecipe extends Recipe { + + /** + * Represents the bowl item. + */ + protected static final Item BOWL = new Item(1923); + + @Override + public void mix(final Player player, final NodeUsageEvent event) { + if (player.getSkills().getLevel(Skills.COOKING) < getLevel()) { + player.getDialogueInterpreter().sendDialogue("You need a Cooking level of at least " + getLevel() + " in order to do this."); + return; + } + super.mix(player, event); + player.getSkills().addExperience(Skills.COOKING, getExperience(), true); + } + + @Override + public Item getBase() { + return BOWL; + } + + @Override + public String getMixMessage(NodeUsageEvent event) { + return null; + } + + @Override + public boolean isSingular() { + return true; + } + + /** + * Method used to get the level required. + * @return the level. + */ + public abstract int getLevel(); + + /** + * Method used to get the experience gained. + * @return the experience. + */ + public abstract double getExperience(); + +} diff --git a/Server/src/main/content/global/skill/cooking/recipe/topping/impl/ChilliConCarne.java b/Server/src/main/content/global/skill/cooking/recipe/topping/impl/ChilliConCarne.java new file mode 100644 index 0000000..4085d14 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/topping/impl/ChilliConCarne.java @@ -0,0 +1,81 @@ +package content.global.skill.cooking.recipe.topping.impl; + +import core.game.node.entity.skill.Skills; +import content.global.skill.cooking.recipe.Recipe; +import core.game.interaction.NodeUsageEvent; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +/** + * Represents the chilli con carne recipe. This recipe consists of using spicy + * sauce with cooked meat. + * @author 'Vexia + * @date 22/12/2013 + */ +public class ChilliConCarne extends Recipe { + + /** + * Represents the bowl item. + */ + private static final Item SPICY_SAUCE = new Item(7072); + + /** + * Represents the chilli con carne item. + */ + private static final Item CHILLI_CON_CARNE = new Item(7062); + + /** + * Represents the cooked meat item. + */ + private static final Item COOKED_MEAT = new Item(2142); + + /** + * Represents the knife item. + */ + private static final Item KNIFE = new Item(946); + + @Override + public void mix(final Player player, final NodeUsageEvent event) { + if (player.getSkills().getLevel(Skills.COOKING) < 9) { + player.getDialogueInterpreter().sendDialogue("You need a Cooking level of at least " + 9 + " in order to do this."); + return; + } + if (!player.getInventory().containsItem(KNIFE)) { + player.getDialogueInterpreter().sendDialogue("You need a knife in order to cut up the meat."); + return; + } + super.mix(player, event); + player.getSkills().addExperience(Skills.COOKING, 25, true); + } + + @Override + public Item getBase() { + return SPICY_SAUCE; + } + + @Override + public Item getProduct() { + return CHILLI_CON_CARNE; + } + + @Override + public Item[] getIngredients() { + return new Item[] { COOKED_MEAT }; + } + + @Override + public Item[] getParts() { + return new Item[] {}; + } + + @Override + public String getMixMessage(NodeUsageEvent event) { + return "You put the cut up meat into the bowl."; + } + + @Override + public boolean isSingular() { + return true; + } + +} diff --git a/Server/src/main/content/global/skill/cooking/recipe/topping/impl/ChoppedOnion.java b/Server/src/main/content/global/skill/cooking/recipe/topping/impl/ChoppedOnion.java new file mode 100644 index 0000000..5a30107 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/topping/impl/ChoppedOnion.java @@ -0,0 +1,69 @@ +package content.global.skill.cooking.recipe.topping.impl; + +import content.global.skill.cooking.recipe.topping.ToppingRecipe; +import core.game.interaction.NodeUsageEvent; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +/** + * Represents the chopped onion recipe. This recipe consists of using an onion + * on a bowl with a knife. + * @author 'Vexia + * @date 22/12/2013 + */ +public class ChoppedOnion extends ToppingRecipe { + + /** + * Represents the chopped onion product item. + */ + private static final Item CHOPPED_ONION = new Item(1871); + + /** + * Represents the knife used to cut the onion. + */ + private static final Item KNIFE = new Item(946); + + /** + * Represents the onion item. + */ + private static final Item ONION = new Item(1957); + + @Override + public void mix(final Player player, final NodeUsageEvent event) { + if (!player.getInventory().containsItem(KNIFE)) { + player.getDialogueInterpreter().sendDialogue("You need a knife in order to slice up the onion."); + return; + } + super.mix(player, event); + } + + @Override + public int getLevel() { + return 1; + } + + @Override + public double getExperience() { + return 0; + } + + @Override + public Item getProduct() { + return CHOPPED_ONION; + } + + @Override + public Item[] getIngredients() { + return new Item[] { ONION }; + } + + @Override + public Item[] getParts() { + return new Item[] {}; + } + + @Override + public boolean isSingular() { + return true; + } +} diff --git a/Server/src/main/content/global/skill/cooking/recipe/topping/impl/ChoppedTuna.java b/Server/src/main/content/global/skill/cooking/recipe/topping/impl/ChoppedTuna.java new file mode 100644 index 0000000..4723c61 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/topping/impl/ChoppedTuna.java @@ -0,0 +1,69 @@ +package content.global.skill.cooking.recipe.topping.impl; + +import content.global.skill.cooking.recipe.topping.ToppingRecipe; +import core.game.interaction.NodeUsageEvent; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +/** + * Represents the chopped tuna recipe. This recipe consists of adding tuna to a + * bowl with a knife. + * @author 'Vexia + * @date 22/12/2013 + */ +public class ChoppedTuna extends ToppingRecipe { + + /** + * Represents the chopped tuna item. + */ + private static final Item CHOPPED_TUNA = new Item(7086); + + /** + * Represents the tuna item. + */ + private static final Item TUNA = new Item(361); + + /** + * Represents the knife item. + */ + private static final Item KNIFE = new Item(946); + + @Override + public void mix(final Player player, final NodeUsageEvent event) { + if (!player.getInventory().containsItem(KNIFE)) { + player.getDialogueInterpreter().sendDialogue("You need a knife in order to slice up the tuna."); + return; + } + super.mix(player, event); + } + + @Override + public int getLevel() { + return 1; + } + + @Override + public double getExperience() { + return 1; + } + + @Override + public Item getProduct() { + return CHOPPED_TUNA; + } + + @Override + public Item[] getIngredients() { + return new Item[] { TUNA }; + } + + @Override + public Item[] getParts() { + return new Item[] {}; + } + + @Override + public boolean isSingular() { + return true; + } +} diff --git a/Server/src/main/content/global/skill/cooking/recipe/topping/impl/EggAndTomato.java b/Server/src/main/content/global/skill/cooking/recipe/topping/impl/EggAndTomato.java new file mode 100644 index 0000000..dabf2db --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/topping/impl/EggAndTomato.java @@ -0,0 +1,72 @@ +package content.global.skill.cooking.recipe.topping.impl; + +import content.global.skill.cooking.recipe.Recipe; +import core.game.node.entity.skill.Skills; +import core.game.interaction.NodeUsageEvent; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +/** + * Represents the egg and tomato recipe. This recipe consists of mixing a tomato + * with a scrambled egg. + * @author 'Vexia + * @date 22/12/2013 + */ +public class EggAndTomato extends Recipe { + + /** + * Represents the egg and tomato. + */ + private static final Item EGG_AND_TOMATO = new Item(7064); + + /** + * Represents the scrambled egg item. + */ + private static final Item SCRAMBLED_EGG = new Item(7078); + + /** + * epresents the tomato item. + */ + private static final Item TOMATO = new Item(1982); + + @Override + public void mix(final Player player, final NodeUsageEvent event) { + if (player.getSkills().getLevel(Skills.COOKING) < 23) { + player.getDialogueInterpreter().sendDialogue("You need a Cooking level of at least " + 23 + " in order to do this."); + return; + } + super.mix(player, event); + player.getSkills().addExperience(Skills.COOKING, 50, true); + } + + @Override + public Item getBase() { + return SCRAMBLED_EGG; + } + + @Override + public Item getProduct() { + return EGG_AND_TOMATO; + } + + @Override + public Item[] getIngredients() { + return new Item[] { TOMATO }; + } + + @Override + public Item[] getParts() { + return new Item[] {}; + } + + @Override + public String getMixMessage(NodeUsageEvent event) { + return null; + } + + @Override + public boolean isSingular() { + return true; + } + +} diff --git a/Server/src/main/content/global/skill/cooking/recipe/topping/impl/MushroomAndOnion.java b/Server/src/main/content/global/skill/cooking/recipe/topping/impl/MushroomAndOnion.java new file mode 100644 index 0000000..3b99200 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/topping/impl/MushroomAndOnion.java @@ -0,0 +1,72 @@ +package content.global.skill.cooking.recipe.topping.impl; + +import core.game.node.entity.skill.Skills; +import content.global.skill.cooking.recipe.Recipe; +import core.game.interaction.NodeUsageEvent; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +/** + * Represents the mushroom and onion recipe. This recipe consists of using a + * fried mushroom with a friend onion. + * @author 'Vexia + * @date 22/12/2013 + */ +public class MushroomAndOnion extends Recipe { + + /** + * Represents the mushroom and onion item. + */ + private static final Item MUSHROOM_AND_ONION = new Item(7066); + + /** + * Represents the fried onions item. + */ + private static final Item FRIED_ONIONS = new Item(7084); + + /** + * Represents the fried mushrooms item. + */ + private static final Item FRIED_MUSHROOMS = new Item(7082); + + @Override + public void mix(final Player player, final NodeUsageEvent event) { + if (player.getSkills().getLevel(Skills.COOKING) < 57) { + player.getDialogueInterpreter().sendDialogue("You need a Cooking level of at least " + 57 + " in order to do this."); + return; + } + super.mix(player, event); + player.getSkills().addExperience(Skills.COOKING, 120, true); + } + + @Override + public Item getBase() { + return FRIED_MUSHROOMS; + } + + @Override + public Item getProduct() { + return MUSHROOM_AND_ONION; + } + + @Override + public Item[] getIngredients() { + return new Item[] { FRIED_ONIONS }; + } + + @Override + public Item[] getParts() { + return new Item[] {}; + } + + @Override + public String getMixMessage(NodeUsageEvent event) { + return null; + } + + @Override + public boolean isSingular() { + return true; + } + +} diff --git a/Server/src/main/content/global/skill/cooking/recipe/topping/impl/SlicedMushroom.java b/Server/src/main/content/global/skill/cooking/recipe/topping/impl/SlicedMushroom.java new file mode 100644 index 0000000..46f9d09 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/topping/impl/SlicedMushroom.java @@ -0,0 +1,69 @@ +package content.global.skill.cooking.recipe.topping.impl; + +import content.global.skill.cooking.recipe.topping.ToppingRecipe; +import core.game.interaction.NodeUsageEvent; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +/** + * Represents the fried mushroom recipe. This recipe consists of using a + * mushroom on a bowl. + * @author 'Vexia + * @date 22/12/2013 + */ +public final class SlicedMushroom extends ToppingRecipe { + + /** + * Represents the sliced mushrooms item. + */ + private static final Item SLICED_MUSHROOMS = new Item(7080); + + /** + * Represents the mushroom item. + */ + private static final Item MUSHROOM = new Item(6004); + + /** + * Represents the knife item. + */ + private static final Item KNIFE = new Item(946); + + @Override + public void mix(final Player player, final NodeUsageEvent event) { + if (!player.getInventory().containsItem(KNIFE)) { + player.getDialogueInterpreter().sendDialogue("You need a knife in order to slice up the mushrooms."); + return; + } + super.mix(player, event); + } + + @Override + public int getLevel() { + return 1; + } + + @Override + public double getExperience() { + return 0; + } + + @Override + public Item getProduct() { + return SLICED_MUSHROOMS; + } + + @Override + public Item[] getIngredients() { + return new Item[] { MUSHROOM }; + } + + @Override + public Item[] getParts() { + return new Item[] {}; + } + + @Override + public boolean isSingular() { + return true; + } +} diff --git a/Server/src/main/content/global/skill/cooking/recipe/topping/impl/SpicySauce.java b/Server/src/main/content/global/skill/cooking/recipe/topping/impl/SpicySauce.java new file mode 100644 index 0000000..2b0a7e1 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/topping/impl/SpicySauce.java @@ -0,0 +1,84 @@ +package content.global.skill.cooking.recipe.topping.impl; + +import core.game.node.entity.skill.Skills; +import content.global.skill.cooking.recipe.Recipe; +import core.game.interaction.NodeUsageEvent; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +/** + * Represents the spicy sauce recipe. This recipe consists of mixing gnome spice + * and garlic together. + * @author 'Vexia + * @date 22/12/2013 + */ +public class SpicySauce extends Recipe { + + /** + * Represents the spicy sauce item. + */ + private static final Item SPICY_SAUCE = new Item(7072); + + /** + * Represents the bowl item. + */ + private static final Item BOWL = new Item(1923); + + /** + * Represents the garlic item. + */ + private static final Item GARLIC = new Item(1550); + + /** + * Represents the chopped garlic item. + */ + private static final Item CHOPPED_GARLIC = new Item(7074); + + /** + * Represents the gnome spice item. + */ + private static final Item GNOME_SPICE = new Item(2169); + + @Override + public void mix(final Player player, final NodeUsageEvent event) { + if (player.getSkills().getLevel(Skills.COOKING) < 9) { + player.getDialogueInterpreter().sendDialogue("You need a Cooking level of at least " + 9 + " in order to do this."); + return; + } + super.mix(player, event); + if (event.getBaseItem().getId() == GNOME_SPICE.getId() || event.getUsedItem().getId() == GNOME_SPICE.getId()) { + player.getSkills().addExperience(Skills.COOKING, 25, true); + } + } + + @Override + public Item getBase() { + return BOWL; + } + + @Override + public Item getProduct() { + return SPICY_SAUCE; + } + + @Override + public Item[] getIngredients() { + return new Item[] { GARLIC, GNOME_SPICE }; + } + + @Override + public Item[] getParts() { + return new Item[] { BOWL, CHOPPED_GARLIC, SPICY_SAUCE }; + } + + @Override + public String getMixMessage(NodeUsageEvent event) { + return null; + } + + @Override + public boolean isSingular() { + return false; + } + +} diff --git a/Server/src/main/content/global/skill/cooking/recipe/topping/impl/TunaAndCorn.java b/Server/src/main/content/global/skill/cooking/recipe/topping/impl/TunaAndCorn.java new file mode 100644 index 0000000..1e2c92a --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/topping/impl/TunaAndCorn.java @@ -0,0 +1,72 @@ +package content.global.skill.cooking.recipe.topping.impl; + +import core.game.node.entity.skill.Skills; +import content.global.skill.cooking.recipe.Recipe; +import core.game.interaction.NodeUsageEvent; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +/** + * Represents the tuna and corn recipe. This recipe consists of adding cooked + * sweetcorn to a bowl of chopped tuna. + * @author 'Vexia + * @date 22/12/2013 + */ +public final class TunaAndCorn extends Recipe { + + /** + * Represents the chopped tuna item. + */ + private static final Item CHOPPED_TUNA = new Item(7086); + + /** + * Represents the cooked corn item. + */ + private static final Item COOKED_CORN = new Item(5988); + + /** + * Represents the tuna and corn item. + */ + private static final Item TUNA_AND_CORN = new Item(7068); + + @Override + public void mix(final Player player, final NodeUsageEvent event) { + if (player.getSkills().getLevel(Skills.COOKING) < 67) { + player.getDialogueInterpreter().sendDialogue("You need a Cooking level of at least " + 57 + " in order to do this."); + return; + } + super.mix(player, event); + player.getSkills().addExperience(Skills.COOKING, 204, true); + } + + @Override + public Item getBase() { + return CHOPPED_TUNA; + } + + @Override + public Item getProduct() { + return TUNA_AND_CORN; + } + + @Override + public Item[] getIngredients() { + return new Item[] { COOKED_CORN }; + } + + @Override + public Item[] getParts() { + return new Item[] {}; + } + + @Override + public String getMixMessage(NodeUsageEvent event) { + return null; + } + + @Override + public boolean isSingular() { + return true; + } + +} diff --git a/Server/src/main/content/global/skill/cooking/recipe/topping/impl/UncookedEgg.java b/Server/src/main/content/global/skill/cooking/recipe/topping/impl/UncookedEgg.java new file mode 100644 index 0000000..61ce503 --- /dev/null +++ b/Server/src/main/content/global/skill/cooking/recipe/topping/impl/UncookedEgg.java @@ -0,0 +1,54 @@ +package content.global.skill.cooking.recipe.topping.impl; + +import content.global.skill.cooking.recipe.topping.ToppingRecipe; +import core.game.node.item.Item; + +/** + * Represents the uncooked egg recipe. This recipe consists of adding an + * uncooked egg into a bowl. + * @author 'Vexia + * @date 22/12/2013 + */ +public final class UncookedEgg extends ToppingRecipe { + + /** + * Represents the egg item. + */ + private static final Item EGG = new Item(1944); + + /** + * Represents the uncooked egg product. + */ + private static final Item UNCOOKED_EGG = new Item(7076); + + @Override + public int getLevel() { + return 1; + } + + @Override + public double getExperience() { + return 1; + } + + @Override + public Item getProduct() { + return UNCOOKED_EGG; + } + + @Override + public Item[] getIngredients() { + return new Item[] { EGG }; + } + + @Override + public boolean isSingular() { + return true; + } + + @Override + public Item[] getParts() { + return new Item[] {}; + } + +} diff --git a/Server/src/main/content/global/skill/crafting/AmuletStringingPlugin.java b/Server/src/main/content/global/skill/crafting/AmuletStringingPlugin.java new file mode 100644 index 0000000..cfe3cfd --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/AmuletStringingPlugin.java @@ -0,0 +1,50 @@ +package content.global.skill.crafting; + +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import content.global.skill.crafting.jewellery.JewelleryCrafting; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Plugin; + +/** + * Represents the plugin used to string an amulet. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class AmuletStringingPlugin extends UseWithHandler { + + /** + * Constructs a new {@code AmuletStringingPlugin} {@code Object}. + */ + public AmuletStringingPlugin() { + super(1673, 1675, 1677, 1679, 1681, 1683, 6579); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(1759, ITEM_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + final JewelleryCrafting.JewelleryItem data = JewelleryCrafting.JewelleryItem.forProduct(event.getUsedItem().getId() == 6579 ? 6579 : ((Item) event.getUsedWith()).getId()); + if (data == null) { + return true; + } + if (player.getSkills().getLevel(Skills.CRAFTING) < data.getLevel()) { + player.getPacketDispatch().sendMessage("You need a Crafting level of at least " + data.getLevel() + " to do that."); + return true; + } + if (player.getInventory().remove(event.getUsedItem(), event.getBaseItem())) { + player.getInventory().add(new Item(data == JewelleryCrafting.JewelleryItem.ONYX_AMULET ? 6581 : data.getSendItem() + 19)); + } + return true; + } + +} diff --git a/Server/src/main/content/global/skill/crafting/BattlestaffListener.kt b/Server/src/main/content/global/skill/crafting/BattlestaffListener.kt new file mode 100644 index 0000000..54a82b5 --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/BattlestaffListener.kt @@ -0,0 +1,89 @@ +package content.global.skill.crafting + +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.link.diary.DiaryType +import core.game.node.entity.skill.Skills +import org.rs09.consts.Items +import kotlin.math.min + +class BattlestaffListener : InteractionListener { + + private val battlestaff = Items.BATTLESTAFF_1391 + val orbs = BattlestaffProduct.values().map { it.requiredOrbItemId }.toIntArray() + + override fun defineListeners() { + onUseWith(IntType.ITEM, orbs, battlestaff) { player, used, with -> + val product = BattlestaffProduct.productMap[used.id] ?: return@onUseWith true + + if (!hasLevelDyn(player, Skills.CRAFTING, product.minimumLevel)) { + sendMessage(player, "You need a Crafting level of ${product.minimumLevel} to make this.") + return@onUseWith true + } + + // Avoids sending dialogue if only one can be created + if (amountInInventory(player, used.id) == 1 || amountInInventory(player, with.id) == 1) { + + if (removeItem(player, product.requiredOrbItemId) && removeItem(player, Items.BATTLESTAFF_1391)) { + addItem(player, product.producedItemId, product.amountProduced) + rewardXP(player, Skills.CRAFTING, product.experience) + } + + if (product.producedItemId == Items.AIR_BATTLESTAFF_1397) { + player.achievementDiaryManager.finishTask(player, DiaryType.VARROCK, 2, 6) + } + + return@onUseWith true + } + + sendSkillDialogue(player) { + withItems(product.producedItemId) + create { _, amount -> + + runTask(player, 2, amount) { + if (amount < 1) return@runTask + + if (removeItem(player, product.requiredOrbItemId) && removeItem(player, Items.BATTLESTAFF_1391)) { + addItem(player, product.producedItemId, product.amountProduced) + rewardXP(player, Skills.CRAFTING, product.experience) + } + + if (product.producedItemId == Items.AIR_BATTLESTAFF_1397) { + player.achievementDiaryManager.finishTask(player, DiaryType.VARROCK, 2, 6) + } else return@runTask + } + } + + calculateMaxAmount { _ -> + min(amountInInventory(player, with.id), amountInInventory(player, used.id)) + } + } + + return@onUseWith true + } + } + + enum class BattlestaffProduct( + val requiredOrbItemId: Int, + val producedItemId: Int, + val amountProduced: Int, + val minimumLevel: Int, + val experience: Double, + ) { + WATER_BATTLESTAFF(Items.WATER_ORB_571, Items.WATER_BATTLESTAFF_1395, 1, 54, 100.0), + EARTH_BATTLESTAFF(Items.EARTH_ORB_575, Items.EARTH_BATTLESTAFF_1399, 1, 58, 112.5), + FIRE_BATTLESTAFF(Items.FIRE_ORB_569, Items.FIRE_BATTLESTAFF_1393, 1, 62, 125.0), + AIR_BATTLESTAFF(Items.AIR_ORB_573, Items.AIR_BATTLESTAFF_1397, 1, 66, 137.5); + + companion object { + val productMap = HashMap() + + init { + for (product in BattlestaffProduct.values()) { + productMap[product.requiredOrbItemId] = product + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/crafting/ChiselLimestonePlugin.java b/Server/src/main/content/global/skill/crafting/ChiselLimestonePlugin.java new file mode 100644 index 0000000..cf584b2 --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/ChiselLimestonePlugin.java @@ -0,0 +1,38 @@ +package content.global.skill.crafting; + +import content.global.skill.crafting.limestone.ChiselLimestonePulse; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * The plugin that starts the chisel limestone cutting pulse. + * @author Jamix77 + */ +@Initializable +public final class ChiselLimestonePlugin extends UseWithHandler { + + /** + * Constructs a new {@code GemCutPlugin} {@Code Object} + */ + public ChiselLimestonePlugin() { + super(3211); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(1755, ITEM_TYPE, this); + return null; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + player.getPulseManager().run(new ChiselLimestonePulse(player, new Item(3211))); + return true; + } + +} diff --git a/Server/src/main/content/global/skill/crafting/GemCutPlugin.java b/Server/src/main/content/global/skill/crafting/GemCutPlugin.java new file mode 100644 index 0000000..f848bac --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/GemCutPlugin.java @@ -0,0 +1,58 @@ +package content.global.skill.crafting; + +import content.global.skill.crafting.gem.GemCutPulse; +import core.game.dialogue.SkillDialogueHandler; +import core.game.dialogue.SkillDialogueHandler.SkillDialogue; +import content.global.skill.crafting.gem.Gems; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the plugin used to cut a gem. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class GemCutPlugin extends UseWithHandler { + + /** + * Constructs a new {@code GemCutPlugin} {@Code Object} + */ + public GemCutPlugin() { + super(1623, 1621, 1619, 1617, 1631, 6571, 1625, 1627, 1629, 6571); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(1755, ITEM_TYPE, this); + return null; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + final Gems gem = Gems.forId(event.getUsedItem().getId() == 1755 ? event.getBaseItem() : event.getUsedItem()); + SkillDialogueHandler handler = new SkillDialogueHandler(player, SkillDialogue.ONE_OPTION, gem.getGem()) { + @Override + public void create(final int amount, int index) { + player.getPulseManager().run(new GemCutPulse(player, gem.getUncut(), amount, gem)); + } + + @Override + public int getAll(int index) { + return player.getInventory().getAmount(gem.getUncut()); + } + + }; + if (player.getInventory().getAmount(gem.getUncut()) == 1) { + handler.create(0, 1); + } else { + handler.open(); + } + return true; + } + +} diff --git a/Server/src/main/content/global/skill/crafting/JewelleryCraftPlugin.java b/Server/src/main/content/global/skill/crafting/JewelleryCraftPlugin.java new file mode 100644 index 0000000..72d19ef --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/JewelleryCraftPlugin.java @@ -0,0 +1,43 @@ +package content.global.skill.crafting; + +import core.plugin.Initializable; +import content.global.skill.crafting.jewellery.JewelleryCrafting; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.plugin.Plugin; + +/** + * Represents the plugin used to craft jewellery. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class JewelleryCraftPlugin extends UseWithHandler { + + /** + * Represents the ids to use for this plugin. + */ + private static final int[] IDS = new int[] { 4304, 6189, 11010, 11666, 12100, 12809, 18497, 26814, 30021, 30510, 36956, 37651 }; + + /** + * Constructs a new {@code JewelleryCraftPlugin} {@code Object}. + */ + public JewelleryCraftPlugin() { + super(2357); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (int i : IDS) { + addHandler(i, OBJECT_TYPE, this); + } + return this; + } + + @Override + public boolean handle(final NodeUsageEvent event) { + JewelleryCrafting.open(event.getPlayer()); + return true; + } + +} diff --git a/Server/src/main/content/global/skill/crafting/LeatherCraftDialogue.java b/Server/src/main/content/global/skill/crafting/LeatherCraftDialogue.java new file mode 100644 index 0000000..0692339 --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/LeatherCraftDialogue.java @@ -0,0 +1,227 @@ +package content.global.skill.crafting; + +import static core.api.ContentAPIKt.*; +import core.api.InputType; +import core.cache.def.impl.ItemDefinition; +import core.game.component.Component; +import core.game.dialogue.DialoguePlugin; +import kotlin.Unit; +import content.global.skill.crafting.armour.DragonCraftPulse; +import content.global.skill.crafting.armour.HardCraftPulse; +import content.global.skill.crafting.armour.LeatherCrafting; +import content.global.skill.crafting.armour.LeatherCrafting.DragonHide; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.game.node.item.Item; + +/** + * Represents the dialogue plugin used for leather crafting. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class LeatherCraftDialogue extends DialoguePlugin { + + /** + * Represents the type. + */ + private String type = ""; + + /** + * Represents the leather. + */ + private int leather; + + /** + * Constructs a new {@code LeatherCraftDialogue} {@code Object}. + */ + public LeatherCraftDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code LeatherCraftDialogue} {@code Object}. + * @param player the player. + */ + public LeatherCraftDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new LeatherCraftDialogue(player); + } + + @Override + public boolean open(Object... args) { + Component component = new Component(304); + type = (String) args[0]; + if (type.equals("hard")) { + player.getInterfaceManager().openChatbox(309); + player.getPacketDispatch().sendItemZoomOnInterface(1131, 150, 309, 2); + player.getPacketDispatch().sendString("



Hardleather body", 309, 6); + } else { + /** dragon */ + leather = (int) args[1]; + player.getInterfaceManager().openChatbox(component); + int index[] = new int[3]; + if (leather == LeatherCrafting.GREEN_LEATHER) { + index[0] = DragonHide.GREEN_D_HIDE_BODY.getProduct(); + index[1] = DragonHide.GREEN_D_HIDE_VAMBS.getProduct(); + index[2] = DragonHide.GREEN_D_HIDE_CHAPS.getProduct(); + } + if (leather == LeatherCrafting.BLUE_LEATHER) { + index[0] = DragonHide.BLUE_D_HIDE_BODY.getProduct(); + index[1] = DragonHide.BLUE_D_HIDE_VAMBS.getProduct(); + index[2] = DragonHide.BLUE_D_HIDE_CHAPS.getProduct(); + } + if (leather == LeatherCrafting.RED_LEATHER) { + index[0] = DragonHide.RED_D_HIDE_BODY.getProduct(); + index[1] = DragonHide.RED_D_HIDE_VAMBS.getProduct(); + index[2] = DragonHide.RED_D_HIDE_CHAPS.getProduct(); + } + if (leather == LeatherCrafting.BLACK_LEATHER) { + index[0] = DragonHide.BLACK_D_HIDE_BODY.getProduct(); + index[1] = DragonHide.BLACK_D_HIDE_VAMBS.getProduct(); + index[2] = DragonHide.BLACK_D_HIDE_CHAPS.getProduct(); + } + player.getPacketDispatch().sendItemZoomOnInterface(index[0], 175, 304, 2); + player.getPacketDispatch().sendItemZoomOnInterface(index[1], 175, 304, 3); + player.getPacketDispatch().sendItemZoomOnInterface(index[2], 165, 304, 4); + player.getPacketDispatch().sendString("



" + ItemDefinition.forId(index[0]).getName(), 304, 8); + player.getPacketDispatch().sendString("



" + ItemDefinition.forId(index[1]).getName(), 304, 11); + player.getPacketDispatch().sendString("



" + ItemDefinition.forId(index[2]).getName(), 304, 16); + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + player.getInterfaceManager().closeChatbox(); + int amt = 0; + switch (type) { + case "hard": + switch (buttonId) { + case 6: + amt = 1; + break; + case 4: + amt = 5; + break; + case 3: + sendInputDialogue(player, true, "Enter the amount:", (value) -> { + player.getPulseManager().run(new HardCraftPulse(player, null, (int) value)); + return Unit.INSTANCE; + }); + return true; + case 2: + amt = player.getInventory().getAmount(new Item(LeatherCrafting.HARD_LEATHER)); + break; + } + player.getPulseManager().run(new HardCraftPulse(player, null, amt)); + break; + case "dragon": + int index = 0; + if (buttonId > 3 && buttonId < 8) { + index = 1; + } + if (buttonId > 7 && buttonId < 12) { + index = 2; + } + if (buttonId > 11 && buttonId < 16) { + index = 3; + } + DragonHide hide = null; + if (index == 1) { + switch (leather) { + case LeatherCrafting.GREEN_LEATHER: + hide = DragonHide.GREEN_D_HIDE_BODY; + break; + case LeatherCrafting.BLUE_LEATHER: + hide = DragonHide.BLUE_D_HIDE_BODY; + break; + case LeatherCrafting.RED_LEATHER: + hide = DragonHide.RED_D_HIDE_BODY; + break; + case LeatherCrafting.BLACK_LEATHER: + hide = DragonHide.BLACK_D_HIDE_BODY; + break; + } + } + if (index == 2) { + switch (leather) { + case LeatherCrafting.GREEN_LEATHER: + hide = DragonHide.GREEN_D_HIDE_VAMBS; + break; + case LeatherCrafting.BLUE_LEATHER: + hide = DragonHide.BLUE_D_HIDE_VAMBS; + break; + case LeatherCrafting.RED_LEATHER: + hide = DragonHide.RED_D_HIDE_VAMBS; + break; + case LeatherCrafting.BLACK_LEATHER: + hide = DragonHide.BLACK_D_HIDE_VAMBS; + break; + } + } + if (index == 3) { + switch (leather) { + case LeatherCrafting.GREEN_LEATHER: + hide = DragonHide.GREEN_D_HIDE_CHAPS; + break; + case LeatherCrafting.BLUE_LEATHER: + hide = DragonHide.BLUE_D_HIDE_CHAPS; + break; + case LeatherCrafting.RED_LEATHER: + hide = DragonHide.RED_D_HIDE_CHAPS; + break; + case LeatherCrafting.BLACK_LEATHER: + hide = DragonHide.BLACK_D_HIDE_CHAPS; + break; + } + } + switch (buttonId) { + case 7: + case 11: + case 15: + amt = 1; + break; + case 6: + case 10: + case 14: + amt = 5; + break; + case 5: + case 9: + case 13: + amt = 10; + break; + case 4: + case 8: + case 12: + final DragonHide hidee = hide; + if (hidee == null) { + return false; + } + sendInputDialogue(player, InputType.AMOUNT, "Enter the amount:", (value) -> { + player.getPulseManager().run(new DragonCraftPulse(player, null, hidee, (int) value)); + return Unit.INSTANCE; + }); + return true; + } + if (hide == null) { + return false; + } + player.getPulseManager().run(new DragonCraftPulse(player, null, hide, amt)); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 48923 }; + } +} diff --git a/Server/src/main/content/global/skill/crafting/PotteryPlugin.java b/Server/src/main/content/global/skill/crafting/PotteryPlugin.java new file mode 100644 index 0000000..f7fa44e --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/PotteryPlugin.java @@ -0,0 +1,164 @@ +package content.global.skill.crafting; + +import content.global.skill.crafting.pottery.FirePotteryPulse; +import content.global.skill.crafting.pottery.PotteryItem; +import core.cache.def.impl.SceneryDefinition; +import core.plugin.Initializable; +import core.game.dialogue.SkillDialogueHandler; +import core.game.dialogue.SkillDialogueHandler.SkillDialogue; +import content.global.skill.crafting.pottery.PotteryPulse; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.OptionHandler; +import core.game.interaction.UseWithHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Plugin; + +/** + * Represents the plugin used to handle pottery actions. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class PotteryPlugin extends UseWithHandler { + + /** + * Represents the soft clay item. + */ + private static final Item SOFT_CLAY = new Item(1761); + + /** + * Represents the oven ids. + */ + private static final int[] OVENS = new int[] { 2643, 4308, 11601, 34802 }; + + /** + * Constructs a new {@code PotteryPlugin} {@code Object}. + */ + public PotteryPlugin() { + super(1761); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + new FireOvenPlugin().newInstance(arg); + addHandler(2642, OBJECT_TYPE, this); + addHandler(2643, OBJECT_TYPE, this); + addHandler(4308, OBJECT_TYPE, this); + addHandler(4310, OBJECT_TYPE, this); + addHandler(20375, OBJECT_TYPE, this); + addHandler(34801, OBJECT_TYPE, this); + addHandler(34802, OBJECT_TYPE, this); + return this; + } + + @Override + public boolean handle(final NodeUsageEvent event) { + final Player player = event.getPlayer(); + new SkillDialogueHandler(player, SkillDialogue.FIVE_OPTION, (Object[]) getPottery(false)) { + + @Override + public void create(final int amount, int index) { + player.getPulseManager().run(new PotteryPulse(player, event.getUsedItem(), amount, PotteryItem.values()[index])); + } + + @Override + public int getAll(int index) { + return player.getInventory().getAmount(SOFT_CLAY); + } + + }.open(); + return true; + } + + /** + * Gets the pottery items. + * @param finished if not. + * @return the items. + */ + private Item[] getPottery(boolean finished) { + final Item[] items = new Item[PotteryItem.values().length]; + for (int i = 0; i < items.length; i++) { + items[i] = finished ? PotteryItem.values()[i].getProduct() : PotteryItem.values()[i].getUnfinished(); + } + return items; + } + + /** + * Represents the fire oven plugin. + * @author 'Vexia + * @version 1.0 + */ + public class FireOvenPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (int id : OVENS) { + SceneryDefinition.forId(id).getHandlers().put("option:fire", this); + } + new FireUseHandler().newInstance(arg); + return this; + } + + @Override + public boolean handle(final Player player, Node node, String option) { + getSkillHandler(player).open(); + return true; + } + + /** + * Represents the fire use with handler. + * @author 'Vexia + * @version 1.0 + */ + public final class FireUseHandler extends UseWithHandler { + + /** + * Constructs a new {@code FireUseHandler} {@code Object}. + */ + public FireUseHandler() { + super(1787, 1789, 1791, 5352, 4438); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(2643, OBJECT_TYPE, this); + addHandler(4308, OBJECT_TYPE, this); + addHandler(11601, OBJECT_TYPE, this); + addHandler(34802, OBJECT_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + getSkillHandler(player).open(); + return true; + } + + } + + /** + * Gets the skill handler dialogue. + * @param player the player. + * @return the dialogue handler. + */ + public SkillDialogueHandler getSkillHandler(final Player player) { + return new SkillDialogueHandler(player, SkillDialogue.FIVE_OPTION, (Object[]) getPottery(true)) { + + @Override + public void create(final int amount, final int index) { + player.getPulseManager().run(new FirePotteryPulse(player, PotteryItem.values()[index].getUnfinished(), PotteryItem.values()[index], amount)); + } + + @Override + public int getAll(int index) { + return player.getInventory().getAmount(PotteryItem.values()[index].getUnfinished()); + } + }; + } + + } + +} diff --git a/Server/src/main/content/global/skill/crafting/SnakeSkinPlugin.java b/Server/src/main/content/global/skill/crafting/SnakeSkinPlugin.java new file mode 100644 index 0000000..f492924 --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/SnakeSkinPlugin.java @@ -0,0 +1,70 @@ +package content.global.skill.crafting; + +import content.global.skill.crafting.armour.SnakeSkin; +import content.global.skill.crafting.armour.SnakeSkinPulse; +import core.plugin.Initializable; +import core.game.dialogue.SkillDialogueHandler; +import core.game.dialogue.SkillDialogueHandler.SkillDialogue; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Plugin; + +/** + * Handles snake skin plugin. + * @author Vexia + */ +@Initializable +public class SnakeSkinPlugin extends UseWithHandler { + + /** + * Constructs a new {@Code SnakeSkinPlugin} {@Code Object} + */ + public SnakeSkinPlugin() { + super(1733); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(6289, ITEM_TYPE, this); + return this; + } + + @Override + public boolean handle(final NodeUsageEvent event) { + final Player player = event.getPlayer(); + new SkillDialogueHandler(player, SkillDialogue.FIVE_OPTION, (Object[]) getSkins()) { + + @Override + public void create(final int amount, int index) { + player.getPulseManager().run(new SnakeSkinPulse(player, event.getUsedItem(), amount, SnakeSkin.values()[index])); + } + + @Override + public int getAll(int index) { + return player.getInventory().getAmount(new Item(6289)); + } + + @Override + public String getName(Item item) { + return item.getId() == 6328 ? "Boots" : item.getId() == 6330 ? "Vambs" : item.getId() == 6326 ? "Bandana" : item.getId() == 6324 ? "Chaps" : "Body"; + } + + }.open(); + return true; + } + + /** + * Gets the skins. + * @return the item. + */ + public Item[] getSkins() { + Item[] items = new Item[SnakeSkin.values().length]; + for (int i = 0; i < items.length; i++) { + items[i] = SnakeSkin.values()[i].getProduct(); + } + return items; + } + +} diff --git a/Server/src/main/content/global/skill/crafting/SnelmCraftPlugin.java b/Server/src/main/content/global/skill/crafting/SnelmCraftPlugin.java new file mode 100644 index 0000000..1b1335c --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/SnelmCraftPlugin.java @@ -0,0 +1,111 @@ +package content.global.skill.crafting; + +import core.plugin.Initializable; +import core.game.node.entity.skill.SkillPulse; +import core.game.node.entity.skill.Skills; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Plugin; + +/** + * Handles the crafting of a snelm helmet. + * @author Vexia + */ +@Initializable +public class SnelmCraftPlugin extends UseWithHandler { + + /** + * The snelm data. + */ + private static final int[][] DATA = new int[][] { { 3345, 3327 }, { 3355, 3337 },// blamish + { 3349, 3341 }, { 3341, 3359 },// ochre + { 3347, 3329 }, { 3357, 3339 },// blood + { 3351, 3333 }, { 3361, 3343 },// blue + { 3353, 3335 },// bark + }; + + /** + * Constructs a new {@Code SnelmCraftPlugin} {@Code Object} + */ + public SnelmCraftPlugin() { + super(1755); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (int i = 0; i < DATA.length; i++) { + for (int k = 0; k < DATA[i].length; k++) { + addHandler(DATA[i][0], ITEM_TYPE, this); + } + } + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + int[] snelm = null; + for (int i = 0; i < DATA.length; i++) { + for (int k = 0; k < DATA[i].length; k++) { + if (DATA[i][0] == event.getUsedItem().getId()) { + snelm = DATA[i]; + break; + } + } + } + if (snelm == null) { + return false; + } + player.lock(1); + player.getPulseManager().run(new SnelmCraftPulse(player, event.getUsedItem(), snelm)); + return true; + } + + /** + * Handles the crafting of a snelm helmet. + * @author Vexia + */ + public static final class SnelmCraftPulse extends SkillPulse { + + /** + * The snelm data. + */ + private final int[] data; + + /** + * Constructs a new {@Code SnelmCraftPulse} {@Code Object} + * @param player the player. + * @param node the node. + */ + public SnelmCraftPulse(Player player, Item node, int[] data) { + super(player, node); + this.setDelay(1); + this.data = data; + } + + @Override + public boolean checkRequirements() { + if (player.getSkills().getStaticLevel(Skills.CRAFTING) < 15) { + player.sendMessage("You need a Crafting level of at least 15 in order to do this."); + return false; + } + return true; + } + + @Override + public void animate() { + + } + + @Override + public boolean reward() { + player.sendMessage("You craft the shell into a helmet."); + player.getInventory().replace(new Item(data[1]), node.getSlot()); + player.getSkills().addExperience(Skills.CRAFTING, 32.5, true); + return true; + } + + } +} diff --git a/Server/src/main/content/global/skill/crafting/StitchCraftPlugin.java b/Server/src/main/content/global/skill/crafting/StitchCraftPlugin.java new file mode 100644 index 0000000..973710e --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/StitchCraftPlugin.java @@ -0,0 +1,45 @@ +package content.global.skill.crafting; + +import core.game.component.Component; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * The Stitch Crafting Plugin + * @author SonicForce41 + */ +@Initializable +public class StitchCraftPlugin extends UseWithHandler { + + /** + * Constructs a new {@code StitchCraftPlugin.java} {@Code Object} + */ + public StitchCraftPlugin() { + super(1741); + } + + /** + * Method handles the actions for this Plugin + */ + @Override + public boolean handle(NodeUsageEvent event) { + Player player = event.getPlayer(); + int itemId = event.getUsedItem().getId(); + player.getAttributes().put("leatherId", itemId); + player.getInterfaceManager().open(new Component(154)); + return true; + } + + /** + * Method returns the instance for plugin + */ + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(1733, ITEM_TYPE, this); + return null; + } + +} diff --git a/Server/src/main/content/global/skill/crafting/StuddedArmourPlugin.java b/Server/src/main/content/global/skill/crafting/StuddedArmourPlugin.java new file mode 100644 index 0000000..1abe86f --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/StuddedArmourPlugin.java @@ -0,0 +1,244 @@ +package content.global.skill.crafting; + +import core.plugin.Initializable; +import core.game.dialogue.SkillDialogueHandler; +import core.game.dialogue.SkillDialogueHandler.SkillDialogue; +import core.game.node.entity.skill.SkillPulse; +import core.game.node.entity.skill.Skills; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; + +/** + * Represents the studded body plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class StuddedArmourPlugin extends UseWithHandler { + + /** + * Represents the steel studs item. + */ + private static final Item STEEL_STUDS = new Item(2370); + + /** + * Constructs a new {@code StuddedBodyPlugin} {@code Object}. + */ + public StuddedArmourPlugin() { + super(2370); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (StuddedArmour armour : StuddedArmour.values()) { + addHandler(armour.getItem().getId(), ITEM_TYPE, this); + } + return this; + } + + @Override + public boolean handle(final NodeUsageEvent event) { + final Player player = event.getPlayer(); + final StuddedArmour armour = StuddedArmour.forItem(event.getBaseItem()); + SkillDialogueHandler handler = new SkillDialogueHandler(player, SkillDialogue.ONE_OPTION, armour.getStudded()) { + + @Override + public void create(int amount, int index) { + player.getPulseManager().run(new StudArmourPulse(player, event.getBaseItem(), armour, amount)); + } + + @Override + public int getAll(int index) { + return player.getInventory().getAmount(STEEL_STUDS); + } + + }; + if (player.getInventory().getAmount(armour.getItem()) == 1) { + handler.create(1, 0); + } else { + handler.open(); + } + return true; + } + + /** + * Represents a studded armour. + * @author 'Vexia + * @version 1.0 + */ + public enum StuddedArmour { + CHAPS(new Item(1095), new Item(1097), 44, 42), BODY(new Item(1129), new Item(1133), 41, 40); + + /** + * Represents the unstudded item. + */ + private final Item item; + + /** + * Represents the studded item. + */ + private final Item studded; + + /** + * Represents the level needed. + */ + private final int level; + + /** + * Represents the experience gained. + */ + private final double experience; + + /** + * Constructs a new {@code StuddedArmour} {@code Object}. + * @param item the item. + * @param studded the studded item. + * @param level the level. + * @param experience the experience. + */ + private StuddedArmour(Item item, Item studded, int level, double experience) { + this.item = item; + this.studded = studded; + this.level = level; + this.experience = experience; + } + + /** + * Gets the studded armour for the item. + * @param item the item. + * @return the studden armour. + */ + public static StuddedArmour forItem(final Item item) { + for (StuddedArmour armour : values()) { + if (armour.getItem().getId() == item.getId()) { + return armour; + } + } + return null; + } + + /** + * Gets the item. + * @return The item. + */ + public Item getItem() { + return item; + } + + /** + * Gets the studded. + * @return The studded. + */ + public Item getStudded() { + return studded; + } + + /** + * Gets the level. + * @return The level. + */ + public int getLevel() { + return level; + } + + /** + * Gets the experience. + * @return The experience. + */ + public double getExperience() { + return experience; + } + + } + + /** + * Represents the skill pulse used to stud armour. + * @author 'Vexia + * @version 1.0 + */ + public static final class StudArmourPulse extends SkillPulse { + + /** + * Represents the animation to use. + */ + private static final Animation ANIMATION = Animation.create(1249); + + /** + * Represents the armour being studded. + */ + private final StuddedArmour armour; + + /** + * Represents the amount to make. + */ + private int amount; + + /** + * Represents the ticks passed. + */ + private int ticks; + + /** + * Constructs a new {@code StudArmourPulse} {@code Object}. + * @param player the player. + * @param node the node. + * @param armour the armour. + * @param amount the amount. + */ + public StudArmourPulse(Player player, Item node, final StuddedArmour armour, final int amount) { + super(player, node); + this.armour = armour; + this.amount = amount; + } + + @Override + public boolean checkRequirements() { + if (player.getSkills().getLevel(Skills.CRAFTING) < armour.getLevel()) { + player.getPacketDispatch().sendMessage("You need a Crafting level of at least " + armour.getLevel() + " to do this."); + return false; + } + if (!player.getInventory().containsItem(STEEL_STUDS)) { + player.getPacketDispatch().sendMessage("You need studs in order to make studded armour."); + return false; + } + if (!player.getInventory().containsItem(armour.getItem())) { + return false; + } + return true; + } + + @Override + public void animate() { + if (ticks % 5 == 0) { + player.animate(ANIMATION); + } + } + + @Override + public boolean reward() { + if (++ticks % 5 != 0) { + return false; + } + if (player.getInventory().remove(armour.getItem(), STEEL_STUDS)) { + player.getInventory().add(armour.getStudded()); + player.getSkills().addExperience(Skills.CRAFTING, armour.getExperience(), true); + player.getPacketDispatch().sendMessage("You make a " + armour.getStudded().getName().toLowerCase() + "."); + } + amount--; + return amount < 1; + } + + @Override + public void message(int type) { + switch (type) { + case 0: + player.getPacketDispatch().sendMessage("You use the studs with the " + node.getName().toLowerCase() + "."); + break; + } + } + } +} diff --git a/Server/src/main/content/global/skill/crafting/TanningProduct.java b/Server/src/main/content/global/skill/crafting/TanningProduct.java new file mode 100644 index 0000000..30192b4 --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/TanningProduct.java @@ -0,0 +1,155 @@ +package content.global.skill.crafting; + +import core.cache.def.impl.ItemDefinition; +import core.game.component.Component; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.item.Item; + +/** + * Represents a tanning product. + * @author Vexia + * @version 1.1 + */ +public enum TanningProduct { + SOFT_LEATHER(1, 1739, 1741), + HARD_LEATHER(2, 1739, 1743), + SNAKESKIN(3, 6287, 6289), + SNAKESKIN2(4, 7801, 6289), + GREEN_DHIDE(5, 1753, 1745), + BLUEDHIDE(6, 1751, 2505), + REDDHIDE(7, 1749, 2507), + BLACKDHIDE(8, 1747, 2509); + + /** + * The button. + */ + private final int button; + + /** + * The item needed. + */ + private final int item; + + /** + * The product. + */ + private final int product; + + /** + * Constructs a new {@code TanningProduct} {@Code Object} + * @param button the button. + * @param item the item. + * @param product the product. + */ + TanningProduct(int button, int item, int product) { + this.button = button; + this.item = item; + this.product = product; + } + + /** + * @return the button. + */ + public int getButton() { + return button; + } + + /** + * @return the item. + */ + public int getItem() { + return item; + } + + /** + * @return the product. + */ + public int getProduct() { + return product; + } + + /** + * Gets the product by the id. + * @param id the id. + * @return the product. + */ + public static TanningProduct forId(int id) { + for (TanningProduct def : TanningProduct.values()) { + if (def.getButton() == id) { + return def; + } + } + return null; + } + + /** + * Gets the product by the id. + * @param id the id. + * @return te product. + */ + public static TanningProduct forItemId(int id) { + for (TanningProduct def : TanningProduct.values()) { + if (def.getItem() == id) { + return def; + } + } + return null; + } + + /** + * Method used to open the tanning interface. + */ + public static void open(final Player player, final int npc) { + player.getInterfaceManager().open(new Component(324)); + //Removed all the string modification that was here earlier -- it seems the client automatically does it now. + } + + /** + * Method used to tan the hide. + * @param player the player. + * @param amount the amount. + */ + public static void tan(final Player player, int amount, TanningProduct def) { + if (amount > player.getInventory().getAmount(new Item(def.getItem()))) { + amount = player.getInventory().getAmount(new Item(def.getItem())); + } + int coins = 0; + if (def == SOFT_LEATHER) { + coins = 1; + } else if (def == HARD_LEATHER) { + coins = 3; + } else if (def == SNAKESKIN) { + coins = 15; + } else if (def == SNAKESKIN2) { + coins = 20; + } else { + coins = 20; + } + if (amount == 0) { + return; + } + if (!player.getInventory().contains(def.getItem(), amount)) { + player.getPacketDispatch().sendMessage("You don't have any " + ItemDefinition.forId(def.getItem()).getName().toLowerCase() + " to tan."); + return; + } + player.getInterfaceManager().close(); + if (!player.getInventory().contains(995, coins * amount)) { + player.getPacketDispatch().sendMessage("You don't have enough coins to tan that many."); + return; + } + if (player.getInventory().remove(new Item(995, coins * amount)) && player.getInventory().remove(new Item(def.getItem(), amount))) { + player.getInventory().add(new Item(def.getProduct(), amount)); + if (amount > 1) { + player.getPacketDispatch().sendMessage("The tanner tans " + amount + " " + ItemDefinition.forId(def.getItem()).getName().toLowerCase() + "s for you."); + } else { + player.getPacketDispatch().sendMessage("The tanner tans your " + ItemDefinition.forId(def.getItem()).getName().toLowerCase() + "."); + } + if (def == SOFT_LEATHER) { + player.getAchievementDiaryManager().finishTask(player, DiaryType.LUMBRIDGE, 1, 2); + } + } else { + player.getPacketDispatch().sendMessage("You don't have enough coins to tan that many."); + } + } +} diff --git a/Server/src/main/content/global/skill/crafting/WeaveOptionPlugin.java b/Server/src/main/content/global/skill/crafting/WeaveOptionPlugin.java new file mode 100644 index 0000000..4307d45 --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/WeaveOptionPlugin.java @@ -0,0 +1,204 @@ +package content.global.skill.crafting; + +import core.cache.def.impl.SceneryDefinition; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.game.dialogue.SkillDialogueHandler; +import core.game.dialogue.SkillDialogueHandler.SkillDialogue; +import core.game.node.entity.skill.SkillPulse; +import core.game.node.entity.skill.Skills; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; +import core.tools.StringUtils; + +/** + * Represents the plugin used for weaving. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class WeaveOptionPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.setOptionHandler("weave", this); + return this; + } + + @Override + public boolean handle(final Player player, final Node node, String option) { + new SkillDialogueHandler(player, SkillDialogue.THREE_OPTION, WeavingItem.SACK.getProduct(), WeavingItem.BASKET.getProduct(), WeavingItem.CLOTH.getProduct()) { + @Override + public void create(int amount, int index) { + player.getPulseManager().run(new WeavePulse(player, (Scenery) node, WeavingItem.values()[index], amount)); + } + }.open(); + return true; + } + + /** + * Represents the weaving pulse. + * @author 'Vexia + * @version 1.0 + */ + public static final class WeavePulse extends SkillPulse { + + /** + * Represents the animation to use. + */ + private static final Animation ANIMATION = new Animation(2270); + + /** + * Represents the weaving item. + */ + private final WeavingItem type; + + /** + * Represents the amount. + */ + private int amount; + + /** + * Represents the ticks passed. + */ + private int ticks; + + /** + * Constructs a new {@code WeavePulse} {@code Object}. + * @param player the player. + * @param node the node. + * @param amount the amount. + */ + public WeavePulse(Player player, Scenery node, final WeavingItem type, final int amount) { + super(player, node); + this.type = type; + this.amount = amount; + } + + @Override + public boolean checkRequirements() { + if (player.getSkills().getLevel(Skills.CRAFTING) < type.getLevel()) { + player.getPacketDispatch().sendMessage("You need a Crafting level of at least " + type.getLevel() + " in order to do this."); + return false; + } + if (!player.getInventory().containsItem(type.getRequired())) { + player.getPacketDispatch().sendMessage("You need " + type.getRequired().getAmount() + " " + type.getRequired().getName().toLowerCase().replace("ball", "balls") + "" + (type == WeavingItem.SACK ? "s" : type == WeavingItem.CLOTH ? "" : "es") + " to weave " + (StringUtils.isPlusN(type.getProduct().getName().toLowerCase()) ? "an" : "a") + " " + type.getProduct().getName().toLowerCase() + "."); + return false; + } + return true; + } + + @Override + public void animate() { + if (ticks % 5 == 0) { + player.animate(ANIMATION); + } + } + + @Override + public boolean reward() { + if (++ticks % 5 != 0) { + return false; + } + if (player.getInventory().remove(type.getRequired())) { + player.getInventory().add(type.getProduct()); + player.getSkills().addExperience(Skills.CRAFTING, type.getExperience(), true); + player.getPacketDispatch().sendMessage("You weave the " + + type.getRequired().getName().toLowerCase().replace("ball", "balls") + + "" + (type == WeavingItem.SACK ? "s" : type == WeavingItem.CLOTH ? "" : "es") + + " into " + (StringUtils.isPlusN(type.getProduct().getName().toLowerCase()) ? "an" : "a") + + " " + type.getProduct().getName().toLowerCase() + "."); + if (type == WeavingItem.BASKET && node.getId() == 8717 && player.getLocation().withinDistance(new Location(3039,3287,0)) + && !player.getAchievementDiaryManager().getDiary(DiaryType.FALADOR).isComplete(1,0)) { + player.getAchievementDiaryManager().getDiary(DiaryType.FALADOR).updateTask(player,1,0, true); + } + } + amount--; + return amount < 1; + } + + } + + /** + * Represents a weaving item. + * @author 'Vexia + * @version 1.0 + */ + public enum WeavingItem { + SACK(new Item(5418), new Item(5931, 4), 21, 38), + BASKET(new Item(5376), new Item(5933, 6), 36, 56), + CLOTH(new Item(3224), new Item(1759, 4), 10, 12); + + /** + * Represents the product. + */ + private final Item product; + + /** + * Represents the required required. + */ + private final Item required; + + /** + * Represents the level needed. + */ + private final int level; + + /** + * Represents the experience gained. + */ + private final double experience; + + /** + * Constructs a new {@code WeavingItem} {@code Object}. + * @param product the product. + * @param level the level. + * @param required the required. + * @param experience the experience. + */ + private WeavingItem(Item product, final Item required, int level, double experience) { + this.product = product; + this.required = required; + this.level = level; + this.experience = experience; + } + + /** + * Gets the product. + * @return The product. + */ + public Item getProduct() { + return product; + } + + /** + * Gets the required. + * @return The required + */ + public Item getRequired() { + return required; + } + + /** + * Gets the level. + * @return The level. + */ + public int getLevel() { + return level; + } + + /** + * Gets the experience. + * @return The experience. + */ + public double getExperience() { + return experience; + } + } +} diff --git a/Server/src/main/content/global/skill/crafting/armour/DragonCraftPulse.java b/Server/src/main/content/global/skill/crafting/armour/DragonCraftPulse.java new file mode 100644 index 0000000..924d136 --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/armour/DragonCraftPulse.java @@ -0,0 +1,107 @@ +package content.global.skill.crafting.armour; + +import core.cache.def.impl.ItemDefinition; +import core.game.node.entity.skill.SkillPulse; +import core.game.node.entity.skill.Skills; +import content.global.skill.crafting.armour.LeatherCrafting.DragonHide; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; +import core.tools.StringUtils; + +/** + * Represents a pulse used to craft dragon armour. + * @author 'Vexia + */ +public final class DragonCraftPulse extends SkillPulse { + + /** + * Represents the animation to use. + */ + private static final Animation ANIMATION = Animation.create(1249); + + /** + * Represents the dragon hide type. + */ + private DragonHide hide; + + /** + * Represents the amount to make. + */ + private int amount; + + /** + * Represents the ticks passed. + */ + private int ticks; + + /** + * Constructs a new {@code DragonCraftPulse} {@code Object}. + * @param player the player. + * @param node the node. + * @param amount the amount. + */ + public DragonCraftPulse(Player player, Item node, DragonHide hide, int amount) { + super(player, node); + this.hide = hide; + this.amount = amount; + } + + @Override + public boolean checkRequirements() { + if (player.getSkills().getLevel(Skills.CRAFTING) < hide.getLevel()) { + player.getDialogueInterpreter().sendDialogue("You need a crafting level of " + hide.getLevel() + " to make " + ItemDefinition.forId(hide.getProduct()).getName() + "."); + amount = 0; + return false; + } + if (!player.getInventory().contains(LeatherCrafting.NEEDLE, 1)) { + player.getDialogueInterpreter().sendDialogue("You need a needle to make this."); + amount = 0; + return false; + } + if (!player.getInventory().containsItem(LeatherCrafting.THREAD)) { + player.getDialogueInterpreter().sendDialogue("You need thread to make this."); + amount = 0; + return false; + } + if (!player.getInventory().contains(hide.getLeather(), hide.getAmount())) { + player.getDialogueInterpreter().sendDialogue("You need " + hide.getAmount() + " " + ItemDefinition.forId(hide.getLeather()).getName().toLowerCase() + " to make this."); + amount = 0; + return false; + } + player.getInterfaceManager().close(); + return true; + } + + @Override + public void animate() { + if (ticks % 5 == 0) { + player.animate(ANIMATION); + } + } + + @Override + public boolean reward() { + if (++ticks % 5 != 0) { + return false; + } + if (player.getInventory().remove(new Item(hide.getLeather(), hide.getAmount()))) { + if (hide.name().contains("VAMBS")) { + player.getPacketDispatch().sendMessage("You make a pair of " + ItemDefinition.forId(hide.getProduct()).getName().toLowerCase() + "'s."); + } else { + player.getPacketDispatch().sendMessage("You make " + (StringUtils.isPlusN(ItemDefinition.forId(hide.getProduct()).getName().toLowerCase()) ? "an" : "a") + " " + ItemDefinition.forId(hide.getProduct()).getName().toLowerCase() + "."); + } + Item item = new Item(hide.getProduct()); + player.getInventory().add(item); + player.getSkills().addExperience(Skills.CRAFTING, hide.getExperience(), true); + LeatherCrafting.decayThread(player); + amount--; + } + return amount < 1; + } + + @Override + public void message(int type) { + + } +} diff --git a/Server/src/main/content/global/skill/crafting/armour/HardCraftPulse.java b/Server/src/main/content/global/skill/crafting/armour/HardCraftPulse.java new file mode 100644 index 0000000..5a2207b --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/armour/HardCraftPulse.java @@ -0,0 +1,83 @@ +package content.global.skill.crafting.armour; + +import core.game.node.entity.skill.SkillPulse; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; + +/** + * Represents the pulse used to craft hard leather. + * @author 'Vexia + */ +public final class HardCraftPulse extends SkillPulse { + + /** + * Represents the animation to use. + */ + private static final Animation ANIMATION = Animation.create(1249); + + /** + * Represents the amount to make. + */ + private int amount; + + /** + * Represents the ticks passed. + */ + private int ticks; + + /** + * Constructs a new {@code HardCraftPulse} {@code Object}. + * @param player the player. + * @param node the node. + * @param amount the amount. + */ + public HardCraftPulse(Player player, Item node, int amount) { + super(player, node); + this.amount = amount; + } + + @Override + public boolean checkRequirements() { + if (player.getSkills().getLevel(Skills.CRAFTING) < 28) { + player.getDialogueInterpreter().sendDialogue("You need a crafting level of " + 28 + " to make a hardleather body."); + return false; + } + if (!player.getInventory().contains(LeatherCrafting.NEEDLE, 1)) { + return false; + } + if (!player.getInventory().contains(LeatherCrafting.HARD_LEATHER, 1)) { + return false; + } + if (!player.getInventory().containsItem(LeatherCrafting.THREAD)) { + player.getDialogueInterpreter().sendDialogue("You need thread to make this."); + return false; + } + player.getInterfaceManager().close(); + return true; + } + + @Override + public void animate() { + if (ticks % 5 == 0) { + player.animate(ANIMATION); + } + } + + @Override + public boolean reward() { + if (++ticks % 5 != 0) { + return false; + } + if (player.getInventory().remove(new Item(LeatherCrafting.HARD_LEATHER))) { + Item item = new Item(1131); + player.getInventory().add(item); + player.getSkills().addExperience(Skills.CRAFTING, 35, true); + LeatherCrafting.decayThread(player); + } + amount--; + return amount < 1; + } + +} diff --git a/Server/src/main/content/global/skill/crafting/armour/LeatherCrafting.java b/Server/src/main/content/global/skill/crafting/armour/LeatherCrafting.java new file mode 100644 index 0000000..02f14d1 --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/armour/LeatherCrafting.java @@ -0,0 +1,263 @@ +package content.global.skill.crafting.armour; + +import core.api.Container; +import core.game.component.Component; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import org.rs09.consts.Items; + +import static core.api.ContentAPIKt.*; + +/** + * Represents a useful class for leather crafting related information. + * @author 'Vexia + */ +public final class LeatherCrafting { + + /** + * Constant of a needle id. + */ + public static final int NEEDLE = 1733; + + /** + * Constant of a thread id. + */ + public static final Item THREAD = new Item(1734, 1); + + /** + * Constant of a needle id. + */ + public static final int LEATHER = 1741; + + /** + * Constant of a thread id. + */ + public static final int HARD_LEATHER = 1743; + + /** + * The constants of leather id's related to dragon hides. + */ + public static final int GREEN_LEATHER = 1745, BLUE_LEATHER = 2505, RED_LEATHER = 2507, BLACK_LEATHER = 2509; + + /** + * The leather interface component. + */ + private static final Component COMPONENT = new Component(154); + + /** + * Method used to decay thread. + * @author Player Name + */ + public static void decayThread(final Player player) { + int charges = getAttribute(player, "threadCharges", 5) - 1; + if (charges <= 0 && removeItem(player, Items.THREAD_1734, Container.INVENTORY)) { + charges = 5; + sendMessage(player, "You use a reel of your thread."); + } + setAttribute(player, "/save:threadCharges", charges); + } + + /** + * Represents the dragon hide crafting data. + * @author 'Vexia + */ + public enum DragonHide { + GREEN_D_HIDE_VAMBS(1745, 1, 1065, 57, 62), + GREEN_D_HIDE_CHAPS(1745, 2, 1099, 60, 124), + GREEN_D_HIDE_BODY(1745, 3, 1135, 63, 186), + BLUE_D_HIDE_VAMBS(2505, 1, 2487, 66, 70), + BLUE_D_HIDE_CHAPS(2505, 2, 2493, 68, 140), + BLUE_D_HIDE_BODY(2505, 3, 2499, 71, 210), + RED_D_HIDE_VAMBS(2507, 1, 2489, 73, 78), + RED_D_HIDE_CHAPS(2507, 2, 2495, 75, 156), + RED_D_HIDE_BODY(2507, 3, 2501, 77, 234), + BLACK_D_HIDE_VAMBS(2509, 1, 2491, 79, 86), + BLACK_D_HIDE_CHAPS(2509, 2, 2497, 82, 172), + BLACK_D_HIDE_BODY(2509, 3, 2503, 84, 258); + + /** + * Constructs a new {@code LeatherCrafting.java} {@code Object}. + * @param leather the leather required. + * @param amount the amount of leather needed. + * @param product the product item. + * @param level the level required. + * @param experience the experience. + */ + DragonHide(int leather, int amount, int product, int level, double experience) { + this.leather = leather; + this.amount = amount; + this.product = product; + this.level = level; + this.experience = experience; + } + + /** + * The leather id. + */ + private final int leather; + + /** + * The leather amount required. + */ + private final int amount; + + /** + * The product. + */ + private final int product; + + /** + * The required level. + */ + private final int level; + + /** + * The experiences gained. + */ + private final double experience; + + /** + * @return the leather. + */ + public int getLeather() { + return leather; + } + + /** + * @return the amount. + */ + public int getAmount() { + return amount; + } + + /** + * @return the product. + */ + public int getProduct() { + return product; + } + + /** + * @return the level. + */ + public int getLevel() { + return level; + } + + /** + * @return the experience. + */ + public double getExperience() { + return experience; + } + + /** + * Method used to return the type for the leather. + * @param leather the leather. + * @return the hide. + */ + public static DragonHide forLeather(int leather) { + for (DragonHide hide : DragonHide.values()) { + if (hide.getLeather() == leather) { + return hide; + } + } + return null; + } + } + + /** + * Represents an enumeration of soft leather crafting values. + * @author 'Vexia + */ + public enum SoftLeather { + ARMOUR(28, 14, 25, new Item(1129)), + GLOVES(29, 1, 13.8, new Item(1059)), + BOOTS(30, 7, 16.3, new Item(1061)), + VAMBRACES(31, 11, 22, new Item(1063)), + CHAPS(32, 18, 27, new Item(1095)), + COIF(33, 38, 37, new Item(1169)), + COWL(34, 9, 18.5, new Item(1167)); + + /** + * Constructs a new {@code Soft} {@code Object}. + * @param level the level. + * @param experience the experience. + * @param product the product. + */ + SoftLeather(int button, int level, double experience, Item product) { + this.button = button; + this.level = level; + this.experience = experience; + this.product = product; + } + + /** + * The button. + */ + private final int button; + + /** + * The level required. + */ + private final int level; + + /** + * The experience gained. + */ + private final double experience; + + /** + * The product. + */ + private final Item product; + + /** + * Method used to open the crafting interface. + * @param player the player. + */ + public static void open(final Player player) { + player.getInterfaceManager().open(COMPONENT); + } + + /** + * @return the level. + */ + public int getLevel() { + return level; + } + + /** + * @return the experience. + */ + public double getExperience() { + return experience; + } + + /** + * @return the product. + */ + public Item getProduct() { + return product; + } + + /** + * @return the button. + */ + public int getButton() { + return button; + } + + /** + * Method used to get the value by the id. + */ + public static SoftLeather forButton(int button) { + for (SoftLeather soft : SoftLeather.values()) { + if (soft.getButton() == button) { + return soft; + } + } + return null; + } + } +} diff --git a/Server/src/main/content/global/skill/crafting/armour/SnakeSkin.java b/Server/src/main/content/global/skill/crafting/armour/SnakeSkin.java new file mode 100644 index 0000000..c4468d2 --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/armour/SnakeSkin.java @@ -0,0 +1,78 @@ +package content.global.skill.crafting.armour; + +import core.game.node.item.Item; + +/** + * A snake skin. + * @author Vexia + */ +public enum SnakeSkin { + SNAKESKIN_BOOT(new Item(6328), 45, 30, 6), SNAKESKIN_VAMBRACES(new Item(6330), 47, 35, 8), SNAKESKIN_BANDANA(new Item(6326), 48, 45, 5), SNAKESKIN_CHAPS(new Item(6324), 51, 50, 12), SNAKESKIN_BODY(new Item(6322), 53, 55, 15); + + /** + * The item product. + */ + private final Item product; + + /** + * The level. + */ + private final int level; + + /** + * The experience. + */ + private final double experience; + + /** + * The required amount of snakeskins. + */ + private final int requiredAmount; + + /** + * Constructs a new {@Code SnakeSkin} {@Code Object} + * @param product the product. + * @param level the level. + * @param experience the exp. + * @param requiredAmount the required amount. + */ + private SnakeSkin(Item product, int level, double experience, int requiredAmount) { + this.product = product; + this.level = level; + this.experience = experience; + this.requiredAmount = requiredAmount; + } + + /** + * Gets the product. + * @return the product + */ + public Item getProduct() { + return product; + } + + /** + * Gets the level. + * @return the level + */ + public int getLevel() { + return level; + } + + /** + * Gets the experience. + * @return the experience + */ + public double getExperience() { + return experience; + } + + /** + * Gets the requiredAmount. + * @return the requiredAmount + */ + public int getRequiredAmount() { + return requiredAmount; + } + +} diff --git a/Server/src/main/content/global/skill/crafting/armour/SnakeSkinPulse.java b/Server/src/main/content/global/skill/crafting/armour/SnakeSkinPulse.java new file mode 100644 index 0000000..be012d0 --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/armour/SnakeSkinPulse.java @@ -0,0 +1,90 @@ +package content.global.skill.crafting.armour; + +import core.game.node.entity.skill.SkillPulse; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; + +/** + * Represents the pulse used to craft snake skin. + * @author 'Vexia + */ +public final class SnakeSkinPulse extends SkillPulse { + + /** + * Represents the animation to use. + */ + private static final Animation ANIMATION = Animation.create(1249); + + /** + * The snake skin. + */ + private final SnakeSkin skin; + + /** + * Represents the amount to make. + */ + private int amount; + + /** + * Represents the ticks passed. + */ + private int ticks; + + /** + * Constructs a new {@code HardCraftPulse} {@code Object}. + * @param player the player. + * @param node the node. + * @param amount the amount. + */ + public SnakeSkinPulse(Player player, Item node, int amount, SnakeSkin skin) { + super(player, node); + this.amount = amount; + this.skin = skin; + } + + @Override + public boolean checkRequirements() { + if (player.getSkills().getLevel(Skills.CRAFTING) < skin.getLevel()) { + player.getDialogueInterpreter().sendDialogue("You need a crafting level of " + skin.getLevel() + " to make this."); + return false; + } + if (!player.getInventory().contains(LeatherCrafting.NEEDLE, 1)) { + return false; + } + if (!player.getInventory().containsItem(LeatherCrafting.THREAD)) { + player.getDialogueInterpreter().sendDialogue("You need thread to make this."); + return false; + } + if (!player.getInventory().contains(6289, skin.getRequiredAmount())) { + player.getDialogueInterpreter().sendDialogue("You need " + skin.getRequiredAmount() + " snakeskins in order to do this."); + return false; + } + player.getInterfaceManager().close(); + return true; + } + + @Override + public void animate() { + if (ticks % 5 == 0) { + player.animate(ANIMATION); + } + } + + @Override + public boolean reward() { + if (++ticks % 5 != 0) { + return false; + } + if (player.getInventory().remove(new Item(6289, skin.getRequiredAmount()))) { + Item item = skin.getProduct(); + player.getInventory().add(item); + player.getSkills().addExperience(Skills.CRAFTING, skin.getExperience(), true); + LeatherCrafting.decayThread(player); + } + amount--; + return amount < 1; + } + +} diff --git a/Server/src/main/content/global/skill/crafting/armour/SoftCraftPulse.java b/Server/src/main/content/global/skill/crafting/armour/SoftCraftPulse.java new file mode 100644 index 0000000..ab49815 --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/armour/SoftCraftPulse.java @@ -0,0 +1,101 @@ +package content.global.skill.crafting.armour; + +import core.game.node.entity.skill.SkillPulse; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; +import core.tools.StringUtils; + +/** + * Represents a pulse used to craft soft leather. + * @author 'Vexia + */ +public final class SoftCraftPulse extends SkillPulse { + + /** + * Represents the animation to use. + */ + private static final Animation ANIMATION = Animation.create(1249); + + /** + * Represents the leather to use. + */ + private LeatherCrafting.SoftLeather soft; + + /** + * Represents the amount to make. + */ + private int amount; + + /** + * Represents the ticks passed. + */ + private int ticks; + + /** + * Constructs a new {@code SoftCraftPulse} {@code Object}. + * @param player the player. + * @param node the node. + * @param leather the soft. + * @param amount the amount. + */ + public SoftCraftPulse(Player player, Item node, LeatherCrafting.SoftLeather leather, int amount) { + super(player, node); + this.soft = leather; + this.amount = amount; + } + + @Override + public boolean checkRequirements() { + if (player.getSkills().getLevel(Skills.CRAFTING) < soft.getLevel()) { + player.getDialogueInterpreter().sendDialogue("You need a crafting level of " + soft.getLevel() + " to make " + (StringUtils.isPlusN(soft.getProduct().getName()) ? "an" : "a" + " " + soft.getProduct().getName()).toLowerCase() + "."); + return false; + } + if (!player.getInventory().contains(LeatherCrafting.NEEDLE, 1)) { + return false; + } + if (!player.getInventory().contains(LeatherCrafting.LEATHER, 1)) { + return false; + } + if (!player.getInventory().containsItem(LeatherCrafting.THREAD)) { + player.getDialogueInterpreter().sendDialogue("You need thread to make this."); + amount = 0; + return false; + } + player.getInterfaceManager().close(); + return true; + } + + @Override + public void animate() { + if (ticks % 5 == 0) { + player.animate(ANIMATION); + } + } + + @Override + public boolean reward() { + if (++ticks % 5 != 0) { + return false; + } + if (player.getInventory().remove(new Item(LeatherCrafting.LEATHER))) { + if (soft == LeatherCrafting.SoftLeather.GLOVES || soft == LeatherCrafting.SoftLeather.BOOTS || soft == LeatherCrafting.SoftLeather.VAMBRACES) { + player.getPacketDispatch().sendMessage("You make a pair of " + soft.getProduct().getName().toLowerCase() + "."); + } else { + player.getPacketDispatch().sendMessage("You make " + (StringUtils.isPlusN(soft.getProduct().getName()) ? "an " : "a ") + soft.getProduct().getName().toLowerCase() + "."); + } + Item item = soft.getProduct(); + player.getInventory().add(item); + player.getSkills().addExperience(Skills.CRAFTING, soft.getExperience(), true); + LeatherCrafting.decayThread(player); + if (soft == LeatherCrafting.SoftLeather.GLOVES) { + player.getAchievementDiaryManager().finishTask(player, DiaryType.LUMBRIDGE, 1, 3); + } + } + amount--; + return amount < 1; + } + +} diff --git a/Server/src/main/content/global/skill/crafting/gem/GemCutPulse.java b/Server/src/main/content/global/skill/crafting/gem/GemCutPulse.java new file mode 100644 index 0000000..f094fa8 --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/gem/GemCutPulse.java @@ -0,0 +1,82 @@ +package content.global.skill.crafting.gem; + +import core.game.node.entity.skill.SkillPulse; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playAudio; + +/** + * Represents the pulse used to cut a gem. + * @author 'Vexia + */ +public final class GemCutPulse extends SkillPulse { + + /** + * Represents the chisel item. + */ + private static final Item CHISEL = new Item(1755); + + /** + * Represents the gem to cut. + */ + private final Gems gem; + + /** + * Represents the amount to make. + */ + private int amount; + + /** + * Represents the ticks passed. + */ + private int ticks; + + /** + * Constructs a new {@code GemCuttingPulse} {@Code Object} + * @param player the player. + * @param item the item cut. + */ + public GemCutPulse(Player player, Item item, int ammount, final Gems gem) { + super(player, item); + this.amount = ammount; + this.gem = gem; + this.resetAnimation = false; + } + + @Override + public boolean checkRequirements() { + if (!player.getInventory().containsItem(CHISEL)) { + return false; + } + if (!player.getInventory().containsItem(gem.getUncut())) { + return false; + } + if (player.getSkills().getLevel(Skills.CRAFTING) < gem.getLevel()) { + player.getPacketDispatch().sendMessage("You need a crafting level of " + gem.getLevel() + " to craft this gem."); + return false; + } + return true; + } + + @Override + public void animate() { + if (ticks % 5 == 0 || ticks < 1) { + playAudio(player, Sounds.CHISEL_2586); + player.animate(gem.getAnimation()); + } + } + + @Override + public boolean reward() { + if (player.getInventory().remove(gem.getUncut())) { + final Item item = gem.getGem(); + player.getInventory().add(item); + player.getSkills().addExperience(Skills.CRAFTING, gem.getExp(), true); + } + amount--; + return amount < 1; + } +} diff --git a/Server/src/main/content/global/skill/crafting/gem/Gems.java b/Server/src/main/content/global/skill/crafting/gem/Gems.java new file mode 100644 index 0000000..0d01981 --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/gem/Gems.java @@ -0,0 +1,114 @@ +package content.global.skill.crafting.gem; + +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; + +/** + * Represents a gem enumeration. + * @author 'Vexia + */ +public enum Gems { + SAPPHIRE(new Item(1623), new Item(1607), 20, new Animation(888), 50), + EMERALD(new Item(1621), new Item(1605), 27, new Animation(889), 67), + RUBY(new Item(1619), new Item(1603), 34, new Animation(887), 85), + DIAMOND(new Item(1617), new Item(1601), 43, new Animation(886), 107.5), + DRAGONSTONE(new Item(1631), new Item(1615), 55, new Animation(885), 137.5), + ONYX(new Item(6571), new Item(6573), 67, new Animation(2717), 168), + OPAL(new Item(1625), new Item(1609), 1, new Animation(890), 10), + JADE(new Item(1627), new Item(1611), 13, new Animation(891), 20), + RED_TOPAZ(new Item(1629), new Item(1613), 16, new Animation(892), 25); + + /** + * Represents the raw gem. + */ + private final Item uncut; + + /** + * Represents the gem cut. + */ + private final Item gem; + + /** + * Represents the level needed. + */ + private final int level; + + /** + * Represents the animation used. + */ + private final Animation animation; + + /** + * Represents the experience gained. + */ + private final double exp; + + /** + * Constructs a new {@code Gems} {@code Object}. + * @param uncut the uncut. + * @param gem the gem. + * @param level the level. + * @param animation the animation. + * @param exp the exp. + */ + private Gems(Item uncut, Item gem, int level, Animation animation, double exp) { + this.uncut = uncut; + this.gem = gem; + this.level = level; + this.animation = animation; + this.exp = exp; + } + + /** + * Gets the gem by the id. + * @return the gem. + */ + public static Gems forId(final Item item) { + for (Gems gem : Gems.values()) { + if (gem.getUncut().getId() == item.getId()) { + return gem; + } + } + return null; + } + + /** + * Gets the uncut. + * @return The uncut. + */ + public Item getUncut() { + return uncut; + } + + /** + * Gets the gem. + * @return The gem. + */ + public Item getGem() { + return gem; + } + + /** + * Gets the level. + * @return The level. + */ + public int getLevel() { + return level; + } + + /** + * Gets the animation. + * @return The animation. + */ + public Animation getAnimation() { + return animation; + } + + /** + * Gets the exp. + * @return The exp. + */ + public double getExp() { + return exp; + } +} diff --git a/Server/src/main/content/global/skill/crafting/glass/GlassCraftingListener.kt b/Server/src/main/content/global/skill/crafting/glass/GlassCraftingListener.kt new file mode 100644 index 0000000..84f0c19 --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/glass/GlassCraftingListener.kt @@ -0,0 +1,69 @@ +package content.global.skill.crafting.glass + +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.interaction.InterfaceListener +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import org.rs09.consts.Components +import org.rs09.consts.Items + +class GlassCraftingListener : InteractionListener, InterfaceListener { + + companion object { + private const val OP_MAKE_ONE = 155 + private const val OP_MAKE_FIVE = 196 + private const val OP_MAKE_ALL = 124 + private const val OP_MAKE_X = 199 + + private const val GLASS_BLOWING_PIPE = Items.GLASSBLOWING_PIPE_1785 + private const val MOLTEN_GLASS = Items.MOLTEN_GLASS_1775 + private const val GLASS_BLOWING_INTERFACE = Components.CRAFTING_GLASS_542 + } + + override fun defineListeners() { + onUseWith(IntType.ITEM, GLASS_BLOWING_PIPE, MOLTEN_GLASS) { player, _, _ -> + openInterface(player, GLASS_BLOWING_INTERFACE) + return@onUseWith true + } + } + + override fun defineInterfaceListeners() { + on(GLASS_BLOWING_INTERFACE) { player, _, opcode, buttonID, _, _ -> + val product = GlassProduct.forButtonID(buttonID) ?: return@on true + + if (!inInventory(player, GLASS_BLOWING_PIPE)) { + sendMessage(player, "You need a glassblowing pipe to do this.") + return@on true + } + + if (!inInventory(player, MOLTEN_GLASS)) { + sendMessage(player, "You need molten glass to do this.") + return@on true + } + + if (!hasLevelDyn(player, Skills.CRAFTING, product.minimumLevel)) { + sendMessage(player, "You need a Crafting level of ${product.minimumLevel} to make this.") + return@on true + } + + when (opcode) { + OP_MAKE_ONE -> make(player, product, 1) + OP_MAKE_FIVE -> make(player, product, 5) + OP_MAKE_ALL -> make(player, product, amountInInventory(player, MOLTEN_GLASS)) + OP_MAKE_X -> sendInputDialogue(player, InputType.AMOUNT, "Enter the amount:") { value -> + make(player, product, Integer.parseInt(value.toString())) + } + else -> return@on true + } + + return@on true + } + } + + private fun make(player: Player, product: GlassProduct, amount: Int) { + closeInterface(player) + submitIndividualPulse(player, GlassCraftingPulse(player, product, amount)) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/crafting/glass/GlassCraftingPulse.kt b/Server/src/main/content/global/skill/crafting/glass/GlassCraftingPulse.kt new file mode 100644 index 0000000..f287ff9 --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/glass/GlassCraftingPulse.kt @@ -0,0 +1,44 @@ +package content.global.skill.crafting.glass + +import core.api.* +import core.game.event.ResourceProducedEvent +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.system.task.Pulse +import org.rs09.consts.Items +import org.rs09.consts.Sounds + +class GlassCraftingPulse( + private val player: Player, + private val product: GlassProduct, + private var amount: Int +) : Pulse() { + + override fun pulse(): Boolean { + if (amount < 1) return true + + if (!inInventory(player, Items.GLASSBLOWING_PIPE_1785) || !inInventory(player, Items.MOLTEN_GLASS_1775)) { + return true + } + + //Animation is updated on 2 June 2009 - https://runescape.wiki/w/Update:Patch_Notes_(2_June_2009) + animate(player, 884) + playAudio(player, Sounds.GLASSBLOWING_2724) + if (product.producedItemId in intArrayOf(Items.UNPOWERED_ORB_567, Items.OIL_LAMP_4525)) { + sendMessage(player, "You make an ${product.name.lowercase().replace("_", " ")}.") + + } else sendMessage(player, "You make a ${product.name.lowercase().replace("_", " ")}.") + + if (removeItem(player, Items.MOLTEN_GLASS_1775)) { + addItem(player, product.producedItemId, product.amount) + rewardXP(player, Skills.CRAFTING, product.experience) + player.dispatch(ResourceProducedEvent(product.producedItemId, product.amount, player)) + + } else return true + + amount-- + delay = 3 + + return false + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/crafting/glass/GlassMakeListener.kt b/Server/src/main/content/global/skill/crafting/glass/GlassMakeListener.kt new file mode 100644 index 0000000..9dc4d98 --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/glass/GlassMakeListener.kt @@ -0,0 +1,40 @@ +package content.global.skill.crafting.glass + +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import org.rs09.consts.Items +import kotlin.math.min + +class GlassMakeListener : InteractionListener { + + companion object{ + private const val SODA_ASH = Items.SODA_ASH_1781 + private const val BUCKET_OF_SAND = Items.BUCKET_OF_SAND_1783 + private const val MOLTEN_GLASS = Items.MOLTEN_GLASS_1775 + private val INPUTS = intArrayOf(SODA_ASH, BUCKET_OF_SAND) + private val FURNACES = intArrayOf(4304, 6189, 9390, 11010, 11666, 12100, 12809, 18497, 26814, 30021, 30510, 36956, 37651) + } + + override fun defineListeners() { + onUseWith(IntType.SCENERY, INPUTS, *FURNACES){ player, _, _ -> + + if (!inInventory(player, SODA_ASH, 1) || !inInventory(player, BUCKET_OF_SAND, 1)) { + sendMessage(player, "You need at least one heap of soda ash and one bucket of sand to do this.") + return@onUseWith true + } + + sendSkillDialogue(player) { + withItems(MOLTEN_GLASS) + create { id, amount -> + submitIndividualPulse(player, GlassMakePulse(player, id, amount)) + } + calculateMaxAmount { _ -> + min(amountInInventory(player, SODA_ASH), amountInInventory(player, BUCKET_OF_SAND)) + } + } + + return@onUseWith true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/crafting/glass/GlassMakePulse.kt b/Server/src/main/content/global/skill/crafting/glass/GlassMakePulse.kt new file mode 100644 index 0000000..a641e20 --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/glass/GlassMakePulse.kt @@ -0,0 +1,40 @@ +package content.global.skill.crafting.glass + +import core.api.* +import core.game.event.ResourceProducedEvent +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.system.task.Pulse +import org.rs09.consts.Items + +class GlassMakePulse( + private val player: Player, + private val product: Int, + private var amount: Int +) : Pulse() { + + override fun pulse(): Boolean { + if (amount < 1) return true + + if (!inInventory(player, Items.SODA_ASH_1781) || !inInventory(player, Items.BUCKET_OF_SAND_1783)) { + return true + } + + animate(player, 3243) + //Audio unknown (2725?) + sendMessage(player, "You heat the sand and soda ash in the furnace to make glass.") + + if (removeItem(player, Items.SODA_ASH_1781) && removeItem(player, Items.BUCKET_OF_SAND_1783)) { + addItem(player, Items.BUCKET_1925) + addItem(player, Items.MOLTEN_GLASS_1775) + rewardXP(player, Skills.CRAFTING, 20.0) + player.dispatch(ResourceProducedEvent(product, amount, player)) + + } else return true + + amount-- + delay = 2 + + return false + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/crafting/glass/GlassProduct.kt b/Server/src/main/content/global/skill/crafting/glass/GlassProduct.kt new file mode 100644 index 0000000..4e0ced5 --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/glass/GlassProduct.kt @@ -0,0 +1,35 @@ +package content.global.skill.crafting.glass + +enum class GlassProduct ( + val buttonId: Int, + val producedItemId: Int, + val amount: Int, + val minimumLevel: Int, + val experience: Double +) { + VIAL(38, 229, 1, 33, 35.0), + ORB(39, 567, 1, 46, 52.5), + BEER_GLASS(40, 1919, 1, 1, 17.5), + CANDLE_LANTERN(41, 4527, 1, 4, 19.0), + OIL_LAMP(42, 4525, 1, 12, 25.0), + LANTERN_LENS(43, 4542, 1, 49, 55.0), + FISHBOWL(44, 6667, 1, 42, 42.5), + LIGHT_ORB(45, 10973, 1, 87, 70.0); + + companion object { + private val BUTTON_MAP = HashMap() + private val PRODUCT_MAP = HashMap() + + init { + for (product in GlassProduct.values()) { + BUTTON_MAP[product.buttonId] = product + } + + for (product in GlassProduct.values()) { + PRODUCT_MAP[product.producedItemId] = product + } + } + + fun forButtonID(buttonId: Int): GlassProduct? = BUTTON_MAP[buttonId] + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/crafting/jewellery/JewelleryCrafting.java b/Server/src/main/content/global/skill/crafting/jewellery/JewelleryCrafting.java new file mode 100644 index 0000000..37304e7 --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/jewellery/JewelleryCrafting.java @@ -0,0 +1,294 @@ +package content.global.skill.crafting.jewellery; + +import core.cache.def.impl.ItemDefinition; +import core.game.component.Component; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +import java.util.HashMap; + +/** + * Represents a useful class for jewellery crafting information. + * @author Ceikry + */ +public class JewelleryCrafting { + + /** + * Represents constants of useful items. + */ + public static final int RING_MOULD = 1592, AMULET_MOULD = 1595, NECKLACE_MOULD = 1597, BRACELET_MOULD = 11065, GOLD_BAR = 2357, SAPPHIRE = 1607, EMERALD = 1605, RUBY = 1603, DIAMOND = 1601, DRAGONSTONE = 1615, ONYX = 6573; + + /** + * Represents the anum of jewellery data. + * @author 'Vexia + */ + public enum JewelleryItem { + //Ring + GOLD_RING(5, 15, 19, 1635, GOLD_BAR), + SAPPIRE_RING(20, 40, 21, 1637, SAPPHIRE, GOLD_BAR), + EMERALD_RING(27, 55, 23, 1639, EMERALD, GOLD_BAR), + RUBY_RING(34, 70, 25, 1641, RUBY, GOLD_BAR), + DIAMOND_RING(43, 85, 27, 1643, DIAMOND, GOLD_BAR), + DRAGONSTONE_RING(55, 100, 29, 1645, DRAGONSTONE, GOLD_BAR), + ONYX_RING(67, 115, 31, 6575, 6573, GOLD_BAR), + + //Necklaces + GOLD_NECKLACE(6, 20, 41, 1654, 2357), + SAPPHIRE_NECKLACE(22, 55, 43, 1656, 1607, 2357), + EMERALD_NECKLACE(29, 60, 45, 1658, 1605, 2357), + RUBY_NECKLACE(40, 75, 47, 1660, 1603, 2357), + DIAMOND_NECKLACE(56, 90, 49, 1662, 1601, 2357), + DRAGONSTONE_NECKLACE(72, 105, 51, 1664, 1615, 2357), + ONYX_NECKLACE(82, 120, 53, 6577, 6573, 2357), + SLAYER_RING(75, 15, 34, 13281, 4155, GOLD_BAR), + + + //Amulet + GOLD_AMULET(8, 30, 60, 1673, 2357), + SAPPHIRE_AMULET(24, 63, 62, 1675, 1607, 2357), + EMERALD_AMULET(31, 70, 64, 1677, 1605, 2357), + RUBY_AMULET(50, 85, 66, 1679, 1603, 2357), + DIAMOND_AMULET(70, 100, 68, 1681, 1601, 2357), + DRAGONSTONE_AMULET(80, 150, 70, 1683, 1615, 2357), + ONYX_AMULET(90, 165, 72, 6579, 6573, 2357), + + //Bracelet + GOLD_BRACELET(7, 25, 79, 11069, 2357), + SAPPHIRE_BRACELET(23, 60, 81, 11072, 1607, 2357), + EMERALD_BRACELET(30, 65, 83, 11076, 1605, 2357), + RUBY_BRACELET(42, 80, 85, 11085, 1603, 2357), + DIAMOND_BRACELET(58, 95, 87, 11092, 1601, 2357), + DRAGONSTONE_BRACELET(74, 110, 89, 11115, 1615, 2357), + ONYX_BRACELET(84, 125, 91, 11130, 6573, 2357); + + public static HashMap productMap = new HashMap<>(); + static{ + JewelleryItem[] jewelleryArray = JewelleryItem.values(); + for (JewelleryItem jewelleryItem : jewelleryArray) { + productMap.putIfAbsent(jewelleryItem.sendItem, jewelleryItem); + } + } + + /** + * Represents the item ids. + */ + private final int[] items; + + /** + * Represents the send item. + */ + private final int sendItem; + + /** + * Represents the component id. + */ + private final int componentId; + + /** + * Represents the level. + */ + private final int level; + + /** + * Represents the experience gained. + */ + private final double experience; + + /** + * Constructs a new {@code Jewellery.java} {@code Object}. + * @param level the level. + * @param experience the experience. + */ + JewelleryItem(int level, int experience, int componentId, int sendItem, int... items) { + this.level = level; + this.experience = experience; + this.componentId = componentId; + this.sendItem = sendItem; + this.items = items; + } + + /** + * Gets the jewellery by the product. + * @param id the id. + * @return the jewellery. + */ + public static JewelleryItem forProduct(int id) { + return productMap.get(id); + } + + /** + * Gets the items. + * @return The items. + */ + public int[] getItems() { + return items; + } + + /** + * Gets the sendItem. + * @return The sendItem. + */ + public int getSendItem() { + return sendItem; + } + + /** + * Gets the componentId. + * @return The componentId. + */ + public int getComponentId() { + return componentId; + } + + /** + * Gets the level. + * @return The level. + */ + public int getLevel() { + return level; + } + + /** + * Gets the experience. + * @return The experience. + */ + public double getExperience() { + return experience; + } + } + + /** + * Method used to open the jewellery crafting interface. + * @param player the player. + */ + public static void open(final Player player) { + player.getInterfaceManager().open(new Component(446)); + if (player.getInventory().contains(RING_MOULD, 1)) { + player.getPacketDispatch().sendInterfaceConfig(446, 14, true); + /** hides the mould and text. */ + } + if (player.getInventory().contains(NECKLACE_MOULD, 1)) { + player.getPacketDispatch().sendInterfaceConfig(446, 36, true); + /** hides the mould and text. */ + } + if (player.getInventory().contains(AMULET_MOULD, 1)) { + player.getPacketDispatch().sendInterfaceConfig(446, 55, true); + /** hides the mould and text. */ + } + if (player.getInventory().contains(BRACELET_MOULD, 1)) { + player.getPacketDispatch().sendInterfaceConfig(446, 74, true); + /** hides the mould and text. */ + } + for (JewelleryItem data : JewelleryItem.values()) { + int length = 0; + for (int i = 0; i < data.items.length; i++) { + if (player.getInventory().contains(data.getItems()[i], 1)) { + length++; + } + } + if (!player.getInventory().contains(mouldFor(data.name()), 1)) { + length--; + } + if (length == data.getItems().length && player.getSkills().getLevel(Skills.CRAFTING) >= data.getLevel()) { + player.getPacketDispatch().sendItemZoomOnInterface(data.getSendItem(), 170, 446, data.getComponentId()); + } else { + String name = ItemDefinition.forId(data.getSendItem()).getName().toLowerCase(); + if (name.contains("amulet") && player.getInventory().contains(mouldFor(data.name()), 1)) { + for (int i = 0; i < data.items.length; i++) { + if (!player.getInventory().contains(data.getItems()[i], 1)) { + player.getPacketDispatch().sendItemZoomOnInterface(1685, 220, 446, data.getComponentId()); + break; + } + } + } + if (name.contains("ring") && !player.getInventory().contains(RING_MOULD, 1)) { + continue; + } + if (name.contains("necklace") && !player.getInventory().contains(NECKLACE_MOULD, 1)) { + continue; + } + if (data == JewelleryItem.DRAGONSTONE_AMULET && !player.getInventory().contains(AMULET_MOULD, 1)) { + continue; + } + if (name.contains("amulet") && !player.getInventory().contains(AMULET_MOULD, 1)) { + continue; + } + if (name.contains("bracelet") && !player.getInventory().contains(BRACELET_MOULD, 1)) { + continue; + } + player.getPacketDispatch().sendItemZoomOnInterface(name.contains("ring") ? 1647 : name.contains("necklace") ? 1666 : name.contains("amulet") || name.contains("ammy") ? 1685 : name.contains("bracelet") ? 11067 : -1, 1, 446, data.getComponentId()); + } + } + } + + /** + * Represents the making of a jewellery. + * @param player the player. + * @param data the data. + * @param amount the amount. + */ + public static final void make(final Player player, JewelleryItem data, int amount) { + int length = 0; + int amt = 0; + if (data.name().contains("GOLD")) { + amt = player.getInventory().getAmount(new Item(GOLD_BAR)); + } else { + int first = player.getInventory().getAmount(new Item(data.getItems()[0])); + int second = player.getInventory().getAmount(new Item(data.getItems()[1])); + if (first == second) { + amt = first; + } else if (first > second) { + amt = second; + } else { + amt = first; + } + } + if (amount > amt) { + amount = amt; + } + for (int i = 0; i < data.items.length; i++) { + if (player.getInventory().contains(data.getItems()[i], amount)) { + length++; + } + } + if (length != data.getItems().length) { + player.getPacketDispatch().sendMessage("You don't have the required items to make this item."); + return; + } + if (player.getSkills().getLevel(Skills.CRAFTING) < data.getLevel()) { + player.getPacketDispatch().sendMessage("You need a crafting level of " + data.getLevel() + " to craft this."); + return; + } + Item items[] = new Item[data.items.length]; + int index = 0; + for (int i = 0; i < data.items.length; i++) { + items[index] = new Item(data.items[i], 1 * amount); + index++; + } + player.getInterfaceManager().close(); + player.getPulseManager().run(new JewelleryPulse(player, null, data, amount)); + } + + /** + * Gets the mould id for the name. + * @param name the name. + * @return the mould id. + */ + public static int mouldFor(String name) { + name = name.toLowerCase(); + if (name.contains("ring")) { + return RING_MOULD; + } + if (name.contains("necklace")) { + return NECKLACE_MOULD; + } + if (name.contains("amulet")) { + return AMULET_MOULD; + } + if (name.contains("bracelet")) { + return BRACELET_MOULD; + } + return -1; + } +} diff --git a/Server/src/main/content/global/skill/crafting/jewellery/JewelleryPulse.java b/Server/src/main/content/global/skill/crafting/jewellery/JewelleryPulse.java new file mode 100644 index 0000000..e69a7ee --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/jewellery/JewelleryPulse.java @@ -0,0 +1,93 @@ +package content.global.skill.crafting.jewellery; + +import core.game.node.entity.skill.SkillPulse; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.*; + +/** + * Represents the pulse used to craft jewllery. + * @author 'Vexia + */ +public final class JewelleryPulse extends SkillPulse { + + /** + * Represents the animation to use. + */ + private static final Animation ANIMATION = new Animation(3243); + + /** + * Represents the data of jewellery. + */ + private JewelleryCrafting.JewelleryItem type; + + /** + * Represents the amount to make. + */ + private int amount; + + /** + * Represents the ticks. + */ + private int ticks; + + /** + * Constructs a new {@code CraftJewellery.java} {@code Object}. + * @param player the player. + * @param node the node. + */ + public JewelleryPulse(Player player, Item node, JewelleryCrafting.JewelleryItem data, int amount) { + super(player, node); + this.type = data; + this.amount = amount; + } + + @Override + public boolean checkRequirements() { + if (player.getSkills().getLevel(Skills.CRAFTING) < type.getLevel()) { + return false; + } + return true; + } + + @Override + public void animate() { + if (ticks % 5 == 0) { + player.animate(ANIMATION); + playAudio(player, Sounds.FURNACE_2725); + } + } + + @Override + public boolean reward() { + if (++ticks % 5 != 0) { + return false; + } + if (player.getInventory().remove(getItems())) { + final Item item = new Item(type.getSendItem()); + player.getInventory().add(item); + player.getSkills().addExperience(Skills.CRAFTING, type.getExperience(), true); + } + amount--; + return amount < 1; + } + + /** + * Gets the items to remove. + * @return the items. + */ + private Item[] getItems() { + Item items[] = new Item[type.getItems().length]; + int index = 0; + for (int i = 0; i < type.getItems().length; i++) { + items[index] = new Item(type.getItems()[i], 1); + index++; + } + return items; + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/crafting/leather/SpikyVambraces.kt b/Server/src/main/content/global/skill/crafting/leather/SpikyVambraces.kt new file mode 100644 index 0000000..7646744 --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/leather/SpikyVambraces.kt @@ -0,0 +1,68 @@ +package content.global.skill.crafting.leather + +import core.api.Container +import core.api.* +import core.game.interaction.NodeUsageEvent +import core.game.interaction.UseWithHandler +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import org.rs09.consts.Items +import core.plugin.Initializable +import core.plugin.Plugin + +/** + * Handles attaching Kebbit Claws to Vambraces + * to create "Spiky Vambraces" + * @author downthecrop + */ + +@Initializable +class SpikyVambraces: UseWithHandler(Items.KEBBIT_CLAWS_10113) { + + override fun newInstance(arg: Any?): Plugin { + addHandler(Items.LEATHER_VAMBRACES_1063, ITEM_TYPE, this) + addHandler(Items.GREEN_DHIDE_VAMB_1065, ITEM_TYPE, this) + addHandler(Items.BLUE_DHIDE_VAMB_2487, ITEM_TYPE, this) + addHandler(Items.RED_DHIDE_VAMB_2489, ITEM_TYPE, this) + addHandler(Items.BLACK_DHIDE_VAMB_2491, ITEM_TYPE, this) + return this + } + override fun handle(event: NodeUsageEvent?): Boolean { + event ?: return false + val vamb = event.usedWith.id + val player = event.player + when(vamb){ + Items.LEATHER_VAMBRACES_1063 -> { + craftVamb(player,vamb,Items.SPIKY_VAMBRACES_10077,"leather") + } + Items.GREEN_DHIDE_VAMB_1065 -> { + craftVamb(player,vamb,Items.GREEN_SPIKY_VAMBS_10079,"green dragonhide") + } + Items.BLUE_DHIDE_VAMB_2487 -> { + craftVamb(player,vamb,Items.BLUE_SPIKY_VAMBS_10081,"blue dragonhide") + } + Items.RED_DHIDE_VAMB_2489 -> { + craftVamb(player,vamb,Items.RED_SPIKY_VAMBS_10083,"red dragonhide") + } + Items.BLACK_DHIDE_VAMB_2491 -> { + craftVamb(player,vamb,Items.BLACK_SPIKY_VAMBS_10085,"black dragonhide") + } + } + return true + } + + private fun craftVamb(player: Player, vamb: Int, product: Int, vambLeather: String){ + if (player.skills.getLevel(Skills.CRAFTING) >= 32){ + if (removeItem(player,vamb,Container.INVENTORY) && + removeItem(player,Items.KEBBIT_CLAWS_10113,Container.INVENTORY) + ) { + addItem(player,product) + player.skills.addExperience(Skills.CRAFTING,6.0) + sendMessage(player, "You carefully attach the sharp claws to the $vambLeather vambraces.") + } + } + else{ + sendMessage(player,"You need a crafting level of 32 to craft this.") + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/crafting/lightsources/LanternCrafting.kt b/Server/src/main/content/global/skill/crafting/lightsources/LanternCrafting.kt new file mode 100644 index 0000000..13daf97 --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/lightsources/LanternCrafting.kt @@ -0,0 +1,97 @@ +package content.global.skill.crafting.lightsources + +import core.game.interaction.NodeUsageEvent +import core.game.interaction.UseWithHandler +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.plugin.Initializable +import core.plugin.Plugin + +/** + * Handles the combining of items to craft lanterns + * @author Ceikry + */ +@Initializable +class LanternCrafting : UseWithHandler(36,38,4525,4542,1607){ + /** + * For candle lanterns -> Glassblowing produces 4527 + * 4527 + white candle = 4529 + * 4527 + black candle = 4532 + * + * For oil lanterns -> Glassblowing produces 4525 + * 4525 + 4540 (oil lantern frame) = 4535 (empty oil lantern) + * + * For Bullseye lanterns -> Smithing produces 4544 (bullseye lantern (unf)) + * 4544 + Lens(4542) -> 4546 + * 4544 + Sapphire(1607) -> 4700 (Sapphire lantern) + */ + override fun newInstance(arg: Any?): Plugin { + addHandler(4527, ITEM_TYPE, this) //Empty candle lantern + addHandler(4540, ITEM_TYPE,this) //oil lantern frame + addHandler(4544, ITEM_TYPE,this) //Bullseye lantern(unf) + return this + } + + override fun handle(event: NodeUsageEvent?): Boolean { + event ?: return false //if event is null don't execute + val used = event.used + return when(used.id){ + 4527 -> craftCandleLantern(event.player,event) + 4540 -> craftOilLantern(event.player,event) + 4544 -> craftBullseyeLantern(event.player,event) + else -> false + } + } + + private fun craftCandleLantern(player: Player, event: NodeUsageEvent): Boolean{ + return when(event.usedWith.id){ + 36,38 -> { + removeEventItems(player,event) + player.inventory.add( if(event.usedWith.id == 36) Item(4529) else Item(4532)) + player.sendMessage("You place the unlit candle inside the lantern.") + true + } + else -> false + } + } + + private fun craftOilLantern(player: Player, event: NodeUsageEvent): Boolean { + return when(event.usedWith.id){ + 4525 -> { + removeEventItems(player,event) + player.inventory.add(Item(4535)) + player.sendMessage("You place the oil lamp inside its metal frame.") + true + } + else -> false + } + } + + private fun craftBullseyeLantern(player: Player,event: NodeUsageEvent): Boolean{ + return when(event.usedWith.id){ + 4542 -> { + removeEventItems(player,event) + player.inventory.add( Item(4546) ) + player.sendMessage("You fashion the lens onto the lantern.") + true + } + 1607 -> { + if(player.skills.getLevel(Skills.CRAFTING) >= 20){ + removeEventItems(player,event) + player.inventory.add(Item(4700)) + player.sendMessage("You fashion the gem into a lens and fit it onto the lantern.") + } else { + player.sendMessage("You require a crafting level of 20 to use a gem as a lens.") + } + true + } + else -> false + } + } + + private fun removeEventItems(player: Player, event: NodeUsageEvent){ + player.inventory.remove(event.used.asItem()) + player.inventory.remove(event.usedWith.asItem()) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/crafting/lightsources/LightSourceExtinguisher.kt b/Server/src/main/content/global/skill/crafting/lightsources/LightSourceExtinguisher.kt new file mode 100644 index 0000000..357b69c --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/lightsources/LightSourceExtinguisher.kt @@ -0,0 +1,44 @@ +package content.global.skill.crafting.lightsources + +import core.api.log +import core.cache.def.impl.ItemDefinition +import core.game.container.Container +import core.game.interaction.OptionHandler +import core.game.node.Node +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.tools.SystemLogger +import core.plugin.Initializable +import core.plugin.Plugin +import core.tools.Log + + +/** + * Extinguishes light sources + * @author Ceikry + */ +@Initializable +class LightSourceExtinguisher : OptionHandler(){ + override fun newInstance(arg: Any?): Plugin { + ItemDefinition.setOptionHandler("extinguish",this) + return this + } + + override fun handle(player: Player?, node: Node?, option: String?): Boolean { + node ?: return false + player ?: return false + + val lightSource = LightSources.forId(node.id) + + lightSource ?: return false.also { log(this::class.java, Log.WARN, "UNHANDLED EXTINGUISH OPTION: ID = ${node.id}") } + + player.inventory.replace(node.asItem(), Item(lightSource.fullID)) + return true + } + + fun Container.replace(item: Item, with: Item){ + if(remove(item)) { + add(with) + } + } +} diff --git a/Server/src/main/content/global/skill/crafting/lightsources/LightSourceLighter.kt b/Server/src/main/content/global/skill/crafting/lightsources/LightSourceLighter.kt new file mode 100644 index 0000000..81a1a98 --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/lightsources/LightSourceLighter.kt @@ -0,0 +1,98 @@ +package content.global.skill.crafting.lightsources + +import core.game.container.Container +import core.game.event.LitLightSourceEvent +import core.game.interaction.NodeUsageEvent +import core.game.interaction.UseWithHandler +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.plugin.Initializable +import core.plugin.Plugin + +/** + * Method used to light various light sources + * @author Ceikry + */ +@Initializable +class LightSourceLighter : UseWithHandler(590,36,38){ + /** + * For Candles: + * 36 + tinderbox = 33 + * 38 + tinderbox = 32 + * + * For torches: + * 596 + tinderbox = 594 + * + * For Candle lanterns: + * 4529 + tinderbox = 4531 + * 4532 + tinderbox = 4534 + * Required Level: 4 Firemaking + * + * For oil lamps: + * 4522 + tinderbox = 4524 + * Required Level: 12 Firemaking + * + * For oil lanterns: + * 4537 + tinderbox = 4539 + * Required Level: 26 Firemaking + * + * For bullseye lanterns: + * 4548 + tinderbox = 4550 + * 4701 + tinderbox = 4702 + * 9064 + tinderbox = 9065 + * Required Level: 49 Firemaking + */ + + override fun newInstance(arg: Any?): Plugin { + addHandler(590, ITEM_TYPE, this) + addHandler(596, ITEM_TYPE, this) + addHandler(4529, ITEM_TYPE, this) + addHandler(4532, ITEM_TYPE, this) + addHandler(4522, ITEM_TYPE, this) + addHandler(4537, ITEM_TYPE, this) + addHandler(4548, ITEM_TYPE, this) + addHandler(4701, ITEM_TYPE, this) + addHandler(9064, ITEM_TYPE, this) + return this + } + + override fun handle(event: NodeUsageEvent?): Boolean { + event ?: return false + val inventory = event.player.inventory + val used = if(event.used.id == 590) event.usedWith.asItem() else event.used.asItem() //compensation for bad two-way use with handler shit + + val lightSource = LightSources.forId(used.id) + + lightSource ?: return false + + // For Sea Slug Quest - No lighting of any torch on the fishing platform. + if(event.player.location.isInRegion(11059)) { + event.player.sendMessage("Your tinderbox is damp from the sea crossing. It won't work here.") + return true + } + + if(!light(event.player,used,lightSource)){ + event.player.sendMessage("You need a Firemaking level of at least ${lightSource.levelRequired} to light this.") + } + + return true + } + + fun Container.replace(item: Item, with: Item){ + if(remove(item)) { + add(with) + } + } + + fun light(player: Player, item: Item, lightSource: LightSources): Boolean{ + val requiredLevel = lightSource.levelRequired + val playerLevel = player.skills.getLevel(Skills.FIREMAKING) + + if(playerLevel < requiredLevel) return false + + player.inventory.replace(item,Item(lightSource.litID)) + player.dispatch(LitLightSourceEvent(lightSource.litID)) + return true + } +} diff --git a/Server/src/main/content/global/skill/crafting/lightsources/LightSources.kt b/Server/src/main/content/global/skill/crafting/lightsources/LightSources.kt new file mode 100644 index 0000000..2c528dd --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/lightsources/LightSources.kt @@ -0,0 +1,34 @@ +package content.global.skill.crafting.lightsources + +enum class LightSources(val emptyID: Int, val fullID: Int, val litID: Int, val levelRequired: Int, val openFlame: Boolean) { + WHITE_CANDLE(0,36,33,0,true), + BLACK_CANDLE(0,38,32,0,true), + TORCH(0,596,594,0,true), + WHITE_CANDLE_LANTERN(4527,4529,4531,4,true), + BLACK_CANDLE_LANTERN(4527,4532,4534,4,true), + OIL_LAMP(4525,4522,4524,12,true), + OIL_LANTERN(4535,4537,4539,26,false), + BULLSEYE_LANTERN(4546,4548,4550,49,false), + SAPPHIRE_LANTERN(0,4701,4702,49,false), + MINING_HELMET(0,5014,5013,65,false), + EMERALD_LANTERN(0,9064,9065,49,false); + + companion object { + fun forId(id: Int): LightSources? { + return when (id) { + 36, 33 -> WHITE_CANDLE + 38, 32 -> BLACK_CANDLE + 596, 594 -> TORCH + 4529, 4531 -> WHITE_CANDLE_LANTERN + 4532, 4534 -> BLACK_CANDLE_LANTERN + 4522, 4524 -> OIL_LAMP + 4537, 4539 -> OIL_LANTERN + 4548, 4550 -> BULLSEYE_LANTERN + 4701, 4702 -> SAPPHIRE_LANTERN + 5014, 5013 -> MINING_HELMET + 9064, 9065 -> EMERALD_LANTERN + else -> null + } + } + } +} diff --git a/Server/src/main/content/global/skill/crafting/limestone/ChiselLimestonePulse.java b/Server/src/main/content/global/skill/crafting/limestone/ChiselLimestonePulse.java new file mode 100644 index 0000000..259850d --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/limestone/ChiselLimestonePulse.java @@ -0,0 +1,73 @@ +package content.global.skill.crafting.limestone; + +import core.game.node.entity.skill.SkillPulse; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playAudio; + +/** + * + * The skill pulse for chiseling a limestone into a limestone brick. + * + * @author Jamix77 + * + */ +public class ChiselLimestonePulse extends SkillPulse { + + /** + * Represents the chisel item. + */ + private static final Item CHISEL = new Item(1755); + + /** + * Represents the ticks passed. + */ + private int ticks; + + public ChiselLimestonePulse(Player player, Item node) { + super(player, node); + this.resetAnimation= false; + } + + @Override + public boolean checkRequirements() { + if (!player.getInventory().containsItem(CHISEL)) { + return false; + } + if (!player.getInventory().containsItem(new Item(3211))) { + return false; + } + if (player.getSkills().getLevel(Skills.CRAFTING) < 12) { + player.getPacketDispatch().sendMessage("You need a crafting level of 12 to make limestone bricks."); + return false; + } + return true; + } + + @Override + public void animate() { + if (ticks % 5 == 0 || ticks < 1) { + playAudio(player, Sounds.CHISEL_2586); + player.animate(Animation.create(4470)); + } + } + + @Override + public boolean reward() { + if (++ticks % 2 != 0) { + return false; + } + if (player.getInventory().remove(new Item(3211))) { + + player.getInventory().add(new Item(3420)); + + player.getSkills().addExperience(Skills.CRAFTING, 6, true); + } + return !player.getInventory().containsItem(new Item(3211)); + } + +} diff --git a/Server/src/main/content/global/skill/crafting/pottery/FirePotteryPulse.java b/Server/src/main/content/global/skill/crafting/pottery/FirePotteryPulse.java new file mode 100644 index 0000000..e4cf4ec --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/pottery/FirePotteryPulse.java @@ -0,0 +1,100 @@ +package content.global.skill.crafting.pottery; + +import core.game.world.map.Location; +import core.game.node.entity.skill.SkillPulse; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; + +/** + * Represents the pulse used to fire pottery. + * + * @author 'Vexia + */ +public final class FirePotteryPulse extends SkillPulse { + + /** + * Represents the animation to use. + */ + private static final Animation ANIMATION = new Animation(899); + + /** + * Represents the pottery item. + */ + private final PotteryItem pottery; + + /** + * Represents the amount to make. + */ + private int amount; + + /** + * Represents the ticks passed. + */ + private int ticks; + + /** + * Constructs a new {@code FirePotteryPulse} {@code Object}. + * + * @param player the player. + * @param node the node. + * @param pottery the pottery. + * @param amount the amount. + */ + public FirePotteryPulse(Player player, Item node, final PotteryItem pottery, final int amount) { + super(player, node); + this.pottery = pottery; + this.amount = amount; + } + + @Override + public boolean checkRequirements() { + if (player.getSkills().getLevel(Skills.CRAFTING) < pottery.getLevel()) { + player.getPacketDispatch().sendMessage("You need a crafting level of " + pottery.getLevel() + " in order to do this."); + return false; + } + if (!player.getInventory().containsItem(pottery.getUnfinished())) { + player.getPacketDispatch().sendMessage("You need a " + pottery.name().toLowerCase() + " in order to do this."); + return false; + } + return true; + } + + @Override + public void animate() { + if (ticks % 5 == 0) { + player.animate(ANIMATION); + } + } + + @Override + public boolean reward() { + if (++ticks % 5 != 0) { + return false; + } + if (player.getInventory().remove(pottery.getUnfinished())) { + final Item item = pottery.getProduct(); + player.getInventory().add(item); + player.getSkills().addExperience(Skills.CRAFTING, pottery.getFireExp(), true); + player.getPacketDispatch().sendMessage("You put the " + pottery.getUnfinished().getName().toLowerCase() + " in the oven."); + player.getPacketDispatch().sendMessage("You remove a " + pottery.getProduct().getName().toLowerCase() + " from the oven."); + + // Spin a bowl on the pottery wheel and fire it in the oven in

Barbarian Village + if (pottery == PotteryItem.BOWL + && player.getLocation().withinDistance(Location.create(3085,3408,0)) + && player.getAttribute("diary:varrock:spun-bowl", false)) { + player.getAchievementDiaryManager().finishTask(player, DiaryType.VARROCK, 0, 9); + } + + // Fire a pot in the kiln in the Barbarian Village potter's

house + if (pottery == PotteryItem.POT && player.getLocation().withinDistance(Location.create(3085,3408,0))) { + player.getAchievementDiaryManager().finishTask(player, DiaryType.LUMBRIDGE, 0, 7); + } + } + amount--; + return amount < 1; + } + +} diff --git a/Server/src/main/content/global/skill/crafting/pottery/PotteryItem.java b/Server/src/main/content/global/skill/crafting/pottery/PotteryItem.java new file mode 100644 index 0000000..6eafb8f --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/pottery/PotteryItem.java @@ -0,0 +1,107 @@ +package content.global.skill.crafting.pottery; + +import core.game.node.item.Item; + +/** + * Represents a pottery item definition. + * @author 'Vexia + */ +public enum PotteryItem { + POT(new Item(1787), new Item(1931), 1, 6.3, 6.3), DISH(new Item(1789), new Item(2313), 7, 15, 10), BOWL(new Item(1791), new Item(1923), 8, 18, 15), PLANT(new Item(5352), new Item(5350), 19, 20, 17.5), LID(new Item(4438), new Item(4440), 25, 20, 20); + + /** + * Represents the unfinished product. + */ + private final Item unfinished; + + /** + * Represents the product. + */ + private final Item product; + + /** + * Represents the level required. + */ + private final int level; + + /** + * Represents the exp given. + */ + private final double exp; + + /** + * Represents the fire exp. + */ + private final double fireExp; + + /** + * Constructs a new {@code PotteryItem} {@code Object}. + * @param unfinished the unfinished. + * @param product the product. + * @param level the level. + * @param exp the exp. + * @param fireExp the fire experience. + */ + private PotteryItem(Item unfinished, Item product, int level, double exp, double fireExp) { + this.unfinished = unfinished; + this.product = product; + this.level = level; + this.exp = exp; + this.fireExp = fireExp; + } + + /** + * Gets the pottery item by the id. + * @param id the id. + * @return the item. + */ + public static PotteryItem forId(int id) { + for (PotteryItem def : PotteryItem.values()) { + if (def.getUnfinished().getId() == id) { + return def; + } + } + return null; + } + + /** + * Gets the unfinished. + * @return The unfinished. + */ + public Item getUnfinished() { + return unfinished; + } + + /** + * Gets the product. + * @return The product. + */ + public Item getProduct() { + return product; + } + + /** + * Gets the level. + * @return The level. + */ + public int getLevel() { + return level; + } + + /** + * Gets the exp. + * @return The exp. + */ + public double getExp() { + return exp; + } + + /** + * Gets the fireExp. + * @return The fireExp. + */ + public double getFireExp() { + return fireExp; + } + +} diff --git a/Server/src/main/content/global/skill/crafting/pottery/PotteryPulse.java b/Server/src/main/content/global/skill/crafting/pottery/PotteryPulse.java new file mode 100644 index 0000000..c9cbe0c --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/pottery/PotteryPulse.java @@ -0,0 +1,93 @@ +package content.global.skill.crafting.pottery; + +import core.game.world.map.Location; +import core.game.node.entity.skill.SkillPulse; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; +import core.tools.StringUtils; + +/** + * Represents the skill pulse of the pottery unfired items. + * @author 'Vexia + */ +public final class PotteryPulse extends SkillPulse { + + /** + * Represents the animation to use. + */ + private static final Animation ANIMATION = Animation.create(896); + + /** + * Represnets the soft clay item. + */ + private static final Item SOFT_CLAY = new Item(1761); + + /** + * Represents the pottery item to make. + */ + private final PotteryItem pottery; + + /** + * Represents the amount to make. + */ + private int amount; + + /** + * Represents the ticks passed. + */ + private int ticks; + + /** + * Constructs a new {@code PotteryPulse} {@code Object}. + * @param player the player. + * @param node the node. + * @param amount the amount. + * @param pottery the pottery. + */ + public PotteryPulse(Player player, Item node, int amount, final PotteryItem pottery) { + super(player, node); + this.pottery = pottery; + this.amount = amount; + } + + @Override + public boolean checkRequirements() { + if (!player.getInventory().contains(1761, 1)) { + player.getPacketDispatch().sendMessage("You need soft clay in order to do this."); + return false; + } + if (player.getSkills().getLevel(Skills.CRAFTING) < pottery.getLevel()) { + player.getPacketDispatch().sendMessage("You need a crafting level of " + pottery.getLevel() + " to make this."); + return false; + } + return true; + } + + @Override + public void animate() { + if (ticks % 5 == 0) { + player.animate(ANIMATION); + } + } + + @Override + public boolean reward() { + if (++ticks % 5 != 0) { + return false; + } + if (player.getInventory().remove(SOFT_CLAY)) { + if (pottery == PotteryItem.BOWL && player.getLocation().withinDistance(Location.create(3086,3410,0))) { + player.setAttribute("/save:diary:varrock:spun-bowl", true); + } + final Item item = pottery.getUnfinished(); + player.getInventory().add(item); + player.getSkills().addExperience(Skills.CRAFTING, pottery.getExp(), true); + player.getPacketDispatch().sendMessage("You make the soft clay into " + (StringUtils.isPlusN(pottery.getUnfinished().getName()) ? "an" : "a") + " " + pottery.getUnfinished().getName().toLowerCase() + "."); + } + amount--; + return amount < 1; + } + +} diff --git a/Server/src/main/content/global/skill/crafting/silver/SilverCraftingListener.kt b/Server/src/main/content/global/skill/crafting/silver/SilverCraftingListener.kt new file mode 100644 index 0000000..346b61b --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/silver/SilverCraftingListener.kt @@ -0,0 +1,111 @@ +package content.global.skill.crafting.silver + +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import org.rs09.consts.Components +import org.rs09.consts.Items +import org.rs09.consts.Scenery +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.game.interaction.InterfaceListener + +import core.game.node.scenery.Scenery as CoreScenery + +/** + * Handles silver crafting interface interactions + * as well as silver -> furnace use-with interaction. + * + * @author vddCore + */ +class SilverCraftingListener : InterfaceListener, InteractionListener { + companion object { + private const val OP_MAKE_ONE = 155 + private const val OP_MAKE_FIVE = 196 + private const val OP_MAKE_ALL = 124 + private const val OP_MAKE_X = 199 + + private val FURNACES = intArrayOf( + Scenery.FURNACE_2966, Scenery.FURNACE_3044, Scenery.FURNACE_3294, Scenery.FURNACE_4304, + Scenery.FURNACE_6189, Scenery.FURNACE_11009, Scenery.FURNACE_11010, Scenery.FURNACE_11666, + Scenery.FURNACE_12100, Scenery.FURNACE_12809, Scenery.FURNACE_18497, Scenery.FURNACE_18525, + Scenery.FURNACE_18526, Scenery.FURNACE_21879, Scenery.FURNACE_22721, Scenery.FURNACE_26814, + Scenery.FURNACE_28433, Scenery.FURNACE_28434, Scenery.FURNACE_30021, Scenery.FURNACE_30510, + Scenery.FURNACE_36956, Scenery.FURNACE_37651 + ) + + private const val ATTRIBUTE_FURNACE_ID = "crafting:silver:furnace_id" + } + + override fun defineInterfaceListeners() { + onOpen(Components.CRAFTING_SILVER_CASTING_438) { player, _ -> + sendItemOnInterface(player, Components.CRAFTING_SILVER_CASTING_438, 17, Items.HOLY_SYMBOL_1718) + sendItemOnInterface(player, Components.CRAFTING_SILVER_CASTING_438, 24, Items.UNHOLY_SYMBOL_1724) + sendItemOnInterface(player, Components.CRAFTING_SILVER_CASTING_438, 31, Items.SILVER_SICKLE_2961) + sendItemOnInterface(player, Components.CRAFTING_SILVER_CASTING_438, 38, Items.CONDUCTOR_4201) + sendItemOnInterface(player, Components.CRAFTING_SILVER_CASTING_438, 45, Items.TIARA_5525) + sendItemOnInterface(player, Components.CRAFTING_SILVER_CASTING_438, 53, Items.SILVTHRILL_ROD_7637) + sendItemOnInterface(player, Components.CRAFTING_SILVER_CASTING_438, 60, Items.DEMONIC_SIGIL_6748) + sendItemOnInterface(player, Components.CRAFTING_SILVER_CASTING_438, 67, Items.SILVER_BOLTS_UNF_9382) + sendItemOnInterface(player, Components.CRAFTING_SILVER_CASTING_438, 74, Items.SILVTHRIL_CHAIN_13154) + + return@onOpen true + } + + on(Components.CRAFTING_SILVER_CASTING_438) { player, _, opcode, buttonID, _, _ -> + val product = SilverProduct.forButtonID(buttonID) ?: return@on true + + if (!inInventory(player, product.requiredItemId)) { + sendMessage( + player, + "You need a ${itemDefinition(product.requiredItemId).name.lowercase()} to make this item." + ) + return@on true + } + + if (product == SilverProduct.SILVTHRILL_ROD || product == SilverProduct.SILVTHRIL_CHAIN) { + sendMessage(player, "You can't do that yet.") + return@on true + } + + if (!hasLevelDyn(player, Skills.CRAFTING, product.minimumLevel)) { + sendMessage(player, "You need a Crafting level of ${product.minimumLevel} to make this.") + return@on true + } + + when (opcode) { + OP_MAKE_ONE -> make(player, product, 1) + OP_MAKE_FIVE -> make(player, product, 5) + OP_MAKE_ALL -> make(player, product, amountInInventory(player, Items.SILVER_BAR_2355)) + OP_MAKE_X -> sendInputDialogue(player, InputType.AMOUNT, "Enter the amount:") { value -> + make(player, product, Integer.parseInt(value.toString())) + } + else -> return@on true + } + + return@on true + } + } + + override fun defineListeners() { + onUseWith(IntType.SCENERY, Items.SILVER_BAR_2355, *FURNACES) { player, _, with -> + setAttribute(player, ATTRIBUTE_FURNACE_ID, with) + openInterface(player, Components.CRAFTING_SILVER_CASTING_438) + return@onUseWith true + } + } + + private fun make(player: Player, product: SilverProduct, amount: Int) { + closeInterface(player) + + submitIndividualPulse( + player, + SilverCraftingPulse( + player, + product, + getAttribute(player, ATTRIBUTE_FURNACE_ID, CoreScenery(-1, -1, 0)), + amount + ) + ) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/crafting/silver/SilverCraftingPulse.kt b/Server/src/main/content/global/skill/crafting/silver/SilverCraftingPulse.kt new file mode 100644 index 0000000..8bc7700 --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/silver/SilverCraftingPulse.kt @@ -0,0 +1,53 @@ +package content.global.skill.crafting.silver + +import core.api.* +import core.game.event.ResourceProducedEvent +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.scenery.Scenery +import core.game.system.task.Pulse +import org.rs09.consts.Animations +import org.rs09.consts.Items +import org.rs09.consts.Sounds + +/** + * Handles tick-based silver crafting logic. + * + * @author vddCore + */ +class SilverCraftingPulse( + private val player: Player, + private val product: SilverProduct, + private val furnace: Scenery, + private var amount: Int +) : Pulse() { + override fun pulse(): Boolean { + if (amount < 1) return true + + if (!inInventory(player, product.requiredItemId) || !inInventory(player, Items.SILVER_BAR_2355)) { + return true + } + + animate(player, Animations.HUMAN_FURNACE_SMELTING_3243) + playAudio(player, Sounds.FURNACE_2725) + + if (removeItem(player, Items.SILVER_BAR_2355, Container.INVENTORY)) { + addItem(player, product.producedItemId, product.amountProduced) + rewardXP(player, Skills.CRAFTING, product.xpReward) + + player.dispatch( + ResourceProducedEvent( + product.producedItemId, + product.amountProduced, + furnace, + Items.SILVER_BAR_2355 + ) + ) + } else return true + + amount-- + delay = 5 + + return false + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/crafting/silver/SilverProduct.kt b/Server/src/main/content/global/skill/crafting/silver/SilverProduct.kt new file mode 100644 index 0000000..83becbf --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/silver/SilverProduct.kt @@ -0,0 +1,55 @@ +package content.global.skill.crafting.silver + +import org.rs09.consts.Items + +private const val BUTTON_UNBLESSED = 16 +private const val BUTTON_UNHOLY = 23 +private const val BUTTON_SICKLE = 30 +private const val BUTTON_TIARA = 44 +private const val BUTTON_DEMONIC_SIGIL = 59 +private const val BUTTON_SILVTHRIL_CHAIN = 73 +private const val BUTTON_LIGHTNING_ROD = 37 +private const val BUTTON_SILVTHRILL_ROD = 52 +private const val BUTTON_CROSSBOW_BOLTS = 66 + +/** + * Provides silver crafting product definitions. + * + * @author vddCore + */ +enum class SilverProduct( + val buttonId: Int, + val requiredItemId: Int, + val producedItemId: Int, + val amountProduced: Int, + val minimumLevel: Int, + val xpReward: Double, + val strungId: Int +) { + HOLY(BUTTON_UNBLESSED, Items.HOLY_MOULD_1599, Items.UNSTRUNG_SYMBOL_1714, 1, 16, 50.0, Items.UNBLESSED_SYMBOL_1716), + UNHOLY(BUTTON_UNHOLY, Items.UNHOLY_MOULD_1594, Items.UNSTRUNG_EMBLEM_1720, 1, 17, 50.0, Items.UNHOLY_SYMBOL_1724), + SICKLE(BUTTON_SICKLE, Items.SICKLE_MOULD_2976, Items.SILVER_SICKLE_2961, 1, 18, 50.0, -1), + TIARA(BUTTON_TIARA, Items.TIARA_MOULD_5523, Items.TIARA_5525, 1, 23, 52.5, -1), + SILVTHRIL_CHAIN(BUTTON_SILVTHRIL_CHAIN, Items.CHAIN_LINK_MOULD_13153, Items.SILVTHRIL_CHAIN_13154, 1, 47, 100.0, -1), + LIGHTNING_ROD(BUTTON_LIGHTNING_ROD, Items.CONDUCTOR_MOULD_4200, Items.CONDUCTOR_4201, 1, 20, 50.0, -1), + SILVTHRILL_ROD(BUTTON_SILVTHRILL_ROD, Items.ROD_CLAY_MOULD_7649, Items.SILVTHRILL_ROD_7637, 1, 25, 55.0, -1), + CROSSBOW_BOLTS(BUTTON_CROSSBOW_BOLTS, Items.BOLT_MOULD_9434, Items.SILVER_BOLTS_UNF_9382, 10, 21, 50.0, -1); + + companion object { + private val BUTTON_MAP = HashMap() + private val PRODUCT_MAP = HashMap() + + init { + for (product in SilverProduct.values()) { + BUTTON_MAP[product.buttonId] = product + } + + for (product in SilverProduct.values()) { + PRODUCT_MAP[product.producedItemId] = product + } + } + + fun forButtonID(buttonId: Int): SilverProduct? = BUTTON_MAP[buttonId] + fun forProductID(productId: Int): SilverProduct? = PRODUCT_MAP[productId] + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/crafting/silver/SilverStringingListener.kt b/Server/src/main/content/global/skill/crafting/silver/SilverStringingListener.kt new file mode 100644 index 0000000..591dc42 --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/silver/SilverStringingListener.kt @@ -0,0 +1,37 @@ +package content.global.skill.crafting.silver + +import core.api.addItem +import core.api.removeItem +import core.game.node.Node +import core.game.node.entity.player.Player +import org.rs09.consts.Items +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +/** + * Handles ball of wool <-> stringable silver items interaction. + * + * @author vddCore + */ +class SilverStringingListener : InteractionListener { + companion object { + private val STRINGABLE_PRODUCTS = intArrayOf( + Items.UNSTRUNG_SYMBOL_1714, + Items.UNSTRUNG_EMBLEM_1720 + ) + } + + private fun stringSilverProduct(player: Player, used: Node, with: Node): Boolean { + SilverProduct.forProductID(with.id)?.let { + if (removeItem(player, with.id) && removeItem(player, used.id)) { + addItem(player, it.strungId) + } + } + + return true + } + + override fun defineListeners() { + onUseWith(IntType.ITEM, Items.BALL_OF_WOOL_1759, *STRINGABLE_PRODUCTS, handler = ::stringSilverProduct) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/crafting/spinning/SpinningItem.java b/Server/src/main/content/global/skill/crafting/spinning/SpinningItem.java new file mode 100644 index 0000000..27e561d --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/spinning/SpinningItem.java @@ -0,0 +1,105 @@ +package content.global.skill.crafting.spinning; + +/** + * Represents an item to be spinned. + * @author 'Vexia + */ +public enum SpinningItem { + WOOL(19, 1737, 1759, 1, 2.5), FLAX(17, 1779, 1777, 10, 15), ROOT(23, 6051, 6038, 19, 30), ROOT1(23, 6043, 6038, 19, 30), ROOT2(23, 6045, 6038, 19, 30), ROOT3(23, 6047, 6038, 19, 30), ROOT4(23, 6049, 6038, 19, 30), ROOT5(23, 6053, 6038, 19, 30), SINEW(27, 9436, 9438, 10, 15), TREE_ROOTS(31, 6043, 9438, 10, 15), YACK(35, 10814, 954, 30, 25); + + /** + * The button id. + */ + private final int button; + + /** + * The needed item. + */ + private final int need; + + /** + * The product. + */ + private final int product; + + /** + * The level required. + */ + private final int level; + + /** + * The exp gained. + */ + private final double exp; + + /** + * Constructs a new {@code SpinningItem} {@code Object}. + * @param button the button. + * @param need the needed item id. + * @param product the product. + * @param level the level. + * @param exp the exp. + */ + SpinningItem(int button, int need, int product, int level, double exp) { + this.button = button; + this.need = need; + this.product = product; + this.level = level; + this.exp = exp; + } + + /** + * Gets the spinning item. + * @param id the id. + * @return the item. + */ + public static SpinningItem forId(int id) { + for (SpinningItem spin : SpinningItem.values()) { + if (spin.button == id) { + return spin; + } + } + return null; + } + + /** + * Gets the button. + * @return The button. + */ + public int getButton() { + return button; + } + + /** + * Gets the need. + * @return The need. + */ + public int getNeed() { + return need; + } + + /** + * Gets the product. + * @return The product. + */ + public int getProduct() { + return product; + } + + /** + * Gets the level. + * @return The level. + */ + public int getLevel() { + return level; + } + + /** + * Gets the exp. + * @return The exp. + */ + public double getExp() { + return exp; + } + +} diff --git a/Server/src/main/content/global/skill/crafting/spinning/SpinningPulse.java b/Server/src/main/content/global/skill/crafting/spinning/SpinningPulse.java new file mode 100644 index 0000000..ae652f9 --- /dev/null +++ b/Server/src/main/content/global/skill/crafting/spinning/SpinningPulse.java @@ -0,0 +1,113 @@ +package content.global.skill.crafting.spinning; + +import core.cache.def.impl.ItemDefinition; +import core.game.container.impl.EquipmentContainer; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.world.map.Location; +import core.game.node.entity.skill.SkillPulse; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playAudio; + +/** + * Represents the pulse used to spin an item. + * + * @author 'Vexia + */ +public final class SpinningPulse extends SkillPulse { + + /** + * Represents the animation to use. + */ + private static final Animation ANIMATION = new Animation(896); + + /** + * Represents the type of spinning item. + */ + private final SpinningItem type; + + /** + * Represents the amount to spin. + */ + private int ammount; + + /** + * Represents the ticks passed. + */ + private int ticks; + + /** + * Constructs a new {@code SpinningPulse.java} {@Code Object} + * + * @param player + * @param node + */ + public SpinningPulse(Player player, Item node, int ammount, SpinningItem def) { + super(player, node); + this.type = def; + this.ammount = ammount; + } + + @Override + public boolean checkRequirements() { + player.getInterfaceManager().close(); + if (player.getSkills().getLevel(Skills.CRAFTING) < type.getLevel()) { + player.getPacketDispatch().sendMessage("You need a crafting level of " + type.getLevel() + " to make this."); + return false; + } + if (!player.getInventory().contains(type.getNeed(), 1)) { + player.getPacketDispatch().sendMessage("You need " + ItemDefinition.forId(type.getNeed()).getName() + " to do this."); + return false; + } + return true; + } + + @Override + public void animate() { + if (ticks % 5 == 0) { + player.animate(ANIMATION); + playAudio(player, Sounds.SPINNING_2590); + } + } + + @Override + public boolean reward() { + int tickThreshhold = 4; + if (player.getAchievementDiaryManager().getDiary(DiaryType.SEERS_VILLAGE).isComplete(2) + && player.getLocation().withinDistance(Location.create(2711,3471,1)) + && player.getEquipment().get(EquipmentContainer.SLOT_HAT) != null + && player.getEquipment().get(EquipmentContainer.SLOT_HAT).getId() == 14631) { + tickThreshhold = 2; + } + if (++ticks % tickThreshhold != 0) { + return false; + } + if (player.getInventory().remove(new Item(type.getNeed(), 1))) { + final Item item = new Item(type.getProduct(), 1); + player.getInventory().add(item); + player.getSkills().addExperience(Skills.CRAFTING, type.getExp(), true); + + // Seers achievement diary + if (player.getViewport().getRegion().getId() == 10806 + && !player.getAchievementDiaryManager().getDiary(DiaryType.SEERS_VILLAGE).isComplete(0, 4)) { + if (player.getAttribute("diary:seers:bowstrings-spun", 0) >= 4) { + player.setAttribute("/save:diary:seers:bowstrings-spun", 5); + player.getAchievementDiaryManager().finishTask(player, DiaryType.SEERS_VILLAGE, 0, 4); + } else { + player.setAttribute("/save:diary:seers:bowstrings-spun", player.getAttribute("diary:seers:bowstrings-spun", 0) + 1); + } + } + } + ammount--; + return ammount < 1; + } + + @Override + public void message(int type) { + } + +} diff --git a/Server/src/main/content/global/skill/farming/BasketsAndSacks.kt b/Server/src/main/content/global/skill/farming/BasketsAndSacks.kt new file mode 100644 index 0000000..fea2f83 --- /dev/null +++ b/Server/src/main/content/global/skill/farming/BasketsAndSacks.kt @@ -0,0 +1,50 @@ +package content.global.skill.farming + +import org.rs09.consts.Items + +/** + * I don't want to do it this way but jagex has forced my hand + */ +enum class BasketsAndSacks(val produceID: Int, val baseContainer: Int, val capacity : Int) { + POTATO(Items.POTATO_1942, Items.POTATOES1_5420, 10), + ONION(Items.ONION_1957, Items.ONIONS1_5440, 10), + CABBAGE(Items.CABBAGE_1965, Items.CABBAGES1_5460, 10), + APPLE(Items.COOKING_APPLE_1955, Items.APPLES1_5378, 5), + BANANA(Items.BANANA_1963, Items.BANANAS1_5408, 5), + ORANGE(Items.ORANGE_2108, Items.ORANGES1_5388, 5), + STRAWBERRY(Items.STRAWBERRY_5504, Items.STRAWBERRIES1_5398, 5), + TOMATO(Items.TOMATO_1982, Items.TOMATOES1_5960, 5); + + val containers = ArrayList() + + companion object{ + private val map = HashMap() + + init { + values().map { it.produceID to it }.toMap(map) + for(b in values()){ + for(i in 0 until b.capacity){ + map[b.baseContainer + (i * 2)] = b + b.containers.add(b.baseContainer + (i * 2)) + } + } + } + + @JvmStatic + fun forId(itemId: Int): BasketsAndSacks?{ + return map[itemId] + } + } + + fun checkIsLast(containerID: Int): Boolean { + return containerID == containers.last() + } + + fun checkIsFirst(containerID: Int): Boolean { + return containerID == containers.first() + } + + fun checkWhich(containerID: Int): Int{ + return containers.indexOf(containerID) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/farming/CompostBin.kt b/Server/src/main/content/global/skill/farming/CompostBin.kt new file mode 100644 index 0000000..c7e7f5c --- /dev/null +++ b/Server/src/main/content/global/skill/farming/CompostBin.kt @@ -0,0 +1,202 @@ +package content.global.skill.farming + +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.tools.RandomFunction +import org.json.simple.JSONArray +import org.json.simple.JSONObject +import org.rs09.consts.Items +import org.rs09.consts.Sounds +import java.util.concurrent.TimeUnit + +class CompostBin(val player: Player, val bin: CompostBins) { + private var items = ArrayList() + var isSuperCompost = true + var isTomatoes = true + var isClosed = false + var finishedTime = 0L + var isFinished = false + + /** + * Resets the compost bin to its initial state. + */ + fun reset() { + items.clear() + isSuperCompost = true + isTomatoes = true + isClosed = false + finishedTime = 0L + isFinished = false + updateBit() + } + + fun isFull() : Boolean { + return items.size == 15 + } + + fun close() { + isClosed = true + sendMessage(player, "You close the compost bin.") + // TODO: Add animation - https://youtu.be/B50dwm8fdcQ?t=225 https://youtu.be/BHYgNDLx0s4?t=488 + playAudio(player, Sounds.COMPOST_CLOSE_2428) + sendMessage(player, "The contents have begun to rot.") + finishedTime = System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(RandomFunction.random(35,50).toLong()) + updateBit() + } + + fun open(){ + isClosed = false + // TODO: Add animation + playAudio(player, Sounds.COMPOST_OPEN_2429) + sendMessage(player, "You open the compost bin.") + updateBit() + } + + fun takeItem(): Item?{ + if(items.isEmpty()) return null + val item = items[0] + items.remove(item) + if(items.isEmpty()){ + isFinished = false + finishedTime = 0L + isTomatoes = true + isSuperCompost = true + isClosed = false + } + playAudio(player, Sounds.FARMING_SCOOP_2443) + updateBit() + if(isSuperCompost) rewardXP(player, Skills.FARMING, 8.5) + else rewardXP(player, Skills.FARMING, 4.5) + return Item(item) + } + + fun isDefaultState() : Boolean { + return (isFinished == false && finishedTime == 0L && items.size == 0) + } + + fun isReady(): Boolean { + return System.currentTimeMillis() > finishedTime && finishedTime != 0L + } + + fun checkSuperCompostItem(id: Int): Boolean{ + return when (id){ + Items.WATERMELON_5982, + Items.PINEAPPLE_2114, + Items.CALQUAT_FRUIT_5980, + Items.OAK_ROOTS_6043, + Items.WILLOW_ROOTS_6045, + Items.MAPLE_ROOTS_6047, + Items.YEW_ROOTS_6049, + Items.MAGIC_ROOTS_6051, + Items.COCONUT_5974, + Items.COCONUT_SHELL_5978, + Items.PAPAYA_FRUIT_5972, + Items.JANGERBERRIES_247, + Items.WHITE_BERRIES_239, + Items.POISON_IVY_BERRIES_6018, + Items.CLEAN_TOADFLAX_2998, + Items.CLEAN_AVANTOE_261, + Items.CLEAN_KWUARM_263, + Items.CLEAN_CADANTINE_265, + Items.CLEAN_DWARF_WEED_267, + Items.CLEAN_TORSTOL_269, + Items.CLEAN_LANTADYME_2481, + Items.CLEAN_SNAPDRAGON_3000, + Items.GRIMY_TOADFLAX_3049, + Items.GRIMY_KWUARM_213, + Items.GRIMY_AVANTOE_211, + Items.GRIMY_TORSTOL_219, + Items.GRIMY_DWARF_WEED_217, + Items.GRIMY_LANTADYME_2485, + Items.GRIMY_SNAPDRAGON_3051, + Items.GRIMY_CADANTINE_215 -> true + else -> false + } + } + + fun addItem(item: Int){ + if(!isFull()) { + items.add(item) + if (!checkSuperCompostItem(item)) { + isSuperCompost = false + } + if(item != Items.TOMATO_1982) isTomatoes = false + } + updateBit() + } + + fun addItem(item: Item){ + val remaining = 15 - items.size + val amount = if(item.amount > remaining){ + remaining + } else item.amount + for(i in 0 until amount) { + + playAudio(player, Sounds.FARMING_PUTIN_2441) + addItem(item.id) + } + } + + fun updateBit(){ + if(items.isNotEmpty()) { + if (isClosed) { + setVarbit(player, bin.varbit, 0x40) + } else if (isFinished) { + var finalValue = if (items.size == 15) 15 else 14 + if (isTomatoes) finalValue += 0x80 + else if (isSuperCompost) finalValue += 0x20 + setVarbit(player, bin.varbit, finalValue) + } else { + var finalValue = items.size + if (isTomatoes) finalValue += 0x80 + setVarbit(player, bin.varbit, finalValue) + } + } else setVarbit(player, bin.varbit, 0) + } + + fun save(root: JSONObject){ + val binObject = JSONObject() + binObject.put("isSuper",this.isSuperCompost) + val items = JSONArray() + for(id in this.items){ + items.add(id) + } + binObject.put("items",items) + binObject.put("finishTime",finishedTime) + binObject.put("isTomato",isTomatoes) + binObject.put("isClosed",isClosed) + binObject.put("isFinished",isFinished) + root.put("binData",binObject) + } + + fun parse(_data: JSONObject){ + val isSuper = if(_data.containsKey("isSuper")) (_data["isSuper"] as Boolean) else true + if(_data.containsKey("items")){ + (_data["items"] as JSONArray).forEach { + addItem(it.toString().toInt()) + } + } + if(_data.containsKey("finishTime")) finishedTime = _data["finishTime"].toString().toLong() + if(_data.containsKey("isTomato")) isTomatoes = _data["isTomato"] as Boolean + if(_data.containsKey("isClosed")) isClosed = _data["isClosed"] as Boolean + if(_data.containsKey("isFinished")) isFinished = _data["isFinished"] as Boolean + updateBit() + } + + fun finish(){ + if(isTomatoes) items = items.map { Items.ROTTEN_TOMATO_2518 } as ArrayList + else if(isSuperCompost) items = items.map { Items.SUPERCOMPOST_6034 } as ArrayList + else items = items.map { Items.COMPOST_6032 } as ArrayList + isFinished = true + } + + fun convert(){ + if(!isSuperCompost){ + items = items.map { Items.SUPERCOMPOST_6034 } as ArrayList + isSuperCompost = true + updateBit() + } + } +} diff --git a/Server/src/main/content/global/skill/farming/CompostBinOptionHandler.kt b/Server/src/main/content/global/skill/farming/CompostBinOptionHandler.kt new file mode 100644 index 0000000..a8a0b18 --- /dev/null +++ b/Server/src/main/content/global/skill/farming/CompostBinOptionHandler.kt @@ -0,0 +1,50 @@ +package content.global.skill.farming + +import core.api.* +import core.cache.def.impl.SceneryDefinition +import core.game.interaction.OptionHandler +import core.game.node.Node +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.plugin.Plugin + +@Initializable +class CompostBinOptionHandler : OptionHandler() { + override fun newInstance(arg: Any?): Plugin { + for (i in 7836..7839) + SceneryDefinition.forId(i).childrenIds.forEach { + val def = SceneryDefinition.forId(it) + def.handlers["option:open"] = this + def.handlers["option:close"] = this + def.handlers["option:take-tomato"] = this + } + return this + } + + override fun handle(player: Player?, node: Node?, option: String?): Boolean { + player ?: return false + node ?: return false + val cBin = CompostBins.forObject(node.asScenery()) ?: return false + val bin = cBin.getBinForPlayer(player) + + when (option) { + "close" -> if (!bin.isFull()) sendMessage(player, "This shouldn't be happening. Report this.") else bin.close() + "open" -> if (!bin.isFinished) sendMessage(player, "I should probably wait until it is done to open it.") else bin.open() + "take-tomato" -> { + if (!bin.isTomatoes || !bin.isFinished) { + sendMessage(player, "This shouldn't be happening. Report this.") + } else { + if (player.inventory.isFull) { + sendMessage(player, "You don't have enough inventory space to do this.") + } else { + val reward = bin.takeItem() + if (reward != null) + player.inventory.add(reward) + } + } + } + } + return true + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/farming/CompostBins.kt b/Server/src/main/content/global/skill/farming/CompostBins.kt new file mode 100644 index 0000000..3780625 --- /dev/null +++ b/Server/src/main/content/global/skill/farming/CompostBins.kt @@ -0,0 +1,35 @@ +package content.global.skill.farming + +import content.global.skill.farming.timers.Compost +import core.api.getOrStartTimer +import core.cache.def.impl.SceneryDefinition +import core.game.node.entity.player.Player +import core.game.node.scenery.Scenery + +enum class CompostBins(val varbit: Int) { + FALADOR_COMPOST(740), + CATHERBY_COMPOST(741), + PORT_PHAS_COMPOST(742), + ARDOUGNE_COMPOST(743); + + companion object { + @JvmField + val bins = values().map { it.varbit to it }.toMap() + + @JvmStatic + fun forObject(obj: Scenery): CompostBins?{ + return forObjectID(obj.id) + } + + @JvmStatic + fun forObjectID(id: Int): CompostBins?{ + val objDef = SceneryDefinition.forId(id) + return bins[objDef.varbitID] + } + } + + fun getBinForPlayer(player: Player) : CompostBin { + val bins = getOrStartTimer (player) + return bins.getBin (this) + } +} diff --git a/Server/src/main/content/global/skill/farming/CompostType.kt b/Server/src/main/content/global/skill/farming/CompostType.kt new file mode 100644 index 0000000..01e34db --- /dev/null +++ b/Server/src/main/content/global/skill/farming/CompostType.kt @@ -0,0 +1,7 @@ +package content.global.skill.farming + +enum class CompostType { + NONE, + COMPOST, + SUPERCOMPOST +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/farming/CropHarvester.kt b/Server/src/main/content/global/skill/farming/CropHarvester.kt new file mode 100644 index 0000000..1ba3dd4 --- /dev/null +++ b/Server/src/main/content/global/skill/farming/CropHarvester.kt @@ -0,0 +1,142 @@ +package content.global.skill.farming + +import core.api.* +import core.cache.def.impl.SceneryDefinition +import core.game.interaction.OptionHandler +import core.game.node.Node +import content.global.skill.summoning.familiar.GiantEntNPC +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.game.world.update.flag.context.Animation +import core.plugin.Initializable +import core.plugin.Plugin +import org.rs09.consts.Items +import org.rs09.consts.Sounds + +val livesBased = arrayOf(PatchType.HERB_PATCH, PatchType.CACTUS_PATCH, PatchType.BELLADONNA_PATCH, PatchType.HOPS_PATCH, PatchType.ALLOTMENT, PatchType.EVIL_TURNIP_PATCH) + +@Initializable +class CropHarvester : OptionHandler() { + + override fun newInstance(arg: Any?): Plugin { + SceneryDefinition.setOptionHandler("harvest", this) + SceneryDefinition.setOptionHandler("pick", this) + return this + } + + companion object { + @JvmStatic + fun harvestPulse(player: Player?, node: Node?, crop: Int): Pulse? { + player ?: return null + node ?: return null + val fPatch = FarmingPatch.forObject(node.asScenery()) + fPatch ?: return null + val patch = fPatch.getPatchFor(player) + val patchName = patch.patch.type.displayName() + val plantable = patch.plantable + plantable ?: return null + var firstHarvest = true + + return object : Pulse(0) { + override fun pulse(): Boolean { + var reward = Item(crop) + + val familiar = player.familiarManager.familiar + if (familiar != null && familiar is GiantEntNPC) { + familiar.modifyFarmingReward(fPatch, reward) + } + if (!hasSpaceFor(player, reward)) { + sendMessage(player, "You have run out of inventory space.") + return true + } + var requiredItem = when (fPatch.type) { + PatchType.TREE_PATCH -> Items.SECATEURS_5329 + else -> Items.SPADE_952 + } + if (requiredItem == Items.SECATEURS_5329) { + if (inInventory(player, Items.MAGIC_SECATEURS_7409)) { + requiredItem = Items.MAGIC_SECATEURS_7409 + } + } + val anim = when (requiredItem) { + Items.SPADE_952 -> { + when (fPatch.type) { + PatchType.HERB_PATCH -> Animation(2282) + PatchType.FLOWER_PATCH -> Animation(2292) + else -> Animation(830) + } + } + Items.SECATEURS_5329 -> if (fPatch.type == PatchType.TREE_PATCH) Animation(2277) else Animation(7227) + Items.MAGIC_SECATEURS_7409 -> if (fPatch.type == PatchType.TREE_PATCH) Animation(3340) else Animation(7228) + else -> Animation(0) + } + val sound = when (requiredItem) { + Items.SPADE_952 -> Sounds.DIGSPADE_1470 + Items.SECATEURS_5329 -> Sounds.FARMING_PICK_2437 + Items.MAGIC_SECATEURS_7409 -> Sounds.FARMING_PICK_2437 + else -> 0 + } + if (!inInventory(player, requiredItem)) { + sendMessage(player, "You lack the needed tool to harvest these crops.") + return true + } + val sendHarvestMessages = if (fPatch.type == PatchType.FLOWER_PATCH) false else true + if (sendHarvestMessages && firstHarvest) { + sendMessage(player, "You begin to harvest the $patchName.") + firstHarvest = false + } + animate(player, anim) + playAudio(player, sound) + // TODO: If a flower patch is being harvested, delay the clearing of the + // patch until after the animation has played - https://youtu.be/lg4GktlVNUY?t=75 + delay = 2 + addItem(player, reward.id) + rewardXP(player, Skills.FARMING, plantable.harvestXP) + if (patch.patch.type in livesBased) { + patch.rollLivesDecrement( + getDynLevel(player, Skills.FARMING), + inInventory(player, Items.MAGIC_SECATEURS_7409) //add ||inEquipment() check when Fairy Tale pt 1 has been implemented + ) + } else { + patch.harvestAmt-- + if (patch.harvestAmt <= 0 && crop == plantable.harvestItem) { + patch.clear() + } + } + if (sendHarvestMessages && (patch.cropLives <= 0 || patch.harvestAmt <= 0)) { + sendMessage(player, "The $patchName is now empty.") + } + return patch.cropLives <= 0 || patch.harvestAmt <= 0 + } + } + } + } + + override fun handle(player: Player?, node: Node?, option: String?): Boolean { + player ?: return false + node ?: return false + val fPatch = FarmingPatch.forObject(node.asScenery()) + fPatch ?: return false + val patch = fPatch.getPatchFor(player) + val plantable = patch.plantable + plantable ?: return false + + if (patch.isWeedy() || patch.isEmptyAndWeeded()) { + sendMessage(player, "Something seems to have gone wrong here. Report this.") + return true + } + + if (!hasSpaceFor(player, Item(plantable.harvestItem))) { + sendMessage(player, "You don't have enough inventory space to do that.") + return true + } + + val pulse = harvestPulse(player, node, plantable.harvestItem) ?: return false + submitIndividualPulse(player, pulse) + + return true + } + +} diff --git a/Server/src/main/content/global/skill/farming/DigUpPatchDialogue.kt b/Server/src/main/content/global/skill/farming/DigUpPatchDialogue.kt new file mode 100644 index 0000000..a0d70bb --- /dev/null +++ b/Server/src/main/content/global/skill/farming/DigUpPatchDialogue.kt @@ -0,0 +1,86 @@ +package content.global.skill.farming + +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.interaction.QueueStrength +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Sounds + +@Initializable +class DigUpPatchDialogue(player: Player? = null) : DialoguePlugin(player) { + var patch: Patch? = null + + override fun newInstance(player: Player?): DialoguePlugin { + return DigUpPatchDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + patch = args[0] as Patch + if (patch?.isWeedy() == true || patch?.isEmptyAndWeeded() == true) { + sendDialogue(player, "There aren't any crops in this patch to dig up.") + stage = 1000 + return true + } + if (patch?.patch?.type == PatchType.TREE_PATCH) { + val isTreeStump = patch?.getCurrentState() == patch?.plantable!!.value + patch?.plantable!!.stages + 2 + if (patch!!.isGrown() && !isTreeStump) { + sendMessage(player, "You need to chop this tree down first.") // this message is not authentic + stage = 1000 + return true + } + } + sendDialogueOptions(player, "Are you sure you want to dig up this patch?", "Yes, I want to clear it for new crops.", "No, I want to leave it as it is.") + stage = 0 + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> when (buttonId) { + 1 -> { + end() + val anim = getAnimation(830) + sendMessage(player, "You start digging the farming patch...") + queueScript(player, 0, QueueStrength.WEAK) { stage: Int -> + when (stage) { + 0 -> { + animate(player, anim) + playAudio(player, Sounds.DIGSPADE_1470) + return@queueScript delayScript(player,anim.duration + 2) + } + 1 -> { + animate(player, anim) + playAudio(player, Sounds.DIGSPADE_1470) + return@queueScript delayScript(player, anim.duration + 1) + } + 2 -> { + if (patch?.patch?.type == PatchType.TREE_PATCH) { + if (patch?.getCurrentState() == (patch?.plantable?.value ?: 0) + (patch?.plantable?.stages ?: 0) + 2 && patch?.isWeedy() != true && patch?.isEmptyAndWeeded() != true) { + addItemOrDrop(player, patch?.plantable?.harvestItem ?: 0) + } + } + if (patch?.plantable == Plantable.SCARECROW) { + addItemOrDrop(player, patch?.plantable?.harvestItem ?: 0) + } + patch?.clear() + sendMessage(player, "You have successfully cleared this patch for new crops.") + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + } + else -> end() + } + + 1000 -> end() + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(67984003) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/farming/FarmerPayOptionDialogue.kt b/Server/src/main/content/global/skill/farming/FarmerPayOptionDialogue.kt new file mode 100644 index 0000000..7b29a55 --- /dev/null +++ b/Server/src/main/content/global/skill/farming/FarmerPayOptionDialogue.kt @@ -0,0 +1,113 @@ +package content.global.skill.farming + +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.item.Item +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.Items + +class FarmerPayOptionDialogue(val patch: Patch, val quickPay: Boolean = false): DialogueFile() { + var item: Item? = null + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + START_DIALOGUE -> { + if (patch.patch.type == PatchType.TREE_PATCH && patch.plantable != null && patch.isGrown()) { + // This is for the right-click "Pay" option; full dialogue is in GardenerDialoguePlugin + showTopics( + Topic("Yes, get rid of the tree.", 300, true), + Topic("No thanks.", END_DIALOGUE, true), + title = "Pay 200 gp to have the tree chopped down?" + ) + } else if (patch.protectionPaid) { + npc("I don't know what you're talking about - I'm already", "looking after that patch for you.").also { stage = 100 } + } else if (patch.isDead) { + npc("That patch is dead - it's too late for me to do", "anything about it now.").also { stage = END_DIALOGUE } + } else if (patch.isDiseased) { + npc("That patch is diseased - I can't look after it", "until it has been cured.").also { stage = END_DIALOGUE } // this dialogue is not authentic + } else if (patch.isWeedy() || patch.isEmptyAndWeeded()) { + npc(FacialExpression.NEUTRAL, "You don't have anything planted in that patch. Plant", "something and I might agree to look after it for you.").also { stage = END_DIALOGUE } + } else if (patch.isGrown()) { + npc("That patch is already fully grown!", "I don't know what you want me to do with it!").also { stage = END_DIALOGUE } + } else { + item = patch.plantable?.protectionItem + val protectionText = when (item?.id) { + Items.COMPOST_6032 -> if (item?.amount == 1) "bucket of compost" else "buckets of compost" + Items.POTATOES10_5438 -> if (item?.amount == 1) "sack of potatoes" else "sacks of potatoes" + Items.ONIONS10_5458 -> if (item?.amount == 1) "sack of onions" else "sacks of onions" + Items.CABBAGES10_5478 -> if (item?.amount == 1) "sack of cabbages" else "sacks of cabbages" + Items.JUTE_FIBRE_5931 -> "jute fibres" + Items.APPLES5_5386 -> if (item?.amount == 1) "basket of apples" else "baskets of apples" + Items.MARIGOLDS_6010 -> "harvest of marigold" + Items.TOMATOES5_5968 -> if (item?.amount == 1) "basket of tomatoes" else "baskets of tomatoes" + Items.ORANGES5_5396 -> if (item?.amount == 1) "basket of oranges" else "baskets of oranges" + Items.COCONUT_5974 -> "coconuts" + Items.CACTUS_SPINE_6016 -> "cactus spines" + Items.STRAWBERRIES5_5406 -> if (item?.amount == 1) "basket of strawberries" else "baskets of strawberries" + Items.BANANAS5_5416 -> if (item?.amount == 1) "basket of bananas" else "baskets of bananas" + else -> item?.name?.lowercase() + } + if (item == null) { + npc("Sorry, I won't protect that.").also { stage = END_DIALOGUE } + } else if (quickPay && !(inInventory(player!!, item!!.id, item!!.amount) || inInventory(player!!, note(item!!).id, note(item!!).amount))) { + val amount = if (item?.amount == 1) "one" else item?.amount + npc(FacialExpression.HAPPY, "I want $amount $protectionText for that.") + stage = 200 + } else if (quickPay) { + val amount = if (item?.amount == 1) "one" else item?.amount + showTopics( + Topic("Yes", 20, true), + Topic("No", END_DIALOGUE, true), + title = "Pay $amount $protectionText?" + ) + } else { + val amount = if (item?.amount == 1) "one" else item?.amount + npc("If you like, but I want $amount $protectionText for that.") + stage++ + } + } + } + + 1 -> { + if (!(inInventory(player!!, item!!.id, item!!.amount) || inInventory(player!!, note(item!!).id, note(item!!).amount))) { + player("I'm afraid I don't have any of those at the moment.").also { stage = 10 } + } else { + showTopics( + Topic(FacialExpression.NEUTRAL, "Okay, it's a deal.", 20), + Topic(FacialExpression.NEUTRAL, "No, that's too much.", 10) + ) + } + } + + 10 -> npc("Well, I'm not wasting my time for free.").also { stage = END_DIALOGUE } + + 20 -> { + if (removeItem(player!!, item) || removeItem(player!!, note(item!!))) { + patch.protectionPaid = true + // Note: A slight change in this dialogue was seen in a December 2009 video - https://youtu.be/7gVh42ylQ48?t=138 + npc("That'll do nicely, ${if (player!!.isMale) "sir" else "madam"}. Leave it with me - I'll make sure", "those crops grow for you.").also { stage = END_DIALOGUE } + } else { + npc("This shouldn't be happening. Please report this.").also { stage = END_DIALOGUE } + } + } + + 100 -> player("Oh sorry, I forgot.").also { stage = END_DIALOGUE } + + // Right-click "Pay" - protect patch - player doesn't have payment + 200 -> player(FacialExpression.NEUTRAL, "Thanks, maybe another time.").also { stage = END_DIALOGUE } + + // Right-click "Pay" - chop down tree + 300 -> { + if (removeItem(player!!, Item(Items.COINS_995, 200))) { + patch.clear() + dialogue("The gardener obligingly removes your tree.").also { stage = END_DIALOGUE } + } else { + dialogue("You need 200 gp to pay for that.").also { stage = END_DIALOGUE } // not authentic + } + } + + } + } +} diff --git a/Server/src/main/content/global/skill/farming/FarmerPayOptionHandler.kt b/Server/src/main/content/global/skill/farming/FarmerPayOptionHandler.kt new file mode 100644 index 0000000..52d7874 --- /dev/null +++ b/Server/src/main/content/global/skill/farming/FarmerPayOptionHandler.kt @@ -0,0 +1,28 @@ +package content.global.skill.farming + +import core.api.openDialogue +import core.game.node.Node +import core.game.node.entity.player.Player +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +class FarmerPayOptionHandler : InteractionListener { + + override fun defineListeners() { + on(IntType.NPC,"pay","pay (north)","pay (north-west)") { player, node -> + return@on attemptPay(player,node,0) + } + + on(IntType.NPC,"pay (south)","pay (south-east)") { player, node -> + return@on attemptPay(player,node,1) + } + } + + fun attemptPay(player: Player, node: Node, index: Int): Boolean { + val farmer = Farmers.forId(node.id) ?: return false + val patch = farmer.patches[index].getPatchFor(player) + + openDialogue(player, FarmerPayOptionDialogue(patch, true), node.asNpc()) + return true + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/farming/Farmers.kt b/Server/src/main/content/global/skill/farming/Farmers.kt new file mode 100644 index 0000000..4a57fee --- /dev/null +++ b/Server/src/main/content/global/skill/farming/Farmers.kt @@ -0,0 +1,35 @@ +package content.global.skill.farming + +enum class Farmers(val id: Int, val patches: Array) { + LYRA(2326, arrayOf(FarmingPatch.PORT_PHAS_ALLOTMENT_NW,FarmingPatch.PORT_PHAS_ALLOTMENT_SE)), + ELSTAN(2323, arrayOf(FarmingPatch.S_FALADOR_ALLOTMENT_NW,FarmingPatch.S_FALADOR_ALLOTMENT_SE)), + HESKEL(2340, arrayOf(FarmingPatch.N_FALADOR_TREE)), + ALAIN(2339, arrayOf(FarmingPatch.TAVERLY_TREE)), + DANTAERA(2324, arrayOf(FarmingPatch.CATHERBY_ALLOTMENT_N,FarmingPatch.CATHERBY_ALLOTMENT_S)), + ELLENA(2331, arrayOf(FarmingPatch.CATHERBY_FRUIT_TREE)), + GARTH(2330,arrayOf(FarmingPatch.BRIMHAVEN_FRUIT_TREE)), + GILETH(2344,arrayOf(FarmingPatch.TREE_GNOME_VILLAGE_FRUIT_TREE)), + AMAETHWR(2860,arrayOf(FarmingPatch.LLETYA_FRUIT_TREE)), + SELENA(2332, arrayOf(FarmingPatch.YANILLE_HOPS)), + KRAGEN(2325, arrayOf(FarmingPatch.ARDOUGNE_ALLOTMENT_N,FarmingPatch.ARDOUGNE_ALLOTMENT_S)), + BOLONGO(2343, arrayOf(FarmingPatch.GNOME_STRONGHOLD_FRUIT_TREE)), + PRISSY_SCILLA(1037, arrayOf(FarmingPatch.GNOME_STRONGHOLD_TREE)), + FAYETH(2342, arrayOf(FarmingPatch.LUMBRIDGE_TREE)), + TREZNOR(2341, arrayOf(FarmingPatch.VARROCK_TREE)), + VASQUEN(2333, arrayOf(FarmingPatch.LUMBRIDGE_HOPS)), + RHONEN(2334, arrayOf(FarmingPatch.MCGRUBOR_HOPS)), + FRANCIS(2327, arrayOf(FarmingPatch.ENTRANA_HOPS)), + DREVEN(2335, arrayOf(FarmingPatch.CHAMPIONS_GUILD_BUSH)), + TARIA(2336, arrayOf(FarmingPatch.RIMMINGTON_BUSH)), + TORRELL(2338, arrayOf(FarmingPatch.ARDOUGNE_BUSH)); + + companion object{ + @JvmField + val farmers = values().map { it.id to it }.toMap() + + @JvmStatic + fun forId(id: Int): Farmers?{ + return farmers[id] + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/farming/FarmingPatch.kt b/Server/src/main/content/global/skill/farming/FarmingPatch.kt new file mode 100644 index 0000000..ed033d2 --- /dev/null +++ b/Server/src/main/content/global/skill/farming/FarmingPatch.kt @@ -0,0 +1,124 @@ +package content.global.skill.farming + +import core.api.* +import core.cache.def.impl.SceneryDefinition +import core.game.node.scenery.Scenery +import core.game.node.entity.player.Player +import content.global.skill.farming.timers.CropGrowth + +enum class FarmingPatch(val varbit: Int, val type: PatchType) { + //Allotments + S_FALADOR_ALLOTMENT_NW(708,PatchType.ALLOTMENT), + S_FALADOR_ALLOTMENT_SE(709,PatchType.ALLOTMENT), + CATHERBY_ALLOTMENT_N(710,PatchType.ALLOTMENT), + CATHERBY_ALLOTMENT_S(711,PatchType.ALLOTMENT), + ARDOUGNE_ALLOTMENT_S(713,PatchType.ALLOTMENT), + ARDOUGNE_ALLOTMENT_N(712,PatchType.ALLOTMENT), + PORT_PHAS_ALLOTMENT_NW(714,PatchType.ALLOTMENT), + PORT_PHAS_ALLOTMENT_SE(715,PatchType.ALLOTMENT), + HARMONY_ISLAND_ALLOTMENT(3402,PatchType.ALLOTMENT), + + //Herb + CATHERBY_HERB_CE(781,PatchType.HERB_PATCH), + S_FALADOR_HERB_NE(780,PatchType.HERB_PATCH), + ARDOUGNE_HERB_CE(782,PatchType.HERB_PATCH), + PORT_PHAS_HERB_NE(783,PatchType.HERB_PATCH), + TROLL_STRONGHOLD_HERB(2788,PatchType.HERB_PATCH), + + //Flower + S_FALADOR_FLOWER_C(728,PatchType.FLOWER_PATCH), + CATHERBY_FLOWER_C(729,PatchType.FLOWER_PATCH), + ARDOUGNE_FLOWER_C(730,PatchType.FLOWER_PATCH), + PORT_PHAS_FLOWER_C(731,PatchType.FLOWER_PATCH), + WILDERNESS_FLOWER(5067,PatchType.FLOWER_PATCH), + + //Tree + N_FALADOR_TREE(701,PatchType.TREE_PATCH), + TAVERLY_TREE(700,PatchType.TREE_PATCH), + GNOME_STRONGHOLD_TREE(2953,PatchType.TREE_PATCH), + LUMBRIDGE_TREE(703,PatchType.TREE_PATCH), + VARROCK_TREE(702,PatchType.TREE_PATCH), + + //Fruit Tree + GNOME_STRONGHOLD_FRUIT_TREE(704,PatchType.FRUIT_TREE_PATCH), + CATHERBY_FRUIT_TREE(707,PatchType.FRUIT_TREE_PATCH), + TREE_GNOME_VILLAGE_FRUIT_TREE(705,PatchType.FRUIT_TREE_PATCH), + BRIMHAVEN_FRUIT_TREE(706,PatchType.FRUIT_TREE_PATCH), + LLETYA_FRUIT_TREE(4317,PatchType.FRUIT_TREE_PATCH), + + //Hops + ENTRANA_HOPS(717,PatchType.HOPS_PATCH), + LUMBRIDGE_HOPS(718,PatchType.HOPS_PATCH), + MCGRUBOR_HOPS(719,PatchType.HOPS_PATCH), + YANILLE_HOPS(716,PatchType.HOPS_PATCH), + + //Bushes + CHAMPIONS_GUILD_BUSH(732,PatchType.BUSH_PATCH), + RIMMINGTON_BUSH(733,PatchType.BUSH_PATCH), + ARDOUGNE_BUSH(735,PatchType.BUSH_PATCH), + ETCETERIA_BUSH(734,PatchType.BUSH_PATCH), + + //Spirit Tree + ETCETERIA_SPIRIT_TREE(722,PatchType.SPIRIT_TREE_PATCH), + PORT_SARIM_SPIRIT_TREE(720,PatchType.SPIRIT_TREE_PATCH), + KARAMJA_SPIRIT_TREE(724,PatchType.SPIRIT_TREE_PATCH), + + //Other + DRAYNOR_BELLADONNA(748, PatchType.BELLADONNA_PATCH), + CANIFIS_MUSHROOM(746, PatchType.MUSHROOM_PATCH), + ALKHARID_CACTUS(744, PatchType.CACTUS_PATCH), + EVIL_TURNIP(4291, PatchType.EVIL_TURNIP_PATCH); + + + companion object { + @JvmField + val patches = FarmingPatch.values().map { it.varbit to it }.toMap() + val patchNodes = ArrayList() + val nodeMap = HashMap() + + init { + patchNodes.addAll(8550..8557) //allotment wrappers + patchNodes.addAll(7847..7853) //flower patch wrappers + patchNodes.addAll(8150..8156) //herb patch wrappers + patchNodes.addAll(8388..8391) // Tree patches + patchNodes.add(19147) //Tree patch + patchNodes.addAll(7962..7965) //fruit trees + patchNodes.addAll(8173..8176) //hops + patchNodes.addAll(7577..7580) //bush + patchNodes.add(23760) //evil turnip + patchNodes.add(7572) //belladonna + patchNodes.add(8337) //mushroom + patchNodes.add(27197) //jade vine + patchNodes.add(7771) //cactus + patchNodes.add(7807) //calquat + patchNodes.addAll(8382..8383)//spirit trees + patchNodes.add(8338) //spirit tree + patchNodes.add(18816) //death plateau wrapper + + for (patch in patchNodes) { + val def = SceneryDefinition.forId(patch) + nodeMap[def.varbitID] = def + } + } + + @JvmStatic + fun forObject(obj: Scenery): FarmingPatch?{ + return forObjectID(obj.id) + } + + @JvmStatic + fun forObjectID(id: Int): FarmingPatch?{ + val objDef = SceneryDefinition.forId(id) + return patches[objDef.varbitID] + } + + fun getSceneryDefByVarbit (id: Int) : SceneryDefinition? { + return nodeMap[id] + } + } + + fun getPatchFor(player: Player, addPatch : Boolean = true): Patch{ + val crops = getOrStartTimer (player) + return crops.getPatch(this, addPatch) + } +} diff --git a/Server/src/main/content/global/skill/farming/FarmingPatchZone.kt b/Server/src/main/content/global/skill/farming/FarmingPatchZone.kt new file mode 100644 index 0000000..09a190c --- /dev/null +++ b/Server/src/main/content/global/skill/farming/FarmingPatchZone.kt @@ -0,0 +1,78 @@ +package content.global.skill.farming + +import core.api.* +import core.game.dialogue.FacialExpression +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.world.map.zone.ZoneBorders +import org.rs09.consts.NPCs +import core.game.dialogue.DialogueFile + +class FarmingPatchZone : MapArea, TickListener { + private val playersInZone = hashMapOf() + + override fun defineAreaBorders(): Array { + return arrayOf( + getRegionBorders(12083), + getRegionBorders(10548), + ZoneBorders(3594,3521,3608,3532) + ) + } + + override fun areaEnter(entity: Entity) { + if(entity is Player && playersInZone[entity] == null && getStatLevel(entity, Skills.FARMING) <= 15) { + playersInZone[entity] = 0 + } + } + + override fun areaLeave(entity: Entity, logout: Boolean) { + if(entity is Player) + playersInZone.remove(entity) + } + + override fun tick() { + playersInZone.toList().forEach { (player, ticks) -> + if(!player.isArtificial) { + if (ticks == 500) { + spawnGithan(player, true) + } else if (ticks == 1000) { + spawnGithan(player, false) + } + playersInZone[player] = ticks + 1 + } + } + } + + /** + * Spawns a Githan at a player if they've been standing in a farming patch zone for long enough. + * @param player The player to spawn the Githan at. + * @param firstDialogue Whether the Githan should play the first dialogue or not (and playing the second dialogue instead). + */ + private fun spawnGithan(player: Player, firstDialogue: Boolean) { + val npc = NPC(NPCs.GITHAN_7122) + npc.location = player.location + npc.init() + npc.moveStep() + npc.face(player) + openDialogue(player, SpiritDialogue(firstDialogue), npc) + } + + internal class SpiritDialogue(private val firstDialogue: Boolean) : DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + when(stage){ + 0 -> { + if(firstDialogue) npcl(FacialExpression.NEUTRAL, "In case you didn't know, you don't have to stand by your Farming patch. Your crops will grow even if you're not around.").also { stage++ } + else npcl(FacialExpression.NEUTRAL, "Did you know that if your Farming patch has fully grown, it will never catch disease or die? It will be perfectly safe until you choose to harvest it.").also { stage++ } + } + 1 -> end() + } + } + + override fun end(){ + super.end() + poofClear(npc ?: return) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/farming/FruitAndBerryPicker.kt b/Server/src/main/content/global/skill/farming/FruitAndBerryPicker.kt new file mode 100644 index 0000000..f076893 --- /dev/null +++ b/Server/src/main/content/global/skill/farming/FruitAndBerryPicker.kt @@ -0,0 +1,96 @@ +package content.global.skill.farming + +import core.api.* +import core.cache.def.impl.SceneryDefinition +import core.game.interaction.OptionHandler +import core.game.node.Node +import content.global.skill.summoning.familiar.GiantEntNPC +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.game.world.update.flag.context.Animation +import core.plugin.Initializable +import core.plugin.Plugin +import org.rs09.consts.Sounds +import java.util.concurrent.TimeUnit + +@Initializable +class FruitAndBerryPicker : OptionHandler() { + override fun newInstance(arg: Any?): Plugin { + SceneryDefinition.setOptionHandler("pick-coconut",this) + SceneryDefinition.setOptionHandler("pick-banana",this) + SceneryDefinition.setOptionHandler("pick-apple",this) + SceneryDefinition.setOptionHandler("pick-orange",this) + SceneryDefinition.setOptionHandler("pick-pineapple",this) + SceneryDefinition.setOptionHandler("pick-papaya",this) + SceneryDefinition.setOptionHandler("pick-leaf",this) + SceneryDefinition.setOptionHandler("pick-from",this) + SceneryDefinition.setOptionHandler("pick-fruit",this) + SceneryDefinition.setOptionHandler("pick-spine",this) + return this + } + + override fun handle(player: Player?, node: Node?, option: String?): Boolean { + player ?: return false + node ?: return false + + val fPatch = FarmingPatch.forObject(node.asScenery()) + fPatch ?: return false + + val patch = fPatch.getPatchFor(player) + + val plantable = patch.plantable + plantable ?: return false + + val animation = Animation(2281) + + if (patch.getFruitOrBerryCount() <= 0) { + sendMessage(player, "This shouldn't be happening. Please report this.") + return true + } + + if (!hasSpaceFor(player, Item(plantable.harvestItem))) { + sendMessage(player, "You don't have enough inventory space to do that.") + return true + } + + if (System.currentTimeMillis() - patch.nextGrowth > TimeUnit.MINUTES.toMillis(45)) { + patch.nextGrowth = System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(45) + } + + submitIndividualPulse(player, object : Pulse(animation.duration) { + override fun pulse(): Boolean { + val reward = Item(plantable.harvestItem, 1) + + if (!hasSpaceFor(player, reward)) { + sendMessage(player, "You have run out of inventory space.") + return true + } + + val familiar = player.familiarManager.familiar + if (familiar != null && familiar is GiantEntNPC) { + familiar.modifyFarmingReward(fPatch, reward) + } + + animate(player, animation) + playAudio(player, Sounds.FARMING_PICK_2437) + addItemOrDrop(player, reward.id, reward.amount) + rewardXP(player, Skills.FARMING, plantable.harvestXP) + patch.setCurrentState(patch.getCurrentState() - 1) + + if (patch.patch.type == PatchType.CACTUS_PATCH) { + sendMessage(player, "You carefully pick a spine from the cactus.") + } else { + val determiner = if (patch.patch.type == PatchType.BUSH_PATCH) "some" else "a" + sendMessage(player, "You pick $determiner ${reward.name.lowercase()}.") + } + + return patch.getFruitOrBerryCount() == 0 + } + }) + + return true + } + +} diff --git a/Server/src/main/content/global/skill/farming/HealthChecker.kt b/Server/src/main/content/global/skill/farming/HealthChecker.kt new file mode 100644 index 0000000..5c819f1 --- /dev/null +++ b/Server/src/main/content/global/skill/farming/HealthChecker.kt @@ -0,0 +1,67 @@ +package content.global.skill.farming + +import core.api.* +import core.cache.def.impl.SceneryDefinition +import core.game.interaction.OptionHandler +import core.game.node.Node +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import core.plugin.Plugin +import core.tools.Log +import java.util.concurrent.TimeUnit + +@Initializable +class HealthChecker : OptionHandler() { + override fun newInstance(arg: Any?): Plugin { + SceneryDefinition.setOptionHandler("check-health", this) + return this + } + + override fun handle(player: Player?, node: Node?, option: String?): Boolean { + player ?: return false + node ?: return false + val fPatch = FarmingPatch.forObject(node.asScenery()) + fPatch ?: return false + val patch = fPatch.getPatchFor(player) + val type = patch.patch.type + + if (type != PatchType.BUSH_PATCH && type != PatchType.FRUIT_TREE_PATCH && type != PatchType.TREE_PATCH && type != PatchType.CACTUS_PATCH) { + sendMessage(player, "This shouldn't be happening. Please report this.") + return true + } + + if (!patch.isCheckHealth) return true + + rewardXP(player, Skills.FARMING, patch.plantable?.checkHealthXP ?: 0.0) + patch.isCheckHealth = false + when (type) { + PatchType.TREE_PATCH -> { + patch.setCurrentState(patch.getCurrentState() + 1) + sendMessage(player, "You examine the tree for signs of disease and find that it is in perfect health.") + } + PatchType.FRUIT_TREE_PATCH -> { + patch.setCurrentState(patch.getCurrentState() - 14) + sendMessage(player, "You examine the tree for signs of disease and find that it is in perfect health.") + } + PatchType.BUSH_PATCH -> { + patch.setCurrentState(patch.plantable!!.value + patch.plantable!!.stages + 4) + sendMessage(player, "You examine the bush for signs of disease and find that it's in perfect health.") + } + PatchType.CACTUS_PATCH -> { + patch.setCurrentState(patch.plantable!!.value + patch.plantable!!.stages + 3) + sendMessage(player, "You examine the cactus for signs of disease and find that it is in perfect health.") + } + else -> log(this::class.java, Log.ERR, "Unreachable patch type from when(type) switch in HealthChecker.kt") + } + + if (type == PatchType.FRUIT_TREE_PATCH) { + patch.nextGrowth = TimeUnit.MINUTES.toMillis(45) + } + + patch.update() + + return true + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/farming/InspectionHandler.kt b/Server/src/main/content/global/skill/farming/InspectionHandler.kt new file mode 100644 index 0000000..00a30a5 --- /dev/null +++ b/Server/src/main/content/global/skill/farming/InspectionHandler.kt @@ -0,0 +1,55 @@ +package content.global.skill.farming + +import core.api.* +import core.cache.def.impl.SceneryDefinition +import core.game.interaction.OptionHandler +import core.game.node.Node +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.plugin.Plugin +import core.tools.prependArticle + +@Initializable +class InspectionHandler : OptionHandler() { + override fun newInstance(arg: Any?): Plugin { + SceneryDefinition.setOptionHandler("inspect", this) + return this + } + + override fun handle(player: Player?, node: Node?, option: String?): Boolean { + node ?: return false + player ?: return false + val patch = FarmingPatch.forObject(node.asScenery()) + if (patch == null) { + sendMessage(player, "This is an improperly handled inspect option. Report this please.") + return true + } + + val p = patch.getPatchFor(player) + val patchName = p.patch.type.displayName() + + val statusPatchType = if (patch == FarmingPatch.TROLL_STRONGHOLD_HERB) "This is a very special herb patch." + else "This is ${prependArticle(patchName)}." + + val statusCompost = if (p.compost == CompostType.NONE) "The soil has not been treated." + else "The soil has been treated with ${p.compost.name.lowercase()}." + + val statusStage = if (p.plantable == Plantable.SCARECROW) "" + else if (p.isWeedy()) "The patch needs weeding." + else if (p.isEmptyAndWeeded()) "The patch is empty and weeded." + else if (p.isDiseased && !p.isDead) "The patch is diseased and needs attending to before it dies." + else if (p.isDead) "The patch has become infected by disease and has died." + else if (p.isGrown()) "The patch is fully grown." + else "The patch has something growing in it." + + val statusGardener = if (patch == FarmingPatch.TROLL_STRONGHOLD_HERB) "My Arm will look after this patch for you." + else if (p.protectionPaid) "A nearby gardener is looking after this patch for you." + else "" + + sendMessage(player, "$statusPatchType $statusCompost $statusStage".trim()) + if (statusGardener != "") sendMessage(player, statusGardener) + + return true + } + +} diff --git a/Server/src/main/content/global/skill/farming/LeprechaunNoter.kt b/Server/src/main/content/global/skill/farming/LeprechaunNoter.kt new file mode 100644 index 0000000..3a3d47b --- /dev/null +++ b/Server/src/main/content/global/skill/farming/LeprechaunNoter.kt @@ -0,0 +1,37 @@ +package content.global.skill.farming + +import core.api.* +import core.game.node.item.Item +import org.rs09.consts.NPCs +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +class LeprechaunNoter : InteractionListener { + + val CROPS = Plantable.values().map{ it.harvestItem }.toIntArray() + val LEPRECHAUNS = intArrayOf(NPCs.TOOL_LEPRECHAUN_3021,NPCs.GOTH_LEPRECHAUN_8000,NPCs.TOOL_LEPRECHAUN_4965,NPCs.TECLYN_2861) + + override fun defineListeners() { + onUseWith(IntType.NPC,CROPS,*LEPRECHAUNS){ player, used, with -> + val usedItem = used.asItem() + val npc = with.asNpc() + val expr = when(npc.id){ + 3021 -> core.game.dialogue.FacialExpression.OLD_NORMAL + else -> core.game.dialogue.FacialExpression.FRIENDLY + } + + if(usedItem.noteChange != usedItem.id){ + val amt = player.inventory.getAmount(usedItem.id) + if(player.inventory.remove(Item(usedItem.id,amt))){ + player.inventory.add(Item(usedItem.noteChange,amt)) + } + sendItemDialogue(player,usedItem.id,"The leprechaun exchanges your items for banknotes.") + } else { + // Unsure why the line below no longer functions, despite only changing the line above to be more correct. Using your note(NOT CROP) on the leprechaun no longer functions because of this. - Crash + player.dialogueInterpreter.sendDialogues(npc.id,expr,"That IS a banknote!") + } + + return@onUseWith true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/farming/Patch.kt b/Server/src/main/content/global/skill/farming/Patch.kt new file mode 100644 index 0000000..8965167 --- /dev/null +++ b/Server/src/main/content/global/skill/farming/Patch.kt @@ -0,0 +1,396 @@ +package content.global.skill.farming + +import core.api.* +import core.game.node.entity.player.Player +import core.tools.Log +import core.tools.RandomFunction +import org.rs09.consts.Items +import java.util.concurrent.TimeUnit +import kotlin.math.ceil +import kotlin.math.min + +class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantable?, var currentGrowthStage: Int, var isDiseased: Boolean, var isDead: Boolean, var isWatered: Boolean, var nextGrowth: Long, var harvestAmt: Int, var isCheckHealth: Boolean) { + constructor(player: Player, patch: FarmingPatch) : this(player,patch,null,0,false,false,false,0L,0,false) + + var diseaseMod = 0 + var compost = CompostType.NONE + var protectionPaid = false + var cropLives = 3 + + fun setNewHarvestAmount() { + val compostMod = when(compost) { + CompostType.NONE -> 0 + CompostType.COMPOST -> 1 + CompostType.SUPERCOMPOST -> 2 + } + harvestAmt = when (plantable) { + Plantable.LIMPWURT_SEED, Plantable.WOAD_SEED -> 3 + Plantable.MUSHROOM_SPORE -> 6 + Plantable.WILLOW_SAPLING -> 0 + else -> 1 + } + if(plantable != null && plantable?.applicablePatch != PatchType.FLOWER_PATCH) { + harvestAmt += compostMod + } + cropLives = 3 + compostMod + } + + fun rollLivesDecrement(farmingLevel: Int, magicSecateurs: Boolean){ + if(patch.type == PatchType.HERB_PATCH){ + //authentic formula thanks to released data. + var herbSaveLow = when(plantable){ + Plantable.GUAM_SEED -> min(24 + farmingLevel, 80) + Plantable.MARRENTILL_SEED -> min(28 + farmingLevel, 80) + Plantable.TARROMIN_SEED -> min(31 + farmingLevel, 80) + Plantable.HARRALANDER_SEED -> min(36 + farmingLevel, 80) + Plantable.GOUT_TUBER -> min(39 + farmingLevel, 80) + Plantable.RANARR_SEED -> min(39 + farmingLevel, 80) + Plantable.SPIRIT_WEED_SEED -> min(43 + farmingLevel, 80) + Plantable.TOADFLAX_SEED -> min(43 + farmingLevel, 80) + Plantable.IRIT_SEED -> min(46 + farmingLevel, 80) + Plantable.AVANTOE_SEED -> min(50 + farmingLevel, 80) + Plantable.KWUARM_SEED -> min(54 + farmingLevel, 80) + Plantable.SNAPDRAGON_SEED -> min(57 + farmingLevel, 80) + Plantable.CADANTINE_SEED -> min(60 + farmingLevel, 80) + Plantable.LANTADYME_SEED -> min(64 + farmingLevel, 80) + Plantable.DWARF_WEED_SEED -> min(67 + farmingLevel, 80) + Plantable.TORSTOL_SEED -> min(71 + farmingLevel, 80) + else -> -1 + } + + if(magicSecateurs) herbSaveLow = ceil(1.10 * herbSaveLow).toInt() + + val rand = RandomFunction.random(256) + + if(rand > herbSaveLow){ + cropLives -= 1 + } + } else { + //inauthentic formulae based on reported averages due to lack of formula + var chance = when(patch.type){ + PatchType.ALLOTMENT -> 8 //average of 8 per life times 3 lives = average 24 + PatchType.HOPS_PATCH -> 6 //average of 6 per life times 3 lives = 18 + PatchType.BELLADONNA_PATCH -> 2 //average of 2 per life times 3 lives = 6 + PatchType.EVIL_TURNIP_PATCH -> 2 //average 2 per, same as BELLADONNA + PatchType.CACTUS_PATCH -> 3 //average of 3 per life times 3 lives = 9 + else -> 0 // nothing should go here, but if it does, do not give extra crops amd decrement cropLives + } + + if(magicSecateurs) chance += ceil(1.10 * chance).toInt() //will increase average yield by roughly 3. + + if(RandomFunction.roll(chance)) cropLives -= 1 + } + + if(cropLives <= 0) clear() + } + + fun isWeedy(): Boolean { + return getCurrentState() in 0..2 + } + + fun isEmptyAndWeeded(): Boolean { + return getCurrentState() == 3 + } + + fun getCurrentState(): Int{ + return getVarbit(player, patch.varbit) + } + + fun setCurrentState(state: Int){ + setVarbit(player, patch.varbit, state) + updateBit() + } + + fun setVisualState (state: Int) { + val finalState = ensureStateSanity(state) + setVarbit(player, patch.varbit, finalState) + } + + fun ensureStateSanity (state: Int) : Int { + val patchDef = FarmingPatch.getSceneryDefByVarbit(patch.varbit) ?: return state + val currentStateDef = patchDef.getChildObjectAtIndex(state) + if (currentStateDef.name == patchDef.getChildObjectAtIndex(3).name) { //if we're weedy + if (state and 0x40 != 0) { //if this invalid state was caused by water/death + //remove water/death + isDead = false + isWatered = false + log(this::class.java, Log.DEBUG, "Patch for ${player.username} at varbit ${patch.varbit} with plantable ${plantable?.name ?: "none"} was set to watered/dead at stage $currentGrowthStage, which isn't valid.") + return (state and (0x40.inv())) + } + else if (state and 0x80 != 0) { //if this invalid state was caused by disease + //remove disease + isDiseased = false + log(this::class.java, Log.DEBUG, "Patch for ${player.username} at varbit ${patch.varbit} with plantable ${plantable?.name ?: "none"} was set to diseased at stage $currentGrowthStage, which isn't valid.") + return (state and (0x80.inv())) + } + else if (state in listOf(0, 1, 2, 3)){ + // we're weedy (or an empty plot) as normal just continue + } + else { + log (this::class.java, Log.ERR, "Patch for ${player.username} at varbit ${patch.varbit} with plantable ${plantable?.name ?: "none"} was set to state $state at growth stage $currentGrowthStage, which isn't valid. We're not sure why this is happening.") + } + } + return state + } + + fun isFertilized(): Boolean { + return compost != CompostType.NONE + } + + /** + * Returns true if the patch is fully grown. + * + * Note: This returns true if the patch is fully weedy. + * Use `plantable == null` to check if a patch does + * not have anything planted. + */ + fun isGrown(): Boolean{ + return currentGrowthStage == (plantable?.stages ?: 0) + } + + fun updateBit(){ + if(isCheckHealth){ + when(patch.type){ + PatchType.FRUIT_TREE_PATCH -> setVarbit(player, patch.varbit, plantable!!.value + plantable!!.stages + 20) + PatchType.BUSH_PATCH -> setVarbit(player, patch.varbit, 250 + (plantable!!.ordinal - Plantable.REDBERRY_SEED.ordinal)) + PatchType.CACTUS_PATCH -> setVarbit(player, patch.varbit, 31) + PatchType.TREE_PATCH -> setVarbit(player, patch.varbit, plantable!!.value + plantable!!.stages) + else -> log(this::class.java, Log.WARN, "Invalid setting of isCheckHealth for patch type: " + patch.type.name + "at" + patch.name) + } + } else { + when(patch.type){ + PatchType.ALLOTMENT,PatchType.FLOWER_PATCH,PatchType.HOPS_PATCH -> { + var state = getUnmodifiedValue() + if (isWatered || isDead) state = state or 0x40 + if (isDiseased) state = state or 0x80 + + if (state != getVarbit(player, patch.varbit)) + setVisualState(state) + } + PatchType.BUSH_PATCH -> { + if(isDead) setVisualState(getBushDeathValue()) + else if(isDiseased && !isDead) setVisualState(getBushDiseaseValue()) + } + PatchType.TREE_PATCH -> { + var state = getVarbit(player, patch.varbit) + + if (isDead) state = state or 0x80 + else if (isDiseased) state = state or 0x40 + + if (state != getVarbit(player, patch.varbit)) + setVisualState(state) + } + PatchType.FRUIT_TREE_PATCH -> { + if(isDead) setVisualState(getFruitTreeDeathValue()) + else if(isDiseased && !isDead) setVisualState(getFruitTreeDiseaseValue()) + } + PatchType.BELLADONNA_PATCH -> { + if(isDead) setVisualState(getBelladonnaDeathValue()) + else if(isDiseased && !isDead) setVisualState(getBelladonnaDiseaseValue()) + else setVisualState((plantable?.value ?: 0) + currentGrowthStage) + } + PatchType.CACTUS_PATCH -> { + if(isDead) setVisualState(getCactusDeathValue()) + else if(isDiseased && !isDead) setVisualState(getCactusDiseaseValue()) + } + PatchType.HERB_PATCH -> { + if(isDead) setVisualState(getHerbDeathValue()) + else if(isDiseased && !isDead) setVisualState(getHerbDiseaseValue()) + else setVisualState((plantable?.value ?: 0) + currentGrowthStage) + } + else -> {} + } + } + } + + fun cureDisease() { + setVarbit(player, patch.varbit, (plantable?.value ?: 0) + currentGrowthStage) + isDiseased = false + updateBit() + } + + fun water() { + isWatered = true + updateBit() + } + + private fun getUnmodifiedValue(): Int { + return (plantable?.value ?: 0) + currentGrowthStage + } + + private fun getBushDiseaseValue(): Int{ + if(plantable == Plantable.POISON_IVY_SEED){ + return (plantable?.value ?: 0) + currentGrowthStage + 12 + } else { + return (plantable?.value ?: 0) + currentGrowthStage + 64 + } + } + + private fun getBushDeathValue(): Int{ + if(plantable == Plantable.POISON_IVY_SEED){ + return (plantable?.value ?: 0) + currentGrowthStage + 22 + } else { + return (plantable?.value ?: 0) + currentGrowthStage + 126 + } + } + + private fun getFruitTreeDiseaseValue(): Int { + return (plantable?.value ?: 0) + currentGrowthStage + 12 + } + + private fun getFruitTreeDeathValue(): Int { + return (plantable?.value ?: 0) + currentGrowthStage + 18 + } + + private fun getBelladonnaDiseaseValue(): Int { + return (plantable?.value ?: 0) + currentGrowthStage + 4 + } + + private fun getBelladonnaDeathValue(): Int { + return (plantable?.value ?: 0) + currentGrowthStage + 7 + } + + private fun getCactusDiseaseValue(): Int { + return (plantable?.value ?: 0) + currentGrowthStage + 10 + } + + private fun getCactusDeathValue(): Int { + return (plantable?.value ?: 0) + currentGrowthStage + 16 + } + + private fun getHerbDiseaseValue(): Int { + return if (plantable?.value ?: -1 <= 103) { + 128 + (((plantable?.ordinal ?: 0) - Plantable.GUAM_SEED.ordinal) * 3) + currentGrowthStage - 1 + } else if (plantable == Plantable.SPIRIT_WEED_SEED) { + 211 + currentGrowthStage - 1 + } else { + 198 + currentGrowthStage -1 + } + } + + private fun getHerbDeathValue(): Int { + return if(plantable == Plantable.GOUT_TUBER){ + 201 + currentGrowthStage - 1 + } else 170 + currentGrowthStage - 1 + } + + private fun grow(){ + if((isWeedy() || isEmptyAndWeeded()) && getCurrentState() > 0) { + nextGrowth = System.currentTimeMillis() + 60000 + setCurrentState(getCurrentState() - 1) + currentGrowthStage-- + return + } + + if(isDiseased){ + isDead = true + return + } + + // This is so a cheat can force disease + diseaseMod = if (diseaseMod < 0) -128 else when(compost){ + CompostType.NONE -> 0 + CompostType.COMPOST -> 8 + CompostType.SUPERCOMPOST -> 13 + } + + if(patch != FarmingPatch.TROLL_STRONGHOLD_HERB && RandomFunction.random(128) <= (17 - diseaseMod) && !isWatered && !isGrown() && !protectionPaid && !isFlowerProtected() && patch.type != PatchType.EVIL_TURNIP_PATCH && currentGrowthStage != 0){ + isDiseased = true + // If we manually set disease mod reset it back to 0 so that crops can naturally grow after being treated/accidentally attempted to disease when they cannot be + if (diseaseMod < 0) diseaseMod = 0 + return + } + + if((patch.type == PatchType.FRUIT_TREE_PATCH || patch.type == PatchType.TREE_PATCH || patch.type == PatchType.BUSH_PATCH || patch.type == PatchType.CACTUS_PATCH) && plantable != null && plantable?.stages == currentGrowthStage + 1){ + isCheckHealth = true + } + + if((patch.type == PatchType.FRUIT_TREE_PATCH || patch.type == PatchType.BUSH_PATCH || patch.type == PatchType.CACTUS_PATCH) && plantable?.stages == currentGrowthStage){ + if((patch.type == PatchType.BUSH_PATCH && getFruitOrBerryCount() < 4) || (patch.type == PatchType.FRUIT_TREE_PATCH && getFruitOrBerryCount() < 6) || (patch.type == PatchType.CACTUS_PATCH && getFruitOrBerryCount() < 3)){ + setCurrentState(getCurrentState() + 1) + } + } + if(patch.type == PatchType.TREE_PATCH) { + // Willow branches + if(harvestAmt < 6) { + harvestAmt++ + } + } + + if(plantable?.stages ?: 0 > currentGrowthStage && !isGrown()){ + currentGrowthStage++ + setCurrentState(getCurrentState() + 1) + isWatered = false + } + + regrowIfTreeStump() + } + + fun regrowIfTreeStump() { + if(patch.type == PatchType.TREE_PATCH && plantable != null) { + // plantable.value + plantable.stages is the check-health stage, so +1 is the choppable tree, and +2 is the stump + if(getCurrentState() == plantable!!.value + plantable!!.stages + 2) { + setCurrentState(getCurrentState() - 1) + isWatered = false + } + } + } + + fun update(){ + grow() + updateBit() + } + + fun plant(plantable: Plantable){ + nextGrowth = System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(plantable.applicablePatch.stageGrowthTime.toLong()) + this.plantable = plantable + isDead = false + isDiseased = false + currentGrowthStage = 0 + setCurrentState(plantable.value) + } + + fun clear(){ + isCheckHealth = false + isDiseased = false + isDead = false + plantable = null + setVarbit(player, patch.varbit, 0) + nextGrowth = 0L + currentGrowthStage = 3 + setCurrentState(3) + compost = CompostType.NONE + protectionPaid = false + } + + fun getFruitOrBerryCount() : Int { + plantable ?: return 0 + return getCurrentState() - plantable!!.value - plantable!!.stages + } + + fun getStageGrowthMinutes() : Int { + var minutes = patch.type.stageGrowthTime + if(patch.type == PatchType.FRUIT_TREE_PATCH && isGrown()) { + // Fruit trees take 160 minutes per stage to grow, but + // restocking their fruit should take 40 minutes per fruit + minutes = 40 + } + return minutes + } + + fun isFlowerProtected(): Boolean{ + if(patch.type != PatchType.ALLOTMENT) return false + + val fpatch = when(patch){ + FarmingPatch.S_FALADOR_ALLOTMENT_SE,FarmingPatch.S_FALADOR_ALLOTMENT_NW -> FarmingPatch.S_FALADOR_FLOWER_C + FarmingPatch.ARDOUGNE_ALLOTMENT_S,FarmingPatch.ARDOUGNE_ALLOTMENT_N -> FarmingPatch.ARDOUGNE_FLOWER_C + FarmingPatch.CATHERBY_ALLOTMENT_S,FarmingPatch.CATHERBY_ALLOTMENT_N -> FarmingPatch.CATHERBY_FLOWER_C + FarmingPatch.PORT_PHAS_ALLOTMENT_SE,FarmingPatch.PORT_PHAS_ALLOTMENT_NW -> FarmingPatch.PORT_PHAS_FLOWER_C + else -> return false + }.getPatchFor(player, false) + + return (fpatch.plantable != null && + (fpatch.plantable == plantable?.protectionFlower || fpatch.plantable == Plantable.forItemID(Items.WHITE_LILY_SEED_14589)) + && fpatch.isGrown()) + } +} diff --git a/Server/src/main/content/global/skill/farming/PatchRaker.kt b/Server/src/main/content/global/skill/farming/PatchRaker.kt new file mode 100644 index 0000000..10af954 --- /dev/null +++ b/Server/src/main/content/global/skill/farming/PatchRaker.kt @@ -0,0 +1,48 @@ +package content.global.skill.farming + +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.system.task.Pulse +import org.rs09.consts.Items +import org.rs09.consts.Sounds + +object PatchRaker { + val RAKE_ANIM = getAnimation(2273) + + @JvmStatic + fun rake(player: Player, patch: FarmingPatch) { + val p = patch.getPatchFor(player) + val patchName = p.patch.type.displayName() + var firstRake = true + if (!p.isWeedy()) { + sendMessage(player, "This $patchName doesn't need weeding right now.") + return + } + submitIndividualPulse(player, object : Pulse() { + override fun pulse(): Boolean { + var patchStage = patch.getPatchFor(player).getCurrentState() + if (firstRake || patchStage < 2) { + // don't play the animation when on patchStage 2 as it has already + // played three times at this point and the patch will be weed-free + // after the third play + animate(player, RAKE_ANIM) + playAudio(player, Sounds.FARMING_RAKING_2442) + firstRake = false + } + if (delay < 5) { + delay = 5 + } else { + patch.getPatchFor(player).currentGrowthStage++ + patch.getPatchFor(player).setCurrentState(++patchStage) + addItem(player, Items.WEEDS_6055) + rewardXP(player, Skills.FARMING, 4.0) + } + if (patchStage >= 3) { + resetAnimator(player) + } + return patchStage >= 3 + } + }) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/farming/PatchType.kt b/Server/src/main/content/global/skill/farming/PatchType.kt new file mode 100644 index 0000000..0cbe401 --- /dev/null +++ b/Server/src/main/content/global/skill/farming/PatchType.kt @@ -0,0 +1,21 @@ +package content.global.skill.farming + +enum class PatchType(val stageGrowthTime: Int) { + ALLOTMENT(10), + HOPS_PATCH(10), + TREE_PATCH(40), + FRUIT_TREE_PATCH(160), + BUSH_PATCH(20), + FLOWER_PATCH(5), + HERB_PATCH(20), + SPIRIT_TREE_PATCH(295), + MUSHROOM_PATCH(30), + BELLADONNA_PATCH(80), + CACTUS_PATCH(60), + EVIL_TURNIP_PATCH(5); + + /** + * Returns the display name of this PatchType. + */ + fun displayName(): String = name.lowercase().replace("_", " ") +} diff --git a/Server/src/main/content/global/skill/farming/Plantable.kt b/Server/src/main/content/global/skill/farming/Plantable.kt new file mode 100644 index 0000000..83c016c --- /dev/null +++ b/Server/src/main/content/global/skill/farming/Plantable.kt @@ -0,0 +1,102 @@ +package content.global.skill.farming + +import core.game.node.item.Item +import org.rs09.consts.Items + +enum class Plantable(val itemID: Int, val displayName: String, val value: Int, val stages: Int, val plantingXP: Double, val harvestXP: Double, val checkHealthXP: Double, val requiredLevel: Int, val applicablePatch: PatchType, val harvestItem: Int, val protectionItem: Item? = null, val protectionFlower: Plantable? = null) { + + // Flowers + MARIGOLD_SEED(Items.MARIGOLD_SEED_5096,"marigold seed",8,4,8.5,47.0,0.0,2,PatchType.FLOWER_PATCH,Items.MARIGOLDS_6010), + ROSEMARY_SEED(Items.ROSEMARY_SEED_5097,"rosemary seed",13,4,12.0,66.5,0.0,11,PatchType.FLOWER_PATCH, Items.ROSEMARY_6014), + NASTURTIUM_SEED(Items.NASTURTIUM_SEED_5098,"nasturtium seed",18,4,19.5,111.0,0.0,24,PatchType.FLOWER_PATCH,Items.NASTURTIUMS_6012), + WOAD_SEED(Items.WOAD_SEED_5099,"woad seed",23,4,20.5,115.5,0.0,25,PatchType.FLOWER_PATCH,Items.WOAD_LEAF_1793), + LIMPWURT_SEED(Items.LIMPWURT_SEED_5100,"limpwurt seed",28,4,21.5,120.0,0.0,26,PatchType.FLOWER_PATCH,Items.LIMPWURT_ROOT_225), + WHITE_LILY_SEED(Items.WHITE_LILY_SEED_14589,"white lily seed",37,4,42.0,250.0,0.0,52,PatchType.FLOWER_PATCH,Items.WHITE_LILY_14583), + + // Flower (technically) + SCARECROW(Items.SCARECROW_6059,"scarecrow",33,3,0.0,0.0,0.0,23,PatchType.FLOWER_PATCH,Items.SCARECROW_6059), + + // Allotments + POTATO_SEED(Items.POTATO_SEED_5318, "potato seed", 6, 4, 8.0, 9.0, 0.0, 1, PatchType.ALLOTMENT, Items.POTATO_1942,Item(Items.COMPOST_6032,2),MARIGOLD_SEED), + ONION_SEED(Items.ONION_SEED_5319, "onion seed", 13, 4, 9.5, 10.5,0.0, 5, PatchType.ALLOTMENT,Items.ONION_1957,Item(Items.POTATOES10_5438),MARIGOLD_SEED), + CABBAGE_SEED(Items.CABBAGE_SEED_5324, "cabbage seed", 20, 4, 10.0, 11.5, 0.0,7, PatchType.ALLOTMENT,Items.CABBAGE_1965,Item(Items.ONIONS10_5458),ROSEMARY_SEED), + TOMATO_SEED(Items.TOMATO_SEED_5322,"tomato seed",27,4,12.5,14.0,0.0,12,PatchType.ALLOTMENT,Items.TOMATO_1982,Item(Items.CABBAGES10_5478,2),MARIGOLD_SEED), + SWEETCORN_SEED(Items.SWEETCORN_SEED_5320,"sweetcorn seed",34,6,17.0,19.0,0.0,20,PatchType.ALLOTMENT,Items.SWEETCORN_5986,Item(Items.JUTE_FIBRE_5931,10),SCARECROW), + STRAWBERRY_SEED(Items.STRAWBERRY_SEED_5323,"strawberry seed",43,6,26.0,29.0,0.0,31,PatchType.ALLOTMENT,Items.STRAWBERRY_5504,Item(Items.APPLES5_5386)), + WATERMELON_SEED(Items.WATERMELON_SEED_5321,"watermelon seed",52,8,48.5,54.5,0.0,47,PatchType.ALLOTMENT,Items.WATERMELON_5982,Item(Items.CURRY_LEAF_5970,10),NASTURTIUM_SEED), + + // Hops + BARLEY_SEED(Items.BARLEY_SEED_5305,"barley seed",49,4,8.5,9.5,0.0,3,PatchType.HOPS_PATCH,Items.BARLEY_6006,Item(Items.COMPOST_6032,3)), + HAMMERSTONE_SEED(Items.HAMMERSTONE_SEED_5307,"Hammerstone hop seed",4,4,9.0,10.0,0.0,4,PatchType.HOPS_PATCH,Items.HAMMERSTONE_HOPS_5994,Item(Items.MARIGOLDS_6010)), + ASGARNIAN_SEED(Items.ASGARNIAN_SEED_5308,"Asgarnian hop seed",11,5,10.9,12.0,0.0,8,PatchType.HOPS_PATCH,Items.ASGARNIAN_HOPS_5996,Item(Items.ONIONS10_5458)), + JUTE_SEED(Items.JUTE_SEED_5306,"jute plant seed",56,5,13.0,14.5,0.0,13,PatchType.HOPS_PATCH,Items.JUTE_FIBRE_5931,Item(Items.BARLEY_MALT_6008,6)), + YANILLIAN_SEED(Items.YANILLIAN_SEED_5309,"Yanillian hop seed",19,6,14.5,16.0,0.0,16,PatchType.HOPS_PATCH,Items.YANILLIAN_HOPS_5998,Item(Items.TOMATOES5_5968)), + KRANDORIAN_SEED(Items.KRANDORIAN_SEED_5310,"Krandorian hop seed",28,7,17.5,19.5,0.0,21,PatchType.HOPS_PATCH,Items.KRANDORIAN_HOPS_6000,Item(Items.CABBAGES10_5478,3)), + WILDBLOOD_SEED(Items.WILDBLOOD_SEED_5311,"Wildblood hop seed",38,8,23.0,26.0,0.0,28,PatchType.HOPS_PATCH,Items.WILDBLOOD_HOPS_6002,Item(Items.NASTURTIUMS_6012)), + + // Trees + OAK_SAPLING(Items.OAK_SAPLING_5370,"oak sapling",8,4,14.0,0.0,467.3,15,PatchType.TREE_PATCH,Items.OAK_ROOTS_6043,Item(Items.TOMATOES5_5968)), + WILLOW_SAPLING(Items.WILLOW_SAPLING_5371,"willow sapling",15,6,25.0,0.0,1456.5,30,PatchType.TREE_PATCH,Items.WILLOW_ROOTS_6045,Item(Items.APPLES5_5386)), + MAPLE_SAPLING(Items.MAPLE_SAPLING_5372,"maple sapling",24,8,45.0,0.0,3403.4,45,PatchType.TREE_PATCH,Items.MAPLE_ROOTS_6047,Item(Items.ORANGES5_5396)), + YEW_SAPLING(Items.YEW_SAPLING_5373,"yew sapling",35,10,81.0,0.0,7069.9,60,PatchType.TREE_PATCH,Items.YEW_ROOTS_6049,Item(Items.CACTUS_SPINE_6016,10)), + MAGIC_SAPLING(Items.MAGIC_SAPLING_5374,"magic Tree sapling",48,12,145.5,0.0,13768.3,75,PatchType.TREE_PATCH,Items.MAGIC_ROOTS_6051,Item(Items.COCONUT_5974,25)), + + // Fruit Trees + APPLE_SAPLING(Items.APPLE_SAPLING_5496,"apple tree sapling",8,6,22.0,8.5,1199.5,27,PatchType.FRUIT_TREE_PATCH,Items.COOKING_APPLE_1955,Item(Items.SWEETCORN_5986,9)), + BANANA_SAPLING(Items.BANANA_SAPLING_5497,"banana tree sapling",35,6,28.0,10.5,1750.5,33,PatchType.FRUIT_TREE_PATCH,Items.BANANA_1963,Item(Items.APPLES5_5386,4)), + ORANGE_SAPLING(Items.ORANGE_SAPLING_5498,"orange tree sapling",72,6,35.5,13.5,2470.2,39,PatchType.FRUIT_TREE_PATCH,Items.ORANGE_2108,Item(Items.STRAWBERRIES5_5406,3)), + CURRY_SAPLING(Items.CURRY_SAPLING_5499,"curry tree sapling",99,6,40.0,15.0,2906.9,42,PatchType.FRUIT_TREE_PATCH,Items.CURRY_LEAF_5970,Item(Items.BANANAS5_5416,5)), + PINEAPPLE_SAPLING(Items.PINEAPPLE_SAPLING_5500,"pineapple plant",136,6,57.0,21.5,4605.7,51,PatchType.FRUIT_TREE_PATCH,Items.PINEAPPLE_2114,Item(Items.WATERMELON_5982,10)), + PAPAYA_SAPLING(Items.PAPAYA_SAPLING_5501,"papaya tree sapling",163,6,72.0,27.0,6146.4,57,PatchType.FRUIT_TREE_PATCH,Items.PAPAYA_FRUIT_5972,Item(Items.PINEAPPLE_2114,10)), + PALM_SAPLING(Items.PALM_SAPLING_5502,"palm tree sapling",200,6,110.5,41.5,10150.1,68,PatchType.FRUIT_TREE_PATCH,Items.COCONUT_5974,Item(Items.PAPAYA_FRUIT_5972,15)), + + // Bushes + REDBERRY_SEED(Items.REDBERRY_SEED_5101,"redberry bush seed",5,5,11.5,4.5,64.0,10,PatchType.BUSH_PATCH,Items.REDBERRIES_1951,Item(Items.CABBAGES10_5478,4)), + CADAVABERRY_SEED(Items.CADAVABERRY_SEED_5102,"cadavaberry bush seed",15,6,18.0,7.0,102.5,22,PatchType.BUSH_PATCH,Items.CADAVA_BERRIES_753,Item(Items.TOMATOES5_5968,3)), + DWELLBERRY_SEED(Items.DWELLBERRY_SEED_5103,"dwellberry bush seed",26,27,31.5,12.0,177.5,36,PatchType.BUSH_PATCH,Items.DWELLBERRIES_2126,Item(Items.STRAWBERRIES5_5406,3)), + JANGERBERRY_SEED(Items.JANGERBERRY_SEED_5104,"jangerberry bush seed",38,8,50.5,19.0,284.5,48,PatchType.BUSH_PATCH,Items.JANGERBERRIES_247,Item(Items.WATERMELON_5982,6)), + WHITEBERRY_SEED(Items.WHITEBERRY_SEED_5105,"whiteberry bush seed",51,8,78.0,29.0,437.5,59,PatchType.BUSH_PATCH,Items.WHITE_BERRIES_239,null), + POISON_IVY_SEED(Items.POISON_IVY_SEED_5106,"poison ivy bush seed",197,8,120.0,45.0,675.0,70,PatchType.BUSH_PATCH,Items.POISON_IVY_BERRIES_6018,null), + + // Herbs + GUAM_SEED(Items.GUAM_SEED_5291,"guam seed",4,4,11.0,12.5,0.0,9,PatchType.HERB_PATCH,Items.GRIMY_GUAM_199), + MARRENTILL_SEED(Items.MARRENTILL_SEED_5292,"marrentill seed",11,4,13.5,15.0,0.0,14,PatchType.HERB_PATCH,Items.GRIMY_MARRENTILL_201), + TARROMIN_SEED(Items.TARROMIN_SEED_5293,"tarromin seed",18,4,16.0,18.0,0.0,19,PatchType.HERB_PATCH,Items.GRIMY_TARROMIN_203), + HARRALANDER_SEED(Items.HARRALANDER_SEED_5294,"harralander seed",25,4,21.5,24.0,0.0,26,PatchType.HERB_PATCH,Items.GRIMY_HARRALANDER_205), + RANARR_SEED(Items.RANARR_SEED_5295,"ranarr seed",32,4,27.0,30.5,0.0,32,PatchType.HERB_PATCH,Items.GRIMY_RANARR_207), + AVANTOE_SEED(Items.AVANTOE_SEED_5298,"avantoe seed",39,4,54.5,61.5,0.0,50,PatchType.HERB_PATCH,Items.GRIMY_AVANTOE_211), + TOADFLAX_SEED(Items.TOADFLAX_SEED_5296,"toadflax seed",46,4,34.0,38.5,0.0,38,PatchType.HERB_PATCH,Items.GRIMY_TOADFLAX_3049), + IRIT_SEED(Items.IRIT_SEED_5297,"irit seed",53,4,43.0,48.5,0.0,44,PatchType.HERB_PATCH,Items.GRIMY_IRIT_209), + KWUARM_SEED(Items.KWUARM_SEED_5299,"kwuarm seed",68,4,69.0,78.0,0.0,56,PatchType.HERB_PATCH,Items.GRIMY_KWUARM_213), + SNAPDRAGON_SEED(Items.SNAPDRAGON_SEED_5300,"snapdragon seed",75,4,87.5,98.5,0.0,62,PatchType.HERB_PATCH,Items.GRIMY_SNAPDRAGON_3051), + CADANTINE_SEED(Items.CADANTINE_SEED_5301,"cadantine seed",82,4,106.5,120.0,0.0,67,PatchType.HERB_PATCH,Items.GRIMY_CADANTINE_215), + LANTADYME_SEED(Items.LANTADYME_SEED_5302,"lantadyme seed",89,4,134.5,151.5,0.0,73,PatchType.HERB_PATCH,Items.GRIMY_LANTADYME_2485), + DWARF_WEED_SEED(Items.DWARF_WEED_SEED_5303,"dwarf weed seed",96,4,170.5,192.0,0.0,79,PatchType.HERB_PATCH,Items.GRIMY_DWARF_WEED_217), + TORSTOL_SEED(Items.TORSTOL_SEED_5304,"torstol seed",103,4,199.5,224.5,0.0,85,PatchType.HERB_PATCH,Items.GRIMY_TORSTOL_219), + GOUT_TUBER(Items.GOUT_TUBER_6311,"gout tuber",192,4,105.0,45.0,0.0,29,PatchType.HERB_PATCH,Items.GOUTWEED_3261), + SPIRIT_WEED_SEED(Items.SPIRIT_WEED_SEED_12176,"spirit weed seed", 204, 4, 32.0, 36.0, 0.0, 36, PatchType.HERB_PATCH, Items.GRIMY_SPIRIT_WEED_12174), + + // Special + BELLADONNA_SEED(Items.BELLADONNA_SEED_5281, "belladonna seed", 4, 4, 91.0, 128.0, 0.0, 63, PatchType.BELLADONNA_PATCH, Items.CAVE_NIGHTSHADE_2398), + MUSHROOM_SPORE(Items.MUSHROOM_SPORE_5282, "mushroom spore", 6, 7, 61.5, 57.7, 0.0, 53, PatchType.MUSHROOM_PATCH, Items.MUSHROOM_6004), + CACTUS_SEED(Items.CACTUS_SEED_5280, "cactus seed", 8, 7, 66.5, 25.0, 374.0, 55, PatchType.CACTUS_PATCH, Items.CACTUS_SPINE_6016), + EVIL_TURNIP_SEED(Items.EVIL_TURNIP_SEED_12148, "evil turnip seed", 4, 1, 41.0, 46.0, 0.0, 42, PatchType.EVIL_TURNIP_PATCH, Items.EVIL_TURNIP_12134) + ; + + constructor(itemID: Int, displayName: String, value: Int, stages: Int, plantingXP: Double, harvestXP: Double, checkHealthXP: Double, requiredLevel: Int, applicablePatch: PatchType, harvestItem: Int, protectionFlower: Plantable) + : this(itemID,displayName,value,stages,plantingXP,harvestXP,checkHealthXP,requiredLevel,applicablePatch,harvestItem,null,protectionFlower) + companion object { + @JvmField + val plantables = values().map { it.itemID to it }.toMap() + + @JvmStatic + fun forItemID(id: Int): Plantable?{ + return plantables[id] + } + + @JvmStatic + fun forItem(item: Item): Plantable?{ + return forItemID(item.id) + } + } +} diff --git a/Server/src/main/content/global/skill/farming/SackBasketOptionHandler.kt b/Server/src/main/content/global/skill/farming/SackBasketOptionHandler.kt new file mode 100644 index 0000000..ce7a401 --- /dev/null +++ b/Server/src/main/content/global/skill/farming/SackBasketOptionHandler.kt @@ -0,0 +1,140 @@ +package content.global.skill.farming + +import core.cache.def.impl.ItemDefinition +import core.game.interaction.OptionHandler +import core.game.node.Node +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import core.plugin.Plugin +import org.rs09.consts.Items + +@Initializable +class SackBasketOptionHandler : OptionHandler() { + + private companion object { + val fruit = arrayOf(Items.ORANGE_2108,Items.COOKING_APPLE_1955,Items.BANANA_1963,Items.STRAWBERRY_5504,Items.TOMATO_1982) + val produce = arrayOf(Items.POTATO_1942,Items.ONION_1957,Items.CABBAGE_1965) + } + + override fun newInstance(arg: Any?): Plugin { + BasketsAndSacks.values().forEach { it.containers.forEach { id -> + val def = ItemDefinition.forId(id) + def.handlers["option:fill"] = this + def.handlers["option:empty"] = this + def.handlers["option:remove-one"] = this + } } + var def = ItemDefinition.forId(Items.EMPTY_SACK_5418) + def.handlers["option:fill"] = this + def = ItemDefinition.forId(Items.BASKET_5376) + def.handlers["option:fill"] = this + return this + } + + override fun handle(player: Player?, node: Node?, option: String?): Boolean { + player ?: return false + node ?: return false + + when(option){ + "fill" -> tryFill(player,node.asItem()) + "empty" -> tryEmpty(player,node.asItem()) + "remove-one" -> tryTakeOne(player,node.asItem()) + } + return true + } + + private fun tryFill(player: Player?, item: Item){ + player ?: return + val containerID = item.id + val appropriateProduce = getAppropriateProduce(player,containerID) ?: return + val container = BasketsAndSacks.forId(containerID) ?: BasketsAndSacks.forId(appropriateProduce.id) ?: return + val isLast = container.checkIsLast(containerID) + val specific = container.checkWhich(containerID) + val max = container.containers.size - 1 + + if(isLast){ + player.sendMessage("This is already full.") + return + } + + if(specific + appropriateProduce.amount > max){ + appropriateProduce.amount = (max - specific) + } + + if(player.inventory.remove(item) && player.inventory.remove(appropriateProduce)) + player.inventory.add(Item(container.containers[specific + appropriateProduce.amount])) + } + + private fun tryEmpty(player: Player?, item: Item){ + val container = BasketsAndSacks.forId(item.id) + if(container == null) return + player ?: return + + val emptyItem = if(produce.contains(container.produceID)) Items.EMPTY_SACK_5418 else Items.BASKET_5376 + val returnItem = Item(container.produceID,container.checkWhich(item.id) + 1) + + if(!player.inventory.hasSpaceFor(returnItem)){ + player.sendMessage("You don't have enough inventory space to do this.") + return + } + + if(player.inventory.remove(item)){ + player.inventory.add(Item(emptyItem)) + player.inventory.add(returnItem) + } + } + + private fun tryTakeOne(player: Player?,item: Item){ + val container = BasketsAndSacks.forId(item.id) + if(container == null) return + player ?: return + + val emptyItem = if(produce.contains(container.produceID)) Items.EMPTY_SACK_5418 else Items.BASKET_5376 + val isLast = container.checkIsFirst(item.id) + val withdrawnItem = Item(container.produceID) + + if(!player.inventory.hasSpaceFor(withdrawnItem)){ + player.sendMessage("You don't have enough inventory space to do this.") + return + } + + if(player.inventory.remove(item)){ + if(isLast){ + player.inventory.add(Item(emptyItem)) + } else { + val it = Item(container.containers[container.checkWhich(item.id) - 1]) + player.inventory.add(it) + } + player.inventory.add(withdrawnItem) + } + } + + private fun getAppropriateProduce(player: Player?, containerID: Int): Item?{ + player ?: return null + val container = BasketsAndSacks.forId(containerID) + val produce = if(container == null){ + var selected = 0 + if(containerID == Items.EMPTY_SACK_5418) { + for (i in (produce)) { + if (player.inventory.contains(i, 1)) { + selected = i + break + } + } + selected + } else { + for (i in (fruit)) { + if (player.inventory.contains(i, 1)) { + selected = i + break + } + } + selected + } + } else { + container.produceID + } + + return if(produce == 0) null else Item(produce,player.inventory.getAmount(produce)) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/farming/SeedOnPlantPot.kt b/Server/src/main/content/global/skill/farming/SeedOnPlantPot.kt new file mode 100644 index 0000000..39c8348 --- /dev/null +++ b/Server/src/main/content/global/skill/farming/SeedOnPlantPot.kt @@ -0,0 +1,110 @@ +package content.global.skill.farming + +import core.api.* +import core.game.node.Node +import org.rs09.consts.Items +import core.game.interaction.IntType +import core.game.node.entity.player.Player +import content.global.skill.farming.timers.* +import core.game.interaction.InteractionListener +import core.tools.prependArticle + +class SeedlingListener : InteractionListener { + override fun defineListeners() { + onUseWith(IntType.ITEM, TREE_SEEDS, Items.PLANT_POT_5354, handler = ::addSeedToPot) + onUseWith(IntType.ITEM, TREE_SEEDLINGS, *WATERING_CANS, handler = ::waterSeedling) + } + + fun addSeedToPot(player: Player, used: Node, with: Node) : Boolean { + val seed = used.asItem() ?: return false + val pot = with.asItem() ?: return false + + if (!inInventory(player, Items.GARDENING_TROWEL_5325)) { + sendDialogue(player, "You need a gardening trowel on you to do this.") + return false + } + + val seedling = getSeedling(seed.id) + if (seedling == -1) return false + if (!removeItem(player, seed.id) || !removeItem(player, pot)) return true + addItem(player, seedling) + sendMessage(player, "You sow ${prependArticle(seed.name.lowercase())} in the plantpot.") + sendMessage(player, "It needs watering before it will grow.") + return true + } + + fun waterSeedling(player: Player, used: Node, with: Node) : Boolean { + val seedling = used.asItem() ?: return false + val can = with.asItem() ?: return false + + val nextCan = can.id.getNext() + val wateredSeedling = if (seedling.id > 5400) seedling.id + 8 else seedling.id + 6 + + if (!removeItem(player, can) || !removeItem(player, seedling)) return false + addItem(player, wateredSeedling) + addItem(player, nextCan) + + var seedlings = getOrStartTimer (player) + seedlings.addSeedling(wateredSeedling) + return true + } + + private fun Int.getNext(): Int { + val index = WATERING_CANS.indexOf(this) + if (index == -1) return Items.WATERING_CAN_5331 + return if (index != WATERING_CANS.size -1) WATERING_CANS[index + 1] else Items.WATERING_CAN_5331 + } + + fun getSeedling(id: Int) : Int { + return when (id) { + Items.ACORN_5312 -> Items.OAK_SEEDLING_5358 + Items.WILLOW_SEED_5313 -> Items.WILLOW_SEEDLING_5359 + Items.MAPLE_SEED_5314 -> Items.MAPLE_SEEDLING_5360 + Items.YEW_SEED_5315 -> Items.YEW_SEEDLING_5361 + Items.MAGIC_SEED_5316 -> Items.MAGIC_SEEDLING_5362 + Items.APPLE_TREE_SEED_5283 -> Items.APPLE_SEEDLING_5480 + Items.BANANA_TREE_SEED_5284 -> Items.BANANA_SEEDLING_5481 + Items.ORANGE_TREE_SEED_5285 -> Items.ORANGE_SEEDLING_5482 + Items.CURRY_TREE_SEED_5286 -> Items.CURRY_SEEDLING_5483 + Items.PINEAPPLE_SEED_5287 -> Items.PINEAPPLE_SEEDLING_5484 + Items.PAPAYA_TREE_SEED_5288 -> Items.PAPAYA_SEEDLING_5485 + Items.PALM_TREE_SEED_5289 -> Items.PALM_SEEDLING_5486 + Items.SPIRIT_SEED_5317 -> Items.SPIRIT_SEEDLING_5363 + else -> -1 + } + } + + val TREE_SEEDS = intArrayOf( + Items.ACORN_5312, + Items.WILLOW_SEED_5313, + Items.MAPLE_SEED_5314, + Items.YEW_SEED_5315, + Items.MAGIC_SEED_5316, + Items.APPLE_TREE_SEED_5283, + Items.BANANA_TREE_SEED_5284, + Items.ORANGE_TREE_SEED_5285, + Items.CURRY_TREE_SEED_5286, + Items.PINEAPPLE_SEED_5287, + Items.PAPAYA_TREE_SEED_5288, + Items.PALM_TREE_SEED_5289, + Items.SPIRIT_SEED_5317 + ) + + val TREE_SEEDLINGS = intArrayOf( + Items.OAK_SEEDLING_5358, + Items.WILLOW_SEEDLING_5359, + Items.MAPLE_SEEDLING_5360, + Items.YEW_SEEDLING_5361, + Items.MAGIC_SEEDLING_5362, + Items.APPLE_SEEDLING_5480, + Items.BANANA_SEEDLING_5481, + Items.ORANGE_SEEDLING_5482, + Items.CURRY_SEEDLING_5483, + Items.PINEAPPLE_SEEDLING_5484, + Items.PAPAYA_SEEDLING_5485, + Items.PALM_SEEDLING_5486, + Items.SPIRIT_SEEDLING_5363 + ) + + private val WATERING_CANS = intArrayOf(Items.WATERING_CAN8_5340,Items.WATERING_CAN7_5339,Items.WATERING_CAN6_5338,Items.WATERING_CAN5_5337,Items.WATERING_CAN4_5336,Items.WATERING_CAN3_5335,Items.WATERING_CAN2_5334,Items.WATERING_CAN1_5333) +} diff --git a/Server/src/main/content/global/skill/farming/Seedling.kt b/Server/src/main/content/global/skill/farming/Seedling.kt new file mode 100644 index 0000000..a2e8f7a --- /dev/null +++ b/Server/src/main/content/global/skill/farming/Seedling.kt @@ -0,0 +1,5 @@ +package content.global.skill.farming + +class Seedling(val id: Int, val TTL: Long, val sapling: Int) { + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/farming/ToolLeprechaunDialogue.kt b/Server/src/main/content/global/skill/farming/ToolLeprechaunDialogue.kt new file mode 100644 index 0000000..50ec966 --- /dev/null +++ b/Server/src/main/content/global/skill/farming/ToolLeprechaunDialogue.kt @@ -0,0 +1,187 @@ +package content.global.skill.farming + +import content.minigame.vinesweeper.Vinesweeper +import core.api.openInterface +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.Components +import org.rs09.consts.NPCs + +/** + * Tool Leprechaun dialogue. + * @author ovenbread + * + * This is really hard to find anything beyond the first dialogue. + * https://www.youtube.com/watch?v=2wgWB9U5Ju8 0L25 May 19, 2010 + * https://www.youtube.com/watch?v=gqend8EibPs: 0:02 Nov 28, 2010 + * https://www.youtube.com/watch?v=6cnsQsVGzXI: 4:05 Feb 14, 2012 - The Leprechaun in Troll Stronghold! + * + * Note: + * Ultracompost was introduced in 2017(OSRS) 2018(RS3), so it is not included. + * Leprechaun Composting was only added in 2016, so it is also not included. + */ +@Initializable +class ToolLeprechaunDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage) { + START_DIALOGUE -> npc(FacialExpression.OLD_HAPPY, "Ah, 'tis a foine day to be sure! Can I help ye with tool", "storage, or a trip to Winkin's Farm, or what?").also { stage++ } + + 1 -> showTopics( + Topic(FacialExpression.NEUTRAL, "Yes, please.", 10), + Topic("What tools can you store?", 2, true), + Topic(FacialExpression.NEUTRAL, "No thanks, I'll keep hold of my stuff.", 20), + Topic("Can you take me to Winkin's Farm?", 30), + // "Other topics." -> Lost City quest where is Shamus. Evil Tree Reward collection in late 2009. + ) + 2 -> playerl(FacialExpression.THINKING, "What can you store?").also { stage++ } + 3 -> npcl(FacialExpression.OLD_HAPPY, "We'll hold onto yer rake, yer seed dibber, yer spade, yer secateurs, yer waterin' can and yer trowel - but mind it's not one of them fancy trowels only archaeologists use!").also { stage++ } + 4 -> npcl(FacialExpression.OLD_HAPPY, "We'll take a few buckets off yer hands too, and even yer compost and supercompost! There's room in our shed for plenty of compost, so bring it on.").also { stage++ } + 5 -> npcl(FacialExpression.OLD_HAPPY, "Also if ye hands us yer farming produce, we might be able to change it into banknotes.").also { stage++ } + 6 -> npcl(FacialExpression.OLD_HAPPY, "So... do ye want to be using the store?").also { stage++ } + 7 -> showTopics( + Topic(FacialExpression.NEUTRAL, "Yes, please.", 10), + Topic("What do you do with the tools you're storing?", 11, true), + Topic(FacialExpression.NEUTRAL, "No thanks, I'll keep hold of my stuff.", 20), + Topic("Can you take me to Winkin's Farm?", 30), + ) + 10 -> { + end() + openInterface(player, Components.FARMING_TOOLS_125) + } + 11 -> playerl(FacialExpression.THINKING, "What do you do with the tools you're storing? They can't possibly all fit in your pockets!").also { stage++ } + 12 -> npcl(FacialExpression.OLD_HAPPY, "We leprechauns have a shed where we keep 'em. It's a magic shed, so ye can get yer items back from any of us leprechauns whenever ye want. Saves ye havin' to carry loads of stuff around the country!").also { stage++ } + 13 -> npcl(FacialExpression.OLD_HAPPY, "So... do ye want to be using the store?").also { stage = 1 } + + 20 -> npcl(FacialExpression.OLD_NORMAL, "Ye must be dafter than ye look if ye likes luggin' yer tools everywhere ye goes!").also { + stage = END_DIALOGUE + } + 30 -> { + end() + Vinesweeper.Companion.VinesweeperTeleport.teleport(npc!!, player!!) + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return ToolLeprechaunDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.TOOL_LEPRECHAUN_3021) + } +} + +/** + * Note: + * This Leprechaun Larry is a special case where he does NOT transport you to Winkin's farm, but has a store. + */ +@Initializable +class ToolLeprechaunOnVacationDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage) { + START_DIALOGUE -> npc(FacialExpression.OLD_HAPPY, "Aye, top o' th' mornin' to ya!", "Are ye wantin' help with th' tool store?").also { + stage = 2 + } + 2 -> showTopics( + Topic(FacialExpression.NEUTRAL, "Yes please.", 10), + Topic(FacialExpression.THINKING, "Why are you sunbathing up a mountain?", 3), + Topic(FacialExpression.NEUTRAL, "No thanks, I'll keep hold of my stuff.", 20), + Topic("Would you like to trade?", 12), + ) + 3 -> npcl(FacialExpression.OLD_HAPPY, "We tool leprechauns work hard, that we do. An'nary a penny do we get in return. So ye cannae begrudge me mah holiday an' a wee drink or twelve!").also { stage++ } + 4 -> playerl(FacialExpression.THINKING, "Yes, very nice, but why are you sunbathing up a mountain? Surely a beach would be more appropriate?").also { stage++ } + 5 -> npcl(FacialExpression.OLD_HAPPY, "Ahh, but I likes th' ruggedy mountain, ye see. Also, I ha' a terrible allergy to sand.").also { stage++ } + 6 -> playerl(FacialExpression.NEUTRAL, "Fair enough, I suppose.").also { stage++ } + 7 -> npcl(FacialExpression.OLD_HAPPY, "So were ye wantin' help with th' tool store?").also { stage++ } + 8 -> showTopics( + Topic(FacialExpression.NEUTRAL, "Yes, please.", 10), + Topic(FacialExpression.NEUTRAL, "No thanks, I'll keep hold of my stuff.", 20), + ) + 10 -> { + end() + openInterface(player, Components.FARMING_TOOLS_125) + } + 12 -> npcl(FacialExpression.OLD_HAPPY, "Sure, have a look.").also { stage++ } + 13 -> end().also{ + npc.openShop(player) + } + 20 -> npcl(FacialExpression.OLD_NORMAL, "Ye must be dafter than ye look if ye likes luggin' yer tools everywhere ye goes!").also { + stage = END_DIALOGUE + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return ToolLeprechaunOnVacationDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.TOOL_LEPRECHAUN_4965) + } +} + +/** + * Note: + * Goth chatheads are unfortunately updated and have frozen FacialExpressions. Disabled talk-to for now. + */ +// @Initializable +class ToolLeprechaunGothDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage) { + START_DIALOGUE -> npc(FacialExpression.HAPPY, "Ah, 'tis a foine day to be sure! Can I help ye with tool", "storage, or a trip to Winkin's Farm, or what?").also { stage++ } + + 1 -> showTopics( + Topic(FacialExpression.NEUTRAL, "Yes, please.", 10), + Topic("What tools can you store?", 2, true), + Topic(FacialExpression.NEUTRAL, "No thanks, I'll keep hold of my stuff.", 20), + Topic("Can you take me to Winkin's Farm?", 30), + // "Other topics." -> Lost City quest where is Shamus. Evil Tree Reward collection in late 2009. + ) + 2 -> playerl(FacialExpression.THINKING, "What can you store?").also { stage++ } + 3 -> npcl(FacialExpression.HAPPY, "We'll hold onto yer rake, yer seed dibber, yer spade, yer secateurs, yer waterin' can and yer trowel - but mind it's not one of them fancy trowels only archaeologists use!").also { stage++ } + 4 -> npcl(FacialExpression.HAPPY, "We'll take a few buckets off yer hands too, and even yer compost and supercompost! There's room in our shed for plenty of compost, so bring it on.").also { stage++ } + 5 -> npcl(FacialExpression.HAPPY, "Also if ye hands us yer farming produce, we might be able to change it into banknotes.").also { stage++ } + 6 -> npcl(FacialExpression.HAPPY, "So... do ye want to be using the store?").also { stage++ } + 7 -> showTopics( + Topic(FacialExpression.NEUTRAL, "Yes, please.", 10), + Topic("What do you do with the tools you're storing?", 11, true), + Topic(FacialExpression.NEUTRAL, "No thanks, I'll keep hold of my stuff.", 20), + Topic("Can you take me to Winkin's Farm?", 30), + ) + 10 -> { + end() + openInterface(player, Components.FARMING_TOOLS_125) + } + 11 -> playerl(FacialExpression.THINKING, "What do you do with the tools you're storing? They can't possibly all fit in your pockets!").also { stage++ } + 12 -> npcl(FacialExpression.HAPPY, "We leprechauns have a shed where we keep 'em. It's a magic shed, so ye can get yer items back from any of us leprechauns whenever ye want. Saves ye havin' to carry loads of stuff around the country!").also { stage++ } + 13 -> npcl(FacialExpression.HAPPY, "So... do ye want to be using the store?").also { stage = 1 } + + 20 -> npcl(FacialExpression.NEUTRAL, "Ye must be dafter than ye look if ye likes luggin' yer tools everywhere ye goes!").also { + stage = END_DIALOGUE + } + 30 -> { + end() + Vinesweeper.Companion.VinesweeperTeleport.teleport(npc!!, player!!) + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return ToolLeprechaunDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.GOTH_LEPRECHAUN_8000) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/farming/ToolLeprechaunHandler.kt b/Server/src/main/content/global/skill/farming/ToolLeprechaunHandler.kt new file mode 100644 index 0000000..d233860 --- /dev/null +++ b/Server/src/main/content/global/skill/farming/ToolLeprechaunHandler.kt @@ -0,0 +1,37 @@ +package content.global.skill.farming + +import core.cache.def.impl.NPCDefinition +import core.game.component.Component +import core.game.dialogue.FacialExpression +import core.game.interaction.OptionHandler +import core.game.node.Node +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.plugin.Plugin +import org.rs09.consts.Components +import org.rs09.consts.NPCs +import content.minigame.vinesweeper.Vinesweeper + +val TL_IDS = arrayOf(NPCs.TOOL_LEPRECHAUN_3021,NPCs.GOTH_LEPRECHAUN_8000,NPCs.TOOL_LEPRECHAUN_4965,NPCs.TECLYN_2861) +@Initializable +class ToolLeprechaunHandler : OptionHandler() { + override fun newInstance(arg: Any?): Plugin { + for(id in TL_IDS){ + val def = NPCDefinition.forId(id) + def.handlers["option:exchange"] = this + def.handlers["option:teleport"] = this + } + return this + } + + override fun handle(player: Player?, node: Node?, option: String?): Boolean { + node ?: return false + when(option){ + "exchange" -> player?.interfaceManager?.open(Component(Components.FARMING_TOOLS_125)) + "teleport" -> Vinesweeper.Companion.VinesweeperTeleport.teleport(node!! as NPC, player!!) + } + return true + } + +} diff --git a/Server/src/main/content/global/skill/farming/ToolLeprechaunInterface.kt b/Server/src/main/content/global/skill/farming/ToolLeprechaunInterface.kt new file mode 100644 index 0000000..29e0d71 --- /dev/null +++ b/Server/src/main/content/global/skill/farming/ToolLeprechaunInterface.kt @@ -0,0 +1,351 @@ +package content.global.skill.farming + +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.item.Item +import org.rs09.consts.Components +import org.rs09.consts.Items +import core.game.interaction.InterfaceListener + +class ToolLeprechaunInterface : InterfaceListener { + private val FARMING_TOOLS = Components.FARMING_TOOLS_125 + private val TOOLS_SIDE = Components.FARMING_TOOLS_SIDE_126 + + override fun defineInterfaceListeners() { + + onOpen(FARMING_TOOLS) { player, component -> + openSingleTab(player, TOOLS_SIDE) + return@onOpen true + } + + onClose(FARMING_TOOLS) { player, _ -> + closeTabInterface(player) + return@onClose true + } + + on(FARMING_TOOLS) { player, _, opcode, buttonID, _, _ -> + when (buttonID) { + 33 -> doWithdrawal(player, Items.RAKE_5341, ::setHasRake, ::hasRake) + 34 -> doWithdrawal(player, Items.SEED_DIBBER_5343, ::setHasDibber, ::hasDibber) + 35 -> doWithdrawal(player, Items.SPADE_952, ::setHasSpade, ::hasSpade) + 36 -> { + val sec = if (hasMagicSecateurs(player)) Items.MAGIC_SECATEURS_7409 else Items.SECATEURS_5329 + doWithdrawal(player, sec, ::setHasSecateurs, ::hasSecateurs) + } + 37 -> { + if (!hasWateringCan(player)) { + sendMessage(player, "You haven't got a watering can stored in here!") + } else { + if (freeSlots(player) == 0) { + sendMessage(player, "You don't have enough space for that.") + } + if (addItem(player, getWateringCan(player))) setNoWateringCan(player) + } + } + 38 -> doWithdrawal(player, Items.GARDENING_TROWEL_5325, ::setHasGardeningTrowel, ::hasGardeningTrowel) + 39 -> doStackedWithdrawal(player, Items.BUCKET_1925, getAmount(opcode), ::updateBuckets, ::getNumBuckets) + 40 -> doStackedWithdrawal(player, Items.COMPOST_6032, getAmount(opcode), ::updateCompost, ::getNumCompost) + 41 -> doStackedWithdrawal(player, Items.SUPERCOMPOST_6034, getAmount(opcode), ::updateSuperCompost, ::getNumSuperCompost) + } + return@on true + } + + on(TOOLS_SIDE) { player, _, opcode, buttonID, _, _ -> + when (buttonID) { + 18 -> doDeposit(player, Items.RAKE_5341, ::setHasRake, ::hasRake) + 19 -> doDeposit(player, Items.SEED_DIBBER_5343, ::setHasDibber, ::hasDibber) + 20 -> doDeposit(player, Items.SPADE_952, ::setHasSpade, ::hasSpade) + 21 -> { + if (!inInventory(player, Items.SECATEURS_5329) && !inInventory(player, Items.MAGIC_SECATEURS_7409)) { + sendMessage(player, "You haven't got any secateurs to store.") + } else if (!hasSecateurs(player)) { + if (inInventory(player, Items.MAGIC_SECATEURS_7409)) { + removeItem(player, Items.MAGIC_SECATEURS_7409) + setHasSecateurs(player,true) + setHasMagicSecateurs(player,true) + } else { + removeItem(player, Items.SECATEURS_5329) + setHasSecateurs(player,true) + setHasMagicSecateurs(player,false) + } + } else { + sendMessage(player, "You cannot store more than one pair of secateurs in here.") + } + } + 22 -> { + val can = getHighestCan(player) + if (can == null) { + sendMessage(player, "You haven't got a watering can to store.") + } else if (!hasWateringCan(player)) { + removeItem(player, can) + setWateringCan(player,can) + } else { + sendMessage(player, "You cannot store more than one watering can in here.") + } + } + 23 -> doDeposit(player, Items.GARDENING_TROWEL_5325, ::setHasGardeningTrowel, ::hasGardeningTrowel) + 24 -> doStackedDeposit(player, Items.BUCKET_1925, getAmount(opcode), ::updateBuckets, ::getNumBuckets) + 25 -> doStackedDeposit(player, Items.COMPOST_6032, getAmount(opcode), ::updateCompost, ::getNumCompost) + 26 -> doStackedDeposit(player, Items.SUPERCOMPOST_6034, getAmount(opcode), ::updateSuperCompost, ::getNumSuperCompost) + } + return@on true + } + + } + + private fun doWithdrawal(player: Player?, item: Int, withdrawMethod: (Player?, Boolean) -> Unit, checkMethod: (Player?) -> Boolean) { + player ?: return + if (!checkMethod.invoke(player)) { + val determiner = if (getItemName(item).lowercase().endsWith("s")) "any" else "a" + sendMessage(player, "You haven't got $determiner ${getItemName(item).lowercase()} stored in here!") + } else { + if (!hasSpaceFor(player, Item(item))) { + sendMessage(player, "You don't have enough space for that.") + return + } + withdrawMethod.invoke(player, false) + addItem(player, item) + } + } + + private fun doDeposit(player: Player?, item: Int, depositMethod: (Player?, Boolean) -> Unit, checkMethod: (Player?) -> Boolean) { + player ?: return + if (!inInventory(player, item)) { + val determiner = if (getItemName(item).lowercase().endsWith("s")) "any" else "a" + sendMessage(player, "You haven't got $determiner ${getItemName(item).lowercase()} to store.") + return + } + if (!checkMethod.invoke(player)) { + depositMethod.invoke(player, true) + removeItem(player, item) + } else { + val itemName = when (item) { + // secateurs and watering cans are handled separately + Items.RAKE_5341 -> "rake" + Items.SEED_DIBBER_5343 -> "dibber" + Items.SPADE_952 -> "spade" + Items.GARDENING_TROWEL_5325 -> "trowel" + else -> getItemName(item).lowercase() + } + sendMessage(player, "You cannot store more than one $itemName in here.") + } + } + + private fun doStackedDeposit(player: Player?, item: Int, amount: Int, updateQuantityMethod: (Player?, Int) -> Unit, quantityCheckMethod: (Player?) -> Int) { + player ?: return + val hasAmount = amountInInventory(player, item) + var finalAmount = amount + val spaceLeft = (if (item == Items.BUCKET_1925) 31 else 255) - quantityCheckMethod.invoke(player) + + if (hasAmount == 0) { + val itemName = if (item == Items.BUCKET_1925) "buckets" else getItemName(item).lowercase() + sendMessage(player, "You haven't got any $itemName to store.") + return + } + + if (amount == -2) { + sendInputDialogue(player, true, "Enter the amount:") { value -> + var amt = value as Int + if (amt > hasAmount) { + amt = hasAmount + } + if (amt > spaceLeft) { + amt = spaceLeft + } + if (removeItem(player, Item(item, amt))) updateQuantityMethod.invoke(player, amt) + } + return + } + + if (amount == -1) { + finalAmount = hasAmount + if (finalAmount > spaceLeft) { + finalAmount = spaceLeft + } + } + + if (finalAmount > hasAmount) { + finalAmount = hasAmount + } + + if (finalAmount > spaceLeft) { + if (item == Items.BUCKET_1925) { + sendMessage(player, "You can't store that many buckets in here.") + } else { + sendMessage(player, "You can't store that much ${getItemName(item).lowercase()} in here.") + } + return + } + + removeItem(player, Item(item, finalAmount)) + updateQuantityMethod.invoke(player,finalAmount) + } + + private fun doStackedWithdrawal(player: Player?, item: Int, amount: Int, updateQuantityMethod: (Player?, Int) -> Unit, quantityCheckMethod: (Player?) -> Int) { + player ?: return + val hasAmount = quantityCheckMethod.invoke(player) + var finalAmount = amount + + if (hasAmount == 0) { + val itemName = if (item == Items.BUCKET_1925) "buckets" else getItemName(item).lowercase() + sendMessage(player, "You haven't got any $itemName stored in here!") + return + } + + if (amount == -2) { + sendInputDialogue(player, InputType.AMOUNT, "Enter the amount:") { value -> + var amt = value as Int + if (amt > hasAmount) { + amt = hasAmount + } + if (amt > freeSlots(player)) { + amt = freeSlots(player) + } + if (amt <= 0) { + sendMessage(player, "You don't have enough inventory space for that.") + } else { + addItem(player, item, amt) + updateQuantityMethod.invoke(player, -amt) + } + } + return + } + if (amount == -1) { + finalAmount = freeSlots(player) + } + if (finalAmount > hasAmount) { + finalAmount = hasAmount + } + if (!hasSpaceFor(player, Item(item, finalAmount)) || finalAmount == 0) { + sendMessage(player, "You don't have enough inventory space for that.") + return + } + addItem(player, item, finalAmount) + updateQuantityMethod.invoke(player, -finalAmount) + } + + fun getAmount(opcode: Int): Int { + return when (opcode) { + 155 -> 1 + 196 -> 5 + 124 -> -1 + 199 -> -2 + else -> 0 + } + } + + private fun hasRake(player: Player?): Boolean { + return getVarbit(player!!, 1435) == 1 + } + + private fun setHasRake(player: Player?, hasRake: Boolean) { + setVarbit(player!!, 1435, if (hasRake) 1 else 0, true) + } + + private fun hasDibber(player: Player?): Boolean { + return getVarbit(player!!, 1436) == 1 + } + + private fun setHasDibber(player: Player?, hasDibber: Boolean) { + setVarbit(player!!, 1436, if (hasDibber) 1 else 0, true) + } + + private fun hasSpade(player: Player?): Boolean { + return getVarbit(player!!, 1437) == 1 + } + + private fun setHasSpade(player: Player?, hasSpade: Boolean) { + setVarbit(player!!, 1437, if (hasSpade) 1 else 0, true) + } + + private fun hasSecateurs(player: Player?): Boolean { + return getVarbit(player!!, 1438) == 1 + } + + private fun setHasSecateurs(player: Player?, hasSecateurs: Boolean) { + setVarbit(player!!, 1438, if (hasSecateurs) 1 else 0, true) + } + + private fun hasWateringCan(player: Player?): Boolean { + return getVarbit(player!!, 1439) > 0 + } + + private fun getWateringCan(player: Player?): Int { + var can = getVarbit(player!!, 1439) //Watering cans are stored in the Varp as a number between 1 and 9. Watering Can(0) is 1 and Watering Can(8) is 9 + if (can == 1) can = 0 + return Items.WATERING_CAN_5331 + can + } + + private fun setWateringCan(player: Player?, item: Item) { + val can = when (item.id) { + Items.WATERING_CAN_5331 -> 1 + Items.WATERING_CAN1_5333 -> 2 + Items.WATERING_CAN2_5334 -> 3 + Items.WATERING_CAN3_5335 -> 4 + Items.WATERING_CAN4_5336 -> 5 + Items.WATERING_CAN5_5337 -> 6 + Items.WATERING_CAN6_5338 -> 7 + Items.WATERING_CAN7_5339 -> 8 + Items.WATERING_CAN8_5340 -> 9 + else -> 0 + } + setVarbit(player!!, 1439, can, true) + } + + private fun setNoWateringCan(player: Player?) { + setVarbit(player!!, 1439, 0, true) + } + + private fun hasGardeningTrowel(player: Player?): Boolean { + return getVarbit(player!!, 1440) == 1 + } + + private fun setHasGardeningTrowel(player: Player?, hasTrowel: Boolean) { + setVarbit(player!!, 1440, if (hasTrowel) 1 else 0, true) + } + + private fun getNumBuckets(player: Player?): Int { + return getVarbit(player!!, 1441) + } + + private fun updateBuckets(player: Player?, amount: Int) { + setVarbit(player!!, 1441, getNumBuckets(player) + amount, true) + } + + private fun getNumCompost(player: Player?): Int { + return getVarbit(player!!, 1442) + } + + private fun updateCompost(player: Player?, amount: Int) { + setVarbit(player!!, 1442, getNumCompost(player) + amount, true) + } + + private fun getNumSuperCompost(player: Player?): Int { + return getVarbit(player!!, 1443) + } + + private fun updateSuperCompost(player: Player?, amount: Int) { + setVarbit(player!!, 1443, getNumSuperCompost(player) + amount, true) + } + + private fun hasMagicSecateurs(player: Player?): Boolean { + return getVarbit(player!!, 1848) == 1 + } + + private fun setHasMagicSecateurs(player: Player?, hasMagic: Boolean) { + setVarbit(player!!, 1848, if (hasMagic) 1 else 0, true) + } + + private fun getHighestCan(player: Player?): Item? { + player ?: return null + var highestCan = Item(0) + for (item in player.inventory.toArray()) { + if (item == null) continue + if (item.name.contains("Watering")) { + if (item.id > highestCan.id) highestCan = item + } + } + return if (highestCan.id == 0) null else highestCan + } + +} diff --git a/Server/src/main/content/global/skill/farming/UseWithBinHandler.kt b/Server/src/main/content/global/skill/farming/UseWithBinHandler.kt new file mode 100644 index 0000000..8d557e9 --- /dev/null +++ b/Server/src/main/content/global/skill/farming/UseWithBinHandler.kt @@ -0,0 +1,104 @@ +package content.global.skill.farming + +import core.api.* +import core.game.system.task.Pulse +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items +import core.game.interaction.IntType +import core.game.interaction.InteractionListener + +class UseWithBinHandler : InteractionListener { + @JvmField + val allowedNodes = ArrayList(100) + val fillAnim = Animation(832) + val compostPotionAnimation = Animation(2259) + val scoopAnimation = Animation(8905) + + val bins = 7836..7840 + + override fun defineListeners() { + loadNodes() + onUseWith(IntType.SCENERY, allowedNodes.toIntArray(), *bins.toIntArray()) { player, usedNode, with -> + val cBin = CompostBins.forObject(with.asScenery()) ?: return@onUseWith true + val bin = cBin.getBinForPlayer(player) + val used = usedNode.id + + + when (used) { + Items.COMPOST_POTION1_6476, Items.COMPOST_POTION2_6474, Items.COMPOST_POTION3_6472, Items.COMPOST_POTION4_6470 -> { + if (!bin.isSuperCompost && bin.isFinished && !bin.isClosed) { + animate(player, compostPotionAnimation) + submitIndividualPulse(player, object : Pulse(compostPotionAnimation.duration) { + override fun pulse(): Boolean { + if (removeItem(player, usedNode.asItem())) { + bin.convert() + addItem(player, used.getNext()) + } + return true + } + }) + } else { + sendDialogue(player, "You can only do this with an open bin of finished regular compost.") + } + } + + Items.BUCKET_1925 -> { + if (bin.isFinished && !bin.isClosed) { + submitIndividualPulse(player, object : Pulse(scoopAnimation.duration) { + override fun pulse(): Boolean { + if (!player.inventory.containsItem(usedNode.asItem())) return true + animate(player, scoopAnimation) + val item = bin.takeItem() + if (item != null && removeItem(player, usedNode.asItem())) { + player.inventory.add(item) + } + return item == null || !player.inventory.containsItem(usedNode.asItem()) + } + }) + } else { + sendDialogue(player, "You can only scoop an opened bin of finished compost.") + } + } + + else -> + if (bin.isFull()) { + sendMessage(player, "This compost bin is already full.") + return@onUseWith true + } else if (!bin.isFinished) { + submitIndividualPulse(player, object : Pulse(fillAnim.duration) { + override fun pulse(): Boolean { + animate(player, fillAnim) + if (removeItem(player, usedNode.asItem())) { + bin.addItem(usedNode.asItem()) + } + return bin.isFull() || player.inventory.getAmount(usedNode.asItem()) == 0 + } + }) + } else { + sendDialogue(player, "The compost bin must be empty of compost before you can put new items in it.") + } + } + return@onUseWith true + } + } + + fun loadNodes() { + for (p in Plantable.values()) { + if (p.harvestItem != Items.SCARECROW_6059) { + allowedNodes.add(p.harvestItem) + } + } + allowedNodes.add(Items.COCONUT_SHELL_5978) + allowedNodes.add(Items.WEEDS_6055) + allowedNodes.add(Items.COMPOST_POTION4_6470) + allowedNodes.add(Items.COMPOST_POTION3_6472) + allowedNodes.add(Items.COMPOST_POTION2_6474) + allowedNodes.add(Items.COMPOST_POTION1_6476) + allowedNodes.add(Items.BUCKET_1925) + } + + private fun Int.getNext(): Int { + if (this != 6476) return this + 2 + else return Items.VIAL_229 + } +} diff --git a/Server/src/main/content/global/skill/farming/UseWithPatchHandler.kt b/Server/src/main/content/global/skill/farming/UseWithPatchHandler.kt new file mode 100644 index 0000000..6dac10d --- /dev/null +++ b/Server/src/main/content/global/skill/farming/UseWithPatchHandler.kt @@ -0,0 +1,351 @@ +package content.global.skill.farming + +import core.api.* +import core.game.node.entity.player.link.diary.DiaryType +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.system.task.Pulse +import org.rs09.consts.Items +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength +import core.tools.StringUtils +import core.tools.prependArticle +import org.rs09.consts.Sounds +import content.data.Quests + +class UseWithPatchHandler : InteractionListener { + val RAKE = Items.RAKE_5341 + val SEED_DIBBER = Items.SEED_DIBBER_5343 + val SPADE = Items.SPADE_952 + val SECATEURS = Items.SECATEURS_5329 + val MAGIC_SECATEURS = Items.MAGIC_SECATEURS_7409 + val TROWEL = Items.GARDENING_TROWEL_5325 + val spadeDigAnim = getAnimation(830) + val trowelDigAnim = getAnimation(2272) + val pourBucketAnim = getAnimation(2283) + val seedDibberAnim = getAnimation(2291) + val wateringCanAnim = getAnimation(2293) + val plantCureAnim = getAnimation(2288) + val secateursTreeAnim = getAnimation(2277) + val magicSecateursTreeAnim = getAnimation(3340) + + @JvmField + val allowedNodes = ArrayList() + + override fun defineListeners() { + loadNodes() + onUseWith(IntType.SCENERY, allowedNodes.toIntArray(), *FarmingPatch.patchNodes.toIntArray()) { player, used, with -> + val patch = FarmingPatch.forObject(with.asScenery()) ?: return@onUseWith true + val usedItem = used.asItem() + + if (patch == FarmingPatch.TROLL_STRONGHOLD_HERB) { + if (!hasRequirement(player, Quests.MY_ARMS_BIG_ADVENTURE)) + return@onUseWith true + } + + player.faceLocation(with.location) + when (usedItem.id) { + RAKE -> PatchRaker.rake(player,patch) + SEED_DIBBER -> sendMessage(player, "I should plant a seed, not the seed dibber.") + SPADE -> { + val anim = spadeDigAnim + val p = patch.getPatchFor(player) + if (p.isDead) { + sendMessage(player, "You start digging the farming patch...") + queueScript(player, 0, QueueStrength.WEAK) { stage: Int -> + when (stage) { + 0 -> { + animate(player, anim) + playAudio(player, Sounds.DIGSPADE_1470) + return@queueScript delayScript(player,anim.duration + 2) + } + 1 -> { + animate(player, anim) + playAudio(player, Sounds.DIGSPADE_1470) + return@queueScript delayScript(player, anim.duration + 1) + } + 2 -> { + p.clear() + sendMessage(player, "You have successfully cleared this patch for new crops.") + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + } else { + openDialogue(player, 67984003, patch.getPatchFor(player)) // DigUpPatchDialogue.kt + } + } + SECATEURS, MAGIC_SECATEURS -> { + val p = patch.getPatchFor(player) + if (patch.type == PatchType.TREE_PATCH) { + if (p.isDiseased && !p.isDead) { + submitIndividualPulse(player, object: Pulse() { + override fun pulse(): Boolean { + if (usedItem.id == SECATEURS) animate(player, secateursTreeAnim) else animate(player, magicSecateursTreeAnim) + p.cureDisease() + return true + } + }) + } else if (p.plantable == Plantable.WILLOW_SAPLING && p.harvestAmt > 0) { + val pulse = CropHarvester.harvestPulse(player, with, Items.WILLOW_BRANCH_5933) ?: return@onUseWith false + submitIndividualPulse(player, pulse) + } + } + } + TROWEL, Items.PLANT_POT_5350 -> { + if (!inInventory(player, TROWEL)) { + sendMessage(player, "You need a trowel to fill plant pots with dirt.") + return@onUseWith true + } + val p = patch.getPatchFor(player) + if (!p.isWeedy() && !p.isEmptyAndWeeded()) { + sendMessage(player, "This patch has something growing in it.") + return@onUseWith true + } else if (p.currentGrowthStage != 3) { + sendMessage(player, "I should clear this of weeds before trying to take some dirt.") + return@onUseWith true + } + + val potAmount = amountInInventory(player, Items.PLANT_POT_5350) + + if (potAmount == 0) { + sendMessage(player, "You have no plant pots to fill.") + return@onUseWith true + } + + val anim = trowelDigAnim + + submitIndividualPulse(player, object : Pulse(anim.duration) { + override fun pulse(): Boolean { + if (removeItem(player, Items.PLANT_POT_5350)) { + animate(player, anim) + addItem(player, Items.PLANT_POT_5354) + } else return true + return false + } + }) + } + + Items.PLANT_CURE_6036 -> { + val p = patch.getPatchFor(player) + val patchName = p.patch.type.displayName() + if (p.isDiseased && !p.isDead) { + sendMessage(player, "You treat the $patchName with the plant cure.") + queueScript(player, 0, QueueStrength.WEAK) { stage: Int -> + when (stage) { + 0 -> { + animate(player, plantCureAnim) + playAudio(player, Sounds.FARMING_PLANTCURE_2438) + return@queueScript delayScript(player, plantCureAnim.duration / 2) + } + 1 -> { + if (removeItem(player, usedItem)) { + addItem(player, Items.VIAL_229) + p.cureDisease() + sendMessage(player, "It is restored to health.") + } + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + } else { + sendMessage(player, "I have no reason to do this right now.") + } + } + + Items.WATERING_CAN_5331,Items.WATERING_CAN1_5333,Items.WATERING_CAN2_5334,Items.WATERING_CAN3_5335,Items.WATERING_CAN4_5336,Items.WATERING_CAN5_5337,Items.WATERING_CAN6_5338,Items.WATERING_CAN7_5339,Items.WATERING_CAN8_5340 -> { + val p = patch.getPatchFor(player) + val t = p.patch.type + if (t == PatchType.ALLOTMENT || t == PatchType.FLOWER_PATCH || t == PatchType.HOPS_PATCH) { + submitIndividualPulse(player, object : Pulse() { + override fun pulse(): Boolean { + if (p.isWeedy() || p.isEmptyAndWeeded()) { + sendMessage(player, "You should grow something first.") + return true + } + if (p.isWatered || p.isGrown() || p.plantable == Plantable.SCARECROW) { + sendMessage(player, "This patch doesn't need watering.") + return true + } + if (p.isDiseased || p.isDead) { + sendMessage(player, "Water isn't going to cure that!") + return true + } + if (usedItem.id == Items.WATERING_CAN_5331) { + sendMessage(player, "You need to fill the watering can first.") + return true + } + animate(player, wateringCanAnim) + playAudio(player, Sounds.FARMING_WATERING_2446) + if (removeItem(player, usedItem)) { + addItem(player, usedItem.id.getNext()) + p.water() + } + return true + } + }) + } else { + sendMessage(player, "This patch doesn't need watering.") + } + } + + Items.SUPERCOMPOST_6034, Items.COMPOST_6032 -> { + val p = patch.getPatchFor(player) + val patchName = p.patch.type.displayName() + + if (!p.isEmptyAndWeeded()) { + sendMessage(player, "This patch needs to be empty and weeded to do that.") + } else if (p.compost == CompostType.NONE) { + animate(player, pourBucketAnim) + playAudio(player, Sounds.FARMING_COMPOST_2427) + runTask(player) { + if (player.inventory.remove(usedItem,false)) { + sendMessage(player, "You treat the $patchName with ${usedItem.name.lowercase()}.") + p.compost = if (usedItem.id == Items.SUPERCOMPOST_6034) CompostType.SUPERCOMPOST else CompostType.COMPOST + if (p.compost == CompostType.SUPERCOMPOST) rewardXP(player, Skills.FARMING, 26.0) else rewardXP(player, Skills.FARMING, 18.5) + if (p.plantable != null && p.plantable?.applicablePatch != PatchType.FLOWER_PATCH) { + p.harvestAmt += if (p.compost == CompostType.COMPOST) 1 else if (p.compost == CompostType.SUPERCOMPOST) 2 else 0 + } + p.cropLives += if (p.compost == CompostType.SUPERCOMPOST) 2 else 1 + addItem(player, Items.BUCKET_1925) + } + return@runTask + } + } else { + sendMessage(player, "This $patchName has already been treated with ${p.compost.name.lowercase()}.") + } + } + + else -> { + val plantable = Plantable.forItemID(usedItem.id) ?: return@onUseWith false + + if (plantable.applicablePatch != patch.type) { + val plantableNamePlural = StringUtils.plusS(plantable.displayName) + val patchType = if (plantable.applicablePatch == PatchType.ALLOTMENT) "a vegetable patch" else prependArticle(plantable.applicablePatch.displayName()) + sendMessage(player, "You can only plant $plantableNamePlural in $patchType.") + return@onUseWith true + } + + if (!hasLevelDyn(player, Skills.FARMING, plantable.requiredLevel)) { + sendMessage(player, "You need a Farming level of ${plantable.requiredLevel} to plant this.") + return@onUseWith true + } + + val p = patch.getPatchFor(player) + if (p.getCurrentState() < 3 && p.isWeedy() && plantable != Plantable.SCARECROW) { + sendMessage(player, "This patch needs weeding first.") + return@onUseWith true + } else if (p.getCurrentState() > 3) { + sendMessage(player, "There is already something growing in this patch.") + return@onUseWith true + } + + val plantItem = when (patch.type) { + PatchType.ALLOTMENT -> Item(plantable.itemID, 3) + PatchType.HOPS_PATCH -> if (plantable == Plantable.JUTE_SEED) Item(plantable.itemID, 3) else Item(plantable.itemID, 4) + else -> Item(plantable.itemID,1) + } + + if (!player.inventory.containsItem(plantItem)) { + val seedPlural = if (plantItem.amount == 1) "seed" else "seeds" + sendMessage(player, "You need ${plantItem.amount} $seedPlural to plant ${prependArticle(patch.type.displayName())}.") + return@onUseWith true + } + + val requiredItem = when (patch.type) { + PatchType.TREE_PATCH, PatchType.FRUIT_TREE_PATCH -> Items.SPADE_952 + PatchType.FLOWER_PATCH -> if (plantable == Plantable.SCARECROW) null else Items.SEED_DIBBER_5343 + else -> Items.SEED_DIBBER_5343 + } + if (requiredItem != null && !inInventory(player, requiredItem)) { + sendMessage(player, "You need ${prependArticle(requiredItem.asItem().name.lowercase())} to plant that.") + return@onUseWith true + } + + queueScript(player, 0, QueueStrength.WEAK) { stage: Int -> + when (stage) { + 0 -> { + val (anim, sound) = when (requiredItem) { + Items.SPADE_952 -> Pair(spadeDigAnim, Sounds.DIGSPADE_1470) + else -> Pair(seedDibberAnim,Sounds.FARMING_DIBBING_2432) + } + animate(player, anim) + playAudio(player, sound) + val delay = if (patch.type == PatchType.TREE_PATCH || patch.type == PatchType.FRUIT_TREE_PATCH || plantable == Plantable.SCARECROW) 3 else 0 + return@queueScript delayScript(player,anim.duration + delay) + } + 1 -> { + if (removeItem(player, plantItem)) { + if (plantable == Plantable.JUTE_SEED && patch == FarmingPatch.MCGRUBOR_HOPS && !player.achievementDiaryManager.hasCompletedTask(DiaryType.SEERS_VILLAGE, 0, 7)) { + player.achievementDiaryManager.finishTask(player, DiaryType.SEERS_VILLAGE, 0, 7) + } + p.plant(plantable) + rewardXP(player, Skills.FARMING, plantable.plantingXP) + p.setNewHarvestAmount() + if (p.patch.type == PatchType.TREE_PATCH || p.patch.type == PatchType.FRUIT_TREE_PATCH) { + addItem(player, Items.PLANT_POT_5350) + } + + val itemAmount = + if (p.patch.type == PatchType.TREE_PATCH || p.patch.type == PatchType.FRUIT_TREE_PATCH) "the" + else if (plantItem.amount == 1) "a" + else plantItem.amount + val itemName = + if (plantItem.amount == 1) plantable.displayName else StringUtils.plusS( + plantable.displayName + ) + val patchName = p.patch.type.displayName() + if (plantable == Plantable.SCARECROW) { + sendMessage(player, "You place the scarecrow in the $patchName.") + } else { + sendMessage(player, "You plant $itemAmount $itemName in the $patchName.") + } + } + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + } + } + return@onUseWith true + } + } + + fun loadNodes() { + for (p in Plantable.values()) { + allowedNodes.add(p.itemID) + } + allowedNodes.addAll( + arrayListOf( + RAKE, + SEED_DIBBER, + SPADE, + SECATEURS, + MAGIC_SECATEURS, + TROWEL, + Items.SUPERCOMPOST_6034, + Items.COMPOST_6032, + Items.PLANT_CURE_6036, + Items.WATERING_CAN_5331, + Items.WATERING_CAN1_5333, + Items.WATERING_CAN2_5334, + Items.WATERING_CAN3_5335, + Items.WATERING_CAN4_5336, + Items.WATERING_CAN5_5337, + Items.WATERING_CAN6_5338, + Items.WATERING_CAN7_5339, + Items.WATERING_CAN8_5340, + Items.PLANT_POT_5350 + ) + ) + } + + private fun Int.getNext(): Int { + if (this == Items.WATERING_CAN1_5333) return Items.WATERING_CAN_5331 + else return this - 1 + } +} diff --git a/Server/src/main/content/global/skill/farming/timers/Compost.kt b/Server/src/main/content/global/skill/farming/timers/Compost.kt new file mode 100644 index 0000000..cc69490 --- /dev/null +++ b/Server/src/main/content/global/skill/farming/timers/Compost.kt @@ -0,0 +1,65 @@ +package content.global.skill.farming.timers + +import core.api.* +import core.game.system.timer.* +import org.json.simple.* +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import content.global.skill.farming.* + +class Compost : PersistTimer (500, "farming:compost", isSoft = true) { + private val binMap = HashMap() + lateinit var player: Player + + override fun onRegister (entity: Entity) { + player = (entity as? Player)!! + } + + override fun getInitialRunDelay() : Int { + return 1 //run once immediately after log in to complete any pending-but-enough-time-has-passed bins. + } + + override fun run (entity: Entity) : Boolean { + val removeList = ArrayList () + for((cBin,bin) in binMap){ + if(bin.isReady() && !bin.isFinished){ + bin.finish() + } + else if (bin.isDefaultState()) + removeList.add(cBin) + } + removeList.forEach { binMap.remove(it) } + removeList.clear() + + return binMap.isNotEmpty() + } + + fun getBin (bin: CompostBins) : CompostBin{ + return binMap[bin] ?: (CompostBin (player, bin).also { binMap[bin] = it }) + } + + fun getBins(): MutableCollection{ + return binMap.values + } + + override fun save (root: JSONObject, entity: Entity) { + val bins = JSONArray() + for((key,bin) in binMap){ + val b = JSONObject() + b.put("bin-ordinal",key.ordinal) + bin.save(b) + bins.add(b) + } + root.put("bins", bins) + } + + override fun parse (root: JSONObject, entity: Entity) { + (root["bins"] as JSONArray).forEach { + val bin = it as JSONObject + val binOrdinal = bin["bin-ordinal"].toString().toInt() + val cBin = CompostBins.values()[binOrdinal] + val b = CompostBin ((entity as? Player)!!, cBin).also { binMap[cBin] = it } + b.parse(bin["binData"] as JSONObject) + } + } +} diff --git a/Server/src/main/content/global/skill/farming/timers/CropGrowth.kt b/Server/src/main/content/global/skill/farming/timers/CropGrowth.kt new file mode 100644 index 0000000..074e5ae --- /dev/null +++ b/Server/src/main/content/global/skill/farming/timers/CropGrowth.kt @@ -0,0 +1,153 @@ +package content.global.skill.farming.timers + +import core.tools.* +import core.game.system.timer.* +import org.json.simple.* +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import content.global.skill.farming.* +import java.util.concurrent.TimeUnit +import java.time.* + +class CropGrowth : PersistTimer (500, "farming:crops", isSoft = true) { + private val patchMap = HashMap() + lateinit var player: Player + + override fun onRegister (entity: Entity) { + player = (entity as? Player)!! + runOfflineCatchupLogic() + } + + //Sync the 5 minute run cycles with :05 on realtime clocks - authentic + override fun getInitialRunDelay() : Int { + val now = LocalTime.now() + val minsUntil5MinSync = 5 - (now.getMinute() % 5) + val ticks = secondsToTicks (minsUntil5MinSync * 60) + player.debug("[CropGrowth] Scheduled first growth cycle for $ticks ticks from now.") + return ticks + } + + override fun run (entity: Entity) : Boolean { + var removeList = ArrayList() + for((fp,patch) in patchMap){ + if(patch.getCurrentState() in 1..3 && patch.nextGrowth == 0L){ + patch.nextGrowth = System.currentTimeMillis() + 60000 + continue + } + + //Go ahead and grow anything within 4 minutes of the 5-minute-synced growth cycles, bringing out-of-sync patches into sync. + //This seems to be authentic as well, with the RS wiki sometimes stating 20-minute patches can grow in as little as 7 minutes depending on timing of planting + //It also makes sense, as otherwise if you e.g. planted something at 10:34 that takes 5 minutes to grow, it would take 6 minutes in reality instead of 5. + //Another more extreme example is if you planted something at 10:31 that takes 5 minutes to grow. 10:35 comes around, it hasn't been 5 minutes, so it doesn't grow, meaning + //it actually grows at 10:40, an extra 4 minutes. + //this code makes it so crops planted both at 10:31 and 10:34 grow at 10:35 if they are supposed to take 5 minutes for each stage. + if(patch.nextGrowth < (System.currentTimeMillis() + 240_000L) && !patch.isDead){ + patch.nextGrowth = System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(patch.getStageGrowthMinutes().toLong()) + patch.update() + } + + if (patch.getCurrentState() == 0) + removeList.add(fp) + } + removeList.forEach { patchMap.remove(it) } + removeList.clear() + return patchMap.isNotEmpty() + } + + private fun runOfflineCatchupLogic() { + for ((_, patch) in patchMap) { + val type = patch.patch.type + val shouldPlayCatchup = !patch.isGrown() || (type == PatchType.BUSH_PATCH && patch.getFruitOrBerryCount() < 4) || (type == PatchType.FRUIT_TREE_PATCH && patch.getFruitOrBerryCount() < 6) + if (shouldPlayCatchup && !patch.isDead) { + var stagesToSimulate = if (!patch.isGrown()) { + if (patch.isWeedy() || patch.isEmptyAndWeeded()) patch.currentGrowthStage % 4 + else patch.plantable!!.stages - patch.currentGrowthStage + } else 0 + + if (patch.plantable != null) { + if (type == PatchType.BUSH_PATCH) + stagesToSimulate += Math.min(4, 4 - patch.getFruitOrBerryCount()) + if (type == PatchType.FRUIT_TREE_PATCH) + stagesToSimulate += Math.min(6, 6 - patch.getFruitOrBerryCount()) + } + + val nowTime = System.currentTimeMillis() + var simulatedTime = patch.nextGrowth + + while (simulatedTime < nowTime && stagesToSimulate-- > 0 && !patch.isDead) { + val timeToIncrement = TimeUnit.MINUTES.toMillis(patch.getStageGrowthMinutes().toLong()) + patch.update() + simulatedTime += timeToIncrement + } + } + } + } + + fun getPatch(patch: FarmingPatch, addPatch: Boolean ): Patch { + return patchMap[patch] ?: (Patch(player,patch).also { if (addPatch) patchMap[patch] = it }) + } + + fun getPatches(): MutableCollection{ + return patchMap.values + } + + override fun save (root: JSONObject, entity: Entity) { + val patches = JSONArray() + for((key,patch) in patchMap){ + val p = JSONObject() + p.put("patch-ordinal",key.ordinal) + p.put("patch-plantable-ordinal",patch.plantable?.ordinal ?: -1) + p.put("patch-watered",patch.isWatered) + p.put("patch-diseased",patch.isDiseased) + p.put("patch-dead",patch.isDead) + p.put("patch-stage",patch.currentGrowthStage) + p.put("patch-state",patch.getCurrentState()) + p.put("patch-nextGrowth",patch.nextGrowth) + p.put("patch-harvestAmt",patch.harvestAmt) + p.put("patch-checkHealth",patch.isCheckHealth) + p.put("patch-compost",patch.compost.ordinal) + p.put("patch-paidprot",patch.protectionPaid) + p.put("patch-croplives", patch.cropLives) + patches.add(p) + } + root["patches"] = patches + } + + override fun parse (root: JSONObject, entity: Entity) { + val data = root["patches"] as JSONArray + for(d in data){ + val p = d as JSONObject + val patchOrdinal = p["patch-ordinal"].toString().toInt() + val patchPlantableOrdinal = p["patch-plantable-ordinal"].toString().toInt() + val patchWatered = p["patch-watered"] as Boolean + val patchDiseased = p["patch-diseased"] as Boolean + val patchDead = p["patch-dead"] as Boolean + val patchStage = p["patch-stage"].toString().toInt() + val nextGrowth = p["patch-nextGrowth"].toString().toLong() + val harvestAmt = (p["patch-harvestAmt"] ?: 0).toString().toInt() + val checkHealth = p["patch-checkHealth"] as Boolean + val savedState = p["patch-state"].toString().toInt() + val compostOrdinal = p["patch-compost"].toString().toInt() + val protectionPaid = p["patch-paidprot"] as Boolean + val cropLives = if(p["patch-croplives"] != null) p["patch-croplives"].toString().toInt() else 3 + val fPatch = FarmingPatch.values()[patchOrdinal] + val plantable = if(patchPlantableOrdinal != -1) Plantable.values()[patchPlantableOrdinal] else null + val patch = Patch((entity as? Player)!!,fPatch,plantable,patchStage,patchDiseased,patchDead,patchWatered,nextGrowth,harvestAmt,checkHealth) + + patch.cropLives = cropLives + patch.compost = CompostType.values()[compostOrdinal] + patch.protectionPaid = protectionPaid + patch.setCurrentState(savedState) + + if((savedState - (patch?.plantable?.value ?: 0)) > patch.currentGrowthStage){ + patch.setCurrentState(savedState) + } else { + patch.setCurrentState((patch.plantable?.value ?: 0) + patch.currentGrowthStage) + } + + if(patchMap[fPatch] == null) { + patchMap[fPatch] = patch + } + } + } +} diff --git a/Server/src/main/content/global/skill/farming/timers/SeedlingGrowth.kt b/Server/src/main/content/global/skill/farming/timers/SeedlingGrowth.kt new file mode 100644 index 0000000..843c687 --- /dev/null +++ b/Server/src/main/content/global/skill/farming/timers/SeedlingGrowth.kt @@ -0,0 +1,74 @@ +package content.global.skill.farming.timers + +import core.game.node.entity.Entity +import core.game.node.item.Item +import core.game.system.timer.* +import core.game.node.entity.player.Player +import content.global.skill.farming.* +import java.util.concurrent.TimeUnit +import org.json.simple.* +import java.time.* + +class SeedlingGrowth : PersistTimer (1, "farming:seedling", isSoft = true) { + val seedlings = ArrayList() + lateinit var player: Player + + fun addSeedling(seedling: Int){ + seedlings.add( + Seedling( + seedling, + System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(5), + seedling + if(seedling > 5400) 8 else 6 + ) + ) + } + + override fun onRegister (entity: Entity) { + player = (entity as? Player)!! + } + + override fun run (entity: Entity) : Boolean { + val removeList = ArrayList() + for (seed in seedlings) { + if (System.currentTimeMillis() > seed.TTL) { + val inInventory = player.inventory.get(Item(seed.id)) + if (inInventory != null) { + player.inventory.replace(Item(seed.sapling), inInventory.slot) + removeList.add(seed) + } else { + val inBank = player.bank.get(Item(seed.id)) + if(inBank == null) removeList.add(seed) + else { + player.bank.remove(Item(inBank.id,1)) + player.bank.add(Item(seed.sapling)) + removeList.add(seed) + } + } + } + } + seedlings.removeAll(removeList) + return seedlings.isNotEmpty() + } + + override fun save(root: JSONObject, entity: Entity) { + val seedArray = JSONArray() + for(s in seedlings){ + val seed = JSONObject() + seed.put("id",s.id) + seed.put("ttl",s.TTL) + seed.put("sapling",s.sapling) + seedArray.add(seed) + } + root.put("seedlings",seedArray) + } + + override fun parse(root: JSONObject, entity: Entity) { + (root["seedlings"] as JSONArray).forEach { + val s = it as JSONObject + val id = s["id"].toString().toInt() + val ttl = s["ttl"].toString().toLong() + val sapling = s["sapling"].toString().toInt() + seedlings.add(Seedling(id,ttl,sapling)) + } + } +} diff --git a/Server/src/main/content/global/skill/firemaking/FireMakingOptionPlugin.kt b/Server/src/main/content/global/skill/firemaking/FireMakingOptionPlugin.kt new file mode 100644 index 0000000..76f745d --- /dev/null +++ b/Server/src/main/content/global/skill/firemaking/FireMakingOptionPlugin.kt @@ -0,0 +1,22 @@ +package content.global.skill.firemaking + +import core.game.node.item.GroundItem +import org.rs09.consts.Items +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +class FiremakingListener : InteractionListener +{ + val logs = intArrayOf(1511, 1521, 1513, 1515, 1517, 1519, 2862, 3438, 3440, 3442, 3444, 3446, 3448, 6211, 6213, 6332, 6333, 7404, 7405, 7406, 8934, 9067, 10328, 10329, 10808, 10810, 10812, 11035, 12581, 12583, 3125) + + override fun defineListeners() { + onUseWith(IntType.ITEM, Items.TINDERBOX_590, *logs) { player, _, with -> + player.pulseManager.run(FireMakingPulse(player, with.asItem(), null)) + return@onUseWith true + } + onUseWith(IntType.GROUNDITEM, Items.TINDERBOX_590, *logs) { player, _, with -> + player.pulseManager.run(FireMakingPulse(player, with.asItem(), with as GroundItem)) + return@onUseWith true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/firemaking/FireMakingPulse.java b/Server/src/main/content/global/skill/firemaking/FireMakingPulse.java new file mode 100644 index 0000000..50b969e --- /dev/null +++ b/Server/src/main/content/global/skill/firemaking/FireMakingPulse.java @@ -0,0 +1,200 @@ +package content.global.skill.firemaking; + +import core.api.Container; +import core.game.event.LitFireEvent; +import core.game.node.entity.skill.SkillPulse; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItem; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.world.GameWorld; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import core.tools.RandomFunction; +import org.rs09.consts.Items; + +import static core.api.ContentAPIKt.inInventory; +import static core.api.ContentAPIKt.replaceSlot; + +/** + * Represents the pulse used to light a log. + * @author 'Vexia + */ +public final class FireMakingPulse extends SkillPulse { + + /** + * Represents the animation to use. + */ + private static final Animation ANIMATION = new Animation(733); + + /** + * Represents the tinderbox item. + */ + private static final Item TINDERBOX = new Item(Items.TINDERBOX_590); + + + /** + * Represents the log being burned. + */ + private final Log fire; + + /** + * Represents the ground item. + */ + private GroundItem groundItem; + + /** + * Represents the ticks. + */ + private int ticks; + + /** + * Constructs a new {@code FireMaking}. + * @param player the player. + * @param node the node. + * @param groundItem the ground item if not null. + */ + public FireMakingPulse(Player player, Item node, GroundItem groundItem) { + super(player, node); + this.fire = Log.forId(node.getId()); + if (groundItem == null) { + this.groundItem = new GroundItem(node, player.getLocation(), player); + player.setAttribute("remove-log", true); + } else { + this.groundItem = groundItem; + player.removeAttribute("remove-log"); + } + } + + @Override + public boolean checkRequirements() { + if (fire == null) { + return false; + } + if (RegionManager.getObject(player.getLocation()) != null || player.getZoneMonitor().isInZone("bank")) { + player.getPacketDispatch().sendMessage("You can't light a fire here."); + return false; + } + if (!player.getInventory().containsItem(TINDERBOX)) { + player.getPacketDispatch().sendMessage("You do not have the required items to light this."); + return false; + } + if (player.getSkills().getLevel(Skills.FIREMAKING) < fire.getLevel()) { + player.getPacketDispatch().sendMessage("You need a firemaking level of " + fire.getLevel() + " to light this log."); + return false; + } + if (player.getAttribute("remove-log", false)) { + player.removeAttribute("remove-log"); + if (inInventory(player, node.getId(), 1)) { + replaceSlot(player, node.getSlot(), new Item(node.getId(), (node.getAmount() - 1)), node, Container.INVENTORY); + GroundItemManager.create(groundItem); + } + } + return true; + } + + @Override + public void animate() { + } + + @Override + public boolean reward() { + if (getLastFire() >= GameWorld.getTicks()) { + createFire(); + return true; + } + if (ticks == 0) { + player.animate(ANIMATION); + } + if (++ticks % 3 != 0) { + return false; + } + if (ticks % 12 == 0) { + player.animate(ANIMATION); + } + if (!success()) { + return false; + } + createFire(); + return true; + } + + /** + * Creates the fire. + */ + public void createFire() { + if (!groundItem.isActive()) { + return; + } + // GameObject originalOnSpot = + // RegionManager.getObject(player.getLocation()); + final Scenery object = new Scenery(fire.getFireId(), player.getLocation()); + SceneryBuilder.add(object, fire.getLife(), getAsh(player, fire, object)); + GroundItemManager.destroy(groundItem); + player.moveStep(); + player.faceLocation(object.getFaceLocation(player.getLocation())); + player.getSkills().addExperience(Skills.FIREMAKING,fire.getXp()); + + int playerRegion = player.getViewport().getRegion().getId(); + + setLastFire(); + player.dispatch(new LitFireEvent(fire.getLogId())); + } + + @Override + public void message(int type) { + String name = node.getId() == Items.JOGRE_BONES_3125 ? "bones" : "logs"; + switch (type) { + case 0: + player.getPacketDispatch().sendMessage("You attempt to light the " + name + ".."); + break; + case 1: + player.getPacketDispatch().sendMessage("The fire catches and the " + name + " begin to burn."); + break; + } + } + + /** + * Gets the last firemake. + * @return the tick. + */ + public int getLastFire() { + return player.getAttribute("last-firemake", 0); + } + + /** + * Sets the last fire. + */ + public void setLastFire() { + player.setAttribute("last-firemake", GameWorld.getTicks() + 2); + } + + /** + * Gets the ground item ash. + * @param object the object. + * @return {@code GroundItem} the itemm. + */ + public static GroundItem getAsh(final Player player, Log fire, final Scenery object) { + final GroundItem ash = new GroundItem(new Item(Items.ASHES_592), object.getLocation(), player); + ash.setDecayTime(fire.getLife() + 200); + return ash; + } + + /** + * Checks if the player gets rewarded. + * @return {@code True} if so. + */ + private boolean success() { + int level = 1 + player.getSkills().getLevel(Skills.FIREMAKING); + double req = fire.getLevel(); + double successChance = Math.ceil((level * 50 - req * 15) / req / 3 * 4); + int roll = RandomFunction.random(99); + if (successChance >= roll) { + return true; + } + return false; + } +} diff --git a/Server/src/main/content/global/skill/firemaking/LightLogPlugin.java b/Server/src/main/content/global/skill/firemaking/LightLogPlugin.java new file mode 100644 index 0000000..db524a6 --- /dev/null +++ b/Server/src/main/content/global/skill/firemaking/LightLogPlugin.java @@ -0,0 +1,32 @@ +package content.global.skill.firemaking; + +import core.cache.def.impl.ItemDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItem; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the plugin used to light a log. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class LightLogPlugin extends OptionHandler { + + @Override + public boolean handle(Player player, Node node, String option) { + player.getPulseManager().run(new FireMakingPulse(player, ((Item) node), ((GroundItem) node))); + return true; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ItemDefinition.setOptionHandler("light", this); + return this; + } + +} diff --git a/Server/src/main/content/global/skill/firemaking/Log.java b/Server/src/main/content/global/skill/firemaking/Log.java new file mode 100644 index 0000000..59c7b82 --- /dev/null +++ b/Server/src/main/content/global/skill/firemaking/Log.java @@ -0,0 +1,128 @@ +package content.global.skill.firemaking; + +import java.util.HashMap; + +/** + * Represents an enumeration of burnable logs. + * @author 'Vexia + */ +public enum Log { + NORMAL(1511, 1, 180, 2732, 40), + ACHEY(2862, 1, 180, 2732, 40), + OAK(1521, 15, 200, 2732, 60), + WILLOW(1519, 30, 250, 2732, 90), + TEAK(6333, 35, 300, 2732, 105), + ARCTIC_PINE(10810, 42, 500, 2732, 125), + MAPLE(1517, 45, 300, 2732, 135), + MAHOGANY(6332, 50, 300, 2732, 157.5), + EUCALYPTUS(12581, 58, 300, 2732, 193.5), + YEW(1515, 60, 400, 2732, 202.5), + MAGIC(1513, 75, 450, 2732, 303.8), + CURSED_MAGIC(13567, 82, 650, 2732, 303.8), + PURPLE(10329, 1, 200, 20001, 50), + WHITE(10328, 1, 200, 20000, 50), + BLUE(7406, 1, 200, 11406, 50), + GREEN(7405, 1, 200, 11405, 50), + RED(7404, 1, 200, 11404, 50), + JOGRE(3125, 1, 200, 3862, 50); + + public static HashMap logMap = new HashMap<>(); + static{ + Log[] logArray = Log.values(); + int logLength = logArray.length; + for(int i = 0; i < logLength; i++){ + Log log = logArray[i]; + logMap.putIfAbsent(log.logId,log); + } + } + + /** + * The log id. + */ + private final int logId; + + /** + * The level. + */ + private final int level; + + /** + * The life. + */ + private final int life; + + /** + * The fire id. + */ + private final int fireId; + + /** + * The exp gained. + */ + private final double xp; + + /** + * Constructs a new {@code FireMakingDefinitions.java} {@code Object}. + * @param logId the log id. + * @param level the level. + * @param life the life. + * @param fireId the fire id. + * @param xp the experience. + */ + Log(int logId, int level, int life, int fireId, double xp) { + this.logId = logId; + this.level = level; + this.life = life; + this.fireId = fireId; + this.xp = xp; + } + + /** + * Gets the logId. + * @return The logId. + */ + public int getLogId() { + return logId; + } + + /** + * Gets the level. + * @return The level. + */ + public int getLevel() { + return level; + } + + /** + * Gets the life. + * @return The life. + */ + public int getLife() { + return life; + } + + /** + * Gets the fireId. + * @return The fireId. + */ + public int getFireId() { + return fireId; + } + + /** + * Gets the xp. + * @return The xp. + */ + public double getXp() { + return xp; + } + + /** + * Gets the log by the id. + * @param id the id. + * @return the log. + */ + public static Log forId(int id) { + return logMap.get(id); + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fishing/Fish.kt b/Server/src/main/content/global/skill/fishing/Fish.kt new file mode 100644 index 0000000..8ccc67f --- /dev/null +++ b/Server/src/main/content/global/skill/fishing/Fish.kt @@ -0,0 +1,67 @@ +package content.global.skill.fishing + +import core.api.asItem +import core.game.node.item.Item +import org.rs09.consts.Items + +enum class Fish(val id: Int, val level: Int, val experience: Double, val lowChance: Double, val highChance: Double) { + CRAYFISH(Items.RAW_CRAYFISH_13435, 1, 10.0, 0.15, 0.5), + SHRIMP(Items.RAW_SHRIMPS_317, 1, 10.0, 0.191, 0.5), + SARDINE(Items.RAW_SARDINE_327, 5, 20.0, 0.148, 0.374), + KARAMBWANJI(Items.RAW_KARAMBWANJI_3150, 5, 5.0, 0.4, 0.98), + HERRING(Items.RAW_HERRING_345, 10, 30.0, 0.129, 0.504), + ANCHOVIE(Items.RAW_ANCHOVIES_321, 15, 40.0, 0.098, 0.5), + MACKEREL(Items.RAW_MACKEREL_353, 16, 20.0, 0.055, 0.258), + TROUT(Items.RAW_TROUT_335, 20, 50.0, 0.246, 0.468), + COD(Items.RAW_COD_341, 23, 45.0, 0.063, 0.219), + PIKE(Items.RAW_PIKE_349, 25, 60.0, 0.14, 0.379), + SLIMY_EEL(Items.SLIMY_EEL_3379, 28, 65.0, 0.117, 0.216), + SALMON(Items.RAW_SALMON_331, 30, 70.0, 0.156, 0.378), + FROG_SPAWN(Items.FROG_SPAWN_5004, 33, 75.0, 0.164, 0.379), + TUNA(Items.RAW_TUNA_359, 35, 80.0, 0.109, 0.205), + RAINBOW_FISH(Items.RAW_RAINBOW_FISH_10138, 38, 80.0, 0.113, 0.254), + CAVE_EEL(Items.RAW_CAVE_EEL_5001, 38, 80.0, 0.145, 0.316), + LOBSTER(Items.RAW_LOBSTER_377, 40, 90.0, 0.16, 0.375), + BASS(Items.RAW_BASS_363, 46, 100.0, 0.078, 0.16), + SWORDFISH(Items.RAW_SWORDFISH_371, 50, 100.0, 0.105, 0.191), + LAVA_EEL(Items.RAW_LAVA_EEL_2148, 53, 60.0, 0.227, 0.379), + MONKFISH(Items.RAW_MONKFISH_7944, 62, 120.0, 0.293, 0.356), + KARAMBWAN(Items.RAW_KARAMBWAN_3142, 65, 105.0, 0.414, 0.629), + SHARK(Items.RAW_SHARK_383, 76, 110.0, 0.121, 0.16), + SEA_TURTLE(Items.RAW_SEA_TURTLE_395, 79, 38.0, 0.0, 0.0), + MANTA_RAY(Items.RAW_MANTA_RAY_389, 81, 46.0, 0.0, 0.0), + SEAWEED(Items.SEAWEED_401, 16, 1.0, 0.63, 0.219), + CASKET(Items.CASKET_405, 16, 10.0, 0.63, 0.219), + OYSTER(Items.OYSTER_407, 16, 10.0, 0.63, 0.219); + + companion object { + val fishMap: HashMap = HashMap() + val bigFishMap: HashMap = HashMap() + init { + for(fish in values()) { + fishMap[fish.id] = fish + } + bigFishMap[Fish.BASS] = Items.BIG_BASS_7989 + bigFishMap[Fish.SWORDFISH] = Items.BIG_SWORDFISH_7991 + bigFishMap[Fish.SHARK] = Items.BIG_SHARK_7993 + } + + @JvmStatic + fun forItem(item: Item) : Fish? { + return fishMap[item.id] + } + + @JvmStatic + fun getBigFish(fish: Fish) : Int? { + return bigFishMap[fish] + } + } + + fun getSuccessChance(level: Int): Double { + return (level.toDouble() - 1.0) * ((highChance - lowChance) / (99.0 - 1.0)) + lowChance + } + + fun getItem() : Item { + return this.id.asItem() + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fishing/FishSpots.kt b/Server/src/main/content/global/skill/fishing/FishSpots.kt new file mode 100644 index 0000000..937c555 --- /dev/null +++ b/Server/src/main/content/global/skill/fishing/FishSpots.kt @@ -0,0 +1,224 @@ +package content.global.skill.fishing + +import core.game.world.map.Location + +enum class FishSpots(vararg val locations: Location) { + CATHERBY( + Location(2844, 3429, 0), + Location(2839, 3431, 0), + Location(2836, 3431, 0), + Location(2837, 3431, 0), + Location(2838, 3431, 0), + Location(2839, 3431, 0), + Location(2840, 3431, 0), + Location(2844, 3429, 0), + Location(2845, 3429, 0), + Location(2846, 3429, 0), + Location(2853, 3423, 0), + Location(2854, 3423, 0), + Location(2855, 3423, 0), + Location(2859, 3426, 0), + Location(2860, 3426, 0) + ), + ENTRANA( + Location(2842, 3359, 0), + Location(2843, 3359, 0), + Location(2844, 3359, 0), + Location(2847, 3361, 0), + Location(2848, 3361, 0), + Location(2849, 3361, 0), + Location(2850, 3361, 0) + ), + ENTRANA_PLATFORM( + Location(2879, 3334, 0), + Location(2879, 3335, 0), + Location(2879, 3338, 0), + Location(2879, 3339, 0), + Location(2877, 3342, 0), + Location(2876, 3342, 0), + Location(2875, 3342, 0), + Location(2875, 3331, 0), + Location(2876, 3331, 0), + Location(2877, 3331, 0) + ), + SEERS( + Location(2714, 3533, 0), + Location(2714, 3532, 0), + Location(2726, 3524, 0), + Location(2727, 3524, 0), + Location(2728, 3524, 0) + ), + DRAYNOR( + Location(3085, 3230, 0), + Location(3086, 3227, 0) + ), + BARBARIAN( + Location(3110, 3432, 0), + Location(3110, 3433, 0), + Location(3110, 3434, 0), + Location(3104, 3425, 0), + Location(3104, 3424, 0) + ), + LUMBRIDGE( + Location(3239, 3243, 0), + Location(3239, 3241, 0), + Location(3239, 3242, 0), + Location(3238, 3251, 0), + Location(3238, 3252, 0), + Location(3238, 3253, 0) + ), + LUMBRIDGE_SWAMP( + Location(3242, 3143, 0), + Location(3242, 3148, 0), + Location(3241, 3148, 0), + Location(3240, 3147, 0), + Location(3240, 3146, 0), + Location(3244, 3150, 0), + Location(3245, 3152, 0), + Location(3246, 3155, 0), + Location(3246, 3156, 0), + Location(3239, 3241, 0) + ), + LUMBRIDGE_MARSH( + Location(3169, 3266, 0), + Location(3168, 3266, 0), + Location(3174, 3274, 0), + Location(3173, 3274, 0) + ), + ALKHARID( + Location(3267, 3148, 0), + Location(3268, 3147, 0), + Location(3276, 3140, 0), + Location(3275, 3140, 0) + ), + FISHING_GUILD( + Location(2612, 3411, 0), + Location(2602, 3423, 0), + Location(2602, 3411, 0), + Location(2602, 3412, 0), + Location(2602, 3414, 0), + Location(2602, 3415, 0), + Location(2603, 3417, 0), + Location(2604, 3417, 0), + Location(2605, 3416, 0), + Location(2606, 3416, 0), + Location(2607, 3416, 0), + Location(2608, 3416, 0), + Location(2609, 3416, 0), + Location(2610, 3416, 0), + Location(2611, 3416, 0), + Location(2612, 3415, 0), + Location(2612, 3414, 0), + Location(2607, 3410, 0), + Location(2606, 3410, 0), + Location(2605, 3410, 0), + Location(2599, 3419, 0), + Location(2600, 3419, 0), + Location(2602, 3419, 0), + Location(2603, 3419, 0), + Location(2604, 3419, 0), + Location(2605, 3420, 0), + Location(2605, 3421, 0), + Location(2604, 3422, 0), + Location(2603, 3422, 0), + Location(2602, 3422, 0), + Location(2601, 3422, 0), + Location(2605, 3424, 0), + Location(2605, 3425, 0), + Location(2602, 3426, 0), + Location(2603, 3426, 0), + Location(2604, 3426, 0) + ), + GNOME( + Location(2388, 3424, 0), + Location(2390, 3422, 0), + Location(2391, 3421, 0), + Location(2382, 3413, 0), + Location(2382, 3414, 0), + Location(2382, 3415, 0) + ), + CASTLEWAR( + Location(2465, 3156, 0), + Location(2464, 3155, 0), + Location(2468, 3157, 0), + Location(2469, 3157, 0), + Location(2471, 3158, 0), + Location(2472, 3156, 0), + Location(2462, 3145, 0), + Location(2461, 3150, 0), + Location(2461, 3151, 0) + ), + SHILO( + Location(2460, 3144, 0), + Location(2461, 3150, 0), + Location(2461, 3151, 0), + Location(2853, 2977, 0), + Location(2854, 2977, 0), + Location(2855, 2977, 0), + Location(2856, 2977, 0), + Location(2858, 2976, 0), + Location(2859, 2976, 0), + Location(2860, 2976, 0), + Location(2863, 2975, 0), + Location(2863, 2975, 0), + Location(2864, 2975, 0), + Location(2865, 2972, 0), + Location(2860, 2972, 0), + Location(2855, 2974, 0), + Location(2852, 2973, 0) + ), + KARAMJA( + Location(2923, 3178, 0), + Location(2923, 3179, 0), + Location(2923, 3180, 0), + Location(2924, 3181, 0), + Location(2925, 3181, 0), + Location(2926, 3180, 0), + Location(2926, 3179, 0), + Location(2926, 3178, 0), + Location(2926, 3177, 0), + Location(2926, 3176, 0) + ), + PISCATORIS( + Location(2341, 3702, 0), + Location(2342, 3702, 0), + Location(2343, 3702, 0), + Location(2344, 3702, 0), + Location(2345, 3702, 0), + Location(2346, 3702, 0), + Location(2347, 3702, 0), + Location(2349, 3702, 0), + Location(2352, 3703, 0) + ), + TUTORIAL_ISLAND( + Location(3101, 3092, 0) + ), + WILDERNESS_AREA( + Location(3187, 3927, 0), + Location(3185, 3926, 0), + Location(3183, 3926, 0), + Location(3181, 3926, 0) + ); + + companion object { + private val locs: ArrayList = ArrayList() + private val locMap: HashMap = HashMap() + init { + for(value in values()) { + for(loc in value.locations) { + locMap[loc] = value + locs.add(loc) + } + } + } + + @JvmStatic + fun forLocation(loc: Location): FishSpots? { + return if (locMap[loc] == null) { + TUTORIAL_ISLAND + } else { + locMap[loc] + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fishing/FishingNPC.kt b/Server/src/main/content/global/skill/fishing/FishingNPC.kt new file mode 100644 index 0000000..2af0ba8 --- /dev/null +++ b/Server/src/main/content/global/skill/fishing/FishingNPC.kt @@ -0,0 +1,55 @@ +package content.global.skill.fishing + +import core.api.* +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.tools.RandomFunction + +private val fishingSpots = FishingSpot.getAllIds() +class FishingNPC : NPCBehavior(*fishingSpots) { + + override fun onCreation(self: NPC) { + setAttribute(self, "fishing:spot", FishSpots.forLocation(self.location)) + setAttribute(self, "fishing:switchdelay", 0) + } + + override fun tick(self: NPC): Boolean { + if(getSpot(self) == null) { + return false + } + if(getAttribute(self, "fishing:switchdelay", 0) < getWorldTicks()) { + moveSpot(self) + return false + } + return false + } + + private fun moveSpot(self: NPC) { + when (val spot = getSpot(self)) { + null -> { + self.isInvisible = !self.isInvisible + setAttribute(self, "fishing:switchdelay", getWorldTicks() + getRandomDelay()) + return + } + FishSpots.TUTORIAL_ISLAND -> { + return + } + else -> { + val randLoc = spot.locations[RandomFunction.random(spot.locations.size)] + if(findLocalNPCs(randLoc, 0).isEmpty()) { + teleport(self, randLoc) + } + setAttribute(self, "fishing:switchdelay", getWorldTicks() + getRandomDelay()) + } + } + } + + private fun getRandomDelay(): Int { + return RandomFunction.random(200, 390) + } + + private fun getSpot(npc: NPC): FishSpots? { + return getAttribute(npc, "fishing:spot", null) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fishing/FishingOption.kt b/Server/src/main/content/global/skill/fishing/FishingOption.kt new file mode 100644 index 0000000..b75ccf9 --- /dev/null +++ b/Server/src/main/content/global/skill/fishing/FishingOption.kt @@ -0,0 +1,104 @@ +package content.global.skill.fishing + +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.world.update.flag.context.Animation +import core.tools.RandomFunction +import org.rs09.consts.Items + +enum class FishingOption(val tool: Int, val level: Int, val animation: Animation, val bait: IntArray?, val option: String, vararg val fish: Fish) { + CRAYFISH_CAGE(Items.CRAYFISH_CAGE_13431, 1, Animation(10009), null, "cage", Fish.CRAYFISH), + SMALL_NET(Items.SMALL_FISHING_NET_303, 1, Animation(621), null, "net", Fish.SHRIMP, Fish.ANCHOVIE), + BAIT(Items.FISHING_ROD_307, 5, Animation(622), intArrayOf(Items.FISHING_BAIT_313), "bait", Fish.SARDINE, Fish.HERRING), + LURE(Items.FLY_FISHING_ROD_309, 20, Animation(622), intArrayOf(Items.FEATHER_314, Items.STRIPY_FEATHER_10087), "lure", Fish.TROUT, Fish.SALMON, Fish.RAINBOW_FISH), + PIKE_BAIT(Items.FISHING_ROD_307, 25, Animation(622), intArrayOf(Items.FISHING_BAIT_313), "bait", Fish.PIKE), + LOBSTER_CAGE(Items.LOBSTER_POT_301, 40, Animation(619), null, "cage", Fish.LOBSTER), + HARPOON(Items.HARPOON_311, 35, Animation(618), null, "harpoon", Fish.TUNA, Fish.SWORDFISH), + BARB_HARPOON(Items.BARB_TAIL_HARPOON_10129, 35, Animation(618), null, "harpoon", Fish.TUNA, Fish.SWORDFISH), + BIG_NET(Items.BIG_FISHING_NET_305, 16, Animation(620), null, "net", Fish.MACKEREL, Fish.COD, Fish.BASS, Fish.SEAWEED), + SHARK_HARPOON(Items.HARPOON_311, 76, Animation(618), null, "harpoon", Fish.SHARK), + MONKFISH_NET(Items.SMALL_FISHING_NET_303, 62, Animation(621), null, "net", Fish.MONKFISH), + MORTMYRE_ROD(Items.FISHING_ROD_307, 5, Animation(622), intArrayOf(Items.FISHING_BAIT_313), "bait", Fish.SLIMY_EEL), + LUMBDSWAMP_ROD(Items.FISHING_ROD_307, 5, Animation(622), intArrayOf(Items.FISHING_BAIT_313), "bait", Fish.SLIMY_EEL, Fish.CAVE_EEL), + LUMBDSWAMP_NET(Items.SMALL_FISHING_NET_303, 1, Animation(621), null, "net", Fish.FROG_SPAWN), + KBWANJI_NET(Items.SMALL_FISHING_NET_303, 5, Animation(621), null, "net", Fish.KARAMBWANJI), + KARAMBWAN_VES(Items.KARAMBWAN_VESSEL_3157, 65, Animation(1193), intArrayOf((Items.RAW_KARAMBWANJI_3150)), "fish", Fish.KARAMBWAN), + OILY_FISHING_ROD(Items.OILY_FISHING_ROD_1585, 53, Animation(622), intArrayOf(Items.FISHING_BAIT_313), "bait", Fish.LAVA_EEL); + + companion object { + private val nameMap: HashMap = HashMap() + + init { + for(value in values()) { + nameMap[value.option] = value + } + } + + fun forName(opName: String): FishingOption? { + return nameMap[opName] + } + } + + fun rollFish(player: Player): Fish? { + if(this == BIG_NET) { + when(RandomFunction.randomize(100)) { + 0 -> return Fish.OYSTER + 50 -> return Fish.CASKET + 90 -> return Fish.SEAWEED + } + } + val vlvl = getDynLevel(player, Skills.FISHING) + val ilvl = vlvl + player.familiarManager.getBoost(Skills.FISHING) + for(f in fish) { + if(f.level > vlvl) { + continue + } + if(this == LURE && inInventory(player, Items.STRIPY_FEATHER_10087) != (f == Fish.RAINBOW_FISH)) { + continue + } + val chance = f.getSuccessChance(ilvl) + if(RandomFunction.random(0.0, 1.0) < chance) { + return f + } + } + return null + } + + fun getBaitName(): String { + if(bait != null && bait.isNotEmpty()) { + return getItemName(bait[0]) + } + return "none" + } + + fun hasBait(player: Player): Boolean { + return if(bait == null) true else { + var anyBait = false + for(b in bait) { + anyBait = anyBait || inInventory(player, b) + } + anyBait + } + } + + fun removeBait(player: Player): Boolean { + return if (bait == null) { + true + } else { + for (i in bait.size downTo 1) { + if (removeItem(player, bait[i - 1], Container.INVENTORY)) { + return true + } + } + false + } + } + + fun getStartMessage(): String { + return if(option == "net") + "You cast out your net..." + else + "You attempt to catch a fish." + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fishing/FishingSpot.kt b/Server/src/main/content/global/skill/fishing/FishingSpot.kt new file mode 100644 index 0000000..e60dcb9 --- /dev/null +++ b/Server/src/main/content/global/skill/fishing/FishingSpot.kt @@ -0,0 +1,165 @@ +package content.global.skill.fishing + +import org.rs09.consts.NPCs + +enum class FishingSpot(val ids: IntArray, vararg val options: FishingOption) { + NET_BAIT( + intArrayOf( + NPCs.FISHING_SPOT_952, + NPCs.FISHING_SPOT_316, + NPCs.FISHING_SPOT_319, + NPCs.FISHING_SPOT_320, + NPCs.FISHING_SPOT_323, + NPCs.FISHING_SPOT_325, + NPCs.FISHING_SPOT_326, + NPCs.FISHING_SPOT_327, + NPCs.FISHING_SPOT_330, + NPCs.FISHING_SPOT_332, + NPCs.FISHING_SPOT_404, + NPCs.FISHING_SPOT_1331, + NPCs.FISHING_SPOT_2724, + NPCs.FISHING_SPOT_4908, + NPCs.FISHING_SPOT_7045 + ), + FishingOption.SMALL_NET, + FishingOption.BAIT + ), + CAGE( + intArrayOf( + NPCs.FISHING_SPOT_6267, + NPCs.FISHING_SPOT_6996, + NPCs.FISHING_SPOT_7862, + NPCs.FISHING_SPOT_7863, + NPCs.FISHING_SPOT_7864 + ), + FishingOption.CRAYFISH_CAGE + ), + LURE_BAIT( + intArrayOf( + NPCs.FISHING_SPOT_309, + NPCs.FISHING_SPOT_310, + NPCs.FISHING_SPOT_311, + NPCs.FISHING_SPOT_314, + NPCs.FISHING_SPOT_315, + NPCs.FISHING_SPOT_317, + NPCs.FISHING_SPOT_318, + NPCs.FISHING_SPOT_328, + NPCs.FISHING_SPOT_329, + NPCs.FISHING_SPOT_331, + NPCs.FISHING_SPOT_403, + NPCs.FISHING_SPOT_927, + NPCs.FISHING_SPOT_1189, + NPCs.FISHING_SPOT_1190, + NPCs.FISHING_SPOT_3019 + ), + FishingOption.LURE, + FishingOption.PIKE_BAIT + ), + CAGE_HARPOON( + intArrayOf( + NPCs.FISHING_SPOT_312, + NPCs.FISHING_SPOT_321, + NPCs.FISHING_SPOT_324, + NPCs.FISHING_SPOT_333, + NPCs.FISHING_SPOT_405, + NPCs.FISHING_SPOT_1332, + NPCs.FISHING_SPOT_1399, + NPCs.FISHING_SPOT_3804, + NPCs.FISHING_SPOT_5470, + NPCs.FISHING_SPOT_7046 + ), + FishingOption.LOBSTER_CAGE, + FishingOption.HARPOON + ), + NET_HARPOON( + intArrayOf( + NPCs.FISHING_SPOT_313, + NPCs.FISHING_SPOT_322, + NPCs.FISHING_SPOT_334, + NPCs.FISHING_SPOT_406, + NPCs.FISHING_SPOT_1191, + NPCs.FISHING_SPOT_1333, + NPCs.FISHING_SPOT_1405, + NPCs.FISHING_SPOT_1406, + NPCs.FISHING_SPOT_3574, + NPCs.FISHING_SPOT_3575, + NPCs.FISHING_SPOT_5471, + NPCs.FISHING_SPOT_7044 + ), + FishingOption.BIG_NET, + FishingOption.SHARK_HARPOON + ), + HARPOON_NET( + intArrayOf( + NPCs.FISHING_SPOT_3848, + NPCs.FISHING_SPOT_3849 + ), + FishingOption.HARPOON, + FishingOption.MONKFISH_NET + ), + SPOT_MORTMYRE( + intArrayOf( + NPCs.FISHING_SPOT_5748, + NPCs.FISHING_SPOT_5749 + ), + FishingOption.MORTMYRE_ROD + ), + SPOT_LUMDSWAMP( + intArrayOf( + NPCs.FISHING_SPOT_2067, + NPCs.FISHING_SPOT_2068 + ), + FishingOption.LUMBDSWAMP_NET, + FishingOption.LUMBDSWAMP_ROD + ), + SPOT_KBWANJI( + intArrayOf( + NPCs.FISHING_SPOT_1174 + ), + FishingOption.KBWANJI_NET + ), + SPOT_KARAMBWAN( + intArrayOf( + NPCs.FISHING_SPOT_1177 + ), + FishingOption.KARAMBWAN_VES + ), + BAIT_EELS( + intArrayOf( + NPCs.FISHING_SPOT_800 + ), + FishingOption.OILY_FISHING_ROD + ); + + companion object { + private val spotMap: HashMap = HashMap() + private val array: ArrayList = ArrayList() + + init { + val spots = values() + for(spot in spots) { + for(id in spot.ids) { + spotMap[id] = spot + array.add(id) + } + } + } + + fun forId(npcID: Int) : FishingSpot? { + return spotMap[npcID] + } + + fun getAllIds() : IntArray { + return array.toIntArray() + } + } + + fun getOptionByName(op: String) : FishingOption? { + for(o in options) { + if(o.option == op.lowercase()) { + return o + } + } + return null + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/Fletching.java b/Server/src/main/content/global/skill/fletching/Fletching.java new file mode 100644 index 0000000..3a6c690 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/Fletching.java @@ -0,0 +1,355 @@ +package content.global.skill.fletching; + +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; + +import java.util.HashMap; +public class Fletching { + public static HashMaplogMap = new HashMap<>(); + public static HashMap boltMap = new HashMap<>(); + public static HashMap dartMap = new HashMap<>(); + public static HashMap arrowHeadMap = new HashMap<>(); + public static HashMap gemMap = new HashMap<>(); + public static HashMap tipMap = new HashMap<>(); + public static HashMap stringMap = new HashMap<>(); + public static HashMap limbMap = new HashMap<>(); + static{ + Items[] itemsArray = Items.values(); + int thisLength = itemsArray.length; + for(int x = 0; x < thisLength; x++){ + Items item = itemsArray[x]; + logMap.putIfAbsent(item.id, item.items); + } + Bolts[] boltArray = Bolts.values(); + thisLength = boltArray.length; + for(int x = 0; x < thisLength; x++){ + Bolts bolt = boltArray[x]; + boltMap.putIfAbsent(bolt.unfinished,bolt); + } + Darts[] dartArray = Darts.values(); + thisLength = dartArray.length; + for(int x = 0; x < thisLength; x++){ + Darts dart = dartArray[x]; + dartMap.putIfAbsent(dart.unfinished,dart); + } + ArrowHeads[] ahArray = ArrowHeads.values(); + thisLength = ahArray.length; + for(int x = 0; x < thisLength; x++){ + ArrowHeads arrowhead = ahArray[x]; + arrowHeadMap.putIfAbsent(arrowhead.unfinished,arrowhead); + } + GemBolts[] gbArray = GemBolts.values(); + thisLength = gbArray.length; + for(int x = 0; x < thisLength; x++){ + GemBolts gem = gbArray[x]; + gemMap.putIfAbsent(gem.gem,gem); + tipMap.putIfAbsent(gem.tip,gem); + } + String[] stringArray = String.values(); + thisLength = stringArray.length; + for(int x = 0; x < thisLength; x++){ + String bow = stringArray[x]; + stringMap.putIfAbsent(bow.unfinished,bow); + } + Limb[] limbsArray = Limb.values(); + thisLength = limbsArray.length; + for(int x = 0; x < thisLength; x++){ + Limb limb = limbsArray[x]; + limbMap.putIfAbsent(limb.stock, limb); + } + } + public static FletchingItems[] getEntries(int id){ + return logMap.get(id); + } + public static boolean isLog(int id){ + return logMap.get(id) != null; + } + public static boolean isBolt(int id){ + return boltMap.get(id) != null; + } + public static boolean isDart(int id){ + return dartMap.get(id) != null; + } + public static boolean isArrowHead(int id){ + return arrowHeadMap.get(id) != null; + } + public static boolean isGemTip(int id){ + return tipMap.get(id) != null; + } + public static Item[] getItems(int id){ + FletchingItems[] entry = getEntries(id); + Item items[] = {}; + switch(entry.length){ + case 1: + items = new Item[] {new Item(entry[0].id)}; + break; + case 2: + items = new Item[] {new Item(entry[0].id), new Item(entry[1].id)}; + break; + case 3: + items = new Item[] {new Item(entry[0].id), new Item(entry[1].id), new Item(entry[2].id)}; + break; + case 4: + items = new Item[] {new Item(entry[0].id), new Item(entry[1].id), new Item(entry[2].id), new Item(entry[3].id)}; + break; + } + return items; + } + public enum Limb { + WOODEN_STOCK(9440,9420,9454,9, 12, new Animation(4436)), + OAK_STOCK(9442,9422,9456,24, 32, new Animation(4437)), + WILLOW_STOCK(9444,9423,9457,39, 44, new Animation(4438)), + TEAK_STOCK(9446,9425,9459,46, 54, new Animation(4439)), + MAPLE_STOCK(9448,9427,9461,54, 64, new Animation(4440)), + MAHOGANY_STOCK(9450,9429,9463,61, 82, new Animation(4441)), + YEW_STOCK(9452,9431,9465,69, 100, new Animation(4442)); + + + public int stock, limb, product,level; + public double experience; + public Animation animation; + + Limb(int stock, int limb, int product, int level, double experience, Animation animation) { + this.stock = stock; + this.limb = limb; + this.product = product; + this.level = level; + this.experience = experience; + this.animation = animation; + } + } + public enum String{ + //Bows + SHORT_BOW((byte) 1,50,841,5, 5, new Animation(6678)), + LONG_BOW((byte) 1,48,839,10, 10, new Animation(6684)), + OAK_SHORTBOW((byte) 1,54,843,20, 16.5, new Animation(6679)), + OAK_LONGBOW((byte) 1,56,845,25, 25, new Animation(6685)), + WILLOW_SHORTBOW((byte) 1,60,849,35, 33.3, new Animation(6680)), + WILLOW_LONGBOW((byte) 1,58,847,40, 41.5, new Animation(6686)), + MAPLE_SHORTBOW((byte) 1,64,853,50, 50, new Animation(6681)), + MAPLE_LONGBOW((byte) 1,62,851,55, 58.3, new Animation(6687)), + YEW_SHORTBOW((byte) 1,68,857,65, 67.5, new Animation(6682)), + YEW_LONGBOW((byte) 1,66,855,70, 75, new Animation(6688)), + MAGIC_SHORTBOW((byte) 1,72,861,80, 83.3, new Animation(6683)), + MAGIC_LONGBOW((byte) 1,70,859,85, 91.5, new Animation(6689)), + OGRE_COMP_BOW((byte) 1,4825,4827,30, 45, new Animation(-1)), + + //crossbows + BRONZE_CBOW((byte) 2,9454,9174,9, 6, new Animation(6671)), + BLURITE_CBOW((byte) 2,9456,9176,24, 16, new Animation(6672)), + IRON_CBOW((byte) 2,9457,9177,39, 22, new Animation(6673)), + STEEL_CBOW((byte) 2,9459,9179,46, 27, new Animation(6674)), + MITHIRIL_CBOW((byte) 2,9461,9181,54, 32, new Animation(6675)), + ADAMANT_CBOW((byte) 2,9463,9183,61, 41, new Animation(6676)), + RUNITE_CBOW((byte) 2,9465,9185,69, 50, new Animation(6677)); + + + public int unfinished,product,string,level; + public final double experience; + public final Animation animation; + String(byte indicator, final int unfinished, final int product, final int level, final double experience, final Animation animation) { + this.unfinished = unfinished; + this.product = product; + this.level = level; + this.experience = experience; + this.animation = animation; + switch(indicator & 0xFF){ + case 1: + this.string = org.rs09.consts.Items.BOW_STRING_1777; + break; + case 2: + this.string = org.rs09.consts.Items.CROSSBOW_STRING_9438; + break; + default: + break; + } + } + } + public enum GemBolts { + OPAL(877, org.rs09.consts.Items.OPAL_1609, 45, 879, 11, 1.6), + PEARL(9140, org.rs09.consts.Items.OYSTER_PEARL_411, 46, 880, 41, 3.2), + PEARLS(9140, org.rs09.consts.Items.OYSTER_PEARLS_413, 46, 880, 41, 3.2), + JADE(9139, org.rs09.consts.Items.JADE_1611, 9187, 9335, 26, 2.4), + RED_TOPAZ(9141, org.rs09.consts.Items.RED_TOPAZ_1613, 9188, 9336, 48, 3.9), + SAPPHIRE(9142, org.rs09.consts.Items.SAPPHIRE_1607, 9189, 9337, 56, 4.7), + EMERALD(9142, org.rs09.consts.Items.EMERALD_1605, 9190, 9338, 58, 5.5), + RUBY(9143, org.rs09.consts.Items.RUBY_1603, 9191, 9339, 63, 6.3), + DIAMOND(9143, org.rs09.consts.Items.DIAMOND_1601, 9192, 9340, 65, 7), + DRAGONSTONE(9144, org.rs09.consts.Items.DRAGONSTONE_1615, 9193, 9341, 71, 8.2), + ONYX(9144, org.rs09.consts.Items.ONYX_6573, 9194, 9342, 73, 9.4); + + public int gem,tip,base,product,level; + public double experience; + GemBolts(int base, int gem, int tip, int product, int level, double experience){ + this.gem = gem; + this.tip = tip; + this.base = base; + this.product = product; + this.level = level; + this.experience = experience; + } + + } + public enum ArrowHeads { + BRONZE_ARROW(39, 882, 1, 1.3), + IRON_ARROW(40, 884, 15, 2.5), + STEEL_ARROW(41, 886, 30, 5), + MITHRIL_ARROW(42, 888, 45, 7.5), + ADAMANT_ARROW(43, 890, 60, 10), + RUNE_ARROW(44, 892, 75, 12.5), + DRAGON_ARROW(11237, 11212, 90, 15), + BROAD_ARROW(13278, 4160, 52, 15); + + public int unfinished,finished,level; + public double experience; + ArrowHeads(int unfinished, int finished, int level, double experience){ + this.unfinished = unfinished; + this.finished = finished; + this.level = level; + this.experience = experience; + } + public Item getFinished(){ + return new Item(finished); + } + public Item getUnfinished(){ + return new Item(unfinished); + } + } + public enum Darts{ + BRONZE_DART(819, 806, 1, 1.8), + IRON_DART(820, 807, 22, 3.8), + STEEL_DART(821, 808, 37, 7.5), + MITHRIL_DART(822, 809, 52, 11.2), + ADAMANT_DART(823, 810, 67, 15), + RUNE_DART(824, 811, 81, 18.8), + DRAGON_DART(11232, 11230, 95, 25); + + public int unfinished, finished, level; + public double experience; + Darts(int unfinished, int finished, int level, double experience){ + this.unfinished = unfinished; + this.finished = finished; + this.level = level; + this.experience = experience; + } + public Item getFinished(){ + return new Item(finished); + } + public Item getUnfinished(){ + return new Item(unfinished); + } + } + public enum Bolts{ + BRONZE_BOLT(9375, 877, 9, 0.5), + BLURITE_BOLT(9376, 9139, 24, 1), + IRON_BOLT(9377, 9140, 39, 1.5), + SILVER_BOLT(9382, 9145, 43, 2.5), + STEEL_BOLT(9378, 9141, 46, 3.5), + MITHRIL_BOLT(9379, 9142, 54, 5), + ADAMANTITE_BOLT(9380, 9143, 61, 7), + RUNITE_BOLT(9381, 9144, 69, 10), + BROAD_BOLT(13279, 13280, 55, 3); + + public int unfinished, finished, level; + public double experience; + Bolts(int unfinished, int finished, int level, double experience){ + this.unfinished = unfinished; + this.finished = finished; + this.level = level; + this.experience = experience; + } + public Item getFinished(){ + return new Item(finished); + } + public Item getUnfinished(){ + return new Item(unfinished); + } + } + private enum Items{ + STANDARD(1511,FletchingItems.ARROW_SHAFT, FletchingItems.SHORT_BOW, FletchingItems.LONG_BOW, FletchingItems.WOODEN_STOCK), + ACHEY(2862, FletchingItems.OGRE_ARROW_SHAFT, FletchingItems.OGRE_COMP_BOW), + OAK(1521, FletchingItems.OAK_SHORTBOW, FletchingItems.OAK_LONGBOW, FletchingItems.OAK_STOCK), + WILLOW(1519, FletchingItems.WILLOW_SHORTBOW, FletchingItems.WILLOW_LONGBOW, FletchingItems.WILLOW_STOCK), + MAPLE(1517, FletchingItems.MAPLE_SHORTOW, FletchingItems.MAPLE_LONGBOW, FletchingItems.MAPLE_STOCK), + YEW(1515, FletchingItems.YEW_SHORTBOW, FletchingItems.YEW_LONGBOW, FletchingItems.YEW_STOCK), + MAGIC(1513, FletchingItems.MAGIC_SHORTBOW, FletchingItems.MAGIC_LONGBOW), + TEAK(6333, FletchingItems.TEAK_STOCK), + MAHOGANY(6332, FletchingItems.MAHOGANY_STOCK); + + + FletchingItems[] items; + int id; + Items(int id, FletchingItems item_1, FletchingItems item_2, FletchingItems item_3, FletchingItems item_4){ + items = new FletchingItems[] {item_1, item_2, item_3, item_4}; + this.id = id; + } + Items(int id, FletchingItems item_1, FletchingItems item_2, FletchingItems item_3){ + items = new FletchingItems[] {item_1, item_2, item_3}; + this.id = id; + } + Items(int id, FletchingItems item_1, FletchingItems item_2){ + items = new FletchingItems[] {item_1, item_2}; + this.id = id; + } + Items(int id, FletchingItems item_1){ + items = new FletchingItems[] {item_1}; + this.id = id; + } + } + public enum FletchingItems { + //Standard logs + ARROW_SHAFT(52, 5, 1, 15), + SHORT_BOW(50, 5, 5, 1), + LONG_BOW(48, 10, 10, 1), + WOODEN_STOCK(9440, 6, 9, 1), + + //Achey logs + OGRE_ARROW_SHAFT(2864, 6.4, 5, 4), + OGRE_COMP_BOW(4825, 45, 30, 1), + + //Oak logs + OAK_SHORTBOW(54, 16.5, 20, 1), + OAK_LONGBOW(56,25,25,1), + OAK_STOCK(9442, 16, 24, 1), + + //Willow logs + WILLOW_SHORTBOW(60, 33.3, 35, 1), + WILLOW_LONGBOW(58, 41.5, 40, 1), + WILLOW_STOCK(9444, 22, 39, 1), + + //Maple logs + MAPLE_SHORTOW(64, 50, 50, 1), + MAPLE_LONGBOW(62, 58.3, 55, 1), + MAPLE_STOCK(9448, 32, 54, 1), + + //Yew logs + YEW_SHORTBOW(68, 67.5, 65, 1), + YEW_LONGBOW(66, 75, 70, 1), + YEW_STOCK(9452, 50, 69, 1), + + //Magic logs + MAGIC_SHORTBOW(72, 83.3, 80,1), + MAGIC_LONGBOW(70, 91.5, 85, 1), + + //Teak + TEAK_STOCK(9446, 27, 46,1), + + //Mahogany + MAHOGANY_STOCK(9450, 41.0, 61, 1); + + + int id,level,amount,logId; + double experience; + FletchingItems(int id, double experience, int level, int amount){ + this.id = id; + this.level = level; + this.amount = amount; + this.experience = experience; + } + + public Item getItem(){ + return new Item(id); + } + } + +} diff --git a/Server/src/main/content/global/skill/fletching/FletchingListeners.kt b/Server/src/main/content/global/skill/fletching/FletchingListeners.kt new file mode 100644 index 0000000..464a0b6 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/FletchingListeners.kt @@ -0,0 +1,197 @@ +package content.global.skill.fletching + +import content.data.Quests +import content.global.skill.fletching.items.arrow.ArrowHeadPulse +import content.global.skill.fletching.items.arrow.HeadlessArrowPulse +import content.global.skill.fletching.items.arrow.HeadlessOgreArrowPulse +import content.global.skill.fletching.items.bow.StringPulse +import content.global.skill.fletching.items.crossbow.LimbPulse +import core.api.* +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.net.packet.PacketRepository +import core.net.packet.context.ChildPositionContext +import core.net.packet.out.RepositionChild +import org.rs09.consts.Components +import org.rs09.consts.Items +import org.rs09.consts.Items.BLUE_FEATHER_10089 +import org.rs09.consts.Items.FEATHER_314 +import org.rs09.consts.Items.ORANGE_FEATHER_10091 +import org.rs09.consts.Items.RED_FEATHER_10088 +import org.rs09.consts.Items.STRIPY_FEATHER_10087 +import org.rs09.consts.Items.YELLOW_FEATHER_10090 +import core.game.dialogue.SkillDialogueHandler +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.game.node.entity.player.Player + +class FletchingListeners : InteractionListener { + + val LIMBIDs = Fletching.Limb.values().map(Fletching.Limb::limb).toIntArray() + val STOCKIDs = Fletching.Limb.values().map(Fletching.Limb::stock).toIntArray() + val MITHRIL_BOLT = Items.MITHRIL_BOLTS_9142 + val MITH_GRAPPLE_TIP = Items.MITH_GRAPPLE_TIP_9416 + val ROPE = Items.ROPE_954 + val MITH_GRAPPLE = Items.MITH_GRAPPLE_9418 + val ROPE_GRAPPLE = Items.MITH_GRAPPLE_9419 + val ARROW_SHAFT = Items.ARROW_SHAFT_52 + val OGRE_ARROW_SHAFT = Items.OGRE_ARROW_SHAFT_2864 + val FLETCHED_SHAFT = Items.HEADLESS_ARROW_53 + val FLIGHTED_OGRE_ARROW = Items.FLIGHTED_OGRE_ARROW_2865 + val UNFINISHED_ARROWS = Fletching.ArrowHeads.values().map(Fletching.ArrowHeads::unfinished).toIntArray() + val FEATHERS = intArrayOf(FEATHER_314,STRIPY_FEATHER_10087,RED_FEATHER_10088,BLUE_FEATHER_10089,YELLOW_FEATHER_10090,ORANGE_FEATHER_10091) + val UNSTRUNG_BOWS = Fletching.String.values().map(Fletching.String::unfinished).toIntArray() + val STRINGS = intArrayOf(Items.BOW_STRING_1777,Items.CROSSBOW_STRING_9438) + + override fun defineListeners() { + + onUseWith(IntType.ITEM,STRINGS,*UNSTRUNG_BOWS){ player, string, bow -> + val enum = Fletching.stringMap[bow.id] ?: return@onUseWith false + + if (bow.id == Items.UNSTRUNG_COMP_BOW_4825) { + // You shouldn't be able to string a bow + if (getQuestStage(player, Quests.ZOGRE_FLESH_EATERS) < 8) { + player.packetDispatch.sendMessage("You must have started Zogre Flesh Eaters and asked Grish to string this.") + return@onUseWith true + } + } + if(enum.string != string.id){ + player.sendMessage("That's not the right kind of string for this.") + return@onUseWith true + } + val handler: SkillDialogueHandler = + object : SkillDialogueHandler(player, SkillDialogue.ONE_OPTION, Item(enum.product)) { + override fun create(amount: Int, index: Int) { + player.pulseManager.run(StringPulse(player, string.asItem(), enum, amount)) + } + + override fun getAll(index: Int): Int { + return player.inventory.getAmount(string.asItem()) + } + } + handler.open() + PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, Components.SKILL_MULTI1_309, 2, 215, 10)) + return@onUseWith true + } + + onUseWith(IntType.ITEM,ARROW_SHAFT,*FEATHERS){ player, shaft, feather -> + val handler: SkillDialogueHandler = + object : SkillDialogueHandler(player, SkillDialogue.MAKE_SET_ONE_OPTION, Item(FLETCHED_SHAFT)) { + override fun create(amount: Int, index: Int) { + player.pulseManager.run(HeadlessArrowPulse(player, shaft.asItem(), Item(feather.id), amount)) + } + + override fun getAll(index: Int): Int { + return player.inventory.getAmount(FLETCHED_SHAFT) + } + } + handler.open() + return@onUseWith true + } + + onUseWith(IntType.ITEM,OGRE_ARROW_SHAFT,*FEATHERS){ player, shaft, feather -> + val handler: SkillDialogueHandler = + object : SkillDialogueHandler(player, SkillDialogue.MAKE_SET_ONE_OPTION, Item(FLIGHTED_OGRE_ARROW)) { + override fun create(amount: Int, index: Int) { + player.pulseManager.run(HeadlessOgreArrowPulse(player, shaft.asItem(), Item(feather.id, 4), amount)) + } + + override fun getAll(index: Int): Int { + return player.inventory.getAmount(FLIGHTED_OGRE_ARROW) + } + } + handler.open() + return@onUseWith true + } + + onUseWith(IntType.ITEM,FLETCHED_SHAFT,*UNFINISHED_ARROWS){ player, shaft, unfinished -> + val head = Fletching.arrowHeadMap[unfinished.id] ?: return@onUseWith false + val handler: SkillDialogueHandler = + object : SkillDialogueHandler(player, SkillDialogue.MAKE_SET_ONE_OPTION, head.getFinished()) { + override fun create(amount: Int, index: Int) { + player.pulseManager.run(ArrowHeadPulse(player, shaft.asItem(), head, amount)) + } + + override fun getAll(index: Int): Int { + return player.inventory.getAmount(head.getUnfinished()) + } + } + handler.open() + return@onUseWith true + } + + onUseWith(IntType.ITEM,MITHRIL_BOLT,MITH_GRAPPLE_TIP){ player, bolt, tip -> + if(player.skills.getLevel(Skills.FLETCHING) < 59){ + player.sendMessage("You need a fletching level of 59 to make this.") + return@onUseWith true + } + if(player.inventory.remove(Item(MITHRIL_BOLT,1),tip.asItem())){ + player.inventory.add(Item(MITH_GRAPPLE)) + } + return@onUseWith true + } + + onUseWith(IntType.ITEM,ROPE,MITH_GRAPPLE){ player, rope, grapple -> + if(player.skills.getLevel(Skills.FLETCHING) < 59){ + player.sendMessage("You need a fletching level of 59 to make this.") + return@onUseWith true + } + if(player.inventory.remove(rope.asItem(),grapple.asItem())){ + player.inventory.add(Item(ROPE_GRAPPLE)) + } + return@onUseWith true + } + + onUseWith(IntType.ITEM,LIMBIDs,*STOCKIDs){ player, limb, stock -> + val limbEnum = Fletching.limbMap[stock.id] ?: return@onUseWith false + if(limbEnum.limb != limb.id){ + player.sendMessage("That's not the right limb to attach to that stock.") + return@onUseWith true + } + val handler: SkillDialogueHandler = object : SkillDialogueHandler(player, SkillDialogue.ONE_OPTION, Item(limbEnum.product)){ + override fun create(amount: Int, index: Int) { + player.pulseManager.run(LimbPulse(player, stock.asItem(), limbEnum, amount)) + } + + override fun getAll(index: Int): Int { + return player.inventory.getAmount(stock.asItem()) + } + } + handler.open() + PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, Components.SKILL_MULTI1_309, 2, 210, 10)) + return@onUseWith true + } + + /** + * (Long) Kebbit bolts don't need feathers and go 6 at a time so use their own interaction + */ + fun makeKebbitBolt(player : Player, ingredient : Item) : Boolean{ + val longBolts = when(ingredient.id){ + Items.KEBBIT_SPIKE_10105 -> false + Items.LONG_KEBBIT_SPIKE_10107 -> true + else -> return false + } + val level = if(longBolts) 42 else 26 + if (getDynLevel(player, Skills.FLETCHING) < level){ + sendMessage(player, "You need a fletching level of $level to create ${if (longBolts) "long " else ""}kebbit bolts.") + return true + } + val finalProduct = if(longBolts) Items.LONG_KEBBIT_BOLTS_10159 else Items.KEBBIT_BOLTS_10158 + val xp = if(longBolts) 47.7 else 28.6 // source https://runescape.wiki/w/Fletching?oldid=1069981#Bolts_2 + if(removeItem(player, ingredient.id)){ + addItem(player, finalProduct, 6) + player.skills.addExperience(Skills.FLETCHING, xp) + animate(player, 885) + } + return true + } + onUseWith(IntType.ITEM, Items.CHISEL_1755, Items.KEBBIT_SPIKE_10105) { player, used, with -> + return@onUseWith makeKebbitBolt(player, with as Item) + } + + onUseWith(IntType.ITEM, Items.CHISEL_1755, Items.LONG_KEBBIT_SPIKE_10107) { player, used, with -> + return@onUseWith makeKebbitBolt(player, with as Item) + } + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/FletchingPlugin.java b/Server/src/main/content/global/skill/fletching/FletchingPlugin.java new file mode 100644 index 0000000..3ec1228 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/FletchingPlugin.java @@ -0,0 +1,131 @@ +package content.global.skill.fletching; + +import content.global.skill.fletching.items.bolts.BoltPulse; +import content.global.skill.fletching.items.darts.DartPulse; +import org.rs09.consts.Items; +import core.game.dialogue.SkillDialogueHandler; +import core.game.dialogue.SkillDialogueHandler.SkillDialogue; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.net.packet.PacketRepository; +import core.net.packet.context.ChildPositionContext; +import core.net.packet.out.RepositionChild; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the plugin used to open the fletching dialogue. + * @author Ceikry + */ +@Initializable +public class FletchingPlugin extends UseWithHandler { + + public FletchingPlugin() { + super(819,820,821,822,823,824,11232,9375,9376,9377,9382,9378,9379,9380,9381,13279,1511,1521,1519,1517,1515,1513,2862,6332,6333, Items.MAHOGANY_LOGS_6332); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + // Knife + addHandler(946, ITEM_TYPE, this); + + // Feathers plus colored feathers + addHandler(314, ITEM_TYPE,this); + addHandler(10087, ITEM_TYPE, this); + addHandler(10088, ITEM_TYPE, this); + addHandler(10089, ITEM_TYPE, this); + addHandler(10090, ITEM_TYPE, this); + addHandler(10091, ITEM_TYPE, this); + + return this; + } + + @Override + public boolean handle(final NodeUsageEvent event) { + final Player player = event.getPlayer(); + + //handle darts + if(Fletching.isDart(event.getUsedItem().getId())){ + final Fletching.Darts dart = Fletching.dartMap.get(event.getUsedItem().getId()); + SkillDialogueHandler handler = new SkillDialogueHandler(player, SkillDialogue.MAKE_SET_ONE_OPTION, dart.getFinished()) { + @Override + public void create(final int amount, int index) { + player.getPulseManager().run(new DartPulse(player, event.getUsedItem(), dart, amount)); + } + @Override + public int getAll(int index) { + return player.getInventory().getAmount(event.getUsedItem()); + } + }; + handler.open(); + return true; + } + + //handle bolts + if(Fletching.isBolt(event.getUsedItem().getId()) || Fletching.isBolt(event.getUsedWith().getId())){ + // figure out which of the used items is a bolt, and which is potentially a feather + final Fletching.Bolts bolt + = Fletching.isBolt(event.getUsedItem().getId()) + ? Fletching.boltMap.get(event.getUsedItem().getId()) + : Fletching.boltMap.get(event.getUsedWith().getId()); + final int featherId + = Fletching.isBolt(event.getUsedItem().getId()) + ? event.getUsedWith().getId() + : event.getUsedItem().getId(); + final boolean hasFeather = (featherId == 314 || (featherId >= 10087 && featherId <= 10091)); + + if (hasFeather) { + SkillDialogueHandler handler = new SkillDialogueHandler(player, SkillDialogue.MAKE_SET_ONE_OPTION, bolt.getFinished()) { + @Override + public void create(final int amount, int index) { + player.getPulseManager().run(new BoltPulse(player, event.getUsedItem(), bolt, new Item(featherId), amount)); + } + @Override + public int getAll(int index) { + return player.getInventory().getAmount(event.getUsedItem()); + } + }; + handler.open(); + return true; + } + return false; + } + + //handle logs + if(Fletching.isLog(event.getUsedItem().getId()) && event.getUsedWith().getId() == 946) { + final Item log = event.getUsedItem(); + Item[] items = Fletching.getItems(log.getId()); + SkillDialogue dialLength = SkillDialogue.ONE_OPTION; + switch (items.length) { + case 2: + dialLength = SkillDialogue.TWO_OPTION; + break; + case 3: + dialLength = SkillDialogue.THREE_OPTION; + break; + case 4: + dialLength = SkillDialogue.FOUR_OPTION; + break; + } + SkillDialogueHandler handler = new SkillDialogueHandler(player, dialLength, items) { + + @Override + public void create(final int amount, int index) { + final Fletching.FletchingItems item = Fletching.getEntries(log.getId())[index]; + player.getPulseManager().run(new FletchingPulse(player, log, amount, item)); + } + + @Override + public int getAll(int index) { + return player.getInventory().getAmount(log); + } + + }; + handler.open(); + return true; + } + return false; + } +} diff --git a/Server/src/main/content/global/skill/fletching/FletchingPulse.java b/Server/src/main/content/global/skill/fletching/FletchingPulse.java new file mode 100644 index 0000000..b02e405 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/FletchingPulse.java @@ -0,0 +1,145 @@ +package content.global.skill.fletching; + +import core.tools.RandomFunction; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.world.map.zone.ZoneBorders; +import core.game.node.entity.skill.SkillPulse; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; +import core.tools.StringUtils; +import content.data.Quests; + +/** + * fletching skill pulse + * @author ceik + */ +public final class FletchingPulse extends SkillPulse { + + /** + * Seers bank zone borders for the diary task + */ + private static final ZoneBorders bankZone = new ZoneBorders(2721,3493,2730,3487); + + /** + * Represents the animation used in this generic pulse. + */ + private static final Animation ANIMATION = new Animation(1248); + + /** + * Represents the item we are fletching. + */ + private Fletching.FletchingItems fletch; + + /** + * Represents the amount to fletch. + */ + private int amount = 0; + + /** + * Represents the amount to arrows fletched (for ogre arrow shafts which is a random number from 2-6). + */ + private int finalAmount = 0; + + /** + * Constructs a new {@code FletchingPulse.java} {@code Object}. + * @param player + * @param node + */ + public FletchingPulse(final Player player, final Item node, final int amount, final Fletching.FletchingItems fletch) { + super(player, node); + this.amount = amount; + this.fletch = fletch; + } + + @Override + public boolean checkRequirements() { + if (player.getSkills().getLevel(Skills.FLETCHING) < fletch.level) { + player.getDialogueInterpreter().sendDialogue("You need a Fletching skill of " + fletch.level + " or above to make " + (StringUtils.isPlusN(fletch.getItem().getName().replace("(u)", "").trim()) ? "an" : "a") + " " + fletch.getItem().getName().replace("(u)", "").trim()); + return false; + } + if (amount > player.getInventory().getAmount(node)) { + amount = player.getInventory().getAmount(node); + } + if (fletch == Fletching.FletchingItems.OGRE_ARROW_SHAFT) { + if (player.getQuestRepository().getQuest(Quests.BIG_CHOMPY_BIRD_HUNTING).getStage(player) == 0) { + player.getPacketDispatch().sendMessage("You must have started Big Chompy Bird Hunting to make those."); + return false; + } + } + if (fletch == Fletching.FletchingItems.OGRE_COMP_BOW) { + // Technically, this isn't supposed to show up till you've asked Grish. + if (player.getQuestRepository().getQuest(Quests.ZOGRE_FLESH_EATERS).getStage(player) < 8) { + player.getPacketDispatch().sendMessage("You must have started Zogre Flesh Eaters and asked Grish to make this."); + return false; + } + if (!player.getInventory().contains(2859, 1)) { + player.getPacketDispatch().sendMessage("You need to have Wolf Bones in order to make this."); + return false; + } + } + return true; + } + + @Override + public void animate() { + player.animate(ANIMATION); + } + + @Override + public boolean reward() { + if(bankZone.insideBorder(player) && fletch == Fletching.FletchingItems.MAGIC_SHORTBOW) { + player.getAchievementDiaryManager().finishTask(player, DiaryType.SEERS_VILLAGE, 2, 2); + } + if (getDelay() == 1) { + super.setDelay(4); + return false; + } + if (player.getInventory().remove(node)) { + final Item item = new Item(fletch.id,fletch.amount); + if ( fletch == Fletching.FletchingItems.OGRE_ARROW_SHAFT ) { + // The amount of shafts given is random; between two and six will be made. + finalAmount = RandomFunction.random(2,6); + item.setAmount(finalAmount); + } + if ( fletch == Fletching.FletchingItems.OGRE_COMP_BOW ) { + if (!player.getInventory().contains(2859, 1)) { + return false; + } else { + player.getInventory().remove(new Item(2859)); + } + } + player.getInventory().add(item); + player.getSkills().addExperience(Skills.FLETCHING, fletch.experience, true); + String message = getMessage(); + player.getPacketDispatch().sendMessage(message); + + if (fletch.id == Fletching.FletchingItems.MAGIC_SHORTBOW.id + && (new ZoneBorders(2721, 3489, 2724, 3493, 0).insideBorder(player) + || new ZoneBorders(2727, 3487, 2730, 3490, 0).insideBorder(player)) + && !player.getAchievementDiaryManager().hasCompletedTask(DiaryType.SEERS_VILLAGE, 2, 2)) { + player.setAttribute("/save:diary:seers:fletch-magic-short-bow", true); + } + } else { + return true; + } + amount--; + return amount == 0; + } + + /** + * Method used to get the message of the fletch. + * @return the message. + */ + public String getMessage() { + switch (fletch) { + case ARROW_SHAFT: + return "You carefully cut the wood into 15 arrow shafts."; + case OGRE_ARROW_SHAFT: + return "You carefully cut the wood into " + finalAmount + " arrow shafts."; + default: + return "You carefully cut the wood into " + (StringUtils.isPlusN(fletch.getItem().getName()) ? "an" : "a") + " " + fletch.getItem().getName().replace("(u)", "").trim() + "."; + } + } +} diff --git a/Server/src/main/content/global/skill/fletching/GemBoltListener.kt b/Server/src/main/content/global/skill/fletching/GemBoltListener.kt new file mode 100644 index 0000000..94c09c6 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/GemBoltListener.kt @@ -0,0 +1,69 @@ +package content.global.skill.fletching + +import content.global.skill.fletching.Fletching.GemBolts +import content.global.skill.fletching.items.gem.GemBoltCutPulse +import content.global.skill.fletching.items.gem.GemBoltPulse +import core.api.amountInInventory +import core.game.dialogue.SkillDialogueHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.item.Item +import core.net.packet.PacketRepository +import core.net.packet.context.ChildPositionContext +import core.net.packet.out.RepositionChild +import org.rs09.consts.Items +import kotlin.math.min + +class GemBoltListener : InteractionListener { + val gems = intArrayOf( + Items.OYSTER_PEARL_411, + Items.OYSTER_PEARLS_413, + Items.OPAL_1609, + Items.JADE_1611, + Items.RED_TOPAZ_1613, + Items.SAPPHIRE_1607, + Items.EMERALD_1605, + Items.RUBY_1603, + Items.DIAMOND_1601, + Items.DRAGONSTONE_1615, + Items.ONYX_6573 + ) + val boltBases = GemBolts.values().map { it.base }.toIntArray() + val boltTips = GemBolts.values().map { it.tip }.toIntArray() + + override fun defineListeners() { + onUseWith(IntType.ITEM, Items.CHISEL_1755, *gems) { player, used, with -> + val gem = Fletching.gemMap[with.id] ?: return@onUseWith true + + object : SkillDialogueHandler(player, SkillDialogue.ONE_OPTION, Item(gem.gem)) { + override fun create(amount: Int, index: Int) { + player.pulseManager.run(GemBoltCutPulse(player, used as? Item, gem, amount)) + } + + override fun getAll(index: Int): Int { + return player.inventory.getAmount(gem.gem) + } + }.open() + return@onUseWith true + } + + onUseWith(IntType.ITEM, boltBases, *boltTips) {player, used, with -> + val bolt = Fletching.tipMap[with.id] ?: return@onUseWith true + if (used.id != bolt.base || with.id != bolt.tip) return@onUseWith true + + + val handler: SkillDialogueHandler = + object : SkillDialogueHandler(player, SkillDialogue.MAKE_SET_ONE_OPTION, Item(bolt.product)) { + override fun create(amount: Int, index: Int) { + player.pulseManager.run(GemBoltPulse(player, used as? Item, bolt, amount)) + } + + override fun getAll(index: Int): Int { + return min(amountInInventory(player, used.id), amountInInventory(player, with.id)) + } + } + handler.open() + return@onUseWith true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/items/arrow/ArrowHead.java b/Server/src/main/content/global/skill/fletching/items/arrow/ArrowHead.java new file mode 100644 index 0000000..c7ab5ec --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/items/arrow/ArrowHead.java @@ -0,0 +1,123 @@ +/* +package core.game.node.entity.skill.fletching.items.arrow; + +import org.crandor.game.node.item.Item; + +*/ +/** + * Represents the enum storing the arrow head information. + * @author 'Vexia + * @note brutal arrows after quest. + *//* + +public enum ArrowHead { + BRONZE_ARROW(new Item(39), new Item(882), 1, 2.6), + IRON_ARROW(new Item(40), new Item(884), 15, 3.8), + STEEL_ARROW(new Item(41), new Item(886), 30, 6.3), + MITHRIL_ARROW(new Item(42), new Item(888), 45, 8.8), + ADAMANT_ARROW(new Item(43), new Item(890), 60, 10), + RUNE_ARROW(new Item(44), new Item(892), 75, 13.8), + DRAGON_ARROW(new Item(11237), new Item(11212), 90, 16.3), + BROAD_ARROW(new Item(13278), new Item(4160), 52, 10); + + */ +/** + * Constructs a new {@code ArrowHead.java} {@code Object}. + * @param item the item. + * @param product the product. + * @param level the level. + * @param experience the experience. + *//* + + ArrowHead(Item item, Item product, int level, double experience) { + this.item = item; + this.product = product; + this.level = level; + this.experience = experience; + } + + */ +/** + * Represents the arrow tip. + *//* + + private final Item item; + + */ +/** + * Represents the product item. + *//* + + private final Item product; + + */ +/** + * Represents the level required. + *//* + + private final int level; + + */ +/** + * Represents the experience gained. + *//* + + private final double experience; + + */ +/** + * Gets the item. + * @return The item. + *//* + + public Item getTips() { + return item; + } + + */ +/** + * Gets the product. + * @return The product. + *//* + + public Item getProduct() { + return product; + } + + */ +/** + * Gets the level. + * @return The level. + *//* + + public int getLevel() { + return level; + } + + */ +/** + * Gets the experience. + * @return The experience. + *//* + + public double getExperience() { + return experience; + } + + */ +/** + * Gets the arrow head. + * @param item the item. + * @return the arrow head. + *//* + + public static ArrowHead forItem(final Item item) { + for (ArrowHead arrow : ArrowHead.values()) { + if (arrow.getTips().getId() == item.getId()) { + return arrow; + } + } + return null; + } +} +*/ diff --git a/Server/src/main/content/global/skill/fletching/items/arrow/ArrowHeadPulse.java b/Server/src/main/content/global/skill/fletching/items/arrow/ArrowHeadPulse.java new file mode 100644 index 0000000..5ea27c2 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/items/arrow/ArrowHeadPulse.java @@ -0,0 +1,110 @@ +package content.global.skill.fletching.items.arrow; + +import content.global.skill.slayer.SlayerManager; +import core.game.node.entity.skill.SkillPulse; +import core.game.node.entity.skill.Skills; +import content.global.skill.fletching.Fletching; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +import static core.api.ContentAPIKt.*; + +/** + * Represents the arrow head pulse to complete the headless arrow. + * @author 'Vexia + */ +public class ArrowHeadPulse extends SkillPulse { + + /** + * Represents the headless arrow item. + */ + private static final Item HEADLESS_ARROW = new Item(53); + + /** + * Represents the arrow head. + */ + private final Fletching.ArrowHeads arrow; + + /** + * Represents the sets to do. + */ + private int sets; + + /** + * Constructs a new {@code ArrowHeadPulse.java} {@code Object}. + * @param player the player. + * @param node the node. + * @param arrow the arrow. + * @param sets the sets. + */ + public ArrowHeadPulse(final Player player, final Item node, final Fletching.ArrowHeads arrow, final int sets) { + super(player, node); + this.arrow = arrow; + this.sets = sets; + } + + @Override + public boolean checkRequirements() { + if (arrow.unfinished == 4160) { + if (!SlayerManager.getInstance(player).flags.isBroadsUnlocked()) { + player.getDialogueInterpreter().sendDialogue("You need to unlock the ability to create broad arrows."); + return false; + } + } + if (player.getSkills().getLevel(Skills.FLETCHING) < arrow.level) { + player.getDialogueInterpreter().sendDialogue("You need a fletching level of " + arrow.level + " to do this."); + return false; + } + if (!hasSpaceFor(player, arrow.getFinished())) { + sendDialogue(player, "You do not have enough inventory space."); + return false; + } + return true; + } + + @Override + public void animate() { + } + + @Override + public boolean reward() { + if (getDelay() == 1) { + super.setDelay(3); + } + Item tip = arrow.getUnfinished(); + int tipAmount = player.getInventory().getAmount(arrow.unfinished); + int shaftAmount = player.getInventory().getAmount(HEADLESS_ARROW); + if (tipAmount >= 15 && shaftAmount >= 15) { + HEADLESS_ARROW.setAmount(15); + tip.setAmount(15); + player.getPacketDispatch().sendMessage("You attach arrow heads to 15 arrow shafts."); + } else { + int amount = tipAmount > shaftAmount ? shaftAmount : tipAmount; + HEADLESS_ARROW.setAmount(amount); + tip.setAmount(amount); + player.getPacketDispatch().sendMessage(amount == 1 ? "You attach an arrow head to an arrow shaft." : "You attach arrow heads to " + amount + " arrow shafts."); + } + if (player.getInventory().remove(HEADLESS_ARROW, tip)) { + player.getSkills().addExperience(Skills.FLETCHING, arrow.experience * tip.getAmount(), true); + Item product = arrow.getFinished(); + product.setAmount(tip.getAmount()); + player.getInventory().add(product); + } + HEADLESS_ARROW.setAmount(1); + tip.setAmount(1); + if (!player.getInventory().containsItem(HEADLESS_ARROW)) { + return true; + } + if (!player.getInventory().containsItem(tip)) { + return true; + } + sets--; + return sets == 0; + } + + @Override + public void message(int type) { + + } + +} diff --git a/Server/src/main/content/global/skill/fletching/items/arrow/HeadlessArrowPulse.java b/Server/src/main/content/global/skill/fletching/items/arrow/HeadlessArrowPulse.java new file mode 100644 index 0000000..3125b56 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/items/arrow/HeadlessArrowPulse.java @@ -0,0 +1,145 @@ +package content.global.skill.fletching.items.arrow; + +import org.rs09.consts.Items; +import core.game.node.entity.skill.SkillPulse; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +import static core.api.ContentAPIKt.*; + +/** + * Represents the arrow pulse for creating unfinished arrows. + * @author 'Vexia + */ +public final class HeadlessArrowPulse extends SkillPulse { + + /** + * Represents the headless arrow item. + */ + private final Item HEADLESS_ARROW = new Item(Items.HEADLESS_ARROW_53); + + /** + * Represents the arrow shaft item. + */ + private final Item ARROW_SHAFT = new Item(Items.ARROW_SHAFT_52); + + /** + * Represents the feather items. + */ + private static final Item[] FEATHER = new Item[] { + new Item(Items.FEATHER_314), + new Item(Items.STRIPY_FEATHER_10087), + new Item(Items.RED_FEATHER_10088), + new Item(Items.BLUE_FEATHER_10089), + new Item(Items.YELLOW_FEATHER_10090), + new Item(Items.ORANGE_FEATHER_10091) + }; + + /** + * The feather being used. + */ + private Item feather; + + /** + * Represents the amount to make. + */ + private int sets; + + /** + * Represents if we should use sets, meaning we have 15 & 15 arrow shafts and feathers. + */ + private boolean useSets = false; + + /** + * Constructs a new {@code ArrowPulse.java} {@code Object}. + * @param player the player. + * @param node the node. + */ + public HeadlessArrowPulse(Player player, Item node, Item feather, int sets) { + super(player, node); + this.sets = sets; + this.feather = feather; + } + + @Override + public boolean checkRequirements() { + if (!player.getInventory().containsItem(ARROW_SHAFT)) { + player.getDialogueInterpreter().sendDialogue("You don't have any arrow shafts."); + return false; + } + if (feather == null || !player.getInventory().containsItem(feather)) { + player.getDialogueInterpreter().sendDialogue("You don't have any feathers."); + return false; + } + if (player.getInventory().contains(ARROW_SHAFT.getId(), 15) && player.getInventory().contains(feather.getId(), 15)) { + useSets = true; + } else { + useSets = false; + } + if (!hasSpaceFor(player, HEADLESS_ARROW.asItem())) { + sendDialogue(player, "You do not have enough inventory space."); + return false; + } + return true; + } + + @Override + public void animate() { + } + + @Override + public boolean reward() { + int featherAmount = player.getInventory().getAmount(feather); + int shaftAmount = player.getInventory().getAmount(ARROW_SHAFT); + if (getDelay() == 1) { + super.setDelay(3); + } + if (featherAmount >= 15 && shaftAmount >= 15) { + feather.setAmount(15); + ARROW_SHAFT.setAmount(15); + player.getPacketDispatch().sendMessage("You attach feathers to 15 arrow shafts."); + } else { + int amount = Math.min(featherAmount, shaftAmount); + feather.setAmount(amount); + ARROW_SHAFT.setAmount(amount); + player.getPacketDispatch().sendMessage(amount == 1 + ? "You attach a feathers to a shaft." : "You attach feathers to " + amount + " arrow shafts."); + } + if (player.getInventory().remove(feather, ARROW_SHAFT)) { + HEADLESS_ARROW.setAmount(feather.getAmount()); + player.getSkills().addExperience(Skills.FLETCHING, HEADLESS_ARROW.getAmount(), true); + player.getInventory().add(HEADLESS_ARROW); + } + HEADLESS_ARROW.setAmount(1); + feather.setAmount(1); + ARROW_SHAFT.setAmount(1); + if (!player.getInventory().containsItem(ARROW_SHAFT)) { + return true; + } + if (!player.getInventory().containsItem(feather)) { + return true; + } + sets--; + return sets <= 0; + } + + @Override + public void message(int type) { + } + + /** + * Gets the feather item. + * @return the item. + */ + private Item getFeather() { + int length = FEATHER.length; + for (int i = 0; i < length; i++) { + Item f = FEATHER[i]; + if (player.getInventory().containsItem(f)) { + return f; + } + } + return null; + } +} diff --git a/Server/src/main/content/global/skill/fletching/items/arrow/HeadlessOgreArrowPulse.java b/Server/src/main/content/global/skill/fletching/items/arrow/HeadlessOgreArrowPulse.java new file mode 100644 index 0000000..fd7af67 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/items/arrow/HeadlessOgreArrowPulse.java @@ -0,0 +1,131 @@ +package content.global.skill.fletching.items.arrow; + +import core.game.node.entity.player.Player; +import core.game.node.entity.skill.SkillPulse; +import core.game.node.entity.skill.Skills; +import core.game.node.item.Item; +import org.rs09.consts.Items; + +import static core.api.ContentAPIKt.hasSpaceFor; +import static core.api.ContentAPIKt.sendDialogue; + +/** + * Represents the arrow pulse for creating unfinished ogre arrows. + * @author 'Vexia + */ +public final class HeadlessOgreArrowPulse extends SkillPulse { + + /** + * Represents the headless ogre arrow item. + */ + private final Item HEADLESS_ARROW = new Item(Items.FLIGHTED_OGRE_ARROW_2865); + + /** + * Represents the ogre arrow shaft item. + */ + private final Item ARROW_SHAFT = new Item(Items.OGRE_ARROW_SHAFT_2864); + + /** + * Represents the feather items. + */ + private static final Item[] FEATHER = new Item[] { + new Item(Items.FEATHER_314, 4), + }; + + /** + * The feather being used. + */ + private Item feather; + + /** + * Represents the amount to make. + */ + private int sets; + + /** + * Constructs a new {@code ArrowPulse.java} {@code Object}. + * @param player the player. + * @param node the node. + */ + public HeadlessOgreArrowPulse(Player player, Item node, Item feather, int sets) { + super(player, node); + this.sets = sets; + this.feather = feather; + } + + @Override + public boolean checkRequirements() { + if (!player.getInventory().containsItem(ARROW_SHAFT)) { + player.getDialogueInterpreter().sendDialogue("You don't have any arrow shafts."); + return false; + } + if (feather == null || !player.getInventory().containsItem(feather)) { + player.getDialogueInterpreter().sendDialogue("You don't have any feathers."); + return false; + } + if (!hasSpaceFor(player, HEADLESS_ARROW.asItem())) { + sendDialogue(player, "You do not have enough inventory space."); + return false; + } + return true; + } + + @Override + public void animate() { + } + + @Override + public boolean reward() { + int featherAmount = player.getInventory().getAmount(feather); + int shaftAmount = player.getInventory().getAmount(ARROW_SHAFT); + if (getDelay() == 1) { + super.setDelay(3); + } + if (featherAmount >= 24 && shaftAmount >= 6) { + feather.setAmount(24); + ARROW_SHAFT.setAmount(6); + player.getPacketDispatch().sendMessage("You attach 24 feathers to 6 ogre arrow shafts."); + } else { + int amount = Math.min(featherAmount / 4, shaftAmount); + feather.setAmount(amount*4); + ARROW_SHAFT.setAmount(amount); + player.getPacketDispatch().sendMessage(amount == 1 + ? "You attach a feathers to a shaft." : "You attach " + amount * 4 + " feathers to " + amount + " ogre arrow shafts."); + } + if (player.getInventory().remove(feather, ARROW_SHAFT)) { + HEADLESS_ARROW.setAmount(ARROW_SHAFT.getAmount()); + player.getSkills().addExperience(Skills.FLETCHING, HEADLESS_ARROW.getAmount(), true); + player.getInventory().add(HEADLESS_ARROW); + } + HEADLESS_ARROW.setAmount(1); + feather.setAmount(1); + ARROW_SHAFT.setAmount(1); + if (!player.getInventory().containsItem(ARROW_SHAFT)) { + return true; + } + if (!player.getInventory().containsItem(feather)) { + return true; + } + sets--; + return sets <= 0; + } + + @Override + public void message(int type) { + } + + /** + * Gets the feather item. + * @return the item. + */ + private Item getFeather() { + int length = FEATHER.length; + for (int i = 0; i < length; i++) { + Item f = FEATHER[i]; + if (player.getInventory().containsItem(f)) { + return f; + } + } + return null; + } +} diff --git a/Server/src/main/content/global/skill/fletching/items/bolts/Bolt.java b/Server/src/main/content/global/skill/fletching/items/bolts/Bolt.java new file mode 100644 index 0000000..f877050 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/items/bolts/Bolt.java @@ -0,0 +1,123 @@ +/* +package core.game.node.entity.skill.fletching.items.bolts; + +import org.crandor.game.node.item.Item; + +*/ +/** + * Represents an enum of bolts. + * @author 'Vexia + *//* + +public enum Bolt { + BRONZE_BOLT(new Item(9375), new Item(877), 9, 0.5), + BLURITE_BOLT(new Item(9376), new Item(9139), 24, 1), + IRON_BOLT(new Item(9377), new Item(9140), 39, 1.5), + SILVER_BOLT(new Item(9382), new Item(9145), 43, 2.5), + STEEL_BOLT(new Item(9378), new Item(9141), 46, 3.5), + MITHRIL_BOLT(new Item(9379), new Item(9142), 54, 5), + ADAMANTITE_BOLT(new Item(9380), new Item(9143), 61, 7), + RUNITE_BOLT(new Item(9381), new Item(9144), 69, 10), + BROAD_BOLT(new Item(13279), new Item(13280), 55, 3); + + */ +/** + * The item required. + *//* + + private final Item item; + + */ +/** + * The product recieved. + *//* + + private final Item product; + + */ +/** + * The level required. + *//* + + private final int level; + + */ +/** + * The experience gained. + *//* + + private final double experience; + + */ +/** + * Constructs a new {@code Bolt} {@code Object}. + * @param item the item. + * @param product the product. + * @param level the level. + * @param experience the experienece. + *//* + + Bolt(Item item, Item product, int level, double experience) { + this.item = item; + this.product = product; + this.level = level; + this.experience = experience; + } + + */ +/** + * Gets the item. + * @return The item. + *//* + + public Item getItem() { + return item; + } + + */ +/** + * Gets the product. + * @return The product. + *//* + + public Item getProduct() { + return product; + } + + */ +/** + * Gets the level. + * @return The level. + *//* + + public int getLevel() { + return level; + } + + */ +/** + * Gets the experience. + * @return The experience. + *//* + + public double getExperience() { + return experience; + } + + */ +/** + * Method used to get the bolt for the item. + * @param item the item. + * @return the bolt. + *//* + + public static Bolt forItem(final Item item) { + for (Bolt bolt : Bolt.values()) { + if (bolt.getItem().getId() == item.getId()) { + return bolt; + } + } + return null; + } +} +*/ diff --git a/Server/src/main/content/global/skill/fletching/items/bolts/BoltPulse.java b/Server/src/main/content/global/skill/fletching/items/bolts/BoltPulse.java new file mode 100644 index 0000000..b345c42 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/items/bolts/BoltPulse.java @@ -0,0 +1,130 @@ +package content.global.skill.fletching.items.bolts; + +import content.global.skill.slayer.SlayerManager; +import org.rs09.consts.Items; +import core.game.node.entity.skill.SkillPulse; +import core.game.node.entity.skill.Skills; +import content.global.skill.fletching.Fletching; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +/** + * Represents the bolt pulse class to make bolts. + * @author ceik + */ +public final class BoltPulse extends SkillPulse { + + /** + * Represents the feather item. + */ + private Item feather; + + /** + * Represents possible feather Items + */ + private static final Item[] FEATHER = new Item[] { + new Item(Items.FEATHER_314), + new Item(Items.STRIPY_FEATHER_10087), + new Item(Items.RED_FEATHER_10088), + new Item(Items.BLUE_FEATHER_10089), + new Item(Items.YELLOW_FEATHER_10090), + new Item(Items.ORANGE_FEATHER_10091) + }; + + /** + * Represents the bolt. + */ + private final Fletching.Bolts bolt; + + /** + * Represents the sets to do. + */ + private int sets; + + /** + * Represents if we're using sets. + */ + private boolean useSets = false; + + /** + * Constructs a new {@code BoltPulse.java} {@code Object}. + * @param player the player. + * @param node the node. + */ + public BoltPulse(Player player, Item node, final Fletching.Bolts bolt, final Item feather, final int sets) { + super(player, node); + this.bolt = bolt; + this.sets = sets; + this.feather = feather; + } + + @Override + public boolean checkRequirements() { + if (bolt.getUnfinished().getId() == 13279) { + if (!SlayerManager.getInstance(player).flags.isBroadsUnlocked()) { + player.getDialogueInterpreter().sendDialogue("You need to unlock the ability to create broad bolts."); + return false; + } + } + if (player.getSkills().getLevel(Skills.FLETCHING) < bolt.level) { + player.getDialogueInterpreter().sendDialogue("You need a fletching level of " + bolt.level + " in order to do this."); + return false; + } + if (!player.getInventory().containsItem(feather)) { + return false; + } + if (!player.getInventory().containsItem(bolt.getUnfinished())) { + return false; + } + if (!player.getInventory().hasSpaceFor(bolt.getFinished())) { + player.getDialogueInterpreter().sendDialogue("You do not have enough inventory space."); + return false; + } + + return true; + } + + @Override + public void animate() { + } + + @Override + public boolean reward() { + int featherAmount = player.getInventory().getAmount(feather); + int boltAmount = player.getInventory().getAmount(bolt.unfinished); + if (getDelay() == 1) { + super.setDelay(3); + } + final Item unfinished = bolt.getUnfinished(); + if (featherAmount >= 10 && boltAmount >= 10) { + feather.setAmount(10); + unfinished.setAmount(10); + player.getPacketDispatch().sendMessage("You fletch 10 bolts."); + } else { + int amount = featherAmount > boltAmount ? boltAmount : featherAmount; + feather.setAmount(amount); + unfinished.setAmount(amount); + player.getPacketDispatch().sendMessage(amount == 1 ? "You attach a feather to a bolt." : "You fletch " + amount + " bolts"); + } + if (player.getInventory().remove(feather, unfinished)) { + Item product = bolt.getFinished(); + product.setAmount(feather.getAmount()); + player.getSkills().addExperience(Skills.FLETCHING, product.getAmount() * bolt.experience, true); + player.getInventory().add(product); + } + feather.setAmount(1); + if (!player.getInventory().containsItem(feather)) { + return true; + } + if (!player.getInventory().containsItem(bolt.getUnfinished())) { + return true; + } + sets--; + return sets <= 0; + } + + @Override + public void message(int type) { + } + +} diff --git a/Server/src/main/content/global/skill/fletching/items/bow/StringBow.java b/Server/src/main/content/global/skill/fletching/items/bow/StringBow.java new file mode 100644 index 0000000..0187f17 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/items/bow/StringBow.java @@ -0,0 +1,136 @@ +/* +package core.game.node.entity.skill.fletching.items.bow; + +import org.crandor.game.node.item.Item; +import org.crandor.game.world.update.flag.context.Animation; + +*/ +/** + * Represents the enum of stringing bows. + * @author 'Vexia + *//* + +public enum StringBow { + SHORT_BOW(new Item(50), new Item(841), 5, 5, new Animation(6678)), + LONG_BOW(new Item(48), new Item(839), 10, 10, new Animation(6684)), + OAK_SHORTBOW(new Item(54), new Item(843), 20, 16.5, new Animation(6679)), + OAK_LONGBOW(new Item(56), new Item(845), 25, 25, new Animation(6685)), + WILLOW_SHORTBOW(new Item(60), new Item(849), 35, 33.3, new Animation(6680)), + WILLOW_LONGBOW(new Item(58), new Item(847), 40, 41.5, new Animation(6686)), + MAPLE_SHORTBOW(new Item(64), new Item(853), 50, 50, new Animation(6681)), + MAPLE_LONGBOW(new Item(62), new Item(851), 55, 58.3, new Animation(6687)), + YEW_SHORTBOW(new Item(68), new Item(857), 65, 66, new Animation(6682)), + YEW_LONGBOW(new Item(66), new Item(855), 70, 75, new Animation(6688)), + MAGIC_SHORTBOW(new Item(72), new Item(861), 80, 83.3, new Animation(6683)), + MAGIC_LONGBOW(new Item(70), new Item(859), 85, 91.5, new Animation(6689)); + + + StringBow(final Item item, final Item product, final int level, final double experience, final Animation animation) { + this.item = item; + this.product = product; + this.level = level; + this.experience = experience; + this.animation = animation; + } + + */ +/** + * The item required. + *//* + + private final Item item; + + */ +/** + * The item product. + *//* + + private final Item product; + + */ +/** + * The level required. + *//* + + private final int level; + + */ +/** + * The experience required. + *//* + + private final double experience; + + */ +/** + * The animation of stringing. + *//* + + private final Animation animation; + + */ +/** + * Gets the item. + * @return The item. + *//* + + public Item getItem() { + return item; + } + + */ +/** + * Gets the product. + * @return The product. + *//* + + public Item getProduct() { + return product; + } + + */ +/** + * Gets the level. + * @return The level. + *//* + + public int getLevel() { + return level; + } + + */ +/** + * Gets the experience. + * @return The experience. + *//* + + public double getExperience() { + return experience; + } + + */ +/** + * Method used to get the animation. + * @return the animation. + *//* + + public Animation getAnimation() { + return animation; + } + + */ +/** + * Method used to get the string bow for the item. + * @param item the item. + * @return the string bow. + *//* + + public static StringBow forItem(final int id) { + for (StringBow bw : StringBow.values()) { + if (bw.getItem().getId() == id) { + return bw; + } + } + return null; + } +}*/ diff --git a/Server/src/main/content/global/skill/fletching/items/bow/StringPulse.java b/Server/src/main/content/global/skill/fletching/items/bow/StringPulse.java new file mode 100644 index 0000000..0d8645e --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/items/bow/StringPulse.java @@ -0,0 +1,103 @@ +package content.global.skill.fletching.items.bow; + +import core.game.node.entity.player.info.LogType; +import core.game.node.entity.player.info.PlayerMonitor; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.world.map.zone.ZoneBorders; +import core.game.node.entity.skill.SkillPulse; +import core.game.node.entity.skill.Skills; +import content.global.skill.fletching.Fletching; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +import static core.api.ContentAPIKt.amountInInventory; + +/** + * Represents the skill pulse of stringing. + * + * @author Ceikry + */ +public class StringPulse extends SkillPulse { + + /** + * Represents the string bow. + */ + private final Fletching.String bow; + + /** + * The amount. + */ + private int amount; + + private int initialAmount; + private int processedAmount; + + /** + * Constructs a new {@code StringbowPlugin.java} {@code Object}. + * + * @param player the player. + * @param node the node. + */ + public StringPulse(Player player, Item node, final Fletching.String bow, int amount) { + super(player, node); + this.bow = bow; + this.amount = amount; + this.initialAmount = amountInInventory(player, node.getId()); + this.processedAmount = 0; + } + + @Override + public boolean checkRequirements() { + if (getDelay() == 1) { + setDelay(2); + } + if (player.getSkills().getLevel(Skills.FLETCHING) < bow.level) { + player.getDialogueInterpreter().sendDialogue("You need a fletching level of " + bow.level + " to string this bow."); + return false; + } + if (!player.getInventory().containsItem(new Item(bow.unfinished))) { + return false; + } + if (!player.getInventory().containsItem(new Item(bow.string))) { + player.getDialogueInterpreter().sendDialogue("You seem to have run out of bow strings."); + return false; + } + animate(); + return true; + } + + @Override + public void animate() { + player.animate(bow.animation); + } + + @Override + public boolean reward() { + if (player.getInventory().remove(new Item(bow.unfinished), new Item(bow.string))) { + player.getInventory().add(new Item(bow.product)); + player.getSkills().addExperience(Skills.FLETCHING, bow.experience, true); + player.getPacketDispatch().sendMessage("You add a string to the bow."); + processedAmount++; + if (processedAmount > initialAmount) { + PlayerMonitor.log(player, LogType.DUPE_ALERT, "fletched item (" + player.getName() + ", " + bow.unfinished + "): initialAmount " + initialAmount + ", processedAmount " + processedAmount); + } + + if (bow == Fletching.String.MAGIC_SHORTBOW + && (new ZoneBorders(2721, 3489, 2724, 3493, 0).insideBorder(player) + || new ZoneBorders(2727, 3487, 2730, 3490, 0).insideBorder(player)) + && player.getAttribute("diary:seers:fletch-magic-short-bow", false)) { + player.getAchievementDiaryManager().finishTask(player, DiaryType.SEERS_VILLAGE, 2, 2); + } + } + if (!player.getInventory().containsItem(new Item(bow.string)) || !player.getInventory().containsItem(new Item(bow.unfinished))) { + return true; + } + amount--; + return amount == 0; + } + + @Override + public void message(int type) { + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/items/crossbow/CrossbowPulse.java b/Server/src/main/content/global/skill/fletching/items/crossbow/CrossbowPulse.java new file mode 100644 index 0000000..cfe0cf5 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/items/crossbow/CrossbowPulse.java @@ -0,0 +1,97 @@ +/* +package core.game.node.entity.skill.fletching.items.crossbow; + +import core.game.node.entity.skill.SkillPulse; +import core.game.node.entity.skill.Skills; +import org.crandor.game.node.entity.player.Player; +import org.crandor.game.node.item.Item; + +*/ +/** + * Represents the skill pulse of stringing. + * @author 'Vexia + *//* + +public class CrossbowPulse extends SkillPulse { + + */ +/** + * Represents the bow string item. + *//* + + private final Item BOW_STRING = new Item(9438); + + */ +/** + * Represents the string bow. + *//* + + private final StringCross bow; + + */ +/** + * Represents the amount. + *//* + + private int amount; + + */ +/** + * Constructs a new {@code StringcrossbowPlugin.java} {@code Object}. + * @param player the player. + * @param node the node. + *//* + + public CrossbowPulse(Player player, Item node, final StringCross bow, int amount) { + super(player, node); + this.bow = bow; + this.amount = amount; + } + + @Override + public boolean checkRequirements() { + if (player.getSkills().getLevel(Skills.FLETCHING) < bow.getLevel()) { + player.getDialogueInterpreter().sendDialogue("You need a fletching level of " + bow.getLevel() + " to string this crossbow."); + return false; + } + if (!player.getInventory().containsItem(BOW_STRING)) { + player.getDialogueInterpreter().sendDialogue("You seem to have run out of bow strings."); + return false; + } + return true; + } + + @Override + public void animate() { + player.animate(bow.getAnimation()); + } + + @Override + public boolean reward() { + if (getDelay() == 1) { + super.setDelay(5); + return false; + } + if (player.getInventory().remove(bow.getItem(), BOW_STRING)) { + player.getInventory().add(bow.getProduct()); + player.getSkills().addExperience(Skills.FLETCHING, bow.getExperience(), true); + player.getPacketDispatch().sendMessage("You add a string to the crossbow."); + } + if (!player.getInventory().containsItem(BOW_STRING) || !player.getInventory().containsItem(bow.getItem())) { + return true; + } + amount--; + return amount == 0; + } + + @Override + public void message(int type) { + switch (type) { + case 0: + break; + case 1: + break; + } + } + +}*/ diff --git a/Server/src/main/content/global/skill/fletching/items/crossbow/Limb.java b/Server/src/main/content/global/skill/fletching/items/crossbow/Limb.java new file mode 100644 index 0000000..6ffc014 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/items/crossbow/Limb.java @@ -0,0 +1,128 @@ +package content.global.skill.fletching.items.crossbow; + +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; + +/** + * Represents the enum for limbs. + * @author 'Vexia + */ +public enum Limb { + WOODEN_STOCK(new Item(9440), new Item(9420), new Item(9454), 9, 12, new Animation(4436)), + OAK_STOCK(new Item(9442), new Item(9422), new Item(9176), 24, 32, new Animation(4437)), + WILLOW_STOCK(new Item(9444), new Item(9423), new Item(9457), 39, 44, new Animation(4438)), + TEAK_STOCK(new Item(9446), new Item(9425), new Item(9459), 46, 54, new Animation(4439)), + MAPLE_STOCK(new Item(9448), new Item(9427), new Item(9461), 54, 64, new Animation(4440)), + MAHOGANY_STOCK(new Item(9450), new Item(9429), new Item(9463), 61, 82, new Animation(4441)), + YEW_STOCK(new Item(9452), new Item(9431), new Item(9465), 69, 100, new Animation(4442)); + + /** + * Constructs a new {@code StringcrosbowPlugin.java} {@code Object}. + * @param stock the stock. + * @param limb the limb. + * @param product the product. + * @param level the level. + * @param experience the experience. + * @param animation the animation. + */ + Limb(Item stock, Item limb, Item product, int level, double experience, Animation animation) { + this.stock = stock; + this.limb = limb; + this.product = product; + this.level = level; + this.experience = experience; + this.animation = animation; + } + + /** + * The stock. + */ + private final Item stock; + + /** + * The limb. + */ + private final Item limb; + + /** + * The product. + */ + private final Item product; + + /** + * The level. + */ + private final int level; + + /** + * The experience. + */ + private final double experience; + + /** + * The animation. + */ + private final Animation animation; + + /** + * Gets the stock. + * @return The stock. + */ + public Item getStock() { + return stock; + } + + /** + * Gets the limb. + * @return The limb. + */ + public Item getLimb() { + return limb; + } + + /** + * Gets the product. + * @return The product. + */ + public Item getProduct() { + return product; + } + + /** + * Gets the level. + * @return The level. + */ + public int getLevel() { + return level; + } + + /** + * Gets the experience. + * @return The experience. + */ + public double getExperience() { + return experience; + } + + /** + * Gets the animation. + * @return The animation. + */ + public Animation getAnimation() { + return animation; + } + + /** + * Method used to get the {@link Limb} for the item. + * @param item the item. + * @return the limb. + */ + public static Limb forItems(final Item item, final Item second) { + for (Limb l : Limb.values()) { + if (l.getLimb().getId() == item.getId() && l.getStock().getId() == second.getId() || l.getLimb().getId() == second.getId() && l.getStock().getId() == item.getId()) { + return l; + } + } + return null; + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/items/crossbow/LimbPulse.kt b/Server/src/main/content/global/skill/fletching/items/crossbow/LimbPulse.kt new file mode 100644 index 0000000..2d6d355 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/items/crossbow/LimbPulse.kt @@ -0,0 +1,52 @@ +package content.global.skill.fletching.items.crossbow + +import core.game.node.entity.player.Player +import core.game.node.entity.skill.SkillPulse +import core.game.node.entity.skill.Skills +import content.global.skill.fletching.Fletching +import core.game.node.item.Item + +/** + * Represents the skill pulse of attaching limbs. + * @author Ceikry + */ +class LimbPulse(player: Player?, node: Item, private val limb: Fletching.Limb, private var amount: Int) : SkillPulse(player, node) { + override fun checkRequirements(): Boolean { + if (player.skills.getLevel(Skills.FLETCHING) < limb.level) { + player.dialogueInterpreter.sendDialogue("You need a fletching level of " + limb.level + " to attach these limbs.") + return false + } + if (!player.inventory.containsItem(Item(limb.limb))) { + player.dialogueInterpreter.sendDialogue("That's not the correct limb to attach.") + return false + } + if(!player.inventory.containsItem(Item(limb.stock))){ + player.dialogueInterpreter.sendDialogue("That's not the correct stock for that limb.") + return false + } + return player.inventory.containsItem(Item(limb.stock)) + } + + override fun animate() { + player.animate(limb.animation) + } + + override fun reward(): Boolean { + if (delay == 1) { + super.setDelay(6) + return false + } + if (player.inventory.remove(Item(limb.stock), Item(limb.limb))) { + player.inventory.add(Item(limb.product)) + player.skills.addExperience(Skills.FLETCHING, limb.experience, true) + player.packetDispatch.sendMessage("You attach the metal limbs to the stock.") + } + if (!player.inventory.containsItem(Item(limb.limb))) { + return true + } + amount-- + return amount == 0 + } + + override fun message(type: Int) {} +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/items/crossbow/StringCross.java b/Server/src/main/content/global/skill/fletching/items/crossbow/StringCross.java new file mode 100644 index 0000000..32671c4 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/items/crossbow/StringCross.java @@ -0,0 +1,139 @@ +/* +package core.game.node.entity.skill.fletching.items.crossbow; + +import org.crandor.game.node.item.Item; +import org.crandor.game.world.update.flag.context.Animation; + +*/ +/** + * Represents the enum of stringing crossbows. + * @author 'Vexia + *//* + +public enum StringCross { + BRONZE_CBOW(new Item(9454), new Item(9174), 9, 6, new Animation(6671)), + BLURITE_CBOW(new Item(9456), new Item(9176), 24, 16, new Animation(6672)), + IRON_CBOW(new Item(9457), new Item(9177), 39, 22, new Animation(6673)), + STEEL_CBOW(new Item(9459), new Item(9179), 46, 27, new Animation(6674)), + MITHIRIL_CBOW(new Item(9461), new Item(9181), 54, 32, new Animation(6675)), + ADAMANT_CBOW(new Item(9463), new Item(9183), 61, 41, new Animation(6676)), + RUNITE_CBOW(new Item(9465), new Item(9185), 69, 50, new Animation(6677)); + */ +/** + * Constructs a new {@code StringcrossbowPlugin.java} {@code Object}. + * @param item the item. + * @param product the product. + * @param level the level. + * @param experience the experience. + *//* + + StringCross(final Item item, final Item product, final int level, final double experience, final Animation animation) { + this.item = item; + this.product = product; + this.level = level; + this.experience = experience; + this.animation = animation; + } + + */ +/** + * The item required. + *//* + + private final Item item; + + */ +/** + * The item product. + *//* + + private final Item product; + + */ +/** + * The level required. + *//* + + private final int level; + + */ +/** + * The experience required. + *//* + + private final double experience; + + */ +/** + * The animation of stringing. + *//* + + private final Animation animation; + + */ +/** + * Gets the item. + * @return The item. + *//* + + public Item getItem() { + return item; + } + + */ +/** + * Gets the product. + * @return The product. + *//* + + public Item getProduct() { + return product; + } + + */ +/** + * Gets the level. + * @return The level. + *//* + + public int getLevel() { + return level; + } + + */ +/** + * Gets the experience. + * @return The experience. + *//* + + public double getExperience() { + return experience; + } + + */ +/** + * Method used to get the animation. + * @return the animation. + *//* + + public Animation getAnimation() { + return animation; + } + + */ +/** + * Method used to get the string bow for the item. + * @param item the item. + * @return the string bow. + *//* + + public static StringCross forItem(final Item item) { + for (StringCross bw : StringCross.values()) { + if (bw.getItem().getId() == item.getId()) { + return bw; + } + } + return null; + } +} +*/ diff --git a/Server/src/main/content/global/skill/fletching/items/darts/Dart.java b/Server/src/main/content/global/skill/fletching/items/darts/Dart.java new file mode 100644 index 0000000..2358494 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/items/darts/Dart.java @@ -0,0 +1,96 @@ +package content.global.skill.fletching.items.darts; + +import core.game.node.item.Item; + +/** + * Represents the enum to hold dart info. + * @author 'Vexia + */ +public enum Dart { + BRONZE_DART(new Item(819), new Item(806), 1, 1.8), + IRON_DART(new Item(820), new Item(807), 22, 3.8), + STEEL_DART(new Item(821), new Item(808), 37, 7.5), + MITHRIL_DART(new Item(822), new Item(809), 52, 11.2), + ADAMANT_DART(new Item(823), new Item(810), 67, 15), + RUNE_DART(new Item(824), new Item(811), 81, 18.8), + DRAGON_DART(new Item(11232), new Item(11230), 95, 25); + /** + * Constructs a new {@code Dart} {@code Object}. + * @param item the item. + * @param product the product. + * @param level the level. + * @param experience the experience. + */ + Dart(final Item item, final Item product, final int level, final double experience) { + this.item = item; + this.product = product; + this.level = level; + this.experience = experience; + } + + /** + * Represents the item required. + */ + private final Item item; + + /** + * Represents the product gained. + */ + private final Item product; + + /** + * Represents the level required. + */ + private final int level; + + /** + * Represents the experience gained. + */ + private final double experience; + + /** + * Gets the item. + * @return The item. + */ + public Item getItem() { + return item; + } + + /** + * Gets the product. + * @return The product. + */ + public Item getProduct() { + return product; + } + + /** + * Gets the level. + * @return The level. + */ + public int getLevel() { + return level; + } + + /** + * Gets the experience. + * @return The experience. + */ + public double getExperience() { + return experience; + } + + /** + * Method used to get the dart for the item. + * @param item the item. + * @return the dart. + */ + public static Dart forItem(final Item item) { + for (Dart dart : Dart.values()) { + if (dart.getItem().getId() == item.getId()) { + return dart; + } + } + return null; + } +} diff --git a/Server/src/main/content/global/skill/fletching/items/darts/DartPulse.java b/Server/src/main/content/global/skill/fletching/items/darts/DartPulse.java new file mode 100644 index 0000000..d65fac1 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/items/darts/DartPulse.java @@ -0,0 +1,105 @@ +package content.global.skill.fletching.items.darts; + +import core.game.node.entity.skill.SkillPulse; +import core.game.node.entity.skill.Skills; +import content.global.skill.fletching.Fletching; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +import static core.api.ContentAPIKt.*; +import content.data.Quests; + +/** + * Represents the dart pulse. + * @author ceikry + */ +public final class DartPulse extends SkillPulse { + + /** + * Represents the feather item. + */ + private static final Item FEATHER = new Item(314); + + /** + * Represents the dart. + */ + private final Fletching.Darts dart; + + /** + * Represents the sets to make. + */ + private int sets; + + /** + * Constructs a new {@code DartPulse.java} {@code Object}. + * @param player the player. + * @param node the node. + */ + public DartPulse(Player player, Item node, Fletching.Darts dart, int sets) { + super(player, node); + this.dart = dart; + this.sets = sets; + } + + @Override + public boolean checkRequirements() { + if (player.getSkills().getLevel(Skills.FLETCHING) < dart.level) { + player.getDialogueInterpreter().sendDialogue("You need a fletching level of " + dart.level + " to do this."); + return false; + } + if (!player.getQuestRepository().isComplete(Quests.THE_TOURIST_TRAP)){ + player.getDialogueInterpreter().sendDialogue("You need to have completed Tourist Trap to fletch darts."); + return false; + } + if (!hasSpaceFor(player, dart.getFinished())) { + sendDialogue(player, "You do not have enough inventory space."); + return false; + } + return true; + } + + @Override + public void animate() { + + } + + @Override + public boolean reward() { + if (getDelay() == 1) { + super.setDelay(3); + } + final Item unfinished = dart.getUnfinished(); + final int dartAmount = player.getInventory().getAmount(unfinished); + final int featherAmount = player.getInventory().getAmount(FEATHER); + if (dartAmount >= 10 && featherAmount >= 10) { + FEATHER.setAmount(10); + unfinished.setAmount(10); + player.getPacketDispatch().sendMessage("You attach feathers to 10 darts."); + } else { + int amount = featherAmount > dartAmount ? dartAmount : featherAmount; + FEATHER.setAmount(amount); + unfinished.setAmount(amount); + player.getPacketDispatch().sendMessage(amount == 1 ? "You attach a feather to a dart." : "You attach feathers to " + amount + " darts."); + } + if (player.getInventory().remove(FEATHER, unfinished)) { + Item product = dart.getFinished(); + product.setAmount(FEATHER.getAmount()); + player.getSkills().addExperience(Skills.FLETCHING, dart.experience * product.getAmount(), true); + player.getInventory().add(product); + } + FEATHER.setAmount(1); + if (!player.getInventory().containsItem(FEATHER)) { + return true; + } + if (!player.getInventory().containsItem(dart.getUnfinished())) { + return true; + } + sets--; + return sets == 0; + } + + @Override + public void message(int type) { + } + +} diff --git a/Server/src/main/content/global/skill/fletching/items/gem/Gem.java b/Server/src/main/content/global/skill/fletching/items/gem/Gem.java new file mode 100644 index 0000000..6a3377a --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/items/gem/Gem.java @@ -0,0 +1,101 @@ +package content.global.skill.fletching.items.gem; + +import core.game.node.item.Item; + +/** + * Represents gems to cut into bolt tips. + * @author 'Vexia + * @date 01/12/2013 + */ +public enum Gem { + OPAL(new Item(1609), new Item(45, 12), 11, 1.5), + JADE(new Item(1611), new Item(9187, 12), 26, 2.4), + RED_TOPAZ(new Item(1613), new Item(9188, 12), 48, 3.9), + SAPPHIRE(new Item(1607), new Item(9189, 12), 56, 4), + EMERALD(new Item(1605), new Item(9190, 12), 58, 5.5), + RUBY(new Item(1603), new Item(9191, 12), 63, 6.3), + DIAMOND(new Item(1601), new Item(9192, 12), 65, 7), + DRAGONSTONE(new Item(1615), new Item(9193, 12), 71, 8.2), + ONYX(new Item(6573), new Item(9194, 24), 73, 9.4); + + /** + * Constructs a new {@code Gem.java} {@code Object}. + * @param gem the gem. + * @param bolt the bolt. + * @param level the level. + * @param experience the experience. + */ + Gem(Item gem, Item bolt, int level, double experience) { + this.gem = gem; + this.bolt = bolt; + this.level = level; + this.experience = experience; + } + + /** + * Represents the gem. + */ + private final Item gem; + + /** + * Represents the bolt. + */ + private final Item bolt; + + /** + * Represents the level required. + */ + private final int level; + + /** + * Represents the experience gained. + */ + private final double experience; + + /** + * Gets the gem. + * @return The gem. + */ + public Item getGem() { + return gem; + } + + /** + * Gets the bolt. + * @return The bolt. + */ + public Item getBolt() { + return bolt; + } + + /** + * Gets the level. + * @return The level. + */ + public int getLevel() { + return level; + } + + /** + * Gets the experience. + * @return The experience. + */ + public double getExperience() { + return experience; + } + + /** + * Method used to get a gem for the item. + * @param item the item. + * @return the gem. + */ + public static Gem forItem(final Item item) { + for (Gem gem : values()) { + if (gem.getGem().getId() == item.getId()) { + return gem; + } + } + return null; + } + +} diff --git a/Server/src/main/content/global/skill/fletching/items/gem/GemBolt.java b/Server/src/main/content/global/skill/fletching/items/gem/GemBolt.java new file mode 100644 index 0000000..b21e6a1 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/items/gem/GemBolt.java @@ -0,0 +1,144 @@ +/* +package core.game.node.entity.skill.fletching.items.gem; + +import org.crandor.game.node.item.Item; + +*/ +/** + * Represents a gem bolt. + * @author 'Vexia + * @date 01/12/2013 + *//* + +public enum GemBolt { + OPAL(new Item(877, 10), new Item(45, 10), new Item(879, 10), 11, 1.5), + PEARL(new Item(9140, 10), new Item(46, 10), new Item(880, 10), 41, 3.2), + JADE(new Item(9139, 10), new Item(9187, 10), new Item(9335, 10), 26, 2.4), + RED_TOPAZ(new Item(9141, 10), new Item(9188, 10), new Item(9336, 10), 48, 3.9), + SAPPHIRE(new Item(9142, 10), new Item(9189, 10), new Item(9337, 10), 56, 4), + EMERALD(new Item(9142, 10), new Item(9190, 10), new Item(9338, 10), 58, 5.5), + RUBY(new Item(9143, 10), new Item(9191, 10), new Item(9339, 10), 63, 6.3), + DIAMOND(new Item(9143, 10), new Item(9192, 10), new Item(9340, 10), 65, 7), + DRAGONSTONE(new Item(9144, 10), new Item(9193, 10), new Item(9341, 10), 71, 8.2), + ONYX(new Item(9144, 10), new Item(9194, 10), new Item(9342, 10), 73, 9.4); + + */ +/** + * Constructs a new {@code GemBolt} {@code Object}. + * @param base the base. + * @param tip the tip. + * @param level the level. + * @param experience the experience. + *//* + + GemBolt(Item base, Item tip, Item product, int level, double experience) { + this.base = base; + this.tip = tip; + this.product = product; + this.level = level; + this.experience = experience; + } + + */ +/** + * Represents the base item. + *//* + + private final Item base; + + */ +/** + * Represents the tip to attach. + *//* + + private final Item tip; + + */ +/** + * Represents the product. + *//* + + private final Item product; + + */ +/** + * Represents the level. + *//* + + private final int level; + + */ +/** + * Represents the experience. + *//* + + private final double experience; + + */ +/** + * Gets the base. + * @return The base. + *//* + + public Item getBase() { + return base; + } + + */ +/** + * Gets the tip. + * @return The tip. + *//* + + public Item getTip() { + return tip; + } + + */ +/** + * Gets the product. + * @return The product. + *//* + + public Item getProduct() { + return product; + } + + */ +/** + * Gets the level. + * @return The level. + *//* + + public int getLevel() { + return level; + } + + */ +/** + * Gets the experience. + * @return The experience. + *//* + + public double getExperience() { + return experience; + } + + */ +/** + * Method used to get the gem bolt from the id. + * @param boltt the boltt. + * @param tip the tip. + * @return the bolt. + *//* + + public static GemBolt forItems(final Item boltt, final Item tip) { + for (GemBolt bolt : values()) { + if (bolt.getBase().getId() == boltt.getId() && bolt.getTip().getId() == tip.getId() || bolt.getBase().getId() == tip.getId() && bolt.getTip().getId() == boltt.getId()) { + return bolt; + } + } + return null; + } +} +*/ diff --git a/Server/src/main/content/global/skill/fletching/items/gem/GemBoltCutPulse.kt b/Server/src/main/content/global/skill/fletching/items/gem/GemBoltCutPulse.kt new file mode 100644 index 0000000..e037815 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/items/gem/GemBoltCutPulse.kt @@ -0,0 +1,68 @@ +package content.global.skill.fletching.items.gem + +import core.game.node.entity.player.Player +import core.game.node.entity.skill.SkillPulse +import core.game.node.entity.skill.Skills +import content.global.skill.fletching.Fletching.GemBolts +import core.game.node.item.Item +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items + +/** + * Represents the gem cutting pulse(gem to bolt). + * @author Ceikry + */ +class GemBoltCutPulse +/** + * Constructs a new `GemCutPulse.java` `Object`. + * @param player the player. + * @param node the node. + * @param amount the amount. + */(player: Player?, node: Item?, + /** + * Represents the gem we're cutting. + */ + private val gem: GemBolts, + /** + * Represents the amount to make. + */ + private var amount: Int) : SkillPulse(player, node) { + /** + * Represents the ticks passed. + */ + private var ticks = 0 + + override fun checkRequirements(): Boolean { + if (player.skills.getLevel(Skills.FLETCHING) < gem.level) { + player.dialogueInterpreter.sendDialogue("You need a Fletching level of " + gem.level + " or above to do that.") + return false + } + return player.inventory.containsItem(Item(gem.gem)) + } + + override fun animate() { + if (ticks % 6 == 0) { + player.animate(ANIMATION) + } + } + + override fun reward(): Boolean { + if (++ticks % 5 != 0) { + return false + } + val reward = if (gem.gem == Items.OYSTER_PEARLS_413) Item(gem.tip, 24) else Item(gem.tip, 12) + if (player.inventory.remove(Item(gem.gem))) { + player.inventory.add(reward) + player.skills.addExperience(Skills.FLETCHING, gem.experience, true) + } + amount-- + return amount <= 0 + } + + companion object { + /** + * Represents the cutting animation. + */ + private val ANIMATION = Animation(6702) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/fletching/items/gem/GemBoltPulse.java b/Server/src/main/content/global/skill/fletching/items/gem/GemBoltPulse.java new file mode 100644 index 0000000..4cd856e --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/items/gem/GemBoltPulse.java @@ -0,0 +1,91 @@ +package content.global.skill.fletching.items.gem; + +import core.game.node.entity.skill.SkillPulse; +import core.game.node.entity.skill.Skills; +import content.global.skill.fletching.Fletching; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +/** + * Represents the attaching of a gem bolt to a premade bolt. + * @author Ceikry + */ +public final class GemBoltPulse extends SkillPulse { + + /** + * Represents the gem bolt being made. + */ + private Fletching.GemBolts bolt; + + /** + * Represents the sets to make. + */ + private int sets = 0; + + /** + * Represents the ticks passed. + */ + private int ticks; + + /** + * Constructs a new {@code GemBoltPulse} {@code Object}. + * @param player the player. + * @param node the node. + * @param sets the sets. + */ + public GemBoltPulse(Player player, Item node, Fletching.GemBolts bolt, int sets) { + super(player, node); + this.bolt = bolt; + this.sets = sets; + } + + @Override + public boolean checkRequirements() { + if (player.getSkills().getLevel(Skills.FLETCHING) < bolt.level) { + player.getDialogueInterpreter().sendDialogue("You need a Fletching level of " + bolt.level + " or above to do that."); + return false; + } + if (!player.getInventory().containsItem(new Item(bolt.base)) || !player.getInventory().containsItem(new Item(bolt.tip))) { + return false; + } + if (!player.getInventory().hasSpaceFor(new Item(bolt.product))){ + player.getDialogueInterpreter().sendDialogue("You do not have enough inventory space."); + return false; + } + return true; + } + + @Override + public void animate() { + } + + @Override + public boolean reward() { + if (++ticks % 3 != 0) { + return false; + } + int baseAmount = player.getInventory().getAmount(bolt.base); + int tipAmount = player.getInventory().getAmount(bolt.tip); + Item base = new Item(bolt.base); + Item tip = new Item(bolt.tip); + Item product = new Item(bolt.product); + if(baseAmount >= 10 && tipAmount >= 10){ + base.setAmount(10); + tip.setAmount(10); + product.setAmount(10); + } else { + int amount = baseAmount > tipAmount ? tipAmount : baseAmount; + base.setAmount(amount); + tip.setAmount(amount); + product.setAmount(amount); + } + if (player.getInventory().remove(base,tip)) { + player.getInventory().add(product); + player.getSkills().addExperience(Skills.FLETCHING, bolt.experience * product.getAmount(), true); + player.getPacketDispatch().sendMessage(product.getAmount() == 1 ? "You attach the tip to the bolt." : "You fletch " + product.getAmount() + " bolts."); + } + sets--; + return sets <= 0; + } + +} diff --git a/Server/src/main/content/global/skill/fletching/items/grapple/GrapplePulse.java b/Server/src/main/content/global/skill/fletching/items/grapple/GrapplePulse.java new file mode 100644 index 0000000..cbba382 --- /dev/null +++ b/Server/src/main/content/global/skill/fletching/items/grapple/GrapplePulse.java @@ -0,0 +1,85 @@ +package content.global.skill.fletching.items.grapple; + +import core.game.node.entity.skill.SkillPulse; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +/** + * Represents the skill pulse used to create a mith grapple. + * @author 'Vexia + * @date 21/12/2013 + */ +public final class GrapplePulse extends SkillPulse { + + /** + * Represents the mith grapple tip. + */ + private static final Item MITH_GRAPPLE = new Item(9418); + + /** + * Represents the mithril grapple tio. + */ + private static final Item GRAPPLE_TIP = new Item(9416); + + /** + * Represents the mithril bolt. + */ + private static final Item MITHRIL_BOLT = new Item(9142); + + /** + * Represents the amount of the grapple to make. + */ + private int amount; + + /** + * Constructs a new {@code GrapplePulse} {@code Object}. + * @param player the player. + * @param node the node. + * @param amount the amount. + */ + public GrapplePulse(Player player, Item node, int amount) { + super(player, node); + this.amount = amount; + } + + @Override + public boolean checkRequirements() { + int inventoryAmount = player.getInventory().getAmount(GRAPPLE_TIP); + if (amount > inventoryAmount) { + amount = inventoryAmount; + } + if (!player.getInventory().containsItem(GRAPPLE_TIP) || !player.getInventory().containsItem(MITHRIL_BOLT)) { + return false; + } + if (player.getSkills().getLevel(Skills.FLETCHING) < 59) { + player.getDialogueInterpreter().sendDialogue("You need a fletching level of at least 59 in order to do this."); + return false; + } + return true; + } + + @Override + public void animate() { + } + + @Override + public boolean reward() { + if (getDelay() == 1) { + setDelay(3); + return false; + } + if (player.getInventory().remove(GRAPPLE_TIP) && player.getInventory().remove(MITHRIL_BOLT)) { + player.getInventory().add(MITH_GRAPPLE); + player.getSkills().addExperience(Skills.FLETCHING, 5, true); + } + amount--; + return amount < 1; + } + + @Override + public void message(int type) { + + } + +} diff --git a/Server/src/main/content/global/skill/gather/GatheringSkillOptionListeners.kt b/Server/src/main/content/global/skill/gather/GatheringSkillOptionListeners.kt new file mode 100644 index 0000000..cc7112f --- /dev/null +++ b/Server/src/main/content/global/skill/gather/GatheringSkillOptionListeners.kt @@ -0,0 +1,25 @@ +package content.global.skill.gather + +import content.global.skill.fishing.FishingSpot +import content.global.skill.gather.fishing.FishingPulse +import core.game.interaction.InteractionListener +import core.game.node.Node +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player + +class GatheringSkillOptionListeners : InteractionListener { + + val ETCETERIA_REGION = 10300 + + override fun defineListeners() { + + } + + fun fish(player: Player, node: Node, opt: String): Boolean{ + val npc = node as NPC + val spot = FishingSpot.forId(npc.id) ?: return false + val op = spot.getOptionByName(opt) ?: return false + player.pulseManager.run(FishingPulse(player, npc, op)) + return true + } +} diff --git a/Server/src/main/content/global/skill/gather/PickaxeRepairPlugin.kt b/Server/src/main/content/global/skill/gather/PickaxeRepairPlugin.kt new file mode 100644 index 0000000..83e3db8 --- /dev/null +++ b/Server/src/main/content/global/skill/gather/PickaxeRepairPlugin.kt @@ -0,0 +1,44 @@ +package content.global.skill.gather + +import core.api.playAudio +import core.game.interaction.NodeUsageEvent +import core.game.interaction.UseWithHandler +import core.game.node.item.Item +import core.plugin.Initializable +import core.plugin.Plugin +import org.rs09.consts.Sounds + +/** + * Repairs pickaxes after being broken + * @author Ceikry + */ +@Initializable +class PickaxeRepairPlugin : UseWithHandler(480,482,484,486,488,490){ + override fun newInstance(arg: Any?): Plugin { + addHandler(466, ITEM_TYPE,this) + return this + } + + override fun handle(event: NodeUsageEvent?): Boolean { + event ?: return false + val used = event.used + + val product = + when(used.id){ + 480 -> 1265 + 482 -> 1267 + 484 -> 1269 + 488 -> 1271 + 486 -> 1273 + 490 -> 1275 + else -> 0 + } + event.player.inventory.remove(Item(466)) + event.player.inventory.remove(used.asItem()) + event.player.inventory.add(Item(product)) + event.player.sendMessage("You carefully reattach the head to the handle.") + playAudio(event.player, Sounds.EYEGLO_COIN_10) + return true + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/gather/SkillingResource.java b/Server/src/main/content/global/skill/gather/SkillingResource.java new file mode 100644 index 0000000..2d2b43e --- /dev/null +++ b/Server/src/main/content/global/skill/gather/SkillingResource.java @@ -0,0 +1,921 @@ +package content.global.skill.gather; + +import core.ServerConstants; +import core.game.node.entity.skill.Skills; +import core.tools.SystemLogger; +import core.game.world.repository.Repository; +import core.game.world.update.flag.context.Animation; + +import java.util.HashMap; +import java.util.Map; + +/** + * Represents a skill resource. + * @author Emperor + */ +public enum SkillingResource { + + /** + * Standard tree (Woodcutting). + */ + STANDARD_TREE_1(1276, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "tree", null, 1342, Skills.WOODCUTTING), + STANDARD_TREE_2(1277, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "tree", null, 1343, Skills.WOODCUTTING), + STANDARD_TREE_3(1278, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "tree", null, 1342, Skills.WOODCUTTING), + STANDARD_TREE_4(1279, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "tree", null, 1345, Skills.WOODCUTTING), + STANDARD_TREE_5(1280, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "tree", null, 1343, Skills.WOODCUTTING), + STANDARD_TREE_6(1330, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "tree", null, 1341, Skills.WOODCUTTING), + STANDARD_TREE_7(1331, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "tree", null, 1341, Skills.WOODCUTTING), + STANDARD_TREE_8(1332, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "tree", null, 1341, Skills.WOODCUTTING), + STANDARD_TREE_9(2409, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "tree", null, 1342, Skills.WOODCUTTING), + STANDARD_TREE_10(3033, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "tree", null, 1345, Skills.WOODCUTTING), + STANDARD_TREE_11(3034, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "tree", null, 1345, Skills.WOODCUTTING), + STANDARD_TREE_12(3035, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "tree", null, 1347, Skills.WOODCUTTING), + STANDARD_TREE_13(3036, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "tree", null, 1351, Skills.WOODCUTTING), + STANDARD_TREE_14(3879, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "tree", null, 3880, Skills.WOODCUTTING), + STANDARD_TREE_15(3881, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "tree", null, 3880, Skills.WOODCUTTING), + STANDARD_TREE_16(3882, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "tree", null, 3880, Skills.WOODCUTTING), + STANDARD_TREE_17(3883, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "tree", null, 3884, Skills.WOODCUTTING), + STANDARD_TREE_18(10041, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "tree", null, 1342, Skills.WOODCUTTING), + STANDARD_TREE_19(14308, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "tree", null, 1342, Skills.WOODCUTTING), + STANDARD_TREE_20(14309, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "tree", null, 1342, Skills.WOODCUTTING), + STANDARD_TREE_21(16264, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "tree", null, 1342, Skills.WOODCUTTING), + STANDARD_TREE_22(16265, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "tree", null, 1342, Skills.WOODCUTTING), + STANDARD_TREE_23(30132, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "tree", null, 1342, Skills.WOODCUTTING), + STANDARD_TREE_24(30133, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "tree", null, 1342, Skills.WOODCUTTING), + STANDARD_TREE_25(37477, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "tree", null, 1342, Skills.WOODCUTTING), + STANDARD_TREE_26(37478, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "tree", null, 37653, Skills.WOODCUTTING), + STANDARD_TREE_27(37652, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "tree", null, 37653, Skills.WOODCUTTING), + + /** + * Fruit trees. + */ + APPLE_TREE(7941, 1, 0.05, 50 | 100 << 16, 25.0, -1, 1, "tree", null, 37653, Skills.WOODCUTTING, true), + BANANA_TREE(8000, 1, 0.05, 50 | 100 << 16, 25.0, -1, 1, "tree", null, 37653, Skills.WOODCUTTING, true), + ORANGE_TREE(8057, 1, 0.05, 50 | 100 << 16, 25.0, -1, 1, "tree", null, 37653, Skills.WOODCUTTING, true), + CURRY_TREE(8026, 1, 0.05, 50 | 100 << 16, 25.0, -1, 1, "tree", null, 37653, Skills.WOODCUTTING, true), + PINEAPPLE_TREE(7972, 1, 0.05, 50 | 100 << 16, 25.0, -1, 1, "tree", null, 37653, Skills.WOODCUTTING, true), + PAPAYA_TREE(8111, 1, 0.05, 50 | 100 << 16, 25.0, -1, 1, "tree", null, 37653, Skills.WOODCUTTING, true), + PALM_TREE(8084, 1, 0.05, 50 | 100 << 16, 25.0, -1, 1, "tree", null, 37653, Skills.WOODCUTTING, true), + + /** + * Dead tree (Woodcutting). + */ + DEAD_TREE_1(1282, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "dead tree", null, 1347, Skills.WOODCUTTING), + DEAD_TREE_2(1283, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "dead tree", null, 1347, Skills.WOODCUTTING), + DEAD_TREE_3(1284, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "dead tree", null, 1348, Skills.WOODCUTTING), + DEAD_TREE_4(1285, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "dead tree", null, 1349, Skills.WOODCUTTING), + DEAD_TREE_5(1286, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "dead tree", null, 1351, Skills.WOODCUTTING), + DEAD_TREE_6(1289, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "dead tree", null, 1353, Skills.WOODCUTTING), + DEAD_TREE_7(1290, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "dead tree", null, 1354, Skills.WOODCUTTING), + DEAD_TREE_8(1291, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "dead tree", null, 23054, Skills.WOODCUTTING), + DEAD_TREE_9(1365, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "dead tree", null, 1352, Skills.WOODCUTTING), + DEAD_TREE_10(1383, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "dead tree", null, 1358, Skills.WOODCUTTING), + DEAD_TREE_11(1384, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "dead tree", null, 1359, Skills.WOODCUTTING), + DEAD_TREE_12(5902, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "dead tree", null, 1347, Skills.WOODCUTTING), + DEAD_TREE_13(5903, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "dead tree", null, 1353, Skills.WOODCUTTING), + DEAD_TREE_14(5904, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "dead tree", null, 1353, Skills.WOODCUTTING), + DEAD_TREE_15(32294, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "dead tree", null, 1353, Skills.WOODCUTTING), + DEAD_TREE_16(37481, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "dead tree", null, 1347, Skills.WOODCUTTING), + DEAD_TREE_17(37482, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "dead tree", null, 1351, Skills.WOODCUTTING), + DEAD_TREE_18(37483, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "dead tree", null, 1358, Skills.WOODCUTTING), + DEAD_TREE_19(24168, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "dying tree", null, 24169, Skills.WOODCUTTING), + + /** + * Dramen tree (Woodcutting/Lost city quest). + */ + DRAMEN_TREE(1292, 36, 0.05, -1, 25.0, 771, Integer.MAX_VALUE, "dramen tree", null, -1, Skills.WOODCUTTING), + + /** + * Evergreen (Woodcutting). + */ + EVERGREEN_1(1315, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "evergreen", null, 1342, Skills.WOODCUTTING), + EVERGREEN_2(1316, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "evergreen", null, 1355, Skills.WOODCUTTING), + EVERGREEN_3(1318, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "evergreen", null, 1355, Skills.WOODCUTTING), + EVERGREEN_4(1319, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 1, "evergreen", null, 1355, Skills.WOODCUTTING), + + /** + * Jungle tree (Woodcutting). + */ + JUNGLE_TREE_1(2887, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 2, "jungle tree", null, 0, Skills.WOODCUTTING), + JUNGLE_TREE_2(2889, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 2, "jungle tree", null, 0, Skills.WOODCUTTING), + JUNGLE_TREE_3(2890, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 2, "jungle tree", null, 0, Skills.WOODCUTTING), + JUNGLE_TREE_4(4818, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 2, "jungle tree", null, 0, Skills.WOODCUTTING), + JUNGLE_TREE_5(4820, 1, 0.05, 50 | 100 << 16, 25.0, 1511, 2, "jungle tree", null, 0, Skills.WOODCUTTING), + + JUNGLE_BUSH_1(2892, 1, 0.15, 50 | 100 << 16, 100.0, 1511, 1, "jungle bush", null, 2894, Skills.WOODCUTTING), + JUNGLE_BUSH_2(2893, 1, 0.15, 50 | 100 << 16, 100.0, 1511, 1, "jungle bush", null, 2895, Skills.WOODCUTTING), + + /** + * Achey tree (Woodcutting). + */ + ACHEY_TREE(2023, 1, 0.05, 50 | 100 << 16, 25.0, 2862, 1, "achey tree", null, 3371, Skills.WOODCUTTING), + + /** + * Oak tree (Woodcutting). + */ + OAK_TREE_1(1281, 15, 0.15, 14 | 22 << 16, 37.5, 1521, 10, "oak tree", null, 1356, Skills.WOODCUTTING), + OAK_TREE_2(3037, 15, 0.15, 14 | 22 << 16, 37.5, 1521, 10, "oak tree", null, 1357, Skills.WOODCUTTING), + OAK_TREE_3(37479, 15, 0.15, 14 | 22 << 16, 37.5, 1521, 10, "oak tree", null, 1356, Skills.WOODCUTTING), + OAK_TREE_4(8467, 15, 0.15, 14 | 22 << 16, 37.5, 1521, 10, "oak tree", null, 1356, Skills.WOODCUTTING, true), + + /** + * Willow tree (Woodcutting). + */ + WILLOW_TREE_1(1308, 30, 0.3, 14 | 22 << 16, 67.8, 1519, 20, "willow tree", null, 7399, Skills.WOODCUTTING), + WILLOW_TREE_2(5551, 30, 0.3, 14 | 22 << 16, 67.8, 1519, 20, "willow tree", null, 5554, Skills.WOODCUTTING), + WILLOW_TREE_3(5552, 30, 0.3, 14 | 22 << 16, 67.8, 1519, 20, "willow tree", null, 5554, Skills.WOODCUTTING), + WILLOW_TREE_4(5553, 30, 0.3, 14 | 22 << 16, 67.8, 1519, 20, "willow tree", null, 5554, Skills.WOODCUTTING), + WILLOW_TREE_5(37480, 30, 0.3, 14 | 22 << 16, 67.8, 1519, 20, "willow tree", null, 7399, Skills.WOODCUTTING), + WILLOW_TREE_6(8488, 30, 0.3, 14 | 22 << 16, 67.8, 1519, 20, "willow tree", null, 7399, Skills.WOODCUTTING, true), + + /** + * Teak (Woodcutting). + */ + TEAK_1(9036, 35, 0.7, 35 | 60 << 16, 85.0, 6333, 25, "teak", null, 9037, Skills.WOODCUTTING), + TEAK_2(15062, 35, 0.7, 35 | 60 << 16, 85.0, 6333, 25, "teak", null, 9037, Skills.WOODCUTTING), + + /** + * Maple tree (Woodcutting). + */ + MAPLE_TREE_1(1307, 45, 0.65, 58 | 100 << 16, 100.0, 1517, 30, "maple tree", null, 7400, Skills.WOODCUTTING), + MAPLE_TREE_2(4674, 45, 0.65, 58 | 100 << 16, 100.0, 1517, 30, "maple tree", null, 7400, Skills.WOODCUTTING), + MAPLE_TREE_3(8444, 45, 0.65, 58 | 100 << 16, 100.0, 1517, 30, "maple tree", null, 7400, Skills.WOODCUTTING, true), + + /** + * Hollow tree (Woodcutting). + */ + HOLLOW_TREE_1(2289, 45, 0.6, 58 | 100 << 16, 82.5, 3239, 30, "hollow tree", null, 2310, Skills.WOODCUTTING), + HOLLOW_TREE_2(4060, 45, 0.6, 58 | 100 << 16, 82.5, 3239, 30, "hollow tree", null, 4061, Skills.WOODCUTTING), + + /** + * Mahogany (Woodcutting). + */ + MAHOGANY(9034, 50, 0.7, 62 | 115 << 16, 125.0, 6332, 35, "mahogany", null, 9035, Skills.WOODCUTTING), + + /** + * Arctic pine (Woodcutting). + */ + ARCTIC_PINE(21273, 54, 0.73, 75 | 130 << 16, 140.2, 10810, 35, "arctic pine", null, 21274, Skills.WOODCUTTING), + + /** + * Eucalyptus tree (Woodcutting). + */ + EUCALYPTUS_1(28951, 58, 0.77, 80 | 140 << 16, 165.0, 12581, 35, "eucalyptus tree", null, 28954, Skills.WOODCUTTING), + EUCALYPTUS_2(28952, 58, 0.77, 80 | 140 << 16, 165.0, 12581, 35, "eucalyptus tree", null, 28955, Skills.WOODCUTTING), + EUCALYPTUS_3(28953, 58, 0.77, 80 | 140 << 16, 165.0, 12581, 35, "eucalyptus tree", null, 28956, Skills.WOODCUTTING), + + /** + * Yew tree (Woodcutting). + */ + YEW(1309, 60, 0.8, 100 | 162 << 16, 175.0, 1515, 40, "yew", null, 7402, Skills.WOODCUTTING), + YEW_1(8513, 60, 0.8, 100 | 162 << 16, 175.0, 1515, 40, "yew", null, 7402, Skills.WOODCUTTING, true), + + /** + * Magic tree (Woodcutting). + */ + MAGIC_TREE_1(1306, 75, 0.9, 200 | 317 << 16, 250.0, 1513, 50, "magic tree", null, 7401, Skills.WOODCUTTING), + MAGIC_TREE_2(37823, 75, 0.9, 200 | 317 << 16, 250.0, 1513, 50, "magic tree", null, 37824, Skills.WOODCUTTING), + MAGIC_TREE_3(8409, 75, 0.9, 200 | 317 << 16, 250.0, 1513, 50, "magic tree", null, 37824, Skills.WOODCUTTING, true), + + CURSED_MAGIC_TREE(37821, 82, 0.95, 200 | 317 << 16, 275.0, 1513, 50, "magic tree", null, 37822, Skills.WOODCUTTING), + + /** + * Copper ore (Mining). + */ + COPPER_ORE_0(2090, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 450, Skills.MINING), + COPPER_ORE_1(2091, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 452, Skills.MINING), + COPPER_ORE_2(4976, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 4994, Skills.MINING), + COPPER_ORE_3(4977, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 4995, Skills.MINING), + COPPER_ORE_4(4978, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 4996, Skills.MINING), + COPPER_ORE_5(9710, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 18954, Skills.MINING), + COPPER_ORE_6(9709, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 32448, Skills.MINING), + COPPER_ORE_7(9708, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 32447, Skills.MINING), + COPPER_ORE_8(11960, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 11555, Skills.MINING), + COPPER_ORE_9(11961, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 11556, Skills.MINING), + COPPER_ORE_10(11962, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 11557, Skills.MINING), + COPPER_ORE_11(11937, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 11553, Skills.MINING), + COPPER_ORE_12(11936, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 11552, Skills.MINING), + COPPER_ORE_13(11938, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 11554, Skills.MINING), + COPPER_ORE_14(12746, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 450, Skills.MINING), + COPPER_ORE_15(14906, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 14894, Skills.MINING), + COPPER_ORE_16(14907, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 14895, Skills.MINING), + COPPER_ORE_17(20448, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 20445, Skills.MINING), + COPPER_ORE_18(20451, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 20445, Skills.MINING), + COPPER_ORE_19(20446, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 20443, Skills.MINING), + COPPER_ORE_20(20447, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 20444, Skills.MINING), + COPPER_ORE_21(20408, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 20407, Skills.MINING), + COPPER_ORE_22(18993, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 19005, Skills.MINING), + COPPER_ORE_23(18992, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 19004, Skills.MINING), + COPPER_ORE_24(19007, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 19016, Skills.MINING), + COPPER_ORE_25(19006, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 19021, Skills.MINING), + COPPER_ORE_26(18991, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 19003, Skills.MINING), + COPPER_ORE_27(19008, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 19017, Skills.MINING), + COPPER_ORE_28(21285, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 21297, Skills.MINING), + COPPER_ORE_29(21284, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 21296, Skills.MINING), + COPPER_ORE_30(21286, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 21298, Skills.MINING), + COPPER_ORE_31(29231, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 29219, Skills.MINING), + COPPER_ORE_32(29230, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 29218, Skills.MINING), + COPPER_ORE_33(29232, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 29220, Skills.MINING), + COPPER_ORE_34(31082, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 37650, Skills.MINING), + COPPER_ORE_35(31081, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 37649, Skills.MINING), + COPPER_ORE_36(31080, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 37639, Skills.MINING), + COPPER_ORE_37(37647, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 37650, Skills.MINING), + COPPER_ORE_38(37646, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 37649, Skills.MINING), + COPPER_ORE_39(37645, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 37639, Skills.MINING), + COPPER_ORE_40(37637, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 37639, Skills.MINING), + COPPER_ORE_41(37688, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 21298, Skills.MINING), + COPPER_ORE_42(37686, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 21296, Skills.MINING), + COPPER_ORE_43(37687, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 21297, Skills.MINING), + COPPER_ORE_44(3042, 1, 0.05, 4 | 8 << 16, 17.5, 436, 1, "copper rocks", null, 11552, Skills.MINING), + + /** + * Tin ore (Mining). + */ + TIN_ORE_0(2094, 1, 0.05, 4 | 8 << 16, 17.5, 438, 1, "tin rocks", null, 450, Skills.MINING), + TIN_ORE_1(2095, 1, 0.05, 4 | 8 << 16, 17.5, 438, 1, "tin rocks", null, 452, Skills.MINING), + TIN_ORE_2(3043, 1, 0.05, 4 | 8 << 16, 17.5, 438, 1, "tin rocks", null, 11552, Skills.MINING), + TIN_ORE_3(4979, 1, 0.05, 4 | 8 << 16, 17.5, 438, 1, "tin rocks", null, 4994, Skills.MINING), + TIN_ORE_4(4980, 1, 0.05, 4 | 8 << 16, 17.5, 438, 1, "tin rocks", null, 4995, Skills.MINING), + TIN_ORE_5(4981, 1, 0.05, 4 | 8 << 16, 17.5, 438, 1, "tin rocks", null, 4996, Skills.MINING), + TIN_ORE_6(11957, 1, 0.05, 4 | 8 << 16, 17.5, 438, 1, "tin rocks", null, 11555, Skills.MINING), + TIN_ORE_7(11958, 1, 0.05, 4 | 8 << 16, 17.5, 438, 1, "tin rocks", null, 11556, Skills.MINING), + TIN_ORE_8(11959, 1, 0.05, 4 | 8 << 16, 17.5, 438, 1, "tin rocks", null, 11557, Skills.MINING), + TIN_ORE_9(11934, 1, 0.05, 4 | 8 << 16, 17.5, 438, 1, "tin rocks", null, 11553, Skills.MINING), + TIN_ORE_10(11935, 1, 0.05, 4 | 8 << 16, 17.5, 438, 1, "tin rocks", null, 11554, Skills.MINING), + TIN_ORE_11(11933, 1, 0.05, 4 | 8 << 16, 17.5, 438, 1, "tin rocks", null, 11552, Skills.MINING), + TIN_ORE_12(14902, 1, 0.05, 4 | 8 << 16, 17.5, 438, 1, "tin rocks", null, 14894, Skills.MINING), + TIN_ORE_13(14903, 1, 0.05, 4 | 8 << 16, 17.5, 438, 1, "tin rocks", null, 14895, Skills.MINING), + TIN_ORE_14(18995, 1, 0.05, 4 | 8 << 16, 17.5, 438, 1, "tin rocks", null, 19004, Skills.MINING), + TIN_ORE_15(18994, 1, 0.05, 4 | 8 << 16, 17.5, 438, 1, "tin rocks", null, 19003, Skills.MINING), + TIN_ORE_16(18996, 1, 0.05, 4 | 8 << 16, 17.5, 438, 1, "tin rocks", null, 19005, Skills.MINING), + TIN_ORE_17(19025, 1, 0.05, 4 | 8 << 16, 17.5, 438, 1, "tin rocks", null, 19016, Skills.MINING), + TIN_ORE_18(19024, 1, 0.05, 4 | 8 << 16, 17.5, 438, 1, "tin rocks", null, 19021, Skills.MINING), + TIN_ORE_19(19026, 1, 0.05, 4 | 8 << 16, 17.5, 438, 1, "tin rocks", null, 19017, Skills.MINING), + TIN_ORE_20(21293, 1, 0.05, 4 | 8 << 16, 17.5, 438, 1, "tin rocks", null, 21296, Skills.MINING), + TIN_ORE_21(21295, 1, 0.05, 4 | 8 << 16, 17.5, 438, 1, "tin rocks", null, 21298, Skills.MINING), + TIN_ORE_22(21294, 1, 0.05, 4 | 8 << 16, 17.5, 438, 1, "tin rocks", null, 21297, Skills.MINING), + TIN_ORE_23(29227, 1, 0.05, 4 | 8 << 16, 17.5, 438, 1, "tin rocks", null, 29218, Skills.MINING), + TIN_ORE_24(29229, 1, 0.05, 4 | 8 << 16, 17.5, 438, 1, "tin rocks", null, 29220, Skills.MINING), + TIN_ORE_25(29228, 1, 0.05, 4 | 8 << 16, 17.5, 438, 1, "tin rocks", null, 29219, Skills.MINING), + TIN_ORE_26(31079, 1, 0.05, 4 | 8 << 16, 17.5, 438, 1, "tin rocks", null, 37650, Skills.MINING), + TIN_ORE_27(31078, 1, 0.05, 4 | 8 << 16, 17.5, 438, 1, "tin rocks", null, 37649, Skills.MINING), + TIN_ORE_28(31077, 1, 0.05, 4 | 8 << 16, 17.5, 438, 1, "tin rocks", null, 37639, Skills.MINING), + TIN_ORE_29(37644, 1, 0.05, 4 | 8 << 16, 17.5, 438, 1, "tin rocks", null, 37650, Skills.MINING), + TIN_ORE_30(37643, 1, 0.05, 4 | 8 << 16, 17.5, 438, 1, "tin rocks", null, 37649, Skills.MINING), + TIN_ORE_31(37642, 1, 0.05, 4 | 8 << 16, 17.5, 438, 1, "tin rocks", null, 37639, Skills.MINING), + TIN_ORE_32(37638, 1, 0.05, 4 | 8 << 16, 17.5, 438, 1, "tin rocks", null, 37639, Skills.MINING), + TIN_ORE_33(37685, 1, 0.05, 4 | 8 << 16, 17.5, 438, 1, "tin rocks", null, 21298, Skills.MINING), + + /** + * Rune/Pure essence (Mining). + */ + RUNE_ESSENCE(2491, 1, 0.1, 1 | 1 << 16, 5.0, 1436, Integer.MAX_VALUE, "rune essence", null, -1, Skills.MINING), + + /** + * Clay (Mining). + */ + CLAY_0(2109, 1, 0.1, 1 | 1 << 16, 5.0, 434, 1, "clay", null, 452, Skills.MINING), + CLAY_1(2108, 1, 0.1, 1 | 1 << 16, 5.0, 434, 1, "clay", null, 450, Skills.MINING), + CLAY_2(9712, 1, 0.1, 1 | 1 << 16, 5.0, 434, 1, "clay", null, 32448, Skills.MINING), + CLAY_3(9713, 1, 0.1, 1 | 1 << 16, 5.0, 434, 1, "clay", null, 18954, Skills.MINING), + CLAY_4(9711, 1, 0.1, 1 | 1 << 16, 5.0, 434, 1, "clay", null, 32447, Skills.MINING), + CLAY_5(10949, 1, 0.1, 1 | 1 << 16, 5.0, 434, 1, "clay", null, 10945, Skills.MINING), + CLAY_6(11190, 1, 0.1, 1 | 1 << 16, 5.0, 434, 1, "clay", null, 21297, Skills.MINING), + CLAY_7(11191, 1, 0.1, 1 | 1 << 16, 5.0, 434, 1, "clay", null, 21298, Skills.MINING), + CLAY_8(11189, 1, 0.1, 1 | 1 << 16, 5.0, 434, 1, "clay", null, 21296, Skills.MINING), + CLAY_9(12942, 1, 0.1, 1 | 1 << 16, 5.0, 434, 1, "clay", null, 4995, Skills.MINING), + CLAY_10(12943, 1, 0.1, 1 | 1 << 16, 5.0, 434, 1, "clay", null, 4996, Skills.MINING), + CLAY_11(12941, 1, 0.1, 1 | 1 << 16, 5.0, 434, 1, "clay", null, 4994, Skills.MINING), + CLAY_12(14904, 1, 0.1, 1 | 1 << 16, 5.0, 434, 1, "clay", null, 14894, Skills.MINING), + CLAY_13(14905, 1, 0.1, 1 | 1 << 16, 5.0, 434, 1, "clay", null, 14895, Skills.MINING), + CLAY_14(15505, 1, 0.1, 1 | 1 << 16, 5.0, 434, 1, "clay", null, 11557, Skills.MINING), + CLAY_15(15504, 1, 0.1, 1 | 1 << 16, 5.0, 434, 1, "clay", null, 11556, Skills.MINING), + CLAY_16(15503, 1, 0.1, 1 | 1 << 16, 5.0, 434, 1, "clay", null, 11555, Skills.MINING), + CLAY_17(20449, 1, 0.1, 1 | 1 << 16, 5.0, 434, 1, "clay", null, 20443, Skills.MINING), + CLAY_18(20450, 1, 0.1, 1 | 1 << 16, 5.0, 434, 1, "clay", null, 20444, Skills.MINING), + CLAY_19(20409, 1, 0.1, 1 | 1 << 16, 5.0, 434, 1, "clay", null, 20407, Skills.MINING), + CLAY_20(32429, 1, 0.1, 1 | 1 << 16, 5.0, 434, 1, "clay", null, 33400, Skills.MINING), + CLAY_21(32430, 1, 0.1, 1 | 1 << 16, 5.0, 434, 1, "clay", null, 33401, Skills.MINING), + CLAY_22(32431, 1, 0.1, 1 | 1 << 16, 5.0, 434, 1, "clay", null, 33402, Skills.MINING), + CLAY_23(31062, 1, 0.1, 1 | 1 << 16, 5.0, 434, 1, "clay", null, 37639, Skills.MINING), + CLAY_24(31063, 1, 0.1, 1 | 1 << 16, 5.0, 434, 1, "clay", null, 37649, Skills.MINING), + CLAY_25(31064, 1, 0.1, 1 | 1 << 16, 5.0, 434, 1, "clay", null, 37650, Skills.MINING), + + /** + * Limestone. + */ + LIMESTONE_0(4027, 10, 0.2, 10 | 20 << 16, 26.5, 3211, 1, "limestone", null, 12564, Skills.MINING), + LIMESTONE_1(4028, 10, 0.2, 10 | 20 << 16, 26.5, 3211, 1, "limestone", null, 12565, Skills.MINING), + LIMESTONE_2(4029, 10, 0.2, 10 | 20 << 16, 26.5, 3211, 1, "limestone", null, 12566, Skills.MINING), + LIMESTONE_3(4030, 10, 0.2, 10 | 20 << 16, 26.5, 3211, 1, "limestone", null, 12567, Skills.MINING), + + /** + * Blurite ore. + */ + BLURITE_ORE_0(33220, 10, 0.2, 10 | 20 << 16, 17.5, 668, 1, "blurite rocks", null, 33222, Skills.MINING), + BLURITE_ORE_1(33221, 10, 0.2, 10 | 20 << 16, 17.5, 668, 1, "blurite rocks", null, 33223, Skills.MINING), + + /** + * Iron ore. + */ + IRON_ORE_0(2092, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 450, Skills.MINING), + IRON_ORE_1(2093, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 452, Skills.MINING), + IRON_ORE_2(4982, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 4994, Skills.MINING), + IRON_ORE_3(4983, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 4995, Skills.MINING), + IRON_ORE_4(4984, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 4996, Skills.MINING), + IRON_ORE_5(6943, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 21296, Skills.MINING), + IRON_ORE_6(6944, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 21297, Skills.MINING), + IRON_ORE_7(9718, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 32448, Skills.MINING), + IRON_ORE_8(9719, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 18954, Skills.MINING), + IRON_ORE_9(9717, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 32447, Skills.MINING), + IRON_ORE_10(11956, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 11557, Skills.MINING), + IRON_ORE_11(11954, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 11555, Skills.MINING), + IRON_ORE_12(11955, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 11556, Skills.MINING), + IRON_ORE_13(14914, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 14895, Skills.MINING), + IRON_ORE_14(14913, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 14894, Skills.MINING), + IRON_ORE_15(14858, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 25373, Skills.MINING), + IRON_ORE_16(14857, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 25372, Skills.MINING), + IRON_ORE_17(14856, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 25371, Skills.MINING), + IRON_ORE_18(14900, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 14894, Skills.MINING), + IRON_ORE_19(14901, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 14895, Skills.MINING), + IRON_ORE_20(20423, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 20444, Skills.MINING), + IRON_ORE_21(20422, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 20443, Skills.MINING), + IRON_ORE_22(20425, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 20407, Skills.MINING), + IRON_ORE_23(20424, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 20445, Skills.MINING), + IRON_ORE_24(19002, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 19005, Skills.MINING), + IRON_ORE_25(19001, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 19004, Skills.MINING), + IRON_ORE_26(19000, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 19003, Skills.MINING), + IRON_ORE_27(21281, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 21296, Skills.MINING), + IRON_ORE_28(21283, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 21298, Skills.MINING), + IRON_ORE_29(21282, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 21297, Skills.MINING), + IRON_ORE_30(29221, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 29218, Skills.MINING), + IRON_ORE_31(29223, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 29220, Skills.MINING), + IRON_ORE_32(29222, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 29219, Skills.MINING), + IRON_ORE_33(32441, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 33400, Skills.MINING), + IRON_ORE_34(32443, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 33402, Skills.MINING), + IRON_ORE_35(32442, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 33401, Skills.MINING), + IRON_ORE_36(32452, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 32448, Skills.MINING), + IRON_ORE_37(32451, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 32447, Skills.MINING), + IRON_ORE_38(31073, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 37650, Skills.MINING), + IRON_ORE_39(31072, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 37649, Skills.MINING), + IRON_ORE_40(31071, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 37639, Skills.MINING), + IRON_ORE_41(37307, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 11552, Skills.MINING), + IRON_ORE_42(37309, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 11554, Skills.MINING), + IRON_ORE_43(37308, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 11553, Skills.MINING), + IRON_ORE_49(42034, 15, 0.2, 15 | 25 << 16, 35.0, 440, 1, "iron rocks", null, 450, Skills.MINING), + + /** + * Silver ore. + */ + SILVER_ORE_0(2101, 20, 0.3, 100 | 200 << 16, 40.0, 442, 1, "silver rocks", null, 452, Skills.MINING), + SILVER_ORE_1(2100, 20, 0.3, 100 | 200 << 16, 40.0, 442, 1, "silver rocks", null, 450, Skills.MINING), + SILVER_ORE_2(6945, 20, 0.3, 100 | 200 << 16, 40.0, 442, 1, "silver rocks", null, 21296, Skills.MINING), + SILVER_ORE_3(6946, 20, 0.3, 100 | 200 << 16, 40.0, 442, 1, "silver rocks", null, 21297, Skills.MINING), + SILVER_ORE_4(9716, 20, 0.3, 100 | 200 << 16, 40.0, 442, 1, "silver rocks", null, 18954, Skills.MINING), + SILVER_ORE_5(9714, 20, 0.3, 100 | 200 << 16, 40.0, 442, 1, "silver rocks", null, 32447, Skills.MINING), + SILVER_ORE_6(9715, 20, 0.3, 100 | 200 << 16, 40.0, 442, 1, "silver rocks", null, 32448, Skills.MINING), + SILVER_ORE_7(11188, 20, 0.3, 100 | 200 << 16, 40.0, 442, 1, "silver rocks", null, 21298, Skills.MINING), + SILVER_ORE_8(11186, 20, 0.3, 100 | 200 << 16, 40.0, 442, 1, "silver rocks", null, 21296, Skills.MINING), + SILVER_ORE_9(11187, 20, 0.3, 100 | 200 << 16, 40.0, 442, 1, "silver rocks", null, 21297, Skills.MINING), + SILVER_ORE_10(15581, 20, 0.3, 100 | 200 << 16, 40.0, 442, 1, "silver rocks", null, 14834, Skills.MINING), + SILVER_ORE_11(15580, 20, 0.3, 100 | 200 << 16, 40.0, 442, 1, "silver rocks", null, 14833, Skills.MINING), + SILVER_ORE_12(15579, 20, 0.3, 100 | 200 << 16, 40.0, 442, 1, "silver rocks", null, 14832, Skills.MINING), + SILVER_ORE_13(16998, 20, 0.3, 100 | 200 << 16, 40.0, 442, 1, "silver rocks", null, 14915, Skills.MINING), + SILVER_ORE_14(16999, 20, 0.3, 100 | 200 << 16, 40.0, 442, 1, "silver rocks", null, 14916, Skills.MINING), + SILVER_ORE_15(17007, 20, 0.3, 100 | 200 << 16, 40.0, 442, 1, "silver rocks", null, 14915, Skills.MINING), + SILVER_ORE_16(17000, 20, 0.3, 100 | 200 << 16, 40.0, 442, 1, "silver rocks", null, 31061, Skills.MINING), + SILVER_ORE_17(17009, 20, 0.3, 100 | 200 << 16, 40.0, 442, 1, "silver rocks", null, 31061, Skills.MINING), + SILVER_ORE_18(17008, 20, 0.3, 100 | 200 << 16, 40.0, 442, 1, "silver rocks", null, 14916, Skills.MINING), + SILVER_ORE_19(17385, 20, 0.3, 100 | 200 << 16, 40.0, 442, 1, "silver rocks", null, 32447, Skills.MINING), + SILVER_ORE_20(17387, 20, 0.3, 100 | 200 << 16, 40.0, 442, 1, "silver rocks", null, 18954, Skills.MINING), + SILVER_ORE_21(17386, 20, 0.3, 100 | 200 << 16, 40.0, 442, 1, "silver rocks", null, 32448, Skills.MINING), + SILVER_ORE_22(29225, 20, 0.3, 100 | 200 << 16, 40.0, 442, 1, "silver rocks", null, 29219, Skills.MINING), + SILVER_ORE_23(29224, 20, 0.3, 100 | 200 << 16, 40.0, 442, 1, "silver rocks", null, 29218, Skills.MINING), + SILVER_ORE_24(29226, 20, 0.3, 100 | 200 << 16, 40.0, 442, 1, "silver rocks", null, 29220, Skills.MINING), + SILVER_ORE_25(32445, 20, 0.3, 100 | 200 << 16, 40.0, 442, 1, "silver rocks", null, 33401, Skills.MINING), + SILVER_ORE_26(32444, 20, 0.3, 100 | 200 << 16, 40.0, 442, 1, "silver rocks", null, 33400, Skills.MINING), + SILVER_ORE_27(32446, 20, 0.3, 100 | 200 << 16, 40.0, 442, 1, "silver rocks", null, 33402, Skills.MINING), + SILVER_ORE_28(31075, 20, 0.3, 100 | 200 << 16, 40.0, 442, 1, "silver rocks", null, 37649, Skills.MINING), + SILVER_ORE_29(31074, 20, 0.3, 100 | 200 << 16, 40.0, 442, 1, "silver rocks", null, 37639, Skills.MINING), + SILVER_ORE_30(31076, 20, 0.3, 100 | 200 << 16, 40.0, 442, 1, "silver rocks", null, 37650, Skills.MINING), + SILVER_ORE_31(37305, 20, 0.3, 100 | 200 << 16, 40.0, 442, 1, "silver rocks", null, 11553, Skills.MINING), + SILVER_ORE_32(37304, 20, 0.3, 100 | 200 << 16, 40.0, 442, 1, "silver rocks", null, 11552, Skills.MINING), + SILVER_ORE_33(37306, 20, 0.3, 100 | 200 << 16, 40.0, 442, 1, "silver rocks", null, 11554, Skills.MINING), + SILVER_ORE_34(37670, 20, 0.3, 100 | 200 << 16, 40.0, 442, 1, "silver rocks", null, 11552, Skills.MINING), + SILVER_ORE_35(11948, 20, 0.3, 100 | 200 << 16, 40.0, 442, 1, "silver rocks", null, 11555, Skills.MINING), + SILVER_ORE_36(11949, 20, 0.3, 100 | 200 << 16, 40.0, 442, 1, "silver rocks", null, 11556, Skills.MINING), + SILVER_ORE_37(11950, 20, 0.3, 100 | 200 << 16, 40.0, 442, 1, "silver rocks", null, 11557, Skills.MINING), + + /** + * Coal. + */ + COAL_0(2097, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 452, Skills.MINING), + COAL_1(2096, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 450, Skills.MINING), + COAL_2(4985, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 4994, Skills.MINING), + COAL_3(4986, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 4995, Skills.MINING), + COAL_4(4987, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 4996, Skills.MINING), + COAL_5(4676, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 450, Skills.MINING), + COAL_6(10948, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 10944, Skills.MINING), + COAL_7(11964, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 11556, Skills.MINING), + COAL_8(11965, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 11557, Skills.MINING), + COAL_9(11963, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 11555, Skills.MINING), + COAL_10(11932, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 11554, Skills.MINING), + COAL_11(11930, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 11552, Skills.MINING), + COAL_12(11931, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 11553, Skills.MINING), + COAL_13(15246, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 15249, Skills.MINING), + COAL_14(15247, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 15250, Skills.MINING), + COAL_15(15248, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 15251, Skills.MINING), + COAL_16(14852, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 25373, Skills.MINING), + COAL_17(14851, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 25372, Skills.MINING), + COAL_18(14850, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 25371, Skills.MINING), + COAL_19(20410, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 20443, Skills.MINING), + COAL_20(20411, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 20444, Skills.MINING), + COAL_21(20412, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 20445, Skills.MINING), + COAL_22(20413, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 20407, Skills.MINING), + COAL_23(18999, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 19005, Skills.MINING), + COAL_24(18998, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 19004, Skills.MINING), + COAL_25(18997, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 19003, Skills.MINING), + COAL_26(21287, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 21296, Skills.MINING), + COAL_27(21289, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 21298, Skills.MINING), + COAL_28(21288, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 21297, Skills.MINING), + COAL_29(23565, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 21298, Skills.MINING), + COAL_30(23564, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 21297, Skills.MINING), + COAL_31(23563, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 21296, Skills.MINING), + COAL_32(29215, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 29218, Skills.MINING), + COAL_33(29217, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 29220, Skills.MINING), + COAL_34(29216, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 29219, Skills.MINING), + COAL_35(32426, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 33400, Skills.MINING), + COAL_36(32427, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 33401, Skills.MINING), + COAL_37(32428, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 33402, Skills.MINING), + COAL_38(32450, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 32448, Skills.MINING), + COAL_39(32449, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 32447, Skills.MINING), + COAL_40(31068, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 37639, Skills.MINING), + COAL_41(31069, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 37649, Skills.MINING), + COAL_42(31070, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 37650, Skills.MINING), + COAL_43(31168, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 14833, Skills.MINING), + COAL_44(31169, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 14834, Skills.MINING), + COAL_45(31167, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 14832, Skills.MINING), + COAL_46(37699, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 21298, Skills.MINING), + COAL_47(37698, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 21297, Skills.MINING), + COAL_48(37697, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 21296, Skills.MINING), + COAL_49(42035, 30, 0.4, 50 | 100 << 16, 50.0, 453, 1, "coal", null, 452, Skills.MINING), + + /** + * Sandstone. + */ + SANDSTONE(10946, 35, 0.2, 30 | 60 << 16, 30.0, 6971, 1, "sandstone", null, 10944, Skills.MINING), + + /** + * Gold ore. + */ + GOLD_ORE_0(2099, 40, 0.6, 100 | 200 << 16, 65.0, 444, 1, "gold rocks", null, 452, Skills.MINING), + GOLD_ORE_1(2098, 40, 0.6, 100 | 200 << 16, 65.0, 444, 1, "gold rocks", null, 450, Skills.MINING), + GOLD_ORE_2(2611, 40, 0.6, 100 | 200 << 16, 65.0, 444, 1, "gold rocks", null, 21298, Skills.MINING), + GOLD_ORE_3(2610, 40, 0.6, 100 | 200 << 16, 65.0, 444, 1, "gold rocks", null, 21297, Skills.MINING), + GOLD_ORE_4(2609, 40, 0.6, 100 | 200 << 16, 65.0, 444, 1, "gold rocks", null, 21296, Skills.MINING), + GOLD_ORE_5(9722, 40, 0.6, 100 | 200 << 16, 65.0, 444, 1, "gold rocks", null, 18954, Skills.MINING), + GOLD_ORE_6(9720, 40, 0.6, 100 | 200 << 16, 65.0, 444, 1, "gold rocks", null, 32447, Skills.MINING), + GOLD_ORE_7(9721, 40, 0.6, 100 | 200 << 16, 65.0, 444, 1, "gold rocks", null, 32448, Skills.MINING), + GOLD_ORE_8(11183, 40, 0.6, 100 | 200 << 16, 65.0, 444, 1, "gold rocks", null, 21296, Skills.MINING), + GOLD_ORE_9(11184, 40, 0.6, 100 | 200 << 16, 65.0, 444, 1, "gold rocks", null, 21297, Skills.MINING), + GOLD_ORE_10(11185, 40, 0.6, 100 | 200 << 16, 65.0, 444, 1, "gold rocks", null, 21298, Skills.MINING), + GOLD_ORE_11(11952, 40, 0.6, 100 | 200 << 16, 65.0, 444, 1, "gold rocks", null, 11556, Skills.MINING), + GOLD_ORE_12(11953, 40, 0.6, 100 | 200 << 16, 65.0, 444, 1, "gold rocks", null, 11557, Skills.MINING), + GOLD_ORE_13(11951, 40, 0.6, 100 | 200 << 16, 65.0, 444, 1, "gold rocks", null, 11555, Skills.MINING), + GOLD_ORE_14(15578, 40, 0.6, 100 | 200 << 16, 65.0, 444, 1, "gold rocks", null, 14834, Skills.MINING), + GOLD_ORE_15(15577, 40, 0.6, 100 | 200 << 16, 65.0, 444, 1, "gold rocks", null, 14833, Skills.MINING), + GOLD_ORE_16(15576, 40, 0.6, 100 | 200 << 16, 65.0, 444, 1, "gold rocks", null, 14832, Skills.MINING), + GOLD_ORE_17(17002, 40, 0.6, 100 | 200 << 16, 65.0, 444, 1, "gold rocks", null, 14916, Skills.MINING), + GOLD_ORE_18(17003, 40, 0.6, 100 | 200 << 16, 65.0, 444, 1, "gold rocks", null, 31061, Skills.MINING), + GOLD_ORE_19(17001, 40, 0.6, 100 | 200 << 16, 65.0, 444, 1, "gold rocks", null, 14915, Skills.MINING), + GOLD_ORE_20(21291, 40, 0.6, 100 | 200 << 16, 65.0, 444, 1, "gold rocks", null, 21297, Skills.MINING), + GOLD_ORE_21(21290, 40, 0.6, 100 | 200 << 16, 65.0, 444, 1, "gold rocks", null, 21296, Skills.MINING), + GOLD_ORE_22(21292, 40, 0.6, 100 | 200 << 16, 65.0, 444, 1, "gold rocks", null, 21298, Skills.MINING), + GOLD_ORE_23(32433, 40, 0.6, 100 | 200 << 16, 65.0, 444, 1, "gold rocks", null, 33401, Skills.MINING), + GOLD_ORE_24(32432, 40, 0.6, 100 | 200 << 16, 65.0, 444, 1, "gold rocks", null, 33400, Skills.MINING), + GOLD_ORE_25(32434, 40, 0.6, 100 | 200 << 16, 65.0, 444, 1, "gold rocks", null, 33402, Skills.MINING), + GOLD_ORE_26(31065, 40, 0.6, 100 | 200 << 16, 65.0, 444, 1, "gold rocks", null, 37639, Skills.MINING), + GOLD_ORE_27(31066, 40, 0.6, 100 | 200 << 16, 65.0, 444, 1, "gold rocks", null, 37649, Skills.MINING), + GOLD_ORE_28(31067, 40, 0.6, 100 | 200 << 16, 65.0, 444, 1, "gold rocks", null, 37650, Skills.MINING), + GOLD_ORE_29(37311, 40, 0.6, 100 | 200 << 16, 65.0, 444, 1, "gold rocks", null, 11553, Skills.MINING), + GOLD_ORE_30(37310, 40, 0.6, 100 | 200 << 16, 65.0, 444, 1, "gold rocks", null, 11552, Skills.MINING), + GOLD_ORE_31(37312, 40, 0.6, 100 | 200 << 16, 65.0, 444, 1, "gold rocks", null, 11554, Skills.MINING), + GOLD_ORE_32(37471, 40, 0.6, 100 | 200 << 16, 65.0, 444, 1, "gold rocks", null, 15249, Skills.MINING), + GOLD_ORE_33(37473, 40, 0.6, 100 | 200 << 16, 65.0, 444, 1, "gold rocks", null, 15251, Skills.MINING), + GOLD_ORE_34(37472, 40, 0.6, 100 | 200 << 16, 65.0, 444, 1, "gold rocks", null, 15250, Skills.MINING), + GOLD_ORE_49(42033, 40, 0.6, 100 | 200 << 16, 65.0, 444, 1, "gold rocks", null, 452, Skills.MINING), + + /** + * Granite. + */ + GRANITE(10947, 45, 0.2, 10 | 20 << 16, 50.0, 6979, 1, "granite", null, 10945, Skills.MINING), + + /** + * Rubium. + */ + RUBIUM(29746, 46, 0.6, 50 | 100 << 16, 17.5, 12630, 1, "rubium", null, 29747, Skills.MINING), + + /** + * Mithril ore. + */ + MITHRIL_ORE_0(2103, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 452, Skills.MINING), + MITHRIL_ORE_1(2102, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 450, Skills.MINING), + MITHRIL_ORE_2(4988, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 4994, Skills.MINING), + MITHRIL_ORE_3(4989, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 4995, Skills.MINING), + MITHRIL_ORE_4(4990, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 4996, Skills.MINING), + MITHRIL_ORE_5(11943, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 11553, Skills.MINING), + MITHRIL_ORE_6(11942, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 11552, Skills.MINING), + MITHRIL_ORE_7(11945, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 11555, Skills.MINING), + MITHRIL_ORE_8(11944, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 11554, Skills.MINING), + MITHRIL_ORE_9(11947, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 11557, Skills.MINING), + MITHRIL_ORE_10(11946, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 11556, Skills.MINING), + MITHRIL_ORE_11(14855, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 25373, Skills.MINING), + MITHRIL_ORE_12(14854, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 25372, Skills.MINING), + MITHRIL_ORE_13(14853, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 25371, Skills.MINING), + MITHRIL_ORE_14(16687, 50, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 450, Skills.MINING), + MITHRIL_ORE_15(20421, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 20407, Skills.MINING), + MITHRIL_ORE_16(20420, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 20445, Skills.MINING), + MITHRIL_ORE_17(20419, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 20444, Skills.MINING), + MITHRIL_ORE_18(20418, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 20443, Skills.MINING), + MITHRIL_ORE_19(19012, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 19021, Skills.MINING), + MITHRIL_ORE_20(19013, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 19016, Skills.MINING), + MITHRIL_ORE_21(19014, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 19017, Skills.MINING), + MITHRIL_ORE_22(21278, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 21296, Skills.MINING), + MITHRIL_ORE_23(21279, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 21297, Skills.MINING), + MITHRIL_ORE_24(21280, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 21298, Skills.MINING), + MITHRIL_ORE_25(25369, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 10586, Skills.MINING), + MITHRIL_ORE_26(25368, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 10585, Skills.MINING), + MITHRIL_ORE_27(25370, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 10587, Skills.MINING), + MITHRIL_ORE_28(29236, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 29218, Skills.MINING), + MITHRIL_ORE_29(29237, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 29219, Skills.MINING), + MITHRIL_ORE_30(29238, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 29220, Skills.MINING), + MITHRIL_ORE_31(32439, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 33401, Skills.MINING), + MITHRIL_ORE_32(32438, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 33400, Skills.MINING), + MITHRIL_ORE_33(32440, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 33402, Skills.MINING), + MITHRIL_ORE_34(31087, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 37649, Skills.MINING), + MITHRIL_ORE_35(31086, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 37639, Skills.MINING), + MITHRIL_ORE_36(31088, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 37650, Skills.MINING), + MITHRIL_ORE_37(31170, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 14832, Skills.MINING), + MITHRIL_ORE_38(31171, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 14833, Skills.MINING), + MITHRIL_ORE_39(31172, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 14834, Skills.MINING), + MITHRIL_ORE_40(37692, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 21296, Skills.MINING), + MITHRIL_ORE_41(37693, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 21297, Skills.MINING), + MITHRIL_ORE_42(37694, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 21298, Skills.MINING), + MITHRIL_ORE_49(42036, 55, 0.70, 200 | 400 << 16, 80.0, 447, 1, "mithril rocks", null, 452, Skills.MINING), + + /** + * Adamantite ore. + */ + ADAMANTITE_ORE_0(2105, 70, 0.85, 400 | 800 << 16, 95.0, 449, 1, "adamant rocks", null, 452, Skills.MINING), + ADAMANTITE_ORE_1(2104, 70, 0.85, 400 | 800 << 16, 95.0, 449, 1, "adamant rocks", null, 450, Skills.MINING), + ADAMANTITE_ORE_2(4991, 70, 0.85, 400 | 800 << 16, 95.0, 449, 1, "adamant rocks", null, 4994, Skills.MINING), + ADAMANTITE_ORE_3(4992, 70, 0.85, 400 | 800 << 16, 95.0, 449, 1, "adamant rocks", null, 4995, Skills.MINING), + ADAMANTITE_ORE_4(4993, 70, 0.85, 400 | 800 << 16, 95.0, 449, 1, "adamant rocks", null, 4996, Skills.MINING), + ADAMANTITE_ORE_5(11941, 70, 0.85, 400 | 800 << 16, 95.0, 449, 1, "adamant rocks", null, 11554, Skills.MINING), + ADAMANTITE_ORE_6(11940, 70, 0.85, 400 | 800 << 16, 95.0, 449, 1, "adamant rocks", null, 11553, Skills.MINING), + ADAMANTITE_ORE_7(11939, 70, 0.85, 400 | 800 << 16, 95.0, 449, 1, "adamant rocks", null, 11552, Skills.MINING), + ADAMANTITE_ORE_8(14864, 70, 0.85, 400 | 800 << 16, 95.0, 449, 1, "adamant rocks", null, 25373, Skills.MINING), + ADAMANTITE_ORE_9(14863, 70, 0.85, 400 | 800 << 16, 95.0, 449, 1, "adamant rocks", null, 25372, Skills.MINING), + ADAMANTITE_ORE_10(14862, 70, 0.85, 400 | 800 << 16, 95.0, 449, 1, "adamant rocks", null, 25371, Skills.MINING), + ADAMANTITE_ORE_11(20417, 70, 0.85, 400 | 800 << 16, 95.0, 449, 1, "adamant rocks", null, 20407, Skills.MINING), + ADAMANTITE_ORE_12(20416, 70, 0.85, 400 | 800 << 16, 95.0, 449, 1, "adamant rocks", null, 20445, Skills.MINING), + ADAMANTITE_ORE_13(20414, 70, 0.85, 400 | 800 << 16, 95.0, 449, 1, "adamant rocks", null, 20443, Skills.MINING), + ADAMANTITE_ORE_14(20415, 70, 0.85, 400 | 800 << 16, 95.0, 449, 1, "adamant rocks", null, 20444, Skills.MINING), + ADAMANTITE_ORE_15(19020, 70, 0.85, 400 | 800 << 16, 95.0, 449, 1, "adamant rocks", null, 19017, Skills.MINING), + ADAMANTITE_ORE_16(19018, 70, 0.85, 400 | 800 << 16, 95.0, 449, 1, "adamant rocks", null, 19021, Skills.MINING), + ADAMANTITE_ORE_17(19019, 70, 0.85, 400 | 800 << 16, 95.0, 449, 1, "adamant rocks", null, 19016, Skills.MINING), + ADAMANTITE_ORE_18(21275, 70, 0.85, 400 | 800 << 16, 95.0, 449, 1, "adamant rocks", null, 21296, Skills.MINING), + ADAMANTITE_ORE_19(21276, 70, 0.85, 400 | 800 << 16, 95.0, 449, 1, "adamant rocks", null, 21297, Skills.MINING), + ADAMANTITE_ORE_20(21277, 70, 0.85, 400 | 800 << 16, 95.0, 449, 1, "adamant rocks", null, 21298, Skills.MINING), + ADAMANTITE_ORE_21(29233, 70, 0.85, 400 | 800 << 16, 95.0, 449, 1, "adamant rocks", null, 29218, Skills.MINING), + ADAMANTITE_ORE_22(29234, 70, 0.85, 400 | 800 << 16, 95.0, 449, 1, "adamant rocks", null, 29219, Skills.MINING), + ADAMANTITE_ORE_23(29235, 70, 0.85, 400 | 800 << 16, 95.0, 449, 1, "adamant rocks", null, 29220, Skills.MINING), + ADAMANTITE_ORE_24(32435, 70, 0.85, 400 | 800 << 16, 95.0, 449, 1, "adamant rocks", null, 33400, Skills.MINING), + ADAMANTITE_ORE_25(32437, 70, 0.85, 400 | 800 << 16, 95.0, 449, 1, "adamant rocks", null, 33402, Skills.MINING), + ADAMANTITE_ORE_26(32436, 70, 0.85, 400 | 800 << 16, 95.0, 449, 1, "adamant rocks", null, 33401, Skills.MINING), + ADAMANTITE_ORE_27(31083, 70, 0.85, 400 | 800 << 16, 95.0, 449, 1, "adamant rocks", null, 37639, Skills.MINING), + ADAMANTITE_ORE_28(31085, 70, 0.85, 400 | 800 << 16, 95.0, 449, 1, "adamant rocks", null, 37650, Skills.MINING), + ADAMANTITE_ORE_29(31084, 70, 0.85, 400 | 800 << 16, 95.0, 449, 1, "adamant rocks", null, 37649, Skills.MINING), + ADAMANTITE_ORE_30(31173, 70, 0.85, 400 | 800 << 16, 95.0, 449, 1, "adamant rocks", null, 14832, Skills.MINING), + ADAMANTITE_ORE_31(31174, 70, 0.85, 400 | 800 << 16, 95.0, 449, 1, "adamant rocks", null, 14833, Skills.MINING), + ADAMANTITE_ORE_32(31175, 70, 0.85, 400 | 800 << 16, 95.0, 449, 1, "adamant rocks", null, 14834, Skills.MINING), + ADAMANTITE_ORE_33(37468, 70, 0.85, 400 | 800 << 16, 95.0, 449, 1, "adamant rocks", null, 15249, Skills.MINING), + ADAMANTITE_ORE_34(37469, 70, 0.85, 400 | 800 << 16, 95.0, 449, 1, "adamant rocks", null, 15250, Skills.MINING), + ADAMANTITE_ORE_35(37470, 70, 0.85, 400 | 800 << 16, 95.0, 449, 1, "adamant rocks", null, 15251, Skills.MINING), + ADAMANTITE_ORE_36(37689, 70, 0.85, 400 | 800 << 16, 95.0, 449, 1, "adamant rocks", null, 21296, Skills.MINING), + ADAMANTITE_ORE_37(37690, 70, 0.85, 400 | 800 << 16, 95.0, 449, 1, "adamant rocks", null, 21297, Skills.MINING), + ADAMANTITE_ORE_38(37691, 70, 0.85, 400 | 800 << 16, 95.0, 449, 1, "adamant rocks", null, 21298, Skills.MINING), + ADAMANTITE_ORE_39(42037, 70, 0.85, 400 | 800 << 16, 95.0, 449, 1, "adamant rocks", null, 452, Skills.MINING), + + /** + * Runite ore. + */ + RUNITE_ORE_0(2107, 85, 0.95, 1250 | 2500 << 16, 125.0, 451, 1, "runite rocks", null, 452, Skills.MINING), + RUNITE_ORE_1(2106, 85, 0.95, 1250 | 2500 << 16, 125.0, 451, 1, "runite rocks", null, 450, Skills.MINING), + RUNITE_ORE_5(14861, 85, 0.95, 1250 | 2500 << 16, 125.0, 451, 1, "runite rocks", null, 25373, Skills.MINING), + RUNITE_ORE_6(14860, 85, 0.95, 1250 | 2500 << 16, 125.0, 451, 1, "runite rocks", null, 25372, Skills.MINING), + RUNITE_ORE_7(14859, 85, 0.95, 1250 | 2500 << 16, 125.0, 451, 1, "runite rocks", null, 25371, Skills.MINING), + RUNITE_ORE_8(33079, 85, 0.95, 1250 | 2500 << 16, 125.0, 451, 1, "runite rocks", null, 33401, Skills.MINING), + RUNITE_ORE_9(33078, 85, 0.95, 1250 | 2500 << 16, 125.0, 451, 1, "runite rocks", null, 33400, Skills.MINING), + RUNITE_ORE_10(37208, 85, 0.95, 1250 | 2500 << 16, 125.0, 451, 1, "runite rocks", null, 21296, Skills.MINING), + RUNITE_ORE_11(37465, 85, 0.95, 1250 | 2500 << 16, 125.0, 451, 1, "runite rocks", null, 15249, Skills.MINING), + RUNITE_ORE_12(37466, 85, 0.95, 1250 | 2500 << 16, 125.0, 451, 1, "runite rocks", null, 15250, Skills.MINING), + RUNITE_ORE_13(37467, 85, 0.95, 1250 | 2500 << 16, 125.0, 451, 1, "runite rocks", null, 15251, Skills.MINING), + RUNITE_ORE_14(37695, 85, 0.95, 1250 | 2500 << 16, 125.0, 451, 1, "runite rocks", null, 21297, Skills.MINING), + RUNITE_ORE_15(37696, 85, 0.95, 1250 | 2500 << 16, 125.0, 451, 1, "runite rocks", null, 21298, Skills.MINING), + + /** + * Gem rocks. + */ + GEM_ROCK_0(23567, 40, 0.95, 166 | 175 << 16, 65, 1625, 1, "gem rocks", null, 21297, Skills.MINING), + GEM_ROCK_1(23566, 40, 0.95, 166 | 175 << 16, 65, 1625, 1, "gem rocks", null, 21296, Skills.MINING), + GEM_ROCK_2(23568, 40, 0.95, 166 | 175 << 16, 65, 1625, 1, "gem rocks", null, 21298, Skills.MINING), + + /** + * Magic stone. + */ + MAGIC_STONE_0(6669, 20, 0.3, 100 | 200 << 16, 0.0, 4703, 1, "magic stone", null, 21296, Skills.MINING), + MAGIC_STONE_1(6671, 20, 0.3, 100 | 200 << 16, 0.0, 4703, 1, "magic stone", null, 21298, Skills.MINING), + MAGIC_STONE_2(6670, 20, 0.3, 100 | 200 << 16, 0.0, 4703, 1, "magic stone", null, 21297, Skills.MINING); + + + /** + * The resources mapping. + */ + private static final Map RESOURCES = new HashMap<>(); + + /** + * Populate the mapping. + */ + static { + for (SkillingResource resource : SkillingResource.values()) { + if (RESOURCES.containsKey(resource.id)) { + } + RESOURCES.put(resource.id, resource); + } + } + + /** + * The resource id. + */ + private final int id; + + /** + * The level required. + */ + private final int level; + + /** + * The rate. + */ + private final double rate; + + /** + * The respawn rate. + */ + private final int respawnRate; + + /** + * The experience to be rewarded. + */ + private final double experience; + + /** + * The reward item id. + */ + private final int reward; + + /** + * The amount to reward. + */ + private final int rewardAmount; + + /** + * The name. + */ + private final String name; + + /** + * The animation. + */ + private final Animation animation; + + /** + * The id to replace this id with when the resource runs out. + */ + private final int emptyId; + + /** + * The skill id. + */ + private final int skillId; + + /** + * Represents if its a farming resource. + */ + private final boolean farming; + + /** + * Constructs a new {@code SkillingResource} {@code Object}. + * @param id The id. + * @param level The level required. + * @param rate The rate. + * @param respawnRate The respawn rate (lowest ticks | highest ticks << 16). + * @param experience The experience. + * @param reward The reward item id. + * @param rewardAmount The reward amount. + * @param name The name. + * @param animation The animation. + * @param emptyId The id to replace this id with when the resource runs out. + * @param skillId The skill id. + */ + private SkillingResource(int id, int level, double rate, int respawnRate, double experience, int reward, int rewardAmount, String name, Animation animation, int emptyId, int skillId) { + this.id = id; + this.level = level; + this.rate = rate; + this.respawnRate = respawnRate; + this.experience = experience; + this.reward = reward; + this.rewardAmount = rewardAmount; + this.name = name; + this.animation = animation; + this.emptyId = emptyId; + this.skillId = skillId; + this.farming = false; + } + + /** + * Constructs a new {@code SkillingResource} {@code Object}. + * @param id The id. + * @param level The level required. + * @param rate The rate. + * @param respawnRate The respawn rate (lowest ticks | highest ticks << 16). + * @param experience The experience. + * @param reward The reward item id. + * @param rewardAmount The reward amount. + * @param name The name. + * @param animation The animation. + * @param emptyId The id to replace this id with when the resource runs out. + * @param skillId The skill id. + */ + private SkillingResource(int id, int level, double rate, int respawnRate, double experience, int reward, int rewardAmount, String name, Animation animation, int emptyId, int skillId, boolean farming) { + this.id = id; + this.level = level; + this.rate = rate; + this.respawnRate = respawnRate; + this.experience = experience; + this.reward = reward; + this.rewardAmount = rewardAmount; + this.name = name; + this.animation = animation; + this.emptyId = emptyId; + this.skillId = skillId; + this.farming = farming; + } + + /** + * Gets the skilling resource for the given id. + * @param id The id. + * @return The resource. + */ + public static SkillingResource forId(int id) { + return RESOURCES.get(id); + } + + /** + * Checks if the object id is an empty resource. + * @param id The object id. + * @return {@code True} if so. + */ + public static boolean isEmpty(int id) { + for (SkillingResource r : SkillingResource.values()) { + if (r.getEmptyId() == id) { + return true; + } + } + return false; + } + + /** + * Gets the current respawn duration (in ticks). + * @return The respawn duration. + */ + public int getRespawnDuration() { + int minimum = respawnRate & 0xFFFF; + int maximum = (respawnRate >> 16) & 0xFFFF; + double playerRatio = (double) ServerConstants.MAX_PLAYERS / Repository.getPlayers().size(); + return (int) (minimum + ((maximum - minimum) / playerRatio)); + } + + /** + * Gets the maximum respawn time (in ticks). + * @return The maximum respawn time. + */ + public int getMaximumRespawn() { + return (respawnRate >> 16) & 0xFFFF; + } + + /** + * Gets the minimum respawn time (in ticks). + * @return The minimum respawn time. + */ + public int getMinimumRespawn() { + return respawnRate & 0xFFFF; + } + + /** + * Gets the id. + * @return The id. + */ + public int getId() { + return id; + } + + /** + * Gets the level. + * @return The level. + */ + public int getLevel() { + return level; + } + + /** + * Gets the rate. + * @return The rate. + */ + public double getRate() { + return rate; + } + + /** + * Gets the respawnRate. + * @return The respawnRate. + */ + public int getRespawnRate() { + return respawnRate; + } + + /** + * Gets the experience. + * @return The experience. + */ + public double getExperience() { + return experience; + } + + /** + * Gets the reward. + * @return The reward. + */ + public int getReward() { + return reward; + } + + /** + * Gets the name. + * @return The name. + */ + public String getName() { + return name; + } + + /** + * Gets the animation. + * @return The animation. + */ + public Animation getAnimation() { + return animation; + } + + /** + * Gets the emptyId. + * @return The emptyId. + */ + public int getEmptyId() { + return emptyId; + } + + /** + * Gets the skillId. + * @return The skillId. + */ + public int getSkillId() { + return skillId; + } + + /** + * Gets the rewardAmount. + * @return The rewardAmount. + */ + public int getRewardAmount() { + return rewardAmount; + } + + /** + * Gets the farming. + * @return The farming. + */ + public boolean isFarming() { + return farming; + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/gather/fishing/FishingListener.kt b/Server/src/main/content/global/skill/gather/fishing/FishingListener.kt new file mode 100644 index 0000000..1cad8a2 --- /dev/null +++ b/Server/src/main/content/global/skill/gather/fishing/FishingListener.kt @@ -0,0 +1,166 @@ +package content.global.skill.gather.fishing + +import content.global.handlers.item.equipment.fistofguthixgloves.FOGGlovesManager +import content.global.skill.fishing.Fish +import content.global.skill.fishing.FishingOption +import content.global.skill.fishing.FishingSpot +import content.global.skill.skillcapeperks.SkillcapePerks +import content.global.skill.skillcapeperks.SkillcapePerks.Companion.isActive +import content.global.skill.summoning.familiar.Forager +import core.api.* +import core.game.event.ResourceProducedEvent +import core.game.interaction.Clocks +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.Node +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.system.command.sets.STATS_BASE +import core.game.system.command.sets.STATS_FISH +import core.game.world.GameWorld +import core.game.world.map.path.Pathfinder +import core.tools.RandomFunction +import core.tools.colorize +import org.rs09.consts.Items + +class FishingListener : InteractionListener{ + override fun defineListeners() { + val SPOT_IDS = FishingSpot.values().flatMap { it.ids.toList() }.toIntArray() + defineInteraction( + IntType.NPC, + SPOT_IDS, + "net", "lure", "bait", "harpoon", "cage", "fish", + persistent = true, + allowedDistance = 1, + handler = ::handleFishing + ) + } + + private fun handleFishing(player: Player, node: Node, state: Int) : Boolean { + val npc = node as? NPC ?: return clearScripts(player) + val spot = FishingSpot.forId(npc.id) ?: return clearScripts(player) + val op = spot.getOptionByName(getUsedOption(player)) ?: return clearScripts(player) + + var forager: Forager? = null + + if (player.familiarManager.hasFamiliar() && player.familiarManager.familiar is Forager) { + forager = player.familiarManager.familiar as Forager + } + + if (!finishedMoving(player)) { + return restartScript(player) + } + + if (state == 0) { + if (!checkRequirements(player, op, node)) return clearScripts(player) + forager?.let { + val dest = player.location.transform(player.direction) + Pathfinder.find(it, dest).walk(it) + } + when (op.option) { + "cage" -> if (spot.name == "CAGE_HARPOON") { + sendMessage(player, "You attempt to catch a lobster.") + } else sendMessage(player, "You attempt to catch a crayfish.") + "harpoon" -> sendMessage(player, "You start harpooning fish.") + "net" -> sendMessage(player, "You cast out your net...") + in arrayOf("bait", "lure") -> { + sendMessage(player, "You cast out your line...") + sendMessage(player, "You attempt to catch a fish.") + } + else -> { // Probably not authentic, but covers unknown cases. + sendMessage(player, "You attempt to catch some fish...") + } + } + } + + if (clockReady(player, Clocks.SKILLING)) { + anim(player, op) + forager?.handlePassiveAction() + + val fish = op?.rollFish(player) ?: return delayClock(player, Clocks.SKILLING, 5) + if (!hasSpaceFor(player, Item(fish.id)) || !op.removeBait(player)) return restartScript(player) + player.dispatch(ResourceProducedEvent(fish.id, fish.getItem().amount, node)) + val item = fish.getItem() + val bigFishId = Fish.getBigFish(fish) + val bigFishChance = if (GameWorld.settings?.isDevMode == true) 10 else 5000 + if (bigFishId != null && RandomFunction.roll(bigFishChance)) { + sendMessage(player, "You catch an enormous" + getItemName(fish.id).lowercase().replace("raw", "") + "!") + addItemOrDrop(player, bigFishId, 1) + } else { + var msg = when (fish) { + in arrayOf(Fish.ANCHOVIE, Fish.SHRIMP, Fish.SEAWEED) -> "You catch some " + in arrayOf(Fish.OYSTER) -> "You catch an " + else -> "You catch a " + } + msg += getItemName(fish.id).lowercase().replace("raw ", "").replace("big ", "") + msg += if (fish == Fish.SHARK) "!" else "." + sendMessage(player, msg) + addItemOrDrop(player, item.id, item.amount) + } + + if (isActive(SkillcapePerks.GREAT_AIM, player) && RandomFunction.roll(20)) { + addItemOrDrop(player, item.id, item.amount) + sendMessage(player, colorize("%RYour expert aim catches you a second fish.")) + player.incrementAttribute("/save:$STATS_BASE:$STATS_FISH") + } + + player.incrementAttribute("/save:$STATS_BASE:$STATS_FISH") + var xp = fish.experience + if ((item.id == Items.RAW_SWORDFISH_371 && inEquipment(player, Items.SWORDFISH_GLOVES_12860)) + || (item.id == Items.RAW_SHARK_383 && inEquipment(player, Items.SHARK_GLOVES_12861))) { + xp += 100 + FOGGlovesManager.updateCharges(player) + } + rewardXP(player, Skills.FISHING, xp) + delayClock(player, Clocks.SKILLING, 5) + if (!checkRequirements(player, op, node)) return clearScripts(player) + } + return keepRunning(player) + } + + private fun anim(player: Player, option: FishingOption) { + if (animationFinished(player)) + animate(player, option.animation) + } + + private fun checkRequirements(player: Player, option: FishingOption, node: Node) : Boolean { + if (!inInventory(player, option.tool) && !hasBarbTail(player, option)) { + // The fly fishing rod & net dialogue is confirmed from videos. Others are assumptions based upon this. + var msg = "You need a " + msg += if (getItemName(option.tool).contains("net", true)) "net to " else "${getItemName(option.tool).lowercase()} to " + msg += if (option.option in arrayOf("lure", "bait")) "${option.option} these fish." else "catch these fish." + sendDialogue(player, msg) + return false + } + if (!option.hasBait(player)) { + var msg = "You don't have any " + option.getBaitName().lowercase() + msg += if (option.getBaitName() == getItemName(Items.FISHING_BAIT_313)) " left." else "s left." + sendDialogue(player, msg) + return false + } + if (!hasLevelDyn(player, Skills.FISHING, option.level)) { + sendDialogue(player, "You need a Fishing level of at least ${option.level} to ${option.option} these fish.") + return false + } + if (freeSlots(player) == 0) { + if (option.fish.contains(Fish.LOBSTER)) { + sendDialogue(player, "You can't carry any more lobsters.") + } else { + sendDialogue(player, "You can't carry any more fish.") + } + return false + } + return node.isActive && node.location.withinDistance(player.location, 1) + } + + + private fun hasBarbTail(player: Player, option: FishingOption): Boolean { + val bh = FishingOption.BARB_HARPOON.tool + if (option == FishingOption.HARPOON || option == FishingOption.SHARK_HARPOON) { + if (inInventory(player, bh) || inEquipment(player, bh)) return true + } + return false + } +} diff --git a/Server/src/main/content/global/skill/gather/fishing/FishingPulse.kt b/Server/src/main/content/global/skill/gather/fishing/FishingPulse.kt new file mode 100644 index 0000000..ea254e3 --- /dev/null +++ b/Server/src/main/content/global/skill/gather/fishing/FishingPulse.kt @@ -0,0 +1,306 @@ +package content.global.skill.gather.fishing + +import content.data.skill.SkillingPets +import content.global.skill.fishing.Fish +import content.global.skill.fishing.FishingOption +import content.global.skill.skillcapeperks.SkillcapePerks +import content.global.skill.skillcapeperks.SkillcapePerks.Companion.isActive +import content.global.skill.summoning.familiar.Forager +import core.api.* +import core.game.event.ResourceProducedEvent +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.skillertasks.SkillTasks +import core.game.node.entity.skill.SkillPulse +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.system.command.sets.STATS_BASE +import core.game.system.command.sets.STATS_FISH +import core.game.system.task.Pulse +import core.game.world.GameWorld.Pulser +import core.game.world.map.Location +import core.game.world.map.path.Pathfinder +import core.game.world.update.flag.context.Animation +import core.tools.RandomFunction +import core.tools.colorize +import org.rs09.consts.Items + +/** + * Handles a fishing pulse. + * + * @author Ceikry + */ +class FishingPulse(player: Player?, npc: NPC, private val option: FishingOption?) : SkillPulse(player, npc) { + /** + * Represents the fish type. + */ + private var fish: Fish? = null + + /** + * Represents the base location the npc was at. + */ + private val location: Location = npc.location + + override fun start() { + if (player.familiarManager.hasFamiliar() && player.familiarManager.familiar is Forager) { + val forager = player.familiarManager.familiar as Forager + val dest = player.location.transform(player.direction) + Pathfinder.find(forager.location, dest).walk(forager) + } + super.start() + } + + override fun checkRequirements(): Boolean { + if (option == null) { + return false + } + player.debug(inInventory(player, option.tool).toString()) + if (!inInventory(player, option.tool) && !hasBarbTail()) { + // The fly fishing rod & net dialogue is confirmed from videos. Others are assumptions based upon this. + var msg = "You need a " + msg += if (getItemName(option.tool).contains("net", true)) "net to " else "${getItemName(option.tool).lowercase()} to " + msg += if (option.option in arrayOf("lure", "bait")) "${option.option} these fish." else "catch these fish." + sendDialogue(player, msg) + stop() + return false + } + if (!option.hasBait(player)) { + var msg = "You don't have any " + option.getBaitName().lowercase() + msg += if (option.getBaitName() == getItemName(Items.FISHING_BAIT_313)) " left." else "s left." + sendDialogue(player, msg) + stop() + return false + } + if (!hasLevelDyn(player, Skills.FISHING, option.level)) { + sendDialogue(player, "You need a Fishing level of at least ${option.level} to ${option.option} these fish.") + stop() + return false + } + if (freeSlots(player) == 0) { + if (option.fish.contains(Fish.LOBSTER)) { + sendDialogue(player, "You can't carry any more lobsters.") + } else { + sendDialogue(player, "You can't carry any more fish.") + } + stop() + return false + } + if (location !== node!!.location || !node!!.isActive || node!!.isInvisible) { + stop() + return false + } + return true + } + + override fun animate() { + if (isBareHanded(player)) { + player.animate(Animation(6709)) + Pulser.submit(object : Pulse(1) { + var counter = 0 + override fun pulse(): Boolean { + when (counter++) { + 5 -> getCatchAnimationAndLoot(player) + } + return false + } + }) + } else { + player.animate(option!!.animation) + } + } + + override fun reward(): Boolean { + if (delay == 1) { + super.setDelay(5) + return false + } + if (player.familiarManager.hasFamiliar() && player.familiarManager.familiar is Forager) { + val forager = player.familiarManager.familiar as Forager + forager.handlePassiveAction() + } + if (success()) { + if (player.inventory.hasSpaceFor(Item(fish!!.id)) && option!!.removeBait(player)) { + if (player.skillTasks.hasTask()) { + updateSkillTask() + } + player.dispatch(ResourceProducedEvent(fish!!.id, 1, node!!)) + SkillingPets.checkPetDrop(player, SkillingPets.HERON) + val item = fish!! + if (isActive(SkillcapePerks.GREAT_AIM, player) && RandomFunction.random(100) <= 5) { + addItem(player, item.id) + player.sendMessage(colorize("%RYour expert aim catches you a second fish.")) + } + addItem(player, item.id) + var fishCaught = player.getAttribute(STATS_BASE + ":" + STATS_FISH, 0) + player.setAttribute("/save:$STATS_BASE:$STATS_FISH", ++fishCaught) + player.skills.addExperience(Skills.FISHING, fish!!.experience, true) + message(2) + } + } + return player.inventory.freeSlots() == 0 + } + + fun updateSkillTask() { + when (fish) { + Fish.ANCHOVIE -> { + player.skillTasks.decreaseTask(player, SkillTasks.FANCHOVIES1) + player.skillTasks.decreaseTask(player, SkillTasks.FANCHOVIES2) + } + Fish.HERRING -> { + player.skillTasks.decreaseTask(player, SkillTasks.FHERRING1) + player.skillTasks.decreaseTask(player, SkillTasks.FHERRING2) + } + Fish.LOBSTER -> { + player.skillTasks.decreaseTask(player, SkillTasks.FLOBSTER1) + player.skillTasks.decreaseTask(player, SkillTasks.FLOBSTER2) + } + Fish.SALMON -> { + player.skillTasks.decreaseTask(player, SkillTasks.FSALMON1) + player.skillTasks.decreaseTask(player, SkillTasks.FSALMON2) + } + Fish.SHARK -> { + player.skillTasks.decreaseTask(player, SkillTasks.FSHARK1) + player.skillTasks.decreaseTask(player, SkillTasks.FSHARK2) + player.skillTasks.decreaseTask(player, SkillTasks.FSHARK3) + } + Fish.SHRIMP -> { + player.skillTasks.decreaseTask(player, SkillTasks.FSHRIMP1) + player.skillTasks.decreaseTask(player, SkillTasks.FSHRIMP2) + } + Fish.SWORDFISH -> { + player.skillTasks.decreaseTask(player, SkillTasks.FSWORD1) + player.skillTasks.decreaseTask(player, SkillTasks.FSWORD2) + } + Fish.TROUT -> { + player.skillTasks.decreaseTask(player, SkillTasks.FTROUT1) + player.skillTasks.decreaseTask(player, SkillTasks.FTROUT2) + } + Fish.TUNA -> { + player.skillTasks.decreaseTask(player, SkillTasks.FTUNA1) + player.skillTasks.decreaseTask(player, SkillTasks.FTUNA2) + } + else -> {} + } + } + + private fun isBareHanded(p: Player): Boolean { + if (option == FishingOption.HARPOON || option == FishingOption.SHARK_HARPOON) { + if (checkFish(p) > 0 && !(inInventory(player, option.tool) || inEquipment(player, option.tool) || hasBarbTail()) + ) { + return true + } + if (checkFish(p) > 2 && !(inInventory(player, option.tool) || inEquipment(player, option.tool) || hasBarbTail()) + ) { + return true + } + } + return false + } + + private fun getCatchAnimationAndLoot(p: Player): Int { + val fishingFor = checkFish(p) + when (node!!.id) { + 324 -> when (fishingFor) { + 1 -> { + p.animate(Animation(6710)) + p.skills.addExperience(Skills.FISHING, 80.0) + p.skills.addExperience(Skills.STRENGTH, 8.0) + p.inventory.add(Item(359)) + } + 2, 3 -> if (RandomFunction.random(1) == 1) { + p.animate(Animation(6710)) + p.skills.addExperience(Skills.FISHING, 80.0) + p.skills.addExperience(Skills.STRENGTH, 8.0) + p.inventory.add(Item(359)) + } else { + p.animate(Animation(6707)) + p.skills.addExperience(Skills.FISHING, 100.0) + p.skills.addExperience(Skills.STRENGTH, 10.0) + p.inventory.add(Item(371)) + } + } + 313 -> { + p.animate(Animation(6705)) + p.skills.addExperience(Skills.FISHING, 110.0) + p.skills.addExperience(Skills.STRENGTH, 11.0) + p.inventory.add(Item(383)) + } + } + return 0 + } + + /** + * Checks if they have the barb tail harpoon. + * + * @return `True` if so. + */ + private fun hasBarbTail(): Boolean { + val bh = FishingOption.BARB_HARPOON.tool + if (option == FishingOption.HARPOON || option == FishingOption.SHARK_HARPOON) { + if (inInventory(player, bh) || inEquipment(player, bh)) { + return true + } + } + return false + } + + override fun message(type: Int) { + when (type) { + 0 -> sendMessage(player, option!!.getStartMessage()) + 2 -> { + var msg = when (fish) { + in arrayOf(Fish.ANCHOVIE, Fish.SHRIMP, Fish.SEAWEED) -> "You catch some " + in arrayOf(Fish.OYSTER) -> "You catch an " + else -> "You catch a " + } + msg += getItemName(fish!!.id).lowercase().replace("raw ", "").replace("big ", "") + msg += if (fish == Fish.SHARK) "!" else "." + sendMessage(player, msg) + + if (player.inventory.freeSlots() == 0) { + if (fish == Fish.LOBSTER) { + sendDialogue(player, "You can't carry any more lobsters.") + } else { + sendDialogue(player, "You can't carry any more fish.") + } + stop() + } + } + } + } + + /** + * Method used to check if the catch was a success. + * + * @return `True` if so. + */ + private fun success(): Boolean { + if (delay == 1) { + return false + } + fish = option!!.rollFish(player) + return fish != null + } + + companion object { + fun checkFish(p: Player): Int { + return if (p.skills.getLevel(Skills.FISHING) >= 55 && p.skills.getLevel(Skills.STRENGTH) >= 35) { + if (p.skills.getLevel(Skills.FISHING) >= 70 && p.skills.getLevel(Skills.STRENGTH) >= 50) { + if (p.skills.getLevel(Skills.FISHING) >= 96 && p.skills.getLevel(Skills.STRENGTH) >= 76) { + 3 + } else 2 + } else 1 + } else 0 + } + } + + /** + * Constructs a new `FishingPulse` `Object`. + * + * @param player the player. + * @param npc the fishing spot NPC. + * @param option The fishing option. + */ + init { + } +} diff --git a/Server/src/main/content/global/skill/gather/fishing/barbfishing/BarbFishInteractionListeners.kt b/Server/src/main/content/global/skill/gather/fishing/barbfishing/BarbFishInteractionListeners.kt new file mode 100644 index 0000000..7963fb0 --- /dev/null +++ b/Server/src/main/content/global/skill/gather/fishing/barbfishing/BarbFishInteractionListeners.kt @@ -0,0 +1,31 @@ +package content.global.skill.gather.fishing.barbfishing + +import core.game.node.item.Item +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +class BarbFishInteractionListeners : InteractionListener { + override fun defineListeners() { + + on(25268, IntType.SCENERY, "search"){ player, _ -> + if(player.getAttribute("barbtraining:fishing",false) == true){ + if(!player.inventory.containsItem(Item(11323))){ + player.inventory.add(Item(11323)) + player.sendMessage("Under the bed you find a fishing rod.") + } else { + player.sendMessage("You find nothing under the bed") + } + } else { + player.sendMessage("Maybe I should speak to Otto before looking under his bed.") + } + return@on true + } + + on(1176, IntType.NPC, "fish"){ player, _ -> + player.pulseManager.run(BarbFishingPulse(player)) + player.sendMessage("You attempt to catch a fish...") + return@on true + } + + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/gather/fishing/barbfishing/BarbFishingPulse.kt b/Server/src/main/content/global/skill/gather/fishing/barbfishing/BarbFishingPulse.kt new file mode 100644 index 0000000..a443872 --- /dev/null +++ b/Server/src/main/content/global/skill/gather/fishing/barbfishing/BarbFishingPulse.kt @@ -0,0 +1,102 @@ +package content.global.skill.gather.fishing.barbfishing + +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.skill.SkillPulse +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.world.update.flag.context.Animation +import core.tools.RandomFunction +import org.rs09.consts.Items +import core.tools.colorize + +/** + * Pulse used for barbarian fishing + * @author Ceikry + */ +class BarbFishingPulse(player: Player) : SkillPulse(player,NPC(1176)) { + override fun checkRequirements(): Boolean { + /*if(player.getAttribute("barbtraining:fishing:completed",false) == false){ + player.sendMessage(colorize("%RYou need to complete barbarian fishing training to fish here.")) + return false + }*/ + if(player.skills.getLevel(Skills.FISHING) < 48){ + player.sendMessage(colorize("%RYou need a fishing level of at least 48 to fish here.")) + return false + } + if(player.skills.getLevel(Skills.AGILITY) < 15 || player.skills.getLevel(Skills.STRENGTH) < 15){ + player.sendMessage(colorize("%RYou need a strength and agility level of at least 15 to fish here.")) + return false + } + if(!player.inventory.containsItem(Item(11323))){ + player.sendMessage(colorize("%RYou need a barbarian fishing rod to fish here.")) + return false + } + if(player.inventory.isFull){ + player.sendMessage("You don't have enough space in your inventory.") + return false + } + if(!(player.inventory.containsItem(Item(Items.FEATHER_314)) || player.inventory.containsItem(Item(Items.FISH_OFFCUTS_11334)))){ + player.sendMessage("You don't have any bait with which to fish.") + return false + } + return true + } + + override fun animate() { + player.animator.animate(Animation(622)) + } + + override fun reward(): Boolean { + if (delay == 1){ + super.setDelay(5) + return false + } + val stragiXP = arrayOf(5,6,7) + val fishXP = arrayOf(50,70,80) + val reward = getRandomFish() + val success = rollSuccess(when(reward.id){ + 11328 -> 48 + 11330 -> 58 + 11332 -> 70 + else -> 99 + }) + val index = (when(reward.id){ + 11328 -> 0 + 11330 -> 1 + 11332 -> 2 + else -> 0 + }) + if(success){ + if(!player.inventory.remove(Item(Items.FISH_OFFCUTS_11334))) { + player.inventory.remove(Item(Items.FEATHER_314)) + } + player.inventory.add(reward) + player.skills.addExperience(Skills.FISHING,fishXP[index].toDouble()) + player.skills.addExperience(Skills.AGILITY,stragiXP[index].toDouble()) + player.skills.addExperience(Skills.STRENGTH,stragiXP[index].toDouble()) + player.sendMessage("You manage to catch a ${reward.name.toLowerCase()}.") + } + super.setDelay(5) + return player.inventory.freeSlots() == 0 + } + + fun rollSuccess(fish: Int): Boolean{ + val level = 1 + player.skills.getLevel(Skills.FISHING) + player.familiarManager.getBoost(Skills.FISHING) + val hostRatio: Double = Math.random() * fish + val clientRatio: Double = Math.random() * (level * 3.0 - fish) + return hostRatio < clientRatio + } + + fun getRandomFish(): Item{ + val fish = arrayOf(11328,11330,11332) + val fishing = player.skills.getLevel(Skills.FISHING) + val strength = player.skills.getLevel(Skills.STRENGTH) + val agility = player.skills.getLevel(Skills.AGILITY) + var possibleIndex = 0 + if(fishing >= 58 && (strength >= 30 && agility >= 30)) possibleIndex++ + if(fishing >= 70 && (strength >= 45 && agility >= 45)) possibleIndex++ + return Item(fish[RandomFunction.random(possibleIndex + 1)]) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/gather/fishing/barbfishing/FishCuttingPulse.kt b/Server/src/main/content/global/skill/gather/fishing/barbfishing/FishCuttingPulse.kt new file mode 100644 index 0000000..9ec1e14 --- /dev/null +++ b/Server/src/main/content/global/skill/gather/fishing/barbfishing/FishCuttingPulse.kt @@ -0,0 +1,46 @@ +package content.global.skill.gather.fishing.barbfishing + +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items + +/** + * Pulse used for cutting fish into fish offcuts + * @param player the player running the pulse + * @param fish the fish being cut + * @author Ceikry + */ +class FishCuttingPulse(val player: Player, val fish: Int) : Pulse(0){ + fun checkRequirements(): Boolean { + if(!(player.inventory.freeSlots() >= 2 || (player.inventory.freeSlots() >= 1 && player.inventory.containsItem(Item( + Items.FISH_OFFCUTS_11334))))){ + player.sendMessage("You do not have enough space to do that.") + return false + } + return true + } + + override fun pulse(): Boolean { + player.animator.animate(Animation(1248)) + player.inventory.remove(Item(fish)) + + player.inventory.add(Item(Items.FISH_OFFCUTS_11334)) + + player.inventory.add(Item(when(fish){ + 11328, 11330 -> Items.ROE_11324 + 11332 -> Items.CAVIAR_11326 + else -> 0 + })) + + player.skills.addExperience(Skills.COOKING,when(fish){ + 11328,11330 -> 10.0 + 11332 -> 15.0 + else -> 0.0 + }) + + return true + } +} diff --git a/Server/src/main/content/global/skill/gather/fishing/barbfishing/KnifeWithFish.kt b/Server/src/main/content/global/skill/gather/fishing/barbfishing/KnifeWithFish.kt new file mode 100644 index 0000000..0b6e249 --- /dev/null +++ b/Server/src/main/content/global/skill/gather/fishing/barbfishing/KnifeWithFish.kt @@ -0,0 +1,26 @@ +package content.global.skill.gather.fishing.barbfishing + +import core.game.interaction.NodeUsageEvent +import core.game.interaction.UseWithHandler +import core.plugin.Initializable +import core.plugin.Plugin +import org.rs09.consts.Items + +@Initializable +/** + * Handles using a knife with barbarian fishing fish + * @author Ceikry + */ +class KnifeWithFish : UseWithHandler(11328,11330,11332){ + override fun handle(event: NodeUsageEvent?): Boolean { + event?.player ?: return false + event.player.pulseManager.run(FishCuttingPulse(event.player,event.usedItem.id)) + return true + } + + override fun newInstance(arg: Any?): Plugin { + addHandler(Items.KNIFE_946, ITEM_TYPE,this) + return this + } + +} diff --git a/Server/src/main/content/global/skill/gather/fishing/barbfishing/SpotManager.kt b/Server/src/main/content/global/skill/gather/fishing/barbfishing/SpotManager.kt new file mode 100644 index 0000000..60946cd --- /dev/null +++ b/Server/src/main/content/global/skill/gather/fishing/barbfishing/SpotManager.kt @@ -0,0 +1,78 @@ +package content.global.skill.gather.fishing.barbfishing + +import content.global.skill.gather.fishing.barbfishing.SpotManager.Companion.locations +import content.global.skill.gather.fishing.barbfishing.SpotManager.Companion.usedLocations +import core.api.StartupListener +import core.api.TickListener +import core.game.node.entity.npc.NPC +import core.game.world.map.Location +import core.tools.RandomFunction + +/** + * Manages fishing spot spawning and relocation + * @author Ceikry + */ +class SpotManager : TickListener, StartupListener { + var ticks = 0 + val spots = ArrayList() + + companion object{ + val usedLocations = arrayListOf() + val locations = listOf( + Location.create(2506, 3494, 0), + Location.create(2504, 3497, 0), + Location.create(2504, 3497, 0), + Location.create(2500, 3506, 0), + Location.create(2500, 3509, 0), + Location.create(2500, 3512, 0), + Location.create(2504, 3516, 0) + ) + } + + override fun tick() { + if(ticks % 50 == 0){ + usedLocations.clear() + for(spot in spots) usedLocations.add(spot.loc ?: Location(0,0,0)) + } + } + + override fun startup() { + for(i in 0 until 5){ + spots.add(BarbFishingSpot(getNewLoc(), getNewTTL()).also { it.init() }) + } + } +} + +fun getNewTTL(): Int{ + return RandomFunction.random(400,2000) +} + +fun getNewLoc(): Location { + val possibleLoc = ArrayList() + for(loc in locations) if(usedLocations.contains(loc)) continue else possibleLoc.add(loc) + val loc = possibleLoc.random() + usedLocations.add(loc) + return loc +} + +class BarbFishingSpot(var loc: Location? = null, var ttl: Int) : NPC(1176){ + init { + location = loc + } + val locations = listOf( + Location.create(2506, 3494, 0), + Location.create(2504, 3497, 0), + Location.create(2504, 3497, 0), + Location.create(2500, 3506, 0), + Location.create(2500, 3509, 0), + Location.create(2500, 3512, 0), + Location.create(2504, 3516, 0) + ) + override fun handleTickActions() { + if(location != loc) properties.teleportLocation = loc.also { ttl = getNewTTL() } + if(ttl-- <= 0){ + usedLocations.remove(location) + loc = getNewLoc() + } + } +} diff --git a/Server/src/main/content/global/skill/gather/mining/MiningListener.kt b/Server/src/main/content/global/skill/gather/mining/MiningListener.kt new file mode 100644 index 0000000..1e6bb3a --- /dev/null +++ b/Server/src/main/content/global/skill/gather/mining/MiningListener.kt @@ -0,0 +1,232 @@ +package content.global.skill.gather.mining + +import content.data.skill.SkillingPets +import content.data.skill.SkillingTool +import content.global.skill.skillcapeperks.SkillcapePerks +import content.global.activity.shootingstar.StarBonus +import core.api.* +import core.cache.def.impl.ItemDefinition +import core.game.event.ResourceProducedEvent +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.Node +import core.game.node.entity.npc.drop.DropFrequency +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.diary.DiaryType +import core.game.node.entity.skill.Skills +import core.game.node.item.ChanceItem +import core.game.node.scenery.Scenery +import core.game.node.scenery.SceneryBuilder +import core.game.system.command.sets.STATS_BASE +import core.game.system.command.sets.STATS_ROCKS +import core.game.world.map.zone.ZoneBorders +import core.tools.RandomFunction +import core.tools.prependArticle +import org.rs09.consts.Items + +class MiningListener : InteractionListener { + override fun defineListeners() { + defineInteraction( + IntType.SCENERY, + MiningNode.values().map { it.id }.toIntArray(), + "mine", + persistent = true, allowedDistance = 1, + handler = ::handleMining + ) + } + private val GEM_REWARDS = arrayOf(ChanceItem(1623, 1, DropFrequency.COMMON), ChanceItem(1621, 1, DropFrequency.COMMON), ChanceItem(1619, 1, DropFrequency.UNCOMMON), ChanceItem(1617, 1, DropFrequency.RARE)) + + private fun handleMining(player: Player, node: Node, state: Int) : Boolean { + val resource = MiningNode.forId(node.id) + val tool = SkillingTool.getPickaxe(player) + val isEssence = resource.id == 2491 + val isGems = resource.identifier == MiningNode.GEM_ROCK_0.identifier + + if (!finishedMoving(player)) + return true + + if (state == 0) { + if (!checkRequirements(player, resource, node)) { + player.scripts.reset() + return true + } + anim(player, tool) + sendMessage(player, "You swing your pickaxe at the rock...") + return delayScript(player, getDelay(resource)) + } + + anim(player, tool) + if (!checkReward(player, resource, tool)) + return delayScript(player, getDelay(resource)) + + // Reward logic + var reward = resource!!.reward + var rewardAmount : Int + if (reward > 0) { + reward = calculateReward(player, resource, isEssence, isGems, reward) // calculate rewards + rewardAmount = calculateRewardAmount(player, isEssence, reward) // calculate amount + + player.dispatch(ResourceProducedEvent(reward, rewardAmount, node)) + SkillingPets.checkPetDrop(player, SkillingPets.GOLEM) // roll for pet + + // Reward mining experience + val experience = resource!!.experience * rewardAmount + rewardXP(player, Skills.MINING, experience) + + // If player is wearing Bracelet of Clay, soften + if(reward == Items.CLAY_434){ + val bracelet = getItemFromEquipment(player, EquipmentSlot.HANDS) + if(bracelet != null && bracelet.id == Items.BRACELET_OF_CLAY_11074){ + var charges = player.getAttribute("jewellery-charges:bracelet-of-clay", 28) + charges-- + reward = Items.SOFT_CLAY_1761 + sendMessage(player, "Your bracelet of clay softens the clay for you.") + if(charges <= 0) { + if(removeItem(player, bracelet, Container.EQUIPMENT)) { + sendMessage(player, "Your bracelet of clay crumbles to dust.") + charges = 28 + } + } + player.setAttribute("/save:jewellery-charges:bracelet-of-clay", charges) + } + } + + //If the player is mining gold in the witchaven dungeon, reward family crest perfect gold ore + val familyCrestGoldOreArea = ZoneBorders(2733, 9695, 2741, 9683) + if (reward == Items.GOLD_ORE_444 && inBorders(player, familyCrestGoldOreArea)) { + reward = Items.PERFECT_GOLD_ORE_446 + } + val rewardName = getItemName(reward).lowercase() + + // Send the message for the resource reward + if (isGems) { + sendMessage(player, "You get ${prependArticle(rewardName)}.") + } else { + sendMessage(player, "You get some ${rewardName.lowercase()}.") + } + + // Give the mining reward, increment 'rocks mined' attribute + addItemOrDrop(player, reward, rewardAmount) + var rocksMined = getAttribute(player, "$STATS_BASE:$STATS_ROCKS", 0) + setAttribute(player, "/save:$STATS_BASE:$STATS_ROCKS", rocksMined + rewardAmount) + + // Calculate bonus gem chance while mining + if (!isEssence) { + var chance = 282 + var altered = false + val ring = getItemFromEquipment(player, EquipmentSlot.RING) + if (ring != null && ring.name.lowercase().contains("ring of wealth") || inEquipment(player, Items.RING_OF_THE_STAR_SPRITE_14652)) { + chance = (chance / 1.5).toInt() + altered = true + } + val necklace = getItemFromEquipment(player, EquipmentSlot.NECK) + if (necklace != null && necklace.id in 1705..1713) { + chance = (chance / 1.5).toInt() + altered = true + } + if (RandomFunction.roll(chance)) { + val gem = GEM_REWARDS.random() + sendMessage(player,"You find a ${gem.name}!") + if (freeSlots(player) == 0) { + sendMessage(player,"You do not have enough space in your inventory, so you drop the gem on the floor.") + } + addItemOrDrop(player, gem.id) + } + } + + // Transform ore to depleted version + if (!isEssence && resource!!.respawnRate != 0) { + SceneryBuilder.replace(node as Scenery, Scenery(resource!!.emptyId, node.getLocation(), node.type, node.rotation), resource!!.respawnDuration) + node.setActive(false) + return true + } + } + return true + } + + private fun calculateRewardAmount(player: Player, isMiningEssence: Boolean, reward: Int): Int { + var amount = 1 + + // If player is wearing Varrock armour from diary, roll chance at extra ore + if (!isMiningEssence && player.achievementDiaryManager.getDiary(DiaryType.VARROCK).level != -1) { + when (reward) { + Items.CLAY_434, Items.COPPER_ORE_436, Items.TIN_ORE_438, Items.LIMESTONE_3211, Items.BLURITE_ORE_668, Items.IRON_ORE_440, Items.ELEMENTAL_ORE_2892, Items.SILVER_ORE_442, Items.COAL_453 -> if (player.achievementDiaryManager.armour >= 0 && RandomFunction.random(100) < 4) { + amount += 1 + sendMessage(player,"The Varrock armour allows you to mine an additional ore.") + } + Items.GOLD_ORE_444, Items.GRANITE_500G_6979, Items.GRANITE_2KG_6981, Items.GRANITE_5KG_6983, Items.MITHRIL_ORE_447 -> if (player.achievementDiaryManager.armour >= 1 && RandomFunction.random(100) < 3) { + amount += 1 + sendMessage(player, "The Varrock armour allows you to mine an additional ore.") + } + Items.ADAMANTITE_ORE_449 -> if (player.achievementDiaryManager.armour >= 2 && RandomFunction.random(100) < 2) { + amount += 1 + sendMessage(player, "The Varrock armour allows you to mine an additional ore.") + } + } + } + + // If player has mining boost from Shooting Star, roll chance at extra ore + if (hasTimerActive(player)) { + if (RandomFunction.getRandom(5) == 3) { + sendMessage(player, "...you manage to mine a second ore thanks to the Star Sprite.") + amount += 1 + } + } + return amount + } + + private fun calculateReward(player: Player, resource: MiningNode, isMiningEssence: Boolean, isMiningGems: Boolean, reward: Int): Int { + // If the player is mining sandstone or granite, then get size of sandstone/granite and xp reward for that size + var reward = reward + if (resource == MiningNode.SANDSTONE || resource == MiningNode.GRANITE) { + val value = RandomFunction.randomize(if (resource == MiningNode.GRANITE) 3 else 4) + reward += value shl 1 + rewardXP(player, Skills.MINING, value * 10.toDouble()) + } else if (isMiningEssence && getDynLevel(player, Skills.MINING) >= 30) { + reward = 7936 + } else if (isMiningGems) { + reward = RandomFunction.rollWeightedChanceTable(MiningNode.gemRockGems).id + } + return reward + } + + private fun checkReward(player: Player, resource: MiningNode?, tool: SkillingTool): Boolean { + val level = 1 + getDynLevel(player, Skills.MINING) + getFamiliarBoost(player, Skills.MINING) + val hostRatio = Math.random() * (100.0 * resource!!.rate) + var toolRatio = tool.ratio + if(SkillcapePerks.isActive(SkillcapePerks.PRECISION_MINER,player)){ + toolRatio += 0.075 + } + val clientRatio = Math.random() * ((level - resource.level) * (1.0 + toolRatio)) + return hostRatio < clientRatio + } + + fun getDelay(resource: MiningNode) : Int { + return if (resource.id == 2491) 3 else 4 + } + + fun anim(player: Player, tool: SkillingTool) { + if (animationFinished(player)) + animate(player, tool.animation) + } + + fun checkRequirements(player: Player, resource: MiningNode, node: Node): Boolean { + if (getDynLevel(player, Skills.MINING) < resource.level) { + sendMessage(player, "You need a mining level of ${resource.level} to mine this rock.") + return false + } + if (SkillingTool.getPickaxe(player) == null) { + sendMessage(player, "You do not have a pickaxe to use.") + return false + } + if (freeSlots(player) == 0) { + if(resource.identifier == 13.toByte()) { + sendDialogue(player,"Your inventory is too full to hold any more gems.") + return false + } + sendDialogue(player,"Your inventory is too full to hold any more ${ItemDefinition.forId(resource!!.reward).name.lowercase()}.") + return false + } + return node.isActive + } +} diff --git a/Server/src/main/content/global/skill/gather/mining/MiningNode.java b/Server/src/main/content/global/skill/gather/mining/MiningNode.java new file mode 100644 index 0000000..b271fde --- /dev/null +++ b/Server/src/main/content/global/skill/gather/mining/MiningNode.java @@ -0,0 +1,653 @@ +package content.global.skill.gather.mining; + +import core.ServerConstants; +import core.game.node.item.WeightedChanceItem; +import core.game.world.repository.Repository; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +// 11553 11552 +/** + * Mining nodes + * @author ceik + */ +public enum MiningNode{ + //Copper + COPPER_ORE_0( 2090, 450, (byte) 1), + COPPER_ORE_1( 2091, 452, (byte) 1), + COPPER_ORE_2( 4976, 4994, (byte) 1), + COPPER_ORE_3( 4977, 4995, (byte) 1), + COPPER_ORE_4( 4978, 4996, (byte) 1), + COPPER_ORE_5( 9710, 18954, (byte) 1), + COPPER_ORE_6( 9709, 32448, (byte) 1), + COPPER_ORE_7( 9708, 32447, (byte) 1), + COPPER_ORE_8( 11960,11555, (byte) 1), + COPPER_ORE_9( 11961,11556, (byte) 1), + COPPER_ORE_10(11962,11557, (byte) 1), + COPPER_ORE_11(11937,11553, (byte) 1), + COPPER_ORE_12(11936,11552, (byte) 1), + COPPER_ORE_13(11938,11554, (byte) 1), + COPPER_ORE_14(12746,450, (byte) 1), + COPPER_ORE_15(14906,14894, (byte) 1), + COPPER_ORE_16(14907,14895, (byte) 1), + COPPER_ORE_17(20448,20445, (byte) 1), + COPPER_ORE_18(20451,20445, (byte) 1), + COPPER_ORE_19(20446,20443, (byte) 1), + COPPER_ORE_20(20447,20444, (byte) 1), + COPPER_ORE_21(20408,20407, (byte) 1), + COPPER_ORE_22(18993,19005, (byte) 1), + COPPER_ORE_23(18992,19004, (byte) 1), + COPPER_ORE_24(19007,19016, (byte) 1), + COPPER_ORE_25(19006,19021, (byte) 1), + COPPER_ORE_26(18991,19003, (byte) 1), + COPPER_ORE_27(19008,19017, (byte) 1), + COPPER_ORE_28(21285,21297, (byte) 1), + COPPER_ORE_29(21284,21296, (byte) 1), + COPPER_ORE_30(21286,21298, (byte) 1), + COPPER_ORE_31(29231,29219, (byte) 1), + COPPER_ORE_32(29230,29218, (byte) 1), + COPPER_ORE_33(29232,29220, (byte) 1), + COPPER_ORE_34(31082,37650, (byte) 1), + COPPER_ORE_35(31081,37649, (byte) 1), + COPPER_ORE_36(31080,37639, (byte) 1), + COPPER_ORE_37(37647,37650, (byte) 1), + COPPER_ORE_38(37646,37649, (byte) 1), + COPPER_ORE_39(37645,37639, (byte) 1), + COPPER_ORE_40(37637,37639, (byte) 1), + COPPER_ORE_41(37688,21298, (byte) 1), + COPPER_ORE_42(37686,21296, (byte) 1), + COPPER_ORE_43(37687,21297, (byte) 1), + COPPER_ORE_44(3042, 11552, (byte) 1), + + //Tin + TIN_ORE_0( 2094, 450, (byte) 2), + TIN_ORE_1( 2095, 452, (byte) 2), + TIN_ORE_2( 3043, 11552, (byte) 2), + TIN_ORE_3( 4979, 4994, (byte) 2), + TIN_ORE_4( 4980, 4995, (byte) 2), + TIN_ORE_5( 4981, 4996, (byte) 2), + TIN_ORE_6( 11957,11555, (byte) 2), + TIN_ORE_7( 11958,11556, (byte) 2), + TIN_ORE_8( 11959,11557, (byte) 2), + TIN_ORE_9( 11934,11553, (byte) 2), + TIN_ORE_10(11935,11554, (byte) 2), + TIN_ORE_11(11933,11552, (byte) 2), + TIN_ORE_12(14902,14894, (byte) 2), + TIN_ORE_13(14903,14895, (byte) 2), + TIN_ORE_14(18995,19004, (byte) 2), + TIN_ORE_15(18994,19003, (byte) 2), + TIN_ORE_16(18996,19005, (byte) 2), + TIN_ORE_17(19025,19016, (byte) 2), + TIN_ORE_18(19024,19021, (byte) 2), + TIN_ORE_19(19026,19017, (byte) 2), + TIN_ORE_20(21293,21296, (byte) 2), + TIN_ORE_21(21295,21298, (byte) 2), + TIN_ORE_22(21294,21297, (byte) 2), + TIN_ORE_23(29227,29218, (byte) 2), + TIN_ORE_24(29229,29220, (byte) 2), + TIN_ORE_25(29228,29219, (byte) 2), + TIN_ORE_26(31079,37650, (byte) 2), + TIN_ORE_27(31078,37649, (byte) 2), + TIN_ORE_28(31077,37639, (byte) 2), + TIN_ORE_29(37644,37650, (byte) 2), + TIN_ORE_30(37643,37649, (byte) 2), + TIN_ORE_31(37642,37639, (byte) 2), + TIN_ORE_32(37638,37639, (byte) 2), + TIN_ORE_33(37685,21298, (byte) 2), + + //Clay + CLAY_0( 2109, 452, (byte) 3), + CLAY_1( 2108, 450, (byte) 3), + CLAY_2( 9712, 32448, (byte) 3), + CLAY_3( 9713, 18954, (byte) 3), + CLAY_4( 9711, 32447, (byte) 3), + CLAY_5( 10949,10945, (byte) 3), + CLAY_6( 11190,21297, (byte) 3), + CLAY_7( 11191,21298, (byte) 3), + CLAY_8( 11189,21296, (byte) 3), + CLAY_9( 12942,4995, (byte) 3), + CLAY_10(12943,4996, (byte) 3), + CLAY_11(12941,4994, (byte) 3), + CLAY_12(14904,14894, (byte) 3), + CLAY_13(14905,14895, (byte) 3), + CLAY_14(15505,11557, (byte) 3), + CLAY_15(15504,11556, (byte) 3), + CLAY_16(15503,11555, (byte) 3), + CLAY_17(20449,20443, (byte) 3), + CLAY_18(20450,20444, (byte) 3), + CLAY_19(20409,20407, (byte) 3), + CLAY_20(32429,33400, (byte) 3), + CLAY_21(32430,33401, (byte) 3), + CLAY_22(32431,33402, (byte) 3), + CLAY_23(31062,37639, (byte) 3), + CLAY_24(31063,37649, (byte) 3), + CLAY_25(31064,37650, (byte) 3), + + //Limestone + LIMESTONE_0(4027,12564, (byte) 4), + LIMESTONE_1(4028,12565, (byte) 4), + LIMESTONE_2(4029,12566, (byte) 4), + LIMESTONE_3(4030,12567, (byte) 4), + + //Blurite + BLURITE_ORE_0(33220,33222, (byte) 5), + BLURITE_ORE_1(33221,33223, (byte) 5), + + //Iron + IRON_ORE_0( 2092, 450, (byte) 6), + IRON_ORE_1( 2093, 452, (byte) 6), + IRON_ORE_2( 4982, 4994, (byte) 6), + IRON_ORE_3( 4983, 4995, (byte) 6), + IRON_ORE_4( 4984, 4996, (byte) 6), + IRON_ORE_5( 6943, 21296, (byte) 6), + IRON_ORE_6( 6944, 21297, (byte) 6), + IRON_ORE_7( 9718, 32448, (byte) 6), + IRON_ORE_8( 9719, 18954, (byte) 6), + IRON_ORE_9( 9717, 32447, (byte) 6), + IRON_ORE_10(11956,11557, (byte) 6), + IRON_ORE_11(11954,11555, (byte) 6), + IRON_ORE_12(11955,11556, (byte) 6), + IRON_ORE_13(14914,14895, (byte) 6), + IRON_ORE_14(14913,14894, (byte) 6), + IRON_ORE_15(14858,25373, (byte) 6), + IRON_ORE_16(14857,25372, (byte) 6), + IRON_ORE_17(14856,25371, (byte) 6), + IRON_ORE_18(14900,14894, (byte) 6), + IRON_ORE_19(14901,14895, (byte) 6), + IRON_ORE_20(20423,20444, (byte) 6), + IRON_ORE_21(20422,20443, (byte) 6), + IRON_ORE_22(20425,20407, (byte) 6), + IRON_ORE_23(20424,20445, (byte) 6), + IRON_ORE_24(19002,19005, (byte) 6), + IRON_ORE_25(19001,19004, (byte) 6), + IRON_ORE_26(19000,19003, (byte) 6), + IRON_ORE_27(21281,21296, (byte) 6), + IRON_ORE_28(21283,21298, (byte) 6), + IRON_ORE_29(21282,21297, (byte) 6), + IRON_ORE_30(29221,29218, (byte) 6), + IRON_ORE_31(29223,29220, (byte) 6), + IRON_ORE_32(29222,29219, (byte) 6), + IRON_ORE_33(32441,33400, (byte) 6), + IRON_ORE_34(32443,33402, (byte) 6), + IRON_ORE_35(32442,33401, (byte) 6), + IRON_ORE_36(32452,32448, (byte) 6), + IRON_ORE_37(32451,32447, (byte) 6), + IRON_ORE_38(31073,37650, (byte) 6), + IRON_ORE_39(31072,37649, (byte) 6), + IRON_ORE_40(31071,37639, (byte) 6), + IRON_ORE_41(37307,11552, (byte) 6), + IRON_ORE_42(37309,11554, (byte) 6), + IRON_ORE_43(37308,11553, (byte) 6), + IRON_ORE_49(42034,450, (byte) 6), + + //Silver + SILVER_ORE_0( 2101, 452, (byte) 7), + SILVER_ORE_1( 2100, 450, (byte) 7), + SILVER_ORE_2( 6945, 21296, (byte) 7), + SILVER_ORE_3( 6946, 21297, (byte) 7), + SILVER_ORE_4( 9716, 18954, (byte) 7), + SILVER_ORE_5( 9714, 32447, (byte) 7), + SILVER_ORE_6( 9715, 32448, (byte) 7), + SILVER_ORE_7( 11188,21298, (byte) 7), + SILVER_ORE_8( 11186,21296, (byte) 7), + SILVER_ORE_9( 11187,21297, (byte) 7), + SILVER_ORE_10(15581,14834, (byte) 7), + SILVER_ORE_11(15580,14833, (byte) 7), + SILVER_ORE_12(15579,14832, (byte) 7), + SILVER_ORE_13(16998,14915, (byte) 7), + SILVER_ORE_14(16999,14916, (byte) 7), + SILVER_ORE_15(17007,14915, (byte) 7), + SILVER_ORE_16(17000,31061, (byte) 7), + SILVER_ORE_17(17009,31061, (byte) 7), + SILVER_ORE_18(17008,14916, (byte) 7), + SILVER_ORE_19(17385,32447, (byte) 7), + SILVER_ORE_20(17387,18954, (byte) 7), + SILVER_ORE_21(17386,32448, (byte) 7), + SILVER_ORE_22(29225,29219, (byte) 7), + SILVER_ORE_23(29224,29218, (byte) 7), + SILVER_ORE_24(29226,29220, (byte) 7), + SILVER_ORE_25(32445,33401, (byte) 7), + SILVER_ORE_26(32444,33400, (byte) 7), + SILVER_ORE_27(32446,33402, (byte) 7), + SILVER_ORE_28(31075,37649, (byte) 7), + SILVER_ORE_29(31074,37639, (byte) 7), + SILVER_ORE_30(31076,37650, (byte) 7), + SILVER_ORE_31(37305,11553, (byte) 7), + SILVER_ORE_32(37304,11552, (byte) 7), + SILVER_ORE_33(37306,11554, (byte) 7), + SILVER_ORE_34(37670,11552, (byte) 7), + SILVER_ORE_35(11948,11555, (byte) 7), + SILVER_ORE_36(11949,11556, (byte) 7), + SILVER_ORE_37(11950,11557, (byte) 7), + SILVER_ORE_38(2311, 11552, (byte) 7), + + //Coal + COAL_0( 2097, 452, (byte) 8), + COAL_1( 2096, 450, (byte) 8), + COAL_2( 4985, 4994, (byte) 8), + COAL_3( 4986, 4995, (byte) 8), + COAL_4( 4987, 4996, (byte) 8), + COAL_5( 4676, 450, (byte) 8), + COAL_6( 10948,10944, (byte) 8), + COAL_7( 11964,11556, (byte) 8), + COAL_8( 11965,11557, (byte) 8), + COAL_9( 11963,11555, (byte) 8), + COAL_10(11932,11554, (byte) 8), + COAL_11(11930,11552, (byte) 8), + COAL_12(11931,11553, (byte) 8), + COAL_13(15246,15249, (byte) 8), + COAL_14(15247,15250, (byte) 8), + COAL_15(15248,15251, (byte) 8), + COAL_16(14852,25373, (byte) 8), + COAL_17(14851,25372, (byte) 8), + COAL_18(14850,25371, (byte) 8), + COAL_19(20410,20443, (byte) 8), + COAL_20(20411,20444, (byte) 8), + COAL_21(20412,20445, (byte) 8), + COAL_22(20413,20407, (byte) 8), + COAL_23(18999,19005, (byte) 8), + COAL_24(18998,19004, (byte) 8), + COAL_25(18997,19003, (byte) 8), + COAL_26(21287,21296, (byte) 8), + COAL_27(21289,21298, (byte) 8), + COAL_28(21288,21297, (byte) 8), + COAL_29(23565,21298, (byte) 8), + COAL_30(23564,21297, (byte) 8), + COAL_31(23563,21296, (byte) 8), + COAL_32(29215,29218, (byte) 8), + COAL_33(29217,29220, (byte) 8), + COAL_34(29216,29219, (byte) 8), + COAL_35(32426,33400, (byte) 8), + COAL_36(32427,33401, (byte) 8), + COAL_37(32428,33402, (byte) 8), + COAL_38(32450,32448, (byte) 8), + COAL_39(32449,32447, (byte) 8), + COAL_40(31068,37639, (byte) 8), + COAL_41(31069,37649, (byte) 8), + COAL_42(31070,37650, (byte) 8), + COAL_43(31168,14833, (byte) 8), + COAL_44(31169,14834, (byte) 8), + COAL_45(31167,14832, (byte) 8), + COAL_46(37699,21298, (byte) 8), + COAL_47(37698,21297, (byte) 8), + COAL_48(37697,21296, (byte) 8), + COAL_49(42035,452, (byte) 8), + + //Gold + GOLD_ORE_0( 2099, 452, (byte) 9), + GOLD_ORE_1( 2098, 450, (byte) 9), + GOLD_ORE_2( 2611, 21298, (byte) 9), + GOLD_ORE_3( 2610, 21297, (byte) 9), + GOLD_ORE_4( 2609, 21296, (byte) 9), + GOLD_ORE_5( 9722, 18954, (byte) 9), + GOLD_ORE_6( 9720, 32447, (byte) 9), + GOLD_ORE_7( 9721, 32448, (byte) 9), + GOLD_ORE_8( 11183,21296, (byte) 9), + GOLD_ORE_9( 11184,21297, (byte) 9), + GOLD_ORE_10(11185,21298, (byte) 9), + GOLD_ORE_11(11952,11556, (byte) 9), + GOLD_ORE_12(11953,11557, (byte) 9), + GOLD_ORE_13(11951,11555, (byte) 9), + GOLD_ORE_14(15578,14834, (byte) 9), + GOLD_ORE_15(15577,14833, (byte) 9), + GOLD_ORE_16(15576,14832, (byte) 9), + GOLD_ORE_17(17002,14916, (byte) 9), + GOLD_ORE_18(17003,31061, (byte) 9), + GOLD_ORE_19(17001,14915, (byte) 9), + GOLD_ORE_20(21291,21297, (byte) 9), + GOLD_ORE_21(21290,21296, (byte) 9), + GOLD_ORE_22(21292,21298, (byte) 9), + GOLD_ORE_23(32433,33401, (byte) 9), + GOLD_ORE_24(32432,33400, (byte) 9), + GOLD_ORE_25(32434,33402, (byte) 9), + GOLD_ORE_26(31065,37639, (byte) 9), + GOLD_ORE_27(31066,37649, (byte) 9), + GOLD_ORE_28(31067,37650, (byte) 9), + GOLD_ORE_29(37311,11553, (byte) 9), + GOLD_ORE_30(37310,11552, (byte) 9), + GOLD_ORE_31(37312,11554, (byte) 9), + GOLD_ORE_32(37471,15249, (byte) 9), + GOLD_ORE_33(37473,15251, (byte) 9), + GOLD_ORE_34(37472,15250, (byte) 9), + GOLD_ORE_49(42033,452, (byte) 9), + + //Mithril + MITHRIL_ORE_0( 2103, 452, (byte) 10), + MITHRIL_ORE_1( 2102, 450, (byte) 10), + MITHRIL_ORE_2( 4988, 4994, (byte) 10), + MITHRIL_ORE_3( 4989, 4995, (byte) 10), + MITHRIL_ORE_4( 4990, 4996, (byte) 10), + MITHRIL_ORE_5( 11943,11553, (byte) 10), + MITHRIL_ORE_6( 11942,11552, (byte) 10), + MITHRIL_ORE_7( 11945,11555, (byte) 10), + MITHRIL_ORE_8( 11944,11554, (byte) 10), + MITHRIL_ORE_9( 11947,11557, (byte) 10), + MITHRIL_ORE_10(11946,11556, (byte) 10), + MITHRIL_ORE_11(14855,25373, (byte) 10), + MITHRIL_ORE_12(14854,25372, (byte) 10), + MITHRIL_ORE_13(14853,25371, (byte) 10), + MITHRIL_ORE_14(16687,450, (byte) 10), + MITHRIL_ORE_15(20421,20407, (byte) 10), + MITHRIL_ORE_16(20420,20445, (byte) 10), + MITHRIL_ORE_17(20419,20444, (byte) 10), + MITHRIL_ORE_18(20418,20443, (byte) 10), + MITHRIL_ORE_19(19012,19021, (byte) 10), + MITHRIL_ORE_20(19013,19016, (byte) 10), + MITHRIL_ORE_21(19014,19017, (byte) 10), + MITHRIL_ORE_22(21278,21296, (byte) 10), + MITHRIL_ORE_23(21279,21297, (byte) 10), + MITHRIL_ORE_24(21280,21298, (byte) 10), + MITHRIL_ORE_25(25369,10586, (byte) 10), + MITHRIL_ORE_26(25368,10585, (byte) 10), + MITHRIL_ORE_27(25370,10587, (byte) 10), + MITHRIL_ORE_28(29236,29218, (byte) 10), + MITHRIL_ORE_29(29237,29219, (byte) 10), + MITHRIL_ORE_30(29238,29220, (byte) 10), + MITHRIL_ORE_31(32439,33401, (byte) 10), + MITHRIL_ORE_32(32438,33400, (byte) 10), + MITHRIL_ORE_33(32440,33402, (byte) 10), + MITHRIL_ORE_34(31087,37649, (byte) 10), + MITHRIL_ORE_35(31086,37639, (byte) 10), + MITHRIL_ORE_36(31088,37650, (byte) 10), + MITHRIL_ORE_37(31170,14832, (byte) 10), + MITHRIL_ORE_38(31171,14833, (byte) 10), + MITHRIL_ORE_39(31172,14834, (byte) 10), + MITHRIL_ORE_40(37692,21296, (byte) 10), + MITHRIL_ORE_41(37693,21297, (byte) 10), + MITHRIL_ORE_42(37694,21298, (byte) 10), + MITHRIL_ORE_49(42036,452, (byte) 10), + + //Adamant + ADAMANTITE_ORE_0( 2105, 452, (byte) 11), + ADAMANTITE_ORE_1( 2104, 450, (byte) 11), + ADAMANTITE_ORE_2( 4991, 4994, (byte) 11), + ADAMANTITE_ORE_3( 4992, 4995, (byte) 11), + ADAMANTITE_ORE_4( 4993, 4996, (byte) 11), + ADAMANTITE_ORE_5( 11941,11554, (byte) 11), + ADAMANTITE_ORE_6( 11940,11553, (byte) 11), + ADAMANTITE_ORE_7( 11939,11552, (byte) 11), + ADAMANTITE_ORE_8( 14864,25373, (byte) 11), + ADAMANTITE_ORE_9( 14863,25372, (byte) 11), + ADAMANTITE_ORE_10(14862,25371, (byte) 11), + ADAMANTITE_ORE_11(20417,20407, (byte) 11), + ADAMANTITE_ORE_12(20416,20445, (byte) 11), + ADAMANTITE_ORE_13(20414,20443, (byte) 11), + ADAMANTITE_ORE_14(20415,20444, (byte) 11), + ADAMANTITE_ORE_15(19020,19017, (byte) 11), + ADAMANTITE_ORE_16(19018,19021, (byte) 11), + ADAMANTITE_ORE_17(19019,19016, (byte) 11), + ADAMANTITE_ORE_18(21275,21296, (byte) 11), + ADAMANTITE_ORE_19(21276,21297, (byte) 11), + ADAMANTITE_ORE_20(21277,21298, (byte) 11), + ADAMANTITE_ORE_21(29233,29218, (byte) 11), + ADAMANTITE_ORE_22(29234,29219, (byte) 11), + ADAMANTITE_ORE_23(29235,29220, (byte) 11), + ADAMANTITE_ORE_24(32435,33400, (byte) 11), + ADAMANTITE_ORE_25(32437,33402, (byte) 11), + ADAMANTITE_ORE_26(32436,33401, (byte) 11), + ADAMANTITE_ORE_27(31083,37639, (byte) 11), + ADAMANTITE_ORE_28(31085,37650, (byte) 11), + ADAMANTITE_ORE_29(31084,37649, (byte) 11), + ADAMANTITE_ORE_30(31173,14832, (byte) 11), + ADAMANTITE_ORE_31(31174,14833, (byte) 11), + ADAMANTITE_ORE_32(31175,14834, (byte) 11), + ADAMANTITE_ORE_33(37468,15249, (byte) 11), + ADAMANTITE_ORE_34(37469,15250, (byte) 11), + ADAMANTITE_ORE_35(37470,15251, (byte) 11), + ADAMANTITE_ORE_36(37689,21296, (byte) 11), + ADAMANTITE_ORE_37(37690,21297, (byte) 11), + ADAMANTITE_ORE_38(37691,21298, (byte) 11), + ADAMANTITE_ORE_39(42037,452, (byte) 11), + + //Runite + RUNITE_ORE_0( 2107, 452, (byte) 12), + RUNITE_ORE_1( 2106, 450, (byte) 12), + RUNITE_ORE_5( 14861,25373, (byte) 12), + RUNITE_ORE_6( 14860,25372, (byte) 12), + RUNITE_ORE_7( 14859,25371, (byte) 12), + RUNITE_ORE_8( 33079,33401, (byte) 12), + RUNITE_ORE_9( 33078,33400, (byte) 12), + RUNITE_ORE_10(37208,21296, (byte) 12), + RUNITE_ORE_11(37465,15249, (byte) 12), + RUNITE_ORE_12(37466,15250, (byte) 12), + RUNITE_ORE_13(37467,15251, (byte) 12), + RUNITE_ORE_14(37695,21297, (byte) 12), + RUNITE_ORE_15(37696,21298, (byte) 12), + + //Gem rocks + GEM_ROCK_0(23567,21297, (byte) 13), + GEM_ROCK_1(23566,21296, (byte) 13), + GEM_ROCK_2(23568,21298, (byte) 13), + GEM_ROCK_3(23560,25371, (byte) 13),// good?? + GEM_ROCK_4(23561,25372, (byte) 13),//good ?? + GEM_ROCK_5(23562,21298, (byte) 13),//good + + + //Rune essence + RUNE_ESSENCE(2491, -1, (byte) 14), + + //Sandstone + SANDSTONE(10946,10944, (byte) 15), + + //Granite + GRANITE(10947,10945, (byte) 16), + + //Rubium? + RUBIUM(29746,29747, (byte) 17), + + //Magic stone (Tears of Guthix) + MAGIC_STONE_0( 6669, 21296, (byte) 18), // Was mistaken for RUNITE_ORE_2 + MAGIC_STONE_1( 6671, 21298, (byte) 18), // Was mistaken for RUNITE_ORE_3 + MAGIC_STONE_2( 6670, 21297, (byte) 18), // Was mistaken for RUNITE_ORE_4 + + ; + + + public static List gemRockGems = new ArrayList<>(20); + static { + gemRockGems.add(new WeightedChanceItem(1625, 1, 60)); //uncut Opal + gemRockGems.add(new WeightedChanceItem(1627, 1, 30)); //uncut Jade + gemRockGems.add(new WeightedChanceItem(1629, 1, 15)); //uncut Red Topaz + gemRockGems.add(new WeightedChanceItem(1623, 1, 9)); //uncut Sapphire + gemRockGems.add(new WeightedChanceItem(1621, 1, 5)); //uncut Emerald + gemRockGems.add(new WeightedChanceItem(1619, 1, 5)); //uncut Ruby + gemRockGems.add(new WeightedChanceItem(1617, 1, 4)); //uncut Diamond + } + int full,empty,respawnRate,reward,level; + double rate,experience; + public byte identifier; + + MiningNode(int full, int empty, byte identifier){ + this.full = full; + this.empty = empty; + this.identifier = identifier; + switch(identifier & 0xFF) { + case 1: + case 2: + respawnRate = 4 | 8 << 16; + experience = 17.5; + rate = 0.05; + reward = identifier == 1 ? 436 : 438; + level = 1; + break; + case 3: + respawnRate = 1 | 1 << 16; + experience = 5.0; + rate = 0.1; + reward = 434; + level = 1; + break; + case 4: + respawnRate = 10 | 20 << 16; + experience = 26.5; + rate = 0.2; + reward = 3211; + level = 10; + break; + case 5: + respawnRate = 10 | 20 << 16; + experience = 17.5; + rate = 0.2; + reward = 668; + level = 10; + break; + case 6: + respawnRate = 15 | 25 << 16; + experience = 35.0; + rate = 0.2; + reward = 440; + level = 15; + break; + case 7: + respawnRate = 100 | 200 << 16; + experience = 40.0; + rate = 0.3; + reward = 442; + level = 20; + break; + case 8: + respawnRate = 50 | 100 << 16; + experience = 50.0; + rate = 0.4; + reward = 453; + level = 30; + break; + case 9: + respawnRate = 100 | 200 << 16; + experience = 65.0; + rate = 0.6; + reward = 444; + level = 40; + break; + case 10: + respawnRate = 200 | 400 << 16; + experience = 80.0; + rate = 0.70; + reward = 447; + level = 55; + break; + case 11: + respawnRate = 400 | 800 << 16; + experience = 95.0; + rate = 0.85; + reward = 449; + level = 70; + break; + case 12: + respawnRate = 1250 | 2500 << 16; + experience = 125.0; + rate = 0.95; + reward = 451; + level = 85; + break; + case 13: + respawnRate = 166 | 175 << 16; + experience = 65; + rate = 0.95; + reward = 1625; + level = 40; + break; + case 14: + respawnRate = 1 | 1 << 16; + experience = 5.0; + rate = 0.1; + reward = 1436; + level = 1; + break; + case 15: + respawnRate = 30 | 60 << 16; + experience = 30.0; + rate = 0.2; + reward = 6971; + level = 35; + break; + case 16: + respawnRate = 10 | 20 << 16; + experience = 50.0; + rate = 0.2; + reward = 6979; + level = 45; + break; + case 17: + respawnRate = 50 | 100 << 16; + experience = 17.5; + rate = 0.6; + reward = 12630; + level = 46; + break; + case 18: + respawnRate = 100 | 200 << 16; + experience = 0.0; + rate = 0.3; + reward = 4703; + level = 20; + break; + } + } + private static HashMap NODE_MAP = new HashMap<>(); + private static HashMap EMPTY_MAP = new HashMap<>(); + static{ + for(MiningNode node : MiningNode.values()){ + NODE_MAP.putIfAbsent(node.full,node); + } + for(MiningNode node : MiningNode.values()){ + EMPTY_MAP.putIfAbsent(node.empty,node.full); + } + } + + public static MiningNode forId(int id){ + return NODE_MAP.get(id); + } + + public static boolean isEmpty(int id){ + return EMPTY_MAP.get(id) != null; + } + + public int getRewardAmount() { + return 1; + } + + public int getEmptyId() { + return empty; + } + + public int getReward() { + return reward; + } + + public double getExperience() { + return experience; + } + + public int getRespawnRate() { + return respawnRate; + } + + public double getRate() { + return rate; + } + + public int getLevel() { + return level; + } + + public int getId() { + return full; + } + + public int getMinimumRespawn() { + return respawnRate & 0xFFFF; + } + + public int getMaximumRespawn() { + return (respawnRate >> 16) & 0xFFFF; + } + + public int getRespawnDuration() { + int minimum = respawnRate & 0xFFFF; + int maximum = (respawnRate >> 16) & 0xFFFF; + double playerRatio = (double) ServerConstants.MAX_PLAYERS / Repository.getPlayers().size(); + return (int) (minimum + ((maximum - minimum) / playerRatio)); + } +} diff --git a/Server/src/main/content/global/skill/gather/mining/MiningSkillPulse.kt b/Server/src/main/content/global/skill/gather/mining/MiningSkillPulse.kt new file mode 100644 index 0000000..5846467 --- /dev/null +++ b/Server/src/main/content/global/skill/gather/mining/MiningSkillPulse.kt @@ -0,0 +1,274 @@ +package content.global.skill.gather.mining + +import core.api.* +import core.game.event.ResourceProducedEvent +import core.cache.def.impl.ItemDefinition +import content.data.skill.SkillingPets +import core.game.node.Node +import core.game.node.entity.impl.Animator +import core.game.node.entity.npc.drop.DropFrequency +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.diary.DiaryType +import core.game.node.entity.skill.Skills +import content.data.skill.SkillingTool +import content.global.activity.shootingstar.StarBonus +import content.global.skill.skillcapeperks.SkillcapePerks +import core.game.node.item.ChanceItem +import core.game.node.scenery.Scenery +import core.game.node.scenery.SceneryBuilder +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.tools.RandomFunction +import org.rs09.consts.Items +import core.game.system.command.sets.STATS_BASE +import core.game.system.command.sets.STATS_ROCKS +import core.tools.prependArticle + +/** + * Mining skill pulse + * @author Ceikry + * @author bushtail -> maintenance July 2022 + */ +class MiningSkillPulse(private val player: Player, private val node: Node) : Pulse(1, player, node) { + private var resource: MiningNode? = null + private var isMiningEssence = false + private var isMiningGems = false + private var ticks = 0 + private var resetAnimation = true + + // Perfect Gold Ore in Witchhaven Dungeon (Family Crest) + private val perfectGoldOreLocations = listOf( + Location(2735, 9695, 0), + Location(2737, 9689, 0), + Location(2740, 9684, 0), + Location(2737, 9683, 0), + ) + + fun message(type: Int) { + if (type == 0) { + sendMessage(player, "You swing your pickaxe at the rock...") + } + } + + override fun pulse(): Boolean { + if (!checkRequirements()) { + return true + } + animate() + return reward() + } + + override fun stop() { + if (resetAnimation) { + animate(player, Animation(-1, Animator.Priority.HIGH)) + } + super.stop() + message(1) + } + + override fun start() { + resource = MiningNode.forId(node.id) + if (MiningNode.isEmpty(node.id)) { + sendMessage(player, "This rock contains no ore.") + } + if (resource == null) { + return + } + if (resource!!.id == 2099 && + !perfectGoldOreLocations.contains(node.location) ) { + // Perfect Gold Ore IDs outside Witchhaven are replaced with a normal gold rock. + resource = MiningNode.forId(2098) + } + if (resource!!.id == 2491) { + isMiningEssence = true + } + if (resource!!.identifier == MiningNode.GEM_ROCK_0.identifier) { + isMiningGems = true + } + if (checkRequirements()) { + super.start() + message(0) + } + } + + fun checkRequirements(): Boolean { + if (getDynLevel(player, Skills.MINING) < resource!!.level) { + sendMessage(player, "You need a mining level of ${resource!!.level} to mine this rock.") + return false + } + if (SkillingTool.getPickaxe(player) == null) { + sendMessage(player, "You do not have a pickaxe to use.") + return false + } + if (freeSlots(player) == 0) { + if(resource!!.identifier == 13.toByte()) { + sendDialogue(player,"Your inventory is too full to hold any more gems.") + return false + } + sendDialogue(player,"Your inventory is too full to hold any more ${ItemDefinition.forId(resource!!.reward).name.lowercase()}.") + return false + } + return true + } + + fun animate() { + animate(player, SkillingTool.getPickaxe(player).animation) + } + + fun reward(): Boolean { + if (++ticks % (if (isMiningEssence) 3 else 4) != 0) { + return false + } + if (!checkReward()) { + return false + } + + // Reward logic + var reward = resource!!.reward + var rewardAmount : Int + if (reward > 0) { + reward = calculateReward(reward) // calculate rewards + rewardAmount = calculateRewardAmount(reward) // calculate amount + + player.dispatch(ResourceProducedEvent(reward, rewardAmount, node)) + SkillingPets.checkPetDrop(player, SkillingPets.GOLEM) // roll for pet + + // Reward mining experience + val experience = resource!!.experience * rewardAmount + rewardXP(player, Skills.MINING, experience) + + // If player is wearing Bracelet of Clay, soften + if(reward == Items.CLAY_434){ + val bracelet = getItemFromEquipment(player, EquipmentSlot.HANDS) + if(bracelet != null && bracelet.id == Items.BRACELET_OF_CLAY_11074){ + var charges = player.getAttribute("jewellery-charges:bracelet-of-clay", 28) + charges-- + reward = Items.SOFT_CLAY_1761 + sendMessage(player, "Your bracelet of clay softens the clay for you.") + if(charges <= 0) { + if(removeItem(player, bracelet, Container.EQUIPMENT)) { + sendMessage(player, "Your bracelet of clay crumbles to dust.") + charges = 28 + } + } + player.setAttribute("/save:jewellery-charges:bracelet-of-clay", charges) + } + } + val rewardName = getItemName(reward).lowercase() + + // Send the message for the resource reward + if (isMiningGems) { + sendMessage(player, "You get ${prependArticle(rewardName)}.") + } else { + sendMessage(player, "You get some ${rewardName.lowercase()}.") + } + + // Give the mining reward, increment 'rocks mined' attribute + addItemOrDrop(player, reward, rewardAmount) + var rocksMined = getAttribute(player, "$STATS_BASE:$STATS_ROCKS", 0) + setAttribute(player, "/save:$STATS_BASE:$STATS_ROCKS", rocksMined + rewardAmount) + + // Calculate bonus gem chance while mining + if (!isMiningEssence) { + var chance = 282 + var altered = false + val ring = getItemFromEquipment(player, EquipmentSlot.RING) + if (ring != null && ring.name.lowercase().contains("ring of wealth") || inEquipment(player, Items.RING_OF_THE_STAR_SPRITE_14652)) { + chance = (chance / 1.5).toInt() + altered = true + } + val necklace = getItemFromEquipment(player, EquipmentSlot.NECK) + if (necklace != null && necklace.id in 1705..1713) { + chance = (chance / 1.5).toInt() + altered = true + } + if (RandomFunction.roll(chance)) { + val gem = GEM_REWARDS.random() + sendMessage(player,"You find a ${gem.name}!") + if (freeSlots(player) == 0) { + sendMessage(player,"You do not have enough space in your inventory, so you drop the gem on the floor.") + } + addItemOrDrop(player, gem.id) + } + } + + // Transform ore to depleted version + if (!isMiningEssence && resource!!.respawnRate != 0) { + SceneryBuilder.replace(node as Scenery, Scenery(resource!!.emptyId, node.getLocation(), node.type, node.rotation), resource!!.respawnDuration) + node.setActive(false) + return true + } + } + return false + } + + private fun calculateRewardAmount(reward: Int): Int { + var amount = 1 + + // If player is wearing Varrock armour from diary, roll chance at extra ore + if (!isMiningEssence && player.achievementDiaryManager.getDiary(DiaryType.VARROCK).level != -1) { + when (reward) { + Items.CLAY_434, Items.COPPER_ORE_436, Items.TIN_ORE_438, Items.LIMESTONE_3211, Items.BLURITE_ORE_668, Items.IRON_ORE_440, Items.ELEMENTAL_ORE_2892, Items.SILVER_ORE_442, Items.COAL_453 -> if (player.achievementDiaryManager.armour >= 0 && RandomFunction.random(100) <= 10) { + amount += 1 + sendMessage(player,"The Varrock armour allows you to mine an additional ore.") + } + Items.GOLD_ORE_444, Items.GRANITE_500G_6979, Items.GRANITE_2KG_6981, Items.GRANITE_5KG_6983, Items.MITHRIL_ORE_447 -> if (player.achievementDiaryManager.armour >= 1 && RandomFunction.random(100) <= 10) { + amount += 1 + sendMessage(player, "The Varrock armour allows you to mine an additional ore.") + } + Items.ADAMANTITE_ORE_449 -> if (player.achievementDiaryManager.armour >= 2 && RandomFunction.random(100) <= 10) { + amount += 1 + sendMessage(player, "The Varrock armour allows you to mine an additional ore.") + } + } + } + + // If player has mining boost from Shooting Star, roll chance at extra ore + if (hasTimerActive(player)) { + if (RandomFunction.getRandom(5) == 3) { + sendMessage(player, "...you manage to mine a second ore thanks to the Star Sprite.") + amount += 1 + } + } + return amount + } + + private fun calculateReward(reward: Int): Int { + // If the player is mining sandstone or granite, then get size of sandstone/granite and xp reward for that size + var reward = reward + if (resource == MiningNode.SANDSTONE || resource == MiningNode.GRANITE) { + val value = RandomFunction.randomize(if (resource == MiningNode.GRANITE) 3 else 4) + reward += value shl 1 + rewardXP(player, Skills.MINING, value * 10.toDouble()) + } else if (isMiningEssence && getDynLevel(player, Skills.MINING) >= 30) { + reward = 7936 + } else if (isMiningGems) { + reward = RandomFunction.rollWeightedChanceTable(MiningNode.gemRockGems).id + } + return reward + } + + /** + * Checks if the player gets rewarded. + * @return `True` if so. + */ + private fun checkReward(): Boolean { + val level = 1 + getDynLevel(player, Skills.MINING) + getFamiliarBoost(player, Skills.MINING) + val hostRatio = Math.random() * (100.0 * resource!!.rate) + var toolRatio = SkillingTool.getPickaxe(player).ratio + if(SkillcapePerks.isActive(SkillcapePerks.PRECISION_MINER,player)){ + toolRatio += 0.075 + } + val clientRatio = Math.random() * ((level - resource!!.level) * (1.0 + toolRatio)) + return hostRatio < clientRatio + } + + companion object { + private val GEM_REWARDS = arrayOf(ChanceItem(1623, 1, DropFrequency.COMMON), ChanceItem(1621, 1, DropFrequency.COMMON), ChanceItem(1619, 1, DropFrequency.UNCOMMON), ChanceItem(1617, 1, DropFrequency.RARE)) + } + + init { + super.stop() + } +} diff --git a/Server/src/main/content/global/skill/gather/mining/ProspectListener.kt b/Server/src/main/content/global/skill/gather/mining/ProspectListener.kt new file mode 100644 index 0000000..13ec9b0 --- /dev/null +++ b/Server/src/main/content/global/skill/gather/mining/ProspectListener.kt @@ -0,0 +1,52 @@ +package content.global.skill.gather.mining + +import core.api.* +import content.global.skill.gather.mining.MiningNode +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +/** + * @author: bushtail + */ + +class ProspectListener : InteractionListener { + + override fun defineListeners() { + on(IntType.SCENERY, "prospect") { player, node -> + val rock = MiningNode.forId(node.asScenery().id) + + if(rock == null) { + sendMessage(player, "There is no ore currently available in this rock.") + return@on true + } + + /** Check if the rock contains gems */ + if(MiningNode.forId(node.id).identifier == 13.toByte()) { + sendMessage(player,"You examine the rock for ores...") + /** Send a simple text string saying it's a gem rock */ + player.pulseManager.run(object : Pulse(3) { + override fun pulse(): Boolean { + sendMessage(player, "This rock contains gems.") + return true + } + }) + return@on true + } + + /** If it doesn't contain gems */ + else { + sendMessage(player,"You examine the rock for ores...") + /** Get the name of the rock's reward and sends a message to the player */ + player.pulseManager.run(object : Pulse(3) { + override fun pulse(): Boolean { + sendMessage(player, "This rock contains ${Item(rock.reward).name.lowercase()}.") + return true + } + }) + } + return@on true + } + } +} diff --git a/Server/src/main/content/global/skill/gather/woodcutting/WoodcuttingListener.kt b/Server/src/main/content/global/skill/gather/woodcutting/WoodcuttingListener.kt new file mode 100644 index 0000000..c73b135 --- /dev/null +++ b/Server/src/main/content/global/skill/gather/woodcutting/WoodcuttingListener.kt @@ -0,0 +1,276 @@ +package content.global.skill.gather.woodcutting + +import content.data.skill.SkillingPets +import content.data.skill.SkillingTool +import content.data.tables.BirdNest +import content.global.skill.farming.FarmingPatch.Companion.forObject +import content.global.skill.firemaking.Log +import content.global.skill.skillcapeperks.SkillcapePerks +import content.global.skill.skillcapeperks.SkillcapePerks.Companion.isActive +import content.region.misc.miscellania.dialogue.KjallakOnChopDialogue +import core.api.* +import core.cache.def.impl.ItemDefinition +import core.game.container.impl.EquipmentContainer +import core.game.event.ResourceProducedEvent +import core.game.interaction.Clocks +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength +import core.game.node.Node +import core.game.node.entity.impl.Projectile +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.diary.DiaryType +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.node.scenery.Scenery +import core.game.node.scenery.SceneryBuilder +import core.game.system.command.sets.STATS_BASE +import core.game.system.command.sets.STATS_LOGS +import core.game.world.map.RegionManager +import core.tools.RandomFunction +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Sounds +import org.rs09.consts.Sounds.TREE_FALLING_2734 +import java.util.* +import kotlin.streams.toList + +class WoodcuttingListener : InteractionListener { + private val woodcuttingSounds = intArrayOf( + Sounds.WOODCUTTING_HIT_3038, + Sounds.WOODCUTTING_HIT_3039, + Sounds.WOODCUTTING_HIT_3040, + Sounds.WOODCUTTING_HIT_3041, + Sounds.WOODCUTTING_HIT_3042 + ) + + override fun defineListeners() { + defineInteraction( + IntType.SCENERY, + ids = WoodcuttingNode.values().map { it.id }.toIntArray(), + "chop-down", "chop", "chop down", "cut down", + persistent = true, + allowedDistance = 1, + handler = ::handleWoodcutting + ) + } + + private fun handleWoodcutting(player: Player, node: Node, state: Int) : Boolean { + val resource = WoodcuttingNode.forId(node.id) + val tool = SkillingTool.getHatchet(player) + + if (!finishedMoving(player)) + return restartScript(player) + + if (state == 0) { + if (!checkWoodcuttingRequirements(player, resource, node)) { + return clearScripts(player) + } + sendMessage(player, "You swing your axe at the tree...") + } + + if (clockReady(player, Clocks.SKILLING)) { + animateWoodcutting(player) + if (!checkReward(player, resource, tool)) + return delayClock(player, Clocks.SKILLING, 3) + + val reward = resource.getReward() + val rewardAmount: Int + + if (tool.id == Items.INFERNO_ADZE_13661 && reward != Items.BARK_3239 && RandomFunction.roll(4)) { + sendMessage(player, "You chop some logs. The heat of the inferno adze incinerates them.") + Projectile.create( + player, null, + 1776, + 35, 30, + 20, 25 + ).transform( + player, + player.location.transform(2, 0, 0), + true, + 25, 25 + ).send() + + //add woodcutting experience + player.getSkills().addExperience(Skills.WOODCUTTING, resource.getExperience()) + + //nullcheck the fire, and only if it exists award the firemaking XP + val fire = Log.forId(reward) + if (fire != null) { + player.getSkills().addExperience(Skills.FIREMAKING, fire.getXp()) + } + + delayClock(player, Clocks.SKILLING, 3) + return rollDepletion(player, node.asScenery(), resource) + } + + if (reward > 0) { + rewardAmount = calculateRewardAmount(player, reward) // calculate amount + SkillingPets.checkPetDrop(player, SkillingPets.BEAVER) // roll for pet + + //add experience + val experience: Double = calculateExperience(player, resource, rewardAmount) + player.getSkills().addExperience(Skills.WOODCUTTING, experience, true) + + //send the message for the resource reward + if (resource == WoodcuttingNode.DRAMEN_TREE) { + player.packetDispatch.sendMessage("You cut a branch from the Dramen tree.") + } else if (reward == Items.BARK_3239 && rewardAmount == 0) { + player.packetDispatch.sendMessage("You chop away some bark, but it falls to pieces before you can pick it up.") + } else { + player.packetDispatch.sendMessage("You get some " + ItemDefinition.forId(reward).name.lowercase(Locale.getDefault()) + ".") + } + + //give the reward + player.inventory.add(Item(reward, rewardAmount)) + player.dispatch(ResourceProducedEvent(reward, rewardAmount, node, -1)) + var cutLogs = player.getAttribute("$STATS_BASE:$STATS_LOGS", 0) + player.setAttribute("/save:$STATS_BASE:$STATS_LOGS", ++cutLogs) + + //calculate bonus bird nest for mining + val chance = 282 + if (RandomFunction.random(chance) == chance / 2) { + if (isActive(SkillcapePerks.NEST_HUNTER, player)) { + if (!player.inventory.add(BirdNest.getRandomNest(false).nest)) { + BirdNest.drop(player) + } + } else { + BirdNest.drop(player) + } + } + } + + delayClock(player, Clocks.SKILLING, 3) + rollDepletion(player, node.asScenery(), resource) + if (!checkWoodcuttingRequirements(player, resource, node)) { + return clearScripts(player) + } + } + return keepRunning(player) + } + + private fun rollDepletion(player: Player, node: Scenery, resource: WoodcuttingNode): Boolean { + //transform to depleted version + //OSRS and RS3 Wikis both agree: All trees present in 2009 are a 1/8 fell chance, aside from normal trees/dead trees which are 100% + //OSRS: https://oldschool.runescape.wiki/w/Woodcutting scroll down to the mechanics section + //RS3 : https://runescape.wiki/w/Woodcutting scroll down to the mechanics section, and expand the tree felling chances table + if (resource.getRespawnRate() > 0) { + if (RandomFunction.roll(8) || listOf(1, 2, 3, 4, 6).contains(resource.identifier.toInt())){ + if (resource.isFarming()) { + val fPatch = forObject(node.asScenery()) + if (fPatch != null) { + val patch = fPatch.getPatchFor(player) + patch.setCurrentState(patch.getCurrentState() + 1) + node.isActive = false + playAudio(player, TREE_FALLING_2734) + queueScript(player, 2, QueueStrength.SOFT) { + node.isActive = true + return@queueScript stopExecuting(player) + } + } + return true + } + if (resource.getEmptyId() > -1) { + SceneryBuilder.replace(node, node.transform(resource.getEmptyId()), resource.getRespawnDuration()) + } else { + SceneryBuilder.replace(node, node.transform(0), resource.getRespawnDuration()) + } + node.setActive(false) + playAudio(player, TREE_FALLING_2734) + return true + } + } + return false + } + + private fun checkReward(player: Player, resource: WoodcuttingNode, tool: SkillingTool): Boolean { + val skill = Skills.WOODCUTTING + val level: Int = player.getSkills().getLevel(skill) + player.getFamiliarManager().getBoost(skill) + val hostRatio = RandomFunction.randomDouble(100.0) + val lowMod: Double = if (tool == SkillingTool.BLACK_AXE) resource.tierModLow / 2 else resource.tierModLow + val low: Double = resource.baseLow + tool.ordinal * lowMod + val highMod: Double = if (tool == SkillingTool.BLACK_AXE) resource.tierModHigh / 2 else resource.tierModHigh + val high: Double = resource.baseHigh + tool.ordinal * highMod + val clientRatio = RandomFunction.getSkillSuccessChance(low, high, level) + return hostRatio < clientRatio + } + + fun animateWoodcutting(player: Player) { + if (!player.animator.isAnimating) { + player.animate(SkillingTool.getHatchet(player).animation) + val playersAroundMe: List = RegionManager.getLocalPlayers(player, 2) + .stream() + .filter { p: Player -> p.username != player.username } + .toList() + val soundIndex = RandomFunction.random(0, woodcuttingSounds.size) + + for (p in playersAroundMe) { + playAudio(p, woodcuttingSounds[soundIndex]) + } + } + } + + fun checkWoodcuttingRequirements(player: Player, resource: WoodcuttingNode, node: Node): Boolean { + var regionId = player.location.regionId + if (regionId == 10300 || regionId == 10044) { //miscellania then etceteria, respectively. + var npc = if (regionId == 10300) NPCs.CARPENTER_KJALLAK_3916 else NPCs.LUMBERJACK_LEIF_1395 + openDialogue(player, KjallakOnChopDialogue(), NPC(npc, player.location)) + return false + } + if (player.getSkills().getLevel(Skills.WOODCUTTING) < resource.getLevel()) { + player.getPacketDispatch().sendMessage("You need a woodcutting level of " + resource.getLevel() + " to chop this tree.") + return false + } + if (SkillingTool.getHatchet(player) == null) { + player.packetDispatch.sendMessage("You do not have an axe to use.") + return false + } + if (player.inventory.freeSlots() < 1 && node.isActive) { + player.sendMessage("Your inventory is too full to hold any more " + ItemDefinition.forId(resource.getReward()).name.lowercase(Locale.getDefault()) + ".") + return false + } + return node.isActive + } + + + private fun calculateRewardAmount(player: Player, reward: Int): Int { + var amount = 1 + + // 3239: Hollow tree (bark) 10% chance of obtaining + if (reward == 3239 && RandomFunction.random(100) >= 10) { + amount = 0 + } + + // Seers village medium reward - extra normal log while in seer's village + if (reward == 1511 && player.getAchievementDiaryManager().getDiary(DiaryType.SEERS_VILLAGE).isComplete(1) && player.getViewport().getRegion().getId() == 10806) { + amount = 2 + } + return amount + } + + private fun calculateExperience(player: Player, resource: WoodcuttingNode, amount: Int): Double { + var amount = amount + var experience: Double = resource.getExperience() + val reward = resource.reward + if (player.getLocation().getRegionId() == 10300) { + return 1.0 + } + + // Bark + if (reward == Items.BARK_3239) { + // If we receive the item, give the experience points + if (amount >= 1) { + experience = 82.5 + } else { + return 0.0 + } + } + + // Seers village medium reward - extra 10% xp from maples while wearing headband + if (reward == 1517 && player.getAchievementDiaryManager().getDiary(DiaryType.SEERS_VILLAGE).isComplete(1) && player.getEquipment().get(EquipmentContainer.SLOT_HAT) != null && player.getEquipment().get(EquipmentContainer.SLOT_HAT).getId() == 14631) { + experience *= 1.10 + } + return experience * amount + } +} diff --git a/Server/src/main/content/global/skill/gather/woodcutting/WoodcuttingNode.java b/Server/src/main/content/global/skill/gather/woodcutting/WoodcuttingNode.java new file mode 100644 index 0000000..ea769da --- /dev/null +++ b/Server/src/main/content/global/skill/gather/woodcutting/WoodcuttingNode.java @@ -0,0 +1,471 @@ +package content.global.skill.gather.woodcutting; + +import core.ServerConstants; +import core.game.world.repository.Repository; + +import java.util.HashMap; + +/** + * Woodcutting nodes + * @author ceik + */ +public enum WoodcuttingNode { + //standard trees + STANDARD_TREE_1( 1276, 1342, (byte) 1), + STANDARD_TREE_2( 1277, 1343, (byte) 1), + STANDARD_TREE_3( 1278, 1342, (byte) 1), + STANDARD_TREE_4( 1279, 1345, (byte) 1), + STANDARD_TREE_5( 1280, 1343, (byte) 1), + STANDARD_TREE_6( 1330, 1341, (byte) 1), + STANDARD_TREE_7( 1331, 1341, (byte) 1), + STANDARD_TREE_8( 1332, 1341, (byte) 1), + STANDARD_TREE_9( 2409, 1342, (byte) 1), + STANDARD_TREE_10(3033, 1345, (byte) 1), + STANDARD_TREE_11(3034, 1345, (byte) 1), + STANDARD_TREE_12(3035, 1347, (byte) 1), + STANDARD_TREE_13(3036, 1351, (byte) 1), + STANDARD_TREE_14(3879, 3880, (byte) 1), + STANDARD_TREE_15(3881, 3880, (byte) 1), + STANDARD_TREE_16(3882, 3880, (byte) 1), + STANDARD_TREE_17(3883, 3884, (byte) 1), + STANDARD_TREE_18(10041,1342, (byte) 1), + STANDARD_TREE_19(14308,1342, (byte) 1), + STANDARD_TREE_20(14309,1342, (byte) 1), + STANDARD_TREE_21(16264,1342, (byte) 1), + STANDARD_TREE_22(16265,1342, (byte) 1), + STANDARD_TREE_23(30132,1342, (byte) 1), + STANDARD_TREE_24(30133,1342, (byte) 1), + STANDARD_TREE_25(37477,1342, (byte) 1), + STANDARD_TREE_26(37478,37653, (byte) 1), + STANDARD_TREE_27(37652,37653, (byte) 1), + + //Dead trees + DEAD_TREE_1( 1282, 1347, (byte) 2), + DEAD_TREE_2( 1283, 1347, (byte) 2), + DEAD_TREE_3( 1284, 1348, (byte) 2), + DEAD_TREE_4( 1285, 1349, (byte) 2), + DEAD_TREE_5( 1286, 1351, (byte) 2), + DEAD_TREE_6( 1289, 1353, (byte) 2), + DEAD_TREE_7( 1290, 1354, (byte) 2), + DEAD_TREE_8( 1291, 23054, (byte) 2), + DEAD_TREE_9( 1365, 1352, (byte) 2), + DEAD_TREE_10(1383, 1358, (byte) 2), + DEAD_TREE_11(1384, 1359, (byte) 2), + DEAD_TREE_12(5902, 1347, (byte) 2), + DEAD_TREE_13(5903, 1353, (byte) 2), + DEAD_TREE_14(5904, 1353, (byte) 2), + DEAD_TREE_15(32294,1353, (byte) 2), + DEAD_TREE_16(37481,1347, (byte) 2), + DEAD_TREE_17(37482,1351, (byte) 2), + DEAD_TREE_18(37483,1358, (byte) 2), + DEAD_TREE_19(24168,24169, (byte) 2), + + //Evergreen + EVERGREEN_1(1315,1342,(byte) 3), + EVERGREEN_2(1316,1355,(byte) 3), + EVERGREEN_3(1318,1355,(byte) 3), + EVERGREEN_4(1319,1355,(byte) 3), + + //Jungle stuff + JUNGLE_TREE_1(2887,0, (byte) 4), + JUNGLE_TREE_2(2889,0, (byte) 4), + JUNGLE_TREE_3(2890,0, (byte) 4), + JUNGLE_TREE_4(4818,0, (byte) 4), + JUNGLE_TREE_5(4820,0, (byte) 4), + + JUNGLE_BUSH_1(2892,2894, (byte) 5), + JUNGLE_BUSH_2(2893,2895, (byte) 5), + + //Achey + ACHEY_TREE(2023,3371, (byte) 6), + + //Oak + OAK_TREE_1(1281, 1356, (byte) 7), + OAK_TREE_2(3037, 1357, (byte) 7), + OAK_TREE_3(37479,1356, (byte) 7), + OAK_TREE_4(8467, 1356, (byte) 19, true), + + //Willow + WILLOW_TREE_1(1308, 7399, (byte) 8), + WILLOW_TREE_2(5551, 5554, (byte) 8), + WILLOW_TREE_3(5552, 5554, (byte) 8), + WILLOW_TREE_4(5553, 5554, (byte) 8), + WILLOW_TREE_5(37480,7399, (byte) 8), + WILLOW_TREE_6(8488,7399, (byte) 20, true), + + //Teak + TEAK_1(9036, 9037, (byte) 9), + TEAK_2(15062,9037, (byte) 9), + + //Maple + MAPLE_TREE_1(1307,7400, (byte) 10), + MAPLE_TREE_2(4674,7400, (byte) 10), + MAPLE_TREE_3(8444,7400, (byte) 21, true), + + //Hollow + HOLLOW_TREE_1(2289,2310, (byte) 11), + HOLLOW_TREE_2(4060,4061, (byte) 11), + + //Mahogany + MAHOGANY(9034,9035, (byte) 12), + + //Swaying Tree + SWAYING_TREE(4142,-1, (byte) 30), + + //Arctic pine + ARCTIC_PINE(21273,21274, (byte) 13), + + //Eucalyptus + EUCALYPTUS_1(28951,28954, (byte) 14), + EUCALYPTUS_2(28952,28955, (byte) 14), + EUCALYPTUS_3(28953,28956, (byte) 14), + + //Yew + YEW(1309,7402, (byte) 15), + YEW_1(8513,7402,(byte) 22, true), + + //Magic + MAGIC_TREE_1(1306, 7401, (byte) 16), + MAGIC_TREE_2(37823,37824, (byte) 16), + MAGIC_TREE_3(8409, 37824, (byte) 23, true), + + //Cursed Magic + CURSED_MAGIC_TREE(37821,37822, (byte) 17), + + //Dramen + DRAMEN_TREE(1292, -1, (byte) 18); + + + + int full,empty,reward,respawnRate,level, rewardAmount; + double experience,rate; + public byte identifier; + boolean farming; + public double baseLow = 2; + public double baseHigh = 6; + public double tierModLow = 1; + public double tierModHigh = 3; + WoodcuttingNode(int full, int empty,byte identifier){ + this.full = full; + this.empty = empty; + this.identifier = identifier; + this.farming = false; + this.rewardAmount = 1; + switch(identifier & 0xFF){ + case 1: + case 2: + case 3: + case 4: + reward = 1511; + respawnRate = 50 | 100 << 16; + rate = 0.05; + experience = 25.0; + level = 1; + baseLow = 64; + baseHigh = 200; + tierModLow = 32; + tierModHigh = 100; + break; + case 5: + reward = 1511; + respawnRate = 50 | 100 << 16; + rate = 0.15; + experience = 100; + level = 1; + this.rewardAmount = 2; + baseLow = 64; + baseHigh = 200; + tierModLow = 32; + tierModHigh = 100; + break; + case 6: + reward = 2862; + respawnRate = 50 | 100 << 16; + rate = 0.05; + experience = 25.0; + level = 1; + baseLow = 64; + baseHigh = 200; + tierModLow = 32; + tierModHigh = 100; + break; + case 7: + reward = 1521; + respawnRate = 14 | 22 << 16; + rate = 0.15; + experience = 37.5; + level = 15; + rewardAmount = 10; + baseLow = 32; + baseHigh = 100; + tierModLow = 16; + tierModHigh = 50; + break; + case 8: + reward = 1519; + respawnRate = 14 | 22 << 16; + rate = 0.3; + experience = 67.8; + level = 30; + rewardAmount = 20; + baseLow = 16; + baseHigh = 50; + tierModLow = 8; + tierModHigh = 25; + break; + case 9: + reward = 6333; + respawnRate = 35 | 60 << 16; + rate = 0.7; + experience = 85.0; + level = 35; + rewardAmount = 25; + baseLow = 15; + baseHigh = 46; + tierModLow = 8; + tierModHigh = 23.5; + break; + case 10: + reward = 1517; + respawnRate = 58 | 100 << 16; + rate = 0.65; + experience = 100.0; + level = 45; + rewardAmount = 30; + baseLow = 8; + baseHigh = 25; + tierModLow = 4; + tierModHigh = 12.5; + break; + case 11: + reward = 3239; + respawnRate = 58 | 100 << 16; + rate = 0.6; + experience = 82.5; + level = 45; + rewardAmount = 30; + baseLow = 18; + baseHigh = 26; + tierModLow = 10; + tierModHigh = 14; + break; + case 12: + reward = 6332; + respawnRate = 62 | 115 << 16; + rate = 0.7; + experience = 125.0; + level = 50; + rewardAmount = 35; + baseLow = 8; + baseHigh = 25; + tierModLow = 4; + tierModHigh = 12.5; + break; + case 13: + reward = 10810; + respawnRate = 75 | 130 << 16; + rate = 0.73; + experience = 40.0; + level = 54; + rewardAmount = 35; + baseLow = 6; + baseHigh = 30; + tierModLow = 3; + tierModHigh = 13.5; + break; + case 14: + reward = 12581; + respawnRate = 80 | 140 << 16; + rate = 0.77; + experience = 165.0; + level = 58; + rewardAmount = 35; + break; + case 15: + reward = 1515; + respawnRate = 100 | 162 << 16; + rate = 0.8; + experience = 175.0; + level = 60; + rewardAmount = 40; + baseLow = 4; + baseHigh = 12.5; + tierModLow = 2; + tierModHigh = 6.25; + break; + case 16: + reward = 1513; + respawnRate = 200 | 317 << 16; + rate = 0.9; + experience = 250.0; + level = 75; + rewardAmount = 50; + baseLow = 2; + baseHigh = 6; + tierModLow = 1; + tierModHigh = 3; + break; + case 17: + reward = 1513; + respawnRate = 200 | 317 << 16; + rate = 0.95; + experience = 275.0; + level = 82; + rewardAmount = 50; + break; + case 18: + reward = 771; + respawnRate = -1; + rate = 0.05; + experience = 25.0; + level = 36; + rewardAmount = Integer.MAX_VALUE; + baseLow = 255; + baseHigh = 255; + tierModLow = 0; + tierModHigh = 0; + break; + case 30: + reward = 3692; + respawnRate = -1; + rate = 0.05; + experience = 1; + level = 40; + rewardAmount = Integer.MAX_VALUE; + break; + } + } + WoodcuttingNode(int full, int empty, byte identifier, boolean farming){ + this.full = full; + this.empty = empty; + this.identifier = identifier; + this.farming = farming; + switch(identifier & 0xFF){ + case 19: + reward = 1521; + respawnRate = 14 | 22 << 16; + rate = 0.15; + experience = 37.5; + level = 15; + rewardAmount = 10; + baseLow = 32; + baseHigh = 100; + tierModLow = 16; + tierModHigh = 50; + break; + case 20: + reward = 1519; + respawnRate = 14 | 22 << 16; + rate = 0.3; + experience = 67.8; + level = 30; + rewardAmount = 20; + baseLow = 16; + baseHigh = 50; + tierModLow = 8; + tierModHigh = 25; + break; + case 21: + reward = 1517; + respawnRate = 58 | 100 << 16; + rate = 0.65; + experience = 100.0; + level = 45; + rewardAmount = 30; + baseLow = 8; + baseHigh = 25; + tierModLow = 4; + tierModHigh = 12.5; + break; + case 22: + reward = 1515; + respawnRate = 100 | 162 << 16; + rate = 0.8; + experience = 175.0; + level = 60; + rewardAmount = 40; + baseLow = 4; + baseHigh = 12.5; + tierModLow = 2; + tierModHigh = 6.25; + break; + case 23: + reward = 1513; + respawnRate = 200 | 317 << 16; + rate = 0.9; + experience = 250.0; + level = 75; + rewardAmount = 50; + baseLow = 2; + baseHigh = 6; + tierModLow = 1; + tierModHigh = 3; + break; + } + } + private static HashMap NODE_MAP = new HashMap<>(); + private static HashMap EMPTY_MAP = new HashMap<>(); + static{ + for(WoodcuttingNode node : WoodcuttingNode.values()){ + NODE_MAP.putIfAbsent(node.full,node); + EMPTY_MAP.putIfAbsent(node.empty,node.full); + } + } + + public static WoodcuttingNode forId(int id){ + return NODE_MAP.get(id); + } + + public static boolean isEmpty(int id){ + return EMPTY_MAP.get(id) != null; + } + + public int getRewardAmount() { + return rewardAmount; + } + + public int getEmptyId() { + return empty; + } + + public int getReward() { + return reward; + } + + public double getExperience() { + return experience; + } + + public int getRespawnRate() { + return respawnRate; + } + + public double getRate() { + return rate; + } + + public int getLevel() { + return level; + } + + public int getId() { + return full; + } + + public int getMinimumRespawn() { + return respawnRate & 0xFFFF; + } + + public int getMaximumRespawn() { + return (respawnRate >> 16) & 0xFFFF; + } + + public boolean isFarming(){ return farming;} + + public int getRespawnDuration() { + int minimum = respawnRate & 0xFFFF; + int maximum = (respawnRate >> 16) & 0xFFFF; + double playerRatio = (double) ServerConstants.MAX_PLAYERS / Repository.getPlayers().size(); + return (int) (minimum + ((maximum - minimum) / playerRatio)); + } +} diff --git a/Server/src/main/content/global/skill/gather/woodcutting/WoodcuttingSkillPulse.java b/Server/src/main/content/global/skill/gather/woodcutting/WoodcuttingSkillPulse.java new file mode 100644 index 0000000..bdb54f1 --- /dev/null +++ b/Server/src/main/content/global/skill/gather/woodcutting/WoodcuttingSkillPulse.java @@ -0,0 +1,292 @@ +package content.global.skill.gather.woodcutting; + +import content.data.tables.BirdNest; +import content.global.skill.farming.FarmingPatch; +import content.global.skill.farming.Patch; +import content.global.skill.skillcapeperks.SkillcapePerks; +import core.game.event.ResourceProducedEvent; +import core.cache.def.impl.ItemDefinition; +import core.game.container.impl.EquipmentContainer; +import core.game.dialogue.FacialExpression; +import content.data.skill.SkillingPets; +import core.game.node.entity.impl.Animator; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.audio.Audio; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.entity.skill.Skills; +import content.data.skill.SkillingTool; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import core.tools.RandomFunction; +import org.rs09.consts.Sounds; + +import java.util.List; +import java.util.stream.Collectors; + +import static core.api.ContentAPIKt.playAudio; +import static core.game.system.command.sets.StatAttributeKeysKt.STATS_BASE; +import static core.game.system.command.sets.StatAttributeKeysKt.STATS_LOGS; + +/** + * Woodcutting skill pulse + * + * @author ceik + */ +public class WoodcuttingSkillPulse extends Pulse { + private int[] woodcuttingSounds = { + Sounds.WOODCUTTING_HIT_3038, + Sounds.WOODCUTTING_HIT_3039, + Sounds.WOODCUTTING_HIT_3040, + Sounds.WOODCUTTING_HIT_3041, + Sounds.WOODCUTTING_HIT_3042 + }; + + private WoodcuttingNode resource; + private int ticks; + private Player player; + private Scenery node; + protected boolean resetAnimation = true; + + + public WoodcuttingSkillPulse(Player player, Scenery node) { + super(1, player, node); + this.player = player; + this.node = node; + super.stop(); + } + + public void message(int type) { + if (type == 0) { + player.getPacketDispatch().sendMessage("You swing your axe at the tree..."); + } + } + + @Override + public boolean pulse() { + if (!checkRequirements()) { + return true; + } + animate(); + return reward(); + } + + @Override + public void stop() { + if (resetAnimation) { + player.animate(new Animation(-1, Animator.Priority.HIGH)); + } + super.stop(); + message(1); + } + + @Override + public void start() { + resource = WoodcuttingNode.forId(node.getId()); + if (resource == null) { + return; + } + if (checkRequirements()) { + super.start(); + message(0); + } + } + + public boolean checkRequirements() { + if (player.getSkills().getLevel(Skills.WOODCUTTING) < resource.getLevel()) { + player.getPacketDispatch().sendMessage("You need a woodcutting level of " + resource.getLevel() + " to chop this tree."); + return false; + } + if (SkillingTool.getHatchet(player) == null) { + player.getPacketDispatch().sendMessage("You do not have an axe to use."); + return false; + } + if (player.getInventory().freeSlots() < 1) { + player.getDialogueInterpreter().sendDialogue("Your inventory is too full to hold any more " + ItemDefinition.forId(resource.getReward()).getName().toLowerCase() + "."); + return false; + } + return true; + } + + public void animate() { + if(!player.getAnimator().isAnimating()) { + player.animate(SkillingTool.getHatchet(player).getAnimation()); + + List playersAroundMe = RegionManager.getLocalPlayers(player, 2) + .stream() + .filter(p -> !p.getUsername().equals(player.getUsername())) + .collect(Collectors.toList()); + + int soundIndex = RandomFunction.random(0, woodcuttingSounds.length); + + for (Player p : playersAroundMe) { + playAudio(p, woodcuttingSounds[soundIndex]); + } + } + } + + public boolean reward() { + if (++ticks % 4 != 0) { + return false; + } + if (node.getId() == 10041) { + player.getDialogueInterpreter().sendDialogues(2574, FacialExpression.FURIOUS, RandomFunction.random(2) == 1 ? "You'll blow my cover! I'm meant to be hidden!" : "Will you stop that?"); + return true; + } + if (!checkReward(SkillingTool.getHatchet(player))) { + return false; + } + + // 20% chance to auto burn logs when using "inferno adze" item + if (SkillingTool.getHatchet(player).getId() == 13661 && RandomFunction.random(100) < 25) { + player.sendMessage("You chop some logs. The heat of the inferno adze incinerates them."); + Projectile.create(player, null, 1776, 35, 30, 20, 25).transform(player, new Location(player.getLocation().getX() + 2, player.getLocation().getY()), true, 25, 25).send(); + player.getSkills().addExperience(Skills.WOODCUTTING, resource.getExperience()); + player.getSkills().addExperience(Skills.FIREMAKING, resource.getExperience()); + return rollDepletion(); + } + + //actual reward calculations + int reward = resource.getReward(); + int rewardAmount = 0; + if (reward > 0) { + reward = calculateReward(reward); // calculate rewards + rewardAmount = calculateRewardAmount(reward); // calculate amount + SkillingPets.checkPetDrop(player, SkillingPets.BEAVER); // roll for pet + + //add experience + double experience = calculateExperience(resource.reward, rewardAmount); + + player.getSkills().addExperience(Skills.WOODCUTTING, experience, true); + + //send the message for the resource reward, and in the case of the dramen tree, authentically abort the chopping action + if (resource == WoodcuttingNode.DRAMEN_TREE) { + player.getPacketDispatch().sendMessage("You cut a branch from the Dramen tree."); + stop(); + } else { + player.getPacketDispatch().sendMessage("You get some " + ItemDefinition.forId(reward).getName().toLowerCase() + "."); + } + //give the reward + player.getInventory().add(new Item(reward, rewardAmount)); + player.dispatch(new ResourceProducedEvent(reward, rewardAmount, node, -1)); + int cutLogs = player.getAttribute(STATS_BASE + ":" + STATS_LOGS,0); + player.setAttribute("/save:" + STATS_BASE + ":" + STATS_LOGS,++cutLogs); + + //calculate bonus bird nest for mining + int chance = 282; + if (RandomFunction.random(chance) == chance / 2) { + if(SkillcapePerks.isActive(SkillcapePerks.NEST_HUNTER,player)){ + if(!player.getInventory().add(BirdNest.getRandomNest(false).getNest())){ + BirdNest.drop(player); + } + } else { + BirdNest.drop(player); + } + } + + } + + return rollDepletion(); + } + + private boolean rollDepletion() { + //transform to depleted version + //OSRS and RS3 Wikis both agree: All trees present in 2009 are a 1/8 fell chance, aside from normal trees/dead trees which are 100% + //OSRS: https://oldschool.runescape.wiki/w/Woodcutting scroll down to the mechanics section + //RS3 : https://runescape.wiki/w/Woodcutting scroll down to the mechanics section, and expand the tree felling chances table + if (resource.getRespawnRate() > 0) { + if (RandomFunction.roll(8) || resource.identifier == 1 || resource.identifier == 2 || resource.identifier == 3 || resource.identifier == 6) { + if (resource.isFarming()) { + FarmingPatch fPatch = FarmingPatch.forObject(node.asScenery()); + if(fPatch != null) { + Patch patch = fPatch.getPatchFor(player, true); + patch.setCurrentState(patch.getCurrentState() + 1); + } + return true; + } + if (resource.getEmptyId() > -1) { + SceneryBuilder.replace(node, node.transform(resource.getEmptyId()), resource.getRespawnDuration()); + } else { + SceneryBuilder.replace(node, node.transform(0), resource.getRespawnDuration()); + } + node.setActive(false); + + playAudio(player, Sounds.TREE_FALLING_2734); + return true; + } + } + return false; + } + + private int calculateRewardAmount(int reward) { + int amount = 1; + + // 3239: Hollow tree (bark) 10% chance of obtaining + if (reward == 3239 && RandomFunction.random(100) >= 10) { + amount = 0; + } + + // Seers village medium reward - extra normal log while in seer's village + if (reward == 1511 + && player.getAchievementDiaryManager().getDiary(DiaryType.SEERS_VILLAGE).isComplete(1) + && player.getViewport().getRegion().getId() == 10806) { + amount = 2; + } + + return amount; + } + + private double calculateExperience(int reward, int amount) { + double experience = resource.getExperience(); + + if(player.getLocation().getRegionId() == 10300){ + return 1.0; + } + + // Bark + if (reward == 3239) { + // If we receive the item, give the full experience points otherwise give the base amount + if (amount >= 1) { + experience = 275.2; + } else { + amount = 1; + } + } + + // Seers village medium reward - extra 10% xp from maples while wearing headband + if (reward == 1517 + && player.getAchievementDiaryManager().getDiary(DiaryType.SEERS_VILLAGE).isComplete(1) + && player.getEquipment().get(EquipmentContainer.SLOT_HAT) != null + && player.getEquipment().get(EquipmentContainer.SLOT_HAT).getId() == 14631) { + experience *= 1.10; + } + + return experience * amount; + } + + private int calculateReward(int reward) { + return reward; + } + + /** + * Checks if the player gets rewarded. + * + * @return {@code True} if so. + */ + private boolean checkReward(SkillingTool tool) { + int skill = Skills.WOODCUTTING; + int level = player.getSkills().getLevel(skill) + player.getFamiliarManager().getBoost(skill); + double hostRatio = RandomFunction.randomDouble(100.0); + double lowMod = tool == SkillingTool.BLACK_AXE ? resource.tierModLow / 2 : resource.tierModLow; + double low = resource.baseLow + (tool.ordinal() * lowMod); + double highMod = tool == SkillingTool.BLACK_AXE ? resource.tierModHigh / 2 : resource.tierModHigh; + double high = resource.baseHigh + (tool.ordinal() * highMod); + double clientRatio = RandomFunction.getSkillSuccessChance(low,high,level); + return hostRatio < clientRatio; + } +} diff --git a/Server/src/main/content/global/skill/herblore/BarbarianMixListener.kt b/Server/src/main/content/global/skill/herblore/BarbarianMixListener.kt new file mode 100644 index 0000000..20077f2 --- /dev/null +++ b/Server/src/main/content/global/skill/herblore/BarbarianMixListener.kt @@ -0,0 +1,59 @@ +package content.global.skill.herblore + +import content.global.skill.herblore.BarbarianPotion +import core.game.node.entity.skill.Skills +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.node.Node +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.api.hasLevelStat +import core.api.sendMessage +import core.api.removeItem +import core.api.addItem +import core.api.rewardXP + +/** + * Represents the barbarian mixing listener. + * @author 'Vexia + * @author treevar + * @version 2.0 + */ + +class BarbarianMixListener : InteractionListener { + override fun defineListeners(){ + for (potion in BarbarianPotion.values()) { + if (potion.isBoth()) { + onUseWith(IntType.ITEM, potion.getItem(), 11324) { player, used, with -> //Roe + handle(player, used, with); + } + } + onUseWith(IntType.ITEM, potion.getItem(), 11326) { player, used, with -> //Caviar + handle(player, used, with); + } + } + } + + fun handle(player: Player, inputPotion: Node, egg: Node): Boolean { + val potion: BarbarianPotion? = BarbarianPotion.forId(inputPotion.getId()) + if(potion == null){ + return false + } + + if (!hasLevelStat(player, Skills.HERBLORE, potion.getLevel())) { + sendMessage(player, "You need a herblore level of " + potion.getLevel().toString() + " to make this mix.") + return true + } + + if(!removeItem(player, potion.getItem())) { //Remove input potion + return false + } + if(!removeItem(player, egg.getId())) { //Remove egg used + addItem(player, potion.getItem()) //Add potion back to inventory if we can't remove the egg + return false + } + addItem(player, potion.getProduct()) //Add output potion + rewardXP(player, Skills.HERBLORE, potion.getExp()) //Add exp + return true + } +} diff --git a/Server/src/main/content/global/skill/herblore/BarbarianPotion.kt b/Server/src/main/content/global/skill/herblore/BarbarianPotion.kt new file mode 100644 index 0000000..5876c40 --- /dev/null +++ b/Server/src/main/content/global/skill/herblore/BarbarianPotion.kt @@ -0,0 +1,108 @@ +package content.global.skill.herblore; + +/** + * Represents the barbarian potion. + * @author 'Vexia + * @author treevar + */ +public enum class BarbarianPotion { + ATTACK_POTION(123, 4, 11429, 8.0, true), ANTI_POISION_POTION(177, 6, 11433, 12.0, true), RELIC(4846, 9, 11437, 14.0, true), STRENGTH_POTION(117, 14, 11443, 17.0, true), RESTORE_POTION(129, 24, 11449, 21.0, true), ENERGY_POTION(3012, 29, 11453, 23.0, false), DEFENCE_POTION(135, 33, 11457, 25.0, false), AGILITY_POTION(3036, 37, 11461, 27.0, false), COMBAT_POTION(9743, 40, 11445, 28.0, false), PRAYER_POTION(141, 42, 11465, 29.0, false), SUPER_ATTACK_POTION(147, 47, 11469, 33.0, false), SUPER_ANTIPOISION_POTION(183, 51, 11473, 35.0, false), FISHING_POTION(153, 53, 11477, 38.0, false), SUPER_ENERGY_POTION(3020, 56, 11481, 42.0, false), HUNTER_POTION(10002, 58, 11517, 40.0, false), SUPER_STRENGTH_POTION(159, 59, 11485, 42.0, false), SUPER_RESTORE(3028, 67, 11493, 48.0, false), SUPER_DEFENCE_POTION(165, 71, 11497, 50.0, false), ANTIDOTE_PLUS(5947, 74, 11501, 52.0, false), ANTIFIRE_POTION(2456, 75, 11505, 53.0, false), RANGING_POTION(171, 80, 11509, 54.0, false), MAGIC_POTION(3044, 83, 11513, 57.0, false), ZAMORAK_BREW(191, 85, 11521, 58.0, false); + + /** + * Constructs a new {@code BarbarianPotion} {@Code Object}. + * @param item the input potion id. + * @param level the level requirement to make. + * @param product the product potion id. + * @param exp the exp rewarded. + * @param both if both can be added(roe, cavier). + */ + constructor(item: Int, level: Int, product: Int, exp: Double, both: Boolean) { + this.item = item; + this.level = level; + this.product = product; + this.exp = exp; + this.both = both; + } + + /** + * The item id. + */ + private val item: Int; + + /** + * The product item id. + */ + private val product: Int; + + /** + * The level required. + */ + private val level: Int; + + /** + * the exp gained. + */ + private val exp: Double; + + /** + * Represents if both Roe & Cavier can be added. + */ + private val both: Boolean; + + /** + * Gets the item. + * @return The item. + */ + fun getItem(): Int { + return item; + } + + /** + * Gets the product. + * @return The product. + */ + fun getProduct(): Int { + return product; + } + + /** + * Gets the level. + * @return The level. + */ + fun getLevel(): Int { + return level; + } + + /** + * Gets the exp. + * @return The exp. + */ + fun getExp(): Double { + return exp; + } + + /** + * Gets whether roe and caviar can be used. + * @return true if both, false if only caviar. + */ + fun isBoth(): Boolean { + return both; + } + + companion object { + /** + * Gets the barbarian potion from the input potion id + * @param id the id of the input potion. + * @return the barbarian potion that takes the id as input. + */ + @JvmStatic + fun forId(id: Int): BarbarianPotion? { + for (pot in BarbarianPotion.values()) { + if (pot.getItem() == id) { + return pot; + } + } + return null; + } + } +} diff --git a/Server/src/main/content/global/skill/herblore/FinishedPotion.java b/Server/src/main/content/global/skill/herblore/FinishedPotion.java new file mode 100644 index 0000000..e78d804 --- /dev/null +++ b/Server/src/main/content/global/skill/herblore/FinishedPotion.java @@ -0,0 +1,136 @@ +package content.global.skill.herblore; + +import core.game.node.item.Item; +import org.rs09.consts.Items; + +/** + * Represents a finished potion. + * @author 'Vexia + */ +public enum FinishedPotion { + ATTACK_POTION(UnfinishedPotion.GUAM, new Item(221), 3, 25, new Item(121)), + ANTIPOISON_POTION(UnfinishedPotion.MARRENTILL, new Item(235), 5, 37.5, new Item(175)), + STRENGTH_POTION(UnfinishedPotion.TARROMIN, new Item(225), 12, 50, new Item(115)), + RESTORE_POTION(UnfinishedPotion.HARRALANDER, new Item(223), 22, 62.5, new Item(127)), + ENERGY_POTION(UnfinishedPotion.HARRALANDER, new Item(1975), 26, 67.5, new Item(3010)), + DEFENCE_POTION(UnfinishedPotion.RANARR, new Item(239), 30, 45, new Item(133)), + AGILITY_POTION(UnfinishedPotion.TOADFLAX, new Item(2152), 34, 80, new Item(3034)), + COMBAT_POTION(UnfinishedPotion.HARRALANDER, new Item(9736), 36, 84, new Item(9741)), + PRAYER_POTION(UnfinishedPotion.RANARR, new Item(231), 38, 87.5, new Item(139)), + SUMMONING_POTION(UnfinishedPotion.SPIRIT_WEED, new Item(12109), 40, 92, new Item(12142)), + SUPER_ATTACK(UnfinishedPotion.IRIT, new Item(221), 45, 100, new Item(145)), + SUPER_ANTIPOISON(UnfinishedPotion.IRIT, new Item(235), 48, 106.3, new Item(181)), + FISHING_POTION(UnfinishedPotion.AVANTOE, new Item(231), 50, 112.5, new Item(151)), + SUPER_ENERGY(UnfinishedPotion.AVANTOE, new Item(2970), 52, 117.5, new Item(3018)), + HUNTING_POTION(UnfinishedPotion.AVANTOE, new Item(Items.KEBBIT_TEETH_DUST_10111), 53, 120, new Item(10000)), + SUPER_STRENGTH(UnfinishedPotion.KWUARM, new Item(225), 55, 125, new Item(157)), + WEAPON_POISON(UnfinishedPotion.KWUARM, new Item(241), 60, 137.5, new Item(187)), + SUPER_RESTORE(UnfinishedPotion.SNAPDRAGON, new Item(223), 63, 142.5, new Item(3026)), + SUPER_DEFENCE(UnfinishedPotion.CADANTINE, new Item(239), 66, 160, new Item(163)), + ANTIFIRE(UnfinishedPotion.LANTADYME, new Item(241), 69, 157.5, new Item(2454)), + SUPER_RANGING_POTION(UnfinishedPotion.DWARF_WEED, new Item(245), 72, 162.5, new Item(169)), + SUPER_MAGIC(UnfinishedPotion.LANTADYME, new Item(3138), 76, 172.5, new Item(3042)), + ZAMORAK_BREW(UnfinishedPotion.TORSTOL, new Item(247), 78, 175, new Item(189)), + SARADOMIN_BREW(UnfinishedPotion.TOADFLAX, GrindingItem.BIRDS_NEST.getProduct(), 81, 180, new Item(6687)), + STRONG_WEAPON_POISON(UnfinishedPotion.STRONG_WEAPON_POISON, new Item(223), 73, 165, new Item(5937)), + SUPER_STRONG_WEAPON_POISON(UnfinishedPotion.SUPER_STRONG_WEAPON_POISON, new Item(6018), 82, 190, new Item(5940)), + STRONG_ANTIPOISON(UnfinishedPotion.STRONG_ANTIPOISON, new Item(6049), 68, 155, new Item(5945)), + SUPER_STRONG_ANTIPOISON(UnfinishedPotion.SUPER_STRONG_ANTIPOISON, new Item(6051), 79, 177.5, new Item(5954)), + BLAMISH_OIL(UnfinishedPotion.HARRALANDER, new Item(1581), 25, 80, new Item(1582)); + + /** + * Represents the unfinished potion. + */ + private final UnfinishedPotion unfinished; + + /** + * Represents the ingredient required. + */ + private final Item ingredient; + + /** + * Represents the level required. + */ + private final int level; + + /** + * Represents the experience gained. + */ + private final double experience; + + /** + * Represents the potion item. + */ + private final Item potion; + + /** + * Constructs a new {@code FinishedPotion} {@code Object}. + * @param unfinished the unfinished potion base. + * @param ingredient the ingredient. + * @param level the level. + * @param experience the experience. + * @param potion the potion. + */ + FinishedPotion(final UnfinishedPotion unfinished, final Item ingredient, final int level, final double experience, final Item potion) { + this.unfinished = unfinished; + this.ingredient = ingredient; + this.level = level; + this.experience = experience; + this.potion = potion; + } + + /** + * Gets the unfinished. + * @return The unfinished. + */ + public UnfinishedPotion getUnfinished() { + return unfinished; + } + + /** + * Gets the ingredient. + * @return The ingredient. + */ + public Item getIngredient() { + return ingredient; + } + + /** + * Gets the level. + * @return The level. + */ + public int getLevel() { + return level; + } + + /** + * Gets the experience. + * @return The experience. + */ + public double getExperience() { + return experience; + } + + /** + * Gets the potion. + * @return The potion. + */ + public Item getPotion() { + return potion; + } + + /** + * Gets the finished potion by the unfinished potion and the ingredient. + * @param unf the unf-potion. + * @param ingredient the ingredient. + * @return the finished potion. + */ + public static FinishedPotion getPotion(final Item unf, final Item ingredient) { + for (FinishedPotion pot : values()) { + if (pot.getUnfinished().getPotion().getId() == unf.getId() && pot.getIngredient().getId() == ingredient.getId()) { + return pot; + } + } + return null; + } +} diff --git a/Server/src/main/content/global/skill/herblore/FinishedPotionPlugin.java b/Server/src/main/content/global/skill/herblore/FinishedPotionPlugin.java new file mode 100644 index 0000000..61b8717 --- /dev/null +++ b/Server/src/main/content/global/skill/herblore/FinishedPotionPlugin.java @@ -0,0 +1,75 @@ +package content.global.skill.herblore; + +import core.plugin.Initializable; +import core.game.dialogue.SkillDialogueHandler; +import core.game.dialogue.SkillDialogueHandler.SkillDialogue; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.Player; +import core.plugin.Plugin; + +/** + * Represents the finished potion plugin creating. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class FinishedPotionPlugin extends UseWithHandler { + + /** + * Constructs a new {@code FinishedPotionPlugin} {@code Object} + */ + public FinishedPotionPlugin() { + super(getUnfinishedItems()); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (FinishedPotion potion : FinishedPotion.values()) { + addHandler(potion.getIngredient().getId(), ITEM_TYPE, this); + } + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final FinishedPotion finished = FinishedPotion.getPotion(event.getUsedItem().getName().contains("(unf)") ? event.getUsedItem() : event.getBaseItem(), event.getUsedItem().getName().contains("(unf)") ? event.getBaseItem() : event.getUsedItem()); + if (finished == null) { + return false; + } + final GenericPotion potion = GenericPotion.transform(finished); + final Player player = event.getPlayer(); + SkillDialogueHandler handler = new SkillDialogueHandler(player, SkillDialogue.ONE_OPTION, potion.getProduct()) { + @Override + public void create(final int amount, int index) { + player.getPulseManager().run(new HerblorePulse(player, potion.getBase(), amount, potion)); + } + + @Override + public int getAll(int index) { + return player.getInventory().getAmount(potion.getBase()); + } + + }; + if (player.getInventory().getAmount(potion.getBase()) == 1) { + handler.create(0, 1); + } else { + handler.open(); + } + return true; + } + + /** + * Method used to gather the unfinished item bases. + * @return the ids. + */ + public static int[] getUnfinishedItems() { + int[] ids = new int[UnfinishedPotion.values().length]; + int counter = 0; + for (UnfinishedPotion potion : UnfinishedPotion.values()) { + ids[counter] = potion.getPotion().getId(); + counter++; + } + return ids; + } +} diff --git a/Server/src/main/content/global/skill/herblore/GenericPotion.java b/Server/src/main/content/global/skill/herblore/GenericPotion.java new file mode 100644 index 0000000..3f84a0b --- /dev/null +++ b/Server/src/main/content/global/skill/herblore/GenericPotion.java @@ -0,0 +1,110 @@ +package content.global.skill.herblore; + +import core.game.node.item.Item; + +/** + * Represents a generic potion which is used to transform incoming data to + * represent a potion(finished or unfinished). + * @author 'Vexia + */ +public final class GenericPotion { + + /** + * Represents the base of the potion. + */ + private final Item base; + + /** + * Represents the ingredient. + */ + private final Item ingredient; + + /** + * Represents the level required. + */ + private final int level; + + /** + * Represents the experience gained. + */ + private final double experience; + + /** + * Represents the product item. + */ + private final Item product; + + /** + * Constructs a new {@code GenericPotion} {@code Object}. + * @param base the base. + * @param ingredient the ingredient. + * @param level the level. + * @param experience the experience. + * @param product the product. + */ + public GenericPotion(final Item base, final Item ingredient, final int level, final double experience, final Item product) { + this.base = base; + this.ingredient = ingredient; + this.level = level; + this.experience = experience; + this.product = product; + } + + /** + * Method used to transform an unfinished potion into a generic potion. + * @param potion the potion to transform. + * @return the transformed potion. + */ + public static GenericPotion transform(final UnfinishedPotion potion) { + return new GenericPotion(potion.getBase(), potion.getIngredient(), potion.getLevel(), 0, potion.getPotion()); + } + + /** + * Method used to transform a finished potion into a generic potion. + * @param potion the potion to transform. + * @return the transformed potion. + */ + public static GenericPotion transform(final FinishedPotion potion) { + return new GenericPotion(potion.getUnfinished().getPotion(), potion.getIngredient(), potion.getLevel(), potion.getExperience(), potion.getPotion()); + } + + /** + * Gets the base. + * @return The base. + */ + public Item getBase() { + return base; + } + + /** + * Gets the level. + * @return The level. + */ + public int getLevel() { + return level; + } + + /** + * Gets the experience. + * @return The experience. + */ + public double getExperience() { + return experience; + } + + /** + * Gets the product. + * @return The product. + */ + public Item getProduct() { + return product; + } + + /** + * Gets the ingredient. + * @return The ingredient. + */ + public Item getIngredient() { + return ingredient; + } +} diff --git a/Server/src/main/content/global/skill/herblore/GrindItemPlugin.kt b/Server/src/main/content/global/skill/herblore/GrindItemPlugin.kt new file mode 100644 index 0000000..ec9cd70 --- /dev/null +++ b/Server/src/main/content/global/skill/herblore/GrindItemPlugin.kt @@ -0,0 +1,101 @@ +package content.global.skill.herblore + +import core.api.addItem +import core.api.amountInInventory +import core.api.removeItem +import core.game.dialogue.SkillDialogueHandler +import core.game.interaction.NodeUsageEvent +import core.game.interaction.UseWithHandler +import core.game.node.entity.skill.SkillPulse +import core.game.node.item.Item +import core.game.world.update.flag.context.Animation +import core.net.packet.PacketRepository +import core.net.packet.context.ChildPositionContext +import core.net.packet.out.RepositionChild +import core.plugin.Initializable +import core.plugin.Plugin +import org.rs09.consts.Items +import kotlin.math.ceil +import kotlin.math.roundToInt + +/** + * plugin used to handle the grinding of an item. + * @author 'Ceikry + */ +@Initializable +class GrindItemPlugin : UseWithHandler(233) { + override fun newInstance(arg: Any?): Plugin? { + for (grind in GrindingItem.values()) { + for (i in grind.items) { + addHandler(i.id, ITEM_TYPE, this) + } + } + return this + } + + override fun handle(event: NodeUsageEvent): Boolean { + val grind = GrindingItem.forItem(if (event.usedItem.id == 233) event.baseItem else event.usedItem) + val handler = object : SkillDialogueHandler(event.player,SkillDialogue.ONE_OPTION,grind.product) { + override fun create(amount: Int, index: Int) { + player.pulseManager.run(object : SkillPulse(player,event.usedItem) { + var amt = 0 + init { + amt = amount + if(amt > amountInInventory(player, node.id)) { + amt = amountInInventory(player, node.id) + } + if (node.id == FISHING_BAIT) { + if(amt > (amountInInventory(player, node.id) / 10)) { + amt = ceil(amountInInventory(player, node.id).toDouble() / 10).roundToInt() + } + } + super.setDelay(2) + } + override fun checkRequirements(): Boolean { + return true + } + + override fun animate() { + player.animator.animate(ANIMATION) + } + + override fun reward(): Boolean { + if (node.id == Items.FISHING_BAIT_313) { + var quantity = 0 + quantity = if (amountInInventory(player, FISHING_BAIT) >= 10) { + 10 + } else { + amountInInventory(player, FISHING_BAIT) + } + if (removeItem(player, Item(node.id, quantity))) { + addItem(player, GrindingItem.forItem(node).product.id, quantity) + } + } else { + if (removeItem(player, Item(node.id, 1))) { + addItem(player, GrindingItem.forItem(node).product.id) + } + } + amt-- + return amt <= 0 + } + }) + + } + + override fun getAll(index: Int): Int { + return amountInInventory(player, event.usedItem.id) + } + } + handler.open() + PacketRepository.send(RepositionChild::class.java, ChildPositionContext(event.player, 309, 2, 210, 15)) + return true + } + + companion object { + /** + * Represents the animation to use. + */ + private val ANIMATION = Animation(364) + private const val FISHING_BAIT = Items.FISHING_BAIT_313 + } +} diff --git a/Server/src/main/content/global/skill/herblore/GrindingItem.java b/Server/src/main/content/global/skill/herblore/GrindingItem.java new file mode 100644 index 0000000..83b1f3e --- /dev/null +++ b/Server/src/main/content/global/skill/herblore/GrindingItem.java @@ -0,0 +1,80 @@ +package content.global.skill.herblore; + +import org.rs09.consts.Items; +import core.game.node.item.Item; + +/** + * Represents an item that will can be ground by pestle and mortar. + * @author Vexia + */ +public enum GrindingItem { + UNICORN_HORN(new Item[] { new Item(Items.UNICORN_HORN_237) }, new Item(Items.UNICORN_HORN_DUST_235)), + KEBBIT_TEETH(new Item[] { new Item(Items.KEBBIT_TEETH_10109) }, new Item(Items.KEBBIT_TEETH_DUST_10111)), + BIRDS_NEST(new Item[] { new Item(Items.BIRDS_NEST_5075) }, new Item(Items.CRUSHED_NEST_6693)), + GOAT_HORN(new Item[] { new Item(Items.DESERT_GOAT_HORN_9735) }, new Item(Items.GOAT_HORN_DUST_9736)), + MUD_RUNE(new Item[] { new Item(Items.MUD_RUNE_4698) }, new Item(Items.GROUND_MUD_RUNES_9594)), + ASHES(new Item[] { new Item(Items.ASHES_592) }, new Item(Items.GROUND_ASHES_8865)), + POISON_KARAMBWAN(new Item[] { new Item(Items.POISON_KARAMBWAN_3146) }, new Item(Items.KARAMBWAN_PASTE_3152)), + FISHING_BAIT(new Item[] { new Item(Items.FISHING_BAIT_313) }, new Item(Items.GROUND_FISHING_BAIT_12129)), + SEAWEED(new Item[] { new Item(Items.SEAWEED_401) }, new Item(Items.GROUND_SEAWEED_6683)), + BAT_BONES(new Item[] { new Item(Items.BAT_BONES_530) }, new Item(Items.GROUND_BAT_BONES_2391)), + CHARCOAL(new Item[] { new Item(Items.CHARCOAL_973) }, new Item(Items.GROUND_CHARCOAL_704)), + ASTRAL_RUNE_SHARDS(new Item[] { new Item(Items.ASTRAL_RUNE_SHARDS_11156) }, new Item(Items.GROUND_ASTRAL_RUNE_11155)), + GARLIC(new Item[] { new Item(Items.GARLIC_1550) }, new Item(Items.GARLIC_POWDER_4668)), + DRAGON_SCALE(new Item[] { new Item(Items.BLUE_DRAGON_SCALE_243) }, new Item(Items.DRAGON_SCALE_DUST_241)), + ANCHOVIES(new Item[] { new Item(Items.ANCHOVIES_319) }, new Item(Items.ANCHOVY_PASTE_11266)), + CHOCOLATE_BAR(new Item[] {new Item(Items.CHOCOLATE_BAR_1973)}, new Item(Items.CHOCOLATE_DUST_1975)), + GUAM_LEAF(new Item[] { new Item(Items.CLEAN_GUAM_249) }, new Item(Items.GROUND_GUAM_6681)); + + /** + * Represents the item to grind. + */ + private final Item[] items; + + /** + * Represents the product item. + */ + private final Item product; + + /** + * Constructs a new {@code GrindingItem} {@code Object}. + * @param items the items. + * @param product the product. + */ + GrindingItem(final Item[] items, final Item product) { + this.items = items; + this.product = product; + } + + /** + * Gets the item. + * @return The item. + */ + public Item[] getItems() { + return items; + } + + /** + * Gets the product. + * @return The product. + */ + public Item getProduct() { + return product; + } + + /** + * Gets the grinding item. + * @param item the item. + * @return the item. + */ + public static GrindingItem forItem(final Item item) { + for (GrindingItem g : values()) { + for (Item i : g.getItems()) { + if (i.getId() == item.getId()) { + return g; + } + } + } + return null; + } +} diff --git a/Server/src/main/content/global/skill/herblore/HerbCleanListener.kt b/Server/src/main/content/global/skill/herblore/HerbCleanListener.kt new file mode 100644 index 0000000..6807e5d --- /dev/null +++ b/Server/src/main/content/global/skill/herblore/HerbCleanListener.kt @@ -0,0 +1,35 @@ +package content.global.skill.herblore + +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import java.util.* +import content.data.Quests + +/** + * Dirty herb cleaning listener + * @author Woah + */ +class HerbCleanListener : InteractionListener { + override fun defineListeners() { + on(IntType.ITEM, "clean") { player, node -> + lock(player, 1) + if (!requireQuest(player, Quests.DRUIDIC_RITUAL, "before you can use Herblore.")) return@on true + val herb: Herbs = Herbs.forItem(node as Item) ?: return@on true + + if (getDynLevel(player, Skills.HERBLORE) < herb.level) { + sendMessage(player, "You cannot clean this herb. You need a Herblore level of " + herb.level + " to attempt this.") + return@on true + } + + val exp = herb.experience + replaceSlot(player, node.asItem().slot, herb.product, node.asItem()) + rewardXP(player, Skills.HERBLORE, exp) + playAudio(player, 5153) + sendMessage(player, "You clean the dirt from the " + herb.product.name.lowercase(Locale.getDefault()).replace("clean", "").trim { it <= ' ' } + " leaf.") + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/herblore/HerbTarPlugin.java b/Server/src/main/content/global/skill/herblore/HerbTarPlugin.java new file mode 100644 index 0000000..fe60ca4 --- /dev/null +++ b/Server/src/main/content/global/skill/herblore/HerbTarPlugin.java @@ -0,0 +1,53 @@ +package content.global.skill.herblore; + +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.net.packet.PacketRepository; +import core.net.packet.context.ChildPositionContext; +import core.net.packet.out.RepositionChild; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.game.dialogue.SkillDialogueHandler; + +/** + * Represents the plugin used to create a herb tar. + * @author Ceikry, fawk Vexia and his bad design. + * @version 1.0 + */ +@Initializable +public final class HerbTarPlugin extends UseWithHandler { + + /** + * Constructs a new {@code HerbTarPlugin} {@code Object}. + */ + public HerbTarPlugin() { + super(1939); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (Tars tar : Tars.values()) { + addHandler(tar.getIngredient().getId(), ITEM_TYPE, this); + } + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + //Tars.forItem(event.getUsedItem().getId() == 1939 ? event.getBaseItem() : event.getUsedItem()) + SkillDialogueHandler handler = new SkillDialogueHandler(event.getPlayer(), SkillDialogueHandler.SkillDialogue.ONE_OPTION,Tars.forItem(event.getUsedItem().getId() == 1939 ? event.getBaseItem() : event.getUsedItem()).getTar()){ + @Override + public void create(int amount, int index) { + event.getPlayer().getPulseManager().run(new HerbTarPulse(event.getPlayer(), null, Tars.forItem(event.getUsedItem().getId() == 1939 ? event.getBaseItem() : event.getUsedItem()), amount)); + } + @Override + public int getAll(int index) { + return event.getPlayer().getInventory().getAmount(event.getUsedItem()); + } + }; + handler.open(); + PacketRepository.send(RepositionChild.class, new ChildPositionContext(event.getPlayer(), 309, 2, 210, 15)); + return true; + } + +} diff --git a/Server/src/main/content/global/skill/herblore/HerbTarPulse.java b/Server/src/main/content/global/skill/herblore/HerbTarPulse.java new file mode 100644 index 0000000..247f69f --- /dev/null +++ b/Server/src/main/content/global/skill/herblore/HerbTarPulse.java @@ -0,0 +1,110 @@ +package content.global.skill.herblore; + +import core.game.node.entity.skill.SkillPulse; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; +import content.data.Quests; + +/** + * Represents the pulse used to create herb tars. + * @author 'Vexia + */ +public final class HerbTarPulse extends SkillPulse { + + /** + * Represents the animation to use. + */ + private static final Animation ANIMATION = new Animation(364); + + /** + * Represents the pestle and mortar item. + */ + private static final Item PESTLE_AND_MORTAR = new Item(233); + + /** + * Represents the swamp tar item. + */ + private static final Item SWAMP_TAR = new Item(1939, 15); + + /** + * Represents the tar to make. + */ + private final Tars tar; + + /** + * Represents the amount to make. + */ + private int amount; + + /** + * Constructs a new {@code HerbTarPulse} {@code Object}. + * @param player the player. + * @param node the node. + * @param tar the tar. + * @param amount the amount. + */ + public HerbTarPulse(Player player, Item node, Tars tar, int amount) { + super(player, node); + this.tar = tar; + this.amount = amount; + } + + @Override + public boolean checkRequirements() { + if (!player.getQuestRepository().isComplete(Quests.DRUIDIC_RITUAL)) { + player.getPacketDispatch().sendMessage("You must complete the Druidic Ritual quest before you can use Herblore."); + return false; + } + if (player.getSkills().getLevel(Skills.HERBLORE) < tar.getLevel()) { + player.getPacketDispatch().sendMessage("You need a Herblore level of at least " + tar.getLevel() + " in order to do this."); + return false; + } + if (!player.getInventory().containsItem(PESTLE_AND_MORTAR)) { + player.getPacketDispatch().sendMessage("You need Pestle and Mortar in order to crush the herb."); + return false; + } + if (!player.getInventory().containsItem(SWAMP_TAR)) { + player.getPacketDispatch().sendMessage("You need at least 15 swamp tar in order to do this."); + return false; + } + return true; + } + + @Override + public void animate() { + player.animate(ANIMATION); + } + + @Override + public boolean reward() { + if (getDelay() == 1) { + setDelay(4); + return false; + } + if (player.getInventory().containsItem(SWAMP_TAR) && player.getInventory().containsItem(tar.getIngredient()) && player.getInventory().remove(SWAMP_TAR) && player.getInventory().remove(tar.getIngredient())) { + final Item item = new Item(tar.getTar().getId(), 15); + player.getInventory().add(item); + player.getSkills().addExperience(Skills.HERBLORE, tar.getExperience(), true); + player.getPacketDispatch().sendMessage("You add the " + tar.getIngredient().getName().toLowerCase().replace("clean", "").trim() + " to the swamp tar."); + } else { + return true; + } + amount--; + return amount == 0; + } + + @Override + public void message(int type) { + } + + /** + * Gets the tar. + * @return The tar. + */ + public Tars getTar() { + return tar; + } + +} diff --git a/Server/src/main/content/global/skill/herblore/HerblorePulse.java b/Server/src/main/content/global/skill/herblore/HerblorePulse.java new file mode 100644 index 0000000..0f859ad --- /dev/null +++ b/Server/src/main/content/global/skill/herblore/HerblorePulse.java @@ -0,0 +1,157 @@ +package content.global.skill.herblore; + +import core.game.node.entity.skill.SkillPulse; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; +import core.tools.StringUtils; +import content.global.skill.skillcapeperks.*; +import content.data.consumables.Consumables; +import core.tools.RandomFunction; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playAudio; +import content.data.Quests; + + +/** + * Represents the skill pulse used to handle the creating of potions. + * @author 'Vexia + */ +public final class HerblorePulse extends SkillPulse { + + /** + * Represents the vial of water item. + */ + public static final Item VIAL_OF_WATER = new Item(227); + + /** + * Represents the coonut milk item. + */ + public static final Item COCONUT_MILK = new Item(5935); + + /** + * Represents the animation to use when making a potion. + */ + private static final Animation ANIMATION = new Animation(363); + + /** + * Represents the generic potion. + */ + private final GenericPotion potion; + + /** + * Represents the amount to make. + */ + private int amount; + + /** + * Represents the initial amount to make. + */ + private int initialAmount; + + /** + * Represents the cycles. + */ + private int cycles; + + /** + * Constructs a new {@code HerblorePulse} {@code Object}. + * @param player the player. + * @param node the node. + */ + public HerblorePulse(final Player player, final Item node, final int amount, final GenericPotion potion) { + super(player, node); + this.amount = amount; + this.initialAmount = amount; + this.potion = potion; + } + + @Override + public boolean checkRequirements() { + if (!player.getQuestRepository().isComplete(Quests.DRUIDIC_RITUAL)) { + player.getPacketDispatch().sendMessage("You must complete the Druidic Ritual quest before you can use Herblore."); + return false; + } + if (player.getSkills().getLevel(Skills.HERBLORE) < potion.getLevel()) { + player.getPacketDispatch().sendMessage("You need a Herblore level of at least " + potion.getLevel() + " in order to do this."); + return false; + } + if (!player.getInventory().containsItem(potion.getBase()) || !player.getInventory().containsItem(potion.getIngredient())) { + return false; + } + return true; + } + + @Override + public void animate() { + } + + @Override + public boolean reward() { + if (potion.getBase().getId() == VIAL_OF_WATER.getId()) { + if (initialAmount == 1 && getDelay() == 1) { + player.animate(ANIMATION); + setDelay(3); + return false; + } + handleUnfinished(); + } else { + if (initialAmount == 1 && getDelay() == 1) { + player.animate(ANIMATION); + setDelay(3); + return false; + } + if (getDelay() == 1) { + setDelay(3); + player.animate(ANIMATION); + return false; + } + handleFinished(); + } + amount--; + return amount == 0; + } + + /** + * Method used to handle the potion making of an unf-potion. + */ + public void handleUnfinished() { + if (cycles == 0) { + player.animate(ANIMATION); + } + if ((player.getInventory().containsItem(potion.getBase()) && player.getInventory().containsItem(potion.getIngredient())) && player.getInventory().remove(potion.getBase(), potion.getIngredient())) { + final Item item = potion.getProduct(); + player.getInventory().add(item); + player.getPacketDispatch().sendMessage("You put the" + StringUtils.formatDisplayName(potion.getIngredient().getName().toLowerCase().replace("clean", "")) + " leaf into the vial of water."); + playAudio(player, Sounds.GRIND_2608); + if (cycles++ == 3) { + player.animate(ANIMATION); + cycles = 0; + } + } + } + + /** + * Method used to handle the finished potion making. + */ + public void handleFinished() { + if ((player.getInventory().containsItem(potion.getBase()) && player.getInventory().containsItem(potion.getIngredient())) && player.getInventory().remove(potion.getBase(), potion.getIngredient())) { + Item item = potion.getProduct(); + if (SkillcapePerks.isActive (SkillcapePerks.BREWMASTER, player)) { + if (RandomFunction.random(100) < 15) { + Consumables consum = Consumables.getConsumableById (item.getId()); + if (consum != null) + item = new Item (consum.getConsumable().getIds()[0], item.getAmount()); + player.sendMessage ("Due to your expertise, you manage to make an extra dose."); + } + } + player.getInventory().add(item); + player.getSkills().addExperience(Skills.HERBLORE, potion.getExperience(), true); + player.getPacketDispatch().sendMessage("You mix the " + potion.getIngredient().getName().toLowerCase() + " into your potion."); + playAudio(player, Sounds.GRIND_2608); + player.animate(ANIMATION); + } + } +} diff --git a/Server/src/main/content/global/skill/herblore/Herbs.java b/Server/src/main/content/global/skill/herblore/Herbs.java new file mode 100644 index 0000000..1973162 --- /dev/null +++ b/Server/src/main/content/global/skill/herblore/Herbs.java @@ -0,0 +1,91 @@ +package content.global.skill.herblore; + +import core.game.node.item.Item; + +/** + * Represents the enumeration of herbs to clean. + * @author 'Vexia + */ +public enum Herbs { + GUAM(new Item(199), 2.5, 3, new Item(249)), MARRENTILL(new Item(201), 3.8, 5, new Item(251)), TARROMIN(new Item(203), 5, 11, new Item(253)), HARRALANDER(new Item(205), 6.3, 20, new Item(255)), RANARR(new Item(207), 7.5, 25, new Item(257)), TOADFLAX(new Item(3049), 8, 30, new Item(2998)), SPIRIT_WEED(new Item(12174), 7.8, 35, new Item(12172)), IRIT(new Item(209), 8.8, 40, new Item(259)), AVANTOE(new Item(211), 10, 48, new Item(261)), KWUARM(new Item(213), 11.3, 54, new Item(263)), SNAPDRAGON(new Item(3051), 11.8, 59, new Item(3000)), CADANTINE(new Item(215), 12.5, 65, new Item(265)), LANTADYME(new Item(2485), 13.1, 67, new Item(2481)), DWARF_WEED(new Item(217), 13.8, 70, new Item(267)), TORSTOL(new Item(219), 15, 75, new Item(269)), SNAKE_WEED(new Item(1525), 2.5, 3, new Item(1526)), ARDRIGAL(new Item(1527), 2.5, 3, new Item(1528)), SITO_FOIL(new Item(1529), 2.5, 3, new Item(1530)), VOLENCIA_MOSS(new Item(1531), 2.5, 3, new Item(1532)), ROGUES_PURSE(new Item(1533), 0, 8, new Item(1534)); + + /** + * Represents the herb item. + */ + private final Item herb; + + /** + * Represents the level required to clean this herb. + */ + private final int level; + + /** + * Represents the experience. + */ + private final double experience; + + /** + * Represents the product recieved from cleaning the herb. + */ + private final Item product; + + /** + * Constructs a new {@code Herbs} {@code Object}. + * @param herb the herb. + * @param level the level. + * @param experience the experience. + * @param product the product. + */ + Herbs(final Item herb, final double experience, final int level, final Item product) { + this.herb = herb; + this.experience = experience; + this.level = level; + this.product = product; + } + + /** + * Gets the herb. + * @return The herb. + */ + public Item getHerb() { + return herb; + } + + /** + * Gets the level. + * @return The level. + */ + public int getLevel() { + return level; + } + + /** + * Gets the experience. + * @return The experience. + */ + public double getExperience() { + return experience; + } + + /** + * Gets the product. + * @return The product. + */ + public Item getProduct() { + return product; + } + + /** + * Gets the herb from the item id. + * @param item the item. + * @return the herb. + */ + public static Herbs forItem(final Item item) { + for (Herbs herb : Herbs.values()) { + if (herb.getHerb().getId() == item.getId()) { + return herb; + } + } + return null; + } +} diff --git a/Server/src/main/content/global/skill/herblore/SwampToadPlugin.java b/Server/src/main/content/global/skill/herblore/SwampToadPlugin.java new file mode 100644 index 0000000..472846a --- /dev/null +++ b/Server/src/main/content/global/skill/herblore/SwampToadPlugin.java @@ -0,0 +1,36 @@ +package content.global.skill.herblore; + + +import core.cache.def.impl.ItemDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the swamp toad plugin. + * @author Zombiemode + * @version 1.0 + */ +@Initializable +public final class SwampToadPlugin extends OptionHandler { + @Override + public Plugin newInstance(Object arg) throws Throwable { + ItemDefinition.setOptionHandler("remove-legs", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + if (player.getInventory().replace(new Item(2152), ((Item) node).getSlot()) != null) { + player.getPacketDispatch().sendMessage("You pull the legs off the toad. Poor toad. At least they'll grow back."); + } + return true; + } + + @Override + public boolean isWalk() { return false; } +} + diff --git a/Server/src/main/content/global/skill/herblore/Tars.java b/Server/src/main/content/global/skill/herblore/Tars.java new file mode 100644 index 0000000..c63d783 --- /dev/null +++ b/Server/src/main/content/global/skill/herblore/Tars.java @@ -0,0 +1,96 @@ +package content.global.skill.herblore; + +import core.game.node.item.Item; +import org.rs09.consts.Items; + +/** + * Represents a tar to create. + * @author 'Vexia + */ +public enum Tars { + GUAM_TAR(Herbs.GUAM.getProduct(), 19, 30, new Item(10142)), + GROUND_GUAM_TAR(new Item(Items.GROUND_GUAM_6681), 19, 30, new Item(10142)), + MARRENTILL_TAR(Herbs.MARRENTILL.getProduct(), 31, 42.5, new Item(10143)), + TARROMIN_TAR(Herbs.TARROMIN.getProduct(), 39, 55, new Item(10144)), + HARRALANDER_TAR(Herbs.HARRALANDER.getProduct(), 44, 72.5, new Item(10145)); + + /** + * Represents the ingredient. + */ + private final Item ingredient; + + /** + * Represents the level required. + */ + private final int level; + + /** + * Represents the experience gained. + */ + private final double experience; + + /** + * Represents the tar item. + */ + private final Item tar; + + /** + * Constructs a new {@code Tars} {@code Object}. + * @param ingredient the ingredient. + * @param level the level. + * @param experience the experience. + * @param tar the tar. + */ + Tars(Item ingredient, int level, double experience, Item tar) { + this.ingredient = ingredient; + this.level = level; + this.experience = experience; + this.tar = tar; + } + + /** + * Gets the ingredient. + * @return The ingredient. + */ + public Item getIngredient() { + return ingredient; + } + + /** + * Gets the level. + * @return The level. + */ + public int getLevel() { + return level; + } + + /** + * Gets the experience. + * @return The experience. + */ + public double getExperience() { + return experience; + } + + /** + * Gets the tar. + * @return The tar. + */ + public Item getTar() { + return tar; + } + + /** + * Gets the tar. + * @param item the item. + * @return the tar. + */ + public static Tars forItem(final Item item) { + for (Tars tar : Tars.values()) { + if (tar.getIngredient().getId() == item.getId()) { + return tar; + } + } + return null; + } +} diff --git a/Server/src/main/content/global/skill/herblore/UnfinishedPotion.java b/Server/src/main/content/global/skill/herblore/UnfinishedPotion.java new file mode 100644 index 0000000..aa6e48d --- /dev/null +++ b/Server/src/main/content/global/skill/herblore/UnfinishedPotion.java @@ -0,0 +1,121 @@ +package content.global.skill.herblore; + +import core.game.node.item.Item; + +/** + * Represents an unfinished potion to make. + * @author 'Vexia + */ +public enum UnfinishedPotion { + GUAM(Herbs.GUAM.getProduct(), 3, new Item(91)), + MARRENTILL(Herbs.MARRENTILL.getProduct(), 5, new Item(93)), + ROGUES_PURSE(Herbs.ROGUES_PURSE.getProduct(), 5, new Item(4840)), + TARROMIN(Herbs.TARROMIN.getProduct(), 12, new Item(95)), + HARRALANDER(Herbs.HARRALANDER.getProduct(), 22, new Item(97)), + RANARR(Herbs.RANARR.getProduct(), 30, new Item(99)), + TOADFLAX(Herbs.TOADFLAX.getProduct(), 34, new Item(3002)), + SPIRIT_WEED(Herbs.SPIRIT_WEED.getProduct(), 40, new Item(12181)), + IRIT(Herbs.IRIT.getProduct(), 45, new Item(101)), + AVANTOE(Herbs.AVANTOE.getProduct(), 50, new Item(103)), + KWUARM(Herbs.KWUARM.getProduct(), 55, new Item(105)), + SNAPDRAGON(Herbs.SNAPDRAGON.getProduct(), 63, new Item(3004)), + CADANTINE(Herbs.CADANTINE.getProduct(), 66, new Item(107)), + LANTADYME(Herbs.LANTADYME.getProduct(), 69, new Item(2483)), + DWARF_WEED(Herbs.DWARF_WEED.getProduct(), 72, new Item(109)), + TORSTOL(Herbs.TORSTOL.getProduct(), 75, new Item(111)), + STRONG_WEAPON_POISON(HerblorePulse.COCONUT_MILK, new Item(6016), 73, new Item(5936)), + SUPER_STRONG_WEAPON_POISON(HerblorePulse.COCONUT_MILK, new Item(2398), 82, new Item(5939)), + STRONG_ANTIPOISON(HerblorePulse.COCONUT_MILK, Herbs.TOADFLAX.getProduct(), 68, new Item(5942)), + SUPER_STRONG_ANTIPOISON(HerblorePulse.COCONUT_MILK, Herbs.IRIT.getProduct(), 79, new Item(5951)); + + /** + * Represents the base item. + */ + private final Item base; + + /** + * Represents the ingredient needed to make this unf-potion. + */ + private final Item ingredient; + + /** + * Represents the level required to make this unf-potion. + */ + private final int level; + + /** + * Represents the potion product. + */ + private final Item potion; + + /** + * Constructs a new {@code UnfinishedPotion} {@code Object}. + * @param ingredient the ingredient. + * @param level the level. + * @param potion the potion. + */ + UnfinishedPotion(final Item base, final Item ingredient, final int level, final Item potion) { + this.base = base; + this.ingredient = ingredient; + this.level = level; + this.potion = potion; + } + + /** + * Constructs a new {@code UnfinishedPotion} {@code Object}. + * @param ingredient the ingredient. + * @param level the level. + * @param potion the potion. + */ + UnfinishedPotion(final Item ingredient, final int level, final Item potion) { + this(HerblorePulse.VIAL_OF_WATER, ingredient, level, potion); + } + + /** + * Gets the ingredient. + * @return The ingredient. + */ + public Item getIngredient() { + return ingredient; + } + + /** + * Gets the level. + * @return The level. + */ + public int getLevel() { + return level; + } + + /** + * Gets the potion. + * @return The potion. + */ + public Item getPotion() { + return potion; + } + + /** + * Gets the base. + * @return The base. + */ + public Item getBase() { + return base; + } + + /** + * Gets the unf-potion. + * @param item the item. + * @paramt the base item. + * @return the unf-potion. + */ + public static UnfinishedPotion forItem(final Item item, final Item base) { + for (UnfinishedPotion potion : values()) { + if ((potion.getIngredient().getId() == item.getId() || potion.getIngredient().getId() == base.getId()) && (item.getId() == potion.getBase().getId() || base.getId() == potion.getBase().getId())) { + return potion; + } + } + return null; + } + +} diff --git a/Server/src/main/content/global/skill/herblore/UnfinishedPotionPlugin.java b/Server/src/main/content/global/skill/herblore/UnfinishedPotionPlugin.java new file mode 100644 index 0000000..7504b00 --- /dev/null +++ b/Server/src/main/content/global/skill/herblore/UnfinishedPotionPlugin.java @@ -0,0 +1,61 @@ +package content.global.skill.herblore; + +import core.plugin.Initializable; +import core.game.dialogue.SkillDialogueHandler; +import core.game.dialogue.SkillDialogueHandler.SkillDialogue; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.Player; +import core.plugin.Plugin; + +/** + * Represents the plugin used to handle the creation of creation an unf-potion. + * @author 'Vexia + */ +@Initializable +public final class UnfinishedPotionPlugin extends UseWithHandler { + + /** + * Constructs a new {@code UnfinishedPotionPlugin} {@code Object}. + */ + public UnfinishedPotionPlugin() { + super(227, 5935); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (UnfinishedPotion potion : UnfinishedPotion.values()) { + addHandler(potion.getIngredient().getId(), ITEM_TYPE, this); + } + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final UnfinishedPotion unf = UnfinishedPotion.forItem(event.getUsedItem(), event.getBaseItem()); + if (unf == null) { + return false; + } + final GenericPotion potion = GenericPotion.transform(unf); + final Player player = event.getPlayer(); + SkillDialogueHandler handler = new SkillDialogueHandler(player, SkillDialogue.ONE_OPTION, potion.getProduct()) { + @Override + public void create(final int amount, int index) { + player.getPulseManager().run(new HerblorePulse(player, potion.getBase(), amount, potion)); + } + + @Override + public int getAll(int index) { + return player.getInventory().getAmount(potion.getBase()); + } + + }; + if (player.getInventory().getAmount(potion.getBase()) == 1) { + handler.create(0, 1); + } else { + handler.open(); + } + return true; + } + +} diff --git a/Server/src/main/content/global/skill/hunter/BoxTrapNode.java b/Server/src/main/content/global/skill/hunter/BoxTrapNode.java new file mode 100644 index 0000000..1297020 --- /dev/null +++ b/Server/src/main/content/global/skill/hunter/BoxTrapNode.java @@ -0,0 +1,37 @@ +package content.global.skill.hunter; + +import core.game.node.entity.skill.Skills; +import core.game.node.entity.npc.NPC; +import core.game.node.item.Item; + +/** + * Handles the box trap node. + * @author Vexia + */ +public class BoxTrapNode extends TrapNode { + + /** + * The summoning level required. + */ + private final int summoningLevel; + + /** + * Constructs a new {@code BoxTrapNode} {@code Object}. + * @param npcIds the npc ids. + * @param level the level. + * @param experience the experience. + * @param rewards the rewards. + */ + public BoxTrapNode(int[] npcIds, int level, double experience, Item[] rewards, final int summoningLevel) { + super(npcIds, level, experience, new int[] { 19188, 19189 }, rewards); + this.summoningLevel = summoningLevel; + } + + @Override + public boolean canCatch(TrapWrapper wrapper, final NPC npc) { + if (wrapper.getPlayer().getSkills().getStaticLevel(Skills.SUMMONING) < summoningLevel) { + return false; + } + return super.canCatch(wrapper, npc); + } +} diff --git a/Server/src/main/content/global/skill/hunter/DeadfallSetting.java b/Server/src/main/content/global/skill/hunter/DeadfallSetting.java new file mode 100644 index 0000000..56202d3 --- /dev/null +++ b/Server/src/main/content/global/skill/hunter/DeadfallSetting.java @@ -0,0 +1,170 @@ +package content.global.skill.hunter; + +import content.global.skill.firemaking.Log; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; + +import java.util.ArrayList; +import java.util.List; + +/** + * Handles a deadfall trap. + * @author Vexia + */ +public final class DeadfallSetting extends TrapSetting { + + /** + * Constructs a new {@code DeadfallSetting} {@code Object}. + */ + public DeadfallSetting() { + super(new int[] { 28935, 19205 }, + new Item[] { new Item(946) }, + new int[] { 28937, 19206 }, + new int[] { 10138, 6006, 12574, 341, 2132 }, + "set-trap", 23, -1, new Animation(5208), new Animation(9726), true); + } + + @Override + public boolean hasItems(Player player) { + if (!super.hasItems(player)) { + player.getPacketDispatch().sendMessage("You need a knife in order to set a deadfall trap."); + return false; + } + for (Log log : Log.values()) { + if (player.getInventory().contains(log.getLogId(), 1)) { + return true; + } + } + player.getPacketDispatch().sendMessage("You need logs in order to set a deadfall trap."); + return false; + } + + @Override + public TrapHook createHook(TrapWrapper wrapper) { + return new TrapHook(wrapper, getLocations(wrapper.getObject()).toArray(new Location[] {})); + } + + @Override + public void reward(Player player, Node node, TrapWrapper wrapper) { + player.getInventory().remove(new Item(getLog(player).getLogId())); + } + + @Override + public boolean clear(TrapWrapper wrapper, int type) { + if (super.clear(wrapper, type)) { + SceneryBuilder.add(wrapper.getObject().transform(getNodeForObjectId(wrapper.isCaught() ? wrapper.getOriginalId() : wrapper.getObject().getId()))); + return true; + } + return false; + } + + @Override + public boolean canCatch(TrapWrapper wrapper, NPC npc) { + int x = wrapper.getObject().getLocation().getX(), y = wrapper.getObject().getLocation().getY(); + Direction direction = wrapper.getObject().getDirection(); + int dir = 0; + if (direction == Direction.NORTH) { + if (npc.getLocation().getY() < y) { + dir = 1; + } else { + dir = 0; + } + } else if (direction == Direction.SOUTH) { + if (npc.getLocation().getY() < y) { + dir = 0; + } else { + dir = 1; + } + } else if (direction == Direction.WEST) { + if (npc.getLocation().getX() > x) { + dir = 1; + } else { + dir = 0; + } + } else { + if (npc.getLocation().getX() > x) { + dir = 0; + } else { + dir = 1; + } + } + npc.faceLocation(wrapper.getObject().getLocation()); + wrapper.getObject().getAttributes().setAttribute("kebbit-dir", dir); + return true; + } + + @Override + public boolean isSuccess(Player player, final TrapNode node) { + return true; + } + + @Override + public int getTransformId(TrapWrapper wrapper, TrapNode node) { + int dir = wrapper.getObject().getAttributes().getAttribute("kebbit-dir", 0); + int id = dir == 0 ? node.getObjectIds()[0] : node.getObjectIds()[1]; + return id; + } + + @Override + public int getFinalId(TrapWrapper wrapper, TrapNode node) { + return node.getObjectIds()[2]; + } + + @Override + public Scenery buildObject(Player player, Node node) { + return node.asScenery().transform(getObjectForNode(node)); + } + + @Override + public String getLimitMessage(Player player) { + return "You can only have one deadfall trap at a time."; + } + + @Override + public boolean exceedsLimit(Player player) { + return HunterManager.getInstance(player).getTrapAmount() > 0; + } + + /** + * Gets the list of locations. + * @return the locations. + */ + private List getLocations(Scenery object) { + List locs = new ArrayList<>(20); + if (object.getDirection() == Direction.NORTH) { + locs.add(object.getLocation().transform(1, -1, 0)); + locs.add(object.getLocation().transform(1, 1, 0)); + } else if (object.getDirection() == Direction.SOUTH) { + locs.add(object.getLocation().transform(0, 1, 0)); + locs.add(object.getLocation().transform(0, -1, 0)); + } else if (object.getDirection() == Direction.WEST) { + locs.add(object.getLocation().transform(1, 1, 0)); + locs.add(object.getLocation().transform(-1, 1, 0)); + } else { + locs.add(object.getLocation().transform(-1, 0, 0)); + locs.add(object.getLocation().transform(1, 0, 0)); + } + return locs; + } + + /** + * Gets the log the player has. + * @param player the player. + * @return the log. + */ + private Log getLog(Player player) { + for (Log log : Log.values()) { + if (player.getInventory().contains(log.getLogId(), 1)) { + return log; + } + } + return null; + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/hunter/FalconryActivityPlugin.java b/Server/src/main/content/global/skill/hunter/FalconryActivityPlugin.java new file mode 100644 index 0000000..a3e8c2c --- /dev/null +++ b/Server/src/main/content/global/skill/hunter/FalconryActivityPlugin.java @@ -0,0 +1,216 @@ +package content.global.skill.hunter; + +import content.global.skill.hunter.falconry.FalconryCatchPulse; +import core.cache.def.impl.ItemDefinition; +import core.cache.def.impl.NPCDefinition; +import core.game.activity.ActivityPlugin; +import core.game.node.entity.skill.Skills; +import content.global.skill.hunter.falconry.FalconCatch; +import core.game.interaction.Option; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.HintIconManager; +import core.game.node.item.Item; +import core.game.world.map.Location; +import core.game.world.map.zone.ZoneBorders; +import core.plugin.Plugin; +import core.plugin.ClassScanner; + +/** + * Represents the activity used during falconry practice. + * @author Vexia + */ +public final class FalconryActivityPlugin extends ActivityPlugin { + + /** + * Constructs a new {@code FalconryActivityPlugin} {@code Object}. + */ + public FalconryActivityPlugin() { + this(null); + } + + /** + * Constructs a new {@code FalconryActivityPlugin} {@code Object}. + * @param player the player. + */ + public FalconryActivityPlugin(final Player player) { + super("falconry", true, false, false); + this.player = player; + } + + @Override + public ActivityPlugin newInstance(Player p) throws Throwable { + return new FalconryActivityPlugin(p); + } + + @Override + public boolean start(final Player player, boolean login, Object... args) { + player.setAttribute("/save:falconry", true); + return super.start(player, login, args); + } + + @Override + public boolean leave(final Entity entity, boolean logout) { + if (!(entity instanceof Player)) { + return super.leave(entity, logout); + } + if (entity instanceof Player) { + if (!logout) { + ((Player) entity).removeAttribute("falconry"); + removeItems((Player) entity); + } + } + return super.leave(entity, logout); + } + + /** + * Method used to remove the items. + */ + public static void removeItems(final Player player) { + player.getInventory().remove(new Item(10023, player.getInventory().getAmount(new Item(10023)))); + player.getInventory().remove(new Item(10024, player.getInventory().getAmount(new Item(10024)))); + player.getEquipment().remove(new Item(10023)); + player.getEquipment().remove(new Item(10024)); + } + + @Override + public boolean teleport(final Entity entity, int type, Node node) { + removeItems((Player) entity); + return true; + } + + @Override + public boolean interact(final Entity e, Node target, Option option) { + return false; + } + + @Override + public Location getSpawnLocation() { + return null; + } + + @Override + public void configure() { + register(new ZoneBorders(2360, 3571, 2396, 3637)); + } + + @Override + public void register() { + ClassScanner.definePlugin(new FalconryPlugin()); + } + + /** + * Represents the falconry plugin. + * @author Vexia + */ + public static final class FalconryPlugin extends OptionHandler { + + /** + * Represents the bones. + */ + private static final Item BONES = new Item(526); + + /** + * Represents the falcon item. + */ + private static final Item FALCON = new Item(10024); + + /** + * Represents the falcon glove. + */ + private static final Item GLOVE = new Item(10023); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + NPCDefinition.forId(5093).getHandlers().put("option:quick-falconry", this); + NPCDefinition.forId(5094).getHandlers().put("option:retrieve", this); + for (FalconCatch falconCatch : FalconCatch.values()) { + NPCDefinition.forId(falconCatch.getNpc()).getHandlers().put("option:catch", this); + } + ClassScanner.definePlugin(new Plugin() { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ItemDefinition.forId(10024).getHandlers().put("equipment", this); + ItemDefinition.forId(10023).getHandlers().put("equipment", this); + return this; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + final Player player = (Player) args[0]; + switch (identifier) { + case "unequip": + if (player.getZoneMonitor().isInZone("falconry")) { + player.getDialogueInterpreter().sendDialogue("Leave the area in order to remove your falcon."); + return false; + } + break; + } + return true; + } + + }); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + switch (option) { + case "quick-falconry": + player.getDialogueInterpreter().open(5093, null, true); + break; + case "catch": + player.face(((NPC) node)); + player.getPulseManager().run(new FalconryCatchPulse(player, ((NPC) node), FalconCatch.forNPC(((NPC) node)))); + break; + case "retrieve": + final NPC npc = ((NPC) node); + if (!npc.getAttribute("falcon:owner", "").equals(player.getUsername())) { + player.getPacketDispatch().sendMessage("This isn't your falcon."); + return true; + } + if (player.getInventory().freeSlots() == 0) { + player.getPacketDispatch().sendMessage("You don't have enough inventory space."); + return true; + } + npc.clear(); + HintIconManager.removeHintIcon(player, 1); + final FalconCatch falconCatch = npc.getAttribute("falcon:catch"); + player.getSkills().addExperience(Skills.HUNTER, falconCatch.getExperience(), true); + player.getPacketDispatch().sendMessage("You retrieve the falcon as well as the fur of the dead kebbit."); + player.getInventory().add(falconCatch.getItem()); + player.getInventory().add(BONES); + if (player.getEquipment().remove(GLOVE)) { + player.getEquipment().add(FALCON, true, false); + } else { + player.getInventory().remove(GLOVE); + player.getInventory().add(FALCON); + } + break; + } + return true; + } + + @Override + public boolean isWalk() { + return false; + } + + @Override + public boolean isWalk(final Player player, Node node) { + if (node instanceof NPC) { + final NPC n = ((NPC) node); + if (n.getId() == 5093 || n.getId() == 5094) { + return true; + } + } + return false; + } + + } + +} diff --git a/Server/src/main/content/global/skill/hunter/HunterGear.java b/Server/src/main/content/global/skill/hunter/HunterGear.java new file mode 100644 index 0000000..ac845fd --- /dev/null +++ b/Server/src/main/content/global/skill/hunter/HunterGear.java @@ -0,0 +1,81 @@ +package content.global.skill.hunter; + +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +/** + * Represents a set of hunter gear. + * @author Vexia + */ +public enum HunterGear { + GLOVE_OF_SILENCE(3.0, new Item(10075)), SPOTIER_CAPE(5.0, new Item(10071)), SPOTTED_CAPE(5.0, new Item(10069)), LARUPIA(10.00, new Item(10045), new Item(10043), new Item(10041)), DESERT_GEAR(10.00, new Item(12568), new Item(10063), new Item(10061)), GRAAHK_GEAR(10.00, new Item(10051), new Item(10047), new Item(10049)), KYATT_GEAR(10.00, new Item(10039), new Item(10035), new Item(10037)), JUNGLE_GEAR(8.00, new Item(10059), new Item(10057)), POLAR_GEAR(8.00, new Item(10065), new Item(10067)); + + /** + * Constructs a new {@code Trap} {@code Object}. + * @param equipment the equipment. + * @param chanceRate the rate. + */ + HunterGear(double chanceRate, Item... equipment) { + this.equipment = equipment; + this.chanceRate = chanceRate; + } + + /** + * Represents the equipment. + */ + private final Item[] equipment; + + /** + * Represents the chance it increased. + */ + private final double chanceRate; + + /** + * Method used to check if the player in the gear. + * @param player the player. + * @return the gear. + */ + public static HunterGear inGear(final Player player) { + int contained = 0; + for (HunterGear type : values()) { + for (Item i : type.getEquipment()) { + if (player.getEquipment().containsItem(i)) { + contained += 1; + } + if (contained == type.getEquipment().length) { + return type; + } + } + } + return null; + } + + /** + * Gets the chance rate the player has. + * @param player the player. + * @return the rate. + */ + public static double getChanceRate(Player player) { + final HunterGear gear = inGear(player); + if (gear == null) { + return 0.0; + } + return gear.getChanceRate(); + } + + /** + * Gets the equipment. + * @return The equipment. + */ + public Item[] getEquipment() { + return equipment; + } + + /** + * Gets the increase. + * @return The increase. + */ + public double getChanceRate() { + return chanceRate; + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/hunter/HunterManager.java b/Server/src/main/content/global/skill/hunter/HunterManager.java new file mode 100644 index 0000000..a026eb0 --- /dev/null +++ b/Server/src/main/content/global/skill/hunter/HunterManager.java @@ -0,0 +1,202 @@ +package content.global.skill.hunter; + +import core.api.LoginListener; +import core.api.LogoutListener; +import core.game.event.EventHook; +import core.game.event.TickEvent; +import core.game.node.entity.Entity; +import core.game.node.entity.skill.Skills; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import org.jetbrains.annotations.NotNull; +import core.api.Event; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * Manages the players hunter state. + * @author Vexia + */ +public final class HunterManager implements LoginListener, LogoutListener, EventHook { + + /** + * The list of active traps. + */ + private final List traps = new ArrayList<>(20); + + /** + * The player instance. + */ + private final Player player; + + /** + * Constructs a new {@code HunterManager} {@code Object}. + * @param player the player. + */ + public HunterManager(final Player player) { + this.player = player; + } + + public HunterManager() { + this.player = null; + } + + @Override + public void login(@NotNull Player player) { + HunterManager instance = new HunterManager(player); + player.hook(Event.getTick(), instance); + player.setAttribute("hunter-manager", instance); + } + + @Override + public void logout(@NotNull Player player) { + HunterManager instance = getInstance(player); + if (instance == null) return; + Iterator iterator = instance.traps.iterator(); + TrapWrapper wrapper = null; + while (iterator.hasNext()) { + wrapper = iterator.next(); + if (wrapper.getType().getSettings().clear(wrapper, 0)) { + iterator.remove(); + } + } + } + + @Override + public void process(@NotNull Entity entity, @NotNull TickEvent event) { + if (traps.size() == 0) { + return; + } + Iterator iterator = traps.iterator(); + TrapWrapper wrapper = null; + while (iterator.hasNext()) { + wrapper = iterator.next(); + if (wrapper.cycle()) { + iterator.remove(); + } + } + } + + /** + * Register a hunting trap. + * @param trap the trap. + * @param node the node. + * @param object the object. + * @return {@code True} if registered. + */ + public boolean register(Traps trap, Node node, final Scenery object) { + final TrapWrapper wrapper = new TrapWrapper(player, trap, object); + trap.getSettings().reward(player, node, wrapper); + wrapper.setHook(trap.addHook(wrapper)); + return traps.add(wrapper); + } + + /** + * Removes the wrapper from the registar. + * @param wrapper the wrapper. + * @return {@code True} if so. + */ + public boolean deregister(final TrapWrapper wrapper) { + return traps.remove(wrapper); + } + + /** + * Checks if they're the owner of the trap. + * @param object the object. + * @return {@code True} if they're the owner. + */ + public boolean isOwner(Scenery object) { + return getUid(object) == getUid(); + } + + /** + * Gets the wrapper. + * @param object the object. + * @return the wrapper. + */ + public TrapWrapper getWrapper(Scenery object) { + for (TrapWrapper wrapper : traps) { + if (wrapper.getObject() == object || (wrapper.getSecondary() != null && wrapper.getSecondary() == object)) { + return wrapper; + } + } + return null; + } + + /** + * Checks if the player exceeds the trap limit. + * @return {@code True} if so. + */ + public boolean exceedsTrapLimit(Traps trap) { + if (trap.getSettings().exceedsLimit(player)) { + return true; + } + return traps.size() + 1 > getMaximumTraps(); + } + + /** + * Gets the trap amount. + * @return the trap amount. + */ + public int getTrapAmount() { + return traps.size(); + } + + /** + * Gets the maximum amount of traps. + * @return the traps. + */ + public int getMaximumTraps() { + final int level = getStaticLevel(); + return level >= 80 ? 5 : level >= 60 ? 4 : level >= 40 ? 3 : level >= 20 ? 2 : 1; + } + + /** + * Gets the uid of a trap. + * @param object the object. + * @return the uid. + */ + public int getUid(Scenery object) { + return object.getAttributes().getAttribute("trap-uid", 0); + } + + /** + * Gets the uid of this manager. + * @return the manager. + */ + public int getUid() { + return player.getName().hashCode(); + } + + /** + * Gets the static level. + * @return the level. + */ + public int getStaticLevel() { + return player.getSkills().getStaticLevel(Skills.HUNTER); + } + + /** + * Gets the player. + * @return The player. + */ + public Player getPlayer() { + return player; + } + + /** + * Gets the traps. + * @return The traps. + */ + public List getTraps() { + return traps; + } + + public static HunterManager getInstance(Player player) + { + return player.getAttribute("hunter-manager"); + } +} diff --git a/Server/src/main/content/global/skill/hunter/HunterNPC.java b/Server/src/main/content/global/skill/hunter/HunterNPC.java new file mode 100644 index 0000000..725cdb1 --- /dev/null +++ b/Server/src/main/content/global/skill/hunter/HunterNPC.java @@ -0,0 +1,161 @@ +package content.global.skill.hunter; + +import core.api.ContentAPIKt; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.TeleportManager; +import org.rs09.consts.NPCs; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.tools.RandomFunction; + +import java.util.ArrayList; +import java.util.List; + +import static core.api.ContentAPIKt.getPathableRandomLocalCoordinate; +import static core.api.ContentAPIKt.sendGraphics; + +/** + * Handles a hunter npc. + * @author Vexia + */ +public final class HunterNPC extends AbstractNPC { + + private static final int IMP_TELEPORT_CHANCE_ON_HIT = 10; // 1/10 + private static final int IMP_TELEPORT_CHANCE_ON_TICK = 1000; // 1/75 + + /** + * The trap type. + */ + private final Traps trap; + + /** + * The trap type node. + */ + private final TrapNode type; + + /** + * Constructs a new {@code HunterNPC} {@code Object}. + */ + public HunterNPC() { + this(0, null, null, null); + this.setWalks(true); + } + + /** + * Constructs a new {@code HunterNPC} {@code Object}. + * @param id the id. + * @param location the location. + * @param trap the trap. + * @param type the type. + */ + public HunterNPC(int id, Location location, Traps trap, TrapNode type) { + super(id, location); + this.trap = trap; + this.type = type; + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + Object[] data = Traps.getNode(id); + return new HunterNPC(id, location, (Traps) data[0], (TrapNode) data[1]); + } + + @Override + public void updateLocation(Location last) { + final TrapWrapper wrapper = trap.getByHook(getLocation()); + if (wrapper != null) { + wrapper.getType().catchNpc(wrapper, this); + } + } + + @Override + protected Location getMovementDestination() { + if (trap.getHooks().size() == 0 || RandomFunction.random(170) > 5) { + return super.getMovementDestination(); + } + TrapHook hook = trap.getHooks().get(RandomFunction.random(trap.getHooks().size())); + if (hook == null || !type.canCatch(hook.getWrapper(), this)) { + return super.getMovementDestination(); + } + Location destination = hook.getChanceLocation(); + return destination != null && destination.getDistance(getLocation()) <= 24 ? destination : super.getMovementDestination(); + } + + @Override + public void handleDrops(Player p, Entity killer) { + int ticks = getAttribute("hunter", 0); + if (ticks < GameWorld.getTicks()) { + super.handleDrops(p, killer); + } + } + + @Override + public int[] getIds() { + List ids = new ArrayList<>(10); + for (Traps t : Traps.values()) { + for (TrapNode node : t.getNodes()) { + for (int id : node.getNpcIds()) { + ids.add(id); + } + } + } + int[] array = new int[ids.size()]; + for (int i = 0; i < array.length; i++) { + array[i] = ids.get(i); + } + return array; + } + + @Override + public void checkImpact(BattleState state) { + super.checkImpact(state); + + if (this.getId() == NPCs.IMP_708 || this.getId() == NPCs.IMP_709 || this.getId() == NPCs.IMP_1531) { + if (RandomFunction.roll(IMP_TELEPORT_CHANCE_ON_HIT)) { + getRandomLocAndTeleport(); + } + } + } + + @Override + public void tick() { + super.tick(); + + if (this.getId() == NPCs.IMP_708 || this.getId() == NPCs.IMP_709 || this.getId() == NPCs.IMP_1531) { + if (RandomFunction.roll(IMP_TELEPORT_CHANCE_ON_TICK)) { + getRandomLocAndTeleport(); + } + } + } + + /** + * Gets the type. + * @return The type. + */ + public TrapNode getType() { + return type; + } + + /** + * Gets the trap. + * @return The trap. + */ + public Traps getTrap() { + return trap; + } + + /** + * Used to teleport imps + */ + private void getRandomLocAndTeleport() { + Location teleportLocation = getPathableRandomLocalCoordinate(this, walkRadius, getProperties().getSpawnLocation(), 3); + + if (getLocation() != teleportLocation) { + sendGraphics(1119, getLocation()); + ContentAPIKt.teleport(this, teleportLocation, TeleportManager.TeleportType.INSTANT); + } + } +} diff --git a/Server/src/main/content/global/skill/hunter/HunterPlugin.java b/Server/src/main/content/global/skill/hunter/HunterPlugin.java new file mode 100644 index 0000000..b434c22 --- /dev/null +++ b/Server/src/main/content/global/skill/hunter/HunterPlugin.java @@ -0,0 +1,317 @@ +package content.global.skill.hunter; + +import content.global.skill.hunter.bnet.BNetNode; +import content.global.skill.hunter.bnet.BNetTypes; +import content.global.skill.hunter.bnet.ImplingNode; +import core.cache.def.Definition; +import core.cache.def.impl.ItemDefinition; +import core.cache.def.impl.NPCDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.plugin.Initializable; +import content.global.skill.hunter.NetTrapSetting.NetTrap; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.OptionHandler; +import core.game.interaction.UseWithHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItem; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; +import core.plugin.ClassScanner; + +import java.util.ArrayList; +import java.util.List; + +/** + * Handles the hunter skill. + * @author Vexia + */ +@Initializable +public final class HunterPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + Definition definition = null; + for (Traps trap : Traps.values()) { + for (int nodeId : trap.getSettings().getNodeIds()) { + definition = trap.getSettings().isObjectTrap() ? SceneryDefinition.forId(nodeId) : ItemDefinition.forId(nodeId); + definition.getHandlers().put("option:" + trap.getSettings().getOption(), this); + } + if (trap.getSettings().getFailId() != -1) { + definition = SceneryDefinition.forId(trap.getSettings().getFailId()); + definition.getHandlers().put("option:dismantle", this); + definition.getHandlers().put("option:deactivate", this); + } + for (int objectId : trap.getSettings().getObjectIds()) { + definition = SceneryDefinition.forId(objectId); + definition.getHandlers().put("option:deactivate", this); + definition.getHandlers().put("option:dismantle", this); + definition.getHandlers().put("option:investigate", this); + } + for (TrapNode node : trap.getNodes()) { + for (int objectId : node.getObjectIds()) { + definition = SceneryDefinition.forId(objectId); + definition.getHandlers().put("option:check", this); + definition.getHandlers().put("option:retrieve", this); + } + } + } + for (NetTrap trap : NetTrap.values()) { + SceneryDefinition.forId(trap.getBent()).getHandlers().put("option:dismantle", this); + SceneryDefinition.forId(trap.getFailed()).getHandlers().put("option:dismantle", this); + SceneryDefinition.forId(trap.getNet()).getHandlers().put("option:dismantle", this); + SceneryDefinition.forId(trap.getCaught()).getHandlers().put("option:check", this); + SceneryDefinition.forId(trap.getBent()).getHandlers().put("option:investigate", this); + SceneryDefinition.forId(trap.getFailed()).getHandlers().put("option:investigate", this); + SceneryDefinition.forId(trap.getNet()).getHandlers().put("option:investigate", this); + } + ClassScanner.definePlugin(new HunterNPC()); + ClassScanner.definePlugin(new HunterNetPlugin()); + ClassScanner.definePlugin(new HunterItemPlugin()); + ClassScanner.definePlugin(new FalconryActivityPlugin()); + ClassScanner.definePlugin(new HuntingItemUseWithHandler()); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + final Traps trap = Traps.forNode(node); + switch (option) { + case "lay": + case "activate": + case "set-trap": + case "trap": + trap.create(player, node); + return true; + case "dismantle": + case "deactivate": + case "retrieve": + case "check": + trap.dismantle(player, (Scenery) node); + return true; + case "investigate": + trap.investigate(player, (Scenery) node); + return true; + } + return true; + } + + @Override + public Location getDestination(Node node, Node n) { + if (n.getName().startsWith("Bird")) { + if (node.getLocation().equals(n.getLocation())) { + return n.getLocation().transform(node.getDirection(), 1); + } + } + return null; + } + + @Override + public boolean isWalk(Player player, Node node) { + return node instanceof GroundItem || !(node instanceof Item); + } + + @Override + public boolean isWalk() { + return false; + } + + /** + * Handles the usage of an item on a trap. + * @author Vexia + */ + public final static class HuntingItemUseWithHandler extends UseWithHandler { + + /** + * Constructs a new {@code HuntingItemUseWithHandler} {@code Object}. + */ + public HuntingItemUseWithHandler() { + super(getIds()); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (Traps trap : Traps.values()) { + for (int objectId : trap.getSettings().getObjectIds()) { + addHandler(objectId, OBJECT_TYPE, this); + } + } + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + final Scenery object = event.getUsedWith() instanceof Scenery ? (Scenery) event.getUsedWith() : (Scenery) event.getUsed(); + final Item item = event.getUsedItem(); + if (HunterManager.getInstance(player).isOwner(object)) { + player.sendMessage("This isn't your trap!"); + return true; + } + final TrapWrapper wrapper = HunterManager.getInstance(player).getWrapper(object); + if (item.getId() == 594) { + wrapper.smoke(); + } else { + wrapper.bait(item); + } + return true; + } + + /** + * Gets the ids to be used. + * @return the ids. + */ + public static int[] getIds() { + List list = new ArrayList<>(10); + for (Traps trap : Traps.values()) { + for (int id : trap.getSettings().getBaitIds()) { + list.add(id); + } + } + list.add(594); + int[] array = new int[list.size()]; + for (int i = 0; i < array.length; i++) { + array[i] = list.get(i); + } + return array; + } + + } + + /** + * Handles a hunter item plugin. + * @author Vexia + */ + public static final class HunterItemPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ItemDefinition.setOptionHandler("release", this); + for (int i = BNetTypes.BABY_IMPLING.ordinal() - 1; i < BNetTypes.values().length; i++) { + BNetTypes.values()[i].getNode().getReward().getDefinition().getHandlers().put("option:loot", this); + } + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + switch (option) { + case "release": + ReleaseType type = ReleaseType.forId(node.getId()); + if (type != null) { + type.release(player, (Item) node); + } + break; + case "loot": + ((ImplingNode) BNetTypes.forItem((Item) node)).loot(player, (Item) node); + break; + } + return true; + } + + @Override + public boolean isWalk() { + return false; + } + + /** + * A release type. + * @author Vexia + */ + public enum ReleaseType { + TRAPS(10033, 10034, 10092, 10146, 10147, 10148, 10149), BUTTERFLY(10020, 10018, 10016, 10014) { + @Override + public void release(final Player player, final Item item) { + BNetNode node = BNetTypes.forItem(item); + if (player.getInventory().remove(item)) { + player.animate(Animation.create(5213)); + player.getInventory().add(new Item(10012)); + player.graphics(node.getGraphics()[1]); + } + } + }; + + /** + * The ids of the item. + */ + private final int[] ids; + + /** + * Constructs a new {@code ReleaseType} {@code Object}. + * @param ids the ids. + */ + private ReleaseType(int... ids) { + this.ids = ids; + } + + /** + * Releases an item. + * @param player the player. + * @param item the item. + */ + public void release(final Player player, final Item item) { + boolean multiple = item.getAmount() > 1; + player.getInventory().remove(item); + player.sendMessage("You release the " + item.getName().toLowerCase() + (multiple ? "s" : "") + " and " + (multiple ? "they" : "it") + " bound" + (!multiple ? "s" : "") + " away."); + } + + /** + * Handles a release type. + * @param id the id. + * @return the type. + */ + public static ReleaseType forId(int id) { + for (ReleaseType type : values()) { + for (int i : type.getIds()) { + if (i == id) { + return type; + } + } + } + return null; + } + + /** + * Gets the ids. + * @return The ids. + */ + public int[] getIds() { + return ids; + } + } + } + + /** + * Handles the catching of a hunter npc with a net. + * @author Vexia + */ + public static final class HunterNetPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (BNetTypes type : BNetTypes.values()) { + for (int id : type.getNode().getNpcs()) { + NPCDefinition.forId(id).getHandlers().put("option:catch", this); + } + } + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + BNetTypes type = BNetTypes.forNpc((NPC) node); + if (type == null) { + player.sendMessage("There seems to be something wrong with this catch option."); + player.sendMessage("Please submit a detailed bug report on gitlab."); + return true; + } + type.handle(player, (NPC) node); + return true; + } + + } +} diff --git a/Server/src/main/content/global/skill/hunter/ImpBoxPlugin.java b/Server/src/main/content/global/skill/hunter/ImpBoxPlugin.java new file mode 100644 index 0000000..800e342 --- /dev/null +++ b/Server/src/main/content/global/skill/hunter/ImpBoxPlugin.java @@ -0,0 +1,174 @@ +package content.global.skill.hunter; + +import core.cache.def.impl.ItemDefinition; +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.plugin.Initializable; +import core.game.dialogue.DialogueInterpreter; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.net.packet.PacketRepository; +import core.net.packet.context.ContainerContext; +import core.net.packet.out.ContainerPacket; +import core.plugin.Plugin; +import core.plugin.ClassScanner; +import core.tools.RandomFunction; + +/** + * Handles the imp box. + * @author Taylor + */ +@Initializable +public class ImpBoxPlugin extends OptionHandler { + + /** + * The item ids. + */ + private static final int[] IDS = new int[] { 10028, 10027 }; + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ClassScanner.definePlugin(new ImpInterfaceHandler(null)); + for (int id : IDS) { + ItemDefinition.forId(id).getHandlers().put("option:bank", this); + ItemDefinition.forId(id).getHandlers().put("option:talk-to", this); + } + ClassScanner.definePlugin(new ImpBoxDialogue()); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + switch (option) { + case "bank": + Component component = new Component(478); + component.setPlugin(new ImpInterfaceHandler((Item) node)); + player.getInterfaceManager().open(component); + PacketRepository.send(ContainerPacket.class, new ContainerContext(player, 478, 61, 91, player.getInventory(), true)); + break; + case "talk-to": + player.getDialogueInterpreter().open("imp-box"); + break; + } + return true; + } + + @Override + public boolean isWalk() { + return false; + } + + /** + * Handles talk-to dialogue on the imp box. + * @author Taylor + */ + public static class ImpBoxDialogue extends DialoguePlugin { + + /** + * The messages to send. + */ + private static final String[] MESSAGES = { "Let me outa here!", "Errgghh..", "Well look who it is.", "What are you looking at?" }; + + /** + * Constructs a new {@code ImpBoxDialogue} {@code Object}. + */ + public ImpBoxDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code ImpBoxDialogue} {@code Object}. + * @param player The player. + */ + public ImpBoxDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new ImpBoxDialogue(player); + } + + @Override + public boolean open(Object... args) { + interpreter.sendDialogues(708, FacialExpression.FURIOUS, MESSAGES[RandomFunction.getRandom(MESSAGES.length - 1)]); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + end(); + return true; + } + + @Override + public int[] getIds() { + return new int[] { DialogueInterpreter.getDialogueKey("imp-box") }; + } + + } + + /** + * Handles the imp interface. + * @author Taylor + */ + public class ImpInterfaceHandler extends ComponentPlugin { + + /** + * The message to show when the imp is gone. + */ + private static final String FINISHING_MESSAGE = "The imp teleports away, taking the item to your bank account."; + + /** + * The box the player is using. + */ + private Item box; + + /** + * Constructs a new {@code ImpInterfaceHandler} {@code Object}. + * @param box The box the player is using. + */ + public ImpInterfaceHandler(Item box) { + this.box = box; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.forId(478).setPlugin(this); + return this; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + Item item = player.getInventory().get(slot); + if (item != null) { + if (player.getBank().canAdd(item) && item.getId() != box.getId()) { + player.getDialogueInterpreter().close(); + player.getInventory().remove(item); + player.getBank().add(item); + PacketRepository.send(ContainerPacket.class, new ContainerContext(player, 478, 61, 91, player.getInventory(), true)); + if (box.getId() == IDS[1]) { + int boxSlot = player.getInventory().getSlot(box); + player.getInventory().replace((box = new Item(IDS[0])), boxSlot); + } else if (box.getId() == IDS[0]) { + int boxSlot = player.getInventory().getSlot(box); + player.getInventory().replace(new Item(10025), boxSlot); + player.getInterfaceManager().close(component); + player.sendMessage(FINISHING_MESSAGE); + } + } + } else { + player.sendMessage("You cannot add this item to your bank."); + return false; + } + return true; + } + } +} diff --git a/Server/src/main/content/global/skill/hunter/MagicBoxSetting.java b/Server/src/main/content/global/skill/hunter/MagicBoxSetting.java new file mode 100644 index 0000000..1992060 --- /dev/null +++ b/Server/src/main/content/global/skill/hunter/MagicBoxSetting.java @@ -0,0 +1,40 @@ +package content.global.skill.hunter; + +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.world.update.flag.context.Animation; + +/** + * Handles the magic box. + * @author Vexia + */ +public final class MagicBoxSetting extends TrapSetting { + + /** + * Constructs a new {@code MagicBoxSetting} {@code Object}. + */ + public MagicBoxSetting() { + super(10025, new int[] { 19223 }, new int[] { 1470, 1472, 1476, 1474 }, "activate", 19224, Animation.create(5208), Animation.create(9726), 27); + } + + @Override + public void handleCatch(int counter, TrapWrapper wrapper, TrapNode node, NPC npc, boolean success) { + switch (counter) { + case 2: + if (success) { + wrapper.getPlayer().getPacketDispatch().sendPositionedGraphic(932, 0, 0, npc.getLocation()); + } + break; + case 3: + npc.moveStep(); + break; + } + } + + @Override + public void addTool(Player player, TrapWrapper wrapper, int type) { + if (!wrapper.isCaught()) { + super.addTool(player, wrapper, type); + } + } +} diff --git a/Server/src/main/content/global/skill/hunter/NetTrapSetting.java b/Server/src/main/content/global/skill/hunter/NetTrapSetting.java new file mode 100644 index 0000000..415f57c --- /dev/null +++ b/Server/src/main/content/global/skill/hunter/NetTrapSetting.java @@ -0,0 +1,301 @@ +package content.global.skill.hunter; + +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; + +import java.util.ArrayList; +import java.util.List; + +/** + * Handles the net trap. + * @author Vexia + */ +public final class NetTrapSetting extends TrapSetting { + + /** + * Constructs a new {@code NetTrapSetting} {@code Object}. + */ + public NetTrapSetting() { + super(new int[] { 19652, 19663, 19671, 19679, 28564 }, new Item[] { new Item(303), new Item(954) }, NetTrap.getIds(), new int[] { 10142, 10143, 10144, 10145 }, "set-trap", 29, -1, new Animation(5215), Animation.create(5207), true); + } + + @Override + public boolean hasItems(Player player) { + if (!super.hasItems(player)) { + player.sendMessage("You need a net and a rope to set a net trap."); + return false; + } + return true; + } + + @Override + public boolean clear(TrapWrapper wrapper, int type) { + if (super.clear(wrapper, type)) { + if (wrapper.getSecondary() != null && wrapper.getSecondary().isActive()) { + SceneryBuilder.remove(wrapper.getSecondary()); + } + SceneryBuilder.add(wrapper.getObject().transform(wrapper.getNetType().getOriginal())); + return true; + } + return false; + } + + @Override + public void returnItems(Scenery object, TrapWrapper wrapper, int type) { + super.returnItems(object, wrapper, type); + if (type == 0) { + for (Item i : super.getItems()) { + createGroundItem(i, object.getLocation(), wrapper.getPlayer()); + } + } + } + + @Override + public void reward(Player player, Node node, TrapWrapper wrapper) { + Scenery object = wrapper.getObject(); + wrapper.setNetType(NetTrap.forId(node.getId())); + int rotation = 0; + int increment = 0; + boolean x = false; + Object[] netInfo = getNetInfo(player, node); + rotation = (int) netInfo[0]; + increment = (int) netInfo[1]; + x = (boolean) netInfo[2]; + Scenery secondary = new Scenery(wrapper.getNetType().getNet(), object.getLocation().transform(x ? increment : 0, !x ? increment : 0, 0), rotation); + secondary = SceneryBuilder.add(secondary); + wrapper.setSecondary(secondary); + player.moveStep(); + wrapper.addItem(getItems()); + player.getInventory().remove(wrapper.getType().getSettings().getItems()); + } + + @Override + public void handleCatch(int counter, TrapWrapper wrapper, TrapNode node, NPC npc, boolean success) { + switch (counter) { + case 2: + SceneryBuilder.remove(wrapper.getSecondary()); + break; + case 3: + npc.moveStep(); + wrapper.setObject(wrapper.getNetType().getFailed()); + break; + } + } + + @Override + public Scenery buildObject(Player player, Node node) { + return ((Scenery) node).transform(NetTrap.forId(node.getId()).getBent()); + } + + @Override + public TrapHook createHook(TrapWrapper wrapper) { + return new TrapHook(wrapper, new Location[] { wrapper.getSecondary().getLocation() }); + } + + @Override + public int getTransformId(TrapWrapper wrapper, TrapNode node) { + return wrapper.getNetType().getCatching(); + } + + @Override + public int getFinalId(TrapWrapper wrapper, TrapNode node) { + return wrapper.getNetType().getCaught(); + } + + @Override + public int getFailId(TrapWrapper wrapper, TrapNode node) { + return wrapper.getNetType().getFailing(); + } + + @Override + public String getTimeUpMessage() { + return "The net trap that you constructed has collapsed."; + } + + /** + * Gets the net info. + * @param player the player. + * @param node the node. + * @return the data. + */ + private Object[] getNetInfo(Player player, Node node) { + int rotation; + int increment; + boolean x = false; + if (player.getLocation().getX() < node.getLocation().getX()) { + rotation = 3; + increment = -1; + x = true; + } else if (player.getLocation().getX() > node.getLocation().getX()) { + rotation = 1; + increment = 1; + x = true; + } else if (player.getLocation().getY() < node.getLocation().getY()) { + rotation = 2; + increment = -1; + } else { + rotation = 0; + increment = 1; + } + return new Object[] { rotation, increment, x }; + } + + /** + * Represents a net trap. + * @author Vexia + */ + public enum NetTrap { + GREEN(19679, 19678, 19676, 19677, 19674, 19675, 19651), SQUIREL(28564, 28563, 28752, 28753, 28750, 28751, 28566), ORANGE(19652, 19650, 19657, 19656, 19655, 19654, 19665), RED(19663, 19662, 19660, 19661, 19658, 19659, 19673), BLACK(19671, 19670, 19668, 19669, 19666, 19667, 19681); + + /** + * Represents the original object id. + */ + private final int original; + + /** + * Represents the bend object id. + */ + private final int bent; + + /** + * Represents the failing object id. + */ + private final int failing; + + /** + * Represents the failed object id. + */ + private final int failed; + + /** + * Represents the catching object id. + */ + private final int catching; + + /** + * Represents the caught object id. + */ + private final int caught; + + /** + * Represents the net. + */ + private final int net; + + /** + * Constructs a new {@code StationaryCatch.java} {@code Object}. + * @param original the original. + * @param bent the bent. + * @param failing the failing. + * @param failed the failed. + * @param catching the catching. + * @param caught the caught. + * @param net the net. + */ + NetTrap(int original, int bent, int failing, int failed, int catching, int caught, int net) { + this.original = original; + this.bent = bent; + this.failing = failing; + this.failed = failed; + this.catching = catching; + this.caught = caught; + this.net = net; + } + + /** + * Gets the net trap for the id. + * @param id the id. + * @return the trap. + */ + public static NetTrap forId(int id) { + for (NetTrap trap : values()) { + if (trap.getOriginal() == id) { + return trap; + } + } + return null; + } + + /** + * Gets the id. + * @return the array. + */ + public static int[] getIds() { + List ids = new ArrayList<>(10); + for (NetTrap trap : NetTrap.values()) { + ids.add(trap.getBent()); + ids.add(trap.getCaught()); + ids.add(trap.getNet()); + ids.add(trap.getOriginal()); + } + int[] array = new int[ids.size()]; + for (int i = 0; i < array.length; i++) { + array[i] = ids.get(i); + } + return array; + } + + /** + * Gets the original. + * @return The original. + */ + public int getOriginal() { + return original; + } + + /** + * Gets the bent. + * @return The bent. + */ + public int getBent() { + return bent; + } + + /** + * Gets the failed. + * @return The failed. + */ + public int getFailed() { + return failed; + } + + /** + * Gets the catching. + * @return The catching. + */ + public int getCatching() { + return catching; + } + + /** + * Gets the caught. + * @return The caught. + */ + public int getCaught() { + return caught; + } + + /** + * Gets the failing. + * @return The failing. + */ + public int getFailing() { + return failing; + } + + /** + * Gets the net. + * @return The net. + */ + public int getNet() { + return net; + } + + } +} diff --git a/Server/src/main/content/global/skill/hunter/TrapCreatePulse.java b/Server/src/main/content/global/skill/hunter/TrapCreatePulse.java new file mode 100644 index 0000000..dddc84e --- /dev/null +++ b/Server/src/main/content/global/skill/hunter/TrapCreatePulse.java @@ -0,0 +1,173 @@ +package content.global.skill.hunter; + +import core.game.node.entity.skill.SkillPulse; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.entity.skill.Skills; +import core.game.node.item.GroundItem; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.*; + +/** + * Handles the trap creating pulse. + * @author Vexia + */ +public final class TrapCreatePulse extends SkillPulse { + + /** + * The starting location of the trap. + */ + private final Location startLocation; + + /** + * The ground item of the trap. + */ + private GroundItem groundItem; + + /** + * The trap type. + */ + private final Traps trap; + + /** + * The amounts of ticks passed. + */ + private int ticks; + + private final HunterManager instance; + + /** + * Constructs a new {@code TrapCreatePulse} {@code Object}. + * @param player the player. + * @param node the node. + * @param trap the trap. + */ + public TrapCreatePulse(Player player, Node node, Traps trap) { + super(player, node); + this.trap = trap; + this.startLocation = node instanceof GroundItem ? node.getLocation() : player.getLocation(); + this.instance = HunterManager.getInstance(player); + if (checkRequirements()){ + switch(trap) { + case BIRD_SNARE: + playAudio(player, Sounds.HUNTING_SETNOOSE_2646, 40); + break; + case BOX_TRAP: + playAudio(player, Sounds.HUNTING_LAYBOXTRAP_2636, 20); + break; + case NET_TRAP: + lock(player, 3); + playAudio(player, Sounds.HUNTING_SET_TWITCHNET_2644); + break; + case RABBIT_SNARE: + playAudio(player, Sounds.HUNTING_SETSNARE_2647); + break; + case DEAD_FALL: + lock(player, 6); + playAudio(player, Sounds.HUNTING_SETDEADFALL_2645, 130); + } + } + } + + @Override + public boolean checkRequirements() { + if (player.skills.getStaticLevel(Skills.HUNTER) < trap.getSettings().getLevel()) { + player.sendMessage("You need a Hunter level of at least " + trap.getSettings().getLevel() + " in order to setup a " + node.getName().toLowerCase() + "."); + return false; + } + if (instance.exceedsTrapLimit(trap)) { + player.sendMessage(trap.getSettings().getLimitMessage(player)); + return false; + } + if (RegionManager.getObject(player.getLocation()) != null) { + player.sendMessage("You can't lay a trap here."); + return false; + } + if (!player.getLocation().equals(startLocation)) { + return false; + } + if (trap.getSettings().isObjectTrap() && !trap.getSettings().hasItems(player)) { + return false; + } + return true; + } + + @Override + public void animate() { + if (ticks < 1) { + player.getAnimator().forceAnimation(trap.getSettings().getSetupAnimation()); + } + } + + @Override + public boolean reward() { + if (++ticks % (trap.getSettings().getSetupAnimation().getDefinition().getDurationTicks()) != 0) { + return false; + } + Scenery object = trap.getSettings().buildObject(player, node); + if (isGroundSetup() || groundItem != null) { + GroundItemManager.destroy(groundItem); + } + if (!trap.getSettings().isObjectTrap()) { + player.moveStep(); + } else { + SceneryBuilder.remove(node.asScenery()); + } + object = SceneryBuilder.add(object); + instance.register(trap, node, object); + return true; + } + + @Override + public void message(int type) { + switch (type) { + case 0: + setUp(); + player.getPacketDispatch().sendMessage("You begin setting up the trap."); + break; + } + } + + /** + * Sets up the trap. + */ + private void setUp() { + player.lock(1); + player.getWalkingQueue().reset(); + if (trap.getSettings().isObjectTrap()) { + + } else { + if (!isGroundSetup()) { + if (player.getInventory().remove((Item) node)) { + groundItem = new GroundItem((Item) node, player.getLocation(), player); + GroundItemManager.create(groundItem); + } + return; + } + groundItem = (GroundItem) node; + } + } + + /** + * If we're setting it up from the ground. + * @return {@code True} if so. + */ + public boolean isGroundSetup() { + return node instanceof GroundItem; + } + + /** + * Gets the trap. + * @return The trap. + */ + public Traps getTrap() { + return trap; + } +} diff --git a/Server/src/main/content/global/skill/hunter/TrapDismantlePulse.java b/Server/src/main/content/global/skill/hunter/TrapDismantlePulse.java new file mode 100644 index 0000000..0492f93 --- /dev/null +++ b/Server/src/main/content/global/skill/hunter/TrapDismantlePulse.java @@ -0,0 +1,139 @@ +package content.global.skill.hunter; + +import content.data.skill.SkillingPets; +import core.game.node.entity.skill.SkillPulse; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.*; + +/** + * Handles the dismantling of a trap. + * @author Vexia + */ +public final class TrapDismantlePulse extends SkillPulse { + + /** + * The trap wrapper. + */ + private final TrapWrapper wrapper; + + /** + * The trap type. + */ + private final Traps trap; + + /** + * The ticks passed. + */ + private int ticks; + + private final HunterManager instance; + + /** + * Constructs a new {@code TrapDismantlePulse} {@code Object}. + * @param player the player. + * @param node the node. + */ + public TrapDismantlePulse(Player player, Scenery node, final TrapWrapper wrapper) { + super(player, node); + this.trap = wrapper.getType(); + this.wrapper = wrapper; + this.instance = HunterManager.getInstance(player); + if (checkRequirements()){ + switch(trap) { + case BIRD_SNARE: + lock(player,5); + playAudio(player, Sounds.HUNTING_DISMANTLE_2632, 50); + break; + case BOX_TRAP: + lock(player,4); + playAudio(player, Sounds.HUNTING_DISMANTLE_2632, 50); + break; + case NET_TRAP: + lock(player, 5); + playAudio(player, Sounds.HUNTING_DISMANTLE_2632, 20); + break; + case RABBIT_SNARE: + case DEAD_FALL: + lock(player, 4); + playAudio(player, Sounds.HUNTING_DISMANTLE_2632, 80); + break; + } + } + } + + @Override + public boolean checkRequirements() { + if (wrapper == null || !instance.isOwner(node)) { + player.sendMessage("This isn't your trap!"); + return false; + } + final int itemCount = wrapper.getItems().size() + (wrapper.getType().getSettings().isObjectTrap() ? 0 : 1); + final int difference = itemCount - player.getInventory().freeSlots(); + if (player.getInventory().freeSlots() < itemCount) { + player.getPacketDispatch().sendMessage("You don't have enough inventory space. You need " + difference + " more free slot" + (difference > 1 ? "s" : "") + "."); + return false; + } + return true; + } + + @Override + public void animate() { + if (ticks < 1) { + player.getAnimator().forceAnimation(trap.getSettings().getDismantleAnimation()); + } + } + + @Override + public boolean reward() { + if (++ticks % (trap.getSettings().getDismantleAnimation().getDefinition().getDurationTicks() + 1) != 0) { + return false; + } + if (wrapper.getType().getSettings().clear(wrapper, 1)) { + instance.deregister(wrapper); + if (wrapper.isCaught()) { + if (wrapper.getType().equals(Traps.BOX_TRAP)) { + for (int i : wrapper.getReward().getNpcIds()) { + if (i == 5080 || i == 5079) { + SkillingPets.checkPetDrop(player, i == 5080 ? SkillingPets.BABY_RED_CHINCHOMPA : SkillingPets.BABY_GREY_CHINCHOMPA); + } + } + } + player.getSkills().addExperience(Skills.HUNTER, wrapper.getReward().getExperience(), true); + } + player.getPacketDispatch().sendMessage("You dismantle the trap."); + } + return true; + } + + @Override + public void message(int type) { + switch (type) { + case 0: + int ticks = wrapper.getTicks() + (wrapper.getType().getSettings().getDismantleAnimation().getDefinition().getDurationTicks()) + 1; + wrapper.setTicks(ticks); + wrapper.setBusyTicks(ticks); + break; + } + } + + /** + * Gets the trap. + * @return The trap. + */ + public Traps getTrap() { + return trap; + } + + /** + * Gets the wrapper. + * @return The wrapper. + */ + public TrapWrapper getWrapper() { + return wrapper; + } + +} diff --git a/Server/src/main/content/global/skill/hunter/TrapHook.java b/Server/src/main/content/global/skill/hunter/TrapHook.java new file mode 100644 index 0000000..61e4840 --- /dev/null +++ b/Server/src/main/content/global/skill/hunter/TrapHook.java @@ -0,0 +1,77 @@ +package content.global.skill.hunter; + +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.tools.RandomFunction; + +/** + * A trap location hook. + * @author Vexia + */ +public class TrapHook { + + /** + * The wrapper of the hook. + */ + private final TrapWrapper wrapper; + + /** + * The locations for the trap to trigger. + */ + private final Location[] locations; + + /** + * Constructs a new {@code TrapHook} {@code Object}. + * @param wrapper the wrapper. + * @param locations the locations. + */ + public TrapHook(TrapWrapper wrapper, Location[] locations) { + this.wrapper = wrapper; + this.locations = locations; + } + + /** + * Gets a location by chance for the npc to go to. + * @return the location. + */ + public Location getChanceLocation() { + final double chance = wrapper.getChanceRate(); + final int roll = RandomFunction.random(99); + final double successChance = (GameWorld.getSettings().isDevMode() ? 100 : 55.0) + chance; + if (successChance > roll) { + return RandomFunction.getRandomElement(locations); + } + return null; + } + + /** + * Checks if the trap is hooked. + * @param location the location. + * @return {@code True} if hooked. + */ + public boolean isHooked(Location location) { + for (Location l : locations) { + if (l.equals(location)) { + return true; + } + } + return false; + } + + /** + * Gets the wrapper. + * @return The wrapper. + */ + public TrapWrapper getWrapper() { + return wrapper; + } + + /** + * Gets the locations. + * @return The locations. + */ + public Location[] getLocations() { + return locations; + } + +} diff --git a/Server/src/main/content/global/skill/hunter/TrapNode.java b/Server/src/main/content/global/skill/hunter/TrapNode.java new file mode 100644 index 0000000..ad86087 --- /dev/null +++ b/Server/src/main/content/global/skill/hunter/TrapNode.java @@ -0,0 +1,130 @@ +package content.global.skill.hunter; + +import content.data.skill.SkillingPets; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.skill.Skills; +import core.game.node.item.Item; + +/** + * Represents a node for a trap. + * @author Vexia + */ +public class TrapNode { + + /** + * The npc ids related to the node. + */ + private final int[] npcIds; + + /** + * The level required. + */ + private final int level; + + /** + * The experience received. + */ + private final double experience; + + /** + * The object ids for this node. + */ + private final int[] objectIds; + + /** + * The rewards received. + */ + private final Item[] rewards; + + /** + * Constructs a new {@code TrapNode} {@code Object}. + * @param npcIds the npc ids. + * @param level the level. + * @param experience the experience. + * @param rewards the rewards. + */ + public TrapNode(int[] npcIds, int level, double experience, int[] objectIds, Item[] rewards) { + this.npcIds = npcIds; + this.level = level; + this.experience = experience; + this.objectIds = objectIds; + this.rewards = rewards; + } + + /** + * Has the requirements to catch the node. + * @param wrapper the wrapper. + * @param npc the npc. + * @return {@code True} if so. + * @note Override for quests. + */ + public boolean canCatch(TrapWrapper wrapper, final NPC npc) { + final Player player = wrapper.getPlayer(); + if (wrapper.isCaught() || wrapper.isBusy() || wrapper.isFailed()) { + return false; + } + return player.skills.getStaticLevel(Skills.HUNTER) >= level && !npc.isInvisible(); + } + + /** + * Gets the transform id. + * @return the id. + */ + public int getTransformId() { + return objectIds[0]; + } + + /** + * Gets the final id. + * @return the id. + */ + public int getFinalId() { + return objectIds[1]; + } + + /** + * Gets the npcIds. + * @return The npcIds. + */ + public int[] getNpcIds() { + return npcIds; + } + + /** + * Gets the level. + * @return The level. + */ + public int getLevel() { + return level; + } + + /** + * Gets the experience. + * @return The experience. + */ + public double getExperience() { + return experience; + } + + /** + * Gets the rewards. + * @return The rewards. + */ + public Item[] getRewards() { + return rewards; + } + + /** + * Gets the objectIds. + * @return The objectIds. + */ + public int[] getObjectIds() { + return objectIds; + } + + public SkillingPets getPet() { + return null; + } + +} diff --git a/Server/src/main/content/global/skill/hunter/TrapSetting.java b/Server/src/main/content/global/skill/hunter/TrapSetting.java new file mode 100644 index 0000000..ec0f87b --- /dev/null +++ b/Server/src/main/content/global/skill/hunter/TrapSetting.java @@ -0,0 +1,610 @@ +package content.global.skill.hunter; + +import core.cache.def.impl.ItemDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.skill.Skills; +import core.game.node.item.GroundItem; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.tools.RandomFunction; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playAudio; + +/** + * A setting for a trap type. + * @author Vexia + */ +public class TrapSetting { + + /** + * The node ids to create the trap. + */ + private final int[] nodeIds; + + /** + * The items required. + */ + private final Item[] items; + + /** + * The create option. + */ + private final String option; + + /** + * The level required to set the trap. + */ + private final int level; + + /** + * The setup animation of the trap. + */ + private final Animation setupAnimation; + + /** + * The animation + */ + private final Animation dismantleAnimation; + + /** + * The fail object id. + */ + private final int failId; + + /** + * The corresponding object ids. + */ + private final int[] objectIds; + + /** + * The bait ids. + */ + private final int[] baitIds; + + /** + * If it's an object trap. + */ + private final boolean objectTrap; + + /** + * Constructs a new {@code TrapSetting} {@code Object}. + * @param nodeIds the node ids. + * @param items the items. + * @param level the level. + * @param option the option. + * @param setupAnimation the animation. + * @param objectTrap if an object trap. + */ + public TrapSetting(int[] nodeIds, Item[] items, int[] objectIds, final int[] baitIds, final String option, int level, final int failId, final Animation setupAnimation, final Animation dismantleAnimation, boolean objectTrap) { + this.nodeIds = nodeIds; + this.items = items; + this.objectIds = objectIds; + this.baitIds = baitIds; + this.level = level; + this.option = option; + this.objectTrap = objectTrap; + this.failId = failId; + this.setupAnimation = setupAnimation; + this.dismantleAnimation = dismantleAnimation; + } + + /*** + * Constructs a new {@code TrapSetting} {@code Object}. + * @param nodeId the node id. + * @param items the items. + * @param option the option. + * @param level the level. + * @param objectTrap if an object trap. + */ + public TrapSetting(int nodeId, Item[] items, int[] objectIds, final int[] baitIds, final String option, int level, final int failId, final Animation setupAnimation, final Animation dismantleAnimation, boolean objectTrap) { + this(new int[] { nodeId }, items, objectIds, baitIds, option, level, failId, setupAnimation, dismantleAnimation, objectTrap); + } + + /** + * Constructs a new {@code TrapSetting} {@code Object}. + * @param nodeId the node id. + * @param option the option. + * @param objectIds the ids. + * @param level the level. + */ + public TrapSetting(int nodeId, int[] objectIds, final int[] baitIds, String option, final int failId, final Animation setupAnimation, final Animation dismantleAnimation, int level) { + this(new int[] { nodeId }, objectIds, baitIds, option, level, failId, setupAnimation, dismantleAnimation, false); + } + + /** + * Constructs a new {@code TrapSetting} {@code Object}. + * @param nodeIds the node ids. + * @param option the option. + * @param level the level. + * @param objectTrap the object trap. + */ + public TrapSetting(int[] nodeIds, int[] objectIds, final int[] baitIds, String option, int level, final int failId, final Animation setupAnimation, final Animation dismantleAnimation, boolean objectTrap) { + this(nodeIds, new Item[] { new Item(nodeIds[0]) }, objectIds, baitIds, option, level, failId, setupAnimation, dismantleAnimation, objectTrap); + } + + /** + * Clears the trap. + * @param wrapper the wrapper. + * @param type the clear type (0=groundItems, 1=inventory) + * @return {@code True} if cleared. + */ + public boolean clear(TrapWrapper wrapper, int type) { + Scenery object = wrapper.getObject(); + returnItems(object, wrapper, type); + wrapper.getType().getHooks().remove(wrapper.getHook()); + removeObject(wrapper); + return true; + } + + /** + * Returns the items to the ground or player. + * @param object the object. + * @param wrapper the wrapper. + * @param type the type. + */ + public void returnItems(Scenery object, TrapWrapper wrapper, int type) { + boolean ground = type == 0; + Player player = wrapper.getPlayer(); + if (!isObjectTrap()) { + if (ground) { + createGroundItem(items[0], object.getLocation(), wrapper.getPlayer()); + return; + } + addTool(player, wrapper, type); + player.getInventory().add(wrapper.getItems().toArray(new Item[] {})); + } else { + if (isObjectTrap() && !ground) { + player.getInventory().add(wrapper.getItems().toArray(new Item[] {})); + return; + } + } + } + + /** + * Adds the tool back to the inventory. + * @param player the player. + * @param wrapper the wrapper. + * @param type the type. + */ + public void addTool(Player player, TrapWrapper wrapper, int type) { + player.getInventory().add(items[0]); + } + + /** + * Checks if the player has the required items. + * @param player the player. + * @return {@code True} if so. + */ + public boolean hasItems(Player player) { + for (Item item : items) { + if (!player.getInventory().containsItem(item)) { + return false; + } + } + return true; + } + + /** + * Creates a ground item. + * @param item the item. + * @param location the location. + * @param player the player. + */ + public void createGroundItem(Item item, Location location, Player player) { + GroundItemManager.create(new GroundItem(item, location, player)); + } + + /** + * Removes the object from a wrapper. + * @param wrapper the object. + */ + public boolean removeObject(TrapWrapper wrapper) { + return removeObject(wrapper.getObject()); + } + + /** + * Removes the object from the region. + * @param object the object. + * @return {@code True} if so. + */ + public boolean removeObject(Scenery object) { + return SceneryBuilder.remove(object); + } + + /** + * Builds a scenery. + * @param node the node. + * @return the object. + */ + public Scenery buildObject(Player player, Node node) { + return new Scenery(objectIds[0], player.getLocation()); + } + + /** + * Investigates a trap. + * @param player the player. + * @param object the object. + */ + public void investigate(Player player, Scenery object) { + HunterManager instance = HunterManager.getInstance(player); + if (!instance.isOwner(object)) { + player.sendMessage("This isn't your trap."); + return; + } + TrapWrapper wrapper = instance.getWrapper(object); + player.sendMessage("This trap " + (wrapper.isSmoked() ? "has" : "hasn't") + " been smoked."); + } + + /** + * Catches an npc. + * @param wrapper the wrapper. + * @param npc the npc. + */ + public void catchNpc(final TrapWrapper wrapper, final TrapNode node, final NPC npc) { + final boolean success = isSuccess(wrapper.getPlayer(), node); + int ticks = success ? 3 : 2; + npc.lock(ticks); + wrapper.setBusyTicks(ticks); + npc.getWalkingQueue().reset(); + npc.getPulseManager().clear(); + wrapper.setTicks(wrapper.getTicks() + 4); + GameWorld.getPulser().submit(getCatchPulse(wrapper, node, npc, success)); + } + + /** + * Handles the catch on a pulse. + * @param counter the counter. + * @param wrapper the wrapper. + * @param node the node. + * @param npc the npc. + * @param success the success. + */ + public void handleCatch(int counter, TrapWrapper wrapper, TrapNode node, NPC npc, boolean success) { + } + + /** + * Gets the catch pulse. + * @param wrapper the wrapper. + * @param node the node. + * @param npc the npc. + * @return the pulse. + */ + public Pulse getCatchPulse(final TrapWrapper wrapper, final TrapNode node, final NPC npc, final boolean success) { + final Player player = wrapper.getPlayer(); + wrapper.setFailed(!success); + return new Pulse(1) { + int counter; + + @Override + public boolean pulse() { + switch (++counter) { + case 2: + handleCatch(counter, wrapper, node, npc, success); + if (success) { + int transformId = getTransformId(wrapper, node); + npc.setAttribute("hunter", GameWorld.getTicks() + 6); + npc.finalizeDeath(player); + if (transformId != -1) { + wrapper.setObject(getTransformId(wrapper, node)); + } + npc.getProperties().setTeleportLocation(npc.getProperties().getSpawnLocation()); + break; + } + npc.moveStep(); + wrapper.setObject(getFailId(wrapper, node)); + break; + case 3: + handleCatch(counter, wrapper, node, npc, success); + if (success) { + wrapper.setTicks(GameWorld.getTicks() + 100); + wrapper.setReward(node); + wrapper.setObject(getFinalId(wrapper, node)); + switch(wrapper.getType()) { + case BIRD_SNARE: + playAudio(player, Sounds.HUNTING_NOOSE_2637, 0, 1, wrapper.getObject().getLocation(), 10); + playAudio(player, Sounds.HUNTING_BIRDCAUGHT_2625, 20, 1, wrapper.getObject().getLocation(), 10); + break; + case BOX_TRAP: + playAudio(player, Sounds.HUNTING_BOXTRAP_2627, 0, 1, wrapper.getObject().getLocation(), 10); + break; + case NET_TRAP: + playAudio(player, Sounds.HUNTING_TWITCHNET_2652, 0, 1, wrapper.getObject().getLocation(), 10); + playAudio(player, Sounds.SALAMANDER_HIT_739, 20, 1, wrapper.getObject().getLocation(), 10); + break; + case DEAD_FALL: + playAudio(player, Sounds.HUNTING_DEADFALL_2631, 0, 1, wrapper.getObject().getLocation(), 10); + break; + } + return true; + } + npc.moveStep(); + return true; + } + return false; + } + + }; + } + + /** + * Checks if the catch was successfull. + * @param player the player. + * @param node the node. + * @return {@code True} if so. + */ + public boolean isSuccess(Player player, final TrapNode node) { + double level = player.skills.getStaticLevel(Skills.HUNTER); + double req = node.getLevel(); + double successChance = Math.ceil((level * 50 - req * 17) / req / 3 * 4); + int roll = RandomFunction.random(99); + if (successChance >= roll) { + return true; + } + return false; + } + + /** + * Creates a trap hook. + * @param wrapper the wrapper. + * @return the hook. + */ + public TrapHook createHook(TrapWrapper wrapper) { + return new TrapHook(wrapper, new Location[] { wrapper.getObject().getLocation() }); + } + + /** + * Calles when an object is setup. + * @param player the player. + * @param node the node. + * @param wrapper the wrapper. + */ + public void reward(Player player, Node node, TrapWrapper wrapper) { + + } + + /** + * A global method to check if a catch can be made. + * @param wrapper the wrapper. + * @param npc the npc. + * @return {@code True} if so. + */ + public boolean canCatch(TrapWrapper wrapper, NPC npc) { + return true; + } + + /** + * Checks if the bait corresponds. + * @param bait the bait. + * @return {@code True} if so. + */ + public boolean hasBait(Item bait) { + for (int id : getBaitIds()) { + if (id == bait.getId()) { + return true; + } + } + return false; + } + + /** + * Gets the node for the object. + * @param objectId the object. + * @return the node id. + */ + public int getNodeForObjectId(int objectId) { + return getNodeForObject(getObjectIndex(objectId)); + } + + /** + * Gets the node for the object. + * @param index the index. + * @return the id. + */ + public int getNodeForObject(int index) { + return nodeIds[index]; + } + + /** + * Gets the object id for the node. + * @param node the node. the id. + */ + public int getObjectForNode(Node node) { + return getObjectForNode(getNodeIndex(node)); + } + + /** + * Gets the object id for the node. + * @param index the index. + * @return the id. + */ + public int getObjectForNode(int index) { + return objectIds[index]; + } + + /** + * Gets the node index. + * @param node the node. + * @return the index. + */ + public int getNodeIndex(Node node) { + for (int i = 0; i < nodeIds.length; i++) { + if (node.getId() == nodeIds[i]) { + return i; + } + } + return -1; + } + + /** + * Gets the object index. + * @param objectId the object. + * @return the index. + */ + public int getObjectIndex(int objectId) { + for (int i = 0; i < objectIds.length; i++) { + if (objectId == objectIds[i]) { + return i; + } + } + return -1; + } + + /** + * Gets the transform id. + * @param node the node. + * @param wrapper the object. + * @return the id. + */ + public int getTransformId(TrapWrapper wrapper, TrapNode node) { + return node.getTransformId(); + } + + /** + * Gets the final id. + * @param wrapper the wrapper. + * @param node the node. + * @return the id. + */ + public int getFinalId(TrapWrapper wrapper, TrapNode node) { + return node.getFinalId(); + } + + /** + * Gets the failId. + * @param wrapper the wrapper. + * @param node the node. + * @return The failId. + */ + public int getFailId(TrapWrapper wrapper, TrapNode node) { + return failId; + } + + /** + * Gets the limit message. + * @param player the player. + * @return the message. + */ + public String getLimitMessage(Player player) { + HunterManager instance = HunterManager.getInstance(player); + return "You don't have a high enough Hunter level to set up more than " + instance.getMaximumTraps() + " trap" + (instance.getMaximumTraps() == 1 ? "." : "s."); + } + + /** + * Gets the name of the trap. + * @return the name. + */ + public String getName() { + if (isObjectTrap()) { + return SceneryDefinition.forId(nodeIds[0]).getName().toLowerCase(); + } + return ItemDefinition.forId(nodeIds[0]).getName().toLowerCase(); + } + + /** + * Gets the time up message. + * @return the message. + */ + public String getTimeUpMessage() { + return "The " + getName() + " " + (isObjectTrap() ? "trap that you constructed has collapsed." : "that you laid has fallen over."); + } + + /** + * Checks if adding this trap will exceed the limit. + * @param player the player. + * @return {@code True} if so. + */ + public boolean exceedsLimit(Player player) { + return false; + } + + /** + * Gets the objectTrap. + * @return The objectTrap. + */ + public boolean isObjectTrap() { + return objectTrap; + } + + /** + * Gets the nodeIds. + * @return The nodeIds. + */ + public int[] getNodeIds() { + return nodeIds; + } + + /** + * Gets the items. + * @return The items. + */ + public Item[] getItems() { + return items; + } + + /** + * Gets the option. + * @return The option. + */ + public String getOption() { + return option; + } + + /** + * Gets the level. + * @return The level. + */ + public int getLevel() { + return level; + } + + /** + * Gets the setupAnimation. + * @return The setupAnimation. + */ + public Animation getSetupAnimation() { + return setupAnimation; + } + + /** + * Gets the objectIds. + * @return The objectIds. + */ + public int[] getObjectIds() { + return objectIds; + } + + /** + * Gets the dismantleAnimation. + * @return The dismantleAnimation. + */ + public Animation getDismantleAnimation() { + return dismantleAnimation; + } + + /** + * The fail id. + * @return the id. + */ + public int getFailId() { + return failId; + } + + /** + * Gets the baitIds. + * @return The baitIds. + */ + public int[] getBaitIds() { + return baitIds; + } + +} diff --git a/Server/src/main/content/global/skill/hunter/TrapWrapper.java b/Server/src/main/content/global/skill/hunter/TrapWrapper.java new file mode 100644 index 0000000..4cbe329 --- /dev/null +++ b/Server/src/main/content/global/skill/hunter/TrapWrapper.java @@ -0,0 +1,422 @@ +package content.global.skill.hunter; + +import core.game.node.entity.skill.Skills; +import content.global.skill.hunter.NetTrapSetting.NetTrap; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.world.GameWorld; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; + +import java.util.ArrayList; +import java.util.List; + +/** + * A wrapper class for a trap object. + * @author Vexia + */ +public final class TrapWrapper { + + /** + * The items to be recieved on trap clearing. + */ + private final List items = new ArrayList<>(10); + + /** + * The player instance. + */ + private final Player player; + + /** + * The type of trap. + */ + private final Traps type; + + /** + * The net type if net trapping. + */ + private NetTrap netType; + + /** + * The original object id. + */ + private final int originalId; + + /** + * The object of the trap. + */ + private Scenery object; + + /** + * The secondary scenery. + */ + private Scenery secondary; + + /** + * The trap hook. + */ + private TrapHook hook; + + /** + * The reward of the trap. + */ + private TrapNode reward; + + /** + * If the trap has been smoked. + */ + private boolean smoked; + + /** + * If the trap has been baited. + */ + private boolean baited; + + /** + * If the trap has failed. + */ + private boolean failed; + + /** + * If the trap is currently in an reward. + */ + private int busyTicks; + + /** + * The tick when the life is up. + */ + private int ticks; + + private HunterManager instance; + + /** + * Constructs a new {@code TrapWrapper} {@code Object}. + * @param player the player. + * @param type the type. + * @param object the object. + */ + public TrapWrapper(final Player player, Traps type, Scenery object) { + this.player = player; + this.type = type; + this.object = object; + this.originalId = object.getId(); + this.ticks = GameWorld.getTicks() + (100); + this.instance = HunterManager.getInstance(player); + this.object.getAttributes().setAttribute("trap-uid", instance.getUid()); + } + + /** + * Cycles this trap wrapper. + * @return {@code True} to deregister the trap. + */ + public boolean cycle() { + if (isTimeUp() && type.getSettings().clear(this, 0)) { + if (!isCaught()) { + player.sendMessage(type.getSettings().getTimeUpMessage()); + } + return true; + } + return false; + } + + /** + * Sets the new object of the wrapper. + * @param id the id. + */ + public void setObject(final int id) { + Scenery newObject = object.transform(id); + SceneryBuilder.remove(object); + this.object = SceneryBuilder.add(newObject); + this.object.getAttributes().setAttribute("trap-uid", instance.getUid()); + } + + /** + * Smokes the trap. + */ + public void smoke() { + if (smoked) { + player.sendMessage("This trap has already been smoked."); + return; + } + if (player.skills.getStaticLevel(Skills.HUNTER) < 39) { + player.sendMessage("You need a Hunter level of at least 39 to be able to smoke traps."); + return; + } + smoked = true; + player.lock(4); + player.visualize(new Animation(5208), new Graphics(931)); + player.sendMessage("You use the smoke from the torch to remove your scent from the trap."); + } + + /** + * Baits the trap. + */ + public void bait(Item bait) { + if (baited) { + player.sendMessage("This trap has already been baited."); + return; + } + if (!type.getSettings().hasBait(bait)) { + player.sendMessage("You can't use that on this trap."); + return; + } + baited = true; + bait = new Item(bait.getId(), 1); + player.getInventory().remove(new Item(bait.getId(), 1)); + } + + /** + * Gets the chance ratio of luring. + * @return the chance rate. + */ + public double getChanceRate() { + double chance = 0.0; + if (baited) { + chance += 1.0; + } + if (smoked) { + chance += 1.0; + } + chance += HunterGear.getChanceRate(player); + return chance; + } + + /** + * Adds items to the recieved list. + * @param items the items. + */ + public void addItem(Item... items) { + for (Item item : items) { + addItem(item); + } + } + + /** + * Adds an item to the recieved list. + * @param item the item. + */ + public void addItem(Item item) { + items.add(item); + } + + /** + * Checks if the time is up. + * @return {@code True} if o. + */ + private boolean isTimeUp() { + return ticks < GameWorld.getTicks(); + } + + /** + * Gets the type. + * @return The type. + */ + public Traps getType() { + return type; + } + + /** + * Gets the object. + * @return The object. + */ + public Scenery getObject() { + return object; + } + + /** + * The original id. + * @return the id. + */ + public int getOriginalId() { + return originalId; + } + + /** + * Gets the player. + * @return The player. + */ + public Player getPlayer() { + return player; + } + + /** + * Gets the ticks. + * @return The ticks. + */ + public int getTicks() { + return ticks; + } + + /** + * Sets the ticks. + * @param ticks The ticks to set. + */ + public void setTicks(int ticks) { + this.ticks = ticks; + } + + /** + * Gets the smoked. + * @return The smoked. + */ + public boolean isSmoked() { + return smoked; + } + + /** + * Sets the smoked. + * @param smoked The smoked to set. + */ + public void setSmoked(boolean smoked) { + this.smoked = smoked; + } + + /** + * Gets the hook. + * @return The hook. + */ + public TrapHook getHook() { + return hook; + } + + /** + * Sets the hook. + * @param hook The hook to set. + */ + public void setHook(TrapHook hook) { + this.hook = hook; + } + + /** + * Gets the baited. + * @return The baited. + */ + public boolean isBaited() { + return baited; + } + + /** + * Sets the baited. + * @param baited The baited to set. + */ + public void setBaited(boolean baited) { + this.baited = baited; + } + + /** + * Checks if the trap has been caught. + * @return {@code True} if so. + */ + public boolean isCaught() { + return getReward() != null; + } + + /** + * Gets the reward. + * @return The reward. + */ + public TrapNode getReward() { + return reward; + } + + /** + * Sets the reward. + * @param reward The reward to set. + */ + public void setReward(TrapNode reward) { + this.reward = reward; + this.addItem(reward.getRewards()); + } + + /** + * Checks if the trap is busy. + * @return {@code True} if so. + */ + public boolean isBusy() { + return getBusyTicks() > GameWorld.getTicks(); + } + + /** + * Gets the busyTicks. + * @return The busyTicks. + */ + public int getBusyTicks() { + return busyTicks; + } + + /** + * Sets the busyTicks. + * @param busyTicks The busyTicks to set. + */ + public void setBusyTicks(int busyTicks) { + this.busyTicks = GameWorld.getTicks() + busyTicks; + } + + /** + * Gets the items. + * @return The items. + */ + public List getItems() { + return items; + } + + /** + * Gets the secondary. + * @return The secondary. + */ + public Scenery getSecondary() { + return secondary; + } + + /** + * Sets the secondary. + * @param secondary The secondary to set. + */ + public void setSecondary(Scenery secondary) { + this.secondary = secondary; + this.secondary.getAttributes().setAttribute("trap-uid", player.getName().hashCode()); + } + + /** + * Gets the netType. + * @return The netType. + */ + public NetTrap getNetType() { + return netType; + } + + /** + * Sets the netType. + * @param netType The netType to set. + */ + public void setNetType(NetTrap netType) { + this.netType = netType; + } + + /** + * Sets the object. + * @param object The object to set. + */ + public void setObject(Scenery object) { + this.object = object; + } + + /** + * Gets the failed. + * @return The failed. + */ + public boolean isFailed() { + return failed; + } + + /** + * Sets the failed. + * @param failed The failed to set. + */ + public void setFailed(boolean failed) { + this.failed = failed; + } + +} diff --git a/Server/src/main/content/global/skill/hunter/Traps.java b/Server/src/main/content/global/skill/hunter/Traps.java new file mode 100644 index 0000000..f2151d6 --- /dev/null +++ b/Server/src/main/content/global/skill/hunter/Traps.java @@ -0,0 +1,263 @@ +package content.global.skill.hunter; + +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.tools.Log; +import core.tools.SystemLogger; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; + +import java.util.ArrayList; +import java.util.List; + +import static core.api.ContentAPIKt.log; + +/** + * Represents a trap type. + * @author Vexia + */ +public enum Traps { + BIRD_SNARE(new TrapSetting(10006, new int[] { 19175 }, new int[] {}, "lay", 19174, Animation.create(5208), Animation.create(5207), 1), + new TrapNode(new int[] { 5073 }, 1, 34, new int[] { 19179, 19180 }, new Item[] { new Item(10088, 8), new Item(9978), new Item(526) }), + new TrapNode(new int[] { 5075 }, 5, 48, new int[] { 19183, 19184 }, new Item[] { new Item(10090, 8), new Item(9978), new Item(526) }), + new TrapNode(new int[] { 5076 }, 9, 61, new int[] { 19185, 19186 }, new Item[] { new Item(10091, 8), new Item(9978), new Item(526) }), + new TrapNode(new int[] { 5074 }, 11, 64.7, new int[] { 19181, 19182 }, new Item[] { new Item(10089, 8), new Item(9978), new Item(526) }), + new TrapNode(new int[] { 5072 }, 19, 95.2, new int[] { 19177, 19178 }, new Item[] { new Item(10087, 8), new Item(9978), new Item(526) }), + new TrapNode(new int[] { 7031 }, 39, 167, new int[] { 28931, 28930 }, new Item[] { new Item(11525, 8), new Item(9978), new Item(526) }) { + @Override + public boolean canCatch(TrapWrapper wrapper, final NPC npc) { + return false; + } + }), + BOX_TRAP(new TrapSetting(10008, new int[] { 19187 }, new int[] { 1963, 12579, 1869, 9996, 5972, 12535 }, "lay", 19192, Animation.create(5208), new Animation(9726), 27), + new BoxTrapNode(new int[] { 5081 }, 27, 100, new Item[] { new Item(10092) }, 1), + new BoxTrapNode(new int[] { 6918, 7289, 7290, 7291, 7292 }, 27, 100, new Item[] { new Item(12184) }, 10), + new BoxTrapNode(new int[] { 1487 }, 27, 100, new Item[] { new Item(4033, 1) }, 95), + new BoxTrapNode(new int[] { 7021, 7022, 7023 }, 48, 150, new Item[] { new Item(12551, 1) }, 1), + new BoxTrapNode(new int[] { 5079 }, 53, 198, new Item[] { new Item(10033, 1) }, 1), + new BoxTrapNode(new int[] { 5428, 5430, 5449, 5450, 5451 }, 56, 150, new Item[] { new Item(12188) }, 1), + new BoxTrapNode(new int[] { 5080 }, 63, 265, new Item[] { new Item(10034, 1) }, 1), + new BoxTrapNode(new int[] { 7012, 7014 }, 66, 400, new Item[] { new Item(12535) }, 1), + new BoxTrapNode(new int[] { 8654 }, 73, 315, new Item[] { new Item(14861) }, 1), + new BoxTrapNode(new int[] { 7010, 7011 }, 77, 0, new Item[] { new Item(12539, 1) }, 1) { + @Override + public boolean canCatch(TrapWrapper wrapper, final NPC npc) { + //old xp: 726 + wrapper.getPlayer().sendMessage("Note: Giving 0 xp for grenwalls until this area and its requirements are implemented."); + return super.canCatch(wrapper, npc); + } + }), + RABBIT_SNARE(new TrapSetting(10031, new int[] { 19333 }, new int[] {}, "lay", -1, Animation.create(5208), Animation.create(9726), 27)), + IMP_BOX(new MagicBoxSetting(), + new TrapNode(new int[] { 708, 709, 1531 }, 71, 450, new int[] { -1, 19226 }, new Item[] { new Item(10027) })), + DEAD_FALL(new DeadfallSetting(), + new TrapNode(new int[] { 5089 }, 23, 128, new int[] { 19213, 19214, 19218 }, new Item[] { new Item(10113), new Item(526) }), + new TrapNode(new int[] { 5088 }, 33, 168, new int[] { 19211, 19212, 19217 }, new Item[] { new Item(10129), new Item(526) }), + new TrapNode(new int[] { 5086 }, 37, 204, new int[] { 19208, 19208, 19217 }, new Item[] { new Item(10105), new Item(526) }), + new TrapNode(new int[] { 7039 }, 44, 200, new int[] { 28939, 28940, 28941 }, new Item[] { new Item(12567), new Item(526) }), + new TrapNode(new int[] { 5087 }, 51, 200, new int[] { 19209, 19210, 19216 }, new Item[] { new Item(10109), new Item(526) })), + NET_TRAP(new NetTrapSetting(), new TrapNode(new int[] { 5117 }, 29, 152, new int[] {}, new Item[] { new Item(10149) }), + new TrapNode(new int[] { 5114 }, 47, 224, new int[] {}, new Item[] { new Item(10146) }), + new TrapNode(new int[] { 6921 }, 29, 152, new int[] {}, new Item[] { new Item(12130) }), + new TrapNode(new int[] { 5115 }, 59, 272, new int[] {}, new Item[] { new Item(10147) }), + new TrapNode(new int[] { 5116 }, 67, 304, new int[] {}, new Item[] { new Item(10148) })); + + /** + * The location hooks for this node. + */ + private final List hooks = new ArrayList<>(5); + + /** + * The trap settings. + */ + private final TrapSetting settings; + + /** + * The nodes related to the trap. + */ + private final TrapNode[] nodes; + + /** + * Constructs a new {@code TrapType} {@code Object}. + * @param settings the settings. + * @param nodes the nodes. + */ + Traps(TrapSetting settings, TrapNode... nodes) { + this.settings = settings; + this.nodes = nodes; + } + + /** + * Creates a trap instance. + * @param player the player. + */ + public void create(Player player, Node node) { + player.getPulseManager().run(new TrapCreatePulse(player, node, this)); + } + + /** + * Dismantles a trap. + * @param player the player. + * @param object the object. + */ + public void dismantle(Player player, Scenery object) { + HunterManager instance = HunterManager.getInstance(player); + + if (!instance.isOwner(object)) { + player.sendMessage("This isn't your trap!"); + return; + } + if (instance.getWrapper(object) == null) { + log(this.getClass(), Log.ERR, "NO WRAPPER (HUNTER DISMANTLE)"); + return; + } + player.faceLocation(object.getLocation()); + player.getPulseManager().run(new TrapDismantlePulse(player, object, instance.getWrapper(object))); + } + + /** + * Investigates the trap. + * @param player the player. + * @param object the object. + */ + public void investigate(Player player, Scenery object) { + getSettings().investigate(player, object); + } + + /** + * Called when an npc is hooked. + * @param wrapper the wrapper. + * @param npc the npc. + */ + public void catchNpc(TrapWrapper wrapper, NPC npc) { + final TrapNode trapNode = forNpc(npc); + if (trapNode == null || !trapNode.canCatch(wrapper, npc) || !settings.canCatch(wrapper, npc)) { + return; + } + settings.catchNpc(wrapper, trapNode, npc); + } + + /** + * Adds a hook. + * @param wrapper the wrapper. + */ + public TrapHook addHook(TrapWrapper wrapper) { + TrapHook hook = settings.createHook(wrapper); + hooks.add(hook); + return hook; + } + + /** + * Gets a node by the npc. + * @param npc the npc. + * @return the node. + */ + public TrapNode forNpc(NPC npc) { + for (TrapNode node : nodes) { + for (int npcId : node.getNpcIds()) { + if (npcId == npc.getId()) { + return node; + } + } + } + return null; + } + + /** + * Gets a trap by the node id. + * @param node the node. + * @return the {@code Traps}. + */ + public static Traps forNode(Node node) { + for (Traps trap : Traps.values()) { + for (int nodeId : trap.getSettings().getNodeIds()) { + if (node.getId() == nodeId) { + return trap; + } + } + for (int objectId : trap.getSettings().getObjectIds()) { + if (objectId == node.getId()) { + return trap; + } + } + for (TrapNode n : trap.getNodes()) { + for (int id : n.getObjectIds()) { + if (id == node.getId()) { + return trap; + } + } + } + if (trap.getSettings().getFailId() == node.getId()) { + return trap; + } + if (trap == NET_TRAP) { + for (NetTrapSetting.NetTrap net : NetTrapSetting.NetTrap.values()) { + if (net.getOriginal() == node.getId() || net.getFailed() == node.getId() || net.getNet() == node.getId() || net.getBent() == node.getId() || net.getCaught() == node.getId()) { + return trap; + } + } + } + } + return null; + } + + /** + * Gets a trap node by the id. + * @param id the id. + * @return the node. + */ + public static Object[] getNode(int id) { + for (Traps trap : values()) { + for (TrapNode t : trap.getNodes()) { + for (int i : t.getNpcIds()) { + if (i == id) { + return new Object[] { trap, t }; + } + } + } + } + return null; + } + + /** + * Gets the wrapper by the hook. + * @param location the location. + * @return the wrapper. + */ + public TrapWrapper getByHook(Location location) { + for (TrapHook hook : hooks) { + if (hook.isHooked(location)) { + return hook.getWrapper(); + } + } + return null; + } + + /** + * Gets the settings. + * @return The settings. + */ + public TrapSetting getSettings() { + return settings; + } + + /** + * Gets the nodes. + * @return The nodes. + */ + public TrapNode[] getNodes() { + return nodes; + } + + /** + * Gets the hooks. + * @return The hooks. + */ + public List getHooks() { + return hooks; + } + +} diff --git a/Server/src/main/content/global/skill/hunter/bnet/BNetNode.java b/Server/src/main/content/global/skill/hunter/bnet/BNetNode.java new file mode 100644 index 0000000..7f512bf --- /dev/null +++ b/Server/src/main/content/global/skill/hunter/bnet/BNetNode.java @@ -0,0 +1,222 @@ +package content.global.skill.hunter.bnet; + +import core.cache.def.impl.NPCDefinition; +import core.game.container.impl.EquipmentContainer; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Graphics; + +/** + * A butterfly net node. + * @author Vexia + */ +public class BNetNode { + + /** + * The butterfly jar item. + */ + private static final Item BUTTERFLY_JAR = new Item(10012); + + /** + * The impling jar item. + */ + protected static final Item IMPLING_JAR = new Item(11260); + + /** + * The npcs related to this node. + */ + private final int[] npcs; + + /** + * The levels needed. + */ + private final int[] levels; + + /** + * The experience gained. + */ + private final double[] experience; + + /** + * The graphics related to the node. + */ + private final Graphics[] graphics; + + /** + * The reward item. + */ + private final Item reward; + + /** + * Constructs a new {@code ButterflyNetNode} {@code Object}. + * @param npcs the npcs. + * @param levels the levels. + * @param experience the experience. + * @param graphics the graphics. + */ + public BNetNode(int[] npcs, int[] levels, double[] experience, Graphics[] graphics, Item reward) { + this.npcs = npcs; + this.levels = levels; + this.experience = experience; + this.graphics = graphics; + this.reward = reward; + } + + /** + * Rewards the player. + * @param player the player. + * @param npc the npc. + */ + public void reward(Player player, NPC npc) { + if (!isBareHand(player)) { + if (player.getInventory().remove(getJar())) { + final Item item = getReward(); + player.getInventory().add(item); + player.getSkills().addExperience(Skills.HUNTER, getExperience(player), true); + } + } else { + player.graphics(graphics[0]); + player.getSkills().addExperience(Skills.HUNTER, getExperiences()[1], true); + player.getSkills().addExperience(Skills.AGILITY, getExperiences()[2], true); + } + } + + /** + * Handles a message event. + * @param type the type. + * @param success the success. + */ + public void message(Player player, int type, boolean success) { + if (!success) { + return; + } + switch (type) { + case 1: + player.getPacketDispatch().sendMessage("You manage to catch the butterfly."); + if (isBareHand(player)) { + player.getPacketDispatch().sendMessage("You release the " + NPCDefinition.forId(npcs[0]).getName().toLowerCase() + " butterfly."); + } + break; + } + } + + /** + * Checks if the player has a jar. + * @param player the player. + * @return {@code True} if so. + */ + public boolean hasJar(Player player) { + return player.getInventory().containsItem(getJar()); + } + + /** + * Checks if the player has a weapon. + * @param player the player. + * @return {@code True} if so. + */ + public boolean hasWeapon(Player player) { + Item item = player.getEquipment().get(EquipmentContainer.SLOT_WEAPON); + return item != null && (item.getId() != 10010 && item.getId() != 11259); + } + + /** + * Checks if the player has a net. + * @param player the player. + * @return {@code True} if so. + */ + public boolean hasNet(Player player) { + return player.getEquipment().contains(10010, 1) || player.getEquipment().contains(11259, 1); + } + + /** + * Checks if the player is bare handed. + * @param player the player. + * @return {@code} True if so. + */ + public boolean isBareHand(Player player) { + return !hasNet(player) && player.getSkills().getLevel(Skills.HUNTER) >= getBareHandLevel() && player.getSkills().getLevel(Skills.AGILITY) >= getAgilityLevel(); + } + + /** + * Gets the experience in hunter. + * @return the exp. + */ + public double getExperience(Player player) { + return experience[0]; + } + + /** + * Gets the hunter level. + * @return the level. + */ + public int getLevel() { + return levels[0]; + } + + /** + * Gets the agility level. + * @return the level. + */ + public int getAgilityLevel() { + return levels[2]; + } + + /** + * Gets the bare hand level. + * @return the level. + */ + public int getBareHandLevel() { + return levels[1]; + } + + /** + * Gets the npcs. + * @return The npcs. + */ + public int[] getNpcs() { + return npcs; + } + + /** + * Gets the levels. + * @return The levels. + */ + public int[] getLevels() { + return levels; + } + + /** + * Gets the experience. + * @return The experience. + */ + public double[] getExperiences() { + return experience; + } + + /** + * Gets the graphics. + * @return The graphics. + */ + public Graphics[] getGraphics() { + return graphics; + } + + /** + * Gets the reward. + * @return The reward. + */ + public Item getReward() { + return reward; + } + + /** + * Gets the jar. + * @return the jar. + */ + public Item getJar() { + return BUTTERFLY_JAR; + } + +} diff --git a/Server/src/main/content/global/skill/hunter/bnet/BNetPulse.java b/Server/src/main/content/global/skill/hunter/bnet/BNetPulse.java new file mode 100644 index 0000000..38371c4 --- /dev/null +++ b/Server/src/main/content/global/skill/hunter/bnet/BNetPulse.java @@ -0,0 +1,157 @@ +package content.global.skill.hunter.bnet; + +import core.game.container.impl.EquipmentContainer; +import core.game.node.entity.skill.SkillPulse; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.combat.DeathTask; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.GameWorld; +import core.game.world.update.flag.context.Animation; +import core.tools.RandomFunction; +import core.tools.StringUtils; +import org.rs09.consts.Sounds; + +import java.util.Random; + +import static core.api.ContentAPIKt.playAudio; + +/** + * Handles the butterfly net catch pulse. + * @author Vexia + */ +public final class BNetPulse extends SkillPulse { + + /** + * The swinging animation. + */ + private static final Animation ANIMATION = new Animation(6999); + + /** + * The net node. + */ + private final BNetNode type; + + /** + * If we are successfull. + */ + private boolean success; + + /** + * The ticks passed. + */ + private int ticks; + + /** + * Update lumbridge impling task, makes sure we're in puro puro and checks diary entry completion + * @returns false if not in puro puro, true and updates diary if in puro puro + */ + public boolean updateLumbridgeImplingTask(Player player) { + if(!player.getZoneMonitor().isInZone("puro puro")){ + return false; + } else { +/* if(!player.getAchievementDiaryManager().hasCompletedTask(DiaryType.LUMBRIDGE,1,8)){ + player.getAchievementDiaryManager().updateTask(player,DiaryType.LUMBRIDGE,1,8,true); + }*/ + return true; + } + } + + /** + * Constructs a new {@code BNetPulse} {@code Object}. + * @param player the player. + * @param node the node. + * @param type the type. + */ + public BNetPulse(Player player, NPC node, BNetNode type) { + super(player, node); + this.type = type; + this.resetAnimation = false; + } + + @Override + public boolean checkRequirements() { + if (player.getSkills().getLevel(Skills.HUNTER) < type.getLevel()) { + player.sendMessage("You need a Hunter level of at least " + type.getLevel() + " in order to do that."); + return false; + } + if (type.hasWeapon(player)) { + player.getPacketDispatch().sendMessage("Your hands need to be free."); + return false; + } else if (!type.hasNet(player)) { + player.sendMessage("You need to be wielding a butterfly net to catch " + (type instanceof ImplingNode ? "implings" : "butterflies") + "."); + return false; + } else if (!type.hasJar(player)) { + player.getPacketDispatch().sendMessage("You need to have a" + (StringUtils.isPlusN(type.getJar().getName()) ? "n" : "") + " " + type.getJar().getName().toLowerCase() + "."); + return false; + } + if (node.isInvisible() || DeathTask.isDead(node)) { + return false; + } + return true; + } + + @Override + public void animate() { + if (ticks < 1) { + player.animate(ANIMATION); + playAudio(player, Sounds.HUNTING_BUTTERFLYNET_2623); + } + } + + @Override + public boolean reward() { + if (node.isInvisible() || DeathTask.isDead(node)) { + return true; + } + if (++ticks % 2 != 0) { + return false; + } + if (node.getAttribute("dead", 0) > GameWorld.getTicks()) { + player.sendMessage("Ooops! It's gone."); + return true; + } + if ((success = isSuccessful())) { + node.finalizeDeath(player); + type.reward(player, node); + node.setAttribute("dead", GameWorld.getTicks() + 10); + if (type == BNetTypes.ECLECTIC_IMPLING.getNode() || type == BNetTypes.ESSENCE_IMPLING.getNode() ) { + updateLumbridgeImplingTask(player); + } + } else { + node.moveStep(); + } + return true; + } + + @Override + public void message(int type) { + if (type == 0) { + node.setAttribute("looting", GameWorld.getTicks() + (ANIMATION.getDuration() + 1)); + player.lock(ANIMATION.getDuration()); + } + this.type.message(player, type, success); + } + + /** + * Checks if the player has succesfully caught the impling. + * @return {@code True} if succesful, {@code false} if not. + */ + private boolean isSuccessful() { + int huntingLevel = player.getSkills().getLevel(Skills.HUNTER); + int level = type.getLevel(); + if (type.hasNet(player)) { + Item net = player.getEquipment().get(EquipmentContainer.SLOT_WEAPON); + if (net != null && net.getId() == 11259) { + huntingLevel += 5; + } + } else { + huntingLevel *= 0.5; + } + int currentLevel = RandomFunction.random(huntingLevel) + 1; + double ratio = (double) currentLevel / (new Random().nextInt(level + 5) + 1); + return Math.round(ratio * huntingLevel) >= level; + } + +} diff --git a/Server/src/main/content/global/skill/hunter/bnet/BNetTypes.java b/Server/src/main/content/global/skill/hunter/bnet/BNetTypes.java new file mode 100644 index 0000000..0b1e65f --- /dev/null +++ b/Server/src/main/content/global/skill/hunter/bnet/BNetTypes.java @@ -0,0 +1,136 @@ +package content.global.skill.hunter.bnet; + +import core.game.node.entity.npc.NPC; +import core.game.node.entity.npc.drop.DropFrequency; +import core.game.node.entity.player.Player; +import core.game.node.item.ChanceItem; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Graphics; + +import java.util.ArrayList; +import java.util.List; + +/** + * A butterfly net type catch. + * @author Vexia + */ +public enum BNetTypes { + // Butterflies + RUBY_HARVEST(new BNetNode(new int[] { 5085 }, new int[] { 15, 80, 75 }, new double[] { 24, 300, 50 }, new Graphics[] { new Graphics(913), new Graphics(917) }, new ChanceItem(10020))), + SAPPHIRE_GLACIALIS(new BNetNode(new int[] { 5084, 7499 }, new int[] { 25, 85, 80 }, new double[] { 34, 400, 70 }, new Graphics[] { new Graphics(912), new Graphics(916) }, new ChanceItem(10018))), + SNOWRY_KNIGHT(new BNetNode(new int[] { 5083, 7498 }, new int[] { 35, 90, 85 }, new double[] { 44, 500, 100 }, new Graphics[] { new Graphics(911), new Graphics(915) }, new ChanceItem(10016))), + BLACK_WARLOCK(new BNetNode(new int[] { 5082 }, new int[] { 45, 95, 90 }, new double[] { 54, 650, 125 }, new Graphics[] { new Graphics(910), new Graphics(914) }, new ChanceItem(10014))), + // Implings ( Clearly these morons typed way too fast - wasn't sure if these names were anywhere else in the code) + BABY_IMPLING(new ImplingNode(new int[] { 1028, 6055 }, 17, 20, 18, new Item(11238), new ChanceItem(1755, 1, 1, DropFrequency.COMMON), new ChanceItem(1734, 1, 1, DropFrequency.COMMON), new ChanceItem(1733, 1, 1, DropFrequency.COMMON), new ChanceItem(946, 1, 1, DropFrequency.COMMON), new ChanceItem(1985, 1, 1, DropFrequency.COMMON), new ChanceItem(2347, 1, 1, DropFrequency.COMMON), new ChanceItem(1759, 1, 1, DropFrequency.COMMON), new ChanceItem(1927, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(319, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(2007, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(2007, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(1779, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(7170, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(401, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(1438, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(2355, 1, 1, DropFrequency.RARE), new ChanceItem(1607, 1, 1, DropFrequency.RARE), new ChanceItem(1743, 1, 1, DropFrequency.RARE), new ChanceItem(379, 1, 1, DropFrequency.RARE), new ChanceItem(1761, 1, 1, DropFrequency.RARE))), + YOUNG_IMPLING(new ImplingNode(new int[] { 1029, 6056 }, 22, 22, 20, new Item(11240), new ChanceItem(1539, 5, 5, DropFrequency.COMMON), new ChanceItem(1901, 1, 1, DropFrequency.COMMON), new ChanceItem(7936, 1, 1, DropFrequency.COMMON), new ChanceItem(361, 1, 1, DropFrequency.COMMON), new ChanceItem(1523, 1, 1, DropFrequency.COMMON), new ChanceItem(453, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(1777, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(2293, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(1353, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(2359, 1, 1, DropFrequency.RARE))), + GOURMET_IMPLING(new ImplingNode(new int[] { 1030, 6057 }, 28, 24, 22, new Item(11242), new ChanceItem(365, 1, 1, DropFrequency.COMMON), new ChanceItem(361, 1, 1, DropFrequency.COMMON), new ChanceItem(2011, 1, 1, DropFrequency.COMMON), new ChanceItem(1897, 1, 1, DropFrequency.COMMON), new ChanceItem(2327, 1, 1, DropFrequency.COMMON), new ChanceItem(5004, 1, 1, DropFrequency.COMMON), new ChanceItem(2007, 1, 1, DropFrequency.COMMON), new ChanceItem(5970, 1, 1, DropFrequency.COMMON), new ChanceItem(365, 4, 4, DropFrequency.UNCOMMON), new ChanceItem(3145, 2, 2, DropFrequency.RARE), new ChanceItem(7178, 1, 5, DropFrequency.UNCOMMON), new ChanceItem(5755, 1, 1, DropFrequency.RARE), new ChanceItem(386, 3, 3, DropFrequency.UNCOMMON), new ChanceItem(5406, 1, 1, DropFrequency.RARE), new ChanceItem(10136, 1, 1, DropFrequency.RARE), new ChanceItem(1883, 1, 1, DropFrequency.UNCOMMON))), + EARTH_IMPLING(new ImplingNode(new int[] { 1031, 6058 }, 36, 27, 25, new Item(11244), new ChanceItem(6033, 6, 6, DropFrequency.COMMON), new ChanceItem(1440, 1, 1, DropFrequency.COMMON), new ChanceItem(5535, 1, 1, DropFrequency.COMMON), new ChanceItem(557, 32, 32, DropFrequency.COMMON), new ChanceItem(1442, 1, 1, DropFrequency.COMMON), new ChanceItem(1784, 4, 4, DropFrequency.UNCOMMON), new ChanceItem(447, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(447, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(1606, 2, 2, DropFrequency.RARE))), + ESSENCE_IMPLING(new ImplingNode(new int[] { 1032, 6059 }, 42, 29, 27, new Item(11246), new ChanceItem(7937, 20, 20, DropFrequency.COMMON), new ChanceItem(555, 30, 30, DropFrequency.COMMON), new ChanceItem(556, 30, 30, DropFrequency.COMMON), new ChanceItem(558, 25, 25, DropFrequency.COMMON), new ChanceItem(559, 28, 28, DropFrequency.COMMON), new ChanceItem(562, 4, 4, DropFrequency.COMMON), new ChanceItem(1448, 1, 1, DropFrequency.COMMON), new ChanceItem(564, 4, 4, DropFrequency.UNCOMMON), new ChanceItem(565, 7, 7, DropFrequency.RARE), new ChanceItem(563, 13, 13, DropFrequency.RARE), new ChanceItem(566, 11, 11, DropFrequency.RARE))), + ECLECTIC_IMPLING(new ImplingNode(new int[] { 1033, 6060 }, 50, 32, 30, new Item(11248), new ChanceItem(1273, 1, 1, DropFrequency.COMMON), new ChanceItem(1199, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(2493, 1, 1, DropFrequency.RARE), new ChanceItem(10083, 1, 1, DropFrequency.RARE), new ChanceItem(1213, 1, 1, DropFrequency.RARE), new ChanceItem(1391, 1, 1, DropFrequency.VERY_RARE), new ChanceItem(5970, 1, 1, DropFrequency.COMMON), new ChanceItem(231, 1, 1, DropFrequency.COMMON), new ChanceItem(556, 30, 57, DropFrequency.COMMON), new ChanceItem(8779, 4, 4, DropFrequency.COMMON), new ChanceItem(4527, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(444, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(2358, 5, 5, DropFrequency.UNCOMMON), new ChanceItem(7937, 20, 35, DropFrequency.UNCOMMON), new ChanceItem(237, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(450, 10, 10, DropFrequency.RARE), new ChanceItem(5760, 2, 2, DropFrequency.RARE), new ChanceItem(7208, 1, 1, DropFrequency.RARE), new ChanceItem(5321, 3, 3, DropFrequency.RARE), new ChanceItem(1601, 1, 1, DropFrequency.VERY_RARE))), + NATURE_IMPLING(new ImplingNode(new int[] { 1034, 6061 }, 58, 36, 34, new Item(11250), new ChanceItem(5303, 1, 1, DropFrequency.VERY_RARE), new ChanceItem(270, 2, 2, DropFrequency.VERY_RARE), new ChanceItem(5295, 1, 1, DropFrequency.RARE), new ChanceItem(5304, 1, 1, DropFrequency.RARE), new ChanceItem(5298, 5, 5, DropFrequency.UNCOMMON), new ChanceItem(5299, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(5297, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(5974, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(3000, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(5285, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(5286, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(5100, 1, 1, DropFrequency.COMMON), new ChanceItem(5104, 1, 1, DropFrequency.COMMON), new ChanceItem(5281, 1, 1, DropFrequency.COMMON), new ChanceItem(5294, 1, 1, DropFrequency.COMMON), new ChanceItem(6016, 1, 1, DropFrequency.COMMON), new ChanceItem(1513, 1, 1, DropFrequency.COMMON), new ChanceItem(254, 4, 4, DropFrequency.COMMON), new ChanceItem(5313, 1, 1, DropFrequency.UNCOMMON))), + MAGPIE_IMPLING(new ImplingNode(new int[] { 1035, 6062 }, 65, 216, 44, new Item(11252), 500, new ChanceItem(1682, 3, 3, DropFrequency.COMMON), new ChanceItem(1732, 3, 3, DropFrequency.COMMON), new ChanceItem(2569, 3, 3, DropFrequency.COMMON), new ChanceItem(3391, 1, 1, DropFrequency.COMMON), new ChanceItem(1347, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(2571, 4, 4, DropFrequency.UNCOMMON), new ChanceItem(4097, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(4095, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(1215, 1, 1, DropFrequency.RARE), new ChanceItem(1185, 1, 1, DropFrequency.RARE), new ChanceItem(5541, 1, 1, DropFrequency.COMMON), new ChanceItem(1748, 6, 6, DropFrequency.COMMON), new ChanceItem(2364, 2, 2, DropFrequency.UNCOMMON), new ChanceItem(1602, 4, 4, DropFrequency.RARE), new ChanceItem(5287, 1, 1, DropFrequency.RARE), new ChanceItem(985, 1, 1, DropFrequency.RARE), new ChanceItem(987, 1, 1, DropFrequency.RARE), new ChanceItem(993, 1, 1, DropFrequency.VERY_RARE), new ChanceItem(5300, 1, 1, DropFrequency.VERY_RARE))), + NINJA_IMPLING(new ImplingNode(new int[] { 6053, 6063 }, 74, 240, 50, new Item(11254), 2000, new ChanceItem(4097, 1, 1, DropFrequency.COMMON), new ChanceItem(1113, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(3385, 1, 1, DropFrequency.COMMON), new ChanceItem(1215, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(811, 70, 70, DropFrequency.UNCOMMON), new ChanceItem(1333, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(1347, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(9342, 2, 2, DropFrequency.UNCOMMON), new ChanceItem(9194, 4, 4, DropFrequency.RARE), new ChanceItem(140, 4, 4, DropFrequency.COMMON), new ChanceItem(6155, 3, 3, DropFrequency.UNCOMMON), new ChanceItem(1748, 10, 16, DropFrequency.COMMON))), + // Pirate should be here + DRAGON_IMPLING(new ImplingNode(new int[] { 6054, 6064 }, 83, 300, 65, new Item(11256), 3000, new ChanceItem(1705, 2, 3, DropFrequency.RARE), new ChanceItem(4093, 1, 1, DropFrequency.VERY_RARE), new ChanceItem(1684, 2, 3, DropFrequency.VERY_RARE), new ChanceItem(11212, 100, 500, DropFrequency.COMMON), new ChanceItem(9341, 3, 40, DropFrequency.COMMON), new ChanceItem(1305, 1, 1, DropFrequency.COMMON), new ChanceItem(5699, 3, 3, DropFrequency.UNCOMMON), new ChanceItem(11230, 105, 350, DropFrequency.UNCOMMON), new ChanceItem(11232, 105, 350, DropFrequency.COMMON), new ChanceItem(11237, 100, 500, DropFrequency.COMMON), new ChanceItem(9193, 10, 49, DropFrequency.COMMON), new ChanceItem(535, 111, 297, DropFrequency.COMMON), new ChanceItem(5316, 1, 1, DropFrequency.UNCOMMON), new ChanceItem(537, 52, 99, DropFrequency.UNCOMMON), new ChanceItem(1616, 3, 6, DropFrequency.UNCOMMON), new ChanceItem(5300, 6, 6, DropFrequency.RARE), new ChanceItem(7219, 5, 15, DropFrequency.RARE))); + + + /** + * The implings. + */ + private static final List IMPLINGS = new ArrayList<>(20); + + /** + * The node. + */ + private final BNetNode node; + + /** + * Constructs a new {@code BNetTypes} {@code Object}. + * @param node the node. + */ + private BNetTypes(BNetNode node) { + this.node = node; + } + + /** + * Catches a net npc. + * @param player the player. + * @param npc the npc. + */ + public void handle(Player player, NPC npc) { + player.getPulseManager().run(new BNetPulse(player, npc, node)); + } + + /** + * Gets an impling. + * @param player the player. + * @return the imp. + */ + public static ImplingNode getImpling(Player player) { + for (ImplingNode imp : IMPLINGS) { + if (player.getInventory().containsItem(imp.getReward())) { + return imp; + } + } + return null; + } + + /** + * Gets a net type for the npc. + * @param npc the npc. + * @return {@code BNetTypes} type. + */ + public static BNetTypes forNpc(NPC npc) { + for (BNetTypes type : BNetTypes.values()) { + for (int id : type.getNode().getNpcs()) { + if (id == npc.getId()) { + return type; + } + } + } + return null; + } + + /** + * Gets the BNetNode by the item. + * @param item the item. + * @return the instance. + */ + public static BNetNode forItem(Item item) { + for (BNetTypes type : values()) { + if (type.getNode().getReward().getId() == item.getId()) { + return type.getNode(); + } + } + return null; + } + + /** + * Gets the node. + * @return The node. + */ + public BNetNode getNode() { + return node; + } + + /** + * Gets the implings. + * @return The implings. + */ + public static List getImplings() { + return IMPLINGS; + } + + /** + * static-modifier. + */ + static { + for (BNetTypes type : values()) { + BNetNode node = type.getNode(); + if (node instanceof ImplingNode) { + IMPLINGS.add((ImplingNode) node); + } + } + } + +} diff --git a/Server/src/main/content/global/skill/hunter/bnet/ImplingNode.java b/Server/src/main/content/global/skill/hunter/bnet/ImplingNode.java new file mode 100644 index 0000000..e454b8d --- /dev/null +++ b/Server/src/main/content/global/skill/hunter/bnet/ImplingNode.java @@ -0,0 +1,131 @@ +package content.global.skill.hunter.bnet; + +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.item.ChanceItem; +import core.game.node.item.Item; +import core.tools.RandomFunction; + +import java.util.Random; + +/** + * Handles the impling node. + * @author Vexia + */ +public final class ImplingNode extends BNetNode { + + /** + * The loot from an imp. + */ + private final ChanceItem[] loot; + + /** + * The respawn time. + */ + private final int respawnTime; + + /** + * Constructs a new {@code ImplingNode} {@code Object}. + * @param npcs the npcs. + * @param level the level. + * @param exp the exp. + * @param puroExp the puro exp. + * @param reward the reward. + * @param loot the loot. + */ + public ImplingNode(int[] npcs, int level, double exp, double puroExp, Item reward, final int respawnTime, final ChanceItem... loot) { + super(npcs, new int[] { level }, new double[] { exp, puroExp }, null, reward); + this.loot = loot; + this.respawnTime = respawnTime; + } + + /** + * Constructs a new {@code ImplingNode} {@code Object}. + * @param npcs the npcs. + * @param level the level. + * @param exp the exp. + * @param puroExp the puro exp. + * @param reward the reward. + * @param loot the loot. + */ + public ImplingNode(int[] npcs, int level, double exp, double puroExp, Item reward, final ChanceItem... loot) { + this(npcs, level, exp, puroExp, reward, 16, loot); + } + + /** + * Loots an imp jar. + * @param player the player. + * @param item the item. + */ + public void loot(final Player player, final Item item) { + player.lock(1); + if (player.getInventory().freeSlots() < 1) { + player.getPacketDispatch().sendMessage("You don't have enough inventory space."); + return; + } + final Item reward = RandomFunction.getChanceItem(getLoot()).getRandomItem(); + if (player.getInventory().remove(item)) { + if (isBroken(player)) { + player.sendMessage("You break the jar as you try and open it. You throw the shattered remains away."); + } else { + player.getInventory().add(IMPLING_JAR); + } + player.getInventory().add(reward, player); + } + } + + /** + * Checks if the item will break. + * @param player the player. + * @return {@code True} if so. + */ + private boolean isBroken(Player player) { + int strengthLevel = player.getSkills().getLevel(Skills.STRENGTH); + strengthLevel /= 0.5; + int level = getLevel(); + int currentLevel = RandomFunction.random(strengthLevel) + 1; + double ratio = (double) currentLevel / (new Random().nextInt(level + 5) + 1); + return Math.round(ratio * strengthLevel) < level; + } + + @Override + public void message(Player player, int type, boolean success) { + if (!success) { + return; + } + if(type == 1){ + player.sendMessage("You manage to catch the impling and squeeze it into a jar."); + } + } + + @Override + public double getExperience(Player player) { + return player.getZoneMonitor().isInZone("puro puro") ? getExperiences()[1] : super.getExperience(player); + } + + @Override + public boolean isBareHand(Player player) { + return false; + } + + @Override + public Item getJar() { + return IMPLING_JAR; + } + + /** + * Gets the loot. + * @return The loot. + */ + public ChanceItem[] getLoot() { + return loot; + } + + /** + * Gets the respawnTime. + * @return The respawnTime. + */ + public int getRespawnTime() { + return respawnTime; + } +} diff --git a/Server/src/main/content/global/skill/hunter/falconry/FalconCatch.java b/Server/src/main/content/global/skill/hunter/falconry/FalconCatch.java new file mode 100644 index 0000000..4f0c646 --- /dev/null +++ b/Server/src/main/content/global/skill/hunter/falconry/FalconCatch.java @@ -0,0 +1,107 @@ +package content.global.skill.hunter.falconry; + +import core.game.node.entity.npc.NPC; +import core.game.node.item.Item; + +/** + * Represents a falcon catch. + * @author Vexia + */ +public enum FalconCatch { + SPOTTED_KEBBIT(5098, 43, 104, new Item(10125)), DARK_KEBBIT(5099, 57, 132, new Item(10115)), DASHING_KEBBIT(5100, 69, 156, new Item(10127)); + + /** + * Represents the npc. + */ + private final int npc; + + /** + * Represents the level. + */ + private final int level; + + /** + * Represents the experience gained. + */ + private final double experience; + + /** + * Represents the item reward. + */ + private final Item item; + + /** + * Constructs a new {@code FalconCatch} {@code Object}. + * @param npc the npc. + * @param level the level. + * @param experience the experience. + * @param item the item. + */ + FalconCatch(int npc, int level, double experience, Item item) { + this.npc = npc; + this.level = level; + this.experience = experience; + this.item = item; + } + + /** + * Gets the falcon catch. + * @param item the item. + * @return the falcon catch. + */ + public static FalconCatch forItem(final Item item) { + for (FalconCatch falconCatch : FalconCatch.values()) { + if (item.getId() == falconCatch.getItem().getId()) { + return falconCatch; + } + } + return null; + } + + /** + * Gets the falcon catch. + * @param npc the npc. + * @return the falcon catch. + */ + public static FalconCatch forNPC(final NPC npc) { + for (FalconCatch falconCatch : FalconCatch.values()) { + if (npc.getId() == falconCatch.getNpc()) { + return falconCatch; + } + } + return null; + } + + /** + * Gets the npc. + * @return The npc. + */ + public int getNpc() { + return npc; + } + + /** + * Gets the level. + * @return The level. + */ + public int getLevel() { + return level; + } + + /** + * Gets the experience. + * @return The experience. + */ + public double getExperience() { + return experience; + } + + /** + * Gets the item. + * @return The item. + */ + public Item getItem() { + return item; + } + +} diff --git a/Server/src/main/content/global/skill/hunter/falconry/FalconryCatchPulse.java b/Server/src/main/content/global/skill/hunter/falconry/FalconryCatchPulse.java new file mode 100644 index 0000000..b33667e --- /dev/null +++ b/Server/src/main/content/global/skill/hunter/falconry/FalconryCatchPulse.java @@ -0,0 +1,184 @@ +package content.global.skill.hunter.falconry; + +import core.game.container.impl.EquipmentContainer; +import core.game.node.entity.skill.SkillPulse; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.HintIconManager; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.repository.Repository; +import core.tools.RandomFunction; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playAudio; + +/** + * Represents the skill pulse used to catch a kebbit. + * @author Vexia + */ +public final class FalconryCatchPulse extends SkillPulse { + + /** + * Represents the falcon catch. + */ + private final FalconCatch falconCatch; + + /** + * Represents the falcon item. + */ + private static final Item FALCON = new Item(10024); + + /** + * Represents the falcon glove. + */ + private static final Item GLOVE = new Item(10023); + + /** + * Represents the original location. + */ + private final Location originalLocation; + + /** + * If the falcon has been checked. + */ + private boolean checked; + + /** + * The ticks passed. + */ + private int ticks; + + /** + * Constructs a new {@code FalconryCatchPulse.java} {@code Object}. + * @param player + * @param node + */ + public FalconryCatchPulse(final Player player, final NPC node, final FalconCatch falconCatch) { + super(player, node); + this.falconCatch = falconCatch; + this.originalLocation = node.getLocation(); + } + + @Override + public void start() { + player.faceTemporary(node, 1); + node.getWalkingQueue().reset(); + player.getWalkingQueue().reset(); + super.start(); + } + + @Override + public boolean checkRequirements() { + if (!checked) { + checked = true; + if (node.getLocation().getDistance(player.getLocation()) > 15) { + player.getPacketDispatch().sendMessage("You can't catch a kebbit that far away."); + return false; + } + if (player.getSkills().getLevel(Skills.HUNTER) < falconCatch.getLevel()) { + player.getPacketDispatch().sendMessage("You need a Hunter level of at least " + falconCatch.getLevel() + " to catch this kebbit."); + return false; + } + if (player.getEquipment().get(EquipmentContainer.SLOT_HANDS) != null || player.getEquipment().get(EquipmentContainer.SLOT_SHIELD) != null) { + player.getDialogueInterpreter().sendDialogue("Sorry, free your hands, weapon, and shield slot first."); + return false; + } + if (player.getEquipment().get(EquipmentContainer.SLOT_WEAPON) == null || !player.getEquipment().containsItem(FALCON)) { + player.getPacketDispatch().sendMessage("You need a falcon to catch a kebbit."); + return false; + } + if (player.getEquipment().remove(FALCON)) { + player.getEquipment().add(GLOVE, true, false); + sendProjectile(); + } + node.lock(getDistance()+1); + player.lock(getDistance()+1); + } + return true; + } + + @Override + public void stop() { + super.stop(); + player.unlock(); + } + + @Override + public void animate() { + } + + @Override + public boolean reward() { + if (++ticks % getDistance() != 0) { + return false; + } + final boolean success = success(); + player.getPacketDispatch().sendMessage(success ? "The falcon successfully swoops down and captures the kebbit." : "The falcon swoops down on the kebbit, but just misses catching it."); + if (success) { + node.finalizeDeath(player); + final NPC falcon = NPC.create(5094, node.getLocation()); + falcon.setAttribute("falcon:owner", player.getUsername()); + falcon.setAttribute("falcon:catch", falconCatch); + falcon.init(); + HintIconManager.registerHintIcon(player, falcon); + playAudio(player, Sounds.HUNTING_FALCON_SWOOP_2634, 10, 1, node.getLocation(), 12); + GameWorld.getPulser().submit(new Pulse(100, falcon) { + @Override + public boolean pulse() { + if (!falcon.isActive()) { + return true; + } + Projectile projectile = Projectile.create(node, Repository.findNPC(5093), 918); + projectile.setSpeed(80); + projectile.send(); + player.getPacketDispatch().sendMessage("Your falcon has left its prey. You see it heading back toward the falconer."); + falcon.clear(); + return true; + } + }); + } else { + if (player.getEquipment().remove(GLOVE)) { + player.getEquipment().add(FALCON, true, false); + } + } + player.face(null); + return true; + } + + /** + * Sends the projectile. + */ + private void sendProjectile() { + Projectile projectile = Projectile.create(player, node, 918); + projectile.setSpeed(80); + projectile.setStartHeight(26); + projectile.setEndHeight(1); + projectile.send(); + playAudio(player, Sounds.HUNTING_FALCON_FLY_2633); + } + + /** + * Gets the distance of the npc. + * @return the distance. + */ + public int getDistance() { + return (int) (2 + (player.getLocation().getDistance(node.getLocation())) * 0.5); + } + + /** + * Checks if the catch was successful. + * @return {@code True} if so. + */ + public boolean success() { + if (originalLocation != node.getLocation()) { + return RandomFunction.random(1, 3) == 2; + } + return ((RandomFunction.getRandom(3) * player.getSkills().getLevel(Skills.HUNTER)) / 3) > (falconCatch.getLevel() / 2); + } + +} diff --git a/Server/src/main/content/global/skill/hunter/implings/ImplingBehavior.kt b/Server/src/main/content/global/skill/hunter/implings/ImplingBehavior.kt new file mode 100644 index 0000000..0848390 --- /dev/null +++ b/Server/src/main/content/global/skill/hunter/implings/ImplingBehavior.kt @@ -0,0 +1,83 @@ +package content.global.skill.hunter.implings + +import core.api.* +import core.tools.* +import core.game.world.map.RegionManager +import core.game.world.map.path.ClipMaskSupplier +import core.game.node.entity.npc.* +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.SpellBookManager +import core.game.node.item.Item +import core.game.node.entity.combat.CombatStyle +import content.global.skill.magic.spellconsts.Modern + +/** + * Manages the behavior for implings themselves. +*/ +class ImplingBehavior : NPCBehavior (*Impling.getIds()) { + override fun onCreation (self: NPC) { + self.isWalks = true + self.isNeverWalks = false + } + + override fun tick(self: NPC) : Boolean { + if (RandomFunction.roll(10)) + sendChat(self, "Tee-hee!") + return true + } + + override fun onRespawn(self: NPC) { + if (!isPuroImpling(self)) + log (this::class.java, Log.ERR, "Non-puro impling has respawned!") + sendGraphics(1119, self.properties.teleportLocation) + } + + override fun canBeAttackedBy(self: NPC, attacker: Entity, style: CombatStyle, shouldSendMessage: Boolean) : Boolean { + if (attacker !is Player) return false + + if (style != CombatStyle.MAGIC) { + if (shouldSendMessage) + sendMessage (attacker, "You can't do that.") + return false + } + + val spellBook = attacker.spellBookManager.spellBook + if (spellBook != SpellBookManager.SpellBook.MODERN.interfaceId) { + if (shouldSendMessage) + sendMessage (attacker, "The impling is too fast for that.") + return false + } + + val spellId = attacker.properties.spell.spellId + if (spellId != Modern.BIND && spellId != Modern.SNARE && spellId != Modern.ENTANGLE) { + if (shouldSendMessage) + sendMessage (attacker, "The impling is immune to that magic.") + return false + } + + return true + } + + override fun onDeathFinished (self: NPC, killer: Entity) { + if (!isPuroImpling(self)) + ImplingController.deregister(self) + else if (self.originalId != self.id) { //if this is a spawner that transformed + self.reTransform() //turn back into spawner NPC + self.behavior = forId(self.id) + } + } + + //manually clear any rolled drops so any drops set by JSON are properly ignored. + override fun onDropTableRolled (self: NPC, killer: Entity, drops: ArrayList) { + drops.clear() + } + + override fun getClippingSupplier (self: NPC) : ClipMaskSupplier { + return ImplingClipper + } + + private fun isPuroImpling (self: NPC) : Boolean { + return self.id > 6054 + } +} diff --git a/Server/src/main/content/global/skill/hunter/implings/ImplingController.kt b/Server/src/main/content/global/skill/hunter/implings/ImplingController.kt new file mode 100644 index 0000000..c27316a --- /dev/null +++ b/Server/src/main/content/global/skill/hunter/implings/ImplingController.kt @@ -0,0 +1,90 @@ +package content.global.skill.hunter.implings + +import core.api.* +import core.tools.* +import core.game.world.map.Location +import core.game.node.entity.npc.NPC +import core.game.system.command.* +import kotlin.math.* + +/** + * Manages the high-level behavior of implings in the overworld: Spawning them, clearing them, etc. + * NOTE: This does not manage the spawns INSIDE puro-puro. Those are actually handled by JSON. +*/ +class ImplingController : TickListener, Commands { + override fun tick() { + if (--nextCycle > getTicksBeforeNextCycleToDespawn()) + return + if (activeImplings.size > 0) { + clearSomeImplings(min(activeImplings.size, implingsClearedPerTick)) + return + } + generateSpawners() + nextCycle = secondsToTicks(60 * 30) // 30 minutes + } + + override fun defineCommands() { + define ("implings", Privilege.ADMIN, "", "Lists the currently active implings/spawners") { player, _ -> + for (i in 0..310) + setInterfaceText(player, "", 275, i) + setInterfaceText(player, "Implings", 275, 2) + for ((index, impling) in activeImplings.withIndex()) { + var text = "This shouldn't be here -> ${impling.id}" + if (impling.id < 1028) { + val table = ImplingSpawner.forId(impling.id) + if (table != null) + text = table.name + } + else text = impling.name + setInterfaceText(player, "$text -> ${impling.location}", 275, index + 11) + } + openInterface(player, 275) + } + } + + companion object { + val implingsClearedPerTick = 5 + + var nextCycle = 0 + var activeImplings = ArrayList() + + fun clearSomeImplings (amount: Int) { + for (i in 0 until amount) { + val impling = activeImplings.removeAt(0) + poofClear(impling) + } + } + + fun generateSpawners () { + val typeLocations = ImplingSpawnLocations.values() + for (set in typeLocations) { + val locations = set.locations + val type = set.type + locations.forEach { generateSpawnersAt(it, type) } + } + } + + fun generateSpawnersAt(location: Location, type: ImplingSpawnTypes) { + for (i in 0 until type.spawnRolls) { + val spawner = type.table.roll() ?: continue + if (spawner == ImplingSpawner.Nothing) continue + val npc = NPC.create (spawner.npcId, location) + npc.init() + activeImplings.add(npc) + } + } + + fun getTicksBeforeNextCycleToDespawn() : Int { + return ceil (activeImplings.size / implingsClearedPerTick.toDouble()).toInt() + } + + fun deregister (impling: NPC, graceful: Boolean = false) : Boolean { + activeImplings.remove(impling) + if (graceful) + poofClear(impling) + else + impling.clear() + return true + } + } +} diff --git a/Server/src/main/content/global/skill/hunter/implings/ImplingData.kt b/Server/src/main/content/global/skill/hunter/implings/ImplingData.kt new file mode 100644 index 0000000..affe203 --- /dev/null +++ b/Server/src/main/content/global/skill/hunter/implings/ImplingData.kt @@ -0,0 +1,178 @@ +package content.global.skill.hunter.implings + +import core.api.utils.* +import core.game.world.map.* +import core.game.world.map.path.* +import core.game.world.map.build.* + +enum class Impling (val npcId: Int, val puroId: Int) { + Baby (1028, 6055), + Young (1029, 6056), + Gourmet (1030, 6057), + Earth (1031, 6058), + Essence (1032, 6059), + Eclectic (1033, 6060), + Ninja (6053, 6063), + Nature (1034, 6061), + Magpie (1035, 6062), + Dragon (6054, 6064); + + companion object { + fun getIds() : IntArray { + val list = ArrayList() + for (imp in values()){ + list.add(imp.npcId) + list.add(imp.puroId) + } + return list.toIntArray() + } + } +} + +enum class ImplingSpawner (val npcId: Int, val table: WeightedTable) { + LowTier (npcId = 1024, WeightedTable.create + ( + Pair (Impling.Baby, 20.0), + Pair (Impling.Young, 20.0), + Pair (Impling.Gourmet, 20.0), + Pair (Impling.Earth, 20.0), + Pair (Impling.Essence, 10.0), + Pair (Impling.Eclectic,10.0) + )), + MidTier (npcId = 1025, WeightedTable.create + ( + Pair (Impling.Gourmet, 10.0), + Pair (Impling.Earth, 10.0), + Pair (Impling.Essence, 20.0), + Pair (Impling.Eclectic, 37.0), + Pair (Impling.Nature, 20.0), + Pair (Impling.Magpie, 2.0), + Pair (Impling.Ninja, 1.0) + )), + HighTier (npcId = 1026, WeightedTable.create + ( + Pair (Impling.Nature, 10.0), + Pair (Impling.Magpie, 50.0), + Pair (Impling.Ninja, 30.0), + Pair (Impling.Dragon, 10.0) + )), + LowPuroTier (npcId = 6065, WeightedTable.create + ( + Pair (Impling.Baby, 20.0), + Pair (Impling.Young, 20.0), + Pair (Impling.Gourmet, 20.0), + Pair (Impling.Earth, 20.0), + Pair (Impling.Essence, 10.0), + Pair (Impling.Eclectic,10.0) + )), + MidPuroTier (npcId = 6066, WeightedTable.create + ( + Pair (Impling.Gourmet, 10.0), + Pair (Impling.Earth, 10.0), + Pair (Impling.Essence, 20.0), + Pair (Impling.Eclectic, 37.0), + Pair (Impling.Nature, 20.0), + Pair (Impling.Magpie, 2.0), + Pair (Impling.Ninja, 1.0) + )), + HighPuroTier (npcId = 6067, WeightedTable.create + ( + Pair (Impling.Nature, 150.0), + Pair (Impling.Magpie, 114.0), + Pair (Impling.Ninja, 37.0), + Pair (Impling.Dragon, 10.0), + )), + Nothing (npcId = -1, WeightedTable()); + + companion object { + private val idMap = values().map { it.npcId to it }.toMap() + + fun forId (id: Int) : ImplingSpawner? { + return idMap[id] + } + + fun getIds() : IntArray { + return idMap.keys.toIntArray() + } + } +} + +enum class ImplingSpawnTypes (val table: WeightedTable, val spawnRolls: Int) { + Standard (WeightedTable.create + ( + Pair (ImplingSpawner.LowTier, 14.0), + Pair (ImplingSpawner.MidTier, 7.0), + Pair (ImplingSpawner.HighTier, 4.0), + Pair (ImplingSpawner.Nothing, 75.0) + ), spawnRolls = 3), + LowTierOnly (WeightedTable.create + ( + Pair (ImplingSpawner.LowTier, 100.0) + ), spawnRolls = 1), + MidTierOnly (WeightedTable.create + ( + Pair (ImplingSpawner.MidTier, 100.0) + ), spawnRolls = 1), + HighTierOnly (WeightedTable.create + ( + Pair (ImplingSpawner.HighTier, 100.0) + ), spawnRolls = 1), + HighPuroTierOnly (WeightedTable.create + ( + Pair (ImplingSpawner.HighPuroTier, 100.0) + ), spawnRolls = 1) +} + +enum class ImplingSpawnLocations (val type: ImplingSpawnTypes, vararg val locations: Location) { + StandardSpawns (ImplingSpawnTypes.Standard, + Location.create(2204, 3232, 0), + Location.create(2582, 2974, 0), + Location.create(2522, 3105, 0), + Location.create(2470, 3221, 0), + Location.create(2593, 3251, 0), + Location.create(2735, 3354, 0), + Location.create(2646, 3424, 0), + Location.create(2462, 3429, 0), + Location.create(2386, 3513, 0), + Location.create(2335, 3649, 0), + Location.create(2740, 3536, 0), + Location.create(2654, 3609, 0), + Location.create(2724, 3769, 0), + Location.create(2817, 3513, 0), + Location.create(2844, 3154, 0), + Location.create(2844, 3033, 0), + Location.create(2841, 2926, 0), + Location.create(2907, 3491, 0), + Location.create(3020, 3525, 0), + Location.create(3021, 3424, 0), + Location.create(2981, 3276, 0), + Location.create(3135, 3377, 0), + Location.create(3149, 3233, 0), + Location.create(3170, 3004, 0), + Location.create(3239, 3289, 0), + Location.create(3287, 3271, 0), + Location.create(3418, 3124, 0), + Location.create(3356, 3010, 0), + Location.create(3550, 3529, 0), + Location.create(3449, 3488, 0), + Location.create(3441, 3352, 0) + ), + LowTierOnlySpawns (ImplingSpawnTypes.LowTierOnly, + Location.create(2348, 3610, 0), + Location.create(2277, 3186, 0), + Location.create(2459, 3085, 0), + Location.create(2564, 3393, 0), + Location.create(2780, 3463, 0), + Location.create(2966, 3411, 0), + Location.create(3094, 3237, 0), + Location.create(3281, 3427, 0), + Location.create(3278, 3160, 0) + ) +} + +object ImplingClipper : ClipMaskSupplier { + override fun getClippingFlag (z: Int, x: Int, y: Int) : Int { + var flag = RegionManager.getClippingFlag(z, x, y) + return flag and (RegionFlags.SOLID_TILE.inv()) and (RegionFlags.TILE_OBJECT.inv()) //Allow walking on water and flying over small objects, but keep all other tile flags the same. + } +} diff --git a/Server/src/main/content/global/skill/hunter/implings/ImplingSpawnerBehavior.kt b/Server/src/main/content/global/skill/hunter/implings/ImplingSpawnerBehavior.kt new file mode 100644 index 0000000..ad49144 --- /dev/null +++ b/Server/src/main/content/global/skill/hunter/implings/ImplingSpawnerBehavior.kt @@ -0,0 +1,52 @@ +package content.global.skill.hunter.implings + +import core.api.* +import core.tools.* +import core.game.node.entity.npc.* +import core.game.world.map.path.ClipMaskSupplier + +/** + * Manages the behavior for impling spawners (the invisible NPCs that turn into random implings). +*/ +class ImplingSpawnerBehavior : NPCBehavior (*ImplingSpawner.getIds()) { + override fun onCreation (self: NPC) { + val isPuro = isPuroSpawner(self) + val delay = if (isPuro) 120 else 180 + setAttribute(self, "transformTime", getWorldTicks() + secondsToTicks(delay)) + self.setRespawnTicks(3) + self.isRespawn = isPuro + self.walkRadius = if (isPuro) 20 else 100 + self.isWalks = true + self.isNeverWalks = false + self.setInvisible(true) + } + + override fun onRespawn (self: NPC) { + if (!isPuroSpawner(self)) + log (this::class.java, Log.ERR, "Non-puro spawner has respawned!") + this.onCreation(self) + } + + override fun tick (self: NPC) : Boolean { + var transformTime = getAttribute(self, "transformTime", 0) + if (transformTime != 0 && transformTime <= getWorldTicks()) { + val table = ImplingSpawner.forId(self.id)?.table ?: return ImplingController.deregister(self) + val impling = table.roll() ?: return ImplingController.deregister(self) + val targetId = if (isPuroSpawner(self)) impling.puroId else impling.npcId + self.transform(targetId) + self.behavior = forId(self.id) + self.setInvisible(false) + removeAttribute(self, "transformTime") + sendGraphics(1119, self.location) + } + return true + } + + override fun getClippingSupplier (self: NPC) : ClipMaskSupplier { + return ImplingClipper + } + + private fun isPuroSpawner(self: NPC) : Boolean { + return self.id > 6000 + } +} diff --git a/Server/src/main/content/global/skill/hunter/pitfall/HunterPitfall.kt b/Server/src/main/content/global/skill/hunter/pitfall/HunterPitfall.kt new file mode 100644 index 0000000..f4959cb --- /dev/null +++ b/Server/src/main/content/global/skill/hunter/pitfall/HunterPitfall.kt @@ -0,0 +1,338 @@ +import java.util.concurrent.TimeUnit + +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.impl.Animator.Priority +import core.game.node.entity.impl.ForceMovement +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import content.global.skill.hunter.HunterManager +import core.game.node.item.Item +import core.game.node.scenery.Scenery +import core.game.system.task.Pulse +import core.game.world.map.Direction +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.plugin.Initializable +import core.tools.RandomFunction +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.game.world.GameWorld +import org.rs09.consts.Sounds + +/*@Initializable +class HunterPitfall : OptionHandler() { + //19227, + val graahkPitIds = intArrayOf(19227)//, 19268,19267,19266,19264,19265) + val GRAAHK_ID = 5105 + val hunterReq = 41 + override fun handle(player: Player?, node: Node?, option: String?): Boolean { + node ?: return true + player ?: return true + player.sendMessage("Hello from HunterPitfall: ${option}") + when(option) { + "tease" -> { + (node as Entity).attack(player) + } + } + return true + } + + override fun newInstance(arg: Any?): Plugin { + for(graahkPit in graahkPitIds) { + SceneryDefinition.forId(graahkPit).handlers["option:trap"] = this + } + //NPCDefinition.forId(GRAAHK_ID).handlers["option:tease"] = this + return this + } +}*/ + +val LARUPIA_IDS: IntArray = intArrayOf(NPCs.SPINED_LARUPIA_5104) +val GRAAHK_IDS: IntArray = intArrayOf(NPCs.HORNED_GRAAHK_5105, NPCs.HORNED_GRAAHK_5106, NPCs.HORNED_GRAAHK_5107, NPCs.HORNED_GRAAHK_5108) +val KYATT_IDS: IntArray = intArrayOf(NPCs.SABRE_TOOTHED_KYATT_5103, NPCs.SABRE_TOOTHED_KYATT_7497) +val BEAST_IDS: IntArray = intArrayOf(*LARUPIA_IDS, *GRAAHK_IDS, *KYATT_IDS) +val HUNTER_REQS = hashMapOf( + "Spined larupia" to 31, + "Horned graahk" to 41, + "Sabre-toothed kyatt" to 55, + ) +//val pitVarpOffsets = hashMapOf( 19264 to 3, 19265 to 6, 19266 to 9, 19267 to 12, 19268 to 15,) +data class Pit(val varbitId: Int, val horizontal: Boolean) +val pitVarps = hashMapOf( + // Larupia pits (the duplicate 24 is likely authentic) + Location.create(2565,2888) to Pit(2967, true), + Location.create(2573,2885) to Pit(2968, false), + Location.create(2556,2893) to Pit(2964, false), + Location.create(2552,2904) to Pit(2966, true), + Location.create(2543,2908) to Pit(2965, false), + Location.create(2538,2899) to Pit(2966, true), + // Kyatt pits + Location.create(2700,3795) to Pit(2958, true), + Location.create(2700,3785) to Pit(2959, false), + Location.create(2706,3789) to Pit(2960, false), + Location.create(2730,3791) to Pit(2961, true), + Location.create(2737,3784) to Pit(2962, true), + Location.create(2730,3780) to Pit(2963, false), + // Graahk pits + Location.create(2766,3010) to Pit(2969, false), + Location.create(2762,3005) to Pit(2970, false), + Location.create(2771,3004) to Pit(2971, true), + Location.create(2777,3001) to Pit(2972, false), + Location.create(2784,3001) to Pit(2973, true), + ) +/*val pitJumpSpots = hashMapOf( + Location.create(2766,3010) to hashMapOf( + Location.create(2766,3009) to Direction.NORTH, + Location.create(2767,3009) to Direction.NORTH, + Location.create(2766,3012) to Direction.SOUTH, + Location.create(2767,3012) to Direction.SOUTH, + ), + Location.create(2762,3005) to hashMapOf( + Location.create(2762,3004) to Direction.NORTH, + Location.create(2763,3004) to Direction.NORTH, + Location.create(2762,3007) to Direction.SOUTH, + Location.create(2763,3007) to Direction.SOUTH, + ), + Location.create(2771,3004) to hashMapOf( + Location.create(2770,3004) to Direction.EAST, + Location.create(2770,3005) to Direction.EAST, + Location.create(2773,3004) to Direction.WEST, + Location.create(2773,3005) to Direction.WEST, + ), + Location.create(2777,3001) to hashMapOf( + Location.create(2777,3000) to Direction.NORTH, + Location.create(2778,3000) to Direction.NORTH, + Location.create(2777,3003) to Direction.SOUTH, + Location.create(2778,3003) to Direction.SOUTH, + ), + Location.create(2784,3001) to hashMapOf( + Location.create(2783,3002) to Direction.EAST, + Location.create(2783,3001) to Direction.EAST, + Location.create(2786,3002) to Direction.WEST, + Location.create(2786,3001) to Direction.WEST, + ), + )*/ +fun pitJumpSpots(loc: Location): HashMap? { + val pit = pitVarps[loc] ?: return null + if(pit.horizontal) { + return hashMapOf( + loc.transform(-1, 0, 0) to Direction.EAST, + loc.transform(-1, 1, 0) to Direction.EAST, + loc.transform(2, 0, 0) to Direction.WEST, + loc.transform(2, 1, 0) to Direction.WEST, + ) + } else { + return hashMapOf( + loc.transform(0, -1, 0) to Direction.NORTH, + loc.transform(1, -1, 0) to Direction.NORTH, + loc.transform(0, 2, 0) to Direction.SOUTH, + loc.transform(1, 2, 0) to Direction.SOUTH, + ) + } +} + +val KNIFE = Item(Items.KNIFE_946) +val TEASING_STICK = Item(Items.TEASING_STICK_10029) +val LOGS = Item(Items.LOGS_1511) + +val PIT = 19227 +val SPIKED_PIT = 19228 +val GRAAHK_PIT = 19231 +val LARUPIA_PIT = 19232 +val KYATT_PIT = 19233 + +class PitfallListeners : InteractionListener { + + override fun defineListeners() { + setDest(IntType.SCENERY, intArrayOf(PIT, SPIKED_PIT, LARUPIA_PIT, GRAAHK_PIT, KYATT_PIT), "trap", "jump", "dismantle") { player, node -> + val pit = node as Scenery + val src = player.getLocation() + var dst = pit.getLocation() + val locs = pitJumpSpots(dst) + if(locs != null) { + for(loc in locs.keys) { + if(src.getDistance(loc) <= src.getDistance(dst)) { + dst = loc + } + } + } else { + if(player is Player) { + player.sendMessage("Error: Unimplemented pit at ${pit.location}") + } + } + return@setDest dst + } + on(PIT, IntType.SCENERY, "trap") { player, node -> + val pit = node as Scenery + // TODO: check hunter level, remove logs + if(player.skills.getLevel(Skills.HUNTER) < 31) { + player.sendMessage("You need a hunter level of 31 to set a pitfall trap.") + return@on true + } + + val maxTraps = HunterManager.getInstance(player).maximumTraps + if(player.getAttribute("pitfall:count", 0) >= maxTraps) { + player.sendMessage("You can't set up more than $maxTraps pitfall traps at your hunter level.") + return@on true + } + player.incrementAttribute("pitfall:count", 1) + + if(!player.inventory.containsItem(KNIFE) || !player.inventory.remove(LOGS)) { + player.sendMessage("You need some logs and a knife to set a pitfall trap.") + return@on true + } + + player.setAttribute("pitfall:timestamp:${pit.location.x}:${pit.location.y}", System.currentTimeMillis()) + setPitState(player, pit.location, 1) + playAudio(player, Sounds.HUNTING_PLACEBRANCHES_2639) + val collapsePulse = object : Pulse(201, player) { + override fun pulse(): Boolean { + val oldTime = player.getAttribute("pitfall:timestamp:${pit.location.x}:${pit.location.y}", System.currentTimeMillis()) + if(System.currentTimeMillis() - oldTime >= TimeUnit.MINUTES.toMillis(2)) { + player.sendMessage("Your pitfall trap has collapsed.") + setPitState(player, pit.location, 0) + player.incrementAttribute("pitfall:count", -1) + } + return true + } + } + GameWorld.Pulser.submit(collapsePulse) + return@on true + } + on(SPIKED_PIT, IntType.SCENERY, "jump") { player, node -> + val pit = node as Scenery + val src = player.getLocation() + val dir = pitJumpSpots(pit.getLocation())!![src] + if(dir != null) { + val dst = src.transform(dir, 3) + ForceMovement.run(player, src, dst, ForceMovement.WALK_ANIMATION, Animation(1603), dir, 16) + playAudio(player, Sounds.HUNTING_JUMP_2635) + val pitfall_npc: Entity? = player.getAttribute("pitfall_npc", null) + if(pitfall_npc != null && pitfall_npc.getLocation().getDistance(src) < 3.0) { + val last_pit_loc: Location? = pitfall_npc.getAttribute("last_pit_loc", null) + if(last_pit_loc == pit.location) { + player.sendMessage("The ${pitfall_npc.name.toLowerCase()} won't jump the same pit twice in a row.") + return@on true + } + // TODO: what are the actual probabilities of a graahk jumping over a pit? + val chance = RandomFunction.getSkillSuccessChance(50.0, 100.0, player.skills.getLevel(Skills.HUNTER)) + if(RandomFunction.random(0.0, 100.0) < chance) { + //ForceMovement.run(pitfall_npc, pitfall_npc.getLocation(), pit.getLocation(), ForceMovement.WALK_ANIMATION, Animation(ANIM), dir, 8); + //pitfall_npc.setLocation(pit.getLocation()); + //pitfall_npc.walkingQueue.addPath(pit.location.x, pit.location.y); + teleport(pitfall_npc, pit.location) + pitfall_npc.removeAttribute("last_pit_loc") + playAudio(player, Sounds.HUNTING_PITFALL_COLLAPSE_2638, 0, 1, pit.location, 10) + playAudio(player, Sounds.PANTHER_DEATH_667, 50, 1, pit.location, 10) + pitfall_npc.startDeath(null) + player.removeAttribute("pitfall:timestamp:${pit.location.x}:${pit.location.y}") + player.incrementAttribute("pitfall:count", -1) + setPitState(player, pit.location, 3) + //pitfall_npc.animate(Animation(5234)) + } else { + //ForceMovement.run(pitfall_npc, pitfall_npc.getLocation(), dst, ForceMovement.WALK_ANIMATION, Animation(ANIM), dir, 8); + //pitfall_npc.walkingQueue.addPath(npcdst.x, npcdst.y) + val npcdst = dst.transform(dir, if(dir == Direction.SOUTH || dir == Direction.WEST) 1 else 0) + teleport(pitfall_npc, npcdst) + pitfall_npc.animate(Animation(5232, Priority.HIGH)) + playAudio(player, Sounds.HUNTING_BIGCAT_JUMP_2619, 0, 1, pit.location, 10) + pitfall_npc.attack(player) + pitfall_npc.setAttribute("last_pit_loc", pit.location) + } + } + } + return@on true + } + on(SPIKED_PIT, IntType.SCENERY, "dismantle") { player, node -> + val pit = node as Scenery + playAudio(player, Sounds.HUNTING_TAKEBRANCHES_2649) + player.removeAttribute("pitfall:timestamp:${pit.location.x}:${pit.location.y}") + player.incrementAttribute("pitfall:count", -1) + setPitState(player, pit.location, 0) + return@on true + } + on(LARUPIA_PIT, IntType.SCENERY, "dismantle") { player, node -> + lootCorpse(player, node as Scenery, 180.0, Items.LARUPIA_FUR_10095, Items.TATTY_LARUPIA_FUR_10093) + sendMessage(player, "You've caught a spined larupia!") + return@on true + } + on(GRAAHK_PIT, IntType.SCENERY, "dismantle") { player, node -> + lootCorpse(player, node as Scenery, 240.0, Items.GRAAHK_FUR_10099, Items.TATTY_GRAAHK_FUR_10097) + sendMessage(player, "You've caught a horned graahk!") + return@on true + } + on(KYATT_PIT, IntType.SCENERY, "dismantle") { player, node -> + lootCorpse(player, node as Scenery, 300.0, Items.KYATT_FUR_10103, Items.TATTY_KYATT_FUR_10101) + sendMessage(player, "You've caught a sabretoothed kyatt!") + return@on true + } + on(BEAST_IDS, IntType.NPC, "tease") { player, node -> + val entity = node as Entity + val hunterReq = HUNTER_REQS[entity.name]!! + if(player.skills.getLevel(Skills.HUNTER) < hunterReq) { + player.sendMessage("You need a hunter level of ${hunterReq} to hunt ${entity.name.toLowerCase()}s.") + return@on true + } + if(!player.inventory.containsItem(TEASING_STICK)) { + player.sendMessage("You need a teasing stick to hunt ${entity.name.toLowerCase()}s.") + return@on true + } + entity.attack(player) + playAudio(player, Sounds.HUNTING_TEASE_FELINE_2651) + player.setAttribute("pitfall_npc", entity) + return@on true + } + } + + fun lootCorpse(player: Player, pit: Scenery, xp: Double, goodFur: Int, badFur: Int) { + if(player.inventory.freeSlots() < 2) { + player.sendMessage("You don't have enough inventory space. You need 2 more free slots.") + return + } + setPitState(player, pit.location, 0) + player.getSkills().addExperience(Skills.HUNTER, xp, true) + player.inventory.add(Item(Items.BIG_BONES_532)) + playAudio(player, Sounds.HUNTING_TAKEBRANCHES_2649) + // TODO: what's the actual probability of tatty vs perfect fur? + val chance = RandomFunction.getSkillSuccessChance(50.0, 100.0, player.skills.getLevel(Skills.HUNTER)) + if(RandomFunction.random(0.0, 100.0) < chance) { + player.inventory.add(Item(goodFur)) + } else { + player.inventory.add(Item(badFur)) + } + } + + fun setPitState(player: Player, loc: Location, state: Int) { + val pit = pitVarps[loc]!! + setVarbit(player, pit.varbitId, state) + } +} + +@Initializable +class PitfallNPC : AbstractNPC { + constructor() : super(NPCs.HORNED_GRAAHK_5105, null, true) {} + private constructor(id: Int, location: Location) : super(id, location) {} + override fun construct(id: Int, location: Location, vararg objects: Any?): AbstractNPC { + return PitfallNPC(id, location) + } + + init { + walkRadius = 22 + } + + override fun getIds(): IntArray { + return BEAST_IDS + } + + override fun isAttackable(entity: Entity, style: CombatStyle, message: Boolean): Boolean { + return false + } + + override fun isIgnoreAttackRestrictions(victim: Entity): Boolean { + return victim is Player + } +} diff --git a/Server/src/main/content/global/skill/hunter/tracking/CommonKebbitEast.kt b/Server/src/main/content/global/skill/hunter/tracking/CommonKebbitEast.kt new file mode 100644 index 0000000..a78e64f --- /dev/null +++ b/Server/src/main/content/global/skill/hunter/tracking/CommonKebbitEast.kt @@ -0,0 +1,74 @@ +package content.global.skill.hunter.tracking + +import core.cache.def.impl.SceneryDefinition +import core.game.node.item.Item +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.plugin.Initializable +import core.plugin.Plugin +import org.rs09.consts.Items + +@Initializable +class CommonKebbitEast : HunterTracking() { + + init { + initialMap = hashMapOf( + 19439 to arrayListOf( + TrailDefinition(2974,TrailType.LINKING, false,Location.create(2354, 3595, 0),Location.create(2360, 3602, 0)), + TrailDefinition(2975,TrailType.LINKING,false,Location.create(2354, 3595, 0),Location.create(2355, 3601, 0)), + TrailDefinition(2976,TrailType.LINKING,false,Location.create(2354, 3594, 0),Location.create(2349, 3604, 0)) + ), + 19440 to arrayListOf( + TrailDefinition(2980,TrailType.LINKING,true,Location.create(2361, 3611, 0),Location.create(2360, 3602, 0)), + TrailDefinition(2981,TrailType.LINKING,true,Location.create(2360, 3612, 0),Location.create(2357, 3607, 0)) + ) + ) + + linkingTrails = arrayListOf( + TrailDefinition(2982,TrailType.LINKING,false,Location.create(2357, 3607, 0),Location.create(2354, 3609, 0),Location.create(2355, 3608, 0)), + TrailDefinition(2983,TrailType.LINKING,false,Location.create(2354, 3609, 0),Location.create(2349, 3604, 0),Location.create(2351, 3608, 0)), + TrailDefinition(2977,TrailType.LINKING,false ,Location.create(2360, 3602, 0),Location.create(2355, 3601, 0),Location.create(2358, 3599, 0)), + TrailDefinition(2978,TrailType.LINKING,false,Location.create(2355, 3601, 0),Location.create(2349, 3604, 0),Location.create(2352, 3603, 0)), + TrailDefinition(2979,TrailType.LINKING,false,Location.create(2360, 3602, 0),Location.create(2357, 3607, 0),Location.create(2358, 3603, 0)) + ) + experience = 36.0 + varp = 919 + trailLimit = 3 + attribute = "hunter:tracking:commontrail" + indexAttribute = "hunter:tracking:commonIndex" + rewards = arrayOf(Item(Items.COMMON_KEBBIT_FUR_10121), Item(Items.BONES_526),Item(Items.RAW_BEAST_MEAT_9986)) + KEBBIT_ANIM = Animation(5259) + } + + + override fun newInstance(arg: Any?): Plugin { + if(!linkingTrails.contains(initialMap.values.random()[0])){ + addExtraTrails() + } + SceneryDefinition.forId(19439).handlers["option:inspect"] = this + SceneryDefinition.forId(19440).handlers["option:inspect"] = this + SceneryDefinition.forId(19360).handlers["option:inspect"] = this + SceneryDefinition.forId(19361).handlers["option:inspect"] = this + SceneryDefinition.forId(19362).handlers["option:inspect"] = this + SceneryDefinition.forId(19363).handlers["option:inspect"] = this + SceneryDefinition.forId(19364).handlers["option:inspect"] = this + SceneryDefinition.forId(19365).handlers["option:inspect"] = this + SceneryDefinition.forId(19356).handlers["option:inspect"] = this + SceneryDefinition.forId(19357).handlers["option:inspect"] = this + SceneryDefinition.forId(19358).handlers["option:inspect"] = this + SceneryDefinition.forId(19359).handlers["option:inspect"] = this + SceneryDefinition.forId(19375).handlers["option:inspect"] = this + SceneryDefinition.forId(19376).handlers["option:inspect"] = this + SceneryDefinition.forId(19377).handlers["option:inspect"] = this + SceneryDefinition.forId(19378).handlers["option:inspect"] = this + SceneryDefinition.forId(19379).handlers["option:inspect"] = this + SceneryDefinition.forId(19372).handlers["option:inspect"] = this + SceneryDefinition.forId(19380).handlers["option:inspect"] = this + SceneryDefinition.forId(19374).handlers["option:inspect"] = this + SceneryDefinition.forId(19373).handlers["option:inspect"] = this + SceneryDefinition.forId(19428).handlers["option:search"] = this + SceneryDefinition.forId(19428).handlers["option:attack"] = this + + return this + } +} diff --git a/Server/src/main/content/global/skill/hunter/tracking/CommonKebbitWest.kt b/Server/src/main/content/global/skill/hunter/tracking/CommonKebbitWest.kt new file mode 100644 index 0000000..537d443 --- /dev/null +++ b/Server/src/main/content/global/skill/hunter/tracking/CommonKebbitWest.kt @@ -0,0 +1,4 @@ +package content.global.skill.hunter.tracking + +class CommonKebbitWest { +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/hunter/tracking/HunterTracking.kt b/Server/src/main/content/global/skill/hunter/tracking/HunterTracking.kt new file mode 100644 index 0000000..3a56ee5 --- /dev/null +++ b/Server/src/main/content/global/skill/hunter/tracking/HunterTracking.kt @@ -0,0 +1,266 @@ +package content.global.skill.hunter.tracking + +import core.api.* +import core.game.interaction.OptionHandler +import core.game.node.Node +import core.game.node.scenery.Scenery +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.tools.RandomFunction +import org.rs09.consts.Items +import core.game.world.GameWorld +import core.tools.Log +import org.rs09.consts.Sounds +import java.util.* + +/** + * Main class for hunter tracking. All the other subclasses just define values that the methods in this class use. + * @author Ceikry + */ +abstract class HunterTracking : OptionHandler(){ + var KEBBIT_ANIM = Animation(0) + val MISS_ANIM = Animation(5255) + var trailLimit = 0 + var attribute = "" + var indexAttribute = "" + var rewards = Array(0){Item(0)} + var tunnelEntrances = Array(0){ Location(0,0,0) } + var initialMap = HashMap>() + var linkingTrails = ArrayList() + var experience = 0.0 + var varp = 0 + var requiredLevel = 1 + + /** + * Gets the initial trail based on the ID of the hole object the player clicked on + * @author Ceikry + */ + fun getInitialTrail(obj: Scenery): TrailDefinition? { + return initialMap[obj.id]?.random() + } + + /** + * Generates the entire trail all at once. + * @author Ceikry + */ + fun generateTrail(startobj: Scenery, player: Player) { + val trail = player.getAttribute(attribute, ArrayList()) + val initialTrail = getInitialTrail(startobj) + if(initialTrail == null) { + log(this::class.java, Log.WARN, "UNHANDLED STARTING OBJECT FOR HUNTER TRACKING $startobj") + return + } + trail.add(initialTrail) + player.setAttribute(attribute,trail) + + var numSpots = RandomFunction.random(2,trailLimit) + var triesRemaining = numSpots * 3 + + while(numSpots > 0){ + if(triesRemaining-- <= 0) { + clearTrail(player) + return + } + val nextTrail = getLinkingTrail(player) + nextTrail ?: continue + var offsetUsed = false + for(i in trail){ + if(i.varbit == nextTrail.varbit){ offsetUsed = true; break } + } + if(offsetUsed) continue + if(nextTrail.type == TrailType.TUNNEL){ + trail.add(nextTrail) + continue + } + trail.add(nextTrail) + player.setAttribute(attribute,trail) + numSpots-- + } + } + + /** + * Gets a linking trail point, used to build entire trails + * @author Ceikry + */ + fun getLinkingTrail(player: Player): TrailDefinition? { + val trail = player.getAttribute(attribute,ArrayList()) + val previousTrail = trail.get(trail.lastIndex) + if(previousTrail.type == TrailType.TUNNEL){ + val possibleTrails = ArrayList() + for(trail in linkingTrails){ + val invTrail = getTrailInverse(trail,false) + if(invTrail.type == TrailType.TUNNEL && previousTrail.endLocation.withinDistance(invTrail.startLocation,5) && !previousTrail.endLocation.equals(invTrail.startLocation) && previousTrail.varbit != trail.varbit){ + possibleTrails.add(trail) + } + } + return possibleTrails.random() + } + val possibleTrails = ArrayList() + for(trail in linkingTrails){ + if(trail.startLocation.equals(previousTrail.endLocation) && previousTrail.varbit != trail.varbit){ + possibleTrails.add(trail) + } + } + return possibleTrails.random() + } + + + /** + * Inverts a trail so trails only have to be defined manually in one direction + * @author Ceikry + */ + fun getTrailInverse(trail: TrailDefinition, swapLocations: Boolean): TrailDefinition{ + if(swapLocations) + return TrailDefinition(trail.varbit,if(tunnelEntrances.contains(trail.startLocation)) TrailType.TUNNEL else TrailType.LINKING,!trail.inverted,trail.endLocation,trail.startLocation, trail.triggerObjectLocation) + return TrailDefinition(trail.varbit, if(tunnelEntrances.contains(trail.startLocation)) TrailType.TUNNEL else TrailType.LINKING, !trail.inverted, trail.startLocation, trail.endLocation) + } + + /** + * Populates the linked trail list with inverses of the manually defined trails + * @author Ceikry + */ + fun addExtraTrails(){ + linkingTrails.toTypedArray().forEach { trail -> + linkingTrails.add(getTrailInverse(trail,true)) + } + if(this is PolarKebbitHunting){ + initialMap.values.forEach { + linkingTrails.addAll(it) + it.forEach { trail -> + linkingTrails.add(getTrailInverse(trail, true)) + } + } + } + } + + /** + * Resets a player's trail + * @author Ceikry + */ + fun clearTrail(player: Player){ + player.removeAttribute(attribute) + player.removeAttribute(indexAttribute) + setVarp(player, varp, 0) + } + + /** + * Check if a player has an active trail + * @author Ceikry + */ + fun hasTrail(player: Player): Boolean{ + return player.getAttribute(attribute,null) != null + } + + /** + * Rewards the player with items from the rewards array and awards experience. + * Pass false to success to just play the kebbit animation without rewarding anything. + * @author Ceikry + */ + fun reward(player: Player, success: Boolean) { + player.lock() + player.animator.animate(if(success) KEBBIT_ANIM else MISS_ANIM) + playAudio(player, Sounds.HUNTING_NOOSE_2637) + GameWorld.Pulser.submit(object : Pulse(KEBBIT_ANIM.duration){ + override fun pulse(): Boolean { + if(hasTrail(player) && success){ + for(item in rewards){ + if(!player.inventory.add(item)) + GroundItemManager.create(item,player) + } + player.skills.addExperience(Skills.HUNTER,experience) + clearTrail(player) + } + player.unlock() + return true + } + }) + } + + /** + * Updates the trail varp based on the current trail index + * @author Ceikry + */ + fun updateTrail(player: Player){ + player ?: return + val trail = player.getAttribute(attribute,ArrayList()) + val trailIndex = player.getAttribute(indexAttribute,0) + for(index in 0..trailIndex){ + val trl = trail[index] + var current = getVarp(player, varp) + setVarbit(player, trl.varbit, (if (trl.inverted) 1 else 0) or (1 shl 2)) + } + } + + /** + * Handles all trail interactions + * @author Ceikry + */ + override fun handle(player: Player?, node: Node?, option: String?): Boolean { + node ?: return true + player ?: return true + val trail = player.getAttribute(attribute,ArrayList()) + val currentIndex = player.getAttribute(indexAttribute,0) + if(!hasTrail(player) && !initialMap.containsKey(node.id)){ + player.dialogueInterpreter.sendDialogue("You search but find nothing.") + return true + } + val currentTrail = if(hasTrail(player)) { + if (currentIndex < trail.lastIndex) { + trail.get(currentIndex + 1) + } else { + trail.get(currentIndex) + } + } else { + TrailDefinition(0,TrailType.LINKING,false,Location(0,0,0),Location(0,0,0),Location(0,0,0)) + } + when(option){ + + "attack" -> { + if(!hasNooseWand(player)){ + player.dialogueInterpreter.sendDialogue("You need a noose wand to catch the kebbit.") + return true + } + if(currentIndex == trail.lastIndex && currentTrail.endLocation.equals(node.location)){ + reward(player,true) + } else { + reward(player,false) + } + } + + "inspect","search" -> { + if(!hasTrail(player)){ + if(player.skills.getLevel(Skills.HUNTER) < requiredLevel){ + player.dialogueInterpreter.sendDialogue("You need a hunter level of $requiredLevel to track these.") + return true + } + generateTrail(node.asScenery(),player) + updateTrail(player) + } else { + if(currentTrail.triggerObjectLocation.equals(node.location) || (currentIndex == trail.lastIndex && currentTrail.endLocation.equals(node.location))){ + if(currentIndex == trail.lastIndex){ + player.dialogueInterpreter.sendDialogue("It looks like something is moving around in there.") + } else { + player.dialogueInterpreter.sendDialogue("You discover some tracks nearby.") + player.incrementAttribute(indexAttribute) + updateTrail(player) + } + } else { + player.dialogueInterpreter.sendDialogue("You search but find nothing of interest.") + } + } + } + + + } + return true + } + + fun hasNooseWand(player: Player) : Boolean{ + return player.equipment.contains(Items.NOOSE_WAND_10150,1) || player.inventory.contains(Items.NOOSE_WAND_10150,1) + } +} diff --git a/Server/src/main/content/global/skill/hunter/tracking/PolarKebbitHunting.kt b/Server/src/main/content/global/skill/hunter/tracking/PolarKebbitHunting.kt new file mode 100644 index 0000000..92e8744 --- /dev/null +++ b/Server/src/main/content/global/skill/hunter/tracking/PolarKebbitHunting.kt @@ -0,0 +1,68 @@ +package content.global.skill.hunter.tracking + +import core.cache.def.impl.SceneryDefinition +import core.game.node.item.Item +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.plugin.Initializable +import core.plugin.Plugin +import org.rs09.consts.Items + +@Initializable +class PolarKebbitHunting : HunterTracking() { + + init { + KEBBIT_ANIM = Animation(5256) + trailLimit = 3 + attribute = "hunter:tracking:polartrail" + indexAttribute = "hunter:tracking:polarindex" + rewards = arrayOf(Item(Items.RAW_BEAST_MEAT_9986),Item(Items.POLAR_KEBBIT_FUR_10117),Item(Items.BONES_526)) + tunnelEntrances = arrayOf( + Location.create(2711, 3819, 1), + Location.create(2714, 3821, 1), + Location.create(2718, 3829, 1), + Location.create(2721, 3827, 1), + Location.create(2718, 3832, 1), + Location.create(2715, 3820, 1) + ) + initialMap = hashMapOf( + 19640 to arrayListOf( + TrailDefinition(3061,TrailType.TUNNEL,false,Location.create(2712, 3831, 1),Location.create(2718, 3832, 1)), + TrailDefinition(3060,TrailType.LINKING,true,Location.create(2712, 3831, 1),Location.create(2716, 3827, 1),Location.create(2713,3827,1)), + TrailDefinition(3057,TrailType.LINKING,false,Location.create(2712, 3831, 1),Location.create(2708, 3819, 1),Location.create(2708,3825,1)) + ), + 19641 to arrayListOf( + TrailDefinition(3053,TrailType.LINKING,true,Location.create(2718, 3820, 1),Location.create(2708, 3819, 1),Location.create(2712,3815,1)), + TrailDefinition(3055,TrailType.TUNNEL,false, Location.create(2718, 3820, 1),Location.create(2715, 3820, 1)), + TrailDefinition(3056,TrailType.TUNNEL,false,Location.create(2718, 3820, 1),Location.create(2721, 3827, 1)) + ) + ) + linkingTrails = arrayListOf( + TrailDefinition(3058,TrailType.LINKING,true,Location.create(2714,3821,1),Location.create(2716, 3827, 1)), + TrailDefinition(3059,TrailType.TUNNEL,true,Location.create(2716, 3827, 1),Location.create(2718,3829,1)), + TrailDefinition(3054,TrailType.TUNNEL,false,Location.create(2708, 3819, 1),Location.create(2711, 3819, 1)) + ) + experience = 30.0 + varp = 926 + requiredLevel = 1 + } + + override fun newInstance(arg: Any?): Plugin { + addExtraTrails() + SceneryDefinition.forId(19640).handlers["option:inspect"] = this + SceneryDefinition.forId(19641).handlers["option:inspect"] = this + SceneryDefinition.forId(19435).handlers["option:inspect"] = this + SceneryDefinition.forId(36689).handlers["option:inspect"] = this + SceneryDefinition.forId(36690).handlers["option:inspect"] = this + SceneryDefinition.forId(19421).handlers["option:inspect"] = this + SceneryDefinition.forId(19424).handlers["option:inspect"] = this + SceneryDefinition.forId(19426).handlers["option:inspect"] = this + SceneryDefinition.forId(19419).handlers["option:inspect"] = this + SceneryDefinition.forId(19420).handlers["option:inspect"] = this + SceneryDefinition.forId(19423).handlers["option:inspect"] = this + SceneryDefinition.forId(36688).handlers["option:inspect"] = this + SceneryDefinition.forId(19435).handlers["option:search"] = this + SceneryDefinition.forId(19435).handlers["option:attack"] = this + return this + } +} diff --git a/Server/src/main/content/global/skill/hunter/tracking/TrailDefinition.kt b/Server/src/main/content/global/skill/hunter/tracking/TrailDefinition.kt new file mode 100644 index 0000000..a3af8d3 --- /dev/null +++ b/Server/src/main/content/global/skill/hunter/tracking/TrailDefinition.kt @@ -0,0 +1,14 @@ +package content.global.skill.hunter.tracking + +import core.game.world.map.Location + +class TrailDefinition(val varbit: Int, val type: TrailType, var inverted: Boolean, val startLocation: Location, val endLocation: Location, val triggerObjectLocation: Location = endLocation){ + override fun toString(): String { + return "$startLocation $endLocation [varbit: $varbit] [${type.name}] [inverted: $inverted]" + } +} +enum class TrailType{ + LINKING, + INITIAL, + TUNNEL +} diff --git a/Server/src/main/content/global/skill/magic/MagicAltarListener.kt b/Server/src/main/content/global/skill/magic/MagicAltarListener.kt new file mode 100644 index 0000000..eb4e61f --- /dev/null +++ b/Server/src/main/content/global/skill/magic/MagicAltarListener.kt @@ -0,0 +1,64 @@ +package content.global.skill.magic + +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.Node +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.SpellBookManager.SpellBook +import core.game.node.entity.skill.Skills +import org.rs09.consts.Scenery +import org.rs09.consts.Sounds +import content.data.Quests + +class MagicAltarListener : InteractionListener { + override fun defineListeners() { + on(intArrayOf(ANCIENT_ALTAR, LUNAR_ALTAR), IntType.SCENERY, "pray-at", "pray") { player, node -> + if (meetsRequirements(player, node)) { + swapSpellBook(player, node) + } + + return@on true + } + } + + private fun meetsRequirements(player: Player, altar: Node): Boolean { + val level = if (altar.id == ANCIENT_ALTAR) 50 else 65 + + if (!hasRequirement(player, if (altar.id == ANCIENT_ALTAR) Quests.DESERT_TREASURE else Quests.LUNAR_DIPLOMACY)) { + return false + } + + if (!hasLevelStat(player, Skills.MAGIC, level)) { + sendMessage(player, "You need a Magic level of at least $level in order to do this.") + return false + } + + return true + } + + private fun swapSpellBook(player: Player, altar: Node) { + lock(player, 3) + playAudio(player, Sounds.PRAYER_RECHARGE_2674) + animate(player, 645) + + if (altar.id == ANCIENT_ALTAR) { + player.skills.decrementPrayerPoints(player.skills.prayerPoints) + } + + if (SpellBook.forInterface(player.spellBookManager.spellBook) == if (altar.id == ANCIENT_ALTAR) SpellBook.ANCIENT else SpellBook.LUNAR) { + sendMessage(player, if (altar.id == ANCIENT_ALTAR) "You feel a strange drain upon your memory..." else "Modern spells activated!") + player.spellBookManager.setSpellBook(SpellBook.MODERN) + player.spellBookManager.update(player) + } else { + sendMessage(player, if (altar.id == ANCIENT_ALTAR) "You feel a strange wisdom fill your mind..." else "Lunar spells activated!") + player.spellBookManager.setSpellBook(if (altar.id == ANCIENT_ALTAR) SpellBook.ANCIENT else SpellBook.LUNAR) + player.spellBookManager.update(player) + } + } + + companion object { + private const val ANCIENT_ALTAR = Scenery.ALTAR_6552 + private const val LUNAR_ALTAR = Scenery.ALTAR_17010 + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/magic/SpellListener.kt b/Server/src/main/content/global/skill/magic/SpellListener.kt new file mode 100644 index 0000000..64383b0 --- /dev/null +++ b/Server/src/main/content/global/skill/magic/SpellListener.kt @@ -0,0 +1,127 @@ +package content.global.skill.magic + +import core.api.playAudio +import core.api.playGlobalAudio +import core.api.setAttribute +import core.cache.def.impl.ItemDefinition +import core.game.node.Node +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import core.game.interaction.Listener +import core.game.world.GameWorld + +abstract class SpellListener(val bookName: String) : Listener { + companion object { + @JvmField + val NPC = -1 + @JvmField + val OBJECT = -2 + @JvmField + val ITEM = -3 + @JvmField + val PLAYER = -4 + @JvmField + val NONE = -5 + @JvmField + val GROUND_ITEM = -6 + } + fun onCast(spellID: Int, type: Int, range: Int = 10, method: (player: Player, node: Node?) -> Unit){ + SpellListeners.add(spellID, type, bookName, range, method) + } + + fun onCast(spellID: Int, type: Int, vararg ids: Int, range: Int = 10, method: (player: Player, node: Node?) -> Unit){ + SpellListeners.add(spellID, type, ids, bookName, range, method) + } + + fun requires(player: Player, magicLevel: Int = 0, runes: Array = arrayOf(), specialEquipment: IntArray = intArrayOf()) { + if(player.getAttribute("magic-delay",0) > GameWorld.ticks){ + throw IllegalStateException() + } + if(player.getAttribute("tablet-spell",false)){ + return + } + if(player.skills.getLevel(Skills.MAGIC) < magicLevel){ + player.sendMessage("You need a magic level of $magicLevel to cast this spell.") + throw IllegalStateException() + } + for(rune in runes){ + if(!SpellUtils.hasRune(player,rune)){ + player.sendMessage("You don't have enough ${rune.definition.name.lowercase()}s to cast this spell.") + throw IllegalStateException() + } + } + for(item in specialEquipment){ + if(!player.equipment.contains(item,1)){ + player.sendMessage("You need a ${ItemDefinition.forId(item).name} to cast this.") + throw IllegalStateException() + } + } + } + + fun removeRunes(player: Player,removeAttr: Boolean = true){ + player.inventory.remove(*player.getAttribute("spell:runes",ArrayList()).toTypedArray()) + if(removeAttr) { + player.removeAttribute("spell:runes") + player.removeAttribute("tablet-spell") + } + } + + fun addXP(player: Player,amount:Double){ + if(player.getAttribute("tablet-spell",false)) return + player.skills.addExperience(Skills.MAGIC,amount) + } + + /** + * @param player The player to visualize the spell on + * @param anim The animation object. I.e. Animation(Animations.LUNAR_SPELLBOOK_*) + * @param gfx The graphics object. I.e. Graphics(Graphics.LUNAR_SPELLBOOK_*, height in int) + * @param soundID The sound to play, either raw integer or from the Sounds ConstLib. Defaults to -1 (Nothing). + * @param delay The delay that should be applied before the sound plays, defaults to 0. + * @param global Whether the sound should be played globally instead of per-player. Defaults to true. + */ + fun visualizeSpell(player: Player, anim: Animation, gfx: Graphics, soundID: Int = -1, delay: Int = 0, global: Boolean = true){ + if(player.getAttribute("tablet-spell",false)) return + player.visualize(anim, gfx) + if(soundID != -1){ + if(global) playGlobalAudio(player.location, soundID, delay) + else playAudio(player, soundID, delay) + } + } + + /** + * @param player The player to visualize the spell on + * @param anim The integer ID of the animation, found in the Animations ConstLib. + * @param gfx The integer ID of the graphics to show, found in the Graphics ConstLib. + * @param height How high the graphics should display above the ground(?). Defaults to 0. + * @param soundID The sound to play, either raw integer or from the Sounds ConstLib. Defaults to -1 (Nothing). + * @param delay The delay that should be applied before the sound plays, defaults to 0. + * @param global Whether the sound should be played globally instead of per-player. Defaults to true. + */ + fun visualizeSpell(player: Player, anim: Int, gfx: Int, height: Int = 0, soundID: Int = -1, delay: Int = 0, global: Boolean = true) { + if(player.getAttribute("tablet-spell",false)) return + player.visualize(Animation(anim), Graphics(gfx, height)) + if(soundID != -1){ + if(global) playGlobalAudio(player.location, soundID, delay) + else playAudio(player, soundID, delay) + } + } + + fun setDelay(player: Player, isTeleport: Boolean = false){ + if(!isTeleport) player.setAttribute("magic-delay", GameWorld.ticks + 3) else player.setAttribute("magic-delay", GameWorld.ticks + 5) + } + + fun setDelay(player: Player, delay: Int) { + setAttribute(player, "magic-delay", GameWorld.ticks + delay) + } + + fun interrupt(player: Player){ + player.pulseManager.clear() + } + + fun showMagicTab(player: Player){ + player.interfaceManager.setViewedTab(6) + } +} diff --git a/Server/src/main/content/global/skill/magic/SpellListeners.kt b/Server/src/main/content/global/skill/magic/SpellListeners.kt new file mode 100644 index 0000000..95ff686 --- /dev/null +++ b/Server/src/main/content/global/skill/magic/SpellListeners.kt @@ -0,0 +1,81 @@ +package content.global.skill.magic + +import core.game.event.SpellCastEvent +import core.api.* +import core.game.node.Node +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.SpellBookManager +import core.tools.Log +import core.tools.SystemLogger +import core.game.interaction.* +import core.game.world.map.path.Pathfinder + +object SpellListeners { + val castMap = HashMap Unit>() + val spellRanges = HashMap() + + fun add(spellID: Int, type: Int, book: String, distance: Int, method: (Player,Node?) -> Unit){ + castMap["$book:$spellID:$type"] = method + spellRanges["$book:$spellID:$type"] = distance + } + + fun add(spellID: Int, type: Int, ids: IntArray, book: String, distance: Int, method: (Player, Node?) -> Unit){ + for(id in ids) { + castMap["$book:$spellID:$type:$id"] = method + spellRanges["$book:$spellID:$type:$id"] = distance + } + } + + fun get(spellID: Int, type: Int, book: String): Pair Unit)?> { + log(this::class.java, Log.FINE, "Getting $book:$spellID:$type") + return Pair (spellRanges["$book:$spellID:$type"] ?: 10, castMap["$book:$spellID:$type"]) + } + + fun get(spellID: Int, type: Int, id: Int, book: String): Pair Unit)?> { + log(this::class.java, Log.FINE, "Getting $book:$spellID:$type:$id") + return Pair (spellRanges["$book:$spellID:$type:$id"] ?: 10, castMap["$book:$spellID:$type:$id"]) + } + + @JvmStatic + fun run(button: Int, type: Int, book: String, player: Player, node: Node? = null){ + var (range, method) = get (button, type, node?.id ?: 0, book) + if (method == null) { + var next = get (button, type, book) + range = next.first + method = next.second ?: return + } + + if (type in intArrayOf (SpellListener.NPC, SpellListener.OBJECT, SpellListener.PLAYER, SpellListener.GROUND_ITEM)) { + player.pulseManager.run (object : MovementPulse (player, node, Pathfinder.SMART) { + override fun pulse() : Boolean { + try { + method?.invoke (player, node) + } catch (e: IllegalStateException) { + player.removeAttribute ("spell:runes") + return true + } + return true + } + + override fun update () : Boolean { + if (player.location.withinMaxnormDistance (node!!.centerLocation, range) && hasLineOfSight (player, node!!)) { + player.faceLocation (node.getFaceLocation(player.location)) + player.walkingQueue.reset() + pulse() + stop() + return true + } + return super.update() + } + }) + } else { + try { + method?.invoke(player, node) + player.dispatch(SpellCastEvent(SpellBookManager.SpellBook.valueOf(book.uppercase()), button, node)) + } catch (e: IllegalStateException){ + player.removeAttribute("spell:runes") + return + } + } + } +} diff --git a/Server/src/main/content/global/skill/magic/SpellTablets.kt b/Server/src/main/content/global/skill/magic/SpellTablets.kt new file mode 100644 index 0000000..62b550f --- /dev/null +++ b/Server/src/main/content/global/skill/magic/SpellTablets.kt @@ -0,0 +1,40 @@ +package content.global.skill.magic + +import content.global.skill.magic.spellconsts.Modern +import core.api.playAudio +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import org.rs09.consts.Sounds + +class SpellTablets : InteractionListener { + val B2P_TABLET = Items.BONES_TO_PEACHES_8015 + val B2B_TABLET = Items.BONES_TO_BANANAS_8014 + override fun defineListeners() { + + on(B2B_TABLET, IntType.ITEM, "break"){ player, node -> + breakTablet(player) + SpellListeners.run(Modern.BONES_TO_BANANAS,SpellListener.NONE,"modern",player) + player.inventory.remove(Item(node.id)) + return@on true + } + + on(B2P_TABLET, IntType.ITEM, "break"){ player, node -> + breakTablet(player) + SpellListeners.run(Modern.BONES_TO_PEACHES,SpellListener.NONE,"modern",player) + player.inventory.remove(Item(node.id)) + return@on true + } + + } + + fun breakTablet(player: Player){ + playAudio(player, Sounds.POH_TABLET_BREAK_979) + player.animator.forceAnimation(Animation(4069)) + player.lock(5) + player.setAttribute("tablet-spell",true) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/magic/SpellUtils.kt b/Server/src/main/content/global/skill/magic/SpellUtils.kt new file mode 100644 index 0000000..a80d646 --- /dev/null +++ b/Server/src/main/content/global/skill/magic/SpellUtils.kt @@ -0,0 +1,98 @@ +package content.global.skill.magic + +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.combat.spell.CombinationRune +import core.game.node.entity.combat.spell.MagicStaff +import core.game.node.entity.combat.spell.Runes +import core.game.node.item.Item + +object SpellUtils { + fun usingStaff(p: Player, rune: Int): Boolean { + val weapon = p.equipment[3] ?: return false + val staff = MagicStaff.forId(rune) ?: return false + val staves = staff.staves + for (id in staves) { + if (weapon.id == id) { + return true + } + } + return false + } + + fun hasRune(p:Player,rune:Item):Boolean{ + val removeItems = p.getAttribute("spell:runes",ArrayList()) + if(usingStaff(p,rune.id)) return true + if(p.inventory.containsItem(rune)){ + removeItems.add(rune) + p.setAttribute("spell:runes",removeItems) + } + + val baseAmt = p.inventory.getAmount(rune.id) + var amtRemaining = rune.amount - baseAmt + val possibleComboRunes = CombinationRune.eligibleFor(Runes.forId(rune.id)) + for (r in possibleComboRunes) { + if (p.inventory.containsItem(Item(r.id)) && amtRemaining > 0) { + val amt = p.inventory.getAmount(r.id) + if (amtRemaining <= amt) { + removeItems.add(Item(r.id,amtRemaining)) + amtRemaining = 0 + break + } + removeItems.add(Item(r.id,p.inventory.getAmount(r.id))) + amtRemaining -= p.inventory.getAmount(r.id) + } + } + p.setAttribute("spell:runes",removeItems) + return amtRemaining <= 0 + } + + fun hasRune(p: Player, item: Item, toRemove: MutableList, message: Boolean): Boolean { + if (!usingStaff(p, item.id)) { + val hasBaseRune = p.inventory.contains(item.id, item.amount) + if (!hasBaseRune) { + val baseAmt = p.inventory.getAmount(item.id) + if (baseAmt > 0) { + toRemove.add(Item(item.id, p.inventory.getAmount(item.id))) + } + var amtRemaining = item.amount - baseAmt + val possibleComboRunes = CombinationRune.eligibleFor(Runes.forId(item.id)) + for (r in possibleComboRunes) { + if (p.inventory.containsItem(Item(r.id)) && amtRemaining > 0) { + val amt = p.inventory.getAmount(r.id) + if (amtRemaining < amt) { + toRemove.add(Item(r.id, amtRemaining)) + amtRemaining = 0 + continue + } + amtRemaining -= p.inventory.getAmount(r.id) + toRemove.add(Item(r.id, p.inventory.getAmount(r.id))) + } + } + return if (amtRemaining <= 0) { + true + } else { + p.packetDispatch.sendMessage("You don't have enough " + item.name + "s to cast this spell.") + false + } + } + toRemove.add(item) + return true + } + return true + } + + fun attackableNPC(npc: NPC): Boolean{ + return npc.definition.hasAction("attack") + } + + @JvmStatic + fun getBookFromInterface(id: Int): String{ + return when(id){ + 192 -> "modern" + 193 -> "ancient" + 430 -> "lunar" + else -> "none" + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/magic/SpellbookSwapDialogue.java b/Server/src/main/content/global/skill/magic/SpellbookSwapDialogue.java new file mode 100644 index 0000000..8f9a62c --- /dev/null +++ b/Server/src/main/content/global/skill/magic/SpellbookSwapDialogue.java @@ -0,0 +1,88 @@ +package content.global.skill.magic; + +import core.game.component.Component; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; + +/** + * Handles the SpellbookSwapDialogue dialogue. + * @author Vexia + * + */ +@Initializable +public class SpellbookSwapDialogue extends DialoguePlugin { + + /** + * If we're using the perk. + */ + private boolean perk; + + /** + * Constructs a new {@Code SpellbookSwapDialogue} {@Code Object} + */ + public SpellbookSwapDialogue() { + /* + * empty. + */ + } + + /** + * Constructs a new {@Code SpellbookSwapDialogue} {@Code Object} + * @param player the player. + */ + public SpellbookSwapDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new SpellbookSwapDialogue(player); + } + + @Override + public boolean open(Object... args) { + if (args.length > 1) { + perk = true; + interpreter.sendOptions("Select a Spellbook", "Modern", "Ancient", "Lunar"); + return true; + } + interpreter.sendOptions("Select a Spellbook", "Ancient", "Modern"); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + if (perk) { + SpellBook book = SpellBook.values()[buttonId - 1]; + player.getSpellBookManager().setSpellBook(book); + player.getInterfaceManager().openTab(new Component(book.getInterfaceId())); + end(); + return true; + } + int type = 0; + switch (buttonId) { + case 1: + type = 1; + break; + case 2: + type = 2; + break; + } + final SpellBook book = type == 1 ? SpellBook.ANCIENT : SpellBook.MODERN; + player.getSpellBookManager().setSpellBook(book); + player.getInterfaceManager().openTab(new Component(book.getInterfaceId())); + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 3264731 }; + } +} diff --git a/Server/src/main/content/global/skill/magic/TeleportMethod.kt b/Server/src/main/content/global/skill/magic/TeleportMethod.kt new file mode 100644 index 0000000..0f092eb --- /dev/null +++ b/Server/src/main/content/global/skill/magic/TeleportMethod.kt @@ -0,0 +1,7 @@ +package content.global.skill.magic + +enum class TeleportMethod { + JEWELRY, + SPELL, + NPC +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/magic/ancient/AncientTeleportPlugin.java b/Server/src/main/content/global/skill/magic/ancient/AncientTeleportPlugin.java new file mode 100644 index 0000000..3944c3c --- /dev/null +++ b/Server/src/main/content/global/skill/magic/ancient/AncientTeleportPlugin.java @@ -0,0 +1,97 @@ +package content.global.skill.magic.ancient; + +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.entity.combat.spell.MagicSpell; +import core.game.node.entity.combat.spell.Runes; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.spell.SpellType; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.node.entity.player.link.TeleportManager.TeleportType; +import core.game.node.item.Item; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.tools.RandomFunction; + +/** + * Represents the plugin used to handle all ancient teleporting plugins. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class AncientTeleportPlugin extends MagicSpell { + + /** + * Represents the location to teleport to. + */ + private Location location; + + /** + * Constructs a new {@code AncientTeleportPlugin} {@code Object}. + */ + public AncientTeleportPlugin() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code AncientTeleportPlugin.java} {@code Object}. + * @param level the level. + * @param experience the experience. + * @param location the location. + * @param items the items. + */ + public AncientTeleportPlugin(final int level, final double experience, final Location location, final Item... items) { + super(SpellBook.ANCIENT, level, experience, null, null, null, items); + this.location = location; + } + + @Override + public boolean cast(Entity entity, Node target) { + if (entity.isTeleBlocked() || !super.meetsRequirements(entity, true, false)) { + entity.asPlayer().sendMessage("A magical force has stopped you from teleporting."); + return false; + } + if (entity.getTeleporter().send(location.transform(0, RandomFunction.random(3), 0), getSpellId() == 28 ? TeleportType.HOME : TeleportType.ANCIENT)) { + if (!super.meetsRequirements(entity, true, true)) { + entity.getTeleporter().getCurrentTeleport().stop(); + return false; + } + // Use the Home Teleport spell in the Ancient Magicks spellbook

to teleport to Edgeville + if (entity.isPlayer() && location.equals(Location.create(3087, 3495, 0))) { + entity.asPlayer().getAchievementDiaryManager().finishTask(entity.asPlayer(), DiaryType.VARROCK, 2, 11); + } + entity.setAttribute("teleport:items", super.runes); + entity.setAttribute("magic-delay", GameWorld.getTicks() + 5); + return true; + } + return false; + } + + @Override + public Plugin newInstance(SpellType arg) throws Throwable { + // home + SpellBook.ANCIENT.register(28, new AncientTeleportPlugin(0, 0, Location.create(3087, 3495, 0))); + // paddewwa teleport + SpellBook.ANCIENT.register(20, new AncientTeleportPlugin(54, 64, Location.create(3098, 9882, 0), new Item(Runes.LAW_RUNE.getId(), 2), new Item(Runes.FIRE_RUNE.getId(), 1), new Item(Runes.AIR_RUNE.getId(), 1))); + // sennisten teleport + SpellBook.ANCIENT.register(21, new AncientTeleportPlugin(60, 70, Location.create(3320, 3338, 0), new Item(Runes.SOUL_RUNE.getId(), 1), new Item(Runes.LAW_RUNE.getId(), 2))); + // karyll teleport + SpellBook.ANCIENT.register(22, new AncientTeleportPlugin(66, 76, Location.create(3493, 3472, 0), new Item(Runes.LAW_RUNE.getId(), 2), new Item(Runes.BLOOD_RUNE.getId(), 1))); + // lassar teleport + SpellBook.ANCIENT.register(23, new AncientTeleportPlugin(72, 82, Location.create(3003, 3470, 0), new Item(Runes.LAW_RUNE.getId(), 2), new Item(Runes.WATER_RUNE.getId(), 4))); + // dareeyak teleport + SpellBook.ANCIENT.register(24, new AncientTeleportPlugin(78, 88, Location.create(2966, 3696, 0), new Item(Runes.LAW_RUNE.getId(), 2), new Item(Runes.FIRE_RUNE.getId(), 3), new Item(Runes.AIR_RUNE.getId(), 2))); + // carralangar teleport + SpellBook.ANCIENT.register(25, new AncientTeleportPlugin(84, 82, Location.create(3163, 3664, 0), new Item(Runes.SOUL_RUNE.getId(), 2), new Item(Runes.LAW_RUNE.getId(), 2))); + // annakarl teleport + SpellBook.ANCIENT.register(26, new AncientTeleportPlugin(90, 100, Location.create(3287, 3883, 0), new Item(Runes.BLOOD_RUNE.getId(), 2), new Item(Runes.LAW_RUNE.getId(), 2))); + // ghorrock teleport + SpellBook.ANCIENT.register(27, new AncientTeleportPlugin(96, 106, Location.create(2972, 3873, 0), new Item(Runes.LAW_RUNE.getId(), 2), new Item(Runes.WATER_RUNE.getId(), 8))); + return this; + } + +} diff --git a/Server/src/main/content/global/skill/magic/ancient/BloodSpells.java b/Server/src/main/content/global/skill/magic/ancient/BloodSpells.java new file mode 100644 index 0000000..2cd3111 --- /dev/null +++ b/Server/src/main/content/global/skill/magic/ancient/BloodSpells.java @@ -0,0 +1,135 @@ +package content.global.skill.magic.ancient; + +import java.util.List; + +import core.game.node.entity.combat.spell.Runes; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.spell.CombatSpell; +import core.game.node.entity.combat.spell.SpellType; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.plugin.Plugin; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playGlobalAudio; + +/** + * Handles the Blood spells from the Ancient spellbook. + * @author Emperor + * @version 1.0 + */ +@Initializable +public final class BloodSpells extends CombatSpell { + + /** + * The projectile for Blood rush. + */ + private static final Projectile RUSH_PROJECTILE = Projectile.create((Entity) null, null, 372, 40, 36, 52, 75, 15, 11); + + /** + * The end graphic for Blood rush. + */ + private static final Graphics RUSH_END = new Graphics(373, 96); + + /** + * The end graphic for Blood burst. + */ + private static final Graphics BURST_END = new Graphics(376, 0); + + /** + * The projectile for Blood blitz. + */ + private static final Projectile BLITZ_PROJECTILE = Projectile.create((Entity) null, null, 374, 40, 36, 52, 75, 15, 11); + + /** + * The end graphic for Blood blitz. + */ + private static final Graphics BLITZ_END = new Graphics(375, 96); + + /** + * The end graphic for Blood barrage. + */ + private static final Graphics BARRAGE_END = new Graphics(377, 0); + + /** + * Constructs a new {@code BloodSpells} {@code Object}. + */ + public BloodSpells() { + /* + * ( empty. + */ + } + + /** + * Constructs a new {@code BloodSpells} {@Code Object} + * @param type The spell type. + * @param impactSound The impact sound id. + * @param anim The animation. + * @param start The start graphics. + * @param projectile The projectile. + * @param end The end graphics. + */ + private BloodSpells(SpellType type, int level, double baseExperience, int sound, int impactSound, Animation anim, Graphics start, Projectile projectile, Graphics end, Item... runes) { + super(type, SpellBook.ANCIENT, level, baseExperience, sound, impactSound, anim, start, projectile, end, runes); + } + + @Override + public Plugin newInstance(SpellType arg) throws Throwable { + SpellBook.ANCIENT.register(4, new BloodSpells(SpellType.RUSH, 56, 33.0, Sounds.BLOOD_RUSH_CASTING_108, Sounds.BLOOD_RUSH_IMPACT_110, new Animation(1978, Priority.HIGH), null, RUSH_PROJECTILE, RUSH_END, Runes.BLOOD_RUNE.getItem(1), Runes.DEATH_RUNE.getItem(2), Runes.CHAOS_RUNE.getItem(2))); + SpellBook.ANCIENT.register(6, new BloodSpells(SpellType.BURST, 68, 39.0, Sounds.BLOOD_CAST_106, Sounds.BLOOD_BURST_IMPACT_105, new Animation(1979, Priority.HIGH), null, null, BURST_END, Runes.BLOOD_RUNE.getItem(2), Runes.DEATH_RUNE.getItem(2), Runes.CHAOS_RUNE.getItem(4))); + SpellBook.ANCIENT.register(5, new BloodSpells(SpellType.BLITZ, 80, 45.0, Sounds.BLOOD_CAST_106, Sounds.BLOOD_BLITZ_IMPACT_104, new Animation(1978, Priority.HIGH), null, BLITZ_PROJECTILE, BLITZ_END, Runes.BLOOD_RUNE.getItem(4), Runes.DEATH_RUNE.getItem(2))); + SpellBook.ANCIENT.register(7, new BloodSpells(SpellType.BARRAGE, 92, 51.0, Sounds.BLOOD_CAST_106, Sounds.BLOOD_BARRAGE_IMPACT_102, new Animation(1979, Priority.HIGH), null, null, BARRAGE_END, Runes.SOUL_RUNE.getItem(1), Runes.BLOOD_RUNE.getItem(4), Runes.DEATH_RUNE.getItem(4))); + return this; + } + + @Override + public void visualize(Entity entity, Node target) { + entity.graphics(graphic); + if (projectile != null) { + projectile.transform(entity, (Entity) target, false, 58, 10).send(); + } + entity.animate(animation); + playGlobalAudio(entity.getLocation(), audio.id, 20); + } + + @Override + public void fireEffect(Entity entity, Entity victim, BattleState state) { + if (state.getEstimatedHit() > -1) { + int heal = state.getEstimatedHit() / 4; + if (heal > 0) { + entity.getSkills().heal(heal); + if (entity instanceof Player) { + ((Player) entity).getPacketDispatch().sendMessage("You drain some of your opponent's health."); + } + } + } + } + + @Override + public BattleState[] getTargets(Entity entity, Entity target) { + if (animation.getId() == 1978 || !entity.getProperties().isMultiZone() || !target.getProperties().isMultiZone()) { + return super.getTargets(entity, target); + } + List list = getMultihitTargets(entity, target, 9); + BattleState[] targets = new BattleState[list.size()]; + int index = 0; + for (Entity e : list) { + targets[index++] = new BattleState(entity, e); + } + return targets; + } + + @Override + public int getMaximumImpact(Entity entity, Entity victim, BattleState state) { + return getType().getImpactAmount(entity, victim, 3); + } + +} diff --git a/Server/src/main/content/global/skill/magic/ancient/IceSpells.java b/Server/src/main/content/global/skill/magic/ancient/IceSpells.java new file mode 100644 index 0000000..e4f2875 --- /dev/null +++ b/Server/src/main/content/global/skill/magic/ancient/IceSpells.java @@ -0,0 +1,162 @@ +package content.global.skill.magic.ancient; + +import java.util.List; + +import core.game.node.entity.combat.spell.Runes; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.spell.CombatSpell; +import core.game.node.entity.combat.spell.SpellType; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.plugin.Plugin; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.*; + +/** + * Handles the Ice spells from the Ancient spellbook. + * @author Emperor + * @version 1.0 + */ +@Initializable +public final class IceSpells extends CombatSpell { + + /** + * The barrage orb GFX. + */ + private static final Graphics BARRAGE_ORB = new Graphics(1677, 96); //119 + + /** + * The projectile for Ice rush. + */ + private static final Projectile RUSH_PROJECTILE = Projectile.create((Entity) null, null, 360, 40, 36, 52, 75, 15, 11); + + /** + * The end graphic for Ice rush. + */ + private static final Graphics RUSH_END = new Graphics(361, 96); + + /** + * The projectile for Ice barrage. + */ + private static final Projectile BURST_PROJECTILE = Projectile.create((Entity) null, null, 362, 40, 36, 52, 75, 15, 11); + + /** + * The end graphic for Ice barrage. + */ + private static final Graphics BURST_END = new Graphics(363, 0); + + /** + * The start graphic for Ice rush. + */ + private static final Graphics BLITZ_START = new Graphics(366, 96); + + /** + * The end graphic for Ice rush. + */ + private static final Graphics BLITZ_END = new Graphics(367, 96); + + /** + * The projectile for Ice barrage. + */ + private static final Projectile BARRAGE_PROJECTILE = Projectile.create((Entity) null, null, 368, 40, 36, 52, 75, 15, 11); + + /** + * The end graphic for Ice barrage. + */ + private static final Graphics BARRAGE_END = new Graphics(369, 0); + + /** + * Constructs a new {@code IceSpells} {@code Object}. + */ + public IceSpells() { + /* + * empty. + */ + } + + /** + * Constructs a new {@code IceSpells} {@Code Object} + * @param type The spell type. + * @param impactSound The impact sound id. + * @param anim The animation. + * @param start The start graphics. + * @param projectile The projectile. + * @param end The end graphics. + */ + private IceSpells(SpellType type, int level, double baseExperience, int impactSound, Animation anim, Graphics start, Projectile projectile, Graphics end, Item... runes) { + super(type, SpellBook.ANCIENT, level, baseExperience, Sounds.ICE_CAST_171, impactSound, anim, start, projectile, end, runes); + } + + @Override + public void visualize(Entity entity, Node target) { + entity.graphics(graphic); + if (projectile != null) { + projectile.transform(entity, (Entity) target, false, 58, 10).send(); + } + entity.animate(animation); + playGlobalAudio(entity.getLocation(), audio.id, 20); + + } + + @Override + public void visualizeImpact(Entity entity, Entity target, BattleState state) { + if (state.isFrozen()) { + playGlobalAudio(target.getLocation(), impactAudio, 20); + target.graphics(BARRAGE_ORB); + return; + } + super.visualizeImpact(entity, target, state); + } + + @Override + public Plugin newInstance(SpellType arg) throws Throwable { + SpellBook.ANCIENT.register(0, new IceSpells(SpellType.RUSH, 58, 34.0, Sounds.ICE_RUSH_IMPACT_173, new Animation(1978, Priority.HIGH), null, RUSH_PROJECTILE, RUSH_END, Runes.DEATH_RUNE.getItem(2), Runes.CHAOS_RUNE.getItem(2), Runes.WATER_RUNE.getItem(2))); + SpellBook.ANCIENT.register(2, new IceSpells(SpellType.BURST, 70, 40.0, Sounds.ICE_BURST_IMPACT_170, new Animation(1979, Priority.HIGH), null, BURST_PROJECTILE, BURST_END, Runes.DEATH_RUNE.getItem(2), Runes.CHAOS_RUNE.getItem(4), Runes.WATER_RUNE.getItem(4))); + SpellBook.ANCIENT.register(1, new IceSpells(SpellType.BLITZ, 82, 46.0, Sounds.ICE_BLITZ_IMPACT_169, new Animation(1978, Priority.HIGH), BLITZ_START, null, BLITZ_END, Runes.BLOOD_RUNE.getItem(2), Runes.DEATH_RUNE.getItem(2), Runes.WATER_RUNE.getItem(3))); + SpellBook.ANCIENT.register(3, new IceSpells(SpellType.BARRAGE, 94, 52.0, Sounds.ICE_BARRAGE_IMPACT_168, new Animation(1979, Priority.HIGH), null, BARRAGE_PROJECTILE, BARRAGE_END, Runes.BLOOD_RUNE.getItem(2), Runes.DEATH_RUNE.getItem(4), Runes.WATER_RUNE.getItem(6))); + return this; + } + + @Override + public void fireEffect(Entity entity, Entity victim, BattleState state) { + if (state.getEstimatedHit() == -1) { + return; + } + int ticks = (1 + (type.ordinal() - SpellType.RUSH.ordinal())) * 8; + if (state.getEstimatedHit() > -1) { + if (!hasTimerActive(victim, "frozen:immunity")) { + registerTimer(victim, spawnTimer("frozen", ticks, true)); + } else if (type == SpellType.BARRAGE) { + state.setFrozen(true); + } + } + } + + @Override + public BattleState[] getTargets(Entity entity, Entity target) { + if (animation.getId() == 1978 || !entity.getProperties().isMultiZone() || !target.getProperties().isMultiZone()) { + return super.getTargets(entity, target); + } + List list = getMultihitTargets(entity, target, 9); + BattleState[] targets = new BattleState[list.size()]; + int index = 0; + for (Entity e : list) { + targets[index++] = new BattleState(entity, e); + } + return targets; + } + + @Override + public int getMaximumImpact(Entity entity, Entity victim, BattleState state) { + return getType().getImpactAmount(entity, victim, 4); + } + +} diff --git a/Server/src/main/content/global/skill/magic/ancient/MiasmicSpells.java b/Server/src/main/content/global/skill/magic/ancient/MiasmicSpells.java new file mode 100644 index 0000000..1faf6ed --- /dev/null +++ b/Server/src/main/content/global/skill/magic/ancient/MiasmicSpells.java @@ -0,0 +1,181 @@ + package content.global.skill.magic.ancient; + +import java.util.List; + +import core.game.container.impl.EquipmentContainer; +import core.plugin.Initializable; +import core.game.node.entity.combat.spell.Runes; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.spell.CombatSpell; +import core.game.node.entity.combat.spell.SpellType; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.node.item.Item; +import core.game.world.GameWorld; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Plugin; + +import static core.api.ContentAPIKt.*; + +/** + * Handles the Miasmic spells that are a part of the Ancient spellbook. + * @author Splinter + * @version 1.0 + */ +@Initializable +public final class MiasmicSpells extends CombatSpell { + + /** + * The start graphic for Miasmic rush. + */ + private static final Graphics RUSH_START = new Graphics(1845, 0, 15); + + /** + * The end graphic for Miasmic rush. + */ + private static final Graphics RUSH_END = new Graphics(1847, 40); + + /** + * The start graphic for Miasmic rush. + */ + private static final Graphics BURST_START = new Graphics(1848, 0); + + /** + * The end graphic for Miasmic barrage. + */ + private static final Graphics BURST_END = new Graphics(1849, 20, 30); + + /** + * The start graphic for Miasmic rush. + */ + private static final Graphics BLITZ_START = new Graphics(1850, 15); + + /** + * The end graphic for Miasmic rush. + */ + private static final Graphics BLITZ_END = new Graphics(1851, 0); + + /** + * The start graphic for Miasmic rush. + */ + private static final Graphics BARRAGE_START = new Graphics(1853, 0); + + /** + * The end graphic for Miasmic barrage. + */ + private static final Graphics BARRAGE_END = new Graphics(1854, 0, 30); + + /** + * The item ids of the staves able to cast Miasmic spells. + */ + private static final int[] VALID_STAFF_IDS = { 13867, 13869, 13841, 13843 }; + + /** + * Constructs a new {@code MiasmicSpells} {@code Object}. + */ + public MiasmicSpells() { + } + + /** + * Constructs a new {@code MiasmicSpells} {@Code Object} + * @param type The spell type. + * @param impactSound The impact sound id. + * @param anim The animation. + * @param start The start graphics. + * @param projectile The projectile. + * @param end The end graphics. + */ + private MiasmicSpells(SpellType type, int level, double baseExperience, int castAudio, int impactSound, Animation anim, Graphics start, Projectile projectile, Graphics end, Item... runes) { + super(type, SpellBook.ANCIENT, level, baseExperience, castAudio, impactSound, anim, start, projectile, end, runes); + } + + @Override + public void visualize(Entity entity, Node target) { + entity.graphics(graphic); + if (projectile != null) { + projectile.transform(entity, (Entity) target, false, 58, 10).send(); + } + entity.animate(animation); + playGlobalAudio(entity.getLocation(), audio.id, 20); + } + + @Override + public void visualizeImpact(Entity entity, Entity target, BattleState state) { + super.visualizeImpact(entity, target, state); + } + + @Override + public Plugin newInstance(SpellType arg) throws Throwable { + SpellBook.ANCIENT.register(16, new MiasmicSpells(SpellType.RUSH, 61, 36.0, 5368, 5365, new Animation(10513, Priority.HIGH), RUSH_START, null, RUSH_END, Runes.EARTH_RUNE.getItem(1), Runes.SOUL_RUNE.getItem(1), Runes.CHAOS_RUNE.getItem(2))); + SpellBook.ANCIENT.register(17, new MiasmicSpells(SpellType.BURST, 73, 42.0, 5366, 5372, new Animation(10516, Priority.HIGH), BURST_START, null, BURST_END, Runes.EARTH_RUNE.getItem(3), Runes.SOUL_RUNE.getItem(3), Runes.CHAOS_RUNE.getItem(4))); + SpellBook.ANCIENT.register(18, new MiasmicSpells(SpellType.BLITZ, 85, 48.0, 5370, 5367, new Animation(10524, Priority.HIGH), BLITZ_START, null, BLITZ_END, Runes.EARTH_RUNE.getItem(3), Runes.SOUL_RUNE.getItem(3), Runes.BLOOD_RUNE.getItem(2))); + SpellBook.ANCIENT.register(19, new MiasmicSpells(SpellType.BARRAGE, 97, 54.0, 5371, 5369, new Animation(10518, Priority.HIGH), BARRAGE_START, null, BARRAGE_END, Runes.EARTH_RUNE.getItem(4), Runes.SOUL_RUNE.getItem(4), Runes.BLOOD_RUNE.getItem(4))); + return this; + } + + @Override + public void fireEffect(Entity entity, Entity victim, BattleState state) { + if (!hasTimerActive(victim, "miasmic:immunity")) { + registerTimer(victim, spawnTimer("miasmic", (getSpellId() - 15) * 20)); + } + } + + /** + * Checks if a valid staff is equipped. + * @param entity The attacking entity. + * @return {@code True} if so. + */ + public boolean validStaffEquipped(Entity entity){ + for(int i = 0; i < VALID_STAFF_IDS.length; i++){ + if(((Player) entity).getEquipment().getNew(EquipmentContainer.SLOT_WEAPON).getId() == VALID_STAFF_IDS[i]){ + return true; + } + } + return false; + } + + @Override + public boolean cast(Entity entity, Node target) { + if (!validStaffEquipped(entity) && !GameWorld.getSettings().isDevMode()) { + ((Player) entity).getPacketDispatch().sendMessage("You need to be wielding Zuriel's staff in order to cast this spell."); + return false; + } + if (!meetsRequirements(entity, true, false)) { + return false; + } + return super.cast(entity, target); + } + + @Override + public BattleState[] getTargets(Entity entity, Entity target) { + if (animation.getId() == 10513 || animation.getId() == 10524 + || !entity.getProperties().isMultiZone() || !target.getProperties().isMultiZone()) { + return super.getTargets(entity, target); + } + List list = getMultihitTargets(entity, target, 9); + BattleState[] targets = new BattleState[list.size()]; + int index = 0; + for (Entity e : list) { + targets[index++] = new BattleState(entity, e); + } + return targets; + } + + @Override + public int getMaximumImpact(Entity entity, Entity victim, BattleState state) { + int add = 9; + if(animation.getId() == 10524 || animation.getId() == 10516){ + add = 6; + } + if(animation.getId() == 10513){ + add = 4; + } + return getType().getImpactAmount(entity, victim, add); + } + +} diff --git a/Server/src/main/content/global/skill/magic/ancient/ShadowSpells.java b/Server/src/main/content/global/skill/magic/ancient/ShadowSpells.java new file mode 100644 index 0000000..22ca33f --- /dev/null +++ b/Server/src/main/content/global/skill/magic/ancient/ShadowSpells.java @@ -0,0 +1,132 @@ +package content.global.skill.magic.ancient; + +import java.util.List; + +import core.game.node.entity.player.Player; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.combat.spell.Runes; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.spell.CombatSpell; +import core.game.node.entity.combat.spell.SpellType; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.plugin.Plugin; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playGlobalAudio; + +/** + * Handles the Shadow spells from the Ancient spellbook. + * @author Emperor + */ +@Initializable +public final class ShadowSpells extends CombatSpell { + + /** + * The projectile for Shadow rush. + */ + private static final Projectile RUSH_PROJECTILE = Projectile.create((Entity) null, null, 378, 40, 36, 52, 75, 15, 11); + + /** + * The end graphic for Shadow rush. + */ + private static final Graphics RUSH_END = new Graphics(379, 96); + + /** + * The projectile for Shadow burst. + */ + private static final Projectile BURST_PROJECTILE = Projectile.create((Entity) null, null, 380, 40, 36, 52, 75, 15, 11); + + /** + * The end graphic for Shadow burst. + */ + private static final Graphics BURST_END = new Graphics(381, 0); + + /** + * The end graphic for Shadow blitz. + */ + private static final Graphics BLITZ_END = new Graphics(382, 96); + + /** + * The end graphic for Shadow barrage. + */ + private static final Graphics BARRAGE_END = new Graphics(383, 0); + + /** + * Constructs a new {@code ShadowSpells} {@code Object}. + */ + public ShadowSpells() { + /* + * empty. + */ + } + + /** + * Constructs a new {@code ShadowSpells} {@Code Object} + * @param type The spell type. + * @param level The level requirement. + * @param sound The casting sound. + * @param impactSound The impact sound id. + * @param anim The animation. + * @param start The start graphics. + * @param projectile The projectile. + * @param end The end graphics. + */ + private ShadowSpells(SpellType type, int level, double baseExperience, int sound, int impactSound, Animation anim, Graphics start, Projectile projectile, Graphics end, Item... runes) { + super(type, SpellBook.ANCIENT, level, baseExperience, sound, impactSound, anim, start, projectile, end, runes); + } + + @Override + public Plugin newInstance(SpellType arg) throws Throwable { + SpellBook.ANCIENT.register(12, new ShadowSpells(SpellType.RUSH, 52, 31.0, Sounds.SHADOW_CAST_178, Sounds.SHADOW_RUSH_IMPACT_179, new Animation(1978, Priority.HIGH), null, RUSH_PROJECTILE, RUSH_END, Runes.SOUL_RUNE.getItem(1), Runes.DEATH_RUNE.getItem(2), Runes.CHAOS_RUNE.getItem(2), Runes.AIR_RUNE.getItem(1))); + SpellBook.ANCIENT.register(14, new ShadowSpells(SpellType.BURST, 64, 37.0, Sounds.SHADOW_CAST_178, Sounds.SHADOW_BURST_IMPACT_177, new Animation(1979, Priority.HIGH), null, BURST_PROJECTILE, BURST_END, Runes.SOUL_RUNE.getItem(2), Runes.DEATH_RUNE.getItem(2), Runes.CHAOS_RUNE.getItem(4), Runes.AIR_RUNE.getItem(1))); + SpellBook.ANCIENT.register(13, new ShadowSpells(SpellType.BLITZ, 76, 43.0, Sounds.SHADOW_CAST_178, Sounds.SHADOW_BLITZ_IMPACT_176, new Animation(1978, Priority.HIGH), null, null, BLITZ_END, Runes.SOUL_RUNE.getItem(2), Runes.BLOOD_RUNE.getItem(2), Runes.DEATH_RUNE.getItem(2), Runes.AIR_RUNE.getItem(2))); + SpellBook.ANCIENT.register(15, new ShadowSpells(SpellType.BARRAGE, 88, 48.0, Sounds.SHADOW_CAST_178, Sounds.SHADOW_BARRAGE_IMPACT_175, new Animation(1979, Priority.HIGH), null, null, BARRAGE_END, Runes.SOUL_RUNE.getItem(3), Runes.BLOOD_RUNE.getItem(2), Runes.DEATH_RUNE.getItem(4), Runes.AIR_RUNE.getItem(4))); + return this; + } + + @Override + public void visualize(Entity entity, Node target) { + entity.graphics(graphic); + if (projectile != null) { + projectile.transform(entity, (Entity) target, false, 58, 10).send(); + } + entity.animate(animation); + playGlobalAudio(entity.getLocation(), audio.id, 20); + } + + @Override + public void fireEffect(Entity entity, Entity victim, BattleState state) { + if (state.getEstimatedHit() > -1) { + int level = victim.getSkills().getStaticLevel(Skills.ATTACK); + victim.getSkills().updateLevel(Skills.ATTACK, (int) -(level * 0.1), (int) (level - (level * 0.1))); + } + } + + @Override + public BattleState[] getTargets(Entity entity, Entity target) { + if (animation.getId() == 1978 || !entity.getProperties().isMultiZone() || !target.getProperties().isMultiZone()) { + return super.getTargets(entity, target); + } + List list = getMultihitTargets(entity, target, 9); + BattleState[] targets = new BattleState[list.size()]; + int index = 0; + for (Entity e : list) { + targets[index++] = new BattleState(entity, e); + } + return targets; + } + + @Override + public int getMaximumImpact(Entity entity, Entity victim, BattleState state) { + return getType().getImpactAmount(entity, victim, 2); + } + +} diff --git a/Server/src/main/content/global/skill/magic/ancient/SmokeSpells.java b/Server/src/main/content/global/skill/magic/ancient/SmokeSpells.java new file mode 100644 index 0000000..23ddf93 --- /dev/null +++ b/Server/src/main/content/global/skill/magic/ancient/SmokeSpells.java @@ -0,0 +1,140 @@ +package content.global.skill.magic.ancient; + +import java.util.List; + +import core.game.node.entity.combat.spell.Runes; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.spell.CombatSpell; +import core.game.node.entity.combat.spell.SpellType; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.plugin.Plugin; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.*; + +/** + * Handles the Smoke spells from the Ancient spellbook. + * @author Emperor + */ +@Initializable +public final class SmokeSpells extends CombatSpell { + + /** + * The projectile for Smoke rush. + */ + private static final Projectile RUSH_PROJECTILE = Projectile.create((Entity) null, null, 384, 40, 36, 52, 75, 15, 11); + + /** + * The end graphic for Smoke rush. + */ + private static final Graphics RUSH_END = new Graphics(385, 96); + + /** + * The projectile for Smoke burst. + */ + private static final Projectile BURST_PROJECTILE = Projectile.create((Entity) null, null, 386, 40, 36, 52, 75, 15, 11); + + /** + * The end graphic for Smoke burst. + */ + private static final Graphics BURST_END = new Graphics(387, 0); + + /** + * The projectile for Smoke blitz. + */ + private static final Projectile BLITZ_PROJECTILE = Projectile.create((Entity) null, null, 389, 40, 36, 52, 75, 15, 11); + + /** + * The end graphic for Smoke blitz. + */ + private static final Graphics BLITZ_END = new Graphics(388, 96); + + /** + * The projectile for Smoke barrage. + */ + private static final Projectile BARRAGE_PROJECTILE = Projectile.create((Entity) null, null, 391, 40, 36, 52, 75, 15, 11); + + /** + * The end graphic for Smoke barrage. + */ + private static final Graphics BARRAGE_END = new Graphics(390, 0); + + /** + * Constructs a new {@code SmokeSpells} {@code Object}. + */ + public SmokeSpells() { + /* + * empty. + */ + } + + /** + * Constructs a new {@code SmokeSpells} {@Code Object} + * @param type The spell type. + * @param level The level requirement. + * @param sound The casting sound. + * @param impactSound The impact sound id. + * @param anim The animation. + * @param start The start graphics. + * @param projectile The projectile. + * @param end The end graphics. + */ + private SmokeSpells(SpellType type, int level, double baseExperience, int sound, int impactSound, Animation anim, Graphics start, Projectile projectile, Graphics end, Item... runes) { + super(type, SpellBook.ANCIENT, level, baseExperience, sound, impactSound, anim, start, projectile, end, runes); + } + + @Override + public Plugin newInstance(SpellType arg) throws Throwable { + SpellBook.ANCIENT.register(8, new SmokeSpells(SpellType.RUSH, 50, 30.0, Sounds.SMOKE_CAST_183, Sounds.SMOKE_RUSH_IMPACT_185, new Animation(1978, Priority.HIGH), null, RUSH_PROJECTILE, RUSH_END, Runes.DEATH_RUNE.getItem(2), Runes.CHAOS_RUNE.getItem(2), Runes.FIRE_RUNE.getItem(1), Runes.AIR_RUNE.getItem(1))); + SpellBook.ANCIENT.register(10, new SmokeSpells(SpellType.BURST, 62, 36.0, Sounds.SMOKE_CAST_183, Sounds.SMOKE_BURST_IMPACT_182, new Animation(1979, Priority.HIGH), null, BURST_PROJECTILE, BURST_END, Runes.DEATH_RUNE.getItem(2), Runes.CHAOS_RUNE.getItem(4), Runes.FIRE_RUNE.getItem(2), Runes.AIR_RUNE.getItem(2))); + SpellBook.ANCIENT.register(9, new SmokeSpells(SpellType.BLITZ, 74, 42.0, Sounds.SMOKE_CAST_183, Sounds.SMOKE_BLITZ_IMPACT_181, new Animation(1978, Priority.HIGH), null, BLITZ_PROJECTILE, BLITZ_END, Runes.BLOOD_RUNE.getItem(2), Runes.DEATH_RUNE.getItem(2), Runes.FIRE_RUNE.getItem(2), Runes.AIR_RUNE.getItem(2))); + SpellBook.ANCIENT.register(11, new SmokeSpells(SpellType.BARRAGE, 86, 48.0, Sounds.SMOKE_CAST_183, Sounds.SMOKE_BARRAGE_IMPACT_180, new Animation(1979, Priority.HIGH), null, BARRAGE_PROJECTILE, BARRAGE_END, Runes.BLOOD_RUNE.getItem(2), Runes.DEATH_RUNE.getItem(4), Runes.FIRE_RUNE.getItem(4), Runes.AIR_RUNE.getItem(4))); + return this; + } + + @Override + public void visualize(Entity entity, Node target) { + entity.graphics(graphic); + if (projectile != null) { + projectile.transform(entity, (Entity) target, false, 58, 10).send(); + } + entity.animate(animation); + playGlobalAudio(entity.getLocation(), audio.id, 20); + } + + @Override + public void fireEffect(Entity entity, Entity victim, BattleState state) { + if (state.getEstimatedHit() > -1) { + applyPoison(victim, entity, type.ordinal() >= SpellType.BLITZ.ordinal() ? 4 : 2); + } + } + + @Override + public BattleState[] getTargets(Entity entity, Entity target) { + if (animation.getId() == 1978 || !entity.getProperties().isMultiZone() || !target.getProperties().isMultiZone()) { + return super.getTargets(entity, target); + } + List list = getMultihitTargets(entity, target, 9); + BattleState[] targets = new BattleState[list.size()]; + int index = 0; + for (Entity e : list) { + targets[index++] = new BattleState(entity, e); + } + return targets; + } + + @Override + public int getMaximumImpact(Entity entity, Entity victim, BattleState state) { + return getType().getImpactAmount(entity, victim, 1); + } + +} diff --git a/Server/src/main/content/global/skill/magic/lunar/HealSpell.java b/Server/src/main/content/global/skill/magic/lunar/HealSpell.java new file mode 100644 index 0000000..f79c857 --- /dev/null +++ b/Server/src/main/content/global/skill/magic/lunar/HealSpell.java @@ -0,0 +1,145 @@ +package content.global.skill.magic.lunar; + +import core.game.node.entity.combat.spell.MagicSpell; +import core.game.node.entity.combat.spell.Runes; +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.ImpactHandler.HitsplatType; +import core.game.node.entity.combat.spell.SpellType; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.node.item.Item; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Plugin; +import org.rs09.consts.Sounds; + +import java.util.Iterator; +import java.util.List; + +import static core.api.ContentAPIKt.playGlobalAudio; + +/** + * Represents the healing spell. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class HealSpell extends MagicSpell { + + /** + * Represents the animation for this spell. + */ + private static final Animation ANIMATION = new Animation(4411); + + /** + * Represents the graphics of this spell. + */ + private static final Graphics GRAPHICS = new Graphics(738, 90); + + /** + * Represents the animation used for the group heal. + */ + private static final Animation ANIMATION_G = new Animation(1979); + + /** + * Represents the graphics used for the group heal. + */ + private static final Graphics GRAPHICS_G = new Graphics(734, 90); + + /** + * Constructs a new {@code HealSpell} {@code Object}. + */ + public HealSpell() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code HealSpell} {@code Object}. + */ + public HealSpell(int level, int experience, Item[] runes) { + super(SpellBook.LUNAR, level, experience, null, null, null, runes); + } + + @Override + public Plugin newInstance(SpellType arg) throws Throwable { + SpellBook.LUNAR.register(29, new HealSpell(92, 101, new Item[] { new Item(Runes.BLOOD_RUNE.getId(), 1), new Item(Runes.LAW_RUNE.getId(), 3), new Item(Runes.ASTRAL_RUNE.getId(), 3) })); + SpellBook.LUNAR.register(30, new HealSpell(92, 101, new Item[] { new Item(Runes.BLOOD_RUNE.getId(), 3), new Item(Runes.LAW_RUNE.getId(), 6), new Item(Runes.ASTRAL_RUNE.getId(), 4) })); + return this; + } + + @Override + public boolean cast(Entity entity, Node target) { + final Player player = (Player) entity; + boolean group = getSpellId() == 30; + int eleven = (int) (player.getSkills().getStaticLevel(Skills.HITPOINTS) * 0.11); + if (player.getSkills().getLifepoints() < eleven) { + player.sendMessage("You need at least 11 percent of your original hitpoints in order to do this."); + return false; + } + if (!group) { + if (!(target instanceof Player)) { + return false; + } + final Player o = (Player) target; + player.face(o); + if (!o.isActive() || o.getLocks().isInteractionLocked()) { + player.getPacketDispatch().sendMessage("This player is busy."); + return false; + } + if (!o.getSettings().isAcceptAid()) { + player.getPacketDispatch().sendMessage("The player is not accepting any aid."); + return false; + } + if (o.getSkills().getLifepoints() == o.getSkills().getLevel(Skills.HITPOINTS)) { + player.getPacketDispatch().sendMessage("The player already has full hitpoints."); + return false; + } + if (!super.meetsRequirements(player, true, true)) { + return false; + } + int transfer = (int) (player.getSkills().getLifepoints() * 0.75); + player.getImpactHandler().manualHit(player, transfer, null); + o.getSkills().heal(transfer); + player.animate(ANIMATION); + playGlobalAudio(player.getLocation(), Sounds.LUNAR_HEAL_OTHER_2895); + playGlobalAudio(o.getLocation(), Sounds.LUNAR_HEAL_OTHER_INDIVIDUAL_2892); + o.graphics(GRAPHICS); + } else { + List players = RegionManager.getLocalPlayers(player, 1); + if (!super.meetsRequirements(player, true, true)) { + return false; + } + int percentage = (int) Math.ceil(player.getSkills().getLifepoints() * 0.75); + for (Iterator it = players.iterator(); it.hasNext();) { + Player p = it.next(); + if (p == player || !p.getSettings().isAcceptAid() || !p.isActive() || p.getSkills().getLifepoints() == p.getSkills().getMaximumLifepoints()) { + it.remove(); + } + } + if (players.isEmpty()) { + player.getPacketDispatch().sendMessage("There are no players around to replenish."); + return false; + } + if (percentage < 1) { + player.getPacketDispatch().sendMessage("You don't have enough hitpoints left to cast this spell."); + return false; + } + player.getImpactHandler().manualHit(player, percentage, HitsplatType.NORMAL); + player.animate(ANIMATION_G); + playGlobalAudio(player.getLocation(), Sounds.LUNAR_HEAL_GROUP_2894); + for (Player p : players) { + playGlobalAudio(p.getLocation(), Sounds.LUNAR_HEAL_OTHER_INDIVIDUAL_2892); + p.graphics(GRAPHICS_G); + p.getSkills().heal(percentage); + } + } + return true; + } + +} diff --git a/Server/src/main/content/global/skill/magic/lunar/LunarData.kt b/Server/src/main/content/global/skill/magic/lunar/LunarData.kt new file mode 100644 index 0000000..9a1b28f --- /dev/null +++ b/Server/src/main/content/global/skill/magic/lunar/LunarData.kt @@ -0,0 +1,135 @@ +package content.global.skill.magic.lunar + +import core.api.addItemOrDrop +import core.api.freeSlots +import core.api.removeItem +import core.api.sendMessage +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import org.rs09.consts.Items + +private val HunterKitContents = intArrayOf( + Items.NOOSE_WAND_10150, + Items.BUTTERFLY_NET_10010, + Items.BIRD_SNARE_10006, + Items.RABBIT_SNARE_10031, + Items.TEASING_STICK_10029, + Items.UNLIT_TORCH_596, + Items.BOX_TRAP_10008 +) + +class HunterKitInteraction : InteractionListener { + override fun defineListeners() { + on(Items.HUNTER_KIT_11159, IntType.ITEM, "open") { player, _ -> + if(freeSlots(player) < 6) sendMessage(player, "You don't have enough inventory space.").also { return@on false } + if(removeItem(player, Items.HUNTER_KIT_11159)) { + for(item in HunterKitContents) { + addItemOrDrop(player, item) + } + } + return@on true + } + } +} + +enum class StringJewelleryItems(val unstrung: Int, val strung: Int) { + GOLD(Items.GOLD_AMULET_1673, Items.GOLD_AMULET_1692), + SAPPHIRE(Items.SAPPHIRE_AMULET_1675, Items.SAPPHIRE_AMULET_1694), + EMERALD(Items.EMERALD_AMULET_1677, Items.EMERALD_AMULET_1696), + RUBY(Items.RUBY_AMULET_1679, Items.RUBY_AMULET_1698), + DIAMOND(Items.DIAMOND_AMULET_1681, Items.DIAMOND_AMULET_1700), + DRAGONSTONE(Items.DRAGONSTONE_AMMY_1683, Items.DRAGONSTONE_AMMY_1702), + ONYX(Items.ONYX_AMULET_6579, Items.ONYX_AMULET_6581), + SALVE(Items.SALVE_SHARD_4082, Items.SALVE_AMULET_4081), + HOLY(Items.UNSTRUNG_SYMBOL_1714, Items.UNBLESSED_SYMBOL_1716), + UNHOLY(Items.UNSTRUNG_EMBLEM_1720, Items.UNPOWERED_SYMBOL_1722); + companion object { + private val productOfString = values().associate { it.unstrung to it.strung } + fun forId(id: Int): Int { + return productOfString[id]!! + } + + fun unstrungContains(id: Int): Boolean { + return productOfString.contains(id) + } + } +} + +enum class HumidifyItems(val empty: Int, val full: Int) { + VIAL(Items.VIAL_229, Items.VIAL_OF_WATER_227), + WATERSKIN0(Items.WATERSKIN0_1831, Items.WATERSKIN4_1823), + WATERSKIN1(Items.WATERSKIN1_1829, Items.WATERSKIN4_1823), + WATERSKIN2(Items.WATERSKIN2_1827, Items.WATERSKIN4_1823), + WATERSKIN3(Items.WATERSKIN3_1825, Items.WATERSKIN4_1823), + BUCKET(Items.BUCKET_1925, Items.BUCKET_OF_WATER_1929), + BOWL(Items.BOWL_1923, Items.BOWL_OF_WATER_1921), + JUG(Items.JUG_1935, Items.JUG_OF_WATER_1937), + WATERING_CAN0(Items.WATERING_CAN_5331, Items.WATERING_CAN8_5340), + WATERING_CAN1(Items.WATERING_CAN1_5333, Items.WATERING_CAN8_5340), + WATERING_CAN2(Items.WATERING_CAN2_5334, Items.WATERING_CAN8_5340), + WATERING_CAN3(Items.WATERING_CAN3_5335, Items.WATERING_CAN8_5340), + WATERING_CAN4(Items.WATERING_CAN4_5336, Items.WATERING_CAN8_5340), + WATERING_CAN5(Items.WATERING_CAN5_5337, Items.WATERING_CAN8_5340), + WATERING_CAN6(Items.WATERING_CAN6_5338, Items.WATERING_CAN8_5340), + WATERING_CAN7(Items.WATERING_CAN7_5339, Items.WATERING_CAN8_5340), + FISHBOWL(Items.FISHBOWL_6667, Items.FISHBOWL_6668), + KETTLE(Items.KETTLE_7688, Items.FULL_KETTLE_7690), + ENCHANTED_VIAL(Items.ENCHANTED_VIAL_731, Items.HOLY_WATER_732), + CUP(Items.EMPTY_CUP_1980, Items.CUP_OF_WATER_4458); + companion object { + private val productOfFill = values().associate { it.empty to it.full } + fun forId(id: Int): Int { + return productOfFill[id]!! + } + + fun emptyContains(id: Int): Boolean { + return productOfFill.contains(id) + } + } +} + +enum class PlankType (val log: Item, val plank: Item, val price: Int) { + WOOD(Item(1511), Item(960), 70), + OAK(Item(1521), Item(8778), 175), + TEAK(Item(6333), Item(8780), 350), + MAHOGANY(Item(6332), Item(8782), 1050); + companion object { + fun getForLog(item: Item): PlankType? { + for (plankType in values()) { + if (plankType.log.id == item.id) { + return plankType + } + } + return null + } + } +} + +val statSpySkills = arrayOf( + intArrayOf(Skills.ATTACK, 1, 2), + intArrayOf(Skills.HITPOINTS, 5, 6), + intArrayOf(Skills.MINING, 9, 10), + intArrayOf(Skills.STRENGTH, 13, 14), + intArrayOf(Skills.AGILITY, 17, 18), + intArrayOf(Skills.SMITHING, 21, 22), + intArrayOf(Skills.DEFENCE, 25, 26), + intArrayOf(Skills.HERBLORE, 29, 30), + intArrayOf(Skills.FISHING, 33, 34), + intArrayOf(Skills.RANGE, 37, 38), + intArrayOf(Skills.THIEVING, 41, 42), + intArrayOf(Skills.COOKING, 45, 46), + intArrayOf(Skills.PRAYER, 49, 50), + intArrayOf(Skills.CRAFTING, 53, 54), + intArrayOf(Skills.FIREMAKING, 57, 58), + intArrayOf(Skills.MAGIC, 61, 62), + intArrayOf(Skills.FLETCHING, 65, 66), + intArrayOf(Skills.WOODCUTTING, 69, 70), + intArrayOf(Skills.RUNECRAFTING, 73, 74), + intArrayOf(Skills.SLAYER, 77, 78), + intArrayOf(Skills.FARMING, 81, 82), + intArrayOf(Skills.CONSTRUCTION, 85, 86), + intArrayOf(Skills.HUNTER, 89, 90), + intArrayOf(Skills.SUMMONING, 93, 94) +) \ No newline at end of file diff --git a/Server/src/main/content/global/skill/magic/lunar/LunarListeners.kt b/Server/src/main/content/global/skill/magic/lunar/LunarListeners.kt new file mode 100644 index 0000000..1a89b9f --- /dev/null +++ b/Server/src/main/content/global/skill/magic/lunar/LunarListeners.kt @@ -0,0 +1,851 @@ +package content.global.skill.magic.lunar + +import content.global.skill.cooking.CookableItems +import content.global.skill.farming.CompostBins +import content.global.skill.farming.CompostType +import content.global.skill.farming.FarmingPatch +import content.global.skill.magic.SpellListener +import content.global.skill.magic.spellconsts.Lunar +import core.api.* +import core.game.component.CloseEvent +import core.game.component.Component +import core.game.interaction.QueueStrength +import core.game.node.Node +import core.game.node.entity.combat.ImpactHandler +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.TeleportManager +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.node.scenery.Scenery +import core.game.system.command.Privilege +import core.game.system.config.NPCConfigParser +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.map.RegionManager +import core.game.world.repository.Repository +import core.game.world.update.flag.context.Animation +import core.tools.RandomFunction +import org.rs09.consts.* +import kotlin.math.floor + +class LunarListeners : SpellListener("lunar"), Commands { + + override fun defineListeners() { + // Level 0 + onCast(Lunar.HOME_TELEPORT, NONE) { player, _ -> + requires(player) + player.teleporter.send(Location.create(2100, 3914, 0),TeleportManager.TeleportType.HOME) + setDelay(player,true) + } + + // Level 65 + onCast(Lunar.BAKE_PIE, NONE) { player, _ -> + requires(player,65, arrayOf(Item(Items.ASTRAL_RUNE_9075), Item(Items.FIRE_RUNE_554,5), Item(Items.WATER_RUNE_555,4))) + bakePie(player) + } + + // Level 66 + onCast(Lunar.CURE_PLANT, OBJECT) { player, node -> + requires(player,66, arrayOf(Item(Items.ASTRAL_RUNE_9075), Item(Items.EARTH_RUNE_557,8))) + curePlant(player,node!!.asScenery()) + } + + // Level 66 + onCast(Lunar.MONSTER_EXAMINE, NPC) { player, node -> + requires(player,66, arrayOf(Item(Items.ASTRAL_RUNE_9075), Item(Items.MIND_RUNE_558), Item(Items.COSMIC_RUNE_564))) + monsterExamine(player,node!!.asNpc()) + } + + // Level 67 + onCast(Lunar.NPC_CONTACT, NONE) { player, _ -> + requires(player,67, arrayOf(Item(Items.ASTRAL_RUNE_9075), Item(Items.COSMIC_RUNE_564), Item(Items.AIR_RUNE_556,2))) + npcContact(player) + } + + // Level 68 + onCast(Lunar.CURE_OTHER, PLAYER) { player, node -> + requires(player, 68, arrayOf(Item(Items.ASTRAL_RUNE_9075, 1), Item(Items.LAW_RUNE_563), Item(Items.EARTH_RUNE_557, 10))) + node?.let { cureOther(player, node) } + } + + // Level 68 + onCast(Lunar.HUMIDIFY, NONE) { player, _ -> + requires(player, 68, arrayOf(Item(Items.ASTRAL_RUNE_9075, 1), Item(Items.WATER_RUNE_555, 3), Item(Items.FIRE_RUNE_554, 1))) + humidify(player) + } + + // Level 69 + onCast(Lunar.MOONCLAN_TELEPORT, NONE) { player, _ -> + requires(player, 69, arrayOf(Item(Items.ASTRAL_RUNE_9075,2), Item(Items.LAW_RUNE_563,1), Item(Items.EARTH_RUNE_557,2))) + if (!player.isTeleBlocked) playGlobalAudio(player.location, Sounds.TELEPORT_ALL_200) + sendTeleport(player, 66.0, Location.create(2111, 3916, 0)) + } + + // Level 70 + onCast(Lunar.MOONCLAN_GROUP_TELEPORT, NONE) { player, _ -> + requires(player,70, arrayOf(Item(Items.ASTRAL_RUNE_9075,2), Item(Items.LAW_RUNE_563,1), Item(Items.EARTH_RUNE_557,4))) + if (!player.isTeleBlocked) playGlobalAudio(player.location, Sounds.TELEPORT_ALL_200) + sendGroupTeleport(player,67.0,"Moonclan Island",Location.create(2111, 3916, 0)) + } + + // Level 71 + onCast(Lunar.OURANIA_TELEPORT, NONE) { player, _ -> + requires(player, 71, arrayOf(Item(Items.ASTRAL_RUNE_9075, 2), Item(Items.LAW_RUNE_563, 1), Item(Items.EARTH_RUNE_557, 6))) + if (!player.isTeleBlocked) playGlobalAudio(player.location, Sounds.TELEPORT_ALL_200) + sendTeleport(player, 69.0, Location.create(2469, 3247, 0)) + } + + // Level 71 + onCast(Lunar.CURE_ME, NONE) { player, _ -> + requires(player, 71, arrayOf(Item(Items.ASTRAL_RUNE_9075, 2), Item(Items.LAW_RUNE_563, 1), Item(Items.COSMIC_RUNE_564, 2))) + cureMe(player) + } + + // Level 71 + onCast(Lunar.HUNTER_KIT, NONE) { player, _ -> + requires(player, 71, arrayOf(Item(Items.ASTRAL_RUNE_9075, 2), Item(Items.EARTH_RUNE_557, 2))) + if(freeSlots(player) == 0) sendMessage(player, "Not enough inventory space!").also { return@onCast } + hunterKit(player) + } + + // Level 72 + onCast(Lunar.WATERBIRTH_TELEPORT, NONE){ player, _ -> + requires(player,72, arrayOf(Item(Items.ASTRAL_RUNE_9075,2), Item(Items.LAW_RUNE_563), Item(Items.WATER_RUNE_555))) + if (!player.isTeleBlocked) playGlobalAudio(player.location, Sounds.TELEPORT_ALL_200) + sendTeleport(player,71.0, Location.create(2527, 3739, 0)) + } + + // Level 73 + onCast(Lunar.WATERBIRTH_GROUP_TELEPORT, NONE) { player, _ -> + requires(player,73, arrayOf(Item(Items.ASTRAL_RUNE_9075,2), Item(Items.LAW_RUNE_563), Item(Items.WATER_RUNE_555,5))) + if (!player.isTeleBlocked) playGlobalAudio(player.location, Sounds.TELEPORT_ALL_200) + sendGroupTeleport(player,72.0,"Waterbirth Island", Location.create(2527, 3739, 0)) + } + + // Level 74 + onCast(Lunar.CURE_GROUP, NONE) { player, _ -> + requires(player, 74, arrayOf(Item(Items.ASTRAL_RUNE_9075, 2), Item(Items.LAW_RUNE_563, 2), Item(Items.COSMIC_RUNE_564, 2))) + cureGroup(player) + } + + // Level 75 + onCast(Lunar.STAT_SPY, PLAYER) { player, node -> + requires(player, 75, arrayOf(Item(Items.COSMIC_RUNE_564, 2), Item(Items.ASTRAL_RUNE_9075, 2), Item(Items.BODY_RUNE_559, 5))) + node?.let { statSpy(player, node) } + } + + // Level 75 + onCast(Lunar.BARBARIAN_TELEPORT, NONE) { player, _ -> + requires(player,75, arrayOf(Item(Items.ASTRAL_RUNE_9075,2), Item(Items.LAW_RUNE_563,2), Item(Items.FIRE_RUNE_554,3))) + if (!player.isTeleBlocked) playGlobalAudio(player.location, Sounds.TELEPORT_ALL_200) + sendTeleport(player,76.0, Location.create(2544, 3572, 0)) + } + + // Level 76 + onCast(Lunar.BARBARIAN_GROUP_TELEPORT, NONE) { player, _ -> + requires(player,77, arrayOf(Item(Items.ASTRAL_RUNE_9075,2), Item(Items.LAW_RUNE_563,2), Item(Items.FIRE_RUNE_554,6))) + if (!player.isTeleBlocked) playGlobalAudio(player.location, Sounds.TELEPORT_ALL_200) + sendGroupTeleport(player,77.0,"Barbarian Outpost", Location.create(2544, 3572, 0)) + } + + // Level 77 + onCast(Lunar.SUPERGLASS_MAKE, NONE) { player, _ -> + requires(player, 77, arrayOf(Item(Items.ASTRAL_RUNE_9075, 2), Item(Items.FIRE_RUNE_554, 6), Item(Items.AIR_RUNE_556, 10))) + superglassMake(player) + } + + // Level 78 + onCast(Lunar.KHAZARD_TELEPORT, NONE) { player, _ -> + requires(player,78, arrayOf(Item(Items.ASTRAL_RUNE_9075,2), Item(Items.LAW_RUNE_563,2), Item(Items.WATER_RUNE_555,4))) + if (!player.isTeleBlocked) playGlobalAudio(player.location, Sounds.TELEPORT_ALL_200) + sendTeleport(player,80.0, Location.create(2656, 3157, 0)) + } + + // Level 79 + onCast(Lunar.KHAZARD_GROUP_TELEPORT, NONE) { player, _ -> + requires(player,79, arrayOf(Item(Items.ASTRAL_RUNE_9075,2), Item(Items.LAW_RUNE_563,2), Item(Items.WATER_RUNE_555,8))) + if (!player.isTeleBlocked) playGlobalAudio(player.location, Sounds.TELEPORT_ALL_200) + sendGroupTeleport(player,81.0, "Port Khazard", Location.create(2656, 3157, 0)) + } + + // Level 79 + onCast(Lunar.DREAM, NONE) { player, _ -> + requires(player, 79, arrayOf(Item(Items.ASTRAL_RUNE_9075, 2), Item(Items.BODY_RUNE_559, 5), Item(Items.COSMIC_RUNE_564, 1))) + dream(player) + } + + // Level 80 + onCast(Lunar.STRING_JEWELLERY, NONE) { player, _ -> + requires(player, 80, arrayOf(Item(Items.ASTRAL_RUNE_9075, 2), Item(Items.EARTH_RUNE_557, 10), Item(Items.WATER_RUNE_555, 5))) + stringJewellery(player) + } + + // Level 81 + /** + * Stat Restore Pot Share + */ + + // Level 82 + /** + * Magic Imbue + */ + + // Level 83 + onCast(Lunar.FERTILE_SOIL, OBJECT) { player, node -> + requires(player, 83, arrayOf(Item(Items.ASTRAL_RUNE_9075, 3), Item(Items.NATURE_RUNE_561, 2), Item(Items.EARTH_RUNE_557, 15))) + node?.let { fertileSoil(player, node.asScenery()) } + } + + // Level 84 + /** + * Boost Potion Share + */ + + // Level 85 + onCast(Lunar.FISHING_GUILD_TELEPORT, NONE) { player, _ -> + requires(player,85, arrayOf(Item(Items.ASTRAL_RUNE_9075,3), Item(Items.LAW_RUNE_563,3), Item(Items.WATER_RUNE_555,10))) + if (!player.isTeleBlocked) playGlobalAudio(player.location, Sounds.TELEPORT_ALL_200) + sendTeleport(player,89.0, Location.create(2611, 3393, 0)) + } + + // Level 86 + onCast(Lunar.FISHING_GUILD_GROUP_TELEPORT, NONE) { player, _ -> + requires(player,86, arrayOf(Item(Items.ASTRAL_RUNE_9075,3), Item(Items.LAW_RUNE_563,3), Item(Items.WATER_RUNE_555,14))) + if (!player.isTeleBlocked) playGlobalAudio(player.location, Sounds.TELEPORT_ALL_200) + sendGroupTeleport(player,90.0,"Fishing Guild", Location.create(2611, 3393, 0)) + } + + // Level 86 + onCast(Lunar.PLANK_MAKE, ITEM) { player, node -> + requires(player, 86, arrayOf(Item(Items.ASTRAL_RUNE_9075, 2), Item(Items.NATURE_RUNE_561, 1), Item(Items.EARTH_RUNE_557, 15))) + plankMake(player, node!!.asItem()) + } + + // Level 87 + onCast(Lunar.CATHERBY_TELEPORT, NONE) { player, _ -> + requires(player,87, arrayOf(Item(Items.ASTRAL_RUNE_9075,3), Item(Items.LAW_RUNE_563,3), Item(Items.WATER_RUNE_555,10))) + if (!player.isTeleBlocked) playGlobalAudio(player.location, Sounds.TELEPORT_ALL_200) + sendTeleport(player,92.0, Location.create(2804, 3433, 0)) + } + + // Level 88 + onCast(Lunar.CATHERBY_GROUP_TELEPORT, NONE) { player, _ -> + requires(player,88, arrayOf(Item(Items.ASTRAL_RUNE_9075,3), Item(Items.LAW_RUNE_563,3), Item(Items.WATER_RUNE_555,15))) + if (!player.isTeleBlocked) playGlobalAudio(player.location, Sounds.TELEPORT_ALL_200) + sendGroupTeleport(player,93.0,"Catherby", Location.create(2804, 3433, 0)) + } + + // Level 89 + onCast(Lunar.ICE_PLATEAU_TELEPORT, NONE) { player, _ -> + requires(player,89, arrayOf(Item(Items.ASTRAL_RUNE_9075,3), Item(Items.LAW_RUNE_563,3), Item(Items.WATER_RUNE_555,8))) + if (!player.isTeleBlocked) playGlobalAudio(player.location, Sounds.TELEPORT_ALL_200) + sendTeleport(player,96.0, Location.create(2972, 3873, 0)) + } + + // Level 90 + onCast(Lunar.ICE_PLATEAU_GROUP_TELEPORT, NONE) { player, _ -> + requires(player,90, arrayOf(Item(Items.ASTRAL_RUNE_9075,3), Item(Items.LAW_RUNE_563,3), Item(Items.WATER_RUNE_555,16))) + if (!player.isTeleBlocked) playGlobalAudio(player.location, Sounds.TELEPORT_ALL_200) + sendGroupTeleport(player,99.0, "Ice Plateau", Location.create(2972, 3873, 0)) + } + + // Level 91 + onCast(Lunar.ENERGY_TRANSFER, PLAYER) { player, node -> + requires(player, 91, arrayOf(Item(Items.ASTRAL_RUNE_9075, 3), Item(Items.LAW_RUNE_563, 2), Item(Items.NATURE_RUNE_561, 1))) + node?.let { energyTransfer(player, node) } + } + + // Level 92 + /** + * Heal Other + */ + + // Level 93 + /** + * Vengeance Other + */ + + // Level 94 + /** + * Vengeance + */ + + // Level 95 + /** + * Heal Group + */ + + // Level 96 + /** + * Spellbook Swap + */ + } + + // Spell handlers + // Level 65 + private fun bakePie(player: Player){ + val playerPies = ArrayList() + + for(item in player.inventory.toArray()){ + if(item == null) continue + val pie = CookableItems.forId(item.id) ?: continue + if(!pie.name.lowercase().contains("pie")) continue + if(player.skills.getLevel(Skills.COOKING) < pie.level) continue + playerPies.add(item) + } + + if(playerPies.isEmpty()){ + player.sendMessage("You have no pies which you have the level to cook.") + return + } + + player.pulseManager.run(object : Pulse(){ + var counter = 0 + override fun pulse(): Boolean { + if(playerPies.isEmpty()) return true + + if(counter == 0) delay = animationDuration(Animation(Animations.LUNAR_SPELLBOOK_BAKE_PIE_4413)) + 1 + val item = playerPies[0] + val pie = CookableItems.forId(item.id) + visualizeSpell(player, Animations.LUNAR_SPELLBOOK_BAKE_PIE_4413, Graphics.LUNAR_SPELLBOOK_BAKE_PIE_746, 75, Sounds.LUNAR_BAKE_PIE_2879) + addXP(player,60.0) + player.skills.addExperience(Skills.COOKING, pie.experience) + setDelay(player,false) + player.inventory.remove(item) + player.inventory.add(Item(pie.cooked)) + playerPies.remove(item) + if(playerPies.isNotEmpty()) removeRunes(player,false) else removeRunes(player,true) + return false + } + }) + } + + // Level 66 + fun curePlant(player: Player, obj: Scenery) { + if (CompostBins.forObject(obj) != null) { + sendMessage(player, "Bins don't often get diseased.") + return + } + val fPatch = FarmingPatch.forObject(obj) + if (fPatch == null) { + sendMessage(player, "Umm... this spell won't cure that!") + return + } + val patch = fPatch.getPatchFor(player) + if (patch.isWeedy()) { + sendMessage(player, "The weeds are healthy enough already.") + return + } + if (patch.isEmptyAndWeeded()) { + sendMessage(player, "There's nothing there to cure.") + return + } + if (patch.isGrown()) { + sendMessage(player, "That's not diseased.") + return + } + if (patch.isDead) { + sendMessage(player, "It says 'Cure' not 'Resurrect'. Although death may arise from disease, it is not in itself a disease and hence cannot be cured. So there.") + return + } + if (!patch.isDiseased) { + sendMessage(player, "It is growing just fine.") + return + } + + patch.cureDisease() + removeRunes(player) + addXP(player,60.0) + visualizeSpell(player, Animations.LUNAR_SPELLBOOK_CURE_PLANT_4409, Graphics.LUNAR_SPELLBOOK_CURE_PLANT_748, 100, Sounds.LUNAR_CURE_GROUP_2882) + setDelay(player,false) + } + + // Level 66 + private fun monsterExamine(player: Player, npc: NPC){ + if(!npc.location.withinDistance(player.location)){ + sendMessage(player, "You must get closer to use this spell.") + return + } + face(player, npc) + visualizeSpell(player, Animations.LUNAR_SPELLBOOK_STATSPY_6293, Graphics.LUNAR_SPELLBOOK_STAT_SPY_OVER_PLAYER_1060, soundID = Sounds.LUNAR_STAT_SPY_3620) + removeRunes(player) + addXP(player,66.0) + + setDelay(player, false) + openSingleTab(player, Components.DREAM_MONSTER_STAT_522) + setInterfaceText(player, "Monster name : ${npc.definition.name}", Components.DREAM_MONSTER_STAT_522, 0) + setInterfaceText(player, "Combat Level : ${npc.definition.combatLevel}", Components.DREAM_MONSTER_STAT_522, 1) + setInterfaceText(player, "Hitpoints : ${npc.definition.handlers[NPCConfigParser.LIFEPOINTS] ?: 0}", Components.DREAM_MONSTER_STAT_522, 2) + setInterfaceText(player, "Max hit : ${npc.getSwingHandler(false).calculateHit(npc, player, 1.0)}", Components.DREAM_MONSTER_STAT_522, 3) + + val poisonStatus = if(npc.definition.handlers.getOrDefault(NPCConfigParser.POISON_IMMUNE,false) == true){ + "This creature is immune to poison." + } else "This creature is not immune to poison." + + setInterfaceText(player, poisonStatus, Components.DREAM_MONSTER_STAT_522, 4) + } + + // Level 67 + private fun npcContact(player: Player) { + openInterface(player, 429) + setAttribute(player, "contact-caller") { + removeRunes(player) + addXP(player,63.0) + setDelay(player,false) + visualizeSpell(player, Animations.LUNAR_SPELLBOOK_NPC_CONTACT_4413, Graphics.LUNAR_SPELLBOOK_NPC_CONTACT_728, 130,3618) + } + } + + // Level 68 + private fun cureOther(player: Player, target: Node) { + if(!isPlayer(target)) { + sendMessage(player, "You can only cast this spell on other players.") + return + } + val p = target.asPlayer() + if(!p.isActive || p.locks.isInteractionLocked) { + sendMessage(player, "This player is busy.") + return + } + if(!p.settings.isAcceptAid) { + sendMessage(player, "This player is not accepting any aid.") + return + } + if(!isPoisoned(p)) { + sendMessage(player, "This player is not poisoned.") + return + } + player.face(p) + visualizeSpell(player, Animations.LUNAR_SPELLBOOK_CURE_OTHER_4411, Graphics.LUNAR_SPELLBOOK_CURE_OTHER_736, 130, Sounds.LUNAR_CURE_OTHER_2886) + visualizeSpell(p, -1, Graphics.LUNAR_SPELLBOOK_CURE_OTHER_736, 130, Sounds.LUNAR_CURE_OTHER_INDIVIDUAL_2889) + removeRunes(player, true) + curePoison(p) + sendMessage(p, "You have been cured of poison.") + addXP(player, 65.0) + } + + // Level 68 + private fun humidify(player: Player) { + val playerEmpties = ArrayDeque() + + for(item in player.inventory.toArray()) { + if(item == null) continue + if(!HumidifyItems.emptyContains(item.id)) continue + playerEmpties.add(item) + } + + if(playerEmpties.isEmpty()) { + sendMessage(player, "You have nothing in your inventory that this spell can humidify.") + return + } + + removeRunes(player) + delayEntity(player, Animation(Animations.LUNAR_SPELLBOOK_HUMIDIFY_6294).duration) + visualizeSpell(player, Animations.LUNAR_SPELLBOOK_HUMIDIFY_6294, Graphics.LUNAR_SPELLBOOK_HUMIDIFY_1061, 20, Sounds.LUNAR_HUMIDIFY_3614) + for(item in playerEmpties) { + val filled = HumidifyItems.forId(item.id) + removeItem(player, item.id) && addItem(player, filled) + } + addXP(player, 65.0) + /** + queueScript(player) { + return@queueScript stopExecuting(player) + } + */ + } + + // Level 71 + private fun cureMe(player: Player) { + if(!isPoisoned(player)) { + sendMessage(player, "You are not poisoned.") + return + } + removeRunes(player, true) + visualizeSpell(player, Animations.LUNAR_SPELLBOOK_CURE_ME_4411, Graphics.LUNAR_SPELLBOOK_CURE_ME_742, 90, Sounds.LUNAR_CURE_2884) + curePoison(player) + addXP(player, 69.0) + playAudio(player, Sounds.LUNAR_CURE_OTHER_INDIVIDUAL_2900) + sendMessage(player, "You have been cured of poison.") + } + + // Level 71 + private fun hunterKit(player: Player) { + removeRunes(player, true) + if(addItem(player, Items.HUNTER_KIT_11159)) { + visualizeSpell(player, Animations.LUNAR_SPELLBOOK_HUNTER_KIT_6303, Graphics.LUNAR_SPELLBOOK_HUNTER_KIT_1074, soundID = Sounds.LUNAR_HUNTER_KIT_3615) + addXP(player, 70.0) + setDelay(player, 2) + } + } + + // Level 74 + private fun cureGroup(player: Player) { + removeRunes(player, true) + visualizeSpell(player, Animations.LUNAR_SPELLBOOK_CURE_GROUP_4409, Graphics.LUNAR_SPELLBOOK_CURE_GROUP_744, 130, Sounds.LUNAR_CURE_GROUP_2882) + curePoison(player) + for(acct in RegionManager.getLocalPlayers(player, 1)) { + if(!acct.isActive || acct.locks.isInteractionLocked) { + continue + } + if(!acct.settings.isAcceptAid) { + continue + } + curePoison(acct) + sendMessage(acct, "You have been cured of poison.") + visualizeSpell(acct, -1, Graphics.LUNAR_SPELLBOOK_CURE_GROUP_744, 130, Sounds.LUNAR_CURE_OTHER_INDIVIDUAL_2889) + } + addXP(player, 74.0) + } + + // Level 75 + private fun statSpy(player: Player, target: Node) { + if(target !is Player) { + sendMessage(player, "You can only cast this spell on players.") + return + } + val stat = Components.DREAM_PLAYER_STATS_523 + val statCloseEvent = CloseEvent { p, _ -> + p.interfaceManager.restoreTabs() + return@CloseEvent true + } + + removeRunes(player, true) + + face(player, target) + animate(player, Animations.LUNAR_SPELLBOOK_STATSPY_6293) + playAudio(player, Sounds.LUNAR_STAT_SPY_3620) + + rewardXP(player, Skills.MAGIC, 76.0) + + Component(stat).setCloseEvent(statCloseEvent) + + sendGraphics(Graphics.LUNAR_SPELLBOOK_STAT_SPY_OVER_PLAYER_1060, player.location) + sendGraphics(Graphics.LUNAR_SPELLBOOK_STAT_SPY_OVER_MONSTER_734, target.location) + + playGlobalAudio(target.location, Sounds.LUNAR_STAT_SPY_IMPACT_3621) + + for(element in statSpySkills) { + setInterfaceText(player, "${ getDynLevel(target, element[0]) }", Components.DREAM_PLAYER_STATS_523, element[1]) + setInterfaceText(player, "${ getStatLevel(target, element[0]) }", Components.DREAM_PLAYER_STATS_523, element[2]) + } + + setInterfaceText(player, target.username, Components.DREAM_PLAYER_STATS_523, 99) + openSingleTab(player, stat) + } + + // Level 77 + private fun superglassMake(player: Player) { + val GLASS_WEEDS = hashSetOf(Items.SODA_ASH_1781, Items.SEAWEED_401, Items.SWAMP_WEED_10978) + val inv = player.inventory.toArray() + var playerWeed: Int = amountInInventory(player, Items.SODA_ASH_1781) + amountInInventory(player, Items.SEAWEED_401) + amountInInventory(player, Items.SWAMP_WEED_10978) + var playerSand: Int = amountInInventory(player, Items.BUCKET_OF_SAND_1783) + var index = 0 + + fun addMolten(): Boolean { + if(RandomFunction.randomDouble(1.0) < 0.3) { + if(addItem(player, Items.MOLTEN_GLASS_1775, 2)) return true + } else { + if(addItem(player, Items.MOLTEN_GLASS_1775)) return true + } + return false + } + + val size = minOf(playerSand, playerWeed) + + if(index != size && size != 0) { + for (item in inv) { + if (item == null) continue + if (index == size) break + if (GLASS_WEEDS.contains(item.id)) { + if (removeItem(player, item) && removeItem(player, Items.BUCKET_OF_SAND_1783) && addMolten()) { + index++ + } else { + break + } + } + } + } else if (playerWeed == 0 || playerSand == 0 || size == 0) { + sendMessage(player, "You lack the required ingredients.") + } + + if(index == size && size != 0) { + removeRunes(player, true) + visualizeSpell(player, Animations.LUNAR_SPELLBOOK_SUPERGLASS_MAKE_4413, Graphics.LUNAR_SPELLBOOK_SUPERGLASS_MAKE_729, 120, Sounds.LUNAR_HEATGLASS_2896) + rewardXP(player, Skills.CRAFTING, 10.0) + addXP(player, 78.0) + } + } + + // Level 79 + private fun dream(player: Player) { + if(player.skills.lifepoints >= getStatLevel(player, Skills.HITPOINTS)) { + sendMessage(player, "You have no need to cast this spell since your hitpoints are already full.") + return + } + + animate(player, Animations.LUNAR_SPELLBOOK_DREAM_START_6295) + delayEntity(player, 4) + queueScript(player, 4, QueueStrength.WEAK) { stage: Int -> + when(stage) { + 0 -> { + animate(player, Animations.LUNAR_SPELLBOOK_DREAM_MID_6296) + sendGraphics(Graphics.LUNAR_SPELLBOOK_DREAM_1056, player.location) + playAudio(player, Sounds.LUNAR_SLEEP_3619) + return@queueScript delayScript(player, 5) + } + else -> { + sendGraphics(Graphics.LUNAR_SPELLBOOK_DREAM_1056, player.location) + // This heals 2 HP every min. Naturally you heal 1 for a total of 3 + // The script steps every 5 ticks and we want 50 ticks before a heal + if (stage.mod(10) == 0){ + heal(player, 1) + if(player.skills.lifepoints >= getStatLevel(player, Skills.HITPOINTS)) { + animate(player, Animations.LUNAR_SPELLBOOK_DREAM_END_6297) + return@queueScript stopExecuting(player) + } + } + return@queueScript delayScript(player, 5) + } + } + } + } + + private fun stringJewellery(player: Player) { + val playerJewellery = ArrayDeque() + + for(item in player.inventory.toArray()) { + if(item == null) continue + if(!StringJewelleryItems.unstrungContains(item.id)) continue + playerJewellery.add(item) + } + + player.pulseManager.run(object : Pulse() { + var counter = 0 + override fun pulse(): Boolean { + removeAttribute(player, "spell:runes") + if (playerJewellery.isEmpty()) + return true + requires(player, 80, arrayOf(Item(Items.ASTRAL_RUNE_9075, 2), Item(Items.EARTH_RUNE_557, 10), Item(Items.WATER_RUNE_555, 5))) + if(counter == 0) delay = animationDuration(Animation(Animations.LUNAR_SPELLBOOK_STRING_JEWELLERY_4412)) + 1 + val item = playerJewellery[0] + val strung = StringJewelleryItems.forId(item.id) + setDelay(player,false) + if(removeItem(player, item) && addItem(player, strung)) { + removeRunes(player, true) + visualizeSpell(player, Animations.LUNAR_SPELLBOOK_STRING_JEWELLERY_4412, Graphics.LUNAR_SPELLBOOK_STRING_JEWELLERY_730, 100, Sounds.LUNAR_STRING_AMULET_2903) + rewardXP(player, Skills.CRAFTING, 4.0) + addXP(player, 83.0) + playerJewellery.remove(item) + if(playerJewellery.isNotEmpty()) removeRunes(player,false) else removeRunes(player,true) + } + counter++ + return playerJewellery.isEmpty() + } + }) + } + + // Level 81 + /** + * Stat Restore Pot Share + */ + + // Level 82 + /** + * Magic Imbue + */ + + // Level 83 + private fun fertileSoil(player: Player, target: Scenery) { + if (CompostBins.forObjectID(target.id) != null) { + sendMessage(player, "No, that would be silly.") + return + } + + val fPatch = FarmingPatch.forObject(target) + if(fPatch == null) { + sendMessage(player, "Um... I don't want to fertilize that!") + return + } + + val patch = fPatch.getPatchFor(player) + if (patch.isGrown()) { + sendMessage(player, "Composting isn't going to make it get any bigger.") + return + } + if (patch.isFertilized()) { + sendMessage(player, "This patch has already been composted.") + return + } + removeRunes(player, true) + animate(player, Animations.LUNAR_SPELLBOOK_FERTILE_SOIL_4413) + sendGraphics(Graphics.LUNAR_SPELLBOOK_FERTILE_SOIL_724, target.location) + playGlobalAudio(target.location, Sounds.LUNAR_FERTILIZE_2891) + patch.compost = CompostType.SUPERCOMPOST + sendMessage(player, "You fertilize the soil.") + addXP(player, 87.0) + } + + // Level 84 + /** + * Boost Potion Share + */ + + // Level 86 + private fun plankMake(player: Player, item: Item) { + val plankType = PlankType.getForLog(item) + if (plankType == null) { + sendMessage(player, "You need to use this spell on logs.") + return + } + if (amountInInventory(player, Items.COINS_995) < plankType.price || !removeItem(player, Item(Items.COINS_995, plankType.price))) { + sendMessage(player, "You need ${plankType.price} coins to convert that log into a plank.") + return + } + lock(player, 3) + setDelay(player, false) + visualizeSpell(player, Animations.LUNAR_SPELLBOOK_PLANK_MAKE_6298, Graphics.LUNAR_SPELLBOOK_PLANK_MAKE_1063, 120, Sounds.LUNAR_MAKE_PLANK_3617) + removeRunes(player) + replaceSlot(player, item.slot, plankType.plank) + addXP(player, 90.0) + showMagicTab(player) + } + + // Level 91 + private fun energyTransfer(player: Player, target: Node) { + if(!isPlayer(target)) { + sendMessage(player, "You can only cast this spell on other players.") + return + } + val targetPlayer = target.asPlayer() + if(!targetPlayer.isActive || targetPlayer.locks.isInteractionLocked) { + sendMessage(player, "This player is busy.") + return + } + if(!targetPlayer.settings.isAcceptAid) { + sendMessage(player, "This player is not accepting any aid.") + return + } + if(10 >= player.skills.lifepoints) { + sendMessage(player, "You need more hitpoints to cast this spell.") + return + } + player.face(targetPlayer) + visualizeSpell(player, Animations.LUNAR_SPELLBOOK_ENERGY_TRANSFER_4411, Graphics.LUNAR_SPELLBOOK_ENERGY_TRANSFER_738, 90, Sounds.LUNAR_ENERGY_TRANSFER_2885) + visualize(targetPlayer, -1, Graphics.LUNAR_SPELLBOOK_ENERGY_TRANSFER_738) + val hp = floor(player.skills.lifepoints * 0.10) + var run = hp + if(run > (100 - targetPlayer.settings.runEnergy)) { + run = (100 - targetPlayer.settings.runEnergy) + } + if(run < 0) { + run = 0.0 + } + targetPlayer.settings.runEnergy += run + player.settings.runEnergy -= run + impact(player, hp.toInt(), ImpactHandler.HitsplatType.NORMAL) + var energy = 100 + energy -= targetPlayer.settings.specialEnergy + if(energy < 0) { + energy = 0 + } + if(energy > player.settings.specialEnergy) { + energy = player.settings.specialEnergy + } + targetPlayer.settings.specialEnergy += energy + player.settings.specialEnergy -= energy + removeRunes(player, true) + addXP(player, 100.0) + } + + // Level 92 + /** + * Heal Other + */ + + // Level 93 + /** + * Vengeance Other + */ + + // Level 94 + /** + * Vengeance + */ + + // Level 95 + /** + * Heal Group + */ + + // Level 96 + /** + * Spellbook Swap + */ + + // Other/Multi spell use-case + private fun sendTeleport(player: Player, xp: Double, loc: Location){ + if(player.teleporter.send(loc,TeleportManager.TeleportType.LUNAR)) { + addXP(player, xp) + removeRunes(player) + setDelay(player, true) + } + } + + private fun sendGroupTeleport(player: Player, xp: Double, destName: String, loc: Location){ + RegionManager.getLocalPlayers(player, 1).forEach { + if(it == player) return@forEach + if(it.isTeleBlocked) return@forEach + if(!it.isActive) return@forEach + if(!it.settings.isAcceptAid) return@forEach + if(it.ironmanManager.isIronman) return@forEach + setAttribute(it, "t-o_location", loc) + openInterface(it, Components.TELEPORT_OTHER_326) + setInterfaceText(it, player.username, Components.TELEPORT_OTHER_326, 1) + setInterfaceText(it, destName, Components.TELEPORT_OTHER_326, 3) + } + + sendTeleport(player, xp, loc) + } + + override fun defineCommands() { + define("poison", privilege = Privilege.ADMIN) { player, strings -> + if(strings.size == 3) { + val dmg = strings[2].toIntOrNull() + val p = Repository.getPlayerByName(strings[1]) + if(p == null) { + sendMessage(player, "Player ${strings[1]} does not exist.") + return@define + } + if(dmg != null) { + p.let { applyPoison(it, it, dmg) } + } else { + sendMessage(player, "Damage must be an integer. Format:") + sendMessage(player, "::poison username damage") + } + } else { + sendMessage(player, "Invalid arguments provided. Format:") + sendMessage(player, "::poison username damage") + } + } + + define("humidifykit", privilege = Privilege.ADMIN) { player, _ -> + if(freeSlots(player) < 24) { + sendMessage(player, "Not enough free space.") + return@define + } else { + addItem(player, Items.ASTRAL_RUNE_9075, 100) + addItem(player, Items.WATER_RUNE_555, 300) + addItem(player, Items.FIRE_RUNE_554, 100) + for(item in HumidifyItems.values()) { + addItem(player, item.empty) + } + } + } + } +} + + + + + diff --git a/Server/src/main/content/global/skill/magic/lunar/MagicImbueSpell.java b/Server/src/main/content/global/skill/magic/lunar/MagicImbueSpell.java new file mode 100644 index 0000000..79512f7 --- /dev/null +++ b/Server/src/main/content/global/skill/magic/lunar/MagicImbueSpell.java @@ -0,0 +1,71 @@ +package content.global.skill.magic.lunar; + +import core.game.node.entity.combat.spell.MagicSpell; +import core.game.node.entity.combat.spell.Runes; +import core.plugin.Initializable; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.spell.SpellType; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.node.item.Item; +import core.game.world.GameWorld; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Plugin; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playAudio; + +/** + * The magic imbue spell. + * @author 'Vexia + */ +@Initializable +public class MagicImbueSpell extends MagicSpell { + + /** + * The graphic. + */ + private static final Graphics GRAPHIC = new Graphics(141, 96); + + /** + * The animation. + */ + private static final Animation ANIMATION = new Animation(722); + + /** + * Constructs a new {@code StatRestoreSpell} {@code Object}. + */ + public MagicImbueSpell() { + super(SpellBook.LUNAR, 82, 86, null, null, null, new Item[] { new Item(Runes.ASTRAL_RUNE.getId(), 2), new Item(Runes.FIRE_RUNE.getId(), 7), new Item(Runes.WATER_RUNE.getId(), 7) }); + } + + @Override + public Plugin newInstance(SpellType arg) throws Throwable { + SpellBook.LUNAR.register(13, this); + return this; + } + + @Override + public boolean cast(Entity entity, Node target) { + final Player player = ((Player) entity); + if (player == null) { + return false; + } + if (player.getAttribute("spell:imbue", 0) > GameWorld.getTicks()) { + player.sendMessage("You already have this activated."); + return false; + } + if (!super.meetsRequirements(player, true, true)) { + return false; + } + player.setAttribute("spell:imbue", GameWorld.getTicks() + 20); + player.lock(ANIMATION.getDuration() + 1); + player.graphics(GRAPHIC); + player.animate(ANIMATION); + playAudio(player, Sounds.LUNAR_EMBUE_RUNES_2888); + player.getPacketDispatch().sendMessage("You are charged to combine runes!"); + return true; + } +} diff --git a/Server/src/main/content/global/skill/magic/lunar/SpellbookSwapSpell.java b/Server/src/main/content/global/skill/magic/lunar/SpellbookSwapSpell.java new file mode 100644 index 0000000..4c152b0 --- /dev/null +++ b/Server/src/main/content/global/skill/magic/lunar/SpellbookSwapSpell.java @@ -0,0 +1,84 @@ +package content.global.skill.magic.lunar; + +import core.game.component.Component; +import core.game.node.entity.combat.spell.MagicSpell; +import core.game.node.entity.combat.spell.Runes; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.spell.SpellType; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.tools.RandomFunction; + +/** + * The spellbook swap spell. + * @author 'Vexia + */ +@Initializable +public class SpellbookSwapSpell extends MagicSpell { + + /** + * Represents the animation of this spell. + */ + private final Animation ANIMATION = new Animation(6299); + + /** + * Represents the graphics of this spell. + */ + private final Graphics GRAPHIC = new Graphics(1062); + + /** + * Constructs a new {@code SpellbookSwapSpell} {@code Object}. + */ + public SpellbookSwapSpell() { + super(SpellBook.LUNAR, 96, 130, null, null, null, new Item[] { new Item(Runes.LAW_RUNE.getId(), 1), new Item(Runes.COSMIC_RUNE.getId(), 2), new Item(Runes.ASTRAL_RUNE.getId(), 3) }); + } + + @Override + public Plugin newInstance(SpellType arg) throws Throwable { + SpellBook.LUNAR.register(12, this); + return this; + } + + @Override + public boolean cast(Entity entity, Node target) { + final Player player = (Player) entity; + if (!super.meetsRequirements(player, true, true)) { + return false; + } + player.lock(9); + player.animate(ANIMATION); + player.graphics(GRAPHIC); + player.getDialogueInterpreter().open(3264731); + final int id = RandomFunction.random(1, 500000); + player.setAttribute("spell:swap", id); + GameWorld.getPulser().submit(new Pulse(20, player) { + @Override + public boolean pulse() { + if (player.getAttribute("spell:swap", 0) == id) { + removeTemporarySpell(player); + } + return true; + } + + }); + return true; + } + + /** + * Method used to remove the temp spell swap. + * @param player the player. + */ + public static void removeTemporarySpell(final Player player) { + player.removeAttribute("spell:swap"); + player.getSpellBookManager().setSpellBook(SpellBook.LUNAR); + player.getInterfaceManager().openTab(new Component(SpellBook.LUNAR.getInterfaceId())); + } +} diff --git a/Server/src/main/content/global/skill/magic/lunar/StatBoostSpell.java b/Server/src/main/content/global/skill/magic/lunar/StatBoostSpell.java new file mode 100644 index 0000000..61aeee5 --- /dev/null +++ b/Server/src/main/content/global/skill/magic/lunar/StatBoostSpell.java @@ -0,0 +1,97 @@ +package content.global.skill.magic.lunar; + +import content.data.consumables.Consumables; +import core.game.consumable.Potion; +import core.game.node.entity.combat.spell.MagicSpell; +import core.game.node.entity.combat.spell.Runes; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.spell.SpellType; +import core.game.node.entity.player.Player; +import core.game.bots.AIPlayer; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.node.item.Item; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.plugin.Plugin; +import org.rs09.consts.Sounds; + +import java.util.List; + +import static core.api.ContentAPIKt.playGlobalAudio; + +@Initializable +public final class StatBoostSpell extends MagicSpell { + + private static final Animation ANIMATION = new Animation(4413); + private static final Graphics GRAPHICS = new Graphics(733, 130); + public static final int VIAL = 229; + public StatBoostSpell() { + super(SpellBook.LUNAR, 84, 88, null, null, null, new Item[] { new Item(Runes.ASTRAL_RUNE.getId(), 3), new Item(Runes.EARTH_RUNE.getId(), 12), new Item(Runes.WATER_RUNE.getId(), 10) }); + } + + @Override + public Plugin newInstance(SpellType arg) throws Throwable { + SpellBook.LUNAR.register(26, this); + return this; + } + + @Override + public boolean cast(Entity entity, Node target) { + final Player player = ((Player) entity); + Item item = ((Item) target); + final Potion potion = (Potion) Consumables.getConsumableById(item.getId()).getConsumable(); + player.getInterfaceManager().setViewedTab(6); + if (potion == null) { + player.getPacketDispatch().sendMessage("You can only cast this spell on a potion."); + return false; + } + if (!item.getDefinition().isTradeable() || item.getName().toLowerCase().contains("restore") || item.getName().toLowerCase().contains("zamorak") || item.getName().toLowerCase().contains("saradomin") || item.getName().toLowerCase().contains("combat")) { + player.getPacketDispatch().sendMessage("You can't cast this spell on that item."); + return false; + } + List pl = RegionManager.getLocalPlayers(player, 1); + int plSize = pl.size() - 1; + int doses = potion.getDose(item); + if (pl.size() == 0) { + return false; + } + if (!super.meetsRequirements(player, true, false)) { + return false; + } + int size = 0; + for (Player players : pl) { + Player o = (Player) players; + if (size >= doses) break; + if (!o.isActive() || o.getLocks().isInteractionLocked() || o == player) { + continue; + } + if (!o.getSettings().isAcceptAid() && !(o instanceof AIPlayer)) { + continue; + } + o.graphics(GRAPHICS); + playGlobalAudio(o.getLocation(), Sounds.LUNAR_STRENGTH_SHARE2_2902); + potion.getEffect().activate(o); + size++; + } + if (size == 0) { + player.getPacketDispatch().sendMessage("There is nobody around that has accept aid on to share the potion with you."); + return false; + } + super.meetsRequirements(player, true, true); + potion.getEffect().activate(player); + playGlobalAudio(player.getLocation(), Sounds.LUNAR_STRENGTH_SHARE_2901); + player.animate(ANIMATION); + player.graphics(GRAPHICS); + player.getInventory().remove(item); + int newIndex = (potion.getIds().length - doses) + size; + if (newIndex > potion.getIds().length - 1) { + player.getInventory().add(new Item(229)); + return true; + } + player.getInventory().add(new Item(potion.getIds()[newIndex])); + return true; + } +} diff --git a/Server/src/main/content/global/skill/magic/lunar/StatRestoreSpell.java b/Server/src/main/content/global/skill/magic/lunar/StatRestoreSpell.java new file mode 100644 index 0000000..1f984d2 --- /dev/null +++ b/Server/src/main/content/global/skill/magic/lunar/StatRestoreSpell.java @@ -0,0 +1,113 @@ +package content.global.skill.magic.lunar; + +import content.data.consumables.Consumables; +import core.game.consumable.Potion; +import core.plugin.Initializable; +import core.game.node.entity.combat.spell.MagicSpell; +import core.game.node.entity.combat.spell.Runes; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.spell.SpellType; +import core.game.node.entity.player.Player; +import core.game.bots.AIPlayer; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.node.item.Item; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Plugin; +import org.rs09.consts.Sounds; + +import java.util.List; + +import static core.api.ContentAPIKt.playGlobalAudio; + +@Initializable +public class StatRestoreSpell extends MagicSpell { + + private static final Animation ANIMATION = new Animation(4413); + private static final Graphics GRAPHICS = new Graphics(733, 130); + private static final Consumables[] acceptedPotions = new Consumables[] { Consumables.RESTORE, Consumables.SUPER_RESTO, Consumables.PRAYER, Consumables.ENERGY, Consumables.SUPER_ENERGY }; + + public StatRestoreSpell() { + super(SpellBook.LUNAR, 81, 84, null, null, null, new Item[] { new Item(Runes.ASTRAL_RUNE.getId(), 2), new Item(Runes.EARTH_RUNE.getId(), 10), new Item(Runes.WATER_RUNE.getId(), 10) }); + } + + @Override + public Plugin newInstance(SpellType arg) throws Throwable { + SpellBook.LUNAR.register(27, this); + return this; + } + + @Override + public boolean cast(Entity entity, Node target) { + final Player player = ((Player) entity); + Item item = ((Item) target); + player.getInterfaceManager().setViewedTab(6); + + if (Consumables.getConsumableById(item.getId()) == null) { + player.getPacketDispatch().sendMessage("You can only cast this spell on a potion."); + return false; + } + + final Potion potion = (Potion) Consumables.getConsumableById(item.getId()).getConsumable(); + + if (potion == null) { + player.getPacketDispatch().sendMessage("You can only cast this spell on a potion."); + return false; + } + if (!item.getDefinition().isTradeable() || !isRestore(potion)) { + player.getPacketDispatch().sendMessage("You can't cast this spell on that item."); + return false; + } + List pl = RegionManager.getLocalPlayers(player, 2); + int plSize = pl.size() - 1; + int doses = potion.getDose(item); + if (pl.size() == 0) { + return false; + } + if (!super.meetsRequirements(player, true, false)) { + return false; + } + int size = 0; + for (Player players : pl) { + if (size >= doses) break; + Player o = (Player) players; + if (!o.isActive() || o.getLocks().isInteractionLocked() || o == player) { + continue; + } + if (!o.getSettings().isAcceptAid() && !(o instanceof AIPlayer)) { + continue; + } + o.graphics(GRAPHICS); + potion.getEffect().activate(o); + size++; + } + if (size == 0) { + player.getPacketDispatch().sendMessage("There is nobody around that has accept aid on to share the potion with you."); + return false; + } + super.meetsRequirements(player, true, true); + potion.getEffect().activate(player); + playGlobalAudio(player.getLocation(), Sounds.LUNAR_STAT_SHARE_2899); + player.animate(ANIMATION); + player.graphics(GRAPHICS); + player.getInventory().remove(item); + int newIndex = (potion.getIds().length - doses) + size; + if (newIndex > potion.getIds().length - 1) { + player.getInventory().add(new Item(229)); + return true; + } + player.getInventory().add(new Item(potion.getIds()[newIndex])); + return true; + } + + private boolean isRestore(Potion p) { + for (int i = 0; i < acceptedPotions.length; i++) { + if (p == acceptedPotions[i].getConsumable()) + return true; + } + return false; + } + +} diff --git a/Server/src/main/content/global/skill/magic/lunar/VengeanceSpell.java b/Server/src/main/content/global/skill/magic/lunar/VengeanceSpell.java new file mode 100644 index 0000000..e068218 --- /dev/null +++ b/Server/src/main/content/global/skill/magic/lunar/VengeanceSpell.java @@ -0,0 +1,92 @@ +package content.global.skill.magic.lunar; + +import core.game.node.entity.combat.spell.MagicSpell; +import core.game.node.entity.combat.spell.Runes; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.spell.SpellType; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.node.item.Item; +import core.game.world.GameWorld; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.plugin.Plugin; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playAudio; +import static core.api.ContentAPIKt.playGlobalAudio; + +/** + * Handles the vengeance (other) spell. + * @author Emperor + */ +@Initializable +public final class VengeanceSpell extends MagicSpell { + + /** + * Constructs a new {@code VengeanceSpell} {@code Object}. + */ + public VengeanceSpell() { + /* + * empty. + */ + } + + /** + * Constructs a new {@code VengeanceSpell} {@code Object}. + * @param level The level required. + * @param experience The experience gained from casting this spell. + * @param anim The cast animation. + * @param graphic The graphics. + * @param runes The runes required. + */ + public VengeanceSpell(int level, double experience, Animation anim, Graphics graphic, Item... runes) { + super(SpellBook.LUNAR, level, experience, anim, graphic, null, runes); + } + + @Override + public Plugin newInstance(SpellType arg) throws Throwable { + // Vengeance other + SpellBook.LUNAR.register(19, new VengeanceSpell(93, 78, Animation.create(4411), new Graphics(725, 96), Runes.ASTRAL_RUNE.getItem(3), Runes.DEATH_RUNE.getItem(2), Runes.EARTH_RUNE.getItem(10))); + // Vengeance + SpellBook.LUNAR.register(14, new VengeanceSpell(94, 112, Animation.create(4410), new Graphics(726, 96), Runes.ASTRAL_RUNE.getItem(4), Runes.DEATH_RUNE.getItem(2), Runes.EARTH_RUNE.getItem(10))); + return this; + } + + @Override + public void visualize(Entity entity, Node target) { + entity.animate(animation); + ((Entity) target).graphics(graphic); + } + + @Override + public boolean cast(Entity entity, Node target) { + int ticks = GameWorld.getTicks(); + boolean vengOther = spellId == 19; + if (entity.getAttribute("vengeance_delay", -1) > ticks) { + ((Player) entity).getPacketDispatch().sendMessage("You can only cast vengeance spells once every 30 seconds."); + return false; + } + if (vengOther && (target == null || !(target instanceof Player))) { + return false; + } + Player p = (Player) (vengOther ? target : entity); + if (vengOther) { + if (!p.getSettings().isAcceptAid()) { + ((Player) entity).getPacketDispatch().sendMessage("The player is not accepting any aid."); + return false; + } + } + if (!meetsRequirements(entity, true, true)) { + return false; + } + visualize(entity, p); + entity.setAttribute("vengeance_delay", ticks + 50); + p.setAttribute("vengeance", true); + playGlobalAudio(p.getLocation(), vengOther ? Sounds.LUNAR_VENGENCE_OTHER_2908 : Sounds.LUNAR_VENGENCE_2907); + return true; + } + +} diff --git a/Server/src/main/content/global/skill/magic/modern/AirSpell.java b/Server/src/main/content/global/skill/magic/modern/AirSpell.java new file mode 100644 index 0000000..07cfcf1 --- /dev/null +++ b/Server/src/main/content/global/skill/magic/modern/AirSpell.java @@ -0,0 +1,127 @@ +package content.global.skill.magic.modern; + +import core.plugin.Initializable; +import core.game.node.entity.combat.spell.Runes; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.spell.CombatSpell; +import core.game.node.entity.combat.spell.SpellType; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Plugin; +import org.rs09.consts.Sounds; + +/** + * Represents the combat spell plugin used to handle air spells. + * @author Emperor + * @version 1.0 + */ +@Initializable +public final class AirSpell extends CombatSpell { + + /** + * The start graphic for Air strike. + */ + private static final Graphics STRIKE_START = new Graphics(90, 96); + + /** + * The projectile for Air strike. + */ + private static final Projectile STRIKE_PROJECTILE = Projectile.create((Entity) null, null, 91, 40, 36, 52, 75, 15, 11); + + /** + * The end graphic for Air strike. + */ + private static final Graphics STRIKE_END = new Graphics(92, 96); + + /** + * The start graphic for Air bolt. + */ + private static final Graphics BOLT_START = new Graphics(117, 96); + + /** + * The projectile for Air bolt. + */ + private static final Projectile BOLT_PROJECTILE = Projectile.create((Entity) null, null, 118, 40, 36, 52, 75, 15, 11); + + /** + * The end graphic for Air bolt. + */ + private static final Graphics BOLT_END = new Graphics(119, 96); + + /** + * The start graphic for Air blast. + */ + private static final Graphics BLAST_START = new Graphics(132, 96); // 129 + + /** + * The projectile for Air blast. + */ + private static final Projectile BLAST_PROJECTILE = Projectile.create((Entity) null, null, 133, 40, 36, 52, 75, 15, 11); // 130 + + /** + * The end graphic for Air blast. + */ + private static final Graphics BLAST_END = new Graphics(134, 96); // 131 + + /** + * The start graphic for Air wave. + */ + private static final Graphics WAVE_START = new Graphics(158, 96); + + /** + * The projectile for Air wave. + */ + private static final Projectile WAVE_PROJECTILE = Projectile.create((Entity) null, null, 159, 40, 36, 52, 75, 15, 11); + + /** + * The end graphic for Air wave. + */ + private static final Graphics WAVE_END = new Graphics(160, 96); + + /** + * The cast animation. + */ + private static final Animation ANIMATION = new Animation(711, Priority.HIGH); + + /** + * Constructs a new {@code AirSpell} {@Code Object} + */ + public AirSpell() { + /* + * empty. + */ + } + + /** + * Constructs a new {@code AirSpell} {@Code Object} + * @param type The spell type. + * @param level The level requirement. + * @param sound The cast sound. + * @param start The start graphics. + * @param projectile The projectile. + * @param end The end graphics. + * @param runes The rune requirements. + */ + private AirSpell(SpellType type, int level, double baseExperience, int sound, Graphics start, Projectile projectile, Graphics end, Item... runes) { + super(type, SpellBook.MODERN, level, baseExperience, sound, sound + 1, ANIMATION, start, projectile, end, runes); + } + + @Override + public int getMaximumImpact(Entity entity, Entity victim, BattleState state) { + return getType().getImpactAmount(entity, victim, 1); + } + + @Override + public Plugin newInstance(SpellType type) throws Throwable { + SpellBook.MODERN.register(1, new AirSpell(SpellType.STRIKE, 1, 5.5, Sounds.WINDSTRIKE_CAST_AND_FIRE_220, STRIKE_START, STRIKE_PROJECTILE, STRIKE_END, Runes.MIND_RUNE.getItem(1), Runes.AIR_RUNE.getItem(1))); + SpellBook.MODERN.register(10, new AirSpell(SpellType.BOLT, 17, 13.5, Sounds.WINDBOLT_CAST_AND_FIRE_218, BOLT_START, BOLT_PROJECTILE, BOLT_END, Runes.CHAOS_RUNE.getItem(1), Runes.AIR_RUNE.getItem(2))); + SpellBook.MODERN.register(24, new AirSpell(SpellType.BLAST, 41, 25.5, Sounds.WINDBLAST_CAST_AND_FIRE_216, BLAST_START, BLAST_PROJECTILE, BLAST_END, Runes.DEATH_RUNE.getItem(1), Runes.AIR_RUNE.getItem(3))); + SpellBook.MODERN.register(45, new AirSpell(SpellType.WAVE, 62, 36.0, Sounds.WINDWAVE_CAST_AND_FIRE_222, WAVE_START, WAVE_PROJECTILE, WAVE_END, Runes.BLOOD_RUNE.getItem(1), Runes.AIR_RUNE.getItem(5))); + return this; + } +} diff --git a/Server/src/main/content/global/skill/magic/modern/BindSpell.java b/Server/src/main/content/global/skill/magic/modern/BindSpell.java new file mode 100644 index 0000000..83352a1 --- /dev/null +++ b/Server/src/main/content/global/skill/magic/modern/BindSpell.java @@ -0,0 +1,147 @@ +package content.global.skill.magic.modern; + +import core.plugin.Initializable; +import core.game.node.entity.combat.spell.Runes; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.spell.CombatSpell; +import core.game.node.entity.combat.spell.SpellType; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.node.item.Item; +import core.game.world.GameWorld; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Plugin; +import org.rs09.consts.Sounds; + +/** + * Represents the binding combat spell. + * @author 'Vexia + * @author Emperor + * @version 1.0 + */ +@Initializable +public final class BindSpell extends CombatSpell { + + /** + * The start graphic for Earth strike. + */ + private static final Graphics BIND_START = new Graphics(177, 96); + + /** + * The projectile for Earth strike. + */ + private static final Projectile BIND_PROJECTILE = Projectile.create((Entity) null, null, 178, 40, 36, 52, 75, 15, 11); + + /** + * The end graphic for Earth strike. + */ + private static final Graphics BIND_END = new Graphics(181, 96); + + /** + * The start graphic for Earth strike. + */ + private static final Graphics SNARE_START = new Graphics(177, 96); + + /** + * The projectile for Earth strike. + */ + private static final Projectile SNARE_PROJECTILE = Projectile.create((Entity) null, null, 178, 40, 36, 52, 75, 15, 11); + + /** + * The end graphic for Earth strike. + */ + private static final Graphics SNARE_END = new Graphics(180, 96); + + /** + * The start graphic for Earth strike. + */ + private static final Graphics ENTANGLE_START = new Graphics(177, 96); + + /** + * The projectile for Earth strike. + */ + private static final Projectile ENTANGLE_PROJECTILE = Projectile.create((Entity) null, null, 178, 40, 36, 52, 75, 15, 11); + + /** + * The end graphic for Earth strike. + */ + private static final Graphics ENTANGLE_END = new Graphics(179, 96); + + /** + * The cast animation. + */ + private static final Animation ANIMATION = new Animation(710, Priority.HIGH); + + /** + * Constructs a new {@code BindSpell} {@Code Object} + */ + public BindSpell() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code BindSpell} {@code Object}. + * @param type the type. + * @param level the level. + * @param sound the sound. + * @param start the start. + * @param projectile the projectile. + * @param end the end. + * @param runes the runes. + */ + private BindSpell(SpellType type, int level, double baseExperience, int sound, int impactAudio, Graphics start, Projectile projectile, Graphics end, Item... runes) { + super(type, SpellBook.MODERN, level, baseExperience, sound, impactAudio, ANIMATION, start, projectile, end, runes); + } + + @Override + public void fireEffect(Entity entity, Entity victim, BattleState state) { + if (victim instanceof NPC) { + NPC npc = (NPC) victim; + if (npc.getName().contains("impling")) { + state.setEstimatedHit(-2); + } + } + if (state.getEstimatedHit() == -1) { + return; + } + int tick = 9; + if (getType() == SpellType.BIND) { + state.setEstimatedHit(-2); + } + if (state.getSpell().getSpellId() == 30) { + tick = 17; + } else if (state.getSpell().getSpellId() == 56) { + tick = 25; + } + if (!victim.getLocks().isMovementLocked() && victim instanceof Player) { + ((Player) victim).getPacketDispatch().sendMessage("A magical force stops you from moving!"); + } + victim.getWalkingQueue().reset(); + victim.getLocks().lockMovement(tick); + entity.setAttribute("entangleDelay", GameWorld.getTicks() + tick + 2); + } + + @Override + public int getMaximumImpact(Entity entity, Entity victim, BattleState state) { + return getType() == SpellType.ENTANGLE ? 5 : 3; + } + + @Override + public Plugin newInstance(SpellType type) throws Throwable { + // TODO: bind/snare/entangle have separate casting and onhit components + // to their sound effects, in order for splashes to sound distinct, currently + // these just sound like the spells should on success, even if they splash + SpellBook.MODERN.register(12, new BindSpell(SpellType.BIND, 20, 30.0, Sounds.BIND_CAST_101, Sounds.BIND_IMPACT_99, BIND_START, BIND_PROJECTILE, BIND_END, Runes.NATURE_RUNE.getItem(2), Runes.EARTH_RUNE.getItem(3), Runes.WATER_RUNE.getItem(3))); + SpellBook.MODERN.register(30, new BindSpell(SpellType.SNARE, 50, 60.0, Sounds.SNARE_CAST_AND_FIRE_3003, Sounds.SNARE_IMPACT_3002, SNARE_START, SNARE_PROJECTILE, SNARE_END, Runes.NATURE_RUNE.getItem(3), Runes.EARTH_RUNE.getItem(4), Runes.WATER_RUNE.getItem(4))); + SpellBook.MODERN.register(56, new BindSpell(SpellType.ENTANGLE, 79, 89.0, Sounds.ENTANGLE_CAST_AND_FIRE_151, Sounds.ENTANGLE_HIT_153, ENTANGLE_START, ENTANGLE_PROJECTILE, ENTANGLE_END, Runes.NATURE_RUNE.getItem(4), Runes.EARTH_RUNE.getItem(5), Runes.WATER_RUNE.getItem(5))); + return this; + } + +} diff --git a/Server/src/main/content/global/skill/magic/modern/ChargeSpell.java b/Server/src/main/content/global/skill/magic/modern/ChargeSpell.java new file mode 100644 index 0000000..4aa2b1c --- /dev/null +++ b/Server/src/main/content/global/skill/magic/modern/ChargeSpell.java @@ -0,0 +1,60 @@ +package content.global.skill.magic.modern; + +import core.game.node.entity.combat.spell.Runes; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.spell.SpellType; +import core.game.node.entity.combat.spell.MagicSpell; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.audio.Audio; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.plugin.Plugin; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.*; + +/** + * Represents the charge spell magic spell. + * @author Emperor + * @version 1.0 + */ +@Initializable +public final class ChargeSpell extends MagicSpell { + + /** + * Constructs a new {@code ChargeSpell} {@code Object}. + */ + public ChargeSpell() { + super(SpellBook.MODERN, 80, 180, Animation.create(811), new Graphics(6, 96), new Audio(Sounds.CHARGE_1651), new Item[] { Runes.FIRE_RUNE.getItem(3), Runes.BLOOD_RUNE.getItem(3), Runes.AIR_RUNE.getItem(3) }); + } + + @Override + public Plugin newInstance(SpellType arg) throws Throwable { + SpellBook.MODERN.register(58, this); + return this; + } + + @Override + public boolean cast(Entity entity, Node target) { + final Player p = (Player) entity; + if (p.getLocks().isLocked("charge_cast")) { + p.getPacketDispatch().sendMessage("You need to wait for the spell to recharge."); + return false; + } + if (!meetsRequirements(entity, true, true)) { + return false; + } + p.getLocks().lock("charge_cast", 100); + visualize(entity, target); + // Remove the previous copy of the state in order to refresh the duration if recast before 7 minutes + removeTimer (p, "magic:spellcharge"); + registerTimer (p, spawnTimer("magic:spellcharge")); + p.getPacketDispatch().sendMessage("You feel charged with magic power."); + return true; + } + +} diff --git a/Server/src/main/content/global/skill/magic/modern/CrumbleUndead.java b/Server/src/main/content/global/skill/magic/modern/CrumbleUndead.java new file mode 100644 index 0000000..ec23e25 --- /dev/null +++ b/Server/src/main/content/global/skill/magic/modern/CrumbleUndead.java @@ -0,0 +1,56 @@ +package content.global.skill.magic.modern; + +import core.game.node.entity.combat.spell.Runes; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.spell.CombatSpell; +import core.game.node.entity.combat.spell.SpellType; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.plugin.Plugin; +import org.rs09.consts.Sounds; + +/** + * Handles the crumble undead spell. + * @author Emperor + * @version 1.0 + */ +@Initializable +public final class CrumbleUndead extends CombatSpell { + + /** + * Constructs a new {@code CrumbleUndead} {@code Object}. + */ + public CrumbleUndead() { + super(SpellType.CRUMBLE_UNDEAD, SpellBook.MODERN, 39, 24.5, Sounds.CRUMBLE_CAST_AND_FIRE_122, Sounds.CRUMBLE_HIT_124, new Animation(724, Priority.HIGH), new Graphics(145, 96), Projectile.create((Entity) null, null, 146, 40, 36, 52, 75, 15, 11), new Graphics(147, 96), Runes.EARTH_RUNE.getItem(2), Runes.AIR_RUNE.getItem(2), Runes.CHAOS_RUNE.getItem(1)); + } + + @Override + public boolean cast(Entity entity, Node target) { + NPC npc = target instanceof NPC ? (NPC) target : null; + if (npc == null || npc.getTask() == null || !npc.getTask().undead) { + ((Player) entity).getPacketDispatch().sendMessage("This spell only affects the undead."); + return false; + } + return super.cast(entity, target); + } + + @Override + public Plugin newInstance(SpellType arg) throws Throwable { + SpellBook.MODERN.register(22, this); + return this; + } + + @Override + public int getMaximumImpact(Entity entity, Entity victim, BattleState state) { + return type.getImpactAmount(entity, victim, 0); + } + +} diff --git a/Server/src/main/content/global/skill/magic/modern/CurseSpells.java b/Server/src/main/content/global/skill/magic/modern/CurseSpells.java new file mode 100644 index 0000000..6b76c04 --- /dev/null +++ b/Server/src/main/content/global/skill/magic/modern/CurseSpells.java @@ -0,0 +1,201 @@ +package content.global.skill.magic.modern; + +import core.game.node.entity.skill.Skills; +import core.game.node.entity.combat.spell.Runes; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.spell.CombatSpell; +import core.game.node.entity.combat.spell.SpellType; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.plugin.Plugin; +import org.rs09.consts.Sounds; + +/** + * Represents the curse spells. + * @author Emperor + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class CurseSpells extends CombatSpell { + + /** + * The start graphic for Earth strike. + */ + private static final Graphics CONFUSE_START = new Graphics(102, 96); + + /** + * The projectile for Earth strike. + */ + private static final Projectile CONFUSE_PROJECTILE = Projectile.create((Entity) null, null, 103, 40, 36, 52, 75, 15, 11); + + /** + * The end graphic for Earth strike. + */ + private static final Graphics CONFUSE_END = new Graphics(104, 96); + + /** + * The start graphic for Earth strike. + */ + private static final Graphics WEAKEN_START = new Graphics(105, 96); + + /** + * The projectile for Earth strike. + */ + private static final Projectile WEAKEN_PROJECTILE = Projectile.create((Entity) null, null, 106, 40, 36, 52, 75, 15, 11); + + /** + * The end graphic for Earth strike. + */ + private static final Graphics WEAKEN_END = new Graphics(107, 96); + + /** + * The start graphic for Earth strike. + */ + private static final Graphics CURSE_START = new Graphics(108, 96); + + /** + * The projectile for Earth strike. + */ + private static final Projectile CURSE_PROJECTILE = Projectile.create((Entity) null, null, 109, 40, 36, 52, 75, 15, 11); + + /** + * The end graphic for Earth strike. + */ + private static final Graphics CURSE_END = new Graphics(110, 96); + + /** + * The start graphic for Earth strike. + */ + private static final Graphics VULNER_START = new Graphics(167, 96); + + /** + * The projectile for Earth strike. + */ + private static final Projectile VULNER_PROJECTILE = Projectile.create((Entity) null, null, 168, 40, 36, 52, 75, 15, 11); + + /** + * The end graphic for Earth strike. + */ + private static final Graphics VULNER_END = new Graphics(169, 96); + + /** + * The start graphic for Earth strike. + */ + private static final Graphics ENFEEBLE_START = new Graphics(170, 96); + + /** + * The projectile for Earth strike. + */ + private static final Projectile ENFEEBLE_PROJECTILE = Projectile.create((Entity) null, null, 171, 40, 36, 52, 75, 15, 11); + + /** + * The end graphic for Earth strike. + */ + private static final Graphics ENFEEBLE_END = new Graphics(172, 96); + + /** + * The start graphic for Earth strike. + */ + private static final Graphics STUN_START = new Graphics(173, 96); + + /** + * The projectile for Earth strike. + */ + private static final Projectile STUN_PROJECTILE = Projectile.create((Entity) null, null, 174, 40, 36, 52, 75, 15, 11); + + /** + * The end graphic for Earth strike. + */ + private static final Graphics STUN_END = new Graphics(107, 96); + + /** + * The cast animation. + */ + private static final Animation LOW_ANIMATION = new Animation(716, Priority.HIGH); + + /** + * The cast animation. + */ + private static final Animation HIGH_ANIMATION = new Animation(729, Priority.HIGH); + + /** + * Constructs a new {@code EarthSpell} {@Code Object} + */ + public CurseSpells() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code CurseSpells} {@code Object}. + * @param type the type. + * @param level the level. + * @param sound the sound. + * @param start the start. + * @param projectile the projectile. + * @param end the end. + * @param runes the runes. + */ + private CurseSpells(SpellType type, int level, double baseExperience, int sound, int impactAudio, Graphics start, Projectile projectile, Graphics end, Item... runes) { + super(type, SpellBook.MODERN, level, baseExperience, sound, impactAudio, type.ordinal() <= SpellType.CURSE.ordinal() ? LOW_ANIMATION : HIGH_ANIMATION, start, projectile, end, runes); + } + + @Override + public int getMaximumImpact(Entity entity, Entity victim, BattleState state) { + return 1; + } + + @Override + public void fireEffect(Entity entity, Entity victim, BattleState state) { + if (state.getEstimatedHit() == -1) { + return; + } + state.setEstimatedHit(-2); + switch (getType()) { + case CONFUSE: + victim.getSkills().drainLevel(Skills.ATTACK, 0.05, 0.05); + break; + case WEAKEN: + victim.getSkills().drainLevel(Skills.STRENGTH, 0.05, 0.05); + break; + case CURSE: + victim.getSkills().drainLevel(Skills.DEFENCE, 0.05, 0.05); + break; + case VULNERABILITY: + victim.getSkills().drainLevel(Skills.DEFENCE, 0.10, 0.10); + break; + case ENFEEBLE: + victim.getSkills().drainLevel(Skills.STRENGTH, 0.10, 0.10); + break; + case STUN: + victim.getSkills().drainLevel(Skills.ATTACK, 0.10, 0.10); + break; + default: + } + } + + @Override + public void addExperience(Entity entity, int hit) { + entity.getSkills().addExperience(Skills.MAGIC, getExperience()); + } + + @Override + public Plugin newInstance(SpellType type) throws Throwable { + SpellBook.MODERN.register(2, new CurseSpells(SpellType.CONFUSE, 3, 13.0, Sounds.CONFUSE_CAST_AND_FIRE_119, Sounds.CONFUSE_HIT_121, CONFUSE_START, CONFUSE_PROJECTILE, CONFUSE_END, Runes.BODY_RUNE.getItem(1), Runes.EARTH_RUNE.getItem(2), Runes.WATER_RUNE.getItem(3))); + SpellBook.MODERN.register(7, new CurseSpells(SpellType.WEAKEN, 11, 21.0, Sounds.WEAKEN_CAST_AND_FIRE_3011, Sounds.WEAKEN_HIT_3010, WEAKEN_START, WEAKEN_PROJECTILE, WEAKEN_END, Runes.BODY_RUNE.getItem(1), Runes.EARTH_RUNE.getItem(2), Runes.WATER_RUNE.getItem(3))); + SpellBook.MODERN.register(11, new CurseSpells(SpellType.CURSE, 19, 29.0, Sounds.CURSE_CAST_AND_FIRE_127, Sounds.CURSE_HIT_126, CURSE_START, CURSE_PROJECTILE, CURSE_END, Runes.BODY_RUNE.getItem(1), Runes.EARTH_RUNE.getItem(3), Runes.WATER_RUNE.getItem(2))); + SpellBook.MODERN.register(50, new CurseSpells(SpellType.VULNERABILITY, 66, 76.0, Sounds.VULNERABILITY_CAST_AND_FIRE_3009, Sounds.VULNERABILITY_IMPACT_3008, VULNER_START, VULNER_PROJECTILE, VULNER_END, Runes.SOUL_RUNE.getItem(1), Runes.EARTH_RUNE.getItem(5), Runes.WATER_RUNE.getItem(5))); + SpellBook.MODERN.register(53, new CurseSpells(SpellType.ENFEEBLE, 73, 83.0, Sounds.ENFEEBLE_CAST_AND_FIRE_148, Sounds.ENFEEBLE_HIT_150, ENFEEBLE_START, ENFEEBLE_PROJECTILE, ENFEEBLE_END, Runes.SOUL_RUNE.getItem(1), Runes.EARTH_RUNE.getItem(8), Runes.WATER_RUNE.getItem(8))); + SpellBook.MODERN.register(57, new CurseSpells(SpellType.STUN, 80, 90.0, Sounds.STUN_CAST_AND_FIRE_3004, Sounds.STUN_IMPACT_3005, STUN_START, STUN_PROJECTILE, STUN_END, Runes.SOUL_RUNE.getItem(1), Runes.EARTH_RUNE.getItem(12), Runes.WATER_RUNE.getItem(12))); + return this; + } + +} diff --git a/Server/src/main/content/global/skill/magic/modern/EarthSpell.java b/Server/src/main/content/global/skill/magic/modern/EarthSpell.java new file mode 100644 index 0000000..3da9d50 --- /dev/null +++ b/Server/src/main/content/global/skill/magic/modern/EarthSpell.java @@ -0,0 +1,128 @@ +package content.global.skill.magic.modern; + +import core.game.node.entity.combat.spell.Runes; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.spell.CombatSpell; +import core.game.node.entity.combat.spell.SpellType; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.plugin.Plugin; +import org.rs09.consts.Sounds; + +/** + * Represents the earth combat spells. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class EarthSpell extends CombatSpell { + + /** + * The start graphic for Earth strike. + */ + private static final Graphics STRIKE_START = new Graphics(96, 96); + + /** + * The projectile for Earth strike. + */ + private static final Projectile STRIKE_PROJECTILE = Projectile.create((Entity) null, null, 97, 40, 36, 52, 75, 15, 11); + + /** + * The end graphic for Earth strike. + */ + private static final Graphics STRIKE_END = new Graphics(98, 96); + + /** + * The start graphic for Earth bolt. + */ + private static final Graphics BOLT_START = new Graphics(123, 96); + + /** + * The projectile for Earth bolt. + */ + private static final Projectile BOLT_PROJECTILE = Projectile.create((Entity) null, null, 124, 40, 36, 52, 75, 15, 11); + + /** + * The end graphic for Earth bolt. + */ + private static final Graphics BOLT_END = new Graphics(125, 96); + + /** + * The start graphic for Earth blast. + */ + private static final Graphics BLAST_START = new Graphics(138, 96); + + /** + * The projectile for Earth blast. + */ + private static final Projectile BLAST_PROJECTILE = Projectile.create((Entity) null, null, 139, 40, 36, 52, 75, 15, 11); + + /** + * The end graphic for Earth blast. + */ + private static final Graphics BLAST_END = new Graphics(140, 96); + + /** + * The start graphic for Earth wave. + */ + private static final Graphics WAVE_START = new Graphics(164, 96); + + /** + * The projectile for Earth wave. + */ + private static final Projectile WAVE_PROJECTILE = Projectile.create((Entity) null, null, 165, 40, 36, 52, 75, 15, 11); + + /** + * The end graphic for Earth wave. + */ + private static final Graphics WAVE_END = new Graphics(166, 96); + + /** + * The cast animation. + */ + private static final Animation ANIMATION = new Animation(711, Priority.HIGH); + + /** + * Constructs a new {@code EarthSpell} {@Code Object} + */ + public EarthSpell() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code EarthSpell} {@Code Object}. + * @param type The spell type. + * @param level The level requirement. + * @param sound The cast sound. + * @param start The start graphics. + * @param projectile The projectile. + * @param end The end graphics. + * @param runes The rune requirements. + */ + private EarthSpell(SpellType type, int level, double baseExperience, int sound, Graphics start, Projectile projectile, Graphics end, Item... runes) { + super(type, SpellBook.MODERN, level, baseExperience, sound, sound + 1, ANIMATION, start, projectile, end, runes); + } + + @Override + public int getMaximumImpact(Entity entity, Entity victim, BattleState state) { + return getType().getImpactAmount(entity, victim, 3); + } + + @Override + public Plugin newInstance(SpellType type) throws Throwable { + SpellBook.MODERN.register(6, new EarthSpell(SpellType.STRIKE, 9, 9.5, Sounds.EARTHSTRIKE_CAST_AND_FIRE_132, STRIKE_START, STRIKE_PROJECTILE, STRIKE_END, Runes.MIND_RUNE.getItem(1), Runes.EARTH_RUNE.getItem(2), Runes.AIR_RUNE.getItem(1))); + SpellBook.MODERN.register(17, new EarthSpell(SpellType.BOLT, 29, 19.5, Sounds.EARTHBOLT_CAST_AND_FIRE_130, BOLT_START, BOLT_PROJECTILE, BOLT_END, Runes.CHAOS_RUNE.getItem(1), Runes.EARTH_RUNE.getItem(3), Runes.AIR_RUNE.getItem(2))); + SpellBook.MODERN.register(33, new EarthSpell(SpellType.BLAST, 53, 31.5, Sounds.EARTHBLAST_CAST_AND_FIRE_128, BLAST_START, BLAST_PROJECTILE, BLAST_END, Runes.DEATH_RUNE.getItem(1), Runes.EARTH_RUNE.getItem(4), Runes.AIR_RUNE.getItem(3))); + SpellBook.MODERN.register(52, new EarthSpell(SpellType.WAVE, 70, 40.0, Sounds.EARTHWAVE_CAST_AND_FIRE_134, WAVE_START, WAVE_PROJECTILE, WAVE_END, Runes.BLOOD_RUNE.getItem(1), Runes.EARTH_RUNE.getItem(7), Runes.AIR_RUNE.getItem(5))); + return this; + } + +} diff --git a/Server/src/main/content/global/skill/magic/modern/EnchantCrossbowSpell.java b/Server/src/main/content/global/skill/magic/modern/EnchantCrossbowSpell.java new file mode 100644 index 0000000..c5ad348 --- /dev/null +++ b/Server/src/main/content/global/skill/magic/modern/EnchantCrossbowSpell.java @@ -0,0 +1,45 @@ +package content.global.skill.magic.modern; + +import core.game.component.Component; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.spell.SpellType; +import core.game.node.entity.combat.spell.MagicSpell; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the enchant crossbow spell. + * @author 'Vexia. + * @version 1.0 + */ +@Initializable +public final class EnchantCrossbowSpell extends MagicSpell { + + /** + * Constructs a new {@code EnchantCrossbowSpell} {@code Object}. + */ + public EnchantCrossbowSpell() { + super(SpellBook.MODERN, 4, 0, null, null, null, null); + } + + @Override + public Plugin newInstance(SpellType arg) throws Throwable { + SpellBook.MODERN.register(3, this); + return null; + } + + @Override + public boolean cast(Entity entity, Node target) { + final Player player = ((Player) entity); + player.getInterfaceManager().open(new Component(432)); + int[][] data = new int[][] { { 17, 879 }, { 21, 9335 }, { 25, 880 }, { 28, 9336 }, { 31, 9337 }, { 34, 9338 }, { 37, 9339 }, { 40, 9340 }, { 43, 9341 }, { 46, 9342 } }; + for (int i = 0; i < data.length; i++) { + player.getPacketDispatch().sendItemZoomOnInterface(data[i][1], 10, 270, 432, data[i][0]); + } + return true; + } + +} diff --git a/Server/src/main/content/global/skill/magic/modern/FireSpell.java b/Server/src/main/content/global/skill/magic/modern/FireSpell.java new file mode 100644 index 0000000..7feb995 --- /dev/null +++ b/Server/src/main/content/global/skill/magic/modern/FireSpell.java @@ -0,0 +1,129 @@ +package content.global.skill.magic.modern; + +import core.game.node.entity.combat.spell.Runes; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.spell.CombatSpell; +import core.game.node.entity.combat.spell.SpellType; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.plugin.Plugin; +import org.rs09.consts.Sounds; + +/** + * Handles the fire spells. + * @author Emperor + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class FireSpell extends CombatSpell { + + /** + * The start graphic for Fire strike. + */ + private static final Graphics STRIKE_START = new Graphics(99, 96); + + /** + * The projectile for Fire strike. + */ + private static final Projectile STRIKE_PROJECTILE = Projectile.create((Entity) null, null, 100, 40, 36, 52, 75, 15, 11); + + /** + * The end graphic for Fire strike. + */ + private static final Graphics STRIKE_END = new Graphics(101, 96); + + /** + * The start graphic for Fire bolt. + */ + private static final Graphics BOLT_START = new Graphics(126, 96); + + /** + * The projectile for Fire bolt. + */ + private static final Projectile BOLT_PROJECTILE = Projectile.create((Entity) null, null, 127, 40, 36, 52, 75, 15, 11); + + /** + * The end graphic for Fire bolt. + */ + private static final Graphics BOLT_END = new Graphics(128, 96); + + /** + * The start graphic for Fire blast. + */ + private static final Graphics BLAST_START = new Graphics(129, 96); + + /** + * The projectile for Fire blast. + */ + private static final Projectile BLAST_PROJECTILE = Projectile.create((Entity) null, null, 130, 40, 36, 52, 75, 15, 11); + + /** + * The end graphic for Fire blast. + */ + private static final Graphics BLAST_END = new Graphics(131, 96); + + /** + * The start graphic for Fire wave. + */ + private static final Graphics WAVE_START = new Graphics(155, 96); + + /** + * The projectile for Fire wave. + */ + private static final Projectile WAVE_PROJECTILE = Projectile.create((Entity) null, null, 156, 40, 36, 52, 75, 15, 11); + + /** + * The end graphic for Fire wave. + */ + private static final Graphics WAVE_END = new Graphics(157, 96); + + /** + * The cast animation. + */ + private static final Animation ANIMATION = new Animation(711, Priority.HIGH); + + /** + * Constructs a new {@code FireSpell} {@Code Object} + */ + public FireSpell() { + /* + * empty. + */ + } + + /** + * Constructs a new {@code FireSpell} {@code Object}. + * @param type The spell type. + * @param level The level requirement. + * @param sound The cast sound. + * @param start The start graphics. + * @param projectile The projectile. + * @param end The end graphics. + * @param runes The rune requirements. + */ + private FireSpell(SpellType type, int level, double baseExperience, int sound, Graphics start, Projectile projectile, Graphics end, Item... runes) { + super(type, SpellBook.MODERN, level, baseExperience, sound, sound + 1, ANIMATION, start, projectile, end, runes); + } + + @Override + public int getMaximumImpact(Entity entity, Entity victim, BattleState state) { + return getType().getImpactAmount(entity, victim, 4); + } + + @Override + public Plugin newInstance(SpellType type) throws Throwable { + SpellBook.MODERN.register(8, new FireSpell(SpellType.STRIKE, 13, 11.5, Sounds.FIRESTRIKE_CAST_AND_FIRE_160, STRIKE_START, STRIKE_PROJECTILE, STRIKE_END, Runes.MIND_RUNE.getItem(1), Runes.FIRE_RUNE.getItem(3), Runes.AIR_RUNE.getItem(2))); + SpellBook.MODERN.register(20, new FireSpell(SpellType.BOLT, 35, 22.5, Sounds.FIREBOLT_CAST_AND_FIRE_157, BOLT_START, BOLT_PROJECTILE, BOLT_END, Runes.CHAOS_RUNE.getItem(1), Runes.FIRE_RUNE.getItem(4), Runes.AIR_RUNE.getItem(3))); + SpellBook.MODERN.register(38, new FireSpell(SpellType.BLAST, 59, 34.5, Sounds.FIREBLAST_CAST_AND_FIRE_155, BLAST_START, BLAST_PROJECTILE, BLAST_END, Runes.DEATH_RUNE.getItem(1), Runes.FIRE_RUNE.getItem(5), Runes.AIR_RUNE.getItem(4))); + SpellBook.MODERN.register(55, new FireSpell(SpellType.WAVE, 75, 42.5, Sounds.FIREWAVE_CAST_AND_FIRE_162, WAVE_START, WAVE_PROJECTILE, WAVE_END, Runes.BLOOD_RUNE.getItem(1), Runes.FIRE_RUNE.getItem(7), Runes.AIR_RUNE.getItem(5))); + return this; + } + +} diff --git a/Server/src/main/content/global/skill/magic/modern/GodSpells.java b/Server/src/main/content/global/skill/magic/modern/GodSpells.java new file mode 100644 index 0000000..8b492fd --- /dev/null +++ b/Server/src/main/content/global/skill/magic/modern/GodSpells.java @@ -0,0 +1,224 @@ +package content.global.skill.magic.modern; + +import core.cache.def.impl.ItemDefinition; +import core.game.container.impl.EquipmentContainer; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.spell.CombatSpell; +import core.game.node.entity.combat.spell.Runes; +import core.game.node.entity.combat.spell.SpellType; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.node.entity.skill.Skills; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.plugin.Plugin; +import org.rs09.consts.Items; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.*; + +/** + * Handles the god spells. + * @author Emperor + * @author 'Vexia + */ +@Initializable +public final class GodSpells extends CombatSpell { + + /** + * The spell names. + */ + private static final String[] NAMES = new String[] { "Saradomin strike", "Guthix claws", "Flames of Zamorak" }; + private static final int[] GOD_STAVES = new int[] { Items.SARADOMIN_STAFF_2415, Items.GUTHIX_STAFF_2416, Items.ZAMORAK_STAFF_2417 }; + + /** + * The start graphic for Air strike. + */ + private static final Graphics SARA_START = null; + + /** + * The projectile for Air strike. + */ + private static final Projectile SARA_PROJECTILE = null; + + /** + * The end graphic for Air strike. + */ + private static final Graphics SARA_END = new Graphics(76, 0); + + /** + * The start graphic for Air strike. + */ + private static final Graphics GUTHIX_START = null; + + /** + * The projectile for Air strike. + */ + private static final Projectile GUTHIX_PROJECTILE = null; + + /** + * The end graphic for Air strike. + */ + private static final Graphics GUTHIX_END = new Graphics(77, 0); + + /** + * The start graphic for Air strike. + */ + private static final Graphics ZAM_START = null; + + /** + * The projectile for Air strike. + */ + private static final Projectile ZAM_PROJECTILE = null; + + /** + * The end graphic for Air strike. + */ + private static final Graphics ZAM_END = new Graphics(78, 0); + + /** + * The cast animation. + */ + private static final Animation ANIMATION = new Animation(811, Priority.HIGH); + + /** + * Constructs a new {@code AirSpell} {@Code Object} + */ + public GodSpells() { + /* + * empty. + */ + } + + /** + * Constructs a new {@code GodSpells} {@code Object}. + * @param type the type. + * @param sound the sound. + * @param start the start. + * @param projectile the projectile. + * @param end the end. + * @param runes the runes. + */ + private GodSpells(SpellType type, int sound, int impactAudio, Graphics start, Projectile projectile, Graphics end, Item... runes) { + super(type, SpellBook.MODERN, 60, 35.0, sound, impactAudio, ANIMATION, start, projectile, end, runes); + } + + private int getSpellIndex() { + int index = -1; + switch (runes[1].getAmount()) { + case 2: // Saradomin strike + index = 0; + break; + case 1: // Guthix claws + index = 1; + break; + case 4: // Flames of Zamorak + index = 2; + break; + } + return index; + } + + @Override + public boolean meetsRequirements(Entity caster, boolean message, boolean remove) { + if (caster instanceof NPC) { + return true; + } + if (caster instanceof Player) { + int staffId = ((Player) caster).getEquipment().getNew(EquipmentContainer.SLOT_WEAPON).getId(); + int index = getSpellIndex(); + if(index < 0) { + return false; + } + int required = GOD_STAVES[index]; + Player p = (Player) caster; + if (p.getSavedData().getActivityData().getGodCasts()[index] < 100 && !p.getZoneMonitor().isInZone("mage arena")) { + p.sendMessage("You need to cast " + NAMES[index] + " " + (100 - p.getSavedData().getActivityData().getGodCasts()[index]) + " more times inside the Mage Arena."); + return false; + } + + if (staffId != required && !(index == 1 && staffId == Items.VOID_KNIGHT_MACE_8841)) { + if (message) { + ((Player) caster).getPacketDispatch().sendMessage("You need to wear a " + ItemDefinition.forId(required).getName() + " to cast this spell."); + } + return false; + } + } + return super.meetsRequirements(caster, message, remove); + } + + @Override + public void fireEffect(Entity entity, Entity victim, BattleState state) { + switch(getSpellIndex()) { + case 0: + victim.getSkills().decrementPrayerPoints(1); + break; + case 1: + victim.getSkills().drainLevel(Skills.DEFENCE, 0.05, 0.05); + break; + case 2: + victim.getSkills().drainLevel(Skills.MAGIC, 0.05, 0.05); + break; + } + } + + @Override + public void visualize(Entity entity, Node target) { + super.visualize(entity, target); + if (entity instanceof NPC) { + NPC n = (NPC) entity; + if (n.getId() > 911 && n.getId() < 915 || (n.getId() > 906 && n.getId() < 912)) { + n.getAnimator().forceAnimation(n.getProperties().getAttackAnimation()); + } + } + } + @Override + public void visualizeImpact(Entity entity, Entity target, BattleState state) { + if (entity instanceof Player) { + int index = getSpellIndex(); + Player p = (Player) entity; + if (p.getSavedData().getActivityData().getGodCasts()[index] < 100) { + p.getSavedData().getActivityData().getGodCasts()[index]++; + if (p.getSavedData().getActivityData().getGodCasts()[index] >= 100) { + p.sendMessage("You can now cast " + NAMES[index] + " outside the Arena."); + } + } + if (state.getEstimatedHit() == -1) { + target.graphics(SPLASH_GRAPHIC); + if (projectile == SARA_PROJECTILE) { + playGlobalAudio(target.getLocation(), Sounds.SARADOMIN_STRIKE_FAIL_1656, 20); + } + if (projectile == GUTHIX_PROJECTILE) { + playGlobalAudio(target.getLocation(), Sounds.CLAWS_OF_GUTHIX_FAIL_1652, 20); + } + if (projectile == ZAM_PROJECTILE) { + playGlobalAudio(target.getLocation(), Sounds.FLAMES_OF_ZAMORAK_FAIL_1654, 20); + } + return; + } + } + target.graphics(endGraphic); + playGlobalAudio(target.getLocation(), impactAudio); + } + + @Override + public int getMaximumImpact(Entity entity, Entity victim, BattleState state) { + return getType().getImpactAmount(entity, victim, 0); + } + + @Override + public Plugin newInstance(SpellType type) throws Throwable { + SpellBook.MODERN.register(41, new GodSpells(SpellType.GOD_STRIKE, -1, Sounds.SARADOMIN_STRIKE_1659, SARA_START, SARA_PROJECTILE, SARA_END, Runes.BLOOD_RUNE.getItem(2), Runes.FIRE_RUNE.getItem(2), Runes.AIR_RUNE.getItem(4))); + SpellBook.MODERN.register(42, new GodSpells(SpellType.GOD_STRIKE, -1, Sounds.CLAWS_OF_GUTHIX_1653, GUTHIX_START, GUTHIX_PROJECTILE, GUTHIX_END, Runes.BLOOD_RUNE.getItem(2), Runes.FIRE_RUNE.getItem(1), Runes.AIR_RUNE.getItem(4))); + SpellBook.MODERN.register(43, new GodSpells(SpellType.GOD_STRIKE, -1, Sounds.FLAMES_OF_ZAMORAK_1655, ZAM_START, ZAM_PROJECTILE, ZAM_END, Runes.BLOOD_RUNE.getItem(2), Runes.FIRE_RUNE.getItem(4), Runes.AIR_RUNE.getItem(1))); + return this; + } + +} diff --git a/Server/src/main/content/global/skill/magic/modern/IbanBlast.java b/Server/src/main/content/global/skill/magic/modern/IbanBlast.java new file mode 100644 index 0000000..5a35d7e --- /dev/null +++ b/Server/src/main/content/global/skill/magic/modern/IbanBlast.java @@ -0,0 +1,54 @@ +package content.global.skill.magic.modern; + +import core.game.container.impl.EquipmentContainer; +import core.game.node.entity.combat.spell.Runes; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.spell.CombatSpell; +import core.game.node.entity.combat.spell.SpellType; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.plugin.Plugin; +import org.rs09.consts.Sounds; + +/** + * Represents the iban blast spell. + * @author Emperor + * @version 1.0 + */ +@Initializable +public final class IbanBlast extends CombatSpell { + + /** + * Constructs a new {@code IbanBlast} {@code Object}. + */ + public IbanBlast() { + super(SpellType.IBANS_BLAST, SpellBook.MODERN, 50, 60.5, Sounds.FIREWAVE_CAST_AND_FIRE_162, Sounds.FIREWAVE_HIT_163, new Animation(708, Priority.HIGH), new Graphics(87, 96), Projectile.create((Entity) null, null, 88, 40, 36, 52, 75, 15, 11), new Graphics(89, 96), Runes.FIRE_RUNE.getItem(5), Runes.DEATH_RUNE.getItem(1)); + } + + @Override + public boolean cast(Entity entity, Node target) { + if (((Player) entity).getEquipment().getNew(EquipmentContainer.SLOT_WEAPON).getId() != 1409) { + ((Player) entity).getPacketDispatch().sendMessage("You need to wear Iban's staff to cast this spell."); + return false; + } + return super.cast(entity, target); + } + + @Override + public Plugin newInstance(SpellType arg) throws Throwable { + SpellBook.MODERN.register(29, this); + return this; + } + + @Override + public int getMaximumImpact(Entity entity, Entity victim, BattleState state) { + return type.getImpactAmount(entity, victim, 0); + } +} diff --git a/Server/src/main/content/global/skill/magic/modern/MagicDart.java b/Server/src/main/content/global/skill/magic/modern/MagicDart.java new file mode 100644 index 0000000..3d01de0 --- /dev/null +++ b/Server/src/main/content/global/skill/magic/modern/MagicDart.java @@ -0,0 +1,57 @@ +package content.global.skill.magic.modern; + +import core.game.container.impl.EquipmentContainer; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.combat.spell.Runes; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.spell.CombatSpell; +import core.game.node.entity.combat.spell.SpellType; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Handles the magic dart spell. + * @author Emperor + */ +@Initializable +public class MagicDart extends CombatSpell { + + /** + * Constructs a new {@code MagicDart} {@code Object}. + */ + public MagicDart() { + super(SpellType.MAGIC_DART, SpellBook.MODERN, 50, 30.0, 218, 219, new Animation(1576, Priority.HIGH), null, Projectile.create((Entity) null, null, 330, 40, 36, 52, 75, 15, 11), new Graphics(331, 96), Runes.DEATH_RUNE.getItem(1), Runes.MIND_RUNE.getItem(4)); + } + + @Override + public boolean cast(Entity entity, Node target) { + if (entity.getSkills().getLevel(Skills.SLAYER) < 55) { + ((Player) entity).getPacketDispatch().sendMessage("You need a Slayer level of 55 to cast this spell."); + return false; + } + if (((Player) entity).getEquipment().getNew(EquipmentContainer.SLOT_WEAPON).getId() != 4170) { + ((Player) entity).getPacketDispatch().sendMessage("You need to wear a Slayer's staff to cast this spell."); + return false; + } + return super.cast(entity, target); + } + + @Override + public Plugin newInstance(SpellType arg) throws Throwable { + SpellBook.MODERN.register(31, this); + return this; + } + + @Override + public int getMaximumImpact(Entity entity, Entity victim, BattleState state) { + return type.getImpactAmount(entity, victim, 0); + } +} diff --git a/Server/src/main/content/global/skill/magic/modern/ModernData.kt b/Server/src/main/content/global/skill/magic/modern/ModernData.kt new file mode 100644 index 0000000..793a757 --- /dev/null +++ b/Server/src/main/content/global/skill/magic/modern/ModernData.kt @@ -0,0 +1,63 @@ +package content.global.skill.magic.modern + +import core.game.node.item.Item +import core.game.world.update.flag.context.Graphics +import org.rs09.consts.Items +import org.rs09.consts.Scenery +import org.rs09.consts.Sounds + +enum class ChargeOrbData( + val obelisk: Int, + val requiredRunes: Array, + val level: Int, + val experience: Double, + val graphics: Graphics, + val sound: Int, + val chargedOrb: Int +) { + CHARGE_WATER_ORB( + Scenery.OBELISK_OF_WATER_2151, + arrayOf(Item(Items.COSMIC_RUNE_564, 3), Item(Items.WATER_RUNE_555, 30), Item(Items.UNPOWERED_ORB_567)), + 56, + 66.0, + Graphics(149, 90), + Sounds.CHARGE_WATER_ORB_118, + Items.WATER_ORB_571 + ), + CHARGE_EARTH_ORB( + Scenery.OBELISK_OF_EARTH_29415, + arrayOf(Item(Items.COSMIC_RUNE_564, 3), Item(Items.EARTH_RUNE_557, 30), Item(Items.UNPOWERED_ORB_567)), + 60, + 70.0, + Graphics(151, 90), + Sounds.CHARGE_EARTH_ORB_115, + Items.EARTH_ORB_575 + ), + CHARGE_FIRE_ORB( + Scenery.OBELISK_OF_FIRE_2153, + arrayOf(Item(Items.COSMIC_RUNE_564, 3), Item(Items.FIRE_RUNE_554, 30), Item(Items.UNPOWERED_ORB_567)), + 63, + 73.0, + Graphics(152, 90), + Sounds.CHARGE_FIRE_ORB_117, + Items.FIRE_ORB_569 + ), + CHARGE_AIR_ORB( + Scenery.OBELISK_OF_AIR_2152, + arrayOf(Item(Items.COSMIC_RUNE_564, 3), Item(Items.AIR_RUNE_556, 30), Item(Items.UNPOWERED_ORB_567)), + 66, + 76.0, + Graphics(150, 90), + Sounds.CHARGE_AIR_ORB_116, + Items.AIR_ORB_573 + ); + companion object{ + val spellMap = HashMap() + + init { + for (spell in ChargeOrbData.values()) { + spellMap[spell.obelisk] = spell + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/magic/modern/ModernListeners.kt b/Server/src/main/content/global/skill/magic/modern/ModernListeners.kt new file mode 100644 index 0000000..085f447 --- /dev/null +++ b/Server/src/main/content/global/skill/magic/modern/ModernListeners.kt @@ -0,0 +1,378 @@ +package content.global.skill.magic.modern + +import content.data.Quests +import content.global.skill.magic.SpellListener +import content.global.skill.magic.SpellUtils.hasRune +import content.global.skill.magic.TeleportMethod +import content.global.skill.magic.spellconsts.Modern +import content.global.skill.prayer.Bones +import content.global.skill.smithing.smelting.Bar +import content.global.skill.smithing.smelting.SmeltingPulse +import core.ServerConstants +import core.api.* +import core.game.event.ItemAlchemizationEvent +import core.game.event.ResourceProducedEvent +import core.game.event.TeleportEvent +import core.game.interaction.MovementPulse +import core.game.node.Node +import core.game.node.entity.Entity +import core.game.node.entity.combat.spell.MagicStaff +import core.game.node.entity.impl.Animator +import core.game.node.entity.impl.Projectile +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.TeleportManager +import core.game.node.entity.player.link.diary.DiaryType +import core.game.node.entity.skill.Skills +import content.region.kandarin.ardougne.quest.plaguecity.PlagueCityListeners +import core.game.node.item.Item +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import org.rs09.consts.Items +import org.rs09.consts.Scenery +import org.rs09.consts.Sounds + +class ModernListeners : SpellListener("modern"){ + override fun defineListeners() { + onCast(Modern.HOME_TELEPORT, NONE){ player, _ -> + if (!getAttribute(player, "tutorial:complete", false)) { + return@onCast + } + requires(player) + player.teleporter.send(ServerConstants.HOME_LOCATION,TeleportManager.TeleportType.HOME) + setDelay(player,true) + } + + onCast(Modern.VARROCK_TELEPORT, NONE){ player, _-> + requires(player,25, arrayOf(Item(Items.FIRE_RUNE_554),Item(Items.AIR_RUNE_556,3),Item(Items.LAW_RUNE_563))) + val alternateTeleport = getAttribute(player, "diaries:varrock:alttele", false) + val dest = if(alternateTeleport) Location.create(3165, 3472, 0) else Location.create(3213, 3424, 0) + sendTeleport(player,35.0, dest) + } + + onCast(Modern.LUMBRIDGE_TELEPORT, NONE){ player, _ -> + requires(player,31, arrayOf(Item(Items.EARTH_RUNE_557),Item(Items.AIR_RUNE_556,3),Item(Items.LAW_RUNE_563))) + sendTeleport(player,41.0,Location.create(3221, 3219, 0)) + } + + onCast(Modern.FALADOR_TELEPORT, NONE){ player, _ -> + requires(player,37, arrayOf(Item(Items.WATER_RUNE_555),Item(Items.AIR_RUNE_556,3),Item(Items.LAW_RUNE_563))) + sendTeleport(player,47.0,Location.create(2965, 3378, 0)) + } + + onCast(Modern.CAMELOT_TELEPORT, NONE){ player, _-> + requires(player,45, arrayOf(Item(Items.AIR_RUNE_556,5),Item(Items.LAW_RUNE_563))) + player.achievementDiaryManager.finishTask(player, DiaryType.SEERS_VILLAGE, 1, 5) + sendTeleport(player,55.5, Location.create(2758, 3478, 0)) + } + + onCast(Modern.ARDOUGNE_TELEPORT, NONE){ player, _ -> + if (getAttribute(player, PlagueCityListeners.ARDOUGNE_TELE_ATTRIBUTE, false)){ + requires(player,51, arrayOf(Item(Items.WATER_RUNE_555,2),Item(Items.LAW_RUNE_563,2))) + sendTeleport(player,61.0, Location.create(2662, 3307, 0)) + } + else { + // source https://runescape.salmoneus.net/forums/topic/289818-ardougne-teleport-help/ + sendDialogue(player, "You haven\'t learnt how to cast this spell yet") + } + return@onCast + } + + onCast(Modern.WATCHTOWER_TELEPORT, NONE){ player, _ -> + if (!hasRequirement(player, Quests.WATCHTOWER)) + return@onCast + requires(player,58, arrayOf(Item(Items.EARTH_RUNE_557,2),Item(Items.LAW_RUNE_563,2))) + sendTeleport(player,68.0, Location.create(2549, 3112, 0)) + } + + onCast(Modern.TROLLHEIM_TELEPORT, NONE){ player, _ -> + if (!hasRequirement(player, Quests.EADGARS_RUSE)) + return@onCast + requires(player,61, arrayOf(Item(Items.FIRE_RUNE_554,2),Item(Items.LAW_RUNE_563,2))) + sendTeleport(player,68.0, Location.create(2891, 3678, 0)) + } + + onCast(Modern.APE_ATOLL_TELEPORT, NONE){ player, _ -> + if (!hasRequirement(player, Quests.MONKEY_MADNESS)) + return@onCast + requires(player,64, arrayOf(Item(Items.FIRE_RUNE_554,2),Item(Items.WATER_RUNE_555,2),Item(Items.LAW_RUNE_563,2),Item(Items.BANANA_1963))) + sendTeleport(player,74.0, Location.create(2754, 2784, 0)) + } + + onCast(Modern.TELEPORT_TO_HOUSE, NONE){ player, _ -> + requires(player,40, arrayOf(Item(Items.LAW_RUNE_563), Item(Items.AIR_RUNE_556), Item(Items.EARTH_RUNE_557))) + attemptHouseTeleport(player) + } + + onCast(Modern.LOW_ALCHEMY, ITEM){ player, node -> + val item = node?.asItem() ?: return@onCast + requires(player,21, arrayOf(Item(Items.FIRE_RUNE_554,3),Item(Items.NATURE_RUNE_561))) + alchemize(player,item,high = false) + } + + onCast(Modern.HIGH_ALCHEMY, ITEM){ player, node -> + val item = node?.asItem() ?: return@onCast + requires(player,55, arrayOf(Item(Items.FIRE_RUNE_554,5),Item(Items.NATURE_RUNE_561,1))) + alchemize(player,item,high = true) + } + + onCast(Modern.SUPERHEAT, ITEM){ player, node -> + val item = node?.asItem() ?: return@onCast + requires(player,43, arrayOf(Item(Items.FIRE_RUNE_554,4),Item(Items.NATURE_RUNE_561,1))) + superheat(player,item) + } + + onCast(Modern.BONES_TO_BANANAS, NONE){ player, _ -> + requires(player,15, arrayOf(Item(Items.EARTH_RUNE_557,2), Item(Items.WATER_RUNE_555,2), Item(Items.NATURE_RUNE_561,1))) + boneConvert(player,true) + } + + onCast(Modern.BONES_TO_PEACHES, NONE){ player, _ -> + requires(player,60, arrayOf(Item(Items.EARTH_RUNE_557,4), Item(Items.WATER_RUNE_555,4), Item(Items.NATURE_RUNE_561,2))) + boneConvert(player,false) + } + + onCast(Modern.CHARGE_WATER_ORB, OBJECT, Scenery.OBELISK_OF_WATER_2151, 3, method = ::chargeOrb) + onCast(Modern.CHARGE_EARTH_ORB, OBJECT, Scenery.OBELISK_OF_EARTH_29415, 3, method = ::chargeOrb) + onCast(Modern.CHARGE_FIRE_ORB, OBJECT, Scenery.OBELISK_OF_FIRE_2153, 3, method = ::chargeOrb) + onCast(Modern.CHARGE_AIR_ORB, OBJECT, Scenery.OBELISK_OF_AIR_2152, 3, method = ::chargeOrb) + } + + private fun boneConvert(player: Player,bananas: Boolean){ + val isInMTA = player.zoneMonitor.isInZone("Creature Graveyard") + if(isInMTA && player.getAttribute("tablet-spell",false)){ + player.sendMessage("You can not use this tablet in the Mage Training Arena.") + return + } + + if(!bananas && !player.savedData.activityData.isBonesToPeaches && !player.getAttribute("tablet-spell",false)){ + player.sendMessage("You can only learn this spell from the Mage Training Arena.") + return + } + + val bones = if(isInMTA) intArrayOf(6904,6905,6906,6907) else Bones.values().map { it.itemId }.toIntArray() + + for(item in player.inventory.toArray()){ + item ?: continue + if(isInMTA){ + if(bones.contains(item.id)){ + val inInventory = player.inventory.getAmount(item.id) + val amount = inInventory * (content.minigame.mta.impl.GraveyardZone.BoneType.forItem(Item(item.id)).ordinal + 1) + if(amount > 0){ + player.inventory.remove(Item(item.id,inInventory)) + player.inventory.add(Item(if(bananas) Items.BANANA_1963 else Items.PEACH_6883,amount)) + } + } + } else { + if(bones.contains(item.id)){ + val inInventory = player.inventory.getAmount(item.id) + player.inventory.remove(Item(item.id,inInventory)) + player.inventory.add(Item(if(bananas) Items.BANANA_1963 else Items.PEACH_6883,inInventory)) + } + } + } + visualizeSpell(player,BONE_CONVERT_ANIM, BONE_CONVERT_GFX) + playAudio(player, Sounds.BONES_TO_BANANAS_ALL_114) + removeRunes(player) + addXP(player,if(bananas) 25.0 else 65.0) + setDelay(player,false) + } + + private fun superheat(player: Player,item: Item){ + if(!item.name.contains("ore") && !item.name.equals("coal", true)){ + player.sendMessage("You can only cast this spell on ore.") + return + } + + // Elemental Workshop I special interaction + if(item.id == Items.ELEMENTAL_ORE_2892) { + sendMessage(player, "Even this spell is not hot enough to heat this item.") + return + } + + fun returnBar(player: Player,item: Item): Bar? { + // Loop through all metal bars starting with the highest tier + for (potentialBar in Bar.values().reversed()) { + // Check if the ore being cast on is needed for the current bar being considered + val inputOreInBar = potentialBar.ores.map{it.id}.contains(item.id) + // Check the player has all the required ores (and corresponding quantities) to make the current bar being considered + val playerHasNecessaryOres = potentialBar.ores.all{ore -> inInventory(player, ore.id, ore.amount)} + // If both tests pass return the current bar being considered as the one the spell should try to make + if (inputOreInBar && playerHasNecessaryOres) return potentialBar + } + // If none of the bars passed both tests the player must be missing a required ore + player.packetDispatch.sendMessage("You do not have the required ores to make this bar.") + return null + } + var bar = returnBar(player,item)?: return + + if(player.skills.getLevel(Skills.SMITHING) < bar.level){ + player.sendMessage("You need a smithing level of ${bar.level} to superheat that ore.") + return + } + + player.lock(3) + removeRunes(player) + addXP(player,53.0) + playAudio(player, Sounds.SUPERHEAT_ALL_190) + showMagicTab(player) + player.pulseManager.run(SmeltingPulse(player, item, bar, 1, true)) + setDelay(player,false) + } + + fun alchemize(player: Player, item: Item, high: Boolean, explorersRing: Boolean = false): Boolean { + if(item.name == "Coins") player.sendMessage("You can't alchemize something that's already gold!").also { return false } + if((!item.definition.isTradeable) && (!item.definition.isAlchemizable)) player.sendMessage("You can't cast this spell on something like that.").also { return false } + + if(player.zoneMonitor.isInZone("Alchemists' Playground")){ + player.sendMessage("You can only alch items from the cupboards!") + return false + } + + val coins = Item(995, item.definition.getAlchemyValue(high)) + if (item.amount > 1 && coins.amount > 0 && !player.inventory.hasSpaceFor(coins)) { + player.sendMessage("Not enough space in your inventory!") + return false + } + + if (player.pulseManager.current !is MovementPulse) { + player.pulseManager.clear() + } + + if (explorersRing) { + visualize(player, LOW_ALCH_ANIM, EXPLORERS_RING_GFX) + } else { + val weapon = getItemFromEquipment(player, EquipmentSlot.WEAPON) + if (weapon != null && weapon.id in MagicStaff.FIRE_RUNE.staves) { + visualize(player, if (high) HIGH_ALCH_STAFF_ANIM else LOW_ALCH_STAFF_ANIM, if (high) HIGH_ALCH_STAFF_GFX else LOW_ALCH_STAFF_GFX) + } else { + visualize(player, if (high) HIGH_ALCH_ANIM else LOW_ALCH_ANIM, if (high) HIGH_ALCH_GFX else LOW_ALCH_GFX) + } + } + playAudio(player, if (high) Sounds.HIGH_ALCHEMY_97 else Sounds.LOW_ALCHEMY_98) + player.dispatch(ItemAlchemizationEvent(item.id, high)) + if (player.inventory.remove(Item(item.id, 1)) && coins.amount > 0) { + player.inventory.add(coins) + } + removeRunes(player) + addXP(player, if (high) 65.0 else 31.0) + showMagicTab(player) + setDelay(player, 5) + return true + } + + private fun sendTeleport(player: Player, xp: Double, location: Location){ + if(player.isTeleBlocked){ + player.removeAttribute("spell:runes") + player.sendMessage("A magical force prevents you from teleporting.") + return + } + + val teleType = TeleportManager.TeleportType.NORMAL + + if (player.teleporter.send(location, teleType)) { + player.dispatch(TeleportEvent(teleType, TeleportMethod.SPELL, -1, location)) + + removeRunes(player) + addXP(player, xp) + setDelay(player, true) + } + } + + private fun attemptHouseTeleport(player: Player){ + if(player.isTeleBlocked){ + player.removeAttribute("spell:runes") + player.sendMessage("A magical force prevents you from teleporting.") + return + } + val hasHouse = player.houseManager.location.exitLocation != null + if(!hasHouse){ + player.sendMessage("You do not have a house you can teleport to.") + return + } + + player.houseManager.preEnter(player, false) + val teleType = TeleportManager.TeleportType.NORMAL + val loc = player.houseManager.getEnterLocation() + player.teleporter.send(loc, teleType) + player.houseManager.postEnter(player, false) //this actually runs when the teleport is SUBMITTED rather than EXECUTED, but this is fine + removeRunes(player) + addXP(player,30.0) + setDelay(player,true) + } + + private fun chargeOrb(player: Player, node: Node?) { + if (node == null) return + val spell = ChargeOrbData.spellMap[node.id] ?: return + requires(player, spell.level, spell.requiredRunes) + removeAttribute(player, "spell:runes") + face(player, node) + sendSkillDialogue(player) { + withItems(spell.chargedOrb) + calculateMaxAmount { return@calculateMaxAmount amountInInventory(player, Items.UNPOWERED_ORB_567) } + create { _, amount -> + var crafted = 0 + queueScript(player, 0) { + if (!hasLevelDyn(player, Skills.CRAFTING, spell.level)) { + sendMessage(player, "You need a magic level of ${spell.level} to cast this spell.") + return@queueScript stopExecuting(player) + } + for (rune in spell.requiredRunes) { + if(!hasRune(player,rune)){ + sendMessage(player, "You don't have enough ${rune.name.lowercase()}s to cast this spell.") + return@queueScript stopExecuting(player) + } + } + visualizeSpell(player, CHARGE_ORB_ANIM, spell.graphics, spell.sound) + removeRunes(player) + addItem(player, spell.chargedOrb) + addXP(player, spell.experience) + setDelay(player, 3) + crafted++ + + if (crafted == 5 && spell.chargedOrb == Items.WATER_ORB_571) { + player.dispatch(ResourceProducedEvent(spell.chargedOrb, crafted, node)) + } + if (amount == crafted) { return@queueScript stopExecuting(player) } + setCurrentScriptState(player, 0) + return@queueScript delayScript(player, 6) + } + } + } + return + } + companion object { + private val CONFUSE_START = Graphics(102, 96) + private val CONFUSE_PROJECTILE = Projectile.create(null as Entity?, null, 103, 40, 36, 52, 75, 15, 11) + private val CONFUSE_END = Graphics(104, 96) + private val WEAKEN_START = Graphics(105, 96) + private val WEAKEN_PROJECTILE = Projectile.create(null as Entity?, null, 106, 40, 36, 52, 75, 15, 11) + private val WEAKEN_END = Graphics(107, 96) + private val CURSE_START = Graphics(108, 96) + private val CURSE_PROJECTILE = Projectile.create(null as Entity?, null, 109, 40, 36, 52, 75, 15, 11) + private val CURSE_END = Graphics(110, 96) + private val VULNER_START = Graphics(167, 96) + private val VULNER_PROJECTILE = Projectile.create(null as Entity?, null, 168, 40, 36, 52, 75, 15, 11) + private val VULNER_END = Graphics(169, 96) + private val ENFEEBLE_START = Graphics(170, 96) + private val ENFEEBLE_PROJECTILE = Projectile.create(null as Entity?, null, 171, 40, 36, 52, 75, 15, 11) + private val ENFEEBLE_END = Graphics(172, 96) + private val STUN_START = Graphics(173, 96) + private val STUN_PROJECTILE = Projectile.create(null as Entity?, null, 174, 40, 36, 52, 75, 15, 11) + private val STUN_END = Graphics(107, 96) + private val LOW_ANIMATION = Animation(716, Animator.Priority.HIGH) + private val HIGH_ANIMATION = Animation(729, Animator.Priority.HIGH) + private val LOW_ALCH_ANIM = Animation(9623) + private val LOW_ALCH_STAFF_ANIM = Animation(9625) + private val HIGH_ALCH_ANIM = Animation(9631) + private val HIGH_ALCH_STAFF_ANIM = Animation(9633) + private val LOW_ALCH_GFX = Graphics(763) + private val HIGH_ALCH_GFX = Graphics(1691) + private val LOW_ALCH_STAFF_GFX = Graphics(1692) + private val HIGH_ALCH_STAFF_GFX = Graphics(1693) + private val EXPLORERS_RING_GFX = Graphics(1698) + private val BONE_CONVERT_GFX = Graphics(141, 96) + private val BONE_CONVERT_ANIM = Animation(722) + private val CHARGE_ORB_ANIM = Animation(726) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/magic/modern/SonicWaveSpell.java b/Server/src/main/content/global/skill/magic/modern/SonicWaveSpell.java new file mode 100644 index 0000000..af397df --- /dev/null +++ b/Server/src/main/content/global/skill/magic/modern/SonicWaveSpell.java @@ -0,0 +1,61 @@ +package content.global.skill.magic.modern; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.spell.CombatSpell; +import core.game.node.entity.combat.spell.SpellType; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the sonic wave spell of an evil chicken. + * @author 'Vexia + * @date 24/11/2013 + */ +@Initializable +public final class SonicWaveSpell extends CombatSpell { + + /** + * The projectile for Earth strike. + */ + private static final Projectile STRIKE_PROJECTILE = Projectile.create((Entity) null, null, 337, 8, 8, 52, 100, 15, 1); + + /** + * Constructs a new {@code EarthSpell} {@Code Object} + */ + public SonicWaveSpell() { + /* + * empty. + */ + } + + /** + * Constructs a new {@code EarthSpell} {@Code Object}. + * @param type The spell type. + * @param level The level requirement. + * @param sound The cast sound. + * @param start The start graphics. + * @param projectile The projectile. + * @param end The end graphics. + * @param runes The rune requirements. + */ + private SonicWaveSpell(SpellType type, int level, int sound, Graphics start, Projectile projectile, Graphics end, Item... runes) { + super(type, SpellBook.MODERN, level, 0.0, sound, sound + 1, null, start, projectile, end, runes); + } + + @Override + public int getMaximumImpact(Entity entity, Entity victim, BattleState state) { + return getType().getImpactAmount(entity, victim, 5); + } + + @Override + public Plugin newInstance(SpellType type) throws Throwable { + SpellBook.MODERN.register(63232, new SonicWaveSpell(SpellType.STRIKE, 1, -1, new Graphics(337), STRIKE_PROJECTILE, null)); + return this; + } + +} diff --git a/Server/src/main/content/global/skill/magic/modern/SpellCharge.kt b/Server/src/main/content/global/skill/magic/modern/SpellCharge.kt new file mode 100644 index 0000000..fba47af --- /dev/null +++ b/Server/src/main/content/global/skill/magic/modern/SpellCharge.kt @@ -0,0 +1,16 @@ +package content.global.skill.magic.modern + +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import org.rs09.consts.Sounds +import core.game.system.timer.PersistTimer + +class SpellCharge : PersistTimer (700, "magic:spellcharge") { + override fun run (entity: Entity) : Boolean { + if (entity !is Player) return false + sendMessage(entity, "Your magical charge fades away.") + playAudio(entity, Sounds.CHARGE_GONE_1650) + return false + } +} diff --git a/Server/src/main/content/global/skill/magic/modern/TeleblockSpell.java b/Server/src/main/content/global/skill/magic/modern/TeleblockSpell.java new file mode 100644 index 0000000..baac8b5 --- /dev/null +++ b/Server/src/main/content/global/skill/magic/modern/TeleblockSpell.java @@ -0,0 +1,126 @@ +package content.global.skill.magic.modern; + +import core.game.node.entity.combat.spell.Runes; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.spell.CombatSpell; +import core.game.node.entity.combat.spell.SpellType; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.node.entity.player.link.prayer.PrayerType; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.plugin.Plugin; + +import static core.api.ContentAPIKt.*; + +/** + * Handles the teleportation block spell in the modern spellbook. + * @author Splinter + * + */ +@Initializable +public final class TeleblockSpell extends CombatSpell { + + /** + * The projectile for the teleblock spell. + */ + private static final Projectile TELEBLOCK_ORB = Projectile.create((Entity) null, null, 1842, 40, 36, 52, 75, 15, 11); + + /** + * The ending graphic for the teleblock spell. + */ + private static final Graphics TELEBLOCK_SUCCESS = new Graphics(1843, 0); + + /** + * The starting graphic for the teleblock spell. + */ + private static final Graphics TELEBLOCK_START = new Graphics(1841, 0); + + /** + * Constructs a new {@code TeleblockSpell} {@code Object}. + */ + public TeleblockSpell() { + /* + * empty. + */ + } + + /** + * Constructs a new {@code TeleblockSpell} {@code Object}. + * @param level - the level needed to cast this spell + * @param baseExperience - the base amount of experience we need to give + * @param impactSound -the sound played on successful impact + * @param anim - the animation to play + * @param start - the starting graphic + * @param projectile - the projectile to send + * @param end - the ending graphic + */ + public TeleblockSpell(SpellType type, int level, double baseExperience, int impactSound, Animation anim, Graphics start, Projectile projectile, Graphics end, Item... runes) { + super(type, SpellBook.MODERN, level, baseExperience, 202, 203, anim, TELEBLOCK_START, TELEBLOCK_ORB, TELEBLOCK_SUCCESS, runes); + } + + @Override + public Plugin newInstance(SpellType arg) throws Throwable { + SpellBook.MODERN.register(63, new TeleblockSpell(SpellType.TELEBLOCK, 85, 80, 203, new Animation(10503, Priority.HIGH), TELEBLOCK_START, TELEBLOCK_ORB, TELEBLOCK_SUCCESS, Runes.LAW_RUNE.getItem(1), Runes.DEATH_RUNE.getItem(1), Runes.CHAOS_RUNE.getItem(1))); + return this; + } + + @Override + public void visualize(Entity entity, Node target) { + entity.graphics(graphic); + if (projectile != null) { + projectile.transform(entity, (Entity) target, false, 58, 10).send(); + } + entity.animate(animation); + playGlobalAudio(entity.getLocation(), audio.id, 20); + } + + @Override + public boolean cast(Entity entity, Node target) { + if (!(target instanceof Player)) { + entity.asPlayer().sendMessage("You can only cast this spell on another player."); + return false; + } + if (!entity.getZoneMonitor().isInZone("Wilderness") || !((Player) target).getZoneMonitor().isInZone("Wilderness")) { + entity.asPlayer().sendMessage("You and your opponent must both be in the wilderness for you to use this spell."); + return false; + } + if (hasTimerActive(target.asPlayer(), "teleblock")) { + entity.asPlayer().sendMessage("That player is already affected by this spell."); + return false; + } + if (!meetsRequirements(entity, true, false)) { + return false; + } + return super.cast(entity, target); + } + + @Override + public void visualizeImpact(Entity entity, Entity target, BattleState state) { + super.visualizeImpact(entity, target, state); + } + + @Override + public int getMaximumImpact(Entity entity, Entity victim, BattleState state) { + return 0; + } + + @Override + public void fireEffect(Entity entity, Entity victim, BattleState state) { + if(!hasTimerActive(victim, "teleblock") && victim instanceof Player && state.getStyle().getSwingHandler().isAccurateImpact(entity, victim)){ + int ticks = 500; + if(((Player) victim).getPrayer().get(PrayerType.PROTECT_FROM_MAGIC)){ + ticks /= 2; + } + registerTimer(victim, spawnTimer("teleblock", ticks)); + } else if(hasTimerActive(victim, "teleblock")){ + entity.asPlayer().sendMessage("Your target is already blocked from teleporting."); + } + } +} diff --git a/Server/src/main/content/global/skill/magic/modern/TeleotherSpells.java b/Server/src/main/content/global/skill/magic/modern/TeleotherSpells.java new file mode 100644 index 0000000..9219295 --- /dev/null +++ b/Server/src/main/content/global/skill/magic/modern/TeleotherSpells.java @@ -0,0 +1,103 @@ +package content.global.skill.magic.modern; + +import core.game.node.entity.combat.spell.Runes; +import core.game.component.Component; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.spell.SpellType; +import core.game.node.entity.combat.spell.MagicSpell; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.node.entity.player.link.audio.Audio; +import core.game.node.item.Item; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.plugin.Plugin; +import org.rs09.consts.Sounds; + +/** + * Handles the teleport other spells. + * @author Emperor + */ +@Initializable +public final class TeleotherSpells extends MagicSpell { + + /** + * The destination. + */ + private String destination; + + /** + * The destination location. + */ + private Location location; + + /** + * Constructs a new {@code TeleotherSpells} {@code Object}. + */ + public TeleotherSpells() { + /* + * empty. + */ + } + + /** + * Constructs a new {@code TeleotherSpells} {@code Object}. + * @param level The level required. + * @param destination The destination name. + * @param location The location to teleport to. + * @param runes The runes required. + */ + public TeleotherSpells(int level, double experience, String destination, Location location, Item... runes) { + super(SpellBook.MODERN, level, experience, Animation.create(1818), Graphics.create(343), new Audio(Sounds.TELE_OTHER_CAST_199, 1, 0), runes); + this.destination = destination; + this.location = location; + } + + @Override + public Plugin newInstance(SpellType arg) throws Throwable { + SpellBook.MODERN.register(54, new TeleotherSpells(74, 84, "Lumbridge", Location.create(3222, 3217, 0), Runes.SOUL_RUNE.getItem(1), Runes.LAW_RUNE.getItem(1), Runes.EARTH_RUNE.getItem(1))); + SpellBook.MODERN.register(59, new TeleotherSpells(82, 92, "Falador", Location.create(2965, 3378, 0), Runes.SOUL_RUNE.getItem(1), Runes.LAW_RUNE.getItem(1), Runes.WATER_RUNE.getItem(1))); + SpellBook.MODERN.register(62, new TeleotherSpells(90, 100, "Camelot", Location.create(2758, 3478, 0), Runes.SOUL_RUNE.getItem(2), Runes.LAW_RUNE.getItem(1))); + return this; + } + + @Override + public boolean cast(Entity entity, Node target) { + Player p = (Player) entity; + if (!(target instanceof Player)) { + p.getPacketDispatch().sendMessage("You can only cast this spell on other players."); + return false; + } + if (!entity.getZoneMonitor().teleport(0, null)) { + return false; + } + Player o = (Player) target; + if (!o.isActive() || o.isTeleBlocked() || o.getInterfaceManager().isOpened()) { + p.getPacketDispatch().sendMessage("The other player is currently busy."); + return false; + } + if(o.getZoneMonitor().isInZone("Wilderness") && o.getProperties().getCombatPulse().isInCombat()){ + p.sendMessage("The other player has their hands full at the moment!"); + return true; + } + if (!o.getSettings().isAcceptAid()) { + p.getPacketDispatch().sendMessage("The player is not accepting any aid."); + return false; + } + if (!meetsRequirements(entity, true, true)) { + return false; + } + visualize(entity, target); + Graphics.send(new Graphics(342), o.getLocation()); + p.faceLocation(o.getLocation()); + o.setAttribute("t-o_location", location); + o.getPacketDispatch().sendString(p.getUsername(), 326,1); + o.getPacketDispatch().sendString(destination, 326, 3); + o.getInterfaceManager().open(new Component(326)); + return true; + } + +} diff --git a/Server/src/main/content/global/skill/magic/modern/WaterSpell.java b/Server/src/main/content/global/skill/magic/modern/WaterSpell.java new file mode 100644 index 0000000..8096c40 --- /dev/null +++ b/Server/src/main/content/global/skill/magic/modern/WaterSpell.java @@ -0,0 +1,128 @@ +package content.global.skill.magic.modern; + +import core.plugin.Initializable; +import core.game.node.entity.combat.spell.Runes; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.spell.CombatSpell; +import core.game.node.entity.combat.spell.SpellType; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Plugin; +import org.rs09.consts.Sounds; + +/** + * Represents the water spells. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class WaterSpell extends CombatSpell { + + /** + * The start graphic for Water strike. + */ + private static final Graphics STRIKE_START = new Graphics(93, 96); + + /** + * The projectile for Water strike. + */ + private static final Projectile STRIKE_PROJECTILE = Projectile.create((Entity) null, null, 94, 40, 36, 52, 75, 15, 11); + + /** + * The end graphic for Water strike. + */ + private static final Graphics STRIKE_END = new Graphics(95, 96); + + /** + * The start graphic for Water bolt. + */ + private static final Graphics BOLT_START = new Graphics(120, 96); + + /** + * The projectile for Water bolt. + */ + private static final Projectile BOLT_PROJECTILE = Projectile.create((Entity) null, null, 121, 40, 36, 52, 75, 15, 11); + + /** + * The end graphic for Water bolt. + */ + private static final Graphics BOLT_END = new Graphics(122, 96); + + /** + * The start graphic for Water blast. + */ + private static final Graphics BLAST_START = new Graphics(135, 96); // 129 + + /** + * The projectile for Water blast. + */ + private static final Projectile BLAST_PROJECTILE = Projectile.create((Entity) null, null, 136, 40, 36, 52, 75, 15, 11); // 130 + + /** + * The end graphic for Water blast. + */ + private static final Graphics BLAST_END = new Graphics(137, 96); // 131 + + /** + * The start graphic for Water wave. + */ + private static final Graphics WAVE_START = new Graphics(161, 96); + + /** + * The projectile for Water wave. + */ + private static final Projectile WAVE_PROJECTILE = Projectile.create((Entity) null, null, 162, 40, 36, 52, 75, 15, 11); + + /** + * The end graphic for Water wave. + */ + private static final Graphics WAVE_END = new Graphics(163, 96); + + /** + * The cast animation. + */ + private static final Animation ANIMATION = new Animation(711, Priority.HIGH); + + /** + * Constructs a new {@code WaterSpell} {@Code Object} + */ + public WaterSpell() { + /* + * empty. + */ + } + + /** + * Constructs a new {@code WaterSpell} {@Code Object} + * @param type The spell type. + * @param level The level requirement. + * @param sound The cast sound. + * @param start The start graphics. + * @param projectile The projectile. + * @param end The end graphics. + * @param runes The rune requirements. + */ + private WaterSpell(SpellType type, int level, double baseExperience, int sound, Graphics start, Projectile projectile, Graphics end, Item... runes) { + super(type, SpellBook.MODERN, level, baseExperience, sound, sound + 1, ANIMATION, start, projectile, end, runes); + } + + @Override + public int getMaximumImpact(Entity entity, Entity victim, BattleState state) { + return getType().getImpactAmount(entity, victim, 2); + } + + @Override + public Plugin newInstance(SpellType type) throws Throwable { + SpellBook.MODERN.register(4, new WaterSpell(SpellType.STRIKE, 5, 7.5, Sounds.WATERSTRIKE_CAST_AND_FIRE_211, STRIKE_START, STRIKE_PROJECTILE, STRIKE_END, Runes.MIND_RUNE.getItem(1), Runes.WATER_RUNE.getItem(1), Runes.AIR_RUNE.getItem(1))); + SpellBook.MODERN.register(14, new WaterSpell(SpellType.BOLT, 23, 16.5, Sounds.WATERBOLT_CAST_AND_FIRE_209, BOLT_START, BOLT_PROJECTILE, BOLT_END, Runes.CHAOS_RUNE.getItem(1), Runes.WATER_RUNE.getItem(2), Runes.AIR_RUNE.getItem(2))); + SpellBook.MODERN.register(27, new WaterSpell(SpellType.BLAST, 47, 28.5, Sounds.WATERBLAST_CAST_AND_FIRE_207, BLAST_START, BLAST_PROJECTILE, BLAST_END, Runes.DEATH_RUNE.getItem(1), Runes.WATER_RUNE.getItem(3), Runes.AIR_RUNE.getItem(3))); + SpellBook.MODERN.register(48, new WaterSpell(SpellType.WAVE, 65, 37.5, Sounds.WATERWAVE_CAST_AND_FIRE_213, WAVE_START, WAVE_PROJECTILE, WAVE_END, Runes.BLOOD_RUNE.getItem(1), Runes.WATER_RUNE.getItem(7), Runes.AIR_RUNE.getItem(5))); + return this; + } + +} diff --git a/Server/src/main/content/global/skill/magic/spellconsts/Lunar.kt b/Server/src/main/content/global/skill/magic/spellconsts/Lunar.kt new file mode 100644 index 0000000..69e0fa5 --- /dev/null +++ b/Server/src/main/content/global/skill/magic/spellconsts/Lunar.kt @@ -0,0 +1,44 @@ +package content.global.skill.magic.spellconsts + +object Lunar { + const val BARBARIAN_TELEPORT = 0 + const val CURE_OTHER = 1 + const val FERTILE_SOIL = 2 + const val CURE_GROUP = 3 + const val NPC_CONTACT = 4 + const val ENERGY_TRANSFER = 5 + const val MONSTER_EXAMINE = 6 + const val HUMIDIFY = 7 + const val HUNTER_KIT = 8 + const val STAT_SPY = 9 + const val DREAM = 10 + const val PLANK_MAKE = 11 + const val SPELLBOOK_SWAP = 12 + const val MAGIC_IMBUE = 13 + const val VENGEANCE = 14 + const val BAKE_PIE = 15 + const val HOME_TELEPORT = 16 + const val FISHING_GUILD_TELEPORT = 17 + const val KHAZARD_TELEPORT = 18 + const val VENGEANCE_OTHER = 19 + const val MOONCLAN_TELEPORT = 20 + const val CATHERBY_TELEPORT = 21 + const val STRING_JEWELLERY = 22 + const val CURE_ME = 23 + const val WATERBIRTH_TELEPORT = 24 + const val SUPERGLASS_MAKE = 25 + const val BOOST_POTION_SHARE = 26 + const val STAT_RESTORE_POT_SHARE = 27 + const val ICE_PLATEAU_TELEPORT = 28 + const val HEAL_OTHER = 29 + const val HEAL_GROUP = 30 + const val OURANIA_TELEPORT = 31 + const val CURE_PLANT = 32 + const val MOONCLAN_GROUP_TELEPORT = 33 + const val WATERBIRTH_GROUP_TELEPORT = 34 + const val BARBARIAN_GROUP_TELEPORT = 35 + const val KHAZARD_GROUP_TELEPORT = 36 + const val FISHING_GUILD_GROUP_TELEPORT = 37 + const val CATHERBY_GROUP_TELEPORT = 38 + const val ICE_PLATEAU_GROUP_TELEPORT = 39 +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/magic/spellconsts/Modern.kt b/Server/src/main/content/global/skill/magic/spellconsts/Modern.kt new file mode 100644 index 0000000..fa3d3f0 --- /dev/null +++ b/Server/src/main/content/global/skill/magic/spellconsts/Modern.kt @@ -0,0 +1,32 @@ +package content.global.skill.magic.spellconsts + +object Modern { + const val HOME_TELEPORT = 0 + const val CONFUSE = 2 + const val BONES_TO_BANANAS = 9 + const val WEAKEN = 11 + const val BIND = 12 + const val LOW_ALCHEMY = 13 + const val VARROCK_TELEPORT = 15 + const val LUMBRIDGE_TELEPORT = 18 + const val CURSE = 19 + const val FALADOR_TELEPORT = 21 + const val SUPERHEAT = 25 + const val CAMELOT_TELEPORT = 26 + const val TELEPORT_TO_HOUSE = 23 + const val SNARE = 30 + const val ARDOUGNE_TELEPORT = 32 + const val HIGH_ALCHEMY = 34 + const val CHARGE_WATER_ORB = 35 + const val WATCHTOWER_TELEPORT = 37 + const val CHARGE_EARTH_ORB = 39 + const val BONES_TO_PEACHES = 40 + const val TROLLHEIM_TELEPORT = 44 + const val CHARGE_FIRE_ORB = 46 + const val APE_ATOLL_TELEPORT = 47 + const val CHARGE_AIR_ORB = 49 + const val VULNERABILITY = 50 + const val ENFEEBLE = 53 + const val ENTANGLE = 56 + const val STUN = 57 +} diff --git a/Server/src/main/content/global/skill/prayer/BoneBuryListener.kt b/Server/src/main/content/global/skill/prayer/BoneBuryListener.kt new file mode 100644 index 0000000..5b41927 --- /dev/null +++ b/Server/src/main/content/global/skill/prayer/BoneBuryListener.kt @@ -0,0 +1,50 @@ +package content.global.skill.prayer + +import core.api.* +import core.game.event.BoneBuryEvent +import core.game.interaction.Clocks +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import org.rs09.consts.Animations +import org.rs09.consts.Sounds + +class BoneBuryListener : InteractionListener { + override fun defineListeners() { + + /* + * Handles the bury options for bones in Bones.kt + */ + on(Bones.array, IntType.ITEM, "bury") { player, node -> + val bones = Bones.forId(node.id) ?: return@on true + if (!clockReady(player, Clocks.SKILLING)) return@on true + if (!inInventory(player, node.id)) return@on true + + stopWalk(player) + lock(player, 2) + delayClock(player, Clocks.SKILLING, 2) + sendMessage(player, "You dig a hole in the ground.") + animate(player, Animations.HUMAN_BURYING_BONES_827) + playAudio(player, Sounds.BONES_DOWN_2738) + + // A strong queue is required in the event a player moves immediately after clicking the bones + queueScript(player, 1, QueueStrength.STRONG) { + if (removeBones(player, node.asItem())) { + sendMessage(player, "You bury the bones.") + rewardXP(player, Skills.PRAYER, bones.experience) + player.dispatch(BoneBuryEvent(bones.itemId)) + } + return@queueScript stopExecuting(player) + } + return@on true + } + } + + private fun removeBones(player: Player, item: Item): Boolean { + val removedBones = replaceSlot(player, item.slot, Item()) + return removedBones == item && removedBones.slot == item.slot + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/prayer/Bones.kt b/Server/src/main/content/global/skill/prayer/Bones.kt new file mode 100644 index 0000000..755a806 --- /dev/null +++ b/Server/src/main/content/global/skill/prayer/Bones.kt @@ -0,0 +1,116 @@ +package content.global.skill.prayer + +import org.rs09.consts.Items + +/** + * Represents the type of bones. + * @author Apache Ah64 + */ +enum class Bones( + /** + * Construct a new `Bones` `Object`. + * @param itemId The item id. + * @param experience The experience given by burying the bone. + */ + + /** + * The bone item id. + */ + val itemId: Int, + + /** + * The experience given by burying the bone. + */ + val experience: Double, + + /** + * The bones' bonemeal item id if applicable. + */ + val bonemealId: Int?, +) { + BONES(Items.BONES_526, 4.5, Items.BONEMEAL_4255), + BONES_2(Items.BONES_2530, 4.5, Items.BONEMEAL_4255), + BONES_3(Items.BONES_3187, 4.5, Items.BONEMEAL_4255), + WOLF_BONES(Items.WOLF_BONES_2859, 4.5, Items.BONEMEAL_4257), + BURNT_BONES(Items.BURNT_BONES_528, 4.5, Items.BONEMEAL_4258), + SMALL_NINJA_MONKEY_BONES(Items.MONKEY_BONES_3179, 16.0, Items.BONEMEAL_4256), + MEDIUM_NINJA_MONKEY_BONES(Items.MONKEY_BONES_3180, 18.0, Items.BONEMEAL_4270), + GORILLA_BONES(Items.MONKEY_BONES_3181, 18.0, Items.BONEMEAL_4855), + BEARDED_GORILLA_BONES(Items.MONKEY_BONES_3182, 18.0, Items.BONEMEAL_5615), + KARAMJA_MONKEY_BONES(Items.MONKEY_BONES_3183, 5.0, Items.BONEMEAL_4260), + SMALL_ZOMBIE_MONKEY_BONES(Items.MONKEY_BONES_3185, 5.0, Items.BONEMEAL_6728), + LARGE_ZOMBIE_MONKEY_BONES(Items.MONKEY_BONES_3186, 5.0, Items.BONEMEAL_6810), + BAT_BONES(Items.BAT_BONES_530, 5.3, Items.BONEMEAL_4261), + BIG_BONES(Items.BIG_BONES_532, 15.0, Items.BONEMEAL_4262), + JOGRE_BONES(Items.JOGRE_BONES_3125, 15.0, Items.BONEMEAL_4263), + ZOGRE_BONES(Items.ZOGRE_BONES_4812, 22.5, Items.BONEMEAL_4264), + SHAIKAHAN_BONES(Items.SHAIKAHAN_BONES_3123, 25.0, Items.BONEMEAL_4265), + BABY_DRAGON_BONES(Items.BABYDRAGON_BONES_534, 30.0, Items.BONEMEAL_4266), + WYVERN_BONES(Items.WYVERN_BONES_6812, 50.0, Items.BONEMEAL_4267), //The bonemeal id should be 6810 + DRAGON_BONES(Items.DRAGON_BONES_536, 72.0, Items.BONEMEAL_4268), + FAYRG(Items.FAYRG_BONES_4830, 84.0, Items.BONEMEAL_4852), + RAURG_BONES(Items.RAURG_BONES_4832, 96.0, Items.BONEMEAL_4853), + DAGANNOTH(Items.DAGANNOTH_BONES_6729, 125.0, Items.BONEMEAL_4271), // The bonemeal id should be 6728 + OURG_BONES(Items.OURG_BONES_4834, 140.0, Items.BONEMEAL_4854), + BURNT_JOGRE_BONES(Items.BURNT_JOGRE_BONES_3127, 16.0, Items.BONEMEAL_4259), + BURNT_RAW_PASTY_JOGRE_BONES(Items.PASTY_JOGRE_BONES_3128, 17.0, null), + BURNT_COOKED_PASTY_JOGRE_BONES(Items.PASTY_JOGRE_BONES_3129, 17.0, null), + MARINATED_JOGRE_BONES(Items.MARINATED_J_BONES_3130, 18.0, null), + RAW_PASTY_JOGRE_BONES(Items.PASTY_JOGRE_BONES_3131, 17.0, null), + COOKED_PASTY_JOGRE_BONES(Items.PASTY_JOGRE_BONES_3132, 17.0, null), + MARINATED_JOGRE_BONES_BAD(Items.MARINATED_J_BONES_3133, 18.0, null); + + companion object { + /** + * Holds all bones. + */ + private val bones = HashMap() + + /** + * Gets the bones for the bone meal. + * @param itemId the item. + * @return the bones. + */ + @JvmStatic + fun forBoneMeal(itemId: Int): Bones? { + for (bone in values()) { + if (bone.bonemealId == itemId) { + return bone + } + } + return null + } + + /** + * Gets the bone ids. + * @return the ids. + */ + val array: IntArray + @JvmStatic get() { + val list: MutableList = ArrayList(20) + for (i in bones.keys) { + list.add(i) + } + return list.toIntArray() + } + + /** + * Get the bone. + * @param itemId The item id. + * @return The bone. + */ + @JvmStatic + fun forId(itemId: Int): Bones? { + return bones[itemId] + } + + /** + * Construct the bones. + */ + init { + for (bone in values()) { + bones[bone.itemId] = bone + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/prayer/PrayerAltarListener.kt b/Server/src/main/content/global/skill/prayer/PrayerAltarListener.kt new file mode 100644 index 0000000..71982f5 --- /dev/null +++ b/Server/src/main/content/global/skill/prayer/PrayerAltarListener.kt @@ -0,0 +1,166 @@ +package content.global.skill.prayer + +import core.api.* +import core.game.event.PrayerPointsRechargeEvent +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength +import core.game.node.Node +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.TeleportManager +import core.game.node.entity.skill.Skills +import core.game.world.map.Location +import org.rs09.consts.Scenery +import org.rs09.consts.Sounds +import content.data.Quests + +class PrayerAltarListener : InteractionListener { + override fun defineListeners() { + on(altars, IntType.SCENERY, "pray", "pray-at") { player, node -> + if (node.id == Scenery.TRIBAL_STATUE_3863 && !hasRequirement(player, Quests.TAI_BWO_WANNAI_TRIO)) { + // https://runescape.wiki/w/Tribal_Statue?oldid=1940922 + return@on true + } + + if (!pray(player, node)) { + if (node.id != Scenery.ELIDINIS_STATUETTE_10439) return@on true + } + + if (node.id == Scenery.ELIDINIS_STATUETTE_10439) { + // https://youtu.be/kEwYhnrQCu8?t=727 & https://youtu.be/b9Wy1JWDes8?t=413 + setTempLevel(player, Skills.HITPOINTS, getStatLevel(player, Skills.HITPOINTS).plus(7)) + sendMessage(player, "You feel much healthier after praying in the shrine.") + } + + if (node.id == Scenery.CHAOS_ALTAR_412) { + lock(player, 4) + queueScript(player, 4, QueueStrength.STRONG) { + sendMessage(player, "It's a trap!") + teleport(player, Location(2583, 9576, 0), TeleportManager.TeleportType.INSTANT) + return@queueScript stopExecuting(player) + } + } + return@on true + } + + on(Scenery.CHAOS_ALTAR_61, IntType.SCENERY, "check") { player, _ -> + if (getQuestStage(player, Quests.MERLINS_CRYSTAL) == 70) { + sendDialogue(player, "You find a small inscription at the bottom of the altar. It reads: 'Snarthon Candtrick Termanto'.") + setQuestStage(player, Quests.MERLINS_CRYSTAL, 80) + } else { + sendMessage(player, "An altar of the evil god Zamorak.") + } + return@on true + } + } + + private fun pray(player: Player, node: Node): Boolean { + val prayerLevel = getStatLevel(player, Skills.PRAYER).plus(if (node.id in boostedAltars) 2 else 0) + + if (player.skills.prayerPoints >= prayerLevel.toDouble()) { + sendMessage(player, "You already have full prayer points.") + return false + } + + lock(player, 3) + animate(player, 645) + playAudio(player, Sounds.PRAYER_RECHARGE_2674) + setTempLevel(player, Skills.PRAYER, prayerLevel) + sendMessage(player, "You recharge your prayer points.") + player.dispatch(PrayerPointsRechargeEvent(node)) + return true + } + + companion object { + private val altars = intArrayOf( + Scenery.ALTAR_409, + Scenery.ALTAR_2478, + Scenery.ALTAR_2479, + Scenery.ALTAR_2480, + Scenery.ALTAR_2481, + Scenery.ALTAR_2482, + Scenery.ALTAR_2483, + Scenery.ALTAR_2484, + Scenery.ALTAR_2485, + Scenery.ALTAR_2486, + Scenery.ALTAR_2487, + Scenery.ALTAR_2488, + Scenery.ALTAR_2489, + Scenery.ALTAR_2640, + Scenery.ALTAR_4008, + Scenery.ALTAR_8749, + Scenery.ALTAR_10639, + Scenery.ALTAR_10640, + Scenery.ALTAR_13179, + Scenery.ALTAR_13180, + Scenery.ALTAR_13181, + Scenery.ALTAR_13182, + Scenery.ALTAR_13183, + Scenery.ALTAR_13184, + Scenery.ALTAR_13185, + Scenery.ALTAR_13186, + Scenery.ALTAR_13187, + Scenery.ALTAR_13188, + Scenery.ALTAR_13189, + Scenery.ALTAR_13190, + Scenery.ALTAR_13191, + Scenery.ALTAR_13192, + Scenery.ALTAR_13193, + Scenery.ALTAR_13194, + Scenery.ALTAR_13195, + Scenery.ALTAR_13196, + Scenery.ALTAR_13197, + Scenery.ALTAR_13198, + Scenery.ALTAR_13199, + Scenery.ALTAR_15050, + Scenery.ALTAR_15051, + Scenery.ALTAR_18254, + Scenery.ALTAR_19145, + Scenery.ALTAR_20377, + Scenery.ALTAR_20378, + Scenery.ALTAR_20379, + Scenery.ALTAR_24343, + Scenery.ALTAR_27306, + Scenery.ALTAR_27307, + Scenery.ALTAR_27308, + Scenery.ALTAR_27309, + Scenery.ALTAR_27334, + Scenery.ALTAR_27338, + Scenery.ALTAR_27339, + Scenery.ALTAR_27661, + Scenery.ALTAR_30624, + Scenery.ALTAR_30726, + Scenery.ALTAR_34616, + Scenery.ALTAR_36972, + Scenery.ALTAR_37630, + Scenery.ALTAR_37901, + Scenery.ALTAR_37902, + Scenery.ALTAR_37903, + Scenery.ALTAR_37904, + Scenery.ALTAR_37905, + Scenery.ALTAR_37906, + Scenery.ALTAR_37907, + Scenery.ALTAR_37908, + Scenery.ALTAR_37909, + Scenery.ALTAR_37910, + Scenery.ALTAR_37911, + Scenery.ALTAR_37912, + Scenery.ALTAR_39547, + Scenery.ALTAR_39842, + Scenery.CHAOS_ALTAR_61, + Scenery.CHAOS_ALTAR_411, + Scenery.CHAOS_ALTAR_412, + Scenery.CHAOS_ALTAR_32079, + Scenery.CHAOS_ALTAR_37990, + Scenery.GORILLA_STATUE_4858, + Scenery.GORILLA_STATUE_4859, + Scenery.ALTAR_OF_GUTHIX_410, + Scenery.ALTAR_OF_GUTHIX_28698, + Scenery.ALTAR_OF_NATURE_3521, + Scenery.TRIBAL_STATUE_3863, + Scenery.ELIDINIS_STATUETTE_10439, + Scenery.DECAYED_ALTAR_37985 + ) + private val boostedAltars = intArrayOf(Scenery.ALTAR_2640, Scenery.ALTAR_OF_NATURE_3521) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/runecrafting/Altar.java b/Server/src/main/content/global/skill/runecrafting/Altar.java new file mode 100644 index 0000000..487d61e --- /dev/null +++ b/Server/src/main/content/global/skill/runecrafting/Altar.java @@ -0,0 +1,194 @@ +package content.global.skill.runecrafting; + +import core.cache.def.impl.ItemDefinition; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; + +import static core.api.ContentAPIKt.hasRequirement; +import content.data.Quests; + +/** + * Represents an altar an it's relative information(corresponding ruin, etc) + * @author 'Vexia + * @date 01/11/2013 + */ +public enum Altar { + AIR(2478, 2465, 7139, MysteriousRuin.AIR, Rune.AIR), + MIND(2479, 2466, 7140, MysteriousRuin.MIND, Rune.MIND), + WATER(2480, 2467, 7137, MysteriousRuin.WATER, Rune.WATER), + EARTH(2481, 2468, 7130, MysteriousRuin.EARTH, Rune.EARTH), + FIRE(2482, 2469, 7129, MysteriousRuin.FIRE, Rune.FIRE), + BODY(2483, 2470, 7131, MysteriousRuin.BODY, Rune.BODY), + COSMIC(2484, 2471, 7132, MysteriousRuin.COSMIC, Rune.COSMIC), + CHAOS(2487, 2474, 7134, MysteriousRuin.CHAOS, Rune.CHAOS), + ASTRAL(17010, 0, 0, null, Rune.ASTRAL), + NATURE(2486, 2473, 7133, MysteriousRuin.NATURE, Rune.NATURE), + LAW(2485, 2472, 7135, MysteriousRuin.LAW, Rune.LAW), + DEATH(2488, 2475, 7136, MysteriousRuin.DEATH, Rune.DEATH), + BLOOD(30624, 2477, 7141, MysteriousRuin.BLOOD, Rune.BLOOD), + SOUL(2489, 0, 7138, null, Rune.SOUL), OURANIA(26847, 0, 0, null, null); + + /** + * Represents the object of the altar. + */ + private final int object; + + /** + * Represents the portal object. + */ + private final int portal; + + /** + * The rift id. + */ + private final int riftId; + + /** + * Represents the corresponding ruin. + */ + private final MysteriousRuin ruin; + + /** + * Represents the rune constructed. + */ + private final Rune rune; + + /** + * Constructs a new {@code Altar} {@code Object}. + * @param object the object. + * @param ruin the ruin. + * @param rune the rune. + */ + Altar(final int object, final int portal, final int riftId, final MysteriousRuin ruin, final Rune rune) { + this.object = object; + this.portal = portal; + this.riftId = riftId; + this.ruin = ruin; + this.rune = rune; + } + + /** + * Enters a rift. + * @param player the player. + */ + public void enterRift(Player player) { + if (this == ASTRAL) { + if (!hasRequirement(player, Quests.LUNAR_DIPLOMACY)) + return; + } + if (this == DEATH) { + if (!hasRequirement(player, Quests.MOURNINGS_END_PART_II)) + return; + } + if (this == BLOOD) { + if (!hasRequirement(player, Quests.LEGACY_OF_SEERGAZE)) + return; + } + if (this == LAW) { + if (!ItemDefinition.canEnterEntrana(player)) { + player.sendMessage("The power of Saradomin prevents you from taking armour or weaponry to Entrana."); + return; + } + } + if (this == COSMIC && !player.getQuestRepository().isComplete(Quests.LOST_CITY)) { + player.getPacketDispatch().sendMessage("You need to have completed the Lost City quest in order to do that."); + return; + } + if (getRuin() == null) { + return; + } + if (getRuin().getEnd() == null) { + return; + } + player.getProperties().setTeleportLocation(getRuin().getEnd()); + } + + /** + * Gets the object. + * @return The object. + */ + public int getObject() { + return object; + } + + /** + * Gets the ruin. + * @return The ruin. + */ + public MysteriousRuin getRuin() { + return ruin; + } + + /** + * Gets the rune. + * @return The rune. + */ + public Rune getRune() { + return rune; + } + + /** + * Checks if its the ourania altar. + * @return the ourania. + */ + public boolean isOurania() { + return getRune() == null; + } + + /** + * Gets the talisman. + * @return the talisman. + */ + public Talisman getTalisman() { + for (Talisman talisman : Talisman.values()) { + if (talisman.name().equals(name())) { + return talisman; + } + } + return null; + } + + /** + * Gets the tiara. + * @return the tiara. + */ + public Tiara getTiara() { + for (Tiara tiara : Tiara.values()) { + if (tiara.name().equals(name())) { + return tiara; + } + } + return null; + } + + /** + * Method used to get the Altar by the object. + * @param object the object. + * @return the Altar or Null. + */ + public static Altar forObject(final Scenery object) { + for (Altar altar : values()) { + if (altar.getObject() == object.getId() || altar.getPortal() == object.getId() || object.getId() == altar.getRiftId()) { + return altar; + } + } + return null; + } + + /** + * Gets the portal. + * @return The portal. + */ + public int getPortal() { + return portal; + } + + /** + * Gets the riftId. + * @return The riftId. + */ + public int getRiftId() { + return riftId; + } + +} diff --git a/Server/src/main/content/global/skill/runecrafting/CombinationRune.java b/Server/src/main/content/global/skill/runecrafting/CombinationRune.java new file mode 100644 index 0000000..62760bf --- /dev/null +++ b/Server/src/main/content/global/skill/runecrafting/CombinationRune.java @@ -0,0 +1,130 @@ +package content.global.skill.runecrafting; + +import core.game.node.item.Item; + +/** + * Represents the combination rune. + * @author 'Vexia + */ +public enum CombinationRune { + MIST(new Item(4695), 6, 8.0, new Altar[] { Altar.WATER, Altar.AIR }, Rune.AIR, Rune.WATER), + DUST(new Item(4696), 10, 8.3, new Altar[] { Altar.EARTH, Altar.AIR }, Rune.AIR, Rune.EARTH), + MUD(new Item(4698), 13, 9.3, new Altar[] { Altar.EARTH, Altar.WATER }, Rune.WATER, Rune.EARTH), + SMOKE(new Item(4697), 15, 8.5, new Altar[] { Altar.FIRE, Altar.AIR }, Rune.AIR, Rune.FIRE), + STEAM(new Item(4694), 19, 9.3, new Altar[] { Altar.WATER, Altar.FIRE }, Rune.WATER, Rune.FIRE), + LAVA(new Item(4699), 23, 10.0, new Altar[] { Altar.FIRE, Altar.EARTH }, Rune.EARTH, Rune.FIRE); + + /** + * Represents the rune rewarded. + */ + private final Item rune; + + /** + * Represents the required level. + */ + private final int level; + + /** + * Represents the base experience. + */ + private final double experience; + + /** + * Represents the altars. + */ + private final Altar[] altars; + + /** + * Represents the runes required. + */ + private final Rune[] runes; + + /** + * Constructs a new {@code CombinationRune} {@code Object}. + * @param rune the rune. + * @param level the level. + * @param experience the base experience/ + * @param runes the runes. + */ + CombinationRune(final Item rune, final int level, final double experience, final Altar[] altars, final Rune... runes) { + this.rune = rune; + this.level = level; + this.experience = experience; + this.altars = altars; + this.runes = runes; + } + + /** + * Gets the rune. + * @return The rune. + */ + public final Item getRune() { + return rune; + } + + /** + * Gets the level. + * @return The level. + */ + public final int getLevel() { + return level; + } + + /** + * Gets the experience. + * @return The experience. + */ + public final double getExperience() { + return experience; + } + + /** + * Gets the runes. + * @return The runes. + */ + public final Rune[] getRunes() { + return runes; + } + + /** + * Method used to get the high experience. + * @return the experience incremented. + */ + public final double getHighExperience() { + return (experience % 1 == 0) ? experience + 5 : experience + 8; + } + + /** + * Gets the altars. + * @return The altars. + */ + public Altar[] getAltars() { + return altars; + } + + /** + * Gets the combination rune. + * @param altar the altar. + * @return the combo rune. + */ + public static CombinationRune forAltar(final Altar altar, final Item item) { + for (CombinationRune rune : values()) { + for (Altar alt : rune.getAltars()) { + if (alt == altar) { + String altarElement = alt.name(); + String talismanElement = item.getName().contains("talisman") ? Talisman.forItem(item).name() : Rune.forItem(item).name(); + if (altarElement.equals(talismanElement)) { + continue; + } + for (Rune r : rune.getRunes()) { + if (r.name().equals(talismanElement)) { + return rune; + } + } + continue; + } + } + } + return null; + } +} diff --git a/Server/src/main/content/global/skill/runecrafting/CombinationRunePlugin.java b/Server/src/main/content/global/skill/runecrafting/CombinationRunePlugin.java new file mode 100644 index 0000000..bcfb0d2 --- /dev/null +++ b/Server/src/main/content/global/skill/runecrafting/CombinationRunePlugin.java @@ -0,0 +1,42 @@ +package content.global.skill.runecrafting; + +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.plugin.Plugin; + +/** + * Handles the combination runes. + * @author Vexia + */ +public final class CombinationRunePlugin extends UseWithHandler { + + /** + * Constructs a new {@code CombinationRunePlugin} {@code Object}. + */ + public CombinationRunePlugin() { + super(Talisman.AIR.getTalisman().getId(), Talisman.WATER.getTalisman().getId(), Talisman.EARTH.getTalisman().getId(), Talisman.FIRE.getTalisman().getId(), Rune.WATER.getRune().getId(), Rune.EARTH.getRune().getId(), Rune.AIR.getRune().getId(), Rune.FIRE.getRune().getId()); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (Altar altar : Altar.values()) { + addHandler(altar.getObject(), OBJECT_TYPE, this); + } + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + final Altar altar = Altar.forObject(((Scenery) event.getUsedWith())); + final CombinationRune combo = CombinationRune.forAltar(altar, event.getUsedItem()); + if (combo == null) { + return false; + } + player.getPulseManager().run(new RuneCraftPulse(player, event.getUsedItem(), altar, true, combo)); + return true; + } + +} diff --git a/Server/src/main/content/global/skill/runecrafting/EnchantTiaraDialogue.java b/Server/src/main/content/global/skill/runecrafting/EnchantTiaraDialogue.java new file mode 100644 index 0000000..6c596bf --- /dev/null +++ b/Server/src/main/content/global/skill/runecrafting/EnchantTiaraDialogue.java @@ -0,0 +1,97 @@ +package content.global.skill.runecrafting; + +import static core.api.ContentAPIKt.*; + +import core.game.dialogue.DialoguePlugin; +import core.plugin.Initializable; +import core.game.interaction.NodeUsageEvent; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import kotlin.Unit; + +/** + * Represents the enchant tiara dialogue. + * @author Vexia + * @version 1.0 + */ +@Initializable +public final class EnchantTiaraDialogue extends DialoguePlugin { + + /** + * Represents the node usage event. + */ + private NodeUsageEvent event; + + /** + * The altar. + */ + private Altar altar; + + /** + * Constructs a new {@code EnchantTiaraDialogue} {@code Object}. + */ + public EnchantTiaraDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code EnchantTiaraDialogue} {@code Object}. + * @param player the player. + */ + public EnchantTiaraDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new EnchantTiaraDialogue(player); + } + + @Override + public boolean open(Object... args) { + event = ((NodeUsageEvent) args[0]); + altar = Altar.forObject(((Scenery) event.getUsedWith())); + if (!player.getInventory().containsItem(altar.getTalisman().getTalisman())) { + player.getPacketDispatch().sendMessage("You don't have the required talisman."); + return true; + } + player.getInterfaceManager().openChatbox(309); + player.getPacketDispatch().sendString("



" + altar.getTiara().getTiara().getName(), 309, 6); + player.getPacketDispatch().sendItemZoomOnInterface(altar.getTiara().getTiara().getId(), 175, 309, 2); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + int amt = 0; + // ButtonId 5=1x, 4=5x, 3=MakeX, 2=All + switch (buttonId) { + case 5: + amt = 1; + break; + case 4: + amt = 5; + break; + case 3: + end() +; sendInputDialogue(player, true, "Enter the amount:", (value) -> { + player.getPulseManager().run(new EnchantTiaraPulse(player, event.getUsedItem(), altar ,Talisman.forItem(event.getUsedItem()).getTiara(), (int) value)); + return Unit.INSTANCE; + }); + return true; + case 2: + amt = player.getInventory().getAmount(event.getUsedItem()); + break; + } + player.getPulseManager().run(new EnchantTiaraPulse(player, event.getUsedItem(), altar ,altar.getTiara(), amt)); + end(); + return true; + } + + @Override + public int[] getIds() { + return new int[] { 8432482 }; + } +} diff --git a/Server/src/main/content/global/skill/runecrafting/EnchantTiaraPlugin.java b/Server/src/main/content/global/skill/runecrafting/EnchantTiaraPlugin.java new file mode 100644 index 0000000..f15985d --- /dev/null +++ b/Server/src/main/content/global/skill/runecrafting/EnchantTiaraPlugin.java @@ -0,0 +1,41 @@ +package content.global.skill.runecrafting; + +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.plugin.Plugin; + +/** + * Handles the tiara enchanting. + * @author Vexia + */ +public final class EnchantTiaraPlugin extends UseWithHandler { + + /** + * Constructs a new {@code EnchantTiaraPlugin} {@code Object}. + */ + public EnchantTiaraPlugin() { + super(1438, 1448, 1444, 1440, 1442, 5516, 1446, 1454, 1452, 1462, 1458, 1456, 1450, 1460, 5525); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (Altar altar : Altar.values()) { + addHandler(altar.getObject(), OBJECT_TYPE, this); + } + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + Player player = event.getPlayer(); + Altar altar = Altar.forObject(((Scenery) event.getUsedWith())); + if (!player.getInventory().containsItem(altar.getTalisman().getTalisman())) { + return false; + } + event.getPlayer().getDialogueInterpreter().open(8432482, event); + return true; + } + +} diff --git a/Server/src/main/content/global/skill/runecrafting/EnchantTiaraPulse.java b/Server/src/main/content/global/skill/runecrafting/EnchantTiaraPulse.java new file mode 100644 index 0000000..542d776 --- /dev/null +++ b/Server/src/main/content/global/skill/runecrafting/EnchantTiaraPulse.java @@ -0,0 +1,116 @@ +package content.global.skill.runecrafting; + +import core.game.node.entity.impl.Animator; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.scenery.Scenery; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.game.node.entity.skill.SkillPulse; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +import java.util.Objects; + +import static java.lang.Math.min; + +/** + * Represents the enchanting of a tiara pulse. + * @author 'Vexia + */ +public class EnchantTiaraPulse extends SkillPulse { + + /** + * Represents the Altar. + */ + private final Altar altar; + + /** + * Represents the tiara. + */ + private final Tiara tiara; + + /** + * Represents the item tiara. + */ + private final Item TIARA = new Item(5525); + + private static final Animation ANIMATION = new Animation(791, Animator.Priority.HIGH); + private static final Graphics GRAPHICS = new Graphics(186, 100); + + /** + * Represents the amount. + */ + private int amount; + + /** + * Constructs a new {@code EnchantTiaraPulse.java} {@code Object}. + * @param player the player. + * @param node the node. + */ + public EnchantTiaraPulse(Player player, Item node, final Altar altar, final Tiara tiara, final int amount) { + super(player, node); + this.tiara = tiara; + this.amount = amount; + this.altar = altar; + } + + @Override + public void start() { + super.start(); + int tiaraAmt = player.getInventory().getAmount(TIARA); // Plain Silver Tiara + int talismanAmt = player.getInventory().getAmount(tiara.getTalisman().getTalisman()); // specific talisman being fused, "node" is all various talismans in inventory + String talismanType = tiara.getTalisman().getTalisman().getName().toLowerCase(); + String altarType = altar.getRuin().name().toLowerCase(); + // Check that the talisman type and the alter type match + if ( talismanType.contains(altarType) ){ + amount = min(talismanAmt, min(tiaraAmt, amount)); + } + + } + + @Override + public boolean checkRequirements() { + if (!player.getInventory().containsItem(TIARA)) { + player.getPacketDispatch().sendMessage("You need a tiara."); + return false; + } + return true; + } + + @Override + public void animate() { + player.animate(ANIMATION); + player.graphics(GRAPHICS); + } + + @Override + public boolean reward() { + if (getDelay() == 1) { + setDelay(2); + return false; + } + if (player.getInventory().remove(TIARA) && player.getInventory().remove(tiara.getTalisman().getTalisman())) { + player.getInventory().add(tiara.getTiara()); + player.getSkills().addExperience(Skills.RUNECRAFTING, tiara.getExperience(), true); + + if (tiara == Tiara.AIR) { + player.getAchievementDiaryManager().finishTask(player, DiaryType.FALADOR, 0, 11); + } + // Craft an earth tiara on the Earth Altar + if (tiara == Tiara.EARTH) { + player.getAchievementDiaryManager().finishTask(player, DiaryType.VARROCK, 1, 11); + } + } + amount--; + return amount == 0; + } + + @Override + public void message(int type) { + if (type == 1) { + player.getPacketDispatch().sendMessage("You bind the power of the talisman into your tiara."); + } + } + +} diff --git a/Server/src/main/content/global/skill/runecrafting/MysteriousRuin.java b/Server/src/main/content/global/skill/runecrafting/MysteriousRuin.java new file mode 100644 index 0000000..41089d2 --- /dev/null +++ b/Server/src/main/content/global/skill/runecrafting/MysteriousRuin.java @@ -0,0 +1,146 @@ +package content.global.skill.runecrafting; + +import core.game.node.scenery.Scenery; +import core.game.world.map.Location; + +/** + * Represents a mysterious ruin. + * @author 'Vexia + * @date 01/11/2013 + */ +public enum MysteriousRuin { + AIR(new int[] { 2452, 7103, 7104 }, Location.create(2983, 3292, 0), Location.create(2841, 4829, 0), Talisman.AIR, Tiara.AIR), + MIND(new int[] { 2453, 7105, 7106 }, Location.create(2980, 3514, 0), Location.create(2793, 4828, 0), Talisman.MIND, Tiara.MIND), + WATER(new int[] { 2454, 7107, 7108 }, Location.create(3183, 3163, 0), Location.create(3482 ,4838,0), Talisman.WATER, Tiara.WATER), + EARTH(new int[] { 2455, 7109, 7110 }, Location.create(3304, 3475, 0), Location.create(2655, 4830, 0), Talisman.EARTH, Tiara.EARTH), + FIRE(new int[] { 2456, 7111, 7112 }, Location.create(3312, 3253, 0), Location.create(2574, 4849, 0), Talisman.FIRE, Tiara.FIRE), + BODY(new int[] { 2457, 7113, 7114 }, Location.create(3051, 3443, 0), Location.create(2521, 4834, 0), Talisman.BODY, Tiara.BODY), + COSMIC(new int[] { 2458, 7115, 7116 }, Location.create(2406, 4375, 0), Location.create(2162, 4833, 0), Talisman.COSMIC, Tiara.COSMIC), + CHAOS(new int[] { 2461, 7121, 7122 }, Location.create(3059, 3590, 0), Location.create(2281, 4837, 0), Talisman.CHAOS, Tiara.CHAOS), + NATURE(new int[] { 2460, 7119, 7120 }, Location.create(2869, 3021, 0), Location.create(2400, 4835, 0), Talisman.NATURE, Tiara.NATURE), + LAW(new int[] { 2459, 7117, 7118 }, Location.create(2857, 3379, 0), Location.create(2464, 4819, 0), Talisman.LAW, Tiara.LAW), + DEATH(new int[] { 2462, 7123, 7124 }, Location.create(1862, 4639, 0), Location.create(2208, 4830, 0), Talisman.DEATH, Tiara.DEATH), + BLOOD(new int[] { 2464, 30529, 30530 }, Location.create(3561, 9779, 0), Location.create(2467, 4889, 1), Talisman.BLOOD, Tiara.BLOOD); + + /** + * Represents the object id. + */ + private final int[] object; + + /** + * Represents the base location. + */ + private final Location base; + + /** + * Represents the end location. + */ + private final Location end; + + /** + * Represents the talisman. + */ + private final Talisman talisman; + + /** + * Represents the tiara. + */ + private final Tiara tiara; + + /** + * Constructs a new {@code MysteriousRuin} {@code Object}. + * @param object the object. + * @param base the base. + * @param end the end. + * @param talisman the talisman. + * @param tiara the tiara. + */ + MysteriousRuin(int[] object, Location base, Location end, final Talisman talisman, final Tiara tiara) { + this.object = object; + this.base = base; + this.end = end; + this.talisman = talisman; + this.tiara = tiara; + } + + /** + * Gets the object. + * @return The object. + */ + public int[] getObject() { + return object; + } + + /** + * Gets the base. + * @return The base. + */ + public Location getBase() { + return base; + } + + /** + * Gets the end. + * @return The end. + */ + public Location getEnd() { + return end; + } + + /** + * Gets the talisman. + * @return The talisman. + */ + public Talisman getTalisman() { + for (Talisman talisman : Talisman.values()) { + if (talisman.name().equals(name())) { + return talisman; + } + } + return talisman; + } + + /** + * Gets the tiara. + * @return The tiara. + */ + public Tiara getTiara() { + for (Tiara tiara : Tiara.values()) { + if (tiara.name().equals(name())) { + return tiara; + } + } + return tiara; + } + + /** + * Method used to get the MysteriousRuin by the object. + * @param object the object. + * @return the MysteriousRuin or Null. + */ + public static MysteriousRuin forObject(final Scenery object) { + for (MysteriousRuin ruin : values()) { + for (int i : ruin.getObject()) { + if (i == object.getId()) { + return ruin; + } + } + } + return null; + } + + /** + * Method used to get the MysteriousRuin + * @param talisman the talisman. + * @return the MysteriousRuin. + */ + public static MysteriousRuin forTalisman(final Talisman talisman) { + for (MysteriousRuin ruin : values()) { + if (ruin.getTalisman() == talisman) { + return ruin; + } + } + return null; + } + +} diff --git a/Server/src/main/content/global/skill/runecrafting/MysteriousRuinListener.kt b/Server/src/main/content/global/skill/runecrafting/MysteriousRuinListener.kt new file mode 100644 index 0000000..7bf55dd --- /dev/null +++ b/Server/src/main/content/global/skill/runecrafting/MysteriousRuinListener.kt @@ -0,0 +1,106 @@ +package content.global.skill.runecrafting + +import content.data.Quests +import content.region.misthalin.varrock.diary.VarrockAchivementDiary.Companion.EasyTasks.ENTER_EARTH_ALTAR +import core.api.* +import core.game.container.impl.EquipmentContainer.SLOT_HAT +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.Node +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.diary.DiaryType +import core.game.node.item.Item +import core.game.requirement.QuestReq +import core.game.requirement.QuestRequirements.* +import core.game.system.task.Pulse +import core.game.world.update.flag.context.Animation + +class MysteriousRuinListener : InteractionListener { + + private val animation = Animation(827) + private val allowedUsed = arrayOf(1438, 1448, 1444, 1440, 1442, 5516, 1446, 1454, 1452, 1462, 1458, 1456, 1450, 1460).toIntArray() + private val allowedWith = allRuins() + private val nothingInteresting = "Nothing interesting happens." + + override fun defineListeners() { + onUseWith(IntType.SCENERY, allowedUsed, *allowedWith) { player, used, with -> + return@onUseWith handleTalisman(player, used, with) + } + on(allowedWith, IntType.SCENERY, "enter") { player, node -> + return@on handleTiara(player, node) + } + } + + private fun allRuins(): IntArray { + return MysteriousRuin + .values() + .flatMap { ruins -> ruins.`object`.asList() } + .toIntArray() + } + + private fun handleTalisman(player: Player, used: Node, with: Node): Boolean { + val ruin = MysteriousRuin.forObject(with.asScenery()) + if (!checkQuestCompletion(player, ruin)) { + return true + } + + val talisman = Talisman.forItem(used.asItem()) + if (talisman != ruin.talisman && talisman != Talisman.ELEMENTAL) { + sendMessage(player, nothingInteresting) + return false + } + if (talisman == Talisman.ELEMENTAL && (ruin.talisman != Talisman.AIR && ruin.talisman != Talisman.WATER && ruin.talisman != Talisman.FIRE && ruin.talisman != Talisman.EARTH)) { + sendMessage(player, nothingInteresting) + return false + } + + teleportToRuinTalisman(player, used.asItem(), ruin) + return true + } + + private fun handleTiara(player: Player, node: Node): Boolean { + val ruin = MysteriousRuin.forObject(node.asScenery()) + + if (!checkQuestCompletion(player, ruin)) { + return true + } + + val tiara = Tiara.forItem(player.equipment.get(SLOT_HAT)) + if (tiara == null || tiara != ruin.tiara) { + sendMessage(player, nothingInteresting) + return false + } + + submitTeleportPulse(player, ruin, 0) + return true + } + + private fun checkQuestCompletion(player: Player, ruin: MysteriousRuin): Boolean { + return when (ruin) { + MysteriousRuin.DEATH -> hasRequirement(player, Quests.MOURNINGS_END_PART_II, true) + MysteriousRuin.BLOOD -> hasRequirement(player, Quests.LEGACY_OF_SEERGAZE, true) + else -> hasRequirement(player, Quests.RUNE_MYSTERIES, true) + } + } + + private fun teleportToRuinTalisman(player: Player, talisman: Item, ruin: MysteriousRuin) { + lock(player, 4) + animate(player, animation) + sendMessage(player, "You hold the ${talisman.name} towards the mysterious ruins.") + submitTeleportPulse(player, ruin, 3) + } + + private fun submitTeleportPulse(player: Player, ruin: MysteriousRuin, delay: Int) { + sendMessage(player, "You feel a powerful force take hold of you.") + submitWorldPulse(object : Pulse(delay, player) { + override fun pulse(): Boolean { + teleport(player, ruin.end) + if (ruin == MysteriousRuin.EARTH) { + player.achievementDiaryManager.finishTask(player, DiaryType.VARROCK, 0, ENTER_EARTH_ALTAR) + } + return true + } + }) + } + +} diff --git a/Server/src/main/content/global/skill/runecrafting/PouchManager.kt b/Server/src/main/content/global/skill/runecrafting/PouchManager.kt new file mode 100644 index 0000000..22cc186 --- /dev/null +++ b/Server/src/main/content/global/skill/runecrafting/PouchManager.kt @@ -0,0 +1,216 @@ +package content.global.skill.runecrafting + +import core.api.* +import core.game.container.Container +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import org.json.simple.JSONArray +import org.json.simple.JSONObject +import org.rs09.consts.Items + +/** + * A class for managing rune pouches. + * @param player the player this manager instance belongs to. + * @author Ceikry, Player Name + */ +class PouchManager(val player: Player) { + val pouches = mapOf( + Items.SMALL_POUCH_5509 to RCPouch(3, 3, 1), + Items.MEDIUM_POUCH_5510 to RCPouch(6, 264, 25), + Items.LARGE_POUCH_5512 to RCPouch(9, 186, 50), + Items.GIANT_POUCH_5514 to RCPouch(12,140, 75) + ) + + /** + * Method to add essence to a pouch + * @param itemId the item ID of the pouch we are adding to + * @param amount the amount of essence to add + * @param essence the ID of the essence item we are trying to add + * @author Ceikry, Player Name + */ + fun addToPouch(itemId: Int, amount: Int, essence: Int) { + val pouchId = if (isDecayedPouch(itemId)) itemId - 1 else itemId + if (!checkRequirement(pouchId)) { + sendMessage(player, "You lack the required level to use this pouch.") + return + } + var amt = amount + val pouch = pouches[pouchId] + val otherEssence = when(essence) { + Items.RUNE_ESSENCE_1436 -> Items.PURE_ESSENCE_7936 + Items.PURE_ESSENCE_7936 -> Items.RUNE_ESSENCE_1436 + else -> 0 + } + pouch ?: return + if (amount > pouch.container.freeSlots()) { + amt = pouch.container.freeSlots() + } + if (amt == pouch.container.freeSlots()) { + sendMessage(player, "Your pouch is full.") //https://www.youtube.com/watch?v=wbYtRwODKTo + } + if (pouch.container.contains(otherEssence,1)) { + sendMessage(player, "You can only store one type of essence in each pouch.") + return + } + + var disappeared = false + if (itemId != Items.SMALL_POUCH_5509) { + pouch.charges -= amt + } + if (pouch.charges <= 0) { + pouch.currentCap -= when (pouchId) { + Items.MEDIUM_POUCH_5510 -> 1 + Items.LARGE_POUCH_5512 -> 2 + Items.GIANT_POUCH_5514 -> 3 + else /*small pouch*/ -> 0 + } + if (pouch.currentCap <= 0) { + // The pouch will disappear: https://runescape.wiki/w/Runecrafting_pouches?oldid=708494, https://oldschool.runescape.wiki/w/Essence_pouch + // "Degraded pouches will continue to degrade and lose essence capacity until they disappear or are repaired." implies that this is the end result of a gradual decay process + if (removeItem(player, itemId)) { + disappeared = true + sendMessage(player, "Your pouch has degraded completely.") + // Reset the pouch for when the player obtains a new one + pouch.currentCap = pouch.capacity + pouch.charges = pouch.maxCharges + pouch.remakeContainer() + replaceAllItems(player, itemId, itemId - 1) //in case the player had more copies + } + } else { + if (!isDecayedPouch(itemId)) { + replaceAllItems(player, itemId, itemId + 1) + } + sendMessage(player, "Your pouch has decayed through use.") //https://www.youtube.com/watch?v=FUcPYrgPUlQ + pouch.charges = 9 * pouch.currentCap //implied by multiple contemporaneous sources, quantified only by https://oldschool.runescape.wiki/w/Large_pouch + pouch.remakeContainer() + if (amt > pouch.currentCap) { + amt = pouch.currentCap + } + } + } + val essItem = Item(essence, amt) + if (!disappeared && removeItem(player, essItem)) { + pouch.container.add(essItem) + } + } + + /** + * Method to withdraw rune essence from a pouch. + * @param itemId the item ID of the pouch to withdraw from + * @author Ceikry, Player Name + */ + fun withdrawFromPouch(itemId: Int) { + val pouchId = if (isDecayedPouch(itemId)) itemId - 1 else itemId + val pouch = pouches[pouchId] + pouch ?: return + val playerFree = freeSlots(player) + var amount = pouch.currentCap - pouch.container.freeSlots() + if (amount > playerFree) { + amount = playerFree + } else { + sendMessage(player, "Your pouch has no essence left in it.") //https://www.youtube.com/watch?v=wbYtRwODKTo + if (amount == 0) { + return + } + } + val essence = Item(pouch.container.get(0).id, amount) + pouch.container.remove(essence) + pouch.container.shift() + addItem(player, essence.id, essence.amount) + } + + /** + * Method to save pouches to a root JSONObject + * @param root the JSONObject we are adding the "pouches" JSONArray to + * @author Ceikry + */ + fun save(root: JSONObject) { + val pouches = JSONArray() + + for(i in this.pouches) { + val pouch = JSONObject() + pouch.put("id",i.key.toString()) + val items = JSONArray() + for(item in i.value.container.toArray()) { + item ?: continue + val it = JSONObject() + it.put("itemId",item.id.toString()) + it.put("amount",item.amount.toString()) + items.add(it) + } + pouch.put("container",items) + pouch.put("charges",i.value.charges.toString()) + pouch.put("currentCap",i.value.currentCap.toString()) + pouches.add(pouch) + } + root.put("pouches",pouches) + } + + /** + * Method to parse save data from a JSONArray + * @param data the JSONArray that contains the data to parse + * @author Ceikry + */ + fun parse(data: JSONArray) { + for (e in data){ + val pouch = e as JSONObject + val id = pouch["id"].toString().toInt() + val p = pouches[id] + p ?: return + val charges = pouch["charges"].toString().toInt() + val currentCap = pouch["currentCap"].toString().toInt() + p.charges = charges + p.currentCap = currentCap + p.remakeContainer() + for (i in pouch["container"] as JSONArray) { + val it = i as JSONObject + it["itemId"] ?: continue + val item = it["itemId"].toString().toInt() + val amount = it["amount"].toString().toInt() + p.container.add(Item(item,amount)) + } + } + } + + /** + * Method for checking the level requirement for a given pouch. + * @param pouchId the item ID of the pouch to check + * @author Ceikry + */ + fun checkRequirement(pouchId: Int): Boolean { + val p = pouches[pouchId] + p ?: return false + return player.skills.getLevel(Skills.RUNECRAFTING) >= p.levelRequirement + } + + /** + * Method for sending the player a message about how much space is left in a pouch + * @param itemId the item ID of the pouch to check + * @author Ceikry, Player Name + */ + fun checkAmount(itemId: Int) { + val pouchId = if (isDecayedPouch(itemId)) itemId - 1 else itemId + val p = pouches[pouchId] + p ?: return + player.sendMessage("This pouch has space for ${p.container.freeSlots()} more essence.") + } + + fun isDecayedPouch(pouchId: Int): Boolean { + if (pouchId == Items.MEDIUM_POUCH_5510) return false + return pouches[pouchId - 1] != null + } + + /** + * A class that represents a runecrafting pouch. + * @author Ceikry + */ + class RCPouch(val capacity: Int, val maxCharges: Int, val levelRequirement: Int) { + var container = Container(capacity) + var currentCap = capacity + var charges = maxCharges + fun remakeContainer() { + this.container = Container(currentCap) + } + } +} diff --git a/Server/src/main/content/global/skill/runecrafting/Rune.java b/Server/src/main/content/global/skill/runecrafting/Rune.java new file mode 100644 index 0000000..7736c57 --- /dev/null +++ b/Server/src/main/content/global/skill/runecrafting/Rune.java @@ -0,0 +1,136 @@ +package content.global.skill.runecrafting; + +import core.game.node.entity.combat.spell.Runes; +import core.game.node.item.Item; + +/** + * Represents a Rune type to craft. + * @author 'Vexia + * @date 01/11/2013 + */ +public enum Rune { + AIR(Runes.AIR_RUNE.transform(), 1, 5, new int[] { 1, 11, 22, 33, 44, 55, 66, 77, 88, 99, 110 }), + MIND(Runes.MIND_RUNE.transform(), 2, 5.5, new int[] { 1, 14, 28, 42, 56, 70, 84, 98, 112 }), + WATER(Runes.WATER_RUNE.transform(), 5, 6, new int[] { 1, 19, 38, 57, 76, 95, 114 }), + EARTH(Runes.EARTH_RUNE.transform(), 9, 6.5, new int[] { 1, 26, 52, 78, 104 }), + FIRE(Runes.FIRE_RUNE.transform(), 14, 7, new int[] { 1, 35, 70, 105 }), + BODY(Runes.BODY_RUNE.transform(), 20, 7.5, new int[] { 1, 46, 92, 138 }), + COSMIC(Runes.COSMIC_RUNE.transform(), 27, 8, new int[] { 1, 59, 118 }), + CHAOS(Runes.CHAOS_RUNE.transform(), 35, 8.5, new int[] { 1, 74, 148 }), + ASTRAL(Runes.ASTRAL_RUNE.transform(), 40, 8.7, new int[] { 1, 82, 164 }), + NATURE(Runes.NATURE_RUNE.transform(), 44, 9, new int[] { 1, 91, 182 }), + LAW(Runes.LAW_RUNE.transform(), 54, 9.5, new int[] { 1, 110, }), + DEATH(Runes.DEATH_RUNE.transform(), 65, 10, new int[] { 1, 131 }), + BLOOD(Runes.BLOOD_RUNE.transform(), 77, 10.5, new int[] { 1, 154 }), + SOUL(Runes.SOUL_RUNE.transform(), 90, 11); + + /** + * Constructs a new {@code Rune} {@code Object}. + * @param rune the rune. + * @param level the level. + * @param experience the experience. + * @param multiple + */ + Rune(Item rune, int level, double experience, int... multiple) { + this.rune = rune; + this.level = level; + this.experience = experience; + this.multiple = multiple; + } + + /** + * Represents the rune item to craft. + */ + private final Item rune; + + /** + * Represents the level required. + */ + private final int level; + + /** + * Represents the experience gained. + */ + private final double experience; + + /** + * Represents the multiple runes allowed to create at a certain level. + */ + private final int[] multiple; + + /** + * Gets the rune. + * @return The rune. + */ + public Item getRune() { + return rune; + } + + /** + * Gets the level. + * @return The level. + */ + public int getLevel() { + return level; + } + + /** + * Gets the experience. + * @return The experience. + */ + public double getExperience() { + return experience; + } + + /** + * Gets the multiple. + * @return The multiple. + */ + public int[] getMultiple() { + return multiple; + } + + /** + * Checks if this rune uses normal essence. + * @return True if so. + */ + public final boolean isNormal() { + return this == AIR || this == MIND || this == WATER || this == EARTH || this == FIRE || this == BODY; + } + + /** + * Checks if this rune is a multi creation rune. + * @return True if so. + */ + public final boolean isMultiple() { + return getMultiple() != null; + } + + /** + * Method used to get the Rune by the item. + * @param item the item. + * @return the Rune or Null. + */ + public static Rune forItem(final Item item) { + for (Rune rune : values()) { + if (rune.getRune().getId() == item.getId()) { + return rune; + } + } + return null; + } + + /** + * Method used to the Rune by the name. + * @param name the name. + * @return the Rune or Null. + */ + public static Rune forName(final String name) { + for (Rune r : Rune.values()) { + if (r.name().equals(name)) { + return r; + } + } + return null; + } +} diff --git a/Server/src/main/content/global/skill/runecrafting/RuneCraftPulse.java b/Server/src/main/content/global/skill/runecrafting/RuneCraftPulse.java new file mode 100644 index 0000000..c9fa23e --- /dev/null +++ b/Server/src/main/content/global/skill/runecrafting/RuneCraftPulse.java @@ -0,0 +1,376 @@ +package content.global.skill.runecrafting; + +import content.global.handlers.item.equipment.fistofguthixgloves.FOGGlovesManager; +import core.ServerConstants; +import core.api.Container; +import core.game.container.impl.EquipmentContainer; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.entity.skill.SkillPulse; +import core.game.node.entity.skill.Skills; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.tools.RandomFunction; + +import static core.api.ContentAPIKt.*; +import static core.game.system.command.sets.StatAttributeKeysKt.STATS_BASE; +import static core.game.system.command.sets.StatAttributeKeysKt.STATS_RC; + +import core.game.world.GameWorld; +import org.rs09.consts.Items; +import org.rs09.consts.Sounds; + +import java.util.ArrayList; +import java.util.Arrays; +import content.data.Quests; + +/** + * A class used to craft runes. + * + * @author Vexia + * @author Player Name + */ +public final class RuneCraftPulse extends SkillPulse { + + /** + * Represent the rune essence item. + */ + private static final Item RUNE_ESSENCE = new Item(1436); + + /** + * Represents the pure essence item. + */ + private static final Item PURE_ESSENCE = new Item(7936); + + /** + * Represents the binding necklace item. + */ + private static final Item BINDING_NECKLACE = new Item(5521); + + /** + * Represents the animation used for this pulse. + */ + private static final Animation ANIMATION = new Animation(791, Priority.HIGH); + + /** + * Represents the graphics used for this pulse. + */ + private static final Graphics GRAPHICS = new Graphics(186, 100); + + /** + * Represents the altar. + */ + private final Altar altar; + + /** + * Represents the rune we're crafting. + */ + private final Rune rune; + + /** + * Represents the combination rune(if any) + */ + private final CombinationRune combo; + + /** + * Represents if it's a combination pulse. + */ + private final boolean combination; + + /** + * Represents the talisman to remove. + */ + private Talisman talisman; + + /** + * Constructs a new {@code RuneCraftPulse} {@code Object}. + * + * @param player the player. + * @param node the node. + * @param altar the altar. + */ + public RuneCraftPulse(Player player, Item node, final Altar altar, final boolean combination, final CombinationRune combo) { + super(player, node); + this.altar = altar; + this.rune = altar.getRune(); + this.combination = combination; + this.combo = combo; + this.resetAnimation = false; + } + + @Override + public boolean checkRequirements() { + if (altar == Altar.ASTRAL) { + if (!hasRequirement(player, Quests.LUNAR_DIPLOMACY)) + return false; + } + if (altar == Altar.DEATH) { + if (!hasRequirement(player, Quests.MOURNINGS_END_PART_II)) + return false; + } + if (altar == Altar.BLOOD) { + if (!hasRequirement(player, Quests.LEGACY_OF_SEERGAZE)) + return false; + } + if (!altar.isOurania() && getDynLevel(player, Skills.RUNECRAFTING) < rune.getLevel()) { + sendMessage(player, "You need a Runecrafting level of at least " + rune.getLevel() + " to craft this rune."); + return false; + } + if (combination && amountInInventory(player, PURE_ESSENCE.getId()) == 0) { + sendMessage(player, "You need pure essence to craft this rune."); + return false; + } + if (!altar.isOurania() && !rune.isNormal() && amountInInventory(player, PURE_ESSENCE.getId()) == 0) { + sendMessage(player, "You need pure essence to craft this rune."); + return false; + } + if (!altar.isOurania() && rune.isNormal() && amountInInventory(player, PURE_ESSENCE.getId()) == 0 && amountInInventory(player, RUNE_ESSENCE.getId()) == 0) { + sendMessage(player, "You need rune essence or pure essence in order to craft this rune."); + return false; + } + if (altar.isOurania() && amountInInventory(player, PURE_ESSENCE.getId()) == 0) { + sendMessage(player, "You need pure essence to craft this rune."); + return false; + } + if (combination && getDynLevel(player, Skills.RUNECRAFTING) < combo.getLevel()) { + sendMessage(player, "You need a Runecrafting level of at least " + combo.getLevel() + " to combine this rune."); + return false; + } + if (node != null) { + if (node.getName().contains("rune") && !hasSpellImbue()) { + final Rune r = Rune.forItem(node); + final Talisman t = Talisman.forName(r.name()); + if (amountInInventory(player, t.getTalisman().getId()) == 0) { + sendMessage(player, "You don't have the correct talisman to combine this rune."); + return false; + } + talisman = t; + } + } + player.lock(4); + return true; + } + + @Override + public void animate() { + player.animate(ANIMATION); + player.graphics(GRAPHICS); + playAudio(player, Sounds.BIND_RUNES_2710); + } + + @Override + public boolean reward() { + if (!combination) { + craft(); + } else { + combine(); + } + return true; + } + + private static final int[][] OuraniaTable = { //https://x.com/JagexAsh/status/1312893446395506688/photo/1 + /*level up to 9*/ { 2, 7, 15, 30, 60, 105, 165, 250, 400, 700,1300,2500,5000,10000}, + /*level up to 19*/ { 3, 9, 21, 45, 85, 145, 225, 400,1000,2200,4600,6700,8500,10000}, + /*level up to 29*/ { 8, 23, 55, 110, 220, 430, 850,1650,3250,4750,6150,7500,8800,10000}, + /*level up to 39*/ { 20, 60, 120, 250, 500,1000,2000,4000,5300,6500,7600,8500,9300,10000}, + /*level up to 49*/ { 40, 120, 240, 500,1000,2000,4000,5500,6500,7300,8050,8750,9400,10000}, + /*level up to 59*/ { 80, 250, 600,1300,2650,4150,5250,6250,7000,7700,8350,8950,9500,10000}, + /*level up to 69*/ {100, 300, 700,1500,3050,4450,5500,6450,7200,7900,8500,9050,9550,10000}, + /*level up to 79*/ {200, 700,1700,3500,5000,6200,7100,7800,8300,8700,9100,9400,9700,10000}, + /*level up to 89*/ {400,1000,2450,3900,5250,6300,7100,7800,8400,8900,9300,9600,9800,10000}, + /*level up to 98*/ {650,1650,3300,4750,6100,7100,7800,8400,8900,9300,9600,9800,9900,10000}, + /*level up to 99*/ {900,2200,3750,5200,6550,7500,8100,8600,9000,9300,9600,9800,9900,10000} + }; + + /** + * Method used to craft runes. + */ + private void craft() { + final Item item = getEssenceItem(); + int amount = player.getInventory().getAmount(item); + if (altar.isOurania()) { + if (removeItem(player, item, Container.INVENTORY)) { + sendMessage(player, "You bind the temple's power into runes."); + player.incrementAttribute("/save:" + STATS_BASE + ":" + STATS_RC, amount); + + int[] OuraniaValues; + if (getDynLevel(player, Skills.RUNECRAFTING) == 99) { + OuraniaValues = OuraniaTable[10]; + } else { + int index = getDynLevel(player, Skills.RUNECRAFTING) / 10; + OuraniaValues = OuraniaTable[index]; + } + for (int i = 0; i < amount; i++) { + int roll = RandomFunction.random(10000); + Rune rune = null; + for (int j = 0; j < 14; j++) { + if (roll < OuraniaValues[j]) { + rune = Rune.values()[13 - j]; + break; + } + } + rewardXP(player, Skills.RUNECRAFTING, rune.getExperience() * 2); + addItemOrDrop(player, rune.getRune().getId(), 1); + } + } + } else { + int total = 0; + for(int j = 0; j < amount; j++) { + // since getMultiplier is stochastic, roll `amount` independent copies + total += getMultiplier(); + } + + if (removeItem(player, item, Container.INVENTORY)) { + sendMessage(player, "You bind the temple's power into " + (combination ? combo.getRune().getName().toLowerCase() : rune.getRune().getName().toLowerCase()) + "s."); + addItemOrDrop(player, rune.getRune().getId(), total); + player.incrementAttribute("/save:" + STATS_BASE + ":" + STATS_RC, amount); + + // Fist of guthix gloves + double xp = rune.getExperience() * amount; + if ((altar == Altar.AIR && inEquipment(player, Items.AIR_RUNECRAFTING_GLOVES_12863, 1)) + || (altar == Altar.WATER && inEquipment(player, Items.WATER_RUNECRAFTING_GLOVES_12864, 1)) + || (altar == Altar.EARTH && inEquipment(player, Items.EARTH_RUNECRAFTING_GLOVES_12865, 1))) { + xp += xp * FOGGlovesManager.updateCharges(player, amount) / amount; + } + rewardXP(player, Skills.RUNECRAFTING, xp); + + // Achievement Diary handling + // Craft some nature runes + if (altar == Altar.NATURE) { + player.getAchievementDiaryManager().finishTask(player, DiaryType.KARAMJA, 2, 3); + } + // Craft 196 or more air runes simultaneously + if (altar == Altar.AIR && total >= 196) { + player.getAchievementDiaryManager().finishTask(player, DiaryType.FALADOR, 2, 2); + } + // Craft a water rune at the Water Altar + if (altar == Altar.WATER && rune == Rune.WATER) { + player.getAchievementDiaryManager().finishTask(player, DiaryType.LUMBRIDGE, 1, 11); + } + + } + } + } + + /** + * Method used to combine runes. + */ + private void combine() { + final Item remove = node.getName().contains("talisman") ? node : talisman != null ? talisman.getTalisman() : Talisman.forName(Rune.forItem(node).name()).getTalisman(); + boolean imbued = hasSpellImbue(); + if (!imbued ? removeItem(player, remove, Container.INVENTORY) : imbued) { + int amount = 0; + int essenceAmt = player.getInventory().getAmount(PURE_ESSENCE); + final Item rune = node.getName().contains("rune") ? Rune.forItem(node).getRune() : Rune.forName(Talisman.forItem(node).name()).getRune(); + int runeAmt = player.getInventory().getAmount(rune); + amount = Math.min(essenceAmt, runeAmt); + if (removeItem(player, new Item(PURE_ESSENCE.getId(), amount), Container.INVENTORY) && removeItem(player, new Item(rune.getId(), amount), Container.INVENTORY)) { + for (int i = 0; i < amount; i++) { + if (RandomFunction.random(1, 3) == 1 || hasBindingNecklace()) { + addItemOrDrop(player, combo.getRune().getId(), 1); + rewardXP(player, Skills.RUNECRAFTING, combo.getExperience()); + } + } + if (hasBindingNecklace()) { + player.getEquipment().get(EquipmentContainer.SLOT_AMULET).setCharge(player.getEquipment().get(EquipmentContainer.SLOT_AMULET).getCharge() - 1); + if (1000 - player.getEquipment().get(EquipmentContainer.SLOT_AMULET).getCharge() > 14) { + if (player.getEquipment().remove(BINDING_NECKLACE, true)) { + sendMessage(player, "Your binding necklace crumbles into dust."); + } + } + } + } + } + } + + /** + * Checks if the player has the spell imbue. + * + * @return {@code True} if so. + */ + private boolean hasSpellImbue() { + return player.getAttribute("spell:imbue", 0) > GameWorld.getTicks(); + } + + /** + * Gets the rune essence item. + * + * @return the rune essence item. + */ + private Item getEssenceItem() { + if (altar.isOurania() && amountInInventory(player, PURE_ESSENCE.getId()) > 0) { + return new Item(PURE_ESSENCE.getId(), amountInInventory(player, PURE_ESSENCE.getId())); + } + if (!rune.isNormal() && amountInInventory(player, PURE_ESSENCE.getId()) > 0) { + return new Item(PURE_ESSENCE.getId(), amountInInventory(player, PURE_ESSENCE.getId())); + } + if (rune.isNormal() && amountInInventory(player, RUNE_ESSENCE.getId()) > 0) { + return new Item(RUNE_ESSENCE.getId(), amountInInventory(player, RUNE_ESSENCE.getId())); + } + return new Item(PURE_ESSENCE.getId(), amountInInventory(player, PURE_ESSENCE.getId())); + } + + /** + * Gets the multiplied amount of runes to make. + * + * @return the amount. + */ + public int getMultiplier() { + if (altar.isOurania()) { + return 1; + } + int rcLevel = getDynLevel(player, Skills.RUNECRAFTING); + int runecraftingFormulaRevision = ServerConstants.RUNECRAFTING_FORMULA_REVISION; + boolean lumbridgeDiary = player.getAchievementDiaryManager().getDiary(DiaryType.LUMBRIDGE).isComplete(1); + return RuneCraftPulse.getMultiplier(rcLevel, rune, runecraftingFormulaRevision, lumbridgeDiary); + } + + public static int getMultiplier(int rcLevel, Rune rune, int runecraftingFormulaRevision, boolean lumbridgeDiary) { + int[] multipleLevels = rune.getMultiple(); + int i = 0; + for (int level : multipleLevels) { + if (rcLevel >= level) { + i++; + } + } + + if (multipleLevels.length > i && runecraftingFormulaRevision >= 573) { + int a = Math.max(multipleLevels[i-1], rune.getLevel()); + int b = multipleLevels[i]; + if(b <= 99 || runecraftingFormulaRevision >= 581) { + double chance = ((double)rcLevel - (double)a) / ((double)b - (double)a); + if(RandomFunction.random(0.0, 1.0) < chance) { + i += 1; + } + } + } + + if (lumbridgeDiary + && new ArrayList<>(Arrays.asList(Rune.AIR, Rune.WATER, Rune.FIRE, Rune.EARTH)).contains(rune) + && RandomFunction.getRandom(10) == 0) { //approximately 10% chance + i += 1; + } + + return i != 0 ? i : 1; + } + + /** + * Method used to check if the player has a binding necklace. + * + * @return True if so. + */ + public boolean hasBindingNecklace() { + return player.getEquipment().containsItem(BINDING_NECKLACE); + } + + /** + * Gets the altar. + * + * @return The altar. + */ + public Altar getAltar() { + return altar; + } +} diff --git a/Server/src/main/content/global/skill/runecrafting/RunePouch.java b/Server/src/main/content/global/skill/runecrafting/RunePouch.java new file mode 100644 index 0000000..b2fbf89 --- /dev/null +++ b/Server/src/main/content/global/skill/runecrafting/RunePouch.java @@ -0,0 +1,643 @@ +package content.global.skill.runecrafting; + +import core.game.global.action.DropListener; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +/** + * Represents a rune pouch. + * @author Vexia + */ +public enum RunePouch { + SMALL(new Item(5509), 1, 3, 3, 0), MEDIUM(new Item(5510), 25, 6, 9, 45), LARGE(new Item(5512), 50, 9, 18, 29), GIANT(new Item(5514), 75, 12, 30, 10); + + /** + * The pure essence item. + */ + private static final Item PURE_ESSENCE = new Item(7936); + + /** + * The rune essence item. + */ + private static final Item NORMAL_ESSENCE = new Item(1436); + + /** + * The pure essence base. + */ + private static final int PURE_BASE = 6000; + + /** + * The normal essence base. + */ + private static final int NORMAL_BASE = 2000; + + /** + * The pouch item. + */ + private final Item pouch; + + /** + * The decayed pouch. + */ + private final Item decayedPouch; + + /** + * The level required to use it. + */ + private final int level; + + /** + * The capacity. + */ + private final int capacity; + + /** + * The cumulative capacity. + */ + private final int cumulativeCapacity; + + /** + * The uses until decay. + */ + private final int uses; + + /** + * Constructs a new {@code Pouch} {@code Object}. + * @param pouch the pouch. + * @param level the level. + * @param capacity the capacity. + * @param cumulativeCapacity the cumulative capacity. + * @param uses the uses. + */ + RunePouch(Item pouch, int level, int capacity, int cumulativeCapacity, int uses) { + this.pouch = pouch; + this.decayedPouch = new Item(pouch.getId() + 1); + this.level = level; + this.capacity = capacity; + this.cumulativeCapacity = cumulativeCapacity; + this.uses = uses; + } + + /** + * Method used to handle the reward. + * @param player the player. + * @param pouch the item. + * @param option the option. + */ + public void action(final Player player, final Item pouch, final String option) { + if (pouch.getCharge() == 1000 && getDecay(player) > 0) { + resetDecay(player); + } + switch (option) { + case "fill": + fill(player, pouch); + break; + case "empty": + empty(player, pouch); + break; + case "check": + check(player, pouch); + break; + case "drop": + drop(player, pouch); + break; + } + } + + /** + * Method used to fill a pouch. + * @param player the player. + * @param pouch the item. + */ + public final void fill(final Player player, Item pouch) { + if (isFull(pouch, player)) { + return; + } + if (!hasEssence(player)) { + player.sendMessage("You do not have any essence to fill your pouch with."); + return; + } + if (player.getSkills().getStaticLevel(Skills.RUNECRAFTING) < level) { + player.sendMessage("You need level " + level + " Runecrafting to fill a " + name().toLowerCase() + " pouch."); + return; + } + final Item essence = getEssence(player); + if (!isValidEssence(pouch, essence, player)) { + player.sendMessage("You can only put " + getPouchEssenceName(pouch) + " in this pouch."); + return; + } + int amount = getAddAmount(pouch, essence, player); + addEssence(player, pouch, essence, amount); + if (isFull(pouch, player)) { + return; + } + } + + /** + * Emptys a rune pouch. + * @param player the player. + * @param pouch the item. + */ + public final void empty(final Player player, Item pouch) { + if (isEmpty(pouch)) { + player.sendMessage("There are no essences in your pouch."); + return; + } + int essenceAmount = getEssence(pouch); + int addAmount = essenceAmount; + if (player.getInventory().freeSlots() < essenceAmount) { + addAmount = essenceAmount - (essenceAmount - player.getInventory().freeSlots()); + } + Item add = new Item(getEssenceType(pouch).getId(), addAmount); + if (!player.getInventory().hasSpaceFor(add)) { + player.sendMessage("You do not have any more free space in your inventory."); + return; + } + if (player.getInventory().add(add)) { + incrementCharge(pouch, addAmount); + if (essenceAmount != addAmount) {// means all didnt get added + player.sendMessage("You do not have any more free space in your inventory."); + } + } + } + + /** + * Check for doubles. + * @param player the player. + */ + public boolean checkDoubles(Player player) { + boolean hit = false; + for (RunePouch pouch : values()) { + if (player.getInventory().getAmount(pouch.getPouch()) > 1 || player.getBank().getAmount(pouch.getPouch()) > 1) { + hit = true; + player.getInventory().remove(new Item(pouch.getPouch().getId(), player.getInventory().getAmount(pouch.getPouch()) - 1)); + player.getBank().remove(new Item(pouch.getPouch().getId(), player.getBank().getAmount(pouch.getPouch()))); + } + } + return hit; + } + + /** + * Checks the essence pouch. + * @param player the player. + * @param item the item. + */ + public final void check(final Player player, Item item) { + int amount = getEssence(item); + player.sendMessage(amount == 0 ? "There are no essences in this pouch." : "There " + (amount == 1 ? "is" : "are") + " " + amount + " " + getPouchEssenceName(item, amount) + " in this pouch."); + } + + /** + * Drops an item. + * @param player the player. + * @param item the item. + */ + private void drop(Player player, Item item) { + onDrop(player, item); + DropListener.drop(player, item); + } + + /** + * Handles the on dropping of a pouch. + * @param player the player. + * @param item the item. + */ + public void onDrop(Player player, Item item) { + if (!isEmpty(item)) { + resetCharge(item); + player.sendMessage("The contents of the pouch fell out as you dropped it!"); + } + } + + /** + * Adds an essence amount to the pouch. + * @param player the player. + * @param pouch the pouch. + * @param essence the essence. + * @param amount the amount. + */ + public void addEssence(Player player, Item pouch, Item essence, int amount) { + final Item remove = new Item(essence.getId(), amount); + if (!player.getInventory().containsItem(remove)) { + return; + } + if (player.getInventory().remove(remove)) { + int charge = getPouchCharge(pouch); + if (charge == 1000) { + charge = (isPureEssence(essence) ? PURE_BASE : NORMAL_BASE); + setCharge(pouch, charge); + } + if (isPureEssence(essence) && charge == NORMAL_BASE) { + charge = PURE_BASE; + } else if (isNormalEssence(essence) && charge == PURE_BASE) { + charge = NORMAL_BASE; + } + charge -= amount; + setHash(pouch, charge); + decay(player, pouch); + } + } + + /** + * Decays a pouch. + * @param player the player. + * @param pouch the pouch. + */ + public void decay(Player player, Item pouch) { + incrementDecay(player); + if (getDecay(player) >= uses) { + String message = ""; + if (!isDecayed(pouch)) { + int decrementAmount = 0; + if (getDecayAmount() > getEssence(pouch)) { + decrementAmount = getDecayAmount() - (getDecayAmount() - getEssence(pouch)); + } else { + decrementAmount = getEssence(pouch) - (getEssence(pouch) - getDecayAmount()); + } + incrementCharge(pouch, decrementAmount); + message = "Your pouch has decayed through use."; + player.getInventory().replace(new Item(getDecayedPouch().getId(), pouch.getAmount(), pouch.getCharge()), pouch.getSlot()); + } else { + message = "Your pouch has decayed beyond any further use."; + player.getInventory().remove(pouch); + } + resetDecay(player); + player.sendMessage(message); + } + } + + /** + * Repairs a pouch. + * @param pouch the pouch. + */ + public void repair(Player player, Item pouch) { + if (isDecayed(pouch)) { + player.getInventory().replace(new Item(getPouch().getId(), pouch.getAmount(), pouch.getCharge()), pouch.getSlot()); + } + resetDecay(player); + } + + /** + * Increments the decay. + * @param player the player. + */ + public void incrementDecay(Player player) { + player.getSavedData().getGlobalData().getRcDecays()[ordinal() - 1]++; + } + + /** + * Increments the charge on a pouch. + * @param pouch the pouch. + * @param chargeIncrement the charge increment. + */ + public void incrementCharge(Item pouch, int chargeIncrement) { + setHash(pouch, getPouchCharge(pouch) + chargeIncrement); + } + + /** + * Decrements the charge on a pouch. + * @param pouch the pouch. + * @param chargeIncrement the charge increment. + */ + public void decrementCharge(Item pouch, int chargeIncrement) { + setHash(pouch, getPouchCharge(pouch) - chargeIncrement); + } + + /** + * Sets the charge. + * @param pouch the pouch. + * @param charge the charge. + */ + public void setCharge(Item pouch, int charge) { + setHash(pouch, charge); + } + + /** + * Resets the decay on a pouch. + */ + public void resetDecay(Player player) { + player.getSavedData().getGlobalData().getRcDecays()[ordinal() - 1] = 0; + } + + /** + * Resets the charge on the pouch. + * @param pouch the pouch. + */ + public void resetCharge(Item pouch) { + setHash(pouch, 1000); + } + + /** + * Sets the hash of the pouch. + * @param pouch the pouch. + * @param charge the charge. + */ + public void setHash(Item pouch, int charge) { + pouch.setCharge(charge); + } + + /** + * Gets the decay. + * @param player the player. + * @return the decay. + */ + public int getDecay(Player player) { + return player.getSavedData().getGlobalData().getRcDecay(ordinal() - 1); + } + + /** + * Gets the charge of the pouch. + * @param pouch the pouch. + * @return the charge. + */ + public int getPouchCharge(Item pouch) { + return pouch.getCharge(); + } + + /** + * Checks if the pouch is full. + * @param item the item. + * @return {@code True} if so. + */ + public boolean isFull(Item item) { + return getEssence(item) >= getCapacity(pouch); + } + + /** + * Gets the add amount. + * @param pouch the pouch. + * @param essence the essence. + * @return the amount. + */ + public int getAddAmount(Item pouch, Item essence, Player player) { + int essyAmount = player.getInventory().getAmount(essence); + int pouchAmount = getEssence(pouch); + int maxAdd = getCapacity(pouch) - pouchAmount;// 3 - 0 == 3, thus max = + // 3. + if (essyAmount > maxAdd) { + return maxAdd; + } else if (essyAmount <= maxAdd) { + return essyAmount; + } + return 0; + + } + + /** + * Checks if essence can go inside a pouch. + * @param pouch the pouch. + * @param essence the essence. + * @param player the player. + * @return {@code True} if so. + */ + public boolean isValidEssence(Item pouch, Item essence, Player player) { + if (isEmpty(pouch)) { + return true; + } + return getPouchEssenceName(pouch).equals(getEssenceName(essence)); + } + + /** + * Checks if the pouch is full. + * @param item the item. + * @param player the player. + * @return + */ + public boolean isFull(Item item, Player player) { + if (isFull(item)) { + player.sendMessage("Your pouch is full."); + return true; + } + return false; + } + + /** + * Gets the essence name. + * @param item the item. + * @param amount the amount. + * @return the name. + */ + public String getPouchEssenceName(Item item, int amount) { + return getPouchEssenceName(item) + (amount > 1 ? "s" : ""); + } + + /** + * Gets the essence name. + * @param item the item. + * @return the name. + */ + public String getPouchEssenceName(Item item) { + int charge = getPouchCharge(item); + return charge > NORMAL_BASE ? "pure essence" : "normal essence"; + } + + /** + * Gets the essence item in the pouch. + * @param pouch the pouch. + * @return {@code True} item. + */ + public Item getEssenceInPouch(Item pouch) { + return getPouchEssenceName(pouch).equals("pure essence") ? PURE_ESSENCE : NORMAL_ESSENCE; + } + + /** + * Gets the essence name. + * @param essence the essence. + * @return the name. + */ + public String getEssenceName(Item essence) { + return essence.getId() == PURE_ESSENCE.getId() ? "pure essence" : "normal essence"; + } + + /** + * Gets the essence base. + * @param item the item. + * @return the base. + */ + public int getEssenceBase(Item item) { + return getPouchEssenceName(item).equals("pure essence") ? PURE_BASE : NORMAL_BASE; + } + + /** + * Checks if it's a pure essence pouch. + * @param pouch the item. + * @return {@code True} if so. + */ + public boolean isPureEssencePouch(Item pouch) { + return getPouchEssenceName(pouch).equals("pure essence"); + } + + /** + * Checks if its a pure essence. + * @param essence the essence. + * @return {@code True} if so. + */ + public boolean isPureEssence(Item essence) { + return essence.getId() == PURE_ESSENCE.getId(); + } + + /** + * Checks if its normal essence. + * @param essence the essence. + * @return {@code True} if so. + */ + public boolean isNormalEssence(Item essence) { + return essence.getId() == NORMAL_ESSENCE.getId(); + } + + /** + * Gets the essence type. + * @param pouch the pouch. + * @return the item. + */ + public Item getEssenceType(Item pouch) { + return getPouchEssenceName(pouch).equals("pure essence") ? PURE_ESSENCE : NORMAL_ESSENCE; + } + + /** + * Gets the essence type. + * @param player the player. + * @return {@code True} if so. + */ + public Item getEssence(Player player) { + if (player.getInventory().containsItem(PURE_ESSENCE)) { + return PURE_ESSENCE; + } else if (player.getInventory().containsItem(NORMAL_ESSENCE)) { + return NORMAL_ESSENCE; + } + return null; + } + + /** + * Checks if the player has essence. + * @param player the player. + * @return {@code True} if so. + */ + public boolean hasEssence(Player player) { + return player.getInventory().containsItem(PURE_ESSENCE) || player.getInventory().containsItem(NORMAL_ESSENCE); + } + + /** + * Gets a rune pouch for the item. + * @param pouch the pouch. + * @return the {@code RunePouch}. + */ + public static RunePouch forItem(final Item pouch) { + for (RunePouch p : RunePouch.values()) { + if (p.getPouch().getId() == pouch.getId() || (p != SMALL && p.getDecayedPouch().getId() == pouch.getId())) { + return p; + } + } + return null; + } + + /** + * Checks if the pouch is empty. + * @param item the item. + * @return {@code True} if so. + */ + public boolean isEmpty(Item item) { + return getEssence(item) <= 0; + } + + /** + * Gets the essence amount. + * @param item the item. + * @return the amount. + */ + public int getEssence(Item item) { + if (getPouchCharge(item) == 1000 || getPouchCharge(item) == 2000) { + return 0; + } + return getEssenceBase(item) - getPouchCharge(item); + } + + /** + * Gets the pouch. + * @return The pouch. + */ + public Item getPouch() { + return pouch; + } + + /** + * Gets the level. + * @return The level. + */ + public int getLevel() { + return level; + } + + /** + * Gets the capacity. + * @param pouch the pouch. + * @return The capacity. + */ + public int getCapacity(Item pouch) { + return capacity - (isDecayed(pouch) ? getDecayAmount() : 0); + } + + /** + * Gets the decay amount. + * @return the amount. + */ + public int getDecayAmount() { + return this == GIANT ? 3 : this == LARGE ? 2 : 1; + } + + /** + * Gets the cumulativeCapacity. + * @return The cumulativeCapacity. + */ + public int getCumulativeCapacity() { + return cumulativeCapacity; + } + + /** + * Gets the uses. + * @return The uses. + */ + public int getUses() { + return uses; + } + + /** + * Checks if the pouch is decayed. + * @param pouch the pouch. + * @returne {@code True} if decayed. + */ + public boolean isDecayed(Item pouch) { + return pouch.getId() == decayedPouch.getId(); + } + + /** + * Checks if the pouch is decayable. + * @return {@code True} if so. + */ + public boolean isDecayable() { + return this != SMALL; + } + + /** + * Gets the decayedPouch. + * @return The decayedPouch. + */ + public Item getDecayedPouch() { + if (this == SMALL) { + return pouch; + } + return decayedPouch; + } + + /** + * Checks if this pouch has decay. + * @param player the player. + * @param pouch the pouch. + * @return {@code True} if so. + */ + public boolean hasDecay(Player player, Item pouch) { + return getDecay(player) > 0 || isDecayed(pouch); + } + +} diff --git a/Server/src/main/content/global/skill/runecrafting/RunePouchPlugin.kt b/Server/src/main/content/global/skill/runecrafting/RunePouchPlugin.kt new file mode 100644 index 0000000..599ca05 --- /dev/null +++ b/Server/src/main/content/global/skill/runecrafting/RunePouchPlugin.kt @@ -0,0 +1,52 @@ +package content.global.skill.runecrafting + +import core.cache.def.impl.ItemDefinition +import core.game.interaction.OptionHandler +import core.game.node.Node +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Plugin +import org.rs09.consts.Items +import core.tools.colorize + +/** + * Handles the rune pouches. + * @author Ceikry, Player Name + */ +class RunePouchPlugin : OptionHandler() { + @Throws(Throwable::class) + override fun newInstance(arg: Any?): Plugin? { + for (i in 5509..5515) { + ItemDefinition.forId(i).handlers["option:fill"] = this + ItemDefinition.forId(i).handlers["option:empty"] = this + ItemDefinition.forId(i).handlers["option:check"] = this + ItemDefinition.forId(i).handlers["option:drop"] = this + } + return this + } + + override fun handle(player: Player, node: Node, option: String): Boolean { + val rEssAmt = player.inventory.getAmount(Items.RUNE_ESSENCE_1436) + val pEssAmt = player.inventory.getAmount(Items.PURE_ESSENCE_7936) + var preferenceFlag = 0 //0 -> rune ess, 1 -> pure ess + if(rEssAmt - pEssAmt == 0 && option == "fill") return true + if(rEssAmt > pEssAmt) preferenceFlag = 0 else preferenceFlag = 1 + + val essence = Item( + if(preferenceFlag == 0) Items.RUNE_ESSENCE_1436 else Items.PURE_ESSENCE_7936, + if(preferenceFlag == 0) rEssAmt else pEssAmt + ) + + when (option) { + "fill" -> player.pouchManager.addToPouch(node.id, essence.amount, essence.id) + "empty" -> player.pouchManager.withdrawFromPouch(node.id) + "check" -> player.pouchManager.checkAmount(node.id) + "drop" -> player.dialogueInterpreter.open(9878,Item(node.id)) + } + return true + } + + override fun isWalk(): Boolean { + return false + } +} diff --git a/Server/src/main/content/global/skill/runecrafting/RunecraftingPlugin.java b/Server/src/main/content/global/skill/runecrafting/RunecraftingPlugin.java new file mode 100644 index 0000000..954948e --- /dev/null +++ b/Server/src/main/content/global/skill/runecrafting/RunecraftingPlugin.java @@ -0,0 +1,148 @@ +package content.global.skill.runecrafting; + +import content.global.travel.EssenceTeleport; +import core.cache.def.impl.ItemDefinition; +import core.cache.def.impl.NPCDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.game.component.Component; +import core.game.global.action.ClimbActionHandler; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.info.Rights; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.net.packet.PacketRepository; +import core.net.packet.context.MinimapStateContext; +import core.net.packet.out.MinimapState; +import core.plugin.ClassScanner; +import core.plugin.Initializable; +import core.plugin.Plugin; + +import static core.api.ContentAPIKt.hasRequirement; +import content.data.Quests; + +/** + * Handles runecraftign related options. + * @author Vexia + */ +@Initializable +public class RunecraftingPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addNodes(); + ClassScanner.definePlugin(new TiaraPlugin()); + ClassScanner.definePlugin(new RunePouchPlugin()); + ClassScanner.definePlugin(new EnchantTiaraPlugin()); + ClassScanner.definePlugin(new CombinationRunePlugin()); + SceneryDefinition.forId(2492).getHandlers().put("option:use", this); + NPCDefinition.forId(553).getHandlers().put("option:teleport", this); + NPCDefinition.forId(2328).getHandlers().put("option:teleport", this); + SceneryDefinition.forId(26849).getHandlers().put("option:climb", this); + SceneryDefinition.forId(26850).getHandlers().put("option:climb", this); + SceneryDefinition.forId(268).getHandlers().put("option:climb", this); + SceneryDefinition.forId(26844).getHandlers().put("option:squeeze-through", this); + SceneryDefinition.forId(26845).getHandlers().put("option:squeeze-through", this); + return this; + } + + @Override + public boolean handle(final Player player, Node node, String option) { + if (!player.getQuestRepository().isComplete(Quests.RUNE_MYSTERIES) && player.getDetails().getRights() != Rights.ADMINISTRATOR) { + player.getPacketDispatch().sendMessage("You need to finish the Rune Mysteries Quest in order to do this."); + return true; + } + switch (node.getId()) { + case 2492: + EssenceTeleport.home(player,node); + return true; + case 26844: + case 26845: + final Location location = node.getId() == 26845 ? new Location(3309, 4820, 0) : new Location(3311, 4817, 0); + player.lock(4); + player.getInterfaceManager().openOverlay(new Component(115)); + PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 1)); + GameWorld.getPulser().submit(new Pulse(4, player) { + + @Override + public boolean pulse() { + player.teleport(location); + player.getInterfaceManager().close(); + player.getInterfaceManager().closeOverlay(); + PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 0)); + return true; + } + + }); + return true; + case 553: + case 2328: + case 844: + EssenceTeleport.teleport(((NPC) node), player); + return true; + } + switch (option) { + case "use": + final Altar altar = Altar.forObject(((Scenery) node)); + player.getProperties().setTeleportLocation(altar.getRuin().getBase()); + break; + case "craft-rune": + if(node.getLocation().equals(new Location(3151, 3484))){ + player.sendMessage("You can only craft Astral runes on Lunar Isle."); + return true; + } + Altar a = Altar.forObject(((Scenery) node)); + if (a == Altar.ASTRAL) { + if (!hasRequirement(player, Quests.LUNAR_DIPLOMACY)) + return true; + } + player.getPulseManager().run(new RuneCraftPulse(player, null, a, false, null)); + break; + case "locate": + final Talisman talisman = Talisman.forItem(((Item) node)); + talisman.locate(player); + break; + case "climb": + int id = (node).getId(); + switch (id) { + case 26849: + ClimbActionHandler.climb(player, null, new Location(3271, 4861, 0)); + break; + case 26850: + ClimbActionHandler.climb(player, null, new Location(2452, 3230, 0)); + break; + } + break; + } + return true; + } + + /** + * Adds the nodes to this plugin. + */ + private void addNodes() { + for (Altar altar : Altar.values()) { + SceneryDefinition.forId(altar.getObject()).getHandlers().put("option:craft-rune", this); + SceneryDefinition.forId(altar.getPortal()).getHandlers().put("option:use", this); + } + for (Talisman talisman : Talisman.values()) { + ItemDefinition.forId(talisman.getTalisman().getId()).getHandlers().put("option:locate", this); + } + } + + @Override + public boolean isWalk() { + return false; + } + + @Override + public boolean isWalk(final Player player, final Node node) { + return !(node instanceof Item); + } + +} diff --git a/Server/src/main/content/global/skill/runecrafting/Talisman.java b/Server/src/main/content/global/skill/runecrafting/Talisman.java new file mode 100644 index 0000000..3d2f3ba --- /dev/null +++ b/Server/src/main/content/global/skill/runecrafting/Talisman.java @@ -0,0 +1,121 @@ +package content.global.skill.runecrafting; + +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.map.Location; + +/** + * Represents a talisman. + * @author 'Vexia + */ +public enum Talisman { + AIR(new Item(1438), MysteriousRuin.AIR), MIND(new Item(1448), MysteriousRuin.MIND), WATER(new Item(1444), MysteriousRuin.WATER), EARTH(new Item(1440), MysteriousRuin.EARTH), FIRE(new Item(1442), MysteriousRuin.FIRE), ELEMENTAL(new Item(5516), null), BODY(new Item(1446), MysteriousRuin.BODY), COSMIC(new Item(1454), MysteriousRuin.COSMIC), CHAOS(new Item(1452), MysteriousRuin.CHAOS), NATURE(new Item(1462), MysteriousRuin.NATURE), LAW(new Item(1458), MysteriousRuin.LAW), DEATH(new Item(1456), MysteriousRuin.DEATH), BLOOD(new Item(1450), null), SOUL(new Item(1460), null); + + /** + * Constructs a new {@code Talisman} {@code Object}. + */ + Talisman(final Item talisman, MysteriousRuin ruin) { + this.talisman = talisman; + this.ruin = ruin; + } + + /** + * Represents the talisman item. + */ + private final Item talisman; + + /** + * Represents the mysterious ruin. + */ + private final MysteriousRuin ruin; + + /** + * Gets the talisman. + * @return The talisman. + */ + public Item getTalisman() { + return talisman; + } + + /** + * Method used to locate a ruin. + */ + public final void locate(final Player player) { + if (this == ELEMENTAL || getRuin() == null) { + player.getPacketDispatch().sendMessage("You cannot tell which direction the Talisman is pulling..."); + return; + } + String direction = ""; + Location loc = getRuin().getBase(); + if (player.getLocation().getY() > loc.getY() && player.getLocation().getX() - 1 > loc.getX()) + direction = "south-west"; + else if (player.getLocation().getX() < loc.getX() && player.getLocation().getY() > loc.getY()) + direction = "south-east"; + else if (player.getLocation().getX() > loc.getX() + 1 && player.getLocation().getY() < loc.getY()) + direction = "north-west"; + else if (player.getLocation().getX() < loc.getX() && player.getLocation().getY() < loc.getY()) + direction = "north-east"; + else if (player.getLocation().getY() < loc.getY()) + direction = "north"; + else if (player.getLocation().getY() > loc.getY()) + direction = "south"; + else if (player.getLocation().getX() < loc.getX() + 1) + direction = "east"; + else if (player.getLocation().getX() > loc.getX() + 1) + direction = "west"; + player.getPacketDispatch().sendMessage("The talisman pulls towards the " + direction + "."); + } + + /** + * Gets the ruin. + * @return The ruin. + */ + public MysteriousRuin getRuin() { + for (MysteriousRuin ruin : MysteriousRuin.values()) { + if (ruin.name().equals(name())) { + return ruin; + } + } + return ruin; + } + + /** + * Gets the tiara. + * @return the tiara. + */ + public Tiara getTiara() { + for (Tiara tiara : Tiara.values()) { + if (tiara.name().equals(name())) { + return tiara; + } + } + return null; + } + + /** + * Method used to get the Talisman by the item. + * @param item the item. + * @return the Talisman or Null. + */ + public static Talisman forItem(final Item item) { + for (Talisman talisman : values()) { + if (talisman.getTalisman().getId() == item.getId()) { + return talisman; + } + } + return null; + } + + /** + * Method used to get the Talisman by the item. + * @return the Talisman or Null. + */ + public static Talisman forName(final String name) { + for (Talisman talisman : values()) { + if (talisman.name().equals(name)) { + return talisman; + } + } + return null; + } +} diff --git a/Server/src/main/content/global/skill/runecrafting/Tiara.java b/Server/src/main/content/global/skill/runecrafting/Tiara.java new file mode 100644 index 0000000..956c633 --- /dev/null +++ b/Server/src/main/content/global/skill/runecrafting/Tiara.java @@ -0,0 +1,89 @@ +package content.global.skill.runecrafting; + +import core.game.node.item.Item; + +/** + * Represents a tiara item and it's corresponding information related to + * (runecrafting) + * @author 'Vexia + * @date 01/11/2013 + */ +public enum Tiara { + AIR(new Item(5527), 25), + MIND(new Item(5529), 27.5), + WATER(new Item(5531), 30), + EARTH(new Item(5535), 32.5), + FIRE(new Item(5537), 35), + BODY(new Item(5533), 37.5), + COSMIC(new Item(5539), 40), + CHAOS(new Item(5543), 43.5), + ASTRAL(new Item(9106), 43.5), + NATURE(new Item(5541), 45), + LAW(new Item(5545), 47.5), + DEATH(new Item(5547), 50), + BLOOD(new Item(5549), 52.5), + SOUL(new Item(5551), 55); + + /** + * Constructs a new {@code Tiara} {@code Object}. + * @param tiara the tiara. + * @param experience the experience. + */ + Tiara(final Item tiara, final double experience) { + this.tiara = tiara; + this.experience = experience; + } + + /** + * Represents the tiara item. + */ + private final Item tiara; + + /** + * Represents the experience gained. + */ + private final double experience; + + /** + * Gets the tiara. + * @return The tiara. + */ + public Item getTiara() { + return tiara; + } + + /** + * Gets the experience. + * @return The experience. + */ + public double getExperience() { + return experience; + } + + /** + * Method used to get the talisman for this tiara. + * @return the talisman. + */ + public Talisman getTalisman() { + for (Talisman talisman : Talisman.values()) { + if (talisman.name().equals(name())) { + return talisman; + } + } + return null; + } + + /** + * Method used to get the Tiara by the item. + * @param item the item. + * @return the Tiara or Null. + */ + public static Tiara forItem(final Item item) { + for (Tiara tiara : values()) { + if (tiara.getTiara().getId() == item.getId()) { + return tiara; + } + } + return null; + } +} diff --git a/Server/src/main/content/global/skill/runecrafting/TiaraPlugin.java b/Server/src/main/content/global/skill/runecrafting/TiaraPlugin.java new file mode 100644 index 0000000..b52a7c1 --- /dev/null +++ b/Server/src/main/content/global/skill/runecrafting/TiaraPlugin.java @@ -0,0 +1,69 @@ +package content.global.skill.runecrafting; + +import static core.api.ContentAPIKt.*; + +import core.cache.def.impl.VarbitDefinition; +import core.cache.def.impl.ItemDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Plugin; + +/** + * Handles a tiara equipment. + * @author Vexia + */ +public final class TiaraPlugin implements Plugin { + + /** + * The config id. + */ + private static final int CONFIG = 491; + + /** + * The tiara ids. + */ + private static final int[] IDS = new int[] { 9765, 9766, 14831, 14833, 14835, 14839, 14840, 5527, 5529, 5531, 5533, 5535, 5537, 5539, 5541, 5543, 5545, 5547, 5551, 5549 }; + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (int i : IDS) { + ItemDefinition.forId(i).getHandlers().put("equipment", this); + } + return this; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + final Player player = (Player) args[0]; + final Item item = (Item) args[1]; + switch (identifier) { + case "equip": + if (item.getName().contains("cape")) { + setVarp(player, CONFIG, 6143); + break; + } + MysteriousRuin ruin = MysteriousRuin.forTalisman(Tiara.forItem(item).getTalisman()); + setVarbit(player, SceneryDefinition.forId(ruin.getObject()[0]).getVarbitID(), 1, true); + break; + case "unequip": + final Item other = args.length == 2 ? null : (Item) args[2]; + if (other != null) { + if (other.getName().toLowerCase().contains("cape")) { + setVarp(player, CONFIG, 6143); + break; + } + Tiara tiara = Tiara.forItem(other); + if (tiara != null) { + MysteriousRuin r = MysteriousRuin.forTalisman(tiara.getTalisman()); + setVarbit(player, SceneryDefinition.forId(r.getObject()[0]).getVarbitID(), 1, true); + break; + } + } + setVarp(player, CONFIG, 0); + break; + } + return true; + } + +} diff --git a/Server/src/main/content/global/skill/runecrafting/abyss/AbyssPlugin.kt b/Server/src/main/content/global/skill/runecrafting/abyss/AbyssPlugin.kt new file mode 100644 index 0000000..e44b57d --- /dev/null +++ b/Server/src/main/content/global/skill/runecrafting/abyss/AbyssPlugin.kt @@ -0,0 +1,369 @@ +package core.game.node.entity.skill.runecrafting.abyss + +import core.api.* +import core.game.node.Node +import core.plugin.ClassScanner.definePlugin +import core.tools.colorize +import core.game.node.scenery.Scenery +import core.game.node.entity.impl.Animator +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import content.data.skill.SkillingTool +import content.global.skill.runecrafting.Altar +import content.global.skill.runecrafting.abyss.AbyssalNPC +import content.global.skill.runecrafting.abyss.DarkMageDialogue +import content.global.skill.runecrafting.abyss.ZamorakMageDialogue +import core.game.system.task.Pulse +import core.game.system.timer.impl.Skulled +import core.game.world.map.Location +import core.game.world.map.RegionManager +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import core.plugin.Initializable +import core.tools.RandomFunction +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery as Sceneries +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.game.world.GameWorld +import core.tools.Log +import kotlin.math.cos +import kotlin.math.sin +import kotlin.random.Random + +/** + * A plugin used to handle the abyss. + * @author lila + * @author cfunny + */ +@Initializable +class AbyssPlugin : InteractionListener { + + override fun defineListeners() { + definePlugin(AbyssalNPC()) + definePlugin(DarkMageDialogue()) + definePlugin(ZamorakMageDialogue()) + on(NPCs.MAGE_OF_ZAMORAK_2259, IntType.NPC, "teleport"){ player, node -> + teleport(player, node as NPC) + return@on true + } + on(NPCs.DARK_MAGE_2262, IntType.NPC, "repair-pouches"){ player, node -> + player.dialogueInterpreter.open(node.id, node, true) + return@on true + } + on(IntType.SCENERY, "exit-through"){ player, node -> + val altar = Altar.forObject(node as Scenery) + altar?.enterRift(player) + return@on true + } + on(Sceneries.PASSAGE_7154, IntType.SCENERY, "go-through",){ player, node -> + player.properties.teleportLocation = innerRing(node) + return@on true + } + on(Sceneries.ROCK_7158, IntType.SCENERY, "mine"){ player, node -> + val tool: SkillingTool? = getTool(player, true) + if (tool == null) { + sendMessage(player, "You need a pickaxe in order to do that.") + return@on true + } + return@on handleObstacle( + node, + player, + Skills.MINING, + MINE_PROGRESS, + tool.animation, + arrayOf( + "You attempt to mine your way through...", + "...and manage to break through the rock.", + "...but fail to break-up the rock." + ) + ) + } + on(Sceneries.TENDRILS_7161, IntType.SCENERY, "chop"){ player, node -> + val tool: SkillingTool? = getTool(player, false) + if (tool == null) { + sendMessage(player, "You need an axe in order to do that.") + return@on true + } + return@on handleObstacle( + node, + player, + Skills.WOODCUTTING, + CHOP_PROGRESS, + tool.animation, + arrayOf( + "You attempt to chop your way through...", + "...and manage to chop down the tendrils.", + "...but fail to cut through the tendrils." + ) + ) + } + on(Sceneries.BOIL_7165, IntType.SCENERY, "burn-down"){ player, node -> + if (!inInventory(player, Items.TINDERBOX_590)) { + sendMessage(player, "You don't have a tinderbox to burn it.") + return@on true + } + // TODO: i vaguely remember there being burn graphics for the boil. find if this is indeed true, and if so, find gfx id + return@on handleObstacle( + node, + player, + Skills.FIREMAKING, + BURN_PROGRESS, +// Animation(Animations.HUMAN_LIGHT_FIRE_WITH_TINDERBOX_733), + Animation(733), + arrayOf( + "You attempt to burn your way through...", + "...and manage to burn it down and get past.", + "...but fail to set it on fire." + ) + ) + } + on(Sceneries.EYES_7168, IntType.SCENERY, "distract"){ player, node -> + val distractEmote = Animation(distractEmotes[RandomFunction.random(0,distractEmotes.size)]) + return@on handleObstacle( + node, + player, + Skills.THIEVING, + DISTRACT_PROGRESS, + distractEmote, + arrayOf( + "You use your thieving skills to misdirect the eyes...", + "...and sneak past while they're not looking.", + "...but fail to distract the eyes." + ) + ) + } + on(Sceneries.GAP_7164, IntType.SCENERY, "squeeze-through"){ player, node -> + return@on handleObstacle( + node, + player, + Skills.AGILITY, + null, +// Animation(Animations.HUMAN_SQUEEZE_INTO_GAP_1331), + Animation(1331), + arrayOf( + "You attempt to squeeze through the narrow gap...", + "...and you manage to crawl through.", + "...but fail to crawl through." + ) + ) + } + } + + /** + * emotes used for the eyes obstacle + */ + private val distractEmotes = intArrayOf( + 855, + 856, + 857, + 858, + 859, + 860, + 861, + 862, + 863, + 864, + 865, + 866, + 2113, + 2109, + 2111, + 2106, + 2107, + 2108, + 0x558, + 2105, + 2110, + 2112, + 0x84F, + 0x850, + 1131, + 1130, + 1129, + 1128, + 1745, + 3544, + 3543, + 2836 + ) + + companion object { + + /** + * varp bit offset for the abyss obstacles varbits + */ + const val ABYSS_OBSTACLES = 18 + // varp value, until the constant is defined in consntlib + const val VARP_SCENERY_ABYSS = 491 + + /** + * Represents teleporting to the abyss, + * including randomized location and rotating obstacles accordingly + */ + fun teleport(player: Player, npc: NPC) { + + var teleportLoc = AbyssLoc.randomLoc() + while(!teleportLoc.isValid()) { + teleportLoc = teleportLoc.attract() + } + + player.lock(3) +// npc.visualize(Animation(Animations.MAGE_OF_ZAMORAK_TELEOTHER_1979), Graphics(Gfx.TELEOTHER_PURPLE_BEAMS_4)) + npc.visualize(Animation(1979), Graphics(4)) + npc.sendChat("Veniens! Sallakar! Rinnesset!") + player.skills.decrementPrayerPoints(100.0) + removeTimer(player) + registerTimer(player, spawnTimer(2000)) + GameWorld.Pulser.submit(object : Pulse(2, player) { + override fun pulse(): Boolean { + rotateObstacles(player,teleportLoc) + player.properties.teleportLocation = teleportLoc.toAbs() + npc.updateMasks.reset() + return true + } + }) + } + + /** + * Represents getting the inner ring location corresponding to a node in the outer ring. + * Used to send a player to the inner ring when they pass an obstacle. + */ + fun innerRing(node: Node): Location { + val obstacleLoc = AbyssLoc.fromAbs(node.location) + var loc = obstacleLoc.attract(5) + while (!loc.isValid()) { + loc = loc.attract() + } + return loc.toAbs() + } + + + /** + * Represents rotating the abyssal obstacles for the player. + * Used to make sure the player lands by the blocked obstacle. + */ + fun rotateObstacles(player: Player, abyssLoc: AbyssLoc) { + setVarbit(player, 625, abyssLoc.getSegment(), true) + } + + /** + * Handles attempts at passing abyssal obstacles to get from outer ring to inner ring + */ + const val MINE_PROGRESS = 12 + const val CHOP_PROGRESS = 14 + const val BURN_PROGRESS = 16 + const val DISTRACT_PROGRESS = 18 + fun handleObstacle(obstacle: Node, player: Player, skill: Int, varbitVal: Int?, animation: Animation, messages: Array): Boolean { + log(this::class.java, Log.FINE, "handled abyss ${obstacle.name}") + player.lock() + player.animate(animation) + GameWorld.Pulser.submit(object : Pulse(1, player) { + var count = 0 + override fun pulse(): Boolean { + when (count++) { + 1 -> sendMessage(player, messages[0]) + 3 -> return if (RandomFunction.random(100) < getStatLevel(player,skill)+1) { + sendMessage(player, colorize("%G${messages[1]}")) + if(varbitVal != null) { setVarbit(player, 625, varbitVal) } + false + } else { + sendMessage(player, colorize("%R${messages[2]}")) + player.unlock() + true + } + 5 -> { + if(varbitVal != null) { setVarbit(player, 625, varbitVal or 1) } + } + 7 -> { + player.unlock() + player.properties.teleportLocation = innerRing(obstacle) + return true + } + } + return false + } + + override fun stop() { + super.stop() + player.animate(Animation(-1, Animator.Priority.HIGH)) + } + }) + return true + } + } +} + +/** + * Polar coordinates class for abyss + * @author lila + */ +class AbyssLoc(val radius: Double, val angle: Double) { + + /** + * Attract the location towards the center + */ + fun attract(steps: Int = 1): AbyssLoc { + return AbyssLoc(radius-steps.toDouble(),angle) + } + + /** + * Get the segment of an abyssloc - its angle as an integer modulo 12, with south = 0 and positive = clockwise + * this is used to determine which of the 12 evenly spaced obstacles around the outer ring the location is nearest to + */ + fun getSegment() : Int { + val segments = 12 + val angleToCircle = angle * segments / ( 2 * Math.PI ) + val angleSegment = (angleToCircle + 0.5).toInt() + // now 'normalize' the segment, so that 0 is the southernmost obstacle and 1 is clockwise from it + val normalSegment = ( 9 - angleSegment ).mod(12) + return normalSegment + } + + /** + * Transform back to absolute coordinates + */ + fun toAbs() : Location { + val x = (radius * cos(angle)).toInt() + val y = (radius * sin(angle)).toInt() + return origin.transform(x,y,0) + } + + /** + * Check if location is valid + */ + fun isValid() : Boolean { + val abs = toAbs() + return (RegionManager.isTeleportPermitted(abs) && RegionManager.getObject(abs) == null) + } + companion object { + + /** + * origin and outer radius values of the abyss itself + */ + // origin: the exact center of the abyss, inside that spinny ball thing + val origin = Location(3039,4832,0) + // the outer ring is generally at radius 24-26; testing shows that a minimum of 25.1 guarantees that players don't end up on an obstacle or inner wall + const val outerRadius = 25.1 + + /** + * turn an absolute location into an abyss location + */ + fun fromAbs(loc: Location) : AbyssLoc { + val local = Location.getDelta(origin,loc) + val radius = Math.sqrt((local.x * local.x + local.y * local.y).toDouble()) + val angle = Math.atan2(local.y.toDouble(),local.x.toDouble()) + return AbyssLoc(radius,angle) + } + + /** + * get a random location around the abyss outer ring + */ + fun randomLoc() : AbyssLoc { + val angle = Random.nextDouble() * 2 * Math.PI + return AbyssLoc(outerRadius,angle) + } + } +} diff --git a/Server/src/main/content/global/skill/runecrafting/abyss/AbyssalNPC.java b/Server/src/main/content/global/skill/runecrafting/abyss/AbyssalNPC.java new file mode 100644 index 0000000..f713fb6 --- /dev/null +++ b/Server/src/main/content/global/skill/runecrafting/abyss/AbyssalNPC.java @@ -0,0 +1,90 @@ +package content.global.skill.runecrafting.abyss; + +import content.global.skill.runecrafting.RunePouch; +import core.game.node.entity.Entity; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.map.Location; +import core.tools.RandomFunction; + +/** + * Handles an abyssal npc. + * @author Vexia + */ +public final class AbyssalNPC extends AbstractNPC { + + /** + * Constructs a new {@code AbyssalNPC} {@code Object}. + */ + public AbyssalNPC() { + super(0, null, true); + setAggressive(true); + } + + /** + * Constructs a new {@code AbyssalNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + public AbyssalNPC(int id, Location location) { + super(id, location, true); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new AbyssalNPC(id, location); + } + + @Override + public void init() { + super.init(); + this.setDefaultBehavior(); + } + + @Override + public void handleTickActions() { + super.handleTickActions(); + } + + @Override + public void finalizeDeath(Entity killer) { + super.finalizeDeath(killer); + if (killer instanceof Player) { + Player p = killer.asPlayer(); + if (RandomFunction.random(750) < 12) { + Item pouch = getPouch(p); + if (pouch != null) { + getDefinition().getDropTables().createDrop(pouch, p, this, getLocation()); + } + } + } + } + + /** + * Gets the next pouch item. + * @param player the player. + * @return the pouch. + */ + private Item getPouch(Player player) { + if (!player.hasItem(RunePouch.SMALL.getPouch())) { + return RunePouch.SMALL.getPouch(); + } + if (!player.hasItem(RunePouch.MEDIUM.getPouch()) && !player.hasItem(RunePouch.MEDIUM.getDecayedPouch())) { + return RunePouch.MEDIUM.getPouch(); + } + if (!player.hasItem(RunePouch.LARGE.getPouch()) && !player.hasItem(RunePouch.LARGE.getDecayedPouch())) { + return RunePouch.LARGE.getPouch(); + } + if (!player.hasItem(RunePouch.GIANT.getPouch()) && !player.hasItem(RunePouch.GIANT.getDecayedPouch())) { + return RunePouch.GIANT.getPouch(); + } + return null; + } + + @Override + public int[] getIds() { + return new int[] { 2263, 2264, 2265 }; + } + +} diff --git a/Server/src/main/content/global/skill/runecrafting/abyss/DarkMageDialogue.java b/Server/src/main/content/global/skill/runecrafting/abyss/DarkMageDialogue.java new file mode 100644 index 0000000..a7b6450 --- /dev/null +++ b/Server/src/main/content/global/skill/runecrafting/abyss/DarkMageDialogue.java @@ -0,0 +1,168 @@ +package content.global.skill.runecrafting.abyss; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import org.rs09.consts.Items; + +import static core.api.ContentAPIKt.replaceAllItems; + +/** + * Handles the dark mages dialogue. + * @author Vexia + */ +public final class DarkMageDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code DarkMageDialogue} {@code Object}. + */ + public DarkMageDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code DarkMageDialogue} {@code Object}. + * @param player the player. + */ + public DarkMageDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new DarkMageDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + if (args.length >= 2) { + if (repair()) { + npc("There, I have repaired your pouches.", "Now leave me alone. I'm concentrating."); + stage = 30; + return true; + } else { + npc("You don't seem to have any pouches in need of repair.", "Leave me alone."); + stage = 30; + return true; + } + } + player("Hello there."); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + npc("Quiet!", "You must not break my concentration!"); + stage++; + break; + case 1: + options("Why not?", "What are you doing here?", "Can you repair my pouches?","Ok, Sorry"); + stage++; + break; + case 2: + switch (buttonId) { + case 1: + player("Why not?"); + stage = 10; + break; + case 2: + player("What are you doing here?"); + stage = 20; + break; + case 3: + player("Can you repair my pouches, please?"); + stage = 50; + break; + case 4: + player("Ok, sorry."); + stage = 30; + break; + } + break; + case 10: + npc("Well, if my concentration is broken while keeping this", "gate open, then if we are lucky, everyone within a one", "mile radius will either have their heads explode, or will be", "consumed internally by the creatures of the Abyss."); + stage++; + break; + case 11: + player("Erm...", "And if we are unlucky?"); + stage++; + break; + case 12: + npc("If we are unlucky, then the entire universe will begin", "to fold in upon itself, and all reality as we know it will", "be annihilated in a single stroke."); + stage++; + break; + case 13: + npc("So leave me alone!"); + stage = 30; + break; + case 20: + npc("Do you mean what am I doing here in Abyssal space,", "Or are you asking me what I consider my ultimate role", "to be in this voyage that we call life?"); + stage++; + break; + case 21: + player("Um... the first one."); + stage++; + break; + case 22: + npc("By remaining here and holding this portal open, I am", "providing a permanent link between normal space and", "this strange dimension that we call Abyssal space."); + stage++; + break; + case 23: + npc("As long as this spell remains in effect, we have the", "capability to teleport into abyssal space at will."); + stage++; + break; + case 24: + npc("Now leave me be!", "I can afford no distraction in my task!"); + stage = 30; + break; + case 30: + end(); + break; + case 50: + npc("Fine, fine! Give them here."); + stage++; + break; + case 51: + repair(); + npc("There, I've repaired them all.","Now get out of my sight!"); + stage = 30; + break; + } + return true; + } + + /** + * Repairs pouches. + */ + private boolean repair() { + player.pouchManager.getPouches().forEach((id, pouch) -> { + pouch.setCurrentCap(pouch.getCapacity()); + pouch.setCharges(pouch.getMaxCharges()); + Item essItem = null; + if (!pouch.getContainer().isEmpty()) { + int essence = pouch.getContainer().get(0).getId(); + int amount = pouch.getContainer().getAmount(essence); + essItem = new Item(essence, amount); + } + pouch.remakeContainer(); + if (essItem != null) { + pouch.getContainer().add(essItem); + } + if (id != Items.SMALL_POUCH_5509) { + replaceAllItems(player, id + 1, id); + } + }); + return true; + } + + @Override + public int[] getIds() { + return new int[] { 2262 }; + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/runecrafting/abyss/ZamorakMageDialogue.java b/Server/src/main/content/global/skill/runecrafting/abyss/ZamorakMageDialogue.java new file mode 100644 index 0000000..ab06e48 --- /dev/null +++ b/Server/src/main/content/global/skill/runecrafting/abyss/ZamorakMageDialogue.java @@ -0,0 +1,476 @@ +package content.global.skill.runecrafting.abyss; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +import static core.api.ContentAPIKt.*; +import content.data.Quests; + + +/** + * Handles the zamorak mages dialogue. + * @author Vexia + */ +public final class ZamorakMageDialogue extends DialoguePlugin { + + /** + * The scrying orbs. + */ + private static final Item[] ORBS = new Item[] { new Item(5519), new Item(5518) }; + + /** + * If its the varrock mage. + */ + private boolean varrockMage; + + /** + * Constructs a new {@code ZamorakMageDialogue} {@code Object}. + */ + public ZamorakMageDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code ZamorakMageDialogue} {@code Object}. + * @param player the player. + */ + public ZamorakMageDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new ZamorakMageDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + varrockMage = npc.getId() == 2261 || npc.getId() == 2260; + if (!player.getQuestRepository().isComplete(Quests.RUNE_MYSTERIES)) { + end(); + player.sendMessage("The mage doesn't seem interested in talking to you."); + return true; + } + if (!varrockMage) { + switch (getStage()) { + case 0: + npc("Meet me in Varrock's Chaos Temple.", "Here is not the place to talk."); + break; + case 1: + case 2: + case 3: + npc("I already told you!", "meet me in the Varrock Chaos Temple!"); + break; + case 4: + npc("This is no place to talk!", "Meet me at the Varrock Chaos Temple!"); + break; + } + } else { + switch (getStage()) { + case 0: + npc("I am in no mood to talk to you", "stranger!"); + break; + case 1: + npc("Ah, you again.", "What was it you wanted?", "The wilderness is hardly the appropriate place for a", "conversation now, is it?"); + break; + case 2: + npc("Well?", "Have you managed to use my scrying orb to obtain the", "information yet?"); + break; + case 3: + player("So... that's my end of the deal upheld.", "What do I get in return?"); + break; + case 4: + options("So what is this 'abyss' stuff?", "Is this abyss dangerous?", "Can you teleport me there now?"); + break; + } + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + if (!varrockMage) { + switch (getStage()) { + case 0: + setStage(1); + end(); + break; + case 1: + case 2: + case 3: + case 4: + end(); + break; + } + } else { + switch (getStage()) { + case 0: + end(); + break; + case 1: + switch (stage) { + case 0: + options("I'd like to buy some runes!", "Where do you get your runes from?", "All hail Zamorak!", "Nothing, thanks."); + stage++; + break; + case 1: + switch (buttonId) { + case 1: + player("I'd like to buy some runes!"); + stage = 10; + break; + case 2: + player("Where do you get your runes from?", "No offence, but people around here don't exactly like", "'your type'."); + stage = 20; + break; + case 3: + player("All hail Zamorak!", "He's the man!", "If he can't do it, maybe some other guy can!"); + stage = 30; + break; + case 4: + player("I didn't really want anything, thanks.", "I just like talking to random people I meet around the", "world."); + stage = 40; + break; + } + break; + case 10: + npc("I do not conduct business in this pathetic city.", "Speak to me in the wilderness if you desire to purchase", "runes from me."); + stage++; + break; + case 11: + end(); + break; + case 20: + npc("My 'type' Explain."); + stage++; + break; + case 21: + player("You know...", "Scary bearded men in dark clothing with unhealthy", "obsessions with destruction and stuff."); + stage++; + break; + case 22: + npc("Hmmm.", "Well, you may be right, the foolish Saradominists that", "own this pathetic city don't appreciate loyal Zamorakians,", "it is true."); + stage++; + break; + case 23: + player("So you can't be getting your runes anywhere around", "here..."); + stage++; + break; + case 24: + npc("That is correct stranger.", "My mysteries of manufacturing Runes is a closely", "guarded secret of the Zamorakian brotherhood."); + stage++; + break; + case 25: + player("Oh, you mean the whole teleporting to the Rune", "essence mine, mining some essence, then using the", "talismans to locate the Rune Temples, then binding", "runes there?"); + stage++; + break; + case 26: + player("I know all about it..."); + stage++; + break; + case 27: + npc("WHAT?", "I... but... you..."); + stage++; + break; + case 28: + npc("Tell me, this is important:", "You know of the ancient temples?", "You have been to a place where this 'rune essence'", "material is freely available?"); + stage++; + break; + case 29: + npc("How did you get to such place?"); + stage = 200; + break; + case 200: + player("Well, I helped deliver some research notes to Sedridor", "at the Wizards Tower, and he teleported me to a huge", "mine he said was hidden off to the North somewhere", "where I could mine essence."); + stage++; + break; + case 201: + npc("And there is an abundant supply of this 'essence' there", "you say?"); + stage++; + break; + case 202: + player("Yes, but I thought you said that you knew how to make", "runes?", "All this stuff is fairly basic knowledge I thought."); + stage++; + break; + case 203: + npc("No.", "No, not at all."); + stage++; + break; + case 204: + npc("We occasionally manage to plunder small samples of this", "'essence' and we have recently discovered these temples", "you speak of, but I have never ever heard of these talismans", "before, and I was certainly not aware that this 'essence'"); + stage++; + break; + case 205: + npc("substance is a heavily stockpiled resource at the Wizards", "Tower."); + stage++; + break; + case 206: + npc("This changes everything."); + stage++; + break; + case 207: + player("How do you mean?"); + stage++; + break; + case 208: + npc("For many years there has been a struggle for power", "on this world.", "You may dispute the morality of each side as you wish,", "but the stalemate that exists between my Lord Zamorak"); + stage++; + break; + case 209: + npc("and that pathetic meddling fool Saradomin has meant", "that our struggle have become more secretive.", "We exist in a 'cold war' if you will, each side fearful of", "letting the other gain too much power, and each side"); + stage++; + break; + case 210: + npc("equally fearful of entering into open warfare for fear of", "bringing our struggles to the attention of... other", "beings."); + stage++; + break; + case 211: + player("You mean Guthix?"); + stage++; + break; + case 212: + npc("Indeed.", "Amongst others.", "But you now tell me that the Saradominist Wizards", "have the capability to mass produce runes, I can only"); + stage++; + break; + case 213: + npc("conclude that they have been doing so secretly for some", "time now."); + stage++; + break; + case 214: + npc("I implore you adventurer, you may or may not agree", "with my aims, but you cannot allow such a one-sided", "shift in the balance of power to occur."); + stage++; + break; + case 215: + npc("Will you help me and my fellow Zamorakians to access", "this 'essence' mine?", "In return I will share with you the research we have", "gathered."); + stage++; + break; + case 216: + player("Okay, I'll help you.", "What can I do?"); + stage++; + break; + case 217: + npc("All I need from you is the spell that will teleport me to", "this essence mine.", "That should be sufficient for the armies of Zamorak to", "once more begin stockpiling magic for war."); + stage++; + break; + case 218: + player("Oh.", "Erm...", "I don't actually know that spell."); + stage++; + break; + case 219: + npc("What?", "Then how do you access this location?"); + stage++; + break; + case 220: + player("Oh, well, people who do know the spell teleport me there", "directly.", "Apparently they wouldn't teach it to me to try and keep", "the location secret."); + stage++; + break; + case 221: + npc("Hmmm.", "Yes, yes I see.", "Very well then, you may still assist us in finding this", "mysterious essence mine."); + stage++; + break; + case 222: + player("How would I do that?"); + stage++; + break; + case 223: + setStage(2); + player.getInventory().add(ORBS[0], player); + npc("Here, take this scrying orb.", "I have cast a standard cypher spell upon it, so that it", "will absorb mystical energies that it is exposed to."); + stage++; + break; + case 30: + end(); + break; + case 40: + npc("...I see.", "Well, in the future, do not waste my time, or you will", "feel the wrath of Zamorak upon you."); + stage++; + break; + case 41: + end(); + break; + } + break; + case 2: + switch (stage) { + case 0: + if (!player.hasItem(ORBS[0]) && !player.getInventory().containsItem(ORBS[1])) { + player("Uh...", "No...", "I kinda lost that orb thingy that you gave me."); + stage++; + break; + } + if (!player.getInventory().containsItem(ORBS[1])) { + player("No...", "Actually, I had something I wanted to ask you..."); + stage = 3; + } else { + player("Yes I have! I've got it right here!"); + stage = 50; + } + break; + case 1: + player.getInventory().add(ORBS[0], player); + npc("What?", "Incompetent fool. Take this.", "And do not make me regret allying myself with you."); + stage++; + break; + case 2: + end(); + break; + case 3: + npc("I assume the task to be self-explanatory.", "What is it you wish to know?"); + stage++; + break; + case 4: + player("Please excuse me, I have a very bad short term", "memory.", "What exactly am I supposed to be doing again?"); + stage++; + break; + case 5: + npc("All I wish for you to do is to teleport to this 'rune", "essence' location from three different locations while", "carrying the scrying orb I gave you.", "It will collect the data as you teleport."); + stage++; + break; + case 6: + end(); + break; + case 224: + npc("Bring it with you and teleport to the rune essence", "location, and it will absorb the mechanics of the spell and", "allow us to reverse-engineer the magic behind it."); + stage++; + break; + case 225: + npc("The important part is that you must teleport to the", "essence location from three entirely seperate locations."); + stage++; + break; + case 226: + npc("More than three may be helpful to us, but we need a", "minimum of three in order to triangulate the position of", "this essence mine."); + stage++; + break; + case 227: + npc("Is that all clear, stranger?"); + stage++; + break; + case 228: + player("Yeah, I think so."); + stage++; + break; + case 229: + npc("Good.", "If you encounter any difficulties speak to me again."); + stage++; + break; + case 230: + end(); + break; + case 50: + npc("Excellent.", "Give it here, and I shall examine the findings.", "Speak to me in a small while."); + stage++; + break; + case 51: + setStage(3); + player.getInventory().remove(ORBS[1]); + end(); + break; + } + break; + case 3: + switch (stage) { + case 0: + npc("Indeed, a deal is always a deal."); + stage++; + break; + case 1: + npc("I offer you three things as a reward for your efforts on", "behalf of my Lord Zamorak;"); + stage++; + break; + case 2: + npc("The first is knowledge.", "I offer you my collected research on the abyss.", "I also offer you 1000 points of experience in", "RuneCrafting for your trouble."); + stage++; + break; + case 3: + npc("Your second gift is convenience.", "Here you may take this pouch I discovered amidst my", "research.", "You will find it to have certain... interesting properties."); + stage++; + break; + case 4: + npc("Your final gift is that of movement", "I will from now on offer you a teleport to the abyss", "whenever you should require it."); + stage++; + break; + case 5: + setStage(4); + player.getInventory().add(new Item(5520), player); + player.getInventory().add(new Item(5509), player); + player.getSkills().addExperience(Skills.RUNECRAFTING, 1000); + player("Huh?", "Abyss?", "What are you talking about?", "You told me that you would help me with"); + stage++; + break; + } + break; + case 4: + switch (stage) { + case 0: + switch (buttonId) { + case 1: + player("Uh...", "I really don't see how this talk about an 'abyss' relates", "to RuneCrafting in the slightest..."); + stage = 10; + break; + case 2: + player("So...", "This 'abyss' place...", "Is it dangerous?"); + stage = 20; + break; + case 3: + player("Well, I reckon I'm prepared to go there now.", "Beam me there, or whatever it is that you do!"); + stage = 30; + break; + } + break; + case 10: + npc("My primary research responsibility was not towards the", "manufacture of runes, this is true."); + stage = 8; + break; + case 20: + npc("Well, the creatures there ARE particularly offensive..."); + stage = 8; + break; + case 30: + npc("No, not from here.", "The use of my Lord Zamorak magic in this land will", "draw too much attention to myself."); + stage = 8; + break; + case 6: + player("RuneCrafting!"); + stage++; + break; + case 7: + npc("And so I have done.", "Read my research notes, they may enlighten you", "somewhat."); + stage++; + break; + case 8: + end(); + break; + } + break; + } + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 2257, 2258, 2259, 2260, 2261 }; + } + + /** + * Sets the stage. + * @param stage the stage. + */ + public void setStage(int stage) { + setVarp(player, 492, stage, true); + } + + /** + * Gets the stage. + * @return the stage. + */ + public int getStage() { + return getVarp(player, 492); + } +} diff --git a/Server/src/main/content/global/skill/skillcapeperks/Skillcape.kt b/Server/src/main/content/global/skill/skillcapeperks/Skillcape.kt new file mode 100644 index 0000000..b69a2b5 --- /dev/null +++ b/Server/src/main/content/global/skill/skillcapeperks/Skillcape.kt @@ -0,0 +1,62 @@ +package content.global.skill.skillcapeperks + +enum class Skillcape { + ATTACK, + STRENGTH, + DEFENCE, + RANGING, + PRAYER, + MAGIC, + RUNECRAFTING, + HITPOINTS, + AGILITY, + HERBLORE, + THIEVING, + CRAFTING, + FLETCHING, + SLAYER, + CONSTRUCTION, + MINING, + SMITHING, + FISHING, + COOKING, + FIREMAKING, + WOODCUTTING, + FARMING, + HUNTING, + SUMMONING, + NONE + ; + companion object{ + @JvmStatic + fun forId(id: Int): Skillcape{ + return when(id){ + 9747,9748 -> ATTACK + 9750,9751 -> STRENGTH + 9753,9754 -> DEFENCE + 9756,9757 -> RANGING + 9759,9760 -> PRAYER + 9762,9763 -> MAGIC //magic + 9765,9766 -> RUNECRAFTING //runecrafting + 9768,9769 -> HITPOINTS //hp + 9771,9772 -> AGILITY //agility + 9774,9775 -> HERBLORE //herblore + 9777,9778 -> THIEVING //thieving + 9780,9781 -> CRAFTING //crafting + 9783,9784 -> FLETCHING //fletching + 9786,9787 -> SLAYER //slayer + 9789,9790 -> CONSTRUCTION //construction + 9792,9793 -> MINING //mining + 9795,9796 -> SMITHING //smithing + 9798,9799 -> FISHING //fishing + 9801,9802 -> COOKING //cooking + 9804,9805 -> FIREMAKING //firemaking + 9807,9808 -> WOODCUTTING //woodcutting + 9810,9811 -> FARMING //farming + 9948,9949 -> HUNTING //hunting + 12169,12170 -> SUMMONING //summoning + else -> NONE + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/skillcapeperks/SkillcapeEquipmentPlugin.kt b/Server/src/main/content/global/skill/skillcapeperks/SkillcapeEquipmentPlugin.kt new file mode 100644 index 0000000..0ad090f --- /dev/null +++ b/Server/src/main/content/global/skill/skillcapeperks/SkillcapeEquipmentPlugin.kt @@ -0,0 +1,27 @@ +package content.global.skill.skillcapeperks + +import core.game.interaction.InteractionListener + +class SkillcapeEquipmentPlugin : InteractionListener { + override fun defineListeners() { + val capeIds = ArrayList() + for(cape in content.data.skill.SkillcapePerks.values()){ + cape.skillcapeIds.forEach { capeIds.add(it) } + } + val capes = capeIds.toIntArray() + + onEquip(capes){player, node -> + val skillcape = Skillcape.forId(node.id) + val perk = SkillcapePerks.forSkillcape(skillcape) + perk.activate(player) + return@onEquip true + } + + onUnequip(capes){player, node -> + val skillcape = Skillcape.forId(node.id) + val perk = SkillcapePerks.forSkillcape(skillcape) + perk.deactivate(player) + return@onUnequip true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/skillcapeperks/SkillcapeOperatePlugin.kt b/Server/src/main/content/global/skill/skillcapeperks/SkillcapeOperatePlugin.kt new file mode 100644 index 0000000..3b0bf60 --- /dev/null +++ b/Server/src/main/content/global/skill/skillcapeperks/SkillcapeOperatePlugin.kt @@ -0,0 +1,30 @@ +package content.global.skill.skillcapeperks + +import core.cache.def.impl.ItemDefinition +import core.game.interaction.OptionHandler +import core.game.node.Node +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.plugin.Plugin + +@Initializable +class SkillcapeOperatePlugin : OptionHandler() { + override fun newInstance(arg: Any?): Plugin { + for(cape in content.data.skill.SkillcapePerks.values()){ + cape.skillcapeIds.forEach { + ItemDefinition.forId(it).handlers["option:operate"] = this + } + } + return this + } + + override fun handle(player: Player?, node: Node?, option: String?): Boolean { + player ?: return false + val skillcape = Skillcape.forId(node?.id ?: 0) + val perk = SkillcapePerks.forSkillcape(skillcape) + + perk.operate(player) + return true + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/skillcapeperks/SkillcapePerks.kt b/Server/src/main/content/global/skill/skillcapeperks/SkillcapePerks.kt new file mode 100644 index 0000000..7dbc199 --- /dev/null +++ b/Server/src/main/content/global/skill/skillcapeperks/SkillcapePerks.kt @@ -0,0 +1,298 @@ +package content.global.skill.skillcapeperks + +import core.game.component.Component +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.SpellBookManager +import core.game.node.entity.player.link.TeleportManager +import content.global.skill.runecrafting.Altar +import core.game.world.map.Location +import core.game.world.map.zone.impl.DarkZone +import core.plugin.Initializable +import core.game.world.GameWorld +import content.global.skill.farming.* +import core.ServerStore +import core.ServerStore.Companion.getBoolean +import core.ServerStore.Companion.getInt +import core.api.* +import core.cache.def.impl.ItemDefinition +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import content.data.Quests + +enum class SkillcapePerks(val attribute: String, val effect: ((Player) -> Unit)? = null) { + BAREFISTED_SMITHING("cape_perks:barefisted-smithing"), + DIVINE_FAVOR("cape_perks:divine-favor"), + CONSTANT_GLOW("cape_perks:eternal-glow"), + PRECISION_MINER("cape_perks:precision-miner"), + GREAT_AIM("cape_perks:great-aim"), + NEST_HUNTER("cape_perks:nest-hunter"), + PRECISION_STRIKES("cape_perks:precision-strikes"), + FINE_ATTUNEMENT("cape_perks:fine-attunement"), + GRAND_BULLWARK("cape_perks:grand-bullwark"), + ACCURATE_MARKSMAN("cape_perks:accurate-marksman"), + DAMAGE_SPONG("cape_perks:damage-sponge"), + MARATHON_RUNNER("cape_perks:marathon-runner"), + LIBRARIAN_MAGUS("cape_perks:librarian-magus",{player -> + val store = ServerStore.getArchive("daily-librarian-magus") + val used = store.getInt(player.name,0) + if (used >= 3) { + player.dialogueInterpreter.sendDialogue("Your cape is still on cooldown.") + } else { + player.dialogueInterpreter.open(509871234) + store[player.name] = used + 1 + } + }), + ABYSS_WARPING("cape_perks:abyss_warp",{player -> + val store = ServerStore.getArchive("daily-abyss-warp") + val used = store.getInt(player.name,0) + if (used >= 3) { + player.dialogueInterpreter.sendDialogue("Your cape is still on cooldown.") + } else { + player.dialogueInterpreter.open(509871233) + } + }), + SEED_ATTRACTION("cape_perks:seed_attract",{player -> + val store = ServerStore.getArchive("daily-seed-attract") + if (store.getBoolean(player.name)) { + player.dialogueInterpreter.sendDialogue("Your cape is still on cooldown.") + } else { + val possibleSeeds = Plantable.values() + for(i in 0 until 10){ + var seed = possibleSeeds.random() + while(seed == Plantable.SCARECROW || seed.applicablePatch == PatchType.FRUIT_TREE_PATCH || seed.applicablePatch == PatchType.TREE_PATCH || seed.applicablePatch == PatchType.SPIRIT_TREE_PATCH){ + seed = possibleSeeds.random() + } + val reward = core.game.node.item.Item(seed.itemID) + if(!player.inventory.add(reward)){ + core.game.node.item.GroundItemManager.create(reward,player) + } + } + player.dialogueInterpreter.sendDialogue("You pluck off the seeds that were stuck to your cape.") + store[player.name] = true + } + }), + TRICKS_OF_THE_TRADE("cape_perks:tott",{player -> + val hasHelmetBonus = getAttribute(player, "cape_perks:tott:helmet-stored", false) + if(hasHelmetBonus){ + sendDialogue(player, "Your cape's pockets are lined with all the utilities you need for slayer.") + } else { + sendDialogue(player, "Your cape is lined with empty pockets shaped like various utilities needed for slayer.") + } + }), + HASTY_COOKING("cape_perks:hasty-cooking"), + SMOOTH_HANDS("cape_perks:smooth-hands"), + PET_MASTERY("cape_perks:pet-mastery"), + BREWMASTER("cape_perks:brewmaster"), + NONE("cape_perks:none") + ; + + companion object{ + @JvmStatic + fun isActive(perk: SkillcapePerks, player: Player): Boolean{ + return player.getAttribute(perk.attribute,false) + } + + fun forSkillcape(skillcape: Skillcape): SkillcapePerks{ + return when(skillcape){ + Skillcape.ATTACK -> PRECISION_STRIKES + Skillcape.STRENGTH -> FINE_ATTUNEMENT + Skillcape.DEFENCE -> GRAND_BULLWARK + Skillcape.RANGING -> ACCURATE_MARKSMAN + Skillcape.PRAYER -> DIVINE_FAVOR + Skillcape.MAGIC -> LIBRARIAN_MAGUS + Skillcape.RUNECRAFTING -> ABYSS_WARPING + Skillcape.HITPOINTS -> DAMAGE_SPONG + Skillcape.AGILITY -> MARATHON_RUNNER + Skillcape.HERBLORE -> BREWMASTER + Skillcape.THIEVING -> SMOOTH_HANDS + Skillcape.CRAFTING -> NONE + Skillcape.FLETCHING -> NONE + Skillcape.SLAYER -> TRICKS_OF_THE_TRADE + Skillcape.CONSTRUCTION -> NONE + Skillcape.MINING -> PRECISION_MINER + Skillcape.SMITHING -> BAREFISTED_SMITHING + Skillcape.FISHING -> GREAT_AIM + Skillcape.COOKING -> HASTY_COOKING + Skillcape.FIREMAKING -> CONSTANT_GLOW + Skillcape.WOODCUTTING -> NEST_HUNTER + Skillcape.FARMING -> SEED_ATTRACTION + Skillcape.HUNTING -> NONE + Skillcape.SUMMONING -> PET_MASTERY + else -> NONE + } + } + } + + fun activate(player: Player){ + if(GameWorld.settings?.skillcape_perks != true){ + return + } + if(!isActive(this,player)){ + player.setAttribute("/save:$attribute",true) + } + player.debug("Activated ${this.name}") + if(this == CONSTANT_GLOW) + DarkZone.checkDarkArea(player) + } + + fun operate(player: Player){ + if(GameWorld.settings?.skillcape_perks != true){ + player.sendMessage("This item can not be operated.") + return + } + effect?.invoke(player) + } + + fun deactivate(player: Player){ + player.removeAttribute(attribute) + if(this == CONSTANT_GLOW) + DarkZone.checkDarkArea(player) + } + + @Initializable + class MagicCapeDialogue(player: Player? = null): core.game.dialogue.DialoguePlugin(player){ + override fun newInstance(player: Player?): core.game.dialogue.DialoguePlugin { + return MagicCapeDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + when(player.spellBookManager.spellBook){ + SpellBookManager.SpellBook.ANCIENT.interfaceId -> options("Modern","Lunar") + SpellBookManager.SpellBook.MODERN.interfaceId -> options("Ancient","Lunar") + SpellBookManager.SpellBook.LUNAR.interfaceId -> options ("Modern","Ancient") + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + val spellbook = when(player.spellBookManager.spellBook){ + SpellBookManager.SpellBook.ANCIENT.interfaceId -> { + when(buttonId){ + 1 -> SpellBookManager.SpellBook.MODERN + 2 -> SpellBookManager.SpellBook.LUNAR + else -> null + } + } + + SpellBookManager.SpellBook.MODERN.interfaceId -> { + when(buttonId){ + 1 -> SpellBookManager.SpellBook.ANCIENT + 2 -> SpellBookManager.SpellBook.LUNAR + else -> null + } + } + + SpellBookManager.SpellBook.LUNAR.interfaceId -> { + when(buttonId){ + 1 -> SpellBookManager.SpellBook.MODERN + 2 -> SpellBookManager.SpellBook.ANCIENT + else -> null + } + } + + else -> null + } + + end() + if(spellbook != null){ + if (spellbook == SpellBookManager.SpellBook.ANCIENT) { + if (!hasRequirement(player, Quests.DESERT_TREASURE)) + return true + } + else if (spellbook == SpellBookManager.SpellBook.LUNAR) { + if (!hasRequirement(player, Quests.LUNAR_DIPLOMACY)) + return true + } + player.spellBookManager.setSpellBook(spellbook) + player.interfaceManager.openTab(Component(spellbook.interfaceId)) + player.incrementAttribute("/save:cape_perks:librarian-magus-charges",-1) + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(509871234) + } + + } + + @Initializable + class RCCapeDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin(player){ + override fun newInstance(player: Player?): core.game.dialogue.DialoguePlugin { + return RCCapeDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + altarList(0) + stage = 0 + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage) { + 0 -> when(buttonId) { + 1 -> sendAltar(player, Altar.AIR) + 2 -> sendAltar(player, Altar.MIND) + 3 -> sendAltar(player, Altar.WATER) + 4 -> sendAltar(player, Altar.EARTH) + 5 -> altarList(++stage) + } + 1 -> when(buttonId) { + 1 -> altarList(--stage) + 2 -> sendAltar(player, Altar.FIRE) + 3 -> sendAltar(player, Altar.BODY) + 4 -> sendAltar(player, Altar.COSMIC) + 5 -> altarList(++stage) + } + 2 -> when(buttonId) { + 1 -> altarList(--stage) + 2 -> sendAltar(player, Altar.CHAOS) + 3 -> sendAltar(player, Altar.ASTRAL) + 4 -> sendAltar(player, Altar.NATURE) + 5 -> altarList(++stage) + } + 3 -> when(buttonId) { + 1 -> altarList(--stage) + 2 -> sendAltar(player, Altar.LAW) + 3 -> sendAltar(player, Altar.DEATH) + 4 -> sendAltar(player, Altar.BLOOD) + 5 -> altarList(0).also { stage = 0 } + } + } + return true + } + + fun altarList(stage: Int) { + when (stage) { + 0 -> options("Air", "Mind", "Water", "Earth", "More...") + 1 -> options("Back...", "Fire", "Body", "Cosmic", "More...") + 2 -> options("Back...", "Chaos", "Astral", "Nature", "More...") + 3 -> options("Back...", "Law", "Death", "Blood", "More...") + } + } + + fun sendAltar(player: Player,altar: Altar) { + end() + if (altar == Altar.DEATH && !hasRequirement(player, Quests.MOURNINGS_END_PART_II)) return + if (altar == Altar.ASTRAL && !hasRequirement(player, Quests.LUNAR_DIPLOMACY)) return + if (altar == Altar.BLOOD && !hasRequirement(player, Quests.LEGACY_OF_SEERGAZE)) return + if (altar == Altar.LAW && !ItemDefinition.canEnterEntrana(player)) { + sendMessage(player, "The power of Saradomin prevents you from taking armour or weaponry to Entrana."); + return + } + + var endLoc = if (altar == Altar.ASTRAL) Location.create(2151, 3864, 0) else altar.ruin.end + + val store = ServerStore.getArchive("daily-abyss-warp") + val used = store.getInt(player.name,0) + store[player.name] = used + 1 + player.teleporter.send(endLoc, TeleportManager.TeleportType.TELE_OTHER) + player.incrementAttribute("/save:cape_perks:abyssal_warp",-1) + } + + override fun getIds(): IntArray { + return intArrayOf(509871233) + } + + } +} diff --git a/Server/src/main/content/global/skill/slayer/AberrantSpectreNPC.java b/Server/src/main/content/global/skill/slayer/AberrantSpectreNPC.java new file mode 100644 index 0000000..e32e6e4 --- /dev/null +++ b/Server/src/main/content/global/skill/slayer/AberrantSpectreNPC.java @@ -0,0 +1,86 @@ +package content.global.skill.slayer; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.skill.Skills; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.node.entity.combat.MagicSwingHandler; + +/** + * Handles the aberrant spectre npc. + * @author Vexia + */ +@Initializable +public final class AberrantSpectreNPC extends AbstractNPC { + + /** + * The skills to drain. + */ + private static final int[] SKILLS = new int[] { Skills.ATTACK, Skills.STRENGTH, Skills.DEFENCE, Skills.RANGE, Skills.MAGIC, Skills.PRAYER, Skills.AGILITY }; + + /** + * The combat handler to use. + */ + private static final MagicSwingHandler COMBAT_HANDLER = new MagicSwingHandler() { + @Override + public void impact(final Entity entity, final Entity victim, BattleState state) { + if (victim instanceof Player) { + Player player = (Player) victim; + if (!SlayerEquipmentFlags.hasNosePeg(player)) { + for (int skill : SKILLS) { + int drain = (int) (player.getSkills().getStaticLevel(skill) * 0.5); + player.getSkills().updateLevel(skill, -drain, 0); + } + } + } + super.impact(entity, victim, state); + } + }; + + /** + * Constructs a new {@code AberrantSpectreNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + public AberrantSpectreNPC(int id, Location location) { + super(id, location); + } + + /** + * Constructs a new {@code AberrantSpectreNPC} {@code Object}. + */ + public AberrantSpectreNPC() { + super(0, null); + } + + @Override + public void checkImpact(BattleState state) { + super.checkImpact(state); + if (state.getAttacker() instanceof Player) { + final Player player = (Player) state.getAttacker(); + if (!SlayerEquipmentFlags.hasNosePeg(player)) { + state.neutralizeHits(); + } + } + } + + @Override + public CombatSwingHandler getSwingHandler(boolean swing) { + return COMBAT_HANDLER; + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new AberrantSpectreNPC(id, location); + } + + @Override + public int[] getIds() { + return Tasks.ABERRANT_SPECTRES.getNpcs(); + } + +} diff --git a/Server/src/main/content/global/skill/slayer/AbyssalDemonNPC.java b/Server/src/main/content/global/skill/slayer/AbyssalDemonNPC.java new file mode 100644 index 0000000..ababe2b --- /dev/null +++ b/Server/src/main/content/global/skill/slayer/AbyssalDemonNPC.java @@ -0,0 +1,73 @@ +package content.global.skill.slayer; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.node.entity.combat.MeleeSwingHandler; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.tools.RandomFunction; + +import static core.api.ContentAPIKt.getPathableRandomLocalCoordinate; + +/** + * Handles the abyssal npc. + * @author Vexia + */ +@Initializable +public class AbyssalDemonNPC extends AbstractNPC { + + /** + * The melee swing handler. + */ + private static final MeleeSwingHandler SWING_HANDLER = new MeleeSwingHandler() { + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + if (victim instanceof Player && RandomFunction.random(8) <= 2) { + boolean npc = RandomFunction.random(100) <= 50; + Entity source = npc ? victim : entity; + Entity teleported = npc ? entity : victim; + Location loc = getPathableRandomLocalCoordinate(teleported, 1, source.getLocation(), 3); + teleported.graphics(Graphics.create(409)); + teleported.teleport(loc, 1); + } + return super.swing(entity, victim, state); + } + }; + + /** + * Constructs a new {@Code AbyssalNPC} {@Code Object} + */ + public AbyssalDemonNPC() { + super(-1, null); + } + + /** + * Constructs a new {@Code AbyssalNPC} {@Code Object} + * @param id the id. + * @param location the location. + */ + public AbyssalDemonNPC(int id, Location location) { + super(id, location); + } + + @Override + public CombatSwingHandler getSwingHandler(boolean swing) { + return SWING_HANDLER; + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new AbyssalDemonNPC(id, location); + } + + @Override + public int[] getIds() { + return Tasks.ABYSSAL_DEMONS.getNpcs(); + } + +} diff --git a/Server/src/main/content/global/skill/slayer/BansheeNPC.java b/Server/src/main/content/global/skill/slayer/BansheeNPC.java new file mode 100644 index 0000000..da0babf --- /dev/null +++ b/Server/src/main/content/global/skill/slayer/BansheeNPC.java @@ -0,0 +1,116 @@ +package content.global.skill.slayer; + +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.node.entity.combat.InteractionType; +import core.game.node.entity.combat.MeleeSwingHandler; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.tools.RandomFunction; + +/** + * Handles the banshee npc. + * @author Vexia + */ +@Initializable +public final class BansheeNPC extends AbstractNPC { + + /** + * The skills to drain. + */ + private static final int[] SKILLS = new int[] { Skills.ATTACK, Skills.STRENGTH, Skills.DEFENCE, Skills.RANGE, Skills.MAGIC, Skills.PRAYER, Skills.AGILITY }; + + /** + * The combat handler. + */ + private static final MeleeSwingHandler COMBAT_HANDLER = new MeleeSwingHandler() { + @Override + public void impact(Entity entity, Entity victim, BattleState state) { + if (victim instanceof Player) { + final Player player = (Player) victim; + if (!hasEarMuffs(player)) { + if (RandomFunction.random(10) < 4 && player.getProperties().getCombatPulse().getNextAttack() <= GameWorld.getTicks()) { + player.getWalkingQueue().reset(); + player.getLocks().lockMovement(3); + player.getProperties().getCombatPulse().setNextAttack(3); + player.animate(new Animation(1572, Priority.HIGH)); + } + for (int skill : SKILLS) { + int drain = (int) (player.getSkills().getStaticLevel(skill) * 0.5); + player.getSkills().updateLevel(skill, -drain, 0); + } + state.setEstimatedHit(8); + } + } + super.impact(entity, victim, state); + } + + @Override + public InteractionType isAttackable(Entity entity, Entity victim) { + return CombatStyle.MAGIC.getSwingHandler().isAttackable(entity, victim); + } + }; + + /** + * Constructs a new {@code BansheeNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + public BansheeNPC(int id, Location location) { + super(id, location); + } + + /** + * Constructs a new {@code BansheeNPC} {@code Object}. + */ + public BansheeNPC() { + super(0, null); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new BansheeNPC(id, location); + } + + @Override + public void onImpact(Entity entity, BattleState state) { + super.onImpact(entity, state); + if (state.getAttacker() instanceof Player) { + final Player player = (Player) state.getAttacker(); + if (!hasEarMuffs(player)) { + state.neutralizeHits(); + } + } + if (state.getEstimatedHit() > 0 || state.getSecondaryHit() > 0) { + getSkills().heal(1); + } + } + + @Override + public CombatSwingHandler getSwingHandler(boolean swing) { + return COMBAT_HANDLER; + } + + /** + * Checks if the player has ear muffs. + * @param player the player. + * @return {@code True} if they have it. + */ + public static boolean hasEarMuffs(Player player) { + return SlayerEquipmentFlags.hasEarmuffs(player); + } + + @Override + public int[] getIds() { + return new int[] { 1612 }; + } + +} diff --git a/Server/src/main/content/global/skill/slayer/BasiliskNPC.java b/Server/src/main/content/global/skill/slayer/BasiliskNPC.java new file mode 100644 index 0000000..6c5a5a5 --- /dev/null +++ b/Server/src/main/content/global/skill/slayer/BasiliskNPC.java @@ -0,0 +1,53 @@ +package content.global.skill.slayer; + +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.node.entity.npc.AbstractNPC; +import core.game.world.map.Location; +import core.plugin.Initializable; + +/** + * Handles the basilisk npc. + * @author Vexia + */ +@Initializable +public final class BasiliskNPC extends AbstractNPC { + + /** + * Constructs a new {@code BasiliskNPC} {@code Object}. + */ + public BasiliskNPC() { + super(0, null); + } + + /** + * Constructs a new {@code BasiliskNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + public BasiliskNPC(int id, Location location) { + super(id, location); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new BasiliskNPC(id, location); + } + + @Override + public CombatSwingHandler getSwingHandler(boolean swing) { + return MirrorShieldHandler.SINGLETON; + } + + @Override + public void checkImpact(BattleState state) { + super.checkImpact(state); + MirrorShieldHandler.SINGLETON.checkImpact(state); + } + + @Override + public int[] getIds() { + return new int[] { 1616, 1617 }; + } + +} diff --git a/Server/src/main/content/global/skill/slayer/BrutalDragonNPC.java b/Server/src/main/content/global/skill/slayer/BrutalDragonNPC.java new file mode 100644 index 0000000..401c759 --- /dev/null +++ b/Server/src/main/content/global/skill/slayer/BrutalDragonNPC.java @@ -0,0 +1,69 @@ +package content.global.skill.slayer; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.equipment.SwitchAttack; +import content.global.handlers.item.equipment.special.DragonfireSwingHandler; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.npc.AbstractNPC; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.node.entity.combat.MultiSwingHandler; + +/** + * Handles a brutal dragon npc. + * @author Vexia + */ +@Initializable +public final class BrutalDragonNPC extends AbstractNPC { + + /** + * The dragonfire attack. + */ + private static final SwitchAttack DRAGONFIRE = DragonfireSwingHandler.get(false, 52, new Animation(81, Priority.HIGH), Graphics.create(1), null, null); + + /** + * Handles the combat. + */ + private final CombatSwingHandler combatAction = new MultiSwingHandler(true, new SwitchAttack(CombatStyle.MELEE.getSwingHandler(), new Animation(80, Priority.HIGH)), new SwitchAttack(CombatStyle.MELEE.getSwingHandler(), new Animation(80, Priority.HIGH)), new SwitchAttack(CombatStyle.MAGIC.getSwingHandler(), new Animation(81, Priority.HIGH), null, null, Projectile.create((Entity) null, null, 500, 20, 20, 41, 40, 18, 255)), DRAGONFIRE); + + /** + * Constructs a new {@code BrutalDragonNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + public BrutalDragonNPC(int id, Location location) { + super(id, location); + } + + /** + * Constructs a new {@code MithrilDragonNPC} {@code Object}. + */ + public BrutalDragonNPC() { + super(0, null); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new BrutalDragonNPC(id, location); + } + + @Override + public CombatSwingHandler getSwingHandler(boolean swing) { + return combatAction; + } + + @Override + public int getDragonfireProtection(boolean fire) { + return 0x2 | 0x4 | 0x8; + } + + @Override + public int[] getIds() { + return new int[] { 5362 }; + } +} diff --git a/Server/src/main/content/global/skill/slayer/BugSwarmNPC.java b/Server/src/main/content/global/skill/slayer/BugSwarmNPC.java new file mode 100644 index 0000000..5617a7d --- /dev/null +++ b/Server/src/main/content/global/skill/slayer/BugSwarmNPC.java @@ -0,0 +1,65 @@ +package content.global.skill.slayer; + +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.map.Location; +import core.plugin.Initializable; + +/** + * Represents the plugin used to handle the harpie bug swarm. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class BugSwarmNPC extends AbstractNPC { + + /** + * Represents the lit latern item. + */ + private static final Item LIT_LANTERN = new Item(7053); + + /** + * Constructs a new {@code BugSwarmNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + public BugSwarmNPC(int id, Location location) { + super(id, location, true); + } + + /** + * Constructs a new {@code BugSwarmNPC} {@code Object}. + */ + public BugSwarmNPC() { + super(0, null); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new BugSwarmNPC(id, location); + } + + @Override + public void checkImpact(BattleState state) { + super.checkImpact(state); + if (state.getAttacker() instanceof Player) { + final Player player = (Player) state.getAttacker(); + if (!player.getEquipment().containsItem(LIT_LANTERN)) { + if (state.getEstimatedHit() > -1) { + state.setEstimatedHit(0); + } + if (state.getSecondaryHit() > -1) { + state.setSecondaryHit(0); + } + } + } + } + + @Override + public int[] getIds() { + return new int[] { 3153 }; + } + +} diff --git a/Server/src/main/content/global/skill/slayer/BuglanternPlugin.java b/Server/src/main/content/global/skill/slayer/BuglanternPlugin.java new file mode 100644 index 0000000..80a930d --- /dev/null +++ b/Server/src/main/content/global/skill/slayer/BuglanternPlugin.java @@ -0,0 +1,95 @@ +package content.global.skill.slayer; + +import core.cache.def.impl.ItemDefinition; +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.OptionHandler; +import core.game.interaction.UseWithHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Plugin; + +/** + * Represents the plugin used to handle a bug lantern. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class BuglanternPlugin implements Plugin { + + /** + * Represents the unlit lantern item. + */ + private static final Item UNLIT_LANTERN = new Item(7051); + + /** + * Represents the lit latern item. + */ + private static final Item LIT_LANTERN = new Item(7053); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + new LightLanternPlugin().newInstance(arg); + ItemDefinition.forId(LIT_LANTERN.getId()).getHandlers().put("option:extinguish", new OptionHandler() { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + if (player.getInventory().remove(LIT_LANTERN)) { + player.getInventory().add(UNLIT_LANTERN); + } + return true; + } + + @Override + public boolean isWalk() { + return false; + } + }); + return this; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + /** + * Represents the plugin used to light the lantern. + * @author 'Vexia + * @version 1.0 + */ + public final class LightLanternPlugin extends UseWithHandler { + + /** + * Constructs a new {@code LightLanternPlugin} {@code Object}. + */ + public LightLanternPlugin() { + super(590); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(UNLIT_LANTERN.getId(), ITEM_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + if (player.getSkills().getLevel(Skills.FIREMAKING) < 33) { + player.sendMessage("You need a Firemaking level of at least 33 in order to do this."); + return true; + } + player.getInventory().replace(LIT_LANTERN, event.getUsedItem().getSlot()); + return true; + } + + } +} diff --git a/Server/src/main/content/global/skill/slayer/CaveBugNPC.java b/Server/src/main/content/global/skill/slayer/CaveBugNPC.java new file mode 100644 index 0000000..66a883d --- /dev/null +++ b/Server/src/main/content/global/skill/slayer/CaveBugNPC.java @@ -0,0 +1,60 @@ +package content.global.skill.slayer; + +import core.game.node.entity.Entity; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.plugin.Initializable; + +/** + * Handles the cave bug npc. + * @author Vexia + * + */ +@Initializable +public class CaveBugNPC extends AbstractNPC { + + /** + * The cave border. + */ +// private static final ZoneBorders CAVE_BORDER = new ZoneBorders(3139, 9534, 3260, 9587); + + /** + * Constructs the {@code CaveBugNPC} + */ + public CaveBugNPC() { + super(-1, null); + } + + /** + * Constructs the {@code CaveBugNPC} + * @param id The id. + * @param location The location. + */ + public CaveBugNPC(int id, Location location) { + super(id, location); + } + + @Override + public void finalizeDeath(Entity killer) { + super.finalizeDeath(killer); + if (killer instanceof Player) { + Player p = killer.asPlayer(); +/* AchievementDiary diary = p.getAchievementDiaryManager().getDiary(DiaryType.LUMBRIDGE); + if (!diary.isComplete(0, 0) && CAVE_BORDER.insideBorder(p)) { + diary.updateTask(p, 0, 0, true); + }*/ + } + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new CaveBugNPC(id, location); + } + + @Override + public int[] getIds() { + return new int[] {1832, 1833, 5750}; + } + +} diff --git a/Server/src/main/content/global/skill/slayer/CaveHorrorNPC.java b/Server/src/main/content/global/skill/slayer/CaveHorrorNPC.java new file mode 100644 index 0000000..1bb4945 --- /dev/null +++ b/Server/src/main/content/global/skill/slayer/CaveHorrorNPC.java @@ -0,0 +1,85 @@ +package content.global.skill.slayer; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.node.entity.combat.InteractionType; +import core.game.node.entity.combat.MeleeSwingHandler; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.tools.RandomFunction; + +/** + * Handles the Cave Horrors on Mos'le Harmless. You technically do not need a witchwood icon to fight them. + * "Without the icon, cave horrors can damage the player for 10% of their total hitpoints, although it does not lower stats." + * @author Splinter + */ +@Initializable +public final class CaveHorrorNPC extends AbstractNPC { + /** + * The Cave Horror combat handler. + */ + private static final MeleeSwingHandler COMBAT_HANDLER = new MeleeSwingHandler() { + @Override + public void impact(Entity entity, Entity victim, BattleState state) { + if (victim instanceof Player) { + final Player player = (Player) victim; + if (!hasWitchwood(player)) { + if (RandomFunction.random(10) < 5) { + state.setEstimatedHit(player.getSkills().getLifepoints() / 10); + } + } + } + super.impact(entity, victim, state); + } + + @Override + public InteractionType isAttackable(Entity entity, Entity victim) { + return CombatStyle.MELEE.getSwingHandler().isAttackable(entity, victim); + } + }; + + /** + * Constructs a new {@code CaveHorrorNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + public CaveHorrorNPC(int id, Location location) { + super(id, location); + } + + /** + * Constructs a new {@code CaveHorrorNPC} {@code Object}. + */ + public CaveHorrorNPC() { + super(0, null); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new CaveHorrorNPC(id, location); + } + + @Override + public CombatSwingHandler getSwingHandler(boolean swing) { + return COMBAT_HANDLER; + } + + /** + * Checks if the player has the icon equipped. + * @param player the player. + * @return {@code true} if it is equipped. + */ + public static boolean hasWitchwood(Player player) { + return SlayerEquipmentFlags.hasWitchwoodIcon(player); + } + + @Override + public int[] getIds() { + return new int[] { 4354, 4355, 4353, 4356, 4357 }; + } + +} diff --git a/Server/src/main/content/global/skill/slayer/CockatriceNPC.java b/Server/src/main/content/global/skill/slayer/CockatriceNPC.java new file mode 100644 index 0000000..2885456 --- /dev/null +++ b/Server/src/main/content/global/skill/slayer/CockatriceNPC.java @@ -0,0 +1,53 @@ +package content.global.skill.slayer; + +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.node.entity.npc.AbstractNPC; +import core.game.world.map.Location; +import core.plugin.Initializable; + +/** + * Handles a cockatrice npc. + * @author Vexia + */ +@Initializable +public final class CockatriceNPC extends AbstractNPC { + + /** + * Constructs a new {@code CockatriceNPC} {@code Object}. + */ + public CockatriceNPC() { + super(0, null); + } + + /** + * Constructs a new {@code CockatriceNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + public CockatriceNPC(int id, Location location) { + super(id, location); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new CockatriceNPC(id, location); + } + + @Override + public CombatSwingHandler getSwingHandler(boolean swing) { + return MirrorShieldHandler.SINGLETON; + } + + @Override + public void checkImpact(BattleState state) { + super.checkImpact(state); + MirrorShieldHandler.SINGLETON.checkImpact(state); + } + + @Override + public int[] getIds() { + return new int[] { 1620, 1621 }; + } + +} diff --git a/Server/src/main/content/global/skill/slayer/DesertLizardPlugin.java b/Server/src/main/content/global/skill/slayer/DesertLizardPlugin.java new file mode 100644 index 0000000..49cc5a8 --- /dev/null +++ b/Server/src/main/content/global/skill/slayer/DesertLizardPlugin.java @@ -0,0 +1,148 @@ +package content.global.skill.slayer; + +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.ImpactHandler.HitsplatType; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.map.Location; +import core.plugin.Plugin; + +/** + * Represents the dezert lizard plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class DesertLizardPlugin implements Plugin { + + /** + * Represents the ids to use. + */ + private static final int[] IDS = new int[] { 2803, 2804, 2805, 2806, 2807, 2808 }; + + @Override + public Plugin newInstance(Object arg) throws Throwable { + new IcecoolerPlugin().newInstance(arg); + new DezertLizardNPC().newInstance(arg); + return this; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + /** + * Represents the ice cooler plugin. + * @author 'Vexia + * @version 1.0 + */ + public static final class IcecoolerPlugin extends UseWithHandler { + + /** + * Represents the ice cooler item. + */ + private static final Item ICE_COOLER = new Item(6696); + + /** + * Constructs a new {@code IcecoolerPlugin} {@code Object}. + */ + public IcecoolerPlugin() { + super(ICE_COOLER.getId()); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (int id : IDS) { + addHandler(id, NPC_TYPE, this); + } + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + if (player.getSkills().getLevel(Skills.SLAYER) < 22) { + player.getPacketDispatch().sendMessage("You need a Slayer level of at least 22 to do this."); + return true; + } + final NPC npc = (NPC) event.getUsedWith(); + if (npc.getSkills().getLifepoints() > 2) { + player.getPacketDispatch().sendMessage("The lizard isn't weak enough to be affected by the icy water."); + return true; + } + if (player.getInventory().remove(ICE_COOLER)) { + npc.getImpactHandler().manualHit(player, npc.getSkills().getLifepoints(), HitsplatType.NORMAL); + player.getPacketDispatch().sendMessage("The lizard shudders and collapses from the freezing water."); + } + return true; + } + + } + + /** + * Represents the desert lizard npc. + * @author 'Vexia + * @version 1.0 + */ + public final class DezertLizardNPC extends AbstractNPC { + + /** + * Constructs a new {@code DezertLizardNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + public DezertLizardNPC(int id, Location location) { + super(id, location); + } + + /** + * Constructs a new {@code DezertLizardNPC} {@code Object}. + */ + public DezertLizardNPC() { + super(0, null); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new DezertLizardNPC(id, location); + } + + @Override + public void checkImpact(BattleState state) { + super.checkImpact(state); + int lifepoints = getSkills().getLifepoints(); + if (state.getEstimatedHit() > -1) { + lifepoints -= state.getEstimatedHit(); + if (lifepoints < 1) { + state.setEstimatedHit(lifepoints - 1); + } + if (state.getEstimatedHit() < 0) { + state.setEstimatedHit(0); + getSkills().setLifepoints(2); + } + } + if (state.getSecondaryHit() > -1) { + lifepoints -= state.getSecondaryHit(); + if (lifepoints < 1) { + state.setSecondaryHit(lifepoints - 1); + } + if (state.getSecondaryHit() < 0) { + state.setSecondaryHit(0); + } + } + } + + @Override + public int[] getIds() { + return IDS; + } + + } +} diff --git a/Server/src/main/content/global/skill/slayer/DustDevilNPC.java b/Server/src/main/content/global/skill/slayer/DustDevilNPC.java new file mode 100644 index 0000000..081e04d --- /dev/null +++ b/Server/src/main/content/global/skill/slayer/DustDevilNPC.java @@ -0,0 +1,95 @@ +package content.global.skill.slayer; + +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.node.entity.combat.InteractionType; +import core.game.node.entity.combat.MeleeSwingHandler; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.world.map.Location; + +/** + * Handles the dust devil npc. + * @author Vexia + */ +@Initializable +public final class DustDevilNPC extends AbstractNPC { + + /** + * The skills. + */ + private static final int[] SKILLS = new int[] { Skills.ATTACK, Skills.STRENGTH, Skills.RANGE, Skills.MAGIC }; + + /** + * The combat handler. + */ + private static final MeleeSwingHandler COMBAT_HANDLER = new MeleeSwingHandler() { + @Override + public void impact(Entity entity, Entity victim, BattleState state) { + if (victim instanceof Player) { + final Player player = (Player) victim; + if (!SlayerEquipmentFlags.hasFaceMask(player)) { + for (int i : SKILLS) { + player.getSkills().updateLevel(i, -player.getSkills().getStaticLevel(i), 0); + } + player.getSkills().decrementPrayerPoints((double) player.getSkills().getStaticLevel(Skills.PRAYER) / 2); + state.setEstimatedHit(14); + } + } + super.impact(entity, victim, state); + } + + @Override + public InteractionType isAttackable(Entity entity, Entity victim) { + return CombatStyle.MAGIC.getSwingHandler().isAttackable(entity, victim); + } + }; + + /** + * Constructs a new {@code DustDevilNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + public DustDevilNPC(int id, Location location) { + super(id, location); + super.getProperties().getCombatPulse().setHandler(COMBAT_HANDLER); + } + + /** + * Constructs a new {@code DustDevilNPC} {@code Object}. + */ + public DustDevilNPC() { + super(0, null); + } + + @Override + public CombatSwingHandler getSwingHandler(boolean swing) { + return COMBAT_HANDLER; + } + + @Override + public void checkImpact(BattleState state) { + super.checkImpact(state); + if (state.getAttacker() instanceof Player) { + Player player = (Player) state.getAttacker(); + if (!SlayerEquipmentFlags.hasFaceMask(player)) { + state.neutralizeHits(); + } + } + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new DustDevilNPC(id, location); + } + + @Override + public int[] getIds() { + return Tasks.DUST_DEVILS.getNpcs(); + } + +} diff --git a/Server/src/main/content/global/skill/slayer/GargoyleNPC.java b/Server/src/main/content/global/skill/slayer/GargoyleNPC.java new file mode 100644 index 0000000..e944ca3 --- /dev/null +++ b/Server/src/main/content/global/skill/slayer/GargoyleNPC.java @@ -0,0 +1,118 @@ +package content.global.skill.slayer; + +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.ImpactHandler.HitsplatType; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.plugin.Plugin; +import org.rs09.consts.Items; +import core.plugin.ClassScanner; + +/** + * Handles the gargoyle npc. + * @author Vexia + */ +@Initializable +public final class GargoyleNPC extends AbstractNPC { + + /** + * Constructs a new {@code GargoyleNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + public GargoyleNPC(int id, Location location) { + super(id, location); + } + + /** + * Constructs a new {@code GargoyleNPC} {@code Object}. + */ + public GargoyleNPC() { + super(0, null); + } + + @Override + public void checkImpact(BattleState state) { + super.checkImpact(state); + int lp = getSkills().getLifepoints(); + if (state.getEstimatedHit() > -1) { + if (lp - state.getEstimatedHit() < 1) { + state.setEstimatedHit(0); + if (lp > 1) { + state.setEstimatedHit(lp - 1); + } + } + } + if (state.getSecondaryHit() > -1) { + if (lp - state.getSecondaryHit() < 1) { + state.setSecondaryHit(0); + if (lp > 1) { + state.setSecondaryHit(lp - 1); + } + } + } + int totalHit = state.getEstimatedHit() + state.getSecondaryHit(); + if (lp - totalHit < 1) { + state.setEstimatedHit(0); + state.setSecondaryHit(0); + } + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ClassScanner.definePlugin(new RockHammerHandler()); + return super.newInstance(arg); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new GargoyleNPC(id, location); + } + + @Override + public int[] getIds() { + return Tasks.GARGOYLES.getNpcs(); + } + + /** + * The rock hammer handler plugin. + * @author Vexia + */ + public final class RockHammerHandler extends UseWithHandler { + + /** + * Constructs a new {@code RockHammerHandler} {@code Object}. + */ + public RockHammerHandler() { + super(Items.ROCK_HAMMER_4162); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (int id : getIds()) { + addHandler(id, NPC_TYPE, this); + } + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + final NPC npc = (NPC) event.getUsedWith(); + if (npc.getSkills().getLifepoints() > 10) { + player.getPacketDispatch().sendMessage("The gargoyle isn't weak enough to be harmed by the hammer."); + } else { + player.getPacketDispatch().sendMessage("The gargoyle cracks apart."); + npc.getImpactHandler().manualHit(player, npc.getSkills().getLifepoints(), HitsplatType.NORMAL); + } + return true; + } + + } + +} diff --git a/Server/src/main/content/global/skill/slayer/InfernalMageNPC.java b/Server/src/main/content/global/skill/slayer/InfernalMageNPC.java new file mode 100644 index 0000000..8689bef --- /dev/null +++ b/Server/src/main/content/global/skill/slayer/InfernalMageNPC.java @@ -0,0 +1,48 @@ +package content.global.skill.slayer; + +import core.game.node.entity.combat.spell.CombatSpell; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.world.map.Location; +import core.plugin.Initializable; + +/** + * Handles the infernal mage npc. + * @author Vexia + */ +@Initializable +public final class InfernalMageNPC extends AbstractNPC { + + /** + * Constructs a new {@code InfernalMageNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + public InfernalMageNPC(int id, Location location) { + super(id, location); + } + + /** + * Constructs a new {@code InfernalMageNPC} {@code Object}. + */ + public InfernalMageNPC() { + super(0, null); + } + + @Override + public void init() { + super.init(); + getProperties().setAutocastSpell((CombatSpell) SpellBook.MODERN.getSpell(8)); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new InfernalMageNPC(id, location); + } + + @Override + public int[] getIds() { + return Tasks.INFERNAL_MAGES.getNpcs(); + } + +} diff --git a/Server/src/main/content/global/skill/slayer/KuraskNPC.java b/Server/src/main/content/global/skill/slayer/KuraskNPC.java new file mode 100644 index 0000000..4f7daa5 --- /dev/null +++ b/Server/src/main/content/global/skill/slayer/KuraskNPC.java @@ -0,0 +1,58 @@ +package content.global.skill.slayer; + +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.plugin.Initializable; + +/** + * Handles the kurask npc. + * @author Vexia + */ +@Initializable +public final class KuraskNPC extends AbstractNPC { + + /** + * Constructs a new {@code KuraskNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + public KuraskNPC(int id, Location location) { + super(id, location); + } + + /** + * Constructs a new {@code KuraskNPC} {@code Object}. + */ + public KuraskNPC() { + super(0, null); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new KuraskNPC(id, location); + } + + @Override + public void checkImpact(final BattleState state) { + super.checkImpact(state); + boolean effective = false; + if (state.getAttacker() instanceof Player) { + final Player player = (Player) state.getAttacker(); + effective = SlayerUtils.hasBroadWeaponEquipped(player, state); + } + if (!effective) { + state.setEstimatedHit(0); + if (state.getSecondaryHit() > 0) { + state.setSecondaryHit(0); + } + } + } + + @Override + public int[] getIds() { + return new int[] { 1608, 1609, 4229 }; + } + +} diff --git a/Server/src/main/content/global/skill/slayer/Master.java b/Server/src/main/content/global/skill/slayer/Master.java new file mode 100644 index 0000000..aad0fa5 --- /dev/null +++ b/Server/src/main/content/global/skill/slayer/Master.java @@ -0,0 +1,289 @@ +package content.global.skill.slayer; + +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; + +/** + * A non-garbage way of representing slayer masters + * Source for task amounts: ... + * Need to add a source for weights + * @author ceik + * @author gregf + */ +public enum Master { + TURAEL(8273, 3, 0, new int[]{15, 50}, new int[]{0, 0, 0}, + new Task(Tasks.BANSHEE, 8), + new Task(Tasks.BATS, 7), + new Task(Tasks.BEARS, 7), + new Task(Tasks.BIRDS, 6), + new Task(Tasks.CAVE_BUG, 8), + new Task(Tasks.CAVE_CRAWLERS, 8), + new Task(Tasks.CAVE_SLIMES, 8), + new Task(Tasks.COWS, 8), + new Task(Tasks.CRAWLING_HAND, 8), + new Task(Tasks.DESERT_LIZARDS, 8), + new Task(Tasks.DOG, 7), + new Task(Tasks.DWARF, 7), + new Task(Tasks.GHOSTS, 7), + new Task(Tasks.GOBLINS, 7), + new Task(Tasks.ICE_FIENDS, 8), + new Task(Tasks.KALPHITES, 6), + new Task(Tasks.MINOTAURS, 7), + new Task(Tasks.MONKEYS, 6), + new Task(Tasks.SCORPIONS, 7), + new Task(Tasks.SKELETONS, 7), + new Task(Tasks.SPIDERS, 6), + new Task(Tasks.WOLVES, 7), + new Task(Tasks.ZOMBIES, 7)), + + MAZCHNA(8274, 20, 0, new int[]{40, 70}, new int[]{2, 5, 15}, + new Task(Tasks.BANSHEE, 8), + new Task(Tasks.BATS,7), + new Task(Tasks.BEARS,6), + new Task(Tasks.CATABLEPONS,8), + new Task(Tasks.CAVE_BUG,8), + new Task(Tasks.CAVE_CRAWLERS, 8), + new Task(Tasks.CAVE_SLIMES, 8), + new Task(Tasks.COCKATRICES, 8), + new Task(Tasks.CRAWLING_HAND, 8), + new Task(Tasks.DESERT_LIZARDS, 8), + new Task(Tasks.DOG,7), + new Task(Tasks.EARTH_WARRIORS,6), + new Task(Tasks.FLESH_CRAWLERS,7), + new Task(Tasks.GHOSTS,7), + new Task(Tasks.GHOULS, 7), + new Task(Tasks.HILL_GIANTS,7), + new Task(Tasks.HOBGOBLINS, 7), + new Task(Tasks.ICE_WARRIOR, 7), + new Task(Tasks.KALPHITES,6), + new Task(Tasks.MOGRES, 8), + new Task(Tasks.PYREFIENDS, 8), + new Task(Tasks.ROCK_SLUGS,8), + new Task(Tasks.SHADE,8), + new Task(Tasks.SKELETONS, 7), + new Task(Tasks.VAMPIRES, 6), + // new Task(Tasks.WALL_BEASTS,7), + new Task(Tasks.WOLVES, 7), + new Task(Tasks.ZOMBIES,7)), + + VANNAKA(1597, 40, 0, new int[]{60, 120}, new int[]{4, 20, 60}, + new Task(Tasks.ABERRANT_SPECTRES, 8), + new Task(Tasks.ANKOU,7), + new Task(Tasks.BANSHEE,6), + new Task(Tasks.BASILISKS,8), + new Task(Tasks.BLUE_DRAGONS,7), + new Task(Tasks.BLOODVELDS,8), + new Task(Tasks.BRINE_RATS,7), + new Task(Tasks.CAVE_BUG,7), + new Task(Tasks.CAVE_CRAWLERS,7), + new Task(Tasks.CAVE_SLIMES,7), + new Task(Tasks.COCKATRICES,8), + new Task(Tasks.CRAWLING_HAND,6), + new Task(Tasks.CROCODILES,6, new Integer[]{30, 60}), + new Task(Tasks.DAGANNOTHS, 7), + new Task(Tasks.DESERT_LIZARDS,7, new Integer[]{30, 60}), + new Task(Tasks.DUST_DEVILS,8), + new Task(Tasks.EARTH_WARRIORS,6, new Integer[]{30, 60}), + new Task(Tasks.ELVES, 7, new Integer[]{30, 60}), + //new Task(Tasks.FEVER_SPIDERS,7), + new Task(Tasks.FIRE_GIANTS,7), + new Task(Tasks.GHOULS,7), + new Task(Tasks.GREEN_DRAGONS,6, new Integer[]{30, 60}), + new Task(Tasks.HARPIE_BUG_SWARMS,8), + new Task(Tasks.HELLHOUNDS,7), + new Task(Tasks.HILL_GIANTS,7), + new Task(Tasks.ICE_GIANTS,7, new Integer[]{30, 60}), + new Task(Tasks.ICE_WARRIOR,7), + new Task(Tasks.INFERNAL_MAGES,8), + new Task(Tasks.JELLIES,8), + new Task(Tasks.JUNGLE_HORRORS, 8), + new Task(Tasks.KALPHITES,7), + // new Task(Tasks.KILLERWATTS,6), + new Task(Tasks.KURASKS,7), + new Task(Tasks.LESSER_DEMONS,7), + new Task(Tasks.MOGRES,7), + // new Task(Tasks.MOLANISKS,7), + new Task(Tasks.MOSS_GIANTS,7), + new Task(Tasks.OGRES,7), + new Task(Tasks.OTHERWORDLY_BEING,8), + new Task(Tasks.PYREFIENDS,8), + new Task(Tasks.ROCK_SLUGS,7), + // new Task(Tasks.SEA_SNAKES,6), + new Task(Tasks.SHADE,8), + // new Task(Tasks.SHADOW_WARRIORS, 8), + new Task(Tasks.TROLLS,7), + new Task(Tasks.TUROTHS, 8), + new Task(Tasks.VAMPIRES,7), + // new Task(Tasks.WALL_BEASTS,6), + new Task(Tasks.WEREWOLVES,7)), + + CHAELDAR(1598, 70, 0, new int[]{110, 170}, new int[]{10, 50, 150}, + new Task(Tasks.ABERRANT_SPECTRES,8), + new Task(Tasks.ABYSSAL_DEMONS,12), + new Task(Tasks.BANSHEE, 5), + new Task(Tasks.BASILISKS,7), + new Task(Tasks.BLUE_DRAGONS,8), + new Task(Tasks.BLOODVELDS,8), + new Task(Tasks.BRINE_RATS,7), + new Task(Tasks.BRONZE_DRAGONS,11, new Integer[]{30, 60}), + new Task(Tasks.CAVE_BUG, 5), + new Task(Tasks.CAVE_CRAWLERS, 5), + new Task(Tasks.CAVE_HORRORS,10), + new Task(Tasks.CAVE_SLIMES,6), + new Task(Tasks.COCKATRICES,6), + new Task(Tasks.CRAWLING_HAND, 5), + new Task(Tasks.CROCODILES, 5, new Integer[]{30, 60}), + new Task(Tasks.DAGANNOTHS,11), + new Task(Tasks.DESERT_LIZARDS, 5, new Integer[]{30, 60}), + new Task(Tasks.DUST_DEVILS,9), + new Task(Tasks.ELVES,8, new Integer[]{60, 90}), + //new Task(Tasks.FEVER_SPIDERS,7), + new Task(Tasks.FIRE_GIANTS, 12), + new Task(Tasks.GARGOYLES,11), + new Task(Tasks.GREATER_DEMONS,9), + new Task(Tasks.HARPIE_BUG_SWARMS,6), + new Task(Tasks.HELLHOUNDS,9), + new Task(Tasks.IRON_DRAGONS,12, new Integer[]{30, 60}), + new Task(Tasks.INFERNAL_MAGES,7), + new Task(Tasks.JELLIES, 10), + new Task(Tasks.JUNGLE_HORRORS,10), + new Task(Tasks.KALPHITES,11), + new Task(Tasks.KURASKS, 12), + new Task(Tasks.LESSER_DEMONS,9), + new Task(Tasks.MOGRES,6), + // new Task(Tasks.MOLANISKS,6), + //new Task(Tasks.MUTATED_ZYGOMITES,7, new Integer[]{30, 60}), + new Task(Tasks.NECHRYAELS, 12), + new Task(Tasks.PYREFIENDS,6), + new Task(Tasks.ROCK_SLUGS, 5), + // new Task(Tasks.SHADOW_WARRIORS,8), + new Task(Tasks.SPIRTUAL_WARRIORS,4), + new Task(Tasks.SPIRTUAL_RANGERS,4), + new Task(Tasks.SPIRTUAL_MAGES,4), + new Task(Tasks.TROLLS,11), + new Task(Tasks.TUROTHS, 10)), + // new Task(Tasks.WALL_BEASTS,6, new Integer[]{10, 20}), + // new Task(Tasks.WARPED_TERROR_BIRD, 5), + // new Task(Tasks.WARPED_TORTOISE, 5) + + SUMONA(7780, 85, 35, new int[]{120, 185}, new int[]{12, 60, 180}, + new Task(Tasks.ABERRANT_SPECTRES, 15), + new Task(Tasks.ABYSSAL_DEMONS, 10), + new Task(Tasks.AVIANSIES, 10), + new Task(Tasks.BANSHEE, 15), + new Task(Tasks.BASILISKS, 15), + new Task(Tasks.BLACK_DEMONS, 10), + new Task(Tasks.BLUE_DRAGONS, 5), + new Task(Tasks.BLOODVELDS, 10), + new Task(Tasks.CAVE_CRAWLERS, 15), + new Task(Tasks.CAVE_HORRORS, 15), + new Task(Tasks.DAGANNOTHS, 10), + new Task(Tasks.DUST_DEVILS, 15), + new Task(Tasks.ELVES, 10, new Integer[]{60, 90}), + new Task(Tasks.FIRE_GIANTS, 10), + new Task(Tasks.GARGOYLES, 10), + new Task(Tasks.GREATER_DEMONS, 10), + new Task(Tasks.HELLHOUNDS, 10), + new Task(Tasks.IRON_DRAGONS, 7, new Integer[]{30, 60}), + new Task(Tasks.KALPHITES, 10), + new Task(Tasks.KURASKS, 15), + new Task(Tasks.NECHRYAELS, 10), + new Task(Tasks.RED_DRAGONS, 5), + // new Task(Tasks.SCABARITES, 9, new Integer[]{30, 60}), + new Task(Tasks.SPIRTUAL_MAGES, 10), + new Task(Tasks.SPIRTUAL_WARRIORS, 10), + // new Task(Tasks.TERROR_DOGS, 10, new Integer[]{30, 60}), + new Task(Tasks.TROLLS, 10), + new Task(Tasks.TUROTHS, 15)), + // new Task(Tasks.WARPED_TORTOISE, 15)), + + DURADEL(8275, 100, 50, new int[]{130, 200}, new int[]{15, 75, 225}, + new Task(Tasks.ABERRANT_SPECTRES,7), + new Task(Tasks.ABYSSAL_DEMONS,12), + new Task(Tasks.AVIANSIES, 10), + new Task(Tasks.BLACK_DEMONS,8), + new Task(Tasks.BLACK_DRAGONS,9, new Integer[]{40, 80}), + new Task(Tasks.BLOODVELDS,8), + new Task(Tasks.DAGANNOTHS,9), + new Task(Tasks.DARK_BEASTS,11), + new Task(Tasks.DUST_DEVILS,5), + new Task(Tasks.FIRE_GIANTS,7), + new Task(Tasks.GARGOYLES,8), + new Task(Tasks.GORAKS,9), + new Task(Tasks.GREATER_DEMONS,9), + new Task(Tasks.HELLHOUNDS, 10), + new Task(Tasks.IRON_DRAGONS,5, new Integer[]{40, 80}), + new Task(Tasks.KALPHITES,9), + new Task(Tasks.MITHRIL_DRAGONS,9, new Integer[]{4, 8}), + new Task(Tasks.NECHRYAELS,9), + // new Task(Tasks.SCABARITES, 9, new Integer[]{40, 80}), + new Task(Tasks.SKELETAL_WYVERN,7, new Integer[]{40, 80}), + new Task(Tasks.SPIRTUAL_MAGES,2), + new Task(Tasks.STEEL_DRAGONS,7, new Integer[]{40, 80}), + new Task(Tasks.SUQAHS,8, new Integer[]{40, 80}), + // new Task(Tasks.WARPED_TERROR_BIRD,8), + new Task(Tasks.WATERFIENDS,2)); + + private static final HashMap idMap = new HashMap<>(); + + static{ + Arrays.stream(Master.values()).forEach(m -> idMap.putIfAbsent(m.npc_id, m)); + } + + final int npc_id; + final int required_combat; + final int required_slayer; + public final int[] default_assignment_range; + final int[] streakPoints; + public final List tasks; + Master(int npc_id, int required_combat, int required_slayer, int[] default_assignment_range, int[] streakPoints, Task... tasks) { + this.npc_id = npc_id; + this.required_combat = required_combat; + this.required_slayer = required_slayer; + this.default_assignment_range = default_assignment_range; + this.streakPoints = streakPoints; + this.tasks = new ArrayList<>(Arrays.asList(tasks)); + } + + public static Master forId(int id){ + return idMap.get(id); + } + + public int getNpc(){ + return this.npc_id; + } + + public int[] getTaskPoints(){ + return streakPoints; + } + + public boolean hasRequirements(Player player){ + return player.getProperties().getCurrentCombatLevel() >= this.required_combat && player.getSkills().getLevel(Skills.SLAYER) >= this.required_slayer; + } + + public static boolean hasSameTask(Master master, Player player){ + return master.tasks.stream().filter(task -> task.task == SlayerManager.getInstance(player).getTask()).count() != 0; + } + + public static class Task{ + public Tasks task; + public Integer weight; + public Integer[] task_range; + public Task(Tasks task, Integer weight){ + this.task = task; + this.weight = weight; + this.task_range = new Integer[]{null, null}; + } + + Task(Tasks task, Integer weight, Integer[] task_range){ + this.task = task; + this.weight = weight; + this.task_range = task_range; + } + } +} diff --git a/Server/src/main/content/global/skill/slayer/MirrorShieldHandler.java b/Server/src/main/content/global/skill/slayer/MirrorShieldHandler.java new file mode 100644 index 0000000..87cfea3 --- /dev/null +++ b/Server/src/main/content/global/skill/slayer/MirrorShieldHandler.java @@ -0,0 +1,66 @@ +package content.global.skill.slayer; + +import core.game.node.entity.skill.Skills; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.MeleeSwingHandler; +import core.game.node.entity.player.Player; + +/** + * The swing handler for an npc that requires a mirror shield with its victim. + * @author Vexia + * @version 1.0 + */ +public final class MirrorShieldHandler extends MeleeSwingHandler { + + /** + * The singleton of this handler. + */ + public static final MirrorShieldHandler SINGLETON = new MirrorShieldHandler(); + + /** + * The skills to drain. + */ + private static final int[] SKILLS = new int[] { Skills.ATTACK, Skills.STRENGTH, Skills.DEFENCE, Skills.RANGE }; + + @Override + public void impact(Entity entity, Entity victim, BattleState state) { + if (victim instanceof Player) { + final Player player = (Player) victim; + if (!hasShield(player)) { + state.setEstimatedHit(11); + for (int skill : SKILLS) { + int drain = (int) (player.getSkills().getStaticLevel(skill) * 0.25); + player.getSkills().updateLevel(skill, -drain, player.getSkills().getStaticLevel(skill) - drain); + } + } + } + super.impact(entity, victim, state); + } + + /** + * Checks the impact of a victim with or without a shield. + * @param state the state. + */ + public void checkImpact(final BattleState state) { + if (state.getAttacker() instanceof Player) { + final Player player = (Player) state.getAttacker(); + if (!hasShield(player)) { + state.setEstimatedHit(0); + if (state.getSecondaryHit() > 0) { + state.setSecondaryHit(0); + } + } + } + } + + /** + * Checks if the player has the mirror shield. + * @param player the player. + * @return {@code True} if so. + */ + private static boolean hasShield(final Player player) { + return SlayerEquipmentFlags.hasMirrorShield(player); + } + +} diff --git a/Server/src/main/content/global/skill/slayer/MithrilDragonNPC.java b/Server/src/main/content/global/skill/slayer/MithrilDragonNPC.java new file mode 100644 index 0000000..aa9e966 --- /dev/null +++ b/Server/src/main/content/global/skill/slayer/MithrilDragonNPC.java @@ -0,0 +1,97 @@ +package content.global.skill.slayer; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.equipment.SwitchAttack; +import content.global.handlers.item.equipment.special.DragonfireSwingHandler; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.npc.AbstractNPC; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.tools.RandomFunction; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.node.entity.combat.MultiSwingHandler; + +/** + * Handles a mithril dragon npc. + * @author Vexia + */ +@Initializable +public final class MithrilDragonNPC extends AbstractNPC { + + /** + * The dragonfire attack. + */ + private static final SwitchAttack DRAGONFIRE = DragonfireSwingHandler.get(false, 52, new Animation(81, Priority.HIGH), Graphics.create(1), null, null); + + /** + * Handles the combat. + */ + private final CombatSwingHandler combatAction = new MultiSwingHandler(true, new SwitchAttack(CombatStyle.MELEE.getSwingHandler(), new Animation(80, Priority.HIGH)), new SwitchAttack(CombatStyle.MELEE.getSwingHandler(), new Animation(80, Priority.HIGH)), new SwitchAttack(CombatStyle.MAGIC.getSwingHandler(), new Animation(81, Priority.HIGH), null, null, Projectile.create((Entity) null, null, 500, 20, 20, 41, 40, 18, 255)), DRAGONFIRE, new SwitchAttack(CombatStyle.RANGE.getSwingHandler(), new Animation(81, Priority.HIGH), null, null, Projectile.create((Entity) null, null, 16, 20, 20, 41, 40, 18, 255))); + + /** + * Constructs a new {@code MithrilDragonNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + public MithrilDragonNPC(int id, Location location) { + super(id, location); + } + + /** + * Constructs a new {@code MithrilDragonNPC} {@code Object}. + */ + public MithrilDragonNPC() { + super(0, null); + } + + @Override + public void sendImpact(BattleState state) { + CombatStyle style = state.getStyle(); + if (style == null) { + return; + } + int maxHit = state.getEstimatedHit(); + if (maxHit < 1) { + return; + } + switch (style) { + case MELEE: + maxHit = 28; + break; + case MAGIC: + maxHit = 18; + break; + case RANGE: + maxHit = 18; + break; + } + if (state.getEstimatedHit() > maxHit) { + state.setEstimatedHit(RandomFunction.random(maxHit - 5, maxHit)); + } + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new MithrilDragonNPC(id, location); + } + + @Override + public CombatSwingHandler getSwingHandler(boolean swing) { + return combatAction; + } + + @Override + public int getDragonfireProtection(boolean fire) { + return 0x2 | 0x4 | 0x8; + } + + @Override + public int[] getIds() { + return Tasks.MITHRIL_DRAGONS.getNpcs(); + } +} diff --git a/Server/src/main/content/global/skill/slayer/MogreNPC.kt b/Server/src/main/content/global/skill/slayer/MogreNPC.kt new file mode 100644 index 0000000..c1f5fce --- /dev/null +++ b/Server/src/main/content/global/skill/slayer/MogreNPC.kt @@ -0,0 +1,33 @@ +package content.global.skill.slayer + +import core.game.node.entity.Entity +import core.game.node.entity.npc.AbstractNPC +import core.game.world.map.Location +import org.rs09.consts.NPCs + +/** + * Represents a mogre npc. + * @author 'Vexia + * @author gregf36665 + * @version 2.0 + */ +class MogreNPC : AbstractNPC(NPCs.MOGRE_114, null) { + + override fun tick() { + super.tick() + val victim = properties.combatPulse.getVictim() + if (victim != null) { + if (victim.location.getDistance(getLocation()) > 15) { + clear() + } + } + } + + override fun construct(id: Int, location: Location?, vararg objects: Any?): AbstractNPC { + return MogreNPC() + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.MOGRE_114) + } +} diff --git a/Server/src/main/content/global/skill/slayer/NechryaelBehavior.kt b/Server/src/main/content/global/skill/slayer/NechryaelBehavior.kt new file mode 100644 index 0000000..da44565 --- /dev/null +++ b/Server/src/main/content/global/skill/slayer/NechryaelBehavior.kt @@ -0,0 +1,104 @@ +package content.global.skill.slayer + +import core.api.animate +import core.api.getAttribute +import core.api.setAttribute +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.combat.DeathTask +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import core.game.world.GameWorld +import core.tools.RandomFunction +import org.rs09.consts.NPCs + +class NechryaelBehavior : NPCBehavior(*Tasks.NECHRYAELS.npcs) { + private val ATTR_SPAWNS = "deathSpawns" + private val ATTR_NEXTSPAWN = "deathSpawnNextTick" + + override fun afterDamageReceived(self: NPC, attacker: Entity, state: BattleState) { + if (attacker !is Player) return + if (!canSpawnDeathspawn(self)) return + if (!RandomFunction.roll(5)) return + spawnDeathSpawn(self, attacker) + } + + fun spawnDeathSpawn(self: NPC, player: Player) { + val npc = NPC.create(NPCs.DEATH_SPAWN_1614, self.location.transform(self.direction, 1)) + setAttribute(npc, "parent", self) + setAttribute(npc, "target", player) + npc.isRespawn = false + npc.init() + addSpawn(self, npc) + setNextSpawn(self) + animate(self, 9491) + } + + fun canSpawnDeathspawn(self: NPC) : Boolean { + if (getSpawns(self).size >= 2) { + setNextSpawn(self) + return false + } + return getNextSpawn(self) <= GameWorld.ticks + } + + fun getNextSpawn(self: NPC) : Int { + return getAttribute(self, ATTR_NEXTSPAWN, 0) + } + + fun setNextSpawn(self: NPC) { + setAttribute(self, ATTR_NEXTSPAWN, GameWorld.ticks + 50) + } + + fun getSpawns(self: NPC) : ArrayList { + return getAttribute(self, ATTR_SPAWNS, ArrayList()) + } + + fun addSpawn(self: NPC, spawn: NPC) { + val list = getSpawns(self) + list.add(spawn) + setAttribute(self, ATTR_SPAWNS, list) + } + + fun removeSpawn(self: NPC, spawn: NPC) { + val list = getSpawns(self) + list.remove(spawn) + setAttribute(self, ATTR_SPAWNS, list) + } + + override fun shouldIgnoreMultiRestrictions(self: NPC, victim: Entity): Boolean { + val list = getSpawns(self) + return victim == self.properties.combatPulse.getVictim() || list.contains(victim.properties.combatPulse.getVictim()) + } +} + +class DeathspawnBehavior : NPCBehavior(NPCs.DEATH_SPAWN_1614) { + override fun onCreation(self: NPC) { + setAttribute(self, "despawn-time", GameWorld.ticks + 100) + val target = getAttribute(self, "target", null) ?: return + self.attack(target) + } + + override fun onRemoval(self: NPC) { + val parent = getAttribute(self, "parent", null) ?: return + (parent.behavior as? NechryaelBehavior)?.let { it.removeSpawn (parent, self) } + } + + override fun tick(self: NPC): Boolean { + val target = getAttribute(self, "target", null) ?: return true + + if (!target.isActive || DeathTask.isDead(target) || getAttribute(self, "despawn-time", 0) <= GameWorld.ticks) + self.clear() + return true + } + + override fun shouldIgnoreMultiRestrictions(self: NPC, victim: Entity): Boolean { + return victim == getAttribute(self, "target", null) + } + + override fun canBeAttackedBy(self: NPC, attacker: Entity, style: CombatStyle, shouldSendMessage: Boolean): Boolean { + return attacker == getAttribute(self, "target", null) + } +} diff --git a/Server/src/main/content/global/skill/slayer/RockSlug.kt b/Server/src/main/content/global/skill/slayer/RockSlug.kt new file mode 100644 index 0000000..58dfb49 --- /dev/null +++ b/Server/src/main/content/global/skill/slayer/RockSlug.kt @@ -0,0 +1,50 @@ +package content.global.skill.slayer + +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.Node +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.combat.ImpactHandler +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import org.rs09.consts.Items +import java.lang.Integer.max + +class RockSlug : NPCBehavior(*Tasks.ROCK_SLUGS.ids), InteractionListener { + override fun defineListeners() { + onUseWith(IntType.NPC, Items.BAG_OF_SALT_4161, *ids, handler = ::handleSaltUsage) + } + + override fun beforeDamageReceived(self: NPC, attacker: Entity, state: BattleState) { + val lifepoints = self.skills.lifepoints + if (state.estimatedHit + max(state.secondaryHit, 0) > lifepoints - 1) { + state.estimatedHit = lifepoints - 1 + state.secondaryHit = -1 + setAttribute(self, "shouldRun", true) + } + } + + override fun tick(self: NPC): Boolean { + if (getAttribute(self, "shouldRun", false)){ + self.properties.combatPulse.stop() + forceWalk(self, self.properties.spawnLocation, "smart") + removeAttribute(self, "shouldRun") + } + return true + } + + private fun handleSaltUsage(player: Player, used: Node, with: Node) : Boolean { + if (with !is NPC) return false + if (!removeItem(player, used.id)) return false + if (with.skills.lifepoints >= 5) + sendMessage(player, "Your bag of salt is ineffective. The Rockslug is not weak enough.") + else { + sendMessage(player, "The Rockslug shrivels up and dies.") + with.impactHandler.manualHit(player, with.skills.lifepoints, ImpactHandler.HitsplatType.NORMAL) + } + return true + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/slayer/SkeletalWyvernBehavior.kt b/Server/src/main/content/global/skill/slayer/SkeletalWyvernBehavior.kt new file mode 100644 index 0000000..437e2e6 --- /dev/null +++ b/Server/src/main/content/global/skill/slayer/SkeletalWyvernBehavior.kt @@ -0,0 +1,37 @@ +package content.global.skill.slayer + +import content.global.handlers.item.equipment.special.DragonfireSwingHandler +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.combat.CombatSwingHandler +import core.game.node.entity.combat.MultiSwingHandler +import core.game.node.entity.combat.equipment.SwitchAttack +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import org.rs09.consts.Items + +class SkeletalWyvernBehavior : NPCBehavior(*Tasks.SKELETAL_WYVERN.ids) { + /** + * The combat swing handler. + */ + private val COMBAT_HANDLER = MultiSwingHandler(SwitchAttack(CombatStyle.MELEE.swingHandler, Animation(2985)), SwitchAttack(CombatStyle.RANGE.swingHandler, Animation(2989), Graphics(499)), DragonfireSwingHandler.get(false, 54, Animation(2988), Graphics(501), null, null, false)) + + /** + * The combat swing handler for far combat (5+ tile distance) + */ + private val COMBAT_HANDLER_FAR = MultiSwingHandler(SwitchAttack(CombatStyle.RANGE.swingHandler, Animation(2989), Graphics(499))) + + private val SHIELDS = intArrayOf(Items.DRAGONFIRE_SHIELD_11283, Items.DRAGONFIRE_SHIELD_11285, Items.ELEMENTAL_SHIELD_2890, Items.MIND_SHIELD_9731) + + override fun getSwingHandlerOverride(self: NPC, original: CombatSwingHandler): CombatSwingHandler { + val victim = self.properties.combatPulse.getVictim() ?: return original + if (victim !is Player) return original + + return if (victim.location.getDistance(self.location) >= 5) + COMBAT_HANDLER_FAR + else + COMBAT_HANDLER + } +} diff --git a/Server/src/main/content/global/skill/slayer/SlayerEquipmentFlags.kt b/Server/src/main/content/global/skill/slayer/SlayerEquipmentFlags.kt new file mode 100644 index 0000000..e8c5e01 --- /dev/null +++ b/Server/src/main/content/global/skill/slayer/SlayerEquipmentFlags.kt @@ -0,0 +1,88 @@ +package content.global.skill.slayer + +import content.global.skill.skillcapeperks.SkillcapePerks +import core.api.EquipmentSlot +import core.api.getAttribute +import core.api.getItemFromEquipment +import core.game.node.entity.player.Player +import org.rs09.consts.Items + +/** + * Represents a slayer equipment. + * @author Ceikry + */ +object SlayerEquipmentFlags { + + val blackMasks = (Items.BLACK_MASK_10_8901..Items.BLACK_MASK_8921).map { it }.toIntArray() + val slayerItems = intArrayOf(Items.NOSE_PEG_4168, Items.EARMUFFS_4166, Items.FACE_MASK_4164, *blackMasks, Items.SPINY_HELMET_4551, Items.SLAYER_CAPET_9787, Items.SLAYER_CAPE_9786, Items.SLAYER_HELMET_13263, Items.WITCHWOOD_ICON_8923, Items.MIRROR_SHIELD_4156) + + @JvmStatic + fun updateFlags(player: Player){ + var flags = 0 + if(SkillcapePerks.isActive(SkillcapePerks.TRICKS_OF_THE_TRADE, player) && getAttribute(player, "cape_perks:tott:helmet-stored", false)) flags = 0x3F + else if(hasItem(player, Items.SLAYER_HELMET_13263)) flags = 0x1F + else if(hasItem(player, Items.NOSE_PEG_4168)) flags = 1 + else if(hasItem(player, Items.EARMUFFS_4166)) flags = flags or (1 shl 1) + else if(hasItem(player, Items.FACE_MASK_4164)) flags = flags or (1 shl 2) + else if((getItemFromEquipment(player, EquipmentSlot.HEAD)?.id ?: 0) in blackMasks) flags = flags or (1 shl 3) + else if(hasItem(player, Items.SPINY_HELMET_4551)) flags = flags or (1 shl 4) + + if((getItemFromEquipment(player, EquipmentSlot.NECK)?.id ?: 0) == Items.WITCHWOOD_ICON_8923) flags = flags or (1 shl 7) + if((getItemFromEquipment(player, EquipmentSlot.SHIELD)?.id ?: 0) == Items.MIRROR_SHIELD_4156) flags = flags or (1 shl 8) + SlayerManager.getInstance(player).flags.equipmentFlags = flags + } + + @JvmStatic + fun hasNosePeg(player: Player): Boolean{ + return SlayerManager.getInstance(player).flags.equipmentFlags and 1 == 1 + } + + @JvmStatic + fun hasEarmuffs(player: Player): Boolean { + return (SlayerManager.getInstance(player).flags.equipmentFlags shr 1) and 1 == 1 + } + + @JvmStatic + fun hasFaceMask(player: Player): Boolean { + return (SlayerManager.getInstance(player).flags.equipmentFlags shr 2) and 1 == 1 + } + + @JvmStatic + fun hasBlackMask(player: Player): Boolean { + return (SlayerManager.getInstance(player).flags.equipmentFlags shr 3) and 1 == 1 + } + + @JvmStatic + fun hasSpinyHelmet(player: Player): Boolean { + return (SlayerManager.getInstance(player).flags.equipmentFlags shr 4) and 1 == 1 + } + + @JvmStatic + fun hasWitchwoodIcon(player: Player): Boolean { + return (SlayerManager.getInstance(player).flags.equipmentFlags shr 7) and 1 == 1 + } + + @JvmStatic + fun hasMirrorShield(player: Player): Boolean { + return (SlayerManager.getInstance(player).flags.equipmentFlags shr 8) and 1 == 1 + } + + @JvmStatic + fun getDamAccBonus(player: Player): Double { + val isCape = SlayerManager.getInstance(player).flags.equipmentFlags == 0x3F + val hasMask = hasBlackMask(player) + + return if(hasMask) 1.1667 + else if(isCape) 1.075 + else 1.0 + } + + private fun hasItem(player: Player, id: Int): Boolean{ + return (getItemFromEquipment(player, EquipmentSlot.HEAD)?.id ?: 0) == id + } + + fun isSlayerEq(item: Int): Boolean{ + return item in slayerItems + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/slayer/SlayerFlags.kt b/Server/src/main/content/global/skill/slayer/SlayerFlags.kt new file mode 100644 index 0000000..ade4ac5 --- /dev/null +++ b/Server/src/main/content/global/skill/slayer/SlayerFlags.kt @@ -0,0 +1,159 @@ +package content.global.skill.slayer + +import content.global.skill.slayer.Master +import content.global.skill.slayer.Tasks + +/** + * Bitflag-based system for storing slayer-related data for a player and various helper functions. + * @author Ceikry + */ +class SlayerFlags { + var taskFlags = 0 + var rewardFlags = 0 + var equipmentFlags = 0 + var completedTasks = 0 + var taskStreak = 0 + + /** + * The removed tasks. + */ + val removed: ArrayList = ArrayList(4) + + /** + * Get/set master flags + */ + fun getMaster(): Master { + val ordinal = taskFlags and 0xF + return Master.values()[ordinal] + } + + fun setMaster(master: Master){ + taskFlags = (taskFlags - (taskFlags and 0xF)) or master.ordinal + } + + /** + *============================================== + */ + + + /** + * Get/set task flags + */ + fun getTask(): Tasks { + val ordinal = (taskFlags shr 4) and 0x7F + return Tasks.values()[ordinal] + } + + fun setTask(tasks: Tasks){ + taskFlags = (taskFlags - (getTask().ordinal shl 4)) or (tasks.ordinal shl 4) + } + + /** + *============================================== + */ + + /** + * Get/set/decrement task amount flag + */ + fun getTaskAmount(): Int { + return (taskFlags shr 11) and 0xFF + } + + fun setTaskAmount(amount: Int) { + taskFlags = (taskFlags - (getTaskAmount() shl 11)) or (amount shl 11) + } + + fun decrementTaskAmount(amount: Int){ + setTaskAmount(getTaskAmount() - amount) + } + /** + *============================================== + */ + + /** + * Get/Set canEarnPoints flag + */ + fun canEarnPoints(): Boolean { + return (taskFlags shr 20) and 1 == 1 + } + + fun flagCanEarnPoints() { + taskFlags = taskFlags or (1 shl 20) + } + /** + *============================================== + */ + + /** + * Get/set reward unlock flags + */ + fun isBroadsUnlocked(): Boolean{ + return rewardFlags and 1 == 1 + } + + fun unlockBroads() { + rewardFlags = rewardFlags or 1 + } + + fun isRingUnlocked(): Boolean { + return (rewardFlags shr 1) and 1 == 1 + } + + fun unlockRing() { + rewardFlags = rewardFlags or (1 shl 1) + } + + fun isHelmUnlocked(): Boolean { + return (rewardFlags shr 2) and 1 ==1 + } + + fun unlockHelm() { + rewardFlags = rewardFlags or (1 shl 2) + } + + /** + *============================================== + */ + + /** + * Get/set/increment points flag + */ + fun setPoints(amount: Int) { + rewardFlags = (rewardFlags - (getPoints() shl 15)) or (amount shl 15) + } + + fun getPoints(): Int { + return (rewardFlags shr 15) and 0xFFFF + } + + fun incrementPoints(amount: Int){ + setPoints(getPoints() + amount) + } + /** + *============================================== + */ + + /** + * Reset task and task amount to 0 + */ + fun clearTask() { + setTask(Tasks.values()[0]) + setTaskAmount(0) + } + + /** + * Checks if we have a task + */ + fun hasTask(): Boolean{ + return getTaskAmount() != 0 + } + + fun fullClear() { + taskFlags = 0 + rewardFlags = 0 + equipmentFlags = 0 + completedTasks = 0 + taskStreak = 0 + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/slayer/SlayerManager.kt b/Server/src/main/content/global/skill/slayer/SlayerManager.kt new file mode 100644 index 0000000..5542a77 --- /dev/null +++ b/Server/src/main/content/global/skill/slayer/SlayerManager.kt @@ -0,0 +1,251 @@ +package content.global.skill.slayer + +import content.global.handlers.item.equipment.fistofguthixgloves.FOGGlovesManager +import core.api.* +import core.game.event.EventHook +import core.game.event.NPCKillEvent +import core.cache.def.impl.NPCDefinition +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import org.json.simple.JSONArray +import org.json.simple.JSONObject +import java.util.* +import org.rs09.consts.Items + +/** + * Manages the players slayer data. + * @author Ceikry + */ +class SlayerManager(val player: Player? = null) : LoginListener, PersistPlayer, EventHook { + override fun login(player: Player) { + val instance = SlayerManager(player) + player.hook(Event.NPCKilled, instance) + player.setAttribute("slayer-manager", instance) + } + + /** + * The player's slayer flags + */ + @JvmField + val flags: SlayerFlags = SlayerFlags() + + override fun savePlayer(player: Player, save: JSONObject) { + val slayer = JSONObject() + val slayerManager = getInstance(player) + if(slayerManager.removed.isNotEmpty()) { + val removedTasks = JSONArray() + slayerManager.removed.map { + removedTasks.add(it.ordinal.toString()) + } + slayer["removedTasks"] = removedTasks + } + slayer["taskStreak"] = slayerManager.flags.taskStreak.toString() + slayer["totalTasks"] = slayerManager.flags.completedTasks.toString() + slayer["equipmentFlags"] = slayerManager.flags.equipmentFlags + slayer["taskFlags"] = slayerManager.flags.taskFlags + slayer["rewardFlags"] = slayerManager.flags.rewardFlags + save["slayer"] = slayer + } + + override fun parsePlayer(player: Player, data: JSONObject) { + val slayerData = data["slayer"] as JSONObject + val m = slayerData["master"] + val flags = getInstance(player).flags + if (m != null) { + flags.setMaster(Master.forId(m.toString().toInt())) + } + val t = slayerData["taskId"] + if (t != null) flags.setTask(Tasks.values()[t.toString().toInt()]) + val a = slayerData["taskAmount"] + if (a != null) flags.setTaskAmount(a.toString().toInt()) + val points = slayerData["points"] + if (points != null) { + flags.setPoints(points.toString().toInt()) + } + val taskStreak = slayerData["taskStreak"] + if (taskStreak != null) { + flags.taskStreak = taskStreak.toString().toInt() + } + val la = slayerData["learned_rewards"] + if (la != null) { + val learnedArray = slayerData["learned_rewards"] as JSONArray? + for (i in learnedArray!!.indices) { + val unlocked = learnedArray[i] as Boolean + when (i) { + 0 -> if (unlocked) flags.unlockBroads() + 1 -> if (unlocked) flags.unlockRing() + 2 -> if (unlocked) flags.unlockHelm() + else -> {} + } + } + } + val removedTasks = slayerData["removedTasks"] as JSONArray? + if (removedTasks != null) { + for (i in removedTasks.indices) { + flags.removed.add(Tasks.values()[removedTasks[i].toString().toInt()]) + } + } + val completedTasks: Any = slayerData["totalTasks"].toString() + flags.completedTasks = completedTasks.toString().toInt() + if (flags.completedTasks >= 4) flags.flagCanEarnPoints() + + //New system parsing + if (slayerData.containsKey("equipmentFlags")) flags.equipmentFlags = slayerData["equipmentFlags"].toString().toInt() + if (slayerData.containsKey("taskFlags")) flags.taskFlags = slayerData["taskFlags"].toString().toInt() + if (slayerData.containsKey("rewardFlags")) flags.rewardFlags = slayerData["rewardFlags"].toString().toInt() + } + + override fun process(entity: Entity, event: NPCKillEvent) { + val npc = event.npc + val player = entity as? Player ?: return + val slayer = getInstance(player) + val flags = slayer.flags + + if (slayer.hasTask() && npc.id in slayer.task!!.npcs) { + var xp = npc.skills.maximumLifepoints.toDouble() + if (slayer.task!!.dragon && inEquipment(player, Items.DRAGON_SLAYER_GLOVES_12862)) { + xp *= 1.15 + FOGGlovesManager.updateCharges(player) + } + rewardXP(player, Skills.SLAYER, xp) + slayer.decrementAmount(1) + if(slayer.hasTask()) return + flags.taskStreak = flags.taskStreak + 1 + flags.completedTasks = flags.completedTasks + 1 + if ((flags.completedTasks > 4 || flags.canEarnPoints()) && flags.getMaster() != Master.TURAEL && flags.getPoints() < 64000) { + var points = flags.getMaster().taskPoints[0] + if (flags.taskStreak % 50 == 0) { + points = flags.getMaster().taskPoints[2] + } else if (flags.taskStreak % 10 == 0) { + points = flags.getMaster().taskPoints[1] + } + flags.incrementPoints(points) + if (flags.getPoints() > 64000) { + flags.setPoints(64000) + } + player.sendMessages("You've completed " + flags.taskStreak + " tasks in a row and received " + points + " points, with a total of " + flags.getPoints(), "You have completed " + flags.completedTasks + " tasks in total. Return to a Slayer master.") + } else if (flags.completedTasks == 4) { + player.sendMessage("You've completed your task; you will start gaining points on your next task!") + flags.flagCanEarnPoints() + } else if (flags.getMaster() == Master.TURAEL) { + player.sendMessages("You've completed your task; Tasks from Turael do not award points.", "Return to a Slayer master.") + } else { + player.sendMessages("You've completed your task; Complete " + (4 - flags.completedTasks) + " more task(s) to start gaining points.", "Return to a Slayer master.") + } + } + } + + /** + * Method used to assign a new task for a player. + * @param master the master to give the task. + */ + fun generate(master: Master) { + val task = SlayerUtils.generate(player!!, master) ?: return + SlayerUtils.assign(player!!, task, master) + } + + /** + * Clears the task. + */ + fun clear() { + amount = 0 + } + + /** + * Gets the task name. + * @return the name. + */ + val taskName: String + get() { + val task = flags.getTask() + if (task.npcs == null) { + return "no npcs report me" + } + return if (task.npcs.isEmpty()) { + "npc length too small report me" + } else NPCDefinition.forId(task.npcs[0]).name.toLowerCase() + } + + var task: Tasks? + get() = flags.getTask() + set(task) { + flags.setTask(task!!) + } + + var activeTask: Tasks? = null + get() { + if (hasTask()) + return flags.getTask() + return null + } + + var master: Master? + get() = flags.getMaster() + set(master) { + flags.setMaster(master!!) + } + + /** + * Checks if a **Player** contains a task. + * @return `True` if so. + */ + fun hasTask(): Boolean { + return amount > 0 + } + + /** + * Method used to check if the task is completed. + * @return `True` if so. + */ + val isCompleted: Boolean + get() = flags.getTaskAmount() <= 0 + + var amount: Int + get() = flags.getTaskAmount() + set(amount) { + flags.setTaskAmount(amount) + } + + fun decrementAmount(amount: Int) { + flags.decrementTaskAmount(amount) + setVarp(player!!, 2502, flags.taskFlags shr 4) + } + + /** + * Method used to check if the player has started slayer. + * @return `True` if so. + */ + fun hasStarted(): Boolean { + return flags.completedTasks > 0 || flags.getTaskAmount() > 0 + } + /** + * Gets the slayerPoints. + * @return the slayerPoints. + */ + /** + * Sets the slayerPoints. + * @param slayerPoints the slayerPoints to set + */ + var slayerPoints: Int + get() = flags.getPoints() + set(slayerPoints) { + flags.setPoints(slayerPoints) + } + + /** + * Gets the removed. + * @return the removed. + */ + val removed: List + get() = flags.removed + val isCanEarnPoints: Boolean + get() = flags.canEarnPoints() + + companion object { + @JvmStatic fun getInstance(player: Player) : SlayerManager + { + return getAttribute(player, "slayer-manager", SlayerManager()) + } + } +} diff --git a/Server/src/main/content/global/skill/slayer/SlayerMasterDialogue.java b/Server/src/main/content/global/skill/slayer/SlayerMasterDialogue.java new file mode 100644 index 0000000..cb6aa65 --- /dev/null +++ b/Server/src/main/content/global/skill/slayer/SlayerMasterDialogue.java @@ -0,0 +1,706 @@ +package content.global.skill.slayer; + +import org.json.simple.JSONObject; +import core.ServerStore; +import core.game.world.GameWorld; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.global.Skillcape; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.AchievementDiary; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import core.plugin.Initializable; + + +import static core.tools.DialogueConstKt.END_DIALOGUE; +import content.data.Quests; + +/** + * Represents the dialogue plugin used for a slayer master. + * + * @author Vexia + */ +@Initializable +public final class SlayerMasterDialogue extends DialoguePlugin { + + /** + * The enchanted gem item. + */ + private static final Item GEM = new Item(4155, 1); + + /** + * The mithril axe item. + */ + private static final Item MITHRIL_AXE = new Item(1355); + + /** + * The holy symbol item. + */ + private static final Item HOLY_SYMBOL = new Item(1718); + + /** + * Represents the items to use. + */ + private static final Item[] ITEMS = new Item[]{new Item(9813), new Item(9814)}; + + /** + * Represents the coins item. + */ + private static final Item COINS = new Item(995, 99000); + + /** + * Represents the master talking. + */ + private Master master; + + /** + * The quest instance. + */ + private Quest quest; + + /** + * If we're chatting about our diary. + */ + private boolean isDiary; + + private final int level = 2; + + private int rerolls = 0; + + /** + * Constructs a new {@code SlayerMasterDialogue} {@code Object}. + */ + public SlayerMasterDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code SlayerMasterDialogue} {@code Object}. + * + * @param player the player. + */ + public SlayerMasterDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new SlayerMasterDialogue(player); + } + + @Override + public boolean open(Object... args) { + if (args[0] instanceof NPC) { + npc = (NPC) args[0]; + } + master = Master.forId(args[0] instanceof NPC ? ((NPC) args[0]).getId() : (int) args[0]); + quest = player.getQuestRepository().getQuest(Quests.ANIMAL_MAGNETISM); + + if (master == Master.DURADEL) { + if (Skillcape.isMaster(player, Skills.SLAYER)) { + options("Ask about Skillcape", "Something else"); + stage = 900; + return true; + } + } + interpreter.sendDialogues(master.getNpc(), getExpression(master), "'Ello, and what are you after, then?"); + if (master == Master.VANNAKA) { + stage = -1; + } else { + stage = 0; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + rerolls = ServerStore.getInt(getStoreFile(), player.getUsername().toLowerCase(), 0); + if (isDiary) { + switch (stage) { + case 999: + end(); + break; + case -1: + options("What is the Achievement Diary?", "What are the rewards?", "How do I claim the rewards?", "See you later."); + stage++; + break; + case 0: + switch (buttonId) { + case 1: + player("What is the Achievement Diary?"); + stage = 410; + break; + case 2: + player("What are the rewards?"); + stage = 420; + break; + case 3: + player("How do I claim the rewards?"); + stage = 430; + break; + case 4: + player("See you later."); + stage = 999; + break; + } + break; + case 440: + npc("I can imagine! I expect you'll be wanting a reward for", "your hard efforts, eh?"); + stage++; + break; + case 441: + player("Yes, please."); + stage++; + break; + case 442: + AchievementDiary.grantReplacement(player, DiaryType.VARROCK, level); + npc("I'm happy to say that you've done well, so I will reward", "you suitably for your work."); + stage++; + break; + case 443: + player("Great! Thanks."); + stage++; + break; + case 444: + sendDialogue("Vannaka takes the Varrock armour and carves some symbols into it.", "He waves his hands over the symbols and the armour appears to glow", "brilliantly."); + stage++; + break; + case 450: + AchievementDiary.grantReplacement(player, DiaryType.VARROCK, level); + npc("You better be more careful this time."); + stage = 41; + break; + case 410: + npc("It's a diary that helps you keep track of particular", "achievements. Here in Varrock it can help you", "discover some quite useful things. Eventually, with", "enough exploration, the people of Varrock will reward"); + stage++; + break; + case 411: + npc("you."); + stage++; + break; + case 412: + npc("You can see what tasks you have listed by clicking on", "the green button in the Quest List."); + stage = 41; + break; + case 420: + npc("Well, there's three different levels of Varrock Armour,", "which match up with the three levels of difficulty. Each", "has the same rewards as the previous level, and an", "additional one too... but I won't spoil your surprise."); + stage++; + break; + case 421: + npc("Rest assured, the people of Varrock are happy to see", "you visiting the land."); + stage = 41; + break; + case 430: + npc("Just complete the tasks so they're all ticked off, then", "you can claim your reward. Most of them are", "straightforward; you might find some require quests to", "be started, if not finished."); + stage++; + break; + case 431: + npc("To claim the different Varrock Armour, speak to Vannaka", "Rat Burgis, and myself."); + stage = 41; + break; + case 50: + end(); + break; + } + return true; + } + switch (stage) { + case 999: + end(); + break; + case -1: // vannaka - has options for achievement diary + if (!SlayerManager.getInstance(player).hasStarted()) { + options("Who are you?", "Do you have anything for trade?", "Er...nothing...", "I have a question about my Achievement Diary."); + stage = 1; + } else { + options("I need another assignment.", "Do you have anything for trade?", "Er...nothing...", "I have a question about my Achievement Diary."); + stage = 690; + } + break; + case 0: // not vannaka + if (master == Master.TURAEL) { // only give option to talk about holy axe with Turael + if (quest.getStage(player) == 30) { + options("I need another assignment.", "Do you have anything for trade?", "Er...nothing...", "I'm here about a quest."); + stage = 700; + break; + } else if (quest.getStage(player) == 31) { + options("I need another assignment.", "Do you have anything for trade?", "Er...nothing...", "Hello, I'm here about those trees again."); + stage = 700; + break; + } + } + if (!SlayerManager.getInstance(player).hasStarted()) { + options("Who are you?", "Do you have anything for trade?", "Er...nothing..."); + stage = 1; + } else { + options("I need another assignment.", "Do you have anything for trade?", "Er...nothing..."); + stage = 700; + } + break; + case 1: + switch (buttonId) { + case 1: + player("Who are you?"); + stage = 10; + break; + case 2: + player("Do you have anything for trade?"); + stage = 20; + break; + case 3: + player("Er...nothing..."); + stage = 999; + break; + case 4: + player("I have a question about my Achievement Diary."); + stage = 691; + break; + } + break; + case 10: + interpreter.sendDialogues(master.getNpc(), getExpression(master), "I'm " + (master.getNpc() == 8273 ? "the lowest level Slayer Master available." : "one of the elite Slayer Masters."), + master.getNpc() == 8273 ? "The other Slayer Masters are spread around the world." : "I can teach you about the ways of the Slayer."); + stage = 11; + break; + case 11: + options("What's a Slayer?", "Never heard of you..."); + stage = 12; + break; + case 12: + switch (buttonId) { + case 1: + player("What's a Slayer?"); + stage = 100; + break; + case 2: + player("Never heard of you..."); + stage = 2000; + break; + } + break; + case 20: + interpreter.sendDialogues(master.getNpc(), getExpression(master), "I have a wide selection of Slayer equipment; take a look!"); + stage = 21; + break; + case 21: + end(); + if (npc != null) { + npc.openShop(player); + } + break; + case 100: + interpreter.sendDialogues(master.getNpc(), getExpression(master), "Oh dear, what do they teach you in school?"); + stage = 101; + break; + case 101: + player("Well....er..."); + stage = 102; + break; + case 102: + interpreter.sendDialogues(master.getNpc(), getExpression(master), "I suppose I'll have to educate you, then. A Slayer is", "someone who is trained to fight specific creatures. They", "know those creatures' every weakenss and strength. As", "you can guess, it makes killing those creatures a lot"); + stage = 103; + break; + case 103: + interpreter.sendDialogues(master.getNpc(), getExpression(master), "easier."); + stage = 104; + break; + case 104: + options("Wow, can you teach me?", "Sounds useless to me."); + stage = 105; + break; + case 105: + switch (buttonId) { + case 1: + player("Wow, can you teach me?"); + stage = 500; + break; + case 2: + player("Sounds useless to me."); + stage = 1000; + break; + } + break; + case 500: + interpreter.sendDialogues(master.getNpc(), getExpression(master), "Hmmm, well, I'm not so sure..."); + stage = 501; + break; + case 501: + player("Pleeeaasssse! I'll be your best friend!"); + stage = 502; + break; + case 502: + if (!master.hasRequirements(player)) { + interpreter.sendDialogues(master.getNpc(), getExpression(master), "Sorry, but you're not strong enough to be taught by", "me."); + stage = 999; + break; + } + interpreter.sendDialogues(master.getNpc(), getExpression(master), "Oh, okay then; you twisted my arm. You'll have to", "train against specific groups of creatures."); + stage = 503; + break; + case 503: + player("Okay then, what's first?"); + stage = 504; + break; + case 504: + if (player.getInventory().freeSlots() != 0) { + player.getInventory().add(GEM); + SlayerManager.getInstance(player).generate(master); + interpreter.sendDialogues(master.getNpc(), getExpression(master), "We'll start you off hunting " + SlayerUtils.pluralise(SlayerManager.getInstance(player).getTaskName()) + ", you'll need to", "kill " + SlayerManager.getInstance(player).getAmount() + " of them."); + stage = 510; + } else if (player.getInventory().freeSlots() == 0) { + player("Sorry, I don't have enough inventory space."); + stage = 999; + } + break; + case 510: + interpreter.sendDialogues(master.getNpc(), getExpression(master), "You'll also need this enchanted gem. It allows Slayer", "Masters like myself to contact you and update you on", "your progress. Don't worry if you lose it; you can buy", "another from any Slayer Master."); + stage = 511; + break; + case 511: + player("Okay, great!"); + stage = 999; + break; + case 1000: + interpreter.sendDialogues(master.getNpc(), getExpression(master), "That's what you think.."); + stage = 999; + break; + case 2000: + interpreter.sendDialogues(master.getNpc(), getExpression(master), "I am one of the greatest Slayer masters!"); + stage = 999; + break; + case 690: + switch (buttonId) { + case 1: + player("I need another assignment."); + stage = 701; + break; + case 2: + player("Do you have anything for trade?"); + stage = 20; + break; + case 3: + player("Er...nothing..."); + stage = 30; + break; + case 4: + player("I have a question about my Achievement Diary."); + stage = 691; + break; + } + break; + case 691: + sendDiaryDialogue(); + break; + case 700: + switch (buttonId) { + case 1: + player("I need another assignment."); + stage = 701; + break; + case 2: + player("Do you have anything for trade?"); + stage = 20; + break; + case 3: + player("Er...nothing..."); + stage = 30; + break; + case 4: + if (quest.getStage(player) == 30) { + player("I'm here about a quest. Ava said she saw you hanging", "around the moving trees near Draynor Manor."); + stage = 8000; + } else if (quest.getStage(player) == 31) { + player("Hello, I'm here about those trees again."); + stage = 8006; + } + break; + } + break; + case 8000:// avas. + npc("Ahh, you came to the right man, odd things, those trees.", "What is it you are needing exactly?"); + stage++; + break; + case 8001: + player("I think I need some of the wood from them, but my", "axe just bounced off the trunk."); + stage++; + break; + case 8002: + npc("Sounds like you need a blessed axe. No one really", "makes them, though these days."); + stage++; + break; + case 8003: + npc("If you can give me a mithril axe and a holy symbol of", "Saradomin I can let you have my axe. I'll make myself", "a new one when no one is pestering me for Slayer", "tasks."); + stage++; + break; + case 8004: + player("Okay, so I'll see whether I can spare an axe and a", "symbol. Thanks."); + stage++; + break; + case 8005: + quest.setStage(player, 31); + end(); + break; + case 8006: + if (player.hasItem(new Item(10491))) { + npc("You already have an axe."); + stage = 999; + break; + } + npc("I can make an axe for you now, if you wish.", "Remember, it will be no use for normal wooducutting", "after I have added the silver edge."); + stage++; + break; + case 8007: + player("I'd love one, thanks."); + stage++; + break; + case 8008: + if (!player.getInventory().containsItem(MITHRIL_AXE)) { + npc("You'll need to hand over both a mithril axe and a holy", "symbol of Saradomin. You don't have an axe in your", "pack, so I'm not able to help."); + stage = 999; + break; + } + if (!player.getInventory().containsItem(HOLY_SYMBOL)) { + npc("You'll need to hand over both a mithril axe and a holy", "symbol of Saradomin. You don't have a holy symbol in", "your pack, so I'm not able to help."); + stage = 999; + break; + } + if (player.getInventory().remove(MITHRIL_AXE, HOLY_SYMBOL)) { + player.getInventory().add(new Item(10491)); + npc("Here's a new axe; may it serve you well."); + stage = 999; + } + break; + case 701: + if (!master.hasRequirements(player)) { + interpreter.sendDialogues(master.getNpc(), getExpression(master), "Sorry, but you're not strong enough to be taught by", "me."); + stage = 999; + break; + } + if (!SlayerManager.getInstance(player).hasTask()) { + SlayerManager.getInstance(player).generate(master); + if (SlayerManager.getInstance(player).getTask() == Tasks.JAD) { + interpreter.sendDialogues(master.getNpc(), getExpression(master), "Excellent, you're doing great. Your new task is to", "defeat the almighty TzTok-Jad."); + } else { + interpreter.sendDialogues(master.getNpc(), getExpression(master), "Excellent, you're doing great. Your new task is to kill", "" + SlayerManager.getInstance(player).getAmount() + " " + SlayerUtils.pluralise(SlayerManager.getInstance(player).getTaskName()) + "."); + } + stage = 844; + break; + } + if (Master.hasSameTask(master, player)) { + interpreter.sendDialogues(master.getNpc(), getExpression(master), "You're still hunting something. But let me check something..."); + stage = 847; + } else { + SlayerManager.getInstance(player).flags.setTaskStreak(0); + SlayerManager.getInstance(player).generate(master); + if (SlayerManager.getInstance(player).getTask() == Tasks.JAD) { + interpreter.sendDialogues(master.getNpc(), getExpression(master), "Excellent, you're doing great. Your new task is to", "defeat the almighty TzTok-Jad."); + } else { + interpreter.sendDialogues(master.getNpc(), getExpression(master), "Excellent, you're doing great. Your new task is to kill", "" + SlayerManager.getInstance(player).getAmount() + " " + SlayerUtils.pluralise(SlayerManager.getInstance(player).getTaskName()) + "."); + } + stage = 844; + } + break; + case 844: + if (GameWorld.getSettings().getAllow_slayer_reroll()) { + options("Got any tips for me?", "Okay, great!", "I'd like to re-roll that task."); + } else { + options("Got any tips for me?", "Okay, great!"); + } + stage++; + break; + case 845: + switch (buttonId) { + case 1: + interpreter.sendDialogues(master.getNpc(), getExpression(master), SlayerManager.getInstance(player).getTask().getTip()); + stage = 860; + break; + case 2: + player("Okay, great!"); + stage = 999; + break; + case 3: + player("I'd like to re-roll this task."); + if(rerolls == 10){ + stage++; + } else { + SlayerManager.getInstance(player).clear(); + getStoreFile().put(player.getUsername().toLowerCase(), rerolls + 1); + stage = 701; + } + } + break; + case 846: + npcl(FacialExpression.NEUTRAL, "Actually, you're out of free rerolls. You can buy a reroll from my reward store, though."); + stage = END_DIALOGUE; + break; + case 847: + if(rerolls < 10){ + npcl(FacialExpression.NEUTRAL, "You do have " + (10 - rerolls) + " rerolls left today, would you like to use one?"); + stage++; + } + else { + npcl(FacialExpression.NEUTRAL, "And it also seems you're out of rerolls for today. That's unfortunate."); + stage = END_DIALOGUE; + } + break; + case 848: + options("Yes, please.", "No, thanks."); + stage++; + break; + case 849: + switch(buttonId){ + case 1: + playerl(FacialExpression.FRIENDLY, "Yes, please."); + SlayerManager.getInstance(player).clear(); + getStoreFile().put(player.getUsername().toLowerCase(), rerolls + 1); + stage = 701; + break; + case 2: + playerl(FacialExpression.NEUTRAL, "No, thanks."); + stage = END_DIALOGUE; + break; + } + break; + case 860: + player("Great, thanks!"); + stage = 999; + break; + case 900: + switch (buttonId) { + case 1: + player("Can I buy a Skillcape of Slayer?"); + stage = 901; + break; + case 2: + interpreter.sendDialogues(master.getNpc(), FacialExpression.HALF_GUILTY, "'Ello, and what are you after, then?"); + stage = 0; + break; + } + break; + case 901: + interpreter.sendDialogues(Master.DURADEL.getNpc(), FacialExpression.HALF_GUILTY, "Certainly! Right when you give me 99000 coins."); + stage = 902; + break; + case 902: + options("Okay, here you go.", "No, thanks."); + stage = 903; + break; + case 903: + switch (buttonId) { + case 1: + player("Okay, here you go."); + stage = 904; + break; + case 2: + end(); + break; + } + break; + case 904: + if (Skillcape.purchase(player, Skills.SLAYER)) { + interpreter.sendDialogues(Master.DURADEL.getNpc(), FacialExpression.HALF_GUILTY, "There you go! Enjoy."); + } + stage = 999; + break; + case 906: + switch (buttonId) { + case 1: + player("May I buy a Quest Point cape?"); + stage = 907; + break; + case 2: + interpreter.sendDialogues(master.getNpc(), FacialExpression.HALF_GUILTY, "'Ello, and what are you after, then?"); + stage = 0; + break; + } + break; + case 907: + npc("You bet, " + player.getUsername() + "! Right when you give me 99000 coins."); + stage = 908; + break; + case 908: + options("Okay, here you go.", "No, thanks."); + stage = 909; + break; + case 909: + switch (buttonId) { + case 1: + player("Okay, here you go."); + stage = 910; + break; + case 2: + end(); + break; + } + break; + case 910: + if (player.getInventory().freeSlots() < 2) { + player("I don't seem to have enough inventory space."); + stage = 999; + return true; + } + if (!player.getInventory().containsItem(COINS)) { + player("I don't seem to have enough coins with", "me at this time."); + stage = 999; + return true; + } + if (player.getInventory().remove(COINS) && player.getInventory().add(ITEMS)) { + npc("Have fun with it."); + stage = 999; + } else { + player("I don't seem to have enough coins with", "me at this time."); + stage = 999; + } + break; + } + return true; + } + + /** + * Checks which expression to use. + * + * @param master the master. + * @return the expression. + */ + private FacialExpression getExpression(Master master) { + if (master == Master.CHAELDAR) { + return FacialExpression.OLD_NORMAL; + } + return FacialExpression.HALF_GUILTY; + } + + /** + * Sends the diary dialogue. + */ + private void sendDiaryDialogue() { + isDiary = true; + if (AchievementDiary.canClaimLevelRewards(player, DiaryType.VARROCK, level)) { + player("I've completed all the hard tasks in my Varrock", "Achievement Diary and, let me tell you, it wasn't an", "easy job."); + stage = 440; + return; + } + if (AchievementDiary.canReplaceReward(player, DiaryType.VARROCK, level)) { + player("I've seemed to have lost my armour..."); + stage = 460; + return; + } + options("What is the Achievement Diary?", "What are the rewards?", "How do I claim the rewards?", "See you later."); + stage = 0; + } + + @Override + public int[] getIds() { + return new int[]{70, 1598, 1596, 1597, 1599, 7780, 8275, 8273, 8274, 8649}; + } + + private JSONObject getStoreFile() { + return ServerStore.getArchive("daily-slayer-rerolls"); + } + +} diff --git a/Server/src/main/content/global/skill/slayer/SlayerPlugin.java b/Server/src/main/content/global/skill/slayer/SlayerPlugin.java new file mode 100644 index 0000000..53e426a --- /dev/null +++ b/Server/src/main/content/global/skill/slayer/SlayerPlugin.java @@ -0,0 +1,92 @@ +package content.global.skill.slayer; + +import core.cache.def.impl.SceneryDefinition; +import core.game.global.action.ClimbActionHandler; +import core.game.global.action.DigAction; +import core.game.global.action.DigSpadeHandler; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.plugin.Plugin; + +import static core.api.ContentAPIKt.hasRequirement; +import content.data.Quests; + +/** + * Handles related slayer nodes. + * @author Vexia + */ +@Initializable +public class SlayerPlugin extends OptionHandler { + + /** + * The bryne dig locations. + */ + private static final Location[] BRYNE_DIGS = new Location[] { new Location(2749, 3733, 0), new Location(2748, 3733, 0), new Location(2747, 3733, 0), new Location(2747, 3734, 0), new Location(2747, 3735, 0), new Location(2747, 3736, 0), new Location(2748, 3736, 0), new Location(2749, 3736, 0) }; + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(8785).getHandlers().put("option:climb-up", this); + SceneryDefinition.forId(23158).getHandlers().put("option:exit", this); + SceneryDefinition.forId(23157).getHandlers().put("option:exit", this); + SceneryDefinition.forId(15767).getHandlers().put("option:enter", this); + SceneryDefinition.forId(15811).getHandlers().put("option:exit", this); + SceneryDefinition.forId(15812).getHandlers().put("option:exit", this); + SceneryDefinition.forId(96).getHandlers().put("option:climb-up", this); + SceneryDefinition.forId(35121).getHandlers().put("option:climb-down", this); + for (Location loc : BRYNE_DIGS) { + DigSpadeHandler.register(loc, new DigAction() { + @Override + public void run(Player player) { + player.teleport(new Location(2697, 10119, 0)); + player.sendMessages("You dig a hole...", "...And fall into a dark and slimy pit!"); + } + + }); + } + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + switch (node.getId()) { + case 8785: + player.teleport(new Location(2543, 3327, 0)); + break; + case 23158: + case 23157: + player.teleport(new Location(2729, 3733, 0)); + break; + case 15767: + if (!hasRequirement(player, Quests.CABIN_FEVER)) + return true; + player.teleport(new Location(3748, 9373, 0)); + break; + case 15811: + case 15812: + player.teleport(new Location(3749, 2973, 0)); + break; + case 96: + ClimbActionHandler.climb(player, null, new Location(2649, 9804, 0)); + break; + case 35121: + ClimbActionHandler.climb(player, null, new Location(2641, 9763, 0)); + break; + } + return true; + } + + @Override + public Location getDestination(Node node, Node n) { + if (n.getId() == 23158 || n.getId() == 23157) { + return new Location(2690, 10124, 0); + } + if (n.getId() == 96) { + return new Location(2641, 9763, 0); + } + return null; + } + +} diff --git a/Server/src/main/content/global/skill/slayer/SlayerRewardPlugin.java b/Server/src/main/content/global/skill/slayer/SlayerRewardPlugin.java new file mode 100644 index 0000000..247e87b --- /dev/null +++ b/Server/src/main/content/global/skill/slayer/SlayerRewardPlugin.java @@ -0,0 +1,411 @@ +package content.global.skill.slayer; + +import core.cache.def.impl.ItemDefinition; +import core.cache.def.impl.NPCDefinition; +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.node.entity.skill.Skills; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.OptionHandler; +import core.game.interaction.UseWithHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.plugin.ClassScanner; + +import static core.api.ContentAPIKt.hasRequirement; +import content.data.Quests; + +/** + * Handles the slayer reward interface plugin. + * @author Vexia + * + */ +@Initializable +public class SlayerRewardPlugin extends ComponentPlugin { + + /** + * The assignment component tab. + */ + private static final Component ASSIGNMENT = new Component(161); + + /** + * The learn component tab. + */ + private static final Component LEARN = new Component(163); + + /** + * The buy component tab. + */ + private static final Component BUY = new Component(164); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.forId(161).setPlugin(this);//assignment + ComponentDefinition.forId(163).setPlugin(this);//learn + ComponentDefinition.forId(164).setPlugin(this);//buy + ClassScanner.definePlugins(new SlayerMasterPlugin(), new SlayerHelmCraftPlugin()); + return this; + } + + @Override + public void open(Player player, Component open) { + updateInterface(player, open); + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + switch (component.getId()) { + case 161://asignment + switch (button) { + case 23://reassign + case 26: + if (!SlayerManager.getInstance(player).hasTask()) { + player.sendMessage("You don't have an active task right now."); + break; + } + if (purchase(player, 30)) { + SlayerManager.getInstance(player).clear(); + player.sendMessage("You have canceled your current task."); + } + break; + case 24: + case 27: + if (SlayerManager.getInstance(player).getTask() == null) { + player.sendMessage("You don't have a slayer task."); + break; + } + if (SlayerManager.getInstance(player).getRemoved().size() >= 4) { + player.sendMessage("You can't remove anymore tasks."); + break; + } + if (SlayerManager.getInstance(player).getSlayerPoints() >= 30 && !player.isAdmin()) { + int size = SlayerManager.getInstance(player).getRemoved().size(); + int qp = player.getQuestRepository().getAvailablePoints(); + if (size == 0 && qp < 50) { + player.sendMessage("You need 50 quest points as a requirement in order to block one task."); + break; + } else if (size == 1 && qp < 100) { + player.sendMessage("You need 100 quest points as a requirement in order to block two tasks."); + break; + } else if (size == 2 && qp < 150) { + player.sendMessage("You need 150 quest points as a requirement in order to block three tasks."); + break; + } else if (size == 3 && qp < 200) { + player.sendMessage("You need 200 quest points as a requirement in order to block four tasks."); + break; + } + } + if (purchase(player, 100)) { + SlayerManager.getInstance(player).getRemoved().add(SlayerManager.getInstance(player).getTask()); + SlayerManager.getInstance(player).clear(); + updateInterface(player, player.getInterfaceManager().getOpened()); + } + break; + case 36: + case 37: + case 38: + case 39: + int index = 3 - (39 - button); + if (SlayerManager.getInstance(player).getRemoved().isEmpty() || index > SlayerManager.getInstance(player).getRemoved().size() - 1 || SlayerManager.getInstance(player).getRemoved().get(index) == null) { + break; + } + SlayerManager.getInstance(player).getRemoved().remove(index); + updateInterface(player, player.getInterfaceManager().getOpened()); + break; + case 15: + openTab(player, BUY); + break; + case 14: + openTab(player, LEARN); + break; + } + break; + case 163://learn + switch (button) { + case 14: + openTab(player, ASSIGNMENT); + break; + case 15: + openTab(player, BUY); + break; + case 22://Broad arrows + case 29: + if (SlayerManager.getInstance(player).flags.isBroadsUnlocked()) { + player.sendMessage("You don't need to learn this ability again."); + break; + } + if (purchase(player, 300)) { + SlayerManager.getInstance(player).flags.unlockBroads(); + updateInterface(player, component); + } + break; + case 23://Slayer ring + case 30: + if (SlayerManager.getInstance(player).flags.isRingUnlocked()) { + player.sendMessage("You don't need to learn this ability again."); + break; + } + if (purchase(player, 300)) { + SlayerManager.getInstance(player).flags.unlockRing(); + updateInterface(player, component); + } + break; + case 24://Slayer helm + case 31: + if (SlayerManager.getInstance(player).flags.isHelmUnlocked()) { + player.sendMessage("You don't need to learn this ability again."); + break; + } + if (purchase(player, 400)) { + SlayerManager.getInstance(player).flags.unlockHelm(); + updateInterface(player, component); + } + break; + } + break; + case 164://buy + switch (button) { + case 16: + openTab(player, LEARN); + break; + case 17: + openTab(player, ASSIGNMENT); + break; + case 24://slayer exp + case 32: + if (purchase(player, 400)) { + player.getSkills().addExperience(Skills.SLAYER, 10000, false); + } + break; + case 26://ring of slaying + case 33: + if (player.getInventory().freeSlots() < 1 && SlayerManager.getInstance(player).getSlayerPoints() >= 75) { + player.sendMessage("You don't have enough inventory space."); + break; + } + if (purchase(player, 75)) { + player.getInventory().add(new Item(13281), player); + } + break; + case 28: + case 36: + if (purchase(player, 35)) { + player.getInventory().add(new Item(558, 1000), player); + player.getInventory().add(new Item(560, 250), player); + } + break; + case 34: + case 37: + if (purchase(player, 35)) { + player.getInventory().add(new Item(13280, 250), player); + } + break; + case 35: + case 39: + if (purchase(player, 35)) { + player.getInventory().add(new Item(4172, 250), player); + } + break; + } + break; + } + return true; + } + + /** + * Purchases a slayer point reward. + * @param player The player. + * @param amount The amount of points. + * @return {@code True} if purchased. + */ + private boolean purchase(Player player, int amount) { + if (SlayerManager.getInstance(player).getSlayerPoints() < amount) { + player.sendMessage("You need " + amount + " slayer points in order to purchase this reward."); + return false; + } + SlayerManager.getInstance(player).setSlayerPoints(SlayerManager.getInstance(player).getSlayerPoints() - amount); + updateInterface(player, player.getInterfaceManager().getOpened()); + return true; + } + + /** + * Switches the tab on the reward interface. + * @param player The player instance + * @param open The component to open. + */ + private void openTab(Player player, Component open) { + player.getInterfaceManager().open(open); + updateInterface(player, open); + } + + /** + * Update the current points text. + * @param player the player. + * @param open the component. + */ + private void updateInterface(Player player, Component open) { + if (open == null) { + return; + } + String space = ""; + String num = String.valueOf(SlayerManager.getInstance(player).getSlayerPoints()); + if (num != "0") { + for (int i = 0; i < num.length(); i++) { + space += " "; + } + } + switch (open.getId()) { + case 161://assignment + int childs[] = new int[] {35, 30, 31, 32}; + String[] letters = new String[] {"A", "B", "C", "D"}; + Tasks task = null; + for (int i = 0; i < 4; i++) { + task = i > SlayerManager.getInstance(player).getRemoved().size() - 1 ? null : SlayerManager.getInstance(player).getRemoved().get(i); + player.getPacketDispatch().sendString(task == null ? letters[i] : task.getName(), open.getId(), childs[i]); + } + player.getPacketDispatch().sendString(space + SlayerManager.getInstance(player).getSlayerPoints(), open.getId(), 19); + break; + case 163://learn + for (int i = 0; i < 3; i++) { + switch(i){ + case 0: + player.getPacketDispatch().sendInterfaceConfig(open.getId(), 25 + i, !SlayerManager.getInstance(player).flags.isBroadsUnlocked()); + break; + case 1: + player.getPacketDispatch().sendInterfaceConfig(open.getId(), 25 + i, !SlayerManager.getInstance(player).flags.isRingUnlocked()); + break; + case 2: + player.getPacketDispatch().sendInterfaceConfig(open.getId(), 25 + i, !SlayerManager.getInstance(player).flags.isHelmUnlocked()); + break; + default: + break; + } + } + player.getPacketDispatch().sendString(space + SlayerManager.getInstance(player).getSlayerPoints(), open.getId(), 18); + break; + case 164://buy + player.getPacketDispatch().sendString(space + SlayerManager.getInstance(player).getSlayerPoints(), open.getId(), 20); + break; + } + } + + /** + * Handles the slayer master option plugin. + * @author Vexia + * + */ + public class SlayerMasterPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (Master m : Master.values()) { + NPCDefinition.forId(m.getNpc()).getHandlers().put("option:rewards", this); + } + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + if (!hasRequirement(player, Quests.SMOKING_KILLS)) + return true; + openTab(player, BUY); + return true; + } + + } + + /** + * Handles the crafting of a slayer helmet. + * @author Vexia + * + */ + public static class SlayerHelmCraftPlugin extends UseWithHandler { + + /** + * The slayer helm item. + */ + private static final Item SLAYER_HELM = new Item(13263); + + /** + * The spiny helmet. + */ + private static final Item SPINY_HELMET = new Item(4551); + + /** + * The ingredients needed. + */ + private static final int[] INGREDIENTS = new int[] {4168, 4166, 4164, 8921}; + + /** + * Constructs a new {@Code SlayerHelmCraftPlugin} {@Code Object} + */ + public SlayerHelmCraftPlugin() { + super(INGREDIENTS); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(SPINY_HELMET.getId(), ITEM_TYPE, this); + ClassScanner.definePlugin(new OptionHandler() { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ItemDefinition.forId(SLAYER_HELM.getId()).getHandlers().put("option:disassemble", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + if (player.getInventory().freeSlots() < 4) { + player.sendMessage("You don't have enough inventory space."); + return true; + } + player.lock(1); + if (player.getInventory().remove(node.asItem())) { + for (int id : INGREDIENTS) { + player.getInventory().add(new Item(id)); + } + player.getInventory().add(SPINY_HELMET); + } + player.sendMessage("You dissasemble your Slayer helm."); + return true; + } + + }); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + if (player.getSkills().getStaticLevel(Skills.CRAFTING) < 55) { + player.sendMessage("You need a Crafting level of at least 55 in order to do this."); + return true; + } + if (!SlayerManager.getInstance(player).flags.isHelmUnlocked()) { + player.sendMessage("You need to unlock the ability to do that first."); + return true; + } + if (!player.getInventory().containItems(INGREDIENTS)) { + player.sendMessages("You need a nosepeg, facemask, earmuffs, spiny helmet, and a black mask in", "your inventory in order to construct a Slayer helm."); + return true; + } + player.lock(1); + if (player.getInventory().remove(SPINY_HELMET)) { + for (int id : INGREDIENTS) { + if (!player.getInventory().remove(new Item(id))) { + return true; + } + } + player.getInventory().add(SLAYER_HELM); + player.sendMessage("You combine the items into a Slayer helm."); + } + return true; + } + + } +} diff --git a/Server/src/main/content/global/skill/slayer/SlayerTowerPlugin.java b/Server/src/main/content/global/skill/slayer/SlayerTowerPlugin.java new file mode 100644 index 0000000..aa8f0e3 --- /dev/null +++ b/Server/src/main/content/global/skill/slayer/SlayerTowerPlugin.java @@ -0,0 +1,69 @@ +package content.global.skill.slayer; + +import core.cache.def.impl.SceneryDefinition; +import core.game.global.action.DoorActionHandler; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Handles the interactions for the slayer tower. + * @author Vexia + */ +@Initializable +public final class SlayerTowerPlugin extends OptionHandler { + + /** + * The locations of the states. + */ + private static final Location[] LOCATIONS = new Location[] { new Location(3430, 3534, 0), new Location(3426, 3534, 0) }; + + /** + * The open id. + */ + private static final int OPEN_ID = 5117; + + /** + * The closed id. + */ + private static final int CLOSED_ID = 5116; + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(4490).getHandlers().put("option:open", this); + SceneryDefinition.forId(4487).getHandlers().put("option:open", this); + SceneryDefinition.forId(4492).getHandlers().put("option:close", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + switch (node.getId()) { + case 4490: + case 4487: + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + switchStatue(); + return true; + } + return true; + } + + /** + * Switches the object id of the statue. + */ + private void switchStatue() { + for (Location l : LOCATIONS) { + Scenery object = RegionManager.getObject(l); + if (object != null) { + int id = object.getId() == OPEN_ID ? CLOSED_ID : OPEN_ID; + SceneryBuilder.replace(object, object.transform(id)); + } + } + } +} diff --git a/Server/src/main/content/global/skill/slayer/SlayerTowerZone.java b/Server/src/main/content/global/skill/slayer/SlayerTowerZone.java new file mode 100644 index 0000000..c9c583f --- /dev/null +++ b/Server/src/main/content/global/skill/slayer/SlayerTowerZone.java @@ -0,0 +1,64 @@ +package content.global.skill.slayer; + +import core.game.global.action.DoorActionHandler; +import core.game.node.entity.skill.Skills; +import core.game.interaction.Option; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneBuilder; +import core.game.world.map.zone.ZoneRestriction; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Handles the slayer tower map zone. + * @author Vexia + */ +@Initializable +public final class SlayerTowerZone extends MapZone implements Plugin { + + /** + * Constructs a new {@code SlayerTowerZone} {@code Object}. + */ + public SlayerTowerZone() { + super("slayer tower", true, ZoneRestriction.CANNON); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ZoneBuilder.configure(this); + return this; + } + + @Override + public boolean interact(Entity e, Node target, Option option) { + if (e instanceof Player) { + Player player = (Player) e; + int level = player.getLocation().getZ() == 0 ? 61 : 71; + if (target.getId() == 9319 && e.getSkills().getLevel(Skills.AGILITY) < level) { + player.getPacketDispatch().sendMessage("You need an Agility level of at least " + level + " in order to do this."); + return true; + } + if (target.getId() == 10527 || target.getId() == 10528) { + DoorActionHandler.handleAutowalkDoor(player, (Scenery) target); + return true; + } + } + return super.interact(e, target, option); + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public void configure() { + register(new ZoneBorders(3401, 3527, 3459, 3585)); + } + +} diff --git a/Server/src/main/content/global/skill/slayer/SlayerUtils.kt b/Server/src/main/content/global/skill/slayer/SlayerUtils.kt new file mode 100644 index 0000000..c034fc5 --- /dev/null +++ b/Server/src/main/content/global/skill/slayer/SlayerUtils.kt @@ -0,0 +1,80 @@ +package content.global.skill.slayer + +import core.api.setVarp +import core.game.node.entity.combat.BattleState +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.SpellBookManager.SpellBook +import core.game.node.entity.player.link.diary.DiaryType +import core.game.node.entity.skill.Skills +import core.tools.RandomFunction +import org.rs09.consts.Items + +object SlayerUtils { + fun generate(player: Player, master: Master): Master.Task? + { + val tasks: MutableList = ArrayList(10) + val taskWeightSum = intArrayOf(0) + master.tasks.stream().filter { task: Master.Task -> canBeAssigned(player, task.task) && task.task.combatCheck <= player.properties.currentCombatLevel }.forEach { task: Master.Task -> + taskWeightSum[0] += task.weight + tasks.add(task) + } + tasks.shuffle(RandomFunction.RANDOM) + var rnd = RandomFunction.random(taskWeightSum[0]) + for (task in tasks) { + if (rnd < task!!.weight) return task + rnd -= task.weight + } + return null + } + + fun canBeAssigned(player: Player, task: Tasks): Boolean + { + return player.getSkills().getLevel(Skills.SLAYER) >= task.levelReq && !SlayerManager.getInstance(player).flags.removed.contains(task) && task.hasQuestRequirements(player) + } + + fun assign(player: Player, task: Master.Task, master: Master) + { + SlayerManager.getInstance(player).master = master + SlayerManager.getInstance(player).task = task.task + if (task.task_range[0] == null) + SlayerManager.getInstance(player).amount = RandomFunction.random(master.default_assignment_range[0], master.default_assignment_range[1]) + else + SlayerManager.getInstance(player).amount = RandomFunction.random(task.task_range[0], task.task_range[1]) + if (master == Master.DURADEL) { + player.achievementDiaryManager.finishTask(player, DiaryType.KARAMJA, 2, 8) + } else if (master == Master.VANNAKA) { + player.achievementDiaryManager.finishTask(player, DiaryType.VARROCK, 1, 14) + } + setVarp(player, 2502, SlayerManager.getInstance(player).flags.taskFlags shr 4) + } + + @JvmStatic + fun hasBroadWeaponEquipped(player: Player, state: BattleState): Boolean { + return (state.weapon != null && state.weapon.id == Items.LEAF_BLADED_SPEAR_4158 || + state.weapon != null && state.weapon.id == Items.LEAF_BLADED_SWORD_13290 || + state.ammunition != null && (state.ammunition.itemId == Items.BROAD_ARROW_4160 || state.ammunition.itemId == Items.BROAD_TIPPED_BOLTS_13280) || + state.spell != null && state.spell.spellId == 31 && player.spellBookManager + .spellBook == SpellBook.MODERN.interfaceId + ) + } + + @JvmStatic + fun pluralise(str: String): String { + return when (str) { + "black bear" -> "bears" + "cyclops" -> "cyclopes" + "guard dog" -> "dogs" + "dwarf" -> "dwarves" + "elf warrior" -> "elves" + "jelly" -> "jellies" + "nechryael" -> str // the plural and singular is the same + "turoth" -> str // the plural and singular is the same + "tzhaar-mej" -> "tzHaar" + "werewolf" -> "werewolves" + "wolf" -> "wolves" + "kalphite worker" -> "kalphites" + "scarab swarm" -> "scabarites" + else -> str + "s" + } + } +} diff --git a/Server/src/main/content/global/skill/slayer/Tasks.java b/Server/src/main/content/global/skill/slayer/Tasks.java new file mode 100644 index 0000000..81a195f --- /dev/null +++ b/Server/src/main/content/global/skill/slayer/Tasks.java @@ -0,0 +1,186 @@ +package content.global.skill.slayer; + + +import core.cache.def.impl.NPCDefinition; + +import java.util.Arrays; +import java.util.HashMap; +import core.game.node.entity.player.Player; + +import static core.api.ContentAPIKt.hasRequirement; +import content.data.Quests; + +/** + * A non-garbage way of representing tasks + * Slayer level source: ... + * Combat level source: None + * @author ceik + * @author gregf + */ +public enum Tasks { + ABERRANT_SPECTRES(65, new int[] { 1604, 1605, 1606, 1607, 7801, 7802, 7803, 7804 }, new String[] { "Aberrant Spectres are fetid, vile ghosts. The very", "smell of them will paralyse and harm you. A nose peg", "will help ignore their stink." }, 60, true, false), + ABYSSAL_DEMONS(85, new int[] { 1615 }, new String[] { "Abyssal Demons are nasty creatures to fight. They", "aren't really part of this realm, and are able to", "move very quickly to trap their prey."}, 85, false, false), + ANKOU(40, new int[] { 4381, 4382, 4383 }, new String[] { "Ankou are undead skeletal ghosts. They'll fight you", "up close but make sure to take advantage out of their", "limited defence." }, 1, true, false), + AVIANSIES(60, new int[] { 6245, 6243, 6235, 6232, 6244, 6246, 6233, 6241, 6238, 6237, 6240, 6242, 6239, 6234 }, new String[] { "Aviansies are bird-like creatures found in the icy", "dungeons of the north. Melee weapons can't reach them,", "so use Magic or Ranged attacks." }, 1, false, false), + BANSHEE(20, new int[] { 1612 }, new String[] { "Banshees use a piercing scream to shock their enemies.", "You'll need some earmuffs to protect yourself from them." }, 15, true, false), + BASILISKS(40, new int[] { 1616, 1617 }, new String[] { "Basilisks, like Cockatrice, have a gaze which will", "paralyse and harm their prey. You'll need a Mirror", "Shield to protect you." }, 40, false, false), + BATS(5, new int[] { 412, 78, 3711 }, new String[] { "Bats are rarely found on the ground, so you'll have", "to fight them while they're airborne, which won't be", "easy for melee." }, 1, false, false), + BEARS(13, new int[] { 106, 105, 1195, 3645, 3664, 1326, 1327 }, new String[] { "Bears are tough creatures and fierce fighters, watch", "out for their powerful claws." }, 1, false, false), + BIRDS(1, new int[] { 1475, 5120, 5121, 5122, 5123, 5133, 1475, 1476, 41, 951, 1017, 1401, 1402, 2313, 2314, 2315, 1016, 1550, 147, 1180, 1754, 1755, 1756, 2252, 4570, 4571, 1911, 6114, 46, 2693, 6113, 6112, 146, 149, 150, 450, 451, 1179, 1322, 1323, 1324, 1325, 1400, 2726, 2727, 3197, 138, 48, 4373, 4374, 4535, 139, 1751, 148, 1181, 6382, 2459, 2460, 2461, 2462, 2707, 2708, 6115, 6116, 3296, 6378, 1996, 3675, 3676, 6792, 6946, 7320, 7322, 7324, 7326, 7328, 1692, 6322, 3476, 1018, 1403, }, new String[] { "Birds aren't the most intelligent of creatures, but", "watch out for their sharp stabbing beaks." }, 1, false, false), + BLACK_DEMONS(80, new int[] { 84, 677, 4702, 4703, 4704, 4705, 6208, }, new String[] { "Black Demons are magic creatures that are weak", "to magic attacks. They're a very strong", "demon and very dangerous." }, 1, false, false), + BLACK_DRAGONS(80, new int[] {54, 4673, 4674, 4675, 4676, 3376, 50 }, new String[] { "Black dragons are the strongest dragons;", "watch out for their fiery breath." }, 1, false, true), + BLOODVELDS(50, new int[] { 1618, 1619, 6215, 7643, 7642 }, new String[] { "Bloodvelds are strange demonic creatures, they use their", "long rasping tongue to feed on just about", "anything they can find." }, 50, false, false), + BLUE_DRAGONS(65, new int[] { 55, 4681, 4682, 4683, 4684, 5178, 52, 4665, 4666, }, new String[] { "Blue dragons aren't as strong as other dragons but they're", "still very powerful, watch out for their fiery breath." }, 1, false, true), + BRINE_RATS(45, new int[] { 3707 }, new String[] { "Brine rats can be found in caves that are near the", "sea. They are hairless, bad-tempered and generally", "unfriendly." }, 47, Quests.OLAFS_QUEST), + BRONZE_DRAGONS(75, new int[] { 1590 }, new String[] { "Bronze Dragons are the weakest of the metallic", "dragons, their bronze scales are far thicker than", "normal bronze armour." }, 1, false, true), + CATABLEPONS(35, new int[] { 4397, 4398, 4399, }, new String[] { "Catablepon are mythical, cow like, magical creatures", "Beware their weakening glare." }, 1, false, false), + CAVE_BUG(1, new int[] { 1832, 5750, }, new String[] { "Cave Bugs are like Cave Crawlers, except smaller and", "easier to squish, though they still have a fondness", "for plants." }, 7, false, false), + CAVE_CRAWLERS(10, new int[] { 1600, 1601, 1602, 1603, }, new String[] { "Cave Crawlers are small and fast, often hiding in", "ambush. Avoid their barbed tongue or you'll", "get poisoned." }, 10, false, false), + CAVE_HORRORS(85, new int[] { 4353, 4354, 4355, 4356, 4357, }, new String[] { "Cave Horrors can be found under Mos Le'Harmless. You", "will need a Witchwood Icon to fight them effectively." }, 58, Quests.CABIN_FEVER), + CAVE_SLIMES(15, new int[] { 1831 }, new String[] { "Cave Slimes are the lesser cousins of Jellies, though", "don't be fooled they can still be dangerous as", "they're often poisonous." }, 17, false, false), + COCKATRICES(25, new int[] { 1620, 1621, 4227, }, new String[] { "Cockatrice, like Basilisks, have a gaze which will", "paralyse and harm their prey. You'll need a Mirror", "Shield to protect you." }, 25, false, false), + COWS(5, new int[] { 81, 1766, 1768, 2310, 397, 955, 1767, 3309 }, new String[] { "Cows are bigger than you, so they'll often hit fairly", "hard but are usually fairly slow to react." }, 1, false, false), + CRAWLING_HAND(1,new int[] { 1648, 1649, 1650, 1651, 1652, 1653, 1654, 1655, 1656, 1657, 4226, 7640, 7641 }, new String[] { "Crawling Hands are undead severed hands, fast and", "dexterous they claw their victims." }, 5, true, false), + CROCODILES(50, new int[] { 1993, 6779 }, new String[] { "Crocodiles are large reptiles which live near water.", "You'll want to have a stabbing weapon handy for", "puncturing their thick scaly hides." }, 1, false, false), + DAGANNOTHS(75, new int[] { 1338, 1339, 1340, 1341, 1342, 1343, 1344, 1345, 1346, 1347, 2454, 2455, 2456, 2881, 2882, 2883, 2887, 2888, 3591, }, new String[] { "Dagannoth are large sea dwelling creatures which are", "very aggressive. You'll often find them in caves", "near sea water." }, 1, Quests.HORROR_FROM_THE_DEEP), + DARK_BEASTS(90, new int[] { 2783 }, new String[] { "Dark Beasts are large, dog-like predators.", "Their massively muscled bodies protect", "them from crushing weapons." }, 90, Quests.MOURNINGS_END_PART_II), + DESERT_LIZARDS(15, new int[] { 2803, 2804, 2805, 2806, 2807, 2808 }, new String[] { "Lizards are large reptiles with tough skin. Those", "found in the desert will need you to douse them with", "freezing water to finish them off after a tough battle." }, 22, false, false), + DOG(15, new int[] { 99, 3582, 1994, 1593, 1594, 3582 }, new String[] { "Dogs are much like Wolves, they are", "pack creatures which will hunt in groups." }, 1, false, false), + DUST_DEVILS(70, new int[] { 1624 }, new String[] { "Dust Devils use clouds of dust, sand, ash and whatever", "else they can inhale to blind and disorientate", "their victims." }, 65, false, false), + DWARF(6, new int[] { 118, 120, 121, 382, 3219, 3220, 3221, 3268, 3269, 3270, 3271, 3272, 3273, 3274, 3275, 3294, 3295, 4316, 5880, 5881, 5882, 5883, 5884, 5885, 2130, 2131, 2132, 2133, 3276, 3277, 3278, 3279, 119, 2423 }, new String[] { "Dwarves are a small but tough race of miners, often", "using pickaxes to pierce their opponents armour." }, 1, false, false), + EARTH_WARRIORS(35, new int[] { 124 }, new String[] { "Earth Warriors are a kind of earth elemental,", "grind them to dust with blunt weapons." }, 1, false, false), + ELVES(70, new int[] { 1183, 1184, 2359, 2360, 2361, 2362, 2373, 7438, 7439, 7440, 7441 }, new String[]{ "Elves are quick, agile, and vicious fighters which", "often favour bows and polearms."}, 1, Quests.REGICIDE), + // Waiting for either Rum Deal or Pirate Pete and Fever Spiders before adding this assignment + FEVER_SPIDER(1, new int[] { 2850 }, new String[] { "Fever Spiders are giant spiders that carry the deadly", "Spider Fever. If you don't want to catch it I suggest", "you wear Slayer Gloves to fight them." }, 42, Quests.RUM_DEAL), + FIRE_GIANTS(65, new int[] { 110, 1582, 1583, 1584, 1585, 1586, 7003, 7004 }, new String[] { "Like other giants, Fire Giants often wield large weapons", "learn to recognise what kind of weapon it is,", "and act accordingly." }, 1, false, false), + FLESH_CRAWLERS(15, new int[] { 4389, 4390, 4391 }, new String[] { "Flesh Crawlers are scavengers and will eat you - and", "anyone else, given the chance." }, 1, false, false), + GARGOYLES(80, new int[] { 1610, 6389 }, new String[] { "Gargoyles are winged creatures of stone. You'll need", "to fight them to near death before breaking them apart", "with a rock hammer." }, 75, false, false), + GHOSTS(13, new int[] { 103, 104, 491, 1541, 1549, 2716, 2931, 4387, 388, 5342, 5343, 5344, 5345, 5346, 5347, 5348, 1698, 5349, 5350, 5351, 5352, 5369, 5370, 5371, 5372, 5373, 5374, 5572, 6094, 6095, 6096, 6097, 6098, 6504, 13645, 13466, 13467, 13468, 13469, 13470, 13471, 13472, 13473, 13474, 13475, 13476, 13477, 13478, 13479, 13480, 13481 }, new String[] { "Ghosts are undead so magic is your best bet against", "them, there is even a spell specially for fighting", "the undead." }, 1, true, false), + GHOULS(25, new int[] { 1218, 3059 }, new String[] { "Ghouls aren't undead but they are stronger and", "tougher than they look. However they're also very", "cowardly and will run if they're losing a fight." }, 1, false, false), + GOBLINS(1, new int[] { 100, 101, 102, 444, 445, 489, 1769, 1770, 1771, 1772, 1773, 1774, 1775, 1776, 2274, 2275, 2276, 2277, 2278, 2279, 2280, 2281, 2678, 2679, 2680, 2681, 3060, 3264, 3265, 3266, 3267, 3413, 3414, 3415, 3726, 4261, 4262, 4263, 4264, 4265, 4266, 4267, 4268, 4269, 4270, 4271, 4272, 4273, 4274, 4275, 4276, 4407, 4408, 4409, 4410, 4411, 4412, 4479, 4480, 4481, 4482, 4483, 4484, 4485, 4486, 4487, 4488, 4489, 4490, 4491, 4492, 4499, 4633, 4634, 4635, 4636, 4637, 5786, 5824, 5855, 5856, 6125, 6126, 6132, 6133, 6279, 6280, 6281, 6282, 6283, 6402, 6403, 6404, 6405, 6406, 6407, 6408, 6409, 6410, 6411, 6412, 6413, 6414, 6415, 6416, 6417, 6418, 6419, 6420, 6421, 6422, 6423, 6424, 6425, 6426, 6427, 6428, 6429, 6430, 6431, 6432, 6433, 6434, 6435, 6436, 6437, 6438, 6439, 6440, 6441, 6442, 6443, 6444, 6445, 6446, 6447, 6448, 6449, 6450, 6451, 6452, 6453, 6454, 6455, 6456, 6457, 6458, 6459, 6460, 6461, 6462, 6463, 6464, 6465, 6466, 6467, 6490, 6491, 6492, 6493, 6494, 6495, 6496, 6497 }, new String[] { "Goblins are mostly just annoying, but they can be vicious.", "Watch out for the spears they sometimes carry." }, 1, false, false), + GORAKS(70, new int[] { 4418, 6218 }, new String[] { "Goraks are extremely aggressive creatures. They have", "been imprisoned on an alternative plane, which is", "only accessible by using the fairyrings. Be extremely", "careful, their touch drains health as well as skills!" }, 1, Quests.FAIRYTALE_I_GROWING_PAINS), + GREATER_DEMONS(75, new int[] { 83, 4698, 4699, 4700, 4701, 6204 }, new String[] { "Greater Demons are magic creatures so they are weak", "to magical attacks. Though not the strongest demon,", "they are still dangerous." }, 1, false, false), + GREEN_DRAGONS(52, new int[] { 941, 4677, 4678, 4679, 4680, 5362, 742 }, new String[] { "Green Dragons are the weakest dragon but still very", "powerful, watch out for their fiery breath." }, 1, false, true), + HARPIE_BUG_SWARMS(45, new int[] { 3153 }, new String[] { "Harpie Bug Swarms are pesky critters that are hard to", "hit. You need a lit bug lantern to distract them with", "its hypnotic light." }, 33, false, false), + HELLHOUNDS(75, new int[] { 49, 3586, 6210, }, new String[] { "Hellhounds are a cross between Dogs and Demons, they", "are dangerous with a fierce bite." }, 1, false, false), + HILL_GIANTS(25, new int[] { 117, 4689, 4690, 3058, 4691, 4692, 4693 }, new String[] { "Hill Giants often wield large weapons, learn to", "recognise what kind of weapon it is and", "act accordingly." }, 1, false, false), + HOBGOBLINS(20, new int[] { 122, 123, 2685, 2686, 3061, 6608, 6642, 6661, 6684, 6710, 6722, 6727, 2687, 2688, 3583, 4898, 6275 }, new String[] { "Hobgoblins are sneaky underhanded creatures, they", "often wield spears and some times carry javelins too." }, 1, false, false), + ICE_FIENDS(20, new int[] { 3406, 6217, 7714, 7715, 7716 }, new String[] { "Icefiends are beings of ice and freezing rock, they're", "quick and agile so you'll want to be careful when", "getting close to them." }, 1, false, false), + ICE_GIANTS(50, new int[] { 111, 3072, 4685, 4686, 4687 }, new String[] { "Like other giants, Ice Giants often wield large", "weapons, learn to recognise what kind of weapon it is", "and act accordingly." }, 1, false, false), + ICE_WARRIOR(45, new int[] { 125, 145, 3073 }, new String[] { "Ice Warriors are a kind of ice elemental, shatter them", "with blunt weapons or melt them with fire." }, 1, false, false), + INFERNAL_MAGES(40, new int[] { 1643, 1644, 1645, 1646, 1647 }, new String[] { "Infernal Mages are dangerous spell users, beware of", "their magic spells and go properly prepared" }, 45, false, false), + IRON_DRAGONS(80, new int[] { 1591 }, new String[] { "Iron Dragons are some of the weaker metallic dragons,", "their iron scales are far thicker than normal", "iron armour." }, 1, false, true), + JELLIES(57, new int[] { 1637, 1638, 1639, 1640, 1641, 1642 }, new String[] { "Jellies are nasty cube-like gelatinous creatures which", "absorb everything they come across into themselves." }, 52, false, false), + JUNGLE_HORRORS(65, new int[] { 4348, 4349, 4350, 4351, 4352 }, new String[] { "Jungle Horrors can be found all over Mos Le'Harmless.", "They are strong and aggressive, so watch out!" }, 1, Quests.CABIN_FEVER), + KALPHITES(15, new int[] { 1153, 1154, 1155, 1156, 1157, 1159, 1160, 1161 }, new String[] { "Kalphites are large insects which live in great hives", "under the desert sands." }, 1, false, false), + // Waiting for the killer watt plane to be implemented before adding to assignments + KILLERWATTS(1, new int[] { 3201 }, new String[] { "Killerwatts store huge amounts of energy in their", "bodies, which is released if they are touched. You'll", "need to wear heavily insulated boots to counter this", "shocking effect." }, 37, Quests.ERNEST_THE_CHICKEN), + KURASKS(65, new int[] { 1608, 1609, 4229, 7805, 7797 }, new String[] { "Kurasks are large brutal creatures with very thick", "hides. You'll need a Leaf-Tipped Spear Sword or", "Battle-axe, Broad Arrows, or a Magic Dart to harm them." }, 70, false, false), + LESSER_DEMONS(60, new int[] { 82, 6203, 3064, 4694, 4695, 6206, 3064, 4696, 4697, 6101 }, new String[] { "Lesser Demons are magic creatures so they are weak to", "magical attacks. Though they're relatively weak they", "are still dangerous." }, 1, false, false), + MINOTAURS(7, new int[] { 4404, 4405, 4406 }, new String[] { "Minotaurs are large manlike creatures but you'll", "want to be careful of their horns." }, 1, false, false), + MITHRIL_DRAGONS(60, new int[] { 5363 }, new String[] { "Mithril dragons are more vulnerable to magic and to", "stab-based melee attacks than to anything else." }, 1, false, true), + MOGRES(1, new int[] { 114 }, new String[] { "Mogres are a type of aquatic Ogre that is", "often mistaken for a giant mudskipper. You have to force", "them out of the water with a fishing explosive." }, 32, false, false), + // Waiting for molanisks transform to be implemented before adding this to assignments + MOLANISKS(1, new int[] { 5751 }, new String[] { "Molanisks are subterranean creatures. You can find", "them in caves deep below the ground. I heard that the", "goblins have recently had trouble with some, but they", "use a bell of some sort to deal with them."}, 39, Quests.DEATH_TO_THE_DORGESHUUN), + MONKEYS(1, new int[] { 132, 1463, 1464, 2301, 4344, 4363, 6943, 7211, 7213, 7215, 7217, 7219, 7221, 7223, 7225, 7227, 1455, 1459, 1460, 1456, 1457, 1458 }, new String[] { "Monkeys are tricky creatures, they are agile and", "fairly fast. Learn to anticipate their movements." }, 1, false, false), + MOSS_GIANTS(40, new int[] { 112, 1587, 1588, 1681, 4534, 4688, 4706 }, new String[] { "Like other giants, Moss Giants often wield large", "weapons, learn to recognise what kind of weapon it is", "and act accordingly." }, 1, false, false), + // Waiting for zygomite transform to be implemented before adding this to assignments + MUTATED_ZYGOMITES(1, new int[] { 3346, 3347 }, new String[] { "Mutated Zygomites are hard to destroy. They regenerate", "quickly so you will need to finish them with fungicide." }, 57, Quests.LOST_CITY), + NECHRYAELS(85, new int[] { 1613 }, new String[] { "Nechryael are demons of decay which summon small", "winged beings to help them fight their victims." }, 80, false, false), + OGRES(40, new int[] { 115, 374, 2044, 2045, 2046, 2047, 2048, 2049, 2050, 2051, 2052, 2053, 2054, 2055, 2056, 2057, 2060, 2801, 3419, 7078, 7079, 7080, 7081, 7082 }, new String[] { "Ogres are brutal creatures, favouring large blunt", "maces and clubs they often attack without warning." }, 1, false, false), + OTHERWORDLY_BEING(40, new int[] { 126 }, new String[] { "Otherworldly Beings are ethereal beings making them", "weak to magical attack." }, 1, false, false), + PYREFIENDS(25, new int[] { 1633, 1634, 1635, 1636, 6216, 6631, 6641, 6660, 6668, 6683, 6709, 6721, }, new String[] { "Pyrefiends are beings of fire and molten rock,", "they're quick and agile so you'll want to be careful", "when getting close to them." }, 30, false, false), + RED_DRAGONS(1, new int[] { 53, 1589, 3588, 4667, 4668, 4669, 4670, 4671, 4672 }, new String[] { "Red Dragons are very powerful, stronger than most", "dragons, watch out for their fiery breath." }, 1, false, false), + ROCK_SLUGS(20, new int[] { 1631, 1632 }, new String[] { "Rockslugs are strange stoney slugs. You'll need to", "fight them to near death before finishing them off", "with Salt." }, 20, false, false), + // Seems to need Contact or the NPCs added to dungeons before adding this assignment as a task + SCABARITES(1, new int[] { 2001, 4500, 5251, 5252, 5255, 5256, 5250, 5254, 6777, 6778, 6774, 6780, 6781, 6773 }, new String[] {"Scabarites are insectoid creatures, found beyond the", "Kharidian deserts. They can be extremely dangerous."}, 1, Quests.CONTACT), + SCORPIONS(7, new int[] { 107, 1477, 4402, 4403, 144 }, new String[] { "Scorpions are almost always poisonous, their hard", "carapace makes them resistant to crushing and", "stabbing attacks." }, 1, false, false), + SEA_SNAKES(1, new int[] { 3939, 3940 }, new String[] { "Sea Snakes are long and slithery with a venomous bite.", "The larger ones are more poisonous, so keep an eye on", "your health." }, 1, Quests.ROYAL_TROUBLE), + SHADE(30, new int[] { 3617, 1250, 1241, 1246, 1248, 1250, 428, 1240 }, new String[] { "Shades are undead so magic is your best best against", "them, you can find Shades at Mort'ton." }, 1, true, false), + // Dungeon needs to be connected to the Legend's Guild before adding this assignment as a task + SHADOW_WARRIORS(1, new int[] { 158 }, new String[] { "Shadow Warriors are dark and mysterious, they hide in", "the shadows so be wary of ambushes." }, 1, Quests.LEGENDS_QUEST), + SKELETAL_WYVERN(70, new int[] { 3068, 3069, 3070, 3071 }, new String[] { "Skeletal Wyverns are extremely dangerous and they are", "hard to hit with arrows as they slip right through.", "To stand a good chance of surviving you'll need some", "elemental shielding from its icy breath." }, 72, false, false), + SKELETONS(15, new int[] { 90, 91, 92, 93, 94, 459, 1471, 1575, 1973, 2036, 2037, 2715, 2717, 3065, 3151, 3291, 3581, 3697, 3698, 3699, 3700, 3701, 3702, 3703, 3704, 3705, 3844, 3850, 3851, 4384, 4385, 4386, 5332, 5333, 5334, 5335, 5336, 5337, 5338, 5339, 5340, 5341, 5359, 5365, 5366, 5367, 5368, 5381, 5384, 5385, 5386, 5387, 5388, 5389, 5390, 5391, 5392, 5411, 5412, 5422, 6091, 6092, 6093, 6103, 6104, 6105, 6106, 6107, 6764, 6765, 6766, 6767, 6768, 2050, 2056, 2057, 1539, 7640 }, new String[] { "Skeletons are undead so magic is your best bet against", "them, there is even a spell specially for fighting the undead." }, 1, true, false), + SPIDERS(1, new int[] { 61, 1004, 1221, 1473, 1474, 63, 4401, 2034, 977, 7207, 134, 1009, 59, 60, 4400, 58, 62, 1478, 2491, 2492, 6376, 6377, }, new String[] { "Spiders are often poisonous, and many varieties are", "camouflaged too." }, 1, false, false), + SPIRTUAL_MAGES(60, new int[] { 6221, 6231, 6257, 6278 }, new String[] { "Spiritual mages can be found in the icy caverns near", "Trollheim, supporting the cause of their chosen god." }, 83, Quests.DEATH_PLATEAU), + SPIRTUAL_RANGERS(60, new int[] { 6220, 6230, 6256, 6276 }, new String[] { "Spiritual rangers can be found in the icy caverns near", "Trollheim, supporting the cause of their chosen god." }, 63, Quests.DEATH_PLATEAU), + SPIRTUAL_WARRIORS(60, new int[] { 6219, 6229, 6255, 6277, }, new String[] { "Spiritual warriors can be found in the icy caverns near", "Trollheim, supporting the cause of their chosen god." }, 68, Quests.DEATH_PLATEAU), + STEEL_DRAGONS( 85,new int[] { 1592, 3590 }, new String[] { "Steel dragons are dangerous and metallic, with steel", "scales that are far thicker than normal steel armour. As", "you are an accomplished slayer, I am sure you'll be", "able to deal with them easily."}, 1, false, true), + SUQAHS (65, new int[] { 4527, 4528, 4529, 4530, 4531, 4532, 4533 }, new String[] { "Suqahs can only be found on the mystical Lunar Isle.", "They are capable of melee and magic attacks and often", "drop hide, teeth and herbs!" }, 1, Quests.LUNAR_DIPLOMACY), + // No access to Lair of Tarn Razorlor but this should be added as a task when there is access + TERROR_DOGS(1, new int[] { 5417, 5418 }, new String[] { "Terror dogs are the personal pets of Tarn Razorlor.", "Wherever you find him, you will find them. They are", "bad-tempered and generally unfriendly." }, 40, Quests.HAUNTED_MINE), + TROLLS(60, new int[] { 72, 3584, 1098, 1096, 1097, 1095, 1101, 1105, 1102, 1103, 1104, 1130, 1131, 1132, 1133, 1134, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1138, 1560, 1561, 1562, 1563, 1564, 1565, 1566, 1935, 1936, 1937, 1938, 1939, 1940, 1941, 1942, 3840, 3841, 3842, 3843, 3845, 1933, 1934, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 391, 392, 393, 394, 395, 396}, new String[] { "Trolls regenerate damage quickly but are still", "vulnerable to poisons, they usually use crushing", "weapons." }, 1, false, false), + TUROTHS(60, new int[] { 1622, 1611, 1623, 1626, 1627, 1628, 1629, 1630, 7800}, new String[] { "Turoth are large vicious creatures with thick hides.", "You'll need a Leaf-Tipped Spear Sword or Battle-axe,", "Broad Arrows, or a Magic Dart to harm them." }, 55, false, false), + VAMPIRES(35, new int[] { 1220, 1223, 1225, 6214 }, new String[] { "Vampires are extremely powerful beings. They feed on", "the blood of the living so watch out you don't", "get bitten." }, 1, false, false), + // Waiting for the wall beast movement bug to be fixed before adding this as a task + WALL_BEASTS(1, new int[] { 7823 }, new String[] { "Wall Beasts are really much larger creatures but", "you'll only see their arms. You'll want something", "sharp on your head to stop them grabbing you." }, 35, false, false ), + // No way to get to Poison Swamp Cave + // If a grapple is implemented from W Castle Wars to E Posion Swamps + // The dungeon connected and populated + // then these could be added as a task + WARPED_TERROR_BIRD(1, new int[] { 6285, 6286, 6287, 6288, 6289, 6290, 6291, 6292, 6293, 6294, 6295, 6323, 6324, 6325, 6326, 6327, 6328, 6329, 6330, 6331, 6332, 6608 }, new String[] { "Warped Creatures can supposedly be found within a", "mysterious dungeon on the eastern edge of the Poison", "Waste. Be aware that to defeat them, you'll need to", "purify them in some way." },56, Quests.THE_PATH_OF_GLOUPHRIE), + WARPED_TORTOISE(1, new int[] { 6296, 6297 }, new String[] { "Warped Creatures can supposedly be found within a", "mysterious dungeon on the eastern edge of the Poison", "Waste. Be aware that to defeat them, you'll need to", "purify them in some way." },56, Quests.THE_PATH_OF_GLOUPHRIE), + WATERFIENDS(75, new int[] { 5361 }, new String[] { "Waterfiends are creatures of water, which live under", "the Baxtorian Lake. Their watery form is well defended", "against slashing and piercing weapons, so use", "something blunt." }, 1, false, false), + WEREWOLVES(60, new int[] { 6006, 6007, 6008, 6009, 6010, 6011, 6012, 6013, 6014, 6015, 6016, 6017, 6018, 6019, 6020, 6021, 6022, 6023, 6024, 6025, 6212, 6213, 6607, 6609, 6614, 6617, 6625, 6632, 6644, 6663, 6675, 6686, 6701, 6712, 6724, 6728, }, new String[] { "Werewolves are feral creatures, they are strong and", "tough with sharp claws and teeth." }, 1, false, false), + WOLVES(20, new int[] { 95, 96, 97, 141, 142, 143, 839, 1198, 1330, 1558, 1559, 1951, 1952, 1953, 1954, 1955, 1956, 4413, 4414, 6046, 6047, 6048, 6049, 6050, 6051, 6052, 6829, 6830, 7005 }, new String[] { "Wolves are pack animals, so you'll always find them", "in groups. Watch out for their bite, it can be nasty." }, 1, false, false), + ZOMBIES(10, new int[] { 73, 74, 75, 76, 2060, 2714, 2863, 2866, 2869, 2878, 3622, 4392, 4393, 4394, 5293, 5294, 5295, 5296, 5297, 5298, 5299, 5300, 5301, 5302, 5303, 5304, 5305, 5306, 5307, 5308, 5309, 5310, 5311, 5312, 5313, 5314, 5315, 5316, 5317, 5318, 5319, 5320, 5321, 5322, 5323, 5324, 5325, 5326, 5327, 5328, 5329, 5330, 5331, 5375, 5376, 5377, 5378, 5379, 5380, 5393, 5394, 5395, 5396, 5397, 5398, 5399, 5400, 5401, 5402, 5403, 5404, 5405, 5406, 5407, 5408, 5409, 5410, 6099, 6100, 6131, 8149, 8150, 8151, 8152, 8153, 8159, 8160, 8161, 8162, 8163, 8164, 2044, 2045, 2046, 2047, 2048, 2049, 2050, 2051, 2052, 2053, 2054, 2055, 7641, 1465, 1466, 1467, 2837, 2838, 2839, 2840, 2841, 2842, 5629, 5630, 5631, 5632, 5633, 5634, 5635, 5636, 5637, 5638, 5639, 5640, 5641, 5642, 5643, 5644, 5645, 5646, 5647, 5648, 5649, 5650, 5651, 5652, 5653, 5654, 5655, 5656, 5657, 5658, 5659, 5660, 5661, 5662, 5663, 5664, 5665, 2843, 2844, 2845, 2846, 2847, 2848}, new String[] { "Zombies are undead so magic is your best bet against", "them, there is even a spell specially for", "fighting the undead." }, 1, true, false), + // Bosses need to be handled differently/have a source. They should probably be removed from here + JAD(90, new int[] { }, new String[] { "You must complete the entire fight cave, including", "TzTok-Jad. Beware, only those skilled in combat should", "attempt this and death will reset your task." }, 1, false, false), + CHAOS_ELEMENTAL(90, new int[] { 3200 }, new String[] { "The Chaos Elemental roams the deepest Wilderness. It", "can teleport you and make you unequip items randomly." }, 1, false, false), + GIANT_MOLE(75, new int[] { 3340 }, new String[] { "Dig on the mole-hills in Falador Park to enter the", "mole cave, and bring a lantern he can't extinguish." }, 1, false, false), + KING_BLACK_DRAGON(75, new int[] { 50 }, new String[] { "The King Black Dragon's cave is reached by pulling a", "lever in the Wilderness. An anti-fire shield is", "strongly recommended." }, 1, false, true), + COMMANDER_ZILYANA(90, new int[] { 6247 }, new String[] { "Commander Zilyana is in the God Wars Dungeon.", "She frequently uses magic attacks." }, 1, false, false), + GENERAL_GRARDOOR(90, new int[] { 6260 }, new String[] { "General Graardor is in the God Wars Dungeon.", "He uses melee and ranged attacks." }, 1, false, false), + KRIL_TSUTSAROTH(90, new int[] { 6203 }, new String[] { "K'ril Tsutsaroth is in the God Wars Dungeon.", "He's poisonous and he can hit through prayers." }, 1, false, false), + KREE_ARRA(90, new int[] { 6222 }, new String[] { "Kree'arra roosts in the God Wars Dungeon.", "Melee attacks don't work on flying creatures,", "and you'll need a grappling hook to get in." }, 1, false, false), + ; + + static final HashMap taskMap = new HashMap<>(); + static{ + Arrays.stream(Tasks.values()).forEach(entry -> Arrays.stream(entry.ids).forEach(id -> taskMap.putIfAbsent(id,entry))); + } + public final int levelReq; + public final int combatCheck; + public final String[] info; + public final int[] ids; + public boolean undead = false; + public boolean dragon = false; + public Quests questReq = null; + Tasks(int combatCheck, int[] ids, String[] info, int levelReq, boolean undead, boolean dragon){ + this.levelReq = levelReq; + this.ids = ids; + this.info = info; + this.undead = undead; + this.dragon = dragon; + this.combatCheck = combatCheck; + } + + Tasks (int combatCheck, int[] ids, String[] info, int levelReq, Quests questReq) { + this.combatCheck = combatCheck; + this.ids = ids; + this.info = info; + this.levelReq = levelReq; + this.questReq = questReq; + } + + public int[] getNpcs(){ + return ids; + } + + public String[] getTip(){ + return info; + } + + public boolean hasQuestRequirements (Player player) { + return questReq == null || hasRequirement(player, questReq, false); + } + + public static Tasks forId(int id){ + return taskMap.get(id); + } + + public String getName(){ + return NPCDefinition.forId(ids[0]).getName(); + } + +} diff --git a/Server/src/main/content/global/skill/slayer/TurothBehavior.kt b/Server/src/main/content/global/skill/slayer/TurothBehavior.kt new file mode 100644 index 0000000..c1cbfac --- /dev/null +++ b/Server/src/main/content/global/skill/slayer/TurothBehavior.kt @@ -0,0 +1,16 @@ +package content.global.skill.slayer + +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player + +class TurothBehavior : NPCBehavior(*Tasks.TUROTHS.ids) { + override fun beforeDamageReceived(self: NPC, attacker: Entity, state: BattleState) { + if (attacker is Player) { + if (!SlayerUtils.hasBroadWeaponEquipped(attacker, state)) + state.neutralizeHits() + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/slayer/WaterfiendBehavior.kt b/Server/src/main/content/global/skill/slayer/WaterfiendBehavior.kt new file mode 100644 index 0000000..e814eaf --- /dev/null +++ b/Server/src/main/content/global/skill/slayer/WaterfiendBehavior.kt @@ -0,0 +1,55 @@ +package content.global.skill.slayer + +import core.game.node.entity.Entity +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.combat.CombatSwingHandler +import core.game.node.entity.combat.MultiSwingHandler +import core.game.node.entity.combat.equipment.SwitchAttack +import core.game.node.entity.impl.Animator.Priority +import core.game.node.entity.impl.Projectile +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.world.update.flag.context.Animation + +class WaterfiendBehavior : NPCBehavior(*Tasks.WATERFIENDS.ids) { + private val combatHandler = MultiSwingHandler( + true, + SwitchAttack( + CombatStyle.MAGIC.swingHandler, + Animation(1581, Priority.HIGH), + null, + null, + Projectile.create( + null as Entity?, + null, + 500, + 15, + 30, + 50, + 50, + 14, + 255 + ) + ), + SwitchAttack( + CombatStyle.RANGE.swingHandler, + Animation(1581, Priority.HIGH), + null, + null, + Projectile.create( + null as Entity?, + null, + 16, + 15, + 30, + 50, + 50, + 14, + 255 + ) + ) + ) + override fun getSwingHandlerOverride(self: NPC, original: CombatSwingHandler): CombatSwingHandler { + return combatHandler + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/slayer/dungeon/AncientCavern.java b/Server/src/main/content/global/skill/slayer/dungeon/AncientCavern.java new file mode 100644 index 0000000..7e8e55c --- /dev/null +++ b/Server/src/main/content/global/skill/slayer/dungeon/AncientCavern.java @@ -0,0 +1,239 @@ +package content.global.skill.slayer.dungeon; + +import static core.api.ContentAPIKt.*; +import core.cache.def.impl.SceneryDefinition; +import core.game.component.CloseEvent; +import core.game.component.Component; +import core.plugin.Initializable; +import content.global.skill.agility.AgilityHandler; +import core.game.interaction.Option; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.ImpactHandler.HitsplatType; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneBuilder; +import core.game.world.map.zone.ZoneRestriction; +import core.game.world.update.flag.context.Animation; +import core.net.packet.PacketRepository; +import core.net.packet.context.MinimapStateContext; +import core.net.packet.out.MinimapState; +import core.plugin.Plugin; +import core.plugin.ClassScanner; +import core.tools.RandomFunction; + +/** + * Handles the ancient cavern. + * @author Vexia + */ +@Initializable +public final class AncientCavern extends MapZone implements Plugin { + + /** + * The loots recieved when rummaging a skeleton. + */ + private static final Item[] LOOTS = new Item[] { new Item(526), new Item(11337), new Item(11341) }; + + /** + * The skeleton barbarian id. + */ + private static final int[] SKELETONS = new int[] { 6103, 6106 }; + + /** + * Constructs a new {@code AnicentCavern} {@code Object}. + */ + public AncientCavern() { + super("ancient cavern", true, ZoneRestriction.CANNON); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ZoneBuilder.configure(this); + ClassScanner.definePlugin(new OptionHandler() { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(25274).getHandlers().put("option:dive in", this); + return this; + } + + @Override + public boolean handle(final Player player, Node node, String option) { + lock(player, 30); + AgilityHandler.forceWalk(player, -1, player.getLocation(), player.getLocation().transform(0, -6, 0), Animation.create(6723), 10, 0.0, null); + GameWorld.getPulser().submit(new Pulse(1, player) { + int count; + + @Override + public boolean pulse() { + switch (++count) { + case 4: + player.getInterfaceManager().openOverlay(new Component(115)); + break; + case 7: + player.getAnimator().reset(); + player.getInterfaceManager().close(); + player.getInterfaceManager().closeOverlay(); + player.getProperties().setTeleportLocation(Location.create(1763, 5365, 1)); + player.getPacketDispatch().sendMessages("You dive into the swirling maelstorm of the whirlpool.", "You are swirled beneath the water, the darkness and pressure are overwhelming.", "Mystical forces guide you into a cavern below the whirlpool."); + break; + case 8: + unlock(player); + return true; + } + return false; + } + }); + return true; + } + + @Override + public Location getDestination(Node node, Node n) { + if (node.getLocation().getX() <= 2511) { + return Location.create(2511, 3516, 0); + } else { + return Location.create(2512, 3516, 0); + } + } + + }); + return this; + } + + @Override + public boolean interact(Entity e, Node target, Option option) { + if (e instanceof Player) { + Player player = (Player) e; + switch (target.getId()) { + case 25216: + handleLog(player); + return true; + case 25362: + rummageSkeleton(player, (Scenery) target); + return true; + } + } + return super.interact(e, target, option); + } + + /** + * Handles the log ride. + * @param player the player. + */ + private void handleLog(final Player player) { + player.removeAttribute("canClose"); + player.lock(14); + player.getImpactHandler().setDisabledTicks(14); + GameWorld.getPulser().submit(new Pulse(1) { + int count = 0; + + @Override + public boolean pulse() { + switch (count++) { + case 1: + Component c = new Component(115); + c.setCloseEvent(new CloseEvent() { + + @Override + public boolean close(Player player, Component c) { + if (player.getAttribute("canClose", false)) { + return true; + } + return false; + } + + }); + player.getInterfaceManager().open(c); + break; + case 3: + PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 2)); + player.getInterfaceManager().removeTabs(0, 1, 2, 3, 4, 5, 6, 11, 12); + break; + case 13: + player.getProperties().setTeleportLocation(Location.create(2532, 3412, 0)); + break; + case 14: + player.setAttribute("canClose", true); + player.unlock(); + player.getInterfaceManager().close(); + player.getInterfaceManager().closeOverlay(); + player.getInterfaceManager().restoreTabs(); + PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 0)); + return true; + } + return false; + } + + }); + } + + /** + * Rummages a skeleton. + * @param player the player. + * @param object the object. + */ + private void rummageSkeleton(Player player, Scenery object) { + final boolean fullInvy = player.getInventory().freeSlots() < 1; + final int random = RandomFunction.random(0, 2); + player.getPacketDispatch().sendMessages("You rummage in the sharp, slimy pile of bones in search of something useful..."); + if (random == 0) { + if (!fullInvy) { + player.getInventory().add(LOOTS[RandomFunction.random(LOOTS.length)], player); + player.getPacketDispatch().sendMessage("...you find something and stow it in your pack."); + } else { + player.getPacketDispatch().sendMessage("...you find something, but it drops to the floor."); + } + } else if (random == 1) { + NPC spawn = NPC.create(SKELETONS[RandomFunction.random(SKELETONS.length)], object.getLocation()); + spawn.init(); + spawn.setRespawn(false); + removeSkeleton(object, spawn); + spawn.getProperties().getCombatPulse().attack(player); + player.getPacketDispatch().sendMessage("...the bones object."); + } else { + player.getPacketDispatch().sendMessage("...but there's nothing remotely valuable."); + } + if (RandomFunction.random(10) < 3) { + player.getImpactHandler().manualHit(player, RandomFunction.random(14), HitsplatType.NORMAL); + } + } + + /** + * Removes a skeleton. + * @param object the object. + * @param spawn the spawn. + */ + private void removeSkeleton(final Scenery object, final NPC spawn) { + SceneryBuilder.remove(object); + GameWorld.getPulser().submit(new Pulse(200) { + @Override + public boolean pulse() { + if (spawn != null && spawn.isActive()) { + spawn.clear(); + } + SceneryBuilder.add(object); + return true; + } + }); + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return this; + } + + @Override + public void configure() { + register(new ZoneBorders(1723, 5296, 1831, 5394)); + } + +} diff --git a/Server/src/main/content/global/skill/slayer/dungeon/FremennikDungeon.java b/Server/src/main/content/global/skill/slayer/dungeon/FremennikDungeon.java new file mode 100644 index 0000000..cb1cb5c --- /dev/null +++ b/Server/src/main/content/global/skill/slayer/dungeon/FremennikDungeon.java @@ -0,0 +1,112 @@ +package content.global.skill.slayer.dungeon; + +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import content.global.skill.agility.AgilityHandler; +import core.game.interaction.Option; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.ImpactHandler.HitsplatType; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneBuilder; +import core.game.world.map.zone.ZoneRestriction; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; +import core.tools.RandomFunction; + +/** + * Represents the femennik dungeon zone. + * @author Vexia + */ +@Initializable +public final class FremennikDungeon extends MapZone implements Plugin { + + /** + * Constructs a new {@code FremennikDungeon} {@code Object}. + */ + public FremennikDungeon() { + super("fremennik", true, ZoneRestriction.CANNON); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ZoneBuilder.configure(this); + return this; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return true; + } + + @Override + public boolean interact(Entity entity, Node target, Option option) { + if (entity instanceof Player && target instanceof Scenery) { + final Player player = (Player) entity; + final Scenery object = (Scenery) target; + final Direction dir = Direction.getLogicalDirection(player.getLocation(), object.getLocation()); + switch (target.getId()) { + case 9326:// pyrefiend area. + if (player.getSkills().getLevel(Skills.AGILITY) < 81) { + player.getPacketDispatch().sendMessage("You need an Agility level of at least 81 to do this."); + return true; + } + player.lock(); + GameWorld.getPulser().submit(new Pulse(1, player) { + int count; + + @Override + public boolean pulse() { + switch (++count) { + case 1: + Location start = object.getLocation().transform(dir.getOpposite(), 2); + player.getWalkingQueue().reset(); + player.getWalkingQueue().addPath(start.getX(), start.getY()); + break; + case 2: + player.faceLocation(object.getLocation()); + break; + case 3: + Location end = object.getLocation().transform(dir, 1); + AgilityHandler.forceWalk(player, -1, player.getLocation(), end, Animation.create(1995), 20, 0.0, null); + break; + case 4: + final boolean fail = AgilityHandler.hasFailed(player, 20, 0.1); + if (fail) { + player.getImpactHandler().manualHit(player, RandomFunction.random(6), HitsplatType.NORMAL); + player.getPacketDispatch().sendMessage("You trigger the trap as you jump over it."); + } + player.animate(Animation.create(1603)); + player.unlock(); + return true; + } + return false; + } + }); + return true; + case 9321: + if (player.getSkills().getLevel(Skills.AGILITY) < 62) { + player.getPacketDispatch().sendMessage("You need an Agility level of at least 62 to do this."); + return true; + } + Location end = object.getLocation().transform(dir, 4); + AgilityHandler.walk(player, -1, player.getLocation(), end, Animation.create(156), 10, "You climb your way through the narrow crevice."); + return true; + } + } + return super.interact(entity, target, option); + } + + @Override + public void configure() { + register(new ZoneBorders(2671, 9950, 2813, 10054)); + } + +} diff --git a/Server/src/main/content/global/skill/slayer/dungeon/LumbridgeDungeon.java b/Server/src/main/content/global/skill/slayer/dungeon/LumbridgeDungeon.java new file mode 100644 index 0000000..c47cfff --- /dev/null +++ b/Server/src/main/content/global/skill/slayer/dungeon/LumbridgeDungeon.java @@ -0,0 +1,181 @@ +package content.global.skill.slayer.dungeon; + +import content.global.skill.slayer.SlayerEquipmentFlags; +import core.cache.def.impl.NPCDefinition; +import core.game.interaction.Option; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneBuilder; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.plugin.ClassScanner; +import core.tools.RandomFunction; + +import java.util.HashMap; +import java.util.Map; + +/** + * Handles the lumbridge dungeon. + * @author Vexia + */ +@Initializable +public final class LumbridgeDungeon extends MapZone implements Plugin { + + /** + * The beast locations to check. + */ + private static final Map BEASTS = new HashMap<>(); + + /** + * Constructs a new {@code LumbridgeDungeon} {@code Object}. + */ + public LumbridgeDungeon() { + super("lumbridge swamp dungeon", true); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ZoneBuilder.configure(this); + ClassScanner.definePlugin(new WallBeastNPC()); + return this; + } + + /* + * @Override public boolean move(Entity e, Location loc, Location dest) { if + * (!e.getLocks().isMovementLocked() && e instanceof Player) { final + * WallBeastNPC npc = BEASTS.get(e.getLocation()); if (npc != null) { + * e.setDirection(Direction.getLogicalDirection(loc, dest)); return false; } + * } return super.move(e, loc, dest); } + */ + + @Override + public void locationUpdate(Entity entity, Location last) { + if (entity instanceof Player) { + final Player player = (Player) entity; + final WallBeastNPC npc = BEASTS.get(last); + if (npc != null && npc.canAttack(player)) { + npc.trigger(player); + } + } + } + + /** + * Checks if the player has the helmet. + * @param player the player. + * @return {@code True} if so. + */ + private boolean hasHelmet(final Player player) { + return SlayerEquipmentFlags.hasSpinyHelmet(player); + } + + @Override + public boolean interact(Entity e, Node target, Option option) { + return super.interact(e, target, option); + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public void configure() { + register(new ZoneBorders(3137, 9534, 3295, 9602)); + } + + /** + * Handles the wall beast npc. + * @author Vexia + */ + public final class WallBeastNPC extends AbstractNPC { + + /** + * Constructs a new {@code WallBeastNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + public WallBeastNPC(int id, Location location) { + super(id, location,false); + } + + /** + * Constructs a new {@code WallBeastNPC} {@code Object}. + */ + public WallBeastNPC() { + super(7823, null,false); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new WallBeastNPC(id, location); + } + + @Override + public void init() { + super.init(); + getLocks().lockMovement(Integer.MAX_VALUE); + BEASTS.put(getLocation().transform(Direction.SOUTH, 1), this); + } + + @Override + public void handleTickActions() { + super.handleTickActions(); + + } + + /** + * Triggers the beast. + * @param player the player. + */ + public void trigger(final Player player) { + boolean isProtected = hasHelmet(player); + player.face(this); + if (!isProtected) { + animate(NPCDefinition.forId(7823).getCombatAnimation(3)); + player.animate(Animation.create(1810)); + GameWorld.getPulser().submit(new Pulse(8, player) { + @Override + public boolean pulse() { + getAnimator().reset(); + player.getAnimator().reset(); + player.getImpactHandler().handleImpact(WallBeastNPC.this, RandomFunction.random(1, 18), CombatStyle.MELEE); + return true; + } + }); + return; + } else { + transform(7823); + attack(player); + } + } + + @Override + public void finalizeDeath(Entity killer) { + //TODO + } + + @Override + public boolean isPoisonImmune() { + return true; + } + + @Override + public int[] getIds() { + //return Tasks.WALL_BEASTS.getTask().getNpcs(); + int[] empty = {}; + return empty; + } + + } + +} diff --git a/Server/src/main/content/global/skill/slayer/dungeon/SmokeDungeon.java b/Server/src/main/content/global/skill/slayer/dungeon/SmokeDungeon.java new file mode 100644 index 0000000..3dec3dd --- /dev/null +++ b/Server/src/main/content/global/skill/slayer/dungeon/SmokeDungeon.java @@ -0,0 +1,181 @@ +package content.global.skill.slayer.dungeon; + +import content.global.skill.slayer.SlayerEquipmentFlags; +import core.cache.def.impl.SceneryDefinition; +import core.game.component.Component; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.ImpactHandler.HitsplatType; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneBuilder; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.plugin.ClassScanner; +import core.tools.RandomFunction; + +import java.util.ArrayList; +import java.util.List; + +/** + * Handles the smoke dungeon. + * @author Vexia + */ +@Initializable +public final class SmokeDungeon extends MapZone implements Plugin { + + /** + * The chats to send. + */ + private static final String[] CHATS = new String[] { "*choke*", "*cough*" }; + + /** + * The players list. + */ + private static final List PLAYERS = new ArrayList<>(20); + + /** + * The tick delay until the next effect. + */ + private static final int DELAY = 20; + + /** + * The smoke effect pulse. + */ + private static Pulse pulse = new Pulse(3) { + @Override + public boolean pulse() { + for (Player player : PLAYERS) { + if (player.getInterfaceManager().isOpened() || player.getInterfaceManager().hasChatbox() || player.getLocks().isMovementLocked()) { + continue; + } + if (SmokeDungeon.getDelay(player) < GameWorld.getTicks() && !isProtected(player)) { + effect(player); + } + } + return PLAYERS.isEmpty(); + } + }; + + /** + * Constructs a new {@code SmokeDungeon} {@code Object} + */ + public SmokeDungeon() { + super("zmoke dungeon", true); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ClassScanner.definePlugin(new OptionHandler() { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(36002).getHandlers().put("option:climb-down", this); + SceneryDefinition.forId(6439).getHandlers().put("option:climb-up", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + switch (node.getId()) { + case 36002: + player.getProperties().setTeleportLocation(Location.create(3206, 9379, 0)); + player.getPacketDispatch().sendMessage("You climb down the well."); + break; + case 6439: + player.getProperties().setTeleportLocation(Location.create(3310, 2963, 0)); + player.getPacketDispatch().sendMessage("You climb up the rope."); + break; + } + return true; + } + + }); + ZoneBuilder.configure(this); + return this; + } + + @Override + public boolean enter(Entity e) { + if (e instanceof Player) { + Player p = (Player) e; + setDelay(p); + PLAYERS.add(p); + if (!pulse.isRunning()) { + pulse.restart(); + pulse.start(); + GameWorld.getPulser().submit(pulse); + } + p.getInterfaceManager().openOverlay(new Component(118)); + } + return true; + } + + @Override + public boolean leave(Entity e, boolean logout) { + if (e instanceof Player) { + Player p = (Player) e; + p.getInterfaceManager().closeOverlay(); + PLAYERS.remove(e); + e.removeAttribute("smoke-delay"); + } + return super.leave(e, logout); + } + + /** + * Effects the player with smoke. + * @param player the player. + */ + private static void effect(Player player) { + int hit = 10; + setDelay(player); + if (RandomFunction.random(2) == 1) { + player.sendChat(CHATS[RandomFunction.random(CHATS.length)]); + player.getPacketDispatch().sendMessage("The stagnant, smoky air chokes you."); + } + player.getImpactHandler().manualHit(player, hit, HitsplatType.NORMAL); + } + + /** + * Sets the delay on the player. + * @param player the player. + */ + private static void setDelay(Player player) { + player.setAttribute("smoke-delay", GameWorld.getTicks() + DELAY); + } + + /** + * Gets the smoke delay. + * @param player the player. + * @return the delay. + */ + private static int getDelay(Player player) { + return player.getAttribute("smoke-delay", 0); + } + + /** + * Checks if the player is protected. + * @param player the player. + * @return {@code True} if so. + */ + private static boolean isProtected(Player player) { + return SlayerEquipmentFlags.hasFaceMask(player); + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return this; + } + + @Override + public void configure() { + register(new ZoneBorders(3196, 9337, 3344, 9407)); + pulse.stop(); + } + +} diff --git a/Server/src/main/content/global/skill/slayer/dungeon/StrongholdSlayerCave.java b/Server/src/main/content/global/skill/slayer/dungeon/StrongholdSlayerCave.java new file mode 100644 index 0000000..03852d1 --- /dev/null +++ b/Server/src/main/content/global/skill/slayer/dungeon/StrongholdSlayerCave.java @@ -0,0 +1,241 @@ +/* +package core.game.node.entity.skill.slayer.dungeon; + +import core.game.dialogue.FacialExpression; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.skill.gather.SkillingTool; +import core.game.node.entity.skill.slayer.Master; +import org.crandor.game.interaction.Option; +import org.crandor.game.node.Node; +import org.crandor.game.node.entity.Entity; +import org.crandor.game.node.entity.combat.CombatStyle; +import org.crandor.game.node.entity.impl.ForceMovement; +import org.crandor.game.node.entity.npc.NPC; +import org.crandor.game.node.entity.player.Player; +import org.crandor.game.node.object.GameObject; +import org.crandor.game.node.object.ObjectBuilder; +import org.crandor.game.system.task.Pulse; +import org.crandor.game.world.map.Location; +import org.crandor.game.world.map.zone.MapZone; +import org.crandor.game.world.map.zone.ZoneBorders; +import org.crandor.game.world.map.zone.ZoneBuilder; +import org.crandor.game.world.update.flag.context.Animation; +import org.crandor.plugin.InitializablePlugin; +import org.crandor.plugin.Plugin; + +*/ +/** + * Handles the stronghold slayer cave. + * @author Vexia + * @author Empathy + * + *//* + +@InitializablePlugin +public class StrongholdSlayerCave extends MapZone implements Plugin { + + */ +/** + * The step over animation. + *//* + + private final Animation stepOver = new Animation(1603); + + */ +/** + * The climb animation. + *//* + + private final Animation climb = new Animation(3063); + + */ +/** + * Constructs a new @{Code StrongholdSlayerCave} object. + *//* + + public StrongholdSlayerCave() { + super("Slayer stronghold zone", true); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ZoneBuilder.configure(this); + return this; + } + + @Override + public boolean interact(Entity e, final Node node, Option option) { + int id = node.getId(); + final Player player = e.asPlayer(); + switch (option.getName().toLowerCase()) { + case "attack": + if (player.isAdmin()) { + player.attack(node); + return true; + } + attack: { + if (SlayerManager.getInstance(player).getMaster() == Master.NIEVE) { + for (int i : SlayerManager.getInstance(player).getTask().getNpcs()) { + if (i != id) { + continue; + } + player.attack(node); + break attack; + } + } + player.face(node.asNpc()); + player.getDialogueInterpreter().sendDialogues(Master.NIEVE.getNpc(), FacialExpression.OLD_NORMAL, "That's not your assigned Slayer target. In my cave,", "I expect people to focus on their Slayer training."); + } + return true; + case "enter": + switch (id){ + case 44131://stronghold entrance + player.teleport(Location.create(2444, 9825, 0)); + break; + case 42284://kraken entrance + player.teleport(Location.create(3696, 5798, 0)); + break; + } + return true; + case "use": + switch (id) { + case 42287: + player.teleport(Location.create(2430, 3424, 0)); + break; + case 42340: + player.teleport(Location.create(2486, 9797, 0)); + break; + } + return true; + case "chop": + final GameObject object = node.asObject(); + SkillingTool axe = SkillingTool.getHatchet(player); + if (axe == null) { + player.sendMessage("You need an axe to chop through this."); + return true; + } + player.animate(axe.getAnimation()); + player.getPulseManager().run(new Pulse(3, player) { + + @Override + public boolean pulse() { + if (ObjectBuilder.replace(object, object.transform(0), 2)) { + Location destination = getRootLocation(player, object); + player.lock(3); + player.getWalkingQueue().reset(); + player.getWalkingQueue().addPath(destination.getX(), destination.getY(), true); + return true; + } + return true; + } + + }); + return true; + case "climb": + final GameObject mud = node.asObject(); + final Location rightPile = Location.create(2427, 9763, 0); + final Location leftPile = Location.create(2427, 9766, 0); + if (id == 42311) { + if (player.getSkills().getLevel(Skills.AGILITY) < 72) { + player.sendMessage("You need an Agility level of at least 72 to negotiate this obstacle."); + return true; + } + final boolean northPile = mud.getLocation().equals(leftPile); + ForceMovement.run(player, player.getLocation(), northPile ? leftPile : rightPile, climb); + player.getPulseManager().run(new Pulse(1, player) { + + int count; + + @Override + public boolean pulse() { + count++; + if (count == 6) { + player.teleport(Location.create(2427, northPile ? 9762 : 9767, 0)); + return true; + } + if (count == 3) { + player.teleport(northPile ? rightPile : leftPile); + player.faceLocation(northPile ? leftPile : rightPile); + return false; + } + return false; + } + + }); + + } + return true; + case "step-over": + final GameObject root = node.asObject(); + final Location destination = getRootLocation(player, root); + player.getPulseManager().run(new Pulse(1, player) { + + @Override + public boolean pulse() { + ForceMovement.run(player, player.getLocation(), destination, stepOver); + return true; + } + + }); + return true; + } + return super.interact(e, node, option); + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public void configure() { + register(new ZoneBorders(2244, 9730, 2506, 9845)); + registerRegion(14682); + registerRegion(9525); + registerRegion(14939); + } + + + @Override + public boolean continueAttack(Entity e, Node target, CombatStyle style, boolean message) { + if (!e.isPlayer() || !(target instanceof NPC)) { + return super.continueAttack(e, target, style, message); + } + Player player = e.asPlayer(); + if (player.isAdmin()) { + return super.continueAttack(player, target, style, message); + } + int id = target.getId(); + if (SlayerManager.getInstance(player).getMaster() == Master.NIEVE) { + for (int i : SlayerManager.getInstance(player).getTask().getNpcs()) { + if (i != id) { + continue; + } + return super.continueAttack(player, target, style, message); + } + } + player.face(target.asNpc()); + player.getDialogueInterpreter().sendDialogues(Master.NIEVE.getNpc(), FacialExpression.OLD_NORMAL, "That's not your assigned Slayer target. In my cave,", "I expect people to focus on their Slayer training."); + return false; + } + + */ +/** + * Gets the location for the player to move to. + * @param player The player. + * @param object The object. + *//* + + private Location getRootLocation(Player player, GameObject object) { + Location obj = object.getLocation(); + Location play = player.getLocation(); + if (obj.getY() == play.getY()) { + int newX = (play.getX() - obj.getX() > 0 ? obj.getX() - 1 : obj.getX() + 1); + return Location.create(newX, play.getY(), play.getZ()); + } + int newY = (play.getY() - obj.getY() > 0 ? obj.getY() - 1 : obj.getY() + 1); + return Location.create(play.getX(), newY, play.getZ()); + } + +} +*/ diff --git a/Server/src/main/content/global/skill/smithing/BarType.java b/Server/src/main/content/global/skill/smithing/BarType.java new file mode 100644 index 0000000..1052998 --- /dev/null +++ b/Server/src/main/content/global/skill/smithing/BarType.java @@ -0,0 +1,113 @@ +package content.global.skill.smithing; + +/** + * @author Emperor + */ +public enum BarType { + + /** + * Bronze Interface + */ + BRONZE(2349, 12.5, "Bronze Smithing"), + + /** + * Blurite + */ + BLURITE(9467, 16, "Blurite Smithing"), + + /** + * Iron + */ + IRON(2351, 25, "Iron Smithing"), + + /** + * Steel + */ + STEEL(2353, 37.5, "Steel Smithing"), + + /** + * Mithril + */ + MITHRIL(2359, 50, "Mithril Smithing"), + + /** + * Adamant + */ + ADAMANT(2361, 62.5, "Adamant Smithing"), + + /** + * Runite + */ + RUNITE(2363, 75, "Runite Smithing"); + + /** + * The bar type id. + */ + private int bar; + + /** + * The bar's name. + */ + private String string; + + /** + * The amount of experience gained + */ + private double experience; + + /** + * Constructs a new {@code BarType} {@code Object}. + * @param bar the bar. + * @param experience the exp. + * @param string the string. + */ + private BarType(int bar, double experience, String string) { + this.bar = bar; + this.string = string; + this.experience = experience; + } + + /** + * Retreive's the bar's type. + * @return bar type id; + */ + public int getBarType() { + return bar; + } + + /** + * Retreive's the bar's name. + * @return the bar's name. + */ + public String getBarName() { + return string; + } + + /** + * Gets the exp. + * @return the exp. + */ + public double getExperience() { + return experience; + } + + public static BarType getBarTypeForId(int itemId) { + switch (itemId) { + case 2349: + return BarType.BRONZE; + case 2351: + return BarType.IRON; + case 2353: + return BarType.STEEL; + case 2359: + return BarType.MITHRIL; + case 2361: + return BarType.ADAMANT; + case 2363: + return BarType.RUNITE; + case 9467: + return BarType.BLURITE; + } + return null; + } +} diff --git a/Server/src/main/content/global/skill/smithing/Bars.java b/Server/src/main/content/global/skill/smithing/Bars.java new file mode 100644 index 0000000..7514693 --- /dev/null +++ b/Server/src/main/content/global/skill/smithing/Bars.java @@ -0,0 +1,918 @@ +package content.global.skill.smithing; + +import core.game.node.entity.player.Player; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author Emperor + * @author 'Vexia + */ +public enum Bars { + + /** + * Bronze Dagger + */ + BRONZE_DAGGER(BarType.BRONZE, SmithingType.TYPE_DAGGER, 1205, 1), + + /** + * Bronze Axe + */ + BRONZE_AXE(BarType.BRONZE, SmithingType.TYPE_AXE, 1351, 1), + + /** + * Bronze Mace + */ + BRONZE_MACE(BarType.BRONZE, SmithingType.TYPE_MACE, 1422, 2), + + /** + * Bronze Medium helm + */ + BRONZE_MED_HELM(BarType.BRONZE, SmithingType.TYPE_MEDIUM_HELM, 1139, 3), + + /** + * Bronze Crossbow Bolt + */ + BRONZE_CROSSBOW_BOLT(BarType.BRONZE, SmithingType.TYPE_CROSSBOW_BOLT, 9375, 3), + + /** + * Bronze Sword + */ + BRONZE_SWORD(BarType.BRONZE, SmithingType.TYPE_SWORD, 1277, 4), + + /** + * Bronze Dart Tips + */ + BRONZE_DART_TIPS(BarType.BRONZE, SmithingType.TYPE_DART_TIP, 819, 4), + + /** + * Bronze Nails + */ + BRONZE_NAILS(BarType.BRONZE, SmithingType.TYPE_NAIL, 4819, 4), + + /** + * Bronze Wire + */ + BRONZE_WIRE(BarType.BRONZE, SmithingType.TYPE_WIRE, 1794, 4), + + /** + * Bronze Arrow Tips + */ + BRONZE_ARROW_TIPS(BarType.BRONZE, SmithingType.TYPE_ARROW_TIP, 39, 5), + + /** + * Bronze Scimitar + */ + BRONZE_SCIMITAR(BarType.BRONZE, SmithingType.TYPE_SCIMITAR, 1321, 5), + + /** + * Bronze Crossbow Limbs + */ + BRONZE_CROSSBOW_LIMBS(BarType.BRONZE, SmithingType.TYPE_CROSSBOW_LIMB, 9420, 6), + + /** + * Bronze longsword + */ + BRONZE_LONGSWORD(BarType.BRONZE, SmithingType.TYPE_LONGSWORD, 1291, 6), + + /** + * Bronze ThrowingKnife + */ + BRONZE_THROWINGKNFIE(BarType.BRONZE, SmithingType.TYPE_THROWING_KNIFE, 864, 7), + + /** + * Bronze Full helmet + */ + BRONZE_FULL_HELM(BarType.BRONZE, SmithingType.TYPE_FULL_HELM, 1155, 7), + + /** + * Bronze Square Shield + */ + BRONZE_SQUARE_SHIELD(BarType.BRONZE, SmithingType.TYPE_SQUARE_SHIELD, 1173, 8), + + /** + * Bronze Warhammer + */ + BRONZE_WAR_HAMMER(BarType.BRONZE, SmithingType.TYPE_WARHAMMER, 1337, 9), + + /** + * Bronze BattleAxe + */ + BRONZE_BATTLEAXE(BarType.BRONZE, SmithingType.TYPE_BATTLE_AXE, 1375, 10), + + /** + * Bronze ChainBody + */ + BRONZE_CHAINBODY(BarType.BRONZE, SmithingType.TYPE_CHAINBODY, 1103, 11), + + /** + * Bronze KitShield + */ + BRONZE_KITESHIELD(BarType.BRONZE, SmithingType.TYPE_KITE_SHIELD, 1189, 12), + + /** + * Bronze Claws + */ + BRONZE_CLAWS(BarType.BRONZE, SmithingType.TYPE_CLAWS, 3095, 13), + + /** + * Bronze 2h + */ + BRONZE_TWO_HANDED(BarType.BRONZE, SmithingType.TYPE_TWO_HAND_SWORD, 1307, 14), + + /** + * Bronze PlateSkirt + */ + BRONZE_PLATE_SKIRT(BarType.BRONZE, SmithingType.TYPE_PLATE_SKIRT, 1087, 16), + + /** + * Bronze PlateLegs + */ + BRONZE_PLATELEGS(BarType.BRONZE, SmithingType.TYPE_PLATELEG, 1075, 16), + + /** + * Bronze PlateBody + */ + BRONZE_PLATEBODY(BarType.BRONZE, SmithingType.TYPE_PLATEBODY, 1117, 18), + + /** + * Bronze Pickaxe + */ + BRONZE_PICKAXE(BarType.BRONZE, SmithingType.TYPE_PICKAXE, 1265, 5), + + /** + * Iron Dagger + */ + IRON_DAGGER(BarType.IRON, SmithingType.TYPE_DAGGER, 1203, 15), + + /** + * Iron Hatchet + */ + IRON_AXE(BarType.IRON, SmithingType.TYPE_AXE, 1349, 16), + + /** + * Iron Mace + */ + IRON_MACE(BarType.IRON, SmithingType.TYPE_MACE, 1420, 17), + + /** + * Iron Med Helm + */ + IRON_MED_HELM(BarType.IRON, SmithingType.TYPE_MEDIUM_HELM, 1137, 18), + + /** + * Iron Bolt + */ + IRON_BOLT(BarType.IRON, SmithingType.TYPE_CROSSBOW_BOLT, 9377, 18), + + /** + * Iron Sword + */ + IRON_SWORD(BarType.IRON, SmithingType.TYPE_SWORD, 1279, 19), + + /** + * Iron Dart Tips + */ + IRON_DART_TIPS(BarType.IRON, SmithingType.TYPE_DART_TIP, 820, 19), + + /** + * Iron Nails + */ + IRON_NAILS(BarType.IRON, SmithingType.TYPE_NAIL, 4820, 19), + + /** + * Iron Split + */ + IRON_SPIT(BarType.IRON, SmithingType.TYPE_SPIT_IRON, 7225, 16), + + /** + * Iron Arrow Tips + */ + IRON_ARROW_TIPS(BarType.IRON, SmithingType.TYPE_ARROW_TIP, 40, 20), + + /** + * Iron Scimitar + */ + IRON_SCIMITAR(BarType.IRON, SmithingType.TYPE_SCIMITAR, 1323, 20), + + /** + * Iron Crossbow Limbs + */ + IRON_CROSSBOW_LimbS(BarType.IRON, SmithingType.TYPE_CROSSBOW_LIMB, 9423, 23), + + /** + * Iron LongSword + */ + IRON_LONGSWORD(BarType.IRON, SmithingType.TYPE_LONGSWORD, 1293, 21), + + /** + * Iron Knife + */ + IRON_KNIFE(BarType.IRON, SmithingType.TYPE_THROWING_KNIFE, 863, 22), + + /** + * Iron Full Helm + */ + IRON_FULL_HELM(BarType.IRON, SmithingType.TYPE_FULL_HELM, 1153, 22), + + /** + * Iron Square Shield + */ + IRON_SQUARE_SHIELD(BarType.IRON, SmithingType.TYPE_SQUARE_SHIELD, 1175, 23), + + /** + * Oil Lantern Frame + */ + OIL_LANTERN_FRAME(BarType.IRON, SmithingType.TYPE_OIL_LANTERN, 4540, 26), + /** + * Iron WarHammer + */ + IRON_WARHAMMER(BarType.IRON, SmithingType.TYPE_WARHAMMER, 1335, 24), + + /** + * Iron Battleaxe + */ + IRON_BATTLEAXE(BarType.IRON, SmithingType.TYPE_BATTLE_AXE, 1363, 25), + + /** + * Iron ChainBody + */ + IRON_CHAINBODY(BarType.IRON, SmithingType.TYPE_CHAINBODY, 1101, 26), + + /** + * Iron Kite Shield + */ + IRON_KITE_SHIELD(BarType.IRON, SmithingType.TYPE_KITE_SHIELD, 1191, 27), + + /** + * Iron Claws + */ + IRON_CLAWS(BarType.IRON, SmithingType.TYPE_CLAWS, 3096, 28), + + /** + * Iron 2H + */ + IRON_TWO_HANDED_SWORD(BarType.IRON, SmithingType.TYPE_TWO_HAND_SWORD, 1309, 29), + + /** + * Iron PlateSkirt + */ + IRON_PLATESKIRT(BarType.IRON, SmithingType.TYPE_PLATE_SKIRT, 1081, 31), + + /** + * Iron PlateLegs + */ + IRON_PLATELEGS(BarType.IRON, SmithingType.TYPE_PLATELEG, 1067, 31), + + /** + * Iron PlateBody + */ + IRON_PLATEBODY(BarType.IRON, SmithingType.TYPE_PLATEBODY, 1115, 33), + + /** + * Iron PickAxe + */ + IRON_PICKAXE(BarType.IRON, SmithingType.TYPE_PICKAXE, 1267, 20), + + /** + * Steel Dagger + */ + STEEL_DAGGER(BarType.STEEL, SmithingType.TYPE_DAGGER, 1207, 30), + + /** + * Steel Axe + */ + STEEL_AXE(BarType.STEEL, SmithingType.TYPE_AXE, 1353, 31), + + /** + * Steel Mace + */ + STEEL_MACE(BarType.STEEL, SmithingType.TYPE_MACE, 1424, 32), + + /** + * Steel Medium Helm + */ + STEEL_MED_HELM(BarType.STEEL, SmithingType.TYPE_MEDIUM_HELM, 1141, 33), + + /** + * Steel CrossBow bolts + */ + STEEL_CROSSBOW_BOLT(BarType.STEEL, SmithingType.TYPE_CROSSBOW_BOLT, 9378, 33), + + /** + * Steel Sword + */ + STEEL_SWORD(BarType.STEEL, SmithingType.TYPE_SWORD, 1281, 34), + + /** + * Steel Dart Tips + */ + STEEL_DART_TIPS(BarType.STEEL, SmithingType.TYPE_DART_TIP, 821, 34), + + /** + * Steel Nails + */ + STEEL_NAILS(BarType.STEEL, SmithingType.TYPE_NAIL, 1539, 34), + + /** + * Steel ArrowTips + */ + STEEL_ARROW_TIPS(BarType.STEEL, SmithingType.TYPE_ARROW_TIP, 41, 35), + + /** + * Steel Scimitar + */ + STEEL_SCIMITAR(BarType.STEEL, SmithingType.TYPE_SCIMITAR, 1325, 35), + + /** + * Steel Crossbow Limbs + */ + STEEL_CROSSBOW_LIMBS(BarType.STEEL, SmithingType.TYPE_CROSSBOW_LIMB, 9425, 36), + + /** + * Steel LongSword + */ + STEEL_LONGSWORD(BarType.STEEL, SmithingType.TYPE_LONGSWORD, 1295, 36), + + /** + * Steel Knife + */ + STEEL_THROWING_KNIFE(BarType.STEEL, SmithingType.TYPE_THROWING_KNIFE, 865, 37), + + /** + * Steel Full Helm + */ + STEEL_FULL_HELM(BarType.STEEL, SmithingType.TYPE_FULL_HELM, 1157, 37), + + /** + * Steel Studs + */ + STEEL_STUDS(BarType.STEEL, SmithingType.TYPE_STUDS, 2370, 36), + + /** + * Steel Square Shield + */ + STEEL_SQUARE_SHIELD(BarType.STEEL, SmithingType.TYPE_SQUARE_SHIELD, 1177, 38), + + /** + * Steel Lantern + */ + STEEL_BULLSEYE(BarType.STEEL, SmithingType.TYPE_BULLSEYE, 4544, 49), + + /** + * Steel WarHammer + */ + STEEL_WARHAMMER(BarType.STEEL, SmithingType.TYPE_WARHAMMER, 1339, 39), + + /** + * Steel battle axe + */ + STEEL_BATTLE_AXE(BarType.STEEL, SmithingType.TYPE_BATTLE_AXE, 1365, 40), + + /** + * Steel ChainBody + */ + STEEL_CHAINBODY(BarType.STEEL, SmithingType.TYPE_CHAINBODY, 1105, 41), + + /** + * Steel Kite Shield + */ + STEEL_KITE_SHIELD(BarType.STEEL, SmithingType.TYPE_KITE_SHIELD, 1193, 42), + + /** + * Steel Claws + */ + STEEL_CLAWS(BarType.STEEL, SmithingType.TYPE_CLAWS, 3097, 43), + + /** + * Steel 2h + */ + STEEL_TWO_HANDED_SWORD(BarType.STEEL, SmithingType.TYPE_TWO_HAND_SWORD, 1311, 44), + + /** + * Steel plate skirt + */ + STEEL_PLATE_SKIRT(BarType.STEEL, SmithingType.TYPE_PLATE_SKIRT, 1083, 46), + + /** + * Steel platelegs + */ + STEEL_PLATELEGS(BarType.STEEL, SmithingType.TYPE_PLATELEG, 1069, 46), + + /** + * Steel platebody + */ + STEEL_PLATEBODY(BarType.STEEL, SmithingType.TYPE_PLATEBODY, 1119, 48), + + /** + * Steel pickaxe + */ + STEEL_PICKAXE(BarType.STEEL, SmithingType.TYPE_PICKAXE, 1269, 35), + + /** + * Mithril Dagger + */ + MITHRIL_DAGGER(BarType.MITHRIL, SmithingType.TYPE_DAGGER, 1209, 50), + + /** + * Mithril Hatchet + */ + MITHRIL_HATCHET(BarType.MITHRIL, SmithingType.TYPE_AXE, 1355, 51), + + /** + * Mithril Mace + */ + MITHRIL_MACE(BarType.MITHRIL, SmithingType.TYPE_MACE, 1428, 52), + + /** + * Mithril Med Helm + */ + MITHRIL_MED_HELM(BarType.MITHRIL, SmithingType.TYPE_MEDIUM_HELM, 1143, 53), + + /** + * Mithril Crossbow Bolt + */ + MITHRIL_CROSSBOW_BOLT(BarType.MITHRIL, SmithingType.TYPE_CROSSBOW_BOLT, 9379, 53), + + /** + * Mithril Sword + */ + MITHRIL_SWORD(BarType.MITHRIL, SmithingType.TYPE_SWORD, 1285, 54), + + /** + * Mithril Dart Tips + */ + MITHRIL_DART_TIPS(BarType.MITHRIL, SmithingType.TYPE_DART_TIP, 822, 54), + + /** + * Mithril Nails + */ + MITHRIL_NAILS(BarType.MITHRIL, SmithingType.TYPE_NAIL, 4822, 54), + + /** + * Mithril Arrow Tips + */ + MITHRIL_ARROW_TIPS(BarType.MITHRIL, SmithingType.TYPE_ARROW_TIP, 42, 55), + + /** + * Mithril Scimitar + */ + MITHRIL_SCIMITAR(BarType.MITHRIL, SmithingType.TYPE_SCIMITAR, 1329, 55), + + /** + * Mithril Crossbow Limbs + */ + MITHRIL_CROSSBOW_LIMBS(BarType.MITHRIL, SmithingType.TYPE_CROSSBOW_LIMB, 9427, 56), + + /** + * Mithril LongSword + */ + MITHRIL_LONGSWORD(BarType.MITHRIL, SmithingType.TYPE_LONGSWORD, 1299, 56), + + /** + * Mithril Knife + */ + MITHRIL_KNIFE(BarType.MITHRIL, SmithingType.TYPE_THROWING_KNIFE, 866, 57), + + /** + * Mithril Full Helm + */ + MITHRIL_FULL_HELM(BarType.MITHRIL, SmithingType.TYPE_FULL_HELM, 1159, 57), + + /** + * Mithril SquareShield + */ + MITHRIL_SQUARE_SHIELD(BarType.MITHRIL, SmithingType.TYPE_SQUARE_SHIELD, 1181, 58), + + /** + * Mithril Grapple Tips + */ + MITHRIL_GRAPPLE_TIPS(BarType.MITHRIL, SmithingType.TYPE_GRAPPLE_TIP, 9416, 59), + + /** + * Mithril Warhammer + */ + MITHRIL_WARHAMMER(BarType.MITHRIL, SmithingType.TYPE_WARHAMMER, 1343, 59), + + /** + * Mithril BattleAxe + */ + MITHRIL_BATTLEAXE(BarType.MITHRIL, SmithingType.TYPE_BATTLE_AXE, 1369, 60), + + /** + * Mithril ChainBody + */ + MITHRIL_CHAINBODY(BarType.MITHRIL, SmithingType.TYPE_CHAINBODY, 1109, 61), + + /** + * Mithril KiteShield + */ + MITHRIL_KITE_SHIELD(BarType.MITHRIL, SmithingType.TYPE_KITE_SHIELD, 1197, 62), + + /** + * Mithril Claws + */ + MITHRIL_CLAWS(BarType.MITHRIL, SmithingType.TYPE_CLAWS, 3099, 63), + + /** + * Mithril 2H + */ + MITHRIL_TWO_HANDED_SWORD(BarType.MITHRIL, SmithingType.TYPE_TWO_HAND_SWORD, 1315, 64), + + /** + * Mithril PlateSkirt + */ + MITHRIL_PLATESKIRT(BarType.MITHRIL, SmithingType.TYPE_PLATE_SKIRT, 1085, 66), + + /** + * Mithril PlateLegs + */ + MITHRIL_PLATELEGS(BarType.MITHRIL, SmithingType.TYPE_PLATELEG, 1071, 66), + + /** + * Mithril PlateBody + */ + MITHRIL_PLATEBODY(BarType.MITHRIL, SmithingType.TYPE_PLATEBODY, 1121, 68), + + /** + * Mithril PickAxe + */ + MITHRIL_PICKAXE(BarType.MITHRIL, SmithingType.TYPE_PICKAXE, 1273, 55), + + /** + * Adamant Dagger + */ + ADAMANT_DAGGER(BarType.ADAMANT, SmithingType.TYPE_DAGGER, 1211, 70), + + /** + * Adamant Hatchet + */ + ADAMANT_AXE(BarType.ADAMANT, SmithingType.TYPE_AXE, 1357, 71), + + /** + * Adamant Mace + */ + ADAMANT_MACE(BarType.ADAMANT, SmithingType.TYPE_MACE, 1430, 72), + + /** + * Adamant Med Helm + */ + ADAMANT_MEDIUM_HELM(BarType.ADAMANT, SmithingType.TYPE_MEDIUM_HELM, 1145, 73), + + /** + * Adamant Crossbow Bolt + */ + ADAMANT_BOLT(BarType.ADAMANT, SmithingType.TYPE_CROSSBOW_BOLT, 9380, 73), + + /** + * Adamant Sword + */ + ADAMANT_SWORD(BarType.ADAMANT, SmithingType.TYPE_SWORD, 1287, 74), + + /** + * Adamant Dart Tips + */ + ADAMANT_DART_TIPS(BarType.ADAMANT, SmithingType.TYPE_DART_TIP, 823, 74), + + /** + * Adamant Nails + */ + ADAMANT_NAILS(BarType.ADAMANT, SmithingType.TYPE_NAIL, 4823, 74), + + /** + * Adamant Arrow Tips + */ + ADAMANT_ARROW_TIPS(BarType.ADAMANT, SmithingType.TYPE_ARROW_TIP, 43, 75), + + /** + * Adamant Scmitar + */ + ADAMANT_SCIMITAR(BarType.ADAMANT, SmithingType.TYPE_SCIMITAR, 1331, 75), + + /** + * Adamant Crossbow Limbs + */ + ADAMANT_LIMBS(BarType.ADAMANT, SmithingType.TYPE_CROSSBOW_LIMB, 9429, 76), + + /** + * Adamant LongSword + */ + ADAMANT_LONGSWORD(BarType.ADAMANT, SmithingType.TYPE_LONGSWORD, 1301, 76), + + /** + * Adamant Knife + */ + ADAMANT_KNIFE(BarType.ADAMANT, SmithingType.TYPE_THROWING_KNIFE, 867, 77), + + /** + * Adamant Full Helm + */ + ADAMANT_FULL_HELM(BarType.ADAMANT, SmithingType.TYPE_FULL_HELM, 1161, 77), + + /** + * Adamant Square Shield + */ + ADAMANT_SQUARE_SHIELD(BarType.ADAMANT, SmithingType.TYPE_SQUARE_SHIELD, 1183, 78), + + /** + * Adamant Warhammer + */ + ADAMANT_WARHAMMER(BarType.ADAMANT, SmithingType.TYPE_WARHAMMER, 1345, 79), + + /** + * Adamant BattleAxe + */ + ADAMANT_BATTLEAXE(BarType.ADAMANT, SmithingType.TYPE_BATTLE_AXE, 1371, 80), + + /** + * Adamant ChainBody + */ + ADAMANT_CHAINBODY(BarType.ADAMANT, SmithingType.TYPE_CHAINBODY, 1111, 81), + + /** + * Adamant KiteShield + */ + ADAMANT_KITESHIELD(BarType.ADAMANT, SmithingType.TYPE_KITE_SHIELD, 1199, 82), + + /** + * Adamant Claws + */ + ADAMANT_CLAWS(BarType.ADAMANT, SmithingType.TYPE_CLAWS, 3100, 83), + + /** + * Adamant 2H + */ + ADAMANT_TWO_HANDED_SWORD(BarType.ADAMANT, SmithingType.TYPE_TWO_HAND_SWORD, 1317, 84), + + /** + * Adamant PlateSkirt + */ + ADAMANT_PLATE_SKIRT(BarType.ADAMANT, SmithingType.TYPE_PLATE_SKIRT, 1091, 86), + + /** + * Adamant PlateLegs + */ + ADAMANT_PLATE_LEGS(BarType.ADAMANT, SmithingType.TYPE_PLATELEG, 1073, 86), + + /** + * Adamant PlateBody + */ + ADAMANT_PLATE_BODY(BarType.ADAMANT, SmithingType.TYPE_PLATEBODY, 1123, 88), + + /** + * Adamant PickAxe + */ + ADAMANT_PICKAXE(BarType.ADAMANT, SmithingType.TYPE_PICKAXE, 1271, 75), + + /** + * Rune Dagger + */ + RUNE_DAGGER(BarType.RUNITE, SmithingType.TYPE_DAGGER, 1213, 85), + + /** + * Rune Hatchet + */ + RUNITE_AXE(BarType.RUNITE, SmithingType.TYPE_AXE, 1359, 86), + + /** + * Rune Mace + */ + RUNITE_MACE(BarType.RUNITE, SmithingType.TYPE_MACE, 1432, 87), + + /** + * Rune Med Helm + */ + RUNITE_MEDIUM_HELM(BarType.RUNITE, SmithingType.TYPE_MEDIUM_HELM, 1147, 88), + + /** + * Rune Crossbow Bolt + */ + RUNITE_BOLT(BarType.RUNITE, SmithingType.TYPE_CROSSBOW_BOLT, 9381, 88), + + /** + * Rune Sword + */ + RUNITE_SWORD(BarType.RUNITE, SmithingType.TYPE_SWORD, 1289, 89), + + /** + * Rune Dart Tips + */ + RUNITE_DART_TIPS(BarType.RUNITE, SmithingType.TYPE_DART_TIP, 824, 89), + + /** + * Rune Nails + */ + RUNITE_NAILS(BarType.RUNITE, SmithingType.TYPE_NAIL, 4824, 89), + + /** + * Rune Arrow Tips + */ + RUNITE_ARROW_TIPS(BarType.RUNITE, SmithingType.TYPE_ARROW_TIP, 44, 90), + + /** + * Rune Scmitar + */ + RUNITE_SCIMITAR(BarType.RUNITE, SmithingType.TYPE_SCIMITAR, 1333, 90), + + /** + * Rune Crossbow Limbs + */ + RUNITE_LIMBS(BarType.RUNITE, SmithingType.TYPE_CROSSBOW_LIMB, 9431, 91), + + /** + * Rune LongSword + */ + RUNITE_LONGSWORD(BarType.RUNITE, SmithingType.TYPE_LONGSWORD, 1303, 91), + + /** + * Rune Knife + */ + RUNITE_KNIFE(BarType.RUNITE, SmithingType.TYPE_THROWING_KNIFE, 868, 92), + + /** + * Rune Full Helm + */ + RUNITE_FULL_HELM(BarType.RUNITE, SmithingType.TYPE_FULL_HELM, 1163, 92), + + /** + * Rune Square Shield + */ + RUNITE_SQUARE_SHIELD(BarType.RUNITE, SmithingType.TYPE_SQUARE_SHIELD, 1185, 93), + + /** + * Rune Warhammer + */ + RUNITE_WARHAMMER(BarType.RUNITE, SmithingType.TYPE_WARHAMMER, 1347, 94), + + /** + * Rune BattleAxe + */ + RUNITE_BATTLEAXE(BarType.RUNITE, SmithingType.TYPE_BATTLE_AXE, 1373, 95), + + /** + * Rune ChainBody + */ + RUNITE_CHAINBODY(BarType.RUNITE, SmithingType.TYPE_CHAINBODY, 1113, 96), + + /** + * Rune KiteShield + */ + RUNITE_KITESHIELD(BarType.RUNITE, SmithingType.TYPE_KITE_SHIELD, 1201, 97), + + /** + * Rune Claws + */ + RUNITE_CLAWS(BarType.RUNITE, SmithingType.TYPE_CLAWS, 3101, 98), + + /** + * Rune 2H + */ + RUNITE_TWO_HANDED_SWORD(BarType.RUNITE, SmithingType.TYPE_TWO_HAND_SWORD, 1319, 99), + + /** + * Rune PlateSkirt + */ + RUNITE_PLATE_SKIRT(BarType.RUNITE, SmithingType.TYPE_PLATE_SKIRT, 1093, 99), + + /** + * Rune PlateLegs + */ + RUNITE_PLATE_LEGS(BarType.RUNITE, SmithingType.TYPE_PLATELEG, 1079, 99), + + /** + * Rune PlateBody + */ + RUNITE_PLATE_BODY(BarType.RUNITE, SmithingType.TYPE_PLATEBODY, 1127, 99), + + /** + * Rune PickAxe + */ + RUNITE_PICKAXE(BarType.RUNITE, SmithingType.TYPE_PICKAXE, 1275, 90), + + /** + * Blurite CrossBow bolts + */ + BLURITE_CROSSBOW_BOLT(BarType.BLURITE, SmithingType.TYPE_CROSSBOW_BOLT, 9376, 8), + + /** + * Blurite Crossbow Limbs + */ + BLURITE_CROSSBOW_LIMBS(BarType.BLURITE, SmithingType.TYPE_CROSSBOW_LIMB, 9422, 13); + + /** + * A map of object ids to primary ingredients. + */ + private static Map bars = new HashMap(); + + /** + * Gets a bar by an item id. + * @param item The item id. + * @return The bar or null if the object is not a bar. + */ + public static Bars forId(int item) { + for (Bars bar : Bars.values()) { + if (bar.getProduct() == item) { + return bar; + } + } + return null; + } + + /** + * Populates the herb mapping. + */ + static { + for (Bars bar : Bars.values()) { + bars.put((short) bar.getProduct(), bar); + } + } + + private BarType Btype; + private SmithingType Stype; + private int product; + private int level; + + private Bars(BarType Btype, SmithingType Stype, int productId, int level) { + this.Btype = Btype; + this.Stype = Stype; + this.product = productId; + this.level = level; + } + + public BarType getBarType() { + return Btype; + } + + public SmithingType getSmithingType() { + return Stype; + } + + public int getProduct() { + return product; + } + + public int getLevel() { + return level; + } + + public static boolean constructInterface(Player player, int itemId) { + switch (itemId) { + case 2349: + case 2351: + case 2353: + case 2359: + case 2361: + case 2363: + return true; + } + return false; + } + + public static Bars[] getBars(BarType type) { + List bars = new ArrayList(); + for (Bars bar : Bars.values()) { + if (bar.getBarType() == type) { + bars.add(bar); + } + } + Bars[] barss = new Bars[bars.size()]; + for (int i = 0; i < bars.size(); i++) { + barss[i] = bars.get(i); + } + return barss; + } + + public static int getItemId(int buttonId, BarType type) { + for (Bars bar : Bars.values()) { + if (bar.getBarType() != type) { + continue; + } + for (int i : bar.getSmithingType().getButton()) { + if (buttonId == i) { + return bar.getProduct(); + } + } + } + return -1; + } + + public static int getIndex(Player player, int buttonId, BarType type) { + int index = 0; + for (Bars bar : Bars.values()) { + if (bar.getBarType() != type) { + continue; + } + bar = Bars.forId(bar.getProduct()); + for (int i = 0; i < bar.getSmithingType().getButton().length; i++) { + if (buttonId != bar.getSmithingType().getButton()[i]) { + index++; + return index; + } + } + } + return -1; + } +} diff --git a/Server/src/main/content/global/skill/smithing/DragonShieldDialogue.java b/Server/src/main/content/global/skill/smithing/DragonShieldDialogue.java new file mode 100644 index 0000000..6483309 --- /dev/null +++ b/Server/src/main/content/global/skill/smithing/DragonShieldDialogue.java @@ -0,0 +1,105 @@ +package content.global.skill.smithing; + +import content.global.skill.skillcapeperks.SkillcapePerks; +import core.api.Container; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import org.rs09.consts.Items; + +import static core.api.ContentAPIKt.*; + +/** + * Represents the dialogue plugin used for making a dragon shield. + * @author 'Vexia + * @author Player Name + * @version 1.1 + */ +@Initializable +public final class DragonShieldDialogue extends DialoguePlugin { + /** + * Constructs a new {@code DragonShieldDialogue} {@code Object}. + */ + public DragonShieldDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code DragonShieldDialogue} {@code Object}. + * @param player the player. + */ + public DragonShieldDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new DragonShieldDialogue(player); + } + + @Override + public boolean open(Object... args) { + if (!inInventory(player, Items.HAMMER_2347, 1) && !SkillcapePerks.isActive(SkillcapePerks.BAREFISTED_SMITHING, player)) { + interpreter.sendDialogue("You need a hammer to work the metal with."); + } + int type = (int) args[0]; + if (type == 1) { + if (!(inInventory(player, Items.SHIELD_RIGHT_HALF_2368, 1) && inInventory(player, Items.SHIELD_LEFT_HALF_2366, 1))) { + interpreter.sendDialogue("You need the other half of the shield."); //todo authentic message + return false; + } + interpreter.sendDialogue("You set to work trying to fix the ancient shield. It's seen some", "heavy action and needs some serious work doing to it."); + stage = 0; + } else { + if (!inInventory(player, Items.ANTI_DRAGON_SHIELD_1540, 1)) { + interpreter.sendDialogue("You need an anti-dragon shield to attach the visage to."); //todo authentic message + return false; + } + if (!inInventory(player, Items.DRACONIC_VISAGE_11286, 1)) { + interpreter.sendDialogue("You don't have anything you could attach to the shield."); //todo authentic message + return false; + } + interpreter.sendDialogue("You set to work, trying to attach the ancient draconic", "visage to your anti-dragonbreath shield. It's not easy to", "work with the ancient artifact and it takes all of your", "skills as a master smith."); + stage = 10; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + lock(player, 5); + animate(player, 898, false); + if (removeItem(player, Items.SHIELD_RIGHT_HALF_2368, Container.INVENTORY) && removeItem(player, Items.SHIELD_LEFT_HALF_2366, Container.INVENTORY)) { + interpreter.sendDialogue("Even for an experienced armourer it is not an easy task, but", "eventually it is ready. You have restored the dragon square shield to", "its former glory."); + addItem(player, Items.DRAGON_SQ_SHIELD_1187, 1, Container.INVENTORY); + rewardXP(player, Skills.SMITHING, 75); + } + stage = 1; + break; + case 1: + end(); + break; + case 10: + lock(player, 5); + animate(player, 898, false); + if (removeItem(player, Items.ANTI_DRAGON_SHIELD_1540, Container.INVENTORY) && removeItem(player, Items.DRACONIC_VISAGE_11286, Container.INVENTORY)) { + interpreter.sendDialogue("Even for an experienced armourer it is not an easy task, but", "eventually it is ready. You have crafted the", "draconic visage and anti-dragonbreath shield into a", "dragonfire shield."); + addItem(player, Items.DRAGONFIRE_SHIELD_11284, 1, Container.INVENTORY); + rewardXP(player, Skills.SMITHING, 2000); + } + stage = 1; + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 82127843 }; + } +} diff --git a/Server/src/main/content/global/skill/smithing/FurnaceOptionPlugin.java b/Server/src/main/content/global/skill/smithing/FurnaceOptionPlugin.java new file mode 100644 index 0000000..e34e71c --- /dev/null +++ b/Server/src/main/content/global/skill/smithing/FurnaceOptionPlugin.java @@ -0,0 +1,164 @@ +package content.global.skill.smithing; + +import content.global.skill.smithing.smelting.Bar; +import core.cache.def.impl.SceneryDefinition; +import core.game.node.entity.skill.Skills; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.OptionHandler; +import core.game.interaction.UseWithHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; + +import java.util.ArrayList; +import java.util.List; +import content.data.Quests; + +/** + * Represents the plugin used for the furnace. + * @author Vexia + */ +@Initializable +public final class FurnaceOptionPlugin extends OptionHandler { + + /** + * Represents the animation to use. + */ + private static final Animation ANIMATION = new Animation(833); + + /** + * Represents the items used for the tutorial island (ores). + */ + private static final Item[] ITEMS = new Item[] { new Item(438, 1), new Item(436, 1) }; + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.setOptionHandler("smelt", this); + SceneryDefinition.setOptionHandler("smelt-ore", this); + SceneryDefinition.forId(3044).getHandlers().put("option:use", this); + SceneryDefinition.forId(21303).getHandlers().put("option:use", this); + new SmeltUseWithHandler().newInstance(arg); + return this; + } + + @Override + public boolean handle(final Player player, Node node, String option) { + if (node.getId() == 26814 && !player.getAchievementDiaryManager().getDiary(DiaryType.VARROCK).isComplete(0)) { + player.sendMessage("You need to have completed the easy tasks in the Varrock Diary in order to use this."); + return true; + } + show(player); + return true; + } + + /** + * Shows the items. + * @param player the player. + */ + private static void show(final Player player) { + player.getInterfaceManager().openChatbox(311); + player.getPacketDispatch().sendItemZoomOnInterface(2349, 150, 311, 4); + if (player.getQuestRepository().isComplete(Quests.THE_KNIGHTS_SWORD)) { + player.getPacketDispatch().sendString("



Blurite", 311, 20); + } + player.getPacketDispatch().sendItemZoomOnInterface(Bar.BLURITE.getProduct().getId(), 150, 311, 5); + player.getPacketDispatch().sendItemZoomOnInterface(Bar.IRON.getProduct().getId(), 150, 311, 6); + player.getPacketDispatch().sendItemZoomOnInterface(2355, 150, 311, 7); + player.getPacketDispatch().sendItemZoomOnInterface(2353, 150, 311, 8); + player.getPacketDispatch().sendItemZoomOnInterface(2357, 150, 311, 9); + player.getPacketDispatch().sendItemZoomOnInterface(2359, 150, 311, 10); + player.getPacketDispatch().sendItemZoomOnInterface(2361, 150, 311, 11); + player.getPacketDispatch().sendItemZoomOnInterface(2363, 150, 311, 12); + } + + /** + * Method used to handle the tutorial island interaction. + * @param player the player. + */ + private final void handleTutorialIsland(final Player player) { + if (player.getInventory().containItems(438, 436)) { + player.animate(ANIMATION); + GameWorld.getPulser().submit(new Pulse(2, player) { + @Override + public boolean pulse() { + player.getInventory().remove(ITEMS); + player.getInventory().add(Bar.BRONZE.getProduct()); + player.getSkills().addExperience(Skills.SMITHING, Bar.BRONZE.getExperience()); + return true; + } + + }); + } + } + + /** + * Represents the plugin used to handle the ore on the furance. + * @author 'Vexia + * @version 1.0 + */ + public final static class SmeltUseWithHandler extends UseWithHandler { + + /** + * Represents the ids. + */ + public static final int[] furnaceIDS = new int[] { 4304, 6189, 11010, 11666, 12100, 12809, 14921, 18497, 26814, 30021, 30510, 36956, 37651 }; + + /** + * Constructs a new {@code SmeltUseWithHandler} {@code Object}. + */ + public SmeltUseWithHandler() { + super(getIds()); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (int i : furnaceIDS) { + addHandler(i, OBJECT_TYPE, this); + } + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + if (event.getUsedWith().getId() == 26814 && !event.getPlayer().getAchievementDiaryManager().getDiary(DiaryType.VARROCK).isComplete(0)) { + event.getPlayer().sendMessage("You need to have completed the easy tasks in the Varrock Diary in order to use this."); + return true; + } + show(event.getPlayer()); + return true; + } + + /** + * Gets the ore ids. + * @return the ids. + */ + public static final int[] getIds() { + List ids = new ArrayList<>(10); + for (Bar bar : Bar.values()) { + for (Item i : bar.getOres()) { + ids.add(i.getId()); + } + } + int[] array = new int[ids.size()]; + for (int i = 0; i < ids.size(); i++) { + array[i] = ids.get(i); + } + return array; + } + } + + @Override + public Location getDestination(Node node, Node n) { + if (node instanceof Player && ((Player) node).getZoneMonitor().isInZone("Donator Zone")) { + return n.getLocation().transform(1, 2, 0); + } + return null; + } +} diff --git a/Server/src/main/content/global/skill/smithing/SmithingBuilder.java b/Server/src/main/content/global/skill/smithing/SmithingBuilder.java new file mode 100644 index 0000000..6159f16 --- /dev/null +++ b/Server/src/main/content/global/skill/smithing/SmithingBuilder.java @@ -0,0 +1,142 @@ +package content.global.skill.smithing; + +import content.global.skill.smithing.smelting.Bar; +import core.game.component.Component; +import core.game.container.access.InterfaceContainer; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.tools.StringUtils; + +/** + * Represents the builder class to view the correct information, on the + * interface of smithing, ie, the items ammount, and name. + * @author 'Vexia + */ +public final class SmithingBuilder { + + /** + * The bar type. + */ + private BarType type; + + /** + * The bar used. + */ + private Bar bar; + + /** + * Constructs a new {@code SmithingBuilder.java} {@code Object}. + * @param item the item. + */ + public SmithingBuilder(Item item) { + this.bar = Bar.forId(item.getId()); + this.type = BarType.getBarTypeForId(item.getId()); + } + + /** + * Builds the interface of the smithing. + * @param player the player. + */ + public void build(Player player) { + player.getGameAttributes().removeAttribute("smith-type"); + player.getGameAttributes().setAttribute("smith-type", type); + if (type.name().equals("BLURITE")) { + // interface 300 spawns with most things already there. Hide everything except what we want + int[] values = { + 17, // dagger + 25, // axe + 33, // mace + 41, // med helm + // show this 49, // bolts + 57, // sword + 65, // dart tip + 73, // nail + 105, // arrow tip + 113, // scimmy + // show this 121, // limbs + 129, // long sword + 137, // throwing knife + 145, // full helm + 153, // square shield + 177, // warhammer + 185, // battleaxe + 193, // chain body + 201, // kiteshield + 217, // 2h + 225, // plate sk + 233, // plate l + 241, // platebody + }; + for (int childId : values) { + player.getPacketDispatch().sendInterfaceConfig(300, childId, true); + + } + } + else { + player.getPacketDispatch().sendInterfaceConfig(300, 267, false);// pickaxe + } + final Bars bars[] = Bars.getBars(type); + for (int i = 0; i < bars.length; i++) { + if (bars[i].getSmithingType() == SmithingType.TYPE_GRAPPLE_TIP) { + player.getPacketDispatch().sendInterfaceConfig(300, 169, false); + } + if (bars[i].getSmithingType() == SmithingType.TYPE_DART_TIP) { + player.getPacketDispatch().sendInterfaceConfig(300, 65, false); + } + if (bars[i].getSmithingType() == SmithingType.TYPE_WIRE){ + player.getPacketDispatch().sendInterfaceConfig(300, 81, false); + } + if (bars[i].getSmithingType() == SmithingType.TYPE_SPIT_IRON){ + player.getPacketDispatch().sendInterfaceConfig(300, 89, false); + } + if ( bars[i].getSmithingType() == SmithingType.TYPE_BULLSEYE) { + player.getPacketDispatch().sendInterfaceConfig(300, 161, false); + } + if (bars[i].getSmithingType() == SmithingType.TYPE_CLAWS) { + player.getPacketDispatch().sendInterfaceConfig(300, 209, false); + } + if (bars[i].getSmithingType() == SmithingType.TYPE_OIL_LANTERN) { + player.getPacketDispatch().sendInterfaceConfig(300, 161, false); + } + if (bars[i].getSmithingType() == SmithingType.TYPE_STUDS) { + player.getPacketDispatch().sendInterfaceConfig(300, 97, false); + } + String color = ""; + if (player.getSkills().getLevel(Skills.SMITHING) < bars[i].getLevel()) { + } else { + color = ""; + } + player.getPacketDispatch().sendString(color + StringUtils.formatDisplayName(bars[i].getSmithingType().name().replace("TYPE_", "")), 300, bars[i].getSmithingType().getName()); + if (player.getInventory().contains(bars[i].getBarType().getBarType(), bars[i].getSmithingType().getRequired())) { + color = ""; + } else { + color = null; + } + if (color != null) { + String amt = bars[i].getSmithingType().getRequired() > 1 ? "s" : ""; + player.getPacketDispatch().sendString(color + String.valueOf(bars[i].getSmithingType().getRequired()) + " Bar" + amt, 300, bars[i].getSmithingType().getName() + 1); + } + InterfaceContainer.generateItems(player, new Item[] { new Item(bars[i].getProduct(), bars[i].getSmithingType().getProductAmount()) }, new String[] { "" }, 300, bars[i].getSmithingType().getChild() - 1); + } + player.getPacketDispatch().sendString(type.getBarName(), 300, 14); + player.getInterfaceManager().open(new Component(300)); + } + + /** + * Gets the type. + * @return the type. + */ + public BarType getType() { + return type; + } + + /** + * Gets the bar. + * @return the bar. + */ + public Bar getBar() { + return bar; + } + +} diff --git a/Server/src/main/content/global/skill/smithing/SmithingPulse.java b/Server/src/main/content/global/skill/smithing/SmithingPulse.java new file mode 100644 index 0000000..97a844d --- /dev/null +++ b/Server/src/main/content/global/skill/smithing/SmithingPulse.java @@ -0,0 +1,129 @@ +package content.global.skill.smithing; + +import content.global.skill.skillcapeperks.SkillcapePerks; +import core.game.event.ResourceProducedEvent; +import core.cache.def.impl.ItemDefinition; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.entity.skill.SkillPulse; +import core.game.node.entity.skill.Skills; +import core.game.node.item.Item; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.tools.StringUtils; + +import static core.api.ContentAPIKt.hasRequirement; +import static core.api.ContentAPIKt.sendDialogue; +import content.data.Quests; + +/** + * Represents the pulse used to smith a bar. + * + * @author 'Vexia + */ +public class SmithingPulse extends SkillPulse { + + /** + * Represents the animation to use. + */ + private static final Animation ANIMATION = new Animation(898); + + /** + * Represents the bar being made. + */ + private final Bars bar; + + /** + * Represents the amount to make. + */ + private int amount; + + /** + * Constructs a new {@code SmithingPulse} {@code Object}. + * + * @param player the player. + * @param item the item. + */ + public SmithingPulse(Player player, Item item, Bars bar, int amount) { + super(player, item); + this.bar = bar; + this.amount = amount; + } + + @Override + public boolean checkRequirements() { + if (!player.getInventory().contains(bar.getBarType().getBarType(), bar.getSmithingType().getRequired() * amount)) { + amount = player.getInventory().getAmount(new Item(bar.getBarType().getBarType())); + } + player.getInterfaceManager().close(); + if (player.getSkills().getLevel(Skills.SMITHING) < bar.getLevel()) { + player.getDialogueInterpreter().sendDialogue("You need a Smithing level of " + bar.getLevel() + " to make a " + ItemDefinition.forId(bar.getProduct()).getName() + "."); + return false; + } + if (!player.getInventory().contains(bar.getBarType().getBarType(), bar.getSmithingType().getRequired())) { + player.getDialogueInterpreter().sendDialogue("You don't have enough " + ItemDefinition.forId(bar.getBarType().getBarType()).getName().toLowerCase() + "s to make a " + bar.getSmithingType().name().replace("TYPE_", "").replace("_", " ").toLowerCase() + "."); + return false; + } + if (!player.getInventory().contains(2347, 1) && !SkillcapePerks.isActive(SkillcapePerks.BAREFISTED_SMITHING,player)) { + player.getDialogueInterpreter().sendDialogue("You need a hammer to work the metal with."); + return false; + } + if (!player.getQuestRepository().isComplete(Quests.THE_TOURIST_TRAP) && bar.getSmithingType() == SmithingType.TYPE_DART_TIP) { + player.getDialogueInterpreter().sendDialogue("You need to complete Tourist Trap to smith dart tips."); + return false; + } + if (!hasRequirement(player, Quests.DEATH_PLATEAU, false) && bar.getSmithingType() == SmithingType.TYPE_CLAWS) { + sendDialogue(player, "You need to complete Death Plateau to smith claws."); + return false; + } + return true; + } + + @Override + public void animate() { + if(SkillcapePerks.isActive(SkillcapePerks.BAREFISTED_SMITHING,player)){ + player.animate(new Animation(2068)); //Torag's Hammer animation lol + return; + } + player.animate(ANIMATION); + } + + @Override + public boolean reward() { + if (getDelay() == 1) { + setDelay(4); + return false; + } + player.getInventory().remove(new Item(bar.getBarType().getBarType(), bar.getSmithingType().getRequired())); + final Item item = new Item(node.getId(), bar.getSmithingType().getProductAmount()); + player.getInventory().add(item); + player.dispatch(new ResourceProducedEvent(item.getId(), 1, player, bar.getBarType().getBarType())); + player.getSkills().addExperience(Skills.SMITHING, bar.getBarType().getExperience() * bar.getSmithingType().getRequired(), true); + String message = StringUtils.isPlusN(ItemDefinition.forId(bar.getProduct()).getName().toLowerCase()) ? "an" : "a"; + player.getPacketDispatch().sendMessage("You hammer the " + bar.getBarType().getBarName().toLowerCase().replace("smithing", "") + "and make " + message + " " + ItemDefinition.forId(bar.getProduct()).getName().toLowerCase() + "."); + + if (bar == Bars.BLURITE_CROSSBOW_LIMBS + && player.getLocation().withinDistance(new Location(3000, 3145, 0), 10)) { // near Thurgo's anvil + player.getAchievementDiaryManager().finishTask(player, DiaryType.FALADOR, 1, 9); + } + + // Smith a steel longsword on the anvil in the jailhouse

sewers + if (bar == Bars.STEEL_LONGSWORD && player.getLocation().withinDistance(Location.create(3112, 9688, 0))) { + player.getAchievementDiaryManager().finishTask(player, DiaryType.LUMBRIDGE, 2, 0); + } + + // Smith an adamantite medium helm on the south-east anvil in

Varrock, next to Aubury's Rune Shop + if (bar == Bars.ADAMANT_MEDIUM_HELM && player.getLocation().withinDistance(Location.create(3247, 3404, 0))) { + player.getAchievementDiaryManager().finishTask(player, DiaryType.VARROCK, 2, 3); + } + + amount--; + return amount < 1; + } + + @Override + public void message(int type) { + + } + +} diff --git a/Server/src/main/content/global/skill/smithing/SmithingType.java b/Server/src/main/content/global/skill/smithing/SmithingType.java new file mode 100644 index 0000000..fd38a62 --- /dev/null +++ b/Server/src/main/content/global/skill/smithing/SmithingType.java @@ -0,0 +1,250 @@ +package content.global.skill.smithing; + +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +/** + * Represents a type of smithing. + * @author Emperor + */ +public enum SmithingType { + + /** + * Dagger + */ + TYPE_DAGGER(1, 18, 19, new int[] { 24, 23, 22, 21 }, 1), + + /** + * Axe + */ + TYPE_AXE(1, 26, 27, new int[] { 32, 31, 30, 29 }, 1), + + /** + * Mace + */ + TYPE_MACE(1, 34, 35, new int[] { 40, 39, 38, 37 }, 1), + + /** + * Med helm + */ + TYPE_MEDIUM_HELM(1, 42, 43, new int[] { 48, 47, 46, 45 }, 1), + + /** + * Crossbow bolt + */ + TYPE_CROSSBOW_BOLT(1, 50, 51, new int[] { 56, 55, 54, 53 }, 10), + + /** + * Sword + */ + TYPE_SWORD(1, 58, 59, new int[] { 64, 63, 62, 61 }, 1), + + /** + * Dart tips + */ + TYPE_DART_TIP(1, 66, 67, new int[] { 72, 71, 70, 69 }, 10), + + /** + * Nails + */ + TYPE_NAIL(1, 74, 75, new int[] { 80, 79, 78, 77 }, 15), + + /** + * Bullseye + */ + TYPE_BULLSEYE(1, 162, 163, new int[] { 168, 167, 166, 165 }, 1), + + /** + * Spit Iron + */ + TYPE_SPIT_IRON(1, 90, 91, new int[] { 96, 95, 94, 93 }, 1), + /** + * + */ + TYPE_WIRE(1, 82, 83, new int[] { 88, 87, 86, 85 }, 1), + + /** + * Arrow Tips + */ + TYPE_ARROW_TIP(1, 106, 107, new int[] { 112, 111, 110, 109 }, 15), + + /** + * Scimitar + */ + TYPE_SCIMITAR(2, 114, 115, new int[] { 120, 119, 118, 117 }, 1), + + /** + * Crossbow Limbs + */ + TYPE_CROSSBOW_LIMB(1, 122, 123, new int[] { 128, 127, 126, 125 }, 1), + + /** + * LongSword + */ + TYPE_LONGSWORD(2, 130, 131, new int[] { 136, 135, 134, 133 }, 1), + + /** + * Throwing Knife + */ + TYPE_THROWING_KNIFE(1, 138, 139, new int[] { 144, 143, 142, 141 }, 5), + + /** + * Full helm + */ + TYPE_FULL_HELM(2, 146, 147, new int[] { 152, 151, 150, 149 }, 1), + + /** + * Square Shield + */ + TYPE_SQUARE_SHIELD(2, 154, 155, new int[] { 160, 159, 158, 157 }, 1), + + /** + * Oil Lantern + */ + TYPE_OIL_LANTERN(1,162,163,new int[] {168,167,166,165},1), + + /** + * Grapple Tips + */ + TYPE_GRAPPLE_TIP(1, 170, 171, new int[] { 175, 176, 175, 174, 173 }, 1), + + /** + * The studs type. + */ + TYPE_STUDS(1, 98, 99, new int[] { 104, 103, 102, 101, 100 }, 1), + + /** + * Warhammer + */ + TYPE_WARHAMMER(3, 178, 179, new int[] { 184, 183, 182, 181 }, 1), + + /** + * Battle axe + */ + TYPE_BATTLE_AXE(3, 186, 187, new int[] { 192, 191, 190, 189 }, 1), + + /** + * Chainbody + */ + TYPE_CHAINBODY(3, 194, 195, new int[] { 200, 199, 198, 197 }, 1), + + /** + * Kite shield + */ + TYPE_KITE_SHIELD(3, 202, 203, new int[] { 208, 207, 206, 205 }, 1), + + /** + * Claws + */ + TYPE_CLAWS(2, 210, 211, new int[] { 216, 215, 214, 213 }, 1), + + /** + * 2H + */ + TYPE_TWO_HAND_SWORD(3, 218, 219, new int[] { 224, 223, 222, 221 }, 1), + + /** + * Plate Skirt + */ + TYPE_PLATE_SKIRT(3, 226, 227, new int[] { 232, 231, 230, 229 }, 1), + + /** + * Platelegs + */ + TYPE_PLATELEG(3, 234, 235, new int[] { 240, 239, 238, 237 }, 1), + + /** + * Platebody + */ + TYPE_PLATEBODY(5, 242, 243, new int[] { 248, 247, 246, 245 }, 1), + + /** + * Pickaxe + */ + TYPE_PICKAXE(2, 267, 268, new int[] { 273, 272, 271, 270 }, 1); + + private final int name; + + private final int[] button; + + private final int child; + + private final int required; + + private final int product_amount; + + /** + * Constructs a new {@code SmithingType.java} {@code Object}. + * @param requiredBars bars. + * @param interfaceChild the interface child. + * @param nameChild the name child. + * @param buttonId the button id. + * @param productedAmount the producted amount. + */ + SmithingType(int requiredBars, int interfaceChild, int nameChild, int[] buttonId, int productedAmount) { + this.name = nameChild; + this.button = buttonId; + this.child = interfaceChild; + this.required = requiredBars; + this.product_amount = productedAmount; + } + + /** + * @return the name. + */ + public int getName() { + return name; + } + + /** + * @return the button. + */ + public int[] getButton() { + return button; + } + + /** + * @return the child. + */ + public int getChild() { + return child; + } + + /** + * @return the required. + */ + public int getRequired() { + return required; + } + + /** + * @return the product_amount. + */ + public int getProductAmount() { + return product_amount; + } + + public static int forButton(Player player, Bars bar, int button, int item) { + int count = 0; + if (bar == null) { + return -1; + } + for (int i = 0; i < bar.getSmithingType().getButton().length; i++) { + if (bar.getSmithingType().getButton()[i] != button) { + count++; + } else { + if (count == 0) { + count = 1; + } else if (count == 1) { + count = 5; + } else if (count == 2) { + count = -1; + } else if (count == 3) { + count = player.getInventory().getAmount(new Item(item)); + } + return count; + } + } + return -1; + } +} diff --git a/Server/src/main/content/global/skill/smithing/smelting/Bar.java b/Server/src/main/content/global/skill/smithing/smelting/Bar.java new file mode 100644 index 0000000..04177c1 --- /dev/null +++ b/Server/src/main/content/global/skill/smithing/smelting/Bar.java @@ -0,0 +1,103 @@ +package content.global.skill.smithing.smelting; + +import core.game.node.item.Item; + +/** + * Represents the Bar that can be created during a

Smelting

+ * session. + * @author 'Vexia + */ +public enum Bar { + BRONZE(1, 6.2, new Item(2349, 1), new Item(436, 1), new Item(438, 1)), + BLURITE(8, 8, new Item(9467, 1), new Item(668, 1)), + IRON(15, 12.5, new Item(2351, 1), new Item(440)), + SILVER(20, 13.7, new Item(2355, 1), new Item(442, 1)), + STEEL(30, 17.5, new Item(2353, 1), new Item(453, 2), new Item(440, 1)), + GOLD(40, 22.5, new Item(2357, 1), new Item(444, 1)), + MITHRIL(50, 30, new Item(2359, 1), new Item(447, 1), new Item(453, 4)), + ADAMANT(70, 37.5, new Item(2361, 1), new Item(449, 1), new Item(453, 6)), + RUNITE(85, 50, new Item(2363, 1), new Item(451, 1), new Item(453, 8)); + + /** + * The ore required. + */ + private final Item[] ores; + + /** + * The product gained. + */ + private final Item product; + + /** + * The level required. + */ + private final int level; + + /** + * The experience gained. + */ + private final double experience; + + /** + * Constructs a new {@code Bar} {@code Object}. + * @param level the level. + * @param experience the experience. + * @param product the product. + * @param ores the ores. + */ + Bar(int level, double experience, Item product, Item... ores) { + this.level = level; + this.experience = experience; + this.product = product; + this.ores = ores; + } + + public static Bar forId(int id) { + for (Bar bar : Bar.values()) { + if (bar.getProduct().getId() == id) { + return bar; + } + } + return null; + } + + public static Bar forOre(int id) { + for (Bar bar : Bar.values()) { + for (Item i : bar.getOres()) { + if (i.getId() == id) { + return bar; + } + } + } + return null; + } + + /** + * @return the ores. + */ + public Item[] getOres() { + return ores; + } + + /** + * @return the product. + */ + public Item getProduct() { + return product; + } + + /** + * @return the level. + */ + public int getLevel() { + return level; + } + + /** + * @return the experience. + */ + public double getExperience() { + return experience; + } + +} diff --git a/Server/src/main/content/global/skill/smithing/smelting/SmeltingPulse.java b/Server/src/main/content/global/skill/smithing/smelting/SmeltingPulse.java new file mode 100644 index 0000000..5f7876d --- /dev/null +++ b/Server/src/main/content/global/skill/smithing/smelting/SmeltingPulse.java @@ -0,0 +1,208 @@ +package content.global.skill.smithing.smelting; + +import static core.api.ContentAPIKt.*; + +import core.api.Container; +import core.game.event.ResourceProducedEvent; +import core.game.container.impl.EquipmentContainer; +import core.tools.Log; +import org.rs09.consts.Items; +import core.game.world.map.Location; +import core.game.node.entity.skill.SkillPulse; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.tools.RandomFunction; +import core.tools.StringUtils; +import org.rs09.consts.Sounds; +import content.data.Quests; + +/** + * Represents the pulse used to smelt. + * + * @author 'Vexia + */ +public class SmeltingPulse extends SkillPulse { + + /** + * The ring of forging item. + */ + private static final Item RING_OF_FORGING = new Item(2568); + + /** + * Represents the bar to make. + */ + private final Bar bar; + + /** + * Represents if using the super heat spell. + */ + private final boolean superHeat; + + /** + * The ticks passed. + */ + private int ticks; + + /** + * Represents the amount to produce. + */ + private int amount; + + /** + * Constructs a new {@code SmeltingPulse} {@code Object}. + * + * @param player the player. + * @param node the node. + * @param bar the bar. + * @param amount the amount. + */ + public SmeltingPulse(Player player, Item node, Bar bar, int amount) { + super(player, node); + this.bar = bar; + this.amount = amount; + this.superHeat = false; + } + + /** + * Constructs a new {@code SmeltingPulse} {@code Object}. + * + * @param player the player. + * @param node the node. + * @param bar the bar. + * @param amount the amount. + * @param heat the heat. + */ + public SmeltingPulse(Player player, Item node, Bar bar, int amount, boolean heat) { + super(player, node); + this.bar = bar; + this.amount = amount; + this.superHeat = heat; + this.resetAnimation = false; + } + + @Override + public boolean checkRequirements() { + player.getInterfaceManager().closeChatbox(); + if (bar == null || player == null) { + return false; + } + if (bar == Bar.BLURITE && !player.getQuestRepository().isComplete(Quests.THE_KNIGHTS_SWORD)) { + return false; + } + if (player.getSkills().getLevel(Skills.SMITHING) < bar.getLevel()) { + player.getPacketDispatch().sendMessage("You need a Smithing level of at least " + bar.getLevel() + " in order to smelt " + bar.getProduct().getName().toLowerCase().replace("bar", "") + "."); + player.getInterfaceManager().closeChatbox(); + return false; + } + for (Item item : bar.getOres()) { + if (!player.getInventory().contains(item.getId(), item.getAmount())) { + player.getPacketDispatch().sendMessage("You do not have the required ores to make this bar."); + return false; + } + } + return true; + } + + @Override + public void animate() { + if (ticks == 0 || ticks % 5 == 0) { + if (superHeat) { + player.visualize(Animation.create(725), new Graphics(148, 96)); + } else { + player.animate(Animation.create(3243)); // Used to be 899 but that looked wonky and broken + playAudio(player, Sounds.FURNACE_2725); + } + } + } + + @Override + public boolean reward() { + if (!superHeat && ++ticks % 5 != 0) { + return false; + } + if (!superHeat) { + player.getPacketDispatch().sendMessage("You place the required ores and attempt to create a bar of " + StringUtils.formatDisplayName(bar.toString().toLowerCase()) + "."); + } + for (Item i : bar.getOres()) { + if (!player.getInventory().remove(i)) { + return true; + } + } + if (success(player)) { + // Varrock Armour secondary reward + int amt = (player.getInventory().freeSlots() != 0 && !superHeat + && player.getLocation().withinDistance(Location.create(3107, 3500, 0)) // edgeville furnace + && player.getInventory().containsItems(bar.getOres()) + && player.getAchievementDiaryManager().getDiary(DiaryType.VARROCK).getLevel() != -1 + && player.getAchievementDiaryManager().checkSmithReward(bar) + && RandomFunction.random(100) <= 10) ? 2 : 1; + if (amt != 1) { + if (!player.getInventory().remove(bar.getOres())) { + amt = 1; + } else { + player.sendMessage("The magic of the Varrock armour enables you to smelt 2 bars at the same time."); + } + } + player.getInventory().add(new Item(bar.getProduct().getId(), amt)); + player.dispatch(new ResourceProducedEvent(bar.getProduct().getId(), 1, player, -1)); + double xp = bar.getExperience() * amt; + // Goldsmith gauntlets + if (((player.getEquipment().get(EquipmentContainer.SLOT_HANDS) != null + && player.getEquipment().get(EquipmentContainer.SLOT_HANDS).getId() == Items.GOLDSMITH_GAUNTLETS_776)) + && bar.getProduct().getId() == 2357) { + xp = 56.2 * amt; + } + player.getSkills().addExperience(Skills.SMITHING, xp, true); + if (!superHeat) { + player.getPacketDispatch().sendMessage("You retrieve a bar of " + bar.getProduct().getName().toLowerCase().replace(" bar", "") + "."); + } + + // Smelt a steel bar in the Lumbridge furnace + if (bar == Bar.STEEL && player.getLocation().withinDistance(Location.create(3226, 3254, 0))) { + player.getAchievementDiaryManager().finishTask(player, DiaryType.LUMBRIDGE, 1, 5); + } + // Smelt a silver bar in the Lumbridge furnace + if (bar == Bar.SILVER && player.getLocation().withinDistance(Location.create(3226, 3254, 0))) { + player.getAchievementDiaryManager().finishTask(player, DiaryType.LUMBRIDGE, 2, 7); + } + + } else { + player.getPacketDispatch().sendMessage("The ore is too impure and you fail to refine it."); + } + amount--; + return amount < 1; + } + + /** + * Checks if the forging is a succes. + * + * @param player the player. + * @return {@code True} if success. + */ + public boolean success(Player player) { + if (bar == Bar.IRON && !superHeat) { + if (inEquipment(player, Items.RING_OF_FORGING_2568, 1)) { + int charges = getAttribute(player, "ringOfForgingCharges", 140) - 1; + if (charges <= 0) { + if (removeItem(player, Items.RING_OF_FORGING_2568, Container.EQUIPMENT)) { + charges = 140; + sendMessage(player, "Your ring of forging uses up its last charge and disintegrates."); + } else { + log(this.getClass(), Log.ERR, "Failed to delete empty ring of forging for player " + player.getName()); + return false; //unfair but prevents exploit if the impossible happens + } + } + setAttribute(player, "/save:ringOfForgingCharges", charges); + return true; + } else { + return RandomFunction.nextBool(); + } + } + return true; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/CarvedEvilTurnipListener.kt b/Server/src/main/content/global/skill/summoning/CarvedEvilTurnipListener.kt new file mode 100644 index 0000000..c78082f --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/CarvedEvilTurnipListener.kt @@ -0,0 +1,21 @@ +import core.api.* +import org.rs09.consts.Items +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +class CarvedEvilTurnipListener : InteractionListener { + val knife = Items.KNIFE_946 + val evilTurnip = Items.EVIL_TURNIP_12134 + val carvedEvilTurnip = Items.CARVED_EVIL_TURNIP_12153 + + override fun defineListeners() { + onUseWith(IntType.ITEM, evilTurnip, knife) { player, used, with -> + if(removeItem(player, used.asItem())) { + sendMessage(player, "You carve a scary face into the evil turnip.") + sendMessage(player, "Wooo! It's enough to give you nightmares.") + return@onUseWith addItem(player, carvedEvilTurnip) + } + return@onUseWith false + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/summoning/ObeliskOptionPlugin.java b/Server/src/main/content/global/skill/summoning/ObeliskOptionPlugin.java new file mode 100644 index 0000000..3ecea4d --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/ObeliskOptionPlugin.java @@ -0,0 +1,52 @@ +package content.global.skill.summoning; + +import core.game.event.SummoningPointsRechargeEvent; +import core.cache.def.impl.SceneryDefinition; +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Plugin; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playAudio; + +/** + * Represents the option used on the summoning obelisk. + * @author 'Vexia + * @author Emperor + */ +@Initializable +public final class ObeliskOptionPlugin extends OptionHandler { + + @Override + public boolean handle(Player player, Node node, String option) { + switch (option) { + case "infuse-pouch": + SummoningCreator.open(player, true); + return true; + case "renew-points": + if (player.getSkills().getLevel(Skills.SUMMONING) == player.getSkills().getStaticLevel(Skills.SUMMONING)) { + player.getPacketDispatch().sendMessage("You already have full summoning points."); + return true; + } + player.visualize(Animation.create(8502), Graphics.create(1308)); + playAudio(player, Sounds.DREADFOWL_BOOST_4214); + player.getSkills().setLevel(Skills.SUMMONING, player.getSkills().getStaticLevel(Skills.SUMMONING)); + player.dispatch(new SummoningPointsRechargeEvent(node)); + player.getPacketDispatch().sendMessage("You renew your summoning points."); + return true; + } + return false; + } + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.setOptionHandler("infuse-pouch", this); + SceneryDefinition.setOptionHandler("renew-points", this); + return this; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/SummoningCreationPlugin.java b/Server/src/main/content/global/skill/summoning/SummoningCreationPlugin.java new file mode 100644 index 0000000..637b63a --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/SummoningCreationPlugin.java @@ -0,0 +1,113 @@ +package content.global.skill.summoning; + +import static core.api.ContentAPIKt.*; +import core.cache.def.impl.ItemDefinition; +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; +import kotlin.Unit; +import core.plugin.ClassScanner; + +/** + * Represents a component plugin used to handle the summoning creation of a + * node. + * @author 'Vexia + */ +@Initializable +public final class SummoningCreationPlugin extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.put(669, this); + ComponentDefinition.put(673, this); + ClassScanner.definePlugin(new ObeliskHandler()); + return this; + } + + @Override + public boolean handle(Player player, final Component component, int opcode, int button, final int slot, int itemId) { + switch (button) { + case 18: + case 17: + player.getInterfaceManager().close(); + SummoningCreator.configure(player, button == 17); + return true; + } + switch (component.getId()) { + case 669: + case 673: + switch (opcode) { + case 155: + case 196: + case 124: + case 199: + SummoningCreator.create(player, getItemAmount(opcode), component.getId() == 669 ? SummoningPouch.forSlot(slot > 50 ? slot -1 : slot) : SummoningScroll.forId(slot > 50 ? slot -1 : slot)); + break; + case 234: + sendInputDialogue(player, true, "Enter the amount:", (value) -> { + SummoningCreator.create(player, (int) value, component.getId() == 669 ? SummoningPouch.forSlot(slot > 50 ? slot -1 : slot) : SummoningScroll.forId(slot > 50 ? slot -1 : slot)); + return Unit.INSTANCE; + }); + return true; + case 166: + SummoningCreator.list(player, SummoningPouch.forSlot(slot > 50 ? slot -1 : slot)); + break; + } + break; + case 168: + player.getPacketDispatch().sendMessage(ItemDefinition.forId(SummoningScroll.forId(slot > 50 ? slot -1 : slot).getItemId()).getExamine()); + break; + } + return true; + } + + /** + * Method used to get the item amount based on id. + * @param opcode the opcode. + * @return the amount to make. + */ + private final int getItemAmount(final int opcode) { + return opcode == 155 ? 1 : opcode == 196 ? 5 : opcode == 124 ? 10 : opcode == 199 ? 28 : -1; + } + + /** + * Represents the use with handler for an obelisk. + * @author 'Vexia + * @version 1.0 + */ + public static final class ObeliskHandler extends UseWithHandler { + + /** + * Represents the ids of the obelisks. + */ + private static final int[] IDS = new int[] { 28716, 28719, 28722, 28725, 28278, 28731, 28734 }; + + /** + * Constructs a new {@code ObeliskHandler} {@code Object}. + */ + public ObeliskHandler() { + super(12047, 12043, 12059, 12019, 12009, 12778, 12049, 12055, 12808, 2067, 12064, 12091, 12800, 12053, 12065, 12021, 12818, 12781, 12798, 12814, 12073, 12075, 12077, 12079, 12081, 12083, 12087, 12071, 12051, 12095, 12097, 12099, 12101, 12103, 12105, 12107, 12816, 12041, 12061, 12007, 12035, 12027, 12531, 12812, 12784, 12710, 12023, 12085, 12037, 12015, 12045, 12123, 12031, 12029, 12033, 12820, 12057, 12792, 12069, 12011, 12782, 12794, 12013, 12025, 12017, 12039, 12089, 12093, 12802, 12804, 12806, 12788, 12776, 12786, 12796, 12822, 12790); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (int id : IDS) { + addHandler(id, OBJECT_TYPE, this); + } + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + SummoningCreator.open(player, false); + return true; + } + + } +} diff --git a/Server/src/main/content/global/skill/summoning/SummoningCreator.java b/Server/src/main/content/global/skill/summoning/SummoningCreator.java new file mode 100644 index 0000000..d7a2827 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/SummoningCreator.java @@ -0,0 +1,304 @@ +package content.global.skill.summoning; + +import core.cache.def.impl.CS2Mapping; +import core.game.component.Component; +import core.game.node.entity.skill.SkillPulse; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playAudio; + +/** + * Represents a utility class of creating summoning nodes. + * @author Vexia + */ +public final class SummoningCreator { + + /** + * Represents the animation used when creating a node. + */ + private static final Animation ANIMATION = new Animation(9068); + + /** + * Represents the params used for the accessmask on the pouch creating + * interface. + */ + private static final Object[] POUCH_PARAMS = new Object[] { "List", "Infuse-X", "Infuse-All", "Infuse-10", "Infuse-5", "Infuse", 20, 4, 669 << 16 | 15 }; + + /** + * Represents the params used for the accessmask on the scrollc reating + * interface. + */ + private static final Object[] SCROLL_PARAMS = new Object[] { "Transform-X", "Transform-All", "Transform-10", "Transform-5", "Transform", 20, 4, 673 << 16 | 15 }; + + /** + * Represents the summoning component. + */ + private static final Component SUMMONING_COMPONENT = new Component(669); + + /** + * Represents the scroll component. + */ + private static final Component SCROLL_COMPONENT = new Component(673); + + /** + * Method used to open the creation screen. + * @param player the player. + */ + public static final void open(final Player player, final boolean pouch) { + configure(player, pouch); + } + + /** + * Method used to configure a creation interface. + * @param player the player. + * @param pouch the pouch. + */ + public static final void configure(final Player player, final boolean pouch) { + player.getInterfaceManager().open(pouch ? SUMMONING_COMPONENT : SCROLL_COMPONENT); + player.getPacketDispatch().sendRunScript(pouch ? 757 : 765, pouch ? "Iiissssss" : "Iiisssss", pouch ? POUCH_PARAMS : SCROLL_PARAMS); + player.getPacketDispatch().sendIfaceSettings(pouch ? 190 : 126, 15, pouch ? 669 : 673, 0, 78); + } + + /** + * Method used to create a summoning node type. + * @param player the player. + * @param amount the amount. + * @param node the node. + */ + public static void create(final Player player, final int amount, Object node) { + if (node == null) { + return; + } + player.getPulseManager().run(new CreatePulse(player, null, SummoningNode.parse(node), amount)); + } + + /** + * Method used to list the items needed for a pouch. + * @param pouch the pouch. + */ + public static void list(final Player player, final SummoningPouch pouch) { + player.getPacketDispatch().sendMessage((String) CS2Mapping.forId(1186).getMap().get(pouch.getPouchId())); + } + + /** + * Represents the skill pulse used to create a summoning node. + * @author 'Vexia + */ + public static final class CreatePulse extends SkillPulse { + + /** + * Represents the summoning node type. + */ + private final SummoningCreator.SummoningNode type; + + /** + * Represents the object. + */ + private Scenery object; + + /** + * Represents the amount to make. + */ + private int amount; + + /** + * Constructs a new {@code SummoningCreator} {@code Object}. + * @param player the player. + * @param node the node. + * @param type the type. + * @param amount the amount. + */ + public CreatePulse(Player player, Item node, final SummoningCreator.SummoningNode type, final int amount) { + super(player, node); + this.type = type; + this.amount = amount; + this.object = RegionManager.getObject(new Location(2209, 5344, 0)); + + } + + @Override + public boolean checkRequirements() { + player.getInterfaceManager().close(); + if (player.getSkills().getStaticLevel(Skills.SUMMONING) < type.getLevel()) { + player.getPacketDispatch().sendMessage("You need a Summoning level of at least " + type.getLevel() + " in order to do this."); + return false; + } + if (amount == 0) { + player.getPacketDispatch().sendMessage("You don't have the required item(s) to make this."); + return false; + } + for (Item i : type.getRequired()) { + if (!player.getInventory().containsItem(i)) { + player.getPacketDispatch().sendMessage("You don't have the required item(s) to make this."); + return false; + } + } + return true; + } + + @Override + public void animate() { + player.lock(3); + player.animate(ANIMATION); + } + + @Override + public void stop() { + super.stop(); + player.getPacketDispatch().sendSceneryAnimation(object, new Animation(8510)); + } + + @Override + public boolean reward() { + if (getDelay() == 1) { + setDelay(4); + player.getPacketDispatch().sendSceneryAnimation(object, Animation.create(8509)); + playAudio(player, Sounds.CRAFT_POUCH_4164); // 4277 also sounds the same + return false; + } + player.getPacketDispatch().sendSceneryAnimation(object, Animation.create(8510)); + for (int i = 0; i < amount; i++) { + for (Item item : type.getRequired()) { + if (!player.getInventory().containsItem(item)) { + return true; + } + } + if (player.getInventory().remove(type.getRequired())) { + final Item item = type.getProduct(); + player.getInventory().add(item); + player.getSkills().addExperience(Skills.SUMMONING, type.getExperience(), true); + } + } + return true; + } + + } + + /** + * Represents a summoning node type. + * @author 'Vexia + */ + public static class SummoningNode { + + /** + * Represents the base object. + */ + private final Object base; + + /** + * Represents the required items. + */ + private final Item[] required; + + /** + * Represents the product. + */ + private final Item product; + + /** + * Represents the experience. + */ + private final double experience; + + /** + * Represents the level. + */ + private final int level; + + /** + * Constructs a new {@code SummoningCreator} {@code Object}. + * @param required the required items. + * @param product the product. + * @param experience the experience. + * @param level the level. + */ + public SummoningNode(final Object base, Item[] required, Item product, double experience, int level) { + this.base = base; + this.required = required; + this.product = product; + this.experience = experience; + this.level = level; + } + + /** + * Gets the required. + * @return The required. + */ + public Item[] getRequired() { + return required; + } + + /** + * Gets the product. + * @return The product. + */ + public Item getProduct() { + return product; + } + + /** + * Gets the experience. + * @return The experience. + */ + public double getExperience() { + return experience; + } + + /** + * Gets the level. + * @return The level. + */ + public int getLevel() { + return level; + } + + /** + * Gets the base. + * @return The base. + */ + public Object getBase() { + return base; + } + + /** + * Method used to check if the base is a pouch. + * @return the pouch. + */ + public boolean isPouch() { + return base instanceof SummoningPouch; + } + + /** + * Method used to parse a summoning node. + * @param node the node. + * @return the summoning node. + */ + public static SummoningNode parse(final Object node) { + final Item[] required = node instanceof SummoningPouch ? ((SummoningPouch) node).getItems() : createList(((SummoningScroll) node).getItems()); + final Item product = node instanceof SummoningPouch ? new Item(((SummoningPouch) node).getPouchId(), 1) : new Item(((SummoningScroll) node).getItemId(), 10); + final int level = node instanceof SummoningPouch ? ((SummoningPouch) node).getLevelRequired() : ((SummoningScroll) node).getLevel(); + final double experience = node instanceof SummoningPouch ? ((SummoningPouch) node).getCreateExperience() : ((SummoningScroll) node).getExperience(); + return new SummoningNode(node, required, product, experience, level); + } + + /** + * Method used to create the list. + * @param ids the ids. + * @return the array of items. + */ + private static final Item[] createList(final int... ids) { + Item[] list = new Item[ids.length]; + for (int i = 0; i < ids.length; i++) { + list[i] = new Item(ids[i], 1); + } + return list; + } + } +} diff --git a/Server/src/main/content/global/skill/summoning/SummoningPouch.java b/Server/src/main/content/global/skill/summoning/SummoningPouch.java new file mode 100644 index 0000000..b916343 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/SummoningPouch.java @@ -0,0 +1,585 @@ +package content.global.skill.summoning; + +import core.game.node.item.Item; + +import java.util.HashMap; +import java.util.Map; + +/** + * Represents a summoning pouch. + * @author Emperor + */ +public enum SummoningPouch { + + /** + * Represents a spirit wolf pouch. + */ + SPIRIT_WOLF_POUCH(0, 12047, 1, 4.8, 6829, 0.1, 1, false, new Item(12158), new Item(12155), new Item(2859), new Item(12183, 7)), + + /** + * Represents a dreadfowl pouch. + */ + DREADFOWL_POUCH(1, 12043, 4, 9.3, 6825, 0.1, 1, false, new Item(12158), new Item(12155), new Item(2138), new Item(12183, 8)), + + /** + * Represents a spirit spider pouch. + */ + SPIRIT_SPIDER_POUCH(2, 12059, 10, 12.6, 6841, 0.2, 2, false, new Item(12158), new Item(12155), new Item(6291), new Item(12183, 8)), + + /** + * Represents a thorny snail pouch. + */ + THORNY_SNAIL_POUCH(3, 12019, 13, 12.6, 6806, 0.2, 2, false, new Item(12158), new Item(12155), new Item(3363), new Item(12183, 9)), + + /** + * Represents a granite crab pouch. + */ + GRANITE_CRAB_POUCH(4, 12009, 16, 21.6, 6796, 0.2, 2, false, new Item(12158), new Item(12155), new Item(440), new Item(12183, 7)), + + /** + * Represents a spirit mosquito pouch. + */ + SPIRIT_MOSQUITO_POUCH(5, 12778, 17, 46.5, 7331, 0.5, 2, false, new Item(12158), new Item(12155), new Item(6319), new Item(12183, 1)), + + /** + * Represents a desrrt wyrm pouch. + */ + DESERT_WYRM_POUCH(6, 12049, 18, 31.2, 6831, 0.4, 1, false, new Item(12159), new Item(12155), new Item(1783), new Item(12183, 45)), + + /** + * Represents a spirit scorpion pouch. + */ + SPIRIT_SCORPION_POUCH(7, 12055, 19, 83.2, 6837, 0.9, 2, false, new Item(12160), new Item(12155), new Item(3095), new Item(12183, 57)), + + /** + * Represents a spirit tz-kih pouch. + */ + SPIRIT_TZ_KIH_POUCH(8, 12808, 22, 96.8, 7361, 1.1, 3, false, new Item(12160), new Item(12168), new Item(12155), new Item(12183, 64)), + + /** + * Represents an albino rat pouch. + */ + ALBINO_RAT_POUCH(9, 12067, 23, 202.4, 6847, 2.3, 1, false, new Item(12163), new Item(12155), new Item(2134), new Item(12183, 75)), + + /** + * Represents a spirit kalphite pouch. + */ + SPIRIT_KALPHITE_POUCH(10, 12063, 25, 220, 6994, 2.5, 3,false, new Item(12163), new Item(12155), new Item(3138), new Item(12183, 51)), + + /** + * Represents a compost mound pouch. + */ + COMPOST_MOUND_POUCH(11, 12091, 28, 49.8, 6871, 0.6, 6, false, new Item(12159), new Item(12155), new Item(6032), new Item(12183, 47)), + + /** + * Represents a giant chinchompa pouch. + */ + GIANT_CHINCHOMPA_POUCH(12, 12800, 29, 255.2, 7353, 2.9, 1, false, new Item(12163), new Item(12155), new Item(10033), new Item(12183, 84)), + + /** + * Represents a vampire bat pouch. + */ + VAMPIRE_BAT_POUCH(13, 12053, 31, 136, 6835, 1.5, 4, false, new Item(12160), new Item(12155), new Item(3325), new Item(12183, 81)), + + /** + * Represents a honey badger pouch. + */ + HONEY_BADGER_POUCH(14, 12065, 32, 140.8, 6845, 1.6, 4, false, new Item(12160), new Item(12155), new Item(12156), new Item(12183, 84)), + + /** + * Represents a beaver pouch. + */ + BEAVER_POUCH(15, 12021, 33, 57.6, 6808, 0.7, 4, true, new Item(12159), new Item(12155), new Item(1519), new Item(12183, 72)), + + /** + * Represents a void ravager pouch. + */ + VOID_RAVAGER_POUCH(16, 12818, 34, 59.6, 7370, 0.7, 4, false, new Item(12159), new Item(12164), new Item(12155), new Item(12183, 74)), + + /** + * Represents a void spinner pouch. + */ + VOID_SPINNER_POUCH(17, 12780, 34, 59.6, 7333, 0.7, 4, true, new Item(12163), new Item(12166), new Item(12155), new Item(12183, 74)), + + /** + * Represents a void torcher pouch. + */ + VOID_TORCHER_POUCH(18, 12798, 34, 59.6, 7351, 0.7, 4, false, new Item(12163), new Item(12167), new Item(12155), new Item(12183, 74)), + + /** + * Represents a void shifter pouch. + */ + VOID_SHIFTER_POUCH(19, 12814, 34, 59.6, 7367, 0.7, 4, false, new Item(12163), new Item(12165), new Item(12155), new Item(12183, 74)), + + /** + * Represents a bronze minotaur pouch. + */ + BRONZE_MINOTAUR_POUCH(64, 12073, 36, 316.8, 6853, 3.6, 3, false, new Item(12163), new Item(12155), new Item(2349), new Item(12183, 102)), + + /** + * Represents an iron minotaur pouch. + */ + IRON_MINOTAUR_POUCH(65, 12075, 46, 404.8, 6855, 4.6, 9, false, new Item(12163), new Item(12155), new Item(2351), new Item(12183, 125)), + + /** + * Represents a steel minotaur pouch. + */ + STEEL_MINOTAUR_POUCH(66, 12077, 56, 492.8, 6857, 5.6, 9, false, new Item(12163), new Item(12155), new Item(2353), new Item(12183, 141)), + + /** + * Represents a mithril minotaur pouch. + */ + MITHRIL_MINOTAUR_POUCH(67, 12079, 66, 580.8, 6859, 6.6, 9,false, new Item(12163), new Item(12155), new Item(2359), new Item(12183, 152)), + + /** + * Represents an adamant minotaur pouch. + */ + ADAMANT_MINOTAUR_POUCH(68, 12081, 76, 668.8, 6861, 7.6, 9, false, new Item(12163), new Item(12155), new Item(2361), new Item(12183, 144)), + + /** + * Represents a rune minotaur pouch. + */ + RUNE_MINOTAUR_POUCH(69, 12083, 86, 756.8, 6863, 8.6, 9, false, new Item(12163), new Item(12155), new Item(2363), new Item(12183, 1)), + + /** + * Represents a bull ant pouch. + */ + BULL_ANT_POUCH(20, 12087, 40, 52.8, 6867, 0.6, 5, false, new Item(12158), new Item(12155), new Item(6010), new Item(12183, 11)), + + /** + * Represents a macaw pouch. + */ + MACAW_POUCH(21, 12071, 41, 72.4, 6851, 0.8, 5, true, new Item(12159), new Item(12155), new Item(249), new Item(12183, 78)), + + /** + * Represents an evil turnip pouch. + */ + EVIL_TURNIP_POUCH(22, 12051, 42, 184.8, 6833, 2.1, 5, false, new Item(12160), new Item(12155), new Item(12153), new Item(12183, 104)), + + /** + * Represents a spirit cockatrice pouch. + */ + SPIRIT_COCKATRICE_POUCH(23, 12095, 43, 75.2, 6875, 0.9, 5, false, new Item(12159), new Item(12155), new Item(12109), new Item(12183, 88)), + + /** + * Represents a spirit guthatrice pouch. + */ + SPIRIT_GUTHATRICE_POUCH(24, 12097, 43, 75.2, 6877, 0.9, 5, false, new Item(12159), new Item(12155), new Item(12111), new Item(12183, 88)), + + /** + * Represents a spirit saratrice pouch. + */ + SPIRIT_SARATRICE_POUCH(25, 12099, 43, 75.2, 6879, 0.9, 5, false, new Item(12159), new Item(12155), new Item(12113), new Item(12183, 88)), + + /** + * Represents a spirit zamatrice pouch. + */ + SPIRIT_ZAMATRICE_POUCH(26, 12101, 43, 75.2, 6881, 0.9, 5, false, new Item(12159), new Item(12155), new Item(12115), new Item(12183, 88)), + + /** + * Represents a spirit pengatrice pouch. + */ + SPIRIT_PENGATRICE_POUCH(27, 12103, 43, 75.2, 6883, 0.9, 5, false, new Item(12159), new Item(12155), new Item(12117), new Item(12183, 88)), + + /** + * Represents a coraxatrice pouch. + */ + SPIRIT_CORAXATRICE_POUCH(28, 12105, 43, 75.2, 6885, 0.9, 5, false, new Item(12159), new Item(12155), new Item(12119), new Item(12183, 88)), + + /** + * Represents a vulatrice pouch. + */ + SPIRIT_VULATRICE(29, 12107, 43, 75.2, 6887, 0.9, 5, false, new Item(12159), new Item(12155), new Item(12121), new Item(12183, 88)), + + /** + * Represents a pyrelord pouch. + */ + PYRELORD_POUCH(30, 12816, 46, 202.4, 7377, 2.3, 5, false, new Item(12160), new Item(12155), new Item(590), new Item(12183, 111)), + + /** + * Represents a magpie pouch. + */ + MAGPIE_POUCH(31, 12041, 47, 83.2, 6824, 0.9, 5, true, new Item(12159), new Item(12155), new Item(1635), new Item(12183, 88)), + + /** + * Represents a bloated leech pouch. + */ + BLOATED_LEECH_POUCH(32, 12061, 49, 215.2, 6843, 2.4, 5, false, new Item(12160), new Item(12155), new Item(2132), new Item(12183, 117)), + + /** + * Represents a spirit terrorbird pouch. + */ + SPIRIT_TERRORBIRD_POUCH(33, 12007, 52, 68.4, 6794, 0.8, 6, true, new Item(12158), new Item(12155), new Item(9978), new Item(12183, 12)), + + /** + * Represents an abyssal parasite pouch. + */ + ABYSSAL_PARASITE_POUCH(34, true,12035, 54, 94.8, 6818, 1.1, 6, false, new Item(12159), new Item(12155), new Item(12161), new Item(12183, 106)), + + /** + * Represents a spirit jelly pouch. + */ + SPIRIT_JELLY_POUCH(35, 12027, 55, 484, 6992, 5.5, 6, false, new Item(12163), new Item(12155), new Item(1937), new Item(12183, 151)), + + /** + * Represents an ibis pouch. + */ + IBIS_POUCH(36, 12531, 56, 98.8, 6991, 1.1, 6, true, new Item(12159), new Item(12155), new Item(311), new Item(12183, 109)), + + /** + * Represents a spirit kyatt pouch. + */ + SPIRIT_KYATT_POUCH(37, 12812, 57, 501.6, 7365, 5.7, 6, false, new Item(12163), new Item(12155), new Item(10103), new Item(12183, 153)), + + /** + * Represents a spirit larupia pouch. + */ + SPIRIT_LARUPIA_POUCH(38, 12784, 57, 501.6, 7337, 5.7, 6, false, new Item(12163), new Item(12155), new Item(10095), new Item(12183, 155)), + + /** + * Represents a spirit graahk pouch. + */ + SPIRIT_GRAAHK_POUCH(39, 12810, 57, 501.6, 7363, 5.7, 6, false, new Item(12163), new Item(12155), new Item(10099), new Item(12183, 154)), + + /** + * Represents a karamthulhu overlord pouch. + */ + KARAMTHULHU_POUCH(40, 12023, 58, 510.4, 6809, 5.8, 6, false, new Item(12163), new Item(12155), new Item(6667), new Item(12183, 144)), + + /** + * Represents a smoke devil pouch. + */ + SMOKE_DEVIL_POUCH(41, 12085, 61, 268, 6865, 3, 7, false, new Item(12160), new Item(12155), new Item(9736), new Item(12183, 141)), + + /** + * Represents an abyssal lurker pouch. + */ + ABYSSAL_LUKRER(42, true,12037, 62, 109.6, 6820, 1.9, 9, false, new Item(12159), new Item(12155), new Item(12161), new Item(12183, 119)), + + /** + * Represents a spirit cobra pouch. + */ + SPIRIT_COBRA_POUCH(43, 12015, 63, 276.8, 6802, 3.1, 6, false, new Item(12160), new Item(12155), new Item(6287), new Item(12183, 116)), + + /** + * Represents a stranger plant pouch. + */ + STRANGER_PLANT_POUCH(44, 12045, 64, 281.6, 6827, 3.2, 6, false, new Item(12160), new Item(12155), new Item(8431), new Item(12183, 128)), + + /** + * Represents a barker toad pouch. + */ + BARKER_TOAD_POUCH(45, 12123, 66, 87, 6889, 1, 7, false, new Item(12158), new Item(12155), new Item(2150), new Item(12183, 11)), + + /** + * Represents a war tortoise pouch. + */ + WAR_TORTOISE_POUCH(46, 12031, 67, 58.6, 6815, 0.7, 7, true, new Item(12158), new Item(12155), new Item(7939), new Item(12183, 1)), + + /** + * Represents a bunyip pouch. + */ + BUNYIP_POUCH(47, 12029, 68, 119.2, 6813, 1.4, 7, true, new Item(12159), new Item(12155), new Item(383), new Item(12183, 110)), + + /** + * Represents a fruit bat pouch. + */ + FRUIT_BAT_POUCH(48, 12033, 69, 121.2, 6817, 1.4, 8, true, new Item(12159), new Item(12155), new Item(1963), new Item(12183, 130)), + + /** + * Represents a ravenous locust pouch. + */ + RAVENOUS_LOCUST_POUCH(49, 12820, 70, 132, 7372, 1.5, 4, false, new Item(12160), new Item(12155), new Item(1933), new Item(12183, 79)), + + /** + * Represents an arctic bear pouch. + */ + ARCTIC_BEAR_POUCH(50, 12057, 71, 93.2, 6839, 1.1, 8, false, new Item(12158), new Item(12155), new Item(10117), new Item(12183, 14)), + + /** + * Represents a Phoenix + */ + PHOENIX_POUCH(50, 14623, 72, 93.2, 8575, 1.1, 8, false, new Item(12160, 1), new Item(12183, 165), new Item(12155, 1), new Item(14616, 1)), + + /** + * Represents an obsidian golem pouch. + */ + OBSIDIAN_GOLEM_POUCH(51, 12792, 73, 642.4, 7345, 7.3, 8, false, new Item(12163), new Item(12155), new Item(12168), new Item(12183, 195)), + + /** + * Represents a granite lobster pouch. + */ + GRANITE_LOBSTER_POUCH(52, 12069, 74, 325.6, 6849, 3.7, 8, false, new Item(12160), new Item(12155), new Item(6979), new Item(12183, 166)), + + /** + * Represents a praying mantis pouch. + */ + PRAYING_MANTIS_POUCH(53, 12011, 75, 329.6, 6798, 3.6, 8, false, new Item(12160), new Item(12155), new Item(2460), new Item(12183, 168)), + + /** + * Represents a forge regent pouch. + */ + FORGE_REGENT_BEAST(54, 12782, 76, 134, 7335, 1.5, 9, false, new Item(12159), new Item(12155), new Item(10020), new Item(12183, 141)), + + /** + * Represents a talon beast pouch. + */ + TALON_BEAST_POUCH(55, 12794, 77, 1015.2, 7347, 3.8, 9, false, new Item(12160), new Item(12155), new Item(12162), new Item(12183, 174)), + + /** + * Represents a giant ent pouch. + */ + GIANT_ENT_POUCH(56, 12013, 78, 136.8, 6800, 1.6, 8, false, new Item(12159), new Item(5933), new Item(12155), new Item(12183, 124)), + + /** + * Represents a hydra pouch. + */ + HYDRA_POUCH(60, 12025, 80, 140.8, 6811, 1.6, 9, false, new Item(12159), new Item(571), new Item(12155), new Item(12183, 128)), + + /** + * Represents a spirit dagannoth pouch. + */ + SPIRIT_DAGANNOTH_POUCH(61, 12017, 83, 364.8, 6804, 4.1, 9, false, new Item(12160), new Item(6155), new Item(12155), new Item(12183, 1)), + + /** + * Represents a unicorn stallion pouch. + */ + UNICORN_STALLION_POUCH(70, 12039, 88, 154.4, 6822, 1.8, 9, true, new Item(12159), new Item(237), new Item(12155), new Item(12183, 140)), + + /** + * Represents a wolpertinger pouch. + */ + WOLPERTINGER_POUCH(72, 12089, 92, 404.8, 6869, 4.5, 10, false, new Item(12160), new Item(2859), new Item(3226), new Item(12155), new Item(12183, 203)), + + /** + * Represents a pack yak pouch. + */ + PACK_YAK_POUCH(75, 12093, 96, 422.4, 6873, 4.8, 10, true, new Item(12160), new Item(10818), new Item(12155), new Item(12183, 211)), + + /** + * Represents a fire titan pouch. + */ + FIRE_TITAN_POUCH(57, 12802, 79, 695.2, 7355, 7.9, 9, false, new Item(12163), new Item(1442), new Item(12155), new Item(12183, 198)), + + /** + * Represents a moss titan pouch. + */ + MOSS_TITAN_POUCH(58, 12804, 79, 695.2, 7357, 7.9, 9, false, new Item(12163), new Item(1440), new Item(12155), new Item(12183, 198)), + + /** + * Represents an ice titan pouch. + */ + ICE_TITAN_POUCH(59, 12806, 79, 695.2, 7359, 7.9, 9, false, new Item(12163), new Item(1438), new Item(1444), new Item(12155), new Item(12183, 198)), + + /** + * Represents a lava titan pouch. + */ + LAVA_TITAN_POUCH(62, 12788, 83, 730.4, 7341, 8.3, 9, false, new Item(12163), new Item(12168), new Item(12155), new Item(12183, 219)), + + /** + * Represents a swamp titan pouch. + */ + SWAMP_TITAN_POUCH(63, 12776, 85, 373.6, 7329, 4.2, 9, false, new Item(12160), new Item(10149), new Item(12155), new Item(12183, 150)), + + /** + * Represents a geyser titan pouch. + */ + GEYSER_TITAN_POUCH(71, 12786, 89, 783.2, 7339, 8.9, 9, false, new Item(12163), new Item(1444), new Item(12155), new Item(12183, 222)), + + /** + * Represents an abyssal titan pouch. + */ + ABYSSAL_TITAN_POUCH(73, true,12796, 93, 163.2, 7349, 1.9, 10, false, new Item(12159), new Item(12161), new Item(12155), new Item(12183, 113)), + + /** + * Represents an iron titan pouch. + */ + IRON_TITAN_POUCH(74, 12822, 95, 417.6, 7375, 4.7, 10, false, new Item(12160), new Item(1115), new Item(12155), new Item(12183, 198)), + + /** + * Represents a steel titan pouch. + */ + STEEL_TITAN_POUCH(76, 12790, 99, 435.2, 7343, 4.9, 10, false, new Item(12160), new Item(1119), new Item(12155), new Item(12183, 178)), + + SACRED_CLAY_POUCH_1(-1, 14422, 1, 0, 8240, 0, 1, false, new Item(14182)), + SACRED_CLAY_POUCH_2(-1, 14424, 20, 0, 8242, 0, 3, false, new Item(14184)), + SACRED_CLAY_POUCH_3(-1, 14426, 40, 0, 8244, 0, 5, false, new Item(14186)), + SACRED_CLAY_POUCH_4(-1, 14428, 60, 0, 8246, 0, 7, false, new Item(14188)), + SACRED_CLAY_POUCH_5(-1, 14430, 80, 0, 8248, 0, 9, false, new Item(14190)); + + /** + * The mapping. + */ + private static final Map POUCHES = new HashMap(); + + /** + * Populate the mapping. + */ + static { + for (SummoningPouch pouch : SummoningPouch.values()) { + POUCHES.put(pouch.pouchId, pouch); + } + } + + /** + * Gets a summoning pouch object from the mapping. + * @param pouchId The pouch item id. + * @return The {@code SummoningPouch} {@code Object},
or {@code null} + * if the pouch didn't exist. + */ + public static SummoningPouch get(int pouchId) { + return POUCHES.get(pouchId); + } + + /** + * The slot id. + */ + private final int slot; + + /** + * The pouch item id. + */ + private final int pouchId; + + /** + * The level required to create this pouch. + */ + private final int levelRequired; + + /** + * The experience gained when creating this pouch. + */ + private final double createExperience; + + /** + * The familiar npc id. + */ + private final int npcId; + + /** + * The experience gained when summoning the familiar. + */ + private final double summonExperience; + + /** + * The summon cost. + */ + private final int summonCost; + + /** + * Is the familiar peaceful + */ + private final boolean peaceful; + + /** + * The items required to create this pouch. + */ + private final Item[] items; + + public boolean abyssal; + + /** + * Constructs a new {@code SummoningPouch} {@code Object}. + * @param pouchId The pouch item id. + * @param levelRequired The level required to create. + * @param createExperience The experience gained when creating a pouch. + * @param npcId The familiar's NPC id. + * @param summonExperience The experience gained when summoning. + * @param summonCost The amount of summoning points to drain when summoned. + * @param peaceful Determines whether the familiar is peaceful and should attack. + * @param items The items required to create this pouch. + */ + private SummoningPouch(int slot, int pouchId, int levelRequired, double createExperience, int npcId, double summonExperience, int summonCost, boolean peaceful, Item... items) { + this.slot = slot; + this.pouchId = pouchId; + this.levelRequired = levelRequired; + this.createExperience = createExperience; + this.npcId = npcId; + this.summonExperience = summonExperience; + this.summonCost = summonCost; + this.peaceful = peaceful; + this.items = items; + } + + private SummoningPouch(int slot, boolean abyssal, int pouchId, int levelRequired, double createExperience, int npcId, double summonExperience, int summonCost, boolean peaceful, Item... items) { + this(slot, pouchId, levelRequired, createExperience, npcId, summonExperience, summonCost, peaceful, items); + this.abyssal = abyssal; + } + /** + * Gets the summoning pouch for the given slot. + * @param slot The slot. + * @return The summoning pouch. + */ + public static SummoningPouch forSlot(int slot) { + for (SummoningPouch pouch : SummoningPouch.values()) { + if (pouch.getSlot() == slot) { + return pouch; + } + } + return null; + } + + /** + * @return the pouchId + */ + public int getPouchId() { + return pouchId; + } + + /** + * @return the levelRequired + */ + public int getLevelRequired() { + return levelRequired; + } + + /** + * @return the createExperience + */ + public double getCreateExperience() { + return createExperience; + } + + /** + * @return the npcId + */ + public int getNpcId() { + return npcId; + } + + /** + * @return the summonExperience + */ + public double getSummonExperience() { + return summonExperience; + } + + /** + * Gets the amount of points to decrease the summoning points with when + * summoned. + * @return The amount of points. + */ + public int getSummonCost() { + return summonCost; + } + + /** + * @return Whether the familiar is peaceful + */ + public boolean getPeaceful() { return peaceful; } + + /** + * @return the items + */ + public Item[] getItems() { + return items; + } + + /** + * @return the slot + */ + public int getSlot() { + return slot; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/SummoningScroll.java b/Server/src/main/content/global/skill/summoning/SummoningScroll.java new file mode 100644 index 0000000..a11c706 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/SummoningScroll.java @@ -0,0 +1,215 @@ +package content.global.skill.summoning; + +/** + * Represents a summoning scroll. + * @author 'Vexia + */ +public enum SummoningScroll { + HOWL_SCROLL(0, 12425, 0.1, 1, 12047), + DREADFOWL_STRIKE_SCROLL(1, 12445, 0.1, 4, 12043), + EGG_SPAWN_SCROLL(2, 12428, 0.2, 10, 12059), + SLIME_SPRAY_SCROLL(3, 12459, 0.2, 13, 12019), + STONY_SHELL_SCROLL(4, 12533, 0.2, 16, 12009), + PESTER_SCROLL(5, 12838, 0.5, 17, 12778), + ELECTRIC_LASH_SCROLL(6, 12460, 0.4, 18, 12049), + VENOM_SHOT_SCROLL(7, 12432, 0.9, 19, 12055), + FIREBALL_ASSAULT_SCROLL(8, 12839, 1.1, 22, 12808), + CHEESE_FEAST_SCROLL(9, 12430, 2.3, 23, 12067), + SANDSTORM_SCROLL(10, 12446, 2.5, 25, 12063), + GENERATE_COMPOST_SCROLL(11, 12440, 0.6, 28, 12091), + EXPLODE_SCROLL(12, 12834, 2.9, 29, 12800), + VAMPYRE_TOUCH_SCROLL(13, 12447, 1.5, 31, 12053), + INSANE_FEROCITY_SCROLL(14, 12433, 1.6, 32, 12065), + MULTICHOP_SCROLL(15, 12429, 0.7, 33, 12021), + CALL_TO_ARMS_SCROLL1(16, 12443, 0.7, 34, 12818), + CALL_TO_ARMS_SCROLL2(17, 12443, 0.7, 34, 12814), + CALL_TO_ARMS_SCROLL3(18, 12443, 0.7, 34, 12780), + CALL_TO_ARMS_SCROLL4(19, 12443, 0.7, 34, 12798), + BRONZE_BULL_RUSH_SCROLL(64, 12461, 3.6, 36, 12073), + UNBURDEN_SCROLL(20, 12431, 0.6, 40, 12087), + HERBCALL_SCROLL(21, 12422, 0.8, 41, 12071), + EVIL_FLAMES_SCROLL(22, 12448, 2.1, 42, 12051), + PETRIFYING_GAZE_SCROLL1(23, 12458, 0.9, 43, 12095), + PETRIFYING_GAZE_SCROLL2(24, 12458, 0.9, 43, 12097), + PETRIFYING_GAZE_SCROLL3(25, 12458, 0.9, 43, 12099), + PETRIFYING_GAZE_SCROLL4(26, 12458, 0.9, 43, 12101), + PETRIFYING_GAZE_SCROLL5(27, 12458, 0.9, 43, 12103), + PETRIFYING_GAZE_SCROLL6(28, 12458, 0.9, 43, 12105), + PETRIFYING_GAZE_SCROLL7(29, 12458, 0.9, 43, 12107), + IRON_BULL_RUSH_SCROLL(65, 12462, 4.6, 46, 12075), + IMMENSE_HEAT_SCROLL(30, 12829, 2.3, 46, 12816), + THIEVING_FINGERS_SCROLL(31, 12426, 47, 47, 12041), + BLOOD_DRAIN_SCROLL(32, 12444, 2.4, 49, 12061), + TIRELESS_RUN_SCROLL(33, 12441, 0.8, 52, 12007), + ABYSSAL_DRAIN_SCROLL(34, 12454, 1.1, 54, 12035), + DISSOLVE_SCROLL(35, 12453, 5.5, 55, 12027), + STEEL_BULL_RUSH_SCROLL(66, 12463, 5.6, 56, 12077), + FISH_RAIN_SCROLL(36, 12424, 1.1, 56, 12531), + AMBUSH_SCROLL(37, 12836, 5.7, 57, 12812), + RENDING_SCROLL(38, 12840, 5.7, 57, 12784), + GOAD_SCROLL(39, 12835, 5.7, 57, 12810), + DOOMSPHERE_SCROLL(40, 12455, 5.8, 58, -1), + DUST_CLOUD_SCROLL(41, 12468, 3.0, 61, 12085), + ABYSSAL_STEALTH_SCROLL(42, 12427, 1.9, 62, 12037), + OPHIDIAN_INCUBATION_SCROLL(43, 12436, 3.1, 63, 12015), + POISONOUS_BLAST_SCROLL(44, 12467, 3.2, 64, 12045), + MITHRIL_BULL_RUSH_SCROLL(67, 12464, 6.6, 66, 12079), + TOAD_BARK_SCROLL(45, 12452, 1.0, 66, 12123), + ESTUDO_SCROLL(46, 12439, 0.7, 67, 12031), + SWALLOW_WHOLE_SCROLL(47, 12438, 1.4, 68, 12029), + FRUITFALL_SCROLL(48, 12423, 1.4, 69, 12033), + FAMINE_SCROLL(49, 12830, 1.5, 70, 12820), + ARCTIC_BLAST_SCROLL(50, 12451, 1.1, 71, 12057), + + // RISE_FROM_THE_ASHES_SCROLL(51, 14622, 8.0, 277, -1), + VOLCANIC_STRENGTH_SCROLL(51, 12826, 7.3, 73, 12792), + CRUSHING_CLAW_SCROLL(52, 12449, 3.7, 74, 12069), + MANTIS_STRIKE_SCROLL(53, 12450, 3.7, 75, 12011), + INFERNO_SCROLL(54, 12841, 1.5, 76, 12782), + ADAMANT_BULL_RUSH_SCROLL(68, 12465, 7.6, 76, 12081), + DEADLY_CLAW_SCROLL(55, 12831, 11.0, 77, 12162), + ACORN_MISSILE_SCROLL(56, 12457, 1.6, 78, 12013), + TITANS_CONSTITUTION_SCROLL1(57, 12824, 7.9, 79, 12802), + TITANS_CONSTITUTION_SCROLL2(58, 12824, 7.9, 79, 12806), + TITANS_CONSTITUTION_SCROLL3(59, 12824, 7.9, 79, 12804), + REGROWTH_SCROLL(60, 12442, 1.6, 80, 12025), + SPIKE_SHOT_SCROLL(61, 12456, 4.1, 83, 12017), + EBON_THUNDER_SCROLL(62, 12837, 8.3, 83, 12788), + SWAMP_PLAGUE_SCROLL(63, 12832, 4.1, 85, 12776), + RUNE_BULL_RUSH_SCROLL(69, 12466, 8.6, 86, 12083), + HEALING_AURA_SCROLL(70, 12434, 1.8, 88, 12039), + BOIL_SCROLL(71, 12833, 8.9, 89, 12786), + MAGIC_FOCUS_SCROLL(72, 12437, 4.6, 92, 12089), + ESSENCE_SHIPMENT_SCROLL(73, 12827, 1.9, 93, 12796), + IRON_WITHIN_SCROLL(74, 12828, 4.7, 95, 12822), + WINTER_STORAGE_SCROLL(75, 12435, 4.8, 96, 12093), + STEEL_OF_LEGENDS_SCROLL(76, 12825, 4.9, 99, 12790), + CLAY_DEPOSIT_SCROLL_1(-1, 14421, 0, 1, 14422), + CLAY_DEPOSIT_SCROLL_2(-1, 14421, 0, 20, 14424), + CLAY_DEPOSIT_SCROLL_3(-1, 14421, 0, 40, 14426), + CLAY_DEPOSIT_SCROLL_4(-1, 14421, 0, 60, 14428), + CLAY_DEPOSIT_SCROLL_5(-1, 14421, 0, 80, 14430); + + /** + * The level required. + */ + private int level; + + /** + * The item id needed. + */ + private int itemId; + + /** + * The slot id. + */ + private int slotId; + + /** + * The xp gained. + */ + private double xp; + + /** + * The items required. + */ + private int[] items; + + /** + * Constructs a new {@code SummoningScroll} {@code Object}. + * @param level + * @param itemId + * @param xp + * @param slotId + * @param items + */ + SummoningScroll(int slotId, int itemId, double xp, int level, int... items) { + this.level = level; + this.itemId = itemId; + this.xp = xp; + this.slotId = slotId; + this.items = items; + } + + public int getPouch(){ + return items[0]; + } + + /** + * Gets the level. + * @return The level. + */ + public int getLevel() { + return level; + } + + /** + * Gets the itemId. + * @return The itemId. + */ + public int getItemId() { + return itemId; + } + + /** + * Gets the slotId. + * @return The slotId. + */ + public int getSlotId() { + return slotId; + } + + /** + * Gets the xp. + * @return The xp. + */ + public double getExperience() { + return xp; + } + + /** + * Gets the items. + * @return The items. + */ + public int[] getItems() { + return items; + } + + /** + * Gets the summoning value for the id. + * @param id + * @return + */ + public static SummoningScroll forId(int id) { + for (SummoningScroll scroll : SummoningScroll.values()) { + if (scroll.slotId == id) { + return scroll; + } + } + return null; + } + + public static SummoningScroll forItemId(int id) { + for (SummoningScroll scroll : SummoningScroll.values()) { + if (scroll.itemId == id) { + return scroll; + } + } + return null; + } + + /** + * Gets the scroll for the given pouch item id. + * @param pouchId The pouch item id. + * @return The scroll. + */ + public static SummoningScroll forPouch(int pouchId) { + for (SummoningScroll scroll : SummoningScroll.values()) { + if (scroll.items[0] == pouchId) { + return scroll; + } + } + return null; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/SummoningTabListener.kt b/Server/src/main/content/global/skill/summoning/SummoningTabListener.kt new file mode 100644 index 0000000..c47862b --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/SummoningTabListener.kt @@ -0,0 +1,67 @@ +import content.global.skill.summoning.familiar.BurdenBeast +import content.global.skill.summoning.familiar.FamiliarSpecial +import content.global.skill.summoning.pet.Pet +import core.api.sendMessage +import core.game.interaction.InterfaceListener + +class SummoningTabListener : InterfaceListener { + override fun defineInterfaceListeners() { + on(662) { player, _, opcode, buttonID, _, _ -> + when(buttonID) { + 51 -> { + if (player.familiarManager.hasFamiliar()) { + player.familiarManager.familiar.call() + } else { + player.getPacketDispatch().sendMessage("You don't have a follower.") + } + } + 67 -> { + if (player.familiarManager.hasFamiliar()) { + if (player.familiarManager.familiar.isInvisible || !player.familiarManager.familiar.location.withinDistance(player.location)) { + sendMessage(player, "Your familiar is too far away!") + return@on true + } + if (!player.familiarManager.familiar.isBurdenBeast()) { + player.getPacketDispatch().sendMessage("Your familiar is not a beast of burden.") + return@on true + } + val beast = player.familiarManager.familiar as BurdenBeast + if (beast.getContainer().isEmpty()) { + player.getPacketDispatch().sendMessage("Your familiar is not carrying any items.") + return@on true + } + beast.withdrawAll() + return@on true + } + player.getPacketDispatch().sendMessage("You don't have a follower.") + } + 53 -> { + if (player.familiarManager.hasFamiliar()) { + if(opcode == 155) { + // Dismiss familiar + player.getDialogueInterpreter().open("dismiss_dial") + } else if(opcode == 196) { + // Dismiss now + if (player.getFamiliarManager().getFamiliar() is Pet) { + val pet = player.familiarManager.familiar as Pet + player.familiarManager.removeDetails(pet.getItemId()) + } + player.familiarManager.dismiss() + } + } else { + player.getPacketDispatch().sendMessage("You don't have a follower.") + } + } + else -> { + if (player.familiarManager.hasFamiliar()) { + player.familiarManager.familiar.executeSpecialMove(FamiliarSpecial(player)) + } else { + player.getPacketDispatch().sendMessage("You don't have a follower.") + } + } + } + return@on true + } + } +} + diff --git a/Server/src/main/content/global/skill/summoning/SummoningTrainingRoom.java b/Server/src/main/content/global/skill/summoning/SummoningTrainingRoom.java new file mode 100644 index 0000000..6296dae --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/SummoningTrainingRoom.java @@ -0,0 +1,611 @@ +package content.global.skill.summoning; + +import core.cache.def.impl.SceneryDefinition; +import core.game.component.Component; +import core.game.activity.ActivityManager; +import core.game.activity.ActivityPlugin; +import core.game.activity.CutscenePlugin; +import core.plugin.Initializable; +import core.game.dialogue.DialoguePlugin; +import core.game.global.action.ClimbActionHandler; +import core.game.node.entity.skill.Skills; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.build.DynamicRegion; +import core.game.world.map.path.Pathfinder; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.net.packet.PacketRepository; +import core.net.packet.context.CameraContext; +import core.net.packet.context.CameraContext.CameraType; +import core.net.packet.context.MinimapStateContext; +import core.net.packet.out.CameraViewPacket; +import core.net.packet.out.MinimapState; +import core.plugin.Plugin; +import core.plugin.ClassScanner; + +import static core.api.ContentAPIKt.*; +import content.data.Quests; + +/** + * Handles the summoning training room. + * @author Emperor + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class SummoningTrainingRoom extends OptionHandler { + + /** + * Represents the wolf bones item. + */ + private static final Item BONES = new Item(2859, 2); + + /** + * Represents the trapdoor key. + */ + private static final Item TRAPDOOR_KEY = new Item(12528); + + /** + * Represents the howl scroll item. + */ + private static final Item HOWL_SCROLL = new Item(12425); + + /** + * Represents the wolf pouch. + */ + private static final Item WOLF_POUCH = new Item(12047); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(28675).getHandlers().put("option:open", this); + SceneryDefinition.forId(28676).getHandlers().put("option:climb-down", this); + SceneryDefinition.forId(28653).getHandlers().put("option:climb-down", this); + SceneryDefinition.forId(28572).getHandlers().put("option:climb-up", this); + SceneryDefinition.forId(28676).getHandlers().put("option:close", this); + SceneryDefinition.forId(28714).getHandlers().put("option:climb", this); + SceneryDefinition.forId(28586).getHandlers().put("option:search", this); + ActivityManager.register(new FluffyCutscene()); + return this; + } + + @Override + public boolean handle(final Player player, Node node, String option) { + Scenery object = (Scenery) node; + Location loc = null; + Quest quest = player.getQuestRepository().getQuest(Quests.WOLF_WHISTLE); + int questVal = quest.getStage(player) == 0 ? 0 : quest.getStage(player) > 0 && quest.getStage(player) < 100 ? 5 : 28893; + switch (option) { + case "close": + setVarp(player, 1178, questVal == 28893 ? 32989 : (1 << 11) + questVal); + return true; + case "open": + if (quest.getStage(player) < 40) { + player.getPacketDispatch().sendMessage("The trapdoor is locked."); + return true; + } else if (quest.getStage(player) == 40) { + if (player.getAttribute("has-key", false) || player.getInventory().remove(TRAPDOOR_KEY)) { + player.setAttribute("has-key", true); + setVarp(player, 1178, (2 << 11) + questVal, true); + } else { + player.getPacketDispatch().sendMessage("The trapdoor is locked."); + return true; + } + } + setVarp(player, 1178, questVal == 28893 ? 28893 : (2 << 11) + questVal); + return true; + case "climb-down": + if (object.getId() == 28653) { + if (quest.getStage(player) == 50) { + final CutscenePlugin plugin = player.getAttribute("in-cutscene", null); + if (plugin != null) { + plugin.stop(true); + } else { + ClimbActionHandler.climbLadder(player, object, option); + } + } else { + ClimbActionHandler.climbLadder(player, object, option); + } + return true; + } + if (!object.getLocation().equals(Location.create(2927, 3444, 0))) { + return false; + } + loc = Location.create(2209, 5348, 0); + break; + case "climb": + if (!object.getLocation().equals(Location.create(2209, 5349, 0))) { + return false; + } + loc = Location.create(2926, 3444, 0); + break; + case "climb-up": + switch (quest.getStage(player)) { + case 10: + case 50: + if (player.getFamiliarManager().hasFamiliar()) { + player.getPacketDispatch().sendMessage("You can't bring a familiar up there."); + return true; + } + if (quest.getStage(player) == 50 && (!player.getInventory().containsItem(WOLF_POUCH) || !player.getInventory().containsItem(HOWL_SCROLL))) { + player.getDialogueInterpreter().sendDialogues(player, null, "I should bring my spirit wolf pouch and howl scroll", "with me up there."); + return true; + } + ActivityManager.start(player, "fluffy cutscene", false); + break; + case 100: + case 60: + ClimbActionHandler.climbLadder(player, (Scenery) node, option); + break; + default: + player.getDialogueInterpreter().sendDialogue("There is a loud crash from upstairs, followed by the tinkling of", "broken glass."); + break; + } + return true; + case "search": + if (quest.getStage(player) == 30 && !player.getAttribute("searched-body", false)) { + if (!player.getInventory().hasSpaceFor(BONES)) { + player.getPacketDispatch().sendMessage("You search the dead body but find nothing."); + return true; + } + if (!player.getInventory().containsItem(BONES) && player.getInventory().add(BONES)) { + player.setAttribute("/save:searched-body", true); + player.getPacketDispatch().sendMessage("You search the dead body and find two wolf bones."); + return true; + } else { + player.getPacketDispatch().sendMessage("You search the dead body but find nothing."); + return true; + } + } else { + player.getPacketDispatch().sendMessage("You search the dead body but find nothing."); + } + return true; + default: + return false; + } + ClimbActionHandler.climb(player, new Animation(828), loc); + return true; + } + + /** + * Represents the cutscene used during wolf whistle. + * @author 'Vexia + * @version 1.0 + */ + public static final class FluffyCutscene extends CutscenePlugin { + + /** + * Constructs a new {@code FluffyCutscene} {@code Object}. + */ + public FluffyCutscene() { + super("fluffy cutscene"); + } + + /** + * Constructs a new {@code FluffyCutscene} {@code Object}. + * @param player the player. + */ + public FluffyCutscene(final Player player) { + this(); + this.player = player; + } + + @Override + public ActivityPlugin newInstance(Player p) throws Throwable { + return new FluffyCutscene(p); + } + + @Override + public void open() { + player.getDialogueInterpreter().open(392932, this); + player.setAttribute("wolf-dial", player.getDialogueInterpreter().getDialogue()); + player.setAttribute("in-cutscene", this); + player.lock(); + } + + @Override + public void end() { + super.end(); + player.removeAttribute("in-cutscene"); + player.getFamiliarManager().dismiss(); + } + + @Override + public Location getSpawnLocation() { + return null; + } + + @Override + public Location getStartLocation() { + return base.transform(46, 50, 1); + } + + @Override + public void configure() { + region = DynamicRegion.create(11573); + setRegionBase(); + registerRegion(region.getId()); + } + + @Override + public void register() { + ClassScanner.definePlugin(new FluffyDialogue()); + } + + /** + * Represents the dialogue used during the fluffy cutscene. + * @author 'Vexia + * @version 1.0 + */ + public static final class FluffyDialogue extends DialoguePlugin { + + /** + * Represents the scared animation. + */ + private static final Animation SCARED_ANIMATION = new Animation(2836); + + /** + * Represents the wolpertiner graphic. + */ + private static final Graphics GRAPHIC = new Graphics(1522); + + /** + * Represents the shudder animation. + */ + private static final Animation SHUDDER_ANIMATION = new Animation(8506); + + /** + * Represents the death animation. + */ + private static final Animation DEATH_ANIMATION = new Animation(8507); + + /** + * Represents the cutscene instance. + */ + private CutscenePlugin cutscene; + + /** + * Represents the quest instance. + */ + private Quest quest; + + /** + * Represents the fluffy npc. + */ + private NPC fluffy; + + /** + * Represents the wolf npc. + */ + private NPC wolf; + + /** + * Constructs a new {@code FluffyDialogue} {@code Object}. + */ + public FluffyDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code FluffyDialogue} {@code Object}. + * @param player the player. + */ + public FluffyDialogue(final Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new FluffyDialogue(player); + } + + @Override + public boolean open(Object... args) { + cutscene = (CutscenePlugin) args[0]; + quest = player.getQuestRepository().getQuest(Quests.WOLF_WHISTLE); + fluffy = NPC.create(6990, cutscene.getBase().transform(41, 52, 1)); + fluffy.init(); + fluffy.faceTemporary(player, 1); + Location b = cutscene.getBase().transform(42, 50, 0); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.POSITION, b.getX(), b.getY(), 244, 1, 100)); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.ROTATION, b.getX() + 1, b.getY(), 244, 1, 100)); + switch (quest.getStage(player)) { + case 10: + player("Come on then little, fluffy..."); + break; + case 50: + player("Mustn't look round, bunny will eat me.", "Mustn't look round, bunny will eat me.", "Mustn't look round, bunny will eat me."); + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (quest.getStage(player)) { + case 10: + switch (stage) { + case 0: + close(); + GameWorld.getPulser().submit(new Pulse(1, player, fluffy) { + int counter = 0; + + @Override + public boolean pulse() { + switch (++counter) { + case 2: + player.face(fluffy); + break; + case 5: + player("Gigantic..."); + stage = 1; + return true; + } + return false; + } + + }); + break; + case 1: + player("scary-looking..."); + stage = 2; + break; + case 2: + player("razor-fanged..."); + stage = 3; + break; + case 3: + player("bunny..."); + stage = 4; + break; + case 4: + close(); + int x = player.getLocation().getX() + 1; + int y = player.getLocation().getY() - 1; + int height = 300; + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.POSITION, x, y, height, 1, 100)); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.ROTATION, x + 1000, y + 13, height, 1, 100)); + player.faceLocation(cutscene.getBase().transform(44, 50, 1)); + GameWorld.getPulser().submit(new Pulse(1, player, fluffy) { + int counter = 0; + + @Override + public boolean pulse() { + switch (++counter) { + case 3: + fluffy.sendChat("Mrooowr?"); + break; + case 6: + player("What is that thing?"); + stage = 5; + return true; + } + return false; + } + + }); + break; + case 5: + player("Maybe, if I leave quitely, it won't notice me."); + stage = 6; + break; + case 6: + close(); + GameWorld.getPulser().submit(new Pulse(1, player, fluffy) { + int counter = 0; + + @Override + public boolean pulse() { + switch (++counter) { + case 2: + Pathfinder.find(fluffy, cutscene.getBase().transform(41, 51, 1)).walk(fluffy); + break; + case 4: + fluffy.face(player); + fluffy.graphics(GRAPHIC); + break; + case 5: + fluffy.sendChat("Raaaarw!"); + break; + case 8: + int x = player.getLocation().getX() - 4; + int y = player.getLocation().getY(); + int height = 270; + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.POSITION, x, y, height, 1, 100)); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.ROTATION, x + 1, y, height, 1, 100)); + interpreter.sendDialogue("A chilling, unnatural fear envelops you!"); + stage = 7; + return true; + } + return false; + } + + }); + break; + case 7: + player("It's coming to get me!"); + player.animate(SCARED_ANIMATION); + player.sendChat("It's coming to get me!"); + stage = 8; + break; + case 8: + end(); + GameWorld.getPulser().submit(new Pulse(2) { + @Override + public boolean pulse() { + player.animate(Animation.create(827)); + return true; + } + + }); + cutscene.stop(true); + quest.setStage(player, 20); + break; + } + break; + case 50:// second cutscene. + switch (stage) { + case 0: + fluffy.faceLocation(cutscene.getBase().transform(40, 53, 1)); + player("Okay, I have the spirit wolf pouch, so it can't hurt me..."); + stage = 1; + break; + case 1: + player("...I hope."); + stage = 2; + break; + case 2: + int x = player.getLocation().getX() + 1; + int y = player.getLocation().getY() - 1; + int height = 300; + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.POSITION, x, y, height, 1, 100)); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.ROTATION, x + 1000, y + 13, height, 1, 100)); + player.faceLocation(cutscene.getBase().transform(44, 50, 1)); + close(); + player("Oh, good. It's too busy gnawing to notice me."); + stage = 3; + break; + case 3: + fluffy.faceTemporary(player, 1); + fluffy.sendChat("Raaaarw!"); + player("I spoke too soon!"); + stage = 4; + break; + case 4: + player("I'll use the spirit wolf pouch. I hope this works."); + stage = 5; + break; + case 5: + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.RESET, 0 + 1000, 0 + 13, 0, 1, 100)); + PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 0)); + player.unlock(); + player.getLocks().lockMovement(10000000); + player.getInterfaceManager().openTab(new Component(149)); + stage = -5; + break; + case -5: + player.setAttribute("in-cutscene", cutscene); + close(); + stage = 6; + break; + case 6: + Location l = cutscene.getBase().transform(46, 50, 0); + x = l.getX() + 1; + y = l.getY() - 2; + height = 440; + player.lock(); + player.getLocks().lockMovement(100000); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.POSITION, x, y, height, 1, 95)); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.ROTATION, x + 1000, y + 17, height, 1, 95)); + wolf = player.getFamiliarManager().getFamiliar(); + GameWorld.getPulser().submit(new Pulse(1, player, fluffy) { + int counter; + + @Override + public boolean pulse() { + switch (++counter) { + case 1: + wolf.sendChat("Grrrrrrrrrrrrrrrr..."); + break; + case 2: + fluffy.sendChat("Whiiiiiine!"); + break; + case 4: + player("Get that thing!"); + stage = 7; + return true; + } + return false; + } + }); + break; + case 7: + player.getLocks().lockMovement(1000000); + player.lock(); + close(); + fluffy.animate(SHUDDER_ANIMATION); + if (player.getInventory().remove(HOWL_SCROLL)) { + player.getDialogueInterpreter().setDialogue(this); + player.getDialogueInterpreter().getDialogue().setStage(8); + GameWorld.getPulser().submit(new Pulse(1, player, fluffy, wolf) { + int counter; + + @Override + public boolean pulse() { + switch (++counter) { + case 2: + wolf.animate(Animation.create(8293)); + Projectile.magic(wolf, fluffy, 1333, 40, 36, 50, 5).send(); + player.getSkills().updateLevel(Skills.SUMMONING, -2, 0); + break; + case 5: + fluffy.animate(DEATH_ANIMATION); + break; + case 12: + fluffy.clear(); + wolf.face(player); + player.face(player); + player("Well, that certainly seems to have got rid of the giant", "wolpertinger."); + stage = 8; + player.getDialogueInterpreter().setDialogue(FluffyDialogue.this); + player.getDialogueInterpreter().getDialogue().setStage(8); + return true; + } + return false; + } + + }); + } + break; + case 8: + player("Come on, let's go tell Pikkupstix."); + stage = 9; + break; + case 9: + wolf.clear(); + player("They both vanished! I'm sure Pikkupstix will be able to", "explain this to me."); + stage = 10; + break; + case 10: + end(); + quest.setStage(player, 60); + cutscene.stop(true); + break; + } + break; + } + return true; + } + + @Override + public boolean close() { + return super.close(); + } + + @Override + public void end() { + super.end(); + if (player.getFamiliarManager().hasFamiliar()) { + player.getFamiliarManager().getFamiliar().dismiss(); + } + } + + @Override + public int[] getIds() { + return new int[] { 392932 }; + } + + } + } +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/AbyssalLurkerNPC.java b/Server/src/main/content/global/skill/summoning/familiar/AbyssalLurkerNPC.java new file mode 100644 index 0000000..9fb1eff --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/AbyssalLurkerNPC.java @@ -0,0 +1,66 @@ +package content.global.skill.summoning.familiar; + +import core.game.node.entity.skill.Skills; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.game.world.update.flag.context.Graphics; + +/** + * Represents the Abyssal Lurker familiar. + * @author Aero + */ +@Initializable +public class AbyssalLurkerNPC extends BurdenBeast { + + /** + * Constructs a new {@code AbyssalLurkerNPC} {@code Object}. + */ + public AbyssalLurkerNPC() { + this(null, 6820); + } + + /** + * Constructs a new {@code AbyssalLurkerNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public AbyssalLurkerNPC(Player owner, int id) { + super(owner, id, 4100, 12037, 3, 7, WeaponInterface.STYLE_CAST); + } + + @Override + public Familiar construct(Player owner, int id) { + return new AbyssalLurkerNPC(owner, id); + } + + @Override + public boolean isAllowed(Player owner, Item item) { + if (item.getId() != 1436 && item.getId() != 7936) { + owner.getPacketDispatch().sendMessage("Your familiar can only hold unnoted essence."); + return false; + } + return super.isAllowed(owner, item); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + visualize(Animation.create(7682), Graphics.create(0)); + owner.getSkills().updateLevel(Skills.AGILITY, 4); + owner.getSkills().updateLevel(Skills.THIEVING, 4); + return true; + } + + @Override + public void visualizeSpecialMove() { + owner.visualize(new Animation(7660), new Graphics(1296)); + } + + @Override + public int[] getIds() { + return new int[] { 6820, 6821 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/AbyssalParasiteNPC.java b/Server/src/main/content/global/skill/summoning/familiar/AbyssalParasiteNPC.java new file mode 100644 index 0000000..7954847 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/AbyssalParasiteNPC.java @@ -0,0 +1,75 @@ +package content.global.skill.summoning.familiar; + +import core.plugin.Initializable; +import core.game.node.entity.Entity; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.tools.RandomFunction; + +/** + * Represents the Abyssal Parasite familiar. + * @author Aero + * @note do the shit for the abbys. + */ +@Initializable +public class AbyssalParasiteNPC extends BurdenBeast { + + /** + * The special move flag. + */ + @SuppressWarnings("unused") + private boolean specialMove = false; + + /** + * Constructs a new {@code AbyssalParasiteNPC} {@code Object}. + */ + public AbyssalParasiteNPC() { + this(null, 6818); + } + + /** + * Constructs a new {@code AbyssalParasiteNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public AbyssalParasiteNPC(Player owner, int id) { + super(owner, id, 3000, 12035, 1, 7); + } + + @Override + public Familiar construct(Player owner, int id) { + return new AbyssalParasiteNPC(owner, id); + } + + @Override + public boolean isAllowed(Player owner, Item item) { + if (item.getId() != 1436 && item.getId() != 7936) { + owner.getPacketDispatch().sendMessage("Your familiar can only hold unnoted essence."); + return false; + } + return super.isAllowed(owner, item); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + final Entity target = special.getTarget(); + if (!canCombatSpecial(target)) { + return false; + } + faceTemporary(target, 2); + sendFamiliarHit(target, 7); + visualize(Animation.create(7672), Graphics.create(1422)); + Projectile.magic(this, target, 1423, 40, 36, 51, 10).send(); + target.getSkills().decrementPrayerPoints(RandomFunction.random(1, 3)); + return true; + } + + @Override + public int[] getIds() { + return new int[] { 6818, 6819 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/AbyssalTitanNPC.kt b/Server/src/main/content/global/skill/summoning/familiar/AbyssalTitanNPC.kt new file mode 100644 index 0000000..a7ed47a --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/AbyssalTitanNPC.kt @@ -0,0 +1,90 @@ +package content.global.skill.summoning.familiar + +import core.api.Container +import core.api.addItem +import core.api.amountInInventory +import core.api.removeItem +import core.game.node.entity.combat.equipment.WeaponInterface +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +/** + * Represents the Abyssal Titan familiar. + * @author Aero + * @author Splinter + */ +@Initializable +class AbyssalTitanNPC +constructor(owner: Player? = null, id: Int = NPCs.ABYSSAL_TITAN_7349) : + BurdenBeast(owner, id, 3200, Items.ABYSSAL_TITAN_POUCH_12796, 6, 7, WeaponInterface.STYLE_ACCURATE) { + override fun construct(owner: Player, id: Int): Familiar { + return AbyssalTitanNPC(owner, id) + } + + override fun isAllowed(owner: Player, item: Item): Boolean { + return when (item.id) { + Items.RUNE_ESSENCE_1436, Items.PURE_ESSENCE_7936 -> super.isAllowed(owner, item) + else -> { + owner.packetDispatch.sendMessage("Your familiar can only hold unnoted essence.") + false + } + } + } + + override fun specialMove(special: FamiliarSpecial): Boolean { + val playerRuneEssenceAmount = amountInInventory(owner, Items.RUNE_ESSENCE_1436) + val playerPureEssenceAmount = amountInInventory(owner, Items.PURE_ESSENCE_7936) + val beastRuneEssenceAmount = this.container.getAmount(Items.RUNE_ESSENCE_1436) + val beastPureEssenceAmount = this.container.getAmount(Items.PURE_ESSENCE_7936) + val totalRuneEssence = playerRuneEssenceAmount + beastRuneEssenceAmount + val totalPureEssence = playerPureEssenceAmount + beastPureEssenceAmount + + if ((totalRuneEssence + totalPureEssence) == 0) { + owner.sendMessage("You have no essence to send to the bank.") + return false + } + + if (!owner.bank.hasSpaceFor( + Item(Items.RUNE_ESSENCE_1436, totalRuneEssence), + Item(Items.PURE_ESSENCE_7936, totalPureEssence) + ) + ) { + owner.sendMessage("You have no space in your bank to deposit your essence.") + return false + } + + + if (removeItem(owner, Item(Items.RUNE_ESSENCE_1436, playerRuneEssenceAmount))) { + addItem(owner, Items.RUNE_ESSENCE_1436, playerRuneEssenceAmount, Container.BANK) + } + + if (removeItem(owner, Item(Items.PURE_ESSENCE_7936, playerPureEssenceAmount))) { + addItem(owner, Items.PURE_ESSENCE_7936, playerPureEssenceAmount, Container.BANK) + } + + if (this.container.remove(Item(Items.RUNE_ESSENCE_1436, beastRuneEssenceAmount))) { + addItem(owner, Items.RUNE_ESSENCE_1436, beastRuneEssenceAmount, Container.BANK) + } + + if (this.container.remove(Item(Items.PURE_ESSENCE_7936, beastPureEssenceAmount))) { + addItem(owner, Items.PURE_ESSENCE_7936, beastPureEssenceAmount, Container.BANK) + } + + owner.sendMessage("The titan sends $totalRuneEssence rune essence and $totalPureEssence pure essence to your bank.") + return true + } + + override fun visualizeSpecialMove() { + owner.visualize(Animation.create(7660), Graphics.create(1316)) + visualize(Animation.create(7694), Graphics.create(1457)) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.ABYSSAL_TITAN_7349, NPCs.ABYSSAL_TITAN_7350) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/summoning/familiar/AlbinoRatNPC.java b/Server/src/main/content/global/skill/summoning/familiar/AlbinoRatNPC.java new file mode 100644 index 0000000..28842ad --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/AlbinoRatNPC.java @@ -0,0 +1,59 @@ +package content.global.skill.summoning.familiar; + +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.game.world.update.flag.context.Graphics; + +/** + * Represents the Albino Rat familiar. + * @author Aero + * @author Vexia + */ +@Initializable +public class AlbinoRatNPC extends Forager { + + /** + * The cheese item. + */ + private static final Item CHEESE = new Item(1985, 4); + + /** + * Constructs a new {@code AlbinoRatNPC} {@code Object}. + */ + public AlbinoRatNPC() { + this(null, 6847); + } + + /** + * Constructs a new {@code AlbinoRatNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public AlbinoRatNPC(Player owner, int id) { + super(owner, id, 2200, 12067, 6, WeaponInterface.STYLE_ACCURATE, CHEESE); + } + + @Override + public Familiar construct(Player owner, int id) { + return new AlbinoRatNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + if (produceItem(CHEESE)) { + owner.lock(7); + visualize(Animation.create(4934), Graphics.create(1384)); + return true; + } + return false; + } + + @Override + public int[] getIds() { + return new int[] { 6847, 6848 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/ArcticBearNPC.java b/Server/src/main/content/global/skill/summoning/familiar/ArcticBearNPC.java new file mode 100644 index 0000000..8639adb --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/ArcticBearNPC.java @@ -0,0 +1,62 @@ +package content.global.skill.summoning.familiar; + +import core.game.node.entity.skill.SkillBonus; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.player.Player; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.game.world.update.flag.context.Graphics; + +/** + * Represents the Arctic Bear familiar. + * @author Aero + */ +@Initializable +public class ArcticBearNPC extends Familiar { + + /** + * Constructs a new {@code ArcticBearNPC} {@code Object}. + */ + public ArcticBearNPC() { + this(null, 6839); + } + + /** + * Constructs a new {@code ArcticBearNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public ArcticBearNPC(Player owner, int id) { + super(owner, id, 2800, 12057, 6, WeaponInterface.STYLE_CONTROLLED); + boosts.add(new SkillBonus(Skills.HUNTER, 7)); + } + + @Override + public Familiar construct(Player owner, int id) { + return new ArcticBearNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + Entity target = special.getTarget(); + if (!canCombatSpecial(target)) { + return false; + } + animate(Animation.create(4926)); + graphics(Graphics.create(1405)); + Projectile p = Projectile.magic(this, target, 1406, 40, 40, 1, 10); + p.setSpeed(25); + p.send(); + sendFamiliarHit(target, 15, Graphics.create(1407)); + return true; + } + + @Override + public int[] getIds() { + return new int[] { 6839, 6840 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/BarkerToadNPC.java b/Server/src/main/content/global/skill/summoning/familiar/BarkerToadNPC.java new file mode 100644 index 0000000..97d7512 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/BarkerToadNPC.java @@ -0,0 +1,54 @@ +package content.global.skill.summoning.familiar; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.game.world.update.flag.context.Graphics; + +/** + * Represents the Barker Toad familiar. + * @author Aero + */ +@Initializable +public class BarkerToadNPC extends Familiar { + + /** + * Constructs a new {@code BarkerToadNPC} {@code Object}. + */ + public BarkerToadNPC() { + this(null, 6889); + } + + /** + * Constructs a new {@code BarkerToadNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public BarkerToadNPC(Player owner, int id) { + super(owner, id, 800, 12123, 6, WeaponInterface.STYLE_AGGRESSIVE); + } + + @Override + public Familiar construct(Player owner, int id) { + return new BarkerToadNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + final Entity target = special.getTarget(); + if (!canCombatSpecial(target)) { + return false; + } + animate(getProperties().getAttackAnimation()); + graphics(Graphics.create(1403)); + sendFamiliarHit(target, 8, Graphics.create(1404)); + return true; + } + + @Override + public int[] getIds() { + return new int[] { 6889, 6890 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/BeaverDialogue.java b/Server/src/main/content/global/skill/summoning/familiar/BeaverDialogue.java new file mode 100644 index 0000000..dff82b3 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/BeaverDialogue.java @@ -0,0 +1,66 @@ +package content.global.skill.summoning.familiar; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Handles the beaver dialgoue. + * @author Empathy + * + */ +@Initializable +public final class BeaverDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code BeaverDialogue} {@code Object}. + */ + public BeaverDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code BeaverDialogue} {@code Object}. + * + * @param player the player. + */ + public BeaverDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new BeaverDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "How much wood would a woodchuck chuck if a", "woodchuck could chuck wood?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Approximately 32,768 depending on his woodcutting", "level."); + stage = 1; + break; + case 1: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 8635 }; + } + } diff --git a/Server/src/main/content/global/skill/summoning/familiar/BeaverNPC.java b/Server/src/main/content/global/skill/summoning/familiar/BeaverNPC.java new file mode 100644 index 0000000..05c810f --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/BeaverNPC.java @@ -0,0 +1,146 @@ +package content.global.skill.summoning.familiar; + +import core.game.node.entity.skill.SkillBonus; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Direction; +import core.game.world.map.path.Pathfinder; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.tools.RandomFunction; + +/** + * Represents the Beaver familiar. + * @author Vexia + * @author Aero + */ +@Initializable +public class BeaverNPC extends Forager { + + /** + * The items to foraged. + */ + private static final Item[] ITEMS = new Item[] { new Item(1511), new Item(2862), new Item(1521), new Item(1519), new Item(6333), new Item(10810), new Item(1517), new Item(6332), new Item(12581), new Item(960), new Item(8778) }; + + /** + * The tree names the scroll can be casted on. + */ + private static final String[] TREE_NAMES = new String[] { "Tree", "Oak", "Hollow", "Willow", "Arctic pine", "Eucalyptus", "Maple", "Yew", "Magic", "Cursed magic" }; + + /** + * If multi chopping. + */ + private boolean multiChop; + + /** + * Constructs a new {@code BeaverNPC} {@code Object}. + */ + public BeaverNPC() { + this(null, 6808); + } + + /** + * Constructs a new {@code BeaverNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public BeaverNPC(Player owner, int id) { + super(owner, id, 2700, 12021, 6, ITEMS); + boosts.add(new SkillBonus(Skills.WOODCUTTING, 2)); + } + + @Override + public Familiar construct(Player owner, int id) { + return new BeaverNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + final Scenery object = (Scenery) special.getNode(); + if (!isTree(object.getName())) { + owner.getPacketDispatch().sendMessages("This scroll only works on naturally growing, oak, willow, arctic pine", "teak, mahogany, maple, yew, and magic trees."); + return false; + } + if (owner.getInventory().freeSlots() == 0) { + return false; + } + if (object.getLocation().getDistance(getLocation()) > 5) { + owner.getPacketDispatch().sendMessages("The beaver is a little too far from the tree for the scroll to work - stand", "closer."); + return false; + } + Direction dir = Direction.getLogicalDirection(getLocation(), object.getLocation()); + Pathfinder.find(getLocation(), object.getLocation().transform(dir)).walk(this); + final int ticks = 2 + (int) Math.floor(owner.getLocation().getDistance(object.getLocation().transform(dir)) * 0.5); + owner.lock(ticks); + multiChop = true; + getPulseManager().clear(); + GameWorld.getPulser().submit(new Pulse(ticks, owner, this) { + @Override + public boolean pulse() { + lock(11); + owner.lock(11); + faceLocation(object.getLocation()); + animate(Animation.create(7722)); + GameWorld.getPulser().submit(new Pulse(1, owner, BeaverNPC.this) { + int counter; + boolean recieved = false; + + @Override + public boolean pulse() { + switch (++counter) { + default: + if (counter > 3) { + if (RandomFunction.random(12) < 4) { + owner.getInventory().add(ITEMS[RandomFunction.random(ITEMS.length)], owner); + recieved = true; + } + } + break; + case 11: + if (!recieved) { + owner.getInventory().add(ITEMS[RandomFunction.random(ITEMS.length)], owner); + } + multiChop = false; + return true; + } + return false; + } + }); + return true; + } + }); + return true; + } + + @Override + public void startFollowing() { + if (multiChop) { + return; + } + super.startFollowing(); + } + + /** + * Checks if its a tree. + * @param name the name. + * @return {@code True} if so. + */ + private boolean isTree(final String name) { + for (String s : TREE_NAMES) { + if (s.equals(name)) { + return true; + } + } + return false; + } + + @Override + public int[] getIds() { + return new int[] { 6808 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/BloatedLeechNPC.java b/Server/src/main/content/global/skill/summoning/familiar/BloatedLeechNPC.java new file mode 100644 index 0000000..8dfb2ef --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/BloatedLeechNPC.java @@ -0,0 +1,62 @@ +package content.global.skill.summoning.familiar; + +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.combat.ImpactHandler.HitsplatType; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.player.Player; +import core.tools.RandomFunction; + +import static core.api.ContentAPIKt.*; + +/** + * Represents the Bloated Leech familiar. + * @author Aero + */ +@Initializable +public class BloatedLeechNPC extends Familiar { + + /** + * Constructs a new {@code BloatedLeechNPC} {@code Object}. + */ + public BloatedLeechNPC() { + this(null, 6843); + } + + /** + * Constructs a new {@code BloatedLeechNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public BloatedLeechNPC(Player owner, int id) { + super(owner, id, 3400, 12061, 6, WeaponInterface.STYLE_ACCURATE); + } + + @Override + public Familiar construct(Player owner, int id) { + return new BloatedLeechNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + curePoison(owner); + removeTimer(owner, "disease"); + for (int i = 0; i < Skills.SKILL_NAME.length; i++) { + if (owner.getSkills().getLevel(i) < owner.getSkills().getStaticLevel(i)) { + owner.getSkills().updateLevel( + i, + (int) Math.ceil(owner.getSkills().getStaticLevel(i) * 0.2), + owner.getSkills().getStaticLevel(i) + ); + } + } + owner.getImpactHandler().manualHit(owner, RandomFunction.random(1, 5), HitsplatType.NORMAL); + return true; + } + + @Override + public int[] getIds() { + return new int[] { 6843, 6844 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/BullAntNPC.java b/Server/src/main/content/global/skill/summoning/familiar/BullAntNPC.java new file mode 100644 index 0000000..46e4be3 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/BullAntNPC.java @@ -0,0 +1,60 @@ +package content.global.skill.summoning.familiar; + +import core.game.node.entity.skill.Skills; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.player.Player; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.game.world.update.flag.context.Graphics; + +/** + * Represents the Bull Ant familiar. + * @author Aero + */ +@Initializable +public class BullAntNPC extends BurdenBeast { + + /** + * Constructs a new {@code BullAntNPC} {@code Object}. + */ + public BullAntNPC() { + this(null, 6867); + } + + /** + * Constructs a new {@code BullAntNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public BullAntNPC(Player owner, int id) { + super(owner, id, 3000, 12087, 12, 9, WeaponInterface.STYLE_CONTROLLED); + } + + @Override + public Familiar construct(Player owner, int id) { + return new BullAntNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + if (owner.getSettings().getRunEnergy() >= 100) { + owner.getPacketDispatch().sendMessage("You already have full run energy."); + return false; + } + int amount = owner.getSkills().getStaticLevel(Skills.AGILITY) / 2; + visualize(Animation.create(7896), Graphics.create(1382)); + owner.getSettings().updateRunEnergy(-amount); + return true; + } + + @Override + public void visualizeSpecialMove() { + owner.visualize(new Animation(7660), new Graphics(1296)); + } + + @Override + public int[] getIds() { + return new int[] { 6867, 6868 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/BunyipNPC.java b/Server/src/main/content/global/skill/summoning/familiar/BunyipNPC.java new file mode 100644 index 0000000..df1c54e --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/BunyipNPC.java @@ -0,0 +1,162 @@ +package content.global.skill.summoning.familiar; + +import core.game.node.entity.combat.ImpactHandler; +import core.game.consumable.Consumable; +import content.data.consumables.Consumables; +import core.game.node.entity.skill.Skills; +import content.global.skill.cooking.CookableItems; +import content.global.skill.fishing.Fish; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.GameWorld; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Plugin; +import core.plugin.Initializable; +import core.tools.RandomFunction; + +/** + * Represents the Bunyip familiar. + * @author Aero + * @author Vexia + */ +@Initializable +public class BunyipNPC extends Familiar { + + /** + * The fish. + */ + private static final int[] FISH = new int[] { 317, 327, 3150, 345, 321, 353, 335, 341, 349, 3379, 331, 5004, 359, 10138, 5001, 377, 363, 371, 2148, 7944, 3142, 383, 395, 389, 401, 405, 407 }; + + /** + * The time since the last heal. + */ + private int lastHeal; + + /** + * Constructs a new {@code BunyipNPC} {@code Object}. + */ + public BunyipNPC() { + this(null, 6813); + } + + /** + * Constructs a new {@code BunyipNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public BunyipNPC(Player owner, int id) { + super(owner, id, 4400, 12029, 3, WeaponInterface.STYLE_ACCURATE); + setLastHeal(); + } + + @Override + public Familiar construct(Player owner, int id) { + return new BunyipNPC(owner, id); + } + + @Override + public void tick() { + super.tick(); + if (lastHeal < GameWorld.getTicks()) { + setLastHeal(); + owner.graphics(Graphics.create(1507), 1); + // Since https://runescape.wiki/w/Bunyip?oldid=391088 (2008-04-02) + // "The bunyip will automatically heal two hitpoints approximately every 15 seconds up to a player's maximum." + // Since https://runescape.wiki/w/Bunyip?oldid=400848 (2008-04-06) + // "The healing effect of the Bunyip can restore up to 352 hitpoints over its summoning duration of 44 minutes." + // Numbers were multiplied by 10 with the constitution update on 2010-03-10 (https://runescape.wiki/w/Bunyip?oldid=2345672) + owner.getSkills().heal(2); + } + } + + @Override + public boolean isPoisonImmune() { + return true; + } + + /** + * Sets the last heal. + */ + public void setLastHeal() { + this.lastHeal = GameWorld.getTicks() + (int) (15 / 0.6); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + Fish fish = Fish.forItem(special.getItem()); + Player player = owner; + if (fish == null) { + player.sendMessage("You can't use this special on an object like that."); + return false; + } + Consumable consumable = Consumables.getConsumableById(special.getItem().getId() + 2).getConsumable(); + if (consumable == null) { + player.sendMessage("Error: Report to admin."); + return false; + } + if (player.getSkills().getLevel(Skills.COOKING) < CookableItems.forId(special.getItem().getId()).level) { + player.sendMessage("You need a Cooking level of at least " + CookableItems.forId(special.getItem().getId()).level + " in order to do that."); + return false; + } + if (player.getInventory().remove(special.getItem())) { + animate(Animation.create(7747)); + graphics(Graphics.create(1481)); + final int healthEffectValue = consumable.getHealthEffectValue(player); + if (healthEffectValue > 0) { + owner.getSkills().heal(consumable.getHealthEffectValue(player)); + } else { + owner.getImpactHandler().manualHit(player, healthEffectValue, ImpactHandler.HitsplatType.NORMAL); + } + } + return true; + } + + @Override + public void visualizeSpecialMove() { + owner.visualize(Animation.create(7660), Graphics.create(1316)); + } + + @Override + protected void handleFamiliarTick() { + } + + @Override + protected void configureFamiliar() { + UseWithHandler.addHandler(6813, UseWithHandler.NPC_TYPE, new UseWithHandler(FISH) { + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(6814, UseWithHandler.NPC_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + Player player = event.getPlayer(); + Fish fish = Fish.forItem(event.getUsedItem()); + Consumable consumable = Consumables.getConsumableById(fish.getItem().getId() + 2).getConsumable(); + if (consumable == null) { + return true; + } + player.lock(1); + Item runes = new Item(555, RandomFunction.random(1, consumable.getHealthEffectValue(player))); + if (player.getInventory().remove(event.getUsedItem())) { + player.animate(Animation.create(2779)); + Projectile.create(player, event.getUsedWith().asNpc(), 1435).send(); + player.getInventory().add(runes); + player.sendMessage("The bunyip transmutes the fish into some water runes."); + } + return true; + } + }); + } + + @Override + public int[] getIds() { + return new int[] { 6813, 6814 }; + } +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/BurdenBeast.java b/Server/src/main/content/global/skill/summoning/familiar/BurdenBeast.java new file mode 100644 index 0000000..d6a3100 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/BurdenBeast.java @@ -0,0 +1,212 @@ +package content.global.skill.summoning.familiar; + +import core.game.component.CloseEvent; +import core.game.component.Component; +import core.game.container.Container; +import core.game.container.access.InterfaceContainer; +import core.game.system.config.ItemConfigParser; +import content.global.skill.summoning.SummoningPouch; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItem; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +/** + * Represents a beast of burden familiar. + * @author Emperor + */ +public abstract class BurdenBeast extends Familiar { + + /** + * The container. + */ + protected Container container; + + /** + * Constructs a new {@code BurdenBeast} {@code Object}. + * @param owner The owner. + * @param id The NPC id. + * @param ticks The amount of ticks. + * @param pouchId The pouch id. + * @param specialCost The special move cost. + * @param containerSize The container size. + * @param attackStyle the style. + */ + public BurdenBeast(Player owner, int id, int ticks, int pouchId, int specialCost, int containerSize, int attackStyle) { + super(owner, id, ticks, pouchId, specialCost, attackStyle); + this.container = new Container(containerSize).register(new BurdenContainerListener(owner)); + } + + /** + * Constructs a new {@code BurdenBeast} {@code Object}. + * @param owner The owner. + * @param id The NPC id. + * @param ticks The amount of ticks. + * @param pouchId The pouch id. + * @param specialCost The special move cost. + * @param containerSize The container size. + */ + public BurdenBeast(Player owner, int id, int ticks, int pouchId, int specialCost, int containerSize) { + this(owner, id, ticks, pouchId, specialCost, containerSize, WeaponInterface.STYLE_DEFENSIVE); + } + + @Override + public void dismiss() { + if (owner.getInterfaceManager().hasMainComponent(671)) { + owner.getInterfaceManager().close(); + } + + for (Item item : container.toArray()) { + if (item != null) { + GroundItemManager.create(new GroundItem(item, location, 500, owner)); + } + } + + container.clear(); + super.dismiss(); + } + + @Override + public boolean isBurdenBeast() { + return true; + } + + @Override + public boolean isPoisonImmune() { + return true; + } + + /** + * Checks if the item is allowed to be stored. + * @param owner The owner. + * @param item The item to store. + * @return {@code True} if so. + */ + public boolean isAllowed(Player owner, Item item) { + if (item.getValue() > 50000) { + owner.getPacketDispatch().sendMessage("This item is too valuable to trust to this familiar."); + return false; + } + if (!item.getDefinition().isTradeable()) { + owner.getPacketDispatch().sendMessage("You can't trade this item, not even to your familiar."); + return false; + } + if ((!SummoningPouch.get(getPouchId()).abyssal && (item.getId() == 1436 || item.getId() == 7936))|| !item.getDefinition().getConfiguration(ItemConfigParser.BANKABLE, true)) { + owner.getPacketDispatch().sendMessage("You can't store " + item.getName().toLowerCase() + " in this familiar."); + return false; + } + if(SummoningPouch.get(this.getPouchId()).abyssal){ + if(!item.getName().toLowerCase().contains("essence")) { + owner.getPacketDispatch().sendMessage("You can only give unnoted essence to this familiar."); + return false; + } + if(item.getId() == 1437 || item.getId() == 7937) { + owner.getPacketDispatch().sendMessage("You can't give noted essence to this familiar."); + return false; + } + } + return true; + } + + /** + * Transfers an item. + * @param item The item to store. + * @param amount The amount to store. + * @param withdraw If the player is withdrawing. + */ + public void transfer(Item item, int amount, boolean withdraw) { + if (this instanceof Forager && !withdraw) { + owner.getPacketDispatch().sendMessage("You can't store your items in this familiar."); + return; + } + if (item == null || owner == null) { + return; + } + if (!withdraw && !isAllowed(owner, new Item(item.getId(), item.getDefinition().isStackable() ? amount : 1))) { + return; + } + Container to = withdraw ? owner.getInventory() : container; + Container from = withdraw ? container : owner.getInventory(); + int fromAmount = from.getAmount(item); + if (amount > fromAmount) { + amount = fromAmount; + } + int maximum = to.getMaximumAdd(item); + if (amount > maximum) { + amount = maximum; + } + if (amount < 1) { + if (withdraw) { + owner.getPacketDispatch().sendMessage("Not enough space in your inventory."); + } else { + owner.getPacketDispatch().sendMessage("Your familiar can't carry any more items."); + } + return; + } + if (!item.getDefinition().isStackable() && item.getSlot() > -1) { + from.replace(null, item.getSlot()); + to.add(new Item(item.getId(), 1)); + amount--; + } + if (amount > 0) { + item = new Item(item.getId(), amount); + if (from.remove(item)) { + to.add(item); + } + } + } + + /** + * Withdraws the full container. + */ + public void withdrawAll() { + for (int i = 0; i < container.capacity(); i++) { + Item item = container.get(i); + if (item == null) { + continue; + } + int amount = owner.getInventory().getMaximumAdd(item); + if (item.getAmount() > amount) { + item = new Item(item.getId(), amount); + container.remove(item, false); + owner.getInventory().add(item, false); + } else { + container.replace(null, i, false); + owner.getInventory().add(item, false); + } + } + container.update(); + owner.getInventory().update(); + } + + /** + * Opens the beast of burden interface. + */ + public void openInterface() { + if (getContainer().itemCount() == 0 && this instanceof Forager) { + owner.getPacketDispatch().sendMessage("Your familiar is not carrying any items that you can withdraw."); + return; + } + owner.getInterfaceManager().open(new Component(671)).setCloseEvent(new CloseEvent() { + @Override + public boolean close(Player player, Component c) { + player.getInterfaceManager().closeSingleTab(); + return true; + } + }); + container.shift(); + owner.getInterfaceManager().openSingleTab(new Component(665)); + InterfaceContainer.generateItems(owner, owner.getInventory().toArray(), new String[] { "Examine", "Store-X", "Store-All", "Store-10", "Store-5", "Store-1" }, 665, 0, 7, 4, 93); + InterfaceContainer.generateItems(owner, container.toArray(), new String[] { "Examine", "Withdraw-X", "Withdraw-All", "Withdraw-10", "Withdraw-5", "Withdraw-1" }, 671, 27, 5, 6, 30); + container.refresh(); + } + + /** + * Gets the item container. + * @return The container. + */ + public Container getContainer() { + return container; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/BurdenContainerListener.java b/Server/src/main/content/global/skill/summoning/familiar/BurdenContainerListener.java new file mode 100644 index 0000000..4856fd7 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/BurdenContainerListener.java @@ -0,0 +1,40 @@ +package content.global.skill.summoning.familiar; + +import core.game.container.Container; +import core.game.container.ContainerEvent; +import core.game.container.ContainerListener; +import core.game.node.entity.player.Player; +import core.net.packet.PacketRepository; +import core.net.packet.context.ContainerContext; +import core.net.packet.out.ContainerPacket; + +/** + * The beast of burden container listener. + * @author Emperor + */ +public final class BurdenContainerListener implements ContainerListener { + + /** + * The player. + */ + private final Player player; + + /** + * Constructs a new {@code BurdenContainerListener} {@code Object}. + * @param player The player. + */ + public BurdenContainerListener(Player player) { + this.player = player; + } + + @Override + public void update(Container c, ContainerEvent event) { + PacketRepository.send(ContainerPacket.class, new ContainerContext(player, -1, -2, 30, event.getItems(), false, event.getSlots())); + } + + @Override + public void refresh(Container c) { + PacketRepository.send(ContainerPacket.class, new ContainerContext(player, -1, -2, 30, c.toArray(), c.capacity(), false)); + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/summoning/familiar/BurdenInterfacePlugin.java b/Server/src/main/content/global/skill/summoning/familiar/BurdenInterfacePlugin.java new file mode 100644 index 0000000..f9a8fd1 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/BurdenInterfacePlugin.java @@ -0,0 +1,70 @@ +package content.global.skill.summoning.familiar; + +import static core.api.ContentAPIKt.*; +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.container.Container; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.Plugin; +import kotlin.Unit; + +/** + * Handles the beast of burden interface. + * @author Emperor + */ +@Initializable +public final class BurdenInterfacePlugin extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.put(665, this); + ComponentDefinition.put(671, this); + return this; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + if (!player.getFamiliarManager().hasFamiliar() || !player.getFamiliarManager().getFamiliar().isBurdenBeast()) { + return false; + } + final BurdenBeast beast = (BurdenBeast) player.getFamiliarManager().getFamiliar(); + final boolean withdraw = component.getId() == 671; + final Container container = withdraw ? beast.getContainer() : player.getInventory(); + final Item item = slot >= 0 && slot < container.capacity() ? container.get(slot) : null; + if (item == null && button != 29) { + return true; + } + switch (opcode) { + case 155: + if (button == 29) { + beast.withdrawAll(); + return true; + } + beast.transfer(item, 1, withdraw); + return true; + case 196: + beast.transfer(item, 5, withdraw); + return true; + case 124: + beast.transfer(item, 10, withdraw); + return true; + case 199: + beast.transfer(item, container.getAmount(item), withdraw); + return true; + case 234: + sendInputDialogue(player, true, "Enter the amount:", (value) -> { + beast.transfer(item, (int) value, withdraw); + return Unit.INSTANCE; + }); + break; + case 168: + player.getPacketDispatch().sendMessage(item.getDefinition().getExamine()); + return true; + } + return false; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/CockatriceFamiliarNPC.java b/Server/src/main/content/global/skill/summoning/familiar/CockatriceFamiliarNPC.java new file mode 100644 index 0000000..02564d7 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/CockatriceFamiliarNPC.java @@ -0,0 +1,344 @@ +package content.global.skill.summoning.familiar; + +import core.game.node.entity.skill.Skills; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Plugin; +import core.plugin.Initializable; +import core.plugin.ClassScanner; + +/** + * Handles the loading of a cockatrice familiar. + * @author Vexia + */ +@Initializable +public final class CockatriceFamiliarNPC implements Plugin { + + /** + * The cockatrice egg. + */ + private static final Item COCKATRICE_EGG = new Item(12109); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ClassScanner.definePlugin(new SpiritCockatrice()); + ClassScanner.definePlugin(new SpiritGuthatrice()); + ClassScanner.definePlugin(new SpiritZamatrice()); + ClassScanner.definePlugin(new SpiritPengatrice()); + ClassScanner.definePlugin(new SpiritCoraxatrice()); + ClassScanner.definePlugin(new SpiritVulatrice()); + ClassScanner.definePlugin(new SpiritSaratrice()); + return this; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + /** + * Handles a petrified gaze. + * @param familiar the familiar. + * @param special the special. + * @return {@code True} if so. + */ + public boolean petrifyingGaze(final Familiar familiar, final FamiliarSpecial special, final int skill) { + final Entity target = special.getTarget(); + if (!familiar.canCombatSpecial(target)) { + return false; + } + familiar.faceTemporary(target, 2); + familiar.visualize(Animation.create(7762), Graphics.create(1467)); + GameWorld.getPulser().submit(new Pulse(1, familiar.getOwner(), familiar, target) { + @Override + public boolean pulse() { + if(skill == 5) { + target.skills.decrementPrayerPoints(3); + }else { + target.getSkills().updateLevel(skill, -3, 0); + } + Projectile.magic(familiar, target, 1468, 40, 36, 71, 10).send(); + familiar.sendFamiliarHit(target, 10, Graphics.create(1469)); + return true; + } + }); + return true; + } + + /** + * Handles the spirit cockatrice. + * @author Vexia + */ + public final class SpiritCockatrice extends Forager { + + /** + * Constructs a new {@code SpiritCockatrice} {@code Object}. + */ + public SpiritCockatrice() { + this(null, 6875); + } + + /** + * Constructs a new {@code SpiritCockatrice} {@code Object}. + * @param owner the owner. + * @param id the id. + */ + public SpiritCockatrice(Player owner, int id) { + super(owner, id, 3600, 12095, 3, WeaponInterface.STYLE_CAST, COCKATRICE_EGG); + } + + @Override + public Familiar construct(Player owner, int id) { + return new SpiritCockatrice(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + return petrifyingGaze(this, special, Skills.DEFENCE); + } + + @Override + public int[] getIds() { + return new int[] { 6875, 6876 }; + } + + } + + /** + * Handles the spirit guthatrice. + * @author Vexia + */ + public class SpiritGuthatrice extends Forager { + + /** + * Constructs a new {@code SpiritGuthatrice} {@code Object}. + */ + public SpiritGuthatrice() { + this(null, 6877); + } + + /** + * Constructs a new {@code SpiritGuthatrice} {@code Object}. + * @param owner the owner. + * @param id the id. + */ + public SpiritGuthatrice(Player owner, int id) { + super(owner, id, 3600, 12097, 3, WeaponInterface.STYLE_CAST, COCKATRICE_EGG); + } + + @Override + public Familiar construct(Player owner, int id) { + return new SpiritGuthatrice(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + return petrifyingGaze(this, special, Skills.ATTACK); + } + + @Override + public int[] getIds() { + return new int[] { 6877, 6878 }; + } + } + + /** + * Handles the spirit zamatrice. + * @author Vexia + */ + public class SpiritZamatrice extends Forager { + + /** + * Constructs a new {@code SpiritZamatrice} {@code Object}. + */ + public SpiritZamatrice() { + this(null, 6881); + } + + /** + * Constructs a new {@code SpiritZamatrice} {@code Object}. + * @param owner the owner. + * @param id the id. + */ + public SpiritZamatrice(Player owner, int id) { + super(owner, id, 3600, 12101, 3, WeaponInterface.STYLE_CAST, COCKATRICE_EGG); + } + + @Override + public Familiar construct(Player owner, int id) { + return new SpiritZamatrice(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + return petrifyingGaze(this, special, Skills.STRENGTH); + } + + @Override + public int[] getIds() { + return new int[] { 6881, 6882 }; + } + } + + /** + * Handles the spirit pengatrice. + * @author Vexia + */ + public class SpiritPengatrice extends Forager { + + /** + * Constructs a new {@code SpiritPengatrice} {@code Object}. + */ + public SpiritPengatrice() { + this(null, 6883); + } + + /** + * Constructs a new {@code SpiritPengatrice} {@code Object}. + * @param owner the owner. + * @param id the id. + */ + public SpiritPengatrice(Player owner, int id) { + super(owner, id, 3600, 12103, 3, WeaponInterface.STYLE_CAST, COCKATRICE_EGG); + } + + @Override + public Familiar construct(Player owner, int id) { + return new SpiritPengatrice(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + return petrifyingGaze(this, special, Skills.MAGIC); + } + + @Override + public int[] getIds() { + return new int[] { 6883, 6884 }; + } + } + + /** + * Represents the Spirit Coraxatrice familiar. + * @author Aero + */ + public class SpiritCoraxatrice extends Forager { + + /** + * Constructs a new {@code SpiritCoraxatriceNPC} {@code Object}. + */ + public SpiritCoraxatrice() { + this(null, 6885); + } + + /** + * Constructs a new {@code SpiritCoraxatriceNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public SpiritCoraxatrice(Player owner, int id) { + super(owner, id, 3600, 12105, 3, WeaponInterface.STYLE_CAST, COCKATRICE_EGG); + } + + @Override + public Familiar construct(Player owner, int id) { + return new SpiritCoraxatrice(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + return petrifyingGaze(this, special, Skills.SUMMONING); + } + + @Override + public int[] getIds() { + return new int[] { 6885, 6886 }; + } + + } + + /** + * Represents the Spirit Vulatrice familiar. + * @author Aero + */ + public class SpiritVulatrice extends Forager { + + /** + * Constructs a new {@code SpiritVulatriceNPC} {@code Object}. + */ + public SpiritVulatrice() { + this(null, 6887); + } + + /** + * Constructs a new {@code SpiritVulatriceNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public SpiritVulatrice(Player owner, int id) { + super(owner, id, 3600, 12107, 3, WeaponInterface.STYLE_CAST, COCKATRICE_EGG); + } + + @Override + public Familiar construct(Player owner, int id) { + return new SpiritVulatrice(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + return petrifyingGaze(this, special, Skills.RANGE); + } + + @Override + public int[] getIds() { + return new int[] { 6887, 6888 }; + } + + } + + /** + * Represents the Spirit Saratrice familiar. + * @author Aero - DeadlyGenga + */ + public class SpiritSaratrice extends Forager { + + /** + * Constructs a new {@code SpiritSaratriceNPC} {@code Object}. + */ + public SpiritSaratrice() { + this(null, 6879); + } + + /** + * Constructs a new {@code SpiritSaratriceNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public SpiritSaratrice(Player owner, int id) { + super(owner, id, 3600, 12099, 3, WeaponInterface.STYLE_CAST, COCKATRICE_EGG); + } + + @Override + public Familiar construct(Player owner, int id) { + return new SpiritSaratrice(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + return petrifyingGaze(this, special, Skills.PRAYER); + } + + @Override + public int[] getIds() { + return new int[] { 6879, 6880 }; + } + + } +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/CompostMoundNPC.java b/Server/src/main/content/global/skill/summoning/familiar/CompostMoundNPC.java new file mode 100644 index 0000000..77aae4d --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/CompostMoundNPC.java @@ -0,0 +1,228 @@ +package content.global.skill.summoning.familiar; + +import content.global.skill.farming.CompostBin; +import content.global.skill.farming.CompostBins; +import core.game.dialogue.DialogueInterpreter; +import core.game.dialogue.DialoguePlugin; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.combat.ImpactHandler.HitsplatType; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.player.Player; +import core.game.node.entity.skill.Skills; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.tools.RandomFunction; +import org.rs09.consts.Items; +import core.plugin.ClassScanner; + +/** + * Represents the Compost Mound familiar. + * @author Vexia + * @author Aero + */ +@Initializable +public class CompostMoundNPC extends Forager { + + /** + * The product items. + */ + private static final Item[] ITEMS = new Item[] { new Item(6032), new Item(6034), new Item(5318), new Item(5319), new Item(5324), new Item(5322), new Item(5320), new Item(5323), new Item(5321), new Item(5305), new Item(5307), new Item(5308), new Item(5306), new Item(5309), new Item(5310), new Item(5311), new Item(5101), new Item(5102), new Item(5103), new Item(5104), new Item(5105), new Item(5106), new Item(5096), new Item(5097), new Item(5098), new Item(5099), new Item(5100), new Item(5291), new Item(5292), new Item(5293), new Item(5294), new Item(5295), new Item(12176), new Item(5296), new Item(5298), new Item(5299), new Item(5300), new Item(5301), new Item(5302), new Item(5303), new Item(5304) }; + + /** + * Constructs a new {@code CompostMoundNPC} {@code Object}. + */ + public CompostMoundNPC() { + this(null, 6871); + } + + /** + * Constructs a new {@code CompostMoundNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public CompostMoundNPC(Player owner, int id) { + super(owner, id, 2400, 12091, 12, WeaponInterface.STYLE_AGGRESSIVE, ITEMS); + } + + @Override + public Familiar construct(Player owner, int id) { + return new CompostMoundNPC(owner, id); + } + + @Override + public void configureFamiliar() { + ClassScanner.definePlugin(new CompostBucketPlugin()); + if (!DialogueInterpreter.contains(getIds()[1])) { + ClassScanner.definePlugin(new CompostMoundDialogue()); + } + } + + @Override + public boolean isPoisonImmune() { + return true; + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + final Scenery object = (Scenery) special.getNode(); + if (!object.getName().equals("Compost Bin")) { + owner.getPacketDispatch().sendMessage("This scroll can only be used on an empty compost bin."); + return false; + } + CompostBins cbin = CompostBins.forObject(special.getNode().asScenery()); + if(cbin == null){ + return false; + } + CompostBin bin = cbin.getBinForPlayer(owner); + if(bin.isFinished() || bin.isFull() || bin.isClosed()){ + return false; + } + final boolean superCompost = RandomFunction.random(10) == 1; + faceLocation(object.getLocation()); + Item toAdd = new Item(superCompost ? Items.PINEAPPLE_2114 : Items.POTATO_1942); + toAdd.setAmount(15); + bin.addItem(toAdd); + bin.close(); + animate(Animation.create(7775)); + graphics(Graphics.create(1424)); + return true; + } + + @Override + public int[] getIds() { + return new int[] { 6871, 6872 }; + } + + /** + * The compost bucket plugin. + * @author Vexia + * @version 1.0 + */ + public class CompostBucketPlugin extends UseWithHandler { + + /** + * Constructs a new {@code CompostBucketPlugin} {@code Object}. + */ + public CompostBucketPlugin() { + super(1925); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(6871, NPC_TYPE, this); + addHandler(6872, NPC_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + final Familiar familiar = (Familiar) event.getUsedWith(); + if (!player.getFamiliarManager().isOwner(familiar)) { + return true; + } + player.animate(Animation.create(895)); + familiar.animate(Animation.create(7775)); + player.getInventory().replace(ITEMS[0], event.getUsedItem().getSlot()); + familiar.getImpactHandler().manualHit(player, 2, HitsplatType.NORMAL); + return true; + } + + } + + /** + * The compost dialogue. + * @author Vexia + * @version 1.0 + */ + public class CompostMoundDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code CompostDialogue} {@code Object}. + */ + public CompostMoundDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code CompostDialogue} {@code Object}. + * @param player the player. + */ + public CompostMoundDialogue(final Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new CompostMoundDialogue(player); + } + + @Override + public boolean open(Object... args) { + options("Chat", "Withdraw", "Farming boost"); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + switch (buttonId) { + case 1: + npc("Schlorp, splort, splort, splutter shclorp?", "(What we be doin' 'ere, zur?)"); + stage = 10; + break; + case 2: + end(); + Forager forager = (Forager) player.getFamiliarManager().getFamiliar(); + forager.openInterface(); + break; + case 3: + player("Can you boost my Farming stat, please?"); + stage = 30; + break; + } + break; + case 10: + player("Oh, I have a few things to take care of here, is all."); + stage++; + break; + case 11: + npc("Schorp, splutter, splutter. Schlup schorp.", "(Aye, right ye are, zur. Oi'll be roight there.)"); + stage++; + break; + case 12: + end(); + break; + case 30: + npc("Schlup glorp sputter!", "(Oi do believe oi can!)"); + stage++; + break; + case 31: + if (player.getSkills().getLevel(Skills.FARMING) > player.getSkills().getStaticLevel(Skills.FARMING)) { + end(); + player.getPacketDispatch().sendMessage("Your stat cannot be boosted this way right now."); + return true; + } + player.getSkills().updateLevel(Skills.FARMING, (int) (1 + (player.getSkills().getStaticLevel(Skills.FARMING) * 0.02))); + player.getPacketDispatch().sendMessage("The Compost mound has boosted your Farming stat."); + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return CompostMoundNPC.this.getIds(); + } + + } +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/DesertWyrmNPC.java b/Server/src/main/content/global/skill/summoning/familiar/DesertWyrmNPC.java new file mode 100644 index 0000000..0510469 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/DesertWyrmNPC.java @@ -0,0 +1,163 @@ +package content.global.skill.summoning.familiar; + +import java.util.ArrayList; +import java.util.List; + +import content.global.skill.gather.mining.MiningNode; +import core.cache.def.impl.NPCDefinition; +import core.plugin.Initializable; +import core.game.node.entity.skill.SkillBonus; +import core.game.node.entity.skill.Skills; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Plugin; +import core.plugin.ClassScanner; + +/** + * Represents the Desert Wyrm familiar. + * @author Vexia + * @author Aero + */ +@Initializable +public final class DesertWyrmNPC extends Forager { + + /** + * Constructs a new {@code DesertWyrmNPC} {@code Object}. + */ + public DesertWyrmNPC() { + this(null, 6831); + } + + /** + * Constructs a new {@code DesertWyrmNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public DesertWyrmNPC(Player owner, int id) { + super(owner, id, 1900, 12049, 6, WeaponInterface.STYLE_AGGRESSIVE); + boosts.add(new SkillBonus(Skills.MINING, 1)); + } + + @Override + public Familiar construct(Player owner, int id) { + return new DesertWyrmNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + final Entity target = (Entity) special.getNode(); + if (!canCombatSpecial(target)) { + return false; + } + faceTemporary((Entity) special.getNode(), 2); + visualize(new Animation(7795), new Graphics(1410)); + Projectile.magic(this, target, 1411, 40, 36, 51, 10).send(); + sendFamiliarHit(target, 5); + return true; + } + + @Override + public void configureFamiliar() { + ClassScanner.definePlugin(new OptionHandler() { + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (int i : getIds()) { + NPCDefinition.forId(i).getHandlers().put("option:burrow", this); + } + return this; + } + + @Override + public boolean handle(final Player player, final Node node, String option) { + final Scenery rock = getClosestRock(player); + if (!player.getFamiliarManager().isOwner((Familiar) node)) { + return true; + } + if (((NPC) node).getLocks().isMovementLocked()) { + return true; + } + if (rock == null) { + player.getPacketDispatch().sendMessage("There are no rocks around here for the desert wyrm to mine from!"); + return true; + } + final MiningNode resource = MiningNode.forId(rock.getId()); + if (resource == null) { + player.getPacketDispatch().sendMessage("There are no rocks around here for the desert wyrm to mine from!"); + return true; + } + final Familiar familiar = (Familiar) node; + player.lock(9); + familiar.lock(8); + familiar.visualize(new Animation(7800), new Graphics(1412)); + GameWorld.getPulser().submit(new Pulse(1, player, familiar) { + int counter; + + @Override + public boolean pulse() { + switch (++counter) { + case 4: + familiar.setInvisible(true); + break; + case 8: + familiar.call(); + GroundItemManager.create(new Item(resource.getReward()), familiar.getLocation(), player); + return true; + } + return false; + } + }); + return true; + } + + /** + * Gets the closest combat rock. + * @return the object. + */ + public Scenery getClosestRock(Player player) { + List rocks = new ArrayList<>(20); + for (int k = 0; k < 7; k++) { + for (int i = 0; i < 4; i++) { + Direction dir = Direction.get(i); + Location loc = player.getLocation().transform(dir.getStepX() * k, dir.getStepY() * k, 0); + Scenery object = RegionManager.getObject(loc); + if (object != null && object.getName().equals("Rocks")) { + rocks.add(object); + } + } + } + int ordinal = 0; + Scenery o = null; + for (Scenery r : rocks) { + MiningNode resource = MiningNode.forId(r.getId()); + if (resource != null && MiningNode.SILVER_ORE_0.ordinal() > resource.ordinal() && resource.ordinal() > ordinal) { + ordinal = resource.ordinal(); + o = r; + } + } + return o; + } + + }); + } + + @Override + public int[] getIds() { + return new int[] { 6831, 6832 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/DismissDialoguePlugin.java b/Server/src/main/content/global/skill/summoning/familiar/DismissDialoguePlugin.java new file mode 100644 index 0000000..b369bf4 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/DismissDialoguePlugin.java @@ -0,0 +1,81 @@ +package content.global.skill.summoning.familiar; + +import core.game.dialogue.DialogueInterpreter; +import core.game.dialogue.DialoguePlugin; +import core.plugin.Initializable; +import content.global.skill.summoning.pet.Pet; +import core.game.node.entity.player.Player; + +/** + * Represents the dialogue plugin used to dismiss a follower. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class DismissDialoguePlugin extends DialoguePlugin { + + /** + * Constructs a new {@code DismissDialoguePlugin} {@code Object}. + */ + public DismissDialoguePlugin() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code DismissDialoguePlugin} {@code Object}. + * @param player the player. + */ + public DismissDialoguePlugin(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new DismissDialoguePlugin(player); + } + + @Override + public boolean open(Object... args) { + if (player.getFamiliarManager().getFamiliar() instanceof Pet) { + interpreter.sendOptions("Free pet", "Yes", "No"); + } else { + interpreter.sendOptions("Dismiss Familiar", "Yes", "No"); + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + switch (buttonId) { + case 1: + if (player.getFamiliarManager().getFamiliar() instanceof Pet) { + interpreter.sendDialogues(player, null, "Run along; I'm setting you free."); + Pet pet = (Pet) player.getFamiliarManager().getFamiliar(); + player.getFamiliarManager().removeDetails(pet.getItemId()); + } else { + end(); + } + player.getFamiliarManager().dismiss(); + stage = 1; + break; + case 2: + end(); + break; + } + break; + case 1: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { DialogueInterpreter.getDialogueKey("dismiss_dial") }; + } +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/DreadfowlNPC.java b/Server/src/main/content/global/skill/summoning/familiar/DreadfowlNPC.java new file mode 100644 index 0000000..857048c --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/DreadfowlNPC.java @@ -0,0 +1,124 @@ +package content.global.skill.summoning.familiar; + +import core.plugin.Initializable; +import core.game.node.entity.skill.SkillBonus; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.node.entity.combat.InteractionType; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.combat.MeleeSwingHandler; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.tools.RandomFunction; + +/** + * Represents the dreadfowl familiar. + * @author Emperor + */ +@Initializable +public final class DreadfowlNPC extends Familiar { + + /** + * If the special move is toggled. + */ + private boolean specialMove; + + /** + * The combat handler. + */ + private static final CombatSwingHandler COMBAT_HANDLER = new MeleeSwingHandler() { + + @Override + public InteractionType canSwing(Entity entity, Entity victim) { + if (((DreadfowlNPC) entity).specialMove) { + return CombatStyle.MAGIC.getSwingHandler().canSwing(entity, victim); + } + return super.canSwing(entity, victim); + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + DreadfowlNPC npc = (DreadfowlNPC) entity; + if (npc.specialMove) { + npc.specialMove(new FamiliarSpecial(victim)); + npc.specialMove = false; + return -1; + } + npc.specialMove = RandomFunction.randomize(10) == 0; + return super.swing(entity, victim, state); + } + + }; + + /** + * Constructs a new {@code DreadfowlNPC} {@code Object}. + */ + public DreadfowlNPC() { + this(null, 6825); + } + + /** + * Constructs a new {@code DreadfowlNPC} {@code Object}. + * @param owner The owner. + * @param id The NPC id. + */ + public DreadfowlNPC(Player owner, int id) { + super(owner, id, 400, 12043, 3, WeaponInterface.STYLE_CAST); + super.setCombatHandler(COMBAT_HANDLER); + boosts.add(new SkillBonus(Skills.FARMING, 1)); + } + + @Override + public Familiar construct(Player owner, int id) { + return new DreadfowlNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + final Entity target = (Entity) special.getNode(); + if (!canAttack(target)) { + return false; + } + if (!owner.getProperties().getCombatPulse().isAttacking() && !owner.inCombat()) { + owner.getPacketDispatch().sendMessage("Your familiar can only attack when you're in combat."); + return false; + } + if (getProperties().getCombatPulse().getNextAttack() > GameWorld.getTicks() || CombatStyle.MAGIC.getSwingHandler().canSwing(this, target) == InteractionType.NO_INTERACT) { + specialMove = true; + getProperties().getCombatPulse().attack(target); + return true; + } + visualize(new Animation(5387, Priority.HIGH), Graphics.create(1523)); + Projectile.magic(this, target, 1318, 40, 36, 51, 10).send(); + int ticks = 2 + (int) Math.floor(getLocation().getDistance(target.getLocation()) * 0.5); + getProperties().getCombatPulse().setNextAttack(4); + GameWorld.getPulser().submit(new Pulse(ticks, this, target) { + @Override + public boolean pulse() { + BattleState state = new BattleState(DreadfowlNPC.this, target); + int hit = 0; + if (CombatStyle.MAGIC.getSwingHandler().isAccurateImpact(DreadfowlNPC.this, target)) { + hit = RandomFunction.randomize(3); + } + state.setEstimatedHit(hit); + target.getImpactHandler().handleImpact(owner, hit, CombatStyle.MAGIC, state); + return true; + } + }); + return true; + } + + @Override + public int[] getIds() { + return new int[] { 6825, 6826 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/ElementalTitanNPC.java b/Server/src/main/content/global/skill/summoning/familiar/ElementalTitanNPC.java new file mode 100644 index 0000000..bfebc39 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/ElementalTitanNPC.java @@ -0,0 +1,39 @@ +package content.global.skill.summoning.familiar; + +import core.game.node.entity.player.Player; +import core.game.node.entity.skill.Skills; +import content.global.skill.summoning.familiar.Familiar; +import content.global.skill.summoning.familiar.FamiliarSpecial; + +public abstract class ElementalTitanNPC extends Familiar { + + private static final int scrollHealAmount = 8; + private static final double scrollDefenceBoostPercent = 0.125; + + public ElementalTitanNPC(Player owner, int id, int ticks, int pouchId, int specialCost, int attackStyle) { + super(owner, id, ticks, pouchId, specialCost, attackStyle); + } + + /** + raises defence by 12.5% and heals 8 hp (with ability to over heal) + */ + @Override + protected boolean specialMove(FamiliarSpecial special) { + int currentDefenceLevel = owner.getSkills().getLevel(Skills.DEFENCE); + int maximumDefenceLevel = owner.getSkills().getStaticLevel(Skills.DEFENCE); + owner.getSkills().updateLevel(Skills.DEFENCE, + (int)((1.0 + scrollDefenceBoostPercent) * currentDefenceLevel), + (int)((1.0 + scrollDefenceBoostPercent) * maximumDefenceLevel)); + int currentHp = owner.getSkills().getLifepoints(); + int maxHp = owner.getSkills().getMaximumLifepoints() + scrollHealAmount; + int healAmount = Math.min(maxHp - currentHp, scrollHealAmount); + if (healAmount> 0) { + owner.getSkills().healNoRestrictions(healAmount); + return true; + } + else { + owner.sendMessage("You are already at maximum hitpoints!"); + return false; + } + } +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/EvilTurnipNPC.java b/Server/src/main/content/global/skill/summoning/familiar/EvilTurnipNPC.java new file mode 100644 index 0000000..0d6de51 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/EvilTurnipNPC.java @@ -0,0 +1,74 @@ +package content.global.skill.summoning.familiar; + +import core.game.node.entity.skill.Skills; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.game.world.update.flag.context.Graphics; + +/** + * Represents the Evil Turnip familiar. + * @author Aero + * @author Vexia + */ +@Initializable +public class EvilTurnipNPC extends Forager { + + /** + * The evil turnip item. + */ + private static final Item EVIL_TURNIP = new Item(12136); + + /** + * Constructs a new {@code EvilTurnipNPC} {@code Object}. + */ + public EvilTurnipNPC() { + this(null, 6833); + } + + /** + * Constructs a new {@code EvilTurnipNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public EvilTurnipNPC(Player owner, int id) { + super(owner, id, 3000, 12051, 6, WeaponInterface.STYLE_RANGE_ACCURATE, EVIL_TURNIP); + } + + @Override + public Familiar construct(Player owner, int id) { + return new EvilTurnipNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + final Entity target = (Entity) special.getNode(); + if (!canCombatSpecial(target)) { + return false; + } + int ticks = 2 + (int) Math.floor(getLocation().getDistance(target.getLocation()) * 0.5); + getSkills().heal(2); + faceTemporary(target, 2); + sendFamiliarHit(target, 10); + animate(Animation.create(8251)); + target.graphics(Graphics.create(1329), ticks); + target.getSkills().updateLevel(Skills.MAGIC, -1, 0); + Projectile.magic(this, target, 1330, 40, 36, 51, 10).send(); + return true; + } + + @Override + public int getRandom() { + return 20; + } + + @Override + public int[] getIds() { + return new int[] { 6833, 6834 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/Familiar.java b/Server/src/main/content/global/skill/summoning/familiar/Familiar.java new file mode 100644 index 0000000..b85c1ec --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/Familiar.java @@ -0,0 +1,819 @@ +package content.global.skill.summoning.familiar; + +import content.global.skill.summoning.SummoningScroll; +import content.global.skill.summoning.pet.Pet; +import core.cache.def.impl.NPCDefinition; +import core.game.interaction.MovementPulse; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.impl.PulseType; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.skill.SkillBonus; +import core.game.node.entity.skill.Skills; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.map.path.Pathfinder; +import core.game.world.map.zone.ZoneRestriction; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Plugin; +import core.tools.Log; +import core.tools.RandomFunction; +import core.game.node.entity.combat.CombatPulse; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.world.GameWorld; +import content.global.skill.summoning.SummoningPouch; +import org.rs09.consts.Sounds; + +import java.util.ArrayList; +import java.util.List; + +import static core.api.ContentAPIKt.*; + +/** + * Represents a familiar. + * @author Emperor + */ +public abstract class Familiar extends NPC implements Plugin { + + /** + * The summon graphics for a small familiar. + */ + protected static final Graphics SMALL_SUMMON_GRAPHIC = Graphics.create(1314); + + /** + * The spawn graphics for a large familiar. + */ + protected static final Graphics LARGE_SUMMON_GRAPHIC = Graphics.create(1315); + + /** + * The special animation. + */ + protected static final Animation SPECIAL_ANIMATION = Animation.create(7660); + + /** + * The special graphic. + */ + protected static final Graphics SPECIAL_GRAPHIC = Graphics.create(1316); + + /** + * The owner. + */ + protected Player owner; + + /** + * The amount of ticks left. + */ + protected int ticks; + + /** + * The initial amount of ticks. + */ + protected int maximumTicks; + + /** + * The amount of special points left. + */ + protected int specialPoints = 60; + + /** + * The pouch id. + */ + private final int pouchId; + + /** + * The special move cost. + */ + private final int specialCost; + + private final SummoningPouch pouch; + + /** + * The combat reward. + */ + private CombatSwingHandler combatHandler; + + /** + * If the familiar is a combat familiar. + */ + protected boolean combatFamiliar; + + /** + * If the familiars special is charged. + */ + protected boolean charged; + + /** + * The invisible familiar boosts. + */ + protected List boosts = new ArrayList<>(20); + + /** + * The attack style. + */ + private final int attackStyle; + + /** + * The amount of points to drain every tick. + * This is a constant depending on the familiar's level req and time remaining (GL #1903). + * https://runescape.wiki/w/Summoning_points?oldid=2171795: "Over the life of the familiar, the number of summoning + * points drained will be equal to the level required to summon the familiar (unless you run out of summoning + * points). This means that if a player summons a bunyip with 75 Summoning points remaining, 7 points will be + * drained immediately, and 61 more will be drained over the life the bunyip, for a total of 68 points (the level of + * the bunyip)." + */ + private final double pointsPerTick; + + /** + * Keeps track of the fractional pointsPerTick that have been drained already. If >1.0, drain a point and subtract + * 1.0. Note that this means that we will never drain a point on the final tick (unless pointsPerTick turned out to + * be integer, but this case is handled by the 'ticks > 0' check in handleTickActions()). This is intentional; it + * allows us to, correctly, artificially extend the interval by one so that the drain events are evenly spaced + * throughout the lifetime of the summon (refer to the dreadfowl example below). + */ + private double fracDrain = 0.0; + + /** + * Whether this is the first call (i.e. not a renew summon). + */ + private boolean firstCall = true; + + /** + * Constructs a new {@code Familiar} {@code Object}. + * @param owner The owner. + * @param id The NPC id. + * @param ticks The ticks left. + * @param pouchId The pouch. + * @param specialCost The special move cost. + * @param attackStyle the style. + */ + public Familiar(Player owner, int id, int ticks, int pouchId, int specialCost, final int attackStyle) { + super(id, null); + this.owner = owner; + this.maximumTicks = ticks; + this.ticks = ticks; + this.pouchId = pouchId; + this.pouch = SummoningPouch.get(pouchId); + this.specialCost = specialCost; + this.combatFamiliar = NPCDefinition.forId(getOriginalId() + 1).getName().equals(getName()); + this.attackStyle = attackStyle; + /* The initial points are drained on summon. Then, the remaining points are drained over an interval. + * To prevent the last point from being drained only very late, we artificially extend the interval by one. + * Example: a dreadfowl drains 1 point on summon, and then needs to drain 3 points over 400 ticks. Naively + * draining a point on ticks 133, 266, and 399 allows players to save a point at the expense of just one tick. + * Instead, we drain on ticks 100, 200, and 300. + * Example 2: a spirit tz-kih drains 3 points on summon, then needs to drain 19 more points over 1800 ticks. + * This means it needs to drain a point every 90 ticks, since the 0th tick remaining will not drain. + * Example 3: a vampire bat needs to drain 27 points over 3300 ticks. It hence drains a point every ~118 ticks. + * Example 4: an abyssal titan drains 10 points on summon, then needs to drain 83 more points over 3200 ticks. + * This means it needs to drain a point every ~34 ticks. + */ + if (pouchId == -1) { + this.pointsPerTick = 0.0; + } else { + int drain = pouch.getLevelRequired() - pouch.getSummonCost() + 1; + this.pointsPerTick = (double) drain / maximumTicks; + } + } + + /** + * Constructs a new {@code Familiar} {@code Object}. + * @param owner The owner. + * @param id The NPC id. + * @param ticks The ticks left. + * @param pouchId The pouch. + * @param specialCost The special move cost. + */ + public Familiar(Player owner, int id, int ticks, int pouchId, int specialCost) { + this(owner, id, ticks, pouchId, specialCost, WeaponInterface.STYLE_DEFENSIVE); + } + + /** + * Creates the familiar. + * @param loc The location. + */ + public void init(Location loc, boolean call) { + location = loc; + if (location == null) { + location = owner.getLocation(); + setInvisible(true); + } + super.init(); + startFollowing(); + sendConfiguration(); + if (call) { + call(); + } + owner.getInterfaceManager().openInfoBars(); + if (getZoneMonitor().isInZone("Wilderness")) { + transform(); + } + } + + @Override + public void init() { + init(getSpawnLocation(), true); + } + + @Override + public void handleTickActions() { + ticks--; + fracDrain += pointsPerTick; + if (fracDrain > 1.0 && ticks > 0) { + fracDrain -= 1.0; + owner.getSkills().updateLevel(Skills.SUMMONING, -1, 0); + } + if (ticks % 50 == 0) { + updateSpecialPoints(-15); + if (!getText().isEmpty()) { + super.sendChat(getText()); + } + } + sendTimeRemaining(); + switch (ticks) { + case 100: + owner.getPacketDispatch().sendMessage("You have 1 minute before your familiar vanishes."); + break; + case 50: + owner.getPacketDispatch().sendMessage("You have 30 seconds before your familiar vanishes."); + break; + case 0: + if (isBurdenBeast() && !((BurdenBeast) this).getContainer().isEmpty()) { + owner.getPacketDispatch().sendMessage("Your familiar has dropped all the items it was holding."); + } else { + owner.getPacketDispatch().sendMessage("Your familiar has vanished."); + } + dismiss(); + return; + } + CombatPulse combat = owner.getProperties().getCombatPulse(); + if (!isInvisible() && !getProperties().getCombatPulse().isAttacking() && (combat.isAttacking() || owner.inCombat())) { + Entity victim = combat.getVictim(); + if (victim == null) { + victim = owner.getAttribute("combat-attacker"); + } + if (combat.getVictim() != this && victim != null && !victim.isInvisible() && getProperties().isMultiZone() && owner.getProperties().isMultiZone() && isCombatFamiliar() && !isBurdenBeast() && !isPeacefulFamiliar()) { + getProperties().getCombatPulse().attack(victim); + } + } + if ((!isInvisible() && owner.getLocation().getDistance(getLocation()) > 12) || (isInvisible() && ticks % 25 == 0)) { + if (!call()) { + setInvisible(true); + } + } else if (!getPulseManager().hasPulseRunning()) { + startFollowing(); + } + handleFamiliarTick(); + } + + @Override + public boolean isAttackable(Entity entity, CombatStyle style, boolean message) { + if (entity == owner) { + if (message) { + owner.getPacketDispatch().sendMessage("You can't just betray your own familiar like that!"); + } + return false; + } + if (entity instanceof Player) { + if (!owner.isAttackable(entity, style, message)) { + return false; + } + } + if (!getProperties().isMultiZone()) { + if (entity instanceof Player && !((Player) entity).getProperties().isMultiZone()) { + if (message) { + ((Player) entity).getPacketDispatch().sendMessage("You have to be in multicombat to attack a player's familiar."); + } + return false; + } + if (entity instanceof Player) { + if (message) { + ((Player) entity).getPacketDispatch().sendMessage("This familiar is not in the a multicombat zone."); + } + } + return false; + } + if (entity instanceof Player) { + if (!((Player) entity).getSkullManager().isWilderness()) { + if (message) { + ((Player) entity).getPacketDispatch().sendMessage("You have to be in the wilderness to attack a player's familiar."); + } + return false; + } + if (!owner.getSkullManager().isWilderness()) { + if (message) { + ((Player) entity).getPacketDispatch().sendMessage("This familiar's owner is not in the wilderness."); + } + return false; + } + } + return super.isAttackable(entity, style, message); + } + + @Override + public void onRegionInactivity() { + call(); + } + + @Override + public CombatSwingHandler getSwingHandler(boolean swing) { + if (combatHandler != null) { + return combatHandler; + } + return super.getSwingHandler(swing); + } + + /** + * Constructs a new {@code Familiar} {@code Object}. + * @param owner The owner. + * @param id The NPC id. + * @return The familiar. + */ + public abstract Familiar construct(Player owner, int id); + + /** + * Executes the special move. + * @param special The familiar special object. + * @return {@code True} if the move was executed. + */ + protected abstract boolean specialMove(FamiliarSpecial special); + + /** + * Handles the familiar special tick. + */ + protected void handleFamiliarTick() { + } + + /** + * Configures use with events, and other plugin related content.. + */ + protected void configureFamiliar() { + + } + + /** + * Gets the forced chat text for this familiar. + * @return The forced chat text. + */ + protected String getText() { + return ""; + } + + /** + * Transforms the familiar into the Wilderness combat form. + */ + public void transform() { + if (isCombatFamiliar()) { + transform(getOriginalId() + 1); + } + } + + public void refreshTimer() { + ticks = maximumTicks; + } + + /** + * Sends the time remaining. + */ + private void sendTimeRemaining() { + int minutes = ticks / 100; + int centiminutes = ticks % 100; + setVarbit(owner, 4534, minutes); + setVarbit(owner, 4290, centiminutes > 49 ? 1 : 0); + } + + /** + * Checks if the familiar can execute its special move and does so if able. + * @param special The familiar special object. + */ + public boolean executeSpecialMove(FamiliarSpecial special) { + if (special.getNode() == this) { + return false; + } + if (specialCost > specialPoints) { + owner.getPacketDispatch().sendMessage("Your familiar does not have enough special move points left."); + return false; + } + SummoningScroll scroll = SummoningScroll.forPouch(pouchId); + if (scroll == null) { + owner.getPacketDispatch().sendMessage("Invalid scroll for pouch " + pouchId + " - report!"); + return false; + } + if (!owner.getInventory().contains(scroll.getItemId(), 1)) { + owner.getPacketDispatch().sendMessage("You do not have enough scrolls left to do this special move."); + return false; + } + if (owner.getLocation().getDistance(getLocation()) > 15) { + owner.getPacketDispatch().sendMessage("Your familiar is too far away to use that scroll, or it cannot see you."); + return false; + } + if (specialMove(special)) { + setAttribute("special-delay", GameWorld.getTicks() + 3); + owner.getInventory().remove(new Item(scroll.getItemId())); + playAudio(owner, Sounds.SPELL_4161); + visualizeSpecialMove(); + updateSpecialPoints(specialCost); + owner.getSkills().addExperience(Skills.SUMMONING, scroll.getExperience(), true); + } + return true; + } + + /** + * Sends the special move visualization for the owner. + */ + public void visualizeSpecialMove() { + owner.visualize(Animation.create(7660), Graphics.create(1316)); + } + + /** + * Sends a familiar hit. + * @param target the target. + * @param maxHit the max hit. + * @param graphics the graphics. + */ + public void sendFamiliarHit(final Entity target, final int maxHit, final Graphics graphics) { + final int ticks = 2 + (int) Math.floor(getLocation().getDistance(target.getLocation()) * 0.5); + getProperties().getCombatPulse().setNextAttack(4); + GameWorld.getPulser().submit(new Pulse(ticks, this, target) { + @Override + public boolean pulse() { + BattleState state = new BattleState(Familiar.this, target); + int hit = 0; + if (getCombatStyle().getSwingHandler().isAccurateImpact(Familiar.this, target)) { + hit = RandomFunction.randomize(maxHit); + } + state.setEstimatedHit(hit); + target.getImpactHandler().handleImpact(owner, hit, CombatStyle.MELEE, state); + if (graphics != null) { + target.graphics(graphics); + } + return true; + } + }); + } + + /** + * Sends a projectile to the target. + * @param target the target. + * @param projectileId the projectile id. + */ + public void projectile(final Entity target, final int projectileId) { + Projectile.magic(this, target, projectileId, 40, 36, 51, 10).send(); + } + + /** + * Sends a familiar hit. + * @param maxHit the max hit. + */ + public void sendFamiliarHit(final Entity target, final int maxHit) { + sendFamiliarHit(target, maxHit, null); + } + + /** + * Checks if this familiar can attack the target (used mainly for special + * moves). + */ + public boolean canAttack(Entity target, boolean message) { + if (!target.isAttackable(owner, owner.getProperties().getCombatPulse().getStyle(), true)) { + return false; + } + if (target.getLocation().getDistance(getLocation()) > 8) { + if (message) { + owner.getPacketDispatch().sendMessage("That target is too far."); + } + return false; + } + if (target.getLocks().isInteractionLocked() || !target.isAttackable(this, CombatStyle.MAGIC, true)) { + return false; + } + return isCombatFamiliar(); + } + + @Override + public boolean canAttack(Entity target) { + return canAttack(target, true); + } + + /** + * Checks if a familiar can perform a combat special attack. + * @param target the target. + * @param message show message. + * @return {@code True} if so. + */ + public boolean canCombatSpecial(Entity target, boolean message) { + if (!canAttack(target, message)) { + return false; + } + if (!isOwnerAttackable()) { + return false; + } + if (getAttribute("special-delay", 0) > GameWorld.getTicks()) { + return false; + } + return true; + } + + /** + * Checks if a faimiliar can perform a combat special attack. + * @param target the target. + * @return {@code True} if so. + */ + public boolean canCombatSpecial(Entity target) { + return canCombatSpecial(target, true); + } + + /** + * Checks if the owner is attackable. + * @return {@code True} if so. + */ + public boolean isOwnerAttackable() { + if (!owner.getProperties().getCombatPulse().isAttacking() && !owner.inCombat() && !getProperties().getCombatPulse().isAttacking()) { + owner.getPacketDispatch().sendMessage("Your familiar cannot fight whilst you are not in combat."); + return false; + } + return true; + } + + /** + * Gets the combat style. + * @return the style. + */ + public CombatStyle getCombatStyle() { + return CombatStyle.MAGIC; + } + + /** + * Adjusts a players battle state. + * @param state the state. + */ + public void adjustPlayerBattle(final BattleState state) { + + } + + /** + * Starts following the owner. + */ + public void startFollowing() { + getPulseManager().run(new MovementPulse(this, owner, Pathfinder.DUMB) { + @Override + public boolean pulse() { + return false; + } + }, PulseType.STANDARD); + face(owner); + } + + @Override + public void finalizeDeath(Entity killer) { + dismiss(); + } + + /** + * Checks if the familiar is a combat familiar. + * @return {@code True} if so. + */ + public boolean isCombatFamiliar() { + return combatFamiliar; + } + + /** + * Sends the familiar packets. + */ + public void sendConfiguration() { + setVarp(owner, 448, getPouchId()); + setVarp(owner, 1174, getOriginalId()); + setVarp(owner, 1175, specialCost << 23); + sendTimeRemaining(); + updateSpecialPoints(0); + } + + /** + * Calls the familiar. + */ + //int spamTimer = 0; + public boolean call() { + Location destination = getSpawnLocation(); + if (destination == null) { + //owner.getPacketDispatch().sendMessage("Your familiar is too big to fit here. Try calling it again when you are standing"); + //owner.getPacketDispatch().sendMessage("somewhere with more space."); + //spamTimer = 50; + return false; + } + setInvisible(owner.getZoneMonitor().isRestricted(ZoneRestriction.FOLLOWERS) && !owner.getLocks().isLocked("enable_summoning")); + if (isInvisible()) return true; + getProperties().setTeleportLocation(destination); + if (!(this instanceof Pet)) { + if (firstCall) { + // TODO: Each familiar has its own initial summon sound that needs to be implemented at some point + playAudio(owner, Sounds.SUMMON_NPC_188); + firstCall = false; + } else { + playAudio(owner, Sounds.SUMMON_NPC_188); + } + if (size() > 1) { + graphics(LARGE_SUMMON_GRAPHIC); + } else { + graphics(SMALL_SUMMON_GRAPHIC); + } + } + if (getProperties().getCombatPulse().isAttacking()) { + startFollowing(); + } else { + face(owner); + } + if (!isRenderable() && owner.isActive()) { + // log(this.getClass(), Log.ERR, "Familiar in inactive region!"); + getWalkingQueue().update(); + getUpdateMasks().prepare(this); + } + return true; + } + + /** + * Gets the spawning location of the familiar. + * @return The spawn location. + */ + public Location getSpawnLocation() { + return RegionManager.getSpawnLocation(owner, this); + } + + /** + * Dismisses the familiar. + */ + public void dismiss() { + clear(); + getPulseManager().clear(); + owner.getInterfaceManager().removeTabs(7); + owner.getFamiliarManager().setFamiliar(null); + setVarp(owner, 448, -1); + setVarp(owner, 1176, 0); + setVarp(owner, 1175, 182986); + setVarp(owner, 1174, -1); + owner.getAppearance().sync(); + owner.getInterfaceManager().setViewedTab(3); + } + + /** + * Updates the special move points. + * @param diff The difference to decrease with. + */ + public void updateSpecialPoints(int diff) { + specialPoints -= diff; + if (specialPoints > 60) { + specialPoints = 60; + } + setVarp(owner, 1177, specialPoints); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (int id : getIds()) { + if (FamiliarManager.getFamiliars().containsKey(id)) { + log(this.getClass(), Log.ERR, "Familiar " + id + " was already registered!"); + return null; + } + FamiliarManager.getFamiliars().put(id, this); + configureFamiliar(); + } + return this; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + /** + * Gets the charged. + * @return The charged. + */ + public boolean isCharged() { + if (charged) { + owner.getPacketDispatch().sendMessage("Your familiar is already charging its attack!"); + return true; + } + return false; + } + + /** + * Gets a familiar boost. + * @param skill the skill. + * @return the boost. + */ + public int getBoost(int skill) { + SkillBonus bonus = null; + for (SkillBonus b : boosts) { + if (b.getSkillId() == skill) { + bonus = b; + break; + } + } + if (bonus == null) { + return 0; + } + return (int) bonus.getBonus(); + } + + /** + * Charges a familiar. + */ + public void charge() { + setCharged(true); + } + + /** + * Sets the charged. + * @param charged The charged to set. + */ + public void setCharged(boolean charged) { + this.charged = charged; + } + + /** + * Checks if the familiar is a beast of burden. + * @return {@code True} if so. + */ + public boolean isBurdenBeast() { + return false; + } + + public boolean isPeacefulFamiliar() { + return pouch.getPeaceful(); + } + + /** + * Gets the NPC ids. + * @return The npc ids. + */ + public abstract int[] getIds(); + + /** + * Gets the pouch id. + * @return The pouch id. + */ + public int getPouchId() { + return pouchId; + } + + /** + * Gets the owner. + * @return The owner. + */ + public Player getOwner() { + return owner; + } + + /** + * Sets the owner. + * @param owner The owner to set. + */ + public void setOwner(Player owner) { + this.owner = owner; + } + + /** + * Gets the combatHandler. + * @return The combatHandler. + */ + public CombatSwingHandler getCombatHandler() { + return combatHandler; + } + + /** + * Sets the combatHandler. + * @param combatHandler The combatHandler to set. + */ + public void setCombatHandler(CombatSwingHandler combatHandler) { + this.combatHandler = combatHandler; + } + + /** + * Gets the view animation for remote viewing. + * @return the animation. + */ + public Animation getViewAnimation() { + return null; + } + + /** + * Gets the exp style. + * @return the style. + */ + public int getAttackStyle() { + return attackStyle; + } + + public int getTicks() { + return ticks; + } + + public int getSpecialPoints() { + return specialPoints; + } +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/FamiliarDialoguePlugin.java b/Server/src/main/content/global/skill/summoning/familiar/FamiliarDialoguePlugin.java new file mode 100644 index 0000000..563165e --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/FamiliarDialoguePlugin.java @@ -0,0 +1,148 @@ +package content.global.skill.summoning.familiar; + +import core.game.dialogue.DialoguePlugin; +import core.plugin.Initializable; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.tools.RandomFunction; + +/** + * Represents the dialogue plugin used for familiars. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class FamiliarDialoguePlugin extends DialoguePlugin { + + /** + * Constructs a new {@code FamiliarDialoguePlugin} {@code Object}. + */ + public FamiliarDialoguePlugin() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code FamiliarDialoguePlugin} {@code Object}. + * @param player the player. + */ + public FamiliarDialoguePlugin(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new FamiliarDialoguePlugin(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + if (!(npc instanceof Familiar)) { + return false; + } + final Familiar f = (Familiar) npc; + if (f.getOwner() != player) { + player.getPacketDispatch().sendMessage("This is not your follower."); + return true; + } + // if (f.getDetails().getType() == FamiliarType.PET) {TODO:Pet + // if (player.getSkills().getLevel(Skills.SUMMONING) < ((PetDetails) + // f.getDetails()).getPet().getSummoningLevel() + 10) { + // interpreter.sendDialogues(npc, null, "Grumble...!"); + // int lvl = ((PetDetails) f.getDetails()).getPet().getSummoningLevel() + // + 10; + // if (lvl > 99) { + // player.getPacketDispatch().sendMessage("It is impossible to talk to this pet.");//dragon, + // chamerelon, monket..etc + // return true; + // } + // player.getPacketDispatch().sendMessage("You need a summoning level of " + // + lvl + " in order to communicate with your pet."); + // stage = 99; + // return true; + // } + // } + stage = RandomFunction.random(1, 3); + switch (stage) { + case 1: + interpreter.sendDialogues(npc, null, "Are we going to be walking all day?"); + stage = 1; + break; + case 2: + interpreter.sendDialogues(npc, null, "Yer lookin' tired. You should have a nap."); + stage = 20; + break; + case 3: + interpreter.sendDialogues(npc, null, "I could do wi' a cup of tea, mind."); + stage = 30; + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 1:// random first. + interpreter.sendDialogues(player, null, "Well, I could carry you if you like."); + stage = 10; + break; + case 10: + interpreter.sendDialogues(npc, null, "That would be great!"); + stage = 11; + break; + case 11: + interpreter.sendDialogues(player, null, "You know, you won't grow up to be big and strong", "if you keep getting carried everywhere."); + stage = 12; + break; + case 12: + interpreter.sendDialogues(npc, null, "I know, I know."); + stage = 99; + break; + case 2:// random second dial. + interpreter.sendDialogues(npc, null, "Yer lookin' tired. You should have a nap."); + stage = 20; + break; + case 20: + interpreter.sendDialogues(player, null, "Is it me who needs a rest or you?"); + stage = 21; + break; + case 21: + interpreter.sendDialogues(npc, null, "Well, if you took one, I might too..."); + stage = 22; + break; + case 22: + interpreter.sendDialogues(player, null, "Yeah, I thought as much."); + stage = 23; + break; + case 23: + interpreter.sendDialogues(npc, null, "Grumble..."); + stage = 99; + break; + case 3:// random third dial. + interpreter.sendDialogues(npc, null, "I could do wi' a cup of tea, mind."); + stage = 30; + break; + case 30: + interpreter.sendDialogues(player, null, "I don't know if a cup of tea would be good for you."); + stage = 31; + break; + case 31: + interpreter.sendDialogues(npc, null, "Fair 'nuff, then."); + stage = 99; + break; + case 99: + end(); + player.getFamiliarManager().getFamiliar().startFollowing(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 761, 762, 763, 764, 765, 766, 3505, 3598, 6969, 7259, 7260, 6964, 7249, 7251, 6960, 7241, 7243, 6962, 7245, 7247, 6966, 7253, 7255, 6958, 7237, 7239, 6915, 7277, 7278, 7279, 7280, 7018, 7019, 7020, 6908, 7313, 7316, 6947, 7293, 7295, 7297, 7299, 6911, 7261, 7263, 7265, 7267, 7269, 6919, 7301, 7303, 7305, 7307, 6949, 6952, 6955, 6913, 7271, 7273, 6945, 7319, 7321, 7323, 7325, 7327, 6922, 6942, 7210, 7212, 7214, 7216, 7218, 7220, 7222, 7224, 7226, 6900, 6902, 6904, 6906, 768, 769, 770, 771, 772, 773, 3504, 8214, 6968, 7257, 7258, 6965, 7250, 7252, 6961, 7242, 7244, 6963, 7246, 7248, 6967, 7254, 7256, 6859, 7238, 7240, 6916, 7281, 7282, 7283, 7284, 7015, 7016, 7017, 6909, 7314, 7317, 11413, 6948, 7294, 7296, 7298, 7300, 6912, 7262, 7264, 7266, 7268, 7270, 6920, 7302, 7304, 7306, 7308, 6950, 6953, 6956, 6914, 7272, 7274, 13090, 6946, 7320, 7322, 7324, 7326, 7328, 6923, 6943, 7211, 7213, 7215, 7217, 7219, 7221, 7223, 7225, 7227, 6901, 6903, 6905, 6907, 774, 775, 776, 777, 778, 779, 3503, 8216, 6951, 6954, 6957 }; + } +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/FamiliarFeedPlugin.java b/Server/src/main/content/global/skill/summoning/familiar/FamiliarFeedPlugin.java new file mode 100644 index 0000000..74f73e4 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/FamiliarFeedPlugin.java @@ -0,0 +1,43 @@ +package content.global.skill.summoning.familiar; + +import content.global.skill.summoning.pet.Pet; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the class used to handle the feeding of pets. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class FamiliarFeedPlugin extends UseWithHandler { + + /** + * Constructs a new {@code FamiliarFeedPlugin} {@code Object}. + */ + public FamiliarFeedPlugin() { + super(321, 363, 341, 15264, 345, 377, 353, 389, 7944, 349, 331, 327, 395, 383, 317, 371, 335, 359, 15270, 1927, 321, 2132, 2134, 2136, 2138, 10816, 9986, 9978, 526, 1059, 225, 221, 592, 12125, 12127, 313, 12129, 2970, 1977, 12130, 13379, 1963, 319, 365, 339, 347, 379, 355, 391, 7946, 351, 329, 325, 397, 385, 315, 373, 333, 361, 1927); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + int[] ids = new int[] { 761, 762, 763, 764, 765, 766, 3505, 3598, 6969, 7259, 7260, 6964, 7249, 7251, 6960, 7241, 7243, 6962, 7245, 7247, 6966, 7253, 7255, 6958, 7237, 7239, 6915, 7277, 7278, 7279, 7280, 7018, 7019, 7020, 6908, 7313, 7316, 6947, 7293, 7295, 7297, 7299, 6911, 7261, 7263, 7265, 7267, 7269, 6919, 7301, 7303, 7305, 7307, 6949, 6952, 6955, 6913, 7271, 7273, 6945, 7319, 7321, 7323, 7325, 7327, 6922, 6942, 7210, 7212, 7214, 7216, 7218, 7220, 7222, 7224, 7226, 6900, 6902, 6904, 6906, 768, 769, 770, 771, 772, 773, 3504, 8214, 6968, 7257, 7258, 6965, 7250, 7252, 6961, 7242, 7244, 6963, 7246, 7248, 6967, 7254, 7256, 6859, 7238, 7240, 6916, 7281, 7282, 7283, 7284, 7015, 7016, 7017, 6909, 7314, 7317, 11413, 6948, 7294, 7296, 7298, 7300, 6912, 7262, 7264, 7266, 7268, 7270, 6920, 7302, 7304, 7306, 7308, 6950, 6953, 6956, 6914, 7272, 7274, 13090, 6946, 7320, 7322, 7324, 7326, 7328, 6923, 6943, 7211, 7213, 7215, 7217, 7219, 7221, 7223, 7225, 7227, 6901, 6903, 6905, 6907, 774, 775, 776, 777, 778, 779, 3503, 8216, 6951, 6954, 6957 }; + for (int i : ids) { + addHandler(i, NPC_TYPE, this); + } + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Familiar f = (Familiar) event.getUsedWith(); + if (!(f instanceof Pet)) { + return false; + } + event.getPlayer().getFamiliarManager().eat(event.getUsedItem().getId(), (Pet) f); + return true; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/FamiliarItemOptionPlugin.java b/Server/src/main/content/global/skill/summoning/familiar/FamiliarItemOptionPlugin.java new file mode 100644 index 0000000..7f9612c --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/FamiliarItemOptionPlugin.java @@ -0,0 +1,64 @@ +package content.global.skill.summoning.familiar; + +import content.global.skill.summoning.pet.Pets; +import core.cache.def.impl.ItemDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the familiar items option plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class FamiliarItemOptionPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (Pets p : Pets.values()) { + ItemDefinition def = ItemDefinition.forId(p.getBabyItemId()); + if (def == null) { + continue; + } + def.getHandlers().put("option:drop", this); + def.getHandlers().put("option:release", this); + if (p.getGrownItemId() > -1) { + ItemDefinition.forId(p.getGrownItemId()).getHandlers().put("option:drop", this); + ItemDefinition.forId(p.getGrownItemId()).getHandlers().put("option:release", this); + } + if (p.getOvergrownItemId() > -1) { + ItemDefinition.forId(p.getOvergrownItemId()).getHandlers().put("option:drop", this); + ItemDefinition.forId(p.getOvergrownItemId()).getHandlers().put("option:release", this); + } + } + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + switch (option) { + case "drop": + player.getFamiliarManager().summon(((Item) node), true); + return true; + case "release": + if (((Item) node).getId() == 7771) { + player.getFamiliarManager().summon(((Item) node), true); + return true; + } + if (player.getInventory().remove(((Item) node))) { + player.getDialogueInterpreter().sendDialogues(player, null, "Run along; I'm setting you free."); + } + return true; + } + return true; + } + + @Override + public boolean isWalk() { + return false; + } +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/FamiliarManager.java b/Server/src/main/content/global/skill/summoning/familiar/FamiliarManager.java new file mode 100644 index 0000000..888fa8f --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/FamiliarManager.java @@ -0,0 +1,525 @@ +package content.global.skill.summoning.familiar; + +import content.global.skill.summoning.pet.Pet; +import content.global.skill.summoning.pet.Pets; +import core.cache.def.impl.ItemDefinition; +import core.game.component.Component; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import core.game.node.entity.skill.Skills; +import content.global.skill.summoning.SummoningPouch; +import content.global.skill.summoning.pet.PetDetails; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.player.Player; + +import core.game.node.item.Item; +import core.game.world.map.Location; +import core.game.world.map.zone.ZoneRestriction; +import core.game.world.update.flag.context.Animation; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import static core.api.ContentAPIKt.*; + +/** + * Handles a player's familiar. + * @author Emperor + * @author Player Name + */ +public final class FamiliarManager { + + /** + * The familiars mapping. + */ + private static final Map FAMILIARS = new HashMap<>(); + + /** + * The pet details mapping. + */ + private final Map> petDetails = new HashMap<>(); + + /** + * The player. + */ + private final Player player; + + /** + * The familiar. + */ + private Familiar familiar; + + /** + * The combat level difference when using summoning. + */ + private int summoningCombatLevel; + + /** + * If the player has a summoning pouch. + */ + private boolean hasPouch; + + /** + * Constructs a new {@code FamiliarManager} {@code Object}. + * @param player The player. + */ + public FamiliarManager(Player player) { + this.player = player; + } + + public void parse(JSONObject familiarData) { + int currentPet = -1; + if (familiarData.containsKey("currentPet")) { + currentPet = Integer.parseInt(familiarData.get("currentPet").toString()); + } + if (player.version < 2) { //migrate the v1 format + for (Pets pet : Pets.values()) { + for (int id : new int[]{pet.getBabyItemId(), pet.getGrownItemId(), pet.getOvergrownItemId()}) { + if (id != -1) { + petDetails.put(id, new ArrayList()); + } + } + } + + JSONArray petDetails = (JSONArray) familiarData.get("petDetails"); + for (Object petDetail : petDetails) { + JSONObject detail = (JSONObject) petDetail; + PetDetails details = new PetDetails(0); + details.updateHunger(Double.parseDouble(detail.get("hunger").toString())); + details.updateGrowth(Double.parseDouble(detail.get("growth").toString())); + int itemId; + int itemIdHash = Integer.parseInt(detail.get("petId").toString()); + // The below is for migrating the v0 format, which stored baby item IDs + growth stages + if (detail.containsKey("stage")) { + // The itemIdHash is actually the baby item ID. The "stage" gives the actual pet stage we want. + int babyItemId = itemIdHash; + itemId = babyItemId; + int stage = Integer.parseInt(detail.get("stage").toString()); + if (stage > 0) { + Pets pets = Pets.forId(babyItemId); + itemId = pets.getNextStageItemId(itemId); + if (stage > 1) { + itemId = pets.getNextStageItemId(itemId); + } + } + } else { + itemId = itemIdHash >> 16 & 0xFFFF; //in the legacy v1 format, was hash rather than item id + } + this.petDetails.get(itemId).add(details); + } + if (currentPet > 65536) { + currentPet = currentPet >> 16 & 0xFFFF; //in the legacy v1 format, was hash rather than item id + } + } else { + JSONObject petDetails = (JSONObject) familiarData.get("petDetails"); + for (Object key : petDetails.keySet()) { + int itemId = Integer.parseInt(key.toString()); + this.petDetails.put(itemId, new ArrayList<>()); + JSONArray values = (JSONArray) petDetails.get(key.toString()); + for (Object petDetail : values) { + JSONObject detail = (JSONObject) petDetail; + PetDetails details = new PetDetails(0); + details.updateHunger(Double.parseDouble(detail.get("hunger").toString())); + details.updateGrowth(Double.parseDouble(detail.get("growth").toString())); + this.petDetails.get(itemId).add(details); + } + } + } + if (currentPet != -1) { + int last = this.petDetails.get(currentPet).size() - 1; + PetDetails details = this.petDetails.get(currentPet).get(last); + Pets pets = Pets.forId(currentPet); + familiar = new Pet(player, details, currentPet, pets.getNpcId(currentPet)); + } else if (familiarData.containsKey("familiar")) { + JSONObject currentFamiliar = (JSONObject) familiarData.get("familiar"); + int familiarId = Integer.parseInt( currentFamiliar.get("originalId").toString()); + familiar = FAMILIARS.get(familiarId).construct(player,familiarId); + familiar.ticks = Integer.parseInt( currentFamiliar.get("ticks").toString()); + familiar.specialPoints = Integer.parseInt( currentFamiliar.get("specialPoints").toString()); + JSONArray famInv = (JSONArray) currentFamiliar.get("inventory"); + if (famInv != null) { + ((BurdenBeast) familiar).container.parse(famInv); + } + familiar.setAttribute("hp",Integer.parseInt( currentFamiliar.get("lifepoints").toString())); + } + } + + /** + * Called when the player logs in. + */ + public void login() { + if (hasFamiliar()) { + familiar.init(); + } + player.getFamiliarManager().setConfig(243269632); + } + + /** + * Summons a familiar. + * @param item The item. + * @param pet If the familiar is a pet. + * @param deleteItem we should delete the item. + */ + public void summon(Item item, boolean pet, boolean deleteItem) { + boolean renew = false; + if (hasFamiliar()) { + if (familiar.getPouchId() == item.getId()) { + renew = true; + } else { + player.getPacketDispatch().sendMessage("You already have a follower."); + return; + } + } + if (player.getZoneMonitor().isRestricted(ZoneRestriction.FOLLOWERS) && !player.getLocks().isLocked("enable_summoning")) { + player.getPacketDispatch().sendMessage("This is a Summoning-free area."); + return; + } + if (pet) { + summonPet(item, deleteItem); + return; + } + final SummoningPouch pouch = SummoningPouch.get(item.getId()); + if (pouch == null) { + return; + } + if (player.getSkills().getStaticLevel(Skills.SUMMONING) < pouch.getLevelRequired()) { + player.getPacketDispatch().sendMessage("You need a Summoning level of " + pouch.getLevelRequired() + " to summon this familiar."); + return; + } + if (player.getSkills().getLevel(Skills.SUMMONING) < pouch.getSummonCost()) { + player.getPacketDispatch().sendMessage("You need at least " + pouch.getSummonCost() + " Summoning points to summon this familiar."); + return; + } + final int npcId = pouch.getNpcId(); + Familiar fam = !renew ? FAMILIARS.get(npcId) : familiar; + if (fam == null) { + player.getPacketDispatch().sendMessage("Invalid familiar " + npcId + " - report on 2009Scape GitLab"); + return; + } + if (!renew) { + fam = fam.construct(player, npcId); + if (fam.getSpawnLocation() == null) { + player.getPacketDispatch().sendMessage("The spirit in this pouch is too big to summon here. You will need to move to a larger"); + player.getPacketDispatch().sendMessage("area."); + return; + } + } + if (!player.getInventory().remove(item)) { + return; + } + player.getSkills().updateLevel(Skills.SUMMONING, -pouch.getSummonCost(), 0); + player.getSkills().addExperience(Skills.SUMMONING, pouch.getSummonExperience()); + if (!renew) { + familiar = fam; + spawnFamiliar(); + } else { + familiar.refreshTimer(); + } + player.getAppearance().sync(); + } + + /** + * Summons a familiar. + * @param item the item. + * @param pet the pet. + */ + public void summon(final Item item, boolean pet) { + summon(item, pet, true); + } + + /** + * Morphs a pet. + * @param item the item. + * @param deleteItem the item. + * @param location the location. + */ + public void morphPet(final Item item, boolean deleteItem, Location location, double hunger, double growth) { + int hasWarned = ((Pet) familiar).getHasWarned(); + familiar.dismiss(); + summonPet(item, deleteItem, true, location, hasWarned, hunger, growth); + } + + /** + * Summons a pet. + * @param item the item. + * @param deleteItem the item. + */ + private boolean summonPet(final Item item, boolean deleteItem) { + return summonPet(item, deleteItem, false, null, 0, -1, -1); + } + + /** + * Summons a pet. + * @param item the item. + * @param morph the pet. + */ + private boolean summonPet(final Item item, boolean deleteItem, boolean morph, Location location, int hasWarned, double hunger, double growth) { + final int itemId = item.getId(); + if (itemId > 8850 && itemId < 8900) { + return false; + } + Pets pets = Pets.forId(itemId); + if (pets == null) { + return false; + } + if (player.getSkills().getStaticLevel(Skills.SUMMONING) < pets.getSummoningLevel()) { + player.getDialogueInterpreter().sendDialogue("You need a summoning level of " + pets.getSummoningLevel() + " to summon this."); + return false; + } + if (!this.petDetails.containsKey(itemId)) { + petDetails.put(itemId, new ArrayList()); + } + int last = this.petDetails.get(itemId).size() - 1; + if (last < 0) { //new pet + last = 0; + PetDetails details = new PetDetails(pets.getGrowthRate() == 0.0 ? 100.0 : 0.0); + this.petDetails.get(itemId).add(details); + } + PetDetails details = this.petDetails.get(itemId).get(last); + int npcId = pets.getNpcId(itemId); + if (npcId > 0) { + familiar = new Pet(player, details, itemId, npcId); + ((Pet) familiar).setHasWarned(hasWarned); + if (hunger != -1) ((Pet) familiar).getDetails().setHunger(hunger); + if (growth != -1) ((Pet) familiar).getDetails().setGrowth(growth); + if (deleteItem) { + player.animate(new Animation(827)); + if (!player.getInventory().remove(item, true)) { + return false; + } + } + if (morph) { + morphFamiliar(location); + } else { + spawnFamiliar(); + } + return true; + } + return true; + } + + /** + * Morphs the current familiar. + * @param location the location. + */ + public void morphFamiliar(Location location) { + familiar.init(location, false); + player.getInterfaceManager().openTab(new Component(662)); + player.getInterfaceManager().setViewedTab(7); + } + + /** + * Spawns the current familiar. + */ + public void spawnFamiliar() { + familiar.init(); + player.getInterfaceManager().openTab(new Component(662)); + player.getInterfaceManager().setViewedTab(7); + } + + /** + * Makes the pet eat. + * @param foodId The food item id. + * @param npc The pet NPC. + */ + public void eat(int foodId, Pet npc) { + if (npc != familiar) { + player.getPacketDispatch().sendMessage("This isn't your pet!"); + return; + } + Pet pet = (Pet) familiar; + Pets pets = Pets.forId(pet.getItemId()); + if (pets == null) { + return; + } + for (int food : pets.getFood()) { + if (food == foodId) { + player.getInventory().remove(new Item(foodId)); + player.getPacketDispatch().sendMessage("Your pet happily eats the " + ItemDefinition.forId(food).getName() + "."); + player.animate(new Animation(827)); + npc.getDetails().updateHunger(-15.0); + return; + } + } + player.getPacketDispatch().sendMessage("Nothing interesting happens."); + } + + /** + * Picks up a pet. + */ + public void pickup() { + if (player.getInventory().freeSlots() == 0) { + player.getPacketDispatch().sendMessage("You don't have enough room in your inventory."); + return; + } + Pet pet = ((Pet) familiar); + if (player.getInventory().add(new Item(pet.getItemId()))) { + player.animate(Animation.create(827)); + player.getFamiliarManager().dismiss(); + } + } + + /** + * Adjusts the battle state. + * @param state the state. + */ + public void adjustBattleState(final BattleState state) { + if (!hasFamiliar()) { + return; + } + familiar.adjustPlayerBattle(state); + } + + /** + * Gets a boost from a familiar. + * @param skill the skill. + * @return the boosted level. + */ + public int getBoost(int skill) { + if (!hasFamiliar()) { + return 0; + } + return familiar.getBoost(skill); + } + + /** + * Checks if the player has an active familiar. + * @return {@code True} if so. + */ + public boolean hasFamiliar() { + return familiar != null; + } + + /** + * Checks if the player has an active familiar and is a pet. + * @return {@code True} if so. + */ + public boolean hasPet() { + return hasFamiliar() && familiar instanceof Pet; + } + + /** + * Dismisses the familiar. + */ + public void dismiss() { + if (hasFamiliar()) { + familiar.dismiss(); + } + } + + /** + * Adds pet details for a new pet to that pet's stack. + * @param itemId The item id of the pet. + * @param details The new pet details. + */ + public void addDetails(int itemId, PetDetails details) { + petDetails.get(itemId).add(details); + } + + /** + * Removes the details for this pet. + * @param itemId The item id of the pet. + */ + public void removeDetails(int itemId) { + int last = petDetails.get(itemId).size() - 1; + if (last >= 0) { + petDetails.get(itemId).remove(last); + } + } + + /** + * Checks if it's the owner of a familiar. + * @param familiar the familiar + * @return {@code True} if so. + */ + public boolean isOwner(Familiar familiar) { + if (!hasFamiliar()) { + return false; + } + if (this.familiar != familiar) { + player.getPacketDispatch().sendMessage("This is not your familiar."); + return false; + } + return true; + } + + /** + * Sets a config value. + * @param value the value. + */ + public void setConfig(int value) { + int current = getVarp(player, 1160); + int newVal = current + value; + setVarp(player, 1160, newVal); + } + + /** + * Gets the familiar. + * @return The familiar. + */ + public Familiar getFamiliar() { + return familiar; + } + + /** + * Sets the familiar. + * @param familiar The familiar to set. + */ + public void setFamiliar(Familiar familiar) { + this.familiar = familiar; + } + + /** + * Gets the familiars. + * @return The familiars. + */ + public static Map getFamiliars() { + return FAMILIARS; + } + + /** + * Gets the usingSummoning. + * @return The usingSummoning. + */ + public boolean isUsingSummoning() { + return hasPouch || (hasFamiliar() && !hasPet()); + } + + /** + * Gets the hasPouch. + * @return The hasPouch. + */ + public boolean isHasPouch() { + return hasPouch; + } + + /** + * Sets the hasPouch. + * @param hasPouch The hasPouch to set. + */ + public void setHasPouch(boolean hasPouch) { + this.hasPouch = hasPouch; + } + + /** + * Gets the summoningCombatLevel. + * @return The summoningCombatLevel. + */ + public int getSummoningCombatLevel() { + return summoningCombatLevel; + } + + /** + * Sets the summoningCombatLevel. + * @param summoningCombatLevel The summoningCombatLevel to set. + */ + public void setSummoningCombatLevel(int summoningCombatLevel) { + this.summoningCombatLevel = summoningCombatLevel; + } + + + public Map> getPetDetails() { + return petDetails; + } +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/FamiliarNPCOptionPlugin.java b/Server/src/main/content/global/skill/summoning/familiar/FamiliarNPCOptionPlugin.java new file mode 100644 index 0000000..6801931 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/FamiliarNPCOptionPlugin.java @@ -0,0 +1,62 @@ +package content.global.skill.summoning.familiar; + +import core.cache.def.impl.NPCDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the class used for handling the npc options of familiars. + * @author Emperor + * @author 'Vexia + * @version 2.0 + */ +@Initializable +public final class FamiliarNPCOptionPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + NPCDefinition.setOptionHandler("pick-up", this); + NPCDefinition.setOptionHandler("interact-with", this); + NPCDefinition.setOptionHandler("interact", this); + NPCDefinition.setOptionHandler("store", this); + NPCDefinition.setOptionHandler("withdraw", this); + return this; + } + + @Override + public boolean handle(final Player player, Node node, String option) { + if (!(node instanceof Familiar)) { + return false; + } + Familiar familiar = (Familiar) node; + if (familiar.getOwner() != player) { + player.getPacketDispatch().sendMessage("This is not your familiar."); + return true; + } + switch (option) { + case "pick-up": + player.faceLocation(familiar.getFaceLocation(player.getLocation())); + player.getFamiliarManager().pickup(); + break; + case "interact-with": + player.getDialogueInterpreter().open(343823); + break; + case "interact": + player.getDialogueInterpreter().open(node.getId(), node); + break; + case "store": + case "withdraw": + if (!familiar.isBurdenBeast()) { + player.getPacketDispatch().sendMessage("This is not a beast of burden."); + break; + } + ((BurdenBeast) familiar).openInterface(); + break; + } + return true; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/FamiliarSpecial.java b/Server/src/main/content/global/skill/summoning/familiar/FamiliarSpecial.java new file mode 100644 index 0000000..2aa0b81 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/FamiliarSpecial.java @@ -0,0 +1,127 @@ +package content.global.skill.summoning.familiar; + +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.item.Item; + +/** + * A class which represents a familiar special. + * @author Aero + */ +public class FamiliarSpecial { + + /** + * The node. + */ + private Node node; + + /** + * The interface id. + */ + private int interfaceID; + + /** + * The component. + */ + private int component; + + /** + * The item. + */ + private Item item; + + /** + * Constructs a new {@code FamiliarSpecial} {@code Object}. + * @param node The node. + */ + public FamiliarSpecial(Node node) { + this(node, -1, -1, null); + } + + /** + * Constructs a new {@code FamiliarSpecial} {@code Object}. + * @param node The node. + * @param interfaceID The interface id. + * @param component The component. + * @param item The item. + */ + public FamiliarSpecial(Node node, int interfaceID, int component, Item item) { + this.node = node; + this.interfaceID = interfaceID; + this.component = component; + this.item = item; + } + + /** + * Gets the node. + * @return The node. + */ + public Node getNode() { + return node; + } + + /** + * Sets the node. + * @param node The node to set. + */ + public void setNode(Node node) { + this.node = node; + } + + /** + * Gets the interfaceID. + * @return The interfaceID. + */ + public int getInterfaceID() { + return interfaceID; + } + + /** + * Sets the interfaceID. + * @param interfaceID The interfaceID to set. + */ + public void setInterfaceID(int interfaceID) { + this.interfaceID = interfaceID; + } + + /** + * Gets the component. + * @return The component. + */ + public int getComponent() { + return component; + } + + /** + * Sets the component. + * @param component The component to set. + */ + public void setComponent(int component) { + this.component = component; + } + + /** + * Gets the item. + * @return The item. + */ + public Item getItem() { + return item; + } + + /** + * Sets the item. + * @param item The item to set. + */ + public void setItem(Item item) { + this.item = item; + } + + /** + * Gets the target. + * @return the target. + */ + public Entity getTarget() { + return (Entity) node; + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/summoning/familiar/FireTitanNPC.java b/Server/src/main/content/global/skill/summoning/familiar/FireTitanNPC.java new file mode 100644 index 0000000..524ed9a --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/FireTitanNPC.java @@ -0,0 +1,40 @@ +package content.global.skill.summoning.familiar; + +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the Fire Titan familiar. + * @author Aero + */ +@Initializable +public class FireTitanNPC extends ElementalTitanNPC { + + /** + * Constructs a new {@code FireTitanNPC} {@code Object}. + */ + public FireTitanNPC() { + this(null, 7355); + } + + /** + * Constructs a new {@code FireTitanNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public FireTitanNPC(Player owner, int id) { + super(owner, id, 6200, 12802, 20, WeaponInterface.STYLE_CAST); + } + + @Override + public Familiar construct(Player owner, int id) { + return new FireTitanNPC(owner, id); + } + + @Override + public int[] getIds() { + return new int[] { 7355, 7356 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/Forager.java b/Server/src/main/content/global/skill/summoning/familiar/Forager.java new file mode 100644 index 0000000..c7ad322 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/Forager.java @@ -0,0 +1,108 @@ +package content.global.skill.summoning.familiar; + +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.GameWorld; +import core.tools.RandomFunction; + +/** + * Represents a forager familiar. + * @author Vexia + */ +public abstract class Forager extends BurdenBeast { + + /** + * The items to product if passive with no restrictions. + */ + private final Item[] items; + + /** + * The delay until the next random passive product. + */ + private int passiveDelay; + + /** + * Constructs a new {@code Forager} {@code Object}. + * @param owner the owner. + * @param id the id. + * @param ticks the ticks. + * @param pouchId the pouch id. + * @param specialCost the special cost. + */ + public Forager(Player owner, int id, int ticks, int pouchId, int specialCost, int attackStyle, final Item... items) { + super(owner, id, ticks, pouchId, specialCost, 30, attackStyle); + this.items = items; + setRandomPassive(); + } + + /** + * Constructs a new {@code Forager} {@code Object}. + * @param owner the owner. + * @param id the id. + * @param ticks the ticks. + * @param pouchId the pouch id. + * @param specialCost the special cost. + */ + public Forager(Player owner, int id, int ticks, int pouchId, int specialCost, final Item... items) { + this(owner, id, ticks, pouchId, specialCost, WeaponInterface.STYLE_DEFENSIVE, items); + } + + @Override + public void handleFamiliarTick() { + super.handleFamiliarTick(); + if (items != null && items.length > 0 && passiveDelay < GameWorld.getTicks()) { + if (RandomFunction.random(getRandom()) < 4) { + produceItem(items[RandomFunction.random(items.length)]); + } + setRandomPassive(); + } + } + + /** + * Adds an item to the container. + * @param item the item. + * @return {@code True} if so. + */ + public boolean produceItem(final Item item) { + if (!container.hasSpaceFor(item)) { + owner.getPacketDispatch().sendMessage("Your familar is too full to collect items."); + return false; + } + owner.getPacketDispatch().sendMessage(item.getAmount() == 1 ? "Your familar has produced an item." : "Your familiar has produced items."); + return container.add(item); + } + + /** + * Wrapper method for {@link #produceItem()}. + * @return {@code True} if produced. + */ + public boolean produceItem() { + if (items == null || items.length == 0) { + return false; + } + return produceItem(items[RandomFunction.random(items.length)]); + } + + /** + * Handles the passive reward of a forager. + */ + public void handlePassiveAction() { + + } + + /** + * Gets the random mod. + * @return the random mod. + */ + public int getRandom() { + return 11; + } + + /** + * Sets a random passive delay. + */ + public void setRandomPassive() { + passiveDelay = GameWorld.getTicks() + RandomFunction.random(100, 440); + } +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/ForgeRegentNPC.java b/Server/src/main/content/global/skill/summoning/familiar/ForgeRegentNPC.java new file mode 100644 index 0000000..3c560fc --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/ForgeRegentNPC.java @@ -0,0 +1,169 @@ +package content.global.skill.summoning.familiar; + +import core.game.container.impl.EquipmentContainer; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.item.GroundItem; +import core.game.node.item.GroundItemManager; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.plugin.ClassScanner; +import core.game.node.entity.skill.SkillBonus; +import core.game.node.entity.skill.Skills; +import content.global.skill.firemaking.FireMakingPulse; +import content.global.skill.firemaking.Log; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Graphics; +import core.tools.RandomFunction; + +/** + * Represents the Forge Regent familiar. + * @author Aero + */ +@Initializable +public class ForgeRegentNPC extends Familiar { + + /** + * The animation of the forge regent. + */ + private static final Animation FIREMAKE_ANIMATION = Animation.create(8085); // TODO FIX - this is from pyrelord + + /** + * Constructs a new {@code ForgeRegentNPC} {@code Object}. + */ + public ForgeRegentNPC() { + this(null, 7335); + } + + /** + * Constructs a new {@code ForgeRegentNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public ForgeRegentNPC(Player owner, int id) { + super(owner, id, 4500, 12782, 6, WeaponInterface.STYLE_RANGE_ACCURATE); + boosts.add(new SkillBonus(Skills.FIREMAKING, 4)); + } + + @Override + public Familiar construct(Player owner, int id) { + return new ForgeRegentNPC(owner, id); + } + + @Override + public void configureFamiliar() { + ClassScanner.definePlugin(new ForgeRegentFiremake()); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + if (!(special.getTarget() instanceof Player)) { + owner.sendMessage("You can't use this special on an npc."); + return false; + } + Player target = special.getTarget().asPlayer(); + if (!canCombatSpecial(target)) { + return false; + } + if (target.getInventory().freeSlots() < 1) { + owner.sendMessage("The target doesn't have enough inventory space."); + return false; + } + Item weapon = target.getEquipment().get(EquipmentContainer.SLOT_WEAPON); + Item shield = target.getEquipment().get(EquipmentContainer.SLOT_SHIELD); + if (weapon == null && shield == null) { + owner.sendMessage("The target doesn't have a weapon or shield."); + return false; + } + Item remove = null; + while (remove == null) { + if (RandomFunction.random(2) == 1) { + remove = weapon; + } else { + remove = shield; + } + } + graphics(Graphics.create(1394)); + target.graphics(Graphics.create(1393)); + if (target.getEquipment().remove(remove)) { + target.getInventory().add(remove); + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 7335, 7336 }; + } + + /** + * Handles the use with event of a log on a forge regent. + */ + public final class ForgeRegentFiremake extends UseWithHandler { + + /** + * Constructs a new {@code ForgeRegentFiremake} {@code Object}. + */ + public ForgeRegentFiremake() { + super(1511, 2862, 1521, 1519, 6333, 10810, 1517, 6332, 12581, 1515, 1513, 13567, 10329, 10328, 7406, 7405, 7404); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (int id : getIds()) { + addHandler(id, NPC_TYPE, this); + } + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + final Log log = Log.forId(event.getUsedItem().getId()); + final Familiar familiar = (Familiar) event.getUsedWith(); + final int ticks = FIREMAKE_ANIMATION.getDefinition().getDurationTicks(); + if (!player.getFamiliarManager().isOwner(familiar)) { + return true; + } + if (RegionManager.getObject(familiar.getLocation()) != null || familiar.getZoneMonitor().isInZone("bank")) { + player.getPacketDispatch().sendMessage("You can't light a fire here."); + return false; + } + familiar.lock(ticks); + familiar.animate(FIREMAKE_ANIMATION); + if (player.getInventory().remove(event.getUsedItem())) { + final GroundItem ground = GroundItemManager.create(event.getUsedItem(), familiar.getLocation(), player); + GameWorld.getPulser().submit(new Pulse(ticks, player, familiar) { + @Override + public boolean pulse() { + if (!ground.isActive()) { + return true; + } + final Scenery object = new Scenery(log.getFireId(), familiar.getLocation()); + familiar.moveStep(); + GroundItemManager.destroy(ground); + player.getSkills().addExperience(Skills.FIREMAKING, log.getXp() + 10); + familiar.faceLocation(object.getFaceLocation(familiar.getLocation())); + SceneryBuilder.add(object, log.getLife(), FireMakingPulse.getAsh(player, log, object)); + if (player.getViewport().getRegion().getId() == 10806) { + player.getAchievementDiaryManager().finishTask(player, DiaryType.SEERS_VILLAGE, 1, 9); + } + return true; + } + }); + } + return true; + } + + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/FruitBatNPC.java b/Server/src/main/content/global/skill/summoning/familiar/FruitBatNPC.java new file mode 100644 index 0000000..bd701f5 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/FruitBatNPC.java @@ -0,0 +1,150 @@ +package content.global.skill.summoning.familiar; + +import core.game.node.item.WeightedChanceItem; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.tools.RandomFunction; +import org.rs09.consts.Items; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +/** + * Represents the Fruit Bat familiar. + * @author Aero + * @author afaroutdude + */ +@Initializable +public class FruitBatNPC extends Forager { + + /** + * The random fruit to forage. + */ + private static final Item[] FRUIT_FORAGE = new Item[] { + new Item(Items.PAPAYA_FRUIT_5972), + new Item(Items.ORANGE_2108), + new Item(Items.PINEAPPLE_2114), + new Item(Items.LEMON_2102), + new Item(Items.LIME_2120), + new Item(Items.STRAWBERRY_5504), + new Item(Items.WATERMELON_5982), + new Item(Items.COCONUT_5974) + }; + + /** + * The fruit for special move fruitfall EXCEPT the papaya + * Sourced rates from various youtube videos and the RS wiki. + * Note the RS wiki page does not go back to 2009 but there's no + * indication that the rates have changed over time. + * https://www.youtube.com/watch?v=sS8ch9HkGHY + * https://www.youtube.com/watch?v=cMTjDUOvHVM + * https://www.youtube.com/watch?v=WrVsge_MNp4 + * https://2009scape.wiki/w/Money_making_guide/Casting_fruitfall + */ + private static final WeightedChanceItem[] FRUIT_FALL = new WeightedChanceItem[] { + new WeightedChanceItem(Items.ORANGE_2108, 1, 4), + new WeightedChanceItem(Items.PINEAPPLE_2114, 1, 3), + new WeightedChanceItem(Items.LEMON_2102, 1, 2), + new WeightedChanceItem(Items.LIME_2120, 1, 2), + new WeightedChanceItem(Items.BANANA_1963, 1, 2), + new WeightedChanceItem(0, 1, 4) + }; + + /** + * Constructs a new {@code FruitBatNPC} {@code Object}. + */ + public FruitBatNPC() { + this(null, 6817); + } + + /** + * Constructs a new {@code FruitBatNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public FruitBatNPC(Player owner, int id) { + super(owner, id, 4500, 12033, 6, FRUIT_FORAGE); + } + + @Override + public Familiar construct(Player owner, int id) { + return new FruitBatNPC(owner, id); + } + + @Override + public int[] getIds() { + return new int[] { 6817 }; + } + + /** + * Fruitfall works as follows: + * - 80% chance of getting anything at all, in which case a papaya is guaranteed, then + * - increasingly small chance of getting up to 7 more fruits from the table. + */ + @Override + protected boolean specialMove(FamiliarSpecial special) { + if (owner.getAttribute("fruit-bat", 0) > GameWorld.getTicks()) { + return false; + } + + final boolean anyFruit = RandomFunction.random(10) <= 8; + final boolean goodFruit = RandomFunction.random(100) <= 2; + final int otherFruitAmount = (!goodFruit && RandomFunction.random(10) == 1) ? RandomFunction.random(0, 1) : RandomFunction.random(0, goodFruit ? 7 : 3); + + animate(new Animation(8320)); + graphics(new Graphics(1332, 200)); + animate(new Animation(8321), 3); // TODO - this animates the fruit bat with the splattering fruit animation, should do it for all falling fruits but Items are not Entities and therefore cannot animate + graphics(new Graphics(1331), 4); + owner.setAttribute("fruit-bat", GameWorld.getTicks() + 5); + lock(4); + GameWorld.getPulser().submit(new Pulse(4, this) { + @Override + public boolean pulse() { + if (anyFruit){ + class Pair { + public final int p1; + public final int p2; + Pair(int p1, int p2) { + this.p1 = p1; + this.p2 = p2; + } + } + List coords = new LinkedList<>(); + coords.add(new Pair(-1, -1)); + coords.add(new Pair(-1, 0)); + coords.add(new Pair(-1, 1)); + coords.add(new Pair(0, -1)); + coords.add(new Pair(0, 1)); + coords.add(new Pair(1, -1)); + coords.add(new Pair(1, 0)); + coords.add(new Pair(1, 1)); + Collections.shuffle(coords); + + Pair coord = coords.remove(0); + GroundItemManager.create(new Item(Items.PAPAYA_FRUIT_5972), + owner.getLocation().transform(coord.p1, coord.p2, 0), + owner); + + for (int i = 0; i < otherFruitAmount; i++) { + Item item = RandomFunction.rollWeightedChanceTable(FRUIT_FALL); + if (item.getId() != 0) { + coord = coords.remove(0); + GroundItemManager.create(item, + owner.getLocation().transform(coord.p1, coord.p2, 0), + owner); + } + } + } + return true; + } + }); + return true; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/GeyserTitanNPC.java b/Server/src/main/content/global/skill/summoning/familiar/GeyserTitanNPC.java new file mode 100644 index 0000000..76406f3 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/GeyserTitanNPC.java @@ -0,0 +1,69 @@ +package content.global.skill.summoning.familiar; + +import core.plugin.Initializable; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.player.Player; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.tools.RandomFunction; + +/** + * Represents the Geyser Titan familiar. + * @author Aero + */ +@Initializable +public class GeyserTitanNPC extends Familiar { + + /** + * Constructs a new {@code GeyserTitanNPC} {@code Object}. + */ + public GeyserTitanNPC() { + this(null, 7339); + } + + /** + * Constructs a new {@code GeyserTitanNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public GeyserTitanNPC(Player owner, int id) { + super(owner, id, 6900, 12786, 6, WeaponInterface.STYLE_RANGE_ACCURATE); + } + + @Override + public Familiar construct(Player owner, int id) { + return new GeyserTitanNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + if (!canCombatSpecial(special.getTarget())) { + return false; + } + Entity target = special.getTarget(); + visualize(new Animation(7883), new Graphics(1375, 315)); + int maxHit = 30; + int defBonus = 0; + for (int i = 5; i < 11; i++) { + defBonus += target.getProperties().getBonuses()[i]; + } + maxHit = defBonus / 40; + if (maxHit <= 1) { + maxHit = RandomFunction.random(0, 3); + } + if (maxHit > 30) { + maxHit = RandomFunction.random(20, 30); + } + Projectile.ranged(this, special.getTarget(), 1376, 300, 30, 0, 45).send(); + super.sendFamiliarHit(special.getTarget(), maxHit, Graphics.create(1377)); + return true; + } + + @Override + public int[] getIds() { + return new int[] { 7339, 7340 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/GiantChinchompaNPC.java b/Server/src/main/content/global/skill/summoning/familiar/GiantChinchompaNPC.java new file mode 100644 index 0000000..c0c5720 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/GiantChinchompaNPC.java @@ -0,0 +1,85 @@ +package content.global.skill.summoning.familiar; + +import java.util.List; + +import core.plugin.Initializable; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.ImpactHandler.HitsplatType; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.tools.RandomFunction; + +/** + * Represents the Giant Chinchompa familiar. + * @author Aero + * @author Vexia + */ +@Initializable +public class GiantChinchompaNPC extends Familiar { + + /** + * Constructs a new {@code GiantChinchompaNPC} {@code Object}. + */ + public GiantChinchompaNPC() { + this(null, 7353); + } + + /** + * Constructs a new {@code GiantChinchompaNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public GiantChinchompaNPC(Player owner, int id) { + super(owner, id, 3100, 12800, 3, WeaponInterface.STYLE_RANGE_ACCURATE); + } + + @Override + public Familiar construct(Player owner, int id) { + return new GiantChinchompaNPC(owner, id); + } + + @Override + public void onAttack(Entity entity) { + super.onAttack(entity); + if (RandomFunction.random(20) == 10) { + executeSpecialMove(new FamiliarSpecial(null)); + } + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + if (!isOwnerAttackable()) { + return false; + } + final List entitys = RegionManager.getLocalEntitys(owner, 6); + entitys.remove(owner); + entitys.remove(this); + sendChat("Squeak!"); + animate(Animation.create(7758)); + graphics(Graphics.create(1364)); + GameWorld.getPulser().submit(new Pulse(3, owner, this) { + @Override + public boolean pulse() { + for (Entity entity : entitys) { + if (canCombatSpecial(entity, false)) { + entity.getImpactHandler().manualHit(GiantChinchompaNPC.this, RandomFunction.random(13), HitsplatType.NORMAL); + } + } + dismiss(); + return true; + } + }); + return true; + } + + @Override + public int[] getIds() { + return new int[] { 7353, 7354 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/GiantEntNPC.java b/Server/src/main/content/global/skill/summoning/familiar/GiantEntNPC.java new file mode 100644 index 0000000..5ed4db9 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/GiantEntNPC.java @@ -0,0 +1,89 @@ +package content.global.skill.summoning.familiar; + +import content.global.skill.farming.FarmingPatch; +import content.global.skill.farming.PatchType; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.tools.RandomFunction; +import org.rs09.consts.Items; + +/** + * Represents the Giant Ent familiar. + * @author Aero + */ +@Initializable +public class GiantEntNPC extends Forager { + private static final Item[] ITEMS = new Item[] { new Item(Items.OAK_LOGS_1521) }; + + /** + * Constructs a new {@code GiantEntNPC} {@code Object}. + */ + public GiantEntNPC() { + this(null, 6800); + } + + /** + * Constructs a new {@code GiantEntNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public GiantEntNPC(Player owner, int id) { + super(owner, id, 4900, 12013, 6, WeaponInterface.STYLE_CONTROLLED, ITEMS); + } + + @Override + public Familiar construct(Player owner, int id) { + return new GiantEntNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + return false; + } + + @Override + public int[] getIds() { + return new int[] { 6800, 6801 }; + } + + @Override + protected void configureFamiliar() { + UseWithHandler.addHandler(6800, UseWithHandler.NPC_TYPE, new UseWithHandler(Items.PURE_ESSENCE_7936) { + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(6800, UseWithHandler.NPC_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + Player player = event.getPlayer(); + player.lock(1); + int runeType = RandomFunction.random(9) < 4 ? Items.EARTH_RUNE_557 : Items.NATURE_RUNE_561; + Item runes = new Item(runeType, 1); + if (player.getInventory().remove(event.getUsedItem())) { + player.getInventory().add(runes); + player.sendMessage(String.format("The giant ent transmutes the pure essence into a %s.", runes.getName().toLowerCase())); + } + return true; + } + }); + } + + public void modifyFarmingReward(FarmingPatch fPatch, Item reward) { + PatchType patchType = fPatch.getType(); + if(patchType == PatchType.FRUIT_TREE_PATCH || + patchType == PatchType.BUSH_PATCH || + patchType == PatchType.BELLADONNA_PATCH || + patchType == PatchType.CACTUS_PATCH) { + if(RandomFunction.roll(2)) { + reward.setAmount(2 * reward.getAmount()); + } + } + } +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/GraniteCrabNPC.java b/Server/src/main/content/global/skill/summoning/familiar/GraniteCrabNPC.java new file mode 100644 index 0000000..be937a0 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/GraniteCrabNPC.java @@ -0,0 +1,78 @@ +package content.global.skill.summoning.familiar; + +import core.plugin.Initializable; +import core.game.node.entity.skill.SkillBonus; +import core.game.node.entity.skill.Skills; +import content.global.skill.fishing.Fish; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.tools.RandomFunction; + +/** + * Represents the Granite Crab familiar. + * @author Vexia + * @author Aero + */ +@Initializable +public class GraniteCrabNPC extends Forager { + + /** + * The fish item. + */ + private static final Item[] FISH = new Item[] { Fish.COD.getItem(), Fish.PIKE.getItem(), Fish.SEAWEED.getItem(), Fish.OYSTER.getItem() }; + + /** + * Constructs a new {@code GraniteCrabNPC} {@code Object}. + */ + public GraniteCrabNPC() { + this(null, 6796); + } + + /** + * Constructs a new {@code GraniteCrabNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public GraniteCrabNPC(Player owner, int id) { + super(owner, id, 1800, 12009, 12, WeaponInterface.STYLE_DEFENSIVE); + boosts.add(new SkillBonus(Skills.FISHING, 1)); + } + + @Override + public Familiar construct(Player owner, int id) { + return new GraniteCrabNPC(owner, id); + } + + @Override + public void handlePassiveAction() { + if (RandomFunction.random(4) == 1) { + final Item item = FISH[RandomFunction.random(FISH.length)]; + animate(Animation.create(8107)); + if (item.getId() == Fish.COD.getItem().getId() || item.getId() == Fish.PIKE.getItem().getId()) { + owner.getSkills().addExperience(Skills.FISHING, 5.5); + } + produceItem(item); + } + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + owner.getSkills().updateLevel(Skills.DEFENCE, 4); + visualize(Animation.create(8109), Graphics.create(1326)); + return true; + } + + @Override + public void visualizeSpecialMove() { + owner.visualize(new Animation(7660), new Graphics(1296)); + } + + @Override + public int[] getIds() { + return new int[] { 6796, 6797 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/GraniteLobsterNPC.java b/Server/src/main/content/global/skill/summoning/familiar/GraniteLobsterNPC.java new file mode 100644 index 0000000..d2db30c --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/GraniteLobsterNPC.java @@ -0,0 +1,78 @@ +package content.global.skill.summoning.familiar; + +import core.game.node.entity.skill.SkillBonus; +import core.game.node.entity.skill.Skills; +import content.global.skill.fishing.Fish; +import core.game.node.entity.Entity; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.tools.RandomFunction; + +/** + * Represents the Granite Lobster familiar. + * @author Aero + */ +@Initializable +public class GraniteLobsterNPC extends Forager { + + /** + * The fish. + */ + private static final Item[] FISH = new Item[] { new Item(383), new Item(371) }; + + /** + * Constructs a new {@code GraniteLobsterNPC} {@code Object}. + */ + public GraniteLobsterNPC() { + this(null, 6849); + } + + /** + * Constructs a new {@code GraniteLobsterNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public GraniteLobsterNPC(Player owner, int id) { + super(owner, id, 4700, 12069, 6); + boosts.add(new SkillBonus(Skills.FISHING, 4)); + } + + @Override + public Familiar construct(Player owner, int id) { + return new GraniteLobsterNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + Entity target = special.getTarget(); + if (!canCombatSpecial(target)) { + return false; + } + animate(new Animation(8118)); + graphics(Graphics.create(1351)); + Projectile.ranged(this, target, 1352, 60, 40, 1, 45).send(); + sendFamiliarHit(target, 14); + return true; + } + + @Override + public void handlePassiveAction() { + if (RandomFunction.random(40) == 1) { + final Item item = FISH[RandomFunction.random(FISH.length)]; + animate(Animation.create(8107)); + Fish fish = Fish.forItem(item); + owner.getSkills().addExperience(Skills.FISHING, fish.getExperience() * 0.10); + produceItem(item); + } + } + + @Override + public int[] getIds() { + return new int[] { 6849, 6850 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/HoneyBadgerNPC.java b/Server/src/main/content/global/skill/summoning/familiar/HoneyBadgerNPC.java new file mode 100644 index 0000000..6005c79 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/HoneyBadgerNPC.java @@ -0,0 +1,73 @@ +package content.global.skill.summoning.familiar; + +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.Player; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.game.world.update.flag.context.Graphics; + +/** + * Represents the Honey Badger familiar. + * @author Aero + * @author Vexia + */ +@Initializable +public class HoneyBadgerNPC extends Familiar { + + /** + * Constructs a new {@code HoneyBadgerNPC} {@code Object}. + */ + public HoneyBadgerNPC() { + this(null, 6845); + } + + /** + * Constructs a new {@code HoneyBadgerNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public HoneyBadgerNPC(Player owner, int id) { + super(owner, id, 2500, 12065, 4, WeaponInterface.STYLE_AGGRESSIVE); + } + + @Override + public Familiar construct(Player owner, int id) { + return new HoneyBadgerNPC(owner, id); + } + + @Override + public void visualizeSpecialMove() { + owner.visualize(Animation.create(7660), Graphics.create(1399)); + } + + @Override + public String getText() { + return "Raaaar!"; + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + if (isCharged()) { + return false; + } + charge(); + visualize(new Animation(7928, Priority.HIGH), Graphics.create(1397)); + return true; + } + + @Override + public boolean isCharged() { + if (charged) { + owner.getPacketDispatch().sendMessage("Your honey badger is already enraged!"); + return true; + } + return false; + } + + @Override + public int[] getIds() { + return new int[] { 6845, 6846 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/HydraNPC.java b/Server/src/main/content/global/skill/summoning/familiar/HydraNPC.java new file mode 100644 index 0000000..04ba4c6 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/HydraNPC.java @@ -0,0 +1,60 @@ +package content.global.skill.summoning.familiar; + +import content.global.skill.farming.FarmingPatch; +import content.global.skill.farming.Patch; +import core.game.node.Node; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.plugin.Initializable; + +/** + * Represents the Hydra familiar. + * @author Aero + */ +@Initializable +public class HydraNPC extends Familiar { + + /** + * Constructs a new {@code HydraNPC} {@code Object}. + */ + public HydraNPC() { + this(null, 6811); + } + + /** + * Constructs a new {@code HydraNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public HydraNPC(Player owner, int id) { + super(owner, id, 4900, 12025, 6, WeaponInterface.STYLE_RANGE_ACCURATE); + } + + @Override + public Familiar construct(Player owner, int id) { + return new HydraNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + Node node = special.getNode(); + if(node instanceof Scenery) { + Scenery scenery = (Scenery)node; + FarmingPatch farmingPatch = FarmingPatch.forObject(scenery); + if(farmingPatch != null) { + Patch patch = farmingPatch.getPatchFor(owner, true); + patch.regrowIfTreeStump(); + return true; + } + } + + return false; + } + + @Override + public int[] getIds() { + return new int[] { 6811, 6812 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/IbisNPC.java b/Server/src/main/content/global/skill/summoning/familiar/IbisNPC.java new file mode 100644 index 0000000..43fc370 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/IbisNPC.java @@ -0,0 +1,95 @@ +package content.global.skill.summoning.familiar; + +import core.game.node.entity.skill.SkillBonus; +import core.game.node.entity.skill.Skills; +import content.global.skill.fishing.Fish; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.tools.RandomFunction; + +/** + * Represents the Ibis familiar. + * @author Aero + * @author Vexia + */ +@Initializable +public class IbisNPC extends Forager { + + /** + * The randon fish during fish rain. + */ + private static final Fish[] FISH = new Fish[] { Fish.SHRIMP, Fish.BASS, Fish.COD, Fish.MACKEREL }; + + /** + * Constructs a new {@code IbisNPC} {@code Object}. + */ + public IbisNPC() { + this(null, 6991); + } + + /** + * Constructs a new {@code IbisNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public IbisNPC(Player owner, int id) { + super(owner, id, 3800, 12531, 12, new Item(361), new Item(373)); + boosts.add(new SkillBonus(Skills.FISHING, 3)); + } + + @Override + public void handlePassiveAction() { + if (RandomFunction.random(15) < 4) { + produceItem(); + } + } + + @Override + public boolean produceItem(Item item) { + if (super.produceItem(item)) { + if (item.getId() == 373) { + owner.getSkills().addExperience(Skills.FISHING, 10); + } + return true; + } + return false; + } + + @Override + public Familiar construct(Player owner, int id) { + return new IbisNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + animate(Animation.create(8201)); + GameWorld.getPulser().submit(new Pulse(3, owner, this) { + @Override + public boolean pulse() { + Location loc = null; + for (int i = 0; i < 2; i++) { + loc = owner.getLocation().transform(RandomFunction.random(2), RandomFunction.random(2), 0); + if (RegionManager.getObject(loc) != null) { + continue; + } + GroundItemManager.create(FISH[RandomFunction.random(FISH.length)].getItem(), loc, owner); + } + return true; + } + }); + return true; + } + + @Override + public int[] getIds() { + return new int[] { 6991 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/IceTitanNPC.java b/Server/src/main/content/global/skill/summoning/familiar/IceTitanNPC.java new file mode 100644 index 0000000..23bd94f --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/IceTitanNPC.java @@ -0,0 +1,48 @@ +package content.global.skill.summoning.familiar; + +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.player.Player; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.game.world.update.flag.context.Graphics; + +/** + * Represents the Ice Titan familiar. + * @author Aero + */ +@Initializable +public class IceTitanNPC extends ElementalTitanNPC { + + /** + * Constructs a new {@code IceTitanNPC} {@code Object}. + */ + public IceTitanNPC() { + this(null, 7359); + } + + /** + * Constructs a new {@code IceTitanNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public IceTitanNPC(Player owner, int id) { + super(owner, id, 6400, 12806, 20, WeaponInterface.STYLE_ACCURATE); + } + + @Override + public Familiar construct(Player owner, int id) { + return new IceTitanNPC(owner, id); + } + + + @Override + public void visualizeSpecialMove() { + owner.visualize(new Animation(7660), new Graphics(1306)); + } + + @Override + public int[] getIds() { + return new int[] { 7359, 7360 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/IronTitanNPC.java b/Server/src/main/content/global/skill/summoning/familiar/IronTitanNPC.java new file mode 100644 index 0000000..f47cbf8 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/IronTitanNPC.java @@ -0,0 +1,93 @@ +package content.global.skill.summoning.familiar; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.equipment.SwitchAttack; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.player.Player; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.tools.RandomFunction; +import core.game.node.entity.combat.MultiSwingHandler; + +/** + * Represents the Iron Titan familiar. + * @author Aero + */ +@Initializable +public class IronTitanNPC extends Familiar { + + /** + * If the titan is using its special move. + */ + private boolean specialMove; + + /** + * The attacks. + */ + private static final SwitchAttack[] ATTACKS = { new SwitchAttack(CombatStyle.MELEE.getSwingHandler(), Animation.create(8183)) }; + + /** + * Constructs a new {@code IronTitanNPC} {@code Object}. + */ + public IronTitanNPC() { + this(null, 7375); + } + /** + * Constructs a new {@code IronTitanNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public IronTitanNPC(Player owner, int id) { + super(owner, id, 6000, 12822, 12, WeaponInterface.STYLE_DEFENSIVE); + super.setCombatHandler(new MultiSwingHandler(true, ATTACKS) { + @Override + public int swing(Entity entity, Entity victim, BattleState s) { + int ticks = super.swing(entity, victim, s); + if (specialMove) { + BattleState[] states = new BattleState[3]; + for (int i = 1; i < 3; i++) { + BattleState state = states[i] = new BattleState(entity, victim); + int hit = 0; + if (isAccurateImpact(entity, victim)) { + int max = calculateHit(entity, victim, 1.0); + state.setMaximumHit(max); + hit = RandomFunction.random(max); + state.setEstimatedHit(hit); + } + state.setEstimatedHit(hit); + state.setStyle(getCurrent().getStyle()); + } + states[0] = s; + s.setTargets(states); + specialMove = false; + } + return ticks; + } + }); + } + + @Override + public Familiar construct(Player owner, int id) { + return new IronTitanNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + if (specialMove) { + owner.getPacketDispatch().sendMessage("Your familiar is already charging its attack."); + return false; + } + specialMove = true; + visualize(Animation.create(8183), Graphics.create(1450)); + return true; + } + + @Override + public int[] getIds() { + return new int[] { 7375, 7376 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/KaramthulhuOverlordNPC.java b/Server/src/main/content/global/skill/summoning/familiar/KaramthulhuOverlordNPC.java new file mode 100644 index 0000000..d2e2bf1 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/KaramthulhuOverlordNPC.java @@ -0,0 +1,45 @@ +package content.global.skill.summoning.familiar; + +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the Karamthulhu Overlord familiar. + * @author Aero + */ +@Initializable +public class KaramthulhuOverlordNPC extends Familiar { + + /** + * Constructs a new {@code KaramthulhuOverlordNPC} {@code Object}. + */ + public KaramthulhuOverlordNPC() { + this(null, 6809); + } + + /** + * Constructs a new {@code KaramthulhuOverlordNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public KaramthulhuOverlordNPC(Player owner, int id) { + super(owner, id, 4400, 12023, 3, WeaponInterface.STYLE_RANGE_ACCURATE); + } + + @Override + public Familiar construct(Player owner, int id) { + return new KaramthulhuOverlordNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + return false; + } + + @Override + public int[] getIds() { + return new int[] { 6809, 6810 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/LavaTitanDialogue.java b/Server/src/main/content/global/skill/summoning/familiar/LavaTitanDialogue.java new file mode 100644 index 0000000..dc1854e --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/LavaTitanDialogue.java @@ -0,0 +1,73 @@ +package content.global.skill.summoning.familiar; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.TeleportManager.TeleportType; +import core.game.world.map.Location; +import core.game.world.map.zone.impl.WildernessZone; +import core.plugin.Initializable; + +/** + * Represents the lava titan's dialogue + */ +@Initializable +public final class LavaTitanDialogue extends DialoguePlugin { + + public LavaTitanDialogue() { + } + + /** + * Constructs a new {@code LavaTitanDialogue} {@code Object}. + * @param player the player. + */ + public LavaTitanDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new LavaTitanDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + if (!(npc instanceof Familiar)) { + return false; + } + final Familiar fam = (Familiar) npc; + if (fam.getOwner() != player) { + player.getPacketDispatch().sendMessage("This is not your familiar."); + return true; + } else { + interpreter.sendOptions("Select an Option", "Chat", "Teleport to Lava Maze"); + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (buttonId) { + case 1: + player.sendMessage("The lava titan does not feel like talking now."); + end(); + break; + case 2: + if (!WildernessZone.checkTeleport(player, 20)) { + player.sendMessage("You cannot teleport with the Lava Titan above level 20 wilderness."); + end(); + } else { + player.getTeleporter().send(new Location(3048, 3820), TeleportType.NORMAL); + end(); + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 8700 }; + } +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/LavaTitanNPC.java b/Server/src/main/content/global/skill/summoning/familiar/LavaTitanNPC.java new file mode 100644 index 0000000..edac3c9 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/LavaTitanNPC.java @@ -0,0 +1,49 @@ +package content.global.skill.summoning.familiar; + +import core.game.node.entity.skill.SkillBonus; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the Lava Titan familiar. + * @author Aero + */ +@Initializable +public class LavaTitanNPC extends Familiar { + + /** + * Constructs a new {@code LavaTitanNPC} {@code Object}. + */ + public LavaTitanNPC() { + this(null, 7341); + } + + /** + * Constructs a new {@code LavaTitanNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public LavaTitanNPC(Player owner, int id) { + super(owner, id, 6100, 12788, 4, WeaponInterface.STYLE_AGGRESSIVE); + boosts.add(new SkillBonus(Skills.MINING, 10)); + boosts.add(new SkillBonus(Skills.FIREMAKING, 10)); + } + + @Override + public Familiar construct(Player owner, int id) { + return new LavaTitanNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + return false; + } + + @Override + public int[] getIds() { + return new int[] { 7341, 7342 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/LavaTitanOptionPlugin.java b/Server/src/main/content/global/skill/summoning/familiar/LavaTitanOptionPlugin.java new file mode 100644 index 0000000..bdbe77f --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/LavaTitanOptionPlugin.java @@ -0,0 +1,28 @@ +package content.global.skill.summoning.familiar; + +import core.cache.def.impl.NPCDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the plugin used to handle the lava titan familiar + */ +@Initializable +public final class LavaTitanOptionPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + NPCDefinition.forId(7341).getHandlers().put("option:interact", this); + return this; + } + + @Override + public boolean handle(final Player player, Node node, String option) { + player.getDialogueInterpreter().open(8700, node.asNpc()); + return true; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/MacawNPC.java b/Server/src/main/content/global/skill/summoning/familiar/MacawNPC.java new file mode 100644 index 0000000..a5ccf78 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/MacawNPC.java @@ -0,0 +1,173 @@ +package content.global.skill.summoning.familiar; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Plugin; +import core.plugin.ClassScanner; +import core.plugin.Initializable; +import core.tools.RandomFunction; + +/** + * Represents the Macaw familiar. + * @author Aero + * @author Vexia + */ +@Initializable +public class MacawNPC extends Forager { + + /** + * The herb items. + */ + private static final Item[] HERBS = new Item[] { new Item(249), new Item(251), new Item(253), new Item(255), new Item(257), new Item(2998), new Item(12172), new Item(259), new Item(261), new Item(263), new Item(3000), new Item(265), new Item(2481), new Item(267), new Item(269) }; + + /** + * The delay until the next special. + */ + private int specialDelay; + + /** + * Constructs a new {@code MacawNPC} {@code Object}. + */ + public MacawNPC() { + this(null, 6851); + } + + /** + * Constructs a new {@code MacawNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public MacawNPC(Player owner, int id) { + super(owner, id, 3100, 12071, 12, HERBS); + } + + @Override + public Familiar construct(Player owner, int id) { + return new MacawNPC(owner, id); + } + + @Override + public Plugin newInstance(Object object) throws Throwable { + ClassScanner.definePlugin(new MacawDialogue()); + return super.newInstance(object); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + if (specialDelay > GameWorld.getTicks()) { + owner.getPacketDispatch().sendMessage("You must wait one minute until using the macaws special again."); + return false; + } + final Item herb = HERBS[RandomFunction.random(HERBS.length)]; + animate(Animation.create(8013)); + graphics(Graphics.create(1321), 2); + GameWorld.getPulser().submit(new Pulse(5, owner) { + @Override + public boolean pulse() { + GroundItemManager.create(herb, getLocation(), owner); + return true; + } + }); + specialDelay = GameWorld.getTicks() + 100; + return true; + } + + /** + * Handles the macaw dialogue. + * @author Vexia + */ + public final class MacawDialogue extends DialoguePlugin { + + /** + * The familiar. + */ + private Familiar familiar; + + /** + * Constructs a new {@code MacawDialogue} {@code Object}. + */ + public MacawDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code MacawDialogue} {@code Object}. + * @param player the player. + */ + public MacawDialogue(final Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new MacawDialogue(player); + } + + @Override + public boolean open(Object... args) { + familiar = (Familiar) args[0]; + options("Chat", "Remote view", "Withdraw"); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + switch (buttonId) { + case 1: + npc("Awh! Gimme the rum! Gimme the rum!"); + stage++; + break; + case 2: + end(); + RemoteViewer.openDialogue(player, familiar); + break; + case 3: + end(); + ((BurdenBeast) familiar).openInterface(); + break; + } + break; + case 1: + player(" I don't think you'll like the stuff. Besides, I think there", "is a law about feeding birds alcohol."); + stage++; + break; + case 2: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return MacawNPC.this.getIds(); + } + + } + + @Override + public Animation getViewAnimation() { + return Animation.create(8013); + } + + @Override + public int getRandom() { + return 40; + } + + @Override + public int[] getIds() { + return new int[] { 6851, 6852 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/MagpieNPC.java b/Server/src/main/content/global/skill/summoning/familiar/MagpieNPC.java new file mode 100644 index 0000000..244c489 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/MagpieNPC.java @@ -0,0 +1,69 @@ +package content.global.skill.summoning.familiar; + +import core.game.node.entity.skill.SkillBonus; +import core.game.node.entity.skill.Skills; +import content.global.skill.crafting.gem.Gems; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.game.world.update.flag.context.Graphics; + +/** + * Represents the Magpie familiar. + * @author Aero + * @author Vexia + */ +@Initializable +public class MagpieNPC extends Forager { + + /** + * The items to forage. + */ + private static final Item[] ITEMS = new Item[] { Gems.SAPPHIRE.getUncut(), Gems.EMERALD.getUncut(), Gems.RUBY.getUncut(), Gems.DIAMOND.getUncut() }; + + /** + * Constructs a new {@code MagpieNPC} {@code Object}. + */ + public MagpieNPC() { + this(null, 6824); + } + + /** + * Constructs a new {@code MagpieNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public MagpieNPC(Player owner, int id) { + super(owner, id, 3400, 12041, 3, ITEMS); + boosts.add(new SkillBonus(Skills.THIEVING, 3)); + } + + @Override + public Familiar construct(Player owner, int id) { + return new MagpieNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + visualize(Animation.create(8020), Graphics.create(1336)); + return true; + } + + @Override + public void visualizeSpecialMove() { + owner.getSkills().updateLevel(Skills.THIEVING, 2); + owner.visualize(new Animation(7660), new Graphics(1296)); + } + + @Override + public int getRandom() { + return 14; + } + + @Override + public int[] getIds() { + return new int[] { 6824 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/MinotaurFamiliarNPC.java b/Server/src/main/content/global/skill/summoning/familiar/MinotaurFamiliarNPC.java new file mode 100644 index 0000000..2fbdf0d --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/MinotaurFamiliarNPC.java @@ -0,0 +1,343 @@ +package content.global.skill.summoning.familiar; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Plugin; +import core.plugin.ClassScanner; +import core.plugin.Initializable; +import core.tools.RandomFunction; + +import static core.api.ContentAPIKt.stun; + +/** + * The plugin used to load the minotaur familiar npcs. + * @author Vexia + * @version 1.0 + */ +@Initializable +public final class MinotaurFamiliarNPC implements Plugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ClassScanner.definePlugin(new BronzeMinotaurNPC()); + ClassScanner.definePlugin(new IronMinotaurNPC()); + ClassScanner.definePlugin(new SteelMinotaurNPC()); + ClassScanner.definePlugin(new MithrilMinotaurNPC()); + ClassScanner.definePlugin(new AdamantMinotaurNPC()); + ClassScanner.definePlugin(new RuneMinotaurNPC()); + return this; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + /** + * Handles the bullrush special. + * @param familiar the familiar. + * @param special the special. + * @param maxHit the max hit. + */ + public boolean bullRush(final Familiar familiar, final FamiliarSpecial special, final int maxHit) { + final Entity target = (Entity) special.getNode(); + if (!familiar.canCombatSpecial(target)) { + return false; + } + familiar.sendFamiliarHit(target, RandomFunction.random(maxHit)); + Projectile.magic(familiar, target, 1497, 80, 36, 70, 10).send(); + familiar.visualize(Animation.create(8026), Graphics.create(1496)); + if (!(familiar instanceof BronzeMinotaurNPC || familiar instanceof RuneMinotaurNPC) && RandomFunction.random(10) < 6) { + final int ticks = 2 + (int) Math.floor(familiar.getLocation().getDistance(target.getLocation()) * 0.5); + GameWorld.getPulser().submit(new Pulse(ticks) { + @Override + public boolean pulse() { + stun(target, 4); + return true; + } + }); + } + return true; + } + + /** + * Represents the Bronze Minotaur familiar. + * @author Aero + */ + public class BronzeMinotaurNPC extends Familiar { + + /** + * Constructs a new {@code BronzeMinotaurNPC} {@code Object}. + */ + public BronzeMinotaurNPC() { + this(null, 6853); + } + + /** + * Constructs a new {@code BronzeMinotaurNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public BronzeMinotaurNPC(Player owner, int id) { + super(owner, id, 3000, 12073, 6, WeaponInterface.STYLE_DEFENSIVE); + } + + @Override + public Familiar construct(Player owner, int id) { + return new BronzeMinotaurNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + return bullRush(this, special, 4); + } + + @Override + public boolean isPoisonImmune() { + return true; + } + + @Override + public int[] getIds() { + return new int[] { 6853, 6854 }; + } + + } + + /** + * Represents the Iron Minotaur familiar. + * @author Aero + */ + public class IronMinotaurNPC extends Familiar { + + /** + * Constructs a new {@code IronMinotaurNPC} {@code Object}. + */ + public IronMinotaurNPC() { + this(null, 6855); + } + + /** + * Constructs a new {@code IronMinotaurNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public IronMinotaurNPC(Player owner, int id) { + super(owner, id, 3700, 12075, 6, WeaponInterface.STYLE_DEFENSIVE); + } + + @Override + public Familiar construct(Player owner, int id) { + return new IronMinotaurNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + return bullRush(this, special, 6); + } + + @Override + public boolean isPoisonImmune() { + return true; + } + + @Override + public int[] getIds() { + return new int[] { 6855, 6856 }; + } + + } + + /** + * Represents the Steel Minotaur familiar. + * @author Aero + */ + public class SteelMinotaurNPC extends Familiar { + + /** + * Constructs a new {@code SteelMinotaurNPC} {@code Object}. + */ + public SteelMinotaurNPC() { + this(null, 6857); + } + + /** + * Constructs a new {@code SteelMinotaurNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public SteelMinotaurNPC(Player owner, int id) { + super(owner, id, 4600, 12077, 6, WeaponInterface.STYLE_DEFENSIVE); + } + + @Override + public Familiar construct(Player owner, int id) { + return new SteelMinotaurNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + return bullRush(this, special, 9); + } + + @Override + public CombatStyle getCombatStyle() { + return CombatStyle.MELEE; + } + + @Override + public boolean isPoisonImmune() { + return true; + } + + @Override + public int[] getIds() { + return new int[] { 6857, 6858 }; + } + + } + + /** + * Represents the Mithril Minotaur familiar. + * @author Aero + */ + public class MithrilMinotaurNPC extends Familiar { + + /** + * Constructs a new {@code MithrilMinotaurNPC} {@code Object}. + */ + public MithrilMinotaurNPC() { + this(null, 6859); + } + + /** + * Constructs a new {@code MithrilMinotaurNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public MithrilMinotaurNPC(Player owner, int id) { + super(owner, id, 5500, 12079, 6, WeaponInterface.STYLE_DEFENSIVE); + } + + @Override + public Familiar construct(Player owner, int id) { + return new MithrilMinotaurNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + return bullRush(this, special, 13); + } + + @Override + public boolean isPoisonImmune() { + return true; + } + + @Override + public int[] getIds() { + return new int[] { 6859, 6860 }; + } + + } + + /** + * Represents the Adamant Minotaur familiar. + * @author Aero + */ + public class AdamantMinotaurNPC extends Familiar { + + /** + * Constructs a new {@code AdamantMinotaurNPC} {@code Object}. + */ + public AdamantMinotaurNPC() { + this(null, 6861); + } + + /** + * Constructs a new {@code AdamantMinotaurNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public AdamantMinotaurNPC(Player owner, int id) { + super(owner, id, 6600, 12081, 6, WeaponInterface.STYLE_DEFENSIVE); + } + + @Override + public Familiar construct(Player owner, int id) { + return new AdamantMinotaurNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + return bullRush(this, special, 16); + } + + @Override + public CombatStyle getCombatStyle() { + return CombatStyle.MELEE; + } + + @Override + public boolean isPoisonImmune() { + return true; + } + + @Override + public int[] getIds() { + return new int[] { 6861, 6862 }; + } + + } + + /** + * Represents the Rune Minotaur familiar. + * @author Aero + */ + public class RuneMinotaurNPC extends Familiar { + + /** + * Constructs a new {@code RuneMinotaurNPC} {@code Object}. + */ + public RuneMinotaurNPC() { + this(null, 6863); + } + + /** + * Constructs a new {@code RuneMinotaurNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public RuneMinotaurNPC(Player owner, int id) { + super(owner, id, 15100, 12083, 6, WeaponInterface.STYLE_DEFENSIVE); + } + + @Override + public Familiar construct(Player owner, int id) { + return new RuneMinotaurNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + return bullRush(this, special, 20); + } + + @Override + public boolean isPoisonImmune() { + return true; + } + + @Override + public int[] getIds() { + return new int[] { 6863, 6864 }; + } + + } +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/MossTitanNPC.java b/Server/src/main/content/global/skill/summoning/familiar/MossTitanNPC.java new file mode 100644 index 0000000..380ec0d --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/MossTitanNPC.java @@ -0,0 +1,40 @@ +package content.global.skill.summoning.familiar; + +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the Moss Titan familiar. + * @author Aero + */ +@Initializable +public class MossTitanNPC extends ElementalTitanNPC { + + /** + * Constructs a new {@code MossTitanNPC} {@code Object}. + */ + public MossTitanNPC() { + this(null, 7357); + } + + /** + * Constructs a new {@code MossTitanNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public MossTitanNPC(Player owner, int id) { + super(owner, id, 5800, 12804, 20, WeaponInterface.STYLE_AGGRESSIVE); + } + + @Override + public Familiar construct(Player owner, int id) { + return new MossTitanNPC(owner, id); + } + + @Override + public int[] getIds() { + return new int[] { 7357, 7358 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/ObsidianGolemNPC.java b/Server/src/main/content/global/skill/summoning/familiar/ObsidianGolemNPC.java new file mode 100644 index 0000000..6b62e34 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/ObsidianGolemNPC.java @@ -0,0 +1,56 @@ +package content.global.skill.summoning.familiar; + +import core.plugin.Initializable; +import core.game.node.entity.skill.SkillBonus; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.player.Player; +import core.game.world.update.flag.context.Graphics; + +/** + * Represents the Obsidian Golem familiar. + * @author Aero + */ +@Initializable +public class ObsidianGolemNPC extends Familiar { + + /** + * Constructs a new {@code ObsidianGolemNPC} {@code Object}. + */ + public ObsidianGolemNPC() { + this(null, 7345); + } + + /** + * Constructs a new {@code ObsidianGolemNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public ObsidianGolemNPC(Player owner, int id) { + super(owner, id, 5500, 12792, 12, WeaponInterface.STYLE_AGGRESSIVE); + boosts.add(new SkillBonus(Skills.MINING, 7)); + } + + @Override + public Familiar construct(Player owner, int id) { + return new ObsidianGolemNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + graphics(Graphics.create(1465)); + owner.getSkills().updateLevel(Skills.STRENGTH, 9); + return true; + } + + @Override + public String getText() { + return "Onwards, to Glory!"; + } + + @Override + public int[] getIds() { + return new int[] { 7345, 7346 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/PackYakNPC.java b/Server/src/main/content/global/skill/summoning/familiar/PackYakNPC.java new file mode 100644 index 0000000..b55b659 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/PackYakNPC.java @@ -0,0 +1,100 @@ +package content.global.skill.summoning.familiar; + +import core.api.Container; +import core.game.node.entity.player.info.LogType; +import core.game.node.entity.player.info.PlayerMonitor; +import core.game.system.config.ItemConfigParser; +import core.plugin.Initializable; +import content.global.skill.summoning.SummoningScroll; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; + +import static core.api.ContentAPIKt.addItem; +import static core.api.ContentAPIKt.removeItem; + +/** + * Represents the Pack Yak familiar. + * @author Aero + */ +@Initializable +public class PackYakNPC extends BurdenBeast { + + /** + * Constructs a new {@code PackYakNPC} {@code Object}. + */ + public PackYakNPC() { + this(null, 6873); + } + + /** + * Constructs a new {@code PackYakNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public PackYakNPC(Player owner, int id) { + super(owner, id, 5800, 12093, 12, 30, WeaponInterface.STYLE_AGGRESSIVE); + } + + @Override + public Familiar construct(Player owner, int id) { + return new PackYakNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + Player player = owner; + Item item = new Item(special.getItem().getId(), 1); + if (item.getId() == SummoningScroll.WINTER_STORAGE_SCROLL.getItemId()) { + return false; + } + if (!item.getDefinition().getConfiguration(ItemConfigParser.BANKABLE, true)) { + player.sendMessage("A magical force prevents you from banking this item."); + return false; + } + Item remove = item; + if (!item.getDefinition().isUnnoted()) { + remove = new Item(item.getId(), 1); + item = new Item(item.getNoteChange(), 1); + } + boolean success = addItem(player, item.getId(), item.getAmount(), Container.BANK); + if (success) { + success = removeItem(player, remove, Container.INVENTORY); + if (!success) { + // Add worked, but remove failed. This should never happen (it by definition constitutes an item duplication). + boolean recovered = removeItem(player, item, Container.BANK); + if (recovered) { + PlayerMonitor.log(player, LogType.DUPE_ALERT, "Successfully recovered from potential dupe attempt involving the winter storage scroll"); + } else { + PlayerMonitor.log(player, LogType.DUPE_ALERT, "Failed to recover from potentially successful dupe attempt involving the winter storage scroll"); + } + } + } + if (success) { + player.getDialogueInterpreter().close(); + graphics(Graphics.create(1358)); + player.getPacketDispatch().sendMessage("The pack yak has sent an item to your bank."); + } else { + player.getPacketDispatch().sendMessage("The pack yak can't send that item to your bank."); + } + return true; + } + + @Override + public void visualizeSpecialMove() { + owner.visualize(Animation.create(7660), Graphics.create(1316)); + } + + @Override + public int[] getIds() { + return new int[] { 6873, 6874 }; + } + + @Override + protected String getText() { + return "Baroo!"; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/PrayingMantisNPC.java b/Server/src/main/content/global/skill/summoning/familiar/PrayingMantisNPC.java new file mode 100644 index 0000000..d6c8298 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/PrayingMantisNPC.java @@ -0,0 +1,45 @@ +package content.global.skill.summoning.familiar; + +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the Praying Mantis familiar. + * @author Aero + */ +@Initializable +public class PrayingMantisNPC extends Familiar { + + /** + * Constructs a new {@code PrayingMantisNPC} {@code Object}. + */ + public PrayingMantisNPC() { + this(null, 6798); + } + + /** + * Constructs a new {@code PrayingMantisNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public PrayingMantisNPC(Player owner, int id) { + super(owner, id, 6900, 12011, 6, WeaponInterface.STYLE_ACCURATE); + } + + @Override + public Familiar construct(Player owner, int id) { + return new PrayingMantisNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + return false; + } + + @Override + public int[] getIds() { + return new int[] { 6798, 6799 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/PyreLordNPC.java b/Server/src/main/content/global/skill/summoning/familiar/PyreLordNPC.java new file mode 100644 index 0000000..c4672b6 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/PyreLordNPC.java @@ -0,0 +1,147 @@ +package content.global.skill.summoning.familiar; + +import core.game.node.entity.player.link.diary.DiaryType; +import core.plugin.Initializable; +import core.game.node.entity.skill.SkillBonus; +import core.game.node.entity.skill.Skills; +import content.global.skill.crafting.jewellery.JewelleryCrafting; +import content.global.skill.firemaking.FireMakingPulse; +import content.global.skill.firemaking.Log; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItem; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Plugin; +import core.plugin.ClassScanner; + +/** + * Represents the Pyrelord familiar. + * @author Aero + * @author Vexia + */ +@Initializable +public class PyreLordNPC extends Familiar { + + /** + * The animation of the pyre lord. + */ + private static final Animation FIREMAKE_ANIMATION = Animation.create(8085); + + /** + * Constructs a new {@code PyreLordNPC} {@code Object}. + */ + public PyreLordNPC() { + this(null, 7377); + } + + /** + * Constructs a new {@code PyreLordNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public PyreLordNPC(Player owner, int id) { + super(owner, id, 3200, 12816, 6, WeaponInterface.STYLE_AGGRESSIVE); + boosts.add(new SkillBonus(Skills.FIREMAKING, 3)); + } + + @Override + public Familiar construct(Player owner, int id) { + return new PyreLordNPC(owner, id); + } + + @Override + public void configureFamiliar() { + ClassScanner.definePlugin(new PyreLordFiremake()); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + final Item item = (Item) special.getNode(); + if (item.getId() != 2357) { + owner.getPacketDispatch().sendMessage("You can only use this special on gold bars."); + return false; + } + owner.lock(1); + animate(Animation.create(8081)); + owner.graphics(Graphics.create(1463)); + JewelleryCrafting.open(owner); + return true; + } + + @Override + public int[] getIds() { + return new int[] { 7377, 7378 }; + } + + /** + * Handles the use with event of a log on a pyrelord. + * @author Vexia + */ + public final class PyreLordFiremake extends UseWithHandler { + + /** + * Constructs a new {@code PyreLordFiremake} {@code Object}. + */ + public PyreLordFiremake() { + super(1511, 2862, 1521, 1519, 6333, 10810, 1517, 6332, 12581, 1515, 1513, 13567, 10329, 10328, 7406, 7405, 7404); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (int id : getIds()) { + addHandler(id, NPC_TYPE, this); + } + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + final Log log = Log.forId(event.getUsedItem().getId()); + final Familiar familiar = (Familiar) event.getUsedWith(); + final int ticks = FIREMAKE_ANIMATION.getDefinition().getDurationTicks(); + if (!player.getFamiliarManager().isOwner(familiar)) { + return true; + } + if (RegionManager.getObject(familiar.getLocation()) != null || familiar.getZoneMonitor().isInZone("bank")) { + player.getPacketDispatch().sendMessage("You can't light a fire here."); + return false; + } + familiar.lock(ticks); + familiar.animate(FIREMAKE_ANIMATION); + if (player.getInventory().remove(event.getUsedItem())) { + final GroundItem ground = GroundItemManager.create(event.getUsedItem(), familiar.getLocation(), player); + GameWorld.getPulser().submit(new Pulse(ticks, player, familiar) { + @Override + public boolean pulse() { + if (!ground.isActive()) { + return true; + } + final Scenery object = new Scenery(log.getFireId(), familiar.getLocation()); + familiar.moveStep(); + GroundItemManager.destroy(ground); + player.getSkills().addExperience(Skills.FIREMAKING, log.getXp() + 10); + familiar.faceLocation(object.getFaceLocation(familiar.getLocation())); + SceneryBuilder.add(object, log.getLife(), FireMakingPulse.getAsh(player, log, object)); + if (player.getViewport().getRegion().getId() == 10806) { + player.getAchievementDiaryManager().finishTask(player, DiaryType.SEERS_VILLAGE, 1, 9); + } + return true; + } + }); + } + return true; + } + + } +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/RavenousLocustNPC.java b/Server/src/main/content/global/skill/summoning/familiar/RavenousLocustNPC.java new file mode 100644 index 0000000..ad6d518 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/RavenousLocustNPC.java @@ -0,0 +1,70 @@ +package content.global.skill.summoning.familiar; + +import core.game.consumable.Consumable; +import content.data.consumables.Consumables; +import core.plugin.Initializable; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Graphics; + +/** + * Represents the Ravenous Locust familiar. + * @author Aero + */ +@Initializable +public class RavenousLocustNPC extends Familiar { + + /** + * Constructs a new {@code RavenousLocustNPC} {@code Object}. + */ + public RavenousLocustNPC() { + this(null, 7372); + } + + /** + * Constructs a new {@code RavenousLocustNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public RavenousLocustNPC(Player owner, int id) { + super(owner, id, 2400, 12820, 12, WeaponInterface.STYLE_ACCURATE); + } + + @Override + public Familiar construct(Player owner, int id) { + return new RavenousLocustNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + Entity target = special.getTarget(); + if (!canCombatSpecial(target)) { + return false; + } + animate(getProperties().getAttackAnimation()); + graphics(Graphics.create(1346)); + target.graphics(Graphics.create(1347)); + if (target instanceof Player) { + Player p = target.asPlayer(); + for (Item item : p.getInventory().toArray()) { + if (item == null) { + continue; + } + Consumable consumable = Consumables.getConsumableById(item.getId()).getConsumable(); + if (consumable != null) { + p.getInventory().remove(item); + break; + } + } + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 7372, 7373 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/RemoteViewDialogue.java b/Server/src/main/content/global/skill/summoning/familiar/RemoteViewDialogue.java new file mode 100644 index 0000000..01e9e81 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/RemoteViewDialogue.java @@ -0,0 +1,61 @@ +package content.global.skill.summoning.familiar; + +import core.plugin.Initializable; +import core.game.dialogue.DialogueInterpreter; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; + +/** + * Handles the remote viewing dialogue. + * @author Vexia + */ +@Initializable +public final class RemoteViewDialogue extends DialoguePlugin { + + /** + * The familiar instance. + */ + private Familiar familiar; + + /** + * Constructs a new {@code RemoteViewDialogue} {@code Object}. + */ + public RemoteViewDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code RemoteViewDialogue} {@code Object}. + * @param player the player. + */ + public RemoteViewDialogue(final Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new RemoteViewDialogue(player); + } + + @Override + public boolean open(Object... args) { + familiar = (Familiar) args[0]; + options("North", "East", "South", "West", "Straight up"); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + end(); + RemoteViewer.create(player, familiar, familiar.getViewAnimation(), RemoteViewer.ViewType.values()[-1 + buttonId]).startViewing(); + return true; + } + + @Override + public int[] getIds() { + return new int[] { DialogueInterpreter.getDialogueKey(RemoteViewer.DIALOGUE_NAME) }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/RemoteViewer.java b/Server/src/main/content/global/skill/summoning/familiar/RemoteViewer.java new file mode 100644 index 0000000..647bddd --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/RemoteViewer.java @@ -0,0 +1,271 @@ +package content.global.skill.summoning.familiar; + +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.net.packet.PacketRepository; +import core.net.packet.context.CameraContext; +import core.net.packet.context.CameraContext.CameraType; +import core.net.packet.out.CameraViewPacket; + +/** + * Handles the remote viewing of an area. + * @author Vexia + */ +public final class RemoteViewer { + + /** + * The dialogue name to use. + */ + public static final String DIALOGUE_NAME = "remote-view"; + + /** + * The remote camera height. + */ + public static final int HEIGHT = 1000; + + /** + * The player. + */ + private final Player player; + + /** + * The familiar. + */ + private final Familiar familiar; + + /** + * The animation to start viewing. + */ + private final Animation animation; + + /** + * The view type. + */ + private final ViewType type; + + /** + * Constructs a new {@code RemoteViewer} {@code Object}. + * @param player the player. + * @param familiar the familiar. + * @param animation the animation. + * @param type the type. + */ + public RemoteViewer(Player player, Familiar familiar, Animation animation, ViewType type) { + this.player = player; + this.familiar = familiar; + this.animation = animation; + this.type = type; + } + + /** + * Creates a remote view object. + * @param player the player. + * @param familiar the familiar. + * @param animation the animation. + * @param type + * @return + */ + public static RemoteViewer create(final Player player, Familiar familiar, Animation animation, ViewType type) { + return new RemoteViewer(player, familiar, animation, type); + } + + /** + * Starts viewing an area. + */ + public void startViewing() { + player.lock(); + familiar.animate(animation); + player.getPacketDispatch().sendMessage("You send the " + familiar.getName().toLowerCase() + " to fly " + (type == ViewType.STRAIGHT_UP ? "directly up" : "to the " + type.name().toLowerCase()) + "..."); + GameWorld.getPulser().submit(new Pulse(5) { + @Override + public boolean pulse() { + view(); + return true; + } + }); + } + + /** + * Views the area from the view type. + */ + private void view() { + if (!canView()) { + return; + } + sendCamera(type.getXOffset(), type.getYOffset(), type.getXRot(), type.getYRot()); + GameWorld.getPulser().submit(new Pulse(13) { + @Override + public boolean pulse() { + reset(); + return true; + } + }); + } + + /** + * Checks if a remote view can start. + * @return {@code True} if so. + */ + private boolean canView() { + // player.getPacketDispatch().sendMessage("There seems to be an obstruction in the direction; the familiar cannot fly there"); + if (!familiar.isActive()) { + return false; + } + return true; + } + + /** + * Resets the camera packet. + */ + private void reset() { + familiar.call(); + player.unlock(); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.RESET, 0, 0, HEIGHT, 1, 100)); + } + + /** + * Sends a camera packet. + * @param xRot the xRot. + * @param yRot the yRot. + */ + private void sendCamera(int xOffset, int yOffset, final int xRot, final int yRot) { + final Location location = type.getLocationTransform(player); + final int x = location.getX() + xOffset; + final int y = location.getY() + yOffset; + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.POSITION, x, y, HEIGHT, 1, 100)); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.ROTATION, x + xRot, y + yRot, HEIGHT, 1, 90)); + } + + /** + * Opens the remote viewing dialogue. + * @param player the player. + * @param familiar the familiar. + */ + public static void openDialogue(final Player player, final Familiar familiar) { + player.getDialogueInterpreter().open(DIALOGUE_NAME, familiar); + } + + /** + * Gets the player. + * @return The player. + */ + public Player getPlayer() { + return player; + } + + /** + * Gets the familiar. + * @return The familiar. + */ + public Familiar getFamiliar() { + return familiar; + } + + /** + * Gets the animation. + * @return The animation. + */ + public Animation getAnimation() { + return animation; + } + + /** + * Gets the type. + * @return The type. + */ + public ViewType getType() { + return type; + } + + /** + * A view type. + * @author Vexia + */ + public enum ViewType { + NORTH(Direction.NORTH, 0, 0, 0, 0), EAST(Direction.WEST, 0, 0, 0, 0), SOUTH(Direction.SOUTH, 0, 0, 0, 0), WEST(Direction.EAST, 0, 0, 0, 0), STRAIGHT_UP(null, 0, 0, 0, 0); + + /** + * The direction. + */ + private final Direction direction; + + /** + * The data for the camera. + */ + private final int[] data; + + /** + * Constructs a new {@code ViewType} {@code Object}. + * @param data the data. + */ + private ViewType(Direction direction, int... data) { + this.direction = direction; + this.data = data; + } + + /** + * Gets the transformed location. + * @param player the player. + * @return the location. + */ + public Location getLocationTransform(final Player player) { + if (this == STRAIGHT_UP) { + return player.getLocation(); + } + return player.getLocation().transform(direction, 10); + } + + /** + * Gets the direction. + * @return The direction. + */ + public Direction getDirection() { + return direction; + } + + /** + * Gets the x offset. + * @return the offset. + */ + public int getXOffset() { + return data[0]; + } + + /** + * Gets the y offset. + * @return the offset. + */ + public int getYOffset() { + return data[1]; + } + + /** + * Gets the x rotation. + * @return the rotation. + */ + public int getXRot() { + return data[2]; + } + + /** + * Gets the y rot. + * @return the rot. + */ + public int getYRot() { + return data[3]; + } + + /** + * Gets the data. + * @return The data. + */ + public int[] getData() { + return data; + } + + } +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/SmokeDevilNPC.java b/Server/src/main/content/global/skill/summoning/familiar/SmokeDevilNPC.java new file mode 100644 index 0000000..545ce63 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/SmokeDevilNPC.java @@ -0,0 +1,89 @@ +package content.global.skill.summoning.familiar; + +import java.util.List; + +import core.cache.def.impl.NPCDefinition; +import core.plugin.Initializable; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.ImpactHandler.HitsplatType; +import core.game.node.entity.player.Player; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Plugin; +import core.tools.RandomFunction; + +/** + * Represents the Smoke Devil familiar. + * @author Aero + * @author Vexia + */ +@Initializable +public class SmokeDevilNPC extends Familiar { + + /** + * Constructs a new {@code SmokeDevilNPC} {@code Object}. + */ + public SmokeDevilNPC() { + this(null, 6865); + } + + /** + * Constructs a new {@code SmokeDevilNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public SmokeDevilNPC(Player owner, int id) { + super(owner, id, 4800, 12085, 6); + } + + @Override + public Familiar construct(Player owner, int id) { + return new SmokeDevilNPC(owner, id); + } + + @Override + public void configureFamiliar() { + NPCDefinition.setOptionHandler("flames", new OptionHandler() { + @Override + public Plugin newInstance(Object arg) throws Throwable { + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + final Familiar familiar = (Familiar) node; + if (!player.getFamiliarManager().isOwner(familiar)) { + return true; + } + // TODO: + return true; + } + }); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + if (!isOwnerAttackable()) { + return false; + } + final List entitys = RegionManager.getLocalEntitys(this, 1); + entitys.remove(this); + entitys.remove(owner); + visualize(Animation.create(7820), Graphics.create(1375)); + for (Entity e : entitys) { + if (super.canCombatSpecial(e, false)) { + e.getImpactHandler().manualHit(this, RandomFunction.random(6), HitsplatType.NORMAL); + } + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 6865, 6866 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/SpiritCobraNPC.java b/Server/src/main/content/global/skill/summoning/familiar/SpiritCobraNPC.java new file mode 100644 index 0000000..18d4946 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/SpiritCobraNPC.java @@ -0,0 +1,112 @@ +package content.global.skill.summoning.familiar; + +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.game.node.item.Item; + +/** + * Represents the Spirit Cobra familiar. + * @author Aero + * @author Vexia + */ +@Initializable +public class SpiritCobraNPC extends Familiar { + + /** + * Constructs a new {@code SpiritCobraNPC} {@code Object}. + */ + public SpiritCobraNPC() { + this(null, 6802); + } + + /** + * Constructs a new {@code SpiritCobraNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public SpiritCobraNPC(Player owner, int id) { + super(owner, id, 5600, 12015, 3, WeaponInterface.STYLE_ACCURATE); + } + + @Override + public Familiar construct(Player owner, int id) { + return new SpiritCobraNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + final Item item = (Item) special.getNode(); + final Egg egg = Egg.forEgg(item); + if (egg == null) { + owner.getPacketDispatch().sendMessage("You can't use the special move on this item."); + return false; + } + owner.getInventory().replace(egg.getProduct(), item.getSlot()); + return true; + } + + @Override + public int[] getIds() { + return new int[] { 6802, 6803 }; + } + + /** + * Represents an incubated egg. + * @author Vexia + */ + public enum Egg { + COCKATRICE(new Item(1944), new Item(12109)), SARATRICE(new Item(5077), new Item(12113)), ZAMATRICE(new Item(5076), new Item(12115)), GUTHATRICE(new Item(5078), new Item(12111)), CORACATRICE(new Item(11964), new Item(12119)), PENGATRICE(new Item(12483), new Item(12117)), VULATRICE(new Item(11965), new Item(12121)); + + /** + * The egg item. + */ + private final Item egg; + + /** + * The product. + */ + private final Item product; + + /** + * Constructs a new {@code Egg} {@code Object}. + * @param egg the egg. + * @param product the product. + */ + private Egg(Item egg, Item product) { + this.egg = egg; + this.product = product; + } + + /** + * Gets the egg for the item. + * @param item the item. + * @return the egg. + */ + public static Egg forEgg(final Item item) { + for (Egg egg : values()) { + if (egg.getEgg().getId() == item.getId()) { + return egg; + } + } + return null; + } + + /** + * Gets the egg. + * @return The egg. + */ + public Item getEgg() { + return egg; + } + + /** + * Gets the product. + * @return The product. + */ + public Item getProduct() { + return product; + } + + } +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/SpiritDagannothNPC.java b/Server/src/main/content/global/skill/summoning/familiar/SpiritDagannothNPC.java new file mode 100644 index 0000000..b7e5bac --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/SpiritDagannothNPC.java @@ -0,0 +1,45 @@ +package content.global.skill.summoning.familiar; + +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the Spirit Dagannoth familiar. + * @author Aero + */ +@Initializable +public class SpiritDagannothNPC extends Familiar { + + /** + * Constructs a new {@code SpiritDagannothNPC} {@code Object}. + */ + public SpiritDagannothNPC() { + this(null, 6804); + } + + /** + * Constructs a new {@code SpiritDagannothNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public SpiritDagannothNPC(Player owner, int id) { + super(owner, id, 5700, 12017, 6, WeaponInterface.STYLE_CONTROLLED); + } + + @Override + public Familiar construct(Player owner, int id) { + return new SpiritDagannothNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + return false; + } + + @Override + public int[] getIds() { + return new int[] { 6804, 6805 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/SpiritGraahkDialogue.java b/Server/src/main/content/global/skill/summoning/familiar/SpiritGraahkDialogue.java new file mode 100644 index 0000000..98721c6 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/SpiritGraahkDialogue.java @@ -0,0 +1,81 @@ +package content.global.skill.summoning.familiar; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.TeleportManager.TeleportType; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.game.world.map.zone.impl.WildernessZone; + +/** + * Represents the spirit graahk's dialogue + * @author Splinter + * @version 1.0 + */ +@Initializable +public final class SpiritGraahkDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code GertrudesCatDialogue} {@code Object}. + */ + public SpiritGraahkDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code GertrudesCatDialogue} {@code Object}. + * @param player the player. + */ + public SpiritGraahkDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new SpiritGraahkDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + if (!(npc instanceof Familiar)) { + return false; + } + final Familiar fam = (Familiar) npc; + if (fam.getOwner() != player) { + player.getPacketDispatch().sendMessage("This is not your familiar."); + return true; + } else { + interpreter.sendOptions("Select an Option", "Chat", "Teleport"); + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (buttonId) { + case 1: + player.sendMessage("The Graahk does not feel like talking now."); + end(); + break; + case 2: + if (!WildernessZone.checkTeleport(player, 20)) { + player.sendMessage("You cannot teleport with the Graahk above level 20 wilderness."); + end(); + } else { + player.getTeleporter().send(new Location(2786, 3002), TeleportType.NORMAL); + end(); + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 7353, 7364 }; + } +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/SpiritGraahkNPC.java b/Server/src/main/content/global/skill/summoning/familiar/SpiritGraahkNPC.java new file mode 100644 index 0000000..dd6b489 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/SpiritGraahkNPC.java @@ -0,0 +1,52 @@ +package content.global.skill.summoning.familiar; + +import core.game.node.entity.skill.SkillBonus; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the Spirit Graahk familiar. + * @author Aero + */ +@Initializable +public class SpiritGraahkNPC extends Familiar { + + /** + * Constructs a new {@code SpiritGraahkNPC} {@code Object}. + */ + public SpiritGraahkNPC() { + this(null, 7363); + } + + /** + * Constructs a new {@code SpiritGraahkNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public SpiritGraahkNPC(Player owner, int id) { + super(owner, id, 4900, 12810, 3, WeaponInterface.STYLE_AGGRESSIVE); + boosts.add(new SkillBonus(Skills.HUNTER, 5)); + } + + @Override + public Familiar construct(Player owner, int id) { + return new SpiritGraahkNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + if (!super.isOwnerAttackable()) { + return false; + } + call(); + return true; + } + + @Override + public int[] getIds() { + return new int[] { 7363, 7364 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/SpiritGraahkOptionPlugin.java b/Server/src/main/content/global/skill/summoning/familiar/SpiritGraahkOptionPlugin.java new file mode 100644 index 0000000..44c4678 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/SpiritGraahkOptionPlugin.java @@ -0,0 +1,29 @@ +package content.global.skill.summoning.familiar; + +import core.cache.def.impl.NPCDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the plugin used to handle the spirit graahk familiar + * @author Splinter + */ +@Initializable +public final class SpiritGraahkOptionPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + NPCDefinition.forId(7363).getHandlers().put("option:interact", this); + return this; + } + + @Override + public boolean handle(final Player player, Node node, String option) { + player.getDialogueInterpreter().open(7353, node.asNpc()); + return true; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/SpiritJellyNPC.java b/Server/src/main/content/global/skill/summoning/familiar/SpiritJellyNPC.java new file mode 100644 index 0000000..86ee948 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/SpiritJellyNPC.java @@ -0,0 +1,58 @@ +package content.global.skill.summoning.familiar; + +import core.game.node.entity.skill.Skills; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.game.world.update.flag.context.Animation; + +/** + * Represents the Spirit Jelly familiar. + * @author Aero + */ +@Initializable +public class SpiritJellyNPC extends Familiar { + + /** + * Constructs a new {@code SpiritJellyNPC} {@code Object}. + */ + public SpiritJellyNPC() { + this(null, 6992); + } + + /** + * Constructs a new {@code SpiritJellyNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public SpiritJellyNPC(Player owner, int id) { + super(owner, id, 4300, 12027, 6, WeaponInterface.STYLE_AGGRESSIVE); + } + + @Override + public Familiar construct(Player owner, int id) { + return new SpiritJellyNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + final Entity target = (Entity) special.getNode(); + if (!canCombatSpecial(target)) { + return false; + } + faceTemporary(target, 2); + sendFamiliarHit(target, 13); + animate(Animation.create(8575)); + Projectile.magic(this, target, 1360, 40, 36, 51, 10).send(); + target.getSkills().updateLevel(Skills.ATTACK, -3, target.getSkills().getStaticLevel(Skills.ATTACK) - 3); + return true; + } + + @Override + public int[] getIds() { + return new int[] { 6992, 6993 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/SpiritKalphiteNPC.java b/Server/src/main/content/global/skill/summoning/familiar/SpiritKalphiteNPC.java new file mode 100644 index 0000000..09a8350 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/SpiritKalphiteNPC.java @@ -0,0 +1,84 @@ +package content.global.skill.summoning.familiar; + +import java.util.List; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.game.world.update.flag.context.Graphics; + +/** + * Represents the Spirit Kalphite familiar. + * @author Vexia + * @author Aero + */ +@Initializable +public class SpiritKalphiteNPC extends BurdenBeast { + + /** + * Constructs a new {@code SpiritKalphiteNPC} {@code Object}. + */ + public SpiritKalphiteNPC() { + this(null, 6994); + } + + /** + * Constructs a new {@code SpiritKalphiteNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public SpiritKalphiteNPC(Player owner, int id) { + super(owner, id, 2200, 12063, 6, 6, WeaponInterface.STYLE_DEFENSIVE); + } + + @Override + public Familiar construct(Player owner, int id) { + return new SpiritKalphiteNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + return false; ///bodge this for now, until someone fixes this abomination. +// if (!isOwnerAttackable()) { +// return false; +// } +// final List entitys = RegionManager.getLocalEntitys(owner, 6); +// visualize(Animation.create(8517), Graphics.create(1350)); +// GameWorld.getPulser().submit(new Pulse(1, owner) { +// @Override +// public boolean pulse() { +// int count = 0; +// for (Entity entity : entitys) { +// if (count > 5) { +// return true; +// } +// if (!canCombatSpecial(entity)) { +// continue; +// } +// Projectile.magic(SpiritKalphiteNPC.this, entity, 1349, 40, 36, 50, 5).send(); +// sendFamiliarHit(entity, 20); +// count++; +// } +// return true; +// } +// }); +// return false; + } + + @Override + public String getText() { + return "Hsssss!"; + } + + @Override + public int[] getIds() { + return new int[] { 6994, 6995 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/SpiritKyattDialogue.java b/Server/src/main/content/global/skill/summoning/familiar/SpiritKyattDialogue.java new file mode 100644 index 0000000..e0f3113 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/SpiritKyattDialogue.java @@ -0,0 +1,81 @@ +package content.global.skill.summoning.familiar; + +import core.game.dialogue.DialoguePlugin; +import core.plugin.Initializable; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.TeleportManager.TeleportType; +import core.game.world.map.Location; +import core.game.world.map.zone.impl.WildernessZone; + +/** + * Represents the spirit kyatt's dialogue + * @author Splinter + * @version 1.0 + */ +@Initializable +public final class SpiritKyattDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code GertrudesCatDialogue} {@code Object}. + */ + public SpiritKyattDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code GertrudesCatDialogue} {@code Object}. + * @param player the player. + */ + public SpiritKyattDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new SpiritKyattDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + if (!(npc instanceof Familiar)) { + return false; + } + final Familiar f = (Familiar) npc; + if (f.getOwner() != player) { + player.getPacketDispatch().sendMessage("This is not your follower."); + return true; + } else { + interpreter.sendOptions("Select an Option", "Chat", "Teleport"); + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (buttonId) { + case 1: + player.sendMessage("The Kyatt does not feel like talking now."); + end(); + break; + case 2: + if (!WildernessZone.checkTeleport(player, 20)) { + player.sendMessage("You cannot teleport with the Kyatt above level 20 wilderness."); + end(); + } else { + player.getTeleporter().send(new Location(2326, 3636), TeleportType.NORMAL); + end(); + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 7365, 7366 }; + } +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/SpiritKyattNPC.java b/Server/src/main/content/global/skill/summoning/familiar/SpiritKyattNPC.java new file mode 100644 index 0000000..9bc3c45 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/SpiritKyattNPC.java @@ -0,0 +1,52 @@ +package content.global.skill.summoning.familiar; + +import core.game.node.entity.skill.SkillBonus; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the Spirit Kyatt familiar. + * @author Aero + */ +@Initializable +public class SpiritKyattNPC extends Familiar { + + /** + * Constructs a new {@code SpiritKyattNPC} {@code Object}. + */ + public SpiritKyattNPC() { + this(null, 7366); + } + + /** + * Constructs a new {@code SpiritKyattNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public SpiritKyattNPC(Player owner, int id) { + super(owner, id, 4900, 12812, 3, WeaponInterface.STYLE_ACCURATE); + boosts.add(new SkillBonus(Skills.HUNTER, 5)); + } + + @Override + public Familiar construct(Player owner, int id) { + return new SpiritKyattNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + if (!super.isOwnerAttackable()) { + return false; + } + call(); + return true; + } + + @Override + public int[] getIds() { + return new int[] { 7365, 7366 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/SpiritKyattOptionPlugin.java b/Server/src/main/content/global/skill/summoning/familiar/SpiritKyattOptionPlugin.java new file mode 100644 index 0000000..4cf9122 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/SpiritKyattOptionPlugin.java @@ -0,0 +1,69 @@ +package content.global.skill.summoning.familiar; + +import core.cache.def.impl.NPCDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the plugin used to handle the spirit kyatt familiar and the summoning area. + * @author Splinter + */ +@Initializable +public final class SpiritKyattOptionPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + NPCDefinition.forId(7365).getHandlers().put("option:interact", this); + SceneryDefinition.forId(28741).getHandlers().put("option:open", this); + SceneryDefinition.forId(28743).getHandlers().put("option:climb-up", this); + SceneryDefinition.forId(28743).getHandlers().put("option:climb-up", this); + SceneryDefinition.forId(14910).getHandlers().put("option:take", this); + SceneryDefinition.forId(14912).getHandlers().put("option:take", this); + return this; + } + + private final Item BRONZE_AXE = new Item(1351, 1); + private final Item BRONZE_PICKAXE = new Item(1265, 1); + + @Override + public boolean handle(final Player player, Node node, String option) { + switch(node.getId()){ + case 7365: + player.getDialogueInterpreter().open(7365, node.asNpc()); + break; + case 28741: + player.animate(new Animation(827)); + player.teleport(new Location(2333, 10015)); + break; + case 28743: + player.animate(new Animation(828)); + player.teleport(new Location(2328, 3646)); + break; + case 14912: + if (!player.getInventory().add(BRONZE_AXE)) { + player.getPacketDispatch().sendMessage("You don't have enough inventory space."); + return true; + } + SceneryBuilder.replace(((Scenery) node), ((Scenery) node).transform(14908), 500); + break; + case 14910: + if (!player.getInventory().add(BRONZE_PICKAXE)) { + player.getPacketDispatch().sendMessage("You don't have enough inventory space."); + return true; + } + SceneryBuilder.replace(((Scenery) node), ((Scenery) node).transform(14908), 500); + break; + } + return true; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/SpiritLarupiaNPC.java b/Server/src/main/content/global/skill/summoning/familiar/SpiritLarupiaNPC.java new file mode 100644 index 0000000..64f8c29 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/SpiritLarupiaNPC.java @@ -0,0 +1,60 @@ +package content.global.skill.summoning.familiar; + +import core.plugin.Initializable; +import core.game.node.entity.skill.SkillBonus; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.player.Player; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; + +/** + * Represents the Spirit Larupia familiar. + * @author Aero + */ +@Initializable +public class SpiritLarupiaNPC extends Familiar { + + /** + * Constructs a new {@code SpiritLarupiaNPC} {@code Object}. + */ + public SpiritLarupiaNPC() { + this(null, 7337); + } + + /** + * Constructs a new {@code SpiritLarupiaNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public SpiritLarupiaNPC(Player owner, int id) { + super(owner, id, 4900, 12784, 6, WeaponInterface.STYLE_CONTROLLED); + boosts.add(new SkillBonus(Skills.HUNTER, 5)); + } + + @Override + public Familiar construct(Player owner, int id) { + return new SpiritLarupiaNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + final Entity target = special.getTarget(); + if (!canCombatSpecial(target)) { + return false; + } + target.getSkills().updateLevel(Skills.STRENGTH, -1, target.getSkills().getStaticLevel(Skills.STRENGTH) - 1); + faceTemporary(target, 2); + projectile(target, 1371); + sendFamiliarHit(target, 10); + visualize(Animation.create(5229), Graphics.create(1370)); + return true; + } + + @Override + public int[] getIds() { + return new int[] { 7337, 7338 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/SpiritMosquitoNPC.java b/Server/src/main/content/global/skill/summoning/familiar/SpiritMosquitoNPC.java new file mode 100644 index 0000000..d110462 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/SpiritMosquitoNPC.java @@ -0,0 +1,60 @@ +package content.global.skill.summoning.familiar; + +import core.plugin.Initializable; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.player.Player; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; + +/** + * Represents the Spirit Mosquito familiar. + * @author Vexia + * @author Aero + */ +@Initializable +public class SpiritMosquitoNPC extends Familiar { + + /** + * Constructs a new {@code SpiritMosquitoNPC} {@code Object}. + */ + public SpiritMosquitoNPC() { + this(null, 7331); + } + + /** + * Constructs a new {@code SpiritMosquitoNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public SpiritMosquitoNPC(Player owner, int id) { + super(owner, id, 1200, 12778, 3, WeaponInterface.STYLE_ACCURATE); + } + + @Override + public Familiar construct(Player owner, int id) { + return new SpiritMosquitoNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + final Entity target = (Entity) special.getNode(); + if (!canAttack(target)) { + return false; + } + visualize(Animation.create(8032), Graphics.create(1442)); + getProperties().getCombatPulse().attack(target); + return true; + } + + @Override + public boolean isPoisonImmune() { + return true; + } + + @Override + public int[] getIds() { + return new int[] { 7331, 7332 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/SpiritPengatriceNPC.java b/Server/src/main/content/global/skill/summoning/familiar/SpiritPengatriceNPC.java new file mode 100644 index 0000000..4ed246f --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/SpiritPengatriceNPC.java @@ -0,0 +1,42 @@ +package content.global.skill.summoning.familiar; + +import core.game.node.entity.player.Player; + +/** + * Represents the Spirit Pengatrice familiar. + * @author Aero + */ +public class SpiritPengatriceNPC extends Familiar { + + /** + * Constructs a new {@code SpiritPengatriceNPC} {@code Object}. + */ + public SpiritPengatriceNPC() { + this(null, 6883); + } + + /** + * Constructs a new {@code SpiritPengatriceNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public SpiritPengatriceNPC(Player owner, int id) { + super(owner, id, 3600, 12103, 3); + } + + @Override + public Familiar construct(Player owner, int id) { + return new SpiritPengatriceNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + return false; + } + + @Override + public int[] getIds() { + return new int[] { 6883, 6884 }; + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/summoning/familiar/SpiritScorpionNPC.java b/Server/src/main/content/global/skill/summoning/familiar/SpiritScorpionNPC.java new file mode 100644 index 0000000..85bacaf --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/SpiritScorpionNPC.java @@ -0,0 +1,75 @@ +package content.global.skill.summoning.familiar; + +import core.plugin.Initializable; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.equipment.Weapon; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; + +import static core.api.ContentAPIKt.*; + +/** + * Represents the Spirit Scorpion familiar. + * @author Vexia + * @author Aero + */ +@Initializable +public class SpiritScorpionNPC extends Familiar { + + /** + * Constructs a new {@code SpiritScorpionNPC} {@code Object}. + */ + public SpiritScorpionNPC() { + this(null, 6837); + } + + /** + * Constructs a new {@code SpiritScorpionNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public SpiritScorpionNPC(Player owner, int id) { + super(owner, id, 1700, 12055, 6, WeaponInterface.STYLE_CONTROLLED); + } + + @Override + public Familiar construct(Player owner, int id) { + return new SpiritScorpionNPC(owner, id); + } + + @Override + public void adjustPlayerBattle(BattleState state) { + if (state.getStyle() == CombatStyle.RANGE) { + final Weapon weapon = state.getWeapon(); + if (isCharged() && new Item(weapon.getId() + 6).getName().startsWith(weapon.getName())) { + final Entity victim = state.getVictim(); + setCharged(false); + applyPoison(victim, owner, 1); + } + } + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + if (isCharged()) { + return false; + } + charge(); + owner.graphics(new Graphics(1355, 180), 2); + visualize(new Animation(6261), new Graphics(1354, 95)); + Projectile.create(this, owner, 1355, 95, 50, 50, 10).send(); + return false; + } + + @Override + public int[] getIds() { + return new int[] { 6837, 6838 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/SpiritSpiderNPC.java b/Server/src/main/content/global/skill/summoning/familiar/SpiritSpiderNPC.java new file mode 100644 index 0000000..5857c3b --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/SpiritSpiderNPC.java @@ -0,0 +1,105 @@ +package content.global.skill.summoning.familiar; + +import core.plugin.Initializable; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import core.tools.RandomFunction; + +/** + * Represents the Spirit Spider familiar. + * @author Aero + * @author Vexia + */ +@Initializable +public class SpiritSpiderNPC extends Familiar { + + /** + * The red spider egg item. + */ + private static final Item EGG = new Item(223); + + /** + * The delay until the next chance of random eggs. + */ + private int eggDelay = GameWorld.getTicks() + 500; + + /** + * Constructs a new {@code SpiritSpiderNPC} {@code Object}. + */ + public SpiritSpiderNPC() { + this(null, 6841); + } + + /** + * Constructs a new {@code SpiritSpiderNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public SpiritSpiderNPC(Player owner, int id) { + super(owner, id, 1500, 12059, 6, WeaponInterface.STYLE_CONTROLLED); + } + + @Override + public void handleFamiliarTick() { + super.handleFamiliarTick(); + if (eggDelay < GameWorld.getTicks()) { + if (RandomFunction.random(25) == 5) { + createEggs(); + sendChat("Clicketyclack"); + eggDelay = GameWorld.getTicks() + 500; + } + } + } + + @Override + public Familiar construct(Player owner, int id) { + return new SpiritSpiderNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + createEggs(); + return true; + } + + /** + * Creates red spider eggs. + */ + private void createEggs() { + final int amount = RandomFunction.random(8); + Location location = null; + for (int i = 0; i < amount; i++) { + location = getEggLocation(); + if (location == null) { + continue; + } + owner.getPacketDispatch().sendPositionedGraphic(1342, 0, 0, location); + GroundItemManager.create(EGG, location, owner); + } + animate(Animation.create(5328)); + } + + /** + * Gets the egg location. + * @return the location. + */ + private Location getEggLocation() { + Location loc = owner.getLocation().transform(RandomFunction.random(2) == 1 ? -RandomFunction.random(2) : RandomFunction.random(2), RandomFunction.random(2) == 1 ? -RandomFunction.random(2) : RandomFunction.random(2), 0); + if (loc.equals(owner.getLocation()) || !RegionManager.isTeleportPermitted(loc) || RegionManager.getObject(loc) != null) { + return null; + } + return loc; + } + + @Override + public int[] getIds() { + return new int[] { 6841, 6842 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/SpiritTerrorbirdNPC.java b/Server/src/main/content/global/skill/summoning/familiar/SpiritTerrorbirdNPC.java new file mode 100644 index 0000000..9895522 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/SpiritTerrorbirdNPC.java @@ -0,0 +1,57 @@ +package content.global.skill.summoning.familiar; + +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.player.Player; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; + +/** + * Represents the Spirit Terrorbird familiar. + * @author Aero + * @author Vexia + */ +@Initializable +public class SpiritTerrorbirdNPC extends BurdenBeast { + + /** + * Constructs a new {@code SpiritTerrorbirdNPC} {@code Object}. + */ + public SpiritTerrorbirdNPC() { + this(null, 6794); + } + + /** + * Constructs a new {@code SpiritTerrorbirdNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public SpiritTerrorbirdNPC(Player owner, int id) { + super(owner, id, 3600, 12007, 8, 12, WeaponInterface.STYLE_CONTROLLED); + } + + @Override + public Familiar construct(Player owner, int id) { + return new SpiritTerrorbirdNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + visualize(Animation.create(1009), Graphics.create(1521)); + owner.getSkills().updateLevel(Skills.AGILITY, 2); + owner.getSettings().updateRunEnergy(-owner.getSkills().getStaticLevel(Skills.AGILITY) / 2.0); + return true; + } + + @Override + public void visualizeSpecialMove() { + owner.visualize(new Animation(7660), new Graphics(1295)); + } + + @Override + public int[] getIds() { + return new int[] { 6794, 6795 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/SpiritTzKihNPC.java b/Server/src/main/content/global/skill/summoning/familiar/SpiritTzKihNPC.java new file mode 100644 index 0000000..19f97c6 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/SpiritTzKihNPC.java @@ -0,0 +1,75 @@ +package content.global.skill.summoning.familiar; + +import java.util.List; + +import core.plugin.Initializable; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.player.Player; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; + +/** + * Represents the Spirit Tz-Kih familiar. + * @author Vexia + * @author Aero + */ +@Initializable +public class SpiritTzKihNPC extends Familiar { + + /** + * Constructs a new {@code SpiritTzKihNPC} {@code Object}. + */ + public SpiritTzKihNPC() { + this(null, 7361); + } + + /** + * Constructs a new {@code SpiritTzKihNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public SpiritTzKihNPC(Player owner, int id) { + super(owner, id, 1800, 12808, 6, WeaponInterface.STYLE_CAST); + } + + @Override + public Familiar construct(Player owner, int id) { + return new SpiritTzKihNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + final List entitys = RegionManager.getLocalEntitys(owner, 8); + if (entitys.size() == 0) { + return false; + } + boolean success = false; + Entity target = null; + for (int i = 0; i < 2; i++) { + if (entitys.size() >= i) { + target = entitys.get(i); + if (target == null || target == this || target == owner) { + continue; + } + if (!canCombatSpecial(target)) { + continue; + } + success = true; + sendFamiliarHit(target, 7, Graphics.create(1329)); + } + } + if (success) { + animate(Animation.create(8257)); + return true; + } + return false; + } + + @Override + public int[] getIds() { + return new int[] { 7361, 7362 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/SpiritWolfNPC.java b/Server/src/main/content/global/skill/summoning/familiar/SpiritWolfNPC.java new file mode 100644 index 0000000..9c528bd --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/SpiritWolfNPC.java @@ -0,0 +1,141 @@ +package content.global.skill.summoning.familiar; + +import core.game.activity.CutscenePlugin; +import core.plugin.Initializable; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.path.Path; +import core.game.world.map.path.Pathfinder; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playAudio; + +/** + * Handles the Spirit wolf familiar. + * @author Emperor + */ +@Initializable +public final class SpiritWolfNPC extends Familiar { + + /** + * Represents the cutscene during wolf whistle. + */ + private CutscenePlugin cutscene; + + /** + * Constructs a new {@code SpiritWolfNPC} {@code Object}. + */ + public SpiritWolfNPC() { + this(null, 6829); + } + + /** + * Constructs a new {@code SpiritWolfNPC} {@code Object}. + * @param owner The owner. + * @param id The NPC id. + */ + public SpiritWolfNPC(Player owner, int id) { + super(owner, id, 600, 12047, 3, WeaponInterface.STYLE_ACCURATE); + if (owner != null) { + cutscene = (CutscenePlugin) owner.getAttribute("in-cutscene", null); + } + } + + @Override + public Familiar construct(Player owner, int id) { + return new SpiritWolfNPC(owner, id); + } + + @Override + public void init() { + super.init(); + if (cutscene != null) { + getProperties().setTeleportLocation(cutscene.getBase().transform(44, 52, 1)); + faceLocation(cutscene.getBase().transform(42, 53, 1)); + } + } + + @Override + public void startFollowing() { + if (cutscene != null) { + return; + } + super.startFollowing(); + } + + @Override + public boolean call() { + if (cutscene != null) { + return true; + } + return super.call(); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + if (!(special.getNode() instanceof NPC)) { + owner.getPacketDispatch().sendMessage("You can only target monsters with this special move."); + return false; + } + final NPC npc = (NPC) special.getNode(); + if (npc.getWalkRadius() > 20) { // Usually indicates special NPC. + owner.getPacketDispatch().sendMessage("This monster won't get intimidated by your familiar."); + return false; + } + if (cutscene != null) { + if (npc.getId() != 6990) { + owner.getPacketDispatch().sendMessage("You can't do this right now."); + return false; + } + DialoguePlugin dial = owner.getAttribute("wolf-dial", null); + if (dial != null) { + dial.handle(0, 0); + } else { + cutscene.stop(true); + } + return false; + } + if (!canAttack(npc)) { + return false; + } + visualizeSpecialMove(); + playAudio(owner, Sounds.WOLF_HOWL2_4265); + faceTemporary(npc, owner, 2); + super.visualize(Animation.create(8293), new Graphics(1334, 96)); + Projectile.magic(this, npc, 1333, 40, 36, 50, 5).send(); + GameWorld.getPulser().submit(new Pulse(2, this, npc) { + @Override + public boolean pulse() { + npc.faceTemporary(SpiritWolfNPC.this, 2); + Location destination = npc.getLocation().transform(Direction.getLogicalDirection(location, npc.getLocation()), 3); + Path path = Pathfinder.find(npc, destination); + path.walk(npc); + return true; + } + }); + return true; + } + + @Override + public Location getSpawnLocation() { + if (cutscene != null) { + return cutscene.getBase().transform(44, 52, 1); + } + return super.getSpawnLocation(); + } + + @Override + public int[] getIds() { + return new int[] { 6829, 6830 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/SteelTitanNPC.java b/Server/src/main/content/global/skill/summoning/familiar/SteelTitanNPC.java new file mode 100644 index 0000000..7a52be5 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/SteelTitanNPC.java @@ -0,0 +1,94 @@ +package content.global.skill.summoning.familiar; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.equipment.SwitchAttack; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.player.Player; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.tools.RandomFunction; +import core.game.node.entity.combat.MultiSwingHandler; + +/** + * Handles the Steel titan familiar. + * @author Emperor + */ +@Initializable +public final class SteelTitanNPC extends Familiar { + + /** + * If the titan is using its special move. + */ + private boolean specialMove; + + /** + * The attacks. + */ + private static final SwitchAttack[] ATTACKS = { new SwitchAttack(CombatStyle.RANGE.getSwingHandler(), Animation.create(8190), null, null, Projectile.create(null, null, 1445, 60, 36, 41, 46)), new SwitchAttack(CombatStyle.MAGIC.getSwingHandler(), Animation.create(8190), null, null, Projectile.create(null, null, 1445, 60, 36, 41, 46)), new SwitchAttack(CombatStyle.MELEE.getSwingHandler(), Animation.create(8183)) }; + + /** + * Constructs a new {@code SteelTitanNPC} {@code Object}. + */ + public SteelTitanNPC() { + this(null, 7343); + } + + /** + * Constructs a new {@code SteelTitanNPC} {@code Object}. + * @param owner The owner. + * @param id The NPC id. + */ + public SteelTitanNPC(Player owner, int id) { + super(owner, id, 6400, 12790, 12, WeaponInterface.STYLE_RANGE_ACCURATE); + super.setCombatHandler(new MultiSwingHandler(true, ATTACKS) { + @Override + public int swing(Entity entity, Entity victim, BattleState s) { + int ticks = super.swing(entity, victim, s); + if (specialMove) { + BattleState[] states = new BattleState[4]; + for (int i = 1; i < 4; i++) { + BattleState state = states[i] = new BattleState(entity, victim); + int hit = 0; + if (isAccurateImpact(entity, victim)) { + int max = calculateHit(entity, victim, 1.0); + state.setMaximumHit(max); + hit = RandomFunction.random(max); + } + state.setEstimatedHit(hit); + state.setStyle(getCurrent().getStyle()); + } + states[0] = s; + s.setTargets(states); + specialMove = false; + } + return ticks; + } + }); + } + + @Override + public Familiar construct(Player owner, int id) { + return new SteelTitanNPC(owner, id); + } + + @Override + public int[] getIds() { + return new int[] { 7343, 7344 }; + } + + @Override + public boolean specialMove(FamiliarSpecial special) { + if (specialMove) { + owner.getPacketDispatch().sendMessage("Your familiar is already charging its attack."); + return false; + } + specialMove = true; + visualize(Animation.create(8183), Graphics.create(1449)); + return true; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/StrangerPlantNPC.java b/Server/src/main/content/global/skill/summoning/familiar/StrangerPlantNPC.java new file mode 100644 index 0000000..04d26f2 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/StrangerPlantNPC.java @@ -0,0 +1,63 @@ +package content.global.skill.summoning.familiar; + +import core.plugin.Initializable; +import core.game.node.entity.Entity; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.tools.RandomFunction; + +import static core.api.ContentAPIKt.*; + +/** + * Represents the Stranger Plant familiar. + * @author Aero + */ +@Initializable +public class StrangerPlantNPC extends Forager { + + /** + * Constructs a new {@code StrangerPlantNPC} {@code Object}. + */ + public StrangerPlantNPC() { + this(null, 6827); + } + + /** + * Constructs a new {@code StrangerPlantNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public StrangerPlantNPC(Player owner, int id) { + super(owner, id, 4900, 12045, 6, new Item(464)); + } + + @Override + public Familiar construct(Player owner, int id) { + return new StrangerPlantNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + if (!canCombatSpecial(special.getTarget())) { + return false; + } + Entity target = special.getTarget(); + if (RandomFunction.random(2) == 1) { + applyPoison(target, owner, 20); + } + animate(Animation.create(8211)); + Projectile.ranged(this, target, 1508, 50, 40, 1, 45).send(); + target.graphics(Graphics.create(1511)); + sendFamiliarHit(target, 2); + return false; + } + + @Override + public int[] getIds() { + return new int[] { 6827, 6828 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/SummonFamiliarPlugin.java b/Server/src/main/content/global/skill/summoning/familiar/SummonFamiliarPlugin.java new file mode 100644 index 0000000..ee21603 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/SummonFamiliarPlugin.java @@ -0,0 +1,46 @@ +package content.global.skill.summoning.familiar; + +import core.cache.def.impl.ItemDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.item.Item; +import core.game.world.map.zone.ZoneBorders; +import core.plugin.Initializable; +import core.plugin.Plugin; +import content.data.Quests; + +/** + * Handles summoning a familiar. + * @author Emperor + */ +@Initializable +public final class SummonFamiliarPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ItemDefinition.setOptionHandler("summon", this); + return null; + } + + @Override + public boolean handle(Player player, Node node, String option) { + Item item = (Item) node; + if (!player.getQuestRepository().isComplete(Quests.WOLF_WHISTLE) && player.getAttribute("in-cutscene", null) == null) { + player.getPacketDispatch().sendMessage("You have to complete Wolf Whistle before you can summon a familiar."); + return true; + } + player.getFamiliarManager().summon(item, false); + + // Achievement diary handlers + if (player.getFamiliarManager().hasFamiliar() + && player.getFamiliarManager().getFamiliar() instanceof IbisNPC + && (new ZoneBorders(3011, 3222, 3017, 3229, 0).insideBorder(player) + || new ZoneBorders(3011, 3220, 3015, 3221, 0).insideBorder(player))) { + player.getAchievementDiaryManager().finishTask(player,DiaryType.FALADOR, 2, 9); + } + return true; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/SwampTitanNPC.java b/Server/src/main/content/global/skill/summoning/familiar/SwampTitanNPC.java new file mode 100644 index 0000000..eb9071a --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/SwampTitanNPC.java @@ -0,0 +1,45 @@ +package content.global.skill.summoning.familiar; + +import core.plugin.Initializable; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.player.Player; + +/** + * Represents the Swamp Titan familiar. + * @author Aero + */ +@Initializable +public class SwampTitanNPC extends Familiar { + + /** + * Constructs a new {@code SwampTitanNPC} {@code Object}. + */ + public SwampTitanNPC() { + this(null, 7329); + } + + /** + * Constructs a new {@code SwampTitanNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public SwampTitanNPC(Player owner, int id) { + super(owner, id, 5600, 12776, 6, WeaponInterface.STYLE_ACCURATE); + } + + @Override + public Familiar construct(Player owner, int id) { + return new SwampTitanNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + return false; + } + + @Override + public int[] getIds() { + return new int[] { 7329, 7330 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/TalonBeastNPC.java b/Server/src/main/content/global/skill/summoning/familiar/TalonBeastNPC.java new file mode 100644 index 0000000..b9d8537 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/TalonBeastNPC.java @@ -0,0 +1,45 @@ +package content.global.skill.summoning.familiar; + +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the Talon Beast familiar. + * @author Aero + */ +@Initializable +public class TalonBeastNPC extends Familiar { + + /** + * Constructs a new {@code TalonBeastNPC} {@code Object}. + */ + public TalonBeastNPC() { + this(null, 7347); + } + + /** + * Constructs a new {@code TalonBeastNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public TalonBeastNPC(Player owner, int id) { + super(owner, id, 4900, 12794, 6, WeaponInterface.STYLE_AGGRESSIVE); + } + + @Override + public Familiar construct(Player owner, int id) { + return new TalonBeastNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + return false; + } + + @Override + public int[] getIds() { + return new int[] { 7347, 7348 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/ThornySnailNPC.java b/Server/src/main/content/global/skill/summoning/familiar/ThornySnailNPC.java new file mode 100644 index 0000000..6e3bf4f --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/ThornySnailNPC.java @@ -0,0 +1,84 @@ +package content.global.skill.summoning.familiar; + +import core.plugin.Initializable; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.tools.RandomFunction; + +/** + * Represents the Thorny Snail familiar. + * @author Aero + * @author Vexia + */ +@Initializable +public class ThornySnailNPC extends BurdenBeast { + + /** + * Constructs a new {@code ThornySnailNPC} {@code Object}. + */ + public ThornySnailNPC() { + this(null, 6806); + } + + /** + * Constructs a new {@code ThornySnailNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public ThornySnailNPC(Player owner, int id) { + super(owner, id, 1600, 12019, 3, 3); + } + + @Override + public Familiar construct(Player owner, int id) { + return new ThornySnailNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + final Entity target = (Entity) special.getNode(); + if (!canCombatSpecial(target)) { + return false; + } + visualizeSpecialMove(); + visualize(new Animation(8148, Priority.HIGH), Graphics.create(1385)); + Projectile.magic(this, target, 1386, 40, 36, 51, 10).send(); + int ticks = 2 + (int) Math.floor(getLocation().getDistance(target.getLocation()) * 0.5); + getProperties().getCombatPulse().setNextAttack(4); + faceTemporary(target, 2); + GameWorld.getPulser().submit(new Pulse(ticks, this, target) { + @Override + public boolean pulse() { + BattleState state = new BattleState(ThornySnailNPC.this, target); + int hit = 0; + if (CombatStyle.MAGIC.getSwingHandler().isAccurateImpact(ThornySnailNPC.this, target)) { + hit = RandomFunction.randomize(8); + } + state.setEstimatedHit(hit); + target.getImpactHandler().handleImpact(owner, hit, CombatStyle.MAGIC, state); + target.graphics(new Graphics(1387)); + return true; + } + }); + return true; + } + + @Override + public boolean isPoisonImmune() { + return true; + } + + @Override + public int[] getIds() { + return new int[] { 6806, 6807 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/UnicornStallionNPC.java b/Server/src/main/content/global/skill/summoning/familiar/UnicornStallionNPC.java new file mode 100644 index 0000000..fde55d5 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/UnicornStallionNPC.java @@ -0,0 +1,101 @@ +package content.global.skill.summoning.familiar; + +import core.cache.def.impl.NPCDefinition; +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.player.Player; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Plugin; +import core.plugin.ClassScanner; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.*; + +/** + * Represents the Unicorn Stallion familiar. + * @author Aero + */ +@Initializable +public class UnicornStallionNPC extends Familiar { + + /** + * Constructs a new {@code UnicornStallion} {@code Object}. + */ + public UnicornStallionNPC() { + this(null, 6822); + } + + /** + * Constructs a new {@code UnicornStallion} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public UnicornStallionNPC(Player owner, int id) { + super(owner, id, 5400, 12039, 20, WeaponInterface.STYLE_CONTROLLED); + } + + @Override + public Familiar construct(Player owner, int id) { + return new UnicornStallionNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + Player player = (Player) special.getNode(); + playAudio(player, Sounds.HEALING_AURA_4372); + visualize(Animation.create(8267), Graphics.create(1356)); + player.getSkills().heal((int) (player.getSkills().getMaximumLifepoints() * 0.15)); + return true; + } + + @Override + protected void configureFamiliar() { + ClassScanner.definePlugin(new OptionHandler() { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + NPCDefinition.forId(6822).getHandlers().put("option:cure", this); + NPCDefinition.forId(6823).getHandlers().put("option:cure", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + Familiar familiar = (Familiar) node; + if (!player.getFamiliarManager().isOwner(familiar)) { + return true; + } + Player owner = player; + if (owner.getSkills().getLevel(Skills.MAGIC) < 2) { + player.sendMessage("You don't have enough summoning points left"); + return true; + } + if (!isPoisoned(owner)) { + player.sendMessage("You are not poisoned."); + return true; + } + playAudio(player, Sounds.HEALING_AURA_4372); + familiar.visualize(Animation.create(8267), Graphics.create(1356)); + curePoison(player); + player.getSkills().updateLevel(Skills.SUMMONING, -2, 0); + return true; + } + + }); + } + + @Override + public void visualizeSpecialMove() { + owner.visualize(Animation.create(7660), Graphics.create(1298)); + } + + @Override + public int[] getIds() { + return new int[] { 6822, 6823 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/VampireBatNPC.java b/Server/src/main/content/global/skill/summoning/familiar/VampireBatNPC.java new file mode 100644 index 0000000..5c1007c --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/VampireBatNPC.java @@ -0,0 +1,61 @@ +package content.global.skill.summoning.familiar; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.ImpactHandler.HitsplatType; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.player.Player; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.tools.RandomFunction; + +/** + * Represents the Vampire Bat familiar. + * @author Aero + * @author Vexia + */ +@Initializable +public class VampireBatNPC extends Familiar { + + /** + * Constructs a new {@code VampireBatNPC} {@code Object}. + */ + public VampireBatNPC() { + this(null, 6835); + } + + /** + * Constructs a new {@code VampireBatNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public VampireBatNPC(Player owner, int id) { + super(owner, id, 3300, 12053, 4, WeaponInterface.STYLE_CONTROLLED); + } + + @Override + public Familiar construct(Player owner, int id) { + return new VampireBatNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + final Entity target = (Entity) special.getNode(); + if (!canCombatSpecial(target)) { + return false; + } else { + if (RandomFunction.random(10) < 4) { + owner.getSkills().heal(2); + } + visualize(Animation.create(8275), Graphics.create(1323)); + target.getImpactHandler().manualHit(this, RandomFunction.random(12), HitsplatType.NORMAL); + return true; + } + } + + @Override + public int[] getIds() { + return new int[] { 6835, 6836 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/VoidFamiliarNPC.java b/Server/src/main/content/global/skill/summoning/familiar/VoidFamiliarNPC.java new file mode 100644 index 0000000..4f8d3fa --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/VoidFamiliarNPC.java @@ -0,0 +1,285 @@ +package content.global.skill.summoning.familiar; + +import core.cache.def.impl.NPCDefinition; +import core.plugin.Initializable; +import core.game.node.entity.skill.SkillBonus; +import core.game.node.entity.skill.Skills; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Plugin; +import core.plugin.ClassScanner; + +/** + * The plugin used to load void familiar npcs. + * @author Vexia + * @version 1.0 + */ +@Initializable +public final class VoidFamiliarNPC implements Plugin { + + /** + * The foraging items. + */ + private static final Item[] ITEMS = new Item[] { new Item(434), new Item(440), new Item(453), new Item(444), new Item(447) }; + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ClassScanner.definePlugin(new VoidRavagerNPC()); + ClassScanner.definePlugin(new VoidShifterNPC()); + ClassScanner.definePlugin(new VoidSpinnerNPC()); + ClassScanner.definePlugin(new VoidTorcherNPC()); + return this; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + /** + * Handles the call to arms scroll. + * @param special the special. + * @return {@code True} if so. + */ + public boolean callToArms(Familiar familiar, FamiliarSpecial special) { + final Player owner = familiar.getOwner(); + owner.lock(); + GameWorld.getPulser().submit(new Pulse(1, owner) { + int counter; + + @Override + public boolean pulse() { + switch (++counter) { + case 1: + owner.visualize(Animation.create(8136), Graphics.create(1503)); + break; + case 3: + owner.unlock(); + owner.getProperties().setTeleportLocation(Location.create(2659, 2658, 0)); + owner.visualize(Animation.create(8137), Graphics.create(1502)); + return true; + } + return false; + } + }); + return true; + } + + /** + * Represents the Void Ravager familiar. + * @author Vexia + * @author Aero + */ + public final class VoidRavagerNPC extends Forager { + + /** + * Constructs a new {@code VoidRavagerNPC} {@code Object}. + */ + public VoidRavagerNPC() { + this(null, 7370); + } + + /** + * Constructs a new {@code VoidRavagerNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public VoidRavagerNPC(Player owner, int id) { + super(owner, id, 2700, 12818, 3, WeaponInterface.STYLE_AGGRESSIVE, ITEMS); + boosts.add(new SkillBonus(Skills.MINING, 1)); + } + + @Override + public Familiar construct(Player owner, int id) { + return new VoidRavagerNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + return callToArms(this, special); + } + + @Override + public int[] getIds() { + return new int[] { 7370, 7371 }; + } + + } + + /** + * Represents the Void Shifter familiar. + * @author Aero + */ + public class VoidShifterNPC extends Familiar { + + /** + * Constructs a new {@code VoidShifterNPC} {@code Object}. + */ + public VoidShifterNPC() { + this(null, 7367); + } + + /** + * Constructs a new {@code VoidShifterNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public VoidShifterNPC(Player owner, int id) { + super(owner, id, 9400, 12814, 3, WeaponInterface.STYLE_ACCURATE); + } + + @Override + public Familiar construct(Player owner, int id) { + return new VoidShifterNPC(owner, id); + } + + @Override + public void adjustPlayerBattle(BattleState state) { + super.adjustPlayerBattle(state); + int percentage = (int) (owner.getSkills().getStaticLevel(Skills.HITPOINTS) * 0.10); + if (owner.getSkills().getLifepoints() < percentage) { + owner.getProperties().setTeleportLocation(Location.create(2659, 2658, 0)); + } + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + return callToArms(this, special); + } + + @Override + public int[] getIds() { + return new int[] { 7367, 7368 }; + } + + } + + /** + * Represents the Void Spinner familiar. + * @author Aero + * @author Vexia + */ + public class VoidSpinnerNPC extends Familiar { + + /** + * The delay till the next heal. + */ + private int healDelay; + + /** + * Constructs a new {@code VoidSpinnerNPC} {@code Object}. + */ + public VoidSpinnerNPC() { + this(null, 7333); + } + + /** + * Constructs a new {@code VoidSpinnerNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public VoidSpinnerNPC(Player owner, int id) { + super(owner, id, 2700, 12780, 3, WeaponInterface.STYLE_DEFENSIVE); + } + + @Override + public void handleFamiliarTick() { + super.handleFamiliarTick(); + if (healDelay < GameWorld.getTicks()) { + getSkills().heal(1); + healDelay = GameWorld.getTicks() + 25; + } + } + + @Override + public Familiar construct(Player owner, int id) { + return new VoidSpinnerNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + return callToArms(this, special); + } + + @Override + public int[] getIds() { + return new int[] { 7333, 7334 }; + } + + } + + /** + * Represents the Void Torcher familiar. + * @author Aero + * @author Vexia + * @note TODO: the "Strike" attack. + */ + public class VoidTorcherNPC extends Familiar { + + /** + * Constructs a new {@code VoidTorcherNPC} {@code Object}. + */ + public VoidTorcherNPC() { + this(null, 7351); + } + + /** + * Constructs a new {@code VoidTorcherNPC} {@code Object}. + * @param owner The owner. + * @param id The id. + */ + public VoidTorcherNPC(Player owner, int id) { + super(owner, id, 9400, 12798, 3, WeaponInterface.STYLE_CAST); + } + + @Override + public Familiar construct(Player owner, int id) { + return new VoidTorcherNPC(owner, id); + } + + @Override + public void configureFamiliar() { + ClassScanner.definePlugin(new OptionHandler() { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (int i : getIds()) { + NPCDefinition.forId(i).getHandlers().put("option:strike", this); + } + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + final Familiar familiar = (Familiar) node; + if (!player.getFamiliarManager().isOwner(familiar)) { + return true; + } + // TODO: + return true; + } + + }); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + return callToArms(this, special); + } + + @Override + public int[] getIds() { + return new int[] { 7351, 7352 }; + } + + } +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/WarTortoiseNPC.java b/Server/src/main/content/global/skill/summoning/familiar/WarTortoiseNPC.java new file mode 100644 index 0000000..b3b6455 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/WarTortoiseNPC.java @@ -0,0 +1,55 @@ +package content.global.skill.summoning.familiar; + +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.player.Player; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; + +/** + * Represents the War tortoise familiar. + * @author Emperor + */ +@Initializable +public final class WarTortoiseNPC extends BurdenBeast { + + /** + * Constructs a new {@code WarTortoiseNPC} {@code Object}. + */ + public WarTortoiseNPC() { + this(null, 6815); + } + + /** + * Constructs a new {@code WarTortoiseNPC} {@code Object}. + * @param owner The owner. + * @param id The NPC id. + */ + public WarTortoiseNPC(Player owner, int id) { + super(owner, id, 4300, 12031, 20, 18, WeaponInterface.STYLE_DEFENSIVE); + } + + @Override + public Familiar construct(Player owner, int id) { + return new WarTortoiseNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + owner.getSkills().updateLevel(Skills.DEFENCE, 9, owner.getSkills().getStaticLevel(Skills.DEFENCE) + 9); + visualize(Animation.create(8288), Graphics.create(1414)); + return true; + } + + @Override + public void visualizeSpecialMove() { + owner.visualize(Animation.create(7660), Graphics.create(1310)); + } + + @Override + public int[] getIds() { + return new int[] { 6815, 6816 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/familiar/WolpertingerNPC.java b/Server/src/main/content/global/skill/summoning/familiar/WolpertingerNPC.java new file mode 100644 index 0000000..ff1cfbc --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/familiar/WolpertingerNPC.java @@ -0,0 +1,57 @@ +package content.global.skill.summoning.familiar; + +import core.plugin.Initializable; +import core.game.node.entity.skill.SkillBonus; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.player.Player; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; + +/** + * Represents the Wolpertinger familiar. + * @author Aero + */ +@Initializable +public class WolpertingerNPC extends Familiar { + + /** + * Constructs a new {@code WolpertingerNPC} {@code Object}. + */ + public WolpertingerNPC() { + this(null, 6869); + } + + /** + * Constructs a new {@code WolpertingerNPC} {@code Object}. + * @param owner The owner. + * @param id The NPC id. + */ + public WolpertingerNPC(Player owner, int id) { + super(owner, id, 6200, 12089, 1, WeaponInterface.STYLE_CAST); + boosts.add(new SkillBonus(Skills.HUNTER, 5)); + } + + @Override + public Familiar construct(Player owner, int id) { + return new WolpertingerNPC(owner, id); + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + owner.getSkills().updateLevel(Skills.MAGIC, 7, (owner.getSkills().getStaticLevel(Skills.MAGIC) + 7)); + visualize(Animation.create(8267), Graphics.create(1464)); + return true; + } + + @Override + public void visualizeSpecialMove() { + owner.visualize(Animation.create(7660), Graphics.create(1306)); + } + + @Override + public int[] getIds() { + return new int[] { 6869, 6870 }; + } + +} diff --git a/Server/src/main/content/global/skill/summoning/pet/IncubatorEgg.java b/Server/src/main/content/global/skill/summoning/pet/IncubatorEgg.java new file mode 100644 index 0000000..11a6a02 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/pet/IncubatorEgg.java @@ -0,0 +1,102 @@ +package content.global.skill.summoning.pet; + +import core.game.node.item.Item; + +/** + * An egg to put in the incubator. + * @author Vexia + */ +public enum IncubatorEgg { + PENGUIN(new Item(12483), 30, 30, new Item(12481)), + RAVEN(new Item(11964), 50, 30, new Item(12484)), + SARADOMIN_OWL(new Item(5077), 70, 60, new Item(12503)), + ZAMORAK_HAWK(new Item(5076), 70, 60, new Item(12506)), + GUTHIX_RAPTOR(new Item(5078), 70, 60, new Item(12509)), + VULTURE(new Item(11965), 85, 60, new Item(12498)), + CHAMELEON(new Item(12494), 90, 60, new Item(12492)), + RED_DRAGON(new Item(12477), 99, 60, new Item(12469)), + BLACK_DRAGON(new Item(12480), 99, 60, new Item(12475)), + BLUE_DRAGON(new Item(12478), 99, 60, new Item(12471)), + GREEN_DRAGON(new Item(12479), 99, 60, new Item(12473)); + + /** + * The egg item. + */ + private final Item egg; + + /** + * The level. + */ + private final int level; + + /** + * The incubation time. + */ + private final int inucbationTime; + + /** + * The product item. + */ + private final Item product; + + /** + * Constructs a new {@Code IncubatorEgg} {@Code Object} + * @param egg the egg. + * @param level the level. + * @param inucbationTime the incubation time. + * @param product the product. + */ + private IncubatorEgg(Item egg, int level, int inucbationTime, Item product) { + this.egg = egg; + this.level = level; + this.inucbationTime = inucbationTime; + this.product = product; + } + + /** + * Gets an egg by the item. + * @param item the item. + * @return the egg. + */ + public static IncubatorEgg forItem(Item item) { + for (IncubatorEgg e : values()) { + if (e.getEgg().getId() == item.getId()) { + return e; + } + } + return null; + } + + /** + * Gets the egg. + * @return the egg + */ + public Item getEgg() { + return egg; + } + + /** + * Gets the level. + * @return the level + */ + public int getLevel() { + return level; + } + + /** + * Gets the inucbationTime. + * @return the inucbationTime + */ + public int getInucbationTime() { + return inucbationTime; + } + + /** + * Gets the product. + * @return the product + */ + public Item getProduct() { + return product; + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/summoning/pet/IncubatorHandler.kt b/Server/src/main/content/global/skill/summoning/pet/IncubatorHandler.kt new file mode 100644 index 0000000..edb11ca --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/pet/IncubatorHandler.kt @@ -0,0 +1,73 @@ +package content.global.skill.summoning.pet + +import core.api.* +import core.game.node.Node +import core.game.node.entity.player.Player +import core.game.interaction.* +import core.tools.StringUtils + +class IncubatorHandler : InteractionListener { + val eggIds = IncubatorEgg.values().map { it.egg.id }.toIntArray() + val incubators = intArrayOf(28550, 28352, 28359) + + override fun defineListeners() { + on (incubators, IntType.SCENERY, "inspect", handler = ::handleInspectOption) + on (incubators, IntType.SCENERY, "take-egg", handler = ::handleTakeOption) + onUseWith (IntType.SCENERY, eggIds, *incubators, handler = ::handleEggOnIncubator) + } + + fun handleEggOnIncubator (player: Player, used: Node, with: Node) : Boolean { + val egg = IncubatorEgg.forItem (used.asItem()) ?: return false + val activeEgg = IncubatorTimer.getEggFor (player, player.location.regionId) + + if (activeEgg != null) { + sendMessage (player, "You already have an egg in this incubator.") + return true + } + + if (removeItem(player, used.asItem())) + IncubatorTimer.registerEgg (player, player.location.regionId, egg) + return true + } + + fun handleInspectOption (player: Player, node: Node) : Boolean { + val activeEgg = IncubatorTimer.getEggFor (player, player.location.regionId) + + if (activeEgg == null) { + sendMessage (player, "The incubator is currently empty.") + return true + } + + if (activeEgg.finished) { + sendMessage (player, "The egg inside has finished incubating.") + return true + } + + val creatureName = activeEgg.egg.product.name.lowercase() + sendMessage (player, "There is currently ${if (StringUtils.isPlusN(creatureName)) "an" else "a"} $creatureName egg incubating.") + return true + } + + fun handleTakeOption (player: Player, node: Node) : Boolean { + val region = player.location.regionId + val activeEgg = IncubatorTimer.getEggFor (player, region) ?: return false + + if (!activeEgg.finished) { + sendMessage (player, "That egg hasn't finished incubating!") + return true + } + + if (freeSlots(player) < 1) { + sendMessage (player, "You do not have enough inventory space to do that.") + return true + } + + val egg = IncubatorTimer.removeEgg (player, region) ?: return false + val product = egg.product + val name = product.name.lowercase() + + sendMessage(player, "You take your $name out of the incubator.") + addItem(player, product.id) + return true + } +} diff --git a/Server/src/main/content/global/skill/summoning/pet/IncubatorTimer.kt b/Server/src/main/content/global/skill/summoning/pet/IncubatorTimer.kt new file mode 100644 index 0000000..899deee --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/pet/IncubatorTimer.kt @@ -0,0 +1,105 @@ +package content.global.skill.summoning.pet + +import core.api.* +import core.tools.* +import core.game.system.timer.* +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import java.util.* +import org.json.simple.* + +class IncubatorTimer : PersistTimer (500, "incubation") { + val incubatingEggs = HashMap() + + override fun getInitialRunDelay() : Int { + return 50 + } + + override fun parse (root: JSONObject, entity: Entity) { + val eggs = root["eggs"] as? JSONArray ?: return + for (eggData in eggs) { + val eggInfo = eggData as JSONArray + val egg = IncubatingEgg ( + eggInfo[0].toString().toInt(), + IncubatorEgg.values()[eggInfo[1].toString().toInt()], + eggInfo[2].toString().toLong(), + eggInfo[3].toString().toBoolean() + ) + incubatingEggs[egg.region] = egg + } + } + + override fun save (root: JSONObject, entity: Entity) { + val arr = JSONArray() + for ((_, eggInfo) in incubatingEggs) { + val eggArr = JSONArray() + eggArr.add(eggInfo.region.toString()) + eggArr.add(eggInfo.egg.ordinal.toString()) + eggArr.add(eggInfo.endTime.toString()) + eggArr.add(eggInfo.finished) + arr.add(eggArr) + } + root["eggs"] = arr + } + + override fun onRegister(entity: Entity) { + if (entity !is Player) return + for ((region, _) in incubatingEggs) { + setVarbit(entity.asPlayer(), varbitForRegion(region), 1, true) + } + } + + override fun run (entity: Entity) : Boolean { + if (entity !is Player) return false + for ((_, egg) in incubatingEggs) { + if (egg.finished) continue + if (egg.isDone()) { + sendMessage(entity, colorize("%RYour ${egg.egg.product.name.lowercase()} egg has finished hatching.")) + egg.finished = true + } + } + return !incubatingEggs.isEmpty() + } + + data class IncubatingEgg (val region: Int, val egg: IncubatorEgg, var endTime: Long, var finished: Boolean = false) + fun IncubatingEgg.isDone() : Boolean { + return endTime < System.currentTimeMillis() + } + + companion object { + val TAVERLEY_REGION = 11573 + val TAVERLEY_VARBIT = 4277 + val YANILLE_REGION = 10288 + val YANILLE_VARBIT = 4221 + + fun varbitForRegion (region: Int) : Int { + return when (region) { + TAVERLEY_REGION -> TAVERLEY_VARBIT + YANILLE_REGION -> YANILLE_VARBIT + else -> -1 + } + } + + fun getEggFor (player: Player, region: Int) : IncubatingEgg? { + val playerTimer = getTimer(player) ?: return null + return playerTimer.incubatingEggs[region] + } + + fun registerEgg (player: Player, region: Int, egg: IncubatorEgg) { + val timer = getTimer(player) ?: IncubatorTimer() + timer.incubatingEggs [region] = IncubatingEgg (region, egg, System.currentTimeMillis() + (ticksToSeconds(egg.inucbationTime * 100) * 1000)) + + if (!hasTimerActive(player)) + registerTimer(player, timer) + setVarbit(player, varbitForRegion(region), 1, true) + } + + fun removeEgg (player: Player, region: Int) : IncubatorEgg? { + val egg = getEggFor (player, region) ?: return null + val timer = getTimer(player) ?: return null + timer.incubatingEggs.remove(region) + setVarbit(player, varbitForRegion(region), 0, true) + return egg.egg + } + } +} diff --git a/Server/src/main/content/global/skill/summoning/pet/KittenInteractDialogue.java b/Server/src/main/content/global/skill/summoning/pet/KittenInteractDialogue.java new file mode 100644 index 0000000..8925c4c --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/pet/KittenInteractDialogue.java @@ -0,0 +1,145 @@ +package content.global.skill.summoning.pet; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.RegionManager; +import core.game.world.map.path.Path; +import core.game.world.map.path.Pathfinder; +import core.plugin.Initializable; +import core.game.world.update.flag.context.Animation; + +/** + * Represents the dialogue plugin used for kitten interactions. + * @author Vexia + * @version 1.0 + */ +@Initializable +public final class KittenInteractDialogue extends DialoguePlugin { + + /** + * Represents the animation to use. + */ + private static final Animation PLAYER_STROKE_ANIMATION = new Animation(9224); + private static final Animation KITTEN_STROKE_ANIMATION = new Animation(9173); + + /** + * Constructs a new {@code KittenInterfactDialogue} {@code Object}. + */ + public KittenInteractDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code KittenInterfactDialogue} {@code Object}. + * @param player the player. + */ + public KittenInteractDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new KittenInteractDialogue(player); + } + + @Override + public boolean open(Object... args) { + interpreter.sendOptions("Interact with Kitten", "Stroke", "Chase vermin", "Shoo away"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + switch (buttonId) { + case 1:// stroke + player.getFamiliarManager().getFamiliar().face(player); + player.animate(PLAYER_STROKE_ANIMATION); + player.getFamiliarManager().getFamiliar().animate(KITTEN_STROKE_ANIMATION); + player.getFamiliarManager().getFamiliar().sendChat("Purr...purr..."); + interpreter.sendDialogues(player, null, "That cat sure loves to be stroked."); + stage = 99; + break; + case 2:// chase-vermine + end(); + player.sendChat("Go on puss...kill that rat!"); + boolean cant = true; + NPC rat = null; + for (NPC n : RegionManager.getLocalNpcs(player.getLocation(), 10)) { + if (!n.getName().contains("rat")) { + cant = false; + continue; + } + if (n.getLocation().getDistance(player.getFamiliarManager().getFamiliar().getLocation()) < 8) { + cant = true; + rat = n; + break; + } else { + cant = false; + } + } + if (!cant) { + player.getPacketDispatch().sendMessage("Your cat cannot get to its prey."); + } else { + player.getFamiliarManager().getFamiliar().sendChat("Meeeoooooowwww!"); + final Path path = Pathfinder.find(player.getFamiliarManager().getFamiliar(), rat); + path.walk(player.getFamiliarManager().getFamiliar()); + rat.sendChat("Eeek!"); + GameWorld.getPulser().submit(new Pulse(5) { + + @Override + public boolean pulse() { + player.getFamiliarManager().getFamiliar().call(); + player.getPacketDispatch().sendMessage("The rat manages to get away!"); + return true; + } + + }); + } + break; + case 3:// shoo-away + interpreter.sendOptions("Are you sure?", "Yes I am.", "No I'm not."); + stage = 560; + break; + } + break; + case 560: + switch (buttonId) { + case 1:// yes + if (player.getFamiliarManager().hasFamiliar()) { //in case the cat had already run away from hunger by the time the player clicked 'yes' + player.sendChat("Shoo cat!"); + Pet currentPet = (Pet) player.getFamiliarManager().getFamiliar(); + player.getFamiliarManager().getFamiliar().sendChat("Miaow!"); + player.getFamiliarManager().getFamiliar().dismiss(); + player.getFamiliarManager().removeDetails(currentPet.getItemId()); + player.getPacketDispatch().sendMessage("The cat has run away."); + } + end(); + break; + case 2:// no + end(); + break; + } + break; + case 99: + if (player.getFamiliarManager().hasFamiliar()) { + player.getFamiliarManager().getFamiliar().sendChat("Miaow!"); + } + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 343823 }; + } +} diff --git a/Server/src/main/content/global/skill/summoning/pet/Pet.java b/Server/src/main/content/global/skill/summoning/pet/Pet.java new file mode 100644 index 0000000..bb83f16 --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/pet/Pet.java @@ -0,0 +1,209 @@ +package content.global.skill.summoning.pet; + +import content.global.skill.skillcapeperks.SkillcapePerks; +import content.global.skill.summoning.familiar.Familiar; +import content.global.skill.summoning.familiar.FamiliarSpecial; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.GameWorld; + +import static core.api.ContentAPIKt.*; + +/** + * Represents a pet. + * @author Emperor + * @author 'Vexia + * @author Player Name + */ +public final class Pet extends Familiar { + + /** + * The item id. + */ + private final int itemId; + + /** + * The pet details. + */ + private final PetDetails details; + + /** + * The growth rate of the pet. + */ + private final double growthRate; + + /** + * The pets type. + */ + private final Pets pet; + + /** + * Whether a hunger warning has been fired yet; 0 = none, 1 = hungry, 2 = starving. + */ + private int hasWarned = 0; + + /** + * Constructs a new {@code Pet} {@code Object}. + * @param owner the owner. + * @param details the details. + * @param itemId the itemId. + * @param id the id. + */ + public Pet(Player owner, final PetDetails details, int itemId, int id) { + super(owner, id, -1, -1, -1); + this.pet = Pets.forId(itemId); + this.details = details; + this.itemId = itemId; + this.growthRate = pet.getGrowthRate(); + } + + @Override + public void sendConfiguration() { + setVarp(owner, 1175, ((int) details.getGrowth() << 1) | ((int) details.getHunger() << 9)); + setVarp(owner, 1174, getId()); + setVarp(owner, 448, itemId); + } + + @Override + public void handleTickActions() { + final PetDetails petDetails = details; + if (getPet().getFood().length > 0) { + if(!SkillcapePerks.isActive(SkillcapePerks.PET_MASTERY, owner)) { + double amount = itemId == pet.getBabyItemId() ? 0.025 : 0.018; + if (GameWorld.getSettings().isDevMode()) { + amount *= 100; + } + petDetails.updateHunger(amount); + } + } + double hunger = petDetails.getHunger(); + if (hunger >= 75.0 && hunger <= 90.0 && hasWarned < 1) { + owner.sendMessage("Your pet is getting hungry."); + hasWarned = 1; + } + else if (hunger >= 90.0 && hasWarned < 2) { + owner.getPacketDispatch().sendMessage("Your pet is starving, feed it before it runs off."); + hasWarned = 2; + } + if (hunger >= 100.0 && growthRate != 0 && pet.getFood().length != 0) { + owner.getFamiliarManager().dismiss(); + owner.getFamiliarManager().removeDetails(getItemId()); + owner.getFamiliarManager().setFamiliar(null); + setVarp(owner, 1175, 0); + owner.sendMessage("Your pet has run away."); + return; + } + double growth = petDetails.getGrowth(); + double growthrate = pet.getGrowthRate(); + if (growthrate > 0.000) { + if (GameWorld.getSettings().isDevMode()) { + growthrate *= 100; + } + petDetails.updateGrowth(growthrate); + if (growth == 100.0) { + growNextStage(); + } + } + if ((!isInvisible() && owner.getLocation().getDistance(getLocation()) > 12) || (isInvisible() && ticks % 25 == 0)) { + if (!call()) { + setInvisible(true); + } + } else if (!getPulseManager().hasPulseRunning()) { + startFollowing(); + } + setVarp(owner, 1175, ((int) details.getGrowth() << 1) | ((int) details.getHunger() << 9)); + } + + /** + * Method used to grow the npc's next stage. + */ + public void growNextStage() { + if (pet == null) { + return; + } + int newItemId = pet.getNextStageItemId(itemId); + if (newItemId == -1) { + // then this pet is already overgrown + return; + } + if (pet.isKitten(itemId)) { + owner.incrementAttribute("/save:stats_manager:cats_raised"); + } + owner.getFamiliarManager().removeDetails(getItemId()); + owner.getFamiliarManager().addDetails(newItemId, details); + owner.getFamiliarManager().morphPet(new Item(newItemId), false, location, details.getHunger(), 0); + owner.getPacketDispatch().sendMessage("Your pet has grown larger."); + } + + @Override + public Familiar construct(Player owner, int id) { + return this; + } + + @Override + protected boolean specialMove(FamiliarSpecial special) { + return false; + } + + @Override + public boolean isCombatFamiliar() { + return false; + } + + /** + * Gets the itemId. + * @return The itemId. + */ + public int getItemId() { + return itemId; + } + + /** + * Gets the details. + * @return The details. + */ + public PetDetails getDetails() { + return details; + } + + /** + * Gets the pet. + * @return The pet. + */ + public Pets getPet() { + return pet; + } + + /** + * Gets the hunger level. + */ + public double getHunger() { + return details.getHunger(); + } + + /** + * Gets the growth level. + */ + public double getGrowth() { + return details.getGrowth(); + } + + /** + * Gets the hunger warning level. + */ + public int getHasWarned() { + return hasWarned; + } + + /** + * Sets the hunger warning level. + */ + public void setHasWarned(int value) { + this.hasWarned = value; + } + + @Override + public int[] getIds() { + return new int[] { 761, 762, 763, 764, 765, 766, 3505, 3598, 6969, 7259, 7260, 6964, 7249, 7251, 6960, 7241, 7243, 6962, 7245, 7247, 6966, 7253, 7255, 6958, 7237, 7239, 6915, 7277, 7278, 7279, 7280, 7018, 7019, 7020, 6908, 7313, 7316, 6947, 7293, 7295, 7297, 7299, 6911, 7261, 7263, 7265, 7267, 7269, 6919, 7301, 7303, 7305, 7307, 6949, 6952, 6955, 6913, 7271, 7273, 6945, 7319, 7321, 7323, 7325, 7327, 6922, 6942, 7210, 7212, 7214, 7216, 7218, 7220, 7222, 7224, 7226, 6900, 6902, 6904, 6906, 768, 769, 770, 771, 772, 773, 3504, 6968, 7257, 7258, 6965, 7250, 7252, 6961, 7242, 7244, 6963, 7246, 7248, 6967, 7254, 7256, 6859, 7238, 7240, 6916, 7281, 7282, 7283, 7284, 7015, 7016, 7017, 6909, 7314, 7317, 6948, 7294, 7296, 7298, 7300, 6912, 7262, 7264, 7266, 7268, 7270, 6920, 7302, 7304, 7306, 7308, 6950, 6953, 6956, 6914, 7272, 7274, 6946, 7320, 7322, 7324, 7326, 7328, 6923, 6943, 7211, 7213, 7215, 7217, 7219, 7221, 7223, 7225, 7227, 6901, 6903, 6905, 6907, 774, 775, 776, 777, 778, 779, 3503, 6951, 6954, 6957 }; + } +} diff --git a/Server/src/main/content/global/skill/summoning/pet/PetDetails.java b/Server/src/main/content/global/skill/summoning/pet/PetDetails.java new file mode 100644 index 0000000..b3b0b8f --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/pet/PetDetails.java @@ -0,0 +1,83 @@ +package content.global.skill.summoning.pet; + + + +/** + * A class containing pet details for a certain pet. + * @author Emperor + * @author Player Name + */ +public final class PetDetails { + + /** + * The hunger rate. + */ + private double hunger = 0.0; + + /** + * The growth rate. + */ + private double growth = 0.0; + + /** + * Constructs a new {@code PetDetails} {@code Object}. + * @param growth The growth value. + */ + public PetDetails(double growth) { + this.growth = growth; + } + + /** + * Increases the hunger value by the given amount. + * @param amount The amount. + */ + public void updateHunger(double amount) { + hunger += amount; + if (hunger < 0.0) { + hunger = 0.0; + } + } + + /** + * Increases the growth value by the given amount. + * @param amount The amount. + */ + public void updateGrowth(double amount) { + growth += amount; + if (growth < 0.0) { + growth = 0.0; + } else if (growth > 100.0) { + growth = 100.0; + } + } + + /** + * Gets the hunger. + * @return The hunger. + */ + public double getHunger() { + return hunger; + } + + /** + * Sets the hunger. (You probably want to use updateHunger() instead.) + */ + public void setHunger(double value) { + this.hunger = value; + } + + /** + * Gets the growth. + * @return The growth. + */ + public double getGrowth() { + return growth; + } + + /** + * Sets the growth. (You probably want to use updateGrowth() instead.) + */ + public void setGrowth(double value) { + this.growth = value; + } +} diff --git a/Server/src/main/content/global/skill/summoning/pet/Pets.java b/Server/src/main/content/global/skill/summoning/pet/Pets.java new file mode 100644 index 0000000..263d04a --- /dev/null +++ b/Server/src/main/content/global/skill/summoning/pet/Pets.java @@ -0,0 +1,449 @@ +package content.global.skill.summoning.pet; + +import core.game.node.entity.player.Player; +import core.tools.Log; + +import java.util.HashMap; +import java.util.Map; + +import static core.api.ContentAPIKt.log; + +/** + * An enum containing all the pets and their info. + * @author Emperor + * @author Player Name + */ +public enum Pets { + + /** + * A cat/kitten pet. + */ + CAT(1555, 1561, 1567, 761, 768, 774, 0.0154320987654321, 0, 321, 319, 363, 365, 341, 339, 15264, 345, 347, 377, 379, 353, 355, 389, 391, 7944, 7946, 349, 351, 331, 329, 327, 325, 395, 397, 383, 385, 317, 315, 371, 373, 335, 333, 359, 361, 15264, 15270, 1927), CAT_1(1556, 1562, 1568, 762, 769, 775, 0.0154320987654321, 0, 321, 319, 363, 365, 341, 339, 15264, 345, 347, 377, 379, 353, 355, 389, 391, 7944, 7946, 349, 351, 331, 329, 327, 325, 395, 397, 383, 385, 317, 315, 371, 373, 335, 333, 359, 361, 15264, 15270, 1927), CAT_2(1557, 1563, 1569, 763, 770, 776, 0.0154320987654321, 0, 321, 319, 363, 365, 341, 339, 15264, 345, 347, 377, 379, 353, 355, 389, 391, 7944, 7946, 349, 351, 331, 329, 327, 325, 395, 397, 383, 385, 317, 315, 371, 373, 335, 333, 359, 361, 15264, 15270, 1927), CAT_3(1558, 1564, 1570, 764, 771, 777, 0.0154320987654321, 0, 321, 319, 363, 365, 341, 339, 15264, 345, 347, 377, 379, 353, 355, 389, 391, 7944, 7946, 349, 351, 331, 329, 327, 325, 395, 397, 383, 385, 317, 315, 371, 373, 335, 333, 359, 361, 15264, 15270, 1927), CAT_4(1559, 1565, 1571, 765, 772, 778, 0.0154320987654321, 0, 321, 319, 363, 365, 341, 339, 15264, 345, 347, 377, 379, 353, 355, 389, 391, 7944, 7946, 349, 351, 331, 329, 327, 325, 395, 397, 383, 385, 317, 315, 371, 373, 335, 333, 359, 361, 15264, 15270, 1927), CAT_5(1560, 1566, 1572, 766, 773, 779, 0.0154320987654321, 0, 321, 319, 363, 365, 341, 339, 15264, 345, 347, 377, 379, 353, 355, 389, 391, 7944, 7946, 349, 351, 331, 329, 327, 325, 395, 397, 383, 385, 317, 315, 371, 373, 335, 333, 359, 361, 15264, 15270, 1927), HELLCAT(7583, 7582, 7581, 3505, 3504, 3503, 0.0154320987654321, 0, 321, 319, 363, 365, 341, 339, 15264, 345, 347, 377, 379, 353, 355, 389, 391, 7944, 7946, 349, 351, 331, 329, 327, 325, 395, 397, 383, 385, 317, 315, 371, 373, 335, 333, 359, 361, 15264, 15270, 1927), CAT_6(14089, 14090, 15092, 8217, 8214, 8216, 0.0154320987654321, 0, 321, 319, 363, 365, 341, 339, 15264, 345, 347, 377, 379, 353, 355, 389, 391, 7944, 7946, 349, 351, 331, 329, 327, 325, 395, 397, 383, 385, 317, 315, 371, 373, 335, 333, 359, 361, 15264, 15270, 1927), + + /** + * A clockwork cat. + */ + CLOCKWORK_CAT(7771, 7772, -1, 3598, -1, -1, 0.0, 0), + + /** + * The firemaker's curse pets. + */ + SEARING_FLAME(22994, -1, -1, 14769, -1, -1, 0.0, 0), GLOWING_EMBER(22993, -1, -1, 14768, -1, -1, 0.0, 0), TWISTED_FIRESTARTER(22995, -1, -1, 14770, -1, -1, 0.0, 0), WARMING_FLAME(22992, -1, -1, 14767, -1, -1, 0.0, 0), + + /** + * Troll baby pet. + */ + TROLL_BABY(23030, 23030, -1, 14846, -1, -1, 0.0, 0), + + /** + * A bulldog pet. + */ + BULLDOG(12522, 12523, -1, 6969, 6968, -1, 0.0033333333333333, 4, 2132, 2134, 2136, 2138, 10816, 9986, 9978, 526), BULLDOG_1(12720, 12721, -1, 7259, 7257, -1, 0.0033333333333333, 4, 2132, 2134, 2136, 2138, 10816, 9986, 9978, 526), BULLDOG_2(12722, 12723, -1, 7260, 7258, -1, 0.0033333333333333, 4, 2132, 2134, 2136, 2138, 10816, 9986, 9978, 526), + + /** + * A dalmation pet. + */ + DALMATIAN(12518, 12519, -1, 6964, 6965, -1, 0.0033333333333333, 4, 2132, 2134, 2136, 2138, 10816, 9986, 9978, 526), DALMATIAN_1(12712, 12713, -1, 7249, 7250, -1, 0.0033333333333333, 4, 2132, 2134, 2136, 2138, 10816, 9986, 9978, 526), DALMATIAN_2(12714, 12715, -1, 7251, 7252, -1, 0.0033333333333333, 4, 2132, 2134, 2136, 2138, 10816, 9986, 9978, 526), + + /** + * A greyhound pet. + */ + GREYHOUND(12514, 12515, -1, 6960, 6961, -1, 0.0033333333333333, 4, 2132, 2134, 2136, 2138, 10816, 9986, 9978, 526), GREYHOUND_1(12704, 12705, -1, 7241, 7242, -1, 0.0033333333333333, 4, 2132, 2134, 2136, 2138, 10816, 9986, 9978, 526), GREYHOUND_2(12706, 12707, -1, 7243, 7244, -1, 0.0033333333333333, 4, 2132, 2134, 2136, 2138, 10816, 9986, 9978, 526), + + /** + * A labrador pet. + */ + LABRADOR(12516, 12517, -1, 6962, 6963, -1, 0.0033333333333333, 4, 2132, 2134, 2136, 2138, 10816, 9986, 9978, 526), LABRADOR_1(12708, 12709, -1, 7245, 7246, -1, 0.0033333333333333, 4, 2132, 2134, 2136, 2138, 10816, 9986, 9978, 526), LABRADOR_2(12710, 12711, -1, 7247, 7248, -1, 0.0033333333333333, 4, 2132, 2134, 2136, 2138, 10816, 9986, 9978, 526), + + /** + * A sheepdog pet. + */ + SHEEPDOG(12520, 12521, -1, 6966, 6967, -1, 0.0033333333333333, 4, 2132, 2134, 2136, 2138, 10816, 9986, 9978, 526), SHEEPDOG_1(12716, 12717, -1, 7253, 7254, -1, 0.0033333333333333, 4, 2132, 2134, 2136, 2138, 10816, 9986, 9978, 526), SHEEPDOG_2(12718, 12719, -1, 7255, 7256, -1, 0.0033333333333333, 4, 2132, 2134, 2136, 2138, 10816, 9986, 9978, 526), + + /** + * A terrier pet. + */ + TERRIER(12512, 12513, -1, 6958, 6859, -1, 0.0033333333333333, 4, 2132, 2134, 2136, 2138, 10816, 9986, 9978, 526), TERRIER_1(12700, 12701, -1, 7237, 7238, -1, 0.0033333333333333, 4, 2132, 2134, 2136, 2138, 10816, 9986, 9978, 526), TERRIER_2(12702, 12703, -1, 7239, 7240, -1, 0.0033333333333333, 4, 2132, 2134, 2136, 2138, 10816, 9986, 9978, 526), + + /** + * A creeping hand pet. + */ + //CREEPING_HAND(14652, -1, -1, 8619, -1, -1, 0.0033333333333333, 4, 1059), + + /** + * Minitrice pet. + */ + //MINITRICE(14653, -1, -1, 8620, -1, -1, 0.0033333333333333, 4, 225), + + /** + * Baby basilisk pet. + */ + //BABY_BASILISK(14654, -1, -1, 8621, -1, -1, 0.0033333333333333, 4, 221), + + /** + * Baby kurask pet. + */ + //BABY_KURASK(14655, -1, -1, 8622, -1, -1, 0.0033333333333333, 4, 526), + + /** + * Abyssal minion pet. + */ + //ABYSSAL_MINION(14651, -1, -1, 8624, -1, -1, 0.0033333333333333, 4, 592), + + /** + * Rune guardian pets. + */ + RUNE_GUARDIAN(15626, -1, -1, 9656, -1, -1, 0.0033333333333333, 4), RUNE_GUARDIAN_1(15627, -1, -1, 9657, -1, -1, 0.0033333333333333, 4), RUNE_GUARDIAN_2(15628, -1, -1, 9658, -1, -1, 0.0033333333333333, 4), RUNE_GUARDIAN_3(15629, -1, -1, 9659, -1, -1, 0.0033333333333333, 4), RUNE_GUARDIAN_4(15630, -1, -1, 9660, -1, -1, 0.0033333333333333, 4), RUNE_GUARDIAN_5(15631, -1, -1, 9661, -1, -1, 0.0033333333333333, 4), RUNE_GUARDIAN_6(15632, -1, -1, 9662, -1, -1, 0.0033333333333333, 4), RUNE_GUARDIAN_7(15633, -1, -1, 9663, -1, -1, 0.0033333333333333, 4), RUNE_GUARDIAN_8(15634, -1, -1, 9664, -1, -1, 0.0033333333333333, 4), RUNE_GUARDIAN_9(15635, -1, -1, 9665, -1, -1, 0.0033333333333333, 4), RUNE_GUARDIAN_10(15636, -1, -1, 9666, -1, -1, 0.0033333333333333, 4), RUNE_GUARDIAN_11(15637, -1, -1, 9667, -1, -1, 0.0033333333333333, 4), RUNE_GUARDIAN_12(15638, -1, -1, 9668, -1, -1, 0.0033333333333333, 4), RUNE_GUARDIAN_13(15639, -1, -1, 9669, -1, -1, 0.0033333333333333, 4), + + /** + * Gecko pet. + */ + GECKO(12488, 12489, -1, 6915, 6916, -1, 0.005, 10, 12125, 12127), GECKO_1(12738, 12742, -1, 7277, 7281, -1, 0.005, 10, 12125, 12127), GECKO_2(12739, 12743, -1, 7278, 7282, -1, 0.005, 10, 12125, 12127), GECKO_3(12740, 12744, -1, 7279, 7283, -1, 0.005, 10, 12125, 12127), GECKO_4(12741, 12745, -1, 7280, 7284, -1, 0.005, 10, 12125, 12127), + + /** + * The platypus pet. + */ + PLATYPUS(12551, 12548, -1, 7018, 7015, -1, 0.0046296296296296, 10, 321, 363, 341, 15264, 345, 377, 353, 389, 7944, 349, 331, 327, 395, 383, 317, 371, 335, 359, 15264, 15270, 313, 12129), PLATYPUS_1(12552, 12549, -1, 7019, 7016, -1, 0.0046296296296296, 10, 321, 363, 341, 15264, 345, 377, 353, 389, 7944, 349, 331, 327, 395, 383, 317, 371, 335, 359, 15264, 15270, 313, 12129), PLATYPUS_2(12553, 12550, -1, 7020, 7017, -1, 0.0046296296296296, 10, 321, 363, 341, 15264, 345, 377, 353, 389, 7944, 349, 331, 327, 395, 383, 317, 371, 335, 359, 15264, 15270, 313, 12129), + + /** + * The broav pet. + */ + BROAV(14533, -1, -1, 8491, -1, -1, 0.0, 23, 2970), + + /** + * The penguin pet. + */ + PENGUIN(12481, 12482, -1, 6908, 6909, -1, 0.0046296296296296, 30, 321, 363, 341, 15264, 345, 377, 353, 389, 7944, 349, 331, 327, 395, 383, 317, 371, 335, 359, 15264, 15270), PENGUIN_1(12763, 12762, -1, 7313, 7314, -1, 0.0046296296296296, 30, 321, 363, 341, 15264, 345, 377, 353, 389, 7944, 349, 331, 327, 395, 383, 317, 371, 335, 359, 15264, 15270), PENGUIN_2(12765, 12764, -1, 7316, 7317, -1, 0.0046296296296296, 30, 321, 363, 341, 15264, 345, 377, 353, 389, 7944, 349, 331, 327, 395, 383, 317, 371, 335, 359, 15264, 15270), + + /** + * A tooth creature pet. + */ + TOOTH_CREATURE(18671, 18669, -1, 11411, 11413, -1, 0.075757575757576, 37, 1927, 1977), + + /** + * A giant crab pet. + */ + GIANT_CRAB(12500, 12501, -1, 6947, 6948, -1, 0.0069444444444444, 40, 321, 363, 341, 15264, 345, 377, 353, 389, 7944, 349, 331, 327, 395, 383, 317, 371, 335, 359, 15264, 15270), GIANT_CRAB_1(12746, 12747, -1, 7293, 7294, -1, 0.0069444444444444, 40, 321, 363, 341, 15264, 345, 377, 353, 389, 7944, 349, 331, 327, 395, 383, 317, 371, 335, 359, 15264, 15270), GIANT_CRAB_2(12748, 12749, -1, 7295, 7296, -1, 0.0069444444444444, 40, 321, 363, 341, 15264, 345, 377, 353, 389, 7944, 349, 331, 327, 395, 383, 317, 371, 335, 359, 15264, 15270), GIANT_CRAB_3(12750, 12751, -1, 7297, 7298, -1, 0.0069444444444444, 40, 321, 363, 341, 15264, 345, 377, 353, 389, 7944, 349, 331, 327, 395, 383, 317, 371, 335, 359, 15264, 15270), GIANT_CRAB_4(12752, 12753, -1, 7299, 7300, -1, 0.0069444444444444, 40, 321, 363, 341, 15264, 345, 377, 353, 389, 7944, 349, 331, 327, 395, 383, 317, 371, 335, 359, 15264, 15270), + + /** + * A Raven pet. + */ + RAVEN(12484, 12485, -1, 6911, 6912, -1, 0.00698888, 50, 313, 12129), RAVEN_1(12724, 12725, -1, 7261, 7262, -1, 0.00698888, 50, 313, 12129), RAVEN_2(12726, 12727, -1, 7263, 7264, -1, 0.00698888, 50, 313, 12129), RAVEN_3(12728, 12729, -1, 7265, 7266, -1, 0.00698888, 50, 313, 12129), RAVEN_4(12730, 12731, -1, 7267, 7268, -1, 0.00698888, 50, 313, 12129), RAVEN_5(12732, 12733, -1, 7269, 7270, -1, 0.00698888, 50, 313, 12129), + + /** + * A squirrel pet. + */ + SQUIRREL(12490, 12491, -1, 6919, 6920, -1, 0.0071225071225071, 60, 12130), SQUIRREL_1(12754, 12755, -1, 7301, 7302, -1, 0.0071225071225071, 60, 12130), SQUIRREL_2(12756, 12757, -1, 7303, 7304, -1, 0.0071225071225071, 60, 12130), SQUIRREL_3(12758, 12759, -1, 7305, 7306, -1, 0.0071225071225071, 60, 12130), SQUIRREL_4(12760, 12761, -1, 7307, 7308, -1, 0.0071225071225071, 60, 12130), + + /** + * Godbirds. + */ + SARADOMIN_OWL(12503, 12504, 12505, 6949, 6950, 6951, 0.0069444444444444, 70, 313, 12129), ZAMORAK_HAWK(12506, 12507, 12508, 6952, 6953, 6954, 0.0069444444444444, 70, 313, 12129), GUTHIX_RAPTOR(12509, 12510, 12511, 6955, 6956, 6957, 0.0069444444444444, 70, 313, 12129), + + /** + * Ex-ex parrot + */ + EX_EX_PARROT(13335, -1, -1, 7844, -1, -1, 0.0, 71, 13379), + + /** + * The phoenix eggling pets. + */ + CUTE_PHOENIX_EGGLING(14627, -1, -1, 8578, -1, -1, 0.0, 72, 592), MEAN_PHOENIX_EGGLING(14626, -1, -1, 8577, -1, -1, 0.0, 72, 592), + + /** + * A raccoon pet. + */ + RACCOON(12486, 12487, -1, 6913, 6914, -1, 0.0029444444444444, 80, 321, 363, 341, 15264, 345, 377, 353, 389, 7944, 349, 331, 327, 395, 383, 317, 371, 335, 359, 15264, 15270, 2132, 2134, 2136, 2138, 10816, 9986, 9978), RACCOON_1(12734, 12735, -1, 7271, 7272, -1, 0.0029444444444444, 80, 321, 363, 341, 15264, 345, 377, 353, 389, 7944, 349, 331, 327, 395, 383, 317, 371, 335, 359, 15264, 15270, 2132, 2134, 2136, 2138, 10816, 9986, 9978), RACCOON_2(12736, 12737, -1, 7273, 7274, -1, 0.0029444444444444, 80, 321, 363, 341, 15264, 345, 377, 353, 389, 7944, 349, 331, 327, 395, 383, 317, 371, 335, 359, 15264, 15270, 2132, 2134, 2136, 2138, 10816, 9986, 9978), + + /** + * A sneaker peeper pet. + */ + SNEAKER_PEEPER(19894, 19895, -1, 13089, 13090, -1, 0.05, 80, 221), + + /** + * A vulture pet. + */ + VULTURE(12498, 12499, -1, 6945, 6946, -1, 0.0078, 85, 313, 12129), VULTURE_1(12766, 12767, -1, 7319, 7320, -1, 0.0078, 85, 313, 12129), VULTURE_2(12768, 12769, -1, 7321, 7322, -1, 0.0078, 85, 313, 12129), VULTURE_3(12770, 12771, -1, 7323, 7324, -1, 0.0078, 85, 313, 12129), VULTURE_4(12772, 12773, -1, 7325, 7326, -1, 0.0078, 85, 313, 12129), VULTURE_5(12774, 12775, -1, 7327, 7328, -1, 0.0078, 85, 313, 12129), + + /** + * A chameleon pet. + */ + CHAMELEON(12492, 12493, -1, 6922, 6923, -1, 0.0069444444444444, 90, 12125), + + /** + * A monkey pet. + */ + MONKEY(12496, 12497, -1, 6942, 6943, -1, 0.0069444444444444, 95, 1963), MONKEY_1(12682, 12683, -1, 7210, 7211, -1, 0.0069444444444444, 95, 1963), MONKEY_2(12684, 12685, -1, 7212, 7213, -1, 0.0069444444444444, 95, 1963), MONKEY_3(12686, 12687, -1, 7214, 7215, -1, 0.0069444444444444, 95, 1963), MONKEY_4(12688, 12689, -1, 7216, 7217, -1, 0.0069444444444444, 95, 1963), MONKEY_5(12690, 12691, -1, 7218, 7219, -1, 0.0069444444444444, 95, 1963), MONKEY_6(12692, 12693, -1, 7220, 7221, -1, 0.0069444444444444, 95, 1963), MONKEY_7(12694, 12695, -1, 7222, 7223, -1, 0.0069444444444444, 95, 1963), MONKEY_8(12696, 12697, -1, 7224, 7225, -1, 0.0069444444444444, 95, 1963), MONKEY_9(12698, 12699, -1, 7226, 7227, -1, 0.0069444444444444, 95, 1963), + + /** + * A baby dragon pet. + */ + BABY_DRAGON(12469, 12470, -1, 6900, 6901, -1, 0.0052, 99, 2132, 2134, 2136, 2138, 10816, 9986, 9978, 321, 363, 341, 15264, 345, 377, 353, 389, 7944, 349, 331, 327, 395, 383, 317, 371, 335, 359, 15264, 15270), BABY_DRAGON_1(12471, 12472, -1, 6902, 6903, -1, 0.0052, 99, 2132, 2134, 2136, 2138, 10816, 9986, 9978, 321, 363, 341, 15264, 345, 377, 353, 389, 7944, 349, 331, 327, 395, 383, 317, 371, 335, 359, 15264, 15270), BABY_DRAGON_2(12473, 12474, -1, 6904, 6905, -1, 0.0052, 99, 2132, 2134, 2136, 2138, 10816, 9986, 9978, 321, 363, 341, 15264, 345, 377, 353, 389, 7944, 349, 331, 327, 395, 383, 317, 371, 335, 359, 15264, 15270), BABY_DRAGON_3(12475, 12476, -1, 6906, 6907, -1, 0.0052, 99, 2132, 2134, 2136, 2138, 10816, 9986, 9978, 321, 363, 341, 15264, 345, 377, 353, 389, 7944, 349, 331, 327, 395, 383, 317, 371, 335, 359, 15264, 15270); + + /** + * The baby pets mapping. + */ + private static final Map babyPets = new HashMap(); + + /** + * The grown pets mapping. + */ + private static final Map grownPets = new HashMap(); + + /** + * The overgrown pets mapping. + */ + private static final Map overgrownPets = new HashMap(); + + /** + * Populates the mappings. + */ + static { + for (Pets pet : Pets.values()) { + babyPets.put(pet.babyItemId, pet); + if (pet.grownItemId > 0) { + grownPets.put(pet.grownItemId, pet); + if (pet.getOvergrownItemId() > 0) { + overgrownPets.put(pet.overgrownItemId, pet); + } + } + } + } + + /** + * Gets the pet object for the item id. + * @param itemId The item id. + * @return The pet object. + */ + public static Pets forId(int itemId) { + Pets pet = babyPets.get(itemId); + if (pet == null) { + pet = grownPets.get(itemId); + if (pet == null) { + return overgrownPets.get(itemId); + } + return pet; + } + return pet; + } + + /** + * Checks if a player has a pet. + * @param player The player. + * @return {@code True} if so. + */ + public static boolean hasPet(Player player) { + for (int itemId : babyPets.keySet()) { + if (player.getInventory().containsAtLeastOneItem(itemId)) { + return true; + } + } + for (int itemId : grownPets.keySet()) { + if (player.getInventory().containsAtLeastOneItem(itemId)) { + return true; + } + } + for (int itemId : overgrownPets.keySet()) { + if (player.getInventory().containsAtLeastOneItem(itemId)) { + return true; + } + } + return false; + } + + /** + * The baby item id. + */ + private final int babyItemId; + + /** + * The grown pet's item id. + */ + private final int grownItemId; + + /** + * The overgrown pet's item id. + */ + private final int overgrownItemId; + + /** + * The baby pet NPC id. + */ + private final int babyNpcId; + + /** + * The grown pet NPC id. + */ + private final int grownNpcId; + + /** + * The overgrown pet NPC id. + */ + private final int overgrownNpcId; + + /** + * The growth rate. + */ + private final double growthRate; + + /** + * The summoning level required. + */ + private final int summoningLevel; + + /** + * The food this pet uses. + */ + private final int[] food; + + /** + * Constructs a new {@code Pets} {@code Object}. + * @param babyItemId The baby pet item id. + * @param grownItemId The grown pet item id. + * @param overgrownItemId The overgrown item id. + * @param babyNpcId The baby pet npc id. + * @param grownNpcId The grown pet npc id. + * @param overgrownNpcId The overgrown npc id. + * @param growthRate The growth rate (amount to increase growth with every + * tick). + * @param summoningLevel The summoning level required. + * @param food The food item ids the pet uses. + */ + private Pets(int babyItemId, int grownItemId, int overgrownItemId, int babyNpcId, int grownNpcId, int overgrownNpcId, double growthRate, int summoningLevel, int... food) { + this.babyItemId = babyItemId; + this.grownItemId = grownItemId; + this.overgrownItemId = overgrownItemId; + this.babyNpcId = babyNpcId; + this.grownNpcId = grownNpcId; + this.overgrownNpcId = overgrownNpcId; + this.growthRate = growthRate; + this.summoningLevel = summoningLevel; + this.food = food; + } + + /** + * Gets the babyItemId. + * @return The babyItemId. + */ + public int getBabyItemId() { + return babyItemId; + } + + /** + * Gets the grownItemId. + * @return The grownItemId. + */ + public int getGrownItemId() { + return grownItemId; + } + + /** + * Gets the overgrownItemId. + * @return The overgrownItemId. + */ + public int getOvergrownItemId() { + return overgrownItemId; + } + + /** + * Gets the babyNpcId. + * @return The babyNpcId. + */ + public int getBabyNpcId() { + return babyNpcId; + } + + /** + * Gets the grownNpcId. + * @return The grownNpcId. + */ + public int getGrownNpcId() { + return grownNpcId; + } + + /** + * Gets the overgrownNpcId. + * @return The overgrownNpcId. + */ + public int getOvergrownNpcId() { + return overgrownNpcId; + } + + /** + * Gets the growthRate. + * @return The growthRate. + */ + public double getGrowthRate() { + return growthRate; + } + + /** + * Gets the summoningLevel. + * @return The summoningLevel. + */ + public int getSummoningLevel() { + return summoningLevel; + } + + /** + * Gets the food. + * @return The food. + */ + public int[] getFood() { + return food; + } + + /** + * Gets the NPC id for this pet. + * @param itemId An int giving the ID of the item for which we want to know the corresponding NPC id. + * @return The NPC id. + */ + public int getNpcId(int itemId) { + if (itemId == babyItemId) { + return babyNpcId; + } + if (itemId == grownItemId) { + return grownNpcId; + } + if (itemId == overgrownItemId) { + return overgrownNpcId; + } + log(this.getClass(), Log.ERR, "Could not locate NPC ID for pet item " + itemId); + return -1; + } + + /** + * Gets the next growth stage's item ID for this pet. + * @param itemId An int giving the current pet's item ID. + * @return The item ID for the next growth stage, or -1 if there isn't any (i.e. pet is already overgrown). + */ + public int getNextStageItemId(int itemId) { + if (itemId == babyItemId) { + return grownItemId; + } + if (itemId == grownItemId) { + return overgrownItemId; + } + return -1; + } + + /** + * Checks if this pet is a kitten + * @return a boolean, true if the pet is a kitten + */ + public boolean isKitten(int id) { + switch (this) { + case CAT: + case CAT_1: + case CAT_2: + case CAT_3: + case CAT_4: + case CAT_5: + case CAT_6: + case HELLCAT: + return id == babyItemId; + default: + return false; + } + } +} diff --git a/Server/src/main/content/global/skill/thieving/PickableDoorHandler.java b/Server/src/main/content/global/skill/thieving/PickableDoorHandler.java new file mode 100644 index 0000000..7014d07 --- /dev/null +++ b/Server/src/main/content/global/skill/thieving/PickableDoorHandler.java @@ -0,0 +1,267 @@ +package content.global.skill.thieving; + +import core.cache.def.impl.SceneryDefinition; +import core.game.global.action.DoorActionHandler; +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.ImpactHandler; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.plugin.Plugin; +import core.tools.RandomFunction; + +import java.util.ArrayList; +import java.util.List; + +import static core.api.ContentAPIKt.sendMessage; + +/** + * Represents a pickable door. + * @author Vexia + */ +@Initializable +public class PickableDoorHandler extends OptionHandler { + /** + * The lock pick item. + */ + private static final Item LOCK_PICK = new Item(1523); + + private static final List pickableDoors = new ArrayList<>(20); + + private static final int[] DOORS = new int[]{42028, 2550, 2551, 2554, 2555, 2556, 2557, 2558, 2559, 5501, 7246, 9565, 13314, 13317, 13320, 13323, 13326, 13344, 13345, 13346, 13347, 13348, 13349, 15759, 34005, 34805, 34806, 34812}; + + PickableDoor door; + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (int i : DOORS) { + SceneryDefinition.forId(i).getHandlers().put("option:pick-lock", this); + SceneryDefinition.forId(i).getHandlers().put("option:open", this); + } + pickableDoors.add(new PickableDoor(new Location[]{Location.create(2672, 3308, 0)}, 1, 3.8)); + pickableDoors.add(new PickableDoor(new Location[]{Location.create(2672, 3301, 0)}, 14, 15)); + pickableDoors.add(new PickableDoor(new Location[]{Location.create(2610, 3316, 0)}, 15, 15)); + pickableDoors.add(new PickableDoor(new Location[]{Location.create(3190, 3957, 0)}, 32, 25, true)); + pickableDoors.add(new PickableDoor(new Location[]{Location.create(2565, 3356, 0)}, 46, 37.5)); + pickableDoors.add(new PickableDoor(new Location[]{Location.create(2579, 3286, 1)}, 61, 50)); + pickableDoors.add(new PickableDoor(new Location[]{Location.create(2579, 3307, 1)}, 61, 50)); + pickableDoors.add(new PickableDoor(new Location[]{Location.create(3018, 3187, 0)}, 1, 0.0)); + pickableDoors.add(new PickableDoor(new Location[]{Location.create(2601, 9482, 0)}, 82, 0.0, true)); + pickableDoors.add(new PickableDoor(new Location[]{Location.create(3044, 3956, 0)}, 39, 35.0, true, true)); + pickableDoors.add(new PickableDoor(new Location[]{Location.create(3041, 3959, 0)}, 39, 35.0, true, true)); + pickableDoors.add(new PickableDoor(new Location[]{Location.create(3038, 3956, 0)}, 39, 35.0, true, true)); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + door = forDoor(node.getLocation()); + if (option.equals("open")) { + if (door == null) { + player.getPacketDispatch().sendMessage("The door is locked."); + return true; + } + door.open(player, (Scenery) node); + return true; + } + if (option.equals("pick-lock")) { + if (door == null) { + sendMessage(player, "This door cannot be unlocked."); + return true; + } + door.pickLock(player, (Scenery) node); + return true; + } + + return false; + } + + @Override + public Location getDestination(Node node, Node n) { + if (n instanceof Scenery) { + Scenery object = (Scenery) n; + if (object.getDefinition().hasAction("pick-lock")) { + return DoorActionHandler.getDestination((Entity) node, object); + } + } + return null; + } + + private PickableDoor forDoor(Location location) { + for (PickableDoor door : pickableDoors) { + for (Location l : door.getLocations()) { + if (l.equals(location)) { + return door; + } + } + } + return null; + } + + public class PickableDoor{ + /** + * The locations of the door. + */ + private final Location[] locations; + + /** + * The level. + */ + private final int level; + + /** + * The experience required. + */ + private final double experience; + + /** + * If it requires a lockpick. + */ + private final boolean lockpick; + + /** + * If the door should be flipped around when checking for which side requires lockpicking. + */ + private final boolean flipped; + + /** + * Constructs a new {@code PickableDoor} {@code Object}. + * @param locations the locations. + * @param level the level. + * @param experience the experience. + * @param lockpick the lock pick. + * @param flipped the door to be flipped when lockpicking. + */ + public PickableDoor(final Location[] locations, int level, double experience, boolean lockpick, boolean flipped) { + this.locations = locations; + this.level = level; + this.experience = experience; + this.lockpick = lockpick; + this.flipped = flipped; + } + + /** + * Constructs a new {@code PickableDoor} {@code Object}. + * @param locations the locations. + * @param level the level. + * @param experience the experience. + * @param lockpick the lock pick. + */ + public PickableDoor(final Location[] locations, int level, double experience, boolean lockpick) { + this(locations, level, experience, lockpick, false); + } + + /** + * Constructs a new {@code PickableDoor} {@code Object}. + * @param level the level. + * @param experience the experience. + */ + public PickableDoor(Location[] locations, int level, double experience) { + this(locations, level, experience, false); + } + + /** + * Gets the location. + * @return The location. + */ + public Location[] getLocations() { + return locations; + } + + /** + * Opens a pickable door. + * @param player the player. + * @param object the object. + */ + public void open(Player player, Scenery object) { + if (isInside(player, object) != flipped) { + DoorActionHandler.handleAutowalkDoor(player, object); + player.getPacketDispatch().sendMessage("You go through the door."); + } else { + player.getPacketDispatch().sendMessage("The door is locked."); + } + } + + /** + * Picks a lock on a door. + * @param player the player. + * @param object the object. + */ + public void pickLock(Player player, Scenery object) { + boolean success = RandomFunction.random(12) >= 4; + if (isInside(player, object) != flipped) { + player.getPacketDispatch().sendMessage("The door is already unlocked."); + return; + } + if (player.getSkills().getLevel(Skills.THIEVING) < level) { + player.sendMessage("You attempt to pick the lock."); + boolean hit = RandomFunction.random(10) < 5; + player.getImpactHandler().manualHit(player, RandomFunction.random(1, 3), ImpactHandler.HitsplatType.NORMAL); + player.sendMessage(hit ? "You have activated a trap on the lock." : "You fail to pick the lock."); + return; + } + if (lockpick && !player.getInventory().containsItem(LOCK_PICK)) { + player.sendMessage("You need a lockpick in order to pick this lock."); + return; + } + if (success) { + player.getSkills().addExperience(Skills.THIEVING, experience, true); + DoorActionHandler.handleAutowalkDoor(player, object); + } + player.getPacketDispatch().sendMessage("You attempt to pick the lock."); + player.getPacketDispatch().sendMessage("You " + (success ? "manage" : "fail") + " to pick the lock."); + } + + /** + * Checks if we're behind the door/inside the building. + * @param player the player. + * @param object the object. + * @return {@code True} if so. + */ + private boolean isInside(Player player, Scenery object) { + boolean inside = false; + Direction dir = Direction.getLogicalDirection(player.getLocation(), object.getLocation()); + Direction direction = object.getDirection(); + if (direction == Direction.SOUTH && dir == Direction.WEST) { + inside = true; + } else if (direction == Direction.EAST && dir == Direction.SOUTH) { + inside = true; + } else if (direction == Direction.NORTH && dir == Direction.EAST) { + inside = true; + } + return inside; + } + + /** + * Gets the level. + * @return The level. + */ + public int getLevel() { + return level; + } + + /** + * Gets the experience. + * @return The experience. + */ + public double getExperience() { + return experience; + } + + /** + * Gets the lockpick. + * @return The lockpick. + */ + public boolean isLockpick() { + return lockpick; + } + } + +} + diff --git a/Server/src/main/content/global/skill/thieving/Pickpockets.kt b/Server/src/main/content/global/skill/thieving/Pickpockets.kt new file mode 100644 index 0000000..4580f25 --- /dev/null +++ b/Server/src/main/content/global/skill/thieving/Pickpockets.kt @@ -0,0 +1,203 @@ +package content.global.skill.thieving + +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.tools.RandomFunction +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import core.api.utils.WeightBasedTable +import core.api.utils.WeightedItem +import java.util.stream.IntStream + +enum class Pickpockets(val ids: IntArray, val requiredLevel: Int, val low: Double, val high: Double, val experience: Double, val stunDamageMin: Int, val stunDamageMax: Int, val stunTime: Int, val table: WeightBasedTable) { + MAN(intArrayOf(1, 2, 3, 4, 5, 6, 16, 24, 25, 170, 1086, 2683, 2684, 3224, 3915, 3226, 3227, 5924, 5923), 1, 180.0, 240.0, 8.0, 1, 1,5, WeightBasedTable.create( + WeightedItem(Items.COINS_995,3,3,1.0,true) + )), + FARMER(intArrayOf(7, 1757, 1758), 10, 180.0, 240.0, 14.5, 1,1,5, WeightBasedTable.create( + WeightedItem(Items.COINS_995,9,9,1.0,true), + WeightedItem(Items.POTATO_SEED_5318,1,1,1.0,true) + )), + MALE_HAM_MEMBER(intArrayOf(1714), 20, 117.0, 240.0, 22.5, 1,3,4, WeightBasedTable.create( + WeightedItem(Items.COINS_995,1,21,5.5), + WeightedItem(Items.TINDERBOX_590,1,1,5.0), + WeightedItem(Items.LOGS_1511,1,1,7.0), + WeightedItem(Items.UNCUT_JADE_1627,1,1,2.5), + WeightedItem(Items.UNCUT_OPAL_1625,1,1,2.5), + WeightedItem(Items.RAW_ANCHOVIES_321,1,1,7.0), + WeightedItem(Items.RAW_CHICKEN_2138,1,1,3.5), + WeightedItem(Items.HAM_CLOAK_4304,1,1,0.25), + WeightedItem(Items.HAM_HOOD_4302,1,1,0.25), + WeightedItem(Items.HAM_LOGO_4306,1,1,0.25), + WeightedItem(Items.HAM_ROBE_4300,1,1,0.25), + WeightedItem(Items.HAM_SHIRT_4298,1,1,0.25), + WeightedItem(Items.BOOTS_4310,1,1,1.0), + WeightedItem(Items.GLOVES_4308,1,1,1.0), + WeightedItem(Items.BRONZE_PICKAXE_1265,1,1,5.0), + WeightedItem(Items.IRON_PICKAXE_1267,1,1,5.0), + WeightedItem(Items.STEEL_PICKAXE_1269,1,1,2.5), + WeightedItem(Items.GRIMY_GUAM_199,1,1,2.0), + WeightedItem(Items.GRIMY_HARRALANDER_205,1,1,2.0), + WeightedItem(Items.GRIMY_KWUARM_213,1,1,2.0), + WeightedItem(Items.GRIMY_MARRENTILL_201,1,1,1.5), + WeightedItem(Items.RUSTY_SWORD_686,1,1,3.5), + WeightedItem(Items.BROKEN_ARMOUR_698,1,1,3.5), + WeightedItem(Items.BROKEN_STAFF_689,1,1,3.2), + WeightedItem(Items.BROKEN_ARROW_687,1,1,3.1), + WeightedItem(Items.BUTTONS_688,1,1,3.0) + ).insertEasyClue(1.0)), + FEMALE_HAM_MEMBER(intArrayOf(1715), 15, 135.0, 240.0, 18.5, 1,3,4, WeightBasedTable.create( + WeightedItem(Items.COINS_995,1,21,5.5), + WeightedItem(Items.TINDERBOX_590,1,1,5.0), + WeightedItem(Items.LOGS_1511,1,1,7.0), + WeightedItem(Items.UNCUT_JADE_1627,1,1,2.5), + WeightedItem(Items.UNCUT_OPAL_1625,1,1,2.5), + WeightedItem(Items.RAW_ANCHOVIES_321,1,1,7.0), + WeightedItem(Items.RAW_CHICKEN_2138,1,1,3.5), + WeightedItem(Items.HAM_CLOAK_4304,1,1,0.25), + WeightedItem(Items.HAM_HOOD_4302,1,1,0.25), + WeightedItem(Items.HAM_LOGO_4306,1,1,0.25), + WeightedItem(Items.HAM_SHIRT_4298,1,1,0.25), + WeightedItem(Items.HAM_ROBE_4300,1,1,0.25), + WeightedItem(Items.BOOTS_4310,1,1,1.0), + WeightedItem(Items.GLOVES_4308,1,1,1.0), + WeightedItem(Items.BRONZE_PICKAXE_1265,1,1,5.0), + WeightedItem(Items.IRON_PICKAXE_1267,1,1,5.0), + WeightedItem(Items.STEEL_PICKAXE_1269,1,1,2.5), + WeightedItem(Items.GRIMY_GUAM_199,1,1,2.0), + WeightedItem(Items.GRIMY_HARRALANDER_205,1,1,2.0), + WeightedItem(Items.GRIMY_KWUARM_213,1,1,2.0), + WeightedItem(Items.GRIMY_MARRENTILL_201,1,1,1.5), + WeightedItem(Items.RUSTY_SWORD_686,1,1,3.5), + WeightedItem(Items.BROKEN_ARMOUR_698,1,1,3.5), + WeightedItem(Items.BROKEN_STAFF_689,1,1,3.2), + WeightedItem(Items.BROKEN_ARROW_687,1,1,3.1), + WeightedItem(Items.BUTTONS_688,1,1,3.0) + ).insertEasyClue(1.0)), + WARRIOR(intArrayOf(15, 18), 25, 84.0, 240.0, 26.0, 2, 2, 5, WeightBasedTable.create( + WeightedItem(Items.COINS_995,18,18,1.0,true) + )), + ROGUE(intArrayOf(187, 2267, 2268, 2269, 8122), 32, 74.0, 240.0,35.5, 2, 2, 5, WeightBasedTable.create( + WeightedItem(Items.COINS_995,25,40,5.0,true), + WeightedItem(Items.JUG_OF_WINE_1993,1,1,6.0), + WeightedItem(Items.AIR_RUNE_556,8,8,8.0), + WeightedItem(Items.LOCKPICK_1523,1,1,5.0), + WeightedItem(Items.IRON_DAGGERP_1219,1,1,1.0) + )), + CAVE_GOBLIN(IntStream.rangeClosed(5752, 5768).toArray(), 36, 72.0, 240.0, 40.0, 1,1,5, WeightBasedTable.create( + WeightedItem(Items.COINS_995,30,30,6.5), + WeightedItem(Items.OIL_LAMP_4522,1,1,0.5), + WeightedItem(Items.BULLSEYE_LANTERN_4544,1,1,0.5), + WeightedItem(Items.UNLIT_TORCH_596,1,1,0.5), + WeightedItem(Items.TINDERBOX_590,1,1,0.5), + WeightedItem(Items.SWAMP_TAR_1939,1,1,0.5), + WeightedItem(Items.IRON_ORE_441,1,4,0.25) + )), + MASTER_FARMER(intArrayOf(2234, 2235, NPCs.MARTIN_THE_MASTER_GARDENER_3299), 38, 90.0, 240.0, 43.0, 3, 3, 5, WeightBasedTable.create( + WeightedItem(Items.POTATO_SEED_5318,1,3,50.0), + WeightedItem(Items.ONION_SEED_5319,1,3,50.0), + WeightedItem(Items.CABBAGE_SEED_5324,1,3,50.0), + WeightedItem(Items.TOMATO_SEED_5322,1,2,50.0), + WeightedItem(Items.SWEETCORN_SEED_5320,1,2,50.0), + WeightedItem(Items.STRAWBERRY_SEED_5323,1,1,25.0), + WeightedItem(Items.WATERMELON_SEED_5321,1,1,8.0), + WeightedItem(Items.BARLEY_SEED_5305,1,4,50.0), + WeightedItem(Items.HAMMERSTONE_SEED_5307,1,3,50.0), + WeightedItem(Items.ASGARNIAN_SEED_5308,1,3,50.0), + WeightedItem(Items.JUTE_SEED_5306,1,3,50.0), + WeightedItem(Items.YANILLIAN_SEED_5309,1,2,25.0), + WeightedItem(Items.KRANDORIAN_SEED_5310,1,2,25.0), + WeightedItem(Items.WILDBLOOD_SEED_5311,1,1,8.0), + WeightedItem(Items.MARIGOLD_SEED_5096,1,1,50.0), + WeightedItem(Items.NASTURTIUM_SEED_5098,1,1,50.0), + WeightedItem(Items.ROSEMARY_SEED_5097,1,1,50.0), + WeightedItem(Items.WOAD_SEED_5099,1,1,50.0), + WeightedItem(Items.LIMPWURT_SEED_5100,1,1,25.0), + WeightedItem(Items.REDBERRY_SEED_5101,1,1,50.0), + WeightedItem(Items.CADAVABERRY_SEED_5102,1,1,50.0), + WeightedItem(Items.DWELLBERRY_SEED_5103,1,1,25.0), + WeightedItem(Items.JANGERBERRY_SEED_5104,1,1,25.0), + WeightedItem(Items.WHITEBERRY_SEED_5105,1,1,25.0), + WeightedItem(Items.GUAM_SEED_5291,1,1,50.0), + WeightedItem(Items.MARRENTILL_SEED_5292,1,1,50.0), + WeightedItem(Items.TARROMIN_SEED_5293,1,1,50.0), + WeightedItem(Items.HARRALANDER_SEED_5294,1,1,25.0), + WeightedItem(Items.RANARR_SEED_5295,1,1,8.0), + WeightedItem(Items.TOADFLAX_SEED_5296,1,1,8.0), + WeightedItem(Items.IRIT_SEED_5297,1,1,8.0), + WeightedItem(Items.AVANTOE_SEED_5298,1,1,8.0), + WeightedItem(Items.KWUARM_SEED_5299,1,1,8.0), + WeightedItem(Items.SNAPDRAGON_SEED_5300,1,1,5.0), + WeightedItem(Items.CADANTINE_SEED_5301,1,1,8.0), + WeightedItem(Items.LANTADYME_SEED_5302,1,1,5.0), + WeightedItem(Items.DWARF_WEED_SEED_5303,1,1,5.0), + WeightedItem(Items.TORSTOL_SEED_5304,1,1,5.0) + )), + GUARD(intArrayOf(9, 32, 206, 296, 297, 298, 299, 344, 345, 346, 368, 678, 812, 9, 32, 296, 297, 298, 299, 2699, 2700, 2701, 2702, 2703, 3228, 3229, 3230, 3231, 3232, 3233, 3241, 3407, 3408, 4307, 4308, 4309, 4310, 4311, 5919, 5920), 40, 50.0, 240.0, 46.5, 2,2,5, WeightBasedTable.create( + WeightedItem(Items.COINS_995,30,30,1.0,true) + )), + FREMENNIK_CITIZEN(intArrayOf(1305, 1306, 1308, 1309, 1310, 1311, 1312, 1313, 1314, 2462), 45, 65.0, 240.0, 65.0, 2, 2, 5, WeightBasedTable.create( + WeightedItem(Items.COINS_995,40,40,1.0,true) + )), + BEARDED_BANDIT(intArrayOf(1880, 1881, 6174), 45, 50.0, 240.0, 65.0, 5,5,5, WeightBasedTable.create( + WeightedItem(Items.ANTIPOISON4_2446,1,1,1.0), + WeightedItem(Items.LOCKPICK_1523,1,1,2.0), + WeightedItem(Items.COINS_995,1,1,4.0) + )), + DESERT_BANDIT(intArrayOf(1926, 1921), 53, 50.0, 240.0, 79.5, 3,3,5, WeightBasedTable.create( + WeightedItem(Items.COINS_995,50,1,3.0), + WeightedItem(Items.ANTIPOISON4_2446,1,1,1.0), + WeightedItem(Items.LOCKPICK_1523,1,1,1.0) + )), + KNIGHT_OF_ADROUGNE(intArrayOf(23, 26), 55, 50.0, 240.0, 84.3, 3,3,5, WeightBasedTable.create( + WeightedItem(Items.COINS_995,50,50,1.0,true) + )), + YANILLE_WATCHMAN(intArrayOf(34), 65, 50.0, 240.0, 137.5, 3,3,5, WeightBasedTable.create( + WeightedItem(Items.COINS_995,60,60,1.0,true), + WeightedItem(Items.BREAD_2309,1,1,1.0,true) + )), + MENAPHITE_THUG(intArrayOf(1905), 65, 50.0, 240.0, 137.5, 5,5,5, WeightBasedTable.create( + WeightedItem(Items.COINS_995,60,60,1.0,true) + )), + PALADIN(intArrayOf(20, 2256), 70, 50.0, 150.0,151.75, 3,3,5, WeightBasedTable.create( + WeightedItem(Items.COINS_995,80,80,1.0,true), + WeightedItem(Items.CHAOS_RUNE_562,2,2,1.0,true) + )), + GNOME(intArrayOf(66, 67, 68, 168, 169, 2249, 2250, 2251, 2371, 2649, 2650, 6002, 6004), 75, 8.0, 120.0, 198.5, 1,1,5, WeightBasedTable.create( + WeightedItem(Items.COINS_995,300,300,2.5), + WeightedItem(Items.EARTH_RUNE_557,1,1,3.5), + WeightedItem(Items.GOLD_ORE_445,1,1,1.0), + WeightedItem(Items.FIRE_ORB_569,1,1,5.0), + WeightedItem(Items.SWAMP_TOAD_2150,1,1,8.0), + WeightedItem(Items.KING_WORM_2162,1,1,9.0) + )), + HERO(intArrayOf(21), 80, 6.0, 100.0,273.3, 6,6,4, WeightBasedTable.create( + WeightedItem(Items.COINS_995,200,300,1.5), + WeightedItem(Items.DEATH_RUNE_560,2,2,1.0), + WeightedItem(Items.BLOOD_RUNE_565,1,1,0.5), + WeightedItem(Items.FIRE_ORB_569,1,1,2.5), + WeightedItem(Items.DIAMOND_1601,1,1,2.0), + WeightedItem(Items.GOLD_ORE_444,1,1,1.5), + WeightedItem(Items.JUG_OF_WINE_1993,1,1,3.0) + )); + + + companion object { + val idMap = HashMap(values().size * 5) + + init { + values().forEach { + it.ids.forEach { id -> idMap[id] = it } + } + } + + @JvmStatic + fun forID(id: Int): Pickpockets? { + return idMap[id] + } + } + + + fun getSuccessChance(player: Player): Double{ + return RandomFunction.getSkillSuccessChance(low,high,player.skills.getLevel(Skills.THIEVING)) + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/skill/thieving/Stall.java b/Server/src/main/content/global/skill/thieving/Stall.java new file mode 100644 index 0000000..59498da --- /dev/null +++ b/Server/src/main/content/global/skill/thieving/Stall.java @@ -0,0 +1,96 @@ +package content.global.skill.thieving; + +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.tools.RandomFunction; + +import java.util.*; + +import static org.rs09.consts.Items.CANDLE_36; +import static org.rs09.consts.Scenery.CANDLES_19127; + +/** + * Represents a thieving stall. + * @author Ceikry, Woahscam + */ +public enum Stall { + VEGETABLE_STALL(new Integer[]{4706, 4708}, new Integer[] { 634 }, 2, new Item[]{new Item(1957, 1), new Item(1965, 1), new Item(1942, 1), new Item(1982, 1), new Item(1550, 1)}, 10, 4,"vegetables"), + BAKER_STALL(new Integer[]{2561, 6163, 34384}, new Integer[] { 634, 6984, 34381 }, 5, new Item[]{new Item(1891, 1), new Item(2309, 1), new Item(1901, 1)}, 16, 4,"pastries"), + CRAFTING_STALL(new Integer[]{4874, 6166}, new Integer[] { 4797, 6984 }, 5, new Item[]{new Item(1592, 1), new Item(1597, 1), new Item(1755, 1)}, 16, 12,"crafting supplies"), + TEA_STALL(new Integer[]{635, 6574}, new Integer[] { 634, 6573 }, 5, new Item[]{new Item(712, 1)}, 16, 12,"tea"), + SILK_STALL(new Integer[]{34383, 2560}, new Integer[] { 34381, 634 }, 20, new Item[]{new Item(950, 1)}, 24, 13,"silk"), + WINE_STALL(new Integer[]{14011}, new Integer[] { 634 }, 22, new Item[]{new Item(1935, 1), new Item(1937, 1), new Item(1993, 1), new Item(7919, 1)}, 27, 27,"wine"), + MARKET_SEED_STALL(new Integer[]{7053}, new Integer[] { 634 }, 27, new Item[]{new Item(5096, 1), new Item(5097, 1), new Item(5101, 1), new Item(5318, 1), new Item(5319, 1), new Item(5324, 1)}, 10, 19,"seeds"), + FUR_STALL(new Integer[]{ 34387, 2563, 4278}, new Integer[] { 34381, 634, 634 }, 35, new Item[]{new Item(6814, 1), new Item(958, 1)}, 36, 25,"fur"), + FISH_STALL(new Integer[]{ 4277, 4705, 4707 }, new Integer[] { 634, 634, 634 }, 42, new Item[]{new Item(331, 1), new Item(359, 1), new Item(377, 1)}, 42, 27,"fish"), + CROSSBOW_STALL(new Integer[]{17031}, new Integer[] { 6984 }, 49, new Item[]{new Item(877, 3), new Item(9420, 1), new Item(9440, 1)}, 52, 19,"equipment"), + SILVER_STALL(new Integer[]{2565, 6164, 34382}, new Integer[] { 634, 6984, 34381}, 50, new Item[]{new Item(442, 1)}, 54, 50,"jewellery"), + SPICE_STALL(new Integer[]{34386, 6166}, new Integer[] { 34381, 6984 }, 65, new Item[]{new Item(2007, 1)}, 81, 134,"spices"), + GEM_STALL(new Integer[]{2562, 6162, 34385}, new Integer[] { 634, 6984, 34381 }, 75, new Item[]{new Item(1623, 1), new Item(1605, 1), new Item(1603, 1), new Item(1601, 1)}, 160, 300,"gems"), + //Ape Atoll Stalls + SCIMITAR_STALL(new Integer[]{4878}, new Integer[] { 4797 }, 65, new Item[]{new Item(1323, 1)}, 100, 134,"equipment"), + MAGIC_STALL(new Integer[]{4877}, new Integer[] { 4797 }, 65, new Item[]{new Item(556, 1), new Item(557, 1), new Item(554, 1), new Item(555, 1), new Item(563, 1)}, 100, 134,"equipment"), + GENERAL_STALL(new Integer[]{4876}, new Integer[] { 4797 }, 5, new Item[]{new Item(1931, 1), new Item(2347, 1), new Item(590, 1)}, 16, 12,"goods"), + FOOD_STALL(new Integer[]{4875}, new Integer[] { 4797 }, 5, new Item[]{new Item(1963, 1)}, 16, 12,"food"), + //CRAFTING_STALL (Ape Atoll) shares same drops/exp as regular crafting stall + CANDLES(new Integer[]{CANDLES_19127}, new Integer[]{CANDLES_19127}, 20, new Item[]{new Item(CANDLE_36, 1)}, 20, 0, "candles"); + //Quest Stalls Rocking Out + //CUSTOMS_EVIDENCE_FILES(new Integer[]{FIND OBJ ID}, FIND OBJ EMPTY ID, 63, new Item[]{new Item(1333, 1), new Item(1617, 1), new Item(1619, 1), new Item(1623, 1), new Item(385, 1), new Item(2359, 1), new Item(2357, 1), new Item(2351, 1), new Item(7114, 1), new Item(7134, 1), new Item(1025, 1), new Item(1281, 1), new Item(1325, 1), new Item(1323, 1), new Item(1321, 1), new Item(995, 300)}, 75, 100); + + public static HashMap idMap = new HashMap<>(); + static{ + Arrays.stream(Stall.values()).forEach(entry -> entry.full_ids.stream().forEach(id -> idMap.putIfAbsent(id, entry))); + } + + List full_ids; + List empty_ids; + int level, delay; + Item[] rewards; + double experience; + String msgItem; + + Stall(Integer[] full_ids, Integer[] empty_ids, int level, Item[] rewards, double experience, int delay, String msgItem) { + this.full_ids = new ArrayList(Arrays.asList(full_ids)); + this.empty_ids = new ArrayList(Arrays.asList(empty_ids)); + this.level = level; + this.delay = delay; + this.rewards = rewards; + this.experience = experience; + this.msgItem = msgItem; + } + + + + public List getFullIDs() { + return full_ids; + } + + public int getLevel() { + return level; + } + + public Item[] getRewards() { + return rewards; + } + + public double getExperience() { + return experience; + } + + public int getEmpty(int id) { + int fullIndex = full_ids.indexOf(id); + return this.empty_ids.get(fullIndex); + } + + public int getDelay() { + return delay; + } + + public Item getRandomLoot() { + return rewards[RandomFunction.random(rewards.length)]; + } + + public static Stall forObject(final Scenery object) { + return idMap.get(object.getId()); + } +} diff --git a/Server/src/main/content/global/skill/thieving/StallThiefPulse.java b/Server/src/main/content/global/skill/thieving/StallThiefPulse.java new file mode 100644 index 0000000..b081853 --- /dev/null +++ b/Server/src/main/content/global/skill/thieving/StallThiefPulse.java @@ -0,0 +1,170 @@ +package content.global.skill.thieving; + +import core.game.event.ResourceProducedEvent; +import core.game.node.entity.combat.ImpactHandler; +import core.game.node.entity.skill.SkillPulse; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.world.GameWorld; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import core.tools.RandomFunction; +import core.tools.StringUtils; + +import static core.api.ContentAPIKt.*; +import content.data.Quests; + +/** + * Represents the pulse used to thieve a stall. + * @author 'Vexia + */ +public final class StallThiefPulse extends SkillPulse { + + /** + * Represents the stealing animation. + */ + private static final Animation ANIMATION = new Animation(832); + + /** + * Represents the stall being thieved. + */ + private final Stall stall; + + /** + * Represents the ticks passed. + */ + private int ticks; + + /** + * Constructs a new {@code StallThiefPulse} {@code Object}. + * @param player the player. + * @param node the node. + * @param stall the stall. + */ + public StallThiefPulse(Player player, Scenery node, final Stall stall) { + super(player, node); + this.stall = stall; + } + + @Override + public void start() { + player.setAttribute("thieveDelay", GameWorld.getTicks()); + super.start(); + } + + @Override + public boolean checkRequirements() { + if (stall == null) { + return false; + } + if (player.inCombat()) { + player.getPacketDispatch().sendMessage("You cant steal from the market stall during combat!"); + return false; + } + if (player.getSkills().getLevel(Skills.THIEVING) < stall.getLevel()) { + player.getPacketDispatch().sendMessage("You need to be level " + stall.getLevel() + " to steal from the " + node.getName().toLowerCase() + "."); + return false; + } + if (player.getInventory().freeSlots() == 0) { + player.getPacketDispatch().sendMessage("You don't have enough inventory space."); + return false; + } + if (player.getLocation().isInRegion(10553) && !isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS) && stall.full_ids.contains(4278)) { + sendDialogue(player, "The fur trader is staring at you suspiciously. You cannot steal from his stall while he distrusts you."); + return false; + } + + if (player.getLocation().isInRegion(10553) && !isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS) && stall.full_ids.contains(4277)) { + sendDialogue(player, "The fishmonger is staring at you suspiciously. You cannot steal from his stall while he distrusts you."); + return false; + } + return true; + } + + @Override + public boolean hasInactiveNode() { + if (player.getAttribute("thieveDelay", 0) <= GameWorld.getTicks()) { + return false; + } + return super.hasInactiveNode(); + } + + @Override + public void animate() { + } + + @Override + public boolean reward() { + if (ticks == 0) { + player.animate(ANIMATION); + player.getLocks().lockInteractions(2); + } + if (++ticks % 3 != 0) { + return false; + } + final boolean success = success(); + if (success) { + if (stall == Stall.SILK_STALL) { + player.getSavedData().getGlobalData().setSilkSteal(System.currentTimeMillis() + 1800000); + } + if (node.isActive()) { + SceneryBuilder.replace(node, node.transform(stall.getEmpty(node.getId())), stall.getDelay()); + } + final Item item = stall.getRandomLoot(); + player.getInventory().add(item); + player.getSkills().addExperience(Skills.THIEVING, stall.getExperience(), true); + if (item.getId() == 1987) { + player.getPacketDispatch().sendMessage("You steal grapes from the grape stall."); + return true; + } + if(stall == Stall.CANDLES) { + return true; + } + player.getPacketDispatch().sendMessage("You steal " + (StringUtils.isPlusN(item.getName()) ? "an" : "a") + " " + item.getName().toLowerCase() + " from the " + stall.name().toLowerCase().replace('_',' ') + "."); + player.dispatch(new ResourceProducedEvent(item.getId(), item.getAmount(), node, 0)); + } + return true; + } + + @Override + public void message(int type) { + if(stall == Stall.CANDLES) { + return; + } + if (type == 0) { + player.getPacketDispatch().sendMessage("You attempt to steal some " + stall.msgItem + " from the " + stall.name().toLowerCase().replace('_', ' ')); + } + } + + /** + * Checks if the thief is successful. + * @return {@code True} if so. + */ + private boolean success() { + int mod = 0; + if (RandomFunction.random(15 + mod) < 4) { + if(stall == Stall.CANDLES) { + stun(player, 15, false); + impact(player, 1, ImpactHandler.HitsplatType.NORMAL); + // Location playerLoc = player.getLocation(); + // forceMove(player, playerLoc, new Location(playerLoc.getX() - 1, playerLoc.getY() - 1), + // 0, 4, Direction.SOUTH_WEST, 819, null); + player.sendMessage("A higher power smites you"); + return false; + } + for (NPC npc : RegionManager.getLocalNpcs(player.getLocation(), 8)) { + if (!npc.getProperties().getCombatPulse().isAttacking() && (npc.getId() == 32 || npc.getId() == 2236)) { + npc.sendChat("Hey! Get your hands off there!"); + npc.getProperties().getCombatPulse().attack(player); + return false; + } + } + } + return true; + } + +} diff --git a/Server/src/main/content/global/skill/thieving/ThievableChestPlugin.java b/Server/src/main/content/global/skill/thieving/ThievableChestPlugin.java new file mode 100644 index 0000000..f711dad --- /dev/null +++ b/Server/src/main/content/global/skill/thieving/ThievableChestPlugin.java @@ -0,0 +1,282 @@ +package content.global.skill.thieving; + +import core.cache.def.impl.SceneryDefinition; +import core.game.node.entity.skill.Skills; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.combat.ImpactHandler.HitsplatType; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; + +import static core.api.ContentAPIKt.*; + +/** + * Handles the thieving of chests. + * @author Vexia + */ +@Initializable +public final class ThievableChestPlugin extends OptionHandler { + /** + * The lock pick item. + */ + private static final Item LOCK_PICK = new Item(1523); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + + for (Chest chest : Chest.values()) { + for (int id : chest.getObjectIds()) { + SceneryDefinition def = SceneryDefinition.forId(id); + def.getHandlers().put("option:open", this); + def.getHandlers().put("option:search for traps", this); + } + } + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + final Chest chest = Chest.forId(node.getId()); + switch (option) { + case "open": + if (chest != null) { + chest.open(player, (Scenery) node); + return true; + } + return true; + case "search for traps": + chest.searchTraps(player, (Scenery) node); + return true; + } + return true; + } + + /** + * Represents a thievable chest. + * @author Vexia + */ + public static enum Chest { + TEN_COIN(2566, 13, 7.8, new Item[] { new Item(995, 10) }, 7), NATURE_RUNE(2567, 28, 25, new Item[] { new Item(995, 3), new Item(561, 1) }, 8), FIFTY_COIN(2568, 43, 125, new Item[] { new Item(995, 50) }, 55), STEEL_ARROWHEADS(2573, 47, 150, new Item[] { new Item(41, 5) }, 210), BLOOD_RUNES(2569, 59, 250, new Item[] { new Item(995, 500), new Item(565, 2) }, 135), PALADIN(2570, 72, 500, new Item[] { new Item(995, 1000), new Item(383, 1), new Item(449, 1), new Item(1623, 1) }, 120); + + /** + * The object id. + */ + private final int[] objectIds; + + /** + * The level required. + */ + private final int level; + + /** + * The experience gained. + */ + private final double experience; + + /** + * The rewards. + */ + private final Item[] rewards; + + /** + * The respawn time. + */ + private final int respawn; + + /** + * The current respawn time. + */ + private int currentRespawn; + + /** + * Constructs a new {@code Chest} {@code Object}. + * @param level the level. + * @param experience the experience. + * @param rewards the rewards. + * @param respawn the respawn time. + */ + private Chest(int[] objectIds, int level, double experience, Item[] rewards, int respawn) { + this.objectIds = objectIds; + this.level = level; + this.experience = experience; + this.rewards = rewards; + this.respawn = respawn; + } + + /** + * Constructs a new {@code Chest} {@code Object}. + * @param objectId the object id. + * @param level the level. + * @param experience the experience. + * @param rewards the rewards. + * @param respawn the respawn time. + */ + private Chest(int objectId, int level, double experience, Item[] rewards, int respawn) { + this(new int[] { objectId }, level, experience, rewards, respawn); + } + + /** + * Opens the chest for a reward. + * @param player the player. + * @param object the object. + */ + private void open(final Player player, final Scenery object) { + if (isRespawning()) { + player.sendMessage("It looks like this chest has already been looted."); + return; + } + player.lock(2); + player.sendMessage("You have activated a trap on the chest."); + player.getImpactHandler().manualHit(player, getHitAmount(player), HitsplatType.NORMAL); + } + + /** + * Searches for traps on a chest. + * @param player the player. + * @param object the object. + */ + private void searchTraps(final Player player, final Scenery object) { + player.faceLocation(object.getLocation()); + if (isRespawning()) { + player.sendMessage("It looks like this chest has already been looted."); + return; + } + if (player.getSkills().getLevel(Skills.THIEVING) < level) { + animate(player, 536, false); + lock(player, 2); + player.sendMessage("You search the chest for traps."); + player.sendMessage("You find nothing.", 1); + return; + } + if (player.getInventory().freeSlots() == 0) { + player.getPacketDispatch().sendMessage("Not enough inventory space."); + return; + } + lock(player, 6); + animate(player, 536, false); + player.sendMessage("You find a trap on the chest..."); + player.getImpactHandler().setDisabledTicks(6); + GameWorld.getPulser().submit(new Pulse(1, player) { + int counter; + + @Override + public boolean pulse() { + switch (++counter) { + case 2: + player.sendMessage("You disable the trap."); + break; + case 4: + player.animate(Animation.create(536)); + player.faceLocation(object.getLocation()); + player.sendMessage("You open the chest."); + break; + case 6: + for (Item i : rewards) { + player.getInventory().add(i, player); + } + player.sendMessage("You find treasure inside!"); + player.getSkills().addExperience(Skills.THIEVING, experience, true); + if (object.isActive()) { + SceneryBuilder.replace(object, object.transform(2574), 3); + } + setRespawn(); + return true; + } + return false; + } + }); + } + + /** + * Sets the respawn delay. + */ + public void setRespawn() { + currentRespawn = GameWorld.getTicks() + (int) (respawn / 0.6); + } + + /** + * Checks if the chest is respawning. + * @return {@code True} if so. + */ + public boolean isRespawning() { + return currentRespawn > GameWorld.getTicks(); + } + + /** + * Gets the amount of damage to deal. + * @param player The player. + * @return The amount of damage. + */ + protected static int getHitAmount(Player player) { + int hit = player.getSkills().getLifepoints() / 12; + if (hit < 2) { + hit = 2; + } + return hit; + } + + /** + * Gets a chest by the id. + * @param id the id. + * @return the chest. + */ + public static Chest forId(int id) { + for (Chest chest : values()) { + for (int i : chest.getObjectIds()) { + if (i == id) { + return chest; + } + } + } + return null; + } + + /** + * Gets the objectId. + * @return The objectId. + */ + public int[] getObjectIds() { + return objectIds; + } + + /** + * Gets the level. + * @return The level. + */ + public int getLevel() { + return level; + } + + /** + * Gets the experience. + * @return The experience. + */ + public double getExperience() { + return experience; + } + + /** + * Gets the rewards. + * @return The rewards. + */ + public Item[] getRewards() { + return rewards; + } + + /** + * Gets the respawn. + * @return The respawn. + */ + public int getRespawn() { + return respawn; + } + + } +} diff --git a/Server/src/main/content/global/skill/thieving/ThievingListeners.kt b/Server/src/main/content/global/skill/thieving/ThievingListeners.kt new file mode 100644 index 0000000..d6123fc --- /dev/null +++ b/Server/src/main/content/global/skill/thieving/ThievingListeners.kt @@ -0,0 +1,91 @@ +package content.global.skill.thieving + +import content.global.skill.skillcapeperks.SkillcapePerks +import core.api.* +import core.api.utils.WeightBasedTable +import core.game.node.entity.combat.ImpactHandler +import core.game.node.entity.impl.Animator +import core.game.node.entity.skill.Skills +import core.game.world.update.flag.context.Animation +import core.tools.RandomFunction +import org.rs09.consts.Items +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.game.node.entity.player.Player +import core.game.node.item.Item +import org.rs09.consts.Sounds + +class ThievingListeners : InteractionListener { + + companion object { + val PICKPOCKET_ANIM = Animation(881,Animator.Priority.HIGH) + val NPC_ANIM = Animation(422) + + /** Standalone pickpocketing function. For thieving other stuff outside of normal pickpocketing tables. */ + fun pickpocketRoll(player: Player, low: Double, high: Double, table: WeightBasedTable): ArrayList? { + // Able to pickpocket + var successMod = 0.0 + if(SkillcapePerks.isActive(SkillcapePerks.SMOOTH_HANDS, player)) { + successMod += 25 + } + if (player.equipment.contains(Items.GLOVES_OF_SILENCE_10075,1)){ + successMod += 3 + } + + val chance = RandomFunction.randomDouble(1.0, 100.0) + val failThreshold = RandomFunction.getSkillSuccessChance(low, high ,player.skills.getLevel(Skills.THIEVING)) + successMod + + if (chance > failThreshold) { + // Fail Pickpocket + return null // Returns a null, different from an empty table. + } else { + // Success Pickpocket + return table.roll() // You could also successfully pickpocket nothing when the table returns a blank array. + } + } + } + + override fun defineListeners() { + + on(IntType.NPC,"pickpocket","pick-pocket"){ player, node -> + val pickpocketData = Pickpockets.forID(node.id) ?: return@on false + + if(player.inCombat()){ + player.sendMessage("You can't pickpocket while in combat.") + return@on true + } + + if(player.skills.getLevel(Skills.THIEVING) < pickpocketData.requiredLevel){ + player.sendMessage("You need a Thieving level of ${pickpocketData.requiredLevel} to do that.") + return@on true + } + + if(!pickpocketData.table.canRoll(player)){ + player.sendMessage("You don't have enough inventory space to do that.") + return@on true + } + + player.animator.animate(PICKPOCKET_ANIM) + val lootTable = pickpocketRoll(player, pickpocketData.low, pickpocketData.high, pickpocketData.table) + if(lootTable == null){ + node.asNpc().face(player) + node.asNpc().animator.animate(NPC_ANIM) + + playHurtAudio(player, 20) + + stun(player, pickpocketData.stunTime) + + player.impactHandler.manualHit(node.asNpc(),RandomFunction.random(pickpocketData.stunDamageMin,pickpocketData.stunDamageMax),ImpactHandler.HitsplatType.NORMAL) + + node.asNpc().face(null) + } else { + playAudio(player, Sounds.PICK_2581) + player.lock(2) + lootTable.forEach { player.inventory.add(it) } + player.skills.addExperience(Skills.THIEVING,pickpocketData.experience) + } + + return@on true + } + } +} diff --git a/Server/src/main/content/global/skill/thieving/ThievingOptionPlugin.java b/Server/src/main/content/global/skill/thieving/ThievingOptionPlugin.java new file mode 100644 index 0000000..2d51037 --- /dev/null +++ b/Server/src/main/content/global/skill/thieving/ThievingOptionPlugin.java @@ -0,0 +1,40 @@ +package content.global.skill.thieving; + +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the plugin used to handle thieving options. + * @author 'Vexia + * @date 22/10/2013 + */ +@Initializable +public class ThievingOptionPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.setOptionHandler("steal-from", this); + SceneryDefinition.setOptionHandler("steal from", this); + SceneryDefinition.setOptionHandler("steal", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + switch (option) { + case "steal-from": + case "steal from": + case "steal": + player.getPulseManager().run(new StallThiefPulse(player, (Scenery) node, Stall.forObject((Scenery) node))); + player.getLocks().lockInteractions(6); + break; + } + return true; + } + +} diff --git a/Server/src/main/content/global/travel/EssenceTeleport.kt b/Server/src/main/content/global/travel/EssenceTeleport.kt new file mode 100644 index 0000000..cf79f80 --- /dev/null +++ b/Server/src/main/content/global/travel/EssenceTeleport.kt @@ -0,0 +1,222 @@ +package content.global.travel + +import content.global.skill.magic.TeleportMethod +import core.game.event.TeleportEvent +import core.api.* +import core.api.lock +import core.api.teleport +import core.api.unlock +import core.game.node.Node +import core.game.node.entity.impl.Projectile +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.TeleportManager +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import core.tools.RandomFunction +import core.game.world.GameWorld +import org.rs09.consts.Sounds + +/** + * Represents a utilitity class for rune essence teleporting. + * @author 'Vexia + */ +object EssenceTeleport { + /** + * Array of all the possible `Location` locations. + */ + val LOCATIONS = arrayOf( + Location.create(2911, 4832, 0), + Location.create(2913, 4837, 0), + Location.create(2930, 4850, 0), + Location.create(2894, 4811, 0), + Location.create(2896, 4845, 0), + Location.create(2922, 4820, 0), + Location.create(2931, 4813, 0) + ) + + /** + * Represents constants used for gfx/animation + */ + private const val CURSE_PROJECTILE = 109 + private val ANIMATION = Animation(437) + private val GLOWING_HANDS_GFX = Graphics(108) + private val TELEPORT_GFX = Graphics(110,150) + + + /** + * Method used to teleport a player. + * @param npc the npc. + * @param player the player. + */ + @JvmStatic + fun teleport(npc: NPC, player: Player) { + npc.animate(ANIMATION) + npc.faceTemporary(player, 1) + npc.graphics(GLOWING_HANDS_GFX) + lock(player,4) + playGlobalAudio(player.location, Sounds.CURSE_ALL_125, 0, 1) + Projectile.create(npc, player, CURSE_PROJECTILE).send() + npc.sendChat("Senventior Disthine Molenko!") + GameWorld.Pulser.submit(object : Pulse(1) { + var counter = 0 + override fun pulse(): Boolean { + when (counter++) { + 0 -> player.graphics(TELEPORT_GFX) + 1 -> { + if (getStage(player) == 2 && player.inventory.contains(5519, 1)) { + val item = player.inventory[player.inventory.getSlot(Item(5519))] + if (item != null) { + if (item.charge == 1000) { + player.savedData.globalData.resetAbyss() + } + val wizard = Wizard.forNPC(npc.id) + if (!player.savedData.globalData.hasAbyssCharge(wizard.ordinal)) { + player.savedData.globalData.setAbyssCharge(wizard.ordinal) + item.charge = item.charge + 1 + if (item.charge == 1003) { + player.sendMessage("Your scrying orb has absorbed enough teleport information.") + player.inventory.remove(Item(5519)) + player.inventory.add(Item(5518)) + } + } + } + } + player.savedData.globalData.essenceTeleporter = npc.id + player.graphics(TELEPORT_GFX) + + val loc = LOCATIONS[RandomFunction.random(0, LOCATIONS.size)] + teleport(player,loc) + + player.dispatch( + TeleportEvent( + TeleportManager.TeleportType.TELE_OTHER, + TeleportMethod.NPC, + npc, + loc + ) + ) + } + + 2 -> { + unlock(player) + return true + } + } + return false + } + }) + } + + /** + * Method used to teleport back to the home. + * @param player the prayer. + */ + @JvmStatic + fun home(player: Player, node: Node) { + val wizard = Wizard.forNPC(player.savedData.globalData.essenceTeleporter) + Projectile.create(node.location, player.location, CURSE_PROJECTILE, 15, 10, 0, 10, 0, 2).send() + GameWorld.Pulser.submit(object : Pulse(1) { + var counter = 0 + override fun pulse(): Boolean { + when (counter++) { + 0 -> { + lock(player,2) + player.graphics(TELEPORT_GFX) + } + 1 -> { + teleport(player,wizard.location) + player.graphics(TELEPORT_GFX) + unlock(player) + return true + } + } + return false + } + }) + } + + /** + * Gets the stage. + * @return the stage. + */ + fun getStage(player: Player): Int { + return getVarp(player, 492) + } + + /** + * Method used to get a random location. + * @return the location. + */ + val location: Location + get() { + val count = RandomFunction.random(LOCATIONS.size) + return LOCATIONS[count] + } + + /** + * Represents the wizard npc who can teleport. + * @author 'Vexia + */ + enum class Wizard + /** + * Constructs a new `WizardTowerPlugin` `Object`. + * @param npc the npc. + * @param location the location. + */( + /** + * Represents the npc of this wizard. + */ + val npc: Int, + /** + * The mask. + */ + val mask: Int, + /** + * Represents the returining location. + */ + val location: Location) { + AUBURY(553, 0x2, Location(3253, 3401, 0)), + SEDRIDOR(300, 0x4, Location(3107, 9573, 0)), + DISTENTOR(462, 0x8, Location(2591, 3085, 0)), + CROMPERTY(2328, 0x12, Location.create(2682, 3323, 0)); + + /** + * Gets the npc. + * @return The npc. + */ + + /** + * Gets the mask. + * @return The mask. + */ + + /** + * Gets the location. + * @return The location. + */ + + companion object { + /** + * Method used to get a wizard by the npc. + * @param npc the npc. + * @return the wizard. + */ + fun forNPC(npc: Int): Wizard { + for (wizard in values()) { + if (npc == 844) { + return CROMPERTY + } + if (wizard.npc == npc) { + return wizard + } + } + return AUBURY + } + } + + } +} diff --git a/Server/src/main/content/global/travel/canoe/CanoeListener.kt b/Server/src/main/content/global/travel/canoe/CanoeListener.kt new file mode 100644 index 0000000..57553ba --- /dev/null +++ b/Server/src/main/content/global/travel/canoe/CanoeListener.kt @@ -0,0 +1,372 @@ +package content.global.travel.canoe + +import content.data.skill.SkillingTool +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.interaction.InterfaceListener +import core.game.interaction.QueueStrength +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.scenery.SceneryBuilder +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.net.packet.PacketRepository +import core.net.packet.context.MinimapStateContext +import core.net.packet.out.MinimapState +import core.tools.RandomFunction +import org.rs09.consts.Components +import org.rs09.consts.Scenery +import org.rs09.consts.Sounds +import kotlin.math.abs + +/** + * Interaction and interface listener for canoe along river Lum. + * This handles Components.CANOE_52, Components.CANOE_STATIONS_MAP_53 and Components.CANOE_TRAVEL_758 globally. + */ +class CanoeListener : InteractionListener, InterfaceListener { + companion object { + const val CANOE_STATION_VARBIT_ATTRIBUTE = "canoeStationVarbit" // Index of Canoe Stations (0-4) + const val CANOE_SELECTED_ATTRIBUTE = "canoeSelected" // Index of Canoes (0-3) + + const val CANOE_SHAPING_INTERFACE = Components.CANOE_52 + const val CANOE_DESTINATION_INTERFACE = Components.CANOE_STATIONS_MAP_53 + const val CANOE_TRAVEL_INTERFACE = Components.CANOE_TRAVEL_758 + + val CANOE_SHAPING_SILHOUETTE = arrayOf(0, 9, 10, 8) + val CANOE_SHAPING_TEXT = arrayOf(0, 3, 2, 5) + val CANOE_SHAPING_BUTTONS = arrayOf(30, 31, 32, 33) + + val CANOE_DESTINATION_BUTTONS = arrayOf(47, 48, 3, 6, 49) + val CANOE_DESTINATION_HIDE_ROW = arrayOf(10, 11, 12, 20, 18) + val CANOE_DESTINATION_YOU_ARE_HERE = arrayOf(25, 24, 23, 19, 0) + + val CANOE_TREE_FALLING_ANIMATION = Animation(3304) + val CANOE_PLAYER_PUSHING_ANIMATION = Animation(3301) + val CANOE_PUSHING_ANIMATION = Animation(3304) + val CANOE_SINKING_ANIMATION = Animation(3305) + /** Canoe travel interface animations. A 2D array mapping [ origin ][ destination ]. Index 0-4 for Lumbridge to Wilderness. */ + val CANOE_TRAVEL_ANIMATIONS = arrayOf( + arrayOf(0, 9890, 9889, 9888, 9887), + arrayOf(9906, 0, 9893, 9892, 9891), + arrayOf(9904, 9905, 0, 9895, 9894), + arrayOf(9901, 9902, 9903, 0, 9896), + arrayOf(9897, 9898, 9899, 9900, 0), + ) + + @JvmStatic + fun getAxeAnimation(axe: SkillingTool): Animation { + return when (axe) { + SkillingTool.BRONZE_AXE -> Animation(6744) + SkillingTool.IRON_AXE -> Animation(6743) + SkillingTool.STEEL_AXE -> Animation(6742) + SkillingTool.BLACK_AXE -> Animation(6741) + SkillingTool.MITHRIL_AXE -> Animation(6740) + SkillingTool.ADAMANT_AXE -> Animation(6739) + SkillingTool.RUNE_AXE -> Animation(6738) + SkillingTool.DRAGON_AXE -> Animation(6745) + else -> axe.animation + } + } + + /** To scale woodcutting success. Follows WoodcuttingNode values at 15,30,45,60 (3 levels 'harder'). */ + private fun checkSuccess(player: Player, resource: Canoes, tool: SkillingTool): Boolean { + val skill = Skills.WOODCUTTING + val level: Int = getDynLevel(player, skill) + getFamiliarBoost(player, skill) + val hostRatio = RandomFunction.randomDouble(100.0) + val lowMod: Double = if (tool == SkillingTool.BLACK_AXE) resource.tierModLow / 2 else resource.tierModLow + val low: Double = resource.baseLow + tool.ordinal * lowMod + val highMod: Double = if (tool == SkillingTool.BLACK_AXE) resource.tierModHigh / 2 else resource.tierModHigh + val high: Double = resource.baseHigh + tool.ordinal * highMod + val clientRatio = RandomFunction.getSkillSuccessChance(low, high, level) + return hostRatio < clientRatio + } + + /** Maps canoe stations stages to related properties. */ + enum class CanoeStationSceneries(val sceneryId: Int, val varbitValue: Int) { + // Stage 1 - Tree is standing, option to chop-down. + TREE_STANDING(Scenery.CANOE_STATION_12144, 0), + + // Stage 2 - The tree is falling via an animation, denies player of options. + TREE_FALLING(Scenery.CANOE_STATION_12145, 9), + + // Stage 3 - Tree is on the cradle after the chop, option to shape the boat via an interface. + TREE_FALLEN(Scenery.CANOE_STATION_12146, 10), + + // Stage 4 - Tree gets shaped into 1 of 4 canoes, option to push it into the water. + TREE_SHAPED_LOG(Scenery.CANOE_STATION_12147, 1), + TREE_SHAPED_DUGOUT(Scenery.CANOE_STATION_12148, 2), + TREE_SHAPED_STABLE_DUGOUT(Scenery.CANOE_STATION_12149, 3), + TREE_SHAPED_WAKA(Scenery.CANOE_STATION_12150, 4), + + // Stage 5 - Canoe is being pushed into the water via an animation, option to travel is available. + CANOE_PUSHING_LOG(Scenery.CANOE_STATION_12151, 5), + CANOE_PUSHING_DUGOUT(Scenery.CANOE_STATION_12152, 6), + CANOE_PUSHING_STABLE_DUGOUT(Scenery.CANOE_STATION_12153, 7), + CANOE_PUSHING_WAKA(Scenery.CANOE_STATION_12154, 8), + + // Stage 6 - Canoe is in the water, option to travel via an interface. + CANOE_FLOATING_LOG(Scenery.CANOE_STATION_12155, 11), + CANOE_FLOATING_DUGOUT(Scenery.CANOE_STATION_12156, 12), + CANOE_FLOATING_STABLE_DUGOUT(Scenery.CANOE_STATION_12157, 13), + CANOE_FLOATING_WAKA(Scenery.CANOE_STATION_12158, 14), + + // Stage 7 - Canoe is animated to be sunk at the end of the ride. NO VARBITS, NOT PART OF THE CANOE_STATION SCENERY. + CANOE_SINKING_LOG(Scenery.A_SINKING_CANOE_12159, 0), + CANOE_SINKING_DUGOUT(Scenery.A_SINKING_CANOE_12160, 0), + CANOE_SINKING_STABLE_DUGOUT(Scenery.A_SINKING_CANOE_12161, 0), + CANOE_SINKING_WAKA(Scenery.A_SINKING_CANOE_12162, 0); + + companion object { + @JvmField + val stationIdMap = values().associateBy { it.sceneryId } + val stationIdArray = stationIdMap.values.map { it.sceneryId }.toIntArray() + } + } + + /** Enums to map canoes to related properties. */ + enum class Canoes(val level: Int, val experience: Double, val maxDistance: Int, val baseLow: Double, val baseHigh: Double, val tierModLow: Double, val tierModHigh: Double, val treeShaped: CanoeStationSceneries, val canoePushing: CanoeStationSceneries, val canoeFloating: CanoeStationSceneries, val canoeSinking: CanoeStationSceneries) { + LOG (12, 30.0, 1, 32.0, 100.0, 16.0, 50.0, CanoeStationSceneries.TREE_SHAPED_LOG, CanoeStationSceneries.CANOE_PUSHING_LOG, CanoeStationSceneries.CANOE_FLOATING_LOG, CanoeStationSceneries.CANOE_SINKING_LOG), + DUGOUT (27, 60.0, 2, 16.0, 50.0, 8.0, 25.0, CanoeStationSceneries.TREE_SHAPED_DUGOUT, CanoeStationSceneries.CANOE_PUSHING_DUGOUT, CanoeStationSceneries.CANOE_FLOATING_DUGOUT, CanoeStationSceneries.CANOE_SINKING_DUGOUT), + STABLE_DUGOUT (42, 90.0, 3, 8.0, 25.0, 4.0, 12.5, CanoeStationSceneries.TREE_SHAPED_STABLE_DUGOUT, CanoeStationSceneries.CANOE_PUSHING_STABLE_DUGOUT, CanoeStationSceneries.CANOE_FLOATING_STABLE_DUGOUT, CanoeStationSceneries.CANOE_SINKING_STABLE_DUGOUT), + WAKA (57, 150.0, 4, 4.0, 12.5, 2.0, 6.25, CanoeStationSceneries.TREE_SHAPED_WAKA, CanoeStationSceneries.CANOE_PUSHING_WAKA, CanoeStationSceneries.CANOE_FLOATING_WAKA, CanoeStationSceneries.CANOE_SINKING_WAKA); + + companion object { + @JvmField + val indexMap = Canoes.values().associateBy { it.ordinal } + } + } + + /** Enums to map canoe stations locations to related properties. */ + enum class CanoeStationLocations(val stationRegion: Int, val stationVarbit: Int, val playerChopLocation: Location, val playerFloatLocation: Location, val playerFacingLocation: Location, val canoeSinkLocation: Location, val playerDestination: Location, val locationName: String) { + LUMBRIDGE(12850, 1839, Location(3243, 3235), Location(3243, 3237), Location(-1, 0), Location(3239, 3242), Location(3240, 3242), "Lumbridge"), + CHAMPIONS(12852, 1840, Location(3204, 3343), Location(3202, 3343), Location(0, -1), Location(3199, 3344), Location(3199, 3344), "the Champion's Guild"), + BARBARIAN(12341, 1841, Location(3112, 3409), Location(3112, 3411), Location(-1, 0), Location(3109, 3411), Location(3109, 3415), "Barbarian Village"), + EDGEVILLE(12342, 1842, Location(3132, 3508), Location(3132, 3510), Location(-1, 0), Location(3132, 3510), Location(3132, 3510), "Edgeville"), + WILDERNESS(12603, 0, Location(0, 0), Location(0, 0), Location(0, 0), Location(3142, 3795), Location(3139, 3796), "the Wilderness Pond"); + + companion object { + private val stationRegionMap = CanoeStationLocations.values().associateBy { it.stationRegion } + + @JvmStatic + fun getCanoeStationbyLocation(location: Location): CanoeStationLocations { + return stationRegionMap[location.regionId]!! + } + } + } + } + + override fun defineDestinationOverrides() { + // Set player's standing location when chopping down the tree. + setDest(IntType.SCENERY, CanoeStationSceneries.stationIdArray, "chop-down") { _, node -> + return@setDest CanoeStationLocations.getCanoeStationbyLocation(node.location).playerChopLocation + } + // Set player's standing location when shaping and floating the canoe. + setDest(IntType.SCENERY, CanoeStationSceneries.stationIdArray, "shape-canoe", "float canoe", "float log", "float waka") { _, node -> + return@setDest CanoeStationLocations.getCanoeStationbyLocation(node.location).playerFloatLocation + } + } + + override fun defineListeners() { + // Stage 1 - 2: Tree is standing, option to chop-down. + on(CanoeStationSceneries.stationIdArray, IntType.SCENERY, "chop-down") { player, node -> + val canoeStation = CanoeStationLocations.getCanoeStationbyLocation(node.location) + val axe: SkillingTool? = SkillingTool.getHatchet(player) + val stationVarbit = node.asScenery().definition.configFile + if (axe == null) { + sendMessage(player, "You do not have an axe which you have the woodcutting level to use.") + return@on true + } + if (getStatLevel(player, Skills.WOODCUTTING) < 12) { + sendMessage(player, "You need a woodcutting level of at least 12 to chop down this tree.") + return@on true + } + lock(player, axe.animation.duration + CANOE_TREE_FALLING_ANIMATION.duration) + face(player, canoeStation.playerChopLocation.transform(canoeStation.playerFacingLocation)) + animate(player, axe.animation) + queueScript(player, axe.animation.duration, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + player.animator.stop() + setVarbit(player, stationVarbit, CanoeStationSceneries.TREE_FALLING.varbitValue) + animateScenery(player, node.asScenery(), CANOE_TREE_FALLING_ANIMATION.id) + return@queueScript delayScript(player, CANOE_TREE_FALLING_ANIMATION.duration) + } + 1 -> { + setVarbit(player, stationVarbit, CanoeStationSceneries.TREE_FALLEN.varbitValue) + unlock(player) + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + return@on true + } + + // Stage 3: Tree is on the cradle after the chop, option to shape-canoe via interface CANOE_52. + on(CanoeStationSceneries.stationIdArray, IntType.SCENERY, "shape-canoe") { player, node -> + val canoeStation = CanoeStationLocations.getCanoeStationbyLocation(node.location) + setAttribute(player, CANOE_STATION_VARBIT_ATTRIBUTE, canoeStation.stationVarbit) + face(player, canoeStation.playerFloatLocation.transform(canoeStation.playerFacingLocation)) + openInterface(player, CANOE_SHAPING_INTERFACE) + openOverlay(player, 333) // Black overlay + return@on true + } + + // Stage 4 - 5: Tree gets shaped into 1 of 4 canoes, option to float-canoe. + on(CanoeStationSceneries.stationIdArray, IntType.SCENERY, "float canoe", "float log", "float waka") { player, node -> + val canoeStation = CanoeStationLocations.getCanoeStationbyLocation(node.location) + val canoe = Canoes.indexMap[getAttribute(player, CANOE_SELECTED_ATTRIBUTE, 0)]!! + setVarbit(player, canoeStation.stationVarbit, canoe.canoePushing.varbitValue) + lock(player, CANOE_PLAYER_PUSHING_ANIMATION.duration) + playAudio(player, Sounds.CANOE_ROLL_2731) + face(player, canoeStation.playerFloatLocation.transform(canoeStation.playerFacingLocation)) + queueScript(player, 0, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + animate(player, CANOE_PLAYER_PUSHING_ANIMATION) + animateScenery(player, node.asScenery(), CANOE_PUSHING_ANIMATION.id) + return@queueScript delayScript(player, CANOE_PLAYER_PUSHING_ANIMATION.duration) + } + 1 -> { + setVarbit(player, canoeStation.stationVarbit, canoe.canoeFloating.varbitValue) + unlock(player) + player.animator.stop() + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + return@on true + } + + // Stage 6: Canoe is in the water, option to paddle via interface CANOE_STATIONS_MAP_53. + on(CanoeStationSceneries.stationIdArray, IntType.SCENERY, "paddle log", "paddle canoe") { player, _ -> + closeInterface(player) + openInterface(player, Components.CANOE_STATIONS_MAP_53) + openOverlay(player, 333) // Black overlay + return@on true + } + } + + var temp = 14 + override fun defineInterfaceListeners() { + + // Stage 3: Opening interface 52 + onOpen(CANOE_SHAPING_INTERFACE) { player, _ -> + Canoes.values().forEach { + if (getStatLevel(player, Skills.WOODCUTTING) >= it.level && it != Canoes.LOG) { + setComponentVisibility(player, CANOE_SHAPING_INTERFACE, CANOE_SHAPING_SILHOUETTE[it.ordinal], true) + setComponentVisibility(player, CANOE_SHAPING_INTERFACE, CANOE_SHAPING_TEXT[it.ordinal], false) + } + } + return@onOpen true + } + + // Stage 3: On button click interface 52 + on(CANOE_SHAPING_INTERFACE) { player, _, _, buttonID, _, _ -> + closeInterface(player) + val canoe = Canoes.indexMap[CANOE_SHAPING_BUTTONS.indexOf(buttonID)]!! + val stationVarbit = getAttribute(player, CANOE_STATION_VARBIT_ATTRIBUTE, 1839) + val axe: SkillingTool? = SkillingTool.getHatchet(player) + if (axe == null) { + sendMessage(player, "You do not have an axe which you have the woodcutting level to use.") + return@on true + } + + lock(player, 4) + animate(player, getAxeAnimation(axe)) + submitIndividualPulse(player, object : Pulse(3) { + override fun pulse(): Boolean { + if (checkSuccess(player, canoe, axe)) { + setAttribute(player, CANOE_SELECTED_ATTRIBUTE, CANOE_SHAPING_BUTTONS.indexOf(buttonID)) + setVarbit(player, stationVarbit, canoe.treeShaped.varbitValue) + rewardXP(player, Skills.WOODCUTTING, canoe.experience) + unlock(player) + return true + } + animate(player, getAxeAnimation(axe)) + return false + } + }) + return@on true + } + + onOpen(CANOE_DESTINATION_INTERFACE) { player, component -> + val canoe = Canoes.indexMap[getAttribute(player, CANOE_SELECTED_ATTRIBUTE, 0)]!! + val origin = CanoeStationLocations.getCanoeStationbyLocation(player.location) + for (i in CanoeStationLocations.values()) { + setComponentVisibility(player, component.id, CANOE_DESTINATION_HIDE_ROW[i.ordinal], true) + if (i == CanoeStationLocations.WILDERNESS) { + if (canoe == Canoes.WAKA) { + // setComponentVisibility(player, component.id, 22, false) // Some red text on Wildy text. + setComponentVisibility(player, component.id, CANOE_DESTINATION_HIDE_ROW[i.ordinal], false) + } + } else if (i.ordinal == origin.ordinal) { + setComponentVisibility(player, component.id, CANOE_DESTINATION_YOU_ARE_HERE[i.ordinal], false) + }else if (abs(i.ordinal - origin.ordinal) <= canoe.maxDistance) { + setComponentVisibility(player, component.id, CANOE_DESTINATION_HIDE_ROW[i.ordinal], false) + } + } + return@onOpen true + } + + on(CANOE_DESTINATION_INTERFACE) { player, _, _, buttonID, _, _ -> + val origin = CanoeStationLocations.getCanoeStationbyLocation(player.location) + var destination: CanoeStationLocations = CanoeStationLocations.LUMBRIDGE + when (buttonID) { + CANOE_DESTINATION_BUTTONS[0] -> destination = CanoeStationLocations.LUMBRIDGE + CANOE_DESTINATION_BUTTONS[1] -> destination = CanoeStationLocations.CHAMPIONS + CANOE_DESTINATION_BUTTONS[2] -> destination = CanoeStationLocations.BARBARIAN + CANOE_DESTINATION_BUTTONS[3] -> destination = CanoeStationLocations.EDGEVILLE + CANOE_DESTINATION_BUTTONS[4] -> destination = CanoeStationLocations.WILDERNESS + } + val arrivalMessage = destination.locationName + val interfaceAnimationId = CANOE_TRAVEL_ANIMATIONS[origin.ordinal][destination.ordinal] + + if (player.familiarManager.hasFamiliar()) { + sendMessage(player, "You can't take a follower on a canoe.") + return@on true + } + lock(player, Animation(interfaceAnimationId).duration + 1 + Animation(Components.FADE_FROM_BLACK_170).duration) + // Tried using queueScript here, but it doesn't work as interfaces and overlays can't open. Maybe its because this is within an interface listener. + submitIndividualPulse(player, object : Pulse() { + var counter = 0 + override fun pulse(): Boolean { + when (counter++) { + 0 -> { + openInterface(player, CANOE_TRAVEL_INTERFACE) + openOverlay(player, 333) // Only call openOverlay(player, 333) after openInterface + animateInterface(player, CANOE_TRAVEL_INTERFACE, 3, interfaceAnimationId) + PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 2)) + player.interfaceManager.removeTabs(0, 1, 2, 3, 4, 5, 6, 11, 12) + } + Animation(interfaceAnimationId).duration + 1 -> { + teleport(player, destination.playerDestination) + closeInterface(player) + closeOverlay(player) + openOverlay(player, Components.FADE_FROM_BLACK_170) + } + Animation(interfaceAnimationId).duration + 1 + Animation(Components.FADE_FROM_BLACK_170).duration -> { + unlock(player) + player.interfaceManager.restoreTabs() + PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 0)) + val sinkingScenery = SceneryBuilder.add(core.game.node.scenery.Scenery(Scenery.A_SINKING_CANOE_12159, destination.canoeSinkLocation, 1), 3) as core.game.node.scenery.Scenery + animateScenery(sinkingScenery, CANOE_SINKING_ANIMATION.id) + sendMessage(player, "You arrive at $arrivalMessage.") + sendMessage(player, "Your canoe sinks from the long journey.") + if (destination == CanoeStationLocations.WILDERNESS) { + sendMessage(player, "There are no trees nearby to make a new canoe. Guess you're walking.") + } + setVarbit(player, origin.stationVarbit, 0) + return true + } + } + return false + } + }) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/global/travel/glider/CaptainDalburDialogue.java b/Server/src/main/content/global/travel/glider/CaptainDalburDialogue.java new file mode 100644 index 0000000..67f0cba --- /dev/null +++ b/Server/src/main/content/global/travel/glider/CaptainDalburDialogue.java @@ -0,0 +1,83 @@ +package content.global.travel.glider; + +import content.data.Quests; +import core.game.component.Component; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +import static core.api.ContentAPIKt.isQuestComplete; +import static core.tools.DialogueConstKt.END_DIALOGUE; + +/** + * Represents the dialogue plugin used for the captain dalbur npc. + * @author 'Vexia + * @note complete with gnome city stuff. + * @version 1.0 + */ +@Initializable +public final class CaptainDalburDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code CaptainDalburDialogue} {@code Object}. + */ + public CaptainDalburDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code CaptainDalburDialogue.java} {@code Object}. + * @param player the player. + */ + public CaptainDalburDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new CaptainDalburDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "What do you want human?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "May you fly me somewhere on your glider?"); + stage = 1; + break; + case 1: + if(!isQuestComplete(player, Quests.THE_GRAND_TREE)){ + interpreter.sendDialogues(npc, FacialExpression.ANNOYED, "I only fly friends of the gnomes!"); + stage = END_DIALOGUE; + } + else { + npc("If you wish."); + stage++; + } + break; + case 2: + end(); + player.getInterfaceManager().open(new Component(138)); + Gliders.sendConfig(npc, player); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 3809, 3810, 3811, 3812, 3813 }; + } +} diff --git a/Server/src/main/content/global/travel/glider/GliderPlugin.java b/Server/src/main/content/global/travel/glider/GliderPlugin.java new file mode 100644 index 0000000..b3cbe63 --- /dev/null +++ b/Server/src/main/content/global/travel/glider/GliderPlugin.java @@ -0,0 +1,43 @@ +package content.global.travel.glider; + +import content.data.Quests; +import core.api.ContentAPIKt; +import core.cache.def.impl.NPCDefinition; +import core.game.component.Component; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; +import static core.api.ContentAPIKt.isQuestComplete; + +/** + * Represents the plugin used for gliders. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class GliderPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + NPCDefinition.forId(3809).getHandlers().put("option:glider", this); + NPCDefinition.forId(3810).getHandlers().put("option:glider", this); + NPCDefinition.forId(3811).getHandlers().put("option:glider", this); + NPCDefinition.forId(3812).getHandlers().put("option:glider", this); + NPCDefinition.forId(3813).getHandlers().put("option:glider", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + if(isQuestComplete(player, Quests.THE_GRAND_TREE)){ + player.getInterfaceManager().open(new Component(138)); + Gliders.sendConfig(node.asNpc(), player); + } else { + ContentAPIKt.sendMessage(player,"You must complete The Grand Tree Quest to access the gnome glider."); + } + return true; + } + +} diff --git a/Server/src/main/content/global/travel/glider/GliderPulse.java b/Server/src/main/content/global/travel/glider/GliderPulse.java new file mode 100644 index 0000000..06873a6 --- /dev/null +++ b/Server/src/main/content/global/travel/glider/GliderPulse.java @@ -0,0 +1,84 @@ +package content.global.travel.glider; + +import core.game.component.Component; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.system.task.Pulse; +import core.net.packet.PacketRepository; +import core.net.packet.context.CameraContext; +import core.net.packet.context.CameraContext.CameraType; +import core.net.packet.context.MinimapStateContext; +import core.net.packet.out.CameraViewPacket; +import core.net.packet.out.MinimapState; + +import static core.api.ContentAPIKt.*; + + +/** + * Represents the pulse used for a glider. + * + * @author 'Vexia + */ +public final class GliderPulse extends Pulse { + + /** + * Represents the player. + */ + private final Player player; + + /** + * Represents the glider. + */ + private final Gliders glider; + + /** + * Represents the count. + */ + private int count; + + /** + * Constructs a new {@code GliderPulse.java} {@Code Object} + * + * @param delay + */ + public GliderPulse(int delay, Player player, Gliders glider) { + super(delay, player); + this.player = player; + this.glider = glider; + player.lock(); + } + + @Override + public boolean pulse() { + final boolean crash = glider == Gliders.LEMANTO_ADRA; + if (count == 1) { + setVarp(player, 153, glider.getConfig()); + PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 2)); + } else if (count == 2 && crash) { + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.SHAKE, 4, 4, 1200, 4, 4)); + player.getPacketDispatch().sendMessage("The glider almost gets blown from its path as it withstands heavy winds."); + } + if (count == 3) { + player.getInterfaceManager().openOverlay(new Component(115)); + } else if (count == 4) { + player.unlock(); + player.getProperties().setTeleportLocation(glider.getLocation()); + } else if (count == 5) { + if (crash) { + player.getPacketDispatch().sendMessage("The glider becomes uncontrollable and crashes down..."); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.RESET, 0, 0, 0, 0, 0)); + } + player.getInterfaceManager().closeOverlay(); + player.getInterfaceManager().close(); + PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 0)); + setVarp(player, 153, 0); + // Use the gnome glider to travel to Karamja + if (!crash && glider == Gliders.GANDIUS) { + player.getAchievementDiaryManager().finishTask(player, DiaryType.KARAMJA, 1, 11); + } + return true; + } + count++; + return false; + } +} diff --git a/Server/src/main/content/global/travel/glider/Gliders.java b/Server/src/main/content/global/travel/glider/Gliders.java new file mode 100644 index 0000000..99f9f78 --- /dev/null +++ b/Server/src/main/content/global/travel/glider/Gliders.java @@ -0,0 +1,128 @@ +package content.global.travel.glider; + +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.world.map.Location; + +import static core.api.ContentAPIKt.setVarp; + +/** + * Represents an enum of glider locations. + * @author 'Vexia + */ +public enum Gliders { + TA_QUIR_PRIW(16, Location.create(2465, 3501, 3), 9, 3809), + SINDARPOS(17, Location.create(2848, 3497, 0), 1, 3810), + LEMANTO_ADRA(18, Location.create(3321, 3427, 0), 3, -1), + AR_HEWO(19, Location.create(3278, 3212, 0), 4, 3812), + LEMANTOLLY_UNDRI(20, Location.create(2544, 2970, 0), 10, 3813), + GANDIUS(15, Location.create(2972, 2969, 0), 8, 3811); + + /** + * The button of the location. + */ + private final int button; + + /** + * The location to fly to. + */ + private final Location location; + + /** + * The config value. + */ + private final int config; + + /** + * The npc. + */ + private final int npc; + + /** + * Constructs a new {@code Gliders.java} {@Code Object} + * @param button the button. + * @param location the location. + * @param config the config. + * @param npc the npc. + */ + Gliders(int button, Location location, int config, int npc) { + this.button = button; + this.location = location; + this.config = config; + this.npc = npc; + } + + /** + * Sends the config. + * @param asNpc the npc. + * @param player the player. + */ + public static void sendConfig(NPC asNpc, Player player) { + Gliders g = forNpc(asNpc.getId()); + if (g == null) { + return; + } + setVarp(player, 153, g.getConfig()); + } + + /** + * Gets the glider by the npc. + * @param npc the npc. + * @return the gliders. + */ + public static Gliders forNpc(int npc) { + for (Gliders g : values()) { + if (g.getNpc() == npc) { + return g; + } + } + return null; + } + + /** + * Gets the button. + * @return The button. + */ + public int getButton() { + return button; + } + + /** + * Gets the location. + * @return The location. + */ + public Location getLocation() { + return location; + } + + /** + * Gets the config. + * @return The config. + */ + public int getConfig() { + return config; + } + + /** + * Gets the flider value for the button id. + * @param id the id. + * @return the value. + */ + public static Gliders forId(int id) { + for (Gliders i : Gliders.values()) { + if (i.getButton() == id) { + return i; + } + } + return null; + } + + /** + * Gets the npc. + * @return the npc + */ + public int getNpc() { + return npc; + } + +} diff --git a/Server/src/main/content/global/travel/ship/SeamanDialoguePlugin.java b/Server/src/main/content/global/travel/ship/SeamanDialoguePlugin.java new file mode 100644 index 0000000..41b226d --- /dev/null +++ b/Server/src/main/content/global/travel/ship/SeamanDialoguePlugin.java @@ -0,0 +1,161 @@ +package content.global.travel.ship; + +import core.game.container.impl.EquipmentContainer; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.plugin.Initializable; +import org.rs09.consts.Items; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.item.Item; + +import static core.api.ContentAPIKt.*; +import content.data.Quests; + +/** + * Represents the dialogue used to handle the sailing from and to karamja. + * + * @author Vexia + */ +@Initializable +public class SeamanDialoguePlugin extends DialoguePlugin { + + /** + * Constructs a new {@code SeamanDialoguePlugin} {@code Object}. + */ + public SeamanDialoguePlugin() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code SeamanDialoguePlugin} {@code Object}. + * + * @param player the player. + */ + public SeamanDialoguePlugin(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new SeamanDialoguePlugin(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + if (args.length > 1 && player.getQuestRepository().isComplete(Quests.PIRATES_TREASURE)) { + if (player.getEquipment().get(EquipmentContainer.SLOT_RING) != null && player.getEquipment().get(EquipmentContainer.SLOT_RING).getId() == Items.RING_OF_CHAROSA_6465) { + travel(); + } else if (player.getAchievementDiaryManager().getDiary(DiaryType.KARAMJA).isComplete(0)) { + pay(15); + } else { + pay(30); + } + return true; + } else { + player.getPacketDispatch().sendMessage("You may only use the Pay-fare option after completing Pirate's Treasure."); + } + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Do you want to go on a trip to Karamja?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "The trip will cost you 30 coins."); + stage = 1; + break; + case 1: + boolean charos = false; + if (player.getEquipment().get(EquipmentContainer.SLOT_RING) != null) { + charos = player.getEquipment().get(EquipmentContainer.SLOT_RING).getId() == Items.RING_OF_CHAROSA_6465; + } + if (charos) { + interpreter.sendOptions("Select an Option", "Yes, please.", "No, thank you.", "(Charm) Or I could pay you nothing at all..."); + } else { + interpreter.sendOptions("Select an Option", "Yes, please.", "No, thank you."); + } + stage = 2; + break; + case 2: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Yes, please."); + if (player.getAchievementDiaryManager().getDiary(DiaryType.KARAMJA).isComplete(0)) { + stage = 9; + } else { + stage = 11; + } + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No, thank you."); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Or I could pay you nothing at all..."); + stage = 5; + break; + } + break; + case 5: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Mmmm ... Nothing at all you say ..."); + stage = 6; + break; + case 6: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Yes, why not - jump aboard then."); + if (!player.getAchievementDiaryManager().getDiary(DiaryType.FALADOR).isComplete(1,10)) { + player.getAchievementDiaryManager().getDiary(DiaryType.FALADOR).updateTask(player, 1,10, true); + } + stage = 30; + break; + case 9: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Wait a minute... Aren't those Karamja gloves?", "Thought I'd seen you helping around the island.", "You can go on half price - 15 coins."); + stage = 10; + break; + case 10: + pay(15); + break; + case 11: + pay(30); + break; + case 20: + end(); + break; + case 30: + travel(); + + } + return true; + } + + /** + * Method used to pay the fare. + */ + public void pay(int price) { + if (!player.getInventory().contains(995, price)) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Sorry, I don't have enough coins for that."); + stage = 20; + } else { + player.getInventory().remove(new Item(995, price)); + player.getPacketDispatch().sendMessage("You pay " + price + " coins and board the ship."); + travel(); + } + } + + public void travel() { + end(); + Ships.PORT_SARIM_TO_KARAMAJA.sail(player); + playJingle(player, 172); + } + + @Override + public int[] getIds() { + return new int[]{377, 378, 376}; + } +} diff --git a/Server/src/main/content/global/travel/ship/ShipCharter.java b/Server/src/main/content/global/travel/ship/ShipCharter.java new file mode 100644 index 0000000..9e04a88 --- /dev/null +++ b/Server/src/main/content/global/travel/ship/ShipCharter.java @@ -0,0 +1,404 @@ +package content.global.travel.ship; + +import core.game.component.Component; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.repository.Repository; +import core.net.packet.PacketRepository; +import core.net.packet.context.MinimapStateContext; +import core.net.packet.out.MinimapState; +import core.tools.StringUtils; + +import java.util.ArrayList; +import java.util.List; + +import static core.api.ContentAPIKt.*; +import content.data.Quests; + +/** + * Represents a class used to charter ships. + * @author 'Vexia + */ +public final class ShipCharter { + + /** + * Represents the component of charting a ship. + */ + private final static Component COMPONENT = new Component(95); + + /** + * Represents the ring of charos item. + */ + private final static Item RING_OF_CHAROS = new Item(6465); + + /** + * Constructs a new {@code ShipCharter} {@code Object}. + */ + public ShipCharter() { + /** + * empty. + */ + } + + /** + * Method used to open the ship chartering interface. + * @param player the player. + */ + public static void open(final Player player) { + final Destination current = Destination.getFromBase(player.getLocation()); + if (current != null) { + int[] hiddenComponents = getHiddenComponents(player, current); + for (int component : hiddenComponents) { + player.getPacketDispatch().sendInterfaceConfig(95, component, true); + } + player.getInterfaceManager().open(COMPONENT); + } + } + + /** + * Method used to handle a ship charter. + * @param player the player. + * @param button the button. + */ + public static void handle(final Player player, final int button) { + final Destination destination = Destination.forButton(button); + if (destination == null) { + return; + } + if (!destination.checkTravel(player)) { + return; + } + final int cost = getCost(player, destination); + player.getInterfaceManager().close(); + player.getDialogueInterpreter().open(4651, Repository.findNPC(4651), destination, cost); + } + + /** + * Method used to get the cost of the charter. + * @param player the player. + * @param destination the destination. + * @return the cost. + */ + public static int getCost(final Player player, Destination destination) { + int cost = destination.getCost(player, destination); + if (player.getQuestRepository().isComplete(Quests.CABIN_FEVER)) { + cost -= Math.round((cost / 2.)); + } + if (player.getEquipment().containsItem(RING_OF_CHAROS)) { + cost -= Math.round((cost / 2.)); + } + return cost; + } + + /** + * Method used to get the hidden childs on the screen. + * @param player the player. + * @return the hidden childs. + */ + public static int[] getHiddenComponents(final Player player, Destination base) { + final Destination[] restrictions = new Destination[] { /* Destination.MOS_LE_HARMLESS, */ + Destination.OO_GLOG, Destination.SHIPYARD, /* Destination.PORT_TYRAS, */ + Destination.CRANDOR + }; + List childs = new ArrayList<>(20); + for (Destination destination : restrictions) { + childs.add(destination.getXChild()); + childs.add(destination.getNameChild()); + } + childs.add(base.getXChild()); + childs.add(base.getNameChild()); + if (base == Destination.KARAMJA) { + childs.add(Destination.PORT_SARIM.getXChild()); + childs.add(Destination.PORT_SARIM.getNameChild()); + } + if (base == Destination.PORT_SARIM) { + childs.add(Destination.KARAMJA.getXChild()); + childs.add(Destination.KARAMJA.getNameChild()); + } + int[] arrayChilds = new int[childs.size()]; + for (int i = 0; i < arrayChilds.length; i++) { + arrayChilds[i] = childs.get(i); + } + return arrayChilds; + } + + /** + * Method used to get the component of ship chartering. + * @return the component.. + */ + public static Component getComponent() { + return COMPONENT; + } + + /** + * Represents the destination to travel to. + * @author 'Vexia + */ + public enum Destination { + CATHERBY(Location.create(2792, 3417, 1), 25, new int[] { 480, 0, 480, 625, 1600, 3250, 1000, 1600, 3200, 3400 }, Location.create(2797, 3414, 0), 3, 14), + PORT_PHASMATYS(Location.create(3705, 3503, 1), 24, new int[] { 3650, 3250, 1850, 0, 0, 0, 2050, 1850, 3200, 1100 }, Location.create(3702, 3502, 0), 2, 13) { + @Override + public boolean checkTravel(Player player) { + return requireQuest(player, Quests.PRIEST_IN_PERIL, "to go there."); + } + }, + CRANDOR(Location.create(2792, 3417, 1), 32, new int[] { 0, 480, 480, 925, 400, 3650, 1600, 400, 3200, 3800 }, null, 10, 21) { + @Override + public boolean checkTravel(Player player) { + return requireQuest(player, Quests.DRAGON_SLAYER, "to go there."); + } + }, + BRIMHAVEN(Location.create(2763, 3238, 1), 28, new int[] { 0, 480, 480, 925, 400, 3650, 1600, 400, 3200, 3800 }, Location.create(2760, 3238, 0), 6, 17){ + @Override + public int getCost(Player player, Destination destination) { + boolean hasGloves = DiaryType.KARAMJA.hasRewardEquipment(player); + if(destination == PORT_KHAZARD && hasGloves) return 15; + return super.getCost(player, destination); + } + }, + PORT_SARIM(Location.create(3038, 3189, 1), 30, new int[] { 1600, 1000, 0, 325, 1280, 650, 1280, 400, 3200, 1400 }, Location.create(3039, 3193, 0), 8, 19){ + @Override + public int getCost(Player player, Destination destination) { + boolean hasGloves = DiaryType.KARAMJA.hasRewardEquipment(player); + if(destination == KARAMJA && hasGloves) return 15; + return super.getCost(player, destination); + } + }, + PORT_TYRAS(Location.create(2142, 3122, 0), 23, new int[] { 3200, 3200, 3200, 1600, 3200, 3200, 3200, 3200, 0, 3200 }, Location.create(2143, 3122, 0), 1, 12) { + @Override + public boolean checkTravel(Player player) { + return hasRequirement(player, Quests.REGICIDE); + } + + }, + KARAMJA(Location.create(2957, 3158, 1), 27, new int[] { 200, 480, 0, 225, 400, 1850, 0, 200, 3200, 2000 }, Location.create(2954, 3156, 0), 5, 16) { + @Override + public int getCost(Player player, Destination destination) { + boolean hasGloves = DiaryType.KARAMJA.hasRewardEquipment(player); + if(destination == PORT_SARIM && hasGloves) return 15; + return super.getCost(player, destination); + } + }, + PORT_KHAZARD(Location.create(2674, 3141, 1), 29, new int[] { 1600, 1000, 0, 325, 180, 650, 1280, 400, 3200, 1400 }, Location.create(2674, 3144, 0), 7, 18){ + @Override + public int getCost(Player player, Destination destination) { + boolean hasGloves = DiaryType.KARAMJA.hasRewardEquipment(player); + if(destination == BRIMHAVEN && hasGloves) return 15; + return super.getCost(player, destination); + } + }, + SHIPYARD(Location.create(3001, 3032, 0), 26, new int[] { 400, 1600, 200, 225, 720, 1850, 400, 0, 3200, 900 }, Location.create(3001, 3032, 0), 4, 15) { + @Override + public boolean checkTravel(Player player) { + return requireQuest(player, Quests.THE_GRAND_TREE, "to go there."); + } + }, + OO_GLOG(Location.create(2623, 2857, 0), 33, new int[] { 300, 3400, 2000, 550, 5000, 2800, 1400, 900, 3200, 0}, Location.create(2622, 2857, 0), 11, 22), + MOS_LE_HARMLESS(Location.create(3671, 2931, 0), 31, new int[] { 725, 625, 1025, 0, 1025, 0, 325, 275, 1600, 500 }, Location.create(3671, 2933, 0), 9, 20) { + @Override + public boolean checkTravel(Player player) { + return hasRequirement(player, Quests.CABIN_FEVER); + } + }; + + /** + * Constructs a new {@code ShipCharter} {@code Object}. + * @param location the location. + * @param button the button. + * @param costs the money. + * @param base the base. + * @param components the children. + */ + Destination(Location location, int button, int[] costs, final Location base, int... components) { + this.location = location; + this.button = button; + this.costs = costs; + this.base = base; + this.childs = components; + } + + /** + * Represents the location of the destination. + */ + private final Location location; + + /** + * Represents the button of the destination. + */ + private final int button; + + /** + * Represents the costs from destination to destination. + */ + private final int[] costs; + + /** + * Represents the base location(how we find where we're at) + */ + private final Location base; + + /** + * Represents the childs on the screen. + */ + private final int[] childs; + + /** + * Gets the location. + * @return The location. + */ + public Location getLocation() { + return location; + } + + /** + * Gets the button. + * @return The button. + */ + public int getButton() { + return button; + } + + /** + * Gets the moneys. + * @return The moneys. + */ + public int[] getCosts() { + return costs; + } + + /** + * Gets the base. + * @return The base. + */ + public Location getBase() { + return base; + } + + /** + * Gets the childs. + * @return The childs. + */ + public int[] getComponents() { + return childs; + } + + /** + * Gets the x component. + * @return the component. + */ + public int getXChild() { + return childs[0]; + } + + /** + * Gets the name component. + * @return the component. + */ + public int getNameChild() { + return childs[1]; + } + + /** + * Gets the cost of chartering a ship. + * @param player the player. + * @return the cost. + */ + public int getCost(final Player player, final Destination destination) { + final Destination current = Destination.getFromBase(player.getLocation()); + if (current == null) { + return 0; + } + final Destination[] costTable = new Destination[] { BRIMHAVEN, CATHERBY, KARAMJA, MOS_LE_HARMLESS, PORT_KHAZARD, PORT_PHASMATYS, PORT_SARIM, SHIPYARD, PORT_TYRAS, OO_GLOG }; + int index = 0; + for (int i = 0; i < costTable.length; i++) { + if (costTable[i] == destination) { + index = i; + break; + } + } + return current.getCosts()[index]; + } + + /** + * Method used to get the destination from the base. + * @param location the location. + * @return the destination. + */ + public static Destination getFromBase(Location location) { + for (Destination destination : Destination.values()) { + if (destination.getBase() == null) { + continue; + } + if (destination.getBase().getDistance(location) < 30) { + return destination; + } + } + return null; + } + + /** + * Method used to get the destination for the button id. + * @param button the button. + * @return the destination. + */ + public static Destination forButton(final int button) { + for (Destination destination : values()) { + if (destination.getButton() == button) { + return destination; + } + } + return null; + } + + public boolean checkTravel(Player player) { + return true; + } + + /** + * Method used to sail the ship. + * @param player the player. + */ + public void sail(final Player player) { + player.lock(7); + playJingle(player, 171); + Location start = player.getLocation(); + GameWorld.getPulser().submit(new Pulse(1) { + int count = 0; + + @Override + public boolean pulse() { + switch (count++) { + case 0: + player.getInterfaceManager().openOverlay(new Component(115)); + break; + case 2: + PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 2)); + break; + case 3: + player.getProperties().setTeleportLocation(getLocation()); + break; + case 5: + player.unlock(); + player.getInterfaceManager().close(); + player.getInterfaceManager().closeOverlay(); + player.getInterfaceManager().restoreTabs(); + PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 0)); + player.getPacketDispatch().sendMessage("You pay the fare and sail to " + StringUtils.formatDisplayName(name()) + "."); + // Charter a ship from the shipyard in the far east of Karamja + if (start.withinDistance(Location.create(3001,3032,0))) { + player.getAchievementDiaryManager().finishTask(player, DiaryType.KARAMJA, 1, 17); + } + return true; + } + return false; + } + + }); + } + } + +} diff --git a/Server/src/main/content/global/travel/ship/ShipCharterInterface.java b/Server/src/main/content/global/travel/ship/ShipCharterInterface.java new file mode 100644 index 0000000..8dcdb81 --- /dev/null +++ b/Server/src/main/content/global/travel/ship/ShipCharterInterface.java @@ -0,0 +1,31 @@ +package content.global.travel.ship; + +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import content.global.travel.ship.ShipCharter; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the chip chartering interface plugin. + * @author 'Vexia + * @date 28/11/2013 + */ +@Initializable +public class ShipCharterInterface extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.put(95, this); + return this; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + ShipCharter.handle(player, button); + return true; + } + +} diff --git a/Server/src/main/content/global/travel/ship/ShipCharterNPCPlugin.java b/Server/src/main/content/global/travel/ship/ShipCharterNPCPlugin.java new file mode 100644 index 0000000..cf809e9 --- /dev/null +++ b/Server/src/main/content/global/travel/ship/ShipCharterNPCPlugin.java @@ -0,0 +1,38 @@ +package content.global.travel.ship; + +import core.cache.def.impl.NPCDefinition; +import content.global.travel.ship.ShipCharter; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the plugin used to handle the "charter" option. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class ShipCharterNPCPlugin extends OptionHandler { + + /** + * Represents the ship charter npcs. + */ + private static final int[] IDS = new int[] { 4650, 4651, 4652, 4653, 4654, 4655, 4656 }; + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (int id : IDS) { + NPCDefinition.forId(id).getHandlers().put("option:charter", this); + } + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + ShipCharter.open(player); + return true; + } + +} diff --git a/Server/src/main/content/global/travel/ship/ShipTravelPulse.java b/Server/src/main/content/global/travel/ship/ShipTravelPulse.java new file mode 100644 index 0000000..5f58087 --- /dev/null +++ b/Server/src/main/content/global/travel/ship/ShipTravelPulse.java @@ -0,0 +1,103 @@ +package content.global.travel.ship; + +import core.game.component.Component; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.system.task.Pulse; +import core.net.packet.PacketRepository; +import core.net.packet.context.MinimapStateContext; +import core.net.packet.out.MinimapState; + +import static core.api.ContentAPIKt.setVarp; + +/** + * Represents a pulse used to travel a player to a location. + * @author Vexia + */ +public final class ShipTravelPulse extends Pulse { + + /** + * Represents the player instance. + */ + private final Player player; + + /** + * Represents the ship we're using. + */ + private final Ships ship; + + /** + * Represents the current counter. + */ + private int counter = 0; + + /** + * Constructs a new {@code ShipTravelPulse.java} {@code Object}. + * @param player the Player. + */ + public ShipTravelPulse(Player player, Ships ship) { + super(1); + this.player = player; + this.ship = ship; + } + + @Override + public boolean pulse() { + switch (counter++) { + case 0: + prepare(); + break; + case 1: + if (ship != Ships.PORT_SARIM_TO_CRANDOR) { + player.getProperties().setTeleportLocation(ship.getLocation()); + } + break; + default: + if (counter == ship.getDelay()) { + arrive(); + return true; + } + break; + } + return false; + } + + /** + * Method used to arrive at a location. + */ + private void arrive() { + player.unlock(); + setVarp(player, 75, 0); + player.getInterfaceManager().close(); + PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 0)); + if (!ship.getName().equals("Crandor")) { + player.getDialogueInterpreter().sendDialogue("The ship arrives at " + ship.getName() + "."); + player.getInterfaceManager().close(); + } else { + player.getInterfaceManager().open(new Component(317)); + PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 2)); + player.getInterfaceManager().openOverlay(new Component(544)); + player.getInterfaceManager().open(new Component(317)); + } + + if (ship == Ships.KARAMJAMA_TO_PORT_SARIM) { + player.getAchievementDiaryManager().finishTask(player, DiaryType.KARAMJA, 0, 3); + } + if (ship == Ships.BRIMHAVEN_TO_ARDOUGNE) { + player.getAchievementDiaryManager().finishTask(player, DiaryType.KARAMJA, 0, 4); + } + if (ship == Ships.CAIRN_ISLAND_TO_PORT_KHAZARD) { + player.getAchievementDiaryManager().finishTask(player, DiaryType.KARAMJA, 1, 6); + } + } + + /** + * Method used to prepare the player. + */ + private void prepare() { + player.lock(ship.getDelay() + 1); + player.getInterfaceManager().open(new Component(299)); + PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 2)); + setVarp(player, 75, ship.getConfig()); + } +} diff --git a/Server/src/main/content/global/travel/ship/Ships.java b/Server/src/main/content/global/travel/ship/Ships.java new file mode 100644 index 0000000..c89adbb --- /dev/null +++ b/Server/src/main/content/global/travel/ship/Ships.java @@ -0,0 +1,109 @@ +package content.global.travel.ship; + +import core.game.node.entity.player.Player; +import core.game.world.map.Location; + +/** + * Represents a ship to travel on. + * @author 'Vexia + */ +public enum Ships { + PORT_SARIM_TO_ENTRANA(Location.create(2834, 3331, 1), 1, 15, "Entrana"), + ENTRANA_TO_PORT_SARIM(Location.create(3048, 3234, 0), 2, 15, "Port Sarim"), + PORT_SARIM_TO_CRANDOR(Location.create(2849, 3238, 0), 3, 12, "Crandor"), + CRANDOR_TO_PORT_SARIM(Location.create(2834, 3335, 0), 4, 13, "Port Sarim"), + PORT_SARIM_TO_KARAMAJA(Location.create(2956, 3143, 1), 5, 9, "Karamja"), + KARAMJAMA_TO_PORT_SARIM(Location.create(3029, 3217, 0), 6, 8, "Port Sarim"), + ARDOUGNE_TO_BRIMHAVEN(Location.create(2775, 3234, 1), 7, 4, "Brimhaven"), + BRIMHAVEN_TO_ARDOUGNE(Location.create(2683, 3268, 1), 8, 4, "Ardougne"), + CAIRN_ISLAND_TO_PORT_KHAZARD(Location.create(2676, 3170, 0), 10, 8, "Port Khazard"), + PORT_KHAZARD_TO_SHIP_YARD(Location.create(2998, 3043, 0), 11, 23, "the Ship Yard"), + SHIP_YARD_TO_PORT_KHAZARD(Location.create(2676, 3170, 0), 12, 23, "Port Khazard"), + CAIRN_ISLAND_TO_PORT_SARIM(Location.create(3048, 3234, 0), 13, 17, "Port Sarim"), + PORT_SARIM_TO_PEST_CONTROL(Location.create(2663, 2676, 1), 14, 12, "Pest Control"), + PEST_TO_PORT_SARIM(Location.create(3041, 3198, 1), 15, 12, "Port Sarim"), + FELDIP_TO_KARAMJA(Location.create(2763, 2956, 0), 16, 10, "Karamja"), + KARAMJA_TO_FELDIP(Location.create(2763, 2956, 0), 17, 10, "Feldip"); + + /** + * Constructs a new {@code Ships} {@code Object}. + * @param location the destination location. + * @param config the config value. + */ + Ships(Location location, int config, int delay, final String name) { + this.location = location; + this.config = config; + this.delay = delay; + this.name = name; + } + + /** + * Represents the destination location of the ship. + */ + private final Location location; + + /** + * The config value. + */ + private final int config; + + /** + * The delay of the ship. + */ + private final int delay; + + /** + * Represents the name of returning. + */ + private final String name; + + /** + * Method used to sail across the sea. + * @param player the player. + * @param ship the ship. + */ + public static void sail(final Player player, final Ships ship) { + player.getPulseManager().run(new ShipTravelPulse(player, ship)); + } + + /** + * Method used to sail. + * @param player the player. + */ + public void sail(final Player player) { + player.getPulseManager().run(new ShipTravelPulse(player, this)); + } + + /** + * Gets the location. + * @return The location. + */ + public Location getLocation() { + return location; + } + + /** + * Gets the config. + * @return The config. + */ + public int getConfig() { + return config; + } + + /** + * Gets the delay. + * @return The delay. + */ + public int getDelay() { + return delay; + } + + /** + * Gets the name. + * @return The name. + */ + public String getName() { + return name; + } + +} \ No newline at end of file diff --git a/Server/src/main/content/global/travel/ship/TraderCrewmemberDialogue.java b/Server/src/main/content/global/travel/ship/TraderCrewmemberDialogue.java new file mode 100644 index 0000000..405064a --- /dev/null +++ b/Server/src/main/content/global/travel/ship/TraderCrewmemberDialogue.java @@ -0,0 +1,182 @@ +package content.global.travel.ship; + +import content.global.travel.ship.ShipCharter.Destination; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.tools.StringUtils; + +/** + * Handles the TraderCrewmemberDialogue dialogue. + * @author 'Vexia + */ +@Initializable +public class TraderCrewmemberDialogue extends DialoguePlugin { + + /** + * Represents the ship charter destination. + */ + private Destination destination; + + /** + * Represents the cost of charting the ship. + */ + private int cost; + + /** + * Constructs a new {@code TraderCrewmemberDialogue} {@code Object}. + */ + public TraderCrewmemberDialogue() { + } + + /** + * Constructs a new {@code TraderCrewmemberDialogue} {@code Object}. + * @param player the player. + */ + public TraderCrewmemberDialogue(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[] { 4651, 4652, 4653, 4654, 4655, 4656, 4650 }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Choose an option:", "Yes, who are you?", "Yes, I would like to charter a ship."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.ASKING,"Yes, who are you?"); + stage = 100; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.FRIENDLY,"Yes, I would like to charter a ship."); + stage = 2000; + break; + } + break; + case 100: + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY,"I'm one of the Trader Stan's crew; we are all part of the", "largest fleet of trading and sailing vessels to ever sail the", "seven seas."); + stage = 101; + break; + case 101: + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY,"If you want to get to a port in a hurry then you can", "charter one of our ships to take you there - if the price", "is right..."); + stage = 102; + break; + case 102: + interpreter.sendDialogues(player, FacialExpression.HALF_ASKING,"So, where exactly can I go with your ships?"); + stage = 103; + break; + case 103: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL,"We run ships from Port Phasmatys over to Port Tyras,", "stopping at Port Sarim, Catherby, Karamja,", "the Shipyard and Port Khazard."); + stage = 104; + break; + case 104: + interpreter.sendDialogues(player, FacialExpression.FRIENDLY,"Wow, that's a lot of ports. I take it you have some exotic", "stuff to trade?"); + stage = 105; + break; + case 105: + interpreter.sendDialogues(npc, FacialExpression.HAPPY,"We certainly do! We have access to items", "bought and sold from around the world."); + stage = 106; + break; + case 106: + interpreter.sendDialogues(npc, FacialExpression.HALF_ASKING,"Would you like to take a look?"); + stage = 107; + break; + case 107: + options("Yes.", "No."); + stage = 108; + break; + case 108: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.FRIENDLY,"Yes."); + stage = 1000; + break; + case 2: + end(); + break; + + } + break; + case 1000: + end(); + npc.openShop(player); + break; + case 2000: + interpreter.sendDialogues(npc, FacialExpression.HAPPY,"Certainly sir, where would you like to go?"); + stage = 2001; + break; + case 2001: + end(); + ShipCharter.open(player); + break; + case 3000: + options("Ok", "Choose again", "No"); + stage = 30001; + break; + case 30001: + switch (buttonId) { + case 1: + end(); + if (cost == 0) { + destination.sail(player); + break; + } + if (!player.getInventory().containsItem(new Item(995, cost))) { + end(); + return true; + } + if (!player.getInventory().remove(new Item(995, cost))) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I don't have the money for that."); + stage = 30002; + return true; + } + destination.sail(player); + break; + case 2: + end(); + ShipCharter.open(player); + break; + case 3: + end(); + break; + } + break; + case 30002: + end(); + break; + } + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new TraderCrewmemberDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + if (args.length > 1) { + destination = ((Destination) args[1]); + cost = (int) args[2]; + interpreter.sendDialogue("To sail to " + StringUtils.formatDisplayName(destination.name()) + " from here will cost you " + cost + " gold.", "Are you sure you want to pay that?"); + stage = 3000; + return true; + } + npc("Can I help you?"); + stage = 0; + return true; + } +} diff --git a/Server/src/main/content/global/travel/trees/GnomeSpiritTreeListener.kt b/Server/src/main/content/global/travel/trees/GnomeSpiritTreeListener.kt new file mode 100644 index 0000000..838473c --- /dev/null +++ b/Server/src/main/content/global/travel/trees/GnomeSpiritTreeListener.kt @@ -0,0 +1,118 @@ +package content.global.travel.trees + +import core.api.isQuestComplete +import core.api.openDialogue +import core.api.sendDialogue +import core.api.teleport +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.diary.DiaryType +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import org.rs09.consts.NPCs +import core.game.dialogue.DialogueFile +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.game.world.GameWorld.Pulser +import core.tools.END_DIALOGUE +import content.data.Quests + +class GnomeSpiritTreeListener: InteractionListener { + val spiritTrees = intArrayOf(1317,1293,1294) + + override fun defineListeners() { + on(spiritTrees, IntType.SCENERY, "talk-to"){ player, _ -> + openDialogue(player, GnomeSpiritTreeDialogue(), NPC(NPCs.SPIRIT_TREE_3636)) + return@on true + } + on(spiritTrees, IntType.SCENERY, "teleport"){ player, _ -> + openDialogue(player, GnomeSpiritTreeTeleportDialogue(), NPC(NPCs.SPIRIT_TREE_3636)) + return@on true + } + } +} + +class GnomeSpiritTreeTeleportDialogue: DialogueFile() { + private val LOCATIONS = arrayOf( + Location(2542, 3170, 0), + Location(2461, 3444, 0), + Location(2556, 3259, 0), + Location(3184, 3508, 0) + ) + + private val ANIMATIONS = arrayOf(Animation(7082), Animation(7084)) + private val GRAPHICS = arrayOf(Graphics(1228), Graphics(1229)) + + fun hasQuestCompleted(player: Player): Boolean { + if (!isQuestComplete(player, Quests.TREE_GNOME_VILLAGE)) { + sendDialogue(player, "The tree doesn't feel like talking.") + stage = END_DIALOGUE + return false + } + return true + } + + private fun sendTeleport(player: Player, location: Location) { + end() + Pulser.submit(object : Pulse(1, player) { + var count = 0 + override fun pulse(): Boolean { + when (count) { + 0 -> { + player.animate(ANIMATIONS[0]) + player.graphics(GRAPHICS[0]) + } + 3 -> { teleport(player,location) } + 5 -> { + player.animate(ANIMATIONS[1]) + player.graphics(GRAPHICS[1]) + player.face(null) + if (player.location.withinDistance(Location.create(3184, 3508, 0))) { + player.achievementDiaryManager.finishTask(player, DiaryType.VARROCK, 1, 5) + } + return true + } + } + count++ + return false + } + }) + } + + override fun handle(componentID: Int, buttonID: Int) { + if(!GnomeSpiritTreeTeleportDialogue().hasQuestCompleted(player!!)) { + stage = END_DIALOGUE + return + } + when (stage) { + 0 -> interpreter!!.sendOptions( + "Where would you like to go?", + "Tree Gnome Village", + "Tree Gnome Stronghold", + "Battlefield of Khazard", + "Grand Exchange" + ).also { stage++ } + 1 -> when (buttonID) { + 1 -> sendTeleport(player!!, LOCATIONS[0]) + 2 -> sendTeleport(player!!, LOCATIONS[1]) + 3 -> sendTeleport(player!!, LOCATIONS[2]) + 4 -> sendTeleport(player!!, LOCATIONS[3]) + } + } + } +} + +class GnomeSpiritTreeDialogue: DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + if(!GnomeSpiritTreeTeleportDialogue().hasQuestCompleted(player!!)) { + stage = END_DIALOGUE + return + } + when (stage) { + 0 -> npcl("If you are a friend of the gnome people, you are a friend of mine, Do you wish to travel?").also{ stage++ } + 1 -> { openDialogue(player!!, GnomeSpiritTreeTeleportDialogue()) } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/allfiredup/AFUBeacon.kt b/Server/src/main/content/minigame/allfiredup/AFUBeacon.kt new file mode 100644 index 0000000..c97013a --- /dev/null +++ b/Server/src/main/content/minigame/allfiredup/AFUBeacon.kt @@ -0,0 +1,75 @@ +package content.minigame.allfiredup + +import core.api.* +import core.game.node.entity.player.Player +import core.tools.SystemLogger +import core.game.world.map.Location +import core.tools.Log + +/** + * Various data for beacons, such as varp and offset, required FM level, etc + * @author Ceikry + */ +enum class AFUBeacon(val title: String, val fmLevel: Int, val varbit: Int, val location: Location, val experience: Double, val keeper: Int = 0) { + RIVER_SALVE("",43,5146,Location.create(3396, 3464, 0),216.2,8065), + RAG_AND_BONE("",43,5147,Location.create(3343, 3510, 0),235.8,8066), + JOLLY_BOAR("",48,5148,Location.create(3278, 3525, 0), 193.8,8067), + NORTH_VARROCK_CASTLE("",53,5149,Location.create(3236, 3527, 0),178.5,8068), + GRAND_EXCHANGE("",59,5150,Location.create(3170, 3536, 0),194.3,8069), + EDGEVILLE("",62,5151,Location.create(3087, 3516, 0),86.7,8070), + MONASTERY("",68,5152,Location.create(3034, 3518, 0),224.4,8071), + GOBLIN_VILLAGE("",72,5153,Location.create(2968, 3516, 0),194.8,8072), + BURTHORPE("",76,5154,Location.create(2940, 3565, 0),195.3,8073), + DEATH_PLATEAU("",79,5155,Location.create(2944, 3622, 0),249.9,8074), + TROLLHEIM("",83,5156,Location.create(2939, 3680, 0),201.0,8075), + GWD("",87,5157,Location.create(2937, 3773, 0),255.0,8076), + TEMPLE("",89,5158,Location.create(2946, 3836, 0),198.9), + PLATEAU("",92,5159,Location.create(2964, 3931, 0),147.9); + + companion object { + fun forLocation(location: Location): AFUBeacon { + for (beacon in values()) { + if (beacon.location.equals(location)) return beacon + } + return AFUBeacon.RIVER_SALVE.also { log(this::class.java, Log.WARN, "Unhandled Beacon Location ${location.toString()}") } + } + + fun resetAllBeacons(player: Player){ + for(beacon in values()){ + setVarbit(player, beacon.varbit, 0) + } + } + } + + fun light(player: Player){ + setVarbit(player, varbit, 2) + } + + fun diminish(player: Player){ + setVarbit(player, varbit, 3) + } + + fun extinguish(player: Player){ + setVarbit(player, varbit, 0) + } + + fun lightGnomish(player: Player){ + setVarbit(player, varbit, 4) + } + + fun fillWithLogs(player: Player){ + setVarbit(player, varbit, 1, true) + } + + fun getState(player: Player): BeaconState { + return BeaconState.values()[getVarbit(player, varbit)] + } +} + +enum class BeaconState{ + EMPTY, + FILLED, + LIT, + DYING, + WARNING +} diff --git a/Server/src/main/content/minigame/allfiredup/AFUBeaconHandler.kt b/Server/src/main/content/minigame/allfiredup/AFUBeaconHandler.kt new file mode 100644 index 0000000..cd50cb9 --- /dev/null +++ b/Server/src/main/content/minigame/allfiredup/AFUBeaconHandler.kt @@ -0,0 +1,218 @@ +package content.minigame.allfiredup + +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.game.world.GameWorld +import content.data.Quests + +private val VALID_LOGS = intArrayOf(Items.LOGS_1511, Items.OAK_LOGS_1521,Items.WILLOW_LOGS_1519,Items.MAPLE_LOGS_1517,Items.YEW_LOGS_1515,Items.MAGIC_LOGS_1513) +private val FILL_ANIM = Animation(9136) +private val LIGHT_ANIM = Animation(7307) + +/** + * Handles interactions for beacons + * @author Ceikry + */ +class AFUBeaconListeners : InteractionListener { + + override fun defineListeners() { + on(IntType.SCENERY,"add-logs","light"){ player, node -> + val beacon = AFUBeacon.forLocation(node.location) + val questComplete = player.questRepository.isComplete(Quests.ALL_FIRED_UP) + val questStage = player.questRepository.getStage(Quests.ALL_FIRED_UP) + + if ((beacon != AFUBeacon.RIVER_SALVE && beacon != AFUBeacon.RAG_AND_BONE && !questComplete) + || (beacon == AFUBeacon.RIVER_SALVE && questStage < 20 && !questComplete) + || (beacon == AFUBeacon.RAG_AND_BONE && questStage < 50 && !questComplete)) { + player.dialogueInterpreter.sendDialogues(player, core.game.dialogue.FacialExpression.THINKING, "I probably shouldn't mess with this.") + return@on true + } + player.debug(beacon.getState(player).name) + + when (beacon.getState(player)) { + BeaconState.EMPTY -> fillBeacon(player, beacon, questComplete) + + BeaconState.DYING -> restoreBeacon(player, beacon, questComplete) + + BeaconState.FILLED -> lightBeacon(player, beacon, questComplete) + + BeaconState.LIT, BeaconState.WARNING -> { + player.debug("INVALID BEACON STATE") + } + } + return@on true + } + } + + fun fillBeacon(player: Player, beacon: AFUBeacon, questComplete: Boolean){ + + when(beacon){ + AFUBeacon.MONASTERY -> { + if(player.skills.getLevel(Skills.PRAYER) < 31){ + player.dialogueInterpreter.sendDialogues(NPC(beacon.keeper).getShownNPC(player), core.game.dialogue.FacialExpression.ANGRY,"You must join the monastery to light this beacon!") + return + } + } + + AFUBeacon.GWD -> { + if(!AFURepairClimbHandler.isRepaired(player, beacon)){ + player.dialogueInterpreter.sendDialogue("You must repair the windbreak before you","can light this beacon.") + return + } + } + + AFUBeacon.GOBLIN_VILLAGE -> { + if(!player.questRepository.isComplete(Quests.THE_LOST_TRIBE)){ + player.dialogueInterpreter.sendDialogues(NPC(beacon.keeper).getShownNPC(player), core.game.dialogue.FacialExpression.THINKING,"We no trust you outsider. You no light our beacon.","(Complete Lost Tribe to use this beacon.)") + return + } + } + + else -> {} + + } + + if(player.skills.getLevel(Skills.FIREMAKING) < beacon.fmLevel){ + player.dialogueInterpreter.sendDialogue("You need ${beacon.fmLevel} Firemaking to light this beacon.") + return + } + + val logs = getLogs(player,20) + if (logs.id != 0 && player.inventory.remove(logs)) { + player.lock() + + var session: AFUSession? = null + if(questComplete){ + session = player.getAttribute("afu-session", null) + if(session == null) { + session = AFUSession(player) + session.init() + } + } + + GameWorld.Pulser.submit(object : Pulse() { + var counter = 0 + override fun pulse(): Boolean { + when (counter++) { + 0 -> player.animator.animate(FILL_ANIM) + 1 -> { + beacon.fillWithLogs(player) + if(questComplete){ + session?.setLogs(beacon.ordinal,logs) + } + } + 2 -> player.unlock().also {player.animator.animate(Animation.RESET); return true } + } + return false + } + }) + } else { + player.dialogueInterpreter.sendDialogue("You need some logs to do this.") + } + } + + fun lightBeacon(player: Player, beacon: AFUBeacon, questComplete: Boolean){ + var session: AFUSession? = null + if(questComplete){ + session = player.getAttribute("afu-session",null) + if(session == null) return + } + + if(player.inventory.contains(Items.TINDERBOX_590,1)){ + player.lock() + GameWorld.Pulser.submit(object: Pulse(){ + var counter = 0 + override fun pulse(): Boolean { + when(counter++){ + 0 -> player.animator.animate(LIGHT_ANIM) + 1 -> { + beacon.light(player) + if(questComplete){ + session?.startTimer(beacon.ordinal) + if(session?.getLitBeacons() == 6 && !player.hasFireRing()){ + player.sendMessage("Congratulations on lighting 6 beacons at once! King Roald has something for you.") + player.setAttribute("/save:afu-mini:ring",true) + } + if(session?.getLitBeacons() == 10 && !player.hasFlameGloves()){ + player.sendMessage("Congratulations on lighting 10 beacons at once! King Roald has something for you.") + player.setAttribute("/save:afu-mini:gloves",true) + } + if(session?.getLitBeacons() == 14 && !player.hasInfernoAdze()){ + player.sendMessage("Congratulations on lighting all 14 beacons! King Roald has something special for you.") + player.setAttribute("/save:afu-mini:adze",true) + } + var experience = beacon.experience + experience += session?.getBonusExperience() ?: 0.0 + player.skills.addExperience(Skills.FIREMAKING,experience) + } else { + player.questRepository.getQuest(Quests.ALL_FIRED_UP).setStage(player, player.questRepository.getStage(Quests.ALL_FIRED_UP) + 10) + } + } + 2 -> player.unlock().also { return true } + } + return false + } + }) + } else { + player.dialogueInterpreter.sendDialogue("You need a tinderbox to light this.") + } + } + + fun restoreBeacon(player: Player, beacon: AFUBeacon, questComplete: Boolean){ + var session: AFUSession? = null + if(questComplete){ + session = player.getAttribute("afu-session",null) + if(session == null) return + } + + val logs = getLogs(player, 5) + if (logs.id != 0 && player.inventory.remove(logs)) { + player.lock() + GameWorld.Pulser.submit(object: Pulse(){ + var counter = 0 + override fun pulse(): Boolean { + when(counter++){ + 0 -> player.animator.animate(FILL_ANIM) + 1 -> beacon.light(player).also { + if(questComplete){ + session?.refreshTimer(beacon,logs.id) + } else { + player.questRepository.getQuest(Quests.ALL_FIRED_UP).setStage(player, 80) + } + } + 2 -> player.unlock().also { return true } + } + return false + } + }) + } else { + player.dialogueInterpreter.sendDialogue("You need some logs to do this.") + } + } + + fun getLogs(player: Player, amount: Int): Item{ + var logId = 0 + for (log in VALID_LOGS) if (player.inventory.getAmount(log) >= amount) {logId = log; break} + return Item(logId,amount) + } + + fun Player.hasFireRing(): Boolean{ + return inventory.containsItem(Item(Items.RING_OF_FIRE_13659)) || bank.containsItem(Item(Items.RING_OF_FIRE_13659)) || equipment.containsItem(Item(Items.RING_OF_FIRE_13659)) + } + + fun Player.hasFlameGloves(): Boolean{ + return inventory.containsItem(Item(Items.FLAME_GLOVES_13660)) || bank.containsItem(Item(Items.FLAME_GLOVES_13660)) || equipment.containsItem(Item(Items.FLAME_GLOVES_13660)) + } + + fun Player.hasInfernoAdze(): Boolean{ + return inventory.containsItem(Item(Items.INFERNO_ADZE_13661)) || bank.containsItem(Item(Items.INFERNO_ADZE_13661)) || equipment.containsItem(Item(Items.INFERNO_ADZE_13661)) + } + +} diff --git a/Server/src/main/content/minigame/allfiredup/AFURepairClimbHandler.kt b/Server/src/main/content/minigame/allfiredup/AFURepairClimbHandler.kt new file mode 100644 index 0000000..f95dfb1 --- /dev/null +++ b/Server/src/main/content/minigame/allfiredup/AFURepairClimbHandler.kt @@ -0,0 +1,185 @@ +package content.minigame.allfiredup + +import content.data.Quests +import core.game.node.entity.impl.ForceMovement +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import content.global.skill.construction.NailType +import core.game.node.item.Item +import core.game.world.map.Direction +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.api.* +import java.util.* + +/** + * Handles repairing and climbing of the 3 beacon shortcuts needed to access them + * @author Ceikry + */ +class AFURepairClimbHandler : InteractionListener { + + val repairIDs = intArrayOf(38480,38470,38494) + val climbIDs = intArrayOf(38469,38471,38486,38481) + + override fun defineListeners() { + + on(repairIDs, IntType.SCENERY, "repair"){ player, _ -> + if (hasRequirement(player, Quests.ALL_FIRED_UP)){ + val rco: RepairClimbObject? = getClimbingObject(player) + repair(player,rco!!) + return@on true + } + return@on false + } + + on(climbIDs, IntType.SCENERY, "climb"){ player, node -> + val rco: RepairClimbObject? = getClimbingObject(player) + climb(player,rco!!,node.location) + return@on true + } + + } + + private fun getClimbingObject(player: Player): RepairClimbObject?{ + for(ent in RepairClimbObject.values()) + if(ent.destinationDown?.withinDistance(player.location,2) == true || + ent.destinationUp?.withinDistance(player.location,2) == true){ + return ent + } + return null + } + + private fun repair(player: Player,rco: RepairClimbObject){ + if (rco == RepairClimbObject.TEMPLE){ + // You can do this 2 different ways + val hasSmithingLevel = getDynLevel(player, Skills.SMITHING) >= 70 + val hasConstructionLevel = getDynLevel(player, Skills.CONSTRUCTION) >= 59 + + if (!hasConstructionLevel && !hasSmithingLevel){ + sendDialogue(player, "You need level 70 smithing or 59 construction for this.") + return + } + + val hasHammer = inInventory(player, Items.HAMMER_2347) + val hasSmithingItems = hasHammer && inInventory(player, Items.IRON_BAR_2351, 2) + val hasConstructionItems = hasHammer && inInventory(player, Items.PLANK_960, 2) + + if (hasSmithingLevel && hasSmithingItems){ + if (removeItem(player,Item(Items.IRON_BAR_2351, 2))) { + setVarbit(player, rco.varbit, 1, true) + return + } + } + // Only check this if the smithing repair didn't work + if (hasConstructionLevel && hasConstructionItems){ + val nails = NailType.get(player, 4) + if (nails != null){ + if (removeItem(player, Item(Items.PLANK_960, 2)) && removeItem(player, Item(nails.itemId, 4))) { + setVarbit(player, rco.varbit, 1, true) + return + } + } + } + + var msg = "You need " + msg += if (hasSmithingLevel) "a hammer and 2 iron bars" else "" + msg += if (hasSmithingLevel && hasConstructionLevel) " or " else "" + msg += if (hasConstructionLevel) "a hammer, 2 planks and 4 nails for this." else " for this." + sendDialogue(player, msg) + return + } + val skill = rco.levelRequirement?.first ?: 0 + val level = rco.levelRequirement?.second ?: 0 + if(player.skills.getLevel(skill) < level){ + player.dialogueInterpreter.sendDialogue("You need level $level ${Skills.SKILL_NAME[skill]} for this.") + } + + var requiresNeedle = false + + val requiredItems = when(rco){ + RepairClimbObject.DEATH_PLATEAU -> { + arrayOf(Item(Items.PLANK_960,2)) + } + + RepairClimbObject.BURTHORPE -> { + arrayOf(Item(Items.IRON_BAR_2351,2)) + } + + RepairClimbObject.GWD -> { + requiresNeedle = true + arrayOf(Item(Items.JUTE_FIBRE_5931,3)) + } + else -> return + } + + if(requiresNeedle){ + if(player.inventory.containsItem(Item(Items.NEEDLE_1733)) && player.inventory.containItems(*requiredItems.map { it.id }.toIntArray())) { + player.inventory.remove(*requiredItems) + if (Random().nextBoolean()) player.inventory.remove(Item(Items.NEEDLE_1733)) + } else { + player.dialogueInterpreter.sendDialogue("You need a needle and ${requiredItems.map { "${it.amount} ${it.name.lowercase()}s" }.toString().replace("[","").replace("]","")} for this.") + return + } + } else { + if(player.inventory.containsItem(Item(Items.HAMMER_2347)) && player.inventory.containItems(*requiredItems.map { it.id }.toIntArray())) { + val nails = NailType.get(player,4) + if(nails == null && rco == RepairClimbObject.DEATH_PLATEAU){ + player.dialogueInterpreter.sendDialogue("You need 4 nails for this.") + return + } else if (rco == RepairClimbObject.DEATH_PLATEAU){ + player.inventory.remove(Item(nails.itemId,4)) + } + player.inventory.remove(*requiredItems) + } else { + player.dialogueInterpreter.sendDialogue("You need a hammer and ${requiredItems.map { "${it.amount} ${it.name.lowercase()}s" }.toString().replace("[","").replace("]","")} for this.") + return + } + } + setVarbit(player, rco.varbit, 1, true) + } + + private fun climb(player: Player, rco: RepairClimbObject, location: Location){ + ForceMovement.run(player,location,rco.getOtherLocation(player),rco.getAnimation(player),rco.getAnimation(player),rco.getDirection(player),20).endAnimation = Animation(-1) + } + + private enum class RepairClimbObject(val varbit: Int, val destinationUp: Location?, val destinationDown: Location?, val levelRequirement: Pair?){ + DEATH_PLATEAU(5161,Location.create(2949, 3623, 0),Location.create(2954, 3623, 0), Pair(Skills.CONSTRUCTION,42)), + BURTHORPE(5160,Location.create(2941, 3563, 0),Location.create(2934, 3563, 0),Pair(Skills.SMITHING,56)), + GWD(5163,null,null,Pair(Skills.CRAFTING,60)), + TEMPLE(5164,Location.create(2949, 3835, 0),Location.create(2956, 3835, 0),Pair(0,0)); // This needs to be handled specially so don't have levels here + + fun getOtherLocation(player: Player): Location?{ + if(player.location == destinationDown) return destinationUp + else return destinationDown + } + + fun getAnimation(player: Player): Animation { + if(getOtherLocation(player) == destinationDown) return Animation(1148) + else return Animation(740) + } + + fun getDirection(player: Player): Direction { + if(this == BURTHORPE){ + return Direction.EAST + } else return Direction.WEST + } + + fun isRepaired(player: Player): Boolean{ + return getVarbit(player, varbit) == 1 + } + } + + companion object { + fun isRepaired(player: Player, beacon: AFUBeacon): Boolean{ + if(beacon == AFUBeacon.DEATH_PLATEAU) return RepairClimbObject.DEATH_PLATEAU.isRepaired(player) + if(beacon == AFUBeacon.BURTHORPE) return RepairClimbObject.BURTHORPE.isRepaired(player) + if(beacon == AFUBeacon.GWD) return RepairClimbObject.GWD.isRepaired(player) + if(beacon == AFUBeacon.TEMPLE) return RepairClimbObject.TEMPLE.isRepaired(player) + else return true + } + } + +} diff --git a/Server/src/main/content/minigame/allfiredup/AFUSession.kt b/Server/src/main/content/minigame/allfiredup/AFUSession.kt new file mode 100644 index 0000000..1168a0f --- /dev/null +++ b/Server/src/main/content/minigame/allfiredup/AFUSession.kt @@ -0,0 +1,121 @@ +package content.minigame.allfiredup + +import core.api.LogoutListener +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.game.world.GameWorld +import org.rs09.consts.Items +import core.tools.colorize + +/** + * Handles keeping track of lit beacons and their burn time remaining + * @author Ceikry + */ +class AFUSession(val player: Player? = null) : LogoutListener { + private val beaconTimers = Array(14){i -> BeaconTimer(0, AFUBeacon.values()[i]) } + private val logInventories = Array(14){Item(0,0)} + private val beaconWatched = Array(14){false} + private var isActive = false + + fun init() { + isActive = true + GameWorld.Pulser.submit(object: Pulse(){ + override fun pulse(): Boolean { + player!!.setAttribute("afu-pulse",this) + beaconTimers.forEach {timer -> + timer.ticks-- + if(timer.ticks == 300) timer.beacon.diminish(player).also { + if(beaconWatched[timer.beacon.ordinal]){ + beaconWatched[timer.beacon.ordinal] = false + timer.ticks += (getTicks(logInventories[timer.beacon.ordinal].id) * 5) + timer.beacon.light(player) + player.sendMessage(colorize("%RThe ${timer.beacon.name.toLowerCase().replace("_"," ")} watcher has used your backup logs.")) + } else { + player.sendMessage(colorize("%RThe ${timer.beacon.name.toLowerCase().replace("_", " ")} beacon is dying!")) + } + } + if(timer.ticks == 0) timer.beacon.extinguish(player).also { player.sendMessage(colorize("%RThe ${timer.beacon.name.toLowerCase().replace("_"," ")} beacon has gone out!")) } + } + return !isActive + } + }) + player!!.setAttribute("afu-session",this) + } + + fun getLitBeacons(): Int{ + return beaconTimers.count { it.ticks > 0 } + } + + fun end(){ + isActive = false + } + + fun setLogs(beaconIndex: Int, logs: Item){ + logInventories[beaconIndex] = logs + } + + fun startTimer(beaconIndex: Int){ + val ticks = getTicks(logInventories[beaconIndex].id) * 20 + logInventories[beaconIndex] = Item(0,0) + beaconTimers[beaconIndex].ticks = ticks + } + + fun refreshTimer(beacon: AFUBeacon, logID: Int){ + val ticks = getTicks(logID) * 5 + beaconTimers.forEach { + if(it.beacon.ordinal == beacon.ordinal) it.ticks += ticks + } + } + + fun setWatcher(index: Int, logs: Item){ + beaconWatched[index] = true + logInventories[index] = logs + } + + fun isWatched(index: Int): Boolean{ + return beaconWatched[index] + } + + fun getTicks(logID: Int): Int{ + val ticks = when(logID){ + Items.LOGS_1511 -> 65 + Items.OAK_LOGS_1521 -> 68 + Items.WILLOW_LOGS_1519 -> 73 + Items.MAPLE_LOGS_1517 -> 79 + Items.YEW_LOGS_1515 -> 83 + Items.MAGIC_LOGS_1513 -> 90 + else -> 0 + } + return ticks + } + + fun getBonusExperience(): Double{ + return when(getLitBeacons()){ + 1 -> 608.4 + 2 -> 1622.4 + 3 -> 1987.4 + 4 -> 2149.6 + 5 -> 2149.6 + 6 -> 2514.6 + 7 -> 2555.2 + 8 -> 2758.0 + 9 -> 2839.1 + 10 -> 3041.9 + 11 -> 3123.0 + 12 -> 3244.7 + 13 -> 3366.4 + 14 -> 4867.4 + else -> 0.0 + } + } + + override fun logout(player: Player) { + AFUBeacon.resetAllBeacons(player) + val session: AFUSession? = player.getAttribute("afu-session",null) + session?.end() + player.removeAttribute("afu-session") + } + + internal class BeaconTimer(var ticks: Int, val beacon: AFUBeacon) +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/allfiredup/BeaconTenderDialogue.kt b/Server/src/main/content/minigame/allfiredup/BeaconTenderDialogue.kt new file mode 100644 index 0000000..f2b25db --- /dev/null +++ b/Server/src/main/content/minigame/allfiredup/BeaconTenderDialogue.kt @@ -0,0 +1,93 @@ +package content.minigame.allfiredup + +import core.ServerConstants +import core.game.dialogue.* +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.plugin.Initializable +import content.region.wilderness.dialogue.* +import org.rs09.consts.Items + +private val VALID_LOGS = arrayOf(Items.LOGS_1511, Items.OAK_LOGS_1521, Items.WILLOW_LOGS_1519, Items.MAPLE_LOGS_1517, Items.YEW_LOGS_1515, Items.MAGIC_LOGS_1513) + +@Initializable +//TODO: Add requirements for beacon keepers to watch beacons, most of the requirements were not possible to implement at the time of writing this. +class BeaconTenderDialogue(player: Player? = null) : DialoguePlugin(player) { + var index = 0 + + override fun newInstance(player: Player?): DialoguePlugin { + return BeaconTenderDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = (args[0] as NPC).getShownNPC(player) + index = getIndexOf((args[0] as NPC).originalId) + if(index == AFUBeacon.GWD.ordinal && player.skills.getLevel(Skills.SUMMONING) < 81){ + npc("Awwf uurrrhur","(You need 81 Summoning to communicate with Nanuq.)") + stage = 1000 + return true + } + if(index == AFUBeacon.MONASTERY.ordinal && player.skills.getLevel(Skills.PRAYER) < 53){ + npc("I will aid you when your devotion is","strong enough.","(You need 53 Prayer for him to assist you.)") + stage = 1000 + return true + } + npc("Hello, adventurer.") + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + val beacon = AFUBeacon.values()[index] + val logs = getLogs(player,5) + val session: AFUSession? = player.getAttribute("afu-session",null) + when(stage){ + 0 -> player("Hello!").also { stage++ } + 1 -> if(beacon.getState(player) == BeaconState.LIT && session?.isWatched(index) == false){ + options("Can you watch this beacon for me?","Nevermind.").also { stage = 10 } + } else { + npc("Carry on, adventurer.").also { stage = 1000 } + } + 10 -> when(buttonId){ + 1 -> player("Can you watch this beacon for me?").also { stage++ } + 2 -> player("Nevermind.").also { stage = 1000 } + } + 11 -> npc("Certainly, adventurer. Do you have logs for me?").also { stage++ } + 12 -> if(logs.id != 0){ + player("Yes, I do!").also { stage++ } + } else { + player("No, I don't.").also { stage = 1000 } + } + 13 -> npc("Great, hand them over.").also { stage++ } + 14 -> player("Here you go!").also { + player.inventory.remove(logs) + session?.setWatcher(index,logs) + stage = 1000 + } + + 1000 -> end() + } + return true + } + + fun getIndexOf(id: Int): Int{ + if(id == 8065) return 0 + if(id == 8066) return 1 + for(index in ids.indices){ + if(ids[index] == id) return index + 2 + } + return -1 + } + + fun getLogs(player: Player, amount: Int): Item { + var logId = 0 + for (log in VALID_LOGS) if (player.inventory.getAmount(log) >= amount) {logId = log; break} + return Item(logId,amount) + } + + override fun getIds(): IntArray { + return intArrayOf(8067,8068,8069,8070,8071,8072,8073,8074,8075,8076) + } + +} diff --git a/Server/src/main/content/minigame/allfiredup/KingRoaldAFUMiniDialogue.kt b/Server/src/main/content/minigame/allfiredup/KingRoaldAFUMiniDialogue.kt new file mode 100644 index 0000000..a7398de --- /dev/null +++ b/Server/src/main/content/minigame/allfiredup/KingRoaldAFUMiniDialogue.kt @@ -0,0 +1,47 @@ +package content.minigame.allfiredup + +import core.game.node.item.Item +import org.rs09.consts.Items +import core.game.dialogue.DialogueFile +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE + +class KingRoaldAFUMiniDialogue : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when(stage){ + START_DIALOGUE -> npc("Did what?").also { stage++ } + 1 -> { + if (player!!.getAttribute("afu-mini:adze", false)) { + player("I lit all 14 beacons at once!") + } else if (player!!.getAttribute("afu-mini:gloves", false)) { + player("I lit 10 beacons at once!") + } else if (player!!.getAttribute("afu-mini:ring", false)) { + player("I lit 6 beacons at once!") + } + stage++ + } + + 2 -> { + npc("Oh, wonderful! Here is your reward then.") + if (player!!.getAttribute( + "afu-mini:adze", + false + ) + ) if (player!!.inventory.add(Item(Items.INFERNO_ADZE_13661))) player!!.removeAttribute("afu-mini:adze") + if (player!!.getAttribute( + "afu-mini:gloves", + false + ) + ) if (player!!.inventory.add(Item(Items.FLAME_GLOVES_13660))) player!!.removeAttribute("afu-mini:gloves") + if (player!!.getAttribute( + "afu-mini:ring", + false + ) + ) if (player!!.inventory.add(Item(Items.RING_OF_FIRE_13659))) player!!.removeAttribute("afu-mini:ring") + stage = END_DIALOGUE + } + + END_DIALOGUE -> end() + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/barbassault/CaptainCainDialogue.kt b/Server/src/main/content/minigame/barbassault/CaptainCainDialogue.kt new file mode 100644 index 0000000..baeb381 --- /dev/null +++ b/Server/src/main/content/minigame/barbassault/CaptainCainDialogue.kt @@ -0,0 +1,74 @@ +package content.minigame.barbassault + +import core.api.Container +import core.api.addItem +import core.api.inInventory +import core.api.removeItem +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import java.text.SimpleDateFormat +import java.time.temporal.ChronoUnit +import java.util.* + +@Initializable +class CaptainCainDialogue(player: Player? = null) : DialoguePlugin(player) { + companion object { + const val TORSO_PRICE = 4_500_000 + } + + val sdf = SimpleDateFormat("ddMMyyyy") + override fun newInstance(player: Player?): DialoguePlugin { + return CaptainCainDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npcl(FacialExpression.FRIENDLY, "Hello, there, adventurer. Say, you wouldn't happen to be interested in purchasing a Fighter Torso would you?") + stage = 0 + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + val start = sdf.parse("27112020").toInstant() + val now = Date().toInstant() + val days = ChronoUnit.DAYS.between(start,now) + when(stage){ + 0 -> npcl(FacialExpression.ANNOYED,"I'm having to offer this service because it's been $days days since Ryan promised to give us barbarian assault.").also { stage++ } + 1 -> options("Yes, please.","No, thanks.").also { stage++ } + 2 -> when(buttonId){ + 1 -> playerl(FacialExpression.FRIENDLY, "Yes, please.").also { stage = 10 } + 2 -> playerl(FacialExpression.HALF_THINKING, "No, thanks.").also { stage = END_DIALOGUE } + } + + 10 -> npcl(FacialExpression.FRIENDLY, "Alright, then, that'll be %,d gold please.".format(TORSO_PRICE)).also { stage++ } + 11 -> options("Here you go!","Nevermind.").also { stage++ } + 12 -> when(buttonId){ + 1 -> if(inInventory(player, 995, TORSO_PRICE)) + playerl(FacialExpression.FRIENDLY, "Here you go!").also { stage = 20 } + else + playerl(FacialExpression.HALF_GUILTY, "Actually, I don't have that much.").also { stage = END_DIALOGUE } + + 2 -> playerl(FacialExpression.FRIENDLY, "On second thought, never mind.").also { stage = END_DIALOGUE } + } + + 20 -> { + npcl(FacialExpression.FRIENDLY, "Thank you much, kind sir. And here's your torso.") + if(removeItem(player, Item(995, TORSO_PRICE), Container.INVENTORY)) { + addItem(player, Items.FIGHTER_TORSO_10551, 1) + } + stage = END_DIALOGUE + } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.CAPTAIN_CAIN_5030) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/barrows/BarrowBrother.java b/Server/src/main/content/minigame/barrows/BarrowBrother.java new file mode 100644 index 0000000..43caf98 --- /dev/null +++ b/Server/src/main/content/minigame/barrows/BarrowBrother.java @@ -0,0 +1,126 @@ +package content.minigame.barrows; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.DeathTask; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.HintIconManager; +import core.game.world.map.Location; +import core.tools.RandomFunction; + +/** + * Handles a barrow brother NPC. + * @author Emperor + */ +public final class BarrowBrother extends NPC { + + /** + * The player to target. + */ + private final Player player; + + /** + * Constructs a new {@code BarrowBrother} {@code Object}. + * @param player The target. + * @param id The NPC id. + * @param location The location. + */ + public BarrowBrother(Player player, int id, Location location) { + super(id, location); + this.player = player; + } + + @Override + public void init() { + super.init(); + super.setRespawn(false); + if (location.getZ() == 3) { + sendChat("You dare disturb my rest!"); + } else { + sendChat("You dare steal from us!"); + } + getProperties().getCombatPulse().attack(player); + HintIconManager.registerHintIcon(player, this); + } + + @Override + public void handleTickActions() { + if (DeathTask.isDead(player)) { + return; + } + if (!player.isActive() || !player.getLocation().withinDistance(location)) { + clear(); + return; + } + if (!getProperties().getCombatPulse().isAttacking()) { + getProperties().getCombatPulse().attack(player); + } + } + + @Override + public void sendImpact(BattleState state) { + int maxHit = 0; + switch (getId()) { + case 2025:// ahrim + maxHit = 25; + break; + case 2026:// dharok + maxHit = 60; + break; + case 2027:// guthan + maxHit = 24; + break; + case 2028:// karil + maxHit = 20; + break; + case 2029:// torag + maxHit = 23; + break; + case 2030:// verac + maxHit = 25; + break; + } + if (state.getEstimatedHit() > maxHit) { + state.setEstimatedHit(RandomFunction.random(maxHit - 10, maxHit)); + } + if (state.getSecondaryHit() > maxHit) { + state.setSecondaryHit(RandomFunction.random(maxHit - 10, maxHit)); + } + } + + @Override + public void finalizeDeath(Entity killer) { + super.finalizeDeath(killer); + if (killer == player) { + player.getSavedData().getActivityData().getBarrowBrothers()[getBrotherIndex()] = true; + BarrowsActivityPlugin.sendConfiguration(player); + } + } + + @Override + public void clear() { + super.clear(); + if (player.isActive()) { + player.getHintIconManager().clear(); + } + player.removeAttribute("barrow:npc"); + player.removeAttribute("brother:" + getBrotherIndex()); + } + + /** + * Gets the barrow brother index. + * @return The index. + */ + private int getBrotherIndex() { + return getId() - 2025; + } + + /** + * Gets the player. + * @return The player. + */ + public Player getPlayer() { + return player; + } +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/barrows/BarrowsActivityPlugin.java b/Server/src/main/content/minigame/barrows/BarrowsActivityPlugin.java new file mode 100644 index 0000000..fa8df17 --- /dev/null +++ b/Server/src/main/content/minigame/barrows/BarrowsActivityPlugin.java @@ -0,0 +1,383 @@ +package content.minigame.barrows; + +import core.game.component.Component; +import core.game.activity.ActivityPlugin; +import core.game.global.action.ClimbActionHandler; +import core.game.global.action.DoorActionHandler; +import core.game.interaction.Option; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.DeathTask; +import core.game.node.entity.combat.ImpactHandler.HitsplatType; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.npc.agg.AggressiveBehavior; +import core.game.node.entity.npc.agg.AggressiveHandler; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.ActivityData; +import content.global.skill.summoning.familiar.Familiar; +import core.game.node.scenery.Scenery; +import core.game.system.task.Pulse; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.update.flag.context.Graphics; +import core.net.packet.PacketRepository; +import core.net.packet.context.CameraContext; +import core.net.packet.context.CameraContext.CameraType; +import core.net.packet.context.MinimapStateContext; +import core.net.packet.out.CameraViewPacket; +import core.net.packet.out.MinimapState; +import core.plugin.Initializable; +import core.tools.RandomFunction; +import core.game.world.GameWorld; +import core.plugin.ClassScanner; + +import java.util.stream.IntStream; + +import static core.api.ContentAPIKt.*; + +/** + * Handles the barrows activity plugin. + * @author Emperor + */ +@Initializable +public final class BarrowsActivityPlugin extends ActivityPlugin { + + /** + * The tunnel configuration values. + */ + private static final int[] TUNNEL_CONFIGS = { 55328769, 2867201, 44582944, 817160, 537688072, 40763408, 44320784, 23478274 }; + + /** + * Represents the tunnels between 2 rooms in the barrows tunnels. + */ + public static final ZoneBorders[] MINI_TUNNELS = { + new ZoneBorders(3532, 9665, 3570, 9671), + new ZoneBorders(3575, 9676, 3570, 9671), + new ZoneBorders(3575, 9676, 3581, 9714), + new ZoneBorders(3534, 9718, 3570, 9723), + new ZoneBorders(3523, 9675, 3528, 9712), + new ZoneBorders(3541, 9711, 3545, 9712), + new ZoneBorders(3558, 9711, 3562, 9712), + new ZoneBorders(3568, 9701, 3569, 9705), + new ZoneBorders(3551, 9701, 3552, 9705), + new ZoneBorders(3534, 9701, 3535, 9705), + new ZoneBorders(3541, 9694, 3545, 9695), + new ZoneBorders(3558, 9694, 3562, 9695), + new ZoneBorders(3568, 9684, 3569, 9688), + new ZoneBorders(3551, 9684, 3552, 9688), + new ZoneBorders(3534, 9684, 3535, 9688), + new ZoneBorders(3541, 9677, 3545, 9678), + new ZoneBorders(3558, 9677, 3562, 9678), + }; + + /** + * The overlay. + */ + private static final Component OVERLAY = new Component(24); + + /** + * The activity handling pulse. + */ + private static final Pulse PULSE = new Pulse(0) { + @Override + public boolean pulse() { + boolean end = true; + for (Player p : RegionManager.getRegionPlayers(14231)) { + end = false; + int index = p.getAttribute("barrow:drain-index", -1); + if (index > -1) { + p.removeAttribute("barrow:drain-index"); + p.getPacketDispatch().sendItemOnInterface(-1, 1, 24, index); + continue; + } + if (p.getLocation().getZ() == 0 && p.getAttribute("barrow:looted", false) && getWorldTicks() % 3 == 0) { + if (RandomFunction.random(15) == 0) { + p.getImpactHandler().manualHit(p, RandomFunction.random(5), HitsplatType.NORMAL); + Graphics.send(Graphics.create(405), p.getLocation()); + } + } + int drain = 8; + + //if (p.getLocks().isLocked("barrow:drain") || RandomFunction.random(100) % 2 == 0) { + // continue; + //} + for (boolean killed : p.getSavedData().getActivityData().getBarrowBrothers()) { + if (killed) { + drain += 1; + } + } + if(getWorldTicks() % 30 == 0){ + p.getSkills().decrementPrayerPoints(drain); + p.getLocks().lock("barrow:drain", (3 + RandomFunction.random(15)) * 3); + index = 1 + RandomFunction.random(6); + p.setAttribute("barrow:drain-index", index); + p.getPacketDispatch().sendItemZoomOnInterface(4761 + RandomFunction.random(12), 100, 24, index); + p.getPacketDispatch().sendAnimationInterface(9810, 24, index); + } + } + return end; + } + }; + + /** + * Constructs a new {@code BarrowsActivityPlugin} {@code Object}. + */ + public BarrowsActivityPlugin() { + super("Barrows", false, false, false); + } + + @Override + public void locationUpdate(Entity e, Location last) { + if (e instanceof Player && e.getViewport().getRegion().getId() == 14231) { + boolean tunnel = false; + for (ZoneBorders border : MINI_TUNNELS) { + if (border.insideBorder(e)) { + tunnel = true; + break; + } + } + Player player = (Player) e; + if ((getVarp(player, 1270) == 1) != tunnel) { + setVarp(player, 1270, tunnel ? 3 : 0, true); + } + } + } + + @Override + public boolean enter(Entity e) { + if (e instanceof Player) { + Player player = (Player) e; + PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 2)); + player.getInterfaceManager().openOverlay(OVERLAY); + setVarp(player, 0, 1); + if (getVarp(player, 452) == 0) { + shuffleCatacombs(player); + } + sendConfiguration(player); + if (!PULSE.isRunning()) { + PULSE.restart(); + PULSE.start(); + GameWorld.getPulser().submit(PULSE); + } + } else { + ((NPC) e).setAggressive(true); + ((NPC) e).setAggressiveHandler(new AggressiveHandler(e, new AggressiveBehavior() { + @Override + public boolean canSelectTarget(Entity entity, Entity target) { + if (!target.isActive() || DeathTask.isDead(target)) { + return false; + } + if (!target.getProperties().isMultiZone() && target.inCombat()) { + return false; + } + return true; + } + })); + } + return super.enter(e); + } + + @Override + public boolean leave(Entity e, boolean logout) { + if (e instanceof Player) { + Player player = (Player) e; + PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 0)); + player.getInterfaceManager().closeOverlay(); + NPC npc = player.getAttribute("barrow:npc"); + if (npc != null && !DeathTask.isDead(npc)) { + npc.clear(); + } + player.removeAttribute("barrow:solvedpuzzle"); + player.removeAttribute("barrow:opened_chest"); + player.removeAttribute("crusade-delay"); + if (!logout && player.getAttribute("barrow:looted", false)) { + for (int i = 0; i < 6; i++) { + player.removeAttribute("brother:" + i); + player.getSavedData().getActivityData().getBarrowBrothers()[i] = false; + } + player.removeAttribute("barrow:looted"); + shuffleCatacombs(player); + player.getSavedData().getActivityData().setBarrowTunnelIndex(RandomFunction.random(6)); + player.getSavedData().getActivityData().setBarrowKills(0); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.RESET, 0, 0, 0, 0, 0)); + } + } + return super.leave(e, logout); + } + + /** + * "Shuffles" the catacomb gates. + * @param player The player. + */ + public static void shuffleCatacombs(Player player) { + int value = TUNNEL_CONFIGS[RandomFunction.random(TUNNEL_CONFIGS.length)]; + value |= 1 << (6 + RandomFunction.random(4)); + setVarp(player, 452, value); + } + + @Override + public boolean death(Entity e, Entity killer) { + Player player = null; + if (killer instanceof Player) { + player = (Player) killer; + } else if (killer instanceof Familiar) { + player = ((Familiar) killer).getOwner(); + } + if (player != null && e instanceof NPC) { + player.getSavedData().getActivityData().setBarrowKills(player.getSavedData().getActivityData().getBarrowKills() + 1); + sendConfiguration(player); + } + return false; + } + + @Override + public boolean interact(Entity e, Node target, Option option) { + if (target instanceof Scenery) { + Scenery object = (Scenery) target; + Player player = (Player) e; + if (object.getId() >= 6702 && object.getId() <= 6707) { + ClimbActionHandler.climb((Player) e, ClimbActionHandler.CLIMB_UP, BarrowsCrypt.getCrypt(object.getId() - 6702).getExitLocation()); + return true; + } + if (object.getId() >= 6708 && object.getId() <= 6712) { + ClimbActionHandler.climb((Player) e, ClimbActionHandler.CLIMB_UP, BarrowsCrypt.getCrypt(player.getSavedData().getActivityData().getBarrowTunnelIndex()).getEnterLocation()); + return true; + } + switch (object.getWrapper().getId()) { + case 6727: + case 6724: + case 6746: + case 6743: + if (player.getAttribute("barrow:solvedpuzzle", false)) { + break; + } + player.setAttribute("barrow:puzzledoor", object); + BarrowsPuzzle.open(player); + return true; + } + switch (object.getId()) { + case 6714: + case 6733: + DoorActionHandler.handleAutowalkDoor(e, (Scenery) target); + if (RandomFunction.random(15) == 0) { + // spawn a brother, if any haven't yet been killed + boolean[] brothers = player.getSavedData().getActivityData().getBarrowBrothers(); + int[] alive = IntStream.range(0, 6).filter(i -> !brothers[i]).toArray(); + if (alive.length > 0) { + int index = 0; + if (alive.length > 1) { + index = RandomFunction.random(0, alive.length); + } + BarrowsCrypt.getCrypt(alive[index]).spawnBrother(player, RegionManager.getTeleportLocation(target.getLocation(), 1)); + } + } + return true; + case 6821: + BarrowsCrypt.getCrypt(BarrowsCrypt.AHRIM).openSarcophagus((Player) e, object); + return true; + case 6771: + BarrowsCrypt.getCrypt(BarrowsCrypt.DHAROK).openSarcophagus((Player) e, object); + return true; + case 6773: + BarrowsCrypt.getCrypt(BarrowsCrypt.GUTHAN).openSarcophagus((Player) e, object); + return true; + case 6822: + BarrowsCrypt.getCrypt(BarrowsCrypt.KARIL).openSarcophagus((Player) e, object); + return true; + case 6772: + BarrowsCrypt.getCrypt(BarrowsCrypt.TORAG).openSarcophagus((Player) e, object); + return true; + case 6823: + BarrowsCrypt.getCrypt(BarrowsCrypt.VERAC).openSarcophagus((Player) e, object); + return true; + case 6774: + player.lock(1); + int brother = player.getSavedData().getActivityData().getBarrowTunnelIndex(); + if (!player.getSavedData().getActivityData().getBarrowBrothers()[brother] && !player.getAttribute("brother:" + brother, false)) { + BarrowsCrypt.getCrypt(brother).spawnBrother(player, RegionManager.getTeleportLocation(target.getCenterLocation(), 4)); + } + player.setAttribute("barrow:opened_chest", true); + sendConfiguration(player); + return true; + case 6775: + if (option.getName().equals("Close")) { + player.removeAttribute("barrow:opened_chest"); + sendConfiguration(player); + return true; + } + if (player.getAttribute("barrow:looted", false)) { + player.getPacketDispatch().sendMessage("The chest is empty."); + return true; + } + player.setAttribute("/save:barrow:looted",true); + RewardChest.reward(player); + //PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.SHAKE, 3, 2, 2, 2, 2)); + return true; + } + } + return false; + } + + /** + * Sends the kill count configuration. + * @param player The player. + */ + public static void sendConfiguration(Player player) { + ActivityData data = player.getSavedData().getActivityData(); + int config = data.getBarrowKills() << 17; + for (int i = 0; i < data.getBarrowBrothers().length; i++) { + if (data.getBarrowBrothers()[i]) { // This actually wasn't in 498 + // but we'll keep it anyways. + config |= 1 << i; + } + } + if (player.getAttribute("barrow:opened_chest", false)) { + config |= 1 << 16; + } + setVarp(player, 453, config); + } + + @Override + public boolean actionButton(Player player, int interfaceId, int buttonId, int slot, int itemId, int opcode) { + return false; + } + + @Override + public boolean continueAttack(Entity e, Node target, CombatStyle style, boolean message) { + if (target instanceof BarrowBrother) { + Player p = null; + if (e instanceof Player) { + p = (Player) e; + } else if (e instanceof Familiar) { + p = ((Familiar) e).getOwner(); + } + if (p != null && p != ((BarrowBrother) target).getPlayer()) { + p.getPacketDispatch().sendMessage("He's not after you."); + return false; + } + } + return super.continueAttack(e, target, style, message); + } + + @Override + public ActivityPlugin newInstance(Player p) throws Throwable { + return this; + } + + @Override + public Location getSpawnLocation() { + return null; + } + + @Override + public void configure() { + ClassScanner.definePlugin(new TunnelEntranceDialogue()); + ClassScanner.definePlugin(BarrowsPuzzle.SHAPES); + registerRegion(14231); + BarrowsCrypt.init(); + PULSE.stop(); + } + +} diff --git a/Server/src/main/content/minigame/barrows/BarrowsCrypt.java b/Server/src/main/content/minigame/barrows/BarrowsCrypt.java new file mode 100644 index 0000000..60c0579 --- /dev/null +++ b/Server/src/main/content/minigame/barrows/BarrowsCrypt.java @@ -0,0 +1,191 @@ +package content.minigame.barrows; + +import core.game.global.action.DigAction; +import core.game.global.action.DigSpadeHandler; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; + +/** + * Handles a barrows crypt. + * @author Emperor + */ +public final class BarrowsCrypt { + + /** + * The ahrim barrows crypt index. + */ + public static final int AHRIM = 0; + + /** + * The dharok barrows crypt index. + */ + public static final int DHAROK = 1; + + /** + * The guthan barrows crypt index. + */ + public static final int GUTHAN = 2; + + /** + * The karil barrows crypt index. + */ + public static final int KARIL = 3; + + /** + * The torag barrows crypt index. + */ + public static final int TORAG = 4; + + /** + * The verac barrows crypt index. + */ + public static final int VERAC = 5; + + /** + * The barrows crypts. + */ + private static final BarrowsCrypt[] CRYPTS = { new BarrowsCrypt(AHRIM, 2025, Location.create(3557, 9703, 3), Location.create(3565, 3289, 0)), new BarrowsCrypt(DHAROK, 2026, Location.create(3556, 9718, 3), Location.create(3575, 3298, 0)), new BarrowsCrypt(GUTHAN, 2027, Location.create(3534, 9704, 3), Location.create(3577, 3283, 0)), new BarrowsCrypt(KARIL, 2028, Location.create(3546, 9684, 3), Location.create(3565, 3276, 0)), new BarrowsCrypt(TORAG, 2029, Location.create(3568, 9683, 3), Location.create(3553, 3283, 0)), new BarrowsCrypt(VERAC, 2030, Location.create(3578, 9706, 3), Location.create(3557, 3298, 0)) }; + + /** + * The NPC id. + */ + private final int npcId; + + /** + * The location to teleport to when entering the crypt. + */ + private final Location location; + + /** + * The exit location. + */ + private final Location exitLocation; + + /** + * The crypt index. + */ + private final int index; + + /** + * Constructs a new {@code BarrowsCrypt} {@code Object}. + * @param location The location to teleport to when entering the crypt. + * @param exitLocation The location to teleport to when leaving the crypt. + */ + public BarrowsCrypt(int index, int npcId, Location location, Location exitLocation) { + this.index = index; + this.npcId = npcId; + this.location = location; + this.exitLocation = exitLocation; + } + + /** + * Initializes the barrow crypts. + */ + public static void init() { + for (final BarrowsCrypt crypt : CRYPTS) { + DigAction action = new DigAction() { + @Override + public void run(Player player) { + crypt.enter(player); + } + }; + Location base = crypt.getExitLocation(); + for (int x = -2; x <= 2; x++) { + for (int y = -2; y <= 2; y++) { + DigSpadeHandler.register(base.transform(x, y, 0), action); + } + } + } + } + + /** + * Opens the sarcophagus. + * @param player The player. + */ + public void openSarcophagus(Player player, Scenery object) { + if (index == player.getSavedData().getActivityData().getBarrowTunnelIndex()) { + player.getDialogueInterpreter().open("barrow_tunnel", index); + return; + } + if (player.getSavedData().getActivityData().getBarrowBrothers()[index] || player.getAttribute("barrow:npc") != null) { + player.getPacketDispatch().sendMessage("You don't find anything."); + return; + } + player.getPacketDispatch().sendMessage("You don't find anything."); + Location location = RegionManager.getTeleportLocation(object.getLocation().transform(Direction.SOUTH_WEST), object.getSizeX() + 1, object.getSizeY() + 1); + spawnBrother(player, location); + } + + /** + * Spawns the barrow brother. + * @param player The player. + * @param location The location. + * @return {@code True} if successful. + */ + public boolean spawnBrother(Player player, Location location) { + if (player.getAttribute("brother:" + index, false)) { + return false; + } + NPC npc = new BarrowBrother(player, npcId, location); + npc.init(); + player.setAttribute("barrow:npc", npc); + player.setAttribute("brother:" + index, true); + return true; + } + + /** + * Enters the crypt. + * @param player The player. + */ + protected void enter(Player player) { + player.addExtension(BarrowsCrypt.class, this); + player.getPacketDispatch().sendMessage("You've broken into a crypt!"); + player.getProperties().setTeleportLocation(getEnterLocation()); + } + + /** + * Gets the crypt for the given index. + * @param index The crypt index. + * @return The barrows crypt. + */ + public static BarrowsCrypt getCrypt(int index) { + return CRYPTS[index]; + } + + /** + * Gets the location to teleport to upon entering. + * @return The location. + */ + public Location getEnterLocation() { + return location; + } + + /** + * Gets the exit location. + * @return The location. + */ + public Location getExitLocation() { + return exitLocation; + } + + /** + * Gets the npcId. + * @return The npcId. + */ + public int getNpcId() { + return npcId; + } + + /** + * Gets the index. + * @return The index. + */ + public int getIndex() { + return index; + } + +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/barrows/BarrowsPuzzle.java b/Server/src/main/content/minigame/barrows/BarrowsPuzzle.java new file mode 100644 index 0000000..73762e8 --- /dev/null +++ b/Server/src/main/content/minigame/barrows/BarrowsPuzzle.java @@ -0,0 +1,169 @@ +package content.minigame.barrows; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Random; + +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.node.entity.player.Player; +import core.net.packet.PacketRepository; +import core.net.packet.context.DisplayModelContext; +import core.net.packet.context.DisplayModelContext.ModelType; +import core.net.packet.out.DisplayModel; +import core.plugin.Plugin; +import core.tools.RandomFunction; + +/** + * Handles the barrows puzzle. + * @author Emperor + */ +public final class BarrowsPuzzle extends ComponentPlugin { + + /** + * The shapes puzzle. + */ + public static final BarrowsPuzzle SHAPES = new BarrowsPuzzle(new int[] { 6734, 6735, 6736 }, getAnswerModel(6731, true), getAnswerModel(6732, false), getAnswerModel(6733, false)); + + /** + * The lines puzzle. + */ + public static final BarrowsPuzzle LINES = new BarrowsPuzzle(new int[] { 6728, 6729, 6730 }, getAnswerModel(6725, true), getAnswerModel(6726, false), getAnswerModel(6727, false)); + + /** + * The squares puzzle. + */ + public static final BarrowsPuzzle SQUARES = new BarrowsPuzzle(new int[] { 6722, 6723, 6724 }, getAnswerModel(6719, true), getAnswerModel(6720, false), getAnswerModel(6721, false)); + + /** + * The triangle-on-circles puzzle. + */ + public static final BarrowsPuzzle TRIANGLE_CIRCLES = new BarrowsPuzzle(new int[] { 6716, 6717, 6718 }, getAnswerModel(6713, true), getAnswerModel(6714, false), getAnswerModel(6715, false)); + + /** + * The puzzle component. + */ + private static final Component COMPONENT = new Component(25); + + /** + * The question models. + */ + private final int[] questionModels; + + /** + * The answer models. + */ + private final int[] answerModels; + + /** + * Constructs a new {@code BarrowsPuzzle} {@code Object}. + * @param questionModels The question models. + * @param answerModels The answer models. + */ + private BarrowsPuzzle(int[] questionModels, int... answerModels) { + this.questionModels = questionModels; + this.answerModels = answerModels; + } + + /** + * Creates a new barrows puzzle instance of this puzzle. + * @return The new barrows puzzle instance. + */ + public BarrowsPuzzle create() { + int[] answers = Arrays.copyOf(answerModels, answerModels.length); + List list = new ArrayList<>(20); + for (int answer : answers) { + list.add(answer); + } + Collections.shuffle(list, new Random()); + for (int i = 0; i < list.size(); i++) { + answers[i] = list.get(i); + } + return new BarrowsPuzzle(questionModels, answers); + } + + /** + * Opens a random barrows puzzle. + * @param player The player. + */ + public static void open(Player player) { + int index = RandomFunction.random(4); + if (index == player.getAttribute("puzzle:index", -1)) { + index = (index + 1) % 4; + } + open(player, index); + } + + /** + * Opens the barrows puzzle for the given index. + * @param player The player. + * @param index The index (0 = shapes, 1 = lines, 2 = squares, 3 = + * triangle-on-circle). + */ + public static void open(Player player, int index) { + BarrowsPuzzle puzzle = SHAPES; + switch (index) { + case 1: + puzzle = LINES; + break; + case 2: + puzzle = SQUARES; + break; + case 3: + puzzle = TRIANGLE_CIRCLES; + break; + } + puzzle = puzzle.create(); + player.setAttribute("puzzle:index", index); + player.setAttribute("puzzle:answers", puzzle.answerModels); + player.getInterfaceManager().open(COMPONENT); + for (int i = 0; i < puzzle.questionModels.length; i++) { + PacketRepository.send(DisplayModel.class, new DisplayModelContext(player, ModelType.MODEL, puzzle.questionModels[i], 0, 25, 6 + i)); + } + for (int i = 0; i < puzzle.answerModels.length; i++) { + PacketRepository.send(DisplayModel.class, new DisplayModelContext(player, ModelType.MODEL, puzzle.answerModels[i] & 0xFFFF, 0, 25, 2 + i)); + } + PacketRepository.send(DisplayModel.class, new DisplayModelContext(player, ModelType.MODEL, puzzle.answerModels[2] & 0xFFFF, 0, 25, 5)); + } + + /** + * Gets the answer model id. + * @param modelId The model id. + * @param correct If the answer is correct. + * @return The model id hash. + */ + private static int getAnswerModel(int modelId, boolean correct) { + return modelId | (correct ? 1 : 0) << 16; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.put(25, this); + return this; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + switch (button) { + case 2: + case 3: + case 5: + player.getInterfaceManager().close(); + boolean correct = ((player.getAttribute("puzzle:answers", new int[3])[button == 5 ? 2 : button - 2] >> 16) & 0xFF) == 1; + if (!correct) { + player.getPacketDispatch().sendMessage("You got the puzzle wrong! You can hear the catacombs moving around you."); + BarrowsActivityPlugin.shuffleCatacombs(player); + break; + } + player.setAttribute("/save:barrow:solvedpuzzle", true); + player.getPacketDispatch().sendMessage("You hear the doors' locking mechanism grind open."); + break; + default: + return false; + } + return true; + } +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/barrows/RewardChest.kt b/Server/src/main/content/minigame/barrows/RewardChest.kt new file mode 100644 index 0000000..d12f48a --- /dev/null +++ b/Server/src/main/content/minigame/barrows/RewardChest.kt @@ -0,0 +1,89 @@ +package content.minigame.barrows + +import core.api.announceIfRare +import core.game.component.Component +import core.game.container.access.InterfaceContainer +import content.data.BossKillCounter +import core.game.node.entity.player.Player +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import core.tools.RandomFunction +import org.rs09.consts.Components +import org.rs09.consts.Items +import core.api.utils.WeightBasedTable +import core.api.utils.WeightedItem + +/** + * The reward chest. + * @author Ceikry + * @author kermit + * @author Player Name + */ +object RewardChest { + private val REGULAR_DROPS = WeightBasedTable.create( + WeightedItem(Items.COINS_995, 1, 777, 380.0), + WeightedItem(Items.MIND_RUNE_558, 250, 350, 125.0), + WeightedItem(Items.CHAOS_RUNE_562, 115, 135, 125.0), + WeightedItem(Items.DEATH_RUNE_560, 70, 85, 125.0), + WeightedItem(Items.BLOOD_RUNE_565, 35, 45, 125.0), + WeightedItem(Items.BOLT_RACK_4740, 35, 40, 125.0), + WeightedItem(Items.TOOTH_HALF_OF_A_KEY_985, 1, 1, 3.0), + WeightedItem(Items.LOOP_HALF_OF_A_KEY_987, 1, 1, 3.0), + WeightedItem(Items.DRAGON_MED_HELM_1149, 1, 1, 1.0) + ) + private val AHRIM = arrayOf(4708, 4710, 4712, 4714) + private val DHAROK = arrayOf(4716, 4718, 4720, 4722) + private val GUTHAN = arrayOf(4724, 4726, 4728, 4730) + private val KARIL = arrayOf(4732, 4734, 4736, 4738) + private val TORAG = arrayOf(4745, 4747, 4749, 4751) + private val VERAC = arrayOf(4753, 4755, 4757, 4759) + private val BARROWS_DROP_IDS = arrayOf(AHRIM, DHAROK, GUTHAN, KARIL, TORAG, VERAC) + + /** + * Rewards the player. + * + * @param player The player. + */ + @JvmStatic + fun reward(player: Player) { + var barrowsRewardsIDs: MutableList = ArrayList() + for (i in 0..5) { + if (player.savedData.activityData.barrowBrothers[i]) { + barrowsRewardsIDs.addAll(BARROWS_DROP_IDS[i]) + } + } + barrowsRewardsIDs.shuffle() + + var rewards: MutableList = ArrayList() + val nKilled = barrowsRewardsIDs.size / 4 + roll@for (i in 0 until nKilled+1) { + if (barrowsRewardsIDs.size > 0 && RandomFunction.roll(450 - 58 * nKilled)) { + // Award a random item from a random brother + val reward = barrowsRewardsIDs[0] + rewards.add(Item(reward, 1)) + barrowsRewardsIDs.removeAt(0) + } else { + // Award a drop from the regular drop table + val drop = REGULAR_DROPS.roll(null, 1)[0] + for (i in 0 until rewards.size) { + // If we have already awarded this item, just add to the previous quantity + if (rewards[i].id == drop.id) { + rewards[i].amount += drop.amount + continue@roll + } + } + rewards.add(drop) + } + } + + InterfaceContainer.generateItems(player, rewards.toTypedArray(), arrayOf("Examine"), 364, 4, 3, 4) + player.interfaceManager.open(Component(Components.TRAIL_REWARD_364)) + BossKillCounter.addtoBarrowsCount(player) + for (item in rewards) { + announceIfRare(player, item) + if (!player.inventory.add(item)) { + GroundItemManager.create(item, player) + } + } + } +} diff --git a/Server/src/main/content/minigame/barrows/TunnelEntranceDialogue.java b/Server/src/main/content/minigame/barrows/TunnelEntranceDialogue.java new file mode 100644 index 0000000..22331c4 --- /dev/null +++ b/Server/src/main/content/minigame/barrows/TunnelEntranceDialogue.java @@ -0,0 +1,85 @@ +package content.minigame.barrows; + +import core.game.dialogue.DialogueInterpreter; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.plugin.PluginManifest; +import core.plugin.PluginType; + +import static core.api.ContentAPIKt.*; + +/** + * The tunnel entrance dialogue handling plugin. + * @author Emperor + */ +@PluginManifest(type = PluginType.DIALOGUE) +public final class TunnelEntranceDialogue extends DialoguePlugin { + + /** + * The crypt index. + */ + @SuppressWarnings("unused") + private int index; + + /** + * Constructs a new {@code TunnelEntranceDialogue} {@code Object}. + */ + public TunnelEntranceDialogue() { + super(); + } + + /** + * Constructs a new {@code TunnelEntranceDialogue} {@code Object}. + * @param player The player. + */ + public TunnelEntranceDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new TunnelEntranceDialogue(player); + } + + @Override + public boolean open(Object... args) { + this.index = (Integer) args[0]; + player.getDialogueInterpreter().sendPlainMessage(false, "You find a hidden tunnel, do you want to enter?"); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + if (stage++ == 0) { + player.getDialogueInterpreter().sendOptions(null, "Yeah, I'm fearless!", "No way, that looks scary!"); + return true; + } + switch (buttonId) { + case 1: + int offsetX = 0; + int offsetY = 0; + int configValue = getVarp(player, 452); + if ((configValue & (1 << 7)) != 0) { + offsetX = 34; + offsetY = 34; + } else if ((configValue & (1 << 6)) != 0) { + offsetY = 34; + } else if ((configValue & (1 << 9)) != 0) { + offsetX = 34; + } + int x = 3534 + offsetX; + int y = 9677 + offsetY; + player.getProperties().setTeleportLocation(Location.create(x, y, 0)); + case 2: + end(); + return true; + } + return false; + } + + @Override + public int[] getIds() { + return new int[] { DialogueInterpreter.getDialogueKey("barrow_tunnel") }; + } +} diff --git a/Server/src/main/content/minigame/blastfurnace/BFBeltOre.kt b/Server/src/main/content/minigame/blastfurnace/BFBeltOre.kt new file mode 100644 index 0000000..6506960 --- /dev/null +++ b/Server/src/main/content/minigame/blastfurnace/BFBeltOre.kt @@ -0,0 +1,61 @@ +package content.minigame.blastfurnace + +import core.api.animate +import core.api.queueScript +import core.api.teleport +import core.game.interaction.QueueStrength +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.world.map.Direction +import core.game.world.map.Location +import org.json.simple.JSONObject + +class BFBeltOre (val player: Player, val id: Int, val amount: Int, var location: Location, var npcInstance: NPC? = null) { + val state = BlastFurnace.getPlayerState(player) + + fun tick(): Boolean { + if (location == ORE_END_LOC && npcInstance != null) { + state.container.addOre(id, amount) + npcInstance?.clear() + npcInstance = null + return true + } + else if (npcInstance != null) { + location = location.transform(Direction.SOUTH, 1) + teleport(npcInstance!!, location) + + if (location == ORE_END_LOC) { + val npc = npcInstance!! + queueScript(npc, 1, QueueStrength.STRONG) {_ -> + animate(npc, ORE_DEPOSIT_ANIM) + return@queueScript true + } + } + } + return false + } + + fun createNpc() { + if (npcInstance != null) return + val npcId = BlastFurnace.getNpcForOre(id) + val npc = NPC.create(npcId, location) + npc.isWalks = false + npc.init() + + npcInstance = npc + } + + fun toJson(): JSONObject { + val root = JSONObject() + root["id"] = id.toString() + root["amount"] = amount.toString() + root["location"] = location.toString() + return root + } + + companion object { + val ORE_START_LOC = Location.create(1942, 4966, 0) + val ORE_END_LOC = Location.create(1942, 4963, 0) + val ORE_DEPOSIT_ANIM = 2434 + } +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/blastfurnace/BFOreContainer.kt b/Server/src/main/content/minigame/blastfurnace/BFOreContainer.kt new file mode 100644 index 0000000..5ed5c2c --- /dev/null +++ b/Server/src/main/content/minigame/blastfurnace/BFOreContainer.kt @@ -0,0 +1,194 @@ +package content.minigame.blastfurnace + +import content.global.skill.smithing.smelting.Bar +import content.minigame.blastfurnace.BlastConsts.BAR_LIMIT +import content.minigame.blastfurnace.BlastFurnace.Companion.getBarForOreId +import content.minigame.blastfurnace.BlastFurnace.Companion.getNeededCoal +import core.game.node.item.Item +import org.json.simple.JSONArray +import org.json.simple.JSONObject +import org.rs09.consts.Items + +class BFOreContainer { + private var coalRemaining = 0 //this is the actual important value needed for the calculations and is unit tested + private var ores = Array(BlastConsts.ORE_LIMIT * 2) {-1} + private var barAmounts = Array(9) {0} + + fun addCoal(amount: Int) : Int { + val maxAdd = BlastConsts.COAL_LIMIT - coalRemaining + val toAdd = amount.coerceAtMost(maxAdd) + coalRemaining += toAdd + return amount - toAdd + } + + fun coalAmount() : Int { + return coalRemaining + } + + fun addOre (id: Int, amount: Int): Int { + if (id == Items.COAL_453) + return addCoal(amount) + + var limit = BlastConsts.ORE_LIMIT + if (getBarForOreId(id, -1, 99) == Bar.BRONZE) + limit *= 2 + + var amountLeft = amount + var maxAdd = getAvailableSpace(id, 99) + for (i in 0 until limit) { + if (ores[i] == -1) { + ores[i] = id + if (--amountLeft == 0 || --maxAdd == 0) break + } + } + return amountLeft + } + + fun getOreAmount (id: Int) : Int { + if (id == Items.COAL_453) + return coalAmount() + + var oreCount = 0 + for (i in 0 until BlastConsts.ORE_LIMIT) { + if (ores[i] == id) oreCount++ + } + return oreCount + } + + fun indexOfOre (id: Int) : Int { + for (i in ores.indices) + if (ores[i] == id) return i + return -1 + } + + fun getOreAmounts() : HashMap { + val map = HashMap() + for (ore in ores) { + if (ore == -1) break + map[ore] = (map[ore] ?: 0) + 1 + } + return map + } + + fun convertToBars(level: Int = 99) : Double { + val newOres = Array(BlastConsts.ORE_LIMIT * 2) {-1} + var oreIndex = 0 + var xpReward = 0.0 + for (i in 0 until BlastConsts.ORE_LIMIT) { + val bar = getBarForOreId(ores[i], coalRemaining, level) + + if (bar == null) { + ores[i] = -1 + continue + } + + if (barAmounts[bar.ordinal] >= BAR_LIMIT) { + newOres[oreIndex++] = ores[i] + continue + } + + val coalNeeded = getNeededCoal(bar) + + //special handling for bronze bar edge case, no other ore does this. + if (bar == Bar.BRONZE) { + val indexOfComplement = when (ores[i]) { + Items.COPPER_ORE_436 -> indexOfOre(Items.TIN_ORE_438) + Items.TIN_ORE_438 -> indexOfOre(Items.COPPER_ORE_436) + else -> -1 + } + if (indexOfComplement == -1) { + newOres[oreIndex++] = ores[i] + continue + } + ores[indexOfComplement] = -1 + } + + if (coalRemaining >= coalNeeded) { + coalRemaining -= coalNeeded + ores[i] = -1 + barAmounts[bar.ordinal]++ + xpReward += bar.experience + } else { + newOres[oreIndex++] = ores[i] + } + } + ores = newOres + return xpReward + } + + fun getBarAmount (bar: Bar) : Int { + return barAmounts[bar.ordinal] + } + + fun getTotalBarAmount() : Int { + var total = 0 + for (i in barAmounts) total += i + return total + } + + fun takeBars (bar: Bar, amount: Int) : Item? { + val amt = amount.coerceAtMost(barAmounts[bar.ordinal]) + if (amt == 0) return null + + barAmounts[bar.ordinal] -= amt + return Item(bar.product.id, amt) + } + + fun getAvailableSpace (ore: Int, level: Int = 99) : Int { + if (ore == Items.COAL_453) + return BlastConsts.COAL_LIMIT - coalRemaining + + var freeSlots = 0 + val bar = getBarForOreId(ore, coalRemaining, level)!! + val oreAmounts = HashMap() + for (i in 0 until BlastConsts.ORE_LIMIT) + if (ores[i] == -1) { + var oreLimit = BlastConsts.ORE_LIMIT + if (bar == Bar.BRONZE) oreLimit *= 2 + freeSlots = oreLimit - i + break + } + else oreAmounts[ores[i]] = (oreAmounts[ores[i]] ?: 0) + 1 + + val currentAmount = oreAmounts[ore] ?: 0 + freeSlots = (BlastConsts.ORE_LIMIT - currentAmount).coerceAtMost(freeSlots) + + return (freeSlots - getBarAmount(bar)).coerceAtLeast(0) + } + + fun hasAnyOre() : Boolean { + return ores[0] != -1 + } + + fun toJson() : JSONObject { + val root = JSONObject() + val ores = JSONArray() + val bars = JSONArray() + + for (ore in this.ores) + ores.add(ore.toString()) + for (amount in barAmounts) + bars.add(amount.toString()) + + root["ores"] = ores + root["bars"] = bars + root["coal"] = coalRemaining.toString() + return root + } + + companion object { + fun fromJson (root: JSONObject) : BFOreContainer { + val cont = BFOreContainer() + val jsonOres = root["ores"] as? JSONArray ?: return cont + val jsonBars = root["bars"] as? JSONArray ?: return cont + + + for (i in 0 until BlastConsts.ORE_LIMIT) + cont.ores[i] = jsonOres[i].toString().toIntOrNull() ?: -1 + for (i in 0 until 9) + cont.barAmounts[i] = jsonBars[i].toString().toIntOrNull() ?: 0 + cont.coalRemaining = root["coal"].toString().toIntOrNull() ?: 0 + return cont + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/blastfurnace/BFPlayerState.kt b/Server/src/main/content/minigame/blastfurnace/BFPlayerState.kt new file mode 100644 index 0000000..a7f44f3 --- /dev/null +++ b/Server/src/main/content/minigame/blastfurnace/BFPlayerState.kt @@ -0,0 +1,156 @@ +package content.minigame.blastfurnace + +import content.global.skill.smithing.smelting.Bar +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.world.map.Location +import org.json.simple.JSONArray +import org.json.simple.JSONObject + +class BFPlayerState (val player: Player) { + var container = BFOreContainer() + val oresOnBelt = ArrayList() + var barsNeedCooled = false + private set + + fun processOresIntoBars() : Boolean { + if (barsNeedCooled && getVarbit(player, DISPENSER_STATE) == 1) { + setVarbit(player, DISPENSER_STATE, 2, true) + return false + } + if (getVarbit(player, DISPENSER_STATE) != 0 || !container.hasAnyOre()) + return false + + val xpReward = container.convertToBars(getStatLevel(player, Skills.SMITHING)) + if (xpReward > 0) { + rewardXP(player, Skills.SMITHING, xpReward) + setVarbit(player, DISPENSER_STATE, 1, true) + barsNeedCooled = true + return true + } + + return false + } + + fun updateOres() { + val toRemove = ArrayList() + for (ore in oresOnBelt) { + if (ore.tick()) + toRemove.add(ore) + } + oresOnBelt.removeAll(toRemove) + } + + fun coolBars() { + barsNeedCooled = false + setVarbit(player, DISPENSER_STATE, 3, true) + } + + fun checkBars() { + if (getVarbit(player, DISPENSER_STATE) == 3) + setVarbit(player, DISPENSER_STATE, 0, true) + } + + fun hasBarsClaimable(): Boolean { + return container.getTotalBarAmount() > 0 + } + + fun claimBars (bar: Bar, amount: Int) : Boolean { + if (barsNeedCooled) return false + + val maxAmt = amount.coerceAtMost(freeSlots(player)) + if (maxAmt == 0) return false + + val reward = container.takeBars(bar, maxAmt) ?: return false + addItem(player, reward.id, reward.amount) + setBarClaimVarbits() + return true + } + + fun setBarClaimVarbits() { + for (bar in Bar.values()) { + val amount = container.getBarAmount(bar) + val varbit = getVarbitForBar(bar) + if (varbit == 0) continue + + if (getVarbit(player, varbit) == amount) + continue + + setVarbit(player, varbit, amount, true) + } + + var totalCoalNeeded = 0 + val level = getStatLevel(player, Skills.SMITHING) + for ((id, amount) in container.getOreAmounts()) { + val barType = BlastFurnace.getBarForOreId(id, container.coalAmount(), level) + totalCoalNeeded += BlastFurnace.getNeededCoal(barType!!) * amount + } + + setVarbit(player, COAL_NEEDED, (totalCoalNeeded - container.coalAmount()).coerceAtLeast(0)) + } + + private fun getVarbitForBar (bar: Bar) : Int { + return when (bar) { + Bar.BRONZE -> BRONZE_COUNT + Bar.IRON -> IRON_COUNT + Bar.STEEL -> STEEL_COUNT + Bar.MITHRIL -> MITHRIL_COUNT + Bar.ADAMANT -> ADDY_COUNT + Bar.RUNITE -> RUNITE_COUNT + Bar.SILVER -> SILVER_COUNT + Bar.GOLD -> GOLD_COUNT + else -> 0 + } + } + + fun toJson() : JSONObject { + val save = JSONObject() + save["bf-ore-cont"] = container.toJson() + + val beltOres = JSONArray() + for (ore in oresOnBelt) { + beltOres.add(ore.toJson()) + } + + if (beltOres.isNotEmpty()) + save["bf-belt-ores"] = beltOres + save["barsHot"] = barsNeedCooled + + return save + } + + fun readJson (data: JSONObject) { + oresOnBelt.clear() + if (data.containsKey("bf-ore-cont")) { + val contJson = data["bf-ore-cont"] as JSONObject + container = BFOreContainer.fromJson(contJson) + } + if (data.containsKey("bf-belt-ores")) { + val beltArray = data["bf-belt-ores"] as JSONArray + for (oreObj in beltArray) { + val oreInfo = oreObj as JSONObject + val id = oreInfo["id"].toString().toInt() + val amount = oreInfo["amount"].toString().toInt() + val location = Location.fromString(oreInfo["location"].toString()) + val ore = BFBeltOre(player, id, amount, location) + oresOnBelt.add(ore) + } + } + if (data.containsKey("barsHot")) + barsNeedCooled = data["barsHot"] as Boolean + } + + companion object { + val DISPENSER_STATE = 936 + val COAL_NEEDED = 940 + val BRONZE_COUNT = 941 + val IRON_COUNT = 942 + val STEEL_COUNT = 943 + val MITHRIL_COUNT = 944 + val ADDY_COUNT = 945 + val RUNITE_COUNT = 946 + val GOLD_COUNT = 947 + val SILVER_COUNT = 948 + } +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/blastfurnace/BFSceneryController.kt b/Server/src/main/content/minigame/blastfurnace/BFSceneryController.kt new file mode 100644 index 0000000..d2d3e16 --- /dev/null +++ b/Server/src/main/content/minigame/blastfurnace/BFSceneryController.kt @@ -0,0 +1,110 @@ +package content.minigame.blastfurnace + +import core.api.animateScenery +import core.api.getScenery +import core.api.replaceScenery +import core.game.world.map.Location + +class BFSceneryController { + fun updateBreakable (potPipeBroken: Boolean, pumpPipeBroken: Boolean, beltBroken: Boolean, cogBroken: Boolean) { + val beltObj = getScenery(beltGearRight)!! + val gearObj = getScenery(cogRightLoc)!! + val potPipe = getScenery(potPipeLoc)!! + val pumpPipe = getScenery(pumpPipeLoc)!! + + if (potPipeBroken && potPipe.id != BROKEN_POT_PIPE) + replaceScenery(potPipe, BROKEN_POT_PIPE, -1) + else if (!potPipeBroken && potPipe.id == BROKEN_POT_PIPE) + replaceScenery(potPipe, DEFAULT_POT_PIPE, -1) + + if (pumpPipeBroken && pumpPipe.id != BROKEN_PUMP_PIPE) + replaceScenery(pumpPipe, BROKEN_PUMP_PIPE, -1) + else if (!pumpPipeBroken && pumpPipe.id == BROKEN_PUMP_PIPE) + replaceScenery(pumpPipe, DEFAULT_PUMP_PIPE, -1) + + if (beltBroken && beltObj.id != BROKEN_BELT) + replaceScenery(beltObj, BROKEN_BELT, -1) + else if (!beltBroken && beltObj.id == BROKEN_BELT) + replaceScenery(beltObj, DEFAULT_BELT, -1) + + if (cogBroken && gearObj.id != BROKEN_COG) + replaceScenery(gearObj, BROKEN_COG, -1) + else if (!cogBroken && gearObj.id == BROKEN_COG) + replaceScenery(gearObj, DEFAULT_COG, -1) + } + + fun updateAnimations (pedaling: Boolean, beltBroken: Boolean, cogBroken: Boolean) { + val belt1 = getScenery(belt1Loc)!! + val belt2 = getScenery(belt2Loc)!! + val belt3 = getScenery(belt3Loc)!! + val beltGearLeft = getScenery(beltGearLeft)!! + val beltGearRight = getScenery(beltGearRight)!! + val cogLeft = getScenery(cogLeftLoc)!! + val cogRight = getScenery(cogRightLoc)!! + val cogCenter = getScenery(centralGearLoc)!! + + val beltAnim = if (pedaling && !beltBroken && !cogBroken) BELT_ANIM else -1 + val gearAnim = if (pedaling && !beltBroken && !cogBroken) GEAR_ANIM else -1 + + animateScenery(belt1, beltAnim) + animateScenery(belt2, beltAnim) + animateScenery(belt3, beltAnim) + animateScenery(beltGearLeft, gearAnim) + animateScenery(beltGearRight, gearAnim) + animateScenery(cogLeft, gearAnim) + animateScenery(cogRight, gearAnim) + animateScenery(cogCenter, gearAnim) + } + + fun updateStove (temp: Int) { + val stoveObj = getScenery(stoveLoc)!! + + if (temp >= 67 && stoveObj.id != STOVE_HOT) + replaceScenery(stoveObj, STOVE_HOT, -1) + else if (temp in 34..66 && stoveObj.id != STOVE_WARM) + replaceScenery(stoveObj, STOVE_WARM, -1) + else if (temp in 0..33 && stoveObj.id != STOVE_COLD) + replaceScenery(stoveObj, STOVE_COLD, -1) + } + + fun resetAllScenery() { + val beltObj = getScenery(beltGearRight)!! + val gearObj = getScenery(cogRightLoc)!! + val potPipe = getScenery(potPipeLoc)!! + val pumpPipe = getScenery(pumpPipeLoc)!! + val stoveObj = getScenery(stoveLoc)!! + replaceScenery(gearObj, DEFAULT_COG, -1) + replaceScenery(beltObj, DEFAULT_BELT, -1) + replaceScenery(pumpPipe, DEFAULT_PUMP_PIPE, -1) + replaceScenery(potPipe, DEFAULT_POT_PIPE, -1) + replaceScenery(stoveObj, STOVE_COLD, -1) + } + + companion object { + val belt1Loc = Location(1943, 4967, 0) + val belt2Loc = Location(1943, 4966, 0) + val belt3Loc = Location(1943, 4965, 0) + var potPipeLoc = Location(1943, 4961, 0) + var pumpPipeLoc = Location(1947, 4961, 0) + var cogLeftLoc = Location(1945, 4965, 0) + var cogRightLoc = Location(1945, 4967, 0) + var beltGearLeft = Location(1944, 4965, 0) + var beltGearRight = Location(1944, 4967, 0) + var centralGearLoc = Location(1945, 4966, 0) + var stoveLoc = Location(1948, 4963, 0) + + val DEFAULT_BELT = 9102 + val BROKEN_BELT = 9103 + val DEFAULT_COG = 9104 + val BROKEN_COG = 9105 + val DEFAULT_POT_PIPE = 9116 + val BROKEN_POT_PIPE = 9117 + val DEFAULT_PUMP_PIPE = 9120 + val BROKEN_PUMP_PIPE = 9121 + val STOVE_COLD = 9085 + val STOVE_WARM = 9086 + val STOVE_HOT = 9087 + val BELT_ANIM = 2435 + val GEAR_ANIM = 2436 + } +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/blastfurnace/BFTempEntranceTimer.kt b/Server/src/main/content/minigame/blastfurnace/BFTempEntranceTimer.kt new file mode 100644 index 0000000..733c416 --- /dev/null +++ b/Server/src/main/content/minigame/blastfurnace/BFTempEntranceTimer.kt @@ -0,0 +1,19 @@ +package content.minigame.blastfurnace + +import core.api.resetAnimator +import core.api.teleport +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.system.timer.PersistTimer + +class BFTempEntranceTimer : PersistTimer(BlastConsts.FEE_ENTRANCE_DURATION, "bf-tempentrance") { + override fun run(entity: Entity): Boolean { + if (entity !is Player) return false + if (BlastFurnace.insideBorders(entity)) { + teleport(entity, BlastConsts.EXIT_LOC) + entity.pulseManager.clear() + resetAnimator(entity) + } + return false + } +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/blastfurnace/BlastConsts.kt b/Server/src/main/content/minigame/blastfurnace/BlastConsts.kt new file mode 100644 index 0000000..a2d0982 --- /dev/null +++ b/Server/src/main/content/minigame/blastfurnace/BlastConsts.kt @@ -0,0 +1,28 @@ +package content.minigame.blastfurnace + +import core.game.world.map.Location + +object BlastConsts { + val ENTRANCE_LOC = Location (1940, 4958, 0) + val EXIT_LOC = Location (2931, 10197, 0) + val STAIRLOC_ENTRANCE = Location (2930, 10196) + val STAIRLOC_EXIT = Location (1939, 4956) + val STAIR_ENTRANCE_ID = 9084 + val STAIR_EXIT_ID = 9138 + val BELT = 9100 + val PEDALS = 9097 + val STOVE = intArrayOf(BFSceneryController.STOVE_COLD, BFSceneryController.STOVE_WARM, BFSceneryController.STOVE_HOT) + val PUMP = 9090 + val COKE = 9088 + val TEMP_GAUGE = 9089 + val SINK = 9143 + val DISPENSER = intArrayOf(9093, 9094, 9095, 9096) + + val SMITH_REQ = 60 + val ENTRANCE_FEE = 2500 + val FEE_ENTRANCE_DURATION = 1000 + val COAL_LIMIT = 226 + val ORE_LIMIT = 28 + val BAR_LIMIT = 28 + val COKE_LIMIT = 15 +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/blastfurnace/BlastFurnace.kt b/Server/src/main/content/minigame/blastfurnace/BlastFurnace.kt new file mode 100644 index 0000000..5bbdede --- /dev/null +++ b/Server/src/main/content/minigame/blastfurnace/BlastFurnace.kt @@ -0,0 +1,260 @@ +package content.minigame.blastfurnace + +import content.global.skill.smithing.smelting.Bar +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.world.map.zone.ZoneBorders +import core.tools.RandomFunction +import org.json.simple.JSONObject +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import kotlin.math.max + +class BlastFurnace : MapArea, PersistPlayer, TickListener { + override fun defineAreaBorders(): Array { + return arrayOf(bfArea) + } + + override fun savePlayer(player: Player, save: JSONObject) { + val state = playerStates[player.details.uid] + if (state != null) { + save["bf-state"] = state.toJson() + } + } + + override fun parsePlayer(player: Player, data: JSONObject) { + playerStates.remove(player.details.uid) + if (data.containsKey("bf-state")) { + val stateObj = data["bf-state"] as JSONObject + getPlayerState(player).readJson(stateObj) + } + } + + override fun areaEnter(entity: Entity) { + if (entity is Player) { + playersInArea.add(entity) + val state = getPlayerState(entity) + for (ore in state.oresOnBelt) + ore.createNpc() + } + } + + override fun areaLeave(entity: Entity, logout: Boolean) { + if (entity is Player) { + playersInArea.remove(entity) + val state = getPlayerState(entity) + for (ore in state.oresOnBelt) { + ore.npcInstance?.clear() + ore.npcInstance = null + } + } + } + + override fun tick() { + if (state.beltBroken || state.cogBroken) pedaler = null + if (state.potPipeBroken || state.pumpPipeBroken) pumper = null + state.tick(pumper != null, pedaler != null) + + if (playersInArea.size > 0) { + updateVisuals() + if (getWorldTicks() % 2 == 0) { + updatePedaler() + updatePumper() + } + processBars() + } + + //Reset each tick + pumper = null + pedaler = null + } + + private fun updatePumper() { + if (pumper != null) { + if (state.stoveTemp == 0) return + if (state.furnaceTemp == 100 && RandomFunction.roll(5)) { + impact(pumper!!, (0.2 * pumper!!.skills.maximumLifepoints).toInt()) + sendMessage(pumper!!, "A blast of hot air cooks you a bit.") + pumper!!.pulseManager.clear() + return + } + rewardXP(pumper!!, Skills.STRENGTH, 4.0) + } + } + + private fun updatePedaler() { + if (pedaler == null) return + var oresPedaled = false + for (state in playerStates.values) { + if (state.oresOnBelt.isEmpty()) continue + state.updateOres() + oresPedaled = true + } + if (oresPedaled) { + rewardXP(pedaler!!, Skills.AGILITY, 2.0) + pedaler!!.settings.runEnergy -= 2 + } + } + + private fun updateVisuals() { + sceneryController.updateStove(state.stoveTemp) + sceneryController.updateBreakable( + state.potPipeBroken, + state.pumpPipeBroken, + state.beltBroken, + state.cogBroken + ) + sceneryController.updateAnimations(pedaler != null, state.beltBroken, state.cogBroken) + } + + private fun processBars() { + if (state.furnaceTemp !in 51..66) return + var totalProcessed = 0 + for (player in playersInArea) { + if (getPlayerState(player).processOresIntoBars()) + totalProcessed++ + } + if (totalProcessed == 0) return + for (player in playersInArea) + rewardXP(player, Skills.SMITHING, totalProcessed.toDouble()) + } + + companion object { + val bfArea = ZoneBorders (1934, 4955, 1958, 4975) + val playersInArea = ArrayList() + val playerStates = HashMap() + val state = BlastState() + val sceneryController = BFSceneryController() + var pedaler: Player? = null + var pumper: Player? = null + + + fun insideBorders (player: Player) : Boolean { + return bfArea.insideBorder(player.location) + } + + fun placeAllOre (p: Player, id: Int = -1, accountForSkill: Boolean = false) { + val oreCounts = HashMap() + val oreContainer = getOreContainer(p) + val level = if (accountForSkill) getStatLevel(p, Skills.SMITHING) else 99 + + for (item in p.inventory.toArray()) { + if (item == null) continue + if (getNpcForOre(item.id) == -1) continue + if (id != -1 && item.id != id) continue + + val bar = getBarForOreId(item.id, oreContainer.coalAmount(), level)!! + if (bar.level > level) continue + + oreCounts[item.id] = (oreCounts[item.id] ?: 0) + item.amount + } + + for ((oreId, amount) in oreCounts) { + var maxAmt = oreContainer.getAvailableSpace(oreId, level) + + if (oreId == Items.COPPER_ORE_436 || oreId == Items.TIN_ORE_438) + maxAmt += (BlastConsts.ORE_LIMIT - getAmountOnBelt(p, oreId)) + + if (oreId == Items.COAL_453) + maxAmt -= getAmountOnBelt(p, oreId) + else + maxAmt -= getTotalOreOnBelt(p) + + maxAmt = maxAmt.coerceAtMost(amount).coerceAtLeast(0) + if (maxAmt == 0) continue + + if (removeItem(p, Item(oreId, maxAmt))) + addOreToBelt(p, oreId, maxAmt) + } + } + + fun getPlayerState (p: Player) : BFPlayerState { + if (playerStates[p.details.uid] != null) + return playerStates[p.details.uid]!! + val state = BFPlayerState(p) + playerStates[p.details.uid] = state + return state + } + + fun getOreContainer (p: Player) : BFOreContainer { + return getPlayerState(p).container + } + + fun addOreToBelt (p: Player, id: Int, amount: Int) : BFBeltOre { + val beltOre = BFBeltOre(p, id, amount, BFBeltOre.ORE_START_LOC) + beltOre.createNpc() + getPlayerState(p).oresOnBelt.add(beltOre) + return beltOre + } + + fun getAmountOnBelt (p: Player, id: Int) : Int { + var total = 0 + for (ore in getPlayerState(p).oresOnBelt) { + if (ore.id == id) + total += ore.amount + } + return total + } + + fun getTotalOreOnBelt (p: Player) : Int { + var total = 0 + for (ore in getPlayerState(p).oresOnBelt) + if (ore.id != Items.COAL_453) total += ore.amount + return total + } + + fun getNeededCoal (bar: Bar) : Int { + var coalAmount = 0 + + if (bar.ores.size == 1) + return coalAmount + + for (ore in bar.ores) { + if (ore.id == Items.COAL_453) { + coalAmount = ore.amount + break + } + } + if (coalAmount > 1) coalAmount /= 2 + return coalAmount + } + + + fun getBarForOreId (id: Int, coalAmount: Int, level: Int) : Bar? { + return when (id) { + Items.COPPER_ORE_436, Items.TIN_ORE_438 -> Bar.BRONZE + Items.IRON_ORE_440 -> if (coalAmount >= 1 && level >= Bar.STEEL.level) Bar.STEEL else Bar.IRON + else -> Bar.forOre(id) + } + } + + fun getNpcForOre (id: Int) : Int { + return when (id) { + Items.IRON_ORE_440 -> NPCs.IRON_ORE_2556 + Items.COPPER_ORE_436 -> NPCs.COPPER_ORE_2555 + Items.TIN_ORE_438 -> NPCs.TIN_ORE_2554 + Items.COAL_453 -> NPCs.COAL_2562 + Items.MITHRIL_ORE_447 -> NPCs.MITHRIL_ORE_2557 + Items.ADAMANTITE_ORE_449 -> NPCs.ADAMANTITE_ORE_2558 + Items.SILVER_ORE_442 -> NPCs.SILVER_ORE_2560 + Items.GOLD_ORE_444 -> NPCs.GOLD_ORE_2561 + Items.RUNITE_ORE_451 -> NPCs.RUNITE_ORE_2559 + else -> -1 + } + } + + fun getEntranceFee (hasCharos: Boolean, smithLevel: Int) : Int { + if (smithLevel >= BlastConsts.SMITH_REQ) return 0 + return if (hasCharos) BlastConsts.ENTRANCE_FEE / 2 else BlastConsts.ENTRANCE_FEE + } + + fun enter (player: Player, feePaid: Boolean) { + if (feePaid && !hasTimerActive(player)) + registerTimer(player, BFTempEntranceTimer()) + teleport(player, BlastConsts.ENTRANCE_LOC) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/blastfurnace/BlastFurnaceInterfaceListener.kt b/Server/src/main/content/minigame/blastfurnace/BlastFurnaceInterfaceListener.kt new file mode 100644 index 0000000..61986f2 --- /dev/null +++ b/Server/src/main/content/minigame/blastfurnace/BlastFurnaceInterfaceListener.kt @@ -0,0 +1,51 @@ +package content.minigame.blastfurnace + +import content.global.skill.smithing.smelting.Bar +import core.api.* +import core.game.interaction.InterfaceListener +import core.game.system.task.Pulse +import org.rs09.consts.Components + +class BlastFurnaceInterfaceListener : InterfaceListener { + override fun defineInterfaceListeners() { + onOpen(Components.BLAST_FURNACE_BAR_STOCK_28) { player, component -> + val state = BlastFurnace.getPlayerState(player) + state.setBarClaimVarbits() + state.checkBars() + return@onOpen true + } + + onOpen(Components.BLAST_FURNACE_TEMP_GAUGE_30) {player, _ -> + submitIndividualPulse(player, object : Pulse() { + override fun pulse(): Boolean { + val anim = BlastFurnace.state.furnaceTemp + 2452 + animateInterface(player, 30, 4, anim) + return false + } + }) + return@onOpen true + } + onClose(Components.BLAST_FURNACE_TEMP_GAUGE_30) {player, _ -> player.pulseManager.clear(); return@onClose true } + + on(Components.BLAST_FURNACE_BAR_STOCK_28){ player, _, _, buttonID, _, _ -> + val (isAll, bar) = getBarForButton(buttonID) + val state = BlastFurnace.getPlayerState(player) + state.claimBars(bar, if (isAll) state.container.getBarAmount(bar) else 1) + return@on true + } + } + + private fun getBarForButton (id: Int) : Pair { + return when (id) { + 43,44 -> Pair(id == 44, Bar.BRONZE) + 40,41 -> Pair(id == 41, Bar.IRON) + 36,38 -> Pair(id == 38, Bar.STEEL) + 33,35 -> Pair(id == 35, Bar.MITHRIL) + 30,32 -> Pair(id == 32, Bar.ADAMANT) + 27,29 -> Pair(id == 29, Bar.RUNITE) + 24,26 -> Pair(id == 26, Bar.SILVER) + 21,23 -> Pair(id == 23, Bar.GOLD) + else -> Pair(false, Bar.BRONZE) + } + } +} diff --git a/Server/src/main/content/minigame/blastfurnace/BlastFurnaceListeners.kt b/Server/src/main/content/minigame/blastfurnace/BlastFurnaceListeners.kt new file mode 100644 index 0000000..deaaae1 --- /dev/null +++ b/Server/src/main/content/minigame/blastfurnace/BlastFurnaceListeners.kt @@ -0,0 +1,315 @@ +package content.minigame.blastfurnace + +import content.region.misc.keldagrim.handlers.BlastFurnaceDoorDialogue +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.Topic +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.skill.Skills +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.tools.END_DIALOGUE +import org.rs09.consts.Items + + +class BlastFurnaceListeners : InteractionListener { + companion object { + var initialized = false + val PUMP_LOC = Location.create(1950, 4961, 0) + val PUMP_FACELOC = Location.create(1949, 4961, 0) + val PEDAL_LOC = Location.create(1947, 4966, 0) + val PEDAL_DISMOUNT = Location.create(1947, 4967, 0) + val PEDAL_FACELOC = Location.create(1946, 4966, 0) + val PUMP_ANIM = 2432 + val PEDAL_ANIM = 2433 + val PEDAL_SCENERY = getScenery(PEDAL_LOC)!! + val PUMP_SCENERY = getScenery(PUMP_LOC)!! + val validOreIds = intArrayOf( + Items.IRON_ORE_440, + Items.COPPER_ORE_436, + Items.TIN_ORE_438, + Items.COAL_453, + Items.MITHRIL_ORE_447, + Items.ADAMANTITE_ORE_449, + Items.SILVER_ORE_442, + Items.GOLD_ORE_444, + Items.RUNITE_ORE_451 + ) + } + + override fun defineListeners() { + if (initialized) return + initialized = true + + on (BlastConsts.STAIR_ENTRANCE_ID, IntType.SCENERY, "climb-down") { p, _ -> + val hasCharos = inEquipment(p, Items.RING_OF_CHAROS_4202) || inEquipment(p, Items.RING_OF_CHAROSA_6465) + val fee = BlastFurnace.getEntranceFee(hasCharos, getStatLevel(p, Skills.SMITHING)) + if (fee > 0 && !hasTimerActive(p)) { + openDialogue(p, BlastFurnaceDoorDialogue(fee)) + return@on true + } + BlastFurnace.enter(p, false) + return@on true + } + + on (BlastConsts.STAIR_EXIT_ID, IntType.SCENERY, "climb-up") { p, _ -> + teleport(p, BlastConsts.EXIT_LOC) + return@on true + } + + on (BlastConsts.PUMP, IntType.SCENERY, "operate") { p, _ -> + if (getDynLevel(p, Skills.STRENGTH) >= 30 && BlastFurnace.pumper == null) { + forceMove(p, p.location, PUMP_LOC, 0, 30) { + animate(p, PUMP_ANIM) + removeScenery(PUMP_SCENERY) + submitIndividualPulse(p, object : Pulse() { + override fun pulse(): Boolean { + face(p, PUMP_FACELOC) + animate(p, PUMP_ANIM) + BlastFurnace.pumper = p + return false + } + + override fun stop() { + resetAnimator(p) + BlastFurnace.pumper = null + addScenery(PUMP_SCENERY) + super.stop() + } + }) + } + } + else if (BlastFurnace.pumper != null) + sendMessage(p, "Someone else is already doing that.") + else + sendMessage(p, "You need a Strength level of 30 to do that.") + return@on true + } + setDest(IntType.SCENERY, BlastConsts.PUMP) { _, _ -> Location.create(1951, 4961, 0) } + + on (BlastConsts.PEDALS, IntType.SCENERY, "pedal") { p, n -> + if (getDynLevel(p, Skills.AGILITY) > 30 && BlastFurnace.pedaler == null) { + forceMove(p, p.location, PEDAL_LOC, 0, 30) { + animate(p, PEDAL_ANIM) + removeScenery(PEDAL_SCENERY) + submitIndividualPulse(p, object : Pulse() { + override fun pulse(): Boolean { + if (p.settings.runEnergy < 1.0) { + teleport(p, PEDAL_DISMOUNT) + return true + } + face(p, PEDAL_FACELOC) + animate(p, PEDAL_ANIM) + BlastFurnace.pedaler = p + return false + } + + override fun stop() { + resetAnimator(p) + BlastFurnace.pedaler = null + addScenery(PEDAL_SCENERY) + super.stop() + } + }) + } + } + else if (BlastFurnace.pedaler != null) + sendMessage(p, "Someone else is already doing that.") + else + sendMessage(p, "You need an Agility level of 30 to do that.") + return@on true + } + setDest(IntType.SCENERY, BlastConsts.PEDALS) { _, _ -> Location.create(1948, 4966, 0) } + + on (BlastConsts.COKE, SCENERY, "collect") { player, _ -> + if (inInventory(player, Items.SPADE_952, 1)) { + if(removeItem(player, Items.SPADE_952, Container.INVENTORY) && addItem(player, Items.SPADEFUL_OF_COKE_6448, 1)) { + lockInteractions(player,1) + animate(player, 2441) + } + } else { + sendMessage(player, "You need a spade to do this!") + } + return@on true + } + + on (Items.SPADEFUL_OF_COKE_6448, ITEM, "empty") {p, n -> + if (removeItem(p, n)) addItem(p, Items.SPADE_952) + return@on true + } + + on (BlastConsts.STOVE, SCENERY, "refuel") { player, _ -> + if (inInventory(player, Items.SPADEFUL_OF_COKE_6448, 1)) { + if (BlastFurnace.state.cokeInStove >= BlastConsts.COKE_LIMIT) { + sendMessage(player, "The stove is already full of coke!") + return@on true + } + if (getDynLevel(player, Skills.FIREMAKING) < 30) { + sendMessage(player, "You need a Firemaking level of 30 to do this.") + return@on true + } + animate(player, 2442) + lock(player,2) + submitIndividualPulse(player, object : Pulse() { + override fun pulse(): Boolean { + return if(removeItem(player, Items.SPADEFUL_OF_COKE_6448, Container.INVENTORY) && addItem(player, Items.SPADE_952, 1)) { + animate(player, 2443) + rewardXP(player, Skills.FIREMAKING, 5.0) + BlastFurnace.state.addCoke(1) + true + } else { + false + } + } + }) + } else { + sendMessage(player,"You need some coke to do that!") + } + return@on true + } + + on (BlastConsts.BELT, IntType.SCENERY, "put-ore-on") { p, _ -> + openDialogue(p, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> sendDialogue(p, "Really place all your ore on the belt?").also { stage++ } + 1 -> showTopics( + Topic("Yes.", 100, true), + Topic("Nevermind.", END_DIALOGUE, true) + ) + 100 -> { + end() + BlastFurnace.placeAllOre(p, accountForSkill = true) + } + } + } + }) + return@on true + } + + onUseWith (IntType.SCENERY, validOreIds, BlastConsts.BELT) { p, used, _ -> + BlastFurnace.placeAllOre(p, used.id, accountForSkill = true) + return@onUseWith true + } + + on(BlastConsts.TEMP_GAUGE, IntType.SCENERY, "read") { p, _ -> + openInterface(p, 30) + return@on true + } + + on(BlastConsts.DISPENSER, IntType.SCENERY, "search", "take") { p, _ -> + openInterface(p, 28) + return@on true + } + + onUseWith(SCENERY, Items.BUCKET_OF_WATER_1929, *BlastConsts.DISPENSER){ p, _, _ -> + when (getVarbit(p, BFPlayerState.DISPENSER_STATE)) { + 1,2 -> { + var barsCooled = false + for (player in BlastFurnace.playersInArea) { + val state = BlastFurnace.getPlayerState(player) + if (state.barsNeedCooled) { + state.coolBars() + barsCooled = true + } + } + if (barsCooled) { + removeItem(p, Items.BUCKET_OF_WATER_1929, Container.INVENTORY) + addItem(p, Items.BUCKET_1925) + } + } + 0 -> sendDialogue(p,"There's nothing to cool off!") + 3 -> sendDialogue(p,"These bars have already cooled off!") + } + return@onUseWith true + } + + on(BFSceneryController.BROKEN_POT_PIPE, SCENERY, "repair"){ player, _ -> + if(player.getSkills().getLevel(Skills.CRAFTING) >= 30){ + if (!BlastFurnace.state.potPipeBroken) { + sendMessage(player, "You can't fix something that isn't broken.") + return@on true + } + if(inInventory(player,Items.HAMMER_2347,1)) { + rewardXP(player, Skills.CRAFTING, 50.0) + BlastFurnace.state.potPipeBroken = false + } else { + sendMessage(player, "I need a hammer to do this!") + } + } else { + sendDialogue(player,"I need 30 Crafting in order to do this") + } + return@on true + } + + on(BFSceneryController.BROKEN_PUMP_PIPE, SCENERY, "repair"){ player, _ -> + if(player.getSkills().getLevel(Skills.CRAFTING) >= 30){ + if (!BlastFurnace.state.pumpPipeBroken) { + sendMessage(player, "You can't fix something that isn't broken.") + return@on true + } + if(inInventory(player,Items.HAMMER_2347,1)) { + rewardXP(player, Skills.CRAFTING, 50.0) + BlastFurnace.state.pumpPipeBroken = false + } else { + sendMessage(player, "I need a hammer to do this!") + } + } else { + sendDialogue(player,"I need 30 Crafting in order to do this") + } + return@on true + } + + on(BFSceneryController.BROKEN_BELT, SCENERY, "repair"){ player, _ -> + if(player.getSkills().getLevel(Skills.CRAFTING) >= 30){ + if (!BlastFurnace.state.beltBroken) { + sendMessage(player, "You can't fix something that isn't broken.") + return@on true + } + if(inInventory(player,Items.HAMMER_2347,1)) { + rewardXP(player, Skills.CRAFTING, 50.0) + BlastFurnace.state.beltBroken = false + } else { + sendMessage(player, "I need a hammer to do this!") + } + } else { + sendDialogue(player,"I need 30 Crafting in order to do this") + } + return@on true + } + + on(BFSceneryController.BROKEN_COG, SCENERY, "repair"){ player, _ -> + if(player.getSkills().getLevel(Skills.CRAFTING) >= 30){ + if (!BlastFurnace.state.cogBroken) { + sendMessage(player, "You can't fix something that isn't broken.") + return@on true + } + if(inInventory(player,Items.HAMMER_2347,1)) { + rewardXP(player, Skills.CRAFTING, 50.0) + BlastFurnace.state.cogBroken = false + } else { + sendMessage(player, "I need a hammer to do this!") + } + } else { + sendDialogue(player,"I need 30 Craft in order to do this") + } + return@on true + } + + on(BlastConsts.SINK, SCENERY,"fill-bucket"){ player, _ -> + player.pulseManager.run(object : Pulse(1){ + override fun pulse(): Boolean { + if(removeItem(player, Items.BUCKET_1925)) + { + animate(player, 832) + sendMessage(player, "You fill the bucket from the sink.") + addItemOrDrop(player, Items.BUCKET_OF_WATER_1929) + } + return true + } + }) + return@on true + } + } +} diff --git a/Server/src/main/content/minigame/blastfurnace/BlastState.kt b/Server/src/main/content/minigame/blastfurnace/BlastState.kt new file mode 100644 index 0000000..07dafe3 --- /dev/null +++ b/Server/src/main/content/minigame/blastfurnace/BlastState.kt @@ -0,0 +1,76 @@ +package content.minigame.blastfurnace + +import core.tools.RandomFunction + +class BlastState { + var disableBreaking = false + var forceBreaking = false + var potPipeBroken = false + var pumpPipeBroken = false + var beltBroken = false + var cogBroken = false + var ticksElapsed = 0 + + var stoveTemp = 0 + private set + var furnaceTemp = 0 + private set + var cokeInStove = 0 + private set + + fun tick(pumping: Boolean, pedaling: Boolean) { + ticksElapsed++ + + adjustStoveTemperature() + adjustFurnaceTemperature(pumping) + + checkForCokeDecrement() + checkForBreakage(pedaling, pumping) + } + + private fun adjustStoveTemperature() { + if (cokeInStove > 0) + stoveTemp = (stoveTemp + 1).coerceAtMost(100) + else stoveTemp = (stoveTemp - 1).coerceAtLeast(0) + } + + private fun adjustFurnaceTemperature(pumping: Boolean) { + if (pumping && !pumpPipeBroken && !potPipeBroken && !beltBroken && !cogBroken) { + when (stoveTemp) { + in 1..32 -> furnaceTemp += 1 + in 32..66 -> furnaceTemp += 2 + in 67..100 -> furnaceTemp += 3 + } + } else furnaceTemp-- + + furnaceTemp = furnaceTemp + .coerceAtLeast(0) + .coerceAtMost(100) + } + + private fun checkForBreakage(pedaling: Boolean, pumping: Boolean) { + if (disableBreaking) return + if (pumping && (!potPipeBroken || !pumpPipeBroken)) { + if (RandomFunction.roll(50) || forceBreaking) { + if (RandomFunction.nextBool()) potPipeBroken = true + else pumpPipeBroken = true + } + } + + if (pedaling && (!beltBroken || !cogBroken)) { + if (RandomFunction.roll(50) || forceBreaking) + beltBroken = true + else if (RandomFunction.roll(50) || forceBreaking) + cogBroken = true + } + } + + private fun checkForCokeDecrement() { + if (ticksElapsed % 10 == 0) + cokeInStove = (cokeInStove - 1).coerceAtLeast(0) + } + + fun addCoke (amount: Int) { + cokeInStove += amount.coerceAtMost(BlastConsts.COKE_LIMIT - cokeInStove) + } +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/bountyhunter/BHOptionHandler.java b/Server/src/main/content/minigame/bountyhunter/BHOptionHandler.java new file mode 100644 index 0000000..4af321f --- /dev/null +++ b/Server/src/main/content/minigame/bountyhunter/BHOptionHandler.java @@ -0,0 +1,80 @@ +package content.minigame.bountyhunter; + +import core.cache.def.impl.SceneryDefinition; +import core.game.activity.ActivityManager; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; + +/** + * Handles the bounty hunter options. + * @author Emperor + */ +public final class BHOptionHandler extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(28110).getHandlers().put("option:exit", this); + SceneryDefinition.forId(28119).getHandlers().put("option:enter", this); + SceneryDefinition.forId(28120).getHandlers().put("option:enter", this); + SceneryDefinition.forId(28121).getHandlers().put("option:enter", this); + SceneryDefinition.forId(28122).getHandlers().put("option:exit", this); + SceneryDefinition.forId(28115).getHandlers().put("option:view", this); + SceneryDefinition.forId(28116).getHandlers().put("option:view", this); + return this; + } + + @Override + public boolean handle(final Player player, Node node, String option) { + Scenery object = (Scenery) node; + final BountyHunterActivity activity = player.getExtension(BountyHunterActivity.class); + switch (object.getId()) { + case 28119: + ActivityManager.start(player, "BH low_level", false); + return true; + case 28120: + ActivityManager.start(player, "BH mid_level", false); + return true; + case 28121: + ActivityManager.start(player, "BH high_level", false); + return true; + case 28115: + BHScoreBoard.getRogues().open(player); + return true; + case 28116: + BHScoreBoard.getHunters().open(player); + return true; + case 28122: + if (activity == null) { + return false; + } + if (player.getAttribute("exit_penalty", 0) > GameWorld.getTicks()) { + player.getPacketDispatch().sendMessage("You can't leave the crater until the exit penalty is over."); + return true; + } + player.lock(2); + GameWorld.getPulser().submit(new Pulse(1) { + @Override + public boolean pulse() { + player.getProperties().setTeleportLocation(activity.getType().getExitLocation()); + return true; + } + }); + player.animate(Animation.create(7376)); + return true; + case 28110: + if (activity == null) { + return false; + } + activity.leaveWaitingRoom(player, false); + return true; + } + return false; + } + +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/bountyhunter/BHScoreBoard.java b/Server/src/main/content/minigame/bountyhunter/BHScoreBoard.java new file mode 100644 index 0000000..c57c3ef --- /dev/null +++ b/Server/src/main/content/minigame/bountyhunter/BHScoreBoard.java @@ -0,0 +1,158 @@ +package content.minigame.bountyhunter; + +import java.nio.ByteBuffer; + +import core.cache.misc.buffer.ByteBufferUtils; +import core.game.component.Component; +import core.game.node.entity.player.Player; +import core.tools.StringUtils; + +/** + * The score board. + * @author Emperor + */ +public final class BHScoreBoard { + + /** + * The score board size. + */ + private static final int SIZE = 10; + + /** + * The names. + */ + private String[] names = new String[SIZE]; + + /** + * The scores. + */ + private int[] scores = new int[SIZE]; + + /** + * The bounty hunters scoreboard. + */ + private static final BHScoreBoard HUNTERS = new BHScoreBoard(); + + /** + * The bounty hunter rogues scoreboard. + */ + private static final BHScoreBoard ROGUES = new BHScoreBoard(); + + /** + * Constructs a new {@code BHScoreBoard} {@code Object}. + */ + public BHScoreBoard() { + for (int i = 0; i < SIZE; i++) { + names[i] = "Nobody yet"; + } + } + + /** + * Initializes the score boards data. + */ + public static void init() { +/* if (true) { // Indicates no cache exists yet. + return; + } + ByteBuffer buffer = file.data(); + for (int i = 0; i < SIZE; i++) { + HUNTERS.scores[i] = buffer.getInt(); + HUNTERS.names[i] = ByteBufferUtils.getString(buffer); + } + for (int i = 0; i < SIZE; i++) { + ROGUES.scores[i] = buffer.getInt(); + ROGUES.names[i] = ByteBufferUtils.getString(buffer); + }*/ + } + + /** + * Updates the store file for the scores. + */ + public static void update() { + ByteBuffer buffer = ByteBuffer.allocate(500); + for (int i = 0; i < SIZE; i++) { + buffer.putInt(HUNTERS.scores[i]); + ByteBufferUtils.putString(HUNTERS.names[i], buffer); + } + for (int i = 0; i < SIZE; i++) { + buffer.putInt(ROGUES.scores[i]); + ByteBufferUtils.putString(ROGUES.names[i], buffer); + } + buffer.flip(); + //AriosStore.setArchive("bh_scores", buffer); + } + + /** + * Opens the score board. + * @param player The player. + */ + public void open(Player player) { + int component = 654; + if (this == ROGUES) { + component = 655; + } + player.getInterfaceManager().open(new Component(component)); + for (int i = 0; i < SIZE; i++) { + player.getPacketDispatch().sendString(StringUtils.formatDisplayName(names[i]), component, 15 + i); + player.getPacketDispatch().sendString(Integer.toString(scores[i]), component, 25 + i); + } + } + + /** + * Checks if the ratings of the player is good enough for the score board. + * @param player The player. + */ + public void check(Player player) { + int score = player.getSavedData().getActivityData().getBountyHunterRate(); + if (this == ROGUES) { + score = player.getSavedData().getActivityData().getBountyRogueRate(); + } + for (int i = 0; i < SIZE; i++) { + if (score > scores[i]) { + insert(player, score, i); + update(); + break; + } + } + } + + /** + * Inserts the player in the score board. + * @param player The player. + * @param score The score. + * @param index The board index. + */ + private void insert(Player player, int score, int index) { + if (names[index].equals(player.getName())) { + scores[index] = score; + return; + } + for (int i = SIZE - 2; i >= index; i--) { + String name = names[i]; + if (name.equals(player.getName())) { + name = names[--i]; + } + scores[i + 1] = scores[i]; + names[i + 1] = name; + } + names[index] = player.getName(); + scores[index] = score; + } + + /** + * Gets the rogues. + * @return The rogues. + */ + public static BHScoreBoard getRogues() { + return ROGUES; + } + + /** + * Gets the hunters. + * @return The hunters. + */ + public static BHScoreBoard getHunters() { + return HUNTERS; + } + +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/bountyhunter/BountyEntry.java b/Server/src/main/content/minigame/bountyhunter/BountyEntry.java new file mode 100644 index 0000000..d7021ab --- /dev/null +++ b/Server/src/main/content/minigame/bountyhunter/BountyEntry.java @@ -0,0 +1,105 @@ +package content.minigame.bountyhunter; + +import core.game.node.entity.player.Player; +import core.game.world.GameWorld; + +/** + * Holds a player's bounty hunter data. + * @author Emperor + */ +public final class BountyEntry { + + /** + * The target. + */ + private Player target; + + /** + * The player hunting this player. + */ + private Player hunter; + + /** + * Constructs a new {@code BountyEntry} {@code Object}. + */ + public BountyEntry() { + /* + * empty. + */ + } + + /** + * Updates the overlay. + * @param player The player. + */ + public void update(Player player) { + String name = "No one"; + if (target != null) { + name = target.getUsername(); + } + player.getPacketDispatch().sendString(name, 653, 7); + updatePenalty(player, false); + } + + /** + * Updates the current penalty. + * @param player The player. + * @param unlock If the components should be unlocked. + */ + public void updatePenalty(Player player, boolean unlock) { + int penalty = player.getAttribute("pickup_penalty", 0); + int child = -1; + if (GameWorld.getTicks() > penalty) { + player.removeAttribute("pickup_penalty"); + player.getPacketDispatch().sendInterfaceConfig(653, 8, true); + } else if (penalty != 0) { + child = 8; + int seconds = (int) Math.round((penalty - GameWorld.getTicks()) * 0.6); + player.getPacketDispatch().sendString(seconds + " Sec", 653, 10); + } + penalty = player.getAttribute("exit_penalty", 0); + if (GameWorld.getTicks() > penalty) { + player.removeAttribute("exit_penalty"); + player.getPacketDispatch().sendInterfaceConfig(653, 11, true); + } else if (penalty != 0) { + child = 11; + int seconds = (int) Math.round((penalty - GameWorld.getTicks()) * 0.6); + player.getPacketDispatch().sendString(seconds + " Sec", 653, 13); + } + if (unlock && child > -1) { + player.getPacketDispatch().sendInterfaceConfig(653, child, false); + } + } + + /** + * Gets the target. + * @return The target. + */ + public Player getTarget() { + return target; + } + + /** + * Sets the target. + * @param target The target to set. + */ + public void setTarget(Player target) { + this.target = target; + } + + /** + * Gets the hunter. + * @return The hunter. + */ + public Player getHunter() { + return hunter; + } + + /** + * Sets the hunter. + * @param hunter The hunter to set. + */ + public void setHunter(Player hunter) { + this.hunter = hunter; + } +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/bountyhunter/BountyHunterActivity.java b/Server/src/main/content/minigame/bountyhunter/BountyHunterActivity.java new file mode 100644 index 0000000..08b6c59 --- /dev/null +++ b/Server/src/main/content/minigame/bountyhunter/BountyHunterActivity.java @@ -0,0 +1,642 @@ +package content.minigame.bountyhunter; + +import core.api.*; +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.container.Container; +import core.game.container.ContainerEvent; +import core.game.container.ContainerListener; +import core.game.activity.ActivityManager; +import core.game.activity.ActivityPlugin; +import core.game.interaction.Option; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.HintIconManager; +import core.game.node.entity.player.link.prayer.PrayerType; +import core.game.node.item.GroundItem; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.Point; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneRestriction; +import core.game.world.map.zone.impl.MultiwayCombatZone; +import core.game.world.map.zone.impl.WildernessZone; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.plugin.ClassScanner; +import core.tools.RandomFunction; + +import java.util.*; + +import static core.api.ContentAPIKt.*; + +/** + * Handles the Bounty hunter activity. + * @author Emperor + */ +@Initializable +public final class BountyHunterActivity extends ActivityPlugin { + + /** + * The skull values. + */ + private static final int[] SKULL_VALUES = { 100_000, // Bronze skull + 500_000, // Iron skull + 1_100_000, // Adamant skull + 2_500_000, // Runite skull + -1 // Dragon skull + }; + + /** + * The exit offsets. + */ + private static final Point[] EXIT_OFFSETS = { new Point(19, 58), new Point(24, 44), new Point(29, 34), new Point(36, 22), new Point(52, 17), new Point(14, 72), new Point(15, 85), new Point(17, 127), new Point(14, 133), new Point(19, 151), new Point(38, 163), new Point(49, 170), new Point(64, 20), new Point(84, 16), new Point(106, 18), new Point(69, 176), new Point(85, 176), new Point(127, 174), new Point(130, 21), new Point(138, 33), new Point(155, 48), new Point(163, 53), new Point(172, 60), new Point(174, 64), new Point(176, 106), new Point(178, 84), new Point(155, 169), new Point(162, 162), new Point(163, 153), new Point(173, 136) }; + + /** + * The minimum amount of players to enter the crater. + */ + private static final int MINIMUM_PLAYERS = 2; + + /** + * The waiting room overlay. + */ + private static final Component WAITING_OVERLAY = new Component(656); + + /** + * The game overlay. + */ + private static final Component GAME_OVERLAY = new Component(653); + + /** + * The player in the current crater. + */ + final Map players = new HashMap<>(); + + /** + * The waiting room. + */ + private final List waitingRoom = new ArrayList<>(20); + + /** + * The crater type. + */ + private final CraterType type; + + /** + * The amount of time to wait in the waiting room. + */ + private int waitingTime = 166; + + /** + * The waiting room pulse. + */ + private final Pulse waitRoomPulse = new Pulse(1) { + @Override + public boolean pulse() { + String time = Integer.toString((int) Math.round(waitingTime-- * 0.6)) + " Sec"; + for (Player player : waitingRoom) { + player.getPacketDispatch().sendString(time, 656, 10); + } + if (waitingTime == -1) { + for (Iterator it = waitingRoom.iterator(); it.hasNext();) { + enterCrater(it.next()); + it.remove(); + } + return true; + } + return false; + } + + @Override + public void stop() { + super.stop(); + waitingTime = 166; + } + }; + + /** + * The game pulse (doesn't update every tick on 2009Scape as well). + */ + private final Pulse gamePulse = new Pulse(10) { + @Override + public boolean pulse() { + for (Player player : players.keySet()) { + BountyEntry entry = players.get(player); + if (entry.getTarget() == null) { + findTarget(player); + } + entry.updatePenalty(player, false); + } + return false; + } + }; + + /** + * Constructs a new {@code BountyHunterActivity} {@code Object}. + */ + public BountyHunterActivity() { + this(CraterType.LOW_LEVEL); + } + + /** + * Constructs a new {@code BountyHunterActivity} {@code Object}. + */ + public BountyHunterActivity(CraterType type) { + super("BH " + type.name().toLowerCase(), false, false, false, ZoneRestriction.FOLLOWERS); + this.type = type; + } + + @Override + public void register() { + waitRoomPulse.stop(); + gamePulse.stop(); + if (getType() == CraterType.LOW_LEVEL) { + // Disable bounty hunter area as wilderness + Location check = Location.create(3166, 3679, 0); + for (ZoneBorders border : WildernessZone.getInstance().getBorders()) { + if (border.insideBorder(check)) { + /* if (GameWorld.getSettings().isPvp()) { + border.addException(new ZoneBorders(2924, 3306, 3078, 3404)); + }*/ + border.addException(new ZoneBorders(3140, 3653, 3149, 3670)); + border.addException(new ZoneBorders(3150, 3656, 3154, 3676)); + border.addException(new ZoneBorders(3155, 3661, 3164, 3686)); + border.addException(new ZoneBorders(3165, 3667, 3173, 3693)); + border.addException(new ZoneBorders(3174, 3673, 3192, 3705)); + border.addException(new ZoneBorders(3193, 3681, 3196, 3709)); + break; + } + } + ClassScanner.definePlugin(new ComponentPlugin() { + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.put(657, this); + return this; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + if (button == 18) { + player.getInterfaceManager().close(); + player.lock(1); + BountyHunterActivity activity = player.getExtension(BountyHunterActivity.class); + if (activity.players.isEmpty()) { + activity.joinWaitingRoom(player); + return true; + } + activity.enterCrater(player); + } + return true; + } + + }); + BHScoreBoard.init(); + ClassScanner.definePlugin(new BountyLocateSpell()); + ClassScanner.definePlugin(new BHOptionHandler()); + ActivityManager.register(new BountyHunterActivity(CraterType.MID_LEVEL)); + ActivityManager.register(new BountyHunterActivity(CraterType.HIGH_LEVEL)); + } + } + + @Override + public boolean start(Player player, boolean login, Object... args) { + if (player.getFamiliarManager().hasFamiliar()) { + player.getPacketDispatch().sendMessage("You can't bring a follower into the crater."); + return false; + } + if (!getType().canEnter(player)) { + return false; + } + player.addExtension(BountyHunterActivity.class, this); + if (!login) { + player.getInterfaceManager().open(new Component(657)); + } else { + enterCrater(player); + } + return true; + } + + @Override + public boolean enter(Entity e) { + if (e instanceof Player && getType().getZone().insideBorder(e.getLocation()) || e instanceof Player) { + if (e.getAttribute("viewing_orb") != null) { + return super.enter(e); + } + Player player = (Player) e; + for (int i = 0; i < type.ordinal(); i++) { + if (!player.getMusicPlayer().hasUnlockedIndex(517 + i)) { + player.getMusicPlayer().unlock(444 - i, false); + } + } + player.addExtension(BountyHunterActivity.class, this); + BountyEntry entry = new BountyEntry(); + players.put(player, entry); + player.getInterfaceManager().openOverlay(GAME_OVERLAY); + int penalty; + if ((penalty = player.getAttribute("pickup_penalty", 0)) != 0) { + player.setAttribute("/save:pickup_penalty", GameWorld.getTicks() + penalty); + } + if ((penalty = player.getAttribute("exit_penalty", 0)) != 0) { + player.setAttribute("/save:exit_penalty", GameWorld.getTicks() + penalty); + if (player.getPrayer().get(PrayerType.PROTECT_ITEMS)) { + player.getPrayer().toggle(PrayerType.PROTECT_ITEMS); + } + } + findTarget(player); + entry.updatePenalty(player, true); + player.getInteraction().set(Option._P_ATTACK); + player.getInteraction().remove(Option._P_ASSIST); + player.getSkullManager().setSkullCheckDisabled(true); + player.getSkullManager().setWilderness(true); + player.setAttribute("bh_joined", GameWorld.getTicks() + 10); + updateSkull(player); + if (!gamePulse.isRunning()) { + gamePulse.start(); + GameWorld.getPulser().submit(gamePulse); + } + } + return super.enter(e); + } + + @Override + public boolean leave(Entity e, boolean logout) { + if (e instanceof Player) { + Player player = (Player) e; + player.removeExtension(BountyHunterActivity.class); + if (waitingRoom.contains(player)) { + leaveWaitingRoom(player, logout); + } + BountyEntry entry = players.get(player); + if (entry != null) { + leaveCrater(player, logout, entry); + } + } + return super.leave(e, logout); + } + + @Override + public boolean interact(Entity e, Node target, Option option) { + if (target instanceof GroundItem && option.getName().equals("take")) { + return actionButton((Player) e, 192, 19, -1, -1, 55); + } + if (target instanceof Item && option.getName().equals("drop")) { + if (((Item) target).getValue() > 1000) { + ((Player) e).getPacketDispatch().sendMessage("This item is too valuable to drop in the crater."); + return true; + } + } + return false; + } + + @Override + public boolean ignoreMultiBoundaries(Entity attacker, Entity victim) { + if (attacker instanceof Player) { + BountyEntry entry = players.get(attacker); + return entry != null && entry.getTarget() == victim; + } + return false; + } + + @SuppressWarnings("deprecation") + @Override + public boolean actionButton(Player player, int interfaceId, int buttonId, int slot, int itemId, int opcode) { + if (interfaceId == 192 && buttonId == 19) { + BountyEntry entry = players.get(player); + if (entry != null && player.getAttribute("pickup_penalty", 0) > GameWorld.getTicks()) { + player.getPacketDispatch().sendMessage("You should not be picking up items. Now you must wait before you can leave."); + player.removeAttribute("pickup_penalty"); + player.setAttribute("/save:exit_penalty", GameWorld.getTicks() + 300); + entry.updatePenalty(player, true); + if (player.getPrayer().get(PrayerType.PROTECT_ITEMS)) { + player.getPrayer().toggle(PrayerType.PROTECT_ITEMS); + } + } + } else if (interfaceId == 271 && buttonId == 25) { + if (player.getAttribute("exit_penalty", 0) > GameWorld.getTicks()) { + player.getPacketDispatch().sendMessage("You can't use the protect item prayer until your penalty has passed."); + setVarp(player, PrayerType.PROTECT_ITEMS.getConfig(), 0); + return true; + } + } + return false; + } + + @Override + public boolean continueAttack(Entity e, Node target, CombatStyle style, boolean message) { + if (e instanceof Player && target instanceof Player) { + if (((Player) target).getAttribute("bh_joined", -1) > GameWorld.getTicks()) { + ((Player) e).getPacketDispatch().sendMessage("This player has only just entered and is temporarily invulnerable to attacks."); + return false; + } + e.removeAttribute("bh_joined"); + } + return true; + } + + /** + * Updates the skull. + * @param player The player. + */ + private void updateSkull(final Player player) { + if (player.getAttribute("value_listener") == null) { + ContainerListener listener = new ContainerListener() { + @Override + public void update(Container c, ContainerEvent event) { + refresh(c); + } + + @Override + public void refresh(Container c) { + updateSkull(player); + } + }; + player.setAttribute("value_listener", listener); + player.getInventory().getListeners().add(listener); + player.getEquipment().getListeners().add(listener); + } + long value = 0; + for (Item item : player.getInventory().toArray()) { + if (item != null) { + value += item.getValue(); + } + } + for (Item item : player.getEquipment().toArray()) { + if (item != null) { + value += item.getValue(); + } + } + int skull = 2; + if (value >= 0) { + for (int i = 0; i < SKULL_VALUES.length - 1; i++) { + if (value < SKULL_VALUES[i]) { + skull = 6 - i; + break; + } + } + } + player.getSkullManager().setSkulled(true); + player.getAppearance().setSkullIcon(skull); + player.getAppearance().sync(); + } + + /** + * Enters the bounty hunter crater. + * @param player The player. + */ + public void enterCrater(Player player) { + Point offset = RandomFunction.getRandomElement(EXIT_OFFSETS); + Location destination = Location.create(getType().getZone().getSouthWestX() + offset.getX(), getType().getZone().getSouthWestY() + offset.getY(), 0); + player.getProperties().setTeleportLocation(destination); + player.animate(Animation.create(7377)); + } + + /** + * Leaves the bounty hunter crater. + * @param player The player. + * @param logout If the player has logged out. + * @param entry The player's bounty entry. + */ + public void leaveCrater(Player player, boolean logout, BountyEntry entry) { + if (entry.getHunter() != null) { + BountyEntry other = players.get(entry.getHunter()); + if (other != null) { + entry.getHunter().getPacketDispatch().sendMessage("Your target has " + (logout ? "logged out" : "left") + ". You shall be found a new target."); + other.setTarget(null); + findTarget(entry.getHunter()); + } + } + if (entry.getTarget() != null) { + BountyEntry other = players.get(entry.getTarget()); + if (other != null) { + other.setHunter(null); + } + } + player.getHintIconManager().clear(); + players.remove(player); + ContainerListener listener = player.getAttribute("value_listener"); + if (listener != null) { + player.getInventory().getListeners().remove(listener); + player.getEquipment().getListeners().remove(listener); + } + player.getAppearance().setSkullIcon(-1); + player.getAppearance().sync(); + player.getInteraction().remove(Option._P_ATTACK); + player.getInteraction().set(Option._P_ASSIST); + player.getSkullManager().setSkullCheckDisabled(false); + player.getSkullManager().setWilderness(false); + player.getInterfaceManager().closeOverlay(); + if (players.isEmpty()) { + gamePulse.stop(); + } + int penalty; + if ((penalty = player.getAttribute("pickup_penalty", 0)) > GameWorld.getTicks()) { + player.setAttribute("/save:pickup_penalty", penalty - GameWorld.getTicks()); + } else { + player.removeAttribute("pickup_penalty"); + } + if ((penalty = player.getAttribute("exit_penalty", 0)) > GameWorld.getTicks()) { + player.setAttribute("/save:exit_penalty", penalty - GameWorld.getTicks()); + } else { + player.removeAttribute("exit_penalty"); + } + player.getSkullManager().setSkulled(false); + } + + /** + * Joins the waiting room. + * @param player The player. + */ + private void joinWaitingRoom(Player player) { + waitingRoom.add(player); + player.getProperties().setTeleportLocation(getType().getRoomLocation()); + player.getInterfaceManager().openOverlay(WAITING_OVERLAY); + player.getPacketDispatch().sendString("Players waiting (need " + MINIMUM_PLAYERS + "):", 656, 6); + updateWaitingRoomSize(); + if (waitingRoom.size() == MINIMUM_PLAYERS) { + String time = (int) Math.round(waitingTime * 0.6) + " Sec"; + for (Player p : waitingRoom) { + player.getPacketDispatch().sendString(time, 656, 10); + p.getPacketDispatch().sendInterfaceConfig(656, 9, false); + p.getPacketDispatch().sendInterfaceConfig(656, 8, false); + } + if (!waitRoomPulse.isRunning()) { + waitRoomPulse.start(); + GameWorld.getPulser().submit(waitRoomPulse); + } + } else if (waitingRoom.size() > MINIMUM_PLAYERS) { + player.getPacketDispatch().sendString((int) Math.round(waitingTime * 0.6) + " Sec", 656, 10); + player.getPacketDispatch().sendInterfaceConfig(656, 9, false); + player.getPacketDispatch().sendInterfaceConfig(656, 8, false); + } + } + + /** + * Leaves the waiting room. + * @param player The player. + */ + @SuppressWarnings("deprecation") + public void leaveWaitingRoom(Player player, boolean logout) { + waitingRoom.remove(player); + if (waitingRoom.size() < MINIMUM_PLAYERS && waitRoomPulse.isRunning()) { + waitRoomPulse.stop(); + for (Player p : waitingRoom) { + p.getPacketDispatch().sendInterfaceConfig(656, 9, true); + p.getPacketDispatch().sendInterfaceConfig(656, 8, true); + } + } + updateWaitingRoomSize(); + player.getProperties().setTeleportLocation(getType().getExitLocation()); + player.getInterfaceManager().closeOverlay(); + if (logout) { + player.setLocation(getType().getExitLocation()); + } + } + + /** + * Finds a target for the specified player. + * @param player The player. + */ + private void findTarget(Player player) { + Player target = null; + BountyEntry other = null; + int difference = 999; + for (Player p : players.keySet()) { + if (p == player) { + continue; + } + BountyEntry entry = players.get(p); + if (entry.getHunter() == null) { + int diff = Math.abs(player.getProperties().getCurrentCombatLevel() - p.getProperties().getCurrentCombatLevel()); + if (diff < difference) { + difference = diff; + target = p; + other = entry; + } + } + } + if (other != null) { + other.setHunter(player); + HintIconManager.registerHintIcon(player, target); + } else { + player.getHintIconManager().clear(); + } + BountyEntry entry = players.get(player); + entry.setTarget(target); + entry.update(player); + } + + /** + * Updates the amount of players in the waiting room. + */ + private void updateWaitingRoomSize() { + String size = Integer.toString(waitingRoom.size()); + for (Player player : waitingRoom) { + player.getPacketDispatch().sendString(size, 656, 7); + } + } + + @Override + public boolean canLogout(Player player) { + if (player.getAttribute("exit_penalty", 0) > GameWorld.getTicks()) { + player.getPacketDispatch().sendMessage("You can't logout until the exit penalty is over."); + return false; + } + return true; + } + + @Override + public boolean death(Entity e, Entity killer) { + if (e instanceof Player) { + Player player = (Player) e; + BountyEntry entry = players.get(player); + if (entry != null) { + if (entry.getHunter() != killer && killer instanceof Player) { + handleRogueKill((Player) killer, player, entry); + } else if (entry.getHunter() == killer) { // "They" is not a + // typo, this was + // the actual + // message on RS. + entry.getHunter().getPacketDispatch().sendMessage("You killed " + player.getUsername() + ". They were your target, so your Hunter PvP rating increases!"); + entry.getHunter().getSavedData().getActivityData().updateBountyHunterRate(1); + BHScoreBoard.getHunters().check(entry.getHunter()); + } else if (entry.getHunter() != null) { + entry.getHunter().getPacketDispatch().sendMessage("Your target has died. You shall be found a new target."); + } + if (entry.getHunter() != null) { + BountyEntry other = players.get(entry.getHunter()); + if (other != null) { + other.setTarget(null); + } + entry.setHunter(null); + } + player.getHintIconManager().clear(); + if (player.getAttribute("pickup_penalty", 0) != 0) { + player.setAttribute("pickup_penalty", GameWorld.getTicks() - 5); + } + if (player.getAttribute("exit_penalty", 0) != 0) { + player.setAttribute("exit_penalty", GameWorld.getTicks() - 5); + } + entry.updatePenalty((Player) e, true); + } + } + return false; + } + + /** + * Handles a rogue kill. + * @param player The player who killed the victim. + * @param victim The victim. + */ + private void handleRogueKill(Player player, Player victim, BountyEntry entry) { + player.getPacketDispatch().sendMessage("You killed " + victim.getUsername() + ". They were not your target, so your Rogue PvP rating"); + player.getPacketDispatch().sendMessage("increases!"); + player.getPacketDispatch().sendMessage("This means you get the pick-up penalty: pick anything up and you can't leave!"); + player.getSavedData().getActivityData().updateBountyRogueRate(1); + BHScoreBoard.getRogues().check(player); + player.setAttribute("/save:pickup_penalty", GameWorld.getTicks() + 300); + entry.updatePenalty(player, true); + } + + @Override + public boolean teleport(Entity e, int type, Node node) { + if (e instanceof Player && type != -1) { + ((Player) e).getPacketDispatch().sendMessage("A magical force stops you from teleporting."); + return false; + } + return true; + } + + @Override + public ActivityPlugin newInstance(Player p) throws Throwable { + return this; + } + + @Override + public Location getSpawnLocation() { + return Location.create(3166, 3679, 0); + } + + @Override + public void configure() { + registerRegion(6234); + register(getType().getZone()); + int x = getType().getZone().getSouthWestX(); + int y = getType().getZone().getSouthWestY(); + MultiwayCombatZone.getInstance().register(new ZoneBorders(x + 56, y + 40, x + 140, y + 140)); + } + + /** + * Gets the type. + * @return The type. + */ + public CraterType getType() { + return type; + } + +} diff --git a/Server/src/main/content/minigame/bountyhunter/BountyLocateSpell.java b/Server/src/main/content/minigame/bountyhunter/BountyLocateSpell.java new file mode 100644 index 0000000..36693d2 --- /dev/null +++ b/Server/src/main/content/minigame/bountyhunter/BountyLocateSpell.java @@ -0,0 +1,100 @@ +package content.minigame.bountyhunter; + +import core.game.node.entity.impl.PulseType; +import core.game.node.entity.combat.spell.MagicSpell; +import core.game.node.entity.combat.spell.Runes; +import core.game.interaction.MovementPulse; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.spell.SpellType; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.node.entity.player.link.TeleportManager.TeleportType; +import core.game.node.item.Item; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.plugin.Plugin; + +import static core.api.ContentAPIKt.*; + +/** + * Handles the bounty target locate spell. + * @author Emperor + */ +public final class BountyLocateSpell extends MagicSpell { + + /** + * Constructs a new {@code BountyLocateSpell} {@code Object}. + */ + public BountyLocateSpell() { + super(SpellBook.MODERN, 32, 45, null, null, null, new Item[] { Runes.AIR_RUNE.getItem(1), Runes.FIRE_RUNE.getItem(1), Runes.LAW_RUNE.getItem(1) }); + } + + @Override + public boolean cast(Entity entity, Node target) { + BountyHunterActivity activity = entity.getExtension(BountyHunterActivity.class); + Player player = (Player) entity; + if (activity == null) { + player.getPacketDispatch().sendMessage("You can only use this spell in the Bounty Hunter craters."); + return false; + } + BountyEntry entry = activity.players.get(player); + if (entry == null || entry.getTarget() == null) { + player.getPacketDispatch().sendMessage("You don't have a target to teleport to."); + return true; + } + if (hasTimerActive(player, "frozen") || isStunned(player)) { + player.getPacketDispatch().sendMessage("You can't use this when " + (isStunned(player) ? "stunned." : "frozen.")); + return true; + } + boolean combat = player.inCombat(); + if (!super.meetsRequirements(entity, true, combat)) { + return false; + } + if (combat) { + player.getPacketDispatch().sendMessage("You were fighting recently so you'll run instead of teleport."); + target = entry.getTarget(); + Location location = entry.getTarget().getLocation(); + if (!location.withinDistance(player.getLocation(), 30)) { + int offsetX = location.getX() - player.getLocation().getX(); + int offsetY = location.getY() - player.getLocation().getY(); + if (offsetX > 30) { + offsetX = 30; + } else if (offsetX < -30) { + offsetX = -30; + } + if (offsetY > 30) { + offsetY = 30; + } else if (offsetY < -30) { + offsetY = -30; + } + target = player.getLocation().transform(offsetX, offsetY, 0); + } + player.getPulseManager().run(new MovementPulse(player, target) { + @Override + public boolean pulse() { + return true; + } + }, PulseType.STANDARD); + return true; + } + Location destination = RegionManager.getTeleportLocation(entry.getTarget().getLocation(), 5); + if (entity.getTeleporter().send(destination, TeleportType.NORMAL, -1)) { + if (!super.meetsRequirements(entity, true, true)) { + entity.getTeleporter().getCurrentTeleport().stop(); + return false; + } + entity.setAttribute("magic-delay", GameWorld.getTicks() + 5); + return true; + } + return false; + } + + @Override + public Plugin newInstance(SpellType arg) throws Throwable { + SpellBook.MODERN.register(60, this); + return this; + } + +} diff --git a/Server/src/main/content/minigame/bountyhunter/CraterType.java b/Server/src/main/content/minigame/bountyhunter/CraterType.java new file mode 100644 index 0000000..fe21779 --- /dev/null +++ b/Server/src/main/content/minigame/bountyhunter/CraterType.java @@ -0,0 +1,131 @@ +package content.minigame.bountyhunter; + +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.game.world.map.zone.ZoneBorders; + +/** + * Represents the crater types. + * @author Emperor + */ +public enum CraterType { + + /** + * The low level crater. + */ + LOW_LEVEL(3, Location.create(1548, 5804, 0), Location.create(1548, 5804, 0), Location.create(3152, 3672, 0), new ZoneBorders(2688, 5632, 2879, 5823)), + + /** + * The mid level crater. + */ + MID_LEVEL(50, Location.create(1558, 5785, 0), Location.create(1548, 5804, 0), Location.create(3158, 3680, 0), new ZoneBorders(2944, 5632, 3135, 5823)), + + /** + * The high level crater. + */ + HIGH_LEVEL(95, Location.create(1570, 5804, 0), Location.create(1548, 5804, 0), Location.create(3164, 3685, 0), new ZoneBorders(3200, 5632, 3391, 5823)); + + /** + * The level required to enter the crater. + */ + private final int level; + + /** + * The waiting room location. + */ + private final Location roomLocation; + + /** + * The crater location. + */ + private final Location craterLocation; + + /** + * The exit location. + */ + private final Location exitLocation; + + /** + * The zone borders. + */ + private final ZoneBorders zone; + + /** + * Constructs a new {@code CraterType} {@code Object}. The level required to + * enter the crater. + * @param roomLocation The location of the waiting room. + * @param craterLocation The location of the crater. + * @param exitLocation The location to go the when exiting. + * @param zone The crater zone. + */ + private CraterType(int level, Location roomLocation, Location craterLocation, Location exitLocation, ZoneBorders zone) { + this.level = level; + this.roomLocation = roomLocation; + this.craterLocation = craterLocation; + this.exitLocation = exitLocation; + this.zone = zone; + } + + /** + * Checks if the player can enter the crater. + * @param player The player. + * @return {@code True} if so. + */ + public boolean canEnter(Player player) { + int combatLevel = player.getProperties().getCurrentCombatLevel(); + if (player.getIronmanManager().checkRestriction()) { + return false; + } + if (ordinal() < CraterType.values().length - 1) { + if (combatLevel > CraterType.values()[ordinal() + 1].level + 5) { + player.getPacketDispatch().sendMessage("Your combat level has to be below " + (CraterType.values()[ordinal() + 1].level + 5) + " to enter this crater."); + return false; + } + } + if (combatLevel < level) { + player.getPacketDispatch().sendMessage("You need a combat level of " + level + " to enter this crater."); + return false; + } + return true; + } + + /** + * Gets the level requirement. + * @return The level requirement. + */ + public int getLevel() { + return level; + } + + /** + * Gets the roomLocation. + * @return The roomLocation. + */ + public Location getRoomLocation() { + return roomLocation; + } + + /** + * Gets the craterLocation. + * @return The craterLocation. + */ + public Location getCraterLocation() { + return craterLocation; + } + + /** + * Gets the exitLocation. + * @return The exitLocation. + */ + public Location getExitLocation() { + return exitLocation; + } + + /** + * Gets the zone. + * @return The zone. + */ + public ZoneBorders getZone() { + return zone; + } +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/bountyhunter/MaximillianSackvilleDialogue.kt b/Server/src/main/content/minigame/bountyhunter/MaximillianSackvilleDialogue.kt new file mode 100644 index 0000000..a5b0470 --- /dev/null +++ b/Server/src/main/content/minigame/bountyhunter/MaximillianSackvilleDialogue.kt @@ -0,0 +1,120 @@ +package content.minigame.bountyhunter + +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.IronmanMode +import core.plugin.Initializable +import org.rs09.consts.NPCs +import core.game.dialogue.IfTopic +import core.game.dialogue.Topic +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE + +/** + * Provides dialogue tree for Maximillian Sackville, + * the Bounty Hounter roving banker. + * + * @author vddCore + */ +@Initializable +class MaximillianSackvilleDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + START_DIALOGUE -> when { + hasIronmanRestriction(player, IronmanMode.ULTIMATE) -> { + npcl( + FacialExpression.NEUTRAL, + "My apologies, dear ${if (player.isMale) "sir" else "madam"}, " + + "our services are not available for Ultimate ${if (player.isMale) "Ironmen" else "Ironwomen"}." + ).also { stage = END_DIALOGUE } + } + + else -> { + npcl( + FacialExpression.NEUTRAL, + "Good day, how may I help you?" + ).also { + if (hasAwaitingGrandExchangeCollections(player)) { + stage++ + } else { + stage += 2 + } + } + } + } + + 1 -> npcl( + FacialExpression.NEUTRAL, + "Before we go any further, I should inform you that you " + + "have items ready for collection from the Grand Exchange." + ).also { stage++ } + + 2 -> playerl( + FacialExpression.ASKING, + "Who are you?" + ).also { stage++ } + + 3 -> npcl( + FacialExpression.NEUTRAL, + "How inconsiderate of me, dear ${if (player.isMale) "sir" else "madam"}. " + + "My name is Maximillian Sackville and I conduct operations here on behalf " + + "of The Bank of Gielinor." + ).also { stage++ } + + 4 -> showTopics( + Topic(FacialExpression.NEUTRAL, "I'd like to access my bank account.", 10), + IfTopic( + FacialExpression.NEUTRAL, + "I'd like to switch to my ${getBankAccountName(player, true)} bank account.", + 11, + hasActivatedSecondaryBankAccount(player) + ), + Topic(FacialExpression.NEUTRAL, "I'd like to check my PIN settings.", 12), + Topic(FacialExpression.NEUTRAL, "I'd like to collect items.", 13), + Topic(FacialExpression.ASKING, "Aren't you afraid of working in the Wilderness?", 5) + ) + + 5 -> npcl( + FacialExpression.NEUTRAL, + "While the Wilderness is quite a dangerous place, The Bank of Gielinor offers " + + "us - roving bankers - extraordinary benefits for our hard work in hazardous environments." + ).also { stage++ } + + 6 -> npcl( + FacialExpression.NEUTRAL, + "This allows us to provide our services to customers regardless of their current " + + "whereabouts. Our desire to serve is stronger than our fear of the Wilderness." + ).also { stage = END_DIALOGUE } + + 10 -> { + openBankAccount(player) + end() + } + + 11 -> { + toggleBankAccount(player) + + npcl( + FacialExpression.NEUTRAL, + "Naturally. You can now access your ${getBankAccountName(player)} bank account." + ).also { stage = END_DIALOGUE } + } + + 12 -> { + openBankPinSettings(player) + end() + } + + 13 -> { + openGrandExchangeCollectionBox(player) + end() + } + } + + return true + } + + override fun getIds() = intArrayOf(NPCs.BANKER_6538) +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/bountyhunter/UnimplementedCraterArea.kt b/Server/src/main/content/minigame/bountyhunter/UnimplementedCraterArea.kt new file mode 100644 index 0000000..60050f9 --- /dev/null +++ b/Server/src/main/content/minigame/bountyhunter/UnimplementedCraterArea.kt @@ -0,0 +1,75 @@ +package content.minigame.bountyhunter.handlers + +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import org.rs09.consts.NPCs +import core.game.dialogue.DialogueFile +import core.game.world.GameWorld + +class UnimplementedCraterArea : MapArea { + override fun defineAreaBorders(): Array { + return arrayOf( + ZoneBorders(3200, 5632, 3391, 5823) + ) + } + + override fun areaEnter(entity: Entity) { + if (entity is Player && ( + defineAreaBorders()[0].insideBorder(entity) + )) { + kickThemOut(entity) + } + } + + private fun kickThemOut(entity: Player) { + val watchdog = NPC(NPCs.BANKER_6538) + watchdog.isNeverWalks = true + watchdog.isWalks = false + watchdog.location = entity.location + watchdog.init() + entity.lock() + + runTask(watchdog, 1) { + watchdog.moveStep() + watchdog.face(entity) + openDialogue(entity, UnimplementedCraterDialogue(), watchdog) + GameWorld.Pulser.submit(object : Pulse() { + override fun pulse(): Boolean { + if (getAttribute(entity, "teleporting-away", false)) + return true + if (!entity.isActive) + poofClear(watchdog) + if (entity.dialogueInterpreter.dialogue == null || entity.dialogueInterpreter.dialogue.file == null) + openDialogue(entity, UnimplementedCraterDialogue(), watchdog) + return !watchdog.isActive || !entity.isActive + } + }) + } + } + + class UnimplementedCraterDialogue : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when(stage) { + 0 -> npcl(core.game.dialogue.FacialExpression.WORRIED, "This is unimplemented content, and you are now stuck. Don't worry, I'll get you out of here!").also { stage++ } + 1 -> { + end() + visualize(npc!!, 1818, 343) + sendGraphics(342, player!!.location) + setAttribute(player!!, "teleporting-away", true) + runTask(player!!, 3) { + poofClear(npc!!) + teleport(player!!, Location.create(3179, 3685, 0)) + unlock(player!!) + removeAttribute(player!!, "teleporting-away") + } + } + } + } + } +} + diff --git a/Server/src/main/content/minigame/castlewars/CastleWars.kt b/Server/src/main/content/minigame/castlewars/CastleWars.kt new file mode 100644 index 0000000..670ea45 --- /dev/null +++ b/Server/src/main/content/minigame/castlewars/CastleWars.kt @@ -0,0 +1,81 @@ +package rs09.game.content.activity.castlewars + +import core.game.world.map.zone.ZoneBorders +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +object CastleWars { + // Scenery IDs + const val joinSaradominTeamPortal: Int = Scenery.SARADOMIN_PORTAL_4387 + const val joinZamorakTeamPortal: Int = Scenery.ZAMORAK_PORTAL_4388 + const val saradominLeaveLobbyPortal: Int = Scenery.PORTAL_4389 + const val zamorakLeaveLobbyPortal: Int = Scenery.PORTAL_4390 + const val joinGuthixTeamPortal: Int = Scenery.GUTHIX_PORTAL_4408 + const val cwCastleClimbingRope: Int = Scenery.CLIMBING_ROPE_36312 + const val castleWaterTap: Int = Scenery.TAP_4482 + const val cwSteppingStones: Int = Scenery.STEPPING_STONE_4411 + + // Map of the item table scenery id to the item id they give + val cwTableItemRewardMap = mapOf( + Scenery.TABLE_36573 to Items.TOOLKIT_4051, // Saradomin Toolkit Table + Scenery.TABLE_36580 to Items.TOOLKIT_4051, // Zamorak Toolkit Table + Scenery.TABLE_36574 to Items.ROCK_4043, // Saradomin Rock Table + Scenery.TABLE_36581 to Items.ROCK_4043, // Zamorak Rock Table + Scenery.TABLE_36575 to Items.BARRICADE_4053, // Saradomin Barricade Table + Scenery.TABLE_36582 to Items.BARRICADE_4053, // Zamorak Barricade Table + Scenery.TABLE_36576 to Items.CLIMBING_ROPE_4047, // Saradomin Climbing Rope Table + Scenery.TABLE_36583 to Items.CLIMBING_ROPE_4047, // Zamorak Climbing Rope Table + Scenery.TABLE_36577 to Items.EXPLOSIVE_POTION_4045, // Saradomin Explosive Potion Table + Scenery.TABLE_36584 to Items.EXPLOSIVE_POTION_4045, // Zamorak Explosive Potion Table + Scenery.TABLE_36578 to Items.BRONZE_PICKAXE_1265, // Saradomin Pickaxe Table + Scenery.TABLE_36585 to Items.BRONZE_PICKAXE_1265, // Zamorak Pickaxe Table + Scenery.TABLE_36579 to Items.BANDAGES_4049, // Saradomin Bandages Table + Scenery.TABLE_36586 to Items.BANDAGES_4049 // Zamorak Bandages Table + ) + + val cwCastleBattlementsMap = mapOf( + Scenery.BATTLEMENTS_4446 to Scenery.BATTLEMENTS_36313, + Scenery.BATTLEMENTS_4447 to Scenery.BATTLEMENTS_36314 + ) + + // Item IDs + const val saradominTeamHoodedCloak: Int = Items.HOODED_CLOAK_4041 + const val zamorakTeamHoodedCloak: Int = Items.HOODED_CLOAK_4042 + const val saradominFlag: Int = Items.SARADOMIN_BANNER_4037 // Might be 4038 + const val zamorakFlag: Int = Items.ZAMORAK_BANNER_4039 // Might be 4040 + const val cwPickaxe: Int = Items.BRONZE_PICKAXE_1265 + const val cwRock: Int = Items.ROCK_4043 + const val cwExplosivePotion: Int = Items.EXPLOSIVE_POTION_4045 + const val cwClimbingRope: Int = Items.CLIMBING_ROPE_4047 + const val cwBandages: Int = Items.BANDAGES_4049 + const val cwToolkit: Int = Items.TOOLKIT_4051 + const val cwBarricade: Int = Items.BARRICADE_4053 + const val cwManualBook: Int = Items.CASTLEWARS_MANUAL_4055 + const val cwTicketRewardCurrency: Int = Items.CASTLE_WARS_TICKET_4067 + + // NPC IDs + const val sheep = NPCs.SHEEP_1529 + const val imp = NPCs.IMP_1531 + const val rabbit = NPCs.RABBIT_1530 + const val unknownCwarsBarricade1 = NPCs.BARRICADE_1532 + const val unknownCwarsBarricadeOnFire = NPCs.BARRICADE_1533 + const val unknownCwarsBarricade2 = NPCs.BARRICADE_1534 + const val unknownCwarsBarricade3 = NPCs.BARRICADE_1535 + + // Locations + val lobbyBankArea: ZoneBorders = ZoneBorders(2440, 3092, 2444, 3086, 0) + + // Strings + const val saradominName = "Saradomin" + const val zamorakName = "Zamorak" + const val guthixName = "Guthix" + const val portalAttribute = "castlewars_portal" + const val invFullMessage = "Your inventory is too full to hold any more " + + // Ints + const val gameTimeMinutes = 20 + const val gameCooldownMinutes = 5 + const val ropeAliveTicks = -1 // TODO: Find amount of time until wall reverts to non rope state + +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/castlewars/CastleWarsListeners.kt b/Server/src/main/content/minigame/castlewars/CastleWarsListeners.kt new file mode 100644 index 0000000..24fdb55 --- /dev/null +++ b/Server/src/main/content/minigame/castlewars/CastleWarsListeners.kt @@ -0,0 +1,188 @@ +package rs09.game.content.activity.castlewars + +import core.api.* +import content.global.skill.agility.AgilityHandler +import content.global.skill.summoning.familiar.BurdenBeast +import core.cache.def.impl.ItemDefinition +import core.game.container.Container +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.TeleportManager +import core.game.node.item.Item +import core.game.node.scenery.Scenery +import core.game.node.scenery.SceneryBuilder +import core.game.world.GameWorld +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items +import org.rs09.consts.Sounds +import rs09.game.content.activity.castlewars.areas.CastleWarsWaitingArea + +@Suppress("unused") +class CastleWarsListeners : InteractionListener { + + override fun defineListeners() { + + // Scenery Interactions - PORTALS + on(CastleWars.joinSaradominTeamPortal, IntType.SCENERY, "Enter") { player, _ -> + if (GameWorld.settings?.enable_castle_wars != true) return@on false + if (joinError(player)) return@on true + // MapArea handles joining properties + player.properties.teleportLocation = CastleWarsWaitingArea.saradominWaitingRoom.randomWalkableLoc + player.setAttribute(CastleWars.portalAttribute, CastleWars.saradominName) + return@on true + } + on(CastleWars.joinZamorakTeamPortal, IntType.SCENERY, "Enter") { player, _ -> + if (GameWorld.settings?.enable_castle_wars != true) return@on false + if (joinError(player)) return@on true + // MapArea handles joining properties + player.properties.teleportLocation = CastleWarsWaitingArea.zamorakWaitingRoom.randomWalkableLoc + player.setAttribute(CastleWars.portalAttribute, CastleWars.zamorakName) + return@on true + } + on(CastleWars.saradominLeaveLobbyPortal, IntType.SCENERY, "Exit") { player, _ -> + player.properties.teleportLocation = CastleWars.lobbyBankArea.randomWalkableLoc + // MapArea handles leaving properties + return@on true + } + on(CastleWars.zamorakLeaveLobbyPortal, IntType.SCENERY, "Exit") { player, _ -> + player.properties.teleportLocation = CastleWars.lobbyBankArea.randomWalkableLoc + // MapArea handles leaving properties + return@on true + } + on(CastleWars.joinGuthixTeamPortal, IntType.SCENERY, "Enter") { player, _ -> + if (GameWorld.settings?.enable_castle_wars != true) return@on false + if (joinError(player)) return@on true + + // Join the team with fewer players, if they're equal, join randomly + if (CastleWarsWaitingArea.waitingSaradominPlayers.size < CastleWarsWaitingArea.waitingZamorakPlayers.size) { + player.properties.teleportLocation = CastleWarsWaitingArea.saradominWaitingRoom.randomWalkableLoc + } else if (CastleWarsWaitingArea.waitingSaradominPlayers.size > CastleWarsWaitingArea.waitingZamorakPlayers.size) { + player.properties.teleportLocation = CastleWarsWaitingArea.zamorakWaitingRoom.randomWalkableLoc + } else { + if (Math.random() < 0.5) { + player.properties.teleportLocation = CastleWarsWaitingArea.saradominWaitingRoom.randomWalkableLoc + } else { + player.properties.teleportLocation = CastleWarsWaitingArea.zamorakWaitingRoom.randomWalkableLoc + } + } + player.setAttribute(CastleWars.portalAttribute, CastleWars.guthixName) + return@on true + } + + // Scenery Interactions - Item Tables + on(CastleWars.cwTableItemRewardMap.keys.toIntArray(), SCENERY, "take-from") { player, node -> + // Retrieve the item id from the map (null safe) + val rewardItem: Int = CastleWars.cwTableItemRewardMap.getValue(node.id) + + // If item is added to inventory, play pickup sound + if (addItem(player, rewardItem)) { + playAudio(player, Sounds.PICK2_2582) + + // Warn player inventory full using custom dialogue box + } else { + val formattedItemName = (ItemDefinition.forId(rewardItem).name.lowercase() + "s.") // Get the formatted item name string + .replace("pes.", "pe.") // Replacement for ropes. -> rope. + .replace("bronze ", "") // Replacement for bronze pickaxes. -> pickaxes. + + // Toolkit gets a more grammatically correct sentence + if (rewardItem == Items.TOOLKIT_4051) { + sendDialogue(player, "Your inventory is too full to hold a toolkit.") + } else { + sendDialogue(player, (CastleWars.invFullMessage + formattedItemName)) + } + } + return@on true + } + + // Item/Scenery Interaction - Outside Battlement (Wall) Rope Climb Setup + onUseWith(SCENERY, CastleWars.cwClimbingRope, *CastleWars.cwCastleBattlementsMap.keys.toIntArray()) { player, rope, wall -> + // Remove rope item from inventory + removeItem(player, rope) + // First, replace the scenery with the rope on top of the wall + replaceScenery(wall.asScenery(), CastleWars.cwCastleBattlementsMap.getValue(wall.id), CastleWars.ropeAliveTicks) + // Second, create a new scenery with the rope falling down + val toAdd = Scenery(CastleWars.cwCastleClimbingRope, wall.location, 4, wall.direction.toInteger()) + SceneryBuilder.add(toAdd, CastleWars.ropeAliveTicks) + toAdd.isActive = true + return@onUseWith true + } + + // Scenery Interactions - Outside Battlement (Wall) Player Climbs Rope + on(CastleWars.cwCastleClimbingRope, SCENERY, "climb") { player, rope -> + // Get the direction of the scenery + val dir = rope.asScenery().direction.opposite + // Move player on top of the wall from that specific rope location + teleport(player, Location(dir.stepY + player.location.x, -dir.stepX + player.location.y), TeleportManager.TeleportType.INSTANT) + return@on true + } + + // Scenery Interactions - Water Tap - No pulse + onUseWith(SCENERY, Items.BUCKET_1925, CastleWars.castleWaterTap) { player, used, _ -> + // Lock player + lock(player, 1) + // Bucket fill animation + animate(player, 832) + // Bucket fill sound + playAudio(player, Sounds.TAP_FILL_2609) + // Replace empty -> full water bucket + replaceSlot(player, used.asItem().slot, Item(Items.BUCKET_OF_WATER_1929)) + return@onUseWith true + } + + // Scenery Interactions - Stepping stones + on(CastleWars.cwSteppingStones, SCENERY, "jump-to") { player, stone -> + // Lock the player + lock(player, 3) + // Make the player "Jump" to the next stepping stone + AgilityHandler.forceWalk(player, -1, player.location, stone.location, Animation(741), 10, 0.0, null, 1) + // Delay sound to line up with "jump" movement + runTask(player, 1) { + // Play jumping sound + playAudio(player, Sounds.JUMP_2461) + } + return@on true + } + } + + private fun hasNonCombatItems(container: Container): Boolean { + for (item in container.toArray()) { + if (item?.id != null && (item.id == Items.COINS_995 || item.definition?.noteId == item.id)) + return true + } + return false + } + + private fun capeOrHelmetError(player: Player): String? { + val wornCape = getItemFromEquipment(player, EquipmentSlot.CAPE)?.id ?: -1 + val wornHelmet = getItemFromEquipment(player, EquipmentSlot.HEAD)?.id ?: -1 + + if (wornCape != -1 || wornHelmet != -1) return "You can't wear hats, capes, or helms in the arena." + return null + } + + private fun nonCombatItemsCheck(player: Player): String? { + // Coins & Noted items, possibly others? + if (hasNonCombatItems(player.inventory)) return "You can't take non-combat items into the arena." + + return null + } + + private fun familiarCheck(player: Player): String? { + // https://forum.tip.it/topic/250066-castle-wars-familiar-msg/ + // Your familiar can't hold any non-combat items + + // Check the player's familiar container for Coins or Noted items + val familiar: BurdenBeast = player.familiarManager.familiar as? BurdenBeast ?: return null + + if (hasNonCombatItems(familiar.container)) return "Your familiar can't take non-combat items into the arena." + + return null + } + + private fun joinError(player: Player): Boolean { + val errorMessage = capeOrHelmetError(player) ?: nonCombatItemsCheck(player) ?: familiarCheck(player) ?: return false + player.sendMessage(errorMessage).also { return true } + } +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/castlewars/CastleWarsOverlay.kt b/Server/src/main/content/minigame/castlewars/CastleWarsOverlay.kt new file mode 100644 index 0000000..76a4a8a --- /dev/null +++ b/Server/src/main/content/minigame/castlewars/CastleWarsOverlay.kt @@ -0,0 +1,22 @@ +import core.api.* +import core.game.node.entity.player.Player + +/** + * Handles updating the Castle Wars overlay interface + * @author dginovker + */ +object CastleWarsOverlay { + @JvmStatic + fun sendLobbyUpdate(player: Player, bothTeamsHavePlayers: Boolean, gameStartMinutes: Int) { + setVarp(player, 380, if (bothTeamsHavePlayers) gameStartMinutes else 0) + } + + @JvmStatic + fun sendGameUpdate(player: Player) { + // Todo - Figure out underground mine/etc + setVarbit(player, 143, 0) // Flag status - safe = 0, taken = 1, dropped = 2 + setVarbit(player, 145, 5) // Saradomin's score + setVarbit(player, 153, 0) // Flag status - safe = 0, taken = 1, dropped = 2 + setVarbit(player, 155, 7) // Zamorak's score + } +} diff --git a/Server/src/main/content/minigame/castlewars/Lanthus.kt b/Server/src/main/content/minigame/castlewars/Lanthus.kt new file mode 100644 index 0000000..301e178 --- /dev/null +++ b/Server/src/main/content/minigame/castlewars/Lanthus.kt @@ -0,0 +1,131 @@ +package rs09.game.content.activity.castlewars + +import core.api.TickListener +import core.api.openDialogue +import core.api.sendMessage +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.npc.NPC +import core.game.node.item.Item +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class Lanthus: InteractionListener, TickListener { + override fun defineListeners() { + on(NPCs.LANTHUS_1526, IntType.NPC, "talk-to") { player, npcNode -> + val lanthusNpc = npcNode.asNpc() + openDialogue(player, object : DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + when(stage) { + 0 -> npcl(FacialExpression.FRIENDLY, "Good day, how may I help you?").also { stage = 2 } + 2 -> options( + "What is this place?", + "What do you have for trade?", + "Do you have a manual? I'd like to learn how to play!" + ).also { stage++ } + 3 -> when (buttonID) { + 1 -> player("What is this place?").also { stage = 4 } + 2 -> lanthusNpc.openShop(player).also { stage = END_DIALOGUE } + 3 -> player("Do you have a manual? I'd like to learn how to play!").also { stage = 50 } + } + 4 -> npcl( + FacialExpression.FRIENDLY, + "This is the great Castle Wars arena! Here you can fight for the glory of Saradomin or Zamorak." + ).also { stage++ } + 5 -> options( + "Really, how do I do that?", + "Are there any rules?", + "What can I win?" + ).also { stage++ } + 6 -> when (buttonID) { + 1 -> player("Really, how do I do that?").also { stage = 7 } + 2 -> player("Are there any rules?").also { stage = 80 } + 3 -> player("What can I win?").also { stage = 90 } + } + 7 -> npcl( + FacialExpression.FRIENDLY, + "Easy, you just step through one of the three portals. To join Zamorak, pass through the red portal. To join Saradomin, pass through the blue portal. If you don't mind then pass through the green portal.", + ).also { stage ++ } + 8 -> options( + "Are there any rules?", + "What can I win?", + "What do you have for trade?", + "Do you have a manual? I'd like to learn how to play!" + ).also { stage++ } + 9 -> when (buttonID) { + 1 -> player("Are there any rules?").also { stage = 80 } + 2 -> player("What can I win?").also { stage = 90 } + 3 -> lanthusNpc.openShop(player).also { stage = END_DIALOGUE } + 4 -> player("Do you have a manual? I'd like to learn how to play!").also { stage = 50 } + } + + 80 -> npcl( + FacialExpression.FRIENDLY, "Of course, there are always rules. Firstly you can't wear a cape as you enter the portal, you'll be given your team colours to wear while in the arena. You're also prohibited from taking non-combat related items in") + .also { stage ++ } + + 81 -> npcl( + FacialExpression.FRIENDLY, " with you. So you should only have equipment, potions, and runes on you. Secondly, attacking your own team or your team's defences isn't allowed. You don't want to be angering" + ).also { stage ++ } + + 82 -> npcl( + FacialExpression.FRIENDLY, "your patron god, do you? Other than that, just have fun and enjoy it!" + ).also { stage ++ } + + 50 -> npcl( + FacialExpression.FRIENDLY, + "Sure, here you go.").also { stage = END_DIALOGUE }.also { player.inventory.add(Item(Items.CASTLEWARS_MANUAL_4055)) } + + 83 -> player("Great! Oh, how do I win the game?").also { stage ++ } + 84 -> npcl( + FacialExpression.FRIENDLY, + "The aim is to get into your opponents' castle and take their team standard. Then bring that back and capture it on your team's standard." + ).also { stage ++ } + 85 -> options( + "What can I win?", + "What do you have to trade?", + "Do you have a manual? I'd like to learn how to play!" + ).also { stage ++ } + 86 -> when (buttonID) { + 1 -> player("What can I win?").also { stage = 90 } + 2 -> lanthusNpc.openShop(player).also { stage = END_DIALOGUE } + 3 -> player("Do you have a manual? I'd like to learn how to play!").also { stage = 50 } + } + + 90 -> npcl( + FacialExpression.FRIENDLY, + "Players on the winning team will receive 2 Castle Wars Tickets which you can trade back to me for other items. In the event of a draw every player will get 1 ticket." + ).also { stage ++ } + 91 -> options( + "Are there any rules?", + "What do you have to trade?", + "Do you have a manual? I'd like to learn how to play!" + ).also { stage ++ } + 92 -> when (buttonID) { + 1 -> player("Are there any rules?").also { stage = 80 } + 2 -> lanthusNpc.openShop(player).also { stage = END_DIALOGUE } + 3 -> player("Do you have a manual? I'd like to learn how to play!").also { stage = 50 } + } + // Default + else -> sendMessage(player, "Error - unknown stage $stage").also { stage = END_DIALOGUE } + } + } + }, lanthusNpc) + + return@on true + } + on(NPCs.LANTHUS_1526, IntType.NPC, "trade-with") { player, npcNode -> + npcNode.asNpc().openShop(player) + return@on true + } + } + + override fun tick() { + "The next game will start in 4 minutes" + "The next game will start in 1 minute" + // He also talks to Postie Pete sometimes? + + } +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/castlewars/areas/CastleWarsArea.kt b/Server/src/main/content/minigame/castlewars/areas/CastleWarsArea.kt new file mode 100644 index 0000000..c6b336c --- /dev/null +++ b/Server/src/main/content/minigame/castlewars/areas/CastleWarsArea.kt @@ -0,0 +1,75 @@ +package rs09.game.content.activity.castlewars.areas + +import content.global.skill.summoning.familiar.BurdenBeast +import core.api.* +import core.game.interaction.InteractionListener +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import rs09.game.content.activity.castlewars.CastleWars + +abstract class CastleWarsArea : MapArea, LogoutListener, InteractionListener { + + override fun areaLeave(entity: Entity, logout: Boolean) { + super.areaLeave(entity, logout) + exitArea(entity as? Player ?: return) + } + + override fun logout(player: Player) { + if (!defineAreaBorders().any { it.insideBorder(player.location) }) { + return // We're not in this area + } + + // Move the player to the lobby bank area + // Set location directly here, because we want it to take effect immediately + player.location = CastleWars.lobbyBankArea.randomWalkableLoc + exitArea(player) + } + + open fun exitArea(player: Player) { + // Remove any transformation + player.appearance.transformNPC(-1) + + // Give the player their tabs back + player.interfaceManager.restoreTabs() + + // Let the player run + player.walkingQueue.isRunDisabled = false + + // If we're not entering another Castle Wars area, remove the Castle Wars items + if ((CastleWarsGameArea.areaBorders + CastleWarsWaitingArea.areaBorders).none { it.insideBorder(player.location) }) { + exitCastleWars(player) + } + } + + private fun exitCastleWars(player: Player) { + // Close the overlay interface + player.interfaceManager.closeOverlay() + + // Remove teleblock + removeTimer(player, "teleblock") + + // Remove any Castle Wars items + // Todo Remove any tinderboxes or other castle wars items - See Jan 2018 update: https://oldschool.runescape.wiki/w/Castle_Wars + val cwarsItems = intArrayOf(CastleWars.saradominTeamHoodedCloak, + CastleWars.zamorakTeamHoodedCloak, + CastleWars.saradominFlag, + CastleWars.zamorakFlag) + + player.equipment.removeAll(cwarsItems) + player.inventory.removeAll(cwarsItems) + (player.familiarManager.familiar as? BurdenBeast)?.container?.removeAll(cwarsItems) + } + + override fun defineListeners() { + onUnequip(intArrayOf(CastleWars.saradominTeamHoodedCloak, CastleWars.zamorakTeamHoodedCloak)) { player, _ -> + defineAreaBorders().forEach { border -> + if (border.insideBorder(player)) { + sendMessage(player, "You can't remove your team's colours") + return@onUnequip false + } + } + return@onUnequip true + } + } + +} diff --git a/Server/src/main/content/minigame/castlewars/areas/CastleWarsGameArea.kt b/Server/src/main/content/minigame/castlewars/areas/CastleWarsGameArea.kt new file mode 100644 index 0000000..2b32486 --- /dev/null +++ b/Server/src/main/content/minigame/castlewars/areas/CastleWarsGameArea.kt @@ -0,0 +1,98 @@ +package rs09.game.content.activity.castlewars.areas + +import core.api.* +import core.game.component.Component +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import core.tools.Log +import core.tools.ticksPerMinute +import org.rs09.consts.Components +import rs09.game.content.activity.castlewars.CastleWars + +/** + * Handles the Castle Wars game map + */ +class CastleWarsGameArea : CastleWarsArea(), TickListener { + + companion object { + private val saradominStandardFloor: ZoneBorders = ZoneBorders(Location.create(2426, 3073, 3), Location.create(2430, 3077, 3)) + private val zamorakStandardFloor: ZoneBorders = ZoneBorders(Location.create(2373, 3134, 3), Location.create(2369, 3130, 3)) + private val saradominUpperFloor: ZoneBorders = ZoneBorders(Location.create(2431, 3080, 2), Location.create(2423, 3072, 2)) + private val zamorakUpperFloor: ZoneBorders = ZoneBorders(Location.create(2368, 3127, 2), Location.create(2376, 3135, 2)) + private val saradominFloor: ZoneBorders = ZoneBorders(Location.create(2420, 3072, 1), Location.create(2431, 3083, 1)) + private val zamorakFloor: ZoneBorders = ZoneBorders(Location.create(2379, 3135, 1), Location.create(2368, 3124, 1)) + private val battleField: ZoneBorders = ZoneBorders(Location.create(2368, 3135, 0), Location.create(2431, 3072, 0)) + private val saradominTunnels: ZoneBorders = ZoneBorders(Location.create(2430, 9481, 0), Location.create(2400, 9504, 0)) + private val zamorakTunnels: ZoneBorders = ZoneBorders(Location.create(2401, 9503, 0), Location.create(2366, 9529, 0)) + + val areaBorders = arrayOf(saradominStandardFloor, zamorakStandardFloor, saradominUpperFloor, zamorakUpperFloor, saradominFloor, zamorakFloor, battleField, saradominTunnels, zamorakTunnels) + + val saradominPlayers = mutableSetOf() + val zamorakPlayers = mutableSetOf() + + var ticksLeftInGame = 0 + + fun startGame() { + saradominPlayers.addAll(CastleWarsWaitingArea.waitingSaradominPlayers) + zamorakPlayers.addAll(CastleWarsWaitingArea.waitingZamorakPlayers) + CastleWarsWaitingArea.waitingSaradominPlayers.clear() + CastleWarsWaitingArea.waitingZamorakPlayers.clear() + ticksLeftInGame = CastleWars.gameTimeMinutes * ticksPerMinute + + // Put all the players in their respawn area + saradominPlayers.forEach { player -> + player.properties.teleportLocation = CastleWarsRespawnArea.saradominRespawnRoom.randomWalkableLoc + } + zamorakPlayers.forEach { player -> + player.properties.teleportLocation = CastleWarsRespawnArea.zamorakRespawnRoom.randomWalkableLoc + } + } + } + + private fun endGame() { + saradominPlayers.forEach { player -> + player.properties.teleportLocation = CastleWars.lobbyBankArea.randomWalkableLoc + } + zamorakPlayers.forEach { player -> + player.properties.teleportLocation = CastleWars.lobbyBankArea.randomWalkableLoc + } + saradominPlayers.clear() + zamorakPlayers.clear() + } + + override fun defineAreaBorders(): Array { + return areaBorders + } + + override fun areaEnter(entity: Entity) { + val player = entity as? Player ?: return + super.areaEnter(player) + registerTimer (player, spawnTimer("teleblock", (CastleWars.gameTimeMinutes)*60*2)) + + if (saradominPlayers.contains(player)) { + player.interfaceManager.openOverlay(Component(Components.CASTLEWARS_STATUS_OVERLAY_SARADOMIN_58)) + player.equipment.replace(Item(CastleWars.saradominTeamHoodedCloak), 1) + } else if (zamorakPlayers.contains(player)) { + player.interfaceManager.openOverlay(Component(Components.CASTLEWARS_STATUS_OVERLAY_ZAMORAK_59)) + player.equipment.replace(Item(CastleWars.zamorakTeamHoodedCloak), 1) + } + } + + override fun exitArea(player: Player) { + super.exitArea(player) + // Remove player from the players set (whichever one that is) + saradominPlayers.remove(player) + zamorakPlayers.remove(player) + } + + override fun tick() { + ticksLeftInGame-- + if (ticksLeftInGame == 0) { + endGame() + } + } + +} diff --git a/Server/src/main/content/minigame/castlewars/areas/CastleWarsRespawnArea.kt b/Server/src/main/content/minigame/castlewars/areas/CastleWarsRespawnArea.kt new file mode 100644 index 0000000..6715643 --- /dev/null +++ b/Server/src/main/content/minigame/castlewars/areas/CastleWarsRespawnArea.kt @@ -0,0 +1,40 @@ +package rs09.game.content.activity.castlewars.areas + +import core.api.TickListener +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import rs09.game.content.activity.castlewars.CastleWars + +/** + * Handles the Castle Wars respawn rooms + */ +class CastleWarsRespawnArea : CastleWarsArea(), TickListener { + + companion object { + val zamorakRespawnRoom: ZoneBorders = ZoneBorders(Location.create(2376, 3127, 1), Location.create(2368, 3135, 1)) + val saradominRespawnRoom: ZoneBorders = ZoneBorders(Location.create(2423, 3080, 1), Location.create(2431, 3072, 1)) + + val zamorakPlayersInRespawnRoom = mutableSetOf() + val saradominPlayersInRespawnRoom = mutableSetOf() + } + + override fun defineAreaBorders(): Array { + return arrayOf(zamorakRespawnRoom, saradominRespawnRoom) + } + + override fun areaEnter(entity: Entity) { + val player = entity as? Player ?: return + if (saradominRespawnRoom.insideBorder(player.location)) { + player.equipment.replace(Item(CastleWars.saradominTeamHoodedCloak), 1) + } else if (zamorakRespawnRoom.insideBorder(player.location)) { + player.equipment.replace(Item(CastleWars.zamorakTeamHoodedCloak), 1) + } + } + + override fun tick() { + } + +} diff --git a/Server/src/main/content/minigame/castlewars/areas/CastleWarsWaitingArea.kt b/Server/src/main/content/minigame/castlewars/areas/CastleWarsWaitingArea.kt new file mode 100644 index 0000000..3bc53dd --- /dev/null +++ b/Server/src/main/content/minigame/castlewars/areas/CastleWarsWaitingArea.kt @@ -0,0 +1,128 @@ +package rs09.game.content.activity.castlewars.areas + +import CastleWarsOverlay +import core.api.* +import core.game.component.Component +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.world.map.zone.ZoneBorders +import core.tools.ticksPerMinute +import org.rs09.consts.Components +import rs09.game.content.activity.castlewars.CastleWars + +/** + * Handles the Castle Wars "waiting room" + */ +class CastleWarsWaitingArea : CastleWarsArea(), TickListener { + + companion object { + val zamorakWaitingRoom: ZoneBorders = ZoneBorders(2432, 9510, 2407, 9534, 0) + val saradominWaitingRoom: ZoneBorders = ZoneBorders(2394, 9497, 2369, 9481, 0) + + val areaBorders = arrayOf(zamorakWaitingRoom, saradominWaitingRoom) + + val waitingSaradominPlayers = mutableSetOf() + val waitingZamorakPlayers = mutableSetOf() + } + + override fun defineAreaBorders(): Array { + return areaBorders + } + + override fun areaEnter(entity: Entity) { + val player = entity as? Player ?: return + super.areaEnter(player) + registerTimer(player, spawnTimer("teleblock", (CastleWars.gameCooldownMinutes + CastleWars.gameTimeMinutes)*60*2)) + + // Set team attribute and equip the hooded cloak on the entity based on which waiting room they're in + if (zamorakWaitingRoom.insideBorder(player.location)) { + player.equipment.replace(Item(CastleWars.zamorakTeamHoodedCloak), 1) + waitingZamorakPlayers.add(player) + } else if (saradominWaitingRoom.insideBorder(player.location)) { + player.equipment.replace(Item(CastleWars.saradominTeamHoodedCloak), 1) + waitingSaradominPlayers.add(player) + } + + var transformed = false + if (player.attributes[CastleWars.portalAttribute] == CastleWars.guthixName + && (hasGodItem(player, God.ZAMORAK) || hasGodItem(player, God.SARADOMIN))) { + // https://www.youtube.com/watch?v=Vg3Om-jZNIY + // Turn the player into a sheep + player.appearance.transformNPC(CastleWars.sheep) + // Send the player a chat dialog + sendDialogue(player, "I pity your faith in my brothers. I shall bless you with some time in the most holy of forms; maybe its wisdom will rub off on you and you'll see the error of your ways.") + transformed = true + } + if (player.attributes[CastleWars.portalAttribute] == CastleWars.zamorakName + && hasGodItem(player, God.SARADOMIN) || hasGodItem(player, God.GUTHIX)) + { + // https://youtu.be/hmF-CU9OEY4?t=63 + // Turn the player into an imp! + player.appearance.transformNPC(CastleWars.imp) + // Send the player a chat dialog + sendDialogue(player, "You're wearing objects of my ignorant brothers and you come to me? Such treachery must be rewarded! Enjoy some time in the most mischievous of forms.") + transformed = true + } + if (player.attributes[CastleWars.portalAttribute] == CastleWars.saradominName + && hasGodItem(player, God.ZAMORAK) || hasGodItem(player, God.GUTHIX)) + { + // https://www.youtube.com/watch?v=Vg3Om-jZNIY + // Turn the player into a rabbit! + player.appearance.transformNPC(CastleWars.rabbit) + // Send the player a chat dialog + sendDialogue(player, "You wear objects of my foolish brothers? Perhaps some time spent as the lowliest of forms will help you appreciate the gifts that I can bestow upon my followers.") + transformed = true + } + + if (transformed) { + // Remove the tabs + player.interfaceManager.removeTabs(0, 1, 2, 3, 4, 5, 6, 11, 12) + // Disable player run + player.walkingQueue.isRunDisabled = true + } + + // Remove the join portal attribute + player.removeAttribute(CastleWars.portalAttribute) + + // Open the white text overlay + player.interfaceManager.openOverlay(Component(Components.CASTLEWARS_STATUS_OVERLAY_57)) + } + + override fun exitArea(player: Player) { + super.exitArea(player) + // Remove player from waiting room set (whichever one that is) + waitingSaradominPlayers.remove(player) + waitingZamorakPlayers.remove(player) + } + + override fun tick() { + var nextStart = Int.MAX_VALUE + // The game will start when there's enough players and CastleWarsGameArea.ticksLeftInGame = -5 minutes + if (CastleWarsGameArea.ticksLeftInGame >= 0) { + // A game is going on, display 5 minutes + remaining game time + nextStart = CastleWarsGameArea.ticksLeftInGame + CastleWars.gameCooldownMinutes * ticksPerMinute + } + else if (waitingSaradominPlayers.isEmpty() || waitingZamorakPlayers.isEmpty()) { + // A game is not going and there aren't enough players - Keep the game over time to the current value + CastleWarsGameArea.ticksLeftInGame = -1 + } + else { + // There are enough players - Set nextStart to gameCooldownMinutes + ticksLeftInGame + nextStart = CastleWars.gameCooldownMinutes * ticksPerMinute + CastleWarsGameArea.ticksLeftInGame + } + + for (player in waitingSaradominPlayers + waitingZamorakPlayers) { + CastleWarsOverlay.sendLobbyUpdate( + player, + waitingSaradominPlayers.isNotEmpty() && waitingZamorakPlayers.isNotEmpty() || CastleWarsGameArea.ticksLeftInGame >= 0, + (nextStart - 1) / ticksPerMinute + 1 // Displays max 5 minutes, min 1 minute, seems authentic + ) + } + + if (nextStart <= 0) { + CastleWarsGameArea.startGame() + } + } + +} diff --git a/Server/src/main/content/minigame/clanwars/CWChallengeOption.java b/Server/src/main/content/minigame/clanwars/CWChallengeOption.java new file mode 100644 index 0000000..2f472c8 --- /dev/null +++ b/Server/src/main/content/minigame/clanwars/CWChallengeOption.java @@ -0,0 +1,87 @@ +package content.minigame.clanwars; + +import core.game.activity.ActivityManager; +import core.game.interaction.Option; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.request.RequestModule; +import core.game.node.entity.player.link.request.RequestType; +import core.game.system.communication.ClanRank; +import core.plugin.Plugin; + +/** + * Handles the Clan wars challenge option. + * @author Emperor + * @versuib 1,9 + */ +public final class CWChallengeOption extends OptionHandler { + + /** + * The challenge option. + */ + public static final Option OPTION = new Option("Challenge", 0); + + /** + * The request type. + */ + private static final RequestType REQUEST_TYPE = new RequestType("Sending challenge request...", ":clanreq:", getModule()) { + @Override + public boolean canRequest(Player player, Player target) { + if (player.getCommunication().getClan() == null) { + player.getPacketDispatch().sendMessage("You have to be in a clan to challenge players."); + return false; + } + if (player.getCommunication().getClan().getRank(player).ordinal() < ClanRank.CAPTAIN.ordinal()) { + player.getPacketDispatch().sendMessage("Your clan rank is not high enough to challenge other clans."); + return false; + } + if (player.getCommunication().getClan().getClanWar() != null) { + player.getPacketDispatch().sendMessage("Your clan is already in a war."); + return false; + } + if (target.getCommunication().getClan() == null) { + player.getPacketDispatch().sendMessage("This player is not in a clan."); + return false; + } + if (target.getCommunication().getClan().getRank(target).ordinal() < ClanRank.CAPTAIN.ordinal()) { + player.getPacketDispatch().sendMessage("This player's clan rank is not high enough to accept challenges."); + return false; + } + if (target.getCommunication().getClan().getClanWar() != null) { + player.getPacketDispatch().sendMessage("This player's clan is already in a war."); + return false; + } + if (target.getCommunication().getClan() == player.getCommunication().getClan()) { + player.getPacketDispatch().sendMessage("You can't challenge someone from your own clan."); + return false; + } + return true; + } + }; + + @Override + public Plugin newInstance(Object arg) throws Throwable { + OPTION.setHandler(this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + player.getRequestManager().request((Player) node, REQUEST_TYPE); + return true; + } + + /** + * Gets the request module. + * @return The module. + */ + private static RequestModule getModule() { + return new RequestModule() { + @Override + public void open(Player player, Player target) { + ActivityManager.start(player, "Clan wars", false, target); + } + }; + } +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/clanwars/ClanWarsActivityPlugin.java b/Server/src/main/content/minigame/clanwars/ClanWarsActivityPlugin.java new file mode 100644 index 0000000..8dc12e8 --- /dev/null +++ b/Server/src/main/content/minigame/clanwars/ClanWarsActivityPlugin.java @@ -0,0 +1,497 @@ +package content.minigame.clanwars; + +import java.util.ArrayList; +import java.util.List; + +import core.game.component.Component; +import core.game.activity.ActivityPlugin; +import core.plugin.Initializable; +import content.global.skill.summoning.familiar.Familiar; +import content.global.skill.summoning.pet.Pet; +import core.game.interaction.Option; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.impl.PulseManager; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.communication.ClanEntry; +import core.game.system.communication.ClanRepository; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.map.build.DynamicRegion; +import core.game.world.map.zone.RegionZone; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneType; +import core.game.world.map.zone.impl.MultiwayCombatZone; +import core.game.world.update.flag.chunk.AnimateObjectUpdateFlag; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; +import core.tools.RandomFunction; + +import static core.api.ContentAPIKt.*; + +/** + * Handles the clan wars activity. + * @author Emperor + */ +@Initializable +public final class ClanWarsActivityPlugin extends ActivityPlugin { + + /** + * The first clan. + */ + private ClanRepository firstClan; + + /** + * The second clan. + */ + private ClanRepository secondClan; + + /** + * The first clan's players. + */ + private List firstClanPlayers = new ArrayList<>(20); + + /** + * The second clan's players. + */ + private List secondClanPlayers = new ArrayList<>(20); + + /** + * The list of viewing players. + */ + private List viewingPlayers = new ArrayList<>(20); + + /** + * The amount of ticks. + */ + private int ticks; + + /** + * The updating pulse. + */ + private Pulse pulse; + + /** + * The attack option. + */ + private static final Option ATTACK_OPTION = new Option("Attack", 0).setHandler(new OptionHandler() { + + @Override + public boolean handle(Player player, Node node, String option) { + player.getProperties().getCombatPulse().attack(node); + return true; + } + + @Override + public boolean isWalk() { + return false; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + return this; + } + + @Override + public boolean isDelayed(Player player) { + return false; + } + + }); + + /** + * Constructs a new {@code ClanWarsActivityPlugin} {@code Object}. + */ + public ClanWarsActivityPlugin() { + super("Clan wars", true, false, true); + } + + @Override + public boolean start(Player player, boolean login, Object... args) { + Player other = (Player) args[0]; + firstClan = player.getCommunication().getClan(); + secondClan = other.getCommunication().getClan(); + firstClan.setClanWar(this); + secondClan.setClanWar(this); + sendWarDeclaration(firstClan.getPlayers()); + sendWarDeclaration(secondClan.getPlayers()); + handleWall(); + join(player); + join(other); + return true; + } + + /** + * Handles the wall in the middle of the battlefield. + */ + private void handleWall() { + int offset = 0; + for (int x = 5; x < 54; x++) { + offset = (offset + 1) % 3; + SceneryBuilder.add(new Scenery(28174 + offset, base.transform(x, 64, 0))); + } + GameWorld.getPulser().submit(pulse = new Pulse(200) { + @Override + public boolean pulse() { + for (int x = 5; x < 54; x++) { + Location l = base.transform(x, 64, 0); + Scenery object = RegionManager.getObject(l); + if (object != null) { + Animation anim = Animation.create(7386 + ((object.getId() - 28174) % 3)); + anim.setObject(object); + RegionManager.getRegionChunk(l).flag(new AnimateObjectUpdateFlag(anim)); + } + } + GameWorld.getPulser().submit(new Pulse(5) { + @Override + public boolean pulse() { + for (int x = 5; x < 54; x++) { + Location l = base.transform(x, 64, 0); + Scenery object = RegionManager.getObject(l); + if (object != null) { + SceneryBuilder.remove(object); + } + } + return true; + } + }); + super.setTicksPassed(250); + sendGameData(); + if (firstClanPlayers.isEmpty() || secondClanPlayers.isEmpty()) { + finishWar(); + } + return true; + } + }); + } + + /** + * Ends the war. + */ + public void finishWar() { + firstClan.setClanWar(null); + secondClan.setClanWar(null); + int firstInterfaceId = firstClanPlayers.isEmpty() ? 650 : 651; + int secondInterfaceId = firstClanPlayers.isEmpty() ? 651 : 650; + String[] message = new String[] { "Your clan has been defeated!", "Your clan is victorious!" }; + for (Player p : firstClanPlayers) { + p.getProperties().setTeleportLocation(getLeaveLocation()); + p.getInterfaceManager().openComponent(firstInterfaceId); + p.getPacketDispatch().sendMessage(message[firstInterfaceId - 650]); + p.fullRestore(); + PulseManager.cancelDeathTask(p); + } + for (Player p : secondClanPlayers) { + p.getProperties().setTeleportLocation(getLeaveLocation()); + p.getInterfaceManager().openComponent(secondInterfaceId); + p.getPacketDispatch().sendMessage(message[secondInterfaceId - 650]); + p.fullRestore(); + PulseManager.cancelDeathTask(p); + } + for (Player p : viewingPlayers) { + p.getProperties().setTeleportLocation(getLeaveLocation()); + if (p.getCommunication().getClan() == firstClan) { + p.getInterfaceManager().openComponent(firstInterfaceId); + p.getPacketDispatch().sendMessage(message[firstInterfaceId - 650]); + } else { + p.getInterfaceManager().openComponent(secondInterfaceId); + p.getPacketDispatch().sendMessage(message[secondInterfaceId - 650]); + } + } + } + + /** + * Sends the game data for all players in the game. + */ + public void sendGameData() { + for (Player p : firstClanPlayers) { + sendGameData(p); + } + for (Player p : secondClanPlayers) { + sendGameData(p); + } + for (Player p : viewingPlayers) { + sendGameData(p); + } + } + + /** + * Sends the game data for the player. + * @param p The player. + */ + public void sendGameData(Player p) { + int value = 0; + boolean first = p.getCommunication().getClan() == firstClan; + String name = firstClan.getName(); + if (first) { + value |= firstClanPlayers.size() << 5; + value |= secondClanPlayers.size() << 14; + } else { + name = secondClan.getName(); + value |= secondClanPlayers.size() << 5; + value |= firstClanPlayers.size() << 14; + } + if (pulse.getTicksPassed() < 200) { + value |= (200 - pulse.getTicksPassed()) << 23; + } + setVarp(p, 1147, value); + p.getPacketDispatch().sendString(name, 265, 2); + } + + @Override + public boolean teleport(Entity e, int type, Node node) { + if (type != -1 && type != 2 && e instanceof Player) { + ((Player) e).getPacketDispatch().sendMessage("You can't teleport away from a war."); + return false; + } + return true; + } + + @Override + public boolean enter(Entity e) { + if (e instanceof Player) { + Player player = (Player) e; + player.getInteraction().set(ATTACK_OPTION); + player.getInteraction().remove(Option._P_ASSIST); + player.getSkullManager().setSkullCheckDisabled(true); + player.getSkullManager().setWilderness(true); + player.getInterfaceManager().openOverlay(new Component(265)); + } else if (e instanceof Familiar && !(e instanceof Pet)) { + Familiar familiar = (Familiar) e; + if (familiar.isCombatFamiliar()) { + familiar.transform(familiar.getOriginalId() + 1); + } + } + return true; + } + + @Override + public boolean death(Entity e, Entity killer) { + if (e instanceof Player) { + return enterViewingRoom((Player) e); + } + return false; + } + + /** + * Enters the viewing room. + * @param player The player. + * @return {@code True} if successfully entered the viewing room. + */ + public boolean enterViewingRoom(Player player) { + Location destination = null; + if (player.getCommunication().getClan() == firstClan) { + remove(player, firstClanPlayers); + destination = base.transform(55 + RandomFunction.randomize(3), 51 + RandomFunction.randomize(11), 0); + } else if (player.getCommunication().getClan() == secondClan) { + remove(player, secondClanPlayers); + destination = base.transform(55 + RandomFunction.randomize(3), 66 + RandomFunction.randomize(11), 0); + } else { + return false; + } + player.getProperties().setTeleportLocation(destination); + viewingPlayers.add(player); + sendGameData(); + return true; + } + + @Override + public boolean continueAttack(Entity e, Node target, CombatStyle style, boolean message) { + if (e instanceof Familiar) { + e = ((Familiar) e).getOwner(); + } + if (target instanceof Familiar) { + target = ((Familiar) target).getOwner(); + } + if (e instanceof Player && target instanceof Player) { + Player player = (Player) e; + Player other = (Player) target; + ClanRepository clan = player.getCommunication().getClan(); + if (pulse.isRunning()) { + player.getPacketDispatch().sendMessage("The war hasn't started yet."); + return false; + } + if (!firstClanPlayers.contains(player) && !secondClanPlayers.contains(player)) { + return false; + } + if (other.getCommunication().getClan() == clan) { + player.getPacketDispatch().sendMessage("You can only attack players in a different clan."); + return false; + } + if (!firstClanPlayers.contains(other) && !secondClanPlayers.contains(other)) { + player.getPacketDispatch().sendMessage("You can't attack this player."); + return false; + } + } + return true; + } + + /** + * Removes the player from the game. + * @param player The player. + * @param players The players list. + */ + public void remove(Player player, List players) { + players.remove(player); + if (!pulse.isRunning() && players.isEmpty()) { + finishWar(); + } + } + + @Override + public boolean interact(Entity e, Node target, Option option) { + if (target instanceof Scenery) { + Scenery object = (Scenery) target; + if (object.getId() == 28214 || object.getId() == 28140) { + e.getProperties().setTeleportLocation(getLeaveLocation()); + return true; + } + } + return false; + } + + @Override + public boolean leave(Entity e, boolean logout) { + if (e instanceof Player) { + Player player = (Player) e; + player.getInterfaceManager().closeOverlay(); + player.getInteraction().remove(ATTACK_OPTION); + if (firstClanPlayers.contains(player)) { + remove(player, firstClanPlayers); + } else if (secondClanPlayers.contains(player)) { + remove(player, secondClanPlayers); + } else { + viewingPlayers.remove(player); + } + sendGameData(); + player.getSkullManager().setSkullCheckDisabled(false); + player.getSkullManager().setWilderness(false); + if (logout) { + e.setLocation(getLeaveLocation()); + } + } else if (e instanceof Familiar && !(e instanceof Pet)) { + Familiar familiar = (Familiar) e; + if (familiar.isCombatFamiliar()) { + familiar.reTransform(); + } + } + return true; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + if (identifier.equals("join")) { + join((Player) args[0]); + return true; + } + if (identifier.equals("leavefc")) { + Player p = (Player) args[0]; + p.getProperties().setTeleportLocation(getLeaveLocation()); + return true; + } + return null; + } + + /** + * Gets the leaving location. + * @return The leaving location. + */ + private static Location getLeaveLocation() { + Location l = Location.create(3265 + RandomFunction.randomize(13), 3675 + RandomFunction.randomize(18), 0); + while (!RegionManager.isTeleportPermitted(l)) { + l = l.transform(1, 1, 0); + } + return l; + } + + /** + * Makes the player join the game. + * @param player The player. + */ + public void join(Player player) { + if (!pulse.isRunning()) { + enterViewingRoom(player); + return; + } + boolean first = player.getCommunication().getClan() == firstClan; + if (first) { + if (firstClanPlayers.contains(player)) { + return; + } + firstClanPlayers.add(player); + player.getProperties().setTeleportLocation(base.transform(34 + RandomFunction.randomize(4), 10, 0)); + } else { + if (secondClanPlayers.contains(player)) { + return; + } + secondClanPlayers.add(player); + player.getProperties().setTeleportLocation(base.transform(26 + RandomFunction.randomize(4), 118, 0)); + } + sendGameData(); + } + + /** + * Sends messages to the list of players. + * @param players The players list. + */ + private static void sendWarDeclaration(List players) { + Location check = Location.create(3272, 3682, 0); + for (ClanEntry e : players) { + Player p = e.getPlayer(); + if (p.getLocation().withinDistance(check, 128)) { + p.getPacketDispatch().sendMessage("Your clan has been challenged to a clan war!"); + p.getPacketDispatch().sendMessage("Step through the purple portal in the Challenge Hall."); + p.getPacketDispatch().sendMessage("Battle will commence in 2 minutes."); + } + } + } + + @Override + public void configure() { + setZoneType(ZoneType.SAFE.getId()); + DynamicRegion[] regions = DynamicRegion.create(new ZoneBorders(3264, 3712, 3328, 3840)); + setRegionBase(regions); + int x = base.getX(); + int y = base.getY() + 20; + RegionZone multi = new RegionZone(MultiwayCombatZone.getInstance(), new ZoneBorders(x, y, x + 63, y + 88)); + for (DynamicRegion r : regions) { + r.setMulticombat(true); + r.getRegionZones().add(multi); + r.setRegionTimeOut(250); + r.setMusicId(442); + } + } + + @Override + public Location getSpawnLocation() { + return null; + } + + @Override + public ActivityPlugin newInstance(Player p) throws Throwable { + return new ClanWarsActivityPlugin(); + } + + /** + * Gets the ticks. + * @return The ticks. + */ + public int getTicks() { + return ticks; + } + + /** + * Sets the ticks. + * @param ticks The ticks to set. + */ + public void setTicks(int ticks) { + this.ticks = ticks; + } + +} diff --git a/Server/src/main/content/minigame/clanwars/ClanWarsChallengeRoom.java b/Server/src/main/content/minigame/clanwars/ClanWarsChallengeRoom.java new file mode 100644 index 0000000..7b3d967 --- /dev/null +++ b/Server/src/main/content/minigame/clanwars/ClanWarsChallengeRoom.java @@ -0,0 +1,98 @@ +package content.minigame.clanwars; + +import core.game.interaction.Option; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneBuilder; +import core.game.world.map.zone.ZoneRestriction; +import core.game.world.map.zone.impl.WildernessZone; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.plugin.ClassScanner; + +/** + * Handles the clan wars challenge room. + * @author Emperor + */ +@Initializable +public final class ClanWarsChallengeRoom extends MapZone implements Plugin { + + /** + * Constructs a new {@code ClanWarsChallengeRoom} {@code Object}. + */ + public ClanWarsChallengeRoom() { + super("clan wars cr", true, ZoneRestriction.RANDOM_EVENTS); + } + + @Override + public void configure() { + register(new ZoneBorders(3264, 3672, 3279, 3695)); + } + + @Override + public boolean enter(Entity e) { + if (e instanceof Player) { + Player p = (Player) e; + p.getSkullManager().setWildernessDisabled(true); + p.getSkullManager().setWilderness(false); + p.getInterfaceManager().closeOverlay(); + p.getInteraction().remove(Option._P_ASSIST); + p.getInteraction().set(CWChallengeOption.OPTION); + } + return super.enter(e); + } + + @Override + public boolean leave(final Entity e, final boolean logout) { + if (e instanceof Player) { + Player p = (Player) e; + p.getSkullManager().setWildernessDisabled(false); + p.getInteraction().remove(CWChallengeOption.OPTION); + p.getInteraction().set(Option._P_ASSIST); + if (WildernessZone.isInZone(e)) { + WildernessZone.show(p); + p.getSkullManager().setWilderness(true); + } + } + return super.leave(e, logout); + } + + @Override + public boolean interact(Entity e, Node target, Option option) { + if (target instanceof Scenery) { + Scenery object = (Scenery) target; + Player player = (Player) e; + if (object.getId() == 28213) { + if (player.getCommunication().getClan() == null) { + player.getPacketDispatch().sendMessage("You have to be in a clan to enter this portal."); + } else if (player.getCommunication().getClan().isDefault()) { + player.sendMessage("You can't use the main clan chat for this."); + return true; + } else if (player.getCommunication().getClan().getClanWar() == null) { + player.getPacketDispatch().sendMessage("Your clan has to be in a war."); + } else { + player.getCommunication().getClan().getClanWar().fireEvent("join", player); + } + return true; + } + } + return false; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ZoneBuilder.configure(this); + ClassScanner.definePlugin(new CWChallengeOption()); + return this; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + +} diff --git a/Server/src/main/content/minigame/duel/AfrahDialogue.kt b/Server/src/main/content/minigame/duel/AfrahDialogue.kt new file mode 100644 index 0000000..d480392 --- /dev/null +++ b/Server/src/main/content/minigame/duel/AfrahDialogue.kt @@ -0,0 +1,174 @@ +package content.minigame.duel + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable + +/** + * @author qmqz + */ + +@Initializable +class AfrahDialogue : DialoguePlugin { + + private val conversations = arrayOf (0, 4, 10, 11, 15, 17, 20, 22, 23, 24, 29, 32) + + override fun open(vararg args: Any): Boolean { + player(FacialExpression.ASKING, "Hi!") + stage = conversations.random() + npc = args[0] as NPC + return true + } + + constructor() {} + constructor(player: Player?) : super(player) {} + + override fun getIds(): IntArray { + return intArrayOf(968) + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> { + npc(FacialExpression.ASKING, "Ooh. This is exciting!") + stage++ + } + 1 -> { + player(FacialExpression.ASKING, "Yup!") + stage = 99 + } + 2 -> { + npc(FacialExpression.ASKING, "I wouldn't want to be the poor guy that has to", "clean up after the duels.") + stage++ + } + 3 -> { + player(FacialExpression.ASKING, "Me neither.") + stage = 99 + } + 4 -> { + npc(FacialExpression.ASKING, "My son just won his first duel!") + stage++ + } + 5 -> { + player(FacialExpression.ASKING, "Congratulations!") + stage++ + } + 6 -> { + npc(FacialExpression.ASKING, "He ripped his opponent in half!") + stage++ + } + 7 -> { + player(FacialExpression.ASKING, "That's gotta hurt!") + stage++ + } + 8 -> { + npc(FacialExpression.ASKING, "He's only 10 as well!") + stage++ + } + 9 -> { + player(FacialExpression.ASKING, "You gotta start 'em young!") + stage = 99 + } + 10 -> { + npc(FacialExpression.ASKING, "Hmph.") + stage = 99 + } + 11 -> { + npc(FacialExpression.ASKING, "My favourite fighter is Mubariz!") + stage++ + } + 12 -> { + player(FacialExpression.ASKING, "The guy at the information kiosk?") + stage++ + } + 13 -> { + npc(FacialExpression.ASKING, "Yeah! He rocks!") + stage++ + } + 14 -> { + player(FacialExpression.ASKING, "Takes all sorts, I guess.") + stage = 99 + } + 15 -> { + npc(FacialExpression.ASKING, "Hi! I'm here to watch the duels!") + stage++ + } + 16 -> { + player(FacialExpression.ASKING, "Me too!") + stage = 99 + } + 17 -> { + npc(FacialExpression.ASKING, "Did you know they think this place dates","back to the second age?!") + stage++ + } + 18 -> { + player(FacialExpression.ASKING, "Really?") + stage++ + } + 19 -> { + npc(FacialExpression.ASKING, "Yeah. The guy at the information kiosk was telling me.") + stage = 99 + } + 20 -> { + npc(FacialExpression.ANGRY, "Can't you see I'm watching the duels?") + stage++ + } + 21 -> { + player(FacialExpression.SAD, "I'm sorry!") + stage = 99 + } + 22 -> { + npc(FacialExpression.ASKING, "Well. This beats doing the shopping!") + stage = 99 + } + 23 -> { + npc(FacialExpression.ASKING, "Hi!") + stage = 99 + } + 24 -> { + npc(FacialExpression.ASKING, "Knock knock!") + stage++ + } + 25 -> { + player(FacialExpression.ASKING, "Who's there?") + stage++ + } + 26 -> { + npc(FacialExpression.ASKING, "Boo!") + stage++ + } + 27 -> { + player(FacialExpression.ASKING, "Boo who?") + stage++ + } + 28 -> { + npc(FacialExpression.LAUGH, "Don't cry, it's just me!") + stage = 99 + } + 29 -> { + npc(FacialExpression.ASKING, "Why did the skeleton burp?") + stage++ + } + 30 -> { + player(FacialExpression.ASKING, "I don't know?") + stage++ + } + 31 -> { + npc(FacialExpression.ASKING, "'Cause it didn't have the guts to fart!") + stage = 99 + } + 32 -> { + npc(FacialExpression.ASKING, "Waaaaassssssuuuuupp?!.") + stage = 99 + } + 99 -> end() + } + return true + } + + override fun newInstance(player: Player): DialoguePlugin { + return AfrahDialogue(player) + } +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/duel/ChallengeOptionPlugin.java b/Server/src/main/content/minigame/duel/ChallengeOptionPlugin.java new file mode 100644 index 0000000..9f0e4db --- /dev/null +++ b/Server/src/main/content/minigame/duel/ChallengeOptionPlugin.java @@ -0,0 +1,40 @@ +package content.minigame.duel; + +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.plugin.Plugin; +import static core.api.ContentAPIKt.*; + +/** + * Handles the challenge option for dueling. + * @author Vexia + * + */ +public class ChallengeOptionPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + DuelArenaActivity.CHALLENGE_OPTION.setHandler(this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + Player other = (Player) node; + if (other.getInterfaceManager().isOpened() || other.getExtension(DuelSession.class) != null) { + player.getPacketDispatch().sendMessage("Other player is busy at the moment."); + return true; + } + if (other.getRequestManager().getTarget() == player && other.getAttribute("duel:partner") == player) { + player.getRequestManager().request(other, other.getAttribute("duel:staked", false) ? DuelArenaActivity.STAKE_REQUEST : DuelArenaActivity.FRIEND_REQUEST); + return true; + } + player.getInterfaceManager().open(DuelArenaActivity.DUEL_TYPE_SELECT); + player.setAttribute("duel:staked", false); + player.setAttribute("duel:partner", other); + setVarp(player, 283, 1 << 26); + return true; + } + +} diff --git a/Server/src/main/content/minigame/duel/DuelArea.java b/Server/src/main/content/minigame/duel/DuelArea.java new file mode 100644 index 0000000..6b78d49 --- /dev/null +++ b/Server/src/main/content/minigame/duel/DuelArea.java @@ -0,0 +1,595 @@ +package content.minigame.duel; + +import core.cache.def.impl.SceneryDefinition; +import core.game.container.Container; +import core.game.container.impl.EquipmentContainer; +import core.game.dialogue.DialogueAction; +import core.game.interaction.Option; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.impl.PulseManager; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.HintIconManager; +import core.game.node.entity.player.link.prayer.PrayerType; +import content.global.skill.summoning.familiar.Familiar; +import core.game.node.item.GroundItem; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneRestriction; +import core.plugin.Plugin; +import core.tools.RandomFunction; +import core.tools.StringUtils; +import core.ServerConstants; +import core.game.world.GameWorld; + +import java.util.ArrayList; +import java.util.List; + +/** + * Represents a dueling area. + * @author Vexia + * + */ +public class DuelArea extends MapZone { + + /** + * The respawn locations. + */ + public static final Location[] RESPAWN_LOCATIONS = new Location[] { Location.create(3371, 3275, 0), Location.create(3365, 3276, 0), Location.create(3366, 3274, 0), Location.create(3369, 3274, 0), Location.create(3372, 3275, 0), Location.create(3372, 3266, 0), Location.create(3371, 3269, 0), Location.create(3376, 3270, 0), Location.create(3376, 3273, 0), Location.create(3377, 3275, 0) }; + + /** + * The zone borders set for the area. + */ + private final ZoneBorders border; + + /** + * If this area has obstacles. + */ + private final boolean obstacles; + + /** + * The center location to determine starting points. + */ + private final Location center; + + /** + * The fight option. + */ + private static final Option FIGHT_OPTION = new Option("Fight", 0).setHandler(new OptionHandler() { + + @Override + public boolean handle(Player player, Node node, String option) { + player.getProperties().getCombatPulse().attack(node); + return true; + } + + @Override + public boolean isWalk() { + return false; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + return this; + } + + @Override + public boolean isDelayed(Player player) { + return false; + } + }); + + /** + * Constructs a new {@Code DuelArea} {@Code Object} + */ + public DuelArea() { + this(-1, null, false, null); + } + + /** + * Constructs a new {@Code DuelArea} {@Code Object} + * @param index the index. + * @param border the border. + * @param obstacles if there is obstacles. + */ + public DuelArea(int index, ZoneBorders border, boolean obstacles, Location center) { + super("Duel Area - " + index, true, ZoneRestriction.FIRES, ZoneRestriction.CANNON, ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.FOLLOWERS); + this.obstacles = obstacles; + this.border = border; + this.center = center; + } + + /** + * Starts a duel between two players. + * @param session the session. + */ + public void duel(final DuelSession session) { + Location[] locations = getStartLocations(session); + session.getPlayer().teleport(locations[0]); + session.getOther().teleport(locations[1]); + session.getPlayer().getInterfaceManager().close(); + session.getPlayer().getInterfaceManager().restoreTabs(); + session.getOther().getInterfaceManager().close(); + session.getOther().getInterfaceManager().restoreTabs(); + session.getPlayer().setAttribute("duel:icon", HintIconManager.registerHintIcon(session.getPlayer(), session.getOther())); + session.getOther().setAttribute("duel:icon", HintIconManager.registerHintIcon(session.getOther(), session.getPlayer())); + session.getPlayer().setAttribute("duel:ammo", new ArrayList(100)); + session.getOther().setAttribute("duel:ammo", new ArrayList(100)); + session.getPlayer().setAttribute("vengeance", false); + session.getOther().setAttribute("vengeance", false); + GameWorld.getPulser().submit(new Pulse(4, session.getPlayer(), session.getOther()) { + int count; + + @Override + public boolean pulse() { + String chat = count < 3 ? String.valueOf(3 - count) : "FIGHT!"; + session.getPlayer().sendChat(chat); + session.getOther().sendChat(chat); + return count++ >= 3; + } + + @Override + public void stop() { + super.stop(); + if (session.getPlayer().isActive() && session.getOther().isActive() && session.getFightState() != 2) { + session.setFightState(1); + session.getPlayer().getSkullManager().setSkullCheckDisabled(true); + session.getPlayer().getSkullManager().setWilderness(true); + session.getOther().getSkullManager().setSkullCheckDisabled(true); + session.getOther().getSkullManager().setWilderness(true); + session.getPlayer().getProperties().setMultiZone(true); + session.getOther().getProperties().setMultiZone(true); + } + } + }); + } + + @Override + public boolean interact(Entity e, Node target, Option option) { + if (!e.isPlayer()) { + return true; + } + Player p = e.asPlayer(); + final DuelSession session = getSession(p); + if (session == null) { + return true; + } + if (option.getName().equalsIgnoreCase("eat") && session.hasRule(DuelRule.NO_FOOD)) { + p.sendMessage("You can't eat in this fight."); + return true; + } + if (option.getName().equalsIgnoreCase("drink") && session.hasRule(DuelRule.NO_DRINKS)) { + p.sendMessage("You can't drink in this fight."); + return true; + } + if (option.getName().equalsIgnoreCase("wield") || option.getName().equalsIgnoreCase("wear") && target instanceof Item) { + if (session.isRestrictedEquipment(target.asItem())) { + p.sendMessage("You can't equip that during this duel."); + return true; + } + } + if (option.getName().equalsIgnoreCase("Summon") && !session.hasRule(DuelRule.ENABLE_SUMMONING)) { + p.sendMessage("You cannot summon familiars whilst in a duel."); + return true; + } + if (option.getName().equalsIgnoreCase("drop") && target instanceof Item) { + p.sendMessage("You cannot drop items whilst in a duel."); + return true; + } + switch (target.getId()) { + case 3203: + handleForfeit(p); + return true; + } + return super.interact(e, target, option); + } + + @Override + public boolean move(Entity entity, Location from, Location to) { + if (entity.isPlayer()) { + Player p = entity.asPlayer(); + DuelSession session = getSession(p); + if (session == null) { + return false; + } + return !session.hasRule(DuelRule.NO_MOVEMENT); + } + return super.move(entity, from, to); + } + + @Override + public boolean actionButton(Player player, int interfaceId, int buttonId, int slot, int itemId, int opcode) { + DuelSession session = getSession(player); + if (session == null) { + return true; + } + WeaponInterface inter = player.getExtension(WeaponInterface.class); + if (inter != null && interfaceId == inter.getId()) { + switch (buttonId) { + case 8: + case 10: + if (session.hasRule(DuelRule.NO_SPECIAL_ATTACKS)) { + player.sendMessage("You can't use special attacks during a duel."); + return true; + } + break; + } + } + switch (interfaceId) { + case 182: + player.sendMessage("You can't logout during a duel."); + return true; + case 271: + if (session.hasRule(DuelRule.NO_PRAYER)) { + player.getPrayer().toggle(PrayerType.get(buttonId)); + player.getPrayer().toggle(PrayerType.get(buttonId)); + player.sendMessage("Use of prayer has been turned off for this duel."); + return true; + } + break; + case 430: + if (session.hasRule(DuelRule.NO_MAGIC)) { + player.sendMessage("Use of prayer has been turned off for this duel."); + return true; + } + break; + } + return super.actionButton(player, interfaceId, buttonId, slot, itemId, opcode); + } + + @Override + public boolean continueAttack(Entity e, Node target, CombatStyle style, boolean message) { + if (e.isPlayer() && target instanceof Player && !checkAttack(e.asPlayer(), ((Player) target))) { + return false; + } + if (e instanceof Familiar && target instanceof Player) { + Familiar f = (Familiar) e; + Player o = f.getOwner(); + if (o != null && target.asPlayer() != getSession(o).getOpposite(o)) { + return false; + } + } + if (e instanceof Familiar && target instanceof Familiar) { + Familiar f = (Familiar) e; + Familiar t = (Familiar) target; + if (getSession(f.getOwner()).getOpposite(f.getOwner()) != t.getOwner()) { + return false; + } + } + if (e.isPlayer()) { + Player p = e.asPlayer(); + DuelSession session = getSession(p); + if (session == null) { + return false; + } + boolean canAttack = true; + switch (style) { + case MAGIC: + canAttack = !session.hasRule(DuelRule.NO_MAGIC); + break; + case MELEE: + canAttack = !session.hasRule(DuelRule.NO_MELEE); + break; + case RANGE: + canAttack = !session.hasRule(DuelRule.NO_RANGE); + break; + } + if (!canAttack) { + p.sendMessage(StringUtils.formatDisplayName(style.name().toLowerCase()) + " has been turned off for this duel."); + return false; + } + if (session.hasRule(DuelRule.FUN_WEAPONS) && (p.getEquipment().get(EquipmentContainer.SLOT_WEAPON) == null || !p.getEquipment().get(EquipmentContainer.SLOT_WEAPON).getDefinition().getConfiguration("fun_weapon", false))) { + p.sendMessages("This is a 'fun weapon' duel. You can only use flowers, basket of eggs, or a", "rubber chicken."); + return false; + } + if (target instanceof Familiar) { + Familiar f = (Familiar) target; + if (f.getOwner() != null && getSession(p).getOpposite(p) != f.getOwner()) { + p.sendMessage("You can't attack that familiar."); + return false; + } + } + } + return true; + } + + @Override + public boolean teleport(Entity e, int type, Node node) { + if (e.isPlayer()) { + e.asPlayer().getDialogueInterpreter().sendDialogue("Coward! You can't teleport from a duel."); + } + return false; + } + + @Override + public boolean enter(Entity e) { + if (e.isPlayer()) { + getSession(e.asPlayer()); + e.getProperties().setSafeZone(true); + e.getProperties().setSpawnLocation(RandomFunction.getRandomElement(RESPAWN_LOCATIONS)); + e.asPlayer().getInteraction().remove(DuelArenaActivity.CHALLENGE_OPTION); + e.asPlayer().getInteraction().set(FIGHT_OPTION); + } else if (e instanceof Familiar) { + Familiar f = (Familiar) e; + Player o = f.getOwner(); + if (o != null && !o.getFamiliarManager().hasPet()) { + DuelSession s = getSession(f.getOwner()); + if (s != null && s.hasRule(DuelRule.ENABLE_SUMMONING)) { + f.transform(); + } + } + f.getProperties().setMultiZone(true); + } + return super.enter(e); + } + + @SuppressWarnings("deprecation") + @Override + public boolean leave(Entity entity, boolean logout) { + entity.getProperties().setSafeZone(false); + if (entity instanceof Player) { + Player p = entity.asPlayer(); + if (logout) { + p.setLocation(RandomFunction.getRandomElement(RESPAWN_LOCATIONS)); + } + p.lock(1); + leave(p); + DuelSession session = getSession(p); + if (session == null) { + return true; + } + session.leave(p, logout ? 1 : p.getAttribute("duel:forfeit", false) ? 0 : 2); + remove(session.getOpposite(p)); + leave(session.getOpposite(p)); + } else if (entity instanceof Familiar) { + Familiar familiar = (Familiar) entity; + if (familiar.isCombatFamiliar()) { + familiar.reTransform(); + } + familiar.getProperties().setMultiZone(false); + } + return super.leave(entity, logout); + } + + @Override + public void configure() { + register(border); + } + + /** + * Handles the leaving of a player. + * @param p the player. + */ + private void leave(Player p) { + p.getProperties().setSafeZone(false); + if (p.getAttribute("duel:ammo", null) != null) { + List ammo = p.getAttribute("duel:ammo"); + Container c = new Container(40); + for (GroundItem item : ammo) { + if (item == null) { + continue; + } + if (item.isActive() && GroundItemManager.getItems().contains(item) && item.droppedBy(p)) { + GroundItemManager.destroy(item); + c.add(item); + } + } + p.getInventory().addAll(c); + } + p.getInteraction().remove(FIGHT_OPTION); + p.getSkullManager().setSkullCheckDisabled(false); + p.getSkullManager().setWilderness(false); + p.getProperties().setSpawnLocation(ServerConstants.HOME_LOCATION); + p.getProperties().setMultiZone(false); + p.getInteraction().set(DuelArenaActivity.CHALLENGE_OPTION); + } + + /** + * Forcefully removes a player. + * @param player the player. + */ + private static void remove(Player player) { + HintIconManager.removeHintIcon(player, player.getAttribute("duel:icon", -1)); + if (player.getExtension(DuelSession.class) != null) { + player.teleport(RandomFunction.getRandomElement(RESPAWN_LOCATIONS)); + } + } + + /** + * Handles the forfeit trapdoor. + * @param p the player. + */ + public static void handleForfeit(Player p) { + DuelSession session = getSession(p); + if (session == null) { + return; + } + if (session.getFightState() != 1) { + p.sendMessage("The duel has not started yet!"); + return; + } + if (session.hasRule(DuelRule.NO_FORFEIT)) { + p.getDialogueInterpreter().sendDialogue("Forfeit has been turned off for this duel."); + return; + } + p.getDialogueInterpreter().sendOptions("Do you wish to forfeit?", "Yes", "No"); + p.getDialogueInterpreter().addAction(new DialogueAction() { + @Override + public void handle(Player player, int buttonId) { + if (buttonId == 2) { + remove(player); + player.setAttribute("duel:forfeit", true); + } + } + }); + } + + /** + * Gets the starting locations for the session. + * @param session the session. + * @return the locations. + */ + public Location[] getStartLocations(DuelSession session) { + Location start = null; + Location[] locations = new Location[2]; + while (start == null) { + start = center.transform(RandomFunction.random(10), RandomFunction.random(session.hasRule(DuelRule.NO_MOVEMENT) ? 6 : 10), 0); + if (isValidLocation(start)) { + locations[locations[0] == null ? 0 : 1] = start; + if (session.hasRule(DuelRule.NO_MOVEMENT)) { + Location l = null; + if (!isValidLocation(l = start.transform(1, 0, 0))) { + if (!isValidLocation(l = start.transform(-1, 0, 0))) { + if (!isValidLocation(l = start.transform(1, 0, 0))) { + if (!isValidLocation(l = start.transform(-1, 0, 0))) { + locations[1] = start; + break; + } + } + } + } + start = l; + locations[1] = l; + break; + } + start = locations[1] == null ? null : start; + } else { + start = null; + } + } + return locations; + } + + @Override + public boolean startDeath(Entity entity, Entity killer) { + if (entity instanceof Player) { + Player k = killer instanceof Player ? killer.asPlayer() : killer instanceof Familiar ? ((Familiar) killer).getOwner() : null; + if (k != null) { + k.getImpactHandler().setDisabledTicks(10); + k.getSkills().heal(100); + k.lock(5); + } + } + return true; + } + + @Override + public boolean death(Entity e, Entity killer) { + if (e.isPlayer() && (killer.isPlayer() || killer instanceof Familiar)) { + Player k = killer instanceof Familiar ? ((Familiar) killer).getOwner() : killer.asPlayer(); + if (k != null) { + k.getSkills().heal(100); + PulseManager.cancelDeathTask(e); + } + } + return super.death(e, killer); + } + + /** + * Checks if the location is valid to start on. + * @param location the location. + * @return {@code True} if so. + */ + public boolean isValidLocation(Location location) { + return RegionManager.isTeleportPermitted(location) && RegionManager.getObject(location) == null; + } + + /** + * Checks the attack of a player. + * @param player the player. + * @param target the target. + * @return {@code True} if so. + */ + public boolean checkAttack(Player player, Player target) { + DuelSession session = getSession(player); + if (session == null) { + return false; + } + if (session.getOpposite(player) != target) { + player.sendMessage("You can only attack your opponent!"); + return false; + } + if (session.getFightState() != 1) { + player.sendMessage("You can't attack yet!"); + return false; + } + return true; + } + + /** + * Gets the duel session for the player. + * @param player the player. + * @return the duel session. + */ + public static DuelSession getSession(Player player) { + DuelSession session = player.getExtension(DuelSession.class); + if (session == null) { + remove(player); + } + return session; + } + + /** + * Gets the obstacles. + * @return the obstacles. + */ + public boolean isObstacles() { + return obstacles; + } + + /** + * Gets the border. + * @return the border. + */ + public ZoneBorders getBorder() { + return border; + } + + /** + * Gets the center. + * @return the center. + */ + public Location getCenter() { + return center; + } + + /** + * Handles the forfeit trapdoor plugin. + * @author Vexia + * + */ + public static class ForfeitTrapdoorPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(3203).getHandlers().put("option:forfeit", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + handleForfeit(player); + return true; + } + + @Override + public Location getDestination(Node node, Node n) { + Location loc = null; + if (node instanceof Player) { + DuelSession session = getSession(node.asPlayer()); + if (session != null && session.hasRule(DuelRule.NO_MOVEMENT)) { + loc = node.getLocation(); + } + } + return loc; + } + } +} diff --git a/Server/src/main/content/minigame/duel/DuelArenaActivity.java b/Server/src/main/content/minigame/duel/DuelArenaActivity.java new file mode 100644 index 0000000..75f4907 --- /dev/null +++ b/Server/src/main/content/minigame/duel/DuelArenaActivity.java @@ -0,0 +1,231 @@ +package content.minigame.duel; + +import java.util.ArrayList; +import java.util.List; + +import core.game.component.Component; +import core.game.activity.ActivityPlugin; +import core.game.interaction.Option; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.impl.PulseManager; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.request.RequestType; +import core.game.world.map.Location; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneBuilder; +import core.plugin.Initializable; +import core.plugin.ClassScanner; +import core.tools.RandomFunction; + +import static core.api.ContentAPIKt.*; + +/** + * Handles the Duel Arena activity. + * @author Emperor + * @author Vexia + * + */ +@Initializable +public final class DuelArenaActivity extends ActivityPlugin { + + /** + * The friendly duel request. + */ + public static final RequestType FRIEND_REQUEST = new RequestType("Sending duel offer...", ":duelfriend:", new DuelReqModule(false)); + + /** + * The staked duel request. + */ + public static final RequestType STAKE_REQUEST = new RequestType("Sending duel offer...", ":duelstake:", new DuelReqModule(true)); + + /** + * The dueling areas. + */ + public static final DuelArea[] DUEL_AREAS = new DuelArea[] { new DuelArea(0, new ZoneBorders(3332, 3244, 3357, 3258), false, Location.create(3345, 3251, 0)), new DuelArea(1, new ZoneBorders(3364, 3244, 3388, 3259), true, Location.create(3378, 3251, 0)), new DuelArea(2, new ZoneBorders(3333, 3224, 3357, 3239), true, Location.create(3345, 3231, 0)), new DuelArea(3, new ZoneBorders(3364, 3225, 3388, 3240), false, Location.create(3376, 3231, 0)), new DuelArea(4, new ZoneBorders(3333, 3205, 3357, 3220), false, Location.create(3346, 3212, 0)), new DuelArea(5, new ZoneBorders(3364, 3206, 3388, 3221), true, Location.create(3377, 3213, 0)) }; + + /** + * The challenge option. + */ + public static final Option CHALLENGE_OPTION = new Option("Challenge", 0); + + /** + * The select duel type component. + */ + public static final Component DUEL_TYPE_SELECT = new Component(640); + + /** + * The overlay. + */ + private static final Component OVERLAY = new Component(638); + + /** + * The scoreboard. + */ + private static final String[] SCOREBOARD = new String[50]; + + /** + * Constructs a new {@code DuelArenaActivity} {@code Object}. + */ + public DuelArenaActivity() { + super("Duel arena", false, false, true); + } + + @Override + public boolean enter(Entity e) { + if (e instanceof Player) { + Player player = (Player) e; + player.getInterfaceManager().openOverlay(OVERLAY); + player.getInteraction().set(CHALLENGE_OPTION); + setVarp(player, 286, 0); + } + return super.enter(e); + } + + @Override + public boolean leave(Entity e, boolean logout) { + if (e instanceof Player) { + Player player = (Player) e; + player.getInterfaceManager().closeOverlay(); + player.getInteraction().remove(CHALLENGE_OPTION); + } + return super.leave(e, logout); + } + + @Override + public ActivityPlugin newInstance(Player p) throws Throwable { + return this; + } + + @Override + public Location getSpawnLocation() { + return null; + } + + @Override + public boolean continueAttack(Entity e, Node target, CombatStyle style, boolean message) { + if (e.isPlayer() && e.asPlayer().getZoneMonitor().getZones().size() > 1) { + return super.continueAttack(e, target, style, message); + } + return false; + } + + @Override + public boolean interact(Entity e, Node target, Option o) { + if (e.isPlayer()) { + switch (target.getId()) { + case 3192: + openScoreboard(e.asPlayer()); + return true; + } + } + return super.interact(e, target, o); + } + + @Override + public boolean death(Entity e, Entity killer) { + if (e.isPlayer() && e.asPlayer().getZoneMonitor().getZones().size() > 1) { + return true; + } + if (e instanceof Player && killer instanceof Player) { + e.getSkills().heal(100); + PulseManager.cancelDeathTask(e); + return true; + } + return true; + } + + @Override + public void configure() { + for (DuelArea area : DUEL_AREAS) { + ZoneBuilder.configure(area); + } + parseScoreboard(); + register(new ZoneBorders(3325, 3201, 3396, 3280)); + ClassScanner.definePlugin(new DuelArea.ForfeitTrapdoorPlugin()); + ClassScanner.definePlugins(new DuelSession(null, null, false), new DuelComponentPlugin(), new ChallengeOptionPlugin()); + } + + /** + * Opens the scoreboard. + * @param player the player. + */ + public static void openScoreboard(Player player) { + player.lock(2); + parseScoreboard(); + player.getInterfaceManager().open(new Component(632)); + int index = 0; + for (int i = 16; i < 65; i++) { + player.getPacketDispatch().sendString(SCOREBOARD[index] == null ? "" : SCOREBOARD[index], 632, i - 1); + index++; + } + } + + /** + * Parses the scoreboard data from the database. + */ + public static void parseScoreboard() { + /*Connection connection = SQLManager.getConnection(); + if (connection == null) { + return; + } + java.sql.PreparedStatement statement; + try { + statement = connection.prepareStatement("SELECT * FROM duel_scoreboard WHERE id <= 50"); + ResultSet set = statement.executeQuery(); + while (set.next()) { + SCOREBOARD[set.getInt(1) - 1] = set.getString(2); + } + statement = connection.prepareStatement("DELETE FROM duel_scoreboard WHERE id > 50"); + statement.executeUpdate(); + } catch (SQLException e) { + SQLManager.close(connection); + e.printStackTrace(); + } + SQLManager.close(connection);*/ + } + + /** + * Inserts an entry into the scoreboard. + * @param winner the winner. + * @param looser the looser. + */ + public static void insertEntry(Player winner, Player looser) { + /*String entry = winner.getUsername() + " (" + winner.getProperties().getCurrentCombatLevel() + ") beat " + looser.getUsername() + " (" + looser.getProperties().getCurrentCombatLevel() + ")"; + Connection connection = SQLManager.getConnection(); + if (connection == null) { + return; + } + java.sql.PreparedStatement statement; + try { + statement = connection.prepareStatement("UPDATE duel_scoreboard SET id = ID + 1"); + statement.executeUpdate(); + statement = connection.prepareStatement("INSERT INTO duel_scoreboard (id,entry) VALUES(?,?)"); + statement.setInt(1, 1); + statement.setString(2, entry); + statement.executeUpdate(); + } catch (SQLException e) { + SQLManager.close(connection); + e.printStackTrace(); + } + SQLManager.close(connection);*/ + } + + /** + * Gets the dueling area. + * @param obstacles if we're using obstacles. + * @return {@code DuelArea} the area. + */ + public static DuelArea getDuelArea(boolean obstacles) { + List options = new ArrayList<>(20); + for (DuelArea area : DUEL_AREAS) { + if (!obstacles && area.isObstacles() || obstacles && !area.isObstacles()) { + continue; + } + options.add(area); + } + return options.get(RandomFunction.random(options.size())); + } + +} diff --git a/Server/src/main/content/minigame/duel/DuelComponentPlugin.java b/Server/src/main/content/minigame/duel/DuelComponentPlugin.java new file mode 100644 index 0000000..38dc31f --- /dev/null +++ b/Server/src/main/content/minigame/duel/DuelComponentPlugin.java @@ -0,0 +1,71 @@ +package content.minigame.duel; + +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.node.entity.player.Player; +import core.game.world.GameWorld; +import core.plugin.Plugin; + +import static core.api.ContentAPIKt.*; + +/** + * Handles the duel arena components. + * @author Vexia + * + */ +public class DuelComponentPlugin extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.forId(640).setPlugin(this); + return this; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + switch (component.getId()) { + case 640: + boolean staked = false; + switch (button) { + case 20: + Player other = player.getAttribute("duel:partner"); + if (other == null || other.getExtension(DuelSession.class) != null) { + player.getPacketDispatch().sendMessage("Other player is busy at the moment."); + return true; + } + if (player.getAttribute("duel:staked", false) && other.getIronmanManager().isIronman() && !GameWorld.getSettings().isDevMode()) { + other.sendMessage("You can't accept a staked duel as an Ironman."); + player.sendMessage("You can't duel Ironman players."); + return true; + } + player.getInterfaceManager().close(); + if (!player.getAttribute("duel:staked", false)) { + player.getRequestManager().request(other, DuelArenaActivity.FRIEND_REQUEST); + } else { + player.getRequestManager().request(other, DuelArenaActivity.STAKE_REQUEST); + } + return true; + case 18: + case 22: + staked = false; + break; + case 19: + case 21: + staked = true; + if (player.getIronmanManager().isIronman()) { + player.sendMessage("You can't stake as an Iron man."); + staked = false; + } + break; + default: + return false; + } + player.setAttribute("duel:staked", staked); + setVarp(player, 283, (staked ? 2 : 1) << 26); + break; + } + return true; + } + +} diff --git a/Server/src/main/content/minigame/duel/DuelReqModule.java b/Server/src/main/content/minigame/duel/DuelReqModule.java new file mode 100644 index 0000000..9c2a865 --- /dev/null +++ b/Server/src/main/content/minigame/duel/DuelReqModule.java @@ -0,0 +1,33 @@ +package content.minigame.duel; + +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.request.RequestModule; + +/** + * Handles a duel request getting accepted. + * @author Emperor + */ +public final class DuelReqModule implements RequestModule { + + /** + * If the duel request is staked. + */ + private boolean staked; + + /** + * Constructs a new {@code DuelReqModule} {@code Object}. + * @param staked If the duel is staked. + */ + public DuelReqModule(boolean staked) { + this.staked = staked; + } + + @Override + public void open(Player player, Player target) { + DuelSession session = new DuelSession(player, target, staked); + player.addExtension(DuelSession.class, session); + target.addExtension(DuelSession.class, session); + session.openRules(); + } + +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/duel/DuelRule.java b/Server/src/main/content/minigame/duel/DuelRule.java new file mode 100644 index 0000000..62a737b --- /dev/null +++ b/Server/src/main/content/minigame/duel/DuelRule.java @@ -0,0 +1,72 @@ +package content.minigame.duel; + +import core.game.container.impl.EquipmentContainer; + +/** + * Represents a dueling rule. + * @author Emperor + */ +public enum DuelRule { + NO_RANGE(4, "You cannot use Ranged attacks."), NO_MELEE(5, "You cannot use Melee attacks."), NO_MAGIC(6, "You cannot use Magic attacks."), FUN_WEAPONS(12, "You can only attack with 'fun' weapons."), NO_FORFEIT(0, "You cannot forfeit the duel."), NO_DRINKS(7, "You cannot use potions."), NO_FOOD(8, "You cannot use food."), NO_PRAYER(9, "You cannot use Prayer."), NO_MOVEMENT(1, "You cannot move."), OBSTACLES(10, "There will be obstacles in the arena."), ENABLE_SUMMONING(28, "Familiars will be allowed in the arena."), NO_SPECIAL_ATTACKS(13, "You cannot use special attacks."), NO_HATS(14, "", EquipmentContainer.SLOT_HAT), NO_CAPES(15, "", EquipmentContainer.SLOT_CAPE), NO_AMULET(16, "", EquipmentContainer.SLOT_AMULET), NO_WEAPON(17, "You can't use 2H weapons such as bows.", EquipmentContainer.SLOT_WEAPON), NO_SHIELD(19, "You can't use 2H weapons such as bows.", EquipmentContainer.SLOT_SHIELD), NO_BODY(18, "", EquipmentContainer.SLOT_CHEST), NO_LEGS(21, "", EquipmentContainer.SLOT_LEGS), NO_GLOVES(23, "", EquipmentContainer.SLOT_HANDS), NO_RINGS(26, "", EquipmentContainer.SLOT_RING), NO_BOOTS(24, "", EquipmentContainer.SLOT_FEET), NO_ARROWS(27, "", EquipmentContainer.SLOT_ARROWS); + + /** + * The config index. + */ + private final int configIndex; + + /** + * The information to display on the second screen. + */ + private final String info; + + /** + * The equpment slot. + */ + private int equipmentSlot = -1; + + /** + * Constructs a new {@code DuelRule} {@code Object}. + * @param configIndex The config index. + * @param info the info for the second screen. + */ + private DuelRule(int configIndex, String info) { + this.configIndex = configIndex; + this.info = info; + } + + /** + * Constructs a new {@code DuelRule} {@code Object}. + * @param configIndex The config index. + * @param info the info for the second screen. + * @param equipmentSlot the equipment slot. + */ + private DuelRule(int configIndex, String info, int equipmentSlot) { + this.configIndex = configIndex; + this.info = info; + this.equipmentSlot = equipmentSlot; + } + + /** + * Gets the configIndex. + * @return The configIndex. + */ + public int getConfigIndex() { + return configIndex; + } + + /** + * Gets the info. + * @return The info. + */ + public String getInfo() { + return info; + } + + /** + * Gets the equipmentSlot. + * @return the equipmentSlot. + */ + public int getEquipmentSlot() { + return equipmentSlot; + } +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/duel/DuelSession.java b/Server/src/main/content/minigame/duel/DuelSession.java new file mode 100644 index 0000000..51b4a6d --- /dev/null +++ b/Server/src/main/content/minigame/duel/DuelSession.java @@ -0,0 +1,1026 @@ +package content.minigame.duel; + +import static core.api.ContentAPIKt.*; +import core.game.component.CloseEvent; +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.container.Container; +import core.game.container.ContainerType; +import core.game.container.access.InterfaceContainer; +import core.game.container.impl.EquipmentContainer; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.info.LogType; +import core.game.node.entity.player.info.login.PlayerParser; +import core.game.node.item.Item; +import core.plugin.Plugin; +import core.tools.RandomFunction; +import kotlin.Unit; +import core.game.global.action.EquipHandler; +import core.game.node.entity.player.info.PlayerMonitor; +import core.game.system.config.ItemConfigParser; + +import java.text.DecimalFormat; + +/** + * Represents a duel session. + * @author Emperor + * @author Vexia + * + */ +public final class DuelSession extends ComponentPlugin { + + /** + * The friendly rules interface. + */ + private static final Component FRIENDLY_INTER = new Component(637).setCloseEvent(new CloseEvent() { + @Override + public boolean close(Player player, Component c) { + decline(player); + return true; + } + }); + + /** + * The staked rules interface. + */ + private static final Component STAKED_INTER = new Component(631).setCloseEvent(new CloseEvent() { + @Override + public boolean close(Player player, Component c) { + decline(player); + return true; + } + }); + + /** + * The friendly rule interface. + */ + private static final Component FRIENDLY_RULE_INTER = new Component(639).setCloseEvent(new CloseEvent() { + @Override + public boolean close(Player player, Component c) { + decline(player); + return true; + } + }); + + /** + * The staked rule interface. + */ + private static final Component STAKED_RULE_INTER = new Component(626).setCloseEvent(new CloseEvent() { + @Override + public boolean close(Player player, Component c) { + decline(player); + return true; + } + }); + + /** + * The friendly victory interface. + */ + private static final Component FRIENDLY_VICTORY = new Component(633); + + /** + * The stake victory. + */ + private static final Component STAKE_VICTORY = new Component(634).setCloseEvent(new CloseEvent() { + @Override + public boolean close(Player player, Component c) { + reward(player); + return true; + } + }); + + /** + * The rules. + */ + private final DuelRule[] rules = new DuelRule[DuelRule.values().length]; + + /** + * The players staked container. + */ + private StakeContainer playerContainer; + + /** + * The targets staked container. + */ + private StakeContainer targetContainer; + + /** + * The first player. + */ + private final Player player; + + /** + * The second player. + */ + private final Player other; + + /** + * If this is a staked duel. + */ + private final boolean staked; + + /** + * The accepting state of the session. + */ + private int acceptState; + + /** + * The fight state (0 not started, 1 started, 2 finished) + */ + private int fightState; + + /** + * Constructs a new {@code DuelSession} {@code Object}. + * @param player The first player. + * @param other The second player. + */ + public DuelSession(Player player, Player other, boolean staked) { + this.player = player; + this.other = other; + this.staked = staked; + } + + /** + * Declines the duel. + * @param player The player declining. + */ + public static void decline(Player player) { + DuelSession session = player.getExtension(DuelSession.class); + if (session == null) { + return; + } + if (session.getAcceptState() == 3 || session.getAcceptState() == 7) { + return; + } + if (session.isStaked()) { + session.getPlayerContainer().release(); + session.getTargetContainer().release(); + session.resetAccept(); + } + session.player.removeExtension(DuelSession.class); + session.other.removeExtension(DuelSession.class); + session.end(); + if (player == session.other) { + session.player.getPacketDispatch().sendMessage("Other player declined " + (session.staked ? "stake and " : "") + "duel options."); + } else { + session.other.getPacketDispatch().sendMessage("Other player declined " + (session.staked ? "stake and " : "") + "duel options."); + } + } + + /** + * Ends the session. + */ + public void end() { + player.removeAttribute("duel:partner"); + other.removeAttribute("duel:partner"); + player.removeAttribute("duel:staked"); + other.removeAttribute("duel:staked"); + other.removeAttribute("duel:forfeit"); + player.removeAttribute("duel:forfeit"); + player.getInterfaceManager().close(); + player.getInterfaceManager().closeSingleTab(); + player.getInterfaceManager().restoreTabs(); + other.getInterfaceManager().close(); + other.getInterfaceManager().closeSingleTab(); + other.getInterfaceManager().restoreTabs(); + other.getLocks().unlockMovement(); + player.getLocks().unlockMovement(); + player.getHintIconManager().clear(); + other.getHintIconManager().clear(); + heal(player); + heal(other); + for (DuelRule rule : rules) { + if (rule != null) { + player.getLocks().unlock(rule.name().toLowerCase(), true, player); + other.getLocks().unlock(rule.name().toLowerCase(), true, other); + } + } + } + + /** + * Heals a player after a duel. + * @param p the player. + */ + public void heal(Player p) { + p.fullRestore(); + if (isPoisoned(p)) { + curePoison(p); + } + p.getSkills().restore(); + } + + /** + * Opens the rules interface. + */ + public void openRules() { + player.setAttribute("duel:partner", other); + other.setAttribute("duel:partner", player); + player.setAttribute("duel:staked", staked); + other.setAttribute("duel:staked", staked); + player.removeAttribute("duel:accepted"); + other.removeAttribute("duel:accepted"); + openRules(player, other); + openRules(other, player); + } + + /** + * Opens the rules for a player. + * @param player The player. + */ + private void openRules(Player player, Player opponent) { + setVarp(player, 286, 0); + if (staked) { + StakeContainer container = new StakeContainer(player, this); + if (player == this.player) { + playerContainer = container; + } else { + targetContainer = container; + } + player.getInterfaceManager().open(STAKED_INTER); + player.getPacketDispatch().sendString(opponent.getUsername(), 631, 25); + player.getPacketDispatch().sendString(Integer.toString(opponent.getProperties().getCurrentCombatLevel()), 631, 27); + player.getPacketDispatch().sendString("", 631, 28); + container.open(); + } else { + player.getInterfaceManager().open(FRIENDLY_INTER); + player.getPacketDispatch().sendString(opponent.getUsername(), 637, 16); + player.getPacketDispatch().sendString(Integer.toString(opponent.getProperties().getCurrentCombatLevel()), 637, 18); + player.getPacketDispatch().sendString("", 637, 45); + } + setVarp(player, 286, 0); + } + + /** + * Handles the leaving of a player from the duel area. + * @param p the player who is forced to leave. + * @param type = the type of leaving (0 forfeit, 1 = logout, 2 win) + */ + public void leave(Player p, int type) { + if (fightState == 2) { + return; + } + Player o = getOpposite(p); + o.getImpactHandler().setDisabledTicks(6); + o.teleport(RandomFunction.getRandomElement(DuelArea.RESPAWN_LOCATIONS)); + boolean victory = type == 0 || type == 2 || type == 1 && p.getImpactHandler().getPlayerImpactLog().containsKey(o.getDetails().getUid()); + fightState = 2; + p.removeExtension(DuelSession.class); + end(); + if (victory) { + if (type == 0) { + o.sendMessage("Well done! " + p.getUsername() + " resigned!"); + } else if (type == 2) { + o.sendMessage("Well done! You have defeated " + p.getUsername() + "!"); + } + victory(o); + } else if (type == 1) { + getContainer(player).release(); + getContainer(o).release(); + o.removeExtension(DuelSession.class); + o.getDialogueInterpreter().sendDialogue("Your opponent timed out, there was no winner!"); + } + DuelArenaActivity.insertEntry(o, p); + } + + /** + * Handles the victory for a player. + * @param player the player. + */ + public void victory(Player player) { + Component component = staked ? STAKE_VICTORY : FRIENDLY_VICTORY; + player.getInterfaceManager().open(component); + player.getPacketDispatch().sendString(getOpposite(player).getUsername(), component.getId(), staked ? 23 : 22); + player.getPacketDispatch().sendString(Integer.toString(getOpposite(player).getProperties().getCurrentCombatLevel()), component.getId(), staked ? 22 : 21); + if (staked) { + getContainer(player).release(); + StakeContainer targetContainer = getOppositeContainer(player); + if (targetContainer.itemCount() > 0) { + InterfaceContainer.generateItems(player, targetContainer.toArray(), new String[] { "Examine" }, 634, 33); + } + Container c = new Container(28, ContainerType.ALWAYS_STACK); + c.addAll(targetContainer); + String log = "defeated => " + getOpposite(player).getName() + " and receieved {"; + for (Item i : c.toArray()) { + if (i == null) { + continue; + } + log += i.getName() + " x " + i.getAmount() + ","; + } + if (log.charAt(log.length() - 1) == ',') { + log = log.substring(0, log.length() - 1); + } + log += "}"; + PlayerMonitor.log(player, LogType.DUEL_INFO, log); + } else { + player.removeExtension(DuelSession.class); + } + } + + /** + * Rewards the player. + * @param player the player. + */ + public static void reward(Player player) { + DuelSession session = player.getExtension(DuelSession.class); + if (session == null || session.getFightState() == 4) { + return; + } + StakeContainer targetContainer = session.getOppositeContainer(player); + if (!player.getInventory().hasSpaceFor(targetContainer)) { + player.getBank().addAll(targetContainer); + player.sendMessage("An error occured & the stake transfered to your bank."); + } else { + session.setFightState(4); + player.getInventory().addAll(targetContainer); + } + player.removeExtension(DuelSession.class); + PlayerParser.save(player); + } + + /** + * Handles the accepting of the dule rules. + */ + private void accept() { + DuelSession session = player.getExtension(DuelSession.class); + if (session == null) { + return; + } + switch (session.getAcceptState()) { + case 2: + if (!session.checkRules(session.player) || !session.checkRules(session.other)) { + resetAccept(); + return; + } + session.player.lock(1); + session.other.lock(1); + session.setAcceptState(3); + session.player.removeAttribute("duel:accepted"); + session.other.removeAttribute("duel:accepted"); + session.other.getInterfaceManager().open(session.isStaked() ? STAKED_RULE_INTER : FRIENDLY_RULE_INTER); + session.player.getInterfaceManager().open(session.isStaked() ? STAKED_RULE_INTER : FRIENDLY_RULE_INTER); + session.setAcceptState(4); + session.player.getInterfaceManager().closeSingleTab(); + session.other.getInterfaceManager().closeSingleTab(); + session.player.getInterfaceManager().removeTabs(0, 1, 2, 3, 4, 5, 6, 7, 11, 12); + session.other.getInterfaceManager().removeTabs(0, 1, 2, 3, 4, 5, 6, 7, 11, 12); + StringBuilder before = new StringBuilder(); + StringBuilder during = new StringBuilder(); + if (hasEquipmentRules()) { + before.append("Some worn items will be taken off.
"); + } + if (hasRule(DuelRule.NO_WEAPON) || hasRule(DuelRule.NO_SHIELD)) { + during.append("You can't use 2H weapons such as bows.
"); + } + if (hasRule(DuelRule.NO_DRINKS) || hasRule(DuelRule.NO_FOOD)) { + before.append("Boosted stats will be restored.
"); + } + if (hasRule(DuelRule.NO_PRAYER)) { + before.append("Existing prayers will be stopped.
"); + } + if (before.length() == 0) { + before.append("Nothing will be changed.
"); + } + if (during.length() == 0) { + during.append("You will fight using normal combat.
"); + } + for (DuelRule rule : rules) { + if (rule != null && rule.getEquipmentSlot() == -1) { + during.append(rule.getInfo() + "
"); + } + } + int interfaceId = session.isStaked() ? 626 : 639; + int[] childs = staked ? new int[] { 28, 29, 30, 31, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45 } : new int[] { 16, 17, 18, 19, 20, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32 }; + clearChilds(session.player, interfaceId, childs); + clearChilds(session.other, interfaceId, childs); + String[] tokens = before.toString().split("
"); + for (int i = 0; i < tokens.length; i++) { + session.player.getPacketDispatch().sendString(tokens[i], interfaceId, staked ? (28 + i) : (16 + i)); + session.other.getPacketDispatch().sendString(tokens[i], interfaceId, staked ? (28 + i) : (16 + i)); + } + tokens = during.toString().split("
"); + for (int i = 0; i < tokens.length; i++) { + session.player.getPacketDispatch().sendString(tokens[i], interfaceId, staked ? (34 + i) : (22 + i)); + session.other.getPacketDispatch().sendString(tokens[i], interfaceId, staked ? (34 + i) : (22 + i)); + } + if (staked) { + session.player.getPacketDispatch().sendString(session.getContainer(player).isEmpty() ? "Absolutely nothing!" : getDisplayMessage(session.getContainer(player).toArray()), 626, 25); + session.player.getPacketDispatch().sendString(session.getOppositeContainer(player).isEmpty() ? "Absolutely nothing!" : getDisplayMessage(session.getOppositeContainer(player).toArray()), 626, 26); + session.other.getPacketDispatch().sendString(session.getOppositeContainer(player).isEmpty() ? "Absolutely nothing!" : getDisplayMessage(session.getOppositeContainer(player).toArray()), 626, 25); + session.other.getPacketDispatch().sendString(session.getOppositeContainer(other).isEmpty() ? "Absolutely nothing!" : getDisplayMessage(session.getOppositeContainer(other).toArray()), 626, 26); + } + session.updateToolTip(player, ""); + session.updateToolTip(getOpposite(player), ""); + break; + case 6: + session.player.lock(2); + session.other.lock(2); + session.player.sendMessage("Accepted stake and duel options."); + session.other.sendMessage("Accepted stake and duel options."); + session.setAcceptState(7); + DuelArenaActivity.getDuelArea(hasRule(DuelRule.OBSTACLES)).duel(this); + session.applyRules(session.player); + session.applyRules(session.other); + session.setAcceptState(8); + break; + } + } + + /** + * Applies the rules to a player. + * @param player the player. + */ + public void applyRules(Player player) { + for (DuelRule rule : rules) { + if (rule != null) { + if (rule.getEquipmentSlot() != -1 && player.getEquipment().get(rule.getEquipmentSlot()) != null) { + EquipHandler.unequip(player, rule.getEquipmentSlot(), player.getEquipment().getId(rule.getEquipmentSlot())); + } + player.getLocks().lock(rule.name().toLowerCase(), 100000); + } + } + if (hasRule(DuelRule.NO_SHIELD)) { + Item i = player.getEquipment().get(EquipmentContainer.SLOT_WEAPON); + if (i != null && i.getDefinition().getConfiguration(ItemConfigParser.TWO_HANDED, false)) { + EquipHandler.unequip(player, EquipmentContainer.SLOT_WEAPON, i.getId()); + } + } + if (hasRule(DuelRule.NO_DRINKS) || hasRule(DuelRule.NO_FOOD)) { + player.getSkills().restore(); + } + if (hasRule(DuelRule.NO_PRAYER)) { + player.getPrayer().reset(); + } + } + + /** + * Toggles a rule. + * @param p The player toggling the rule. + * @param index The rule index. + */ + private void toggleRule(Player p, int index) { + DuelSession session = player.getExtension(DuelSession.class); + if (session == null) { + return; + } + session.resetAccept(); + if (rules[index] != null) { + rules[index] = null; + } else { + if (index < 3) { + int count = 0; + for (int i = 0; i < 3; i++) { + if (rules[i] != null) { + count++; + } + } + if (count == 2) { + session.updateToolTip(player, "You can't have No Ranged, No Melee AND No Magic, how would you fight?"); + p.getPacketDispatch().sendMessage("You can't have No Ranged, No Melee AND No Magic, how would you fight?"); + return; + } + } else if ((index == 8 && rules[9] != null) || (index == 9 && rules[8] != null)) { + rules[8] = rules[9] = null; + p.getPacketDispatch().sendMessage(index == 8 ? "You can't have obstacles if you want No Movement." : "You can't have No Movement in an area with obstacles."); + } + if (index == 15 || index == 16) { + player.sendMessage("Beware: You won't be able to use two-handed weapons such as bows."); + } + rules[index] = DuelRule.values()[index]; + } + int value = 0; + for (int i = 0; i < rules.length; i++) { + if (rules[i] != null) { + value |= 1 << rules[i].getConfigIndex(); + } + } + setVarp(player, 286, value); + setVarp(other, 286, value); + } + + /** + * Checks the current rules for restrictions. + */ + private boolean checkRules(Player player) { + Container c = new Container(60); + for (DuelRule rule : rules) { + if (rule != null && rule.getEquipmentSlot() != -1 && player.getEquipment().get(rule.getEquipmentSlot()) != null) { + c.add(player.getEquipment().get(rule.getEquipmentSlot())); + } + } + if (hasRule(DuelRule.FUN_WEAPONS) && !hasFunWeapon(player)) { + updateToolTip(player, "Fun Weapons is selected but you don't have a 'fun weapon'."); + updateToolTip(getOpposite(player), "Fun Weapons is selected but your opponent does not have a 'fun weapon'."); + return false; + } + if (staked) { + c.addAll(getContainer(player)); + c.addAll(getOppositeContainer(player)); + } + if (!player.getInventory().hasSpaceFor(c)) { + updateToolTip(player, "You do not have enough space for the items removed and/or the stake."); + updateToolTip(getOpposite(player), "Your opponent does not have enough space for the items removed and/or the stake."); + return false; + } + return true; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, final int slot, int itemId) { + DuelSession session = player.getExtension(DuelSession.class); + if (session == null) { + return false; + } + switch (component.getId()) { + case 626:// stake rules + if (button == 53) { + requestAccept(player, component); + } + break; + case 639:// friendly rules + if (button == 35) { + requestAccept(player, component); + break; + } + break; + case 631: + if (button == 107) {// decline + decline(player); + break; + } else if (button == 102) { + requestAccept(player, component); + break; + } + final StakeContainer c = session.getContainer(player); + if (button == 103) { + int amount = 0; + switch (opcode) { + case 155: + amount = 1; + break; + case 196: + amount = 5; + break; + case 124: + amount = 10; + break; + case 199: + amount = c.getAmount(c.get(slot)); + break; + case 234: + sendInputDialogue(player, true, "Enter the amount:", (value) -> { + c.withdraw(slot, (int) value); + return Unit.INSTANCE; + }); + break; + } + c.withdraw(slot, amount); + break; + } else if (button == 104) { + break; + } + if (button == 107) { + player.getInterfaceManager().close(); + break; + } + if (button >= 57 && button <= 67) { + int index = 12 + ((57 - button) * -1); + if (button == 60) { + index = DuelRule.values().length - 1; + } else if (button == 61) { + index = 15; + } else if (button == 62) { + index = DuelRule.NO_BODY.ordinal(); + } else if (button == 63) { + index = DuelRule.NO_SHIELD.ordinal(); + } else if (button == 64) { + index = DuelRule.NO_LEGS.ordinal(); + } else if (button == 67) { + index = DuelRule.NO_GLOVES.ordinal(); + } else if (button == 66) { + index = DuelRule.NO_BOOTS.ordinal(); + } + session.toggleRule(player, index); + break; + } + if (button >= 29 && button <= 53) { + if (button > 49) { + button--; + } + int index = (button - 29) / 2; + if (index == 11) { + index = 10; + } else if (index == 10) { + index = 11; + } + session.toggleRule(player, index); + break; + } + return false; + case 637: + if (button == 86) { + player.getInterfaceManager().close(); + break; + } else if (button == 83 && session.acceptState < 2) { + requestAccept(player, component); + break; + } + if (button >= 46 && button <= 56) { + int index = 0; + switch (button) { + case 46: + index = DuelRule.NO_HATS.ordinal(); + break; + case 47: + index = DuelRule.NO_CAPES.ordinal(); + break; + case 48: + index = DuelRule.NO_AMULET.ordinal(); + break; + case 49: + index = DuelRule.NO_ARROWS.ordinal(); + break; + case 50: + index = DuelRule.NO_WEAPON.ordinal(); + break; + case 51: + index = DuelRule.NO_BODY.ordinal(); + break; + case 52: + index = DuelRule.NO_SHIELD.ordinal(); + break; + case 53: + index = DuelRule.NO_LEGS.ordinal(); + break; + case 54: + index = DuelRule.NO_RINGS.ordinal(); + break; + case 55: + index = DuelRule.NO_BOOTS.ordinal(); + break; + case 56: + index = DuelRule.NO_GLOVES.ordinal(); + } + session.toggleRule(player, index); + break; + } + if (button >= 19 && button <= 42) { + session.toggleRule(player, (button - 19) / 2); + break; + } + return false; + case 336: + final StakeContainer c1 = player == session.getPlayer() ? session.getPlayerContainer() : session.getTargetContainer(); + switch (opcode) { + case 155: + c1.offer(slot, 1); + break; + case 196: + c1.offer(slot, 5); + break; + case 124: + c1.offer(slot, 10); + break; + case 199: + c1.offer(slot, player.getInventory().getAmount(player.getInventory().get(slot).getId())); + break; + case 234: + sendInputDialogue(player, true, "Enter the amount:", (value) -> { + c1.offer(slot, (int) value); + return Unit.INSTANCE; + }); + break; + case 9: + player.getPacketDispatch().sendMessage(player.getInventory().get(slot).getDefinition().getExamine()); + break; + } + } + return true; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.put(631, this); + ComponentDefinition.put(637, this); + ComponentDefinition.put(626, this); + ComponentDefinition.put(639, this); + StakeContainer.OVERLAY.setPlugin(this); + return this; + } + + /** + * Requests an accepting of the duel. + * @param player the player. + * @param component the component. + */ + public void requestAccept(Player player, Component component) { + DuelSession session = player.getExtension(DuelSession.class); + if (session == null) { + return; + } + // 1 & 5 are waiing. + // 2 & 6 are completed + if (session.getAcceptState() == (session.getAcceptState() < 3 ? 1 : 5) && session.getOpposite(player).getAttribute("duel:accepted", false)) { + session.setAcceptState(session.getAcceptState() == 1 ? 2 : 6); + session.accept(); + return; + } + if (session.getAcceptState() == 0 || session.getAcceptState() == 4) { + session.setAcceptState(session.getAcceptState() == 0 ? 1 : 5); + player.setAttribute("duel:accepted", true); + session.updateToolTip(player, "Waiting for other player..."); + session.updateToolTip(session.getOpposite(player), "Other player accepted."); + } + } + + /** + * Resets the accept state. + */ + public void resetAccept() { + setAcceptState(getAcceptState() < 3 ? 0 : 4); + player.removeAttribute("duel:accepted"); + other.removeAttribute("duel:accepted"); + } + + /** + * Clears the childs. + * @param childs the childs. + */ + public void clearChilds(Player player, int interfaceId, int... childs) { + for (int i : childs) { + player.getPacketDispatch().sendString("", interfaceId, i); + } + } + + /** + * Updates the tool tip message. + * @param player the player. + * @param message the message. + */ + private void updateToolTip(Player player, String message) { + DuelSession session = player.getExtension(DuelSession.class); + if (session == null) { + return; + } + int interfaceId = 631; + int child = 28; + if (!staked) { + interfaceId = acceptState < 4 ? FRIENDLY_INTER.getId() : FRIENDLY_RULE_INTER.getId(); + child = acceptState < 4 ? 45 : 33; + } else if (acceptState > 3) { + interfaceId = STAKED_RULE_INTER.getId(); + child = 45; + } + player.getPacketDispatch().sendString(message, interfaceId, child); + } + + /** + * Gets the display message for the stake. + * @param items the items. + * @return the message. + */ + private String getDisplayMessage(Item[] items) { + String message = "Absolutely nothing!"; + if (items.length > 0) { + message = ""; + for (int i = 0; i < items.length; i++) { + if (items[i] == null) { + continue; + } + message = message + "" + items[i].getName(); + if (items[i].getAmount() > 1) { + message = message + " x "; + message = message + "" + getFormattedNumber(items[i].getAmount()) + "
"; + } else { + message = message + "
"; + } + } + } + return message; + } + + /** + * Checks if the player has a fun weapon. + * @param player the player. + * @return True + */ + public boolean hasFunWeapon(Player player) { + Container c = new Container(60); + c.addAll(player.getInventory()); + c.addAll(player.getEquipment()); + for (Item item : c.toArray()) { + if (item == null) { + continue; + } + if (item.getDefinition().getConfiguration("fun_weapon", false)) { + return true; + } + } + return false; + } + + /** + * Checks if the item is restricted equipment. + * @param item the item. + * @return {@code True} if so. + */ + public boolean isRestrictedEquipment(Item item) { + if (item == null) { + return false; + } + int slot = item.getDefinition().getConfiguration(ItemConfigParser.EQUIP_SLOT, -1); + if (slot == -1) { + return false; + } + boolean twoHanded = item.getDefinition().getConfiguration(ItemConfigParser.TWO_HANDED, false); + if (slot == EquipmentContainer.SLOT_WEAPON && twoHanded && hasRule(DuelRule.NO_SHIELD)) { + return true; + } + for (DuelRule rule : rules) { + if (rule == null) { + continue; + } + if (rule.getEquipmentSlot() == slot) { + return true; + } + } + return false; + } + + /** + * Checks if this session has equipment rules applied. + * @return {@code True} if so. + */ + public boolean hasEquipmentRules() { + for (DuelRule rule : rules) { + if (rule != null && rule.ordinal() >= DuelRule.NO_HATS.ordinal()) { + return true; + } + } + return false; + } + + /** + * Checks if a rule is active. + * @param r the rule. + * @return {@code True} if so. + */ + public boolean hasRule(DuelRule r) { + return rules[r.ordinal()] != null; + } + + /** + * Gets the opposite container. + * @param player the player. + * @return the container. + */ + public StakeContainer getOppositeContainer(Player player) { + return player == this.player ? targetContainer : playerContainer; + } + + /** + * Gets the players container. + * @param player the player. + * @return the staked container. + */ + public StakeContainer getContainer(Player player) { + return player == this.player ? playerContainer : targetContainer; + } + + /** + * Gets the formatted number. + * @param amount the amount. + * @return the formatted number. + */ + private String getFormattedNumber(int amount) { + return new DecimalFormat("#,###,##0").format(amount).toString(); + } + + /** + * Gets the rule size. + * @return the amount of active rules. + */ + public int getRuleSize() { + int count = 0; + for (DuelRule rule : rules) { + if (rule != null) { + count++; + } + } + return count; + } + + /** + * Gets the opposite. + * @param player the player. + * @return the player. + */ + public Player getOpposite(Player player) { + return this.player == player ? other : this.player; + } + + /** + * Gets the other player. + * @param player the player. + * @return the player. + */ + public Player getOther(Player player) { + return player == this.player ? other : player; + } + + /** + * Gets the rules. + * @return The rules. + */ + public DuelRule[] getRules() { + return rules; + } + + /** + * Gets the playerContainer. + * @return the playerContainer. + */ + public StakeContainer getPlayerContainer() { + return playerContainer; + } + + /** + * Sets the playerContainer. + * @param playerContainer the playerContainer to set + */ + public void setPlayerContainer(StakeContainer playerContainer) { + this.playerContainer = playerContainer; + } + + /** + * Gets the targetContainer. + * @return the targetContainer. + */ + public StakeContainer getTargetContainer() { + return targetContainer; + } + + /** + * Sets the targetContainer. + * @param targetContainer the targetContainer to set + */ + public void setTargetContainer(StakeContainer targetContainer) { + this.targetContainer = targetContainer; + } + + /** + * Gets the player. + * @return the player. + */ + public Player getPlayer() { + return player; + } + + /** + * Gets the other. + * @return the other. + */ + public Player getOther() { + return other; + } + + /** + * Gets the staked. + * @return the staked. + */ + public boolean isStaked() { + return staked; + } + + /** + * Gets the acceptState. + * @return the acceptState. + */ + public int getAcceptState() { + return acceptState; + } + + /** + * Sets the acceptState. + * @param acceptState the acceptState to set + */ + public void setAcceptState(int acceptState) { + this.acceptState = acceptState; + } + + /** + * Gets the fightState. + * @return the fightState. + */ + public int getFightState() { + return fightState; + } + + /** + * Sets the fightState. + * @param fightState the fightState to set + */ + public void setFightState(int fightState) { + this.fightState = fightState; + } +} diff --git a/Server/src/main/content/minigame/duel/MubarizDialogue.java b/Server/src/main/content/minigame/duel/MubarizDialogue.java new file mode 100644 index 0000000..4350ab4 --- /dev/null +++ b/Server/src/main/content/minigame/duel/MubarizDialogue.java @@ -0,0 +1,167 @@ +package content.minigame.duel; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the mubariz dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class MubarizDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code MubarizDialogue {@code Object}. + */ + public MubarizDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code MubarizDialogue} {@code Object}. + * @param player the player. + */ + public MubarizDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new MubarizDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hi!"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Welcome to the Duel Arena!"); + stage = 1; + break; + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Thanks! I need some information."); + stage = 2; + break; + case 2: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "What would you like to know?"); + stage = 3; + break; + case 3: + interpreter.sendOptions("Information", "What is this place?", "How do I challenge someone to a duel?", "What kind of options are there?", "This place looks really old, where did it come from?"); + stage = 4; + break; + case 4: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What is this place?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "How do I challenge someone to a duel?"); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What kind of options are there?"); + stage = 30; + break; + case 4: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "This place looks really old, where did it come from?"); + stage = 40; + break; + + } + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "When you go to the arena you'll go up an access ramp", "to the walkways that overlook the duel arenas. From the", "walkways you can watch the duels and challenge other", "players."); + stage = 21; + break; + case 21: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "You'll know you're in the right place as you'll have a", "Duel-with option when you right-click a player."); + stage = 22; + break; + case 22: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'm there!"); + stage = 23; + break; + case 23: + end(); + break; + case 30: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "You and your opponent can offer items as a stake. If", "you win, you recieve what your opponent staked, but if", "you lose, your opponent will get whatever items you", "staked."); + stage = 31; + break; + case 31: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "You can choose to use rules to spice things up a bit.", "For instance if you both agree to use the 'No Magic'", "rule then neither player can use magic to attack the", "other player. The fight will be restricted to ranging and"); + stage = 32; + break; + case 32: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "melee only."); + stage = 33; + break; + case 33: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "The rules are fairly self-evident with lots of different", "combinations for you to try out!"); + stage = 34; + break; + case 34: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Cool! Thanks!"); + stage = 35; + break; + case 35: + end(); + break; + case 40: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Now that the archaeologists have moved out, a group of", "warriors, headed by myself, have bought the land and", "converted it to a set of duel arenas. The best fighters", "from around the world come here to fight!"); + stage = 41; + break; + case 41: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I challenge you!"); + stage = 42; + break; + case 42: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ho! Ho! Ho!"); + stage = 43; + break; + case 43: + end(); + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "The Duel Arena has six duel arenas where you can", "fight other players in a controlled enviornment. We", "have our own dedicated hospital where we guarantee to", "put you back together, even if you lose."); + stage = 11; + break; + case 11: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Inbetween the arenas are walkways where you can", "watch the fights and challenge other players"); + stage = 13; + break; + case 13: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Sounds great. Thanks!"); + stage = 14; + break; + case 14: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "See you in the arenas!"); + stage = 15; + break; + case 15: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 957 }; + } +} diff --git a/Server/src/main/content/minigame/duel/StakeContainer.java b/Server/src/main/content/minigame/duel/StakeContainer.java new file mode 100644 index 0000000..c505478 --- /dev/null +++ b/Server/src/main/content/minigame/duel/StakeContainer.java @@ -0,0 +1,212 @@ +package content.minigame.duel; + +import core.game.component.Component; +import core.game.container.Container; +import core.game.container.ContainerEvent; +import core.game.container.ContainerListener; +import core.game.container.ContainerType; +import core.game.container.SortType; +import core.game.container.access.InterfaceContainer; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.info.login.PlayerParser; +import core.game.node.item.Item; +import core.net.packet.PacketRepository; +import core.net.packet.context.ContainerContext; +import core.net.packet.out.ContainerPacket; + +/** + * Represents the staking container. + * @author Vexia + * + */ +public class StakeContainer extends Container { + + /** + * The inventory params. + */ + private static final Object[] INVY_PARAMS = new Object[] { "", "", "", "Stake-X", "Stake-All", "Stake-10", "Stake-5", "Stake", -1, 0, 7, 4, 93, (336 << 16) }; + + /** + * The withdraw options. + */ + private static final String[] WITHDRAW_OPTIONS = new String[] { "Remove-X", "Remove-All", "Remove-10", "Remove-5", "Remove" }; + + /** + * The overlay interface. + */ + public static final Component OVERLAY = new Component(336); + + /** + * The serial version UID. + */ + private static final long serialVersionUID = 3454088488966242754L; + + /** + * The player of the container. + */ + private final Player player; + + /** + * The dueling session. + */ + private final DuelSession session; + + /** + * The stake listener. + */ + private final StakeListener listener; + + /** + * If the container has been released. + */ + private boolean released; + + /** + * Constructs a new {@Code StakeContainer} {@Code Object} + * @param player the player. + * @param session the session. + */ + public StakeContainer(Player player, DuelSession session) { + super(28, ContainerType.DEFAULT, SortType.ID); + this.player = player; + this.session = session; + this.getListeners().add(listener = new StakeListener()); + } + + /** + * Opens the staking container. + */ + public void open() { + player.getInterfaceManager().openSingleTab(OVERLAY); + player.getPacketDispatch().sendRunScript(150, "IviiiIssssssss", INVY_PARAMS); + player.getPacketDispatch().sendIfaceSettings(1278, 0, 336, 0, 27); + PacketRepository.send(ContainerPacket.class, new ContainerContext(player, -1, 2, 93, player.getInventory(), false)); + } + + /** + * Offers an item to the stake. + * @param slot the slot. + * @param amount the amount. + */ + public void offer(final int slot, int amount) { + final Item item = player.getInventory().get(slot); + if (item == null) { + return; + } + if ((slot < 0 || slot > player.getInventory().capacity() || amount < 1)) { + return; + } + if (!item.getDefinition().isTradeable()) { + player.sendMessage("You can't offer that item."); + return; + } + Item remove = new Item(item.getId(), amount); + if (item.getAmount() > getMaximumAdd(item)) { + item.setAmount(getMaximumAdd(item)); + if (item.getAmount() < 1) { + return; + } + } + remove.setAmount(amount > player.getInventory().getAmount(item) ? player.getInventory().getAmount(item) : amount); + if (player.getInventory().remove(remove, slot, true)) { + session.resetAccept(); + add(remove); + StakeContainer c = session.getOppositeContainer(player); + c.getListener().update(c, c.getEvent()); + } + } + + /** + * Withdraws an item from the container. + * @param slot the slot. + * @param amount the amount. + */ + public void withdraw(final int slot, int amount) { + final Item item = get(slot); + if (item == null) { + return; + } + if ((slot < 0 || slot > player.getInventory().capacity() || amount < 1)) { + return; + } + if (!item.getDefinition().isTradeable()) { + player.sendMessage("You can't offer that item."); + return; + } + Item remove = new Item(item.getId(), amount); + if (item.getAmount() > getMaximumAdd(item)) { + item.setAmount(getMaximumAdd(item)); + if (item.getAmount() < 1) { + return; + } + } + remove.setAmount(amount > getAmount(item) ? getAmount(item) : amount); + if (remove(remove, slot, true) && player.getInventory().add(remove)) { + session.resetAccept(); + shift(); + StakeContainer c = session.getOppositeContainer(player); + c.getListener().update(c, c.getEvent()); + } + } + + /** + * Releases the container back to the player. + */ + public void release() { + if (released) { + return; + } + released = true; + if (!player.getInventory().hasSpaceFor(this)) { + player.getBank().addAll(this); + player.sendMessage("Your stake was sent to your bake due to invalid inventory space."); + return; + } + player.getInventory().addAll(this); + PlayerParser.save(player); + } + + /** + * Gets the serialversionuid. + * @return the serialversionuid. + */ + public static long getSerialversionuid() { + return serialVersionUID; + } + + /** + * Gets the session. + * @return the session. + */ + public DuelSession getSession() { + return session; + } + + /** + * Gets the listener. + * @return the listener. + */ + public StakeListener getListener() { + return listener; + } + + /** + * Represents the container listener for a players stake session. + * @author Vexia + * + */ + public final class StakeListener implements ContainerListener { + + @Override + public void update(Container c, ContainerEvent event) { + InterfaceContainer.generateItems(player, c.toArray(), WITHDRAW_OPTIONS, 631, 103, 12, 3); + InterfaceContainer.generateItems(player, session.getOppositeContainer(player).toArray(), WITHDRAW_OPTIONS, 631, 104, 12, 3); + } + + @Override + public void refresh(Container c) { + PacketRepository.send(ContainerPacket.class, new ContainerContext(player, -1, 2, 93, player.getInventory(), false)); + } + + } +} diff --git a/Server/src/main/content/minigame/duel/ZahwaDialogue.java b/Server/src/main/content/minigame/duel/ZahwaDialogue.java new file mode 100644 index 0000000..baf7be7 --- /dev/null +++ b/Server/src/main/content/minigame/duel/ZahwaDialogue.java @@ -0,0 +1,65 @@ +package content.minigame.duel; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the dialogue plugin used for zahwa. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class ZahwaDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code ZahwaDialogue} {@code Object}. + */ + public ZahwaDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code ZahwaDialogue} {@code Object}. + * @param player the player. + */ + public ZahwaDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new ZahwaDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hi!"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ughhhh...."); + stage = 1; + break; + case 1: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 963 }; + } +} diff --git a/Server/src/main/content/minigame/fishingtrawler/FishingTrawlerActivity.kt b/Server/src/main/content/minigame/fishingtrawler/FishingTrawlerActivity.kt new file mode 100644 index 0000000..1522316 --- /dev/null +++ b/Server/src/main/content/minigame/fishingtrawler/FishingTrawlerActivity.kt @@ -0,0 +1,100 @@ +package content.minigame.fishingtrawler + +import core.api.MapArea +import core.game.node.entity.player.Player +import core.game.system.task.Pulse +import core.game.world.GameWorld +import core.game.world.map.Location +import core.game.world.map.build.DynamicRegion +import core.game.world.map.zone.ZoneRestriction +import core.plugin.Initializable +import core.tools.ticksToSeconds +import core.game.activity.ActivityManager +import core.game.activity.ActivityPlugin +import core.game.world.map.zone.ZoneBorders +import core.tools.colorize + + +/** + * Handles the fishing trawler "waiting room" + * @author Ceikry + */ +private val WAIT_TIME = if(GameWorld.settings?.isDevMode == true) 30 else 203 +private val waitingPlayers = ArrayList() +private val ftWaitingArea = arrayOf(ZoneBorders(2668, 3165, 2675, 3184)) +private val sessions = ArrayList() +private var activity: FishingTrawlerActivity? = null +private var nextStart = GameWorld.ticks + WAIT_TIME +@Initializable +class FishingTrawlerActivity : ActivityPlugin("fishing trawler",false,false,true,ZoneRestriction.CANNON,ZoneRestriction.FIRES,ZoneRestriction.FOLLOWERS,ZoneRestriction.RANDOM_EVENTS), MapArea { + + init { + activity = this + } + override fun configure() { + GameWorld.Pulser.submit( + object : Pulse(1){ + override fun pulse(): Boolean { + if((nextStart - GameWorld.ticks) % 100 == 0){ + for(player in waitingPlayers) { + player.sendMessage (colorize("%R${ticksToSeconds(nextStart - GameWorld.ticks) / 60} minutes until next game.")) + } + } + if(GameWorld.ticks >= nextStart && waitingPlayers.isNotEmpty()){ + val session = FishingTrawlerSession(DynamicRegion.create(8011), activity!!) + session.start(waitingPlayers) + sessions.add(session) + waitingPlayers.clear() + nextStart = GameWorld.ticks + WAIT_TIME + } + sessions.removeIf { session -> + if(!session.isActive && session.inactiveTicks >= 100){ + session.clearNPCs() + true + } else { + if(!session.isActive) { + session.inactiveTicks++ + } + false + } + } + return false + } + }) + } + + override fun start(player: Player?, login: Boolean, vararg args: Any?): Boolean { + player ?: return false + waitingPlayers.add(player) + return true + } + + fun addPlayer(player: Player){ + if(waitingPlayers.isEmpty()) { + nextStart = GameWorld.ticks + WAIT_TIME + player.dialogueInterpreter.sendDialogue("Trawler will leave in 2 minutes.","If you have a team get them on board now!") + } + waitingPlayers.add(player) + } + + fun removePlayer(player: Player){ + waitingPlayers.remove(player) + } + + override fun newInstance(p: Player?): ActivityPlugin { + ActivityManager.register(this) + return this + } + + override fun getSpawnLocation(): Location { + return Location.create(2667, 3161, 0) + } + + override fun defineAreaBorders(): Array { + return ftWaitingArea + } + + override fun getRestrictions(): Array { + return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.TELEPORT) + } +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/fishingtrawler/FishingTrawlerInteractionHandler.kt b/Server/src/main/content/minigame/fishingtrawler/FishingTrawlerInteractionHandler.kt new file mode 100644 index 0000000..d619d65 --- /dev/null +++ b/Server/src/main/content/minigame/fishingtrawler/FishingTrawlerInteractionHandler.kt @@ -0,0 +1,231 @@ +package content.minigame.fishingtrawler + +import core.api.clearLogoutListener +import core.game.activity.ActivityManager +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.plugin.Initializable +import org.rs09.consts.Items +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.game.system.command.sets.FISHING_TRAWLER_LEAKS_PATCHED +import core.game.system.command.sets.STATS_BASE +import kotlin.math.ceil + +/** + * Option handler for fishing trawler + * @author Ceikry + */ +class FishingTrawlerInteractionHandler : InteractionListener { + val ENTRANCE_PLANK = 2178 + val EXIT_PLANK = 2179 + val HOLE = 2167 + val NETIDs = intArrayOf(2164,2165) + val REWARD_NET = 2166 + val BARREL_IDS = intArrayOf(2159,2160) + val BAILING_BUCKET = 583 + val FULL_BAIL_BUCKET = 585 + + override fun defineListeners() { + + on(ENTRANCE_PLANK, IntType.SCENERY, "cross"){ player, _ -> + if(player.skills.getLevel(Skills.FISHING) < 15){ + player.dialogueInterpreter.sendDialogue("You need to be at least level 15 fishing to play.") + return@on true + } + player.properties.teleportLocation = Location.create(2672, 3170, 1) + (ActivityManager.getActivity("fishing trawler") as FishingTrawlerActivity).addPlayer(player) + return@on true + } + + on(EXIT_PLANK, IntType.SCENERY, "cross"){ player, _ -> + player.properties.teleportLocation = Location.create(2676, 3170, 0) + (ActivityManager.getActivity("fishing trawler") as FishingTrawlerActivity).removePlayer(player) + val session: FishingTrawlerSession? = player.getAttribute("ft-session",null) + session?.players?.remove(player) + return@on true + } + + on(HOLE, IntType.SCENERY, "fill"){ player, node -> + val session: FishingTrawlerSession? = player.getAttribute("ft-session",null) + session ?: return@on false + player.lock() + player.pulseManager.run(object : Pulse(){ + var counter = 0 + override fun pulse(): Boolean { + when(counter++){ + 0 -> player.animator.animate(Animation(827)).also { player.lock() } + 1 -> session.repairHole(player,node.asScenery()).also { player.incrementAttribute("/save:$STATS_BASE:$FISHING_TRAWLER_LEAKS_PATCHED"); player.unlock() } + 2 -> return true + } + return false + } + }) + return@on true + } + + on(NETIDs, IntType.SCENERY, "inspect"){ player, _ -> + player.dialogueInterpreter.open(18237583) + return@on true + } + + on(REWARD_NET, IntType.SCENERY, "inspect"){ player, _ -> + val rolls = player.getAttribute("/save:ft-rolls", 0) + if (rolls == 0) { + player.dialogueInterpreter.sendDialogues(player, core.game.dialogue.FacialExpression.GUILTY,"I'd better not go stealing other people's fish.") + return@on true + } + player.dialogueInterpreter.open(18237582) + return@on true + } + + on(BARREL_IDS, IntType.SCENERY, "climb-on"){ player, _ -> + player.properties.teleportLocation = Location.create(2672, 3222, 0) + player.dialogueInterpreter.sendDialogue("You climb onto the floating barrel and begin to kick your way to the","shore.","You make it to the shore tired and weary.") + player.appearance.setDefaultAnimations() + player.appearance.sync() + clearLogoutListener(player, "ft-logout") + player.locks.unlockTeleport() + return@on true + } + + on(FULL_BAIL_BUCKET, IntType.ITEM, "empty"){ player, node -> + player.lock() + player.pulseManager.run( + object : Pulse(){ + var counter = 0 + override fun pulse(): Boolean { + when(counter++){ + 0 -> player.animator.animate(Animation(2450)) + 1 -> { + if(player.inventory.remove(node.asItem())) + player.inventory.add(Item(Items.BAILING_BUCKET_583)) + player.unlock() + return true + } + } + return false + } + } + ) + return@on true + } + + on(BAILING_BUCKET, IntType.ITEM, "bail-with") { player, node -> + val session: FishingTrawlerSession? = player.getAttribute("ft-session",null) + session ?: return@on false + if(!session.isActive){ + return@on false + } + if(player.location.z > 0){ + player.sendMessage("You can't scoop water out up here.") + return@on true + } + player.lock() + player.pulseManager.run( + object : Pulse(){ + var counter = 0 + override fun pulse(): Boolean { + when(counter++){ + 0 -> player.animator.animate(Animation(4471)) + 1 -> if(player.inventory.remove(node.asItem())) { + if (session.waterAmount > 0) { + session.waterAmount -= 20 + if (session.waterAmount < 0) session.waterAmount = 0 + player.inventory.add(Item(Items.BAILING_BUCKET_585)) + } else { + player.sendMessage("There's no water to remove.") + player.inventory.add(node.asItem()) + } + } + 2 -> player.unlock().also { return true } + } + return false + } + } + ) + return@on true + } + } +} + +@Initializable +class NetLootDialogue(player: Player? = null): core.game.dialogue.DialoguePlugin(player){ + var session: FishingTrawlerSession? = null + var rolls = 0 + override fun newInstance(player: Player?): core.game.dialogue.DialoguePlugin { + return NetLootDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + rolls = player.getAttribute("/save:ft-rolls", 0) + if (rolls == 0) return false + player.dialogueInterpreter.sendOptions("Skip Junk Items?","Yes","No") + stage = 0 + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + val level = player.skills.getLevel(Skills.FISHING) + when(buttonId){ + 1 -> TrawlerLoot.addLootAndMessage(player, level, rolls, true) + 2 -> TrawlerLoot.addLootAndMessage(player, level, rolls, false) + } + player.skills.addExperience(Skills.FISHING,(((0.015 * player.skills.getLevel(Skills.FISHING))) * player.skills.getLevel(Skills.FISHING)) * rolls) + player.removeAttribute("ft-rolls") + end() + return true + } + + override fun getIds(): IntArray { + return intArrayOf(18237582) + } + +} + +@Initializable +class NetRepairDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin(player){ + var session: FishingTrawlerSession? = null + override fun newInstance(player: Player?): core.game.dialogue.DialoguePlugin { + return NetRepairDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + session = player.getAttribute("ft-session",null) + if(session!!.netRipped){ + player.dialogueInterpreter.sendDialogue("The net is ripped and needs repair.") + stage = 10 + } else { + player.dialogueInterpreter.sendDialogue("The net is in perfect condition") + stage = 0 + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + session ?: return false + when(stage++){ + 0 -> end() + 10 -> player.dialogueInterpreter.sendOptions("Repair the net?","Yes","No") + 11 -> when(buttonId){ + 1 -> { + end() + session!!.repairNet(player) + } + else -> {} + } + 12 -> end() + } + + return true + } + + override fun getIds(): IntArray { + return intArrayOf(18237583) + } + +} diff --git a/Server/src/main/content/minigame/fishingtrawler/FishingTrawlerOverlay.kt b/Server/src/main/content/minigame/fishingtrawler/FishingTrawlerOverlay.kt new file mode 100644 index 0000000..9b9ad7e --- /dev/null +++ b/Server/src/main/content/minigame/fishingtrawler/FishingTrawlerOverlay.kt @@ -0,0 +1,27 @@ +package content.minigame.fishingtrawler + +import core.game.node.entity.player.Player +import core.api.* + +private const val configIndex = 391 +private const val interfaceID = 366 +private const val netOkayChild = 27 +private const val netRippedChild = 28 +private const val fishChild = 29 +private const val timeChild = 30 + + +/** + * Handles updating the fishing trawler overlay interface + * @author Ceikry + */ +object FishingTrawlerOverlay { + @JvmStatic + fun sendUpdate(player: Player, waterPercent: Int, NetRipped: Boolean, fishCaught: Int, timeLeft: Int){ + setVarp(player, configIndex, waterPercent) + player.packetDispatch.sendInterfaceConfig(interfaceID,if(NetRipped) netRippedChild else netOkayChild, false) + player.packetDispatch.sendInterfaceConfig(interfaceID,if(NetRipped) netOkayChild else netRippedChild, true) + player.packetDispatch.sendString("${if(fishCaught > 0) fishCaught else "Nothing"}", interfaceID, fishChild) + player.packetDispatch.sendString("$timeLeft Minutes", interfaceID, timeChild) + } +} diff --git a/Server/src/main/content/minigame/fishingtrawler/FishingTrawlerRewardInterface.kt b/Server/src/main/content/minigame/fishingtrawler/FishingTrawlerRewardInterface.kt new file mode 100644 index 0000000..5d606af --- /dev/null +++ b/Server/src/main/content/minigame/fishingtrawler/FishingTrawlerRewardInterface.kt @@ -0,0 +1,42 @@ +package content.minigame.fishingtrawler + +import core.game.component.Component +import core.game.component.ComponentDefinition +import core.game.component.ComponentPlugin +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Plugin +import kotlin.math.ceil + +/** + * THIS will have to be implemented at a later date. + * Interface 367 in our cache, for whatever reason, opens correctly but all the children + * are null or cant hold items. This interface cant even be opened in 2 different versions + * of a cache editor I have. Something is completely fucked about this interface + * in particular. + */ +class FishingTrawlerRewardInterface : ComponentPlugin() { + override fun newInstance(arg: Any?): Plugin { + ComponentDefinition.put(367,this) + return this + } + + override fun open(player: Player?, component: Component?) { + super.open(player, component) + val session: FishingTrawlerSession? = player?.getAttribute("ft-session",null) + session ?: return + + val numRolls = ceil(session.fishAmount / session.players.size.toDouble()).toInt() + player?.removeAttribute("ft-session") + + val loot = ArrayList() + for(i in 0 until numRolls){ + + } + } + + override fun handle(player: Player?, component: Component?, opcode: Int, button: Int, slot: Int, itemId: Int): Boolean { + TODO("Not yet implemented") + } + +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/fishingtrawler/FishingTrawlerSession.kt b/Server/src/main/content/minigame/fishingtrawler/FishingTrawlerSession.kt new file mode 100644 index 0000000..3cabb8d --- /dev/null +++ b/Server/src/main/content/minigame/fishingtrawler/FishingTrawlerSession.kt @@ -0,0 +1,311 @@ +package content.minigame.fishingtrawler + +import core.api.MapArea +import core.api.getRegionBorders +import core.api.* +import core.game.component.Component +import core.game.node.entity.Entity +import core.game.node.scenery.Scenery +import core.game.node.scenery.SceneryBuilder +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.game.world.GameWorld +import core.game.world.map.Location +import core.game.world.map.build.DynamicRegion +import core.game.world.map.zone.ZoneBorders +import core.game.world.map.zone.ZoneRestriction +import core.game.world.update.flag.context.Animation +import core.tools.* +import org.rs09.consts.Components +import org.rs09.consts.Items +import core.game.system.command.sets.FISHING_TRAWLER_GAMES_WON +import core.game.system.command.sets.FISHING_TRAWLER_SHIPS_SANK +import core.game.system.command.sets.STATS_BASE +import core.tools.secondsToTicks +import core.tools.ticksToSeconds +import java.util.concurrent.TimeUnit +import kotlin.math.ceil +import kotlin.random.Random + + +/** + * Handles a fishing trawler session + * @author Ceikry + */ +private const val OVERLAY_ID = Components.TRAWLER_OVERLAY_366 +private const val TUTORIAL_ID = Components.TRAWLER_START_368 +private val HOLE_X_COORDS = intArrayOf(29,30,31,32,33,34,35,36) +private const val HOLE_NORTH_Y = 26 +private const val HOLE_SOUTH_Y = 23 +private const val LEAKING_ID = 2167 +private const val PATCHED_ID = 2168 + +class FishingTrawlerSession(val activity: FishingTrawlerActivity? = null) : MapArea { + constructor(region: DynamicRegion, activity: FishingTrawlerActivity) : this(activity) {this.region = region; this.base = region.baseLocation} + var players: ArrayList = ArrayList() + var netRipped = false + var fishAmount = 0 + var timeLeft = secondsToTicks(600) + lateinit var region: DynamicRegion + lateinit var base: Location + var isActive = false + var boatSank = false + var hole_locations = ArrayList() + var used_locations = ArrayList() + var maxHoles = 0 + var waterAmount = 0 + var murphy: NPC? = null + val murphyLocations = ArrayList() + val npcs = ArrayList() + var inactiveTicks = 0 + + fun start(pl: ArrayList){ + if(RandomFunction.roll(2)) { + region.setMusicId(38) + } else { + region.setMusicId(51) + } + this.players.addAll(pl) + isActive = true + initHoles() + initMurphy(29,25) + initGulls() + GameWorld.Pulser.submit(TrawlerPulse(this)) + for(player in pl){ + player.interfaceManager.openOverlay(Component(OVERLAY_ID)) + player.interfaceManager.open(Component(TUTORIAL_ID)) + updateOverlay(player) + player.properties.teleportLocation = base.transform(36,24,0) + player.setAttribute("ft-session",this) + registerLogoutListener(player, "ft-logout") { + val session = player.getAttribute("ft-session",null) ?: return@registerLogoutListener + player.location = Location.create(2667, 3161, 0) + session.players.remove(player) + player.locks.unlockTeleport() + } + } + zone.register(getRegionBorders(region.id)) + } + + fun swapBoatType(fromRegion: Int){ + val newRegion = DynamicRegion.create(fromRegion) + GameWorld.Pulser.submit(SwapBoatPulse(players,newRegion)) + } + + class SwapBoatPulse(val playerList: ArrayList,val newRegion: DynamicRegion) : Pulse(3){ + override fun pulse(): Boolean { + val session: FishingTrawlerSession? = playerList[0].getAttribute("ft-session",null) + session ?: return true + session.region = newRegion + session.base = newRegion.baseLocation + session.clearNPCs() + session.initMurphy(26,26) + session.initGulls() + for(player in playerList){ + player.interfaceManager.closeOverlay() + player.appearance.setAnimations(Animation(188)) + player.properties.teleportLocation = session.base.transform(36,24,0) + player.incrementAttribute("/save:$STATS_BASE:$FISHING_TRAWLER_SHIPS_SANK") + } + return true + } + } + + class TrawlerPulse(val session: FishingTrawlerSession) : Pulse(){ + var ticks = 0 + override fun pulse(): Boolean { + ticks++ + session.timeLeft-- + + if(session.boatSank){ + session.tickMurphy() + return true + } + + if(ticks % 15 == 0 && !session.netRipped){ + if(RandomFunction.random(100) <= 10){ + session.ripNet() + session.murphy?.sendChat("Arrh! Check that net!") + } else { + session.fishAmount += 3 + } + } + + session.waterAmount += (session.getLeakingHoles()) + if(session.waterAmount >= 500){ + session.boatSank = true + session.isActive = false + session.swapBoatType(7755) + session.zone.unregister(getRegionBorders(session.region.id)) + for(player in session.players) { + player.locks.lockTeleport(1000000) + } + } + + if(RandomFunction.random(100) <= 9){ + session.spawnHole() + } + + if(session.timeLeft <= 0){ + session.isActive = false + for(player in session.players){ + player.interfaceManager.closeOverlay() + player.properties.teleportLocation = Location.create(2666, 3162, 0) + player.incrementAttribute("/save:$STATS_BASE:$FISHING_TRAWLER_GAMES_WON") + val rolls = ceil(session.fishAmount / session.players.size.toDouble()).toInt() + player.removeAttribute("ft-session") + player.setAttribute("/save:ft-rolls", rolls) + clearLogoutListener(player, "ft-logout") + } + session.zone.unregister(getRegionBorders(session.region.id)) + } + + for(player in session.players){ + session.updateOverlay(player) + if(session.timeLeft <= 1) { + lockInteractions(player, 2) + } + } + session.tickMurphy() + return !session.isActive + } + } + + fun initHoles(){ + maxHoles = players.size + if(maxHoles > 16) maxHoles = 16 + if(maxHoles < 5) maxHoles = 5 + val tempLocationList = ArrayList() + while(tempLocationList.size < maxHoles){ + val x = HOLE_X_COORDS.random() + val y = if(Random.nextBoolean()) HOLE_NORTH_Y else HOLE_SOUTH_Y + val loc = Location.create(x,y,0) + var alreadyHas = false + for(location in tempLocationList){ + if(location.equals(loc)) { + alreadyHas = true + break + } + } + if(!alreadyHas) { + tempLocationList.add(base.transform(loc.x, loc.y, 0)) + } + } + hole_locations.addAll(tempLocationList) + } + + fun initMurphy(localX: Int, localY: Int){ + murphy = NPC(463) + murphy?.isWalks = false + murphy?.isPathBoundMovement = true + //29,25 -> 36,25 + murphy?.location = base.transform(localX,localY,0) + murphy?.isRespawn = false + for(i in 29..36){ + murphyLocations.add(Location.create(base.transform(i,25,0))) + } + murphy?.init() + npcs.add(murphy!!) + } + + fun clearNPCs(){ + npcs.forEach { + it.clear() + } + npcs.clear() + } + + fun tickMurphy(){ + var phrase = if(boatSank){ + arrayOf("No fishes for you today!","Keep your head above water, shipmate.", "Arrrgh! We sunk!","You'll be joining Davy Jones!").random() + } else if(waterAmount < 200){ + arrayOf("Blistering barnacles!","Let's get a net full of fishes!").random() + } else { + arrayOf("We'll all end up in a watery grave!","My mother could bail better than that!","It's a fierce sea today traveller.").random() + } + if(getLeakingHoles() > 0 && RandomFunction.random(100) <= 15){ + phrase = "The water is coming in matey!" + } + if(RandomFunction.random(100) <= 10){ + murphy?.sendChat(phrase) + } + if(RandomFunction.random(100) <= 6){ + val dest = murphyLocations.random() + murphy?.walkingQueue?.reset() + murphy?.walkingQueue?.addPath(dest.x,dest.y,true) + } + } + + fun initGulls(){ + for(loc in arrayOf(base.transform(38,17,0),base.transform(33,18,0),base.transform(28,16,0),base.transform(28,30,0),base.transform(34,32,0))){ + val npc = NPC(1179) + npc.location = loc + npcs.add(npc) + npc.isRespawn = false + npc.isWalks = true + npc.walkRadius = 6 + npc.init() + } + } + + fun spawnHole(){ + if(hole_locations.isEmpty() && used_locations.isEmpty()) return + val holeLocation = hole_locations.random().also { hole_locations.remove(it) } + if(!SceneryBuilder.replace(Scenery(PATCHED_ID, holeLocation), Scenery(LEAKING_ID, holeLocation, if (holeLocation.y == HOLE_NORTH_Y) 1 else 3)) && !SceneryBuilder.replace(Scenery(2177, holeLocation), Scenery(LEAKING_ID, holeLocation, if (holeLocation.y == HOLE_NORTH_Y) 1 else 3))) { + maxHoles -= 1 + } + } + + fun getLeakingHoles(): Int{ + return maxHoles - hole_locations.size + } + + fun repairHole(player: Player,obj: Scenery){ + if(player.inventory.remove(Item(Items.SWAMP_PASTE_1941))){ + SceneryBuilder.replace(obj, Scenery(PATCHED_ID, obj.location, obj.rotation)) + hole_locations.add(obj.location) + if(RandomFunction.random(100) <= 30){ + murphy?.sendChat("That's the stuff! Fill those holes!") + } + } else { + player.dialogueInterpreter.sendDialogue("You need swamp paste to repair this.") + } + } + + fun ripNet(){ + netRipped = true + } + + fun repairNet(player: Player){ + if(player.inventory.remove(Item(Items.ROPE_954))){ + netRipped = false + player.dialogueInterpreter.sendDialogue("You repair the net.") + } else { + player.dialogueInterpreter.sendDialogue("You need rope to repair this net.") + } + } + + fun updateOverlay(player: Player){ + FishingTrawlerOverlay.sendUpdate(player, ((waterAmount / 500.0) * 100).toInt(), netRipped, fishAmount, TimeUnit.SECONDS.toMinutes(ticksToSeconds(timeLeft).toLong()).toInt() + 1) + } + + override fun defineAreaBorders(): Array { + return arrayOf() + } + + override fun getRestrictions(): Array { + return arrayOf(ZoneRestriction.CANNON, ZoneRestriction.FIRES, ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.TELEPORT) + } + + override fun areaEnter(entity: Entity) { + super.areaEnter(entity) + log(this::class.java, Log.FINE, "ENTERED FTZ") + } + + override fun areaLeave(entity: Entity, logout: Boolean) { + super.areaLeave(entity, logout) + log(this::class.java, Log.FINE, "EXITED FTZ") + } +} diff --git a/Server/src/main/content/minigame/fishingtrawler/TrawlerLoot.kt b/Server/src/main/content/minigame/fishingtrawler/TrawlerLoot.kt new file mode 100644 index 0000000..87ed06d --- /dev/null +++ b/Server/src/main/content/minigame/fishingtrawler/TrawlerLoot.kt @@ -0,0 +1,112 @@ +package content.minigame.fishingtrawler + +import content.global.skill.fishing.Fish +import core.api.Container +import core.api.addItem +import core.api.addItemOrDrop +import core.api.splitLines +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.IronmanMode +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import core.game.node.item.WeightedChanceItem +import core.tools.RandomFunction +import core.tools.colorize +import org.rs09.consts.Items + +/** + * Rolls/stores the loot table for fishing trawler + * @author Ceikry, RiL + */ +object TrawlerLoot { + private val junkItems = arrayOf(Items.BROKEN_ARMOUR_698, Items.BROKEN_ARROW_687, Items.OLD_BOOT_685, Items.BROKEN_GLASS_1469, Items.BROKEN_STAFF_689, Items.BUTTONS_688,Items.DAMAGED_ARMOUR_697, Items.RUSTY_SWORD_686, Items.EMPTY_POT_1931, Items.OYSTER_407) + private val trawlerFish = arrayOf(Fish.MANTA_RAY, Fish.SEA_TURTLE, Fish.SHARK, Fish.SWORDFISH, Fish.LOBSTER, Fish.TUNA, Fish.ANCHOVIE, Fish.SARDINE, Fish.SHRIMP) + private val trawlerFishIds = arrayOf(Items.RAW_MANTA_RAY_389, Items.RAW_SEA_TURTLE_395, Items.RAW_SHARK_383, Items.RAW_SWORDFISH_371, Items.RAW_LOBSTER_377, Items.RAW_TUNA_359, Items.RAW_ANCHOVIES_321, Items.RAW_SARDINE_327, Items.RAW_SHRIMPS_317) + private val trawlerMisc = arrayOf(Items.LOOP_HALF_OF_A_KEY_987, Items.TOOTH_HALF_OF_A_KEY_985, Items.CASKET_405, Items.PIRATES_HAT_2651, Items.LUCKY_CUTLASS_7140) + + private fun rollTrawlerFish(fishLevel: Int): Item { + while(true) { + for(f in trawlerFish) { + if(f.level > fishLevel) { + continue + } + val lo = 0.6133 + val hi = 0.7852 + //val chance = RandomFunction.getSkillSuccessChance(lo, hi, fishLevel) + val chance = (fishLevel.toDouble() - 15.0)*((hi - lo) / (99.0 - 15.0)) + lo + if(RandomFunction.random(0.0, 1.0) < chance) { + return Item(f.id) + } + } + } + } + + @JvmStatic + fun getLoot(fishLevel: Int, rolls: Int, skipJunk: Boolean): ArrayList{ + val loot = ArrayList() + for(i in 0 until rolls){ + val item = RandomFunction.rollWeightedChanceTable(listOf(*lootTable)) + if(item.id == 0) { + loot.add(rollTrawlerFish(fishLevel)) + } else if (!skipJunk || item.id !in junkItems) { + loot.add(item) + } + } + return loot + } + + /** + * Add Fishing trawler loot to [player] bank. Send message with summary of the loot + */ + @JvmStatic + fun addLootAndMessage(player: Player, fishLevel: Int, rolls: Int, skipJunk: Boolean) { + if (rolls < 1) return + val frequencyList = listOf>(HashMap(), HashMap(), HashMap()) + getLoot(fishLevel, rolls, skipJunk).forEach { + when (it.id) { + in trawlerFishIds -> frequencyList[0].merge(it.id, 1, Int::plus) + in trawlerMisc -> frequencyList[1].merge(it.id, 1, Int::plus) + in junkItems -> frequencyList[2].merge(it.id, 1, Int::plus) + } + } + // Extract and join each frequency map's entries as items + frequencyList.forEachIndexed { idx, fMap -> + if (fMap.isNotEmpty()) { + // Give reward + fMap.forEach { + if (player.ironmanManager.mode == IronmanMode.ULTIMATE || !addItem(player, it.key, it.value, Container.BANK)) { + val notedIdIfFish = if (idx == 0) it.key + 1 else it.key + addItemOrDrop(player, notedIdIfFish, it.value) + } + } + // Split based on length, then send each line as message + splitLines( + fMap.entries.joinToString(prefix = if (idx == 0) "Fish: " else if (idx == 1) "Misc: " else "Junk: ", postfix = ".") { "${Item(it.key).name}: ${it.value}" }, + 85 + ).forEach { player.sendMessage(it) } + } + } + if (player.ironmanManager.mode != IronmanMode.ULTIMATE) { + player.sendMessage(colorize("%RYour reward has been sent to your bank:")) + } + } + + private val lootTable = arrayOf( + WeightedChanceItem(0,1,1430), + WeightedChanceItem(Items.BROKEN_ARROW_687,1,70), + WeightedChanceItem(Items.BROKEN_GLASS_1469,1,70), + WeightedChanceItem(Items.BROKEN_STAFF_689,1,70), + WeightedChanceItem(Items.BUTTONS_688,1,80), + WeightedChanceItem(Items.DAMAGED_ARMOUR_697,1,70), + WeightedChanceItem(Items.OLD_BOOT_685,1,60), + WeightedChanceItem(Items.OYSTER_407,1,50), + WeightedChanceItem(Items.EMPTY_POT_1931,1,50), + WeightedChanceItem(Items.RUSTY_SWORD_686,1,50), + //Inauthentic rewards + WeightedChanceItem(Items.LOOP_HALF_OF_A_KEY_987,1,7), + WeightedChanceItem(Items.TOOTH_HALF_OF_A_KEY_985,1,7), + WeightedChanceItem(Items.CASKET_405,1,60), + WeightedChanceItem(Items.PIRATES_HAT_2651,1,2), + WeightedChanceItem(Items.LUCKY_CUTLASS_7140,1,2) + ) +} diff --git a/Server/src/main/content/minigame/fog/FOGActivityPlugin.java b/Server/src/main/content/minigame/fog/FOGActivityPlugin.java new file mode 100644 index 0000000..05fb53d --- /dev/null +++ b/Server/src/main/content/minigame/fog/FOGActivityPlugin.java @@ -0,0 +1,91 @@ +package content.minigame.fog; + +import core.cache.def.impl.SceneryDefinition; +import core.game.activity.ActivityPlugin; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.game.world.map.zone.ZoneBorders; +import core.plugin.Plugin; +import core.plugin.ClassScanner; + +/** + * Represents the fist of guthix activity. + * @author Vexia + */ +public class FOGActivityPlugin extends ActivityPlugin { + + /** + * The maximum amount of players in a game. + */ + public static final int MAX_PLAYERS = 250; + + /** + * The waiting interface id. + */ + public static final int WAITING_INTERFACE = 731; + + /** + * The current fist of guthix round. + */ + private int round; + + /** + * Constructs a new {@code FOGActivityPlugin} {@code Object} + */ + public FOGActivityPlugin() { + super("Fist of Guthix", false, true, true); + } + + @Override + public ActivityPlugin newInstance(Player p) throws Throwable { + return new FOGActivityPlugin(); + } + + @Override + public Location getSpawnLocation() { + return null; + } + + @Override + public void configure() { + ClassScanner.definePlugin(new FOGLobbyZone()); + ClassScanner.definePlugin(new FOGWaitingZone()); + ClassScanner.definePlugin(new OptionHandler() { + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(30204).getHandlers().put("option:enter", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + switch (node.getId()) { + case 30204: + player.teleport(Location.create(1675, 5599, 0)); + return true; + } + return true; + } + }); + register(new ZoneBorders(1625, 5638, 1715, 5747)); + } + + /** + * Gets the round. + * @return the round + */ + public int getRound() { + return round; + } + + /** + * Sets the round. + * @param round the round to set. + */ + public void setRound(int round) { + this.round = round; + } + +} diff --git a/Server/src/main/content/minigame/fog/FOGLobbyZone.java b/Server/src/main/content/minigame/fog/FOGLobbyZone.java new file mode 100644 index 0000000..e34a021 --- /dev/null +++ b/Server/src/main/content/minigame/fog/FOGLobbyZone.java @@ -0,0 +1,75 @@ +package content.minigame.fog; + +import core.game.component.Component; +import core.game.interaction.Option; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBuilder; +import core.plugin.Plugin; + +/** + * Represents a zone where players can prepare for a game. + * @author Vexia + */ +public class FOGLobbyZone extends MapZone implements Plugin { + + /** + * Constructs a new {@code FOGHallZone} {@code Object} + */ + public FOGLobbyZone() { + super("Fog Lobby", true); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ZoneBuilder.configure(this); + return this; + } + + @Override + public boolean enter(Entity e) { + if (e.isPlayer()) { + sendInterface(e.asPlayer()); + } + return super.enter(e); + } + + @Override + public boolean interact(Entity e, Node target, Option option) { + if (!e.isPlayer()) { + return super.interact(e, target, option); + } + Player player = e.asPlayer(); + switch (target.getId()) { + case 30203: + player.teleport(Location.create(3242, 3574, 0)); + return true; + } + return super.interact(e, target, option); + } + + /** + * Sends the fist of guthix lobby interface. + * @param player the player. + */ + private void sendInterface(Player player) { + player.getInterfaceManager().openOverlay(new Component(FOGActivityPlugin.WAITING_INTERFACE)); + player.getPacketDispatch().sendInterfaceConfig(FOGActivityPlugin.WAITING_INTERFACE, 17, true); + player.getPacketDispatch().sendInterfaceConfig(FOGActivityPlugin.WAITING_INTERFACE, 26, true); + player.getPacketDispatch().sendString("Rating: " + player.getSavedData().getActivityData().getFogRating(), FOGActivityPlugin.WAITING_INTERFACE, 7); + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public void configure() { + super.registerRegion(6743); + } + +} diff --git a/Server/src/main/content/minigame/fog/FOGPlayer.java b/Server/src/main/content/minigame/fog/FOGPlayer.java new file mode 100644 index 0000000..ad015a1 --- /dev/null +++ b/Server/src/main/content/minigame/fog/FOGPlayer.java @@ -0,0 +1,104 @@ +package content.minigame.fog; + +import core.game.node.entity.player.Player; + +/** + * Represents a fist of guthix player. + * @author Vexia + */ +public class FOGPlayer { + + /** + * The player instance. + */ + private final Player player; + + /** + * The target FOG player. + */ + private final FOGPlayer target; + + /** + * If the player is hunted or a hunter. + */ + private boolean hunted; + + /** + * The amount of fist of guthix charges. + */ + private int charges; + + /** + * Constructs a new {@code FOGPlayer} {@code Object} + * @param player the player. + * @param oponent the other player. + */ + public FOGPlayer(Player player, FOGPlayer oponent) { + this.player = player; + this.target = oponent; + } + + /** + * Switches the roles of the player. + */ + public void switchRoles() { + hunted = !hunted; + } + + /** + * Increments the energy charges. + * @param increment the number to increment. + */ + public void incrementCharges(int increment) { + charges += increment; + } + + /** + * Gets the hunted. + * @return the hunted + */ + public boolean isHunted() { + return hunted; + } + + /** + * Sets the hunted. + * @param hunted the hunted to set. + */ + public void setHunted(boolean hunted) { + this.hunted = hunted; + } + + /** + * Gets the charges. + * @return the charges + */ + public int getCharges() { + return charges; + } + + /** + * Sets the charges. + * @param charges the charges to set. + */ + public void setCharges(int charges) { + this.charges = charges; + } + + /** + * Gets the player. + * @return the player + */ + public Player getPlayer() { + return player; + } + + /** + * Gets the target. + * @return the target + */ + public FOGPlayer getTarget() { + return target; + } + +} diff --git a/Server/src/main/content/minigame/fog/FOGRewardsInterface.kt b/Server/src/main/content/minigame/fog/FOGRewardsInterface.kt new file mode 100644 index 0000000..d09b39b --- /dev/null +++ b/Server/src/main/content/minigame/fog/FOGRewardsInterface.kt @@ -0,0 +1,126 @@ +package content.minigame.fog + +import core.api.log +import core.cache.def.impl.ItemDefinition +import core.game.component.Component +import core.game.component.ComponentDefinition +import core.game.component.ComponentPlugin +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import core.plugin.Plugin +import core.tools.Log +import core.tools.SystemLogger + +@Initializable +class FOGRewardsInterface : ComponentPlugin(){ + class ShopItem(val id: Int,val price: Int,val amount: Int) + + override fun handle(player: Player?, component: Component?, opcode: Int, button: Int, slot: Int, itemId: Int): Boolean { + var choice = ShopItem(0, 0, 0) + when(button){ + 2 -> choice = Druidic_Mage_Top + 7 -> choice = Druidic_Mage_Bottom + 12 -> choice = Druidic_Mage_Hood + 19 -> choice = Combat_Robe_Top + 24 -> choice = Combat_Robe_Bottom + 29 -> choice = Combat_Robe_Hood + 36 -> choice = Battle_Robe_Top + 41 -> choice = Battle_Robe_Bottom + 46 -> choice = Battle_Robe_Hood + 53 -> choice = Green_Coif + 58 -> choice = Blue_Coif + 63 -> choice = Red_Coif + 68 -> choice = Black_Coif + 75 -> choice = Bronze_Gaunt + 80 -> choice = Iron_Gaunt + 85 -> choice = Steel_Gaunt + 90 -> choice = Black_Gaunt + 95 -> choice = Mithril_Gaunt + 100 -> choice = Adamant_Gaunt + 105 -> choice = Rune_Gaunt + 110 -> choice = Dragon_Gaunt + 117 -> choice = Addy_Spike + 122 -> choice = Addy_Beserk + 127 -> choice = Rune_Spike + 132 -> choice = Rune_Beserk + 139 -> choice = Irit_Gloves + 144 -> choice = Avantoe_Gloves + 149 -> choice = Kwuarm_Gloves + 154 -> choice = Cadantine_Gloves + 161 -> choice = Swordfish_Gloves + 166 -> choice = Shark_Gloves + 171 -> choice = Dragon_Gloves + 176 -> choice = Air_Gloves + 181 -> choice = Water_Gloves + 186 -> choice = Earth_Gloves + else -> log(this::class.java, Log.WARN, "Unhandled button ID for FOG interface: $button").also { return true } + } + handleOpcode(choice,opcode,player!!) + return true + } + + override fun newInstance(arg: Any?): Plugin { + ComponentDefinition.forId(732).plugin = this + return this + } + + private fun handleOpcode(item: ShopItem, opcode: Int, player: Player){ + when(opcode){ + 155 -> player.sendMessage("${ItemDefinition.forId(item.id).name.replace("100","")}: costs ${item.price} tokens.") + 196 -> handleBuyOption(item,1,player) + 124 -> handleBuyOption(item,5,player) + 199 -> handleBuyOption(item,10,player) + 234 -> player.sendMessage(ItemDefinition.forId(item.id).examine.replace("100","")) + } + } + + private fun handleBuyOption(item: ShopItem, amount: Int, player: Player){ + val neededTokens = Item(12852,item.price * amount) + if(player.inventory.containsItem(neededTokens)){ + if(player.inventory.hasSpaceFor(Item(item.id,amount))){ + player.inventory.remove(neededTokens) + player.inventory.add(Item(item.id,amount)) + } else { + player.sendMessage("You don't have enough space in your inventory.") + } + } + } + + + val Druidic_Mage_Top = (ShopItem(12894, 300, 1)) + val Druidic_Mage_Hood = (ShopItem(12887, 100, 1)) + val Druidic_Mage_Bottom = (ShopItem(12901, 200, 1)) + val Combat_Robe_Top = (ShopItem(12971, 150, 1)) + val Combat_Robe_Hood = (ShopItem(12964, 50, 1)) + val Combat_Robe_Bottom = (ShopItem(12978, 100, 1)) + val Battle_Robe_Hood = (ShopItem(12866, 250, 1)) + val Battle_Robe_Top = (ShopItem(12873, 1500, 1)) + val Battle_Robe_Bottom = (ShopItem(12880, 1000, 1)) + val Green_Coif = (ShopItem(12936, 150, 1)) + val Blue_Coif = (ShopItem(12943, 200, 1)) + val Red_Coif = (ShopItem(12950, 300, 1)) + val Black_Coif = (ShopItem(12957, 500, 1)) + val Bronze_Gaunt = (ShopItem(12985, 15, 1)) + val Iron_Gaunt = (ShopItem(12988, 30, 1)) + val Steel_Gaunt = (ShopItem(12991, 50, 1)) + val Black_Gaunt = (ShopItem(12994, 75, 1)) + val Mithril_Gaunt = (ShopItem(12997, 100, 1)) + val Adamant_Gaunt = (ShopItem(13000, 150, 1)) + val Rune_Gaunt = (ShopItem(13003, 200, 1)) + val Dragon_Gaunt = (ShopItem(13006, 300, 1)) + val Addy_Spike = (ShopItem(12908, 50, 1)) + val Addy_Beserk = (ShopItem(12915, 100, 1)) + val Rune_Spike = (ShopItem(12922, 200, 1)) + val Rune_Beserk = (ShopItem(12929, 300, 1)) + val Air_Gloves = (ShopItem(12863, 75, 1)) + val Water_Gloves = (ShopItem(12864, 75, 1)) + val Earth_Gloves = (ShopItem(12865, 75, 1)) + val Irit_Gloves = (ShopItem(12856, 75, 1)) + val Avantoe_Gloves = (ShopItem(12857, 100, 1)) + val Kwuarm_Gloves = (ShopItem(12858, 200, 1)) + val Cadantine_Gloves = (ShopItem(12859, 200, 1)) + val Swordfish_Gloves = (ShopItem(12860, 200, 1)) + val Shark_Gloves = (ShopItem(12861, 200, 1)) + val Dragon_Gloves = (ShopItem(12862, 200, 1)) +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/fog/FOGWaitingZone.java b/Server/src/main/content/minigame/fog/FOGWaitingZone.java new file mode 100644 index 0000000..d7ff0c9 --- /dev/null +++ b/Server/src/main/content/minigame/fog/FOGWaitingZone.java @@ -0,0 +1,49 @@ +package content.minigame.fog; + +import core.game.interaction.Option; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBuilder; +import core.plugin.Plugin; + +/** + * Represents the zone where players wait for a match. + * @author Vexia + */ +public class FOGWaitingZone extends MapZone implements Plugin { + + /** + * Constructs a new {@code FOGLobbyZone} {@code Object} + */ + public FOGWaitingZone() { + super("Fog Waiting Room", true); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ZoneBuilder.configure(this); + return this; + } + + @Override + public boolean enter(Entity e) { + return super.enter(e); + } + + @Override + public boolean interact(Entity e, Node target, Option option) { + return super.interact(e, target, option); + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public void configure() { + super.registerRegion(6487); + } + +} diff --git a/Server/src/main/content/minigame/fog/FogInteractionHandler.kt b/Server/src/main/content/minigame/fog/FogInteractionHandler.kt new file mode 100644 index 0000000..8f7b2e8 --- /dev/null +++ b/Server/src/main/content/minigame/fog/FogInteractionHandler.kt @@ -0,0 +1,45 @@ +package content.minigame.fog + +import core.game.global.action.ClimbActionHandler +import core.game.interaction.DestinationFlag +import core.game.interaction.MovementPulse +import core.game.node.Node +import core.game.node.scenery.Scenery +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.plugin.Plugin +import core.game.interaction.PluginInteraction +import core.game.interaction.PluginInteractionManager + +@Initializable +class FogInteractionHandler : PluginInteraction(30204, 30203){ + + override fun handle(player: Player?, node: Node?): Boolean { + when(node?.id){ + 30204 -> player?.pulseManager?.run(ClimbPulse(player,node as Scenery)).also { return true } + 30203 -> player?.pulseManager?.run(ClimbPulse(player, node as Scenery)).also { return true } + } + return false + } + + class ClimbPulse(val player: Player,val obj: Scenery) : MovementPulse(player,obj, DestinationFlag.OBJECT){ + override fun pulse(): Boolean { + player.faceLocation(obj.location) + when(obj.id) { + 30204 -> ClimbActionHandler.climbLadder(player, obj, "climb-down") + 30203 -> ClimbActionHandler.climbLadder(player,obj,"climb-up") + } + return true + } + } + + override fun fireEvent(identifier: String?, vararg args: Any?): Any { + return Unit + } + + override fun newInstance(arg: Any?): Plugin { + PluginInteractionManager.register(this, PluginInteractionManager.InteractionType.OBJECT) + return this + } + +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/fog/ReggieDialogue.kt b/Server/src/main/content/minigame/fog/ReggieDialogue.kt new file mode 100644 index 0000000..be5618d --- /dev/null +++ b/Server/src/main/content/minigame/fog/ReggieDialogue.kt @@ -0,0 +1,63 @@ +package content.minigame.fog + +import core.game.component.Component +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.world.GameWorld +import core.plugin.Initializable + +@Initializable +class ReggieDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin(player){ + override fun open(vararg args: Any?): Boolean { + if(GameWorld.settings?.allow_token_purchase == true){ + options("Can I see your shop?","Nevermind.","Can I buy some tokens?") + } else { + options("Can I see your shop?","Nevermind.") + } + stage = 0 + return true + } + + override fun newInstance(player: Player?): core.game.dialogue.DialoguePlugin { + FOGRewardsInterface().newInstance(Unit) + return ReggieDialogue(player) + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + var buyAmount = 0 + when(stage){ + 0 -> when(buttonId){ + 1 -> npc("Certainly!").also { stage++ } + 2 -> end() + 3 -> npc("Sure thing. My tokens are 1000 coins","each.").also { stage = 10 } + } + 1 -> end().also { player.interfaceManager.open(Component(732)) } + + //Buying tokens with config option set to true + 10 -> player?.dialogueInterpreter?.sendOptions("How many?","50","100","250","500").also { stage++ } + 11 -> when(buttonId){ + 1 -> buyAmount = 50 + 2 -> buyAmount = 100 + 3 -> buyAmount = 250 + 4 -> buyAmount = 500 + else -> buyAmount = 0 + }.also { + if(buyAmount > 0){ + if(player?.inventory?.containsItem(Item(995, 1000 * buyAmount))!!) { + player?.inventory?.add(Item(12852, buyAmount)) + player?.inventory?.remove(Item(995, 1000 * buyAmount)) + } else { + player?.sendMessage("You dont have enough coins for that.") + } + } + end() + } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(7601) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/gnomecooking/DeliveryBoxHandler.kt b/Server/src/main/content/minigame/gnomecooking/DeliveryBoxHandler.kt new file mode 100644 index 0000000..55d6657 --- /dev/null +++ b/Server/src/main/content/minigame/gnomecooking/DeliveryBoxHandler.kt @@ -0,0 +1,32 @@ +package content.minigame.gnomecooking + +import core.cache.def.impl.ItemDefinition +import core.game.interaction.OptionHandler +import core.game.node.Node +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import core.plugin.Plugin + +@Initializable +class DeliveryBoxHandler : OptionHandler() { + override fun newInstance(arg: Any?): Plugin { + ItemDefinition.forId(9477).handlers["option:check"] = this + return this + } + + override fun handle(player: Player?, node: Node?, option: String?): Boolean { + player ?: return false + val jobId = player.getAttribute("$GC_BASE_ATTRIBUTE:$GC_JOB_ORDINAL",-1) + if(jobId == -1){ + player.dialogueInterpreter.sendDialogue("You do not currently have a job.") + } else { + val job = GnomeCookingJob.values()[jobId] + val item = player.getAttribute("$GC_BASE_ATTRIBUTE:$GC_NEEDED_ITEM", Item(0)) + player.dialogueInterpreter.sendDialogue("I need to deliver a ${item.name.toLowerCase()} to ${NPC(job.npc_id).name.toLowerCase()},","who is ${job.tip}") + } + return true + } + +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/gnomecooking/GCCompletionDialogue.kt b/Server/src/main/content/minigame/gnomecooking/GCCompletionDialogue.kt new file mode 100644 index 0000000..d069e96 --- /dev/null +++ b/Server/src/main/content/minigame/gnomecooking/GCCompletionDialogue.kt @@ -0,0 +1,41 @@ +package content.minigame.gnomecooking + +import content.minigame.gnomecooking.GnomeTipper.getTip +import core.game.node.item.Item +import core.game.dialogue.DialogueFile +import core.tools.END_DIALOGUE +import core.tools.colorize + +class GCCompletionDialogue(val job: GnomeCookingJob) : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when(stage){ + 0 -> { + val neededItem = player!!.getAttribute("$GC_BASE_ATTRIBUTE:$GC_NEEDED_ITEM", null) + if (neededItem != null && player!!.inventory.containsItem(neededItem)) { + player!!.dialogueInterpreter.sendDialogues(job.npc_id, core.game.dialogue.FacialExpression.OLD_HAPPY, "Thank you!") + player!!.inventory.remove(neededItem) + player!!.inventory.add(getTip(job.level)) + player!!.removeAttribute("$GC_BASE_ATTRIBUTE:$GC_JOB_ORDINAL") + player!!.removeAttribute("$GC_BASE_ATTRIBUTE:$GC_NEEDED_ITEM") + var curPoints = player!!.getAttribute("$GC_BASE_ATTRIBUTE:$GC_POINTS", 0) + curPoints += 3 + if (curPoints == 12) { + player!!.inventory.add(Item(9474)) + player!!.sendMessage(colorize("%RYou have been granted a food delivery token. Use it to have food delivered.")) + } else if (curPoints % 12 == 0) { + var curRedeems = player!!.getAttribute("$GC_BASE_ATTRIBUTE:$GC_REDEEMABLE_FOOD", 0) + player!!.setAttribute( + "/save:$GC_BASE_ATTRIBUTE:$GC_REDEEMABLE_FOOD", + if (curRedeems != 10) ++curRedeems else curRedeems + ) + player!!.sendMessage(colorize("%RYou have been granted a single food delivery charge.")) + } + player!!.setAttribute("/save:$GC_BASE_ATTRIBUTE:$GC_POINTS", curPoints) + } else { + player!!.dialogueInterpreter.sendDialogues(job.npc_id, core.game.dialogue.FacialExpression.ANGRY, "Where's my food?!") + } + stage = END_DIALOGUE + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/gnomecooking/GCRewardTokenHandler.kt b/Server/src/main/content/minigame/gnomecooking/GCRewardTokenHandler.kt new file mode 100644 index 0000000..4ab4ea7 --- /dev/null +++ b/Server/src/main/content/minigame/gnomecooking/GCRewardTokenHandler.kt @@ -0,0 +1,107 @@ +package content.minigame.gnomecooking + +import core.cache.def.impl.ItemDefinition +import core.game.interaction.OptionHandler +import core.game.node.Node +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.plugin.Initializable +import core.plugin.Plugin +import core.tools.RandomFunction +import org.rs09.consts.Items +import core.game.world.GameWorld + +val gnomeItems = arrayOf( + Items.FRUIT_BATTA_2277, Items.TOAD_BATTA_2255, Items.CHEESE_PLUSTOM_BATTA_2259, Items.WORM_BATTA_2253, Items.VEGETABLE_BATTA_2281, + Items.CHOCOLATE_BOMB_2185, Items.VEG_BALL_2195, Items.TANGLED_TOADS_LEGS_2187, Items.WORM_HOLE_2191, Items.TOAD_CRUNCHIES_2217, Items.WORM_CRUNCHIES_2205, Items.CHOCCHIP_CRUNCHIES_2209, Items.SPICY_CRUNCHIES_2213) + +@Initializable +class GCRewardTokenHandler : OptionHandler() { + override fun newInstance(arg: Any?): Plugin { + val def = ItemDefinition.forId(9474) + def.handlers["option:check"] = this + def.handlers["option:activate"] = this + return this + } + + override fun handle(player: Player?, node: Node?, option: String?): Boolean { + player ?: return false + node ?: return false + option ?: return false + + when(option){ + "check" -> { + val charges = player.getAttribute("$GC_BASE_ATTRIBUTE:$GC_REDEEMABLE_FOOD",0) + player.dialogueInterpreter.sendDialogue("You have $charges redeemable charges.") + } + "activate" -> { + player.dialogueInterpreter.open(939382893) + } + } + return true + } + + @Initializable + class RewardTokenActivationDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin(player){ + override fun newInstance(player: Player?): core.game.dialogue.DialoguePlugin { + return RewardTokenActivationDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + player.dialogueInterpreter.sendOptions("How many charges?","1","5","10") + stage = 0 + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> end().also { + when (buttonId) { + 1 -> sendCharges(1, player) + 2 -> sendCharges(5, player) + 3 -> sendCharges(10, player) + } + } + } + return true + } + + fun sendCharges(amount: Int, player: Player){ + val playerCharges = player.getAttribute("$GC_BASE_ATTRIBUTE:$GC_REDEEMABLE_FOOD",0) + if(playerCharges < amount){ + player.dialogueInterpreter.sendDialogue("You don't have that many charges.") + return + } + + if(player.inventory.freeSlots() < amount){ + player.dialogueInterpreter.sendDialogue("You don't have enough space in your inventory.") + return + } + + val itemList = ArrayList() + + for(charge in 0 until amount){ + itemList.add(Item(gnomeItems.random())) + } + + player.dialogueInterpreter.sendDialogue("You put in for delivery of $amount items. Wait a bit...") + GameWorld.Pulser.submit(DeliveryPulse(player,itemList)) + player.setAttribute("/save:$GC_BASE_ATTRIBUTE:$GC_REDEEMABLE_FOOD", playerCharges - amount) + } + + class DeliveryPulse(val player: Player,val items: ArrayList) : Pulse(RandomFunction.random(15,30)){ + override fun pulse(): Boolean { + player.inventory.add(*items.toTypedArray()) + player.dialogueInterpreter.sendDialogue("Your food delivery has arrived!") + return true + } + } + + override fun getIds(): IntArray { + return intArrayOf(939382893) + } + + } + +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/gnomecooking/GnomeCookingConstants.kt b/Server/src/main/content/minigame/gnomecooking/GnomeCookingConstants.kt new file mode 100644 index 0000000..80363f1 --- /dev/null +++ b/Server/src/main/content/minigame/gnomecooking/GnomeCookingConstants.kt @@ -0,0 +1,11 @@ +package content.minigame.gnomecooking + +const val GC_BASE_ATTRIBUTE = "gnome_cooking" +const val GC_TUT_PROG = "gnome-cooking:tutorial:stage" +const val GC_TUT_FIN = "gnome-cooking:tutorial:complete" +const val GC_JOB_ORDINAL = "job:job_ordinal" +const val GC_JOB_COMPLETE = "job:job_complete" +const val GC_HARD_JOB = "job:hard_job" +const val GC_NEEDED_ITEM = "job:needed_item" +const val GC_POINTS = "job:points" +const val GC_REDEEMABLE_FOOD = "job:redeemable_food" diff --git a/Server/src/main/content/minigame/gnomecooking/GnomeCookingJob.kt b/Server/src/main/content/minigame/gnomecooking/GnomeCookingJob.kt new file mode 100644 index 0000000..bf718b4 --- /dev/null +++ b/Server/src/main/content/minigame/gnomecooking/GnomeCookingJob.kt @@ -0,0 +1,19 @@ +package content.minigame.gnomecooking + +enum class GnomeCookingJob(val level: GnomeTipper.LEVEL, val npc_id: Int, val tip: String) { + CPT_ERRDO(GnomeTipper.LEVEL.EASY,3811, "at the top level of the Grand Tree."), + DALILAH(GnomeTipper.LEVEL.EASY,4588, "sitting in the Gnome Restaurant."), + GULLUCK(GnomeTipper.LEVEL.EASY,602, "on the third level of the Grand Tree."), + ROMETTI(GnomeTipper.LEVEL.EASY,601, "on the second level of the Grand Tree."), + NARNODE(GnomeTipper.LEVEL.EASY,670, "at the base of the Grand Tree."), + MEEGLE(GnomeTipper.LEVEL.EASY,4597, "in the terrorbird enclosure."), + PERRDUR(GnomeTipper.LEVEL.EASY,4587,"sitting in the Gnome Restaurant."), + SARBLE(GnomeTipper.LEVEL.EASY,4599, "in the swamp west of the Grand Tree."), + GIMLEWAP(GnomeTipper.LEVEL.HARD,4580, "upstairs in Ardougne castle."), + BLEEMADGE(GnomeTipper.LEVEL.HARD,3810, "at the top of White Wolf Mountain."), + DALBUR(GnomeTipper.LEVEL.HARD,3809, "by the gnome glider in Al Kharid"), + BOLREN(GnomeTipper.LEVEL.HARD,469, "next to the Spirit Tree in Tree Gnome Village"), + SCHEPBUR(GnomeTipper.LEVEL.HARD,3817, "in the battlefield of Khazar, south of the river."), + IMBLEWYN(GnomeTipper.LEVEL.HARD,4586, "on the ground floor of the Magic Guild."), + ONGLEWIP(GnomeTipper.LEVEL.HARD,4585, "in the Wizard's Tower south of Draynor.") +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/gnomecooking/GnomeTipper.kt b/Server/src/main/content/minigame/gnomecooking/GnomeTipper.kt new file mode 100644 index 0000000..2a37668 --- /dev/null +++ b/Server/src/main/content/minigame/gnomecooking/GnomeTipper.kt @@ -0,0 +1,68 @@ +package content.minigame.gnomecooking + +import core.game.node.item.Item +import core.game.node.item.WeightedChanceItem +import core.tools.RandomFunction +import org.rs09.consts.Items + +object GnomeTipper { + private val easyTips = arrayListOf( + WeightedChanceItem(995,50,100,30), + WeightedChanceItem(995,23,76,50), + WeightedChanceItem(995,10,250,20) + ) + + private val hardTips = arrayListOf( + //Uniques Weight = 18 + WeightedChanceItem(Items.GNOME_GOGGLES_9472,1,2), + WeightedChanceItem(Items.GNOME_SCARF_9470,1,2), + WeightedChanceItem(Items.GRAND_SEED_POD_9469,5,7), + WeightedChanceItem(Items.MINT_CAKE_9475,1,4), + WeightedChanceItem(Items.GNOMEBALL_751,1,4), + //Herbs Weight = 20 + WeightedChanceItem(Items.CLEAN_TOADFLAX_2998,3,10), + WeightedChanceItem(Items.CLEAN_SNAPDRAGON_3000,1,10), + //Uncut Gems Weight = 46 + WeightedChanceItem(Items.RED_TOPAZ_1613,1,8), + WeightedChanceItem(Items.DIAMOND_1601,1,7), + WeightedChanceItem(Items.UNCUT_EMERALD_1621,3,5,7), + WeightedChanceItem(Items.UNCUT_JADE_1627,2,3,7), + WeightedChanceItem(Items.UNCUT_SAPPHIRE_1623,6,10,8), + WeightedChanceItem(Items.UNCUT_RUBY_1619,2,3,7), + WeightedChanceItem(Items.UNCUT_OPAL_1625,1,10), + //Runes Weight = 25 + WeightedChanceItem(Items.COSMIC_RUNE_564,11,5), + WeightedChanceItem(Items.NATURE_RUNE_561,10,15,5), + WeightedChanceItem(Items.LAW_RUNE_563,10,5), + WeightedChanceItem(Items.DEATH_RUNE_560,11,5), + WeightedChanceItem(Items.SOUL_RUNE_566,9,5), + //Untipped crossbow bolts Weight = 9 + WeightedChanceItem(Items.MITHRIL_BOLTS_UNF_9379,5,10,3), + WeightedChanceItem(Items.ADAMANT_BOLTSUNF_9380,3,5,3), + WeightedChanceItem(Items.RUNITE_BOLTS_UNF_9381,1,3,3), + //Other tips + WeightedChanceItem(Items.LOOP_HALF_OF_A_KEY_987,1,9), + WeightedChanceItem(Items.TOOTH_HALF_OF_A_KEY_985,1,9), + WeightedChanceItem(Items.PURE_ESSENCE_7937,97,3), + WeightedChanceItem(Items.BIRDS_NEST_5072,1,2), + WeightedChanceItem(Items.YEW_SEED_5315,1,6), + WeightedChanceItem(Items.CALQUAT_TREE_SEED_5290,1,6) + + ) + + enum class LEVEL { + EASY, + HARD + } + + @JvmStatic + fun getTip(level: LEVEL): Item { + return when(level){ + LEVEL.EASY -> RandomFunction.rollWeightedChanceTable(easyTips) + LEVEL.HARD -> RandomFunction.rollWeightedChanceTable(hardTips) + } + } + + + +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/gnomecooking/battas/GnomeBattaCooker.kt b/Server/src/main/content/minigame/gnomecooking/battas/GnomeBattaCooker.kt new file mode 100644 index 0000000..766c61b --- /dev/null +++ b/Server/src/main/content/minigame/gnomecooking/battas/GnomeBattaCooker.kt @@ -0,0 +1,66 @@ +package content.minigame.gnomecooking.battas + +import core.game.interaction.NodeUsageEvent +import core.game.interaction.UseWithHandler +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.game.world.update.flag.context.Animation +import core.plugin.Initializable +import core.plugin.Plugin +import org.rs09.consts.Items +import core.game.world.GameWorld + +/** + * Handles cook options for battas + * @author Ceikry + */ +@Initializable +class GnomeBattaCooker : UseWithHandler(Items.RAW_BATTA_2250,9478,9480,9482,9483,9485) { + override fun newInstance(arg: Any?): Plugin { + addHandler(17131, OBJECT_TYPE,this) + addHandler(2728, OBJECT_TYPE,this) + return this + } + + override fun handle(event: NodeUsageEvent?): Boolean { + event ?: return false + val player = event.player + val used = event.used + val product = when(used.id){ + Items.RAW_BATTA_2250 -> Item(Items.HALF_BAKED_BATTA_2249) + 9478 -> Item(9479) + 9480 -> Item(9481) + 9483 -> Item(9484) + 9485 -> Item(9486) + 9482 -> Item(2255) + else -> Item(0) + } + if(product.id == 0) return false + cook(player,used.asItem(),product) + return true + } + + fun cook(player: Player, raw: Item, product: Item){ + GameWorld.Pulser.submit(object : Pulse(){ + var counter = 0 + override fun pulse(): Boolean { + when(counter++){ + 0 -> player.lock().also { player.animator.animate(Animation(883)) } + 2 -> { + if(player.inventory.containsItem(raw)) { + player.inventory.remove(raw) + player.inventory.add(product) + if(product.id == 2255) player.skills.addExperience(Skills.COOKING,82.0) + else player.skills.addExperience(Skills.COOKING,40.0) + } + player.unlock() + return true + } + } + return false + } + }) + } +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/gnomecooking/battas/GnomeBattaDishFiller.kt b/Server/src/main/content/minigame/gnomecooking/battas/GnomeBattaDishFiller.kt new file mode 100644 index 0000000..29ffc19 --- /dev/null +++ b/Server/src/main/content/minigame/gnomecooking/battas/GnomeBattaDishFiller.kt @@ -0,0 +1,36 @@ +package content.minigame.gnomecooking.battas + +import core.game.interaction.NodeUsageEvent +import core.game.interaction.UseWithHandler +import core.game.node.item.Item +import core.plugin.Initializable +import core.plugin.Plugin +import org.rs09.consts.Items + +private const val GIANNE_DOUGH = 2171 +private const val BATTA_MOULD = 2164 +private const val RAW_CRUNCHIES = 2202 + +/** + * Fills gnome batta dishes + * @author Ceikry + */ +@Initializable +class GnomeBattaDishFiller : UseWithHandler(GIANNE_DOUGH) { + override fun newInstance(arg: Any?): Plugin { + addHandler(BATTA_MOULD, ITEM_TYPE,this) + return this + } + + override fun handle(event: NodeUsageEvent?): Boolean { + event ?: return false + val player = event.player + val used = event.used + val with = event.usedWith + player.inventory.remove(used.asItem()) + player.inventory.remove(with.asItem()) + player.inventory.add(Item(Items.RAW_BATTA_2250)) + return true + } + +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/gnomecooking/battas/GnomeBattaGarnisher.kt b/Server/src/main/content/minigame/gnomecooking/battas/GnomeBattaGarnisher.kt new file mode 100644 index 0000000..034919a --- /dev/null +++ b/Server/src/main/content/minigame/gnomecooking/battas/GnomeBattaGarnisher.kt @@ -0,0 +1,51 @@ +package content.minigame.gnomecooking.battas + +import core.game.interaction.NodeUsageEvent +import core.game.interaction.UseWithHandler +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.plugin.Initializable +import core.plugin.Plugin +import org.rs09.consts.Items + +/** + * Handles garnishing of battas + * @author Ceikry + */ +@Initializable +class GnomeBattaGarnisher : UseWithHandler(9479,9481,9484,9486) { + override fun newInstance(arg: Any?): Plugin { + addHandler(Items.EQUA_LEAVES_2128, ITEM_TYPE,this) + addHandler(Items.GNOME_SPICE_2169, ITEM_TYPE,this) + return this + } + + override fun handle(event: NodeUsageEvent?): Boolean { + event ?: return false + val player = event.player + val used = event.used.asItem() + val with = event.usedWith.asItem() + var product = -1 + when(with.id){ + Items.EQUA_LEAVES_2128 -> { + when(used.id){ + 9486 -> product = Items.WORM_BATTA_2253 + 9484 -> product = Items.VEGETABLE_BATTA_2281 + 9479 -> product = Items.CHEESE_PLUSTOM_BATTA_2259 + } + } + + Items.GNOME_SPICE_2169 -> { + when(used.id){ + 9481 -> product = Items.FRUIT_BATTA_2277 + } + } + } + if(product == -1) return false + player.inventory.remove(used) + player.inventory.remove(with) + player.inventory.add(Item(product)) + player.skills.addExperience(Skills.COOKING,88.0) + return true + } +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/gnomecooking/battas/GnomeBattaInterface.kt b/Server/src/main/content/minigame/gnomecooking/battas/GnomeBattaInterface.kt new file mode 100644 index 0000000..d8872bf --- /dev/null +++ b/Server/src/main/content/minigame/gnomecooking/battas/GnomeBattaInterface.kt @@ -0,0 +1,97 @@ +package content.minigame.gnomecooking.battas + +import core.game.component.Component +import core.game.component.ComponentDefinition +import core.game.component.ComponentPlugin +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.plugin.Initializable +import core.plugin.Plugin +import org.rs09.consts.Items + + +private const val WORM_BATTA = 2219 +private const val TOAD_BATTA = 2221 +private const val CHEESE_TOM_BATTA = 2223 +private const val FRUIT_BATTA = 2225 +private const val VEG_BATTA = 2227 + +/** + * Handles the gnome batta interface + * @author Ceikry + */ +@Initializable +class GnomeBattaInterface : ComponentPlugin() { + + override fun open(player: Player?, component: Component?) { + component ?: return + player ?: return + super.open(player, component) + player.packetDispatch.sendItemOnInterface(FRUIT_BATTA,component.id,component.id,3) + player.packetDispatch.sendItemOnInterface(TOAD_BATTA,component.id,component.id,14) + player.packetDispatch.sendItemOnInterface(WORM_BATTA,component.id,component.id,25) + player.packetDispatch.sendItemOnInterface(VEG_BATTA,component.id,component.id,34) + player.packetDispatch.sendItemOnInterface(CHEESE_TOM_BATTA,component.id,component.id,47) + } + + + override fun handle(player: Player?, component: Component?, opcode: Int, button: Int, slot: Int, itemId: Int): Boolean { + player ?: return false + component ?: return false + + when(button){ + 3 -> attemptMake(CookedProduct.HALF_MADE_FR,player) + 14 -> attemptMake(CookedProduct.HALF_MADE_TO,player) + 25 -> attemptMake(CookedProduct.HALF_MADE_WO,player) + 34 -> attemptMake(CookedProduct.HALF_MADE_VE,player) + 47 -> attemptMake(CookedProduct.HALF_MADE_CT,player) + } + return true + } + + private fun attemptMake(batta: CookedProduct, player: Player){ + if(!player.inventory.containsItem(Item(Items.GNOME_SPICE_2169)) && (batta == CookedProduct.HALF_MADE_TO || batta == CookedProduct.HALF_MADE_WO) ){ + player.dialogueInterpreter.sendDialogue("You need gnome spices for this.") + return + } + + if(player.skills.getLevel(Skills.COOKING) < batta.levelReq){ + player.dialogueInterpreter.sendDialogue("You don't have the needed level to make this.") + return + } + + var hasAll = true + for(item in batta.requiredItems){ + if(!player.inventory.containsItem(item)){ + hasAll = false + break + } + } + + if(!hasAll){ + player.dialogueInterpreter.sendDialogue("You don't have all the ingredients needed for this.") + return + } + + player.inventory.remove(*batta.requiredItems) + player.inventory.remove(Item(Items.HALF_BAKED_BATTA_2249)) + player.inventory.add(Item(batta.product)) + player.skills.addExperience(Skills.COOKING,batta.experience) + player.interfaceManager.close() + } + + internal enum class CookedProduct(val product: Int,val levelReq: Int, val experience: Double, val requiredItems: Array){ + HALF_MADE_CT(9478,29,40.0, arrayOf(Item(Items.TOMATO_1982), Item(Items.CHEESE_1985))), + HALF_MADE_FR(9480,25,40.0, arrayOf(Item(Items.EQUA_LEAVES_2128,4), Item(Items.LIME_CHUNKS_2122), Item(Items.ORANGE_CHUNKS_2110), Item(Items.PINEAPPLE_CHUNKS_2116))), + HALF_MADE_TO(9482,26,40.0, arrayOf(Item(Items.EQUA_LEAVES_2128), Item(Items.CHEESE_1985), Item(Items.TOADS_LEGS_2152))), + HALF_MADE_VE(9483,28,40.0, arrayOf(Item(Items.TOMATO_1982,2), Item(Items.CHEESE_1985), Item(Items.DWELLBERRIES_2126), Item(Items.ONION_1957), Item(Items.CABBAGE_1965))), + HALF_MADE_WO(9485,27,40.0, arrayOf(Item(Items.KING_WORM_2162), Item(Items.CHEESE_1985))) + } + + override fun newInstance(arg: Any?): Plugin { + ComponentDefinition.put(434,this) + return this + } + +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/gnomecooking/battas/GnomeBattaPrepareHandler.kt b/Server/src/main/content/minigame/gnomecooking/battas/GnomeBattaPrepareHandler.kt new file mode 100644 index 0000000..38cecd4 --- /dev/null +++ b/Server/src/main/content/minigame/gnomecooking/battas/GnomeBattaPrepareHandler.kt @@ -0,0 +1,29 @@ +package content.minigame.gnomecooking.battas + +import core.cache.def.impl.ItemDefinition +import core.game.component.Component +import core.game.interaction.OptionHandler +import core.game.node.Node +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.plugin.Plugin +import org.rs09.consts.Items + +/** + * Handles the prepare option for gnome battas + * @author Ceikry + */ +@Initializable +class GnomeBattaPrepareHandler : OptionHandler() { + override fun newInstance(arg: Any?): Plugin { + ItemDefinition.forId(Items.HALF_BAKED_BATTA_2249).handlers["option:prepare"] = this + return this + } + + override fun handle(player: Player?, node: Node?, option: String?): Boolean { + player ?: return false + player.interfaceManager.open(Component(434)) + return true + } + +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/gnomecooking/bowls/GnomeBowlCooker.kt b/Server/src/main/content/minigame/gnomecooking/bowls/GnomeBowlCooker.kt new file mode 100644 index 0000000..00b7977 --- /dev/null +++ b/Server/src/main/content/minigame/gnomecooking/bowls/GnomeBowlCooker.kt @@ -0,0 +1,64 @@ +package content.minigame.gnomecooking.bowls + +import core.game.interaction.NodeUsageEvent +import core.game.interaction.UseWithHandler +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.game.world.update.flag.context.Animation +import core.plugin.Initializable +import core.plugin.Plugin +import org.rs09.consts.Items +import core.game.world.GameWorld + +@Initializable +class GnomeBowlCooker : UseWithHandler(Items.RAW_GNOMEBOWL_2178,9558,9559,9561,9563) { + override fun newInstance(arg: Any?): Plugin { + addHandler(17131, OBJECT_TYPE,this) + addHandler(2728, OBJECT_TYPE,this) + return this + } + + override fun handle(event: NodeUsageEvent?): Boolean { + event ?: return false + val player = event.player + val used = event.used + val product = when(used.id){ + Items.RAW_GNOMEBOWL_2178 -> Item(Items.HALF_BAKED_BOWL_2177) + 9558 -> Item(9560) + 9559 -> Item(Items.TANGLED_TOADS_LEGS_2187) + 9561 -> Item(9562) + 9563 -> Item(9564) + else -> Item(0) + } + if(product.id == 0) return false + cook(player,used.asItem(),product) + return true + } + + fun cook(player: Player, raw: Item, product: Item){ + GameWorld.Pulser.submit(object : Pulse(){ + var counter = 0 + override fun pulse(): Boolean { + when(counter++){ + 0 -> player.lock().also { player.animator.animate(Animation(883)) } + 2 -> { + if(player.inventory.containsItem(raw)) { + if(product.id > 2180){ + player.inventory.add(Item(Items.GNOMEBOWL_MOULD_2166)) + } + player.inventory.remove(raw) + player.inventory.add(product) + player.skills.addExperience(Skills.COOKING,30.0) + } + player.unlock() + return true + } + } + return false + } + }) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/gnomecooking/bowls/GnomeBowlGarnisher.kt b/Server/src/main/content/minigame/gnomecooking/bowls/GnomeBowlGarnisher.kt new file mode 100644 index 0000000..b1d802f --- /dev/null +++ b/Server/src/main/content/minigame/gnomecooking/bowls/GnomeBowlGarnisher.kt @@ -0,0 +1,59 @@ +package content.minigame.gnomecooking.bowls + +import core.game.interaction.NodeUsageEvent +import core.game.interaction.UseWithHandler +import core.game.node.item.Item +import core.plugin.Initializable +import core.plugin.Plugin +import org.rs09.consts.Items + +/** + * Handles garnishing of gnomebowls + * @author Ceikry + */ +@Initializable +class GnomeBowlGarnisher : UseWithHandler(9560,9562,9564) { + override fun newInstance(arg: Any?): Plugin { + addHandler(Items.EQUA_LEAVES_2128, ITEM_TYPE,this) + addHandler(Items.POT_OF_CREAM_2130, ITEM_TYPE,this) + addHandler(Items.CHOCOLATE_DUST_1975, ITEM_TYPE,this) + return this + } + + override fun handle(event: NodeUsageEvent?): Boolean { + event ?: return false + val player = event.player + val used = event.used.asItem() + val with = event.usedWith.asItem() + var product = -1 + when(with.id){ + Items.EQUA_LEAVES_2128 -> { + when(used.id){ + 9562 -> product = Items.VEG_BALL_2195 + 9564 -> product = Items.WORM_HOLE_2191 + } + } + + Items.POT_OF_CREAM_2130,Items.CHOCOLATE_DUST_1975 -> { + when(used.id){ + 9560 -> product = Items.CHOCOLATE_BOMB_2185 + } + } + } + if(product == Items.CHOCOLATE_BOMB_2185){ + val reqCream = Item(Items.POT_OF_CREAM_2130,2) + val reqChoc = Item(Items.CHOCOLATE_DUST_1975) + if(!player.inventory.containsItem(reqChoc) || !player.inventory.containsItem(reqCream)){ + player.dialogueInterpreter.sendDialogue("You don't have enough ingredients to finish that.") + return true + } + player.inventory.remove(reqCream) + player.inventory.remove(reqChoc) + } + if(product == -1) return false + player.inventory.remove(used) + player.inventory.remove(with) + player.inventory.add(Item(product)) + return true + } +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/gnomecooking/bowls/GnomeBowlInterface.kt b/Server/src/main/content/minigame/gnomecooking/bowls/GnomeBowlInterface.kt new file mode 100644 index 0000000..bd8eb1c --- /dev/null +++ b/Server/src/main/content/minigame/gnomecooking/bowls/GnomeBowlInterface.kt @@ -0,0 +1,71 @@ +package content.minigame.gnomecooking.bowls + +import core.game.component.Component +import core.game.component.ComponentDefinition +import core.game.component.ComponentPlugin +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.plugin.Initializable +import core.plugin.Plugin +import org.rs09.consts.Items + +@Initializable +class GnomeBowlInterface : ComponentPlugin() { + + override fun handle(player: Player?, component: Component?, opcode: Int, button: Int, slot: Int, itemId: Int): Boolean { + player ?: return false + component ?: return false + + when(button){ + 3 -> attemptMake(PreparedProduct.HALF_MADE_WOR_HO,player) + 12 -> attemptMake(PreparedProduct.HALF_MADE_VEG_BA,player) + 21 -> attemptMake(PreparedProduct.HALF_MADE_TAN_TO,player) + 34 -> attemptMake(PreparedProduct.HALF_MADE_CHOC_B,player) + } + return true + } + + private fun attemptMake(bowl: PreparedProduct, player: Player){ + if(!player.inventory.containsItem(Item(Items.GNOME_SPICE_2169)) && (bowl != PreparedProduct.HALF_MADE_CHOC_B) ){ + player.dialogueInterpreter.sendDialogue("You need gnome spices for this.") + return + } + + if(player.skills.getLevel(Skills.COOKING) < bowl.levelReq){ + player.dialogueInterpreter.sendDialogue("You don't have the needed level to make this.") + return + } + + var hasAll = true + for(item in bowl.requiredItems){ + if(!player.inventory.containsItem(item)){ + hasAll = false + break + } + } + + if(!hasAll){ + player.dialogueInterpreter.sendDialogue("You don't have all the ingredients needed for this.") + return + } + + player.inventory.remove(*bowl.requiredItems) + player.inventory.remove(Item(Items.HALF_BAKED_BOWL_2177)) + player.inventory.add(Item(bowl.product)) + player.interfaceManager.close() + } + + internal enum class PreparedProduct(val product: Int,val levelReq: Int, val requiredItems: Array){ + HALF_MADE_CHOC_B(9558,42, arrayOf(Item(Items.CHOCOLATE_BAR_1973,4),Item(Items.EQUA_LEAVES_2128))), + HALF_MADE_TAN_TO(9559,40, arrayOf(Item(Items.TOADS_LEGS_2152,4),Item(Items.CHEESE_1985,2),Item(Items.DWELLBERRIES_2126),Item(Items.EQUA_LEAVES_2128,2))), + HALF_MADE_VEG_BA(9561,35, arrayOf(Item(Items.POTATO_1942,2),Item(Items.ONION_1957,2))), + HALF_MADE_WOR_HO(9563,30, arrayOf(Item(Items.KING_WORM_2162,4),Item(Items.ONION_1957,2))) + } + + override fun newInstance(arg: Any?): Plugin { + ComponentDefinition.put(435,this) + return this + } + +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/gnomecooking/bowls/GnomeBowlPrepareHandler.kt b/Server/src/main/content/minigame/gnomecooking/bowls/GnomeBowlPrepareHandler.kt new file mode 100644 index 0000000..99fa956 --- /dev/null +++ b/Server/src/main/content/minigame/gnomecooking/bowls/GnomeBowlPrepareHandler.kt @@ -0,0 +1,25 @@ +package content.minigame.gnomecooking.bowls + +import core.cache.def.impl.ItemDefinition +import core.game.component.Component +import core.game.interaction.OptionHandler +import core.game.node.Node +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.plugin.Plugin +import org.rs09.consts.Items + +@Initializable +class GnomeBowlPrepareHandler : OptionHandler() { + override fun newInstance(arg: Any?): Plugin { + ItemDefinition.forId(Items.HALF_BAKED_BOWL_2177).handlers["option:prepare"] = this + return this + } + + override fun handle(player: Player?, node: Node?, option: String?): Boolean { + player ?: return false + player.interfaceManager.open(Component(435)) + return true + } + +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/gnomecooking/bowls/GnomebowlMouldFiller.kt b/Server/src/main/content/minigame/gnomecooking/bowls/GnomebowlMouldFiller.kt new file mode 100644 index 0000000..2cba2ff --- /dev/null +++ b/Server/src/main/content/minigame/gnomecooking/bowls/GnomebowlMouldFiller.kt @@ -0,0 +1,31 @@ +package content.minigame.gnomecooking.bowls + +import core.game.interaction.NodeUsageEvent +import core.game.interaction.UseWithHandler +import core.game.node.item.Item +import core.plugin.Initializable +import core.plugin.Plugin +import org.rs09.consts.Items + +private const val GNOME_BOWL_MOLD = 2166 +private const val GIANNE_DOUGH = 2171 + +@Initializable +class GnomebowlMouldFiller : UseWithHandler(GIANNE_DOUGH) { + override fun newInstance(arg: Any?): Plugin { + addHandler(GNOME_BOWL_MOLD, ITEM_TYPE,this) + return this + } + + override fun handle(event: NodeUsageEvent?): Boolean { + event ?: return false + val player = event.player + val used = event.used.asItem() + val with = event.usedWith.asItem() + player.inventory.remove(used) + player.inventory.remove(with) + player.inventory.add(Item(Items.RAW_GNOMEBOWL_2178)) + return true + } + +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/gnomecooking/cocktails/CocktailCooker.kt b/Server/src/main/content/minigame/gnomecooking/cocktails/CocktailCooker.kt new file mode 100644 index 0000000..0113074 --- /dev/null +++ b/Server/src/main/content/minigame/gnomecooking/cocktails/CocktailCooker.kt @@ -0,0 +1,61 @@ +package content.minigame.gnomecooking.cocktails + +import core.game.interaction.NodeUsageEvent +import core.game.interaction.UseWithHandler +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.game.world.GameWorld +import core.game.world.update.flag.context.Animation +import core.plugin.Initializable +import core.plugin.Plugin + +private const val UNCOOKED_CHOC_SAT = 9572 +private const val UNCOOKED_DRUN_DRA = 9576 + +/** + * Handles the cooking of certain cocktail products + * @author Ceikry + */ +@Initializable +class CocktailCooker : UseWithHandler(UNCOOKED_CHOC_SAT, UNCOOKED_DRUN_DRA) { + override fun newInstance(arg: Any?): Plugin { + addHandler(17131, OBJECT_TYPE,this) + addHandler(2728, OBJECT_TYPE,this) + return this + } + + override fun handle(event: NodeUsageEvent?): Boolean { + when(event?.used?.id){ + UNCOOKED_CHOC_SAT -> cook(CookedDrinks.COOKED_CHOC_SAT,event.player,event.usedItem) + UNCOOKED_DRUN_DRA -> cook(CookedDrinks.COOKED_DRUN_DRA,event.player,event.usedItem) + } + return true + } + + private fun cook(drink: CookedDrinks, player: Player, raw: Item){ + GameWorld.Pulser.submit(object : Pulse(){ + var counter = 0 + override fun pulse(): Boolean { + when(counter++){ + 0 -> player.lock().also { player.animator.animate(Animation(883)) } + 2 -> { + if(player.inventory.containsItem(raw)) { + player.inventory.remove(raw) + player.inventory.add(Item(drink.product)) + } + player.unlock() + return true + } + } + return false + } + }) + } + + internal enum class CookedDrinks(val product: Int){ + COOKED_CHOC_SAT(9573), + COOKED_DRUN_DRA(2092) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/gnomecooking/cocktails/CocktailFinisher.kt b/Server/src/main/content/minigame/gnomecooking/cocktails/CocktailFinisher.kt new file mode 100644 index 0000000..6eebf9c --- /dev/null +++ b/Server/src/main/content/minigame/gnomecooking/cocktails/CocktailFinisher.kt @@ -0,0 +1,61 @@ +package content.minigame.gnomecooking.cocktails + +import core.cache.def.impl.ItemDefinition +import core.game.interaction.OptionHandler +import core.game.node.Node +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import core.plugin.Plugin +import org.rs09.consts.Items + +private const val UNF_CHOC_SAT = 9573 +private const val UNF_DRUN_DRA = 9575 + +/** + * Handles adding the final ingredients to a couple cocktails + * @author Ceikry + */ +@Initializable +class CocktailFinisher : OptionHandler() { + override fun newInstance(arg: Any?): Plugin { + ItemDefinition.forId(UNF_CHOC_SAT).handlers["option:add-ingreds"] = this + ItemDefinition.forId(UNF_DRUN_DRA).handlers["option:add-ingreds"] = this + return this + } + + override fun handle(player: Player?, node: Node?, option: String?): Boolean { + player ?: return false + node ?: return false + when(node.id){ + UNF_CHOC_SAT -> attemptMake(FinishedDrinks.FIN_CHOC_SAT,player,node) + UNF_DRUN_DRA -> attemptMake(FinishedDrinks.FIN_DRUN_DRA,player,node) + } + return true + } + + private fun attemptMake(drink: FinishedDrinks, player: Player, node: Node){ + var hasAll = true + for(item in drink.requiredItems){ + if(!player.inventory.containsItem(item)){ + hasAll = false + break + } + } + + if(!hasAll){ + player.dialogueInterpreter.sendDialogue("You don't have the ingredients for this.") + return + } + + player.inventory.remove(*drink.requiredItems) + player.inventory.remove(node.asItem()) + player.inventory.add(Item(drink.product)) + } + + internal enum class FinishedDrinks(val product: Int, val requiredItems: Array){ + FIN_CHOC_SAT(2074, arrayOf(Item(Items.CHOCOLATE_DUST_1975),Item(Items.POT_OF_CREAM_2130))), + FIN_DRUN_DRA(9576, arrayOf(Item(Items.PINEAPPLE_CHUNKS_2116),Item(Items.POT_OF_CREAM_2130))) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/gnomecooking/cocktails/CocktailShakerHandler.kt b/Server/src/main/content/minigame/gnomecooking/cocktails/CocktailShakerHandler.kt new file mode 100644 index 0000000..5e4078d --- /dev/null +++ b/Server/src/main/content/minigame/gnomecooking/cocktails/CocktailShakerHandler.kt @@ -0,0 +1,29 @@ +package content.minigame.gnomecooking.cocktails + +import core.cache.def.impl.ItemDefinition +import core.game.component.Component +import core.game.interaction.OptionHandler +import core.game.node.Node +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.plugin.Plugin + +/** + * Handles the mix-cocktail option for the cocktail shaker + * @author Ceikry + */ +@Initializable +class CocktailShakerHandler : OptionHandler() { + override fun newInstance(arg: Any?): Plugin { + ItemDefinition.forId(2025).handlers["option:mix-cocktail"] = this + return this + } + + override fun handle(player: Player?, node: Node?, option: String?): Boolean { + player ?: return false + node ?: return false + player.interfaceManager.open(Component(436)) //Gnome cocktail interface + return true + } + +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/gnomecooking/cocktails/GnomeCocktailInterface.kt b/Server/src/main/content/minigame/gnomecooking/cocktails/GnomeCocktailInterface.kt new file mode 100644 index 0000000..4b9fd3e --- /dev/null +++ b/Server/src/main/content/minigame/gnomecooking/cocktails/GnomeCocktailInterface.kt @@ -0,0 +1,98 @@ +package content.minigame.gnomecooking.cocktails + +import core.game.component.Component +import core.game.component.ComponentDefinition +import core.game.component.ComponentPlugin +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.plugin.Initializable +import core.plugin.Plugin +import org.rs09.consts.Items + +private const val WIZARD_BLIZZARD = 2054 +private const val SHORT_GREEN_GUY = 2080 +private const val FRUIT_BLAST = 2084 +private const val PINEAPPLE_PUNCH = 2048 +private const val DRUNK_DRAGON = 2092 +private const val CHOC_SATURDAY = 2074 +private const val BLURBERRY_SPECIAL = 2064 + +/** + * Handles the gnome cocktail interface + * @author Ceikry + */ +@Initializable +class GnomeCocktailInterface : ComponentPlugin() { + + override fun open(player: Player?, component: Component?) { + player ?: return + component ?: return + super.open(player, component) + player.packetDispatch.sendItemOnInterface(WIZARD_BLIZZARD,1,component.id,3) + player.packetDispatch.sendItemOnInterface(SHORT_GREEN_GUY,1,component.id,16) + player.packetDispatch.sendItemOnInterface(FRUIT_BLAST,1,component.id,23) + player.packetDispatch.sendItemOnInterface(PINEAPPLE_PUNCH,1,component.id,32) + player.packetDispatch.sendItemOnInterface(DRUNK_DRAGON,1,component.id,41) + player.packetDispatch.sendItemOnInterface(CHOC_SATURDAY,1,component.id,50) + player.packetDispatch.sendItemOnInterface(BLURBERRY_SPECIAL,1,component.id,61) + } + + override fun handle(player: Player?, component: Component?, opcode: Int, button: Int, slot: Int, itemId: Int): Boolean { + player ?: return false + when(button){ + 3 -> attemptMake(FruitCocktail.WIZARD_BLIZZARD,player) + 16 -> attemptMake(FruitCocktail.SHORT_GREEN_GUY, player) + 23 -> attemptMake(FruitCocktail.FRUIT_BLAST, player) + 32 -> attemptMake(FruitCocktail.PINEAPPLE_PUNCH,player) + 41 -> attemptMake(FruitCocktail.DRUNK_DRAGON,player) + 50 -> attemptMake(FruitCocktail.CHOC_SATURDAY,player) + 61 -> attemptMake(FruitCocktail.BLURBERRY_SPEC,player) + } + return true + } + + private fun attemptMake(cocktail: FruitCocktail, player: Player){ + var hasAll = true + val cookingLevel = player.skills.getLevel(Skills.COOKING) + + if(cookingLevel < cocktail.levelReq){ + player.dialogueInterpreter.sendDialogue("You don't have the necessary level to make that.") + return + } + + for(ingredient in cocktail.requiredItems){ + if(!player.inventory.containsItem(ingredient)){ + hasAll = false + break + } + } + + if(!hasAll){ + player.dialogueInterpreter.sendDialogue("You don't have the ingredients to make that.") + return + } + + player.inventory.remove(*cocktail.requiredItems) + player.inventory.remove(Item(Items.COCKTAIL_SHAKER_2025)) + player.inventory.add(Item(cocktail.product)) + player.skills.addExperience(Skills.COOKING,cocktail.experience) + player.interfaceManager.close() + } + + override fun newInstance(arg: Any?): Plugin { + ComponentDefinition.put(436,this) + return this + } + + internal enum class FruitCocktail(val levelReq: Int, val experience: Double, val product: Int, val requiredItems: Array){ + FRUIT_BLAST(6,50.0,9568, arrayOf(Item(Items.PINEAPPLE_2114),Item(Items.LEMON_2102),Item(Items.ORANGE_2108))), + PINEAPPLE_PUNCH(8,70.0,9569, arrayOf(Item(Items.PINEAPPLE_2114,2),Item(Items.LEMON_2102),Item(Items.ORANGE_2108))), + WIZARD_BLIZZARD(18,110.0, 9566, arrayOf(Item(Items.VODKA_2015,2),Item(Items.GIN_2019),Item(Items.LIME_2120),Item(Items.LEMON_2102),Item(Items.ORANGE_2108))), + SHORT_GREEN_GUY(20,120.0,9567, arrayOf(Item(Items.VODKA_2015),Item(Items.LIME_2120,3))), + DRUNK_DRAGON(32,160.0,9574, arrayOf(Item(Items.VODKA_2015),Item(Items.GIN_2019),Item(Items.DWELLBERRIES_2126))), + CHOC_SATURDAY(33,170.0,9571, arrayOf(Item(Items.WHISKY_2017),Item(Items.CHOCOLATE_BAR_1973),Item(Items.EQUA_LEAVES_2128),Item(Items.BUCKET_OF_MILK_1927))), + BLURBERRY_SPEC(37,180.0,9570, arrayOf(Item(Items.VODKA_2015),Item(Items.BRANDY_2021),Item(Items.GIN_2019),Item(Items.LEMON_2102,2),Item(Items.ORANGE_2108))) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/gnomecooking/cocktails/PourMixerPlugin.kt b/Server/src/main/content/minigame/gnomecooking/cocktails/PourMixerPlugin.kt new file mode 100644 index 0000000..19cf50a --- /dev/null +++ b/Server/src/main/content/minigame/gnomecooking/cocktails/PourMixerPlugin.kt @@ -0,0 +1,86 @@ +package content.minigame.gnomecooking.cocktails + +import core.cache.def.impl.ItemDefinition +import core.game.interaction.OptionHandler +import core.game.node.Node +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.plugin.Initializable +import core.plugin.Plugin +import org.rs09.consts.Items + +private const val WIZ_BLIZ_MIX = 9566 +private const val SGG_MIX = 9567 +private const val F_BLAST_MIX = 9568 +private const val P_PUNCH_MIX = 9569 +private const val BLU_SPEC_MIX = 9570 +private const val CHOC_SAT_MIX = 9571 +private const val DRUNK_DRAG_MIX = 9574 +private val mixers = arrayOf(WIZ_BLIZ_MIX, SGG_MIX, F_BLAST_MIX, P_PUNCH_MIX, BLU_SPEC_MIX, CHOC_SAT_MIX, DRUNK_DRAG_MIX) + +/** + * Handles the pouring of mixed drinks into cocktail glasses + * @author Ceikry + */ +@Initializable +class PourMixerPlugin : OptionHandler() { + override fun newInstance(arg: Any?): Plugin { + for(mixer in mixers){ + ItemDefinition.forId(mixer).handlers["option:pour"] = this + } + return this + } + + override fun handle(player: Player?, node: Node?, option: String?): Boolean { + player ?: return false + node ?: return false + when(node.id){ + WIZ_BLIZ_MIX -> attemptMake(PouredDrink.WIZ_BLIZZ,player,node) + SGG_MIX -> attemptMake(PouredDrink.SHORT_G_G,player,node) + F_BLAST_MIX -> attemptMake(PouredDrink.FRUIT_BLAST,player,node) + P_PUNCH_MIX -> attemptMake(PouredDrink.PINE_PUNCH,player,node) + BLU_SPEC_MIX -> attemptMake(PouredDrink.BLUR_SPEC, player,node) + CHOC_SAT_MIX -> attemptMake(PouredDrink.CHOC_SAT,player,node) + DRUNK_DRAG_MIX -> attemptMake(PouredDrink.DRUNK_DRAG,player,node) + } + return true + } + + private fun attemptMake(drink: PouredDrink, player: Player, node: Node){ + if(!player.inventory.containsItem(Item(Items.COCKTAIL_GLASS_2026))){ + player.dialogueInterpreter.sendDialogue("You need a glass to pour this into.") + return + } + + var hasAll = true + for(ingredient in drink.requiredItems){ + if(!player.inventory.containsItem(ingredient)){ + hasAll = false + } + } + + if(!hasAll){ + player.dialogueInterpreter.sendDialogue("You don't have the garnishes for this.") + return + } + + player.inventory.remove(*drink.requiredItems) + player.inventory.remove(node.asItem()) + player.inventory.remove(Item(Items.COCKTAIL_GLASS_2026)) + player.inventory.add(Item(drink.product)) + player.inventory.add(Item(Items.COCKTAIL_SHAKER_2025)) + player.skills.addExperience(Skills.COOKING,50.0) + } + + internal enum class PouredDrink(val product: Int, val requiredItems: Array){ + FRUIT_BLAST(9514, arrayOf(Item(Items.LEMON_SLICES_2106))), + PINE_PUNCH(9512, arrayOf(Item(Items.LIME_CHUNKS_2122),Item(Items.PINEAPPLE_CHUNKS_2116),Item(Items.ORANGE_SLICES_2112))), + WIZ_BLIZZ(9508, arrayOf(Item(Items.PINEAPPLE_CHUNKS_2116),Item(Items.LIME_SLICES_2124))), + SHORT_G_G(9510, arrayOf(Item(Items.LIME_SLICES_2124),Item(Items.EQUA_LEAVES_2128))), + DRUNK_DRAG(9575, arrayOf()), + CHOC_SAT(9572, arrayOf()), + BLUR_SPEC(9520, arrayOf(Item(Items.LEMON_CHUNKS_2104),Item(Items.ORANGE_CHUNKS_2110),Item(Items.EQUA_LEAVES_2128),Item(Items.LIME_SLICES_2124))), + } + +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/gnomecooking/crunchies/GnomeCrunchyCooker.kt b/Server/src/main/content/minigame/gnomecooking/crunchies/GnomeCrunchyCooker.kt new file mode 100644 index 0000000..bb360ad --- /dev/null +++ b/Server/src/main/content/minigame/gnomecooking/crunchies/GnomeCrunchyCooker.kt @@ -0,0 +1,71 @@ +package content.minigame.gnomecooking.crunchies + +import core.game.interaction.NodeUsageEvent +import core.game.interaction.UseWithHandler +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.game.world.GameWorld +import core.game.world.update.flag.context.Animation +import core.plugin.Initializable +import core.plugin.Plugin +import core.game.node.entity.skill.Skills + +private const val UNFINISHED_CRUNCHY_CHOC = 9578 +private const val UNFINISHED_CRUNCHY_SPICY = 9580 +private const val UNFINISHED_CRUNCHY_TOAD = 9582 +private const val UNFINISHED_CRUNCHY_WORM = 9584 + +/** + * handles cooking gnome crunchies, don't wanna use standard + * cooking stuff because no experience and no burn chance + * @author Ceikry + */ + +@Initializable +class GnomeCrunchyCooker : UseWithHandler(9577,9579,9581,9583, 2202){ + override fun newInstance(arg: Any?): Plugin { + addHandler(17131, OBJECT_TYPE,this) + addHandler(2728, OBJECT_TYPE,this) + return this + } + + override fun handle(event: NodeUsageEvent?): Boolean { + event ?: return false + val used = event.used.asItem() + val with = event.usedWith + val player = event.player + when(used.id){ + 9577 -> cook(UNFINISHED_CRUNCHY_CHOC,used,player) + 9579 -> cook(UNFINISHED_CRUNCHY_SPICY,used,player) + 9581 -> cook(UNFINISHED_CRUNCHY_TOAD,used,player) + 9583 -> cook(UNFINISHED_CRUNCHY_WORM,used,player) + 2202 -> cook(2201,used,player) + } + return true + } + + private fun cook(product: Int, raw: Item, player: Player){ + GameWorld.Pulser.submit(object : Pulse(){ + var counter = 0 + override fun pulse(): Boolean { + when(counter++){ + 0 -> player.lock().also { player.animator.animate(Animation(883)) } + 2 -> { + if(player.inventory.containsItem(raw)) { + player.inventory.remove(raw) + player.inventory.add(Item(product)) + if(raw.id != 2202) player.inventory.add(Item(2165)) + } + if(raw.id == 2202){ + player.skills.addExperience(Skills.COOKING,30.0) + } + player.unlock() + return true + } + } + return false + } + }) + } +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/gnomecooking/crunchies/GnomeCrunchyGarnisher.kt b/Server/src/main/content/minigame/gnomecooking/crunchies/GnomeCrunchyGarnisher.kt new file mode 100644 index 0000000..06c7d7c --- /dev/null +++ b/Server/src/main/content/minigame/gnomecooking/crunchies/GnomeCrunchyGarnisher.kt @@ -0,0 +1,67 @@ +package content.minigame.gnomecooking.crunchies + +import core.game.interaction.NodeUsageEvent +import core.game.interaction.UseWithHandler +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.plugin.Initializable +import core.plugin.Plugin +import org.rs09.consts.Items + +/** + * Handles garnishing gnome crunchies + * @author Ceikry + */ + +@Initializable +class GnomeCrunchyGarnisher : UseWithHandler(9578,9580,9582,9584) { + override fun newInstance(arg: Any?): Plugin { + addHandler(Items.CHOCOLATE_DUST_1975, ITEM_TYPE,this) + addHandler(Items.GNOME_SPICE_2169, ITEM_TYPE, this) + addHandler(Items.EQUA_LEAVES_2128, ITEM_TYPE, this) + return this + } + + override fun handle(event: NodeUsageEvent?): Boolean { + event ?: return false + val player = event.player + val used = event.used.asItem() + val with = event.usedWith.asItem() + + val product = when(with.id){ + Items.CHOCOLATE_DUST_1975 -> { + when(used.id){ + 9578 -> Items.CHOCCHIP_CRUNCHIES_2209 + else -> -1 + } + } + + Items.GNOME_SPICE_2169 -> { + when(used.id){ + 9584 -> Items.WORM_CRUNCHIES_2205 + 9580 -> Items.SPICY_CRUNCHIES_2213 + else -> -1 + } + } + + Items.EQUA_LEAVES_2128 -> { + when(used.id){ + 9582 -> Items.TOAD_CRUNCHIES_2217 + else -> -1 + } + } + + else -> -1 + } + + if(product == -1) return false + + player.inventory.remove(used) + if(with.id != Items.GNOME_SPICE_2169) + player.inventory.remove(with) + player.inventory.add(Item(product)) + player.skills.addExperience(Skills.COOKING,64.0) + return true + } + +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/gnomecooking/crunchies/GnomeCrunchyInterface.kt b/Server/src/main/content/minigame/gnomecooking/crunchies/GnomeCrunchyInterface.kt new file mode 100644 index 0000000..4785ef3 --- /dev/null +++ b/Server/src/main/content/minigame/gnomecooking/crunchies/GnomeCrunchyInterface.kt @@ -0,0 +1,91 @@ +package content.minigame.gnomecooking.crunchies + +import core.game.component.Component +import core.game.component.ComponentDefinition +import core.game.component.ComponentPlugin +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.plugin.Initializable +import core.plugin.Plugin +import org.rs09.consts.Items + +private const val TOAD_CRUNCHIES = 9538 +private const val SPICE_CRUNCHIES = 9540 +private const val CHOC_CHIP_CRUNCHIES = 9544 +private const val WORM_CRUNCHIES = 9542 +private const val HALF_BAKED_CRUNCHY = 2201 + +/** + * Handles the gnome crunchy interface + * @author Ceikry + */ +@Initializable +class GnomeCrunchyInterface : ComponentPlugin() { + + override fun handle(player: Player?, component: Component?, opcode: Int, button: Int, slot: Int, itemId: Int): Boolean { + player ?: return false + when(button){ + 3 -> attemptMake(HalfMadeCrunchy.TOAD,player) + 10 -> attemptMake(HalfMadeCrunchy.SPICY,player) + 17 -> attemptMake(HalfMadeCrunchy.WORM,player) + 26 -> attemptMake(HalfMadeCrunchy.CHOCCHIP,player) + } + return true + } + + private fun attemptMake(crunchy: HalfMadeCrunchy, player: Player){ + var hasAll = true + + if(player.skills.getLevel(Skills.COOKING) < crunchy.reqLevel){ + player.dialogueInterpreter.sendDialogue("You don't have the required level to make these.") + return + } + + if(!player.inventory.containsItem(Item(Items.GNOME_SPICE_2169))){ + player.dialogueInterpreter.sendDialogue("You need some gnome spice to make these.") + return + } + + for(item in crunchy.requiredItems){ + if(!player.inventory.containsItem(item)){ + hasAll = false + break + } + } + + if(!hasAll){ + player.dialogueInterpreter.sendDialogue("You don't have the required ingredients to make these.") + return + } + + player.inventory.remove(*crunchy.requiredItems) + player.inventory.remove(Item(HALF_BAKED_CRUNCHY)) + player.inventory.add(Item(crunchy.product)) + player.skills.addExperience(Skills.COOKING,30.0) + player.interfaceManager.close() + } + + override fun open(player: Player?, component: Component?) { + player ?: return + component ?: return + super.open(player, component) + + player.packetDispatch.sendItemOnInterface(TOAD_CRUNCHIES,1,component.id,3) + player.packetDispatch.sendItemOnInterface(SPICE_CRUNCHIES,1,component.id,10) + player.packetDispatch.sendItemOnInterface(WORM_CRUNCHIES,1,component.id,17) + player.packetDispatch.sendItemOnInterface(CHOC_CHIP_CRUNCHIES,1,component.id,26) + } + override fun newInstance(arg: Any?): Plugin { + ComponentDefinition.put(437,this) + return this + } + + internal enum class HalfMadeCrunchy(val product: Int,val reqLevel: Int, val requiredItems: Array){ + CHOCCHIP(9577, 16, arrayOf(Item(Items.CHOCOLATE_BAR_1973,2))), + SPICY(9579, 12, arrayOf(Item(Items.EQUA_LEAVES_2128,2))), + TOAD(9581, 10, arrayOf(Item(Items.TOADS_LEGS_2152,2))), + WORM(9583, 14, arrayOf(Item(Items.EQUA_LEAVES_2128),Item(Items.KING_WORM_2162,2))) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/gnomecooking/crunchies/GnomeCrunchyPrepareHandler.kt b/Server/src/main/content/minigame/gnomecooking/crunchies/GnomeCrunchyPrepareHandler.kt new file mode 100644 index 0000000..1416148 --- /dev/null +++ b/Server/src/main/content/minigame/gnomecooking/crunchies/GnomeCrunchyPrepareHandler.kt @@ -0,0 +1,29 @@ +package content.minigame.gnomecooking.crunchies + +import core.cache.def.impl.ItemDefinition +import core.game.component.Component +import core.game.interaction.OptionHandler +import core.game.node.Node +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.plugin.Plugin + +private const val HALF_BAKED_CRUNCHY = 2201 +private const val CRUNCHY_INTERFACE = 437 + +/** + * Opens the gnome crunchy interface + */ +@Initializable +class GnomeCrunchyPrepareHandler : OptionHandler() { + override fun newInstance(arg: Any?): Plugin { + ItemDefinition.forId(HALF_BAKED_CRUNCHY).handlers["option:prepare"] = this + return this + } + + override fun handle(player: Player?, node: Node?, option: String?): Boolean { + player ?: return false + player.interfaceManager.open(Component(CRUNCHY_INTERFACE)) + return true + } +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/gnomecooking/crunchies/GnomeCrunchyTrayFiller.kt b/Server/src/main/content/minigame/gnomecooking/crunchies/GnomeCrunchyTrayFiller.kt new file mode 100644 index 0000000..039d047 --- /dev/null +++ b/Server/src/main/content/minigame/gnomecooking/crunchies/GnomeCrunchyTrayFiller.kt @@ -0,0 +1,32 @@ +package content.minigame.gnomecooking.crunchies + +import core.game.interaction.NodeUsageEvent +import core.game.interaction.UseWithHandler +import core.game.node.item.Item +import core.plugin.Initializable +import core.plugin.Plugin + +private const val GIANNE_DOUGH = 2171 +private const val CRUNCHY_TRAY = 2165 +private const val RAW_CRUNCHIES = 2202 + + +/** + * Handles adding GIANNE_DOUGH to CRUNCHY_TRAY to produce RAW_CRUNCHIES + * @author Ceikry + */ +@Initializable +class GnomeCrunchyTrayFiller : UseWithHandler(GIANNE_DOUGH) { + override fun newInstance(arg: Any?): Plugin { + addHandler(CRUNCHY_TRAY, ITEM_TYPE,this) + return this + } + + override fun handle(event: NodeUsageEvent?): Boolean { + event ?: return false + event.player.inventory.remove(event.used.asItem()) + event.player.inventory.remove(event.usedWith.asItem()) + event.player.inventory.add(Item(RAW_CRUNCHIES)) + return true + } +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/magearena/ChamberGuardianDialogue.java b/Server/src/main/content/minigame/magearena/ChamberGuardianDialogue.java new file mode 100644 index 0000000..6ceb0b0 --- /dev/null +++ b/Server/src/main/content/minigame/magearena/ChamberGuardianDialogue.java @@ -0,0 +1,138 @@ +package content.minigame.magearena; + +import core.game.dialogue.DialoguePlugin; +import content.data.GodType; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; + +/** + * Handles the chamber guardian dialogue. + * @author Vexia + */ +public final class ChamberGuardianDialogue extends DialoguePlugin { + + /** + * The god type. + */ + private GodType godType; + + /** + * Constructs a new {@code ChamberGuardianDialogue} {@code Object}. + */ + public ChamberGuardianDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code ChamberGuardianDialogue} {@code Object}. + * @param player the player. + */ + public ChamberGuardianDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new ChamberGuardianDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + if (player.getSavedData().getActivityData().hasRecievedKolodionReward()) { + player("Hello again."); + return true; + } else if (player.getSavedData().getActivityData().hasKilledKolodion()) { + npc("Hello adventurer, have you made your choice?"); + return true; + } + npc("YOU SHOULD NOT BE IN HERE!"); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + if (player.getSavedData().getActivityData().hasRecievedKolodionReward()) { + switch (stage) { + case 0: + npc("Hello adventurer, are you looking for another staff?"); + stage++; + break; + case 1: + options("What do you have to offer?", "No thanks."); + stage++; + break; + case 2: + switch (buttonId) { + case 1: + end(); + npc.openShop(player); + break; + case 2: + player("No thanks."); + stage++; + break; + } + break; + case 3: + npc("Well let me know if you need one."); + stage++; + break; + case 4: + end(); + break; + } + return true; + } else if (player.getSavedData().getActivityData().hasKilledKolodion()) { + switch (stage) { + case 0: + godType = GodType.getCape(player); + if (godType == null) { + player("Sorry, I'm still looking."); + stage++; + } else { + player("I have."); + stage += 2; + } + break; + case 1: + end(); + break; + case 2: + npc("Good, good, I hope you have chosen well. I will now", "present you with a magic staff. This, along with the", "cape awarded to you by your chosen god, are all the", "weapons and armour you will need here."); + stage++; + break; + case 3: + if (!player.getInventory().hasSpaceFor(godType.getStaff())) { + player("Sorry, I don't have enough inventory space."); + stage = 1; + return true; + } + if (player.getInventory().containsItem(godType.getCape()) || player.getEquipment().containsItem(godType.getCape())) { + stage++; + player.getInventory().add(godType.getStaff()); + player.getSavedData().getActivityData().setKolodionStage(3); + interpreter.sendItemMessage(godType.getStaff(), "The guardian hands you an ornate magic staff."); + } else { + end(); + } + break; + case 4: + end(); + break; + } + return true; + } else { + end(); + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 904 }; + } + +} diff --git a/Server/src/main/content/minigame/magearena/KolodionDialogue.java b/Server/src/main/content/minigame/magearena/KolodionDialogue.java new file mode 100644 index 0000000..5d19240 --- /dev/null +++ b/Server/src/main/content/minigame/magearena/KolodionDialogue.java @@ -0,0 +1,253 @@ +package content.minigame.magearena; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; + +/** + * Handles the kolodion dialogue. + * @author Vexia + */ +public final class KolodionDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code KolodionDialogue} {@code Object}. + */ + public KolodionDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code KolodionDialogue} {@code Object}. + * @param player the player. + */ + public KolodionDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new KolodionDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + if (player.getSavedData().getActivityData().hasStartedKolodion()) { + player("Hi."); + return true; + } + if (player.getSavedData().getActivityData().hasKilledKolodion()) { + player("Hello, Kolodion."); + return true; + } + player("Hello there. What is this place?"); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + if (player.getSavedData().getActivityData().hasStartedKolodion()) { + switch (stage) { + case 0: + npc("You return, young conjurer. You obviously have a", "taste for the dark side of magic."); + stage++; + break; + case 1: + startFight(player); + end(); + break; + } + return true; + } + if (player.getSavedData().getActivityData().hasRecievedKolodionReward()) { + switch (stage) { + case 0: + npc("Hey there, how are you? Are you enjoying the", "bloodshed?"); + stage++; + break; + case 1: + player("I think I've had enough for now."); + stage++; + break; + case 2: + npc("A shame. You're a good battle mage. I hope", "to see you soon."); + stage++; + break; + case 3: + end(); + break; + } + return true; + } else if (player.getSavedData().getActivityData().hasKilledKolodion()) { + switch (stage) { + case 0: + npc("Hello, you mage. You're a tough one."); + stage++; + break; + case 1: + player("What now?"); + stage++; + break; + case 2: + npc("Step into the magic pool. It will take you to a chamber.", "There, you must decide which god you will represent in", "the arena."); + stage++; + break; + case 3: + player("Thanks, Kolodion."); + stage++; + break; + case 4: + npc("That's what I'm here for."); + stage++; + break; + case 5: + end(); + break; + } + return true; + } + switch (stage) { + case 0: + if (player.getSkills().getStaticLevel(Skills.MAGIC) < 60) { + npc("Do not waste my time with trivial questions. I am the", "Great Kolodion, master of battle magic. I have an arena", "to run."); + stage++; + } else { + npc("I am the great Kolodion, master of battle magic, and", "this is my battle arena. Top wizards travel from all over", GameWorld.getSettings().getName() + " to fight here."); + stage = 4; + } + break; + case 1: + player("Can I enter?"); + stage++; + break; + case 2: + npc("Hah! A wizard of your level? Don't be absurd."); + stage++; + break; + case 3: + end(); + break; + case 4: + options("Can I fight here?", "What's the point of that?", "That's barbaric!"); + stage++; + break; + case 5: + switch (buttonId) { + case 1: + player("Can I fight here?"); + stage = 10; + break; + case 2: + player("What's the point of that?"); + stage = 20; + break; + case 3: + player("That's barbaric!"); + stage = 30; + break; + } + break; + case 10: + npc("My arena is open to any high level wizard, but this is", "no game. Many wizards fall in this arena, never to rise", "again. The strongest mages have been destroyed."); + stage++; + break; + case 11: + npc("If you're sure you want in?"); + stage++; + break; + case 12: + options("Yes indeedy.", "No I don't."); + stage++; + break; + case 13: + switch (buttonId) { + case 1: + player("Yes indeedy."); + stage++; + break; + case 2: + end(); + break; + } + break; + case 14: + npc("Good, good. You have a healthy sense of competition."); + stage++; + break; + case 15: + npc("Remember, traveller - in my arena, hand-to-hand", "combat is useless. Your strength will diminish as you", "enter the arena, but the spells you can learn are", "amongst the most powerful in all of " + GameWorld.getSettings().getName() + "."); + stage++; + break; + case 16: + npc("Before I can accept you in, we must duel."); + stage++; + break; + case 17: + options("Okay, let's fight.", "No thanks."); + stage++; + break; + case 18: + switch (buttonId) { + case 1: + player("Okay, let's fight."); + stage++; + break; + case 2: + end(); + break; + } + break; + case 19: + npc("I must first check that you are up to scratch."); + stage = 40; + break; + case 40: + player("You don't need to worry about that."); + stage++; + break; + case 41: + npc("Not just any magician can enter - only the most", "powerful and most feared. Before you can use the", "power of this arena, you must prove yourself against", "me."); + stage++; + break; + case 42: + startFight(player); + end(); + break; + case 20: + npc("They want to crown themselves the best", "mage in all of " + GameWorld.getSettings().getName() + "!"); + stage = 30; + break; + case 30: + end(); + break; + } + return true; + } + + /** + * Starts the fight. + * @param player the player. + */ + private void startFight(final Player player) { + player.getSavedData().getActivityData().setKolodionStage(1); + player.lock(); + npc.animate(Animation.create(811)); + player.teleport(Location.create(3105, 3934, 0), 3); + player.visualize(Animation.create(1816), Graphics.create(301, 100)); + KolodionSession.create(player).start(); + } + + @Override + public int[] getIds() { + return new int[] { 905 }; + } + +} diff --git a/Server/src/main/content/minigame/magearena/KolodionNPC.java b/Server/src/main/content/minigame/magearena/KolodionNPC.java new file mode 100644 index 0000000..74c06d9 --- /dev/null +++ b/Server/src/main/content/minigame/magearena/KolodionNPC.java @@ -0,0 +1,374 @@ +package content.minigame.magearena; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.spell.CombatSpell; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.system.task.Pulse; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.tools.RandomFunction; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.node.entity.combat.MagicSwingHandler; +import core.game.world.GameWorld; + +/** + * Handles the kolodion npc. + * @author Vexia + */ +public final class KolodionNPC extends AbstractNPC { + + /** + * The combat swing handler. + */ + private static final CombatSwingHandler SWING_HANDLER = new MagicSwingHandler() { + + @Override + public void impact(Entity entity, Entity victim, BattleState state) { + super.impact(entity, victim, state); + if (RandomFunction.random(10) < 4) { + ((KolodionNPC) entity).setRandomSpell(); + } + } + + }; + + /** + * The spell ids. + */ + private static final int[] SPELL_IDS = new int[] { 41, 42, 43 }; + + /** + * The session. + */ + private final KolodionSession session; + + /** + * The kolodion type. + */ + private KolodionType type; + + /** + * If the fight has commenced. + */ + private boolean commenced; + + /** + * Constructs a new {@code KolodionNPC} {@code Object}. + */ + public KolodionNPC() { + this(0, null, null); + } + + /** + * Constructs a new {@code KolodionNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + public KolodionNPC(int id, Location location, final KolodionSession session) { + super(id, location); + this.setWalks(true); + this.session = session; + this.setRespawn(false); + this.type = KolodionType.forId(id); + } + + @Override + public void init() { + super.init(); + setRandomSpell(); + } + + @Override + public void handleTickActions() { + super.handleTickActions(); + if (session == null) { + return; + } + if (!session.getPlayer().isActive()) { + clear(); + return; + } + if (commenced && !getProperties().getCombatPulse().isAttacking()) { + getProperties().getCombatPulse().attack(session.getPlayer()); + } + } + + @Override + public void startDeath(Entity killer) { + if (killer == session.getPlayer()) { + type.transform(this, session.getPlayer()); + return; + } + super.startDeath(killer); + } + + /** + * Sets a random spell. + */ + public void setRandomSpell() { + CombatSpell spell = (CombatSpell) SpellBook.MODERN.getSpell(SPELL_IDS[RandomFunction.random(SPELL_IDS.length)]); + getProperties().setSpell(spell); + getProperties().setAutocastSpell(spell); + } + + @Override + public CombatSwingHandler getSwingHandler(boolean swing) { + return SWING_HANDLER; + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new KolodionNPC(id, location, null); + } + + @Override + public boolean isAttackable(Entity entity, CombatStyle style, boolean message) { + if (style != CombatStyle.MAGIC) { + return false; + } + if (session == null) { + return false; + } + if (session.getPlayer() != entity) { + return false; + } + return true; + } + + @Override + public boolean canSelectTarget(Entity target) { + if (target instanceof Player) { + Player p = (Player) target; + if (p != session.getPlayer()) { + return false; + } + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 907, 908, 909, 910, 911 }; + } + + /** + * Gets the session. + * @return The session. + */ + public KolodionSession getSession() { + return session; + } + + /** + * Gets the commenced. + * @return The commenced. + */ + public boolean isCommenced() { + return commenced; + } + + /** + * Sets the commenced. + * @param commenced The commenced to set. + */ + public void setCommenced(boolean commenced) { + this.commenced = commenced; + } + + /** + * Gets the type. + * @return The type. + */ + public KolodionType getType() { + return type; + } + + /** + * Sets the type. + * @param type The type to set. + */ + public void setType(KolodionType type) { + this.type = type; + } + + /** + * Represents a kolodion type. + * @author Vexia + */ + public enum KolodionType { + HUMAN(907, null, -1, "You must prove yourself... now!"), OGRE(908, null, 188, "This is only the beginning; you can't beat me!"), SPIDER(909, new Animation(5324), 190, "Foolish mortal; I am unstoppable."), GHOST(910, new Animation(715), 188, "Now you feel it.. The dark energy."), DEMON(911, new Animation(4623), 190, "Aaaaaaaarrgghhhh! The power!"), END(906, null, 188, null); + + /** + * The npc id. + */ + private final int npcId; + + /** + * The appear animation. + */ + private final Animation appearAnimation; + + /** + * The graphic id. + */ + private final int graphcId; + + /** + * The appeared message. + */ + private final String appearMessage; + + /** + * The spell ids. + */ + private final int[] spellIds; + + /** + * Constructs a new {@code KolodionType} {@code Object}. + * @param npcId the npc id. + * @param appearMessage the message. + */ + private KolodionType(int npcId, final Animation appearAnimation, final int graphicId, String appearMessage, int... spellIds) { + this.npcId = npcId; + this.appearMessage = appearMessage; + this.appearAnimation = appearAnimation; + this.graphcId = graphicId; + this.spellIds = spellIds; + } + + /** + * Transforms the new npc. + */ + public void transform(final KolodionNPC kolodion, final Player player) { + final KolodionType newType = next(); + kolodion.lock(); + kolodion.getPulseManager().clear(); + kolodion.getWalkingQueue().reset(); + kolodion.getImpactHandler().setDisabledTicks(50); + player.getSavedData().getActivityData().setKolodionBoss(newType.ordinal()); + if (newType == END) { + player.lock(); + } + player.lock(2); + GameWorld.getPulser().submit(new Pulse(1, kolodion, player) { + int counter; + + @Override + public boolean pulse() { + switch (++counter) { + case 1: + if (newType != GHOST) { + kolodion.getAnimator().forceAnimation(kolodion.getProperties().getDeathAnimation()); + } + break; + case 3: + if (newType == GHOST) { + kolodion.getAnimator().forceAnimation(kolodion.getProperties().getDeathAnimation()); + } + break; + case 4: + player.getPacketDispatch().sendPositionedGraphic(newType.getGraphcId(), 0, 0, kolodion.getLocation()); + if (newType.getAppearAnimation() != null) { + kolodion.animate(newType.getAppearAnimation()); + } + break; + case 5: + kolodion.unlock(); + kolodion.getAnimator().reset(); + kolodion.fullRestore(); + kolodion.setType(newType); + kolodion.transform(newType.getNpcId()); + kolodion.getImpactHandler().setDisabledTicks(1); + if (newType != END) { + kolodion.getProperties().getCombatPulse().attack(player); + } + break; + case 6: + if (newType.getAppearMessage() != null) { + kolodion.sendChat(newType.getAppearMessage()); + } + if (newType == END) { + return false; + } + return true; + case 7: + player.unlock(); + player.getSavedData().getActivityData().setKolodionStage(2); + player.getProperties().setTeleportLocation(Location.create(2540, 4717, 0)); + return true; + } + return false; + } + + }); + } + + /** + * Gets the kolodion type for the id. + * @param id the id. + * @return the kolodion type. + */ + public static KolodionType forId(int id) { + for (KolodionType type : values()) { + if (type.getNpcId() == id) { + return type; + } + } + return null; + } + + /** + * Gets the next type. + * @return the type. + */ + public KolodionType next() { + return values()[ordinal() + 1]; + } + + /** + * Gets the npcId. + * @return The npcId. + */ + public int getNpcId() { + return npcId; + } + + /** + * Gets the appearMessage. + * @return The appearMessage. + */ + public String getAppearMessage() { + return appearMessage; + } + + /** + * Gets the spellIds. + * @return The spellIds. + */ + public int[] getSpellIds() { + return spellIds; + } + + /** + * Gets the appearAnimation. + * @return The appearAnimation. + */ + public Animation getAppearAnimation() { + return appearAnimation; + } + + /** + * Gets the graphcId. + * @return The graphcId. + */ + public int getGraphcId() { + return graphcId; + } + + } + +} diff --git a/Server/src/main/content/minigame/magearena/KolodionSession.java b/Server/src/main/content/minigame/magearena/KolodionSession.java new file mode 100644 index 0000000..17df19e --- /dev/null +++ b/Server/src/main/content/minigame/magearena/KolodionSession.java @@ -0,0 +1,120 @@ +package content.minigame.magearena; + +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; + +/** + * Represents a session with kolodion. + * @author Vexia + */ +public final class KolodionSession { + + /** + * The player. + */ + private final Player player; + + /** + * The kolodion npc. + */ + private final KolodionNPC kolodion; + + /** + * Constructs a new {@code ExperimentSession} {@code Object}. + * @param player the player. + */ + public KolodionSession(final Player player) { + this.player = player; + this.kolodion = new KolodionNPC(KolodionNPC.KolodionType.values()[player.getSavedData().getActivityData().getKolodionBoss()].getNpcId(), Location.create(3106, 3934, 0), this); + if (player.getExtension(KolodionSession.class) != null) { + player.removeExtension(KolodionSession.class); + } + player.addExtension(KolodionSession.class, this); + } + + /** + * Creates the kolodion session. + * @param player the player. + * @return the session. + */ + public static KolodionSession create(Player player) { + return new KolodionSession(player); + } + + /** + * Starts the session. + */ + public void start() { + if (kolodion.getType().ordinal() > 0) { + kolodion.init(); + kolodion.sendChat("Let us continue with our battle."); + kolodion.getProperties().getCombatPulse().attack(player); + player.unlock(); + player.getAnimator().reset(); + return; + } + GameWorld.getPulser().submit(new Pulse(1, player) { + int count; + + @Override + public boolean pulse() { + switch (++count) { + case 3: + player.getAnimator().reset(); + break; + case 5: + player.getPacketDispatch().sendPositionedGraphic(86, 1, 0, Location.create(3106, 3934, 0)); + break; + case 6: + kolodion.init(); + kolodion.faceTemporary(player, 1); + break; + case 7: + kolodion.sendChat("You must prove yourself... now!"); + break; + case 9: + player.unlock(); + kolodion.setCommenced(true); + return true; + } + return false; + } + }); + } + + /** + * Closes the session. + */ + public void close() { + kolodion.clear(); + player.removeExtension(KolodionSession.class); + } + + /** + * Gets the kolodion session. + * @param player the player. + * @return the session. + */ + public static KolodionSession getSession(Player player) { + return player.getExtension(KolodionSession.class); + } + + /** + * Gets the player. + * @return The player. + */ + public Player getPlayer() { + return player; + } + + /** + * Gets the kolodion. + * @return The kolodion. + */ + public NPC getKolodion() { + return kolodion; + } +} diff --git a/Server/src/main/content/minigame/magearena/LundailDialogue.java b/Server/src/main/content/minigame/magearena/LundailDialogue.java new file mode 100644 index 0000000..5504d23 --- /dev/null +++ b/Server/src/main/content/minigame/magearena/LundailDialogue.java @@ -0,0 +1,103 @@ +package content.minigame.magearena; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.world.GameWorld; + +/** + * Handles the lundail dialogue. + * @author Vexia + */ +public final class LundailDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code LundailDialogue} {@code Object}. + */ + public LundailDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code LundailDialogue} {@code Object}. + * @param player the player. + */ + public LundailDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new LundailDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + npc("Hello sir."); + stage = 1; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 1: + npc("How can I help you, brave adventurer?"); + stage++; + break; + case 2: + options("What are you selling?", "What's that big old building above us?"); + stage++; + break; + case 3: + switch (buttonId) { + case 1: + player("What are you selling?"); + stage = 10; + break; + case 2: + player("What's that big old building above us?"); + stage = 20; + break; + } + break; + case 10: + npc("I sell rune stones. I've got some good stuff, some really", "powerful little rocks. Take a look."); + stage++; + break; + case 11: + npc.openShop(player); + end(); + break; + case 20: + npc("That, my friend is the mage battle arena. Top mages", "come from all over " + GameWorld.getSettings().getName() + " to compete in the arena."); + stage++; + break; + case 21: + player("Wow."); + stage++; + break; + case 22: + npc("Few return, most get fried, hence the smell."); + stage++; + break; + case 23: + player("Hmmm... I did notice."); + stage++; + break; + case 24: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 903 }; + } + +} diff --git a/Server/src/main/content/minigame/magearena/MageArenaNPC.java b/Server/src/main/content/minigame/magearena/MageArenaNPC.java new file mode 100644 index 0000000..e4a4489 --- /dev/null +++ b/Server/src/main/content/minigame/magearena/MageArenaNPC.java @@ -0,0 +1,104 @@ +package content.minigame.magearena; + +import content.data.GodType; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.spell.CombatSpell; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.world.map.Location; +import core.tools.RandomFunction; + +/** + * A mage arena npc. + * @author Vexia + */ +public final class MageArenaNPC extends AbstractNPC { + + /** + * The god type. + */ + private final GodType type; + + /** + * Constructs a new {@code MageArenaNPC} {@code Object}. + */ + public MageArenaNPC() { + super(0, null); + this.type = null; + } + + /** + * Constructs a new {@code MageArenaNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + public MageArenaNPC(int id, Location location) { + super(id, location); + this.setWalks(true); + this.type = GodType.forId(id); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new MageArenaNPC(id, location); + } + + @Override + public void init() { + super.init(); + CombatSpell spell = (CombatSpell) SpellBook.MODERN.getSpell(41 + type.ordinal()); + getProperties().setSpell(spell); + getProperties().setAutocastSpell(spell); + getProperties().getCombatPulse().setStyle(CombatStyle.MAGIC); + } + + @Override + public void handleTickActions() { + super.handleTickActions(); + if (getProperties().getCombatPulse().isAttacking() && RandomFunction.random(20) < 6) { + sendChat(getWrathMessage()); + } else if (getProperties().getCombatPulse().isInCombat() && RandomFunction.random(60) < 10) { + sendChat(getHailMessage()); + } + } + + @Override + public boolean canSelectTarget(Entity target) { + if (target instanceof Player) { + Player p = (Player) target; + if (type.isFriendly(p)) { + return false; + } + if (p.getZoneMonitor().isInZone("mage arena")) { + if (MageArenaPlugin.MAGE_ARENA.hasSession(p)) { + return false; + } + } + } + return true; + } + + /** + * Gets the hail message. + * @return the message. + */ + public String getHailMessage() { + return "Hail " + type.getName() + "!"; + } + + /** + * Gets the wrath message. + * @return the message. + */ + public String getWrathMessage() { + return "Feel the wrath of " + type.getName() + "."; + } + + @Override + public int[] getIds() { + // sara, zammy, guthix + return new int[] { 913, 912, 914 }; + } +} diff --git a/Server/src/main/content/minigame/magearena/MageArenaPlugin.java b/Server/src/main/content/minigame/magearena/MageArenaPlugin.java new file mode 100644 index 0000000..82cf8b2 --- /dev/null +++ b/Server/src/main/content/minigame/magearena/MageArenaPlugin.java @@ -0,0 +1,209 @@ +package content.minigame.magearena; + +import core.cache.def.impl.ItemDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.game.dialogue.DialogueAction; +import content.data.GodType; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import content.global.skill.agility.AgilityHandler; +import core.game.node.item.GroundItem; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.system.task.Pulse; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.game.global.action.PickupHandler; +import core.game.world.GameWorld; +import core.plugin.ClassScanner; + +/** + * Handles the mage arena activity. + * @author Vexia + */ +@Initializable +public final class MageArenaPlugin extends OptionHandler { + + /** + * The pool destinations. + */ + private static final Location[] POOL_DESTINATIONS = new Location[] { Location.create(2542, 4718, 0), Location.create(2509, 4689, 0) }; + + /** + * The mage arena zone. + */ + public static final MageArenaZone MAGE_ARENA = new MageArenaZone(); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ClassScanner.definePlugin(MAGE_ARENA); + ClassScanner.definePlugin(new KolodionNPC()); + ClassScanner.definePlugin(new MageArenaNPC()); + ClassScanner.definePlugin(new LundailDialogue()); + ClassScanner.definePlugin(new KolodionDialogue()); + ClassScanner.definePlugin(new ChamberGuardianDialogue()); + ItemDefinition.forId(2412).getHandlers().put("option:drop", this); + ItemDefinition.forId(2413).getHandlers().put("option:drop", this); + ItemDefinition.forId(2414).getHandlers().put("option:drop", this); + ItemDefinition.forId(2412).getHandlers().put("option:take", this); + ItemDefinition.forId(2413).getHandlers().put("option:take", this); + ItemDefinition.forId(2414).getHandlers().put("option:take", this); + SceneryDefinition.forId(2873).getHandlers().put("option:pray at", this); + SceneryDefinition.forId(2874).getHandlers().put("option:pray at", this); + SceneryDefinition.forId(2875).getHandlers().put("option:pray at", this); + SceneryDefinition.forId(2878).getHandlers().put("option:step-into", this); + SceneryDefinition.forId(2879).getHandlers().put("option:step-into", this); + return this; + } + + @Override + public boolean handle(final Player player, final Node node, String option) { + switch (node.getId()) { + case 2879: + case 2878: + final Location destination = POOL_DESTINATIONS[2879 - node.getId()]; + if (player.getSavedData().getActivityData().hasKilledKolodion()) { + player.getDialogueInterpreter().sendDialogue("You step into the pool of sparkling water. You feel energy rush", "through your veins."); + player.getDialogueInterpreter().addAction(new DialogueAction() { + @Override + public void handle(Player player, int buttonId) { + handlePool(player, true, destination, (Scenery) node); + } + }); + return true; + } + player.lock(1); + GameWorld.getPulser().submit(new Pulse(1, player) { + @Override + public boolean pulse() { + handlePool(player, false, destination, (Scenery) node); + return true; + } + }); + break; + case 2873: + case 2874: + case 2875: + GodType.forObject(node.getId()).pray(player, (Scenery) node); + break; + case 2412: + case 2413: + case 2414: + GodType type = GodType.forCape(((Item) node)); + if (option.toLowerCase().equals("take")) { + GroundItem g = (GroundItem) node; + if (GodType.hasAny(player)) { + GroundItemManager.destroy(g); + player.sendMessages("You may only possess one sacred cape at a time.", "The conflicting powers of the capes drive them apart."); + } else { + PickupHandler.take(player, g); + } + return true; + } else { + if (type != null) { + player.sendMessage(type.getDropMessage()); + player.getInventory().remove(type.getCape()); + } + } + break; + } + return true; + } + + @Override + public boolean isWalk(Player player, Node node) { + if (node instanceof GroundItem) { + return true; + } + return !(node instanceof Item); + } + + @Override + public boolean isWalk() { + return false; + } + + @Override + public Location getDestination(Node node, Node n) { + switch (n.getId()) { + case 2878: + int y = node.getLocation().getY(), + x = node.getLocation().getX(); + Location dest = Location.create(2544, 4720, 0); + Direction dir = Direction.WEST; + if (y <= 4718) { + dest = Location.create(2542, 4718, 0); + dir = Direction.NORTH; + } else if (y == 4722) { + dest = Location.create(2542, 4722, 0); + dir = Direction.SOUTH; + } else if (x <= 2541) { + dest = Location.create(2540, 4720, 0); + dir = Direction.EAST; + } + ((Player) node).setAttribute("mb-loc", dest); + ((Player) node).setAttribute("mb-dir", dir); + return dest; + case 2873: + case 2874: + case 2875: + return n.getLocation().transform(0, -2, 0); + } + return null; + } + + /** + * Handles the pool. + * @param player the player. + * @param enter if entered. + * @param dest the destination. + */ + public void handlePool(final Player player, boolean enter, final Location dest, final Scenery object) { + final Location start = player.getAttribute("mb-loc", player.getLocation()); + final Location end = player.getLocation().transform(player.getAttribute("mb-dir", Direction.NORTH), 1); + player.removeAttribute("mc-loc"); + player.removeAttribute("mb-dir"); + if (enter) { + final Location middle = object.getId() == 2879 ? Location.create(2509, 4687, 0) : Location.create(2542, 4720, 0); + player.lock(); + AgilityHandler.walk(player, -1, start, middle, new Animation(1426), 0.0, null); + GameWorld.getPulser().submit(new Pulse(1, player) { + int counter; + + @Override + public boolean pulse() { + switch (++counter) { + case 3: + player.getPacketDispatch().sendPositionedGraphic(68, 1, 0, middle); + break; + case 4: + player.unlock(); + player.getProperties().setTeleportLocation(dest); + return true; + } + return false; + } + + }); + return; + } + player.sendMessage("You step into the pool."); + AgilityHandler.walk(player, -1, start, end, new Animation(1426), 0.0, "Your boots get wet."); + GameWorld.getPulser().submit(new Pulse(1, player) { + + @Override + public boolean pulse() { + player.getAppearance().setDefaultAnimations(); + player.getAppearance().sync(); + player.getProperties().setTeleportLocation(start); + return true; + } + + }); + } +} diff --git a/Server/src/main/content/minigame/magearena/MageArenaZone.java b/Server/src/main/content/minigame/magearena/MageArenaZone.java new file mode 100644 index 0000000..4a38651 --- /dev/null +++ b/Server/src/main/content/minigame/magearena/MageArenaZone.java @@ -0,0 +1,137 @@ +package content.minigame.magearena; + +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneBuilder; +import core.game.world.map.zone.ZoneRestriction; +import core.plugin.Plugin; + +/** + * Handles the mage arena zone. + * @author Vexia + */ +public final class MageArenaZone extends MapZone implements Plugin { + + /** + * Constructs a new {@code MageArenaZone} {@code Object}. + */ + public MageArenaZone() { + super("mage arena", true, ZoneRestriction.RANDOM_EVENTS); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ZoneBuilder.configure(this); + return this; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public boolean enter(Entity e) { + return super.enter(e); + } + + @SuppressWarnings("deprecation") + @Override + public boolean leave(Entity e, boolean logout) { + if (e instanceof Player) { + final Player p = (Player) e; + if (!logout) { + GameWorld.getPulser().submit(new Pulse(1, e) { + @Override + public boolean pulse() { + if (!p.getZoneMonitor().isInZone("mage arena")) { + if (hasSession(p)) { + getSession(p).close(); + } + } + return true; + } + }); + return true; + } + if (hasSession(p)) { + getSession(p).close(); + } + if (logout && hasSession(p)) { + p.setLocation(Location.create(2540, 4717, 0)); + } + } + return super.leave(e, logout); + } + + @Override + public boolean continueAttack(Entity e, Node target, CombatStyle style, boolean message) { + if (style != CombatStyle.MAGIC) { + return false; + } + if (target instanceof Player) { + final Player t = (Player) target; + if (hasSession(t) && !(e instanceof KolodionNPC)) { + return false; + } + } + return super.continueAttack(e, target, style, message); + } + + /** + * Gets the session. + * @param player the player. + * @return the session. + */ + public KolodionSession getSession(Player player) { + return KolodionSession.getSession(player); + } + + /** + * Checks if the player has a session. + * @param player the player. + * @return {@code True} if so. + */ + public boolean hasSession(final Player player) { + return KolodionSession.getSession(player) != null; + } + + @Override + public void configure() { + register(new ZoneBorders(3093, 3914, 3115, 3952));// the main + register(new ZoneBorders(3084, 3923, 3086, 3942)); + register(new ZoneBorders(3118, 3924, 3126, 3941)); + register(new ZoneBorders(3082, 3921, 3096, 3942)); + int x = 3089, y = 3914, x2 = 3089, y2 = 3949; + for (int i = 0; i < 7; i++) { + register(new ZoneBorders(x - i, y + i, x2 - i, y2 - i)); + } + register(new ZoneBorders(3119, 3942, 3123, 3945)); + register(new ZoneBorders(3115, 3944, 3119, 3949)); + register(new ZoneBorders(3119, 3942, 3119, 3952)); + register(new ZoneBorders(3120, 3940, 2125, 3945)); + register(new ZoneBorders(3114, 3944, 3120, 3949)); + register(new ZoneBorders(3114, 3942, 3117, 3952)); + x = 3118; + y = 3914; + x2 = 3118; + y2 = 3950; + for (int i = 0; i < 7; i++) { + register(new ZoneBorders(x + i, y + i, x2 + i, y2 - i)); + } + register(new ZoneBorders(3107, 3931, 3118, 3947)); + register(new ZoneBorders(3108, 3919, 3123, 3932)); + register(new ZoneBorders(3108, 3921, 3123, 3932)); + register(new ZoneBorders(3104, 3933, 3117, 3948)); + register(new ZoneBorders(3106, 3920, 3117, 3937)); + register(new ZoneBorders(3115, 3928, 3120, 3942)); + } + +} diff --git a/Server/src/main/content/minigame/mta/AlchemyGuardianDialogue.java b/Server/src/main/content/minigame/mta/AlchemyGuardianDialogue.java new file mode 100644 index 0000000..aa09d28 --- /dev/null +++ b/Server/src/main/content/minigame/mta/AlchemyGuardianDialogue.java @@ -0,0 +1,122 @@ +package content.minigame.mta; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; + +/** + * Handles the alchemy guardian dialogue. + * @author Vexia + */ +public class AlchemyGuardianDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code AlchemyGuardianDialogue} {@code Object} + */ + public AlchemyGuardianDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code AlchemyGuardianDialogue} {@code Object} + * @param player the player. + */ + public AlchemyGuardianDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new AlchemyGuardianDialogue(player); + } + + @Override + public boolean open(Object... args) { + player("Hi."); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + options("What do I have to do in this room?", "What are the rewards?", "Got any tips that may help me?", "Thanks, bye!"); + stage++; + break; + case 1: + switch (buttonId) { + case 1: + player("What do I have to do in this room?"); + stage = 10; + break; + case 2: + player("What are the rewards?"); + stage = 20; + break; + case 3: + player("Got any tips that may help me?"); + stage = 30; + break; + case 4: + player("Thanks, bye!"); + stage = 40; + break; + } + break; + case 10: + npc("In this room you will see various cupboards. It is your", "task to search the cupboards to find items to turn into", "gold using your low or high alchemy spells. You must", "deposit the money in the receptacle at the end of the"); + stage++; + break; + case 11: + npc("hall in order to receive your Alchemist Pizazz Points,", "otherwise the money will be taken from you as you", "leave through the portal. This money is used for the", "upkeep of the training arena as well as magic shops all"); + stage++; + break; + case 12: + npc("around Gielinor. Keep an eye on the cost of each", "item as these will change from time-to-time, as will the", "location of the items. Occasionally one of the items will", "be indicated as costing no runestones to convert to"); + stage++; + break; + case 13: + npc("money."); + stage = 0; + break; + case 20: + npc("You will get experience from casting the alchemist", "spells, as well as 1 Alchemist Pizazz Point for every 100", "coins you deposit, and 10% of the coins you deposit will", "be given to you as you leave. Keep in mind that you"); + stage++; + break; + case 21: + npc("will not be able to take more than 1000 coins back out", "with you."); + stage = 0; + break; + case 30: + npc("You must remember to keep ane eye on the various", "costs of the itmes. If you watch the movements of the", "other players, you might be able to guess which are the", "best places to visit. You will get 1 Pizazz Point for"); + stage++; + break; + case 31: + npc("every 100 coins, so if you have 190 coins, why not get", "an extra 10?"); + stage++; + break; + case 32: + player("I see."); + stage++; + break; + case 33: + npc("Oh, and a word of warning: should you decide to leave", "this room by a method other than the exit portals, you", "will be teleported to the entrance and have any items", "that you picked up in the room removed."); + stage = 0; + break; + case 34: + end(); + break; + case 40: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 3099 }; + } + +} diff --git a/Server/src/main/content/minigame/mta/CharmedWarriorDialogue.java b/Server/src/main/content/minigame/mta/CharmedWarriorDialogue.java new file mode 100644 index 0000000..269f7d7 --- /dev/null +++ b/Server/src/main/content/minigame/mta/CharmedWarriorDialogue.java @@ -0,0 +1,123 @@ +package content.minigame.mta; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; + +/** + * Handles the charmed warrior dialogue. + * @author Vexia + */ +public class CharmedWarriorDialogue extends DialoguePlugin { + + /** + * Constructs a new {@Code CharmedWarriorDialogue} {@Code + * Object} + */ + public CharmedWarriorDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@Code CharmedWarriorDialogue} {@Code + * Object} + * @param player the player. + */ + public CharmedWarriorDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new CharmedWarriorDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + switch (npc.getId()) { + case 3105: + case 3104: + player("Is there anybody there?"); + break; + default: + player("Hello?"); + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (npc.getId()) { + case 3107: + switch (stage) { + case 0: + npc("Can't you see I'm busy?"); + stage++; + break; + case 1: + player("Well, I can't really see YOU."); + stage++; + break; + case 2: + end(); + break; + } + break; + case 3106: + switch (stage) { + case 0: + npc("Hey! You haven't paid for your Magic Training Arena", "Membership money!"); + stage++; + break; + case 1: + player("You're lying. I can see right through you!"); + stage++; + break; + case 2: + npc("Oh, HA HA, very funny."); + stage++; + break; + case 3: + end(); + break; + } + break; + case 3105: + switch (stage) { + case 0: + npc("Wooo wooo! Be afraid for I'm a scary ghost. Wooo!"); + stage++; + break; + case 1: + player("Er, whatever."); + stage++; + break; + case 2: + end(); + break; + } + break; + case 3104: + switch (stage) { + case 0: + npc("What do you think?"); + stage++; + break; + case 1: + end(); + break; + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 3106, 3107, 3104, 3105 }; + } +} diff --git a/Server/src/main/content/minigame/mta/EnchantSpell.kt b/Server/src/main/content/minigame/mta/EnchantSpell.kt new file mode 100644 index 0000000..d6df04f --- /dev/null +++ b/Server/src/main/content/minigame/mta/EnchantSpell.kt @@ -0,0 +1,232 @@ +package content.minigame.mta + +import content.minigame.mta.impl.EnchantingZone.Shapes +import core.game.node.Node +import core.game.node.entity.Entity +import core.game.node.entity.combat.spell.SpellType +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.SpellBookManager.SpellBook +import core.game.node.entity.player.link.audio.Audio +import core.game.node.entity.combat.spell.MagicSpell +import core.game.node.entity.combat.spell.Runes +import core.game.node.item.Item +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import core.plugin.Plugin +import org.rs09.consts.Items + +/** + * Represents the enchant spells. + * @author Ceikry + */ +class EnchantSpell : MagicSpell { + /** + * The enchantable jewellery array. + */ + private val jewellery: Map? + + /** + * Constructs a new `EnchantSpell` `Object`. + */ + constructor() { + jewellery = null + } + + /** + * Constructs a new `EnchantSpell` `Object`. + * @param level The level required. + * @param jewellery The jewellery this spell is able to echant. + * @param runes The runes required. + */ + constructor(level: Int, experience: Double, jewellery: Map, runes: Array?) : super(SpellBook.MODERN, level, experience, ANIMATION, GRAPHIC, Audio(115, 1, 0), runes) { + this.jewellery = jewellery + } + + override fun cast(entity: Entity, target: Node): Boolean { + if (target !is Item || entity !is Player) { + return false + } + entity.interfaceManager.setViewedTab(6) + val enchanted = jewellery?.getOrDefault(target.id,null) + + if (enchanted == null) { + entity.packetDispatch.sendMessage("You can't use this spell on this item.") + return false + } + if (!meetsRequirements(entity, true, true)) { + return false + } + + if (entity.inventory.remove(target)) { + visualize(entity, target) + entity.inventory.add(enchanted) + } + + + //MTA-Specific Code + if (entity.zoneMonitor.isInZone("Enchantment Chamber")) { + entity.graphics(Graphics.create(237, 110)) + var pizazz = 0 + if (target.id == 6903) { + pizazz = (if (getSpellId() == 5) 1 else if (getSpellId() == 16) 2 else if (getSpellId() == 28) 3 else if (getSpellId() == 36) 4 else if (getSpellId() == 51) 5 else 6) * 2 + } else { + val shape = Shapes.forItem(target) + if (shape != null) { + var convert = entity.getAttribute("mta-convert", 0) + convert += 1 + if (convert >= 10) { + pizazz = if (getSpellId() == 5) 1 else if (getSpellId() == 16) 2 else if (getSpellId() == 28) 3 else if (getSpellId() == 36) 4 else if (getSpellId() == 51) 5 else 6 + convert = 0 + } + entity.setAttribute("mta-convert", convert) + if (shape == content.minigame.mta.impl.EnchantingZone.BONUS_SHAPE) { + pizazz += 1 + entity.sendMessage("You get " + pizazz + " bonus point" + (if (pizazz != 1) "s" else "") + "!") + } + } + } + if (pizazz != 0) { + content.minigame.mta.impl.EnchantingZone.ZONE.incrementPoints(entity, MTAType.ENCHANTERS.ordinal, pizazz) + } + } + return true + } + + override fun getDelay(): Int { + return 1 + } + + override fun getExperience(player: Player): Double { + return if (player.zoneMonitor.isInZone("Enchantment Chamber")) { + experience - experience * 0.25 + } else experience + } + + override fun newInstance(arg: SpellType?): Plugin? { + /** + * Enchant Sapphire Jewelry (Lvl-1 Enchant) + */ + SpellBook.MODERN.register(5, EnchantSpell(7, 17.5, + mapOf( + //Begin Jewelry Enchantments + Items.SAPPHIRE_RING_1637 to Item(Items.RING_OF_RECOIL_2550), + Items.SAPPHIRE_NECKLACE_1656 to Item(Items.GAMES_NECKLACE8_3853), + Items.SAPPHIRE_AMULET_1694 to Item(Items.AMULET_OF_MAGIC_1727), + Items.SAPPHIRE_BRACELET_11072 to Item(Items.BRACELET_OF_CLAY_11074), + //Begin MTA-specific enchantments + Items.CUBE_6899 to Item(Items.ORB_6902), + Items.CYLINDER_6898 to Item(Items.ORB_6902), + Items.ICOSAHEDRON_6900 to Item(Items.ORB_6902), + Items.PENTAMID_6901 to Item(Items.ORB_6902), + Items.DRAGONSTONE_6903 to Item(Items.ORB_6902) + ), + arrayOf(Item(Items.COSMIC_RUNE_564,1), Item(Items.WATER_RUNE_555,1)))) + + /** + * Enchant Emerald Jewelry (Lvl-2 Enchant) + */ + SpellBook.MODERN.register(16, EnchantSpell(27, 37.0, + mapOf( + //Begin Jewelry Enchantments + Items.EMERALD_RING_1639 to Item(Items.RING_OF_DUELLING8_2552), + Items.EMERALD_NECKLACE_1658 to Item(Items.BINDING_NECKLACE_5521), + Items.EMERALD_AMULET_1696 to Item(Items.AMULET_OF_DEFENCE_1729), + Items.EMERALD_BRACELET_11076 to Item(Items.CASTLEWAR_BRACE3_11079), + //Begin MTA-Specific Enchantments + Items.CUBE_6899 to Item(Items.ORB_6902), + Items.CYLINDER_6898 to Item(Items.ORB_6902), + Items.ICOSAHEDRON_6900 to Item(Items.ORB_6902), + Items.PENTAMID_6901 to Item(Items.ORB_6902), + Items.DRAGONSTONE_6903 to Item(Items.ORB_6902) + ), + arrayOf(Item(Runes.COSMIC_RUNE.id, 1), Item(Runes.AIR_RUNE.id, 3)))) + + /** + * Enchant Ruby Jewelry (Lvl-3 Enchant) + */ + SpellBook.MODERN.register(28, EnchantSpell(49, 59.0, + mapOf( + //Begin Jewelry Enchantments + Items.RUBY_RING_1641 to Item(Items.RING_OF_FORGING_2568), + Items.RUBY_NECKLACE_1660 to Item(Items.DIGSITE_PENDANT_5_11194), + Items.RUBY_AMULET_1698 to Item(Items.AMULET_OF_STRENGTH_1725), + Items.RUBY_BRACELET_11085 to Item(Items.INOCULATION_BRACE_11088), + //Begin MTA-Specific Enchantments + Items.CUBE_6899 to Item(Items.ORB_6902), + Items.CYLINDER_6898 to Item(Items.ORB_6902), + Items.ICOSAHEDRON_6900 to Item(Items.ORB_6902), + Items.PENTAMID_6901 to Item(Items.ORB_6902), + Items.DRAGONSTONE_6903 to Item(Items.ORB_6902) + ), + arrayOf(Item(Runes.COSMIC_RUNE.id, 1), Item(Runes.FIRE_RUNE.id, 5)))) + + /** + * Enchant Diamond Jewelry (Lvl-4 Enchant) + */ + SpellBook.MODERN.register(36, EnchantSpell(57, 67.0, + mapOf( + Items.DIAMOND_RING_1643 to Item(Items.RING_OF_LIFE_2570), + Items.DIAMOND_NECKLACE_1662 to Item(Items.PHOENIX_NECKLACE_11090), + Items.DIAMOND_AMULET_1700 to Item(Items.AMULET_OF_POWER_1731), + Items.DIAMOND_BRACELET_11092 to Item(Items.FORINTHRY_BRACE5_11095), + //Begin MTA-Specific Enchantments + Items.CUBE_6899 to Item(Items.ORB_6902), + Items.CYLINDER_6898 to Item(Items.ORB_6902), + Items.ICOSAHEDRON_6900 to Item(Items.ORB_6902), + Items.PENTAMID_6901 to Item(Items.ORB_6902), + Items.DRAGONSTONE_6903 to Item(Items.ORB_6902) + ), + arrayOf(Item(Runes.COSMIC_RUNE.id, 1), Item(Runes.EARTH_RUNE.id, 10)))) + + /** + * Enchant Dragonstone Jewelry (Lvl-5 Enchant) + */ + SpellBook.MODERN.register(51, EnchantSpell(68, 78.0, + mapOf( + //Begin Jewelry Enchantment + Items.DRAGONSTONE_RING_1645 to Item(14646), + Items.DRAGON_NECKLACE_1664 to Item(Items.SKILLS_NECKLACE4_11105), + Items.DRAGONSTONE_AMMY_1702 to Item(Items.AMULET_OF_GLORY4_1712), + Items.DRAGON_BRACELET_11115 to Item(Items.COMBAT_BRACELET4_11118), + //Begin MTA-Specific Enchantments + Items.CUBE_6899 to Item(Items.ORB_6902), + Items.CYLINDER_6898 to Item(Items.ORB_6902), + Items.ICOSAHEDRON_6900 to Item(Items.ORB_6902), + Items.PENTAMID_6901 to Item(Items.ORB_6902), + Items.DRAGONSTONE_6903 to Item(Items.ORB_6902) + ), + arrayOf(Item(Runes.COSMIC_RUNE.id, 1), Item(Runes.WATER_RUNE.id, 15), Item(Runes.EARTH_RUNE.id, 15)))) + + /** + * Enchant Onyx Jewelry (Lvl-6 Enchant) + */ + SpellBook.MODERN.register(61, EnchantSpell(87, 97.0, + mapOf( + //Begin Jewelry Enchantments + Items.ONYX_RING_6575 to Item(Items.RING_OF_STONE_6583), + Items.ONYX_NECKLACE_6577 to Item(Items.BERSERKER_NECKLACE_11128), + Items.ONYX_AMULET_6581 to Item(Items.AMULET_OF_FURY_6585), + Items.ONYX_BRACELET_11130 to Item(Items.REGEN_BRACELET_11133), + //Begin MTA-Specific Enchantments + Items.CUBE_6899 to Item(Items.ORB_6902), + Items.CYLINDER_6898 to Item(Items.ORB_6902), + Items.ICOSAHEDRON_6900 to Item(Items.ORB_6902), + Items.PENTAMID_6901 to Item(Items.ORB_6902), + Items.DRAGONSTONE_6903 to Item(Items.ORB_6902) + ), + arrayOf(Item(Runes.COSMIC_RUNE.id, 1), Item(Runes.FIRE_RUNE.id, 20), Item(Runes.EARTH_RUNE.id, 20)))) + return this + } + + companion object { + /** + * The animation. + */ + private val ANIMATION = Animation.create(712) + + /** + * The graphic. + */ + private val GRAPHIC = Graphics(114, 96) + } +} diff --git a/Server/src/main/content/minigame/mta/EnchantmentGuardianDialogue.java b/Server/src/main/content/minigame/mta/EnchantmentGuardianDialogue.java new file mode 100644 index 0000000..8f61a9e --- /dev/null +++ b/Server/src/main/content/minigame/mta/EnchantmentGuardianDialogue.java @@ -0,0 +1,120 @@ +package content.minigame.mta; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; + +/** + * Handles the enchantment guardian dialogue. + * @author Vexia + */ +public class EnchantmentGuardianDialogue extends DialoguePlugin { + + /** + * Constructs a new {@Code EnchantmentGuardianDialogue} {@Code + * Object} + */ + public EnchantmentGuardianDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@Code EnchantmentGuardianDialogue} {@Code + * Object} + * @param player the player. + */ + public EnchantmentGuardianDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new EnchantmentGuardianDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc("Greetings young one. How can I enlighten you?"); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + options("What do I have to do in this room?", "What are the rewards?", "Got any tips that may help me?", "Thanks, bye!"); + stage++; + break; + case 1: + switch (buttonId) { + case 1: + player("What do I have to do in this room?"); + stage = 10; + break; + case 2: + player("What are the rewards?"); + stage = 20; + break; + case 3: + player("Got any tips that may help me?"); + stage = 30; + break; + case 4: + player("Thanks, bye!"); + stage = 40; + break; + } + break; + case 10: + npc("In this chamber you will see various piles of shapes. You", "can pick up these shapes and enchant them using the", "enchant jewelry spells. By enchanting these shapes,", "you'll be converting them into orbs which you can be"); + stage++; + break; + case 11: + npc("placed in the hole in the centre. You will get", "Enchantment Pizazz Points for every ten shapes that", "you convert and the points you get depends on the", "level of enchantment spell you cast. You will get a"); + stage++; + break; + case 12: + npc("bonus Pizazz Point for enchanting a certain shape at a", "certain time, which I will periodically shout out. You will", "also be rewarded with an item for every so many orbs", "you deposit into the hole."); + stage = 0; + break; + case 20: + npc("As well as the magic experience from casting your", "enchantment spells, you will get Enchantment Pizazz", "Points for converting so many shapes, plus a bonus", "point for converting shape of the correct type. You"); + stage++; + break; + case 21: + npc("should also note that you will occasionally be rewarded", "with items when you put one of the enchanted orbs in", "the floor."); + stage = 0; + break; + case 30: + npc("Try to guess or keep track of the time between the", "change of the best shape to enchant. This means you", "can be ready to run to a different shape when you", "know it is about to change. Look out for the dragon"); + stage++; + break; + case 31: + npc("gems, as these will get you more Pizazz Points!"); + stage++; + break; + case 32: + player("I see."); + stage++; + break; + case 33: + npc("Oh, and a word of warning: should you decide to leave", "this room by a method other than the exit portals, you", "will be teleported to the entrance and have any items", "that you picked up in the room removed."); + stage = 0; + break; + case 34: + end(); + break; + case 40: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 3100 }; + } + +} diff --git a/Server/src/main/content/minigame/mta/EntranceGuardianDialogue.java b/Server/src/main/content/minigame/mta/EntranceGuardianDialogue.java new file mode 100644 index 0000000..4870b05 --- /dev/null +++ b/Server/src/main/content/minigame/mta/EntranceGuardianDialogue.java @@ -0,0 +1,320 @@ +package content.minigame.mta; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; +import core.game.world.GameWorld; + +/** + * Handles the entrance guardian dialogue. + * @author Vexia + */ +public class EntranceGuardianDialogue extends DialoguePlugin { + + /** + * Constructs a new {@Code EntranceGuardianDialogue} {@Code + * Object} + */ + public EntranceGuardianDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@Code EntranceGuardianDialogue} {@Code + * Object} + * @param player the player. + */ + public EntranceGuardianDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new EntranceGuardianDialogue(player); + } + + @Override + public boolean open(Object... args) { + player("Hi."); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + npc("Greetings. What wisdom do you seek?"); + stage++; + if (player.getSavedData().getActivityData().isStartedMta()) { + stage = 30; + } + break; + case 1: + options("I'm new to this place. Where am I?", "None, I don't really care."); + stage++; + break; + case 2: + if (buttonId == 1) { + player("I'm new to this place. Where am I?"); + stage++; + break; + } + end(); + break; + case 3: + npc("Well young one, you have entered the Magic Training", "Arena. It was built at the start of the Fifth Age, when", "runestones were first discovered. It was made because", "of the many pointless accidents caused by inexperienced"); + stage++; + break; + case 4: + npc("mages."); + stage++; + break; + case 5: + player("Who created it?"); + stage++; + break; + case 6: + npc("Good question. It was originally made by the ancestors", "of the wizards in the Wizards Tower. However, it was", "destroyed by melee and ranged warriors who took", "offence at the use of this new 'Magic Art'. Recently"); + stage++; + break; + case 7: + npc("the current denizens of the Wizards Tower have", "resurrected the arena including various Guardians you", "will see as you look around. We are here to help and to", "ensure things run smoothly."); + stage++; + break; + case 8: + player("Interesting. So what can I do here?"); + stage++; + break; + case 9: + npc("You may train up your skills in the magic arts by", "travelling through one of the portals at the back of this", "entrance hall. By training up in one of these areas you", "will be awarded special Pizazz Points unique to each."); + stage++; + break; + case 10: + npc("room. With these points you may claim a variety of", "items from my fellow guardian up the stairs."); + stage++; + break; + case 11: + player("How do you record the points I have earned?"); + stage++; + break; + case 12: + if (player.getSavedData().getActivityData().isStartedMta()) { + npc("With the Pizazz Progress Hat I gave you, of course."); + stage = 40; + break; + } + npc("You really are full of questions! You will need a special", "Pizzaz Progress Hat! I can give you one if you so", "wish to train here."); + stage++; + break; + case 13: + player("Yes Please!"); + stage++; + break; + case 14: + player.getSavedData().getActivityData().setStartedMta(true); + player.getInventory().add(MageTrainingArenaPlugin.PROGRESS_HAT, player); + npc("Here you go. Talk to the hat to find out your current", "Pizzaz Points totals."); + stage++; + break; + case 15: + player("Talk to it?"); + stage++; + break; + case 16: + npc("Well of course, it's a magic Pizazz Progress Hat! Mind", "your manners though, hats have feelings too!"); + stage++; + break; + case 17: + player("Er... if you insist."); + stage++; + break; + case 18: + npc("Oh, and a word of warning: should you decide to leave", "the rooms by any method other than the exit portals,", "you will be teleported to the entrance and have any", "items that you picked up in the room removed."); + stage++; + break; + case 19: + player("Okay. Thanks!"); + stage++; + break; + case 20: + end(); + break; + case 30: + options("Can you tell me about this place again?", "Can you explain the different portals?", "About the progress hat...", "Thanks, bye!"); + stage++; + break; + case 31: + switch (buttonId) { + case 1: + player("Can you tell me about this place again?"); + stage = 3; + break; + case 2: + player("Can you explain the different portals?"); + stage = 50; + break; + case 3: + player("About the progress hat..."); + stage = 100; + break; + case 4: + end(); + break; + } + break; + case 100: + if (!player.hasItem(MageTrainingArenaPlugin.PROGRESS_HAT)) { + npc("You want another one don't you."); + stage = 110; + break; + } + npc("Which you have stored somewhere I'm sure."); + stage++; + break; + case 101: + player("Yes. What's it for?"); + stage++; + break; + case 102: + npc("Collect Pizazz Points from the various areas and the", "hat will remember your totals. Talk to the hat at any", "time to find out what points you have. Go upstairs and", "talk to the Rewards Guardian to claim items for the"); + stage++; + break; + case 103: + npc("points."); + stage = 30; + break; + case 110: + player("Sorry, can I?"); + stage++; + break; + case 111: + player.getInventory().add(MageTrainingArenaPlugin.PROGRESS_HAT, player); + npc("Here you go. Talk to the hat to find out your current", "Pizazz Point totals."); + stage = 30; + break; + case 40: + player("OK."); + stage++; + break; + case 41: + npc("Oh, and a word of warning: should you decide to log", "out whilst in any of the rooms in the arena, you will be", "teleported to the entrance and have any items that you", "picked up in the room removed."); + stage = 30; + break; + case 50: + npc("They lead to four areas to train your magic: The", "Telekinetic Theatre, The Alchemists' Playground, The", "Enchanting Chamber, and The Creature Graveyard."); + stage++; + break; + case 51: + options("What's the Telekinetic Theatre?", "What's the Alchemists' Playground?", "What's the Enchanting CHamber?", "What's the Creature Gaveyard?", "Thanks, bye!"); + stage++; + break; + case 52: + switch (buttonId) { + case 1: + player("What's the Telekinetic Theatre?"); + stage = 60; + break; + case 2: + player("What's the Alchemists' Playground?"); + stage = 70; + break; + case 3: + player("What's the Enchanting Chamber?"); + stage = 80; + break; + case 4: + player("What's the Creature Gaveyard?"); + stage = 90; + break; + case 5: + end(); + break; + } + break; + case 60: + npc("In there you can earn Telekinetic Pizazz Points for", "trde upstairs."); + stage++; + break; + case 61: + player("What will I be doing in there?"); + stage++; + break; + case 62: + npc("That depends on how much of a time-waster you are!", "You are required to use the Telekinetic Grab spell in", "order to move a statue throuhh a maze. Casting the", "spell will move the statue towards you until it reaches a"); + stage++; + break; + case 63: + npc("wall. So by standing on the different sides of the maze", "you can move the statue Nort, East, South or West.", "You will be rewarded Pizazz Points for each maze", "successfully solved."); + stage = 51; + break; + case 70: + npc("In the playground you can earn Alchemist Pizazz", "Points for trading with the rewards guardian upstairs."); + stage++; + break; + case 71: + player("What's in there?"); + stage++; + break; + case 72: + npc("You'll find eight cupboards containing items you can", "turn to gold using the low and high alchemy spells. The", "money you earn will be taken from you upon leaving", "the playground to pay for the upkeep of this training"); + stage++; + break; + case 73: + npc("arena and to help fund magic shops around " + GameWorld.getSettings().getName() + ".", "You will be rewarded with 1 Pizazz Point for every", "100 coins deposited and a percentage of the money you", "create. Keep in mind that you will not be able to take"); + stage++; + break; + case 74: + npc("more than 1000 coins back out with you."); + stage++; + break; + case 75: + player("Sounds simple."); + stage = 51; + break; + case 80: + npc("In here you will be able to earn Enchantment Pizazz", "Points for trade upstairs."); + stage++; + break; + case 81: + player("What will I have to do?"); + stage++; + break; + case 82: + npc("You will find yourself amongst various piles of shapes.", "You can pick up these shapes and use on of your", "enchanting spells upon it to morph it into an orb. You'll", "also see a hole in the centre of the room; put the orbs"); + stage++; + break; + case 83: + npc("in here and for every 20 we will credit you with a gift,", "You will get Pizazz Points for every 10 shapes that", "you convert and the amount of points depends on the", "spell you use."); + stage = 51; + break; + case 90: + npc("In here you will be able to earn Graveyard Pizazz", "Points for trade upstairs."); + stage++; + break; + case 91: + player("But what do I have to do in there?"); + stage++; + break; + case 92: + npc("Patience young one. A great many creatures die in", "this world and much of their remainds can cause clutter.", "We have taken it upon ourselves to teleport many", "bones from these creatures into this graveyard for a"); + stage++; + break; + case 93: + npc("use. It's up to you to practice your bones to bannanas", "spell in order to put these bones into immediate use -", "nutritious food for monsters! Just convert the bones", "and put them in the holes in the walls. There is a"); + stage++; + break; + case 94: + npc("drawback to this room however, the bones often fall on", "people so you may want to eat some of those bannas", "to stay alive. When people die we confiscate Pizazz", "Points for the effort of teleporting incompetent mages."); + stage = 51; + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 3097 }; + } + +} diff --git a/Server/src/main/content/minigame/mta/GraveyardGuardianDialogue.java b/Server/src/main/content/minigame/mta/GraveyardGuardianDialogue.java new file mode 100644 index 0000000..05d5a73 --- /dev/null +++ b/Server/src/main/content/minigame/mta/GraveyardGuardianDialogue.java @@ -0,0 +1,120 @@ +package content.minigame.mta; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; + +/** + * Handles the graveyard guardian dialogue. + * @author Vexia + */ +public class GraveyardGuardianDialogue extends DialoguePlugin { + + /** + * Constructs a new {@Code GraveyardGuardianDialogue} {@Code + * Object} + */ + public GraveyardGuardianDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@Code GraveyardGuardianDialogue} {@Code + * Object} + * @param player the player. + */ + public GraveyardGuardianDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new GraveyardGuardianDialogue(player); + } + + @Override + public boolean open(Object... args) { + player("Hello."); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + options("What do I have to do in this room?", "What are the rewards?", "Got any tips that may help me?", "Thanks, bye!"); + stage++; + break; + case 1: + switch (buttonId) { + case 1: + player("What do I have to do in this room?"); + stage = 10; + break; + case 2: + player("What are the rewards?"); + stage = 20; + break; + case 3: + player("Got any tips that may help me?"); + stage = 30; + break; + case 4: + player("Thanks, bye!"); + stage = 40; + break; + } + break; + case 10: + npc("Have you noticed all the bones around the room? These", "are teleported here from all over Gielinor to help", "clean up the landscape of countless bones left behind", "from combat. What better use for these bones than to"); + stage++; + break; + case 11: + npc("convert them to nutritious fruit to be eaten by you", "mortals? You have to use your Bones to Bannas spell", "to convert the bones and then place them in the holes", "on the walls to earn Graveyard Pizazz Points."); + stage++; + break; + case 12: + npc("Unluckily for you, your health will constantly decrease", "from getting hit by these dropping bones so you will", "probably want to eat some of the bananas yourself to", "increase your stay here."); + stage = 0; + break; + case 20: + npc("You will get experience from casting your bones to", "bananas spell and you will get Graveyard Pizazz Points", "when you put the bananas though the wall.", "Occasionally you will also be credited with a runestone"); + stage++; + break; + case 21: + npc("to help you in your future spell casting."); + stage = 0; + break; + case 30: + npc("Different bones will provide you with different numbers", "of bananas, so try to find the best type. Collect enough", "points and you will be able to buy a 'Bones to Peaches'", "spell from my fellow guardian above the entrance hall."); + stage++; + break; + case 31: + npc("This spell can be used here just like the bones to", "bananas spell, except this spell will give you even more", "experience and the peaches will restore more health!"); + stage++; + break; + case 32: + player("I see."); + stage++; + break; + case 33: + npc("Oh, and a word of warning: should you decide to leave", "this room by a method other than the exit portals, you", "will be teleported to the entrance and have any items", "that you picked up in the room removed."); + stage = 0; + break; + case 34: + end(); + break; + case 40: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 3101 }; + } + +} diff --git a/Server/src/main/content/minigame/mta/MTAListeners.kt b/Server/src/main/content/minigame/mta/MTAListeners.kt new file mode 100644 index 0000000..bc65634 --- /dev/null +++ b/Server/src/main/content/minigame/mta/MTAListeners.kt @@ -0,0 +1,108 @@ +package content.minigame.mta + +import content.global.skill.magic.SpellListener +import content.global.skill.magic.spellconsts.Modern +import core.api.playAudio +import core.game.node.item.Item +import core.game.world.map.Direction +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import org.rs09.consts.Sounds + +class MTAListeners : InteractionListener { + override fun defineListeners() { + on(NPCs.MAZE_GUARDIAN_3102, IntType.NPC, "talk-to"){ player, node -> + player.dialogueInterpreter.open(node.id, node) + return@on true + } + setDest(IntType.NPC, intArrayOf(NPCs.MAZE_GUARDIAN_3102), "talk-to") { player, node -> + return@setDest node.location.transform(Direction.getDirection(player.location, node.location), -1) + } + } +} + +class MTASpellListeners : SpellListener("modern"){ + private val LOW_ALCH_ANIM = Animation(712) + private val LOW_ALCH_GFX = Graphics(112,5) + private val HIGH_ALCH_ANIM = Animation(713) + private val HIGH_ALCH_GFX = Graphics(113,5) + private val MTA_ALCH_ITEMS = content.minigame.mta.impl.AlchemistZone.AlchemistItem.values().map{it.item.id}.toIntArray() + + override fun defineListeners() { + + onCast(Modern.HIGH_ALCHEMY,ITEM,*MTA_ALCH_ITEMS){ p, node -> + val item = node?.asItem() ?: return@onCast + requires(p,55) + val alchItem = content.minigame.mta.impl.AlchemistZone.AlchemistItem.forItem(item.id) ?: return@onCast + val coins = Item(content.minigame.mta.impl.AlchemistZone.COINS.id, alchItem.cost) + val freeAlch = alchItem == content.minigame.mta.impl.AlchemistZone.freeConvert + + if (p.inventory.getAmount(content.minigame.mta.impl.AlchemistZone.COINS.id) + alchItem.cost > 10000) { + p.dialogueInterpreter.sendDialogue("Warning: You can't deposit more than 12000 coins at a time.") + } + + if (coins.amount > 1 && !p.inventory.hasSpaceFor(coins)) { + p.packetDispatch.sendMessage("Not enough space in your inventory!") + return@onCast + } + + if(!freeAlch){ + requires(p,55,arrayOf(Item(Items.FIRE_RUNE_554,5),Item(Items.NATURE_RUNE_561,1))) + } + + p.lock(3) + p.visualize(HIGH_ALCH_ANIM,HIGH_ALCH_GFX) + if(p.inventory.remove(Item(item.id,1))){ + playAudio(p, Sounds.HIGH_ALCHEMY_97) + if (coins.amount != 0) { + p.inventory.add(coins) + } + } + + showMagicTab(p) + addXP(p,65.0) + setDelay(p,false) + removeRunes(p) + } + + onCast(Modern.LOW_ALCHEMY,ITEM,*MTA_ALCH_ITEMS){p, node -> + val item = node?.asItem() ?: return@onCast + requires(p,21) + val alchItem = content.minigame.mta.impl.AlchemistZone.AlchemistItem.forItem(item.id) ?: return@onCast + val coins = Item(content.minigame.mta.impl.AlchemistZone.COINS.id, alchItem.cost) + val freeAlch = alchItem == content.minigame.mta.impl.AlchemistZone.freeConvert + + if (p.inventory.getAmount(content.minigame.mta.impl.AlchemistZone.COINS.id) + alchItem.cost > 10000) { + p.dialogueInterpreter.sendDialogue("Warning: You can't deposit more than 12000 coins at a time.") + } + + if (coins.amount > 1 && !p.inventory.hasSpaceFor(coins)) { + p.packetDispatch.sendMessage("Not enough space in your inventory!") + return@onCast + } + + if(!freeAlch){ + requires(p,21,arrayOf(Item(Items.FIRE_RUNE_554,3),Item(Items.NATURE_RUNE_561,1))) + } + + p.lock(3) + p.visualize(LOW_ALCH_ANIM,LOW_ALCH_GFX) + if(p.inventory.remove(Item(item.id,1))){ + playAudio(p, Sounds.HIGH_ALCHEMY_97) + if (coins.amount != 0) { + p.inventory.add(coins) + } + } + + showMagicTab(p) + addXP(p,31.0) + setDelay(p,false) + removeRunes(p) + } + + } +} diff --git a/Server/src/main/content/minigame/mta/MTAShop.java b/Server/src/main/content/minigame/mta/MTAShop.java new file mode 100644 index 0000000..beb64a1 --- /dev/null +++ b/Server/src/main/content/minigame/mta/MTAShop.java @@ -0,0 +1,259 @@ +package content.minigame.mta; + +import core.api.ContainerisedItem; +import core.game.component.CloseEvent; +import core.game.component.Component; +import core.game.component.ComponentPlugin; +import core.game.container.Container; +import core.game.container.ContainerType; +import core.game.container.access.InterfaceContainer; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.plugin.Plugin; +import core.game.world.GameWorld; + +import java.util.ArrayList; +import java.util.List; + +import static core.api.ContentAPIKt.hasAnItem; + +/** + * Represents the mage training arena shop. + * @author Vexia + */ +public class MTAShop { + + /** + * The magic training arena shop items. + */ + private static final Item[] ITEMS = new Item[] { new Item(6908, 100), new Item(6910, 100), new Item(6912, 100), new Item(6914, 100), new Item(6916, 100), new Item(6918, 100), new Item(6920, 100), new Item(6922, 100), new Item(6924, 100), new Item(6889, 100), new Item(6926, 100), new Item(4695, 100), new Item(4696, 100), new Item(4697, 100), new Item(4698, 100), new Item(4694, 100), new Item(4699, 100), new Item(564, 100), new Item(562, 100), new Item(561, 100), new Item(560, 100), new Item(563, 100), new Item(566, 100), new Item(565, 100) }; + + /** + * The prices. + */ + private static final int[][] PRICES = new int[][] { { 30, 30, 300, 30 }, { 60, 60, 600, 60 }, { 150, 200, 1500, 150 }, { 240, 240, 2400, 240 }, { 400, 450, 4000, 400 }, { 350, 400, 3000, 350 }, { 120, 120, 1200, 120 }, { 175, 225, 1500, 175 }, { 450, 500, 5000, 450 }, { 500, 550, 6000, 500 }, { 200, 300, 2000, 200 }, { 1, 1, 15, 1 }, { 1, 1, 15, 1 }, { 1, 1, 15, 1 }, { 1, 1, 15, 1 }, { 1, 1, 15, 1 }, { 1, 1, 15, 1 }, { 0, 0, 5, 0 }, { 0, 1, 5, 1 }, { 0, 1, 0, 1 }, { 2, 1, 20, 1 }, { 2, 0, 0, 0 }, { 2, 2, 25, 2 }, { 2, 2, 25, 2 } }; + + /** + * The container. + */ + private final Container container = new Container(ITEMS.length, ContainerType.SHOP); + + /** + * The mage training arena shop plugin. + */ + private final MTAShopPlugin shopPlugin = new MTAShopPlugin(); + + /** + * The viewers. + */ + private final List viewers = new ArrayList<>(100); + + /** + * The shop component. + */ + private final Component component = new Component(197).setCloseEvent(new CloseEvent() { + + @Override + public boolean close(Player player, Component c) { + if (player == null) { + return true; + } + viewers.remove(player); + return true; + } + + }); + + /** + * Constructs a new {@Code MTAShop} {@Code Object} + */ + public MTAShop() { + container.add(ITEMS); + component.setPlugin(shopPlugin); + GameWorld.getPulser().submit(new Pulse(100) { + @Override + public boolean pulse() { + for (int i = 0; i < container.toArray().length; i++) { + final boolean main = true; + final Item item = container.toArray()[i]; + if (item == null) { + continue; + } + if (main) { + if (item.getAmount() < 100) { + item.setAmount(item.getAmount() + 1); + } + MTAShop.this.update(); + } + } + return false; + } + }); + } + + /** + * Opens the shop. + * @param player the player. + */ + public void open(final Player player) { + viewers.add(player); + player.getInterfaceManager().open(component); + update(); + updatePoints(player); + GameWorld.getPulser().submit(new Pulse(1, player) { + + @Override + public boolean pulse() { + updatePoints(player); + return true; + } + + }); + } + + /** + * Updates the viewers. + */ + private void update() { + for (Player p : viewers) { + if (p == null || !p.isActive()) { + continue; + } + InterfaceContainer.generateItems(p, container.toArray(), new String[] { "Buy", "Value" }, 197, 16, 4, 7); + } + } + + /** + * The item to purchase. + * @param player the player. + * @param item the item. + */ + public void buy(Player player, Item item, int slot) { + int[] prices = PRICES[slot]; + if (item.getAmount() < 1) { + player.sendMessage("The shop has ran out of stock."); + return; + } + item = new Item(item.getId(), 1); + if (!player.getInventory().hasSpaceFor(item)) { + player.sendMessage("You don't have enough inventory space."); + return; + } + for (int i = 0; i < prices.length; i++) { + if (getPoints(player, i) < prices[i]) { + player.sendMessage("You cannot afford that item."); + return; + } + } + if (item.getId() == 6926 && player.getSavedData().getActivityData().isBonesToPeaches()) { + player.sendMessage("You already unlocked that spell."); + return; + } + ContainerisedItem itemToRemove = null; + if (slot >= 1 && slot <= 3) { + Item required = ITEMS[slot - 1]; + itemToRemove = hasAnItem(player, required.getId()); + if (!itemToRemove.exists() && !player.hasItem(new Item(6914, 1))) { + player.sendMessage("You don't have the required wand in order to buy this upgrade."); + return; + } + } + if (container.getAmount(item) - 1 <= 0) { + container.get(slot).setAmount(0); + } else { + container.remove(item); + } + if (item.getId() == 6926) { + player.getSavedData().getActivityData().setBonesToPeaches(true); + player.getDialogueInterpreter().sendDialogue("The guardian teaches you how to use the Bones to Peaches spell!"); + } else { + if (itemToRemove == null || itemToRemove.remove()) + player.getInventory().add(item); + } + for (int i = 0; i < prices.length; i++) { + decrementPoints(player, i, prices[i]); + } + updatePoints(player); + update(); + } + + /** + * Values an item. + * @param player the player. + * @param item the item. + */ + public void value(Player player, Item item, int slot) { + int[] prices = PRICES[slot]; + player.sendMessage("The " + item.getName() + " costs " + prices[0] + " Telekinetic, " + prices[1] + " Alchemist,"); + player.sendMessage(prices[2] + " Enchantment and " + prices[3] + " Graveyard Pizazz Points."); + } + + /** + * Updates the points. + * @param player the player. + */ + public void updatePoints(Player player) { + player.getPacketDispatch().sendString("" + getPoints(player, 0), 197, 8);// tele + player.getPacketDispatch().sendString("" + getPoints(player, 2), 197, 9);// enchant + player.getPacketDispatch().sendString("" + getPoints(player, 1), 197, 10);// alch + player.getPacketDispatch().sendString("" + getPoints(player, 3), 197, 11);// grave + } + + /** + * Increments the pizazz points. + * @param player the player. + * @param index the index. + * @param increment the increment. + */ + public void incrementPoints(Player player, int index, int increment) { + player.getSavedData().getActivityData().incrementPizazz(index, increment); + } + + /** + * Decrements the pizazz points. + * @param player the player. + * @param index the index. + * @param decrement the decrement. + */ + public void decrementPoints(Player player, int index, int decrement) { + player.getSavedData().getActivityData().decrementPizazz(index, decrement); + } + + /** + * Gets the points. + * @param player the player. + * @param index the index. + * @return the points. + */ + public int getPoints(Player player, int index) { + return player.getSavedData().getActivityData().getPizazzPoints(index); + } + + /** + * The mta shop plugin. + * @author Vexia + */ + public class MTAShopPlugin extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + return null; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + Item item = container.get(slot); + if (item == null) { + return true; + } + if (opcode == 155) { + value(player, item, slot); + } else if (opcode == 196) { + buy(player, item, slot); + } + return true; + } + + } +} diff --git a/Server/src/main/content/minigame/mta/MTAType.java b/Server/src/main/content/minigame/mta/MTAType.java new file mode 100644 index 0000000..35ad046 --- /dev/null +++ b/Server/src/main/content/minigame/mta/MTAType.java @@ -0,0 +1,216 @@ +package content.minigame.mta; + +import content.minigame.mta.impl.AlchemistZone; +import content.minigame.mta.impl.EnchantingZone; +import content.minigame.mta.impl.GraveyardZone; +import content.minigame.mta.impl.TelekineticZone; +import core.game.component.Component; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.map.Location; + +import content.minigame.mta.impl.AlchemistZone; +import content.minigame.mta.impl.EnchantingZone; +import content.minigame.mta.impl.GraveyardZone; +import content.minigame.mta.impl.TelekineticZone; + +/** + * A magic training arena game type. + * @author Vexia + */ +public enum MTAType { + TELEKINETIC(10778, new Component(198), null, Location.create(3363, 3316, 0), new TelekineticZone()) { + @Override + public boolean hasRequirement(Player player) { + if (!player.getSkills().hasLevel(Skills.MAGIC, 33)) { + player.getDialogueInterpreter().sendDialogue("You need to be able to cast the Telekinetic Grab spell in order to", "enter."); + return false; + } + return true; + } + }, + ALCHEMISTS(10780, new Component(194), new Location(3366, 9623, 2), new Location(3363, 3320, 0), AlchemistZone.ZONE) { + @Override + public boolean hasRequirement(Player player) { + if (!player.getSkills().hasLevel(Skills.MAGIC, 21)) { + player.getDialogueInterpreter().sendDialogue("You need to be able to cast the Telekinetic Grab spell in order to", "enter."); + return false; + } + if (player.getInventory().contains(995, 1)) { + player.getDialogueInterpreter().sendDialogue("You cannot take money into the Alchemists' Playground."); + return false; + } + return true; + } + + @Override + public void exit(Player player) { + int earn = player.getAttribute("alch-earn", 0); + if (earn != 0) { + Item coins = new Item(995, earn); + if (player.getBank().hasSpaceFor(coins)) { + player.getBank().add(coins); + } + player.getDialogueInterpreter().sendDialogue("You've been awarded " + earn + " coins straight into your bank as a reward!"); + } + super.exit(player); + } + }, + ENCHANTERS(10779, new Component(195), new Location(3363, 9649, 0), new Location(3361, 3318, 0), EnchantingZone.ZONE) { + @Override + public boolean hasRequirement(Player player) { + if (!player.getSkills().hasLevel(Skills.MAGIC, 7)) { + player.getDialogueInterpreter().sendDialogue("You need to be able to cast the Lvl-1 Enchant spell in order to", "enter."); + return false; + } + return true; + } + }, + GRAVEYARD(10781, new Component(196), new Location(3363, 9639, 1), new Location(3365, 3318, 0), GraveyardZone.ZONE) { + @Override + public boolean hasRequirement(Player player) { + if (!player.getSkills().hasLevel(Skills.MAGIC, 15)) { + player.getDialogueInterpreter().sendDialogue("You need to be able to cast the Bones to Bananas spell in order to", "enter."); + return false; + } + if (player.getInventory().contains(1963, 1) || player.getInventory().contains(6883, 1)) { + player.getDialogueInterpreter().sendDialogue("You can't take bananas or peaches into the arena."); + return false; + } + return true; + } + }; + + /** + * The object id. + */ + private final int objectId; + + /** + * The overlay component. + */ + private final Component overlay; + + /** + * The start location. + */ + private final Location startLocation; + + /** + * The end location. + */ + private final Location endLocation; + + /** + * The mage training arena zone. + */ + private final MTAZone zone; + + /** + * Constructs a new {@Code MTAType} {@Code Object} + * @param objectId the object id. + * @param overlay the overlay. + * @param zone the zone. + */ + private MTAType(int objectId, Component overlay, Location startLocation, Location endLocation, MTAZone zone) { + this.objectId = objectId; + this.overlay = overlay; + this.zone = zone; + this.startLocation = startLocation; + this.endLocation = endLocation; + } + + /** + * Enters the mage training arena game. + * @param player the player. + */ + public void enter(Player player) { + if (!player.getSavedData().getActivityData().isStartedMta() || (!player.getInventory().containsItem(MageTrainingArenaPlugin.PROGRESS_HAT) && !player.getEquipment().containsItem(MageTrainingArenaPlugin.PROGRESS_HAT))) { + player.getDialogueInterpreter().sendDialogue("You need a Pizazz Progress Hat in order to enter. Talk to the", "Entrance Guardian if you don't have one."); + return; + } + if (!hasRequirement(player)) { + return; + } + if (this != TELEKINETIC) { + player.teleport(startLocation); + } else { + TelekineticZone.start(player); + } + player.sendMessage("You've entered the " + zone.getName() + "."); + } + + /** + * Exits the zone area. + * @param player the player. + */ + public void exit(Player player) { + player.teleport(endLocation); + } + + /** + * Checks if the player has the requirements. + * @param player the player. + * @return {@code True} if so. + */ + public boolean hasRequirement(Player player) { + return false; + } + + /** + * Gets the mta type for the zone. + * @param mtaZone the zone. + * @return the type. + */ + public static MTAType forZone(MTAZone mtaZone) { + for (MTAType type : values()) { + if (type == null) { + continue; + } + if (type.getZone() == mtaZone) { + return type; + } + } + return TELEKINETIC; + } + + /** + * Gets the mtat type. + * @param id the id. + * @return the mtat type. + */ + public static MTAType forId(int id) { + for (MTAType t : values()) { + if (t.getObjectId() == id) { + return t; + } + } + return null; + } + + /** + * Gets the objectId. + * @return the objectId + */ + public int getObjectId() { + return objectId; + } + + /** + * Gets the zone. + * @return the zone + */ + public MTAZone getZone() { + return zone; + } + + /** + * Gets the overlay. + * @return the overlay + */ + public Component getOverlay() { + return overlay; + } + +} diff --git a/Server/src/main/content/minigame/mta/MTAZone.java b/Server/src/main/content/minigame/mta/MTAZone.java new file mode 100644 index 0000000..7110812 --- /dev/null +++ b/Server/src/main/content/minigame/mta/MTAZone.java @@ -0,0 +1,167 @@ +package content.minigame.mta; + +import core.ServerConstants; +import core.game.interaction.Option; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.request.RequestType; +import core.game.node.item.Item; +import core.game.world.map.Location; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneRestriction; +import core.game.world.map.zone.ZoneType; + +/** + * Represents a magic training arena zone. + * @author Vexia + */ +public class MTAZone extends MapZone { + + /** + * The items. + */ + private final Item[] items; + + /** + * The mage training arena type. + */ + private MTAType type; + + /** + * Constructs a new {@Code MTAZone} {@Code Object} + * @param name the name. + * @param items the items. + */ + public MTAZone(String name, Item[] items) { + super(name, false, ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.FOLLOWERS); + this.items = items; + this.setZoneType(ZoneType.SAFE.getId()); + } + + @Override + public boolean enter(Entity entity) { + if (entity instanceof Player) { + Player player = entity.asPlayer(); + if (player == null) { + return true; + } + if (type == null) { + type = MTAType.forZone(this); + } + if (type != null) { + player.getInterfaceManager().openOverlay(type.getOverlay()); + update(player); + } + player.getProperties().setSpawnLocation(new Location(3363, 3302, 0)); + } + return super.enter(entity); + } + + @Override + public boolean canRequest(RequestType type, Player player, Player target) { + player.getDialogueInterpreter().sendDialogue("You can't do that right now."); + return false; + } + + @Override + public boolean interact(Entity e, Node target, Option option) { + if (e instanceof Player) { + if (target.getId() == 10782) { + getType().exit(e.asPlayer()); + return true; + } + } + return super.interact(e, target, option); + } + + @Override + public boolean teleport(Entity e, int type, Node node) { + if (e instanceof Player) { + if (type != -1) { + e.asPlayer().sendMessage("You can't teleport out of the training arena!"); + return false; + } + } + return super.teleport(e, type, node); + } + + @SuppressWarnings("deprecation") + @Override + public boolean leave(Entity entity, boolean logout) { + if (entity instanceof Player) { + Player player = entity.asPlayer(); + if (logout) { + player.setLocation(new Location(3363, 3302, 0)); + } else { + player.getProperties().setSpawnLocation(ServerConstants.HOME_LOCATION); + } + cleanItems(player); + player.getInterfaceManager().closeOverlay(); + } + return super.leave(entity, logout); + } + + @Override + public void configure() { + } + + /** + * Cleans the items. + */ + private void cleanItems(Player player) { + if (player == null) { + return; + } + for (Item item : items) { + if (item == null) { + continue; + } + if (player.getInventory().containsItem(item)) { + player.getInventory().remove(new Item(item.getId(), player.getInventory().getAmount(item))); + } + if (player.getEquipment().containsItem(item)) { + player.getEquipment().remove(new Item(item.getId(), player.getEquipment().getAmount(item))); + } + } + } + + /** + * Increments the pizazz points of a player. + * @param player the player. + * @param index the index. + * @param amount the amount. + */ + public void incrementPoints(Player player, int index, int amount) { + player.getSavedData().getActivityData().incrementPizazz(index, amount); + update(player); + } + + /** + * Updates the player. + * @param player the player. + */ + public void update(Player player) { + if (type == null) { + return; + } + player.getPacketDispatch().sendString("" + player.getSavedData().getActivityData().getPizazzPoints(type.ordinal()), type.getOverlay().getId(), 9); + } + + /** + * Gets the items. + * @return the items + */ + public Item[] getItems() { + return items; + } + + /** + * Gets the type. + * @return the type + */ + public MTAType getType() { + return type; + } + +} diff --git a/Server/src/main/content/minigame/mta/MageTrainingArenaPlugin.java b/Server/src/main/content/minigame/mta/MageTrainingArenaPlugin.java new file mode 100644 index 0000000..31dfc56 --- /dev/null +++ b/Server/src/main/content/minigame/mta/MageTrainingArenaPlugin.java @@ -0,0 +1,126 @@ +package content.minigame.mta; + +import content.minigame.mta.impl.TelekineticZone; +import core.cache.def.impl.ItemDefinition; +import core.cache.def.impl.NPCDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.entity.skill.Skills; +import content.global.skill.agility.AgilityHandler; +import core.game.node.item.GroundItem; +import core.game.node.item.Item; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.zone.ZoneBuilder; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; +import content.minigame.mta.EnchantSpell; +import core.plugin.ClassScanner; + +/** + * Handles the mage training area interactions. + * @author Vexia + */ +@Initializable +public class MageTrainingArenaPlugin extends OptionHandler { + + /** + * The progress hat. + */ + public static final Item PROGRESS_HAT = new Item(6885); + + /** + * The mage training arena shop. + */ + public static final MTAShop SHOP = new MTAShop(); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ItemDefinition.forId(6885).getHandlers().put("option:destroy", this); + ItemDefinition.forId(6885).getHandlers().put("option:talk-to", this); + SceneryDefinition.forId(10721).getHandlers().put("option:enter", this); + NPCDefinition.forId(3103).getHandlers().put("option:trade-with", this); + for (MTAType type : MTAType.values()) { + if (type.getZone() != null) { + ZoneBuilder.configure(type.getZone()); + } + SceneryDefinition.forId(type.getObjectId()).getHandlers().put("option:enter", this); + } + ItemDefinition.forId(TelekineticZone.STATUE).getHandlers().put("option:observe", this); + ItemDefinition.forId(TelekineticZone.STATUE).getHandlers().put("option:reset", this); + NPCDefinition.forId(3102).getHandlers().put("option:talk-to", this); + ClassScanner.definePlugins(new CharmedWarriorDialogue(), new EntranceGuardianDialogue(), new RewardsGuardianDialogue(), new ProgressHatDialogue(), new EnchantmentGuardianDialogue(), new EnchantSpell(), new GraveyardGuardianDialogue(), new AlchemyGuardianDialogue(), new TelekineticGrabSpell(), new TelekineticGuardianDialogue(), new MazeGuardianDialogue()); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + switch (node.getId()) { + case 10721: + if (!player.getSkills().hasLevel(Skills.MAGIC, 7)) { + player.getDialogueInterpreter().sendDialogue("You need a Magic level of at least 7 to enter the guild."); + break; + } + AgilityHandler.walk(player, -1, player.getLocation(), player.getLocation().transform(Direction.getDirection(player.getLocation(), node.getLocation()), 2), new Animation(1426), 0.0, null); + break; + case 3103: + if (!player.getSavedData().getActivityData().isStartedMta()) { + player.getDialogueInterpreter().open(3103, this, true, true); + } else { + SHOP.open(player); + } + break; + case 6885: + player.getDialogueInterpreter().open(3096, option.equals("destroy") ? new Object[] { node, true, true } : new Object[] {}); + break; + case 3102: + player.getDialogueInterpreter().open(node.getId(), node); + break; + } + switch (option) { + case "enter": + MTAType type = MTAType.forId(node.getId()); + if (type != null) { + type.enter(player); + } + break; + case "reset": + case "observe": + TelekineticZone zone = TelekineticZone.getZone(player); + if (option.equals("reset")) { + zone.reset(player); + } else { + zone.observe(player); + } + break; + } + return true; + } + + @Override + public boolean isWalk(Player player, Node n) { + if (!(n instanceof GroundItem)) { + return true; + } + if (n.getId() == TelekineticZone.STATUE) { + return false; + } + return true; + } + + @Override + public Location getDestination(Node node, Node n) { + if (n.getId() == 3102) { + return n.getLocation().transform(Direction.getDirection(node.getLocation(), n.getLocation()), -1); + } + return null; + } + + @Override + public boolean isWalk() { + return false; + } +} diff --git a/Server/src/main/content/minigame/mta/MazeGuardianDialogue.java b/Server/src/main/content/minigame/mta/MazeGuardianDialogue.java new file mode 100644 index 0000000..1a6aac8 --- /dev/null +++ b/Server/src/main/content/minigame/mta/MazeGuardianDialogue.java @@ -0,0 +1,93 @@ +package content.minigame.mta; + +import content.minigame.mta.impl.TelekineticZone; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; + +import content.minigame.mta.impl.TelekineticZone; + +/** + * Handles the maze guardian dialogue. + * @author Vexia + */ +public class MazeGuardianDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code MazeGuardianDialogue} {@code Object} + */ + public MazeGuardianDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code MazeGuardianDialogue} {@code Object} + * @param player the player. + */ + public MazeGuardianDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new MazeGuardianDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + player("Hi!"); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + npc("Well done on releasing me. Would you like to try", "another maze?"); + stage++; + break; + case 1: + options("Yes please!", "No thanks."); + stage++; + break; + case 2: + switch (buttonId) { + case 1: + player("Yes please!"); + stage = 5; + break; + case 2: + player("No thanks."); + stage++; + break; + } + break; + case 3: + npc("Very well. Talk to me if you want to move onto the", "next maze, or you can return to the entrance hall", "through the portal."); + stage++; + break; + case 4: + end(); + break; + case 5: + npc("Very well, I shall teleport you."); + stage++; + break; + case 6: + npc.clear(); + TelekineticZone.getZone(player).setUp(); + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 3102 }; + } + +} diff --git a/Server/src/main/content/minigame/mta/ProgressHatDialogue.java b/Server/src/main/content/minigame/mta/ProgressHatDialogue.java new file mode 100644 index 0000000..49030e0 --- /dev/null +++ b/Server/src/main/content/minigame/mta/ProgressHatDialogue.java @@ -0,0 +1,117 @@ +package content.minigame.mta; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +/** + * Handles the progress hat dialogue. + * @author Vexia + */ +public class ProgressHatDialogue extends DialoguePlugin { + + /** + * The progress hat. + */ + private Item progressHat; + + /** + * Constructs a new {@Code ProgressHatDialogue} {@Code Object} + */ + public ProgressHatDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@Code ProgressHatDialogue} {@Code Object} + * @param player the player. + */ + public ProgressHatDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new ProgressHatDialogue(player); + } + + @Override + public boolean open(Object... args) { + if (args.length > 1) { + progressHat = (Item) args[0]; + npc("How dare you destroy me? You'll lose your Pizazz", "Points!"); + stage = 50; + return true; + } + player("Mr Progress Hat... sir?"); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + npc("Can't you see I'm busy?"); + stage++; + break; + case 1: + player("But you're just a hat? Can you tell me my Pizazz", "Point totals?"); + stage++; + break; + case 2: + npc("Ok, I suppose it's my job. You have:", getPoints(0) + " Telekinetic, " + getPoints(1) + " Alchemist,", getPoints(2) + " Enchantment, and " + getPoints(3) + " Graveyard Pizazz Points."); + stage++; + break; + case 3: + player("Thank you!"); + stage++; + break; + case 4: + end(); + break; + case 50: + interpreter.sendOptions("Destroy Hat?", "Yes", "No"); + stage++; + break; + case 51: + switch (buttonId) { + case 1: + if (progressHat == null) { + end(); + return true; + } + if (!player.getInventory().containsItem(progressHat)) { + end(); + return true; + } + player.getInventory().remove(progressHat); + interpreter.sendDialogue("The hat whispers as you destroy it. You can get another from the", "Entrance Guardian."); + stage = 4; + break; + case 2: + npc("I think so too!"); + stage = 4; + break; + } + break; + } + return true; + } + + /** + * Gets the pizzaz points. + * @param index the index. + * @return the points. + */ + public int getPoints(int index) { + return player.getSavedData().getActivityData().getPizazzPoints(index); + } + + @Override + public int[] getIds() { + return new int[] { 3096 }; + } + +} diff --git a/Server/src/main/content/minigame/mta/RewardsGuardianDialogue.java b/Server/src/main/content/minigame/mta/RewardsGuardianDialogue.java new file mode 100644 index 0000000..39cd0e8 --- /dev/null +++ b/Server/src/main/content/minigame/mta/RewardsGuardianDialogue.java @@ -0,0 +1,136 @@ +package content.minigame.mta; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; + +/** + * Handles the rewards guardian dialogue. + * @author Vexia + */ +public class RewardsGuardianDialogue extends DialoguePlugin { + + /** + * Constructs a new {@Code RewardsGuardianDialogue} {@Code + * Object} + */ + public RewardsGuardianDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@Code RewardsGuardianDialogue} {@Code + * Object} + * @param player the player. + */ + public RewardsGuardianDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new RewardsGuardianDialogue(player); + } + + @Override + public boolean open(Object... args) { + if (args.length > 1) { + npc("Have you spoken to my fellow guardian downstairs?"); + stage = 4; + return true; + } + player("Hi."); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + if (!player.getSavedData().getActivityData().isStartedMta()) { + switch (stage) { + case 0: + npc("Greetings. Have you spoken to my fellow Guardian", "downstairs?"); + stage++; + break; + case 1: + player("Nope."); + stage++; + break; + case 2: + npc("Well, you need to talk to him first."); + stage++; + break; + case 3: + end(); + break; + case 4: + player("Nope."); + stage++; + break; + case 5: + npc("Well, you need to talk to him first."); + stage++; + break; + case 6: + end(); + break; + } + return true; + } + switch (stage) { + case 0: + npc("Greetings. What wisdom do you seek?"); + stage++; + break; + case 1: + options("Who are you?", "Can I trade my Pizazz Points please?", "Thanks, bye!"); + stage++; + break; + case 2: + switch (buttonId) { + case 1: + player("Who are you?"); + stage = 10; + break; + case 2: + player("Can I trade my Pizazz Points please?"); + stage = 20; + break; + case 3: + end(); + break; + } + break; + case 10: + npc("Me? I'm here to grant you rewards for any of the", "Pizazz Points you may have earned in this training", "arena. Like my fellow Guardians, I am part of the", "arena and live to ensure its safe running."); + stage++; + break; + case 11: + player("I see."); + stage = 1; + break; + case 20: + npc("Why of course."); + stage++; + break; + case 21: + end(); + MageTrainingArenaPlugin.SHOP.open(player); + break; + case 30: + npc("Well, we do stock a special book that you may be", "interested in, which provides a comprehensive guide to", "this training arena. It costs 200gp. Would like", "one?"); + stage++; + break; + case 31: + + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 3103 }; + } + +} diff --git a/Server/src/main/content/minigame/mta/TelekineticGrabSpell.java b/Server/src/main/content/minigame/mta/TelekineticGrabSpell.java new file mode 100644 index 0000000..72728d1 --- /dev/null +++ b/Server/src/main/content/minigame/mta/TelekineticGrabSpell.java @@ -0,0 +1,220 @@ +package content.minigame.mta; + +import content.minigame.mta.impl.TelekineticZone; +import core.game.interaction.SpecialGroundItems; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.node.entity.combat.spell.SpellType; +import core.game.node.entity.combat.spell.SpellBlocks; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.node.entity.player.link.audio.Audio; +import core.game.node.entity.combat.spell.MagicSpell; +import core.game.node.entity.combat.spell.Runes; +import core.game.node.item.GroundItem; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Plugin; +import core.game.global.action.PickupHandler; +import core.game.world.GameWorld; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.*; + +/** + * Represents the telekenitic grab spell. + * @author 'Vexia + * @author Emperor + * @version 1.0 + */ +public final class TelekineticGrabSpell extends MagicSpell { + + /** + * Represents the animation to use. + */ + private static final Animation ANIMATION = new Animation(2310); + + /** + * Represents the graphics to use. + */ + private static final Graphics START_GRAPHIC = new Graphics(142, 88, 15); + + /** + * Represents the end graphics to use. + */ + private static final Graphics END_GRAPHIC = new Graphics(144); + + /** + * Represents the sound to use. + */ + private static final Audio SOUND = new Audio(3007, 10, 1); + + /** + * Represents the projectile id to use. + */ + private static final int PROJECTILE_ID = 143; + + /** + * Represents the start height. + */ + private static final int START_HEIGHT = 40; + + /** + * Represents the end height. + */ + private static final int END_HEIGHT = 0; + + /** + * Represents the starting delay. + */ + private static final int START_DELAY = 41; + + /** + * Represents the angle. + */ + private static final int ANGLE = 5; + + /** + * Represents the spell id. + */ + public static final int SPELL_ID = 19; + + /** + * Constructs a new {@code TelekineticGrabSpell} {@code Object}. + */ + public TelekineticGrabSpell() { + super(SpellBook.MODERN, 33, 43, ANIMATION, START_GRAPHIC, SOUND, new Item[] { new Item(Runes.AIR_RUNE.getId()), new Item(Runes.LAW_RUNE.getId(), 1) }); + } + + @Override + public Plugin newInstance(SpellType arg) throws Throwable { + SpellBook.MODERN.register(SPELL_ID, this); + return this; + } + + @Override + public boolean cast(final Entity entity, final Node target) { + if (!(target instanceof GroundItem)) + return false; + final GroundItem ground = (GroundItem) target; + if (!canCast(entity, ground)) { + return false; + } + entity.lock(2); + visualize(entity, target); + GameWorld.getPulser().submit(getGrabPulse(entity, ground)); + return true; + } + + @Override + public void visualize(final Entity entity, final Node target) { + super.visualize(entity, target); + entity.faceLocation(target.getLocation()); + getProjectile(entity, (GroundItem) target).send(); + } + + /** + * Method used to get the grab pulse. + * @param entity the entity. + * @return the {@code Pulse}. + */ + public Pulse getGrabPulse(final Entity entity, final GroundItem ground) { + return new Pulse(getDelay(ground.getLocation().getDistance(entity.getLocation())), entity) { + @Override + public boolean pulse() { + Player player = entity instanceof Player ? (Player) entity : null; + GroundItem g = GroundItemManager.get(ground.getId(), ground.getLocation(), player); + if (g == null) { + player.getPacketDispatch().sendMessage("Too late!"); + return true; + } + if (g == SpecialGroundItems.AHAB_BEER.asGroundItem()){ + player.getDialogueInterpreter().open(2692, new NPC(2692), true); + return true; + } + if (player == null) { + return true; + } + boolean teleZone = player.getZoneMonitor().isInZone("Telekinetic Theatre") && g.getId() == 6888; + if (player != null) { + if (g == null || !g.isActive()) { + player.getPacketDispatch().sendMessage("Too late!"); + return true; + } + playAudio(player, Sounds.VULNERABILITY_IMPACT_3008); + if (!teleZone) { + player.getInventory().add(new Item(g.getId(), g.getAmount(), g.getCharge())); + } else { + TelekineticZone zone = TelekineticZone.getZone(player); + zone.moveStatue(); + player.lock(getDelay()); + } + player.getPacketDispatch().sendPositionedGraphics(END_GRAPHIC, ground.getLocation()); + } + if (!teleZone) { + GroundItemManager.destroy(g); + } + return true; + } + }; + } + + /** + * Method used to check if the spell can be casted. + * @param entity the entity. + * @param item the item to grab. + * @return {@code True} if so. + */ + public boolean canCast(final Entity entity, final GroundItem item) { + if (entity.getLocks().isInteractionLocked() || entity.getLocks().isComponentLocked()) { + return false; + } + if (entity instanceof Player) { + final Player player = (Player) entity; + if (!CombatSwingHandler.isProjectileClipped(player, item, false)) { + sendMessage(player, "I can't reach that."); //TODO authentic message? + return false; + } + if (!hasSpaceFor(player, item)) { + sendMessage(player, "You don't have enough inventory space."); + return false; + } + if (!PickupHandler.canTake(player, item, 1)) { + return false; + } + } + if(SpellBlocks.isBlocked(SPELL_ID,(Node) item)){ + if(entity instanceof Player){ + entity.asPlayer().getDialogueInterpreter().sendDialogue("You can't do that."); + } + return false; + } + return super.meetsRequirements(entity, true, true); + } + + /** + * Gets the projectile. + * @param entity the entity. + * @param item the item. + * @return the projectile. + */ + public Projectile getProjectile(Entity entity, GroundItem item) { + return Projectile.create(entity.getLocation(), item.getLocation(), PROJECTILE_ID, START_HEIGHT, END_HEIGHT, START_DELAY, Projectile.getSpeed(entity, item.getLocation()), ANGLE, 11); + } + + /** + * Gets the delay from the distance. + * @param distance the distance. + * @return the delay. + */ + public int getDelay(double distance) { + return (int) (2 + (distance * 0.5)); + } + +} diff --git a/Server/src/main/content/minigame/mta/TelekineticGuardianDialogue.java b/Server/src/main/content/minigame/mta/TelekineticGuardianDialogue.java new file mode 100644 index 0000000..79c3a2b --- /dev/null +++ b/Server/src/main/content/minigame/mta/TelekineticGuardianDialogue.java @@ -0,0 +1,118 @@ +package content.minigame.mta; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; + +/** + * Handles the telekinetic guardian dialogue. + * @author Vexia + */ +public class TelekineticGuardianDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code TelekineticGuardianDialogue} {@code Object} + */ + public TelekineticGuardianDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code TelekineticGuardianDialogue} {@code Object} + * @param player the player. + */ + public TelekineticGuardianDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new TelekineticGuardianDialogue(player); + } + + @Override + public boolean open(Object... args) { + player("Hi."); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + options("What do I have to do in this room?", "What are the rewards?", "Got any tips that may help me?", "Thanks, bye!"); + stage++; + break; + case 1: + switch (buttonId) { + case 1: + player("What do I have to do in this room?"); + stage = 10; + break; + case 2: + player("What are the rewards?"); + stage = 20; + break; + case 3: + player("Got any tips that may help me?"); + stage = 30; + break; + case 4: + player("Thanks, bye!"); + stage = 40; + break; + } + break; + case 10: + npc("In this room you will see a maze within which one of", "my fellow Guardians has been turned to stone for the", "purpose of this exercise. You must move the statue", "using your telekinetic grab spell to the exit square at"); + stage++; + break; + case 11: + npc("the edge of the maze to bring the Guardian back to life.", "Simply stand on the side that you wish for the statue to", "travel towards and cast the spell on the statue. Once", "you have solved the maze, the statue will change back"); + stage++; + break; + case 12: + npc("into the Guardian and he will award you with", "Telekinetic Pizazz Points and teleport you to the next", "maze. You can switch to a better view of the maze by", "selecting the 'Observe' option on the statue and return"); + stage = 13; + break; + case 13: + npc("your view to normal by selecting the same option again.", "There is also a 'Reset' option on the statue just in case", "things aren't going too well."); + stage = 0; + break; + case 20: + npc("As well as the experience in casting magic, you will get", "Telekinetic Pizazz Points for each maze successfully", "solved and bonus points for completing five mazes in a", "row without returning to the entrance."); + stage++; + break; + case 21: + npc("should also note that you will occasionally be rewarded", "with items when you put one of the enchanted orbs in", "the floor."); + stage = 0; + break; + case 30: + npc("Have a good look at the maze before you try to solve it", "because this can save you time and runes required to", "navigate the maze. Although you will still be getting", "magic experience for moving the statue incorrectly, you"); + stage++; + break; + case 31: + npc("won't be progressing towards collecting Telekinetic", "Pizazz Points. Lastly, all the mazes can be solved in ten", "moves or less."); + stage++; + break; + case 32: + player("I see."); + stage = 0; + break; + case 34: + end(); + break; + case 40: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 3098 }; + } + +} diff --git a/Server/src/main/content/minigame/mta/impl/AlchemistZone.java b/Server/src/main/content/minigame/mta/impl/AlchemistZone.java new file mode 100644 index 0000000..35cd787 --- /dev/null +++ b/Server/src/main/content/minigame/mta/impl/AlchemistZone.java @@ -0,0 +1,438 @@ +package content.minigame.mta.impl; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import content.minigame.mta.MTAZone; +import core.game.node.entity.skill.Skills; +import core.game.interaction.Option; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.update.flag.context.Animation; +import core.tools.RandomFunction; + +import content.minigame.mta.MTAType; + +/** + * Handles the alchemist playground game. + * @author Vexia + */ +public class AlchemistZone extends MTAZone { + + /** + * The alchemist zone. + */ + public static AlchemistZone ZONE = new AlchemistZone(); + + /** + * The coins currency. + */ + public static final Item COINS = new Item(8890); + + /** + * The players in the zone. + */ + private static final List PLAYERS = new ArrayList<>(20); + + /** + * The guardian. + */ + private static NPC guardian; + + /** + * The free alchemist item convert. + */ + public static AlchemistItem freeConvert; + + /** + * The pulse. + */ + private static final Pulse PULSE = new Pulse(GameWorld.getSettings().isDevMode() ? 15 : 53) { + @Override + public boolean pulse() { + if (PLAYERS.isEmpty()) { + return true; + } + shufflePrices(); + String forceChat = "The costs are changing!"; + if (freeConvert == null && RandomFunction.random(3) < 3) { + freeConvert = RandomFunction.getRandomElement(AlchemistItem.values()); + forceChat = "The " + freeConvert.getItem().getName().toLowerCase() + " " + (freeConvert == AlchemistItem.LEATHER_BOOTS ? "are" : "is") + " free to convert!"; + } else if (freeConvert != null) { + freeConvert = null; + } + guardian.sendChat(forceChat); + for (Player p : PLAYERS) { + if (p == null || !p.isActive()) { + continue; + } + getSession(p).shuffleObjects(); + updateInterface(p); + } + return false; + } + }; + + /** + * Constructs a new {@code AlchemistZone} {@code Object} + */ + public AlchemistZone() { + super("Alchemists' Playground", new Item[] { new Item(8890), new Item(6893), new Item(6894), new Item(6895), new Item(6896), new Item(6897) }); + } + + @Override + public boolean leave(Entity e, boolean logout) { + if (e instanceof Player && PLAYERS.contains(e)) { + PLAYERS.remove(e); + if (logout && e.asPlayer().getInventory().containsItem(COINS)) { + int deposit = e.asPlayer().getInventory().getAmount(COINS); + int val = deposit / 100; + int earn = val < 1 ? 0 : val; + incrementPoints(e.asPlayer(), MTAType.ALCHEMISTS.ordinal(), earn); + e.asPlayer().getInventory().remove(COINS); + } + e.asPlayer().removeAttribute("alchemist-session"); + } + return super.leave(e, logout); + } + + @Override + public void update(Player player) { + player.getPacketDispatch().sendString("" + player.getSavedData().getActivityData().getPizazzPoints(getType().ordinal()), getType().getOverlay().getId(), 3); + } + + @Override + public boolean enter(Entity e) { + if (guardian == null) { + guardian = RegionManager.getNpc(new Location(3363, 9627, 2), 3099, 20); + } + if (e instanceof Player && !PLAYERS.contains(e)) { + PLAYERS.add(e.asPlayer()); + if (!PULSE.isRunning()) { + PULSE.restart(); + PULSE.start(); + GameWorld.getPulser().submit(PULSE); + } + e.asPlayer().removeAttribute("alch-earn"); + setSession(e.asPlayer()); + updateInterface(e.asPlayer()); + } + return super.enter(e); + } + + @Override + public boolean interact(Entity e, Node target, Option option) { + if (e instanceof Player) { + Player player = e.asPlayer(); + if (target.getId() == 10734) { + deposit(player); + return true; + } else if (target.getId() >= 6893 && target.getId() <= 6897 && (!option.getName().equals("drop") && !option.getName().equals("take"))) { + player.getDialogueInterpreter().sendDialogue("This item isn't yours to wield, it belongs to the arena!"); + return true; + } else if (target.getName().equals("Cupboard")) { + search(player, target.asScenery()); + return true; + } + } + return super.interact(e, target, option); + } + + /** + * Searches a cupboard. + * @param player the player. + * @param object the object. + */ + private void search(Player player, Scenery object) { + AlchemistSession session = getSession(player); + AlchemistItem item = session.getItem(object.getId()); + if (object.getId() % 2 != 0) { + player.animate(Animation.create(3032)); + SceneryBuilder.replace(object, object.transform(object.getId() + 1), 35); + } + if (item == null) { + player.sendMessage("The cupboard is empty."); + return; + } + if (player.getInventory().freeSlots() < 1) { + player.sendMessage("You have no free space to hold any more items."); + return; + } + player.lock(1); + player.getInventory().add(item.getItem()); + player.sendMessage("You found: " + item.getItem().getName()); + } + + /** + * Deposits the coins. + * @param player the player. + */ + private void deposit(Player player) { + if (!player.getInventory().containsItem(COINS)) { + player.getDialogueInterpreter().sendDialogue("You don't have any coins to deposit."); + return; + } + int deposit = player.getInventory().getAmount(COINS); + if (deposit >= 12000) { + player.teleport(new Location(3363, 3302, 0)); + player.getDialogueInterpreter().sendDialogue("You have been ejected from the arena! You were warned", "not to deposit more than 12000 coins at once."); + return; + } + if (player.getInventory().remove(new Item(COINS.getId(), deposit))) { + int val = deposit / 100; + int earn = val < 1 ? 0 : val; + int exp = deposit * 2; + int taking = player.getAttribute("alch-earn", 0); + int add = (int) (val > 0 ? (deposit / 100) * 10 : 0); + if (add != 0) { + taking += add; + } + if (earn != 0) { + incrementPoints(player, MTAType.ALCHEMISTS.ordinal(), earn); + } + if (taking != 0) { + player.setAttribute("alch-earn", taking); + } + player.getSkills().addExperience(Skills.MAGIC, exp, true); + player.getDialogueInterpreter().sendDialogue("You've just deposited " + deposit + " coins, earning you " + earn + " Alchemist Pizazz", "Points and " + exp + " magic XP. So far you're taking " + taking + " coins as a", "a reward when you leave!"); + } + } + + /** + * Shuffles the prices. + */ + public static void shufflePrices() { + List list = Arrays.asList(1, 5, 8, 10, 15, 20, 30); + Collections.shuffle(list); + for (int i = 0; i < AlchemistItem.values().length; i++) { + AlchemistItem.values()[i].setCost(list.get(i)); + } + } + + /** + * Updates the alchemy interface. + * @param player the player. + */ + public static void updateInterface(Player player) { + for (AlchemistItem i : AlchemistItem.values()) { + player.getPacketDispatch().sendInterfaceConfig(194, i.getChild(), freeConvert == null ? true : freeConvert == i ? false : true); + player.getPacketDispatch().sendString(i.getCost() + "", 194, 9 + i.ordinal()); + } + } + + @Override + public void configure() { + shufflePrices(); + PULSE.stop(); + register(new ZoneBorders(3341, 9618, 3393, 9654, 2)); + } + + /** + * Sets the session. + * @param player the player. + * @return the session. + */ + public static AlchemistSession setSession(Player player) { + AlchemistSession session = new AlchemistSession(player); + player.setAttribute("alchemist-session", session); + return session; + } + + /** + * Gets the alchemist session. + * @param player the player. + * @return the session. + */ + public static AlchemistSession getSession(Player player) { + AlchemistSession session = player.getAttribute("alchemist-session", null); + if (session == null) { + session = setSession(player); + } + return session; + } + + /** + * An alchemist session. + * @author Vexia + */ + public static class AlchemistSession { + + /** + * The player instance. + */ + private final Player player; + + /** + * The current indexer. max = 7 + */ + private int indexer; + + /** + * Constructs a new {@code AlchemistSession} {@code Object} + * @param player the player. + */ + public AlchemistSession(Player player) { + this.player = player; + shuffleObjects(); + } + + /** + * Gets an alchemist item. + * @param id the id. + * @return the item. + */ + public AlchemistItem getItem(int id) { + int[] ids = new int[] { 10797, 10795, 10793, 10791, 10789, 10787, 10785, 10783 }; + int index = 0; + for (int i = 0; i < ids.length; i++) { + if (ids[i] == id || (ids[i] + 1) == id) { + index = i; + break; + } + } + int alchIndex = indexer + index; + if (indexer != 0) { + if (indexer >= 4 && index < 4) { + if (indexer == 4 && indexer - index < 4) { + return null; + } + if (indexer == 4) { + return AlchemistItem.LEATHER_BOOTS; + } else { + if (indexer == 6 && index == 0) { + return AlchemistItem.ADAMANT_HELM; + } else if (indexer == 6 && index == 1) { + return AlchemistItem.ADAMANT_KITESHIELD; + } else if (indexer == 6 && index == 2) { + return AlchemistItem.LEATHER_BOOTS; + } else if (indexer == 7 && index == 0) { + return AlchemistItem.EMERALD; + } else if (indexer == 7 && index == 1) { + return AlchemistItem.ADAMANT_HELM; + } else if (indexer == 7 && index == 2) { + return AlchemistItem.ADAMANT_KITESHIELD; + } else if (indexer == 7 && index == 3) { + return AlchemistItem.LEATHER_BOOTS; + } else if (indexer == 5 && index == 0) { + return AlchemistItem.ADAMANT_KITESHIELD; + } else if (indexer == 5 && index == 1) { + return AlchemistItem.LEATHER_BOOTS; + } + } + return null; + } else { + alchIndex -= (indexer + indexer); + } + } + int finalIndex = (AlchemistItem.values().length - 1) - alchIndex; + if (finalIndex > AlchemistItem.values().length - 1 || finalIndex < 0) { + return null; + } + return AlchemistItem.values()[finalIndex]; + } + + /** + * Shuffles the objects. + */ + private void shuffleObjects() { + indexer++; + if (indexer > 7) { + indexer = 0; + } + } + + /** + * Gets the player. + * @return the player + */ + public Player getPlayer() { + return player; + } + + } + + /** + * An alchemist item. + * @author Vexia + */ + public enum AlchemistItem { + LEATHER_BOOTS(new Item(6893)), ADAMANT_KITESHIELD(new Item(6894)), ADAMANT_HELM(new Item(6895)), EMERALD(new Item(6896)), RUNE_LONGSWORD(new Item(6897)); + + /** + * The item. + */ + private final Item item; + + /** + * The cost of the item. + */ + private int cost; + + /** + * Constructs a new {@code AlchemistItem} {@code Object} + * @param item the item. + */ + private AlchemistItem(Item item) { + this.item = item; + } + + /** + * Gets the alchemist item by the id. + * @param id the id. + * @return the item. + */ + public static AlchemistItem forItem(int id) { + for (AlchemistItem item : values()) { + if (item.getItem().getId() == id) { + return item; + } + } + return null; + } + + /** + * Gets the child. + * @return the child. + */ + public int getChild() { + return 14 + ordinal(); + } + + /** + * Gets the item. + * @return the item + */ + public Item getItem() { + return item; + } + + /** + * Gets the cost. + * @return the cost + */ + public int getCost() { + return cost; + } + + /** + * Sets the cost. + * @param cost the cost to set. + */ + private void setCost(int cost) { + this.cost = cost; + } + + } +} diff --git a/Server/src/main/content/minigame/mta/impl/EnchantingZone.java b/Server/src/main/content/minigame/mta/impl/EnchantingZone.java new file mode 100644 index 0000000..04f2fc7 --- /dev/null +++ b/Server/src/main/content/minigame/mta/impl/EnchantingZone.java @@ -0,0 +1,368 @@ +package content.minigame.mta.impl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import core.game.interaction.Option; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItem; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.update.flag.context.Animation; +import core.tools.RandomFunction; + +import content.minigame.mta.MTAZone; + +/** + * Handles the enchanting zone. + * @author Vexia + */ +public class EnchantingZone extends MTAZone { + + /** + * The singleton of this zone. + */ + public static final EnchantingZone ZONE = new EnchantingZone(); + + /** + * The bonus shape. + */ + public static Shapes BONUS_SHAPE = RandomFunction.getRandomElement(Shapes.values()); + + /** + * The random runes to earn. + */ + private static final Item[] RUNES = new Item[] { new Item(560, 3), new Item(565, 3), new Item(564, 3) }; + + /** + * The location of dragon stones. + */ + private static final Location[] STONES = new Location[] { Location.create(3354, 9645, 0), Location.create(3353, 9635, 0), Location.create(3359, 9632, 0), Location.create(3375, 9633, 0), Location.create(3374, 9643, 0), Location.create(3373, 9651, 0) }; + + /** + * The orb item. + */ + private static final Item ORB = new Item(6902); + + /** + * The players in the zone. + */ + private static final List PLAYERS = new ArrayList<>(20); + + /** + * The guardian. + */ + private static NPC guardian; + + /** + * The list of d spawns. + */ + private static Map> DSPAWNS = new HashMap<>(); + + /** + * The pulse. + */ + private static final Pulse PULSE = new Pulse(36) { + @Override + public boolean pulse() { + if (PLAYERS.isEmpty()) { + return true; + } + Shapes shape = null; + while (shape == null) { + shape = RandomFunction.getRandomElement(Shapes.values()); + if (shape == BONUS_SHAPE) { + shape = null; + } + } + BONUS_SHAPE = shape; + for (Player player : PLAYERS) { + if (player == null || !player.isActive()) { + continue; + } + BONUS_SHAPE.setAsBonus(player); + } + if (guardian != null) { + guardian.sendChat("The bonus shape has changed to the " + BONUS_SHAPE.name().toLowerCase().replace("_", " ").trim() + "."); + } + return false; + } + + }; + + /** + * Constructs a new {@Code EnchantingZone} {@Code Object} + */ + public EnchantingZone() { + super("Enchantment Chamber", new Item[] { new Item(6899), new Item(6898), new Item(6900), new Item(6901), new Item(6903), new Item(6902) }); + } + + @Override + public boolean leave(Entity e, boolean logout) { + if (e instanceof Player && PLAYERS.contains(e)) { + PLAYERS.remove(e); + } + return super.leave(e, logout); + } + + @Override + public boolean enter(Entity e) { + if (guardian == null) { + guardian = RegionManager.getNpc(new Location(3361, 9647, 0), 3100, 20); + } + if (e instanceof Player && !PLAYERS.contains(e)) { + PLAYERS.add(e.asPlayer()); + if (!PULSE.isRunning()) { + PULSE.restart(); + PULSE.start(); + GameWorld.getPulser().submit(PULSE); + } + createGroundSpawns(e.asPlayer()); + BONUS_SHAPE.setAsBonus(e.asPlayer()); + update(e.asPlayer()); + } + return super.enter(e); + } + + @Override + public boolean interact(Entity e, Node target, Option option) { + if (e instanceof Player) { + Player player = e.asPlayer(); + if (target.getId() >= 10799 && target.getId() <= 10802) { + Shapes.forId(target.getId()).take(player, target.asScenery()); + return true; + } + if (target.getId() == 10803) { + deposit(player); + return true; + } + } + return super.interact(e, target, option); + } + + /** + * Creates the ground spawns. + * @param player + */ + public void createGroundSpawns(final Player player) { + if (DSPAWNS.containsKey(player.getName())) { + List items = getGroundSpawns(player); + for (GroundItem item : items) { + item.setDropper(player); + } + DSPAWNS.put(player.getName(), items); + return; + } + List items = getGroundSpawns(player); + for (Location location : STONES) { + final GroundItem item = new GroundItem(new Item(6903), location, player) { + + @Override + public boolean isAutoSpawn() { + return true; + } + + @Override + public boolean isActive() { + return true; + } + + @Override + public boolean isRemainPrivate() {return true;} + + @Override + public void respawn() { + GameWorld.getPulser().submit(getRespawnPulse(this)); + } + }; + items.add(item); + GroundItemManager.create(item); + } + DSPAWNS.put(player.getName(), items); + } + + /** + * Gets the respawn pulse. + * @param item the item. + * @return the pulse. + */ + public Pulse getRespawnPulse(final GroundItem item) { + return new Pulse(GameWorld.getSettings().isDevMode() ? 45 : RandomFunction.random(700, 800)) { + @Override + public boolean pulse() { + GroundItemManager.create(item); + return true; + } + }; + } + + /** + * Removes the ground spawns. + * @param player the player. + */ + public void removeGroundSpawns(Player player) { + List items = getGroundSpawns(player); + for (GroundItem item : items) { + GroundItemManager.destroy(item); + } + } + + /** + * Gets the ground item spawns. + * @param player the player. + * @return the items. + */ + public List getGroundSpawns(Player player) { + List items = DSPAWNS.get(player.getName()); + if (items == null) { + items = new ArrayList(); + } + DSPAWNS.put(player.getName(), items); + return items; + } + + /** + * Deposits the players enchanted orbs. + * @param player the player. + */ + private void deposit(Player player) { + if (!player.getInventory().containsItem(ORB)) { + player.sendMessage("You don't have any orbs to deposit."); + return; + } + int amount = player.getInventory().getAmount(ORB); + player.animate(Animation.create(832)); + player.getInventory().remove(new Item(ORB.getId(), amount)); + int prevAmt = player.getAttribute("mta-orb", 0); + prevAmt += amount; + if (prevAmt >= 20) { + prevAmt = 0; + player.getInventory().add(RandomFunction.getRandomElement(RUNES), player); + player.getDialogueInterpreter().sendDialogue("Congratulations! You've been rewarded with an item for your efforts."); + } + player.setAttribute("mta-orb", prevAmt); + } + + @Override + public void configure() { + PULSE.stop(); + register(new ZoneBorders(3335, 9612, 3389, 9663, 0, true)); + } + + /** + * The shapes around the room to enchant. + * @author Vexia + */ + public enum Shapes { + CUBE(10799, new Item(6899)), CYLINDER(10800, new Item(6898)), PENTAMID(10802, new Item(6901)), ICOSAHEDRON(10801, new Item(6900)); + + /** + * The object of the shape. + */ + private final int objectId; + + /** + * The item for the shape. + */ + private final Item item; + + /** + * Constructs a new {@Code Shapes} {@Code Object} + * @param objectId + * @param item + */ + private Shapes(int objectId, Item item) { + this.objectId = objectId; + this.item = item; + } + + /** + * Takes from the shape object. + * @param player the player. + */ + public void take(Player player, Scenery object) { + if (!player.getInventory().hasSpaceFor(item)) { + player.sendMessage("You have no space left in your inventory."); + return; + } + player.lock(1); + player.getInventory().add(item); + player.animate(Animation.create(827)); + } + + /** + * Sets it as the bonus type. + * @param player the player. + */ + public void setAsBonus(Player player) { + for (Shapes s : values()) { + player.getPacketDispatch().sendInterfaceConfig(195, s.getChild(), true); + } + player.getPacketDispatch().sendInterfaceConfig(195, getChild(), false); + } + + /** + * Gets the child. + * @return the child. + */ + public int getChild() { + return 1 + ordinal(); + } + + /** + * Gets the shape by the item. + * @param item the item. + * @return the shape. + */ + public static Shapes forItem(Item item) { + for (Shapes s : values()) { + if (s.getItem().getId() == item.getId()) { + return s; + } + } + return null; + } + + /** + * Gets a shape for the id. + * @param id the id. + * @return the shape. + */ + public static Shapes forId(int id) { + for (Shapes s : values()) { + if (s.getObjectId() == id) { + return s; + } + } + return null; + } + + /** + * Gets the objectId. + * @return the objectId + */ + public int getObjectId() { + return objectId; + } + + /** + * Gets the item. + * @return the item + */ + public Item getItem() { + return item; + } + + } +} diff --git a/Server/src/main/content/minigame/mta/impl/GraveyardZone.java b/Server/src/main/content/minigame/mta/impl/GraveyardZone.java new file mode 100644 index 0000000..ace8aaf --- /dev/null +++ b/Server/src/main/content/minigame/mta/impl/GraveyardZone.java @@ -0,0 +1,295 @@ +package content.minigame.mta.impl; + +import java.util.ArrayList; +import java.util.List; + +import core.game.node.entity.skill.Skills; +import core.game.interaction.Option; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.ImpactHandler.HitsplatType; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.tools.RandomFunction; +import core.tools.StringUtils; + +import content.minigame.mta.MTAType; +import content.minigame.mta.MTAZone; + +/** + * Handles the creature graveyard zone. + * @author Vexia + */ +public class GraveyardZone extends MTAZone { + + /** + * The graveyard zone. + */ + public static final GraveyardZone ZONE = new GraveyardZone(); + + /** + * The players in the zone. + */ + private static final List PLAYERS = new ArrayList<>(20); + + /** + * The runes rewarded by a chance. + */ + private static final Item[] RUNES = new Item[] { new Item(561), new Item(555), new Item(557) }; + + /** + * The banana item. + */ + private static final Item BANANA = new Item(1963); + + /** + * The peach item. + */ + private static final Item PEACH = new Item(6883); + + /** + * The positions for the graphics. + */ + private static final Location[] GFX_POS = new Location[] { Location.create(3370, 9634, 1), Location.create(3359, 9634, 1), Location.create(3360, 9643, 1), Location.create(3363, 9643, 1), Location.create(3363, 9633, 1), Location.create(3367, 9637, 1), Location.create(3366, 9642, 1), Location.create(3380, 9647, 1), Location.create(3375, 9648, 1), Location.create(3370, 9649, 1), Location.create(3372, 9644, 1), Location.create(3379, 9646, 1), Location.create(3381, 9651, 1), Location.create(3379, 9656, 1), Location.create(3373, 9658, 1), Location.create(3353, 9648, 1), Location.create(3356, 9653, 1), Location.create(3346, 9657, 1), Location.create(3347, 9655, 1), Location.create(3354, 9634, 1), Location.create(3352, 9631, 1), Location.create(3355, 9627, 1), Location.create(3345, 9631, 1), Location.create(3345, 9627, 1), Location.create(3347, 9623, 1), Location.create(3351, 9621, 1), Location.create(3368, 9624, 1), Location.create(3368, 9631, 1), Location.create(3375, 9630, 1), Location.create(3375, 9635, 1), Location.create(3371, 9621, 1), Location.create(3377, 9621, 1), Location.create(3381, 9624, 1), Location.create(3382, 9629, 1), Location.create(3371, 9635, 1), Location.create(3365, 9634, 1), Location.create(3361, 9641, 1), Location.create(3363, 9644, 1) }; + + /** + * The pulse. + */ + private static final Pulse PULSE = new Pulse(6) { + @Override + public boolean pulse() { + if (PLAYERS.isEmpty()) { + return true; + } + List locs = new ArrayList<>(20); + for (Location l : GFX_POS) { + if (RandomFunction.random(12) >= 8) { + continue; + } + locs.add(l); + } + for (Player player : PLAYERS) { + if (player == null || !player.isActive()) { + continue; + } + for (Location l : locs) { + player.getPacketDispatch().sendPositionedGraphics(Graphics.create(520), l); + } + if (player.getDialogueInterpreter().getDialogue() == null) { + player.getImpactHandler().manualHit(player, 2, HitsplatType.NORMAL); + } + } + locs = null; + setDelay(RandomFunction.random(6, 12)); + return false; + } + }; + + /** + * Constructs a new {@Code GraveyardZone} {@Code Object} + */ + public GraveyardZone() { + super("Creature Graveyard", new Item[] { new Item(6904), new Item(6905), new Item(6906), new Item(6907), new Item(1963), new Item(6883) }); + } + + + @Override + public void update(Player player) { + player.getPacketDispatch().sendString("" + player.getSavedData().getActivityData().getPizazzPoints(getType().ordinal()), getType().getOverlay().getId(), 12); + } + + @Override + public boolean leave(Entity e, boolean logout) { + if (e instanceof Player && PLAYERS.contains(e)) { + PLAYERS.remove(e); + } + return super.leave(e, logout); + } + + @Override + public boolean enter(Entity e) { + if (e instanceof Player && !PLAYERS.contains(e)) { + PLAYERS.add(e.asPlayer()); + if (!PULSE.isRunning()) { + PULSE.restart(); + PULSE.start(); + GameWorld.getPulser().submit(PULSE); + } + } + return super.enter(e); + } + + @Override + public boolean interact(Entity e, Node target, Option option) { + if (e instanceof Player) { + Player player = e.asPlayer(); + if (target.getId() == 10735) { + deposit(player); + return true; + } else if (target.getId() >= 10725 && target.getId() <= 10728) { + BoneType.forObject(target.getId()).grab(player, target.asScenery()); + return true; + } + } + return super.interact(e, target, option); + } + + @Override + public boolean death(Entity e, Entity killer) { + if (e instanceof Player) { + Player p = e.asPlayer(); + int points = p.getSavedData().getActivityData().getPizazzPoints(MTAType.GRAVEYARD.ordinal()); + if (points >= 10) { + p.getSavedData().getActivityData().decrementPizazz(MTAType.GRAVEYARD.ordinal(), 10); + } else { + p.getSavedData().getActivityData().decrementPizazz(MTAType.GRAVEYARD.ordinal(), points); + } + } + return super.death(e, killer); + } + + /** + * Deposits the fruit into the chute. + * @param player the player. + */ + private void deposit(Player player) { + if (!player.getInventory().containsItem(BANANA) && !player.getInventory().containsItem(PEACH)) { + player.getDialogueInterpreter().sendDialogue("You don't have any bananas or peaches to deposit."); + return; + } + int totalAmount = player.getAttribute("grave-amt", 0); + int amount = 0; + Item[] items = new Item[] { BANANA, PEACH }; + for (Item item : items) { + if (player.getInventory().containsItem(item)) { + amount = player.getInventory().getAmount(item); + totalAmount += amount; + player.getInventory().remove(new Item(item.getId(), amount)); + } + } + if (totalAmount >= 16) { + if (totalAmount > 16) { + totalAmount = totalAmount - 16; + } else { + totalAmount = 0; + } + Item rune = RandomFunction.getRandomElement(RUNES); + String name = rune.getName().toLowerCase(); + player.getInventory().add(rune, player); + incrementPoints(player, MTAType.GRAVEYARD.ordinal(), 1); + player.getSkills().addExperience(Skills.MAGIC, 50, true); + player.getDialogueInterpreter().sendDialogue("Congratulations - you've been awarded a" + (StringUtils.isPlusN(name) ? "n" : "") + " " + name + " and extra", "magic XP."); + } + player.setAttribute("grave-amt", totalAmount); + } + + @Override + public void configure() { + PULSE.stop(); + register(new ZoneBorders(3333, 9610, 3390, 9663, 1, true)); + } + + /** + * A bone type. + * @author Vexia + */ + public enum BoneType { + FIRST(10725, new Item(6904)), SECOND(10726, new Item(6905)), THIRD(10727, new Item(6906)), FOURTH(10728, new Item(6907)); + + /** + * The object id of the bone. + */ + private final int objectId; + + /** + * The item of the bone. + */ + private final Item item; + + /** + * Constructs a new {@Code BoneType} {@Code Object} + * @param objectId the object id. + * @param item the item. + */ + private BoneType(int objectId, Item item) { + this.objectId = objectId; + this.item = item; + } + + /** + * Grabs the bone from the object. + * @param player the player. + * @param object the object. + */ + public void grab(Player player, Scenery object) { + if (player.getInventory().freeSlots() < 1) { + player.sendMessage("You have no free space!"); + return; + } + int life = object.getAttributes().getAttribute("life", 4); + player.lock(1); + player.getInventory().add(item); + player.animate(Animation.create(827)); + life -= 1; + if (life < 1) { + life = 4; + BoneType type = ordinal() + 1 > BoneType.values().length - 1 ? BoneType.FIRST : BoneType.values()[ordinal() + 1]; + SceneryBuilder.replace(object, object.transform(type.getObjectId())); + } + object.getAttributes().setAttribute("life", life); + } + + /** + * Gets a bone type for the item. + * @param item the item. + * @return the bone type. + */ + public static BoneType forItem(Item item) { + for (BoneType type : values()) { + if (type.getItem().getId() == item.getId()) { + return type; + } + } + return null; + } + + /** + * Gets the bone type by the object id. + * @param objectId the id. + * @return the type. + */ + public static BoneType forObject(int objectId) { + for (BoneType type : values()) { + if (type.getObjectId() == objectId) { + return type; + } + } + return null; + } + + /** + * Gets the objectId. + * @return the objectId + */ + public int getObjectId() { + return objectId; + } + + /** + * Gets the item. + * @return the item + */ + public Item getItem() { + return item; + } + + } +} diff --git a/Server/src/main/content/minigame/mta/impl/TelekineticZone.java b/Server/src/main/content/minigame/mta/impl/TelekineticZone.java new file mode 100644 index 0000000..a810548 --- /dev/null +++ b/Server/src/main/content/minigame/mta/impl/TelekineticZone.java @@ -0,0 +1,556 @@ +package content.minigame.mta.impl; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import core.game.dialogue.DialogueAction; +import core.game.node.entity.skill.Skills; +import core.game.interaction.Option; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItem; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.build.DynamicRegion; +import core.game.world.map.path.Path; +import core.game.world.map.path.Pathfinder; +import core.net.packet.PacketRepository; +import core.net.packet.context.CameraContext; +import core.net.packet.context.CameraContext.CameraType; +import core.net.packet.out.CameraViewPacket; +import core.tools.RandomFunction; + +import content.minigame.mta.MTAType; +import content.minigame.mta.MTAZone; + +/** + * Handles the telekinetic zone. + * @author Vexia, Player Name + */ +public class TelekineticZone extends MTAZone { + + /** + * The statue used in the game. + */ + public static final int STATUE = 6888; + + /** + * The player. + */ + private final Player player; + + /** + * The mazes to choose from. + */ + private final List mazes = new ArrayList<>(20); + + /** + * The dynamic region. + */ + private DynamicRegion region; + + /** + * The location. + */ + private Location base; + + /** + * The maze. + */ + private Maze maze; + + /** + * The statue item. + */ + private GroundItem statue; + + /** + * The npc guardian. + */ + private NPC guardian; + + /** + * The solved mazes. + */ + private int solved; + + /** + * Constructs a new {@code TelekineticZone} {@code Object} + * @param player the player. + */ + public TelekineticZone(Player player) { + super("Telekinetic Theatre", new Item[] {}); + this.player = player; + if (player != null) { + mazes.addAll(Arrays.asList(Maze.values())); + this.solved = player.getSavedData().getActivityData().getSolvedMazes(); + } + } + + /** + * Constructs a new {@code TelekineticZone} {@code Object} + */ + public TelekineticZone() { + this(null); + } + + /** + * Starts the telekinetic game for a player. + * @param player the player. + */ + public static void start(Player player) { + setZone(player); + } + + @Override + public void update(Player player) { + player.getPacketDispatch().sendString("" + player.getSavedData().getActivityData().getPizazzPoints(getType().ordinal()), getType().getOverlay().getId(), 4); + player.getPacketDispatch().sendString("" + solved, 198, 7); + } + + @Override + public boolean leave(Entity entity, boolean logout) { + if (entity instanceof Player) { + Player player = entity.asPlayer(); + if (player == null || player != this.player) { + return super.leave(entity, logout); + } + if (statue != null) { + GroundItemManager.destroy(statue); + } + if (guardian != null) { + guardian.clear(); + } + player.removeAttribute("camera"); + } + return super.leave(entity, logout); + } + + @Override + public boolean interact(Entity e, Node target, Option option) { + return super.interact(e, target, option); + } + + @Override + public boolean parseCommand(Player player, String name, String[] arguments) { + switch (name) { + case "childs": + for (int i = 0; i < 8; i++) { + player.getPacketDispatch().sendString("child=" + i, 198, i); + } + break; + case "reset": + if (player.getAttribute("camera", false)) { + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.RESET, 0, 0, 400, 1, 20)); + player.setAttribute("camera", false); + return true; + } + return true; + } + return false; + } + + @Override + public void configure() { + setUid(getName().hashCode()); + region = DynamicRegion.create(13463); + setBase(Location.create(region.getBorders().getSouthWestX(), region.getBorders().getSouthWestY(), 0)); + registerRegion(region.getId()); + } + + /** + * Sets up the player in the maze. + */ + public void setUp() { + Maze maze = this.maze == null ? RandomFunction.getRandomElement(mazes.toArray(new Maze[] {})) : null; + while (maze == null) { + maze = RandomFunction.getRandomElement(mazes.toArray(new Maze[] {})); + if (maze == this.maze) { + maze = null; + } + } + mazes.remove(maze); + setMaze(maze); + setNodes(); + player.teleport(base.transform(maze.getBase())); + } + + /** + * Sets up the nodes. + */ + public void setNodes() { + if (statue != null) { + GroundItemManager.destroy(statue); + } + if (guardian != null) { + guardian.clear(); + } + moveStatue(base.transform(maze.getStatueLocation())); + guardian = NPC.create(3098, base.transform(maze.getGuardianLocation())); + guardian.setWalks(true); + guardian.init(); + } + + /** + * Moves the statue. + * @param location the location. + */ + public void moveStatue(Location location) { + if (statue != null) { + GroundItemManager.destroy(statue); + } + GroundItemManager.create(statue = createGroundItem(location)); + } + + /** + * Creates the statue ground item. + * @param location the location. + * @return the item. + */ + public GroundItem createGroundItem(Location location) { + GroundItem item = new GroundItem(new Item(STATUE), location, player) { + @Override + public boolean isActive() { + return !isRemoved(); + } + }; + return item; + } + + /** + * Sets the telekinetic zone. + * @param player the player. + * @return the zone. + */ + public static TelekineticZone setZone(Player player) { + TelekineticZone zone = new TelekineticZone(player); + zone.configure(); + zone.setUp(); + player.setAttribute("tele-zone", zone); + return zone; + } + + /** + * Gets the zone. + * @param player the player. + * @return the zone. + */ + public static TelekineticZone getZone(Player player) { + TelekineticZone zone = player.getAttribute("tele-zone", null); + if (zone == null) { + zone = setZone(player); + } + return zone; + } + + /** + * Called when the player wins. + */ + private void win() { + solved++; + GroundItemManager.destroy(statue); + int points = 2; + player.getDialogueInterpreter().sendDialogue("Congratulations! You have received two Telekinetic Pizazz Points!"); + if (solved >= 5) { + mazes.addAll(Arrays.asList(Maze.values())); + solved = 0; + points += 8; + player.getSkills().addExperience(Skills.MAGIC, 1000, true); + player.getInventory().add(new Item(563, 10)); + player.getSavedData().getActivityData().setSolvedMazes(0); + player.getDialogueInterpreter().addAction(new DialogueAction() { + @Override + public void handle(Player player, int buttonId) { + player.getDialogueInterpreter().sendDialogue("Congratulations on solving five mazes in a row, have 8 bonus points,", "10 law runes and extra magic XP!"); + } + }); + } + player.getSavedData().getActivityData().setSolvedMazes(solved); + incrementPoints(player, MTAType.TELEKINETIC.ordinal(), points); + TelekineticZone.this.update(player); + player.setAttribute("camera", false); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.RESET, 0, 0, 400, 1, 20)); + NPC mazeGuard = NPC.create(3102, base.transform(maze.getEndLocation())); + mazeGuard.init(); + } + + /** + * Moves the statue with a telekinetic teleport. + */ + public void moveStatue() { + final Direction dir = getDir(); + if (dir == null) { + player.sendMessage("Invalid move!"); + return; + } + player.lock(); + GameWorld.getPulser().submit(new Pulse(1, player) { + boolean win = false; + + @Override + public boolean pulse() { + if (win) { + win(); + return true; + } + Location next = statue.getLocation().transform(dir, 1); + Path path = Pathfinder.find(statue.getLocation(), next); + boolean end = !path.isSuccessful() || path.isMoveNear() || path.getPoints().size() > 2; + if (end) { + return true; + } + if (next.equals(base.transform(maze.getEndLocation()))) { + win = true; + } + moveStatue(next); + return end; + } + + @Override + public void stop() { + player.unlock(); + super.stop(); + } + }); + } + + /** + * Observes from above. + * @param player the player. + */ + public void observe(Player player) { + if (player.getAttribute("camera", false)) { + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.RESET, 0, 0, 400, 1, 20)); + player.setAttribute("camera", false); + return; + } + player.sendMessage("Click observe on the guardian to reset your camera, or use the command ::reset !"); + Location l = base.transform(maze.getCameraLocation()); + int x = l.getX(); + int y = l.getY(); + int yInc = -10; + int xInc = 0; + int speed = 95; + int height = 798; + player.setAttribute("camera", true); + if (maze == Maze.FOURTH) { + x += 11; + y += 15; + height = 799; + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.POSITION, x + xInc, y + yInc, height, 1, speed)); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.ROTATION, x - 55, y - 25, height, 1, speed)); + return; + } + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.POSITION, x + xInc, y + yInc, height, 1, speed)); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.ROTATION, x + xInc, y + yInc, height, 1, speed)); + } + + /** + * Resets the player. + * @param player the player. + */ + public void reset(Player player) { + moveStatue(base.transform(maze.getStatueLocation())); + } + + /** + * Gets the direction to go. + * @return the direction. + */ + private Direction getDir() { + int myX = player.getLocation().getLocalX(); + int myY = player.getLocation().getLocalY(); + // anything >= 23 is north, anything <= is south, any x <= 10 is west, + // any x >= 21 is east + int[] data = maze.getData(); + if (myY >= data[0]) { + return Direction.NORTH; + } else if (myY <= data[1]) { + return Direction.SOUTH; + } else if (myX <= data[2]) { + return Direction.WEST; + } else if (myX >= data[3]) { + return Direction.EAST; + } + return null; + } + + /** + * Gets the base. + * @return the base + */ + public Location getBase() { + return base; + } + + /** + * Sets the base. + * @param base the base to set. + */ + public void setBase(Location base) { + this.base = base; + } + + /** + * Gets the player. + * @return the player + */ + public Player getPlayer() { + return player; + } + + /** + * Gets the maze. + * @return the maze + */ + public Maze getMaze() { + return maze; + } + + /** + * Sets the maze. + * @param maze the maze to set. + */ + public void setMaze(Maze maze) { + this.maze = maze; + } + + /** + * Gets the solved. + * @return the solved + */ + public int getSolved() { + return solved; + } + + /** + * Sets the solved. + * @param solved the solved to set. + */ + public void setSolved(int solved) { + this.solved = solved; + } + + /** + * A maze. + * @author Vexia + */ + public enum Maze { + FIRST(new Location(8, 54, 0), new Location(15, 41, 0), new Location(8, 39, 0), new Location(19, 50, 0), new Location(15, 45, 0), new int[] { 51, 40, 9, 20 }), // http://puu.sh/cbh82/a0f9f3d206.png + SECOND(new Location(34, 49, 1), new Location(22, 53, 1), new Location(26, 48, 1), new Location(13, 44, 1), new Location(17, 48, 1), new int[] { 54, 43, 12, 23 }), // http://puu.sh/cbgzG/ab25358b4c.png + THIRD(new Location(54, 34, 1), new Location(48, 22, 1), new Location(45, 15, 1), new Location(57, 22, 1), new Location(53, 17, 1), new int[] { 23, 12, 47, 58 }), // http://puu.sh/cbgRX/d229c6129b.png + + FOURTH(new Location(50, 42, 1), new Location(46, 49, 1), new Location(57, 41, 1), new Location(55, 49, 1), new Location(50, 53, 1), new int[] { 59, 48, 45, 56 }), // http://puu.sh/cbgMW/7bd91b0ed1.png + FITH(new Location(46, 32, 0), new Location(45, 14, 0), new Location(45, 23, 0), new Location(47, 18, 0), new Location(45, 13, 0), new int[] { 19, 8, 40, 51 }), // http://puu.sh/cbhuc/83da140de5.png + + SIXTH(new Location(26, 26, 0), new Location(15, 16, 0), new Location(23, 24, 0), new Location(14, 20, 0), new Location(14, 15, 0), new int[] { 21, 10, 9, 10 }), // http://puu.sh/cbgHl/cb55b8011e.png + SEVENTH(new Location(51, 52, 0), new Location(40, 48, 0), new Location(55, 50, 0), new Location(39, 56, 0), new Location(43, 51, 0), new int[] { 57, 46, 37, 48 }), // http://puu.sh/cbgXl/73a9311a76.png + EIGTH(new Location(31, 37, 2), new Location(18, 54, 2), new Location(28, 41, 2), new Location(17, 54, 2), new Location(19, 49, 2), new int[] { 55, 44, 14, 25 }), // http://puu.sh/cbgAV/a2f71c6279.png + NINTH(new Location(40, 16, 2), new Location(20, 10, 2), new Location(34, 15, 2), new Location(11, 19, 2), new Location(16, 14, 2), new int[] { 20, 9, 10, 21 }), // http://puu.sh/cbhbR/59a1477b0c.png + TENTH(new Location(27, 29, 1), new Location(23, 20, 1), new Location(31, 25, 1), new Location(25, 16, 1), new Location(23, 20, 1), new int[] { 26, 15, 17, 28 });// http://puu.sh/cbh58/1cd226cbc0.png + + /** + * The location base of where to start. + */ + private final Location base; + + /** + * The start location of the statue. + */ + private final Location statueLocation; + + /** + * The guardian location. + */ + private final Location guardianLocation; + + /** + * The ending location. + */ + private final Location endLocation; + + /** + * The location camera. + */ + private final Location cameraLocation; + + /** + * The data used to create movements. + */ + private final int[] data; + + /** + * Constructs a new {@code Maze} {@code Object} + * @param base the base. + * @param statueLocation the statue location. + * @param guardianLocation the guardian location. + * @param endLocation the end location. + * @param cameraLocation the camera location. + */ + private Maze(Location base, Location statueLocation, Location guardianLocation, Location endLocation, Location cameraLocation, int[] data) { + this.base = base; + this.statueLocation = statueLocation; + this.guardianLocation = guardianLocation; + this.endLocation = endLocation; + this.cameraLocation = cameraLocation; + this.data = data; + } + + /** + * Gets the base. + * @return the base + */ + public Location getBase() { + return base; + } + + /** + * Gets the statueLocation. + * @return the statueLocation + */ + public Location getStatueLocation() { + return statueLocation; + } + + /** + * Gets the guardianLocation. + * @return the guardianLocation + */ + public Location getGuardianLocation() { + return guardianLocation; + } + + /** + * Gets the endLocation. + * @return the endLocation + */ + public Location getEndLocation() { + return endLocation; + } + + /** + * Gets the cameraLocation. + * @return the cameraLocation + */ + public Location getCameraLocation() { + return cameraLocation; + } + + /** + * Gets the data. + * @return the data + */ + public int[] getData() { + return data; + } + + } + +} diff --git a/Server/src/main/content/minigame/pestcontrol/OutpostSquireDialogue.java b/Server/src/main/content/minigame/pestcontrol/OutpostSquireDialogue.java new file mode 100644 index 0000000..b6d2e5b --- /dev/null +++ b/Server/src/main/content/minigame/pestcontrol/OutpostSquireDialogue.java @@ -0,0 +1,222 @@ +package content.minigame.pestcontrol; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the outpost squire dialogue. + * @author 'Vexia + */ +@Initializable +public final class OutpostSquireDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code OutpostSquireDialogue} {@code Object}. + */ + public OutpostSquireDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code OutpostSquireDialogue} {@code Object}. + * @param player tge player. + */ + public OutpostSquireDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new OutpostSquireDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + npc("Hi, how can I help you?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + options("Who are you?", "What is this place?", "I'm fine thanks."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + player("Who are you?"); + stage = 10; + break; + case 2: + player("What is this place?"); + stage = 20; + break; + case 3: + player("I'm fine thanks."); + stage = 30; + break; + } + break; + case 10: + npc("I'm a a Squire for the Void Knights."); + stage = 5; + break; + case 5: + player("The who?"); + stage = 6; + break; + case 6: + npc("The Void Knights, they are great warriors of balance", "who do Guthix's work here in Gielinor."); + stage = 11; + break; + case 11: + options("Wow, can I join?", "What kind of work?", "What's 'Gielinor'?", "Uh huh, sure."); + stage = 12; + break; + case 12: + switch (buttonId) { + case 1: + player("Wow, can I join?"); + stage = 180; + break; + case 2: + player("What kind of work?"); + stage = 17; + break; + case 3: + player("What's 'Gielinor'?"); + stage = 15; + break; + case 4: + player("Uh huh, sure."); + stage = 14; + break; + } + break; + case 14: + end(); + break; + case 15: + npc("It is the name that Guthix gave to this world, so we", "honour him with its use."); + stage = 16; + break; + case 16: + end(); + break; + case 17: + npc("Ah well you see we try to keep Gielinor as Guthix", "intended, it's very challenging. Actually we've been", "having some problems recently, maybe you could help", "us?"); + stage = 18; + break; + case 18: + options("Yeah OK, what's the problem?", "What's 'Gielinor'?", "I'd rather not, sorry."); + stage = 19; + break; + case 19: + switch (buttonId) { + case 1: + player("Yeah ok, what's the problem?"); + stage = 191; + break; + case 2: + player("What's 'Gielinor'?"); + stage = 15; + break; + case 3: + player("I'd rather not sorry."); + stage = 190; + break; + } + break; + case 180: + npc("Entry is strictly invite only, however we do need help", "continuing Guthix's work."); + stage = 181; + break; + case 181: + player("What kind of work?"); + stage = 17; + break; + case 190: + end(); + break; + case 191: + npc("Well the order has become quite diminished over the", "years, it's a very long process to learn the skills of a", "Void Knight. Recently there have been breaches into", "our realm from somewhere else, and strange creatures"); + stage = 192; + break; + case 192: + npc("have been pouring through. We can't let that happen,", "and we'd be very grateful if you'd help us."); + stage = 193; + break; + case 193: + options("How can I help?", "Sorry, but I can't."); + stage = 194; + break; + case 194: + switch (buttonId) { + case 1: + player("How can I help?"); + stage = 195; + break; + case 2: + player("Sorry, but I can't."); + stage = 190; + break; + } + break; + case 195: + npc("We send launchers from our outpost to the nearby", "islands. If you go and wait in the lander there that'd", "really help."); + stage = 196; + break; + case 196: + end(); + break; + case 20: + npc("This is our outpost. From here we send launchers out to", "the nearby islands to beat back the invaders."); + stage = 21; + break; + case 21: + options("What invaders?", "How can I help?", "Good luck with that."); + stage = 22; + break; + case 22: + switch (buttonId) { + case 1: + player("What invaders?"); + stage = 24; + break; + case 2: + player("How can I help?"); + stage = 195; + break; + case 3: + player("Good luck with that."); + stage = 23; + break; + } + break; + case 23: + end(); + break; + case 24: + npc("Recently there have been breaches into our realm from", "somewhere else, and strange creatures have been", "pouring through. We can't let that happen, and we'd be", "very grateful if you'd help us."); + stage = 193; + break; + case 30: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 3791, 3792, 3793, 3801 }; + } +} diff --git a/Server/src/main/content/minigame/pestcontrol/PCIslandZone.java b/Server/src/main/content/minigame/pestcontrol/PCIslandZone.java new file mode 100644 index 0000000..42cc517 --- /dev/null +++ b/Server/src/main/content/minigame/pestcontrol/PCIslandZone.java @@ -0,0 +1,36 @@ +package content.minigame.pestcontrol; + +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneRestriction; + +/** + * The Pest control island map zone extension. + * @author Emperor + */ +public final class PCIslandZone extends MapZone { + + /** + * Constructs a new {@code PCIslandZone} {@code Object}. + */ + public PCIslandZone() { + super("pest control island", true, ZoneRestriction.CANNON, ZoneRestriction.FIRES, ZoneRestriction.RANDOM_EVENTS); + } + + @Override + public boolean death(Entity e, Entity killer) { + if (e instanceof Player) { // Ensure players can't die on the island. + + e.getProperties().setTeleportLocation(e.getLocation()); + return true; + } + return false; + } + + @Override + public void configure() { + registerRegion(10537); + } + +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/pestcontrol/PCLanderZone.java b/Server/src/main/content/minigame/pestcontrol/PCLanderZone.java new file mode 100644 index 0000000..21cc7fc --- /dev/null +++ b/Server/src/main/content/minigame/pestcontrol/PCLanderZone.java @@ -0,0 +1,103 @@ +package content.minigame.pestcontrol; + +import core.game.interaction.Option; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneRestriction; + +/** + * The pest control lander zone handler. + * @author Emperor + */ +public final class PCLanderZone extends MapZone { + + /** + * The activities. + */ + private PestControlActivityPlugin[] activities; + + /** + * Constructs a new {@code PCLanderZone} {@code Object}. + * @param activities The activities. + */ + public PCLanderZone(PestControlActivityPlugin[] activities) { + super("pest control lander", true, ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.FIRES, ZoneRestriction.FOLLOWERS, ZoneRestriction.CANNON); + this.activities = activities; + } + + @Override + public boolean interact(Entity e, Node target, Option option) { + if (target instanceof Scenery) { + Scenery o = (Scenery) target; + switch (o.getId()) { + case 14314: // Novice exit ladder + if (activities[0].getWaitingPlayers().contains(e)) { + activities[0].getWaitingPlayers().remove(e); + e.getProperties().setTeleportLocation(activities[0].getLeaveLocation()); + } + return true; + case 25629: // Intermediate exit ladder + if (activities[1].getWaitingPlayers().contains(e)) { + activities[1].getWaitingPlayers().remove(e); + e.getProperties().setTeleportLocation(activities[1].getLeaveLocation()); + } + return true; + case 25630: // Veteran exit ladder + if (activities[2].getWaitingPlayers().contains(e)) { + activities[2].getWaitingPlayers().remove(e); + e.getProperties().setTeleportLocation(activities[2].getLeaveLocation()); + } + return true; + } + } + return false; + } + + @Override + public boolean teleport(Entity e, int type, Node node) { + if (e instanceof Player && type != -1) { + for (PestControlActivityPlugin a : activities) { + if (a.getWaitingPlayers().contains(e)) { + ((Player) e).getPacketDispatch().sendMessage("The knights don't appreciate you teleporting off their craft!"); + return false; + } + } + } + return super.teleport(e, type, node); + } + + @Override + public boolean leave(Entity e, boolean logout) { + if (e instanceof Player) { + Player p = (Player) e; + if (p.getInterfaceManager().getComponent(407) != null) { + p.getInterfaceManager().closeOverlay(); + } + for (PestControlActivityPlugin a : activities) { + if (a.getWaitingPlayers().remove(e)) { + if (logout) { + e.getProperties().setTeleportLocation(a.getLeaveLocation()); + } + break; + } + } + } + return super.leave(e, logout); + } + + @Override + public void configure() { + ZoneBorders boatA = new ZoneBorders(2659, 2637, 2664, 2664); + ZoneBorders boatB = new ZoneBorders(2637, 2641, 2642, 2648); + ZoneBorders boatC = new ZoneBorders(2631, 2648, 2636, 2655); + + register(boatA); + register(boatB); + register(boatC); + } + +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/pestcontrol/PCObjectHandler.java b/Server/src/main/content/minigame/pestcontrol/PCObjectHandler.java new file mode 100644 index 0000000..741bbc4 --- /dev/null +++ b/Server/src/main/content/minigame/pestcontrol/PCObjectHandler.java @@ -0,0 +1,305 @@ +package content.minigame.pestcontrol; + +import core.cache.def.impl.SceneryDefinition; +import core.game.world.GameWorld; +import core.game.activity.ActivityManager; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.bots.PvMBotsBuilder; +import core.game.node.entity.player.info.Rights; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; + +import java.util.ArrayList; + +/** + * Handles pest control objects. + * @author Sir Kermit & Emperor + */ +public final class PCObjectHandler extends OptionHandler { + + //public boolean pcbotsSpawned = false; + public boolean PCnBotsSpawned = false; + public boolean PCiBotsSpawned = false; + public ArrayList playersJoined = new ArrayList<>(20); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + // Barricades + SceneryDefinition.forId(14227).getHandlers().put("option:repair", this); + SceneryDefinition.forId(14228).getHandlers().put("option:repair", this); + SceneryDefinition.forId(14229).getHandlers().put("option:repair", this); + SceneryDefinition.forId(14230).getHandlers().put("option:repair", this); + SceneryDefinition.forId(14231).getHandlers().put("option:repair", this); + SceneryDefinition.forId(14232).getHandlers().put("option:repair", this); + // Gates + SceneryDefinition.forId(14233).getHandlers().put("option:open", this); + SceneryDefinition.forId(14234).getHandlers().put("option:close", this); + SceneryDefinition.forId(14235).getHandlers().put("option:open", this); + SceneryDefinition.forId(14236).getHandlers().put("option:close", this); + SceneryDefinition.forId(14237).getHandlers().put("option:open", this); + SceneryDefinition.forId(14237).getHandlers().put("option:repair", this); + SceneryDefinition.forId(14238).getHandlers().put("option:close", this); + SceneryDefinition.forId(14238).getHandlers().put("option:repair", this); + SceneryDefinition.forId(14239).getHandlers().put("option:open", this); + SceneryDefinition.forId(14239).getHandlers().put("option:repair", this); + SceneryDefinition.forId(14240).getHandlers().put("option:close", this); + SceneryDefinition.forId(14240).getHandlers().put("option:repair", this); + SceneryDefinition.forId(14241).getHandlers().put("option:open", this); + SceneryDefinition.forId(14241).getHandlers().put("option:repair", this); + SceneryDefinition.forId(14242).getHandlers().put("option:close", this); + SceneryDefinition.forId(14242).getHandlers().put("option:repair", this); + SceneryDefinition.forId(14243).getHandlers().put("option:open", this); + SceneryDefinition.forId(14243).getHandlers().put("option:repair", this); + SceneryDefinition.forId(14244).getHandlers().put("option:close", this); + SceneryDefinition.forId(14244).getHandlers().put("option:repair", this); + SceneryDefinition.forId(14245).getHandlers().put("option:open", this); + SceneryDefinition.forId(14245).getHandlers().put("option:repair", this); + SceneryDefinition.forId(14246).getHandlers().put("option:close", this); + SceneryDefinition.forId(14246).getHandlers().put("option:repair", this); + SceneryDefinition.forId(14247).getHandlers().put("option:open", this); + SceneryDefinition.forId(14247).getHandlers().put("option:repair", this); + SceneryDefinition.forId(14248).getHandlers().put("option:close", this); + SceneryDefinition.forId(14248).getHandlers().put("option:repair", this); + // Towers + SceneryDefinition.forId(14296).getHandlers().put("option:climb", this); + // Lander crossing plank + SceneryDefinition.forId(14315).getHandlers().put("option:cross", this); + SceneryDefinition.forId(25631).getHandlers().put("option:cross", this); + SceneryDefinition.forId(25632).getHandlers().put("option:cross", this); + return this; + } + + /** + * Starts the pest control. + * @param p The player. + * @param name The name of the activity. + * @param destination The destination location (in the lander). + */ + private void startActivity(Player p, String name, Location destination) { + if (ActivityManager.start(p, name, false)) { + p.getPacketDispatch().sendMessage("You board the lander."); + p.getProperties().setTeleportLocation(destination); + } + } + + @Override + public boolean handle(Player player, Node node, String option) { + int pestBotsAmount = 0; + int pestBots2Amount = 0; + Scenery object = (Scenery) node; + if (option.equals("cross")) { + if (player.getFamiliarManager().hasFamiliar() && player.getRights() != Rights.ADMINISTRATOR) { + player.getPacketDispatch().sendMessage("You can't take a follower on the lander."); + return true; + } + switch (object.getId()){ + case 14315: // Novice + if (!GameWorld.getPCnBotsSpawned() && !player.isArtificial()) { //First person to join gets bots to play with + GameWorld.setPCnBotsSpawned(true); + for (pestBotsAmount = 0; pestBotsAmount <= 35; pestBotsAmount++) { + PvMBotsBuilder.createPestControlTestBot(new Location(2657, 2640)); + } + } + if (!playersJoined.contains(player.getUsername()) && !player.isArtificial()) { //You also get +1 bot for every friend + playersJoined.add(player.getUsername()); + } + + startActivity(player, "pest control novice", Location.create(2661, 2639, 0)); + return true; + case 25631: // Intermediate + if (!GameWorld.getPCiBotsSpawned() && !player.isArtificial()) { //First person to join gets bots to play with + GameWorld.setPCiBotsSpawned(true); + for (pestBots2Amount = 0; pestBots2Amount <= 50; pestBots2Amount++ ) { + PvMBotsBuilder.createPestControlTestBot2(new Location(2644, 2644)); + } + } + if (!playersJoined.contains(player.getUsername()) && !player.isArtificial()) { //You also get +1 bot for every friend + playersJoined.add(player.getUsername()); + } + + startActivity(player, "pest control intermediate", Location.create(2640, 2644, 0)); + return true; + case 25632: // Veteran + startActivity(player, "pest control veteran", Location.create(2634, 2653, 0)); + return true; + } + } + PestControlSession session = player.getExtension(PestControlSession.class); + if (session == null) { + return true; + } + if (object.getId() == 14296) { + handleTurretTower(player, session, object); + return true; + } + if (!object.isActive() || !session.getBarricades().contains(object)) { + return true; + } + if (option.equals("repair")) { // Handle barricades + repair(player, session, object, object.getId() - (object.getId() < 14233 ? 3 : 4)); + return true; + } + if (object.getId() > 14232) { + handleGates(player, session, object); + return true; + } + return false; + } + + /** + * Handles a turret tower ladder. + * @param player The player. + * @param session The session. + * @param object The object. + */ + private void handleTurretTower(Player player, PestControlSession session, Scenery object) { + int x = object.getLocation().getLocalX(); + int y = object.getLocation().getLocalY(); + if (x == 45 && y == 41) { + if (player.getLocation().getLocalX() < x + 1) { + player.getProperties().setTeleportLocation(session.getRegion().getBaseLocation().transform(x + 1, 41, 0)); + } else { + player.getProperties().setTeleportLocation(session.getRegion().getBaseLocation().transform(x - 1, 41, 0)); + } + } else if ((x == 42 || x == 23) && y == 26) { + if (player.getLocation().getLocalY() > 25) { + player.getProperties().setTeleportLocation(session.getRegion().getBaseLocation().transform(x, 25, 0)); + } else { + player.getProperties().setTeleportLocation(session.getRegion().getBaseLocation().transform(x, 27, 0)); + } + } else if (x == 20 && y == 41) { + if (player.getLocation().getLocalX() > 19) { + player.getProperties().setTeleportLocation(session.getRegion().getBaseLocation().transform(x - 1, 41, 0)); + } else { + player.getProperties().setTeleportLocation(session.getRegion().getBaseLocation().transform(x + 1, 41, 0)); + } + } + } + + /** + * Repairs an object. + * @param player The player. + * @param session The pest control session. + * @param object The scenery to repair. + * @param newId The repaired object id. + */ + private void repair(Player player, PestControlSession session, Scenery object, int newId) { + if (!player.getInventory().contains(2347, 1)) { + player.getPacketDispatch().sendMessage("You'll need a hammer to make any repairs!"); + return; + } + if (!player.getInventory().remove(new Item(1511, 1))) { + player.getPacketDispatch().sendMessage("You'll need some logs to make any repairs!"); + return; + } + session.addZealGained(player, 5); + player.animate(Animation.create(898)); + if (session.getBarricades().remove(object)) { + Scenery replacement = object.transform(newId, object.getRotation(), getObjectType(newId)); + session.getBarricades().add(replacement); + SceneryBuilder.replace(object, replacement); + } + } + + /** + * Opens the gates. + * @param player The player. + * @param session The pest control session. + * @param object The scenery. + */ + private static void handleGates(Player player, PestControlSession session, Scenery object) { + boolean open = (object.getId() % 2) != 0; + Scenery second = getSecondDoor(object); + if (second == null) { + return; + } + if (object.getId() > 14240 || second.getId() > 14240) { + player.getPacketDispatch().sendMessage("It's too damaged to be moved!"); + return; + } + int rotation = getRotation(object); + int dir = open ? object.getRotation() : rotation; + Direction direction = Direction.get(!open ? dir : ((3 + dir) % 4)); + if (session.getBarricades().contains(object) && session.getBarricades().contains(second)) { + session.getBarricades().remove(object); + session.getBarricades().remove(second); + + Location l = object.getLocation().transform(direction.getStepX(), direction.getStepY(), 0); + Scenery replacement = new Scenery(object.getId() + (open ? 1 : -1), l, 0, open ? rotation : ((direction.toInteger() + 3) % 4)); + SceneryBuilder.replace(object, replacement); + session.getBarricades().add(replacement); + + l = second.getLocation().transform(direction.getStepX(), direction.getStepY(), 0); + replacement = new Scenery(second.getId() + (open ? 1 : -1), l, 0, open ? getRotation(second) : ((direction.toInteger() + 3) % 4)); + SceneryBuilder.replace(second, replacement); + session.getBarricades().add(replacement); + } + } + + /** + * Gets the rotation for the given object. + * @param object The object. + * @return The rotation. + */ + private static final int getRotation(Scenery object) { + int id = object.getId(); + if (id > 14236) { + id -= 4; + } + switch (id) { + case 14233: + return (object.getRotation() + 1) % 4; + case 14234: + return object.getRotation() % 4; + case 14235: + return (object.getRotation() + 3) % 4; + case 14236: + return (object.getRotation() + 2) % 4; + } + return 0; + } + + /** + * Gets the second door. + * @param object The first door object. + * @return The second door object. + */ + public static Scenery getSecondDoor(Scenery object) { + Location l = object.getLocation(); + Scenery o = null; + if ((o = RegionManager.getObject(l.transform(-1, 0, 0))) != null && o.getName().equals(object.getName())) { + return o; + } + if ((o = RegionManager.getObject(l.transform(1, 0, 0))) != null && o.getName().equals(object.getName())) { + return o; + } + if ((o = RegionManager.getObject(l.transform(0, -1, 0))) != null && o.getName().equals(object.getName())) { + return o; + } + if ((o = RegionManager.getObject(l.transform(0, 1, 0))) != null && o.getName().equals(object.getName())) { + return o; + } + return null; + } + + /** + * Gets the object type for the given object id. + * @param objectId The object id. + * @return The object type. + */ + private static int getObjectType(int objectId) { + if (objectId == 14225 || objectId == 14226 || objectId == 14228 || objectId == 14229) { + return 9; + } + return 0; + } + +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/pestcontrol/PCPortalNPC.java b/Server/src/main/content/minigame/pestcontrol/PCPortalNPC.java new file mode 100644 index 0000000..0bddb9a --- /dev/null +++ b/Server/src/main/content/minigame/pestcontrol/PCPortalNPC.java @@ -0,0 +1,338 @@ +package content.minigame.pestcontrol; + +import java.util.Random; + +import content.minigame.pestcontrol.monsters.PCRavagerNPC; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.RegionPlane; +import core.game.world.update.flag.context.Animation; +import core.tools.RandomFunction; +import content.minigame.pestcontrol.monsters.PCRavagerNPC; +import content.minigame.pestcontrol.monsters.PCSpinnerNPC; + +/** + * Handles the portal NPC. + * @author Emperor + */ +public final class PCPortalNPC extends AbstractNPC { + + /** + * The splatter NPCs. + */ + private static final int[][] SPLATTERS = { + { 3727, 3728, 3729 }, // Novice + { 3728, 3729, 3730 }, // Intermediate + { 3729, 3730, 3731 }, // Veteran + }; + + /** + * The shifter NPCs. + */ + private static final int[][] SHIFTERS = { + { 3732, 3733, 3734, 3735, 3736, 3737 }, // Novice + { 3734, 3735, 3736, 3737, 3738, 3739 }, // Intermediate + { 3736, 3737, 3738, 3739, 3740, 3741 }, // Veteran + }; + + /** + * The ravager NPCs. + */ + private static final int[][] RAVAGERS = { + { 3742, 3743, 3744 }, // Novice + { 3743, 3744, 3745 }, // Intermediate + { 3744, 3745, 3746 }, // Veteran + }; + + /** + * The spinner NPCs. + */ + private static final int[][] SPINNERS = { + { 3747, 3748, 3749 }, // Novice + { 3748, 3749, 3750 }, // Intermediate + { 3749, 3750, 3751 }, // Veteran + }; + + /** + * The torcher NPCs. + */ + private static final int[][] TORCHERS = { + { 3752, 3753, 3754, 3755, 3756, 3757 }, // Novice + { 3754, 3755, 3756, 3757, 3758, 3759 }, // Intermediate + { 3756, 3757, 3758, 3759, 3760, 3761 }, // Veteran + }; + + /** + * The defiler NPCs. + */ + private static final int[][] DEFILERS = { + { 3762, 3763, 3764, 3765, 3766, 3767 }, // Novice + { 3764, 3765, 3766, 3767, 3768, 3769 }, // Intermediate + { 3766, 3767, 3768, 3769, 3770, 3771 }, // Veteran + }; + + /** + * The brawler NPCs. + */ + private static final int[][] BRAWLERS = { + { 3772, 3773, 3774 }, // Novice + { 3773, 3774, 3775 }, // Intermediate + { 3774, 3775, 3776 }, // Veteran + }; + + /** + * If the lifepoints should be updated. + */ + public boolean updateLifepoints = true; + + /** + * The pest control session. + */ + private PestControlSession session; + + /** + * The spinners. + */ + private PCSpinnerNPC[] spinners = new PCSpinnerNPC[3]; + + /** + * The brawlers. + */ + private NPC[] brawlers = new NPC[2]; + + /** + * The portal ids? + */ + final static Integer[] portalIds = new Integer[] { + 6142, 6143, 6144, 6145, 6146, 6147, 6148, 6149, + 6150, 6151, 6152, 6153, 6154, 6155, 6156, 6157, + 7551, 7552, 7553, 7554, 7555, 7556, 7557, 7558 + }; + + /** + * Constructs a new {@code PCPortalNPC} {@code Object}. + */ + public PCPortalNPC() { + this(6142, null); + } + + /** + * Constructs a new {@code PCPortalNPC} {@code Object}. + * @param id The NPC id. + * @param l The location. + */ + public PCPortalNPC(int id, Location l) { + super(id, l); + } + + @Override + public void init() { + super.setWalks(false); + super.setRespawn(false); + super.getProperties().setRetaliating(false); + super.init(); + getProperties().setAttackAnimation(Animation.create(-1)); + getProperties().setDefenceAnimation(Animation.create(-1)); + getProperties().setDeathAnimation(Animation.create(-1)); + session = getExtension(PestControlSession.class); + } + + @Override + public void tick() { + super.tick(); + if (session != null) { + RegionPlane plane = getViewport().getCurrentPlane(); + if (plane != null && session.getTicks() % 35 - plane.getPlayers().size() == 0 && plane.getNpcs().size() < 100) { + spawnNPCs(); + } + if (updateLifepoints && session.getTicks() % 10 == 0) { + String color = getSkills().getLifepoints() > 50 ? "" : ""; + session.sendString(color + getSkills().getLifepoints(), 13 + getPortalIndex()); + updateLifepoints = false; + } + } + } + + @Override + public boolean shouldPreventStacking(Entity mover) { + return true; + } + + @Override + public void onImpact(final Entity entity, BattleState state) { + updateLifepoints = true; + super.onImpact(entity, state); + if (session != null && state != null && entity instanceof Player) { + int total = 0; + if (state.getEstimatedHit() > 0) { + total += state.getEstimatedHit(); + } + if (state.getSecondaryHit() > 0) { + total += state.getSecondaryHit(); + } + session.addZealGained((Player) entity, total); + } + } + + /** + * Spawns the NPCs. + */ + public void spawnNPCs() { + Direction dir = Direction.getLogicalDirection(getLocation(), session.getSquire().getLocation()); + int index = getDifficultyIndex(); + Random r = RandomFunction.RANDOM; + int amount = index + 1; + if (getViewport().getCurrentPlane() != null) { + amount += getViewport().getCurrentPlane().getPlayers().size() / 10; + } + if (getDifficultyIndex() == 0) { + amount += ((getDifficultyIndex() + 1) * 3) / 2; + } + for (int i = 0; i < amount; i++) { + int[] ids = SHIFTERS[index]; + switch (r.nextInt(7)) { + case 0: + ids = SPLATTERS[index]; + break; + case 1: + ids = SHIFTERS[index]; + break; + case 2: + ids = RAVAGERS[index]; + break; + case 3: + boolean spawn = false; + for (PCSpinnerNPC npc : spinners) { + if (npc == null || !npc.isActive()) { + spawn = true; + break; + } + } + if (spawn) { + ids = SPINNERS[index]; + } else { + ids = TORCHERS[index]; + } + break; + case 4: + ids = TORCHERS[index]; + break; + case 5: + ids = DEFILERS[index]; + break; + case 6: + spawn = false; + for (NPC npc : brawlers) { + if (npc == null || !npc.isActive()) { + spawn = true; + break; + } + } + if (spawn) { + ids = BRAWLERS[index]; + } else { + ids = DEFILERS[index]; + } + break; + } + int x = dir.getStepX() * 3; + int y = dir.getStepY() * 3; + if (x == 0) { + x = i; + } else { + y = i; + } + NPC n = session.addNPC(NPC.create(ids[r.nextInt(ids.length)], getLocation().transform(x, y, 0))); + if (ids == RAVAGERS[index]) { + ((PCRavagerNPC) n).setPortalIndex(getPortalIndex()); + } else if (ids == SPINNERS[index]) { + for (int j = 0; j < spinners.length; j++) { + if (spinners[j] == null || !spinners[j].isActive()) { + spinners[j] = ((PCSpinnerNPC) n).setPortalIndex(getPortalIndex()); + break; + } + } + } + n.setWalks(true); + n.setRespawn(false); + } + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new PCPortalNPC(id, location); + } + + @Override + public void finalizeDeath(Entity killer) { + super.finalizeDeath(killer); + if (session != null) { + int value = 0; + boolean endSession = true; + for (int i = 0; i < 4; i++) { + if (!session.getPortals()[i].isActive()) { + value |= 1 << i; + } else { + endSession = false; + } + } + if (value > 0) { + session.sendConfig(value << 28); + if (endSession) { + session.getActivity().end(session, true); + return; + } + } + for (PCSpinnerNPC npc : spinners) { + if (npc != null && npc.isActive()) { + npc.explode(); + } + } + session.sendString("0", 13 + getPortalIndex()); + session.getSquire().getSkills().heal(50); + ((PCSquireNPC) session.getSquire()).FlagInterfaceUpdate(); + } + } + + @Override + public int[] getIds() { + return new int[] { + 6142, 6143, 6144, 6145, 6146, 6147, 6148, 6149, + 6150, 6151, 6152, 6153, 6154, 6155, 6156, 6157, + 7551, 7552, 7553, 7554, 7555, 7556, 7557, 7558 + }; + } + + /** + * The difficulty index. + * @return The index. + */ + public int getDifficultyIndex() { + if (getId() > 7550) { + return 2; + } + if (getId() > 6149) { + return 1; + } + return 0; + } + + /** + * The portal index. + * @return The index. + */ + public int getPortalIndex() { + if (getId() > 7550) { + return (getId() - 7551) % 4; + } + if (getId() > 6149) { + return (getId() - 6150) % 4; + } + return (getId() - 6142) % 4; + } +} diff --git a/Server/src/main/content/minigame/pestcontrol/PCSquireNPC.java b/Server/src/main/content/minigame/pestcontrol/PCSquireNPC.java new file mode 100644 index 0000000..14a4eb1 --- /dev/null +++ b/Server/src/main/content/minigame/pestcontrol/PCSquireNPC.java @@ -0,0 +1,100 @@ +package content.minigame.pestcontrol; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.DeathTask; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; + +/** + * Handles the Squire NPC. + * @author Emperor + */ +public final class PCSquireNPC extends AbstractNPC { + + /** + * The pest control session. + */ + private PestControlSession session; + + /** + * If the amount of lifepoints should be updated. + */ + private boolean updateLifepoints; + + /** + * Constructs a new {@code PCSquireNPC} {@code Object}. + */ + public PCSquireNPC() { + super(3782, null, false); + } + + /** + * Constructs a new {@code PCSquireNPC} {@code Object}. + * @param id The npc id. + * @param location The spawn location. + */ + public PCSquireNPC(int id, Location location) { + super(id, location, false); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new PCSquireNPC(id, location); + } + + @Override + public boolean isAttackable(Entity entity, CombatStyle style, boolean message) { + if (DeathTask.isDead(this) || entity instanceof Player) { + return false; + } + return true; + } + + @Override + public void init() { + super.setRespawn(false); + super.getProperties().setRetaliating(false); + super.init(); + super.getProperties().setDefenceAnimation(Animation.create(-1)); + super.getProperties().setDeathAnimation(Animation.create(-1)); + session = getExtension(PestControlSession.class); + } + + @Override + public void finalizeDeath(Entity killer) { + super.finalizeDeath(killer); + } + + @Override + public void tick() { + super.tick(); + if (updateLifepoints && session != null && (session.getTicks() % 10 == 0)) { + if (getSkills().getLifepoints() > 50) { + session.sendString(Integer.toString(getSkills().getLifepoints()), 1); + } else { + session.sendString("" + Integer.toString(getSkills().getLifepoints()), 1); + } + updateLifepoints = false; + } + } + + @Override + public void onImpact(final Entity entity, BattleState state) { + FlagInterfaceUpdate(); + super.onImpact(entity, state); + } + + public void FlagInterfaceUpdate() { + updateLifepoints = true; + } + + @Override + public int[] getIds() { + return new int[] { 3782, 3785 }; + } + +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/pestcontrol/PestControlActivityPlugin.java b/Server/src/main/content/minigame/pestcontrol/PestControlActivityPlugin.java new file mode 100644 index 0000000..f1fb680 --- /dev/null +++ b/Server/src/main/content/minigame/pestcontrol/PestControlActivityPlugin.java @@ -0,0 +1,367 @@ +package content.minigame.pestcontrol; + +import java.util.ArrayList; +import java.util.List; +import java.util.PriorityQueue; + +import content.minigame.pestcontrol.monsters.*; +import core.ServerConstants; +import core.game.component.Component; +import core.game.activity.ActivityManager; +import core.game.activity.ActivityPlugin; +import core.game.interaction.Option; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.impl.PulseManager; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.info.Rights; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.build.DynamicRegion; +import core.game.world.map.zone.RegionZone; +import core.game.world.map.zone.ZoneBuilder; +import core.game.world.map.zone.ZoneRestriction; +import core.plugin.Initializable; +import core.plugin.ClassScanner; +import core.tools.RandomFunction; +import core.tools.StringUtils; + +import static core.api.ContentAPIKt.*; + + +/** + * Handles the Pest Control activity. + * @author Emperor + */ +@Initializable +public final class PestControlActivityPlugin extends ActivityPlugin { + + /** + * The minimum team size. + */ + protected static final int MIN_TEAM_SIZE = 5; //GameWorld.getSettings().isDevMode() ? 1 : 5; + + /** + * The maximum team size. + */ + protected static final int MAX_TEAM_SIZE = 25; + + /** + * The amount of ticks passed. + */ + private int ticks; + + /** + * The boat type. + */ + private final BoatType type; + + /** + * The waiting players. + */ + private final PriorityQueue waitingPlayers = new PriorityQueue(20, (player1, player2) -> { + //get priorities of players. default to 0 + int p1 = player1.getAttribute("pc_prior", 0); + int p2 = player2.getAttribute("pc_prior", 0); + //return in descending order + return p2 - p1; + }); + + /** + * The active game sessions. + */ + private final List sessions = new ArrayList<>(20); + + /** + * The game updating pulse. + */ + private final Pulse pulse = new Pulse(1) { + + @Override + public boolean pulse() { + sessions.removeIf(session -> session != null && session.update()); + ticks++; + if (waitingPlayers.size() >= MAX_TEAM_SIZE && ticks < 475) + { + ticks = 495; + } + if ((ticks < 450 && ticks % 100 == 0) || (ticks % 50 == 0) || ticks == 495) { + for (Player p : waitingPlayers) { + updateTime(p); + } + } + if (ticks >= 500) { + if (waitingPlayers.size() >= MIN_TEAM_SIZE) { + PestControlActivityPlugin.this.start(); + } else { + ticks = 400; + } + } + return false; + } + }; + + /** + * Starts a new pest control session. + */ + public void start() { + PestControlSession session = new PestControlSession(DynamicRegion.create(10536), this); + session.startGame(waitingPlayers); + session.getRegion().getRegionZones().add(new RegionZone(this, session.getRegion().getBorders())); + sessions.add(session); + ticks = 0; + updatePlayerCount(); + } + + /** + * Ends the pest control session. + * @param session The session to end. + * @param success If the mission was successful. + */ + public void end(PestControlSession session, boolean success) { + if (!session.isActive()) { + return; + } + for (final Player p : session.getRegion().getPlanes()[0].getPlayers()) { + p.getProperties().setTeleportLocation(getLeaveLocation()); + if (!success) { + p.getDialogueInterpreter().open(3781, true, 0, true); + // default, + // type, + // default + } else if (success && p.getAttribute("pc_zeal", 0) >= 50) { + int amount = type.ordinal() + 2; + p.getSavedData().getActivityData().increasePestPoints(amount); + Item coins = new Item(995, p.getProperties().getCurrentCombatLevel() * 10); + if (!p.getInventory().add(coins)) { + GroundItemManager.create(coins, p); + } + // default, type, name + p.getDialogueInterpreter().open(3781, true, 1, type.ordinal() == 0 ? "two" : type.ordinal() == 1 ? "three" : "four"); + } else { + // default type, default + p.getDialogueInterpreter().open(3781, true, 2, true); + } + p.removeAttribute("pc_zeal"); + p.removeExtension(PestControlSession.class); + p.fullRestore(); + if (isPoisoned(p)) { + curePoison(p); + } + PulseManager.cancelDeathTask(p); + GameWorld.getPulser().submit(new Pulse(1, p) { + @Override + public boolean pulse() { + p.getSkills().restore(); + return true; + } + }); + } + session.getRegion().getRegionZones().clear(); + session.setActive(false); + } + + /** + * Gets the location the player should teleport to when leaving the game. + * @return {@code + */ + public Location getLeaveLocation() { + switch (type) { + case NOVICE: + return Location.create(2657, 2639, 0); + case INTERMEDIATE: + return Location.create(2644, 2644, 0); + case VETERAN: + return Location.create(2638, 2653, 0); + } + return ServerConstants.HOME_LOCATION; + } + + /** + * Constructs a new {@code PestControlActivityPlugin} {@code Object}. + */ + public PestControlActivityPlugin() { + this(BoatType.NOVICE); + } + + /** + * Constructs a new {@code PestControlActivityPlugin} {@code Object}. + * @param type The boat type. + */ + public PestControlActivityPlugin(BoatType type) { + super("pest control " + type.name().toLowerCase(), false, true, true, ZoneRestriction.CANNON); + this.safeRespawn = Location.create(2657, 2646, 0); + this.type = type; + } + + @Override + public boolean leave(Entity e, boolean logout) { + if (e instanceof Player) { + Player p = (Player) e; + if (!logout) { + p.getInterfaceManager().closeOverlay(); + } else { + e.setLocation(getLeaveLocation()); + e.getProperties().setTeleportLocation(getLeaveLocation()); + } + waitingPlayers.remove(p); + updatePlayerCount(); + } + return super.leave(e, logout); + } + + @Override + public void register() { + if (type == BoatType.NOVICE) { + PestControlActivityPlugin[] activities = new PestControlActivityPlugin[] { this, new PestControlActivityPlugin(BoatType.INTERMEDIATE), new PestControlActivityPlugin(BoatType.VETERAN) }; + ActivityManager.register(activities[1]); + ActivityManager.register(activities[2]); + // Load abstract NPC plugins + ClassScanner.definePlugin(new PCPortalNPC()); + ClassScanner.definePlugin(new PCSquireNPC()); + ClassScanner.definePlugin(new PCTorcherNPC()); + ClassScanner.definePlugin(new PCDefilerNPC()); + ClassScanner.definePlugin(new PCRavagerNPC()); + ClassScanner.definePlugin(new PCShifterNPC()); + ClassScanner.definePlugin(new PCSplatterNPC()); + ClassScanner.definePlugin(new PCSpinnerNPC()); + ClassScanner.definePlugin(new PCBrawlerNPC()); + ClassScanner.definePlugin(new PCObjectHandler()); + ClassScanner.definePlugin(new PestControlSquire()); + ClassScanner.definePlugin(new VoidSealPlugin()); + ZoneBuilder.configure(new PCLanderZone(activities)); + ZoneBuilder.configure(new PCIslandZone()); + } + pulse.start(); + GameWorld.getPulser().submit(pulse); + } + + @Override + public boolean interact(Entity e, Node target, Option option) { + return super.interact(e, target, option); + } + + @Override + public boolean start(Player p, boolean login, Object... args) { + if (p.getProperties().getCurrentCombatLevel() < type.getRequirement() && p.getRights() != Rights.ADMINISTRATOR) { + p.getPacketDispatch().sendMessage("You need a combat level of " + type.getRequirement() + " or higher to board this lander."); + return false; + } + waitingPlayers.add(p); + openLanderInterface(p); + return true; + } + + /** + * Updates the lander interface. + * @param p The player. + */ + public void openLanderInterface(Player p) { + p.getInterfaceManager().openOverlay(new Component(407)); + updateTime(p); + updatePlayerCount(); + p.getPacketDispatch().sendString("Points: " + p.getSavedData().getActivityData().getPestPoints(), 407, 16); + p.getPacketDispatch().sendString(StringUtils.formatDisplayName(type.name()), 407, 3); + } + + /** + * Updates the current time left. + * @param p The player. + */ + public void updateTime(Player p) { + int ticks = 500 - this.ticks; + if (ticks > 99) { + p.getPacketDispatch().sendString("Next Departure: " + (ticks / 100) + " min", 407, 13); + } else if (ticks > 50) { + p.getPacketDispatch().sendString("Next Departure: 1 min", 407, 13); + } else { + p.getPacketDispatch().sendString("Next Departure: 30 seconds", 407, 13); + } + } + + /** + * Updates the player count for all players in the lander. + */ + public void updatePlayerCount() { + for (Player p : waitingPlayers) { + p.getPacketDispatch().sendString("Players Ready: " + waitingPlayers.size(), 407, 14); + } + } + + @Override + public boolean death(Entity e, Entity killer) { + if (e instanceof Player && e.getViewport().getRegion().getRegionId() == 10536) { + PestControlSession session = e.getExtension(PestControlSession.class); + if (session != null) { + Location l = session.getRegion().getBaseLocation(); + e.getProperties().setTeleportLocation(l.transform(32 + RandomFunction.RANDOM.nextInt(4), 49 + RandomFunction.RANDOM.nextInt(6), 0)); + return true; + } + } + return super.death(e, killer); + } + + @Override + public ActivityPlugin newInstance(Player p) throws Throwable { + return this; + } + + @Override + public Location getSpawnLocation() { + return ServerConstants.HOME_LOCATION; + } + + @Override + public void configure() { + registerRegion(10536); + } + + /** + * Gets the list of waiting players. + * @return The list of waiting players. + */ + public PriorityQueue getWaitingPlayers() { + return waitingPlayers; + } + + /** + * Gets the boat type. + * @return The boat type. + */ + public BoatType getType() { + return type; + } + + /** + * The boat types. + * @author Emperor + */ + public static enum BoatType { + + NOVICE(40), INTERMEDIATE(70), VETERAN(100); + + /** + * The combat level requirement. + */ + private final int requirement; + + /** + * Constructs a new {@code BoatType} {@code Object}. + * @param requirement The combat level requirement. + */ + BoatType(int requirement) { + this.requirement = requirement; + } + + /** + * Gets the requirement. + * @return The requirement. + */ + public int getRequirement() { + return requirement; + } + } +} diff --git a/Server/src/main/content/minigame/pestcontrol/PestControlHelper.kt b/Server/src/main/content/minigame/pestcontrol/PestControlHelper.kt new file mode 100644 index 0000000..82c17b0 --- /dev/null +++ b/Server/src/main/content/minigame/pestcontrol/PestControlHelper.kt @@ -0,0 +1,72 @@ +package content.minigame.pestcontrol + +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import content.minigame.pestcontrol.bots.PestControlTestBot +import content.minigame.pestcontrol.bots.PestControlTestBot2 +import kotlin.random.Random + + +object PestControlHelper { + var GATE_ENTRIES = listOf(14233, 14235) + var Portals_AttackableN = listOf(6142, 6143, 6144, 6145).toMutableList() + var Portals_AttackableI = listOf(6150, 6151, 6152, 6153).toMutableList() + var Portals_AttackableV = listOf(7551, 7552, 7553, 7554).toMutableList() + val portalIds = arrayOf( + 6142, 6143, 6144, 6145, 6146, 6147, 6148, 6149, + 6150, 6151, 6152, 6153, 6154, 6155, 6156, 6157, + 7551, 7552, 7553, 7554, 7555, 7556, 7557, 7558) + var PORTAL_ENTRIES = listOf(*portalIds) + val PestControlLanderIntermediate = Location.create(2644, 2646, 0) + val PestControlLanderNovice = Location.create(2657, 2642, 0) + val PestControlIslandLocation = Location.create(2659, 2676, 0) + val PestControlIslandLocation2 = Location.create(2659, 2676, 0) + + var pclocations = + if (Random.nextBoolean()){ Location.create(2667, 2653,0) + }else if (Random.nextBoolean()){ Location.create(2658, 2654, 0) + }else if (Random.nextBoolean()){ Location.create(2651, 2659, 0) + }else if(Random.nextBoolean()){ Location.create(2650, 2664,0) + }else{ Location.create(2665, 2660, 0) } + + ////////////Begin functions/////////////// + fun isInPestControlInstance(p: Player): Boolean { + return p.getAttribute("pc_zeal") != null + } + + enum class BoatInfo(val boatBorder: ZoneBorders, val outsideBoatBorder: ZoneBorders, val ladderId: Int) { + NOVICE(ZoneBorders(2660, 2638, 2663, 2643), ZoneBorders(2658, 2635, 2656, 2646), 14315), + INTERMEDIATE(ZoneBorders(2638, 2642, 2641, 2647), ZoneBorders(2645, 2639, 2643, 2652), 25631), + VETERAN(ZoneBorders(2632, 2649, 2635, 2654), ZoneBorders(2638, 2652, 2638, 2655), 25632); + } + + fun landerContainsLoc(l: Location?): Boolean { + for (i in BoatInfo.values()) if (i.boatBorder.insideBorder(l)) return true + return false + } + + fun outsideGangplankContainsLoc(l: Location?): Boolean { + for (i in BoatInfo.values()) if (i.outsideBoatBorder.insideBorder(l)) return true + return false + } + + fun landerContainsLoc2(l: Location?): Boolean { + for (n in BoatInfo.values()) if (n.boatBorder.insideBorder(l)) return true + return false + } + + fun outsideGangplankContainsLoc2(l: Location?): Boolean { + for (n in BoatInfo.values()) if (n.outsideBoatBorder.insideBorder(l)) return true + return false + } + + fun getMyPestControlSession1(p: PestControlTestBot): PestControlSession? { + return p.getExtension(PestControlSession::class.java) + } + + fun getMyPestControlSession2(p: PestControlTestBot2): PestControlSession? { + return p.getExtension(PestControlSession::class.java) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/pestcontrol/PestControlSession.java b/Server/src/main/content/minigame/pestcontrol/PestControlSession.java new file mode 100644 index 0000000..8396f97 --- /dev/null +++ b/Server/src/main/content/minigame/pestcontrol/PestControlSession.java @@ -0,0 +1,389 @@ +package content.minigame.pestcontrol; + +import java.util.*; + +import core.game.component.Component; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.world.map.Location; +import core.game.world.map.Point; +import core.game.world.map.RegionPlane; +import core.game.world.map.build.DynamicRegion; +import core.tools.RandomFunction; + +import static content.minigame.pestcontrol.PestControlActivityPlugin.MAX_TEAM_SIZE; +import static core.api.ContentAPIKt.*; + +/** + * Represents a pest control session. + * @author Emperor + */ +public final class PestControlSession { + + /** + * The barricade object offsets. + */ + private static final Point[] OBJECT_OFFSETS = { new Point(46, 33), new Point(46, 32), new Point(32, 25), new Point(33, 25), new Point(19, 32), new Point(19, 33), new Point(49, 33), new Point(49, 32), new Point(49, 31), new Point(49, 30), new Point(52, 27), new Point(52, 26), new Point(52, 25), new Point(52, 24), new Point(52, 14), new Point(52, 13), new Point(52, 12), new Point(52, 11), new Point(42, 18), new Point(43, 18), new Point(44, 18), new Point(45, 18), new Point(32, 15), new Point(33, 15), new Point(34, 15), new Point(35, 15), new Point(23, 18), new Point(24, 18), new Point(25, 18), new Point(26, 18), new Point(13, 11), new Point(13, 12), new Point(13, 13), new Point(13, 14), new Point(12, 28), new Point(12, 29), new Point(12, 30), new Point(12, 31), }; + + /** + * The object ids of non-attackable barricades/gates. + */ + public static final int[] INVALID_OBJECT_IDS = {14230, 14231, 14232, // Barricades + 14245, 14246, 14247, 14248, // Gates + }; + + /** + * The dynamic region. + */ + private final DynamicRegion region; + + /** + * The activity. + */ + private final PestControlActivityPlugin activity; + + /** + * The barricade & gate objects. + */ + private final List barricades = new ArrayList<>(20); + + /** + * The amount of ticks. + */ + private int ticks; + + /** + * The squire. + */ + private NPC squire; + + /** + * List of attackable portals + */ + private final List aportals = new ArrayList<>(20); + /** + * The portals. + */ + private final NPC[] portals = new NPC[4]; + + /** + * The ids. + */ + private Integer[] ids = new Integer[4]; + + /** + * If the session is active. + */ + private boolean active = true; + + /** + * Constructs a new {@code PestControlSession} {@code Object}. + * @param region The dynamic region. + * @param activity The pest control activity. + */ + public PestControlSession(DynamicRegion region, PestControlActivityPlugin activity) { + this.region = region; + this.activity = activity; + } + + /** + * Updates the session. + * @return {@code True} if the session has finished. + */ + public boolean update() { + if (!region.isActive()) { + return true; + } + if (squire != null && !squire.isActive()) { + activity.end(this, false); + return true; + } + if (ticks % 100 == 0) { + sendString(20 - (ticks / 100) + " min", 0); + } + switch (++ticks) { + case 50: // Drop first portal shield + case 100: // Drop second portal shield + case 150: // Drop third portal shield + case 200: // Drop fourth portal shield + int index = (ticks / 50) -1; + removePortalShield(ids[index]); + return false; + case 20_00: // End game. + activity.end(this, true); + return true; + } + return false; + } + + /** + * Sends a message to all the players in the region. + * @param message The message to send. + */ + public void sendMessage(String message) { + for (Player p : region.getPlanes()[0].getPlayers()) { + if (p.isActive()) { + p.getPacketDispatch().sendMessage(message); + } + } + } + + /** + * Sends a string on the interface to all players in the region. + * @param message The message to send. + * @param child The child id. + */ + public void sendString(String message, int child) { + for (Player p : region.getPlanes()[0].getPlayers()) { + if (p.isActive()) { + p.getPacketDispatch().sendString(message, 408, child); + } + } + } + + /** + * Adds zeal to the player's total amount. + * @param player The player. + * @param zeal The amount of zeal to add. + */ + public void addZealGained(Player player, int zeal) { + int total = zeal + player.getAttribute("pc_zeal", 0); + player.setAttribute("pc_zeal", total); + String col = total > 50 ? "" : ""; + if (total > 350) { + player.getPacketDispatch().sendString(col + "LOTS!", 408, 11); + } else { + player.getPacketDispatch().sendString(col + Integer.toString(total), 408, 11); + } + } + + /** + * Sends a string on the interface to all players in the region. + * @param value The message value to send. + */ + public void sendConfig(int value) { + for (Player p : region.getPlanes()[0].getPlayers()) { + if (p.isActive()) { + setVarp(p, 719, value); + } + } + } + + /** + * Removes a portal shield. + * @param index The index. + */ + public void removePortalShield(int index) { + String message = null; + switch (index) { + case 0: // Western purple portal + message = "The purple, western portal shield has dropped!"; + break; + case 1: // Eastern blue portal + message = "The blue, eastern portal shield has dropped!"; + break; + case 2: // South-eastern yellow portal + message = "The yellow, south-eastern portal shield has dropped!"; + break; + case 3: // South-western red portal + message = "The red, south-western portal shield has dropped!"; + break; + } + for (Player p : region.getPlanes()[0].getPlayers()) { + if (p.isActive()) { + p.getPacketDispatch().sendInterfaceConfig(408, 18 + (index << 1), true); + p.getPacketDispatch().sendMessage(message); + } + } + squire.sendChat(message); + NPC portal = portals[index]; + + portal.reTransform(); + aportals.add(portal); + } + + /** + * Starts a game. + * @param waitingPlayers The list of waiting players. + */ + public void startGame(PriorityQueue waitingPlayers) { + region.flagActive(); + initBarricadesList(); + List list = new ArrayList<>(20); + for (int i = 0; i < 4; i++) { + list.add(i); + } + Collections.shuffle(list, RandomFunction.RANDOM); + region.toggleMulticombat(); + region.setMusicId(588); + ids = list.toArray(new Integer[4]); + int count = 0; + String portalHealth = "" + (activity.getType().ordinal() == 0 ? 200 : 250); + + List remainingPlayers = new ArrayList<>(); + for (Player p = waitingPlayers.poll(); p != null; p = waitingPlayers.poll()) { + if (p.getSession().isActive()) { + if (++count > MAX_TEAM_SIZE) { + remainingPlayers.add(p); + continue; + } + addPlayer(p, portalHealth); + } + } + + for (Player p : remainingPlayers) + { + int priority = p.getAttribute("pc_prior", 0) + 1; + p.getPacketDispatch().sendMessage("You have been given priority level " + priority + " over other players in joining the next"); + p.getPacketDispatch().sendMessage("game."); + p.setAttribute("pc_prior", priority); + waitingPlayers.add(p); + } + + spawnNPCs(); + + } + + /** + * Adds a player to the game session. + * @param p The player. + * @param portalHealth The portal health string. + */ + private void addPlayer(Player p, String portalHealth) { + p.lock(1); + p.setAttribute("pc_zeal", 0); + p.removeAttribute("pc_prior"); + p.addExtension(PestControlSession.class, this); + p.getInterfaceManager().openOverlay(new Component(408)); + p.getPacketDispatch().sendString("200", 408, 1); + for (int i = 0; i < 4; i++) { + p.getPacketDispatch().sendString(portalHealth, 408, 13 + i); + } + Random r = RandomFunction.RANDOM; + Location l = region.getBaseLocation(); + p.getProperties().setTeleportLocation(l.transform(32 + r.nextInt(4), 49 + r.nextInt(6), 0)); + setVarp(p, 1147, 0); + p.getDialogueInterpreter().sendDialogues(3781, FacialExpression.FURIOUS, "You must defend the Void Knight while the portals are", "unsummoned. The ritual takes twenty minutes though,", "so you can help out by destroying them yourselves!", "Now GO GO GO!"); + } + + /** + * Initializes the barricades list. + */ + private void initBarricadesList() { + RegionPlane p = region.getPlanes()[0]; + for (Point point : OBJECT_OFFSETS) { + barricades.add(p.getObjects()[point.getX()][point.getY()]); + } + } + + /** + * Spawns the portals & squire. + */ + private void spawnNPCs() { + Location l = region.getBaseLocation(); + int baseId = 6142; + if (activity.getType().ordinal() == 1) { + baseId = 6150; + } else if (activity.getType().ordinal() == 2) { + baseId = 7551; + } + portals[0] = NPC.create(baseId, l.transform(4, 31, 0)); + portals[1] = NPC.create(baseId + 1, l.transform(56, 28, 0)); + portals[2] = NPC.create(baseId + 2, l.transform(45, 10, 0)); + portals[3] = NPC.create(baseId + 3, l.transform(21, 9, 0)); + addNPC(squire = NPC.create(3782 + (RandomFunction.RANDOM.nextBoolean() ? 3 : 0), l.transform(32, 32, 0))); + for (NPC npc : portals) { + addNPC(npc); + npc.transform(npc.getId() + 4); + } + addNPC(NPC.create(3781, l.transform(30, 47, 0))); + } + + /** + * Adds an NPC. + * @param npc The NPC. + */ + public NPC addNPC(NPC npc) { + npc.addExtension(PestControlSession.class, this); + npc.setAttribute("no-spawn-return", true); + npc.init(); + return npc; + } + + /** + * Gets the ticks elapsed. + * @return The ticks. + */ + public int getTicks() { + return ticks; + } + + /** + * Gets the activity. + * @return The activity. + */ + public PestControlActivityPlugin getActivity() { + return activity; + } + + /** + * Gets the dynamic region. + * @return The region. + */ + public DynamicRegion getRegion() { + return region; + } + + /** + * Gets the squire. + * @return The squire. + */ + public NPC getSquire() { + return squire; + } + + /** + * Gets the portals. + * @return The portals. + */ + public NPC[] getPortals() { + return portals; + } + + /** + * Get portals that can be attacked. + * @return Attackable portals + */ + + public List getAportals() { + return aportals; + } + + + /** + * Gets the active. + * @return The active. + */ + public boolean isActive() { + return active; + } + + /** + * Sets the active. + * @param active The active to set. + */ + public void setActive(boolean active) { + this.active = active; + } + + /** + * Gets the barricades. + * @return The barricades. + */ + public List getBarricades() { + return barricades; + } + +} diff --git a/Server/src/main/content/minigame/pestcontrol/PestControlSquire.java b/Server/src/main/content/minigame/pestcontrol/PestControlSquire.java new file mode 100644 index 0000000..d0e7732 --- /dev/null +++ b/Server/src/main/content/minigame/pestcontrol/PestControlSquire.java @@ -0,0 +1,52 @@ +package content.minigame.pestcontrol; + +import core.cache.def.impl.NPCDefinition; +import content.global.travel.ship.Ships; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Plugin; + +import static core.api.ContentAPIKt.*; + +/** + * Handles a pest control squire's options. + * @author Emperor + */ +public final class PestControlSquire extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + NPCDefinition.forId(3781).getHandlers().put("option:talk-to", this); + NPCDefinition.forId(3781).getHandlers().put("option:leave", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + NPC squire = (NPC) node; + PestControlSession session = squire.getExtension(PestControlSession.class); + switch (option) { + case "talk-to": + if (session == null) { + OptionHandler handler = NPCDefinition.getOptionHandlers().get(option); + handler.handle(player, node, option); + return true; + } else { + player.getDialogueInterpreter().open(3781, ((NPC) node), true); + } + return true; + case "leave": + if (session == null) { + Ships.PEST_TO_PORT_SARIM.sail(player); + playJingle(player, 172); + return true; + } + player.getProperties().setTeleportLocation(session.getActivity().getLeaveLocation()); + return true; + } + return false; + } + +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/pestcontrol/SquireDialogue.java b/Server/src/main/content/minigame/pestcontrol/SquireDialogue.java new file mode 100644 index 0000000..c0e7ca1 --- /dev/null +++ b/Server/src/main/content/minigame/pestcontrol/SquireDialogue.java @@ -0,0 +1,239 @@ +package content.minigame.pestcontrol; + +import content.global.travel.ship.Ships; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +import static core.api.ContentAPIKt.*; + +/** + * Handles the SquireDialogue dialogue. + * @author 'Vexia + */ +@Initializable +public class SquireDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code SquireDialogue.java} {@code Object}. + */ + public SquireDialogue() { + /** + * empty. + */ + } + + public SquireDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new SquireDialogue(player); + } + + @Override + public boolean open(Object... args) { + if (args.length == 3) { + int type = (int) args[1]; + if (type == 0) {// lost + interpreter.sendDialogues(3781, FacialExpression.HALF_GUILTY, "The Void Knight was killed, another of our Order has", "fallen and that Island is lost."); + stage = 110; + } else if (type == 1) {// won and awarded. + String points = (String) args[2]; + interpreter.sendDialogues(3781, FacialExpression.HALF_GUILTY, "Congratulations! You managed to destroy all the portals!", "We've awarded you " + points + " Void Knight Commendation", "points. Please also accept these coins as a reward."); + stage = 100; + } else {// won and not awarded. + interpreter.sendDialogues(3781, FacialExpression.HALF_GUILTY, "Congratulations! You managed to destroy all the portals!", "However, you did not succeed in reaching the required", "amount of damage delt we cannot grant you a reward."); + stage = 101; + } + return true; + } + npc = (NPC) args[0]; + if (args.length == 2) { + npc("Be quick, we're under attack!"); + stage = 699; + return true; + } + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hi, how can I help you?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + if (npc.getId() == 3781) { + interpreter.sendOptions("Select an Option", "I'd like to go back to Port Sarim please.", "I'm fine thanks."); + stage = 500; + return true; + } + interpreter.sendOptions("Select an Option", "Who are you?", "Where does this ship go?", "I'd like to go to your outpost.", "I'm fine thanks."); + stage = 1; + break; + case 500: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, null, "I'd like to go back to Port Sarim please."); + stage = 502; + break; + case 2: + interpreter.sendDialogues(player, null, "I'm fine thanks."); + stage = 501; + break; + } + break; + case 501: + end(); + break; + case 502: + interpreter.sendDialogues(npc, null, "Ok, but please come back soon and help us."); + stage = 503; + break; + case 503: + end(); + Ships.PEST_TO_PORT_SARIM.sail(player); + playJingle(player, 172); + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Who are you?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Where does this ship go?"); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'd like to go to your outpost."); + stage = 30; + break; + case 4: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'm fine thanks."); + stage = 40; + break; + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I'm a Squire for the Void Knights."); + stage = 11; + break; + case 11: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "The who?"); + stage = 12; + break; + case 12: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "The Void Knights, they are great warriors of balance", "who do Guthix's work here in Gielinor."); + stage = 13; + break; + case 13: + end(); + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "To the Void Knight outpost. It's a small island just off", "Karamja."); + stage = 21; + break; + case 21: + interpreter.sendOptions("Select an Option", "I'd like to go to your outpost.", "That's nice."); + stage = 22; + break; + case 22: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'd like to go to your outpost."); + stage = 23; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "That's nice."); + stage = 200; + break; + } + break; + case 23: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Certainly, right this way."); + stage = 24; + break; + case 24: + end(); + Ships.PORT_SARIM_TO_PEST_CONTROL.sail(player); + playJingle(player, 172); + break; + case 200: + end(); + break; + case 30: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Certainly, right this way."); + stage = 24; + break; + case 40: + end(); + break; + case 699: + options("What's going on?", "How do I repair things?", "I want to leave.", "I'd better get back to it then."); + stage = 700; + break; + case 700:// ingame + switch (buttonId) { + case 1: + player("What's going on?"); + stage = 710; + break; + case 2: + player("How do I repair things?"); + stage = 720; + break; + case 3: + player("I want to leave."); + stage = 730; + break; + case 4: + player("I'd better get back to it then."); + stage = 740; + break; + } + break; + case 710: + npc("This island is being invaded by outsiders and the Void", "Knight over there is using a ritual to unsummon their", "portals. We must defend the Void Knight at all costs.", "however if you get an opening you can destroy the portals."); + stage = 711; + break; + case 711: + end(); + break; + case 720: + npc("There are trees on the island. You'll need to chop them", "down for logs and use a hammer to repair the defences.", "Be careful tough, the trees here don't grow back very", "fast so your resources are limited!"); + stage = 721; + break; + case 721: + end(); + break; + case 730: + end(); + break; + case 740: + end(); + break; + case 100: + String RED = ""; + String BLUE = ""; + interpreter.sendDialogue(BLUE + "You now have " + RED + "" + player.getSavedData().getActivityData().getPestPoints() + "" + BLUE + " Void Knight Commendation points!", "You can speak to a Void Knight to exchange your points for", "rewards."); + stage = 101; + break; + case 101: + end(); + break; + case 110: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 3781, 3790 }; + } +} diff --git a/Server/src/main/content/minigame/pestcontrol/SquireMagicDialougue.java b/Server/src/main/content/minigame/pestcontrol/SquireMagicDialougue.java new file mode 100644 index 0000000..7922aad --- /dev/null +++ b/Server/src/main/content/minigame/pestcontrol/SquireMagicDialougue.java @@ -0,0 +1,79 @@ +package content.minigame.pestcontrol; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the magic shop squire owner dialgoue. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class SquireMagicDialougue extends DialoguePlugin { + + /** + * Constructs a new {@code SquireMagicDialougue} {@code Object}. + */ + public SquireMagicDialougue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code SquireMagicDialougue} {@code Object}. + * @param player the player. + */ + public SquireMagicDialougue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new SquireMagicDialougue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + npc("Hi, how can I help you?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + options("What do you have for sale?", "I'm fine thanks."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + end(); + npc.openShop(player); + break; + case 2: + player("I'm fine thanks."); + stage = 20; + break; + } + break; + case 10: + end(); + break; + case 20: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 3796, 3798, 3799 }; + } +} diff --git a/Server/src/main/content/minigame/pestcontrol/SquireTypeDialogue.java b/Server/src/main/content/minigame/pestcontrol/SquireTypeDialogue.java new file mode 100644 index 0000000..d259448 --- /dev/null +++ b/Server/src/main/content/minigame/pestcontrol/SquireTypeDialogue.java @@ -0,0 +1,126 @@ +package content.minigame.pestcontrol; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the different tier of squire dialouges. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class SquireTypeDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code SquireTypeDialogue} {@code Object}. + */ + public SquireTypeDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code SquireTypeDialogue} {@code Object}. + * @param player the player. + */ + public SquireTypeDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new SquireTypeDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + npc("Hi, how can I help you?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + options("Who are you?", "What's going on here?", "I'm fine thanks."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + player("Who are you?"); + stage = 10; + break; + case 2: + player("What's going on here?"); + stage = 20; + break; + case 3: + player("I'm fine thanks."); + stage = 30; + break; + } + break; + case 10: + npc("I'm a squire for the Void Knights."); + stage = 11; + break; + case 11: + player("The who?"); + stage = 12; + break; + case 12: + npc("The Void Knights, they are great warriors of balance", "who do Guthix's work here in Gielinor."); + stage = 13; + break; + case 13: + end(); + break; + case 20: + npc("This is where we launch our landers to combat the", "invasion of the nearby islands. You'll see three landers - ", "one for novice, intermediate and veteran adventurers.", "Each has a different difficulty, but they therefore offer"); + stage = 21; + break; + case 21: + npc("varying rewards."); + stage = 22; + break; + case 22: + player("And this lander is...?"); + stage = 23; + break; + case 23: + npc("The " + (npc.getId() == 3802 ? "novice" : npc.getId() == 6140 ? "intermediate" : "veteran") + "."); + stage = 24; + break; + case 24: + player("So how do they work?"); + stage = 25; + break; + case 25: + npc("Simple. We send each lander out every five minutes,", "however we need at least five volunteers or it's a suicide", "mission. The lander can only hold a maximum of", "twenty five people though, so we do send them out"); + stage = 26; + break; + case 26: + npc("early if they get full. If you'd be willing to help us then", "just wait in the lander and we'll launch it as soon as it's", "ready. However you will need a combat level of " + (npc.getId() == 3802 ? "40" : npc.getId() == 6140 ? "70" : "100") + " to", "use this lander."); + stage = 27; + break; + case 27: + end(); + break; + case 30: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 3802, 6140, 6141 }; + } +} diff --git a/Server/src/main/content/minigame/pestcontrol/VoidSealPlugin.java b/Server/src/main/content/minigame/pestcontrol/VoidSealPlugin.java new file mode 100644 index 0000000..95244ea --- /dev/null +++ b/Server/src/main/content/minigame/pestcontrol/VoidSealPlugin.java @@ -0,0 +1,69 @@ +package content.minigame.pestcontrol; + +import content.minigame.pestcontrol.monsters.*; +import core.cache.def.impl.ItemDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.combat.ImpactHandler.HitsplatType; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Plugin; +import core.tools.RandomFunction; + +/** + * Handles the void knight seal. + * @author Emperor + */ +public final class VoidSealPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (int i = 0; i < 8; i++) { + ItemDefinition.forId(11666 + i).getHandlers().put("option:rub", this); + } + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + if (player.getViewport().getRegion().getRegionId() != 10536) { + player.getPacketDispatch().sendMessage("You can only use the seal in Pest Control."); + return true; + } + boolean operate = option.equals("operate"); + player.lock(1); + Item item = (Item) node; + // TODO: check if the seal is used in inventory or equipment operate. + player.getPacketDispatch().sendMessage("You unleash the power of the Void Knights!"); + Item replace = null; + if (item.getId() != 11673) { + replace = new Item(item.getId() + 1); + } + if (operate) { + player.getEquipment().replace(replace, item.getSlot()); + } else { + player.getInventory().replace(replace, item.getSlot()); + } + player.graphics(Graphics.create(1177)); + for (NPC npc : RegionManager.getLocalNpcs(player, 2)) { + if (canTarget(npc)) { + npc.getImpactHandler().manualHit(player, 7 + RandomFunction.randomize(5), HitsplatType.NORMAL, 1); + npc.graphics(Graphics.create(1176)); + } + } + return true; + } + + /** + * Checks if the NPC can be targeted. + * @param npc The NPC. + * @return {@code True} if so. + */ + private static boolean canTarget(NPC npc) { + return npc instanceof PCDefilerNPC || npc instanceof PCRavagerNPC || npc instanceof PCShifterNPC || npc instanceof PCSpinnerNPC || npc instanceof PCSplatterNPC || npc instanceof PCTorcherNPC || npc instanceof PCBrawlerNPC; + } + +} diff --git a/Server/src/main/content/minigame/pestcontrol/bots/CombatState.kt b/Server/src/main/content/minigame/pestcontrol/bots/CombatState.kt new file mode 100644 index 0000000..dbfb2ee --- /dev/null +++ b/Server/src/main/content/minigame/pestcontrol/bots/CombatState.kt @@ -0,0 +1,118 @@ +package content.minigame.pestcontrol.bots + +import core.game.interaction.MovementPulse +import core.game.node.Node +import core.game.node.entity.npc.NPC +import core.game.world.map.Location +import core.game.world.map.RegionManager +import core.game.world.map.path.Pathfinder +import core.tools.RandomFunction +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch +import content.minigame.pestcontrol.PestControlHelper.GATE_ENTRIES +import content.minigame.pestcontrol.PestControlHelper.getMyPestControlSession1 +import core.game.world.GameWorld +import java.util.* + + +class CombatState(val bot: PestControlTestBot) { + private val Random = Random() + val randomtype = Random().nextInt(100) + + fun goToPortals() { + bot.customState = "I'm at portals." + val gate = bot.getClosestNodeWithEntry(75, GATE_ENTRIES) + val sesh = getMyPestControlSession1(bot) + + var portal: Node? = null + if(sesh != null && sesh.aportals.isNotEmpty()){ + val removeList = ArrayList() + for(port in sesh.aportals){ + if(!port.isActive){ + removeList.add(port) + } else { + portal = port + break + } + } + sesh.aportals.removeAll(removeList) + } + + if(bot.pulseManager.hasPulseRunning() && portal == null){ + return + } + + if (bot.justStartedGame) { + bot.customState = "Walking randomly" + bot.justStartedGame = false + bot.randomWalkAroundPoint(getMyPestControlSession1(bot)?.squire?.location ?: bot.location, 15) + bot.movetimer = Random.nextInt(7) + 6 + return + } + + if (gate != null && sesh?.aportals?.isEmpty() == true) { + bot.customState = "Interacting gate ID " + gate.id + bot.interact(gate) + bot.openedGate = true + if (Random.nextInt(4) == 1 && randomtype < 40) { + bot.movetimer = Random.nextInt(2) + 1 + } + return + } + + if (portal != null) { + if(bot.location.withinDistance(portal.location,10) && portal.isActive){ + val spinners = ArrayList() + RegionManager.getLocalNpcs(bot).forEach { + if(it.name.toLowerCase().equals("spinner") && it.location.withinDistance(bot.location,10)) spinners.add(it) + } + if(spinners.isNotEmpty()){ + bot.attack(spinners.random()) + } else { + bot.attack(portal) + } + } else { + randomWalkTo(portal.location, 5) + } + bot.movetimer = Random().nextInt(10) + 5 + return + } else { + bot.AttackNpcsInRadius(50) + } + + bot.customState = "Absolutely nothing. Everything is dead" + } + + fun fightNPCs() { + bot.customState = "Fight NPCs" + bot.AttackNpcsInRadius(8) + bot.eat(379) + + + if (!bot.inCombat()) { + /*if (bot.combatMoveTimer <= 0) { + if (bot.FindTargets(bot, 30) == null) + bot.combatMoveTimer = 5 + }*/ + } + } + + fun randomWalkTo(loc: Location, radius: Int) { + var newloc = loc.transform(RandomFunction.random(radius, -radius), + RandomFunction.random(radius, -radius), 0) + if(!bot.walkingQueue.isMoving) { + walkToIterator(newloc) + } + } + + private fun walkToIterator(loc: Location){ + var diffX = loc.x - bot.location.x + var diffY = loc.y - bot.location.y + + GameWorld.Pulser.submit(object : MovementPulse(bot, bot.location.transform(diffX, diffY, 0), Pathfinder.SMART) { + override fun pulse(): Boolean { + return true + } + }) + } +} diff --git a/Server/src/main/content/minigame/pestcontrol/bots/CombatStateIntermediate.kt b/Server/src/main/content/minigame/pestcontrol/bots/CombatStateIntermediate.kt new file mode 100644 index 0000000..fbea681 --- /dev/null +++ b/Server/src/main/content/minigame/pestcontrol/bots/CombatStateIntermediate.kt @@ -0,0 +1,118 @@ +package content.minigame.pestcontrol.bots + +import core.game.interaction.MovementPulse +import core.game.node.Node +import core.game.node.entity.npc.NPC +import core.game.world.map.Location +import core.game.world.map.RegionManager +import core.game.world.map.path.Pathfinder +import core.tools.RandomFunction +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch +import content.minigame.pestcontrol.PestControlHelper.GATE_ENTRIES +import content.minigame.pestcontrol.PestControlHelper.getMyPestControlSession2 +import core.game.world.GameWorld +import java.util.* + +class CombatStateIntermediate(val bot: PestControlTestBot2) { + private val Random = Random() + val randomtype = Random().nextInt(100) + + fun goToPortals() { + bot.customState = "I'm at portals." + val gate = bot.getClosestNodeWithEntry(75, GATE_ENTRIES) + val sesh = getMyPestControlSession2(bot) + + var portal: Node? = null + if(sesh != null && sesh.aportals.isNotEmpty()){ + val removeList = ArrayList() + for(port in sesh.aportals){ + if(!port.isActive){ + removeList.add(port) + } else { + portal = port + break + } + } + sesh.aportals.removeAll(removeList) + } + + if(bot.pulseManager.hasPulseRunning() && portal == null){ + return + } + + if (bot.justStartedGame) { + bot.customState = "Walking randomly" + bot.justStartedGame = false + bot.randomWalkAroundPoint(getMyPestControlSession2(bot)?.squire?.location ?: bot.location, 15) + bot.movetimer = Random.nextInt(7) + 6 + return + } + + if (gate != null && sesh?.aportals?.isEmpty() == true) { + bot.customState = "Interacting gate ID " + gate.id + bot.interact(gate) + bot.openedGate = true + if (Random.nextInt(4) == 1 && randomtype < 40) { + bot.movetimer = Random.nextInt(2) + 1 + } + return + } + + if (portal != null) { + if(bot.location.withinDistance(portal.location,10) && portal.isActive){ + val spinners = ArrayList() + RegionManager.getLocalNpcs(bot).forEach { + if(it.name.toLowerCase().equals("spinner") && it.location.withinDistance(bot.location,10)) spinners.add(it) + } + if(spinners.isNotEmpty()){ + bot.attack(spinners.random()) + } else { + bot.attack(portal) + } + } else { + randomWalkTo(portal.location, 5) + } + bot.movetimer = Random().nextInt(10) + 5 + return + } else { + bot.AttackNpcsInRadius(50) + } + + bot.customState = "Absolutely nothing. Everything is dead" + } + + fun fightNPCs() { + bot.customState = "Fight NPCs" + bot.AttackNpcsInRadius(8) + bot.eat(379) + + + if (!bot.inCombat()) { + /*if (bot.combatMoveTimer <= 0) { + if (bot.FindTargets(bot, 30) == null) + bot.combatMoveTimer = 5 + }*/ + } + } + + //Functions + fun randomWalkTo(loc: Location, radius: Int) { + var newloc = loc.transform(RandomFunction.random(radius, -radius), + RandomFunction.random(radius, -radius), 0) + if(!bot.walkingQueue.isMoving) { + walkToIterator(newloc) + } + } + + private fun walkToIterator(loc: Location){ + var diffX = loc.x - bot.location.x + var diffY = loc.y - bot.location.y + + GameWorld.Pulser.submit(object : MovementPulse(bot, bot.location.transform(diffX, diffY, 0), Pathfinder.SMART) { + override fun pulse(): Boolean { + return true + } + }) + } +} diff --git a/Server/src/main/content/minigame/pestcontrol/bots/PestControlIntermediateBot.kt b/Server/src/main/content/minigame/pestcontrol/bots/PestControlIntermediateBot.kt new file mode 100644 index 0000000..c369030 --- /dev/null +++ b/Server/src/main/content/minigame/pestcontrol/bots/PestControlIntermediateBot.kt @@ -0,0 +1,200 @@ +package content.minigame.pestcontrol.bots + +import core.game.world.map.Location +import core.tools.RandomFunction +import core.game.bots.CombatBotAssembler +import core.game.bots.PvMBots +import content.minigame.pestcontrol.PestControlHelper +import java.util.* + +class PestControlTestBot2(l: Location) : PvMBots(legitimizeLocation(l)) { + + var tick = 0 + var combatMoveTimer = 0 + var justStartedGame = true + var movetimer = 0 + var openedGate = false + var myCounter = 0 + val num = Random().nextInt(4) + val myBoat = PestControlHelper.BoatInfo.INTERMEDIATE + val combathandler = CombatStateIntermediate(this) + + var time = 0 + + enum class State { + OUTSIDE_GANGPLANK, + REFRESH, + WAITING_IN_BOAT, + PLAY_GAME, + GET_TO_PC + } + //Novice Lander co-ords (2657, 2639, 0) + //Intermediate lander co-ords (2644, 2644, 0) + //Veteran lander co-ords (2638, 2653 0) + init { + val random100 = Random().nextInt(100) + if (random100 < 30) { + setAttribute("pc_role","defend_squire") + } else + { + setAttribute("pc_role","attack_portals") + this.customState = "Fighting NPCs" + } + if (num <= 2) { + CombatBotAssembler().gearPCiMeleeBot( this) + } else { + CombatBotAssembler().gearPCiRangedBot(this, Random().nextInt() % 2 == 0) + } + } + + + override fun tick() { + super.tick() + tick++ + time++ + movetimer-- + if (movetimer <= 0) { + movetimer = 0 + customState = state.toString() + movetimer + when (state) { + State.GET_TO_PC -> toPC() + State.OUTSIDE_GANGPLANK -> enterBoat() + State.WAITING_IN_BOAT -> idleInBoat() + State.PLAY_GAME -> attackNPCs() + State.REFRESH -> toPC() + } + } + } + + private val state: State + get() { + if (PestControlHelper.landerContainsLoc2(this.getLocation())) { + return State.WAITING_IN_BOAT + } + if (PestControlHelper.isInPestControlInstance(this)) { + return State.PLAY_GAME + } + if (PestControlHelper.outsideGangplankContainsLoc2(this.getLocation())) { + return State.OUTSIDE_GANGPLANK + } + if (time == 1200) { + return State.GET_TO_PC//.also { println("I was stuck ${this.username}") } + } + return State.GET_TO_PC + } + + + private fun attackNPCs() { + if (PestControlHelper.outsideGangplankContainsLoc2(getLocation())){ + content.minigame.pestcontrol.PestControlActivityPlugin().leave(this,false) + val test = getClosestNodeWithEntry(50, myBoat.ladderId) + test ?: println("PC: Gangplank Null") + test.interaction.handle(this, test.interaction[0])//.also { println("Intermediate - We think we is in pest control ${this.username}.") } + } + walkingQueue.isRunning = true + + if (getAttribute("pc_role","E") == "attack_portals") { + combathandler.goToPortals() + } else { + movetimer = RandomFunction.random(2,10) + val location = PestControlHelper.getMyPestControlSession2(this)?.squire?.location ?: location + if(location != null) { + randomWalkAroundPoint(location, 5) + } + combathandler.fightNPCs() + } + } + + private var insideBoatWalks = 3 + fun idleInBoat() { + justStartedGame = true + openedGate = false + time = 0 + if (prayer.active.isNotEmpty()) { + prayer.reset() + } + if (PestControlHelper.outsideGangplankContainsLoc2(getLocation())){ + val test = getClosestNodeWithEntry(15, myBoat.ladderId) + test.interaction.handle(this,test.interaction[0]) + enterBoat()//.also { println("We think we is in boat ${this.username}.") } + } + if (Random().nextInt(100) < 40) { + if (Random().nextInt(insideBoatWalks) <= 1) { + (insideBoatWalks * 1.5).toInt() + + if (Random().nextInt(4) == 1) { + this.walkingQueue.isRunning = !this.walkingQueue.isRunning + } + if (Random().nextInt(7) >= 4) { + this.walkToPosSmart(myBoat.boatBorder.randomLoc) + } + } + if (Random().nextInt(3) == 1) { + insideBoatWalks += 2 + } + } + } + + private fun enterBoat() { + if (PestControlHelper.outsideGangplankContainsLoc2(getLocation())){ + movetimer = Random().nextInt(10) + combathandler.randomWalkTo(PestControlHelper.PestControlLanderIntermediate, 1) + } + if (!prayer.active.isEmpty()) { + prayer.reset() + } + if (Random().nextInt(8) >= 3) + { + val pclocs = Location.create(2652,2646,0) + combathandler.randomWalkTo(pclocs,8) + movetimer = Random().nextInt(180) + 15 + } + if (Random().nextInt(8) >= 2) + { + randomWalk(3,3) + movetimer = Random().nextInt(10) + } + if (Random().nextInt(100) > 50) + { + if (Random().nextInt(10) <= 5) { + this.walkToPosSmart(myBoat.outsideBoatBorder.randomLoc) + movetimer += RandomFunction.normalPlusWeightRandDist(400, 200) + } + movetimer = RandomFunction.normalPlusWeightRandDist(100, 50) + return + } + val test = getClosestNodeWithEntry(15, myBoat.ladderId) + test ?: randomWalk(1,1) + test?.interaction?.handle(this, test.interaction[0]) + insideBoatWalks = 3 + } + + var switch = false + private fun toPC() { + time = 0 + if (!switch) { + this.teleport(PestControlHelper.PestControlLanderIntermediate)//.also { println("I was stuck ${this.username}") } + switch = true + return + } + if (switch) { + val test = getClosestNodeWithEntry(30, myBoat.ladderId) + if (test == null) { + switch = false + this.teleport(PestControlHelper.PestControlLanderIntermediate) + State.OUTSIDE_GANGPLANK + } else { + switch = false + test.interaction.handle(this, test.interaction[0]) + State.OUTSIDE_GANGPLANK + } + } + } + + + companion object { + fun legitimizeLocation(l: Location): Location { + return if (PestControlHelper.landerContainsLoc(l)) Location(2648, 2648, 0) else l + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/pestcontrol/bots/PestControlNoviceBot.kt b/Server/src/main/content/minigame/pestcontrol/bots/PestControlNoviceBot.kt new file mode 100644 index 0000000..6d07a15 --- /dev/null +++ b/Server/src/main/content/minigame/pestcontrol/bots/PestControlNoviceBot.kt @@ -0,0 +1,195 @@ +package content.minigame.pestcontrol.bots + +import core.game.world.map.Location +import core.tools.RandomFunction +import core.game.bots.CombatBotAssembler +import core.game.bots.PvMBots +import content.minigame.pestcontrol.PestControlHelper +import java.util.* + +class PestControlTestBot(l: Location) : PvMBots(legitimizeLocation(l)){ + var tick = 0 + var combatMoveTimer = 0 + var justStartedGame = true + var movetimer = 0 + var openedGate = false + var myCounter = 0 + val num = Random().nextInt(4) + val myBoat = PestControlHelper.BoatInfo.NOVICE + val combathandler = CombatState(this) + + var time = 0 + + enum class State { + REFRESH, + OUTSIDE_GANGPLANK, + WAITING_IN_BOAT, + PLAY_GAME, + GET_TO_PC + } + + //Novice Lander co-ords (2657, 2639, 0) + //Intermediate lander co-ords (2644, 2644, 0) + //Veteran lander co-ords (2638, 2653 0) + init { + val random100 = Random().nextInt(100) + if (random100 < 30) { + setAttribute("pc_role","defend_squire") + } else + { + setAttribute("pc_role","attack_portals") + this.customState = "Fighting NPCs" + } + if (num <= 2) { + CombatBotAssembler().gearPCnMeleeBot(this) + } else { + CombatBotAssembler().gearPCnRangedBot(this, Random().nextInt() % 2 == 0) + } + } + + override fun tick() { + super.tick() + tick++ + time++ + movetimer-- + if (movetimer <= 0) { + movetimer = 0 + customState = state.toString() + movetimer + when (state) { + State.GET_TO_PC -> toPC() + State.OUTSIDE_GANGPLANK -> enterBoat() + State.WAITING_IN_BOAT -> idleInBoat() + State.PLAY_GAME -> attackNPCs() + State.REFRESH -> toPC() + } + } + } + + val state: State + get() { + if (PestControlHelper.landerContainsLoc(this.getLocation())) { + return State.WAITING_IN_BOAT + } + if (PestControlHelper.isInPestControlInstance(this)) { + return State.PLAY_GAME + } + if (PestControlHelper.outsideGangplankContainsLoc(this.getLocation())) { + return State.OUTSIDE_GANGPLANK + } + if (time == 1200) { + return State.GET_TO_PC + } + return State.GET_TO_PC + + } + + fun attackNPCs() { + if (PestControlHelper.outsideGangplankContainsLoc(getLocation())){ + content.minigame.pestcontrol.PestControlActivityPlugin().leave(this,false) + val test = getClosestNodeWithEntry(50, myBoat.ladderId) + test ?: println("PC: Gangplank Null") + test.interaction.handle(this, test.interaction[0])//.also { println("Novice - We think we is in pest control ${this.username}.") } + } + walkingQueue.isRunning = true + + if (getAttribute("pc_role","E") == "attack_portals") { + combathandler.goToPortals() + } else { + movetimer = RandomFunction.random(2,10) + randomWalkAroundPoint(PestControlHelper.getMyPestControlSession1(this)?.squire?.location ?: location,5) + combathandler.fightNPCs() + } + } + + var insideBoatWalks = 3 + fun idleInBoat() { + justStartedGame = true + openedGate = false + time = 0 + if (!prayer.active.isEmpty()) { + prayer.reset() + } + if (PestControlHelper.outsideGangplankContainsLoc(getLocation())){ + val test = getClosestNodeWithEntry(15, myBoat.ladderId) + test.interaction.handle(this,test.interaction[0]) + enterBoat()//.also { println("We think we is in boat ${this.username}.") } + } + if (Random().nextInt(100) < 40) { + if (Random().nextInt(insideBoatWalks) <= 1) { + (insideBoatWalks * 1.5).toInt() + + if (Random().nextInt(4) == 1) { + this.walkingQueue.isRunning = !this.walkingQueue.isRunning + } + if (Random().nextInt(7) >= 4) { + this.walkToPosSmart(myBoat.boatBorder.randomLoc!!) + } + } + if (Random().nextInt(3) == 1) { + insideBoatWalks += 2 + } + } + } + + fun enterBoat() { + if (PestControlHelper.outsideGangplankContainsLoc(getLocation())){ + movetimer = Random().nextInt(10) + combathandler.randomWalkTo(PestControlHelper.PestControlLanderNovice, 1) + } + if (!prayer.active.isEmpty()) { + prayer.reset() + } + if (Random().nextInt(8) >= 4) + { + val pclocs = Location.create(2658,2659,0) + combathandler.randomWalkTo(pclocs,12) + movetimer = Random().nextInt(300) + 30 + } + if (Random().nextInt(8) >= 2) + { + randomWalk(3,3) + movetimer = Random().nextInt(10) + } + if (Random().nextInt(100) > 50) + { + if (Random().nextInt(10) <= 5) { + this.walkToPosSmart(myBoat.outsideBoatBorder.randomLoc) + movetimer += RandomFunction.normalPlusWeightRandDist(400, 200) + } + movetimer = RandomFunction.normalPlusWeightRandDist(100, 50) + return + } + val test = getClosestNodeWithEntry(15, myBoat.ladderId) + test ?: randomWalk(1,1) + test?.interaction?.handle(this, test.interaction[0]) + insideBoatWalks = 3 + } + + var switch = false + fun toPC() { + time = 0 + if (!switch){ + this.teleport(PestControlHelper.PestControlLanderNovice)//.also { println("I was stuck ${this.username}") } + switch = true + return + } + if (switch) { + val test = getClosestNodeWithEntry(30, myBoat.ladderId) + if (test == null) { + switch = false + this.teleport(PestControlHelper.PestControlLanderNovice) + State.OUTSIDE_GANGPLANK + } else { + switch = false + test.interaction.handle(this, test.interaction[0]) + State.OUTSIDE_GANGPLANK + } + } + } + + companion object { + fun legitimizeLocation(l: Location): Location { + return if (PestControlHelper.landerContainsLoc(l)) Location(2660, 2648, 0) else l + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/pestcontrol/monsters/PCBrawlerNPC.java b/Server/src/main/content/minigame/pestcontrol/monsters/PCBrawlerNPC.java new file mode 100644 index 0000000..f9f85ea --- /dev/null +++ b/Server/src/main/content/minigame/pestcontrol/monsters/PCBrawlerNPC.java @@ -0,0 +1,77 @@ +package content.minigame.pestcontrol.monsters; + +import content.minigame.pestcontrol.PestControlSession; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.world.map.Location; + +/** + * Handles the pest control brawler NPCs. + * @author Emperor + */ +public final class PCBrawlerNPC extends AbstractNPC { + /** + * The pest control session. + */ + private PestControlSession session; + + /** + * Constructs a new {@code PCBrawlerNPC} {@code Object}. + */ + public PCBrawlerNPC() { + super(3772, null); + } + + /** + * Constructs a new {@code PCBrawlerNPC} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + public PCBrawlerNPC(int id, Location location) { + super(id, location); + } + + @Override + public void init() { + super.setAggressive(true); + super.init(); + super.getDefinition().setCombatDistance(1); + super.walkRadius = 64; + getProperties().getCombatPulse().setStyle(CombatStyle.MELEE); + session = getExtension(PestControlSession.class); + } + + @Override + public boolean shouldPreventStacking(Entity mover) { + return true; + } + + @Override + public void onImpact(final Entity entity, BattleState state) { + super.onImpact(entity, state); + if (session != null && state != null && entity instanceof Player) { + int total = 0; + if (state.getEstimatedHit() > 0) { + total += state.getEstimatedHit(); + } + if (state.getSecondaryHit() > 0) { + total += state.getSecondaryHit(); + } + session.addZealGained((Player) entity, total); + } + } + + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new PCBrawlerNPC(id, location); + } + + @Override + public int[] getIds() { + return new int[] { 3772, 3773, 3774, 3775, 3776 }; + } +} diff --git a/Server/src/main/content/minigame/pestcontrol/monsters/PCDefilerNPC.java b/Server/src/main/content/minigame/pestcontrol/monsters/PCDefilerNPC.java new file mode 100644 index 0000000..73315af --- /dev/null +++ b/Server/src/main/content/minigame/pestcontrol/monsters/PCDefilerNPC.java @@ -0,0 +1,116 @@ +package content.minigame.pestcontrol.monsters; + +import content.minigame.pestcontrol.PestControlSession; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.InteractionType; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.game.world.map.MapDistance; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.node.entity.combat.RangeSwingHandler; + +/** + * Handles the Defiler NPCs. + * @author Emperor + */ +public final class PCDefilerNPC extends AbstractNPC { + + /** + * The pest control session. + */ + private PestControlSession session; + + /** + * The combat swing handler. + */ + private static final CombatSwingHandler SWING_HANDLER = new RangeSwingHandler() { + + @Override + public InteractionType canSwing(Entity entity, Entity victim) { + if (!isProjectileClipped(entity, victim, false)) { + return InteractionType.NO_INTERACT; + } + if (victim.getCenterLocation().withinDistance(entity.getCenterLocation(), 8) && isAttackable(entity, victim) != InteractionType.NO_INTERACT) { + if (victim.getLocation().withinDistance(entity.getLocation(), MapDistance.RENDERING.getDistance() / 2)) { + entity.getWalkingQueue().reset(); + } + return InteractionType.STILL_INTERACT; + } + return InteractionType.NO_INTERACT; + } + }; + + /** + * Constructs a new {@code PCDefilerNPC} {@code Object}. + */ + public PCDefilerNPC() { + super(3762, null); + } + + /** + * Constructs a new {@code PCDefilerNPC} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + public PCDefilerNPC(int id, Location location) { + super(id, location); + } + + @Override + public void init() { + super.setAggressive(true); + super.init(); + super.getDefinition().setCombatDistance(10); + super.walkRadius = 64; + getProperties().getCombatPulse().setStyle(CombatStyle.RANGE); + session = getExtension(PestControlSession.class); + } + + @Override + public void tick() { + super.tick(); + if (session != null && !inCombat() && !getProperties().getCombatPulse().isAttacking()) { + getProperties().getCombatPulse().attack(session.getSquire()); + } + } + + @Override + public boolean shouldPreventStacking(Entity mover) { + return mover instanceof NPC; + } + + @Override + public void onImpact(final Entity entity, BattleState state) { + super.onImpact(entity, state); + if (session != null && state != null && entity instanceof Player) { + int total = 0; + if (state.getEstimatedHit() > 0) { + total += state.getEstimatedHit(); + } + if (state.getSecondaryHit() > 0) { + total += state.getSecondaryHit(); + } + session.addZealGained((Player) entity, total); + } + } + + @Override + public CombatSwingHandler getSwingHandler(boolean swing) { + return SWING_HANDLER; + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new PCDefilerNPC(id, location); + } + + @Override + public int[] getIds() { + return new int[] { 3762, 3763, 3764, 3765, 3766, 3767, 3768, 3769, 3770, 3771 }; + } + +} diff --git a/Server/src/main/content/minigame/pestcontrol/monsters/PCRavagerNPC.java b/Server/src/main/content/minigame/pestcontrol/monsters/PCRavagerNPC.java new file mode 100644 index 0000000..4fba76b --- /dev/null +++ b/Server/src/main/content/minigame/pestcontrol/monsters/PCRavagerNPC.java @@ -0,0 +1,231 @@ +package content.minigame.pestcontrol.monsters; + +import core.game.interaction.MovementPulse; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.impl.PulseType; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.MapDistance; +import core.game.world.map.path.Pathfinder; +import core.game.world.map.zone.ZoneBorders; +import core.tools.RandomFunction; +import content.minigame.pestcontrol.PestControlSession; + +/** + * Handles the Ravager pest control NPC. + * @author Emperor + */ +public class PCRavagerNPC extends AbstractNPC { + + /** + * The current session. + */ + private PestControlSession session; + + /** + * Current object target to destroy. + */ + private Scenery target; + + /** + * The portal index. + */ + private int portalIndex; + + /** + * Next attack tick. + */ + private int nextAttack; + + /** + * The limitation borders. + */ + private ZoneBorders offLimits; + + /** + * Constructs a new {@code PCRavagerNPC} {@code Object}. + */ + public PCRavagerNPC() { + super(3742, null); + } + + /** + * Constructs a new {@code PCRavagerNPC} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + public PCRavagerNPC(int id, Location location) { + super(id, location); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new PCRavagerNPC(id, location); + } + + @Override + public void init() { + super.init(); + super.walkRadius = 64; + if ((session = getExtension(PestControlSession.class)) != null) { + Location l = session.getRegion().getBaseLocation(); + offLimits = new ZoneBorders(l.getX() + 20, l.getY() + 26, l.getX() + 44, l.getY() + 57); + } + } + + @Override + public void tick() { + super.tick(); + if (session != null && !getProperties().getCombatPulse().isAttacking()) { + if (target == null) { + if (findTarget()) { + getPulseManager().clear(); + walk(target); + } else if (!getPulseManager().hasPulseRunning() && RandomFunction.RANDOM.nextInt(10) < 2) { + if (offLimits.insideBorder(getLocation().getX(), getLocation().getY())) { + walk(session.getPortals()[portalIndex]); + } else { + walk(session.getSquire().getLocation()); + } + } + } else { + if (!target.isActive() || !session.getBarricades().contains(target)) { + attack(null); + } else if (nextAttack < GameWorld.getTicks() && getLocation().withinDistance(target.getLocation(), 1)) { + getPulseManager().clear(); + setWalks(false); + super.getWalkingQueue().reset(); + super.getLocks().lockMovement(2); + super.faceLocation(target.getLocation()); + super.animate(getProperties().getAttackAnimation()); + int newId = target.getId() + (target.getId() < 14233 ? 3 : 4); + boolean destroyed = !isTarget(newId); + int type = destroyed ? 22 : target.getType(); + final Scenery o = target; + final Scenery newTarget = o.transform(newId, o.getRotation(), type); + GameWorld.getPulser().submit(new Pulse(1, this, o) { + @Override + public boolean pulse() { + if (getViewport().getRegion().isActive() && session.getBarricades().remove(o)) { + session.getBarricades().add(newTarget); + SceneryBuilder.replace(o, newTarget); + } + return true; + } + }); + target = newTarget; + if (destroyed) { + attack(null); + } + nextAttack = GameWorld.getTicks() + 5; + } + } + } else { + attack(null); + } + getProperties().setRetaliating(target == null); + } + + /** + * Starts attacking a scenery. + * @param o The object. + */ + private void attack(Scenery o) { + target = o; + if (o == null) { + setWalks(true); + super.faceLocation(null); + } + } + + /** + * Walks to the destination. + * @param destination The destination. + */ + private void walk(Node destination) { + getPulseManager().run(new MovementPulse(this, destination, Pathfinder.SMART) { + @Override + public boolean pulse() { + return true; + } + }, PulseType.STANDARD); + } + + /** + * Checks if the object id is a possible target. + * @param id The object id. + * @return {@code true} if so. + */ + private static boolean isTarget(int id) { + for (int object : PestControlSession.INVALID_OBJECT_IDS) { + if (id == object) { + return false; + } + } + return true; + } + + @Override + public boolean shouldPreventStacking(Entity mover) { + return mover instanceof NPC; + } + + @Override + public void onImpact(final Entity entity, BattleState state) { + super.onImpact(entity, state); + if (session != null && state != null && entity instanceof Player) { + int total = 0; + if (state.getEstimatedHit() > 0) { + total += state.getEstimatedHit(); + } + if (state.getSecondaryHit() > 0) { + total += state.getSecondaryHit(); + } + session.addZealGained((Player) entity, total); + } + } + + /** + * Finds an object target. + * @return {@code True} if a target was found. + */ + private boolean findTarget() { + for (Scenery o : session.getBarricades()) { + if (o.getLocation().withinDistance(getLocation(), MapDistance.RENDERING.getDistance() / 3) && isTarget(o.getId())) { + attack(o); + return true; + } + } + return false; + } + + @Override + public int[] getIds() { + return new int[] { 3742, 3743, 3744, 3745, 3746 }; + } + + /** + * Gets the portalIndex. + * @return The portalIndex. + */ + public int getPortalIndex() { + return portalIndex; + } + + /** + * Sets the portalIndex. + * @param portalIndex The portalIndex to set. + */ + public void setPortalIndex(int portalIndex) { + this.portalIndex = portalIndex; + } + +} diff --git a/Server/src/main/content/minigame/pestcontrol/monsters/PCShifterNPC.java b/Server/src/main/content/minigame/pestcontrol/monsters/PCShifterNPC.java new file mode 100644 index 0000000..8364481 --- /dev/null +++ b/Server/src/main/content/minigame/pestcontrol/monsters/PCShifterNPC.java @@ -0,0 +1,172 @@ +package content.minigame.pestcontrol.monsters; + +import content.minigame.pestcontrol.PestControlSession; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.InteractionType; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.tools.RandomFunction; +import core.game.node.entity.combat.CombatPulse; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.node.entity.combat.MeleeSwingHandler; +import core.game.world.GameWorld; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Handles the pest control shifter NPCs. + * @author Emperor + */ +public final class PCShifterNPC extends AbstractNPC { + + /** + * The pest control session. + */ + private PestControlSession session; + + /** + * The combat swing handler. + */ + private static final CombatSwingHandler SWING_HANDLER = new MeleeSwingHandler() { + @Override + public InteractionType canSwing(Entity entity, Entity victim) { + // Allows for diagonal combat + return CombatStyle.RANGE.getSwingHandler().canSwing(entity, victim); + } + }; + + /** + * Constructs a new {@code PCShifterNPC} {@code Object}. + */ + public PCShifterNPC() { + super(3732, null); + } + + /** + * Constructs a new {@code PCShifterNPC} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + public PCShifterNPC(int id, Location location) { + super(id, location); + } + + @Override + public void init() { + super.setAggressive(true); + super.init(); + super.getDefinition().setCombatDistance(1); + super.walkRadius = 64; + getProperties().getCombatPulse().setStyle(CombatStyle.MELEE); + session = getExtension(PestControlSession.class); + } + + @Override + public void tick() { + super.tick(); + CombatPulse pulse = getProperties().getCombatPulse(); + if (session != null && !inCombat() && !pulse.isAttacking() && RandomFunction.RANDOM.nextInt(50) < 2) { + pulse.attack(session.getSquire()); + } + if (pulse.isAttacking() && !getLocation().withinDistance(pulse.getVictim().getLocation(), 5)) { + if (session == null || session.isActive()) { + teleport(session, this, getDestination(pulse.getVictim())); + } + } + } + + @Override + public boolean shouldPreventStacking(Entity mover) { + return mover instanceof NPC; + } + + @Override + public void onImpact(final Entity entity, BattleState state) { + super.onImpact(entity, state); + if (session != null && state != null && entity instanceof Player) { + int total = 0; + if (state.getEstimatedHit() > 0) { + total += state.getEstimatedHit(); + } + if (state.getSecondaryHit() > 0) { + total += state.getSecondaryHit(); + } + session.addZealGained((Player) entity, total); + } + } + + @Override + public CombatSwingHandler getSwingHandler(boolean swing) { + return SWING_HANDLER; + } + + /** + * Gets the destination location. + * @param victim The victim. + * @return The destination. + */ + private Location getDestination(Entity victim) { + List locations = new ArrayList<>(20); + int radius = 2; + for (int x = -radius; x < radius + 1; x++) { + for (int y = -radius; y < radius + 1; y++) { + if (x != 0 && y != 0) { + locations.add(victim.getLocation().transform(x, y, 0)); + } + } + } + Collections.shuffle(locations, RandomFunction.RANDOM); + for (Location l : locations) { + if (RegionManager.isTeleportPermitted(l)) { + return l; + } + } + return null; + } + + /** + * Teleports the entity to the destination location. + * @param session The pest control session. + * @param entity The entity. + * @param destination The destination. + */ + public static void teleport(final PestControlSession session, final Entity entity, final Location destination) { + if (destination == null || session != null && destination.getRegionId() != session.getRegion().getId()) { + return; + } + Graphics.send(Graphics.create(654), entity.getLocation()); + entity.getProperties().setTeleportLocation(destination); + entity.getWalkingQueue().reset(); + entity.getLocks().lockMovement(2); + entity.lock(3); + GameWorld.getPulser().submit(new Pulse(1, entity) { + @Override + public boolean pulse() { + entity.animate(Animation.create(3904)); + Graphics.send(Graphics.create(654), destination); + return true; + } + }); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new PCShifterNPC(id, location); + } + + @Override + public int[] getIds() { + return new int[] { 3732, 3733, 3734, 3735, 3736, 3737, 3738, 3739, 3740, 3741 }; + } + +} diff --git a/Server/src/main/content/minigame/pestcontrol/monsters/PCSpinnerNPC.java b/Server/src/main/content/minigame/pestcontrol/monsters/PCSpinnerNPC.java new file mode 100644 index 0000000..60cc22a --- /dev/null +++ b/Server/src/main/content/minigame/pestcontrol/monsters/PCSpinnerNPC.java @@ -0,0 +1,156 @@ +package content.minigame.pestcontrol.monsters; + +import content.minigame.pestcontrol.PCPortalNPC; +import content.minigame.pestcontrol.PestControlSession; +import core.game.interaction.MovementPulse; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.ImpactHandler.HitsplatType; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.impl.PulseType; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.tools.RandomFunction; + +import static core.api.ContentAPIKt.*; + +/** + * Handles a pest control spinner NPC. + * @author Emperor + */ +public final class PCSpinnerNPC extends AbstractNPC { + + /** + * The current session. + */ + private PestControlSession session; + + /** + * The portal index. + */ + private int portalIndex; + + /** + * Constructs a new {@code PCSpinnerNPC} {@code Object}. + */ + public PCSpinnerNPC() { + super(3747, null); + } + + /** + * Constructs a new {@code PCSpinnerNPC} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + public PCSpinnerNPC(int id, Location location) { + super(id, location); + } + + @Override + public void init() { + super.init(); + super.walkRadius = 4; + session = getExtension(PestControlSession.class); + } + + @Override + public void tick() { + super.tick(); + if (session != null && RandomFunction.RANDOM.nextInt(10) < 2) { + NPC portal = session.getPortals()[portalIndex]; + if (portal.isActive() && portal.getSkills().getLifepoints() > 0) { + if (portal.getSkills().getLifepoints() < portal.getSkills().getMaximumLifepoints()) { + if (getLocation().withinDistance(portal.getCenterLocation(), 5)) { + heal(); + } + getPulseManager().run(new MovementPulse(this, portal) { + @Override + public boolean pulse() { + return true; + } + }, PulseType.STANDARD); + } + } + } + } + + /** + * Heals the portal. + */ + public void heal() { + NPC portal = session.getPortals()[portalIndex]; + if (!portal.isActive() || portal.getSkills().getLifepoints() < 1) { + return; + } + faceTemporary(portal, 1); + visualize(new Animation(3911, Priority.HIGH), Graphics.create(658)); + portal.getSkills().heal(portal.getSkills().getMaximumLifepoints() / 10); + ((PCPortalNPC) portal).updateLifepoints = true; + } + + /** + * Handles the exploding of a spinner. + */ + public void explode() { + animate(getProperties().getDeathAnimation()); + for (Player p : RegionManager.getLocalPlayers(this, 1)) { + p.getImpactHandler().manualHit(this, 5, HitsplatType.POISON); + applyPoison(p, this, 1); + } + GameWorld.getPulser().submit(new Pulse(1, this) { + @Override + public boolean pulse() { + clear(); + return true; + } + }); + } + + @Override + public boolean shouldPreventStacking(Entity mover) { + return mover instanceof NPC; + } + + @Override + public void onImpact(final Entity entity, BattleState state) { + super.onImpact(entity, state); + if (session != null && state != null && entity instanceof Player) { + int total = 0; + if (state.getEstimatedHit() > 0) { + total += state.getEstimatedHit(); + } + if (state.getSecondaryHit() > 0) { + total += state.getSecondaryHit(); + } + session.addZealGained((Player) entity, total); + } + } + + /** + * Sets the portal index. + * @param portalIndex The portal index. + * @return This instance, for chaining. + */ + public PCSpinnerNPC setPortalIndex(int portalIndex) { + this.portalIndex = portalIndex; + return this; + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new PCSpinnerNPC(id, location); + } + + @Override + public int[] getIds() { + return new int[] { 3747, 3748, 3749, 3750, 3751 }; + } + +} diff --git a/Server/src/main/content/minigame/pestcontrol/monsters/PCSplatterNPC.java b/Server/src/main/content/minigame/pestcontrol/monsters/PCSplatterNPC.java new file mode 100644 index 0000000..5e51112 --- /dev/null +++ b/Server/src/main/content/minigame/pestcontrol/monsters/PCSplatterNPC.java @@ -0,0 +1,170 @@ +package content.minigame.pestcontrol.monsters; + +import java.util.ArrayList; + +import content.minigame.pestcontrol.PestControlSession; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.tools.RandomFunction; + +/** + * Handles the pest control splatter NPC. + * @author Emperor + */ +public final class PCSplatterNPC extends AbstractNPC { + + /** + * The current session. + */ + private PestControlSession session; + + /** + * If the splatter is exploding. + */ + private boolean exploding; + + /** + * Constructs a new {@code PCSplatterNPC} {@code Object}. + */ + public PCSplatterNPC() { + super(3727, null); + } + + /** + * Constructs a new {@code PCSplatterNPC} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + public PCSplatterNPC(int id, Location location) { + super(id, location); + } + + @Override + public void init() { + super.init(); + super.walkRadius = 64; + session = getExtension(PestControlSession.class); + } + + @Override + public void tick() { + super.tick(); + if (exploding || session == null) { + return; + } + if (getProperties().getCombatPulse().isAttacking()) { + return; + } + for (Scenery o : session.getBarricades()) { + if (o.getLocation().isNextTo(this)) { + commenceDeath(this); + break; + } + } + } + + @Override + public boolean shouldPreventStacking(Entity mover) { + return mover instanceof NPC; + } + + @Override + public void onImpact(final Entity entity, BattleState state) { + super.onImpact(entity, state); + if (session != null && state != null && entity instanceof Player) { + int total = 0; + if (state.getEstimatedHit() > 0) { + total += state.getEstimatedHit(); + } + if (state.getSecondaryHit() > 0) { + total += state.getSecondaryHit(); + } + session.addZealGained((Player) entity, total); + } + } + + @Override + public void commenceDeath(Entity killer) { + exploding = true; + visualize(new Animation(3888, Priority.VERY_HIGH), Graphics.create(649 + (getId() - 3727))); + GameWorld.getPulser().submit(new Pulse(1, this) { + @Override + public boolean pulse() { + explode(); + return true; + } + }); + } + + @Override + public void finalizeDeath(Entity killer) { + + } + + /** + * Handles the exploding of the splatter. + */ + private void explode() { + int maximum = getProperties().getCurrentCombatLevel() / 3; + int minimum = maximum / 2; + if (session != null) { + for (Scenery o : new ArrayList<>(session.getBarricades())) { + if (o.getLocation().isNextTo(this)) { + int newId = o.getId() + (o.getId() < 14233 ? 3 : 4); + boolean destroyed = !isTarget(newId); + final Scenery newTarget = o.transform(newId, o.getRotation(), destroyed ? 22 : o.getType()); + if (session.getBarricades().remove(o)) { + session.getBarricades().add(newTarget); + SceneryBuilder.replace(o, newTarget); + } + } + } + } + for (Player p : RegionManager.getLocalPlayers(this, 1)) { + p.getImpactHandler().manualHit(this, RandomFunction.random(minimum, maximum), null); + } + for (NPC npc : RegionManager.getLocalNpcs(this, 1)) { + if (npc != this) { + npc.getImpactHandler().manualHit(this, RandomFunction.random(minimum, maximum), null); + } + } + clear(); + } + + /** + * Checks if the object id is a possible target. + * @param id The object id. + * @return {@code true} if so. + */ + private static boolean isTarget(int id) { + for (int object : PestControlSession.INVALID_OBJECT_IDS) { + if (id == object) { + return false; + } + } + return true; + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new PCSplatterNPC(id, location); + } + + @Override + public int[] getIds() { + return new int[] { 3727, 3728, 3729, 3730, 3731 }; + } + +} diff --git a/Server/src/main/content/minigame/pestcontrol/monsters/PCTorcherNPC.java b/Server/src/main/content/minigame/pestcontrol/monsters/PCTorcherNPC.java new file mode 100644 index 0000000..8097645 --- /dev/null +++ b/Server/src/main/content/minigame/pestcontrol/monsters/PCTorcherNPC.java @@ -0,0 +1,151 @@ +package content.minigame.pestcontrol.monsters; + +import content.minigame.pestcontrol.PestControlSession; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.spell.CombatSpell; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.InteractionType; +import core.game.node.entity.combat.spell.SpellType; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.world.map.Location; +import core.game.world.map.MapDistance; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Plugin; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.node.entity.combat.MagicSwingHandler; + +/** + * Handles the torcher pest control NPC. + * @author Emperor + */ +public final class PCTorcherNPC extends AbstractNPC { + + /** + * The torcher spell. + */ + private static final TorcherSpell SPELL = new TorcherSpell(); + + /** + * The combat swing handler. + */ + private static final CombatSwingHandler SWING_HANDLER = new MagicSwingHandler() { + + @Override + public InteractionType canSwing(Entity entity, Entity victim) { + if (!isProjectileClipped(entity, victim, false)) { + return InteractionType.NO_INTERACT; + } + if (victim.getCenterLocation().withinDistance(entity.getCenterLocation(), 8) && isAttackable(entity, victim) != InteractionType.NO_INTERACT) { + if (victim.getLocation().withinDistance(entity.getLocation(), MapDistance.RENDERING.getDistance() / 2)) { + entity.getWalkingQueue().reset(); + } + return InteractionType.STILL_INTERACT; + } + return InteractionType.NO_INTERACT; + } + }; + + /** + * The pest control session. + */ + private PestControlSession session; + + /** + * Constructs a new {@code PCTorcherNPC} {@code Object}. + */ + public PCTorcherNPC() { + super(3752, null); + } + + /** + * Constructs a new {@code PCTorcherNPC} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + public PCTorcherNPC(int id, Location location) { + super(id, location); + } + + @Override + public void init() { + super.setAggressive(true); + super.init(); + super.getDefinition().setCombatDistance(10); + super.walkRadius = 64; + getProperties().getCombatPulse().setStyle(CombatStyle.MAGIC); + super.getProperties().setAutocastSpell(SPELL); + session = getExtension(PestControlSession.class); + } + + @Override + public void tick() { + super.tick(); + if (session != null && !inCombat() && !getProperties().getCombatPulse().isAttacking()) { + getProperties().getCombatPulse().attack(session.getSquire()); + } + } + + @Override + public boolean shouldPreventStacking(Entity mover) { + return mover instanceof NPC; + } + + @Override + public void onImpact(final Entity entity, BattleState state) { + super.onImpact(entity, state); + if (session != null && state != null && entity instanceof Player) { + int total = 0; + if (state.getEstimatedHit() > 0) { + total += state.getEstimatedHit(); + } + if (state.getSecondaryHit() > 0) { + total += state.getSecondaryHit(); + } + session.addZealGained((Player) entity, total); + } + } + + @Override + public CombatSwingHandler getSwingHandler(boolean swing) { + return SWING_HANDLER; + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new PCTorcherNPC(id, location); + } + + @Override + public int[] getIds() { + return new int[] { 3752, 3753, 3754, 3755, 3756, 3757, 3758, 3759, 3760, 3761 }; + } + +} + +class TorcherSpell extends CombatSpell { + + /** + * Constructs a new {@code TorcherSpell} {@code Object}. + */ + public TorcherSpell() { + super(SpellType.STRIKE, SpellBook.MODERN, 0, 0.0, -1, -1, new Animation(3882, Priority.HIGH), Graphics.create(646), Projectile.create((Entity) null, null, 647, 40, 36, 52, 75, 15, 11), new Graphics(648, 96)); + } + + @Override + public int getMaximumImpact(Entity entity, Entity victim, BattleState state) { + return entity.getProperties().getCurrentCombatLevel() / 7; + } + + @Override + public Plugin newInstance(SpellType arg) throws Throwable { + return this; + } + +} diff --git a/Server/src/main/content/minigame/pestcontrol/reward/PCIslandOptionPlugin.java b/Server/src/main/content/minigame/pestcontrol/reward/PCIslandOptionPlugin.java new file mode 100644 index 0000000..ca33a73 --- /dev/null +++ b/Server/src/main/content/minigame/pestcontrol/reward/PCIslandOptionPlugin.java @@ -0,0 +1,37 @@ +package content.minigame.pestcontrol.reward; + +import core.cache.def.impl.NPCDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.plugin.ClassScanner; + +/** + * Represents the option plugin used to handle the pc island related nodes. + * @author 'Vexia + */ +@Initializable +public final class PCIslandOptionPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (int id : new int[] { 3786, 3788, 3789, 5956 }) { + NPCDefinition.forId(id).getHandlers().put("option:exchange", this); + } + ClassScanner.definePlugin(new PCRewardInterface()); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + switch (option) { + case "exchange": + PCRewardInterface.open(player); + break; + } + return true; + } + +} diff --git a/Server/src/main/content/minigame/pestcontrol/reward/PCRewardInterface.java b/Server/src/main/content/minigame/pestcontrol/reward/PCRewardInterface.java new file mode 100644 index 0000000..9140bfd --- /dev/null +++ b/Server/src/main/content/minigame/pestcontrol/reward/PCRewardInterface.java @@ -0,0 +1,773 @@ +package content.minigame.pestcontrol.reward; + +import java.util.ArrayList; +import java.util.List; + +import core.cache.def.impl.ItemDefinition; +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.node.entity.skill.Skills; +import content.global.skill.herblore.Herbs; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.plugin.Plugin; +import core.tools.RandomFunction; + +import static core.api.ContentAPIKt.getStatLevel; + +/** + * Represents the pest control reward interface. + * @author 'Vexia + */ +public final class PCRewardInterface extends ComponentPlugin { + + /** + * Represents the red colour. + */ + public static final String RED = ""; + + /** + * Represents the green colour. + */ + public static final String GREEN = ""; + + /** + * Represents the white colour. + */ + public static final String WHITE = ""; + + /** + * Represents the skill headers ordered by skill index. + */ + public static final int[] SKILL_HEADER = new int[] { 10, 12, 11, 15, 13, 16, 14 }; + + /** + * Represents the skill array of exp rewards. + */ + public static final int[] SKILL_ARRAY = new int[] { Skills.ATTACK, Skills.STRENGTH, Skills.DEFENCE, Skills.RANGE, Skills.MAGIC, Skills.HITPOINTS, Skills.PRAYER }; + + /** + * Represents the skill options array. + */ + public static final int[] SKILL_POINTS = new int[] { 1, 10, 100 }; + + /** + * Represents the charm points. + */ + public static final int[] CHARM_POINTS = new int[] { 2, 28, 56 }; + + /** + * Represents the amount of charms to get the from the points. + */ + public static final int[] CHARM_AMOUNTS = new int[] { 1, 14, 28 }; + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.forId(267).setPlugin(this); + return this; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + switch (button) { + case 96: + confirm(player); + return true; + default: + if (button >= 34 && button <= 86) { + if (player.getSavedData().getActivityData().getPestPoints() == 0) { + player.getPacketDispatch().sendMessage("You don't have enough points."); + return true; + } + select(player, button); + } + break; + } + return true; + } + + /** + * Method used to open the pest control reward interface. + * @param player the player. + */ + public static void open(final Player player) { + player.removeAttribute("pc-reward"); + sendString(player, "Points: " + player.getSavedData().getActivityData().getPestPoints(), 105); + clear(player); + player.getInterfaceManager().open(new Component(267)); + } + + /** + * Method used to send the skill headers. + * @param player the player. + */ + private static final void sendSkills(final Player player) { + for (int skill : SKILL_ARRAY) { + sendString(player, getSkillCondition(player, skill), getSkillChild(skill)); + } + } + + /** + * Method used to send a string onto this interface. + * @param player the player instance. + * @param string the string to send. + * @param child the child to send it on. + */ + private static final void sendString(final Player player, String string, int child) { + player.getPacketDispatch().sendString(string, 267, child); + } + + /** + * Method used to select a reward. + * @param player the player. + * @param button the button. + */ + public void select(final Player player, final int button) { + final Reward reward = Reward.forButton(button); + final int option = reward.getOption(button); + if (!reward.checkRequirements(player, option)) { + return; + } + cacheReward(player, reward, option); + } + + /** + * Method used to selected the current reward. + * @param player the player. + */ + public boolean deselect(final Player player) { + return deselect(player, getReward(player)); + } + + /** + * Method used to deselect the reward. + * @param player the player. + * @param reward the reward. + */ + public boolean deselect(final Player player, final Reward reward) { + if (reward == null) { + return false; + } + clear(player); + reward.deselect(player, getCachedOption(player)); + return true; + } + + /** + * Method used to cache the reward. + * @param player + */ + public final void cacheReward(final Player player, final Reward reward, final int option) { + deselect(player);// delect any previous ones. + reward.select(player, option); + sendString(player, "Confirm:", 106); + sendString(player, reward.getName(), 104); + player.setAttribute("pc-reward", reward); + player.setAttribute("pc-reward:option", option); + } + + /** + * Method used to clear the interface with new data. + * @param player the player. + */ + public final static void clear(final Player player) { + sendSkills(player); + for (Reward reward : Reward.values()) { + if (reward.isSkillReward()) { + continue; + } + if (reward.charm) { + sendString(player, (player.getSavedData().getActivityData().getPestPoints() < 2 ? RED + "You need 2 points." : GREEN + reward.getName()), reward.getHeader()); + continue; + } + sendString(player, (player.getSavedData().getActivityData().getPestPoints() < reward.getPoints() ? player.getSavedData().getActivityData().getPestPoints() < 1 ? RED + ("You need at least 1 point.") : RED + ("You need " + reward.getPoints() + " points.") : (GREEN + reward.getName())), reward.getHeader()); + } + } + + /** + * Method used to calculate the experience the player can receive in this skill. + * @param player the player. + * @return the experience as an integer. + */ + public static int calculateExperience(final Player player, final int skillId, final int points) { + int level = getStatLevel(player, skillId); + int N = 0; + switch (skillId) { + case Skills.PRAYER: + N = 18; + break; + case Skills.MAGIC: + case Skills.RANGE: + N = 32; + break; + case Skills.ATTACK: + case Skills.STRENGTH: + case Skills.DEFENCE: + case Skills.HITPOINTS: + N = 35; + break; + } + int xpPerPoint = (int) ((double) (level * level) / 600) * N; + double bonus = 1.0; + if (points >= 100) { + bonus = 1.1; + } else if (points >= 10) { + bonus = 1.01; + } + return (int) (points * xpPerPoint * bonus); + } + + /** + * Method used to get the skill condition string to send. + * @param player the player. + * @param skillId the skillId. + * @return the string to send. + */ + public static String getSkillCondition(final Player player, final int skillId) { + if (player.getSkills().getStaticLevel(skillId) < 25) { + return RED + "Must reach level 25 first."; + } + return GREEN + getSkillXp(player, skillId); + } + + /** + * Method used to get the skill experience string. + * @param player the player. + * @param skillId the skill id. + * @return the string. + */ + public static String getSkillXp(final Player player, int skillId) { + return Skills.SKILL_NAME[skillId] + " - " + calculateExperience(player, skillId, 1) + " xp"; + } + + /** + * Method used to get the skill header by the index. + * @param skill the skill index. + * @return the skill child id. + */ + public static int getSkillChild(final int skill) { + return SKILL_HEADER[skill]; + } + + /** + * Method used to get the current reward. + * @param player the player. + * @return the reward. + */ + public static Reward getReward(final Player player) { + return player.getAttribute("pc-reward", null); + } + + /** + * Method used to check if the player has a reward set. + * @param player the player. + * @return the reward. + */ + public static boolean hasReward(final Player player) { + return getReward(player) != null; + } + + /** + * Method used to get the pest control reward option index. + * @param player the player. + * @return the option index. + */ + public static int getCachedOption(final Player player) { + return player.getAttribute("pc-reward:option", 0); + } + + /** + * Method used to confirm the reward. + * @param player the player. + */ + public void confirm(final Player player) { + if (!hasReward(player)) { + player.getPacketDispatch().sendMessage("Please choose a reward."); + return; + } + final Reward reward = getReward(player); + if ((reward.charm || !reward.isSkillReward()) && player.getInventory().freeSlots() == 0) { + player.getPacketDispatch().sendMessage("You don't have enough inventory space."); + return; + } + final int option = getCachedOption(player); + final int points = reward.getPoints(option); + String message; + player.getInterfaceManager().close(); + if (player.getSavedData().getActivityData().getPestPoints() >= points) { + player.getSavedData().getActivityData().decreasePestPoints(points); + if (reward.isSkillReward()) { + int experience = calculateExperience(player, reward.getSkill(), points); + player.getSkills().addExperience(reward.getSkill(), experience); + message = "The Void Knight has granted you " + experience + " " + reward.getName() + "."; + } else { + if (!reward.checkItemRequirement(player, option)) { + return; + } + if (!reward.charm) { + if (reward.getReward().length > 1) { + Item[] pack = reward.constructPack(); + for (Item i : pack) { + if (!player.getInventory().add(i)) { + GroundItemManager.create(i, player); + } + } + } else { + if (!player.getInventory().add(reward.getReward()[0])) { + GroundItemManager.create(reward.getReward()[0], player); + } + } + } else { + Item charm = new Item(reward.getReward()[0].getId()); + int amt = CHARM_AMOUNTS[option - 1]; + for (int i = 0; i < amt; i++) { + if (!player.getInventory().add(charm)) { + GroundItemManager.create(charm, player); + } + } + } + message = "The Void Knight has given you a " + reward.getName() + "."; + } + player.getDialogueInterpreter().sendDialogue(message, "Remaining Void Knight Commendation Points: " + player.getSavedData().getActivityData().getPestPoints()); + } + } + + /** + * Represents the rewards that are obtainable with this interface. + * @author 'Vexia + */ + public enum Reward { + ATTACK(Skills.ATTACK, new int[] { 10, 34, 49, 56 }), STRENGTH(Skills.STRENGTH, new int[] { 11, 35, 50, 57 }), DEFENCE(Skills.DEFENCE, new int[] { 12, 36, 51, 58 }), RANGE(Skills.RANGE, new int[] { 13, 37, 52, 59 }), MAGIC(Skills.MAGIC, new int[] { 14, 38, 53, 60 }), HITPOINTS(Skills.HITPOINTS, new int[] { 15, 39, 54, 61 }), PRAYER(Skills.PRAYER, new int[] { 16, 40, 55, 62 }), HERB_PACK("Herb Pack", 30, new Item[] { Herbs.HARRALANDER.getHerb(), Herbs.RANARR.getHerb(), Herbs.TOADFLAX.getHerb(), Herbs.IRIT.getHerb(), Herbs.AVANTOE.getHerb(), Herbs.KWUARM.getHerb(), Herbs.GUAM.getHerb(), Herbs.MARRENTILL.getHerb() }, new int[] { 32, 45 }) { + @Override + public boolean checkItemRequirement(final Player player, final int option) { + if (player.getSkills().getLevel(Skills.HERBLORE) < 25) { + player.getPacketDispatch().sendMessage("You need level 25 herblore to purchase this pack."); + return false; + } + return true; + } + }, + MINERAL_PACK("Mineral Pack", 15, new Item[] { new Item(453), new Item(440) }, new int[] { 47, 46 }) { + @Override + public boolean checkItemRequirement(final Player player, final int option) { + if (player.getSkills().getLevel(Skills.MINING) < 25) { + player.getPacketDispatch().sendMessage("You need level 25 mining to purchase this pack."); + return false; + } + return true; + } + }, + SEED_PACK("Seed Pack", 15, new Item[] { new Item(5320), new Item(5322), new Item(5100) }, new int[] { 33, 48 }) { + @Override + public boolean checkItemRequirement(final Player player, final int option) { + if (player.getSkills().getLevel(Skills.FARMING) < 25) { + player.getPacketDispatch().sendMessage("You need level 25 farming to purchase this pack."); + return false; + } + return true; + } + }, + VOID_MACE("Void Knight Mace", 250, new Item[] { new Item(8841) }, new int[] { 28, 41 }) { + @Override + public boolean checkItemRequirement(final Player player, final int option) { + return hasVoidSkills(player); + } + }, + VOID_TOP("Void Knight Top", 250, new Item[] { new Item(8839) }, new int[] { 29, 42 }) { + @Override + public boolean checkItemRequirement(final Player player, final int option) { + return hasVoidSkills(player); + } + }, + VOID_ROBES("Void Knight Robes", 250, new Item[] { new Item(8840) }, new int[] { 30, 43 }) { + @Override + public boolean checkItemRequirement(final Player player, final int option) { + return hasVoidSkills(player); + } + }, + VOID_GLOVES("Void Knight Gloves", 150, new Item[] { new Item(8842) }, new int[] { 31, 44 }) { + @Override + public boolean checkItemRequirement(final Player player, final int option) { + return hasVoidSkills(player); + } + }, + VOID_MAGE_HELM("Void Knight Mage Helm", 200, new Item[] { new Item(11663) }, new int[] { 63, 67 }) { + @Override + public boolean checkItemRequirement(final Player player, final int option) { + return hasVoidSkills(player); + } + }, + VOID_RANGER_HELM("Void Knight Ranger Helm", 200, new Item[] { new Item(11664) }, new int[] { 64, 68 }) { + @Override + public boolean checkItemRequirement(final Player player, final int option) { + return hasVoidSkills(player); + } + }, + VOID_MELEE_HELM("Void Knight Melee Helm", 200, new Item[] { new Item(11665) }, new int[] { 65, 69 }) { + @Override + public boolean checkItemRequirement(final Player player, final int option) { + return hasVoidSkills(player); + } + }, + VOID_KNIGHT_SEAL("Void Knight Seal", 10, new Item[] { new Item(11666) }, new int[] { 66, 70 }), SPINNER_CHARM("Spinner Charm", new Item(12166), 71, 75, 76, 77), RAVAGER_CHARM("Ravager Charm", new Item(12164), 72, 81, 82, 83), TORCHER_CHARM("Torcher Charm", new Item(12167), 74, 78, 79, 80), SHIFTER_CHAR("Shifter Charm", new Item(12165), 73, 84, 85, 86); + + /** + * Represents the void required skills. + */ + private final int[] VOID_SKILLS = new int[] { Skills.HITPOINTS, Skills.ATTACK, Skills.DEFENCE, Skills.STRENGTH, Skills.RANGE, Skills.MAGIC, Skills.PRAYER }; + + /** + * Represents the childs(header, pts). + */ + private final int[] childs; + + /** + * Represents the skill id. + */ + private int skill; + + /** + * Represents the reward items. + */ + private Item[] reward; + + /** + * Represents the reward name. + */ + private String name; + + /** + * Represents the points required for this reward. + */ + private int points; + + /** + * Represents if the reward is a charm. + */ + private boolean charm = false; + + /** + * Constructs a new {@code PCRewardInterface} {@code Object}. + * @param childs the childs. + */ + Reward(final int[] childs) { + this.childs = childs; + } + + /** + * Constructs a new {@code PCRewardInterface} {@code Object}. + * @param skill the skill. + * @param childs the childs. + */ + Reward(int skill, final int[] childs) { + this.skill = skill; + this.childs = childs; + } + + /** + * Constructs a new {@code PCRewardInterfacce} {@code Object}. + * @param name the name. + * @param points the points. + * @param childs the childs. + */ + Reward(String name, int points, final Item[] reward, final int[] childs) { + this.name = name; + this.points = points; + this.reward = reward; + this.childs = childs; + } + + /** + * Constructs a new {@code PCRewardInterface} {@code Object}. + * @param name the name. + * @param charm the charm. + * @param childs the child. + */ + Reward(final String name, final Item charm, final int... childs) { + this.name = name; + this.charm = true; + this.reward = new Item[] { charm }; + this.childs = childs; + } + + /** + * Method used to check the requirements of a reward. + * @param player the player. + * @param option the option. + * @return True if so. + */ + public boolean checkRequirements(final Player player, final int option) { + if (player.getSavedData().getActivityData().getPestPoints() < getPoints(option)) { + player.getPacketDispatch().sendMessage("You don't have enough points."); + return false; + } + return isSkillReward() ? checkSkillRequirement(player, option) : checkItemRequirement(player, option); + } + + /** + * Method used to select a reward. + * @param player the player. + * @param option the option. + */ + public void select(final Player player, final int option) { + if (isSkillReward()) { + skillSelect(player, option); + } else { + itemSelect(player, option); + } + } + + /** + * Method used to delect a reward. + * @param player the player. + * @param option the option. + */ + public void deselect(final Player player, final int option) { + if (isSkillReward()) { + skillDeselect(player, option); + } else { + itemDeselect(player, option); + } + } + + /** + * Method used to select a skill. + * @param player the player. + * @param option the option index. + */ + public final void skillSelect(final Player player, final int option) { + sendString(player, WHITE + getSkillXp(player, skill), getHeader()); + sendString(player, WHITE + getOptionString(option), getChilds()[option]); + } + + /** + * Method used to handle the item select. + * @param player the player. + * @param option the option. + */ + public final void itemSelect(final Player player, final int option) { + sendString(player, WHITE + getName(), getHeader()); + if (charm) { + sendString(player, WHITE + getOptionString(option), getChilds()[option]); + } + } + + /** + * Method used to deselect a skill. + * @param player the player. + * @param option the option. + */ + public final void skillDeselect(final Player player, final int option) { + sendString(player, "" + getOptionString(option), getChilds()[option]); + } + + /** + * Method used to handle the item deselect. + * @param player the player. + * @param option the option. + */ + public final void itemDeselect(final Player player, final int option) { + if (charm) { + sendString(player, "" + getOptionString(option), getChilds()[option]); + } + } + + /** + * Method used to get the option string. + * @param option the option index. + * @return the string. + */ + public String getOptionString(int option) { + if (charm) { + return (option == 1 ? "(2 Pts)" : option == 2 ? "(28 Pts)" : "(56 Pts)"); + } + return (option == 1 ? "(1 Pt)" : option == 2 ? "(10 Pts)" : "(100 Pts)"); + } + + /** + * Method used to get the option choosen. + * @param button the button. + * @return the optopms. + */ + public int getOption(int button) { + int index = 0; + for (int i : getChilds()) { + if (i == button) { + return index; + } + index++; + } + return -1; + } + + /** + * Gets the amt of required points. + * @return the points. + */ + public int getPoints(final int option) { + if (charm) { + return CHARM_POINTS[option - 1]; + } + return isSkillReward() ? SKILL_POINTS[option - 1] : getPoints(); + } + + /** + * Method used to check if the player has the skills to buy void. + * @param player the player. + * @return True if so. + */ + public boolean hasVoidSkills(final Player player) { + for (int skill : VOID_SKILLS) { + if (player.getSkills().getLevel(skill) < (skill != Skills.PRAYER ? 42 : 22)) { + player.getPacketDispatch().sendMessage("You need level 42 in hitpoints, attack, defence, strength, ranged, magic, and"); + player.getPacketDispatch().sendMessage("22 prayer to purchase the " + name.toLowerCase().replace("_", " ").replace("void knight", "").trim() + "."); + return false; + } + } + return true; + } + + /** + * Gets the name of this reward. + * @return the name. + */ + public String getName() { + return isSkillReward() ? Skills.SKILL_NAME[skill] + " xp" : name; + } + + /** + * Method used to check if it's a charm. + * @return True if so. + */ + public boolean isCharm() { + return charm; + } + + /** + * Method used to check a skill requirement. + * @param player the player. + * @return True if so. + */ + public boolean checkSkillRequirement(final Player player, final int option) { + if (player.getSkills().getLevel(skill) < 25) { + player.getPacketDispatch().sendMessage("The Void Knights will not offer training in skills which you have a level of"); + player.getPacketDispatch().sendMessage("less than 25."); + return false; + } + return true; + } + + /** + * Method used to check the item requirement reward. + * @param player the player. + * @param option the option. + * @return True if so. + */ + public boolean checkItemRequirement(final Player player, final int option) { + /* + * empty. + */ + return true; + } + + /** + * Represents the maximum build of an item array pack. + */ + private static final int MAX_BUILD = 18; + + /** + * Represents the minimum build of an item array pack. + */ + private static final int MIN_BUILD = 13; + + /** + * Method used to generate an item back. + * @return the item pack. + */ + public Item[] constructPack() { + final int build = this == SEED_PACK || this == HERB_PACK ? RandomFunction.random(MIN_BUILD, MAX_BUILD) : RandomFunction.random(38, 43); + int left = build; + List pack = new ArrayList<>(20); + int amt = 0; + for (Item i : getReward()) { + amt = this == SEED_PACK || this == HERB_PACK ? RandomFunction.random(1, 5) : RandomFunction.random(16, 25); + if (amt > left) { + amt = left; + } + if (amt < 1) { + continue; + } + pack.add(new Item(this != SEED_PACK ? ItemDefinition.forId(i.getId()).getNoteId() : i.getId(), amt)); + left -= amt; + } + return pack.toArray(new Item[] {}); + } + + /** + * Method used to get the reward type based off the button. + * @param button the button. + * @return the reward type. + */ + public static Reward forButton(final int button) { + for (Reward reward : values()) { + for (int i : reward.getChilds()) { + if (i == button) { + return reward; + } + } + } + return null; + } + + /** + * Checks if this reward is a skill reward. + * @return True if so. + */ + public boolean isSkillReward() { + return getChilds().length > 2 && !charm; + } + + /** + * Gets the skill. + * @return the skill. + */ + public int getSkill() { + return skill; + } + + /** + * Gets the header. + * @return the header. + */ + public int getHeader() { + return childs[0]; + } + + /** + * Gets the childs. + * @return The childs. + */ + public int[] getChilds() { + return childs; + } + + /** + * Gets the points. + * @return The points. + */ + public int getPoints() { + return points; + } + + /** + * Gets the reward. + * @return The reward. + */ + public Item[] getReward() { + return reward; + } + } + +} diff --git a/Server/src/main/content/minigame/pestcontrol/reward/VoidKnightDialogue.java b/Server/src/main/content/minigame/pestcontrol/reward/VoidKnightDialogue.java new file mode 100644 index 0000000..7ed3d6e --- /dev/null +++ b/Server/src/main/content/minigame/pestcontrol/reward/VoidKnightDialogue.java @@ -0,0 +1,272 @@ +package content.minigame.pestcontrol.reward; + +import core.plugin.Initializable; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; + +/** + * Represents the void knight dialogue. + * + * @author 'Vexia + */ +@Initializable +public final class VoidKnightDialogue extends DialoguePlugin { + + /** + * Reward item + */ + Item reward = new Item(); + + /** + * Repreents the void knight ids. + */ + public static final int IDS[] = new int[] { 3786, 3788, 3789, 5956 }; + + /** + * Constructs a new {@code VoidKnightDialogue} {@code Object}. + */ + public VoidKnightDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code VoidKnightDialogue} {@code Object}. + * + * @param player + * the player. + */ + public VoidKnightDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new VoidKnightDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + npc("Hi, how can I help you?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + options("Who are you?", "What is this place?", "I'm fine thanks."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + player("Who are you?"); + stage = 10; + break; + case 2: + player("What is this place?"); + stage = 20; + break; + case 3: + player("I'm fine thanks."); + stage = 30; + break; + } + break; + case 10: + npc("I'm a Void Knight, one of the order of Guthix. We are", + "warriors of balance who do Guthix's work here in", + "Gielinor."); + stage = 11; + break; + case 11: + options("Wow, can I join?", "What kind of work?", + "What's 'Gielinor'?", "Uh huh, sure."); + stage = 12; + break; + case 12: + switch (buttonId) { + case 1: + player("Wow, can I join?"); + stage = 180; + break; + case 2: + player("What kind of work?"); + stage = 17; + break; + case 3: + player("What's 'Gielinor'?"); + stage = 15; + break; + case 4: + player("Uh huh, sure."); + stage = 14; + break; + } + break; + case 14: + end(); + break; + case 15: + npc("It is the name that Guthix gave to this world, so we", + "honour him with its use."); + stage = 16; + break; + case 16: + end(); + break; + case 17: + npc("Ah well, you see, we try to keep Gielinor as Guthix", + "intended, it's very challenging. Actually we've been", + "having some problems recently, maybe you could help", + "us?"); + stage = 18; + break; + case 18: + options("Yeah OK, what's the problem?", "What's 'Gielinor'?", + "I'd rather not, sorry."); + stage = 19; + break; + case 19: + switch (buttonId) { + case 1: + player("Yeah ok, what's the problem?"); + stage = 191; + break; + case 2: + player("What's 'Gielinor'?"); + stage = 15; + break; + case 3: + player("I'd rather not sorry."); + stage = 190; + break; + } + break; + case 180: + npc("Entry is strictly invite only, however we do need help", + "continuing Guthix's work."); + stage = 181; + break; + case 181: + player("What kind of work?"); + stage = 17; + break; + case 190: + end(); + break; + case 191: + npc("Well the order has become quite diminished over the", + "years, it's a very long process to learn the skills of a", + "Void Knight. Recently there have been breaches into", + "our realm from somewhere else, and strange creatures"); + stage = 192; + break; + case 192: + npc("have been pouring through. We can't let that happen,", + "and we'd be very grateful if you'd help us."); + stage = 193; + break; + case 193: + options("How can I help?", "Sorry, but I can't."); + stage = 194; + break; + case 194: + switch (buttonId) { + case 1: + player("How can I help?"); + stage = 195; + break; + case 2: + player("Sorry, but I can't."); + stage = 190; + break; + } + break; + case 195: + npc("We send launchers from our outpost to the nearby", + "islands. If you go and wait in the lander there that'd", + "really help."); + stage = 196; + break; + case 196: + end(); + break; + case 20: + npc("This is our outpost. From here we send launchers out to", + "the nearby islands to beat back the invaders."); + stage = 21; + break; + case 21: + options("What invaders?", "How can I help?", "Good luck with that."); + stage = 22; + break; + case 22: + switch (buttonId) { + case 1: + player("What invaders?"); + stage = 24; + break; + case 2: + player("How can I help?"); + stage = 195; + break; + case 3: + player("Good luck with that."); + stage = 23; + break; + } + break; + case 23: + end(); + break; + case 24: + npc("Recently there have been breaches into our realm from", + "somewhere else, and strange creatures have been", + "pouring through. We can't let that happen, and we'd be", + "very grateful if you'd help us."); + stage = 193; + break; + case 30: + end(); + break; + case 43: + if (player.getSavedData().getActivityData().getPestPoints() < 150) { + player("I don't have that many points at the moment."); + stage = 30; + } else { + player("Alright, here's one hundred and fifty points."); + stage = 44; + } + break; + case 44: + player.getSavedData() + .getActivityData() + .setPestPoints( + player.getSavedData().getActivityData() + .getPestPoints() - 150); + interpreter.sendItemMessage(reward, "The Void Knight hands over a " + + reward.getName() + "."); + if (player.getInventory().freeSlots() < 1) { + GroundItemManager.create(reward, player.getLocation()); + } else { + player.getInventory().add(reward); + } + stage = 30; + break; + } + return true; + } + + @Override + public int[] getIds() { + return IDS; + } +} diff --git a/Server/src/main/content/minigame/puropuro/CropCircleController.kt b/Server/src/main/content/minigame/puropuro/CropCircleController.kt new file mode 100644 index 0000000..0584e4a --- /dev/null +++ b/Server/src/main/content/minigame/puropuro/CropCircleController.kt @@ -0,0 +1,97 @@ +package content.minigame.puropuro + +import core.api.* +import core.game.interaction.* +import core.game.world.map.Location +import core.game.node.scenery.Scenery +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.TeleportManager.TeleportType + +class CropCircleController : TickListener, InteractionListener, LoginListener { + override fun tick () { + if (getWorldTicks() < nextCircle) + return + deconstructOldCircle() + + val (name, loc) = possibleLocations.random() + constructCircle(loc) + + sendNews("A crop circle has appeared near $name.") + nextCircle = getWorldTicks() + 1500 + currentLocName = name + } + + override fun defineListeners() { + on (center, IntType.SCENERY, "enter") {player, _ -> + if (hasImpBox(player)) { + sendDialogue (player, "Something prevents you from entering. You think the portal is offended by your imp box. They are not popular on imp and impling planes.") + return@on true + } + teleport (player, puroLocation, TeleportType.PURO_PURO) + setAttribute (player, exitLocation, Location.create(player.location)) + return@on true + } + + on (puroExit, IntType.SCENERY, "leave", "quick-leave") {player, _ -> + var exit = getAttribute (player, exitLocation, Location.create(3158, 3300, 0)) + teleport (player, exit, TeleportType.PURO_PURO) + return@on true + } + } + + override fun login (player: Player) { + sendMessage (player, "A crop circle is active near $currentLocName.") + } + + private fun constructCircle (location: Location) { + activeObjects.add ( + addScenery ( + center, + location, + rotation = 0, + type = 10 + ) + ) + for ((index, tile) in location.surroundingTiles.withIndex()) { + activeObjects.add ( + addScenery ( + surrounding[index % 4], + tile, + rotation = (index / 4) * 2, + type = 10 + ) + ) + } + } + + private fun deconstructOldCircle() { + for (scenery in activeObjects) + removeScenery(scenery) + activeObjects.clear() + } + + private fun hasImpBox (player: Player) : Boolean { + return inInventory(player, 10025) || inInventory(player, 10027) || inInventory(player, 10028) + } + + companion object { + var currentLocName = "" + val exitLocation = "/save:puro-exit" + val possibleLocations = arrayOf ( + Pair ("Doric's Hut", Location.create(2953, 3444, 0)), + Pair ("Yanille", Location.create(2583, 3104, 0)), + Pair ("Draynor", Location.create(3113, 3274, 0)), + Pair ("Rimmington", Location.create(2978, 3216, 0)), + Pair ("The Grand Exchange", Location.create(3141, 3461, 0)), + Pair ("Northern Lumbridge", Location.create(3160, 3296, 0)), + Pair ("Southern Varrock", Location.create(3218, 3348, 0)), + Pair ("Northern Ardougne", Location.create(2644, 3350, 0)) + ) + val activeObjects = ArrayList() + val surrounding = arrayOf (24984, 24985, 24986, 24987) + val center = 24991 + val puroExit = 25014 + val puroLocation = Location.create(2591, 4320, 0) + var nextCircle = 0 + } +} diff --git a/Server/src/main/content/minigame/puropuro/ElnockInquisitorDialogue.java b/Server/src/main/content/minigame/puropuro/ElnockInquisitorDialogue.java new file mode 100644 index 0000000..b9cbe7d --- /dev/null +++ b/Server/src/main/content/minigame/puropuro/ElnockInquisitorDialogue.java @@ -0,0 +1,401 @@ +package content.minigame.puropuro; + +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.dialogue.DialoguePlugin; +import content.global.skill.hunter.bnet.BNetTypes; +import content.global.skill.hunter.bnet.ImplingNode; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Plugin; +import core.plugin.ClassScanner; + +import content.minigame.puropuro.ElnockInquisitorDialogue.ElnockExchangeInterfaceHandler.ElnockExchange; + +import static core.api.ContentAPIKt.*; + +/** + * Handles the elnock inquisitor dialogue. + * @author Vexia + */ +public final class ElnockInquisitorDialogue extends DialoguePlugin { + + /** + * The scroll item. + */ + private static final Item SCROLL = new Item(11273); + + /** + * Constructs a new {@code ElnockInquisitorDialogue} {@code Object}. + */ + public ElnockInquisitorDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code ElnockInquisitorDialogue} {@code Object}. + * @param player the player. + */ + public ElnockInquisitorDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new ElnockInquisitorDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc("Ah, good day, it's you again. What can I do for you?"); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + if (!player.hasItem(SCROLL)) { + npc("Ah, I notice you don't own an impling collector's scroll."); + stage = 900; + break; + } + options("Can you remind me how to catch implings again?", "Can I trade some jarred implings please?", "Do you have some spare equipment I can use?"); + stage++; + break; + case 1: + switch (buttonId) { + case 1: + player("Can you remind me how to catch implings again?"); + stage = 10; + break; + case 2: + player("Can I trade some jarred implings please?"); + stage = 20; + break; + case 3: + player("Do you have some spare equipment I can use?"); + stage = 30; + break; + } + break; + case 10: + npc("Certainly."); + stage++; + break; + case 11: + npc("Firstly you will need a butterfly net in which to catch", "them and at least one special impling jar to store an", "impling."); + stage++; + break; + case 12: + npc("You will also require some experience as a Hunter", "since these creatures are elusive. The more immature", "implings require less experience, but some of the rarer", "implings are extraordinarily hard to find and catch."); + stage++; + break; + case 13: + npc("Once you have caught one, you may break the jar", "open and obtain the object the impling is carrying.", "Alternatively, you may exchange certain combinations of", "jars with me. I will return the jars to my clients. In"); + stage++; + break; + case 14: + npc("exchange I will be able to provide you with some", "equipment that may help you hunt butterflies more", "effectively."); + stage++; + break; + case 15: + npc("also beware. Those imps walking around the maze do", "not like the fact that their kindred spirits are being", "captured and will attempt to steal any full jars you have", "on you, setting the implings free."); + stage++; + break; + case 16: + end(); + break; + case 20: + end(); + openShop(player); + break; + case 30: + if (!player.getSavedData().getActivityData().isElnockSupplies()) { + player.getSavedData().getActivityData().setElnockSupplies(true); + player.getInventory().add(new Item(10010), player); + player.getInventory().add(new Item(11262, 1), player); + player.getInventory().add(new Item(11260, 6), player); + npc("Here you go!"); + stage++; + } else { + npc("Since I have already given you some equipment for free,", "I'll be willing to sell you some now."); + stage = 500; + } + break; + case 31: + npc("If you are ready to start hunting implings, then enter", "the main part of the maze."); + stage++; + break; + case 32: + npc("Just push through the wheat that surrounds the centre", "of the maze and get catching!"); + stage++; + break; + case 33: + end(); + break; + case 900: + options("Yes, please.", "No, thanks."); + stage++; + break; + case 901: + switch (buttonId) { + case 1: + player.getInventory().add(SCROLL, player); + interpreter.sendItemMessage(SCROLL, "Elnock gives you a scroll. If you check it whilst in the maze, you will see how many of each impling you have captured."); + stage++; + break; + case 2: + end(); + break; + } + break; + case 902: + end(); + break; + case 500: + player("*sigh*", "Alright, sell me some Impling jars."); + stage++; + break; + case 501: + npc("I'll sell you five jars for 25,000gp, what do you say?"); + stage++; + break; + case 502: + if (player.getInventory().contains(995, 25000)) { + player("Wow, that's expensive!", "Alright... here's some gold for a few jars."); + stage++; + } else { + player("Actually, I don't have that many coins at the moment."); + stage = 902; + } + break; + case 503: + npc("Young one, that is the price you pay for", "forgetting to save some impling jars!"); + if (player.getInventory().remove(new Item(995, 25000))) { + player.getInventory().add(new Item(11260, 5)); + } + stage++; + break; + case 504: + end(); + break; + } + return true; + } + + @Override + public void init() { + super.init(); + ClassScanner.definePlugin(new ElnockExchangeInterfaceHandler()); + } + + @Override + public int[] getIds() { + return new int[] { 6070 }; + } + + /** + * Opens the shop exchange. + * @param player the player. + */ + public static void openShop(Player player) { + int[] vals = new int[] { 22, 25, 28, 31 }; + player.getInterfaceManager().open(new Component(540)); + for (int i = 0; i < ElnockExchange.values().length; i++) { + ElnockExchange e = ElnockExchange.values()[i]; + player.getPacketDispatch().sendItemZoomOnInterface(e.getSendItem(), 115, 540, vals[i]); + } + } + + /** + * Handles the elnock exchange interface. + * @author Vexia + */ + public static final class ElnockExchangeInterfaceHandler extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.forId(540).setPlugin(this); + return this; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + ElnockExchange exchange = player.getAttribute("exchange", null); + if (button == 34) { + setVarp(player, 1018, 0); + if (exchange == null) { + player.sendMessage("Making a selection before confirming."); + return true; + } + if (!exchange.hasItems(player)) { + player.sendMessage("You don't have the required implings in a jar to trade for this."); + return true; + } + if (exchange == ElnockExchange.JAR_GENERATOR && player.hasItem(ElnockExchange.JAR_GENERATOR.getReward())) { + player.sendMessage("You can't have more than one jar generator at a time."); + return true; + } + if (!player.getInventory().hasSpaceFor(exchange.getReward())) { + player.sendMessage("You don't have enough inventory space."); + player.getInterfaceManager().close(); + player.removeAttribute("exchange"); + return true; + } + if (exchange == ElnockExchange.IMPLING_JAR ? player.getInventory().remove(ElnockExchange.getItem(player)) : player.getInventory().remove(exchange.getRequired())) { + player.getInterfaceManager().close(); + player.removeAttribute("exchange"); + player.getInventory().add(exchange.getReward(), player); + } + return true; + } + exchange = ElnockExchange.forButton(button); + if (exchange != null) { + player.setAttribute("exchange", exchange); + setVarp(player, 1018, exchange.getConfigValue()); + } + return true; + } + + /** + * An elnock exchange. + * @author Vexia + */ + public enum ElnockExchange { + IMP_REPELLANT(23, 444928, 11271, new Item(11262), new Item(11238, 3), new Item(11240, 2), new Item(11242)), MAGIC_BUTTERFLY(26, 707072, 11268, new Item(11259), new Item(11242, 3), new Item(11244, 2), new Item(11246)), JAR_GENERATOR(29, 969216, 11267, new Item(11258), new Item(11246, 3), new Item(11248, 2), new Item(11250)), IMPLING_JAR(32, 1231360, 11269, new Item(11260, 3)) { + + @Override + public boolean hasItems(Player player) { + for (ImplingNode node : BNetTypes.getImplings()) { + if (player.getInventory().containsItem(node.getReward())) { + return true; + } + } + return false; + } + + }; + + /** + * The button. + */ + private final int button; + + /** + * The config value. + */ + private final int configValue; + + /** + * The send item. + */ + private final int sendItem; + + /** + * The reward. + */ + private final Item reward; + + /** + * The items required. + */ + private final Item[] required; + + /** + * Constructs a new {@code ElnockExchange} {@code Object}. + * @param button the button. + * @param configValue the value. + * @param reward the reward. + * @param required the required. + */ + private ElnockExchange(int button, int configValue, final int sendItem, Item reward, Item... required) { + this.button = button; + this.configValue = configValue; + this.reward = reward; + this.sendItem = sendItem; + this.required = required; + } + + /** + * Gets the item. + * @param player the player, + * @return the item. + */ + public static Item getItem(Player player) { + for (ImplingNode node : BNetTypes.getImplings()) { + if (player.getInventory().containsItem(node.getReward())) { + return node.getReward(); + } + } + return null; + } + + /** + * Checks if the player has the items. + * @param player the player. + * @return {@code True} if so. + */ + public boolean hasItems(Player player) { + return player.getInventory().containsItems(getRequired()); + } + + /** + * Gets the value. + * @param button the button. + * @return the value. + */ + public static ElnockExchange forButton(int button) { + for (ElnockExchange e : values()) { + if (e.getButton() == button) { + return e; + } + } + return null; + } + + /** + * Gets the reward. + * @return The reward. + */ + public Item getReward() { + return reward; + } + + /** + * Gets the button. + * @return The button. + */ + public int getButton() { + return button; + } + + /** + * Gets the configValue. + * @return The configValue. + */ + public int getConfigValue() { + return configValue; + } + + /** + * Gets the required. + * @return The required. + */ + public Item[] getRequired() { + return required; + } + + /** + * Gets the sendItem. + * @return The sendItem. + */ + public int getSendItem() { + return sendItem; + } + } + } +} diff --git a/Server/src/main/content/minigame/puropuro/FairyAerykaDialogue.java b/Server/src/main/content/minigame/puropuro/FairyAerykaDialogue.java new file mode 100644 index 0000000..fd9e9b7 --- /dev/null +++ b/Server/src/main/content/minigame/puropuro/FairyAerykaDialogue.java @@ -0,0 +1,133 @@ +package content.minigame.puropuro; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; + +/** + * Handles the fairy aeryka dialogue. + * @author Vexia + */ +public final class FairyAerykaDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code FairyAerykaDialogue} {@code Object}. + */ + public FairyAerykaDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code FairyAerykaDialogue} {@code Object}. + * @param player the player. + */ + public FairyAerykaDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new FairyAerykaDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc("It's still here."); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + player("Pardon?"); + stage++; + break; + case 1: + npc("It's still here. The crop circle is still here."); + stage++; + break; + case 2: + player("Oh yes, thanks Aery. It didn't go anywhere in the", "meantime, then?"); + stage++; + break; + case 3: + npc("Nope. It just sat there."); + stage++; + break; + case 4: + player("Jolly good. I can come back and visit Puro-Puro", "whenever I want then. Brilliant!"); + stage++; + break; + case 5: + options("What's in Puro-Puro?", "So what are these implings then?", "I've heard I may find dragon equipment in Puro-Puro?", "No, bye!"); + stage++; + break; + case 6: + switch (buttonId) { + case 1: + player("What's in Puro-Puro?"); + stage = 10; + break; + case 2: + player("So what are these implings then?"); + stage = 20; + break; + case 3: + player("I've heard I may find dragon equipment in Puro-Puro?"); + stage = 30; + break; + case 4: + player("No, bye!"); + stage = 40; + break; + } + break; + case 10: + npc("Implings...and wheat."); + stage = 99; + break; + case 20: + npc("Well, no-one know for sure. The mischievous little", "creatures are probably related to imps. And they fly as", "well."); + stage++; + break; + case 21: + npc("Also, like imps, they love collecting things. I'm not sure", "why, though. They also seem to like being chased."); + stage++; + break; + case 22: + player("So how would I get hold of what they are carrying,", "then?"); + stage++; + break; + case 23: + npc("Catch them, I suppose I don't know really. Why would", "you want to?"); + stage++; + break; + case 24: + end(); + break; + case 30: + npc("Really? You humans like that stuff a lot, don't you? I", "don't like really old stuff myself."); + stage++; + break; + case 31: + end(); + break; + case 40: + npc("See you around!"); + stage = 99; + break; + case 99: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 6072 }; + } + +} diff --git a/Server/src/main/content/minigame/puropuro/ImpDefenderBehavior.kt b/Server/src/main/content/minigame/puropuro/ImpDefenderBehavior.kt new file mode 100644 index 0000000..2c1bb50 --- /dev/null +++ b/Server/src/main/content/minigame/puropuro/ImpDefenderBehavior.kt @@ -0,0 +1,93 @@ +package content.minigame.puropuro + +import core.api.* +import core.tools.* +import core.game.node.entity.npc.* +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import core.game.world.map.zone.ZoneBorders +import core.game.world.map.RegionManager +import core.game.system.task.Pulse +import content.global.skill.hunter.bnet.BNetTypes + +import org.rs09.consts.Items + +class ImpDefenderBehavior : NPCBehavior(6074) { + override fun onCreation (self: NPC) { + self.isWalks = true + self.isNeverWalks = false + self.walkRadius = 30 + } + + override fun tick (self: NPC) : Boolean { + if (!RandomFunction.roll(10)) return true + + var nextCaptureTick = getAttribute(self, "next-capture-tick", 0) + if (getWorldTicks() < nextCaptureTick) return true + + var players = RegionManager.getLocalPlayers(self, 2) + for (player in players) { + var lowestTierImpling = BNetTypes.getImpling(player) + if (lowestTierImpling == null) continue + var jarItem = lowestTierImpling.reward + setAttribute(self, "capture-target", player) + setAttribute(self, "capture-item", jarItem) + setAttribute(self, "next-capture-tick", getWorldTicks() + RandomFunction.random(25, 100)) + submitIndividualPulse(self, TryReleasePulse(self)) + break + } + + return true + } + + private class TryReleasePulse(val self: NPC) : Pulse() { + companion object { + const val catchPlayerLow = 35.0 //14% chance to avoid catch at level 1 + const val catchPlayerHigh = 280.0 //100% chance to avoid catch at level 90 (level 82 with imp repellent) + const val impRepellentBonus = 20.0 //10% bonus if player has imp repellent + } + + var counter = 0 + override fun pulse() : Boolean { + val player: Player? = getAttribute(self, "capture-target", null) + val jarItem: Item? = getAttribute(self, "capture-item", null) + if (player == null || jarItem == null) return true + when (counter++) { + 0 -> { + face (self, player) + animate (self, 6628) + setDelay(animationDuration(getAnimation(6628))) + return false + } + 1 -> { + var hasRepellent = inInventory(player, Items.IMP_REPELLENT_11262) + var baseRoll = RandomFunction.randomDouble(100.0) + var playerRoll = RandomFunction.getSkillSuccessChance( + catchPlayerLow + if (hasRepellent) impRepellentBonus else 0.0, + catchPlayerHigh + if (hasRepellent) impRepellentBonus else 0.0, + getStatLevel(player, Skills.THIEVING) + ) + if (playerRoll < baseRoll) { + sendChat (self, "Be free!") + animate (self, 6629) + removeItem (player, jarItem) + var loc = ZoneBorders ( + self.location.x - 2, + self.location.y - 2, + self.location.x + 2, + self.location.y + 2 + ).randomLoc + GroundItemManager.create( + Item(Items.IMPLING_JAR_11260), + loc, player + ) + } + resetFace (self) + } + } + return true + } + } +} diff --git a/Server/src/main/content/minigame/puropuro/PuroPuroPlugin.java b/Server/src/main/content/minigame/puropuro/PuroPuroPlugin.java new file mode 100644 index 0000000..3aa053f --- /dev/null +++ b/Server/src/main/content/minigame/puropuro/PuroPuroPlugin.java @@ -0,0 +1,513 @@ +package content.minigame.puropuro; + +import core.cache.def.impl.ItemDefinition; +import core.cache.def.impl.NPCDefinition; +import core.game.component.Component; +import core.game.interaction.Option; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.node.entity.skill.Skills; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBuilder; +import core.game.world.map.zone.ZoneType; +import core.game.world.update.flag.context.Animation; +import core.net.packet.PacketRepository; +import core.net.packet.context.MinimapStateContext; +import core.net.packet.out.MinimapState; +import core.plugin.ClassScanner; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.tools.RandomFunction; +import org.rs09.consts.Items; + +import java.util.ArrayList; +import java.util.List; + +import static core.api.ContentAPIKt.*; + +/** + * Handles the puro puro activity. + * + * @author Vexia + */ +@Initializable +public final class PuroPuroPlugin extends MapZone implements Plugin { + + /** + * The moving wheat. + */ + private static final List WHEAT = new ArrayList<>(20); + + /** + * The pulse. + */ + private static final Pulse PULSE = new Pulse(1) { + @Override + public boolean pulse() { + for (WheatSet set : WHEAT) { + if (set.canWhilt()) { + set.whilt(); + } + } + return false; + } + }; + + /** + * Constructs a new {@code PuroPuroActivity} {@code Object}. + */ + public PuroPuroPlugin() { + super("puro puro", true); + setZoneType(ZoneType.SAFE.getId()); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + PULSE.stop(); + ZoneBuilder.configure(this); + ClassScanner.definePlugin(new FairyAerykaDialogue()); + ClassScanner.definePlugin(new WanderingImplingDialogue()); + ClassScanner.definePlugin(new ElnockInquisitorDialogue()); + ClassScanner.definePlugin(new PuroOptionHandler()); + return this; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public boolean enter(Entity e) { + if (e instanceof Player) { + Player p = e.asPlayer(); + PacketRepository.send(MinimapState.class, new MinimapStateContext(p, 2)); + } + if (!PULSE.isRunning()) { + spawnWheat(); + PULSE.restart(); + PULSE.start(); + GameWorld.getPulser().submit(PULSE); + } + return super.enter(e); + } + + @Override + public boolean leave(Entity e, boolean logout) { + if (e instanceof Player) { + Player p = e.asPlayer(); + if (!logout) { + p.getInterfaceManager().close(); + p.getInterfaceManager().closeOverlay(); + PacketRepository.send(MinimapState.class, new MinimapStateContext(p, 0)); + } + } + return super.leave(e, logout); + } + + @Override + public boolean interact(Entity e, Node target, Option option) { + if (e instanceof Player) { + Player p = (Player) e; + switch (target.getId()) { + case 25016: + case 25029: + case 25019: + case 25018: + case 25020: + case 25021: + pushThrough(p, (Scenery) target); + return true; + } + } + return super.interact(e, target, option); + } + + /** + * Pushes through the wheat. + * + * @param player the player. + * @param object the object. + */ + private void pushThrough(final Player player, final Scenery object) { + if (player.getSkills().getStaticLevel(Skills.HUNTER) < 17) { + player.sendMessage("You need a Hunting level of at least 17 to enter the maze."); + return; + } + if (hasImplingBox(player)) { + player.getDialogueInterpreter().sendDialogue("Something prevents you from entering. You think the portal is", "offended by your imp boxes. They are not popular on imp", "and impling planes."); + return; + } + final Location dest = object.getLocation().transform(Direction.getLogicalDirection(player.getLocation(), object.getLocation()), 1); + if (RegionManager.getObject(dest) != null) { + player.sendMessage("An object on the other side is in your way."); + return; + } + if (RandomFunction.random(2) == 0) { + player.sendMessage("You use your strength to push through the wheat."); + } else { + player.sendMessage("You use your strength to push through the wheat. It's hard work though."); + } + player.setAttribute("cantMove", true); + forceMove(player, player.getLocation(), dest, 0, 265, null, 6595, null); + } + + /** + * Spawns the wheat. + */ + private void spawnWheat() { + for (WheatSet set : WHEAT) { + set.init(); + } + } + + /** + * Checks if the player has an impling box. + * + * @param player the player. + * @return {@code True} if so. + */ + private boolean hasImplingBox(Player player) { + return player.getInventory().contains(10025, 1) || player.getInventory().contains(10027, 1) || player.getInventory().contains(10028, 1); + } + + @Override + public void configure() { + registerRegion(10307); + WHEAT.add(new WheatSet(0, Location.create(2606, 4329, 0), Location.create(2606, 4328, 0))); + WHEAT.add(new WheatSet(1, Location.create(2596, 4331, 0), Location.create(2597, 4331, 0))); + WHEAT.add(new WheatSet(0, Location.create(2580, 4326, 0), Location.create(2580, 4325, 0))); + WHEAT.add(new WheatSet(1, Location.create(2595, 4308, 0), Location.create(2596, 4308, 0))); + WHEAT.add(new WheatSet(0, Location.create(2603, 4314, 0), Location.create(2603, 4313, 0))); + WHEAT.add(new WheatSet(1, Location.create(2599, 4305, 0), Location.create(2600, 4305, 0))); + WHEAT.add(new WheatSet(0, Location.create(2577, 4327, 0), Location.create(2577, 4328, 0))); + WHEAT.add(new WheatSet(1, Location.create(2587, 4334, 0), Location.create(2586, 4334, 0))); + WHEAT.add(new WheatSet(0, Location.create(2609, 4310, 0), Location.create(2609, 4309, 0))); + WHEAT.add(new WheatSet(1, Location.create(2586, 4302, 0), Location.create(2587, 4302, 0))); + WHEAT.add(new WheatSet(0, Location.create(2574, 4310, 0), Location.create(2574, 4311, 0))); + WHEAT.add(new WheatSet(1, Location.create(2582, 4337, 0), Location.create(2581, 4337, 0))); + WHEAT.add(new WheatSet(0, Location.create(2571, 4316, 0), Location.create(2571, 4315, 0))); + WHEAT.add(new WheatSet(1, Location.create(2601, 4340, 0), Location.create(2602, 4340, 0))); + WHEAT.add(new WheatSet(0, Location.create(2612, 4324, 0), Location.create(2612, 4323, 0))); + WHEAT.add(new WheatSet(1, Location.create(2584, 4296, 0), Location.create(2583, 4296, 0))); + WHEAT.add(new WheatSet(0, Location.create(2568, 4329, 0), Location.create(2568, 4330, 0))); + WHEAT.add(new WheatSet(1, Location.create(2595, 4343, 0), Location.create(2596, 4343, 0))); + WHEAT.add(new WheatSet(0, Location.create(2615, 4315, 0), Location.create(2615, 4314, 0))); + WHEAT.add(new WheatSet(1, Location.create(2601, 4293, 0), Location.create(2600, 4293, 0))); + WHEAT.add(new WheatSet(0, Location.create(2565, 4310, 0), Location.create(2565, 4311, 0))); + WHEAT.add(new WheatSet(1, Location.create(2582, 4346, 0), Location.create(2583, 4346, 0))); + WHEAT.add(new WheatSet(0, Location.create(2568, 4348, 0), Location.create(2568, 4347, 0))); + WHEAT.add(new WheatSet(0, Location.create(2615, 4347, 0), Location.create(2615, 4348, 0))); + WHEAT.add(new WheatSet(0, Location.create(2612, 4345, 0), Location.create(2612, 4344, 0))); + WHEAT.add(new WheatSet(0, Location.create(2614, 4292, 0), Location.create(2614, 4291, 0))); + WHEAT.add(new WheatSet(0, Location.create(2568, 4292, 0), Location.create(2568, 4291, 0))); + WHEAT.add(new WheatSet(0, Location.create(2571, 4295, 0), Location.create(2571, 4294, 0))); + WHEAT.add(new WheatSet(0, Location.create(2575, 4297, 0), Location.create(2575, 4298, 0))); + WHEAT.add(new WheatSet(0, Location.create(2584, 4330, 0), Location.create(2584, 4329, 0))); + WHEAT.add(new WheatSet(0, Location.create(2599, 4329, 0), Location.create(2599, 4330, 0))); + WHEAT.add(new WheatSet(1, Location.create(2602, 4312, 0), Location.create(2601, 4312, 0))); + WHEAT.add(new WheatSet(1, Location.create(2610, 4312, 0), Location.create(2611, 4312, 0))); + WHEAT.add(new WheatSet(1, Location.create(2570, 4309, 0), Location.create(2569, 4309, 0))); + WHEAT.add(new WheatSet(0, Location.create(2583, 4304, 0), Location.create(2583, 4303, 0))); + } + + /** + * Handles the puro puro options. + * + * @author Vexia + */ + public class PuroOptionHandler extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + NPCDefinition.forId(6070).getHandlers().put("option:trade", this); + ItemDefinition.forId(11273).getHandlers().put("option:toggle-view", this); + ItemDefinition.forId(11258).getHandlers().put("option:butterfly-jar", this); + ItemDefinition.forId(11258).getHandlers().put("option:impling-jar", this); + ItemDefinition.forId(11258).getHandlers().put("option:check", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + switch (node.getId()) { + case 11258: + handleJarGenerator(player, (Item) node, option); + break; + case 6070: + ElnockInquisitorDialogue.openShop(player); + break; + case 11273: + if (!player.getZoneMonitor().isInZone("puro puro")) { + player.sendMessage("You can only use this in the Puro Puro Maze."); + break; + } else { + if (player.getInterfaceManager().getOverlay() != null) { + player.getInterfaceManager().closeOverlay(); + break; + } + + player.getInterfaceManager().openOverlay(new Component(169)); + } + return true; + } + return true; + } + + /** + * Handles the jar generator. + * + * @param player the player. + * @param item the item. + * @param option the option. + */ + private void handleJarGenerator(Player player, Item item, String option) { + switch (option) { + case "butterfly-jar": + case "impling-jar": + generate(player, item, option); + break; + case "check": + player.sendMessage("Your jar generator has a charge percentage of " + getPercent(item) + "."); + break; + } + } + + /** + * Generates a new jar. + * + * @param player the player. + * @param item the item. + * @param option the option. + */ + private void generate(Player player, Item item, String option) { + final Item jar = option.equals("butterfly-jar") ? new Item(10012) : new Item(11260); + final int percent = jar.getId() == 10012 ? 1 : 3; + if (!hasPercent(item, percent)) { + player.sendMessage("Your jar generator doesn't have enough charges to make another " + jar.getName().toLowerCase() + "."); + return; + } + player.lock(5); + player.animate(new Animation(6592)); + player.getInventory().add(jar); + setPercent(item, percent); + player.sendMessage("Your jar generator generates a " + jar.getName().toLowerCase() + "."); + if (getPercent(item) <= 0) { + player.getInventory().remove(item); + player.sendMessage("Your jar generator runs out of charges."); + } + } + + /** + * Checks if the player has the percent. + * + * @param item the item. + * @param percent the percent. + * @return + */ + private boolean hasPercent(Item item, int percent) { + return getPercent(item) - percent >= 0; + } + + /** + * The percent to set. + * + * @param item the item. + * @param percent the percent. + */ + private void setPercent(Item item, int percent) { + item.setCharge(item.getCharge() - percent); + } + + /** + * Gets the percent. + * + * @param item the item. + * @return the percent. + */ + private int getPercent(Item item) { + int difference = item.getCharge() - 1000; + return difference + 100; + } + + @Override + public boolean isWalk(Player p, Node n) { + return !(n instanceof Item); + + } + + @Override + public boolean isWalk() { + return false; + } + } + + /** + * A wheat set. + */ + public static class WheatSet { + + /** + * The locations of the wheat. + */ + private final Location[] locations; + + /** + * The scenerys. + */ + private Scenery[] objects = new Scenery[2]; + + /** + * The rotation. + */ + private int rot; + + /** + * The time until the next whilt. + */ + private int nextWhilt; + + /** + * The busy ticks. + */ + private int busyTicks; + + /** + * If the wheat is removed. + */ + private boolean removed; + + /** + * Constructs a new {@code WheatSet} {@code Object}. + * + * @param locations the locations. + */ + public WheatSet(int rot, Location... locations) { + this.rot = rot; + this.locations = locations; + } + + /** + * Initializes the wheat. + */ + public void init() { + int index = 0; + for (Location location : locations) { + Scenery object = new Scenery(25021, location, 22, rot); + SceneryBuilder.add(object); + objects[index] = object; + index++; + } + setNextWhilt(); + } + + /** + * Whilts the wheat. + */ + public void whilt() { + busyTicks = GameWorld.getTicks() + 5; + for (Scenery object : objects) { + if (object == null) { + continue; + } + if (removed) { + submitWorldPulse(new Pulse() { + int counter = 0; + + @Override + public boolean pulse() { + if (counter++ == 0) { + animateScenery(object, 6596); + setDelay(animationDuration(new Animation(6596))); + return false; + } + return true; + } + }); + SceneryBuilder.add(object); + continue; + } + submitWorldPulse(new Pulse() { + int counter = 0; + + @Override + public boolean pulse() { + if (counter++ == 0) { + animateScenery(object, 6599); + setDelay(animationDuration(new Animation(6599))); + return false; + } + SceneryBuilder.remove(object); + return true; + } + }); + } + removed = !removed; + setNextWhilt(); + } + + /** + * Sets the object spawns. + */ + public void setObjects() { + for (int i = 0; i < locations.length; i++) { + objects[i] = RegionManager.getObject(locations[i]); + } + } + + /** + * Sets the next whilt. + */ + public void setNextWhilt() { + this.nextWhilt = GameWorld.getTicks() + RandomFunction.random(40, 300); + } + + /** + * Checks if the wheat can whilt. + * + * @return {@code True} if so. + */ + public boolean canWhilt() { + return GameWorld.getTicks() > nextWhilt && GameWorld.getTicks() > busyTicks; + } + + /** + * Gets the nextWhilt. + * + * @return The nextWhilt. + */ + public int getNextWhilt() { + return nextWhilt; + } + + /** + * Sets the nextWhilt. + * + * @param nextWhilt The nextWhilt to set. + */ + public void setNextWhilt(int nextWhilt) { + this.nextWhilt = nextWhilt; + } + + /** + * Gets the locations. + * + * @return The locations. + */ + public Location[] getLocations() { + return locations; + } + + } + +} diff --git a/Server/src/main/content/minigame/puropuro/WanderingImplingDialogue.java b/Server/src/main/content/minigame/puropuro/WanderingImplingDialogue.java new file mode 100644 index 0000000..2eabd01 --- /dev/null +++ b/Server/src/main/content/minigame/puropuro/WanderingImplingDialogue.java @@ -0,0 +1,91 @@ +package content.minigame.puropuro; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; + +/** + * Handles the wandering imp dialogue. + * @author Vexia + */ +public final class WanderingImplingDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code WanderingImplingDialogue} {@code Object}. + */ + public WanderingImplingDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code WanderingImplingDialogue} {@code Object}. + * @param player the player. + */ + public WanderingImplingDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new WanderingImplingDialogue(player); + } + + @Override + public boolean open(Object... args) { + player("Hello. So, what is this place?"); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + npc("This is my home, mundane human! What do you have", "in your pockets? Something tasty?"); + stage++; + break; + case 1: + player("Stay out of my pockets! I don't have anything that you", "want."); + stage++; + break; + case 2: + npc("Ah, but do you have anything that *you* want?"); + stage++; + break; + case 3: + player("Of course I do!"); + stage++; + break; + case 4: + npc("Then you have something that implings want."); + stage++; + break; + case 5: + player("Eh?"); + stage++; + break; + case 6: + npc("We want things you people want. They are tasty to us!", "The more you want them, the tastier they are!"); + stage++; + break; + case 7: + player("So, you collect things that humans want? Interesting...", "So, what would happen if I caught an impling in a", "butterfly net?"); + stage++; + break; + case 8: + npc("Don't do that! That would be cruel. But chase us, yes!", "That is good. Implings that are not easy to catch. Especially", "ones with tasty food."); + stage++; + break; + case 9: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 6073 }; + } + +} diff --git a/Server/src/main/content/minigame/pyramidplunder/GuardianMummyDialogue.kt b/Server/src/main/content/minigame/pyramidplunder/GuardianMummyDialogue.kt new file mode 100644 index 0000000..b342116 --- /dev/null +++ b/Server/src/main/content/minigame/pyramidplunder/GuardianMummyDialogue.kt @@ -0,0 +1,74 @@ +package content.minigame.pyramidplunder + +import core.api.setAttribute +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs +import core.tools.END_DIALOGUE + +@Initializable +class GuardianMummyDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun open(vararg args: Any?): Boolean { + npcl(FacialExpression.OLD_NOT_INTERESTED, "*sigh* Not another one.") + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> playerl(FacialExpression.HALF_ASKING, "Another what?").also { stage++ } + 1 -> npcl(FacialExpression.OLD_NOT_INTERESTED, "Another 'archaeologist'. I'm not going to let you plunder my master's tomb you know.").also { stage++ } + 2 -> playerl(FacialExpression.NEUTRAL, "That's a shame. Have you got anything else I could do while I'm here?").also { stage++ } + 3 -> npcl(FacialExpression.OLD_NOT_INTERESTED, "If it will keep you out of mischief I suppose I could set something up for you... I have a few rooms full of some things you humans might consider valuable, do you want to give it a go?").also { stage++ } + 4 -> player.dialogueInterpreter.sendOptions("Play Pyramid Plunder?", "That sounds like fun; what do I do?", "Not right now.", "I know what I'm doing, so let's get on with it.").also { stage++ } + 5 -> when(buttonId) + { + 1 -> playerl(FacialExpression.FRIENDLY, "That sounds like fun; what do I do?").also { stage = 10 } + 2 -> playerl(FacialExpression.NEUTRAL, "Not right now.").also { stage = END_DIALOGUE } + 3 -> playerl(FacialExpression.ANNOYED, "I know what I'm doing, so let's get on with it.").also { stage = 100 } + } + + 10 -> npcl(FacialExpression.OLD_NOT_INTERESTED, "You have five minutes to explore the treasure rooms and collect as many artefacts as you can. The artefacts are in the urns, chests and sarcophagi found in each room.").also { stage++ } + 11 -> npcl(FacialExpression.OLD_NOT_INTERESTED, "There are eight treasure rooms, each subsequent room requires higher thieving skills to both enter the room and thieve from the urns and other containers.").also { stage++ } + 12 -> npcl(FacialExpression.OLD_NOT_INTERESTED, "The rewards also become more lucrative the further into the tomb you go. You will also have to deactivate a trap in order to enter the main part of each room.").also { stage++ } + 13 -> npcl(FacialExpression.OLD_NOT_INTERESTED, "When you want to move onto the next room you need to find the correct door first.").also { stage++ } + 14 -> npcl(FacialExpression.OLD_NOT_INTERESTED, "There are four possible exits... you must open the door before finding out whether it is the exit or not. Opening the doors require picking their locks. Having a lockpick will make this easier.").also { stage++ } + 15 -> player.dialogueInterpreter.sendOptions("Do you have any more questions?", "How do I leave the game?", "How do I get the artefacts?", "What do I do with the artefacts I collect?", "I'm ready to give it a go now.").also { stage++ } + 16 -> when(buttonId) + { + 1 -> playerl(FacialExpression.FRIENDLY, "How do I leave the game?").also { stage = 20 } + 2 -> playerl(FacialExpression.FRIENDLY, "How do I get the artefacts?").also { stage = 30 } + 3 -> playerl(FacialExpression.FRIENDLY, "What do I do with the artefacts?").also { stage = 40 } + 4 -> playerl(FacialExpression.FRIENDLY, "I'm ready to give it a go now.").also { stage = 100 } + } + + 20 -> npcl(FacialExpression.OLD_NOT_INTERESTED, "If at any point you decide you need to leave just use a glowing door. The game will end and you will be taken out of the pyramid").also { stage = 15 } + + 30 -> npcl(FacialExpression.OLD_NOT_INTERESTED, "The artefacts are in the urns, chests and sarcophagi. Urns contain snakes that guard them. The sarcophagi take some strength to open. They take a while to open.").also { stage++ } + 31 -> npcl(FacialExpression.OLD_NOT_INTERESTED, "Of course, Mummies have been known to take a nap in the sarcophagi, so beware. The golden chests generally contain better artefacts, but are also trapped with scarabs!").also { stage = 15 } + + 40 -> npcl(FacialExpression.OLD_NOT_INTERESTED, "There are a number of different artefacts, of three main types. The least valuable are the pottery statuettes and scarabs, and the ivory combs.").also { stage++ } + 41 -> npcl(FacialExpression.OLD_NOT_INTERESTED, "Next are the stone scarabs, statuettes and seals, and finally the gold versions of those artefacts. They are not old, but are well made.").also { stage++ } + 42 -> playerl(FacialExpression.HALF_ASKING, "What do I do with artefacts once I've collected them?").also { stage++ } + 43 -> npcl(FacialExpression.OLD_NOT_INTERESTED, "That Simon Simpleton, I mean Templeton, will probably give you some money for them. He couldn't spot a real artefact if it came up to him and bit him in the face.").also { stage++ } + 44 -> npcl(FacialExpression.OLD_NOT_INTERESTED, "He usually slinks about near the pyramid north-east of Sophanem. I expect he's trying to get some poor fools to steal things from that pyramid as well.").also { stage = 15 } + + 100 -> npcl(FacialExpression.OLD_NOT_INTERESTED, "Alright, fine.").also { stage++ } + 101 -> { + end() + PyramidPlunderMinigame.join(player) + setAttribute(player, "/save:pp:mummy-spoken-to", true) + } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.GUARDIAN_MUMMY_4476) + } + + override fun newInstance(player: Player?): DialoguePlugin { + return GuardianMummyDialogue(player) + } +} \ No newline at end of file diff --git a/Server/src/main/content/minigame/pyramidplunder/PharaohSceptre.kt b/Server/src/main/content/minigame/pyramidplunder/PharaohSceptre.kt new file mode 100644 index 0000000..a295a87 --- /dev/null +++ b/Server/src/main/content/minigame/pyramidplunder/PharaohSceptre.kt @@ -0,0 +1,126 @@ +package content.minigame.pyramidplunder + +import core.api.* +import core.game.world.GameWorld.Pulser +import content.minigame.pyramidplunder.PyramidPlunderMinigame.Companion.GUARDIAN_ROOM +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import org.rs09.consts.Items +import core.game.dialogue.DialogueFile +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import content.data.Quests + +/** + * Adds functionality to the pharoah's scepter + * @author ceik + */ +class PharaohSceptre : InteractionListener { + override fun defineListeners() { + val SCEPTRES = intArrayOf(Items.PHARAOHS_SCEPTRE_9044, Items.PHARAOHS_SCEPTRE_9046, Items.PHARAOHS_SCEPTRE_9048, Items.PHARAOHS_SCEPTRE_9050) + + on(SCEPTRES, IntType.ITEM, "teleport", "operate"){ player, node -> + if (!hasRequirement(player, Quests.ICTHLARINS_LITTLE_HELPER)) + return@on true + + val sceptre = node.asItem() + + if(sceptre.id == SCEPTRES.last()) + { + sendMessage(player, "You have used up all the charges on this sceptre.") + return@on true + } + + openDialogue(player, SceptreDialog()) + return@on true + } + } + + class SceptreDialog : DialogueFile() { + fun teleport(location: Location?, player: Player) { + player.lock() + player.visualize(ANIMATION, GRAPHICS) + player.impactHandler.disabledTicks = 4 + Pulser.submit(object : Pulse(4, player) { + override fun pulse(): Boolean { + player.unlock() + player.properties.teleportLocation = location + player.animator.reset() + return true + } + }) + } + + override fun handle(componentID: Int, buttonID: Int) { + if (player!!.isTeleBlocked) { + player!!.sendMessage("A magical force has stopped you from teleporting.") + return + } + when (stage) { + 0 -> options("Jalsavrah", "Jaleustrophos", "Jaldraocht", "Nowhere").also { stage++ } + 1 -> { + end() + when (buttonID) { + 1 -> { + teleport(GUARDIAN_ROOM, player!!) + } + 2 -> { + teleport(Location.create(3342, 2827, 0), player!!) + } + 3 -> { + teleport(Location.create(3233, 2902, 0), player!!) + } + 4 -> return + } + //Checks the equipment slot. 9044 = full, 9046 = 2 charges, 9048 = 1 charge, 9050 = 0 charges. + if (player!!.equipment.containsItem(Item(Items.PHARAOHS_SCEPTRE_9044))) + { + player!!.equipment.replace(Item(Items.PHARAOHS_SCEPTRE_9046), EquipmentSlot.WEAPON.ordinal) + player!!.packetDispatch.sendMessage("Your Pharoah's Sceptre has 2 charges remaining.") + } + else if (player!!.equipment.containsItem(Item(Items.PHARAOHS_SCEPTRE_9046))) + { + player!!.equipment.replace(Item(Items.PHARAOHS_SCEPTRE_9048), EquipmentSlot.WEAPON.ordinal) + player!!.packetDispatch.sendMessage("Your Pharoah's Sceptre has 1 charge remaining.") + } + else if (player!!.equipment.containsItem(Item(Items.PHARAOHS_SCEPTRE_9048))) + { + player!!.equipment.replace(Item(Items.PHARAOHS_SCEPTRE_9050), EquipmentSlot.WEAPON.ordinal) + player!!.packetDispatch.sendMessage("Your Pharoah's Sceptre has no charges remaining.") + } + //Checks the inventory. 9044 = full, 9046 = 2 charges, 9048 = 1 charge, 9050 = 0 charges. + else if (player!!.inventory.containsItem(Item(Items.PHARAOHS_SCEPTRE_9044))) + { + if (player!!.inventory.remove(Item(Items.PHARAOHS_SCEPTRE_9044))) { + player!!.inventory.add(Item(Items.PHARAOHS_SCEPTRE_9046)) + player!!.packetDispatch.sendMessage("Your Pharoah's Sceptre has 2 charges remaining.") + } + } + else if (player!!.inventory.containsItem(Item(Items.PHARAOHS_SCEPTRE_9046))) + { + if (player!!.inventory.remove(Item(Items.PHARAOHS_SCEPTRE_9046))) { + player!!.inventory.add(Item(Items.PHARAOHS_SCEPTRE_9048)) + player!!.packetDispatch.sendMessage("Your Pharoah's Sceptre has 1 charge remaining.") + } + } + else if (player!!.inventory.containsItem(Item(Items.PHARAOHS_SCEPTRE_9048))) + { + if (player!!.inventory.remove(Item(Items.PHARAOHS_SCEPTRE_9048))) { + player!!.inventory.add(Item(Items.PHARAOHS_SCEPTRE_9050)) + player!!.packetDispatch.sendMessage("Your Pharoah's Sceptre has no charges remaining.") + } + } + } + } + } + } + + companion object { + private val GRAPHICS = Graphics(715) + private val ANIMATION = Animation(714) + } +} diff --git a/Server/src/main/content/minigame/pyramidplunder/PlunderData.kt b/Server/src/main/content/minigame/pyramidplunder/PlunderData.kt new file mode 100644 index 0000000..bf8b622 --- /dev/null +++ b/Server/src/main/content/minigame/pyramidplunder/PlunderData.kt @@ -0,0 +1,45 @@ +package content.minigame.pyramidplunder + +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.world.map.Direction +import core.game.world.map.Location +import org.rs09.consts.Items + +/** + * An object that simply contains Pyramid Plunder data. + */ +object PlunderData { + val playerLocations = HashMap() + val players = ArrayList() + val doorVarbits = arrayOf(2366, 2367, 2368, 2369) + val doors = Array(8){ doorVarbits[0]} + val timeLeft = HashMap() + + val pyramidEntranceVarbits = arrayOf(2371,2372,2373,2374) + var currentEntrance = pyramidEntranceVarbits.random() + var nextEntranceSwitch = 0L + val mummy = NPC(4476, Location.create(1968, 4428, 2)).also { it.isNeverWalks = true; it.init() } + + val artifacts = arrayOf( + arrayOf(Items.IVORY_COMB_9026, Items.POTTERY_SCARAB_9032, Items.POTTERY_STATUETTE_9036), + arrayOf(Items.STONE_SCARAB_9030, Items.STONE_STATUETTE_9038, Items.STONE_SEAL_9042), + arrayOf(Items.GOLDEN_SCARAB_9028, Items.GOLDEN_STATUETTE_9034, Items.GOLD_SEAL_9040) + ) + + val rooms = arrayOf( + PlunderRoom(1, Location.create(1927, 4477, 0), Location.create(1929, 4469, 0), Direction.SOUTH), + PlunderRoom(2, Location.create(1954, 4477, 0), Location.create(1955, 4467, 0), Direction.SOUTH), + PlunderRoom(3, Location.create(1977, 4471, 0), Location.create(1975, 4458, 0), Direction.SOUTH), + PlunderRoom(4, Location.create(1927, 4453, 0), Location.create(1937, 4454, 0), Direction.EAST), + PlunderRoom(5, Location.create(1965, 4444, 0), Location.create(1955, 4449, 0), Direction.WEST), + PlunderRoom(6, Location.create(1927, 4424, 0), Location.create(1925, 4433, 0), Direction.NORTH), + PlunderRoom(7, Location.create(1943, 4421, 0), Location.create(1950, 4427, 0), Direction.NORTH), + PlunderRoom(8, Location.create(1974, 4420, 0), Location.create(1971, 4431, 0), Direction.NORTH) + ) +} + +/** + * A simple way to represent a pyramid plunder room. + */ +data class PlunderRoom(val room: Int, val entrance: Location, val mummyLoc: Location, val spearDirection: Direction) \ No newline at end of file diff --git a/Server/src/main/content/minigame/pyramidplunder/PlunderUtils.kt b/Server/src/main/content/minigame/pyramidplunder/PlunderUtils.kt new file mode 100644 index 0000000..896a087 --- /dev/null +++ b/Server/src/main/content/minigame/pyramidplunder/PlunderUtils.kt @@ -0,0 +1,309 @@ +package content.minigame.pyramidplunder + +import core.api.* +import core.game.component.Component +import core.game.node.Node +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.world.map.Direction +import core.game.world.map.Location +import core.tools.RandomFunction +import org.rs09.consts.Components +import org.rs09.consts.Items + +/** + * A collection of methods needed for Pyramid Plunder. + */ +object PlunderUtils { + fun hasPlayer(player: Player): Boolean + { + return PlunderData.playerLocations[player] != null + } + + fun registerPlayer(player: Player) + { + PlunderData.players.add(player) + PlunderData.timeLeft[player] = 500 //5 minutes + } + + fun unregisterPlayer(player: Player) + { + PlunderData.players.remove(player) + PlunderData.playerLocations.remove(player) + PlunderData.timeLeft.remove(player) + } + + fun expel(player: Player, summonMummy: Boolean) + { + teleport(player, Location.create(3288, 2802, 0)) + unregisterPlayer(player) + resetOverlay(player) + resetObjectVarbits(player) + + if(!summonMummy) + { + sendDialogue(player, "You've run out of time and the guardian mummy has thrown you out.") + } + else + { + sendDialogue(player, "You've been expelled by the guardian mummy.") + } + } + + fun decrementTimeRemaining() : ArrayList + { + val timesUp = ArrayList() + PlunderData.timeLeft.forEach { player, left -> + if(left <= 0) timesUp.add(player) + PlunderData.timeLeft[player] = left - 1 + updateOverlay(player) + } + return timesUp + } + + fun loadNextRoom(player: Player) + { + val current = PlunderData.playerLocations[player] + + val next: PlunderRoom = if(current == null) + getRoom(1) + else + getRoom(current.room + 1) + + if(PlunderData.playerLocations.filter { it.value == next }.isEmpty()) //if no one is in the next room + { + PlunderData.doors[next.room - 1] = PlunderData.doorVarbits.random() //reshuffle the next room's exit door + } + + teleport(player, next.entrance) + PlunderData.playerLocations[player] = next + } + + fun getRoom(number: Int) : PlunderRoom + { + return PlunderData.rooms[number - 1] + } + + fun getRoom(player: Player): PlunderRoom? + { + return PlunderData.playerLocations[player] + } + + fun getRoomLevel(player: Player): Int + { + return 11 + (10 * getRoom(player)!!.room) + } + + fun getSpearDestination(player: Player): Location + { + val room = getRoom(player)!! + return when(room.spearDirection) + { + Direction.NORTH -> player.location.transform(0, 3, 0) + Direction.SOUTH -> player.location.transform(0, -3, 0) + Direction.WEST -> player.location.transform(-3, 0, 0) + Direction.EAST -> player.location.transform(3, 0, 0) + else -> player.location + } + } + + fun getUrnXp(player: Player, check: Boolean): Double + { + val room = getRoom(player)!!.room + return if(check) + { + when(room) + { + 1 -> 20.0 + 2 -> 30.0 + 3 -> 50.0 + 4 -> 70.0 + 5 -> 100.0 + 6 -> 150.0 + 7 -> 225.0 + 8 -> 275.0 + else -> 0.0 + } + } + else + { + when(room) + { + 1 -> 60.0 + 2 -> 90.0 + 3 -> 150.0 + 4 -> 215.0 + 5 -> 300.0 + 6 -> 450.0 + 7 -> 675.0 + 8 -> 825.0 + else -> 0.0 + } + } + } + + fun resetObjectVarbits(player: Player) + { + setVarp(player, 821, 0) + setVarp(player, 820, 0) + PlunderData.doorVarbits.forEach { setVarbit(player, it, 0) } + } + + fun openOverlay(player: Player) + { + player.interfaceManager.openOverlay(Component(Components.NTK_OVERLAY_428)) + updateOverlay(player) + } + + fun updateOverlay(player: Player) + { + setVarbit(player, 2375, 500 - (PlunderData.timeLeft[player] ?: 0)) + setVarbit(player, 2376, 11 + (getRoom(player)!!.room * 10)) + setVarbit(player, 2377, getRoom(player)!!.room) + } + + fun resetOverlay(player: Player) + { + setVarbit(player, 2375, 0) + player.packetDispatch.resetInterface(Components.NTK_OVERLAY_428) + player.interfaceManager.closeOverlay() + } + + fun getDoor(player: Player) : Int + { + if (getRoom(player) == null) + return -1 + val room = getRoom(player)!!.room + return PlunderData.doors[room - 1] + } + + fun rollSceptre(player: Player): Boolean + { + val room = getRoom(player)!!.room + val chance = when(room) + { + 1 -> 1500 + 2 -> 1350 + 3 -> 1250 + 4 -> 1150 + else -> 1000 + } + + if(RandomFunction.roll(chance)) + { + expel(player, true) + runTask(player, 2) + { + addItemOrDrop(player, Items.PHARAOHS_SCEPTRE_9050) + sendNews("${player.username} has received a Pharaoh's Sceptre while doing Pyramid Plunder!") + } + return true + } + return false + } + + fun getSarcophagusXp(player: Player) : Double + { + val room = getRoom(player)!!.room + return when(room) + { + 1 -> 20.0 + 2 -> 30.0 + 3 -> 50.0 + 4 -> 70.0 + 5 -> 100.0 + 6 -> 150.0 + 7 -> 225.0 + 8 -> 275.0 + else -> 0.0 + } + } + + fun getChestXp(player: Player): Double + { + if (getRoom(player) == null) { + expel(player, false) + return 0.0 + } + val room = getRoom(player)!!.room + return when(room) + { + 1 -> 60.0 + 2 -> 90.0 + 3 -> 150.0 + 4 -> 215.0 + 5 -> 300.0 + 6 -> 450.0 + 7 -> 675.0 + 8 -> 825.0 + else -> 0.0 + } * 0.66 + } + + fun getDoorXp(player: Player, lockpick: Boolean) : Double + { + val room = getRoom(player)?.room ?: return 0.0 + var reward = when(room) + { + 1 -> 60.0 + 2 -> 90.0 + 3 -> 150.0 + 4 -> 215.0 + 5 -> 300.0 + 6 -> 450.0 + 7 -> 675.0 + 8 -> 825.0 + else -> 0.0 + } * 0.66 + + if(lockpick) + reward /= 2.0 + + return reward + } + + fun rollArtifact(player: Player, tier: Int) : Int + { + //tier 1 -> urn + //tier 2 -> sarcophagus + //tier 3 -> chest + val room = getRoom(player)!!.room + val divisor = (room * 2) * (tier * 35) + val goldRate = divisor / 650.0 + val stoneRate = divisor / 250.0 + + val roll = RandomFunction.RANDOM.nextDouble() + if(goldRate > roll) + return PlunderData.artifacts[2].random() + if(stoneRate > roll) + return PlunderData.artifacts[1].random() + return PlunderData.artifacts[0].random() + } + + fun checkEntranceSwitch() + { + if(System.currentTimeMillis() > PlunderData.nextEntranceSwitch) + { + PlunderData.currentEntrance = PlunderData.pyramidEntranceVarbits.random() + PlunderData.nextEntranceSwitch = System.currentTimeMillis() + (60000 * 15) + + } + } + + fun checkEntrance(door: Node): Boolean + { + return door.asScenery().definition.varbitID == PlunderData.currentEntrance + } + + fun rollUrnSuccess(player: Player, charmed: Boolean = false): Boolean + { + val level = getDynLevel(player, Skills.THIEVING) + + if (getRoom(player) == null) { + return false + } + + val room = getRoom(player)!!.room + return RandomFunction.random(level) > (room * if(charmed) 2 else 4) + } +} diff --git a/Server/src/main/content/minigame/pyramidplunder/PyramidPlunderMinigame.kt b/Server/src/main/content/minigame/pyramidplunder/PyramidPlunderMinigame.kt new file mode 100644 index 0000000..057e5a9 --- /dev/null +++ b/Server/src/main/content/minigame/pyramidplunder/PyramidPlunderMinigame.kt @@ -0,0 +1,395 @@ +package content.minigame.pyramidplunder + +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.system.task.Pulse +import core.game.world.map.Direction +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.tools.RandomFunction +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery +import core.game.dialogue.DialogueFile +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + + +/** + * The "controller" class for pyramid plunder. Handles per-tick updates, logout hooks, and defines interaction listeners for the minigame. + * @author Ceikry + */ +class PyramidPlunderMinigame : InteractionListener, TickListener, LogoutListener { + override fun tick() { + val playersToExpel = PlunderUtils.decrementTimeRemaining() + playersToExpel.forEach {player -> PlunderUtils.expel(player, false) } + PlunderUtils.checkEntranceSwitch() + } + + override fun logout(player: Player) { + if(PlunderUtils.hasPlayer(player)) + { + player.location = Location.create(3288, 2802, 0) + PlunderUtils.unregisterPlayer(player) + } + } + + override fun defineListeners() { + val CHECK_ANIM = 3572 + val URN_CHECK = 4340 + val URN_BIT = 4341 + val URN_SUCCESS = 4342 + val PUSH_LID_START = 4343 + val PUSH_LID_LOOP = 4344 + val PUSH_LID_FINISH = 4345 + val CHARM_ANIM = 1877 + val OPEN_CHEST_ANIM = 536 + + val SPEAR_OBJ_ANIM = 459 + val SNAKE_URN_ANIM = 4335 + + val SEALED_URNS = intArrayOf(Scenery.URN_16501, Scenery.URN_16502, Scenery.URN_16503) + val OPEN_URNS = intArrayOf(Scenery.URN_16505, Scenery.URN_16506, Scenery.URN_16507) + val SNAKE_URNS = intArrayOf(Scenery.URN_16509, Scenery.URN_16510, Scenery.URN_16511) + val CHARMED_SNAKES = intArrayOf(Scenery.URN_16513, Scenery.URN_16514, Scenery.URN_16515) + val ENTRANCES = intArrayOf(16484, 16487, 16490, 16493) //All Scenery.AN_ANONYMOUS_LOOKING_DOOR_16484/etc + val SARCOPHAGUS = Scenery.SARCOPHAGUS_16495 + + on(Scenery.SPEARTRAP_16517, IntType.SCENERY, "pass"){ player, node -> + val anim = Animation(CHECK_ANIM) + val duration = animationDuration(anim) + + if(player.skills.getStaticLevel(Skills.THIEVING) < PlunderUtils.getRoomLevel(player)) + { + sendDialogue(player, "You need a Thieving level of ${PlunderUtils.getRoomLevel(player)} to do that.") + return@on true + } + + val spearDir = PlunderUtils.getRoom(player)!!.spearDirection + + val pastSpears = (spearDir == Direction.NORTH && player.location.y > node.location.y) + || (spearDir == Direction.SOUTH && player.location.y < node.location.y) + || (spearDir == Direction.EAST && player.location.x > node.location.x) + || (spearDir == Direction.WEST && player.location.x < node.location.x) + + if(pastSpears) + { + sendDialogue(player, "I have no reason to do that.") + return@on true + } + + animate(player, anim) + sendMessage(player, "You carefully try to temporarily disable the trap.") + player.pulseManager.run(object : Pulse(duration) { + override fun pulse(): Boolean { + if(RandomFunction.roll(5)) + { + val dest = PlunderUtils.getSpearDestination(player) + player.walkingQueue.reset() + player.walkingQueue.addPath(dest.x,dest.y) + rewardXP(player, Skills.THIEVING, 10.0) + return true + } + if(RandomFunction.roll(20)) + { + animateScenery(node.asScenery(), SPEAR_OBJ_ANIM) + impact(player, RandomFunction.random(1,5)) + sendChat(player, "Ouch!") + sendMessage(player, "You fail to disable the trap.") + return true + } + animate(player, anim) + return false + } + }) + return@on true + } + + on(intArrayOf(*SEALED_URNS, *SNAKE_URNS), IntType.SCENERY, "search") { player, node -> + animate(player, URN_CHECK) + player.faceLocation(node.location) + lock(player, 1) + runTask(player, 1) { + if(!PlunderUtils.rollUrnSuccess(player)) + { + animate(player, URN_BIT) + sendMessage(player, "You've been bitten by something moving around in the urn.") + impact(player, RandomFunction.random(1,5)) + applyPoison(player, player, 2) + } + else { + animate(player, URN_SUCCESS) + sendMessage(player, "You successfully loot the urn.") + rewardXP(player, Skills.THIEVING, PlunderUtils.getUrnXp(player, false)) + addItemOrDrop(player, PlunderUtils.rollArtifact(player, 1)) + setVarbit(player, node.asScenery().definition.varbitID, 1) + } + } + return@on true + } + + on(SEALED_URNS, IntType.SCENERY, "check for snakes") { player, node -> + val urn = node.asScenery() + animate(player, URN_CHECK) + player.faceLocation(node.location) + lock(player, 1) + runTask(player, 1){ + animate(player, URN_BIT) + setVarbit(player, urn.definition.varbitID, 2) + animateScenery(urn, SNAKE_URN_ANIM) + } + return@on true + } + + on(SNAKE_URNS, IntType.SCENERY, "charm snake") { player, node -> + if(!inInventory(player, Items.SNAKE_CHARM_4605)) + { + sendMessage(player, "You need a snake charm to charm a snake.") + return@on true + } + lock(player, 2) + animate(player, CHARM_ANIM) + runTask(player, 1) + { + setVarbit(player, node.asScenery().definition.varbitID, 3) + sendMessage(player, "You charm the snake with your music.") + } + return@on true + } + + on(CHARMED_SNAKES, IntType.SCENERY, "search") { player, node -> + animate(player, URN_CHECK) + player.faceLocation(node.location) + lock(player, 1) + runTask(player, 1) { + if(!PlunderUtils.rollUrnSuccess(player, true)) + { + animate(player, URN_BIT) + sendMessage(player, "You've been bitten by something moving around in the urn.") + impact(player, RandomFunction.random(1,5)) + applyPoison(player, player, 2) + } + else { + animate(player, URN_SUCCESS) + sendMessage(player, "You successfully loot the urn.") + addItemOrDrop(player, PlunderUtils.rollArtifact(player, 1)) + rewardXP(player, Skills.THIEVING, PlunderUtils.getUrnXp(player, false) * 0.66) + setVarbit(player, node.asScenery().definition.varbitID, 1) + } + } + return@on true + } + + on(OPEN_URNS, IntType.SCENERY, "search") { player, _ -> + sendMessage(player, "You've already looted this urn.") + return@on true + } + + on(SARCOPHAGUS, IntType.SCENERY, "open") { player, node -> + if (PlunderUtils.getRoom(player) == null) { + PlunderUtils.expel(player, false) + return@on true + } + sendMessage(player, "You attempt to push open the massive lid.") + val strength = getDynLevel(player, Skills.STRENGTH) + animate(player, PUSH_LID_START) + player.pulseManager.run(object : Pulse(2) + { + override fun pulse(): Boolean { + animate(player, PUSH_LID_LOOP) + if(RandomFunction.random(125) > strength) + return false + animate(player, PUSH_LID_FINISH) + if (PlunderUtils.getRoom(player) == null) { + PlunderUtils.expel(player, false) + return true + } + runTask(player, 3){ + setVarbit(player, node.asScenery().definition.varbitID, 1) + rewardXP(player, Skills.STRENGTH, PlunderUtils.getSarcophagusXp(player)) + if(RandomFunction.roll(25)) + { + val mummy = PyramidPlunderMummyNPC(player.location, player) + mummy.isRespawn = false + mummy.init() + mummy.attack(player) + } + else if(!PlunderUtils.rollSceptre(player)) + { + addItemOrDrop(player, PlunderUtils.rollArtifact(player, 2)) + } + } + return true + } + }) + return@on true + } + + on(Scenery.GRAND_GOLD_CHEST_16473, IntType.SCENERY, "search") { player, node -> + if (PlunderUtils.getRoom(player) == null) { + PlunderUtils.expel(player, false) + return@on true + } + animate(player, OPEN_CHEST_ANIM) + runTask(player){ + if(RandomFunction.roll(25)) + { + val swarm = PyramidPlunderSwarmNPC(player.location, player) + swarm.isRespawn = false + swarm.init() + swarm.attack(player) + impact(player, RandomFunction.random(1,5)) + } + else + { + rewardXP(player, Skills.THIEVING, PlunderUtils.getChestXp(player)) + if(!PlunderUtils.rollSceptre(player)) + addItemOrDrop(player, PlunderUtils.rollArtifact(player, 3)) + } + setVarbit(player, node.asScenery().definition.varbitID, 1) + } + return@on true + } + + on(Scenery.TOMB_DOOR_16475, IntType.SCENERY, "pick-lock") { player, node -> + val anim = Animation(CHECK_ANIM) + val duration = animationDuration(anim) + + if(PlunderUtils.getRoom(player)!!.room == 8) + { + sendMessage(player, "This is the final room. I should probably just leave instead.") + return@on true + } + + animate(player, anim) + lock(player, duration) + val rate = + if(inInventory(player, Items.LOCKPICK_1523)) + { + sendMessage(player, "You attempt to open the door.") + 2 + } + else + { + sendMessage(player, "You attempt to open the door. Lockpicks would make it easier...") + 3 + } + runTask(player, duration){ + if(RandomFunction.roll(rate)) + { + val varbitId = node.asScenery().definition.varbitID + val door = PlunderUtils.getDoor(player) + + if (door == -1) + PlunderUtils.expel(player, false) + else + rewardXP(player, Skills.THIEVING, PlunderUtils.getDoorXp(player, rate == 3)) + + if (door == varbitId) { + PlunderUtils.loadNextRoom(player) + PlunderUtils.resetObjectVarbits(player) + } else { + sendMessage(player, "The door leads to a dead end.") + setVarbit(player, varbitId, 1) + } + } + else + { + sendMessage(player, "Your attempt fails.") + } + } + return@on true + } + + on(Scenery.TOMB_DOOR_16458, IntType.SCENERY, "leave tomb") { player, _ -> + openDialogue(player, object : DialogueFile() + { + override fun handle(componentID: Int, buttonID: Int) { + when(stage) + { + 0 -> options("Yes, I'm sure I want to leave.", "No, never mind.").also { stage++ } + 1 -> when(buttonID) + { + 1 -> { + end() + teleport(player, Location.create(3288, 2802, 0)) + PlunderUtils.unregisterPlayer(player) + PlunderUtils.resetOverlay(player) + PlunderUtils.resetObjectVarbits(player) + } + 2 -> end() + } + } + } + }) + return@on true + } + + on(ENTRANCES, IntType.SCENERY, "search") { player, door -> + if(!getAttribute(player, "tarik-spoken-to", false)) + { + sendDialogue(player, "I should probably try to find out more about this place before I try to break in.") + return@on true + } + val anim = Animation(CHECK_ANIM) + val duration = animationDuration(anim) + + animate(player, anim) + sendMessage(player, "You use your thieving skills to search the stone panel.") + player.pulseManager.run(object : Pulse(duration){ + override fun pulse(): Boolean { + if(RandomFunction.roll(3)) + { + setAttribute(player, "pyramid-entrance", player.location.transform(0,0,0)) + sendMessage(player, "You find a door! You open it.") + if(PlunderUtils.checkEntrance(door)) { + teleport(player, GUARDIAN_ROOM) + rewardXP(player, Skills.THIEVING, 20.0) + } + else + teleport(player, EMPTY_ROOM) + + return true + } + animate(player, anim) + return false + } + }) + return@on true + } + + on(Scenery.TOMB_DOOR_16459, IntType.SCENERY, "leave tomb") { player, _ -> + teleport(player, getAttribute(player, "pyramid-entrance", Location.create(3288, 2802, 0))) + return@on true + } + + on(NPCs.GUARDIAN_MUMMY_4476, IntType.NPC, "start-minigame") { player, _ -> + if(!getAttribute(player, "pp:mummy-spoken-to", false)) + { + openDialogue(player, NPCs.GUARDIAN_MUMMY_4476) + return@on true + } + + join(player) + return@on true + } + } + + companion object { + @JvmStatic val GUARDIAN_ROOM = Location.create(1968, 4420, 2) + @JvmStatic val EMPTY_ROOM = Location.create(1934, 4450, 2) + + @JvmStatic fun join(player: Player) + { + if(PlunderUtils.hasPlayer(player)) + { + sendMessage(player, "[PLUNDER] You should never see this message. Please report this.") + return + } + PlunderUtils.registerPlayer(player) + PlunderUtils.loadNextRoom(player) + PlunderUtils.openOverlay(player) + } + } +} diff --git a/Server/src/main/content/minigame/pyramidplunder/PyramidPlunderMummyNPC.java b/Server/src/main/content/minigame/pyramidplunder/PyramidPlunderMummyNPC.java new file mode 100644 index 0000000..9d18d2b --- /dev/null +++ b/Server/src/main/content/minigame/pyramidplunder/PyramidPlunderMummyNPC.java @@ -0,0 +1,53 @@ +package content.minigame.pyramidplunder; +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.tools.RandomFunction; + +/** + * Handles the mummy NPC in pyramid plunder + * @author ceik + */ +public final class PyramidPlunderMummyNPC extends PyramidPlunderNPC { + + /** + * The swarm id. + */ + private static final int[] IDS = new int[] { 1958 }; + + public PyramidPlunderMummyNPC(Location location, Player player) { + super(IDS[0], location, player); + } + + @Override + public void init() { + super.init(); + setRespawn(false); + getProperties().getCombatPulse().attack(player); + sendChat("How dare you disturb my rest!"); + } + + @Override + public void handleTickActions() { + super.handleTickActions(); + if (!getProperties().getCombatPulse().isAttacking()) { + getProperties().getCombatPulse().attack(player); + } + if (getProperties().getCombatPulse().isAttacking()) { + if (RandomFunction.random(40) < 2) { + sendChat("Leave this place!"); + } + } + } + + @Override + public boolean isIgnoreMultiBoundaries(Entity victim) { + return victim == player; + } + + @Override + public int[] getIds() { + return IDS; + } + +} diff --git a/Server/src/main/content/minigame/pyramidplunder/PyramidPlunderNPC.java b/Server/src/main/content/minigame/pyramidplunder/PyramidPlunderNPC.java new file mode 100644 index 0000000..329887b --- /dev/null +++ b/Server/src/main/content/minigame/pyramidplunder/PyramidPlunderNPC.java @@ -0,0 +1,188 @@ +package content.minigame.pyramidplunder; + +import core.game.interaction.MovementPulse; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.impl.PulseType; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.map.path.Pathfinder; +import core.plugin.Plugin; + +/** + * Handles a Pyramid Plunder enemy, adapted from AntiMacroNPC.java by ceikry + * @author Vexia + */ +public abstract class PyramidPlunderNPC extends AbstractNPC { + + /** + * The player. + */ + protected final Player player; + + /** + * The quotes the npc will say(null if none) + */ + private String[] quotes; + + /** + * The counter representing speech cycles. + */ + private int count; + + /** + * The time until the next speech. + */ + private int nextSpeech; + + /** + * If the players time is up. + */ + protected boolean timeUp; + + /** + * The end time. + */ + private int endTime; + + /** + * Constructs a new {@code AntiMacroNPC} {@code Object}. + * @param id the id. + * @param location the location. + * @param player the player. + */ + public PyramidPlunderNPC(int id, Location location, Player player) { + super(id, location); + this.player = player; + this.endTime = (int) (GameWorld.getTicks() + (1000 / 0.6)); + } + + @Override + public void init() { + location = RegionManager.getSpawnLocation(player, this); + if (location == null) { + clear(); + return; + } + super.init(); + startFollowing(); + } + + @Override + public void handleTickActions() { + if (GameWorld.getTicks() > endTime) { + clear(); + } + if (!getLocks().isMovementLocked()) { + if (dialoguePlayer == null || !dialoguePlayer.isActive() || !dialoguePlayer.getInterfaceManager().hasChatbox()) { + dialoguePlayer = null; + } + } + if (!player.isActive() || !getLocation().withinDistance(player.getLocation(), 10)) { + handlePlayerLeave(); + } + if (!getPulseManager().hasPulseRunning()) { + startFollowing(); + } + if (quotes != null) { + if (nextSpeech < GameWorld.getTicks() && this.getDialoguePlayer() == null && !this.getLocks().isMovementLocked()) { + if (count > quotes.length - 1) { + return; + } + nextSpeech = (int) (GameWorld.getTicks() + (20 / 0.5)); + if (++count >= quotes.length) { + setTimeUp(true); + handleTimeUp(); + return; + } + } + } + } + + /** + * Called when the player is gone. + */ + public void handlePlayerLeave() { + clear(); + } + + /** + * Called when the quotes are finished. + */ + public void handleTimeUp() { + } + + @Override + public boolean isAttackable(Entity entity, CombatStyle style, boolean message) { + if (entity instanceof Player && entity != player) { + ((Player) entity).getPacketDispatch().sendMessage("It's not after you."); + return false; + } + return super.isAttackable(entity, style, message); + } + + @Override + public void onRegionInactivity() { + super.onRegionInactivity(); + clear(); + } + + @Override + public void clear() { + super.clear(); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return null; + } + + + + /** + * Starts following the player. + */ + public void startFollowing() { + getPulseManager().run(new MovementPulse(this, player, Pathfinder.DUMB) { + @Override + public boolean pulse() { + return false; + } + }, PulseType.STANDARD); + face(player); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + return super.newInstance(arg); + } + + /** + * Gets the player. + * @return The player. + */ + public Player getPlayer() { + return player; + } + + + /** + * Gets the timeUp. + * @return The timeUp. + */ + public boolean isTimeUp() { + return timeUp; + } + + /** + * Sets the timeUp. + * @param timeUp The timeUp to set. + */ + public void setTimeUp(boolean timeUp) { + this.timeUp = timeUp; + } + +} diff --git a/Server/src/main/content/minigame/pyramidplunder/PyramidPlunderSwarmNPC.java b/Server/src/main/content/minigame/pyramidplunder/PyramidPlunderSwarmNPC.java new file mode 100644 index 0000000..f2d9194 --- /dev/null +++ b/Server/src/main/content/minigame/pyramidplunder/PyramidPlunderSwarmNPC.java @@ -0,0 +1,53 @@ +package content.minigame.pyramidplunder; +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.tools.RandomFunction; + +/** + * Handles the swarm NPC in pyramid plunder + * @author ceik + */ +public final class PyramidPlunderSwarmNPC extends PyramidPlunderNPC { + + /** + * The swarm id. + */ + private static final int[] IDS = new int[] { 2001 }; + + public PyramidPlunderSwarmNPC(Location location, Player player) { + super(IDS[0], location, player); + } + + @Override + public void init() { + super.init(); + setRespawn(false); + getProperties().getCombatPulse().attack(player); + sendChat("bzzzzz"); + } + + @Override + public void handleTickActions() { + super.handleTickActions(); + if (!getProperties().getCombatPulse().isAttacking()) { + getProperties().getCombatPulse().attack(player); + } + if (getProperties().getCombatPulse().isAttacking()) { + if (RandomFunction.random(40) < 2) { + sendChat("bzzzzz"); + } + } + } + + @Override + public boolean isIgnoreMultiBoundaries(Entity victim) { + return victim == player; + } + + @Override + public int[] getIds() { + return IDS; + } + +} diff --git a/Server/src/main/content/minigame/pyramidplunder/RechargeSceptre.java b/Server/src/main/content/minigame/pyramidplunder/RechargeSceptre.java new file mode 100644 index 0000000..00bd639 --- /dev/null +++ b/Server/src/main/content/minigame/pyramidplunder/RechargeSceptre.java @@ -0,0 +1,219 @@ +package content.minigame.pyramidplunder; + +import core.game.dialogue.DialoguePlugin; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Allows the sceptre to be recharged by using it on the Guardian Mummy + * @author ceik + */ +@Initializable +public class RechargeSceptre extends UseWithHandler { + Item usedSceptre = new Item(4950); + int clayRecharge[] = new int[24]; + int stoneRecharge[] = new int[12]; + int goldRecharge[] = new int[6]; + public RechargeSceptre() { + super(9046, 9048, 9050); + } + @Override + public Plugin newInstance(Object arg) throws Throwable { + new RechargeDialogue().init(); + addHandler(4476, NPC_TYPE, this); + return this; + } + @Override + public boolean handle(NodeUsageEvent event){ + final Player player = event.getPlayer(); + player.getDialogueInterpreter().open(999876,event.getUsedItem()); + return true; + } + public class RechargeDialogue extends DialoguePlugin { + public RechargeDialogue() { + /** + * empty + */ + } + public RechargeDialogue(Player player){super(player);} + + @Override + public DialoguePlugin newInstance(Player player){ return new RechargeDialogue(player);} + + @Override + public boolean open(Object... args){ + usedSceptre = (Item) args[0]; + player.getPacketDispatch().sendMessage("" + args[0]); + interpreter.sendDialogue("Mrrrh, how do you have this? You shouldn't.", "Nevertheless, I can recharge this for you."); + return true; + } + @Override + public boolean handle(int dialogId, int buttonId){ + switch(stage){ + case 0: + interpreter.sendOptions("Recharge sceptre?", "Yes, please.", "No, thanks."); + stage = 1; + break; + case 1: + switch(buttonId){ + case 1: + interpreter.sendOptions("Recharge with?","Clay/Ivory Artefacts(24)","Stone Artefacts(12)","Gold Artefacts(6)"); + stage = 20; + break; + case 2: + stage = 100; + break; + } + break; + case 20: + switch(buttonId){ + case 1: { + int totalCounter = 0; + for (int i = 0; i < 28; i++) { + if (totalCounter == 24) { + break; + } + int thisSlot = player.getInventory().getId(i); + if (thisSlot == 9026) { + clayRecharge[totalCounter] = i; + totalCounter += 1; + } + } + for (int i = 0; i < 28; i++) { + if (totalCounter == 24) { + break; + } + int thisSlot = player.getInventory().getId(i); + if (thisSlot == 9032) { + clayRecharge[totalCounter] = i; + totalCounter += 1; + } + } + for (int i = 0; i < 28; i++) { + if (totalCounter == 24) { + break; + } + int thisSlot = player.getInventory().getId(i); + if (thisSlot == 9036) { + clayRecharge[totalCounter] = i; + totalCounter += 1; + } + } + if (clayRecharge[23] == 0) { + player.getPacketDispatch().sendMessage("You do not have enough clay/ivory artifacts."); + end(); + break; + } + for (int i = 0; i < 24; i++) { + player.getInventory().remove(new Item(player.getInventory().getId(clayRecharge[i])), clayRecharge[i], true); + } + player.getInventory().remove(usedSceptre); + player.getInventory().add(new Item(9044)); + player.getPacketDispatch().sendMessage("Your Pharoah's Sceptre has been fully recharged!"); + clayRecharge[23] = 0; + end(); + break; + } + case 2: { + int totalCounter = 0; + for (int i = 0; i < 28; i++) { + if (totalCounter == 12) { + break; + } + int thisSlot = player.getInventory().getId(i); + if (thisSlot == 9042) { + stoneRecharge[totalCounter] = i; + totalCounter += 1; + } + } + for (int i = 0; i < 28; i++) { + if (totalCounter == 12) { + break; + } + int thisSlot = player.getInventory().getId(i); + if (thisSlot == 9030) { + stoneRecharge[totalCounter] = i; + totalCounter += 1; + } + } + for (int i = 0; i < 28; i++) { + if (totalCounter == 12) { + break; + } + int thisSlot = player.getInventory().getId(i); + if (thisSlot == 9038) { + stoneRecharge[totalCounter] = i; + totalCounter += 1; + } + } + if (stoneRecharge[11] == 0) { + player.getPacketDispatch().sendMessage("You do not have enough stone artifacts."); + end(); + break; + } + for (int i = 0; i < 12; i++) { + player.getInventory().remove(new Item(player.getInventory().getId(stoneRecharge[i])), stoneRecharge[i], true); + } + player.getInventory().remove(usedSceptre); + player.getInventory().add(new Item(9044)); + player.getPacketDispatch().sendMessage("Your Pharoah's Sceptre has been fully recharged!"); + stoneRecharge[11] = 0; + end(); + break; + } + case 3: { + int totalCounter = 0; + for(int i = 0; i < 28; i++){ + if(totalCounter == 6) {break;} + int thisSlot = player.getInventory().getId(i); + if(thisSlot == 9040){ + goldRecharge[totalCounter] = i; + totalCounter += 1; + } + } + for(int i = 0; i < 28; i++){ + if(totalCounter == 6) {break;} + int thisSlot = player.getInventory().getId(i); + if(thisSlot == 9028){ + goldRecharge[totalCounter] = i; + totalCounter += 1; + } + } + for(int i = 0; i < 28; i++){ + if(totalCounter == 6) {break;} + int thisSlot = player.getInventory().getId(i); + if(thisSlot == 9034){ + goldRecharge[totalCounter] = i; + totalCounter += 1; + } + } + if(goldRecharge[5] == 0){player.getPacketDispatch().sendMessage("You do not have enough gold artifacts."); end(); break;} + for(int i = 0; i < 6; i++){ + player.getInventory().remove( new Item (player.getInventory().getId(goldRecharge[i])), goldRecharge[i], true); + } + player.getInventory().remove(usedSceptre); + player.getInventory().add(new Item(9044)); + player.getPacketDispatch().sendMessage("Your Pharoah's Sceptre has been fully recharged!"); + goldRecharge[5] = 0; + end(); + break; + } + } + break; + case 100: + end(); + break; + } + return true; + } + @Override + public int[] getIds() { + return new int[] { 999876 }; + } + } +} + diff --git a/Server/src/main/content/minigame/pyramidplunder/SimonScepterInteraction.java b/Server/src/main/content/minigame/pyramidplunder/SimonScepterInteraction.java new file mode 100644 index 0000000..3f4d051 --- /dev/null +++ b/Server/src/main/content/minigame/pyramidplunder/SimonScepterInteraction.java @@ -0,0 +1,32 @@ +package content.minigame.pyramidplunder; + +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Handles when a player uses a pharaoh scepter on Simon (necessary to be accurate) + * @author ceik + */ +@Initializable +public final class SimonScepterInteraction extends UseWithHandler { + + public SimonScepterInteraction() { + super(9044, 9046, 9048, 9050); + } + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(3123, NPC_TYPE, this); + //PluginManager.definePlugin(new SimonScepterInteraction()); + return this; + } + @Override + public boolean handle(NodeUsageEvent event){ + final Player player = event.getPlayer(); + player.getDialogueInterpreter().open(3123, ((NPC)event.getUsedWith()), true, false, event.getUsedItem().getId()); + return true; + } +} diff --git a/Server/src/main/content/minigame/sorceress/DelMontyDialogue.java b/Server/src/main/content/minigame/sorceress/DelMontyDialogue.java new file mode 100644 index 0000000..5286f5e --- /dev/null +++ b/Server/src/main/content/minigame/sorceress/DelMontyDialogue.java @@ -0,0 +1,81 @@ +package content.minigame.sorceress; + +import core.game.container.impl.EquipmentContainer; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.game.node.item.Item; + +/** + * Represents the dialogue plugin used for the del monty npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class DelMontyDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code DelMontyDialogue} {@code Object}. + */ + public DelMontyDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code DelMontyDialogue} {@code Object}. + * @param player the player. + */ + public DelMontyDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new DelMontyDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + player("Hey kitty!"); + stage = 1; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 100: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Meow."); + stage = 0; + break; + default: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "\"Meow.\""); + stage = 0; + break; + } + return true; + } + + /** + * Method used to check if a player has a cat speak amulet. + * @param player the player. + * @return {@code True} so. + */ + public static boolean hasCatAmulet(Player player) { + Item item = player.getEquipment().get(EquipmentContainer.SLOT_AMULET); + if (item == null) + return false; + return item.getId() == 4677 || item.getId() == 6544; + } + + @Override + public int[] getIds() { + return new int[] { 5563 }; + } + +} diff --git a/Server/src/main/content/minigame/sorceress/GardenObjectsPlugin.kt b/Server/src/main/content/minigame/sorceress/GardenObjectsPlugin.kt new file mode 100644 index 0000000..53eb47f --- /dev/null +++ b/Server/src/main/content/minigame/sorceress/GardenObjectsPlugin.kt @@ -0,0 +1,1414 @@ +package content.minigame.sorceress + +import core.plugin.Initializable +import core.plugin.Plugin +import core.game.component.Component +import core.game.interaction.NodeUsageEvent +import core.game.interaction.UseWithHandler +import core.game.node.scenery.Scenery +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import core.net.packet.PacketRepository +import core.net.packet.context.MinimapStateContext +import core.net.packet.out.MinimapState +import core.tools.RandomFunction +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.game.world.GameWorld +import core.plugin.ClassScanner +import content.data.Quests + + +class GardenObjectsPlugin : InteractionListener { + + val SQIRK_TREES = intArrayOf(21767, 21768, 21769, 21766) + val FOUNTAIN = 21764 + val HERBS = HerbDefinition.values().map { it.id }.toIntArray() + val SHELVES = 21794 + private val HERBS_ITEMS = intArrayOf(199, 201, 203, 205, 207, 209, 211, 213, 215, 217, 219, 2485, 3049, 3051, 199, 201, 203, 205) + + override fun defineListeners() { + SqirkJuicePlugin().newInstance(null) + SqirkMakingDialogue().init() + ClassScanner.definePlugin(SorceressGardenObject()) + + on(SQIRK_TREES, IntType.SCENERY, "pick-fruit"){ player, node -> + val def = SeasonDefinitions.forTreeId(node.id) + if (def != null) { + player.lock() + player.logoutListeners["garden"] = {p -> p.location = def.respawn} + player.animate(PICK_FRUIT) + player.skills.addExperience(Skills.THIEVING, def.exp, true) + player.skills.addExperience(Skills.FARMING, def.farmExp, true) + GameWorld.Pulser.submit(object : Pulse(2, player) { + var counter = 0 + override fun pulse(): Boolean { + if (counter == 1) { + player.inventory.add(Item(def.fruitId)) + player.interfaceManager.openOverlay(Component(115)) + PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 2)) + } else if (counter == 3) player.properties.teleportLocation = def.respawn else if (counter == 4) { + player.unlock() + player.logoutListeners.remove("garden") + player.packetDispatch.sendMessage("An elemental force emanating from the garden teleports you away.") + PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 0)) + player.interfaceManager.close() + player.interfaceManager.closeOverlay() + player.unlock() + return true + } + counter++ + return false + } + }) + } + return@on true + } + + + on(FOUNTAIN, IntType.SCENERY, "drink-from"){ player, _ -> + player.lock() + GameWorld.Pulser.submit(object : Pulse(1, player) { + var counter = 0 + override fun pulse(): Boolean { + when (counter++) { + 1 -> player.animate(DRINK_ANIM) + 4 -> player.graphics(GRAPHICS) + 5 -> player.animate(TELE) + 6 -> player.interfaceManager.openOverlay(Component(115)) + 7 -> PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 2)) + 9 -> player.properties.teleportLocation = Location(3321, 3141, 0) + 11 -> { + player.unlock() + player.animate(Animation(-1)) + player.interfaceManager.close() + player.interfaceManager.closeOverlay() + PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 0)) + return true + } + } + return false + } + }) + + return@on true + } + + on(SHELVES, IntType.SCENERY, "search"){ player, node -> + if (player.inventory.freeSlots() < 1) { + player.sendMessage("You don't have enough space in your inventory to take a beer glass.") + } else { + player.sendMessage("You take an empty beer glass off the shelves.") + player.inventory.add(Item(1919, 1)) + } + + return@on true + } + + on(HERBS, IntType.SCENERY, "pick"){ player, node -> + val herbDef = HerbDefinition.forId(node.getId()) + if (herbDef != null) { + handleElementalGarden(player, node.asScenery(), herbDef) + } + return@on true + } + + } + + /** + * Method used to handle the elemental garden picking. + * @param player the player. + * @param object the object. + * @param herbDef the herbdef. + */ + private fun handleElementalGarden(player: Player, `object`: Scenery, herbDef: HerbDefinition) { + player.lock() + player.logoutListeners["garden"] = {p -> p.location = herbDef.respawn} + player.animate(ANIMATION) + player.skills.addExperience(Skills.FARMING, herbDef.exp, true) + GameWorld.Pulser.submit(object : Pulse(2, player) { + var counter = 0 + override fun pulse(): Boolean { + if (counter == 1) { + player.inventory.add(Item(HERBS_ITEMS[RandomFunction.random(0, HERBS_ITEMS.size)], +1)) + player.inventory.add(Item(HERBS_ITEMS[RandomFunction.random(0, HERBS_ITEMS.size)], +1)) + player.packetDispatch.sendMessage("You pick up a herb.") + player.interfaceManager.openOverlay(Component(115)) + PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 2)) + } else if (counter == 3) player.properties.teleportLocation = + Location.create(herbDef.respawn) else if (counter == 4) { + player.unlock() + player.packetDispatch.sendMessage("An elemental force emanating from the garden teleports you away.") + PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 0)) + player.interfaceManager.close() + player.interfaceManager.closeOverlay() + player.logoutListeners.remove("garden") + player.unlock() + return true + } + counter++ + return false + } + }) + } + + /** + * Represents the herb definitions. + * @author SonicForce41 + * @version 1.0 + */ + enum class HerbDefinition + /** + * Constructs a new `GardenObjectsPlugin` `Object`. + * @param id the id. + * @param exp the exp. + * @param respawn the respawn. + */( + /** + * Represents the id. + */ + val id: Int, + /** + * Represents the experience. + */ + val exp: Double, + /** + * Represents the respawn location. + */ + val respawn: Location + ) { + WINTER(21671, 30.0, Location(2907, 5470, 0)), SPRING(21668, 40.0, Location(2916, 5473, 0)), AUTUMN( + 21670, + 50.0, + Location(2913, 5467, 0) + ), + SUMMER(21669, 60.0, Location(2910, 5476, 0)); + /** + * Gets the Id + * @return the Id + */ + /** + * Gets the exp + * @return the Exp + */ + /** + * Gets the respawn Location + * @return the Location. + */ + + companion object { + /** + * Gets the herb definition by the id. + * @param id the objectId + * @return the definition. + */ + fun forId(id: Int): HerbDefinition? { + for (def in values()) { + if (def.id == id) { + return def + } + } + return null + } + } + } + + /** + * Represents the season definitions. + * @author SonicForce41 + * @version 1.0 + */ + enum class SeasonDefinitions + /** + * Constructs a new `GardenObjectsPlugin.java` `Object`. + * @param treeId the tree id. + * @param level the level. + * @param farmExp the farm exp. + * @param treeExp the tree exp. + * @param fruitId the fruit id. + * @param juiceId the juice id. + * @param fruitAmt the fruit amt. + * @param boost the boost. + * @param energy the energy. + * @param osmanExp the osman exp. + * @param gateId the gate id. + * @param respawn the respawn. + */( + /** + * The treeId + */ + val treeId: Int, + /** + * The level + */ + val level: Int, + /** + * The farming experience recieved from picking + */ + val farmExp: Double, + /** + * The thieving experience recieved from picking + */ + val exp: Double, + /** + * The fruitId id + */ + val fruitId: Int, + /** + * The juice id + */ + val juiceId: Int, + /** + * The fruit amt + */ + val fruitAmt: Int, + /** + * The boost + */ + val boost: Int, + /** + * The energy + */ + val energy: Int, + /** + * The experience recieved from osman + */ + val osmanExp: Double, + /** + * The gate id + */ + val gateId: Int, + /** + * The respawn location + */ + val respawn: Location + ) { + WINTER(21769, 1, 30.0, 70.0, 10847, 10851, 5, 0, 10, 350.0, 21709, Location(2907, 5470, 0)), SPRING( + 21767, + 25, + 40.0, + 337.5, + 10844, + 10848, + 4, + 1, + 20, + 1350.0, + 21753, + Location(2916, 5473, 0) + ), + AUTUMN(21768, 45, 50.0, 783.3, 10846, 10850, 3, 2, 30, 2350.0, 21731, Location(2913, 5467, 0)), SUMMER( + 21766, + 65, + 60.0, + 1500.0, + 10845, + 10849, + 2, + 3, + 40, + 3000.0, + 21687, + Location(2910, 5476, 0) + ); + /** + * Gets the treeId + * @return the treeId + */ + /** + * Gets the level + * @return the Level + */ + /** + * Gets the farmExp + * @return the farmExp + */ + /** + * Gets the exp from tree + * @return the treeExp + */ + /** + * Gets the fruit Id + * @return the fruitId + */ + /** + * Gets the juice Id + * @return the juiceId + */ + /** + * Gets the fruid amt + * @return the fruitAmt + */ + /** + * Gets the theiving boost + * @return the boost + */ + /** + * Gets the run energy restoring + * @return the energy + */ + /** + * Gets the experience recieved from osman + * @return the osmanExp + */ + /** + * Gets the gate Id + * @return the gateId + */ + /** + * Gets the respawn location + * @return the respawn Location + */ + + companion object { + /** + * Gets the def by the fruit id. + * @param fruitId the fruit id. + * @return the definition. + */ + fun forFruitId(fruitId: Int): SeasonDefinitions? { + for (def in values()) { + if (def == null) continue + if (fruitId == def.fruitId) return def + } + return null + } + + /** + * Gets the def by the gate Id. + * @param gateId the gateId + * @return the def. + */ + @JvmStatic + fun forGateId(gateId: Int): SeasonDefinitions? { + for (def in values()) { + if (gateId == def.gateId) return def + } + return null + } + + /** + * Gets the def by the juice id. + * @param juiceId the juice id. + * @return the def. + */ + fun forJuiceId(juiceId: Int): SeasonDefinitions? { + for (def in values()) { + if (def == null) continue + if (juiceId == def.juiceId) return def + } + return null + } + + /** + * Gets the season def by the tree id. + * @param treeId the tree id. + * @return the def. + */ + fun forTreeId(treeId: Int): SeasonDefinitions? { + for (def in values()) { + if (def == null) continue + if (treeId == def.treeId) return def + } + return null + } + } + } + + /** + * Use with Plugin for Sq'irk Juice making + * @author SonicForce41 + */ + class SqirkJuicePlugin : UseWithHandler(10844, 10845, 10846, 10847) { + override fun handle(event: NodeUsageEvent): Boolean { + val item: Item = event.getUsedItem() + val with: Item = event.getBaseItem() + val player: Player = event.getPlayer() + val def = SeasonDefinitions.forFruitId(item.id) + if (with == null || player == null || def == null) return true + val amt = player.inventory.getAmount(item) + if (!player.inventory.containItems(1919)) { + player.dialogueInterpreter.open(43382, 0) + return true + } + if (amt < def.fruitAmt) { + player.dialogueInterpreter.open(43382, 1, item.id) + return true + } + player.animate(CRUSH_ITEM) + player.skills.addExperience(Skills.COOKING, 5.0, true) + player.inventory.remove(Item(item.id, def.fruitAmt)) + player.inventory.remove(Item(1919)) + player.inventory.add(Item(def.juiceId)) + player.dialogueInterpreter.sendDialogue("You squeeze " + def.fruitAmt + " sq'irks into an empty glass.") + return true + } + + @Throws(Throwable::class) + override fun newInstance(arg: Any?): Plugin { + addHandler(233, ITEM_TYPE, this) + return this + } + + companion object { + /** + * The crushing an item with pestle and mortar animation. + */ + private val CRUSH_ITEM = Animation(364) + } + } + + /** + * Represents the dialougue of the osman NPC. + * @author 'Vexia + * @author SonicForce41 + * @date 31/12/2013 + */ + @Initializable + class OsmanDialogue : core.game.dialogue.DialoguePlugin { + /** + * Represents the quest instance. + */ + private var quest: Quest? = null + + /** + * Represents the count of materials you have gathered. + */ + private var itemCount = 0 + + /** + * Constructs a new `OsmanDialogue` `Object`. + */ + constructor() { + /** + * empty. + */ + } + + /** + * Constructs a new `OsmanDialogue` `Object`. + * @param player the Player + */ + constructor(player: Player?) : super(player) {} + + override fun newInstance(player: Player): core.game.dialogue.DialoguePlugin { + return OsmanDialogue(player) + } + + override fun open(vararg args: Any): Boolean { + npc = args[0] as NPC + quest = player.questRepository.getQuest(Quests.PRINCE_ALI_RESCUE) + when (quest!!.getStage(player)) { + 100 -> { + interpreter.sendDialogues(player, null, "I'd like to talk about sq'irks.") + stage = 0 + return true + } + 60 -> { + interpreter.sendDialogues( + npc, + null, + "The prince is safe on his way home with Leela.", + "You can pick up your payment from the chancellor." + ) + stage = 0 + return true + } + 40, 50 -> { + interpreter.sendDialogues(npc, null, "Speak to Leela for any further instructions.") + stage = 0 + } + 30 -> { + interpreter.sendDialogues(player, null, "Can you tell me what I still need to get?") + stage = 0 + } + 20 -> { + if (!player.getInventory().containsItem(KEY_PRINT)) { + interpreter.sendDialogues(player, null, "Can you tell me what I need to get?") + } else if (!player.getInventory().containsItem(BRONZE_BAR) && player.getInventory().containsItem(KEY_PRINT)) { + interpreter.sendDialogues( + npc, + null, + "Good, you have the print of the key. Get a bar of", + "bronze, too, and I can get the key mad." + ) + stage = 70 + } else { + interpreter.sendDialogues(npc, null, "Well done; we can make the key now.") + stage = 80 + } + return true + } + 10 -> interpreter.sendDialogues(player, null, "The chancellor trusts me. I have come for instructions.") + 0 -> interpreter.sendDialogues(player, null, "I'd like to talk about sq'irks.") + else -> { + } + } + stage = 0 + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (quest!!.getStage(player)) { + 100 -> when (stage) { + else -> handleSqirks(buttonId) + } + 60 -> end() + 40, 50 -> end() + 30 -> when (stage) { + 82 -> end() + 0 -> { + interpreter.sendDialogues(npc, null, "You can collect the key from Leela.") + stage = 11 + } + 11 -> { + if (player.getInventory().containsItem(YELLOW_WIG)) { + interpreter.sendDialogues(npc, null, "The wig you have got, well done.") + itemCount++ + } else { + interpreter.sendDialogues( + npc, + null, + "You need a wig, maybe made from wool. If you find", + "someone who can work with wool ask them about it.", + "There's a witch nearby may be able to help you dye it." + ) + } + stage = 12 + } + 12 -> { + if (player.getInventory().containsItem(SKIRT)) { + interpreter.sendDialogues(npc, null, "You have got the skirt, good.") + itemCount++ + } else { + interpreter.sendDialogues(npc, null, "You will need to get a pink skirt, same as Keli's.") + } + stage = 13 + } + 13 -> { + if (player.getInventory().containsItem(PASTE)) { + interpreter.sendDialogues( + npc, + null, + "You have the skin paint, well done. I thought you would", + "struggle to make that." + ) + itemCount++ + } else { + interpreter.sendDialogues( + npc, + null, + "We still need something to colour the Prince's skin", + "lighter. There's a witch close to here. She knows about", + "many things. She may know some way to make the", + "skin lighter." + ) + } + stage = if (itemCount == 3) 14 else 15 + } + 14 -> { + interpreter.sendDialogues(npc, null, "You do have everything for the disguise.") + stage = 15 + } + 15 -> if (player.getInventory().containsItem(ROPE)) { + interpreter.sendDialogues( + npc, + null, + "You have the rope I see, to tie up Keli. That will be the", + "most dangerous part of the plan." + ) + stage = 16 + } else { + interpreter.sendDialogues( + npc, + null, + "You will still need some rope to tie up Keli, of course. I", + "heard that there's a good rope maker around here." + ) + stage = 16 + } + 16 -> end() + 20 -> { + interpreter.sendDialogues( + npc, + null, + "Yes, that is most important. There is no way you can", + "get the real key. It is on a chain around Keli's neck.", + "Almost impossible to steal." + ) + stage = 21 + } + 21 -> end() + } + 0 -> when (stage) { + else -> handleSqirks(buttonId) + } + 20 -> when (stage) { + 80 -> { + interpreter.sendDialogue("Osman takes the key imprint and the bronze bar.") + stage = 81 + } + 81 -> if (player.getInventory().remove(BRONZE_BAR) && player.getInventory().remove(KEY_PRINT)) { + interpreter.sendDialogues(npc, null, "Pick the key up from Leela.") + quest!!.setStage(player, 30) + stage = 82 + } + 82 -> end() + 70 -> { + interpreter.sendDialogues(player, null, "I will get one and come back.") + stage = 71 + } + 71 -> end() + 0 -> { + interpreter.sendDialogues( + npc, + null, + "A print of the key in soft clay and a bronze bar.", + "Then, collect the key from Leela." + ) + stage = 1 + } + 1 -> { + interpreter.sendDialogues( + npc, + null, + "When you have the full disguise talk to", + "Leela and she will help you with the rest." + ) + stage = 2 + } + 2 -> end() + 10 -> { + interpreter.sendDialogues( + npc, + null, + "The prince is guarded by some stupid guards and a", + "clever woman. The woman is our only way to get the", + "prince out. Only she can walk freely about the area." + ) + stage = 11 + } + 11 -> { + interpreter.sendDialogues( + npc, + null, + "I think you will need to tie her up. One coil of rope", + "should do for that. Then, disguise the prince as her to", + "get him out without suspicion." + ) + stage = 12 + } + 12 -> { + interpreter.sendDialogues(player, null, "How good must the disguise be?") + stage = 13 + } + 13 -> { + interpreter.sendDialogues( + npc, + null, + "Only enough to fool the guards at a distance. Get a", + "skirt like hers. Same colour, same style. We will only", + "have a short time." + ) + stage = 14 + } + 14 -> { + interpreter.sendDialogues( + npc, + null, + "Get a blonde wig, too. that is up to you to make or", + "find. Something to colour the skin of the prince." + ) + stage = 15 + } + 15 -> { + interpreter.sendDialogues( + npc, + null, + "My daughter and top spy, Leela, can help you. She has", + "sent word that she has discovered where they are", + "keeping the prince." + ) + stage = 16 + } + 16 -> { + interpreter.sendDialogues( + npc, + null, + "It's near Draynor Village. She is lurking somewhere", + "near there now." + ) + stage = 17 + } + 17 -> { + quest!!.setStage(player, 20) + interpreter.sendOptions( + "Select an Option", + "Explain the first thing again.", + "What is the second thing you need?", + "Okay, I better go find some things." + ) + stage = 50 + } + 20 -> { + interpreter.sendDialogues( + npc, + null, + "We need the key, or we need a copy made. If you can", + "get some soft clay then you can copy the key..." + ) + stage = 21 + } + 21 -> { + interpreter.sendDialogues( + npc, + null, + "...If you can convince Lady Keli to show it to you", + "for a moment. She is very boastful.", + "It should not be too hard." + ) + stage = 22 + } + 22 -> { + interpreter.sendDialogues(npc, null, "Bring the imprint to me, with a bar of bronze.") + stage = 23 + } + 23 -> { + quest!!.setStage(player, 20) + interpreter.sendOptions( + "Select an Option", + "What is the first thing I must do?", + "What exactly is the second thing you need?", + "Okay, I better go find some things." + ) + stage = 24 + } + 24 -> when (buttonId) { + 1 -> { + interpreter.sendDialogues(player, null, "What is the first thing I must do?") + stage = 10 + } + 2 -> { + interpreter.sendDialogues(player, null, "What exactly is the second thing I must do?") + stage = 20 + } + 3 -> { + interpreter.sendDialogues(player, null, "Okay, I better go find some things.") + stage = 25 + } + } + 25 -> { + interpreter.sendDialogues( + npc, + null, + "May good luck travel with you. Don't forget to find", + "Leela. It can't be done without her help." + ) + stage = 26 + } + 26 -> end() + 50 -> when (buttonId) { + 1 -> { + interpreter.sendDialogues(player, null, "Explain the first thing again.") + stage = 10 + } + 2 -> { + interpreter.sendDialogues(player, null, "What is th second thing you need?") + stage = 20 + } + 3 -> { + interpreter.sendDialogues(player, null, "Okay, I better go find some things.") + stage = 25 + } + } + } + 10 -> when (stage) { + 0 -> { + interpreter.sendDialogues( + npc, + null, + "Our prince is captive by the Lady Keli. We just need", + "to make the rescue. There are two things we need", + "you to do." + ) + stage = 1 + } + 1 -> { + interpreter.sendOptions( + "Select an Option", + "What is the first thing I must do?", + "What is the second thing you need?" + ) + stage = 3 + } + 3 -> when (buttonId) { + 1 -> { + interpreter.sendDialogues(player, null, "What is the first thing I must do?") + stage = 10 + } + 2 -> { + interpreter.sendDialogues(player, null, "What is the second thing you need?") + stage = 20 + } + } + 10 -> { + interpreter.sendDialogues( + npc, + null, + "The prince is guarded by some stupid guards and a", + "clever woman. The woman is our only way to get the", + "prince out. Only she can walk freely about the area." + ) + stage = 11 + } + 11 -> { + interpreter.sendDialogues( + npc, + null, + "I think you will need to tie her up. One coil of rope", + "should do for that. Then, disguise the prince as her to", + "get him out without suspicion." + ) + stage = 12 + } + 12 -> { + interpreter.sendDialogues(player, null, "How good must the disguise be?") + stage = 13 + } + 13 -> { + interpreter.sendDialogues( + npc, + null, + "Only enough to fool the guards at a distance. Get a", + "skirt like hers. Same colour, same style. We will only", + "have a short time." + ) + stage = 14 + } + 14 -> { + interpreter.sendDialogues( + npc, + null, + "Get a blonde wig, too. that is up to you to make or", + "find. Something to colour the skin of the prince." + ) + stage = 15 + } + 15 -> { + interpreter.sendDialogues( + npc, + null, + "My daughter and top spy, Leela, can help you. She has", + "sent word that she has discovered where they are", + "keeping the prince." + ) + stage = 16 + } + 16 -> { + interpreter.sendDialogues( + npc, + null, + "It's near Draynor Village. She is lurking somewhere", + "near there now." + ) + stage = 17 + } + 17 -> { + quest!!.setStage(player, 20) + interpreter.sendOptions( + "Select an Option", + "Explain the first thing again.", + "What is the second thing you need?", + "Okay, I better go find some things." + ) + stage = 50 + } + 20 -> { + interpreter.sendDialogues( + npc, + null, + "We need the key, or we need a copy made. If you can", + "get some soft clay then you can copy the key..." + ) + stage = 21 + } + 21 -> { + interpreter.sendDialogues( + npc, + null, + "...If you can convince Lady Keli to show it to you", + "for a moment. She is very boastful.", + "It should not be too hard." + ) + stage = 22 + } + 22 -> { + interpreter.sendDialogues(npc, null, "Bring the imprint to me, with a bar of bronze.") + stage = 23 + } + 23 -> { + quest!!.setStage(player, 20) + interpreter.sendOptions( + "Select an Option", + "What is the first thing I must do?", + "What exactly is the second thing you need?", + "Okay, I better go find some things." + ) + stage = 24 + } + 24 -> when (buttonId) { + 1 -> { + interpreter.sendDialogues(player, null, "What is the first thing I must do?") + stage = 10 + } + 2 -> { + interpreter.sendDialogues(player, null, "What exactly is the second thing I must do?") + stage = 20 + } + 3 -> { + interpreter.sendDialogues(player, null, "Okay, I better go find some things.") + stage = 25 + } + } + 25 -> { + interpreter.sendDialogues( + npc, + null, + "May good luck travel with you. Don't forget to find", + "Leela. It can't be done without her help." + ) + stage = 26 + } + 26 -> end() + } + else -> { + } + } + return true + } + + /** + * Method used to handle the sqirk juice dials. + * @param buttonId the buttonId. + */ + fun handleSqirks(buttonId: Int) { + when (stage) { + 0 -> if (!hasSqirks()) { + interpreter.sendOptions( + "Select an Option", + "Where do I get sq'irks?", + "Why can't you get the sq'irks yourself?", + "How should I squeeze the fruit?", + "Is there a reward for getting these sq'irks?", + "What's so good about sq'irk juice then?" + ) + stage = 200 + } else { + player(if (hasSqirkJuice()) "I have some sq'riks juice for you." else "I have some sq'irks for you.") + stage = 300 + } + 300 -> if (hasSqirkJuice()) { + val exp = experience + player.getSkills().addExperience(Skills.THIEVING, exp, true) + interpreter.sendDialogue( + "Osman imparts some Thieving advice to", + "you ( $exp Thieving experience points )", + "as a reward for the sq'irk juice." + ) + stage = 304 + } else { + npc("Uh, thanks, but is there any chance that you", "could squeeze the fruit into a glass for me?") + stage = 301 + } + 301 -> { + interpreter.sendOptions( + "Select an Option", + "How should I squeeze the fruit?", + "Can't you do that yourself?" + ) + stage = 302 + } + 302 -> when (buttonId) { + 1 -> { + player("How should I squeeze the fruit?") + stage = 130 + } + 2 -> { + player("Can't you do that yourself?") + stage = 303 + } + } + 304 -> end() + 303 -> { + player("I only carry knives or other such devices on me", "when I'm on the job.") + stage = 119 + } + 200 -> when (buttonId) { + 1 -> { + interpreter.sendDialogues(player, null, "Where do I get sq'irks?") + stage = 110 + } + 2 -> { + interpreter.sendDialogues(player, null, "Why can't you get the sq'irks yourself?") + stage = 120 + } + 3 -> { + interpreter.sendDialogues(player, null, "How should I squeeze the fruit?") + stage = 130 + } + 4 -> { + interpreter.sendDialogues(player, null, "Is there a reward for getting these sq'irks?") + stage = 140 + } + 5 -> { + interpreter.sendDialogues(player, null, "What's so good about sq'irk juice then?") + stage = 150 + } + } + 110 -> { + npc( + "There is a sorceress near the south-eastern edge of Al", + "Kharid who grows them. Once upon a time, we", + "considered each other friends." + ) + stage = 111 + } + 111 -> { + player("What happened?") + stage = 112 + } + 112 -> { + npc("We fell out, and now she won't give me any more", "fruit.") + stage = 113 + } + 113 -> { + player("So all I have to do is ask her for some fruit for you?") + stage = 114 + } + 114 -> { + npc( + "I doubt it will be that easy. She is not renowned for", + "her generosity and is very secretive about her garden's", + "location." + ) + stage = 115 + } + 115 -> { + player("Oh come on, it should be easy enough to find.") + stage = 116 + } + 116 -> { + npc( + "Her garden has remained hidden even to me - the chief", + "spy of Al Kharid. I believe her garden must be hidden", + "by magical means." + ) + stage = 117 + } + 117 -> { + player("This should be an interesting task. How many sq'irks do", "you want?") + stage = 118 + } + 118 -> { + npc( + "I'll reward you for as many as you can get your", + "hands on, but could you please squeeze the fruit into a", + "glass first?" + ) + stage = 119 + } + 119 -> { + interpreter.sendOptions( + "Select an Option", + "I've another question about sq'irks.", + "Thanks for the information." + ) + stage = 98 + } + 98 -> when (buttonId) { + 1 -> { + interpreter.sendOptions( + "Select an Option", + "Where do I get sq'irks?", + "Why can't you get the sq'irks yourself?", + "How should I squeeze the fruit?", + "Is there a reward for getting these sq'irks?", + "What's so good about sq'irk juice then?" + ) + stage = 200 + } + 2 -> { + player("Thanks for the information.") + stage = 99 + } + } + 99 -> end() + 120 -> { + npc( + "I may have mentioned that I had a falling out with the", + "Sorceress. Well, unsurprisingly, she refuses to give me", + "any more of her garden's produce." + ) + stage = 119 + } + 130 -> { + npc( + "Use a pestle and mortar to squeeze the sr'irks. Make", + "sure you have an empty glass with you to collect the", + "juice." + ) + stage = 119 + } + 140 -> { + npc( + "Of course there is. I am a generous man. I'll teach", + "you the art of Thieving for your troubles." + ) + stage = 141 + } + 141 -> { + player("How much training will you give?") + stage = 142 + } + 142 -> { + npc("That depends on the quantity and ripeness of the", "sq'irks you put into the juice.") + stage = 143 + } + 143 -> { + player("That sounds fair enough.") + stage = 119 + } + 150 -> { + npc( + "Ah it's sweet, sweet nectar for a thief or spy; it makes", + "light fingers lighter, fleet feet flightier and comes in four", + "different colours for those who are easily amused." + ) + stage = 151 + } + 151 -> { + interpreter.sendDialogue("Osman starts salivating at the thought of sq'irk juice.") + stage = 152 + } + 152 -> { + player("It wouldn't have addictive properties, would it?") + stage = 153 + } + 153 -> { + npc( + "It only holds power over those with poor self-control,", + "something which I have an abundance of." + ) + stage = 154 + } + 154 -> { + player("I see.") + stage = 119 + } + } + } + + /** + * Gets the experience the player can recieve. + * @return the experience. + */ + val experience: Double + get() { + var total = 0.0 + for (juiceId in JUICES) { + val def = SeasonDefinitions.forJuiceId(juiceId) ?: continue + val amount: Int = player.getInventory().getAmount(Item(juiceId)) + total += amount * def.osmanExp + player.getInventory().remove(Item(juiceId, amount)) + } + player.getInventory().refresh() + return total + } + + /** + * Checks wether the **Player** has sq'irk. + * @return `True`: Player has sq'irk. + */ + fun hasSqirkFruit(): Boolean { + for (i in FRUITS) { + if (player.getInventory().contains(i, 1)) { + return true + } + } + return false + } + + /** + * Checks wether the **Player** has sq'irk juice + * @return `True`: Player has sq'irk juice. + */ + fun hasSqirkJuice(): Boolean { + for (i in JUICES) { + if (player.getInventory().contains(i, 1)) { + return true + } + } + return false + } + + /** + * Checks wether the **Player** has sq'irks (fruit/juice). + * @return `True`: Player has either a fruit or squeezed juice. + */ + fun hasSqirks(): Boolean { + return hasSqirkFruit() || hasSqirkJuice() + } + + override fun getIds(): IntArray { + return intArrayOf(924, 5282) + } + + companion object { + /** + * Represents the key print item. + */ + private val KEY_PRINT = Item(2423) + + /** + * Represents the bronze bar item. + */ + private val BRONZE_BAR = Item(2349) + + /** + * Represents the rope item. + */ + private val ROPE = Item(954) + + /** + * Represents the pink skirt item. + */ + private val SKIRT = Item(1013) + + /** + * Represents the yellow wig item. + */ + private val YELLOW_WIG = Item(2419) + + /** + * Represents the skin paste item. + */ + private val PASTE = Item(2424) + + /** + * Represents the juices. + */ + private val JUICES = intArrayOf(10848, 10849, 10850, 10851) + + /** + * Represents the fruits. + */ + private val FRUITS = intArrayOf(10844, 10845, 10846, 10847) + } + } + + companion object { + /** + * Represents the animation to use. + */ + private val ANIMATION = Animation(827) + + /** + * Represents the herbs items used for the elemental garden picking. + */ + private val HERBS = + intArrayOf(199, 201, 203, 205, 207, 209, 211, 213, 215, 217, 219, 2485, 3049, 3051, 199, 201, 203, 205) + + /** + * Represents the drinking animation. + */ + private val DRINK_ANIM = Animation(5796) + + /** + * Represents the teleport anim. + */ + private val TELE = Animation(714) + + /** + * Represents the graphics to use. + */ + private val GRAPHICS = Graphics(111, 100, 1) + + /** + * Represents the picking fruit anim. + */ + private val PICK_FRUIT = Animation(2280) + } +} + + /** + * Dialogue for Sqirk making + * @author SonicForce41 + */ + class SqirkMakingDialogue : core.game.dialogue.DialoguePlugin { + private var dialogueId = 0 + private var definition: GardenObjectsPlugin.SeasonDefinitions? = null + + /** + * Constructs a new `SqirkMakingDialogue.java` `Object`. + */ + constructor() {} + + /** + * Constructs a new `SqirkMakingDialogue.java` `Object`. + * @param player the Player + */ + constructor(player: Player?) : super(player) {} + + override fun getIds(): IntArray { + return intArrayOf(43382) + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (dialogueId) { + 0 -> end() + 1 -> when (stage) { + 0 -> { + interpreter.sendDialogue("You need " + definition!!.fruitAmt + " sq'irks of this kind to fill a glass of juice.") + stage = 1 + } + 1 -> end() + } + } + return true + } + + override fun newInstance(player: Player): core.game.dialogue.DialoguePlugin { + return SqirkMakingDialogue(player) + } + + override fun open(vararg args: Any): Boolean { + dialogueId = args[0] as Int + when (dialogueId) { + 0 -> interpreter.sendDialogues( + player, + core.game.dialogue.FacialExpression.THINKING, + "I should get an empty beer glass to", + "hold the juice before I squeeze the fruit." + ) + 1 -> { + definition = GardenObjectsPlugin.SeasonDefinitions.forFruitId(args[1] as Int) + if (definition == null) end() + interpreter.sendDialogues( + player, + core.game.dialogue.FacialExpression.THINKING, + "I think I should wait till I have", + "enough fruits to make a full glass." + ) + } + } + stage = 0 + return true + } + } diff --git a/Server/src/main/content/minigame/sorceress/SorcceresDialouge.java b/Server/src/main/content/minigame/sorceress/SorcceresDialouge.java new file mode 100644 index 0000000..b795605 --- /dev/null +++ b/Server/src/main/content/minigame/sorceress/SorcceresDialouge.java @@ -0,0 +1,146 @@ +package content.minigame.sorceress; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.plugin.Initializable; +import core.game.world.map.Location; + +/** + * Handles the SorcceresDialouge dialogue. + * @author Vexia + */ +@Initializable +public class SorcceresDialouge extends DialoguePlugin { + + /** + * Constructs a new {@code SorcceresDialouge} {@code Object}. + */ + public SorcceresDialouge() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code SorcceresDialouge} {@code Object}. + * @param player the player. + */ + public SorcceresDialouge(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new SorcceresDialouge(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + npc("What are you doing in my house?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "None of your business!", "I'm here to kill you!", "Can I have some sq'irks please?", "I'm just passing by."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.FURIOUS, "None of your business!"); + stage = 10; + break; + case 2: + player("I'm here to kill you!"); + stage = 20; + break; + case 3: + player("Can I have some sq'irks please?"); + stage = 30; + break; + case 4: + player("I'm just passing by."); + stage = 40; + break; + } + break; + case 10: + player("I go where I like and do what I like."); + stage = 11; + break; + case 11: + npc("Not in my house. Be gone!"); + stage = 12; + break; + case 12: + end(); + tele(); + break; + case 20: + npc("I think not!"); + stage = 21; + break; + case 21: + end(); + tele(); + break; + case 30: + npc("What do you want them for?"); + stage = 31; + break; + case 31: + player("Someone asked me to bring them some."); + stage = 32; + break; + case 32: + npc("Who?"); + stage = 33; + break; + case 33: + player("You find yourself compelled to answer truthfully:", "Osman."); + stage = 34; + break; + case 34: + npc("In that case I'm sorry, you can't. I have had a falling", "out with him recently and would rather not oblige him."); + stage = 35; + break; + case 35: + end(); + break; + case 40: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 5531 }; + } + + /** + * Method used to tele the player out. + */ + public void tele() { + npc.sendChat("Be gone intruder!"); + player.lock(); + GameWorld.getPulser().submit(new Pulse(2, player) { + @Override + public boolean pulse() { + player.unlock(); + player.getProperties().setTeleportLocation(new Location(3321, 3143, 0)); + return true; + } + }); + } +} diff --git a/Server/src/main/content/minigame/sorceress/SorceressApprenticeDialogue.java b/Server/src/main/content/minigame/sorceress/SorceressApprenticeDialogue.java new file mode 100644 index 0000000..bc3aa16 --- /dev/null +++ b/Server/src/main/content/minigame/sorceress/SorceressApprenticeDialogue.java @@ -0,0 +1,268 @@ +package content.minigame.sorceress; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Graphics; + +import static core.api.ContentAPIKt.hasRequirement; +import content.data.Quests; + +/** + * Dialogue for Sorceress Apprentice + * @author SonicForce41 + */ +public class SorceressApprenticeDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code SorceressApprenticeDialogue.java} {@code Object}. + */ + public SorceressApprenticeDialogue() { + + } + + /** + * Constructs a new {@code SorceressApprenticeDialogue.java} {@code Object}. + * @param player the Player + */ + public SorceressApprenticeDialogue(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[] { 5532 }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Okay, here goes - and remember, to", "return just drink from the fountain."); + stage = 1; + break; + case 1: + teleport(npc, player); + end(); + break; + case 10: + npc("Cleaning, cleaning, always cleaning. This apprenticeship", "isn't all that it was cracked up to be."); + stage = 11; + break; + case 11: + player("Whose apprentice are you?"); + stage = 12; + break; + case 12: + npc("Oh, Aadeela, the sorceress upstairs, said she'd teach me", "magic, she did. And here I am scrubbing floors without", "a spell to help me."); + stage = 13; + break; + case 13: + interpreter.sendOptions("Select an Option", "I could cast a Water Blast or a Wind Blast spell?", "Surely there must be upsides to the task?"); + stage = 14; + break; + case 14: + switch (buttonId) { + case 1: + player("I could cast a Water Blast or a Wind Blast spell to", "hurry things along if you'd like?"); + stage = 110; + break; + case 2: + player("Surely there must be upsides to the task?"); + stage = 120; + break; + } + break; + case 110: + npc("No, no, she'd kill me or worse if she knew I was using", "Magic to do chores. Her last apprentice - well I'd", "rather not say."); + stage = 111; + break; + case 111: + player("Oh go on, what happend to them?"); + stage = 112; + break; + case 112: + npc("They say she turned them into little spiders."); + stage = 113; + break; + case 113: + player("Oh, that's too bad. I had better leave you to it."); + stage = 114; + break; + case 114: + end(); + break; + case 120: + npc("Nope. Clean this, clean that. When I'm finished cleaning", "here I have to go help out in the garden."); + stage = 121; + break; + case 121: + player("What garden?"); + stage = 122; + break; + case 122: + npc("Oh, I shouldn't have told you."); + stage = 123; + break; + case 123: + interpreter.sendOptions("Select an Option", "You're right, you shouldn't have.", "Oh, you can talk to me. I can see you're having a bad day."); + stage = 124; + break; + case 124: + switch (buttonId) { + case 1: + player("You're right, you shouldn't have."); + stage = 125; + break; + case 2: + player("Oh, you can talk to me. I can see you're having a bad", "day."); + stage = 126; + break; + } + break; + case 125: + end(); + break; + case 126: + npc("You know you're right. Nobody listens to me."); + stage = 127; + break; + case 127: + player("A sympathetic ear can do wonders."); + stage = 128; + break; + case 128: + npc("Yes, if I just let my frustrations out, I'd feel a lot", "better. Now what was I saying?"); + stage = 129; + break; + case 129: + player("You mentioned something about the garden."); + stage = 130; + break; + case 130: + npc("Oh yeah, the dreadful garden of hers."); + stage = 131; + break; + case 131: + player("Where is it?"); + stage = 132; + break; + case 132: + npc("Oh, it's nowhere."); + stage = 133; + break; + case 133: + player("What do you mean?"); + stage = 134; + break; + case 134: + npc("Well it's here, but not really. You see the sorceress is", "trying out some new type of compression magic."); + stage = 135; + break; + case 135: + player("Oh, that sounds interesting - so how does it work?"); + stage = 136; + break; + case 136: + npc("It would take too long to explain and, to be honest, I", "don't really understand how it works."); + stage = 137; + break; + case 137: + player("Fair enough, but tell me, how do you get to the", "garden?"); + stage = 138; + break; + case 138: + npc("By magic! The sorceress did teach me one spell."); + stage = 139; + break; + case 139: + interpreter.sendOptions("Select an Option", "Wow, cast the spell on me. It will be good Magic training for you.", "Oh, that's nice. Well it's been great talking to you."); + stage = 140; + break; + case 140: + switch (buttonId) { + case 1: + player("Wow, cast the spell on me. It will be good Magic", "training for you."); + stage = 142; + break; + case 2: + player("Oh, that's nice. Well it's been great", "talking to you."); + stage = 141; + break; + } + break; + case 141: + end(); + break; + case 142: + npc("You wouldn't mind?"); + stage = 143; + break; + case 143: + player("Of course not. I'd be glad to help."); + stage = 144; + break; + case 144: + npc("Okay, here goes! Remember, to return, just drink from", "the fountain."); + stage = 145; + break; + case 145: + player.getSavedData().getGlobalData().setApprentice(true); + teleport(npc, player); + end(); + break; + } + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new SorceressApprenticeDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + if (player.getSavedData().getGlobalData().hasSpokenToApprentice()) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hey apprentice, do you want to try out", "your teleport skills again?"); + stage = 0; + } else { + player("Hello. What are you doing?"); + stage = 10; + } + return true; + } + + public static void teleport(final NPC npc, final Player player) { + if (!hasRequirement(player, Quests.PRINCE_ALI_RESCUE)) + return; + npc.faceTemporary(player, 4); + npc.graphics(new Graphics(108)); + player.lock(); + Projectile.create(npc, player, 109).send(); + npc.sendChat("Senventior Disthinte Molesko!"); + GameWorld.getPulser().submit(new Pulse(1) { + int counter = 0; + + @Override + public boolean pulse() { + switch (counter++) { + case 2: + player.getProperties().setTeleportLocation(Location.create(2912, 5474, 0)); + break; + case 3: + player.graphics(new Graphics(110)); + player.unlock(); + return true; + } + return false; + } + }); + } + +} diff --git a/Server/src/main/content/minigame/sorceress/SorceressApprenticePlugin.java b/Server/src/main/content/minigame/sorceress/SorceressApprenticePlugin.java new file mode 100644 index 0000000..c2993ce --- /dev/null +++ b/Server/src/main/content/minigame/sorceress/SorceressApprenticePlugin.java @@ -0,0 +1,42 @@ +package content.minigame.sorceress; + +import core.cache.def.impl.NPCDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.plugin.ClassScanner; + +/** + * Teleport option for Sorceress Apprentice + * @author SonicForce41 + */ +@Initializable +public class SorceressApprenticePlugin extends OptionHandler { + + @Override + public boolean handle(Player player, Node node, String option) { + switch (option) { + case "teleport": + if (player.getSavedData().getGlobalData().hasSpokenToApprentice()) { + NPC npc = (NPC) node; + SorceressApprenticeDialogue.teleport(npc, player); + } else { + player.getDialogueInterpreter().sendDialogues(((NPC) node), null, "I can't do that now, I'm far too busy sweeping."); + } + } + return true; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + NPCDefinition.forId(5532).getHandlers().put("option:teleport", this); + SceneryDefinition.forId(21781).getHandlers().put("option:climb-up", this); + ClassScanner.definePlugin(new SorceressApprenticeDialogue()); + return this; + } + +} diff --git a/Server/src/main/content/minigame/sorceress/SorceressElementalNPC.java b/Server/src/main/content/minigame/sorceress/SorceressElementalNPC.java new file mode 100644 index 0000000..af3dbc8 --- /dev/null +++ b/Server/src/main/content/minigame/sorceress/SorceressElementalNPC.java @@ -0,0 +1,262 @@ +package content.minigame.sorceress; + +import java.util.List; + +import core.game.component.Component; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.node.entity.combat.DeathTask; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.net.packet.PacketRepository; +import core.net.packet.context.MinimapStateContext; +import core.net.packet.out.MinimapState; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the elementals npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class SorceressElementalNPC extends AbstractNPC { + /** + * Represents the definitions of the elementals. + * @author Sonicforce41 + * @version 1.0 + */ + enum ElementalDefinition { + + /** + * The definition values + */ + ID5533(5533, new Location[] { new Location(2908, 5460, 0), new Location(2898, 5460, 0) }), + ID5534(5534, new Location[] { new Location(2900, 5448, 0), new Location(2900, 5455, 0) }), + ID5535(5535, new Location[] { new Location(2905, 5449, 0), new Location(2899, 5449, 0) }), + ID5536(5536, new Location[] { new Location(2903, 5451, 0), new Location(2903, 5455, 0), new Location(2905, 5455, 0), new Location(2905, 5451, 0) }), + ID5537(5537, new Location[] { new Location(2903, 5457, 0), new Location(2917, 5457, 0) }), + ID5538(5538, new Location[] { new Location(2908, 5455, 0), new Location(2917, 5455, 0) }), + ID5539(5539, new Location[] { new Location(2922, 5471, 0), new Location(2922, 5459, 0) }), + ID5540(5540, new Location[] { new Location(2924, 5463, 0), new Location(2928, 5463, 0), new Location(2928, 5461, 0), new Location(2924, 5461, 0) }), + ID5541(5541, new Location[] { new Location(2924, 5461, 0), new Location(2926, 5461, 0), new Location(2926, 5458, 0), new Location(2924, 5458, 0) }), + ID5542(5542, new Location[] { new Location(2928, 5458, 0), new Location(2928, 5460, 0), new Location(2934, 5460, 0), new Location(2934, 5458, 0) }), + ID5543(5543, new Location[] { new Location(2931, 5477, 0), new Location(2931, 5470, 0) }), + ID5544(5544, new Location[] { new Location(2935, 5469, 0), new Location(2928, 5469, 0) }), + ID5545(5545, new Location[] { new Location(2925, 5464, 0), new Location(2925, 5475, 0) }), + ID5546(5546, new Location[] { new Location(2931, 5477, 0), new Location(2931, 5470, 0) }), + ID5547(5547, new Location[] { new Location(2907, 5488, 0), new Location(2907, 5482, 0) }), + ID5548(5548, new Location[] { new Location(2907, 5490, 0), new Location(2907, 5495, 0) }), + ID5549(5549, new Location[] { new Location(2910, 5493, 0), new Location(2910, 5487, 0) }), + ID5550(5550, new Location[] { new Location(2918, 5483, 0), new Location(2918, 5485, 0), new Location(2915, 5485, 0), new Location(2915, 5483, 0), new Location(2912, 5483, 0), new Location(2912, 5485, 0), new Location(2915, 5485, 0), new Location(2915, 5483, 0) }), + ID5551(5551, new Location[] { new Location(2921, 5486, 0), new Location(2923, 5486, 0), new Location(2923, 5490, 0), new Location(2923, 5486, 0) }), + ID5552(5552, new Location[] { new Location(2921, 5491, 0), new Location(2923, 5491, 0), new Location(2923, 5495, 0), new Location(2921, 5495, 0) }), + ID5553(5553, new Location[] { new Location(2899, 5466, 0), new Location(2899, 5468, 0), new Location(2897, 5468, 0), new Location(2897, 5466, 0), new Location(2897, 5468, 0), new Location(2899, 5468, 0) }), + ID5554(5554, new Location[] { new Location(2897, 5470, 0), new Location(2891, 5470, 0) }), + ID5555(5555, new Location[] { new Location(2897, 5471, 0), new Location(2899, 5471, 0), new Location(2899, 5478, 0), new Location(2897, 5478, 0) }), + ID5556(5556, new Location[] { new Location(2896, 5483, 0), new Location(2900, 5483, 0), new Location(2900, 5480, 0), new Location(2897, 5480, 0), new Location(2897, 5481, 0), new Location(2896, 5481, 0), new Location(2896, 5482, 0) }), + ID5557(5557, new Location[] { new Location(2896, 5483, 0), new Location(2896, 5481, 0), new Location(2891, 5481, 0), new Location(2891, 5483, 0) }), + ID5558(5558, new Location[] { new Location(2889, 5485, 0), new Location(2900, 5485, 0) }); + /** + * The NPC id + */ + private int npcId; + + /** + * The Locations + */ + private Location[] locations; + + /** + * Constructs a new {@code Elementals} {@code Object}. + * @param id the id. + * @param locations the locations. + */ + ElementalDefinition(int id, Location[] locations) { + npcId = id; + this.locations = locations; + } + + /** + * Gets the npcId + * @return 'npcId' + */ + public int getId() { + return npcId; + } + + /** + * Gets the locations to walk + * @return the Locations + */ + public Location[] getLocation() { + return locations; + } + + /** + * Gets the elemental definition by the id. + * @param id the id. + * @return the elemental definition. + */ + static ElementalDefinition forId(int id) { + for (ElementalDefinition def : ElementalDefinition.values()) + if (def != null) + if (def.getId() == id) + return def; + return null; + } + + } + + /** + * The Definition + */ + private ElementalDefinition definition; + + /** + * Index of current steps + */ + private int tilesIndex = 0; + + /** + * Constructs a new Elementals object. + */ + public SorceressElementalNPC() { + super(5533, null); + } + + /** + * Constructs a new Elementals object. + * @param id the id. + * @param location the location. + */ + public SorceressElementalNPC(int id, Location location) { + super(id, location); + } + + /** + * Checks if the entity can teleport. + * @param t the entity. + * @return {@code True} if so. + */ + public boolean canTeleport(Entity t) { + if (getDirection() == Direction.EAST && (t.getLocation().getX() - getLocation().getX()) < 4 && (t.getLocation().getX() - getLocation().getX()) > -1 && (t.getLocation().getY() - getLocation().getY()) == 0) + return true; + if (getDirection() == Direction.WEST && (getLocation().getX() - t.getLocation().getX()) < 4 && (getLocation().getX() - t.getLocation().getX()) > -1 && (t.getLocation().getY() - getLocation().getY()) == 0) + return true; + if (getDirection() == Direction.NORTH && (t.getLocation().getY() - getLocation().getY()) < 4 && (t.getLocation().getY() - getLocation().getY()) > -1 && (t.getLocation().getX() - getLocation().getX()) == 0) + return true; + if (getDirection() == Direction.SOUTH && (getLocation().getY() - t.getLocation().getY()) < 4 && (getLocation().getY() - t.getLocation().getY()) > -1 && (t.getLocation().getX() - getLocation().getX()) == 0) + return true; + return false; + } + + @Override + public void configure() { + super.configure(); + definition = ElementalDefinition.forId(getId()); + if (definition != null) { + configureMovementPath(definition.getLocation()); + setWalks(true); + } + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new SorceressElementalNPC(id, location); + } + + @Override + public int[] getIds() { + return new int[] { 5533, 5534, 5535, 5536, 5537, 5538, 5539, 5540, 5541, 5542, 5543, 5544, 5545, 5546, 5547, 5548, 5549, 5550, 5551, 5552, 5553, 5554, 5555, 5556, 5557, 5558 }; + } + + /** + * Gets the respawn loc. + * @return the loc. + */ + public Location getRespawnLocation() { + Location respawn = null; + if (getId() >= 5533 && getId() <= 5538) + respawn = Location.create(2913, 5467, 0); + else if (getId() >= 5539 && getId() <= 5546) + respawn = Location.create(2916, 5473, 0); + else if (getId() >= 5547 && getId() <= 5552) + respawn = Location.create(2910, 5476, 0); + else if (getId() >= 5553 && getId() <= 5558) + respawn = Location.create(2907, 5470, 0); + return respawn; + } + + /** + * Gets the tilesIndex. + * @return The tilesIndex. + */ + public int getTilesIndex() { + return tilesIndex; + } + + @Override + public void tick() { + super.tick(); + List players = getViewport().getCurrentPlane().getPlayers(); + for (Player player : players) { + if (player == null || !player.isActive() || player.getLocks().isInteractionLocked() || DeathTask.isDead(player) || !canTeleport(player) || !CombatSwingHandler.isProjectileClipped(this, player, false)) { + continue; + } + animate(new Animation(5803)); + sendTeleport(player); + } + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + return super.newInstance(arg); + } + + /** + * Sends a teleport to the Player + * @param player the Player + */ + public void sendTeleport(final Player player) { + player.lock(); + GameWorld.getPulser().submit(new Pulse(1) { + int delay = 0; + + @Override + public boolean pulse() { + if (delay == 0) { + player.getPacketDispatch().sendMessage("You've been spotted by an elemental and teleported out of its garden."); + player.graphics(new Graphics(110, 100)); + player.getInterfaceManager().openOverlay(new Component(115)); + PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 2)); + face(player); + } else if (delay == 6) { + player.getProperties().setTeleportLocation(Location.create(getRespawnLocation())); + PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 0)); + player.getInterfaceManager().closeOverlay(); + player.getInterfaceManager().close(); + face(null); + player.unlock(); + return true; + } + delay++; + return false; + } + }); + } + + /** + * Sets the tilesIndex. + * @param tilesIndex The tilesIndex to set. + */ + public void setTilesIndex(int tilesIndex) { + this.tilesIndex = tilesIndex; + } +} diff --git a/Server/src/main/content/minigame/sorceress/SorceressGardenObject.java b/Server/src/main/content/minigame/sorceress/SorceressGardenObject.java new file mode 100644 index 0000000..bfe8136 --- /dev/null +++ b/Server/src/main/content/minigame/sorceress/SorceressGardenObject.java @@ -0,0 +1,40 @@ +package content.minigame.sorceress; + +import core.cache.def.impl.SceneryDefinition; +import core.game.global.action.DoorActionHandler; +import core.game.node.entity.skill.Skills; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.plugin.Plugin; + +/** + * Hanldes the sorceress garden gates. + * @author 'Vexia + */ +public class SorceressGardenObject extends OptionHandler { + + @Override + public boolean handle(Player player, Node node, String option) { + GardenObjectsPlugin.SeasonDefinitions def = GardenObjectsPlugin.SeasonDefinitions.forGateId(((Scenery) node).getId()); + if (def != null) { + if (player.getSkills().getStaticLevel(Skills.THIEVING) < def.getLevel()) { + player.getDialogueInterpreter().sendItemMessage(10692, "You need Thieving level of " + def.getLevel() + " to pick the lock of this gate."); + return true; + } + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + } + return true; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(21709).getHandlers().put("option:open", this); + SceneryDefinition.forId(21753).getHandlers().put("option:open", this); + SceneryDefinition.forId(21731).getHandlers().put("option:open", this); + SceneryDefinition.forId(21687).getHandlers().put("option:open", this); + return this; + } + +} diff --git a/Server/src/main/content/minigame/vinesweeper/Vinesweeper.kt b/Server/src/main/content/minigame/vinesweeper/Vinesweeper.kt new file mode 100644 index 0000000..9fe1196 --- /dev/null +++ b/Server/src/main/content/minigame/vinesweeper/Vinesweeper.kt @@ -0,0 +1,766 @@ +package content.minigame.vinesweeper + +import BlinkinDialogue +import FarmerDialogue.Companion.FARMER_FLAG_LINES +import WinkinDialogue +import content.minigame.vinesweeper.Vinesweeper.Companion.FARMERS +import content.minigame.vinesweeper.Vinesweeper.Companion.FARMER_CLEAR_RADIUS +import content.minigame.vinesweeper.Vinesweeper.Companion.HOLES +import content.minigame.vinesweeper.Vinesweeper.Companion.NUMBERS +import content.minigame.vinesweeper.Vinesweeper.Companion.RABBITS +import content.minigame.vinesweeper.Vinesweeper.Companion.SEED_LOCS +import content.minigame.vinesweeper.Vinesweeper.Companion.populateSeeds +import content.minigame.vinesweeper.Vinesweeper.Companion.scheduleNPCs +import content.minigame.vinesweeper.Vinesweeper.Companion.sendPoints +import core.api.* +import core.cache.def.impl.ItemDefinition +import core.game.component.Component +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.interaction.InterfaceListener +import core.game.interaction.MovementPulse +import core.game.node.entity.Entity +import core.game.node.entity.combat.DeathTask +import core.game.node.entity.impl.Projectile +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import core.game.node.scenery.Scenery +import core.game.node.scenery.SceneryBuilder +import core.game.system.task.Pulse +import core.game.world.GameWorld +import core.game.world.GameWorld.ticks +import core.game.world.map.Location +import core.game.world.map.RegionManager +import core.game.world.map.zone.ZoneBorders +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import core.plugin.Initializable +import core.tools.RandomFunction +import org.rs09.consts.* +import kotlin.math.max +import kotlin.math.min +import org.rs09.consts.Graphics as Gfx +import org.rs09.consts.Scenery as Sceneries + +class Vinesweeper : InteractionListener, InterfaceListener, MapArea { + override fun defineAreaBorders(): Array { + return arrayOf(getRegionBorders(6473)) + } + + override fun areaEnter(entity: Entity) { + if(entity is Player) + { + openOverlay(entity, Components.RABBIT_OVERLAY_689) + sendUpdatedPoints(entity) + } + } + + override fun areaLeave(entity: Entity, logout: Boolean) { + if(entity is Player) { + entity.interfaceManager.closeOverlay() + if(!logout) { + sendMessage(entity, "Winkin's Farm thanks you for your visit.") + sendMessage(entity, "Leftover ogleroots and flags have been returned to the establishment.") + sendMessage(entity, "You have been reimbursed at a rate of 10gp per ogleroot and the flags have been collected.") + val flags = entity.inventory.getAmount(Item(Items.FLAG_12625)) + if(flags > 0) { + entity.setAttribute("/save:vinesweeper:stored-flags", flags) + entity.inventory.remove(Item(Items.FLAG_12625, flags)) + } + val roots = entity.inventory.getAmount(Item(Items.OGLEROOT_12624)) + if(roots > 0) { + entity.inventory.remove(Item(Items.OGLEROOT_12624, roots)) + entity.inventory.add(Item(Items.COINS_995, roots * 10)) + } + } + } + } + + override fun defineListeners() { + populateSeeds() + on(Sceneries.PORTAL_29534, IntType.SCENERY, "enter") { player, _ -> + val x = player.getAttribute("vinesweeper:return-tele:x", 3052) + val y = player.getAttribute("vinesweeper:return-tele:y", 3304) + val loc = Location(x, y) + if (ZoneBorders.forRegion(11060).insideBorder(loc) && !ItemDefinition.canEnterEntrana(player)) { + sendMessage(player, "The power of Saradomin prevents you from taking armour or weaponry to Entrana."); + return@on true + } + teleport(player, loc) + return@on true + } + on(SIGNS, IntType.SCENERY, "read") { player, node -> + player.interfaceManager.open(Component(INSTRUCTION_SIGNS[node.id]!!)) + return@on true + } + on(HOLES, IntType.SCENERY, "dig") { player, node -> + if(!player.inventory.contains(Items.SPADE_952, 1)) { + // TODO (crash): authenticity + player.sendMessage("You need a spade to dig here.") + } else { + player.visualize(Animation(Animations.HUMAN_VINESWEEPER_DIG_8709), Graphics(Gfx.VINESWEEPER_DIRT_DIG_1543)) + dig(player, node.location) + } + return@on true + } + onUseWith(IntType.SCENERY,Items.SPADE_952,*HOLES) { player, _, with -> + player.visualize(Animation(Animations.HUMAN_VINESWEEPER_DIG_8709), Graphics(Gfx.VINESWEEPER_DIRT_DIG_1543)) + dig(player, with.location) + return@onUseWith true + } + on(HOLES, IntType.SCENERY, "flag") { player, node -> + val hole = node as Scenery + var count = 0 + if(player.location != node.location) { + plantFlag(player,hole) + return@on true + } + GameWorld.Pulser.submit(object : MovementPulse(player, hole, hole.destinationFlag) { + override fun pulse(): Boolean { + when(count++) { + 0 -> { + player.faceLocation(hole.location) + return false + } + 1 -> { + plantFlag(player,hole) + return true + } + } + return true + } + }) + return@on true + } + onUseWith(IntType.SCENERY,Items.FLAG_12625,*HOLES) { player, _, with -> + val hole = with as Scenery + plantFlag(player,hole) + return@onUseWith true + } + on(HOLES, IntType.SCENERY, "inspect") { player, node -> + player.animate(Animation(Animations.HUMAN_INSPECT_HOLE_8710)) + player.lock(5) + GameWorld.Pulser.submit(object : Pulse(5) { + override fun pulse(): Boolean { + val msg = when(RandomFunction.random(0, 7)) { + 0 -> "You don't see anything interesting. You can't be sure if there's a seed there or not." + 1 -> "You get some mud in your eye and it stings! You have no idea what is in the hole." + 2 -> "The mud seems to be too thick to see what is there." + 3 -> "A slimy worm wriggles out of the mud, making you jump and lose concentration. You're not sure if there is a seed here or not." + else -> if(isSeed(node.location)) { + "You notice a seed hidden in the dirt." + } else { + "You are certain there is no seed planted here." + } + } + sendDialogue(player, msg) + return true + } + }) + return@on true + } + on(NPCs.MRS_WINKIN_7132, IntType.NPC, "talk-to") { player, npc -> + openDialogue(player, WinkinDialogue(), npc) + return@on true + } + on(NPCs.MRS_WINKIN_7132, IntType.NPC, "trade") { player, _ -> + player.interfaceManager.open(Component(686)) + return@on true + } + on(NPCs.MRS_WINKIN_7132, IntType.NPC, "buy flags") { player, npc -> + val dialogue = WinkinDialogue() + dialogue.stage = 20 + openDialogue(player, dialogue, npc) + return@on true + } + on(RABBITS, IntType.NPC, "feed") { player, node -> + val rabbit = node as NPC + feedRabbit(player,rabbit) + return@on true + } + onUseWith(IntType.NPC,Items.OGLEROOT_12624,*RABBITS) { player, _, with -> + val rabbit = with as NPC + feedRabbit(player,rabbit) + return@onUseWith true + } + on(NPCs.FARMER_BLINKIN_7131, IntType.NPC, "talk-to") { player, npc -> + //player.interfaceManager.open(Component(TUTORIAL)) + openDialogue(player, BlinkinDialogue(), npc) + return@on true + } + on(NPCs.FARMER_BLINKIN_7131, IntType.NPC, "buy-flags") { player, npc -> + val dialogue = BlinkinDialogue() + dialogue.stage = 21 + openDialogue(player, dialogue, npc) + return@on true + } + on(NPCs.FARMER_BLINKIN_7131, IntType.NPC, "buy-roots") { player, npc -> + val dialogue = BlinkinDialogue() + dialogue.stage = 40 + openDialogue(player, dialogue, npc) + return@on true + } + } + + override fun defineInterfaceListeners() { + on(IFACE) { player, _, opcode, buttonID, _, _ -> + when(opcode) { + Opcode.VALUE.value -> { + when(buttonID) { + TRADE_FOR_XP_BUTTON -> { + player.packetDispatch.sendInterfaceConfig(686, 60, false) + } + XP_CONFIRM -> { + player.packetDispatch.sendInterfaceConfig(686, 60, true) + val level = player.skills.getStaticLevel(Skills.FARMING) + // TODO: more precise formula + val points_per_xp = if (level < 40) { max(1.0, 2.0*(40.0 - level.toDouble())/10.0) } else { 1.0 } + val points = player.getAttribute("vinesweeper:points", 0) + val xp = points / points_per_xp + player.skills.addExperience(Skills.FARMING, xp) + player.setAttribute("/save:vinesweeper:points", 0) + sendUpdatedPoints(player) + + } + XP_DENY -> { + player.packetDispatch.sendInterfaceConfig(686, 60, true) + } + else -> { + val reward = REWARDS[buttonID] ?: return@on true + player.sendMessage("${Item(reward.itemID).name}: ${reward.points} vinesweeper points") + } + } + } + Opcode.BUY1.value -> { + buy(player, buttonID, 1) + return@on true + } + Opcode.BUY5.value -> { + buy(player, buttonID, 5) + return@on true + } + Opcode.BUY10.value -> { + buy(player, buttonID, 10) + return@on true + } + Opcode.BUYX.value -> { + player.setAttribute("runscript") { amount: Int -> + buy(player, buttonID, amount) + } + player.dialogueInterpreter.sendInput(false, "Enter the amount:") + return@on true + } + else -> {} + } + return@on true + } + } + + data class SeedDestination(val player: Player, val loc: Location, val alive: Boolean) { + override fun equals(other: Any?): Boolean { + return if(other is SeedDestination) { + loc == other.loc + } else { + false + } + } + + override fun hashCode(): Int { + return loc.hashCode() + } + } + + companion object + { + val AVACH_NIMPORTO_LOC = Location.create(1637, 4709) + val SIGNS = intArrayOf(Sceneries.INSTRUCTION_SIGN_29461, Sceneries.INSTRUCTION_SIGN_29462, Sceneries.INSTRUCTION_SIGN_29463, Sceneries.INSTRUCTION_SIGN_29464) + val HOLES = intArrayOf(Sceneries.HOLE_29476, Sceneries.HOLE_29477, Sceneries.HOLE_29478) + val NUMBERS = intArrayOf(29447, 29448, 29449, 29450, 29451, 29452, 29453, 29454, 29455) + + val IFACE = 686 + val TRADE_FOR_XP_BUTTON = 53 + val XP_CONFIRM = 72 + val XP_DENY = 73 + + enum class Opcode(val value: Int) { + VALUE(155), + BUY1(196), + BUY5(124), + BUY10(199), + BUYX(234), + } + + data class Reward(val itemID: Int, val points: Int) {} + + val REWARDS = hashMapOf( + 18 to Reward(Items.TOMATO_SEED_5322, 10), + 19 to Reward(Items.SWEETCORN_SEED_5320, 150), + 20 to Reward(Items.STRAWBERRY_SEED_5323, 165), + 21 to Reward(Items.WATERMELON_SEED_5321, 680), + 22 to Reward(Items.GUAM_SEED_5291, 10), + 23 to Reward(Items.MARRENTILL_SEED_5292, 10), + 24 to Reward(Items.RANARR_SEED_5295, 4000), + 25 to Reward(Items.KWUARM_SEED_5299, 1000), + 26 to Reward(Items.TARROMIN_SEED_5293, 10), + 27 to Reward(Items.NASTURTIUM_SEED_5098, 10), + + 28 to Reward(Items.WOAD_SEED_5099, 30), + 29 to Reward(Items.LIMPWURT_SEED_5100, 70), + 30 to Reward(Items.ASGARNIAN_SEED_5308, 5), + 31 to Reward(Items.KRANDORIAN_SEED_5310, 20), + 32 to Reward(Items.REDBERRY_SEED_5101, 5), + 33 to Reward(Items.CADAVABERRY_SEED_5102, 5), + 34 to Reward(Items.DWELLBERRY_SEED_5103, 5), + 35 to Reward(Items.JANGERBERRY_SEED_5104, 10), + 36 to Reward(Items.WHITEBERRY_SEED_5105, 25), + + 37 to Reward(Items.POISON_IVY_SEED_5106, 30), + 38 to Reward(Items.ACORN_5312, 100), + 39 to Reward(Items.WILLOW_SEED_5313, 1800), + 40 to Reward(Items.MAPLE_SEED_5314, 12000), + 41 to Reward(Items.PINEAPPLE_SEED_5287, 10000), + 42 to Reward(Items.YEW_SEED_5315, 29000), + 43 to Reward(Items.PALM_TREE_SEED_5289, 35000), + 44 to Reward(Items.SPIRIT_SEED_5317, 55000), + 45 to Reward(Items.COMPOST_POTION4_6470, 5000), + 46 to Reward(Items.FLAG_12625, 50), + ) + + fun buy(player: Player, buttonID: Int, amount: Int) { + val reward = REWARDS[buttonID] ?: return + val cost = amount * reward.points + val points = player.getAttribute("vinesweeper:points", 0) + if(cost in 1 until points) { + val item = Item(reward.itemID, amount) + if(!player.inventory.add(item)) { + GroundItemManager.create(item, player) + } + player.incrementAttribute("/save:vinesweeper:points", -cost) + sendUpdatedPoints(player) + } else { + // TODO (crash): authenticity + player.sendMessage("You don't have enough points for that.") + } + } + + + val TUTORIAL = 685 + + val INSTRUCTION_SIGNS = hashMapOf( + 29463 to 684, + 29464 to 687, + 29462 to 688, + 29461 to 690 + ) + + val RABBITS = intArrayOf(NPCs.RABBIT_7125, NPCs.RABBIT_7126, NPCs.RABBIT_7127) + val FARMERS = intArrayOf(NPCs.FARMER_7128, NPCs.FARMER_7129, NPCs.FARMER_7130) + + val MAX_SEEDS = 300 + val FARMER_CLEAR_RADIUS = 3 + val VINESWEEPER_BORDERS = ZoneBorders(1600,4672,1663,4735) + + fun sendUpdatedPoints(player: Player) { + val points = player.getAttribute("vinesweeper:points", 0) + setVarbit(player, 4449, points) + } + + var SEED_LOCS: HashSet = HashSet() + + fun isSeed(loc: Location): Boolean { + val scenery = getScenery(loc) + return scenery != null && SEED_LOCS.contains(scenery.location) + } + + fun populateSeeds() { + val holes = countHoles() + val seeds = min(1.0 * MAX_SEEDS, holes * 0.13).toInt() + var tries = 0 // Prevent the while loop from crashing the server + while(SEED_LOCS.size < seeds && tries++ < 1000) { + val loc = VINESWEEPER_BORDERS.getRandomLoc() + val scenery = getScenery(loc) + if(scenery != null && HOLES.contains(scenery.id)) { + SEED_LOCS.add(loc) + } + } + } + + private fun countHoles(): Int { + val northEastX = VINESWEEPER_BORDERS.northEastX + val northEastY = VINESWEEPER_BORDERS.northEastY + val southWestX = VINESWEEPER_BORDERS.southWestX + val southWestY = VINESWEEPER_BORDERS.southWestY + var holeCount = 0 + for (x in southWestX .. northEastX){ + for (y in southWestY .. northEastY){ + val scenery = getScenery(x, y, 0) + if(scenery != null && HOLES.contains(scenery.id)) { + holeCount++ + } + } + } + return holeCount + } + + fun plantFlag(player: Player, hole: Scenery) { + if(player.inventory.remove(Item(Items.FLAG_12625, 1))) { + player.lock() + player.visualize(Animation(Animations.HUMAN_PLANT_FLAG_8711),Graphics(Gfx.VINESWEEPER_PLANT_FLAG_1541)) + player.sendMessage("You add a flag to the patch.") + GameWorld.Pulser.submit(object : Pulse(2, player) { + override fun pulse(): Boolean { + SceneryBuilder.replace(hole, hole.transform(Sceneries.FLAG_29457)) + scheduleNPCs(player, hole.location, true, true) + player.unlock() + return true + } + }) + } else { + // TODO (crash): authenticity + player.sendMessage("You do not have a flag to place in the patch.") + } + } + + fun feedRabbit(player: Player, rabbit: NPC) { + val respawnDelay = 50 + if(rabbit.isInvisible || DeathTask.isDead(rabbit)) { return } + if(rabbit.getAttribute("dead", 0) > ticks) { return } + if(player.inventory.remove(Item(Items.OGLEROOT_12624, 1))) { + rabbit.setAttribute("dead",ticks + respawnDelay) + player.skills.addExperience(Skills.HUNTER, 30.0) + rabbit.sendChat("Squeak!") + rabbit.animate(Animation(Animations.RABBIT_EAT_OGLEROOT_8734)) + rabbit.lock(4) + GameWorld.Pulser.submit(object : Pulse(3, player) { + override fun pulse(): Boolean { + rabbit.finalizeDeath(player) + rabbit.properties.teleportLocation = rabbit.properties.spawnLocation + return true + } + }) + } else { + // TODO (crash): authenticity + player.sendMessage("You don't have any ogleroots to feed the rabbit.") + } + } + + fun dig(player: Player, loc: Location) { + if(isSeed(loc)) { + val oldPoints = player.getAttribute("vinesweeper:points", 0) + player.setAttribute("/save:vinesweeper:points", Math.max(oldPoints-10, 0)) + sendUpdatedPoints(player) + player.sendMessage("Oh dear! It looks like you dug up a potato seed by mistake.") + scheduleNPCs(player, loc, false, false) + val scenery = getScenery(loc) + if(scenery != null) { + SceneryBuilder.replace(scenery, scenery.transform(Sceneries.DEAD_PLANT_29456)) + } + } else { + player.incrementAttribute("/save:vinesweeper:points", 1) + sendUpdatedPoints(player) + var count = 0 + for(dx in -1..1) { + for(dy in -1..1) { + if(isSeed(loc.transform(dx, dy, 0))) { + count += 1 + } + } + } + val scenery = getScenery(loc) + if(scenery != null) { + SceneryBuilder.replace(scenery, scenery.transform(NUMBERS[count])) + } + if(count == 0) { + for(dx in -1..1) { + for(dy in -1..1) { + val newLoc = loc.transform(dx, dy, 0) + if(isHole(newLoc)) + dig(player, newLoc) + } + } + } + } + } + + fun sendPoints(npc: NPC, dest: SeedDestination) { + val level = dest.player.skills.getStaticLevel(Skills.FARMING) + val points = RandomFunction.random(level, 4 * level) + dest.player.incrementAttribute("/save:vinesweeper:points", points) + dest.player.inventory.add(Item(Items.FLAG_12625, 1)) + sendUpdatedPoints(dest.player) + for (neighbor in RegionManager.getLocalPlayers(npc)) { + if (neighbor != dest.player) { + neighbor.incrementAttribute("/save:vinesweeper:points", points / 2) + sendUpdatedPoints(neighbor) + } + } + } + + fun isHole(loc: Location): Boolean { + val scenery = getScenery(loc) + return scenery != null && HOLES.contains(scenery.id) + } + + fun scheduleNPCs(player: Player, loc: Location, alive: Boolean, rabbit: Boolean) { + val dest = SeedDestination(player, loc, alive) + val ids = if(rabbit) { RABBITS + FARMERS } else { FARMERS } + for(npc in findLocalNPCs(player, ids, 30)) { + if(npc is VinesweeperNPC) { + npc.seedDestinations.add(dest) + npc.resetWalk() + } + } + } + + object VinesweeperTeleport { + @JvmStatic + fun teleport(npc: NPC, player: Player) { + if (hasTimerActive(player, "teleblock")) { + sendNPCDialogue(player, npc.id, "I can't do that, you're teleblocked!", core.game.dialogue.FacialExpression.OLD_ANGRY1) + return + } + npc.animate(Animation(437)) + npc.faceTemporary(player, 1) + npc.graphics(Graphics(108)) + player.lock() + playAudio(player, Sounds.CURSE_ALL_125, 0, 1) + Projectile.create(npc, player, 109).send() + npc.sendChat("Avach nimporto!") + GameWorld.Pulser.submit(object : Pulse(1, player) { + var counter = 0 + override fun pulse(): Boolean { + when (counter++) { + 2 -> { + player.savedData.globalData.essenceTeleporter = npc.id + player.setAttribute("/save:vinesweeper:return-tele:x", npc.location.x) + player.setAttribute("/save:vinesweeper:return-tele:y", npc.location.y) + player.properties.teleportLocation = AVACH_NIMPORTO_LOC + } + 3 -> { + player.graphics(Graphics(110)) + player.unlock() + return true + } + } + return false + } + }) + } + } + } +} + +@Initializable +class VinesweeperNPC : AbstractNPC { + var seedDestinations: ArrayList = ArrayList() + + constructor() : super(RABBITS[0], null, true) {} + private constructor(id: Int, location: Location) : super(id, location) {} + override fun construct(id: Int, location: Location, vararg objects: Any?): AbstractNPC { + return VinesweeperNPC(id, location) + } + + init { + walkRadius = 22 + } + + override fun getIds(): IntArray { + return RABBITS + FARMERS + } + override fun handleTickActions() { + val dest = seedDestinations.find { sd -> sd.loc == location } + if (locks.isMovementLocked() || locks.isInteractionLocked()) + return + if(dest != null) { + for(npc in RegionManager.getRegionPlane(location).npcs) { + if(npc is VinesweeperNPC) { + npc.seedDestinations.remove(dest) + npc.resetWalk() + } + } + val scenery = getScenery(dest.loc) + if(scenery != null) { + if(id in RABBITS) { + handleRabbitSeed(scenery, dest) + } else { + if(dest.alive) { + handleFarmerFlag(scenery, dest) + } else { + handleFarmerSeed(scenery, dest) + } + } + } + seedDestinations.remove(dest) + } + super.handleTickActions() + } + + override fun getMovementDestination(): Location? { + if(seedDestinations.size > 0) { + seedDestinations.sortBy { a -> a.loc.getDistance(location).toInt() } + return seedDestinations.first().loc + } else { + return super.getMovementDestination() + } + } + + fun handleRabbitSeed(scenery: Scenery, dest: Vinesweeper.SeedDestination) { + if(SEED_LOCS.contains(dest.loc)) { + val replacement = Sceneries.DEAD_PLANT_29456 + lock(4) + animate(Animation(Animations.RABBIT_EAT_SEED_8718)) + SceneryBuilder.replace(scenery, scenery.transform(replacement)) + scheduleNPCs(dest.player, dest.loc, alive = false, rabbit = false) + } else { + scheduleNPCs(dest.player, dest.loc, alive = true, rabbit = false) + } + } + fun handleFarmerSeed(scenery: Scenery, dest: Vinesweeper.SeedDestination) { + lock() + var i = 0 + animate(Animation(Animations.GNOME_FARMER_DIG_SEED_8730)) + GameWorld.Pulser.submit(object: Pulse(3) { + override fun pulse(): Boolean { + when(i++) { + 0 -> { + sendChat(FARMER_FLAG_LINES.FIND_PLANT.line) + } + 1 -> { + animate(Animation(Animations.GNOME_FARMER_SPADE_SMACK_8732)) + sendChat(FARMER_FLAG_LINES.DEAD_PLANT.line) + SceneryBuilder.replace(scenery, scenery.transform(HOLES[0])) + } + 2 -> { + animate(Animation(Animations.GNOME_FARMER_CLEAR_HOLES_8724)) + farmerClear(dest) + } + 3 -> { + unlock() + return true + } + } + return false + } + }) + } + fun handleFarmerFlag(scenery: Scenery, dest: Vinesweeper.SeedDestination) { + val npc = this + lock() + var i = 0 + animate(Animation(Animations.GNOME_FARMER_DIG_FLAG_8725)) + GameWorld.Pulser.submit(object: Pulse(3) { + override fun pulse(): Boolean { + when(i++) { + 0 -> { + sendChat(FARMER_FLAG_LINES.FIND_FLAG.line) + } + 1 -> { + SceneryBuilder.replace(scenery, scenery.transform(HOLES[0])) + if(SEED_LOCS.contains(dest.loc)) { + sendChat(FARMER_FLAG_LINES.FIND_SEED.line) + animate(Animation(Animations.GNOME_FARMER_HOORAY_8731)) + sendPoints(npc,dest) + i++ + } else { + sendChat(FARMER_FLAG_LINES.NO_SEED.line) + } + } + 2 -> { + sendChat(FARMER_FLAG_LINES.KEEP_FLAG.line) + i++ + } + 3 -> { + animate(Animation(Animations.GNOME_FARMER_CLEAR_HOLES_8724)) + farmerClear(dest) + + } + 4 -> { + unlock() + return true + } + } + return false + } + }) + } + + fun farmerClear(dest: Vinesweeper.SeedDestination) { + for(dx in -FARMER_CLEAR_RADIUS..FARMER_CLEAR_RADIUS) { + for(dy in -FARMER_CLEAR_RADIUS..FARMER_CLEAR_RADIUS) { + val toClear = getScenery(dest.loc.transform(dx, dy, 0)) + if(toClear != null && intArrayOf(Sceneries.DEAD_PLANT_29456, *NUMBERS).contains(toClear.id)) { + SceneryBuilder.replace(toClear, toClear.transform(HOLES[0])) + } + } + } + SEED_LOCS.remove(dest.loc) + populateSeeds() + } +} + + + +/* +https://www.youtube.com/watch?v=WkCVAOOR7Sw +buy-flags +Player: "Have you got any flags?" +NPC: "Let me check for you." +NPC: "Alright, you can have a total of 10 flags. To obtain a\nfull set of flags will cost you 5000 coins. Would you\nlike to buy these flags?" +"Yes, please." "No thanks." +NPC: "Here you are then, dear." + +talk-to +NPC: "Oh hello there, dear. How can I help you?" +"Where are we?" "Have you got any flags?" "Do you have a spare spade?" "Do you have anything for trade?" "Nothing. I'm fine, thanks." + +Player: "Do you have a spare spade?" +NPC: "Why, of course. I can sell you one for 5 gold pieces." +"Okay, thanks." "Actually, I've changed my mind." +NPC: "Here you are, then." + +inspect: +chat log: "You examine the hole to see what might be in it." +chat dialog: "You notice a seed hidden in the dirt." + +Farmer overhead: +"Ah, another flag to clear. Let's see what's there." +"Ah! A seed. Points for everyone near me!" + +https://www.youtube.com/watch?v=UjxfJdHkJnM +inspect: +"Oh dear! It looks like you dug up a potato seed by mistake." +Farmer overhead: +"Hmm. Looks like there's a plant here." +"Gracious me! This one's dead" + +flag: +"You add a flag to the patch." + +digging ogleroot: +"You uncover a rather odd-looking root vegetable." + +https://www.youtube.com/watch?v=fKyy0sgrBYM +Rabbit overhead: +"Squeak!" + +https://www.youtube.com/watch?v=RnhNrwbUjjQ +Player: "Have you got any flags?" +NPC: "Let me check for you." +NPC: "Ah! First things first. One of the farmers dropped off\nsome flags for you. You can have them back. Here you\ngo." + +NPC: "It looks like you have all the flags you need. You don't\nneed to buy any more." + +inspect: +"You notice a seed hidden in the dirt." +"A slimy worm wriggles out of the mud, making you jump and lose\nconcentration. You're not sure if there is a seed here or not." +"You are certain there is no seed planted here." + +farmer overhead: +"Hmm, no seeds planted here, I'm afraid." +"I'll have to keep this 'ere flag. Sorry." + +*/ diff --git a/Server/src/main/content/minigame/vinesweeper/VinesweeperDialogues.kt b/Server/src/main/content/minigame/vinesweeper/VinesweeperDialogues.kt new file mode 100644 index 0000000..23c0124 --- /dev/null +++ b/Server/src/main/content/minigame/vinesweeper/VinesweeperDialogues.kt @@ -0,0 +1,208 @@ +import core.game.component.Component +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import org.rs09.consts.Items +import core.game.dialogue.DialogueFile +import core.tools.END_DIALOGUE +import core.api.* + +abstract class FarmerDialogue : DialogueFile() { + + companion object { + val BLINKIN_FLAG_LINES = arrayOf( + "Let me check for ya.", + "Flags? It appears ya don't have enough room for 'em. Make some space and talk to me again.", + "Ah! First things first. One of the farm lads dropped off some flags for ya. Ya can have them back. Here ya go.", + "Righty-ho! Ya can have a total of 10 flags. To get yerself a full set of flags'll cost ya %d gold pieces. Would ya like to buy these flags?", + "Here ya go, then.", + "Flags? It appears ya don't have enough room for 'em. Make some space and talk to me again.", + "Ya don't have the coins fer these, I'm afraid! Come back when yer a little bit richer p'raps?", + "Right y'are then! See ya.", + "It looks like ya got all the flags ya need right now. Ya don't need to buy any more." + ) + val WINKIN_FLAG_LINES = arrayOf( + "Let me check for you.", + "I'm sorry dear, you don't appear to have enough room. Make some space and talk to me again.", + "Ah! First things first. One of the farmers dropped off some flags for you. You can have them back. Here you go.", + "Alright. You can have a total of 10 flags. To obtain a full set of flags will cost you %d coins. Would you like to buy these flags?", + "Here you are then, dear.", + "I'm sorry dear, you don't appear to have enough room. Make some space and talk to me again.", + "I'm afraid it looks like you don't have enough money, dear. Come back and see me again when you have a bit more.", + "Ok, dear. Goodbye.", + "It looks like you have all the flags you need. You don't need to buy any more." + ) + enum class FARMER_FLAG_LINES(val line: String) { + FIND_FLAG("Ah, another flag to clear. Let's see what's there."), + FIND_SEED("Ah! A seed. Points for everyone near me!"), + NO_SEED("Hmm, no seeds planted here, I'm afraid."), + KEEP_FLAG("I'll have to keep this 'ere flag. Sorry."), + FIND_PLANT("Hmm. Looks like there's a plant here."), + DEAD_PLANT("Gracious me! This one's dead") + } + } + fun handleFlags(componentID: Int, buttonID: Int, lines: Array) { + when(stage) { + 20 -> npcl(lines[0]).also { stage++ } + 21 -> { + val flags = player!!.getAttribute("vinesweeper:stored-flags", 10) + if(flags > 0) { + if(!player!!.inventory.add(Item(Items.FLAG_12625, flags))) { + npcl(lines[1]) + stage = END_DIALOGUE + } else { + player!!.setAttribute("/save:vinesweeper:stored-flags", 0) + npcl(lines[2]) + stage++ + } + } else { + stage++ + handle(componentID, buttonID) + } + } + 22 -> { + val flags = player!!.inventory.getAmount(Items.FLAG_12625) + if(flags < 10) { + val price = 500 * (10 - flags) + npcl(String.format(lines[3], price)) + stage = 220 + } else { + stage = 23 + handle(componentID, buttonID) + } + } + 220 -> options("Yes, please.", "No, thanks").also { stage++ } + 221 -> when(buttonID) { + 1 -> playerl("Yes, please.").also { stage = 222 } + 2 -> playerl("No, thanks.").also { stage = 223 } + } + 222 -> { + val flags = player!!.inventory.getAmount(Items.FLAG_12625) + val price = Item(Items.COINS_995, 500 * (10 - flags)) + if(player!!.inventory.containsItem(price) && player!!.inventory.remove(price)) { + if(player!!.inventory.add(Item(Items.FLAG_12625, 10 - flags))) { + npcl(lines[4]) + stage = 22 + stage = END_DIALOGUE + } else { + npcl(lines[5]) + // Refund the coins, can't fail because we just removed them + player!!.inventory.add(price) + stage = END_DIALOGUE + } + } else { + npcl(lines[6]) + stage = END_DIALOGUE + } + } + 223 -> npcl(lines[7]).also { stage = END_DIALOGUE } + 23 -> npcl(lines[8]).also { stage = END_DIALOGUE } + } + } +} +class BlinkinDialogue : FarmerDialogue() { + override fun handle(componentID: Int, buttonID: Int) { + when(stage) { + 0 -> npcl("'Ello there! Welcome to Winkin's Farm. What can I do for ya?").also { stage++ } + 1 -> options("What is this place?", "Do you have any flags?", "Where is Mr. Winkin?").also { stage++ } + 2 -> when(buttonID) { + 1 -> playerl("What is this place?").also { stage = 10 } + 2 -> playerl("Do you have any flags?").also { stage = 20 } + 3 -> playerl("Where is Mr. Winkin?").also { stage = 30 } + } + 10 -> npcl("Ha! I told ya, it's Winkin's Farm. This is where we grow the magical ogleroots for the rest of the world.").also { stage++ } + 11 -> playerl("So, what can I do here?").also { stage++ } + 12 -> npcl("Ya can improve yer Farming skill by getting some flags from me or Mrs. Winkin, inside. Then, head out to the fields and flag where ya think plants are, er, planted.").also { stage++ } + 13 -> playerl("Is that it?").also { stage++ } + 14 -> npcl("Not at all! There's more. When ya've placed yar flags, the farmers will collect them up and give out points. Ya can trade these points for seeds or experience at the shop inside.").also { stage++ } + 15 -> playerl("Okay, that sounds great! I'll get planting, then.").also { stage++ } + 16 -> npcl("Aye, but be careful where ya plant the flags. If there's no plant under yar flag, the farmer will keep it and they cost a pretty penny to buy more.").also { stage++ } + 17 -> playerl("I see. Thanks for the help.").also { stage++ } + 18 -> npcl("Bye, for now. If I have to say 'flag' one more time, I tell ya...").also { stage = END_DIALOGUE } + 20, 21, 22, 220, 221, 222, 223, 23 -> handleFlags(componentID, buttonID, BLINKIN_FLAG_LINES) + 30 -> npcl("Farmer Winkin? Well, last I 'eard he was heading into market with a fresh load of Ogleroots.").also { stage++ } + 31 -> playerl("Ogleroots?").also { stage++ } + 32 -> npcl("Aye! We get them growing a lot here in the farmyard. We dig 'em up and sell 'em to yar lot.").also { stage++ } + 33 -> playerl("My lot?").also { stage++ } + 34 -> npcl("Aye! Humans.").also { stage++ } + 35 -> playerl("Oh, I see. Thanks!").also { stage++ } + 36 -> npcl("Bye now!").also { stage = END_DIALOGUE } + // Not accessible in normal conversation, requires "buy-roots" right click + 40 -> playerl("Do you have any Ogleroots to feed the rabbits?").also { stage++ } + 41 -> npcl("I sure do. They'll cost ya 10 gold each. Any ya leave with will be returned to us, but ya'll get yer money back for 'em. How many do ya want?").also { stage++ } + 42 -> { + sendInputDialogue(player!!, InputType.AMOUNT, "Enter an amount:") { value -> + val amount = value as Int + val price = Item(Items.COINS_995, 10 * amount) + if(price.amount <= 0){ + return@sendInputDialogue + } + if(player!!.inventory.containsItem(price) && player!!.inventory.remove(price)) { + if(player!!.inventory.add(Item(Items.OGLEROOT_12624, amount))) { + npcl("There ya go! Good luck!") + stage = END_DIALOGUE + } else { + npcl("TODO (crash): dialogue for no space for ogleroots") + // Refund the coins, can't fail because we just removed them + player!!.inventory.add(price) + stage = END_DIALOGUE + } + } else { + npcl("Sorry, ya can't afford that many. Come back when yer feeling a bit richer if ya like!") + stage = END_DIALOGUE + } + //openDialogue(player!!, this, npc as Any) + } + player!!.dialogueInterpreter.sendInput(false, "Enter the amount:") + } + } + } +} + +class WinkinDialogue : FarmerDialogue() { + override fun handle(componentID: Int, buttonID: Int) { + when(stage) { + 0 -> npcl("Oh, hello there, dear. How can I help you?").also { stage++ } + 1 -> options("Where are we?", "Have you got any flags?", "Do you have a spare spade?", "Do you have anything for trade?", "Nothing. I'm fine, thanks.").also { stage++ } + 2 -> when(buttonID) { + 1 -> playerl("Where are we?").also { stage = 10 } + 2 -> playerl("Have you got any flags?").also { stage = 20 } + 3 -> playerl("Do you have a spare spade?").also { stage = 30 } + 4 -> playerl("Do you have anything for trade?").also { stage = 40 } + 5 -> playerl("Nothing. I'm fine, thanks.").also { stage = 50 } + } + 10 -> npcl("This is Winkin's Farm, dear.").also { stage++ } + 11 -> playerl("Oh, I see. So where is Mr. Winkin?").also { stage++ } + 12 -> npcl("Oh, he headed off to the market a while back. We look after the farm while he's gone.").also { stage++ } + 13 -> npcl("Now, was there anything else you wanted?").also { stage = 1 } + 20, 21, 22, 220, 221, 222, 223, 23 -> handleFlags(componentID, buttonID, WINKIN_FLAG_LINES) + 30 -> npcl("Why, of course. I can sell you one for 5 gold pieces.").also { stage++ } + 31 -> options("Okay, thanks.", "Actually, I've changed my mind.").also { stage++ } + 32 -> when(buttonID) { + 1 -> playerl("Okay, thanks.").also { stage = 320 } + 2 -> playerl("Actually, I've changed my mind.").also { stage = 330 } + } + 320 -> { + val price = Item(Items.COINS_995, 5) + if(player!!.inventory.containsItem(price) && player!!.inventory.remove(price)) { + npcl("Here you are, then.") + val spade = Item(Items.SPADE_952) + if(!player!!.inventory.add(spade)) { + GroundItemManager.create(spade, player) + } + stage = END_DIALOGUE + } else { + npcl("I'm afraid it looks like you don't have enough money, dear. Come back and see me again when you have a bit more.") + stage = END_DIALOGUE + } + } + 330 -> npcl("Okay then.").also { stage = END_DIALOGUE } + 40 -> npcl("Of course.").also { stage++ } + 41 -> { + end() + player!!.interfaceManager.open(Component(686)) + } + 50 -> playerl("Nothing. I'm fine, thanks.").also { stage++ } + 51 -> npcl("Okay, dear.").also { stage = END_DIALOGUE } + } + } +} diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/AjjatDialoguePlugin.java b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/AjjatDialoguePlugin.java new file mode 100644 index 0000000..e92c4be --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/AjjatDialoguePlugin.java @@ -0,0 +1,164 @@ +package content.region.asgarnia.burthorpe.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.global.Skillcape; +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; + +/** + * Represents the dialogue plugin used for the ajjat npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class AjjatDialoguePlugin extends DialoguePlugin { + + /** + * Constructs a new {@code AjjatDialoguePlugin} {@code Object}. + */ + public AjjatDialoguePlugin() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code AjjatDialoguePlugin} {@code Object}. + * @param player the player. + */ + public AjjatDialoguePlugin(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new AjjatDialoguePlugin(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + npc("Greetings, fellow warrior. I am Ajjat, former Black Knight", "and now traning officer here in the Warriors' Guild."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "Can you tell me about skillcapes, please?", "Black knight? Why are you here?", "What's the dummy room all about?", "May I claim my tokens please?", "Bye!"); + stage = 1; + break; + case 1: + if (buttonId == 1) { + player("Can you tell me about skillcapes, please?"); + stage = 2; + } else if (buttonId == 2) { + player("Black knight? Why are you here?"); + stage = 4; + } else if (buttonId == 3) { + player("What's the dummy room all about?"); + stage = 6; + } else if (buttonId == 4) { + end(); + player.getDialogueInterpreter().open("wg:claim-tokens", npc.getId()); + } else if (buttonId == 5) { + player("Bye!"); + stage = 12; + } + break; + case 2: + npc("Skillcapes, also knows as Capes of Accomplishment, are", "reserved for the elite of the elite. Only a person who has", "truly mastered a skill can buy one, even then a", "Skillcape can only be bought from one who is recognised as"); + stage = 3; + break; + case 3: + npc("the highest skilled in the land at any particular skill. I", "have the privilege of being the person that controls", "acces to the Skillcape of Attack. Is there anything else I", "can help you with?"); + stage = 600; + break; + case 4: + npc("Indeed I was however, their... methods did not match", "with my ideals, so I left. Harrallak, recognsing my talent as", "a warrior, took me in and offered me a job here."); + stage = 5; + break; + case 5: + player("Hmm...well, if Harrallak trusts you, I guess I can."); + stage = 0; + break; + case 6: + npc("Ahh yes, the dummies. Another ingenious invention of the", "noble dwarf, Gamfred. They're mechanical, you see, and", "pop up out of the floor. You have to hit them with the", "correct attack mode before they dissapear again."); + stage = 7; + break; + case 7: + player("Do, how do I tell wich one is wich?"); + stage = 8; + break; + case 8: + npc("here are two different ways. One indication is their", "colour, the other is the pose and weapons they are", "holding, for instance, the one holding daggers you will", "to hit with a piercing attack."); + stage = 9; + break; + case 9: + npc("In the room, you will find a poster on the wall to", " help you recognize each different dummy."); + stage = 10; + break; + case 10: + player("That sounds ingenious!"); + stage = 11; + break; + case 11: + npc("Indeed, you may find that you need several weapons to", "be successfull all of the time, but keep trying", "The weapons Shop upstairs may help you there."); + stage = 0; + break; + case 12: + npc("Farewell, warrior. Stay away from the dark side."); + stage = 13; + break; + case 13: + end(); + break; + case 600: + if (player.getSkills().getStaticLevel(Skills.ATTACK) == 99) { + player("I'd like to buy a skillcape of Attack."); + stage = 601; + } else { + end(); + } + break; + case 601: + npc("Okay, it will cost you 99000 coins", "is that ok?"); + stage = 602; + break; + case 602: + options("Yes.", "No."); + stage = 603; + break; + case 603: + switch (buttonId) { + case 1: + player("Yes."); + stage = 604; + break; + case 2: + end(); + break; + } + break; + case 604: + if (Skillcape.purchase(player, Skills.ATTACK)) { + npc("There you go! Enjoy."); + } + stage = 605; + break; + case 605: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 4288 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/AntonDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/AntonDialogue.kt new file mode 100644 index 0000000..f777ba0 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/AntonDialogue.kt @@ -0,0 +1,45 @@ +package content.region.asgarnia.burthorpe.dialogue + +import core.api.openDialogue +import core.api.openNpcShop +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class AntonDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, AntonDialogueFile(), npc) + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return AntonDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.ANTON_4295) + } +} + +class AntonDialogueFile : DialogueBuilderFile() { + + override fun create(b: DialogueBuilder) { + b.defaultDialogue().npcl( + FacialExpression.ASKING, + "Ahhh, hello there. How can I help?") + .playerl(FacialExpression.NEUTRAL, + "Looks like you have a good selection of weapons around here...") + .npcl(FacialExpression.FRIENDLY, + "Indeed so, specially imported from the finest smiths around the lands, take a look at my wares.") + .endWith { _, player -> + openNpcShop(player, NPCs.ANTON_4295) + end() + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/BernaldDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/BernaldDialogue.kt new file mode 100644 index 0000000..2e1ca6b --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/BernaldDialogue.kt @@ -0,0 +1,46 @@ +package content.region.asgarnia.burthorpe.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +/** + * Bernald Dialogue + * @author ovenbread + * + * https://www.youtube.com/watch?v=4odb7qhBPfA + * https://www.youtube.com/watch?v=nisJKOtqWIo 1:08:53 + */ +@Initializable +class BernaldDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { +// // Garden of Tranquility has not been implemented. +// if(hasRequirement(player!!, Quests.GARDEN_OF_TRANQUILITY)) { +// if (isQuestComplete(player!!, Quests.DEATH_PLATEAU)) { +// when (stage) { +// 0 -> playerl(FacialExpression.FRIENDLY, "How are your grapes coming along?").also { stage++ } +// 1 -> npc(FacialExpression.FRIENDLY, "Marvellous, thanks to your help, " + player.username + "!").also { stage = END_DIALOGUE } +// } +// } +// } + when (stage) { + START_DIALOGUE -> npcl(FacialExpression.WORRIED, "Do you know anything about grapevine diseases?").also { stage++ } + 1 -> playerl(FacialExpression.FRIENDLY, "No, I'm afraid I don't.").also { stage++ } + 2 -> npcl(FacialExpression.GUILTY, "Oh, that's a shame. I hope I find someone soon, otherwise I could lose all of this year's crop.").also { stage = END_DIALOGUE } + } + return true + } + + override fun newInstance(player: Player): DialoguePlugin { + return BernaldDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.BERNALD_2580) + } +} diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/BreocaDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/BreocaDialogue.kt new file mode 100644 index 0000000..8a885cd --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/BreocaDialogue.kt @@ -0,0 +1,49 @@ +package content.region.asgarnia.burthorpe.dialogue + +import core.api.isQuestComplete +import core.api.toIntArray +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs +import content.data.Quests + +/** + * Breoca Dialogue + * @author 'Vexia + * @author ovenbread + */ +@Initializable +class BreocaDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int) : Boolean { + if(isQuestComplete(player!!, Quests.DEATH_PLATEAU)) { + when (stage) { + START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hi!").also { stage = (1..3).toIntArray().random() } + 1 -> npcl(FacialExpression.HAPPY, "I heard about what you did, thank you!").also { stage = END_DIALOGUE } + 2 -> npcl(FacialExpression.HAPPY, "Thank you so much!").also { stage = END_DIALOGUE } + 3 -> npcl(FacialExpression.HAPPY, "Surely we are safe now!").also { stage = END_DIALOGUE } + } + } else { + when (stage) { + START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hi!").also { stage = (1..3).toIntArray().random() } + 1 -> npcl(FacialExpression.FRIENDLY, "Hello stranger.").also { stage = END_DIALOGUE } + 2 -> npcl(FacialExpression.FRIENDLY, "Hi!").also { stage = END_DIALOGUE } + 3 -> npcl(FacialExpression.FRIENDLY, "Welcome to Burthorpe!").also { stage++ } + 4 -> playerl(FacialExpression.FRIENDLY, "Thanks!").also { stage = END_DIALOGUE } + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return BreocaDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.BREOCA_1084) + } +} + diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/BurthorpeBusySoldierListener.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/BurthorpeBusySoldierListener.kt new file mode 100644 index 0000000..4798297 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/BurthorpeBusySoldierListener.kt @@ -0,0 +1,48 @@ +package content.region.asgarnia.burthorpe.dialogue + +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import org.rs09.consts.NPCs + +/** + * Burthorpe Busy Soldiers Messages + * @author ovenbread + * + * https://www.youtube.com/watch?v=5RfEUmIdH10 for some busy interactions + * Covers the Sergeant/TrainingSoldier/EatingSoldier/Archer/Guard cases. + * These NPCs do not talk to you as they are busy. + */ +class BurthorpeBusySoldierListener: InteractionListener { + override fun defineListeners() { + // For sergeants. + on(intArrayOf(NPCs.SERGEANT_1061, NPCs.SERGEANT_1062), IntType.NPC, "talk-to") { player, npc -> + sendMessage(player, "The Sergeant is busy training the soldiers.") + return@on true + } + + // For soldiers training. + on(intArrayOf(NPCs.SOLDIER_1063, NPCs.SOLDIER_1064), IntType.NPC, "talk-to") { player, npc -> + sendMessage(player, "The soldier is busy training.") + return@on true + } + + // For soldiers sitting around the fire. + on(intArrayOf(NPCs.SOLDIER_1066, NPCs.SOLDIER_1067, NPCs.SOLDIER_1068), IntType.NPC, "talk-to") { player, npc -> + sendMessage(player, "The soldier is busy eating.") + return@on true + } + + // For archers at the castle. + on(intArrayOf(NPCs.ARCHER_1073, NPCs.ARCHER_1074), IntType.NPC, "talk-to") { player, npc -> + sendMessage(player, "The archer won't talk whilst on duty.") + return@on true + } + + // For soldiers at the castle. + on(intArrayOf(NPCs.GUARD_1076, NPCs.GUARD_1077), IntType.NPC, "talk-to") { player, npc -> + sendMessage(player, "The guard won't talk whilst on duty.") + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/BurthorpeSoldierDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/BurthorpeSoldierDialogue.kt new file mode 100644 index 0000000..e73aa0e --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/BurthorpeSoldierDialogue.kt @@ -0,0 +1,81 @@ +package content.region.asgarnia.burthorpe.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +/** + * Burthorpe Soldier Dialogue + * @author 'Vexia + * @author ovenbread + * + * https://www.youtube.com/watch?v=5RfEUmIdH10 for full interaction + * https://www.youtube.com/watch?v=ew0wTgv-2Kc for insults + */ +@Initializable +class BurthorpeSoldierDialogue(player: Player? = null) : DialoguePlugin(player) { + + companion object { + val latinInsults = arrayOf( + "Mihi ignosce. Cum homine de cane debeo congredi.", + "Errare humanum est.", + "Die dulci freure.", + "Carpe Diem!", + "Te audire non possum. Musa sapientum fixa est in aure.", + "Furnulum pani nolo.", + "Fac ut gaudeam.", + "Utinam barbari spatium proprium tuum invadant!", + "Quantum materiae materietur marmota monax si marmota monax materiam possit materiari?", + "Sona si Latine loqueris.", + "Raptus Regaliter", + "Nemo dat quod non habet.", + "Ne auderis delere orbem rigidum meum!", + "Da mihi sis bubulae frustum assae, solana tuberosa in modo gallico fricta, ac quassum lactatum coagulatum crassum.", + "Cogito ergo sum.", + "Vacca foeda.", + "Di! Ecce hora! Uxor mea me necabit!", + "Latine loqui coactus sum.", + "Cave ne ante ullas catapultas ambules.", + "Fac ut vivas!", + "Noli me vocare, ego te vocabo.", + "Meliora cogito.", + "Braccae tuae aperiuntur.", + "Vescere bracis meis.", + "Corripe cervisiam!", + ) + + val randomStages = arrayOf(10, 20, 30, 40, 50) + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hello!").also { stage++ } + 1 -> npcl(FacialExpression.ANGRY, latinInsults.random()).also { stage = randomStages.random() } + + 10 -> playerl(FacialExpression.THINKING, "What?!").also { stage = END_DIALOGUE } + + 20 -> playerl(FacialExpression.THINKING, "Huh?!").also { stage = END_DIALOGUE } + + 30 -> playerl(FacialExpression.HALF_GUILTY, "Er...").also { stage = END_DIALOGUE } + + 40 -> playerl(FacialExpression.HALF_GUILTY, "OK...").also { stage = END_DIALOGUE } + + 50 -> playerl(FacialExpression.THINKING, "Are you insulting me in Latin?").also { stage++ } + 51 -> npcl(FacialExpression.FRIENDLY, "Yes!").also { stage++ } + 52 -> playerl(FacialExpression.HALF_GUILTY, "Hmm...").also { stage = END_DIALOGUE } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return BurthorpeSoldierDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.SOLDIER_1065) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/CeolburgDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/CeolburgDialogue.kt new file mode 100644 index 0000000..006641e --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/CeolburgDialogue.kt @@ -0,0 +1,48 @@ +package content.region.asgarnia.burthorpe.dialogue + +import core.api.isQuestComplete +import core.api.toIntArray +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs +import content.data.Quests + +/** + * Ceolburg Dialogue + * @author 'Vexia + * @author ovenbread + */ +@Initializable +class CeolburgDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int) : Boolean { + if(isQuestComplete(player!!, Quests.DEATH_PLATEAU)) { + when (stage) { + START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hi!").also { stage = (1..3).toIntArray().random() } + 1 -> npcl(FacialExpression.HAPPY, "I heard about what you did, thank you!").also { stage = END_DIALOGUE } + 2 -> npcl(FacialExpression.HAPPY, "Thank you so much!").also { stage = END_DIALOGUE } + 3 -> npcl(FacialExpression.HAPPY, "Surely we are safe now!").also { stage = END_DIALOGUE } + } + } else { + when (stage) { + START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hi!").also { stage = (1..3).toIntArray().random() } + 1 -> npcl(FacialExpression.FRIENDLY, "Hello stranger.").also { stage = END_DIALOGUE } + 2 -> npcl(FacialExpression.FRIENDLY, "Hi!").also { stage = END_DIALOGUE } + 3 -> npcl(FacialExpression.FRIENDLY, "Welcome to Burthorpe!").also { stage++ } + 4 -> playerl(FacialExpression.FRIENDLY, "Thanks!").also { stage = END_DIALOGUE } + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return CeolburgDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.CEOLBURG_1089) + } +} diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/DenulthDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/DenulthDialogue.kt new file mode 100644 index 0000000..2724f9c --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/DenulthDialogue.kt @@ -0,0 +1,106 @@ +package content.region.asgarnia.burthorpe.dialogue + +import content.data.Quests +import content.region.asgarnia.burthorpe.quest.deathplateau.DenulthDialogueFile +import core.api.isQuestComplete +import core.api.isQuestInProgress +import core.api.openDialogue +import core.api.setQuestStage +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +/** + * Denulth main dialogue. + * @author ovenbread + */ +@Initializable +class DenulthDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + + // When Troll Stronghold is complete + if (isQuestComplete(player!!, Quests.TROLL_STRONGHOLD)) { + when(stage) { + START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hello!").also { stage++ } + 1 -> npcl(FacialExpression.HAPPY, "Welcome back friend!").also { stage++ } + 2 -> showTopics( + Topic("How goes your fight with the trolls?", 10), + Topic("I thought the White Knights controlled Asgarnia?", 20), + Topic(FacialExpression.HAPPY, "See you about Denulth!", 30) + ) + 10 -> npcl(FacialExpression.FRIENDLY, "We are busy preparing for an attack by night. Godric knows of a secret entrance to the stronghold. Once we destroy the stronghold Burthorpe will be safe! Friend, we are indebted to you!").also { stage++ } + 11 -> playerl(FacialExpression.FRIENDLY, "Good luck!").also { stage = END_DIALOGUE } + + 20 -> npcl(FacialExpression.ANGRY, "You are right citizen. The White Knights have taken advantage of the old and weak king, they control most of Asgarnia, including Falador. However they do not control Burthorpe!").also { stage++ } + 21 -> npcl(FacialExpression.EVIL_LAUGH, "We are the prince's elite troops! We keep Burthorpe secure!").also { stage++ } + 22 -> npcl(FacialExpression.ANGRY, "The White Knights have overlooked us until now! They are pouring money into their war against the Black Knights, They are looking for an excuse to stop our funding and I'm afraid they may have found it!").also { stage++ } + 23 -> npcl(FacialExpression.HALF_WORRIED, "If we can not destroy the troll camp on Death Plateau then the Imperial Guard will be disbanded and Burthorpe will come under control of the White Knights. We cannot let this happen!").also { stage++ } + 24 -> npcl(FacialExpression.ASKING, "Is there anything else you'd like to know?").also { stage = 2 } + + 30 -> npcl(FacialExpression.FRIENDLY, "Saradomin be with you, friend!").also { stage = END_DIALOGUE } + } + return true + } + + // Troll Stronghold in progress + if (isQuestInProgress(player!!, Quests.TROLL_STRONGHOLD, 1, 99)) { + openDialogue(player!!, content.region.asgarnia.burthorpe.quest.trollstronghold.DenulthDialogueFile(), npc) + return true + } + + // When Death Plateau is completed, start Troll Stronghold + if (isQuestComplete(player!!, Quests.DEATH_PLATEAU)) { + when(stage) { + START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hello!").also { stage++ } + 1 -> npcl(FacialExpression.HAPPY, "Welcome back friend!").also { stage++ } + 2 -> showTopics( + Topic("How goes your fight with the trolls?", 10), + Topic("I thought the White Knights controlled Asgarnia?", 20), + Topic(FacialExpression.HAPPY, "See you about Denulth!", 30) + ) + 10 -> npcl(FacialExpression.HALF_WORRIED, "I'm afraid I have bad news. We made our attack as planned, but we met unexpected resistance.").also { stage++ } + 11 -> playerl(FacialExpression.HALF_ASKING, "What happened?").also { stage++ } + 12 -> npcl(FacialExpression.WORRIED, "We were ambushed by trolls coming from the north. They captured Dunstan's son, Godric, who we enlisted at your request; we tried to follow but we were repelled at the foot of their stronghold.").also { stage++ } + 13 -> showTopics( + Topic(FacialExpression.SAD, "I'm sorry to hear that.", END_DIALOGUE), + Topic("Is there anything I can do to help?", 14) + ) + 14 -> npcl(FacialExpression.HALF_WORRIED, "The way to the stronghold is treacherous, friend. Even if you manage to climb your way up, there will be many trolls defending the stronghold.").also{ stage++ } + 15 -> showTopics( + Topic("I'll get Godric back!", 16), + Topic("I'm sorry, there's nothing I can do.", END_DIALOGUE) + ) + 16 -> npcl(FacialExpression.HAPPY, "God speed friend! I would send some of my men with you, but none of them are brave enough to follow.").also { + stage = END_DIALOGUE + setQuestStage(player!!, Quests.TROLL_STRONGHOLD, 1) + } + + 20 -> npcl(FacialExpression.ANGRY, "You are right citizen. The White Knights have taken advantage of the old and weak king, they control most of Asgarnia, including Falador. However they do not control Burthorpe!").also { stage++ } + 21 -> npcl(FacialExpression.EVIL_LAUGH, "We are the prince's elite troops! We keep Burthorpe secure!").also { stage++ } + 22 -> npcl(FacialExpression.ANGRY, "The White Knights have overlooked us until now! They are pouring money into their war against the Black Knights, They are looking for an excuse to stop our funding and I'm afraid they may have found it!").also { stage++ } + 23 -> npcl(FacialExpression.HALF_WORRIED, "If we can not destroy the troll camp on Death Plateau then the Imperial Guard will be disbanded and Burthorpe will come under control of the White Knights. We cannot let this happen!").also { stage++ } + 24 -> npcl(FacialExpression.ASKING, "Is there anything else you'd like to know?").also { stage = 2 } + + 30 -> npcl(FacialExpression.FRIENDLY, "Saradomin be with you, friend!").also { stage = END_DIALOGUE } + } + return true + } + + // Fallback to default. Always the start of Death Plateau + openDialogue(player!!, DenulthDialogueFile(), npc) + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return DenulthDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.DENULTH_1060) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/DunstanDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/DunstanDialogue.kt new file mode 100644 index 0000000..7375908 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/DunstanDialogue.kt @@ -0,0 +1,173 @@ +package content.region.asgarnia.burthorpe.dialogue + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +/** + * Dunstan main dialogue. + * @author 'ovenbread + * + * https://www.youtube.com/watch?v=gbqcJp99Zd8 + * https://www.youtube.com/watch?v=ujtIALS1L7A + */ +@Initializable +class DunstanDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + // When Troll Stronghold is complete + if (isQuestComplete(player!!, Quests.TROLL_STRONGHOLD)) { + when (stage) { + START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hi!").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "Hi! What can I do for you?").also { stage++ } + 2 -> showTopics( + Topic(FacialExpression.THINKING, "Can you put some spikes on my Climbing boots?", 30), + Topic(FacialExpression.THINKING, "Is it OK if I use your anvil?", 10), + Topic(FacialExpression.FRIENDLY, "Nothing, thanks.", END_DIALOGUE), + Topic(FacialExpression.FRIENDLY, "How is your son getting on?", 15), + // Sleds topic when Troll Romance is implemented. + ) + 10 -> npcl(FacialExpression.FRIENDLY, "So you're a smithy are you?").also { stage++ } + 11 -> playerl(FacialExpression.FRIENDLY, "I dabble.").also { stage++ } + 12 -> npcl(FacialExpression.FRIENDLY, "A fellow smith is welcome to use my anvil!").also { stage++ } + 13 -> playerl(FacialExpression.FRIENDLY, "Thanks!").also { stage++ } + 14 -> npcl(FacialExpression.FRIENDLY, "Anything else before I get on with my work?").also { stage = 2 } + 15 -> npcl(FacialExpression.FRIENDLY, "He is getting on fine! He has just been promoted to Sergeant! I'm really proud of him!").also { stage++ } + 16 -> playerl(FacialExpression.FRIENDLY, "I'm happy for you!").also { stage++ } + 17 -> npcl(FacialExpression.FRIENDLY, "Anything else before I get on with my work?").also { stage = 2 } + 30 -> playerl(FacialExpression.FRIENDLY, "Can you put some spikes on my Climbing boots?").also { stage++ } + 31 -> npcl(FacialExpression.NEUTRAL,"For you, no problem.").also { stage++ } + 32 -> npc(FacialExpression.THINKING, "Do you realise that you can only use the Climbing", "boots right now? The Spiked boots can only be used in", "the Icelands but no ones been able to get there for", "years!").also { stage++ } + 33 -> showTopics( + Topic(FacialExpression.NEUTRAL, "Yes, but I still want them.", 40, true), + Topic(FacialExpression.NEUTRAL, "Oh OK, I'll leave them thanks.", 43), + ) + 40 -> { + if (inInventory(player!!, Items.CLIMBING_BOOTS_3105) && inInventory(player!!, Items.IRON_BAR_2351)) { + sendDoubleItemDialogue(player!!, Items.IRON_BAR_2351, Items.CLIMBING_BOOTS_3105, "You give Dunstan an Iron bar and the climbing boots.") + sendMessage(player!!, "You give Dunstan an Iron bar and the climbing boots.") + if (removeItem(player!!, Item(Items.CLIMBING_BOOTS_3105)) && removeItem(player!!, Item(Items.IRON_BAR_2351))) { + addItemOrDrop(player!!, Items.SPIKED_BOOTS_3107) + stage++ + } else { + stage = END_DIALOGUE + } + } else if (inInventory(player!!, Items.CLIMBING_BOOTS_3105)){ + npcl(FacialExpression.NEUTRAL,"Sorry, I'll need an iron bar to make the spikes.") + stage = 2 + } else { + playerl(FacialExpression.NEUTRAL,"I don't have them on me.") + stage = 2 + } + } + 41 -> sendItemDialogue(player!!, Items.SPIKED_BOOTS_3107, "Dunstan has given you the spiked boots.").also { stage++ + sendMessage(player!!, "Dunstan has given you the spiked boots.") + } + 43 -> npcl(FacialExpression.FRIENDLY, "Anything else before I get on with my work?").also { + stage = 2 + } + } + return true + } + + // Troll Stronghold in progress + if (isQuestInProgress(player!!, Quests.TROLL_STRONGHOLD, 1, 99)) { + openDialogue(player!!, content.region.asgarnia.burthorpe.quest.trollstronghold.DunstanDialogueFile(), npc) + return true + } + + // When Death Plateau is complete + if (isQuestComplete(player!!, Quests.DEATH_PLATEAU)) { + when (stage) { + START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hi!").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "Hi! What can I do for you?").also { stage++ } + 2 -> showTopics( + Topic(FacialExpression.THINKING, "Can you put some spikes on my Climbing boots?", 30), + Topic(FacialExpression.THINKING, "Is it OK if I use your anvil?", 10), + Topic(FacialExpression.FRIENDLY, "Nothing, thanks.", END_DIALOGUE), + Topic(FacialExpression.FRIENDLY, "How is your son getting on?", 15), + ) + 10 -> npcl(FacialExpression.FRIENDLY, "So you're a smithy are you?").also { stage++ } + 11 -> playerl(FacialExpression.FRIENDLY, "I dabble.").also { stage++ } + 12 -> npcl(FacialExpression.FRIENDLY, "A fellow smith is welcome to use my anvil!").also { stage++ } + 13 -> playerl(FacialExpression.FRIENDLY, "Thanks!").also { stage++ } + 14 -> npcl(FacialExpression.FRIENDLY, "Anything else before I get on with my work?").also { stage = 2 } + 15 -> npcl(FacialExpression.SAD, "He was captured by those cursed trolls! I don't know what to do. Even the imperial guard are too afraid to go rescue him.").also { stage++ } + 16 -> playerl(FacialExpression.ASKING, "What happened?").also { stage++ } + 17 -> npcl(FacialExpression.SAD, "Talk to Denulth, he can tell you all about it. Anything else before I get on with my work?").also { stage = 2 } + 30 -> npcl(FacialExpression.NEUTRAL,"For you, no problem.").also { stage++ } + 31 -> npc(FacialExpression.THINKING, "Do you realise that you can only use the Climbing", "boots right now? The Spiked boots can only be used in", "the Icelands but no ones been able to get there for", "years!").also { stage++ } + 32 -> showTopics( + Topic(FacialExpression.NEUTRAL, "Yes, but I still want them.", 40, true), + Topic(FacialExpression.NEUTRAL, "Oh OK, I'll leave them thanks.", 43), + ) + 40 -> { + if (inInventory(player!!, Items.CLIMBING_BOOTS_3105) && inInventory(player!!, Items.IRON_BAR_2351)) { + sendDoubleItemDialogue(player!!, Items.IRON_BAR_2351, Items.CLIMBING_BOOTS_3105, "You give Dunstan an Iron bar and the climbing boots.") + sendMessage(player!!, "You give Dunstan an Iron bar and the climbing boots.") + if (removeItem(player!!, Item(Items.CLIMBING_BOOTS_3105)) && removeItem(player!!, Item(Items.IRON_BAR_2351))) { + addItemOrDrop(player!!, Items.SPIKED_BOOTS_3107) + stage++ + } else { + stage = END_DIALOGUE + } + } else if (inInventory(player!!, Items.CLIMBING_BOOTS_3105)){ + npcl(FacialExpression.NEUTRAL,"Sorry, I'll need an iron bar to make the spikes.") + stage = 2 + } else { + playerl(FacialExpression.NEUTRAL,"I don't have them on me.") + stage = 2 + } + } + 41 -> sendItemDialogue(player!!, Items.SPIKED_BOOTS_3107, "Dunstan has given you the spiked boots.").also { + stage = 43 + sendMessage(player!!, "Dunstan has given you the spiked boots.") + } + 43 -> npcl(FacialExpression.FRIENDLY, "Anything else before I get on with my work?").also { + stage = 2 + } + } + return true + } + + // Death Plateau in progress + if (isQuestInProgress(player!!, Quests.DEATH_PLATEAU, 21, 24)) { + // Call the dialogue file for Dunstan from the deathplateau quest folder. + openDialogue(player!!, content.region.asgarnia.burthorpe.quest.deathplateau.DunstanDialogueFile(), npc) + return true + } + + // Default + when (stage) { + START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hi!").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "Hi! Did you want something?").also { stage++ } + 2 -> showTopics( + Topic(FacialExpression.THINKING, "Is it OK if I use your anvil?", 10), + Topic(FacialExpression.FRIENDLY, "Nothing, thanks.", END_DIALOGUE), + ) + 10 -> npcl(FacialExpression.FRIENDLY, "So you're a smithy are you?").also { stage++ } + 11 -> playerl(FacialExpression.FRIENDLY, "I dabble.").also { stage++ } + 12 -> npcl(FacialExpression.FRIENDLY, "A fellow smith is welcome to use my anvil!").also { stage++ } + 13 -> playerl(FacialExpression.FRIENDLY, "Thanks!").also { stage++ } + 14 -> npcl(FacialExpression.FRIENDLY, "Anything else before I get on with my work?").also { stage = 2 } + } + return true + } + + override fun newInstance(player: Player): DialoguePlugin { + return DunstanDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.DUNSTAN_1082) + } +} diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/EadburgDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/EadburgDialogue.kt new file mode 100644 index 0000000..f2135a7 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/EadburgDialogue.kt @@ -0,0 +1,46 @@ +package content.region.asgarnia.burthorpe.dialogue + +import core.api.openDialogue +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class EadburgDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, EadburgDialogueFile(), npc) + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return EadburgDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.EADBURG_1072) + } +} + +class EadburgDialogueFile : DialogueBuilderFile() { + + override fun create(b: DialogueBuilder) { + b.defaultDialogue().playerl( + FacialExpression.FRIENDLY, + "What's cooking, good looking?" + ).npcl( + FacialExpression.FRIENDLY, + "The stew for the servant's main meal." + ).playerl( + FacialExpression.HALF_WORRIED, + "Um...er...see you later." + ).npcl( + FacialExpression.FRIENDLY, + "Bye!" + ) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/EmeraldBenedictDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/EmeraldBenedictDialogue.kt new file mode 100644 index 0000000..9a200f9 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/EmeraldBenedictDialogue.kt @@ -0,0 +1,89 @@ +package content.region.asgarnia.burthorpe.dialogue + +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.IronmanMode +import core.plugin.Initializable +import org.rs09.consts.NPCs +import core.game.dialogue.IfTopic +import core.game.dialogue.Topic +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE + +/** + * Handles Emerald Benedict's dialogue tree. + * + * @author vddCore + */ +@Initializable +class EmeraldBenedictDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + START_DIALOGUE -> if(hasIronmanRestriction(player, IronmanMode.ULTIMATE)) { + npcl( + FacialExpression.ANNOYED, + "Get lost, tin can." + ).also { stage = END_DIALOGUE } + } else { + npcl( + FacialExpression.SUSPICIOUS, + "Got anything you don't want to lose?" + ).also { + if (hasAwaitingGrandExchangeCollections(player)) { + stage++ + } else { + stage += 2 + } + } + } + + 1 -> npcl( + FacialExpression.SUSPICIOUS, + "By the way, a little bird told me you got some stuff waiting for you " + + "on the Grand Exchange." + ).also { stage++ } + + 2 -> showTopics( + Topic(FacialExpression.ASKING, "Yes, actually. Can you help?", 3), + IfTopic( + FacialExpression.ASKING, + "Yes, but can you switch my bank accounts?", + 4, + hasActivatedSecondaryBankAccount(player) + ), + Topic(FacialExpression.ASKING, "Yes, but can you show me my PIN settings?", 5), + Topic(FacialExpression.ASKING, "Yes, but can you show me my collection box?", 6), + Topic(FacialExpression.ANNOYED, "Yes, thanks. And I'll keep hold of it too.", END_DIALOGUE) + ) + + 3 -> { + openBankAccount(player) + end() + } + + 4 -> { + toggleBankAccount(player) + npcl( + FacialExpression.SUSPICIOUS, + "Sure thing. Feel free to rummage through whatever's in your ${getBankAccountName(player)} now." + ).also { stage = END_DIALOGUE } + } + + 5 -> { + openBankPinSettings(player) + end() + } + + 6 -> { + openGrandExchangeCollectionBox(player) + end() + } + } + + return true + } + + override fun getIds(): IntArray = intArrayOf(NPCs.EMERALD_BENEDICT_2271) +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/EmeraldBenedictListener.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/EmeraldBenedictListener.kt new file mode 100644 index 0000000..9268d2e --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/EmeraldBenedictListener.kt @@ -0,0 +1,26 @@ +package content.region.asgarnia.burthorpe.dialogue + +import core.api.openBankAccount +import core.api.openGrandExchangeCollectionBox +import org.rs09.consts.NPCs +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +/** + * Handles Emerald Benedict's only available interaction. + * + * @author vddCore + */ +class EmeraldBenedictListener : InteractionListener { + override fun defineListeners() { + on(NPCs.EMERALD_BENEDICT_2271, IntType.NPC, "bank") { player, _ -> + openBankAccount(player) + return@on true + } + + on(NPCs.EMERALD_BENEDICT_2271, IntType.NPC, "collect") { player, _ -> + openGrandExchangeCollectionBox(player) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/EohricDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/EohricDialogue.kt new file mode 100644 index 0000000..4fb041b --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/EohricDialogue.kt @@ -0,0 +1,56 @@ +package content.region.asgarnia.burthorpe.dialogue + +import content.data.Quests +import content.region.asgarnia.burthorpe.quest.deathplateau.EohricDialogueFile +import core.api.getQuestStage +import core.api.openDialogue +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +/** + * Eohric main dialogue. + * @author ovenbread + */ +@Initializable +class EohricDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + if (getQuestStage(player!!, Quests.DEATH_PLATEAU) >= 5) { + // Call the dialogue file for Eohric from the deathplateau quest folder. + openDialogue(player!!, EohricDialogueFile(), npc) + return true + } + // Fallback to default. + when (stage) { + START_DIALOGUE -> playerl(FacialExpression.HALF_GUILTY, "Hi!").also { stage++ } + 1 -> npc(FacialExpression.ASKING, "Hello. Can I help?").also { stage++ } + 2 -> options("What is this place?", "That's quite an outfit.", "Goodbye.").also { stage++ } + 3 -> when (buttonId) { + 1 -> npcl(FacialExpression.FRIENDLY, "This is Burthorpe Castle, home to His Royal Highness Prince Anlaf, heir to the throne of Asgarnia.").also { stage = 10 } + 2 -> npcl(FacialExpression.HAPPY, "Why, thank you. I designed it myself. I've always found purple such a cheerful colour!").also { stage = 2 } + 3 -> player(FacialExpression.FRIENDLY, "Goodbye.").also { stage = END_DIALOGUE } + } + 10 -> npc(FacialExpression.FRIENDLY, "No doubt you're impressed.").also { stage++ } + 11 -> options("Where is the prince?", "Goodbye.").also { stage++ } + 12 -> when (buttonId) { + 1 -> npcl(FacialExpression.SUSPICIOUS, "I cannot disclose the prince's exact whereabouts for fear of compromising his personal safety.").also { stage = 20 } + 2 -> player(FacialExpression.FRIENDLY, "Goodbye.").also { stage = END_DIALOGUE } + } + 20 -> npcl(FacialExpression.FRIENDLY, "But rest assured that he is working tirelessly to maintain the safety and wellbeing of Burthorpe's people.").also { stage = 2 } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return EohricDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.EOHRIC_1080) + } +} + diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/GamFredDialoue.java b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/GamFredDialoue.java new file mode 100644 index 0000000..ec37eca --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/GamFredDialoue.java @@ -0,0 +1,204 @@ +package content.region.asgarnia.burthorpe.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.game.node.item.Item; + +/** + * Represents the dialogue plugin used for the gam fred npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class GamFredDialoue extends DialoguePlugin { + + /** + * Constructs a new {@code GamFredDialoue} {@code Object}. + */ + public GamFredDialoue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code GamFredDialoue} {@code Object}. + * @param player the player. + */ + public GamFredDialoue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new GamFredDialoue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + if (args.length > 1) { + interpreter.sendDialogues(player, null, "May I have a shield please?"); + stage = 13; + return true; + } + interpreter.sendDialogues(npc, FacialExpression.CHILD_NORMAL, "Ello there. I'm Gamfred, the engineer in this here guild.", "Have you seen my catapult?"); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "That's not a catapult, it's a large crossbow.", "Yes, beautiful piece of enigneering.", "No, where is it?", "May I claim my tokens please?", "Bye!"); + stage = 1; + break; + case 1: + if (buttonId == 1) { + interpreter.sendDialogues(player, null, "That's not a catapult, it's a large crossbow."); + stage = 2; + } else if (buttonId == 2) { + interpreter.sendDialogues(player, null, "Yes, beautiful piece of engineering."); + stage = 4; + } else if (buttonId == 3) { + interpreter.sendDialogues(player, null, "No, where is it?"); + stage = 15; + } else if (buttonId == 4) { + end(); + player.getDialogueInterpreter().open("wg:claim-tokens", npc.getId()); + } else if (buttonId == 5) { + interpreter.sendDialogues(player, null, "Bye!"); + stage = 16; + } + break; + case 2: + interpreter.sendDialogues(npc, FacialExpression.CHILD_SAD, "WHAT!? I'll have you know that is the finest piece of", "dwarven engineering for miles around! How DARE you", "insult my work!"); + stage = 3; + break; + case 3: + end(); + break; + case 4: + interpreter.sendDialogues(npc, FacialExpression.CHILD_NORMAL, "Nice to meet someone who appreicates fine work, have", "you tried it out yet?"); + stage = 5; + break; + case 5: + interpreter.sendOptions("Select an Option", "Yes", "No, how do I do that?"); + stage = 6; + break; + case 6: + if (buttonId == 1) { + interpreter.sendDialogues(player, null, "Yes."); + stage = 7; + } else if (buttonId == 2) { + interpreter.sendDialogues(player, null, "No, how do I do that?"); + stage = 17; + } + break; + case 7: + interpreter.sendDialogues(npc, FacialExpression.CHILD_NORMAL, "What did you think?"); + stage = 8; + break; + case 8: + interpreter.sendOptions("Select an Option", "It was ok I guess.", "It was fun!", "I didn't like it.", "May i have a shield please?"); + stage = 9; + break; + case 9: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, null, "It was ok I guess."); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, null, "It was fun!"); + stage = 11; + break; + case 3: + interpreter.sendDialogues(player, null, "I didn't like it."); + stage = 12; + break; + case 4: + interpreter.sendDialogues(player, null, "May i have a shield please?"); + stage = 13; + break; + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.CHILD_NORMAL, "Well I guess not everyone will like it."); + stage = 3; + break; + case 11: + interpreter.sendDialogues(npc, FacialExpression.CHILD_NORMAL, "Glad to hear it. Try it again sometime. We have more", "tests to run."); + stage = 3; + break; + case 12: + interpreter.sendDialogues(npc, FacialExpression.CHILD_NORMAL, "Well I guess not everyone will like it. But give it another", " chance before you go."); + stage = 3; + break; + case 13: + if (player.getBank().contains(8856, 1) || player.getInventory().contains(8856, 1) || player.getEquipment().contains(8856, 1)) { + interpreter.sendDialogues(npc, FacialExpression.CHILD_NORMAL, "Silly muffin, you have one already!"); + stage = 3; + } else { + interpreter.sendDialogues(npc, FacialExpression.CHILD_NORMAL, "ofcourse!"); + stage = 14; + } + break; + case 14: + if (player.getInventory().hasSpaceFor(new Item(8856))) { + player.getInventory().add(new Item(8856)); + interpreter.sendItemMessage(8856, "The dwarf hands you a large shield."); + stage = 3; + } else { + interpreter.sendDialogues(npc, FacialExpression.CHILD_NORMAL, "Muffin make some room in your inventory first!"); + stage = 3; + } + break; + case 15: + interpreter.sendDialogues(npc, FacialExpression.CHILD_NORMAL, "Are ye blind lad? Tis over there in the next room with me", "assistant working it!"); + stage = 3; + break; + case 16: + interpreter.sendDialogues(npc, FacialExpression.CHILD_NORMAL, "Come back soon! My catapult needs more test subjects."); + stage = 3; + break; + case 17: + interpreter.sendDialogues(npc, FacialExpression.CHILD_NORMAL, "Well ye take the big defence shield in both hands and", "watch the catapult. My assitant will fire different things", "at you and you need to defend against them. To see", "what might be comming your way and wich defensive"); + stage = 18; + break; + case 18: + interpreter.sendDialogues(npc, FacialExpression.CHILD_NORMAL, "mode to choose, see the poster on the wall."); + stage = 19; + break; + case 19: + interpreter.sendOptions("Select an Option", "May I have a shield please?", "Sounds boring."); + stage = 20; + break; + case 20: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, null, "May I have a shield please?"); + stage = 13; + break; + case 2: + interpreter.sendDialogues(player, null, "Sounds boring."); + stage = 21; + break; + } + break; + case 21: + interpreter.sendDialogues(npc, FacialExpression.CHILD_NORMAL, "Your loss..."); + stage = 3; + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 4287 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/GhommalDialogue.java b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/GhommalDialogue.java new file mode 100644 index 0000000..96114bb --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/GhommalDialogue.java @@ -0,0 +1,94 @@ +package content.region.asgarnia.burthorpe.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; + +/** + * Represents the ghommal dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class GhommalDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code GhommalDialogue} {@code Object}. + */ + public GhommalDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code GhommalDialogue} {@code Object}. + * @param player the player. + */ + public GhommalDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new GhommalDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + if (player.getSkills().getLevel(Skills.ATTACK) + player.getSkills().getLevel(Skills.STRENGTH) >= 130 || player.getSkills().getLevel(Skills.ATTACK) == 99 || player.getSkills().getLevel(Skills.STRENGTH) == 99) { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ghommal welcome you to Warrior Guild!"); + stage = 10; + } else { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "You not pass. You too weedy."); + stage = 0; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What? But I'm a warrior!"); + stage = 1; + break; + case 1: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Heehee... he say he warrior... I not heard that one", "for... at leas' 5 minutes!"); + stage = 2; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Go on, let me in, you know you want to. I could...", "make it worth your while..."); + stage = 3; + break; + case 3: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "No! You is not a strong warrior, you not enter till you", "bigger, Ghommal does not takes bribes."); + stage = 4; + break; + case 4: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ghommal stick to Warrior's Code of Honour. When", "you a bigger, stronger warriror, you come back."); + stage = 5; + break; + case 5: + end(); + break; + case 10: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Umm...thank you, I think."); + stage = 11; + break; + case 11: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 4285 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/HaroldDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/HaroldDialogue.kt new file mode 100644 index 0000000..62d510a --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/HaroldDialogue.kt @@ -0,0 +1,60 @@ +package content.region.asgarnia.burthorpe.dialogue + +import content.data.Quests +import content.region.asgarnia.burthorpe.quest.deathplateau.HaroldDialogueFile +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.world.update.flag.context.Animation +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.Animations +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +/** + * Harold main dialogue. + * @author ovenbread + */ +@Initializable +class HaroldDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + if (isQuestInProgress(player!!, Quests.DEATH_PLATEAU, 10, 29)) { + // Call the dialogue file for Harold from the deathplateau quest folder. + openDialogue(player!!, HaroldDialogueFile(), npc) + } + // Fallback to default. + when (stage) { + START_DIALOGUE -> player(FacialExpression.FRIENDLY, "Hello there.").also { stage++ } + 1 -> npc(FacialExpression.FRIENDLY, "Hi.").also { stage++ } + 2 -> player(FacialExpression.FRIENDLY, "Can I buy you a drink?").also { stage++ } + 3 -> npc(FacialExpression.HAPPY, "Now you're talking! An Asgarnian Ale, please!").also { stage++ } + 4 -> { + if (removeItem(player!!, Items.ASGARNIAN_ALE_1905)) { + sendMessage(player!!, "You give Harold an Asgarnian Ale.") + sendItemDialogue(player!!, Items.ASGARNIAN_ALE_1905, "You give Harold an Asgarnian Ale.").also { stage++ } + } else { + player(FacialExpression.FRIENDLY, "I'll go and get you one.").also { stage = END_DIALOGUE } + } + } + 5 -> { + end() + animate(npc!!, Animation(Animations.HUMAN_EATTING_829), true) + runTask(npc!!, 3) { + npc(FacialExpression.FRIENDLY, "*burp*").also { stage = END_DIALOGUE } + } + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return HaroldDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.HAROLD_1078) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/HarrallakMenarous.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/HarrallakMenarous.kt new file mode 100644 index 0000000..ce0aef1 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/HarrallakMenarous.kt @@ -0,0 +1,539 @@ +package content.region.asgarnia.burthorpe.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * Harrallak Menarous Dialogue + * Warrior's Guildmaster + * NOTE: org.rs09.consts.NPCs enums are wrong + * NPCs.RESOURCE_NPC_8267 is the correct Harrallak Menarous that animates properly + * NPCs.HARRALLAK_MENAROUS_8299 is the wrong Harrallak Menarous that is stuck in animation + * @author 'Vexia + * @author ovenbread + */ +@Initializable +class HarrallakMenarous(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any): Boolean { + npc = args[0] as NPC + npc.isWalks = true + interpreter.sendDialogues( + npc, + FacialExpression.HALF_GUILTY, + "Welcome to my humble guild, " + player.username + "." + ) + stage = 0 + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> { + interpreter.sendOptions( + "Select an Option", + "Quite a place you've got here.", + "You any good with a sword?", + "Bye!" + ) + stage = 1 + } + + 1 -> if (buttonId == 1) { + interpreter.sendDialogues( + player, + FacialExpression.HALF_GUILTY, + "Quite a place you've got here. Tell me more about it." + ) + stage = 53 + } else if (buttonId == 2) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "You any good with a sword?") + stage = 5 + } else if (buttonId == 3) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Bye!") + stage = 2 + } + + 2 -> { + interpreter.sendDialogues( + npc, + FacialExpression.HALF_GUILTY, + "Farewell, brave warrior, I do hope you enjoy my guild." + ) + stage = 120 + } + + 3 -> { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "You any good with a sword?") + stage = 4 + } + + 4 -> { + interpreter.sendDialogues( + npc, + FacialExpression.HALF_GUILTY, + "Am I any good with a sword'? Have you any clue who I", + "am?" + ) + stage = 5 + } + + 5 -> { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Not really, no.") + stage = 6 + } + + 6 -> { + interpreter.sendDialogues( + npc, + FacialExpression.HALF_GUILTY, + "Why, I could best any person alive in a rapier duel!" + ) + stage = 7 + } + + 7 -> { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Try me, then!") + stage = 8 + } + + 8 -> { + interpreter.sendDialogues( + npc, + FacialExpression.HALF_GUILTY, + "My dear man, I couldn't possibly duel you, I might hurt", + "you and then what would happen to my reputation!", + "Besides, I have this wonderful guild to run. Why don't", + " you take a look at the various activities we have." + ) + stage = -8 + } + + -8 -> { + npc( + "You might even collect enough tokens to be allowed in", + "to kill the strange beasts from the east!" + ) + stage = 10 + } + + 10 -> { + interpreter.sendOptions( + "Select an Option", + "Tell me about the Strength training Area.", + "Tell me about the Attack training area.", + "Tell me about the Defence training area.", + "Tell me about the Combat training area.", + "Tell me about tokens." + ) + stage = 11 + } + + 11 -> if (buttonId == 1) { + interpreter.sendDialogues( + player, + FacialExpression.HALF_GUILTY, + "Tell me about the Strength training area." + ) + stage = 12 + } else if (buttonId == 2) { + interpreter.sendDialogues( + player, + FacialExpression.HALF_GUILTY, + "Tell me about the Attack training area." + ) + stage = 29 + } else if (buttonId == 3) { + interpreter.sendDialogues( + player, + FacialExpression.HALF_GUILTY, + "Tell me about the Defence training area" + ) + stage = 16 + } else if (buttonId == 4) { + interpreter.sendDialogues( + player, + FacialExpression.HALF_GUILTY, + "Tell me about the Combat training area" + ) + stage = 35 + } else if (buttonId == 5) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Tell me about tokens.") + stage = 42 + } + + 12 -> { + interpreter.sendDialogues( + npc, + FacialExpression.HALF_GUILTY, + "Ahh, the mighty warrior, Sloane, guards the Strength", + "training area. This intriguing little area consits of two", + "shotput lanes for different weights of shot. It's fairly", + "simple, the referee or Sloane can explain more. There's" + ) + stage = 13 + } + + 13 -> { + interpreter.sendDialogues( + npc, + FacialExpression.HALF_GUILTY, + "also the store room next door where Jimmy might share", + "his talents with you, but don't tell him that I know", + "he's not on guard duty!" + ) + stage = 14 + } + + 14 -> { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Oh? Why?") + stage = 15 + } + + 15 -> { + interpreter.sendDialogues( + npc, + FacialExpression.HALF_GUILTY, + "Well, he's doing no harm and let's face it, with all these", + "warriors around, the guild is hardly unguarded. You can", + "find the strength area just up the stairs behind the bank." + ) + stage = 10 + } + + 16 -> { + interpreter.sendDialogues( + npc, + FacialExpression.HALF_GUILTY, + "To polish your defensive skills to the very highest level,", + "we've employed a most intentive dwarf and a catapult." + ) + stage = 17 + } + + 17 -> { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "You're going to throw dwarves at me?") + stage = 18 + } + + 18 -> { + interpreter.sendDialogues( + npc, + FacialExpression.HALF_GUILTY, + "Oh my, no! I think Gamfred would object to that most", + "strongly." + ) + stage = 19 + } + + 19 -> { + interpreter.sendDialogues( + npc, + FacialExpression.HALF_GUILTY, + "He's an inventor, you see, and has built a marvellous", + "contraptiont hat can throw all sorts of things at you.", + "Things such as magic missiles..." + ) + stage = 20 + } + + 20 -> { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Mmmm?") + stage = 21 + } + + 21 -> { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "...spiked iron balls...") + stage = 22 + } + + 22 -> { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Er...") + stage = 23 + } + + 23 -> { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "...spinning, slashing bladed...") + stage = 24 + } + + 24 -> { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Ummm...") + stage = 25 + } + + 25 -> { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "...and anvils.") + stage = 26 + } + + 26 -> { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "...and anvils.") + stage = 27 + } + + 27 -> { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "ANVILS?") + stage = 28 + } + + 28 -> { + interpreter.sendDialogues( + npc, + FacialExpression.HALF_GUILTY, + "No need to be afraid, it's all under very controlled", + "conditions! You can find it just up the stairs and", + "behind the bank." + ) + stage = 10 + } + + 29 -> { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ahhh, dummies.") + stage = 30 + } + + 30 -> { + interpreter.sendDialogues( + player, + FacialExpression.HALF_GUILTY, + "I'm no dummy, I just want to know what is there!" + ) + stage = 31 + } + + 31 -> { + interpreter.sendDialogues( + npc, + FacialExpression.HALF_GUILTY, + "Oh no, my dear man, I did not mean you at all! The", + "training area has mechanical dummies that pop up out of", + "holes in the floor. The noble dward, Gamfred, invented the", + "mechanism and Ajjat can explain more about what to do" + ) + stage = 32 + } + + 32 -> { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "there.") + stage = 33 + } + + 33 -> { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Oh, okay, I'll have to try it out.") + stage = 34 + } + + 34 -> { + interpreter.sendDialogues( + npc, + FacialExpression.HALF_GUILTY, + "You can find it just down the corridor and on", + "your right." + ) + stage = 10 + } + + 35 -> { + interpreter.sendDialogues( + npc, + FacialExpression.HALF_GUILTY, + "Ahh, yes, our redient magician from foreign lands", + "created a most amazing gadget that can turn your own", + "armour against you! It's really quite intriguing." + ) + stage = 36 + } + + 36 -> { + interpreter.sendDialogues( + player, + FacialExpression.HALF_GUILTY, + "That sounds dangerous. What if I'm wearing it at the", + "time?" + ) + stage = 37 + } + + 37 -> { + interpreter.sendDialogues( + npc, + FacialExpression.HALF_GUILTY, + "So far, that's not happend. You need to speak to", + "Shanomi about the specifics of the process, but as I", + "understand it, putting a suit of armour in one of these", + "devices will make it come to life somehow. The better the" + ) + stage = 38 + } + + 38 -> { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "armour, the harder it is to defeat.") + stage = 39 + } + + 39 -> { + interpreter.sendDialogues( + player, + FacialExpression.HALF_GUILTY, + "Fighting my own armour sounds weird. I could be", + "killed by it..." + ) + stage = 40 + } + + 40 -> { + interpreter.sendDialogues( + npc, + FacialExpression.HALF_GUILTY, + "Indeed, we have had a few fatalities from warriors", + "overstretching themselves and not knowing their limits.", + "Start small and work up, is my motto! That and go see", + "Lidio for some food if you need it." + ) + stage = 41 + } + + 41 -> { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Okay, thanks for the warning.") + stage = 10 + } + + 42 -> { + interpreter.sendDialogues( + npc, + FacialExpression.HALF_GUILTY, + "Ahh, yes! The tokens allow you to spend an amount of", + "time with my 'discovery', located on the top floor of the", + "guild. Now, the amount of tokens you collect from the", + "five activities around the guild will dictate how" + ) + stage = -43 + } + + -43 -> { + npc( + "long Kamfreena will allow in the enclosure on the very", + "top floor. More tokens equals more time. There are", + "also some bonuses available should you take part in all of", + "the activites around the guild." + ) + stage = 44 + } + + 43 -> { + interpreter.sendDialogues( + npc, + FacialExpression.HALF_GUILTY, + "will allow in the enclosure on the very top floor. More", + "tokens equals more time. There are also some bonuses", + "available should you take part in all of the activites", + "around the guild." + ) + stage = 44 + } + + 44 -> { + interpreter.sendDialogues( + player, + FacialExpression.HALF_GUILTY, + "Okay, okay. So, how do i earn these tokens?" + ) + stage = 45 + } + + 45 -> { + interpreter.sendDialogues( + npc, + FacialExpression.HALF_GUILTY, + "You can earn them by simply using the traning exercises", + "around the guild. The staff will enter your token", + "earning into a ledger as you play." + ) + stage = 46 + } + + 46 -> { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Sounds easy enough.") + stage = 120 + } + + 47 -> { + interpreter.sendDialogues( + npc, + FacialExpression.HALF_GUILTY, + "Should you part in all five activites around the guild", + "you can choose to pay for your time on the top floor with", + "tokens of all types. Should you do this then you'll find you", + "spend less tokens overall and have a better chance of" + ) + stage = 48 + } + + 48 -> { + interpreter.sendDialogues( + npc, + FacialExpression.HALF_GUILTY, + "getting the dragon defender, amongst other things." + ) + stage = 49 + } + + 49 -> { + interpreter.sendDialogues( + player, + FacialExpression.HALF_GUILTY, + "Excellent, sounds good. So, what's up on the top floor?" + ) + stage = 50 + } + + 50 -> { + interpreter.sendDialogues( + npc, + FacialExpression.HALF_GUILTY, + "Well, wit giving too much away, they're big and mean,", + "and you get to fight them for defenders. If you're really", + "lucky, they'll summon a cyclossus...although that be", + "unlucky. Still, if you manage to defeat him, you could win" + ) + stage = 51 + } + + 51 -> { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "his hat.") + stage = 52 + } + + 52 -> { + interpreter.sendDialogues( + player, + FacialExpression.HALF_GUILTY, + "Interesting...I will have to explore the top floor then!" + ) + stage = 10 + } + + 53 -> { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Yes indeed. What would you like to know?") + stage = 10 + } + + 120 -> end() + } + return true + } + + override fun newInstance(player: Player): DialoguePlugin { + return HarrallakMenarous(player) + } + + override fun getIds(): IntArray { + // This has the wrong enum. + return intArrayOf(NPCs.RESOURCE_NPC_8267) + } +} diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/HelemosDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/HelemosDialogue.kt new file mode 100644 index 0000000..aede4cd --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/HelemosDialogue.kt @@ -0,0 +1,47 @@ +package content.region.asgarnia.burthorpe.dialogue + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class HelemosDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, HelemosDialogueFile(), npc) + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return HelemosDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.HELEMOS_797) + } +} +class HelemosDialogueFile : DialogueBuilderFile() { + + override fun create(b: DialogueBuilder) { + + b.onPredicate { _ -> true } + .npc("Welcome to the Heroes' Guild!") + .options() + .let { optionBuilder -> + optionBuilder.option("So do you sell anything here?") + .playerl("So do you sell anything good here?") + .npcl("Why yes! We DO run an exclusive shop for our members!") + .endWith { _, player -> + openNpcShop(player, NPCs.HELEMOS_797) + end() + } + optionBuilder.option_playerl("So what can I do here?") + .npcl("Look around... there are all sorts of things to keep our guild members entertained!") + .end() + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/HildDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/HildDialogue.kt new file mode 100644 index 0000000..6b0116c --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/HildDialogue.kt @@ -0,0 +1,48 @@ +package content.region.asgarnia.burthorpe.dialogue + +import core.api.isQuestComplete +import core.api.toIntArray +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs +import content.data.Quests + +/** + * Hild Dialogue + * @author 'Vexia + * @author ovenbread + */ +@Initializable +class HildDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int) : Boolean { + if(isQuestComplete(player!!, Quests.DEATH_PLATEAU)) { + when (stage) { + START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hi!").also { stage = (1..3).toIntArray().random() } + 1 -> npcl(FacialExpression.HAPPY, "I heard about what you did, thank you!").also { stage = END_DIALOGUE } + 2 -> npcl(FacialExpression.HAPPY, "Thank you so much!").also { stage = END_DIALOGUE } + 3 -> npcl(FacialExpression.HAPPY, "Surely we are safe now!").also { stage = END_DIALOGUE } + } + } else { + when (stage) { + START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hi!").also { stage = (1..3).toIntArray().random() } + 1 -> npcl(FacialExpression.FRIENDLY, "Hello stranger.").also { stage = END_DIALOGUE } + 2 -> npcl(FacialExpression.FRIENDLY, "Hi!").also { stage = END_DIALOGUE } + 3 -> npcl(FacialExpression.FRIENDLY, "Welcome to Burthorpe!").also { stage++ } + 4 -> playerl(FacialExpression.FRIENDLY, "Thanks!").also { stage = END_DIALOGUE } + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return CeolburgDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.HILD_1090) + } +} diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/HygdDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/HygdDialogue.kt new file mode 100644 index 0000000..3e3b73b --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/HygdDialogue.kt @@ -0,0 +1,49 @@ +package content.region.asgarnia.burthorpe.dialogue + +import core.api.isQuestComplete +import core.api.toIntArray +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs +import content.data.Quests + +/** + * Hygd Dialogue + * @author 'Vexia + * @author ovenbread + */ +@Initializable +class HygdDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int) : Boolean { + if(isQuestComplete(player!!, Quests.DEATH_PLATEAU)) { + when (stage) { + START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hi!").also { stage = (1..3).toIntArray().random() } + 1 -> npcl(FacialExpression.HAPPY, "I heard about what you did, thank you!").also { stage = END_DIALOGUE } + 2 -> npcl(FacialExpression.HAPPY, "Thank you so much!").also { stage = END_DIALOGUE } + 3 -> npcl(FacialExpression.HAPPY, "Surely we are safe now!").also { stage = END_DIALOGUE } + } + } else { + when (stage) { + START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hi!").also { stage = (1..3).toIntArray().random() } + 1 -> npcl(FacialExpression.FRIENDLY, "Hello stranger.").also { stage = END_DIALOGUE } + 2 -> npcl(FacialExpression.FRIENDLY, "Hi!").also { stage = END_DIALOGUE } + 3 -> npcl(FacialExpression.FRIENDLY, "Welcome to Burthorpe!").also { stage++ } + 4 -> playerl(FacialExpression.FRIENDLY, "Thanks!").also { stage = END_DIALOGUE } + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return HygdDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.HYGD_1088) + } +} + diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/JadeDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/JadeDialogue.kt new file mode 100644 index 0000000..85ebda9 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/JadeDialogue.kt @@ -0,0 +1,106 @@ +package content.region.asgarnia.burthorpe.dialogue + +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.IronmanMode +import core.plugin.Initializable +import org.rs09.consts.NPCs +import core.game.dialogue.IfTopic +import core.game.dialogue.Topic +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE + +/** + * Provides a dialogue tree for Jade inside Warriors' Guild. + * + * @author vddCore + */ +@Initializable +class JadeDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + START_DIALOGUE -> if (hasIronmanRestriction(player, IronmanMode.ULTIMATE)) { + npcl( + FacialExpression.NEUTRAL, + "Greetings, warrior. I wish I could help you, but " + + "our services are not available for Ultimate ${if (player.isMale) "Ironmen" else "Ironwomen"}." + ).also { stage = END_DIALOGUE } + } + else { + npcl( + FacialExpression.NEUTRAL, + "Greetings warrior, how may I help you?" + ).also { + if (hasAwaitingGrandExchangeCollections(player)) { + stage++ + } else { + stage += 2 + } + } + } + + 1 -> npcl( + FacialExpression.NEUTRAL, + "Before we go any further, I should inform you that you " + + "have items ready for collection from the Grand Exchange." + ).also { stage++ } + + 2 -> showTopics( + Topic(FacialExpression.NEUTRAL, "I'd like to access my bank account, please.", 10), + IfTopic( + FacialExpression.NEUTRAL, + "I'd like to switch to my ${getBankAccountName(player, true)} bank account.", + 13, + hasActivatedSecondaryBankAccount(player) + ), + Topic(FacialExpression.NEUTRAL, "I'd like to check my PIN settings.", 11), + Topic(FacialExpression.NEUTRAL, "I'd like to see my collection box.", 12), + Topic(FacialExpression.ASKING, "How long have you worked here?", 3) + ) + + 3 -> npcl( + FacialExpression.FRIENDLY, + "Oh, ever since the Guild opened. I like it here." + ).also { stage++ } + + 4 -> playerl( + FacialExpression.ASKING, + "Why's that?" + ).also { stage++ } + + 5 -> npcl( + FacialExpression.FRIENDLY, + "Well... What with all these warriors around, there's not much chance of my bank being robbed, is there?" + ).also { stage = 2 } + + 10 -> { + openBankAccount(player) + end() + } + + 11 -> { + openBankPinSettings(player) + end() + } + + 12 -> { + openGrandExchangeCollectionBox(player) + end() + } + + 13 -> { + toggleBankAccount(player) + npcl( + FacialExpression.FRIENDLY, + "Of course! Your ${getBankAccountName(player)} account is now active!" + ).also { stage = END_DIALOGUE } + } + } + + return true + } + + override fun getIds(): IntArray = intArrayOf(NPCs.JADE_4296) +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/KamfreenaDialogue.java b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/KamfreenaDialogue.java new file mode 100644 index 0000000..aa398ea --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/KamfreenaDialogue.java @@ -0,0 +1,154 @@ +package content.region.asgarnia.burthorpe.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Handles the KamfreenaDialogue dialogue. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class KamfreenaDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code KamfreenaDialogue} {@code Object}. + */ + public KamfreenaDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code KamfreenaDialogue} {@code Object}. + * @param player the player. + */ + public KamfreenaDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new KamfreenaDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, null, "Why hello there! I'm Kamfreena. Like the look of my pets?", "I think they're eyeing you up."); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(player, null, "That was a really bad pun."); + stage = 1; + break; + case 1: + interpreter.sendDialogues(npc, null, "Sorry...I don't get to see the rest of the guild much", "stuck up here. The cyclopes don't talk much you see."); + stage = 2; + break; + case 2: + interpreter.sendDialogues(player, null, "Shouldn't that be cyclopses?"); + stage = 3; + break; + case 3: + interpreter.sendDialogues(npc, null, "Nope! Cyclopes is the plural of cyclops. One cyclops,", "many cyclopes."); + stage = 4; + break; + case 4: + interpreter.sendDialogues(player, null, "Oh, right, thanks."); + stage = 5; + break; + case 5: + interpreter.sendOptions("Select an Option", "Where are they from?", "How did they get here?", "Why are they here?", "Bye!"); + stage = 6; + break; + case 6: + if (buttonId == 1) { + interpreter.sendDialogues(player, null, "Where are they from?"); + stage = 7; + } else if (buttonId == 2) { + interpreter.sendDialogues(player, null, "How did they get here?"); + stage = 8; + } else if (buttonId == 3) { + interpreter.sendDialogues(player, null, "Why are they here?"); + stage = 9; + } else if (buttonId == 4) { + interpreter.sendDialogues(player, null, "Bye!"); + stage = 20; + } + break; + case 7: + interpreter.sendDialogues(npc, null, "They're from the far east lands."); + stage = 5; + break; + case 8: + interpreter.sendDialogues(npc, null, "Ahh.. our guildmaster, Harrallak, went on an expedition", "there. He brought them back with him."); + stage = 5; + break; + case 9: + interpreter.sendDialogues(npc, null, "For the warriors to train on of course! They also drop a", "rather nice blade."); + stage = 10; + break; + case 10: + interpreter.sendDialogues(player, null, "Oh? What would that be?"); + stage = 11; + break; + case 11: + interpreter.sendDialogues(npc, null, "Defenders."); + stage = 12; + break; + case 12: + interpreter.sendDialogues(player, null, "Err what are they?"); + stage = 13; + break; + case 13: + interpreter.sendDialogues(npc, null, "It's a blade you can defend with using your shield hand,", "like I have."); + stage = 14; + break; + case 14: + interpreter.sendDialogues(player, null, "Wow!"); + stage = 15; + break; + case 15: + interpreter.sendDialogues(npc, null, "For every 10 tokens you collect around the guild, you", "can spend one minute in with my pets. As you get", "defenders you can show them to me to earn even", "better ones... but remember if you lose them you'll have"); + stage = 16; + break; + case 16: + interpreter.sendDialogues(npc, null, "to start at bronze again. I'd advise keeping a spare in", "your bank."); + stage = 17; + break; + case 17: + interpreter.sendDialogues(player, null, "Ok!"); + stage = 18; + break; + case 18: + interpreter.sendDialogues(npc, null, "Oh, by the way, you need to earn 100 tokens", "before I'll let you in!"); + stage = 19; + break; + case 19: + interpreter.sendDialogues(player, null, "Right, I'd better go play some games then!"); + stage = 5; + break; + case 20: + interpreter.sendDialogues(npc, null, "See you back here soon I hope!"); + stage = 21; + break; + case 21: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 4289 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/LidioDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/LidioDialogue.kt new file mode 100644 index 0000000..c6c76e0 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/LidioDialogue.kt @@ -0,0 +1,42 @@ +package content.region.asgarnia.burthorpe.dialogue + +import core.api.openDialogue +import core.api.openNpcShop +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class LidioDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, LidioDialogueFile(), npc) + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return LidioDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.LIDIO_4293) + } +} + +class LidioDialogueFile : DialogueBuilderFile() { + + override fun create(b: DialogueBuilder) { + b.defaultDialogue().npcl(FacialExpression.ASKING, + "Greetings, warrior, how can I fill your stomach today?" + ).playerl(FacialExpression.NEUTRAL, + "With food preferrable." + ).endWith { _, player -> + openNpcShop(player, NPCs.LIDIO_4293) + end() + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/LillyDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/LillyDialogue.kt new file mode 100644 index 0000000..553366b --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/LillyDialogue.kt @@ -0,0 +1,56 @@ +package content.region.asgarnia.burthorpe.dialogue + +import core.api.openDialogue +import core.api.openNpcShop +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class LillyDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, LillyDialogueFile(), npc) + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return LillyDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.LILLY_4294) + } +} + +class LillyDialogueFile : DialogueBuilderFile() { + + override fun create(b: DialogueBuilder) { + b.defaultDialogue().npcl( + FacialExpression.HALF_GUILTY, "Uh..... hi... didn't see you there. Can.... I help?" + ).playerl( + FacialExpression.HALF_ASKING, " Umm... do you sell potions?" + ).npcl( + FacialExpression.HALF_GUILTY, " Erm... yes. When I'm not drinking them." + ).options().let { optionsBuilder -> + optionsBuilder.option("I'd like to see what you have for sale.") + .playerl(FacialExpression.FRIENDLY, "I'd like to see what you have for sale. ") + .endWith { _, player -> openNpcShop(player, NPCs.LILLY_4294) } + optionsBuilder.option("That's a pretty wall hanging.").playerl( + FacialExpression.FRIENDLY, "That's a pretty wall hanging." + ).npcl( + FacialExpression.HAPPY, " Do you think so? I made it myself." + ).playerl( + FacialExpression.ASKING, " Really? Is that why there's all this cloth and dye around?" + ).npcl( + FacialExpression.HAPPY, " Yes, it's a hobby of mine when I'm.... relaxing." + ).end() + optionsBuilder.option("Bye. ").playerl(FacialExpression.FRIENDLY, "Bye.") + .npcl(FacialExpression.FRIENDLY, " Have fun and come back soon!").end() + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/MartinThwaitDialogue.java b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/MartinThwaitDialogue.java new file mode 100644 index 0000000..675d048 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/MartinThwaitDialogue.java @@ -0,0 +1,204 @@ +package content.region.asgarnia.burthorpe.dialogue; + +import core.api.Container; +import core.api.ContentAPIKt; +import core.cache.def.impl.NPCDefinition; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.skill.Skills; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Plugin; +import core.plugin.Initializable; +import core.plugin.ClassScanner; +import org.rs09.consts.Items; + +/** + * Represents the dialogue used for martin thwait. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class MartinThwaitDialogue extends DialoguePlugin { + + /** + * Represents the skillcape items. + */ + private static final Item[] ITEMS = new Item[] { new Item(9777), new Item(9778), new Item(9779) }; + + /** + * Represents the coins to use. + */ + private static final Item COINS = new Item(995, 99000); + + /** + * Constructs a new {@code MartinThwait} {@code Object}. + */ + public MartinThwaitDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code MartinThwait} {@code Object}. + * @param player the player. + */ + public MartinThwaitDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new MartinThwaitDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "You know it's sometimes funny how things work out, I", "lose some gold but find an item, or I lose an item and", "find some gold... no-one ever knows what's gone where", "ya know."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + if (player.getSkills().getLevel(Skills.THIEVING) == 99) { + interpreter.sendOptions("Select an Option", "Yeah I know what you mean, found anything recently?", "Okay... I'll be going now.", "Can you tell me about your skillcape?"); + stage = 1; + } else { + interpreter.sendOptions("Select an Option", "Yeah I know what you mean, found anything recently?", "Okay... I'll be going now."); + stage = 1; + } + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Yeah I know what you mean, found anything recently?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Okay... I'll be going now."); + stage = 20; + break; + case 3: + if (player.getSkills().getLevel(Skills.THIEVING) == 99) { + interpreter.sendDialogues(player, null, "Can you tell me about your skillcape?"); + stage = 30; + break; + } + break; + } + break; + case 10: + if (player.getSkills().getLevel(Skills.AGILITY) >= 50 && player.getSkills().getLevel(Skills.THIEVING) >= 50 || player.getSkills().getLevel(Skills.THIEVING) == 99) { + end(); + npc.openShop(player); + } else { + if (player.getSkills().getLevel(Skills.THIEVING) < 50) { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Sorry, mate. Train up your Thieving skill to at least", "50 and I might be able to help you out."); + } + if (player.getSkills().getLevel(Skills.AGILITY) < 50) { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Sorry, mate. Train up your Agility skill to at least", "50 and I might be able to help you out."); + } + } + stage = 11; + break; + case 11: + end(); + break; + case 20: + end(); + break; + case 30: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Sure, this is a Skillcape of Thieving. It shows my stature as", "a master thief! It has all sorts of uses , if you", "have a level of 99 Thieving I'll sell you one."); + stage = 31; + break; + case 31: + if (player.getSkills().getStaticLevel(Skills.THIEVING) == 99) { + options("Yes, please.", "No, thanks."); + stage = 32; + } else { + end(); + } + break; + case 32: + switch (buttonId) { + case 1: + player("Yes, please."); + stage = 33; + break; + case 2: + end(); + break; + } + break; + case 33: + if (player.getInventory().freeSlots() < 2) { + player("Sorry, I don't seem to have enough inventory space."); + stage = 34; + return true; + } + if (!ContentAPIKt.inInventory(player, COINS.getId(), COINS.getAmount())) { + player("Sorry, I don't seem to have enough coins", "with me at this time."); + stage = 34; + return true; + } + if (ContentAPIKt.removeItem(player, COINS, Container.INVENTORY)) { + ContentAPIKt.addItemOrDrop(player, ITEMS[player.getSkills().getMasteredSkills() > 1 ? 1 : 0].getId(),1); + ContentAPIKt.addItemOrDrop(player, ITEMS[2].getId(),1); + npc("There you go! Enjoy."); + } else { + player("Sorry, I don't seem to have enough coins", "with me at this time."); + } + stage = 34; + break; + case 34: + end(); + break; + } + return true; + } + + @Override + public void init() { + ClassScanner.definePlugin(new OptionHandler() { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + NPCDefinition.forId(2270).getHandlers().put("option:trade", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + if (player.getSkills().getLevel(Skills.AGILITY) > 50 && player.getSkills().getLevel(Skills.THIEVING) > 50 || player.getSkills().getLevel(Skills.THIEVING) == 99) { + if (npc == null) { + return true; + } + npc.openShop(player); + } else { + if (player.getSkills().getLevel(Skills.THIEVING) < 50) { + player.getDialogueInterpreter().sendDialogues(2270, FacialExpression.HALF_GUILTY, "Sorry, mate. Train up your Thieving skill to at least", "50 and I might be able to help you out."); + } + if (player.getSkills().getLevel(Skills.AGILITY) < 50) { + player.getDialogueInterpreter().sendDialogues(2270, FacialExpression.HALF_GUILTY, "Sorry, mate. Train up your Agility skill to at least", "50 and I might be able to help you out."); + } + } + return true; + } + + }); + super.init(); + } + + @Override + public int[] getIds() { + return new int[] { 2270 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/OcgaDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/OcgaDialogue.kt new file mode 100644 index 0000000..0606c45 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/OcgaDialogue.kt @@ -0,0 +1,49 @@ +package content.region.asgarnia.burthorpe.dialogue + +import core.api.isQuestComplete +import core.api.toIntArray +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs +import content.data.Quests + + +/** + * Ocga Dialogue + * @author 'Vexia + * @author ovenbread + */ +@Initializable +class OcgaDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int) : Boolean { + if(isQuestComplete(player!!, Quests.DEATH_PLATEAU)) { + when (stage) { + START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hi!").also { stage = (1..3).toIntArray().random() } + 1 -> npcl(FacialExpression.HAPPY, "I heard about what you did, thank you!").also { stage = END_DIALOGUE } + 2 -> npcl(FacialExpression.HAPPY, "Thank you so much!").also { stage = END_DIALOGUE } + 3 -> npcl(FacialExpression.HAPPY, "Surely we are safe now!").also { stage = END_DIALOGUE } + } + } else { + when (stage) { + START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hi!").also { stage = (1..3).toIntArray().random() } + 1 -> npcl(FacialExpression.FRIENDLY, "Hello stranger.").also { stage = END_DIALOGUE } + 2 -> npcl(FacialExpression.FRIENDLY, "Hi!").also { stage = END_DIALOGUE } + 3 -> npcl(FacialExpression.FRIENDLY, "Welcome to Burthorpe!").also { stage++ } + 4 -> playerl(FacialExpression.FRIENDLY, "Thanks!").also { stage = END_DIALOGUE } + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return OcgaDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.OCGA_1085) + } +} diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/PendaDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/PendaDialogue.kt new file mode 100644 index 0000000..0570a0d --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/PendaDialogue.kt @@ -0,0 +1,59 @@ +package content.region.asgarnia.burthorpe.dialogue + +import core.api.isQuestComplete +import core.api.toIntArray +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs +import content.data.Quests + +/** + * Penda Dialogue + * @author 'Vexia + * @author ovenbread + */ +@Initializable +class PendaDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int) : Boolean { + if(isQuestComplete(player!!, Quests.DEATH_PLATEAU)) { + when (stage) { + START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hi!").also { stage = (1..5).toIntArray().random() } + 1 -> npcl(FacialExpression.HAPPY, "I heard about what you did, thank you!").also { stage = END_DIALOGUE } + 2 -> npcl(FacialExpression.WORRIED, "The White Knights are still going to take over.").also { stage = END_DIALOGUE } + 3 -> npcl(FacialExpression.PANICKED, "I hear the Imperial Guard are preparing an attack!").also { stage = END_DIALOGUE } + 4 -> npcl(FacialExpression.HAPPY, "Thank you so much!").also { stage = END_DIALOGUE } + 5 -> npcl(FacialExpression.HAPPY, "Surely we are safe now!").also { stage = END_DIALOGUE } + } + } else { + when (stage) { + START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hi!").also { stage = (1..12).toIntArray().random() } + 1 -> npcl(FacialExpression.ANGRY, "Let me at 'em!").also { stage = END_DIALOGUE } + 2 -> npcl(FacialExpression.ANGRY, "Trolls? Schmolls!").also { stage = END_DIALOGUE } + 3 -> npcl(FacialExpression.PANICKED, "The trolls are coming!").also { stage = END_DIALOGUE } + 4 -> npcl(FacialExpression.PANICKED, "The trolls took my baby son!").also { stage = END_DIALOGUE } + 5 -> npcl(FacialExpression.PANICKED, "Trolls!").also { stage = END_DIALOGUE } + 6 -> npcl(FacialExpression.FRIENDLY, "Hello stranger.").also { stage = END_DIALOGUE } + 7 -> npcl(FacialExpression.ANGRY, "Go away!").also { stage = END_DIALOGUE } + 8 -> npcl(FacialExpression.PANICKED, "Run!").also { stage = END_DIALOGUE } + 9 -> npcl(FacialExpression.FRIENDLY, "Hi!").also { stage = END_DIALOGUE } + 10 -> npcl(FacialExpression.SAD, "The Imperial Guard can no longer protect us!").also { stage = END_DIALOGUE } + 11 -> npcl(FacialExpression.WORRIED, "The White Knights will soon have control!").also { stage = END_DIALOGUE } + 12 -> npcl(FacialExpression.FRIENDLY, "Welcome to Burthorpe!").also { stage++ } + 13 -> playerl(FacialExpression.FRIENDLY, "Thanks!").also { stage = END_DIALOGUE } + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return PendaDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.PENDA_1087) + } +} diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/RachaelDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/RachaelDialogue.kt new file mode 100644 index 0000000..2a189cb --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/RachaelDialogue.kt @@ -0,0 +1,58 @@ +package content.region.asgarnia.burthorpe.dialogue + +import core.api.openNpcShop +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class RachaelDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int) : Boolean { + when (stage) { + START_DIALOGUE -> npcl(FacialExpression.FRIENDLY, "Welcome to the Burthorpe Games Rooms!").also { stage++ } + 1 -> showTopics( + Topic(FacialExpression.FRIENDLY, "How do I play board games?", 10), + Topic(FacialExpression.FRIENDLY, "What games can I play?", 30), + Topic(FacialExpression.FRIENDLY, "Can I buy a drink please?", 20), + Topic(FacialExpression.FRIENDLY, "Thanks!", END_DIALOGUE), + ) + 10 -> npcl(FacialExpression.FRIENDLY, "You can challenge someone to a game anywhere in the games rooms by using the right click option. Choose the type of game and then choose the options you want such as time per move. If you want to play a particular").also { stage++ } + 11 -> npcl(FacialExpression.FRIENDLY, "game there are challenge rooms dedicated to that game. In the challenge rooms you can see other players ranks by right clicking them, their skill will be displayed instead of their combat level. Once you have enough").also { stage++ } + 12 -> npcl(FacialExpression.FRIENDLY, "experience you will be able to use the challenge rooms on the first floor! If your opponent accepts the challenge you will be taken to one of the tables in the main room where you will play your game of choice.").also { stage++ } + 13 -> npcl(FacialExpression.FRIENDLY, "Once you have finished your game you will go back to the challenge room where you can challenge again!").also { stage = 1 } + + 20 -> npcl(FacialExpression.FRIENDLY, "Certainly ${if (player.isMale) "sir" else "miss"}, our speciality is Asgarnian Ale, we also serve Wizard's Mind Bomb and Dwarven Stout.").also { stage++ } + 21 -> openNpcShop(player, npc.id).also { + end() + stage = END_DIALOGUE + } + + 30 -> npcl(FacialExpression.FRIENDLY, "Currently we offer Draughts, Runelink, Runesquares, and Runeversi.").also { stage++ } + + 31 -> showTopics( + Topic(FacialExpression.FRIENDLY, "Draughts?", 35), + Topic(FacialExpression.FRIENDLY, "Runelink?", 36), + Topic(FacialExpression.FRIENDLY, "Runesquares?", 37), + Topic(FacialExpression.FRIENDLY, "Runeversi?", 38), + ) + 35 -> npcl(FacialExpression.FRIENDLY, "Draughts uses standard rules, apart from: a draw is declared if no piece has been taken or promoted for forty moves. To play Draughts go to the challenge room in the SW corner.").also { stage = 1 } + 36 -> npcl(FacialExpression.FRIENDLY, "Yup, you have to get four runes in row. The challenge room for Runelink is in the SE corner.").also { stage = 1 } + 37 -> npcl(FacialExpression.FRIENDLY, "Yes, you take it in turns to add a line with the goal of making squares. Everytime you make a square you take another turn. The challenge room for Runesquares is in the SW corner.").also { stage = 1 } + 38 -> npcl(FacialExpression.FRIENDLY, "Yep, the aim is to have more of your runes on the board than your opponent. You can take your opponents pieces by trapping them between your own. The challenge room for Runeversi is in the SE corner.").also { stage = 1 } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return RachaelDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.RACHAEL_1358) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/ReffDialogue.java b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/ReffDialogue.java new file mode 100644 index 0000000..079cc66 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/ReffDialogue.java @@ -0,0 +1,171 @@ +package content.region.asgarnia.burthorpe.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * The ref dialogue. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class ReffDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code ReffDialogue} {@code Object}. + */ + public ReffDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code ReffDialogue} {@code Object}. + * @param player the player. + */ + public ReffDialogue(final Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new ReffDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + npc("Greetings " + (player.getAppearance().isMale() ? "Sir" : "Madam") + "."); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + options("Tell me about the Shot Put area.", "May I claim my tokens please?", "Do you have any tips for me?", "Bye!"); + stage++; + break; + case 1: + switch (buttonId) { + case 1: + player("Tell me about the Shot Put area."); + stage = 10; + break; + case 2: + end(); + player.getDialogueInterpreter().open("wg:claim-tokens", npc.getId()); + break; + case 3: + player("Do you have any tips for me?"); + stage = 30; + break; + case 4: + player("Bye!"); + stage = 40; + break; + } + break; + case 10: + npc("Of course " + (player.getAppearance().isMale() ? "Sir" : "Madam") + ". There are two different weights of", "shot..."); + stage++; + break; + case 11: + player("Shot?"); + stage++; + break; + case 12: + npc("Yes Madam. Shot. The iron spheres that are propelled", "by chemical energy stored in your body."); + stage++; + break; + case 13: + player("The... what?"); + stage++; + break; + case 14: + npc("Your strength " + (player.getAppearance().isMale() ? "Sir" : "Madam") + ". The stronger you are, the", "further you can throw the shot, but there are other", "factors of course, like your technique."); + stage++; + break; + case 15: + player("What's that then?"); + stage++; + break; + case 16: + npc("The style of the shot " + (player.getAppearance().isMale() ? "Sir" : "Madam") + "."); + stage++; + break; + case 17: + player("Iron has style??"); + stage++; + break; + case 18: + interpreter.sendDialogue("The Referee sighs, rolls his eyes and continues...."); + stage++; + break; + case 19: + npc((player.getAppearance().isMale() ? "Sir" : "Madam") + ", the style in which you throw the shot, not the", "style of iron."); + stage = -1; + break; + case -1: + player("OH! You mean the spinny round thing or the chuck it", "straight?"); + stage = -2; + break; + case -2: + npc("Crudely put " + (player.getAppearance().isMale() ? "Sir" : "Madam") + ", but yes. Some are more difficult", "than others. Experiment and see which you prefer."); + stage = -3; + break; + case -3: + player("Thanks for the help!"); + stage = -4; + break; + case -4: + npc("You are welcome " + (player.getAppearance().isMale() ? "Sir" : "Madam") + "."); + stage = -5; + break; + case -5: + end(); + break; + case 30: + npc("Tips " + (player.getAppearance().isMale() ? "Sir" : "Madam") + "?"); + stage++; + break; + case 31: + player("Yes, like how can I do better than everyone else."); + stage++; + break; + case 32: + npc((player.getAppearance().isMale() ? "Sir" : "Madam") + " may find that a fine powder applied to the", "hands may give one an advantage when putting the", "shot."); + stage++; + break; + case 33: + player("You mean if I grind something up and put dust on my", "hands I'll chuck the ball further?"); + stage++; + break; + case 34: + npc("Yes " + (player.getAppearance().isMale() ? "Sir" : "Madam") + "."); + stage++; + break; + case 35: + player("Thanks!"); + stage = -4; + break; + case 40: + npc("Good luck " + (player.getAppearance().isMale() ? "Sir" : "Madam") + "."); + stage++; + break; + case 41: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 4299, 4300 }; + } + +} diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/SamDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/SamDialogue.kt new file mode 100644 index 0000000..db371d6 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/SamDialogue.kt @@ -0,0 +1,57 @@ +package content.region.asgarnia.burthorpe.dialogue + +import core.api.openNpcShop +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class SamDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int) : Boolean { + when (stage) { + START_DIALOGUE -> npcl(FacialExpression.FRIENDLY, "Welcome to the Burthorpe Games Rooms!").also { stage++ } + 1 -> showTopics( + Topic(FacialExpression.FRIENDLY, "How do I play board games?", 10), + Topic(FacialExpression.FRIENDLY, "What games can I play?", 30), + Topic(FacialExpression.FRIENDLY, "Can I buy a drink please?", 20), + Topic(FacialExpression.FRIENDLY, "Thanks!", END_DIALOGUE), + ) + 10 -> npcl(FacialExpression.FRIENDLY, "You can challenge someone to a game anywhere in the games rooms by using the right click option. Choose the type of game and then choose the options you want such as time per move. If you want to play a particular").also { stage++ } + 11 -> npcl(FacialExpression.FRIENDLY, "game there are challenge rooms dedicated to that game. In the challenge rooms you can see other players ranks by right clicking them, their skill will be displayed instead of their combat level. Once you have enough").also { stage++ } + 12 -> npcl(FacialExpression.FRIENDLY, "experience you will be able to use the challenge rooms on the first floor! If your opponent accepts the challenge you will be taken to one of the tables in the main room where you will play your game of choice.").also { stage++ } + 13 -> npcl(FacialExpression.FRIENDLY, "Once you have finished your game you will go back to the challenge room where you can challenge again!").also { stage = 1 } + + 20 -> npcl(FacialExpression.FRIENDLY, "Certainly ${if (player.isMale) "sir" else "miss"}, our speciality is Asgarnian Ale, we also serve Wizard's Mind Bomb and Dwarven Stout.").also { stage++ } + 21 -> openNpcShop(player, npc.id).also { + end() + stage = END_DIALOGUE + } + + 30 -> npcl(FacialExpression.FRIENDLY, "Currently we offer Draughts, Runelink, Runesquares, and Runeversi.").also { stage++ } + 31 -> showTopics( + Topic(FacialExpression.FRIENDLY, "Draughts?", 35), + Topic(FacialExpression.FRIENDLY, "Runelink?", 36), + Topic(FacialExpression.FRIENDLY, "Runesquares?", 37), + Topic(FacialExpression.FRIENDLY, "Runeversi?", 38), + ) + 35 -> npcl(FacialExpression.FRIENDLY, "Draughts uses standard rules, apart from: a draw is declared if no piece has been taken or promoted for forty moves. To play Draughts go to the challenge room in the SW corner.").also { stage = 1 } + 36 -> npcl(FacialExpression.FRIENDLY, "Yup, you have to get four runes in row. The challenge room for Runelink is in the SE corner.").also { stage = 1 } + 37 -> npcl(FacialExpression.FRIENDLY, "Yes, you take it in turns to add a line with the goal of making squares. Everytime you make a square you take another turn. The challenge room for Runesquares is in the SW corner.").also { stage = 1 } + 38 -> npcl(FacialExpression.FRIENDLY, "Yep, the aim is to have more of your runes on the board than your opponent. You can take your opponents pieces by trapping them between your own. The challenge room for Runeversi is in the SE corner.").also { stage = 1 } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return SamDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.SAM_1357) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/ServantDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/ServantDialogue.kt new file mode 100644 index 0000000..cc3ac53 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/ServantDialogue.kt @@ -0,0 +1,52 @@ +package content.region.asgarnia.burthorpe.dialogue + +import core.api.openDialogue +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * Servant Dialogue + * @author 'Vexia + * @author ovenbread + * @author Trident101 + */ +@Initializable +class ServantDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, ServantDialogueFile(), npc) + return true + } + + override fun newInstance(player: Player): DialoguePlugin { + return ServantDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.SERVANT_1081) + } +} + +class ServantDialogueFile : DialogueBuilderFile() { + + override fun create(b: DialogueBuilder) { + b.defaultDialogue().playerl( + FacialExpression.HALF_GUILTY, + "Hi!" + ).npcl( + FacialExpression.HALF_GUILTY, + "Hi." + ).npcl( + FacialExpression.HALF_GUILTY, + "Look, I'd better not talk. I'll get in trouble." + ).npcl( + FacialExpression.HALF_GUILTY, + "If you want someone to show you round the castle ask Eohric, the Head Servant." + ) + } +} diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/ShanomiDialogue.java b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/ShanomiDialogue.java new file mode 100644 index 0000000..d3c6f41 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/ShanomiDialogue.java @@ -0,0 +1,144 @@ +package content.region.asgarnia.burthorpe.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * The dialogue used for shanomi. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class ShanomiDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code Shanomi} {@code Object}. + */ + public ShanomiDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code Shanomi} {@code Object}. + * @param player the player. + */ + public ShanomiDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new ShanomiDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, null, "Greetings " + player.getUsername() + ". Welcome you are in the test of", "combat."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "What do I do here?", "Where do the machines come from?", "May I claim my tokens please?", "Bye."); + stage = 1; + break; + case 1: + if (buttonId == 1) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What do I do here?"); + stage = 2; + } else if (buttonId == 2) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Where do the machines come from?"); + stage = 11; + } else if (buttonId == 3) { + end(); + player.getDialogueInterpreter().open("wg:claim-tokens", npc.getId()); + } else if (buttonId == 4) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Bye."); + stage = 16; + } + break; + case 2: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "A spare suit of plate armour need you will. Full helm", "plate, leggings and platebody. Placing it in the centre", "of the magical machines you will be doing. KA-POOF!", "The armour it attacks most furiously as if alive! Kill it"); + stage = -3; + break; + case -3: + npc("you must, yes."); + stage = 3; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "So I use a full set of plate armour on the centre plate of", "the machines and it will animate it? Then I have to kill my", "own armour... how bizarre!"); + stage = 4; + break; + case 4: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Yes. It is as you are saying. For this earn tokens you", "will. Also gain experience in combat you will. Trained", "long and hard here have I."); + stage = 5; + break; + case 5: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "You're not from around here are you...?"); + stage = 6; + break; + case 6: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "It is as you say."); + stage = 7; + break; + case 7: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "So will I lose my armour?"); + stage = 8; + break; + case 8: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Lose armour you will if damaged to much it becomes.", "Rare this is, but still possible. If kill you the armour does,", "also lose armour you will."); + stage = 9; + break; + case 9: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "So, occasionally I might lose a bit because it's being", "bashed about and I'll obviously lose it if I die... that it?"); + stage = 10; + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "It is as you say."); + stage = 0; + break; + case 11: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Make them I did, with magics."); + stage = 12; + break; + case 12: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Magic, in the Warrior's Guild?"); + stage = 13; + break; + case 13: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "A skilled warrior also am I. Harrallak mistakes does not", "make. Potential in my invention he sees and opportunity", "grasps."); + stage = 14; + break; + case 14: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I see, so you made the magical machines and Harrallak", "saw how they could be used in the guild to train warrior's", "combat... interesting. Harrallak certainly is an intelligent", "guy."); + stage = 15; + break; + case 15: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "It is as you say."); + stage = 0; + break; + case 16: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Health be with you travelling."); + stage = 100; + break; + case 100: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 4290 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/SloaneDialogue.java b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/SloaneDialogue.java new file mode 100644 index 0000000..d74f626 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/SloaneDialogue.java @@ -0,0 +1,161 @@ +package content.region.asgarnia.burthorpe.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.global.Skillcape; +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; + +/** + * Represents the dialogue plugin used for sloane. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class SloaneDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code SloaneDialogue} {@code Object}. + */ + public SloaneDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code SloaneDialogue} {@code Object}. + * @param player the player. + */ + public SloaneDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new SloaneDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + if (Skillcape.isMaster(player, Skills.STRENGTH)) { + options("Ask about Skillcape", "Something else"); + stage = 0; + } else { + npc("Ahhh, hello there, " + player.getUsername() + "."); + stage = 10; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + switch (buttonId) { + case 1: + player("Can I buy a Skillcape of Strength?"); + stage = 100; + break; + case 2: + npc("Ahhh, hello there, " + player.getUsername() + "."); + stage = 10; + break; + } + break; + case 10: + options("What can I do here?", "That's a big axe!", "May I claim my tokens please?", "Bye!"); + stage++; + break; + case 11: + switch (buttonId) { + case 1: + player("What can I do here?"); + stage = 12; + break; + case 2: + player("That's a big axe!"); + stage = 30; + break; + case 3: + close(); + player.getDialogueInterpreter().open("wg:claim-tokens", npc.getId()); + break; + case 4: + player("Bye!"); + stage = 50; + break; + } + break; + case 12: + npc("Ahh, the shot put is a great test of strength and can be", "quite rewarding. Mind you do it properly though, you", "might want to dust your hands with some powdery", "substance first. It'll give better grip."); + stage++; + break; + case 13: + end(); + break; + case 30: + npc("Yes indeed it is. Have to be mighty strong to wield it", "too."); + stage++; + break; + case 31: + player("But you don't look that strong!"); + stage++; + break; + case 32: + npc("Maybe, maybe not, but I still had to beat a Barbarian", "to get it. Mind you, usually they don't part with them.", "This was an unusual circumstance."); + stage++; + break; + case 33: + end(); + break; + case 50: + npc("Be well, warrior " + player.getUsername() + "."); + stage++; + break; + case 51: + end(); + break; + case 40: + close(); + player.getDialogueInterpreter().open("wg:claim-tokens", npc.getId()); + break; + case 100: + npc("Certainly! Right when you give me 99000 coins."); + stage = 101; + break; + case 101: + options("Okay, here you go.", "No, thanks."); + stage = 102; + break; + case 102: + switch (buttonId) { + case 1: + player("Okay, here you go."); + stage = 103; + break; + case 2: + end(); + break; + } + break; + case 103: + if (Skillcape.purchase(player, Skills.STRENGTH)) { + npc("There you go! Enjoy."); + } + stage = 104; + break; + case 104: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 4297 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/TostigDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/TostigDialogue.kt new file mode 100644 index 0000000..9fb7db3 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/TostigDialogue.kt @@ -0,0 +1,48 @@ +package content.region.asgarnia.burthorpe.dialogue + +import core.api.openNpcShop +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +/** + * Handles the TostigDialogue dialogue. + * @author 'Vexia + */ +@Initializable +class TostigDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> playerl(FacialExpression.FRIENDLY, "Hi, what ales are you serving?").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "Well ${if (player.isMale) "mister" else "miss"}, our speciality is Asgarnian Ale, we also serve Wizard's Mind Bomb and Dwarven Stout.").also { stage++ } + 2 -> npcl(FacialExpression.FRIENDLY, "Would you like to buy a drink?").also { stage++ } + 3 -> showTopics( + Topic(FacialExpression.FRIENDLY, "Yes, please.", 10), + Topic(FacialExpression.FRIENDLY, "No, thanks.", 20), + ) + 10 -> openNpcShop(player, npc.id).also { + end() + stage = END_DIALOGUE + } + 20 -> npcl(FacialExpression.FRIENDLY, "Ah well... so um... does the grey squirrel sing in the grove?").also { stage++ } + 21 -> showTopics( + Topic(FacialExpression.FRIENDLY, "Huh?", 30), + Topic(FacialExpression.FRIENDLY, "Yes, and the black cat dances in the sink.", 40), + Topic(FacialExpression.FRIENDLY, "No, squirrels can't sing.", 50), + ) + 30 -> npcl(FacialExpression.FRIENDLY, "Er... nevermind.").also { stage = END_DIALOGUE } + 40 -> npcl(FacialExpression.FRIENDLY, "Ah you'll be wanting the trapdoor behind the bar.").also { stage = END_DIALOGUE } + 50 -> npcl(FacialExpression.FRIENDLY, "No... of course they can't...").also { stage = END_DIALOGUE } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.TOSTIG_1079) + } +} diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/UnferthDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/UnferthDialogue.kt new file mode 100644 index 0000000..5c0a232 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/UnferthDialogue.kt @@ -0,0 +1,65 @@ +package content.region.asgarnia.burthorpe.dialogue + +import core.api.isQuestComplete +import core.api.openDialogue +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs +import content.data.Quests + +/** + * Unferth Dialogue + * @author ovenbread + * @author Trident101 + */ +@Initializable +class UnferthDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, UnferthDialogueFile(), npc) + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return UnferthDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.UNFERTH_2655) + } +} + +class UnferthDialogueFile : DialogueBuilderFile() { + + override fun create(b: DialogueBuilder) { + b.onPredicate { player -> isQuestComplete(player, Quests.A_TAIL_OF_TWO_CATS) }.playerl( + FacialExpression.FRIENDLY, "Hi Unferth. How are you doing?" + ).npcl( + FacialExpression.GUILTY, "It's just not the same without Bob around." + ).playerl( + FacialExpression.HALF_GUILTY, "I'm so sorry Unferth." + ).npcl( + FacialExpression.HALF_GUILTY, + "Gertrude asked me if I'd like one of her new kittens. I don't think I'm ready for that yet." + ).playerl( + FacialExpression.FRIENDLY, "Give it time. Things will get better, I promise." + ).npcl( + FacialExpression.HALF_GUILTY, "Thanks, @name." + ).end() + + b.defaultDialogue().npcl( + FacialExpression.GUILTY, + "Hello." + ).playerl( + FacialExpression.FRIENDLY, + "What's wrong?" + ).npcl( + FacialExpression.GUILTY, + "It's fine. Nothing for you to worry about." + ).end() + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/dialogue/WistanDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/WistanDialogue.kt new file mode 100644 index 0000000..66fde48 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/dialogue/WistanDialogue.kt @@ -0,0 +1,55 @@ +package content.region.asgarnia.burthorpe.dialogue + +import core.api.openDialogue +import core.api.openNpcShop +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * Represents the Wistan dialogue plugin. + * @author 'Vexia + * @author ovenbread + * @author Trident101 + */ +@Initializable +class WistanDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, WistanDialogueFile(), npc) + return true + } + + override fun newInstance(player: Player): DialoguePlugin { + return WistanDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.WISTAN_1083) + } +} + +class WistanDialogueFile : DialogueBuilderFile() { + + override fun create(b: DialogueBuilder) { + b.defaultDialogue().playerl( + FacialExpression.FRIENDLY, "Hi!" + ).npcl( + FacialExpression.FRIENDLY, + "Welcome to Burthorpe Supplies. Your last shop before heading north into the mountains!" + ).npcl( + FacialExpression.FRIENDLY, "Would you like to buy something?" + ).options().let { optionsBuilder -> + optionsBuilder.option("Yes, please.").playerl( + FacialExpression.FRIENDLY, "Yes, Please" + ).endWith { _, player -> openNpcShop(player, NPCs.WISTAN_1083) } + optionsBuilder.option("No, thanks.").playerl( + FacialExpression.FRIENDLY, "No, thanks." + ).end() + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/handlers/AntonNPC.java b/Server/src/main/content/region/asgarnia/burthorpe/handlers/AntonNPC.java new file mode 100644 index 0000000..ef37619 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/handlers/AntonNPC.java @@ -0,0 +1,54 @@ +package content.region.asgarnia.burthorpe.handlers; + +import core.game.node.entity.npc.AbstractNPC; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.tools.RandomFunction; + +/** + * Handles the anton NPC. + * @author 'Vexia + */ +@Initializable +public final class AntonNPC extends AbstractNPC { + + /** + * The messages to yell. + */ + private static final String[] FORCE_CHAT = { "Armour and axes to suit your needs.", "Imported weapons from the finest smithys around the lands!", "Ow, my toe! That armour is heavy." }; + + /** + * Constructs a new {@code AntonNPC} {@code Object}. + */ + public AntonNPC() { + this(4295, null); + } + + /** + * Constructs a new {@code AntonNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + public AntonNPC(int id, Location location) { + super(id, location); + } + + @Override + public void tick() { + if (RandomFunction.random(45) == 5) { + sendChat(RandomFunction.getRandomElement(FORCE_CHAT)); + } + super.tick(); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new AntonNPC(id, location); + } + + @Override + public int[] getIds() { + return new int[] { 4295 }; + } + +} diff --git a/Server/src/main/content/region/asgarnia/burthorpe/handlers/BurthorpeOptionPlugin.java b/Server/src/main/content/region/asgarnia/burthorpe/handlers/BurthorpeOptionPlugin.java new file mode 100644 index 0000000..c5528ba --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/handlers/BurthorpeOptionPlugin.java @@ -0,0 +1,80 @@ +package content.region.asgarnia.burthorpe.handlers; + +import core.cache.def.impl.NPCDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.game.global.action.ClimbActionHandler; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the option plugin to handle interactions with 'nodes' in + * burthorpe. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class BurthorpeOptionPlugin extends OptionHandler { + + /** + * Represents the thieving guide location. + */ + private static final Location GUIDE_LOCATION = new Location(3061, 4985, 1); + + /** + * Represents the bar location. + */ + private static final Location BAR_LOCATION = new Location(2906, 3537, 0); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(7257).getHandlers().put("option:enter", this);// thieving + // guide + // trapdoor. + SceneryDefinition.forId(7258).getHandlers().put("option:enter", this);// thieving + // guide + // passegeway. + SceneryDefinition.forId(4624).getHandlers().put("option:climb-down", this); + SceneryDefinition.forId(4627).getHandlers().put("option:climb-up", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + final int id = node instanceof NPC ? ((NPC) node).getId() : ((Scenery) node).getId(); + switch (option) { + case "climb-down": + switch (id) { + case 4624: + ClimbActionHandler.climb(player, null, Location.create(2205, 4934, 1)); + break; + } + break; + case "climb-up": + switch (id) { + case 4627: + ClimbActionHandler.climb(player, null, Location.create(2899, 3565, 0)); + break; + } + break; + case "enter": + switch (id) { + case 7257: + player.getProperties().setTeleportLocation(GUIDE_LOCATION); + break; + case 7258: + player.getProperties().setTeleportLocation(BAR_LOCATION); + break; + } + break; + } + return true; + } + +} diff --git a/Server/src/main/content/region/asgarnia/burthorpe/handlers/BurthorpeTrainNPC.java b/Server/src/main/content/region/asgarnia/burthorpe/handlers/BurthorpeTrainNPC.java new file mode 100644 index 0000000..518c707 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/handlers/BurthorpeTrainNPC.java @@ -0,0 +1,181 @@ +package content.region.asgarnia.burthorpe.handlers; + +import java.util.List; + +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.npc.NPC; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.tools.RandomFunction; + +/** + * Represents a burthorpe training npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public class BurthorpeTrainNPC extends AbstractNPC { + + /** + * The NPC ids of NPCs using this plugin. + */ + private static final int[] IDS = { /** dummy soldier */ + 1063, /** sergant */ + 1061, /** seated soldier */ + 1066, 1067, 1068, /** other sergant */ + 1062, /** other soldiers */ + 1064, 1073, 1074, 1076, 1077 }; + + /** + * Represents the punching animation. + */ + private static final Animation PUNCH = new Animation(422); + + /** + * Represents the kicking animation. + */ + private static final Animation KICK = new Animation(423); + + /** + * Represents the defending animation. + */ + private static final Animation DEFEND = new Animation(424); + + /** + * Represents the eating animation. + */ + private static final Animation EAT = new Animation(1145); + + /** + * Represents the messages the sergant can say. + */ + private static final String[] MESSAGES = new String[] { "Good work soldier!", "Push it!", "Work it!", "The dummy is the enemy. Kill it!", "Put your back into it soldier!", "You're not out for a sunday stroll soldier!", "My daughter can hit harder than that!", "I want to see you sweat!", "Keep it up soldier!" }; + + /** + * Represents the delay. + */ + private long delay; + + /** + * Constructs a new {@code BurthorpeTrainNPC} {@code Object}. + */ + public BurthorpeTrainNPC() { + super(0, null); + } + + /** + * Constructs a new {@code AlKharidWarriorPlugin} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + private BurthorpeTrainNPC(int id, Location location) { + super(id, location, id == 1061 ? true : false); + super.setDirection(Direction.EAST); + } + + @Override + public void init() { + super.init(); + if (getId() == 1063) { + faceLocation(getLocation().transform(2, 0, 0)); + } + if (getId() == 1066 || getId() == 1067 || getId() == 1068) { + faceLocation(Location.create(2893, 3532, 0)); + } + if (getId() == 1064) { + faceLocation(getLocation().transform(0, 1, 0)); + } + if (getId() == 1062) { + faceLocation(Location.create(2893, 3539, 0)); + } + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new BurthorpeTrainNPC(id, location); + } + + @Override + public void tick() { + if (delay < System.currentTimeMillis()) { + action(); + } + super.tick(); + } + + @Override + public int getWalkRadius() { + return getId() == 1061 ? 6 : 12; + } + + @Override + public int[] getIds() { + return IDS; + } + + /** + * Method used to do the reward of this npc. + */ + private final void action() { + switch (getId()) { + case 1061:// sergant + sendChat(MESSAGES[RandomFunction.random(MESSAGES.length)]); + delay = System.currentTimeMillis() + 9000 + RandomFunction.random(1000, 5000); + final List soldiers = RegionManager.getLocalNpcs(this); + NPC soldier = null; + while (soldier == null) { + soldier = soldiers.get(RandomFunction.random(soldiers.size())); + if (soldier.getId() != 1063) { + soldier = null; + } + } + final NPC sol = soldier; + GameWorld.getPulser().submit(new Pulse(1) { + final NPC sold = sol; + @Override + public boolean pulse() { + sold.sendChat("Yes, sir!"); + return true; + } + }); + break; + case 1063:// soldier. + faceLocation(getLocation().transform(2, 0, 0)); + animate(RandomFunction.random(2) == 1 ? PUNCH : KICK); + delay = System.currentTimeMillis() + 3000 + RandomFunction.random(1000, 3000); + break; + case 1066: + case 1067: + case 1068:// seated soldier. + animate(EAT); + delay = System.currentTimeMillis() + 3000 + RandomFunction.random(1000, 2000); + break; + case 1062: + final int rand = RandomFunction.random(5); + final Animation animation = rand == 1 ? PUNCH : rand == 2 ? KICK : DEFEND; + animate(animation); + delay = System.currentTimeMillis() + 3500; + faceLocation(getLocation().transform(0, -1, 0)); + GameWorld.getPulser().submit(new Pulse(2) { + @Override + public boolean pulse() { + final List soldiers = RegionManager.getLocalNpcs(BurthorpeTrainNPC.this, 12); + for (NPC n : soldiers) { + if (n.getId() != 1064) { + continue; + } + n.animate(animation); + } + return true; + } + }); + break; + } + } + +} diff --git a/Server/src/main/content/region/asgarnia/burthorpe/handlers/HeroGuildPlugin.java b/Server/src/main/content/region/asgarnia/burthorpe/handlers/HeroGuildPlugin.java new file mode 100644 index 0000000..cc4e8fb --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/handlers/HeroGuildPlugin.java @@ -0,0 +1,124 @@ +package content.region.asgarnia.burthorpe.handlers; + +import core.cache.def.impl.SceneryDefinition; +import content.data.EnchantedJewellery; +import core.game.global.action.DoorActionHandler; +import content.global.skill.summoning.familiar.Familiar; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.OptionHandler; +import core.game.interaction.UseWithHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; +import core.plugin.Initializable; +import core.plugin.ClassScanner; + +import static core.api.ContentAPIKt.hasRequirement; +import content.data.Quests; + +/** + * Represents the hero guild. + * @author Vexia + */ +@Initializable +public final class HeroGuildPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(2624).getHandlers().put("option:open", this); + SceneryDefinition.forId(2625).getHandlers().put("option:open", this); + ClassScanner.definePlugin(new JewelleryRechargePlugin()); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + final int id = ((Scenery) node).getId(); + switch (option) { + case "open": + switch (id) { + case 2624: + case 2625: + if (!hasRequirement(player, Quests.HEROES_QUEST)) + return true; + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + break; + } + return true; + } + return true; + } + + /** + * Handles the recharging of dragonstone jewellery. + * @author Vexia + */ + public static final class JewelleryRechargePlugin extends UseWithHandler { + + /** + * The ids of rechargeable items. + */ + private static final int[] IDS = new int[] { 1710, 1708, 1706, 1704, 11107, 11109, 11111, 11113, 11120, 11122, 11124, 11126, 10354, 10356, 10358, 10360, 10362, 14644,14642,14640,14638, 2572 }; + + /** + * Constructs a new {@Code JewelleryRechargePlugin} {@Code + * Object} + */ + public JewelleryRechargePlugin() { + super(IDS); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(36695, OBJECT_TYPE, this); + addHandler(7339, NPC_TYPE, this); + addHandler(7340, NPC_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + if (!hasRequirement(player, Quests.HEROES_QUEST)) + return true; + final EnchantedJewellery jewellery; + assert event.getUsedItem() != null; + jewellery = EnchantedJewellery.Companion.getIdMap().get(event.getUsedItem().getId()); + if (!hasRequirement(player, Quests.HEROES_QUEST)) + return true; + if (jewellery == EnchantedJewellery.COMBAT_BRACELET || jewellery == EnchantedJewellery.SKILLS_NECKLACE) + if (!hasRequirement(player, Quests.LEGENDS_QUEST)) + return true; + if (jewellery == null && event.getUsedItem().getId() != 2572) { + return true; + } + boolean fam = event.getUsedWith() instanceof NPC; + if (fam && jewellery != EnchantedJewellery.AMULET_OF_GLORY & jewellery != EnchantedJewellery.AMULET_OF_GLORY_T) { + return false; + } + if (fam) { + Familiar familiar = (Familiar) event.getUsedWith(); + if (!player.getFamiliarManager().isOwner(familiar)) { + return false; + } + familiar.animate(Animation.create(7882)); + } + player.lock(1); + player.animate(Animation.create(832)); + Item rechargedItem = new Item(jewellery.getIds()[0]); + player.getInventory().replace(rechargedItem, event.getUsedItem().getSlot()); + String name = jewellery.getJewelleryName(rechargedItem); + if (!fam) { + player.sendMessage("You dip the " + name + " in the fountain..."); + } else { + player.sendMessage("Your titan recharges the glory."); + } + return true; + } + + } +} diff --git a/Server/src/main/content/region/asgarnia/burthorpe/handlers/KamfreenaNPC.java b/Server/src/main/content/region/asgarnia/burthorpe/handlers/KamfreenaNPC.java new file mode 100644 index 0000000..8b0bb7f --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/handlers/KamfreenaNPC.java @@ -0,0 +1,54 @@ +package content.region.asgarnia.burthorpe.handlers; + +import core.game.node.entity.npc.AbstractNPC; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.tools.RandomFunction; + +/** + * Handles the kamfreena NPC. + * @author 'Vexia + */ +@Initializable +public final class KamfreenaNPC extends AbstractNPC { + + /** + * The messages to yell. + */ + private static final String[] FORCE_CHAT = { "When you aim for perfection, you discover it's a moving target.", "Patience and persistence can bring down the tallest tree.", "Be master of mind rather than mastered by mind.", "A reflection on a pool of water does not reveal its depth.", "Life isn't fair, that doesn't mean you can't win." }; + + /** + * Constructs a new {@code KamfreenaNPC} {@code Object}. + */ + public KamfreenaNPC() { + this(4289, null); + } + + /** + * Constructs a new {@code KamfreenaNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + public KamfreenaNPC(int id, Location location) { + super(id, location); + } + + @Override + public void tick() { + if (RandomFunction.random(45) == 5) { + sendChat(RandomFunction.getRandomElement(FORCE_CHAT)); + } + super.tick(); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new KamfreenaNPC(id, location); + } + + @Override + public int[] getIds() { + return new int[] { 4289 }; + } + +} diff --git a/Server/src/main/content/region/asgarnia/burthorpe/handlers/ShanomiNPC.java b/Server/src/main/content/region/asgarnia/burthorpe/handlers/ShanomiNPC.java new file mode 100644 index 0000000..fde92aa --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/handlers/ShanomiNPC.java @@ -0,0 +1,54 @@ +package content.region.asgarnia.burthorpe.handlers; + +import core.game.node.entity.npc.AbstractNPC; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.tools.RandomFunction; + +/** + * Handles the shanomi NPC. + * @author Emperor + */ +@Initializable +public final class ShanomiNPC extends AbstractNPC { + + /** + * The messages to yell. + */ + private static final String[] FORCE_CHAT = { "Those things which cannot be seen, perceive them.", "Do nothing which is of no use.", "Think not dishonestly.", "The Way in training is.", "Gain and loss between you must distinguish.", "Trifles pay attention even to.", "Way of the warrior this is.", "Acquainted with every art become.", "Ways of all professions know you.", "Judgment and understanding for everything develop you must." }; + + /** + * Constructs a new {@code ShanomiNPC} {@code Object}. + */ + public ShanomiNPC() { + this(4290, null); + } + + /** + * Constructs a new {@code ShanomiNPC} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + public ShanomiNPC(int id, Location location) { + super(id, location); + } + + @Override + public void tick() { + if (RandomFunction.random(45) == 5) { + sendChat(RandomFunction.getRandomElement(FORCE_CHAT)); + } + super.tick(); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new ShanomiNPC(id, location); + } + + @Override + public int[] getIds() { + return new int[] { 4290 }; + } + +} diff --git a/Server/src/main/content/region/asgarnia/burthorpe/handlers/wguild/WGuildListeners.kt b/Server/src/main/content/region/asgarnia/burthorpe/handlers/wguild/WGuildListeners.kt new file mode 100644 index 0000000..e20b682 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/handlers/wguild/WGuildListeners.kt @@ -0,0 +1,42 @@ +package content.region.asgarnia.burthorpe.handlers.wguild + +import core.game.component.Component +import core.game.container.impl.EquipmentContainer +import content.region.asgarnia.burthorpe.handlers.wguild.catapult.CatapultRoom +import core.game.node.item.Item +import org.rs09.consts.Items +import core.game.interaction.InteractionListener + +class WGuildListeners : InteractionListener { + override fun defineListeners() { + onEquip(Items.DEFENSIVE_SHIELD_8856){player, node -> + if (node is Item) { + if (player.location != CatapultRoom.TARGET) { + player.packetDispatch.sendMessage("You may not equip this shield outside the target area in the Warrior's Guild.") + return@onEquip false + } + if (player.equipment[EquipmentContainer.SLOT_WEAPON] != null) { + player.dialogueInterpreter.sendDialogue( + "You will need to make sure your sword hand is free to equip this", + "shield." + ) + return@onEquip false + } + + player.interfaceManager.removeTabs(2, 3, 5, 6, 7, 11, 12) + player.interfaceManager.openTab(4, Component(411)) + player.interfaceManager.setViewedTab(4) + player.interfaceManager.open(Component(410)) + return@onEquip true + } + + return@onEquip false + } + + onUnequip(Items.DEFENSIVE_SHIELD_8856){player, _ -> + player.interfaceManager.restoreTabs() + player.interfaceManager.openTab(4, Component(387)) + return@onUnequip true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/handlers/wguild/WarriorsGuild.java b/Server/src/main/content/region/asgarnia/burthorpe/handlers/wguild/WarriorsGuild.java new file mode 100644 index 0000000..7b22894 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/handlers/wguild/WarriorsGuild.java @@ -0,0 +1,165 @@ +package content.region.asgarnia.burthorpe.handlers.wguild; + +import core.cache.def.impl.NPCDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.game.dialogue.DialogueInterpreter; +import core.game.dialogue.DialoguePlugin; +import core.game.global.action.DoorActionHandler; +import core.game.node.entity.skill.Skills; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.world.map.Location; +import core.plugin.Plugin; +import core.plugin.Initializable; +import core.plugin.ClassScanner; + +/** + * Handles the warrior guild options. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class WarriorsGuild extends OptionHandler { + + /** + * The token item id. + */ + public static final int TOKEN = 8851; + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(15653).getHandlers().put("option:open", this); + SceneryDefinition.forId(1530).getHandlers().put("option:open", this); + NPCDefinition.forId(4287).getHandlers().put("option:claim-shield", this); + NPCDefinition.setOptionHandler("claim-tokens", this); + ClassScanner.definePlugin(new ClaimTokenDialogue()); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + switch (node.getId()) { + case 15653: + case 1530: + if (node.getId() == 1530 && !node.getLocation().equals(new Location(2837, 3549, 0))) { + DoorActionHandler.handleDoor(player, (Scenery) node); + return true; + } + if (canEnter(player)) { + player.getMusicPlayer().unlock(634); + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + } else { + player.getDialogueInterpreter().sendDialogues(4285, null, "You not pass. You too weedy."); + } + break; + + default: + switch (option) { + case "claim-shield": + player.getDialogueInterpreter().open(4287, node, true); + break; + case "claim-tokens": + player.getDialogueInterpreter().open("wg:claim-tokens", node.getId()); + break; + } + break; + } + return true; + } + + /** + * Checks if a player can enter the guild. + * @param player the player. + * @return {@code True} if so. + */ + private boolean canEnter(final Player player) { + return player.getSkills().getStaticLevel(Skills.ATTACK) + player.getSkills().getStaticLevel(Skills.STRENGTH) >= 130 || player.getSkills().getStaticLevel(Skills.ATTACK) == 99 || player.getSkills().getStaticLevel(Skills.STRENGTH) == 99; + } + + /** + * The dialogue used to handle the claiming of tokens. + * @author 'Vexia + * @version 1.0 + */ + public static final class ClaimTokenDialogue extends DialoguePlugin { + + /** + * The npc id being used. + */ + private int npcId; + + /** + * Constructs a new {@code ClaimTokenDialogue} {@code Object}. + */ + public ClaimTokenDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code ClaimTokenDialogue} {@code Object}. + * @param player the player. + */ + public ClaimTokenDialogue(final Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new ClaimTokenDialogue(player); + } + + @Override + public boolean open(Object... args) { + npcId = (Integer) args[0]; + player("May I claim my tokens please?"); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + int tokens = player.getSavedData().getActivityData().getWarriorGuildTokens(); + switch (stage) { + case 0: + if (tokens < 1) { + interpreter.sendDialogues(npcId, null, "I'm afraid you have not earned any tokens yet. Try", "some of the activities around the guild to earn some."); + stage = 3; + } else { + interpreter.sendDialogues(npcId, null, "Of course! Here you go, you've earned " + tokens + " tokens!"); + stage++; + } + break; + case 1: + final Item item = new Item(TOKEN, tokens); + if (!player.getInventory().hasSpaceFor(item)) { + player("Sorry, I don't seem to have enough inventory space."); + stage++; + break; + } + player.getSavedData().getActivityData().setWarriorGuildTokens(0); + player.getInventory().add(item); + player("Thanks!"); + stage++; + break; + case 2: + end(); + break; + case 3: + player("Ok, I'll go see what I can find."); + stage--; + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { DialogueInterpreter.getDialogueKey("wg:claim-tokens") }; + } + + } +} diff --git a/Server/src/main/content/region/asgarnia/burthorpe/handlers/wguild/animator/AnimatedArmour.java b/Server/src/main/content/region/asgarnia/burthorpe/handlers/wguild/animator/AnimatedArmour.java new file mode 100644 index 0000000..dd37999 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/handlers/wguild/animator/AnimatedArmour.java @@ -0,0 +1,124 @@ +package content.region.asgarnia.burthorpe.handlers.wguild.animator; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.HintIconManager; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.world.map.Location; +import core.game.world.map.path.Pathfinder; +import core.game.world.update.flag.context.Animation; +import core.tools.RandomFunction; + +/** + * Represents an animated armour. + * @author Emperor + */ +public final class AnimatedArmour extends NPC { + + /** + * The player. + */ + private final Player player; + + /** + * The armour set. + */ + private final AnimationRoom.ArmourSet set; + + /** + * If the set is running. + */ + private boolean running; + + /** + * Constructs a new {@code AnimatedArmour} {@code Object}. + * @param player The player. + * @param location The location to spawn. + * @param set The armour set. + */ + protected AnimatedArmour(Player player, Location location, AnimationRoom.ArmourSet set) { + super(set.getNpcId(), location); + this.player = player; + this.set = set; + } + + @Override + public void init() { + super.init(); + animate(Animation.create(4166)); + sendChat("I'M ALIVE!"); + getProperties().getCombatPulse().attack(player); + HintIconManager.registerHintIcon(player, this); + } + + @Override + public void clear() { + super.clear(); + player.getHintIconManager().clear(); + } + + @Override + public void handleTickActions() { + if (!running && !getProperties().getCombatPulse().isAttacking()) { + getProperties().getCombatPulse().attack(player); + } + } + + @Override + public void onImpact(final Entity entity, BattleState state) { + if (!running) { + if (getSkills().getLifepoints() < (getSkills().getMaximumLifepoints() / 10) && RandomFunction.randomize(10) < 2) { + running = true; + getProperties().getCombatPulse().stop(); + Pathfinder.find(location, Location.create(2849, 3534, 0)).walk(this); + return; + } + super.onImpact(entity, state); + } + } + + @Override + public boolean isAttackable(Entity entity, CombatStyle style, boolean message) { + if (entity != player) { + if (entity instanceof Player) { + ((Player) entity).getPacketDispatch().sendMessage("This isn't your armour to attack."); + } + return false; + } + return super.isAttackable(entity, style, message); + } + + @Override + public void finalizeDeath(Entity killer) { + clear(); + if (killer != null) { + boolean takenPiece = false; + boolean canTake = RandomFunction.random(180) == 1; + int index = 0; + int takeIndex = 0; + if (canTake) { + takeIndex = RandomFunction.random(set.getPieces().length); + } + for (int piece : set.getPieces()) { + if (canTake && !takenPiece && index == takeIndex) { + takenPiece = true; + player.getPacketDispatch().sendMessage("Your armour was destroyed in the fight."); + continue; + } + GroundItemManager.create(new Item(piece), location, player); + index++; + } + if (killer != null) { // Indicates the player actually killed the + // armour. + int amount = set.getTokenAmount(); + GroundItemManager.create(new Item(8851, amount), location, player); + } + player.logoutListeners.remove("animation-room"); + player.removeAttribute("animated_set"); + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/handlers/wguild/animator/AnimationRoom.java b/Server/src/main/content/region/asgarnia/burthorpe/handlers/wguild/animator/AnimationRoom.java new file mode 100644 index 0000000..746fd93 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/handlers/wguild/animator/AnimationRoom.java @@ -0,0 +1,214 @@ +package content.region.asgarnia.burthorpe.handlers.wguild.animator; + +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.Entity; +import core.game.node.entity.impl.ForceMovement; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.system.task.Pulse; +import kotlin.Unit; +import core.game.world.GameWorld; +import core.game.world.map.Direction; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneBuilder; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playAudio; + +/** + * Handles the animation + * @author Emperor + */ +@Initializable +public final class AnimationRoom extends MapZone implements Plugin { + + /** + * Represents an armour set to be used on the animator. + * @author Emperor + */ + static enum ArmourSet { + BRONZE(4278, 5, 1155, 1117, 1075), IRON(4279, 10, 1153, 1115, 1067), STEEL(4280, 15, 1157, 1119, 1069), BLACK(4281, 20, 1165, 1125, 1077), MITHRIL(4282, 25, 1159, 1121, 1071), ADAMANT(4283, 30, 1161, 1123, 1073), RUNE(4284, 40, 1163, 1127, 1079); + + /** + * The NPC id. + */ + private final int npcId; + + /** + * The amount of tokens to add. + */ + private final int tokenAmount; + + /** + * The pieces. + */ + private final int[] pieces; + + /** + * Constructs a new {@code ArmourSet} {@code Object}. + * @param npcId The NPC id. + * @param pieces The pieces. + */ + private ArmourSet(int npcId, int tokenAmount, int... pieces) { + this.npcId = npcId; + this.tokenAmount = tokenAmount; + this.pieces = pieces; + } + + /** + * Gets the npcId. + * @return The npcId. + */ + public int getNpcId() { + return npcId; + } + + /** + * Gets the tokenAmount. + * @return The tokenAmount. + */ + public int getTokenAmount() { + return tokenAmount; + } + + /** + * Gets the pieces. + * @return The pieces. + */ + public int[] getPieces() { + return pieces; + } + + } + + /** + * Constructs a new {@code AnimationRoom} {@code Object}. + */ + public AnimationRoom() { + super("wg animation", true); + } + + @Override + public boolean leave(Entity e, boolean logout) { + if (e instanceof Player) { + NPC npc = e.getAttribute("animated_set"); + if (npc != null && npc.isActive()) { + npc.finalizeDeath(null); + } + } + return true; + } + + /** + * Animates the armour set. + * @param player The player. + * @param object The animator. + * @param set The set to animate. + */ + private void animateArmour(final Player player, final Scenery object, final ArmourSet set) { + if (!player.getInventory().containItems(set.getPieces())) { + player.getDialogueInterpreter().sendDialogue("You need a plate body, plate legs and full helm of the same type to", "activate the armour animator."); + return; + } + if (player.getAttribute("animated_set") != null) { + player.getPacketDispatch().sendMessage("You already have a set animated."); + return; + } + player.lock(10); + player.animate(Animation.create(827)); + player.getDialogueInterpreter().sendPlainMessage(true, "You place your armour on the platform where it", "disappears..."); + GameWorld.getPulser().submit(new Pulse(5, player) { + boolean spawn; + + @Override + public boolean pulse() { + if (!spawn) { + for (int id : set.getPieces()) { + if (!player.getInventory().remove(new Item(id))) { + return true; + } + } + playAudio(player, Sounds.WARGUILD_ANIMATE_1909); + player.logoutListeners.put("animation-room", player1 -> { + for(int item : set.getPieces()) player1.getInventory().add(new Item(item)); + return Unit.INSTANCE; + }); + player.getDialogueInterpreter().sendPlainMessage(true, "The animator hums, something appears to be working.", "You stand back..."); + spawn = true; + super.setDelay(4); + return false; + } + if (getDelay() == 4) { + setDelay(1); + playAudio(player, Sounds.WARGUILD_ANIMATOR_ACTIVATE_1910); + ForceMovement.run(player, player.getLocation().transform(0, 1, 0)).setDirection(Direction.SOUTH); + return false; + } + player.getInterfaceManager().closeChatbox(); + NPC npc = new AnimatedArmour(player, object.getLocation(), set); + player.setAttribute("animated_set", npc); + npc.init(); + return true; + } + }); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + int[] ids = new int[ArmourSet.values().length * 3]; + int index = 0; + for (ArmourSet set : ArmourSet.values()) { + for (int id : set.getPieces()) { + ids[index++] = id; + } + } + UseWithHandler.addHandler(15621, UseWithHandler.OBJECT_TYPE, new UseWithHandler(ids) { + + @Override + public boolean handle(NodeUsageEvent event) { + Item item = event.getUsedItem(); + ArmourSet set = null; + roar: { + for (ArmourSet s : ArmourSet.values()) { + for (int id : s.getPieces()) { + if (id == item.getId()) { + set = s; + break roar; + } + } + } + } + if(set != null) { + animateArmour(event.getPlayer(), (Scenery) event.getUsedWith(), set); + } + return true; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + return this; + } + + }); + ZoneBuilder.configure(this); + return this; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public void configure() { + super.register(new ZoneBorders(2849, 3534, 2861, 3545)); + } + +} diff --git a/Server/src/main/content/region/asgarnia/burthorpe/handlers/wguild/barrel/BarrelRoom.java b/Server/src/main/content/region/asgarnia/burthorpe/handlers/wguild/barrel/BarrelRoom.java new file mode 100644 index 0000000..e01b9b6 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/handlers/wguild/barrel/BarrelRoom.java @@ -0,0 +1,180 @@ +package content.region.asgarnia.burthorpe.handlers.wguild.barrel; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import core.cache.def.impl.SceneryDefinition; +import core.game.container.impl.EquipmentContainer; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.ImpactHandler.HitsplatType; +import core.game.node.entity.lock.Lock; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneBuilder; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.plugin.ClassScanner; +import core.tools.RandomFunction; + +import static core.api.ContentAPIKt.*; + +/** + * Handles the Barrel room. + * @author Emperor + */ +@Initializable +public final class BarrelRoom extends MapZone implements Plugin { + + /** + * The players list. + */ + private static List players = new ArrayList<>(20); + + /** + * The pulse. + */ + private static Pulse pulse = new Pulse(5) { + @Override + public boolean pulse() { + if (players.isEmpty()) { + return true; + } + for (Iterator it = players.iterator(); it.hasNext();) { + Player player = it.next(); + player.getSettings().updateRunEnergy(5); + if (player.getLocks().isMovementLocked()) { + continue; + } + int barrels = (player.getAttribute("barrel_count", 8860) - 8859); + int chance = (int) (player.getSettings().getRunEnergy() - (5 * barrels)); + if (RandomFunction.randomize(100) > chance) { + removeBarrels(player); + player.sendChat("Ouch!"); + player.getPacketDispatch().sendMessage("Some of the barrels hit you on their way to the floor."); + player.getImpactHandler().manualHit(player, 1, HitsplatType.NORMAL); + player.visualize(Animation.create(4177), Graphics.create(689 - barrels)); + it.remove(); + continue; + } + player.getSavedData().getActivityData().updateWarriorTokens(barrels); + } + return false; + } + }; + + /** + * Constructs a new {@code BarrelRoom} {@code Object}. + */ + public BarrelRoom() { + super("wg barrel", true); + } + + @Override + public void configure() { + super.register(new ZoneBorders(2861, 3536, 2876, 3543)); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ZoneBuilder.configure(this); + pulse.stop(); + ClassScanner.definePlugin(new OptionHandler() { + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(15668).getHandlers().put("option:pick-up", this); + return this; + } + + @Override + public boolean handle(final Player player, final Node node, String option) { + if (player.getSettings().getRunEnergy() < 5) { + player.getDialogueInterpreter().sendDialogue("You're too exhausted to continue. Take a break."); + return true; + } + int helmId = player.getEquipment().getNew(EquipmentContainer.SLOT_HAT).getId(); + int currentBarrel = player.getAttribute("barrel_count", 0); + if (player.getEquipment().get(EquipmentContainer.SLOT_WEAPON) != null || player.getEquipment().get(EquipmentContainer.SLOT_SHIELD) != null || player.getEquipment().get(EquipmentContainer.SLOT_HANDS) != null || helmId != currentBarrel) { + player.getDialogueInterpreter().sendDialogue("To balance kegs you will need your head and hands free!"); + return true; + } + int id = currentBarrel + 1; + if (id < 8860) { + id = 8860; + } else if (id > 8864) { + id = 8864; + } + final int barrelId = id; + player.lock(5); + player.animate(Animation.create(4180)); + Lock lock = new Lock("You're too busy balancing barrels to do that!"); + lock.lock(); + player.getLocks().setEquipmentLock(lock); + player.getPacketDispatch().sendMessage("You pick up the keg and balance it on your head carefully."); + GameWorld.getPulser().submit(new Pulse(3, player) { + @Override + public boolean pulse() { + player.getEquipment().replace(new Item(barrelId), EquipmentContainer.SLOT_HAT); + player.getAppearance().setAnimations(Animation.create(4178)); + player.getAppearance().setStandAnimation(4179); + player.getAppearance().sync(); + player.setAttribute("barrel_count", barrelId); + ((Scenery) node).setChildIndex(player, 1); + if (!players.contains(player)) { + player.getWalkingQueue().setRunDisabled(true); + players.add(player); + if (!pulse.isRunning()) { + pulse.restart(); + pulse.start(); + GameWorld.getPulser().submit(pulse); + } + } + return true; + } + }); + return true; + } + }); + return this; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public boolean leave(Entity e, boolean logout) { + if (e instanceof Player && e.getAttribute("barrel_count", 0) > 0) { + players.remove(e); + removeBarrels((Player) e); + } + return super.leave(e, logout); + } + + /** + * Removes the barrels from the player's head. + * @param player The player. + */ + private static void removeBarrels(Player player) { + if (player.getLocks().getEquipmentLock() != null) { + player.getLocks().getEquipmentLock().unlock(); + } + player.removeAttribute("barrel_count"); + player.getWalkingQueue().setRunDisabled(false); + player.getEquipment().replace(null, EquipmentContainer.SLOT_HAT); + player.getAppearance().setAnimations(); + player.getAppearance().sync(); + setVarp(player, 793, 0); + } + +} diff --git a/Server/src/main/content/region/asgarnia/burthorpe/handlers/wguild/catapult/CatapultRoom.java b/Server/src/main/content/region/asgarnia/burthorpe/handlers/wguild/catapult/CatapultRoom.java new file mode 100644 index 0000000..a5ae501 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/handlers/wguild/catapult/CatapultRoom.java @@ -0,0 +1,275 @@ +package content.region.asgarnia.burthorpe.handlers.wguild.catapult; + +import java.util.ArrayList; +import java.util.List; + +import core.cache.def.impl.ItemDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.container.impl.EquipmentContainer; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.skill.Skills; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.ImpactHandler.HitsplatType; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.audio.Audio; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneBuilder; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; +import core.plugin.ClassScanner; +import core.plugin.Initializable; +import core.tools.RandomFunction; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playAudio; +import static core.api.ContentAPIKt.setVarp; + +/** + * The catapult room. + * @author Emperor + */ +@Initializable +public final class CatapultRoom extends MapZone implements Plugin { + + /** + * The target location. + */ + public static final Location TARGET = Location.create(2842, 3545, 1); + + /** + * The shield item id. + */ + private static final int SHIELD_ID = 8856; + + /** + * Represents a catapult attack. + * @author Emperor + */ + private static enum CatapultAttack { + SPIKY_BALL(679, 15617, Animation.create(4169), Animation.create(4173)), FLUNG_ANVIL(680, 15619, Animation.create(4168), Animation.create(4172)), SLASHING_BLADES(681, 15620, Animation.create(4170), Animation.create(4174)), MAGIC_MISSILE(682, 15618, Animation.create(4171), Animation.create(4175)); + + /** + * The graphic id. + */ + private final int graphicId; + + /** + * The attack name. + */ + private final String name; + + /** + * The object id to replace with. + */ + private final int objectId; + + /** + * The successful animation. + */ + private final Animation success; + + /** + * The animation when failing to defend. + */ + private final Animation fail; + + /** + * Constructs a new {@code CatapultAttack} {@code Object}. + * @param graphicId The graphic id. + * @param success The success animation. + * @param fail The fail animation. + */ + private CatapultAttack(int graphicId, int objectId, Animation success, Animation fail) { + this.graphicId = graphicId; + this.name = name().toLowerCase().replace("_", " "); + this.objectId = objectId; + this.success = success; + this.fail = fail; + } + } + + /** + * The players in the catapult room. + */ + private static List players = new ArrayList<>(20); + + /** + * The current attack. + */ + private static CatapultAttack attack; + + /** + * The pulse. + */ + private static Pulse pulse = new Pulse(10) { + @Override + public boolean pulse() { + attack = RandomFunction.getRandomElement(CatapultAttack.values()); + GameWorld.getPulser().submit(new Pulse(7) { + @Override + public boolean pulse() { + for (Player p : players) { + if (p.isActive() && p.getLocation().equals(TARGET)) { + if (p.getEquipment().getNew(EquipmentContainer.SLOT_SHIELD).getId() != SHIELD_ID) { + p.getDialogueInterpreter().sendDialogues(4287, FacialExpression.FURIOUS, "Watch out! You'll need to equip the shield as soon as", "you're on the target spot else you could get hit! Speak", "to me to get one, and make sure both your hands are", "free to equip it."); + p.getWalkingQueue().reset(); + p.getWalkingQueue().addPath(p.getLocation().getX() + 1, p.getLocation().getY()); + continue; + } + p.faceLocation(Location.create(2842, 3554, 1)); + if (p.getAttribute("catapult_def", CatapultAttack.MAGIC_MISSILE) != attack) { + p.getPacketDispatch().sendMessage("You fail defending against the " + attack.name + "."); + p.getImpactHandler().manualHit(p, 3, HitsplatType.NORMAL); + p.animate(attack.fail); + } else { + p.getSkills().addExperience(Skills.DEFENCE, 10.0, true); + p.getPacketDispatch().sendMessage("You successfully defend against the " + attack.name + "."); + p.getSavedData().getActivityData().updateWarriorTokens(1); + p.animate(attack.success); + } + } + } + return true; + } + }); + Projectile.create(Location.create(2842, 3554, 1), Location.create(2842, 3545, 1), attack.graphicId, 70, 32, 80, 220, 20, 11).send(); + Scenery object = RegionManager.getObject(Location.create(2840, 3552, 1)); + if(object != null) + SceneryBuilder.replace(object, object.transform(attack.objectId), 4); + for (Player p : players) { + playAudio(p, Sounds.WARGUILD_CATAPULT_ANVIL_1911); + } + return players.isEmpty(); + } + }; + + /** + * Constructs a new {@code CatapultRoom} {@code Object}. + */ + public CatapultRoom() { + super("wg catapult", true); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ZoneBuilder.configure(this); + ClassScanner.definePlugin(new OptionHandler() { + @Override + public Plugin newInstance(Object arg) throws Throwable { + ItemDefinition.forId(SHIELD_ID).getHandlers().put("option:wield", this); + SceneryDefinition.forId(15657).getHandlers().put("option:view", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + if (node instanceof Item) { + if (!player.getLocation().equals(TARGET)) { + player.getPacketDispatch().sendMessage("You may not equip this shield outside the target area in the Warrior's Guild."); + return true; + } + if (player.getEquipment().get(EquipmentContainer.SLOT_WEAPON) != null) { + player.getDialogueInterpreter().sendDialogue("You will need to make sure your sword hand is free to equip this", "shield."); + return true; + } + ItemDefinition.getOptionHandlers().get("wield").handle(player, node, option); + if (player.getEquipment().getNew(EquipmentContainer.SLOT_SHIELD).getId() == SHIELD_ID) { + player.getInterfaceManager().removeTabs(2, 3, 5, 6, 7, 11, 12); + player.getInterfaceManager().openTab(4, new Component(411)); + player.getInterfaceManager().setViewedTab(4); + } + return true; + } + player.getInterfaceManager().open(new Component(410)); + return true; + } + }); + ClassScanner.definePlugin(new ComponentPlugin() { + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.put(411, this); + return this; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + if (button >= 9 && button <= 12) { + CatapultAttack attack = CatapultAttack.values()[button - 9]; + player.setAttribute("catapult_def", attack); + setVarp(player, 788, (button - 8) % 4); + return true; + } + return false; + } + + }); + return this; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public void configure() { + super.register(new ZoneBorders(2837, 3542, 2847, 3556)); + pulse.stop(); + } + + @Override + public boolean enter(Entity e) { + if (e instanceof Player && e.getLocation().getZ() == 1) { + players.add((Player) e); + if (!pulse.isRunning()) { + pulse.restart(); + pulse.start(); + GameWorld.getPulser().submit(pulse); + } + } + return super.enter(e); + } + + @Override + public boolean leave(Entity e, boolean logout) { + if (e instanceof Player) { + players.remove(e); + unequipShield((Player) e); + } + return super.leave(e, logout); + } + + @Override + public void locationUpdate(Entity e, Location last) { + if (e instanceof Player && last.equals(TARGET)) { + unequipShield((Player) e); + } + } + + /** + * Unequips the shield. + * @param player The player. + */ + private static void unequipShield(Player player) { + if (player.getEquipment().getNew(EquipmentContainer.SLOT_SHIELD).getId() == SHIELD_ID) { + player.getInventory().add(new Item(SHIELD_ID), player); + player.getEquipment().replace(null, EquipmentContainer.SLOT_SHIELD); + player.getInterfaceManager().restoreTabs(); + player.getInterfaceManager().openTab(4, new Component(387)); + } + } +} diff --git a/Server/src/main/content/region/asgarnia/burthorpe/handlers/wguild/cyclopes/CyclopesRoom.java b/Server/src/main/content/region/asgarnia/burthorpe/handlers/wguild/cyclopes/CyclopesRoom.java new file mode 100644 index 0000000..98111f7 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/handlers/wguild/cyclopes/CyclopesRoom.java @@ -0,0 +1,297 @@ +package content.region.asgarnia.burthorpe.handlers.wguild.cyclopes; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import core.cache.def.impl.SceneryDefinition; +import core.game.container.impl.EquipmentContainer; +import core.plugin.Initializable; +import core.game.dialogue.DialogueInterpreter; +import core.game.dialogue.DialoguePlugin; +import core.game.global.action.DoorActionHandler; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.map.path.Pathfinder; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneBuilder; +import core.game.world.map.zone.ZoneRestriction; +import core.plugin.Plugin; +import core.plugin.ClassScanner; +import core.tools.RandomFunction; +import kotlin.Unit; +import kotlin.jvm.functions.Function1; + +import static core.api.ContentAPIKt.clearLogoutListener; +import static core.api.ContentAPIKt.registerLogoutListener; + +/** + * The cyclopes room. + * @author Emperor + */ +@Initializable +public final class CyclopesRoom extends MapZone implements Plugin { + + /** + * The defenders. + */ + private static final int[] DEFENDERS = { 8844, 8845, 8846, 8847, 8848, 8849, 8850}; + + /** + * The players in the room. + */ + private static final List PLAYERS = new ArrayList<>(20); + + /** + * The pulse. + */ + private static final Pulse PULSE = new Pulse(5) { + @Override + public boolean pulse() { + if (PLAYERS.isEmpty()) { + return true; + } + for (Iterator it = PLAYERS.iterator(); it.hasNext();) { + Player p = it.next(); + int current = p.getAttribute("cyclops_ticks", 0) + 5; + if (current % 100 == 0) { + Item tokens = new Item(8851, 10); + if (!p.getInventory().containsItem(tokens)) { + if (!p.getLocks().isMovementLocked()) { + p.getPulseManager().clear(); + Pathfinder.find(p.getLocation(), Location.create(2847, 3541, 2)).walk(p); + p.lock(50); + } else { + Scenery object = RegionManager.getObject(2, 2847, 3541); + if (object != null && p.getLocation().getX() == 2847 && p.getLocation().getY() == 3541) { + DoorActionHandler.handleAutowalkDoor(p, object); + leave(p); + p.unlock(); + p.lock(3); + it.remove(); + } + } + continue; + } + p.getInventory().remove(tokens); + p.getPacketDispatch().sendMessage("10 of your tokens crumble away."); + } + p.setAttribute("cyclops_ticks", current); + } + return false; + } + }; + + /** + * Constructs a new {@code CyclopesRoom} {@code Object}. + */ + public CyclopesRoom() { + super("wg cyclopes", true, ZoneRestriction.RANDOM_EVENTS); + } + + @Override + public boolean leave(Entity e, boolean logout) { + if (e instanceof Player) { + leave((Player) e); + PLAYERS.remove(e); + if (logout) { + e.setLocation(Location.create(2846, 3540, 2)); + } + clearLogoutListener((Player) e, "cyclopes"); + } + return super.leave(e, logout); + } + + @Override + public boolean death(Entity e, Entity killer) { + if (killer instanceof Player && e instanceof NPC && (e.getId() == 4292 || e.getId() == 4291)) { + int defenderId = getDefenderIndex((Player) killer); + if (RandomFunction.randomize(50) == 10) { + if (++defenderId == DEFENDERS.length) { + defenderId--; + } + GroundItemManager.create(new Item(DEFENDERS[defenderId]), e.getLocation(), (Player) killer); + } + } + return false; + } + + @Override + public void configure() { + super.register(new ZoneBorders(2838, 3534, 2876, 3556, 2)); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ZoneBuilder.configure(this); + PULSE.stop(); + ClassScanner.definePlugin(new KamfreenaDial()); + ClassScanner.definePlugin(new OptionHandler() { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(15641).getHandlers().put("option:open", this); + SceneryDefinition.forId(15644).getHandlers().put("option:open", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + if (player.getLocation().getX() <= 2846) { + Item tokens = new Item(8851, 100); + Item tokens10 = new Item(8851, 10); + if (!player.getInventory().containsItem(tokens)) { + player.getDialogueInterpreter().sendItemMessage(tokens, "You don't have enough Warrior Guild Tokens to enter", "the cyclopes enclosure yet, collect at least 100 then", "come back."); + return true; + } + if (!player.getAttribute("sent_dialogue", false)) { + player.getDialogueInterpreter().open(DialogueInterpreter.getDialogueKey("defender entry"), getDefenderIndex(player)); + return true; + } + player.removeAttribute("sent_dialogue"); + player.getInventory().remove(tokens10); + player.sendMessages("10 tokens are taken as you enter the room."); + enter(player); + } else { + leave(player); + PLAYERS.remove(player); + } + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + return true; + } + + }); + return this; + } + + /** + * Gets the current defender index. + * @param player The player. + * @return The defender index. + */ + private static int getDefenderIndex(Player player) { + int index = -1; + for (int i = DEFENDERS.length - 1; i >= 0; i--) { + int id = DEFENDERS[i]; + if (player.getEquipment().getNew(EquipmentContainer.SLOT_SHIELD).getId() == id || player.getInventory().contains(id, 1)) { + index = i; + break; + } + } + return index; + } + + /** + * Enters the cyclopes room. + * @param player The player. + */ + private static void enter(Player player) { + if (!PLAYERS.contains(player)) { + PLAYERS.add(player); + } + if (!PULSE.isRunning()) { + PULSE.restart(); + PULSE.start(); + GameWorld.getPulser().submit(PULSE); + } + registerLogoutListener(player, "cyclopes", player1 -> { + player1.setLocation(Location.create(2844, 3540, 2)); + return Unit.INSTANCE; + }); + } + + /** + * Leaves the room. + * @param player The player. + */ + private static void leave(Player player) { + player.removeAttribute("cyclops_ticks"); + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + /** + * The Kamfreena entrance dialogue. + * @author Emperor + */ + private static class KamfreenaDial extends DialoguePlugin { + + /** + * The current defender item id. + */ + private int defenderId; + + /** + * Constructs a new {@code KamfreenaDial} {@code Object}. + */ + public KamfreenaDial() { + super(); + } + + /** + * Constructs a new {@code KamfreenaDial} {@code Object}. + * @param player The player. + */ + public KamfreenaDial(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new KamfreenaDial(player); + } + + @Override + public boolean open(Object... args) { + defenderId = (Integer) args[0]; + if (defenderId == -1) { + npc(4289, "Well, since you haven't shown me a defender to prove", "your prowess as a warrior,"); + } else { + npc(4289, "Ahh I see that you have one of the defenders already!", "Well done."); + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + player.setAttribute("sent_dialogue", true); + if (defenderId == DEFENDERS.length - 1) { + npc(4289, "I'll release some cyclopes which might drop the same", "rune defender for you as there isn't any higher! Have", "fun in there."); + } else if (defenderId == -1) { + npc(4289, "I'll release some cyclopes which might drop bronze", "defenders for you to start off with, unless you show me", "another. Have fun in there."); + } else { + npc(4289, "I'll release some cyclopes which might drop the next", "defender for you. Have fun in there."); + } + stage = 1; + break; + case 1: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { DialogueInterpreter.getDialogueKey("defender entry") }; + } + + } + +} diff --git a/Server/src/main/content/region/asgarnia/burthorpe/handlers/wguild/dummy/DummyRoom.java b/Server/src/main/content/region/asgarnia/burthorpe/handlers/wguild/dummy/DummyRoom.java new file mode 100644 index 0000000..bc1ad6f --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/handlers/wguild/dummy/DummyRoom.java @@ -0,0 +1,168 @@ +package content.region.asgarnia.burthorpe.handlers.wguild.dummy; + +import core.cache.def.impl.SceneryDefinition; +import core.game.component.Component; +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.chunk.AnimateObjectUpdateFlag; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Plugin; +import core.tools.RandomFunction; + +/** + * Handles the dummy room. + * @author Emperor + */ +@Initializable +public final class DummyRoom extends OptionHandler { + + /** + * Represents a dummy. + * @author Emperor + */ + private static enum Dummy { + STAB(new Scenery(15629, 2857, 3549, 0, 10, 2), -1, WeaponInterface.BONUS_STAB), SLASH(new Scenery(15625, 2858, 3554, 0), -1, WeaponInterface.BONUS_SLASH), CRUSH(new Scenery(15628, 2859, 3549, 0, 10, 2), -1, WeaponInterface.BONUS_CRUSH), CONTROLLED(new Scenery(15627, 2855, 3552, 0, 10, 3), WeaponInterface.STYLE_CONTROLLED, -1), DEFENCE(new Scenery(15630, 2855, 3550, 0, 10, 3), WeaponInterface.STYLE_DEFENSIVE, -1), AGGRESSIVE(new Scenery(15626, 2860, 3553, 0, 10, 1), WeaponInterface.STYLE_AGGRESSIVE, -1), ACCURATE(new Scenery(15624, 2856, 3554, 0), WeaponInterface.STYLE_ACCURATE, -1), ; + + /** + * The object. + */ + private final Scenery object; + + /** + * The attack style to be used on this dummy. + */ + private final int attackStyle; + + /** + * The bonus type to be used on this dummy. + */ + private final int bonusType; + + /** + * Constructs a new {@code Dummy} {@code Object}. + * @param object The object. + * @param attackStyle The attack style. + */ + private Dummy(Scenery object, int attackStyle, int bonusType) { + this.object = object; + this.attackStyle = attackStyle; + this.bonusType = bonusType; + } + + /** + * Gets the object. + * @return The object. + */ + public Scenery getObject() { + return object; + } + + /** + * Gets the attackStyle. + * @return The attackStyle. + */ + public int getAttackStyle() { + return attackStyle; + } + + /** + * Gets the bonusType. + * @return The bonusType. + */ + public int getBonusType() { + return bonusType; + } + } + + /** + * The current dummy. + */ + private static Dummy dummy; + + /** + * The time stamp. + */ + private static int timeStamp; + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(15656).getHandlers().put("option:view", this); + for (Dummy dummy : Dummy.values()) { + SceneryDefinition.forId(dummy.getObject().getId()).getHandlers().put("option:hit", this); + } + GameWorld.getPulser().submit(new Pulse(10) { + boolean activeDummy; + Scenery controlled; + + @Override + public boolean pulse() { + if (!activeDummy) { + setDelay(10); + timeStamp = GameWorld.getTicks(); + dummy = RandomFunction.getRandomElement(Dummy.values()); + SceneryBuilder.replace(RegionManager.getObject(dummy.getObject().getLocation()), dummy.getObject(), 11); + activeDummy = true; + if (dummy == Dummy.CONTROLLED && controlled == null) { + Location l = Location.create(2860, 3551, 0); + controlled = new Scenery(dummy.getObject().getId(), l, 10, 1); + SceneryBuilder.replace(RegionManager.getObject(l), controlled, 11); + } + return false; + } + setDelay(4); + Animation animation = Animation.create(4164); + animation.setObject(dummy.getObject()); + RegionManager.getRegionChunk(dummy.getObject().getLocation()).flag(new AnimateObjectUpdateFlag(animation)); + activeDummy = false; + if (controlled != null) { + animation = Animation.create(4164); + animation.setObject(controlled); + RegionManager.getRegionChunk(controlled.getLocation()).flag(new AnimateObjectUpdateFlag(animation)); + controlled = null; + } + return false; + } + }); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + Scenery object = (Scenery) node; + if (object.getId() == 15656) { + player.getInterfaceManager().open(new Component(412)); + return true; + } + if (object.getId() == dummy.getObject().getId()) { + if (timeStamp == player.getAttribute("dummy_ts", -1)) { + player.getPacketDispatch().sendMessage("You have already hit a dummy this turn."); + return true; + } + if (player.getProperties().getAttackStyle().getStyle() != dummy.getAttackStyle() && player.getProperties().getAttackStyle().getBonusType() != dummy.getBonusType()) { + player.lock(5); + player.visualize(player.getProperties().getAttackAnimation(), new Graphics(80, 96)); + player.getPacketDispatch().sendMessage("You whack the dummy with the wrong attack style."); + } else { + player.getSkills().addExperience(Skills.ATTACK, 15.0, true); + player.animate(player.getProperties().getAttackAnimation()); + player.getPacketDispatch().sendMessage("You whack the dummy successfully!"); + player.setAttribute("dummy_ts", timeStamp); + player.getSavedData().getActivityData().updateWarriorTokens(2); + } + return true; + } + return false; + } + +} diff --git a/Server/src/main/content/region/asgarnia/burthorpe/handlers/wguild/shot/DustHandListener.kt b/Server/src/main/content/region/asgarnia/burthorpe/handlers/wguild/shot/DustHandListener.kt new file mode 100644 index 0000000..297c29e --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/handlers/wguild/shot/DustHandListener.kt @@ -0,0 +1,27 @@ +package content.region.asgarnia.burthorpe.handlers.wguild.shot + +import core.api.MapArea +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.item.Item +import core.game.world.map.Location +import org.rs09.consts.Items + +/** For ShotPutRoom */ +class DustHandListeners : InteractionListener { + override fun defineListeners() { + on(Items.GROUND_ASHES_8865, IntType.ITEM, "dust-hands") { player, node -> + // Check that player is in the shotput throwing areas. + if (!(player.location.withinDistance(Location(2861, 3553, 1), 1) || + player.location.withinDistance(Location(2861, 3547, 1), 1))) { + player.packetDispatch.sendMessage("You may only dust your hands while in the shotput throwing areas.") + return@on true + } + if (player.inventory.remove(node as Item)) { + player.packetDispatch.sendMessage("You dust your hands with the finely ground ash.") + player.setAttribute("hand_dust", true) + } + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/handlers/wguild/shot/ShotPutRoom.java b/Server/src/main/content/region/asgarnia/burthorpe/handlers/wguild/shot/ShotPutRoom.java new file mode 100644 index 0000000..7e075e3 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/handlers/wguild/shot/ShotPutRoom.java @@ -0,0 +1,198 @@ +package content.region.asgarnia.burthorpe.handlers.wguild.shot; + +import core.cache.def.impl.ItemDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.game.container.impl.EquipmentContainer; +import core.plugin.Initializable; +import core.game.dialogue.DialogueInterpreter; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.skill.Skills; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.combat.ImpactHandler.HitsplatType; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItem; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; +import core.plugin.ClassScanner; +import core.tools.RandomFunction; + +/** + * Handles the shot put room. + * @author Emperor + */ +@Initializable +public final class ShotPutRoom extends DialoguePlugin { + + static { + ClassScanner.definePlugin(new OptionHandler() { + + @Override + public boolean handle(final Player player, Node node, String option) { + final boolean lowWeight = node.getId() == 15664; + if (node instanceof GroundItem) { + player.getDialogueInterpreter().sendDialogues(4300, FacialExpression.FURIOUS, "Hey! You can't take that, it's guild property. Take one", "from the pile."); + return true; + } + if (player.getEquipment().get(EquipmentContainer.SLOT_WEAPON) != null || player.getEquipment().get(EquipmentContainer.SLOT_SHIELD) != null || player.getEquipment().get(EquipmentContainer.SLOT_HANDS) != null) { + player.getDialogueInterpreter().sendDialogue("To throw the shot you need your hands free!"); + return true; + } + if (player.getSettings().getRunEnergy() < 10) { + player.getDialogueInterpreter().sendDialogue("You're too exhausted to throw the shot at this time. Take a break."); + return true; + } + player.lock(4); + player.animate(Animation.create(827)); + GameWorld.getPulser().submit(new Pulse(2) { + @Override + public boolean pulse() { + player.faceLocation(player.getLocation().transform(3, 0, 0)); + player.getDialogueInterpreter().open("shot_put", lowWeight); + return true; + } + }); + return true; + } + + @Override + public Location getDestination(Node n, Node node) { + if (node instanceof Scenery) { + return node.getLocation().transform(0, -1, 0); + } + return null; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(15664).getHandlers().put("option:throw", this); + SceneryDefinition.forId(15665).getHandlers().put("option:throw", this); + ItemDefinition.forId(8858).getHandlers().put("option:take", this); + ItemDefinition.forId(8859).getHandlers().put("option:take", this); + return this; + } + + }); + } + + /** + * If the low weight shot put is used. + */ + private boolean lowWeight; + + /** + * Constructs a new {@code ShotPutRoom} {@code Object}. + */ + public ShotPutRoom() { + super(); + } + + /** + * Constructs a new {@code ShotPutRoom} {@code Object}. + * @param player The player. + */ + public ShotPutRoom(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new ShotPutRoom(player); + } + + @Override + public boolean open(Object... args) { + lowWeight = (Boolean) args[0]; + interpreter.sendOptions("Choose your style", "Standing throw", "Step and throw", "Spin and throw"); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (buttonId) { + case 1: + player.animate(Animation.create(4181)); + throwShotPut(player, 5, lowWeight, "You throw the shot as hard as you can."); + break; + case 2: + player.animate(Animation.create(4182)); + throwShotPut(player, 2, lowWeight, "You take a step and throw the shot as hard as you can."); + break; + case 3: + player.animate(Animation.create(4183)); + throwShotPut(player, 5, lowWeight, "You spin around and release the shot."); + break; + default: + return false; + } + end(); + return true; + } + + /** + * Throws the shot put. + * @param player The player. + * @param delay The delay. + * @param lowWeight If the low weight shot put was thrown. + */ + private static void throwShotPut(final Player player, int delay, final boolean lowWeight, final String message) { + player.lock(); + int cost = lowWeight ? 6 : 12; + if (player.getAttribute("hand_dust", false)) { + player.removeAttribute("hand_dust"); + cost = 0; + } + int distance = 1; + if (RandomFunction.randomize(25 - cost) != 0) { + int mod = (int) (RandomFunction.randomize(cost) * (1 - (player.getSettings().getRunEnergy() / (100 + cost)))); + distance += RandomFunction.randomize(12 - mod); + } + final boolean failed = distance < 2; + final int tiles = distance; + player.getPacketDispatch().sendMessage("You take a deep breath and prepare yourself."); + GameWorld.getPulser().submit(new Pulse(delay, player) { + Location loc = player.getLocation(); + boolean thrown; + + @Override + public boolean pulse() { + if (!thrown) { + player.getSettings().updateRunEnergy(10); + player.getPacketDispatch().sendMessage(message); + if (failed) { + player.getPacketDispatch().sendMessage("You fumble and drop the shot on your toe. Ow!"); + player.getImpactHandler().manualHit(player, 1, HitsplatType.NORMAL, 2); + } + int speed = (int) (30 + (tiles * 10)); + Projectile projectile = Projectile.create(loc, loc = loc.transform(tiles, 0, 0), 690, 40, 0, getDelay() == 5 ? 5 : 12, speed, 20, 11); + projectile.send(); + setDelay(1 + (int) Math.ceil(tiles * 0.3)); + thrown = true; + return false; + } + player.unlock(); + if (!failed) { + player.getSavedData().getActivityData().updateWarriorTokens(tiles + (!lowWeight ? 2 : 0)); + player.getSkills().addExperience(Skills.STRENGTH, tiles); + player.getDialogueInterpreter().sendDialogues(lowWeight ? 4299 : 4300, FacialExpression.HALF_GUILTY, "Well done. You threw the shot " + (tiles - 1) + " yard" + (tiles > 2 ? "s!" : "!")); + } + GroundItemManager.create(new GroundItem(new Item(lowWeight ? 8858 : 8859), loc, 20, player)); + return true; + } + }); + } + + @Override + public int[] getIds() { + return new int[] { DialogueInterpreter.getDialogueKey("shot_put") }; + } + +} diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/DeathPlateau.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/DeathPlateau.kt new file mode 100644 index 0000000..24e3f6c --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/DeathPlateau.kt @@ -0,0 +1,175 @@ +package content.region.asgarnia.burthorpe.quest.deathplateau + +import core.api.addItemOrDrop +import core.api.getAttribute +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import org.rs09.consts.Items +import content.data.Quests + +/** + * Death Plateau Quest + * @author bushtail + * @author ovenbread + */ +@Initializable +class DeathPlateau : Quest(Quests.DEATH_PLATEAU,44, 43, 1, 314, 0, 1, 80) { + override fun drawJournal(player: Player?, stage: Int) { + super.drawJournal(player, stage) + var line = 12 + var stage = getStage(player) + + var started = player?.questRepository?.getStage(Quests.DEATH_PLATEAU)!! > 0 + + if(!started){ + line(player, "I can start this quest by speaking to !!Denulth?? who is in his", line++) + line(player, "tent at the !!Imperial Guard camp?? in !!Burthorpe", line++) + } else { + if(stage >= 5) { + when(stage) { + in 1..18 -> { + line(player,"I have offered to help !!Denulth?? by finding !!another way?? up",line++,) + line(player,"!!Death Plateau.?? I also need to find the !!combination?? to the",line++,) + line(player,"!!equipment room?? and !!unlock?? the door.",line++,) + } + // Technically this part is to be done in parallel with the ball mechanism part above. + in 19..100 -> { + line(player,"I have found another way up Death Plateau.",line++, stage>26) + line++ + line(player,"I have found the combination to the equipment room and",line++,stage>18) + line(player,"unlocked the door.",line++,stage>18) + line++ + } + } + } + if(stage >= 10) { + when(stage) { + 10 -> { + line(player,"The equipment room guard is staying at the local inn, the",line++,stage>18) + line(player,"!!Toad and Chicken.??",line++,stage>18) + } + in 11 .. 12 -> { + line(player,"The equipment room guard is staying at the local inn, the",line++,stage>18) + line(player,"!!Toad and Chicken.?? the guard wouldn't talk to me!",line++,stage>18) + } + in 13 .. 14 -> { + line(player,"The equipment room guard is staying at the local inn, the",line++,stage>18) + line(player,"!!Toad and Chicken.?? the guard wouldn't talk to me! I bought",line++,stage>18) + line(player,"the guard a drink and he seemed more helpful.",line++,stage>18) + } + in 15..100 -> { + line(player,"The equipment room guard is staying at the local inn, the",line++,stage>18) + line(player,"!!Toad and Chicken.?? the guard wouldn't talk to me! I bought",line++,stage>18) + line(player,"the guard a drink and he seemed more helpful. I gambled",line++,stage>18) + line(player,"with the guard until he ran out of money, he wrote out an !!IOU.??",line++,stage>18) + line++ + } + } + } + if(stage >= 16) { + when(stage) { + 16 -> { + line(player,"It turned out the IOU was written on the back of the",line++,stage>18) + line(player,"combination!",line++,stage>18) + } + in 17..100 -> { + line(player,"It turned out the IOU was written on the back of the",line++,stage>18) + line(player,"combination! I put the stone balls in the right places on the",line++,stage>18) + line(player,"stone mechanism and unlocked the door!",line++,stage>18) + line++ + } + } + } + if(stage >= 20) { + when(stage) { + 20 -> { + line(player,"!!Saba?? says that there is a !!sherpa?? living !!nearby?? that may",line++,false) + line(player,"know another way up Death Plateau.",line++,false) + } + 21 -> { + line(player, "I found the !!sherpa's?? house.", line++, true) + // Note: You must give him the 21 items in one go. The items will cross out when you have them in your inventory. + line(player, "!!Tenzing?? will show me a !!secret way?? up Death Plateau if I get", line++, false) + line(player, "him some items:", line++, false) + line(player, "Ten loaves of bread.", line++, getAttribute(player, "deathplateau:bread", false)) + line(player, "Ten cooked trout.", line++, getAttribute(player, "deathplateau:trout", false)) + line(player, "Spiked boots.", line++, getAttribute(player, "deathplateau:boots", false)) + line++ + line(player, "!!Tenzing?? gave me his !!climbing boots??, I need to take them to", line++, false) + line(player, "!!Dunstan?? in !!Burthorpe?? for the !!spikes??", line++, false) + } + 24 -> { + line(player, "I found the !!sherpa's?? house. I gave Tenzing the ten loaves", line++, true) + line(player, "of bread, ten cooked trout and the Spiked boots. Tenzing", line++, true) + line(player, "has given me a map of the secret way.", line++, true) + line++ + line(player,"I need to !!check?? that the !!secret way?? is !!safe?? for the !!Imperial??", line++, false) + line(player,"!!Guard?? to use.", line++, false) + } + 25 -> { + line(player, "I found the !!sherpa's?? house. I gave Tenzing the ten loaves", line++, true) + line(player, "of bread, ten cooked trout and the Spiked boots. Tenzing", line++, true) + line(player, "has given me a map of the secret way.", line++, true) + line++ + line(player,"I need to !!check?? that the !!secret way?? is !!safe?? for the !!Imperial??", line++, false) + line(player,"!!Guard?? to use.", line++, false) + } + in 26 .. 100 -> { + line(player, "I found the !!sherpa's?? house. I gave Tenzing the ten loaves", line++, true) + line(player, "of bread, ten cooked trout and the Spiked boots. Tenzing", line++, true) + line(player, "has given me a map of the secret way. I checked the", line++, true) + line(player, "secret way and it is safe for the Imperial Guard to use.", line++, true) + line++ + } + } + when(stage) { + in 22 .. 23 -> { + line(player, "!!Dunstan?? will help me if I get his !!son signed up?? for the", line++, false) + line(player, "!!Imperial Guard??. I will need an !!Iron bar?? for the boots", line++, false) + } + in 24 .. 100 -> { + line(player,"I have given Dunstan the certificate to prove that his son", line++, true) + line(player,"has been signed up for the Imperial Guard. Dunstan made", line++, true) + line(player, "me the Spiked boots.", line++, true) + line++ + } + } + } + when(stage) { + in 30 .. 40 -> { + line(player, "I should go and tell !!Denulth?? I've completed my mission.", line++, false) + } + in 41 .. 100 -> { + line(player, "I gave Denulth the secret way map and the combination.", line++, true) + line(player, "Denulth gave me some Steel claws and trained me in.", line++, true) + line(player, "attack. I'm now an honorary member of the Imperial Guard!", line++, true) + } + } + if (stage >= 100) { + line++ + line(player,"QUEST COMPLETE!", line) + } + } + } + + override fun finish(player: Player) { + var ln = 10 + super.finish(player) + player.packetDispatch.sendString("You have completed the Death Plateau Quest!", 277, 4) + player.packetDispatch.sendItemZoomOnInterface(Items.STEEL_CLAWS_3097, 240, 277, 5) + + drawReward(player,"1 Quest Point", ln++) + drawReward(player,"3,000 Attack XP", ln++) + drawReward(player,"Some Steel Claws", ln++) + drawReward(player,"Ability to make Claws", ln++) + + addItemOrDrop(player, Items.STEEL_CLAWS_3097, 1) + player.skills.addExperience(Skills.ATTACK, 3000.0) + } + + override fun newInstance(`object`: Any?): Quest { + return this + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/DeathPlateauDoorDialogueFile.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/DeathPlateauDoorDialogueFile.kt new file mode 100644 index 0000000..64c29ce --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/DeathPlateauDoorDialogueFile.kt @@ -0,0 +1,71 @@ +package content.region.asgarnia.burthorpe.quest.deathplateau + +import content.data.Quests +import core.api.getQuestStage +import core.api.getScenery +import core.api.sendDialogue +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.global.action.DoorActionHandler +import core.game.node.entity.npc.NPC +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +class DeathPlateauDoorDialogueFile(val door: Int) : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + if(door == 1) { + npc = NPC(NPCs.HAROLD_1078) + when (stage) { + 0 -> sendDialogue(player!!, "You knock on the door.").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "Come on in!").also { stage++ } + 2 -> { + end() + DoorActionHandler.handleAutowalkDoor(player, getScenery(2906, 3543, 1)) + } + } + } + if(door == 2) { + npc = NPC(NPCs.TENZING_1071) + + when (getQuestStage(player!!, Quests.DEATH_PLATEAU)) { + in 0 .. 19 -> { + when (stage) { + 0 -> sendDialogue(player!!, "You knock on the door.").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "No milk today! Thank you!").also { stage = END_DIALOGUE } + } + } + 20 -> { + when (stage) { + 0 -> sendDialogue(player!!, "You knock on the door.").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "No milk today! Thank you!").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "I'm not the milkman, I need your help!").also { stage++ } + 3 -> npcl(FacialExpression.FRIENDLY, "Oh...OK. You'd better come in then.").also { stage++ } + 4 -> { + end() + DoorActionHandler.handleAutowalkDoor(player, getScenery(2823, 3555, 0)) + } + } + } + in 21 .. 100 -> { + end() + DoorActionHandler.handleAutowalkDoor(player, getScenery(2823, 3555, 0)) + } + } + } + if(door == 3) { + npc = NPC(NPCs.TENZING_1071) + when (getQuestStage(player!!, Quests.DEATH_PLATEAU)) { + in 0..24 -> { + when (stage) { + 0 -> npcl(FacialExpression.FRIENDLY, "Where do you think you're going? This is private property!").also { stage = END_DIALOGUE } + } + } + in 25..100 -> { + end() + DoorActionHandler.handleAutowalkDoor(player, getScenery(2820, 3558, 0)) + } + } + } + + } +} diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/DeathPlateauInteractionListener.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/DeathPlateauInteractionListener.kt new file mode 100644 index 0000000..01a253a --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/DeathPlateauInteractionListener.kt @@ -0,0 +1,95 @@ +package content.region.asgarnia.burthorpe.quest.deathplateau + +import content.data.Quests +import core.api.* +import core.game.global.action.DoorActionHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.item.GroundItemManager +import org.rs09.consts.Items +import org.rs09.consts.Scenery + +class DeathPlateauInteractionListener : InteractionListener { + + companion object { + val stoneBalls = intArrayOf( + Items.STONE_BALL_3109, // Red + Items.STONE_BALL_3110, // Blue + Items.STONE_BALL_3111, // Yellow + Items.STONE_BALL_3112, // Purple + Items.STONE_BALL_3113 // Green + ) + val stoneMechanisms = intArrayOf( + Scenery.STONE_MECHANISM_3676, // 4 Outer stone plates + Scenery.STONE_MECHANISM_3677 // 2 Inner stone plates + ) + } + override fun defineListeners() { + on(Scenery.DOOR_3747, SCENERY, "open") { player, node -> + // Harold's door + when (player.location) { + location(2906, 3543, 1), location(2905, 3543, 1), location(2907, 3543, 1) -> openDialogue(player, DeathPlateauDoorDialogueFile(1)) + else -> DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } + return@on true + } + on(Scenery.DOOR_3745, SCENERY, "open") { player, node -> + when (node.location) { + location(2823, 3555, 0) -> openDialogue(player, DeathPlateauDoorDialogueFile(2)) //1st door to Tenzing + location(2820, 3558, 0) -> openDialogue(player, DeathPlateauDoorDialogueFile(3)) //2nd door to chicken pen + else -> DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } + return@on true + } + + on(Items.IOU_3103, ITEM, "read") { player, _ -> + openDialogue(player, IOUNoteDialogueFile()) + return@on true + } + + on(Items.COMBINATION_3102, ITEM, "read") { player, _ -> + openInterface(player, 220) + setInterfaceText(player, "Red is North of Blue. Yellow is South of Purple.", 220, 7) + setInterfaceText(player, "Green is North of Purple. Blue is West of", 220, 8) + setInterfaceText(player, "Yellow. Purple is East of Red.", 220, 9) + return@on true + } + + onUseWith(IntType.SCENERY, stoneBalls, *stoneMechanisms) { player, used, with -> + val stoneBall = used.asItem() + val stoneMechanism = with.asScenery() + + // Place item on table + if (removeItem(player, stoneBall)) { + produceGroundItem(player, stoneBall.id, 1, stoneMechanism.location) + } + // Check if order was correct + /** + * Facing north + * NONE [2894, 3564, 0] [2895, 3564, 0] GREEN + * RED [2894, 3563, 0] [2895, 3563, 0] PURPLE + * BLUE [2894, 3562, 0] [2895, 3562, 0] YELLOW + */ + if (GroundItemManager.get(Items.STONE_BALL_3109, location(2894, 3563, 0), player) != null && + GroundItemManager.get(Items.STONE_BALL_3110, location(2894, 3562, 0), player) != null && + GroundItemManager.get(Items.STONE_BALL_3111, location(2895, 3562, 0), player) != null && + GroundItemManager.get(Items.STONE_BALL_3112, location(2895, 3563, 0), player) != null && + GroundItemManager.get(Items.STONE_BALL_3113, location(2895, 3564, 0), player) != null) { + if (getQuestStage(player, Quests.DEATH_PLATEAU) == 16) { + sendMessage(player, "The equipment room door has unlocked.") + setQuestStage(player, Quests.DEATH_PLATEAU, 19) + } + } + return@onUseWith true + } + + on(Scenery.LARGE_DOOR_3743, SCENERY, "open") { player, node -> + if (getQuestStage(player, Quests.DEATH_PLATEAU) > 16) { + DoorActionHandler.handleAutowalkDoor(player, node as core.game.node.scenery.Scenery) + } else { + sendMessage(player, "The door is locked.") + } + return@on true + } + } +} diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/DenulthDialogueFile.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/DenulthDialogueFile.kt new file mode 100644 index 0000000..2046cf5 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/DenulthDialogueFile.kt @@ -0,0 +1,177 @@ +package content.region.asgarnia.burthorpe.quest.deathplateau + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.item.Item +import core.tools.END_DIALOGUE +import org.rs09.consts.Items + + +/** + * Denulth sub dialogue file for death plateau. + * Called by EohricDialogue + * @author bushtail + * @author ovenbread + */ + +class DenulthDialogueFile : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (getQuestStage(player!!, Quests.DEATH_PLATEAU)) { + in 0..4 -> { + when (stage) { + 0 -> playerl(FacialExpression.FRIENDLY, "Hello!").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "Hello citizen, how can I help you?").also { stage++ } + 2 -> showTopics( + Topic("Do you have any quests for me?", 100), + Topic("What is this place?", 200), + Topic(FacialExpression.ANNOYED, "You can't, thanks.", END_DIALOGUE) + ) + 100 -> npcl(FacialExpression.FRIENDLY, "I don't know if you can help us!").also { stage++ } + 101 -> npcl(FacialExpression.FRIENDLY, "The trolls have taken up camp on the Death Plateau! They are using it to launch raids at night on the village. We have tried to attack the camp, but the main path is heavily guarded!").also { stage++ } + 102 -> playerl(FacialExpression.ASKING, "Perhaps there is a way you can sneak up at night?").also { stage++ } + 103 -> npcl(FacialExpression.FRIENDLY, "If there is another way, I do not know of it.").also { stage++ } + 104 -> npcl(FacialExpression.FRIENDLY, "Do you know of such a path?").also { stage++ } + 105 -> showTopics( + Topic(FacialExpression.THINKING,"No, but perhaps I could try and find one?", 300), + Topic(FacialExpression.ANNOYED, "No, sorry.", END_DIALOGUE) + ) + + 200 -> npcl(FacialExpression.HAPPY, "Welcome to the Principality of Burthorpe! We are the Imperial Guard for his Royal Highness Prince Anlaf of Burthorpe. Can I assist you with anything else?").also { stage = 2 } + + 300 -> npc(FacialExpression.FRIENDLY, "Citizen you would be well rewarded!").also { stage++ } + 301 -> npcl(FacialExpression.FRIENDLY, "If you go up to Death Plateau, be very careful as the trolls will attack you on sight!").also { stage++ } + 302 -> playerl(FacialExpression.FRIENDLY, "I'll be careful.").also { stage++ } + 303 -> npcl(FacialExpression.FRIENDLY, "One other thing.").also { stage++ } + 304 -> playerl(FacialExpression.FRIENDLY, "What's that?").also { stage++ } + 305 -> npcl(FacialExpression.FRIENDLY, "All of our equipment is kept in the castle on the hill.").also { stage++ } + 306 -> npcl(FacialExpression.FRIENDLY, "The stupid guard that was on duty last night lost the combination to the lock! I told the Prince that the Imperial Guard should've been in charge of security!").also { stage++ } + 307 -> playerl(FacialExpression.ASKING, "No problem, what does the combination look like?").also { stage++ } + 308 -> npcl(FacialExpression.FRIENDLY, "The equipment room is unlocked when the stone balls are placed in the correct order on the stone mechanism outside it. The right order is written on a piece of paper the guard had.").also { stage++ } + 309 -> playerl(FacialExpression.FRIENDLY, "A stone what...?!").also { stage++ } + 310 -> npcl(FacialExpression.FRIENDLY, "Well citizen, the Prince is fond of puzzles. Why we couldn't just have a key is beyond me!").also { stage++ } + 311 -> playerl(FacialExpression.SUSPICIOUS, "I'll get on it right away!").also { + setQuestStage(player!!, Quests.DEATH_PLATEAU, 5) + stage = END_DIALOGUE + } + } + } + in 5..21 -> { + when(stage) { + 0 -> npcl(FacialExpression.HAPPY, "Hello citizen, is there anything you'd like to know?").also { stage++ } + 1 -> showTopics( + Topic("Can you remind me of the quest I am on?", 100), + Topic("I thought the White Knights controlled Asgarnia?", 200), + Topic("What is this place?", 300), + Topic(FacialExpression.HAPPY, "That's all, thanks.", 10) + ) + 10 -> npcl(FacialExpression.HAPPY, "God speed citizen.").also { stage = END_DIALOGUE } + + 100 -> npcl(FacialExpression.HALF_THINKING, "You offered to see if you could find another way up Death Plateau. We could then use it to sneak up and attack the trolls by night.").also { stage++ } + 101 -> playerl(FacialExpression.THINKING, "Ah yes, and the guard had lost the combination to your equipment rooms in the castle on the hill?").also { stage++ } + 102 -> npcl(FacialExpression.HAPPY, "That's right citizen, you offered to recover the combination and unlock the door.").also { stage++ } + 103 -> playerl(FacialExpression.FRIENDLY, "I'll get on it right away!").also { stage++ } + 104 -> npcl(FacialExpression.FRIENDLY, "Good work citizen!").also { stage++ } + 105 -> npcl(FacialExpression.ASKING, "Is there anything else you would like to know?").also { stage = 1 } + + 200 -> npcl(FacialExpression.ANGRY, "You are right citizen. The White Knights have taken advantage of the old and weak king, they control most of Asgarnia, including Falador. However they do not control Burthorpe!").also { stage++ } + 201 -> npcl(FacialExpression.EVIL_LAUGH, "We are the prince's elite troops! We keep Burthorpe secure!").also { stage++ } + 202 -> npcl(FacialExpression.ANGRY, "The White Knights have overlooked us until now! They are pouring money into their war against the Black Knights, They are looking for an excuse to stop our funding and I'm afraid they may have found it!").also { stage++ } + 203 -> npcl(FacialExpression.HALF_WORRIED, "If we can not destroy the troll camp on Death Plateau then the Imperial Guard will be disbanded and Burthorpe will come under control of the White Knights. We cannot let this happen!").also { stage++ } + 204 -> npcl(FacialExpression.ASKING, "Is there anything else you'd like to know?").also { stage = 1 } + + 300 -> npcl(FacialExpression.HAPPY, "Welcome to the Principality of Burthorpe! We are the Imperial Guard for his Royal Highness Prince Anlaf of Burthorpe. Can I assist you with anything else?").also { stage = 1 } + } + } + 22 -> { + when (stage) { + 0 -> playerl(FacialExpression.FRIENDLY, "Hello!").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "Hello citizen, have you found another way up Death Plateau?").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "Yes there is another way up Death Plateau!").also { stage++ } + 3 -> npcl(FacialExpression.FRIENDLY, "We are saved!").also { stage++ } + 4 -> playerl(FacialExpression.FRIENDLY, "There's one thing...").also { stage++ } + 5 -> npcl(FacialExpression.FRIENDLY, "And what is that citizen?").also { stage++ } + 6 -> playerl(FacialExpression.FRIENDLY, "There is a Sherpa who will only show me the secret way if I first get some spikes for his climbing boots. The smith will only do this for me if you sign up his son for the Imperial Guard!").also { stage++ } + 7 -> npcl(FacialExpression.FRIENDLY, "Hmm...this is very irregular.").also { stage++ } + 8 -> playerl(FacialExpression.FRIENDLY, "Will you not do this?").also { stage++ } + 9 -> npcl(FacialExpression.FRIENDLY, "I have heard of Dunstan's son, he is a very promising young man. For the sake of your mission we can make an exception!").also { stage++ } + 10 -> sendItemDialogue(player!!, Items.CERTIFICATE_3114, "Denulth has given you a certificate.").also { + addItemOrDrop(player!!, Items.CERTIFICATE_3114) + stage++ + } + 11 -> npcl(FacialExpression.FRIENDLY, "This certificate proves that we have accepted Dunstan's son for training in the Imperial Guard!").also { stage++ } + 12 -> playerl(FacialExpression.FRIENDLY, "Thank you Denulth, I shall be back shortly!").also { + setQuestStage(player!!, Quests.DEATH_PLATEAU, 23) + stage = END_DIALOGUE + } + } + } + 23 -> { + when (stage) { + 0 -> playerl(FacialExpression.FRIENDLY, "Hello!").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "Hello citizen, have you found the secret way up Death Plateau?").also { + if (!inInventory(player!!, Items.CERTIFICATE_3114)) { + stage = 3 + } else { + stage++ + } + } + 2 -> playerl(FacialExpression.FRIENDLY, "I'm working on it, I just need to give the certificate to Dunstan.").also { stage = END_DIALOGUE } + 3 -> playerl(FacialExpression.FRIENDLY, "I'm working on it but I've lost the certificate!").also { stage++ } + 4 -> npcl(FacialExpression.FRIENDLY, "No problem, I have a duplicate.").also { stage++ } + 5 -> sendItemDialogue(player!!, Items.CERTIFICATE_3114, "Denulth has given you a certificate.").also { + addItemOrDrop(player!!, Items.CERTIFICATE_3114) + stage = END_DIALOGUE + } + } + } + in 24 .. 26 -> { + when (stage) { + 0 -> playerl(FacialExpression.FRIENDLY, "Hello!").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "Hello citizen, have you found the secret way up Death Plateau?").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "Yes! There is a path that runs from a Sherpa's hut around the back of Death Plateau. The trolls haven't found it yet. The Sherpa made a map I can give you.").also { + if (!inInventory(player!!, Items.SECRET_WAY_MAP_3104)) { + stage = 3 + } else { + stage = 4 + } + } + 3 -> playerl(FacialExpression.FRIENDLY, "I don't have the map on me..").also { stage = END_DIALOGUE } + 4 -> sendItemDialogue(player!!, Items.SECRET_WAY_MAP_3104, "You give Denulth the map of the secret way.").also { + if (removeItem(player!!, Item(Items.SECRET_WAY_MAP_3104))) { + stage++ + } else { + stage = END_DIALOGUE + } + } + 5 -> npcl(FacialExpression.FRIENDLY, "Excellent, this looks perfect. They will never see us coming.").also { stage++ } + 6 -> npcl(FacialExpression.FRIENDLY, "Have you managed to open the equipment room?").also { + if (!inInventory(player!!, Items.COMBINATION_3102)) { + stage = 7 + } else { + stage = 8 + } + } + 7 -> playerl(FacialExpression.FRIENDLY, "I have opened the door but I don't have the combination on me.").also { stage = END_DIALOGUE } + 8 -> playerl(FacialExpression.FRIENDLY, "Yes! The door is open and here is the combination.").also { stage++ } + 9 -> sendItemDialogue(player!!, Items.COMBINATION_3102, "You give Denulth the combination to the equipment room.").also { + if (removeItem(player!!, Item(Items.COMBINATION_3102))) { + stage++ + } else { + stage = END_DIALOGUE + } + } + 10 -> npcl(FacialExpression.FRIENDLY, "Well done citizen! We will reward you by training you in attack!").also { stage++ } + 11 -> npcl(FacialExpression.FRIENDLY, "I shall present you with some steel fighting claws. In addition I shall show you the knowledge of creating the fighting claws for yourself.").also { stage++ } + 12 -> npcl(FacialExpression.FRIENDLY, "You are now an honourary member of the Imperial Guard!").also { stage++ } + 13 -> { + stage = END_DIALOGUE + finishQuest(player!!, Quests.DEATH_PLATEAU) + } + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/DiceGameInterfaceListener.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/DiceGameInterfaceListener.kt new file mode 100644 index 0000000..a8ab169 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/DiceGameInterfaceListener.kt @@ -0,0 +1,156 @@ +package content.region.asgarnia.burthorpe.quest.deathplateau + +import core.api.* +import core.game.interaction.InterfaceListener +import core.game.node.entity.player.Player +import core.game.system.task.Pulse +import org.rs09.consts.Components + +/** + * @author bushtail + * Thanks for your work on this quest Phil, it's appreciated. + * @author ovenbread + */ + +class DiceGameInterfaceListener : InterfaceListener { + companion object { + val GOLDSTACKS = intArrayOf(995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004) + val GOLDTHRESHOLDS = intArrayOf(1, 2, 3, 4, 5, 25, 100, 250, 1000, 10000) + + const val ATTRIBUTE_HAROLD_DICE_1 = "deathplateau:harold1" + const val ATTRIBUTE_HAROLD_DICE_2 = "deathplateau:harold2" + const val ATTRIBUTE_PLAYER_DICE_1 = "deathplateau:player1" + const val ATTRIBUTE_PLAYER_DICE_2 = "deathplateau:player2" + const val ATTRIBUTE_WIN_STATE = "deathplateau:winstate" + } + + override fun defineInterfaceListeners() { + onOpen(Components.DEATH_DICE_99) { player, _ -> + var goldID = 0 + var wager = player.getAttribute("deathplateau:wager", 50) + player.setAttribute(ATTRIBUTE_HAROLD_DICE_1, 0) + player.setAttribute(ATTRIBUTE_HAROLD_DICE_2, 0) + player.setAttribute(ATTRIBUTE_PLAYER_DICE_1, 0) + player.setAttribute(ATTRIBUTE_PLAYER_DICE_2, 0) + player.setAttribute(ATTRIBUTE_WIN_STATE, false) + goldID = when(wager){ + 1 -> GOLDSTACKS[0] + 2 -> GOLDSTACKS[1] + 3 -> GOLDSTACKS[2] + 4 -> GOLDSTACKS[3] + 5 -> GOLDSTACKS[4] + in 25..99 -> GOLDSTACKS[5] + in 100..249 -> GOLDSTACKS[6] + in 250..999 -> GOLDSTACKS[7] + in 1000..9999 -> GOLDSTACKS[8] + else -> GOLDSTACKS[9] + } + sendItemOnInterface(player, Components.DEATH_DICE_99, 7, goldID, wager) + sendItemOnInterface(player, Components.DEATH_DICE_99, 8, goldID, wager) + setComponentVisibility(player, Components.DEATH_DICE_99, 9, true) + setInterfaceText(player, "Harold rolls...", Components.DEATH_DICE_99, 13) + preRoll(player) + setInterfaceText(player, player.username, Components.DEATH_DICE_99,6) + (1..4).forEach { sendAnimationOnInterface(player, 1149, Components.DEATH_DICE_99, it) } + submitRollPulse(player, true) + return@onOpen true + } + + on(Components.DEATH_DICE_99){ player, _, _, buttonID, _, _ -> + when(buttonID) { + 10 -> submitRollPulse(player, false) + 12 -> { + closeInterface(player) + val callback: (() -> Unit)? = + getAttribute(player, "deathplateau:dicegameclose", null) + callback?.invoke() + } + } + return@on true + } + + onClose(Components.DEATH_DICE_99){ player, _ -> + setComponentVisibility(player, Components.DEATH_DICE_99, 9, true) + setComponentVisibility(player, Components.DEATH_DICE_99, 11, true) + return@onClose true + } + } + + private fun onClose(deathDice99: Int, any: Any) { + + } + + private fun preRoll(player: Player, triesRemaining: Int = 5) { + val h1 = (1..5).random() + val h2 = (1..5).random() + val p1 = (1..5).random() + val p2 = (1..5).random() + if(h1 + h2 == p1 + p2 && triesRemaining > 0) { + preRoll(player, triesRemaining - 1) + } else { + player.setAttribute(ATTRIBUTE_HAROLD_DICE_1, h1) + player.setAttribute(ATTRIBUTE_HAROLD_DICE_2, h2) + player.setAttribute(ATTRIBUTE_PLAYER_DICE_1, p1) + player.setAttribute(ATTRIBUTE_PLAYER_DICE_2, p2) + player.setAttribute(ATTRIBUTE_WIN_STATE, h1 + h2 < p1 + p2) + } + } + + private fun submitRollPulse(player: Player, isNPCTurn: Boolean) { + val roll1: Int + val roll2: Int + + if (isNPCTurn) { + roll1 = getAttribute(player, ATTRIBUTE_HAROLD_DICE_1, null) ?: return + roll2 = getAttribute(player, ATTRIBUTE_HAROLD_DICE_2, null) ?: return + } else { + roll1 = getAttribute(player, ATTRIBUTE_PLAYER_DICE_1, null) ?: return + roll2 = getAttribute(player, ATTRIBUTE_PLAYER_DICE_2, null) ?: return + } + + val component1 = if (isNPCTurn) 2 else 3 + val component2 = if (isNPCTurn) 1 else 4 + + submitWorldPulse( + InterfaceUpdatePulse( + player, isNPCTurn, + component1, component2, + roll1, roll2 + ) + ) + } + + private class InterfaceUpdatePulse(val player: Player, val isNPCTurn: Boolean, val component1: Int, val component2: Int, val roll1: Int, val roll2: Int) : Pulse() { + val DICEANIM = intArrayOf(42069, 1150, 1151, 1152, 1153, 1154, 1155) + var counter = 0 + override fun pulse(): Boolean { + when (counter++) { + 1 -> { + setComponentVisibility(player, Components.DEATH_DICE_99, 9, true) + if (isNPCTurn) { + setInterfaceText(player, "Harold rolls...", Components.DEATH_DICE_99, 13) + } else { + setInterfaceText(player, "Your roll...", Components.DEATH_DICE_99, 13) + } + sendAnimationOnInterface(player, DICEANIM[roll1], Components.DEATH_DICE_99, component1) + } + 4 -> sendAnimationOnInterface(player, DICEANIM[roll2], Components.DEATH_DICE_99, component2) + 7 -> { + if (isNPCTurn) { + setComponentVisibility(player, Components.DEATH_DICE_99, 9, false) + } else { + if (player.getAttribute("deathplateau:winstate")) { + setInterfaceText(player,"You win!", Components.DEATH_DICE_99, 13) + } else { + setInterfaceText(player,"You lose!", Components.DEATH_DICE_99, 13) + } + setComponentVisibility(player, Components.DEATH_DICE_99, 11, false) + setComponentVisibility(player, Components.DEATH_DICE_99, 9, true) + } + return true + } + } + return false + } + } +} diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/DunstanDialogueFile.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/DunstanDialogueFile.kt new file mode 100644 index 0000000..6cf2eab --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/DunstanDialogueFile.kt @@ -0,0 +1,106 @@ +package content.region.asgarnia.burthorpe.quest.deathplateau + +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.node.item.Item +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.Items +import content.data.Quests + +class DunstanDialogueFile : DialogueFile() { + + override fun handle(componentID: Int, buttonID: Int) { + when (getQuestStage(player!!, Quests.DEATH_PLATEAU)) { + 21 -> { + when (stage) { + START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hi!").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "Hi! How can I help?").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "Tenzing has asked me to bring you his climbing boots, he needs to have spikes put on them.").also { stage++ } + 3 -> npcl(FacialExpression.FRIENDLY, "He does, does he? Well I won't do it till he pays for the last set I made for him!").also { stage++ } + 4 -> playerl(FacialExpression.FRIENDLY, "This is really important!").also { stage++ } + 5 -> npcl(FacialExpression.FRIENDLY, "How so?").also { stage++ } + 6 -> playerl(FacialExpression.FRIENDLY, "Well, I need the Sherpa to show me a secret way up Death Plateau so that the Imperial Guard can destroy the troll camp! He won't help me till I've got the spikes!").also { stage++ } + 7 -> npcl(FacialExpression.FRIENDLY, "Hmm. That's different!").also { stage++ } + 8 -> npcl(FacialExpression.FRIENDLY, "Tell you what, I'll make them for you on one condition.").also { stage++ } + 9 -> playerl(FacialExpression.FRIENDLY, "*sigh* What's the condition?").also { stage++ } + 10 -> npcl(FacialExpression.FRIENDLY, "My son has just turned 16 and I'd very much like him to join the Imperial Guard. The Prince's elite forces are invite only so it's very unlikely he'll get in. If you can arrange that you have a deal!").also { stage++ } + 11 -> playerl(FacialExpression.FRIENDLY, "That won't be a problem as I'm helping out the Imperial Guard!").also { stage++ } + 12 -> npcl(FacialExpression.FRIENDLY, "Excellent! You'll need to bring an Iron bar for the spikes!").also { + setQuestStage(player!!, Quests.DEATH_PLATEAU, 22) + stage = END_DIALOGUE + } + } + } + 22 -> { + when (stage) { + START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hi!").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "Have you managed to get my son signed up for the Imperial Guard?").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "Not yet! I just need to speak to Denulth!").also { stage = END_DIALOGUE } + } + } + 23 -> { + when (stage) { + START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hi!").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "Have you managed to get my son signed up for the Imperial Guard?").also { + stage++ + } + + 2 -> { + if (!inInventory(player!!, Items.CERTIFICATE_3114)) { + playerl(FacialExpression.FRIENDLY, "I have but I don't have the entrance certificate on me.").also { stage++ } + } else { + sendDialogue(player!!, "You give Dunstan the certificate.").also { stage = 5 } + } + } + + 3 -> npcl(FacialExpression.FRIENDLY, "Good but I need to have the certificate.").also { stage = END_DIALOGUE } + + 5 -> npcl(FacialExpression.FRIENDLY, "Thank you!").also { + // Jumps to the next stage immediately in one continuous dialogue (questStage 24, stage 2). + setQuestStage(player!!, Quests.DEATH_PLATEAU, 24) + stage = 2 + } + } + } + 24 -> { + when (stage) { + START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hi!").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "Hi!").also { stage++ } + 2 -> npcl(FacialExpression.FRIENDLY, "Now to keep my end of the bargain. Give me the boots and an iron bar and I'll put on the spikes.").also { + if (inInventory(player!!, Items.CLIMBING_BOOTS_3105) && inInventory(player!!, Items.IRON_BAR_2351)) { + stage = 7 + } else if (inInventory(player!!, Items.CLIMBING_BOOTS_3105)){ + stage = 3 + } else if (inInventory(player!!, Items.IRON_BAR_2351)){ + stage = 4 + } else { + stage = 5 + } + } + 3 -> playerl(FacialExpression.FRIENDLY, "I don't have the iron bar.").also { stage = END_DIALOGUE } + 4 -> playerl(FacialExpression.FRIENDLY, "I don't have the climbing boots.").also { stage = END_DIALOGUE } + 5 -> playerl(FacialExpression.FRIENDLY, "I don't have the iron bar or the climbing boots.").also { stage = END_DIALOGUE } + + 7 -> sendDoubleItemDialogue(player!!, Items.IRON_BAR_2351, Items.CLIMBING_BOOTS_3105, "You give Dunstan an Iron bar and the climbing boots.").also { + sendMessage(player!!, "You give Dunstan an Iron bar and the climbing boots.") + if (removeItem(player!!, Item(Items.CLIMBING_BOOTS_3105)) && removeItem(player!!, Item(Items.IRON_BAR_2351))) { + addItemOrDrop(player!!, Items.SPIKED_BOOTS_3107) + stage++ + } else { + stage = END_DIALOGUE + } + } + 8 -> sendItemDialogue(player!!, Items.SPIKED_BOOTS_3107, "Dunstan has given you the spiked boots.").also { stage++ + sendMessage(player!!, "Dunstan has given you the spiked boots.") + } + 9 -> playerl(FacialExpression.FRIENDLY, "Thank you!").also { stage++ } + 10 -> npcl(FacialExpression.FRIENDLY, "No problem.").also { + stage = END_DIALOGUE + } + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/EohricDialogueFile.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/EohricDialogueFile.kt new file mode 100644 index 0000000..8e0d5f0 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/EohricDialogueFile.kt @@ -0,0 +1,76 @@ +package content.region.asgarnia.burthorpe.quest.deathplateau + +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import content.data.Quests + +/** + * Eohric sub dialogue file for death plateau. + * Called by EohricDialogue + * @author bushtail + * @author ovenbread + */ +class EohricDialogueFile : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (getQuestStage(player!!, Quests.DEATH_PLATEAU)) { + in 5..9 -> { + when (stage) { + START_DIALOGUE -> player(FacialExpression.FRIENDLY, "Hi!").also { stage++ } + 1 -> npc(FacialExpression.FRIENDLY, "Hi, can I help?").also { stage++ } + 2 -> showTopics( + Topic(FacialExpression.THINKING, "I'm looking for the guard that was on the last night.", 10), + Topic(FacialExpression.FRIENDLY, "Do you know of another way up Death Plateau?", 20), + Topic(FacialExpression.FRIENDLY, "No, I'm just looking around.", END_DIALOGUE) + ) + 10 -> npcl(FacialExpression.FRIENDLY,"There was only one guard on last night. Harold. He's a nice lad, if a little dim.").also { stage++ } + 11 -> player(FacialExpression.FRIENDLY, "Do you know where he is staying?").also { stage++ } + 12 -> npc(FacialExpression.FRIENDLY, "Harold is staying at the Toad and Chicken.").also { stage++ } + 13 -> player(FacialExpression.FRIENDLY, "Thanks!").also { + setQuestStage(player!!, Quests.DEATH_PLATEAU, 10) + HaroldDialogueFile.resetNpc(player!!) + stage = END_DIALOGUE + } + 20 -> npcl(FacialExpression.FRIENDLY, "No, sorry. I wouldn't want to go north-east from here, it's very rocky and barren.").also { stage = END_DIALOGUE } + } + } + 10 -> { + when (stage) { + START_DIALOGUE -> player(FacialExpression.FRIENDLY, "Hi!").also { stage++ } + 1 -> npc(FacialExpression.FRIENDLY, "Hi, can I help?").also { stage++ } + 2 -> showTopics( + Topic(FacialExpression.THINKING, "Where is the guard that was on last night staying?", 10), + Topic(FacialExpression.FRIENDLY, "Do you know of another way up Death Plateau?", 20), + Topic(FacialExpression.FRIENDLY, "No, I'm just looking around.", END_DIALOGUE) + ) + 10 -> npc(FacialExpression.FRIENDLY, "Harold is staying at the Toad and Chicken.").also { stage = END_DIALOGUE } + 20 -> npcl(FacialExpression.FRIENDLY, "No, sorry. I wouldn't want to go north-east from here, it's very rocky and barren.").also { stage = END_DIALOGUE } + } + } + 11 -> { + when (stage) { + START_DIALOGUE -> player(FacialExpression.FRIENDLY, "Hi!").also { stage++ } + 1 -> npc(FacialExpression.FRIENDLY, "Hi, can I help?").also { stage++ } + 2 -> playerl(FacialExpression.HALF_GUILTY, "I found Harold but he won't talk to me!.").also { stage++ } + 3 -> npcl(FacialExpression.THINKING, "Hmm. Harold has got in trouble a few over his drinking and gambling. Perhaps he'd open up after a drink?").also { stage++ } + 4 -> playerl(FacialExpression.FRIENDLY, "Thanks, I'll try that!").also { + setQuestStage(player!!, Quests.DEATH_PLATEAU, 12) + stage = END_DIALOGUE + } + } + } + 12 -> { + when (stage) { + START_DIALOGUE -> player(FacialExpression.FRIENDLY, "Hi!").also { stage++ } + 1 -> npc(FacialExpression.FRIENDLY, "Hi, can I help?").also { stage++ } + 2 -> playerl(FacialExpression.ASKING, "You said Harold had a weakness?").also { stage++ } + 3 -> npcl(FacialExpression.THINKING,"Yes, if you buy Harold a beer he might talk to you. I also know he has a weakness for gambling. Hope that helps!").also { stage++ } + 4 -> playerl(FacialExpression.FRIENDLY, "Thanks for the help!").also {stage = END_DIALOGUE} + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/HaroldDialogueFile.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/HaroldDialogueFile.kt new file mode 100644 index 0000000..005206e --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/HaroldDialogueFile.kt @@ -0,0 +1,408 @@ +package content.region.asgarnia.burthorpe.quest.deathplateau + +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.world.update.flag.context.Graphics +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.Animations +import org.rs09.consts.Items +import content.data.Quests + +/** + * Harold sub dialogue file for death plateau. + * Called by HaroldDialogue + * @author bushtail + * @author ovenbread + */ +class HaroldDialogueFile : DialogueFile() { + + companion object{ + const val ATTRIBUTE_JUMPSTAGE = "deathplateau:jumpStage" + const val ATTRIBUTE_HAROLD_MONEY = "/save:deathplateau:haroldMoney" + + /** Resets the NPC's quest attributes */ + fun resetNpc(player: Player) { + setAttribute(player, ATTRIBUTE_JUMPSTAGE, 0) + setAttribute(player, ATTRIBUTE_HAROLD_MONEY, 200) + } + } + override fun handle(componentID: Int, buttonID: Int) { + // This jumpStage is needed to resume the conversation after the dice interface. + // The dice interface closes the dialogue file. + if(getAttribute(player!!, ATTRIBUTE_JUMPSTAGE, 0) != 0) { + stage = getAttribute(player!!, ATTRIBUTE_JUMPSTAGE, 0) + setAttribute(player!!, ATTRIBUTE_JUMPSTAGE, 0) + } + println(getAttribute(player!!, ATTRIBUTE_HAROLD_MONEY, -1)) + when (getQuestStage(player!!, Quests.DEATH_PLATEAU)) { + 10 -> { // First time meeting. + when (stage) { + START_DIALOGUE -> player(FacialExpression.FRIENDLY, "Hello there.").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "Hi.").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "You're the guard that was on duty last night?").also { stage++ } + 3 -> npcl(FacialExpression.FRIENDLY, "Yeah.").also { stage++ } + 4 -> playerl(FacialExpression.HAPPY, "Denulth said that you lost the combination to the equipment room ?").also { stage++ } + 5 -> npcl(FacialExpression.FRIENDLY, "I don't want to talk about it!").also { + setQuestStage(player!!, Quests.DEATH_PLATEAU, 11) + stage = END_DIALOGUE + } + } + } + 11 -> { // Asking again. + when (stage) { + START_DIALOGUE -> player(FacialExpression.FRIENDLY, "Hello there.").also { stage++ } + 1 -> npcl(FacialExpression.ANNOYED, "What?").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "You're the guard that was on duty last night?").also { stage++ } + 3 -> npcl(FacialExpression.FRIENDLY, "I said I didn't want to talk about it!").also { + stage = END_DIALOGUE + } + } + } + 12 -> { // After asking Eohric about opening up. + when (stage) { + START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hello there.").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "Hi.").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "Can I buy you a drink?").also { stage++ } + 3 -> npcl(FacialExpression.HAPPY, "Now you're talking! An Asgarnian Ale, please!").also { stage++ } + 4 -> { + if (inInventory(player!!, Items.ASGARNIAN_ALE_1905, 1)) { + removeItem(player!!, Items.ASGARNIAN_ALE_1905) + setQuestStage(player!!, Quests.DEATH_PLATEAU, 12) + sendMessage(player!!, "You give Harold an Asgarnian Ale.") + setAttribute(player!!, ATTRIBUTE_HAROLD_MONEY, 200) + sendItemDialogue(player!!, Items.ASGARNIAN_ALE_1905, "You give Harold an Asgarnian Ale.").also { stage++ } + } else { + playerl(FacialExpression.FRIENDLY, "I'll go and get you one.").also { stage = END_DIALOGUE } + } + } + 5 -> { + end() + setQuestStage(player!!, Quests.DEATH_PLATEAU, 13) + animate(npc!!, Animations.HUMAN_EATTING_829) + runTask(npc!!, 5) { + npcl(FacialExpression.FRIENDLY, "Arrh. That hit the spot!").also { stage = END_DIALOGUE } + } + } + } + } + 13 -> { // After getting him an Asgarnian Ale. + when (stage) { + START_DIALOGUE -> player(FacialExpression.FRIENDLY, "Hello there.").also { stage++ } + 1 -> npc(FacialExpression.FRIENDLY, "Hi.").also { stage++ } + 2 -> showTopics( + Topic(FacialExpression.ASKING, "Where were you when you last had the combination?", 10), + Topic(FacialExpression.FRIENDLY, "Would you like to gamble?", 30), + Topic(FacialExpression.FRIENDLY, "Can I buy you a drink?", 20) + ) + + 10 -> npcl(FacialExpression.FRIENDLY, "I honestly don't know! I've looked everywhere. I've searched the castle and my room!").also { stage++ } + 11 -> playerl(FacialExpression.ASKING, "Have you tried looking between here and the castle?").also { stage++ } + 12 -> npcl(FacialExpression.FRIENDLY, "Yeah, I tried that.").also { stage++ } + 13 -> npcl(FacialExpression.FRIENDLY, "I need another beer.").also { stage = END_DIALOGUE } + + 20 -> npcl(FacialExpression.FRIENDLY, "Sounds good! I normally drink Asgarnian Ale but you know what?").also { stage++ } + 21 -> playerl(FacialExpression.ASKING, "What?").also { stage++ } + 22 -> npcl(FacialExpression.FRIENDLY, "I really fancy one of those Blurberry Specials. I never get over to the Gnome Stronghold so I haven't had one for ages!").also { stage++ } + 23 -> { + if (removeItem(player!!, Items.BLURBERRY_SPECIAL_2064)) { + sendMessage(player!!, "You give Harold a Blurberry Special.") + sendItemDialogue(player!!, Items.BLURBERRY_SPECIAL_2064, "You give Harold a Blurberry Special.").also { stage++ } + } else if (removeItem(player!!, Items.BLURBERRY_SPECIAL_9520)) { // This should not be here since 9520 is used by the gnome restaurant minigame. + sendMessage(player!!, "You give Harold a Blurberry Special.") + sendItemDialogue(player!!, Items.BLURBERRY_SPECIAL_2064, "You give Harold a Blurberry Special.").also { stage++ } + } else if (removeItem(player!!, Items.PREMADE_BLURB_SP_2028)) { + sendMessage(player!!, "You give Harold a Blurberry Special.") + sendItemDialogue(player!!, Items.PREMADE_BLURB_SP_2028, "You give Harold a Blurberry Special.").also { stage++ } + } else { + player(FacialExpression.FRIENDLY, "I'll go and get you one.").also { stage = END_DIALOGUE } + } + } + 24 -> { + end() + setQuestStage(player!!, Quests.DEATH_PLATEAU, 14) + npc!!.isWalks = false + animate(npc!!, Animations.HUMAN_EATTING_829) + runTask(npc!!, 4) { + npc!!.sendChat("Wow!") + runTask(npc!!, 4) { + sendGraphics(Graphics(80, 96), npc!!.location) + runTask(npc!!, 6) { + npc(FacialExpression.DRUNK, "Now THAT hit the spot!").also { + runTask(npc!!, 6) { + npc!!.isWalks = true + end() + stage = END_DIALOGUE + } + } + } + } + } + } + + 30 -> npcl(FacialExpression.FRIENDLY, "Good. Good. I have some dice. How much do you want to offer?").also { stage++ } + 31 -> { + sendInputDialogue(player!!, true, "Enter amount:") { value -> + val wagerAmount = value as Int + // Check wager amount. + if (wagerAmount <= 0) { + sendMessage(player!!, "You have to offer some money.").also { stage = END_DIALOGUE } + } else if (wagerAmount > 1000) { + npcl(FacialExpression.FRIENDLY, "Woah! Do you think I'm made of money? Max bet is 1000 gold.").also { stage = END_DIALOGUE } + } else if (!inInventory(player!!, Items.COINS_995) || amountInInventory(player!!, Items.COINS_995) < value) { + sendMessage(player!!, "You do not have that much money!").also { stage = END_DIALOGUE } + } else if (removeItem(player!!, Item(Items.COINS_995, value))) { + player!!.setAttribute("deathplateau:wager", wagerAmount) + npc(FacialExpression.FRIENDLY, "OK. I'll roll first!").also { stage++ } + } + return@sendInputDialogue + } + } + 32 -> { + npcl(FacialExpression.FRIENDLY, "Don't forget that once I start my roll you can't back out of the bet! If you do you lose your stake!").also { stage++ } + } + 33 -> { + end() + npc!!.isWalks = false + // Dialogue drops when another interface is clicked. So a resume dialogue is needed. + val advanceStage : (() -> Unit) = { + npc!!.isWalks = true + setAttribute(player!!, ATTRIBUTE_JUMPSTAGE, stage + 1) + openDialogue(player!!, HaroldDialogueFile(), npc!!) + } + setAttribute(player!!, "deathplateau:dicegameclose", advanceStage) + openInterface(player!!, 99) + setInterfaceText(player!!, player!!.name, 99, 6) + } + 34 -> { + val wager = getAttribute(player!!, "deathplateau:wager", 0) + val haroldAmount = getAttribute(player!!, ATTRIBUTE_HAROLD_MONEY, 0) + if (getAttribute(player!!, "deathplateau:winstate", false)) { + // Win + if (wager > haroldAmount) { + npcl(FacialExpression.FRIENDLY, "Oh dear, I seem to have run out of money!").also { stage++ } + } else { + addItemOrDrop(player!!, Items.COINS_995, wager * 2) + sendMessage(player!!, "Harold has given you your winnings!") + setAttribute(player!!, ATTRIBUTE_HAROLD_MONEY,haroldAmount - wager) + sendItemDialogue(player!!, Items.COINS_995, "Harold has given you your winnings!").also { stage = END_DIALOGUE } + } + } else { + // Lose + setAttribute(player!!, ATTRIBUTE_HAROLD_MONEY,haroldAmount + wager) + sendItemDialogue(player!!, Items.COINS_995, "You give Harold his winnings.").also { stage = END_DIALOGUE } + } + } + 35 -> npcl(FacialExpression.FRIENDLY, "Here's what I have.").also { stage++ } + 36 -> sendItemDialogue(player!!, Items.COINS_995, "Harold has given you some of your winnings!").also { + sendMessage(player!!, "Harold has given you some of your winnings!") + val haroldAmount = getAttribute(player!!, ATTRIBUTE_HAROLD_MONEY, 200) + setAttribute(player!!, ATTRIBUTE_HAROLD_MONEY,0) + addItemOrDrop(player!!, Items.COINS_995, haroldAmount) + stage++ + } + 37 -> npcl(FacialExpression.FRIENDLY, "I'll write you out an IOU for the rest.").also { stage++ } + 38 -> { + addItemOrDrop(player!!, Items.IOU_3103) + setQuestStage(player!!, Quests.DEATH_PLATEAU, 15) + sendMessage(player!!, "Harold has given you an IOU scribbled on some paper.") + sendItemDialogue(player!!, Items.IOU_3103, "Harold has given you an IOU scribbled on some paper.").also {stage = END_DIALOGUE} + } + } + } + 14 -> { // After getting him a Blurberry Special. + when (stage) { + START_DIALOGUE -> player(FacialExpression.FRIENDLY, "Hello there.").also { stage++ } + 1 -> npc(FacialExpression.DRUNK, "'Ello matey!'").also { stage++ } + 2 -> showTopics( + Topic(FacialExpression.THINKING, "Where were you when you last had the combination?", 10), + Topic(FacialExpression.FRIENDLY, "Would you like to gamble?", 20), + Topic(FacialExpression.FRIENDLY, "Can I buy you a drink?", 15) + ) + + 10 -> npc(FacialExpression.DRUNK,"Hmm...!").also { stage++ } + 11 -> npc(FacialExpression.DRUNK,"Er...!").also { stage++ } + 12 -> npc(FacialExpression.DRUNK,"What wash the queshtion?").also { stage = END_DIALOGUE } + + 15 -> npcl(FacialExpression.DRUNK, "I fink I've had enough!").also { stage = END_DIALOGUE } + + 20 -> npc(FacialExpression.DRUNK,"Shure!").also { stage++ } + 21 -> npc(FacialExpression.DRUNK,"Place your betsh pleashe!").also { stage++ } + 22 -> npc(FacialExpression.DRUNK,"*giggle*!").also { stage++ } + + 23 -> { + sendInputDialogue(player!!, true, "Enter amount:") { value -> + val wagerAmount = value as Int + // Check wager amount. + if (wagerAmount <= 0) { + sendMessage(player!!, "You have to offer some money.").also { stage = END_DIALOGUE } + } else if (wagerAmount > 1000) { + npcl(FacialExpression.DRUNK, "Eashy tiger! Max bet ish 1000 coinsh.").also { stage = END_DIALOGUE } + } else if (!inInventory(player!!, Items.COINS_995) || amountInInventory(player!!, Items.COINS_995) < value) { + sendMessage(player!!, "You do not have that much money!").also { stage = END_DIALOGUE } + } else if (removeItem(player!!, Item(Items.COINS_995, value))) { + player!!.setAttribute("deathplateau:wager", wagerAmount) + npc(FacialExpression.DRUNK, "Right...er...here goes...").also { stage++ } + } + return@sendInputDialogue + } + } + 24 -> { + end() + npc!!.isWalks = false + // Dialogue drops when another interface is clicked. So a resume dialogue is needed. + val advanceStage : (() -> Unit) = { + setAttribute(player!!, ATTRIBUTE_JUMPSTAGE, stage + (1..4).random()) + openDialogue(player!!, HaroldDialogueFile(), npc!!) + } + setAttribute(player!!, "deathplateau:dicegameclose", advanceStage) + openInterface(player!!, 99) + setInterfaceText(player!!, player!!.name, 99, 6) + } + 25 -> npc(FacialExpression.DRUNK, "Shixteen! How am I shupposhed to beat that!").also { stage = 30 } + 26 -> npc(FacialExpression.DRUNK, "I didn't know you could ushe four dishe. Oh well.").also { stage = 30 } + 27 -> npc(FacialExpression.DRUNK, "*hic*").also { stage = 30 } + 28 -> npc(FacialExpression.DRUNK, "I sheemed to have rolled a one.").also { stage = 30 } + 30 -> { + sendDialogue(player!!, "Harold is so drunk he can hardly see, let alone count!").also { stage++ } + npc!!.isWalks = true + sendMessage(player!!, "Harold is so drunk he can hardly see, let alone count!") + } + 31 -> { + val wager = getAttribute(player!!, "deathplateau:wager", 0) + val haroldAmount = getAttribute(player!!, ATTRIBUTE_HAROLD_MONEY, 0) + // Always Win + if (wager > haroldAmount) { + npcl(FacialExpression.DRUNK, " Um...not enough money.").also { stage++ } + } else { + addItemOrDrop(player!!, Items.COINS_995, wager * 2) + sendMessage(player!!, "Harold has given you your winnings!") + setAttribute(player!!, ATTRIBUTE_HAROLD_MONEY,haroldAmount - wager) + sendItemDialogue(player!!, Items.COINS_995, "Harold has given you your winnings!").also { stage = END_DIALOGUE } + } + } + 32 -> npcl(FacialExpression.DRUNK, "Heresh shome of it.").also { stage++ } + 33 -> sendItemDialogue(player!!, Items.COINS_995, "Harold has given you some of your winnings!").also { + sendMessage(player!!, "Harold has given you some of your winnings!") + val haroldAmount = getAttribute(player!!, ATTRIBUTE_HAROLD_MONEY, 200) + setAttribute(player!!, ATTRIBUTE_HAROLD_MONEY,0) + addItemOrDrop(player!!, Items.COINS_995, haroldAmount) + stage++ + } + 34 -> npcl(FacialExpression.DRUNK, "I owe you the resht!").also { stage++ } + 35 -> { + addItemOrDrop(player!!, Items.IOU_3103) + setQuestStage(player!!, Quests.DEATH_PLATEAU, 15) + sendMessage(player!!, "Harold has given you an IOU scribbled on some paper.") + sendItemDialogue(player!!, Items.IOU_3103, "Harold has given you an IOU scribbled on some paper.").also {stage = END_DIALOGUE} + } + } + } + 15 -> { // If you lose your IOU + when (stage) { + START_DIALOGUE -> npcl(FacialExpression.FRIENDLY, "Hi.").also { + if (inInventory(player!!, Items.IOU_3103)){ + stage = 5 + } else { + stage++ + } + } + 1 -> playerl(FacialExpression.FRIENDLY, "I've lost the IOU you gave me.").also { stage++ } + 2 -> npcl(FacialExpression.FRIENDLY, "I'll write you another.").also { stage++ } + 3 -> { + addItemOrDrop(player!!, Items.IOU_3103) + sendItemDialogue(player!!, Items.IOU_3103, "Harold has given you an IOU scribbled on some paper.").also {stage = END_DIALOGUE} + } + + 5 -> npc(FacialExpression.FRIENDLY, "Hi.").also { stage++ } + 6 -> showTopics( + Topic(FacialExpression.ASKING, "Where were you when you last had the combination?", 10), + Topic(FacialExpression.FRIENDLY, "Would you like to gamble?", 30), + Topic(FacialExpression.FRIENDLY, "Can I buy you a drink?", 20) + ) + + 10 -> npcl(FacialExpression.FRIENDLY, "I honestly don't know! I've looked everywhere. I've searched the castle and my room!").also { stage++ } + 11 -> playerl(FacialExpression.ASKING, "Have you tried looking between here and the castle?").also { stage++ } + 12 -> npcl(FacialExpression.FRIENDLY, "Yeah, I tried that.").also { stage++ } + 13 -> npcl(FacialExpression.FRIENDLY, "I need another beer.").also { stage = END_DIALOGUE } + + 20 -> npcl(FacialExpression.FRIENDLY, "I've run out of money!").also { stage++ } + 21 -> npcl(FacialExpression.FRIENDLY, "Oh dear. I need beer.").also { stage = END_DIALOGUE } + + 30 -> npcl(FacialExpression.HAPPY, "Now you're talking! An Asgarnian Ale, please!").also { stage++ } + 31 -> { + if (inInventory(player!!, Items.ASGARNIAN_ALE_1905, 1)) { + removeItem(player!!, Items.ASGARNIAN_ALE_1905) + sendMessage(player!!, "You give Harold an Asgarnian Ale.") + sendItemDialogue(player!!, Items.ASGARNIAN_ALE_1905, "You give Harold an Asgarnian Ale.").also { stage++ } + } else { + playerl(FacialExpression.FRIENDLY, "I'll go and get you one.").also { stage = END_DIALOGUE } + } + } + 32 -> { + end() + animate(npc!!, Animations.HUMAN_EATTING_829) + runTask(npc!!, 5) { + npcl(FacialExpression.FRIENDLY, "Arrh. That hit the spot!").also { stage = END_DIALOGUE } + } + } + + } + } + in 16 .. 29 -> { // If you lose your IOU + when (stage) { + START_DIALOGUE -> npcl(FacialExpression.FRIENDLY, "Hi.").also { + if (inInventory(player!!, Items.COMBINATION_3102) || inInventory(player!!, Items.IOU_3103)){ + stage = 5 + } else { + stage++ + } + } + 1 -> playerl(FacialExpression.FRIENDLY, "I've lost the IOU you gave me.").also { stage++ } + 2 -> npcl(FacialExpression.FRIENDLY, "I'll write you another.").also { stage++ } + 3 -> { + addItemOrDrop(player!!, Items.COMBINATION_3102) + sendItemDialogue(player!!, Items.COMBINATION_3102, "Harold has given you the IOU, which you know is the combination.").also {stage = END_DIALOGUE} + } + + 5 -> npc(FacialExpression.FRIENDLY, "Hi.").also { stage++ } + 6 -> showTopics( + Topic(FacialExpression.ASKING, "Where were you when you last had the combination?", 10), + Topic(FacialExpression.FRIENDLY, "Would you like to gamble?", 30), + Topic(FacialExpression.FRIENDLY, "Can I buy you a drink?", 20) + ) + + 10 -> npcl(FacialExpression.FRIENDLY, "I honestly don't know! I've looked everywhere. I've searched the castle and my room!").also { stage++ } + 11 -> playerl(FacialExpression.ASKING, "Have you tried looking between here and the castle?").also { stage++ } + 12 -> npcl(FacialExpression.FRIENDLY, "Yeah, I tried that.").also { stage++ } + 13 -> npcl(FacialExpression.FRIENDLY, "I need another beer.").also { stage = END_DIALOGUE } + + 20 -> npcl(FacialExpression.FRIENDLY, "I've run out of money!").also { stage++ } + 21 -> npcl(FacialExpression.FRIENDLY, "Oh dear. I need beer.").also { stage = END_DIALOGUE } + + 30 -> npcl(FacialExpression.HAPPY, "Now you're talking! An Asgarnian Ale, please!").also { stage++ } + 31 -> { + if (inInventory(player!!, Items.ASGARNIAN_ALE_1905, 1)) { + removeItem(player!!, Items.ASGARNIAN_ALE_1905) + sendMessage(player!!, "You give Harold an Asgarnian Ale.") + sendItemDialogue(player!!, Items.ASGARNIAN_ALE_1905, "You give Harold an Asgarnian Ale.").also { stage++ } + } else { + playerl(FacialExpression.FRIENDLY, "I'll go and get you one.").also { stage = END_DIALOGUE } + } + } + 32 -> { + end() + animate(npc!!, Animations.HUMAN_EATTING_829) + runTask(npc!!, 5) { + npcl(FacialExpression.FRIENDLY, "Arrh. That hit the spot!").also { stage = END_DIALOGUE } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/IOUNoteDialogueFile.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/IOUNoteDialogueFile.kt new file mode 100644 index 0000000..4a45314 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/IOUNoteDialogueFile.kt @@ -0,0 +1,38 @@ +package content.region.asgarnia.burthorpe.quest.deathplateau + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.tools.END_DIALOGUE +import org.rs09.consts.Items + +class IOUNoteDialogueFile : DialogueFile() { + var a = 0 + override fun handle(componentID: Int, buttonID: Int) { + when (getQuestStage(player!!, Quests.DEATH_PLATEAU)) { + in 15..16 -> { + when (stage) { + 0 -> player(FacialExpression.NEUTRAL, "The IOU says that Harold owes me some money.").also { stage++ } + 1 -> player(FacialExpression.EXTREMELY_SHOCKED, "Wait just a minute!").also { stage++ } + 2 -> playerl(FacialExpression.EXTREMELY_SHOCKED, "The IOU is written on the back of the combination! The stupid guard had it in his back pocket all the time!").also { stage++ } + 3 -> { + if (removeItem(player!!, Items.IOU_3103)) { + addItemOrDrop(player!!, Items.COMBINATION_3102) + setQuestStage(player!!, Quests.DEATH_PLATEAU, 16) + sendItemDialogue(player!!, Items.COMBINATION_3102, "You have found the combination!").also { stage++ } + } + } + 4 -> { + end() + stage = END_DIALOGUE + openInterface(player!!, 220) + setInterfaceText(player!!, "Red is North of Blue. Yellow is South of Purple.", 220, 7) + setInterfaceText(player!!, "Green is North of Purple. Blue is West of", 220, 8) + setInterfaceText(player!!, "Yellow. Purple is East of Red.", 220, 9) + } + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/SabaDialogueFile.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/SabaDialogueFile.kt new file mode 100644 index 0000000..820fdf2 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/SabaDialogueFile.kt @@ -0,0 +1,63 @@ +package content.region.asgarnia.burthorpe.quest.deathplateau + +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.tools.END_DIALOGUE +import content.data.Quests + +class SabaDialogueFile : DialogueFile() { + + override fun handle(componentID: Int, buttonID: Int) { + when (getQuestStage(player!!, Quests.DEATH_PLATEAU)) { + 19 -> { + when (stage) { + 0 -> player(FacialExpression.FRIENDLY, "Hello!").also { stage++ } + 1 -> npc(FacialExpression.ANNOYED, "What?!").also { stage++ } + 2 -> showTopics( + Topic(FacialExpression.THINKING, "I'm looking for the guard that was on the last night.", 10), + Topic(FacialExpression.THINKING, "Do you know of another way up Death Plateau?", 20), + Topic(FacialExpression.HALF_GUILTY, "Nothing, sorry!", END_DIALOGUE), + ) + 10 -> npcl(FacialExpression.ANNOYED,"Who?!").also { stage++ } + 11 -> npcl(FacialExpression.ANNOYED,"Buzz off!").also { stage = END_DIALOGUE } + + 20 -> npcl(FacialExpression.ANNOYED,"Why would I want to go up there? I just want to be left in peace!").also { stage++ } + 21 -> npcl(FacialExpression.ANNOYED,"It used to be just humans trampling past my cave and making a racket. Now there's those blasted trolls too! Not only do they stink and argue with each other loudly but they are always fighting the humans.").also { stage++ } + 22 -> npcl(FacialExpression.ANNOYED,"I just want to be left in peace!").also { stage++ } + 23 -> playerl(FacialExpression.FRIENDLY, "Ah... I might be able to help you.").also { stage++ } + 24 -> npcl(FacialExpression.ANNOYED,"How?!").also { stage++ } + 25 -> playerl(FacialExpression.HALF_THINKING, "I'm trying to help the...er...humans to reclaim back Death Plateau. If you help me then at least you'd be rid of the trolls.").also { stage++ } + 26 -> npcl(FacialExpression.ANNOYED,"Hmph.").also { stage++ } + 27 -> npcl(FacialExpression.ANNOYED,"Let me see...").also { stage++ } + 28 -> npcl(FacialExpression.HALF_GUILTY,"I've only been up Death Plateau once to complain about the noise but those pesky trolls started throwing rocks at me!").also { stage++ } + 29 -> npcl(FacialExpression.HALF_GUILTY,"Before the trolls came there used to be a nettlesome Sherpa that took humans exploring or something equally stupid. Perhaps he'd know another way.").also { stage++ } + 30 -> playerl(FacialExpression.FRIENDLY, "Where does this Sherpa live?").also { stage++ } + 31 -> npcl(FacialExpression.ANNOYED,"I don't know but it can't be far as he used to be around all the time!").also { + setQuestStage(player!!, Quests.DEATH_PLATEAU, 20) + stage = END_DIALOGUE } + } + } + 20 -> { + when (stage) { + 0 -> playerl(FacialExpression.FRIENDLY, "Hello.").also { stage++ } + 1 -> npcl(FacialExpression.ANNOYED, "Have you got rid of those pesky trolls yet?").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "Where did you say this Sherpa was?").also { stage++ } + 3 -> npcl(FacialExpression.ANNOYED, "I dunno but he must live around here somewhere!").also { + stage = END_DIALOGUE } + } + } + in 21 .. 26 -> { + when (stage) { + 0 -> playerl(FacialExpression.FRIENDLY, "Hello.").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "Have you got rid of those pesky trolls yet?").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "I'm working on it!").also { stage++ } + 3 -> npcl(FacialExpression.FRIENDLY, "Grr!").also { + stage = END_DIALOGUE } + } + } + } + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/SecretWayLocation.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/SecretWayLocation.kt new file mode 100644 index 0000000..96d821a --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/SecretWayLocation.kt @@ -0,0 +1,20 @@ +package content.region.asgarnia.burthorpe.quest.deathplateau + +import content.data.Quests +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.world.map.zone.ZoneBorders + +class SecretWayLocation : MapArea { + override fun defineAreaBorders(): Array { + return arrayOf(ZoneBorders(2866, 3609, 2866, 3609)) + } + + override fun areaEnter(entity: Entity) { + if (entity is Player && getQuestStage(entity, Quests.DEATH_PLATEAU) == 25) { + sendPlayerDialogue(entity, "I think this is far enough, I can see Death Plateau and it looks like the trolls haven't found the path. I'd better go and tell Denulth.") + setQuestStage(entity, Quests.DEATH_PLATEAU, 26) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/TenzingDialogueFile.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/TenzingDialogueFile.kt new file mode 100644 index 0000000..c69cb4a --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/deathplateau/TenzingDialogueFile.kt @@ -0,0 +1,144 @@ +package content.region.asgarnia.burthorpe.quest.deathplateau + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.item.Item +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.Items + +class TenzingDialogueFile : DialogueFile() { + + override fun handle(componentID: Int, buttonID: Int) { + when (getQuestStage(player!!, Quests.DEATH_PLATEAU)) { + 20 -> { + when (stage) { + START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hello!").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "Hello. How can I help?").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "I'm helping the Imperial Guard. They need to find a way to sneak up Death Plateau to destroy the troll camp! Saba seemed to think you'd be able to help.").also { stage++ } + 3 -> npcl(FacialExpression.FRIENDLY, "Ah...Saba is still alive and kicking?").also { stage++ } + 4 -> playerl(FacialExpression.FRIENDLY, "Yeh, he seemed very bitter.").also { stage++ } + 5 -> npcl(FacialExpression.FRIENDLY, "That's Saba alright!").also { stage++ } + 6 -> npcl(FacialExpression.FRIENDLY, "I do know of a secret way up to Death Plateau, the Imperial Guard would be able to use it at night and not be seen until it was too late!").also { stage++ } + 7 -> npcl(FacialExpression.FRIENDLY, "I'd be happy to show you it if you do something for me first.").also { stage++ } + 8 -> playerl(FacialExpression.FRIENDLY, "Name it.").also { stage++ } + 9 -> npcl(FacialExpression.FRIENDLY, "I don't get into town much and I'm getting low on supplies. I need ten loaves of bread and ten cooked trout, that should see me through the winter.").also { stage++ } + 10 -> playerl(FacialExpression.FRIENDLY, "Anything else?").also { stage++ } + 11 -> npcl(FacialExpression.FRIENDLY, "Yes. My climbing boots need to have new spikes, so can you take them to Dunstan in Burthorpe? He always puts my spikes on for me.").also { stage++ } + 12 -> showTopics( + Topic(FacialExpression.FRIENDLY, "OK, I'll get those for you.", 20 ), + Topic(FacialExpression.FRIENDLY, "I'll find the secret way for myself.", 30 ) + ) + 20 -> npcl(FacialExpression.FRIENDLY, "Thank you traveller!").also { stage++ } + 21 -> sendItemDialogue(player!!, Items.CLIMBING_BOOTS_3105, "Tenzing has given you his Climbing boots.").also { + addItemOrDrop(player!!, Items.CLIMBING_BOOTS_3105, 1) + setQuestStage(player!!, Quests.DEATH_PLATEAU, 21) + stage = END_DIALOGUE + } + 30 -> npcl(FacialExpression.ANNOYED, "Hmph.").also { stage = END_DIALOGUE } + } + } + in 21 .. 23 -> { + when (stage) { + START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hello!").also { + if (inInventory(player!!, Items.CLIMBING_BOOTS_3105) || inInventory(player!!, Items.SPIKED_BOOTS_3107)) { + stage = 1 + } else { + stage = 5 + } + } + 1 -> npcl(FacialExpression.FRIENDLY, "Has Dunstan added spikes to my climbing boots yet?").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "No, not yet.").also { stage++ } + 3 -> npcl(FacialExpression.FRIENDLY, "Well, when he has, bring the boots to me with ten loaves of bread and ten cooked trout. I have to prepare for the winter, after all.").also { + stage = END_DIALOGUE + } + 5 -> npcl(FacialExpression.FRIENDLY, "Have you brought me the items I asked for?").also { stage++ } + 6 -> playerl(FacialExpression.FRIENDLY, "I've lost the climbing boots.").also { stage++ } + 7 -> npcl(FacialExpression.FRIENDLY, "These are expensive, do not lose another pair!").also { stage++ } + 8 -> sendItemDialogue(player!!, Items.CLIMBING_BOOTS_3105, "Tenzing has given you his Climbing boots.").also { + addItemOrDrop(player!!, Items.CLIMBING_BOOTS_3105, 1) + stage = END_DIALOGUE + } + } + } + 24 -> { + when (stage) { + START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hello!").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "Have you brought me the items I asked for?").also { + if (inInventory(player!!, Items.SPIKED_BOOTS_3107) && inInventory(player!!, Items.BREAD_2309, 10) && inInventory(player!!, Items.TROUT_333, 10)) { + stage = 3 + } else { + stage = 2 + } + } + 2 -> playerl(FacialExpression.FRIENDLY, "I don't have the:" + + (if(!inInventory(player!!, Items.SPIKED_BOOTS_3107)) " Spiked boots." else "") + + (if(!inInventory(player!!, Items.BREAD_2309, 10)) " Ten loaves of bread." else "") + + (if(!inInventory(player!!, Items.TROUT_333, 10)) " Ten cooked trout." else "") + ).also { + stage = END_DIALOGUE + } + 3 -> sendItemDialogue(player!!, Items.SPIKED_BOOTS_3107, "You give Tenzing the Spiked boots.").also { + if (removeItem(player!!, Item(Items.SPIKED_BOOTS_3107))) { + stage++ + } else { + stage = END_DIALOGUE + } + } + 4 -> sendDoubleItemDialogue(player!!, Items.BREAD_2309, Items.TROUT_333, "You give Tenzing the loaves of bread and the cooked trout.").also { + if (removeItem(player!!, Item(Items.BREAD_2309, 10)) && removeItem(player!!, Item(Items.TROUT_333, 10)) ) { + stage++ + } else { + stage = END_DIALOGUE + } + } + 5 -> npcl(FacialExpression.FRIENDLY, "Thank you very much traveller. I'm now ready for the winter!").also { stage++ } + 6 -> playerl(FacialExpression.FRIENDLY, "You said you would show me the secret way to Death Plateau?").also { stage++ } + 7 -> npcl(FacialExpression.FRIENDLY, "Yes, of course! I drew up a map in case I ever needed to use it again.").also { stage++ } + 8 -> sendDialogue(player!!, "Tenzing has given you a map of the secret way!").also { + addItemOrDrop(player!!, Items.SECRET_WAY_MAP_3104) + stage++ + } + 9 -> npcl(FacialExpression.FRIENDLY, "I don't think the Trolls have found the secret way yet, if they had I would've been attacked by now.").also { stage++ } + 10 -> playerl(FacialExpression.FRIENDLY, "OK thanks but I think I'd better check the path. I don't want to send the Imperial Guards to their death!").also { stage++ } + 11 -> npcl(FacialExpression.FRIENDLY, "You are wise for one so young.").also { + setQuestStage(player!!, Quests.DEATH_PLATEAU, 25) + stage = END_DIALOGUE + } + } + } + in 25.. 29 -> { + when (stage) { + START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hello Tenzing!").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "Hello again traveller. What can I do for you?").also { + if (inInventory(player!!, Items.SECRET_WAY_MAP_3104)) { + stage = 10 + } else { + stage = 2 + } + } + 2 -> playerl(FacialExpression.FRIENDLY, "I've lost the secret way map.").also { stage++ } + 3 -> npcl(FacialExpression.FRIENDLY, "Never mind. I'll quickly draw you another one.").also { stage++ } + 4 -> sendDialogue(player!!, "Tenzing has given you a map of the secret way!").also { + addItemOrDrop(player!!, Items.SECRET_WAY_MAP_3104) + stage = END_DIALOGUE + } + + 10 -> showTopics( + Topic(FacialExpression.FRIENDLY, "I'm lost!", 20 ), + Topic(FacialExpression.FRIENDLY, "Nothing, thanks.", 30 ) + ) + + 20 -> npcl(FacialExpression.FRIENDLY, "To get back to Burthorpe follow the path going east.").also { stage++ } + 21 -> npcl(FacialExpression.FRIENDLY, "I thought you were going to investigate the secret way to Death Plateau? Use the back door to my hut, hop over the stile and follow that path.").also { stage++ } + 22 -> playerl(FacialExpression.FRIENDLY, "Oh yes, of course! Thanks!").also { stage = END_DIALOGUE } + + 30 -> npcl(FacialExpression.FRIENDLY, "Go in peace traveller.").also { stage = END_DIALOGUE } + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/AchiettiesDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/AchiettiesDialogue.kt new file mode 100644 index 0000000..be02fd7 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/AchiettiesDialogue.kt @@ -0,0 +1,180 @@ +package content.region.asgarnia.burthorpe.quest.heroesquest + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class AchiettiesDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, AchiettiesDialogueFile(), npc) + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return AchiettiesDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.ACHIETTIES_796) + } +} + +class AchiettiesDialogueFile : DialogueBuilderFile() { + + override fun create(b: DialogueBuilder) { + + b.onQuestStages(Quests.HEROES_QUEST, 0,1) + .branch { player -> + return@branch getQuestStage(player, Quests.HEROES_QUEST) + }.let{ branch -> + branch.onValue(0) + .npcl(FacialExpression.FRIENDLY, "Greetings. Welcome to the Heroes' Guild.") + .npcl("Only the greatest heroes of this land may gain entrance to this guild.") + // - If the player's skill levels are lower than the quest requirements. (I think this is after 2009) + // linel("Before starting this quest, be aware that one or more of your skill levels are lower than what is required to fully complete it.") + .options() + .let { optionBuilder -> + optionBuilder.option("I'm a hero, may I apply to join?") + .playerl("I'm a hero. May I apply to join?") + .branch { player -> + return@branch if (HeroesQuest.hasRequirements(player)) { + 1 + } else { + 0 + } + }.let { branch -> + branch.onValue(0) + .npcl("You're a hero? I've never heard of YOU. You are required to possess at least 55 quest points to file an application.") + .npcl("Additionally you must have completed the Shield of Arrav, Lost City, Merlin's Crystal and Dragon Slayer quests.") + .end() + return@let branch + }.onValue(1) + .betweenStage { df, player, _, _ -> + if(getQuestStage(player, Quests.HEROES_QUEST) == 0) { + setQuestStage(player, Quests.HEROES_QUEST, 1) + } + } + .npcl("Well you seem to meet our initial requirements, so you may now begin the tasks to earn membership in the Heroes' Guild.") + .npcl("The three items required for entrance are: An Entranan Firebird feather, a Master Thieves' armband, and a cooked Lava Eel.") + .options() + .let { optionBuilder2 -> + optionBuilder2.option_playerl("Any hints on getting the thieves armband?") + .npcl("I'm sure you have the relevant contacts to find out about that.") + .end() + optionBuilder2.option_playerl("Any hints on getting the feather?") + .npcl("Not really - other than Entranan firebirds tend to live on Entrana.") + .end() + optionBuilder2.option_playerl("Any hints on getting the eel?") + .npcl("Maybe go and find someone who knows a lot about fishing?") + .end() + optionBuilder2.option_playerl("I'll start looking for all those things then.") + .npcl("Good luck with that.") + .end() + } + + optionBuilder.option_playerl("Good for the foremost heroes of the land.") + .npcl("Yes. Yes it is.") + .end() + } + branch.onValue(1) + .npcl("Greetings. Welcome to the Heroes' Guild.") + .npcl("How goes thy quest adventurer?") + .playerl("It's tough. I've not done it yet.") + .npcl("Remember, the items you need to enter are:") + .npcl("An Entranan Firebirds' feather, A Master Thieves armband, and a cooked Lava Eel.") + .options() + .let { optionBuilder2 -> + optionBuilder2.option_playerl("Any hints on getting the thieves armband?") + .npcl("I'm sure you have the relevant contacts to find out about that.") + .end() + optionBuilder2.option_playerl("Any hints on getting the feather?") + .npcl("Not really - other than Entranan firebirds tend to live on Entrana.") + .end() + optionBuilder2.option_playerl("Any hints on getting the eel?") + .npcl("Maybe go and find someone who knows a lot about fishing?") + .end() + optionBuilder2.option_playerl("I'll start looking for all those things then.") + .npcl("Good luck with that.") + .end() + } + } + + b.onQuestStages(Quests.HEROES_QUEST, 2, 3, 4) + .npcl("Greetings. Welcome to the Heroes' Guild.") + .npcl("How goes thy quest adventurer?") + .playerl("It's tough. I've not done it yet.") + .npcl("Remember, the items you need to enter are:") + .npcl("An Entranan Firebirds' feather, A Master Thieves armband, and a cooked Lava Eel.") + .options() + .let { optionBuilder2 -> + optionBuilder2.option_playerl("Any hints on getting the thieves armband?") + .npcl("I'm sure you have the relevant contacts to find out about that.") + .end() + optionBuilder2.option_playerl("Any hints on getting the feather?") + .npcl("Not really - other than Entranan firebirds tend to live on Entrana.") + .end() + optionBuilder2.option_playerl("Any hints on getting the eel?") + .npcl("Maybe go and find someone who knows a lot about fishing?") + .end() + optionBuilder2.option_playerl("I'll start looking for all those things then.") + .npcl("Good luck with that.") + .end() + } + + b.onQuestStages(Quests.HEROES_QUEST, 6) + .npcl("Greetings. Welcome to the Heroes' Guild.") + .npcl("How goes thy quest adventurer?") + .branch { player -> + return@branch if (HeroesQuest.allItemsInInventory(player)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(0) + .playerl("It's tough. I've not done it yet.") + .npcl("Remember, the items you need to enter are:") + .npcl("An Entranan Firebirds' feather, A Master Thieves armband, and a cooked Lava Eel.") + .options() + .let { optionBuilder2 -> + optionBuilder2.option_playerl("Any hints on getting the thieves armband?") + .npcl("I'm sure you have the relevant contacts to find out about that.") + .end() + optionBuilder2.option_playerl("Any hints on getting the feather?") + .npcl("Not really - other than Entranan firebirds tend to live on Entrana.") + .end() + optionBuilder2.option_playerl("Any hints on getting the eel?") + .npcl("Maybe go and find someone who knows a lot about fishing?") + .end() + optionBuilder2.option_playerl("I'll start looking for all those things then.") + .npcl("Good luck with that.") + .end() + } + + branch.onValue(1) + .playerl("I have all the required items.") + .npcl("I see that you have. Well done. Now, to complete the quest, and gain entry to the Heroes' Guild in your final task all that you have to do is...") + .playerl("W-what? What do you mean? There's MORE?") + .npcl("I'm sorry, I was just having a little fun with you. Just a little Heroes' Guild humour there. What I really meant was") + .npcl("Congratulations! You have completed the Heroes' Guild entry requirements! You will find the door now open for you! Enter, Hero! And take this reward!") + .endWith { _, player -> + if (HeroesQuest.allItemsInInventory(player)) { + removeItem(player, Items.FIRE_FEATHER_1583) + removeItem(player, Items.LAVA_EEL_2149) + removeItem(player, Items.THIEVES_ARMBAND_1579) + if (getQuestStage(player, Quests.HEROES_QUEST) == 6) { + finishQuest(player, Quests.HEROES_QUEST) + } + } + } + } + + b.onQuestStages(Quests.HEROES_QUEST, 100) + .npcl("Greetings. Welcome to the Heroes' Guild.") + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/AlfonseTheWaiterDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/AlfonseTheWaiterDialogue.kt new file mode 100644 index 0000000..efb262b --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/AlfonseTheWaiterDialogue.kt @@ -0,0 +1,62 @@ +package content.region.asgarnia.burthorpe.quest.heroesquest + +import content.data.Quests +import core.api.getQuestStage +import core.api.openDialogue +import core.api.openNpcShop +import core.api.setQuestStage +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class AlfonseTheWaiterDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return AlfonseTheWaiterDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, AlfonseTheWaiterDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.ALFONSE_THE_WAITER_793) + } +} +class AlfonseTheWaiterDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + + b.onPredicate { _ -> true } + .npc("Welcome to the Shrimp and Parrot.", "Would you like to order, sir?") + .options() + .let { optionBuilder -> + optionBuilder.option_playerl("Yes please.") + .endWith { _, player -> + openNpcShop(player, npc!!.id) + } + + optionBuilder.option_playerl("No thank you.") + .end() + + optionBuilder.optionIf("Do you sell Gherkins?"){ player -> return@optionIf getQuestStage( + player, + Quests.HEROES_QUEST + ) >= 2 && HeroesQuest.isPhoenix(player) } + .playerl("Do you sell Gherkins?") + .npc("Hmmmm Gherkins eh? Ask Charlie the cook, round the", "back. He may have some 'gherkins' for you!") + .linel("Alfonse winks at you.") + .endWith { _, player -> + if(getQuestStage(player, Quests.HEROES_QUEST) == 2) { + setQuestStage(player, Quests.HEROES_QUEST, 3) + } + } + + optionBuilder.option("Where do you get your Karambwan from?") + .npc("We buy directly off Lubufu, a local fisherman. He", "seems to have a monopoly over Karambwan sales.") + .end() + + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/CharlieTheCookDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/CharlieTheCookDialogue.kt new file mode 100644 index 0000000..2bd65f8 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/CharlieTheCookDialogue.kt @@ -0,0 +1,84 @@ +package content.region.asgarnia.burthorpe.quest.heroesquest + +import content.data.Quests +import core.api.getQuestStage +import core.api.openDialogue +import core.api.setQuestStage +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class CharlieTheCookDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return CharlieTheCookDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, CharlieTheCookDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.CHARLIE_THE_COOK_794) + } +} +class CharlieTheCookDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onPredicate { _ -> true } + .npc(FacialExpression.ANGRY, "Hey! What are you doing back here?") + .options() + .let { optionBuilder -> + val continuePath = b.placeholder() + + optionBuilder.optionIf("I'm looking for a gherkin...") { player -> return@optionIf getQuestStage(player, Quests.HEROES_QUEST) >= 3 && HeroesQuest.isPhoenix(player) } + .playerl("I'm looking for a gherkin...") + .goto(continuePath) + + optionBuilder.optionIf("I'm a fellow member of the Phoenix Gang.") { player -> return@optionIf getQuestStage(player, Quests.HEROES_QUEST) >= 3 && HeroesQuest.isPhoenix(player) } + .playerl("I'm a fellow member of the Phoenix Gang.") + .goto(continuePath) + + optionBuilder.option_playerl("Just exploring.") + .npcl(FacialExpression.ANGRY, "Well, get out! This kitchen isn't for exploring. It's a private establishment! It's out of bounds to customers!") + .end() + + return@let continuePath.builder() + } + .npcl("Ah, a fellow Phoenix! So, tell me compadre... What brings you to sunny Brimhaven?") + .options() + .let { optionBuilder -> + optionBuilder.option_playerl("Sun, sand, and the fresh sea air!") + .playerl("Sun, sand, and the fresh sea air!") + .npcl("Well, can't say I blame you, compadre. I used to be a city boy myself, but have to admit it's a lot nicer living here nowadays. Brimhaven's certainly good for it.") + .playerl("I also want to steal Scarface Pete's candlesticks.") + .npcl("Ah yes, of course. The candlesticks. Well, I have to be honest with you, compadre, we haven't made much progress in that task ourselves so far.") + .npcl("We can however offer a little assistance. Setting up this restaurant was the start of things; we have a secret door out the back of here that leads through the back of Cap'n Arnav's garden.") + .npcl("Now, at the other side of Cap'n Arnav's garden, is an old side entrance to Scarface Pete's mansion. It seems to have been blocked off from the rest of the mansion some years ago and we can't seem to find a way through.") + .npcl("We're positive this is the key to entering the house undetected, however, and I promise to let you know if we find anything there.") + .playerl("Mind if I check it out for myself?") + .npcl("Not at all! The more minds we have working on the problem, the quicker we get that loot!") + .endWith { _, player -> + if (getQuestStage(player, Quests.HEROES_QUEST) == 3) { + setQuestStage(player, Quests.HEROES_QUEST, 4) + } + } + + optionBuilder.option_playerl("I want to steal Scarface Pete's candlesticks.") + .npcl("Ah yes, of course. The candlesticks. Well, I have to be honest with you, compadre, we haven't made much progress in that task ourselves so far.") + .npcl("We can however offer a little assistance. Setting up this restaurant was the start of things; we have a secret door out the back of here that leads through the back of Cap'n Arnav's garden.") + .npcl("Now, at the other side of Cap'n Arnav's garden, is an old side entrance to Scarface Pete's mansion. It seems to have been blocked off from the rest of the mansion some years ago and we can't seem to find a way through.") + .npcl("We're positive this is the key to entering the house undetected, however, and I promise to let you know if we find anything there.") + .playerl("Mind if I check it out for myself?") + .npcl("Not at all! The more minds we have working on the problem, the quicker we get that loot!") + .endWith { _, player -> + if (getQuestStage(player, Quests.HEROES_QUEST) == 3) { + setQuestStage(player, Quests.HEROES_QUEST, 4) + } + } + } + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/GarvDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/GarvDialogue.kt new file mode 100644 index 0000000..dc94334 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/GarvDialogue.kt @@ -0,0 +1,72 @@ +package content.region.asgarnia.burthorpe.quest.heroesquest + +import content.data.Quests +import core.api.* +import core.game.dialogue.* +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class GarvDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, GarvDialogueFile(), npc) + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return GarvDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.GARV_788) + } +} + +class GarvDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + // Technically this won't happen since you have to get past Grubor. + b.onQuestStages(Quests.HEROES_QUEST, 0, 1, 2) + .npcl("Hello. What do you want?") + .options() + .let { optionBuilder -> + optionBuilder.option_playerl("Can I go in there?") + .npcl("No. In there is private.") + .end() + optionBuilder.option_playerl("I want for nothing!") + .npcl("You're one of a very lucky few then.") + .end() + } + + b.onQuestStages(Quests.HEROES_QUEST, 3, 4, 5, 6, 100) + // .npcl("Oi! Where do you think you're going pal?") - When you click on the door instead of Garv. + .npcl("Hello. What do you want?") + .playerl("Hi. I'm Hartigen. I've come to work here.") + .branch { player -> + return@branch if (inEquipment(player, Items.BLACK_FULL_HELM_1165) && inEquipment(player, Items.BLACK_PLATEBODY_1125) && inEquipment(player, Items.BLACK_PLATELEGS_1077)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(1) + .npcl("I assume you have your I.D. papers then?") + .branch { player -> + return@branch if (inInventory(player, Items.ID_PAPERS_1584)) { 1 } else { 0 } + }.let { branch2 -> + branch2.onValue(1) + .npcl("You'd better come in then, Grip will want to talk to you.") + .endWith { _, player -> + if(getQuestStage(player, Quests.HEROES_QUEST) == 3) { + setQuestStage(player, Quests.HEROES_QUEST, 4) + } + } + branch2.onValue(0) + .playerl("Uh... Yeah. About that...I must have left them in my other suit of armour.") + .end() + } + branch.onValue(0) + .npcl("Hartigen the Black Knight? I don't think so. He doesn't dress like that.") + .end() + } + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/GerrantDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/GerrantDialogue.kt new file mode 100644 index 0000000..c106acd --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/GerrantDialogue.kt @@ -0,0 +1,66 @@ +package content.region.asgarnia.burthorpe.quest.heroesquest + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class GerrantDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return GerrantDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, GerrantDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.GERRANT_558) + } +} +class GerrantDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + + b.onPredicate { _ -> true } + .npc(FacialExpression.HAPPY, "Welcome! You can buy fishing equipment at my store.", "We'll also buy anything you catch off you.") + .options() + .let { optionBuilder -> + optionBuilder.option_playerl("Let's see what you've got then.") + .endWith { _, player -> + openNpcShop(player, npc!!.id) + } + + optionBuilder.option_playerl("Sorry, I'm not interested.") + .end() + + optionBuilder.optionIf("I want to find out how to catch a lava eel.") { player -> return@optionIf getQuestStage(player, Quests.HEROES_QUEST) >= 1 } + .playerl("I want to find out how to catch a lava eel.") + .npcl("Lava eels, eh? That's a tricky one, that is. You'll need a lava-proof fishing rod. The method for making this would be to take an ordinary fishing rod, and then cover it with fire-proof blamish oil.") + .branch { player -> + return@branch if (inInventory(player, Items.BLAMISH_SNAIL_SLIME_1581)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(1) + .npcl("Of course, you knew that already.") + .playerl("So where can I fish lava eels?") + .npcl("Taverley dungeon or the lava maze in the Wilderness.") + .end() + + branch.onValue(0) + .npcl("You know... thinking about it... I may have a jar of blamish slime around here somewhere. Now where did I put it?") + .linel("Gerrant searches around a bit.") + .betweenStage { df, player, _, _ -> + addItemOrDrop(player, Items.BLAMISH_SNAIL_SLIME_1581) + } + .npcl("Aha! Here it is! Take this slime, mix it with some Harralander and water and you'll have the blamish oil you need to treat your fishing rod.") + .end() + } + + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/GripBehavior.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/GripBehavior.kt new file mode 100644 index 0000000..62d72dc --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/GripBehavior.kt @@ -0,0 +1,59 @@ +package content.region.asgarnia.burthorpe.quest.heroesquest + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.node.entity.Entity +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import core.game.node.item.GroundItem +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class GripBehavior : NPCBehavior(NPCs.GRIP_792) { + // Attacking Grip + override fun canBeAttackedBy(self: NPC, attacker: Entity, style: CombatStyle, shouldSendMessage: Boolean): Boolean { + // You cannot attack if you are a black arm gang member. + if (attacker is Player && HeroesQuest.isBlackArm(attacker)) { + openDialogue(attacker, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + //"I can't attack the head guard here! There are too", "many witnesses around to see me do it! I'd have the", "whole of Brimhaven after me! Besides, if he dies I want", "the promotion!" + START_DIALOGUE -> sendPlayerDialogue(attacker, "I can't attack the head guard here! There are too many witnesses around to see me do it! I'd have the whole of Brimhaven after me! Besides, if he dies I want the promotion!") .also { stage++ } + 1 -> sendDialogueLines(attacker, "Perhaps you need another player's help...?").also { + stage = END_DIALOGUE + } + } + } + }) + return false + } + return true + } + + override fun onDeathFinished(self: NPC, killer: Entity) { + if (killer is Player) { + if (getQuestStage(killer, Quests.HEROES_QUEST) == 4) { + setQuestStage(killer, Quests.HEROES_QUEST, 5) + } + + val gi = GroundItem( + Item(Items.GRIPS_KEY_RING_1588), + self.location, + 5000, + null, + ) + gi.forceVisible = true + gi.isRemainPrivate = false + + val gim = GroundItemManager.create(gi) + gim.isRemainPrivate = false + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/GripDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/GripDialogue.kt new file mode 100644 index 0000000..4146b03 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/GripDialogue.kt @@ -0,0 +1,118 @@ +package content.region.asgarnia.burthorpe.quest.heroesquest + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class GripDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, GripDialogueFile(), npc) + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return GripDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.GRIP_792) + } +} + +class GripDialogueFile : DialogueBuilderFile() { + + override fun create(b: DialogueBuilder) { + b.onPredicate { _ -> true } + .branch { player -> + return@branch if (getAttribute(player, HeroesQuest.attributeGripTookPapers, false)) { 1 } else { 0 } + }.let { branch -> + val continuePath = b.placeholder() + branch.onValue(1) + .goto(continuePath) + branch.onValue(0) + .playerl("Hi there. I am Hartigen, reporting for duty as your new deputy sir!") + .npcl("Ah good, at last. You took your time getting here! Now let me see...") + .npcl("I'll get your hours and duty roster sorted out in a while. Oh, and do you have your I.D. papers with you? Internal security is almost as important as external security for a guard.") + .branch { player -> + return@branch if (inInventory(player, Items.ID_PAPERS_1584)) { 1 } else { 0 } + }.let { branch -> + val continuePath2 = b.placeholder() + branch.onValue(1) + .playerl("Right here sir!") + .linel("You hand the ID papers over to Grip.") + .betweenStage { df, player, _, _ -> + if (removeItem(player, Items.ID_PAPERS_1584)) { + setAttribute(player, HeroesQuest.attributeGripTookPapers, true) + } + } + .goto(continuePath2) + branch.onValue(0) + .playerl("Oh, dear. I don't have that with me any more.") + .npcl("Well, that's no good! Go get them immediately, then report back for duty.") + .end() + return@let continuePath2.builder() + } + .goto(continuePath) + return@let continuePath.builder() + } + .options() + .let { optionBuilder -> + val returnJoin = b.placeholder() + + optionBuilder.option_playerl("So can I please guard the treasure room please?") + .npcl("Well, I might post you outside it sometimes. I prefer to be the only one allowed inside however.") + .npcl("There's some pretty valuable artefacts in there! Those keys stay ONLY with the head guard and Scarface Pete.") + .goto(returnJoin) + + optionBuilder.optionIf("So what do my duties involve?") { player -> + return@optionIf !getAttribute(player, HeroesQuest.attributeGripSaidDuties, false) + } + .betweenStage { _, player, _, _ -> + setAttribute(player, HeroesQuest.attributeGripSaidDuties, true) + } + .playerl("So what do my duties involve?") + .npcl("You'll have various guard related duties on various shifts. I'll assign specific duties as they are required as and when they become necessary. Just so you know, if anything happens to me") + .npcl("you'll need to take over as head guard here. You'll find important keys to the treasure room and Pete's quarters inside my jacket - although I doubt anything bad's going to happen to") + .npcl("me anytime soon!") + .linel("Grip laughs to himself at the thought.") + .goto(returnJoin) + + optionBuilder.option_playerl("Well, I'd better sort my new room out.") + .npcl("Yeah, I'll give you time to settle in. Better get a good night's sleep, I expect you to report for duty at oh five hundred hours tomorrow on the dot!") + .end() + + + optionBuilder.optionIf("Anything I can do now?") { player -> + return@optionIf getAttribute(player, HeroesQuest.attributeGripSaidDuties, false) + } + .playerl("Anything I can do now?") + .branch { player -> + return@branch if (inInventory(player, Items.MISCELLANEOUS_KEY_1586)) { + 1 + } else { + 0 + } + }.let { branch -> + branch.onValue(1) + .npcl("Can't think of anything right now.") + .end() + + branch.onValue(0) + .npcl("Hmm. Well, you could find out what this key opens for me. Apparently it's for something in this building, but for the life of me I can't find what.") + .linel("Grip hands you a key.") + .endWith { _, player -> + addItemOrDrop(player, Items.MISCELLANEOUS_KEY_1586) + } + } + + returnJoin.builder() + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/GruborDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/GruborDialogue.kt new file mode 100644 index 0000000..958d893 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/GruborDialogue.kt @@ -0,0 +1,87 @@ +package content.region.asgarnia.burthorpe.quest.heroesquest + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class GruborDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return GruborDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, GruborDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.GRUBOR_789) + } +} + +class GruborDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + + b.onPredicate { player -> + getQuestStage(player, Quests.HEROES_QUEST) >= 2 && + getAttribute(player, HeroesQuest.attributeGruborLetsYouIn, false) && + HeroesQuest.isBlackArm(player) + } + .playerl("Hi.") + .npcl("Hi, I'm a little busy right now.") + .end() + + b.onPredicate { player -> + getQuestStage(player, Quests.HEROES_QUEST) >= 2 && + !getAttribute(player, HeroesQuest.attributeGruborLetsYouIn, false) && + HeroesQuest.isBlackArm(player) + } + .npcl(FacialExpression.THINKING, "Yes? What do you want?") + .options() + .let { optionBuilder -> + + optionBuilder.option_playerl("Rabbit's foot.") + .npcl("Eh? What are you on about? Go away!") + .end() + + optionBuilder.option_playerl("Four leaved clover.") + .npcl("Oh you're one of the gang are you? Ok, hold up a second, I'll just let you in through here.") + .linel("You hear the door being unbarred from inside.") + .endWith { _, player -> + setAttribute(player, HeroesQuest.attributeGruborLetsYouIn, true) + } + + optionBuilder.option_playerl("Lucky horseshoe.") + .npcl("Eh? What are you on about? Go away!") + .end() + + optionBuilder.option_playerl("Black cat.") + .npcl("Eh? What are you on about? Go away!") + .end() + } + + + b.onPredicate { _ -> true } + .npcl(FacialExpression.THINKING, "Yes? What do you want?") + .options() + .let { optionBuilder -> + + optionBuilder.option_playerl("Would you like your hedges trimming?") + .npcl("Eh? Don't be daft! We don't even HAVE any hedges!") + .end() + + optionBuilder.option_playerl("I want to come in.") + .npcl("No, go away.") + .end() + + optionBuilder.option_playerl("Do you want to trade?") + .npcl("No, I'm busy.") + .end() + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/HeroesQuest.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/HeroesQuest.kt new file mode 100644 index 0000000..7eadbf5 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/HeroesQuest.kt @@ -0,0 +1,262 @@ +package content.region.asgarnia.burthorpe.quest.heroesquest + +import content.data.Quests +import content.region.misthalin.varrock.quest.shieldofarrav.ShieldofArrav +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import org.rs09.consts.Items + +/** + * Heroes' Quest + */ +@Initializable +class HeroesQuest : Quest(Quests.HEROES_QUEST,75, 74, 1, 188, 0, 1, 15) { + /** + * Do note: "other players can help you even if they have already finished Heroes' Quest" + * 1 - Talked to Achietties to start the quest + * + * PHOENIX + * 2 - Talked to Katrine + * 3 - Talked to Alfonse + * 4 - Talked to Charlie + * 5 - HIDDEN Killed Grip (You need key from Black Arm Friend) + * 6 - Talked to Katrine with Candlestick + * BLACK ARM + * 2 - Talked to Straven + * 3 - Talked to Trobert + * 4 - Talked to Garv + * 5 - HIDDEN Unlocked Chest (You need Grip killed from Phoenix Friend) + * 6 - Talked to Katrine with Candlestick + * + * 100 - Achiettes with all the items + */ + + companion object { + const val attributeGruborLetsYouIn = "/save:quest:heroesquest-gruborletsyouin" + const val attributeGripTookPapers = "/save:quest:heroesquest-griptookpapers" + const val attributeGripSaidDuties = "/save:quest:heroesquest-gripsaidduties" + const val attributeHasOpenedBackdoor = "/save:quest:heroesquest-hasopenedbackdoor" + const val attributeHasOpenedChestDoor = "/save:quest:heroesquest-hasopenedchestdoor" + + fun checkQuestsAreComplete(player: Player): Boolean { + return isQuestComplete(player, Quests.SHIELD_OF_ARRAV) && + isQuestComplete(player, Quests.LOST_CITY) && + isQuestComplete(player, Quests.MERLINS_CRYSTAL) && + isQuestComplete(player, Quests.DRAGON_SLAYER) && + getQuestPoints(player) >= 55 + } + + /** Abstraction of Shield of Arrav isPhoenix function */ + fun isPhoenix(player: Player): Boolean { + return ShieldofArrav.isPhoenix(player) + } + + /** Abstraction of Shield of Arrav isBlackArm function */ + fun isBlackArm(player: Player): Boolean { + return ShieldofArrav.isBlackArm(player) + } + + fun hasRequirements(player: Player): Boolean { + return arrayOf( + hasLevelStat(player, Skills.HERBLORE, 25), + hasLevelStat(player, Skills.MINING, 50), + hasLevelStat(player, Skills.FISHING, 53), + hasLevelStat(player, Skills.COOKING, 53), + isQuestComplete(player, Quests.SHIELD_OF_ARRAV), + isQuestComplete(player, Quests.LOST_CITY), + isQuestComplete(player, Quests.MERLINS_CRYSTAL), + isQuestComplete(player, Quests.DRAGON_SLAYER), + getQuestPoints(player) >= 55, + ).all { it } + } + + fun allItemsInInventory(player: Player): Boolean { + return inInventory(player, Items.FIRE_FEATHER_1583) && + inInventory(player, Items.LAVA_EEL_2149) && + inInventory(player, Items.THIEVES_ARMBAND_1579) + } + } + + override fun drawJournal(player: Player?, stage: Int) { + super.drawJournal(player, stage) + var line = 12 + var stage = getStage(player) + + var started = getQuestStage(player!!, Quests.HEROES_QUEST) > 0 + + if(!started){ + if (checkQuestsAreComplete(player)) { + line(player, "I can start this quest by speaking to !!Achietties?? at the", line++) + line(player, "!!Heroes' Guild?? located !!North?? of !!Taverly??", line++) + line(player, "as all required quests are complete, and I have enough QP.", line++) + } else { + line(player, "I can start this quest by speaking to !!Achietties?? at the", line++) + line(player, "!!Heroes' Guild?? located !!North?? of !!Taverly?? after completing", line++) + line(player, "!!The Shield of Arrav??", line++, isQuestComplete(player, Quests.SHIELD_OF_ARRAV)) + line(player, "!!The Lost City??", line++, isQuestComplete(player, Quests.LOST_CITY)) + line(player, "!!Merlin's Crystal??", line++, isQuestComplete(player, Quests.MERLINS_CRYSTAL)) + line(player, "!!The Dragon Slayer??", line++, isQuestComplete(player, Quests.DRAGON_SLAYER)) + line(player, "!!and gaining 55 Quest Points??", line++, getQuestPoints(player) >= 55) + } + line(player, "To complete this quest I need:", line++, false) + line(player, "!!Level 25 Herblore??", line++, hasLevelStat(player, Skills.HERBLORE, 25)) + line(player, "!!Level 50 Mining??", line++, hasLevelStat(player, Skills.MINING, 50)) + line(player, "!!Level 53 Fishing??", line++, hasLevelStat(player, Skills.FISHING, 53)) + line(player, "!!Level 53 Cooking??", line++, hasLevelStat(player, Skills.COOKING, 53)) + } else if (stage < 100) { + line(player, "!!Achietties?? will let me into the !!Heroes' Guild?? if I can get:", line++) + + // This is completely dependent on what you have in your inventory. + if (inInventory(player, Items.FIRE_FEATHER_1583)) { + line(player, "An Entranan Firebird Feather - I now have one on me!", line++, true) + } else { + line(player, "An !!Entranan Firebird Feather?? - I should check on !!Entrana??", line++) + } + + // This is completely dependent on what you have in your inventory. + if (inInventory(player, Items.LAVA_EEL_2149)) { + line(player, "A cooked lava eel - I now have one on me!", line++, true) + } else { + line(player, "A !!cooked lava eel?? - I should speak to a !!Fishing Expert??", line++) + } + + if (isPhoenix(player)) { + if (inInventory(player, Items.THIEVES_ARMBAND_1579)) { + line(player, "A Master Thieves Armband - I now have one on me!", line++, true) + } else { + line(player, "A !!Master Thieves Armband?? - the !!Phoenix Gang can help me??", line++) + } + + if (!inInventory(player, Items.THIEVES_ARMBAND_1579)) { + if (stage >= 2) { + line(player, "I spoke to Straven about the Master Thieves Armband.", line++, true) + } + + if (stage >= 3) { + line(player, "Then I told Alfonse the password 'Gherkin'.", line++, true) + } else if (stage >= 2) { + line(player, "He told me I can get one by stealing !!Pete's Candlestick??", line++) + line(player, "I should use the password he gave me at !!Brimhaven??", line++) + } + + if (stage >= 4) { + line(player, "Charlie told me about a secret door into Scarface Pete's", line++, true) + line(player, "hideout, but he couldn't find a way of getting through it.", line++, true) + } else if (stage >= 3) { + line(player, "He said, secretly speak to !!Charlie?? round the back.", line++) + } + + if (stage >= 6) { + line(player, "A rival gang member collected a candlestick for me after I", line++, true) + line(player, "killed Grip and got the Treasure Room key for them.", line++, true) + line(player, "I gave Straven Scarface Pete's candlestick, and in reward", line++, true) + line(player, "he gave me a Master Thieves Armband to prove my skills.", line++, true) + } else if (stage >= 4) { + line(player, "Maybe !!another player?? can help to get through this !!door???.", line++) + } + } + } + if (isBlackArm(player)) { + if (inInventory(player, Items.THIEVES_ARMBAND_1579)) { + line(player, "A Master Thieves Armband - I now have one on me!", line++, true) + } else { + line(player, "A !!Master Thieves Armband?? - the !!Black Arms can help me??", line++) + } + + if (!inInventory(player, Items.THIEVES_ARMBAND_1579)) { + if (stage >= 2) { + line(player, "I spoke to Katrine about the Master Thieves Armband.", line++, true) + } + + if (stage >= 3) { + line(player, "I used the Black Arm password to enter the Brimhaven HQ.", line++, true) + } else if (stage >= 2) { + line(player, "She told me I can get one by stealing !!Pete's Candlestick??", line++) + line(player, "I should use the password she gave me at !!Brimhaven??", line++) + } + + if (stage >= 4) { + line(player, "I managed to pass myself off as Hartigen and enter the", line++, true) + line(player, "HQ.", line++, true) + } else if (stage >= 3) { + line(player, "I need to disguise myself as !!Hartigen the Black Knight?? in", line++) + line(player, "order to get inside !!Scarface Pete's hideout??", line++) + } + + if (stage >= 6) { + line(player, "I collected the candlesticks with the Treasure Room key", line++, true) + line(player, "after a rival gang member killed Grip.", line++, true) + line(player, "I gave Katrine Scarface Pete's candlestick, and in reward", line++, true) + line(player, "she gave me a Master Thieves Armband to prove my skills.", line++, true) + } else if (stage >= 4) { + line(player, "I can move around the hideout, but now I need Grips keys", line++) + line(player, "to get into the treasure room and get the candlesticks.", line++) + line(player, "I need !!another player's help?? with this, as it's so risky.", line++) + } + } + } + + if (allItemsInInventory(player)) { + line(player, "Now that I have !!all the required items??, I should go and speak to", line++) + line(player, "!!Achietties?? and give them to her", line++) + } + } else { + // Everything above is replaced by this. + line(player, "I gave Achietties an Entranan Firebird Feather, A cooked", line++, true) + line(player, "lava eel from a dangerous fishing spot and after some", line++, true) + line(player, "difficulty, a Master Thief Armband.", line++, true) + line(player, "Once I had handed these over to Achietties I had proved", line++, true) + line(player, "myself worthy of entrance to the Heroes' Guild.", line++, true) + line++ + line++ + line(player,"QUEST COMPLETE!", line) + } + } + + override fun reset(player: Player) { + if (getQuestStage(player, Quests.HEROES_QUEST) == 0) { + removeAttribute(player, attributeGruborLetsYouIn) + removeAttribute(player, attributeGripTookPapers) + removeAttribute(player, attributeGripSaidDuties) + removeAttribute(player, attributeHasOpenedBackdoor) + removeAttribute(player, attributeHasOpenedChestDoor) + + // For testing: if you set quest stage to 0, it will switch your gang (blackarm <-> phoenix) + // Remember to set stage to 0 twice to keep your gang. + println("Swapping gang for Heroes Quest.") + ShieldofArrav.swapGang(player) + } + } + + override fun finish(player: Player) { + var ln = 10 + super.finish(player) + player.packetDispatch.sendString("You have completed the Heroes Quest!", 277, 4) + player.packetDispatch.sendItemZoomOnInterface(Items.DRAGON_BATTLEAXE_1377, 240, 277, 5) + + drawReward(player,"1 Quest Point", ln++) + drawReward(player,"Access to the Heroes' Guild", ln++) + drawReward(player,"A total of 29,232 XP spread", ln++) + drawReward(player,"over twelve skills", ln++) + + rewardXP(player, Skills.ATTACK, 3075.0) + rewardXP(player, Skills.DEFENCE, 3075.0) + rewardXP(player, Skills.STRENGTH, 3075.0) + rewardXP(player, Skills.HITPOINTS, 3075.0) + rewardXP(player, Skills.RANGE, 2075.0) + rewardXP(player, Skills.FISHING, 2725.0) + rewardXP(player, Skills.COOKING, 2825.0) + rewardXP(player, Skills.WOODCUTTING, 1575.0) + rewardXP(player, Skills.FIREMAKING, 1575.0) + rewardXP(player, Skills.SMITHING, 2725.0) + rewardXP(player, Skills.MINING, 2575.0) + rewardXP(player, Skills.HERBLORE, 1325.0) + } + + override fun newInstance(`object`: Any?): Quest { + return this + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/HeroesQuestListener.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/HeroesQuestListener.kt new file mode 100644 index 0000000..8764e7b --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/HeroesQuestListener.kt @@ -0,0 +1,155 @@ +package content.region.asgarnia.burthorpe.quest.heroesquest + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.global.action.DoorActionHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.combat.ImpactHandler +import core.game.node.entity.npc.NPC +import core.game.node.item.GroundItem +import core.game.world.map.Location +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +class HeroesQuestListener: InteractionListener { + + override fun defineListeners() { + // Black arm gang office door. + on(Scenery.DOOR_2626, IntType.SCENERY, "open") { player, node -> + if (getQuestStage(player, Quests.HEROES_QUEST) >= 2 && + getAttribute(player, HeroesQuest.attributeGruborLetsYouIn, false) && + HeroesQuest.isBlackArm(player)) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else { + openDialogue(player, GruborDialogueFile(), NPC(NPCs.GRUBOR_789)) + } + return@on true + } + + // Kitchen entrance + on(Scenery.DOOR_2628, IntType.SCENERY, "open") { player, node -> + if (getQuestStage(player, Quests.HEROES_QUEST) >= 3 && HeroesQuest.isPhoenix(player)) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else { + sendDialogue(player, "This door is locked.") + } + return@on true + } + + // Kitchen wall + on(Scenery.WALL_2629, IntType.SCENERY, "push") { player, node -> + if (getQuestStage(player, Quests.HEROES_QUEST) >= 4 && HeroesQuest.isPhoenix(player)) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else { + openDialogue(player, CharlieTheCookDialogueFile(), NPC(NPCs.CHARLIE_THE_COOK_794)) + } + return@on true + } + + // Mansion frontdoor + on(Scenery.DOOR_2627, IntType.SCENERY, "open") { player, node -> + if (getQuestStage(player, Quests.HEROES_QUEST) >= 4 && HeroesQuest.isBlackArm(player)) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else { + openDialogue(player, GarvDialogueFile(), NPC(NPCs.GARV_788)) + } + return@on true + } + + // Cupboard + + on(Scenery.CUPBOARD_2636, IntType.SCENERY, "search") { player, node -> + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + START_DIALOGUE -> sendNPCDialogue(player, NPCs.PIRATE_GUARD_799, "I don't think Mr Grip will like you opening that. That's his private drinks cabinet.") .also { stage++ } + 1 -> showTopics( + Topic(FacialExpression.NEUTRAL, "He won't notice me having a quick look.", 2), + Topic(FacialExpression.NEUTRAL, "Ok, I'll leave it.", END_DIALOGUE) + ) + 2 -> end().also { + val gripNpc = findNPC(NPCs.GRIP_792) + sendChat(gripNpc!!, "Stay out of my drinks cabinet!") + forceWalk(gripNpc, Location(2777, 3198, 0), "smart") + } + } + } + }) + return@on true + } + + // Mansion backdoor + on(Scenery.DOOR_2622, IntType.SCENERY, "open") { player, node -> + if (getAttribute(player, HeroesQuest.attributeHasOpenedBackdoor, false)) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else { + sendDialogue(player, "This door is locked.") + } + return@on true + } + onUseWith(IntType.SCENERY, Items.MISCELLANEOUS_KEY_1586, Scenery.DOOR_2622) { player, used, with -> + setAttribute(player, HeroesQuest.attributeHasOpenedBackdoor, true) + DoorActionHandler.handleAutowalkDoor(player, with.asScenery()) + return@onUseWith true + } + + // Chest door + on(Scenery.DOOR_2621, IntType.SCENERY, "open") { player, node -> + if (getAttribute(player, HeroesQuest.attributeHasOpenedChestDoor, false)) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else { + sendDialogue(player, "This door is locked.") + } + return@on true + } + onUseWith(IntType.SCENERY, Items.GRIPS_KEY_RING_1588, Scenery.DOOR_2621) { player, used, with -> + setAttribute(player, HeroesQuest.attributeHasOpenedChestDoor, true) + DoorActionHandler.handleAutowalkDoor(player, with.asScenery()) + return@onUseWith true + } + + // Chest + on(Scenery.CHEST_2632, IntType.SCENERY, "open"){ player, node -> + replaceScenery(node as core.game.node.scenery.Scenery, Scenery.CHEST_2633, -1) + return@on true + } + on(Scenery.CHEST_2633, IntType.SCENERY, "close"){ player, node -> + replaceScenery(node as core.game.node.scenery.Scenery, Scenery.CHEST_2632, -1) + return@on true + } + on(Scenery.CHEST_2633, IntType.SCENERY, "search"){ player, node -> + if (inInventory(player, Items.PETES_CANDLESTICK_1577)) { + sendMessage(player, "You search the chest but find nothing.") + } else { + if (getQuestStage(player, Quests.HEROES_QUEST) == 4) { + setQuestStage(player, Quests.HEROES_QUEST, 5) + } + sendDialogue(player, "You find two candlesticks in the chest. So that will be one for you, and one for the person who killed Grip for you.") + addItemOrDrop(player, Items.PETES_CANDLESTICK_1577, 2) + } + return@on true + } + + // + on(Items.FIRE_FEATHER_1583, IntType.GROUNDITEM, "take") { player, groundItem -> + if (inEquipment(player, Items.ICE_GLOVES_1580)) { + addItem(player, Items.FIRE_FEATHER_1583) + removeGroundItem(groundItem as GroundItem) + } else { + sendChat(player, "Ouch!") + player.impactHandler.manualHit(player, 9, ImpactHandler.HitsplatType.NORMAL) + sendMessage(player, "It is too hot to take. You need something cold to pick it up with.") + } + return@on true + } + + // OilFishingRodListener.kt + DrinkBlamishOilListener.kt + FinishedPotion.java + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/KatrineDialogueFile.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/KatrineDialogueFile.kt new file mode 100644 index 0000000..f5c3f1d --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/KatrineDialogueFile.kt @@ -0,0 +1,127 @@ +package content.region.asgarnia.burthorpe.quest.heroesquest + +import content.data.Quests +import core.api.* +import core.game.dialogue.* +import org.rs09.consts.Items + +class KatrineDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + // 0 is handled by default in the old KatrineDialogue. + b.onQuestStages(Quests.HEROES_QUEST, 1) + .playerl("Hey.") + .npcl("Hey.") + .options() + .let { optionBuilder -> + + optionBuilder.option_playerl("Who are all those people in there?") + .npcl("They're just various rogues and thieves.") + .playerl("They don't say a lot...") + .npcl("Nope.") + .end() + + optionBuilder.option_playerl("Is there any way I can get the rank of master thief?") + .npcl("Master thief? Ain't we the ambitious one!") + .npcl("Well, you're gonna have to do something pretty amazing.") + .playerl("Anything you can suggest?") + .npcl("Well, some of the MOST coveted prizes in thiefdom right now are in the pirate town of Brimhaven on Karamja.") + .npcl("The pirate leader Scarface Pete has a pair of extremely valuable candlesticks.") + .npcl("His security is VERY good.") + .npcl("We, of course, have gang members in a town like Brimhaven who may be able to help you.") + .npcl("Visit our hideout in the alleyway on palm street.") + .npcl("To get in you will need to tell them the secret password 'four leaved clover'.") + .endWith { _, player -> + if(getQuestStage(player, Quests.HEROES_QUEST) == 1) { + setQuestStage(player, Quests.HEROES_QUEST, 2) + } + } + + } + + // This is not authentic, she falls back to a boring default conversation, but I guess people might need help during the quest + b.onQuestStages(Quests.HEROES_QUEST, 2, 3, 4) + .playerl("What am I supposed to be doing again?") + .npcl("You told me you wanted to get the rank of master thief! Now pay attention.") + .npcl("Some of the MOST coveted prizes in thiefdom right now are in the pirate town of Brimhaven on Karamja.") + .npcl("The pirate leader Scarface Pete has a pair of extremely valuable candlesticks.") + .npcl("His security is VERY good.") + .npcl("We, of course, have gang members in a town like Brimhaven who may be able to help you.") + .npcl("Visit our hideout in the alleyway on palm street.") + .npcl("To get in you will need to tell them the secret password 'four leaved clover'.") + .end() + + // As FYI, the fallback for 2,3,4 is + /** + * .options() + * .let { optionBuilder -> + * optionBuilder.option_playerl("Who are all those people in there?") + * .npcl("They're just various rogues and thieves.") + * .playerl("They don't say a lot...") + * .npcl("Nope.") + * .end() + * optionBuilder.option("Teach me to be a top class criminal!") + * .playerl("Teach me to be a top class criminal.") + * .npcl("Teach yourself.") + * .end() + * + * + * + * Player: + * I have a candlestick now! + * Katrine: + * Good for you. I'll give a master thief's armband to the one who retrieved that. I know it wasn't you. + */ + + + b.onQuestStages(Quests.HEROES_QUEST, 5) + .branch { player -> + return@branch if (inInventory(player, Items.PETES_CANDLESTICK_1577)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(1) + .options() + .let { optionBuilder -> + optionBuilder.option_playerl("Who are all those people in there?") + .npcl("They're just various rogues and thieves.") + .playerl("They don't say a lot...") + .npcl("Nope.") + .end() + optionBuilder.option("I have a candlestick now.") + .playerl("I have a candlestick now!") + .npcl("Wow... is... it REALLY it?") + .npcl("This really is a FINE bit of thievery.") + .npcl("Us thieves have been trying to get hold of this one for a while!") + .npc("You wanted to be ranked as a master thief didn't you?", "Well, I guess this just about ranks as good enough!") + .linel("Katrine gives you a master thief armband.") + .endWith { _, player -> + if (removeItem(player, Items.PETES_CANDLESTICK_1577)) { + addItemOrDrop(player, Items.THIEVES_ARMBAND_1579) + if (getQuestStage(player, Quests.HEROES_QUEST) == 5) { + setQuestStage(player, Quests.HEROES_QUEST, 6) + } + } + } + + branch.onValue(0) + .playerl("What am I supposed to be doing again?") + .npcl("You told me you wanted to get the rank of master thief! Now pay attention.") + .npcl("Some of the MOST coveted prizes in thiefdom right now are in the pirate town of Brimhaven on Karamja.") + .npcl("The pirate leader Scarface Pete keeps an extremely valuable candlesticks.") + .npcl("His security is VERY good.") + .npcl("We, of course, have gang members in a town like Brimhaven who may be able to help you.") + .npcl("Visit our hideout in the alleyway on palm street.") + .npcl("To get in you will need to tell them the secret password 'four leaved clover'.") + .end() + } + } + + // I lost the armband and some stupid default shit. + b.onQuestStages(Quests.HEROES_QUEST, 6) + .playerl("I have lost my master thief's armband...") + .npcl("Lucky I 'ave a spare ain't it? Don't lose it again.") + .endWith { _, player -> + addItemOrDrop(player, Items.THIEVES_ARMBAND_1579) + } + + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/StravenDialogueFile.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/StravenDialogueFile.kt new file mode 100644 index 0000000..68d2369 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/StravenDialogueFile.kt @@ -0,0 +1,73 @@ +package content.region.asgarnia.burthorpe.quest.heroesquest + +import content.data.Quests +import core.api.* +import core.game.dialogue.* +import org.rs09.consts.Items + +class StravenDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + // 0 is handled by default in the old StravenDialogue. + b.onQuestStages(Quests.HEROES_QUEST, 1) + .playerl("How would I go about getting a Master Thief armband?") + .npcl("Ooh... tricky stuff. Took me YEARS to get that rank.") + .npcl("Well, what some of the more aspiring thieves in our gang are working on right now is to steal some very valuable candlesticks from Scarface Pete - the pirate leader on Karamja.") + .npcl("His security is excellent, and the target very valuable so that might be enough to get you the rank.") + .npcl("Go talk to our man Alfonse, the waiter in the Shrimp and Parrot.") + .npcl("Use the secret word 'gherkin' to show you're one of us.") + .endWith { _, player -> + if(getQuestStage(player, Quests.HEROES_QUEST) == 1) { + setQuestStage(player, Quests.HEROES_QUEST, 2) + } + } + + b.onQuestStages(Quests.HEROES_QUEST, 2, 3, 4) + .playerl("What am I supposed to be doing again?") + .npcl("You told me you wanted to get a Master thief's armband! Now pay attention.") + .npcl("Some of the more aspiring thieves in our gang are working on right now is to steal some very valuable candlesticks from Scarface Pete - the pirate leader on Karamja.") + .npcl("His security is excellent, and the target very valuable so that might be enough to get you the rank.") + .npcl("Go talk to our man Alfonse, the waiter in the Shrimp and Parrot.") + .npcl("Use the secret word 'gherkin' to show you're one of us.") + .end() + + + b.onQuestStages(Quests.HEROES_QUEST, 5) + .branch { player -> + return@branch if (inInventory(player, Items.PETES_CANDLESTICK_1577)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(1) + .playerl("I have retrieved a candlestick!") + .npcl("Hmmm. Not bad, not bad. Let's see it, make sure it's genuine.") + .linel("You hand Straven the candlestick.") + .playerl("So is this enough to get me a Master Thief armband?") + .npcl("Hmm... I dunno... Aww, go on then. I suppose I'm in a generous mood today.") + .linel("Straven hands you a Master Thief armband.") + .endWith { _, player -> + if (removeItem(player, Items.PETES_CANDLESTICK_1577)) { + addItemOrDrop(player, Items.THIEVES_ARMBAND_1579) + if (getQuestStage(player, Quests.HEROES_QUEST) == 5) { + setQuestStage(player, Quests.HEROES_QUEST, 6) + } + } + } + + branch.onValue(0) + .playerl("What am I supposed to be doing again?") + .npcl("You told me you wanted to get a Master thief's armband! Now pay attention.") + .npcl("Some of the more aspiring thieves in our gang are working on right now is to steal some very valuable candlesticks from Scarface Pete - the pirate leader on Karamja.") + .npcl("His security is excellent, and the target very valuable so that might be enough to get you the rank.") + .npcl("Go talk to our man Alfonse, the waiter in the Shrimp and Parrot.") + .npcl("Use the secret word 'gherkin' to show you're one of us.") + .end() + } + + // I lost the armband and some stupid default shit. + b.onQuestStages(Quests.HEROES_QUEST, 6) + .playerl("I'm afraid I've lost my master thief's armband.") + .npcl("Lucky for you I have a spare. Don't lose it again!") + .endWith { _, player -> + addItemOrDrop(player, Items.THIEVES_ARMBAND_1579) + } + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/TrobertDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/TrobertDialogue.kt new file mode 100644 index 0000000..12561ad --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/heroesquest/TrobertDialogue.kt @@ -0,0 +1,92 @@ +package content.region.asgarnia.burthorpe.quest.heroesquest + +import content.data.Quests +import core.api.* +import core.game.dialogue.* +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class TrobertDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, TrobertDialogueFile(), npc) + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return TrobertDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.TROBERT_1884) + } +} + +class TrobertDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + // Technically this won't happen since you have to get past Grubor. + b.onQuestStages(Quests.HEROES_QUEST, 0, 1) + .npcl("Welcome to our Brimhaven headquarters. I'm Trobert and I'm in charge here.") + .playerl("Pleased to meet you.") + .npcl("Likewise.") + .end() + + b.onQuestStages(Quests.HEROES_QUEST, 2) + .npcl("Welcome to our Brimhaven headquarters. I'm Trobert and I'm in charge here.") + .options() + .let { optionBuilder -> + val continuePath = b.placeholder() + optionBuilder.option("So can you help me get Scarface Pete's candlesticks?") + .goto(continuePath) + optionBuilder.option_playerl("Pleased to meet you.") + .npcl("Likewise.") + .goto(continuePath) + return@let continuePath.builder() + } + .playerl("So can you help me get Scarface Pete's candlesticks?") + .npcl("Well, we have made some progress there. We know that one of the only keys to Pete's treasure room is carried by Grip, the head guard, so we thought it might be good to get close to him somehow.") + .npcl("Grip was taking on a new deputy called Hartigen, an Asgarnian Black Knight who was deserting the Black Knight Fortress and seeking new employment here on Brimhaven.") + .npcl("We managed to waylay him on the journey here, and steal his I.D. papers. Now all we need is to find somebody willing to impersonate him and take the deputy role to get that key for us.") + .options() + .let { optionBuilder -> + + optionBuilder.option_playerl("I volunteer to undertake that mission!") + .npcl("Good good. Well, here's the ID papers, take them and introduce yourself to the guards at Scarface Pete's mansion, we'll have that treasure in no time.") + .endWith { _, player -> + addItemOrDrop(player, Items.ID_PAPERS_1584) + if(getQuestStage(player, Quests.HEROES_QUEST) == 2) { + setQuestStage(player, Quests.HEROES_QUEST, 3) + } + } + + optionBuilder.option_playerl("Well, good luck then.") + .npcl("Someone will show up eventually.") + .end() + } + + b.onQuestStages(Quests.HEROES_QUEST, 3, 4, 5) + .branch { player -> + return@branch if (inInventory(player, Items.ID_PAPERS_1584)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(1) + .npcl("How's it going?") + .playerl("Fine, thanks.") + .end() + branch.onValue(0) + .playerl("I have lost Hartigen's ID papers.") + .npcl("Well, that was careless of you, wasn't it? Fortunately for you, he had a spare. Take this one, but please try to be more careful with this one.") + .endWith { _, player -> + addItemOrDrop(player, Items.ID_PAPERS_1584) + } + } + + b.onQuestStages(Quests.HEROES_QUEST, 6, 100) + .npcl("How's it going?") + .playerl("Fine, thanks.") + .end() + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/BerryNpc.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/BerryNpc.kt new file mode 100644 index 0000000..0b04d9b --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/BerryNpc.kt @@ -0,0 +1,52 @@ +package content.region.asgarnia.burthorpe.quest.trollstronghold + +import content.data.Quests +import core.api.isQuestInProgress +import core.api.produceGroundItem +import core.game.node.entity.Entity +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class BerryNpc(id: Int = 0, location: Location? = null) : AbstractNPC(id, location) { + override fun construct(id: Int, location: Location, vararg objects: Any): AbstractNPC { + return BerryNpc(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.BERRY_1127, NPCs.BERRY_1129) + } + + // Transform from sleeping to awake. + override fun isAttackable(entity: Entity, style: CombatStyle, message: Boolean): Boolean { + val attackable = super.isAttackable(entity, style, message) + if (this.id == NPCs.BERRY_1129) { + val prevLifePoints = this.skills.lifepoints + this.transform(NPCs.BERRY_1127) + this.skills.lifepoints = prevLifePoints + } + return attackable + } + + override fun handleTickActions() { + super.handleTickActions() + // When returning to spawn, transform back to sleeping and keep lifepoints. + if (getAttribute("return-to-spawn", false) && this.id == NPCs.BERRY_1127) { + val prevLifePoints = this.skills.lifepoints + this.transform(NPCs.BERRY_1129) + this.skills.lifepoints = prevLifePoints + } + } + + override fun finalizeDeath(killer: Entity?) { + if (isQuestInProgress(killer as Player, Quests.TROLL_STRONGHOLD, 8, 10)) { + produceGroundItem(killer, Items.CELL_KEY_2_3137, 1, this.location) + } + super.finalizeDeath(killer) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/DadDialogue.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/DadDialogue.kt new file mode 100644 index 0000000..a1d76a6 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/DadDialogue.kt @@ -0,0 +1,49 @@ +package content.region.asgarnia.burthorpe.quest.trollstronghold + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class DadDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (getQuestStage(player!!, Quests.TROLL_STRONGHOLD)) { + in 3..4 -> { + when (stage) { + START_DIALOGUE -> npcl(FacialExpression.OLD_HAPPY, "What tiny human do in troll arena? Dad challenge human to fight!").also { stage++ } + 1 -> showTopics( + Topic(FacialExpression.THINKING, "Why are you called Dad?", 2), + Topic(FacialExpression.FRIENDLY, "I accept your challenge!", 3), + Topic(FacialExpression.SCARED, "Eek! No thanks.", END_DIALOGUE) + ) + + 2 -> npcl(FacialExpression.OLD_HAPPY, "Troll named after first thing try to eat!").also { stage = 1 } + 3 -> npcl(FacialExpression.OLD_HAPPY, "Tiny human brave. Dad squish!").also { stage++ } + 4 -> npc!!.attack(player).also { + npc!!.skills.lifepoints = npc!!.skills.maximumLifepoints // Reset dad to max hitpoints. + setQuestStage(player!!, Quests.TROLL_STRONGHOLD, 4) + stage = END_DIALOGUE + } + } + } + in 5..100 -> { + sendMessage(player, "He doesn't seem interested in talking right now.") + } + } + return true + } + override fun newInstance(player: Player?): DialoguePlugin { + return DadDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.DAD_1125) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/DadDialogueFile.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/DadDialogueFile.kt new file mode 100644 index 0000000..4428bf9 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/DadDialogueFile.kt @@ -0,0 +1,41 @@ +package content.region.asgarnia.burthorpe.quest.trollstronghold + +import content.data.Quests +import core.api.setQuestStage +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE + +class DadDialogueFile(private val dialogueNum: Int = 0) : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when(dialogueNum) { + 1 -> when (stage) { + START_DIALOGUE -> npcl(FacialExpression.OLD_HAPPY, "No human pass through arena without defeating Dad!").also { + stage = END_DIALOGUE + setQuestStage(player!!, Quests.TROLL_STRONGHOLD, 3) + } + } + 2 -> when (stage) { + START_DIALOGUE -> npcl(FacialExpression.OLD_NORMAL, "Tiny human brave. Dad squish!").also { stage++ } + 1 -> npc!!.attack(player).also { + npc!!.skills.lifepoints = npc!!.skills.maximumLifepoints // Reset dad to max hitpoints. + setQuestStage(player!!, Quests.TROLL_STRONGHOLD, 4) + stage = END_DIALOGUE + } + } + 3 -> when (stage) { + START_DIALOGUE -> npcl(FacialExpression.OLD_NORMAL, "Stop! You win. Not hurt Dad.").also { stage++ } + 1 -> showTopics( + Topic(FacialExpression.FRIENDLY, "I'll be going now.", END_DIALOGUE), + Topic(FacialExpression.ANGRY_WITH_SMILE, "I'm not done yet! Prepare to die!", 2) + ) + 2 -> player!!.attack(npc).also { + setQuestStage(player!!, Quests.TROLL_STRONGHOLD, 5) + stage = END_DIALOGUE + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/DadNpc.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/DadNpc.kt new file mode 100644 index 0000000..f489aa1 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/DadNpc.kt @@ -0,0 +1,76 @@ +package content.region.asgarnia.burthorpe.quest.trollstronghold + +import content.data.Quests +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.npc.AbstractNPC +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.plugin.Initializable +import core.tools.RandomFunction +import org.rs09.consts.NPCs + +@Initializable +class DadNpc(id: Int = 0, location: Location? = null) : AbstractNPC(id, location) { + override fun construct(id: Int, location: Location, vararg objects: Any): AbstractNPC { + return DadNpc(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.DAD_1125) + } + + override fun isAttackable(entity: Entity, style: CombatStyle, message: Boolean): Boolean { + val attackable = super.isAttackable(entity, style, message) + val player = entity.asPlayer() + + // Attack Dad. If quest is done, you cannot attack Dad. + when (getQuestStage(player, Quests.TROLL_STRONGHOLD)) { + 3 -> openDialogue(player, DadDialogueFile(2), this.asNpc()).also { return false } + 4 -> { return attackable } + in 5 .. 100 -> sendMessage(player, "You don't need to fight him again.").also { return false } + } + return attackable + } + + override fun checkImpact(state: BattleState) { + super.checkImpact(state) + val player = state.attacker + val opponent = state.victim + // If dad is below 30/120 lifepoints, give player option + // Dad can be killed if you oneshot him past 30. + if (opponent.skills.lifepoints < 30) { + player.properties.combatPulse.stop() + opponent.properties.combatPulse.stop() + if (getQuestStage(player!!.asPlayer(), Quests.TROLL_STRONGHOLD) == 4){ + setQuestStage(player!!.asPlayer(), Quests.TROLL_STRONGHOLD, 5) + } + submitWorldPulse(object : Pulse(){ + var counter = 0 + override fun pulse(): Boolean { + when(counter++){ + 1 -> { + openDialogue(player.asPlayer(), DadDialogueFile(3), opponent.asNpc()) + return true; + } + } + return false + } + }) + } + } + override fun finalizeDeath(killer: Entity?) { + // In case Dad gets one shotted to death. + super.finalizeDeath(killer) + if (getQuestStage(killer!!.asPlayer(), Quests.TROLL_STRONGHOLD) == 4){ + setQuestStage(killer!!.asPlayer(), Quests.TROLL_STRONGHOLD, 5) + } + } + override fun handleTickActions() { + super.handleTickActions() + if(RandomFunction.roll(35)){ + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/DenulthDialogueFile.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/DenulthDialogueFile.kt new file mode 100644 index 0000000..2575fc4 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/DenulthDialogueFile.kt @@ -0,0 +1,57 @@ +package content.region.asgarnia.burthorpe.quest.trollstronghold + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.Items + +/** + * Denulth sub dialogue file for troll stronghold. + * Called by DenulthDialogue + * @author ovenbread + */ +class DenulthDialogueFile : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (getQuestStage(player!!, Quests.TROLL_STRONGHOLD)) { + in 1..7 -> { + when (stage) { + START_DIALOGUE -> npcl(FacialExpression.FRIENDLY, "How are you getting on with rescuing Godric?").also { stage++ } + 1 -> { + if (hasAnItem(player!!, Items.CLIMBING_BOOTS_3105).exists()) { + playerl(FacialExpression.FRIENDLY, " I've got some climbing boots.").also { stage = 2 } + } else { + playerl(FacialExpression.FRIENDLY, "I haven't found a way to climb up yet.").also { stage = 3 } + } + } + 2 -> npcl(FacialExpression.FRIENDLY, "Then hurry, friend! What are you still doing here?").also { stage = END_DIALOGUE } + 3 -> npcl(FacialExpression.FRIENDLY, "Hurry, friend! Who knows what they'll do with Godric?").also { stage = END_DIALOGUE } + } + } + in 8 .. 10 -> { + when (stage) { + START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hello!").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "Welcome back friend!").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "I've found my way into the prison.").also { stage++ } + 3 -> npcl(FacialExpression.FRIENDLY, "...and?").also { stage++ } + 4 -> playerl(FacialExpression.FRIENDLY, "That's all.").also { stage++ } + 5 -> npcl(FacialExpression.FRIENDLY, "Hurry, friend. Find a way to free Godric!").also { + stage = END_DIALOGUE + } + } + } + 11 -> { + when (stage) { + START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hello!").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "Welcome back friend!").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "I have freed Godric!").also { stage++ } + 3 -> npcl(FacialExpression.FRIENDLY, "Oh, what great news! You should hurry to tell Dunstan, he will be overjoyed!").also { + stage = END_DIALOGUE + } + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/DunstanDialogueFile.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/DunstanDialogueFile.kt new file mode 100644 index 0000000..4cd3a3f --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/DunstanDialogueFile.kt @@ -0,0 +1,79 @@ +package content.region.asgarnia.burthorpe.quest.trollstronghold + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.item.Item +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.Items + +class DunstanDialogueFile : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (getQuestStage(player!!, Quests.TROLL_STRONGHOLD)) { + in 1..10 -> { + when (stage) { + START_DIALOGUE -> npcl(FacialExpression.FRIENDLY, "Have you managed to rescue Godric yet?").also { stage++ } + 1 -> playerl(FacialExpression.FRIENDLY, "Not yet.").also { stage++ } + 2 -> npcl(FacialExpression.FRIENDLY, "Please hurry! Who knows what they will do to him? Is there anything I can do in the meantime?").also { stage++ } + 3 -> showTopics( + Topic(FacialExpression.THINKING, "Can you put some spikes on my Climbing boots?", 30), + Topic(FacialExpression.THINKING, "Is it OK if I use your anvil?", 10), + Topic(FacialExpression.NEUTRAL, "Nothing, thanks.", 20), + ) + 10 -> npcl(FacialExpression.FRIENDLY, "So you're a smithy are you?").also { stage++ } + 11 -> playerl(FacialExpression.FRIENDLY, "I dabble.").also { stage++ } + 12 -> npcl(FacialExpression.FRIENDLY, "A fellow smith is welcome to use my anvil!").also { stage++ } + 13 -> playerl(FacialExpression.FRIENDLY, "Thanks!").also { stage++ } + 14 -> npcl(FacialExpression.FRIENDLY, "Anything else before I get on with my work?").also { stage = 3 } + 20 -> npcl(FacialExpression.NEUTRAL, "All right. Speak to you later then.").also { stage = END_DIALOGUE } + 30 -> playerl("Can you put some spikes on my Climbing boots?").also { stage++ } + 31 -> npcl("For you, no problem.").also { stage++ } + 32 -> npc("Do you realise that you can only use the Climbing", "boots right now? The Spiked boots can only be used in", "the Icelands but no ones been able to get there for", "years!").also { stage++ } + 33 -> showTopics( + Topic(FacialExpression.NEUTRAL, "Yes, but I still want them.", 40, true), + Topic(FacialExpression.NEUTRAL, "Oh OK, I'll leave them thanks.", 43), + ) + 40 -> { + if (inInventory(player!!, Items.CLIMBING_BOOTS_3105) && inInventory(player!!, Items.IRON_BAR_2351)) { + sendDoubleItemDialogue(player!!, Items.IRON_BAR_2351, Items.CLIMBING_BOOTS_3105, "You give Dunstan an Iron bar and the climbing boots.") + sendMessage(player!!, "You give Dunstan an Iron bar and the climbing boots.") + if (removeItem(player!!, Item(Items.CLIMBING_BOOTS_3105)) && removeItem(player!!, Item(Items.IRON_BAR_2351))) { + addItemOrDrop(player!!, Items.SPIKED_BOOTS_3107) + stage++ + } else { + stage = END_DIALOGUE + } + } else if (inInventory(player!!, Items.CLIMBING_BOOTS_3105)){ + npcl("Sorry, I'll need an iron bar to make the spikes.") + stage = 3 + } else { + playerl("I don't have them on me.") + stage = 3 + } + } + 41 -> sendItemDialogue(player!!, Items.SPIKED_BOOTS_3107, "Dunstan has given you the spiked boots.").also { stage++ + sendMessage(player!!, "Dunstan has given you the spiked boots.") + } + 43 -> npcl(FacialExpression.FRIENDLY, "Anything else before I get on with my work?").also { + stage = 3 + } + } + } + 11 -> { + when (stage) { + START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Has Godric returned home?").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "He is safe and sound, thanks to you my friend!").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "I'm glad to hear it.").also { stage++ } + 3 -> npcl(FacialExpression.FRIENDLY, "I have very little to offer you by way of thanks, but perhaps you will accept these family heirlooms. They were found by my great-great-grandfather, but we still don't have any idea what they do.").also { stage++ } + 4 -> { + stage = END_DIALOGUE + finishQuest(player!!, Quests.TROLL_STRONGHOLD) + } + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/TrollGeneralsNpc.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/TrollGeneralsNpc.kt new file mode 100644 index 0000000..cee11dd --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/TrollGeneralsNpc.kt @@ -0,0 +1,30 @@ +package content.region.asgarnia.burthorpe.quest.trollstronghold + +import content.data.Quests +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class TrollGeneralsNpc(id: Int = 0, location: Location? = null) : AbstractNPC(id,location) { + + override fun construct(id: Int, location: Location?, vararg objects: Any?): AbstractNPC { + return TrollGeneralsNpc(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.TROLL_GENERAL_1115, NPCs.TROLL_GENERAL_1116, NPCs.TROLL_GENERAL_1117) + } + + override fun finalizeDeath(killer: Entity?) { + if(isQuestInProgress(killer as Player, Quests.TROLL_STRONGHOLD, 1, 7)) { + produceGroundItem(killer, Items.PRISON_KEY_3135, 1, this.location) + } + super.finalizeDeath(killer) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/TrollStronghold.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/TrollStronghold.kt new file mode 100644 index 0000000..6630bfa --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/TrollStronghold.kt @@ -0,0 +1,99 @@ +package content.region.asgarnia.burthorpe.quest.trollstronghold + +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import org.rs09.consts.Items +import content.data.Quests + +/** + * Troll Stronghold Quest + * @author ovenbread + */ +@Initializable +class TrollStronghold : Quest(Quests.TROLL_STRONGHOLD,128, 127, 1, 317, 0, 1, 50) { + + override fun drawJournal(player: Player?, stage: Int) { + super.drawJournal(player, stage) + var line = 12 + var stage = getStage(player) + + var started = getQuestStage(player!!, Quests.TROLL_STRONGHOLD) > 0 + + if(!started){ + line(player, "I can start this quest by speaking to !!Denulth?? in his tent at", line++) + line(player, "the !!Imperial Guard camp?? in !!Burthorpe?? after completing the", line++) + line(player, "!!Death Plateau Quest??", line++, isQuestComplete(player, Quests.DEATH_PLATEAU)) + line++ + line(player, "To complete this quest I need:", line++) + line(player, "Level 15 Agility.", line++, hasLevelStat(player, Skills.AGILITY, 15)) + line(player, "I also need to be able to defeat a !!level 113 Troll??.", line++) + line(player, "Level 30 Thieving might be useful.", line++, hasLevelStat(player, Skills.THIEVING, 30)) + if (isQuestComplete(player, Quests.DEATH_PLATEAU) && hasLevelStat(player, Skills.AGILITY, 15) && hasLevelStat(player, Skills.THIEVING, 30)) { + line(player, "I have all the requirements to start this quest.", line++) + } + } else { + line(player, "I promised !!Denulth?? that I would rescue !!Godric?? from the !!Troll??", line++, stage == 100) + line(player, "!!Stronghold??", line++, stage == 100) + line++ + if (stage >= 5 || inBank(player, Items.CLIMBING_BOOTS_3105) || inInventory(player, Items.CLIMBING_BOOTS_3105) || inEquipment(player, Items.CLIMBING_BOOTS_3105)) { + line(player, "I got some !!climbing boots?? from !!Tenzing??", line++, true) + } else { + line(player, "I have to get some !!climbing boots?? from !!Tenzing??", line++) + } + line++ + if (stage >= 5) { + line(player, "I have defeated the !!Troll Champion??", line++, true) + } else if (stage >= 3) { + line(player, "I have accepted the !!Troll Champion's?? challenge.", line++) + } + line++ + if (stage >= 7) { + line(player, "I found my way into the Troll Stronghold", line++, true) + } else if (stage >= 5) { + line(player, "I have to find a way to get into the !!Troll Stronghold??", line++) + } + line++ + if (stage >= 8) { + line(player, "I found my way into the !!Prison??", line++, true) + } else if (stage >= 5) { + line(player, "I have to find a way to get into the !!prison??", line++) + } + line++ + if (stage >= 11) { + line(player, "I've rescued !!Godric?? and !!Mad Eadgar??", line++, true) + } else if (stage >= 8) { + line(player, "I have to rescue !!Godric?? and !!Mad Eadgar??", line++) + } + if (stage >= 100) { + line++ + line(player, "I talked to Dunstan and he rewarded me.", line++, true) + } else if (stage >= 11) { + line(player, "I should return and tell !!Dunstan?? his son is safe.", line++) + } + if (stage >= 100) { + line++ + line(player,"QUEST COMPLETE!", line) + } + } + } + + override fun finish(player: Player) { + var ln = 10 + super.finish(player) + player.packetDispatch.sendString("You have completed the Troll Stronghold quest!", 277, 4) + player.packetDispatch.sendItemZoomOnInterface(Items.MYSTERIOUS_LAMP_13227, 240, 277, 5) + + drawReward(player,"1 Quest Point", ln++) + drawReward(player,"2 Reward lamps giving 10,000", ln++) + drawReward(player,"XP each", ln++) + + addItemOrDrop(player, Items.MYSTERIOUS_LAMP_13227, 2) + } + + override fun newInstance(`object`: Any?): Quest { + return this + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/TrollStrongholdListener.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/TrollStrongholdListener.kt new file mode 100644 index 0000000..f276b39 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/TrollStrongholdListener.kt @@ -0,0 +1,318 @@ +package content.region.asgarnia.burthorpe.quest.trollstronghold + +import content.data.Quests +import core.api.* +import core.game.global.action.DoorActionHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.Node +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.tools.RandomFunction +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery +import kotlin.math.ceil + +class TrollStrongholdListener: InteractionListener { + + override fun defineListeners() { + // Entrance to arena with Dad in it. + on(intArrayOf(Scenery.ARENA_ENTRANCE_3782, Scenery.ARENA_ENTRANCE_3783), IntType.SCENERY, "open"){ player, node -> + // Only get the dialogue once. + if (getQuestStage(player, Quests.TROLL_STRONGHOLD) == 1) { + openDialogue(player, DadDialogueFile(1), findNPC(NPCs.DAD_1125)!!) + } + // Only allow players through when they start Troll Stronghold. + // No one is allowed to go to GWD unless they start the Troll Stronghold quest. + if (getQuestStage(player, Quests.TROLL_STRONGHOLD) > 0) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else { + sendMessage(player, "You need to start the Troll Stronghold quest.") + } + return@on true; + } + + // Not allowed to exit arena into the troll stronghold until Dad is defeated. + on(intArrayOf(Scenery.ARENA_EXIT_3785, Scenery.ARENA_EXIT_3786), IntType.SCENERY, "open"){ player, node -> + if (getQuestStage(player, Quests.TROLL_STRONGHOLD) < 5){ + openDialogue(player, DadDialogueFile(1), findNPC(NPCs.DAD_1125)!!) + } else { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } + return@on true; + } + + // Key to unlock the prison door + on(Scenery.PRISON_DOOR_3780, IntType.SCENERY, "unlock"){ player, node -> + if (getQuestStage(player, Quests.TROLL_STRONGHOLD) >= 8){ + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else { + if (inInventory(player, Items.PRISON_KEY_3135)) { + if (getQuestStage(player, Quests.TROLL_STRONGHOLD) == 5) { + setQuestStage(player, Quests.TROLL_STRONGHOLD, 8) + } + if (removeItem(player, Items.PRISON_KEY_3135)) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + sendMessage(player, "You unlock the prison door.") + } + } else { + sendMessage(player, "The prison door is locked.") + } + } + return@on true; + } + + // Pickpocket Twig + on(NPCs.TWIG_1128, IntType.NPC, "pickpocket") { player, node -> + val npc = node.asNpc() + player.lock() + submitWorldPulse(object : Pulse(){ + var counter = 0 + override fun pulse(): Boolean { + when(counter++){ + 0 -> { + if (hasLevelDyn(player, Skills.THIEVING, 30)){ + animate(player, Animation(881)) + } else { + sendMessage(player, "You need to be a level 30 thief to pickpocket Twig.") + return true + } + } + 3 -> { + val success: Boolean = success(player, Skills.THIEVING) + if(success){ + if(isQuestInProgress(player, Quests.TROLL_STRONGHOLD, 8, 10)) { + addItem(player, Items.CELL_KEY_1_3136) + sendMessage(player, "You find a small key on Twig.") + } else { + sendMessage(player, "You find nothing on Twig.") + } + } else { + sendChat(npc, "What you think you doing?") + transformNpc(npc, NPCs.TWIG_1126, 50) + npc.attack(player) + } + player.unlock() + return true + } + } + return false + } + }) + return@on true + } + + // Pickpocket Berry + on(NPCs.BERRY_1129, IntType.NPC, "pickpocket") { player, node -> + val npc = node.asNpc() + player.lock() + submitWorldPulse(object : Pulse(){ + var counter = 0 + override fun pulse(): Boolean { + when(counter++){ + 0 -> { + if (hasLevelDyn(player, Skills.THIEVING, 30)){ + animate(player, Animation(881)) + } else { + sendMessage(player, "You need to be a level 30 thief to pickpocket Berry.") + return true + } + } + 3 -> { + val success: Boolean = success(player, Skills.THIEVING) + if(success){ + if(isQuestInProgress(player, Quests.TROLL_STRONGHOLD, 8, 10)) { + addItem(player, Items.CELL_KEY_2_3137) + sendMessage(player, "You find a small key on Berry.") + } else { + sendMessage(player, "You find nothing on Berry.") + } + } else { + sendChat(npc, "What you think you doing?") + transformNpc(npc, NPCs.BERRY_1127, 50) + npc.attack(player) + } + player.unlock() + return true + } + } + return false + } + }) + return@on true + } + + // Key to unlock Mad Eadgar's cell + fun unlockMadEadgarCellDoor(player: Player, node: Node) { + if (inInventory(player, Items.CELL_KEY_1_3136)){ + sendMessage(player, "You unlock the cell door.") + if (getQuestStage(player, Quests.TROLL_STRONGHOLD) == 8) { + setQuestStage(player, Quests.TROLL_STRONGHOLD, 9) + } else if (getQuestStage(player, Quests.TROLL_STRONGHOLD) == 10) { + setQuestStage(player, Quests.TROLL_STRONGHOLD, 11) + } + // Animate Mad Eadgar leaving cell. + val npc = findNPC(NPCs.EADGAR_1113)!! + sendNPCDialogue(player, NPCs.EADGAR_1113, "Thanks! I'm off back home!") + npc.walkRadius = 40 + submitWorldPulse(object : Pulse(0) { + // This is basically chaining a series of walks + and door handler. + var count = 0 + var stage = 0 + var trigger = true + var targetLocation = Location(0, 0, 0) + override fun pulse(): Boolean { + if (npc.location.equals(targetLocation)){ + stage++ + trigger = true + } + if (trigger) { + trigger = false + when (stage) { + 0 -> forceWalk(npc, Location(2831, 10082, 0), "dumb").also { + npc.walkRadius = 11 + npc.setWalks(false) + targetLocation = Location(2831, 10082, 0) + } + 1 -> DoorActionHandler.handleAutowalkDoor(npc, node.asScenery()).also { targetLocation = Location(2832, 10082, 0) } + // Delay 2 ticks for DoorActionHandler to finish + 4 -> forceWalk(npc, Location(2836, 10082, 0), "dumb").also { targetLocation = Location(2836, 10082, 0) } + 5 -> forceWalk(npc, Location(2836, 10061, 0), "dumb").also { targetLocation = Location(2836, 10061, 0) } + 6 -> forceWalk(npc, Location(2824, 10050, 0), "dumb").also { targetLocation = Location(2824, 10050, 0) } + 7 -> { + // Out of sight death to trigger respawn. + npc.teleport(Location(2823, 10035, 0)) + npc.startDeath(null) + npc.setWalks(true) + return true + } + } + } + // Keep counting, if more than 100 ticks, end this pulse as a failsafe. + if (count > 100) { + npc.startDeath(null) + npc.setWalks(true) + return true + } + return false + } + }) + + } else { + sendMessage(player, "The cell door is locked.") + } + } + onUseWith(IntType.SCENERY, Items.CELL_KEY_1_3136, Scenery.CELL_DOOR_3765) { player, used, with -> + unlockMadEadgarCellDoor(player, with) + return@onUseWith true + } + on(Scenery.CELL_DOOR_3765, IntType.SCENERY, "unlock"){ player, node -> + unlockMadEadgarCellDoor(player, node) + return@on true + } + + + // Key to unlock Godric's cell + fun unlockGodricCellDoor(player: Player, node: Node) { + if (inInventory(player, Items.CELL_KEY_2_3137)){ + sendMessage(player, "You unlock the cell door.") + if (getQuestStage(player, Quests.TROLL_STRONGHOLD) == 8) { + setQuestStage(player, Quests.TROLL_STRONGHOLD, 10) + } else if (getQuestStage(player, Quests.TROLL_STRONGHOLD) == 9) { + setQuestStage(player, Quests.TROLL_STRONGHOLD, 11) + } + // Animate Godric leaving cell. + val npc = findNPC(NPCs.GODRIC_1114)!! + sendNPCDialogue(player, NPCs.GODRIC_1114, "Thank you, my friend.") + submitWorldPulse(object : Pulse(0) { + // This is basically chaining a series of walks + and door handler. + var count = 0 + var stage = 0 + var trigger = true + var targetLocation = Location(0, 0, 0) + override fun pulse(): Boolean { + if (npc.location.equals(targetLocation)){ + stage++ + trigger = true + } + if (trigger) { + trigger = false + when (stage) { + 0 -> forceWalk(npc, Location(2831, 10078, 0), "dumb").also { + npc.walkRadius = 11 + npc.setWalks(false) + targetLocation = Location(2831, 10078, 0) + } + 1 -> DoorActionHandler.handleAutowalkDoor(npc, node.asScenery()).also { targetLocation = Location(2832, 10078, 0) } + // Delay 2 ticks for DoorActionHandler to finish + 4 -> forceWalk(npc, Location(2836, 10078, 0), "dumb").also { targetLocation = Location(2836, 10078, 0) } + 5 -> forceWalk(npc, Location(2836, 10061, 0), "dumb").also { targetLocation = Location(2836, 10061, 0) } + 6 -> forceWalk(npc, Location(2824, 10050, 0), "dumb").also { targetLocation = Location(2824, 10050, 0) } + 7 -> { + // Out of sight death to trigger respawn. + npc.teleport(Location(2823, 10035, 0)) + npc.startDeath(null) + npc.setWalks(true) + return true + } + } + } + // Keep counting, if more than 100 ticks, end this pulse as a failsafe. + count++ + if (count > 100) { + npc.startDeath(null) + npc.setWalks(true) + return true + } + return false + } + }) + + } else { + sendMessage(player, "The cell door is locked.") + } + } + onUseWith(IntType.SCENERY, Items.CELL_KEY_2_3137, Scenery.CELL_DOOR_3767) { player, used, with -> + unlockGodricCellDoor(player, with) + return@onUseWith true + } + on(Scenery.CELL_DOOR_3767, IntType.SCENERY, "unlock"){ player, node -> + unlockGodricCellDoor(player, node) + return@on true; + } + + // Exit + on(Scenery.EXIT_3761, IntType.SCENERY, "open"){ player, _ -> + player.properties.teleportLocation = Location.create(2827, 3646, 0) + return@on true + } + + // Reentry Secret Door + on(Scenery.SECRET_DOOR_3762, IntType.SCENERY, "open"){ player, _ -> + if (getQuestStage(player, Quests.TROLL_STRONGHOLD) >= 8) { + player.properties.teleportLocation = Location.create(2824, 10050, 0) + } else { + sendMessage(player, "The door is locked.") + } + return@on true + } + } + + /** + * Method used to determine the success of a player when thieving. + * Copied from ThievingGuidePlugin + * @param player the player. + * @return `True` if successful, `False` if not. + */ + fun success(player: Player, skill: Int): Boolean { + val level = player.getSkills().getLevel(skill).toDouble() + val req = 30.0 + val successChance = ceil((level * 50 - req) / req / 3 * 4) + val roll = RandomFunction.random(99) + return successChance >= roll + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/TwigNpc.kt b/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/TwigNpc.kt new file mode 100644 index 0000000..deb316a --- /dev/null +++ b/Server/src/main/content/region/asgarnia/burthorpe/quest/trollstronghold/TwigNpc.kt @@ -0,0 +1,52 @@ +package content.region.asgarnia.burthorpe.quest.trollstronghold + +import content.data.Quests +import core.api.isQuestInProgress +import core.api.produceGroundItem +import core.game.node.entity.Entity +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class TwigNpc(id: Int = 0, location: Location? = null) : AbstractNPC(id, location) { + override fun construct(id: Int, location: Location, vararg objects: Any): AbstractNPC { + return TwigNpc(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.TWIG_1126, NPCs.TWIG_1128) + } + + // Transform from sleeping to awake. + override fun isAttackable(entity: Entity, style: CombatStyle, message: Boolean): Boolean { + val attackable = super.isAttackable(entity, style, message) + if (this.id == NPCs.TWIG_1128) { + val prevLifePoints = this.skills.lifepoints + this.transform(NPCs.TWIG_1126) + this.skills.lifepoints = prevLifePoints + } + return attackable + } + + override fun handleTickActions() { + super.handleTickActions() + // When returning to spawn, transform back to sleeping and keep lifepoints. + if (getAttribute("return-to-spawn", false) && this.id == NPCs.TWIG_1126) { + val prevLifePoints = this.skills.lifepoints + this.transform(NPCs.TWIG_1128) + this.skills.lifepoints = prevLifePoints + } + } + + override fun finalizeDeath(killer: Entity?) { + if (isQuestInProgress(killer as Player, Quests.TROLL_STRONGHOLD, 8, 10)) { + produceGroundItem(killer, Items.CELL_KEY_1_3136, 1, this.location) + } + super.finalizeDeath(killer) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/dialogue/CapelessMasterCrafterDialogue.kt b/Server/src/main/content/region/asgarnia/dialogue/CapelessMasterCrafterDialogue.kt new file mode 100644 index 0000000..135dc1c --- /dev/null +++ b/Server/src/main/content/region/asgarnia/dialogue/CapelessMasterCrafterDialogue.kt @@ -0,0 +1,29 @@ +package content.region.asgarnia.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class CapelessMasterCrafterDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun newInstance(player: Player): DialoguePlugin { + return CapelessMasterCrafterDialogue(player) + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + npcl( + FacialExpression.FRIENDLY, + "Hello, and welcome to the Crafting Guild. Accomplished crafters from all " + + "over the land come here to use our top notch workshops." + ).also { stage = END_DIALOGUE } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.MASTER_CRAFTER_2732) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/dialogue/CuffsDialogue.java b/Server/src/main/content/region/asgarnia/dialogue/CuffsDialogue.java new file mode 100644 index 0000000..261d856 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/dialogue/CuffsDialogue.java @@ -0,0 +1,78 @@ +package content.region.asgarnia.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the dialogue plugin used for the cuffs npc. + * @author 'Vexia + * @version 1.0 + * Fixed a typo -Nuggles + */ +@Initializable +public final class CuffsDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code CuffsDialogue} {@code Object}. + */ + public CuffsDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code CuffsDialogue} {@code Object}. + * @param player the player. + */ + public CuffsDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new CuffsDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello. nice day for a walk, isn't it?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "A walk? Oh, yes, that's what we're doing.", "We're just out here for a walk."); + stage = 1; + break; + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'm glad you're just out here for a walk. A more suspicious", "person would think you were waiting here to attack weak-", "looking travellers."); + stage = 2; + break; + case 2: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Nope, we'd never do anything like that.", "Just a band of innocent walkers, that's us."); + stage = 3; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Alright, have a nice walk."); + stage = 4; + break; + case 4: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 3237 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/dialogue/GrimgnashDialogue.java b/Server/src/main/content/region/asgarnia/dialogue/GrimgnashDialogue.java new file mode 100644 index 0000000..4d19b4e --- /dev/null +++ b/Server/src/main/content/region/asgarnia/dialogue/GrimgnashDialogue.java @@ -0,0 +1,78 @@ +package content.region.asgarnia.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the grimgnash dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class GrimgnashDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code GrimgnashDialogue} {@code Object}. + */ + public GrimgnashDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code GrimgnashDialogue} {@code Object}. + * @param player the player. + */ + public GrimgnashDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new GrimgnashDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "What you want, little human? Grimgnash hungry. Want", "tasty morsel like you!"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Like me? Why? Who are you?"); + stage = 1; + break; + case 1: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I Grimngnash and I hungry! Perhaps I eat you!"); + stage = 2; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'm really not that tasty. I think I should be going now.", "Goodbye."); + stage = 3; + break; + case 3: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Human lucky Grimgnash too tired to hunt for food. Stupid", "wolves keep Grimgnsh awake with howling. Grimgnash", "can't sleep."); + stage = 4; + break; + case 4: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 5997 }; + } + +} diff --git a/Server/src/main/content/region/asgarnia/dialogue/IcyCavernDialogue.java b/Server/src/main/content/region/asgarnia/dialogue/IcyCavernDialogue.java new file mode 100644 index 0000000..cdf4bf6 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/dialogue/IcyCavernDialogue.java @@ -0,0 +1,82 @@ +package content.region.asgarnia.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.game.world.map.Location; + +/** + * Represents the icy cavern dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class IcyCavernDialogue extends DialoguePlugin { + + /** + * Represents the dialogue id. + */ + public static final int ID = 238284; + + /** + * Represents the location to teleport to. + */ + private static final Location LOCATION = Location.create(3056, 9555, 0); + + /** + * Constructs a new {@code IcyCavernDialogue} {@code Object}. + */ + public IcyCavernDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code IcyCavernDialogue} {@code Object}. + * @param player the player. + */ + public IcyCavernDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new IcyCavernDialogue(player); + } + + @Override + public boolean open(Object... args) { + interpreter.sendDialogue("STOP! The creatures in this cave are VERY Dangerous. Are you", "sure you want to enter?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "Yes, I'm not afraid of death!", "No thanks, I don't want to die!"); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + end(); + player.getProperties().setTeleportLocation(LOCATION); + player.getPacketDispatch().sendMessage("You venture into the icy cavern."); + break; + case 2: + end(); + break; + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { ID }; + } +} diff --git a/Server/src/main/content/region/asgarnia/dialogue/JeffDialogue.java b/Server/src/main/content/region/asgarnia/dialogue/JeffDialogue.java new file mode 100644 index 0000000..22d4000 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/dialogue/JeffDialogue.java @@ -0,0 +1,69 @@ +package content.region.asgarnia.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the dialogue plugin used for the jeff npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class JeffDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code JeffDialogue} {@code Object}. + */ + public JeffDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code JeffDialogue} {@code Object}. + * @param player the player. + */ + public JeffDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new JeffDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Tell me, is the guard still watching us?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Why would you care if there's a guard watching you?"); + stage = 1; + break; + case 1: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Oh, forget it."); + stage = 2; + break; + case 2: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 3240 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/dialogue/LakkiDwarfDialogue.java b/Server/src/main/content/region/asgarnia/dialogue/LakkiDwarfDialogue.java new file mode 100644 index 0000000..96332b5 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/dialogue/LakkiDwarfDialogue.java @@ -0,0 +1,66 @@ +package content.region.asgarnia.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the dialogue used for lakki the dwarf npc. (holder dialogue until + * quest) + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class LakkiDwarfDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code LakkiDwarfDialogue} {@code Object}. + */ + public LakkiDwarfDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code LakkiDwarfDialogue} {@code Object}. + * @param player the player. + */ + public LakkiDwarfDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new LakkiDwarfDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello!"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I'm sorry, I can't talk right now."); + stage = 1; + break; + case 1: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 7722 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/dialogue/MasterCrafterDialogue.kt b/Server/src/main/content/region/asgarnia/dialogue/MasterCrafterDialogue.kt new file mode 100644 index 0000000..054dbf2 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/dialogue/MasterCrafterDialogue.kt @@ -0,0 +1,111 @@ +package content.region.asgarnia.dialogue + +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.global.Skillcape +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import core.tools.END_DIALOGUE + +/** + * @author bushtail + */ + +@Initializable +class MasterCrafterDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun newInstance(player: Player): DialoguePlugin { + return MasterCrafterDialogue(player) + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> npcl( + FacialExpression.FRIENDLY, + "Hello, and welcome to the Crafting Guild. Accomplished crafters from all " + + "over the land come here to use our top notch workshops." + ).also { stage++ } + + 1 -> { + if (Skillcape.isMaster(player, Skills.CRAFTING)) { + playerl( + FacialExpression.ASKING, + "Are you the person I need to talk to about buying a Skillcape of Crafting?" + ).also { stage = 100 } + } else { + end() + } + } + + 100 -> npcl( + FacialExpression.FRIENDLY, + "I certainly am, and I can see that you are definitely talented enough to own one! " + + "Unfortunately, being such a prestigious item, they are appropriately expensive. " + + "I'm afraid I must ask you for 99000 gold." + ).also { stage++ } + + 101 -> options( + "99000 gold! Are you mad?", + "That's fine." + ).also { stage++ } + + 102 -> { + when (buttonId) { + 1 -> playerl( + FacialExpression.ASKING, + "99000 gold! Are you mad?" + ).also { stage++ } + + 2 -> playerl( + FacialExpression.FRIENDLY, + "That's fine." + ).also { stage = 110 } + } + } + + 103 -> npcl( + FacialExpression.FRIENDLY, + "Not at all; there are many other adventurers who would love the opportunity to purchase " + + "such a prestigious item! You can find me here if you change your mind." + ).also { stage = END_DIALOGUE } + + 110 -> { + when { + !inInventory(player, Items.COINS_995, 99000) -> playerl( + FacialExpression.NEUTRAL, + "But, unfortunately, I don't have enough money with me." + ).also { stage = 111 } + + freeSlots(player) < 2 -> npcl( + FacialExpression.FRIENDLY, + "Unfortunately all Skillcapes are only available with a free hood, it's part " + + "of a skill promotion deal; buy one get one free, you know. So you'll need " + + "to free up some inventory space before I can sell you one." + ).also { stage = END_DIALOGUE } + + else -> { + Skillcape.purchase(player, Skills.CRAFTING) + npcl( + FacialExpression.FRIENDLY, + "Excellent! Wear that cape with pride my friend." + ).also { stage = END_DIALOGUE } + } + } + } + + 111 -> npcl( + FacialExpression.FRIENDLY, + "Well, come back and see me when you do." + ).also { stage = END_DIALOGUE } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.MASTER_CRAFTER_805) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/dialogue/NarfsDialogue.java b/Server/src/main/content/region/asgarnia/dialogue/NarfsDialogue.java new file mode 100644 index 0000000..30659ab --- /dev/null +++ b/Server/src/main/content/region/asgarnia/dialogue/NarfsDialogue.java @@ -0,0 +1,65 @@ +package content.region.asgarnia.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Handles the NarfsDialogue dialogue. + * @author 'Vexia + */ +@Initializable +public class NarfsDialogue extends DialoguePlugin { + + public NarfsDialogue() { + + } + + public NarfsDialogue(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[] { 3238 }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 1: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "'Narf'? You think that's funny?", "At least I Don't call myself '" + player.getDetails().getUsername() + "' ", "Where did you get a name like that?"); + stage = 100; + break; + case 100: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "It seemed like a good idea at the time!"); + stage = 101; + break; + case 101: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Bah!"); + stage = 102; + break; + case 102: + end(); + break; + + } + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new NarfsDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "That's a funny name you've got."); + stage = 1; + return true; + } +} diff --git a/Server/src/main/content/region/asgarnia/dialogue/OracleDialogue.java b/Server/src/main/content/region/asgarnia/dialogue/OracleDialogue.java new file mode 100644 index 0000000..b811dbc --- /dev/null +++ b/Server/src/main/content/region/asgarnia/dialogue/OracleDialogue.java @@ -0,0 +1,98 @@ +package content.region.asgarnia.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.game.node.entity.player.link.quest.Quest; +import content.data.Quests; + +/** + * Represents the oracle dialogue plugin related to dragon slayer. + * @author 'Vexia + */ +@Initializable +public final class OracleDialogue extends DialoguePlugin { + + /** + * Represents the quest instance. + */ + private Quest quest; + + /** + * Constructs a new {@code OracleDialogue} {@code Object}. + */ + public OracleDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code OracleDialogue} {@code Object}. + * @param player the player. + */ + public OracleDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new OracleDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + quest = player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER); + switch (quest.getStage(player)) { + case 20: + player("I seek a piece of the map to the island of Crandor."); + stage = 0; + break; + default: + player("Can you impart your wise knowledge on me, O Oracle?"); + stage = 0; + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (quest.getStage(player)) { + case 20: + switch (stage) { + case 0: + npc("The map's behind a door below,", "but entering is rather tough.", "This is that you need to know:", "You must use the following stuff."); + stage = 1; + break; + case 1: + npc("First, a drink used by a mage.", "Next, some worm string, changed to sheet.", "Then, a small crustacean cage.", "Last, a bowl that's not seen heat."); + stage = 2; + break; + case 2: + end(); + break; + } + break; + default: + switch (stage) { + case 0: + npc("Don't judge a book by its cover - judge it on its'", "grammar and punctuation."); + stage = 1; + break; + case 1: + end(); + break; + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 746 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/dialogue/RustyDialogue.java b/Server/src/main/content/region/asgarnia/dialogue/RustyDialogue.java new file mode 100644 index 0000000..82d8d60 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/dialogue/RustyDialogue.java @@ -0,0 +1,84 @@ +package content.region.asgarnia.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Handles the RustyDialogue dialogue. + * @author 'Vexia + */ +@Initializable +public class RustyDialogue extends DialoguePlugin { + + public RustyDialogue() { + + } + + public RustyDialogue(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[] { 3239 }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Why are you asking?"); + stage = 1; + break; + case 1: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Um... It's a quiz. I'm asking everyone I meet if they're", "carrying anything valuable."); + stage = 2; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What would you do if I said I had loads of expensive items", "with me?"); + stage = 3; + break; + case 3: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ooh, do you? It's been ages since anyone said they'd got", "anything worth stealing."); + stage = 4; + break; + case 4: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "'Anything worth stealing'?"); + stage = 5; + break; + case 5: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Um... Not that I'd dream of stealing anything!"); + stage = 6; + break; + case 6: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Well, I'll say I'm not carrying anything valuable at all."); + stage = 7; + break; + case 7: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Oh, what a shame."); + stage = 8; + break; + case 8: + end(); + break; + } + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new RustyDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hiya. Are you carrying anything valuable?"); + stage = 0; + return true; + } +} diff --git a/Server/src/main/content/region/asgarnia/dialogue/TannerDialogue.kt b/Server/src/main/content/region/asgarnia/dialogue/TannerDialogue.kt new file mode 100644 index 0000000..b4d9490 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/dialogue/TannerDialogue.kt @@ -0,0 +1,81 @@ +package content.region.asgarnia.dialogue + +import content.global.skill.crafting.TanningProduct +import core.api.amountInInventory +import core.api.inInventory +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.node.entity.npc.NPC +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import core.tools.END_DIALOGUE + +/** + * Handles the Crafting Guild Tanner's dialogue. + * @author bushtail + */ + +@Initializable +class TannerDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun newInstance(player: Player): DialoguePlugin { + return TannerDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npcl(FacialExpression.NEUTRAL, "Greetings friend. I am a manufacturer of leather.") + stage = 0 + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> { + var hasHides = false + + for (tanningProduct in TanningProduct.values()) { + if (inInventory(player, tanningProduct.item)) { + hasHides = true + break + } + } + + if(hasHides) { + npcl(FacialExpression.FRIENDLY, "I see you have brought me some hides. Would you like me to tan them for you?").also { stage = 10 } + } else { + options("Can I buy some leather?", "Leather is rather weak stuff.").also { stage = 20 } + } + } + + 10 -> options("Yes please.", "No thanks.").also { stage++ } + 11 -> when (buttonId) { + 1 -> playerl(FacialExpression.HAPPY, "Yes please.").also { stage = 12 } + 2 -> playerl(FacialExpression.NEUTRAL, "No thanks.").also { stage = 13 } + } + + 12 -> end().also { TanningProduct.open(player, NPCs.TANNER_804) } + 13 -> npcl(FacialExpression.FRIENDLY, "Very well, @g[sir,madam], as you wish.").also { stage = END_DIALOGUE } + + 20 -> when (buttonId) { + 1 -> playerl(FacialExpression.ASKING, "Can I buy some leather?").also { stage = 21 } + 2 -> playerl(FacialExpression.SUSPICIOUS, "Leather is rather weak stuff.").also { stage = 22 } + } + + 21 -> npcl(FacialExpression.FRIENDLY, "I make leather from animal hides. Bring me some cowhides and one gold coin per hide, and I'll tan them into soft leather for you.").also { stage = END_DIALOGUE } + + 22 -> npcl(FacialExpression.NOD_YES, "Normal leather may be quite weak, but it's very cheap - I make it from cowhides for only 1 gp per hide - and it's so easy to craft that anyone can work with it.").also { stage++ } + 23 -> npcl(FacialExpression.HALF_THINKING, "Alternatively you could try hard leather. It's not so easy to craft, but I only charge 3 gp per cowhide to prepare it, and it makes much sturdier armour.").also { stage++ } + 24 -> npcl(FacialExpression.FRIENDLY, "I can also tan snake hides and dragonhides, suitable for crafting into the highest quality armour for rangers.").also { stage++ } + 25 -> playerl(FacialExpression.NEUTRAL, "Thanks, I'll bear it in mind.").also { stage = END_DIALOGUE } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.TANNER_804) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/dialogue/TheDoorDialogues.kt b/Server/src/main/content/region/asgarnia/dialogue/TheDoorDialogues.kt new file mode 100644 index 0000000..fd7f6ba --- /dev/null +++ b/Server/src/main/content/region/asgarnia/dialogue/TheDoorDialogues.kt @@ -0,0 +1,29 @@ +package content.region.asgarnia.dialogue + +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import org.rs09.consts.NPCs +import core.game.dialogue.DialogueFile +import core.tools.END_DIALOGUE + +/** + * @author bushtail + */ + +class TheDoorDialogues(val it: Int) : DialogueFile() { + override fun handle(interfaceId: Int, buttonId: Int) { + npc = NPC(NPCs.MASTER_CRAFTER_805) + when(it) { + 0 -> when(stage) { + 0 -> npcl(FacialExpression.FRIENDLY, "Welcome to the Guild of Master Craftsmen.").also{ stage = END_DIALOGUE } + } + 1 -> when(stage) { + 0 -> npcl(FacialExpression.ASKING, "Where's your brown apron? You can't come in here unless you're wearing one.").also{ stage++ } + 1 -> player(FacialExpression.SAD, "Err... I haven't got one.").also { stage = END_DIALOGUE } + } + 2 -> when(stage) { + 0 -> npcl(FacialExpression.NEUTRAL, "Sorry, only experienced crafters are allowed in here. You must be level 40 or above to enter.").also{ stage = END_DIALOGUE } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/dialogue/ThuroDialogue.java b/Server/src/main/content/region/asgarnia/dialogue/ThuroDialogue.java new file mode 100644 index 0000000..af9e253 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/dialogue/ThuroDialogue.java @@ -0,0 +1,509 @@ +package content.region.asgarnia.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.plugin.Initializable; +import core.game.node.item.Item; +import content.data.Quests; + +/** + * Represents the dialogue plugin used for thurgo. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class ThuroDialogue extends DialoguePlugin { + + /** + * Represents the skillcape items. + */ + private static final Item[] ITEMS = new Item[] { new Item(9795), new Item(9796), new Item(9797) }; + + /** + * Represents the coins item. + */ + private static final Item COINS = new Item(995, 99000); + + /** + * Represents the redberry pie item. + */ + private static final Item REDBERRY_PIE = new Item(2325); + + /** + * Represents the blurite ore item. + */ + private static final Item BLURITE_ORE = new Item(668); + + /** + * Represents the iron bars item. + */ + private static final Item IRON_BARS = new Item(2351, 2); + + /** + * Represents the blurite sword item. + */ + private static final Item BLURITE_SWORD = new Item(667); + + /** + * Represents the current quest. + */ + private Quest quest; + + /** + * Constructs a new {@code ThuroDialogu} {@code Object}. + */ + public ThuroDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code ThuroDialogue} {@code Object}. + * @param player the player. + */ + public ThuroDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new ThuroDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + quest = player.getQuestRepository().getQuest(Quests.THE_KNIGHTS_SWORD); + player.removeAttribute("thurgo:1"); + switch (quest.getStage(player)) { + default: + interpreter.sendOptions("Ask a Question", "Skillcape of Smithing.", "Something else."); + stage = 0; + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + if (stage == 0 && buttonId == 1 || player.getAttribute("thurgo:1", false)) { + switch (stage) { + case 0: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "That's an unusual cape you're wearing, what is it?"); + stage = 10; + player.setAttribute("thurgo:1", true); + break; + case 2: + interpreter.sendDialogue("Thurgo doesn't appear to be interested in talking."); + stage = 9000; + break; + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "It's a Skillcape of Smithing. Shows that I am a master", "blacksmith, but of course that's only to be expected. I", "am an Imcando dwarf after all and everybody knows", "we're the best blacksmiths."); + stage = 11; + break; + case 9000: + end(); + break; + case 11: + if (player.getSkills().getLevel(Skills.SMITHING) == 99) { + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "Wow! An adventurer who is as skilled as me", "would you like to purchase a Skillcape of", "smithing for 99,000 coins?"); + stage = 12; + return true; + } + end(); + break; + case 12: + interpreter.sendOptions("Select an Option", "Yes, please.", "No, thanks."); + stage = 13; + break; + case 13: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Yes, please."); + stage = 15; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No, thanks."); + stage = 14; + break; + } + break; + case 14: + end(); + break; + case 15: + if (player.getInventory().freeSlots() < 2) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Sorry, I don't have enough room in my inventory."); + stage = 14; + return true; + } + if (!player.getInventory().containsItem(COINS)) { + end(); + return true; + } + if (!player.getInventory().remove(COINS)) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Sorry, I don't seem to have enough coins."); + stage = 14; + return true; + } + player.getInventory().add(player.getSkills().getMasteredSkills() >= 1 ? ITEMS[1] : ITEMS[0]); + player.getInventory().add(ITEMS[2]); + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "There you go! You're truley a master of Smithing."); + stage = 16; + break; + case 16: + end(); + break; + } + return true; + } + switch (quest.getStage(player)) { + case 60: + switch (stage) { + case 0: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "About that sword..."); + stage = 1; + break; + case 1: + if (player.getInventory().contains(667, 1) || player.getEquipment().contains(667, 1) || player.getBank().contains(667, 1)) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Thanks for all your help in getting it for me!"); + stage = 9; + } else { + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "How are you doing finding those sword materials?"); + stage = 2; + } + break; + case 2: + if (player.getInventory().containsItem(BLURITE_ORE) && player.getInventory().containsItem(IRON_BARS)) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I have them right here."); + stage = 5; + } else { + if (player.getInventory().containsItem(BLURITE_ORE)) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I don't have enough iron bars..."); + stage = 3; + return true; + } + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I don't have any blurite ore yet..."); + stage = 3; + } + break; + case 3: + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "Better go get some then, huh?"); + stage = 4; + break; + case 4: + end(); + break; + case 5: + interpreter.sendDialogue("You give the blurite ore and two iron bars to Thurgo. Thurgo starts", "to make the sword. Thurgo hands you a sword."); + stage = 6; + break; + case 6: + if (player.getInventory().remove(BLURITE_ORE) && player.getInventory().remove(IRON_BARS)) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Thank you very much!"); + player.getInventory().add(BLURITE_SWORD); + stage = 7; + } + break; + case 7: + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "Just remember to call in with more pie some time!"); + stage = 8; + break; + case 8: + end(); + break; + case 9: + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "No worries mate."); + stage = 10; + break; + case 10: + end(); + break; + } + break; + case 50: + switch (stage) { + case 0: + if (player.getInventory().contains(666, 1)) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I have found a picture of the sword I would like you to", "make."); + stage = 5; + } else { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "About that sword..."); + stage = 1; + } + break; + case 1: + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "Have you got a picture of the sword for me yet?"); + stage = 2; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Sorry, not yet."); + stage = 3; + break; + case 3: + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "Well, come back when you do."); + stage = 4; + break; + case 5: + interpreter.sendDialogue("You give the portrait to Thurgo. Thurgo studies the portrait."); + stage = 6; + break; + case 6: + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "Ok. You'll need to get me some stuff in order for me", "to make this."); + stage = 7; + break; + case 7: + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "I'll need two iron bars to make the sword to start with.", "I'll also need an ore called blurite. It's useless for", "making actual weapons for fighting with except", "crossbows, but I'll need some as decoration for the hilt."); + stage = 8; + break; + case 8: + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "It is fairly rare sort of ore... The only place I know", "where to get it is under this cliff here..."); + stage = 9; + break; + case 9: + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "But it is guarded by a very powerful ice giant."); + stage = 10; + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "Most of the rocks in that cliff are pretty useless, and", "don't contain much of anything, but there's", "DEFINITELY some blurite in there."); + stage = 11; + break; + case 11: + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "You'll need a little bit of mining experience to be able to", "find it."); + stage = 12; + break; + case 12: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Ok. I'll go and find them then."); + stage = 13; + break; + case 13: + if (player.getInventory().remove(new Item(666))) { + quest.setStage(player, 60); + end(); + } + break; + } + break; + case 40: + switch (stage) { + case 0: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "About that sword..."); + stage = 1; + break; + case 1: + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "Have you got a picture of the sword for me yet?"); + stage = 2; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Sorry, not yet."); + stage = 3; + break; + case 3: + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "Well, come back when you do."); + stage = 4; + break; + case 4: + end(); + break; + } + break; + case 30: + switch (stage) { + case 0: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Can you make me a special sword?"); + stage = 1; + break; + case 1: + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "Well, after bringing me my favorite food I guess I", "should give it a go. What sort of sword is it?"); + stage = 2; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I need you to make a sword for one of Falador's", "knights. He had one which was passed down through five", "generations, but his squire has lost it. So we need an", "identical one to replace it."); + stage = 3; + break; + case 3: + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "A Knight's sword eh? Well I'd need to know exactly", "how it looked before I could make a new one."); + stage = 4; + break; + case 4: + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "All the Faladian knights used to have swords with unique", "designs according to their position. Could you bring me", "a picture or something?"); + stage = 5; + break; + case 5: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'll go and ask if his squire and see if I can find one."); + stage = 6; + break; + case 6: + quest.setStage(player, 40); + end(); + break; + case 24: + end(); + break; + } + break; + case 20: + switch (stage) { + case 0: + if (player.getInventory().containsItem(REDBERRY_PIE)) { + interpreter.sendOptions("Select an Option", "Hello. Are you an Imcando dwarf?", "Would you like some redberry pie?"); + stage = 1; + } else { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello. Are you an Imcando dwarf?"); + stage = 10; + } + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello. Are you an Imcando dwarf?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Would you like some redberry pie?"); + stage = 20; + break; + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "Maybe. Who wants to know?"); + stage = 11; + break; + case 11: + if (player.getInventory().containsItem(REDBERRY_PIE)) { + interpreter.sendOptions("Select an Option", "Would you like some redberry pie?", "Can you make me a special sword?"); + stage = 12; + } else { + end(); + } + break; + case 12: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Would you like some redberry pie?"); + stage = 20; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Can you make me a special sword?"); + stage = 13; + break; + } + break; + case 13: + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "No, I don't do that anymore. I'm getting old."); + stage = 14; + break; + case 14: + end(); + break; + case 20: + interpreter.sendDialogue("You see Thurgo's eyes light up."); + stage = 21; + break; + case 21: + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "I'd never say no to a redberry pie! They're GREAT", "stuff!"); + stage = 22; + break; + case 22: + interpreter.sendDialogue("You hand over the pie. Thurgo eats the pie. Thurgo pats his", "stomach."); + stage = 23; + break; + case 23: + if (player.getInventory().remove(REDBERRY_PIE)) { + quest.setStage(player, 30); + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "By Guthix! THAT was good pie! Anyone who makes pie", "like THAT has got to be alright!"); + stage = 24; + } + break; + case 24: + end(); + break; + } + break; + default: + switch (stage) { + case 0: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "That's an unusual cape you're wearing, what is it?"); + stage = 10; + break; + case 2: + interpreter.sendDialogue("Thurgo doesn't appear to be interested in talking."); + stage = 9000; + break; + } + break; + case 9000: + end(); + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "It's a Skillcape of Smithing. Shows that I am a master", "blacksmith, but of course that's only to be expected. I", "am an Imcando dwarf after all and everybody knows", "we're the best blacksmiths."); + stage = 11; + break; + case 11: + if (player.getSkills().getLevel(Skills.SMITHING) == 99) { + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "Wow! An adventurer who is as skilled as me", "would you like to purchase a Skillcape of", "smithing for 99,000 coins?"); + stage = 12; + return true; + } + end(); + break; + case 12: + interpreter.sendOptions("Select an Option", "Yes, please.", "No, thanks."); + stage = 13; + break; + case 13: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Yes, please."); + stage = 15; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No, thanks."); + stage = 14; + break; + } + break; + case 14: + end(); + break; + case 15: + if (player.getInventory().freeSlots() < 2) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Sorry, I don't have enough room in my inventory."); + stage = 14; + return true; + } + if (!player.getInventory().remove(COINS)) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Sorry, I don't seem to have enough coins."); + stage = 14; + return true; + } + player.getInventory().add(player.getSkills().getMasteredSkills() >= 1 ? ITEMS[1] : ITEMS[0]); + player.getInventory().add(ITEMS[2]); + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "There you go! You're truley a master of Smithing."); + stage = 16; + break; + case 16: + end(); + break; + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 604 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/dialogue/YoungMasterCrafterDialogue.kt b/Server/src/main/content/region/asgarnia/dialogue/YoungMasterCrafterDialogue.kt new file mode 100644 index 0000000..84ae78c --- /dev/null +++ b/Server/src/main/content/region/asgarnia/dialogue/YoungMasterCrafterDialogue.kt @@ -0,0 +1,60 @@ +package content.region.asgarnia.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class YoungMasterCrafterDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun newInstance(player: Player): DialoguePlugin { + return YoungMasterCrafterDialogue(player) + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> npcl( + FacialExpression.HALF_ASKING, + "Yeah?" + ).also { stage++ } + + 1 -> playerl( + FacialExpression.FRIENDLY, + "Hello." + ).also { stage++ } + + 2 -> npcl( + FacialExpression.HALF_ASKING, + "Whassup?" + ).also { stage++ } + + 3 -> playerl( + FacialExpression.NEUTRAL, + "So... are you here to give crafting tips?" + ).also { stage++ } + + 4 -> npcl( + FacialExpression.ANNOYED, + "Dude, do I look like I wanna talk to you?" + ).also { stage++ } + + 5 -> playerl( + FacialExpression.NEUTRAL, + "I suppose not." + ).also { stage++ } + + 6 -> npcl( + FacialExpression.NEUTRAL, + "Right on!" + ).also { stage = END_DIALOGUE } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.MASTER_CRAFTER_2733) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/dialogue/ZandarHorfyreDialogue.kt b/Server/src/main/content/region/asgarnia/dialogue/ZandarHorfyreDialogue.kt new file mode 100644 index 0000000..191f723 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/dialogue/ZandarHorfyreDialogue.kt @@ -0,0 +1,53 @@ +package content.region.asgarnia.dialogue + +import core.api.teleport +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.TeleportManager +import core.game.world.map.Location +import core.plugin.Initializable +import core.tools.END_DIALOGUE + +/** + * @author bushtail + */ +@Initializable +class ZandarHorfyreDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun newInstance(player: Player) : DialoguePlugin { + return ZandarHorfyreDialogue(player) + } + + override fun open(vararg args: Any?) : Boolean { + npc = args[0] as NPC + player(FacialExpression.HALF_THINKING,"Who are you?") + stage = -1 + return true + } + + override fun handle(interfaceId: Int, buttonId: Int) : Boolean { + when (stage) { + -1 -> npcl(FacialExpression.NEUTRAL,"My name is Zandar Horfyre, and you, ${ player.username }, are trespassing in my tower, not to mention attacking my students! I thank you to leave immediately!").also{ stage++ } + 0 -> options("Ok, I was going anyway.", "No, I think I'll stay for a bit.").also{ stage++ } + 1 -> when(buttonId) { + 1 -> player("Ok, I was going anyway.").also{ stage = 10 } + 2 -> player("No, I think I'll stay for a bit.").also{ stage = 20 } + } + + 10 -> npcl(FacialExpression.NEUTRAL,"Good! And don't forget to close the door behind you!").also{ stage++ } + 11 -> stage = END_DIALOGUE + + 20 -> npcl(FacialExpression.ANNOYED,"Actually, that wasn't an invitation. I've tried being polite, now we'll do it the hard way!").also{ teleport(player, Location.create(3217, 3177, 0), TeleportManager.TeleportType.INSTANT) }.also{ stage++ } + 21 -> player(FacialExpression.ANGRY, "Zamorak curse that mage!").also{ stage++ } + 22 -> player(FacialExpression.LAUGH, "Actually, I guess he already has!").also{ stage++ } + 23 -> end() + } + return true + } + + override fun getIds() : IntArray { + return intArrayOf(3308) + } +} diff --git a/Server/src/main/content/region/asgarnia/dwarfmine/dialogue/DrogoDialogue.kt b/Server/src/main/content/region/asgarnia/dwarfmine/dialogue/DrogoDialogue.kt new file mode 100644 index 0000000..e5c2343 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/dwarfmine/dialogue/DrogoDialogue.kt @@ -0,0 +1,48 @@ +package content.region.asgarnia.dwarfmine.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class DrogoDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npc(FacialExpression.OLD_DEFAULT,"'Ello. Welcome to my Mining shop, friend.").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> options("Do you want to trade?", "Hello, shorty.", "Why don't you ever restock ores and bars?").also { stage++ } + 1 -> when (buttonId) { + 1 -> player(FacialExpression.FRIENDLY, "Do you want to trade?").also { stage = 10 } + 2 -> player(FacialExpression.FRIENDLY, "Hello, shorty.").also { stage = 20 } + 3 -> player(FacialExpression.FRIENDLY, "Why don't you ever restock ores and bars?").also { stage = 30 } + } + + 10 -> end().also { npc.openShop(player) } + 20 -> npc(FacialExpression.OLD_ANGRY1,"I may be short, but at least I've got manners.").also { stage = 99 } + 30 -> npc(FacialExpression.OLD_DEFAULT,"The only ores and bars I sell are those sold to me.").also { stage = 99 } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return DrogoDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.DROGO_DWARF_579) + } +} diff --git a/Server/src/main/content/region/asgarnia/dwarfmine/dialogue/DrokarDialogue.java b/Server/src/main/content/region/asgarnia/dwarfmine/dialogue/DrokarDialogue.java new file mode 100644 index 0000000..9bb5673 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/dwarfmine/dialogue/DrokarDialogue.java @@ -0,0 +1,69 @@ +package content.region.asgarnia.dwarfmine.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the dialogue plugin used for drokar. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class DrokarDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code DrokarDialogue} {@code Object}. + */ + public DrokarDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code DrokarDialogue} {@code Object}. + * @param player the player. + */ + public DrokarDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new DrokarDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello, how are you?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Packages, packages and more!"); + stage = 1; + break; + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Ugh.. Okay, have a good day."); + stage = 2; + break; + case 2: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 7729 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/dwarfmine/dialogue/DwarfShopDialogue.java b/Server/src/main/content/region/asgarnia/dwarfmine/dialogue/DwarfShopDialogue.java new file mode 100644 index 0000000..dbcbf2c --- /dev/null +++ b/Server/src/main/content/region/asgarnia/dwarfmine/dialogue/DwarfShopDialogue.java @@ -0,0 +1,73 @@ +package content.region.asgarnia.dwarfmine.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the dialouge plugin used for the dwarf shop. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class DwarfShopDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code DwarfShopDialogue} {@code Object}. + */ + public DwarfShopDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code DwarfShopDialogue} {@code Object}. + * @param player the player. + */ + public DwarfShopDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new DwarfShopDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.OLD_HAPPY, "Can I help you at all?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "Yes please, what are you selling?", "No thanks."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + end(); + npc.openShop(player); + break; + case 2: + end(); + break; + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 582 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/dwarfmine/dialogue/DwarvenMineGuardDialogue.kt b/Server/src/main/content/region/asgarnia/dwarfmine/dialogue/DwarvenMineGuardDialogue.kt new file mode 100644 index 0000000..e5d7c85 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/dwarfmine/dialogue/DwarvenMineGuardDialogue.kt @@ -0,0 +1,44 @@ +package content.region.asgarnia.dwarfmine.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class DwarvenMineGuardDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + player(FacialExpression.FRIENDLY,"Hello.").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> npcl(FacialExpression.OLD_ANGRY1, "Don't distract me while I'm on duty! This mine has to be protected!").also { stage++ } + 1 -> player(FacialExpression.FRIENDLY, "What's going to attack a mine?").also { stage++ } + 2 -> npcl(FacialExpression.OLD_ANGRY1, "Goblins! They wander everywhere, attacking anyone they think is small enough to be an easy victim. We need more cannons to fight them off properly.").also { stage++ } + 3 -> player(FacialExpression.FRIENDLY, "Well, I've done my bit to help with that.").also { stage++ } + 4 -> npcl(FacialExpression.OLD_ANGRY1, "Yes, I heard. Now please let me get on with my guard duties.").also { stage++ } + 5 -> player(FacialExpression.FRIENDLY, "Alright, I'll leave you alone now.").also { stage = 99 } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return DwarvenMineGuardDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.GUARD_206) + } +} diff --git a/Server/src/main/content/region/asgarnia/dwarfmine/dialogue/HuraDialogue.java b/Server/src/main/content/region/asgarnia/dwarfmine/dialogue/HuraDialogue.java new file mode 100644 index 0000000..41e01ec --- /dev/null +++ b/Server/src/main/content/region/asgarnia/dwarfmine/dialogue/HuraDialogue.java @@ -0,0 +1,156 @@ +package content.region.asgarnia.dwarfmine.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the dialogue plugin used for the hura npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class HuraDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code HuraDialogue} {@code Object}. + */ + public HuraDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code HuraDialogue} {@code Object}. + * @param player the player. + */ + public HuraDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new HuraDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "'Ello " + player.getUsername() + "."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello, what's that you've got there?"); + stage = 1; + break; + case 1: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "A crossbow, are you interested?"); + stage = 2; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Maybe, are they any good?"); + stage = 3; + break; + case 3: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Are they any good?! They're dwarven engrineering at", "its best!"); + stage = 4; + break; + case 4: + interpreter.sendOptions("Select an Option", "How do I make one for myself?", "What about ammo?", "Thanks for teling me. Bye!"); + stage = 5; + break; + case 5: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "How do I make one for myself?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What about ammo?"); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Thanks for telling me. Bye!"); + stage = 30; + break; + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Well, firstly you'll need to chop yourself some wood,", "then use a knife on the wood to whittle out a nice", "crossbow stock like these here."); + stage = 11; + break; + case 11: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Wood fletched into stock... check."); + stage = 12; + break; + case 12: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Then get yourself some metal and a hammer and smith", "yourself some limbs for the bow, mind that you use the", "right metals and wood though as some wood is too light", "to use with some metal and vice versa."); + stage = 13; + break; + case 13: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Which goes with which?"); + stage = 14; + break; + case 14: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Wood and Bronze as they're basic materials, Oak and", "Blurite, Willow and Iron, Steel and Teak, Mithril and", "Maple, Adamantite and Mahogany and finally Runite", "and Yew."); + stage = 15; + break; + case 15: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Ok, so I have my stock and a pair of limbs... what now?"); + stage = 16; + break; + case 16: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Simply take a hammer and smack the limbs firmly onto", "the stock. You'll need a string, only they're not", "the same as normal bows. You'll need to dry some large", "animal's meat to get sinew, then spin that on a spinning"); + stage = 17; + break; + case 17: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "wheel, it's the only thing we've found to be strong", "enough for a crossbow."); + stage = 18; + break; + case 18: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Thanks for telling me. Bye!"); + stage = 30; + break; + case 30: + end(); + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "You can smith yourself lots of different bolts, don't", "forget to flight them with feathers like you do arrows", "though. You can poison any untipped bolt but there's", "also the option of tipping them with gems then"); + stage = 21; + break; + case 21: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "enchanting them with runes. This can have some pretty", "powerful effects."); + stage = 22; + break; + case 22: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Oh my poor bank, how will I store all those?!"); + stage = 23; + break; + case 23: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Find Hirko in Keldagrim, he also sells crossbow parts", "and I'm sure he has something you can use to store", "bolts in."); + stage = 24; + break; + case 24: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Thanks for the info."); + stage = 25; + break; + case 25: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 4563 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/dwarfmine/dialogue/MiningSkillCapeDwarfDialogue.java b/Server/src/main/content/region/asgarnia/dwarfmine/dialogue/MiningSkillCapeDwarfDialogue.java new file mode 100644 index 0000000..b82f8f6 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/dwarfmine/dialogue/MiningSkillCapeDwarfDialogue.java @@ -0,0 +1,192 @@ +package content.region.asgarnia.dwarfmine.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.game.node.item.Item; + +/** + * Represents the skillcape dwarfs dialogue plugin. + * @author 'Vexia + * @version 1.5 + */ +@Initializable +public final class MiningSkillCapeDwarfDialogue extends DialoguePlugin { + + /** + * Represents the items used for skillcape purchasing. + */ + private static final Item[] ITEMS = new Item[] { new Item(9792), new Item(9793), new Item(9794) }; + + /** + * Represents the coins required to buy a skillcape. + */ + private static final Item COINS = new Item(995, 99000); + + /** + * Constructs a new {@code MiningSkillCapeDwarfDialogue} {@code Object}. + */ + public MiningSkillCapeDwarfDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code MiningSkillCapeDwarfDialogue} {@code Object}. + * @param player the player. + */ + public MiningSkillCapeDwarfDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new MiningSkillCapeDwarfDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "Welcome to the Mining Guild.", "Can I help you with anything?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("What would you like to say?", "What have you got in the Guild?", "What do you dwarves do with the ore you mine?", "Can you tell me about your skillcape?", "No thanks, I'm fine."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What have you got in the guild?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What do you dwarves do with the ore you mine?"); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Can you tell me about your skillcape?"); + stage = 40; + break; + case 4: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No thanks, I'm fine."); + stage = 30; + break; + + } + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "What do you think? We smelt it into bars, smith the metal", "to make armour and weapons, then we exchange them for", "goods and services."); + stage = 21; + break; + case 21: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I don't see many dwarves", "selling armour or weapons here."); + stage = 22; + break; + case 22: + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "No, this is only a mining outpost. We dwarves don't much", "like to settle in human cities. Most of the ore is carted off", "to Keldagrim, the great dwarven city. They've got a", "special blast furnace up there - it makes smelting the ore"); + stage = 12; + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "Ooh, it's WONDERFUL! There are lots of coal rocks,", "and even a few mithril rocks in the guild,", "all exclusively for people with at least level 60 mining.", "There's no better mining site anywhere near here."); + stage = 11; + break; + case 11: + interpreter.sendOptions("What would you like to say?", "What have you got in the Guild?", "What do you dwarves do with the ore you mine?", "Can you tell me about your skillcape?", "No thanks, I'm fine."); + stage = 1; + break; + case 12: + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "so much easier. There are plenty of dwarven traders", "working in Keldagrim. Anyway, can I help you with anything ", "else?"); + stage = 11; + break; + case 30: + end(); + break; + case 40: + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "Sure, this is a Skillcape of Mining. It shows my stature as", "a master miner! It has all sorts of uses , if you", "have a level of 99 mining I'll sell you one."); + stage = 41; + break; + case 41: + if (player.getSkills().getStaticLevel(Skills.MINING) < 99) { + interpreter.sendOptions("What would you like to say?", "What have you got in the Guild?", "What do you dwarves do with the ore you mine?", "Can you tell me about your skillcape?", "No thanks, I'm fine."); + stage = 1; + } else { + options("I'd like to buy a Skillcape of Mining.", "Goodbye."); + stage = 43; + } + break; + case 43: + switch (buttonId) { + case 1: + player("I'd like to buy a Skillcape of Mining."); + stage = 45; + break; + case 2: + player("Goodbye."); + stage = 44; + break; + } + break; + case 44: + end(); + break; + case 45: + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "It will cost you 99,000 gold coins, are you sure?"); + stage = 46; + break; + case 46: + options("Yes.", "No."); + stage = 47; + break; + case 47: + switch (buttonId) { + case 1: + player("Yes."); + stage = 48; + break; + case 2: + end(); + break; + } + break; + case 48: + if (!player.getInventory().containsItem(COINS)) { + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "You need 99,000 gold coins in order to buy a Skillcape", "of mining."); + stage = 44; + return true; + } + if (player.getInventory().freeSlots() < 2) { + player.getPacketDispatch().sendMessage("You don't have enough room in your inventory."); + end(); + return true; + } + if (!player.getInventory().containsItem(COINS)) { + end(); + return true; + } + if (player.getInventory().remove(COINS) && player.getInventory().add(ITEMS[player.getSkills().getMasteredSkills() > 1 ? 1 : 0], ITEMS[2])) { + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "Thanks!"); + stage = 49; + } + break; + case 49: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 3295 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/dwarfmine/dialogue/NurmofDialogue.kt b/Server/src/main/content/region/asgarnia/dwarfmine/dialogue/NurmofDialogue.kt new file mode 100644 index 0000000..366bbfa --- /dev/null +++ b/Server/src/main/content/region/asgarnia/dwarfmine/dialogue/NurmofDialogue.kt @@ -0,0 +1,59 @@ +package content.region.asgarnia.dwarfmine.dialogue + +import core.api.getAttribute +import core.api.setAttribute +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class NurmofDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npcl(FacialExpression.OLD_NORMAL,"Greetings and welcome to my pickaxe shop. Do you want to buy my premium quality pickaxes?").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> options("Yes, please.", "No, thank you.", "Are your pickaxes better than other pickaxes, then?").also { stage++ } + + 1 -> when (buttonId) { + 1 -> end().also { npc.openShop(player) } + 2 -> player(FacialExpression.FRIENDLY, "No thank you.").also { stage = 99 } + 3 -> player(FacialExpression.HALF_ASKING, "Are your pickaxes better than other pickaxes, then?").also { stage = 10 } + } + + 10 -> npcl(FacialExpression.OLD_NORMAL,"Of course they are! My pickaxes are made of higher grade metal than your ordinary bronze pickaxes, allowing you to mine ore just that little bit faster.").also { + if(!getAttribute(player, "pre-dq:said-hi", true)) { + stage++ + } else { + stage = 99 + } + } + 11 -> playerl(FacialExpression.FRIENDLY, "By the way, Doric says hello!").also { stage++ } + 12 -> npcl(FacialExpression.OLD_HAPPY, "Oh! Thank you for telling me, adventurer!").also { stage = 99 } + 99 -> { + setAttribute(player, "pre-dq:said-hi", true) + end() + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return NurmofDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.NURMOF_594) + } +} diff --git a/Server/src/main/content/region/asgarnia/dwarfmine/dialogue/RoladDialogue.java b/Server/src/main/content/region/asgarnia/dwarfmine/dialogue/RoladDialogue.java new file mode 100644 index 0000000..b59a9b3 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/dwarfmine/dialogue/RoladDialogue.java @@ -0,0 +1,60 @@ +package content.region.asgarnia.dwarfmine.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Handles the RoladDialogue dialogue. + * @author 'Vexia + */ +@Initializable +public class RoladDialogue extends DialoguePlugin { + + public RoladDialogue() { + + } + + public RoladDialogue(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[] { 1841 }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Ehm... well... my name is " + player.getUsername() + ", if that rings any bell?"); + stage = 1; + break; + case 1: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "No, never heard of you."); + stage = 2; + break; + case 2: + end(); + break; + } + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new RoladDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Oh, hello... do I know you?"); + stage = 0; + return true; + } +} diff --git a/Server/src/main/content/region/asgarnia/falador/dialogue/AmbassadorSpanfippleDialogue.kt b/Server/src/main/content/region/asgarnia/falador/dialogue/AmbassadorSpanfippleDialogue.kt new file mode 100644 index 0000000..3d94098 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/dialogue/AmbassadorSpanfippleDialogue.kt @@ -0,0 +1,62 @@ +package content.region.asgarnia.falador.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + + +/** + * @author qmqz + */ + +@Initializable +class AmbassadorSpanfippleDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npc(FacialExpression.OLD_DEFAULT,"It's all very white round here, isn't it?").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> { + player(FacialExpression.THINKING, "Well, it is the White Knights' Castle.").also { stage++ } + } + + 1 -> { + npcl(FacialExpression.OLD_DEFAULT, "I think it would all look better in pink. At least then I wouldn't be squinting all the time.").also { stage++ } + } + + 2 -> { + playerl(FacialExpression.FRIENDLY, "Yes, but then they'd have to become the Pink Knights. I think they'd have problems recruiting then.").also { stage++ } + } + + 3 -> { + npc(FacialExpression.OLD_DEFAULT, "You're probably right. Maybe brown, then.").also { stage++ } + } + + 4 -> { + player(FacialExpression.HALF_THINKING, "I think that may be worse...").also { stage++ } + } + + 5 -> { + npc(FacialExpression.OLD_ANGRY1, "Bah, humans have no sense of style...").also { stage = 99 } + } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return AmbassadorSpanfippleDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.AMBASSADOR_SPANFIPPLE_4581) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/falador/dialogue/ApprenticeWorkmanDialogue.kt b/Server/src/main/content/region/asgarnia/falador/dialogue/ApprenticeWorkmanDialogue.kt new file mode 100644 index 0000000..b3aa282 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/dialogue/ApprenticeWorkmanDialogue.kt @@ -0,0 +1,41 @@ +package content.region.asgarnia.falador.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +/** + * @author qmqz + * https://youtu.be/DwQgAQqaXos + */ + +@Initializable +class ApprenticeWorkmanDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + START_DIALOGUE -> player(FacialExpression.FRIENDLY, "Hiya.").also { stage++ } + 1 -> npc(FacialExpression.SAD, "Sorry, I haven't got time to chat. We've only just", + "finished a collossal order of furniture for the Varrock", + "area, and already there's more work coming in.").also { stage++ } + 2 -> player(FacialExpression.ASKING, "Varrock?").also { stage++ } + 3 -> npc(FacialExpression.ROLLING_EYES, "Yeah, the Council's had it redecorated.").also { stage++ } + 4 -> npc(3236, "Oi - stop gabbing and get that chair finished!").also { stage++ } // ANNOYED + 5 -> npc(FacialExpression.SAD, "You'd better let me get on with my work.").also { stage++ } + 6 -> player(FacialExpression.NEUTRAL, "Ok, bye.").also { stage = END_DIALOGUE } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return ApprenticeWorkmanDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.APPRENTICE_WORKMAN_3235) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/falador/dialogue/CassieDialogue.java b/Server/src/main/content/region/asgarnia/falador/dialogue/CassieDialogue.java new file mode 100644 index 0000000..d509b21 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/dialogue/CassieDialogue.java @@ -0,0 +1,77 @@ +package content.region.asgarnia.falador.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the dialogue plugin used for the cassie npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class CassieDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code CassieDialogue} {@code Object}. + */ + public CassieDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code CassieDialogue} {@code Object}. + * @param player the player. + */ + public CassieDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new CassieDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "I buy and sell shields; do you want to trade?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "Yes, please.", "No, thank you."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + end(); + npc.openShop(player); + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HAPPY, "No, thank you."); + stage = 20; + break; + } + break; + case 20: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 577 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/falador/dialogue/ChemistDialogue.java b/Server/src/main/content/region/asgarnia/falador/dialogue/ChemistDialogue.java new file mode 100644 index 0000000..8c82557 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/dialogue/ChemistDialogue.java @@ -0,0 +1,416 @@ +package content.region.asgarnia.falador.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.AchievementDiary; +import core.game.node.entity.player.link.diary.DiaryType; +import core.plugin.Initializable; +import core.game.node.item.Item; + +/** + * Handles the chemist dialogue. + * + * @author Vexia + */ +@Initializable +public final class ChemistDialogue extends DialoguePlugin { + private boolean replacementReward = false; + private int level = 1; + + /** + * Constructs a new {@code ChemistDialogue} {@code Object}. + */ + public ChemistDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code ChemistDialogue} {@code Object}. + * + * @param player the player. + */ + public ChemistDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new ChemistDialogue(player); + } + + @Override + public boolean open(Object... args) { + interpreter.sendOptions("Do you want to talk about lamps?", "Yes.", "No.", "No, I'm more interested in impling jars.", "Falador Achievement Diary"); + stage = 0; + replacementReward = AchievementDiary.canReplaceReward(player, DiaryType.FALADOR, level); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + switch (buttonId) { + case 1: + player("Hi, I need fuel for a lamp."); + stage = 10; + break; + case 2: + player("Hello."); + stage = 20; + break; + case 3: + player("I have a slightly odd question."); + stage = 30; + break; + case 4: + npc("How are you getting on with the Achievement Diary?"); + stage = -1; + break; + } + break; + case 10: + npc("Hello there, the fuel you need is lamp oil, do you need", "help making it?"); + stage++; + break; + case 11: + player("Yes, please."); + stage++; + break; + case 12: + npc("It's really quite simple. You use the small still in here.", "It's all set up, so there's no fiddling around with dials..."); + stage++; + break; + case 13: + npc("Just put ordinary swamp tar in, and then use a lantern", "or lamp to get the oil out."); + stage++; + break; + case 14: + player("Thanks."); + stage++; + break; + case 15: + end(); + break; + case 20: + npc("Oh.. hello, how's it going?"); + stage++; + break; + case 21: + player("Good thanks."); + stage++; + break; + case 22: + npc("Good to hear, sorry but I have a few things to do", "now."); + stage++; + break; + case 23: + player("Well I'd better let you get on then."); + stage++; + break; + case 24: + end(); + break; + case 30: + npc("Jolly good, the odder the better. I like oddities."); + stage++; + break; + case 31: + player("Do you know how I might distill a mix of anchovy oil", "and flowers so that it forms a layer on the inside of a", "butterfly jar?"); + stage++; + break; + case 32: + npc("That is an odd question. I commend you for it. Why", "would you want to do that?"); + stage++; + break; + case 33: + player("Apparently, if I can make a jar like this it will be useful", "for storing implings in."); + stage++; + break; + case 34: + npc("My lamp oil still may be able to do what you want. Use the", "oil and flower mix on the still."); + stage++; + break; + case 35: + npc("Once that's done. Use one of those butterfly jars to", "collect the distillate."); + stage++; + break; + case 36: + player("Thanks!"); + stage++; + break; + case 37: + options("So how do you make anchovy oil?", "Do you have a sieve I can use?", "I'd better go and get the repellent."); + stage++; + break; + case 38: + switch (buttonId) { + case 1: + player("So, how do you make anchovy oil?"); + stage = 50; + break; + case 2: + player("Do you have a sieve I can use?"); + stage = 55; + break; + case 3: + player("I'd better go and get the repellent."); + stage = 51; + break; + } + break; + case 50: + npc("Anchovies are pretty oily fish. I'd have thought you", "could just grind them up and sieve out the bits. You'd", "probably want to remove any water first - Cooking", "should do that pretty well."); + stage++; + break; + case 51: + end(); + break; + case 55: + if (player.hasItem(new Item(6097))) { + npc("Errm, yes. But you already have one. Two sieves is a ", "bit exessive, don't you think?"); + stage = 60; + break; + } + npc("Errm, yes. Here have this one. It's only been used for", "sieving dead rats out of sewer water."); + stage++; + break; + case 56: + player("Err, why? Actually, on second thoughts I don't want to", "know."); + stage++; + break; + case 57: + npc("Well, it would be ideally suited to your task."); + stage++; + break; + case 58: + player("Fair enough."); + stage++; + break; + case 59: + player.getInventory().add(new Item(6097), player); + end(); + break; + case 60: + end(); + break; + + case -1: + if (replacementReward) { + player("I seem to have lost my Falador shield..."); + stage = 80; + } else { + npc("How are you getting on with the Achievement Diary?"); + stage = 90; + } + break; + case 80: + AchievementDiary.grantReplacement(player, DiaryType.FALADOR, level); + npc("Here's your replacement. Please be more careful."); + stage = 999; + break; + + case 90: + options("I've come for my reward.", "I'm doing good.", "I have a question."); + stage = 91; + break; + case 91: + switch (buttonId) { + case 1: + player("I've come for my reward."); + stage = 200; + break; + case 2: + player("I'm doing good."); + stage = 220; + break; + case 3: + player("I have a question."); + stage = 105; + break; + } + break; + // https://www.youtube.com/watch?v=ZW9k1922Ggk + case 105: + if (!AchievementDiary.hasClaimedLevelRewards(player, DiaryType.FALADOR, level)) { + options("What is the Achievement Diary?", "What are the rewards?", "How do I claim the rewards?", "See you later."); + stage = 106; + } else { + options("Can you remind me what my Falador shield does, please?", "What is the Achievement Diary?", "What are the rewards?", "How do I claim the rewards?", "See you later."); + stage = 107; + } + break; + case 106: + switch (buttonId) { + case 1: + player("What is the Achievement Diary?"); + stage = 110; + break; + case 2: + player("What are the rewards?"); + stage = 120; + break; + case 3: + player("How do I claim the rewards?"); + stage = 130; + break; + case 4: + player("See you later."); + stage = 999; + break; + } + break; + + case 107: + switch (buttonId) { + case 1: + player("Can you remind me what my Falador shield does, please?"); + stage = 150; + break; + case 2: + player("What is the Achievement Diary?"); + stage = 110; + break; + case 3: + player("What are the rewards?"); + stage = 120; + break; + case 4: + player("How do I claim the rewards?"); + stage = 130; + break; + case 5: + player("See you later."); + stage = 999; + break; + } + break; + + case 110: + npc("Ah, well, it's a diary that helps you keep track of", "particular achievements you've made here on Gielinor."); + stage = 111; + break; + case 111: + npc("If you manage to complete a particular set of tasks,", "you will be rewarded for your explorative efforts."); + stage = 112; + break; + case 112: + npc("You can access your Achievement Diary by going to", "the Quest Journal, then clicking on the green star icon", "in the top-right hand corner."); + stage = 105; + break; + + case 120: + npc("Ah, well there are different rewards for each", "Achievement Diary. For completing each stage of the", "Falador diary, you are presented with a Falador shield."); + stage = 121; + break; + case 121: + npc("There are three shields available, one for each difficulty", "level."); + stage = 122; + break; + case 122: + npc("When you are presented with your rewards, you will", "be told of their uses."); + stage = 105; + break; + + case 130: + npc("You need to complete all of the tasks in a particular", "difficulty, then you can claim your reward."); + stage = 131; + break; + case 131: + npc("Some of Falador's tasks are simple, some will require", "certain skill levels, and some might require quests to be", "started or completed."); + stage = 132; + break; + case 132: + npc("To claim your Falador Achievement Diary rewards,", "speak to Redbeard the Pirate in Port Sarim, Sir Vyvin's", "squire in the White Knight's Castle, or myself."); + stage = 105; + break; + + case 150: + npc("This is the second stage of the Falador shield: a kite", "shield. It grants you all the benefits fo the buckler, but", "with increased Prayer restore, and Farming experience", "when using the patches near Falador."); + stage = 151; + break; + case 151: + npc("As before, Prayer restore can only be used once per", "day, but it now restores half of your Prayer points."); + stage = 152; + break; + case 152: + npc("The increased Farming experience is only available at", "the allotments, flower and herb patches found just north", "of Port Sarim."); + stage = 153; + break; + case 153: + npc("As well as all of these features, the shield is pretty", "handy in combat, and gives you a good Prayer boost."); + stage = 105; + break; + + case 200: + if (AchievementDiary.hasClaimedLevelRewards(player, DiaryType.FALADOR, level)) { + npc("But you've already gotten yours!"); + stage = 105; + } else if (AchievementDiary.hasCompletedLevel(player, DiaryType.FALADOR, level)) { + npc("So, you've finished. Well done! I believe congratulations", "are in order."); + stage = 201; + } else { + npc("But you haven't finished!"); + stage = 105; + } + break; + case 201: + player("I believe rewards are in order."); + stage = 202; + break; + case 202: + npc("Right you are."); + stage = 203; + break; + case 203: + npc("This is the second stage of the Falador shield: a kite", "shield. It grants you all the benefits fo the buckler, but", "with increased Prayer restore, and Farming experience", "when using the patches near Falador."); + if (!AchievementDiary.hasClaimedLevelRewards(player, DiaryType.FALADOR, level)) { + AchievementDiary.flagRewarded(player, DiaryType.FALADOR, level); + } + stage = 204; + break; + case 204: + npc("As before, Prayer restore can only be used once per", "day, but it now restores half of your Prayer points."); + stage = 205; + break; + case 205: + npc("The increased Farming experience is only available at", "the allotments, flower and herb patches found just north", "of Port Sarim."); + stage = 206; + break; + case 206: + npc("As well as all of these features, the shield is pretty", "handy in combat, and gives you a good Prayer boost."); + stage = 207; + break; + case 207: + npc("I've even thrown in an old lamp I found. Try as I", "might, I can't fill it with fuel or get it to light."); + stage = 208; + break; + case 208: + interpreter.sendDialogues(player, FacialExpression.AMAZED, "Wow, thanks!"); + stage = 209; + break; + case 209: + npc("If you should lose your shield, come back and see me", "for another one."); + stage = 105; + break; + case 220: + npc("Keep it up!"); + stage = 105; + break; + + case 999: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[]{367}; + } + +} diff --git a/Server/src/main/content/region/asgarnia/falador/dialogue/DoricDialogue.kt b/Server/src/main/content/region/asgarnia/falador/dialogue/DoricDialogue.kt new file mode 100644 index 0000000..0d8e029 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/dialogue/DoricDialogue.kt @@ -0,0 +1,171 @@ +package content.region.asgarnia.falador.dialogue + +import content.region.asgarnia.falador.quest.doricsquest.DoricDoricsQuestDialogue +import core.api.* +import core.game.activity.Cutscene +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.IfTopic +import core.game.dialogue.Topic +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.world.GameWorld.settings +import core.game.world.map.Direction +import core.game.world.map.Location +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs +import content.data.Quests + +@Initializable +class DoricDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + val qStage = getQuestStage(player, Quests.DORICS_QUEST) + if(qStage == 0) { + npcl(FacialExpression.OLD_NORMAL, "Hello traveller, what brings you to my humble smithy?").also { stage = 0 } + } else if(qStage in 1..99) { + openDialogue(player, DoricDoricsQuestDialogue(30), npc) + } else { + npcl(FacialExpression.OLD_HAPPY, "Hello traveller, how is your metalworking coming along?").also { stage = 60 } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage) { + 0 -> showTopics( + Topic(FacialExpression.FRIENDLY, "I wanted to use your anvils.", 10), + Topic(FacialExpression.FRIENDLY, "I wanted to use your whetstone.", 20), + IfTopic(FacialExpression.ANNOYED, "Mind your own business, shortstuff!", 30, !getAttribute(player, "pre-dq:doric-calm", false), true), + Topic(FacialExpression.FRIENDLY, "I was just checking out the landscape.", 40), + Topic(FacialExpression.ASKING, "What do you make here?", 50) + ) + + 10 -> openDialogue(player, DoricDoricsQuestDialogue(10), npc) + + 20 -> openDialogue(player, DoricDoricsQuestDialogue(20), npc) + + 30 -> { + if(getAttribute(player, "pre-dq:doric-angy-count", 0) == 10) { + end() + PDC(player).start() + } else { + setAttribute(player, "/save:pre-dq:doric-angy-count", getAttribute(player, "pre-dq:doric-angy-count", 0) + 1) + npcl(FacialExpression.OLD_ANGRY1, "How nice to meet someone with such pleasant manners. Do come again when you need to shout at someone smaller than you!").also { stage = END_DIALOGUE } + } + } + + 40 -> { + npcl(FacialExpression.OLD_HAPPY, "Hope you like it. I do enjoy the solitude of my little home. If you get time, please say hi to my friends in the Dwarven Mine.") + setAttribute(player, "/save:pre-dq:said-hi", false) + stage = END_DIALOGUE + } + + 50 -> npcl(FacialExpression.OLD_NORMAL, "I make pickaxes. I am the best maker of pickaxes in the whole of ${settings!!.name}.").also { stage++ } + 51 -> playerl(FacialExpression.HALF_ASKING, "Do you have any to sell?").also { stage++ } + 52 -> npcl(FacialExpression.OLD_NOT_INTERESTED, "Sorry, but I've got a running order with Nurmof.").also { stage++ } + 53 -> playerl(FacialExpression.FRIENDLY, "Ah, fair enough.").also { stage = END_DIALOGUE } + + 60 -> playerl(FacialExpression.FRIENDLY, "Not too bad, Doric.").also { stage++ } + 61 -> npcl(FacialExpression.OLD_HAPPY, "Good, the love of metal is a thing close to my heart.").also { stage++ } + 62 -> { + if(getAttribute(player, "pre-dq:said-hi", false)) { + playerl(FacialExpression.FRIENDLY, "By the way, I told Nurmof you said hello.") + stage++ + } else { + end() + } + } + 63 -> { + npcl(FacialExpression.OLD_HAPPY, "Thank you traveller! You'll always be welcome in my home.") + removeAttribute(player, "pre-dq:said-hi") + rewardXP(player, Skills.MINING, 5.0) + stage = END_DIALOGUE + } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.DORIC_284) + } +} + +class PDC(player: Player) : Cutscene(player) { + override fun setup() { + setExit(Location(2952, 3450)) + loadRegion(11829) + addNPC(NPCs.DORIC_284, 9, 58, Direction.WEST) + } + + override fun runStage(stage: Int) { + when(stage) { + 0 -> { + fadeToBlack() + timedUpdate(6) + } + 1 -> { + teleport(player, 8, 58) + moveCamera(6, 60, 250) + rotateCamera(8, 58, 75) + player.faceLocation(getNPC(NPCs.DORIC_284)!!.location) + getNPC(NPCs.DORIC_284)!!.faceLocation(player.location) + timedUpdate(2) + } + 2 -> { + fadeFromBlack() + getNPC(NPCs.DORIC_284)!!.faceLocation(player.location) + timedUpdate(2) + } + 3 -> { + sendChat(player, "Mind your own business, shortstuff!") + timedUpdate(6) + } + 4 -> { + sendChat(getNPC(NPCs.DORIC_284)!!, "I guess your mother never taught you manners. Lucky for you, I'll do just that!") + timedUpdate(5) + } + 5 -> { + animate(getNPC(NPCs.DORIC_284)!!, 99) + timedUpdate(1) + } + 6 -> { + animate(player, 837) + timedUpdate(4) + } + 7 -> { + animate(player, 838) + timedUpdate(2) + } + 8 -> { + fadeToBlack() + timedUpdate(5) + } + 9 -> { + animate(player, 0) + timedUpdate(1) + } + 10 -> { + animate(player, 856) + fadeFromBlack() + timedUpdate(2) + } + 11 -> { + sendChat(player, "Okay, I'm sorry!") + animate(player, 856) + timedUpdate(5) + } + 12 -> { + sendChat(getNPC(NPCs.DORIC_284)!!, "That's what I thought. Watch your mouth the next time you speak to me.") + timedUpdate(3) + } + 13 -> { + end { + setAttribute(player, "/save:pre-dq:doric-calm", true) + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/falador/dialogue/DrunkenManDialogue.kt b/Server/src/main/content/region/asgarnia/falador/dialogue/DrunkenManDialogue.kt new file mode 100644 index 0000000..8d3372d --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/dialogue/DrunkenManDialogue.kt @@ -0,0 +1,66 @@ +package content.region.asgarnia.falador.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class DrunkenManDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + player(FacialExpression.FRIENDLY,"Hello.").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> { + npc(FacialExpression.DRUNK, "... whassup?").also { stage++ } + } + + 1 -> { + player(FacialExpression.ASKING, "Are you alright?").also { stage++ } + } + + 2 -> { + npc(FacialExpression.DRUNK, "... see... two of you... why there two of you?").also { stage++ } + } + + 3 -> { + player(FacialExpression.FRIENDLY, "There's only one of me, friend.").also { stage++ } + } + + 4 -> { + npc(FacialExpression.DRUNK, "... no, two of you... you can't count...", + "... maybe you drunk too much...").also { stage++ } + } + + 5 -> { + player(FacialExpression.FRIENDLY, "Whatever you say, friend.").also { stage++ } + } + + 6 -> { + npc(FacialExpression.DRUNK, "... giant hairy cabbages...").also { stage = 99 } + } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return DrunkenManDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.DRUNKEN_MAN_3222) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/falador/dialogue/FaladorGardenerDialogue.java b/Server/src/main/content/region/asgarnia/falador/dialogue/FaladorGardenerDialogue.java new file mode 100644 index 0000000..b2fb3cf --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/dialogue/FaladorGardenerDialogue.java @@ -0,0 +1,69 @@ +package content.region.asgarnia.falador.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the falador gardener dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class FaladorGardenerDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code FaladorGardenerDialogue} {@code Object}. + */ + public FaladorGardenerDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code FaladorGardenerDialogue} {@code Object}. + * @param player the player. + */ + public FaladorGardenerDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new FaladorGardenerDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Oi'm busy. If tha' wants owt, tha' can go find Wyson.", "He's ta boss 'round here. And,", "KEEP YE' TRAMPIN' FEET OFF MA'FLOWERS!"); + stage = 1; + break; + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Right..."); + stage = 2; + break; + case 2: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 1217, 3234 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/falador/dialogue/FaladorManHouseDialogue.java b/Server/src/main/content/region/asgarnia/falador/dialogue/FaladorManHouseDialogue.java new file mode 100644 index 0000000..799e250 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/dialogue/FaladorManHouseDialogue.java @@ -0,0 +1,97 @@ +package content.region.asgarnia.falador.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the falador man house dialogue. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class FaladorManHouseDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code FaladorManHouseDialogue} {@code Object}. + */ + public FaladorManHouseDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code FaladorManHouseDialogue} {@code Object}. + * @param player the player. + */ + public FaladorManHouseDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new FaladorManHouseDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "What are you doing in my house?"); + stage = 1; + break; + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I was just exploring."); + stage = 2; + break; + case 2: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "You're exploring my house?"); + stage = 3; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "You don't mind, do you?"); + stage = 4; + break; + case 4: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "But... why are you exploring in my house?"); + stage = 5; + break; + case 5: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Oh, I don't know. I just wandered in, saw you and thought", "it'd be fun to speak to you."); + stage = 6; + break; + case 6: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "... you are very strange..."); + stage = 7; + break; + case 7: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Perhaps I should go now."); + stage = 8; + break; + case 8: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Yes, please go away now."); + stage = 9; + break; + case 9: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 3223 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/falador/dialogue/FaladorShopKeeperDialogue.java b/Server/src/main/content/region/asgarnia/falador/dialogue/FaladorShopKeeperDialogue.java new file mode 100644 index 0000000..051c554 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/dialogue/FaladorShopKeeperDialogue.java @@ -0,0 +1,81 @@ +package content.region.asgarnia.falador.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the falador shop keeper dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class FaladorShopKeeperDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code FaladorShopKeepDialogue} {@code Object}. + */ + public FaladorShopKeeperDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code FaladorShopKeepDialogue} {@code Object}. + * @param player the player. + */ + public FaladorShopKeeperDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new FaladorShopKeeperDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Can I help you at all?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "Yes, please. What are you selling?", "How should I use your shop?", "No, thanks."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + end(); + npc.openShop(player); + break; + case 2: + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "I'm glad you ask! You can buy as many of the items", "stocked as you wish. You can also sell most items to the", "shop."); + stage = 20; + break; + case 3: + end(); + break; + + } + break; + case 20: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 526, 527 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/falador/dialogue/FaladorSquireDialogue.java b/Server/src/main/content/region/asgarnia/falador/dialogue/FaladorSquireDialogue.java new file mode 100644 index 0000000..8fe2515 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/dialogue/FaladorSquireDialogue.java @@ -0,0 +1,570 @@ +package content.region.asgarnia.falador.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.AchievementDiary; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.game.world.GameWorld; +import content.data.Quests; + +/** + * Represents the falador squire dialogue plugin. + * + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class FaladorSquireDialogue extends DialoguePlugin { + private boolean useDiaryDialogueTree = false; + private boolean replacementReward = false; + private int level = 2; + + /** + * Represents the blurite sword item. + */ + private static final Item BLURITE_SWORD = new Item(667); + + /** + * Represents the quest instance. + */ + private Quest quest; + + /** + * Constructs a new {@code FaladorSquireDialogue} {@code Object}. + */ + public FaladorSquireDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code FaladorSquireDialogue} {@code Object}. + * + * @param player the player. + */ + public FaladorSquireDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new FaladorSquireDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + quest = player.getQuestRepository().getQuest(Quests.THE_KNIGHTS_SWORD); + interpreter.sendOptions("What do you want to do?", "Chat", "Talk about the Falador Achievement Diary"); + stage = -1; + replacementReward = AchievementDiary.canReplaceReward(player, DiaryType.FALADOR, level); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + if (useDiaryDialogueTree || (stage == -1 && buttonId == 2)) { // Achievement Diary + useDiaryDialogueTree = true; + switch (stage) { + case -1: + if (replacementReward) { + player("I seem to have lost my Falador shield..."); + stage = 80; + } else { + npc("How are you getting on with the Achievement Diary?"); + stage = 90; + } + break; + case 80: + AchievementDiary.grantReplacement(player, DiaryType.FALADOR, level); + npc("Here's your replacement. Please be more careful."); + stage = 999; + break; + case 90: + options("I've come for my reward.", "I'm doing good.", "I have a question."); + stage = 91; + break; + case 91: + switch (buttonId) { + case 1: + player("I've come for my reward."); + stage = 200; + break; + case 2: + player("I'm doing good."); + stage = 220; + break; + case 3: + player("I have a question."); + stage = 105; + break; + } + break; + case 105: + if (!AchievementDiary.hasClaimedLevelRewards(player, DiaryType.FALADOR, level)) { + options("What is the Achievement Diary?", "What are the rewards?", "How do I claim the rewards?", "See you later."); + stage = 106; + } else { + options("Can you remind me what my Falador shield does, please?", "What is the Achievement Diary?", "What are the rewards?", "How do I claim the rewards?", "See you later."); + stage = 107; + } + break; + case 106: + switch (buttonId) { + case 1: + player("What is the Achievement Diary?"); + stage = 110; + break; + case 2: + player("What are the rewards?"); + stage = 120; + break; + case 3: + player("How do I claim the rewards?"); + stage = 130; + break; + case 4: + player("See you later."); + stage = 999; + break; + } + break; + + case 107: + switch (buttonId) { + case 1: + player("Can you remind me what my Falador shield does, please?"); + stage = 150; + break; + case 2: + player("What is the Achievement Diary?"); + stage = 110; + break; + case 3: + player("What are the rewards?"); + stage = 120; + break; + case 4: + player("How do I claim the rewards?"); + stage = 130; + break; + case 5: + player("See you later."); + stage = 999; + break; + } + break; + + case 110: + npc("Ah, well, it's a diary that helps you keep track of", "particular achievements you've made here on Gielinor."); + stage = 111; + break; + case 111: + npc("If you manage to complete a particular set of tasks,", "you will be rewarded for your explorative efforts."); + stage = 112; + break; + case 112: + npc("You can access your Achievement Diary by going to", "the Quest Journal, then clicking on the green star icon", "in the top-right hand corner."); + stage = 105; + break; + + case 120: + npc("Ah, well there are different rewards for each", "Achievement Diary. For completing each stage of the", "Falador diary, you are presented with a Falador shield."); + stage = 121; + break; + case 121: + npc("There are three shields available, one for each difficulty", "level."); + stage = 122; + break; + case 122: + npc("When you are presented with your rewards, you will", "be told of their uses."); + stage = 105; + break; + + case 130: + npc("You need to complete all of the tasks in a particular", "difficulty, then you can claim your reward."); + stage = 131; + break; + case 131: + npc("Some of Falador's tasks are simple, some will require", "certain skill levels, and some might require quests to be", "started or completed."); + stage = 132; + break; + case 132: + npc("To claim your Falador Achievement Diary rewards,", "speak to Redbeard the Pirate in Port Sarim, The Chemist", "in Rimmington, or myself."); + stage = 105; + break; + + case 150: + npc("This is the final stage of the Falador shield: a tower", "shield. It grants you all the benefits fo the buckler", "and kiteshield did, full Prayer restore, and access to", "some interesting new seeds that my friend Wyson has"); + stage = 151; + break; + case 151: + npc("found."); + stage = 152; + break; + case 152: + npc("As before, Prayer restore can only be used once per", "day, but this time it restores all of your Prayer points!"); + stage = 153; + break; + case 153: + npc("The new seeds I mentioned were discovered by Wyson,", "who can be found in Falador Park. He'll give you some", "new seeds in return for the skin of the giant mole", "beneath Falador Park.."); + stage = 154; + break; + case 154: + npc("He'll only offer them to you if you're wielding the", "Falador shield, though."); + stage = 155; + break; + case 155: + npc("As well as all these features, the shield is pretty handy", "in combat, and gives you a big Prayer boost."); + stage = 105; + break; + + case 200: + if (AchievementDiary.hasClaimedLevelRewards(player, DiaryType.FALADOR, level)) { + npc("But you've already gotten yours!"); + stage = 105; + } else if (AchievementDiary.hasCompletedLevel(player, DiaryType.FALADOR, level)) { + npc("So, you've finished. Well done! I believe congratulations", "are in order."); + stage = 201; + } else { + npc("But you haven't finished!"); + stage = 105; + } + break; + case 201: + player("I believe rewards are in order."); + stage = 202; + break; + case 202: + npc("Right you are."); + stage = 203; + break; + case 203: + npc("This is the final stage of the Falador shield: a tower", "shield. It grants you all the benefits fo the buckler", "and kiteshield did, full Prayer restore, and access to", "some interesting new seeds that my friend Wyson has"); + AchievementDiary.flagRewarded(player, DiaryType.FALADOR, level); + stage = 204; + break; + case 204: + npc("found."); + stage = 205; + break; + case 205: + npc("As before, Prayer restore can only be used once per", "day, but this time it restores all of your Prayer points!"); + stage = 206; + break; + case 206: + npc("The new seeds I mentioned were discovered by Wyson,", "who can be found in Falador Park. He'll give you some", "new seeds in return for the skin of the giant mole", "beneath Falador Park.."); + stage = 207; + break; + case 207: + npc("He'll only offer them to you if you're wielding the", "Falador shield, though."); + stage = 208; + break; + case 208: + npc("As well as all these features, the shield is pretty handy", "in combat, and gives you a big Prayer boost."); + stage = 209; + break; + case 209: + interpreter.sendDialogues(player, FacialExpression.AMAZED, "Wow, thanks!"); + stage = 210; + break; + case 210: + npc("If you should lose your shield, come back and see me", "for another one."); + stage = 105; + break; + case 220: + npc("Keep it up!"); + stage = 105; + break; + + case 999: + end(); + break; + } + } else { // chat + + switch (quest.getStage(player)) { + case 100: + switch (stage) { + case -1: + npc("Hello friend! Many thanks for all of your help! Vyvin", "never even realised it was a different sword, and I still", "have my job!"); + stage = 0; + break; + case 0: + end(); + break; + } + break; + case 60: + switch (stage) { + case -1: + npc("So how are you doing getting a sword?"); + stage = 0; + break; + case 0: + if (!player.getInventory().containsItem(BLURITE_SWORD)) { + player("I've found a dwarf who will make the sword, I've just", "got to find the materials for it now!"); + stage = 1; + } else { + player("I have retrieved your sword for you."); + stage = 2; + } + break; + case 1: + end(); + break; + case 2: + npc("Thank you, thank you, thank you! I was seriously", "worried I would have to own up to Sir Vyvin!"); + stage = 3; + break; + case 3: + interpreter.sendDialogue("You give the sword to the squire."); + stage = 4; + break; + case 4: + if (player.getInventory().remove(BLURITE_SWORD)) { + quest.finish(player); + end(); + } + break; + } + break; + case 50: + switch (stage) { + case -1: + npc("So how are you doing getting a sword?"); + stage = 0; + break; + case 0: + if (player.getInventory().contains(666, 1)) { + player("I have the picture, I'll just take it to the dwarf now!"); + stage = 3; + } else { + player("I didn't get the picture yet..."); + stage = 1; + } + break; + case 1: + npc("Please try and get it quickly... I am scared Sir Vyvin", "will find out!"); + stage = 2; + break; + case 2: + end(); + break; + case 3: + npc("Please hurry!"); + stage = 2; + break; + } + break; + case 40: + switch (stage) { + case -1: + npc("So how are you doing getting a sword?"); + stage = 0; + break; + case 0: + player("I have found an Imcando dwarf but he needs a picture", "of the sword before he can make it."); + stage = 1; + break; + case 1: + npc("A picture eh? Hmmm.... The only one I can think of is", "in a small portrait of Sir Vyvin's father... Sir Vyvin", "keeps it in a cupboard in his room I think."); + stage = 2; + break; + case 2: + player("Ok, I'll try to get that then."); + stage = 3; + break; + case 3: + npc("Please don't let him catch you! He MUSTN'T know", "what happened!"); + stage = 4; + break; + case 4: + quest.setStage(player, 50); + end(); + break; + } + break; + case 30: + switch (stage) { + case -1: + npc("So how are you doing getting a sword?"); + stage = 0; + break; + case 0: + player("I have found an Imcando Dwarf named Thurgo!", "I have given him Redberry pie, I hope he will", "help me now."); + stage = 1; + break; + case 1: + end(); + break; + } + break; + case 20: + case 10: + switch (stage) { + case -1: + npc("So how are you doing getting a sword?"); + stage = 0; + break; + case 0: + player("I'm still looking for Imcando dwarves to help me..."); + stage = 1; + break; + case 1: + npc("Please try and find them quickly... I am scared Sir", "Vyvin will find out!"); + stage = 2; + break; + case 2: + end(); + break; + case 166: + end(); + break; + } + break; + case 0: + switch (stage) { + case -1: + npc("Hello. I am the squire to Sir Vyvin."); + stage++; + break; + case 0: + options("And how is life as a squire?", "Wouldn't you prefer to be a squire for me?"); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + player("And how is life as a squire?"); + stage = 10; + break; + case 2: + player("Wouldn't you prefer to be a squire for me?"); + stage = 20; + break; + } + break; + case 10: + npc("Well, Sir Vyvin is a good guy to work for, however,", "I'm in a spot of trouble today. I've gone and lost Sir", "Vyvin's sword!"); + stage = 11; + break; + case 11: + options("Do you know where you lost it?", "I can make a new sword if you like...", "Is he angry?"); + stage = 12; + break; + case 12: + switch (buttonId) { + case 1: + player("Do you know where you lost it?"); + stage = 100; + break; + case 2: + player("I can make a new sword if you like..."); + stage = 120; + break; + case 3: + player("Is he angry?"); + stage = 130; + break; + } + break; + case 20: + npc("No, sorry, I'm loyal to Sir Vyvin."); + stage = 999; + break; + case 100: + npc("Well now, if I knew THAT it wouldn't be lost, now", "would it?"); + stage = 999; + break; + case 120: + npc("Thanks for the offer. I'd be surprised if you could", "though."); + stage = 121; + break; + case 121: + npc("The thing is, this sword is a family heirloom. It has been", "passed down through Vyvin's family for five", "generations! It was originally made by the Imcando", "dwarves, who were"); + stage = 122; + break; + case 122: + npc("a particularly skilled tribe of dwarven smiths. I doubt", "anyone could make it in the style they do."); + stage = 123; + break; + case 123: + options("So would these dwarves make another one?", "Well I hope you find it soon."); + stage = 134; + break; + case 134: + switch (buttonId) { + case 1: + player("So would these dwarves make another one?"); + stage = 160; + break; + case 2: + player("Well I hope you find it soon."); + stage = 170; + break; + } + break; + case 160: + npc("I'm not a hundred percent sure the Imcando tribe", "exists anymore. I should think Reldo, the palace", "librarian in Varrock, will know; he has done a lot of", "research on the races of " + GameWorld.getSettings().getName() + "."); + stage = 161; + break; + case 161: + npc("I don't suppose you could try and track down the", "Imcando dwarves for me? I've got so much work to", "do..."); + stage = 162; + break; + case 162: + options("Ok, I'll give it a go.", "No, I've got lots of mining work to do."); + stage = 163; + break; + case 163: + switch (buttonId) { + case 1: + player("Ok, I'll give it a go."); + stage = 165; + break; + case 2: + player("No, I've got lots of mining work to do."); + stage = 164; + break; + } + break; + case 164: + npc("Oh man... I'm in such trouble..."); + stage = 999; + break; + case 165: + npc("Thank you very much! As I say, the best place to start", "should be with Reldo..."); + stage = 999; + quest.setStage(player, 10); + player.getQuestRepository().syncronizeTab(player); + break; + case 170: + npc("Yes, me too. I'm not looking forward to telling Vyvin", "I've lost it. He's going to want it for the parade next", "week as well."); + stage = 999; + break; + case 130: + npc("He doesn't know yet. I was hoping I could think of", "something to do before he does find out, But I find", "myself at a loss."); + stage = 999; + break; + case 999: + end(); + break; + } + break; + } + } + return true; + } + + @Override + public int[] getIds() { + return new int[]{606}; + } +} diff --git a/Server/src/main/content/region/asgarnia/falador/dialogue/FaladorWomenParkDialogue.java b/Server/src/main/content/region/asgarnia/falador/dialogue/FaladorWomenParkDialogue.java new file mode 100644 index 0000000..d650925 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/dialogue/FaladorWomenParkDialogue.java @@ -0,0 +1,85 @@ +package content.region.asgarnia.falador.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the falador women park dialogue. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class FaladorWomenParkDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code FaladorWomenParkDialogue} {@code Object}. + */ + public FaladorWomenParkDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code FaladorWomenParkDialogue} {@code Object}. + * @param player the player. + */ + public FaladorWomenParkDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new FaladorWomenParkDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Grettings! Have you come to gaze in rapture at the", "natural beauty of Falador's parkland?"); + stage = 1; + break; + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Um, yes, very nice. Lots of.... trees and stuff."); + stage = 2; + break; + case 2: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Trees! I do so love trees! And flowers! And squirrels."); + stage = 3; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Sorry, I have a strange urge to be somewhere else."); + stage = 4; + break; + case 4: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Come back to me soon and we can talk again about trees!"); + stage = 5; + break; + case 5: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "..."); + stage = 6; + break; + case 6: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 3226 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/falador/dialogue/FlynnDialogue.java b/Server/src/main/content/region/asgarnia/falador/dialogue/FlynnDialogue.java new file mode 100644 index 0000000..eed86be --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/dialogue/FlynnDialogue.java @@ -0,0 +1,78 @@ +package content.region.asgarnia.falador.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the dialogue plugin used for the flynn npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class FlynnDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code FlynnDialogue} {@code Object}. + */ + public FlynnDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code FlynnDialogue} {@code Object}. + * @param player the player. + */ + public FlynnDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new FlynnDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Hello. Do you want to buy or sell any maces?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "No, thanks.", "Well, I'll have a look, at least."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "No, thanks."); + stage = 10; + break; + case 2: + end(); + npc.openShop(player); + break; + + } + break; + case 10: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 580 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/falador/dialogue/HairdresserDialogue.java b/Server/src/main/content/region/asgarnia/falador/dialogue/HairdresserDialogue.java new file mode 100644 index 0000000..362b124 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/dialogue/HairdresserDialogue.java @@ -0,0 +1,175 @@ +package content.region.asgarnia.falador.dialogue; + +import core.game.component.Component; +import core.game.container.impl.EquipmentContainer; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; + +/** + * Represents the dialogue plugin used for the hairdresser. + */ +@Initializable +public final class HairdresserDialogue extends DialoguePlugin { + + + /** + * Constructs a new {@code HairdresserDialogue} {@code Object}. + */ + public HairdresserDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code HairdresserDialogue} {@code Object}. + * @param player the player. + */ + public HairdresserDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new HairdresserDialogue(player); + } + + @Override + public boolean open(Object... args) { + final String gender = player.isMale() ? "sir" : "madam"; + npc = (NPC) args[0]; + + + //If the player right clicks the hairdresser and presses Hair-cut + if (args.length == 2) { + if (player.getEquipment().get(EquipmentContainer.SLOT_HAT) == null && + player.getEquipment().get(EquipmentContainer.SLOT_WEAPON) == null && player.getEquipment().get(EquipmentContainer.SLOT_SHIELD) == null) { + if (player.isMale()) { + player.getInterfaceManager().open(new Component(596)); + } else { + player.getInterfaceManager().open(new Component(592)); + } + } + else if(player.getEquipment().get(EquipmentContainer.SLOT_HAT) != null || player.getEquipment().get(EquipmentContainer.SLOT_WEAPON) != null || player.getEquipment().get(EquipmentContainer.SLOT_SHIELD) != null ) { + /** NOT ACCURATE DIALOGUE **/ + interpreter.sendDialogues(npc, FacialExpression.SCARED, (player.isMale() ? "Sir, " : "Madam, ") + "I can't cut your hair with those things pointing","at me. Please take them off and speak to me again."); + stage = 13; + }else{ //Not enough money + interpreter.sendDialogues(player, FacialExpression.SAD, "I don't have 2000 gold coins on me..."); + stage = 12; + } + return true; + } + + //If the player talks with the hairdresser + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "Good afternoon " + gender + ". In need of a haircut are we?", player.isMale() ? "Perhaps a shave too?" : ""); + stage = 1; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + + case 1: + if (player.isMale()) { + interpreter.sendOptions("Select an Option", "I'd like a haircut please.", "I'd like a shave please.", "No thank you."); + stage = 2; + } else { + interpreter.sendOptions("Select an Option", "I'd like a haircut please.", "No thank you."); + stage = 5; + } + break; + + //Male Option responses + case 2: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HAPPY, "I'd like a haircut please."); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HAPPY, "I'd like a shave please."); + stage = 10; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "No thank you."); + stage = 20; + break; + } + break; + + //Female Option responses + case 5: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HAPPY, "I'd like a haircut please."); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "No thank you."); + stage = 20; + break; + } + break; + + //HairDresser Dialogues + case 10: + String gender = player.isMale() ? "sir" : "madam"; + String gender2 = player.isMale() ? "men's" : "women's"; + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Certainly " + gender + ". I cut " + gender2 + " hair at the bargain rate of", "only 2000 gold coins. I'll even throw in a free recolour!"); + stage++; + break; + case 11: + if (player.getEquipment().get(EquipmentContainer.SLOT_HAT) == null && + player.getEquipment().get(EquipmentContainer.SLOT_WEAPON) == null && player.getEquipment().get(EquipmentContainer.SLOT_SHIELD) == null) { + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "Please select the hairstyle and colour you would like", "from this brochure."); + stage = 14; + } + //Has helmet or sword/shield + else if(player.getEquipment().get(EquipmentContainer.SLOT_HAT) != null || player.getEquipment().get(EquipmentContainer.SLOT_WEAPON) != null || player.getEquipment().get(EquipmentContainer.SLOT_SHIELD) != null ) { + /** NOT ACCURATE DIALOGUE **/ + interpreter.sendDialogues(npc, FacialExpression.SCARED, (player.isMale() ? "Sir, " : "Madam, ") + "I can't cut your hair with those things pointing","at me. Please take them off and speak to me again."); + stage = 13; + break; + } else { + interpreter.sendDialogues(player, FacialExpression.SAD, "I don't have 2000 gold coins on me..."); + stage = 12; + } + break; + case 12: + interpreter.sendDialogues(npc, FacialExpression.ANNOYED, "Well, come back when you do. I'm not running a", "charity here!"); + stage++; + break; + case 13: + end(); + break; + + //Opens the Hairstyle menu and ends the conversation + case 14: + end(); + if (player.isMale()) { + end(); + player.getInterfaceManager().open(new Component(596)); + } else { + end(); + player.getInterfaceManager().open(new Component(592)); + } + break; + + case 20: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "Very well. Come back if you change your mind."); + stage = 13; + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 598 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/falador/dialogue/HerquinDialogue.java b/Server/src/main/content/region/asgarnia/falador/dialogue/HerquinDialogue.java new file mode 100644 index 0000000..2ea67f3 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/dialogue/HerquinDialogue.java @@ -0,0 +1,81 @@ +package content.region.asgarnia.falador.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the herquin dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class HerquinDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code HerquinDialogue} {@code Object}. + */ + public HerquinDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code HerquinDialogue} {@code Object}. + * @param player the player. + */ + public HerquinDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new HerquinDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendOptions("Select an Option", "Do you wish to trade?", "Sorry, I don't want to talk to you, actually."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(player, FacialExpression.FRIENDLY, "Do you wish to trade?"); + stage = 10; + break; + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Sorry, I don't want to talk to you, actually."); + stage = 2; + break; + case 2: + interpreter.sendDialogues(npc, FacialExpression.ROLLING_EYES, "Huh, charming."); + stage = 3; + break; + case 3: + end(); + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "Why, yes, this is a jewel shop after all."); + stage = 11; + break; + case 11: + end(); + npc.openShop(player); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 584 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/falador/dialogue/LucyPartyRoomDialoguePlugin.java b/Server/src/main/content/region/asgarnia/falador/dialogue/LucyPartyRoomDialoguePlugin.java new file mode 100644 index 0000000..663f0de --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/dialogue/LucyPartyRoomDialoguePlugin.java @@ -0,0 +1,134 @@ +package content.region.asgarnia.falador.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.game.node.item.Item; + +/** + * Represents the dialogue plugin used for the lucy npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class LucyPartyRoomDialoguePlugin extends DialoguePlugin { + + /** + * Represents the npc ids. + */ + private static final int[] NPC_IDS = { 662 }; + + /** + * Represents the coins item. + */ + private static final Item COINS = new Item(995, 2); + + /** + * Represents the beer item. + */ + private static final Item BEER = new Item(1917, 1); + + /** + * Constructs a new {@code LucyPartyRoomDialoguePlugin} {@code Object}. + */ + public LucyPartyRoomDialoguePlugin() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code LucyPartyRoomDialoguePlugin} {@code Object}. + * @param player the player. + */ + public LucyPartyRoomDialoguePlugin(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new LucyPartyRoomDialoguePlugin(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hi! I'm Lucy. Welcome to the Party Room!"); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hi."); + stage = 1; + break; + case 1: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Would you like to buy a beer?"); + stage = 2; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "How much do they cost?"); + stage = 3; + break; + case 3: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Just 2 gold pieces."); + stage = 4; + break; + case 4: + interpreter.sendOptions("Select an Option", "Yes please!", " No thanks, I can't afford that."); + stage = 5; + break; + case 5: + switch (interfaceId) { + case 228: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Yes please!"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No thanks, I can't afford that."); + stage = 69; + break; + } + break; + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Coming right up sir!"); + stage = 11; + break; + case 11: + if (!player.getInventory().containsItem(COINS)) { + end(); + return true; + } + if (player.getInventory().remove(COINS)) { + interpreter.sendItemMessage(1917, "Lucy has given you a beer."); + player.getInventory().add(BEER); + stage = 100; + } else { + end(); + player.getPacketDispatch().sendMessage("You don't have enough coins."); + } + break; + case 69: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I see. Well, come and see me if you change your mind. YOu", "know where I am!"); + stage = 100; + break; + case 100: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return NPC_IDS; + } +} diff --git a/Server/src/main/content/region/asgarnia/falador/dialogue/MakeOverMageDialogue.java b/Server/src/main/content/region/asgarnia/falador/dialogue/MakeOverMageDialogue.java new file mode 100644 index 0000000..2d3a191 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/dialogue/MakeOverMageDialogue.java @@ -0,0 +1,229 @@ +package content.region.asgarnia.falador.dialogue; + +import core.game.component.Component; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.game.node.item.Item; + +/** + * Handles the MakeOverMageDialogue dialogue. + * @author 'Vexia + */ +@Initializable +public class MakeOverMageDialogue extends DialoguePlugin { + + public MakeOverMageDialogue() { + + } + + public MakeOverMageDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new MakeOverMageDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + if (args.length == 2) { + + interpreter.sendDialogues(npc, FacialExpression.HALF_ASKING, "Hmm... you didn't feel any unexpected growths", "anywhere around your head just then did you?"); + stage = 600; + return true; + } + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Hello there! I am known as the make-over mage! I", "have spent many years researching magics that can", "change your physical appearance!"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "I can alter your physical form for a small fee of", "only 3000 gold coins! Would you like me to perform my", "magics upon you?"); + stage = 1; + break; + case 1: + if (!player.getInventory().contains(7803, 1) && !player.getBank().contains(7803, 1) && !player.getEquipment().contains(7803, 1)) { + interpreter.sendOptions("Select an Option", "Tell me more about this 'make-over'.", "Sure. Do it.", "No thanks.", "Cool amulet! Can I have one?"); + } else { + interpreter.sendOptions("Select an Option", "Tell me more about this 'make-over'.", "Sure. Do it.", "No thanks."); + } + stage = 2; + break; + case 2: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HAPPY, "Tell me more about this 'make-over'."); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HAPPY, "Sure. Do it."); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HAPPY, "No thanks. I'm happy as Saradomin made me."); + stage = 19; + break; + case 4: + interpreter.sendDialogues(player, FacialExpression.HAPPY, "Cool amulet! Can I have one?"); + stage = 40; + break; + } + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "You of course agree that if by some accident you", "are turned into a frog you have no rights for", "compensation or refund."); + stage = 25; + break; + case 21: + interpreter.sendDialogues(npc, FacialExpression.ANGRY, "Well, go get it then. No freebies here!"); + stage = 22; + break; + case 22: + end(); + break; + case 25: + if(!player.getEquipment().isEmpty()){ + interpreter.sendDialogue("You need to take off all your equipment before the mage", "can change your appearance."); + stage = 900; + } else { + end(); + player.getInterfaceManager().open(new Component(205)); + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Why, of course! Basically, and I will try and explain", "this so that you will understand it correctly,"); + stage = 11; + break; + case 11: + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "I use my secret magical technique to melt your body", "down into a puddle of its elements."); + stage = 12; + break; + case 12: + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "When I have broken down all trace of your body, I", "then rebuild it into the form I am thinking of."); + stage = 13; + break; + case 13: + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "Or, you know, somewhere vaguely close enough", "anyway."); + stage = 14; + break; + case 14: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Uh... that doesn't sound particularly safe to me..."); + stage = 15; + break; + case 15: + interpreter.sendDialogues(npc, FacialExpression.LAUGH, "It's as safe as houses! Why, I have only had thirty-six", "major accidents this month!"); + stage = 16; + break; + case 16: + interpreter.sendDialogues(npc, FacialExpression.ASKING, "So what do you say? Feel like a change?"); + stage = 17; + break; + case 17: + interpreter.sendOptions("Select an Option", "Sure. Do it.", "No thanks."); + stage = 18; + break; + case 18: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HAPPY, "Sure. Do it."); + stage = 20; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HAPPY, "No thanks. I'm happy as Saradomin made me."); + stage = 19; + break; + } + break; + case 19: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ehhh... suit yourself."); + stage = 900; + break; + case 900: + end(); + break; + case 40: + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "No problem, but please remember that the amulet I will", "sell you is only a copy of my own. It contains no", "magical powers; and as such will only cost you 100", "coins."); + stage = 41; + break; + case 41: + interpreter.sendOptions("Select an Option", "Sure, here you go.", "No way! that's too expensive."); + stage = 42; + break; + case 42: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HAPPY, "Sure, here you go."); + stage = 100; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.AMAZED, "No way! That's too expensive."); + stage = 400; + break; + + } + break; + case 400: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "That's fair enough, my jewellery is not to everyone's", "taste."); + stage = 401; + break; + case 401: + end(); + break; + case 600: + interpreter.sendDialogues(player, FacialExpression.EXTREMELY_SHOCKED, "Uh... No...?"); + stage = 601; + break; + case 601: + interpreter.sendDialogues(npc, FacialExpression.WORRIED, "Good, good, I was worried for a second there!"); + stage = 602; + break; + case 602: + interpreter.sendDialogues(player, FacialExpression.SUSPICIOUS, "Uh... Thanks, I guess."); + stage = 603; + break; + case 603: + end(); + break; + case 100: + if (player.getInventory().freeSlots() == 0) { + end(); + player.getPacketDispatch().sendMessage("You don't have enough inventory space."); + } + if (!player.getInventory().contains(995, 100)) { + end(); + player.getPacketDispatch().sendMessage("You need 100 coins."); + } else { + // you recieve an amulet in exchange for 100 coins. + // 7803 + Item remove = new Item(995, 100); + if (!player.getInventory().containsItem(remove)) { + end(); + return true; + } + if (player.getInventory().remove(remove)) { + interpreter.sendItemMessage(7803, "You receive an amulet in exchange for 100 coins."); + player.getInventory().add(new Item(7803, 1)); + stage = 101; + } + } + break; + case 101: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 2676, 599 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/falador/dialogue/MiningGuildDwarf.java b/Server/src/main/content/region/asgarnia/falador/dialogue/MiningGuildDwarf.java new file mode 100644 index 0000000..83db1cc --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/dialogue/MiningGuildDwarf.java @@ -0,0 +1,135 @@ +package content.region.asgarnia.falador.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the mining guild dwarf. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class MiningGuildDwarf extends DialoguePlugin { + + /** + * Constructs a new {@code MiningGuildDwarf} {@code Object}. + */ + public MiningGuildDwarf() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code MiningGuildDwarf} {@code Object}. + * @param player the player. + */ + public MiningGuildDwarf(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new MiningGuildDwarf(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + if (args.length == 2) { + if (player.getSkills().getStaticLevel(Skills.MINING) < 60) { + interpreter.sendDialogues(npc, null, "Sorry, but you need level 60 Mining to go in there."); + stage = 69; + return true; + } + } + interpreter.sendDialogues(npc, FacialExpression.ASKING, "Welcome to the Mining Guild.", "Can I help you with anything?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 69: + end(); + break; + case 0: + interpreter.sendOptions("What would you like to say?", "What have you got in the Guild?", "What do you dwarves do with the ore you mine?", "No thanks, I'm fine."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.ASKING, "What have you got in the Guild?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.ASKING, "What do you dwarves do with the ore you mine?"); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "No thanks, I'm fine."); + stage = 30; + break; + + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Ooh, it's WONDEFRFUL! There are lots of coal rocks,", "and even a few mithril rocks in the guild,", "all exclusively for people with at least level 60 mining", "There's no better mining site anywhere near here."); + stage = 11; + break; + case 11: + interpreter.sendDialogues(player, FacialExpression.HALF_ASKING, "So you won't let me go in there?"); + stage = 12; + break; + case 12: + if (player.getSkills().getStaticLevel(Skills.MINING) < 60) { + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "Sorry, but the rules are rules. Do some more training", "first."); + stage = 13; + } else { + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "Yes, you can enter if you wish."); + stage = 14; + } + break; + case 13: + end(); + break; + case 14: + end(); + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HALF_THINKING, "What do you think? We smelt it into bars, smith the", "metal to make armour and weapons, then we exchange", "them for goods and services."); + stage = 21; + break; + case 21: + interpreter.sendDialogues(player, FacialExpression.HALF_THINKING, "I don't see many dwarves here."); + stage = 22; + break; + case 22: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "No, this is only a mining outpost. We dwarves don't", "much like to settle in human cities. Most of the ore is", "carted off to Keldagrim, the great dwarven city.", "They've got a special blast furnace up there - it makes"); + stage = 23; + break; + case 23: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "smelting the ore so much easier. There are plenty of", "dwarven traders working in Keldagrim."); + stage = 24; + break; + case 24: + end(); + break; + case 30: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 382 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/falador/dialogue/PartyPeteDialoguePlugin.java b/Server/src/main/content/region/asgarnia/falador/dialogue/PartyPeteDialoguePlugin.java new file mode 100644 index 0000000..02790ab --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/dialogue/PartyPeteDialoguePlugin.java @@ -0,0 +1,179 @@ +package content.region.asgarnia.falador.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.world.GameWorld; +import core.plugin.Initializable; +import core.game.world.update.flag.context.Animation; + +/** + * Handles the party pete dialogue. + * @author 'Vexia + */ +@Initializable +public class PartyPeteDialoguePlugin extends DialoguePlugin { + + /** + * The npc ids pertained to this dialogue. + */ + private int[] NPC_IDS = { 659 }; + + /** + * Constructs a new {@code partyPeteDialoguePlugin}. + */ + public PartyPeteDialoguePlugin() { + + } + + /** + * Constructs a new {@code partyPeteDialoguePlugin} {@code Object}. + * @param player the player. + */ + public PartyPeteDialoguePlugin(Player player) { + super(player); + } + + /** + * interpreter.sendDialogues(player, FacialExpression.NORMAL, ""); + * interpreter.sendDialogues(npc, FacialExpression.NORMAL, ""); + */ + + @Override + public int[] getIds() { + return NPC_IDS; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hi! I'm, Party Pete. Welcome to the Party Room!"); + stage = 1; + break; + case 1: + interpreter.sendOptions("Select an Option", "So, what's this room for?", "What's the big lever over there for?", "What's the gold chest for?", "I wanna party!", "Nothing."); + stage = 2; + break; + case 2: + switch (interfaceId) { + case 234: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "So, what's this room for?"); + stage = 50; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What's the big lever over there for?"); + stage = 55; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What's the gold chest for?"); + stage = 61; + break; + case 4: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I wanna party!"); + stage = 65; + break; + case 5: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Nothing."); + stage = 100; + break; + } + break; + } + break; + case 50: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "This room is for partying the night away!"); + stage = 51; + break; + case 51: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "How do you have a party in " + GameWorld.getSettings().getName() + "?"); + stage = 52; + break; + case 52: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Get a few mates round, get the beers in and have fun!"); + stage = 53; + break; + case 53: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Some players organise parties so kee an eye open!"); + stage = 54; + break; + case 54: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Woop! Thanks Pete!"); + stage = 100; + break; + case 55: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Simple. With the lever you can do some fun stuff."); + stage = 56; + break; + case 56: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What kind of stuff?"); + stage = 57; + break; + case 57: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "A balloon drop costs 1000 gold. For this, you get 200", "balloons dropped across the whole of the party room. You", "canthen have fun popping the balloons!"); + stage = 58; + break; + case 58: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Any items in the Party Drop Chest will be put into balloons", "as soon as you pull the lever."); + stage = 59; + break; + case 59: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "When the balloons are released, you can burst them to", "get at the items!"); + stage = 60; + break; + case 60: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "For 500 gold, you can summon the Party Room Knights,", "who will dance for your delight. Their singing isn't a", "delight, though."); + stage = 100; + break; + case 61: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Any items in the chest will be dropped inside the ballons", "when you pull the lever."); + stage = 62; + break; + case 62: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Cool! Sounds like a fun way to do a drop party."); + stage = 63; + break; + case 63: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Exactly!"); + stage = 64; + break; + case 64: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "A word of warning, though. Any items that you put into", "the chest can't be taken out again, and it costs 1000 gold", "pieces for each drop party."); + stage = 100; + break; + case 65: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I've won the Dance Trophy at the Kandarin Ball three", "years in a trot!"); + stage = 66; + break; + case 66: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Show me your moves Pete!"); + stage = 67; + break; + case 67: + npc.animate(new Animation(784)); + end(); + break; + case 100: + end(); + break; + } + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new PartyPeteDialoguePlugin(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hi!"); + return true; + } + +} diff --git a/Server/src/main/content/region/asgarnia/falador/dialogue/RisingSunInnBartenderDialogue.kt b/Server/src/main/content/region/asgarnia/falador/dialogue/RisingSunInnBartenderDialogue.kt new file mode 100644 index 0000000..199a545 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/dialogue/RisingSunInnBartenderDialogue.kt @@ -0,0 +1,156 @@ +package content.region.asgarnia.falador.dialogue + +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import core.game.dialogue.Topic +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE + +/** + * Handles dialogue for Kaylee and Emily + * of the Rising Sun Inn + * + * @author vddCore + */ +@Initializable +class RisingSunInnBartenderDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin + = RisingSunInnBartenderDialogue(player) + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + + npcl( + FacialExpression.HAPPY, + "Hi! What can I get you?" + ) + + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + START_DIALOGUE -> if (hasAnyBeerGlasses()) { + showTopics( + Topic(FacialExpression.ASKING, "What ales are you serving?", 10), + Topic(FacialExpression.HAPPY, "I've got some beer glasses...", 20) + ) + } else { + playerl(FacialExpression.ASKING, "What ales are you serving?") + .also { stage = 10 } + } + + 10 -> npcl( + FacialExpression.FRIENDLY, + "Well, we've got Asgarnian Ale, Wizard's Mind Bomb and Dwarven Stout. " + + "Each for only 3 coins." + ).also { stage++ } + + 11 -> showTopics( + Topic(FacialExpression.HAPPY, "One Asgarnian Ale, please.", 12), + Topic(FacialExpression.HAPPY, "I'll try the Mind Bomb.", 13), + Topic(FacialExpression.ASKING, "Can I have a Dwarven Stout?", 14), + Topic(FacialExpression.NEUTRAL, "I don't feel like any of those.", END_DIALOGUE) + ) + + 12 -> if (ensureHasMoney()) { + purchaseBrew(Items.ASGARNIAN_ALE_1905) + } + + 13 -> if (ensureHasMoney()) { + purchaseBrew(Items.WIZARDS_MIND_BOMB_1907) + } + + 14 -> if (ensureHasMoney()) { + purchaseBrew(Items.DWARVEN_STOUT_1913) + } + + 20 -> { + npcl( + FacialExpression.HALF_GUILTY, + "Oh, we will buy those from you if you're interested. We offer 2 coins for each glass." + ).also { stage ++ } + } + + 21 -> showTopics( + Topic(FacialExpression.HAPPY, "Yes, please!", 22), + Topic(FacialExpression.NEUTRAL, "No thanks, I like my empty beer glasses.", END_DIALOGUE) + ) + + 22 -> { + trySellAllBeerGlasses() + + npcl( + FacialExpression.FRIENDLY, + "There you go!" + ).also { stage = END_DIALOGUE } + } + + 30 -> { + playerl(FacialExpression.FRIENDLY, "Thanks, ${npc.name}.") + .also { stage = END_DIALOGUE } + } + } + + return true + } + + override fun getIds(): IntArray = intArrayOf( + NPCs.EMILY_736, + NPCs.KAYLEE_3217 + ) + + private fun ensureHasMoney(): Boolean { + if (!inInventory(player, Items.COINS_995, 3)) { + npcl(FacialExpression.ANGRY, "No freeloaders!") + .also { + sendMessage(player, "You don't have enough money to buy that.") + stage = END_DIALOGUE + } + return false + } + + return true + } + + private fun purchaseBrew(brewId: Int) { + if (removeItem(player, Item(Items.COINS_995, 3))) { + addItemOrDrop(player, brewId) + + sendItemDialogue( + player, + Item(brewId), + "You hand 3 coins over to ${npc.name}. She gives you ${when (brewId) { + Items.WIZARDS_MIND_BOMB_1907 -> "a Wizard's Mind Bomb" + Items.DWARVEN_STOUT_1913 -> "a Dwarven Stout" + Items.ASGARNIAN_ALE_1905 -> "an Asgarnian Ale" + else -> "a broken fucking dialogue" + }}." + ).also { stage = 30 } + } + } + + private fun hasAnyBeerGlasses() + = inInventory(player, Items.BEER_GLASS_1919) + || inInventory(player, Items.BEER_GLASS_1920) + + private fun trySellAllBeerGlasses() { + val regularGlassAmount = amountInInventory(player, Items.BEER_GLASS_1919) + val notedGlassAmount = amountInInventory(player, Items.BEER_GLASS_1920) + + if (removeItem(player, Item(Items.BEER_GLASS_1919, regularGlassAmount))) { + addItem(player, Items.COINS_995, regularGlassAmount * 2) + } + + if (removeItem(player, Item(Items.BEER_GLASS_1920, notedGlassAmount))) { + addItem(player, Items.COINS_995, notedGlassAmount * 2) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/falador/dialogue/SarahFarmingPlugin.java b/Server/src/main/content/region/asgarnia/falador/dialogue/SarahFarmingPlugin.java new file mode 100644 index 0000000..e3c33b1 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/dialogue/SarahFarmingPlugin.java @@ -0,0 +1,81 @@ +package content.region.asgarnia.falador.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Handles the SarahFarmingPlugin dialogue. + * @author 'Vexia + */ +@Initializable +public class SarahFarmingPlugin extends DialoguePlugin { + + public SarahFarmingPlugin() { + + } + + public SarahFarmingPlugin(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new SarahFarmingPlugin(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hello."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hi!"); + stage = 1; + break; + case 1: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Would you like to see what I have in stock?"); + stage = 2; + break; + case 2: + interpreter.sendOptions("Select an Option", "Yes please.", "No, thank you."); + stage = 3; + break; + case 3: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Yes please."); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No, thank you."); + stage = 20; + break; + + } + break; + case 10: + end(); + npc.openShop(player); + break; + case 20: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 2304 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/falador/dialogue/SirReniteeDialogue.java b/Server/src/main/content/region/asgarnia/falador/dialogue/SirReniteeDialogue.java new file mode 100644 index 0000000..f8f9695 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/dialogue/SirReniteeDialogue.java @@ -0,0 +1,469 @@ +package content.region.asgarnia.falador.dialogue; + +import core.ServerConstants; +import core.Util; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.plugin.Initializable; +import org.rs09.consts.Items; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.item.Item; +import core.tools.RandomFunction; +import core.game.node.entity.skill.Skills; +import content.global.skill.construction.CrestType; + +/** + * Represents the dialogue to handle Sir Renitee + * + * @author afaroutdude + */ +@Initializable +public class SirReniteeDialogue extends DialoguePlugin { + /** + * Constructs a new {@code SirReniteeDialogue} {@code Object}. + */ + public SirReniteeDialogue() { + } + + public SirReniteeDialogue(Player player) { + super(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hmm? What's that, young " + (player.getAppearance().isMale() ? "man" : "woman") + "? What can I do for", "you?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "I don't know, what can you do for me?", "Nothing, thanks"); + stage = 10; + break; + case 10: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I don't know, what can you do for me?"); + stage = 100; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Nothing, thanks."); + stage = 30; + break; + } + break; + case 30: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Mmm, well, see you some other time maybe."); + stage = 40; + break; + case 40: + end(); + break; + case 100: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hmm, well, mmm, do you have a family crest? I keep", "track of every " + ServerConstants.SERVER_NAME + " family, you know, so I might", "be able to find yours."); + stage = 110; + break; + case 110: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I'm also something of an, mmm, a painter. If you've", "met any important persons or visited any nice places I", "could paint them for you."); + stage = 120; + break; + case 120: + interpreter.sendOptions("Select an Option", "Can you see if I have a family crest?", "Can I buy a painting?"); + stage = 130; + break; + case 130: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Can you see if I have a family crest?"); + stage = 200; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Can I buy a painting?"); + stage = 500; + break; + } + break; + case 200: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "What is your name?"); + stage = 210; + break; + case 210: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, player.getUsername() + "."); + stage = 220; + break; + case 220: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Mmm, " + player.getUsername() + ", let me see..."); + stage = 230; + break; + case 230: + if (player.getSkills().hasLevel(Skills.CONSTRUCTION, 16)) { + if (player.getAttribute("sir-renitee-assigned-crest", false)) { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "According to my records, your crest is ", player.getHouseManager().getCrest().getName() + "."); + } else { + final int c = RandomFunction.random(4); + final CrestType[] crests = {CrestType.VARROCK, CrestType.ASGARNIA, CrestType.KANDARIN, CrestType.MISTHALIN}; + final CrestType crest = crests[c]; + player.getHouseManager().setCrest(crest); + player.setAttribute("/save:sir-renitee-assigned-crest", true); + String message = "that can be your"; + if (crest == CrestType.VARROCK) { + message = "you can use that city's"; + } + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Well, I don't think you have any noble blood,", + "but I see that your ancestors came from " + Util.enumToString(player.getHouseManager().getCrest().name()) + ",", " so " + message + " crest."); + } + if (!player.getAchievementDiaryManager().getDiary(DiaryType.FALADOR).isComplete(0,4)) { + player.getAchievementDiaryManager().getDiary(DiaryType.FALADOR).updateTask(player,0,4,true); + } + stage = 240; + } else { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, + "First thing's first, young " + (player.getAppearance().isMale() ? "man" : "woman") + "! There is not much point", + "in having a family crest if you cannot display it."); + stage = 235; + } + break; + case 235: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "You should train construction until you can build a wall", "decoration in your dining room."); + stage = 40; + break; + case 240: + interpreter.sendOptions("Select an Option", "I don't like that crest. Can I have a different one?", "Thanks!"); + stage = 250; + break; + case 250: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I don't like that crest. Can I have a different one?"); + stage = 300; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Thanks!"); + stage = 260; + break; + } + break; + case 260: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "You're welcome, my " + (player.getAppearance().isMale() ? "boy." : "girl.")); + stage = 40; + break; + case 300: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Mmm, very well. Changing your crest will cost", "5,000 coins."); + if (player.getInventory().getAmount(Items.COINS_995) < 5000) { + stage = 302; + } else { + stage = 305; + } + break; + case 302: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'll have to go and get some money then."); + stage = 40; + break; + case 305: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "There are sixteen different symbols;", "which one would you like?"); + stage = 310; + break; + case 310: + interpreter.sendOptions("Select an Option", "Shield of Arrav", "Asgarnia", "Dorgeshuun Symbol", "Dragon", "More..."); + stage = 320; + break; + case 320: + switch (buttonId) { + case 1: { + CrestType c = CrestType.ARRAV; + if (c.eligible(player) && player.getInventory().getAmount(Items.COINS_995) > c.getCost() + && player.getInventory().remove(new Item(Items.COINS_995, c.getCost()))) { + player.getHouseManager().setCrest(c); + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ah yes, the shield that you helped to retrieve. You have", "certainly earned the right to wear its symbol."); + stage = 40; + } else { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "[MISSING DIALOGUE - NOT ELIGIBLE]"); + stage = 310; + } + break; + } + case 2: { + CrestType c = CrestType.ASGARNIA; + if (c.eligible(player) && player.getInventory().getAmount(Items.COINS_995) > c.getCost() + && player.getInventory().remove(new Item(Items.COINS_995, c.getCost()))) { + player.getHouseManager().setCrest(c); + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ah, splendid, splendid. There is no better symbol", "than that of our fair land!"); + stage = 40; + } else { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "[MISSING DIALOGUE - NOT ELIGIBLE]"); + stage = 310; + } + break; + } + case 3: { + CrestType c = CrestType.DORGESHUUN; + if (c.eligible(player) && player.getInventory().getAmount(Items.COINS_995) > c.getCost() + && player.getInventory().remove(new Item(Items.COINS_995, c.getCost()))) { + player.getHouseManager().setCrest(c); + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ah yes, our new neighbours under Lumbridge. I hear", "you were the one who made contact with them, jolly good."); + stage = 40; + } else { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hmm, have you ever even met the Dorgeshuun? I don't", "think you should wear their symbol until you have", "made contact with that lost tribe."); + stage = 310; + } + break; + } + case 4: { + CrestType c = CrestType.DRAGON; + if (c.eligible(player) && player.getInventory().getAmount(Items.COINS_995) > c.getCost() + && player.getInventory().remove(new Item(Items.COINS_995, c.getCost()))) { + player.getHouseManager().setCrest(c); + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I see you are a mighty dragon-slayer! You have", "certainly earned the right to wear a dragon symbol."); + stage = 40; + } else { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "[MISSING DIALOGUE - NOT ELIGIBLE]"); + stage = 310; + } + break; + } + case 5: + interpreter.sendOptions("Select an option", "Fairy", "Guthix", "HAM", "Horse", "More..."); + stage = 330; + break; + } + break; + case 330: + switch (buttonId) { + case 1: { + CrestType c = CrestType.FAIRY; + if (c.eligible(player) && player.getInventory().getAmount(Items.COINS_995) > c.getCost() + && player.getInventory().remove(new Item(Items.COINS_995, c.getCost()))) { + player.getHouseManager().setCrest(c); + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hmm, mmm, yes, everyone likes pretty fairies."); + stage = 40; + } else { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "[MISSING DIALOGUE - NOT ELIGIBLE]"); + stage = 310; + } + break; + } + case 2: { + CrestType c = CrestType.GUTHIX; + if (c.eligible(player) && player.getInventory().getAmount(Items.COINS_995) > c.getCost() + && player.getInventory().remove(new Item(Items.COINS_995, c.getCost()))) { + player.getHouseManager().setCrest(c); + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Guthix, god of balance! I'm a Saradominist myself,", "you know, but we all find meaning in our own way, what?"); + stage = 40; + } else { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "You do not seem to be very devoted to any god.", "I will not let you have a divine symbol", "unless you have level 70 prayer."); + stage = 310; + } + break; + } + case 3: { + CrestType c = CrestType.HAM; + if (c.eligible(player) && player.getInventory().getAmount(Items.COINS_995) > c.getCost() + && player.getInventory().remove(new Item(Items.COINS_995, c.getCost()))) { + player.getHouseManager().setCrest(c); + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hmm, I'm not sure I like that HAM group, their", "beliefs are a little extreme for me.", "But if that's what you want."); + stage = 40; + } else { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "[MISSING DIALOGUE - NOT ELIGIBLE]"); + stage = 310; + } + break; + } + case 4: { + CrestType c = CrestType.HORSE; + if (c.eligible(player) && player.getInventory().getAmount(Items.COINS_995) > c.getCost() + && player.getInventory().remove(new Item(Items.COINS_995, c.getCost()))) { + player.getHouseManager().setCrest(c); + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ah, I see you've brought a toy horse for me to see. An", + "interesting beast. Certainly you can use that as your", + "crest if you like, although it seems a bit strange to me."); + stage = 40; + } else { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "A horse? I know people talk about them, but I'm not at all sure", + "they ever existed. I don't think I could let you use as", + "your symbol unless you can fetch me some kind of model of one."); + stage = 310; + } + break; + } + case 5: + interpreter.sendOptions("Select an option", "Jogre", "Kandarin", "Misthalin", "Money", "More..."); + stage = 340; + break; + } + break; + case 340: + switch (buttonId) { + case 1: { + CrestType c = CrestType.JOGRE; + if (c.eligible(player) && player.getInventory().getAmount(Items.COINS_995) > c.getCost() + && player.getInventory().remove(new Item(Items.COINS_995, c.getCost()))) { + player.getHouseManager().setCrest(c); + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "A Jungle Ogre, eh? Odd beast, very odd."); + stage = 40; + } else { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "[MISSING DIALOGUE - NOT ELIGIBLE]"); + stage = 310; + } + break; + } + case 2: { + CrestType c = CrestType.KANDARIN; + if (c.eligible(player) && player.getInventory().getAmount(Items.COINS_995) > c.getCost() + && player.getInventory().remove(new Item(Items.COINS_995, c.getCost()))) { + player.getHouseManager().setCrest(c); + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Our neighbours in the west? Very good, very good."); + stage = 40; + } else { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "[MISSING DIALOGUE - NOT ELIGIBLE]"); + stage = 310; + } + break; + } + case 3: { + CrestType c = CrestType.MISTHALIN; + if (c.eligible(player) && player.getInventory().getAmount(Items.COINS_995) > c.getCost() + && player.getInventory().remove(new Item(Items.COINS_995, c.getCost()))) { + player.getHouseManager().setCrest(c); + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ah, the fair land of Lumbridge and Varrock."); + stage = 40; + } else { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "[MISSING DIALOGUE - NOT ELIGIBLE]"); + stage = 310; + } + break; + } + case 4: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "You wish to represent yourself by a moneybag?", "I think to make that meaningful I should increase", "the price to 500,000 coins. Do you agree?"); + stage = 342; + break; + case 5: + interpreter.sendOptions("Select an option", "Saradomin", "Skull", "Varrock", "Zamorak", "More..."); + stage = 350; + break; + } + break; + case 341: + interpreter.sendOptions("Select an option", "All right.", "No way!"); + stage = 342; + break; + case 342: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "All right."); + CrestType c = CrestType.MONEY; + if (c.eligible(player) && player.getInventory().getAmount(Items.COINS_995) > c.getCost()) { + stage = 343; + } else { + stage = 302; + } + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No way!"); + stage = 344; + break; + } + break; + case 343: { + CrestType c = CrestType.MONEY; + if (c.eligible(player) && player.getInventory().getAmount(Items.COINS_995) > c.getCost() + && player.getInventory().remove(new Item(Items.COINS_995, c.getCost()))) { + player.getHouseManager().setCrest(c); + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Thank you very much! You may now use a money-bag", "as your symbol."); + stage = 40; + } else { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "[MISSING DIALOGUE - NOT ELIGIBLE]"); + stage = 310; + } + break; + } + case 344: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Well we can't have just any pauper using a money-bag", "as a symbol, can we? You'll have to choose a", "different symbol."); + stage = 310; + break; + case 350: + switch (buttonId) { + case 1: { + CrestType c = CrestType.SARADOMIN; + if (c.eligible(player) && player.getInventory().getAmount(Items.COINS_995) > c.getCost() + && player.getInventory().remove(new Item(Items.COINS_995, c.getCost()))) { + player.getHouseManager().setCrest(c); + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ah, the great god Saradomin! May he smile on your house", "as you adorn it with his symbol!"); + if (!player.getAchievementDiaryManager().getDiary(DiaryType.FALADOR).isComplete(2,1)) { + player.getAchievementDiaryManager().getDiary(DiaryType.FALADOR).updateTask(player,2,1,true); + } + stage = 40; + } else { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "You do not seem to be very devoted to any god.", "I will not let you have a divine symbol", "unless you have level 70 prayer."); + stage = 310; + } + break; + } + case 2: { + CrestType c = CrestType.SKULL; + if (c.eligible(player) && player.getInventory().getAmount(Items.COINS_995) > c.getCost() + && player.getInventory().remove(new Item(Items.COINS_995, c.getCost()))) { + player.getHouseManager().setCrest(c); + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Of, of course you can have a skull symbol, " + (player.getAppearance().isMale() ? "sir!" : "madam!")); + stage = 40; + } else { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "A symbol of death? You do not seem like a killer to me;", "perhaps some other symbol would suit you better."); + stage = 310; + } + break; + } + case 3: { + CrestType c = CrestType.VARROCK; + if (c.eligible(player) && player.getInventory().getAmount(Items.COINS_995) > c.getCost() + && player.getInventory().remove(new Item(Items.COINS_995, c.getCost()))) { + player.getHouseManager().setCrest(c); + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ah, Varrock, a fine city!"); + stage = 40; + } else { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "[MISSING DIALOGUE - NOT ELIGIBLE]"); + stage = 310; + } + break; + } + case 4: { + CrestType c = CrestType.ZAMORAK; + if (c.eligible(player) && player.getInventory().getAmount(Items.COINS_995) > c.getCost() + && player.getInventory().remove(new Item(Items.COINS_995, c.getCost()))) { + player.getHouseManager().setCrest(c); + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "The god of Chaos? It is a terrible thing to worship", "that evil being. But if that is what you wish..."); + stage = 40; + } else { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "You do not seem to be very devoted to any god.", "I will not let you have a divine symbol", "unless you have level 70 prayer."); + stage = 310; + } + break; + } + case 5: + interpreter.sendOptions("Select an Option", "Shield of Arrav", "Asgarnia", "Dorgeshuun Symbol", "Dragon", "More..."); + stage = 320; + break; + } + break; + case 500: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "[MISSING DIALOGUE - UNIMPLIMENTED]"); + stage = 40; + } + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new SirReniteeDialogue(player); + } + + @Override + public int[] getIds() { + return new int[]{4249}; + } + +} diff --git a/Server/src/main/content/region/asgarnia/falador/dialogue/SirTiffyCashienDialogue.kt b/Server/src/main/content/region/asgarnia/falador/dialogue/SirTiffyCashienDialogue.kt new file mode 100644 index 0000000..70abbe7 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/dialogue/SirTiffyCashienDialogue.kt @@ -0,0 +1,120 @@ +package content.region.asgarnia.falador.dialogue + +import content.data.Quests +import content.region.asgarnia.falador.quest.recruitmentdrive.SirTiffyCashienDialogueFile +import core.ServerConstants +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class SirTiffyCashienDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + + // Completed Recruitment Drive & Start Wanted!! Quest + if (isQuestComplete(player!!, Quests.RECRUITMENT_DRIVE)) { + openDialogue(player, SirTiffyCashienAfterRecruitmentDriveQuestDialogueFile(), npc) + return true + } + + // Recruitment Drive Quest + if (isQuestInProgress(player!!, Quests.RECRUITMENT_DRIVE, 1, 99)) { + openDialogue(player, SirTiffyCashienDialogueFile(), npc) + return true + } + + // Fallback to default. + when (stage) { + START_DIALOGUE -> player("Hello.").also { stage++ } + 1 -> npc(FacialExpression.FRIENDLY, "What ho, ${if (player.isMale) "sirrah" else "milady"}.", "Spiffing day for a walk in the park, what?").also { stage++ } + 2 -> player(FacialExpression.THINKING, "Spiffing?").also { stage++ } + 3 -> npc(FacialExpression.FRIENDLY, "Absolutely, top-hole!", "Well, can't stay and chat all day, dontchaknow!", "Ta-ta for now!").also { stage++ } + 4 -> player(FacialExpression.THINKING, "Erm...goodbye.").also { stage = END_DIALOGUE } + } + + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return SirTiffyCashienDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.SIR_TIFFY_CASHIEN_2290) + } +} + +// Move this to Wanted!! Quest. +class SirTiffyCashienAfterRecruitmentDriveQuestDialogueFile : DialogueBuilderFile() { + private fun dialogueChangeSpawnPoint(builder: DialogueBuilder, place: String, location: Location, tiffyLine1: String, tiffyLine2: String): DialogueBuilder { + return builder.npcl("${tiffyLine1} Are you sure?") + .options().let { optionBuilder -> + optionBuilder.option("Yes, I want to respawn in $place.") + .playerl("Yes, I want to respawn in $place.") + .npcl(tiffyLine2) + .endWith { _, player -> + setAttribute(player, "/save:spawnLocation", location) + player.properties.spawnLocation = location + } + optionBuilder.option("Actually, no thanks. I like my respawn point.") + .playerl("Actually, no thanks. I like my respawn point.") + .npcl("As you wish, what? Ta-ta for now.") + } + } + + override fun create(b: DialogueBuilder) { + b.onPredicate { _ -> true } + .npc(FacialExpression.HAPPY, "What ho, @g[sirrah,milady].", "Jolly good show on the old training grounds thingy,", "what?") + .options().let { optionBuilder -> + optionBuilder.option_playerl("Do you have any jobs for me yet?") + .npcl("Sorry dear @g[boy,gal] but we are still in the process of organising.") + .npcl("I'm sure that we will have something for you soon, so please feel free to check back later.") + // Started of Wanted! quest + .end() + optionBuilder.option("Can you explain the Gaze of Saradomin to me?") + .playerl("I don't really understand this 'Gaze of Saradomin' thing... Do you think you could explain what it does for me?") + .npcl("Certainly @g[sirrah,milady]! As you know, we Temple Knights are personally favoured by Saradomin himself.") + .npcl("And when I say personally favoured, I don't mean that sometime off in the future he's going to buy us all a drink!") + .npcl("He watches over each of us, and when we die he catches us as we fall, and ensures we arrive back at Falador castle safe and sound.") + .npcl("We usually lose some equipment when he does so, but it's a small price to pay to be hale and hearty again, what?") + .npcl("Some lucky fellows have a similar system going already, but when they die they spawn in that squalid little swamp village Lumbridge.") + .playerl("Yeah, what kind of person would want to spawn there... Certainly not me, and I never have! Honest!") + .npcl("Well, you should be glad that we offer you a step up then! Falador is clearly a far superior town to spend your time in!") + .npcl("Was there something else you wanted to ask good old Tiffy, @g[sirrah,milady]?") + .end() + optionBuilder.option("Can I buy some armour?") + .playerl("Can I buy some armour?") + // Recruitment Drive -> Initiate level, Slug Menace -> Proselyte level + .npcl("Of course dear @g[boy,gal]. I can sell you up to Initiate level items only I'm afraid.") + .endWith { _, player -> + openNpcShop(player, npc!!.id) + } + optionBuilder.option("Can I switch respawns please?") + .branch { player -> if (player.properties.spawnLocation == ServerConstants.HOME_LOCATION) { 1 } else { 0 } } + .let { branch -> + dialogueChangeSpawnPoint( + branch.onValue(1), + "Falador", Location(2971, 3340, 0), //https://www.youtube.com/watch?v=Mm15dHuIaVg + "Ah, so you'd like to respawn in Falador, the good old homestead!", + "Top-hole, what? Good old Fally is definitely the hot-spot nowadays!" + ) + dialogueChangeSpawnPoint( + branch.onValue(0), + "Lumbridge", ServerConstants.HOME_LOCATION ?: Location(3222, 3218, 0), + "What? You're saying you want to respawn in Lumbridge?", + "Why anyone would want to visit that smelly little swamp village of oiks is quite beyond me, I'm afraid, but the deed is done now." + ) + } + optionBuilder.option("Goodbye.") + .playerl("Well, see you around Tiffy.") + .npcl(FacialExpression.HAPPY,"Ta-ta for now, old bean!") + .end() + } + } +} diff --git a/Server/src/main/content/region/asgarnia/falador/dialogue/SirVyvinDialogue.java b/Server/src/main/content/region/asgarnia/falador/dialogue/SirVyvinDialogue.java new file mode 100644 index 0000000..b593c12 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/dialogue/SirVyvinDialogue.java @@ -0,0 +1,56 @@ +package content.region.asgarnia.falador.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Handles the SirVyvinDialogue dialogue. + * @author 'Vexia + */ +@Initializable +public class SirVyvinDialogue extends DialoguePlugin { + + public SirVyvinDialogue() { + + } + + public SirVyvinDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new SirVyvinDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Greetings traveller."); + stage = 1; + break; + case 1: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 605 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/falador/dialogue/WayneDialogue.java b/Server/src/main/content/region/asgarnia/falador/dialogue/WayneDialogue.java new file mode 100644 index 0000000..85a9824 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/dialogue/WayneDialogue.java @@ -0,0 +1,74 @@ +package content.region.asgarnia.falador.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the dialogue plugin used for the wayne npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class WayneDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code WayneDialogue} {@code Object}. + */ + public WayneDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code WayneDialogue} {@code Object}. + * @param player the player. + */ + public WayneDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new WayneDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Welcome to Wayne's Chains. Do you wanna buy or", "sell some chain mail?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "Yes please.", "No thanks."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + end(); + npc.openShop(player); + break; + case 2: + end(); + break; + + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 581 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/falador/dialogue/WhiteKnightDialoguePlugin.java b/Server/src/main/content/region/asgarnia/falador/dialogue/WhiteKnightDialoguePlugin.java new file mode 100644 index 0000000..300edab --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/dialogue/WhiteKnightDialoguePlugin.java @@ -0,0 +1,63 @@ +package content.region.asgarnia.falador.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the white knight dialogue. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class WhiteKnightDialoguePlugin extends DialoguePlugin { + + /** + * The NPC ids that use this dialogue plugin. + */ + private static final int[] NPC_IDS = { 660 }; + + /** + * Constructs a new {@code WhiteKnightDialoguePlugin} {@code Object}. + */ + public WhiteKnightDialoguePlugin() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code WhiteKnightDialoguePlugin} {@code Object}. + * @param player the player. + */ + public WhiteKnightDialoguePlugin(Player player) { + super(player); + } + + @Override + public boolean open(Object... args) { + interpreter.sendDialogue("He is too busy dancing to talk!"); + return true; + } + + @Override + public int[] getIds() { + return NPC_IDS; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + end(); + break; + } + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new WhiteKnightDialoguePlugin(player); + } + +} diff --git a/Server/src/main/content/region/asgarnia/falador/dialogue/WorkmanDialogue.kt b/Server/src/main/content/region/asgarnia/falador/dialogue/WorkmanDialogue.kt new file mode 100644 index 0000000..81bd9e2 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/dialogue/WorkmanDialogue.kt @@ -0,0 +1,37 @@ +package content.region.asgarnia.falador.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +/** + * @author qmqz + * https://youtu.be/DwQgAQqaXos + */ + +@Initializable +class WorkmanDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + START_DIALOGUE -> player(FacialExpression.FRIENDLY, "Hiya.").also { stage++ } + 1 -> npc(FacialExpression.ANNOYED, "What do you want? I've got work to do!").also { stage++ } + 2 -> player(FacialExpression.ASKING, "Can you teach me anything?").also { stage++ } + 3 -> npcl(FacialExpression.ANNOYED, "No - I've got one lousy apprentice already, and that's quite enough hassle! Go away!").also { stage = END_DIALOGUE } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return WorkmanDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.WORKMAN_3236) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/falador/dialogue/WysonTheGardenerDialogue.kt b/Server/src/main/content/region/asgarnia/falador/dialogue/WysonTheGardenerDialogue.kt new file mode 100644 index 0000000..1d2592a --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/dialogue/WysonTheGardenerDialogue.kt @@ -0,0 +1,248 @@ +package content.region.asgarnia.falador.dialogue + +import content.data.tables.BirdNest +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.diary.DiaryType +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import core.plugin.Initializable +import org.rs09.consts.Items +import core.game.diary.DiaryLevel + +/** + * Represents the Wyson the gardener dialogue. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +class WysonTheGardenerDialogue : core.game.dialogue.DialoguePlugin { + /** + * If its a bird nest reward. + */ + private var birdNest = false + + /** + * Constructs a new `WysonTheGardenerDialogue` `Object`. + */ + constructor() { + /** + * empty. + */ + } + + /** + * Constructs a new `WysonTheGardenerDialogue` `Object`. + * @param player the player. + */ + constructor(player: Player?) : super(player) {} + + override fun newInstance(player: Player): core.game.dialogue.DialoguePlugin { + return WysonTheGardenerDialogue(player) + } + + override fun open(vararg args: Any): Boolean { + npc = args[0] as NPC + birdNest = player.inventory.containsItem(MOLE_CLAW) || player.inventory.containsItem(MOLE_SKIN) + if (birdNest) { + npc("If I'm not mistaken, you've got some mole bits there!", "I'll trade 'em for bird nest if ye likes.") + stage = 100 + return true + } + npc("I'm the head gardener around here.", "If you're looking for woad leaves, or if you need help", "with owt, I'm yer man.") + stage = 0 + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> { + options("Yes please, I need woad leaves.", "Sorry, but I'm not interested.") + stage = 1 + } + 1 -> when (buttonId) { + 1 -> { + player("Yes please, I need woad leaves.") + stage = 10 + } + 2 -> { + player("Sorry, but I'm not interested.") + stage = 200 + } + } + 10 -> { + npc("How much are you willing to pay?") + stage = 11 + } + 11 -> { + options("How about 5 coins?", "How about 10 coins?", "How about 15 coins?", "How about 20 coins?") + stage = 12 + } + 12 -> when (buttonId) { + 1 -> { + player("How about 5 coins?") + stage = 110 + } + 2 -> { + player("How about 10 coins?") + stage = 110 + } + 3 -> { + player("How about 15 coins?") + stage = 130 + } + 4 -> { + player("How about 20 coins?") + stage = 140 + } + } + 110 -> { + npc("No no, that's far too little. Woad leaves are hard to get. I", "used to have plenty but someone kept stealing them off", "me.") + stage = 111 + } + 111 -> end() + 130 -> { + npc("Mmmm... ok, that sounds fair.") + stage = 131 + } + 131 -> if (player.inventory.contains(995, 15)) { + player.inventory.remove(COINS[0]) + player.inventory.add(WOAD_LEAF) + player("Thanks.") + player.packetDispatch.sendMessage("You buy a woad leaf from Wyson.") + stage = 132 + } else { + end() + player.packetDispatch.sendMessage("You need 15 cold coins to buy a woad leaf.") + } + 132 -> { + npc("I'll be around if you have any more gardening needs.") + stage = 133 + } + 133 -> end() + 140 -> { + npc("Thanks for being generous", "here's an extra woad leaf.") + stage = 141 + } + 141 -> if (player.inventory.contains(995, 20)) { + player.inventory.remove(COINS[1]) + var i = 0 + while (i < 2) { + player.inventory.add(WOAD_LEAF, player) + i++ + } + player("Thanks.") + player.packetDispatch.sendMessage("You buy two woad leaves from Wyson.") + stage = 132 + } else { + end() + player.packetDispatch.sendMessage("You need 15 cold coins to buy a woad leaf.") + } + 200 -> { + npc("Fair enough.") + stage = 201 + } + 201 -> end() + 100 -> { + options("Yes, I will trade the mole claws.", "Okay, I will trade the mole skin.", "I'd like to trade both.", "No, thanks.") + stage = 900 + } + 900 -> when (buttonId) { + 1 -> { + player("Yes, I will trade the mole claws.") + stage = 910 + } + 2 -> { + player("Okay, I will trade the mole skin.") + stage = 920 + } + 3 -> { + player("I'd like to trade both.") + stage = 930 + } + 4 -> { + player("No, thanks.") + stage = 999 + } + } + 910 -> { + if (!player.inventory.containsItem(MOLE_CLAW)) { + player("Sorry, I don't have any mole claws.") + stage = 999 + } + end() + addRewards() + } + 920 -> { + if (!player.inventory.containsItem(MOLE_SKIN)) { + player("Sorry, I don't have any mole skins.") + stage = 999 + } + end() + addRewards() + } + 930 -> { + if (!player.inventory.containsItem(MOLE_CLAW) && !player.inventory.containsItem(MOLE_SKIN)) { + player("Sorry, I don't have any.") + stage = 999 + } + addRewards() + end() + } + 999 -> end() + } + return true + } + + /** + * Adds nests. + * @param nestAmount the amount. + */ + private fun addRewards() { + val moleClaws = player.inventory.getAmount(Items.MOLE_CLAW_7416) + val moleSkin = player.inventory.getAmount(Items.MOLE_SKIN_7418) + val nestAmount = moleClaws + moleSkin + + //Remove claws and skins + player.inventory.remove(Item(Items.MOLE_CLAW_7416,moleClaws)) + player.inventory.remove(Item(Items.MOLE_SKIN_7418, moleSkin)) + + //Add white lily seeds if the player has the hard diary done + if(moleSkin > 0 && player.achievementDiaryManager.getDiary(DiaryType.FALADOR).checkComplete(DiaryLevel.HARD)) { + player.inventory.add(Item(14589, moleSkin), player) + } + + //Add nests + for (i in 0 until nestAmount) { + if(!player.inventory.add(Item(BirdNest.getRandomNest(true).nest.id, 1), player)){ + GroundItemManager.create(Item(BirdNest.getRandomNest(true).nest.id,1),player.location,player) + } + } + } + + override fun getIds(): IntArray { + return intArrayOf(36) + } + + companion object { + /** + * Represents the coins item that can be used. + */ + private val COINS = arrayOf(Item(995, 15), Item(995, 20)) + + /** + * Represents the woad leaf item. + */ + private val WOAD_LEAF = Item(1793, 1) + + /** + * The mole claw item. + */ + private val MOLE_CLAW = Item(7416) + + /** + * The mole skin. + */ + private val MOLE_SKIN = Item(7418) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/falador/dialogue/gardensupplier.java b/Server/src/main/content/region/asgarnia/falador/dialogue/gardensupplier.java new file mode 100644 index 0000000..e3dfa27 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/dialogue/gardensupplier.java @@ -0,0 +1,61 @@ +package content.region.asgarnia.falador.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; + +/** + * Handles the garden supplier NPC + * @author ceik + */ +@Initializable +public class gardensupplier extends DialoguePlugin { + public gardensupplier(){ + /** + * Empty + */ + } + public gardensupplier(Player player){super(player);} + + @Override + public DialoguePlugin newInstance(Player player){return new gardensupplier(player);} + + @Override + public boolean open(Object... args){ + npc("Hello, I sell many plants. Would you like","to see what I have?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int componentId, int buttonId){ + switch(stage){ + case 0: + player.getDialogueInterpreter().sendOptions("Select one","Yes, please!","No, thanks."); + stage++; + break; + case 1: + switch(buttonId){ + case 1: + player("Yes, please!"); + stage++; + break; + case 2: + player("No, thanks."); + stage = 10; + break; + } + break; + case 2: + end(); + new NPC(4251).openShop(player); + break; + case 10: + end(); + break; + } + return true; + } + public int[] getIds() { return new int[] {4251};} +} diff --git a/Server/src/main/content/region/asgarnia/falador/diary/FaladorAchievementDiary.kt b/Server/src/main/content/region/asgarnia/falador/diary/FaladorAchievementDiary.kt new file mode 100644 index 0000000..4831afd --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/diary/FaladorAchievementDiary.kt @@ -0,0 +1,300 @@ +package content.region.asgarnia.falador.diary + +import core.api.allInEquipment +import core.api.inBorders +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.diary.DiaryType +import core.game.node.entity.skill.Skills.FARMING +import core.game.world.map.zone.ZoneBorders +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery +import content.region.asgarnia.falador.dialogue.RisingSunInnBartenderDialogue +import content.global.handlers.iface.FairyRing +import content.global.skill.crafting.lightsources.LightSources +import content.global.skill.farming.FarmingPatch +import core.api.getStatLevel +import core.game.diary.AreaDiaryTask +import core.game.diary.DiaryEventHookBase +import core.game.diary.DiaryLevel +import core.game.event.* +import core.game.node.entity.skill.Skills +import core.game.world.map.Location + +class FaladorAchievementDiary : DiaryEventHookBase(DiaryType.FALADOR) { + companion object { + private const val ATTRIBUTE_BLACK_CHAINBODY_PURCHASED = "diary:falador:black-chain-bought" + + private val MINING_GUILD_AREA = ZoneBorders(3016, 9731, 3055, 9756) + private val DARK_WIZARDS_TOWER_ROOF_AREA = ZoneBorders(2904, 3331, 2911, 3338, 2) + private val WHITE_KNIGHTS_CASTLE_ROOF_AREA = ZoneBorders(2955, 3333, 2996, 3354, 3) + private val PARK_TREE_PATCH_AREA = ZoneBorders(3002, 3371, 3006, 3375) + private val PARK_POND_AREA = ZoneBorders(2987, 3381, 2994, 3386) + private val WAYNES_CHAINS_AREA = ZoneBorders(2969, 3310, 2975, 3314) + private val SARAHS_FARMING_SHOP_AREA = ZoneBorders(3021, 3285, 3040, 3296) + private val FALADOR_GENERAL_AREA = ZoneBorders(2934, 3399, 3399, 3307) + private val CHEMIST_AREA = ZoneBorders(2929, 3213, 2936, 3207) + private val PORT_SARIM_FLOWER_PATCH = ZoneBorders(3053, 3306, 3056, 3309) + + + private val PROSELYTE_FULL_ARMOR_MALE = intArrayOf( + Items.PROSELYTE_SALLET_9672, + Items.PROSELYTE_HAUBERK_9674, + Items.PROSELYTE_CUISSE_9676 + ) + + private val PROSELYTE_FULL_ARMOR_FEMALE = intArrayOf( + Items.PROSELYTE_SALLET_9672, + Items.PROSELYTE_HAUBERK_9674, + Items.PROSELYTE_TASSET_9678 + ) + + private val PARTY_BALLOONS = intArrayOf( + Scenery.PARTY_BALLOON_115, Scenery.PARTY_BALLOON_116, Scenery.PARTY_BALLOON_117, + Scenery.PARTY_BALLOON_118, Scenery.PARTY_BALLOON_119, Scenery.PARTY_BALLOON_120, + Scenery.PARTY_BALLOON_121, Scenery.PARTY_BALLOON_122 + ) + + private val PARK_DUCKS = intArrayOf( + NPCs.DUCK_46, NPCs.DUCK_2693 + ) + + private val FALADOR_GUARD = intArrayOf( + NPCs.GUARD_9, // Guard - City Gates + NPCs.GUARD_3230, // Guard - Greataxe + NPCs.GUARD_3228, // Guard - Fountain Longsword + NPCs.GUARD_3229 // Guard - Fountain Crossbow + ) + + private val SKELETAL_WYVERNS = intArrayOf( + NPCs.SKELETAL_WYVERN_3068, NPCs.SKELETAL_WYVERN_3069, + NPCs.SKELETAL_WYVERN_3070, NPCs.SKELETAL_WYVERN_3071 + ) + + object EasyTasks { + const val PORT_SARIM_SARAH_BUY_FARMING_AMULET = 0 + const val RISING_SUN_BUY_A_STATBOOST = 1 + const val WAYNE_BUY_AND_WEAR_BLACK_CHAINBODY = 2 + const val WHITE_KNIGHTS_CASTLE_CLIMB_TO_TOP = 3 + const val SIR_RENITEE_FAMILY_CREST_DISCOVER = 4 + const val PARK_ENTER_MOLE_LAIR = 5 + const val FEED_RIDGELEY_AT_HAIRDRESSERS = 6 + const val FILL_BUCKET_FROM_NORTHERN_PUMP = 7 + const val HEAL_ELEMENTAL_WIZARD_WITH_SPELL = 8 + const val PARK_KILL_A_DUCK = 9 + const val SOUTHERN_ROAD_KILL_HIGHWAYMAN = 10 + const val MAKE_AIR_TIARA = 11 + const val POP_PARTY_BALLOON = 12 + const val PORT_SARIM_RECHARGE_PRAYER_POINTS = 13 + const val TAKE_BOAT_TO_ENTRANA = 14 + } + + object MediumTasks { + const val PORT_SARIM_CRAFT_FRUIT_BASKET = 0 + const val CRAWL_UNDER_SOUTHERN_WALL = 1 + const val GRAPPLE_AND_JUMP_OFF_NORTHERN_WALL = 2 + const val INCREASE_WHITE_KNIGHT_REPUTATION = 3 + const val ICE_DUNGEON_KILL_ICE_GIANT = 4 + const val CHEMISTS_LIGHT_BULLSEYE_LANTERN = 5 + const val PICKPOCKET_GUARD = 6 + const val PORT_SARIM_NORTHERN_PATCH_PLACE_SCARECROW = 7 + const val SALUTE_SIR_TIFFY_CASHIEN_IN_INITIATE_ARMOR = 8 + const val SMITH_BLURITE_CROSSBOW_LIMBS_ON_THURGOS_ANVIL = 9 + const val PORT_SARIM_CHAROS_TRAVEL_TO_MUSA_POINT = 10 + const val PORT_SARIM_VISIT_RAT_PITS = 11 + } + + object HardTasks { + const val DARK_WIZARDS_TOWER_ASCEND_IN_FULL_PROSELYTE_ARMOR = 0 + const val CHANGE_FAMILY_CREST_TO_SARADOMIN = 1 + const val CRAFT_196_AIR_RUNES_AT_ONCE = 2 + const val CUT_DOWN_GROWN_YEW_OR_MAGIC_TREE = 3 + const val DIAL_FAIRY_RING_MUDSKIPPER_POINT = 4 + const val PORT_SARIM_BETTY_DYE_CAPE_PINK = 5 + const val ENTER_MINING_GUILD = 6 + const val MUDSKIPPER_POINT_KILL_MOGRE = 7 + const val ICE_DUNGEON_KILL_SKELETAL_WYVERN = 8 + const val PORT_SARIM_FISH_STORE_SUMMON_IBIS = 9 + } + } + + override val areaTasks + get() = arrayOf( + AreaDiaryTask( + WHITE_KNIGHTS_CASTLE_ROOF_AREA, + DiaryLevel.EASY, + EasyTasks.WHITE_KNIGHTS_CASTLE_CLIMB_TO_TOP + ), + + AreaDiaryTask( + MINING_GUILD_AREA, + DiaryLevel.HARD, + HardTasks.ENTER_MINING_GUILD + ), + + AreaDiaryTask( + DARK_WIZARDS_TOWER_ROOF_AREA, + DiaryLevel.HARD, + HardTasks.DARK_WIZARDS_TOWER_ASCEND_IN_FULL_PROSELYTE_ARMOR, + ) { player -> + allInEquipment(player, *PROSELYTE_FULL_ARMOR_MALE) + || allInEquipment(player, *PROSELYTE_FULL_ARMOR_FEMALE) + } + ) + + override fun onInteracted(player: Player, event: InteractionEvent) { + when (player.viewport.region.id) { + 12084 -> { + if (event.option == "burst" && event.target.id in PARTY_BALLOONS) { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.POP_PARTY_BALLOON + ) + } + } + } + + if (event.option == "pickpocket" && (event.target.id in FALADOR_GUARD && inBorders(player, FALADOR_GENERAL_AREA) && getStatLevel(player, Skills.THIEVING) >= 40)) { + finishTask( + player, + DiaryLevel.MEDIUM, + MediumTasks.PICKPOCKET_GUARD + ) + } + } + + override fun onDialogueOptionSelected(player: Player, event: DialogueOptionSelectionEvent) { + when (event.dialogue) { + is RisingSunInnBartenderDialogue -> { + if (event.currentStage in 12..14) { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.RISING_SUN_BUY_A_STATBOOST + ) + } + } + } + } + + override fun onResourceProduced(player: Player, event: ResourceProducedEvent) { + when (player.viewport.region.id) { + 11828 -> when (event.itemId) { + Items.YEW_LOGS_1515, Items.MAGIC_LOGS_1513 -> { + if (inBorders(player, PARK_TREE_PATCH_AREA)) { + finishTask( + player, + DiaryLevel.HARD, + HardTasks.CUT_DOWN_GROWN_YEW_OR_MAGIC_TREE + ) + } + } + } + } + } + + override fun onNpcKilled(player: Player, event: NPCKillEvent) { + when (player.viewport.region.id) { + 11828 -> if (event.npc.id in PARK_DUCKS && inBorders(event.npc, PARK_POND_AREA)) { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.PARK_KILL_A_DUCK + ) + } + + 12181 -> if (event.npc.id in SKELETAL_WYVERNS) { + finishTask( + player, + DiaryLevel.HARD, + HardTasks.ICE_DUNGEON_KILL_SKELETAL_WYVERN + ) + } + } + if (event.npc.id == NPCs.MOGRE_114){ + finishTask(player, DiaryLevel.HARD, HardTasks.MUDSKIPPER_POINT_KILL_MOGRE) + } + } + + override fun onItemPurchasedFromShop(player: Player, event: ItemShopPurchaseEvent) { + when { + inBorders(player, WAYNES_CHAINS_AREA) && (event.itemId == Items.BLACK_CHAINBODY_1107) -> { + fulfillTaskRequirement( + player, + DiaryLevel.EASY, + EasyTasks.WAYNE_BUY_AND_WEAR_BLACK_CHAINBODY, + ATTRIBUTE_BLACK_CHAINBODY_PURCHASED + ) + } + + inBorders(player, SARAHS_FARMING_SHOP_AREA) && (event.itemId == Items.AMULET_OF_FARMING8_12622) -> { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.PORT_SARIM_SARAH_BUY_FARMING_AMULET + ) + } + } + } + + override fun onItemEquipped(player: Player, event: ItemEquipEvent) { + when { + inBorders(player, WAYNES_CHAINS_AREA) && (event.itemId == Items.BLACK_CHAINBODY_1107) -> { + whenTaskRequirementFulfilled(player, ATTRIBUTE_BLACK_CHAINBODY_PURCHASED) { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.WAYNE_BUY_AND_WEAR_BLACK_CHAINBODY + ) + } + } + } + } + + override fun onFairyRingDialed(player: Player, event: FairyRingDialEvent) { + if (event.fairyRing == FairyRing.AIQ) { + finishTask( + player, + DiaryLevel.HARD, + HardTasks.DIAL_FAIRY_RING_MUDSKIPPER_POINT + ) + } + } + + override fun onLightSourceLit(player: Player, event: LitLightSourceEvent) { + when { + inBorders(player, CHEMIST_AREA) && (event.litLightSourceId == LightSources.BULLSEYE_LANTERN.litID) -> { + finishTask( + player, + DiaryLevel.MEDIUM, + MediumTasks.CHEMISTS_LIGHT_BULLSEYE_LANTERN + ) + } + } + } + + override fun onUsedWith(player: Player, event: UseWithEvent) { + when { + inBorders(player, PORT_SARIM_FLOWER_PATCH) -> { + if (event.used == Items.SCARECROW_6059 && event.with == 7847 && player.getSkills().hasLevel(FARMING, 23) && FarmingPatch.forObjectID(7840)?.getPatchFor(player)?.plantable == null) { + finishTask( + player, + DiaryLevel.MEDIUM, + MediumTasks.PORT_SARIM_NORTHERN_PATCH_PLACE_SCARECROW + ) + } + } + } + } + + override fun onPrayerPointsRecharged(player: Player, event: PrayerPointsRechargeEvent) { + if (event.altar.id == Scenery.ALTAR_39842 && event.altar.location == Location(2995, 3177, 0)) { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.PORT_SARIM_RECHARGE_PRAYER_POINTS + ) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/falador/handlers/BankNotices.kt b/Server/src/main/content/region/asgarnia/falador/handlers/BankNotices.kt new file mode 100644 index 0000000..11a124e --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/handlers/BankNotices.kt @@ -0,0 +1,48 @@ +package content.region.asgarnia.falador.handlers + +import content.global.handlers.iface.ScrollInterface +import content.global.handlers.iface.ScrollLine +import core.game.interaction.InteractionListener +import org.rs09.consts.Components +import org.rs09.consts.Scenery + +class BankNotices : InteractionListener { + companion object { + val CONTENTS_PIN = arrayOf( + ScrollLine("If you're worried about someone stealing items from your",3), + ScrollLine("bank, why not protect yourself with a Bank PIN?",4), + + ScrollLine("A Bank PIN is a four-digit number. It's like a password that",6), + ScrollLine("protects your bank account. If you set one, you'll be asked to",7), + ScrollLine("enter it before you can take items out of the bank.",8), + + ScrollLine("If you're interested, speak to the bankers and ask about Bank",10), + ScrollLine("PINs.",11), + + ScrollLine("But remember, KEEP YOUR PIN SECRET!",13), + ) + + val CONTENTS_PASSWORD = arrayOf( + ScrollLine("The Bank of RuneScape would like to remind customers that",4), + ScrollLine("they should NEVER tell ANYONE their password.",5), + + ScrollLine("If someone asks you to say your password, please report",7), + ScrollLine("them using the 'Report Abuse' button at the bottom of your",8), + ScrollLine("screen. ",9), + + ScrollLine("Change your password regularly, and make sure no-one else",11), + ScrollLine("could easily guess it!",12), + ) + } + + override fun defineListeners() { + on(Scenery.NOTICEBOARD_11755, SCENERY, "read") { player, _ -> + ScrollInterface.scrollSetup(player, Components.MESSAGESCROLL_220, CONTENTS_PIN) + return@on true + } + on(Scenery.NOTICEBOARD_11756, SCENERY, "read") { player, _ -> + ScrollInterface.scrollSetup(player, Components.MESSAGESCROLL_220, CONTENTS_PASSWORD) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/falador/handlers/FaladorNodePlugin.java b/Server/src/main/content/region/asgarnia/falador/handlers/FaladorNodePlugin.java new file mode 100644 index 0000000..3bb521e --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/handlers/FaladorNodePlugin.java @@ -0,0 +1,157 @@ +package content.region.asgarnia.falador.handlers; + +import core.cache.def.impl.NPCDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.game.global.action.DoorActionHandler; +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.impl.ForceMovement; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; + +/** + * Represents the plugin used to handle node interactions in falador. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class FaladorNodePlugin extends OptionHandler { + + /** + * Represents the opening of a cupboard animation. + */ + private static final Animation OPEN_ANIMATION = new Animation(536); + + /** + * Represents the closing of a cupboard animation. + */ + private static final Animation CLOSE_ANIMATION = new Animation(535); + + /** + * Represents the portrait item. + */ + private static final Item PORTRAIT = new Item(666); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(2271).getHandlers().put("option:open", this);// sir + // vyvans + // cupboard + // (closed) + SceneryDefinition.forId(2272).getHandlers().put("option:shut", this);// sir + // vyvans + // cupboard + // (open) + SceneryDefinition.forId(2272).getHandlers().put("option:search", this);// sir + // vyvans + // cupboard + // (open) + // dwarven mine + SceneryDefinition.forId(30868).getHandlers().put("option:squeeze-through", this); + SceneryDefinition.forId(5020).getHandlers().put("option:ride", this); + // fally park. + NPCDefinition.forId(2290).getHandlers().put("option:talk-to", this); + SceneryDefinition.forId(11708).getHandlers().put("option:close", this); + return this; + } + + @Override + public boolean handle(final Player player, Node node, String option) { + final int id = node.getId(); + switch (id) { + case 11708:// estate door. + DoorActionHandler.handleDoor(player, (Scenery) node); + break; + case 2290: + player.getDialogueInterpreter().open(id, node); + return true; + case 5020: + player.getDialogueInterpreter().sendDialogue("You must visit Keldagrim before you are allowed to ride mine carts."); + break; + case 30868: + if (player.getSkills().getLevel(Skills.AGILITY) < 42) { + player.getPacketDispatch().sendMessage("You need an agility level of 42 to do this."); + return true; + } + Location dest = player.getLocation().equals(new Location(3035, 9806, 0)) ? new Location(3028, 9806, 0) : new Location(3035, 9806, 0); + player.animate(new Animation(2240)); + ForceMovement movement = new ForceMovement(player, player.getLocation(), dest, new Animation(2240)) { + @Override + public void stop() { + super.stop(); + } + }; + movement.run(player, 8); + GameWorld.getPulser().submit(new Pulse(7, player) { + + @Override + public boolean pulse() { + player.animate(new Animation(2240)); + return true; + } + }); + break; + case 2271: + SceneryBuilder.replace((Scenery) node, ((Scenery) node).transform(2272)); + player.animate(OPEN_ANIMATION); + break; + case 2272: + switch (option) { + case "shut": + SceneryBuilder.replace((Scenery) node, ((Scenery) node).transform(2271)); + player.animate(CLOSE_ANIMATION); + break; + case "search": + if (player.getInventory().containsItem(PORTRAIT)) { + player.getDialogueInterpreter().sendDialogue("There is just a load of junk in here."); + return true; + } else { + + if (!player.getInventory().add(PORTRAIT)) { + GroundItemManager.create(PORTRAIT, player); + } + player.getDialogueInterpreter().sendDialogue("You find a small portrait in here which you take."); + } + break; + } + break; + } + return true; + } + + @Override + public Location getDestination(Node node, Node n) { + if (n instanceof NPC) { + final NPC npc = (NPC) n; + if (npc.getId() == 2290) { + return Location.create(2997, 3374, 0); + } + } else if (n instanceof Scenery) { + if (n.getId() == 11708 && node.getLocation().equals(new Location(2981, 3370, 0))) { + return node.getLocation(); + } + } + return null; + } + + @Override + public boolean isWalk() { + return false; + } + + @Override + public boolean isWalk(final Player player, Node node) { + return !(node instanceof Item); + } +} diff --git a/Server/src/main/content/region/asgarnia/falador/handlers/GiantMoleNPC.java b/Server/src/main/content/region/asgarnia/falador/handlers/GiantMoleNPC.java new file mode 100644 index 0000000..6564c96 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/handlers/GiantMoleNPC.java @@ -0,0 +1,316 @@ +package content.region.asgarnia.falador.handlers; + +import content.global.skill.skillcapeperks.SkillcapePerks; +import core.cache.def.impl.SceneryDefinition; +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import content.data.BossKillCounter; +import content.data.LightSource; +import core.game.global.action.DigAction; +import core.game.global.action.DigSpadeHandler; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.map.zone.impl.DarkZone; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.net.packet.PacketRepository; +import core.net.packet.context.InterfaceContext; +import core.net.packet.out.Interface; +import core.plugin.Plugin; +import core.plugin.Initializable; +import core.tools.RandomFunction; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playAudio; + +/** + * Handles the Giant Mole NPC. + * @author Emperor + */ +@Initializable +public final class GiantMoleNPC extends AbstractNPC { + + /** + * The dig locations. + */ + private static final Location[] DIG_LOCATIONS = new Location[] { Location.create(1760, 5183, 0),// center + Location.create(1736, 5223, 0),// top left + Location.create(1777, 5235, 0),// top right + Location.create(1739, 5150, 0), Location.create(1769, 5148, 0), Location.create(1750, 5195, 0), Location.create(1778, 5207, 0), Location.create(1772, 5199, 0), Location.create(1774, 5173, 0), Location.create(1760, 5162, 0), Location.create(1753, 5151, 0), Location.create(1739, 5152, 0) }; + + /** + * The digging animation. + */ + private static final Animation DIG_ANIMATION = new Animation(3314, Priority.VERY_HIGH); + + /** + * The digging graphic. + */ + private static final Graphics DIG_GRAPHIC = new Graphics(572); + + /** + * The dig up animation. + */ + private static final Animation DIG_UP_ANIMATION = new Animation(3315, Priority.VERY_HIGH); + + /** + * The digging graphic. + */ + private static final Graphics DIG_UP_GRAPHIC = new Graphics(573); + + /** + * The dust graphics. + */ + private static final Graphics DUST_GRAPHIC = new Graphics(571); + + /** + * If the NPC is digging. + */ + private boolean digging; + + /** + * Constructs a new {@code GiantMoleNPC} {@code Object}. + */ + public GiantMoleNPC() { + super(3340, null); + } + + /** + * Constructs a new {@code GiantMoleNPC} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + public GiantMoleNPC(int id, Location location) { + super(id, location); + } + + @Override + public void init() { + super.init(); + super.setWalks(true); + super.walkRadius = 128; + } + + /** + * Starts digging. + */ + private void dig() { + digging = true; + lock(5); + getProperties().getCombatPulse().stop(); + getWalkingQueue().reset(); + getLocks().lockMovement(5); + final Direction dir = Direction.get(RandomFunction.randomize(4)); + faceLocation(getCenterLocation().transform(dir.getStepX() << 2, dir.getStepY() << 2, 0)); + setDirection(dir); + int index = RandomFunction.randomize(DIG_LOCATIONS.length); + Location dest = DIG_LOCATIONS[index]; + if (dest.withinDistance(getLocation())) { + dest = DIG_LOCATIONS[(index + 1) % DIG_LOCATIONS.length]; + } + final Location destination = dest; + GameWorld.getPulser().submit(new Pulse(1, this) { + int count = 0; + Location hole; + + @Override + public boolean pulse() { + if (count == 0) { + hole = visualizeDig(destination, true); + } else if (count == 1) { + if (RandomFunction.RANDOM.nextBoolean()) { + splatterMud(hole); + } + } else if (count == 3) { + getProperties().setTeleportLocation(destination); + } else if (count == 4) { + visualizeDig(destination, false); + digging = false; + return true; + } + count++; + return false; + } + }); + } + + /** + * Handles the mud splattering. + * @param hole The hole location. + */ + private void splatterMud(Location hole) { + for (Player p : RegionManager.getLocalPlayers(getCenterLocation(), (size() >> 1) + 2)) { + PacketRepository.send(Interface.class, new InterfaceContext(p, 548, 77, 226, true)); + LightSource s = LightSource.getActiveLightSource(p); + if (s == null || s.isOpen()) { + if (s != null) { + p.getPacketDispatch().sendMessage("Your " + s.getName() + " seems to have been extinguished by the mud."); + int slot = p.getInventory().getSlot(s.getProduct()); + if (slot > -1) { + p.getInventory().replace(new Item(s.getRaw().getId()), slot); + } + } + DarkZone.checkDarkArea(p); + } + } + for (int i = 0; i < 1 + RandomFunction.randomize(3); i++) { + Projectile.create(hole, hole.transform(-4 + RandomFunction.randomize(9), -4 + RandomFunction.randomize(9), 0), 570, 0, 5, 45, 70, 5, 11).send(); + } + } + + /** + * Visualizes the digging. + * @param destination The destination of the mole. + * @param underground If the mole is going underground. + * @return The hole location. + */ + private Location visualizeDig(Location destination, boolean underground) { + Location offset = getCenterLocation(); + if (underground) { + switch (getDirection()) { + case NORTH: + offset = getLocation().transform(1, size() - 1, 0); + break; + case EAST: + offset = getLocation().transform(size() - 1, 1, 0); + break; + case WEST: + offset = getLocation().transform(0, 1, 0); + break; + default: + offset = getLocation().transform(1, 0, 0); + break; + } + } + for (int x = -1; x < 2; x++) { + for (int y = -1; y < 2; y++) { + Graphics.send(DUST_GRAPHIC, offset.transform(x, y, 0)); + } + } + if (underground) { + animate(DIG_ANIMATION); + Graphics.send(DIG_GRAPHIC, offset); + } else { + animate(DIG_UP_ANIMATION); + Graphics.send(DIG_UP_GRAPHIC, offset); + } + return offset; + } + + @Override + public void onImpact(final Entity entity, BattleState state) { + if (!getLocks().isInteractionLocked()) { + if (RandomFunction.randomize(100) < 24 && inCombat() && getSkills().getLifepoints() < 100 && getSkills().getLifepoints() > 5){ + dig(); + return; + } + } + super.onImpact(entity, state); + } + + @Override + public boolean isAttackable(Entity entity, CombatStyle style, boolean message) { + if (digging) { + return false; + } + return super.isAttackable(entity, style, message); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.put(568, new ComponentPlugin() { + @Override + public Plugin newInstance(Object arg) throws Throwable { + return this; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + if (button == 17) { + player.getProperties().setTeleportLocation(Location.create(1752, 5237, 0)); + playAudio(player, Sounds.ROOF_COLLAPSE_1384); + player.getPacketDispatch().sendMessage("You seem to have dropped down into a network of mole tunnels."); + + if (!player.getAchievementDiaryManager().getDiary(DiaryType.FALADOR).isComplete(0, 5)) { + player.getAchievementDiaryManager().getDiary(DiaryType.FALADOR).updateTask(player,0,5,true); + } + } + player.getInterfaceManager().close(); + return false; + } + }); + + DigAction action = new DigAction() { + @Override + public void run(Player player) { + if (!SkillcapePerks.isActive(SkillcapePerks.CONSTANT_GLOW, player) && !LightSource.hasActiveLightSource(player)) { + player.getPacketDispatch().sendMessage("It's going to be dark down there, I should bring a light source."); + return; + } + player.getInterfaceManager().open(new Component(568)); + } + }; + DigSpadeHandler.register(Location.create(3005, 3376, 0), action); + DigSpadeHandler.register(Location.create(2999, 3375, 0), action); + DigSpadeHandler.register(Location.create(2996, 3377, 0), action); + DigSpadeHandler.register(Location.create(2989, 3378, 0), action); + DigSpadeHandler.register(Location.create(2984, 3387, 0), action); + DigSpadeHandler.register(Location.create(2987, 3387, 0), action); + SceneryDefinition.forId(12230).getHandlers().put("option:climb", new OptionHandler() { + @Override + public Plugin newInstance(Object arg) throws Throwable { + return this; + } + + @Override + public boolean handle(final Player player, Node node, String option) { + player.animate(Animation.create(828)); + player.lock(2); + GameWorld.getPulser().submit(new Pulse(1, player) { + @Override + public boolean pulse() { + player.getProperties().setTeleportLocation(Location.create(2985, 3316, 0)); + return true; + } + }); + return true; + } + }); + return super.newInstance(arg); + } + + @Override + public void finalizeDeath(Entity killer) { + super.finalizeDeath(killer); + if (killer instanceof Player) { + Player player = killer.asPlayer(); + BossKillCounter.addtoKillcount(player, this.getId()); + } + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new GiantMoleNPC(id, location); + } + + @Override + public int[] getIds() { + return new int[] { 3340 }; + } + +} diff --git a/Server/src/main/content/region/asgarnia/falador/handlers/MiningGuildPlugin.java b/Server/src/main/content/region/asgarnia/falador/handlers/MiningGuildPlugin.java new file mode 100644 index 0000000..39678d7 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/handlers/MiningGuildPlugin.java @@ -0,0 +1,67 @@ +package content.region.asgarnia.falador.handlers; + +import static core.api.ContentAPIKt.*; +import core.cache.def.impl.SceneryDefinition; +import core.game.global.action.ClimbActionHandler; +import core.game.global.action.DoorActionHandler; +import core.game.node.entity.skill.Skills; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; + +import static core.api.ContentAPIKt.getDynLevel; + +/** + * Represents the plugin used for the mining guild. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class MiningGuildPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(2113).getHandlers().put("option:climb-down", this); + SceneryDefinition.forId(30941).getHandlers().put("option:climb-up", this); + SceneryDefinition.forId(2112).getHandlers().put("option:open", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + if (option.equals("climb-down")) { + if (player.getLocation().withinDistance(Location.create(3019, 3339, 0), 4)) { + if (getDynLevel(player, Skills.MINING) < 60) { + player.getDialogueInterpreter().open(382, NPC.create(382, Location.create(0, 0, 0)), 1); + return true; + } + ClimbActionHandler.climb(player, new Animation(828), Location.create(3021, 9739, 0)); + return true; + } + ClimbActionHandler.climbLadder(player, (Scenery) node, option); + return true; + } + if (option.equals("open")) { + if (getDynLevel(player, Skills.MINING) < 60) { + player.getDialogueInterpreter().open(382, NPC.create(382, Location.create(0, 0, 0)), 1); + return true; + } + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + } + if (option.equals("climb-up")) { + if (player.getLocation().withinDistance(new Location(3019, 9739, 0))) { + ClimbActionHandler.climb(player, new Animation(828), new Location(3017, 3339, 0)); + } else { + ClimbActionHandler.climbLadder(player, (Scenery) node, "climb-up"); + } + } + return true; + } + +} diff --git a/Server/src/main/content/region/asgarnia/falador/handlers/WantedPoster.java b/Server/src/main/content/region/asgarnia/falador/handlers/WantedPoster.java new file mode 100644 index 0000000..67bd978 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/handlers/WantedPoster.java @@ -0,0 +1,26 @@ +package content.region.asgarnia.falador.handlers; + +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; + +@Initializable +public class WantedPoster extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(40992).getHandlers().put("option:look-at", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + //Can do fun stuff related to a player being wanted or something. + player.getDialogueInterpreter().sendPlainMessage(false, "Looks like a generic wanted poster."); + return true; + } + +} diff --git a/Server/src/main/content/region/asgarnia/falador/handlers/partyroom/BalloonManager.java b/Server/src/main/content/region/asgarnia/falador/handlers/partyroom/BalloonManager.java new file mode 100644 index 0000000..79d70ae --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/handlers/partyroom/BalloonManager.java @@ -0,0 +1,333 @@ +package content.region.asgarnia.falador.handlers.partyroom; + +import java.util.ArrayList; +import java.util.List; + +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItem; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; +import core.tools.RandomFunction; + +import static core.api.ContentAPIKt.*; + + +/** + * Manages the droped party balloons. + * @author Vexia + */ +public final class BalloonManager extends OptionHandler { + + /** + * The list of dropped balloons. + */ + private static final List balloons = new ArrayList<>(20); + + /** + * The count down time until droping. + */ + private int countdown; + + /** + * Constructs a new {@Code BalloonManager} {@Code Object} + */ + public BalloonManager() { + /** + * empty. + */ + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (PartyBalloon balloon : PartyBalloon.values()) { + SceneryDefinition.forId(balloon.getBalloonId()).getHandlers().put("option:burst", this); + } + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + switch (option) { + case "burst": + PartyBalloon.forId(node.getId()).burst(player, node.asScenery()); + return true; + } + return true; + } + + @Override + public Location getDestination(Node node, Node n) { + return n.getLocation(); + } + + /** + * Starts the count down. + */ + public void start() { + if (isCountingDown()) { + return; + } + countdown = GameWorld.getTicks() + getDropDelay(); + final NPC partyPete = RegionManager.getNpc(new Location(3052, 3373, 0), 659, 1); + GameWorld.getPulser().submit(new Pulse(1) { + @Override + public boolean pulse() { + int realCount = --countdown - GameWorld.getTicks(); + for (ChestViewer viewer : PartyRoomPlugin.getViewers().values()) { + setVarp(viewer.getPlayer(), 1135, realCount); + } + if (--realCount - GameWorld.getTicks() <= 0) { + drop(); + return true; + } + partyPete.sendChat("" + realCount); + return realCount < 0; + } + }); + } + + /** + * Drops the balloons. + */ + private void drop() { + countdown = 0; + balloons.clear(); + PartyRoomPlugin.getPartyChest().addAll(PartyRoomPlugin.getChestQueue()); + PartyRoomPlugin.getChestQueue().clear(); + PartyRoomPlugin.update(); + GameWorld.getPulser().submit(new Pulse(1) { + int waves; + + @Override + public boolean pulse() { + if (waves == 0 || waves == 3 || waves == 5 || waves == 8 || waves == 10 || waves == 12 || waves == 15 || waves == 18 || waves == 20) { + for (int i = 0; i < 30; i++) { + Scenery balloon = getBalloon(); + if (balloon != null) { + balloons.add(balloon); + SceneryBuilder.add(balloon, RandomFunction.random(200, 300)); + } + } + } + return ++waves > 20; + } + + }); + } + + /** + * Gets the balloon drop. + * @return the balloon. + */ + private Scenery getBalloon() { + final Location location = new Location(3045 + RandomFunction.randomSign(RandomFunction.getRandom(8)), 3378 + RandomFunction.randomSign(RandomFunction.getRandom(6)), 0); + if (!RegionManager.isTeleportPermitted(location) || RegionManager.getObject(location) != null) { + return null; + } + return new Scenery(PartyBalloon.values()[RandomFunction.random(PartyBalloon.values().length)].getBalloonId(), location); + } + + /** + * Checks if the floor is cluttered. + * @return {@code True} if so. + */ + public boolean isCluttered() { + for (Scenery object : balloons) { + if (RegionManager.getObject(object.getLocation()) != null) { + return true; + } + } + return false; + } + + /** + * Gets the drop delay depending on wealth. + * @return the delay. + */ + public int getDropDelay() { + int wealth = getWealth(); + if (wealth <= 50000) { + return 10; + } else if (wealth >= 50000 && wealth <= 150000) { + return 100; + } else if (wealth >= 150000 && wealth <= 1000000) { + return 500; + } else if (wealth > 1000000) { + return 1000; + } + return 0; + } + + /** + * Gets the amount of wealth in the chest. + * @return the wealth. + */ + public int getWealth() { + return PartyRoomPlugin.getChestQueue().getWealth() + PartyRoomPlugin.getPartyChest().getWealth(); + } + + /** + * Checks if the balloon manager is counting down. + * @return {@code True} if so. + */ + public boolean isCountingDown() { + return countdown > GameWorld.getTicks(); + } + + /** + * Gets the balloons. + * @return the balloons + */ + public static List getBalloons() { + return balloons; + } + + /** + * Gets the countdown. + * @return the countdown + */ + public int getCountdown() { + return countdown; + } + + /** + * A party balloon. + * @author Vexia + */ + enum PartyBalloon { + YELLOW(115, 123), RED(116, 124), BLUE(117, 125), GREEN(118, 126), PURPLE(119, 127), WHITE(120, 128), GREEN_BLUE(121, 129), TRI(122, 130); + + /** + * The balloon id. + */ + private final int balloonId; + + /** + * The popping id. + */ + private final int popId; + + /** + * Constructs a new {@Code PartyBallon} {@Code Object} + * @param balloonId the balloon id. + * @param popId the pop id. + */ + private PartyBalloon(int balloonId, int popId) { + this.balloonId = balloonId; + this.popId = popId; + } + + /** + * Bursts a party balloon. + * @param player the player. + * @param object the object. + */ + public void burst(final Player player, final Scenery object) { + final Scenery popped = object.transform(popId); + if (!getBalloons().contains(object)) { + player.sendMessage("Error! Balloon not registered."); + return; + } + player.lock(2); + SceneryBuilder.remove(object); + SceneryBuilder.add(popped); + getBalloons().remove(object); + player.animate(Animation.create(10017)); + + GameWorld.getPulser().submit(new Pulse(1) { + int counter; + + @Override + public boolean pulse() { + switch (++counter) { + case 1: + SceneryBuilder.remove(popped); + if (!player.getIronmanManager().isIronman() && RandomFunction.random(3) == 1) { + GroundItem ground = getGround(object.getLocation(), player); + if (ground != null) { + GroundItemManager.create(ground); + PartyRoomPlugin.getPartyChest().shift(); + PartyRoomPlugin.update(); + } + } + return true; + } + return false; + } + }); + } + + /** + * Gets the ground item. + * @param location the location. + * @param player the player. + * @return the ground item. + */ + private GroundItem getGround(Location location, Player player) { + final Item item = PartyRoomPlugin.getPartyChest().toArray()[RandomFunction.random(PartyRoomPlugin.getPartyChest().itemCount())]; + if (item == null) { + return null; + } + if (PartyRoomPlugin.getPartyChest().remove(item)) { + final Item dropItem; + int newamt; + if (item.getAmount() > 1) { + newamt = RandomFunction.random(1, item.getAmount()); + if (item.getAmount() - newamt > 0) { + Item newItem = new Item(item.getId(), item.getAmount() - newamt); + PartyRoomPlugin.getPartyChest().add(newItem); + } + dropItem = new Item(item.getId(), newamt); + } else { + dropItem = item; + } + return new GroundItem(dropItem, location, player); + } + return null; + } + + /** + * Gets a party balloon. + * @param id the id. + * @return the balloon. + */ + public static PartyBalloon forId(int id) { + for (PartyBalloon balloon : values()) { + if (balloon.getBalloonId() == id) { + return balloon; + } + } + return null; + } + + /** + * Gets the balloonId. + * @return the balloonId + */ + public int getBalloonId() { + return balloonId; + } + + /** + * Gets the popId. + * @return the popId + */ + public int getPopId() { + return popId; + } + + } + +} diff --git a/Server/src/main/content/region/asgarnia/falador/handlers/partyroom/ChestViewer.java b/Server/src/main/content/region/asgarnia/falador/handlers/partyroom/ChestViewer.java new file mode 100644 index 0000000..c1b2302 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/handlers/partyroom/ChestViewer.java @@ -0,0 +1,333 @@ +package content.region.asgarnia.falador.handlers.partyroom; + +import core.game.component.CloseEvent; +import core.game.component.Component; +import core.game.container.Container; +import core.game.container.ContainerEvent; +import core.game.container.ContainerListener; +import core.game.container.ContainerType; +import core.game.container.SortType; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.net.packet.PacketRepository; +import core.net.packet.context.ContainerContext; +import core.net.packet.out.ContainerPacket; + +import static core.api.ContentAPIKt.*; + + +/** + * A chest viewer. + * @author Vexia + */ +public final class ChestViewer { + + /** + * The objects for the chest queue interface. + */ + private static final Object[] BEING_DROPPED = new Object[] { "", "", "", "", "", "", "", "", "", -1, 0, 39, 6, 92, 647 << 16 | 27 }; + + /** + * The objects for the dropping interface. + */ + private static final Object[] READY_TO_DROP = new Object[] { "", "", "", "", "", "", "", "", "", -1, 0, 39, 6, 91, 647 << 16 | 28 }; + + /** + * The objects for the accept interface. + */ + private static final Object[] ACCEPT = new Object[] { "", "", "", "", "Withdraw-X", "Withdraw-All", "Withdraw-10", "Withdraw-5", "Withdraw-1", -1, 0, 4, 10, 90, 647 << 16 | 29 }; + + /** + * The objects for the singletab. + */ + private final static Object[] INV_OPTIONS = new Object[] { "", "", "", "", "Deposit-X", "Deposit-All", "Deposit-10", "Deposit-5", "Deposit", -1, 0, 7, 4, 94, 648 << 16 }; + + /** + * The player viewing the chest. + */ + private final Player player; + + /** + * The container. + */ + private final DepositContainer container; + + /** + * Constructs a new {@Code ChestViewer} {@Code Object} + * @param player the player. + */ + public ChestViewer(Player player) { + this.player = player; + this.container = new DepositContainer(player); + } + + /** + * Views the chest. + */ + public ChestViewer view() { + container.open(); + player.getInventory().refresh(); + player.addExtension(ChestViewer.class, this); + player.getPacketDispatch().sendRunScript(150, "IviiiIsssssssss", ACCEPT); + player.getPacketDispatch().sendRunScript(150, "IviiiIsssssssss", INV_OPTIONS); + player.getInterfaceManager().openSingleTab(new Component(648)); + player.getInterfaceManager().open(new Component(647).setCloseEvent(new ChestCloseEvent())); + setVarp(player, 1135, 0); + update(0, null); + update(1, null); + return this; + } + + /** + * Updates the chest viewer. + * @param type the type. + * @param event the event. + */ + public void update(int type, ContainerEvent event) { + if (event == null) { + player.getPacketDispatch().sendIfaceSettings(1278, 27, 647, 0, 10); + player.getPacketDispatch().sendIfaceSettings(1278, 28, 647, 0, 10); + player.getPacketDispatch().sendIfaceSettings(1278, 29, 647, 0, 10); + switch (type) { + case 0: + player.getPacketDispatch().sendRunScript(150, "IviiiIsssssssss", BEING_DROPPED); + PacketRepository.send(ContainerPacket.class, new ContainerContext(player, -1, -2, 92, PartyRoomPlugin.getChestQueue().toArray(), 10, false)); + break; + case 1: + player.getPacketDispatch().sendRunScript(150, "IviiiIsssssssss", READY_TO_DROP); + PacketRepository.send(ContainerPacket.class, new ContainerContext(player, -1, -2, 91, PartyRoomPlugin.getPartyChest().toArray(), 10, false)); + break; + case 2: + player.getPacketDispatch().sendRunScript(150, "IviiiIsssssssss", ACCEPT); + PacketRepository.send(ContainerPacket.class, new ContainerContext(player, -1, -2, 90, new Item[] { new Item(4151, 2), new Item(11694, 2), new Item(4012, 2000) }, 10, false)); + break; + } + } + } + + /** + * Accepts the container. + */ + public void accept() { + if (PartyRoomPlugin.getChestQueue().itemCount() + getContainer().itemCount() > 215) { + player.sendMessage("The chest is full."); + return; + } + PartyRoomPlugin.getChestQueue().addAll(getContainer()); + getContainer().clear(); + PacketRepository.send(ContainerPacket.class, new ContainerContext(player, -1, -2, 90, new Item[] {}, 10, false)); + PartyRoomPlugin.update(0, null); + PartyRoomPlugin.update(1, null); + } + + /** + * Gets the container. + * @return the container + */ + public DepositContainer getContainer() { + return container; + } + + /** + * Gets the player. + * @return the player + */ + public Player getPlayer() { + return player; + } + + /** + * The close event for the chest interface. + * @author Vexia + */ + public class ChestCloseEvent implements CloseEvent { + + /** + * If the container has given back the items. + */ + private boolean given = false; + + @Override + public boolean close(Player player, Component c) { + if (!given) { + given = true; + player.getInventory().add(container.toArray()); + container.clear(); + player.removeExtension(ChestViewer.class); + player.getInterfaceManager().closeSingleTab(); + PartyRoomPlugin.getViewers().remove(player.getName()); + } + return true; + } + + } + + /** + * The container used when depositng items. + * @author Vexia + */ + public class DepositContainer extends Container { + + /** + * The player. + */ + private final Player player; + + /** + * The party deposit listener. + */ + private final PartyDepositListener listener; + + /** + * Constructs a new {@Code DepositContainer} {@Code + * Object} + * @param player the player. + */ + public DepositContainer(Player player) { + super(8, ContainerType.DEFAULT, SortType.ID); + super.getListeners().add(listener = new PartyDepositListener(player)); + this.player = player; + } + + /** + * Opens the container. + */ + public DepositContainer open() { + super.refresh(); + player.getInventory().getListeners().add(listener); + player.getPacketDispatch().sendRunScript(150, "IviiiIsssssssss", ACCEPT); + player.getPacketDispatch().sendRunScript(150, "IviiiIsssssssss", INV_OPTIONS); + PacketRepository.send(ContainerPacket.class, new ContainerContext(player, -1, -2, 90, new Item[] {}, 10, false)); + return this; + } + + /** + * Adds an item to the container. + * @param slot The item slot. + * @param amount The amount. + */ + public void addItem(int slot, int amount) { + if (slot < 0 || slot > player.getInventory().capacity() || amount < 1) { + return; + } + Item item = player.getInventory().get(slot); + if (item == null) { + return; + } + int maximum = player.getInventory().getAmount(item); + if (amount > maximum) { + amount = maximum; + } + int maxCount = super.getMaximumAdd(item); + if (amount > maxCount) { + amount = maxCount; + if (amount < 1) { + player.getPacketDispatch().sendMessage("You must accept the current items before adding any more."); + return; + } + } + item = new Item(item.getId(), amount); + if (!item.getDefinition().isTradeable()) { + player.getPacketDispatch().sendMessage("You can't add that item to the chest."); + return; + } + if (super.add(item) && player.getInventory().remove(item)) { + listener.update(this, null); + player.getInventory().update(); + PartyRoomPlugin.update(0, null); + PartyRoomPlugin.update(1, null); + } + } + + /** + * Takes a item from the container and adds one to the inventory + * container. + * @param slot The slot. + * @param amount The amount. + */ + public void takeItem(int slot, int amount) { + if (slot < 0 || slot > super.capacity() || amount <= 0) { + return; + } + Item item = super.get(slot); + if (item == null) { + return; + } + int realAmt = item.getAmount(); + if (!item.getDefinition().isStackable()) { + for (Item i : container.toArray()) { + if (i == null) { + continue; + } + if (i != item && i.getId() == item.getId()) { + realAmt++; + } + } + } + if (amount > realAmt) { + amount = realAmt; + } + item = new Item(item.getId(), amount); + Item add = item; + int maxCount = player.getInventory().getMaximumAdd(add); + if (amount > maxCount) { + item.setAmount(maxCount); + add.setAmount(maxCount); + if (maxCount < 1) { + player.getPacketDispatch().sendMessage("Not enough space in your inventory."); + return; + } + } + if (super.remove(item)) { + player.getInventory().add(add); + PacketRepository.send(ContainerPacket.class, new ContainerContext(player, -1, -2, 94, player.getInventory(), false)); + } + PartyRoomPlugin.update(0, null); + PartyRoomPlugin.update(1, null); + } + + /** + * Listeners to the part deposit container. + * @author Vexia + */ + private class PartyDepositListener implements ContainerListener { + + /** + * The player reference. + */ + private Player player; + + /** + * Constructs a new {@code PartyDepsositContainer.java} + * {@code Object}. + * @param player + */ + public PartyDepositListener(Player player) { + this.player = player; + } + + @Override + public void update(Container c, ContainerEvent event) { + if (c instanceof DepositContainer) { + player.getPacketDispatch().sendRunScript(150, "IviiiIsssssssss", ACCEPT); + player.getPacketDispatch().sendRunScript(150, "IviiiIsssssssss", INV_OPTIONS); + PacketRepository.send(ContainerPacket.class, new ContainerContext(player, -1, -2, 90, c.toArray(), 10, false)); + PacketRepository.send(ContainerPacket.class, new ContainerContext(player, -1, -2, 94, player.getInventory(), false)); + player.getPacketDispatch().sendIfaceSettings(1278, 0, 648, 0, 28); + } + } + + @Override + public void refresh(Container c) { + if (c instanceof DepositContainer) { + player.getPacketDispatch().sendIfaceSettings(1278, 0, 648, 0, 28); + player.getPacketDispatch().sendRunScript(150, "IviiiIsssssssss", ACCEPT); + player.getPacketDispatch().sendRunScript(150, "IviiiIsssssssss", INV_OPTIONS); + PacketRepository.send(ContainerPacket.class, new ContainerContext(player, -1, -2, 94, player.getInventory(), false)); + } + + } + } + } + +} diff --git a/Server/src/main/content/region/asgarnia/falador/handlers/partyroom/DropPartyLeverOptionPlugin.java b/Server/src/main/content/region/asgarnia/falador/handlers/partyroom/DropPartyLeverOptionPlugin.java new file mode 100644 index 0000000..fb0e9d9 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/handlers/partyroom/DropPartyLeverOptionPlugin.java @@ -0,0 +1,50 @@ +package content.region.asgarnia.falador.handlers.partyroom; + +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; + +/** + * Represents the plugin used for the drop party lever. + * @author 'Vexia + * @version 1.0 + */ +public final class DropPartyLeverOptionPlugin extends OptionHandler { + + /** + * Represents the animation to use. + */ + private static final Animation ANIMATION = new Animation(6933); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(26194).getHandlers().put("option:pull", this); + return this; + } + + @Override + public boolean handle(final Player player, Node node, String option) { + final Scenery object = (Scenery) node; + if (player.getAttribute("delay:lever", -1) > GameWorld.getTicks()) + return true; + player.setAttribute("delay:picking", GameWorld.getTicks() + 3); + player.lock(2); + player.faceLocation(object.getLocation()); + player.getDialogueInterpreter().open(1 << 16 | 2); + GameWorld.getPulser().submit(new Pulse(1, player) { + @Override + public boolean pulse() { + player.animate(ANIMATION); + return true; + } + }); + return true; + } + +} diff --git a/Server/src/main/content/region/asgarnia/falador/handlers/partyroom/PartyRoomPlugin.java b/Server/src/main/content/region/asgarnia/falador/handlers/partyroom/PartyRoomPlugin.java new file mode 100644 index 0000000..16ef90a --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/handlers/partyroom/PartyRoomPlugin.java @@ -0,0 +1,363 @@ +package content.region.asgarnia.falador.handlers.partyroom; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static core.api.ContentAPIKt.*; +import core.cache.def.impl.SceneryDefinition; +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.container.Container; +import core.game.container.ContainerEvent; +import core.game.dialogue.DialogueAction; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import kotlin.Unit; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; +import core.plugin.Initializable; +import core.plugin.ClassScanner; + +/** + * Handles the party room. + * @author Vexia + */ +@Initializable +public final class PartyRoomPlugin extends OptionHandler { + + /** + * The constants of the object ids. + */ + private static final int CLOSED_CHEST = 26193, OPEN_CHEST = 2418, LEVER = 26194; + + /** + * The queued chest. + */ + private static final Container chestQueue = new Container(215); + + /** + * The items currently being dropped. + */ + private static final Container partyChest = new Container(215); + + /** + * The mapping of chest viewers. + */ + private static final Map viewers = new HashMap<>(); + + /** + * The balloon manager. + */ + private static final BalloonManager balloonManager = new BalloonManager(); + + /** + * If the knight dance is commenced. + */ + private static boolean dancing; + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(CLOSED_CHEST).getHandlers().put("option:open", this); + SceneryDefinition.forId(OPEN_CHEST).getHandlers().put("option:deposit", this); + SceneryDefinition.forId(OPEN_CHEST).getHandlers().put("option:shut", this); + SceneryDefinition.forId(LEVER).getHandlers().put("option:pull", this); + ClassScanner.definePlugin(new DepositInterfaceHandler()); + ClassScanner.definePlugin(new BalloonManager()); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + switch (node.getId()) { + case CLOSED_CHEST: + player.animate(Animation.create(536)); + SceneryBuilder.replace(node.asScenery(), node.asScenery().transform(OPEN_CHEST)); + break; + case OPEN_CHEST: + switch (option) { + case "deposit": + deposit(player); + break; + case "shut": + player.animate(Animation.create(535)); + SceneryBuilder.replace(node.asScenery(), node.asScenery().transform(CLOSED_CHEST)); + break; + } + break; + case LEVER: + handleLever(player, node.asScenery()); + break; + } + return true; + } + + /** + * Updates the chest viewers. + * @param type the type. + * @param event the event. + */ + public static void update(int type, ContainerEvent event) { + for (ChestViewer viewer : viewers.values()) { + viewer.update(type, event); + } + } + + /** + * Updates the party room. + */ + public static void update() { + update(0, null); + update(1, null); + } + + /** + * Opens the deposit interface for the player. + * @param player the player. + */ + private void deposit(Player player) { + if (!viewers.containsKey(player.getName())) { + viewers.put(player.getName(), new ChestViewer(player).view()); + } else { + player.sendMessage("You are already viewing the chest!."); + } + } + + /** + * Commences the knightly dance. + */ + private void commenceDance() { + dancing = true; + final List npcs = new ArrayList(); + for (int i = 0; i < 6; i++) { + NPC npc = NPC.create(660, Location.create(3043 + i, 3378, 0)); + npc.init(); + npcs.add(npc); + } + GameWorld.getPulser().submit(new Pulse(1) { + int count = 0; + + @Override + public boolean pulse() { + switch (count) { + case 3: + npcs.get(3).sendChat("We're Knights of the Party Room"); + break; + case 6: + npcs.get(3).sendChat("We dance round and round like a loon"); + break; + case 8: + npcs.get(3).sendChat("Quite often we like to sing"); + break; + case 11: + npcs.get(3).sendChat("Unfortunately we make a din"); + break; + case 13: + npcs.get(3).sendChat("We're Knights of the Party Room"); + break; + case 16: + npcs.get(3).sendChat("Do you like our helmet plumes?"); + break; + case 18: + npcs.get(3).sendChat("Everyone's happy now we can move"); + break; + case 20: + npcs.get(3).sendChat("Like a party animal in the groove"); + break; + case 24: + dancing = false; + for (int i = 0; i < npcs.size(); i++) { + npcs.get(i).clear(); + } + break; + } + count++; + return false; + } + + }); + + } + + /** + * Handles the lever pulling. + * @param player the player. + * @param object the object. + */ + private void handleLever(Player player, Scenery object) { + player.lock(3); + player.faceLocation(object.getLocation()); + player.animate(Animation.create(6933), 1); + player.getDialogueInterpreter().sendOptions("Select an Option", "Ballon Bonanza (1000 coins).", "Nightly Dance (500 coins).", "No reward."); + player.getDialogueInterpreter().addAction(new DialogueAction() { + @Override + public void handle(Player player, int buttonId) { + switch (buttonId) { + case 2: + if (isCluttered()) { + player.getDialogueInterpreter().sendDialogue("The floor is too cluttered at the moment."); + } else if (balloonManager.isCountingDown()) { + player.getDialogueInterpreter().sendDialogue("A count down has already begun."); + } else if (player.getInventory().contains(995, 1000)) { + balloonManager.start(); + player.getInventory().remove(new Item(995, 1000)); + } else { + player.getDialogueInterpreter().sendDialogue("Balloon Bonanza costs 1000 coins."); + } + break; + case 3: + if (isDancing()) { + player.getDialogueInterpreter().sendDialogue("The party room knights are already here!"); + } else if (player.getInventory().contains(995, 500)) { + commenceDance(); + player.getInventory().remove(new Item(995, 500)); + } else { + player.getDialogueInterpreter().sendDialogue("Nightly Dance costs 500 coins."); + } + break; + default: + break; + } + } + }); + } + + /** + * Checks if the knights are dancing. + * @return {@code True} if so. + */ + private boolean isDancing() { + return dancing; + } + + /** + * Checks if the floor is too cluttered. + * @return {@code True} if so. + */ + private boolean isCluttered() { + return balloonManager.isCluttered(); + } + + /** + * Gets the chestQueue. + * @return the chestQueue + */ + public static Container getChestQueue() { + return chestQueue; + } + + /** + * Gets the partyChest. + * @return the partyChest + */ + public static Container getPartyChest() { + return partyChest; + } + + /** + * Gets the viewers. + * @return the viewers + */ + public static Map getViewers() { + return viewers; + } + + /** + * Handles the deposit interface. + * @author Vexia + */ + public static final class DepositInterfaceHandler extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.put(647, this); + ComponentDefinition.put(648, this); + return this; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, final int slot, int itemId) { + final ChestViewer viewer = player.getExtension(ChestViewer.class); + if (viewer == null || viewer.getContainer() == null) { + player.getInterfaceManager().close(); + return true; + } + switch (component.getId()) { + case 648: + if (itemId == -1) { + if (player.getInventory().get(slot) != null) { + itemId = player.getInventory().get(slot).getId(); + } else { + return true; + } + } + switch (opcode) { + case 155: + viewer.getContainer().addItem(slot, 1); + break; + case 196: + viewer.getContainer().addItem(slot, 5); + break; + case 124: + viewer.getContainer().addItem(slot, 10); + break; + case 199: + int ammount = player.getInventory().getAmount(new Item(itemId)); + viewer.getContainer().addItem(slot, ammount); + break; + case 234: + sendInputDialogue(player, true, "Enter the amount:", (value) -> { + viewer.getContainer().addItem(slot, (int) value); + return Unit.INSTANCE; + }); + break; + } + break; + case 647: + switch (button) { + case 25: + viewer.accept(); + return true; + } + if (itemId == -1 && viewer.getContainer().freeSlot() != 0) { + itemId = viewer.getContainer().get(slot).getId(); + } + switch (opcode) { + case 155: + viewer.getContainer().takeItem(slot, 1); + break; + case 196: + viewer.getContainer().takeItem(slot, 5); + break; + case 124: + viewer.getContainer().takeItem(slot, 10); + break; + case 199: + int ammount = viewer.getContainer().getAmount(new Item(itemId)); + viewer.getContainer().takeItem(slot, ammount); + break; + case 234: + sendInputDialogue(player, true, "Enter the amount:", (value) -> { + viewer.getContainer().takeItem(slot, (int) value); + return Unit.INSTANCE; + }); + break; + } + break; + } + return true; + } + + } + +} diff --git a/Server/src/main/content/region/asgarnia/falador/quest/TheKnightsSword.java b/Server/src/main/content/region/asgarnia/falador/quest/TheKnightsSword.java new file mode 100644 index 0000000..70ca795 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/quest/TheKnightsSword.java @@ -0,0 +1,130 @@ +package content.region.asgarnia.falador.quest; + +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.plugin.Initializable; +import core.game.node.item.Item; +import content.data.Quests; + +/** + * Represents The KnightSword quest. + * @author Vexia + * + */ +@Initializable +public class TheKnightsSword extends Quest { + + /** + * Represents the portrait item. + */ + private static final Item PORTRAIT = new Item(666); + + /** + * Constructs a new {@code TheKnightsSword} {@code Object}. + */ + public TheKnightsSword() { + super(Quests.THE_KNIGHTS_SWORD, 22, 21, 1, 122, 0, 1, 7); + } + + @Override + public Quest newInstance(Object object) { + return this; + } + + @Override + public void drawJournal(Player player, int stage) { + super.drawJournal(player, stage); + switch (stage) { + case 0: + player.getPacketDispatch().sendString(BLUE + "I can start this quest by speaking to the " + RED + "Squire " + BLUE + "in the", 275, 4+ 7); + player.getPacketDispatch().sendString(BLUE + "courtyard of the " + RED + "White Knights' Castle " + BLUE + "in " + RED + "southern Falador", 275, 5+ 7); + player.getPacketDispatch().sendString(BLUE + "To complete this quest I need:", 275, 6+ 7); + player.getPacketDispatch().sendString(RED + "Level 10 Mining", 275, 7+ 7); + player.getPacketDispatch().sendString(BLUE + "and to be unafraid of " + RED + "Level 57 Ice Warriors.", 275, 8+ 7); + break; + case 10: + line(player, "I told the Squire I would help him to replace the sword he", 4+ 7); + line(player, "has lost. It could only be made by an Imcando Dwarf.", 5+ 7); + line(player, BLUE + "The Squire suggests I speak to " + RED + "Reldo " + BLUE + "in the " + RED + " Varrock Palace", 6+ 7); + line(player, RED + "Library " + BLUE + "for information about the " + RED + "Imcando Dwarves", 7+ 7); + break; + case 20: + line(player, "I told the Squire I would help him to replace the sword he", 4+ 7); + line(player, "has lost. It could only be made by an Imcando Dwarf.", 5+ 7); + line(player, BLUE + "Reldo couldn't give me much information about the", 6+ 7); + line(player, RED + "Imcando " + BLUE + "except a few live on the " + RED + "southern peninsula of", 7+ 7); + line(player, RED + "Asgarnia, " + BLUE + "they dislike strangers, and LOVE " + RED + "redberry pies.", 8+ 7); + break; + case 30: + line(player, "I told the Squire I would help him to replace the sword he", 4+ 7); + line(player, "has lost. It could only be made by an Imcando Dwarf.", 5+ 7); + line(player, "I found an Imcando Dwarf named Thurgo thanks to", 6+ 7); + line(player, "information provided by Reldo. He wasn't very talkative", 7+ 7); + line(player, "until I gave him a Redberry pie, which he gobbled up.", 8+ 7); + line(player, BLUE + "He will help me now I have gained his trust through " + RED + "pie", 9+ 7); + break; + case 40: + line(player, "I told the Squire I would help him to replace the sword he", 4+ 7); + line(player, "has lost. It could only be made by an Imcando Dwarf.", 5+ 7); + line(player, "I found an Imcando Dwarf named Thurgo thanks to", 6+ 7); + line(player, "information provided by Reldo. He wasn't very talkative", 7+ 7); + line(player, "until I gave him a Redberry pie, which he gobbled up.", 8+ 7); + line(player, RED + "Thurgo " + BLUE + "needs a " + RED + "picture of the sword " + BLUE + "before he can help.", 9+ 7); + line(player, BLUE + "I should probably ask the " + RED + "Squire " + BLUE + "about obtaining one", 10+ 7); + break; + case 50: + line(player, "I told the Squire I would help him to replace the sword he", 4+ 7); + line(player, "has lost. It could only be made by an Imcando Dwarf.", 5+ 7); + line(player, "I found an Imcando Dwarf named Thurgo thanks to", 6+ 7); + line(player, "information provided by Reldo. He wasn't very talkative", 7+ 7); + line(player, "until I gave him a Redberry pie, which he gobbled up.", 8+ 7); + line(player, "Thurgo needed a picture of the sword to replace.", 9+ 7); + if (!player.getInventory().containsItem(PORTRAIT)) { + line(player, BLUE + "The Squire told me about a " + RED + "portrait ", 10+ 7); + line(player, BLUE + "which has a " + RED + "picture of the sword " + BLUE + "in " + RED + "Sir Vyvin's room", 11+ 7); + } else { + line(player, BLUE + "I now have a picture of the " + RED + "Knight's Sword " + BLUE + "- I should take it", 10+ 7); + line(player, BLUE + "to " + RED + "Thurgo " + BLUE + "so that he can duplicate it.", 11+ 7); + } + break; + case 60: + line(player, "I told the Squire I would help him to replace the sword he", 4+ 7); + line(player, "has lost. It could only be made by an Imcando Dwarf.", 5+ 7); + line(player, "I found an Imcando Dwarf named Thurgo thanks to", 6+ 7); + line(player, "information provided by Reldo. He wasn't very talkative", 7+ 7); + line(player, "until I gave him a Redberry pie, which he gobbled up.", 8+ 7); + line(player, "Thurgo needed a picture of the sword before he could", 9+ 7); + line(player, "start work on a replacement. I took him a portrait of it.", 10+ 7); + if (player.getInventory().contains(667, 1) || player.getEquipment().contains(667, 1) || player.getBank().contains(667, 1)) { + line(player, "Thurgo has now smithed me a replica of Sir Vyvin's sword.", 11+ 7); + line(player, BLUE + "I should return it to the " + RED + "Squire " + BLUE + "for my " + RED + "reward", 13+ 7); + } else { + line(player, BLUE + "according to " + RED + "Thurgo " + BLUE + "to make a " + RED + "replica sword " + BLUE + "he will need", 11+ 7); + line(player, RED + "two Iron Bars " + BLUE + "and some " + RED + "Blurite Ore. Blurite Ore " + BLUE + "can only be", 12+ 7); + line(player, BLUE + "found " + RED + "deep in the caves below Thurgo's house", 13+ 7); + } + break; + case 100: + line(player, "Thurgo needed a picture of the sword before he could", 4+ 7); + line(player, "start work on a replacement. I took him a portrait of it.", 5+ 7); + line(player, "After bringing Thurgo two iron bars and some blurite ore", 6+ 7); + line(player, "he made me a fine replica of Sir Vyvin's Sword, which I", 7+ 7); + line(player, "returned to the Squire for a reward.", 8+ 7); + line(player, "QUEST COMPLETE!", 10+ 7); + break; + } + + } + + @Override + public void finish(Player player) { + super.finish(player); + player.getPacketDispatch().sendString("1 Quest Point", 277, 8 + 2); + player.getPacketDispatch().sendString("12,725 Smithing XP", 277, 9 + 2); + player.getPacketDispatch().sendString("You have completed the Knight's Sword Quest!", 277, 2 + 2); + player.getPacketDispatch().sendItemZoomOnInterface(667, 230, 277, 3 + 2); + player.getSkills().addExperience(Skills.SMITHING, 12725); + } + +} diff --git a/Server/src/main/content/region/asgarnia/falador/quest/blackknightsfortress/BKCabbagePlugin.java b/Server/src/main/content/region/asgarnia/falador/quest/blackknightsfortress/BKCabbagePlugin.java new file mode 100644 index 0000000..1fdcd35 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/quest/blackknightsfortress/BKCabbagePlugin.java @@ -0,0 +1,47 @@ +package content.region.asgarnia.falador.quest.blackknightsfortress; + +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.plugin.Plugin; +import content.data.Quests; + +/** + * Represents the plugin used to send the cabbage down the hole. + * @author 'Vexia + * @version 1.0 + */ +public class BKCabbagePlugin extends UseWithHandler { + + /** + * Constructs a new {@code BKCabbagePlugin} {@code Object}. + */ + public BKCabbagePlugin() { + super(1965, 1967); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(2336, OBJECT_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + final Quest quest = player.getQuestRepository().getQuest(Quests.BLACK_KNIGHTS_FORTRESS); + if (quest.getStage(player) == 20) { + if (event.getUsedItem().getId() == 1967) { + player.getDialogueInterpreter().sendDialogue("This is the wrong sort of cabbage!"); + return true; + } + player.getDialogueInterpreter().open(992752973, true, true); + return true; + } else { + player.getDialogueInterpreter().sendDialogues(player, null, "Why exactly would I want to do that?"); + } + return false; + } + +} diff --git a/Server/src/main/content/region/asgarnia/falador/quest/blackknightsfortress/BKFortressPlugin.java b/Server/src/main/content/region/asgarnia/falador/quest/blackknightsfortress/BKFortressPlugin.java new file mode 100644 index 0000000..9f3c3ad --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/quest/blackknightsfortress/BKFortressPlugin.java @@ -0,0 +1,207 @@ +package content.region.asgarnia.falador.quest.blackknightsfortress; + +import core.cache.def.impl.ItemDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.game.global.action.ClimbActionHandler; +import core.game.global.action.DoorActionHandler; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.repository.Repository; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Plugin; +import org.rs09.consts.Items; + +import static core.api.ContentAPIKt.allInEquipment; + +/** + * Represents the black knights fortress node option plugin. + * @author 'Vexia + * @version 1.0 + */ +public final class BKFortressPlugin extends OptionHandler { + + /** + * Represents the listening animation. + */ + private static final Animation LISTEN_ANIM = new Animation(4195); + + /** + * Represents the lowering animation. + */ + private static final Animation LOWER_ANIM = new Animation(4552); + + /** + * Represents the first animation. + */ + private static final Animation FIRST_ANIM = new Animation(4549); + + /** + * Represents the last anim. + */ + private static final Animation LAST_ANIM = new Animation(4551); + + /** + * Represents the smoke graphic. + */ + private static final Graphics SMOKE = new Graphics(86, 109, 1); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ItemDefinition.forId(9589).getHandlers().put("option:read", this); + SceneryDefinition.forId(74).getHandlers().put("option:open", this); + SceneryDefinition.forId(73).getHandlers().put("option:open", this); + SceneryDefinition.forId(2337).getHandlers().put("option:open", this); + SceneryDefinition.forId(2338).getHandlers().put("option:open", this); + SceneryDefinition.forId(2341).getHandlers().put("option:push", this); + SceneryDefinition.forId(17148).getHandlers().put("option:climb-up", this); + SceneryDefinition.forId(17149).getHandlers().put("option:climb-down", this); + SceneryDefinition.forId(17160).getHandlers().put("option:climb-down", this); + SceneryDefinition.forId(2342).getHandlers().put("option:listen-at", this); + return this; + } + + @Override + public boolean handle(final Player player, Node node, String option) { + final int id = node instanceof Item ? ((Item) node).getId() : ((Scenery) node).getId(); + Scenery object = node instanceof Scenery ? ((Scenery) node) : null; + Location dest = null; + switch (id) { + case 2342:// listen at grill. + player.animate(LISTEN_ANIM); + GameWorld.getPulser().submit(new Pulse(2, player) { + @Override + public boolean pulse() { + player.animate(LOWER_ANIM); + player.getDialogueInterpreter().open(992752973); + return true; + } + }); + break; + case 17160: + if (object.getLocation().equals(new Location(3022, 3518, 1))) { + dest = Location.create(3022, 3517, 0); + } + if (dest != null) { + ClimbActionHandler.climb(player, new Animation(828), dest); + } else { + ClimbActionHandler.climbLadder(player, (Scenery) node, option); + } + break; + case 17149: + if (object.getLocation().equals(new Location(3023, 3513, 2))) { + dest = Location.create(3023, 3514, 1); + } else if (object.getLocation().equals(new Location(3025, 3513, 2))) { + dest = Location.create(3025, 3514, 1); + } else if (object.getLocation().equals(new Location(3016, 3519, 2))) { + dest = Location.create(3016, 3518, 1); + } else if (object.getLocation().equals(new Location(3015, 3519, 1))) { + dest = Location.create(3015, 3518, 0); + } else if (object.getLocation().equals(new Location(3017, 3516, 2))) { + dest = Location.create(3017, 3515, 1); + } + if (dest != null) { + ClimbActionHandler.climb(player, new Animation(828), dest); + } else { + ClimbActionHandler.climbLadder(player, (Scenery) node, option); + } + break; + case 17148: + if (object.getLocation().equals(new Location(3021, 3510, 0))) { + dest = Location.create(3022, 3510, 1); + } else if (object.getLocation().equals(new Location(3015, 3519, 0))) { + dest = Location.create(3015, 3518, 1); + } else if (object.getLocation().equals(new Location(3016, 3519, 0))) { + dest = Location.create(3016, 3518, 2); + } + if (dest != null) { + ClimbActionHandler.climb(player, new Animation(828), dest); + } else { + ClimbActionHandler.climbLadder(player, (Scenery) node, option); + } + break; + case 2341: + player.getPacketDispatch().sendMessage("You push against the wall. You find a secret passage."); + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + return true; + case 2338: + if (player.getLocation().getX() > 3019) { + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); // big table room door + return true; + } + player.getDialogueInterpreter().open(4605, Repository.findNPC(4605), true, true); + break; + case 2337: // Guard Door - only check for uniform from outside + switch (player.getLocation().getY()) { + case 3514: // Outside constant Y location, block the player for checks + if(allInEquipment(player, Items.BRONZE_MED_HELM_1139, Items.IRON_CHAINBODY_1101)){ + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + } + else player.getDialogueInterpreter().open(4605, Repository.findNPC(4604), true); + break; + case 3515: //Inside constant Y location, let the player through + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + default: + break; + } + break; + case 74: + case 73:// large door scenery id 73 + if (player.getLocation().getX() == 3008) { // only opened from inside + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + return true; + } + player.getPacketDispatch().sendMessage("You can't open this door."); // large door to the fortress + break; + case 9589: + switch (option) { + case "read":// 4549, 4551 + if (player.getInventory().remove((Item) node)) { + player.lock(); + GameWorld.getPulser().submit(new Pulse(1) { + int counter = 0; + + @Override + public boolean pulse() { + switch (counter++) { + case 1: + player.animate(FIRST_ANIM); + player.getDialogueInterpreter().sendDialogue("Infiltrate fortress... sabotage secret weapon... self", "destruct in 3...2...ARG!"); + break; + case 5: + player.graphics(SMOKE); + break; + case 7: + player.getInterfaceManager().closeChatbox(); + player.animate(LAST_ANIM); + player.unlock(); + return true; + } + return false; + } + }); + } + break; + } + break; + } + return true; + } + + @Override + public boolean isWalk() { + return false; + } + + @Override + public boolean isWalk(final Player player, final Node node) { + return !(node instanceof Item); + } + +} diff --git a/Server/src/main/content/region/asgarnia/falador/quest/blackknightsfortress/BKListenDialogue.java b/Server/src/main/content/region/asgarnia/falador/quest/blackknightsfortress/BKListenDialogue.java new file mode 100644 index 0000000..b8d4dd5 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/quest/blackknightsfortress/BKListenDialogue.java @@ -0,0 +1,162 @@ +package content.region.asgarnia.falador.quest.blackknightsfortress; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.game.world.update.flag.context.Animation; +import content.data.Quests; + +/** + * Represents the dialogue of listening throug a grill during the black knights' + * fortress quest. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class BKListenDialogue extends DialoguePlugin { + + /** + * Represents the cabbage item. + */ + private static final Item CABBAGE = new Item(1965); + + /** + * Represents the animation to use. + */ + private static final Animation ANIMATION = new Animation(832); + + /** + * Represents the captain npc. + */ + private final int captain = 610; + + /** + * Represents the witch npc. + */ + private final int witch = 611; + + /** + * Represents the goblin greldo npc. + */ + private final int greldo = 612; + + /** + * Represents the cat npc. + */ + private final int cat = 4607; + + /** + * Constructs a new {@code BKListenDialogue} {@code Object}. + */ + public BKListenDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code BKListenDialogue} {@code Object}. + * @param player the player. + */ + public BKListenDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new BKListenDialogue(player); + } + + @Override + public boolean open(Object... args) { + if (args != null && args.length == 2) { + interpreter.sendDialogues(witch, FacialExpression.NEUTRAL, "Where has Greldo got to with that magic cabbage!"); + stage = 10; + player.animate(ANIMATION); + return true; + } + interpreter.sendDialogues(captain, FacialExpression.ASKING, "So... how's the secret weapon coming along?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(witch, FacialExpression.HAPPY, "The invincibility potion is almost ready..."); + stage = 1; + break; + case 1: + interpreter.sendDialogues(witch, FacialExpression.HAPPY, "It's taken me FIVE YEARS, but it's almost ready."); + stage = 2; + break; + case 2: + interpreter.sendDialogues(witch, FacialExpression.NEUTRAL, "Greldo the Goblin here is just going to fetch the last", "ingredient for me."); + stage = 3; + break; + case 3: + interpreter.sendDialogues(witch, FacialExpression.NEUTRAL, "It's a special grown cabbage grown by my cousin", "Helda who lives in Draynor Manor."); + stage = 4; + break; + case 4: + interpreter.sendDialogues(witch, FacialExpression.NEUTRAL, "The soil there is slightly magical and it gives the", "cabbages slight magical properties...."); + stage = 5; + break; + case 5: + interpreter.sendDialogues(witch, FacialExpression.AMAZED, "...not to mention the trees!"); + stage = 6; + break; + case 6: + interpreter.sendDialogues(witch, FacialExpression.NEUTRAL, "Now remember Greldo, only a Draynor Manor", "cabbage will do! Don't get lazy and bring any old", "cabbage, THAT would ENTIRELY wreck the potion!"); + stage = 7; + break; + case 7: + interpreter.sendDialogues(greldo, FacialExpression.OLD_NORMAL, "Yeth, Mithreth."); + stage = 8; + break; + case 8: + player.getQuestRepository().getQuest(Quests.BLACK_KNIGHTS_FORTRESS).setStage(player, 20); + end(); + break; + case 10: + interpreter.sendDialogues(captain, FacialExpression.ASKING, "What's that noise?"); + stage = 11; + break; + case 11: + interpreter.sendDialogues(witch, FacialExpression.NEUTRAL, "Hopefully Greldo with the cabbage... yes, look her it", "co....NOOOOOoooo!"); + stage = 12; + break; + case 12: + interpreter.sendDialogues(witch, FacialExpression.EXTREMELY_SHOCKED, "My potion!"); + stage = 13; + break; + case 13: + interpreter.sendDialogues(captain, FacialExpression.WORRIED, "Oh boy, this doesn't look good!"); + stage = 14; + break; + case 14: + interpreter.sendDialogues(cat, FacialExpression.EXTREMELY_SHOCKED, "Meow!"); + stage = 15; + break; + case 15: + if (player.getInventory().remove(CABBAGE)) { + player.getQuestRepository().getQuest(Quests.BLACK_KNIGHTS_FORTRESS).setStage(player, 30); + interpreter.sendDialogues(player, FacialExpression.HAPPY, "Looks like my work here is done. Seems like that's", "successfully sabotaged their little secret weapon plan."); + stage = 16; + } + break; + case 16: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 992752973 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/falador/quest/blackknightsfortress/BlackKnightNPC.java b/Server/src/main/content/region/asgarnia/falador/quest/blackknightsfortress/BlackKnightNPC.java new file mode 100644 index 0000000..1b38a40 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/quest/blackknightsfortress/BlackKnightNPC.java @@ -0,0 +1,54 @@ +package content.region.asgarnia.falador.quest.blackknightsfortress; + +import core.game.node.entity.Entity; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.world.map.Location; +import core.plugin.Initializable; + +/** + * Represents the a duck npc. + * @author afaroutdude + */ +@Initializable +public final class BlackKnightNPC extends AbstractNPC { + + /** + * Constructs a new {@code BlackKnightNPC} {@code Object}. + */ + public BlackKnightNPC() { + super(0, null); + } + + /** + * Constructs a new {@code BlackKnightNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + public BlackKnightNPC(int id, Location location) { + super(id, location, true); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new BlackKnightNPC(id, location); + } + + @Override + public void finalizeDeath(final Entity killer) { + super.finalizeDeath(killer); + if (killer instanceof Player) { + final Player player = killer.asPlayer(); + if (!player.getAchievementDiaryManager().getDiary(DiaryType.FALADOR).isComplete(1, 3)) { + player.getAchievementDiaryManager().getDiary(DiaryType.FALADOR).updateTask(player, 1, 3, true); + } + } + } + + @Override + public int[] getIds() { + return new int[] { 178, 179, 610, 2698, 6189 }; + } + +} diff --git a/Server/src/main/content/region/asgarnia/falador/quest/blackknightsfortress/BlackKnightsFortress.java b/Server/src/main/content/region/asgarnia/falador/quest/blackknightsfortress/BlackKnightsFortress.java new file mode 100644 index 0000000..a3a1bf4 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/quest/blackknightsfortress/BlackKnightsFortress.java @@ -0,0 +1,97 @@ +package content.region.asgarnia.falador.quest.blackknightsfortress; + +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.ClassScanner; +import content.data.Quests; + +/** + * Represents the black knights fortress quest. + * @author Vexia + * + */ +@Initializable +public final class BlackKnightsFortress extends Quest { + + /** + * Represents the dossier item. + */ + public static final Item DOSSIER = new Item(9589); + + /** + * Constructs a new {@Code BlackKnightsFortress} {@Code Object} + */ + public BlackKnightsFortress() { + super(Quests.BLACK_KNIGHTS_FORTRESS, 14, 13, 3, 130, 0, 1, 4); + } + + @Override + public Quest newInstance(Object object) { + ClassScanner.definePlugins(new BKCabbagePlugin(), new BKFortressPlugin(), new SirAmikVarzeDialogue()); + return this; + } + + @Override + public void drawJournal(Player player, int stage) { + super.drawJournal(player, stage); + switch (stage) { + case 0: + player.getPacketDispatch().sendString("I can start this quest by speaking to the Sir Amik Varze at the", 275, 4 + 7); + player.getPacketDispatch().sendString(RED + " White Knight's Castle " + BLUE + "in " + RED + "Falador.", 275, 12); + if (player.getQuestRepository().getPoints() < 12) { + player.getPacketDispatch().sendString(RED + "I must have a total of at least 12 Quest Points", 275, 13); + } else { + line(player, "I have a total of at least 12 Quest Points", 13); + } + player.getPacketDispatch().sendString(BLUE + "I would have an advantage if I could fight " + RED + "Level 33 Knights", 275, 14); + player.getPacketDispatch().sendString(BLUE + "and if I had a smithing level of " + RED + "26.", 275, 15); + break; + case 10: + line(player, RED + "Sir Amik Varze " + BLUE + "has asked me to investigate the " + RED + "Black", 4 + 7); + line(player, RED + "Knights' Fortress " + BLUE + "which is located on " + RED + "Ice Mountain.", 5 + 7); + line(player, BLUE + "I need to disguise myself to gain entry to the " + RED + "Black", 6 + 7); + line(player, RED + "Knights' Fortress.", 7 + 7); + break; + case 20: + line(player, "Sir Amik Varze asked me to investigate the Black Knights'", 4 + 7); + line(player, "Fortress. I sneaked inside disguised as a Guard.", 5 + 7); + line(player, BLUE + "I eavesdropped on a Witch and the Black Knight Captain", 6+ 7); + line(player, BLUE + "and discovered that their invincibility potion can be", 7+ 7); + line(player, BLUE + "destroyed with a normal " + RED + "cabbage.", 8+ 7); + break; + case 30: + line(player, "Sir Amik Varze asked me to investigate the Black Knights'", 4+ 7); + line(player, "Fortress. I sneaked inside disguised as a Guard.", 5+ 7); + line(player, "I eavesdropped on a Witch and the Black Knight Captain", 6+ 7); + line(player, "and discovered that their invincibility potion could be", 7+ 7); + line(player, "destroyed with a normal cabbage.", 8+ 7); + line(player, BLUE + "Now that I have sabotaged the witch's potion, I can claim", 9+ 7); + line(player, BLUE + "my " + RED + "reward " + BLUE + "from " + RED + "Sir Amik Varze " + BLUE + "in " + RED + "Falador Castle.", 10+ 7); + break; + case 100: + line(player, "Sir Amik Varze asked me to investigate the Black Knights'", 4+ 7); + line(player, "Fortress. I sneaked inside disguised as a Guard.", 5+ 7); + line(player, "I eavesdropped on a Witch and the Black Knight Captain", 6+ 7); + line(player, "and discovered that their invincibility potion could be", 7+ 7); + line(player, "destroyed with a normal cabbage.", 8+ 7); + line(player, "I found a cabbage, and used it to a destroy the potion, then", 9+ 7); + line(player, "claimed my reward for a job well done.", 10+ 7); + line(player, "QUEST COMPLETE!", 12+ 7); + line(player, RED + "Reward:", 13+ 7); + line(player, BLUE + "3 Quest Points", 14+ 7); + line(player, BLUE + "2500gp", 15+ 7); + break; + } + } + + @Override + public void finish(Player player) { + super.finish(player); + player.getPacketDispatch().sendString("3 Quests Points", 277, 10); + player.getPacketDispatch().sendString("2500 Coins", 277, 11); + player.getPacketDispatch().sendItemZoomOnInterface(9591, 230, 277, 5); + } + +} diff --git a/Server/src/main/content/region/asgarnia/falador/quest/blackknightsfortress/FortressGuardDialogue.java b/Server/src/main/content/region/asgarnia/falador/quest/blackknightsfortress/FortressGuardDialogue.java new file mode 100644 index 0000000..51fa140 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/quest/blackknightsfortress/FortressGuardDialogue.java @@ -0,0 +1,235 @@ +package content.region.asgarnia.falador.quest.blackknightsfortress; + +import java.util.List; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.global.action.DoorActionHandler; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.game.world.map.RegionManager; + +/** + * Represents the fortress guard dialogue. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public class FortressGuardDialogue extends DialoguePlugin { + + /** + * Represents the uniform item. + */ + private static final Item[] UNIFORM = new Item[] { new Item(1139), new Item(1101) }; + + /** + * Constructs a new {@code FortressGuardDialogue} {@code Object}. + */ + public FortressGuardDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code FortressGuardDialogue} {@code Object}. + * @param player the player. + */ + public FortressGuardDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new FortressGuardDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + if (args.length == 2) { + interpreter.sendDialogues(npc, FacialExpression.ANGRY, "Hey! You can't come in here! This is a high security", "military installation!"); + stage = 40; + return true; + } + if (args.length == 3) { + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "I wouldn't go in there if I were you. Those Black", "Knights are in an important meeting. They said they'd", "kill anyone who went in there!"); + stage = 50; + return true; + } + if (!inUniform(player)) { + interpreter.sendDialogues(npc, FacialExpression.ANGRY, "Get lost. This is private property."); + stage = 0; + } else { + interpreter.sendDialogues(npc, FacialExpression.FURIOUS, "Hey! Get back on duty!"); + stage = 30; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Yes, but I work here!"); + stage = 1; + break; + case 1: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "Well, this is the guards' entrance. I might be new here", "but I can tell you're not a guard."); + stage = 2; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.ASKING, "How can you tell?"); + stage = 3; + break; + case 3: + interpreter.sendDialogues(npc, FacialExpression.ANGRY, "You're not even wearing proper guards uniform!"); + stage = 4; + break; + case 4: + interpreter.sendOptions("Select an Option", "Oh pleeeaase let me in!", "So what is this uniform?"); + stage = 5; + break; + case 5: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Oh pleeeaaase let me in!"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.ASKING, "So what is this uniform?"); + stage = 20; + break; + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.ANNOYED, "Go away. You're getting annoying."); + stage = 11; + break; + case 11: + end(); + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "Well you can see me wearing it. It's an iron chainbody", "and a medium bronze helm."); + stage = 21; + break; + case 21: + interpreter.sendDialogues(player, FacialExpression.HALF_ASKING, "Hmmm... I wonder if I can make that or get some in", "the local towns..."); + stage = 22; + break; + case 22: + interpreter.sendDialogues(npc, FacialExpression.HALF_ASKING, "What was that you muttered?"); + stage = 23; + break; + case 23: + interpreter.sendDialogues(player, FacialExpression.SUSPICIOUS, "Oh, nothing important!"); + stage = 24; + break; + case 24: + end(); + break; + case 30: + interpreter.sendDialogues(player, FacialExpression.SUSPICIOUS, "Uh..."); + stage = 31; + break; + case 31: + end(); + break; + case 40: + interpreter.sendOptions("Select an Option", "Yes, but I work here!", "Oh, sorry.", "So who does it belong to?"); + stage = 41; + break; + case 41: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Yes, but I work here!"); + stage = 1; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Oh, sorry."); + stage = 42; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.ASKING, "So who does it belong to?"); + stage = 44; + break; + } + break; + case 42: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "Don't let it happen again."); + stage = 43; + break; + case 43: + end(); + break; + case 44: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "This fortress belongs to the order of Black Knights", "known as the Kinshra."); + stage = 45; + break; + case 45: + interpreter.sendDialogues(player, FacialExpression.FRIENDLY, "Oh. Okay, thanks."); + stage = 46; + break; + case 46: + end(); + break; + case 50: + interpreter.sendOptions("Select an Option", "Okay, I won't.", "I don't care. I'm going in anyway."); + stage = 51; + break; + case 51: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Okay, I won't."); + stage = 52; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "I don't care. I'm going in anyway."); + stage = 54; + break; + } + break; + case 52: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "Wise move."); + stage = 53; + break; + case 53: + end(); + break; + case 54: + end(); + DoorActionHandler.handleAutowalkDoor(player, RegionManager.getObject(0, 3020, 3515)); + List npcs = RegionManager.getLocalNpcs(player); + for (NPC npc : npcs) { + if (npc.getId() == 179) { + npc.getProperties().getCombatPulse().attack(player); + npc.sendChat("Die, intruder!"); + return true; + } + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 609, 4603, 4604, 4605, 4606 }; + } + + /** + * Method used to check if the player is in the inventory. + * @param player the player. + * @return True if so. + */ + public static boolean inUniform(final Player player) { + for (Item i : UNIFORM) { + if (!player.getEquipment().containsItem(i)) { + return false; + } + } + return true; + } +} diff --git a/Server/src/main/content/region/asgarnia/falador/quest/blackknightsfortress/SirAmikVarzeDialogue.java b/Server/src/main/content/region/asgarnia/falador/quest/blackknightsfortress/SirAmikVarzeDialogue.java new file mode 100644 index 0000000..93901c1 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/quest/blackknightsfortress/SirAmikVarzeDialogue.java @@ -0,0 +1,331 @@ +package content.region.asgarnia.falador.quest.blackknightsfortress; + +import content.region.asgarnia.falador.quest.recruitmentdrive.SirAmikVarzeDialogueFile; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; + +import static core.api.ContentAPIKt.openDialogue; +import content.data.Quests; + +/** + * Represents the sir amik varze dialogue. + * @author Vexia + * + */ +public class SirAmikVarzeDialogue extends DialoguePlugin { + + /** + * Represents the instanced quest. + */ + private Quest quest; + + /** + * Constructs a new {@code SirAmikVarzeDialogue} {@code Object}. + */ + public SirAmikVarzeDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code SirAmikVarzeDialogue} {@code Object}. + * @param player the player. + */ + public SirAmikVarzeDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new SirAmikVarzeDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + quest = player.getQuestRepository().getQuest(Quests.BLACK_KNIGHTS_FORTRESS); + switch (quest.getStage(player)) { + case 30: + interpreter.sendDialogues(player, FacialExpression.HAPPY, "I have ruined the Black Knights' invincibility potion."); + stage = 0; + break; + case 10: + case 20: + interpreter.sendDialogues(npc, FacialExpression.ASKING, "How's the mission going?"); + stage = 0; + break; + case 100: + interpreter.sendDialogues(player, FacialExpression.HAPPY, "Hello Sir Amik."); + stage = 0; + break; + default: + interpreter.sendDialogues(npc, FacialExpression.ASKING, "I am the leader of the White Knights of Falador. Why", "do you seek my audience?"); + stage = 0; + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (quest.getStage(player)) { + case 100: + openDialogue(player, new SirAmikVarzeDialogueFile(), npc); + break; + case 30: + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "Yes, we have just received a message from the Black", "Knights saying they withdraw their demands, which", "would seem to confirm your story."); + stage = 1; + break; + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_ASKING, "Now I believe there was some talk of a cash reward..."); + stage = 2; + break; + case 2: + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Absolutely right. Please accept this reward."); + stage = 3; + break; + case 3: + interpreter.sendDialogue("Sir Amik hands you 2500 coins."); + stage = 4; + break; + case 4: + if (!player.getInventory().add(new Item(995, 2500))) { + GroundItemManager.create(new Item(995, 2500), player); + } + quest.finish(player); + player.getQuestRepository().syncronizeTab(player); + end(); + break; + } + break; + case 20: + switch (stage) { + case 0: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "I have managed to find what the secret weapon is", "I am now in the process of destroying it."); + stage = 1; + break; + case 1: + end(); + break; + } + break; + case 10: + switch (stage) { + case 0: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I haven't managed to find what the secret weapon is", "yet..."); + stage = 1; + break; + case 1: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "Well keep at it! Falador's future is at stake!"); + stage = 2; + break; + case 2: + if (!player.getInventory().containsItem(BlackKnightsFortress.DOSSIER) && !player.getBank().containsItem(BlackKnightsFortress.DOSSIER)) { + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "Here's the dossier on the case."); + stage = 3; + } else { + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "Don't forget to read that dossier of information I gave", "you."); + stage = 4; + } + break; + case 3: + player.getInventory().add(BlackKnightsFortress.DOSSIER); + end(); + break; + case 4: + end(); + break; + } + break; + case 0: + switch (stage) { + case 0: + if (player.getQuestRepository().getPoints() < 12) { + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "I don't I'm just looking around."); + stage = 2; + } else { + interpreter.sendOptions("Select an Option", "I seek a quest!", "I don't, I'm just looking around."); + stage = 1; + } + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "I seek a quest."); + stage = 5; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "I don't I'm just looking around."); + stage = 2; + break; + } + break; + case 2: + end(); + break; + case 3: + interpreter.sendDialogues(npc, FacialExpression.HALF_WORRIED, "Ok. Please don't break anything."); + stage = 4; + break; + case 4: + end(); + break; + case 5: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "Well, I need some spy work doing but it's quite", "dangerous. It will involve going into the Black Knights'", "fortress."); + stage = 6; + break; + case 6: + interpreter.sendOptions("Select an Option", "I laugh in the face of danger!", "I go and cower in the corner at the first sign of danger!"); + stage = 7; + break; + case 7: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HAPPY, "I laugh in the face of danger!"); + stage = 15; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I go and cower in a corner at the first sign of danger!"); + stage = 8; + break; + } + break; + case 8: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "Err...."); + stage = 9; + break; + case 9: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "Well."); + stage = 10; + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "I... suppose spy work DOES involve a little hiding in", "corners."); + stage = 11; + break; + case 11: + interpreter.sendOptions("Select an Option", "Oh. I suppose I'll give it a go then.", "No, I'm not ready to do that."); + stage = 12; + break; + case 12: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.FRIENDLY, "Oh. I suppose I'll give it a go then."); + stage = 17; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No, I'm not ready to do that."); + stage = 13; + break; + } + break; + case 13: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "Come see me again if you change your mind."); + stage = 14; + break; + case 14: + end(); + break; + case 15: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "Well that's good. Don't get too overconfident though."); + stage = 16; + break; + case 16: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "You've come along at just the right time actually. All of", "my knights are already known to the Black Knights."); + stage = 17; + break; + case 17: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Subtlety isn't exactly our strong point."); + stage = 18; + break; + case 18: + interpreter.sendDialogues(player, FacialExpression.HALF_ASKING, "Can't you just take your White Knights' armour off?", "They wouldn't recognise you then!"); + stage = 19; + break; + case 19: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "I am afraid our charter prevents us using espionage in", "any form, that is the domain of the Temple Knights."); + stage = 20; + break; + case 20: + interpreter.sendDialogues(player, FacialExpression.HALF_ASKING, "Temple Knights? Who are they?"); + stage = 21; + break; + case 21: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "The information is classified. I am forbidden to share it", "with outsiders."); + stage = 22; + break; + case 22: + interpreter.sendDialogues(player, FacialExpression.HALF_ASKING, "So... What do you need doing?"); + stage = 23; + break; + case 23: + interpreter.sendDialogues(npc, FacialExpression.ANGRY, "Well, the Black Knights have started making strange", "threats to us; demanding large amounts of money and", "land, and threatening to invade Falador if we don't pay", "them."); + stage = 24; + break; + case 24: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "Now, NORMALLY this wouldn't be a problem..."); + stage = 25; + break; + case 25: + interpreter.sendDialogues(npc, FacialExpression.ANGRY, "But they claim to have a powerful new secret weapon."); + stage = 26; + break; + case 26: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "Your mission, should you decide to accept it, is to", "infiltrate their fortress, find out what their secret", "weapon is, and then sabotage it."); + stage = 27; + break; + case 27: + interpreter.sendOptions("Select an Option", "Ok, I'll do my best.", "No, I'm not ready to do that."); + stage = 28; + break; + case 28: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Ok, I'll do my best."); + stage = 31; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "No, I'm not ready to do that."); + stage = 29; + break; + } + break; + case 29: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "Come see me again if you change your mind."); + stage = 30; + break; + case 30: + end(); + break; + case 31: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "Good luck! Let me know how you get on. Here's the", "dossier for the case, I've already given you the details."); + stage = 32; + break; + case 32: + if (player.getInventory().add(BlackKnightsFortress.DOSSIER)) { + quest.start(player); + } else { + player.getPacketDispatch().sendMessage("You don't have enough inventory space."); + } + end(); + break; + } + break; + default: + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 608 }; + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/falador/quest/doricsquest/DoricDoricsQuestDialogue.kt b/Server/src/main/content/region/asgarnia/falador/quest/doricsquest/DoricDoricsQuestDialogue.kt new file mode 100644 index 0000000..3c34fca --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/quest/doricsquest/DoricDoricsQuestDialogue.kt @@ -0,0 +1,79 @@ +package content.region.asgarnia.falador.quest.doricsquest + +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import content.data.Quests + +class DoricDoricsQuestDialogue(private val dStage: Int) : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when(dStage) { + 10 -> handleQuestStartDialogue(player, false) + 20 -> handleQuestStartDialogue(player, true) + 30 -> handleGiveDoricItemsDialogue(player) + } + } + + private fun handleQuestStartDialogue(player: Player?, isWhetstone: Boolean) { + player ?: return + when(stage) { + 0 -> { + if(!isWhetstone) { + npcl(FacialExpression.OLD_NORMAL, "My anvils get enough work with my own use. I make pickaxes, and it takes a lot of hard work. If you could get me some more materials, then I could let you use them.") + stage = 30 + } else { + npcl(FacialExpression.OLD_NORMAL, "The whetstone is for more advanced smithing, but I could let you use it as well as my anvils if you could get me some more materials.") + stage = 30 + } + } + 30 -> showTopics( + Topic(FacialExpression.FRIENDLY, "Yes I will get you the materials.", 40), + Topic(FacialExpression.HALF_GUILTY, "No, hitting rocks is for the boring people, sorry.", 100) + ) + // Yes, this has to be npc, not npcl + 40 -> npc(FacialExpression.OLD_NORMAL, "Clay is what I use more than anything, to make casts.", "Could you get me 6 clay, 4 copper ore, and 2 iron ore,", "please? I could pay a little, and let you use my anvils.", "Take this pickaxe with you just in case you need it.").also { stage++ } + 41 -> { + playerl(FacialExpression.FRIENDLY, "Certainly, I'll be right back!") + startQuest(player, Quests.DORICS_QUEST) + if(!inInventory(player, Items.BRONZE_PICKAXE_1265)) addItemOrDrop(player, Items.BRONZE_PICKAXE_1265) + stage = END_DIALOGUE + } + 100 -> npcl(FacialExpression.OLD_NORMAL, "That is your choice. Nice to meet you anyway.").also { stage = END_DIALOGUE } + } + } + + private fun handleGiveDoricItemsDialogue(player: Player?) { + player ?: return + when(stage) { + 0 -> npcl(FacialExpression.OLD_NORMAL, "Have you got my materials yet, traveller?").also { stage++ } + 1 -> { + if(inInventory(player, Items.CLAY_434, 6) && inInventory(player, Items.COPPER_ORE_436, 4) && inInventory(player, Items.IRON_ORE_440, 2)) { + playerl(FacialExpression.HAPPY, "I have everything you need.") + stage++ + } else { + playerl(FacialExpression.HALF_GUILTY, "Sorry, I don't have them all yet.") + stage = 50 + } + } + 2 -> npcl("Many thanks. Pass them here, please. I can spare you some coins for your trouble, and please use my anvils any time you want.").also { stage++ } + 3 -> { + if(removeItem(player, Item(Items.CLAY_434, 6)) && removeItem(player, Item(Items.COPPER_ORE_436, 4)) && removeItem(player, Item(Items.IRON_ORE_440, 2))) { + sendItemDialogue(player, Items.COPPER_ORE_436, "You hand the clay, copper, and iron to Doric.") + finishQuest(player, Quests.DORICS_QUEST) + stage = END_DIALOGUE + } + } + 50 -> npcl(FacialExpression.OLD_NORMAL, "Not to worry, stick at it. Remember, I need 6 clay, 4 copper ore, and 2 iron ore.").also { stage++ } + 51 -> showTopics( + Topic(FacialExpression.HALF_ASKING, "Where can I find those?", 52), + Topic(FacialExpression.HAPPY, "Certainly, I'll be right back.", END_DIALOGUE) + ) + 52 -> npcl(FacialExpression.OLD_NORMAL, "You'll be able to find all those ores in the rocks just inside the Dwarven Mine. Head east from here and you'll find the entrance in the side of Ice Mountain.").also { stage = END_DIALOGUE } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/falador/quest/doricsquest/DoricsQuest.kt b/Server/src/main/content/region/asgarnia/falador/quest/doricsquest/DoricsQuest.kt new file mode 100644 index 0000000..0bc49f1 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/quest/doricsquest/DoricsQuest.kt @@ -0,0 +1,64 @@ +package content.region.asgarnia.falador.quest.doricsquest + +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import org.rs09.consts.Components +import org.rs09.consts.Items +import content.data.Quests + +@Initializable +class DoricsQuest : Quest(Quests.DORICS_QUEST, 17, 16, 1, 31, 0, 1, 100) { + override fun newInstance(`object`: Any?): Quest { return this } + + override fun drawJournal(player: Player?, stage: Int) { + super.drawJournal(player, stage) + player ?: return + var line = 12 + if(stage == 0) { + line(player, "I can start this quest by speaking to !!Doric?? who is !!North of??", line++) + line(player, "!!Falador??.", line++) + line++ + line(player, "There aren't any requirements but !!Level 15 Mining?? will help.", line++) + } else { + if(stage in 1..99) { + // https://www.youtube.com/watch?v=vm4BEXtMoO0 + line(player, "I have spoken to Doric. He agreed to let me use his anvils", line++, true) + line(player, "if I bring him some materials.", line++, true) + line++ + line(player, "I need to collect the following materials and bring them all", line++) + line(player, "to !!Doric??:", line++) + line(player, "!!6 Clay.??", line++, inInventory(player, Items.CLAY_434, 6)) + line(player, "!!4 Copper Ore.??", line++, inInventory(player, Items.COPPER_ORE_436, 4)) + line(player, "!!2 Iron Ore.??", line++, inInventory(player, Items.IRON_ORE_440, 2)) + } + + if(stage == 100) { + line(player, "I have spoken to !!Doric??.", line++, true) + line(player, "I have collected some Clay, Copper Ore, and Iron Ore.", line++, true) + line(player, "Doric rewarded me for all my hard work.", line++, true) + line(player, "I can now use Doric's Anvils whenever I want.", line++, true) + line++ + line(player, "%%QUEST COMPLETE!&&", line++) + } + } + } + + override fun finish(player: Player?) { + super.finish(player) + player ?: return + var line = 10 + + sendItemZoomOnInterface(player, Components.QUEST_COMPLETE_SCROLL_277, 5, Items.STEEL_PICKAXE_1269) + drawReward(player, "1 Quest Point", line++) + drawReward(player, "1300 Mining XP", line++) + drawReward(player, "180 Coins", line++) + drawReward(player, "Use of Doric's Anvils", line++) + + rewardXP(player, Skills.MINING, 1300.0) + addItemOrDrop(player, Items.COINS_995, 180) + removeAttribute(player, "doric-angy-count") + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/AlchemicalNotes.kt b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/AlchemicalNotes.kt new file mode 100644 index 0000000..56eaa77 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/AlchemicalNotes.kt @@ -0,0 +1,248 @@ +package content.region.asgarnia.falador.quest.recruitmentdrive + +import content.global.handlers.iface.BookInterface +import content.global.handlers.iface.BookLine +import content.global.handlers.iface.Page +import content.global.handlers.iface.PageSet +import core.api.setAttribute +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items + +// https://www.youtube.com/watch?v=o-bAoxIYT-A 7:27 +@Initializable +class AlchemicalNotes : InteractionListener { + companion object { + private val TITLE = "Alchemical Reactions Study" + private val CONTENTS = arrayOf( + PageSet( + Page( + BookLine("Acetic acid and Cupric", 55), + BookLine("Sulphate:", 56), + BookLine("Endothermic.", 57), + BookLine("The Cupric is in ", 58), + BookLine("insufficient quantities to", 59), + BookLine("cause any noticeable", 60), + BookLine("reaction.", 61), + ), + Page( + BookLine("Acetic acid and Gypsum:", 66), + BookLine("Endothermic.", 67), + BookLine("Made a particularly bad", 68), + BookLine("smell, but little else that", 69), + BookLine("was productive.", 70), + ) + ), + PageSet( + Page( + BookLine("Acetic acid and Sodium", 55), + BookLine("Chloride:", 56), + BookLine("Endothermic.", 57), + BookLine("Very tasty when", 58), + BookLine("combined with fried", 59), + BookLine("potatoes at room", 60), + BookLine("temperature.", 61), + ), + Page( + BookLine("Acetic acid and", 66), + BookLine("Dihydrogen Monoxide:", 67), + BookLine("Endothermic.", 68), + BookLine("The Dihydrogen", 69), + BookLine("Monoxide served only to", 70), + BookLine("dilute the Acetic acid at", 71), + BookLine("room temperature.", 72), + ) + ), + PageSet( + Page( + BookLine("Acetic acid and Cupric", 55), + BookLine("Ore Powder:", 56), + BookLine("Endothermic.", 57), + BookLine("The powdered form of", 58), + BookLine("Cupric Ore allowed a", 59), + BookLine("lower than usual melting", 60), + BookLine("temperature, but the end", 61), + BookLine("product was non-usable.", 62), + ), + Page( + BookLine("Acetic acid and Tin Ore", 66), + BookLine("powder:", 67), + BookLine("Endothermic.", 68), + BookLine("Similar results to those", 69), + BookLine("made using Cupric Ore.", 70), + ) + ), + PageSet( + Page( + BookLine("Cupric Sulphate and", 55), + BookLine("Dihyrdogen Monoxide:", 56), + BookLine("Exothermic.", 57), + BookLine("A blue compound was", 58), + BookLine("produced, along with heat.", 59), + ), + Page( + BookLine("Cupric Sulphate and", 66), + BookLine("Gypsum:", 67), + BookLine("Endothermic.", 68), + BookLine("At room temperature, no", 69), + BookLine("useful product was", 70), + BookLine("created.", 71), + ) + ), + PageSet( + Page( + BookLine("Cupric Sulphate and", 55), + BookLine("Sodium Chloride:", 56), + BookLine("Endothermic.", 57), + BookLine("A pungent odour was", 58), + BookLine("released when combined.", 59), + ), + Page( + BookLine("Cupric Sulphate and", 66), + BookLine("Cupric Ore powder:", 67), + BookLine("Endothermic.", 68), + BookLine("The Cupric did not react", 69), + BookLine("with each other at room", 70), + BookLine("temperature.", 71), + ) + ), + PageSet( + Page( + BookLine("Cupric Sulphate and Tin", 55), + BookLine("Ore powder:", 56), + BookLine("Endothermic.", 57), + BookLine("Similar results to those", 58), + BookLine("shown with Cupric Ore,", 59), + BookLine("despite the increased", 60), + BookLine("solubility involved with", 61), + BookLine("the powdered form.", 62), + ), + Page( + BookLine("Gypsum and Dihydrogen", 66), + BookLine("Monoxide:", 67), + BookLine("Exothermic.", 68), + BookLine("A white liquid compound", 69), + BookLine("was formed, that quickly", 70), + BookLine("cooled at room", 71), + BookLine("temperature to a white", 72), + BookLine("heat resistant solid very", 73), + BookLine("similar to plaster.", 74), + BookLine("Heat was also produced,", 75), + BookLine("although not in the same", 76), + ) + ), + PageSet( + Page( + BookLine("quantity as Cupric", 55), + BookLine("Sulphate with Dihydrogen", 56), + BookLine("Monoxide", 57), + ), + Page( + BookLine("Gypsum and Sodium", 66), + BookLine("Chloride:", 67), + BookLine("Endothermic.", 68), + BookLine("The two did not seem to", 69), + BookLine("noticably mix together at", 70), + BookLine("room temperature.", 71), + ) + ), + PageSet( + Page( + BookLine("Gypsum and Culpric Ore:", 55), + BookLine("Endothermic.", 56), + BookLine("The gypsum seems quite", 57), + BookLine("resistant to most", 58), + BookLine("compounds at normal", 59), + BookLine("room temperature.", 60), + ), + Page( + BookLine("Gypsum and Tin Ore:", 66), + BookLine("Endothermic.", 67), + BookLine("Again, very similar results", 68), + BookLine("as those shown with", 69), + BookLine("Cupric Ore.", 70), + ) + ), + + PageSet( + Page( + BookLine("Sodium Chloride and", 55), + BookLine("Dihydrogen Monoxide:", 56), + BookLine("Endothermic.", 57), + BookLine("At room temperature, the", 58), + BookLine("Sodium Chloride dissolves", 59), + BookLine("quite easily. Dissolution is", 60), + BookLine("faster at higher", 61), + BookLine("temperatures.", 62), + ), + Page( + BookLine("Sodium Chloride and", 66), + BookLine("Cupric Ore:", 67), + BookLine("Endothermic.", 68), + BookLine("No visible combination at", 69), + BookLine("room temperature.", 70), + ) + ), + PageSet( + Page( + BookLine("Sodium Chloride and Tin", 55), + BookLine("Ore:", 56), + BookLine("Endothermic.", 57), + BookLine("Another very similar ", 58), + BookLine("result as with Cupric Ore.", 59), + ), + Page( + BookLine("Cupric Ore Powder and", 66), + BookLine("Tin Ore Powder:", 67), + BookLine("Endothermic.", 68), + BookLine("When both ores are in", 69), + BookLine("particulate form, a much", 70), + BookLine("lower than usual bonding", 71), + BookLine("temperature can be", 72), + BookLine("obtained.", 73), + BookLine("When combined at a", 74), + BookLine("moderate heat, (my", 75), + BookLine("laboratory heating", 76), + ) + ), + PageSet( + Page( + BookLine("apparatus) I was able to", 55), + BookLine("form liquid Bronze quite", 56), + BookLine("easily, which cooled to", 57), + BookLine("form a standard Bronze", 58), + BookLine("Bar at a temperature far", 60), + BookLine("lower than that required", 61), + BookLine("to produce in mass at a", 62), + BookLine("furnace.", 63), + ), + Page( + BookLine("Nitrous Monoxide:", 66), + BookLine("Was not able to perform", 67), + BookLine("an experimentation using", 68), + BookLine("this substance, as the", 69), + BookLine("gaseous form would", 70), + BookLine("always escape when the", 71), + BookLine("vial was opened.", 72), + ) + ) + ) + } + + private fun display(player:Player, pageNum: Int, buttonID: Int) : Boolean { + BookInterface.pageSetup(player, BookInterface.FANCY_BOOK_3_49, TITLE, CONTENTS) + return true + } + + + override fun defineListeners() { + on(Items.ALCHEMICAL_NOTES_5588, IntType.ITEM, "read") { player, _ -> + setAttribute(player, "bookInterfaceCallback", ::display) + setAttribute(player, "bookInterfaceCurrentPage", 0) + display(player, 0, 0) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/LadyTableDialogue.kt b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/LadyTableDialogue.kt new file mode 100644 index 0000000..b138626 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/LadyTableDialogue.kt @@ -0,0 +1,114 @@ +package content.region.asgarnia.falador.quest.recruitmentdrive + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.system.task.Pulse +import org.rs09.consts.Components +import org.rs09.consts.NPCs + +class LadyTableDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, LadyTableDialogueFile(), npc) + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return LadyTableDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.LADY_TABLE_2283) + } +} + +class LadyTableDialogueFile(private val dialogueNum: Int = 0) : DialogueBuilderFile(), InteractionListener { + companion object { + const val statueVarbit = 658 + const val attributeStatueStateNumber = "quest:recruitmentdrive-statuestatenumber" + val statueArray = intArrayOf(0, 7308, 7307, 7306, 7305, 7304, 7303, 7312, 7313, 7314, 7311, 7310, 7309) + } + + override fun defineListeners() { + + on(statueArray, IntType.SCENERY, "touch") { player, node -> + if( node.id == statueArray[getAttribute(player, attributeStatueStateNumber, 0)]) { + if (getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) == 0) { + setAttribute(player, RecruitmentDrive.attributeStagePassFailState, 1) + sendNPCDialogueLines(player, NPCs.LADY_TABLE_2283, FacialExpression.NEUTRAL, false, "Excellent work, @name.", "Please step through the portal to meet your next", "challenge.") + return@on true + } + } else { + if (getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) == 0) { + setAttribute(player, RecruitmentDrive.attributeStagePassFailState, -1) + openDialogue(player, LadyTableDialogueFile(2), NPC(NPCs.LADY_TABLE_2283)) + return@on true + } + } + if (getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) == 1) { + sendNPCDialogueLines(player, NPCs.LADY_TABLE_2283, FacialExpression.NEUTRAL, false, "Please step through the portal to meet your next", "challenge.") + } + if (getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) == -1) { + openDialogue(player, LadyTableDialogueFile(2), NPC(NPCs.LADY_TABLE_2283)) + } + return@on true + } + + } + override fun create(b: DialogueBuilder) { + b.onPredicate { player -> dialogueNum == 1 } + .endWith { _, player -> + submitWorldPulse(object : Pulse() { + var counter = 0 + override fun pulse(): Boolean { + when (counter++) { + 0 -> { + lock(player, 15) + setAttribute(player, attributeStatueStateNumber, (1..12).random()) + setVarbit(player, statueVarbit, getAttribute(player, attributeStatueStateNumber, 0)) + sendNPCDialogueLines(player, NPCs.LADY_TABLE_2283, FacialExpression.NEUTRAL, true,"Welcome, @name.", "This room will test your observation skills.") + } + 5 -> { + sendNPCDialogueLines(player, NPCs.LADY_TABLE_2283, FacialExpression.NEUTRAL, true, "Study the statues closely.", "There is one missing statue in this room.") + } + 10 -> { + sendNPCDialogueLines(player, NPCs.LADY_TABLE_2283, FacialExpression.NEUTRAL, true, "We will also mix the order up a little, to make things", "interesting for you!") + } + 15 -> { + sendNPCDialogueLines(player, NPCs.LADY_TABLE_2283, FacialExpression.NEUTRAL, true,"You have 10 seconds to memorise the statues... starting", "NOW!") + } + 20 -> { + closeDialogue(player) + } + 31 -> { // From 15 -> 16 * 600ms = 10 seconds + openOverlay(player,Components.FADE_TO_BLACK_120) + sendNPCDialogueLines(player, NPCs.LADY_TABLE_2283, FacialExpression.NEUTRAL, true,"We will now dim the lights and bring the missing statue", "back in.") + } + 34 -> { // From 15 -> 16 * 600ms = 10 seconds + setVarbit(player, statueVarbit, 0) + openOverlay(player,Components.FADE_FROM_BLACK_170) + sendNPCDialogueLines(player, NPCs.LADY_TABLE_2283, FacialExpression.NEUTRAL, true,"Please touch the statue you think has been added.") + return true + } + } + return false + } + }) + } + + b.onPredicate { player -> dialogueNum == 2 || (getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) == -1) } + .betweenStage { _, player, _, _ -> + setAttribute(player, RecruitmentDrive.attributeStagePassFailState, -1) + } + .npc(FacialExpression.SAD, "No... I am very sorry.", "Apparently you are not up to the challenge.", "I will return you where you came from, better luck in the", "future.") + .endWith { _, player -> + removeAttribute(player, attributeStatueStateNumber) + removeAttribute(player, RecruitmentDrive.attributeStagePassFailState) + RecruitmentDriveListeners.FailTestCutscene(player).start() + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/MissCheeversDialogue.kt b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/MissCheeversDialogue.kt new file mode 100644 index 0000000..21fed50 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/MissCheeversDialogue.kt @@ -0,0 +1,512 @@ +package content.region.asgarnia.falador.quest.recruitmentdrive + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.global.action.DoorActionHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +@Initializable +class MissCheeversDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, MissCheeversDialogueFile(), npc) + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return MissCheeversDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.MISS_CHEEVERS_2288) + } +} + +class MissCheeversDialogueFile(private val dialogueNum: Int = 0) : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onPredicate { _ -> dialogueNum == 0 } + .playerl(FacialExpression.FRIENDLY,"Can you give me any help?") + .npcl(FacialExpression.FRIENDLY,"No, I am sorry, but that is forbidden by our rules.") + .npcl(FacialExpression.FRIENDLY,"If you are having a particularly tough time of it, I suggest you leave and come back later when you are in a more receptive frame of mind.") + .npcl(FacialExpression.FRIENDLY,"Sometimes a break from concentration will yield fresh insight. Our aim is to test you, but not to the point of frustration!") + .playerl(FacialExpression.FRIENDLY,"Okay, thanks!") + .end() + + + b.onPredicate { _ -> dialogueNum == 1 } + .betweenStage { _, player, _, _ -> + setVarbit(player, MissCheeversRoomListeners.doorVarbit, 0) + removeAttribute(player, MissCheeversRoomListeners.attributebook) + removeAttribute(player, MissCheeversRoomListeners.attributemagnet) + removeAttribute(player, MissCheeversRoomListeners.attributeKnife) + removeAttribute(player, MissCheeversRoomListeners.attributeShears) + removeAttribute(player, MissCheeversRoomListeners.attributeTin) + removeAttribute(player, MissCheeversRoomListeners.attributeChisel) + removeAttribute(player, MissCheeversRoomListeners.attributeWire) + + removeAttribute(player, MissCheeversRoomListeners.attribute3VialsOfLiquid) + + MissCheeversRoomListeners.Companion.Vials.vialMap.map { + removeAttribute(player, it.value.attribute) + } + + MissCheeversRoomListeners.Companion.DoorVials.doorVialsRequiredMap.map { + removeAttribute(player, it.value.attribute) + } + } + .npcl(FacialExpression.FRIENDLY,"Greetings, @name. Welcome to my challenge.") + .npcl(FacialExpression.FRIENDLY,"All you need to do is leave from the opposite door to where you came in by.") + .npcl(FacialExpression.FRIENDLY,"I will warn you that this is more complicated than it may at first appear.") + .npcl(FacialExpression.FRIENDLY,"I should also warn you that there are limited supplies of the items in this room, so think carefully before using them, you may find yourself stuck and have to leave to start again!") + .npcl(FacialExpression.FRIENDLY,"Best of luck!") + .end() + } +} + +class MissCheeversRoomListeners : InteractionListener { + companion object { + + const val doorVarbit = 686 + + const val attributebook = "quest:recruitmentdrive-book" + const val attributemagnet = "quest:recruitmentdrive-magnet" + const val attributeKnife = "quest:recruitmentdrive-knife" + const val attributeShears = "quest:recruitmentdrive-shears" + const val attributeTin = "quest:recruitmentdrive-tin" + const val attributeChisel = "quest:recruitmentdrive-chisel" + const val attributeWire = "quest:recruitmentdrive-wire" + + const val attribute3VialsOfLiquid = "quest:recruitmentdrive-3vialsofliquid" + + /** Enums to map canoes to related properties. */ + enum class Vials(val itemId: Int, val attribute: String) { + CUPRIC_SULPHATE_5577(Items.CUPRIC_SULPHATE_5577, "quest:recruitmentdrive-cupricsulphate"), + ACETIC_ACID_5578(Items.ACETIC_ACID_5578, "quest:recruitmentdrive-aceticacid"), + GYPSUM_5579(Items.GYPSUM_5579, "quest:recruitmentdrive-gypsum"), + SODIUM_CHLORIDE_5580(Items.SODIUM_CHLORIDE_5580, "quest:recruitmentdrive-sodiumchloride"), + NITROUS_OXIDE_5581(Items.NITROUS_OXIDE_5581, "quest:recruitmentdrive-nitrousoxide"), + VIAL_OF_LIQUID_5582(Items.VIAL_OF_LIQUID_5582, "quest:recruitmentdrive-vialofliquid"), + TIN_ORE_POWDER_5583(Items.TIN_ORE_POWDER_5583, "quest:recruitmentdrive-tinorepowder"), + CUPRIC_ORE_POWDER_5584(Items.CUPRIC_ORE_POWDER_5584, "quest:recruitmentdrive-cupricorepowder"); + + companion object { + @JvmField + val vialMap = Vials.values().associateBy { it.itemId } + } + } + + + /** Enums to map canoes to related properties. */ + enum class DoorVials(val itemId: Int, val attribute: String) { + CUPRIC_SULPHATE_5577(Items.CUPRIC_SULPHATE_5577, "quest:recruitmentdrive-doorcupricsulphate"), + ACETIC_ACID_5578(Items.ACETIC_ACID_5578, ""), + SODIUM_CHLORIDE_5580(Items.SODIUM_CHLORIDE_5580, ""), + VIAL_OF_LIQUID_5582(Items.VIAL_OF_LIQUID_5582, "quest:recruitmentdrive-doorvialofliquid"); + + companion object { + @JvmField + val doorVialsArray = DoorVials.values().map { it.itemId }.toIntArray() + val doorVialsMap = DoorVials.values().associateBy { it.itemId } + val doorVialsRequiredMap = DoorVials.values().associateBy { it.itemId }.filter { it.value.attribute != "" } + } + } + + + fun searchingHelper(player: Player, attributeCheck: String, item: Int, searchingDescription: String, objectDescription: String) { + queueScript(player, 0, QueueStrength.WEAK) { stage: Int -> + when (stage) { + 0 -> { + sendMessage(player, searchingDescription) + return@queueScript delayScript(player, 2) + } + 1 -> { + if (attributeCheck != "" && !getAttribute(player, attributeCheck, false)) { + setAttribute(player, attributeCheck, true) + addItem(player, item) + sendMessage(player, objectDescription) + } else { + sendMessage(player, "You don't find anything interesting.") + } + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + } + } + + override fun defineListeners() { + + /** Obtainable Items */ + + on(Scenery.OLD_BOOKSHELF_7327, IntType.SCENERY, "search") { player, _ -> + searchingHelper(player, attributemagnet, Items.MAGNET_5604, "You search the bookshelves...", "Hidden amongst the books you find a magnet.") + return@on true + } + + on(Scenery.OLD_BOOKSHELF_7328, IntType.SCENERY, "search") { player, _ -> + searchingHelper(player, attributebook, Items.ALCHEMICAL_NOTES_5588, "You search the bookshelves...", "You find a book that looks like it might be helpful.") + return@on true + } + + on(Scenery.OLD_BOOKSHELF_7329, IntType.SCENERY, "search") { player, _ -> + searchingHelper(player, attributeKnife, Items.KNIFE_5605, "You search the bookshelves...", "Hidden amongst the books you find a knife.") + return@on true + } + + on(Scenery.OLD_BOOKSHELF_7330, IntType.SCENERY, "search") { player, _ -> + searchingHelper(player, "", 0, "You search the bookshelves...", "") + return@on true + } + + on(Scenery.SHELVES_7333, IntType.SCENERY, "search") { player, _ -> + val vialList = ArrayList() + if (!getAttribute(player, Vials.vialMap[Items.ACETIC_ACID_5578]!!.attribute, false)) { vialList.add(Items.ACETIC_ACID_5578) } + if (!getAttribute(player, Vials.vialMap[Items.VIAL_OF_LIQUID_5582]!!.attribute, false)) { vialList.add(Items.VIAL_OF_LIQUID_5582) } + openDialogue(player, VialShelfDialogueFile(vialList.toIntArray())) + return@on true + } + + on(Scenery.SHELVES_7334, IntType.SCENERY, "search") { player, _ -> + val vialList = ArrayList() + if (!getAttribute(player, Vials.vialMap[Items.CUPRIC_SULPHATE_5577]!!.attribute, false)) { vialList.add(Items.CUPRIC_SULPHATE_5577) } + openDialogue(player, VialShelfDialogueFile(vialList.toIntArray())) + return@on true + } + + on(Scenery.SHELVES_7335, IntType.SCENERY, "search") { player, _ -> + val vialList = ArrayList() + if (!getAttribute(player, Vials.vialMap[Items.GYPSUM_5579]!!.attribute, false)) { vialList.add(Items.GYPSUM_5579) } + openDialogue(player, VialShelfDialogueFile(vialList.toIntArray())) + return@on true + } + + on(Scenery.SHELVES_7336, IntType.SCENERY, "search") { player, _ -> + val vialList = ArrayList() + if (!getAttribute(player, Vials.vialMap[Items.SODIUM_CHLORIDE_5580]!!.attribute, false)) { vialList.add(Items.SODIUM_CHLORIDE_5580) } + openDialogue(player, VialShelfDialogueFile(vialList.toIntArray())) + return@on true + } + + on(Scenery.SHELVES_7337, IntType.SCENERY, "search") { player, _ -> + val vialList = ArrayList() + if (!getAttribute(player, Vials.vialMap[Items.NITROUS_OXIDE_5581]!!.attribute, false)) { vialList.add(Items.NITROUS_OXIDE_5581) } + openDialogue(player, VialShelfDialogueFile(vialList.toIntArray())) + return@on true + } + + on(Scenery.SHELVES_7338, IntType.SCENERY, "search") { player, _ -> + val vialList = ArrayList() + if (!getAttribute(player, Vials.vialMap[Items.TIN_ORE_POWDER_5583]!!.attribute, false)) { vialList.add(Items.TIN_ORE_POWDER_5583) } + openDialogue(player, VialShelfDialogueFile(vialList.toIntArray())) + return@on true + } + + on(Scenery.SHELVES_7339, IntType.SCENERY, "search") { player, _ -> + val vialList = ArrayList() + if (!getAttribute(player, Vials.vialMap[Items.CUPRIC_ORE_POWDER_5584]!!.attribute, false)) { vialList.add(Items.CUPRIC_ORE_POWDER_5584) } + openDialogue(player, VialShelfDialogueFile(vialList.toIntArray())) + return@on true + } + + on(Scenery.SHELVES_7340, IntType.SCENERY, "search") { player, _ -> + val vialList = ArrayList() + val total = getAttribute(player, attribute3VialsOfLiquid, 3) + for (i in 1..total) { vialList.add(Items.VIAL_OF_LIQUID_5582) } + openDialogue(player, VialShelfDialogueFile(vialList.toIntArray(), attribute3VialsOfLiquid)) + return@on true + } + + on(Scenery.CRATE_7347, IntType.SCENERY, "search") { player, node -> + if (node.location == Location(2476, 4943)) { + searchingHelper(player, attributeTin, Items.TIN_5600, "You search the crate...", "Inside the crate you find a tin.") + } else { + searchingHelper(player, "", 0, "You search the crate...", "") + } + return@on true + } + + on(Scenery.CRATE_7348, IntType.SCENERY, "search") { player, node -> + if (node.location == Location(2476, 4937)) { + searchingHelper(player, attributeChisel, Items.CHISEL_5601, "You search the crate...", "Inside the crate you find a chisel.") + } else { + searchingHelper(player, "", 0, "You search the crate...", "") + } + return@on true + } + + on(Scenery.CRATE_7349, IntType.SCENERY, "search") { player, node -> + if (node.location == Location(2475, 4943)) { + searchingHelper(player, attributeWire, Items.BRONZE_WIRE_5602, "You search the crate...", "Inside the crate you find some wire.") + } else { + searchingHelper(player, "", 0, "You search the crate...", "") + } + return@on true + } + + on(Scenery.CLOSED_CHEST_7350, IntType.SCENERY, "open") { player, node -> + replaceScenery(node as core.game.node.scenery.Scenery, Scenery.OPEN_CHEST_7351, 100) + return@on true + } + + on(Scenery.OPEN_CHEST_7351, IntType.SCENERY, "search") { player, _ -> + searchingHelper(player, attributeShears, Items.SHEARS_5603, "You search the chest...", "Inside the chest you find some shears.") + return@on true + } + + on(Scenery.OPEN_CHEST_7351, IntType.SCENERY, "close") { player, node -> + replaceScenery(node as core.game.node.scenery.Scenery, Scenery.CLOSED_CHEST_7350, -1) + return@on true + } + + /** Combining Items the correct way */ + + onUseWith(ITEM, Items.TIN_5600, Items.GYPSUM_5579) { player, used, with -> + if(removeItem(player, used.id) && removeItem(player, with.id)) { + sendMessage(player, "You empty the vial into the tin.") + addItemOrDrop(player, Items.TIN_5592) + addItemOrDrop(player, Items.VIAL_229) + } + return@onUseWith true + } + + onUseWith(ITEM, Items.TIN_5592, Items.VIAL_OF_LIQUID_5582) { player, used, with -> + if(removeItem(player, used.id) && removeItem(player, with.id)) { + sendMessage(player, "You empty the vial into the tin.") + sendMessage(player, "You notice the tin gets quite warm as you do this.") + sendMessage(player, "A lumpy white mixture is made, that seems to be hardening.") + addItemOrDrop(player, Items.TIN_5593) + addItemOrDrop(player, Items.VIAL_229) + } + return@onUseWith true + } + + onUseWith(SCENERY, Items.TIN_5593, Scenery.KEY_7346) { player, used, _ -> + if(removeItem(player, used.id)) { + sendMessage(player, "You make an impression of the key as the white mixture hardens.") + addItemOrDrop(player, Items.TIN_5594) + } + return@onUseWith true + } + + onUseWith(ITEM, Items.TIN_5594, Items.TIN_ORE_POWDER_5583) { player, used, with -> + if(removeItem(player, used.id) && removeItem(player, with.id)) { + sendMessage(player, "You pour the vial into the impression of the key.") + addItemOrDrop(player, Items.TIN_5595) + addItemOrDrop(player, Items.VIAL_229) + } + return@onUseWith true + } + + onUseWith(ITEM, Items.TIN_5595, Items.CUPRIC_ORE_POWDER_5584) { player, used, with -> + if(removeItem(player, used.id) && removeItem(player, with.id)) { + sendMessage(player, "You pour the vial into the impression of the key.") + addItemOrDrop(player, Items.TIN_5597) + addItemOrDrop(player, Items.VIAL_229) + } + return@onUseWith true + } + + onUseWith(ITEM, Items.TIN_5594, Items.CUPRIC_ORE_POWDER_5584) { player, used, with -> + if(removeItem(player, used.id) && removeItem(player, with.id)) { + sendMessage(player, "You pour the vial into the impression of the key.") + addItemOrDrop(player, Items.TIN_5596) + addItemOrDrop(player, Items.VIAL_229) + } + return@onUseWith true + } + + onUseWith(ITEM, Items.TIN_5596, Items.TIN_ORE_POWDER_5583) { player, used, with -> + if(removeItem(player, used.id) && removeItem(player, with.id)) { + sendMessage(player, "You pour the vial into the impression of the key.") + addItemOrDrop(player, Items.TIN_5597) + addItemOrDrop(player, Items.VIAL_229) + } + return@onUseWith true + } + + onUseWith(SCENERY, Items.TIN_5597, Scenery.BUNSEN_BURNER_7332) { player, used, _ -> + if(removeItem(player, used.id)) { + sendMessage(player, "You heat the two powdered ores together in the tin.") + sendMessage(player, "You make a duplicate of the key in bronze.") + addItemOrDrop(player, Items.TIN_5598) + } + return@onUseWith true + } + + onUseWith(ITEM, Items.TIN_5598, Items.BRONZE_WIRE_5602, Items.CHISEL_5601, Items.KNIFE_5605) { player, used, with -> + if(removeItem(player, used.id)) { + sendMessage(player, "You prise the duplicate key out of the tin.") + addItemOrDrop(player, Items.TIN_5594) + addItemOrDrop(player, Items.BRONZE_KEY_5585) + } + return@onUseWith true + } + + onUseWith(SCENERY, Items.METAL_SPADE_5586, Scenery.BUNSEN_BURNER_7332) { player, used, _ -> + if(removeItem(player, used.id)) { + sendMessage(player, "You burn the wooden handle away from the spade...") + sendMessage(player, "...and are left with a metal spade with no handle.") + addItemOrDrop(player, Items.ASHES_592) + addItemOrDrop(player, Items.METAL_SPADE_5587) + } + return@onUseWith true + } + + + on(Scenery.STONE_DOOR_7343, SCENERY, "study") { player, node -> + sendDialogueLines(player, "There is a stone slab here obstructing the door.", "There is a small hole in the slab that looks like it might be for a handle.") + sendMessage(player, "It's nearly a perfect fit!") + return@on true + } + + onUseWith(SCENERY, Items.METAL_SPADE_5587, Scenery.STONE_DOOR_7343) { player, used, _ -> + if(removeItem(player, used.id)) { + sendMessage(player, "You slide the spade into the hole in the stone...") + sendMessage(player, "It's nearly a perfect fit!") + setVarbit(player, doorVarbit, 1) + } + return@onUseWith true + } + + onUseWith(SCENERY, DoorVials.doorVialsArray, Scenery.STONE_DOOR_7344) { player, used, _ -> + if(removeItem(player, used.id)) { + setAttribute(player, DoorVials.doorVialsMap[used.id]!!.attribute, true) + sendMessage(player, "You pour the vial onto the flat part of the spade.") + } + if (DoorVials.doorVialsRequiredMap.all { getAttribute(player, it.value.attribute, false) }) { + sendMessage(player, "Something caused a reaction when mixed!") + sendMessage(player, "The spade gets hotter, and expands slightly.") + setVarbit(player, doorVarbit, 2) + } + return@onUseWith true + } + + on(Scenery.STONE_DOOR_7344, SCENERY, "pull-spade") { player, node -> + if (DoorVials.doorVialsRequiredMap.all { getAttribute(player, it.value.attribute, false) }) { + sendMessage(player, "You pull on the spade...") + sendMessage(player, "It works as a handle, and you swing the stone door open.") + setVarbit(player, doorVarbit, 3) + } else { + sendMessage(player, "You pull on the spade...") + sendMessage(player, "It comes loose, and slides out of the hole in the stone.") + addItemOrDrop(player, Items.METAL_SPADE_5587) + setVarbit(player, doorVarbit, 0) + } + return@on true + } + + on(Scenery.OPEN_DOOR_7345, SCENERY, "walk-through") { player, node -> + if(player.location.x <= 2477) { + player.walkingQueue.addPath(2477, 4940) + player.walkingQueue.addPath(2478, 4940) + } else { + player.walkingQueue.addPath(2477, 4940) + } + return@on true + } + + + } + +} + +private class VialShelfDialogueFile(private val flaskIdsArray: IntArray, private val specialAttribute: String? = null) : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onPredicate { _ -> true }.branch { _ -> flaskIdsArray.size }.let { branch -> + + branch.onValue(3) + // This is the only shelf with 3 vials of water. + .line("There are three vials on this shelf.") + .options("Take the vials?").let { optionBuilder -> + optionBuilder.option("Take one vial.") + .endWith { _, player -> + addItemOrDrop(player, flaskIdsArray[0]) + if (specialAttribute != null) { + setAttribute(player, specialAttribute, getAttribute(player, specialAttribute, 3) - 1) + print(getAttribute(player, specialAttribute, 3)) + } + } + optionBuilder.option("Take two vials.") + .endWith { _, player -> + addItemOrDrop(player, flaskIdsArray[0]) + addItemOrDrop(player, flaskIdsArray[1]) + if (specialAttribute != null) { + setAttribute(player, specialAttribute, getAttribute(player, specialAttribute, 3) - 2) + } + } + optionBuilder.option("Take all three vials.") + .endWith { _, player -> + addItemOrDrop(player, flaskIdsArray[0]) + addItemOrDrop(player, flaskIdsArray[1]) + addItemOrDrop(player, flaskIdsArray[2]) + if (specialAttribute != null) { + setAttribute(player, specialAttribute, getAttribute(player, specialAttribute, 3) - 3) + } + } + optionBuilder.option("Don't take a vial.") + .end() + } + branch.onValue(2) + .line("There are two vials on this shelf.") + .options("Take the vials?").let { optionBuilder -> + optionBuilder.option("Take the first vial.") + .endWith { _, player -> + addItemOrDrop(player, flaskIdsArray[0]) + if (specialAttribute != null) { + setAttribute(player, specialAttribute, getAttribute(player, specialAttribute, 2) - 1) + } else { + setAttribute(player, MissCheeversRoomListeners.Companion.Vials.vialMap[flaskIdsArray[0]]!!.attribute, true) + } + } + optionBuilder.option("Take the second vial.") + .endWith { _, player -> + addItemOrDrop(player, flaskIdsArray[1]) + if (specialAttribute != null) { + setAttribute(player, specialAttribute, getAttribute(player, specialAttribute, 2) - 1) + } else { + setAttribute(player, MissCheeversRoomListeners.Companion.Vials.vialMap[flaskIdsArray[1]]!!.attribute, true) + } + } + optionBuilder.option("Take both vials.") + .endWith { _, player -> + addItemOrDrop(player, flaskIdsArray[0]) + addItemOrDrop(player, flaskIdsArray[1]) + if (specialAttribute != null) { + setAttribute(player, specialAttribute, getAttribute(player, specialAttribute, 2) - 2) + } else { + setAttribute(player, MissCheeversRoomListeners.Companion.Vials.vialMap[flaskIdsArray[0]]!!.attribute, true) + setAttribute(player, MissCheeversRoomListeners.Companion.Vials.vialMap[flaskIdsArray[1]]!!.attribute, true) + } + } + } + + branch.onValue(1) + .line("There is a vial on this shelf.") + .options("Take the vial?").let { optionBuilder -> + optionBuilder.option("YES") + .endWith { _, player -> + addItemOrDrop(player, flaskIdsArray[0]) + if (specialAttribute != null) { + setAttribute(player, specialAttribute, getAttribute(player, specialAttribute, 1) - 1) + } else { + setAttribute(player, MissCheeversRoomListeners.Companion.Vials.vialMap[flaskIdsArray[0]]!!.attribute, true) + } + } + optionBuilder.option("NO") + .end() + } + + branch.onValue(0) + .line("There is nothing of interest on these shelves.") + } + } +} diff --git a/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/MsHynnTerprettDialogue.kt b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/MsHynnTerprettDialogue.kt new file mode 100644 index 0000000..91be2f7 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/MsHynnTerprettDialogue.kt @@ -0,0 +1,154 @@ +package content.region.asgarnia.falador.quest.recruitmentdrive + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class MsHynnTerprettDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, MsHynnTerprettDialogueFile(), npc) + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return MsHynnTerprettDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.MS_HYNN_TERPRETT_2289) + } +} + +class MsHynnTerprettDialogueFile(private val dialogueNum: Int = 0) : DialogueBuilderFile() { + companion object { + const val attributeRandomRiddle = "quest:recruitmentdrive-randomriddle" + const val attributeRecentlyCorrect = "quest:recruitmentdrive-recentlycorrect" + } + + override fun create(b: DialogueBuilder) { + + b.onPredicate { player -> true }.branch { player -> + if (getAttribute(player, attributeRecentlyCorrect, false)) { + return@branch 3 + } else if (getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) == -1) { + return@branch 2 + } else if (getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) == 1) { + return@branch 1 + } else { + return@branch 0 + } + }.let { branch -> + /** Failed Branch */ + val failedStage = b.placeholder() + failedStage.builder() + .npc(FacialExpression.SAD, "No... I am very sorry.", "Apparently you are not up to the challenge.", "I will return you where you came from, better luck in the", "future.") + .endWith { _, player -> + removeAttribute(player, attributeRandomRiddle) + removeAttribute(player, attributeRecentlyCorrect) + removeAttribute(player, RecruitmentDrive.attributeStagePassFailState) + RecruitmentDriveListeners.FailTestCutscene(player).start() + } + /** Passed Branch */ + val passedStage = b.placeholder() + passedStage.builder() + .betweenStage { _, player, _, _ -> + removeAttribute(player, attributeRandomRiddle) + removeAttribute(player, attributeRecentlyCorrect) + if (getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) == 0) { + setAttribute(player, RecruitmentDrive.attributeStagePassFailState, 1) + } + } + .npc("Excellent work, @name.", "Please step through the portal to meet your next", "challenge.") + .end() + + branch.onValue(3) // Passed stage + .goto(passedStage) + branch.onValue(2) // Failed stage + .goto(failedStage) + branch.onValue(1) // Already passed stage + .npc("You certainly have the wits to be a Temple Knight.", "Pass on through the portal to find your next challenge.") + .end() + branch.onValue(0) + .betweenStage { _, player, _, _ -> + if (getAttribute(player, attributeRandomRiddle, -1) !in 0..4) { + setAttribute(player, attributeRandomRiddle, (0..4).random()) + } + } + .npc("Greetings, @name.", "I am here to test your wits with a simple riddle.") + .branch { player -> getAttribute(player, attributeRandomRiddle, 0) } + .let { branch -> + branch.onValue(0) + .npc(FacialExpression.THINKING, "Here is my riddle:", "I estimate there to be one million inhabitants in the world", "of @servername, creatures and people both.") + .npc(FacialExpression.THINKING, "What number would you get if you multiply", "the number of fingers on everything's left hand, to the", "nearest million?") + .manualStage { _, player, _, _ -> + sendInputDialogue(player, false, "Enter the amount:") { value: Any -> + if(value == "0") { + setAttribute(player, attributeRecentlyCorrect, true) + } else { + setAttribute(player, RecruitmentDrive.attributeStagePassFailState, -1) + } + openDialogue(player, MsHynnTerprettDialogueFile(), NPC(NPCs.MS_HYNN_TERPRETT_2289)) + return@sendInputDialogue + } + } + .end() + + branch.onValue(1) + .npc(FacialExpression.THINKING, "Here is my riddle:", "Which of the following statements is true?") + .options().let { optionBuilder -> + optionBuilder.option("The number of false statements here is one.").goto(failedStage) + optionBuilder.option("The number of false statements here is two.").goto(failedStage) + optionBuilder.option("The number of false statements here is three.").goto(passedStage) + optionBuilder.option("The number of false statements here is four.").goto(failedStage) + } + + branch.onValue(2) + .npc(FacialExpression.THINKING, "Here is my riddle:", "I have both a husband and daughter.") + .npc(FacialExpression.THINKING, "My husband is four times older than my daughter. ", "In twenty years time, he will be twice as old as my", "daughter.") + .npc(FacialExpression.THINKING, "How old is my daughter now?") + .manualStage { _, player, _, _ -> + sendInputDialogue(player, true, "Enter the amount:") { value: Any -> + if(value == 10) { + setAttribute(player, attributeRecentlyCorrect, true) + } else { + setAttribute(player, RecruitmentDrive.attributeStagePassFailState, -1) + } + openDialogue(player, MsHynnTerprettDialogueFile(), NPC(NPCs.MS_HYNN_TERPRETT_2289)) + return@sendInputDialogue + } + } + .end() + + branch.onValue(3) + .npc(FacialExpression.THINKING, "Here is my riddle:", "Imagine that you have been captured by an enemy.", "You are to be killed, but in a moment of mercy, the", "enemy has allowed you to pick your own demise.") + .npc(FacialExpression.THINKING, "Your first choice is to be drowned in a lake of acid.") + .npc(FacialExpression.THINKING, "Your second choice is to be burned on a fire.") + .npc(FacialExpression.THINKING, "Your third choice is to be thrown to a pack of wolves", "that have not been fed in over a month.") + .npc(FacialExpression.THINKING, "Your final choice of fate is to be thrown from the walls", "of a castle, many hundreds of feet high.") + .npc(FacialExpression.THINKING, "Which fate would you be wise to choose?") + .options().let { optionBuilder -> + optionBuilder.option("The lake of acid.").goto(failedStage) + optionBuilder.option("The large fire.").goto(failedStage) + optionBuilder.option("The wolves.").goto(passedStage) + optionBuilder.option("The castle walls.").goto(failedStage) + } + + branch.onValue(4) + .npc(FacialExpression.THINKING, "Here is my riddle:", "I dropped four identical stones, into four identical", "buckets, each containing an identical amount of water.") + .npc(FacialExpression.THINKING, "The first bucket's water was at 32 degrees Fahrenheit,", "the second was at 33 degrees, the third at 34 and the", "fourth was at 35 degrees.") + .npc(FacialExpression.THINKING, "Which bucket's stone dropped to the bottom of the bucket", "last?") + .options().let { optionBuilder -> + optionBuilder.option("Bucket A (32 degrees)").goto(passedStage) + optionBuilder.option("Bucket B (33 degrees)").goto(failedStage) + optionBuilder.option("Bucket C (34 degrees)").goto(failedStage) + optionBuilder.option("Bucket D (35 degrees)").goto(failedStage) + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/RecruitmentDrive.kt b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/RecruitmentDrive.kt new file mode 100644 index 0000000..7092567 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/RecruitmentDrive.kt @@ -0,0 +1,135 @@ +package content.region.asgarnia.falador.quest.recruitmentdrive + +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import org.rs09.consts.Items +import content.data.Quests + +/** + * Recruitment Drive Quest + * + * https://www.youtube.com/watch?v=0yvFREeXNn0 - Quest start log only. + * https://www.youtube.com/watch?v=lNlSiUvPL1o - Very good + * https://www.youtube.com/watch?v=OGWpX1WqpKM 10:12 - Final congrats page. + * https://www.youtube.com/watch?v=nu4OAswRcGg - Speaking to Tiffy after the quest (IMPORTANT!) + * https://www.youtube.com/watch?v=srFMJa4nuX0 1:47 blur ass quest log again + * https://www.youtube.com/watch?v=L7NdDTWa-1Q HAZEEL's CULT + * 1 - Speak to Sir Amik Varze. + * 2 - Sent to secret training ground. + * 3 - Finish all stages. + * 100 - Finish by talking to Tiffy. + */ +@Initializable +class RecruitmentDrive : Quest(Quests.RECRUITMENT_DRIVE, 103, 102, 1, 496, 0, 1, 2) { + companion object { + const val attributeOriginalGender = "/save:quest:recruitmentdrive-originalgender" + + // Stage state: (0: reset), (1: passed), (-1: failed) + const val attributeStagePassFailState = "/save:quest:recruitmentdrive-stagestate" + const val attributeCurrentStage = "/save:quest:recruitmentdrive-currentstage" + const val attributeStage1 = "/save:quest:recruitmentdrive-stage1" + const val attributeStage2 = "/save:quest:recruitmentdrive-stage2" + const val attributeStage3 = "/save:quest:recruitmentdrive-stage3" + const val attributeStage4 = "/save:quest:recruitmentdrive-stage4" + const val attributeStage5 = "/save:quest:recruitmentdrive-stage5" + val attributeStageArray = arrayOf(attributeStage1, attributeStage2, attributeStage3, attributeStage4, attributeStage5) + } + + override fun drawJournal(player: Player, stage: Int) { + super.drawJournal(player, stage) + var line = 12 + var stage = getStage(player) + + var started = getQuestStage(player, Quests.RECRUITMENT_DRIVE) > 0 + + if(!started){ + line(player, "I can start this quest by speaking to !!Sir Amik Varze??,", line++) + line(player, "upstairs in !!Falador Castle,??", line++) + if (isQuestComplete(player, Quests.DRUIDIC_RITUAL)) { + line(player, "with the Druidic Ritual Quest completed,", line++, true) + } else { + line(player, "with the !!Druidic Ritual Quest?? completed,", line++) + } + if (isQuestComplete(player, Quests.BLACK_KNIGHTS_FORTRESS)) { + line(player, "and since I have completed the Black Knights' Fortress", line++, true) + line(player, "Quest.", line++, true) + } else { + line(player, "and after I have completed the !!Black Knights' Fortress??", line++) + line(player, "Quest.", line++) + } + } else { + line(player, "Sir Amik Varze told me that he had put my name forward as", line++, true) + line(player, "a potential member of some mysterious organisation.", line++, true) + + if (stage >= 2) { + } else if (stage >= 1) { + line(player, "I should head to !!Falador Park?? to meet my !!Contact?? so that I", line++, false) + line(player, "can begin my !!testing for the job??", line++, false) + } + + if (stage >= 3) { + line(player, "I went to Falador Park, and met a strange old man named", line++, true) + line(player, "Tiffy.", line++, true) + line(player, "He sent me to a secret training ground, where my wits", line++, true) + line(player, "were thoroughly tested.", line++, true) + line(player, "Luckily, I was too smart to fall for any of their little tricks,", line++, true) + line(player, "and passed the test with flying colours.", line++, true) + } else if (stage >= 2) { + // http://youtu.be/Otc7ATq3tik 4:17 - I guess this is why no one opens their quest log + line(player, "A man named !!Tiffy?? brought me !!here, to the secret training??", line++, false) + line(player, "!!grounds?? so that I could be tested for the job.", line++, false) + line++ + line(player, "I should !!work out?? what I am supposed to do to complete", line++, false) + line(player, "these rooms...", line++, false) + } + + if (stage >= 4) { + line(player, "I am now an official member of the Temple Knights,", line++, true) + line(player, "although I have to wait for the paperwork to go through", line++, true) + line(player, "before I can commence working for them.", line++, true) + } else if (stage >= 3) { + line(player, "I should talk to !!Tiffy?? to become a Temple Knight.", line++, false) + } + if (stage >= 100) { + line++ + line(player,"QUEST COMPLETE!", line) + } + } + } + + override fun reset(player: Player) { + removeAttribute(player, attributeOriginalGender) + removeAttribute(player, attributeStagePassFailState) + removeAttribute(player, attributeCurrentStage) + removeAttribute(player, attributeStage1) + removeAttribute(player, attributeStage2) + removeAttribute(player, attributeStage3) + removeAttribute(player, attributeStage4) + removeAttribute(player, attributeStage5) + } + + override fun finish(player: Player) { + var ln = 10 + super.finish(player) + player.packetDispatch.sendString("You have passed the Recruitment Drive!", 277, 4) + player.packetDispatch.sendItemZoomOnInterface(Items.INITIATE_SALLET_5574, 230, 277, 5) + + drawReward(player, "1 Quest Point", ln++) + drawReward(player, "1000 Prayer, Herblore and", ln++) + drawReward(player, "Agility XP", ln++) + drawReward(player, "Gaze of Saradomin", ln++) + drawReward(player, "Temple Knight's Initiate Helm", ln) + + rewardXP(player, Skills.PRAYER, 1000.0) + rewardXP(player, Skills.HERBLORE, 1000.0) + rewardXP(player, Skills.AGILITY, 1000.0) + addItem(player, Items.INITIATE_SALLET_5574) + } + + override fun newInstance(`object`: Any?): Quest { + return this + } +} diff --git a/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/RecruitmentDriveListeners.kt b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/RecruitmentDriveListeners.kt new file mode 100644 index 0000000..39afdf1 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/RecruitmentDriveListeners.kt @@ -0,0 +1,316 @@ +package content.region.asgarnia.falador.quest.recruitmentdrive + +import content.data.Quests +import core.api.* +import core.game.activity.Cutscene +import core.game.dialogue.FacialExpression +import core.game.global.action.DoorActionHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import core.game.world.map.zone.ZoneRestriction +import core.net.packet.PacketRepository +import core.net.packet.context.MinimapStateContext +import core.net.packet.out.MinimapState +import org.rs09.consts.* + +class RecruitmentDriveListeners : InteractionListener { + companion object { + + enum class Stages(val npc: Int, val startLocation: Location, val startWalkLocation: Location, val quitPortal: Int, val successDoor: Int) { + SIR_SPISHYUS(NPCs.SIR_SPISHYUS_2282, Location(2490, 4972), Location(2489, 4972), Scenery.PORTAL_7272, Scenery.DOOR_7274), + LADY_TABLE(NPCs.LADY_TABLE_2283, Location(2460, 4979), Location(2459, 4979), Scenery.PORTAL_7288, Scenery.DOOR_7302), + SIR_KUAM_FERENTSE(NPCs.SIR_KUAM_FERENTSE_2284, Location(2455, 4964), Location(2456, 4964), Scenery.PORTAL_7315, Scenery.DOOR_7317), + SIR_TINLEY(NPCs.SIR_TINLEY_2286, Location(2471, 4956), Location(2472, 4956), Scenery.PORTAL_7318, Scenery.DOOR_7320), + SIR_REN_ITCHOOD(NPCs.SIR_REN_ITCHOOD_2287, Location(2439, 4956), Location(2440, 4956), Scenery.PORTAL_7321, Scenery.DOOR_7323), + MISS_CHEEVERS(NPCs.MISS_CHEEVERS_2288, Location(2467, 4940), Location(2468, 4940), Scenery.PORTAL_7324, Scenery.DOOR_7326), + MS_HYNN_TERPRETT(NPCs.MS_HYNN_TERPRETT_2289, Location(2451, 4935), Location(2451, 4936), Scenery.PORTAL_7352, Scenery.DOOR_7354); + + companion object { + @JvmField + val indexMap = Stages.values().associateBy { it.ordinal } + val indexArray = Stages.indexMap.keys.map { it } + val quitPortalArray = Stages.indexMap.values.map { it.quitPortal }.toIntArray() + val successDoorArray = Stages.indexMap.values.map { it.successDoor }.toIntArray() + } + } + + fun shuffleStages(player: Player) { + // Obtain an array to shuffle. Must be at least [5] long. + val stagesArrayToShuffle = intArrayOf(0,1,2,3,4,5,6) // Stages.indexArray.toIntArray() + stagesArrayToShuffle.shuffle() + setAttribute(player, RecruitmentDrive.attributeStage1, stagesArrayToShuffle[0]) + setAttribute(player, RecruitmentDrive.attributeStage2, stagesArrayToShuffle[1]) + setAttribute(player, RecruitmentDrive.attributeStage3, stagesArrayToShuffle[2]) + setAttribute(player, RecruitmentDrive.attributeStage4, stagesArrayToShuffle[3]) + setAttribute(player, RecruitmentDrive.attributeStage5, stagesArrayToShuffle[4]) + setAttribute(player, RecruitmentDrive.attributeCurrentStage, 0) + removeAttribute(player, RecruitmentDrive.attributeStagePassFailState) + } + + fun callStartingDialogues (player: Player, npc: Int) { + when (npc) { + NPCs.SIR_SPISHYUS_2282 -> openDialogue(player, SirSpishyusDialogueFile(1), NPC(npc)) + NPCs.LADY_TABLE_2283 -> openDialogue(player, LadyTableDialogueFile(1), NPC(npc)) + NPCs.SIR_KUAM_FERENTSE_2284 -> openDialogue(player, SirKuamFerentseDialogueFile(1), NPC(npc)) + NPCs.SIR_TINLEY_2286 -> openDialogue(player, SirTinleyDialogueFile(1), NPC(npc)) + NPCs.SIR_REN_ITCHOOD_2287 -> openDialogue(player, SirRenItchwoodDialogueFile(1), NPC(npc)) + NPCs.MISS_CHEEVERS_2288 -> openDialogue(player, MissCheeversDialogueFile(1), NPC(npc)) + NPCs.MS_HYNN_TERPRETT_2289 -> openDialogue(player, MsHynnTerprettDialogueFile(1), NPC(npc)) + } + } + } + + override fun defineListeners() { + + on(Stages.quitPortalArray, IntType.SCENERY, "use") { player, node -> + FailTestCutscene(player).start() + return@on true + } + + on(Stages.successDoorArray, IntType.SCENERY, "open") { player, node -> + // This is specially for Miss Cheevers + if (inInventory(player, Items.BRONZE_KEY_5585)) { + sendMessage(player, "You use the duplicate key you made to unlock the door.") + setAttribute(player, RecruitmentDrive.attributeStagePassFailState, 1) + } + // Success Door + if (getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) == 1) { + removeAttribute(player, RecruitmentDrive.attributeStagePassFailState) + setAttribute(player, RecruitmentDrive.attributeCurrentStage, getAttribute(player, RecruitmentDrive.attributeCurrentStage, 0) + 1) + DoorActionHandler.handleAutowalkDoor(player, node as core.game.node.scenery.Scenery) + val currentLevel = getAttribute(player, RecruitmentDrive.attributeCurrentStage, 0) + if (currentLevel >= 5) { + CompleteTestCutscene(player).start() + return@on true + } + val currentStage = getAttribute(player, RecruitmentDrive.attributeStageArray[currentLevel], 0) + val currentStageEnum = Stages.indexMap[currentStage]!! + closeDialogue(player) + + // This is specifically for Sir Spishyus to reset the fox, chicken, grain + SirSpishyusRoomListeners.resetStage(player) + + queueScript(player, 0, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + player.inventory.clear() + player.equipment.clear() + openOverlay(player, Components.FADE_TO_BLACK_120) + return@queueScript delayScript(player, 6) + } + 1 -> { + teleport(player, currentStageEnum.startLocation) + return@queueScript delayScript(player, 2) + } + 2 -> { + openOverlay(player, Components.FADE_FROM_BLACK_170) + return@queueScript delayScript(player, 2) + } + 3 -> { + forceWalk(player, currentStageEnum.startWalkLocation, "dumb") + return@queueScript delayScript(player, 2) + } + 4 -> { + callStartingDialogues(player, currentStageEnum.npc) + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + } else { + if(node.id == Scenery.DOOR_7323) { + // This is specifically for SirRenItchwood + openInterface(player, Components.RD_COMBOLOCK_285) + } else { + sendMessage(player, "You have not completed this room's puzzle yet.") + } + } + return@on true + } + } + + /** Starting Recruitment Drive test cutscene */ + class StartTestCutscene(player: Player) : Cutscene(player) { + override fun setup() { + loadRegion(9805) + val currentStage = getAttribute(player, RecruitmentDrive.attributeStageArray[0], 0) + setExit(Stages.indexMap[currentStage]!!.startLocation) + } + + override fun runStage(stage: Int) { + when (stage) { + 0 -> { + fadeToBlack() + PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 2)) + timedUpdate(6) + } + 1 -> { + dialogueLinesUpdate(NPCs.SIR_TIFFY_CASHIEN_2290, FacialExpression.HAPPY, "Here we go!", "Mind your head!") + timedUpdate(3) + } + 2 -> { + dialogueLinesUpdate(NPCs.SIR_TIFFY_CASHIEN_2290, FacialExpression.HAPPY, "Oops. Ignore the smell!", "Nearly there!") + timedUpdate(3) + } + 3 -> { + dialogueLinesUpdate(NPCs.SIR_TIFFY_CASHIEN_2290, FacialExpression.HAPPY, "And...", "Here we are!", "Best of luck!") + timedUpdate(3) + } + 4 -> { + player.inventory.clear() + player.equipment.clear() + PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 0)) + dialogueClose() + endWithoutFade { + val currentStage = getAttribute(player, RecruitmentDrive.attributeStageArray[0], 0) + val firstStage = Stages.indexMap[currentStage]!! + + // This is specifically for Sir Spishyus to reset the fox, chicken, grain + SirSpishyusRoomListeners.resetStage(player) + + queueScript(player, 0, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + fadeFromBlack() + return@queueScript delayScript(player, 2) + } + 1 -> { + forceWalk(player, firstStage.startWalkLocation, "dumb") + return@queueScript delayScript(player, 2) + } + 2 -> { + callStartingDialogues(player, firstStage.npc) + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + + } + } + } + } + } + + /** Failed Recruitment Drive test cutscene */ + class FailTestCutscene(player: Player) : Cutscene(player) { + override fun setup() { + loadRegion(9805) + setExit(Location(2997, 3374)) + } + + override fun runStage(stage: Int) { + when (stage) { + 0 -> { + closeDialogue(player) + fadeToBlack() + PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 2)) + timedUpdate(6) + } + 1 -> { + var clearBoss = getAttribute(player, SirKuamFerentseDialogueFile.attributeGeneratedSirLeye, NPC(0)) + if (clearBoss.id != 0) { + clearBoss.clear() + } + player.inventory.clear() + player.equipment.clear() + queueScript(player, 0, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + fadeFromBlack() + return@queueScript delayScript(player, 2) + } + 1 -> { + PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 0)) + openDialogue(player, SirTiffyCashienFailedDialogueFile(), NPC(NPCs.SIR_TIFFY_CASHIEN_2290)) + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + endWithoutFade { + face(player, Location(2997, 3373)) + fadeFromBlack() + } + } + } + } + } + + /** Complete Recruitment Drive test cutscene */ + class CompleteTestCutscene(player: Player) : Cutscene(player) { + override fun setup() { + loadRegion(9805) + setExit(Location(2996, 3375)) + } + + override fun runStage(stage: Int) { + when (stage) { + 0 -> { + if (getQuestStage(player, Quests.RECRUITMENT_DRIVE) == 2) { + setQuestStage(player, Quests.RECRUITMENT_DRIVE, 3) + } + closeDialogue(player) + fadeToBlack() + PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 2)) + timedUpdate(6) + } + 1 -> { + player.inventory.clear() + player.equipment.clear() + PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 0)) + queueScript(player, 0, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + fadeFromBlack() + return@queueScript delayScript(player, 2) + } + 1 -> { + openDialogue(player, SirTiffyCashienDialogueFile(), NPC(NPCs.SIR_TIFFY_CASHIEN_2290)) + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + endWithoutFade { + face(player, Location(2997, 3373)) + fadeFromBlack() + } + } + } + } + } + + class LogoutRecruitmentDrive : MapArea { + override fun defineAreaBorders(): Array { + return arrayOf(getRegionBorders(9805)) + } + + override fun getRestrictions(): Array { + return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS) + } + + override fun areaLeave(entity: Entity, logout: Boolean) { + if (entity is Player) { + // This is specifically for Sir Spishyus to reset the fox, chicken, grain + SirSpishyusRoomListeners.resetStage(entity) + // Clear inventory whenever you leave the recruitment drive area + entity.inventory.clear() + entity.equipment.clear() + // Restore player normal tabs on leave + entity.interfaceManager.openDefaultTabs() + // Teleport you out if you log out. You should do this in one sitting. + if (logout) { + PacketRepository.send(MinimapState::class.java, MinimapStateContext(entity, 0)) + teleport(entity, Location(2996, 3375)) + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/SirAmikVarzeDialogueFile.kt b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/SirAmikVarzeDialogueFile.kt new file mode 100644 index 0000000..a9aacdc --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/SirAmikVarzeDialogueFile.kt @@ -0,0 +1,75 @@ +package content.region.asgarnia.falador.quest.recruitmentdrive + +import core.api.* +import core.game.dialogue.* +import content.data.Quests + +class SirAmikVarzeDialogueFile : DialogueBuilderFile() { + + override fun create(b: DialogueBuilder) { + b.onQuestStages(Quests.RECRUITMENT_DRIVE, 0) + .npcl(FacialExpression.FRIENDLY,"Hello, friend!") + .playerl(FacialExpression.THINKING, "Do you have any other quests for me to do?") + .branch { player -> if(isQuestComplete(player, Quests.BLACK_KNIGHTS_FORTRESS) && isQuestComplete(player, Quests.DRUIDIC_RITUAL)) { 1 } else { 0 } } + .let{ branch -> + // Failure branch + branch.onValue(0) + .npcl(FacialExpression.THINKING, "A quest? Alas I do not have any quests I can offer you at this time.") + .end() + return@let branch // Return DialogueBranchBuilder instead of DialogueBuilder to forward the success branch. + }.onValue(1) // Success branch + .npc("Quests, eh?", "Well, I don't have anything on the go at the moment,", "but there is an organisation that is always looking for", "capable adventurers to assist them.") + .npc(FacialExpression.FRIENDLY,"Your excellent work sorting out those Black Knights", "means I will happily write you a letter of", "recommendation.") + .npc("Would you like me to put your name forwards to", "them?") + .options().let { optionBuilder -> + optionBuilder.option ("Yes please") + .playerl("Sure thing Sir Amik, sign me up!") + .npc(FacialExpression.SUSPICIOUS,"Erm, well, this is a little embarrassing, I already HAVE", "put you forward as a potential member.") + .npc("They are the Temple Knights, and you are to", "meet Sir Tiffy Cashien in Falador park for testing", "immediately.") + .playerl("Okey dokey, I'll go do that then.") + .endWith { _, player -> + if(getQuestStage(player, Quests.RECRUITMENT_DRIVE) == 0) { + setAttribute(player, RecruitmentDrive.attributeOriginalGender, player.isMale) + setQuestStage(player, Quests.RECRUITMENT_DRIVE, 1) + } + } + optionBuilder.option_playerl("No thanks") + .end() + optionBuilder.option("Tell me about this organization...") + .npc(FacialExpression.SUSPICIOUS,"I cannot tell you much...", "They are called the Temple Knights, and are an", "organisation that was founded by Saradomin personally", "many centuries ago.") + .npc("There are many rumours and fables about their works and", "actions, but official records of their presence are non-", "existent.") + .npc("It is a secret organisation of extraordinary power and", "resourcefulness...") + .npc("Let me put it this way:", "Should you decide to take them up on their generous", "offer to join, you will find yourself in an advantageous", "position that many in this world would envy, and that few") + .npc("are called to occupy.") + .playerl("Well, that wasn't quite as helpful as I thought it would be...but thanks anyway, I guess.") + .end() + } + + b.onQuestStages(Quests.RECRUITMENT_DRIVE, 1, 2, 3, 4) + .npcl(FacialExpression.FRIENDLY,"Hello, friend!") + .playerl(FacialExpression.THINKING, "Can I just skip the test to become a Temple Knight?") + .npcl("No, I'm afraid not. I suggest you go meet Sir Tiffy in Falador Park, he will be expecting you.") + .end() + + // This should be after the Wanted Quest, but is the placeholder until that quest is implemented. + b.onQuestStages(Quests.RECRUITMENT_DRIVE, 100) + .npcl(FacialExpression.FRIENDLY,"Hello, friend!") + .npcl(FacialExpression.FRIENDLY,"Well @name, now that you are a White Knight, I expect you should be out there hunting Black Knights for us!") + .options().let { optionBuilder -> + optionBuilder.option_playerl("Can you explain the White Knight honour system again?") + .npcl("Sadly we are not as rich as we once were, and there are many White Knights who foolishly lose their combat equipment.") + .npcl("We do not think it fair to make a profit from our brethren, so we will sell you equipment at cost, and rebuy it at the same cost, but we will only sell equipment to those we consider responsible enough to") + .npcl("wield it correctly.") + .npcl("By killing Black Knights, you will increase your reputation with us, by killing White Knights we will obviously think less of you.") + .npcl("You can check your White Knight reputation level by looking at your quest journal for the Wanted! Quest, or Sir Vyvin will let you know what level you are at when you go to purchase equipment.") + .npcl("Sir Vyvin can be found in Falador Castle, and he will sell you any equipment appropriate to your reputation level.") + .npcl("Have fun, and go kill some Black Knights for me!") + .playerl("Okay Amik, thanks for explaining!") + .end() + + optionBuilder.option("Okay, bye!") + .playerl("Okay, 'bye then Amik!") + .end() + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/SirKuamFerentseDialogue.kt b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/SirKuamFerentseDialogue.kt new file mode 100644 index 0000000..055845c --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/SirKuamFerentseDialogue.kt @@ -0,0 +1,58 @@ +package content.region.asgarnia.falador.quest.recruitmentdrive + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class SirKuamFerentseDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, SirKuamFerentseDialogueFile(), npc) + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return SirKuamFerentseDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.SIR_KUAM_FERENTSE_2284) + } +} + +class SirKuamFerentseDialogueFile(private val dialogueNum: Int = 0) : DialogueBuilderFile() { + companion object { + const val attributeGeneratedSirLeye = "quest:recruitmentdrive-generatedsirleye" + } + + override fun create(b: DialogueBuilder) { + b.onPredicate { player -> getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) == 1 } + .npc(FacialExpression.FRIENDLY, "Excellent work, @name.", "Please step through the portal to meet your next", "challenge.") + .end() + + // You can't fail unless you quit the room. + b.onPredicate { _ -> true } + .npc("Ah, @name, you're finally here.", "Your task for this room is to defeat Sir Leye.", "He has been blessed by Saradomin to be undefeatable", "by any man, so it should be quite the challenge for you.") + .npc("If you are having problems, remember", "A true warrior uses his wits as much as his brawn.", "Fight smarter, not harder.") + .endWith { _, player -> + var boss = getAttribute(player, attributeGeneratedSirLeye, NPC(0)) + if (boss.id != 0) { + boss.clear() + } + boss = NPC(NPCs.SIR_LEYE_2285, player.location) + setAttribute(player, attributeGeneratedSirLeye, boss) + boss.isRespawn = false + boss.isAggressive = false + boss.isWalks = true + boss.location = Location(2460, 4963) + boss.init() + registerHintIcon(player, boss) + sendChat(boss, "No man may defeat me!") + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/SirLeyeBehavior.kt b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/SirLeyeBehavior.kt new file mode 100644 index 0000000..3f91752 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/SirLeyeBehavior.kt @@ -0,0 +1,49 @@ +package content.region.asgarnia.falador.quest.recruitmentdrive + +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import org.rs09.consts.NPCs + +class SirLeyeBehavior : NPCBehavior(NPCs.SIR_LEYE_2285) { + var clearTime = 0 + + override fun tick(self: NPC): Boolean { + // You have 400 ticks to kill Sir Leye + if (clearTime++ > 400) { + clearTime = 0 + poofClear(self) + } + return true + } + + override fun beforeDamageReceived(self: NPC, attacker: Entity, state: BattleState) { + val lifepoints = self.skills.lifepoints + if (attacker is Player) { + // If you are male, Sir Leye will recover to full health. + if (attacker.isMale) { + if (state.estimatedHit + Integer.max(state.secondaryHit, 0) > lifepoints - 1) { + self.skills.lifepoints = self.getSkills().getStaticLevel(Skills.HITPOINTS) + } + } + } + } + + override fun onDeathFinished(self: NPC, killer: Entity) { + if (killer is Player) { + clearHintIcon(killer) + setAttribute(killer, RecruitmentDrive.attributeStagePassFailState, 1) + removeAttribute(killer, SirKuamFerentseDialogueFile.attributeGeneratedSirLeye) + } + } + + // No xp from attacking this dude. + override fun getXpMultiplier(self: NPC, attacker: Entity): Double { + return 0.0 + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/SirRenItchwoodDialogue.kt b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/SirRenItchwoodDialogue.kt new file mode 100644 index 0000000..d5ddd45 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/SirRenItchwoodDialogue.kt @@ -0,0 +1,199 @@ +package content.region.asgarnia.falador.quest.recruitmentdrive + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.interaction.InterfaceListener +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.Components +import org.rs09.consts.NPCs + +@Initializable +class SirRenItchwoodDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, SirRenItchwoodDialogueFile(), npc) + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return SirRenItchwoodDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.SIR_REN_ITCHOOD_2287) + } +} + +class SirRenItchwoodDialogueFile(private val dialogueNum: Int = 0) : DialogueBuilderFile() { + companion object { + const val attributeClueNumber = "quest:recruitmentdrive-cluenumber" + } + + override fun create(b: DialogueBuilder) { + b.onPredicate { player -> dialogueNum in 0..1 && getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) != -1 } + .betweenStage { _, player, _, _ -> + if (getAttribute(player, attributeClueNumber, -1) !in 0..5) { + setAttribute(player, attributeClueNumber, (0..5).random()) + } + } + .npc("Greetings friend, and welcome here,", "you'll find my puzzle not so clear.", "Hidden amongst my words, it's true,", "the password for the door as a clue.") + .options().let { optionBuilder -> + optionBuilder.option_playerl ("Can I have the clue for the door?") + .branch { player -> getAttribute(player, attributeClueNumber, 0) } + .let{ branch -> + // Note: all the "I" in here are written in small case "i" (sic) + branch.onValue(0) + .npc("Better than me, you'll not find", "In rhyming and in puzzles.", "This clue so clear will tax your mind", "Entirely as it confuzzles!") + .end() + branch.onValue(1) + .npc("Feel the aching of your mind", "In puzzlement, confused.", "See the clue hidden behind", "His words, as you perused.") + .end() + branch.onValue(2) + .npc("Look closely at the words i speak;", "And study closely every part.", "See for yourself the word you seek", "Trapped for you if you're smart.") + .end() + branch.onValue(3) + .npc("More than words, i have not for you", "Except the things i say today.", "Aware are you, this is a clue?", "Take note of what i say!") + .end() + branch.onValue(4) + .npc("Rare it is that you will see", "A puzzle such as this!", "In many ways it tickles me", "Now, watching you hit and miss!") + .end() + branch.onValue(5) + .npc("This riddle of mine may confuse,", "I am quite sure of that.", "Mayhap you should closely peruse", "Every word i have spat?") + .end() + } + return@let optionBuilder.option("Can I have a different clue?") + .player("I don't get that riddle...", "Can I have a different one?") + .branch { player -> getAttribute(player, attributeClueNumber, 0) } + .let{ branch -> + branch.onValue(0) + .npc("Before you hurry through that door", "Inspect the words i spoke.", "There is a simple hidden flaw", "Ere you think my rhyme a joke.") + .end() + branch.onValue(1) + .npc("First my clue you did not see,", "I really wish you had.", "Such puzzling wordplay devilry", "Has left you kind of mad!") + .end() + branch.onValue(2) + .npc("Last time my puzzle did not help", "Apparently, so you've bidden.", "Study my speech carefully, whelp", "To find the answer, hidden.") + .end() + branch.onValue(3) + .npc("Many types have passed through here", "Even such as you amongst their sort.", "And in the end, the puzzles clear;", "The hidden word you saught.") + .end() + branch.onValue(4) + .npc("Repetition, once again", "Against good sense it goes.", "In my words, the answers plain", "Now that you see rhyme flows.") + .end() + branch.onValue(5) + .npc("Twice it is now, i have stated", "In a rhyme, what is the pass.", "Maybe my words obfuscated", "Entirely beyond your class.") + .end() + } + /* + // I'm too goddamned lazy to implement the final clue dialogue + return@let optionBuilder.option("Can I have the final clue?") + .branch { player -> getAttribute(player, attributeClueNumber, 0) } + .let{ branch -> + branch.onValue(0) + .npc("Betrayed by words the answer is", "In that what i say is the key", "There is no more help after this", "Especially no more from me.") + .end() + branch.onValue(1) + .npc("For the last time i will state", "In simple words, the clue.", "Such tricky words make you irate", "Having no idea what to do...") + .end() + branch.onValue(2) + .npc("Lo! my final speech is now", "Attended to by you.", "Study my words, and find out how", "To understand my clue!") + .end() + branch.onValue(3) + .npc("Many types have passed through here", "Even such as you amongst their sort.", "And in the end, the puzzles clear;", "The hidden word you saught.") + .end() + branch.onValue(4) + .npc("Repetition, once again", "Against good sense it goes.", "In my words, the answers plain", "Now that you see rhyme flows.") + .end() + branch.onValue(5) + .npc("Twice it is now, i have stated", "In a rhyme, what is the pass.", "Maybe my words obfuscated", "Entirely beyond your class.") + .end() + } + */ + + } + b.onPredicate { player -> dialogueNum == 2 || getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) == -1 } + .betweenStage { _, player, _, _ -> + setAttribute(player, RecruitmentDrive.attributeStagePassFailState, -1) + } + .npc(FacialExpression.SAD, "It's sad to say,", "this test beat you.", "I'll send you to Tiffy,", "what to do?") + .endWith { _, player -> + removeAttribute(player, attributeClueNumber) + removeAttribute(player, RecruitmentDrive.attributeStagePassFailState) + RecruitmentDriveListeners.FailTestCutscene(player).start() + } + + } +} + +class DoorLockPuzzleInterfaceListener : InterfaceListener { + + companion object { + const val temp = Components.RD_COMBOLOCK_285 + const val attributeLock1 = "quest:recruitmentdrive-lock1" + const val attributeLock2 = "quest:recruitmentdrive-lock2" + const val attributeLock3 = "quest:recruitmentdrive-lock3" + const val attributeLock4 = "quest:recruitmentdrive-lock4" + val lockArray = arrayOf(attributeLock1, attributeLock2, attributeLock3, attributeLock4) + val answers = arrayOf("BITE", "FISH", "LAST", "MEAT", "RAIN", "TIME") + } + + override fun defineInterfaceListeners() { + + onOpen(Components.RD_COMBOLOCK_285) { player, _ -> + setAttribute(player, attributeLock1, 65) + setAttribute(player, attributeLock2, 65) + setAttribute(player, attributeLock3, 65) + setAttribute(player, attributeLock4, 65) + return@onOpen true + } + + onClose(Components.RD_COMBOLOCK_285) { player, _ -> + removeAttribute(player, attributeLock1) + removeAttribute(player, attributeLock2) + removeAttribute(player, attributeLock3) + removeAttribute(player, attributeLock4) + return@onClose true + } + + on(Components.RD_COMBOLOCK_285) { player, component, opcode, buttonID, slot, itemID -> + // Child IDs for respective locks: + // 6 7 8 9 + // 10 < Lock1 > 11 12 < Lock2 > 13 14 < Lock3 > 15 16 < Lock4 > 17 + if (buttonID in 10..17) { + val position = (buttonID - 10) / 2 + val backForth = (buttonID - 10) % 2 + var newValue = getAttribute(player, lockArray[position], 65) + (if (backForth == 0) { -1 } else { 1 }) + if (newValue < 65) { newValue = 90 } // If char number is under A(65), loop back to Z(90) + if (newValue > 90) { newValue = 65 } // If char number is over Z(90), loop back to A(65) + setAttribute(player, lockArray[position], newValue) + setInterfaceText(player, newValue.toChar().toString(), Components.RD_COMBOLOCK_285, position + 6) + } + // Enter Button + if (buttonID == 18) { + val lock1 = getAttribute(player, attributeLock1, 65).toChar() + val lock2 = getAttribute(player, attributeLock2, 65).toChar() + val lock3 = getAttribute(player, attributeLock3, 65).toChar() + val lock4 = getAttribute(player, attributeLock4, 65).toChar() + val answer = arrayOf(lock1, lock2, lock3, lock4).joinToString("") + closeInterface(player) + if (answers[getAttribute(player, SirRenItchwoodDialogueFile.attributeClueNumber, 0)] == answer){ + removeAttribute(player, SirRenItchwoodDialogueFile.attributeClueNumber) + if (getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) != -1) { + setAttribute(player, RecruitmentDrive.attributeStagePassFailState, 1) + } + sendNPCDialogue(player, NPCs.SIR_REN_ITCHOOD_2287, "Your wit is sharp, your brains quite clear; You solved my puzzle with no fear. At puzzles I rank you quite the best, now enter the portal for your next test.") + } else { + removeAttribute(player, SirRenItchwoodDialogueFile.attributeClueNumber) + if (getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) == 0) { + setAttribute(player, RecruitmentDrive.attributeStagePassFailState, -1) + openDialogue(player, SirRenItchwoodDialogueFile(2), NPC(NPCs.SIR_REN_ITCHOOD_2287)) + } + } + } + return@on true + } + } +} diff --git a/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/SirSpishyusDialogue.kt b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/SirSpishyusDialogue.kt new file mode 100644 index 0000000..8f6df77 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/SirSpishyusDialogue.kt @@ -0,0 +1,221 @@ +package content.region.asgarnia.falador.quest.recruitmentdrive + +import core.api.* +import core.game.container.impl.EquipmentContainer +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.interaction.InteractionListener +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.world.map.zone.ZoneBorders +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +@Initializable +class SirSpishyusDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, SirSpishyusDialogueFile(), npc) + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return SirSpishyusDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.SIR_SPISHYUS_2282) + } +} + +class SirSpishyusDialogueFile(private val dialogueNum: Int = 0) : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onPredicate { player -> getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) == 1 } + .npc(FacialExpression.FRIENDLY, "Excellent work, @name.", "Please step through the portal to meet your next", "challenge.") + .end() + + b.onPredicate { player -> dialogueNum == 2 || getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) == -1 } + .betweenStage { _, player, _, _ -> + setAttribute(player, RecruitmentDrive.attributeStagePassFailState, -1) + } + .npc(FacialExpression.SAD, "No... I am very sorry.", "Apparently you are not up to the challenge.", "I will return you where you came from, better luck in the", "future.") + .endWith { _, player -> + removeAttribute(player, SirTinleyDialogueFile.attributeDoNotMove) + removeAttribute(player, RecruitmentDrive.attributeStagePassFailState) + RecruitmentDriveListeners.FailTestCutscene(player).start() + } + b.onPredicate { _ -> true } + .npcl(FacialExpression.FRIENDLY, "Ah, welcome @name.") + .playerl(FacialExpression.FRIENDLY, "Hello there." + " What am I supposed to be doing in this room?") + .npcl(FacialExpression.FRIENDLY, "Well, your task is to take this fox, this chicken and this bag of grain across that bridge there to the other side of the room.") + .npcl(FacialExpression.FRIENDLY, "When you have done that, your task is complete.") + .playerl(FacialExpression.FRIENDLY, "Is that it?") + .npcl(FacialExpression.FRIENDLY, "Well, it is not quite as simple as that may sound.") + .npcl(FacialExpression.FRIENDLY, "Firstly, you may only carry one of the objects across the room at a time, for the bridge is old and fragile.") + .npcl(FacialExpression.FRIENDLY, "Secondly, the fox wants to eat the chicken, and the chicken wants to eat the grain. Should you ever leave the fox unattended with the chicken, or the grain unattended with the chicken, then") + .npcl(FacialExpression.FRIENDLY, "one of them will be eaten, and you will be unable to complete the test.") + .playerl(FacialExpression.FRIENDLY, "Okay, I'll see what I can do.") + .end() + } +} +class SirSpishyusRoomListeners : InteractionListener { + companion object { + const val foxFromVarbit = 680 + const val foxToVarbit = 681 + const val chickenFromVarbit = 682 + const val chickenToVarbit = 683 + const val grainFromVarbit = 684 + const val grainToVarbit = 685 + + val fromZoneBorder = ZoneBorders(2479, 4967, 2490, 4977) + val toZoneBorder = ZoneBorders(2471, 4967, 2478, 4977) + + fun countEquipmentItems(player: Player): Int { + var count = 0 + if(inEquipment(player, Items.GRAIN_5607)) { count++ } + if(inEquipment(player, Items.FOX_5608)) { count++ } + if(inEquipment(player, Items.CHICKEN_5609)) { count++ } + return count + } + + fun checkFinished(player: Player) { + if (getVarbit(player, foxToVarbit) == 1 && getVarbit(player, chickenToVarbit) == 1 && getVarbit(player, grainToVarbit) == 1) { + sendMessage(player, "Congratulations! You have solved this room's puzzle!") + setAttribute(player, RecruitmentDrive.attributeStagePassFailState, 1) + } + } + + fun checkFail(player: Player): Boolean { + return ((getVarbit(player, foxFromVarbit) == 0 && getVarbit(player, chickenFromVarbit) == 0 && getVarbit(player, grainFromVarbit) == 1) || + (getVarbit(player, foxFromVarbit) == 1 && getVarbit(player, chickenFromVarbit) == 0 && getVarbit(player, grainFromVarbit) == 0) || + (getVarbit(player, foxToVarbit) == 1 && getVarbit(player, chickenToVarbit) == 1 && getVarbit(player, grainToVarbit) == 0) || + (getVarbit(player, foxToVarbit) == 0 && getVarbit(player, chickenToVarbit) == 1 && getVarbit(player, grainToVarbit) == 1)) + } + + fun resetStage(player: Player) { + setVarbit(player, foxFromVarbit, 0) + setVarbit(player, chickenFromVarbit, 0) + setVarbit(player, grainFromVarbit, 0) + setVarbit(player, foxToVarbit, 0) + setVarbit(player, chickenToVarbit, 0) + setVarbit(player, grainToVarbit, 0) + removeItem(player, Items.GRAIN_5607, Container.EQUIPMENT) + removeItem(player, Items.FOX_5608, Container.EQUIPMENT) + removeItem(player, Items.CHICKEN_5609, Container.EQUIPMENT) + } + } + + override fun defineListeners() { + on(Scenery.PRECARIOUS_BRIDGE_7286, SCENERY, "cross") { player, node -> + if (countEquipmentItems(player) > 1) { + sendDialogue(player, "I really don't think I should be carrying more than 5Kg across that rickety bridge...") + } else if (checkFail(player)) { + openDialogue(player, SirTinleyDialogueFile(2), NPC(NPCs.SIR_SPISHYUS_2282)) // Fail + } else { + lock(player, 5) + sendMessage(player, "You carefully walk across the rickety bridge...") + player.walkingQueue.reset() + player.walkingQueue.addPath(2476, 4972) + } + return@on true + } + + on(Scenery.PRECARIOUS_BRIDGE_7287, SCENERY, "cross") { player, node -> + if (countEquipmentItems(player) > 1) { + sendDialogue(player, "I really don't think I should be carrying more than 5Kg across that rickety bridge...") + } else if (checkFail(player)) { + openDialogue(player, SirTinleyDialogueFile(2), NPC(NPCs.SIR_SPISHYUS_2282)) // Fail + } else { + lock(player, 5) + sendMessage(player, "You carefully walk across the rickety bridge...") + player.walkingQueue.reset() + player.walkingQueue.addPath(2484, 4972) + } + return@on true + } + + on(Scenery.GRAIN_7284, SCENERY, "pick-up") { player, _ -> + if (getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) == 0) { + if (fromZoneBorder.insideBorder(player)) { + replaceSlot(player, EquipmentSlot.CAPE.ordinal, Item(Items.GRAIN_5607), null, Container.EQUIPMENT) + setVarbit(player, grainFromVarbit, 1) + } + if (toZoneBorder.insideBorder(player)) { + replaceSlot(player, EquipmentSlot.CAPE.ordinal, Item(Items.GRAIN_5607), null, Container.EQUIPMENT) + setVarbit(player, grainToVarbit, 0) + } + } + return@on true + } + onUnequip(Items.GRAIN_5607) { player, _ -> + if (fromZoneBorder.insideBorder(player)) { + removeItem(player, Items.GRAIN_5607, Container.EQUIPMENT) + setVarbit(player, grainFromVarbit, 0) + } + if (toZoneBorder.insideBorder(player)) { + removeItem(player, Items.GRAIN_5607, Container.EQUIPMENT) + setVarbit(player, grainToVarbit, 1) + checkFinished(player) + } + return@onUnequip true + } + + + on(Scenery.FOX_7277, SCENERY, "pick-up") { player, _ -> + if (getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) == 0) { + if (fromZoneBorder.insideBorder(player)) { + replaceSlot(player, EquipmentSlot.WEAPON.ordinal, Item(Items.FOX_5608), null, Container.EQUIPMENT) + setVarbit(player, foxFromVarbit, 1) + } + if (toZoneBorder.insideBorder(player)) { + replaceSlot(player, EquipmentSlot.WEAPON.ordinal, Item(Items.FOX_5608), null, Container.EQUIPMENT) + setVarbit(player, foxToVarbit, 0) + } + } + return@on true + } + onUnequip(Items.FOX_5608) { player, _ -> + if (fromZoneBorder.insideBorder(player)) { + removeItem(player, Items.FOX_5608, Container.EQUIPMENT) + setVarbit(player, foxFromVarbit, 0) + } + if (toZoneBorder.insideBorder(player)) { + removeItem(player, Items.FOX_5608, Container.EQUIPMENT) + setVarbit(player, foxToVarbit, 1) + checkFinished(player) + } + return@onUnequip true + } + + + on(Scenery.CHICKEN_7281, SCENERY, "pick-up") { player, _ -> + if (getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) == 0) { + if (fromZoneBorder.insideBorder(player)) { + replaceSlot(player, EquipmentSlot.SHIELD.ordinal, Item(Items.CHICKEN_5609), null, Container.EQUIPMENT) + setVarbit(player, chickenFromVarbit, 1) + } + if (toZoneBorder.insideBorder(player)) { + replaceSlot(player, EquipmentSlot.SHIELD.ordinal, Item(Items.CHICKEN_5609), null, Container.EQUIPMENT) + setVarbit(player, chickenToVarbit, 0) + } + } + return@on true + } + onUnequip(Items.CHICKEN_5609) { player, _ -> + if (fromZoneBorder.insideBorder(player)) { + removeItem(player, Items.CHICKEN_5609, Container.EQUIPMENT) + setVarbit(player, chickenFromVarbit, 0) + } + if (toZoneBorder.insideBorder(player)) { + removeItem(player, Items.CHICKEN_5609, Container.EQUIPMENT) + setVarbit(player, chickenToVarbit, 1) + checkFinished(player) + } + return@onUnequip true + } + + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/SirTiffyCashienDialogueFile.kt b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/SirTiffyCashienDialogueFile.kt new file mode 100644 index 0000000..9bd2ecf --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/SirTiffyCashienDialogueFile.kt @@ -0,0 +1,140 @@ +package content.region.asgarnia.falador.quest.recruitmentdrive + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.FacialExpression +import org.rs09.consts.Items + +class SirTiffyCashienDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onQuestStages(Quests.RECRUITMENT_DRIVE, 1) + .player(FacialExpression.FRIENDLY, "Sir Amik Varze sent me to meet you here for some", "sort of testing...") + .npc(FacialExpression.FRIENDLY, "Ah, @name!", "Amik told me all about you, dontchaknow!", "Spliffing job you you did with the old Black Knights there,", "absolutely first class.") + .playerl(FacialExpression.GUILTY, "...Thanks I think.") + // .npcl(FacialExpression.FRIENDLY, "Well, not in those exact words, but you get my point, what?") + .npc(FacialExpression.FRIENDLY, "Well, a top-notch filly like yourself is just the right sort", "we've been looking for for our organisation.") + .npcl(FacialExpression.FRIENDLY, "So, are you ready to begin testing?") + .let { path -> + val originalPath = b.placeholder() + path.goto(originalPath) + return@let originalPath.builder().options().let { optionBuilder -> + val continuePath = b.placeholder() + optionBuilder.option("Testing..?") + .playerl(FacialExpression.FRIENDLY, "Testing? What exactly do you mean by testing?") + .npcl(FacialExpression.FRIENDLY, "Jolly bad show! Varze was supposed to have informed you about all this before sending you here!") + .npcl(FacialExpression.FRIENDLY, "Well, not your fault I suppose, what? Anywho, our organisation is looking for a certain specific type of person to join.") + .playerl(FacialExpression.FRIENDLY, "So... You want me to go kill some monster or something for you?") + .npcl(FacialExpression.FRIENDLY, "Not at all, old bean. There's plenty of warriors around should we require dumb muscle.") + .npcl(FacialExpression.FRIENDLY, "That's really not the kind of thing our organisation is after, what?") + .playerl(FacialExpression.FRIENDLY, "So you want me to go and fetch you some kind of common item, and then take it for delivery somewhere on the other side of the country?") + .playerl(FacialExpression.FRIENDLY, "Because I really hate doing that!") + .npcl(FacialExpression.FRIENDLY, "Haw, haw, haw! What a dull thing to ask of someone, what?") + .npcl(FacialExpression.FRIENDLY, "I know what you mean, though. I did my fair share of running errands when I was a young adventurer, myself!") + .playerl(FacialExpression.FRIENDLY, "So what exactly will this test consist of?") + .npcl(FacialExpression.FRIENDLY, "Can't let just any old riff-raff in, what? The mindless thugs and bully boys are best left in the White Knights or the city guard. We look for the top-shelf brains to join us.") + .playerl(FacialExpression.FRIENDLY, "So you want to test my brains? Will it hurt?") + .npcl(FacialExpression.FRIENDLY, "Haw, haw, haw! That's a good one!") + .npcl(FacialExpression.FRIENDLY, "Not in the slightest.. Well, maybe a bit, but we all have to make sacrifices occasionally, what?") + .playerl(FacialExpression.FRIENDLY, "What do you want me to do then?") + .npcl(FacialExpression.FRIENDLY, "It's a test of wits, what? I'll take you to our secret training grounds, and you will have to pass through a series of five separate intelligence test to prove you're our sort of adventurer.") + .npcl(FacialExpression.FRIENDLY, "Standard puzzle room rules will apply.") + .playerl(FacialExpression.THINKING, "Erm... What are standard puzzle room rules exactly?") + .npcl(FacialExpression.HAPPY, "Never done this sort of thing before, what?") + .npc("The simple rules are:", "No items or equipment to be brought with you.", "Each room is a self-contained puzzle.", "You may quit at any time.") + .npcl(FacialExpression.HAPPY, "Of course, if you quit a room, then all your progress up to that point will be cleared, and you'll have to start again from scratch.") + .npc(FacialExpression.HAPPY, "Our organisation manages to filter all the top-notch", "adventurers this way.", "So, are you ready to go?") + .goto(originalPath) + optionBuilder.option("Organisation?") + .playerl(FacialExpression.THINKING, "This organisation you keep mentioning.. Perhaps you could tell me a little about it?") + .npcl(FacialExpression.FRIENDLY, "Oh, that Amik! Jolly bad form. Did he not tell you anything that he was supposed to?") + .playerl(FacialExpression.FRIENDLY, "No. He didn't really tell me anything except to come here and meet you.") + .npcl(FacialExpression.FRIENDLY, "Well, now, old sport, let me give you the heads up and the low down, what?") + .npcl(FacialExpression.FRIENDLY, "I represent the Temple Knights. We are the premier order of Knights in Asgarnia, if not the world. Saradomin himself personally founded our order centuries ago, and we answer only to him.") + .npcl(FacialExpression.FRIENDLY, "Only the very best of the best are permitted to join, and the powers we command are formidable indeed.") + .npcl(FacialExpression.FRIENDLY, "You might say that we are the front line of defence for the entire kingdom!") + .playerl(FacialExpression.THINKING, "So what's the difference between you and the White Knights?") + .npcl(FacialExpression.FRIENDLY, "Well, in simple terms, we're better! Any fool with a sword can manage to get into the White Knights, which is mostly the reason they are so very, very incompetent, what?") + .npcl(FacialExpression.FRIENDLY, "The Temple Knights, on the other hand, have to be smarter, stronger and better than all others. We are the elite. No man controls us, for our orders come directly from Saradomin himself!") + .npcl(FacialExpression.FRIENDLY, "According to Sir Vey Lance, our head of operations, that is. He claims that everything he tells us to do is done with Saradomin's implicit permission.") + .npcl(FacialExpression.FRIENDLY, "It's not every job where you have more authority than the king, though, is it?") + .playerl(FacialExpression.THINKING, "Wait... You can order the King around?") + .npcl(FacialExpression.FRIENDLY, "Well, not me personally. I'm only in the recruitment side of things, dontchaknow, but the higher ranking members of the organisation have almost absolute power over the kingdom.") + .npcl(FacialExpression.FRIENDLY, "Plus a few others, so I hear...") + .npcl(FacialExpression.FRIENDLY, "Anyway, this is why we keep our organisation shrouded in secrecy, and why we demand such rigorous testing for all potential recruits. Speaking of which, are you ready to begin your testing?") + .goto(originalPath) + optionBuilder.option("Yes, let's go!") + .player(FacialExpression.FRIENDLY, "Yeah. this sounds right up my street.", "Let's go!") + .branch { player -> if(player.inventory.isEmpty && player.equipment.isEmpty && !player.familiarManager.hasFamiliar()) { 1 } else { 0 } } + .let { branch -> + branch.onValue(0) + .npcl(FacialExpression.NEUTRAL, "Well, bad luck, old @g[guy,gal]. You'll need to have a completely empty inventory and you can't be wearing any equipment before we can accurately test you.") + .npcl(FacialExpression.HAPPY, "Don't want people cheating by smuggling stuff in, what? That includes things carried by familiars, too! Come and see me again after you've been to the old bank to drop your stuff off, what?") + .end() + return@let branch + } + .onValue(1) + .npc(FacialExpression.HAPPY, "Jolly good show!", "Now the training grounds location is a secret, so...") + .goto(continuePath) + optionBuilder.option("No, I've changed my mind.") + .player("No, I've changed my mind.") + .end() + + return@let continuePath.builder() + } + + }.endWith { _, player -> + if (getQuestStage(player, Quests.RECRUITMENT_DRIVE) == 1) { + setQuestStage(player, Quests.RECRUITMENT_DRIVE, 2) + } + RecruitmentDriveListeners.shuffleStages(player) + RecruitmentDriveListeners.StartTestCutscene(player).start() + } + b.onQuestStages(Quests.RECRUITMENT_DRIVE, 2) + .npc(FacialExpression.FRIENDLY, "Ah, what ho!", "Back for another go at the old testing, what?") + .options().let { optionBuilder -> + val continuePath = b.placeholder() + optionBuilder.option("Yes, let's go!") + .player(FacialExpression.FRIENDLY, "Yeah. this sounds right up my street.", "Let's go!") + .branch { player -> if(player.inventory.isEmpty && player.equipment.isEmpty && !player.familiarManager.hasFamiliar()) { 1 } else { 0 } } + .let { branch -> + branch.onValue(0) + .npcl(FacialExpression.NEUTRAL, "Well, bad luck, old @g[guy,gal]. You'll need to have a completely empty inventory and you can't be wearing any equipment before we can accurately test you.") + .npcl(FacialExpression.HAPPY, "Don't want people cheating by smuggling stuff in, what? That includes things carried by familiars, too! Come and see me again after you've been to the old bank to drop your stuff off, what?") + .end() + return@let branch + } + .onValue(1) + .npc(FacialExpression.FRIENDLY, "Jolly good show!", "Now the training grounds location is a secret, so...") + .endWith { _, player -> + RecruitmentDriveListeners.shuffleStages(player) + RecruitmentDriveListeners.StartTestCutscene(player).start() + } + optionBuilder.option("No, I've changed my mind.") + .player("No, I've changed my mind.") + .end() + return@let continuePath.builder() + } + b.onQuestStages(Quests.RECRUITMENT_DRIVE, 3) + .npc(FacialExpression.HAPPY, "Oh, jolly well done!", "Your performance will need to be evaluated by Sir Vey", "personally, but I don't think it's going too far ahead of", "myself to welcome you to the team!") + .endWith { _, player -> + // Get a voucher and $3000 to change gender if you did do it during the quest. + if (getAttribute(player, RecruitmentDrive.attributeOriginalGender, true) != player.isMale) { + addItemOrDrop(player, Items.MAKEOVER_VOUCHER_5606) + addItemOrDrop(player, Items.COINS_995, 3000) + } + removeAttribute(player, RecruitmentDrive.attributeOriginalGender) + finishQuest(player, Quests.RECRUITMENT_DRIVE) + } + } +} + +class SirTiffyCashienFailedDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onPredicate { _ -> true } + .npc(FacialExpression.SAD, "Oh, jolly bad luck, what?", "Not quite the brainbox you thought you were, eh?") + .npc(FacialExpression.HAPPY, "Well, never mind!", "You have an open invitation to join our organization, so", "when you're feeling a little smarter, come back and talk", "to me again.") + + } +} diff --git a/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/SirTinleyDialogue.kt b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/SirTinleyDialogue.kt new file mode 100644 index 0000000..d00cae7 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/falador/quest/recruitmentdrive/SirTinleyDialogue.kt @@ -0,0 +1,100 @@ +package content.region.asgarnia.falador.quest.recruitmentdrive + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.interaction.QueueStrength +import core.game.node.entity.Entity +import core.game.node.entity.impl.Projectile +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import core.game.world.update.flag.context.Graphics +import core.plugin.Initializable +import org.rs09.consts.NPCs +import org.rs09.consts.Sounds + +@Initializable +class SirTinleyDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, SirTinleyDialogueFile(), npc) + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return SirTinleyDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.SIR_TINLEY_2286) + } +} + +class SirTinleyDialogueFile(private val dialogueNum: Int = 0) : DialogueBuilderFile(), MapArea { + companion object { + const val attributeDoNotMove = "quest:recruitmentdrive-donotmove" + } + + override fun create(b: DialogueBuilder) { + b.onPredicate {player -> dialogueNum == 0 && !getAttribute(player, attributeDoNotMove, false) && getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) == 0 } + .npc("Ah, welcome @name.", "I have but one clue for you to pass this room's puzzle:", "'Patience'.") + .endWith { _, player -> + setAttribute(player, attributeDoNotMove, true) + queueScript(player, 0, QueueStrength.NORMAL) { stage: Int -> + when (stage) { + 0 -> { + return@queueScript delayScript(player, 15) + } + 1 -> { + if (getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) != -1) { + setAttribute(player, RecruitmentDrive.attributeStagePassFailState, 1) + setAttribute(player, attributeDoNotMove, false) + npc(FacialExpression.FRIENDLY, "Excellent work, @name.", "Please step through the portal to meet your next", "challenge.") + } + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + } + + b.onPredicate {player -> dialogueNum == 0 && !getAttribute(player, attributeDoNotMove, false) && getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) == 1 } + .npc(FacialExpression.FRIENDLY, "Excellent work, @name.", "Please step through the portal to meet your next", "challenge.") + .end() + + // If you talk to him before time is up, you fail. + b.onPredicate { player -> dialogueNum == 0 && getAttribute(player, attributeDoNotMove, false) || dialogueNum == 2 || getAttribute(player, RecruitmentDrive.attributeStagePassFailState, 0) == -1 } + .betweenStage { _, player, _, _ -> + setAttribute(player, RecruitmentDrive.attributeStagePassFailState, -1) + } + .npc(FacialExpression.SAD, "No... I am very sorry.", "Apparently you are not up to the challenge.", "I will return you where you came from, better luck in the", "future.") + .endWith { _, player -> + removeAttribute(player, attributeDoNotMove) + removeAttribute(player, RecruitmentDrive.attributeStagePassFailState) + RecruitmentDriveListeners.FailTestCutscene(player).start() + } + + b.onPredicate { _ -> dialogueNum == 1 } + .npc("Ah, @name, you have arrived.", "Speak to me to begin your task.") + .endWith { _, player -> + setAttribute(player, attributeDoNotMove, false) + } + } + + + override fun defineAreaBorders(): Array { + return arrayOf(ZoneBorders(2474, 4959, 2478, 4957)) + } + + override fun entityStep(entity: Entity, location: Location, lastLocation: Location) { + if (entity is Player) { + if(getAttribute(entity, attributeDoNotMove, false)) { + setAttribute(entity, attributeDoNotMove, false) + setAttribute(entity, RecruitmentDrive.attributeStagePassFailState, -1) + openDialogue(entity, SirTinleyDialogueFile(2), NPC(NPCs.SIR_TINLEY_2286)) + } + } + } +} diff --git a/Server/src/main/content/region/asgarnia/goblinvillage/dialogue/GoblinVillageDialogue.java b/Server/src/main/content/region/asgarnia/goblinvillage/dialogue/GoblinVillageDialogue.java new file mode 100644 index 0000000..e28c34f --- /dev/null +++ b/Server/src/main/content/region/asgarnia/goblinvillage/dialogue/GoblinVillageDialogue.java @@ -0,0 +1,175 @@ +package content.region.asgarnia.goblinvillage.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.tools.RandomFunction; + +/** + * Represents the goblin village dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class GoblinVillageDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code GoblinVillageDialogue} {@code Object}. + */ + public GoblinVillageDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code GoblinVillageDialogue} {@code Object}. + * @param player the player. + */ + public GoblinVillageDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new GoblinVillageDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + int rand = RandomFunction.random(5); + switch (rand) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I kill you human!"); + stage = 0; + break; + case 1: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Go away smelly human!"); + stage = 300; + break; + case 2: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Happy goblin new century!"); + stage = 100; + break; + case 3: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "What you doing here?"); + stage = 200; + break; + case 4: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Brown armour best!"); + stage = 800; + break; + case 5: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Go away smelly human!"); + stage = 300; + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + end(); + npc.getProperties().getCombatPulse().attack(player); + break; + case 100: + interpreter.sendOptions("Select an Option", "Happy new century!", "What is the goblin new century?"); + stage = 101; + break; + case 101: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Happy new century!"); + stage = 169; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What is the goblin new century?"); + stage = 102; + break; + } + break; + case 169: + end(); + break; + case 102: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "You tell human secrets!"); + stage = 103; + break; + case 103: + end(); + break; + case 200: + interpreter.sendOptions("Select an Option", "I'm here to kill all you goblins!", "I'm just looking around."); + stage = 201; + break; + case 201: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'm here to kill all you goblins!"); + stage = 143; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'm just looking around."); + stage = 260; + break; + } + break; + case 143: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I kill you!"); + stage = 0; + break; + case 260: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Me not sure that allowed. You have to check with", "generals."); + stage = 261; + break; + case 261: + end(); + break; + case 300: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "What you call me?"); + stage = 301; + break; + case 301: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I kill you human!"); + stage = 0; + break; + case 800: + interpreter.sendOptions("Select an Option", "Err or.", "Why is brown best?"); + stage = 801; + break; + case 801: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Err ok."); + stage = 810; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Why is brown best?"); + stage = 820; + break; + } + break; + case 810: + end(); + break; + case 820: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "General Wartface and General Bentnoze both say it is.", "And normally they never agree!"); + stage = 821; + break; + case 821: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 4483, 4488, 4489, 4484, 4491, 4485, 4486, 4492, 4487, 4481, 4479, 4482, 4480 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/goblinvillage/dialogue/GoblinVillageGuardDialogue.java b/Server/src/main/content/region/asgarnia/goblinvillage/dialogue/GoblinVillageGuardDialogue.java new file mode 100644 index 0000000..0926dc6 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/goblinvillage/dialogue/GoblinVillageGuardDialogue.java @@ -0,0 +1,78 @@ +package content.region.asgarnia.goblinvillage.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; + +/** + * Represents the dialogue plugin used for the goblin village guard npc. + * @author jamix77 + * Fixed a typo -Nuggles + */ +@Initializable +public final class GoblinVillageGuardDialogue extends DialoguePlugin { + + /** + * + * Constructs a new @{Code HengelDialoguePlugin} object. + */ + public GoblinVillageGuardDialogue() { + /** + * empty. + */ + } + + /** + * + * Constructs a new @{Code GoblinVillageGuardDialogue} object. + * @param player + */ + public GoblinVillageGuardDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new GoblinVillageGuardDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + player("You're a long way out from the city."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + npc("I know. We guards usually stay by banks and shops,", "but I got sent all the way out here to keep an eye on","the brigands loitering just south of here."); + stage = 1; + break; + case 1: + player("Sounds more exciting than standing", "around guarding banks and shops."); + stage = 2; + break; + case 2: + npc("It's not too bad. At least I don't get attacked so often", "out here. Guards in the cities get killed all the time."); + stage++; + break; + case 3: + player("Honestly, people these days just don't know how to behave!"); + stage++; + break; + case 4: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 3241 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/goblinvillage/handlers/GoblinVillageNPC.java b/Server/src/main/content/region/asgarnia/goblinvillage/handlers/GoblinVillageNPC.java new file mode 100644 index 0000000..0c34e38 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/goblinvillage/handlers/GoblinVillageNPC.java @@ -0,0 +1,162 @@ +package content.region.asgarnia.goblinvillage.handlers; + +import java.util.List; + +import core.game.node.entity.Entity; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.npc.NPC; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.plugin.Initializable; +import core.tools.RandomFunction; + +/** + * Represents the goblin village npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class GoblinVillageNPC extends AbstractNPC { + + /** + * The NPC ids of NPCs using this plugin. + */ + private static final int[] ID = { /** r */ + 4483, /** g */ + 4488, /** g */ + 4489, /** r */ + 4484, /** g */ + 4491, /** r */ + 4485, /** g */ + 4486, /** g */ + 4492, /** g */ + 4487, /** r */ + 4481, /** r */ + 4479, /** r */ + 4482, /** r */ + 4480 }; + + /** + * Represents the red goblins. + */ + private static final int[] RED_GOBLINS = new int[] { 4483, 4484, 4485, 4481, 4479, 4482, 4480 }; + + /** + * Represents the green goblins. + */ + private static final int GREEN_GOBLINS[] = new int[] { 4488, 4489, 4491, 4486, 4492, 4487 }; + + /** + * Represents the red messages. + */ + private static final String[] RED_MESSAGES = new String[] { "Red armour best!", "Green armour stupid!", "Red!", "Red not green!", "Stupid greenie!" }; + + /** + * Represents the green messages. + */ + private static final String[] GREEN_MESSAGES = new String[] { "Green armour best!", "Green!", "Stupid reddie!" }; + + /** + * Represents the delay. + */ + private long delay = 0L; + + /** + * Represents if the goblin is green. + */ + private boolean green = true; + + /** + * Constructs a new {@code GoblinVillageNPC} {@code Object}. + */ + public GoblinVillageNPC() { + super(0, null); + } + + /** + * Constructs a new {@code GoblinVillageNPC} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + private GoblinVillageNPC(int id, Location location) { + super(id, location); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new GoblinVillageNPC(id, location); + } + + @Override + public void init() { + super.init(); + for (int i : RED_GOBLINS) { + if (getId() == i) { + green = false; + } + } + } + + @Override + public void tick() { + super.tick(); + if (delay < System.currentTimeMillis() && !getProperties().getCombatPulse().isAttacking()) { + final int rand = RandomFunction.random(1, 4); + if (rand == 2) { + final List surronding = RegionManager.getLocalNpcs(this, 10); + for (NPC n : surronding) { + if (n.getId() == getId()) { + continue; + } + if (n.getProperties().getCombatPulse().isAttacking()) { + continue; + } + for (int i : green ? RED_GOBLINS : GREEN_GOBLINS) { + if (n.getId() == i) { + n.lock(5); + getProperties().getCombatPulse().attack(n); + break; + } + } + } + } + delay = System.currentTimeMillis() + 5000;// 15000; + } else { + final int rand = RandomFunction.random(3); + if (rand != 1) { + return; + } + final Entity oponent = getProperties().getCombatPulse().getVictim(); + if (oponent == null) { + return; + } + if (!(oponent instanceof NPC)) { + return; + } + if (oponent.getLocation().getDistance(getLocation()) > 4) { + return; + } + boolean goblin = false; + for (int i : green ? RED_GOBLINS : GREEN_GOBLINS) { + if (i == ((NPC) oponent).getId()) { + goblin = true; + break; + } + } + if (goblin && RandomFunction.random(0, 3) == 2) { + sendChat(green ? GREEN_MESSAGES[RandomFunction.random(GREEN_MESSAGES.length)] : RED_MESSAGES[RandomFunction.random(RED_MESSAGES.length)]); + } + } + } + + @Override + public void finalizeDeath(Entity killer) { + super.finalizeDeath(killer); + } + + @Override + public int[] getIds() { + return ID; + } + +} diff --git a/Server/src/main/content/region/asgarnia/goblinvillage/handlers/GoblinVillagePopulationListener.kt b/Server/src/main/content/region/asgarnia/goblinvillage/handlers/GoblinVillagePopulationListener.kt new file mode 100644 index 0000000..401d09d --- /dev/null +++ b/Server/src/main/content/region/asgarnia/goblinvillage/handlers/GoblinVillagePopulationListener.kt @@ -0,0 +1,27 @@ +package content.region.asgarnia.goblinvillage.handlers + +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.combat.DeathTask +import core.game.world.map.RegionManager.getLocalNpcs +import org.rs09.consts.Scenery + +class GoblinVillagePopulationListener : InteractionListener{ + override fun defineListeners() { + on(Scenery.SIGNPOST_31301, IntType.SCENERY, "read") { player, node -> + var population = 3 // This covers General Wartface, General Bentnoze and Grubfoot + val npcs = getLocalNpcs(player, 50) // This radius covers more than the goblin village. + // There should be 18 Goblins walking around. + // 10 are within the village walls where the generals are. + // 8 of them are fighting each other on the west of the path to the village. + // Total should be 21. They respawn really fast. + for (n in npcs) { + if (n.name == "Goblin" && !DeathTask.isDead(n)) { + population++ + } + player.dialogueInterpreter.sendPlainMessage(false, "Welcome to Goblin Village.", "Current population: $population") + } + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/goblinvillage/quest/goblindiplomacy/GDiplomacyCutscene.java b/Server/src/main/content/region/asgarnia/goblinvillage/quest/goblindiplomacy/GDiplomacyCutscene.java new file mode 100644 index 0000000..3743a5c --- /dev/null +++ b/Server/src/main/content/region/asgarnia/goblinvillage/quest/goblindiplomacy/GDiplomacyCutscene.java @@ -0,0 +1,895 @@ +package content.region.asgarnia.goblinvillage.quest.goblindiplomacy; + +import content.data.Quests; +import core.game.component.Component; +import core.game.node.entity.player.link.emote.Emotes; +import core.game.activity.ActivityManager; +import core.game.activity.ActivityPlugin; +import core.game.activity.CutscenePlugin; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.Entity; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.map.build.DynamicRegion; +import core.game.world.map.path.Pathfinder; +import core.game.world.repository.Repository; +import core.game.world.update.flag.context.Animation; +import core.net.packet.PacketRepository; +import core.net.packet.context.CameraContext; +import core.net.packet.context.CameraContext.CameraType; +import core.net.packet.out.CameraViewPacket; +import core.tools.RandomFunction; +import core.tools.StringUtils; +import core.game.dialogue.FacialExpression; + +import static core.api.ContentAPIKt.*; + + +/** + * Represents the goblin diplomacy cutscene plugin. + * @author 'Vexia + * @version 1.0 + */ +public final class GDiplomacyCutscene extends CutscenePlugin { + + /** + * Constructs a new {@code GDiplomacyCutscene} {@code Object}. + */ + public GDiplomacyCutscene() { + this(null); + } + + /** + * Constructs a new {@code GDiplomacyCutscene} {@code Object}. + */ + public GDiplomacyCutscene(final Player player) { + super("Goblin Diplomacy Cutscene"); + this.player = player; + } + + @Override + public boolean start(final Player player, final boolean login, Object... args) { + Quest quest = player.getQuestRepository().getQuest(Quests.GOBLIN_DIPLOMACY); + final NPC grubfoot = NPC.create(quest.getStage(player) == 10 ? 4495 : quest.getStage(player) == 20 ? 4497 : quest.getStage(player) == 30 ? 4498 : 4496, getBase().transform(10, 55, 0)); + grubfoot.setWalks(false); + npcs.add(grubfoot); + npcs.add(NPC.create(4494, getBase().transform(14, 55, 0))); + npcs.add(NPC.create(4493, getBase().transform(14, 56, 0))); + for (NPC npc : npcs) { + npc.setDirection(Direction.WEST); + npc.init(); + } + return super.start(player, login, args); + } + + @Override + public void open() { + player.getDialogueInterpreter().open(4494, npcs.get(1), this); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.POSITION, player.getLocation().getX() + 4, player.getLocation().getY() + 1, 390, 1, 100)); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.ROTATION, player.getLocation().getX() + 2, player.getLocation().getY(), 390, 1, 100)); + } + + @Override + public Location getSpawnLocation() { + return null; + } + + @Override + public void configure() { + region = DynamicRegion.create(11830); + setRegionBase(); + registerRegion(region.getId()); + } + + @Override + public void register() { + new GoblinGeneralDialogue().init(); + } + + @Override + public Location getStartLocation() { + return getBase().transform(13, 57, 0); + } + + @Override + public ActivityPlugin newInstance(Player p) throws Throwable { + return new GDiplomacyCutscene(p); + } + + /** + * Represents the dialogue which handles the dialogues between the goblin + * generals. + * @author 'Vexia + * @version 1.0 + */ + public static final class GoblinGeneralDialogue extends DialoguePlugin { + + /** + * Represents an array of dialogues to send. + */ + private static final String[][] DIALOGUES = new String[][] { { "@base (@color) armour best.", "@other No it has to be @ocolor.", "@base Go away human, we busy." }, { "@base I tell all goblins in village to wear @color armour now!", "@other They not listen to you! I already tell them wear @ocolor /n armour!", "@base They listen to me not you! They know me bigger /n general!", "@other Me bigger general! They listen to me!", "@base Human! What colour armour they wearing out there?", "@player Half of them wearing red and half of them green.", "@base Shut up human! They wearing green armour really! /n Human lying because he scared of you!", "@other Human scared of me not you! THen you think me /n bigger general!", "@base What? Me mean...", "@base Shut up! Me bigger general!" }, { "@base All goblins should wear @color armour!", "@other Not @ocolor! @ocolor make you look fat.", "@base Everything make YOU look fat!", "@other Shut up!", "@base Fatty!", "@other SHUT UP!", "@base Even this human think you look fat! Don't you, human?", "@player Um...", "@player No, he doesn't look fat.", "@base Shut up human! @oname fat and human stupid!", "@other Shut up @bname" }, { "@other (@ocolor) armour best.", "@base No no @color every time.", "@other Go away human, we busy." }, }; + + /** + * Represents the cutscene. + */ + private GDiplomacyCutscene cutscene; + + /** + * Represents the instanced quest. + */ + private Quest quest; + + /** + * Represents the other general. + */ + private NPC other; + + /** + * Represents the grubfoot npc. + */ + private NPC grubfoot; + + /** + * Represents the dialogue index we're at. + */ + private int dialIndex; + + /** + * Represents the dialogue index we're at. + */ + private int index; + + /** + * The current grubfoot type. + */ + private GrubFoot type; + + /** + * Constructs a new {@code GeneralWartface} {@code Object}. + */ + public GoblinGeneralDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code GeneralWartface} {@code Object}. + * @param player the player. + */ + public GoblinGeneralDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new GoblinGeneralDialogue(player); + } + + @Override + public Component npc(String... messages) { + return npc(FacialExpression.OLD_NORMAL,messages); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + type = GrubFoot.forConfig(player); + dialIndex = RandomFunction.random(DIALOGUES.length); + other = Repository.findNPC(npc.getId() == 4494 ? 4493 : 4494); + quest = player.getQuestRepository().getQuest(Quests.GOBLIN_DIPLOMACY); + if(player.getQuestRepository().getQuest(Quests.THE_LOST_TRIBE).getStage(player) == 43){ + player("Have you heard of the Dorgeshuun?"); + stage = 5000; + return true; + } + switch (quest.getStage(player)) { + case 100: + npc("Now you've solved out argument we gotta think of", "something else to do."); + stage = 0; + break; + default: + if (args.length >= 2) { + setUpCutScene(args); + return true; + } else { + parseDialogue(DIALOGUES[dialIndex]); + return true; + } + } + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + if(stage >= 5000){ + switch (stage){ + case 5000: + npc("Dorgeshuun? That old goblin legend. Lost tribe."); + stage++; + break; + case 5001: + sendNormalDialogue(other, FacialExpression.OLD_NORMAL,"In time of much war there many tribes. Big High War","God send Dorgesh-tribe to fight beardy short-people","in mountains."); + stage++; + break; + case 5002: + npc("No no, he send them to fight tall people with biting","blades, that what I hear."); + stage++; + break; + case 5003: + sendNormalDialogue(other,FacialExpression.OLD_NORMAL,"It was beardy short-people, that how legend go."); + stage++; + break; + case 5004: + options("Make up your minds!","Do you want me to decide for you again?","It doesn't really matter."); + stage++; + break; + case 5005: + switch(buttonId){ + case 1: + player("Make up your minds!"); + stage = 5010; + break; + case 2: + player("Do you want me to decide for you again?"); + stage = 5020; + break; + case 3: + player("It doesn't really matter. So what happened to them?"); + stage = 5030; + break; + } + break; + case 5010: + npc("It was tall people! That what old storyteller say!"); + stage++; + break; + case 5011: + sendNormalDialogue(other,FacialExpression.OLD_NORMAL,"No, beardy-short-people. That how legend always go,","stupid."); + stage++; + break; + case 5012: + npc("You stupid!"); + stage = 5004; + break; + case 5020: + npc("That most stupid idea yet! If it happen it either happen","one way or the other. You can't just decide whice."); + stage++; + break; + case 5021: + sendNormalDialogue(other,FacialExpression.OLD_NORMAL,"Yeah even goblins know that."); + stage = 5004; + break; + case 5030: + sendNormalDialogue(other,FacialExpression.OLD_NORMAL,"Well, they say, 'We not want to fight,' so god punish","them."); + stage++; + break; + case 5031: + npc("That silly. No goblin ever say that."); + stage++; + break; + case 5032: + sendNormalDialogue(other,FacialExpression.OLD_NORMAL,"What happen then?"); + stage++; + break; + case 5033: + npc("They lose battle, that why god punish them."); + stage++; + break; + case 5034: + sendNormalDialogue(other,FacialExpression.OLD_NORMAL,"Ha ha! If they lost battle they all be dead!"); + stage++; + break; + case 5035: + npc("No no, they losing so they run away, and Big High","War God punish them for running away."); + stage++; + break; + case 5036: + player("Well, either way they refused to fight."); + stage++; + break; + case 5037: + npc("Yeah I suppose so."); + stage++; + break; + case 5038: + npc("Anyway, then Big High War God punish them. He turn","their insides to stone."); + stage++; + break; + case 5039: + sendNormalDialogue(other,FacialExpression.OLD_NORMAL,"Ha ha ha! That silly!"); + stage++; + break; + case 5040: + npc("Not as silly as green armour! What happen then?"); + stage++; + break; + case 5041: + sendNormalDialogue(other,FacialExpression.OLD_NORMAL,"He put them inside stone! Big hole open in ground and","they all go into cave."); + stage++; + break; + case 5042: + npc("That not punishment! Caves nice and cool."); + stage++; + break; + case 5043: + sendNormalDialogue(other,FacialExpression.OLD_NORMAL,"But then he close cave so they not get out!","You not want to stay in cave all the time."); + stage++; + break; + case 5044: + player("Well I found a brooch underground, and I looked up","the symbol and it was the symbol of the Dorgeshuun."); + stage++; + break; + case 5045: + npc("That not look like goblin brooch."); + stage++; + break; + case 5046: + sendNormalDialogue(other,FacialExpression.OLD_NORMAL,"Goblins not wear jewellery."); + stage++; + break; + case 5047: + npc("Well if it is Dorgeshuun tribe they not know who won big","wars. You should greet them with goblin victory dance!"); + stage++; + break; + case 5048: + sendNormalDialogue(other,FacialExpression.OLD_NORMAL,"No no, you greet them with goblin tribal bow."); + stage++; + break; + case 5049: + npc("Doing bow make you look like a wimp."); + stage++; + break; + case 5050: + sendNormalDialogue(other,FacialExpression.OLD_NORMAL,"It how tribes greet each other in old days."); + stage++; + break; + case 5051: + npc("Only if they wimpy tribes! Goblin salute strong!"); + stage++; + break; + case 5052: + player("Well, why not show me both greetings?"); + stage++; + break; + case 5053: + sendNormalDialogue(other,FacialExpression.OLD_NORMAL,"That good idea. Watch."); + stage++; + break; + case 5054: + interpreter.sendDialogue("The generals show you the goblin bow and","goblin salute emotes."); + player.setAttribute("/save:tlt-goblin-emotes",true); + player.getEmoteManager().unlock(Emotes.GOBLIN_BOW); + player.getEmoteManager().unlock(Emotes.GOBLIN_SALUTE); + setVarbit(player, 532, 7, true); + player.getQuestRepository().getQuest(Quests.THE_LOST_TRIBE).setStage(player,44); + stage++; + break; + case 5055: + player("Thanks."); + stage++; + break; + case 5056: + npc("Bye then."); + stage++; + break; + case 5057: + sendNormalDialogue(other,FacialExpression.OLD_NORMAL,"Bye."); + stage++; + break; + case 5058: + player("Bye."); + stage++; + break; + case 5059: + end(); + break; + } + return true; + } + switch (quest.getStage(player)) { + case 0: + handleStart(buttonId); + break; + case 10: + case 20: + case 30: + handleDefault(buttonId); + break; + case 100: + switch (stage) { + case 0: + interpreter.sendDialogues(other, null, "Yep we bored now."); + stage = 1; + break; + case 1: + end(); + break; + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { /** wartface */ + 4494, /** bentnoze */ + 4493 }; + } + + /** + * Method used to parse the dialogue. + * @param dialogue the dialogue. + */ + public void parseDialogue(String[] dialogue) { + if (index == DIALOGUES.length - 1) { + if (quest.getStage(player) == 0) { + interpreter.sendOptions("Select an Option", "Why are you arguing about the colour of your armour?", "Wouldn't you prefer peace?", "Do you want me to pick an armour colour for you?"); + stage = 1; + } else { + if (!player.getInventory().containsItem(type.getMail())) { + options("Why are you arguing about the colour of your armour?", "Wouldn't you prefer peace?", "Where am I meant to get " + type.name().toLowerCase() + " amour?"); + stage = 1; + } else { + options("Why are you arguing about the colour of your armour?", "Wouldn't you prefer peace?", "I have some " + type.name().toLowerCase() + " armour here."); + stage = 1; + } + } + return; + } + final Entity entity = getSpeaker(dialogue[index]); + final String[] lines = getLines(dialogue[index]); + String line = null; + for (int i = 0; i < lines.length; i++) { + line = (String) lines[i]; + line = ((String) line).replace("(@color)", StringUtils.formatDisplayName(getColor((String) line))); + line = ((String) line).replace("(@ocolor)", StringUtils.formatDisplayName(getOtherColor((String) line))); + line = ((String) line).replace("@color", getColor((String) line)); + line = ((String) line).replace("@ocolor", getOtherColor((String) line)); + line = ((String) line).replace("@player", "").replace("@base", "").replace("@other", "").trim(); + line = ((String) line).trim(); + lines[i] = line; + } + interpreter.sendDialogues(entity, null, lines); + index++; + } + + /** + * Handles the default options for each stage. + */ + public void defaultOptions(int buttonId) { + switch (stage) { + case 10: + npc("We decide to celebrate goblin new century by changing", "colour of our armour, brown get boring after a bit.", "We want change."); + stage = 11; + break; + case 11: + interpreter.sendDialogues(other, null, "Problem is they want different change to us."); + stage = 12; + break; + case 12: + end(); + break; + case 20: + interpreter.sendDialogues(other, null, "Yeah peace is good as long as it peace wearing my", "armour."); + stage = 21; + break; + case 21: + npc("But his color too ugly. Nearly make you look", "like an ugly goblin!"); + stage = 22; + break; + case 22: + end(); + break; + case 30: + npc("Well first you get goblin armour..."); + stage = 31; + break; + case 31: + interpreter.sendDialogues(other, null, "...And then you dye it " + type.name().toLowerCase() + "!"); + stage = 32; + break; + case 32: + npc("Even human should be able to work that out!"); + stage = 33; + break; + case 33: + interpreter.sendOptions("Select an Option", "But where do I get goblin armour?", "But where do I get dye?"); + stage = 34; + break; + case 34: + switch (buttonId) { + case 1: + player("But where do I get goblin armour?"); + stage = 35; + break; + case 2: + player("But where do I get dye?"); + stage = 38; + break; + } + break; + case 35: + npc("There some spare armour around village somewhere.", "You can take that."); + stage = 36; + break; + case 36: + interpreter.sendDialogues(other, null, "It in crates somewhere. Can't remember which crates", "now."); + stage = 37; + break; + case 37: + end(); + break; + case 38: + interpreter.sendDialogues(other, null, "You go north of here into wilderness. There you find", "many ways to die!"); + stage = 40; + break; + case 40: + player("no, D-Y-E, not D-I-E."); + stage = 41; + break; + case 41: + npc("Stupid " + other.getName() + ", you not know how to spell!"); + stage = 42; + break; + case 42: + interpreter.sendDialogues(other, null, "Shut up " + npc.getName() + "!"); + stage = 43; + break; + case 43: + player("Do you know where I can get dye though?"); + stage = 44; + break; + case 44: + interpreter.sendDialogues(other, null, "Me not know where dye come from."); + stage = 45; + break; + case 45: + player("Well where did you get your red and green dye from?"); + stage = 46; + break; + case 46: + npc("Some goblin or other, he steal it. Say he steal it from", "old witch in Draynor Village."); + stage = 47; + break; + case 47: + interpreter.sendDialogues(other, null, "Maybe you can get more dye from here?"); + stage = 48; + break; + case 48: + end(); + break; + } + } + + /** + * Handles the default started quest dialogue. + * @param buttonId the buttonId. + */ + public void handleDefault(int buttonId) { + if (stage > 99) { + handleFinishDialogues(); + } + switch (stage) { + case 0: + parseDialogue(DIALOGUES[dialIndex]); + break; + case 1: + switch (buttonId) { + case 1: + player("Why are you arguing about the colour of", "your armour?"); + stage = 10; + break; + case 2: + player("Wouldn't you prefer peace?"); + stage = 20; + break; + case 3: + if (!player.getInventory().containsItem(type.getMail())) { + player("Where am I meant to get " + type.name().toLowerCase() + " armour?"); + stage = 30; + } else { + player("I have some " + type.name().toLowerCase() + " armour here."); + stage = 50; + } + break; + } + break; + case 50: + end(); + ActivityManager.start(player, "Goblin Diplomacy Cutscene", false); + break; + case 60: + player.face(grubfoot); + interpreter.sendDialogues(grubfoot, null, "Yes General Wartface sir?"); + Pathfinder.find(grubfoot, npc.getLocation().transform(-1, 0, 0)).walk(grubfoot); + stage = 61; + break; + case 61: + npc("Put on this armour!"); + player.face(npc); + stage = 62; + break; + case 62: + sendGrubFoot(type, 100); + break; + case 39: + end(); + break; + default: + defaultOptions(buttonId); + break; + } + } + + /** + * Sets up the cutscene. + */ + private void setUpCutScene(Object... args) { + player.lock(); + cutscene = (GDiplomacyCutscene) args[1]; + other = cutscene.getNPCS().get(2); + grubfoot = cutscene.getNPCS().get(0); + npc("Grubfoot!"); + player.face(npc); + stage = 60; + } + + /** + * Sends the new grubfoot. + * @param grubFoot the grubfoot. + * @param endStage the end stage. + */ + public void sendGrubFoot(final GrubFoot grubFoot, final int endStage) { + Pathfinder.find(grubfoot, grubfoot.getLocation().transform(-4, 0, 0)).walk(grubfoot); + GameWorld.getPulser().submit(new Pulse(1, player) { + int counter; + + @Override + public boolean pulse() { + switch (++counter) { + case 1: + player.getDialogueInterpreter().sendPlainMessage(true, "Grubfoot goes into the changing room..."); + break; + case 7: + grubfoot.transform(grubFoot.getId()); + grubfoot.getProperties().setTeleportLocation(grubfoot.getLocation().transform(-1, 0, 0)); + player.getPacketDispatch().sendSceneryAnimation(RegionManager.getObject(cutscene.getBase().transform(9, 55, 0)), new Animation(24)); + break; + case 11: + grubfoot.getProperties().setTeleportLocation(grubfoot.getLocation().transform(1, 0, 0)); + player.getPacketDispatch().sendSceneryAnimation(RegionManager.getObject(cutscene.getBase().transform(9, 55, 0)), new Animation(24)); + break; + case 12: + player.getDialogueInterpreter().sendPlainMessage(true, "...And emerges wearing " + type.name().toLowerCase() + " armour."); + break; + case 13: + Pathfinder.find(grubfoot, npc.getLocation().transform(-1, 0, 0)).walk(grubfoot); + break; + case 16: + stage = endStage; + player.faceLocation(grubfoot.getLocation()); + player.getDialogueInterpreter().sendDialogues(grubfoot, null, "What do you think?"); + return true; + } + return false; + } + + }); + } + + /** + * Handles the starting of the quest. + * @param buttonId the buttonId. + */ + private void handleStart(int buttonId) { + switch (stage) { + case 0: + parseDialogue(DIALOGUES[dialIndex]); + break; + case 1: + switch (buttonId) { + case 1: + player("Why are you arguing about the colour of", "your armour?"); + stage = 10; + break; + case 2: + player("Wouldn't you prefer peace?"); + stage = 20; + break; + case 3: + player("Do you want me to pick an armour colour for you?"); + stage = 30; + break; + } + break; + case 30: + npc("Yes as long as you pick " + (npc.getId() == 4494 ? "green" : "red") + "."); + stage = 31; + break; + case 31: + interpreter.sendDialogues(other, null, "No you have to pick " + (npc.getId() == 4493 ? "green" : "red") + "!"); + stage = 32; + break; + case 32: + player("What about a different colour? Not green or red?"); + stage = 33; + break; + case 33: + npc("That would mean me wrong... but at least", "" + other.getName() + " not right!"); + stage = 34; + break; + case 34: + interpreter.sendDialogues(other, null, "Me dunno what that look like. Have to see armour", "before we decide."); + stage = 35; + break; + case 35: + npc("Human! You bring us armour in new colour!"); + stage = 36; + break; + case 36: + interpreter.sendDialogues(other, null, "What colour we try?"); + stage = 37; + break; + case 37: + npc("Orange armour might be good."); + stage = 38; + break; + case 38: + quest.start(player); + interpreter.sendDialogues(other, null, "Yes bring us orange armour."); + stage = 39; + break; + default: + defaultOptions(buttonId); + break; + } + } + + /** + * Handles the finishing dialogues. + */ + private void handleFinishDialogues() { + if (stage == 120) { + if (player.getInventory().remove(type.getMail())) { + quest.setStage(player, quest.getStage(player) + 10); + } + end(); + cutscene.unpause(); + type.setConfig(player); + return; + } + switch (quest.getStage(player)) { + case 10: + switch (stage) { + case 100: + interpreter.sendDialogues(npc, null, "No I don't like that much."); + player.face(npc); + stage++; + break; + case 101: + interpreter.sendDialogues(other, null, "It clashes with skin colour."); + player.face(other); + stage++; + break; + case 102: + interpreter.sendDialogues(npc, null, "We need darker colour, like blue."); + player.face(npc); + stage++; + break; + case 103: + interpreter.sendDialogues(other, null, "Yeah blue might be good."); + player.face(other); + stage++; + break; + case 104: + interpreter.sendDialogues(npc, null, "Human! Get us blue armour!"); + player.face(npc); + stage = 120; + break; + } + break; + case 20: + switch (stage) { + case 100: + interpreter.sendDialogues(other, null, "That not right. Not goblin colour at all."); + player.face(other); + stage++; + break; + case 101: + interpreter.sendDialogues(npc, null, "Goblins wear dark earthy colours like brown."); + player.face(npc); + stage++; + break; + case 102: + interpreter.sendDialogues(other, null, "Yeah brown might be good."); + player.face(other); + stage++; + break; + case 103: + interpreter.sendDialogues(npc, null, "Human! Get us brown armour!"); + player.face(npc); + stage++; + break; + case 104: + interpreter.sendDialogues(player, null, "I thought that was the armour you were changing", "from. Never mind, anything is worth a try."); + stage = 120; + break; + } + break; + case 30: + switch (stage) { + case 100: + interpreter.sendDialogues(npc, null, "That colour quite nice. Me can see myself wearing", "that."); + player.face(npc); + stage++; + break; + case 101: + interpreter.sendDialogues(other, null, "It a deal then. Brown armour it is."); + player.face(other); + stage++; + break; + case 102: + interpreter.sendDialogues(npc, null, "Thank you for sorting out our argument. Take this", "gold bar as reward!"); + npc.face(player); + other.face(player); + stage++; + break; + case 103: + end(); + cutscene.unpause(); + if (player.getInventory().remove(GrubFoot.BROWN.getMail())) { + quest.finish(player); + GrubFoot.BROWN.setConfig(player); + } + break; + } + break; + } + } + + /** + * Gets the speaker of the dialogue. + * @param line the line. + * @return the entity speaker. + */ + public Entity getSpeaker(final String line) { + return line.contains("@player") ? player : line.contains("@base") ? npc : other; + } + + /** + * Gets the color of the base entity. + * @param line the line. + * @return the color. + */ + public String getColor(final String line) { + return npc.getId() == 4494 ? "green" : "red"; + } + + /** + * Gets the other color of the general. + * @param line the line. + * @return the other color. + */ + public String getOtherColor(final String line) { + return other.getId() == 4493 ? "red" : "green"; + } + + /** + * Gets the lines of the dialogue. + * @param line the line. + * @return the lines. + */ + public String[] getLines(final String line) { + return line.split("/n"); + } + } +} diff --git a/Server/src/main/content/region/asgarnia/goblinvillage/quest/goblindiplomacy/GoblinDiplomacy.java b/Server/src/main/content/region/asgarnia/goblinvillage/quest/goblindiplomacy/GoblinDiplomacy.java new file mode 100644 index 0000000..a85d815 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/goblinvillage/quest/goblindiplomacy/GoblinDiplomacy.java @@ -0,0 +1,154 @@ +package content.region.asgarnia.goblinvillage.quest.goblindiplomacy; + +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.plugin.ClassScanner; +import content.data.Quests; + +/** + * Represents the demon slayer quest. + * @author Vexia + * + */ +@Initializable +public class GoblinDiplomacy extends Quest { + /** + * Represents the orange goblin mail. + */ + private static final Item ORANGE_MAIL = new Item(286); + + /** + * Represents the blue goblin mail. + */ + private static final Item BLUE_MAIL = new Item(287); + + /** + * Represents the goblin mail. + */ + private static final Item GOBLIN_MAIL = new Item(288); + + /** + * Represents the gold bar item. + */ + private static final Item GOLD_BAR = new Item(2357); + + /** + * Constructs a new {@Code GoblinDiplomacy} {@Code Object} + */ + public GoblinDiplomacy() { + super(Quests.GOBLIN_DIPLOMACY, 20, 19, 5); + } + + @Override + public Quest newInstance(Object object) { + ClassScanner.definePlugins(new GDiplomacyCutscene(), new GoblinDiplomacyPlugin(), new GrubfootDialogue()); + return this; + } + + @Override + public void drawJournal(Player player, int stage) { + super.drawJournal(player, stage); + switch (stage) { + case 0: + player.getPacketDispatch().sendString(BLUE + "I can start this quest by speaking to " + RED + "Generals Wartface", 275, 4 + 7); + player.getPacketDispatch().sendString(RED + "and Bentnoze " + BLUE + "in the " + RED + " Goblin Village.", 275, 5+ 7); + player.getPacketDispatch().sendString(BLUE + "There are no requirements for this quest.", 275, 6+ 7); + break; + case 10: + line(player, "I spoke to Generals Wartface and Bentnoze in the Goblin", 4+ 7); + line(player, "Village and found that the goblins were on the bring of civil", 5+ 7); + line(player, "war over the colour of their armour. I offered to help the", 6+ 7); + line(player, "generals by finding another colour that they both like.", 7+ 7); + if (player.getInventory().containsItem(ORANGE_MAIL)) { + line(player, BLUE + "I have some " + RED + "Orange Goblin Armour. " + BLUE + "I should show it to the", 9+ 7); + line(player, BLUE + "generals.", 10+ 7); + } else { + line(player, BLUE + "I should bring the goblins some " + RED + "Orange Goblin Armour", 9+ 7); + line(player, BLUE + "Maybe the generals will know where to get some.", 10+ 7); + } + break; + case 20: + line(player, "I spoke to Generals Wartface and Bentnoze in the Goblin", 4+ 7); + line(player, "Village and found that the goblins were on the bring of civil", 5+ 7); + line(player, "war over the colour of their armour. I offered to help the", 6+ 7); + line(player, "generals by finding another colour that they both like.", 7+ 7); + line(player, "I brought the goblins some orange goblin armour, but they", 9+ 7); + line(player, "didn't like it.", 10+ 7); + if (player.getInventory().containsItem(BLUE_MAIL)) { + line(player, BLUE + "I have some " + RED + "Blue Goblin Armour. " + BLUE + "I should show it to the", 12+ 7); + line(player, BLUE + "generals.", 13+ 7); + } else { + line(player, BLUE + "I should bring the goblins s+ 7+ 7);e " + RED + "Blue Goblin Armour", 12+ 7); + line(player, BLUE + "Maybe the generals will know where to get some.", 13+ 7); + } + break; + case 30: + line(player, "I spoke to Generals Wartface and Bentnoze in the Goblin", 4+ 7); + line(player, "Village and found that the goblins were on the bring of civil", 5+ 7); + line(player, "war over the colour of their armour. I offered to help the", 6+ 7); + line(player, "generals by finding another colour that they both like.", 7+ 7); + line(player, "I brought the goblins some orange goblin armour, but they", 9+ 7); + line(player, "didn't like it.", 10+ 7); + line(player, "I brought the goblins some blue goblin armour, but they", 12+ 7); + line(player, "didn't like it.", 13+ 7); + if (player.getInventory().containsItem(GOBLIN_MAIL)) { + line(player, BLUE + "I have some " + RED + "Brown Goblin Armour. " + BLUE + "I should show it to the", 12+ 7); + line(player, BLUE + "generals.", 13+ 7); + } else { + line(player, BLUE + "I should bring the goblins some " + RED + "Brown Goblin Armour", 12+ 7); + line(player, BLUE + "Maybe the generals will know where to get some.", 13+ 7); + } + break; + case 100: + line(player, "I spoke to Generals Wartface and Bentnoze in the Goblin", 4+ 7); + line(player, "Village and found that the goblins were on the bring of civil", 5+ 7); + line(player, "war over the colour of their armour. I offered to help the", 6+ 7); + line(player, "generals by finding another colour that they both like.", 7+ 7); + line(player, "I brought the goblins some orange goblin armour, but they", 9+ 7); + line(player, "didn't like it.", 10+ 7); + line(player, "I brought the goblins some blue goblin armour, but they", 12+ 7); + line(player, "didn't like it.", 13+ 7); + line(player, "Unfortunately the goblins were very stupid, and it turned", 15+ 7); + line(player, "out that they liked the original colour the most. That's goblins", 16+ 7); + line(player, "for you I guess.", 17+ 7); + line(player, "QUEST COMPLETE!", 18+ 7); + break; + } + } + + @Override + public void finish(Player player) { + super.finish(player); + player.getPacketDispatch().sendString("5 Quests Points", 277, 8 + 2); + player.getPacketDispatch().sendString("200 Crafting XP", 277, 9 + 2); + player.getPacketDispatch().sendString("A gold bar", 277, 10 + 2); + player.getPacketDispatch().sendString("You have completed the Goblin Diplomacy Quest!", 277, 2 + 2); + player.getPacketDispatch().sendItemZoomOnInterface(288, 230, 277, 3 + 2); + player.getSkills().addExperience(Skills.CRAFTING, 200); + if (!player.getInventory().add(GOLD_BAR)) { + GroundItemManager.create(GOLD_BAR, player); + } + } + + @Override + public int[] getConfig(Player player, int stage) { + if (stage == 0) { + return new int[] { 62, 0 }; + } + if (stage == 10) { + return new int[] { 62, 1 }; + } else if (stage == 20) { + return new int[] { 62, 4 }; + } else if (stage == 30) { + return new int[] { 62, 5 }; + } else if (stage == 100) { + return new int[] { 62, 6 }; + } + return new int[] { 62, 0 }; + } + +} diff --git a/Server/src/main/content/region/asgarnia/goblinvillage/quest/goblindiplomacy/GoblinDiplomacyPlugin.java b/Server/src/main/content/region/asgarnia/goblinvillage/quest/goblindiplomacy/GoblinDiplomacyPlugin.java new file mode 100644 index 0000000..a412b18 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/goblinvillage/quest/goblindiplomacy/GoblinDiplomacyPlugin.java @@ -0,0 +1,267 @@ +package content.region.asgarnia.goblinvillage.quest.goblindiplomacy; + +import core.cache.def.impl.ItemDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.OptionHandler; +import core.game.interaction.UseWithHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.world.GameWorld; +import core.plugin.Plugin; +import core.plugin.ClassScanner; +import core.tools.StringUtils; + +/** + * Represents the plugin used to handle node interactions related to goblin + * diplomacy. + * @author Vexia + * @version 1.0 + */ +public final class GoblinDiplomacyPlugin extends OptionHandler { + + /** + * Represents the goblin mail item. + */ + private static final Item GOBLIN_MAIL = new Item(288); + + /** + * Represents the creates item. + */ + private static final int[] CRATES = new int[] { 16557, 16561, 16560, 16559 }; + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ItemDefinition.forId(288).getHandlers().put("option:wear", this); + for (int object : CRATES) { + SceneryDefinition.forId(object).getHandlers().put("option:search", this); + } + for (GoblinMailPlugin.GoblinMail mail : GoblinMailPlugin.GoblinMail.values()) { + ItemDefinition.forId(mail.getProduct().getId()).getHandlers().put("option:wear", this); + } + ClassScanner.definePlugin(new GoblinMailPlugin()); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + int id = node instanceof Item ? ((Item) node).getId() : ((Scenery) node).getId(); + switch (option) { + case "wear": + player.getPacketDispatch().sendMessage("That armour is to small for a human."); + break; + } + switch (id) { + case 16559: + case 16557: + case 16561: + case 16560: + if (player.getAttribute("crate:" + id, 0) < GameWorld.getTicks()) { + player.setAttribute("crate:" + id, GameWorld.getTicks() + 500); + if (!player.getInventory().add(GOBLIN_MAIL)) { + GroundItemManager.create(GOBLIN_MAIL, player); + } + player.getDialogueInterpreter().sendItemMessage(GOBLIN_MAIL.getId(), "You find some goblin armour."); + return true; + } + player.getPacketDispatch().sendMessage("You search the crate but find nothing."); + break; + } + return true; + } + + @Override + public boolean isWalk() { + return false; + } + + @Override + public boolean isWalk(final Player player, final Node node) { + return !(node instanceof Item); + } + + /** + * Represents the goblin mail plugin. + * @author 'Vexia + * @version 1.0 + */ + public static final class GoblinMailPlugin extends UseWithHandler { + + /** + * Constructs a new {@code GoblinMailPlugin} {@code Object}. + */ + public GoblinMailPlugin() { + super(1763, 1769, 1765, 1771, 1767, 1773, 4622, 11808, 6955); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(288, ITEM_TYPE, this); + int[] ids = new int[] { 1763, 1769, 1765, 1771, 1767, 1773, 4622, 11808, 6955 }; + for (int i : ids) { + addHandler(i, ITEM_TYPE, this); + } + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + final GoblinMail mail = GoblinMail.forItem(event.getUsedItem()); + final Dyes dye = Dyes.forItem(event.getUsedItem(), event.getBaseItem()); + if (dye != null && (event.getUsedItem().getId() != 288 || event.getBaseItem().getId() != 288)) { + handleDyeMix(player, dye, event); + return true; + } + if (mail == null || (event.getUsedItem().getId() != 288 && event.getBaseItem().getId() != 288)) { + return false; + } + if (player.getInventory().remove(mail.getDye(), event.getBaseItem())) { + player.getInventory().add(mail.getProduct()); + player.getPacketDispatch().sendMessage("You dye the goblin armour " + mail.name().toLowerCase() + "."); + } + return true; + } + + /** + * Handles the mixing of dyes. + * @param player the player. + * @param dye the dye. + * @param event the event. + */ + public void handleDyeMix(final Player player, Dyes dye, NodeUsageEvent event) { + if (dye == null) { + player.getPacketDispatch().sendMessage("Those dyes dont mix together."); + return; + } + if (player.getInventory().remove(dye.getMaterials())) { + player.getInventory().add(dye.getProduct()); + } + player.getPacketDispatch().sendMessage("You mix the two dyes and make " + (StringUtils.isPlusN(dye.getProduct().getName().toLowerCase().replace("dye", "").trim()) ? "an " : "a ") + dye.getProduct().getName().toLowerCase().replace("dye", "").trim() + " one."); + + } + + /** + * Represents the goblin mail. + * @author 'Vexia + */ + public enum GoblinMail { + RED(new Item(1763), new Item(9054)), ORANGE(new Item(1769), new Item(286)), YELLOW(new Item(1765), new Item(9056)), GREEN(new Item(1771), new Item(9057)), BLUE(new Item(1767), new Item(287)), PURPLE(new Item(1773), new Item(9058)), BLACK(new Item(4622), new Item(9055)), WHITE(new Item(11808), new Item(11791)), PINK(new Item(6955), new Item(9059)); + + /** + * Represents the dye needed. + */ + private final Item dye; + + /** + * Represents the product. + */ + private final Item product; + + /** + * Constructs a new {@code GoblinMailPlugin} {@code Object}. + * @param dye the dye. + * @param product the product. + */ + GoblinMail(Item dye, Item product) { + this.dye = dye; + this.product = product; + } + + /** + * Gets the dye. + * @return The dye. + */ + public Item getDye() { + return dye; + } + + /** + * Gets the product. + * @return The product. + */ + public Item getProduct() { + return product; + } + + /** + * Method used to get the goblin mail. + * @param item the item. + * @return the goblin mail. + */ + public static GoblinMail forItem(final Item item) { + for (GoblinMail mail : GoblinMail.values()) { + if (mail.getDye().getId() == item.getId()) { + return mail; + } + } + return null; + } + } + + /** + * Represents the dye types. + * @author 'Vexia + */ + public static enum Dyes { + ORANGE(new Item(1769), new Item(1763), new Item(1765)), + GREEN(new Item(1771), new Item(1765), new Item(1767)), + PURPLE(new Item(1773), new Item(1767), new Item(1763)); + + /** + * Constructs a new {@code MixDyePlugin} {@code Object}. + * @param product the product. + * @param materials the materials. + */ + Dyes(Item product, Item... materials) { + this.product = product; + this.materials = materials; + } + + /** + * Represents the product item. + */ + private final Item product; + + /** + * Represents the materials. + */ + private final Item[] materials; + + /** + * Gets the product. + * @return The product. + */ + public Item getProduct() { + return product; + } + + /** + * Gets the materials. + * @return The materials. + */ + public Item[] getMaterials() { + return materials; + } + + /** + * Method used to get the dye by item. + * @param item the item. + * @param second the second. + * @return the dye. + */ + public static Dyes forItem(final Item item, final Item second) { + for (Dyes dye : Dyes.values()) { + if (dye.getMaterials()[0].getId() == item.getId() && dye.getMaterials()[1].getId() == second.getId() || dye.getMaterials()[0].getId() == second.getId() && dye.getMaterials()[1].getId() == item.getId()) { + return dye; + } + } + return null; + } + } + + } +} diff --git a/Server/src/main/content/region/asgarnia/goblinvillage/quest/goblindiplomacy/GrubFoot.java b/Server/src/main/content/region/asgarnia/goblinvillage/quest/goblindiplomacy/GrubFoot.java new file mode 100644 index 0000000..af5178b --- /dev/null +++ b/Server/src/main/content/region/asgarnia/goblinvillage/quest/goblindiplomacy/GrubFoot.java @@ -0,0 +1,92 @@ +package content.region.asgarnia.goblinvillage.quest.goblindiplomacy; + +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +import static core.api.ContentAPIKt.*; + +/** + * Represents a grub foot. + * @author Vexia + */ +public enum GrubFoot { + NORMAL(4495, 1, new Item(288)), ORANGE(4497, 4, new Item(286)), BLUE(4498, 5, new Item(287)), BROWN(4496, 6, new Item(288)); + + /** + * The id. + */ + private final int id; + + /** + * The config value. + */ + private final int value; + + /** + * The goblin mail. + */ + private final Item mail; + + /** + * Constructs a new {@code GrubFoot} {@code Object}. + * @param id the id. + * @param value the value. + * @param mail the mail. + */ + private GrubFoot(int id, int value, Item mail) { + this.id = id; + this.value = value; + this.mail = mail; + } + + /** + * Gets the grub foot for the config. + * @param player the player. + * @return the grub foot. + */ + public static GrubFoot forConfig(final Player player) { + int config = getVarp(player, 62); + for (GrubFoot foot : values()) { + if (foot.getValue() == config) { + if (foot.ordinal() + 1 >= values().length) { + return BROWN; + } + return values()[foot.ordinal() + 1]; + } + } + return NORMAL; + } + + /** + * Sets the config value. + * @param player the player. + */ + public void setConfig(Player player) { + setVarp(player, 62, value); + } + + /** + * Gets the id. + * @return The id. + */ + public int getId() { + return id; + } + + /** + * Gets the value. + * @return The value. + */ + public int getValue() { + return value; + } + + /** + * Gets the mail. + * @return The mail. + */ + public Item getMail() { + return mail; + } + +} diff --git a/Server/src/main/content/region/asgarnia/goblinvillage/quest/goblindiplomacy/GrubfootDialogue.java b/Server/src/main/content/region/asgarnia/goblinvillage/quest/goblindiplomacy/GrubfootDialogue.java new file mode 100644 index 0000000..ca562e9 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/goblinvillage/quest/goblindiplomacy/GrubfootDialogue.java @@ -0,0 +1,167 @@ +package content.region.asgarnia.goblinvillage.quest.goblindiplomacy; + +import content.data.Quests; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; + +/** + * Represents the grub foot dialogue. + * @author 'Vexia + * @date 28/12/2013 + */ +public final class GrubfootDialogue extends DialoguePlugin { + + /** + * Represents the quest instance. + */ + private Quest quest; + + /** + * Constructs a new {@code GrubfootDialogue} {@code Object}. + */ + public GrubfootDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code GrubfootDialogue} {@code Object}. + * @param player the player. + */ + public GrubfootDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new GrubfootDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + quest = player.getQuestRepository().getQuest(Quests.GOBLIN_DIPLOMACY); + switch (quest.getStage(player)) { + case 100: + npc("Me lonely."); + stage = 0; + break; + case 30: + npc("Me not like this blue colour."); + stage = 0; + break; + case 20: + npc("Me not like this orange armour. Make me look like that", "thing."); + stage = 0; + break; + default: + npc("Grubfoot wear red armour! Grubfoot wear green", "armour!"); + stage = 0; + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (quest.getStage(player)) { + case 100: + switch (stage) { + case 0: + player("Why?"); + stage = 1; + break; + case 1: + npc("Other goblins in village follow either General Wartface", "or General Bentnoze. Me try to follow both but then", "me get left out of both groups."); + stage = 2; + break; + case 2: + interpreter.sendDialogues(4493, null, "Shut up Grubfoot!"); + stage = 3; + break; + case 3: + end(); + break; + } + break; + case 30: + switch (stage) { + case 0: + player("Why not?"); + stage = 1; + break; + case 1: + npc("Me not know. It just make me feel..."); + stage = 2; + break; + case 2: + player("Makes you feel blue?"); + stage = 3; + break; + case 3: + npc("Makes me feel kinda of sad."); + stage = 4; + break; + case 4: + interpreter.sendDialogues(4493, null, "Shut up Grubfoot!"); + stage = 5; + break; + case 5: + end(); + break; + } + break; + case 20: + switch (stage) { + case 0: + player("Look like what thing?"); + stage = 1; + break; + case 1: + npc("That fruit thing. The one that orange. What it called?"); + stage = 2; + break; + case 2: + player("An orange?"); + stage = 3; + break; + case 3: + npc("That right. This armour make me look same colour as", "orange-fruit."); + stage = 4; + break; + case 4: + interpreter.sendDialogues(4493, null, "Shut up Grubfoot!"); + stage = 5; + break; + case 5: + end(); + break; + } + break; + default: + switch (stage) { + case 0: + npc("Why they not make up their minds?"); + stage = 1; + break; + case 1: + interpreter.sendDialogues(4493, null, "Shut up Grubfoot!"); + stage = 2; + break; + case 2: + end(); + break; + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 4495, 4497, 4498, 4496 }; + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/handlers/CraftingGuildListeners.kt b/Server/src/main/content/region/asgarnia/handlers/CraftingGuildListeners.kt new file mode 100644 index 0000000..32059ef --- /dev/null +++ b/Server/src/main/content/region/asgarnia/handlers/CraftingGuildListeners.kt @@ -0,0 +1,46 @@ +package content.region.asgarnia.handlers + +import content.global.skill.crafting.TanningProduct +import core.api.* +import core.game.interaction.IntType +import core.game.node.entity.skill.Skills +import core.game.world.map.Location +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery +import content.region.asgarnia.dialogue.TheDoorDialogues +import core.game.interaction.InteractionListener + +/** + * @author bushtail, Player Name + */ + +class CraftingGuildListeners : InteractionListener { + override fun defineListeners() { + on(Scenery.GUILD_DOOR_2647, IntType.SCENERY, "open") { player, door -> + if (player.location == Location.create(2933, 3289, 0)) { + if (hasLevelStat(player, Skills.CRAFTING, 40)) { + if (anyInEquipment(player, Items.BROWN_APRON_1757, Items.CRAFTING_CAPE_9780, Items.CRAFTING_CAPET_9781)) { + openDialogue(player, TheDoorDialogues(0)) + core.game.global.action.DoorActionHandler.handleAutowalkDoor(player, door.asScenery()) + return@on true + } else { + openDialogue(player, TheDoorDialogues(1)) + return@on false + } + } else { + openDialogue(player, TheDoorDialogues(2)) + return@on false + } + } else { + core.game.global.action.DoorActionHandler.handleAutowalkDoor(player, door.asScenery()) + return@on true + } + } + + on(NPCs.TANNER_804, IntType.NPC, "trade") { player, node -> + TanningProduct.open(player, node.id) + return@on true + } + } +} diff --git a/Server/src/main/content/region/asgarnia/handlers/WineOfZamorakInteraction.kt b/Server/src/main/content/region/asgarnia/handlers/WineOfZamorakInteraction.kt new file mode 100644 index 0000000..d908028 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/handlers/WineOfZamorakInteraction.kt @@ -0,0 +1,28 @@ +package content.region.asgarnia.handlers + +import core.game.node.item.GroundItem +import core.game.world.map.RegionManager +import org.rs09.consts.Items +import core.game.global.action.PickupHandler +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +class WineOfZamorakInteraction : InteractionListener { + + override fun defineListeners() { + on(Items.WINE_OF_ZAMORAK_245, IntType.GROUNDITEM,"take"){ player, wine -> + if(player.location.regionId != 11574){ + PickupHandler.take(player, wine as GroundItem) + return@on true + } + val npcs = RegionManager.getLocalNpcs(player) + for (n in npcs) { + if (n.id == 188) { + n.sendChat("Hands off zamorak's wine!") + n.properties.combatPulse.attack(player) + } + } + return@on true + } + } +} diff --git a/Server/src/main/content/region/asgarnia/mudskipperpoint/MudSkipperPointListeners.kt b/Server/src/main/content/region/asgarnia/mudskipperpoint/MudSkipperPointListeners.kt new file mode 100644 index 0000000..eed56b4 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/mudskipperpoint/MudSkipperPointListeners.kt @@ -0,0 +1,151 @@ +package content.region.asgarnia.mudskipperpoint + +import content.global.skill.slayer.MogreNPC +import content.region.asgarnia.mudskipperpoint.dialogue.SkippyBootDialogue +import content.region.asgarnia.mudskipperpoint.dialogue.SkippyBucketDialogue +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.impl.Projectile +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import core.plugin.Initializable +import core.tools.RandomFunction +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery +import org.rs09.consts.Vars + +@Initializable +class MudSkipperPointListeners : InteractionListener { + + companion object { + private val MESSAGES = arrayOf( + "Da boom-boom kill all da fishies!", + "I smack you good!", + "Smash stupid human!", + "Tasty human!", + "Human hit me on the head!", + "I get you!", + "Human scare all da fishies!" + ) + + private val FISHING_SPOTS = intArrayOf( + Scenery.OMINOUS_FISHING_SPOT_10087, + Scenery.OMINOUS_FISHING_SPOT_10088, + Scenery.OMINOUS_FISHING_SPOT_10089 + ) + } + + private fun handleExplosives(player: Player, explosives: Item, target: Location): Boolean{ + // Check if the player has unlocked the ability to summon Mogres + if (getVarbit(player, Vars.VARBIT_MINI_QUEST_MOGRE) != SkippyBucketDialogue.DONE_QUEST){ + sendDialogueLines(player, "Sinister as that fishing spot is, why would I want to", "explode it?") + return false + } + val distance = player.location.getDistance(target) + if (distance < 5){ + //too close + sendPlayerDialogue(player, "If this thing explodes, I think I should stand a liiiiitle further away.") + return false + } + if (distance > 14){ + // too far + sendPlayerDialogue(player, "I can't throw that far.") + return false + } + removeItem(player, explosives.id) + animate(player, Animation(385)) // Throw the vial + sendMessage(player, "You hurl the shuddering vial into the water...") + val projectile = Projectile.create(player, null, 49, 30, 20, 30, Projectile.getSpeed(player, target.location)) + projectile.endLocation = target.location + projectile.send() + + val delay = (2+ distance * 0.5).toInt() + queueScript(player, delay){ + val mogre = MogreNPC() + val xOffset = (player.location.x - target.location.x) % 2 + val yOffset = (player.location.y - target.location.y) % 2 + mogre.location = Location.create(target.location.x + xOffset, target.location.y + yOffset) + mogre.init() + mogre.moveStep() + mogre.isRespawn = false + mogre.attack(player) + registerHintIcon(player, mogre) + mogre.sendChat(MESSAGES[RandomFunction.random(MESSAGES.size)]) + if (explosives.id == Items.SUPER_FISHING_EXPLOSIVE_12633){ + impact(mogre, 15) + } + mogre.graphics(Graphics(68)) + sendMessage(player, "...and a Mogre appears!") + return@queueScript stopExecuting(player) + } + return true + } + + private fun soberSkippy(player: Player): Boolean { + if (getVarbit(player, Vars.VARBIT_MINI_QUEST_MOGRE) > SkippyBucketDialogue.DRUNK){ + sendDialogue(player, "I think he's sober enough. And I don't want to use another bucket of water.") + return false + } + else{ + if (hasAnItem(player, Items.BUCKET_OF_WATER_1929).exists()) { + openDialogue(player, SkippyBucketDialogue()) + return true + } + else{ + sendDialogue(player, "You know, I could shock him out of it if I could find some cold water...") + return false + } + } + } + + override fun defineListeners() { + + onUseWith(IntType.SCENERY, Items.FISHING_EXPLOSIVE_6664, *FISHING_SPOTS) { player, used, with -> + handleExplosives(player, used.asItem(), with.location) + } + + onUseWith(IntType.SCENERY, Items.SUPER_FISHING_EXPLOSIVE_12633, *FISHING_SPOTS) { player, used, with -> + handleExplosives(player, used.asItem(), with.location) + } + + on(FISHING_SPOTS, IntType.SCENERY, "Lure", "Bait") { player, _ -> + sendMessage(player, "Something seems to have scared all the fishes away...") + return@on true + } + + on(Scenery.SIGNPOST_10090, IntType.SCENERY, "read") { player, _ -> + setInterfaceText(player, "Mudskipper Point.", 220, 2) + setInterfaceText(player, "WARNING! BEWARE OF THE MUDSKIPPERS!", 220, 4) + openInterface(player, 220) + return@on true + } + + // For some reason the 2795 wrapper does not work for sober-up + on(intArrayOf(NPCs.SKIPPY_2796, NPCs.SKIPPY_2797, NPCs.SKIPPY_2798, NPCs.SKIPPY_2799), + IntType.NPC, "sober-up") { player, _ -> + return@on soberSkippy(player) + } + + onUseWith(IntType.NPC, Items.BUCKET_OF_WATER_1929, NPCs.SKIPPY_2795) { player, _, _ -> + return@onUseWith soberSkippy(player) + } + + onUseWith(IntType.NPC, Items.FORLORN_BOOT_6663, NPCs.SKIPPY_2795){ player, _, _ -> + openDialogue(player, SkippyBootDialogue()) + return@onUseWith true + } + } + + override fun defineDestinationOverrides() { + + // Don't run towards the fishing spots when trying to lure or bait or throw explosives + setDest(IntType.SCENERY, FISHING_SPOTS, "Lure", "Bait", "use"){ entity, _ -> + return@setDest entity.location + } + } +} diff --git a/Server/src/main/content/region/asgarnia/mudskipperpoint/dialogue/SkippyDialogue.kt b/Server/src/main/content/region/asgarnia/mudskipperpoint/dialogue/SkippyDialogue.kt new file mode 100644 index 0000000..2106d68 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/mudskipperpoint/dialogue/SkippyDialogue.kt @@ -0,0 +1,267 @@ +package content.region.asgarnia.mudskipperpoint.dialogue + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.RandomFunction +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Vars + + +@Initializable +class SkippyDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, SkippyBucketDialogue(0, getVarbit(player, Vars.VARBIT_MINI_QUEST_MOGRE))) + return true + } + + + override fun getIds(): IntArray { + return intArrayOf(NPCs.SKIPPY_2795) + } + +} + + +class SkippyBucketDialogue(override var stage: Int = 0, val questStage: Int = 0) : DialogueFile() { + + companion object{ + // Skippy will progress through these stages as you help him + const val DRUNK = 0 + const val TENDER = 1 + const val HUNGOVER = 2 + const val DONE_QUEST = 3 + + // Dialogue branches + const val THROW_WATER = 10 + const val DRUNK_RAMBLING = 30 + const val CRAZY_PEOPLE = 40 + const val WHO_ARE_THEY = 50 + // Tea state + const val LEARN_RECIPE = 170 + const val PLAGUE_CITY_RECIPE = 180 + const val NO_TEA = 190 + // Hangover cure state + const val CURE = 220 + const val NO_CURE = 250 + const val RECIPE = 260 + const val NAME_ORIGIN = 270 + + const val ALL_DONE = 300 + } + + override fun handle(componentID: Int, buttonID: Int) { + npc = NPC(NPCs.SKIPPY_2796) + when (questStage){ + DRUNK -> when (stage) { + 0 -> if(hasAnItem(player!!, Items.BUCKET_OF_WATER_1929).exists()){ + playerl(FacialExpression.THINKING, "Well, I could dump this bucket of water over him. That would sober him up a little.").also { stage = THROW_WATER } + } + else { + playerl(FacialExpression.ASKING, "Are you all right? You seem a little...incoherent.").also { stage = DRUNK_RAMBLING } + } + THROW_WATER -> showTopics( + Topic("Throw the water!", THROW_WATER+ 1, true), + Topic("I think I'll leave it for now.", END_DIALOGUE) + ) + THROW_WATER + 1 -> playerl(FacialExpression.NEUTRAL, "Hey, Skippy!").also { stage++ } + THROW_WATER + 2 -> npcl(FacialExpression.DRUNK, "What?").also { + stage = END_DIALOGUE + queueScript(player!!, 1){ animationStage : Int -> + when(animationStage){ + 1 -> { + // todo get the right animation + animate(player!!, 2283) + removeItem(player!!, Items.BUCKET_OF_WATER_1929) + addItem(player!!, Items.BUCKET_1925) + setVarbit(player!!, Vars.VARBIT_MINI_QUEST_MOGRE, TENDER, true) + return@queueScript delayScript(player!!, 1) + } + 2 -> { + openDialogue(player!!, SkippyBucketDialogue(THROW_WATER + 4)) + return@queueScript delayScript(player!!, 1) + } + 3 -> return@queueScript stopExecuting(player!!) + else -> return@queueScript delayScript(player!!, 1) + } + } } + THROW_WATER + 4 -> npcl(FacialExpression.ANGRY, "Ahhhhhhhhhhgh! That's cold! Are you trying to kill me?").also { stage++ } + THROW_WATER + 5 -> playerl(FacialExpression.NEUTRAL, "Nope. Just sober you up. Memory coming back yet?").also { stage++ } + THROW_WATER + 6 -> npcl(FacialExpression.ANGRY, "No. But I could do with a bowl of tea to warm myself up a bit. Go grab me one and we'll talk.").also { stage++ } + THROW_WATER + 7 -> playerl(FacialExpression.ASKING, "Any particular type of tea?").also { stage++ } + THROW_WATER + 8 -> npcl(FacialExpression.ANGRY, "Nettle for preference. Just make sure it's hot.").also { stage++ } + THROW_WATER + 9 -> npcl(FacialExpression.ANGRY, "And don't throw it at me!").also { stage++ } + THROW_WATER + 10 -> playerl(FacialExpression.HALF_GUILTY, "What's your problem? You're all clean now.").also { stage = END_DIALOGUE } + + + DRUNK_RAMBLING -> npcl(FacialExpression.DRUNK, "Inc'hearnt? Inc'herant! You...you...with yer fancy book- lernin' words. You'd be more than inc'herant if youd seen...").also { stage++ } + DRUNK_RAMBLING + 1 -> npcl(FacialExpression.DRUNK, "(Dramatic pause)").also { stage++ } + DRUNK_RAMBLING + 2 -> npcl(FacialExpression.DRUNK, "THEM!").also { stage++ } + DRUNK_RAMBLING + 3 -> showTopics( + Topic("I'm sure I would as well.", CRAZY_PEOPLE), + Topic("Who are (Dramatic pause) THEY?", WHO_ARE_THEY, true) + ) + + CRAZY_PEOPLE -> playerl(FacialExpression.NEUTRAL, "I'm going over here to talk to non-crazy people now.").also { stage++ } + CRAZY_PEOPLE + 1 -> npcl(FacialExpression.DRUNK, "Yeah? Yeah? Well when THEY come floppin' into your house and eat your furniture you'll be sorry!").also { stage = END_DIALOGUE } + + WHO_ARE_THEY -> playerl(FacialExpression.NEUTRAL, "Who are").also { stage++ } + WHO_ARE_THEY + 1 -> playerl(FacialExpression.NEUTRAL, "(Dramatic pause)").also { stage++ } + WHO_ARE_THEY + 2 -> playerl(FacialExpression.NEUTRAL, "THEY?").also { stage++ } + WHO_ARE_THEY + 3 -> npcl(FacialExpression.DRUNK, "They! Those bloodthirsty, flesh-tearing devils! They are the reason I'm out here every day hurlin' bottles into the sea!").also { stage++ } + WHO_ARE_THEY + 4 -> npcl(FacialExpression.DRUNK, "They are the reason I've lost everything, except the horrifying memory of what THEY look like...").also { stage++ } + WHO_ARE_THEY + 5 -> playerl(FacialExpression.ASKING, "And what do THEY look like?").also { stage++ } + WHO_ARE_THEY + 6 -> npcl(FacialExpression.DRUNK, "Mudskippers!").also { stage++ } + WHO_ARE_THEY + 7 -> playerl(FacialExpression.ASKING, "Mudskippers?").also { stage++ } + WHO_ARE_THEY + 8 -> npcl(FacialExpression.DRUNK, "Aye, Mudskippers! Those ferocious, ravening, evil, beady-eyed terrors of the deep!").also { stage++ } + WHO_ARE_THEY + 9 -> playerl(FacialExpression.SUSPICIOUS, "I...see...").also{ stage++ } + WHO_ARE_THEY + 10 -> npcl(FacialExpression.DRUNK, " I was ambushed by them way back, see. They got the drop on me...I can't remember where, somewhere around here though.").also { stage++ } + WHO_ARE_THEY + 11 -> playerl(FacialExpression.ASKING, "These would be the mudskippers, right?").also{ stage++ } + WHO_ARE_THEY + 12 -> npcl(FacialExpression.DRUNK, "Aye! The mudskippers! Huge they were! Ten feet of glistening, muddy flesh floppin' towards me with white foam flying from their gnashing fangs!").also { stage++ } + WHO_ARE_THEY + 13 -> npcl(FacialExpression.DRUNK, "I fought them up and down the beach, with the tide rising and more of them leaping towards me with cutlasses drawn!").also { stage++ } + WHO_ARE_THEY + 14 -> playerl(FacialExpression.HALF_GUILTY, "This is fascinating, but I have to be...").also{ stage++ } + WHO_ARE_THEY + 15 -> npcl(FacialExpression.DRUNK, "Shut yer' word-hole and listen! I can't remember all the details, as I'm sure they must have hit me quite hard, but the last thing I remember before it all went black...").also { stage++ } + WHO_ARE_THEY + 16 -> npcl(FacialExpression.DRUNK, "...was one of those devils rearing over me, its eyes glowin' red with the fires of hell!").also { stage++ } + WHO_ARE_THEY + 17 -> playerl(FacialExpression.ROLLING_EYES, "Fires of hell...right. I believe you.").also { stage++ } + WHO_ARE_THEY + 18 -> npcl(FacialExpression.DRUNK, "No you don't! You think I'm crazy, like all the rest! Well, if I'm crazy, how did I get these?").also { stage++ } + WHO_ARE_THEY + 19 -> playerl(FacialExpression.ASKING, "Get what?").also { stage++ } + WHO_ARE_THEY + 20 -> sendDialogue(player!!, "Skippy shows you what appears to be massive bite scars on his legs. You're no expert, but they look like... giant mudskipper bites!").also { stage++ } + WHO_ARE_THEY + 21 -> playerl(FacialExpression.ASKING, "Giant mudskipper bites! Where did you get those?").also { stage++ } + WHO_ARE_THEY + 22 -> npcl(FacialExpression.DRUNK, "I can't remember... I've been drinking to forget the horror, and all I seem to have forgotten is where it all happened...").also { stage++ } + WHO_ARE_THEY + 23 -> playerl(FacialExpression.THINKING, "Hmmm...I suppose if I sober you up you may well start to recall.").also{ stage++ } + WHO_ARE_THEY + 24 -> npcl(FacialExpression.DRUNK, "You'll have a job. I've been drinking this for a week.").also { stage++ } + WHO_ARE_THEY + 25 -> playerl(FacialExpression.ASKING, "'Captain Braindeath's Extra Strength Rum/Drain Cleaner. Now 50% more debilitating'?").also { stage++ } + WHO_ARE_THEY + 26 -> npcl(FacialExpression.DRUNK, "It's the extra sheep tranquilizers that gives it that added kick!").also { stage++ } + WHO_ARE_THEY + 27 -> playerl(FacialExpression.NEUTRAL, "Stay here and I'll be right back. Try not to move. Or go near any open flames.").also { stage = END_DIALOGUE } + } + + TENDER -> when(stage){ + 0 -> playerl(FacialExpression.HAPPY, "Hey, Skippy!").also { stage++ } + 1 -> npcl(FacialExpression.PANICKED, "Gaah! Don't drench me again!").also { stage++ } + 2 -> playerl(FacialExpression.HALF_GUILTY, "Hey! I only did that once! Try not to be such a big baby!").also { stage++ } + 3 -> npcl(FacialExpression.HALF_THINKING, "So what are you here for then?").also { stage = if (hasAnItem(player!!, Items.NETTLE_TEA_4239).exists()) 4 else NO_TEA } + 4 -> playerl(FacialExpression.HAPPY, "I've come to give you your tea.").also { stage++ } + 5 -> npcl(FacialExpression.HAPPY, "Excellent! I was thinking I was going to freeze out here!").also { stage++ } + 6 -> sendItemDialogue(player!!, Items.NETTLE_TEA_4239, "Skippy drinks the tea and clutches his forehead in pain.").also { + stage++ + removeItem(player!!, Items.NETTLE_TEA_4239) + setVarbit(player!!, Vars.VARBIT_MINI_QUEST_MOGRE, HUNGOVER, true) + } + 7 -> npcl(FacialExpression.ANNOYED, "Ohhhhh...").also { stage++ } + 8 -> playerl(FacialExpression.ASKING, "What? What's wrong?").also { stage++ } + 9 -> npcl(FacialExpression.ANNOYED, "Not so loud...I think I have a hangover...").also { stage++ } + 10 -> playerl(FacialExpression.HALF_WORRIED, "Great...Well, I doubt you can remember anything through a hangover. What a waste of nettle tea...").also { stage++ } + 11 -> npcl(FacialExpression.FURIOUS, "Hey! A little sympathy here?").also { stage++ } + 12 -> npcl(FacialExpression.ANNOYED, "Owwowwoww... must remember not to shout...").also { stage++ } + 13 -> npcl(FacialExpression.ASKING, "Look, I do know a hangover cure. If you can get me a bucket of the stuff I think I'll be okay.").also { stage = if(getQuestStage(player!!, Quests.PLAGUE_CITY) >= 14 ) PLAGUE_CITY_RECIPE else LEARN_RECIPE } + + PLAGUE_CITY_RECIPE -> playerl(FacialExpression.HALF_THINKING, "Wait... is this cure a bucket of chocolate milk and snape grass?").also { stage++ } + PLAGUE_CITY_RECIPE + 1 -> npcl(FacialExpression.HAPPY, "Yes! That's the stuff!").also { stage++ } + PLAGUE_CITY_RECIPE + 2 -> playerl(FacialExpression.HALF_THINKING, "Ahhh. Yes, I've made some of that stuff before. I should be able to get you some, no problem.").also { stage = END_DIALOGUE } + + LEARN_RECIPE -> playerl(FacialExpression.ASKING, "So what is it you need?").also { stage++ } + LEARN_RECIPE + 1 -> npcl(FacialExpression.NEUTRAL, "A bucket of milk with chocolate ground into it, with a handful of snape grass thrown in on top.").also { stage++ } + LEARN_RECIPE + 2 -> playerl(FacialExpression.ASKING, "What? Run that past me again?").also { stage ++ } + LEARN_RECIPE + 3 -> npcl(FacialExpression.NEUTRAL, "Take a bucket of milk, a bar of chocolate and some snape grass.").also { stage++ } + LEARN_RECIPE + 4 -> npcl(FacialExpression.NEUTRAL, "Grind the chocolate with a mortar and pestle.").also { stage++ } + LEARN_RECIPE + 5 -> npcl(FacialExpression.NEUTRAL, "Add the chocolate powder to the milk, then add the snape grass.").also { stage++ } + LEARN_RECIPE + 6 -> npcl(FacialExpression.NEUTRAL, "Then bring it here and I will drink it.").also { stage++ } + LEARN_RECIPE + 7 -> npcl(FacialExpression.NEUTRAL, "The end, and we all live happily ever after. Got it?").also { stage = END_DIALOGUE } + + NO_TEA -> playerl(FacialExpression.HALF_GUILTY, "No real reason. I just thought I would check up on you is all.").also { stage++ } + NO_TEA + 1 -> npcl(FacialExpression.ANGRY, "Well, I'm still wet, still cold and still waiting on that nettle tea.").also { stage = END_DIALOGUE } + } + HUNGOVER -> when(stage){ + 0 -> playerl(FacialExpression.HAPPY, "Hey, Skippy!").also{ stage++ } + 1 -> npcl(FacialExpression.ANNOYED, "Egad! Don't you know not to shout around a guy with a hangover?").also { stage++ } + 2 -> npcl(FacialExpression.HALF_GUILTY, "Ahhhhhg...No more shouting for me...").also { stage++ } + 3 -> npcl(FacialExpression.ASKING, "What is it anyway?").also { stage = if (hasAnItem(player!!, Items.HANGOVER_CURE_1504).exists()) CURE else NO_CURE } + + CURE -> playerl(FacialExpression.HAPPY, "Well Skippy, you will no doubt be glad to hear that I got you your hangover cure!").also { stage++ } + CURE + 1 ->npcl(FacialExpression.HAPPY, "Gimme!").also { stage++ } + CURE + 2 -> sendDialogue(player!!, "Skippy chugs the hangover cure... very impressive.").also { + removeItem(player!!, Items.HANGOVER_CURE_1504) + stage++ + setVarbit(player!!, 1344, DONE_QUEST, true) + } + CURE + 3 -> npcl(FacialExpression.HAPPY, "Ahhhhhhhhhhhhhhh...").also { stage ++ } + CURE + 4 -> npcl(FacialExpression.HAPPY, "Much better...").also { stage ++ } + CURE + 5 -> playerl(FacialExpression.ASKING, "Feeling better?").also { stage ++ } + CURE + 6 -> npcl(FacialExpression.HAPPY, "Considerably.").also { stage ++ } + CURE + 7 -> playerl(FacialExpression.ASKING, "Then tell me where the mudskippers are!").also { stage++ } + CURE + 8 -> npcl(FacialExpression.NEUTRAL, "I wish you wouldn't go looking for them. Those vicious killers will tear you apart.").also { stage ++ } + CURE + 9 -> npcl(FacialExpression.HALF_THINKING, "It's all becoming clear to me now...").also { stage ++ } + CURE + 10 -> npcl(FacialExpression.HAPPY, "I was fishing using a Fishing Explosive...").also { stage ++ } + CURE + 11 -> playerl(FacialExpression.ASKING, "A Fishing Explosive?").also { stage++ } + CURE + 12 -> npcl(FacialExpression.NEUTRAL, "Well, Slayer Masters sell these highly volatile potions for killing underwater creatures.").also { stage ++ } + CURE + 13 -> npcl(FacialExpression.NEUTRAL, "If you don't feel like lobbing a net about all day you can use them to fish with...").also { stage ++ } + CURE + 14 -> npcl(FacialExpression.NEUTRAL, "But this time I was startled by what I thought was a giant mudskipper.").also { stage ++ } + CURE + 15 -> npcl(FacialExpression.NEUTRAL, "What it was, in fact, was a...").also { stage ++ } + CURE + 16 -> npcl(FacialExpression.NEUTRAL, "Dramatic Pause...").also { stage ++ } + CURE + 17 -> npcl(FacialExpression.PANICKED, "A Mogre!").also { stage ++ } + CURE + 18 -> playerl(FacialExpression.ASKING, "What exactly is a Mogre?").also { stage++ } + CURE + 19 -> npcl(FacialExpression.NEUTRAL, "A Mogre is a type of Ogre that spends most of its time underwater.").also { stage ++ } + CURE + 20 -> npcl(FacialExpression.NEUTRAL, "They hunt giant mudskippers by wearing their skins and swimming close until they can attack them.").also { stage ++ } + CURE + 21 -> npcl(FacialExpression.NEUTRAL, "When I used the Fishing Explosive I scared off all the fish, and so the Mogre got out of the water to express its extreme displeasure.").also { stage ++ } + CURE + 22 -> npcl(FacialExpression.NEUTRAL, "With an iron mace.").also { stage ++ } + CURE + 23 -> playerl(FacialExpression.ASKING, "I take it the head injury is responsible for the staggering and yelling?").also { stage++ } + CURE + 24 -> npcl(FacialExpression.NEUTRAL, "No, no.").also { stage ++ } + CURE + 25 -> npcl(FacialExpression.NEUTRAL, "My addiction to almost-lethal alcohol did that.").also { stage ++ } + CURE + 26 -> npcl(FacialExpression.NEUTRAL, "But if you are set on finding these Mogres just head south from here until you find Mudskipper Point.").also { stage ++ } + CURE + 27 -> playerl(FacialExpression.ASKING, "The mudskipper-eating monsters are to be found at Mudskipper point?").also { stage++ } + CURE + 28 -> playerl(FacialExpression.ROLLING_EYES, "Shock!").also { stage++ } + CURE + 29 -> playerl(FacialExpression.NEUTRAL, "Thanks. I'll be careful.").also { stage = END_DIALOGUE } + + NO_CURE -> playerl(FacialExpression.HALF_GUILTY, "I just came back to ask you something.").also { stage++ } + NO_CURE + 1 -> npcl(FacialExpression.ANNOYED, "What?").also { stage++ } + NO_CURE + 2 -> showTopics( + Topic("How do I make that hangover cure again?", RECIPE), + Topic("Why do they call you 'Skippy'?", NAME_ORIGIN) + ) + + RECIPE -> npcl(FacialExpression.ANGRY, "Give me strength...Here's what you do. Pay attention!").also { stage++ } + RECIPE + 1 -> npcl(FacialExpression.ANGRY, "You take a bucket of milk, a bar of chocolate and some snape grass.").also { stage++ } + RECIPE + 2 -> npcl(FacialExpression.ANGRY, "Grind the chocolate with a pestle and mortar.").also { stage++ } + RECIPE + 3 -> npcl(FacialExpression.ANGRY, "Add the chocolate powder to the milk, then add the snape grass.").also { stage++ } + RECIPE + 4 -> npcl(FacialExpression.ANGRY, "Then bring it here and I will drink it.").also { stage++ } + RECIPE + 5 -> npcl(FacialExpression.ANGRY, "Are you likely to remember that or should I go get some crayons and draw you a picture?").also { stage++ } + RECIPE + 6 -> playerl(FacialExpression.ANGRY, "Hey! I remember it now, ok! See you in a bit.").also { stage = END_DIALOGUE } + + NAME_ORIGIN -> npcl(FacialExpression.THINKING, "I think it may have something to do with my near- constant raving about mudskippers.").also { stage++ } + NAME_ORIGIN + 1 -> npcl(FacialExpression.THINKING, "That or it's something to do with that time with the dress and the field full of daisies...").also { stage = END_DIALOGUE } + } + DONE_QUEST -> when(stage){ + 0 -> playerl(FacialExpression.NEUTRAL, "Hey, Skippy.").also { stage++ } + 1 -> npcl(FacialExpression.HAPPY, "Hey you!").also { stage++ } + 2 -> playerl(FacialExpression.ASKING, "How do I annoy the Mogres again?").also { stage++ } + 3 -> npcl(FacialExpression.HAPPY, "Go south to Mudskipper Point and lob a Fishing Explosive into the sea. You can grab them from the Slayer masters.").also { stage++ } + 4 -> playerl(FacialExpression.ASKING, "Thanks! So, what are you going to do now?").also { stage++ } + 5 -> npcl(FacialExpression.HAPPY, "Well, I was planning on continuing my hobby of wandering up and down this bit of coastline, bellowing random threats and throwing bottles.").also { stage++ } + 6 -> npcl(FacialExpression.ASKING, "And you?").also { stage++ } + 7 -> playerl(FacialExpression.NEUTRAL, "I was planning on wandering up and down the landscape, bugging people to see if they had mindblowingly dangerous quests for me to undertake.").also { stage++ } + 8 -> npcl(FacialExpression.HAPPY, "Well, good luck with that!").also { stage++ } + 9 -> playerl(FacialExpression.HAPPY, "You too!").also { stage++ } + 10 -> npcl(FacialExpression.ROLLING_EYES, "Weirdo...").also { stage++ } + 11 -> playerl(FacialExpression.ROLLING_EYES, "Loony..").also { stage = END_DIALOGUE } + } + } + } +} + +class SkippyBootDialogue: DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + npc = NPC(NPCs.SKIPPY_2796) + val expression = if (getVarbit(player!!, Vars.VARBIT_MINI_QUEST_MOGRE) > SkippyBucketDialogue.DRUNK) FacialExpression.ROLLING_EYES else FacialExpression.DRUNK + npcl(expression, "Thanks! Now I have two right boots!").also { stage = END_DIALOGUE } + } + +} diff --git a/Server/src/main/content/region/asgarnia/portsarim/dialogue/AhabDialogue.java b/Server/src/main/content/region/asgarnia/portsarim/dialogue/AhabDialogue.java new file mode 100644 index 0000000..5f54460 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/portsarim/dialogue/AhabDialogue.java @@ -0,0 +1,190 @@ +package content.region.asgarnia.portsarim.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; +import content.data.Quests; + +/** + * Represents the dialogue plugin used for the npc Ahav. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class AhabDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code AhabDialogue} {@code Object}. + */ + public AhabDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code AhabDialogue} {@code Object}. + * @param player the player. + */ + public AhabDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new AhabDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + if(args.length > 1) { + boolean isTelegrab = (boolean) args[1]; + player.debug("" + isTelegrab); + if (!isTelegrab) { + npc(FacialExpression.FURIOUS, "Oi! Get yer hands off me beer!"); + } else { + npc(FacialExpression.FURIOUS,"Don't ye go castin' spells on me beer!"); + } + stage = 301; + } else { + npc("Arrr, matey!"); + stage = 0; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "Arrr!", "Are you going to sit there all day?", "Do you have anything for trade?"); + stage = 1; + break; + case 1: + + switch (buttonId) { + case 1: + player("Arrr!"); + stage = 10; + break; + case 2: + player("Are you going to sit there all day?"); + stage = 20; + break; + case 3: + player("Do you have anything for trade?"); + stage = 300; + break; + } + + break; + case 10: + npc("Arrr, matey!"); + stage = 0; + break; + case 20: + npc("Aye, I am. I canna walk, ye see."); + stage = 21; + break; + case 21: + player("What's stopping you from walking?"); + stage = 22; + break; + case 22: + npc("Arrr, I'ave only the one leg! I lost its twin when my last", "ship went down."); + stage = 23; + break; + case 23: + player("But I can see both your legs!"); + stage = 24; + break; + case 24: + npc("Nay, young laddie, this be a false leg. For years I had me a", "sturdy wooden peg-leg, but now I wear this dainty little", "feller."); + stage = 25; + break; + case 25: + npc("Yon peg-leg kept getting stuck in the floorboards."); + stage = 26; + break; + case 26: + player("Right..."); + stage = 27; + break; + case 27: + npc("Perhaps a bright young laddie like yerself would like to", "help me? I be needing another ship to go a-hunting my", "enemy."); + stage = 28; + break; + case 28: + if (player.getQuestRepository().isComplete(Quests.DRAGON_SLAYER)) { + player("Well, I do have a ship that I'm not using.", "It's the Lady Lumbridge."); + stage = 29; + } else { + player("No, I don't have a ship."); + stage = 294; + } + break; + case 294: + npc("Arr matey... You make me sad."); + stage = 295; + break; + case 295: + end(); + break; + case 29: + npc("Arrr! That ship be known to me, and a fine lass she is."); + stage = 30; + break; + case 30: + player("I suppose she might be..."); + stage = 31; + break; + case 31: + npc("So would ye be kind enough to let", "me take her out to sea?"); + stage = 32; + break; + case 32: + player("I had to pay 2000gp for that ship! ", "Have you got that much?"); + stage = 33; + break; + case 33: + npc("Nay, I have nary a penny to my name. All my wordly goods", "went down with me old ship."); + stage = 34; + break; + case 34: + player("So you're actually asking me to give you a free ship."); + stage = 35; + break; + case 35: + npc("Arrr! Would ye be so kind?"); + stage = 36; + break; + case 36: + player("No I jolly well wouldn't!"); + stage = 37; + break; + case 37: + npc("Arrr."); + stage = 38; + break; + case 38: + end(); + break; + case 300: + npc("Nothin' at the moment, but then again the Customs", "Agents are on the warpath right now."); + stage = 301; + break; + case 301: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 2692 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/portsarim/dialogue/BettyDialogue.java b/Server/src/main/content/region/asgarnia/portsarim/dialogue/BettyDialogue.java new file mode 100644 index 0000000..df1214c --- /dev/null +++ b/Server/src/main/content/region/asgarnia/portsarim/dialogue/BettyDialogue.java @@ -0,0 +1,81 @@ +package content.region.asgarnia.portsarim.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the dialogue plugin for the betty npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class BettyDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code BettyDialogue} {@code Object}. + */ + public BettyDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code BettyDialogue} {@code Object}. + * @param player the player. + */ + public BettyDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new BettyDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Welcome to the magic emporium."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "Can I see your wares?", "Sorry, I'm not into Magic."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + end(); + npc.openShop(player); + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Sorry, I'm not into Magic."); + stage = 20; + break; + } + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Well, if you see anyone who is into Magic, please send", "them my way."); + stage = 21; + break; + case 21: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 583 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/portsarim/dialogue/GrumDialogue.java b/Server/src/main/content/region/asgarnia/portsarim/dialogue/GrumDialogue.java new file mode 100644 index 0000000..14d964c --- /dev/null +++ b/Server/src/main/content/region/asgarnia/portsarim/dialogue/GrumDialogue.java @@ -0,0 +1,82 @@ +package content.region.asgarnia.portsarim.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the grum dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class GrumDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code GrumDialogue} {@code Object}. + */ + public GrumDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code GrumDialogue} {@code Object}. + * @param player the player. + */ + public GrumDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new GrumDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Would you like to buy or sell some gold jewellery?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "Yes, please.", "No, I'm not that rich."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + end(); + npc.openShop(player); + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No, I', not that rich."); + stage = 20; + break; + + } + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.ANNOYED, "Get out, then! We don't want any riff-raff in here."); + stage = 21; + break; + case 21: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 556 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/portsarim/dialogue/JackSeagullDialogue.java b/Server/src/main/content/region/asgarnia/portsarim/dialogue/JackSeagullDialogue.java new file mode 100644 index 0000000..671e7f4 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/portsarim/dialogue/JackSeagullDialogue.java @@ -0,0 +1,98 @@ +package content.region.asgarnia.portsarim.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the hack seafull dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class JackSeagullDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code JackSeagullDialogue} {@code Object}. + */ + public JackSeagullDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code JackSeagullDialogue} {@code Object}. + * @param player the player. + */ + public JackSeagullDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new JackSeagullDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Arrr, matey!"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("What would you like to say?", "What are you doing here?", "Have you got any quests I could do?"); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What are you doing here?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Have you got any quests I could do?"); + stage = 20; + break; + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Drinking."); + stage = 11; + break; + case 11: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Fair enough."); + stage = 12; + break; + case 12: + end(); + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Nay, I've nothing for ye to do."); + stage = 21; + break; + case 21: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Thanks."); + stage = 22; + break; + case 22: + end(); + break; + } + + return true; + } + + @Override + public int[] getIds() { + return new int[] { 2690 }; + } + +} diff --git a/Server/src/main/content/region/asgarnia/portsarim/dialogue/KlarenseDialogue.java b/Server/src/main/content/region/asgarnia/portsarim/dialogue/KlarenseDialogue.java new file mode 100644 index 0000000..6c5e14b --- /dev/null +++ b/Server/src/main/content/region/asgarnia/portsarim/dialogue/KlarenseDialogue.java @@ -0,0 +1,241 @@ +package content.region.asgarnia.portsarim.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.plugin.Initializable; +import core.game.node.item.Item; +import content.data.Quests; + +/** + * Represents the dialogue used for the klarense npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class KlarenseDialogue extends DialoguePlugin { + + /** + * Represents the amount of coins. + */ + private static final Item COINS = new Item(995, 2000); + + /** + * Represents the quest instance. + */ + private Quest quest; + + /** + * Constructs a new {@code KlarenseDialogue} {@code Object}. + */ + public KlarenseDialogue() { + /** + * emptpy. + */ + } + + /** + * Constructs a new {@code KlarenseDialogue} {@code Object}. + * @param player the player. + */ + public KlarenseDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new KlarenseDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + quest = player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER); + if (args.length > 1) { + interpreter.sendDialogues(npc, FacialExpression.ANGRY, "Hey, stay off my ship! That's private property!"); + stage = 0; + return true; + } + switch (quest.getStage(player)) { + case 100: + player("Hey, that's my ship!"); + stage = -1; + break; + default: + if (player.getSavedData().getQuestData().getDragonSlayerAttribute("ship")) { + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "Hello, captain! Here to inspect your new ship? Just a", "little work and she'll be seaworthy again."); + stage = 400; + return true; + } + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "So, are you interested in buying the Lady Lumbridge?", "Now, I'll be straight with you: she's not quite seaworthy", "right now, but give her a bit of work and she'll be the", "nippiest ship this side of Port Khazard."); + stage = 1; + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + if (stage == 400) { + end(); + return true; + } + switch (quest.getStage(player)) { + case 100: + switch (stage) { + case 0: + end(); + break; + case -1: + interpreter.sendDialogues(npc, FacialExpression.SUSPICIOUS,"No, it's not. It may, to the untrained eye, at first", "appear to be the Lady Lumbridge, but it is definitely", "not. It's my new ship. It just happens to look slightly", "similar, is all."); + stage = 1; + break; + case 1: + interpreter.sendDialogues(player, FacialExpression.ANNOYED,"It has Lady Lumbridge pained out and 'Klarense's", "Cruiser' painted over it!"); + stage = 2; + break; + case 2: + interpreter.sendDialogues(npc, FacialExpression.SUSPICIOUS,"Nope, you're mistaken. It's my new boat."); + stage = 3; + break; + case 3: + end(); + break; + } + break; + case 20: + switch (stage) { + case 0: + end(); + break; + case 1: + interpreter.sendDialogues(player, FacialExpression.ASKING, "Would you take me to Crandor when she's ready?"); + stage = 2; + break; + case 2: + interpreter.sendDialogues(npc, FacialExpression.EXTREMELY_SHOCKED, "Crandor? You're joking, right?"); + stage = 3; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "No. I want to go to Crandor."); + stage = 4; + break; + case 4: + interpreter.sendDialogues(npc, FacialExpression.WORRIED, "Then you must be crazy."); + stage = 5; + break; + case 5: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "That island is surrounded by reefs that would rip this", "ship to shreds. Even if you found a map, you'd need", "an experienced captain to stand a chance of getting", "through"); + stage = 6; + break; + case 6: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL,"even if you gould get to it, there's no way I'm going", "any closer to that dragon than I have to. They say it", "can destroy whole ships with one bite."); + stage = 7; + break; + case 7: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL,"I'd like to buy her."); + stage = 8; + break; + case 8: + interpreter.sendDialogues(npc, FacialExpression.HAPPY,"Of course! I'm sure the work needed to do on it", "wouldn't be too expensive."); + stage = 9; + break; + case 9: + interpreter.sendDialogues(npc, FacialExpression.HAPPY,"How does, 2,000 gold sound? I'll even throw in my", "cabin boy, Jenkins, for free! He'll swab the decks and", "splice the mainsails for you!"); + stage = 10; + break; + case 10: + interpreter.sendDialogues(player, FacialExpression.HAPPY,"Yep, sounds good."); + stage = 11; + break; + case 11: + if (!player.getInventory().containsItem(COINS)) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY,"...except I don't have that kind of money on me..."); + stage = 12; + } else { + if (!player.getInventory().containsItem(COINS)) { + end(); + return false; + } + if (player.getInventory().remove(COINS)) { + interpreter.sendDialogues(npc, FacialExpression.HAPPY,"Okey dokey, she's all yours!"); + player.getSavedData().getQuestData().setDragonSlayerAttribute("ship", true); + stage = 12; + } + } + break; + case 12: + end(); + break; + } + break; + default: + switch (stage) { + case 0: + end(); + break; + case 1: + interpreter.sendOptions("Select an Option", "Do you know when she will be seaworthy?", "Why is she damaged?", "Ah, well, never mind."); + stage = 2; + break; + case 2: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.ASKING, "Do you know when she will be seaworthy?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.ASKING, "Why is she damaged?"); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Ah, well, never mind."); + stage = 30; + break; + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "No, not really. Port Sarim's shipbuilders aren't very", "efficient so it could be quite a while."); + stage = 11; + break; + case 11: + end(); + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Oh, there was no particular accident. It's just years of", "wear and tear."); + stage = 21; + break; + case 21: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "The Lady Lumbridge is an old Crandorian fishing ship -", "the last one of her kind, as far as I know. That kind of", "ship was always mightily manoeuvrable, but not too", "tough."); + stage = 22; + break; + case 22: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "She happened to be somewhere else when Crandor was", "destroyed, and she's had several owners since then. Not", "all of them have looked after her too well,"); + stage = 23; + break; + case 23: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "but once she's patched up, she'll be good as new!"); + stage = 24; + break; + case 24: + end(); + break; + case 30: + end(); + break; + case 400: + end(); + break; + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 744 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/portsarim/dialogue/LongbowBenDialogue.java b/Server/src/main/content/region/asgarnia/portsarim/dialogue/LongbowBenDialogue.java new file mode 100644 index 0000000..46cf18c --- /dev/null +++ b/Server/src/main/content/region/asgarnia/portsarim/dialogue/LongbowBenDialogue.java @@ -0,0 +1,113 @@ +package content.region.asgarnia.portsarim.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the longow ben dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class LongbowBenDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code LongbowBenDialogue} {@code Object}. + */ + public LongbowBenDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code LongbowBenDialogue} {@code Object}. + * @param player the player. + */ + public LongbowBenDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new LongbowBenDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Arrr, matey!"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("What would you like to say?", "Why are you called Longbow Ben?", "Have you got any quests I could do?"); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Why are you called Longbow Ben?"); + stage = 100; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Have you got any quests I could do?"); + stage = 200; + break; + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I was to be marooned, ye see. A srurvy troublemaker had", "taken my ship, and he put me ashore on a little island."); + stage = 11; + break; + case 11: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Gosh, how did you escape?"); + stage = 12; + break; + case 12: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Arrr, ye see, he made on mistake! Before he sailed", "he gave me a bow and one arrow so that I wouldn't have", "to die slowly."); + stage = 13; + break; + case 13: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "So I shot him and took my ship back."); + stage = 14; + break; + case 14: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Right..."); + stage = 15; + break; + case 15: + end(); + break; + case 100: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Arrr, that's a strange yarn."); + stage = 10; + break; + case 200: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Nay, I've nothing for ye to do."); + stage = 201; + break; + case 201: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Thanks."); + stage = 202; + break; + case 202: + end(); + break; + } + + return true; + } + + @Override + public int[] getIds() { + return new int[] { 2691 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/portsarim/dialogue/MonkOfEntranaDialogue.java b/Server/src/main/content/region/asgarnia/portsarim/dialogue/MonkOfEntranaDialogue.java new file mode 100644 index 0000000..e8c9211 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/portsarim/dialogue/MonkOfEntranaDialogue.java @@ -0,0 +1,153 @@ +package content.region.asgarnia.portsarim.dialogue; + +import core.cache.def.impl.ItemDefinition; +import content.global.travel.ship.Ships; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.link.diary.DiaryType; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +import static core.api.ContentAPIKt.*; + +/** + * Represents the dialogue plugin used for the monk of entrana dialogue. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class MonkOfEntranaDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code MonkOfEntranaDialogue} {@code Object}. + */ + public MonkOfEntranaDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code MonkOfEntranaDialogue} {@code Object}. + * @param player the player. + */ + public MonkOfEntranaDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new MonkOfEntranaDialogue(player); + } + + public void sail(Player player, Ships ship) { + ship.sail(player); + playJingle(player, 172); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + if (npc.getId() == 2730 || npc.getId() == 658 || npc.getId() == 2731) { + interpreter.sendDialogues(npc, null, "Do you wish to leave holy Entrana?"); + stage = 500; + return true; + } + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Do you seek passage to holy Entrana? If so, you must", "leave your weaponry and armour behind. This is", "Saradomin's will."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "No, not right now.", "Yes, okay, I'm ready to go."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, null, "No, not right now."); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, null, "Yes, okay, I'm ready to go."); + stage = 20; + break; + } + break; + case 10: + interpreter.sendDialogues(npc, null, "Very well."); + stage = 11; + break; + case 11: + end(); + break; + case 20: + interpreter.sendDialogues(npc, null, "Very well. One moment please."); + stage = 21; + break; + case 21: + interpreter.sendDialogue("The monk quickly searches you."); + stage = 22; + break; + case 22: + if (!ItemDefinition.canEnterEntrana(player)) { + interpreter.sendDialogues(npc, null, "NO WEAPONS OR ARMOUR are permitted on holy", "Entrana AT ALL. We will not allow you to travel there", "in breach of mighty Saradomin's edict."); + stage = 23; + return true; + } + interpreter.sendDialogues(npc, null, "All is satisfactory. You may board the boat now."); + stage = 25; + break; + case 23: + interpreter.sendDialogues(npc, null, "Do not try to deceive us again. Come back when you", "have laid down your Zamorakian instruments of death."); + stage = 24; + break; + case 24: + end(); + break; + case 25: + end(); + sail(player, Ships.PORT_SARIM_TO_ENTRANA); + if (!player.getAchievementDiaryManager().getDiary(DiaryType.FALADOR).isComplete(0, 14)) { + player.getAchievementDiaryManager().getDiary(DiaryType.FALADOR).updateTask(player, 0, 14, true); + } + break; + case 500: + interpreter.sendOptions("Select an Option", "Yes, I'm ready to go.", "Not just yet."); + stage = 501; + break; + case 501: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, null, "Yes, I'm ready to go."); + stage = 510; + break; + case 2: + interpreter.sendDialogues(player, null, "Not just yet."); + stage = 520; + break; + } + break; + case 510: + interpreter.sendDialogues(npc, null, "Okay, let's board..."); + stage = 511; + break; + case 511: + sail(player, Ships.ENTRANA_TO_PORT_SARIM); + break; + case 520: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 2728, 657, 2729, 2730, 2731, 658 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/portsarim/dialogue/PortSarimBartenderDialogue.java b/Server/src/main/content/region/asgarnia/portsarim/dialogue/PortSarimBartenderDialogue.java new file mode 100644 index 0000000..a771cf3 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/portsarim/dialogue/PortSarimBartenderDialogue.java @@ -0,0 +1,101 @@ +package content.region.asgarnia.portsarim.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.game.node.item.Item; + +/** + * Handles the PortSarimBartenderDialogue dialogue. + * @author 'Vexia + */ +@Initializable +public class PortSarimBartenderDialogue extends DialoguePlugin { + + public PortSarimBartenderDialogue() { + + } + + public PortSarimBartenderDialogue(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[] { 734 }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Hello there!"); + stage = 1; + break; + case 1: + interpreter.sendOptions("Choose an option:", "Could I buy a beer, please.", "Bye, then."); + stage = 2; + break; + case 2: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HAPPY, "Could I buy a beer, please?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.FRIENDLY, "Bye, then."); + stage = 20; + break; + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "Sure, that will be two gold coins, please."); + stage = 11; + break; + case 11: + interpreter.sendDialogues(player, FacialExpression.FRIENDLY, "Okay, here you go."); + stage = 12; + break; + case 12: + if (player.getInventory().contains(995, 2)) { + interpreter.sendDialogue("You buy a pint of beer."); + player.getInventory().remove(new Item(995, 2)); + player.getInventory().add(new Item(1917, 1)); + stage = 13; + } else { + player.getPacketDispatch().sendMessage("You need 2 gold coins to buy beer."); + end(); + } + break; + case 13: + end(); + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "Come back soon!"); + stage = 21; + break; + case 21: + end(); + break; + } + + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new PortSarimBartenderDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.FRIENDLY, "Good day to you!"); + stage = 0; + return true; + } +} diff --git a/Server/src/main/content/region/asgarnia/portsarim/dialogue/PortSarimBrianDialogue.java b/Server/src/main/content/region/asgarnia/portsarim/dialogue/PortSarimBrianDialogue.java new file mode 100644 index 0000000..3065f02 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/portsarim/dialogue/PortSarimBrianDialogue.java @@ -0,0 +1,76 @@ +package content.region.asgarnia.portsarim.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Handles the PortSarimBrianDialogue dialogue. + * @author 'Vexia + */ +@Initializable +public class PortSarimBrianDialogue extends DialoguePlugin { + + public PortSarimBrianDialogue() { + + } + + public PortSarimBrianDialogue(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[] { 559 }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.FRIENDLY, "So, are you selling something?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HAPPY, "'Ello."); + stage = 20; + break; + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Yep, take a look at these great axes."); + stage = 11; + break; + case 11: + end(); + npc.openShop(player); + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "'Ello."); + stage = 21; + break; + case 21: + end(); + break; + } + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new PortSarimBrianDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendOptions("Select an Option", "So, are you selling something?", "'Ello."); + stage = 0; + return true; + } +} diff --git a/Server/src/main/content/region/asgarnia/portsarim/dialogue/RedbeardFrankDialogue.java b/Server/src/main/content/region/asgarnia/portsarim/dialogue/RedbeardFrankDialogue.java new file mode 100644 index 0000000..e3a4616 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/portsarim/dialogue/RedbeardFrankDialogue.java @@ -0,0 +1,516 @@ +package content.region.asgarnia.portsarim.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.AchievementDiary; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.GroundItemManager; +import core.plugin.Initializable; +import core.game.node.item.Item; + +import static core.tools.DialogueConstKt.END_DIALOGUE; +import content.data.Quests; + +/** + * Represents the dialogue to handle Rebeard Frank. + * + * @author afaroutdude + */ +@Initializable +public class RedbeardFrankDialogue extends DialoguePlugin { + private boolean replacementReward = false; + private int level = 0; + + /** + * Represents the karamjan rum item. + */ + private static final Item KARAMJAN_RUM = new Item(431); + + /** + * Represents the chest key item. + */ + private static final Item KEY = new Item(432); + + /** + * Represents this quest instance. + */ + private Quest quest; + + /** + * Constructs a new {@code RedbeardFrankDialogue} {@code Object}. + */ + public RedbeardFrankDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code RedbeardFrankDialogue} {@code Object}. + * + * @param player the player. + */ + public RedbeardFrankDialogue(Player player) { + super(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + quest = player.getQuestRepository().getQuest(Quests.PIRATES_TREASURE); + npc("Arr, Matey!"); + stage = 0; + replacementReward = AchievementDiary.canReplaceReward(player, DiaryType.FALADOR, level); + return true; + } + + // https://www.youtube.com/watch?v=U_sNcqQ2dtQ - achievement diary branch + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + if (quest.getStage(player) == 20 && !player.getInventory().containsItem(KEY) && !player.getBank().containsItem(KEY)) { + player("I seem to have lost my chest key..."); + stage = 700; + return true; + } + if (quest.getStage(player) == 10) { + npc("Have ye brought some rum for yer ol' mate Frank?"); + stage = 20; + break; + } + if (quest.getStage(player) == 0) { + options("I'm in search of treasure.", "Arr!", "Do you have anything for trade?", "Tell me about the Falador Achievement Diary."); + stage = 11; + break; + } + options("Arr!", "Do you have anything for trade?", "Tell me about the Falador Achievement Diary."); + stage = 10; + break; + case 10: + switch (buttonId) { + case 1: + player("Arr!"); + stage = 12; + break; + case 2: + player("Do you have anything for trade?"); + stage = 13; + break; + case 3: + player("Tell me about the Falador Achievement Diary."); + stage = 80; + break; + } + break; + case 11: + switch (buttonId) { + case 1: + player("I'm in search of treasure."); + stage = 40; + break; + case 2: + player("Arr!"); + stage = 12; + break; + case 3: + player("Do you have anything for trade?"); + stage = 13; + break; + case 4: + player("Tell me about the Falador Achievement Diary."); + stage = 80; + break; + } + break; + case 12: + npc("Arr!"); + stage = 0; + break; + case 13: + npc("Nothin' at the moment, but then again the Customs", "Agents are on the warpath right now."); + stage = 999; + break; + case 20: + if (!player.getInventory().containsItem(KARAMJAN_RUM)) { + player("No, not yet."); + stage = 21; + } else { + player("Yes, I've got some."); + stage = 31; + } + break; + case 21: + npc("Not suprising, tis no easy task to get it off Karamja."); + stage = 22; + break; + case 22: + player("What do you mean?"); + stage = 23; + break; + case 23: + npc("The Customs office has been clampin' down on the", "export of spirits. You seem like a resourceful young lad,", "I'm sure ye'll be able to find a way to slip the stuff past", "them."); + stage = 24; + break; + case 24: + player("Well I'll give it another shot."); + stage = 25; + break; + case 999: + end(); + break; + case 31: + npc("Now a deal's a deal, I'll tell ye about the treasure. I", "used to serve under a pirate captain called One-Eyed", "Hector."); + stage = 32; + break; + case 32: + npc("Hector were very successful and became very rich.", "But about a year ago we were boarded by the Customs", "and Excise Agents."); + stage = 33; + break; + case 33: + npc("Hector were killed along with many of the crew, I were", "one of the few to escape and I escaped with this."); + stage = 34; + break; + case 34: + if (player.getInventory().remove(KARAMJAN_RUM)) { + if (!player.getInventory().add(KEY)) { + GroundItemManager.create(KEY, player); + } + quest.setStage(player, 20); + interpreter.sendItemMessage(KEY.getId(), "Frank happily takes the rum... ... and hands you a key"); + stage = 35; + } + break; + case 35: + npc("This be Hector's key. I believe it opens his chest in his", "old room in the Blue Moon Inn in Varrock."); + stage = 36; + break; + case 36: + npc("With any luck his treasure will be in there."); + stage = 37; + break; + case 37: + player("Ok thanks, I'll go and get it."); + stage = 999; + break; + case 40: + npc("Arr, treasure you be after eh? Well I might be able to", "tell you where to find some... For a price..."); + stage = 41; + break; + case 41: + player("What sort of price?"); + stage = 42; + break; + case 42: + npc("Well for example if you go and get me a bottle of rum...", "Not just any rum mind..."); + stage = 43; + break; + case 43: + npc("I'd like some rum made on Karamja Island. There's no", "rum like Karamaja Rum!"); + stage = 44; + break; + case 44: + options("Ok, I will bring you some rum.", "Not right now."); + stage = 45; + break; + case 45: + switch (buttonId) { + case 1: + quest.start(player); + player("Ok, I will bring you some rum."); + stage = 47; + break; + case 2: + player("Not right now."); + stage = 46; + break; + } + break; + case 46: + npc("Fair enough. I'll still be here and thirsty whenever you", "feel like helpin' out."); + stage = 999; + break; + case 47: + npc("Yer a saint, although it'll take a miracle to get it off", "Karamja."); + stage = 48; + break; + case 48: + player("What do you mean?"); + stage = 49; + break; + case 49: + npc("The Customs office has been clampin' down on the", "export of spirits. You seem like a resourceful young lad,", "I'm sure ye'll be able to find a way to slip the stuff past", "them."); + stage = 50; + break; + case 50: + player("Well I'll give it a shot."); + stage = 51; + break; + case 51: + npc("Arr, that's the spirit!"); + stage = 999; + break; + + + case 700: + npc("Arr, silly you. Fortunately I took the precaution to have", "another one made."); + stage = 701; + break; + case 701: + interpreter.sendItemMessage(KEY.getId(), "Frank hands you a chest key."); + stage = 702; + break; + case 702: + end(); + if (!player.getInventory().add(KEY)) { + GroundItemManager.create(KEY, player); + } + break; + + + case 80: + if (player.getAttribute("falador-diary-talk-first-time", false)) { + npc("So you're interested in exploring Falador and it's", "surrounding areas, eh?"); + player.setAttribute("/save:falador-diary-talk-first-time", true); + stage = 100; + } else { + npc("How are you getting on with the Achievement Diary?"); + stage = 90; + } + break; + + case 90: + options("I've come for my reward.", "I'm doing good.", "I have a question."); + stage = 91; + break; + case 91: + switch (buttonId) { + case 1: + player("I've come for my reward."); + stage = 200; + break; + case 2: + player("I'm doing good."); + stage = 220; + break; + case 3: + player("I have a question."); + stage = 105; + break; + } + break; + + case 100: + player("Er... I guess."); + stage = 101; + break; + case 101: + npc("Arrr! That's the spirit! Soon ye'll be exploring", "underground caverns, sailin' the high seas and", "plundering booty!"); + stage = 102; + break; + case 102: + interpreter.sendDialogues(player, FacialExpression.AMAZED, "Plundering booty?"); + stage = 103; + break; + case 103: + npc("Arrr! Nay, that be a lie, I be getting carried away."); + stage = 104; + break; + case 104: + npc("Have you got any questions?"); + stage = 105; + break; + case 105: + if (!AchievementDiary.hasClaimedLevelRewards(player, DiaryType.FALADOR, level)) { + options("What is the Achievement Diary?", "What are the rewards?", "How do I claim the rewards?", "See you later."); + stage = 106; + } else { + options("Can you remind me what my Falador shield does, please?", "What is the Achievement Diary?", "What are the rewards?", "How do I claim the rewards?", "See you later."); + stage = 107; + } + break; + case 106: + switch (buttonId) { + case 1: + player("What is the Achievement Diary?"); + stage = 110; + break; + case 2: + player("What are the rewards?"); + stage = 120; + break; + case 3: + player("How do I claim the rewards?"); + stage = 130; + break; + case 4: + player("See you later."); + stage = 999; + break; + } + break; + + case 107: + switch (buttonId) { + case 1: + player("Can you remind me what my Falador shield does, please?"); + stage = 150; + break; + case 2: + player("What is the Achievement Diary?"); + stage = 110; + break; + case 3: + player("What are the rewards?"); + stage = 120; + break; + case 4: + player("How do I claim the rewards?"); + stage = 130; + break; + case 5: + player("See you later."); + stage = 999; + break; + } + break; + + case 110: + npc("Ah, well, it's a diary that helps you keep track of", "particular achievements you've made here on Gielinor."); + stage = 111; + break; + case 111: + npc("If you manage to complete a particular set of tasks,", "you will be rewarded for your explorative efforts."); + stage = 112; + break; + case 112: + npc("You can access your Achievement Diary by going to", "the Quest Journal, then clicking on the green star icon", "in the top-right hand corner."); + stage = 105; + break; + + case 120: + npc("Ah, well there are different rewards for each", "Achievement Diary. For completing each stage of the", "Falador diary, you are presented with a Falador shield."); + stage = 121; + break; + case 121: + npc("There are three shields available, one for each difficulty", "level."); + stage = 122; + break; + case 122: + npc("When you are presented with your rewards, you will", "be told of their uses."); + stage = 105; + break; + + case 130: + npc("You need to complete all of the tasks in a particular", "difficulty, then you can claim your reward."); + stage = 131; + break; + case 131: + npc("Some of Falador's tasks are simple, some will require", "certain skill levels, and some might require quests to be", "started or completed."); + stage = 132; + break; + case 132: + npc("To claim your Falador Achievement Diary rewards,", "speak to the chemist in Rimmington, Sir Vyvin's squire", "in the White Knight's Castle, or myself."); + stage = 105; + break; + + case 150: + npc("This is the first stage fo the Falador shield: a buckler. It", "grants you access to a Prayer restore ability and an", "emote."); + stage = 151; + break; + case 151: + npc("Each of these features can be triggered while wielding", "the shield by selecting the 'Operate' option. The Prayer", "restore can also be activated from your inventory."); + stage = 152; + break; + case 152: + npc("The Prayer restore ability can only be used once per", "day, and gives you back a quarter of your Prayer", "points."); + stage = 153; + break; + case 153: + npc("As well as all of these features, the shield is pretty", "handy in combat, and gives you a small Prayer boost."); + stage = 105; + break; + + case 200: + if (AchievementDiary.canReplaceReward(player, DiaryType.FALADOR, level)) { + playerl(FacialExpression.HALF_GUILTY, "I seem to have lost my shield..."); + stage = 250; + } else if (AchievementDiary.hasClaimedLevelRewards(player, DiaryType.FALADOR, level)) { + npc("But you've already gotten yours!"); + stage = 105; + } else if (AchievementDiary.hasCompletedLevel(player, DiaryType.FALADOR, level)) { + npc("So, you've finished. Well done! I believe congratulations", "are in order."); + stage = 201; + } else { + npc("But you haven't finished!"); + stage = 105; + } + break; + case 201: + player("I believe rewards are in order."); + stage = 202; + break; + case 202: + npc("Right you are."); + stage = 203; + break; + case 203: + npc("This is the first stage of the Falador shield: a buckler. It", "grants you access to a Prayer restore ability and an", "emote."); + AchievementDiary.flagRewarded(player, DiaryType.FALADOR, level); + stage = 204; + break; + case 204: + npc("Each of these features can be triggered while wielding", "the shield by selecting the 'Operate' option. The Prayer", "restore can also be activated from your inventory."); + stage = 205; + break; + case 205: + npc("The Prayer restore ability can only be used once per", "day, and gives you back a quarter of your Prayer", "points."); + stage = 206; + break; + case 206: + npc("As well as all of these features, the shield is pretty", "handy in combat, and gives you a small Prayer boost."); + stage = 207; + break; + case 207: + npc("I've even thrown in a bit of booty I found on my", "travels."); + stage = 208; + break; + case 208: + interpreter.sendDialogues(player, FacialExpression.AMAZED, "Wow, thanks!"); + stage = 209; + break; + case 209: + npc("If you should lose your shield, come back and see me", "for another one."); + stage = 105; + break; + case 220: + npc("Keep it up!"); + stage = 105; + break; + case 250: + npcl(FacialExpression.LAUGH, "Alright, matey, I'll give ye a new one."); + stage++; + break; + case 251: + AchievementDiary.grantReplacement(player, DiaryType.FALADOR, level); + npcl(FacialExpression.FRIENDLY, "Be more careful this time, aye?"); + stage = END_DIALOGUE; + break; + } + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new RedbeardFrankDialogue(player); + } + + @Override + public int[] getIds() { + return new int[]{375}; + } + +} diff --git a/Server/src/main/content/region/asgarnia/portsarim/dialogue/TakiDwarfDialogue.java b/Server/src/main/content/region/asgarnia/portsarim/dialogue/TakiDwarfDialogue.java new file mode 100644 index 0000000..7df140e --- /dev/null +++ b/Server/src/main/content/region/asgarnia/portsarim/dialogue/TakiDwarfDialogue.java @@ -0,0 +1,66 @@ +package content.region.asgarnia.portsarim.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Handles the TakiDwarfDialogue dialogue. + * @author 'Vexia + */ +@Initializable +public class TakiDwarfDialogue extends DialoguePlugin { + + public TakiDwarfDialogue() { + + } + + public TakiDwarfDialogue(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[] { 7115 }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + + switch (stage) { + case 0: + interpreter.sendDialogues(player, FacialExpression.HAPPY, "Hi little fellow."); + stage = 1; + break; + case 1: + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "What did you just say to me!?"); + stage = 2; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.GUILTY, "Arrr! nothing, nothing at all.."); + stage = 3; + break; + case 3: + end(); + break; + } + + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new TakiDwarfDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "Arrr!"); + stage = 0; + return true; + } +} diff --git a/Server/src/main/content/region/asgarnia/portsarim/dialogue/WydinDialogue.java b/Server/src/main/content/region/asgarnia/portsarim/dialogue/WydinDialogue.java new file mode 100644 index 0000000..50b38cc --- /dev/null +++ b/Server/src/main/content/region/asgarnia/portsarim/dialogue/WydinDialogue.java @@ -0,0 +1,234 @@ +package content.region.asgarnia.portsarim.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the dialogue that handles the wydin npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class WydinDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code WydinDialogue} {@code Object}. + */ + public WydinDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code WydinDialogue} {@code Object}. + * @param player the player. + */ + public WydinDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new WydinDialogue(player); + } + + @Override + public boolean open(Object... args) { + boolean door = false; + if (args.length == 2) + door = (boolean) args[1]; + if (door) { + if (player.getSavedData().getGlobalData().isWydinEmployee()) { + interpreter.sendDialogues(557, FacialExpression.HALF_GUILTY, "Can you put your white apron on before going in there", "please."); + stage = 100; + } else { + interpreter.sendDialogues(557, FacialExpression.ANGRY, "Hey, you can't go in there. Only employees of the", "grocery store can go in."); + stage = 100; + } + return true; + } else { + npc = (NPC) args[0]; + } + if (player.getSavedData().getGlobalData().isWydinEmployee()) { + interpreter.sendDialogues(557, FacialExpression.ASKING, "Is it nice and tidy round the back now?"); + stage = 0; + } else { + interpreter.sendDialogues(557, FacialExpression.HAPPY, "Welcome to my food store! Would you like to buy", "anything?"); + stage = 0; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + if (player.getSavedData().getGlobalData().isWydinEmployee()) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "Yes, can I work out front now?", "Yes, are you going to pay me yet?", "No, it's a complete mess.", "Can I buy something please?"); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.ASKING, "Yes, can I work out front now?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.ASKING, "Yes, are you going to pay me yet?"); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No, it's a complete mess."); + stage = 30; + break; + case 4: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Can I buy something please?"); + stage = 40; + break; + + } + break; + case 10: + interpreter.sendDialogues(557, FacialExpression.NEUTRAL, "No, I'm the one who works here."); + stage = 11; + break; + case 11: + end(); + break; + case 20: + interpreter.sendDialogues(557, FacialExpression.THINKING, "Umm... No, not yet."); + stage = 21; + break; + case 21: + end(); + break; + case 30: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No, it's a complete mess."); + stage = 31; + break; + case 31: + interpreter.sendDialogues(557, FacialExpression.THINKING, "Ah well, it'll give you something to do, won't it."); + stage = 32; + break; + case 32: + end(); + break; + case 40: + interpreter.sendDialogues(557, FacialExpression.HAPPY, "Yes, ofcourse."); + stage = 41; + break; + case 41: + end(); + npc.openShop(player); + break; + case 100: + end(); + break; + } + } else { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "Yes please.", "No, thank you.", "What can you recommend?", "Can I get a job here?"); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HAPPY, "Yes please."); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No, thank you."); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.ASKING, "What can you recommend?"); + stage = 30; + break; + case 4: + interpreter.sendDialogues(player, FacialExpression.ASKING, "Can I get a job here?"); + stage = 40; + break; + } + break; + case 10: + end(); + npc.openShop(player); + break; + case 20: + end(); + break; + case 30: + interpreter.sendDialogues(557, FacialExpression.HAPPY, "We have this really exotic fruit all the way from", "Karamja. It's called a banana."); + stage = 31; + break; + case 31: + interpreter.sendOptions("Select an Option", "Hmm, I think I'll try one.", "I don't like the sound of that."); + stage = 32; + break; + case 32: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.FRIENDLY, "Hmm, I think I'll try one."); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I don't like the sound of that."); + stage = 100; + break; + } + break; + case 40: + interpreter.sendDialogues(557, FacialExpression.HAPPY, "Well, you're keen, I'll give you that. Okay, I'll give you", "a go. Have you got your own white apron?"); + stage = 41; + break; + case 41: + if (!player.getInventory().contains(1005, 1) && !player.getEquipment().contains(1005, 1) && !player.getBank().contains(1005, 1)) { + interpreter.sendDialogues(player, FacialExpression.SAD, "No, I haven't."); + stage = 42; + } else { + interpreter.sendDialogues(player, FacialExpression.HAPPY, "Yes, I have one."); + stage = 50; + } + break; + case 42: + interpreter.sendDialogues(557, FacialExpression.FRIENDLY, "Well, you can't work here unless you have a white", "apron. Health and safety regulations, you understand."); + stage = 43; + break; + case 43: + interpreter.sendDialogues(player, FacialExpression.ASKING, "Where can I get one of those?"); + stage = 44; + break; + case 44: + interpreter.sendDialogues(557, FacialExpression.FRIENDLY, "Well, I get all of mine over at the clothing shop in", "Varrock. They sell them cheap there."); + stage = 45; + break; + case 45: + interpreter.sendDialogues(557, FacialExpression.FRIENDLY, "Oh, and I'm sure that I've seen a spare one over in", "Gerrant's fish store somewhere. It's the little place just", "north of here."); + stage = 46; + break; + case 46: + end(); + break; + case 50: + player.getSavedData().getGlobalData().setWydinEmployee(true); + interpreter.sendDialogues(557, FacialExpression.HAPPY, "Wow - you are well prepared! You're hired. Go through", "to the back and tidy up for me, please."); + stage = 100; + break; + case 100: + end(); + break; + } + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 557 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/portsarim/handlers/AhabBeerInteraction.java b/Server/src/main/content/region/asgarnia/portsarim/handlers/AhabBeerInteraction.java new file mode 100644 index 0000000..57bcdce --- /dev/null +++ b/Server/src/main/content/region/asgarnia/portsarim/handlers/AhabBeerInteraction.java @@ -0,0 +1,32 @@ +package content.region.asgarnia.portsarim.handlers; + +import core.game.interaction.Option; +import core.game.interaction.SpecialGroundInteraction; +import core.game.interaction.SpecialGroundItems; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.world.map.RegionManager; +import org.rs09.consts.NPCs; + +import static core.api.ContentAPIKt.findLocalNPC; + +/** + * Handles Ahab's beer in port sarim + * @author ceik + */ + +public class AhabBeerInteraction extends SpecialGroundInteraction { + //The dialogue key + public static final int DIALOGUE_KEY = 2692; + + @Override + public void handle(final Player player, final Option option){ + configure(); + if(option.getName() == "take"){ + player.faceLocation(SpecialGroundItems.AHAB_BEER.getLocation()); + player.getDialogueInterpreter().open(DIALOGUE_KEY, findLocalNPC(player, NPCs.AHAB_2692), false); + } else { + player.debug("Unhandled option: " + option.getName()); + } + } +} diff --git a/Server/src/main/content/region/asgarnia/portsarim/handlers/ElementalWizardNPC.java b/Server/src/main/content/region/asgarnia/portsarim/handlers/ElementalWizardNPC.java new file mode 100644 index 0000000..c00c9dc --- /dev/null +++ b/Server/src/main/content/region/asgarnia/portsarim/handlers/ElementalWizardNPC.java @@ -0,0 +1,329 @@ +package content.region.asgarnia.portsarim.handlers; + +import core.ServerConstants; +import core.game.node.entity.player.link.diary.DiaryType; +import core.plugin.Initializable; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.combat.spell.MagicSpell; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.spell.CombatSpell; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Plugin; +import core.tools.RandomFunction; + +/** + * Represents the elemental wizard npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class ElementalWizardNPC extends AbstractNPC { + + /** + * Represents the spells to use. + */ + private static final int[][] SPELLS = new int[][] { { 8, 7 }, { 4, 7 }, { 6, 7 }, { 1, 7 } }; + + /** + * Constructs a new {@code ElementalWizardNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + public ElementalWizardNPC(int id, Location location) { + super(id, location, true); + getProperties().getCombatPulse().setStyle(CombatStyle.MAGIC); + } + + /** + * Constructs a new {@code ElementalWizardNPC} {@code Object}. + */ + public ElementalWizardNPC() { + super(0, null); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new ElementalWizardNPC(id, location); + } + + @Override + public void onImpact(Entity entity, BattleState state) { + if (state.getSpell() != null && isSpellType(state.getSpell())) { + state.setEstimatedHit(0); + state.setMaximumHit(0); + sendChat("Gratias tibi ago"); + getSkills().heal(getSkills().getStaticLevel(Skills.HITPOINTS)); + Entity attacker = state.getAttacker(); + if (attacker instanceof Player && !attacker.asPlayer().getAchievementDiaryManager().getDiary(DiaryType.FALADOR).isComplete(0, 8)) { + attacker.asPlayer().getAchievementDiaryManager().getDiary(DiaryType.FALADOR).updateTask(attacker.asPlayer(), 0, 8, true); + } + } + if (getAttribute("switch", false)) { + setBaseSpell(); + removeAttribute("switch"); + } + if (RandomFunction.random(6) > 4) { + setSpell(); + } + super.onImpact(entity, state); + } + + /** + * Sets the spell. + */ + private void setSpell() { + int[] spells = SPELLS[getSpellIndex()]; + getProperties().setAutocastSpell((CombatSpell) SpellBook.MODERN.getSpell(spells[RandomFunction.random(spells.length)])); + setAttribute("switch", true); + } + + /** + * Sets the base spell type. + */ + private void setBaseSpell() { + getProperties().setAutocastSpell((CombatSpell) SpellBook.MODERN.getSpell(SPELLS[getSpellIndex()][0])); + } + + /** + * Checks if it is the correct spell type. + * @param spell the spell. + * @return {@code True} if so. + */ + private boolean isSpellType(MagicSpell spell) { + switch (getSpellIndex()) { + case 0:// fire + return spell.getClass().getSimpleName().startsWith("Fire"); + case 1:// water + return spell.getClass().getSimpleName().startsWith("Water"); + case 2:// earth + return spell.getClass().getSimpleName().startsWith("Earth"); + case 3:// air + return spell.getClass().getSimpleName().startsWith("Air"); + } + return false; + } + + /** + * Gets the spell index. + * @return the index. + */ + private int getSpellIndex() { + for (int i = 0; i < getIds().length; i++) { + if (getIds()[i] == getId()) { + return i; + } + } + return 0; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + new MaligniusMortifer().init(); + return super.newInstance(arg); + } + + @Override + public int[] getIds() { + return new int[] { 2709, 2710, 2711, 2712 }; + } + + /** + * Represents the malignius mortifer dialogue. + * @author 'Vexia + * @version 1.0 + */ + public final class MaligniusMortifer extends DialoguePlugin { + + /** + * Constructs a new {@code MaligniusMortifer} {@code Object}. + */ + public MaligniusMortifer() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code MaligniusMortifer} {@code Object}. + * @param player the player. + */ + public MaligniusMortifer(final Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new MaligniusMortifer(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + npc("So, " + player.getUsername() + ", your curiosity leads you to speak to me?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + options("Who are you and what are you doing here?", "Can you teach me something about magic?", "Where can I get clothes like those?", "Actually, I don't want to talk to you."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + player("Who are you and what are you doing here?"); + stage = 10; + break; + case 2: + player("Can you teach me something about magic?"); + stage = 20; + break; + case 3: + player("Where can I get clothes like those?"); + stage = 30; + break; + case 4: + player("Actually, I don't want to talk to you."); + stage = 40; + break; + } + break; + case 10: + npc("I am the great Malignius Mortifer, wielder of strange", "and terrible powers. These lowly followers of mine are", "dedicated students of the magical arts. Their business is", "to follow me and learn all they can."); + stage = 11; + break; + case 11: + player("There don't look very tough."); + stage = 12; + break; + case 12: + npc("You may believe that, but even if you strike one down,", "another will rise up within minutes."); + stage = 13; + break; + case 13: + player("Yeah, right."); + stage = 14; + break; + case 14: + npc("Each of my followers is a master of his chosen element.", "His life becomes bound to that element in a way you", "could not hope to understand."); + stage = 15; + break; + case 15: + player("And what do you do?"); + stage = 16; + break; + case 16: + npc("I am mastering a branch of magic that few dare to", "attempt: Necromancy! THe fools in the Guild of", "Wizards shun anyone who practices this art, but there", "are a few across the lands who know the rudiments."); + stage = 17; + break; + case 17: + npc("Grayzag and Invrigar... Even Melzar studied the", "methods of necromancy, until an accident affected his", "mind. Now his spells tend to result in..."); + stage = 18; + break; + case 18: + npc("... well, let us simply say that he does NOT raise", "armies of undead minions."); + stage = 19; + break; + case 19: + end(); + break; + case 20: + npc("Ah, you are an inquisitive young fellow. I shall speak of", "the great Wizards' Tower, destroyed by fire many", "years ago..."); + stage = 21; + break; + case 21: + npc("Many say it was the greatest building in the history of", ServerConstants.SERVER_NAME + ", a magnificent monument to human ingenuity."); + stage = 22; + break; + case 22: + npc("Yet when humans are offered great power, they so", "often buy it at the cost of their principles."); + stage = 23; + break; + case 23: + npc("Wizards who claimed allegiance to Saradomin began to", "insist that magic be restriced to the few they deemed", "'worthy' of such powers."); + stage = 24; + break; + case 24: + npc("Before long, those who did not share their fatuous", "obsession with Saradomin were excluded from the", "Tower comletely. This state of affairs could not", "continue."); + stage = 25; + break; + case 25: + end(); + break; + case 30: + npc("Bah! Our garments are an outward sign of our", "dominance of the magical arts. You cannot simply buy", "them in a shop."); + stage = 31; + break; + case 31: + player("What happens if I kill you and take them?"); + stage = 32; + break; + case 32: + npc("Try it and see!"); + stage = 33; + break; + case 33: + player("How about if you teach me enough about magic so I", "can wear those clothes too?"); + stage = 34; + break; + case 34: + npc("How about if I turn you into a mushroom to make you", "stop bothering me?"); + stage = 35; + break; + case 35: + transform(); + break; + case 40: + npc("Bah! Then go away!"); + stage = 41; + break; + case 41: + end(); + break; + } + return true; + } + + /** + * Method used to transform the player into a mushroom. + */ + private void transform() { + interpreter.sendDialogues(player, null, true, "MMMmmph!"); + npc.animate(Animation.create(811)); + player.getAppearance().transformNPC(3345); + player.graphics(Graphics.create(453)); + player.lock(8); + player.getLocks().lockMovement(10000); + GameWorld.getPulser().submit(new Pulse(12) { + @Override + public boolean pulse() { + player.getWalkingQueue().reset(); + player.getLocks().unlockMovement(); + player.getAppearance().transformNPC(-1); + end(); + return true; + } + }); + } + + @Override + public int[] getIds() { + return new int[] { 2713 }; + } + + } +} diff --git a/Server/src/main/content/region/asgarnia/portsarim/handlers/PortSarimPlugin.java b/Server/src/main/content/region/asgarnia/portsarim/handlers/PortSarimPlugin.java new file mode 100644 index 0000000..8746b7e --- /dev/null +++ b/Server/src/main/content/region/asgarnia/portsarim/handlers/PortSarimPlugin.java @@ -0,0 +1,147 @@ +package content.region.asgarnia.portsarim.handlers; + +import core.cache.def.impl.NPCDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; +import core.plugin.Initializable; +import core.tools.RandomFunction; +import content.data.Quests; + +/** + * Represents the port sarim plugin. + * + * @author 'Vexia + * @date 30/11/2013 + */ +@Initializable +public final class PortSarimPlugin extends OptionHandler { + + /** + * Represents the taking animation. + */ + private static final Animation TAKE_ANIM = new Animation(832); + + /** + * Represents the karamjan rum item. + */ + private static final Item KARAMJAN_RUM = new Item(431); + + /** + * Represents the messages the sleeping guard can say. + */ + private static final String MESSAGES[] = new String[] { "Hmph... heh heh heh...", "Mmmm... big pint of beer... kebab...", "Mmmmmm... donuts...", "Guh.. mwww... zzzzzz..." }; + + /** + * Represents the entrana monks. + */ + private static final int[] MONKS = new int[] { 2728, 657, 2729, 2730, 2731, 658 }; + + @Override + public Plugin newInstance(Object arg) throws Throwable { + NPCDefinition.forId(2704).getHandlers().put("option:talk-to", this); + SceneryDefinition.forId(9565).getHandlers().put("option:open", this); + SceneryDefinition.forId(9565).getHandlers().put("option:pick-lock", this); + SceneryDefinition.forId(9563).getHandlers().put("option:open", this); + for (int i : MONKS) { + NPCDefinition.forId(i).getHandlers().put("option:take-boat", this); + } + SceneryDefinition.forId(2071).getHandlers().put("option:search", this); + NPCDefinition.forId(745).getHandlers().put("option:attack", this); + SceneryDefinition.forId(33173).getHandlers().put("option:exit", this); + SceneryDefinition.forId(33174).getHandlers().put("option:enter", this); + return this; + } + + @Override + public boolean handle(final Player player, Node node, String option) { + switch (option) { + case "enter": + player.getProperties().setTeleportLocation(Location.create(3056, 9562, 0)); + player.getPacketDispatch().sendMessage("You leave the icy cavern."); + break; + case "exit": + player.getDialogueInterpreter().open(238284); + break; + case "attack": + if (player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER).getStage(player) != 20) { + player.getPacketDispatch().sendMessage("The goblin is already in prison. You have no reason to attack him."); + } else { + player.getProperties().getCombatPulse().attack(node); + } + break; + case "take-boat": + player.getDialogueInterpreter().open(((NPC) node).getId(), ((NPC) node)); + break; + case "open": + switch (((Scenery) node).getId()) { + case 9565: + case 9563: + player.getPacketDispatch().sendMessage("The door is securely locked."); + break; + } + break; + case "pick-lock": + switch (((Scenery) node).getId()) { + case 9565: + if (player.getLocation().getY() <= 3187) { + player.getPacketDispatch().sendMessage("You simply cannot find a way to pick the lock from this side."); + return true; + } + break; + } + break; + case "talk-to": + player.lock(2); + ((NPC) node).sendChat(MESSAGES[RandomFunction.random(MESSAGES.length)]); + GameWorld.getPulser().submit(new Pulse(1) { + @Override + public boolean pulse() { + player.getDialogueInterpreter().sendDialogues(player, null, "Maybe I should let him sleep."); + return true; + } + }); + break; + case "search":// banan box + if (player.getInventory().freeSlots() == 0) { + player.getPacketDispatch().sendMessage("Not enough inventory space."); + return true; + } + player.getPacketDispatch().sendMessage("There are lots of bananas in the crate."); + player.lock(2); + GameWorld.getPulser().submit(new Pulse(1) { + @Override + public boolean pulse() { + if (player.getAttribute("wydin-rum", false)) { + if (player.getInventory().add(KARAMJAN_RUM)) { + player.removeAttribute("wydin-rum"); + player.removeAttribute("stashed-rum"); + player.animate(TAKE_ANIM); + player.getPacketDispatch().sendMessage("You find your bottle of rum in amongst the bananas."); + } + return true; + } + player.getDialogueInterpreter().open(9682749); + return true; + } + + }); + break; + } + return true; + } + + @Override + public boolean isWalk(final Player player, final Node node) { + return !(node instanceof Item); + } +} diff --git a/Server/src/main/content/region/asgarnia/portsarim/handlers/PortsObjectPlugin.java b/Server/src/main/content/region/asgarnia/portsarim/handlers/PortsObjectPlugin.java new file mode 100644 index 0000000..7f45a94 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/portsarim/handlers/PortsObjectPlugin.java @@ -0,0 +1,331 @@ +package content.region.asgarnia.portsarim.handlers; + +import core.cache.def.impl.SceneryDefinition; +import core.game.global.action.ClimbActionHandler; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.world.map.Location; +import core.game.world.repository.Repository; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; +import content.data.Quests; + +/** + * Represents the option handler for port sarim. + * @author 'Vexia + * @date 27/11/2013 + */ +@Initializable +public class PortsObjectPlugin extends OptionHandler { + + /** + * Represents the locations of crossing a gang plank at port sarim. + */ + private final Location PORT_SARIM[] = new Location[] {/* + * port sarim - entrana + * boat + */ + new Location(3048, 3231, 1), Location.create(3048, 3234, 0), new Location(3038, 3192, 0), new Location(3038, 3189, 1), new Location(3032, 3217, 1), new Location(3029, 3217, 0), new Location(3041, 3199, 1), new Location(3041, 3202, 0) }; + + /** + * Represents the entrana locations. + */ + private final Location ENTRANA[] = new Location[] { /* entrana boat */ + new Location(2834, 3331, 1), new Location(2834, 3335, 0) }; + + /** + * Represents the karamja locations. + */ + private final Location KARAMJA[] = new Location[] { new Location(2956, 3143, 1), new Location(2956, 3146, 0), new Location(2957, 3158, 1), new Location(2954, 3158, 0) }; + + /** + * Represents the catherby locations. + */ + private final Location CATHERBY[] = new Location[] { new Location(2792, 3417, 1), new Location(2792, 3414, 0) }; + + /** + * Represents the location teleport to in brimhaven. + */ + private final Location BRIMHAVEN[] = new Location[] { new Location(2763, 3238, 1), Location.create(2760, 3238, 0), new Location(2775, 3234, 1), new Location(2772, 3234, 0) }; + + /** + * Represents the ardougne location. + */ + private final Location ARDOUGNE[] = new Location[] { new Location(2683, 3268, 1), new Location(2683, 3271, 0) }; + + /** + * Represents the port khazard location. + */ + private final Location PORT_KHAZARD[] = new Location[] { new Location(2674, 3141, 1), new Location(2674, 3144, 0) }; + + /** + * represents the port phastmatys locations. + */ + private final Location PORT_PHASMATYS[] = new Location[] { new Location(3705, 3503, 1), new Location(3702, 3503, 0) }; + + /** + * Represents the pest control location. + */ + private final Location PEST_CONTROL[] = new Location[] { new Location(2662, 2676, 1), new Location(2659, 2676, 0) }; + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(2412).getHandlers().put("option:cross", this);// port + // sarim + // - + // entrana + // boat. + SceneryDefinition.forId(2413).getHandlers().put("option:cross", this);// port + // sarim + // - + // entrana + // boat. + SceneryDefinition.forId(17404).getHandlers().put("option:cross", this);// port + // sarim + // - + // charter + // boat. + SceneryDefinition.forId(17405).getHandlers().put("option:cross", this);// port + // sarim + // - + // charter + // boat. + SceneryDefinition.forId(2083).getHandlers().put("option:cross", this);// port + // sarim + // - + // regular + // boat. + SceneryDefinition.forId(2084).getHandlers().put("option:cross", this);// port + // sarim + // - + // regular + // boat. + SceneryDefinition.forId(14304).getHandlers().put("option:cross", this);// port + // sarim + // - + // regular + // boat. + SceneryDefinition.forId(14305).getHandlers().put("option:cross", this);// port + // sarim + // - + // regular + // boat. + SceneryDefinition.forId(2593).getHandlers().put("option:cross", this);// port + // sarim + // - + // lady + // lumbridge. + SceneryDefinition.forId(2415).getHandlers().put("option:cross", this);// entrana + // off + // boat. + SceneryDefinition.forId(2414).getHandlers().put("option:cross", this);// entrana + // on + // boat. + SceneryDefinition.forId(2081).getHandlers().put("option:cross", this);// karamaja + // boat + // (on) + SceneryDefinition.forId(2082).getHandlers().put("option:cross", this);// karamaja + // boat + // (off) + SceneryDefinition.forId(17398).getHandlers().put("option:cross", this);// karamaja + // boat + // (on)(second) + SceneryDefinition.forId(17399).getHandlers().put("option:cross", this);// karamaja + // boat + // (off)(second) + SceneryDefinition.forId(17394).getHandlers().put("option:cross", this);// catherby + // boat + // (on) + SceneryDefinition.forId(17395).getHandlers().put("option:cross", this);// catherby + // boat + // (off) + SceneryDefinition.forId(69).getHandlers().put("option:cross", this);// catherby + // boat + // (on)(second) + SceneryDefinition.forId(17401).getHandlers().put("option:cross", this);// brimhaven + // (off) + SceneryDefinition.forId(17400).getHandlers().put("option:cross", this);// brimhaven + // (on) + SceneryDefinition.forId(2087).getHandlers().put("option:cross", this);// brimhaven + // (on)(second) + SceneryDefinition.forId(2088).getHandlers().put("option:cross", this);// brimhaven + // (off)(second) + SceneryDefinition.forId(2086).getHandlers().put("option:cross", this);// ardougne + // (off) + SceneryDefinition.forId(2085).getHandlers().put("option:cross", this);// ardougne + // (on) + SceneryDefinition.forId(17402).getHandlers().put("option:cross", this);// port + // khazard + // (on) + SceneryDefinition.forId(17403).getHandlers().put("option:cross", this);// port + // khazard + // (off) + SceneryDefinition.forId(17392).getHandlers().put("option:cross", this);// port + // phasmatys(on) + SceneryDefinition.forId(17393).getHandlers().put("option:cross", this);// port + // phasmatys(off) + SceneryDefinition.forId(11209).getHandlers().put("option:cross", this);// port + // phasmatys(other + // boat) + SceneryDefinition.forId(14307).getHandlers().put("option:cross", this);// pest + // control + // ship. + SceneryDefinition.forId(14306).getHandlers().put("option:cross", this);// pest + // control + // ship. + // lady lumby + SceneryDefinition.forId(2590).getHandlers().put("option:climb-down", this); + SceneryDefinition.forId(2592).getHandlers().put("option:climb-up", this); + SceneryDefinition.forId(2594).getHandlers().put("option:cross", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + final int id = ((Scenery) node).getId(); + switch (option) { + case "climb-up": + ClimbActionHandler.climb(player, new Animation(828), new Location(3048, 3208, 1)); + break; + case "climb-down": + ClimbActionHandler.climb(player, new Animation(828), new Location(3048, 9640, 1)); + break; + case "cross": + switch (id) { + case 2594: + cross(player, Location.create(3047, 3204, 0)); + break; + case 14306: + cross(player, PEST_CONTROL[0]); + player.getPacketDispatch().sendMessage("You board the ship."); + break; + case 14307: + cross(player, PEST_CONTROL[1]); + player.getPacketDispatch().sendMessage("You disembark the ship."); + break; + case 2593: + if (player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER).getStage(player) == 100) { + player.getDialogueInterpreter().open(744, Repository.findNPC(744), true);// lady + // lumbridge. + return true; + } + if (!player.getSavedData().getQuestData().getDragonSlayerAttribute("ship")) { + player.getDialogueInterpreter().open(744, Repository.findNPC(744), true);// lady + // lumbridge. + } else { + player.getPacketDispatch().sendMessage("You board the ship."); + cross(player, new Location(3047, 3207, 1)); + } + break; + case 14304: + cross(player, PORT_SARIM[6]); + player.getPacketDispatch().sendMessage("You board the ship."); + break; + case 14305: + cross(player, PORT_SARIM[7]); + player.getPacketDispatch().sendMessage("You disembark the ship."); + break; + case 2083: + cross(player, PORT_SARIM[4]);// port - sarim random + // boat. + break; + case 2084: + cross(player, PORT_SARIM[5]);// port - sarim random + // boat. + break; + case 17404: + cross(player, PORT_SARIM[3]);// port sarim charter boat. + break; + case 17405: + cross(player, PORT_SARIM[2]);// port sarim charter boat. + break; + case 11209: + player.getDialogueInterpreter().sendDialogues(player, null, "I don't think that whoever owns this ship will be happy", "with me wandering all over it."); + break; + case 17392: + cross(player, PORT_PHASMATYS[0]);// port phasmatys on. + break; + case 17393: + cross(player, PORT_PHASMATYS[1]);// port phasmatys off. + break; + case 17402: + cross(player, PORT_KHAZARD[0]);// port khazard on. + break; + case 17403: + cross(player, PORT_KHAZARD[1]);// port khazard off. + break; + case 2086: + cross(player, ARDOUGNE[1]);// ardougne off + break; + case 2085: + cross(player, ARDOUGNE[0]);// ardougne on. + player.getPacketDispatch().sendMessage("You must speak to Captain Barnaby before it will set sail."); + break; + case 2087: + cross(player, BRIMHAVEN[2]);// brimhaven second ship(pay + // fare) + player.getPacketDispatch().sendMessage("You must speak to the Customs Officer before it will set sail."); + break; + case 2088: + cross(player, BRIMHAVEN[3]);// brimhaven second ship(pay + // fare) + break; + case 17401: + cross(player, BRIMHAVEN[1]);// entrana on boat. + break; + case 17400: + cross(player, BRIMHAVEN[0]);// entrana off boat. + break; + case 69:// arhein ship. + player.getDialogueInterpreter().open(563, Repository.findNPC(563), true); + break; + case 17394: + cross(player, CATHERBY[0]);// catherby on + break; + case 17395: + cross(player, CATHERBY[1]);// catherby off + break; + case 2412:// port-sarim to entrana(on boat) + cross(player, PORT_SARIM[0]); + break; + case 2413:// port-sarim to entrana(off boat) + cross(player, PORT_SARIM[1]); + break; + case 2414:// entrana on boat. + cross(player, ENTRANA[0]); + break; + case 2415:// entrana off boat. + cross(player, ENTRANA[1]); + break; + case 2081: + cross(player, KARAMJA[0]); + break; + case 2082: + cross(player, KARAMJA[1]); + break; + case 17398: + cross(player, KARAMJA[2]); + player.getPacketDispatch().sendMessage("You must speak to the Customs Officer before it will set sail."); + break; + case 17399: + cross(player, KARAMJA[3]); + player.getPacketDispatch().sendMessage("You must speak to the Customs Officer before it will set sail."); + break; + } + break; + } + return true; + } + + /** + * Method used to cross a gang plank. + * @param player the player. + * @param location + */ + public final void cross(final Player player, Location location) { + player.getProperties().setTeleportLocation(location); + } +} diff --git a/Server/src/main/content/region/asgarnia/portsarim/handlers/SeamanListener.kt b/Server/src/main/content/region/asgarnia/portsarim/handlers/SeamanListener.kt new file mode 100644 index 0000000..104d86c --- /dev/null +++ b/Server/src/main/content/region/asgarnia/portsarim/handlers/SeamanListener.kt @@ -0,0 +1,15 @@ +package content.region.asgarnia.portsarim.handlers + +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.npc.NPC + +class SeamanListener : InteractionListener { + override fun defineListeners() { + on(IntType.NPC, "pay-fare") { player, node -> + val npc = node as NPC + player.dialogueInterpreter.open(npc.id, npc, true) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/portsarim/handlers/WydinDoorPlugin.java b/Server/src/main/content/region/asgarnia/portsarim/handlers/WydinDoorPlugin.java new file mode 100644 index 0000000..05ea0a1 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/portsarim/handlers/WydinDoorPlugin.java @@ -0,0 +1,44 @@ +package content.region.asgarnia.portsarim.handlers; + +import core.cache.def.impl.SceneryDefinition; +import core.game.global.action.DoorActionHandler; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the plugin used for the door near wydin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class WydinDoorPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(2069).getHandlers().put("option:open", this); + return null; + } + + @Override + public boolean handle(Player player, Node node, String option) { + if (!player.getEquipment().contains(1005, 1) && player.getLocation().getX() >= 3011 && player.getLocation().getX() <= 3018) { + player.getDialogueInterpreter().open(557, true, true); + return true; + } else { + final Scenery object = (Scenery) node; + DoorActionHandler.handleAutowalkDoor(player, object); + } + return true; + } + + @Override + public Location getDestination(Node node, Node n) { + return DoorActionHandler.getDestination(((Entity) node), ((Scenery) n)); + } +} diff --git a/Server/src/main/content/region/asgarnia/portsarim/quest/piratestreasure/GardenerNPC.java b/Server/src/main/content/region/asgarnia/portsarim/quest/piratestreasure/GardenerNPC.java new file mode 100644 index 0000000..f0926df --- /dev/null +++ b/Server/src/main/content/region/asgarnia/portsarim/quest/piratestreasure/GardenerNPC.java @@ -0,0 +1,90 @@ +package content.region.asgarnia.portsarim.quest.piratestreasure; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.plugin.Initializable; +import core.game.world.map.Location; + +/** + * Represents the abstract garden npc used for pirates treasure. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class GardenerNPC extends AbstractNPC { + + /** + * The NPC ids of NPCs using this plugin. + */ + private static final int[] ID = { 1217 }; + + /** + * Constructs a new {@code GardenerNPC} {@code Object}. + */ + public GardenerNPC() { + super(0, null, true); + } + + /** + * Constructs a new {@code RomeoNPC} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + private GardenerNPC(int id, Location location) { + super(id, location, true); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new GardenerNPC(id, location); + } + + @Override + public void tick() { + super.tick(); + if (getAttribute("target", null) != null) { + final Player target = (Player) getAttribute("target", null); + if (getProperties().getCombatPulse().isRunning()) { + getProperties().getCombatPulse().attack(target); + } + if (!target.isActive() || target.getLocation().getDistance(getLocation()) > 16) { + GameWorld.getPulser().submit(new Pulse(2) { + @Override + public boolean pulse() { + clear(); + return true; + } + }); + } + } + } + + @Override + public boolean isAttackable(Entity entity, CombatStyle style, boolean message) { + final Player target = getAttribute("target", null); + if (target != entity) { + return false; + } + return super.isAttackable(entity, style, message); + } + + @Override + public void finalizeDeath(final Entity killer) { + final Player target = getAttribute("target", null); + if (target != null && target == killer) { + target.getSavedData().getQuestData().setGardenerAttack(true); + } + ; + super.finalizeDeath(killer); + } + + @Override + public int[] getIds() { + return ID; + } + +} diff --git a/Server/src/main/content/region/asgarnia/portsarim/quest/piratestreasure/PiratesTreasure.java b/Server/src/main/content/region/asgarnia/portsarim/quest/piratestreasure/PiratesTreasure.java new file mode 100644 index 0000000..65ab84c --- /dev/null +++ b/Server/src/main/content/region/asgarnia/portsarim/quest/piratestreasure/PiratesTreasure.java @@ -0,0 +1,143 @@ +package content.region.asgarnia.portsarim.quest.piratestreasure; + +import core.game.component.Component; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.ClassScanner; +import content.data.Quests; + +/** + * Represents the pirates treasure quest. + * @author Vexia + * + */ +@Initializable +public final class PiratesTreasure extends Quest { + + /** + * Represents the message component for pirates treasure quest. + */ + public static final Component MESSAGE_COMPONENT = new Component(222); + + /** + * Represents the casket rewards (pirates treasure). + */ + public static final Item[] CASKET_REWARDS = new Item[] { new Item(995, 450), new Item(1635), new Item(1605) }; + + /** + * Represents the karamjan rum item. + */ + public static final Item KARAMJAN_RUM = new Item(431); + + /** + * Represents the chest key item. + */ + public static final Item KEY = new Item(432); + + /** + * Represents the pirate message item. + */ + public static final Item PIRATE_MESSAGE = new Item(433); + + /** + * Represents the casket item. + */ + public static final Item CASKET = new Item(7956); + + /** + * Constructs a new {@Code PiratesTreasure} {@Code Object} + */ + public PiratesTreasure() { + super(Quests.PIRATES_TREASURE, 23, 22, 2, 71, 0, 1, 4); + } + + @Override + public Quest newInstance(Object object) { + ClassScanner.definePlugin(new PiratesTreasurePlugin()); + return this; + } + + @Override + public void drawJournal(Player player, int stage) { + super.drawJournal(player, stage); + switch (stage) { + case 0: + player.getPacketDispatch().sendString(BLUE + "I can start this quest by speaking to " + RED + "Redbeard Frank " + BLUE + "who", 275, 4+ 7); + player.getPacketDispatch().sendString(BLUE + "is at " + RED + " Port Sarim.", 275, 5+ 7); + player.getPacketDispatch().sendString(BLUE + "There aren't any requirements for this quest.", 275, 7+ 7); + break; + case 10: + if (!player.getInventory().containsItem(KARAMJAN_RUM)) { + line(player, BLUE + "I have spoken to " + RED + " Redbeard Frank." + BLUE + " He has agreed to tell me", 4+ 7); + line(player, BLUE + "the location of some " + RED + " treasure " + BLUE + "for some " + RED + "Karamjan rum.", 5+ 7); + line(player, BLUE + "I have taken employment on the " + RED + "banana plantation " + BLUE + ", as the", 6+ 7); + line(player, RED + "Customs Officers " + BLUE + "might not notice the " + RED + "rum " + BLUE + "if it is covered", 7+ 7); + line(player, BLUE + "in " + RED + "bananas.", 8+ 7); + line(player, BLUE + "Now all I need is some " + RED + " rum " + BLUE + "to hide in the next crate", 10+ 7); + line(player, BLUE + "destined for " + RED + "Wydin's store" + BLUE + "...", 11+ 7); + } else { + line(player, BLUE + "I have spoken to " + RED + "Redbeard Frank " + BLUE + ". He has agreed to tell me", 5+ 7); + line(player, BLUE + "the location of some " + RED + "treasure " + BLUE + "for some " + RED + "Karamjan rum.", 6+ 7); + line(player, BLUE + "I have the " + RED + "Karamjan rum. " + BLUE + "I should take it to " + RED + "Redbeard Frank.", 8+ 7); + } + break; + case 20: + line(player, "I have smuggled some rum off Karamja, and retrieved it", 4+ 7); + line(player, "from the back room of Wydin's shop.", 5+ 7); + line(player, BLUE + "I have given the rum to " + RED + "Redbeard Frank." + BLUE + " He has told me", 7+ 7); + line(player, BLUE + "that the " + RED + "treasure " + BLUE + "is hidden in the chest in the upstairs", 8+ 7); + line(player, BLUE + "room of the " + RED + "Blue Moon Inn " + BLUE + "in " + RED + "Varrock.", 9+ 7); + if (player.getAttributes().containsKey("pirate-read")) { + line(player, BLUE + "The note reads " + RED + "'Visit the city of the White Knights. In the", 11+ 7); + line(player, RED + "park, Saradomin points to the X which marks the spot.'", 12+ 7); + if (!player.getInventory().containsItem(PIRATE_MESSAGE) && !player.getBank().containsItem(PIRATE_MESSAGE)) { + line(player, BLUE + "It's a good job I remembered that, as I have lost the " + RED + "note.", 14+ 7); + } + return; + } + if (player.getInventory().containsItem(PIRATE_MESSAGE)) { + line(player, BLUE + "I have opened the chest in the " + RED + "Blue Moon" + BLUE + ", and found a", 11+ 7); + line(player, RED + "note " + BLUE + "inside. I think it will tell me where to dig.", 12+ 7); + return; + } + if (player.getInventory().containsItem(KEY)) { + line(player, BLUE + "I have a " + RED + "key " + BLUE + "that can be used to unlock the chest that", 11+ 7); + line(player, BLUE + "holds the treasure.", 12+ 7); + } else { + line(player, BLUE + "I have lost the " + RED + "key " + BLUE + "that " + RED + "Redbeard Frank " + BLUE + "gave me. I should", 11+ 7); + line(player, BLUE + "see if he has another.", 12+ 7); + } + break; + case 100: + line(player, "The note reads 'Visit the city of the White Knights. In the", 4+ 7); + line(player, "park, Saradomin points to the X which marks the spot.'", 5+ 7); + line(player, "QUEST COMPLETE!", 7+ 7); + line(player, BLUE + "I've found a treasure, gained 2 Quest Points and gained", 9+ 7); + line(player, BLUE + "access to the Pay-fare option to travel to and from", 10+ 7); + line(player, BLUE + "Karamja!", 11+ 7); + break; + } + } + + @Override + public void finish(Player player) { + super.finish(player); + player.getPacketDispatch().sendString("2 Quest Points", 277, 8 + 2); + player.getPacketDispatch().sendString("One-Eyed Hector's Treasure", 277, 9 + 2); + player.getPacketDispatch().sendString("Chest", 277, 10 + 2); + player.getPacketDispatch().sendString("You can also use the Pay-", 277, 11 + 2); + player.getPacketDispatch().sendString("fare option to go to and from", 277, 12 + 2); + player.getPacketDispatch().sendString("Karamja", 277, 13 + 2); + player.getPacketDispatch().sendString("You have completed the Pirate's Treasure Quest!", 277, 2 + 2); + player.getPacketDispatch().sendItemZoomOnInterface(7956, 230, 277, 3 + 2); + player.removeAttribute("gardener-attack"); + player.removeAttribute("pirate-read"); + if (!player.getInventory().add(CASKET)) { + GroundItemManager.create(CASKET, player); + } + } + +} diff --git a/Server/src/main/content/region/asgarnia/portsarim/quest/piratestreasure/PiratesTreasurePlugin.java b/Server/src/main/content/region/asgarnia/portsarim/quest/piratestreasure/PiratesTreasurePlugin.java new file mode 100644 index 0000000..ce41de6 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/portsarim/quest/piratestreasure/PiratesTreasurePlugin.java @@ -0,0 +1,121 @@ +package content.region.asgarnia.portsarim.quest.piratestreasure; + +import core.cache.def.impl.ItemDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.game.global.action.DigAction; +import core.game.global.action.DigSpadeHandler; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.HintIconManager; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.world.map.Location; +import core.plugin.Plugin; +import content.data.Quests; + +/** + * Represents the pirates treasure plugin. + * @author Vexia + * + */ +public final class PiratesTreasurePlugin extends OptionHandler { + + /** + * Represents the dig reward to use. + */ + private static final DigAction DIG_ACTION = new TreasureDigPlugin(); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(2079).getHandlers().put("option:open", this);// blue + // moon + // chest(pirates + // treasure + // quest) + ItemDefinition.forId(433).getHandlers().put("option:read", this);// pirate + // message. + ItemDefinition.forId(7956).getHandlers().put("option:open", this); + for (Location l : TreasureDigPlugin.LOCATIONS) { + DigSpadeHandler.register(l, DIG_ACTION); + } + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + int id = node instanceof Scenery ? ((Scenery) node).getId() : ((Item) node).getId(); + switch (id) { + case 2079: + switch (option) { + case "open": + player.getPacketDispatch().sendMessage("The chest is locked."); + break; + } + break; + case 7956:// hectors casket + if (player.getInventory().remove(PiratesTreasure.CASKET)) { + for (Item i : PiratesTreasure.CASKET_REWARDS) { + if (!player.getInventory().add(i)) { + GroundItemManager.create(i, player); + } + } + player.getPacketDispatch().sendMessage("You open the casket, and find One-Eyed Hector's treasure."); + } + break; + case 433: + switch (option) { + case "read": + player.getInterfaceManager().open(PiratesTreasure.MESSAGE_COMPONENT); + player.getPacketDispatch().sendString("Visit the city of the White Knights. In the park,", 222, 5); + player.getPacketDispatch().sendString("Saradomin points to the X which marks the spot.", 222, 6); + player.setAttribute("/save:pirate-read", true); + break; + } + } + return true; + } + + /** + * Represents the treasure dig plugin. + * @author 'Vexia + * @version 1.0 + */ + public static final class TreasureDigPlugin implements DigAction { + + /** + * Represents the locations at which this event will occur. + */ + private static final Location[] LOCATIONS = new Location[] { new Location(2999, 3383, 0), Location.create(3000, 3383, 0) }; + + @Override + public void run(Player player) { + final Quest quest = player.getQuestRepository().getQuest(Quests.PIRATES_TREASURE); + player.lock(2); + if (quest.getStage(player) == 20) { + if (player.getSavedData().getQuestData().isGardenerAttack()) { + player.getPacketDispatch().sendMessage("You dig a hole in the ground..."); + player.getPacketDispatch().sendMessage("and find a little chest of treasure."); + quest.finish(player); + } else { + if (player.getAttribute("gardener-dug", false)) { + return; + } + NPC npc = NPC.create(1217, player.getLocation().transform(0, 1, 0)); + npc.setAttribute("target", player); + npc.setRespawn(false); + npc.init(); + npc.sendChat("First moles, now this! Take this, vandal!"); + npc.getProperties().getCombatPulse().attack(player); + HintIconManager.registerHintIcon(player, npc); + player.setAttribute("gardener-dug", true); + } + return; + } + } + + } +} diff --git a/Server/src/main/content/region/asgarnia/rimmington/dialogue/AnjaDialogue.kt b/Server/src/main/content/region/asgarnia/rimmington/dialogue/AnjaDialogue.kt new file mode 100644 index 0000000..317f964 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/rimmington/dialogue/AnjaDialogue.kt @@ -0,0 +1,87 @@ +package content.region.asgarnia.rimmington.dialogue + +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.node.entity.npc.NPC +import core.game.world.map.RegionManager +import core.tools.RandomFunction +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +/** + * Handles Anja's dialogue. + */ +@Initializable +class AnjaDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + player(FacialExpression.NEUTRAL, "Hello.").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> npcl(FacialExpression.ASKING, "Hello @g[sir,madam]. What are you doing in my house?").also { stage++ } + 1 -> options("I'm just wandering around.", "I was hoping you'd give me some free stuff.", "I've come to kill you.").also { stage++ } + 2 -> when (buttonId) { + 1 -> playerl(FacialExpression.NEUTRAL, "I'm just wondering around.").also { stage = 10 } + 2 -> playerl(FacialExpression.NEUTRAL, "I was hoping you'd give me some free stuff.").also { stage = 20 } + 3 -> playerl(FacialExpression.ANGRY_WITH_SMILE, "I've come to kill you.").also { stage = 30 } + } + + 10 -> npcl(FacialExpression.NEUTRAL, "Oh dear, are you lost?").also { stage++ } + 11 -> options("Yes, I'm lost.", "No, I know where I am.").also { stage++ } + 12 -> when (buttonId) { + 1 -> playerl(FacialExpression.NEUTRAL, "Yes, I'm lost.").also { stage = 13 } + 2 -> playerl(FacialExpression.NEUTRAL, "No, I know where I am.").also { stage = 15 } + } + + 13 -> npcl(FacialExpression.FRIENDLY, "Okay, just walk north-east when you leave this house and soon you'll reach the big city of Falador.").also { stage++ } + 14 -> playerl(FacialExpression.FRIENDLY, "Thanks a lot.").also { stage = END_DIALOGUE } + 15 -> npcl(FacialExpression.ASKING, "Oh? Well, would you mind wandering somewhere else?").also { stage++ } + 16 -> npcl(FacialExpression.NEUTRAL, "This is my house.").also { stage++ } + 17 -> playerl(FacialExpression.NEUTRAL, "Meh!").also { stage = END_DIALOGUE } + + 20 -> { + val dialogues = arrayOf("Do you REALLY need it?", "I don't have much on me...", "I don't know...") + npcl(FacialExpression.NEUTRAL, dialogues[RandomFunction.random(0, 3)]) + stage++ + } + + 21 -> playerl(FacialExpression.ASKING, "I promise I'll stop bothering you!").also { stage++ } + 22 -> playerl(FacialExpression.ASKING, "Pleeease!").also { stage++ } + 23 -> playerl(FacialExpression.ASKING, "Pwetty pleathe wiv thugar on top!").also { stage++ } + 24 -> { + npcl(FacialExpression.NEUTRAL, "Oh, alright. Here you go.") + addItemOrDrop(player, Items.COINS_995, RandomFunction.random(1, 3)) + stage = END_DIALOGUE + } + + 30 -> { + stage = END_DIALOGUE + close() + + val hengel = findLocalNPC(npc, NPCs.HENGEL_2683) + if(hengel != null) + sendChat(hengel, "Aaaaarrgh!") + + sendChat(npc, "Eeeek!") + } + } + + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return AnjaDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.ANJA_2684) + } +} diff --git a/Server/src/main/content/region/asgarnia/rimmington/dialogue/BrianArcheryDialogue.kt b/Server/src/main/content/region/asgarnia/rimmington/dialogue/BrianArcheryDialogue.kt new file mode 100644 index 0000000..0598231 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/rimmington/dialogue/BrianArcheryDialogue.kt @@ -0,0 +1,47 @@ +package content.region.asgarnia.rimmington.dialogue + +import core.api.openNpcShop +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.node.entity.npc.NPC +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +/** + * Handles the BrianArchery's dialogue. + */ +@Initializable +class BrianArcheryDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npcl(FacialExpression.HAPPY, "Would you like to buy some archery equipment?").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> options("Let's see what you've got, then.", "No thanks, I've got all the archery equipment I need.").also { stage++ } + 1 -> when (buttonId) { + 1 -> end().also { openNpcShop(player, npc.id) } + 2 -> playerl(FacialExpression.HALF_GUILTY, "No thanks, I've got all the archery equipment I need.").also { stage = 10 } + } + + 10 -> { + npcl(FacialExpression.FRIENDLY, "Okay. Fare well on your travels.") + stage = END_DIALOGUE + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return BrianArcheryDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.BRIAN_1860) + } +} diff --git a/Server/src/main/content/region/asgarnia/rimmington/dialogue/HengelDialogue.kt b/Server/src/main/content/region/asgarnia/rimmington/dialogue/HengelDialogue.kt new file mode 100644 index 0000000..3bae6f1 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/rimmington/dialogue/HengelDialogue.kt @@ -0,0 +1,67 @@ +package content.region.asgarnia.rimmington.dialogue + +import core.api.findLocalNPC +import core.api.sendChat +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.node.entity.npc.NPC +import core.game.world.map.RegionManager +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +/** + * Handles the Hengel's dialogue. + */ +@Initializable +class HengelDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + playerl(FacialExpression.NEUTRAL, "Hello.").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> npcl(FacialExpression.ASKING, "What are you doing here?").also { stage++ } + 1 -> options("I'm just wandering around.", "I was hoping you'd give me some free stuff.", "I've come to kill you.").also { stage++ } + 2 -> when (buttonId) { + 1 -> playerl(FacialExpression.NEUTRAL, "I'm just wondering around.").also { stage = 10 } + 2 -> playerl(FacialExpression.NEUTRAL, "I was hoping you'd give me some free stuff.").also { stage = 20 } + 3 -> playerl(FacialExpression.ANGRY_WITH_SMILE, "I've come to kill you.").also { stage = 30 } + } + + 10 -> npcl(FacialExpression.ASKING, "You do realise you're wandering around in my house?").also { stage++ } + 11 -> playerl(FacialExpression.NEUTRAL, "Yep.").also { stage++ } + 12 -> npcl(FacialExpression.ANNOYED, "Well please get out!").also { stage++ } + 13 -> playerl(FacialExpression.NEUTRAL, "Sheesh, keep your wig on!").also { stage = END_DIALOGUE } + + 20 -> npcl(FacialExpression.ANNOYED, "No, I jolly well wouldn't!").also { stage++ } + 21 -> npcl(FacialExpression.ANNOYED, "Get out of my house!").also { stage++ } + 22 -> playerl(FacialExpression.NEUTRAL, "Meanie!").also { stage = END_DIALOGUE } + + 30 -> { + stage = END_DIALOGUE + close() + + val anja = findLocalNPC(npc, NPCs.ANJA_2684) + if(anja != null) + sendChat(anja, "Eeeek!") + + sendChat(npc, "Aaaaarrgh!") + } + } + + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return HengelDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.HENGEL_2683) + } +} diff --git a/Server/src/main/content/region/asgarnia/rimmington/dialogue/HettyDialogue.kt b/Server/src/main/content/region/asgarnia/rimmington/dialogue/HettyDialogue.kt new file mode 100644 index 0000000..39a1558 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/rimmington/dialogue/HettyDialogue.kt @@ -0,0 +1,83 @@ +package content.region.asgarnia.rimmington.dialogue + +import content.data.Quests +import content.region.asgarnia.rimmington.quest.witchpotion.HettyWitchsPotionDialogue +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.node.entity.npc.NPC +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +/** + * Handles the Hetty's dialogue. + */ +@Initializable +class HettyDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + + val questStage = getQuestStage(player, Quests.WITCHS_POTION) + + when(questStage) { + 0 -> npcl(FacialExpression.NEUTRAL, "What could you want with an old woman like me?").also { stage = 0 } + in 1..99 -> openDialogue(player, HettyWitchsPotionDialogue(questStage), npc) + else -> npcl(FacialExpression.ASKING, "How's your magic coming along?").also { stage = 30 } + } + + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> options("I am in search of a quest.", "I've heard that you are a witch.").also { stage++ } + 1 -> when (buttonId) { + 1 -> playerl(FacialExpression.NEUTRAL, "I am in search of a quest.").also { stage = 10 } + 2 -> playerl(FacialExpression.NEUTRAL, "I've heard that you are a witch.").also { stage = 20 } + } + + 10 -> npcl(FacialExpression.HAPPY, "Hmmm... Maybe I can think of something for you.").also { stage++ } + 11 -> npcl(FacialExpression.HAPPY, "Would you like to become more proficient in the dark arts?").also { stage++ } + 12 -> options("Yes help me become one with my darker side.", "No I have my principles and honour.", "What, you mean improve my magic?").also { stage++ } + 13 -> when (buttonId) { + 1 -> playerl(FacialExpression.HAPPY, "Yes help me become one with my darker side.").also { stage = 14 } + 2 -> playerl(FacialExpression.NEUTRAL, "No I have my principles and honour.").also { stage = 15 } + 3 -> playerl(FacialExpression.ASKING, "What, you mean improve my magic?").also { stage = 40 } + } + + 14 -> openDialogue(player, HettyWitchsPotionDialogue(0), npc) + 15 -> npcl(FacialExpression.HALF_GUILTY, "Suit yourself, but you're missing out.").also { stage = END_DIALOGUE } + + 20 -> npcl(FacialExpression.HALF_GUILTY, "Yes it does seem to be getting fairly common knowledge").also { stage++ } + 21 -> npcl(FacialExpression.HALF_GUILTY, "I fear I may get a visit from the witch hunter of Falador before long.").also { stage = END_DIALOGUE } + + 30 -> playerl(FacialExpression.HALF_GUILTY, "I'm practicing and slowly getting better.").also { stage++ } + 31 -> npcl(FacialExpression.HALF_GUILTY, "Good, good.").also { stage = END_DIALOGUE } + + 40 -> sendDialogue("The witch sighs.").also { stage++ } + 41 -> npcl(FacialExpression.ANNOYED, "Yes, improve your magic...").also { stage++ } + 42 -> npcl(FacialExpression.ASKING, "Do you have no sense of drama?").also { stage++ } + 43 -> options("Yes I'd like to improve my magic.", "No I'm not interested.", "Show me the mysteries of the dark arts...").also { stage++ } + 44 -> when(buttonId) { + // TODO: Find authentic source for dialogue option + 1 -> playerl(FacialExpression.NEUTRAL, "Yes I'd like to improve my magic.").also { stage = 14 } + // TODO: Find authentic source for dialogue option + 2 -> playerl(FacialExpression.NEUTRAL, "No I'm not interested.").also { stage = 15 } + 3 -> playerl(FacialExpression.NEUTRAL, "Show me the mysteries of the dark arts...").also { stage++ } + } + 45 -> sendDialogue("The witch smiles mysteriously.").also { stage = 14 } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return HettyDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.HETTY_307) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/rimmington/dialogue/RimmingtonShopKeeperDialogue.kt b/Server/src/main/content/region/asgarnia/rimmington/dialogue/RimmingtonShopKeeperDialogue.kt new file mode 100644 index 0000000..1c637f5 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/rimmington/dialogue/RimmingtonShopKeeperDialogue.kt @@ -0,0 +1,44 @@ +package content.region.asgarnia.rimmington.dialogue + +import core.api.openNpcShop +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.node.entity.npc.NPC +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +/** + * Handles the RimmingtonShopKeeper dialogue. + */ +@Initializable +class RimmingtonShopKeeperDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npcl(FacialExpression.HAPPY, "Can I help you at all?").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> options("Yes, please. What are you selling?", "How should I use your shop?", "No, thanks.").also { stage++ } + 1 -> when (buttonId) { + 1 -> end().also { openNpcShop(player, npc.id) } + 2 -> npcl(FacialExpression.HAPPY, "I'm glad you ask! You can buy as many of the items stocked as you wish. You can also sell most items to the shop.").also { stage = END_DIALOGUE } + 3 -> end() + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return RimmingtonShopKeeperDialogue(player) + } + + override fun getIds(): IntArray = intArrayOf( + NPCs.SHOPKEEPER_530, + NPCs.SHOP_ASSISTANT_531 + ) +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/rimmington/dialogue/RommikDialogue.kt b/Server/src/main/content/region/asgarnia/rimmington/dialogue/RommikDialogue.kt new file mode 100644 index 0000000..3cb8514 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/rimmington/dialogue/RommikDialogue.kt @@ -0,0 +1,48 @@ +package content.region.asgarnia.rimmington.dialogue + +import core.api.openNpcShop +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.node.entity.npc.NPC +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +/** + * Handles the Rommik's dialogue. + */ +@Initializable +class RommikDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npcl(FacialExpression.HAPPY, "Would you like to buy some crafting equipment?").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> options("Let's see what you've got, then.", "No thanks, I've got all the crafting equipment I need.").also { stage++ } + 1 -> when (buttonId) { + 1 -> end().also { openNpcShop(player, npc.id) } + 2 -> playerl(FacialExpression.HALF_GUILTY, "No thanks, I've got all the crafting equipment I need.").also { stage = 10 } + } + + 10 -> { + npcl(FacialExpression.FRIENDLY, "Okay. Fare well on your travels.") + stage = END_DIALOGUE + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return RommikDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.ROMMIK_585) + } + +} diff --git a/Server/src/main/content/region/asgarnia/rimmington/handler/RimmingtonListeners.kt b/Server/src/main/content/region/asgarnia/rimmington/handler/RimmingtonListeners.kt new file mode 100644 index 0000000..5dc7275 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/rimmington/handler/RimmingtonListeners.kt @@ -0,0 +1,29 @@ +package content.region.asgarnia.rimmington.handler + +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.item.Item +import core.game.node.scenery.Scenery +import org.rs09.consts.Items +import org.rs09.consts.Sounds + +/** + * @author Player Name + */ + +class RimmingtonListeners : InteractionListener { + override fun defineListeners() { + on(9662, IntType.SCENERY, "take") { player, node -> + if (!hasSpaceFor(player, Item(Items.SPADE_952))) { + sendMessage(player, "You don't have enough inventory space to hold that item.") + return@on true + } + animate(player, 535) + playAudio(player, Sounds.PICK2_2582) + addItem(player, Items.SPADE_952) + replaceScenery(node as Scenery, 0, 50) + return@on true + } + } +} diff --git a/Server/src/main/content/region/asgarnia/rimmington/quest/witchpotion/HettyWitchsPotionDialogue.kt b/Server/src/main/content/region/asgarnia/rimmington/quest/witchpotion/HettyWitchsPotionDialogue.kt new file mode 100644 index 0000000..5016968 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/rimmington/quest/witchpotion/HettyWitchsPotionDialogue.kt @@ -0,0 +1,77 @@ +package content.region.asgarnia.rimmington.quest.witchpotion + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.node.item.Item +import core.game.node.entity.player.Player +import core.tools.END_DIALOGUE +import org.rs09.consts.Items + +/** + * Handles Hetty's dialogue for the Witch's Potion Quest. + */ +class HettyWitchsPotionDialogue(private val dStage: Int) : DialogueFile() { + + override fun handle(componentID: Int, buttonID: Int) { + when (dStage) { + 0 -> handleQuestStartDialogue(player) + 20 -> handleGiveItemsDialogue(player) + 40 -> npcl(FacialExpression.ANNOYED, "Well are you going to drink the potion or not?").also { stage = END_DIALOGUE } + } + } + + private fun handleQuestStartDialogue(player: Player?) { + player ?: return + when (stage) { + 0 -> npcl(FacialExpression.HAPPY, "Ok I'm going to make a potion to help bring out your darker self.").also { stage++ } + 1 -> npcl(FacialExpression.NEUTRAL, "You will need certain ingredients.").also { stage++ } + 2 -> playerl(FacialExpression.NEUTRAL, "What do I need?").also { stage++ } + 3 -> npcl(FacialExpression.NEUTRAL, "You need an eye of newt, a rat's tail, an onion... Oh and a piece of burnt meat.").also { stage++ } + 4 -> { + playerl(FacialExpression.HAPPY, "Great, I'll go and get them.") + startQuest(player, Quests.WITCHS_POTION) + setQuestStage(player, Quests.WITCHS_POTION, 20) + stage = END_DIALOGUE + } + } + } + + private fun handleGiveItemsDialogue(player: Player?) { + player ?: return + when (stage) { + 0 -> npcl(FacialExpression.HAPPY, "So have you found the things for the potion?").also { stage++ } + 1 -> { + if (inInventory(player, Items.ONION_1957, 1) && + inInventory(player, Items.RATS_TAIL_300, 1) && + inInventory(player, Items.BURNT_MEAT_2146, 1) && + inInventory(player, Items.EYE_OF_NEWT_221, 1)) { + playerl(FacialExpression.HAPPY, "Yes I have everything!").also { stage = 20 } + } else { + playerl(FacialExpression.HALF_GUILTY, "I'm afraid I don't have all of them yet.").also { stage = 10 } + } + } + + 10 -> npcl(FacialExpression.ANNOYED, "Well I can't make the potion without them! Remember...").also { stage++ } + 11 -> npcl(FacialExpression.NEUTRAL, "You need an eye of newt, a rat's tail, an onion, and a piece of burnt meat.").also { stage++ } + 12 -> npcl(FacialExpression.FRIENDLY, "Off you go dear!").also { stage = END_DIALOGUE } + + 20 -> npcl(FacialExpression.HAPPY, "Excellent, can I have them then?").also { stage++ } + 21 -> sendDialogue(player, "You pass the ingredients to Hetty and she puts them all into her cauldron. Hetty closes her eyes and begins to chant. The cauldron bubbles mysteriously.").also { stage++ } + + 22 -> playerl(FacialExpression.NEUTRAL, "Well, is it ready?").also { stage++ } + 23 -> { + // Removing the items at this stage is authentic behavior + if (removeItem(player, Item(Items.ONION_1957, 1)) && + removeItem(player, Item(Items.RATS_TAIL_300, 1)) && + removeItem(player, Item(Items.BURNT_MEAT_2146, 1)) && + removeItem(player, Item(Items.EYE_OF_NEWT_221, 1))) { + npcl(FacialExpression.HAPPY, "Ok, now drink from the cauldron.") + setQuestStage(player, Quests.WITCHS_POTION, 40) + stage = END_DIALOGUE + } + } + } + } +} diff --git a/Server/src/main/content/region/asgarnia/rimmington/quest/witchpotion/WitchsPotion.kt b/Server/src/main/content/region/asgarnia/rimmington/quest/witchpotion/WitchsPotion.kt new file mode 100644 index 0000000..0ada42b --- /dev/null +++ b/Server/src/main/content/region/asgarnia/rimmington/quest/witchpotion/WitchsPotion.kt @@ -0,0 +1,86 @@ +package content.region.asgarnia.rimmington.quest.witchpotion + +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import org.rs09.consts.Components +import org.rs09.consts.Items +import content.data.Quests + +/** + * Represents the Witch's Potion Quest + */ +@Initializable +class WitchsPotion : Quest(Quests.WITCHS_POTION, 31, 30, 1, 67, 0, 1, 3) { + + override fun drawJournal(player: Player?, stage: Int) { + super.drawJournal(player, stage) + player ?: return + var line = 11 + if (stage == 0) { + line(player, "I can start this quest by speaking to !!Hetty?? who in her house in", line++) + line(player, "!!Rimmington??, West of !!Port Sarim??.", line++) + } else if (stage in 1..39) { + line(player, "I spoke to !!Hetty?? in her house at Rimmington. Hetty told me", line++, true) + line(player, "she could increase my magic power if I can bring her", line++, true) + line(player, "certain ingredients for a potion.", line++, true) + line++ + line(player, "Hetty needs me to bring her the following:", line++) + + if(inInventory(player, Items.ONION_1957, 1)) + line(player, "I have an onion with me", line++, true) + else + line(player, "!!An onion??", line++) + + if(inInventory(player, Items.RATS_TAIL_300, 1)) + line(player, "I have a rat's tail with me", line++, true) + else + line(player, "!!A rat's tail??", line++) + + if(inInventory(player, Items.BURNT_MEAT_2146, 1)) + line(player, "I have a piece of burnt meat with me", line++, true) + else + line(player, "!!A piece of burnt meat??", line++) + + if(inInventory(player, Items.EYE_OF_NEWT_221, 1)) + line(player, "I have an eye of newt with me", line++, true) + else + line(player, "!!An eye of newt??", line++) + } else if (stage in 40..99) { + line(player, "I spoke to !!Hetty?? in her house at Rimmington. Hetty told me.", line++, true) + line(player, "she could increase my magic power if I can bring her", line++, true) + line(player, "certain ingredients for a potion.", line++, true) + line(player, "I brought her an onion, a rat's tail, a piece of burnt meat", line++, true) + line(player, "and an eye of newt which she used to make a potion.", line++, true) + line(player, "I should drink from the !!cauldron?? and improve my magic!", line++) + } else if (stage == 100) { + line(player, "I have spoken to !!Hetty??.", line++, true) + line(player, "I spoke to !!Hetty?? in her house at Rimmington. Hetty told me.", line++, true) + line(player, "she could increase my magic power if I can bring her", line++, true) + line(player, "certain ingredients for a potion.", line++, true) + line(player, "I brought her an onion, a rat's tail, a piece of burnt meat", line++, true) + line(player, "and an eye of newt which she used to make a potion.", line++, true) + line(player, "I drank from the cauldron and my magic power increased!", line++, true) + line++ + line(player, "%%QUEST COMPLETE!&&", line++) + } + } + + override fun finish(player: Player?) { + super.finish(player) + player ?: return + var line = 10 + + sendItemZoomOnInterface(player, Components.QUEST_COMPLETE_SCROLL_277, 5, Items.EYE_OF_NEWT_221) + drawReward(player, "1 Quest Point", line++) + drawReward(player, "325 Magic XP", line++) + + rewardXP(player, Skills.MAGIC, 325.0) + } + + override fun newInstance(`object`: Any?): Quest { + return this + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/rimmington/quest/witchpotion/WitchsPotionListeners.kt b/Server/src/main/content/region/asgarnia/rimmington/quest/witchpotion/WitchsPotionListeners.kt new file mode 100644 index 0000000..0d00cee --- /dev/null +++ b/Server/src/main/content/region/asgarnia/rimmington/quest/witchpotion/WitchsPotionListeners.kt @@ -0,0 +1,26 @@ +package content.region.asgarnia.rimmington.quest.witchpotion + +import content.data.Quests +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import org.rs09.consts.Scenery + +/** + * Interaction Listener for Witch's Potion Quest. + */ +class WitchsPotionListener : InteractionListener { + + override fun defineListeners() { + + on(Scenery.CAULDRON_2024, IntType.SCENERY, "drink from") { player, node -> + if (getQuestStage(player, Quests.WITCHS_POTION) == 40) { + sendDialogue(player, "You drink from the cauldron, it tastes horrible! You feel yourself imbued with power.") + finishQuest(player, Quests.WITCHS_POTION) + } else { + sendDialogue(player, "As nice as that looks I think I'll give it a miss for now.") + } + return@on true + } + } +} diff --git a/Server/src/main/content/region/asgarnia/taverley/dialogue/BrianORichardDialogue.java b/Server/src/main/content/region/asgarnia/taverley/dialogue/BrianORichardDialogue.java new file mode 100644 index 0000000..1737820 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/taverley/dialogue/BrianORichardDialogue.java @@ -0,0 +1,128 @@ +package content.region.asgarnia.taverley.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; + +/** + * Reprepsents the dialogue plugin used to handle the brian orichard npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class BrianORichardDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code BrianORichardDialogue} {@code Object}. + */ + public BrianORichardDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code BrianORichardDialogue}{@code Object}. + * @param player the player. + */ + public BrianORichardDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new BrianORichardDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hi there, looking for a challenge are you?"); + stage = 1; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 1: + interpreter.sendOptions("Select an Option", "Yes, actually, what've you got?", "What is this place?", "No thanks."); + stage = 2; + break; + case 2: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Yes actually, what've you got?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What is this place?"); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No thanks."); + stage = 30; + break; + } + break; + case 10: + if (player.getSkills().getLevel(Skills.THIEVING) < 50) { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Shame, I don't think I have anything for you. Train up", "your Thieving skill to at least 50 and I might be able to", "help you out."); + stage = 11; + } else { + + } + break; + case 11: + end(); + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ah welcome to my humble home, well actually it belongs", "to mummsie but she's getting on a bit so I look after", "the place for her."); + stage = 21; + break; + case 21: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "So are you interested in a challenge?"); + stage = 22; + break; + case 22: + interpreter.sendOptions("Select an Option", "Yes actually, what've you got?", "No thanks."); + stage = 23; + break; + case 23: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Yes actually, what've you got?"); + stage = 24; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No, thanks."); + stage = 25; + break; + } + break; + case 24: + if (player.getSkills().getLevel(Skills.THIEVING) < 50) { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Shame, I don't think I have anything for you. Train up", "your Thieving skill to at least 50 and I might be able to", "help you out."); + stage = 25; + } else { + + } + break; + case 25: + end(); + break; + case 30: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 2266 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/taverley/dialogue/JatixDialogue.java b/Server/src/main/content/region/asgarnia/taverley/dialogue/JatixDialogue.java new file mode 100644 index 0000000..27702f7 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/taverley/dialogue/JatixDialogue.java @@ -0,0 +1,70 @@ +package content.region.asgarnia.taverley.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the dialogue plugin used for the jatix npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class JatixDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code JatixDialogue} {@code Object}. + */ + public JatixDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code JatixDialogue} {@code Object}. + * @param player the player. + */ + public JatixDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new JatixDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Hello, adventurer."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(player, FacialExpression.FRIENDLY, "Hello."); + stage = 1; + break; + case 1: + interpreter.sendDialogues(player, FacialExpression.FRIENDLY, "What are you selling?"); + stage = 2; + break; + case 2: + end(); + npc.openShop(player); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 587 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/taverley/dialogue/KaqemeexDialogue.java b/Server/src/main/content/region/asgarnia/taverley/dialogue/KaqemeexDialogue.java new file mode 100644 index 0000000..487939a --- /dev/null +++ b/Server/src/main/content/region/asgarnia/taverley/dialogue/KaqemeexDialogue.java @@ -0,0 +1,326 @@ +package content.region.asgarnia.taverley.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.global.Skillcape; +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import content.data.Quests; + +/** + * Represents the kaqemeex dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class KaqemeexDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code KaqemeexDialogue} {@code Object}. + */ + public KaqemeexDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code KaqemeexDialogue} {@code Object}. + * @param player the player. + */ + public KaqemeexDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new KaqemeexDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + if (args.length >= 2) { + interpreter.sendDialogues(npc, null, "I will now explain the fundamentals of Herblore:"); + stage = 1000; + return true; + } + interpreter.sendDialogues(player, FacialExpression.FRIENDLY, "Hello there."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + if (player.getQuestRepository().isComplete(Quests.DRUIDIC_RITUAL)) { + interpreter.sendDialogues(npc, null, "Hello again. How is the Herblore going?"); + stage = 600; + break; + } + if (player.getQuestRepository().getQuest(Quests.DRUIDIC_RITUAL).getStage(player) == 10) { + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "Hello again."); + stage = 40; + break; + } + if (player.getQuestRepository().getQuest(Quests.DRUIDIC_RITUAL).getStage(player) == 99) { + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "I have word from Sanfew that you have been very", "helpful in assisting him with his preparations for the", "purification ritual. As promised I will now teach you the", "ancient arts of Herblore."); + stage = 200; + break; + } + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "What brings you to our holy monument?"); + stage = 1; + break; + case 1: + if (player.getQuestRepository().getQuest(Quests.DRUIDIC_RITUAL).isStarted(player)) { + if (Skillcape.isMaster(player, Skills.HERBLORE)) { + interpreter.sendOptions("Select an Option", "Can I buy a Skillcape of Herblore?", "Who are you?", "Did you build this?"); + stage = 800; + } else { + interpreter.sendOptions("Select an Option", "Who are you?", "Did you build this?"); + stage = 500; + } + break; + } else { + interpreter.sendOptions("Select an Option", "Who are you?", "I'm in search of a quest.", "Did you build this?"); + stage = 2; + } + break; + case 2: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.ASKING, "Who are you?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.FRIENDLY, "I'm in search of a quest."); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.ASKING, "Did you build this?"); + stage = 30; + break; + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "We are the druids of Guthix. We worship our god at", "our famous stone circles. You will find them located", "throughout these lands."); + stage = 11; + break; + case 11: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Well, I'll be on my way now."); + stage = 12; + break; + case 12: + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "Goodbye adventurer. I feel we shall meet again."); + stage = 13; + break; + case 13: + end(); + break; + case 30: + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "What, personally? No, ofcourse I didn't. However, our", "four fathers did. The first Druids of Guthix built many", "stone circles across these lands over eight hundred", "years ago."); + stage = 31; + break; + case 31: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Unfortunately we only know of two remaining and of", "those only one is usable by us anymore."); + stage = 32; + break; + case 32: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Well, I'll be on my way now."); + stage = 12; + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Hmm. I think I may have a worthwhile quest for you", "actually. I don't know if you are familiar with the stone", "circle south of Varrock or not, but..."); + stage = 21; + break; + case 21: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "That used to be our stone circle. Unfortunately,", "many years ago, dark wizards cast a wicked spell", "upon it so that they could corrupt its power for their", "own evil ends."); + stage = 22; + break; + case 22: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "When they cursed the rocks for their rituals, they made", "them useless to us and our magics. We require a brave", "adventurer to go on a quest for us to help purify the", "circle of Varrock."); + stage = 23; + break; + case 23: + interpreter.sendOptions("Select an Option", "Ok, I will try and help.", "No, that doesn't sound very interesting."); + stage = 24; + break; + case 24: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Ok, I will try and help."); + stage = 26; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No, that doesn't sound very interesting."); + stage = 25; + break; + } + break; + case 25: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I will not try and change your mind adventurer. Some", "day when you have matured you may reconsider your", "position. We will wait until then."); + stage = 13; + break; + case 26: + player.getQuestRepository().getQuest(Quests.DRUIDIC_RITUAL).start(player); + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Excellent. Go to the village south of this place and speak", "to my fellow Sanfew who is working on the purification", "ritual. He knows better than I what is required to", "complete it."); + stage = 27; + break; + case 27: + interpreter.sendDialogues(player, FacialExpression.HAPPY, "Will do."); + stage = 28; + break; + case 28: + end(); + break; + case 40: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "You will need to speak to my fellow druid Sanfew in", "the village south of here to continue in your quest", "adventurer."); + stage = 41; + break; + case 41: + end(); + break; + case 200: + end(); + player.getQuestRepository().getQuest(Quests.DRUIDIC_RITUAL).finish(player); + break; + case 500: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_ASKING, "Who are you?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_ASKING, "Did you build this?"); + stage = 30; + break; + } + break; + case 501: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HAPPY, "Can I buy a Skillcape of Herblore?"); + stage = 800; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.ASKING, "Who are you?"); + stage = 10; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_ASKING, "Did you build this?"); + stage = 30; + break; + } + break; + case 600: + interpreter.sendDialogues(player, null, "Good good!"); + stage = 601; + break; + case 601: + if (Skillcape.isMaster(player, Skills.HERBLORE)) { + interpreter.sendOptions("Select an Option", "Can I buy a Skillcape of Herblore?", "Who are you?", "Did you build this?"); + stage = 501; + } else { + interpreter.sendOptions("Select an Option", "Who are you?", "Did you build this?"); + stage = 500; + } + break; + case 1000: + interpreter.sendDialogues(npc, null, "Herblore is the skill of working with herbs and other", "ingredients, to make useful potions and poison."); + stage = 1001; + break; + case 1001: + interpreter.sendDialogues(npc, null, "First you will need a vial, which can be found or made", "with the crafting skill."); + stage = 1002; + break; + case 1002: + interpreter.sendDialogues(npc, null, "Then you must gather the herbs needed to make the", "potion you want."); + stage = 1003; + break; + case 1003: + interpreter.sendDialogues(npc, null, "Refer to the Council's instructions in the Skills section", "of the website for the items needed to make a particular", "kind of potion."); + stage = 1004; + break; + case 1004: + interpreter.sendDialogues(npc, null, "You must fill your vial with water and add the", "ingredients you need. There are normally 2 ingredients", "to each type of potion."); + stage = 1005; + break; + case 1005: + interpreter.sendDialogues(npc, null, "Bear in mind you must first identify each herb, to see", "what it is."); + stage = 1006; + break; + case 1006: + interpreter.sendDialogues(npc, null, "You may also have to grind some herbs before you can", "use them. You will need a pestle and mortar in order", "to do this."); + stage = 1007; + break; + case 1007: + interpreter.sendDialogues(npc, null, "Herbs can be found on the ground, and are also", "dropped by some monsters when you kill them."); + stage = 1008; + break; + case 1008: + interpreter.sendDialogues(npc, null, "Mix these in your water-filled vial, and you will produce", "an Attack potion."); + stage = 1009; + break; + case 1009: + interpreter.sendDialogues(npc, null, "Drink this poition to increase your Attack level."); + stage = 1010; + break; + case 1010: + interpreter.sendDialogues(npc, null, "Different potions also require different Herblore levels", "before you can make them."); + stage = 1011; + break; + case 1011: + interpreter.sendDialogues(npc, null, "Once again, check the instructions found on the", "Council's website for the levels needed to make a", "particulur potion."); + stage = 1012; + break; + case 1012: + interpreter.sendDialogues(npc, null, "Good luck with your Herblore practices, Good day", "Adventurer."); + stage = 1013; + break; + case 1013: + interpreter.sendDialogues(player, null, "Thanks for your help."); + stage = 1014; + break; + case 1014: + end(); + break; + case 800: + npc("Certainly! Right when you give me 99000 coins."); + stage = 801; + break; + case 801: + options("Yes, here you go,", "No, thanks."); + stage = 802; + break; + case 802: + switch (buttonId) { + case 1: + player("Yes, here you go."); + stage = 803; + break; + case 2: + end(); + break; + } + break; + case 803: + if (Skillcape.purchase(player, Skills.HERBLORE)) { + npc("There you go! Enjoy."); + } + stage = 804; + break; + case 804: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 455 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/taverley/dialogue/PetshopOwnerTaverly.java b/Server/src/main/content/region/asgarnia/taverley/dialogue/PetshopOwnerTaverly.java new file mode 100644 index 0000000..39f2486 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/taverley/dialogue/PetshopOwnerTaverly.java @@ -0,0 +1,209 @@ +package content.region.asgarnia.taverley.dialogue; + +import java.util.List; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.game.world.map.RegionManager; + +/** + * Represents the dialogue for the taverly pet shop owner. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class PetshopOwnerTaverly extends DialoguePlugin { + + /** + * Represents the dog name. + */ + private String dogName; + + /** + * Represents the puppy. + */ + private Item puppy; + + /** + * Constructs a new {@code PetshopOwnerTaverly} {@code Object}. + */ + public PetshopOwnerTaverly() { + /** + * emppty. + */ + } + + /** + * Constructs a new {@code PetshopOwnerTaverly} {@code Object}. + * @param player the player. + */ + public PetshopOwnerTaverly(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new PetshopOwnerTaverly(player); + } + + @Override + public boolean open(Object... args) { + if (args.length > 1) { + List npcs = RegionManager.getLocalNpcs(player); + for (NPC n : npcs) { + if (n.getId() == 6893) { + npc = n; + break; + } + } + dogName = (String) args[0]; + puppy = (Item) args[1]; + player("No, the " + dogName + "."); + stage = 699; + return true; + } + npc = (NPC) args[0]; + interpreter.sendOptions("Choose an option:", "Can I see your shop, please?", "How much is that puppy in the window?", "So, what sorts of pets are available?"); + stage = 1; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HAPPY, "Can I see your shop please?"); + stage = 100; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_ASKING, "How much is that puppy in the window?"); + stage = 200; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_ASKING, "So, what sorts of pets are available?"); + stage = 300; + break; + } + break; + case 100: + end(); + npc.openShop(player); + break; + case 200: + interpreter.sendDialogues(npc, FacialExpression.HALF_ASKING, "The one with the waggly tail?"); + stage = 201; + break; + case 201: + end(); + player.getInterfaceManager().openChatbox(668); + stage = 202; + break; + case 202: + break; + case 300: + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "Well, here we sell dogs, but we also have supplies for any", "other creatures you might want to raise."); + stage = 301; + break; + case 301: + interpreter.sendDialogues(player, FacialExpression.HALF_ASKING, "Such as?"); + stage = 302; + break; + case 302: + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "Well, we sell nuts. Those can be used to feed squirrels. If", "you want to capture a squirrel, you'll need to use the nuts", "on the trap you set, as the little scamps won't be fooled", "by anything else."); + stage = 303; + break; + case 303: + interpreter.sendDialogues(player, FacialExpression.FRIENDLY, "I'll bear that in mind."); + stage = 304; + break; + case 304: + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "There are also a number of fabulous and exotic lizards in", "Karmja. Some can be caught easily in a box trap, while", "other will need to be raised from an egg."); + stage = 305; + break; + case 305: + interpreter.sendDialogues(player, FacialExpression.HAPPY, "Thank's alot! You've been very helpfull."); + stage = 306; + break; + case 306: + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "It's always a pleasure to help a fellow animal-lover. Come", "back and visit soon."); + stage = 307; + break; + case 307: + end(); + break; + case 700: + player("Isn't that a little steep?"); + stage = 701; + break; + case 701: + npc("Well, if we gave them away for free then people would", "just buy them and dump them without a care."); + stage = 702; + break; + case 702: + npc("Dogs are a big responsibility and should be cared for."); + stage = 703; + break; + case 703: + npc("If a person in unwilling to invest 500 coins, then they", "don't deserve to have the puppy in the first place."); + stage = 704; + break; + case 704: + npc("So, do you still want one?"); + stage = 705; + break; + case 705: + options("Okay, I'll take the " + dogName + ".", "No thanks."); + stage = 706; + break; + case 706: + switch (buttonId) { + case 1: + player("Okay, I'll take the " + dogName + "."); + stage = 707; + break; + case 2: + end(); + break; + } + break; + case 707: + if (player.getInventory().freeSlots() == 0) { + npc("You don't have enough inventory space."); + stage = 708; + return true; + } + if (!player.getInventory().containsItem(new Item(995, 500))) { + end(); + return true; + } + if (player.getInventory().remove(new Item(995, 500))) { + player.getInventory().add(puppy); + npc("There you go! I hope you two get on."); + stage = 708; + } else { + player.getPacketDispatch().sendMessage("You don't the required coins in order to do this."); + end(); + } + break; + case 708: + end(); + break; + case 699: + npc("500 gold."); + stage = 700; + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 6893 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/taverley/dialogue/PikkupstixDialogue.java b/Server/src/main/content/region/asgarnia/taverley/dialogue/PikkupstixDialogue.java new file mode 100644 index 0000000..f953d27 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/taverley/dialogue/PikkupstixDialogue.java @@ -0,0 +1,825 @@ +package content.region.asgarnia.taverley.dialogue; + +import core.ServerConstants; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.plugin.Initializable; +import core.game.node.item.Item; + +import static core.api.ContentAPIKt.*; +import content.data.Quests; + +/** + * Handles the PikkupstixDialogue dialogue. + * @author Vexia + * @author Splinter + * @version 1.1 + * @notice Modified March 2nd, 2015 to allow the bulk buying of shards. + * @notice The previous notice is dubious + * @notice Spirit shard packs were released 9 September 2009, outside of 530. Option removed. + * Fixed multiple typos -Nuggles + */ +@Initializable +public final class PikkupstixDialogue extends DialoguePlugin { + + /** + * Represents the summoning mastering items. + */ + private static final Item[] ITEMS = new Item[] { new Item(12169), new Item(12170), new Item(12171) }; + + /** + * Represents the coins item. + */ + private static final Item COINS = new Item(995, 99000); + + /** + * Represents the wolf bones item. + */ + private static final Item BONES = new Item(2859, 2); + + /** + * Represents the wolf items. + */ + private static final Item[] WOLF_ITEMS = new Item[] { new Item(12158, 2), new Item(12155, 2), new Item(12183, 14), new Item(12528) }; + + /** + * Represents the howl scroll item. + */ + private static final Item HOWL_SCROLL = new Item(12425); + + /** + * Represents the wolf pouch. + */ + private static final Item WOLF_POUCH = new Item(12047); + + /** + * Represents the quest instance. + */ + private Quest quest; + + /** + * Constructs a new {@code PikkupstixDialogue} {@code Object}. + */ + public PikkupstixDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code PikkupstixDialogue} {@code Object}. + * @param player the player. + */ + public PikkupstixDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new PikkupstixDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + quest = player.getQuestRepository().getQuest(Quests.WOLF_WHISTLE); + switch (quest.getStage(player)) { + case 0: + npc("You there! What are you doing here, as if I didn't have", "enough troubles?"); + break; + case 10: + npc("Have you met the monster upstairs?"); + stage = 0; + break; + case 20: + player("The teeth!"); + stage = 0; + break; + case 30: + if (!player.getInventory().containsItem(BONES)) { + npc("You need to bring two lots of wolf bones. I can provide", "the other items you will need."); + stage = 0; + } else { + player("I have the wolf bones right here."); + stage = 1; + } + break; + case 40: + if (player.getInventory().containsItem(WOLF_POUCH) && player.getInventory().containsItem(HOWL_SCROLL)) { + player("Here is the pouch and scroll."); + stage = 1; + return true; + } + if (!player.getInventory().contains(12528, 1) && !player.getBank().contains(12528, 1) && !player.getAttribute("has-key", false)) { + player.getInventory().add(new Item(12528, 1), player); + } + if (!player.getInventory().containsItem(WOLF_POUCH) || !player.getInventory().containsItem(HOWL_SCROLL)) { + npc("You need to bring me a wolf pouch and a howl scroll."); + stage = 0; + } + break; + case 50: + if (!player.getInventory().containsItem(WOLF_POUCH) || !player.getInventory().containsItem(HOWL_SCROLL)) { + for (Item i : WOLF_ITEMS) { + if (i.getId() == 12183) { + continue; + } + if (!player.getInventory().containsItem(i) && !player.getBank().containsItem(i) && player.getAttribute("taken-summoning-supplies") == null) { + if (i.getId() == 12528 && getVarp(player, 1178) == (2 << 11)) { + continue; + } + player.setAttribute("taken-summoning-supplies", true); + player.getInventory().add(i, player); + } + } + } + npc("Hurry up! Go remove the wolpertinger at last!"); + break; + case 60: + if (player.getSkills().getLevel(Skills.SUMMONING) < player.getSkills().getStaticLevel(Skills.SUMMONING)) { + npc("So, how did it go?"); + } else if (player.getSkills().getLevel(Skills.SUMMONING) >= player.getSkills().getStaticLevel(Skills.SUMMONING)) { + npc("Feeling refreshed?"); + stage = 20; + } + break; + case 100: + npc("Welcome to my humble abode. How can I help", "you?"); + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (quest.getStage(player)) { + case 0: + switch (stage) { + case 0: + player("I'm just a passing adventurer. Who are you?"); + stage = 1; + break; + case 1: + npc("Who am I? My dear boy, I just so happen to be one", "of the most important druids in this village!"); + stage = 2; + break; + case 2: + player("Wow, I don't meet that many celebrities."); + stage = 3; + break; + case 3: + player("What do you do here?"); + stage = 4; + break; + case 4: + npc("Well, firstly, I-"); + stage = 5; + break; + case 5: + interpreter.sendDialogue("There is a loud crash from upstairs, followed by the tinkling of", "broken glass."); + stage = 6; + break; + case 6: + interpreter.sendDialogues(getIds()[0], FacialExpression.FURIOUS, "Confound you, lapine menace!"); + stage = 7; + break; + case 7: + player("What was that?"); + stage = 8; + break; + case 8: + npc("That was the sound of my carefully arranged room", "being destroyed by a fluffy typhoon of wickedness!"); + stage = 9; + break; + case 9: + player("What?"); + stage = 10; + break; + case 10: + player("Wait, I'm good with monsters. Do you want me to go", "kill it for you?"); + stage = 11; + break; + case 11: + npc("Well, yes, but it's a little more complicated than that."); + stage = 12; + break; + case 12: + player("How complicated can it be?"); + stage = 13; + break; + case 13: + interpreter.sendDialogue("A resounding crash comes from upstairs."); + stage = 14; + break; + case 14: + npc("Complicated enough for me to waste time explaining it", "to you."); + stage = 15; + break; + case 15: + npc("Tell me, have you ever heard of Summoning?"); + stage = 16; + break; + case 16: + player("Not really."); + stage = 17; + break; + case 17: + npc("Well, some of the concepts I am about to discuss might", "go over your head, so I'll stick to the basics."); + stage = 18; + break; + case 18: + interpreter.sendDialogue("There is a series of loud crunches from upstairs."); + stage = 19; + break; + case 19: + interpreter.sendDialogues(getIds()[0], FacialExpression.FURIOUS, "Gah! That better not be my wardrobe!"); + stage = 20; + break; + case 20: + npc("Summoners are able to call upon animal familiars for a", "number of uses. These familiars can help the summoner", "practice their skills, fight on the battlefield, or offer any", "number of other benefits."); + stage = 21; + break; + case 21: + npc("Beneath this house is a monument - an obelisk - that", "allows us druids to trap this Summoning power."); + stage = 22; + break; + case 22: + interpreter.sendDialogue("A loud gnawing begins upstairs."); + stage = 23; + break; + case 23: + npc("I chased it upstairs, but I didn't have the necessary", "Summoning pouch to banish it."); + stage = 24; + break; + case 24: + npc("I sent my assistant, Stikklebrix, out to bring me what I", "needed, but he was not returned."); + stage = 25; + break; + case 25: + npc("If I leave this house, it will come down here, potentially", "even getting to the obelisk. If that happens, it could call", "another familiar through and multiply."); + stage = 26; + break; + case 26: + interpreter.sendDialogue("The gnawing stops. There is a crash."); + stage = 27; + break; + case 27: + player("How fast can it multiply?"); + stage = 28; + break; + case 28: + npc("Like a rabbit, because it is-"); + stage = 29; + break; + case 29: + player("A rabbit!"); + stage = 30; + break; + case 30: + npc("Well yes, rabbit-like, but-"); + stage = 31; + break; + case 31: + player("Oh, don't worry, I'll deal with this myself. One rabbit", "stew coming right up."); + stage = 32; + break; + case 32: + interpreter.sendDialogues(getIds()[0], FacialExpression.FURIOUS, "Very well, young fool. You go see how well you do", "against it."); + stage = 33; + break; + case 33: + end(); + quest.start(player); + break; + } + break; + case 10: + switch (stage) { + case 0: + player("No, not yet."); + stage = 1; + break; + case 1: + npc("What are you waiting for? I need to get", "that monster out of my room."); + stage = 2; + break; + case 2: + player("Sorry, I'll go right now."); + stage = 3; + break; + case 3: + end(); + break; + } + break; + case 20: + switch (stage) { + case 0: + npc("So, you finally saw what you're against, eh? Not as", "harmless as you assumed, I take it?"); + stage = 1; + break; + case 1: + player("Horns! Teeth!"); + stage = 2; + break; + case 2: + npc("Are you prepared to treat this situation with the gravity", "it deserves, now?"); + stage = 3; + break; + case 3: + player("What IS it?"); + stage = 4; + break; + case 4: + npc("A wolpertinger, and a pretty big one at that."); + stage = 5; + break; + case 5: + npc("They are spirits that tend to be on the energetic and", "destructive side when they manifest here, but are a little", "less violent on the spiritual plane."); + stage = 6; + break; + case 6: + player("So, what can be done about it? Can't you banish it?"); + stage = 7; + break; + case 7: + npc("Well, I could, but in order to do so, I'd need a spirit", "wolf pouch."); + stage = 8; + break; + case 8: + npc("Wolpertingers are generally afraid of wolves; that's the", "rabbity-side of them. A spirit wolf will scare it and banish", "it."); + stage = 9; + break; + case 9: + npc("The problem is that I don't have any of the necessary", "spirit wolf pouches, and the only thing keeping the giant", "wolpertingers upstairs is my presence. If I were to leave,", "it would amble downstairs to bring more of its kind."); + stage = 10; + break; + case 10: + npc("thought, as I said before."); + stage = 11; + break; + case 11: + player("Well, what if I were to bring you the elements you", "needed? Would that work?"); + stage = 12; + break; + case 12: + npc("Not really; I would need to go down to the obelisk in", "my cellar and use the necessary ingredients to make a", "spirit wolf pouch and some Howl scrolls, but it may slip", "out of the front door."); + stage = 13; + break; + case 13: + npc("You could infuse the pouch yourself, though. Would", "you like to learn the secrets of Summoning? I can", "sense the spark within you, urging you to master the", "art."); + stage = 14; + break; + case 14: + player("Certainly!"); + stage = 15; + break; + case 15: + player("What do you need me to bring?"); + stage = 16; + break; + case 16: + npc("That's wonderful!"); + stage = 17; + break; + case 17: + npc("You need to bring two lots of wolf bones. I can provide", "the other items you will need."); + stage = 18; + break; + case 18: + player("I'll get right on it."); + stage = 19; + break; + case 19: + end(); + quest.setStage(player, 30); + break; + } + break; + case 30: + switch (stage) { + case 0: + end(); + break; + case 1: + npc("Splendid, dear boy."); + stage = 2; + break; + case 2: + quest.setStage(player, 40); + for (Item i : WOLF_ITEMS) { + player.getInventory().add(i, player); + } + npc("Here are the pouches, spirit shards and charms you will", "need to make the spirit wolf pouch and Howl scrolls.", "This key is to the trapdoor over there, which leads to", "the obelisk."); + stage = 20; + break; + } + break; + case 40: + switch (stage) { + case 0: + end(); + break; + case 1: + npc("Wonderful! Now, all you have to do is go upstairs and", "summon the spirit wolf, then the Howl effect."); + stage = 2; + break; + case 2: + player("That's it?"); + stage = 3; + break; + case 3: + npc("It's that simple. The spirit wolf will, when you use the", "Howl scroll, chase away the giant wolpertinger and then", "disappear. Under normal circumstances, the spirit wolf", "would follow you around, defend you in combat and"); + stage = 4; + break; + case 4: + npc("often lend you its powers."); + stage = 5; + break; + case 5: + player("What sort of powers?"); + stage = 6; + break; + case 6: + npc("Well, for a start, it has the ability to perform a", "Summoning scroll that forces the opponents to flee. That is", "what it will use on the giant wolpertinger, with the", "difference being that the giant wolpertinger will be so"); + stage = 7; + break; + case 7: + npc("scared that it will retreat to its spiritual plane, rather", "than face the spirit wolf."); + stage = 8; + break; + case 8: + player("Great! So, how will I make it perform that Summoning", "scroll?"); + stage = 9; + break; + case 9: + npc("All you need to do is use the special move button in", "your Summoning interface, and aim it at the giant", "wolpertinger, once the spirit wolf has been summoned.", "The spirit wolf will then perform its special ability."); + stage = 10; + break; + case 10: + player("What a relief!"); + stage = 11; + break; + case 11: + npc("Well, I think that I have talked enough. Now you have", "to put it into practice."); + stage = 12; + break; + case 12: + player("Wish me luck!"); + stage = 13; + break; + case 13: + quest.setStage(player, 50); + end(); + break; + case 20: + player("What are these things?"); + stage = 21; + break; + case 21: + npc("Well, the wolf bones, spirit shards and gold charms are", "all ingredients to go into the pouch."); + stage = 22; + break; + case 22: + npc("The wolf bones give a solidity to the spirit, the charm", "attracts the type of familiar that you desire - in this", "case a gold charm - and that shards are the spirit's", "focus."); + stage = 23; + break; + case 23: + npc("You will first need to make two Summoning pouches:", "one that can be used to summon the spirit wolf, and", "another to tear open at the obelisk, creating some Howl", "scrolls. These Howl scrolls will help make the spirit wolf"); + stage = 24; + break; + case 24: + npc("perform a fear-inducing Howl special move."); + stage = 25; + break; + case 25: + player("Okay, I think I understood that. So, how do I get the", "obelisk to work?"); + stage = 26; + break; + case 26: + npc("Well, you stand before the obelisk with the charms,", "pouches, shards and bones necessary to complete two", "Summoning pouches. You should then 'use' your empty", "pouch on the obelisk. Your ingredients will be added to"); + stage = 27; + break; + case 27: + npc("the pouch, mixing with the spirits of a familiar to create a", "spirit wolf pouch."); + stage = 28; + break; + case 28: + npc("Creating a scroll is a similar process. By using a", "Summoning pouch on an obelisk and breaking it open,", "you are allowing the spirit energy to transform into a", "different form - some scrolls."); + stage = 29; + break; + case 29: + npc("Once you have a spirit wolf pouch and some Howl", "scrolls, you can come upstairs to see me, to find out", "what must be done with the giant wolpertinger."); + stage = 30; + break; + case 30: + player("It all sounds simple enough."); + stage = 31; + break; + case 31: + end(); + break; + } + break; + case 50: + end(); + break; + case 60: + switch (stage) { + case 0: + player("The spirit wolf scared it away!"); + stage = 1; + break; + case 1: + npc("My dear boy, you've done it!"); + stage = 2; + break; + case 2: + npc("I just hope the damage to my room isn't too bad."); + stage = 3; + break; + case 3: + player("All in a day's..."); + stage = 4; + break; + case 4: + player("Woah, I feel a little dizzy."); + stage = 5; + break; + case 5: + npc("Well, that Summoning was a drain on your rather", "untrained reserves."); + stage = 6; + break; + case 6: + npc("Go downstairs to the obelisk, as it will renew your", "energy."); + stage = 7; + break; + case 7: + npc("You should do that immediately - you'll be cut off from", "Summoning while you have no Summoning skill points", "remaining."); + stage = 8; + break; + case 8: + player("Woooooah..."); + stage = 9; + break; + case 9: + npc("You really need to renew your Summoning skill points", "at the obelisk, " + player.getUsername() + "."); + stage = 10; + break; + case 10: + end(); + break; + case 20: + player("Yeah, that does feel a lot better!"); + stage = 21; + break; + case 21: + player("Won't my energy renew on its own?"); + stage = 22; + break; + case 22: + npc("Not really. Your Summoning skill points need to be", "renewed at the obelisks or mini obelisks scattered", "around the world, while your special move bar will", "recharge slowly over time."); + stage = 23; + break; + case 23: + npc("The special move bar is like your special attack bar, not", "only because it is useful when attacking, but because it", "recharges slowly overtime."); + stage = 24; + break; + case 24: + npc("To help you on your way, I can tell you that I know", "of two other obelisks you can use."); + stage = 25; + break; + case 25: + npc("One is guarded by the ogres in Gu'Tanoth, and the", "other is on the coast near Brimhaven. There will be", "others, however."); + stage = 26; + break; + case 26: + player("Thanks for the information."); + stage = 27; + break; + case 27: + npc("My dear boy, it was nothing."); + stage = 28; + break; + case 28: + npc("Well, from your actions, you have proved yourself", "worthy to learn the secrets of Summoning."); + stage = 29; + break; + case 29: + npc("Speak to me on the subject if you wish to learn more", "about it. In the meantime, I will use my power to grant", "you access to the skill."); + stage = 30; + break; + case 30: + npc("Here is a little something to help you start your", "Summoning training."); + stage = 31; + break; + case 31: + player("Thanks!"); + stage = 32; + break; + case 32: + end(); + quest.finish(player); + break; + } + break; + case 100: + switch (stage) { + case 0: + if (player.getSkills().getStaticLevel(Skills.SUMMONING) == 99) { + options("So, what's Summoning all about, then?", "Can I buy some Summoning supplies?", "Can I buy a Summoning skillcape?"); + stage = 600; + } else { + options("So, what's Summoning all about, then?", "Can I buy some Summoning supplies?", "Please tell me about skillcapes."); + stage = 1; + } + break; + case 1: + switch (buttonId) { + case 1: + player("So, what's summoning all about, then?"); + stage = 10; + break; + case 2: + player("Can I buy some summoning supplies, please?"); + stage = 34; + break; + case 3: + player("Please tell me about skillcapes."); + stage = 400; + break; + } + break; + case 10: + npc("In general? Or did you have a specific topic in mind?"); + stage = 11; + break; + case 11: + options("In general.", "Tell me about summoning familiars.", "Tell me about special moves.", "Tell me about pets."); + stage = 12; + break; + case 12: + switch (buttonId) { + case 1: + npc("Well, you already know about Summoning in general;", "otherwise, we would not be having this conversation!"); + stage = 100; + break; + case 2: + npc("Summoned familiars are at the very core of Summoning.", "Each familiar is different, and the more powerful the", "summoner, the more powerful the familiar they can", "summon."); + stage = 20001; + break; + case 3: + npc("Well, if a Summoning pouch is split apart at an obelisk,", "then the energy it contained will reconstitute itself -", "transform - into a scroll. This scroll can then be used to", "make your familiar perform its special move."); + stage = 2001; + break; + case 4: + npc("Well, these are not really an element of the skill, as such,", "but more like a side-effect of training."); + stage = 2001; + break; + + } + break; + case 100: + npc("Effectively, the skill can be broken into two main parts:", "summoned familiars, and pets."); + stage = 101; + break; + case 101: + npc("Summoned familiars are spiritual animals that can be", "called to you from the spirit plane, to serve you for a", "period of time."); + stage = 102; + break; + case 102: + npc("These animals can also perform a special move, which is", "specific to the species. For example, a spirit wolf can", "perform the Howl special move if you are holding the", "correct Howl scroll."); + stage = 103; + break; + case 103: + npc("The last part of Summoning: the pets. The more", "you practice the skill, the more you will comprehend the", "natural world around you."); + stage = 104; + break; + case 104: + npc("This is reflected in your increased ability to raise animals", "as pets. It takes a skilled summoner to be able to raise", "some of " + ServerConstants.SERVER_NAME + "'s more exotic animals, such as the lizards", "of Karamja, or even dragons!"); + stage = 105; + break; + case 105: + npc("Now that I've given you this overview, do you want to", "know about anything specific?"); + stage = 106; + break; + case 106: + options("Tell me about summoning familiars.", "Tell me about special moves.", "Tell me about pets."); + stage = 107; + break; + case 107: + switch (buttonId) { + case 1: + npc("Summoned familiars are at the very core of Summoning.", "Each familiar is different, and the more powerful the", "summoner, the more powerful the familiar they can", "summon."); + stage = 20001; + break; + case 2: + npc("Well, if a Summoning pouch is split apart at an obelisk,", "then the energy it contained will reconstitute itself -", "transform - into a scroll. This scroll can then be used to", "make your familiar perform its special move."); + stage = 2001; + break; + case 3: + npc("Well, these are not really an element of the skill, as such,", "but more like a side-effect of training."); + stage = 2001; + break; + } + break; + case 2001: + end(); + break; + case 2000: + npc("Summoned familiars are at the very core of Summoning.", "Each familiar is different, and the more powerful the", "summoner, the more powerful the familiar they can", "summon."); + stage = 20001; + break; + case 20001: + end(); + break; + case 34: + npc("If you like! It's good to see you training."); + stage = 35; + break; + case 35: + end(); + npc.openShop(player); + break; + case 400: + npc("Of course. Skillcapes are a symbol of achievement. Only", "people who have mastered a skill and reached level 99 can", "get their hands on them and gain the benefits they carry.", "Is there something else I can help you with perhaps?"); + stage = 401; + break; + case 401: + interpreter.sendOptions("Choose an option:", "So, what's Summoning all about, then?", "Can I buy some Summoning supplies?", "Please tell me about skillcapes."); + stage = 1; + break; + case 600: + switch (buttonId) { + case 1: + player("So, what's summoning all about, then?"); + stage = 10; + break; + case 2: + player("Can I buy some summoning supplies, please?"); + stage = 34; + break; + case 3: + player("Can I buy a Skillcape of Summoning?"); + stage = 599; + break; + } + break; + case 599: + npc("Why yes you can! I must warn you that they cost", "a total of 99000 coins. Do you wish to still", "buy a skillcape of Summoning?"); + stage = 601; + break; + case 601: + options("Yes.", "No."); + stage = 602; + break; + case 602: + switch (buttonId) { + case 1: + player("Yes, please."); + stage = 603; + break; + case 2: + end(); + break; + } + break; + case 603: + if (player.getInventory().freeSlots() < 2) { + player("Sorry, I don't seem to have enough inventory space."); + stage = 604; + return true; + } + if (!player.getInventory().containsItem(COINS)) { + end(); + return true; + } + if (!player.getInventory().remove(COINS)) { + player("Sorry, I don't seem to have enough coins", "with me at this time."); + stage = 604; + return true; + } + if (player.getInventory().add(ITEMS[player.getSkills().getMasteredSkills() > 1 ? 1 : 0], ITEMS[2])) { + player("There you go, enjoy!"); + stage = 604; + } + break; + case 604: + end(); + break; + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 6971 }; + } + +} diff --git a/Server/src/main/content/region/asgarnia/taverley/dialogue/SanfewDialogue.java b/Server/src/main/content/region/asgarnia/taverley/dialogue/SanfewDialogue.java new file mode 100644 index 0000000..0c5d094 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/taverley/dialogue/SanfewDialogue.java @@ -0,0 +1,149 @@ +package content.region.asgarnia.taverley.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.game.node.item.Item; +import content.data.Quests; + +/** + * Handles the SanfewDialogue dialogue. + * @author 'Vexia + */ +@Initializable +public class SanfewDialogue extends DialoguePlugin { + + public SanfewDialogue() { + + } + + public SanfewDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new SanfewDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "What can I do for you young 'un?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + if (player.getQuestRepository().getQuest(Quests.DRUIDIC_RITUAL).getStage(player) == 20) { + interpreter.sendDialogues(npc, FacialExpression.HALF_ASKING, "Did you bring me the required ingredients for the", "potion?"); + stage = 100; + break; + } + if (player.getQuestRepository().getQuest(Quests.DRUIDIC_RITUAL).getStage(player) == 10) { + interpreter.sendOptions("Select an Option", "I've been sent to help purify the Varrock stone circle.", "Actually, I don't need to speak to you."); + stage = 2; + break; + } + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Nothing... I'll just be on my way now."); + stage = 1; + break; + case 1: + end(); + break; + case 2: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I've been sent to assist you with the ritual to purify the", "Varrockian stone circle."); + stage = 5; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Actually, I don't need to speak to you."); + stage = 3; + break; + } + break; + case 3: + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "Well, we all make mistakes sometimes."); + stage = 4; + break; + case 4: + end(); + break; + case 5: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Well, what I'm struggling with right now is the meats", "needed for the potion to honour Guthix. I need the raw", "meat of four different animals for it, but not just any", "old meats will do."); + stage = 6; + break; + case 6: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Each meat has to be dipped individually into the", "Cauldron of Thunder for it to work correctly."); + stage = 7; + break; + case 7: + interpreter.sendDialogues(player, FacialExpression.ASKING, "Where can I find this cauldron?"); + stage = 8; + break; + case 8: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "It is located somewhere in the mysterious underground", "halls which are located somewhere in the woods just", "South of here. They are too dangerous for me to go", "myself however."); + player.getQuestRepository().getQuest(Quests.DRUIDIC_RITUAL).setStage(player, 20); + stage = 9; + break; + case 9: + end(); + break; + case 100: + if (player.getInventory().containItems(522, 523, 524, 525)) { + interpreter.sendDialogues(player, null, "Yes, I have all four now!"); + stage = 200; + break; + } + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No, not yet..."); + stage = 101; + break; + case 101: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Well let me know when you do young 'un."); + stage = 102; + break; + case 102: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'll get on with it."); + stage = 103; + break; + case 103: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Good, good."); + stage = 104; + break; + case 104: + end(); + break; + case 200: + interpreter.sendDialogues(npc, null, "Well hand 'em over then " + (player.isMale() ? "lad" : "lass") + "!"); + stage = 201; + break; + case 201: + interpreter.sendDialogues(npc, null, "Thank you so much adventurer! These meats will allow", "our potion to honour Guthix to be completed, and bring", "one step closer to reclaiming our stone circle!"); + stage = 202; + break; + case 202: + player.getInventory().remove(new Item(522, 1), new Item(523, 1), new Item(524, 1), new Item(525, 1)); + player.getQuestRepository().getQuest(Quests.DRUIDIC_RITUAL).setStage(player, 99); + player.getQuestRepository().syncronizeTab(player); + interpreter.sendDialogues(npc, null, "Now go and talk to Kaqemeex and he will introduce", "you to the wonderful world of herblore and potion", "making!"); + stage = 203; + break; + case 203: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 454 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/taverley/dialogue/TeegidDialogue.java b/Server/src/main/content/region/asgarnia/taverley/dialogue/TeegidDialogue.java new file mode 100644 index 0000000..d6b8d3a --- /dev/null +++ b/Server/src/main/content/region/asgarnia/taverley/dialogue/TeegidDialogue.java @@ -0,0 +1,69 @@ +package content.region.asgarnia.taverley.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.world.map.Direction; +import core.plugin.Initializable; +import core.game.world.map.Location; + +/** + * Handles the TeegidDialogue dialogue. + * @author 'Vexia + */ +@Initializable +public class TeegidDialogue extends DialoguePlugin { + + public TeegidDialogue() { + + } + + public TeegidDialogue(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[] { 1213 }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Yeah. What is it to you?"); + stage = 1; + break; + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Nice day for it."); + stage = 2; + break; + case 2: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Suppose it is."); + stage = 3; + break; + case 3: + end(); + break; + } + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new TeegidDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + npc.setDirection(Direction.SOUTH); + npc.faceLocation(Location.create(2923, 3418, 0)); + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "So, you're doing laundry, eh?"); + stage = 0; + npc.faceLocation(Location.create(2923, 3418, 0)); + return true; + } +} diff --git a/Server/src/main/content/region/asgarnia/taverley/dialogue/VelrakDialogue.kt b/Server/src/main/content/region/asgarnia/taverley/dialogue/VelrakDialogue.kt new file mode 100644 index 0000000..b6ea3c4 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/taverley/dialogue/VelrakDialogue.kt @@ -0,0 +1,62 @@ +package content.region.asgarnia.taverley.dialogue + +import core.api.Container +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import core.tools.END_DIALOGUE + +@Initializable +class VelrakDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player?): DialoguePlugin { + return VelrakDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + if(inInventory(player, Items.DUSTY_KEY_1590)){ + playerl(FacialExpression.HALF_THINKING, "Are you still here?").also { stage = 100 } + } else { + npcl(FacialExpression.FRIENDLY, "Thank you for rescuing me! It isn't very comfy in this cell.") + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> options("So... do you know anywhere good to explore?","Do I get a reward for freeing you?").also { stage++ } + 1 -> when(buttonId){ + 1 -> playerl(FacialExpression.HALF_THINKING, "So... do you know anywhere good to explore?").also { stage = 10 } + 2 -> playerl(FacialExpression.FRIENDLY, "Do I get a reward for freeing you?").also { stage = 20 } + } + + 10 -> npcl(FacialExpression.HALF_THINKING, "Well, this dungeon was quite good to explore...until I got captured, anyway. I was given a key to an inner part of this dungeon by a mysterious stranger!").also { stage++ } + 11 -> npcl(FacialExpression.NEUTRAL, "It's rather tough for me to get that far into the dungeon however. I just keep getting captured! Would you like to give it a go?").also { stage++ } + 12 -> options("Yes, please!", "No, it's too dangerous for me too.").also { stage++ } + 13 -> when(buttonId){ + 1 -> playerl(FacialExpression.FRIENDLY, "Yes, please!").also { stage++ } + 2 -> playerl(FacialExpression.NEUTRAL, "No, it's too dangerous for me too.").also { stage = 15 } + } + + 14 -> sendItemDialogue(player, Items.DUSTY_KEY_1590, "Velrak reaches somewhere mysterious and passes you a key.").also { addItem(player, Items.DUSTY_KEY_1590, 1); stage = END_DIALOGUE } + + 15 -> npcl(FacialExpression.FRIENDLY, "I don't blame you!").also { stage = END_DIALOGUE } + + 20 -> npcl(FacialExpression.HALF_GUILTY, "Well, not really. The Black Knights took all of my stuff before throwing me in here to rot!").also { stage = 0 } + + 100 -> npcl(FacialExpression.HALF_THINKING, "Yes... I'm still plucking up the courage to run out past those Black Knights.").also { stage++ } + 101 -> playerl(FacialExpression.FRIENDLY, "Oh, go on. You can do it!").also { stage = END_DIALOGUE } + } + + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.VELRAK_THE_EXPLORER_798) + } + + +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/taverley/handlers/ArmourSuitNPC.java b/Server/src/main/content/region/asgarnia/taverley/handlers/ArmourSuitNPC.java new file mode 100644 index 0000000..2a85c2b --- /dev/null +++ b/Server/src/main/content/region/asgarnia/taverley/handlers/ArmourSuitNPC.java @@ -0,0 +1,67 @@ +package content.region.asgarnia.taverley.handlers; + +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.plugin.Initializable; +import core.game.world.map.Location; + +/** + * Represents the Suit of armour NPC used in Taverly dungeon (entering Cauldron + * of thunder room). + * @author Emperor + */ +@Initializable +public final class ArmourSuitNPC extends AbstractNPC { + + /** + * Constructs a new {@code ArmourSuitNPC} {@code Object}. + */ + public ArmourSuitNPC() { + this(453, null); + } + + /** + * Constructs a new {@code ArmourSuitNPC} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + public ArmourSuitNPC(int id, Location location) { + super(id, location); + } + + @Override + public void init() { + super.init(); + super.setRespawn(false); + GameWorld.getPulser().submit(new Pulse(50, this) { + @Override + public boolean pulse() { + if (!getProperties().getCombatPulse().isAttacking() && !inCombat()) { + clear(); + return true; + } + return false; + } + }); + } + + @Override + public void clear() { + super.clear(); + SceneryBuilder.add(new Scenery(818, getProperties().getSpawnLocation(), 1)); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new ArmourSuitNPC(id, location); + } + + @Override + public int[] getIds() { + return new int[] { 453 }; + } + +} diff --git a/Server/src/main/content/region/asgarnia/taverley/handlers/CrystalChestPlugin.java b/Server/src/main/content/region/asgarnia/taverley/handlers/CrystalChestPlugin.java new file mode 100644 index 0000000..59fd7be --- /dev/null +++ b/Server/src/main/content/region/asgarnia/taverley/handlers/CrystalChestPlugin.java @@ -0,0 +1,159 @@ +package content.region.asgarnia.taverley.handlers; + +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.OptionHandler; +import core.game.interaction.UseWithHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Plugin; +import core.plugin.ClassScanner; +import core.plugin.Initializable; +import core.tools.RandomFunction; + +/** + * Represents the plugin used for the crystal chest. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class CrystalChestPlugin extends UseWithHandler { + + /** + * Represents the cyrstal key. + */ + private static final Item KEY = new Item(989); + + /** + * Constructs a new {@code CrystalChestPlugin} {@code Object}. + */ + public CrystalChestPlugin() { + super(989); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(172, OBJECT_TYPE, this); + ClassScanner.definePlugin(new OptionHandler() { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(172).getHandlers().put("option:open", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + unlock(player); + return true; + } + + }); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + unlock(event.getPlayer()); + return true; + } + + /** + * Unlocks the chest. + * @param player the player, + * @return true if so. + */ + private boolean unlock(Player player) { + if (!player.getInventory().contains(989, 1)) { + player.getPacketDispatch().sendMessage("This chest is securely locked shut."); + return true; + } + if (player.getInventory().freeSlots() == 0) { + player.getPacketDispatch().sendMessage("Not enough inventory space."); + return true; + } + if (player.getInventory().remove(KEY)) { + Reward reward = Reward.getReward(player); + for (Item i : reward.getItems()) { + player.getInventory().add(i, player); + } + player.getPacketDispatch().sendMessage("You unlock the chest with your key."); + player.getPacketDispatch().sendMessage("You find some treasure in the chest!"); + } + return true; + } + + /** + * Represents a crystal ches reward. + * @author 'Vexia + */ + public enum Reward { + FIRST(39.69, new Item(1631, 1), new Item(1969, 1), new Item(995, 2000)), SECOND(16.72, new Item(1631, 1)), THIRD(10.57, new Item(1631, 1), new Item(371, 5), new Item(995, 1000)), FOURTH(7.73, new Item(1631, 1), new Item(556, 50), new Item(555, 50), new Item(557, 50), new Item(554, 50), new Item(559, 50), new Item(558, 50), new Item(565, 10), new Item(9075, 10), new Item(566, 10)), FIFTH(6.55, new Item(1631, 1), new Item(454, 100)), SIXTH(4.23, new Item(1631, 1), new Item(1603, 2), new Item(1601, 2)), SEVENTH(3.67, new Item(1631, 1), new Item(985, 1), new Item(995, 750)), EIGHT(3.51, new Item(1631, 1), new Item(2363, 3)), NINTH(3.26, new Item(1631, 1), new Item(987, 1), new Item(995, 750)), TENTH(2.75, new Item(1631, 1), new Item(441, 150)), ELEVENTH(1.06, new Item(1631, 1), new Item(1183, 1)), TWELFTH(0.26, new Item(1631, 1), new Item(1079, 1)), // FOR + // MALES! + TWELFTH_FEMALE(0.26, new Item(1631, 1), new Item(1093, 1)); // FOR + // SHEMALES(Female) + + /** + * Represents the item rewards. + */ + private final Item[] items; + + /** + * Represents the chance of getting the item. + */ + private final double chance; + + /** + * Constructs a new {@code CrystalChestPlugin} {@code Object}. + * @param chance the chance. + * @param items the item. + */ + Reward(double chance, Item... items) { + this.chance = chance; + this.items = items; + } + + /** + * Gets the reward. + * @param player the player. + * @return the reward. + */ + public static Reward getReward(final Player player) { + int totalChance = 0; + for (Reward r : values()) { + if (r == Reward.TWELFTH_FEMALE && !player.getAppearance().isMale()) { + continue; + } + totalChance += r.getChance(); + } + final int random = RandomFunction.random(totalChance); + int total = 0; + for (Reward r : values()) { + total += r.getChance(); + if (random < total) { + return r; + } + } + return null; + } + + /** + * Gets the items. + * @return The items. + */ + public Item[] getItems() { + return items; + } + + /** + * Gets the chance. + * @return The chance. + */ + public double getChance() { + return chance; + } + + } + +} diff --git a/Server/src/main/content/region/asgarnia/taverley/handlers/CrystalKeyObjectPlugin.java b/Server/src/main/content/region/asgarnia/taverley/handlers/CrystalKeyObjectPlugin.java new file mode 100644 index 0000000..5bc49c4 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/taverley/handlers/CrystalKeyObjectPlugin.java @@ -0,0 +1,22 @@ +package content.region.asgarnia.taverley.handlers; + +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.plugin.Plugin; + +public class CrystalKeyObjectPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.setOptionHandler("open", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + return false; + } + +} diff --git a/Server/src/main/content/region/asgarnia/taverley/handlers/TaverleyDungeonListeners.kt b/Server/src/main/content/region/asgarnia/taverley/handlers/TaverleyDungeonListeners.kt new file mode 100644 index 0000000..fd9c45b --- /dev/null +++ b/Server/src/main/content/region/asgarnia/taverley/handlers/TaverleyDungeonListeners.kt @@ -0,0 +1,42 @@ +package content.region.asgarnia.taverley.handlers + +import core.api.* +import org.rs09.consts.Items +import org.rs09.consts.Scenery +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +class TaverleyDungeonListeners : InteractionListener { + + val BD_GATE = Scenery.GATE_2623 + val JAIL_DOOR = Scenery.DOOR_31838 + + override fun defineListeners() { + + on(BD_GATE, IntType.SCENERY, "open"){ player, node -> + if(!inInventory(player, Items.DUSTY_KEY_1590)){ + sendMessage(player, "This gate seems to be locked.") + } else { + core.game.global.action.DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } + return@on true + } + + + on(JAIL_DOOR, IntType.SCENERY, "open"){ player, node -> + when(player.location.y){ + 9689 -> core.game.global.action.DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) //inside the cell going out + 9690 -> { //outside the cell going in + if(!inInventory(player, Items.JAIL_KEY_1591)){ + sendMessage(player, "This door is locked.") + } else { + core.game.global.action.DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } + } + } + + return@on true + } + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/taverley/handlers/TaverlyDungeonPlugin.java b/Server/src/main/content/region/asgarnia/taverley/handlers/TaverlyDungeonPlugin.java new file mode 100644 index 0000000..4dc86de --- /dev/null +++ b/Server/src/main/content/region/asgarnia/taverley/handlers/TaverlyDungeonPlugin.java @@ -0,0 +1,71 @@ +package content.region.asgarnia.taverley.handlers; + +import core.cache.def.impl.SceneryDefinition; +import core.game.global.action.DoorActionHandler; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the plugin used for taverly dungeon. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class TaverlyDungeonPlugin extends OptionHandler { + + /** + * The suits of armour. + */ + private static final NPC[] ARMOUR_SUITS = new NPC[2]; + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(2143).getHandlers().put("option:open", this); + SceneryDefinition.forId(2144).getHandlers().put("option:open", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + final int id = ((Scenery) node).getId(); + switch (id) { + case 2143: + case 2144: + if (player.getLocation().getX() < node.getLocation().getX() && !player.getAttribute("spawned_suits", false)) { + boolean alive = true; + for (int i = 0; i < ARMOUR_SUITS.length; i++) { + NPC npc = ARMOUR_SUITS[i]; + if (npc == null || !npc.isActive()) { + Location location = Location.create(2887, 9829 + (i * 3), 0); + ARMOUR_SUITS[i] = npc = NPC.create(453, location); + npc.init(); + npc.getProperties().getCombatPulse().attack(player); + Scenery object = RegionManager.getObject(location); + if (object != null) { + SceneryBuilder.remove(object); + } + alive = false; + } + } + if (!alive) { + player.setAttribute("spawned_suits", true); + player.getPacketDispatch().sendMessage("Suddenly the suit of armour comes to life!"); + return true; + } + } + player.removeAttribute("spawned_suits"); + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + return true; + } + return false; + } + +} diff --git a/Server/src/main/content/region/asgarnia/taverley/quest/DruidicRitual.kt b/Server/src/main/content/region/asgarnia/taverley/quest/DruidicRitual.kt new file mode 100644 index 0000000..15440a4 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/taverley/quest/DruidicRitual.kt @@ -0,0 +1,93 @@ +package content.region.asgarnia.taverley.quest + +import core.api.* +import core.game.component.Component +import core.game.interaction.QueueStrength +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import org.rs09.consts.Items +import content.data.Quests + +/** + * Druidic Ritual Quest + */ +@Initializable +class DruidicRitual : Quest(Quests.DRUIDIC_RITUAL, 48, 47, 4, 80, 0, 3, 4) { + + override fun drawJournal(player: Player, stage: Int) { + super.drawJournal(player, stage) + var line = 12 + var stage = getStage(player) + + var started = getQuestStage(player, Quests.DRUIDIC_RITUAL) > 0 + + if (!started) { + line(player, "I can start this quest by speaking to !!Kaqemeex?? who is at", line++) + line(player, "the !!Druids Circle?? just !!north?? of !!Taverly??.", line++) + } else { + line(player, "Kaqemeex and the druids are preparing a ceremony to", line++, true) + line(player, "purify the Varrock stone circle. I told Kaqemeex I would", line++, true) + line(player, "help them.", line++, true) + + if (stage >= 20) { + // Line disappears. + } else if (stage >= 10) { + line++ + line(player, "I should speak to !!Sanfew?? in the village to the !!south??.", line++) + } + + if (stage >= 99) { + line(player, "The ceremony required various meats being placed in the", line++, true) + line(player, "Cauldron of Thunder. I did this and gave them to Sanfew.", line++, true) + } else if (stage >= 20) { + line++ + line(player, "!!Sanfew?? told me for the ritual they would need me to place", line++) + line(player, "!!raw bear meat??, !!raw chicken??, !!raw rat meat??, and !!raw beef?? in", line++) + line(player, "the !!Cauldron of Thunder?? in the !!dungeon south?? of !!Taverley??.", line++) + } + + if (stage >= 100) { + line(player, "Kaqemeex then taught me the basics of the Heblore skill.", line++, true) + } else if (stage >= 99) { + line++ + line(player, "I should speak to !!Kaqemeex?? again and claim my !!reward??.", line++) + } + + if (stage >= 100) { + line++ + line(player,"QUEST COMPLETE!", line++) + line(player, "I gained !!4 quest points??, !!250 Heblore XP?? and access to", line++) + line(player, "the !!Heblore skill??.", line) + } + } + } + + override fun finish(player: Player) { + var ln = 10 + super.finish(player) + player.packetDispatch.sendString("You have completed the Druidic Ritual Quest!", 277, 4) + player.packetDispatch.sendItemZoomOnInterface(Items.CLEAN_GUAM_249, 230, 277, 5) + + drawReward(player,"4 Quest Points", ln++) + drawReward(player,"250 Herblore XP", ln++) + drawReward(player,"Access to Herblore skill", ln++) + + rewardXP(player, Skills.HERBLORE, 250.0) + + player.interfaceManager.closeChatbox() + } + + override fun questCloseEvent(player: Player?, component: Component?) { + queueScript(player!!, 1, QueueStrength.SOFT) { + openDialogue(player,455, NPC.create(455, player.location), true) + return@queueScript stopExecuting(player) + } + } + + override fun newInstance(`object`: Any?): Quest { + return this + } +} diff --git a/Server/src/main/content/region/asgarnia/taverley/quest/WolfWhistle.java b/Server/src/main/content/region/asgarnia/taverley/quest/WolfWhistle.java new file mode 100644 index 0000000..ec4661c --- /dev/null +++ b/Server/src/main/content/region/asgarnia/taverley/quest/WolfWhistle.java @@ -0,0 +1,192 @@ +package content.region.asgarnia.taverley.quest; + +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import org.rs09.consts.Items; + +import static core.api.ContentAPIKt.*; +import content.data.Quests; + + +/** + * Represents the demon slayer quest. + * @author 'Vexia + */ +@Initializable +public class WolfWhistle extends Quest { + + /** + * The wolf bones item. + */ + public static final Item WOLF_BONES = new Item(2859, 2); + + /** + * Constructs a new {@code WolfWhistle} {@code Object}. + */ + public WolfWhistle() { + super(Quests.WOLF_WHISTLE, 146, 145, 1); + } + + @Override + public void drawJournal(Player player, int stage) { + super.drawJournal(player, stage); + var line = 12; + + if(stage == 0){ + line(player, "I can begin this quest by talking to !!Pikkupstix??, who lives in", line++, false); + line(player, "!!Taverly??.", line++, false); + limitScrolling(player, line, true); + } else { + if (stage >= 10) { + line(player, "Having spoken to !!Pikkupstix??, it seems that all I have to do", line++, stage >= 20); + line(player, "is get rid of the !!little rabbit upstairs in his house??.", line++, stage >= 20); + line++; + } + if (stage >= 20) { + line(player, "It appears that I have underestimated the rabbit in this", line++, stage >= 30); + line(player, "case; it is some !!huge rabbit-wolf-monster-bird-thing??. I", line++, stage >= 30); + line(player, "think I should speak to !!Pikkupstix?? to find out what is going", line++, stage >= 30); + line(player, "on.", line++, stage >= 30); + line++; + } + // Clicking on the ladder - sendMessage("There is no reason to go up there and face that thing again.") + if (stage >= 30) { + line(player, "I have spoken to !!Pikkupstix??, who has promised to teach me ", line++, stage >= 40); + line(player, "the secrets of !!Summoning?? if I can help dismiss the !!giant??", line++, stage >= 40); + line(player, "!!wolpertinger??. To do this, I need to bring him !!2 lots of wolf??", line++, stage >= 40); + line(player, "!!bones??.", line++, stage >= 40); + + if (stage == 30) { + line(player, "!!I need to get 2 lots of wolf bones.??", line++, inInventory(player, Items.WOLF_BONES_2859, 2)); + } else { + line(player, "I have given Pikkupstix all of the items he requested.", line++, true); + line++; + } + } + if (stage >= 40) { + line(player, "Pikkupstix has given me some !!gold charms??, !!spirit shards??", line++, stage >= 50); + line(player, "and !!pouches??, with which to make a !!spirit wolf pouch?? and", line++, stage >= 50); + line(player, "some !!Howl scrolls??. I will then be able to use them to dismiss", line++, stage >= 50); + line(player, "the !!giant wolpertinger??.", line++, stage >= 50); + } + if (stage == 40 && inInventory(player, Items.TRAPDOOR_KEY_12528, 1)) { + line(player, "I need to open the !!trapdoor?? with the !!trapdoor key?? that I", line++, false); + line(player, "have been given.", line++, false); + } else if (stage >= 50 || player.getAttribute("has-key", false)) { + line(player, "I have unlocked the trapdoor.", line++, true); + } + + // This part is a shitshow. + if (stage >= 50 || (stage >= 40 && (inInventory(player, Items.SPIRIT_WOLF_POUCH_12047, 1) || inInventory(player, Items.HOWL_SCROLL_12425, 1)))) { + line(player, "I need to go into Pikkupstix's !!cellar?? and !!infuse a pouch?? at", line++, stage >= 50); + line(player, "the obelisk, using the items I have been given.", line++, stage >= 50); + line++; + line(player, "I have infused the spirit wolf pouch and made some Howl", line++, stage >= 50); + line(player, "scrolls. I should speak with !!Pikkupstix?? about how to use", line++, stage >= 50); + line(player, "them.", line++, stage >= 50); + line++; + } else if (stage >= 40 && inInventory(player, Items.SPIRIT_WOLF_POUCH_12047, 2)) { + line(player, "I have infused the 2 spirit wolf pouches, but I need to", line++, false); + line(player, "transform one of them into scrolls at the obelisk.", line++, false); + } else if (stage >= 40 && player.getAttribute("has-key", false)) { + line(player, "I need to go into Pikkupstix's !!cellar?? and !!infuse a pouch?? at", line++); + line(player, "the obelisk, using the items I have been given.", line++); + line(player, "!!I need to bring 2 lots of wolf bones.??", line++, inInventory(player, Items.WOLF_BONES_2859, 2)); + line(player, "!!I need to bring the pouches.??", line++, inInventory(player, Items.POUCH_12155, 2)); + line(player, "!!I need to bring the gold charms.??", line++, inInventory(player, Items.GOLD_CHARM_12158, 2)); + line(player, "!!I need to bring the spirit shards.??", line++, inInventory(player, Items.SPIRIT_SHARDS_12183, 14)); + } + + if (stage >= 50) { + line(player, "I have been told how to use the spirit wolf pouch and Howl", line++, stage >= 60); + line(player, "scrolls. I should go back upstairs and confront the !!giant??", line++, stage >= 60); + line(player, "!!wolpertinger??.", line++, stage >= 60); + line++; + } + if (stage == 50) { // Does not stay. + if (inInventory(player, Items.SPIRIT_WOLF_POUCH_12047, 1)) { + line(player, "I have the spirit wolf pouch on me.", line++, false); + } else { + line(player, "!!I have lost the spirit wolf pouch.??", line++, false); + } + if (inInventory(player, Items.HOWL_SCROLL_12425, 1)) { + line(player, "I have the Howl scroll on me.", line++, false); + } else { + line(player, "!!I have lost the Howl scroll.??", line++, false); + } + } + + if (stage >= 60) { + // Technically, there should be an extra stage speaking to Pikkupstix here, but it is not available. + line(player, "I have banished the giant !!wolpertinger??. I should speak with", line++, true); + line(player, "!!Pikkupstix?? to get my reward.", line++, true); + line++; + if (player.getSkills().getLevel(Skills.SUMMONING) >= player.getSkills().getStaticLevel(Skills.SUMMONING) || stage >= 100) { + line(player, "I am feeling drained of Summoning skill points and need to", line++, true); + line(player, "recharge at the !!obelisk??.", line++, true); + line++; + line(player, "I have banished the giant !!wolpertinger?? and refreshed my", line++, stage >= 100); + line(player, "Summoning skill points. I should speak with !!Pikkupstix?? to", line++, stage >= 100); + line(player, "get my reward.", line++, stage >= 100); + line++; + } else { + line(player, "I am feeling drained of Summoning skill points and need to", line++); + line(player, "recharge at the !!obelisk??.", line++); + line++; + } + } + + if (stage >= 100) { + line(player, "I have been given access to the secrets of Summoning.", line++, true); + line(player,"QUEST COMPLETE!", line++); + line(player, "!!Reward:??", line++); + line(player, "1 Quest Point,", line++); + line(player, "access to the Summoning skill", line++); + line(player, "275 gold charms", line++); + line(player, "and 276 Summoning XP", line++); + } + limitScrolling(player, line, false); + } + } + + @Override + public void finish(Player player) { + super.finish(player); + player.getPacketDispatch().sendString("1 Quest Points", 277, 8+ 2); + player.getPacketDispatch().sendString("276 Summoning XP", 277, 9+ 2); + player.getPacketDispatch().sendString("Access to the Summoning", 277, 10+ 2); + player.getPacketDispatch().sendString("skill.", 277, 11+ 2); + player.getPacketDispatch().sendString("275 gold charms.", 277, 12+ 2); + player.getPacketDispatch().sendItemZoomOnInterface(12047, 230, 277, 3+ 2); + player.getSkills().addExperience(Skills.SUMMONING, 276); + player.getInventory().add(new Item(12158, 275), player); + player.removeAttribute("searched-body"); + player.getQuestRepository().syncronizeTab(player); + player.getInterfaceManager().openInfoBars(); + } + + @Override + public int[] getConfig(Player player, int stage) { + int val = getVarp(player, 1178); + boolean open = val >= 4096; + boolean closed = val == 2048; + if (stage == 100) { + if (val == 5 || val == 0) { + return new int[] { 1178, 32989 }; + } else if (val == 4101) { + return new int[] { 1178, 28893 }; + } + return new int[] { 1178, val }; + } + return new int[] { 1178, stage > 0 ? 5 + (open ? 4096 : 0) : stage >= 100 ? !closed ? 28893 : 32989 : 0 }; + } + + @Override + public Quest newInstance(Object object) { + return this; + } + +} diff --git a/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/BallInteraction.java b/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/BallInteraction.java new file mode 100644 index 0000000..df28abd --- /dev/null +++ b/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/BallInteraction.java @@ -0,0 +1,76 @@ +package content.region.asgarnia.taverley.quest.witchshouse; + +import core.game.interaction.MovementPulse; +import core.game.interaction.Option; +import core.game.node.entity.impl.PulseType; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.game.node.entity.combat.spell.SpellBlocks; +import content.minigame.mta.TelekineticGrabSpell; +import core.game.interaction.PluginInteraction; +import core.game.interaction.PluginInteractionManager; +import core.game.node.entity.skill.Skills; + +@Initializable +public class BallInteraction extends PluginInteraction { + private boolean handled; + @Override + public Plugin newInstance(Object arg) throws Throwable { + SpellBlocks.register(TelekineticGrabSpell.SPELL_ID, new Item(2407)); + setIds(new int[]{2407}); + PluginInteractionManager.register(this, PluginInteractionManager.InteractionType.ITEM); + return this; + } + + @Override + public boolean handle(Player player, Item item, Option option) { + player.debug("Trying to handle ball..."); + if(option.getName().toLowerCase().equals("take")){ + + player.debug("Take option used..."); + player.getPulseManager().run(new MovementPulse(player, item.getLocation().transform(0, -1, 0)) { + @Override + public boolean pulse() { + return true; + } + }, PulseType.STANDARD); + handleBall(player); + } + return handled; + } + + public void handleBall(Player player){ + if(player.getAttribute("witchs_house:experiment_killed",false)) { + if (player.getInventory().containsItem(new Item(2407))) { + player.sendMessage("You already have the ball."); + handled = true; + player.debug("Handled in branch 1"); + } else { + handled = false; + player.debug("Unhandled."); + } + } else { + if(player.getAttribute("witchs-experiment:npc_spawned", false)){ + player.sendMessage("Finish fighting the experiment first!"); + return; + } + player.debug("Handled in branch 2."); + int[] skillsToDecrease = {Skills.DEFENCE, Skills.ATTACK, Skills.STRENGTH, Skills.RANGE, Skills.MAGIC}; + for (int i = 0; i < skillsToDecrease.length; i++) { + player.getSkills().setLevel(i, player.getSkills().getLevel(i) > 5 ? player.getSkills().getLevel(i) - 5 : 1); + } + player.getPacketDispatch().sendMessage("The experiment glares at you, and you feel yourself weaken."); + new WitchsExperimentNPC(player.getAttribute("witchs_house:experiment_id",897), Location.create(2936, 3463, 0),player).init(); + player.setAttribute("witchs-experiment:npc_spawned",true); + handled = true; + } + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } +} diff --git a/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/BoyDialoguePlugin.java b/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/BoyDialoguePlugin.java new file mode 100644 index 0000000..2574498 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/BoyDialoguePlugin.java @@ -0,0 +1,151 @@ +package content.region.asgarnia.taverley.quest.witchshouse; + +import core.plugin.Initializable; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import content.data.Quests; + +/** + * Created for 2009Scape + * User: Ethan Kyle Millard + * Date: March 15, 2020 + * Time: 11:49 AM + */ +@Initializable +public class BoyDialoguePlugin extends DialoguePlugin { + + private static final Item BALL = new Item(2407); + + public BoyDialoguePlugin() { + } + + public BoyDialoguePlugin(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new BoyDialoguePlugin(player); + } + + @Override + public boolean open(Object... args) { + final Quest quest = player.getQuestRepository().getQuest(Quests.WITCHS_HOUSE); + player.debug(quest.isStarted(player) + " " + quest.getStage(player) ); + if (!quest.isStarted(player) && quest.getStage(player) < 10) { + player(FacialExpression.FRIENDLY, "Hello young man."); + setStage(1); + return true; + } + if (quest.isCompleted(player) || quest.getStage(player) == 100) { + sendDialogue("The boy is too busy playing with his ball to talk."); + finish(); + return true; + } + if (!player.getInventory().containsItem(BALL)) { + npc( FacialExpression.CHILD_THINKING, "Have you gotten my ball back yet?"); + } else { + player(FacialExpression.NEUTRAL, "Hi, I have got your ball back. It was MUCH harder", "than I thought it would be."); + } + setStage(11); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + final Quest quest = player.getQuestRepository().getQuest(Quests.WITCHS_HOUSE); + switch(stage) { + case -1: + end(); + break; + case 1: + sendDialogue("The boy sobs."); + next(); + break; + case 2: + options("What's the matter?", "Well if you're not going to answer then I'll go."); + next(); + break; + case 3: + switch(buttonId) { + case 1: + player(FacialExpression.THINKING, "What's the matter?"); + setStage(5); + break; + case 2: + player(FacialExpression.NEUTRAL, "Well if you're not going to answer then I'll go."); + next(); + break; + } + break; + case 4: + sendDialogue("The boy sniffs slightly."); + finish(); + break; + case 5: + npc(FacialExpression.CHILD_SAD, "I've kicked my ball over that hedge, into that garden!", "The old lady who lives there is scary... She's locked the","ball in her wooden shed! Can you get my ball back for", "me please?"); + next(); + break; + case 6: + options("Ok, I'll see what I can do.", "Get it back yourself."); + next(); + break; + case 7: + switch(buttonId) { + case 1: + player(FacialExpression.NEUTRAL, "Ok, I'll see what I can do."); + setStage(10); + break; + case 2: + player(FacialExpression.NEUTRAL, "Get it back yourself."); + next(); + break; + } + break; + case 8: + npc(FacialExpression.CHILD_SAD, "You're a meany."); + next(); + break; + case 9: + sendDialogue("The boy starts crying again."); + finish(); + break; + case 10: + npc(FacialExpression.CHILD_FRIENDLY, "Thanks mister!"); + finish(); + quest.start(player); + break; + case 11: + if (!player.getInventory().containsItem(BALL)) { + player(FacialExpression.NEUTRAL, "Not yet."); + next(); + } else { + if (player.getInventory().remove(BALL)) + sendDialogue("You give the ball back."); + setStage(13); + } + break; + case 12: + npc(FacialExpression.CHILD_ANGRY, "Well it's in the shed in that garden."); + finish(); + break; + case 13: + npc(FacialExpression.CHILD_FRIENDLY, "Thank you so much!"); + next(); + break; + case 14: + quest.finish(player); + finish(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 895 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/ExperimentSession.java b/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/ExperimentSession.java new file mode 100644 index 0000000..0163724 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/ExperimentSession.java @@ -0,0 +1,111 @@ +/* +package core.game.content.quest.witchs_house; + +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; + +public final class ExperimentSession { + + */ +/** + * The player. + *//* + + private final Player player; + + */ +/** + * The npc npc. + *//* + + private final WitchsExperimentNPC npc; + + */ +/** + * Constructs a new {@code ExperimentSession} {@code Object}. + * + * @param player the player. + *//* + + public ExperimentSession(final Player player) { + this.player = player; + this.npc = new WitchsExperimentNPC(WitchsExperimentNPC.ExperimentType.values()[0].getId(), Location.create(2936, 3463, 0), this); + if (player.getExtension(ExperimentSession.class) != null) { + player.removeExtension(ExperimentSession.class); + } + player.addExtension(ExperimentSession.class, this); + } + + */ +/** + * Creates the npc session. + * + * @param player the player. + * @return the session. + *//* + + public static ExperimentSession create(Player player) { + return new ExperimentSession(player); + } + + */ +/** + * Starts the session. + *//* + + public void start() { + if (npc.getType().ordinal() > 0) { + npc.init(); + npc.getProperties().getCombatPulse().attack(player); + return; + } + GameWorld.getPulser().submit(new Pulse(1, player) { + int count; + + @Override + public boolean pulse() { + if (++count == 1) { + npc.init(); + npc.setCommenced(true); + return true; + } + return false; + } + }); + } + + */ +/** + * Closes the session. + *//* + + public void close() { + npc.clear(); + player.removeExtension(ExperimentSession.class); + } + + */ +/** + * Gets the npc session. + * + * @param player the player. + * @return the session. + *//* + + public static ExperimentSession getSession(Player player) { + return player.getExtension(ExperimentSession.class); + } + + */ +/** + * Gets the player. + * + * @return The player. + *//* + + public Player getPlayer() { + return player; + } +}*/ diff --git a/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/MouseNPC.java b/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/MouseNPC.java new file mode 100644 index 0000000..db5b3d6 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/MouseNPC.java @@ -0,0 +1,97 @@ +package content.region.asgarnia.taverley.quest.witchshouse; + +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.world.GameWorld; +import core.game.world.map.Location; + +/** + * Created for 2009Scape + * User: Ethan Kyle Millard + * Date: March 15, 2020 + * Time: 10:56 AM + */ +public class MouseNPC extends AbstractNPC { + + /** + * The player. + */ + private Player player; + + /** + * The end time of the mouse being spawned. + */ + private int endTime; + + /** + * Represents the NPC ids of NPCs using this plugin. + */ + private static final int[] ID = {901}; + + /** + * Constructs a new {@code DSNedNPC} {@code Object}. + */ + public MouseNPC() { + super(0, null); + } + + /** + * Constructs a new {@code DSNedNPC} {@code Object}. + * + * @param id The NPC id. + * @param location The location. + */ + private MouseNPC(int id, Location location) { + super(id, location); + this.endTime = (int) (GameWorld.getTicks() + (4 / 0.6)); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new MouseNPC(id, location); + } + + @Override + public void handleTickActions() { + super.handleTickActions(); + if (player.getAttribute("mouse_out") == null) { + clear(); + } + if (GameWorld.getTicks() > endTime) { + clear(); + } + if (!player.isActive() || player.getLocation().getDistance(getLocation()) > 8) { + clear(); + } + + } + + @Override + public void clear() { + super.clear(); + player.removeAttribute("mouse_out"); + } + + @Override + public int[] getIds() { + return ID; + } + + /** + * Sets the player. + * @param player the player. + */ + public void setPlayer(Player player) { + this.player = player; + } + + /** + * Gets the player. + * @return The player. + */ + public Player getPlayer() { + return player; + } + + +} diff --git a/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/NoraTHaggNPC.java b/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/NoraTHaggNPC.java new file mode 100644 index 0000000..2192bf8 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/NoraTHaggNPC.java @@ -0,0 +1,149 @@ +package content.region.asgarnia.taverley.quest.witchshouse; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.node.entity.combat.DeathTask; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.net.packet.PacketRepository; +import core.net.packet.context.MinimapStateContext; +import core.net.packet.out.MinimapState; +import core.plugin.Initializable; +import core.plugin.Plugin; + +import java.util.List; + +/** + * Nora T Hagg NPC + * @author Ethan, cleaned up by ceik + * @date y'know + */ + +@Initializable +public class NoraTHaggNPC extends AbstractNPC { + + boolean walkdir; + + public NoraTHaggNPC() { + super(896, Location.create(2904, 3463, 0)); + } + private Location getRespawnLocation() { + return Location.create(2900, 3473, 0); + } + + private NoraTHaggNPC(int id, Location location) { + super(id, location); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + this.configure(); + init(); + return super.newInstance(arg); + } + + private boolean canTeleport(Entity t) { + int playerX = t.getLocation().getX(); + int npcX = getLocation().getX(); + int[] sectors = { 2904, 2907, 2910, 2914, 2918, 2922, 2926, 2928 }; + for (int i = 0; i < sectors.length -1; i++) { + if (npcX >= sectors[i] && npcX <= sectors[i+1] && playerX >= sectors[i] && playerX <= sectors[i+1]) { + if (playerX < npcX && getDirection() == Direction.WEST || playerX > npcX && getDirection() == Direction.EAST) { + return true; + } + if (playerX == npcX) { + return true; + } + } + } + return false; + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new NoraTHaggNPC(id, location); + } + + @Override + public int[] getIds() { + return new int[] { 896 }; + } + + + @Override + public int getWalkRadius() { + return 50; + } + + + public void configure() { + super.configure(); + setWalks(false); + setPathBoundMovement(true); + } + + private void sendTeleport(final Player player) { + player.lock(); + GameWorld.getPulser().submit(new Pulse(1) { + int delay = 0; + + @Override + public boolean pulse() { + if (delay == 0) { + face(player); + player.getInventory().remove(WitchsHousePlugin.BALL); + player.getInventory().remove(WitchsHousePlugin.KEY); + player.getInventory().remove(WitchsHousePlugin.DOOR_KEY); + sendChat("Stop! Thief!"); + player.getPacketDispatch().sendMessage("You've been spotted by the witch."); + player.graphics(new Graphics(110, 100)); + PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 2)); + } else if (delay == 2) { + sendChat("Klarata... Seppteno... Valkan!"); + face(null); + } else if (delay == 4) { + player.getProperties().setTeleportLocation(Location.create(getRespawnLocation())); + PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 0)); + face(null); + player.unlock(); + return true; + } + delay++; + return false; + } + }); + } + + @Override + public void tick() { + super.tick(); + List players = getViewport().getCurrentPlane().getPlayers(); + if(getLocation().getX() == 2930){ + walkdir = false; + } else if(getLocation().getX() == 2904){ + walkdir = true; + } + for (Player player : players) { + if (player == null || !player.isActive() || player.getLocks().isInteractionLocked() || DeathTask.isDead(player) || !canTeleport(player) || !CombatSwingHandler.isProjectileClipped(this, player, false)) { + continue; + } + animate(new Animation(5803)); + sendTeleport(player); + player.getPacketDispatch().sendMessage("" + getLocation() + " matches? " + (getLocation().getX() == 2904)); + } + if (location.getX() != 2930 && walkdir) { + this.getWalkingQueue().reset(); + this.getWalkingQueue().addPath(location.getX() + 1,3463,true); + } else if (location.getX() != 2904 && !walkdir) { + this.getWalkingQueue().reset(); + this.getWalkingQueue().addPath(location.getX() - 1,3463,true); + } + } + +} diff --git a/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/WitchesDiaryBook.kt b/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/WitchesDiaryBook.kt new file mode 100644 index 0000000..8417d0c --- /dev/null +++ b/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/WitchesDiaryBook.kt @@ -0,0 +1,137 @@ +package content.region.asgarnia.taverley.quest.witchshouse + +import content.global.handlers.iface.BookInterface +import content.global.handlers.iface.BookLine +import content.global.handlers.iface.Page +import content.global.handlers.iface.PageSet +import core.api.setAttribute +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import org.rs09.consts.Items + +/** + * Witches' Diary Book + * https://www.youtube.com/watch?v=rLsLPVOjNCY + * @author ovenbreado + * @author Ethan Kyle Millard + */ +class WitchesDiaryBook : InteractionListener { + companion object { + private val TITLE = "Witches' Diary" + private val CONTENTS = arrayOf( + PageSet( + Page( + BookLine("2nd of Pentember", 55), + BookLine("Experiment is growing", 56), + BookLine("larger daily. Making", 57), + BookLine("excellent progress now. I", 58), + BookLine("am currently feeding it", 59), + BookLine("on a mixture of fungus,", 60), + BookLine("tar and clay.", 61), + BookLine("It seems to like this", 62), + BookLine("combination a lot!", 63) + ), + Page( + BookLine("3rd of Pentember", 66), + BookLine("Experiment still going", 67), + BookLine("extremely well. Moved it", 68), + BookLine("to the wooden garden", 69), + BookLine("shed; it does too much", 70), + BookLine("damage in the house! it", 71), + BookLine("is getting very strong", 72), + BookLine("now, but unfortunately is", 73), + BookLine("not too intelligent yet. It", 74), + BookLine("has a really mean stare", 75), + BookLine("too!", 76) + ) + ), + PageSet( + Page( + BookLine("4th of Pentember", 55), + BookLine("Sausages for dinner", 56), + BookLine("tonight! Lovely!", 57), + BookLine("5th of Pentember", 59), + BookLine("A guy called Professor", 60), + BookLine("Oddenstein installed a", 61), + BookLine("new security system for", 62), + BookLine("me in the basement. He", 63), + BookLine("seems to have a lot of", 64), + BookLine("good security ideas.", 65) + ), + Page( + BookLine("6th of Pentember", 66), + BookLine("Don't want people getting", 67), + BookLine("into back garden to see", 68), + BookLine("the experiment. Professor", 69), + BookLine("Oddenstein is fitting me a", 70), + BookLine("new security system,", 71), + BookLine("after his successful", 72), + BookLine("installation in the cellar.", 73) + ) + ), + PageSet( + Page( + BookLine("7th of Pentember", 55), + BookLine("That pesky kid keeps", 56), + BookLine("kicking his ball into my", 57), + BookLine("garden. I swear, if he", 58), + BookLine("does it AGAIN, I'm going", 59), + BookLine("to lock his ball away in", 60), + BookLine("the shed.", 61), + BookLine("8th of Pentember.", 63), + BookLine("The security system is", 64), + BookLine("done. By Zamorak! Wow,", 65) + ), + Page( + BookLine("is it contrived! Now, to", 66), + BookLine("open my own back door,", 67), + BookLine("I lure a mouse out of a", 68), + BookLine("hole in the back porch, I", 69), + BookLine("fit a magic curved piece", 70), + BookLine("of metal to the harness", 71), + BookLine("on its back, the mouse", 72), + BookLine("goes back in the hole, and", 73), + BookLine("the door unlocks! The", 74), + BookLine("prof tells me that this is", 75), + BookLine("cutting edge technology!", 76) + ) + ), + PageSet( + Page( + BookLine("As an added precaution I", 55), + BookLine("have hidden the key to", 56), + BookLine("the shed in a secret", 57), + BookLine("compartment of the", 58), + BookLine("fountain in the garden.", 59), + BookLine("No one will ever look", 60), + BookLine("there.", 61), + BookLine("9th of Pentember", 63), + BookLine("Still can't think of a good", 64), + BookLine("name of 'The", 65) + ), + Page( + BookLine("Experiment'. Leaning", 66), + BookLine("Towards 'fritz'... Although", 67), + BookLine("am considering Lucy as", 68), + BookLine("it reminds me of my", 69), + BookLine("Mother!", 70) + ) + ) + ) + private fun display(player:Player, pageNum: Int, buttonID: Int) : Boolean { + BookInterface.pageSetup(player, BookInterface.FANCY_BOOK_3_49, TITLE, CONTENTS) + if (BookInterface.isLastPage(pageNum, CONTENTS.size)) { + setAttribute(player, "/save:readWitchsBook", true) + } + return true + } + } + + override fun defineListeners() { + on(Items.DIARY_2408, IntType.ITEM, "read") { player, _ -> + BookInterface.openBook(player, BookInterface.FANCY_BOOK_3_49, ::display) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/WitchsExperimentNPC.java b/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/WitchsExperimentNPC.java new file mode 100644 index 0000000..5f1e46e --- /dev/null +++ b/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/WitchsExperimentNPC.java @@ -0,0 +1,183 @@ +package content.region.asgarnia.taverley.quest.witchshouse; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.plugin.Initializable; + +/** + * Created for 2009Scape + * User: Ethan Kyle Millard + * Date: March 25, 2020 + * Time: 8:28 PM + */ +@Initializable +public class WitchsExperimentNPC extends AbstractNPC { + + private ExperimentType type; + private boolean commenced; + Player p; + + public WitchsExperimentNPC() { + super(0, null); + } + + WitchsExperimentNPC(int id, Location location, Player player) { + super(id, location); + this.setWalks(true); + this.setRespawn(false); + this.type = WitchsExperimentNPC.ExperimentType.forId(id); + p = player; + } + + @Override + public void handleTickActions() { + super.handleTickActions(); + if(!p.isActive() || !RegionManager.getLocalPlayers(this).contains(p)){ + p.removeAttribute("witchs-experiment:npc_spawned"); + clear(); + } + if (!getProperties().getCombatPulse().isAttacking()) { + getProperties().getCombatPulse().attack(p); + } + } + + @Override + public void startDeath(Entity killer) { + if (killer == p) { + type.transform(this, p); + return; + } + super.startDeath(killer); + } + + @Override + public boolean isAttackable(Entity entity, CombatStyle style, boolean message) { + return p == entity; + } + + @Override + public boolean canSelectTarget(Entity target) { + if (target instanceof Player) { + Player p = (Player) target; + return p == this.p; + } + return true; + } + + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new WitchsExperimentNPC(id, location, null); + } + + @Override + public int[] getIds() { + return new int[] { 897, 898, 899, 900 }; + } + + public void setType(ExperimentType type) { + this.type = type; + } + + public ExperimentType getType() { + return type; + } + + public void setCommenced(boolean commenced) { + this.commenced = commenced; + } + + public enum ExperimentType { + FIRST(897, ""), + SECOND(898, "The shapeshifter's body begins to deform!", "The shapeshifter turns into a spider!"), + THIRD(899, "The shapeshifter's body begins to twist!", "The shapeshifter turns into a bear!"), + FOURTH(900, "The shapeshifter's body pulses!", "The shapeshifter turns into a wolf!"), + END(-1, ""), + + ; + + private int id; + private String[] message; + + ExperimentType(int id, String... message) { + this.id = id; + this.message = message; + } + + /** + * Transforms the new npc. + */ + public void transform(final WitchsExperimentNPC npc, final Player player) { + final ExperimentType newType = next(); + npc.lock(); + npc.getPulseManager().clear(); + npc.getWalkingQueue().reset(); + player.setAttribute("/save:witchs_house:experiment_id",this.id); + GameWorld.getPulser().submit(new Pulse(1, npc, player) { + int counter; + + @Override + public boolean pulse() { + switch (++counter) { + + case 1: + npc.unlock(); + npc.getAnimator().reset(); + npc.fullRestore(); + npc.setType(newType); + npc.transform(newType.getId()); + npc.getImpactHandler().setDisabledTicks(1); + if (newType != END) { + npc.getProperties().getCombatPulse().attack(player); + } + if (newType.getMessage() != null && newType != END) { + player.sendMessage(newType.getMessage()[0]); + player.sendMessage(newType.getMessage()[1]); + } + if (newType == END) { + player.setAttribute("witchs_house:experiment_killed",true); + npc.clear(); + return false; + } + player.unlock(); + return true; + } + return false; + } + + }); + } + + public static ExperimentType forId(int id) { + for (ExperimentType type : values()) { + if (type.getId() == id) { + return type; + } + } + return null; + } + + private static ExperimentType[] experimentTypes = values(); + + public ExperimentType next() + { + return experimentTypes[this.ordinal() + 1]; + } + + public int getId() { + return id; + } + + public String[] getMessage() { + return message; + } + + } + +} diff --git a/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/WitchsHouse.java b/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/WitchsHouse.java new file mode 100644 index 0000000..ab2b32e --- /dev/null +++ b/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/WitchsHouse.java @@ -0,0 +1,64 @@ +package content.region.asgarnia.taverley.quest.witchshouse; + +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.plugin.Initializable; +import content.data.Quests; + +/** + * Created for 2009Scape + * User: Ethan Kyle Millard + * https://www.youtube.com/watch?v=-RuHho3NbWg + * Date: March 15, 2020 + * Time: 9:21 AM + */ +@Initializable +public class WitchsHouse extends Quest { + + /** + * Constructs a new {@code WitchsHouse} {@code Object}. + */ + public WitchsHouse() { + super(Quests.WITCHS_HOUSE, 124, 123, 4, 226, 0, 1, 7); + } + + @Override + public void drawJournal(Player player, int stage) { + super.drawJournal(player, stage); + var line = 12; + if(stage == 0){ + line(player, "I can start this quest by speaking to the !!little boy??", line++); + line(player, "standing by the long garden just !!north of Taverly??.", line++); + line(player, "I must be able to defeat a !!level 53 enemy??.", line++); + } else { + line(player, "A small boy kicked his ball over the fence into the nearby", line++, true); + line(player, "garden, and I have agreed to retrieve it for him.", line++, true); + if (stage == 10) { + line(player, "I should find a way into the !!garden?? where the !!ball?? is.", line++); + } + if (stage >= 100) { + line(player, "After puzzling through the strangely elaborate security", line++, true); + line(player, "system, and defeating a very strange monster, I returned", line++, true); + line(player, "the child's ball to him, and he thanked me for my help.", line++, true); + line++; + line(player,"QUEST COMPLETE!", line); + } + } + } + + @Override + public void finish(Player player) { + super.finish(player); + player.getPacketDispatch().sendString("4 Quest Points", 277, 8 + 2); + player.getPacketDispatch().sendString("6325 Hitpoints XP", 277, 9 + 2); + player.getSkills().addExperience(Skills.HITPOINTS, 6325); + player.getInterfaceManager().closeChatbox(); + player.getPacketDispatch().sendItemZoomOnInterface(2407, 240, 277, 3 + 2); + } + + @Override + public Quest newInstance(Object object) { + return this; + } +} diff --git a/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/WitchsHousePlugin.java b/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/WitchsHousePlugin.java new file mode 100644 index 0000000..5e8ccb1 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/taverley/quest/witchshouse/WitchsHousePlugin.java @@ -0,0 +1,255 @@ +package content.region.asgarnia.taverley.quest.witchshouse; + +import core.cache.def.impl.ItemDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.game.global.action.DoorActionHandler; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.OptionHandler; +import core.game.interaction.UseWithHandler; +import core.game.node.Node; +import core.game.node.entity.combat.ImpactHandler; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.plugin.ClassScanner; +import core.tools.RandomFunction; +import content.data.Quests; + +/** + * Created for 2009Scape + * User: Ethan Kyle Millard + * Date: March 15, 2020 + * Time: 9:54 AM + */ +@Initializable +public class WitchsHousePlugin extends OptionHandler { + + private static final Item LEATHER_GLOVES = new Item(1059); + public static final Item KEY = new Item(2411); + public static final Item DOOR_KEY = new Item(2409); + private static final Item MAGNET = new Item(2410); + public static final Item BALL = new Item(2407); + private static final Item CHEESE = new Item(1985); + + // private WitchsExperimentNPC experiment; + + @Override + public boolean handle(Player player, Node node, String option) { + final Quest quest = player.getQuestRepository().getQuest(Quests.WITCHS_HOUSE); + final int id = node instanceof Item ? ((Item) node).getId() : node instanceof Scenery ? ((Scenery) node).getId() : node instanceof NPC ? ((NPC) node).getId() : node.getId(); + // boolean killedExperiment = player.getAttribute("witchs_house:experiment_killed",false); + // boolean experimentAlive = !player.getAttribute("witchs_house:experiment_killed", false); + boolean readBook = player.getAttribute("readWitchsBook", false); + boolean magnetAttached = player.getAttribute("attached_magnet", false); + switch (id) { + case 897: + case 898: + case 899: + case 900: + player.debug("Option is: " + option); + if (option.equals("attack")) { + player.getProperties().getCombatPulse().attack(node); + } + break; + case 24692: + int[] items = {1733, 1059, 1061, 1965, 1734}; + for (int item : items) { + if (!player.getInventory().containsItem(new Item(item))) { + switch (item) { + case 1733: + player.getInventory().add(new Item(item)); + player.sendMessage("You find a sewing needle in the bottom of one of the boxes!"); + return true; + case 1734: + player.getInventory().add(new Item(item)); + player.sendMessage("You find some sewing thread in the bottom of one of the boxes!"); + return true; + case 1059: + player.getInventory().add(new Item(item)); + player.sendMessage("You find a pair of leather gloves in the bottom of one of the boxes!"); + return true; + case 1061: + player.getInventory().add(new Item(item)); + player.sendMessage("You find a pair of leather boots in the bottom of one of the boxes!"); + return true; + case 1965: + player.getInventory().add(new Item(item)); + player.sendMessage("You find an old cabbage in the bottom of one of the boxes!"); + return true; + + } + } + } + player.sendMessage("You find nothing interesting in the boxes."); + break; + case 2869: + if (player.getInventory().addIfDoesntHave(MAGNET)) { + player.getDialogueInterpreter().sendDialogue("You find a magnet in the cupboard."); + } else { + player.sendMessage("You search the cupboard but find nothing interesting."); + } + break; + case 2867: + if (player.getInventory().addIfDoesntHave(DOOR_KEY)) { + player.getDialogueInterpreter().sendDialogue("You find a key hidden under the flower pot."); + } else { + player.sendMessage("You search under the flower pot and find nothing."); + } + break; + case 2861: + if (quest.isCompleted(player)) { + player.sendMessage("The lock has seemed to changed since the last time you visited."); + break; + } + if (player.getInventory().containsItem(DOOR_KEY) || player.getLocation().getX() >= 2901) { + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + } else { + player.sendMessage("The door is locked."); + } + break; + case 2862: + if (magnetAttached || player.getLocation().getY() < 3466) { + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + player.removeAttribute("attached_magnet"); + } else { + player.getDialogueInterpreter().sendDialogue("Strange... I can't see any kind of lock or handle to open this door."); + } + break; + case 2865: + case 2866: + if (player.getEquipment().containsItem(LEATHER_GLOVES)) { + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + } else { + player.getImpactHandler().manualHit(player, RandomFunction.random(2, 3), ImpactHandler.HitsplatType.NORMAL); + player.getDialogueInterpreter().sendDialogue("As your bare hands touch the gate you feel a shock."); + } + break; + case 24721: + player.sendMessage("You decide to not attract the attention of the witch by playing the piano."); + break; + case 2863: + if (player.getLocation().getX() >= 2934) { + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + return true; + } + if (player.getInventory().containsItem(KEY)) { + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + } else { + player.sendMessage("The door is locked."); + } + break; + case 2864: + player.debug(readBook + ""); + if (readBook && player.getInventory().addIfDoesntHave(KEY)) { + player.getDialogueInterpreter().sendDialogue("You search for the secret compartment mentioned in the diary.", "Inside it you find a small key. You take the key."); + } else { + player.sendMessage("You search the fountain but find nothing."); + } + break; + case 24724: + player.sendMessage("The gramophone doesn't have a record on it."); + break; + case 24672: + player.teleport(Location.create(2906, 3472, 1)); + break; + case 24673: + player.teleport(Location.create(2906, 3468, 0)); + break; + } + return true; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ClassScanner.definePlugin(new WitchsHouseUseWithHandler()); + ClassScanner.definePlugin(new MouseNPC()); + SceneryDefinition.forId(2867).getHandlers().put("option:look-under", this); + SceneryDefinition.forId(2861).getHandlers().put("option:open", this); + SceneryDefinition.forId(2865).getHandlers().put("option:open", this); + SceneryDefinition.forId(2866).getHandlers().put("option:open", this); + SceneryDefinition.forId(2862).getHandlers().put("option:open", this); + SceneryDefinition.forId(24724).getHandlers().put("option:wind-up", this); + SceneryDefinition.forId(24673).getHandlers().put("option:walk-down", this); + SceneryDefinition.forId(24672).getHandlers().put("option:walk-up", this); + SceneryDefinition.forId(24721).getHandlers().put("option:play", this); + SceneryDefinition.forId(24692).getHandlers().put("option:search", this); + SceneryDefinition.forId(2869).getHandlers().put("option:search", this); + SceneryDefinition.forId(2863).getHandlers().put("option:open", this); + SceneryDefinition.forId(2864).getHandlers().put("option:check", this); + ItemDefinition.forId(2408).getHandlers().put("option:read", this); + + return this; + } + + private void startFight(final Player player) { + player.setAttribute("experimentAlive", true); + player.getSavedData().getQuestData().setWitchsExperimentKilled(false); + //ExperimentSession.create(player).start(); + } + + public static class WitchsHouseUseWithHandler extends UseWithHandler { + + private WitchsHouseUseWithHandler() { + super(CHEESE.getId()); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(15518, OBJECT_TYPE, this); + UseWithHandler.addHandler(901, UseWithHandler.NPC_TYPE, new UseWithHandler(2410) { + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(901, UseWithHandler.NPC_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + Player player = event.getPlayer(); + Item useditem = event.getUsedItem(); + final NPC npc = (NPC) event.getUsedWith(); + assert useditem != null; + assert npc != null; + if (useditem.getId() == MAGNET.getId() && npc.getId() == 901 && player.getAttribute("mouse_out") != null) { + player.getDialogueInterpreter().sendDialogue("You attach a magnet to the mouse's harness."); + player.removeAttribute("mouse_out"); + if (player.getInventory().remove(MAGNET)) + player.setAttribute("attached_magnet", true); + + } + return true; + } + }); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + Player player = event.getPlayer(); + Item useditem = event.getUsedItem(); + final Scenery object = (Scenery) event.getUsedWith(); + assert useditem != null; + assert object != null; + if (player.getAttribute("mouse_out") != null && useditem.getId() == CHEESE.getId() && object.getId() == 15518) { + player.getDialogueInterpreter().sendDialogue("You can't do this right now."); + } + if (useditem.getId() == CHEESE.getId() && object.getId() == 15518 && player.getAttribute("mouse_out") == null) { + if (player.getInventory().remove(CHEESE)) + player.getDialogueInterpreter().sendDialogue("A mouse runs out of the hole."); + MouseNPC mouse = (MouseNPC) MouseNPC.create(901, Location.create(2903, 3466, 0)); + mouse.setPlayer(player); + mouse.setRespawn(false); + mouse.setWalks(false); + mouse.init(); + mouse.faceLocation(Location.create(2903, 3465, 0)); + player.setAttribute("mouse_out", true); + } + return true; + } + } +} diff --git a/Server/src/main/content/region/asgarnia/trollheim/dialogue/GWDKnightDialogue.java b/Server/src/main/content/region/asgarnia/trollheim/dialogue/GWDKnightDialogue.java new file mode 100644 index 0000000..750447d --- /dev/null +++ b/Server/src/main/content/region/asgarnia/trollheim/dialogue/GWDKnightDialogue.java @@ -0,0 +1,117 @@ +package content.region.asgarnia.trollheim.dialogue; + +import core.cache.def.impl.NPCDefinition; +import core.game.dialogue.DialoguePlugin; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.plugin.Plugin; + +import static core.api.ContentAPIKt.*; + +/** + * Handles the dying knight dialogue. + * @author Emperor + * @version 1.0 + */ +@Initializable +public final class GWDKnightDialogue extends DialoguePlugin { + + /** + * Represents the scroll item. + */ + private static final Item SCROLL = new Item(11734); + + /** + * Constructs a new {@code GWDKnightDialogue} {@code Object}. + */ + public GWDKnightDialogue() { + NPCDefinition.forId(6201).getHandlers().put("option:talk-to", new OptionHandler() { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + NPC npc = (NPC) node; + return player.getDialogueInterpreter().open(6201, npc); + } + + @Override + public Location getDestination(Node n, Node node) { + return node.getLocation().transform(0, -1, 0); + } + }); + } + + /** + * Constructs a new {@code GWDKnightDialogue} {@code Object}. + * @param player the player. + */ + public GWDKnightDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new GWDKnightDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + if ((getVarp(player, 1048) & 16) != 0) { + player.getPacketDispatch().sendMessage("The knight has already died."); + return false; + } + player("Who are you? What are you doing here in the snow?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + npc("My name is...Sir Gerry. I am...a member of a", "secret...society of knights. My time is short and I", "need...your help."); + stage = 1; + break; + case 1: + player("A secret society of knights? What a surprise! Is there", "an old charter or decree that says if you're a knight", "you have to belong to a secret order?"); + stage = 2; + break; + case 2: + npc("I'm sorry, my friend... I do not understand your", "meaning. Please, time is short... Take this scroll to Sir", "Tiffy. You will find him in Falador park... You should", "not...read it... It contains information for his eyes only."); + stage = 3; + break; + case 3: + if (player.getInventory().add(SCROLL)) { + interpreter.sendItemMessage(11734, "The knight hands you a scroll."); + setVarbit(player, 3936, 1, true); + stage = 5; + } else { + stage = 4; + } + break; + case 4: + interpreter.sendDialogue("The knight tries to give you something, but your inventory is full."); + stage = 5; + break; + case 5: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 6202 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/trollheim/dialogue/KnightsNotes.kt b/Server/src/main/content/region/asgarnia/trollheim/dialogue/KnightsNotes.kt new file mode 100644 index 0000000..7d267cb --- /dev/null +++ b/Server/src/main/content/region/asgarnia/trollheim/dialogue/KnightsNotes.kt @@ -0,0 +1,55 @@ +package content.region.asgarnia.trollheim.dialogue + +import content.global.handlers.iface.ScrollInterface +import content.global.handlers.iface.ScrollLine +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import org.rs09.consts.Items +import org.rs09.consts.Components + +/** + * @author szu + */ +class KnightsNotes : InteractionListener { + companion object { + val CONTENTS = arrayOf( + ScrollLine("My friend, you were right to send me to investigate the",3), + ScrollLine("dwarf's drunken claims, for I have discovered a treasure",4), + ScrollLine("beyond our wildest dreams. The aviantese are alive, and I",5), + ScrollLine("suspect they still guard the godsword! Beneath the remnants",6), + ScrollLine("of the temple a great battle is being fought between followers",7), + ScrollLine("of Bandos, Armadyl, Saradomin and Zamorak. My command was",8), + ScrollLine("slaughtered and I am grieviously wounded. YOU MUST PREVENT",9), + ScrollLine("THE GODSWORD FROM FALLING INTO THE WRONG HANDS! I do not",10), + ScrollLine("know how I am going to get this message to you, why is that",11), + ScrollLine("talking skull never around when he's needed? Your comrade,",12), + ScrollLine("Sir Gerry.",13), + ) + } + + override fun defineListeners() { + // The scroll has not been opened. This will lead to a different dialogue with Sir Tiffy Cashien. + on(Items.KNIGHTS_NOTES_11734, IntType.ITEM, "read") { player, _ -> + sendDialogueOptions(player, "The scroll is sealed. Do you still want to open it?", "Yes", "No") + player!!.packetDispatch.sendInterfaceConfig(228, 6, true) + player!!.packetDispatch.sendInterfaceConfig(228, 9, false) // childId 7 is left 8 is right + addDialogueAction(player) { player, button -> + if (button == 2) { + sendMessage(player, "You break the wax seal and open the scroll.") + if (removeItem(player, Items.KNIGHTS_NOTES_11734)) { + addItem(player, Items.KNIGHTS_NOTES_11735) + ScrollInterface.scrollSetup(player, Components.MESSAGESCROLL_220, CONTENTS) + } + } + return@addDialogueAction + } + return@on true + } + // The scroll has been read. This will lead to a different dialogue with Sir Tiffy Cashien. + on(Items.KNIGHTS_NOTES_11735, IntType.ITEM, "read") { player, _ -> + ScrollInterface.scrollSetup(player, Components.MESSAGESCROLL_220, CONTENTS) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/trollheim/dialogue/SabaDialogue.kt b/Server/src/main/content/region/asgarnia/trollheim/dialogue/SabaDialogue.kt new file mode 100644 index 0000000..9eb7daf --- /dev/null +++ b/Server/src/main/content/region/asgarnia/trollheim/dialogue/SabaDialogue.kt @@ -0,0 +1,42 @@ +package content.region.asgarnia.trollheim.dialogue + +import content.data.Quests +import content.region.asgarnia.burthorpe.quest.deathplateau.SabaDialogueFile +import core.api.getQuestStage +import core.api.openDialogue +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +/** + * Represents the dialogue plugin used for the tenzing npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +class SabaDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + if (getQuestStage(player!!, Quests.DEATH_PLATEAU) >= 19) { + openDialogue(player!!, SabaDialogueFile(), npc) + return true + } + // Fallback to default. + when (stage) { + START_DIALOGUE -> playerl(FacialExpression.HALF_GUILTY, "Hi!").also { stage++ } + 1 -> npcl(FacialExpression.ANNOYED, "Why won't people leave me alone?!").also { stage = END_DIALOGUE } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return SabaDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.SABA_1070) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/trollheim/dialogue/TenzingDialogue.kt b/Server/src/main/content/region/asgarnia/trollheim/dialogue/TenzingDialogue.kt new file mode 100644 index 0000000..2101a9b --- /dev/null +++ b/Server/src/main/content/region/asgarnia/trollheim/dialogue/TenzingDialogue.kt @@ -0,0 +1,73 @@ +package content.region.asgarnia.trollheim.dialogue + +import content.data.Quests +import content.region.asgarnia.burthorpe.quest.deathplateau.TenzingDialogueFile +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +/** + * Represents the dialogue plugin used for the tenzing npc. + * @author 'Vexia + * @author ovenbread + */ +@Initializable +class TenzingDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + if (isQuestInProgress(player!!, Quests.DEATH_PLATEAU, 20, 29)) { + openDialogue(player!!, TenzingDialogueFile(), npc) + return true + } + // Fallback to default. + when (stage) { + 0 -> player(FacialExpression.FRIENDLY, "Hello Tenzing!").also { stage++ } + 1 -> npc(FacialExpression.FRIENDLY,"Hello traveler. What can I do for you?").also{ stage++ } + 2 -> showTopics( + Topic(FacialExpression.FRIENDLY, "Can I buy some Climbing boots?", 10), + Topic(FacialExpression.FRIENDLY, "What does a Sherpa do?", 20), + Topic(FacialExpression.FRIENDLY, "How did you find out about the secret way?", 30), + Topic(FacialExpression.FRIENDLY, "Nice place you have here.", 40), + Topic(FacialExpression.FRIENDLY, "Nothing, thanks!", END_DIALOGUE) + ) + 10 -> npc("Sure, I'll sell you some in your size for 12 gold.").also{ stage++ } + 11 -> showTopics( + Topic(FacialExpression.FRIENDLY, "OK, sounds good.", 12), + Topic(FacialExpression.FRIENDLY, "No, thanks.", END_DIALOGUE), + ) + 12 -> { + if (!player.inventory.hasSpaceFor(Item(Items.CLIMBING_BOOTS_3105))) { + player("I don't have enough space in my backpack right this second.").also{ stage = END_DIALOGUE } + } + if (!inInventory(player, Items.COINS_995)) { + player("I don't have enough coins right now.").also{ stage = END_DIALOGUE } + } + if (removeItem(player!!, Item(Items.COINS_995, 12))) { + player("I don't have enough coins right now.").also{ stage = END_DIALOGUE } + } + addItemOrDrop(player, Items.CLIMBING_BOOTS_3105, 1) + sendItemDialogue(player, Items.CLIMBING_BOOTS_3105, "Tenzing has given you some Climbing boots.").also { stage = END_DIALOGUE } + sendMessage(player, "Tenzing has given you some Climbing boots.") + } + + 20 -> npcl(FacialExpression.FRIENDLY, "We are expert guides that take adventurers such as yourself, on mountaineering expeditions.").also { stage = END_DIALOGUE } + 30 -> npcl(FacialExpression.FRIENDLY, "I used to take adventurers up Death Plateau and further north before the trolls came. I know these mountains well.").also { stage = END_DIALOGUE } + 40 -> npcl(FacialExpression.FRIENDLY, "Thanks, I built it myself! I'm usually self sufficient but I can't earn any money with the trolls camped on Death Plateau,").also { stage = END_DIALOGUE } + } + return true + } + + override fun newInstance(player: Player): DialoguePlugin { + return TenzingDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.TENZING_1071) + } +} diff --git a/Server/src/main/content/region/asgarnia/trollheim/handlers/ThrowerTrollNPC.java b/Server/src/main/content/region/asgarnia/trollheim/handlers/ThrowerTrollNPC.java new file mode 100644 index 0000000..e8fbf56 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/trollheim/handlers/ThrowerTrollNPC.java @@ -0,0 +1,74 @@ +package content.region.asgarnia.trollheim.handlers; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.DeathTask; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.npc.agg.AggressiveBehavior; +import core.game.node.entity.npc.agg.AggressiveHandler; +import core.plugin.Initializable; +import core.game.world.map.Location; + +/** + * Handles a Thrower troll NPC. + * @author Emperor + */ +@Initializable +public final class ThrowerTrollNPC extends AbstractNPC { + + /** + * Constructs a new {@code ThrowerTrollNPC} {@code Object}. + */ + public ThrowerTrollNPC() { + super(1130, null); + } + + /** + * Constructs a new {@code ThrowerTrollNPC} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + public ThrowerTrollNPC(int id, Location location) { + super(id, location, true); + } + + @Override + public void setDefaultBehavior() { + super.setAggressive(true); + super.setAggressiveHandler(new AggressiveHandler(this, new AggressiveBehavior() { + + @Override + public boolean canSelectTarget(Entity entity, Entity target) { + if (!target.isActive() || DeathTask.isDead(target)) { + return false; + } + if (!target.getProperties().isMultiZone() && target.inCombat()) { + return false; + } + return true; + } + })); + getAggressiveHandler().setChanceRatio(8); + getAggressiveHandler().setRadius(7); + getDefinition().setCombatDistance(7); + super.setWalks(false); + super.getLocks().lockMovement(1 << 25); + } + + @Override + public void init() { + super.init(); + getProperties().getCombatPulse().setStyle(CombatStyle.RANGE); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new ThrowerTrollNPC(id, location); + } + + @Override + public int[] getIds() { + return new int[] { 1101, 1102, 1103, 1104, 1105, 1130, 1131, 1132, 1133, 1134 }; + } + +} diff --git a/Server/src/main/content/region/asgarnia/trollheim/handlers/TrollheimPlugin.java b/Server/src/main/content/region/asgarnia/trollheim/handlers/TrollheimPlugin.java new file mode 100644 index 0000000..b620097 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/trollheim/handlers/TrollheimPlugin.java @@ -0,0 +1,683 @@ +package content.region.asgarnia.trollheim.handlers; + +import core.cache.def.impl.NPCDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.game.component.Component; +import core.game.activity.ActivityManager; +import core.game.activity.ActivityPlugin; +import core.game.activity.CutscenePlugin; +import core.game.dialogue.DialoguePlugin; +import core.game.global.action.ClimbActionHandler; +import core.game.global.action.DoorActionHandler; +import core.game.node.entity.skill.Skills; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneBuilder; +import core.game.world.repository.Repository; +import core.game.world.update.flag.context.Animation; +import core.net.packet.PacketRepository; +import core.net.packet.context.CameraContext; +import core.net.packet.context.CameraContext.CameraType; +import core.net.packet.out.CameraViewPacket; +import core.plugin.Plugin; +import core.plugin.Initializable; +import core.plugin.ClassScanner; + +/** + * Represents the plugin used to handle all trollheim node interations. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class TrollheimPlugin extends OptionHandler { + + /** + * Represents the locations to use. + */ + private static final Location[] LOCATIONS = new Location[] { new Location(2269, 4752, 0), new Location(2858, 3577, 0), Location.create(2808, 10002, 0), Location.create(2796, 3615, 0), Location.create(2907, 10019, 0), Location.create(2904, 3643, 0), new Location(2908, 3654, 0), Location.create(2907, 10035, 0), new Location(2893, 10074, 0), new Location(2893, 3671, 0) }; + + /** + * Represents the climbing boots item. + */ + private static final Item CLIMBING_BOOTS = new Item(3105); + + /** + * Represents the climb down animation. + */ + private static final Animation CLIMB_DOWN = new Animation(1148); + + /** + * Represents the climb up animation. + */ + private static final Animation CLIMB_UP = new Animation(740); + + /** + * Represents the climb fail animation. + */ + public static final Animation CLIMB_FAIL = new Animation(739); + + /** + * Represents the low jumpa nimation. + */ + private static final Animation JUMP = new Animation(839); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(3735).getHandlers().put("option:enter", this); + SceneryDefinition.forId(32738).getHandlers().put("option:exit", this); + NPCDefinition.forId(1069).getHandlers().put("option:talk-to", this); + SceneryDefinition.forId(3742).getHandlers().put("option:read", this); + SceneryDefinition.forId(3774).getHandlers().put("option:leave", this); + SceneryDefinition.forId(3723).getHandlers().put("option:climb", this);// located + // in + // circle + // area. + SceneryDefinition.forId(3722).getHandlers().put("option:climb", this);// located + // in + // circle + // area. + SceneryDefinition.forId(3748).getHandlers().put("option:climb", this); + SceneryDefinition.forId(3790).getHandlers().put("option:climb", this);// pos=Location.create(2858, + // 3627, + // 0) + SceneryDefinition.forId(3791).getHandlers().put("option:climb", this);// pos=Location.create(2858, + // 3627, + // 0) + SceneryDefinition.forId(3782).getHandlers().put("option:open", this);// arena + // entrance + SceneryDefinition.forId(3783).getHandlers().put("option:open", this);// arena + // entrance + SceneryDefinition.forId(3762).getHandlers().put("option:open", this);// secret + // door. + SceneryDefinition.forId(4499).getHandlers().put("option:enter", this);// entrance + // near + // golden + // apple. + SceneryDefinition.forId(4500).getHandlers().put("option:enter", this);// entrance + // near + // golden + // apple. + SceneryDefinition.forId(9303).getHandlers().put("option:climb", this);// lvl + // 41. + SceneryDefinition.forId(3782).getHandlers().put("option:open", this);// arena + // entrance. + SceneryDefinition.forId(3783).getHandlers().put("option:open", this);// arena + // entrance. + SceneryDefinition.forId(3785).getHandlers().put("option:open", this);// arena + // exit. + SceneryDefinition.forId(3786).getHandlers().put("option:open", this);// arena + // exit. + SceneryDefinition.forId(3757).getHandlers().put("option:enter", this);// arena + // cave + // entrance. + SceneryDefinition.forId(3758).getHandlers().put("option:exit", this);// arena + // cave + // exit. + SceneryDefinition.forId(9327).getHandlers().put("option:climb", this);// lvl + // 64 + SceneryDefinition.forId(9304).getHandlers().put("option:climb", this); + ;// lvl + // 43 + SceneryDefinition.forId(3803).getHandlers().put("option:climb", this); + ;// lvl + // 43 + // near + // trollheim + // top. + SceneryDefinition.forId(3804).getHandlers().put("option:climb", this); + ;// lvl + // 43 + // near + // trollheim + // top. + SceneryDefinition.forId(9306).getHandlers().put("option:climb", this);// lvl + // 47 + SceneryDefinition.forId(9305).getHandlers().put("option:climb", this);// lvl + // 44 + SceneryDefinition.forId(3759).getHandlers().put("option:enter", this);// top + // cave. + SceneryDefinition.forId(3771).getHandlers().put("option:enter", this);// stronghold + // to + // herb + // patch + SceneryDefinition.forId(18834).getHandlers().put("option:climb-up", this);// stronghold + // ladder + SceneryDefinition.forId(18833).getHandlers().put("option:climb-down", this);// stronghold + // ladder + ClassScanner.definePlugin(new WoundedSoldier()); + ClassScanner.definePlugin(new WarningZone()); + ActivityManager.register(new WarningCutscene()); + ClassScanner.definePlugin(new TrollNPC()); + return this; + } + + @Override + public boolean handle(final Player player, Node node, String option) { + final int id = node instanceof Scenery ? ((Scenery) node).getId() : ((NPC) node).getId(); + final Location loc = node.getLocation(); + int xOffset = 0, yOffset = 0; + Direction direction = Direction.SOUTH; + switch (option) { + case "enter": + switch (id) { + case 3735: + player.getProperties().setTeleportLocation(LOCATIONS[0]); + break; + case 4499: + player.getProperties().setTeleportLocation(LOCATIONS[2]); + break; + case 4500: + player.getProperties().setTeleportLocation(LOCATIONS[3]); + break; + case 3723: + player.getProperties().setTeleportLocation(LOCATIONS[4]); + break; + case 3757: + player.getProperties().setTeleportLocation(loc.equals(new Location(2907, 3652, 0)) ? LOCATIONS[7] : LOCATIONS[4]); + break; + case 3759: + player.getProperties().setTeleportLocation(LOCATIONS[8]); + break; + case 3771: + player.teleport(new Location(2837, 10090, 2)); + break; + } + break; + case "leave": + player.teleport(new Location(2840, 3690)); + break; + case "exit": + switch (id) { + case 32738: + if (loc.equals(new Location(2892, 10072, 0))) { + player.getProperties().setTeleportLocation(LOCATIONS[0]); + return true; + } + player.teleport(LOCATIONS[1]); + break; + case 3758: + player.getProperties().setTeleportLocation(loc.equals(new Location(2906, 10036, 0)) ? LOCATIONS[6] : LOCATIONS[5]); + break; + } + break; + case "talk-to": + switch (id) { + case 1069: + player.getDialogueInterpreter().open(id, node); + break; + } + break; + case "read": + switch (id) { + case 3742: + ActivityManager.start(player, "trollheim-warning", false); + break; + } + break; + case "open": + switch (id) { + case 3785:// exit + case 3786:// exit + case 3782:// entrance + case 3783:// entrance. + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + return true; + case 3672: + player.getPacketDispatch().sendMessage("You don't know how to open the secret door."); + break; + } + break; + case "climb-up": + switch (id) { + case 18834: + ClimbActionHandler.climb(player, ClimbActionHandler.CLIMB_UP, new Location(2828, 3678), "You clamber onto the windswept roof of the Troll Stronghold."); + break; + } + break; + case "climb-down": + switch (id) { + case 18833: + ClimbActionHandler.climb(player, ClimbActionHandler.CLIMB_DOWN, new Location(2831, 10076, 2), "You clamber back inside the Troll Stronghold."); + break; + } + break; + case "climb": + if (!player.getEquipment().containsItem(CLIMBING_BOOTS)) { + player.getPacketDispatch().sendMessage("You need Climbing boots to negotiate these rocks."); + return true; + } + final Scenery object = ((Scenery) node); + switch (id) { + case 3723: + bandaid(player, player.getLocation(), object.getLocation().transform(0, 2, 0), CLIMB_UP); + break; + case 3722: + bandaid(player, player.getLocation(), object.getLocation().transform(0, -3, 0), CLIMB_DOWN, CLIMB_DOWN, object.getDirection()); + break; + case 3790:// rock scalling. + case 3791: + xOffset = player.getLocation().getX() < loc.getX() ? 2 : -2; + //bandaid(player, player.getLocation(), object.getLocation().transform(xOffset, yOffset, 0), CLIMB_DOWN, CLIMB_DOWN, direction); + player.getProperties().setTeleportLocation(object.getLocation().transform(xOffset, yOffset, 0)); + break; + //bandaid(player, player.getLocation(), object.getLocation().transform(xOffset, yOffset, 0), CLIMB_UP); + case 3748: + player.getPacketDispatch().sendMessage("You climb onto the rock..."); + if (loc.equals(new Location(2821, 3635, 0))) { + bandaid(player, player.getLocation(), loc.transform(player.getLocation().getX() > loc.getX() ? -1 : 1, 0, 0), JUMP); + } else if (loc.equals(new Location(2910, 3687, 0)) || loc.equals(new Location(2910, 3686, 0))) { + if (player.getSkills().getLevel(Skills.AGILITY) < 43) { + player.getPacketDispatch().sendMessage("You need an Agility level of 43 in order to climb this mountain side."); + return true; + } + if (player.getLocation().equals(Location.create(2911, 3687, 0))) { + bandaid(player, player.getLocation(), Location.create(2909, 3687, 0), JUMP); + } else if (player.getLocation().equals(new Location(2909, 3687, 0))) { + bandaid(player, player.getLocation(), Location.create(2911, 3687, 0), JUMP); + } else if (player.getLocation().equals(Location.create(2911, 3686, 0))) { + bandaid(player, player.getLocation(), Location.create(2909, 3686, 0), JUMP); + } else { + bandaid(player, player.getLocation(), Location.create(2911, 3686, 0), JUMP); + } + } else if (loc.equals(new Location(2857, 3612, 0)) || loc.equals(new Location(2856, 3612, 0))) { + if (player.getSkills().getLevel(Skills.AGILITY) < 15) { + player.getPacketDispatch().sendMessage("You need an Agility level of 15 in order to climb this rock."); + return true; + } + bandaid(player, player.getLocation(), player.getLocation().getY() < object.getLocation().getY() ? player.getLocation().transform(0, 2, 0) : player.getLocation().transform(0, -2, 0), JUMP); + } else { + bandaid(player, player.getLocation(), player.getLocation().getY() < object.getLocation().getY() ? player.getLocation().transform(0, 2, 0) : player.getLocation().transform(0, -2, 0), JUMP); + } + player.getPacketDispatch().sendMessage("...and step down the other side."); + break; + case 3803: + case 3804: + if (player.getSkills().getLevel(Skills.AGILITY) < 43) { + player.getPacketDispatch().sendMessage("You need an Agility level of 43 in order to climb this mountain side."); + return true; + } + if (player.getLocation().equals(Location.create(2884, 3684, 0))) { + bandaid(player, player.getLocation(), Location.create(2886, 3684, 0), CLIMB_UP); + } else if (player.getLocation().equals(Location.create(2884, 3683, 0))) { + bandaid(player, player.getLocation(), Location.create(2886, 3683, 0), CLIMB_UP); + } else if (player.getLocation().equals(Location.create(2886, 3683, 0))) { + bandaid(player, player.getLocation(), Location.create(2884, 3683, 0), CLIMB_DOWN, CLIMB_DOWN, Direction.EAST); + } else if (player.getLocation().equals(Location.create(2888, 3660, 0)) || player.getLocation().equals(Location.create(2887, 3660, 0))) { + bandaid(player, player.getLocation(), player.getLocation().transform(0, 2, 0), CLIMB_UP); + } else if (player.getLocation().equals(Location.create(2888, 3662, 0)) || player.getLocation().equals(Location.create(2887, 3662, 0))) { + bandaid(player, player.getLocation(), player.getLocation().transform(0, -2, 0), CLIMB_DOWN, CLIMB_DOWN, Direction.NORTH); + } else { + bandaid(player, player.getLocation(), Location.create(2884, 3684, 0), CLIMB_DOWN, CLIMB_DOWN, Direction.EAST); + } + break; + case 9306: + if (player.getSkills().getLevel(Skills.AGILITY) < 47) { + player.getPacketDispatch().sendMessage("You need an Agility level of 47 in order to climb this mountain side."); + return true; + } + if (player.getLocation().equals(Location.create(2903, 3680, 0))) { + bandaid(player, player.getLocation(), Location.create(2900, 3680, 0), CLIMB_UP); + } else { + bandaid(player, player.getLocation(), Location.create(2903, 3680, 0), CLIMB_DOWN, CLIMB_DOWN, Direction.WEST); + } + break; + case 9303: + if (player.getSkills().getLevel(Skills.AGILITY) < 41) { + player.getPacketDispatch().sendMessage("You need an Agility level of 41 in order to climb this mountain side."); + return true; + } + if (player.getLocation().getX() > loc.getX()) { + bandaid(player, player.getLocation(), object.getLocation().transform(-2, 0, 0), CLIMB_DOWN, CLIMB_DOWN, Direction.EAST); + } else { + bandaid(player, player.getLocation(), object.getLocation().transform(2, 0, 0), CLIMB_UP); + } + break; + case 9304: + if (player.getSkills().getLevel(Skills.AGILITY) < 47) { + player.getPacketDispatch().sendMessage("You need an Agility level of 47 in order to climb this mountain side."); + return true; + } + if (player.getLocation().equals(Location.create(2878, 3665, 0))) { + bandaid(player, player.getLocation(), new Location(2878, 3668, 0), CLIMB_UP); + } else { + bandaid(player, player.getLocation(), new Location(2878, 3665, 0), CLIMB_DOWN, CLIMB_DOWN, Direction.NORTH); + } + break; + case 9305: + if (player.getSkills().getLevel(Skills.AGILITY) < 44) { + player.getPacketDispatch().sendMessage("You need an Agility level of 44 in order to climb this mountain side."); + return true; + } + if (player.getLocation().equals(new Location(2909, 3684, 0))) { + bandaid(player, player.getLocation(), Location.create(2907, 3682, 0), CLIMB_UP, CLIMB_UP, Direction.SOUTH); + } else { + bandaid(player, player.getLocation(), Location.create(2909, 3684, 0), CLIMB_DOWN, CLIMB_DOWN, Direction.SOUTH); + + } + break; + case 9327: + if (player.getSkills().getLevel(Skills.AGILITY) < 64) { + player.getPacketDispatch().sendMessage("You need an Agility level of 64 in order to climb this mountain side."); + return true; + } + if (object.getLocation().equals(new Location(2916, 3672, 0))) { + bandaid(player, player.getLocation(), Location.create(2918, 3672, 0), CLIMB_UP); + } else if (object.getLocation().equals(new Location(2917, 3672, 0))) { + bandaid(player, player.getLocation(), Location.create(2915, 3672, 0), CLIMB_DOWN, CLIMB_DOWN, Direction.EAST); + } else if (object.getLocation().equals(new Location(2923, 3673, 0))) { + bandaid(player, player.getLocation(), Location.create(2921, 3672, 0), CLIMB_UP); + } else if (object.getLocation().equals(new Location(2922, 3672, 0))) { + bandaid(player, player.getLocation(), Location.create(2924, 3673, 0), CLIMB_DOWN, CLIMB_DOWN, Direction.WEST); + } + break; + } + break; + } + return true; + } + + public void bandaid(Player player, Location l, Location e, Animation a){ + player.getProperties().setTeleportLocation(e); + } + + public void bandaid(Player player, Location l, Location e, Animation a, Animation b, Direction d){ + player.getProperties().setTeleportLocation(e); + } + + @Override + public Location getDestination(Node node, Node n) { + if (n instanceof Scenery) { + final Scenery object = ((Scenery) n); + if (object.getId() == 3782) { + if (node.getLocation().getX() >= 2897) { + return Location.create(2897, 3618, 0); + } + } else if (object.getId() == 3804) { + if (object.getLocation().equals(new Location(2885, 3684, 0)) && node.getLocation().getX() >= 2885) { + return object.getLocation().transform(1, 0, 0); + } + } else if (object.getId() == 9306 && node.getLocation().getX() >= 2902) { + return Location.create(2903, 3680, 0); + } + } + return null; + } + + /** + * Gets the opposite direction. + * @param dir the dir. + * @return the opposite direction. + */ + private Direction getOpposite(Direction dir) { + switch (dir) { + case EAST: + return Direction.WEST; + case NORTH: + return Direction.SOUTH; + case SOUTH: + return Direction.NORTH; + case WEST: + return Direction.EAST; + default: + break; + } + return null; + } + + /** + * Represents the wounded soldiers dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ + public final class WoundedSoldier extends DialoguePlugin { + + /** + * Constructs a new {@code WoundedSoldier} {@code Object}. + */ + public WoundedSoldier() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code TrolleimPlugin} {@code Object}. + * @param player the player. + */ + public WoundedSoldier(final Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new WoundedSoldier(player); + } + + @Override + public boolean open(Object... args) { + player("Are you OK?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + npc("Urrrgggh....."); + stage = 1; + break; + case 1: + npc("I'll be OK, the trolls only leave the plateau at nightfall.", "The guys are bringing a stretcher shortly."); + stage = 2; + break; + case 2: + player("As long as you're sure."); + stage = 3; + break; + case 3: + npc("It's my own fault really, I was having a walk and", "wandered past the danger sign. The trolls throw rocks", "down at any one who goes up the path!"); + stage = 4; + break; + case 4: + npc("Don't go up there!"); + stage = 5; + break; + case 5: + player("OK, thanks for the warning."); + stage = 6; + break; + case 6: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 1069 }; + } + + } + + /** + * Represents the warning map zone. + * @author 'Vexia + * @version 1.0 + */ + public static final class WarningZone extends MapZone implements Plugin { + + /** + * Represents the warning component interface, + */ + private static final Component COMPONENT = new Component(581); + + /** + * Constructs a new {@code WarningZone} {@code Object}. + */ + public WarningZone() { + super("trollheim-warning", true); + } + + @Override + public boolean enter(final Entity entity) { + if (entity instanceof Player) { + final Player p = (Player) entity; + if (p.getWalkingQueue().getFootPrint().getY() < 3592) { + p.getWalkingQueue().reset(); + p.getPulseManager().clear(); + p.getInterfaceManager().open(COMPONENT); + } + } + return super.enter(entity); + } + + @Override + public void configure() { + register(new ZoneBorders(2837, 3592, 2838, 3593)); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ZoneBuilder.configure(this); + return this; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + } + + /** + * Represents the warning cutscene plugin. + * @author 'Vexia + * @version 1.0 + */ + public static final class WarningCutscene extends CutscenePlugin { + + /** + * Represents the throwing animation. + */ + private static final Animation THROW = new Animation(1142); + + /** + * Represents the troll location. + */ + private static final Location TROLL_LOCATION = new Location(2851, 3598, 0); + + /** + * Constructs a new {@code WarningCutscene} {@code Object}. + */ + public WarningCutscene() { + super("trollheim-warning"); + } + + /** + * Constructs a new {@code WarningCutscene} {@code Object}. + * @param p the player. + */ + public WarningCutscene(Player p) { + super("trollheim-warning", false); + this.player = p; + } + + @Override + public ActivityPlugin newInstance(Player p) throws Throwable { + return new WarningCutscene(p); + } + + @Override + public void open() { + final NPC npc = Repository.findNPC(TROLL_LOCATION); + Location loc = Location.create(2849, 3597, 0); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.POSITION, loc.getX() - 2, loc.getY(), 1300, 1, 30)); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.ROTATION, loc.getX() + 22, loc.getY() + 10, 1300, 1, 30)); + GameWorld.getPulser().submit(new Pulse(1, player) { + int count = 0; + + @Override + public boolean pulse() { + switch (count++) { + case 4: + if (npc != null) { + npc.faceTemporary(player, 3); + npc.animate(THROW); + } + break; + case 6: + WarningCutscene.this.stop(false); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.RESET, 0, 0, 1300, 1, 30)); + return true; + } + return false; + } + }); + } + + @Override + public int getMapState() { + return 0; + } + + @Override + public Location getSpawnLocation() { + return null; + } + + @Override + public void configure() { + ActivityManager.register(this); + } + + } + + /** + * Represents the a trollheim troll. + * @author 'Vexia + * @version 1.0 + */ + public final class TrollNPC extends AbstractNPC { + + /** + * Constructs a new {@code TrollNPC} {@code Object}. + */ + public TrollNPC() { + super(0, null); + } + + /** + * Constructs a new {@code TrollNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + public TrollNPC(int id, Location location) { + super(id, location, true); + this.setAggressive(true); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new TrollNPC(id, location); + } + + @Override + public int[] getIds() { + return new int[] { 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1138 }; + } + + } +} diff --git a/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/EcumenicalKeyHandler.java b/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/EcumenicalKeyHandler.java new file mode 100644 index 0000000..0bf3e2c --- /dev/null +++ b/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/EcumenicalKeyHandler.java @@ -0,0 +1,70 @@ +/** + * https://oldschool.2009scape.wiki/w/Ecumenical_key + */ +//package core.game.content.activity.gwd; +// +//import core.game.content.global.action.DoorActionHandler; +//import core.game.interaction.NodeUsageEvent; +//import core.game.interaction.UseWithHandler; +//import core.game.node.entity.player.Player; +//import core.game.node.object.GameObject; +//import core.game.world.map.Direction; +//import core.plugin.InitializablePlugin; +//import core.plugin.Plugin; +// +///** +// * Handles the boss room instant-access key. +// * @author Splinter +// */ +//@InitializablePlugin +//public class EcumenicalKeyHandler extends UseWithHandler { +// +// /** +// * Constructs a new {@code EcumenicalKeyHandler} {@code Object} +// */ +// public EcumenicalKeyHandler() { +// super(14674); +// } +// +// @Override +// public Plugin newInstance(Object arg) throws Throwable { +// addHandler(26425, OBJECT_TYPE, this); +// addHandler(26426, OBJECT_TYPE, this); +// addHandler(26427, OBJECT_TYPE, this); +// addHandler(26428, OBJECT_TYPE, this); +// return this; +// } +// +// @Override +// public boolean handle(NodeUsageEvent event) { +// final Player player = event.getPlayer(); +// final GameObject object = event.getUsedWith().asObject(); +// Direction dir = Direction.get((object.getRotation() + 3) % 4); +// if (dir.getStepX() != 0) { +// if (player.getLocation().getX() == object.getLocation().transform(dir.getStepX(), 0, 0).getX()) { +// player.sendMessage("It would be unwise to use the key on this side of the door!"); +// return true; +// } +// } else if (player.getLocation().getY() == object.getLocation().transform(0, dir.getStepY(), 0).getY()) { +// player.sendMessage("It would be unwise to use the key on this side of the door!"); +// return true; +// } +// player.lock(2); +// player.getInventory().remove(event.getUsedItem()); +// player.sendMessage("The key shatters as you insert it into the lock."); +// DoorActionHandler.handleAutowalkDoor(player, event.getUsedWith().asObject()); +// return true; +// } +// +//} +/** + * Function to add key into player inventory + * Goes in GodwarsMapZone.java 'death' method + */ +// int count = killer.asPlayer().getBank().getAmount(14674) + killer.asPlayer().getInventory().getAmount(14674); +// int rand = RandomFunction.random(1, 60 + (count * 10)); +// if(rand == 15 && count < 3){ +// Item item = new Item(14674); +// GroundItemManager.create(item, e.getLocation(), ((Player) killer)); +// killer.asPlayer().sendMessage("A crystalline key falls to the ground as you slay your opponent."); +// } \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GWDGraardorSwingHandler.java b/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GWDGraardorSwingHandler.java new file mode 100644 index 0000000..540d48f --- /dev/null +++ b/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GWDGraardorSwingHandler.java @@ -0,0 +1,182 @@ +package content.region.asgarnia.trollheim.handlers.gwd; + +import java.util.ArrayList; +import java.util.List; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.node.entity.combat.InteractionType; +import core.game.node.entity.combat.equipment.ArmourSet; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.npc.NPC; +import core.game.world.map.RegionManager; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.update.flag.context.Animation; +import core.tools.RandomFunction; + +/** + * Handles General Graardor's combat. + * @author Emperor + */ +public final class GWDGraardorSwingHandler extends CombatSwingHandler { + + /** + * The boss chamber. + */ + private static final ZoneBorders CHAMBER = new ZoneBorders(2864, 5351, 2876, 5369); + + /** + * The melee attack animation. + */ + private static final Animation MELEE_ATTACK = new Animation(7060, Priority.HIGH); + + /** + * The range attack animation. + */ + private static final Animation RANGE_ATTACK = new Animation(7063, Priority.HIGH); + + /** + * Constructs a new {@code GWDGraardorSwingHandler} {@Code Object}. + */ + public GWDGraardorSwingHandler() { + super(CombatStyle.MELEE); + } + + @Override + public InteractionType canSwing(Entity entity, Entity victim) { + return CombatStyle.MELEE.getSwingHandler().canSwing(entity, victim); + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + int ticks = 1; + if (RandomFunction.randomize(10) < 7) { + int hit = 0; + if (CombatStyle.MELEE.getSwingHandler().isAccurateImpact(entity, victim, CombatStyle.MELEE)) { + int max = CombatStyle.MELEE.getSwingHandler().calculateHit(entity, victim, 1.0); + hit = RandomFunction.random(max); + state.setMaximumHit(max); + } + state.setEstimatedHit(hit); + state.setStyle(CombatStyle.MELEE); + } else { + ticks += (int) Math.ceil(entity.getLocation().getDistance(victim.getLocation()) * 0.3); + NPC npc = (NPC) entity; + List list = new ArrayList<>(20); + for (Entity t : RegionManager.getLocalPlayers(npc, 28)) { + if (!CHAMBER.insideBorder(t.getLocation())) { + continue; + } + if (t.isAttackable(npc, CombatStyle.RANGE, false)) { + list.add(new BattleState(entity, t)); + } + } + BattleState[] targets; + state.setStyle(CombatStyle.RANGE); + state.setTargets(targets = list.toArray(new BattleState[0])); + for (BattleState s : targets) { + s.setStyle(CombatStyle.RANGE); + int hit = 0; + if (CombatStyle.RANGE.getSwingHandler().isAccurateImpact(entity, s.getVictim(), CombatStyle.RANGE)) { + int max = CombatStyle.RANGE.getSwingHandler().calculateHit(entity, s.getVictim(), 1.0); + s.setMaximumHit(max); + hit = RandomFunction.random(max); + } + s.setEstimatedHit(hit); + } + } + return ticks; + } + + @Override + public void visualize(Entity entity, Entity victim, BattleState state) { + if(state != null) { + if (state.getStyle() == CombatStyle.MELEE) { + entity.animate(MELEE_ATTACK); + } else { + entity.animate(RANGE_ATTACK); + for (BattleState s : state.getTargets()) { + Projectile.ranged(entity, s.getVictim(), 1200, 0, 0, 46, 1).send(); + } + } + } + } + + @Override + public ArmourSet getArmourSet(Entity e) { + if(getType() != null) + return getType().getSwingHandler().getArmourSet(e); + else return ArmourSet.AHRIM; + } + + @Override + public double getSetMultiplier(Entity e, int skillId) { + if(getType() != null) + return getType().getSwingHandler().getSetMultiplier(e, skillId); + else return 0.0; + } + + @Override + public void impact(Entity entity, Entity victim, BattleState state) { + if (state != null && state.getStyle() != null && state.getStyle() == CombatStyle.MELEE) { + state.getStyle().getSwingHandler().impact(entity, victim, state); + return; + } + if(state != null && state.getTargets() != null) { + for (BattleState s : state.getTargets()) { + if (s == null || s.getEstimatedHit() < 0) { + continue; + } + int hit = s.getEstimatedHit(); + s.getVictim().getImpactHandler().handleImpact(entity, hit, CombatStyle.RANGE, s); + } + } + } + + @Override + public void visualizeImpact(Entity entity, Entity victim, BattleState state) { + if (state.getStyle() == CombatStyle.MELEE) { + victim.animate(victim.getProperties().getDefenceAnimation()); + return; + } + for (BattleState s : state.getTargets()) { + s.getVictim().animate(s.getVictim().getProperties().getDefenceAnimation()); + } + } + + @Override + public void adjustBattleState(Entity entity, Entity victim, BattleState state) { + if (state.getStyle() == CombatStyle.MELEE) { + state.getStyle().getSwingHandler().adjustBattleState(entity, victim, state); + return; + } + for (BattleState s : state.getTargets()) { + CombatStyle.RANGE.getSwingHandler().adjustBattleState(entity, s.getVictim(), s); + } + } + + @Override + public int calculateAccuracy(Entity entity) { + if(getType() != null) + return getType().getSwingHandler().calculateAccuracy(entity); + else return -1; + } + + @Override + public int calculateDefence(Entity victim, Entity attacker) { + if(getType() != null) + return getType().getSwingHandler().calculateDefence(victim, attacker); + else return -1; + } + + @Override + public int calculateHit(Entity entity, Entity victim, double modifier) { + if(getType() != null) + return getType().getSwingHandler().calculateHit(entity, victim, modifier); + else return -1; + } + +} diff --git a/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GWDKreeArraSwingHandler.java b/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GWDKreeArraSwingHandler.java new file mode 100644 index 0000000..925f917 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GWDKreeArraSwingHandler.java @@ -0,0 +1,217 @@ +package content.region.asgarnia.trollheim.handlers.gwd; + +import java.util.ArrayList; +import java.util.List; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.node.entity.combat.InteractionType; +import core.game.node.entity.combat.equipment.ArmourSet; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.npc.NPC; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.tools.RandomFunction; + +/** + * Handles Kree'arra's combat. + * @author Emperor + */ +public final class GWDKreeArraSwingHandler extends CombatSwingHandler { + + /** + * The boss chamber. + */ + private static final ZoneBorders CHAMBER = new ZoneBorders(2824, 5296, 2842, 5308); + + /** + * The melee attack animation. + */ + private static final Animation MELEE_ATTACK = new Animation(6977, Priority.HIGH); + + /** + * The range attack animation. + */ + private static final Animation RANGE_ATTACK = new Animation(6976, Priority.HIGH); + + /** + * The end graphic. + */ + private static final Graphics END_GRAPHIC = new Graphics(80, 96); + + /** + * Constructs a new {@code GWDKreeArraSwingHandler} {@Code Object}. + */ + public GWDKreeArraSwingHandler() { + super(CombatStyle.RANGE); + } + + @Override + public InteractionType canSwing(Entity entity, Entity victim) { + return CombatStyle.RANGE.getSwingHandler().canSwing(entity, victim); + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + int ticks = 1; + int distance = entity != null ? entity.size() >> 1 : 0; + if (entity != null && !entity.inCombat()) { + distance++; + } + if (entity != null && victim.getLocation().withinDistance(entity.getCenterLocation(), distance) && RandomFunction.RANDOM.nextBoolean()) { + int hit = 0; + int max = CombatStyle.MELEE.getSwingHandler().calculateHit(entity, victim, 1.0); + if (CombatStyle.MELEE.getSwingHandler().isAccurateImpact(entity, victim, CombatStyle.MELEE)) { + hit = RandomFunction.random(max); + } + state.setEstimatedHit(hit); + hit = 0; + if (CombatStyle.MELEE.getSwingHandler().isAccurateImpact(entity, victim, CombatStyle.MELEE)) { + hit = RandomFunction.random(max); + } + state.setSecondaryHit(hit); + state.setMaximumHit(max); + state.setStyle(CombatStyle.MELEE); + } else { + ticks += (int) Math.ceil(entity != null ? entity.getLocation().getDistance(victim.getLocation()) : 0.0 * 0.3); + NPC npc = (NPC) entity; + List list = new ArrayList<>(20); + for (Entity t : RegionManager.getLocalPlayers(npc, 28)) { + if (!CHAMBER.insideBorder(t.getLocation())) { + continue; + } + if (t.isAttackable(npc, CombatStyle.RANGE, false)) { + list.add(new BattleState(entity, t)); + } + } + BattleState[] targets; + state.setStyle(CombatStyle.RANGE); + state.setTargets(targets = list.toArray(new BattleState[0])); + for (BattleState s : targets) { + CombatStyle style = RandomFunction.randomize(10) < 3 ? CombatStyle.MAGIC : CombatStyle.RANGE; + s.setStyle(style); + int hit = 0; + if (style.getSwingHandler().isAccurateImpact(entity, s.getVictim(), style)) { + int max = style.getSwingHandler().calculateHit(entity, s.getVictim(), 1.0); + s.setMaximumHit(max); + if(style.equals(CombatStyle.RANGE)){ + max = 71; + } + hit = RandomFunction.random(max); + } + s.setEstimatedHit(hit); + } + } + return ticks; + } + + @Override + public void visualize(Entity entity, Entity victim, BattleState state) { + if(state != null) { + if (state.getStyle() == CombatStyle.MELEE) { + entity.animate(MELEE_ATTACK); + } else { + entity.animate(RANGE_ATTACK); + for (BattleState s : state.getTargets()) { + int gfxId = 1197; + if (s.getStyle() == CombatStyle.MAGIC) { + gfxId = 1198; + } + Projectile.ranged(entity, s.getVictim(), gfxId, 92, 36, 46, 5).send(); + } + } + } + } + + @Override + public ArmourSet getArmourSet(Entity e) { + if(getType() != null) + return getType().getSwingHandler().getArmourSet(e); + else return ArmourSet.AHRIM; + } + + @Override + public double getSetMultiplier(Entity e, int skillId) { + if(getType() != null) + return getType().getSwingHandler().getSetMultiplier(e, skillId); + else return 0.0; + } + + @Override + public void impact(Entity entity, Entity victim, BattleState state) { + if (state != null && state.getStyle() == CombatStyle.MELEE) { + state.getStyle().getSwingHandler().impact(entity, victim, state); + return; + } + if(state != null) { + for (BattleState s : state.getTargets()) { + if (s == null || s.getEstimatedHit() < 0) { + continue; + } + int hit = s.getEstimatedHit(); + s.getVictim().getImpactHandler().handleImpact(entity, hit, s.getStyle(), s); + } + } + } + + @Override + public void visualizeImpact(Entity entity, Entity victim, BattleState state) { + if (state != null && state.getStyle() == CombatStyle.MELEE) { + victim.animate(victim.getProperties().getDefenceAnimation()); + return; + } + if(state != null) { + for (BattleState s : state.getTargets()) { + s.getVictim().animate(s.getVictim().getProperties().getDefenceAnimation()); + if (RandomFunction.randomize(10) < 8) { + Direction dir = Direction.getLogicalDirection(entity.getLocation(), s.getVictim().getLocation()); + Location destination = s.getVictim().getLocation().transform(dir.getStepX(), dir.getStepY(), 0); + if (CHAMBER.insideBorder(destination)) { + s.getVictim().getProperties().setTeleportLocation(destination); + s.getVictim().graphics(END_GRAPHIC); + } + } + } + } + } + + @Override + public void adjustBattleState(Entity entity, Entity victim, BattleState state) { + if (state.getStyle() == CombatStyle.MELEE) { + state.getStyle().getSwingHandler().adjustBattleState(entity, victim, state); + return; + } + for (BattleState s : state.getTargets()) { + s.getStyle().getSwingHandler().adjustBattleState(entity, s.getVictim(), s); + } + } + + @Override + public int calculateAccuracy(Entity entity) { + if(getType() != null) + return getType().getSwingHandler().calculateAccuracy(entity); + else return -1; + } + + @Override + public int calculateDefence(Entity victim, Entity attacker) { + if(getType() != null) + return getType().getSwingHandler().calculateDefence(victim, attacker); + else return -1; + } + + @Override + public int calculateHit(Entity entity, Entity victim, double modifier) { + if(getType() != null) + return getType().getSwingHandler().calculateHit(entity, victim, modifier); + else return -1; + } + +} diff --git a/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GWDTsutsarothSwingHandler.java b/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GWDTsutsarothSwingHandler.java new file mode 100644 index 0000000..d90bd3f --- /dev/null +++ b/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GWDTsutsarothSwingHandler.java @@ -0,0 +1,156 @@ +package content.region.asgarnia.trollheim.handlers.gwd; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.node.entity.combat.InteractionType; +import core.game.node.entity.combat.equipment.ArmourSet; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.Player; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.tools.RandomFunction; + +import static core.api.ContentAPIKt.*; + +/** + * Handles K'ril Tsutsaroth's combat. + * @author Emperor + */ +public final class GWDTsutsarothSwingHandler extends CombatSwingHandler { + + /** + * The melee attack animation. + */ + private static final Animation MELEE_ATTACK = new Animation(6945, Priority.HIGH); + + /** + * The range attack animation. + */ + private static final Animation MAGIC_ATTACK = new Animation(6947, Priority.HIGH); + + /** + * The magic start graphic. + */ + private static final Graphics MAGIC_START = new Graphics(1210); + + /** + * If K'ril is performing its special attack. + */ + private boolean special; + + /** + * Constructs a new {@code GWDTsutsarothSwingHandler} {@Code Object}. + */ + public GWDTsutsarothSwingHandler() { + super(CombatStyle.MELEE); + } + + @Override + public InteractionType canSwing(Entity entity, Entity victim) { + return CombatStyle.MELEE.getSwingHandler().canSwing(entity, victim); + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + int ticks = 1; + special = false; + int hit = 0; + CombatStyle style = CombatStyle.MELEE; + if (RandomFunction.randomize(10) < 4) { + ticks += (int) Math.ceil(entity.getLocation().getDistance(victim.getLocation()) * 0.3); + style = CombatStyle.MAGIC; + } else if (RandomFunction.randomize(10) == 0) { + if (special = (victim instanceof Player)) { + ((Player) victim).getPacketDispatch().sendMessage("K'ril Tsutsaroth slams through your protection prayer, leaving you feeling drained."); + } + entity.sendChat("YARRRRRRR!"); + } + if (style.getSwingHandler().isAccurateImpact(entity, victim)) { + int max = style.getSwingHandler().calculateHit(entity, victim, special ? 1.08 : 1.0); + hit = RandomFunction.random(max); + state.setMaximumHit(max); + if (style == CombatStyle.MELEE) { + applyPoison(victim, entity, 16); + } + if (special) { + ((Player) victim).getSkills().decrementPrayerPoints((double) hit / 2); + } + } + state.setEstimatedHit(hit); + state.setStyle(style); + return ticks; + } + + @Override + public void visualize(Entity entity, Entity victim, BattleState state) { + if(entity == null || state == null || state.getStyle() == null){ + return; + } + if (state.getStyle() == CombatStyle.MELEE) { + entity.animate(MELEE_ATTACK); + } else { + entity.visualize(MAGIC_ATTACK, MAGIC_START); + Projectile.magic(entity, victim, 1211, 0, 0, 46, 1).send(); + } + } + + @Override + public ArmourSet getArmourSet(Entity e) { + return getType().getSwingHandler().getArmourSet(e); + } + + @Override + public double getSetMultiplier(Entity e, int skillId) { + return getType().getSwingHandler().getSetMultiplier(e, skillId); + } + + @Override + public void impact(Entity entity, Entity victim, BattleState state) { + if (state.getStyle() == CombatStyle.MAGIC) { + if (state.getEstimatedHit() > -1) { + victim.getImpactHandler().handleImpact(entity, state.getEstimatedHit(), CombatStyle.MAGIC, state); + } + return; + } + state.getStyle().getSwingHandler().impact(entity, victim, state); + } + + @Override + public void visualizeImpact(Entity entity, Entity victim, BattleState state) { + victim.animate(victim.getProperties().getDefenceAnimation()); + } + + @Override + public void adjustBattleState(Entity entity, Entity victim, BattleState state) { + super.adjustBattleState(entity, victim, state); + } + + @Override + protected int getFormattedHit(Entity entity, Entity victim, BattleState state, int hit) { + if (!special) { + if (state.getArmourEffect() != ArmourSet.VERAC && victim.hasProtectionPrayer(state.getStyle())) { + hit *= entity instanceof Player ? 0.6 : 0; + } + } + return formatHit(victim, hit); + } + + @Override + public int calculateAccuracy(Entity entity) { + return getType().getSwingHandler().calculateAccuracy(entity); + } + + @Override + public int calculateDefence(Entity victim, Entity attacker) { + return getType().getSwingHandler().calculateDefence(victim, attacker); + } + + @Override + public int calculateHit(Entity entity, Entity victim, double modifier) { + return getType().getSwingHandler().calculateHit(entity, victim, modifier); + } + +} diff --git a/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GWDZilyanaSwingHandler.java b/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GWDZilyanaSwingHandler.java new file mode 100644 index 0000000..a1f060d --- /dev/null +++ b/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GWDZilyanaSwingHandler.java @@ -0,0 +1,160 @@ +package content.region.asgarnia.trollheim.handlers.gwd; + +import java.util.ArrayList; +import java.util.List; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.node.entity.combat.InteractionType; +import core.game.node.entity.combat.equipment.ArmourSet; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.npc.NPC; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.tools.RandomFunction; + +/** + * Handles the Commander Zilyana combat. + * @author Emperor + */ +public class GWDZilyanaSwingHandler extends CombatSwingHandler { + + /** + * The melee attack animation. + */ + private static final Animation MELEE_ATTACK = new Animation(6964, Priority.HIGH); + + /** + * The magic attack animation. + */ + private static final Animation MAGIC_ATTACK = new Animation(6967, Priority.HIGH); + + /** + * The magic end graphic. + */ + private static final Graphics MAGIC_END_GRAPHIC = new Graphics(1207); + + /** + * Constructs a new {@code ZilyanaSwingHandler} {@Code Object}. + */ + public GWDZilyanaSwingHandler() { + super(CombatStyle.MAGIC); + } + + @Override + public InteractionType canSwing(Entity entity, Entity victim) { + return CombatStyle.MELEE.getSwingHandler().canSwing(entity, victim); + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + BattleState[] targets; + if (RandomFunction.randomize(10) < 7) { + targets = new BattleState[] { state }; + setType(CombatStyle.MELEE); + state.setStyle(CombatStyle.MELEE); + } else { + NPC npc = (NPC) entity; + List list = new ArrayList<>(20); + for (Entity t : RegionManager.getLocalPlayers(npc.getCenterLocation(), (npc.size() >> 1) + 2)) { + if (t.getLocation().getX() < 2908 && t.isAttackable(npc, CombatStyle.MAGIC, false)) { + list.add(new BattleState(entity, t)); + } + } + state.setTargets(targets = list.toArray(new BattleState[0])); + state.setStyle(CombatStyle.MAGIC); + setType(CombatStyle.MAGIC); + } + for (BattleState s : targets) { + s.setStyle(state.getStyle()); + int hit = getType() == CombatStyle.MAGIC ? -1 : 0; + if (isAccurateImpact(entity, s.getVictim())) { + int max = calculateHit(entity, s.getVictim(), 1.0); + s.setMaximumHit(max); + hit = RandomFunction.random(max); + } + s.setEstimatedHit(hit); + } + return 1; + } + + @Override + public void visualize(Entity entity, Entity victim, BattleState state) { + if(getType() != null) { + switch (getType()) { + case MELEE: + entity.animate(MELEE_ATTACK); + break; + case MAGIC: + entity.animate(MAGIC_ATTACK); + break; + default: + break; + } + } + } + + @Override + public ArmourSet getArmourSet(Entity e) { + if(getType() != null) + return getType().getSwingHandler().getArmourSet(e); + else return ArmourSet.AHRIM; + } + + @Override + public double getSetMultiplier(Entity e, int skillId) { + if(getType() != null) + return getType().getSwingHandler().getSetMultiplier(e, skillId); + else return -1; + } + + @Override + public void impact(Entity entity, Entity victim, BattleState state) { + if(state != null) + state.getStyle().getSwingHandler().impact(entity, victim, state); + } + + @Override + public void adjustBattleState(Entity entity, Entity victim, BattleState state) { + state.getStyle().getSwingHandler().adjustBattleState(entity, victim, state); + } + + @Override + public int calculateAccuracy(Entity entity) { + if(getType() != null) + return getType().getSwingHandler().calculateAccuracy(entity); + else return -1; + } + + @Override + public int calculateDefence(Entity victim, Entity attacker) { + if(getType() != null) + return getType().getSwingHandler().calculateDefence(victim, attacker); + else return -1; + } + + @Override + public int calculateHit(Entity entity, Entity victim, double modifier) { + if(getType() != null) + return getType().getSwingHandler().calculateHit(entity, victim, modifier); + else return -1; + } + + @Override + public void visualizeImpact(Entity entity, Entity victim, BattleState state) { + if (state != null && state.getStyle() == CombatStyle.MAGIC) { + for (BattleState s : state.getTargets()) { + if (s.getEstimatedHit() > 0) { + s.getVictim().graphics(MAGIC_END_GRAPHIC); + } + } + return; + } + if(state != null) + state.getStyle().getSwingHandler().visualizeImpact(entity, victim, state); + } + +} diff --git a/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GodWarsFaction.java b/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GodWarsFaction.java new file mode 100644 index 0000000..2c653de --- /dev/null +++ b/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GodWarsFaction.java @@ -0,0 +1,84 @@ +package content.region.asgarnia.trollheim.handlers.gwd; + +import core.api.God; +import core.game.node.entity.player.Player; + +import static core.api.ContentAPIKt.hasGodItem; + +/** + * The god wars factions. + * @author Emperor + */ +public enum GodWarsFaction { + ARMADYL(6222, 6246, God.ARMADYL), + BANDOS(6260, 6283, God.BANDOS), + SARADOMIN(6247, 6259, God.SARADOMIN), + ZAMORAK(6203, 6221, God.ZAMORAK); + + /** + * The start NPC id. + */ + private final int startId; + + /** + * The end NPC id. + */ + private final int endId; + + /** + * The god this faction represents + */ + private final God god; + + /** + * Constructs a new {@code GodWarsFaction} {@code Object}. + * @param startId The start NPC id. + * @param endId The end NPC id. + * @param god The god this faction represents. + */ + private GodWarsFaction(int startId, int endId, God god) { + this.startId = startId; + this.endId = endId; + this.god = god; + } + + /** + * Gets the god wars faction for the given NPC id. + * @param npcId The NPC id. + * @return The faction for this NPC. + */ + public static GodWarsFaction forId(int npcId) { + for (GodWarsFaction faction : values()) { + if (npcId >= faction.getStartId() && npcId <= faction.getEndId()) { + return faction; + } + } + return null; + } + + /** + * Checks if the player is protected from this faction. + * @param player The player. + * @return {@code True} if no NPCs of this faction should attack the + * player. + */ + public boolean isProtected(Player player) { + return hasGodItem(player, god); + } + + /** + * Gets the startId. + * @return The startId. + */ + public int getStartId() { + return startId; + } + + /** + * Gets the endId. + * @return The endId. + */ + public int getEndId() { + return endId; + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GodWarsMinionNPC.java b/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GodWarsMinionNPC.java new file mode 100644 index 0000000..b6841b4 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GodWarsMinionNPC.java @@ -0,0 +1,103 @@ +package content.region.asgarnia.trollheim.handlers.gwd; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.DeathTask; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.world.GameWorld; +import core.plugin.Initializable; +import core.game.world.map.Location; + +/** + * Handles a god wars minion NPC. + * @author Emperor + */ +@Initializable +public final class GodWarsMinionNPC extends AbstractNPC { + + /** + * The boss NPC. + */ + private NPC boss; + + /** + * Constructs a new {@code GodWarsMinionNPC} {@code Object}. + */ + public GodWarsMinionNPC() { + super(6223, null); + } + + /** + * Constructs a new {@code GodWarsMinionNPC} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + public GodWarsMinionNPC(int id, Location location) { + super(id, location); + } + + @Override + public void init() { + super.init(); + getAggressiveHandler().setAllowTolerance(false); + } + + @Override + public void tick() { + super.tick(); + if (boss != null && boss.inCombat()) { + Entity target = boss.getAttribute("combat-attacker"); + if (target != null && (target != getProperties().getCombatPulse().getVictim() || !getProperties().getCombatPulse().isAttacking())) { + if (!getProperties().getCombatPulse().isAttacking() && !DeathTask.isDead(this)) { + // getProperties().getCombatPulse().attack(target); + } else { + getProperties().getCombatPulse().setVictim(target); + face(target); + } + } + } + } + + @Override + public void finalizeDeath(Entity killer) { + super.finalizeDeath(killer); + getProperties().getCombatPulse().stop(); + if (boss != null && boss.getRespawnTick() > GameWorld.getTicks()) { + setRespawnTick(boss.getRespawnTick()); + } + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new GodWarsMinionNPC(id, location); + } + + @Override + public Object fireEvent(String identifier, Object... args) { + switch (identifier) { + case "set_boss": + boss = (NPC) args[0]; + return true; + } + return null; + } + + @Override + public boolean isAttackable(Entity entity, CombatStyle style, boolean message) { + if (boss != null && boss.getId() == 6222 && style == CombatStyle.MELEE && entity instanceof Player) { + if(message) { + ((Player) entity).getPacketDispatch().sendMessage("The aviansie is flying too high for you to attack using melee."); + } + return false; + } + return super.isAttackable(entity, style, message); + } + + @Override + public int[] getIds() { + return new int[] { 6204, 6206, 6208, 6223, 6225, 6227, 6248, 6250, 6252, 6261, 6263, 6265 }; + } + +} diff --git a/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GodWarsNPC.java b/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GodWarsNPC.java new file mode 100644 index 0000000..215de9f --- /dev/null +++ b/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GodWarsNPC.java @@ -0,0 +1,169 @@ +package content.region.asgarnia.trollheim.handlers.gwd; + +import java.util.ArrayList; +import java.util.List; + +import core.api.ContentAPIKt; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.DeathTask; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.npc.agg.AggressiveBehavior; +import core.game.node.entity.npc.agg.AggressiveHandler; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.TeleportManager; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.game.world.map.RegionManager; +import core.tools.RandomFunction; +import org.rs09.consts.NPCs; + +import static core.api.ContentAPIKt.getPathableRandomLocalCoordinate; +import static core.api.ContentAPIKt.sendGraphics; + +/** + * Handles a god wars NPC. + * @author Emperor + */ +@Initializable +public final class GodWarsNPC extends AbstractNPC { + + private static final int IMP_TELEPORT_CHANCE_ON_HIT = 10; // 1/10 + private static final int IMP_TELEPORT_CHANCE_ON_TICK = 75; // 1/75 + + /** + * The aggressive behavior. + */ + private static final AggressiveBehavior AGGRO_BEHAVIOR = new AggressiveBehavior() { + + @Override + public boolean canSelectTarget(Entity entity, Entity target) { + if (!target.isActive() || DeathTask.isDead(target) || DeathTask.isDead(entity)) { + return false; + } + if (!target.getProperties().isMultiZone() && target.inCombat()) { + return false; + } + if (target instanceof GodWarsNPC) { + if (((GodWarsNPC) target).faction != ((GodWarsNPC) entity).faction) { + return true; + } + } else if (target instanceof Player) { + if (!((GodWarsNPC) entity).faction.isProtected((Player) target)) { + return true; + } + } + return false; + } + + @Override + public List getPossibleTargets(Entity entity, int radius) { + List targets = new ArrayList<>(20); + for (Player player : RegionManager.getLocalPlayers(entity, radius)) { + if (canSelectTarget(entity, player)) { + targets.add(player); + } + } + if (!targets.isEmpty()) { + return targets; + } + for (NPC npc : RegionManager.getLocalNpcs(entity, radius)) { + if (canSelectTarget(entity, npc)) { + targets.add(npc); + } + } + return targets; + } + }; + + /** + * The god wars faction (0=armadyl, 1=bandos, 2=saradomin, 3=zamorak). + */ + private GodWarsFaction faction; + + /** + * Constructs a new {@code GodWarsNPC} {@code Object}. + */ + public GodWarsNPC() { + super(-1, null); + } + + /** + * Constructs a new {@code GodWarsNPC} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + public GodWarsNPC(int id, Location location) { + super(id, location); + } + + @Override + public void init() { + super.init(); + setWalks(true); + faction = GodWarsFaction.forId(getId()); + } + + @Override + public void setDefaultBehavior() { + setAggressive(true); + aggressiveHandler = new AggressiveHandler(this, AGGRO_BEHAVIOR); + } + + @Override + public boolean isAttackable(Entity entity, CombatStyle style, boolean message) { + if (style == CombatStyle.MELEE && faction == GodWarsFaction.ARMADYL && entity instanceof Player) { + if(message) { + ((Player) entity).getPacketDispatch().sendMessage("The aviansie is flying too high for you to attack using melee."); + } + return false; + } + return super.isAttackable(entity, style, message); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new GodWarsNPC(id, location); + } + + @Override + public int[] getIds() { + return new int[] { 6210, 6211, 6212, 6213, 6214, 6215, 6216, 6217, 6218, 6219, 6220, 6221, 6229, 6230, 6231, 6232, 6233, 6234, 6235, 6236, 6237, 6238, 6239, 6240, 6241, 6242, 6243, 6244, 6245, 6246, 6254, 6255, 6256, 6257, 6258, 6259, 6267, 6268, 6269, 6270, 6271, 6272, 6273, 6274, 6275, 6276, 6277, 6278, 6279, 6280, 6281, 6282, 6283 }; + } + + @Override + public void checkImpact(BattleState state) { + super.checkImpact(state); + + if (getId() == NPCs.IMP_6211) { + if (RandomFunction.roll(IMP_TELEPORT_CHANCE_ON_HIT)) { + getRandomLocAndTeleport(); + } + } + } + + @Override + public void tick() { + super.tick(); + + if (getId() == NPCs.IMP_6211) { + if (RandomFunction.roll(IMP_TELEPORT_CHANCE_ON_TICK)) { + getRandomLocAndTeleport(); + } + } + } + + /** + * Used to teleport imps + */ + private void getRandomLocAndTeleport() { + Location teleportLocation = getPathableRandomLocalCoordinate(this, walkRadius, getProperties().getSpawnLocation(), 3); + + if (getLocation() != teleportLocation) { + sendGraphics(1119, getLocation()); + ContentAPIKt.teleport(this, teleportLocation, TeleportManager.TeleportType.INSTANT); + } + } +} diff --git a/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GodswordDialogue.java b/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GodswordDialogue.java new file mode 100644 index 0000000..d6cc049 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GodswordDialogue.java @@ -0,0 +1,158 @@ +package content.region.asgarnia.trollheim.handlers.gwd; + +import core.game.dialogue.DialoguePlugin; +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; + +/** + * Represents the godsword dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class GodswordDialogue extends DialoguePlugin { + + /** + * Represents the animation to use. + */ + private static final Animation ANIMATION = new Animation(898); + + /** + * Represents the godsword blade item. + */ + private static final Item BLADE = new Item(11690); + + /** + * Represents the used item id. + */ + private int used; + + /** + * Constructs a new {@code GodswordDialogue} {@code Object}. + */ + public GodswordDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code GodswordDialogue} {@code Object}. + * @param player the player. + */ + public GodswordDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new GodswordDialogue(player); + } + + @Override + public boolean open(Object... args) { + used = (int) args[0]; + interpreter.sendDialogue("You set to work, trying to fix the ancient sword."); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + boolean passBlade = true; + int remove = -1; + if (used == 11692 && player.getInventory().contains(11710, 1)) { + passBlade = false; + remove = 11710; + } + if (used == 11710 && player.getInventory().containItems(11692)) { + passBlade = false; + remove = 11692; + } + if (used == 11688 && player.getInventory().contains(11712, 1)) { + passBlade = false; + remove = 11712; + } + if (used == 11712 && player.getInventory().containItems(11688)) { + passBlade = false; + remove = 11688; + } + if (used == 11686 && player.getInventory().contains(11714, 1)) { + passBlade = false; + remove = 11714; + } + if (used == 11714 && player.getInventory().containItems(11686)) { + passBlade = false; + remove = 11686; + } + if (!passBlade) { + if (player.getInventory().remove(new Item(used)) && player.getInventory().remove(new Item(remove))) { + player.lock(5); + player.animate(ANIMATION); + interpreter.sendDialogue("Even for an experienced smith it is not an easy task, but eventually", "it is done."); + player.getSkills().addExperience(Skills.SMITHING, 100, true); + player.getInventory().add(BLADE); + } + return true; + } + int base = -1; + if (used == 11710) { + if (player.getInventory().contains(11712, 1)) { + base = 11712; + } else if (player.getInventory().contains(11714, 1)) { + base = 11714; + } + } + if (used == 11712) { + if (player.getInventory().contains(11710, 1)) { + base = 11710; + } else if (player.getInventory().contains(11714, 1)) { + base = 11714; + } + } + if (used == 11714) { + if (player.getInventory().contains(11712, 1)) { + base = 11712; + } else if (player.getInventory().contains(11710, 1)) { + base = 11710; + } + } + if (base == -1) { + end(); + player.getPacketDispatch().sendMessage("You didn't have all the required items."); + return true; + } + if (player.getInventory().remove(new Item(used)) && player.getInventory().remove(new Item(base))) { + int shard = -1; + if (used == 11710 && base == 11712 || used == 11712 && base == 11710) { + shard = 11686; + } else if (used == 11710 && base == 11714 || used == 11714 && base == 11710) { + shard = 11688; + } + if (used == 11712 && base == 11714 || used == 11714 && base == 11712) { + shard = 11692; + } + player.lock(5); + player.animate(ANIMATION); + interpreter.sendDialogue("Even for an experienced smith it is not an easy task, but eventually", "it is done."); + player.getSkills().addExperience(Skills.SMITHING, 100); + player.getInventory().add(new Item(shard)); + } + stage = 1; + break; + case 1: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 62362 }; + } +} diff --git a/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GodwarsBossNPC.java b/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GodwarsBossNPC.java new file mode 100644 index 0000000..4d62e0f --- /dev/null +++ b/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GodwarsBossNPC.java @@ -0,0 +1,310 @@ +package content.region.asgarnia.trollheim.handlers.gwd; + +import content.data.BossKillCounter; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.DeathTask; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.npc.agg.AggressiveBehavior; +import core.game.node.entity.npc.agg.AggressiveHandler; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.prayer.PrayerType; +import core.game.world.map.Location; +import core.game.world.map.zone.ZoneBorders; +import core.plugin.Initializable; +import core.tools.RandomFunction; +import core.game.node.entity.combat.CombatPulse; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.world.GameWorld; + +/** + * Handles a god wars boss NPC. + * @author Emperor + */ +@Initializable +public final class GodwarsBossNPC extends AbstractNPC { + + /** + * Handles the combat swing of Commander Zilyana. + */ + private static final CombatSwingHandler ZILYANA_COMBAT = new GWDZilyanaSwingHandler(); + + /** + * Handles the combat swing of Kree'arra. + */ + private static final CombatSwingHandler KREE_ARRA_COMBAT = new GWDKreeArraSwingHandler(); + + /** + * Handles the combat swing of General Graardor. + */ + private static final CombatSwingHandler GRAARDOR_COMBAT = new GWDGraardorSwingHandler(); + + /** + * Handles the combat swing of General Graardor. + */ + private static final CombatSwingHandler TSUTSAROTH_COMBAT = new GWDTsutsarothSwingHandler(); + + /** + * The battle cries. + */ + private static final String[][] BATTLE_CRIES = { { // Zamorak + "Attack them, you dogs!", "Forward!", "Death to Saradomin's dogs!", "Kill them, you cowards!", "The Dark One will have their souls!", "Zamorak curse them!", "Rend them limb from limb!", "No retreat!", "Flay them all!" }, { // Armadyl + "Kraaaw!" }, { // Saradomin + "Death to the enemies of the light!", "Slay the evil ones!", "Saradomin lend me strength!", "By the power of Saradomin!", "May Saradomin be my sword.", "Good will always triumph!", "Forward! Our allies are with us!", "Saradomin is with us!", "In the name of Saradomin!", "Attack! Find the Godsword!" }, { // Bandos + "Death to our enemies!", "Brargh!", "Break their bones!", "For the glory of Bandos!", "Split their skulls!", "We feast on the bones of our enemies tonight!", "CHAAARGE!", "Crush them underfoot!", "All glory to Bandos!", "GRAAAAAAAAAAAR!", "FOR THE GLORY OF THE BIG HIGH WAR GOD!" } }; + + /** + * The minions. + */ + private NPC[] minions; + + /** + * The boss chamber. + */ + private ZoneBorders chamber; + + /** + * The next battle cry tick. + */ + private int nextBattleCry; + + /** + * The combat swing handler. + */ + private CombatSwingHandler handler; + + /** + * If the NPC focuses on one target. + */ + private boolean targetFocus; + + /** + * Constructs a new {@code CommanderZilyanaNPC} {@code Object}. + */ + public GodwarsBossNPC() { + super(6203, null); + } + + /** + * Constructs a new {@code CommanderZilyanaNPC} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + public GodwarsBossNPC(int id, Location location) { + super(id, location); + } + + @Override + public void init() { + setAggressive(false); + super.init(); + switch (getId()) { + case 6203: + chamber = new ZoneBorders(2918, 5318, 2936, 5331); + handler = TSUTSAROTH_COMBAT; + targetFocus = true; + break; + case 6222: + chamber = new ZoneBorders(2824, 5296, 2842, 5308); + handler = KREE_ARRA_COMBAT; + break; + case 6247: + chamber = new ZoneBorders(2889, 5258, 2907, 5276); + handler = ZILYANA_COMBAT; + break; + case 6260: + chamber = new ZoneBorders(2864, 5351, 2876, 5369); + handler = GRAARDOR_COMBAT; + targetFocus = true; + break; + } + AggressiveBehavior behavior = null; + if (chamber != null) { + final ZoneBorders borders = chamber; + behavior = new AggressiveBehavior() { + @Override + public boolean canSelectTarget(Entity entity, Entity target) { + if (!target.isActive() || DeathTask.isDead(target)) { + return false; + } + if (!target.getProperties().isMultiZone() && target.inCombat()) { + return false; + } + return borders.insideBorder(target.getLocation()); + } + }; + super.setAggressiveHandler(new AggressiveHandler(this, behavior)); + if (chamber.insideBorder(getLocation())) { + minions = new NPC[3]; + for (int i = 0; i < 3; i++) { + int npcId = getId() + 1 + (i << 1); + AbstractNPC npc = (AbstractNPC) (minions[i] = NPC.create(npcId, getSpawnLocation(npcId))); + npc.init(); + npc.fireEvent("set_boss", this); + if (behavior != null) { + npc.setAggressiveHandler(new AggressiveHandler(npc, behavior)); + npc.getAggressiveHandler().setChanceRatio(6); + npc.getAggressiveHandler().setAllowTolerance(false); + npc.getAggressiveHandler().setRadius(28); + } + } + } + } + getProperties().setNPCWalkable(true); + getProperties().setCombatTimeOut(2); + getAggressiveHandler().setChanceRatio(6); + getAggressiveHandler().setRadius(28); + getAggressiveHandler().setAllowTolerance(false); + walkRadius = 28; + } + + @Override + public void tick() { + CombatPulse pulse = getProperties().getCombatPulse(); + if (chamber != null && pulse.isAttacking()) { + Entity e = pulse.getVictim(); + if (!targetFocus) { + Entity target = getImpactHandler().getMostDamageEntity(null); + if (target != null && target != e && target instanceof Player) { + pulse.setVictim(target); + } + } + if (!chamber.insideBorder(e.getLocation().getX(), e.getLocation().getY())) { + getPulseManager().clear(); + } + if (nextBattleCry < GameWorld.getTicks()) { + String[] cries = BATTLE_CRIES[(getId() - 6203) >> 4]; + sendChat(cries[RandomFunction.randomize(cries.length)]); + nextBattleCry = GameWorld.getTicks() + 7 + RandomFunction.randomize(20); + } + } + super.tick(); + if (getRespawnTick() == GameWorld.getTicks() && minions != null) { + for (NPC npc : minions) { + npc.setRespawnTick(-1); + } + } + } + + @Override + public void onImpact(final Entity entity, BattleState state) { + if (targetFocus) { + if (getProperties().getCombatPulse().getNextAttack() < GameWorld.getTicks() - 3) { + getProperties().getCombatPulse().attack(entity); + return; + } + } + super.onImpact(entity, state); + } + + @Override + public void sendImpact(BattleState state) { + if (state.getVictim() == null || getId() != 6222) { + return; + } + int max = 0; + if (state.getVictim().isPlayer() && state.getEstimatedHit() > 0) { + switch (state.getStyle()) { + case MAGIC: + max = 21; + break; + case MELEE: + max = 26; + break; + case RANGE: + max = 71; + break; + + } + } + if (state.getEstimatedHit() > max) { + state.setEstimatedHit(RandomFunction.random(max - 10)); + } + if (state.getStyle() == CombatStyle.RANGE && state.getVictim().asPlayer().getPrayer().get(PrayerType.PROTECT_FROM_MISSILES)) { + state.neutralizeHits(); + } + } + + @Override + public void finalizeDeath(Entity killer) { + super.finalizeDeath(killer); + if (getId() == 6222 || getId() == 6260 || getId() == 6247 || getId() == 6203) { + BossKillCounter.addtoKillcount((Player) killer, this.getId()); + } + if (minions == null) { + return; + } + for (NPC minion : minions) { + if (minion.getRespawnTick() >= GameWorld.getTicks()) { + minion.setRespawnTick(getRespawnTick()); + } + } + } + + @Override + public boolean isAttackable(Entity entity, CombatStyle style, boolean message) { + if (getId() == 6222 && style == CombatStyle.MELEE && entity instanceof Player) { + if(message) { + ((Player) entity).getPacketDispatch().sendMessage("The aviansie is flying too high for you to attack using melee."); + } + return false; + } + return super.isAttackable(entity, style, message); + } + + /** + * Gets the spawn location for the given NPC id. + * @param id The NPC id. + * @return The spawn location. + */ + private Location getSpawnLocation(int id) { + switch (id) { + case 6208: + return Location.create(2920, 5320, 2); + case 6206: + return Location.create(2919, 5327, 2); + case 6204: + return Location.create(2927, 5325, 2); + case 6223: + return Location.create(2828, 5298, 2); + case 6225: + return Location.create(2837, 5299, 2); + case 6227: + return Location.create(2834, 5302, 2); + case 6248: + return Location.create(2898, 5267, 0); + case 6250: + return Location.create(2901, 5268, 0); + case 6252: + return Location.create(2895, 5260, 0); + case 6265: + return Location.create(2866, 5363, 2); + case 6261: + return Location.create(2867, 5354, 2); + case 6263: + return Location.create(2873, 5354, 2); + } + return null; + } + + @Override + public CombatSwingHandler getSwingHandler(boolean swing) { + if (handler != null) { + return handler; + } + return super.getSwingHandler(swing); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new GodwarsBossNPC(id, location); + } + + @Override + public int[] getIds() { + return new int[] { 6203, 6222, 6247, 6260 }; + } + +} diff --git a/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GodwarsEntranceHandler.java b/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GodwarsEntranceHandler.java new file mode 100644 index 0000000..8803d9d --- /dev/null +++ b/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GodwarsEntranceHandler.java @@ -0,0 +1,106 @@ +package content.region.asgarnia.trollheim.handlers.gwd; + +import core.cache.def.impl.SceneryDefinition; +import core.plugin.Initializable; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.skill.Skills; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.impl.ForceMovement; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; + +import static core.api.ContentAPIKt.*; +import content.data.Quests; + +/** + * Handles the entrance hole to the godwars dungeon. + * @author Emperor + */ +@Initializable +public final class GodwarsEntranceHandler extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(26340).getHandlers().put("option:tie-rope", this); + SceneryDefinition.forId(26341).getHandlers().put("option:climb-down", this); + SceneryDefinition.forId(26338).getHandlers().put("option:move", this); + SceneryDefinition.forId(26305).getHandlers().put("option:crawl-through", this); + return this; + } + + @Override + public boolean handle(final Player player, Node node, String option) { + Scenery object = (Scenery) node; + switch (object.getId()) { + case 26340: + if (!player.getInventory().remove(new Item(954))) { + player.getPacketDispatch().sendMessage("You don't have a rope to tie around the pillar."); + return true; + } + setVarbit(player, 3932, 1, true); + return true; + case 26341: + if (player.getSkills().getStaticLevel(Skills.AGILITY) < 15) { + player.getPacketDispatch().sendMessage("You need an Agility level of 15 to enter this."); + return true; + } + if (getVarbit(player, 3936) == 0) { + player.getDialogueInterpreter().sendDialogues(6201, FacialExpression.HALF_GUILTY, "Cough... Hey, over here."); + return true; + } + player.lock(2); + player.getPacketDispatch().sendMessage("You climb down the rope."); + player.animate(Animation.create(828)); + GameWorld.getPulser().submit(new Pulse(1, player) { + @Override + public boolean pulse() { + player.getProperties().setTeleportLocation(Location.create(2882, 5311, 2)); + return true; + } + }); + return true; + case 26338: + if (!hasRequirement(player, Quests.TROLL_STRONGHOLD)) + return true; + if (player.getSkills().getStaticLevel(Skills.STRENGTH) < 60) { + player.getPacketDispatch().sendMessage("You need a Strength level of 60 to move this boulder."); + return true; + } + player.getPacketDispatch().sendSceneryAnimation(object, Animation.create(6980)); + if (player.getLocation().getY() < 3716) { + ForceMovement.run(player, Location.create(2898, 3715, 0), Location.create(2898, 3719, 0), new Animation(6978), 3); + } else { + ForceMovement.run(player, Location.create(2898, 3719, 0), Location.create(2898, 3715, 0), new Animation(6979), 3); + } + GameWorld.getPulser().submit(new Pulse(12, player) { + @Override + public boolean pulse() { + player.getPacketDispatch().sendSceneryAnimation(RegionManager.getObject(0, 2898, 3716), Animation.create(6981)); + return true; + } + }); + return true; + case 26305: + if (player.getSkills().getStaticLevel(Skills.AGILITY) < 60) { + player.getPacketDispatch().sendMessage("You need an Agility level of 60 to squeeze through the crack."); + return true; + } + if (object.getLocation().equals(Location.create(2900, 3713, 0))) { + player.getProperties().setTeleportLocation(Location.create(2904, 3720, 0)); + } else { + player.getProperties().setTeleportLocation(Location.create(2899, 3713, 0)); + } + return true; + } + return false; + } + +} diff --git a/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GodwarsMapzone.java b/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GodwarsMapzone.java new file mode 100644 index 0000000..b2dd1fd --- /dev/null +++ b/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/GodwarsMapzone.java @@ -0,0 +1,562 @@ +package content.region.asgarnia.trollheim.handlers.gwd; + +import core.cache.def.impl.SceneryDefinition; +import core.game.component.Component; +import core.game.container.impl.EquipmentContainer; +import core.game.global.action.DoorActionHandler; +import core.game.interaction.MovementPulse; +import core.game.interaction.Option; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.equipment.RangeWeapon; +import core.game.node.entity.impl.ForceMovement; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.info.Rights; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.system.task.Pulse; +import core.tools.Log; +import core.tools.SystemLogger; +import core.game.world.GameWorld; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneBuilder; +import core.game.world.map.zone.ZoneRestriction; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.net.packet.PacketRepository; +import core.net.packet.context.MinimapStateContext; +import core.net.packet.out.MinimapState; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.tools.StringUtils; +import core.game.node.entity.skill.Skills; + +import static core.api.ContentAPIKt.*; +import static core.api.ContentAPIKt.log; + +/** + * Handles the god wars map zone. + * @author Emperor + */ +@Initializable +public final class GodwarsMapzone extends MapZone implements Plugin { + + /** + * The Zamorak's fortress area. + */ + private static final ZoneBorders ZAMORAK_FORTRESS = new ZoneBorders(2880, 5317, 2944, 5362); + + static { + ZAMORAK_FORTRESS.addException(new ZoneBorders(2880, 5317, 2904, 5338)); + } + + /** + * Constructs a new {@code GodwarsMapzone} {@code Object}. + */ + public GodwarsMapzone() { + super("Godwars", true, ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON); + } + + @Override + public void configure() { + register(new ZoneBorders(2816, 5248, 2943, 5375)); + } + + @Override + public boolean enter(Entity e) { + if (e instanceof Player) { + Player player = (Player) e; + int componentId = player.getInterfaceManager().isResizable() ? 597 : 601; + if (ZAMORAK_FORTRESS.insideBorder(player.getLocation().getX(), player.getLocation().getY())) { + componentId = player.getInterfaceManager().isResizable() ? 598 : 599; + } + openOverlay(player, componentId); + if (player.getDetails().getRights() == Rights.ADMINISTRATOR) { + for (GodWarsFaction faction : GodWarsFaction.values()) { + increaseKillcount(player, faction, 40); + } + } + } + return true; + } + + /** + * Sets the rope setting. + * @param player The player. + * @param setting The setting. + */ + public void setRopeSetting(Player player, int setting) { + setVarbit(player, setting == 1 ? 3933 : 3934, 1, true); + } + + /** + * Opens the overlay. + * @param player The player. + * @param componentId The component id. + */ + private void openOverlay(Player player, int componentId) { + player.setAttribute("gwd:overlay", componentId); + player.getInterfaceManager().openOverlay(new Component(componentId)); + int child = (componentId == 601 || componentId == 599) ? 6 : 7; + for (GodWarsFaction faction : GodWarsFaction.values()) { + int amount = player.getAttribute("gwd:" + faction.name().toLowerCase() + "kc", 0); + player.getPacketDispatch().sendString(Integer.toString(amount), componentId, child + faction.ordinal()); + } + } + + @Override + public boolean leave(Entity e, boolean logout) { + if (!logout && e instanceof Player) { + for (GodWarsFaction faction : GodWarsFaction.values()) { + e.removeAttribute("gwd:" + faction.name().toLowerCase() + "kc"); + } + e.removeAttribute("gwd:overlay"); + e.removeAttribute("gwd:altar-recharge"); + ((Player) e).getInterfaceManager().closeOverlay(); + } else if (logout) { + e.setLocation(e.getAttribute("cross_bridge_loc", e.getLocation())); + } + return true; + } + + @Override + public boolean death(Entity e, Entity killer) { + if (killer instanceof Player && e instanceof NPC) { + int npcId = ((NPC) e).getId(); + increaseKillcount((Player) killer, GodWarsFaction.forId(npcId), 1); + } + return false; + } + + @Override + public void locationUpdate(Entity e, Location last) { + if (e instanceof Player) { + Player player = (Player) e; + Component c = player.getInterfaceManager().getOverlay(); + boolean inZamorakFortress = ZAMORAK_FORTRESS.insideBorder(player.getLocation().getX(), player.getLocation().getY()); + if ((c == null || c.getId() != 598) && inZamorakFortress) { + openOverlay(player, 598); + } else if ((c == null || c.getId() != 597 && c.getId() != 601) && !inZamorakFortress) { + openOverlay(player, player.getInterfaceManager().isResizable() ? 597 : 601); + } + } + } + + @Override + public boolean interact(Entity e, Node target, Option option) { + if (target instanceof Scenery) { + Scenery object = (Scenery) target; + if (object.getId() == 26439) { + handleIceBridge((Player) e, object); + return true; + } + if (object.getId() == 26384) { + handleBigDoor((Player) e, object, true); + return true; + } + if (object.getId() == 26303) { + handlePillarGrapple((Player) e, object); + return true; + } + if (object.getId() == 26293) { + handleRopeClimb((Player) e, Location.create(2915, 3746, 0)); + return true; + } + if (object.getId() == 26295) { + handleRopeClimb((Player) e, Location.create(2915, 5300, 1)); + return true; + } + if (object.getId() == 26296) { + handleRopeTie((Player) e, 1); + return true; + } + if (object.getId() == 26297) { + if (object.getLocation().getY() == 5300) { + handleRopeClimb((Player) e, Location.create(2912, 5300, 2)); + } else { + handleRopeClimb((Player) e, Location.create(2920, 5276, 1)); + } + return true; + } + if (object.getId() == 26299) { + handleRopeClimb((Player) e, Location.create(2919, 5274, 0)); + return true; + } + if (object.getId() == 26300) { + handleRopeTie((Player) e, 2); + return true; + } + if (object.getId() == 26286) { + handleAltar((Player) e, option.getName(), GodWarsFaction.ZAMORAK, Location.create(2925, 5332, 2)); + return true; + } + if (object.getId() == 26287) { + handleAltar((Player) e, option.getName(), GodWarsFaction.SARADOMIN, Location.create(2908, 5265, 0)); + return true; + } + if (object.getId() == 26288) { + handleAltar((Player) e, option.getName(), GodWarsFaction.ARMADYL, Location.create(2839, 5295, 2)); + return true; + } + if (object.getId() == 26289) { + handleAltar((Player) e, option.getName(), GodWarsFaction.BANDOS, Location.create(2863, 5354, 2)); + return true; + } + if (object.getId() >= 26425 && object.getId() <= 26428) { + return handleChamberEntrance((Player) e, object); + } + } + return false; + } + + /** + * Handles praying on an altar. + * @param player The player. + * @param faction The god wars faction. + */ + private void handleAltar(Player player, String option, GodWarsFaction faction, Location destination) { + if (!option.equals("Pray-at")) { + player.getProperties().setTeleportLocation(destination); + return; + } + if (player.getAttribute("gwd:altar-recharge", 0L) > System.currentTimeMillis()) { + player.getPacketDispatch().sendMessage("The gods blessed you recently - this time they ignore your prayers."); + return; + } + if (player.inCombat()) { + player.getPacketDispatch().sendMessage("You can't use the altar while in combat."); + return; + } + if (player.getSkills().getPrayerPoints() >= player.getSkills().getStaticLevel(5)) { + player.getPacketDispatch().sendMessage("You already have full prayer points."); + return; + } + player.lock(2); + int total = player.getSkills().getStaticLevel(5) + faction.getProtectionItemAmount(player); + player.animate(new Animation(645)); + player.getSkills().decrementPrayerPoints(player.getSkills().getPrayerPoints() - total); + player.getPacketDispatch().sendMessage("You recharge your Prayer points."); + int time = 600_000; + player.setAttribute("/save:gwd:altar-recharge", System.currentTimeMillis() + time); + } + + /** + * Handles the rope tying. + * @param player The player. + * @param type The rock tying type. + */ + private void handleRopeTie(Player player, int type) { + if (player.getSkills().getStaticLevel(Skills.AGILITY) < 70) { + player.getPacketDispatch().sendMessage("You need an Agility level of 70 to enter here."); + return; + } + if (!player.getInventory().remove(new Item(954))) { + player.getPacketDispatch().sendMessage("You don't have a rope to tie on this rock."); + return; + } + setRopeSetting(player, type); + } + + /** + * Handles the climbing of a rope. + * @param player The player. + */ + private void handleRopeClimb(final Player player, final Location destination) { + player.lock(2); + player.animate(Animation.create(828)); + GameWorld.getPulser().submit(new Pulse(1, player) { + @Override + public boolean pulse() { + player.getProperties().setTeleportLocation(destination); + return true; + } + }); + } + + /** + * Handles the pillar grappling. + * @param player The player. + * @param object The pillar object. + */ + private void handlePillarGrapple(final Player player, final Scenery object) { + if (player.getSkills().getStaticLevel(Skills.RANGE) < 70) { + player.getPacketDispatch().sendMessage("You need a Range level of 70 to enter here."); + return; + } + if (player.getEquipment().getNew(EquipmentContainer.SLOT_ARROWS).getId() != 9419) { + player.getPacketDispatch().sendMessage("You need a mithril grapple to cross this."); + return; + } + RangeWeapon weapon = RangeWeapon.get(player.getEquipment().getNew(3).getId()); + if (weapon == null || weapon.getType() != 1) { + player.getPacketDispatch().sendMessage("You need to wield a crossbow to fire a mithril grapple."); + return; + } + player.lock(4); + if (player.getLocation().getY() < object.getLocation().getY()) { + ForceMovement.run(player, Location.create(2872, 5269, 2), Location.create(2872, 5279, 2), Animation.create(7081), 60).setCommenceSpeed(3); + } else { + ForceMovement.run(player, Location.create(2872, 5279, 2), Location.create(2872, 5269, 2), Animation.create(7081), 60).setCommenceSpeed(3); + } + player.graphics(new Graphics(1036, 96, 30)); + } + + /** + * Handles the big door. + * @param player The player. + * @param object The door object. + */ + private void handleBigDoor(final Player player, final Scenery object, boolean checkLocation) { + player.lock(4); + if (checkLocation && player.getLocation().getX() > object.getLocation().getX()) { + GameWorld.getPulser().submit(new MovementPulse(player, object.getLocation()) { + @Override + public boolean pulse() { + handleBigDoor(player, object, false); + return true; + } + }); + return; + } + if (player.getSkills().getStaticLevel(Skills.STRENGTH) < 70) { + player.getPacketDispatch().sendMessage("You need a Strength level of 70 to enter here."); + return; + } + if (!player.getInventory().contains(2347, 1)) { + player.getPacketDispatch().sendMessage("You need a hammer to bang on the door."); + return; + } + player.getPacketDispatch().sendMessage("You bang on the big door."); + player.animate(Animation.create(7002)); + GameWorld.getPulser().submit(new Pulse(1, player) { + @Override + public boolean pulse() { + object.getDefinition().getOptions()[1] = "open"; + SceneryDefinition.getOptionHandler(object.getId(), "open").handle(player, object, "open"); + return true; + } + }); + } + + /** + * Handles a chamber door opening reward. + * @param player The player. + * @param object The object. + * @return {@code True} if the player can't pass. + */ + private boolean handleChamberEntrance(Player player, Scenery object) { + Direction dir = Direction.get((object.getRotation() + 3) % 4); + if (dir.getStepX() != 0) { + if (player.getLocation().getX() == object.getLocation().transform(dir.getStepX(), 0, 0).getX()) { + player.getPacketDispatch().sendMessage("You can't leave through this door. The altar can teleport you out."); + return true; + } + } else if (player.getLocation().getY() == object.getLocation().transform(0, dir.getStepY(), 0).getY()) { + player.getPacketDispatch().sendMessage("You can't leave through this door. The altar can teleport you out."); + return true; + } + int index = object.getId() - 26425; + if (index < 2) { + index = 1 - index; + } + GodWarsFaction faction = GodWarsFaction.values()[index]; + String name = faction.name().toLowerCase(); + int required = 40; + if (player.getAttribute("gwd:" + name + "kc", 0) < required) { + player.getPacketDispatch().sendMessage("You need " + required + " " + StringUtils.formatDisplayName(name) + " kills to enter this."); + return true; + } + + if (DoorActionHandler.handleAutowalkDoor(player, object)) { + log(this.getClass(), Log.FINE, player.getUsername() + " entered " + faction.name() + " gwd boss room"); + increaseKillcount(player, faction, -required); + } + return true; + } + + /** + * Handles the ice bridge crossing. + * @param player The player. + * @param object The object. + */ + private void handleIceBridge(final Player player, final Scenery object) { + if (player.getSkills().getStaticLevel(Skills.HITPOINTS) < 70) { + player.getPacketDispatch().sendMessage("You need 70 Hitpoints to cross this bridge."); + return; + } + player.lock(7); + GameWorld.getPulser().submit(new Pulse(1, player) { + @Override + public boolean pulse() { + player.visualize(Animation.create(6988), Graphics.create(68)); + int diffY = 2; + if (object.getLocation().getY() == 5344) { + diffY = -2; + } + player.getProperties().setTeleportLocation(player.getLocation().transform(0, diffY, 0)); + player.getInterfaceManager().openOverlay(new Component(115)); + player.setAttribute("cross_bridge_loc", player.getLocation()); + GameWorld.getPulser().submit(new Pulse(1, player) { + int counter = 0; + + @Override + public boolean pulse() { + switch (counter++) { + case 4: + if (object.getLocation().getY() == 5333) { + player.getProperties().setTeleportLocation(Location.create(2885, 5345, 2)); + } else { + player.getProperties().setTeleportLocation(Location.create(2885, 5332, 2)); + } + player.setDirection(Direction.get((player.getDirection().toInteger() + 2) % 4)); + break; + case 5: + PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 0)); + player.getInterfaceManager().close(); + player.removeAttribute("cross_bridge_loc"); + player.getPacketDispatch().sendMessage("Dripping, you climb out of the water."); + if (player.getLocation().getY() > 5340) { + player.getSkills().decrementPrayerPoints(100.0); + player.getPacketDispatch().sendMessage("The extreme evil of this area leaves your Prayer drained."); + } + return true; + } + return false; + } + }); + return true; + } + }); + } + + /** + * Sets the kill count. + * @param p The player. + * @param faction The god wars faction. + * @param increase The amount to increase with. + */ + public void increaseKillcount(Player p, GodWarsFaction faction, int increase) { + if (faction == null) { + return; + } + String key = "gwd:" + faction.name().toLowerCase() + "kc"; + int amount = p.getAttribute(key, 0) + increase; + int componentId = p.getAttribute("gwd:overlay", 601); + int child = (componentId == 601 || componentId == 599) ? 6 : 7; + if (amount >= 4000) { + p.setAttribute("/save:" + key, 4000); + p.getPacketDispatch().sendString("Max", componentId, child + faction.ordinal()); + return; + } + p.setAttribute("/save:" + key, amount); + p.getPacketDispatch().sendString(Integer.toString(amount), componentId, child + faction.ordinal()); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ZoneBuilder.configure(this); + return this; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + /** + * The god wars factions. + * @author Emperor + */ + static enum GodWarsFaction { + ARMADYL(6222, 6246, 87, 11694, 11718, 11720, 11722, 12670, 12671, 14671), BANDOS(6260, 6283, 11061, 11696, 11724, 11726, 11728), SARADOMIN(6247, 6259, 1718, 2412, 2415, 2661, 2663, 2665, 2667, 3479, 3675, 3489, 3840, 4682, 6762, 8055, 10384, 10386, 10388, 10390, 10440, 10446, 10452, 10458, 10464, 10470, 11181, 11698, 11730), ZAMORAK(6203, 6221, 11716, 11700, 2414, 2417, 2653, 2655, 2657, 2659, 3478, 3674, 3841, 3842, 3852, 4683, 6764, 8056, 10368, 10370, 10372, 10374, 10444, 10450, 10456, 10460, 10468, 10474, 10776, 10786, 10790); + + /** + * The start NPC id. + */ + private final int startId; + + /** + * The end NPC id. + */ + private final int endId; + + /** + * The protection items. + */ + private final int[] protectionItems; + + /** + * Constructs a new {@code GodWarsFaction} {@code Object}. + * @param startId The start NPC id. + * @param endId The end NPC id. + * @param protectionItems The protection items for this faction. + */ + private GodWarsFaction(int startId, int endId, int... protectionItems) { + this.startId = startId; + this.endId = endId; + this.protectionItems = protectionItems; + } + + /** + * Gets the god wars faction for the given NPC id. + * @param npcId The NPC id. + * @return The faction for this NPC. + */ + public static GodWarsFaction forId(int npcId) { + for (GodWarsFaction faction : values()) { + if (npcId >= faction.getStartId() && npcId <= faction.getEndId()) { + return faction; + } + } + return null; + } + + /** + * Gets the amount of items the player is wearing to protect. + * @param player The player. + * @return The amount of protection items. + */ + public int getProtectionItemAmount(Player player) { + int count = 0; + for (Item item : player.getEquipment().toArray()) { + if (item != null) { + for (int id : protectionItems) { + if (item.getId() == id) { + count++; + } + } + } + } + return count; + } + + /** + * Gets the startId. + * @return The startId. + */ + public int getStartId() { + return startId; + } + + /** + * Gets the endId. + * @return The endId. + */ + public int getEndId() { + return endId; + } + + /** + * Gets the protectionItems. + * @return The protectionItems. + */ + public int[] getProtectionItems() { + return protectionItems; + } + } + +} diff --git a/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/IcePathZone.java b/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/IcePathZone.java new file mode 100644 index 0000000..5f399c7 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/trollheim/handlers/gwd/IcePathZone.java @@ -0,0 +1,91 @@ +package content.region.asgarnia.trollheim.handlers.gwd; + +import core.game.component.Component; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.ImpactHandler.HitsplatType; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneBuilder; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.tools.RandomFunction; + +/** + * The God Wars entrance zone monitor. + * @author Emperor + */ +@Initializable +public final class IcePathZone extends MapZone implements Plugin { + + /** + * Constructs a new {@code IcePathZone} {@code Object}. + */ + public IcePathZone() { + super("Ice path zone", true); + } + + @Override + public void configure() { + ZoneBorders border = new ZoneBorders(2821, 3712, 2940, 3839); + border.addException(new ZoneBorders(2821, 3712, 2838, 3745)); + register(border); + } + + @Override + public boolean enter(Entity e) { + if (e instanceof Player) { + final Player player = (Player) e; + player.getInterfaceManager().openOverlay(new Component(482)); // TODO: + // find + // the + // real + // one + Pulse pulse = new Pulse(10, player) { + @Override + public boolean pulse() { + if (player.getLocks().isMovementLocked()) { + return false; + } + player.getSettings().updateRunEnergy(100); + player.getImpactHandler().manualHit(player, 1, HitsplatType.NORMAL); + int skill = RandomFunction.randomize(7); + if (skill == 3 || skill == 5) { + skill++; + } + player.getSkills().updateLevel(skill, -1, 0); + return false; + } + }; + player.setAttribute("ice_path_pulse", pulse); + GameWorld.getPulser().submit(pulse); + } + return true; + } + + @Override + public boolean leave(Entity e, boolean logout) { + if (e instanceof Player) { + ((Player) e).getInterfaceManager().closeOverlay(); + Pulse pulse = e.getAttribute("ice_path_pulse"); + if (pulse != null) { + pulse.stop(); + e.removeAttribute("ice_path_pulse"); + } + } + return true; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ZoneBuilder.configure(this); + return this; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } +} diff --git a/Server/src/main/content/region/asgarnia/trollweiss/handlers/TrollweissListeners.kt b/Server/src/main/content/region/asgarnia/trollweiss/handlers/TrollweissListeners.kt new file mode 100644 index 0000000..55cf634 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/trollweiss/handlers/TrollweissListeners.kt @@ -0,0 +1,38 @@ +package content.region.asgarnia.trollweiss.handlers + +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.game.world.map.Location +import org.rs09.consts.Scenery + +class TrollweissListeners : InteractionListener { + override fun defineListeners() { + // Keldagrim side tunnel to trollweiss mountain + on(Scenery.TUNNEL_5012, IntType.SCENERY, "enter") { player, _ -> + player.properties.teleportLocation = Location.create(2799, 10134, 0) + return@on true + } + on(Scenery.TUNNEL_5013, IntType.SCENERY, "enter") { player, _ -> + player.properties.teleportLocation = Location.create(2796, 3719, 0) + return@on true + } + // Trollheim north to trollweiss dungeon + on(Scenery.CAVE_ENTRANCE_5007, IntType.SCENERY, "enter") { player, _ -> + player.properties.teleportLocation = Location.create(2803, 10187, 0) + return@on true + } + on(Scenery.CAVE_EXIT_32743, IntType.SCENERY, "exit") { player, _ -> + player.properties.teleportLocation = Location.create(2822, 3744, 0) + return@on true + } + // Keldagrim side tunnel to trollweiss mountain + on(Scenery.CREVASSE_33185, IntType.SCENERY, "enter") { player, _ -> + player.properties.teleportLocation = Location.create(2778, 3869, 0) + return@on true + } + on(Scenery.TUNNEL_5009, IntType.SCENERY, "enter") { player, _ -> + player.properties.teleportLocation = Location.create(2772, 10232, 0) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/asgarnia/whitewolfmountain/WhiteWolfMountainListener.kt b/Server/src/main/content/region/asgarnia/whitewolfmountain/WhiteWolfMountainListener.kt new file mode 100644 index 0000000..4e84f83 --- /dev/null +++ b/Server/src/main/content/region/asgarnia/whitewolfmountain/WhiteWolfMountainListener.kt @@ -0,0 +1,64 @@ +package content.region.asgarnia.whitewolfmountain + +import content.data.skill.SkillingTool +import core.api.* +import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength +import core.game.node.entity.skill.Skills +import org.rs09.consts.Scenery + +class WhiteWolfMountainListener : InteractionListener { + override fun defineListeners() { + + on(Scenery.ROCK_SLIDE_2634, SCENERY, "investigate") { player, node -> + // dtWpLjw4X0A + sendMessage(player, "These rocks contain nothing interesting.") + sendMessage(player, "They are just in the way.") + return@on true + } + + on(Scenery.ROCK_SLIDE_2634, SCENERY, "mine") { player, node -> + val pickaxe = SkillingTool.getPickaxe(player) + val rockScenery = node as core.game.node.scenery.Scenery + if (getDynLevel(player, Skills.MINING) < 50) { + sendMessage(player, "You need a mining level of 50 to mine this rock slide.") + return@on true + } + if (pickaxe == null) { + sendMessage(player, "You do not have a pickaxe to use.") + return@on true + } + animate(player, pickaxe.animation) + lock(player, 6) + queueScript(player, 0, QueueStrength.SOFT) { stage: Int -> + when (stage) { + // Scenery.ROCKSLIDE_471 is the original rock. + 0 -> { + replaceScenery(rockScenery, Scenery.ROCKSLIDE_472, 2) + return@queueScript delayScript(player, 2) + } + + 1 -> { + replaceScenery(rockScenery, Scenery.ROCKSLIDE_473, 2) + return@queueScript delayScript(player, 2) + } + + 2 -> { + replaceScenery(rockScenery, 476, 2) + player.walkingQueue.reset() + if (player.location.x < 2839) { + player.walkingQueue.addPath(2840, 3517) + } else { + player.walkingQueue.addPath(2837, 3518) + } + return@queueScript delayScript(player, 2) + } + + else -> return@queueScript stopExecuting(player) + } + } + return@on true + } + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/alkharid/dialogue/AablaDialogue.kt b/Server/src/main/content/region/desert/alkharid/dialogue/AablaDialogue.kt new file mode 100644 index 0000000..0330f7f --- /dev/null +++ b/Server/src/main/content/region/desert/alkharid/dialogue/AablaDialogue.kt @@ -0,0 +1,48 @@ +package content.region.desert.alkharid.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +/** + * @author bushtail + */ + +@Initializable +class AablaDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player?): DialoguePlugin { + return AablaDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + playerl(FacialExpression.FRIENDLY, "Hi!").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage) { + 0 -> showTopics( + Topic("Can you heal me?", AlKharidHealDialogue(true)), + Topic("Do you see a lot of injured fighters?", 101), + Topic("Do you come here often?", 201) + ) + + 101 -> npcl(FacialExpression.FRIENDLY, "I work here, so yes!").also { stage = END_DIALOGUE } + + 201 -> npcl(FacialExpression.HALF_THINKING, "Yes I do. Thankfully we can cope with almost anything. Jaraah really is a wonderful surgeon, his methods are a little unorthodox but he gets the job done.").also { stage++ } + 202 -> npcl(FacialExpression.HALF_GUILTY, "I shouldn't tell you this but his nickname is 'The Butcher'.").also { stage++ } + 203 -> playerl(FacialExpression.HALF_WORRIED, "That's reassuring.").also { stage = END_DIALOGUE } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.AABLA_959) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/alkharid/dialogue/AlKharidHealListener.kt b/Server/src/main/content/region/desert/alkharid/dialogue/AlKharidHealListener.kt new file mode 100644 index 0000000..b7c0356 --- /dev/null +++ b/Server/src/main/content/region/desert/alkharid/dialogue/AlKharidHealListener.kt @@ -0,0 +1,53 @@ +package content.region.desert.alkharid.dialogue + +import core.api.* +import core.game.node.entity.skill.Skills +import org.rs09.consts.Animations +import org.rs09.consts.NPCs +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.tools.END_DIALOGUE + +/** + * @author bushtail + */ + +class AlKharidHealListener : InteractionListener { + override fun defineListeners() { + on(getIds(), IntType.NPC, "heal") { player, node -> + openDialogue(player, AlKharidHealDialogue(false), node.asNpc()) + return@on true + } + } + + fun getIds() : IntArray { + return intArrayOf( + NPCs.AABLA_959, + NPCs.SABREEN_960, + NPCs.SURGEON_GENERAL_TAFANI_961, + NPCs.JARAAH_962 + ) + } +} + +class AlKharidHealDialogue(val skipFirst: Boolean) : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + if (stage == 0 && skipFirst) stage++ + when(stage) { + 0 -> playerl(FacialExpression.ASKING, "Can you heal me?").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "Of course!").also { stage++ } + 2 -> { + animate(npc!!, Animations.HUMAN_PICKPOCKETING_881) + if(player!!.skills.lifepoints < getStatLevel(player!!, Skills.HITPOINTS)) { + player!!.skills.heal(21) + npcl(FacialExpression.FRIENDLY, "There you go!") + } else { + npcl(FacialExpression.FRIENDLY, "You look healthy to me!") + } + stage = END_DIALOGUE + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/alkharid/dialogue/AlKharidShopKeeperDialogue.kt b/Server/src/main/content/region/desert/alkharid/dialogue/AlKharidShopKeeperDialogue.kt new file mode 100644 index 0000000..8035812 --- /dev/null +++ b/Server/src/main/content/region/desert/alkharid/dialogue/AlKharidShopKeeperDialogue.kt @@ -0,0 +1,48 @@ +package content.region.desert.alkharid.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +/** + * @author bushtail + * "Henceforth, you shall be called... Craig." + */ + +@Initializable +class AlKharidShopKeeperDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player?): DialoguePlugin { + return AlKharidShopKeeperDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npcl(FacialExpression.HALF_ASKING, "Can I help you at all?") + stage = 100 + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage) { + 100 -> options("Yes, please. What are you selling?", "How should I use your shop?", "No, thanks.").also { stage++ } + 101 -> when(buttonId) { + 1 -> { + stage = END_DIALOGUE + npc.openShop(player) + } + 2 -> playerl(FacialExpression.ASKING, "How should I use your shop?").also { stage = 201 } + 3 -> playerl(FacialExpression.NEUTRAL, "No, thanks.").also { stage = END_DIALOGUE } + } + 201 -> npcl(FacialExpression.FRIENDLY, "I'm glad you ask! You can buy as many of the items stocked as you wish. You can also sell most items to the shop.").also { stage = END_DIALOGUE } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.SHOPKEEPER_524, NPCs.SHOP_ASSISTANT_525) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/alkharid/dialogue/AlTheCamelDialogue.java b/Server/src/main/content/region/desert/alkharid/dialogue/AlTheCamelDialogue.java new file mode 100644 index 0000000..d8e83e2 --- /dev/null +++ b/Server/src/main/content/region/desert/alkharid/dialogue/AlTheCamelDialogue.java @@ -0,0 +1,76 @@ +package content.region.desert.alkharid.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.tools.RandomFunction; + +/** + * Represents the dialogue plugin used for al the camel. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class AlTheCamelDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code AlTheCamelDialogue} {@code Object}. + */ + public AlTheCamelDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code AlTheCamelDialogue} {@code Object}. + * @param player the player. + */ + public AlTheCamelDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new AlTheCamelDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + int rand = RandomFunction.random(1, 3); + switch (rand) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Mmm... Looks like that camel would make a nice kebab."); + stage = 0; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "If I go near that camel, it'll probably bite my hand off."); + stage = 0; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Mmm... Looks like that camel would make a nice kebab."); + stage = 0; + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + player.getPacketDispatch().sendMessage("The camel tries to stomp on your foot, but you pull it back quickly."); + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 2809 }; + } +} diff --git a/Server/src/main/content/region/desert/alkharid/dialogue/AliMorrisaneDialogue.kt b/Server/src/main/content/region/desert/alkharid/dialogue/AliMorrisaneDialogue.kt new file mode 100644 index 0000000..a0bc89b --- /dev/null +++ b/Server/src/main/content/region/desert/alkharid/dialogue/AliMorrisaneDialogue.kt @@ -0,0 +1,76 @@ +package content.region.desert.alkharid.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +import core.api.* +import content.data.Quests + +/** + * Represents the ali morrisane dialogue. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +class AliMorrisaneDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun newInstance(player: Player?): DialoguePlugin { + return AliMorrisaneDialogue(player) + } + + override fun open(vararg args: Any): Boolean { + npc = args[0] as NPC + npcl(FacialExpression.FRIENDLY, "Good day and welcome back to Al Kharid.") + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> playerl(FacialExpression.FRIENDLY, "Hello to you too.").also { stage = 1 } + 1 -> npcl(FacialExpression.ASKING, "My name is Ali Morrisane - the greatest salesman in the world.").also { stage = 2 } + 2 -> options("If you are, then why are you still selling goods from a stall?", "So what are you selling then?").also { stage = 3 } + 3 -> when (buttonId) { + 1 -> playerl(FacialExpression.ASKING, "If you are, then why are you still selling goods from a stall?").also { stage = 10 } + 2 -> { + end() + if (!hasRequirement(player, Quests.THE_FEUD)) + return true + npc.openShop(player) + } + } + 10 -> npcl(FacialExpression.FRIENDLY, "Well one can only do and sell so much. If I had more staff I'd be able to sell more").also { stage = 11 } + 11 -> npcl(FacialExpression.FRIENDLY,"rather than wasting my time on menial things I could get on with selling sand to the Bedabin and useless tourist trinkets to everyone.").also { stage = 12 } + 12 -> options("I'm far too busy - adventuring is a full time job you know.", "I'd like to help you but....").also { stage = 13 } + 13 -> when (buttonId) { + 1 -> playerl(FacialExpression.FRIENDLY, "I'm far too busy - adventuring is a full time job you know.").also { stage = 16 } + 2 -> playerl(FacialExpression.FRIENDLY, "I'd like to help you but.....").also { stage = 14 } + } + 14 -> npcl(FacialExpression.FRIENDLY, "Yes I know, I know - the life of a shop keeper isn't slaying dragon and wooing damsels but it has its charms").also { stage = 15 } + 15 -> end() + 16 -> npcl(FacialExpression.FRIENDLY,"No problem my friend, perhaps another time.").also { stage = 17 } + 17 -> npcl(FacialExpression.FRIENDLY, "Anyway, have a look at my wares.").also { stage = 18 } + 18 -> options("No, I'm really too busy.", "Okay.").also { stage = 19 } + 19 -> when (buttonId) { + 1 -> { + end() + } + 2 -> { + end() + if (!hasRequirement(player, Quests.THE_FEUD)) + return true + npc.openShop(player) + } + } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.ALI_MORRISANE_1862) + } +} + diff --git a/Server/src/main/content/region/desert/alkharid/dialogue/AliTheFarmerDialogue.kt b/Server/src/main/content/region/desert/alkharid/dialogue/AliTheFarmerDialogue.kt new file mode 100644 index 0000000..46a0e02 --- /dev/null +++ b/Server/src/main/content/region/desert/alkharid/dialogue/AliTheFarmerDialogue.kt @@ -0,0 +1,64 @@ +package content.region.desert.alkharid.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class AliTheFarmerDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun newInstance(player: Player?): DialoguePlugin { + return AliTheFarmerDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + playerl(FacialExpression.FRIENDLY,"Hello there!") + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> npcl(FacialExpression.FRIENDLY,"Oh, er, hello. What do you want?").also { stage++ } + 1 -> options("What can you tell me about Al Kharid?", "So, what do you do here?", "I hear you work for Ali Morrisane...", "I hear you've been threatening the other shopkeepers.").also { stage++ } + 2 -> when(buttonId){ + 1 -> playerl(FacialExpression.ASKING, "What can you tell me about Al Kharid?").also { stage = 10 } + 2 -> playerl(FacialExpression.ASKING, "So, what do you do here?").also { stage = 20 } + 3 -> playerl(FacialExpression.ASKING, "I hear you work for Ali Morrisane...").also { stage = 30 } + 4 -> playerl(FacialExpression.ASKING, "I hear you've been threatening the other shopkeepers.").also { stage = 40 } + } + 10 -> npcl(FacialExpression.FRIENDLY,"There's not much farming land around here. Only that little patch outside.").also { stage++ } + 11 -> playerl(FacialExpression.ASKING,"Can you give me any advice on farming here in the desert?").also { stage++ } + 12 -> npcl(FacialExpression.FRIENDLY,"Like I said, I only know about cactuses...").also { stage++ } + 13 -> playerl(FacialExpression.FRIENDLY,"Just tell me about cactuses, then.").also { stage++ } + 14 -> npcl(FacialExpression.FRIENDLY,"First you have to weed the patch using a rake.").also { stage++ } + 15 -> playerl(FacialExpression.ASKING,"Can you give me any other advice?").also { stage++ } + 16 -> npcl(FacialExpression.FRIENDLY,"Not really. I've not done much farming recently.").also { stage++ } + 17 -> playerl(FacialExpression.ASKING,"Well, can you at least sell me any gardening tools or seeds?").also { stage++ } + 18 -> npcl(FacialExpression.GUILTY,"Sorry. They haven't been delivered yet.").also { stage = 1 } + 20 -> npcl(FacialExpression.FRIENDLY,"I'm going to set up a shop selling farming implements. That patch out there may be small, but it's all we've got.").also { stage = 11 } + 30 -> npcl(FacialExpression.FRIENDLY,"Yes, he bought these tents and had them put up for us. He says he'll also get our goods in, so we can start selling them soon.").also { stage++ } + 31 -> npcl(FacialExpression.FRIENDLY,"I only know how to farm cactuses, so this spot is perfect.").also { stage++ } + 32 -> playerl(FacialExpression.THINKING,"Maybe I should talk to him...").also { stage++ } + 33 -> npcl(FacialExpression.FRIENDLY,"Of course. He's always happy to talk to possible business partners.").also { stage = 1 } + 40 -> npcl(FacialExpression.FRIENDLY,"Now why would you think that?").also { stage++ } + 41 -> playerl(FacialExpression.FRIENDLY,"One of the shopkeepers told they were threatened by a man with a rake...").also { stage++ } + 42 -> npcl(FacialExpression.FRIENDLY,"Those people just don't want us to succeed. Don't listen to them!").also { stage = 99 } + 99 -> { + end() + } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.ALI_THE_FARMER_2821) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/alkharid/dialogue/AliTheGuard.kt b/Server/src/main/content/region/desert/alkharid/dialogue/AliTheGuard.kt new file mode 100644 index 0000000..7704e0a --- /dev/null +++ b/Server/src/main/content/region/desert/alkharid/dialogue/AliTheGuard.kt @@ -0,0 +1,64 @@ +package content.region.desert.alkharid.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class AliTheGuard(player: Player? = null) : DialoguePlugin(player){ + + override fun newInstance(player: Player?): DialoguePlugin { + return AliTheGuard(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + playerl(FacialExpression.FRIENDLY,"Hello there!") + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> npcl(FacialExpression.ANNOYED,"I'm working. What do you have to say that's so urgent?").also { stage++ } + 1 -> options("What can you tell me about Al Kharid?", "So, what do you do here?", "I hear you work for Ali Morrisane...", "I hear you've been threatening the other shopkeepers.").also { stage++ } + 2 -> when(buttonId){ + 1 -> playerl(FacialExpression.ASKING, "What can you tell me about Al Kharid?").also { stage = 10 } + 2 -> playerl(FacialExpression.ASKING, "So, what do you do here?").also { stage = 20 } + 3 -> playerl(FacialExpression.ASKING, "I hear you work for Ali Morrisane...").also { stage = 30 } + 4 -> playerl(FacialExpression.ASKING, "I hear you've been threatening the other shopkeepers.").also { stage = 40 } + } + 10 -> npcl(FacialExpression.FRIENDLY,"There's a lot of space here. More open space than back home.").also { stage++ } + 11 -> playerl(FacialExpression.ASKING,"So where is back home?").also { stage++ } + 12 -> npcl(FacialExpression.FRIENDLY,"Pollnivneach. It's a town to the south of the Shantay Pass.").also { stage = 1 } + 20 -> npcl(FacialExpression.ANNOYED,"I'm on guard duty. Making sure nobody tries to steal anything from the house and tents in the middle of town.").also { stage++ } + 21 -> playerl(FacialExpression.ASKING,"Why are you only guarding those buildings?").also { stage++ } + 22 -> npcl(FacialExpression.SUSPICIOUS,"That's all I've been hired to guard.").also { stage = 1 } + 30 -> npcl(FacialExpression.FRIENDLY,"Yeah, he hired me. He owns this house and these two tents, too.").also { stage++ } + 31 -> playerl(FacialExpression.HALF_ASKING,"Is the work good?").also { stage++ } + 32 -> npcl(FacialExpression.FRIENDLY,"It pays better than back home.").also { stage++ } + 33 -> playerl(FacialExpression.ASKING,"Why, what did you do back home?").also { stage++ } + 34 -> npcl(FacialExpression.SUSPICIOUS,"Never you mind.").also { stage++ } + 35 -> npcl(FacialExpression.FRIENDLY,"But Ali Morrisane pays us well, at least.").also { stage++ } + 36 -> playerl(FacialExpression.ASKING,"Maybe I should talk to him...").also { stage++ } + 37 -> npcl(FacialExpression.FRIENDLY,"Why not? He always likes to meet potential business partners.").also { stage = 1 } + 40 -> npcl(FacialExpression.ANNOYED,"So? They talk too much.").also { stage++ } + 41 -> playerl(FacialExpression.HALF_ASKING,"You're not going to deny it?").also { stage++ } + 42 -> npcl(FacialExpression.LOUDLY_LAUGHING,"Why bother? None of them can fight back, after all.").also { stage = 99 } + 99 -> { + end() + } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.ALI_THE_GUARD_2823) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/alkharid/dialogue/AliTheLeafletDropperDialogue.kt b/Server/src/main/content/region/desert/alkharid/dialogue/AliTheLeafletDropperDialogue.kt new file mode 100644 index 0000000..3ff317b --- /dev/null +++ b/Server/src/main/content/region/desert/alkharid/dialogue/AliTheLeafletDropperDialogue.kt @@ -0,0 +1,71 @@ +package content.region.desert.alkharid.dialogue + +import core.api.addItem +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +/** + * @author bushtail + * Converts AliTheLeafletDropper.java with a Kotlin implementation + */ + +@Initializable +class AliTheLeafletDropperDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun newInstance(player: Player?): DialoguePlugin { + return AliTheLeafletDropperDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npcl(FacialExpression.CHILD_NORMAL, "I don't have the time to talk right now! Ali Morrisane is paying me to hand out these flyers.") + stage = 100 + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage) { + 100 -> options("Who is Ali Morissane?", "What are the flyers for?", "What is there to do round here, boy?").also { stage++ } + 101 -> when(buttonId) { + 1 -> playerl(FacialExpression.ASKING, "Who is Ali Morissane?").also{ stage = 201 } + 2 -> playerl(FacialExpression.ASKING, "What are the flyers for?").also { stage = 301 } + 3 -> playerl(FacialExpression.ASKING, "What is there to do round here, boy?").also { stage = 401 } + } + 201 -> npcl(FacialExpression.CHILD_FRIENDLY, "Ali Morrisane is the greatest merchant in the east!").also { stage++ } + 202 -> playerl(FacialExpression.HALF_ASKING, "Were you paid to say that?").also { stage++ } + 203 -> npcl(FacialExpression.CHILD_LOUDLY_LAUGHING, "Of course I was! You can find him on the north edge of town.").also { stage = END_DIALOGUE } + 301 -> npcl(FacialExpression.CHILD_THINKING, "Well, Ali Morrisane isn't too popular with the other traders in Al Kharid, mainly because he's from Pollnivneach and they feel he has no business trading in their town.").also { stage++ } + 302 -> npcl(FacialExpression.CHILD_FRIENDLY, "I think they're just sour because he's better at making money than them.").also { stage++ } + 303 -> npcl(FacialExpression.CHILD_FRIENDLY, "The flyer advertises the different shops you can find in Al Kharid.").also { stage++ } + 304 -> npcl(FacialExpression.CHILD_THINKING, "It also entitles you to money off your next purchase in any of the shops listed on it. It's Ali's way of getting on the good side of the traders.").also { stage++ } + 305 -> playerl(FacialExpression.ASKING, "Which shops?").also { + if(player.inventory.containItems(Items.AL_KHARID_FLYER_7922)) { + npcl(FacialExpression.CHILD_SUSPICIOUS, "Are you trying to be funny or has age turned your brain to mush? Look at the flyer you already have!").also { stage = END_DIALOGUE } + } else { + if(addItem(player, Items.AL_KHARID_FLYER_7922)) { + npcl(FacialExpression.CHILD_FRIENDLY, "Here! Take one and let me get back to work.").also { stage = END_DIALOGUE } + } else { + end() + } + } + } + 401 -> npcl(FacialExpression.CHILD_NORMAL, "I'm very busy, so listen carefully! I shall say this only once.").also { stage++ } + 402 -> npcl(FacialExpression.CHILD_THINKING, "Apart from a busy and wonderous market place in Al Kharid to the south, there is the Duel Arena to the south-east where you can challenge other players to a fight.").also { stage++ } + 403 -> npcl(FacialExpression.CHILD_NORMAL, "If you're here to make money, there is a mine to the south.").also { stage++ } + 404 -> npcl(FacialExpression.CHILD_SUSPICIOUS, "Watch out for scorpions though, they'll take a pop at you if you go too near them. To avoid them just follow the western fence as you travel south.").also { stage++ } + 405 -> npcl(FacialExpression.CHILD_FRIENDLY, "If you're in the mood for a little rest and relaxation, there are a couple of nice fishing spots south of the town.").also { stage++ } + 406 -> playerl(FacialExpression.FRIENDLY, "Thanks for the help!").also { stage = END_DIALOGUE } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.ALI_THE_LEAFLET_DROPPER_3680) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/alkharid/dialogue/AliTheLeafletDropperListener.kt b/Server/src/main/content/region/desert/alkharid/dialogue/AliTheLeafletDropperListener.kt new file mode 100644 index 0000000..0f662d9 --- /dev/null +++ b/Server/src/main/content/region/desert/alkharid/dialogue/AliTheLeafletDropperListener.kt @@ -0,0 +1,47 @@ +package content.region.desert.alkharid.dialogue + +import core.api.addItem +import core.api.openDialogue +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.npc.NPC +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +/** + * @author bushtail + */ + +class AliTheLeafletDropperListener : InteractionListener { + override fun defineListeners() { + on(NPCs.ALI_THE_LEAFLET_DROPPER_3680, IntType.NPC, "Take-flyer") { player, node -> + if(player.inventory.containItems(Items.AL_KHARID_FLYER_7922)) { + openDialogue(player, DropperDialogue(2), node as NPC) + } else { + if(addItem(player, Items.AL_KHARID_FLYER_7922)) { + openDialogue(player, DropperDialogue(1), node as NPC) + } else { + return@on false + } + } + return@on true + } + } + +} + +class DropperDialogue(val it : Int) : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when(it) { + 1 -> when(stage) { + 0 -> npcl(FacialExpression.CHILD_NORMAL, "Here! Take one and let me get back to work.").also { stage++ } + 1 -> npcl(FacialExpression.CHILD_THINKING, "I still have hundreds of these flyers to hand out. I wonder if Ali would notice if I quietly dumped them somewhere?").also { stage = END_DIALOGUE } + } + 2 -> npcl(FacialExpression.CHILD_SUSPICIOUS, "Are you trying to be funny or has age turned your brain to mush? You already have a flyer!").also { stage = END_DIALOGUE } + } + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/alkharid/dialogue/AliTheSmithDialogue.kt b/Server/src/main/content/region/desert/alkharid/dialogue/AliTheSmithDialogue.kt new file mode 100644 index 0000000..ff79c3d --- /dev/null +++ b/Server/src/main/content/region/desert/alkharid/dialogue/AliTheSmithDialogue.kt @@ -0,0 +1,67 @@ +package content.region.desert.alkharid.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class AliTheSmithDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun newInstance(player: Player?): DialoguePlugin { + return AliTheSmithDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + playerl(FacialExpression.FRIENDLY,"Hello there!") + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> npcl(FacialExpression.FRIENDLY,"You seem rather cheerful. Is there anything you're after?").also { stage++ } + 1 -> options("What can you tell me about Al Kharid?", "So, what do you do here?", "I hear you work for Ali Morrisane...", "I hear you've been threatening the other shopkeepers.").also { stage++ } + 2 -> when(buttonId){ + 1 -> playerl(FacialExpression.ASKING, "What can you tell me about Al Kharid?").also { stage = 10 } + 2 -> playerl(FacialExpression.ASKING, "So, what do you do here?").also { stage = 20 } + 3 -> playerl(FacialExpression.ASKING, "I hear you work for Ali Morrisane...").also { stage = 30 } + 4 -> playerl(FacialExpression.HALF_ASKING, "I hear you've been threatening the other shopkeepers.").also { stage = 40 } + } + + 10 ->npcl(FacialExpression.FRIENDLY,"Well, it's hot and full of sand.").also { stage++ } + 11 ->playerl(FacialExpression.ASKING,"Anything else?").also { stage++ } + 12 ->npcl(FacialExpression.FRIENDLY,"Don't ask me, I'm not from around here.").also { stage++ } + 13 ->playerl(FacialExpression.HALF_ASKING,"So where are you from?").also { stage++ } + 14 ->npcl(FacialExpression.HALF_GUILTY,"A town to the south of the Shantay Pass, called Pollnivneach.").also { stage = 1 } + + 20 ->npcl(FacialExpression.SAD,"Not very much, at the moment. I came from further south to set up a smithy here...").also { stage++ } + 21 ->npcl(FacialExpression.SAD,"...but we still haven't set up the shops, so we have no customers yet.").also { stage = 1 } + + 30 -> npcl(FacialExpression.FRIENDLY,"Yes, he's the one who persuaded us to come here.").also { stage++ } + 31 -> npcl(FacialExpression.HALF_GUILTY,"He said we'd have lots of customers once we set up our shops, and all he asks for is a cut of the profits.").also { stage++ } + 32 -> playerl(FacialExpression.ASKING,"Maybe I should talk to him...").also { stage++ } + 33 -> npcl(FacialExpression.FRIENDLY,"Of course. He's always happy to talk to possible business partners.").also { stage = 1 } + + 40 -> npcl(FacialExpression.SUSPICIOUS,"What? Who's spreading that rumour?").also { stage++ } + 41 -> playerl(FacialExpression.THINKING,"Well, one of the shopkeepers told me a man with a large hammer came to threaten them.").also { stage++ } + 42 -> npcl(FacialExpression.SUSPICIOUS,"Don't pay any attention to those people.").also { stage++ } + 43 -> npcl(FacialExpression.LAUGH,"They're just worried that they'll lose money when we open our shops.").also { stage = 99 } + 99 -> { + end() + } + + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.ALI_THE_SMITH_2820) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/alkharid/dialogue/BorderGuardDialogue.java b/Server/src/main/content/region/desert/alkharid/dialogue/BorderGuardDialogue.java new file mode 100644 index 0000000..4331b93 --- /dev/null +++ b/Server/src/main/content/region/desert/alkharid/dialogue/BorderGuardDialogue.java @@ -0,0 +1,160 @@ +package content.region.desert.alkharid.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.global.action.DoorActionHandler; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.game.world.map.RegionManager; +import content.data.Quests; + +/** + * Represents the border guard dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class BorderGuardDialogue extends DialoguePlugin { + + /** + * Represents the array of object locations. + */ + private static final Location[] LOCATIONS = new Location[] { new Location(3267, 3228, 0), new Location(3267, 3229, 0), new Location(3268, 3228, 0), new Location(3268, 3228, 0), Location.create(3267, 3227, 0), Location.create(3268, 3227, 0), new Location(3268, 3227, 0) }; + + /** + * Represents the coins item. + */ + private static final Item COINS = new Item(995, 10); + + /** + * Represents the door scenery. + */ + private Scenery door; + + /** + * Constructs a new {@code BorderGuardDialogue} {@code Object}. + */ + public BorderGuardDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code BorderGuardDialogue} {@code Object}. + * @param player the player. + */ + public BorderGuardDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new BorderGuardDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + if (args.length == 2) { + door = ((Scenery) args[1]); + } + if (player.getLocation().equals(LOCATIONS[0]) || player.getLocation().equals(LOCATIONS[1]) || player.getLocation().equals(LOCATIONS[2])) { + door = RegionManager.getObject(LOCATIONS[3]); + } + if (player.getLocation().equals(LOCATIONS[4]) || player.getLocation().equals(LOCATIONS[5])) { + door = RegionManager.getObject(LOCATIONS[6]); + } + if (door == null) { + end(); + return true; + } + player("Can I come through this gate?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + if (player.getQuestRepository().getQuest(Quests.PRINCE_ALI_RESCUE).getStage(player) > 50) { + npc("You may pass for free, you are a friend of Al-Kharid."); + stage = 100; + } else { + npc("You must pay a toll of 10 gold coins to pass."); + stage = 1; + } + break; + case 1: + options("Okay, I'll pay.", "Who does my money go to?", "No thanks, I'll walk around."); + stage = 2; + break; + case 2: + switch (buttonId) { + case 1: + end(); + if (!player.getInventory().containsItem(COINS)) { + end(); + return true; + } + if (player.getInventory().remove(COINS)) { + DoorActionHandler.handleAutowalkDoor(player, door); + } else { + player.getPacketDispatch().sendMessage("You need 10 gold coins to pay the toll."); + } + break; + case 2: + player("Who does my money go to?"); + stage = 20; + break; + case 3: + npc("As you wish. Don't go too near the scorpions."); + stage = 23; + break; + + } + break; + case 20: + npc("The money goes to the city of Al-Kharid.", "Will you pay the toll?"); + stage = 21; + break; + case 21: + options("Okay, I'll pay.", "No thanks, I'll walk around."); + stage = 22; + break; + case 22: + switch (buttonId) { + case 1: + end(); + if (player.getInventory().remove(new Item(995, 10))) { + DoorActionHandler.handleAutowalkDoor(player, door); + } else { + player.getPacketDispatch().sendMessage("You need 10 gold coins to pay the toll."); + } + break; + case 2: + npc("As you wish. Don't go too near the scorpions."); + stage = 23; + break; + } + break; + case 23: + end(); + break; + case 100: + end(); + DoorActionHandler.handleAutowalkDoor(player, door); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 925 }; + } +} diff --git a/Server/src/main/content/region/desert/alkharid/dialogue/DommikDialogue.kt b/Server/src/main/content/region/desert/alkharid/dialogue/DommikDialogue.kt new file mode 100644 index 0000000..75d9cd4 --- /dev/null +++ b/Server/src/main/content/region/desert/alkharid/dialogue/DommikDialogue.kt @@ -0,0 +1,47 @@ +package content.region.desert.alkharid.dialogue + +import core.api.sendDialogueOptions +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * Handles the DommikDialogue dialogue. + * @author 'Vexia + */ +@Initializable +class DommikDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player?): DialoguePlugin { + return DommikDialogue(player) + } + + override fun open(vararg args: Any): Boolean { + npc = args[0] as NPC + npcl(FacialExpression.HAPPY, "Would you like to buy some Crafting equipment?") + stage = 0 + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> options("No, thanks, I've got all the Crafting equipment I need.", "Let's see what you've got, then.").also { stage = 1 } + 1 -> when (buttonId) { + 1 -> playerl(FacialExpression.FRIENDLY, "No, thanks, I've got all the Crafting equipment I need.").also { stage = 2 } + 2 -> { + end() + npc.openShop(player) + } + } + 2 -> npcl(FacialExpression.FRIENDLY, "Okay. Fare well on your travels.").also { stage = 3 } + 3 -> end() + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.DOMMIK_545) + } +} diff --git a/Server/src/main/content/region/desert/alkharid/dialogue/EllisDialogue.kt b/Server/src/main/content/region/desert/alkharid/dialogue/EllisDialogue.kt new file mode 100644 index 0000000..6dc4a34 --- /dev/null +++ b/Server/src/main/content/region/desert/alkharid/dialogue/EllisDialogue.kt @@ -0,0 +1,75 @@ +package content.region.desert.alkharid.dialogue + +import content.global.skill.crafting.TanningProduct +import core.api.inInventory +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.node.entity.npc.NPC +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +/** + * Handles Ellis's dialogue. + */ +@Initializable +class EllisDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npcl(FacialExpression.FRIENDLY, "Greetings friend. I am a manufacturer of leather.").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> { + var hasHides = false + + for (tanningProduct in TanningProduct.values()) { + if (inInventory(player, tanningProduct.item)) { + hasHides = true + break + } + } + + if(hasHides) { + npcl(FacialExpression.FRIENDLY, "I see you have brought me some hides. Would you like me to tan them for you?").also { stage = 10 } + } else { + options("Can I buy some leather?", "Leather is rather weak stuff.").also { stage = 20 } + } + } + + 10 -> options("Yes please.", "No thanks.").also { stage++ } + 11 -> when (buttonId) { + 1 -> playerl(FacialExpression.HAPPY, "Yes please.").also { stage = 12 } + 2 -> playerl(FacialExpression.NEUTRAL, "No thanks.").also { stage = 13 } + } + + 12 -> end().also { TanningProduct.open(player, NPCs.ELLIS_2824) } + 13 -> npcl(FacialExpression.FRIENDLY, "Very well, @g[sir,madam], as you wish.").also { stage = END_DIALOGUE } + + 20 -> when (buttonId) { + 1 -> playerl(FacialExpression.ASKING, "Can I buy some leather?").also { stage = 21 } + 2 -> playerl(FacialExpression.SUSPICIOUS, "Leather is rather weak stuff.").also { stage = 22 } + } + + 21 -> npcl(FacialExpression.FRIENDLY, "I make leather from animal hides. Bring me some cowhides and one gold coin per hide, and I'll tan them into soft leather for you.").also { stage = END_DIALOGUE } + + 22 -> npcl(FacialExpression.NOD_YES, "Normal leather may be quite weak, but it's very cheap - I make it from cowhides for only 1 gp per hide - and it's so easy to craft that anyone can work with it.").also { stage++ } + 23 -> npcl(FacialExpression.HALF_THINKING, "Alternatively you could try hard leather. It's not so easy to craft, but I only charge 3 gp per cowhide to prepare it, and it makes much sturdier armour.").also { stage++ } + 24 -> npcl(FacialExpression.FRIENDLY, "I can also tan snake hides and dragonhides, suitable for crafting into the highest quality armour for rangers.").also { stage++ } + 25 -> playerl(FacialExpression.NEUTRAL, "Thanks, I'll bear it in mind.").also { stage = END_DIALOGUE } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return EllisDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.ELLIS_2824) + } +} diff --git a/Server/src/main/content/region/desert/alkharid/dialogue/EllyTheCamelDialogue.java b/Server/src/main/content/region/desert/alkharid/dialogue/EllyTheCamelDialogue.java new file mode 100644 index 0000000..747a6c5 --- /dev/null +++ b/Server/src/main/content/region/desert/alkharid/dialogue/EllyTheCamelDialogue.java @@ -0,0 +1,76 @@ +package content.region.desert.alkharid.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.tools.RandomFunction; + +/** + * Represents the elly the camel dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class EllyTheCamelDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code EllyTheCamelDialogue} {@code Object}. + */ + public EllyTheCamelDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code EllyTheCamelDialogue} {@code Object}. + * @param player the player. + */ + public EllyTheCamelDialogue(Player player) { + super(player); + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + end(); + player.getPacketDispatch().sendMessage("The camel tries to stomp on your foot, but you pull it back quickly."); + break; + } + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new EllyTheCamelDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + int rand = RandomFunction.random(1, 3); + switch (rand) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "If I go near that camel, it'll probably", "bite my hand off."); + stage = 0; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I wonder if that camel has fleas..."); + stage = 0; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I wonder if that camel has fleas..."); + stage = 0; + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 2810, 2812 }; + } +} diff --git a/Server/src/main/content/region/desert/alkharid/dialogue/FadliDialogue.kt b/Server/src/main/content/region/desert/alkharid/dialogue/FadliDialogue.kt new file mode 100644 index 0000000..c827048 --- /dev/null +++ b/Server/src/main/content/region/desert/alkharid/dialogue/FadliDialogue.kt @@ -0,0 +1,72 @@ +package content.region.desert.alkharid.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +/** + * @author bushtail + */ + +@Initializable +class FadliDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player?): DialoguePlugin { + return FadliDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + player(FacialExpression.FRIENDLY, "Hi!").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage) { + 0 -> npcl(FacialExpression.HALF_ASKING, "What?").also { stage++ } + 1 -> showTopics( + Topic("What do you do?", 101), + Topic("What is this place?", 201), + Topic(FacialExpression.FRIENDLY,"I'd like to store some items, please.", 301), + Topic("Do you watch any matches?", 401) + ) + + 101 -> npcl(FacialExpression.FRIENDLY, "You can store your stuff here if you want. You can dump anything you don't want to carry whilst your fighting duels and then pick it up again on the way out.").also { stage++ } + 102 -> npcl(FacialExpression.SAD, "To be honest I'm wasted here.").also { stage++ } + 103 -> npcl(FacialExpression.EVIL_LAUGH, "I should be winning duels in an arena! I'm the best warrior in Al Kharid!").also { stage++ } + 104 -> player(FacialExpression.HALF_WORRIED, "Easy, tiger!").also { stage = END_DIALOGUE } + + 201 -> npcl(FacialExpression.LAUGH, "Isn't it obvious?").also { stage++ } + 202 -> npcl(FacialExpression.ANNOYED, "This is the Duel Arena...duh!").also { stage = END_DIALOGUE } + + 301 -> npcl(FacialExpression.FRIENDLY, "Sure.").also { + end() + player.bank.open() + } + + 401 -> npcl(FacialExpression.LAUGH, "Most aren't any good so I throw rotten fruit at them!").also { stage = END_DIALOGUE } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.FADLI_958) + } +} + +class FadliListener : InteractionListener { + override fun defineListeners() { + on(NPCs.FADLI_958, IntType.NPC, "buy") { player, node -> + if(node.asNpc().openShop(player)) { + return@on true + } + return@on false + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/alkharid/dialogue/GemTraderDialogue.kt b/Server/src/main/content/region/desert/alkharid/dialogue/GemTraderDialogue.kt new file mode 100644 index 0000000..cd6bd5d --- /dev/null +++ b/Server/src/main/content/region/desert/alkharid/dialogue/GemTraderDialogue.kt @@ -0,0 +1,83 @@ +package content.region.desert.alkharid.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs +import content.data.Quests +import core.api.getQuestStage +import core.api.setQuestStage + +/** + * Represents the gem trader Dialogue plugin + * @author plex + * @version 2.0 + */ + +@Initializable +class GemTraderDialogue (player: Player? = null): DialoguePlugin(player){ + override fun newInstance(player: Player?): DialoguePlugin { + return GemTraderDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = (args[0] as NPC).getShownNPC(player) + npc("Good day to you, traveller.", "Would you be interested in buying some gems?") + stage = if (getQuestStage(player, Quests.FAMILY_CREST) == 12) 1 else 2 + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 1 -> options("Yes, please.", "No, thank you.", "I'm in search of a man named Avan Fitzharmon").also{ + stage = 10 + } + + 2 -> options("Yes, please.", "No, thank you.").also{ + stage = 20 + } + + 10 -> when(buttonId){ + 1 -> npc.openShop(player).also { stage = 1000 } + 2 -> player("No, thank you.").also{stage = 1000} + 3 -> npc("Fitzharmon, eh? Hmmm... If I'm not mistaken, ", + "that's the family name of a member ", + "of the Varrockian nobility.").also{stage = 100} + } + + 20 -> when(buttonId){ + 1 -> npc.openShop(player).also { stage = 1000 } + 2 -> player("No, thank you.").also{stage = 1000} + } + + 100 -> npc("You know, I HAVE seen someone of that" , + " persuasion around here recently... " , + "wearing a 'poncey' yellow cape, he was.").also{stage++} + + 101 -> npc("Came in here all la-di-dah, high and mighty,", + "asking for jewellery made from 'perfect gold' - " , + "whatever that is - like 'normal' gold just isn't " , + "good enough for 'little lord fancy pants' there!").also{stage ++} + + 102 -> npc("I told him to head to the desert 'cos " , + "I know there's gold out there, in them there sand dunes. " , + "And if it's not up to his lordship's " , + "high standards of 'gold perfection', then...").also{stage++} + 103 -> npc("Well, maybe we'll all get lucky ", + "and the scorpions will deal with him.").also{ + stage = 1000 + setQuestStage(player, Quests.FAMILY_CREST, 13) + } + + 1000 -> end() + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.GEM_TRADER_540) + } + + +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/alkharid/dialogue/HassanDialogue.java b/Server/src/main/content/region/desert/alkharid/dialogue/HassanDialogue.java new file mode 100644 index 0000000..7c711ed --- /dev/null +++ b/Server/src/main/content/region/desert/alkharid/dialogue/HassanDialogue.java @@ -0,0 +1,163 @@ +package content.region.desert.alkharid.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.GroundItemManager; +import core.plugin.Initializable; +import core.game.node.item.Item; +import content.data.Quests; + +/** + * Represents the dialogue used to handle the Hassan npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class HassanDialogue extends DialoguePlugin { + + /** + * Represents the jug of water item. + */ + private static final Item JUG_OF_WATER = new Item(1937); + + /** + * Represents the quest instance. + */ + private Quest quest; + + /** + * Constructs a new {@code HassanDialogue} {@code Object}. + */ + public HassanDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code HassanDialogue} {@code Object}. + * @param player the player. + */ + public HassanDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new HassanDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + quest = player.getQuestRepository().getQuest(Quests.PRINCE_ALI_RESCUE); + switch (quest.getStage(player)) { + case 100: + interpreter.sendDialogues(npc, null, "You are a friend of the town of Al-Kharid. If we have", "more tasks to complete, we will ask you. Please, keep in", "contact. Good employees are not easy to find."); + stage = 0; + break; + case 60: + interpreter.sendDialogues(npc, null, "You have the eternal gratitude of the Emir for", "rescuing his son. I am authorised to pay you 700", "coins."); + stage = 0; + break; + case 40: + case 50: + case 20: + case 30: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I understand the Spymaster has hired you. I will pay", "the reward only when the Prince is rescued."); + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Have you found the spymaster, Osman, yet? You", "cannot proceed in your task without reporting to him."); + break; + default: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Greetings I am Hassan, Chancellor to the Emir of Al-", "Kharid."); + break; + } + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (quest.getStage(player)) { + case 100: + end(); + break; + case 60: + end(); + quest.finish(player); + break; + case 30: + case 40: + case 50: + case 20: + end(); + break; + case 10: + end(); + break; + case 0: + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "Can I help you? You must need some help here in the desert.", "It's just too hot here. How can you stand it?", "Do you mind if I just kill your warriors?"); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Can I help you? You must need some help here in the", "desert."); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "It's just too hot here. How can you stand it?"); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Do you mind if I just kill your warriors?"); + stage = 30; + break; + } + break; + case 10: + quest.start(player); + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I need the services of someone yes. If you are", "interested, see the spymaster, Osman. I manage the", "finances here. Come to me when you need payment."); + stage = 11; + break; + case 11: + end(); + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "We manage, in our humble way. We are a wealthy", "town and we have water. It cures many thirsts."); + stage = 21; + break; + case 21: + interpreter.sendDialogue("The chancellor hands you some water."); + stage = 22; + break; + case 22: + if (!player.getInventory().add(JUG_OF_WATER)) { + GroundItemManager.create(JUG_OF_WATER, player); + } + end(); + break; + case 30: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "You are welcome. They are not expensive. We have", "them here to stop the elite guard being bothered. They", "are a little harder to kill."); + stage = 31; + break; + case 31: + end(); + break; + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 923 }; + } +} diff --git a/Server/src/main/content/region/desert/alkharid/dialogue/JaraahDialogue.kt b/Server/src/main/content/region/desert/alkharid/dialogue/JaraahDialogue.kt new file mode 100644 index 0000000..d114990 --- /dev/null +++ b/Server/src/main/content/region/desert/alkharid/dialogue/JaraahDialogue.kt @@ -0,0 +1,66 @@ +package content.region.desert.alkharid.dialogue + +import core.api.animate +import core.api.getStatLevel +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.Animations +import org.rs09.consts.NPCs + +/** + * @author bushtail + */ + +@Initializable +class JaraahDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player?): DialoguePlugin { + return JaraahDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + player(FacialExpression.FRIENDLY, "Hi!").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage) { + 0 -> npcl(FacialExpression.ANNOYED, "What? Can't you see I'm busy?!").also { stage++ } + 1 -> showTopics( + Topic("Can you heal me?", 101), + Topic("You must see some gruesome things?", 201), + Topic("Why do they call you 'The Butcher'?", 301) + ) + + // Jaraah has to be special and have different dialogue for the heal listener so I am repeating it here. + 101 -> { + animate(npc!!, Animations.HUMAN_PICKPOCKETING_881) + if(player!!.skills.lifepoints < getStatLevel(player!!, Skills.HITPOINTS)) { + player!!.skills.heal(21) + npcl(FacialExpression.FRIENDLY, "There you go!") + } else { + npcl(FacialExpression.FRIENDLY, "Okay, this will hurt you more than it will me.") + } + stage = END_DIALOGUE + } + + 201 -> npcl(FacialExpression.FRIENDLY, "It's a gruesome business and with the tools they give me it gets mroe gruesome before it gets better!").also { stage = END_DIALOGUE } + + 301 -> npcl(FacialExpression.HALF_THINKING, "'The Butcher'?").also { stage++ } + 302 -> npcl(FacialExpression.LAUGH, "Ha!").also { stage++ } + 303 -> npcl(FacialExpression.HALF_ASKING, "Would you like me to demonstrate?").also { stage++ } + 304 -> player(FacialExpression.AFRAID, "Er...I'll give it a miss, thanks.").also { stage = END_DIALOGUE } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.JARAAH_962) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/alkharid/dialogue/KarimDialogue.java b/Server/src/main/content/region/desert/alkharid/dialogue/KarimDialogue.java new file mode 100644 index 0000000..41c010f --- /dev/null +++ b/Server/src/main/content/region/desert/alkharid/dialogue/KarimDialogue.java @@ -0,0 +1,105 @@ +package content.region.desert.alkharid.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.game.node.item.Item; + +/** + * Represents the karim dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class KarimDialogue extends DialoguePlugin { + + /** + * Represents the coins item. + */ + private static final Item COINS = new Item(995, 1); + + /** + * Represents the mud kebab item. + */ + private static final Item KEBAB = new Item(1971, 1); + + /** + * Constructs a new {@code KarimDialogue} {@code Object}. + */ + public KarimDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code KarimDialogue} {@code Object}. + * @param player the player. + */ + public KarimDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new KarimDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Would you like to buy a nice kebab? Only one gold."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "I think I'll give it a miss.", "Yes please."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I think I'll give it a miss."); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HAPPY, "Yes please."); + stage = 20; + break; + + } + break; + case 10: + end(); + break; + case 20: + if (player.getInventory().freeSlots() == 0) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I don't have enough room, sorry."); + stage = 21; + } else if (!player.getInventory().contains(995, 1)) { + end(); + player.getPacketDispatch().sendMessage("You need 1 gp to buy a kebab."); + } else { + player.getInventory().remove(COINS); + player.getInventory().add(KEBAB); + end(); + } + break; + case 21: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 543 }; + } +} diff --git a/Server/src/main/content/region/desert/alkharid/dialogue/LouiLegsDialogue.java b/Server/src/main/content/region/desert/alkharid/dialogue/LouiLegsDialogue.java new file mode 100644 index 0000000..f209993 --- /dev/null +++ b/Server/src/main/content/region/desert/alkharid/dialogue/LouiLegsDialogue.java @@ -0,0 +1,86 @@ +package content.region.desert.alkharid.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the plugin used for loui legs. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class LouiLegsDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code LouiLegsDialogue} {@code Object}. + */ + public LouiLegsDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code LouiLegsDialogue} {@code Object}. + * @param player the player. + */ + public LouiLegsDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new LouiLegsDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Hey, wanna buy some armour?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "What have you got?", "No, thank you."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.THINKING, "What have you got?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.FRIENDLY, "No, thank you."); + stage = 20; + break; + + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "I provide items to help you keep your legs!"); + stage = 11; + break; + case 11: + end(); + npc.openShop(player); + break; + case 20: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 542 }; + } +} diff --git a/Server/src/main/content/region/desert/alkharid/dialogue/OllieTheCamelDialogue.java b/Server/src/main/content/region/desert/alkharid/dialogue/OllieTheCamelDialogue.java new file mode 100644 index 0000000..bfff7de --- /dev/null +++ b/Server/src/main/content/region/desert/alkharid/dialogue/OllieTheCamelDialogue.java @@ -0,0 +1,53 @@ +package content.region.desert.alkharid.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Handles the OllieTheCamelDialogue dialogue. + * @author 'Vexia + */ +@Initializable +public class OllieTheCamelDialogue extends DialoguePlugin { + + public OllieTheCamelDialogue() { + + } + + public OllieTheCamelDialogue(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[] { 2811 }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + end(); + player.getPacketDispatch().sendMessage("The camel tries to stamp on your foot, but you pull it back quickly."); + break; + } + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new OllieTheCamelDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I wonder if that camel has fleas..."); + stage = 0; + return true; + } +} diff --git a/Server/src/main/content/region/desert/alkharid/dialogue/RanaelDialogue.java b/Server/src/main/content/region/desert/alkharid/dialogue/RanaelDialogue.java new file mode 100644 index 0000000..cb52690 --- /dev/null +++ b/Server/src/main/content/region/desert/alkharid/dialogue/RanaelDialogue.java @@ -0,0 +1,69 @@ +package content.region.desert.alkharid.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Handles the RanaelDialogue dialogue. + * @author 'Vexia + */ +@Initializable +public class RanaelDialogue extends DialoguePlugin { + + public RanaelDialogue() { + + } + + public RanaelDialogue(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[] { 544 }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "Yes, please.", "No, thank you, that's not my scene."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + end(); + npc.openShop(player); + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No, thank you, that's not my scene."); + stage = 20; + break; + + } + break; + case 20: + end(); + break; + } + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new RanaelDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Do you want to buy any armoured skirts? Designed", "especially for ladies who like to fight."); + stage = 0; + return true; + } +} diff --git a/Server/src/main/content/region/desert/alkharid/dialogue/SabreenDialogue.kt b/Server/src/main/content/region/desert/alkharid/dialogue/SabreenDialogue.kt new file mode 100644 index 0000000..7bfeb16 --- /dev/null +++ b/Server/src/main/content/region/desert/alkharid/dialogue/SabreenDialogue.kt @@ -0,0 +1,48 @@ +package content.region.desert.alkharid.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +/** + * @author bushtail + */ + +@Initializable +class SabreenDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player?): DialoguePlugin { + return SabreenDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + player(FacialExpression.FRIENDLY, "Hi!").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage) { + 0 -> showTopics( + Topic("Can you heal me?", AlKharidHealDialogue(true)), + Topic("Do you see a lot of injured fighters?", 101), + Topic("Do you come here often?", 201) + ) + + 101 -> npcl(FacialExpression.FRIENDLY, "I work here, so yes!").also { stage = END_DIALOGUE } + + 201 -> npcl(FacialExpression.HALF_THINKING, "Yes I do. Thankfully we can cope with almost anything. Jaraah really is a wonderful surgeon, his methods are a little unorthodox but he gets the job done.").also { stage++ } + 202 -> npcl(FacialExpression.HALF_GUILTY, "I shouldn't tell you this but his nickname is 'The Butcher'.").also { stage++ } + 203 -> playerl(FacialExpression.HALF_WORRIED, "That's reassuring.").also { stage = END_DIALOGUE } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.SABREEN_960) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/alkharid/dialogue/SurgeonGeneralTafaniDialogue.kt b/Server/src/main/content/region/desert/alkharid/dialogue/SurgeonGeneralTafaniDialogue.kt new file mode 100644 index 0000000..eb64285 --- /dev/null +++ b/Server/src/main/content/region/desert/alkharid/dialogue/SurgeonGeneralTafaniDialogue.kt @@ -0,0 +1,70 @@ +package content.region.desert.alkharid.dialogue + +import core.api.hasLevelStat +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.IfTopic +import core.game.dialogue.Topic +import core.game.global.Skillcape +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +/** + * @author bushtail + */ + +@Initializable +class SurgeonGeneralTafaniDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player?): DialoguePlugin { + return SurgeonGeneralTafaniDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npcl(FacialExpression.FRIENDLY, "Hi. How can I help?").also { stage = 100 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage) { + 100 -> showTopics( + Topic("Can you heal me?", AlKharidHealDialogue(true)), + Topic("Do you see a lot of injured fighters?", 201), + Topic("Do you come here often?", 301), + IfTopic("Can I buy a Skillcape of Hitpoints from you?", 401, hasLevelStat(player, Skills.HITPOINTS, 99)), + IfTopic("Where can I get a cape like yours?", 501, !hasLevelStat(player, Skills.HITPOINTS, 99)) + ) + + 201 -> npcl(FacialExpression.HALF_THINKING, "Yes I do. Thankfully we can cope with almost anything. Jaraah really is a wonderful surgeon, his methods are a little unorthodox but he gets the job done.").also { stage++ } + 202 -> npcl(FacialExpression.HALF_GUILTY, "I shouldn't tell you this but his nickname is 'The Butcher'.").also { stage++ } + 203 -> playerl(FacialExpression.HALF_WORRIED, "That's reassuring.").also { stage = END_DIALOGUE } + + 301 -> npcl(FacialExpression.LAUGH, "I work here, so yes!").also { stage = END_DIALOGUE } + + 401 -> npcl(FacialExpression.FRIENDLY, "Why, certainly my friend. However, owning such an item makes you part of an elite group and that privilege will cost you 99000 coins.").also { stage++ } + 402 -> showTopics( + Topic(FacialExpression.HALF_GUILTY, "Sorry, that's much too pricey.", 411), + Topic(FacialExpression.HAPPY, "Sure, that's not too expensive for such a magnificent cape.", 421) + ) + + 411 -> npcl(FacialExpression.NEUTRAL, "I'm sorry you feel that way. Still, if you change your mind...").also { stage = END_DIALOGUE } + 421 -> if(Skillcape.purchase(player, Skills.HITPOINTS)) { + npcl(FacialExpression.FRIENDLY, "There you go! I hope you enjoy it.").also { stage = END_DIALOGUE } + } else { + npcl(FacialExpression.HALF_GUILTY, "Sorry, you can't buy that right now.").also { stage = END_DIALOGUE } + } + + 501 -> npcl(FacialExpression.HALF_THINKING, "Well, these capes are only available for people who have achieved a Hitpoint level of 99. You should go and train some more and come back to me when your Hitpoints are higher.").also { stage = END_DIALOGUE } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.SURGEON_GENERAL_TAFANI_961) + } +} + diff --git a/Server/src/main/content/region/desert/alkharid/dialogue/ZekeDialogue.java b/Server/src/main/content/region/desert/alkharid/dialogue/ZekeDialogue.java new file mode 100644 index 0000000..0ffb354 --- /dev/null +++ b/Server/src/main/content/region/desert/alkharid/dialogue/ZekeDialogue.java @@ -0,0 +1,137 @@ +package content.region.desert.alkharid.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the dialogue plugin used for zeke. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class ZekeDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code ZekeDialogue} {@code Object}. + */ + public ZekeDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code ZekeDialogue} {@code Object}. + * @param player the player. + */ + public ZekeDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new ZekeDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "A thousand greetings, sir."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "Do you want to trade?", "Nice cloak.", "Could you sell me a dragon scimitar?"); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HAPPY, "Do you want to trade?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HAPPY, "Nice cloak."); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HAPPY, "Could you sell me a dragon scimitar?"); + stage = 30; + break; + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Yes, certainly. I deal in scimitars."); + stage = 11; + break; + case 11: + npc.openShop(player); + end(); + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Thank you."); + stage = 21; + break; + case 21: + end(); + break; + case 30: + interpreter.sendDialogues(npc, FacialExpression.EXTREMELY_SHOCKED, "A dragon scimitar? A DRAGON scimitar?"); + stage = 31; + break; + case 31: + interpreter.sendDialogues(npc, FacialExpression.EXTREMELY_SHOCKED, "No way, man!"); + stage = 32; + break; + case 32: + interpreter.sendDialogues(npc, FacialExpression.ANGRY, "The banana-brained nitwits who make them would never", "dream of selling any to me."); + stage = 33; + break; + case 33: + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "Seriously, you'll be a monkey's uncle before you'll ever", "hold a dragon scimitar."); + stage = 34; + break; + case 34: + interpreter.sendDialogues(player, FacialExpression.SUSPICIOUS, "Hmmm, funny you should say that..."); + stage = 35; + break; + case 35: + interpreter.sendDialogues(npc, FacialExpression.ASKING, "Perhaps you'd like to take a look at my stock?"); + stage = 36; + break; + case 36: + interpreter.sendOptions("Select an Option", "Yes, please, Zeke.", "Not today, thank you."); + stage = 37; + break; + case 37: + switch (buttonId) { + case 1: + npc.openShop(player); + end(); + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No today, thank you."); + stage = 2000; + break; + } + break; + case 2000: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 541 }; + } + +} diff --git a/Server/src/main/content/region/desert/alkharid/handlers/AlKharidStairsPlugin.kt b/Server/src/main/content/region/desert/alkharid/handlers/AlKharidStairsPlugin.kt new file mode 100644 index 0000000..cec65c1 --- /dev/null +++ b/Server/src/main/content/region/desert/alkharid/handlers/AlKharidStairsPlugin.kt @@ -0,0 +1,51 @@ +package content.region.desert.alkharid.handlers + +import core.api.* +import core.cache.def.impl.SceneryDefinition +import core.game.global.action.DoorActionHandler +import core.game.interaction.OptionHandler +import core.game.node.Node +import core.game.node.entity.player.Player +import core.game.node.scenery.Scenery +import core.game.node.scenery.SceneryBuilder +import core.game.world.map.Location +import core.plugin.Initializable +import core.plugin.Plugin + +@Initializable +class AlKharidStairsPlugin : OptionHandler() { + + private val zekeStairsTop = Scenery(35645,Location(3284,3190,1),2,0) + private val zekeDoorClosed = Scenery(27988,Location(3284,3190,1),0,2) + private val zekeDoorOpened = Scenery(27989,Location(3285,3190,1),0,3) + + private val craftingStairsTop = Scenery(35645,Location(3314,3187,1),2,0) + private val craftingDoorClosed = Scenery(27988,Location(3314,3187,1),0,3) + private val craftingDoorOpened = Scenery(27989,Location(3314,3186,1),0,0) + + override fun handle(player: Player?, node: Node?, option: String?): Boolean { + player ?: return false + node ?: return false + option ?: return false + if(node.location == zekeDoorOpened.location || node.location == craftingDoorOpened.location){ + sendMessage(player,"This door appears to be stuck open.") + } else{ + DoorActionHandler.handleDoor(player,node.asScenery()) + } + return true + } + + override fun newInstance(arg: Any?): Plugin { + + // Zekes Shop Upstairs Door replacement + SceneryBuilder.replace(zekeDoorClosed,zekeDoorOpened) + SceneryBuilder.add(zekeStairsTop) + + // Crafting Shop Upstairs Door replacement + SceneryBuilder.replace(craftingDoorClosed,craftingDoorOpened) + SceneryBuilder.add(craftingStairsTop) + + SceneryDefinition.forId(27989).handlers["option:close"] = this + return this + } +} diff --git a/Server/src/main/content/region/desert/alkharid/handlers/AlKharidWarriorNPC.kt b/Server/src/main/content/region/desert/alkharid/handlers/AlKharidWarriorNPC.kt new file mode 100644 index 0000000..ba1b466 --- /dev/null +++ b/Server/src/main/content/region/desert/alkharid/handlers/AlKharidWarriorNPC.kt @@ -0,0 +1,73 @@ +package content.region.desert.alkharid.handlers + +import core.game.node.Node +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.game.world.map.RegionManager +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * Handles the Al-Kharid Warrior + * @author Ceikry + */ +@Initializable +class AlKharidWarriorNPC : AbstractNPC { + var target: Player? = null + private val supportRange: Int = 5 + + //Constructor spaghetti because Arios I guess + constructor() : super(18, null, true) {} + private constructor(id: Int, location: Location) : super(id, location) {} + override fun construct(id: Int, location: Location, vararg objects: Any): AbstractNPC { + return AlKharidWarriorNPC(id, location) + } + + //Maintains target combat (resolves issue where they would just give up/walk away) + override fun tick() { + if(target != null && !inCombat() && skills.lifepoints > 0){ + attack(target) + } + super.tick() + } + + //Clear target on death + override fun finalizeDeath(killer: Entity?) { + target = null + super.finalizeDeath(killer) + } + + override fun attack(node: Node?) { + if (node is Player) target = node + super.attack(node) + } + + override fun onImpact(entity: Entity?, state: BattleState?) { + if (entity is Player) { + if (target == null) { + target = entity + RegionManager.getLocalNpcs(entity, supportRange).forEach { + if (it.id == NPCs.AL_KHARID_WARRIOR_18 && !it.properties.combatPulse.isAttacking && it != this) { + it.sendChat("Brother, I shall help thee with this infidel!") + it.attack(entity) + } + } + } + } + super.onImpact(entity, state) + } + + override fun getIds(): IntArray { + return ID + } + + companion object { + /** + * The NPC ids of NPCs using this plugin. + */ + private val ID = intArrayOf(NPCs.AL_KHARID_WARRIOR_18) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/alkharid/quest/princealirescue/LadyKeliDialogue.java b/Server/src/main/content/region/desert/alkharid/quest/princealirescue/LadyKeliDialogue.java new file mode 100644 index 0000000..0385670 --- /dev/null +++ b/Server/src/main/content/region/desert/alkharid/quest/princealirescue/LadyKeliDialogue.java @@ -0,0 +1,265 @@ +package content.region.desert.alkharid.quest.princealirescue; + +import java.util.List; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.world.GameWorld; +import core.game.world.map.RegionManager; +import content.data.Quests; + +/** + * Represents the dialogue which handles the lady keli transcript. + * @author 'Vexia + * @version 1.0 + */ +public final class LadyKeliDialogue extends DialoguePlugin { + + /** + * Represents the soft clay item. + */ + private static final Item SOFT_CLAY = new Item(1761); + + /** + * Represents the key print item. + */ + private static final Item KEY_PRINT = new Item(2423); + + /** + * Represents the quest instance. + */ + private Quest quest; + + /** + * Constructs a new {@code LadyKeliDialogue} {@code Object}. + */ + public LadyKeliDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code LadyKeliDialogue} {@code Object}. + * @param player the player. + */ + public LadyKeliDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new LadyKeliDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + quest = player.getQuestRepository().getQuest(Quests.PRINCE_ALI_RESCUE); + switch (quest.getStage(player)) { + case 60: + case 100: + npc.sendChat("You tricked me, and tied me up, Guards kill this stranger!"); + List npcc = RegionManager.getLocalNpcs(player); + for (NPC n : npcc) { + if (n.getId() == 917) { + n.sendChat("Yes M'lady"); + n.getProperties().getCombatPulse().attack(player); + } + } + end(); + break; + default: + interpreter.sendDialogues(player, null, "Are you the famous Lady Keli? Leader of the toughest", "gang of mercenary killers around?"); + stage = 0; + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (quest.getStage(player)) { + default: + switch (stage) { + case 0: + interpreter.sendDialogues(npc, null, "I am Keli, you have heard of me then?"); + stage = 1; + break; + case 1: + interpreter.sendOptions("Select an Option", "Heard of you? You are famous in " + GameWorld.getSettings().getName() + "!", "I have heard a little, but I think Katrine is tougher.", "I have heard rumours that you kill people.", "No I have never really heard of you."); + stage = 2; + break; + case 2: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, null, "The great Lady Keli, of course I have heard of you.", "You are famous in " + GameWorld.getSettings().getName() + "!"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, null, "I think Katrine is tougher."); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, null, "I have heard rumours that you kill people."); + stage = 30; + break; + case 4: + interpreter.sendDialogues(player, null, "No I have never really heard of you."); + stage = 40; + break; + } + break; + case 10: + interpreter.sendDialogues(npc, null, "That's very kind of you to say. Reputations are", "not easily earned. I have managed to succeed", "where many fail."); + stage = 11; + break; + case 11: + interpreter.sendOptions("Select an Option", "I think Katrine is still tougher.", "What is your latest plan then?", "You must have trained a lot for this work.", "I should not disturb someone as tough as you."); + stage = 12; + break; + case 12: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, null, "I think Katrine is tougher."); + stage = 20; + break; + case 2: + interpreter.sendDialogues(player, null, "What is your latest plan then? Of course, you need", "not go into specific details."); + stage = 22; + break; + case 3: + interpreter.sendDialogues(player, null, "You must have trained a lot for this work."); + stage = 25; + break; + case 4: + interpreter.sendDialogues(player, null, "I should not disturb someone as tough as you."); + stage = 27; + break; + } + break; + case 20: + interpreter.sendDialogues(npc, null, "Well you can think that all you like. I know those", "blackarm cowards dare not leave the city. Out here, I", "am the toughest. You can tell them that! Now get out of", "my sight, before I call my guards."); + stage = 21; + break; + case 21: + end(); + break; + case 22: + interpreter.sendDialogues(npc, null, "Well, I can tell you I have a valuable prisoner here", "in my cells."); + stage = 23; + break; + case 23: + interpreter.sendDialogues(npc, null, "I can expect a high reward to be paid very soon for", "this guy. I can't tell you who he is, but he is a lot", "colder now."); + stage = 24; + break; + case 24: + interpreter.sendDialogues(player, null, "You must have been very skillful."); + stage = 50; + break; + case 50: + interpreter.sendDialogues(npc, null, "Yes. I did most of the work. We had to grab the Pr..."); + stage = 51; + break; + case 51: + interpreter.sendDialogues(npc, null, "Er, we had to grab him without his ten bodyguards", "noticing. It was a stroke of genius."); + stage = 52; + break; + case 52: + interpreter.sendDialogues(player, null, "Can you be sure they will not try to get him out?"); + stage = 53; + break; + case 53: + interpreter.sendDialogues(npc, null, "There is no way to release him. The only key to the", "door is on a chain around my neck and the locksmith", "who made the lock died suddenly when he had finished."); + stage = 54; + break; + case 54: + interpreter.sendDialogues(npc, null, "There is not another key like this in the world."); + stage = 55; + break; + case 55: + interpreter.sendDialogues(player, null, "Could I see the key please? Just for a moment. It", "would be something I can tell my grandchildren. When", "you are even more famous than you are now."); + stage = 56; + break; + case 56: + interpreter.sendDialogues(npc, null, "As you put it that way I am sure you can see it. You", "cannot steal the key, it is on a Runite chain."); + stage = 57; + break; + case 57: + interpreter.sendDialogue("Keli shows you a small key on a strong looking chain."); + stage = 58; + break; + case 58: + if (player.getInventory().remove(SOFT_CLAY)) { + if (!player.getInventory().add(KEY_PRINT)) { + GroundItemManager.create(KEY_PRINT, player); + } + interpreter.sendDialogues(player, null, "Could I touch the key for a moment please?"); + stage = 59; + } else { + interpreter.sendDialogues(npc, null, "There, run along now I am very busy."); + stage = 63; + } + break; + case 59: + interpreter.sendDialogues(npc, null, "Only for a moment then."); + stage = 60; + break; + case 60: + interpreter.sendDialogue("You put a piece of your soft clay in your hand. As you touch the", "key, you take an imprint of it."); + stage = 61; + break; + case 61: + interpreter.sendDialogues(player, null, "Thank you so much, you are too kind, o great Keli."); + stage = 62; + break; + case 62: + interpreter.sendDialogues(npc, null, "You are welcome, run along now, I am very busy."); + stage = 63; + break; + case 63: + end(); + break; + case 25: + interpreter.sendDialogues(npc, null, "I have used a sword since I was a small girl. I stabbed", "three people before I was 6 years old."); + stage = 26; + break; + case 26: + end(); + break; + case 27: + interpreter.sendDialogues(npc, null, "I need to do a lot of work, goodbye. When you get a", "little tougher, maybe I will give you a job."); + stage = 28; + break; + case 28: + end(); + break; + case 30: + interpreter.sendDialogues(npc, null, "There's always someone ready to spread rumours. I", "hear all sort of ridiculous things these days."); + stage = 31; + break; + case 31: + end(); + break; + case 40: + interpreter.sendDialogues(npc, null, "You must be new to this land then. EVERYONE", "knows of Lady Keli and her prowess with the sword."); + stage = 41; + break; + case 41: + end(); + break; + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 919 }; + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/alkharid/quest/princealirescue/LadyKeliNPC.java b/Server/src/main/content/region/desert/alkharid/quest/princealirescue/LadyKeliNPC.java new file mode 100644 index 0000000..2e9c31f --- /dev/null +++ b/Server/src/main/content/region/desert/alkharid/quest/princealirescue/LadyKeliNPC.java @@ -0,0 +1,56 @@ +package content.region.desert.alkharid.quest.princealirescue; + +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.world.GameWorld; +import core.game.world.map.Location; + +/** + * Represents the abstract lady keli npc. + * @author 'Vexia + * @version 1.0 + */ +public final class LadyKeliNPC extends AbstractNPC { + + /** + * The NPC ids of NPCs using this plugin. + */ + private static final int[] ID = { 919 }; + + /** + * Constructs a new {@code LadyKeliNPC} {@code Object}. + */ + public LadyKeliNPC() { + super(0, null, true); + } + + /** + * Constructs a new {@code LadyKeliNPC} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + private LadyKeliNPC(int id, Location location) { + super(id, location, true); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new LadyKeliNPC(id, location); + } + + @Override + public boolean isHidden(final Player player) { + return player.getAttribute("keli-gone", 0) > GameWorld.getTicks(); + } + + @Override + public int[] getIds() { + return ID; + } + + @Override + public int getWalkRadius() { + return 2; + } + +} diff --git a/Server/src/main/content/region/desert/alkharid/quest/princealirescue/NedPARDialogue.kt b/Server/src/main/content/region/desert/alkharid/quest/princealirescue/NedPARDialogue.kt new file mode 100644 index 0000000..3994545 --- /dev/null +++ b/Server/src/main/content/region/desert/alkharid/quest/princealirescue/NedPARDialogue.kt @@ -0,0 +1,100 @@ +package content.region.desert.alkharid.quest.princealirescue + +import core.game.dialogue.DialogueFile +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE + +private const val STAGE_KNIT_SWEATER = 10 +private const val STAGE_KNIT_WIG = 20 +private const val STAGE_REPAIR_HOLES = 30 +class NedPARDialogue(val questStage: Int) : DialogueFile() { + + private val WIG_WOOL = Item(1759, 3) + private val WIG = Item(2421) + + override fun handle(componentID: Int, buttonID: Int) { + when(stage){ + START_DIALOGUE -> options( + "Ned, could you make other things from wool?", + "Yes, I would like some rope.", + "No thanks, Ned, I don't need any." + ).also { stage++ } + + 1 -> when(buttonID){ + 1 -> player("Ned could you make other things from wool?").also { stage++ } + 2 -> { + player("Yes, I would like some rope.") + returnAtStage(10) + } + 3 -> player("No thanks Ned, I don't need any.").also { stage = END_DIALOGUE } + } + + 2 -> npc("I am sure I can. What are you thinking of?").also { stage++ } + 3 -> options( + "Could you knit me a sweater?", + "How about some sort of wig?", + "Could you repair the arrow holes in the back of my shirt?" + ).also { stage++ } + + 4 -> when(buttonID){ + 1 -> player("Could you knit me a sweater?").also { stage = STAGE_KNIT_SWEATER } + 2 -> player("How about some sort of wig?").also { stage = STAGE_KNIT_WIG } + 3 -> player("Could you repair the arrow holes in the","back of my shirt?").also { stage = STAGE_REPAIR_HOLES } + } + + //Knit Sweater + STAGE_KNIT_SWEATER -> npc( + "Do I look like a member of a sewing circle?", + "Be off wi' you. I have fought monsters.", + "that would turn your hair blue." + ).also { stage++ } + STAGE_KNIT_SWEATER.substage(1) -> npc( + "I dont't need to be laughted at just 'cos I am getting", + "a bit old." + ).also { stage = END_DIALOGUE } + + //Knit Wig + STAGE_KNIT_WIG -> npc( + "Well... That's an interesting thought. Yes, I think I", + "could do something. Give me 3 balls of wool and I", + "might be able to do it." + ).also { stage++ } + STAGE_KNIT_WIG.substage(1) -> options( + "I have that now. Please, make me a wig.", + "I will come back when I need you to make me one." + ).also { stage++ } + STAGE_KNIT_WIG.substage(2) -> when(buttonID){ + 1 -> player("I have that now. Please, make me a wig.").also { stage++ } + 2 -> player("I will come back when I need you to make me one.").also { stage = END_DIALOGUE } + } + STAGE_KNIT_WIG.substage(3) -> { + if(!player!!.inventory.containsItem(WIG_WOOL)){ + player("Oh, I seem to have forgotten my wool.") + stage = END_DIALOGUE + } else { + npc("Okay, I will have a go.") + stage++ + } + } + STAGE_KNIT_WIG.substage(4) -> interpreter!!.sendDialogue("You hand Ned 3 balls of wool. Ned works with the wool", "His hands move with a speed you couldn't imagine.").also { stage++ } + STAGE_KNIT_WIG.substage(5) -> { + if (player!!.inventory.remove(WIG_WOOL)) { + if (!player!!.inventory.add(WIG)) { + GroundItemManager.create(WIG, player) + } + } + npc("Here you go, how's that for a quick effort?", "Not bad I think!") + stage++ + } + STAGE_KNIT_WIG.substage(6) -> interpreter!!.sendDialogue("Ned gives you a pretty good wig.").also { stage++ } + STAGE_KNIT_WIG.substage(7) -> player("Thanks Ned, there's more to you than meets the eye.").also { stage = END_DIALOGUE } + + STAGE_REPAIR_HOLES -> interpreter!!.sendDialogue("Ned pulls out a nettle and attacks your shirt.").also { stage++ } + STAGE_REPAIR_HOLES.substage(1) -> npc("There you go, good as new.").also { stage = END_DIALOGUE } + + } + } + +} diff --git a/Server/src/main/content/region/desert/alkharid/quest/princealirescue/PrinceAliRescue.java b/Server/src/main/content/region/desert/alkharid/quest/princealirescue/PrinceAliRescue.java new file mode 100644 index 0000000..3df8858 --- /dev/null +++ b/Server/src/main/content/region/desert/alkharid/quest/princealirescue/PrinceAliRescue.java @@ -0,0 +1,204 @@ +package content.region.desert.alkharid.quest.princealirescue; + +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.ClassScanner; +import content.data.Quests; + +/** + * Represents the prince ali rescue quest. + * @author Vexia + * + */ +@Initializable +public class PrinceAliRescue extends Quest { + + /** + * Represents the rope item. + */ + private static final Item ROPE = new Item(954); + + /** + * Represents the pink skirt item. + */ + private static final Item SKIRT = new Item(1013); + + /** + * Represents the yellow wig item. + */ + private static final Item YELLOW_WIG = new Item(2419); + + /** + * Represents the skin paste item. + */ + private static final Item PASTE = new Item(2424); + + /** + * Represents the coins item. + */ + private static final Item COINS = new Item(995, 700); + + /** + * Constructs a new {@Code PrinceAliRescue} {@Code Object} + */ + public PrinceAliRescue() { + super(Quests.PRINCE_ALI_RESCUE, 24, 23, 3, 273, 0, 1, 110); + } + + @Override + public Quest newInstance(Object object) { + ClassScanner.definePlugins(new LadyKeliDialogue(), new LadyKeliNPC(), new PrinceAliRescuePlugin(), new WigDyePlugin()); + return this; + } + + @Override + public void drawJournal(Player player, int stage) { + super.drawJournal(player, stage); + switch (stage) { + case 0: + player.getPacketDispatch().sendString(BLUE + "I can start this quest by speaking to " + RED + "Hassan " + BLUE + "at the palace", 275, 4+ 7); + player.getPacketDispatch().sendString(BLUE + "in" + RED + " Al-Kharid.", 275, 5+ 7); + break; + case 10: + line(player, "I started this quest by speaking to Hassan in Al-Kharid", 4+ 7); + line(player, "Palace. he told me I should speak to Osman the spymaster.", 5+ 7); + line(player, BLUE + "I should go and speak to " + RED + "Osman " + BLUE + "for details on the quest.", 6+ 7); + break; + case 20: + line(player, "I started this quest by speaking to Hassan in Al-Kharid", 4+ 7); + line(player, "Palace. he told me I should speak to Osman the spymaster.", 5+ 7); + line(player, "I should go and speak to Osman for details on the quest.", 6+ 7); + line(player, RED + "Prince Ali " + BLUE + "has been " + RED + "kidnapped " + BLUE + "but luckily the spy " + RED + "Leela " + BLUE + "has", 7+ 7); + line(player, BLUE + "found he is being held near " + RED + "Draynor village. " + BLUE + "I will need to", 8+ 7); + line(player, RED + "disguise " + BLUE + "the " + RED + "Price " + BLUE + "and " + RED + "tie " + BLUE + "up his " + RED + "captop " + BLUE + "to " + RED + "free " + BLUE + "him from", 9+ 7); + line(player, BLUE + "their " + RED + "clutches.", 10+ 7); + line(player, BLUE + "To do this I should:-", 11+ 7); + line(player, BLUE + "Talk to " + RED + "Leela " + BLUE + "near " + RED + "Draynor Village " + BLUE + "for advice.", 12+ 7); + line(player, BLUE + "Get a " + RED + "duplicate " + BLUE + "of the " + RED + "key " + BLUE + "that is " + RED + "imprisoning " + BLUE + "the " + RED + "prince.", 13+ 7); + line(player, hasItem(player, ROPE) ? "I have some rope with me." : BLUE + "Get some " + RED + "rope " + BLUE + "to tie up the Princes' " + RED + "kidnapper.", 14+ 7); + line(player, hasItem(player, PASTE) ? "I have some skin paste suitable for disguise with me." : BLUE + "Get something to " + RED + "colour " + BLUE + "the " + RED + "Princes' skin " + BLUE + "as a " + RED + "disguise.", 15+ 7); + line(player, hasItem(player, SKIRT) ? "I have a skirt suitable for a disguise with me." : BLUE + "Get a " + RED + "skirt " + BLUE + "similar to his " + RED + "kidnapper " + BLUE + "as " + RED + "disguise.", 16+ 7); + line(player, hasItem(player, YELLOW_WIG) ? "I have a wig suitable for disguise with me." : BLUE + "Get a " + RED + "Wig " + BLUE + "to " + RED + "help disguise " + BLUE + "the " + RED + "prince.", 17+ 7); + break; + case 30: + line(player, "I started this quest by speaking to Hassan in Al-Kharid", 4+ 7); + line(player, "Palace. he told me I should speak to Osman the spymaster.", 5+ 7); + line(player, "I should go and speak to Osman for details on the quest.", 6+ 7); + line(player, RED + "Prince Ali " + BLUE + "has been " + RED + "kidnapped " + BLUE + "but luckily the spy " + RED + "Leela " + BLUE + "has", 7+ 7); + line(player, BLUE + "found he is being held near " + RED + "Draynor village. " + BLUE + "I will need to", 8+ 7); + line(player, RED + "disguise " + BLUE + "the " + RED + "Prince " + BLUE + "and " + RED + "tie " + BLUE + "up his " + RED + "captor " + BLUE + "to " + RED + "free " + BLUE + "him from", 9+ 7); + line(player, BLUE + "their " + RED + "clutches.", 10+ 7); + line(player, BLUE + "To do this I should:-", 11+ 7); + line(player, BLUE + "Talk to " + RED + "Leela " + BLUE + "near " + RED + "Draynor Village " + BLUE + "for advice.", 12+ 7); + line(player, BLUE + "I have duplicated a key, I need to get it from " + RED + "Leela.", 13+ 7); + line(player, hasItem(player, ROPE) ? "I have some rope with me." : BLUE + "Get some " + RED + "rope " + BLUE + "to tie up the Princes' " + RED + "kidnapper.", 14+ 7); + line(player, hasItem(player, PASTE) ? "I have some skin paste suitable for disguise with me." : BLUE + "Get something to " + RED + "colour " + BLUE + "the " + RED + "Princes' skin " + BLUE + "as a " + RED + "disguise.", 15+ 7); + line(player, hasItem(player, SKIRT) ? "I have a skirt suitable for a disguise with me." : BLUE + "Get a " + RED + "skirt " + BLUE + "similar to his " + RED + "kidnapper " + BLUE + "as " + RED + "disguise.", 16+ 7); + line(player, hasItem(player, YELLOW_WIG) ? "I have a wig suitable for disguise with me." : BLUE + "Get a " + RED + "Wig " + BLUE + "to " + RED + "help disguise" + BLUE + "the " + RED + "prince.", 17+ 7); + break; + case 40: + line(player, "I started this quest by speaking to Hassan in Al-Kharid", 4+ 7); + line(player, "Palace. he told me I should speak to Osman the spymaster.", 5+ 7); + line(player, "I should go and speak to Osman for details on the quest.", 6+ 7); + if (player.getAttribute("guard-drunk", false)) { + line(player, "Prince Ali has been kidnapped but luckily the spy Leela has", 7+ 7); + line(player, "found he is being held near Draynor village. I will need to", 8+ 7); + line(player, "disguise the Prince and tie up his captor to free him from", 9+ 7); + line(player, "their clutches.", 10+ 7); + line(player, "I also had to prevent the Guard from seeing that I was up", 10+ 7); + line(player, "to, by getting him drunk.", 11+ 7); + line(player, BLUE + "With the guard out of the way, all I have to do now is use", 11+ 7); + line(player, BLUE + "the " + RED + "Skin Potion" + BLUE + ", " + RED + "Pink Skirt" + BLUE + ", " + RED + "Rope" + BLUE + ", " + RED + "Blonde Wig " + BLUE + "and " + RED + "Cell Key " + BLUE + "to", 12+ 7); + line(player, BLUE + "free " + RED + "Prince Ali " + BLUE + "from his cell somehow.", 13+ 7); + } else { + line(player, BLUE + "Do something to prevent " + RED + "Joe the Guard " + BLUE + "seeing the", 7+ 7); + line(player, BLUE + "escape.", 8+ 7); + line(player, BLUE + "Use the " + RED + "Skin potion" + BLUE + ", " + RED + "Pink Skirt" + BLUE + "," + RED + "Rope" + BLUE + "," + RED + "Blonde Wig " + BLUE + "and " + RED + "Cell", 9+ 7); + line(player, RED + "Key" + BLUE + " to free " + RED + "Prince Ali " + BLUE + "from his cell somehow.", 10+ 7); + } + break; + case 50: + line(player, "I started this quest by speaking to Hassan in Al-Kharid", 4+ 7); + line(player, "Palace. he told me I should speak to Osman the spymaster.", 5+ 7); + line(player, "I should go and speak to Osman for details on the quest.", 6+ 7); + line(player, "Prince Ali has been kidnapped but luckily the spy Leela has", 7+ 7); + line(player, "found he is being held near Draynor village. I will need to", 8+ 7); + line(player, "disguise the Prince and tie up his captor to free him from", 9+ 7); + line(player, "their clutches.", 10+ 7); + line(player, "I also had to prevent the Guard from seeing that I was up", 10+ 7); + line(player, "to, by getting him drunk.", 11+ 7); + line(player, "With the guard disposed of, I used my rope to tie up Lady", 11+ 7); + line(player, "Keli in a cupboard, so I could disguise the Prince.", 12+ 7); + line(player, BLUE + "I need to " + RED + "Unlock the cell door " + BLUE + "and then give the Prince the", 13+ 7); + line(player, RED + "Pink Skirt" + BLUE + ", the " + RED + "Skin paste " + BLUE + "and the " + RED + "Blonde Swig " + BLUE + "so that the", 14+ 7); + line(player, BLUE + "can safely " + RED + "escape " + BLUE + "disguised as " + RED + "Lady Keli.", 15+ 7); + break; + case 60: + line(player, "I started this quest by speaking to Hassan in Al-Kharid", 4+ 7); + line(player, "Palace. he told me I should speak to Osman the spymaster.", 5+ 7); + line(player, "I should go and speak to Osman for details on the quest.", 6+ 7); + line(player, "Prince Ali has been kidnapped but luckily the spy Leela has", 7+ 7); + line(player, "found he is being held near Draynor village. I will need to", 8+ 7); + line(player, "disguise the Prince and tie up his captor to free him from", 9+ 7); + line(player, "their clutches.", 10+ 7); + line(player, "I also had to prevent the Guard from seeing that I was up", 10+ 7); + line(player, "to, by getting him drunk.", 11+ 7); + line(player, "With the guard disposed of, I used my rope to tie up Lady", 11+ 7); + line(player, "Keli in a cupboard, so I could disguise the Prince.", 12+ 7); + line(player, "I then used a wig, and some skin paste to make the", 13+ 7); + line(player, "prince look like Lady Keli so he could escape to his", 14+ 7); + line(player, "freedom with Leela after unlocking his cell door.", 15+ 7); + line(player, BLUE + "I should return to " + RED + "Hassan " + BLUE + "to claim my reward.", 16+ 7); + break; + case 100: + line(player, "I started this quest by speaking to Hassan in Al-Kharid", 4+ 7); + line(player, "Palace. he told me I should speak to Osman the spymaster.", 5+ 7); + line(player, "I should go and speak to Osman for details on the quest.", 6+ 7); + line(player, "Prince Ali has been kidnapped but luckily the spy Leela has", 7+ 7); + line(player, "found he is being held near Draynor village. I will need to", 8+ 7); + line(player, "disguise the Prince and tie up his captor to free him from", 9+ 7); + line(player, "their clutches.", 10+ 7); + line(player, "I also had to prevent the Guard from seeing that I was up", 10+ 7); + line(player, "to, by getting him drunk.", 11+ 7); + line(player, "With the guard disposed of, I used my rope to tie up Lady", 11+ 7); + line(player, "Keli in a cupboard, so I could disguise the Prince.", 12+ 7); + line(player, "I then used a wig, and some skin paste to make the", 13+ 7); + line(player, "prince look like Lady Keli so he could escape to his", 14+ 7); + line(player, "freedom with Leela after unlocking his cell door.", 15+ 7); + line(player, "Hassan the chancellor rewarded me for all of my help.", 16+ 7); + line(player, "I am now a friend of Al-Kharid and may pass through the", 17+ 7); + line(player, "gate leading between Lumbridge and Al-Kharid for free", 18+ 7); + line(player, "QUEST COMPLETE!", 19+ 7); + break; + } + } + + /** + * Check if the player has the item. + * @param player the player. + * @param item the item. + * @return true or false. + */ + public static boolean hasItem(final Player player, final Item item) { + return player.getInventory().containsItem(item); + } + + @Override + public void finish(Player player) { + super.finish(player); + player.getPacketDispatch().sendMessage("The chancellor pays you 700 coins."); + player.getPacketDispatch().sendString("3 Quests Points", 277, 8 + 2); + player.getPacketDispatch().sendString("700 Coins", 277, 9 + 2); + player.getPacketDispatch().sendString("You have completed the Prince Ali Rescue Quest!", 277, 2 + 2); + player.getPacketDispatch().sendItemZoomOnInterface(995, 20, 230, 277, 3 + 2); + if (!player.getInventory().add(COINS)) { + GroundItemManager.create(COINS, player); + } + player.removeAttribute("guard-drunk"); + } + + +} diff --git a/Server/src/main/content/region/desert/alkharid/quest/princealirescue/PrinceAliRescuePlugin.java b/Server/src/main/content/region/desert/alkharid/quest/princealirescue/PrinceAliRescuePlugin.java new file mode 100644 index 0000000..3f38c34 --- /dev/null +++ b/Server/src/main/content/region/desert/alkharid/quest/princealirescue/PrinceAliRescuePlugin.java @@ -0,0 +1,90 @@ +package content.region.desert.alkharid.quest.princealirescue; + +import core.cache.def.impl.NPCDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.game.global.action.DoorActionHandler; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.scenery.Scenery; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.plugin.Plugin; +import content.data.Quests; + +/** + * Represents the plugin used to handle prince ali rescue quest interaction nodes. + * @author Vexia + * + */ +@Initializable +public class PrinceAliRescuePlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(2881).getHandlers().put("option:open", this);// prison + // door. + SceneryDefinition.forId(4639).getHandlers().put("option:open", this);// door + // to + // jail + NPCDefinition.forId(925).getHandlers().put("option:talk-to", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + final Quest quest = player.getQuestRepository().getQuest(Quests.PRINCE_ALI_RESCUE); + final int id = node instanceof Scenery ? ((Scenery) node).getId() : node instanceof NPC ? ((NPC) node).getId() : 0; + switch (id) { + case 925: + player.getDialogueInterpreter().open(925, node); + break; + case 2881: + switch (quest.getStage(player)) { + case 60: + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + break; + case 50: + if (player.getAttribute("keli-gone", 0) > GameWorld.getTicks()) { + if (player.getInventory().contains(2418, 1)) { + player.getPacketDispatch().sendMessage("You unlock the door."); + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + } else { + player.getPacketDispatch().sendMessage("The door is locked."); + } + } else { + player.getPacketDispatch().sendMessage("You'd better get rid of Lady Keli before trying to go through there."); + } + break; + default: + player.getPacketDispatch().sendMessage("You'd better get rid of Lady Keli before trying to go through there."); + break; + } + break; + } + return true; + } + + static Location[] locs = new Location[] { new Location(3268, 3227, 0), Location.create(3268, 3228, 0), Location.create(3267, 3228, 0), Location.create(3267, 3227, 0) }; + + @Override + public Location getDestination(final Node node, Node n) { + if (n instanceof NPC) { + NPC npc = ((NPC) n); + if (npc.getLocation().equals(new Location(3268, 3226, 0))) { + return locs[0]; + } else if (npc.getLocation().equals(new Location(3268, 3229, 0))) { + return locs[1]; + } else if (npc.getLocation().equals(new Location(3267, 3229, 0))) { + return locs[2]; + } else if (npc.getLocation().equals(new Location(3267, 3226, 0))) { + return locs[3]; + } + } + return null; + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/alkharid/quest/princealirescue/WigDyePlugin.java b/Server/src/main/content/region/desert/alkharid/quest/princealirescue/WigDyePlugin.java new file mode 100644 index 0000000..4d61582 --- /dev/null +++ b/Server/src/main/content/region/desert/alkharid/quest/princealirescue/WigDyePlugin.java @@ -0,0 +1,54 @@ +package content.region.desert.alkharid.quest.princealirescue; + +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Plugin; + +/** + * Represents the plugin used to dye a wig yellow. + * @author 'Vexia + * @version 1.0 + */ +public final class WigDyePlugin extends UseWithHandler { + + /** + * Represents the yellow dye item. + */ + private static final Item YELLOW_DYE = new Item(1765); + + /** + * Represents the wig item. + */ + private static final Item WIG = new Item(2421); + + /** + * Represents the yellow wig item. + */ + private static final Item YELLOW_WIG = new Item(2419); + + /** + * Constructs a new {@code WigDyePlugin} {@code Object}. + */ + public WigDyePlugin() { + super(1765); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(2421, ITEM_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + if (player.getInventory().remove(WIG, YELLOW_DYE)) { + player.getInventory().add(YELLOW_WIG); + player.getPacketDispatch().sendMessage("You dye the wig blonde."); + } + return true; + } + +} diff --git a/Server/src/main/content/region/desert/bandits/handlers/BanditDialogue.kt b/Server/src/main/content/region/desert/bandits/handlers/BanditDialogue.kt new file mode 100644 index 0000000..2b6d8f8 --- /dev/null +++ b/Server/src/main/content/region/desert/bandits/handlers/BanditDialogue.kt @@ -0,0 +1,63 @@ +package content.region.desert.bandits.handlers + +import content.region.desert.quest.deserttreasure.DesertTreasure +import core.api.getAttribute +import core.api.inInventory +import core.api.openDialogue +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class BanditDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return BanditDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, BanditDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.BANDIT_1926) + } +} +class BanditDialogueFile : DialogueBuilderFile() { + + override fun create(b: DialogueBuilder) { + + b.onQuestStages(DesertTreasure.questName, 100) + .npcl("So you're the one who freed Azzanadra from his prison? Thank you, kind @g[sir,lady]!") + .end() + + b.onQuestStages(DesertTreasure.questName, 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15) + .npcl("What do you want @g[lad,lass]?") + .playerl("I'm here on an archaeological expedition for the Museum of Varrock. I believe there may be some interesting artefacts in the area.") + .branch { player -> + return@branch (0..4).random() + }.let { branch -> + branch.onValue(0) + .npcl("You are a crazy @g[man,woman]. The only thing you will find out here in the desert is your death.") + .end() + branch.onValue(1) + .npcl("I have no interest in the world that betrayed my people. Search where you will, you will find nothing.") + .end() + branch.onValue(2) + .npcl("The gods forsake us, and drove us to this place. Anything of worth has been long gone.") + .end() + branch.onValue(3) + .npcl("I'm sure there are many secrets buried beneath the sands here. The thing about this being a desert, is that they're likely to stay that way.") + .end() + branch.onValue(4) + .npcl("Do I look like I care who you are or where you came from?") + .end() + } + + b.onPredicate { _ -> true } + .npcl("Get out of this village. You are not welcome here.") + .end() + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/bandits/handlers/BanditNPC.kt b/Server/src/main/content/region/desert/bandits/handlers/BanditNPC.kt new file mode 100644 index 0000000..f8c69da --- /dev/null +++ b/Server/src/main/content/region/desert/bandits/handlers/BanditNPC.kt @@ -0,0 +1,62 @@ +package content.region.desert.bandits.handlers + +import core.api.God +import core.api.hasGodItem +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.game.world.map.RegionManager +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class BanditNPC(id: Int = NPCs.BANDIT_1926, location: Location? = null) : AbstractNPC(id, location) { + private val supportRange: Int = 3 + + override fun construct(id: Int, location: Location, vararg objects: Any): AbstractNPC { + return BanditNPC(id, location) + } + + override fun tick() { + if (!inCombat()) { + val players = RegionManager.getLocalPlayers(this, 5) + for (player in players) { + if (player.inCombat()) continue + if (hasGodItem(player, God.SARADOMIN)) { + sendChat("Time to die, Saradominist filth!") + attack(player) + break + } else if (hasGodItem(player, God.ZAMORAK)) { + sendChat("Prepare to suffer, Zamorakian scum!") + attack(player) + break + } + } + } + super.tick() + } + + //Clear target on death + override fun finalizeDeath(killer: Entity?) { + super.finalizeDeath(killer) + } + + override fun onImpact(entity: Entity?, state: BattleState?) { + if (entity is Player) { + RegionManager.getLocalNpcs(entity, supportRange).forEach { + if (it.id == NPCs.BANDIT_1926 && !it.properties.combatPulse.isAttacking && it != this) { + it.sendChat("You picked the wrong place to start trouble!") + it.attack(entity) + } + } + } + super.onImpact(entity, state) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.BANDIT_1926) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/bedabin/handlers/BedabinPlugin.java b/Server/src/main/content/region/desert/bedabin/handlers/BedabinPlugin.java new file mode 100644 index 0000000..a0a2870 --- /dev/null +++ b/Server/src/main/content/region/desert/bedabin/handlers/BedabinPlugin.java @@ -0,0 +1,75 @@ +package content.region.desert.bedabin.handlers; + +import core.cache.def.impl.NPCDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * The plugin used to handle bedabin interactions. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class BedabinPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(2700).getHandlers().put("option:walk-through", this); + SceneryDefinition.forId(2672).getHandlers().put("option:use", this); + NPCDefinition.forId(834).getHandlers().put("option:talk-to", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + final int id = node.getId(); + switch (option) { + case "talk-to": + player.getDialogueInterpreter().open(node.getId(), node); + break; + case "walk-through": + switch (id) { + case 2700: + if (player.getLocation().getY() >= 3046) { + final Scenery door = RegionManager.getObject(new Location(3169, 3046, 0)); + SceneryBuilder.replace(door, door.transform(2701), 2); + player.getWalkingQueue().reset(); + player.getWalkingQueue().addPath(3169, 3045); + player.getPacketDispatch().sendMessage("You walk back out the tent."); + break; + } + player.getDialogueInterpreter().open(834, RegionManager.getNpc(player, 834)); + break; + } + break; + case "use": + switch (id) { + case 2672: + player.getPacketDispatch().sendMessage("To forge items use the metal you wish to work with the anvil."); + break; + } + break; + } + return true; + } + + @Override + public Location getDestination(Node n, Node node) { + if (node instanceof NPC) { + if (node.getId() == 834) { + return new Location(3169, 3045, 0); + } + } + return null; + } + +} diff --git a/Server/src/main/content/region/desert/dialogue/CamelDialoguePlugin.java b/Server/src/main/content/region/desert/dialogue/CamelDialoguePlugin.java new file mode 100644 index 0000000..e0b4e02 --- /dev/null +++ b/Server/src/main/content/region/desert/dialogue/CamelDialoguePlugin.java @@ -0,0 +1,62 @@ +package content.region.desert.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the dialogue plugin used for the camel npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class CamelDialoguePlugin extends DialoguePlugin { + + /** + * Constructs a new {@code CamelDialoguePlugin} {@code Object}. + */ + public CamelDialoguePlugin() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code CamelDialoguePlugin} {@code Object}. + * @param player the player. + */ + public CamelDialoguePlugin(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new CamelDialoguePlugin(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "If I go near that camel, it'll probably bite my hand off."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + end(); + player.getPacketDispatch().sendMessage("The camel spits at you, and you jump back hurriedly."); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 2813 }; + } +} diff --git a/Server/src/main/content/region/desert/dialogue/RugMerchantDialogue.java b/Server/src/main/content/region/desert/dialogue/RugMerchantDialogue.java new file mode 100644 index 0000000..a4a3c62 --- /dev/null +++ b/Server/src/main/content/region/desert/dialogue/RugMerchantDialogue.java @@ -0,0 +1,432 @@ +package content.region.desert.dialogue; + +import core.api.Container; +import static core.api.ContentAPIKt.*; +import static core.tools.GlobalsKt.colorize; + +import core.cache.def.impl.NPCDefinition; +import core.game.container.impl.EquipmentContainer; +import core.game.dialogue.DialoguePlugin; +import core.plugin.Initializable; +import content.global.skill.agility.AgilityHandler; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import kotlin.Unit; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; +import core.plugin.ClassScanner; +import org.rs09.consts.Items; +import org.rs09.consts.Sounds; +import content.data.Quests; + + +/** + * The dialogue plugin used for the rug merchant. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class RugMerchantDialogue extends DialoguePlugin { + + /** + * The ids of the rug merchants. + */ + private static final int[] IDS = new int[] { 2291, 2292, 2293, 2294, 2296, 2298, 3020 }; + + /** + * The floating animation. + */ + private static final Animation FLOATING_ANIMATION = new Animation(330); + + /** + * The current reg destination. + */ + private RugDestination current; + + /** + * The rug destination options,. + */ + private RugDestination[] options; + + /** + * The destinationt o travel to. + */ + private RugDestination destination; + + /** + * Constructs a new {@code RugMerchantDialogue} {@code Object}. + */ + public RugMerchantDialogue() { + } + + @Override + public void init() { + super.init(); + ClassScanner.definePlugin(new RugMerchantPlugin()); + } + + /** + * Constructs a new {@code RugMerchantDialogue} {@code Object}. + * @param player the player. + */ + public RugMerchantDialogue(final Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new RugMerchantDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + current = RugDestination.forId(npc.getId()); + if (args.length >= 2) { + options = getDestination(npc.getId()); + sendOptions(options); + stage = 11; + return true; + } + player("Hello."); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + default: + handleDefault(buttonId); + break; + } + return true; + } + + /** + * Handles the defeault dialogue. + * @param buttonId the buttonId. + */ + private final void handleDefault(final int buttonId) { + switch (stage) { + case 0: + npc("Greetings, desert traveller. Do you require the services", "of Ali Morrisane's flying carpet fleet?"); + stage++; + break; + case 1: + options("Yes, please.", "No thanks."); + stage++; + break; + case 2: + switch (buttonId) { + case 1: + player("Yes, please."); + stage = 10; + break; + case 2: + player("No thanks."); + stage = 20; + break; + } + break; + case 8: + options("Yes.", "No."); + stage++; + break; + case 9: + if (buttonId == 2) { + end(); + } else { + destination = options[0]; + player("Yes, please."); + stage = 11; + } + break; + case 10: + sendOptions((options = getDestination(npc.getId()))); + stage = 11; + break; + case 11: + if (!player.getInventory().contains(995, 200)) { + npc("A travel on one of my rugs costs 200 gold", "coins."); + stage = 20; + return; + } + end(); + destination = options.length == 1 ? options[0] : options[buttonId - 1]; + if (destination == RugDestination.UZER && !hasRequirement(player, Quests.THE_GOLEM)) + break; + else if (destination == RugDestination.BEDABIN_CAMP && !hasRequirement(player, Quests.THE_TOURIST_TRAP)) + break; + else if (destination == RugDestination.SOPHANEM && !hasRequirement(player, Quests.ICTHLARINS_LITTLE_HELPER)) + break; + if(player.getEquipment().get(EquipmentContainer.SLOT_WEAPON) != null){ + player.sendMessage(colorize("%RYou must unequip all your weapons before you can fly on a carpet.")); + } else { + if (player.getInventory().remove(new Item(995, 200))) { + destination.travel(current, player); + } + } + break; + case 20: + end(); + break; + } + } + + /** + * Sends the rug travelling destination options. + * @param destinations the destinations. + */ + private void sendOptions(RugDestination[] destinations) { + String[] options = new String[destinations.length]; + if (destinations.length == 1) { + npc("Travel back to " + destinations[0].getName() + "?"); + stage = 8; + return; + } + for (int i = 0; i < destinations.length; i++) { + options[i] = destinations[i].getName(); + } + interpreter.sendOptions("Select a Destination", options); + } + + /** + * Gets the rug destinations for an npc id. + * @param npcId the npc id. + * @return the rug destinations. + */ + public static RugDestination[] getDestination(int npcId) { + switch (npcId) { + case 2291: + return new RugDestination[] { RugDestination.UZER, RugDestination.BEDABIN_CAMP, RugDestination.NORTH_POLLNIVNEACH }; + case 2292: + return new RugDestination[] { RugDestination.SHANTAY_PASS }; + case 2294: + return new RugDestination[] { RugDestination.SHANTAY_PASS }; + case 2293: + return new RugDestination[] { RugDestination.SHANTAY_PASS }; + case 3020: + return new RugDestination[] { RugDestination.NARDAH, RugDestination.SOPHANEM }; + default: + return new RugDestination[] { RugDestination.SOUTH_POLLNIVNEACH }; + } + } + + @Override + public int[] getIds() { + return IDS; + } + + /** + * Handles the right click on the rug merchant. + * @author Vexia + * + */ + public class RugMerchantPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (int id : IDS) { + NPCDefinition.forId(id).getHandlers().put("option:travel", this); + } + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + player.getDialogueInterpreter().open(node.getId(), node, true, true); + return true; + } + + } + + /** + * A destination for a rug. + * @author 'Vexia + */ + public enum RugDestination { + SHANTAY_PASS(2291, Location.create(3308, 3110, 0), "Shantay Pass"), BEDABIN_CAMP(2292, Location.create(3180, 3045, 0), "Bedabin Camp", Location.create(3305, 3107, 0), Location.create(3299, 3107, 0), Location.create(3285, 3088, 0), Location.create(3285, 3073, 0), Location.create(3268, 3073, 0), Location.create(3263, 3068, 0), Location.create(3246, 3068, 0), Location.create(3246, 3057, 0), Location.create(3232, 3057, 0), Location.create(3215, 3057, 0), Location.create(3200, 3057, 0), Location.create(3179, 3057, 0), Location.create(3179, 3047, 0), Location.create(3180, 3045, 0)), NORTH_POLLNIVNEACH(2294, Location.create(3349, 3003, 0), "North Pollnivneach", new Location(3308, 3096, 0), new Location(3308, 3079, 0), new Location(3308, 3066, 0), new Location(3311, 3057, 0), new Location(3319, 3042, 0), new Location(3332, 3033, 0), new Location(3341, 3020, 0), new Location(3350, 3009, 0), new Location(3351, 3003, 0), new Location(3349, 3003, 0)), UZER(2293, Location.create(3469, 3113, 0), "Uzer", Location.create(3308, 3105, 0), Location.create(3325, 3105, 0), Location.create(3332, 3105, 0), Location.create(3332, 3080, 0), Location.create(3341, 3080, 0), Location.create(3341, 3082, 0), Location.create(3358, 3082, 0), Location.create(3370, 3082, 0), Location.create(3382, 3082, 0), Location.create(3396, 3082, 0), Location.create(3432, 3082, 0), Location.create(3432, 3093, 0), Location.create(3440, 3093, 0), Location.create(3454, 3107, 0), Location.create(3469, 3107, 0), Location.create(3469, 3113, 0)), NARDAH(2296, Location.create(3401, 2916, 0), "Nardah", new Location(3351, 2942, 0), new Location(3350, 2936, 0), new Location(3362, 2936, 0), new Location(3380, 2928, 0), new Location(3392, 2920, 0), new Location(3397, 2916, 0), new Location(3401, 2916, 0)), SOPHANEM(2298, Location.create(3285, 2813, 0), "Sophanem", Location.create(3351, 2934, 0), Location.create(3351, 2928, 0), Location.create(3351, 2919, 0), Location.create(3346, 2902, 0), Location.create(3339, 2884, 0), Location.create(3328, 2877, 0), Location.create(3328, 2862, 0), Location.create(3328, 2845, 0), Location.create(3318, 2838, 0), Location.create(3307, 2828, 0), Location.create(3292, 2817, 0), Location.create(3285, 2818, 0), Location.create(3285, 2813, 0)), SOUTH_POLLNIVNEACH(3020, Location.create(3351, 2942, 0), "South Pollnivneach"); + + /** + * The npc id. + */ + private final int npc; + + /** + * The destination to go to. + */ + private final Location location; + + /** + * The name of the destination. + */ + private final String name; + + /** + * The location data. + */ + private final Location[] locData; + + /** + * Constructs a new {@code RugDestination} {@code Object}. + * @param npc the npc. + * @param destination the destination. + */ + private RugDestination(int npc, Location destination, String name, Location... locData) { + this.npc = npc; + this.location = destination; + this.name = name; + this.locData = locData; + } + + /** + * Travels a player to a destination. + * @param player the player. + */ + public void travel(final RugDestination current, final Player player) { + player.lock(); + setVarp(player, 499, 0); + player.getImpactHandler().setDisabledTicks(GameWorld.getTicks() + 200); + player.getInterfaceManager().removeTabs(0,1,2,3,4,5,6,7,8,9,10,11,12,13); + player.getEquipment().replace(new Item(Items.MAGIC_CARPET_5614),EquipmentContainer.SLOT_WEAPON); + player.getPacketDispatch().sendInterfaceConfig(548,69,true); + playAudio(player, Sounds.CARPET_RISE_1196); + playJingle(player, 132); + + registerLogoutListener(player, "magic-carpet", (pl) -> { + removeItem(pl, Items.MAGIC_CARPET_5614, Container.EQUIPMENT); + return Unit.INSTANCE; + }); + + GameWorld.getPulser().submit(new Pulse(1, player) { + int count; + int index; + Location[] locs = getLocData(); + + @Override + public boolean pulse() { + switch (++count) { + case 1: + if (RugDestination.this == SHANTAY_PASS || RugDestination.this == RugDestination.SOUTH_POLLNIVNEACH) { + Location[] temp = new Location[current.getLocData().length + 1]; + int counter = 0; + for (int i = current.getLocData().length - 1; i >= 0; i--) { + temp[counter++] = current.getLocData()[i]; + } + temp[temp.length - 1] = RugDestination.this.getLocation(); + locs = temp; + } + player.faceLocation(current.getLocation()); + break; + case 2: + AgilityHandler.walk(player, -1, player.getLocation(), current.getLocation(), null, 0.0, null); + break; + case 3: + player.faceLocation(getLocation()); + break; + case 4: + setVarp(player, 499, 1); + break; + case 200: + break; + case 901: + player.getEquipment().replace(null,EquipmentContainer.SLOT_WEAPON); + player.getInterfaceManager().restoreTabs(); + player.getPacketDispatch().sendInterfaceConfig(548,69,false); + player.getImpactHandler().setDisabledTicks(0); + player.unlock(); + player.animate(new Animation(-1)); + setVarp(player, 499, 0); + playAudio(player, Sounds.CARPET_DESCEND_1195); + + clearLogoutListener(player, "magic-carpet"); + + break; + case 902: + player.moveStep(); + return true; + default: + if (index > locs.length - 1) { + count = 900; + break; + } + if (index == 0 || player.getLocation().equals(locs[index - 1])) { + AgilityHandler.walk(player,-1,player.getLocation(),locs[index++],null,0.0,null,true); + } + return false; + } + return false; + } + + @Override + public void stop() { + super.stop(); + player.unlock(); + } + + }); + } + + /** + * Checks if the player has the requirements. + * @param player the player. + * @return {@code True} if so. + */ + public boolean hasRequirements(final Player player) { + return true; + } + + /** + * Gets the rug destination object for the npc id. + * @param id the id. + * @return the rug destination. + */ + public static RugDestination forId(int id) { + for (RugDestination dest : values()) { + if (dest.getNpc() == id) { + return dest; + } + } + return null; + } + + /** + * Gets the npc. + * @return The npc. + */ + public int getNpc() { + return npc; + } + + /** + * Gets the destination. + * @return The destination. + */ + public Location getLocation() { + return location; + } + + /** + * Gets the name. + * @return the name. + */ + public String getName() { + return name; + } + + /** + * Gets the locData. + * @return the locData. + */ + public Location[] getLocData() { + return locData; + } + } + +} diff --git a/Server/src/main/content/region/desert/dialogue/ShantayDialogue.java b/Server/src/main/content/region/desert/dialogue/ShantayDialogue.java new file mode 100644 index 0000000..be8dde9 --- /dev/null +++ b/Server/src/main/content/region/desert/dialogue/ShantayDialogue.java @@ -0,0 +1,296 @@ +package content.region.desert.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.plugin.Initializable; +import core.game.world.map.Location; + +/** + * Represents the dialogue plugin used for shantay. + * @author Vexia + * @version 1.0 + */ +@Initializable +public final class ShantayDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code ShantayDialogue} {@code Object}. + */ + public ShantayDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code ShantayDialogue} {@code Object}. + * @param player the player. + */ + public ShantayDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new ShantayDialogue(player); + } + + @Override + public boolean open(Object... args) { + if (args[0] != null && args[0] instanceof NPC) { + npc = (NPC) args[0]; + } + if (args.length == 2) { + player.getPacketDispatch().sendMessage("Shantay saunters over to talk with you."); + interpreter.sendDialogues(836, FacialExpression.HALF_GUILTY, "If you want to be let out, you have to pay a fine of", "five gold. Do you want to pay now?"); + stage = 703; + return true; + } + interpreter.sendDialogues(836, FacialExpression.HALF_GUILTY, "Hello effendi, I am Shantay."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(836, FacialExpression.HALF_GUILTY, "I see you're new. Please read the billboard poster", "before going into the desert. It'll give yer details on the", "dangers you can face."); + stage = 1; + break; + case 1: + interpreter.sendDialogues(836, FacialExpression.HALF_GUILTY, "There is a heartbroken mother just past the gates and", "in the desert. Her name is Irena and she mourns her", "lost daughter. Such a shame."); + stage = 2; + break; + case 2: + interpreter.sendOptions("Select an Option", "What is this place?", "Can I see what you have to sell please?", "I must be going.", "I want to buy a Shantay pass for 5 gold coins."); + stage = 3; + break; + case 3: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What is this place?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Can I see what you have to sell please?"); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I must be going."); + stage = 30; + break; + case 4: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I want to buy a Shantay pass for 5 gold coins."); + stage = 40; + break; + + } + break; + case 40: + if (!player.getInventory().contains(995, 5)) { + end(); + return true; + } + if (player.getInventory().remove(new Item(995, 5))) { + player.getInventory().add(new Item(1854)); + interpreter.sendItemMessage(1854, "You purchase a Shantay Pass."); + } else { + interpreter.sendDialogues(player, null, "Sorry, I don't seem to have enough money."); + } + stage = 41; + break; + case 41: + end(); + break; + case 30: + interpreter.sendDialogues(836, FacialExpression.HALF_GUILTY, "So long..."); + stage = 31; + break; + case 31: + end(); + break; + case 10: + interpreter.sendDialogues(836, FacialExpression.HALF_GUILTY, "This is the pass of Shantay. I guard this area with my", "men. I am responsible for keeping this pass open and", "repaired."); + stage = 11; + break; + case 11: + interpreter.sendDialogues(836, FacialExpression.HALF_GUILTY, "My men and I prevent outlaws from getting out of the", "desert. And we stop the inexeperienced from a dry death", "in the sands. Which would you say you were?"); + stage = 12; + break; + case 12: + interpreter.sendOptions("Select an Option", "I am definitely an outlaw, prepare to die!", "I am a little inexperienced.", "Er, neither, I'm an adventurer."); + stage = 13; + break; + case 13: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, null, "I am definitely an outlaw, prepare to die."); + stage = 700; + break; + case 2: + interpreter.sendDialogues(player, null, "I am a little inexperienced."); + stage = 710; + break; + case 3: + interpreter.sendDialogues(player, null, "Er, neither, I'm an adventurer."); + stage = 720; + break; + } + break; + case 20: + interpreter.sendDialogues(836, FacialExpression.HALF_GUILTY, "Absolutely Effendi!"); + stage = 21; + break; + case 21: + end(); + npc.openShop(player); + break; + case 700: + interpreter.sendDialogues(836, null, "Ha, very funny....."); + stage = 701; + break; + case 701: + interpreter.sendDialogues(836, null, "Guards arrest him!"); + stage = 702; + break; + case 702: + player.getPacketDispatch().sendMessage("The guards arrest you and place you in the jail."); + close(); + player.lock(10); + GameWorld.getPulser().submit(new Pulse(3, player) { + @Override + public boolean pulse() { + player.setAttribute("/save:shantay-jail", true); + player.getProperties().setTeleportLocation(Location.create(3298, 3123, 0)); + interpreter.sendDialogues(836, null, "You'll have to stay in there until you pay the fine of", "five gold pieces. Do you want to pay now?"); + stage = 703; + return true; + } + }); + break; + case 703: + interpreter.sendOptions("Select an Option", "Yes, okay.", "No thanks, you're not having my money."); + stage = 704; + break; + case 704: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, null, "Yes, okay."); + stage = 705; + break; + case 2: + interpreter.sendDialogues(player, null, "No thanks, you're not having my money."); + stage = 800; + break; + } + break; + case 705: + if (player.getInventory().remove(new Item(995, 5))) { + player.getPacketDispatch().sendMessage("You hand over the five gold pieces to Shantay."); + player.getPacketDispatch().sendMessage("Shantay unlocks the door to the cell."); + interpreter.sendDialogues(836, null, "Great, Effendi, now please try to keep the peace."); + player.removeAttribute("shantay-jail"); + stage = 822; + } else { + interpreter.sendDialogues(player, null, "Sorry, I don't seem to have enough money."); + stage = 825; + } + break; + case 800: + interpreter.sendDialogues(836, null, "You have a choice. You can either pay five gold pieces", "or... You can be transported to a maximum security", "prision in Port Sarim"); + stage = 801; + break; + case 801: + interpreter.sendDialogues(836, null, "Will you pay the five gold pieces?"); + stage = 802; + break; + case 802: + interpreter.sendOptions("Select an Option", "Yes, okay.", "No, do your worst!"); + stage = 803; + break; + case 803: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, null, "Yes, okay."); + stage = 820; + break; + case 2: + interpreter.sendDialogues(player, null, "No, do your worst!"); + stage = 804; + break; + } + break; + case 804: + interpreter.sendDialogues(836, null, "You are to be transported to a maximum security", "prision in Port Sarim. I hope you've learn an important", "lesson from this."); + stage = 805; + break; + case 805: + player.getPacketDispatch().sendMessage("You find yourself in a prison."); + player.removeAttribute("shantay-jail"); + player.getProperties().setTeleportLocation(Location.create(3018, 3188, 0)); + end(); + break; + case 820: + interpreter.sendDialogues(836, null, "Good, I see that you have come to your senses."); + stage = 821; + break; + case 821: + if (player.getInventory().remove(new Item(995, 5))) { + player.getPacketDispatch().sendMessage("You hand over the five gold pieces to Shantay."); + player.getPacketDispatch().sendMessage("Shantay unlocks the door to the cell."); + interpreter.sendDialogues(836, null, "Great, Effendi, now please try to keep the peace."); + stage = 822; + } else { + interpreter.sendDialogues(player, null, "Sorry, I don't seem to have enough money."); + stage = 825; + } + break; + case 822: + end(); + break; + case 825: + end(); + break; + case 710: + interpreter.sendDialogues(836, null, "Can I recommend that you purchase a full waterskin", "and a knife! These items will no doubt save your life. A", "waterskin will keep water from evaporating in the desert."); + stage = 711; + break; + case 711: + interpreter.sendDialogues(836, null, "And a keen woodsman with a knife can extract juice", "from a cactus. Before you go into the desert, it's", "advisable to wear desert clothes. It's very hot in the", "desert and you'll surely cook if you wear amour."); + stage = 712; + break; + case 712: + end(); + break; + case 720: + interpreter.sendDialogues(836, null, "Great, I have just the thing for you the desert adventurer.", "I sell desert clothes which will keep you cool in the heat", "of the desert. I also sell waterskins so that you won't", "die in the desert."); + stage = 721; + break; + case 721: + interpreter.sendDialogues(836, null, "A waterskin and a knife help you survive from the juice", "of a cactus. Use the chest to store your items, we'll take", "them to the bank. It's hot in the desert, you'll bake in", "all that armour."); + stage = 722; + break; + case 722: + interpreter.sendDialogues(836, null, "To keep the pass open we ask for 5 gold pieces. And", "we give you a Shantay Pass, just ask to see what I sell", "to buy one."); + stage = 723; + break; + case 723: + end(); + break; + case 730: + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 836 }; + } +} diff --git a/Server/src/main/content/region/desert/dialogue/ShantayGuard.java b/Server/src/main/content/region/desert/dialogue/ShantayGuard.java new file mode 100644 index 0000000..f4d6310 --- /dev/null +++ b/Server/src/main/content/region/desert/dialogue/ShantayGuard.java @@ -0,0 +1,164 @@ +package content.region.desert.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.plugin.Initializable; +import content.global.skill.agility.AgilityHandler; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.path.Pathfinder; +import core.game.world.repository.Repository; + +/** + * Represents the dialogue used for a shantay guard. + * @author Vexia + * @version 1.0 + */ +@Initializable +public final class ShantayGuard extends DialoguePlugin { + + /** + * Represents a shantay pass item. + */ + private static final Item PASS = new Item(1854); + + /** + * Constructs a new {@code ShantayGuard} {@code Object}. + */ + public ShantayGuard() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code ShantayGuard} {@code Object}. + * @param player the player. + */ + public ShantayGuard(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new ShantayGuard(player); + } + + @Override + public boolean open(Object... args) { + if (args[0] != null && args[0] instanceof NPC) { + npc = ((NPC) args[0]); + } + if (args.length == 2) { + interpreter.sendDialogues(838, null, "Can I see your Desert Pass please?"); + stage = 13; + return true; + } + if (npc != null && npc.getId() != 837) { + interpreter.sendDialogues(838, FacialExpression.HALF_GUILTY, "Hello there!"); + stage = 0; + } else { + interpreter.sendDialogues(838, null, "Go talk to Shantay. I'm on duty and I don't have time", "to talk to the likes of you!"); + stage = 100; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(838, FacialExpression.HALF_GUILTY, "What can I do for you?"); + stage = 1; + break; + case 1: + interpreter.sendOptions("Select an Option", "I'd like to go into the desert please.", "Nothing thanks."); + stage = 2; + break; + case 2: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'd like to go into the desert please."); + stage = 10; + break; + case 2: + end(); + break; + } + break; + case 10: + interpreter.sendDialogues(838, FacialExpression.HALF_GUILTY, "Of course!"); + stage = 11; + break; + case 11: + if (!player.getInventory().containsItem(PASS)) { + player.getDialogueInterpreter().sendDialogues(Repository.findNPC(838), null, "You need a Shantay pass to get through this gate. See", "Shantay, he will sell you one for a very reasonable", "price."); + stage = 12; + return true; + } + interpreter.sendDialogues(838, null, "Can I see your Desert Pass please?"); + stage = 13; + break; + case 12: + end(); + break; + case 13: + if (!player.getInventory().containsItem(PASS)) { + player("Sorry, I don't have one with me."); + stage = 101; + return true; + } + interpreter.sendItemMessage(PASS, "You hand over a Shantay Pass."); + stage = 14; + break; + case 14: + interpreter.sendDialogues(player, null, "Sure, here you go!"); + stage = 15; + break; + case 15: + if (player.getInventory().remove(PASS)) { + final Location dest = player.getLocation().getY() < 3304 ? Location.create(3303, 3117, 0) : Location.create(3305, 3117, 0); + Pathfinder.find(player, dest).walk(player); + player.lock(); + GameWorld.getPulser().submit(new Pulse(1, player) { + @Override + public boolean pulse() { + if (player.getLocation().equals(dest)) { + player.unlock(); + handleShantayPass(player); + return true; + } + return false; + } + }); + } + end(); + break; + case 100: + interpreter.sendDialogue("The guard seems quite bad tempered, probably from having to wear", "heavy armour in this intense heat."); + stage = 101; + break; + case 101: + end(); + break; + } + return true; + } + + /** + * Method used to handle the shantay pass. + * @param player the player. + */ + public static void handleShantayPass(Player player) { + AgilityHandler.walk(player, 0, player.getLocation(), player.getLocation().transform(0, player.getLocation().getY() > 3116 ? -2 : 2, 0), null, 0, null); + } + + @Override + public int[] getIds() { + return new int[] { 837, 838 }; + } +} diff --git a/Server/src/main/content/region/desert/dialogue/SimonTempleton.java b/Server/src/main/content/region/desert/dialogue/SimonTempleton.java new file mode 100644 index 0000000..fe69517 --- /dev/null +++ b/Server/src/main/content/region/desert/dialogue/SimonTempleton.java @@ -0,0 +1,283 @@ +package content.region.desert.dialogue; + +import core.ServerConstants; +import core.api.Container; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.game.node.item.Item; +import org.rs09.consts.Items; + +import static core.api.ContentAPIKt.*; + +/** + * Handles the dialog for Simon Templeton + * @author ceik + */ +@Initializable +public final class SimonTempleton extends DialoguePlugin { + public final Item[][] ARTIFACTS = { {new Item(9032),new Item(9036), new Item(9026)}, {new Item(9042), new Item(9030), new Item(9038)}, {new Item(9040), new Item(9028), new Item(9034)} }; + public SimonTempleton(){ + /** + * Empty on purpose + */ + } + + public SimonTempleton(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new SimonTempleton(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + //Handles what happens when using a pharoah scepter on him (required for accuracy) + if(args.length == 4){ + if(((int) args[3] == 9044 || (int) args[3] == 9046 || (int) args[3] == 9048 || (int) args[3] == 9050)) { + npc("You sellin' me this gold colored", "stick thing. Looks fake to me.", "I'll give you 100 gold for it."); + stage = 30; + return true; + } + } + npc("G'day, mate. Got any new", "pyramid artefacts for me?"); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId){ + boolean hasArtefacts = false; + boolean hasPyramidTopper = false; + int goldReward = 1000; + if (ServerConstants.BETTER_AGILITY_PYRAMID_GP) goldReward =(int)(1000 + ((getStatLevel(player, 16) / 99.0) * 9000)); + switch(stage){ + case 0: + for(int i = 0; i < ARTIFACTS.length; i++){ + for(int j = 0; j < 3; j++){ + if(player.getInventory().containsItem(ARTIFACTS[i][j])){ + hasArtefacts = true; + break; + } + } + } + hasPyramidTopper = player.getInventory().containsItem(new Item(6970)); + if(hasPyramidTopper){ + player("Yes, actually. The top of that pyramid."); + stage = 6; + break; + } + if(hasArtefacts && !hasPyramidTopper){ + player("Why, yes I do!"); + stage = 1; + break; + } + player("No, I haven't."); + stage = 3; + break; + case 1: + npc("Excellent! I would like to buy them."); + stage = 2; + break; + case 2: + interpreter.sendOptions("Sell artefacts?","Yes, I need money!!","No, I'll hang onto them."); + stage = 10; + break; + case 3: + npc("Well, keep my offer in mind", "if you do find one."); + stage = 4; + break; + case 4: + player("I will. Goodbye, Simon."); + stage = 5; + break; + case 5: + npc("Bye, mate."); + stage = 999; + break; + case 6: + npc("Hmmm, very nice. I'll buy them for " + goldReward + " each."); + stage = 7; + break; + case 7: + interpreter.sendOptions("Select an option.","Sounds good!", "No thanks."); + stage = 8; + break; + case 8: + switch(buttonId){ + case 1: + int pyramidTopsInInv = amountInInventory(player, Items.PYRAMID_TOP_6970); + if (removeItem(player, new Item(Items.PYRAMID_TOP_6970, pyramidTopsInInv), Container.INVENTORY)) { + addItem(player, Items.COINS_995, goldReward * pyramidTopsInInv, Container.INVENTORY); + } + end(); + break; + case 2: + npc("Have it your way."); + stage = 9; + break; + } + break; + case 9: + end(); + break; + case 10: + switch(buttonId){ + case 1: + interpreter.sendOptions("Which ones do you want to sell?", "Clay and Ivory", "Stone","Gold","Sell them all!"); + stage = 20; + break; + case 2: + npc("Aww, alright. Well, keep my", "offer in mind, will ya?"); + player("Sure thing, Simon."); + npc("Thanks, mate."); + stage = 999; + break; + } + break; + case 20: + switch(buttonId){ + case 1: + end(); + for(int j = 0; j < 28; j++){ + switch(player.getInventory().getId(j)){ + case 9032: + player.getInventory().remove(new Item(9032),j,true); + player.getInventory().add(new Item(995, 75)); + break; + case 9036: + player.getInventory().remove(new Item(9036),j,true); + player.getInventory().add(new Item(995, 100)); + break; + case 9026: + player.getInventory().remove(new Item(9026),j,true); + player.getInventory().add(new Item(995, 50)); + break; + } + } + stage = 999; + break; + case 2: + end(); + for(int j = 0; j < 28; j++){ + switch(player.getInventory().getId(j)){ + case 9042: + player.getInventory().remove(new Item(9042),j,true); + player.getInventory().add(new Item(995, 150)); + break; + case 9030: + player.getInventory().remove(new Item(9030),j,true); + player.getInventory().add(new Item(995, 175)); + break; + case 9038: + player.getInventory().remove(new Item(9038),j,true); + player.getInventory().add(new Item(995, 200)); + break; + } + } + stage = 999; + break; + case 3: + end(); + for(int j = 0; j < 28; j++){ + switch(player.getInventory().getId(j)){ + case 9040: + player.getInventory().remove(new Item(9040),j,true); + player.getInventory().add(new Item(995, 750)); + break; + case 9028: + player.getInventory().remove(new Item(9028),j,true); + player.getInventory().add(new Item(995, 1000)); + break; + case 9034: + player.getInventory().remove(new Item(9034),j,true); + player.getInventory().add(new Item(995, 1250)); + break; + } + } + stage = 999; + break; + case 4: + end(); + for(int j = 0; j < 28; j++){ + switch(player.getInventory().getId(j)){ + case 9040: + player.getInventory().remove(new Item(9040),j,true); + player.getInventory().add(new Item(995, 750)); + break; + case 9028: + player.getInventory().remove(new Item(9028),j,true); + player.getInventory().add(new Item(995, 1000)); + break; + case 9034: + player.getInventory().remove(new Item(9034),j,true); + player.getInventory().add(new Item(995, 1250)); + break; + case 9042: + player.getInventory().remove(new Item(9042),j,true); + player.getInventory().add(new Item(995, 150)); + break; + case 9030: + player.getInventory().remove(new Item(9030),j,true); + player.getInventory().add(new Item(995, 175)); + break; + case 9038: + player.getInventory().remove(new Item(9038),j,true); + player.getInventory().add(new Item(995, 200)); + break; + case 9032: + player.getInventory().remove(new Item(9032),j,true); + player.getInventory().add(new Item(995, 75)); + break; + case 9036: + player.getInventory().remove(new Item(9036),j,true); + player.getInventory().add(new Item(995, 100)); + break; + case 9026: + player.getInventory().remove(new Item(9026),j,true); + player.getInventory().add(new Item(995, 50)); + break; + } + } + stage = 999; + break; + } + break; + case 30: + player("What! This is a genuine pharaoh's scepter - made out of"," solid gold and finely jewelled with precious gems"," by the finest craftsmen in the area."); + stage = 31; + break; + case 31: + npc("Strewth! I can tell a pile of croc when I hear it!","You've got the patter mate, but I'm no mug.", "That's a fake."); + stage = 32; + break; + case 32: + player("It has magical powers!"); + stage = 33; + break; + case 33: + npc("Oh, magical powers... yeah yeah yeah. Heard it all before"," mate. I'll give you 100 gold, or some 'magic beans'.", "Take it or leave it."); + stage = 34; + break; + case 34: + player("I don't think so! I'll find someone who'll give me", "what it's worth."); + stage = 35; + break; + case 35: + npc("Suit yerself..."); + stage = 999; + break; + case 999: + end(); + break; + } + return true; + } + @Override + public int[] getIds() { + return new int[] { 3123 }; + } +} diff --git a/Server/src/main/content/region/desert/handlers/DesertZone.java b/Server/src/main/content/region/desert/handlers/DesertZone.java new file mode 100644 index 0000000..0708892 --- /dev/null +++ b/Server/src/main/content/region/desert/handlers/DesertZone.java @@ -0,0 +1,208 @@ +package content.region.desert.handlers; + +import java.util.ArrayList; +import java.util.List; + +import core.cache.def.impl.ItemDefinition; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.ImpactHandler.HitsplatType; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneBuilder; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; +import core.plugin.Initializable; +import core.tools.RandomFunction; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.impact; +import static core.api.ContentAPIKt.playAudio; + +/** + * The desert zone map. + * @author Emperor + * @author 'Vexia + * @version 2.0 + */ +@Initializable +public final class DesertZone extends MapZone implements Plugin { + + /** + * Represents the hydrateable waterskin items. + */ + private static final Item[] WATER_SKINS = new Item[] { new Item(1823), new Item(1825), new Item(1827), new Item(1829) }; + + /** + * Represents data of water vessils to dry up. + */ + private static final int[][] VESSILS = new int[][] { { 1937, 1935 }, { 1929, 1925 }, { 1921, 1923 }, { 227, 229 } }; + + /** + * Represents the animation of drinking water. + */ + private static final Animation ANIMATION = new Animation(829); + + /** + * The players list. + */ + private static final List PLAYERS = new ArrayList<>(20); + + /** + * The water draining pulse. + */ + private static Pulse pulse = new Pulse(3) { + @Override + public boolean pulse() { + for (Player player : PLAYERS) { + if (!player.getAttribute("tutorial:complete", false) || player.getInterfaceManager().isOpened() || player.getInterfaceManager().hasChatbox() || player.getLocks().isMovementLocked()) { + continue; + } + if (player.getAttribute("desert-delay", -1) < GameWorld.getTicks()) { + effect(player); + } + } + return PLAYERS.isEmpty(); + } + }; + + /** + * Method used to handle the desert effect on the Player. + * @param p the Player. + */ + private static void effect(Player p) { + p.setAttribute("desert-delay", GameWorld.getTicks() + getDelay(p)); + evaporate(p); + if (drink(p)) { + return; + } + impact(p, RandomFunction.random(1, p.getLocation().getY() < 2990 ? 12 : 8), HitsplatType.NORMAL); + p.getPacketDispatch().sendMessage("You start dying of thirst while you're in the desert."); + } + + /** + * Method used to evaporate the water vessils in the inventory. + * @param p the Player + */ + public static void evaporate(Player p) { + for (int i = 0; i < VESSILS.length; i++) { + if (p.getInventory().contains(VESSILS[i][0], 1)) { + if (p.getInventory().remove(new Item(VESSILS[i][0]))) { + p.getInventory().add(new Item(VESSILS[i][1])); + p.getPacketDispatch().sendMessage("The water in your " + ItemDefinition.forId(VESSILS[i][0]).getName().toLowerCase().replace("of water", "").trim() + " evaporates in the desert heat."); + } + } + } + } + + /** + * Method used to drink a waterskin in the inventory. + * @param p the player. + */ + public static boolean drink(Player p) { + for (Item i : WATER_SKINS) { + if (p.getInventory().containsItem(i) && p.getInventory().remove(i)) { + p.getInventory().add(new Item(i.getId() + 2)); + p.animate(ANIMATION); + p.getPacketDispatch().sendMessage("You take a drink of water."); + playAudio(p, Sounds.LIQUID_2401); + return true; + } + } + if (p.getInventory().contains(1831, 1)) { + p.getPacketDispatch().sendMessage("Perhaps you should fill up one of your empty waterskins."); + } else { + p.getPacketDispatch().sendMessage("You should get a waterskin for any travelling in the desert."); + } + return false; + } + + /** + * Method used to calculate the delay to the next desert effect. + * @param player the player. + * @return Long the amount of the delay. + */ + private static int getDelay(Player player) { + int delay = 116; + if (player.getEquipment().contains(1833, 1)) { + delay += 17; + } + if (player.getEquipment().contains(1835, 1)) { + delay += 17; + } + if (player.getEquipment().contains(1837, 1)) { + delay += 17; + } + return delay; + } + + /** + * Constructs a new {@code DesertZone} {@code Object}. + */ + public DesertZone() { + super("Desert Zone", true); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ZoneBuilder.configure(this); + return this; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public void configure() { + ZoneBorders borders = new ZoneBorders(3063, 2725, 3544, 3115); + borders.addException(new ZoneBorders(3152, 2961, 3191, 2999));// Bandit + // camp + borders.addException(new ZoneBorders(3398, 2914, 3450, 2941));//Nardah + borders.addException(new ZoneBorders(3410, 2883, 3450, 2941));//Nardah2 + borders.addException(new ZoneBorders(3147, 3019, 3185, 3059));// Bedabin + borders.addException(new ZoneBorders(3217, 2881, 3248, 2914));// pyramid + borders.addException(new ZoneBorders(3264, 2752, 3323, 2810));// Sophanem + borders.addException(new ZoneBorders(3326,2942,3371,3006)); //Pollnivneach + borders.addException(new ZoneBorders(3007, 4672, 3071, 4735));// agility-pyramid + // top(region12105) + borders.addException(new ZoneBorders(3274, 3014, 3305, 3041));// Mining + // camp + borders.addException(new ZoneBorders(3260, 9408, 3331, 9472));// Mining + // camp + register(borders); + pulse.stop(); + } + + @Override + public boolean enter(Entity e) { + if (e instanceof Player) { + Player p = (Player) e; + if (p.getAttribute("tutorial:stage", 0) > 71) { + return true; + } + p.setAttribute("desert-delay", GameWorld.getTicks() + getDelay(p)); + PLAYERS.add(p); + if (!pulse.isRunning()) { + pulse.restart(); + pulse.start(); + GameWorld.getPulser().submit(pulse); + } + } + return true; + } + + @Override + public boolean leave(Entity e, boolean logout) { + if (e instanceof Player) { + PLAYERS.remove(e); + e.removeAttribute("desert-delay"); + } + return super.leave(e, logout); + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/handlers/KalphiteEntranceHandler.java b/Server/src/main/content/region/desert/handlers/KalphiteEntranceHandler.java new file mode 100644 index 0000000..0172a06 --- /dev/null +++ b/Server/src/main/content/region/desert/handlers/KalphiteEntranceHandler.java @@ -0,0 +1,85 @@ +package content.region.desert.handlers; + +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.OptionHandler; +import core.game.interaction.UseWithHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Handles the Kalphite hive entrance. + * @author Emperor + */ +@Initializable +public final class KalphiteEntranceHandler extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + UseWithHandler handler = new UseWithHandler(954) { + @Override + public boolean handle(NodeUsageEvent event) { + Scenery object = (Scenery) event.getUsedWith(); + if (object.getId() == 3827 || object.getId() == 23609) { + if (event.getPlayer().getInventory().remove(event.getUsedItem())) { + SceneryBuilder.replace(object, object.transform(object.getId() + 1), 500); + return true; + } + } + return false; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + return this; + } + }; + UseWithHandler.addHandler(3827, UseWithHandler.OBJECT_TYPE, handler); + UseWithHandler.addHandler(23609, UseWithHandler.OBJECT_TYPE, handler); + SceneryDefinition.forId(3828).getHandlers().put("option:climb-down", this); + SceneryDefinition.forId(3829).getHandlers().put("option:climb-up", this); + SceneryDefinition.forId(23610).getHandlers().put("option:climb-down", this); + SceneryDefinition.forId(3832).getHandlers().put("option:climb-up", this); + return this; + } + + @Override + public boolean handle(final Player player, Node node, String option) { + Scenery object = (Scenery) node; + Location destination = null; + switch (object.getId()) { + case 3828: + destination = Location.create(3483, 9509, 2); + break; + case 3829: + destination = Location.create(3229, 3109, 0); + break; + case 23610: + destination = Location.create(3508, 9493, 0); + break; + case 3832: + destination = Location.create(3509, 9496, 2); + break; + } + final Location dest = destination; + player.lock(2); + player.animate(Animation.create(828)); + GameWorld.getPulser().submit(new Pulse(1, player) { + @Override + public boolean pulse() { + player.getProperties().setTeleportLocation(dest); + return true; + } + }); + return true; + } + +} diff --git a/Server/src/main/content/region/desert/handlers/KalphiteQueenArea.kt b/Server/src/main/content/region/desert/handlers/KalphiteQueenArea.kt new file mode 100644 index 0000000..e59ae6c --- /dev/null +++ b/Server/src/main/content/region/desert/handlers/KalphiteQueenArea.kt @@ -0,0 +1,10 @@ +package content.region.desert.handlers + +import core.api.* +import core.game.world.map.zone.ZoneBorders +import core.game.world.map.zone.ZoneRestriction + +class KalphiteQueenArea : MapArea { + override fun defineAreaBorders() : Array { return arrayOf(ZoneBorders(3456, 9472, 3519, 9535, 0, true)) } + override fun getRestrictions() : Array { return arrayOf(ZoneRestriction.RANDOM_EVENTS) } +} diff --git a/Server/src/main/content/region/desert/handlers/KalphiteQueenNPC.java b/Server/src/main/content/region/desert/handlers/KalphiteQueenNPC.java new file mode 100644 index 0000000..be677c5 --- /dev/null +++ b/Server/src/main/content/region/desert/handlers/KalphiteQueenNPC.java @@ -0,0 +1,390 @@ +package content.region.desert.handlers; + +import java.util.ArrayList; +import java.util.List; + +import content.data.BossKillCounter; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.node.entity.combat.InteractionType; +import core.game.node.entity.combat.equipment.ArmourSet; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.tools.RandomFunction; + +import content.region.kandarin.quest.dwarfcannon.dmc.DMCHandler; + +/** + * Handles the Kalphite Queen. + * @author Emperor + * @version 1.0 + */ +@Initializable +public final class KalphiteQueenNPC extends AbstractNPC { + + /** + * The default spawn location. + */ + // 3474, 9495, 0 + private static final Location DEFAULT_SPAWN = Location.create(3222, 3217, 0); + + /** + * The transform animation. + */ + private static final Animation TRANSFORM_ANIM = new Animation(6270, Priority.HIGH); + + /** + * The combat swing handler. + */ + private CombatSwingHandler combatHandler = new KQCombatSwingHandler(); + + /** + * Constructs a new {@code KalphiteQueenNPC} {@code Object}. + */ + public KalphiteQueenNPC() { + this(1158, DEFAULT_SPAWN); + } + + /** + * Constructs a new {@code KalphiteQueenNPC} {@code Object}. + */ + public KalphiteQueenNPC(int id, Location spawn) { + super(id, spawn); + super.setAggressive(true); + } + + @Override + public CombatSwingHandler getSwingHandler(boolean swing) { + return combatHandler; + } + + @Override + public boolean hasProtectionPrayer(CombatStyle style) { + if (getId() == 1158) { + return style == CombatStyle.MAGIC || style == CombatStyle.RANGE; + } + return style == CombatStyle.MELEE; + } + + @Override + public void tick() { + super.tick(); + } + + @Override + public void init() { + super.init(); + setRespawn(true); + configureBossData(); + } + + @Override + public void finalizeDeath(Entity killer) { + if (getId() == 1160) { + removeAttribute("disable:drop"); + super.finalizeDeath(killer); + reTransform(); + BossKillCounter.addtoKillcount((Player) killer, 1160); + return; + } + BossKillCounter.addtoKillcount((Player) killer, this.getId()); + setAttribute("disable:drop", true); + super.finalizeDeath(killer); + super.setRespawnTick(-1); + super.getWalkingQueue().reset(); + super.getLocks().lockMovement(10); + transform(1160); + getProperties().setTeleportLocation(null); + getAnimator().setPriority(Priority.LOW); + visualize(TRANSFORM_ANIM, Graphics.create(1055)); + lock(TRANSFORM_ANIM.getDuration() + 1); + } + + @Override + public void sendImpact(BattleState state) { + if (state.getEstimatedHit() > 31) { + state.setEstimatedHit(RandomFunction.random(1, 12)); + } + if (state.getVictim() instanceof Player) { + Player player = state.getVictim().asPlayer(); + DMCHandler handler = player.getAttribute("dmc"); + if (handler != null && handler.getCannon() != null && handler.getCannon().isActive()) { + + } + } + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new KalphiteQueenNPC(id, location); + } + + @Override + public int[] getIds() { + return new int[] { 1158, 1160 }; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (int id : getIds()) { + mapping.put(id, this); + } + return this; + } + + /** + * Handles the Kalphite Queen combat swings. + * @author Emperor + */ + static class KQCombatSwingHandler extends CombatSwingHandler { + + /** + * The melee attack anim for the first form. + */ + private static final Animation MELEE_ATTACK_1 = new Animation(6241, Priority.HIGH); + + /** + * The range/magic attack anim for the first form. + */ + private static final Animation RANGE_ATTACK_1 = new Animation(6240, Priority.HIGH); + + /** + * The magic graphic for the first form. + */ + private static final Graphics MAGIC_GFX_1 = Graphics.create(278); + + /** + * The melee attack anim for the first form. + */ + private static final Animation MELEE_ATTACK_2 = new Animation(6235, Priority.HIGH); + + /** + * The range/magic attack anim for the first form. + */ + private static final Animation RANGE_ATTACK_2 = new Animation(6234, Priority.HIGH); + + /** + * The magic graphic for the first form. + */ + private static final Graphics MAGIC_GFX_2 = Graphics.create(279); + + /** + * The end graphic for magic. + */ + private static final Graphics MAGIC_END_GFX = Graphics.create(281); + + /** + * The style. + */ + private CombatStyle style = CombatStyle.RANGE; + + /** + * Constructs a new {@code KalphiteQueenNPC} {@code Object}. + */ + public KQCombatSwingHandler() { + super(CombatStyle.RANGE); + } + + @Override + public InteractionType canSwing(Entity entity, Entity victim) { + return getType().getSwingHandler().canSwing(entity, victim); + } + + /** + * Gets the range targets. + * @param e The entity. + * @param victim The victim. + * @return The targets array. + */ + private BattleState[] getRangeTargets(Entity e, Entity victim) { + List list = new ArrayList<>(20); + for (Entity t : RegionManager.getLocalPlayers(victim, -1 + (int) e.getCenterLocation().getDistance(victim.getLocation()))) { + if (t.isAttackable(e, CombatStyle.RANGE, false)) { + list.add(new BattleState(e, t)); + } + } + return list.toArray(new BattleState[list.size()]); + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + style = super.getType(); + super.setType(CombatStyle.values()[1 + RandomFunction.RANDOM.nextInt(2)]); + int ticks = 1; + if (CombatStyle.MELEE.getSwingHandler().canSwing(entity, victim) != InteractionType.NO_INTERACT && RandomFunction.random(10) < 4) { + style = CombatStyle.MELEE; + } else { + ticks += (int) Math.ceil(entity.getLocation().getDistance(victim.getLocation()) * (style == CombatStyle.MAGIC ? 0.5 : 0.3)); + } + BattleState[] targets = new BattleState[] { state }; + if (style == CombatStyle.RANGE) { + targets = getRangeTargets(entity, victim); + state.setTargets(targets); + } + state.setStyle(style); + int max = calculateHit(entity, victim, 1.0); + if (max > 31) { + max = RandomFunction.random(5, 28); + } + for (BattleState s : targets) { + int hit = 0; + s.setStyle(style); + if (isAccurateImpact(entity, s.getVictim())) { + s.setMaximumHit(max); + hit = RandomFunction.random(max); + } + if (victim.hasProtectionPrayer(CombatStyle.RANGE)) { + s.setEstimatedHit(0); + } else { + s.setEstimatedHit(hit); + } + } + return ticks; + } + + @Override + public void visualize(Entity entity, Entity victim, BattleState state) { + boolean secondForm = entity instanceof NPC && ((NPC) entity).getId() == 1160; + switch (state.getStyle()) { + case MELEE: + entity.animate(secondForm ? MELEE_ATTACK_2 : MELEE_ATTACK_1); + break; + case RANGE: + for (BattleState s : state.getTargets()) { + if (s != null) { + Projectile.ranged(entity, s.getVictim(), secondForm ? 289 : 288, 41, 36, 50, 15).send(); + } + } + entity.animate(secondForm ? RANGE_ATTACK_2 : RANGE_ATTACK_1); + break; + case MAGIC: + Projectile.magic(entity, victim, 280, 41, 36, 50, 15).send(); + entity.visualize(secondForm ? RANGE_ATTACK_2 : RANGE_ATTACK_1, secondForm ? MAGIC_GFX_2 : MAGIC_GFX_1); + break; + } + } + + @Override + public void visualizeImpact(Entity entity, Entity victim, BattleState state) { + if (state.getStyle() == CombatStyle.MAGIC) { + victim.graphics(MAGIC_END_GFX); + } + state.getStyle().getSwingHandler().visualizeImpact(entity, victim, state); + } + + @Override + public void adjustBattleState(Entity entity, Entity victim, BattleState state) { + state.getStyle().getSwingHandler().adjustBattleState(entity, victim, state); + } + + @Override + public int calculateAccuracy(Entity entity) { + return style.getSwingHandler().calculateAccuracy(entity); + } + + @Override + public int calculateDefence(Entity victim, Entity attacker) { + return style.getSwingHandler().calculateDefence(victim, attacker); + } + + @Override + public int calculateHit(Entity entity, Entity victim, double modifier) { + return style.getSwingHandler().calculateHit(entity, victim, modifier); + } + + @Override + public void impact(Entity entity, Entity victim, BattleState state) { + CombatStyle style = state.getStyle(); + if (style == CombatStyle.RANGE && state.getTargets() != null) { + for (BattleState s : state.getTargets()) { + style.getSwingHandler().impact(entity, s.getVictim(), s); + } + return; + } + if (style == CombatStyle.MAGIC) { + BattleState[] states = new BattleState[entity.getViewport().getCurrentPlane().getPlayers().size() + 1]; + int index = 1; + if (states.length == 0) { + return; + } + for (Player p : entity.getViewport().getCurrentPlane().getPlayers()) { + if (p != victim) { + states[index++] = new BattleState(entity, p); + } + } + states[0] = new BattleState(); + handleMagicImpact(entity, entity, victim, states, 0); + return; + } + style.getSwingHandler().impact(entity, victim, state); + } + + /** + * Handles a magic impact. + * @param e The entity. + * @param last The last entity to receive the impact. + * @param victim The victim. + * @param targets The list of targets. + * @param index The current target index. + */ + private void handleMagicImpact(final Entity e, final Entity last, final Entity victim, final BattleState[] targets, int index) { + if (targets == null || index >= targets.length) { + return; + } + BattleState s = targets[index]; + if (s == null) { + return; + } + int hit = 0; + if (CombatStyle.MAGIC.getSwingHandler().isAccurateImpact(e, victim)) { + hit = RandomFunction.RANDOM.nextInt(32); + } + if (victim.hasProtectionPrayer(CombatStyle.MAGIC)) { + hit = 0; + } + s.setEstimatedHit(hit); + CombatStyle.MAGIC.getSwingHandler().adjustBattleState(e, victim, s); + victim.getImpactHandler().handleImpact(e, s.getEstimatedHit(), CombatStyle.MAGIC, s); + CombatStyle.MAGIC.getSwingHandler().onImpact(e, victim, s); + while (++index < targets.length && (s = targets[index]) == null) + ; + if (s == null || index >= targets.length) { + return; + } + final BattleState t = s; + final int targetIndex = index; + t.getVictim().graphics(MAGIC_END_GFX); + Projectile.create(victim, t.getVictim(), 280, 41, 36, 0, 30, 15, 11).send(); + GameWorld.getPulser().submit(new Pulse(1, t.getVictim()) { + @Override + public boolean pulse() { + handleMagicImpact(e, victim, t.getVictim(), targets, targetIndex); + return true; + } + }); + } + + @Override + public ArmourSet getArmourSet(Entity e) { + return style.getSwingHandler().getArmourSet(e); + } + + @Override + public double getSetMultiplier(Entity e, int skillId) { + return style.getSwingHandler().getSetMultiplier(e, skillId); + } + } +} diff --git a/Server/src/main/content/region/desert/handlers/KhardianInteractionPlugin.java b/Server/src/main/content/region/desert/handlers/KhardianInteractionPlugin.java new file mode 100644 index 0000000..c2dbc42 --- /dev/null +++ b/Server/src/main/content/region/desert/handlers/KhardianInteractionPlugin.java @@ -0,0 +1,103 @@ +package content.region.desert.handlers; + +import core.cache.def.impl.SceneryDefinition; +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; +import core.tools.RandomFunction; + +/** + * Represents the khardian node interaction plugin. + * @author 'Vexia + * @date 06/11/2013 + */ +@Initializable +public final class KhardianInteractionPlugin extends OptionHandler { + + /** + * Represents the hydrateable waterskin items. + */ + private static final Item[] WATER_SKINS = new Item[] { new Item(1825), new Item(1827), new Item(1829), new Item(1831) }; + + /** + * Represents the animation of cutting a cactus. + */ + private static final Animation ANIMATION = new Animation(911); + + /** + * Represents the dry cactus object id. + */ + private static final int DRY_CACTUS = 2671; + + /** + * Represents the item used to cut a cactus. + */ + private static final Item KNIFE = new Item(946); + + /** + * Represents the delay a cactus spawns at. + */ + private static final int SPAWN_DELAY = 45; + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(2670).getHandlers().put("option:cut", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + switch (option) { + case "cut": + if (!player.getInventory().containsItem(KNIFE)) { + player.getPacketDispatch().sendMessage("You need a knife to cut this Cactus..."); + return true; + } + boolean failed = false; + if (RandomFunction.random(3) == 1) { + failed = true; + player.getPacketDispatch().sendMessage("You fail to cut the cactus correctly and it gives you no water this time."); + } + if (!failed) { + final Item remove = getWaterSkin(player); + if (remove != null && player.getInventory().remove(remove)) { + player.getInventory().add(new Item(remove.getId() - 2)); + player.getPacketDispatch().sendMessage("You top up your skin with water from the cactus."); + } else { + player.getPacketDispatch().sendMessage("You have no empty waterskins to put the water in."); + } + } + player.lock(3); + player.animate(ANIMATION); + if (!failed) { + player.getSkills().addExperience(Skills.WOODCUTTING, 10, true); + } + SceneryBuilder.replace(((Scenery) node), new Scenery(DRY_CACTUS, node.getLocation()), SPAWN_DELAY + RandomFunction.random(RegionManager.getLocalPlayers(player).size() / 2)); + break; + } + return true; + } + + /** + * Method used to get a waterskin Item. + * @param player the Player. + * @return the Item or Null. + */ + public final Item getWaterSkin(final Player player) { + for (Item item : WATER_SKINS) { + if (player.getInventory().containsItem(item)) { + return item; + } + } + return null; + } + +} diff --git a/Server/src/main/content/region/desert/handlers/ShantayOptionPlugin.java b/Server/src/main/content/region/desert/handlers/ShantayOptionPlugin.java new file mode 100644 index 0000000..cfda828 --- /dev/null +++ b/Server/src/main/content/region/desert/handlers/ShantayOptionPlugin.java @@ -0,0 +1,37 @@ +package content.region.desert.handlers; + +import core.cache.def.impl.NPCDefinition; +import core.plugin.Initializable; +import core.game.dialogue.DialogueInterpreter; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Plugin; + +/** + * Represents the option plguin. + * @author 'Vexia + */ +@Initializable +public class ShantayOptionPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + NPCDefinition.forId(836).getHandlers().put("option:buy-pass", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + DialogueInterpreter interpreter = player.getDialogueInterpreter(); + if (player.getInventory().remove(new Item(995, 5))) { + player.getInventory().add(new Item(1854)); + interpreter.sendItemMessage(1854, "You purchase a Shantay Pass."); + } else { + interpreter.sendDialogues(player, null, "Sorry, I don't seem to have enough money."); + } + return true; + } + +} diff --git a/Server/src/main/content/region/desert/handlers/ShantayPassPlugin.java b/Server/src/main/content/region/desert/handlers/ShantayPassPlugin.java new file mode 100644 index 0000000..74ae051 --- /dev/null +++ b/Server/src/main/content/region/desert/handlers/ShantayPassPlugin.java @@ -0,0 +1,156 @@ +package content.region.desert.handlers; + +import core.api.Container; +import core.cache.def.impl.NPCDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.dialogue.FacialExpression; +import core.game.global.action.DoorActionHandler; +import content.global.skill.agility.AgilityHandler; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.plugin.Plugin; +import org.rs09.consts.Items; + +import static core.api.ContentAPIKt.*; +import static core.tools.TickUtilsKt.ticksToCycles; + +/** + * Represents the plugin to handle the shantay pass. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public class ShantayPassPlugin extends OptionHandler { + + /** + * Represents a shantay pass item. + */ + private static final Item PASS = new Item(1854); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (int i = 35542; i < 35545; i++) { + SceneryDefinition.forId(i).getHandlers().put("option:look-at", this); + SceneryDefinition.forId(i).getHandlers().put("option:go-through", this); + SceneryDefinition.forId(i).getHandlers().put("option:quick-pass", this); + } + SceneryDefinition.forId(35400).getHandlers().put("option:look-at", this); + SceneryDefinition.forId(35400).getHandlers().put("option:go-through", this); + SceneryDefinition.forId(35400).getHandlers().put("option:quick-pass", this); + NPCDefinition.forId(838).getHandlers().put("option:bribe", this); + SceneryDefinition.forId(35401).getHandlers().put("option:open", this); + SceneryDefinition.forId(2693).getHandlers().put("option:open", this); + new ShantayComponentPlugin().newInstance(arg); + return this; + } + + @Override + public boolean handle(final Player player, Node node, String option) { + final int id = node instanceof Scenery ? ((Scenery) node).getId() : ((NPC) node).getId(); + switch (option) { + case "open": + if (id == 2693) { + player.getBank().open(); + return true; + } + if (player.getAttribute("shantay-jail", false) && player.getLocation().getX() > 3299) { + player.removeAttribute("shantay-jail");// if we tele + // out(witch is + // allowed) then we + // need to remove. + } + if (!player.getAttribute("shantay-jail", false)) { + DoorActionHandler.handleDoor(player, (Scenery) node); + return true; + } else { + player.getDialogueInterpreter().open(836, null, true); + } + break; + case "bribe": + player.getDialogueInterpreter().open(838, ((NPC) node)); + break; + case "look-at": + player.getDialogueInterpreter().sendDialogue("The Desert is a VERY Dangerous place. Do not enter if you are", "afraid of dying. Beware of high temperatures, and storms, robbers,", "and slavers. No responsibility is taken by Shantay if anything bad", "should happen to you in any circumstances whatsoever."); + break; + case "go-through": + if (player.getLocation().getY() < 3117) { + player.getPacketDispatch().sendMessage("You go through the gate."); + AgilityHandler.walk(player, 0, player.getLocation(), player.getLocation().transform(0, player.getLocation().getY() > 3116 ? -2 : 2, 0), null, 0, null); + return true; + } + player.getInterfaceManager().open(new Component(565)); + break; + case "quick-pass": + if (player.getLocation().getY() > 3116) { + if (!inInventory(player, Items.SHANTAY_PASS_1854, 1)) { + sendNPCDialogue(player, 838, "You need a Shantay pass to get through this gate. See Shantay, he will sell you one for a very reasonable price.", FacialExpression.NEUTRAL, false); + return true; + } + if (!removeItem(player, Items.SHANTAY_PASS_1854, Container.INVENTORY)) return true; + sendMessage(player, "You hand your Shantay pass to the guard and pass through the gate."); + } + forceMove(player, player.getLocation(), player.getLocation().transform(0, player.getLocation().getY() > 3116 ? -2 : 2, 0), 0, ticksToCycles(2), null, 819, null); + break; + } + return true; + } + + @Override + public Location getDestination(Node node, Node n) { + if (n instanceof Scenery) { + final Scenery object = (Scenery) n; + if (object.getId() == 35543) { + return object.getLocation().transform(-1, node.getLocation().getY() > n.getLocation().getY() ? 1 : -1, 0); + } else if (object.getId() == 35544) { + return object.getLocation().transform(-1, node.getLocation().getY() > n.getLocation().getY() ? 1 : -1, 0); + } else if (object.getId() == 35542) { + return object.getLocation().transform(1, node.getLocation().getY() > n.getLocation().getY() ? 1 : -1, 0); + } + } + return null; + } + + /** + * Represents the shantay component plugin. + * @author 'Vexia + * @version 1.0 + */ + public final class ShantayComponentPlugin extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.forId(565).setPlugin(this); + return this; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + switch (button) { + case 17:// proceed. + player.getInterfaceManager().close(); + if (!player.getInventory().containsItem(PASS)) { + player.getDialogueInterpreter().sendDialogues(838, null, "You need a Shantay pass to get through this gate. See", "Shantay, he will sell you one for a very reasonable", "price."); + return true; + } else { + player.getDialogueInterpreter().open(838, null, true); + } + break; + case 18:// stay out. + player.getInterfaceManager().close(); + player.getDialogueInterpreter().sendDialogue("You decide that your visit to the desert can be postponed.", "Perhaps indefinitely."); + break; + } + return true; + } + + } +} diff --git a/Server/src/main/content/region/desert/handlers/TollGateOptionPlugin.java b/Server/src/main/content/region/desert/handlers/TollGateOptionPlugin.java new file mode 100644 index 0000000..2c9f338 --- /dev/null +++ b/Server/src/main/content/region/desert/handlers/TollGateOptionPlugin.java @@ -0,0 +1,55 @@ +package content.region.desert.handlers; + +import core.cache.def.impl.SceneryDefinition; +import core.game.global.action.DoorActionHandler; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.world.repository.Repository; +import core.plugin.Initializable; +import core.plugin.Plugin; + +import static core.game.system.command.sets.StatAttributeKeysKt.STATS_ALKHARID_GATE; +import static core.game.system.command.sets.StatAttributeKeysKt.STATS_BASE; +import content.data.Quests; + +@Initializable +public class TollGateOptionPlugin extends OptionHandler { + + @Override + public boolean handle(Player player, Node node, String option) { + if (option.equals("pay-toll(10gp)")) { + if (player.getQuestRepository().getQuest(Quests.PRINCE_ALI_RESCUE).getStage(player) > 50) { + player.getPacketDispatch().sendMessage("The guards let you through for free."); + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + } else { + if (player.getInventory().contains(995, 10)) { + player.getInventory().remove(new Item(995, 10)); + player.getPacketDispatch().sendMessage("You quickly pay the 10 gold toll and go through the gates."); + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + player.incrementAttribute("/save:" + STATS_BASE + ":" + STATS_ALKHARID_GATE, 10); + return true; + } else { + player.getPacketDispatch().sendMessage("You need 10 gold to pass through the gates."); + } + } + } else { + player.getDialogueInterpreter().open(925, Repository.findNPC(925), (Scenery) node); + return true; + } + return true; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(35551).getHandlers().put("option:open", this); + SceneryDefinition.forId(35551).getHandlers().put("option:pay-toll(10gp)", this); + SceneryDefinition.forId(35549).getHandlers().put("option:open", this); + SceneryDefinition.forId(35549).getHandlers().put("option:pay-toll(10gp)", this); + SceneryDefinition.forId(2882).getHandlers().put("option:pay-toll(10gp)", this); + return this; + } + +} diff --git a/Server/src/main/content/region/desert/nardah/dialogue/AliTheCarter.java b/Server/src/main/content/region/desert/nardah/dialogue/AliTheCarter.java new file mode 100644 index 0000000..aabc56c --- /dev/null +++ b/Server/src/main/content/region/desert/nardah/dialogue/AliTheCarter.java @@ -0,0 +1,99 @@ +package content.region.desert.nardah.dialogue; + +import core.plugin.Initializable; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; + +/** + * Handles Ali the Carter, TODO: Add more dialogue after Spirits of the Elid is added + * @author ceik + */ + +@Initializable +public class AliTheCarter extends DialoguePlugin { + public AliTheCarter(){ + /** + * Empty + */ + } + public AliTheCarter(Player player){super(player);} + @Override + public DialoguePlugin newInstance(Player player){return new AliTheCarter(player);} + public boolean open(Object... args){ + npc = (NPC)args[0]; + player("Hello"); + return true; + } + + public boolean handle(int interfaceId, int buttonId){ + switch(stage){ + case 0: + npc("Hello, friend! Welcome to Nardah.","Do you happen to be in need of water?"); + stage++; + break; + case 1: + interpreter.sendOptions("Select one","Yes I am!","No thank you I'm good."); + stage++; + break; + case 2: + switch(buttonId){ + case 1: + player("Yes I am!"); + stage = 3; + break; + case 2: + player("No thank you."); + stage = 10; + break; + } + break; + case 3: + npc("It'll be 1000 coins for a full waterskin."); + stage++; + break; + case 4: + interpreter.sendOptions("Select one","Oh, wow. Um, sure.","Oh my! No thank you."); + stage++; + break; + case 5: + switch(buttonId){ + case 1: + player("Oh, wow. Um, sure."); + stage++; + break; + case 2: + player("Oh my! No thank you."); + stage = 10; + break; + } + break; + case 6: + if(player.getInventory().contains(995,1000)){ + player.getInventory().remove(new Item(995,1000)); + if(player.getInventory().freeSlots() > 0) { + player.getInventory().add(new Item(1823)); + } else { + GroundItemManager.create(new Item(1823),player.getLocation()); + } + end(); + } else { + player("Err, I seem to not have enough gold."); + stage++; + } + break; + case 7: + npc("Too bad, friend."); + stage = 10; + break; + case 10: + end(); + break; + } + return true; + } + @Override + public int[] getIds() {return new int[] {3030};} +} diff --git a/Server/src/main/content/region/desert/nardah/dialogue/ArtimeusDialogue.java b/Server/src/main/content/region/desert/nardah/dialogue/ArtimeusDialogue.java new file mode 100644 index 0000000..94ee664 --- /dev/null +++ b/Server/src/main/content/region/desert/nardah/dialogue/ArtimeusDialogue.java @@ -0,0 +1,68 @@ +package content.region.desert.nardah.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; + +/** + * Handles dialogue for Artimeus + * @author ceik + */ + +@Initializable +public class ArtimeusDialogue extends DialoguePlugin { + public ArtimeusDialogue(){ + /** + * Empty + */ + } + public ArtimeusDialogue(Player player){ + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player){return new ArtimeusDialogue(player);} + + @Override + public boolean open(Object... args){ + npc("Greetings, friend; my business here deals with Hunter","related items. Is there anything in which I can interest you?"); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId){ + switch(stage){ + case 0: + interpreter.sendOptions("Select one","What kind of items do you stock?","I'm not in the market for Hunter equipment right now, thanks."); + stage++; + break; + case 1: + switch(buttonId){ + case 1: + player("What kind of items do you stock?"); + stage++; + break; + case 2: + player("I'm not in the market for Hunter equipment","right now, thanks."); + stage = 10; + break; + } + break; + case 2: + npc("Have a look for yourself."); + stage++; + break; + case 3: + end(); + NPC Artimeus = new NPC(5109); + Artimeus.openShop(player); + break; + case 10: + end(); + break; + } + return true; + } + public int[] getIds() {return new int[] {5109};} +} diff --git a/Server/src/main/content/region/desert/nardah/dialogue/Awusah.java b/Server/src/main/content/region/desert/nardah/dialogue/Awusah.java new file mode 100644 index 0000000..2d2f471 --- /dev/null +++ b/Server/src/main/content/region/desert/nardah/dialogue/Awusah.java @@ -0,0 +1,42 @@ +package content.region.desert.nardah.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; + +/** + * Handles Awusah pre-quest + * @author ceik + */ +@Initializable +public class Awusah extends DialoguePlugin { + //TODO: Add dialogue for after the quest Spirits of Elid + public Awusah(){ + /** + * Empty + */ + } + public Awusah(Player player){ + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player){return new Awusah(player);} + + @Override + public boolean open(Object... args){ + interpreter.sendDialogue("The mayor doesn't seem interested in talking to you right now."); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId){ + switch(stage){ + case 0: + end(); + break; + } + return true; + } + public int[] getIds() {return new int[] {3040};} +} diff --git a/Server/src/main/content/region/desert/nardah/dialogue/Ghaslor.java b/Server/src/main/content/region/desert/nardah/dialogue/Ghaslor.java new file mode 100644 index 0000000..c8f1601 --- /dev/null +++ b/Server/src/main/content/region/desert/nardah/dialogue/Ghaslor.java @@ -0,0 +1,44 @@ +package content.region.desert.nardah.dialogue; + +import core.plugin.Initializable; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; + +/** + * Handles Ghaslor dialogue + * @author ceik + */ + +//TODO: Add post-quest dialogue +@Initializable +public class Ghaslor extends DialoguePlugin { + public Ghaslor(){ + /** + * empty + */ + } + public Ghaslor(Player player){ + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player){return new Ghaslor(player);} + + @Override + public boolean open(Object... args){ + String gender = player.isMale() ? "gentleman" : "lady"; + npc("Good day young " + gender); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId){ + switch(stage) { + case 0: + end(); + break; + } + return true; + } + public int[] getIds() {return new int[] {3029};} +} diff --git a/Server/src/main/content/region/desert/nardah/dialogue/Kazemde.java b/Server/src/main/content/region/desert/nardah/dialogue/Kazemde.java new file mode 100644 index 0000000..bd293d4 --- /dev/null +++ b/Server/src/main/content/region/desert/nardah/dialogue/Kazemde.java @@ -0,0 +1,85 @@ +package content.region.desert.nardah.dialogue; + +import core.cache.def.impl.NPCDefinition; +import core.game.dialogue.DialoguePlugin; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Handles Kazemde, who runs the general store in Nardah. + * @author ceik + */ + +@Initializable +public class Kazemde extends OptionHandler { + public final int NPC_ID = 3039; + + @Override + public Plugin newInstance(Object arg) throws Throwable { + new KazemdeDialogue().init(); + NPCDefinition.forId(NPC_ID).getHandlers().put("option:trade",this); + NPCDefinition.forId(NPC_ID).getHandlers().put("option:talk-to",this); + return this; + } + + @Override + public final boolean handle(Player player, Node node, String string){ + NPC npc = node.asNpc(); + switch(string){ + case "trade": + npc.openShop(player); + break; + case "talk-to": + player.getDialogueInterpreter().open(NPC_ID); + break; + } + return true; + } + + final class KazemdeDialogue extends DialoguePlugin { + public KazemdeDialogue(){ + /** + * Empty + */ + } + public KazemdeDialogue(Player player){ + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player){return new KazemdeDialogue(player);} + + @Override + public boolean open(Object... args){ + npc("Hello, and welcome to my shop."); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId){ + switch(stage){ + case 0: + interpreter.sendOptions("Select one","Let me see what you have.","Goodbye."); + stage++; + break; + case 1: + switch(buttonId){ + case 1: + end(); + NPC Kazemde = new NPC(NPC_ID); + Kazemde.openShop(player); + break; + case 2: + end(); + break; + } + } + return true; + } + public int[] getIds() {return new int[] {NPC_ID};} + } +} diff --git a/Server/src/main/content/region/desert/nardah/dialogue/Nkuku.kt b/Server/src/main/content/region/desert/nardah/dialogue/Nkuku.kt new file mode 100644 index 0000000..11ceafa --- /dev/null +++ b/Server/src/main/content/region/desert/nardah/dialogue/Nkuku.kt @@ -0,0 +1,41 @@ +package content.region.desert.nardah.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class Nkuku(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + player(FacialExpression.FRIENDLY,"Good day to you.").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> { + npc(FacialExpression.FRIENDLY, "May Saradomin be with you.").also { stage = 99 } + } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return Nkuku(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.NKUKU_3032) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/nardah/dialogue/Rokuh.java b/Server/src/main/content/region/desert/nardah/dialogue/Rokuh.java new file mode 100644 index 0000000..b7e4e49 --- /dev/null +++ b/Server/src/main/content/region/desert/nardah/dialogue/Rokuh.java @@ -0,0 +1,103 @@ +package content.region.desert.nardah.dialogue; + +import core.cache.def.impl.NPCDefinition; +import core.game.dialogue.DialoguePlugin; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Handles Rokuh, who runs the Nardah chocolate stall + * @author ceik + */ + +@Initializable +public class Rokuh extends OptionHandler { + public final int NPC_ID = 3045; + + @Override + public Plugin newInstance(Object arg) throws Throwable { + new RokuhDialogue().init(); + NPCDefinition.forId(NPC_ID).getHandlers().put("option:trade",this); + NPCDefinition.forId(NPC_ID).getHandlers().put("option:talk-to",this); + return this; + } + + @Override + public final boolean handle(Player player, Node node, String string){ + NPC npc = node.asNpc(); + switch(string){ + case "trade": + npc.openShop(player); + break; + case "talk-to": + player.getDialogueInterpreter().open(NPC_ID); + break; + } + return true; + } + + final class RokuhDialogue extends DialoguePlugin { + public RokuhDialogue(){ + /** + * Empty + */ + } + public RokuhDialogue(Player player){ + super(player); + } + @Override + public DialoguePlugin newInstance(Player player){return new RokuhDialogue(player);} + + @Override + public boolean open(Object... args){ + npc("Come one, come all, buy my amazing choc ice invention here!","Chocolate on the outside. Iced cream on the inside.","Oh I also have some chocolate left over from making","choc ices which I'm selling too."); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId){ + switch(stage) { + case 0: + //TODO: Add more options after Spirit of the Elid. + interpreter.sendOptions("Select one", "Cool I'd like to buy some", "No thanks, I'm not interested.", "How do you stop your icy snacks melting?"); + stage++; + break; + case 1: + switch(buttonId){ + case 1: + end(); + NPC Rokuh = new NPC(NPC_ID); + Rokuh.openShop(player); + break; + case 2: + player("No thanks, I'm not interested"); + stage = 10; + break; + case 3: + player("How do you stop your icy snacks melting?","The middle of the desert is the last place I'd expect to see ice."); + stage++; + break; + } + break; + case 2: + npc("It's quite a surprise, isn't it, my friend. I actually have this","special magic box of ice, which I bought for a princely sum","from a strange man while adventuring in lands far away","He said it is imbued with some sort of"); + stage++; + break; + case 3: + npc("powerful ice magic which keeps it cold all the time. I had","never seen any ice magic before, it's clearly very rare","and powerful, so I felt I had to buy it."); + stage = 10; + break; + case 10: + end(); + break; + } + return true; + } + @Override + public int[] getIds() {return new int[]{NPC_ID};} + } +} diff --git a/Server/src/main/content/region/desert/nardah/dialogue/Seddu.java b/Server/src/main/content/region/desert/nardah/dialogue/Seddu.java new file mode 100644 index 0000000..977d4a2 --- /dev/null +++ b/Server/src/main/content/region/desert/nardah/dialogue/Seddu.java @@ -0,0 +1,60 @@ +package content.region.desert.nardah.dialogue; + +import core.plugin.Initializable; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; + +/** + * Added some dialogue for Seddu + * @author ceik + */ + +@Initializable +public class Seddu extends DialoguePlugin { + public Seddu(){ + /** + * Empty + */ + } + public Seddu(Player player){ + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player){return new Seddu(player);} + + @Override + public boolean open(Object... args){ + npc("I buy and sell adventurer's equipment, do you want to trade?"); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId){ + switch(stage){ + case 0: + interpreter.sendOptions("Select one","Yes, please","No, thanks"); + stage++; + break; + case 1: + switch(buttonId){ + case 1: + end(); + NPC seddu = new NPC(3038); + seddu.openShop(player); + break; + case 2: + player("No, thanks."); + stage++; + break; + case 3: + end(); + break; + } + break; + } + return true; + } + public int[] getIds(){return new int[] {3038};} +} diff --git a/Server/src/main/content/region/desert/nardah/dialogue/ZahurDialoguePlugin.java b/Server/src/main/content/region/desert/nardah/dialogue/ZahurDialoguePlugin.java new file mode 100644 index 0000000..591e330 --- /dev/null +++ b/Server/src/main/content/region/desert/nardah/dialogue/ZahurDialoguePlugin.java @@ -0,0 +1,90 @@ +package content.region.desert.nardah.dialogue; + +import core.game.node.item.Item; +import core.cache.def.impl.NPCDefinition; +import core.plugin.Initializable; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.plugin.Plugin; +import core.plugin.ClassScanner; +import java.util.List; +import kotlin.Pair; + +import static core.api.ContentAPIKt.decantContainer; + +/** + * Handles the zahur dialogue. + * @author Empathy + */ +@Initializable +public class ZahurDialoguePlugin extends DialoguePlugin { + /** + * Constructs a new {@code ZahurDialoguePlugin} {@code Object}. + */ + public ZahurDialoguePlugin() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code ZahurDialoguePlugin} {@code Object}. + * @param player the player. + */ + public ZahurDialoguePlugin(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new ZahurDialoguePlugin(player); + } + + @Override + public boolean open(Object... args) { + npc("I can combine your potion vials to try and make", "the potions fit into fewer vials. This service is free.", "Would you like to do this?"); + stage = 1; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 1: + options("Yes", "No"); + stage = 2; + break; + case 2: + if (buttonId == 1) { + Pair,List> decantResult = decantContainer(player.getInventory()); + List toRemove = decantResult.getFirst(); + List toAdd = decantResult.getSecond(); + + for (Item item : toRemove) { + player.getInventory().remove(item); + } + + for (Item item : toAdd) { + player.getInventory().add(item); + } + + npc("There, all done."); + } + stage = 3; + break; + case 3: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 3037 }; + } + +} diff --git a/Server/src/main/content/region/desert/pollniv/dialogue/AliCamelMan.java b/Server/src/main/content/region/desert/pollniv/dialogue/AliCamelMan.java new file mode 100644 index 0000000..d7e1506 --- /dev/null +++ b/Server/src/main/content/region/desert/pollniv/dialogue/AliCamelMan.java @@ -0,0 +1,251 @@ +package content.region.desert.pollniv.dialogue; + +import core.plugin.Initializable; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.player.Player; + + +/** + * Dialogue for Ali the Camel Man + * @author ceik + */ +@Initializable +public class AliCamelMan extends DialoguePlugin { + public AliCamelMan(){ + /** + * Empty + */ + } + public AliCamelMan(Player player){ super(player);} + + @Override + public DialoguePlugin newInstance(Player player){ return new AliCamelMan(player);} + + public boolean open(Object... args){ + npc("Welcome to my discount camel store.","Can I help you with anything?"); + return true; + } + + public boolean handle(int interaceId, int buttonId){ + switch(stage){ + case 0: + interpreter.sendOptions("Select one.","A discount camel store?","Tell me about this town.","Lovely day isn't it?","Are those camels around the side for sale?","I'm looking for Ali from Pollnivneach."); + stage = 10; + break; + case 10: + switch(buttonId){ + case 1: + player(FacialExpression.ASKING,"A discount camel store?"); + stage = 20; + break; + case 2: + player(FacialExpression.THINKING,"Tell me about this town."); + stage = 30; + break; + case 3: + player(FacialExpression.ASKING,"Lovely day isn't it?"); + stage = 40; + break; + case 4: + player(FacialExpression.ASKING,"Are those camels around the side for sale?"); + stage = 50; + break; + case 5: + player(FacialExpression.ASKING,"I'm looking for Ali from Pollnivneach."); + stage = 60; + } + break; + case 20: + npc(FacialExpression.JOLLY,"Yes- a great idea - selling camels at discounted","prices so that the common man can experience","the joys of owning a camel too. They're not just","a source of kebab meat you know!"); + stage = 21; + break; + case 21: + interpreter.sendOptions("Select one.","So can I buy a camel then? I'm hungry!","Yes camels are beautiful creatures.","Filthy animals all they do is spit and...","Actually I think I was a camel in a previous existence.","So is business good then?"); + stage = 22; + break; + case 22: + switch(buttonId){ + case 1: + player(FacialExpression.ASKING,"So can I buy a camel then? I'm hungry!"); + stage = 230; + break; + case 2: + player(FacialExpression.HAPPY,"Yes camels are beautiful creatures."); + stage = 240; + break; + case 3: + player(FacialExpression.DISGUSTED,"Filthy animals all they do is spit and..."); + stage = 250; + break; + case 4: + player(FacialExpression.THINKING,"Actually I think I was a camel in a previous existence."); + stage = 260; + break; + case 5: + player(FacialExpression.ASKING,"So is business good then?"); + stage = 270; + } + break; + case 230: + npc(FacialExpression.DISGUSTED,"I would never sell to the likes of you,","they are beautiful majestic creatures not sandwich","fillers! Get ouf my shop."); + stage = 100; + break; + case 240: + npc(FacialExpression.LAUGH,"Ah, wondrous creatures, ships of the desert, far","more useful than any horse or donkey.","A man's best friend."); + stage = 25; + break; + case 25: + npc(FacialExpression.FRIENDLY,"Is there anything else I can help you with?"); + stage = 26; + break; + case 26: + interpreter.sendOptions("Select one.","Well yes actually I'd like to ask about something else.","No but thanks for your time."); + stage = 27; + break; + case 27: + switch(buttonId){ + case 1: + player("Well yes actually I'd like to ask about something else."); + stage = 0; + break; + case 2: + player("No but thanks for your time."); + stage = 100; + break; + } + break; + case 250: + npc(FacialExpression.ANGRY,"Pah! You just do not know how to treat them.","If you abuse them and treat them badly of","course they are going to spit and bite."); + stage = 25; + break; + case 260: + npc(FacialExpression.LAUGH,"You're teasing me now! You rogue! Everyone has","a laugh at my expense, I'm just more","enlightened than you!"); + stage = 25; + break; + case 270: + npc(FacialExpression.HAPPY,"Business is booming, Pollnivneach has never seen this","number of visitors."); + stage = 271; + break; + case 271: + npc(FacialExpression.THINKING,"In fact I'm thinking of expanding and trying to break","into the camel hire market."); + stage = 25; + break; + case 30: + npc(FacialExpression.THINKING,"Well Polvnivneach is a funny little place. It's a","small town and you'd think it would be a","quiet place."); + stage = 300; + break; + case 300: + npc(FacialExpression.ANGRY,"But those menaphites and bandits are making this place","quit unbearable."); + stage = 310; + break; + case 310: + interpreter.sendOptions("Select one.","In what way?","Well the weak will always be trodden on. Why not stand up to them?","Perhaps I can help."); + stage = 311; + break; + case 311: + switch(buttonId){ + case 1: + player(FacialExpression.ASKING,"In what way?"); + stage = 320; + break; + case 2: + player(FacialExpression.ASKING,"Well the weak will always be trodden on. Why not stand up to them?"); + stage = 330; + break; + case 3: + player(FacialExpression.FRIENDLY,"Perhaps I can help."); + stage = 340; + break; + } + break; + case 320: + npc(FacialExpression.ANGRY,"Well one group is just as bad as the other, stealing from each other","and the locals, fighting, and just the last dayone of the","bandits came looking for protection money."); + stage = 321; + break; + case 321: + player(FacialExpression.ANGRY,"Why don't the authorities stop this?"); + stage = 322; + break; + case 322: + npc(FacialExpression.SAD,"If you haven't noticed this is a remote town, half way between","Menaphos and Al Kharid, a place where neither","exert any power."); + stage = 323; + break; + case 323: + npc(FacialExpression.SAD,"To tell the truth we live in hope that an objective","outsider could broker a deal to halt the hostilities","between them."); + stage = 324; + break; + case 324: + player("Perhaps I will."); + stage = 25; + break; + case 330: + npc("That's a little unfair my friend. We can't all be brave","adventurers. If we were, where would you go to get camels","at discounted prices?"); + stage = 331; + break; + case 331: + npc(FacialExpression.ASKING,"You might think about that. Anyways isn't it the job of the brave","adventurer to deliver the weak and innocent from","evil and harm?"); + stage = 25; + break; + case 340: + //TODO: Add the quest and fix dialogue starting here. + npc(FacialExpression.SAD,"No, I don't think you can just yet. Perhaps in the future."); + stage = 100; + break; + case 40: + npc(FacialExpression.SUSPICIOUS,"It's a beautiful day today but word has it","that it will rain tomorrow."); + stage = 400; + break; + case 400: + player(FacialExpression.SUSPICIOUS,"Really?"); + stage = 410; + break; + case 410: + npc(FacialExpression.LAUGH,"No don't worry I'm only joking!"); + stage = 420; + break; + case 420: + player(FacialExpression.ANNOYED,"Ok so...."); + stage = 25; + break; + case 50: + npc(FacialExpression.HALF_GUILTY,"Those two camels around the side are already sold."); + stage = 500; + break; + case 500: + npc(FacialExpression.FRIENDLY,"I've got new stock coming very soon though.","Come back later if you're still interested."); + stage = 25; + break; + case 60: + npc(FacialExpression.HAPPY,"Well you've found your man."); + stage = 600; + break; + case 600: + player(FacialExpression.SUSPICIOUS,"Really do you have an uncle called Ali?"); + stage = 610; + break; + case 610: + npc(FacialExpression.NEUTRAL,"Why yes - All my uncles are called Ali!"); + stage = 620; + break; + case 620: + player(FacialExpression.THINKING,"Oh dear! Do any of them own a stall in the","Al Kharid Bazaar?"); + stage = 630; + break; + case 630: + npc(FacialExpression.THINKING,"Well no, but one of them owns a camel hire franchise."); + stage = 640; + break; + case 640: + player(FacialExpression.ANNOYED,"Never mind."); + stage = 100; + break; + case 100: + end(); + break; + } + return true; + } + @Override + public int[] getIds(){return new int[] {1867};} +} diff --git a/Server/src/main/content/region/desert/pollniv/dialogue/AliTheCamelHandler.java b/Server/src/main/content/region/desert/pollniv/dialogue/AliTheCamelHandler.java new file mode 100644 index 0000000..6537899 --- /dev/null +++ b/Server/src/main/content/region/desert/pollniv/dialogue/AliTheCamelHandler.java @@ -0,0 +1,93 @@ +package content.region.desert.pollniv.dialogue; + +import core.cache.def.impl.NPCDefinition; +import core.plugin.Initializable; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; +import core.tools.RandomFunction; + +/** + * Handles Ali the Camel interaction + * @author ceik + */ +@Initializable +public class AliTheCamelHandler extends OptionHandler { + public Plugin newInstance(Object arg) throws Throwable { + new AliTheCamelDialogue().init(); + NPCDefinition.forId(1873).getHandlers().put("option:pet",this); + return this; + } + + public boolean handle(Player player, Node node, String options){ + NPC npc = (NPC) node; + if(npc.getId() == 1873){ + if (options.equals("pet")){ + player.getDialogueInterpreter().open(1873); + } + } + return true; + } + + public class AliTheCamelDialogue extends DialoguePlugin { + public AliTheCamelDialogue(){ + /** + * Empty + */ + } + public AliTheCamelDialogue(Player player){super(player);} + + @Override + public DialoguePlugin newInstance(Player player){return new AliTheCamelDialogue(player);} + + @Override + public boolean open(Object... args){ + int phrase = RandomFunction.random(1,4); + switch(phrase){ + case 1: + player(FacialExpression.AFRAID,"That beast would probably bite my fingers off","if I tried to pet it"); + break; + case 2: + player(FacialExpression.DISGUSTED,"I'm not going to pet that! I might get fleas","or something else that nasty creature","might have."); + break; + case 3: + player(FacialExpression.THINKING,"Mmmm... Won't you make the nicest kebab?"); + break; + } + return true; + } + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + player.lock(); + player.animate(new Animation(7299)); + player.getImpactHandler().setDisabledTicks(3); + GameWorld.getPulser().submit(new Pulse(4, player) { + @Override + public boolean pulse() { + player.unlock(); + player.getAnimator().reset(); + return true; + } + }); + player.getDialogueInterpreter().sendDialogue("The camel tries to kick you for insulting it."); + stage = 1; + break; + case 1: + end(); + break; + } + return true; + } + @Override + public int[] getIds(){return new int[] {1873};} + } +} diff --git a/Server/src/main/content/region/desert/pollniv/dialogue/AliTheHagDialogue.kt b/Server/src/main/content/region/desert/pollniv/dialogue/AliTheHagDialogue.kt new file mode 100644 index 0000000..24bafe5 --- /dev/null +++ b/Server/src/main/content/region/desert/pollniv/dialogue/AliTheHagDialogue.kt @@ -0,0 +1,49 @@ +package content.region.desert.pollniv.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable + +/** + * @author qmqz + */ + +@Initializable +class AliTheHagDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + player(FacialExpression.FRIENDLY,"Good day, old hag.") + stage = 0 + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> npc(FacialExpression.LAUGH,"Old hag indeed! I have a name you know!").also { stage++ } + 1 -> player(FacialExpression.THINKING,"Let me guess it wouldn't be Ali would it?").also { stage++ } + 2 -> npc(FacialExpression.ANNOYED,"Well how else would you abbreviate Alice then?", "And no, you can't call me Al!").also { stage++ } + 3 -> npc( + FacialExpression.ASKING,"Now what do you want from the Old hag of Pollnivneach?", + "To hex someone? Power, beauty, eternal youth", "or something else drab like that?").also { stage++ } + 4 -> player(FacialExpression.HALF_GUILTY,"Actually none of those, I'm new in town and", "I just wanted to get to know the locals.").also { stage++ } + 5 -> npc( + FacialExpression.ANNOYED,"I'm busy brewing potions, so if you ", + "disturb me again without reason,","I will turn you into a frog!").also { stage++ } + 6 -> player(FacialExpression.SCARED,"Oh I'm sorry I won't let it happen again.").also { stage = 99 } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return AliTheHagDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(1871) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/pollniv/dialogue/AliTheKebabSeller.java b/Server/src/main/content/region/desert/pollniv/dialogue/AliTheKebabSeller.java new file mode 100644 index 0000000..5e1fe29 --- /dev/null +++ b/Server/src/main/content/region/desert/pollniv/dialogue/AliTheKebabSeller.java @@ -0,0 +1,227 @@ +package content.region.desert.pollniv.dialogue; + +import core.ServerConstants; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; + +@Initializable +public class AliTheKebabSeller extends DialoguePlugin { + public AliTheKebabSeller(){ + /** + * Empty + */ + } + public AliTheKebabSeller(Player player){ super(player);} + + @Override + public DialoguePlugin newInstance(Player player){return new AliTheKebabSeller(player);} + @Override + public boolean open(Object... args){ + npc = (NPC)args[0]; + player("Hello"); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId){ + boolean hasSauced = false; + switch(stage){ + case 0: + npc("Hello. What can I do for you?"); + stage = 1; + break; + case 1: + player("I don't know, what can you do for me?"); + stage = 2; + break; + case 2: + npc("Well, that depends."); + stage = 3; + break; + case 3: + player("Depends on what?"); + stage = 4; + break; + case 4: + npc("It depends on whether you like kebabs or not."); + stage = 5; + break; + case 5: + player("Why is that?"); + stage = 6; + break; + case 6: + npc("Seeing as I'm in the kebab construction industry.","I mainly help people who have want of a kebab."); + stage = 7; + break; + case 7: + player(FacialExpression.THINKING,"Well then, what kind of kebabs do you, erm, construct?"); + stage = 8; + break; + case 8: + npc("I offer two different types of kebabs: the standard","run-of-the-mill kebab seen throughout " + ServerConstants.SERVER_NAME + " and","enjoyed by many a intoxicated dwarf, and my specialty,","the extra-hot kebab. So which shall it be?"); + stage = 9; + break; + case 9: + npc("Or are my services even required?"); + stage = 10; + break; + case 10: + interpreter.sendOptions("Select one","Yes, thanks.","No thanks, I'm good"); + stage = 11; + break; + case 11: + switch(buttonId){ + case 1: + player("Yes, thanks."); + stage = 12; + break; + case 2: + player("No thanks, I'm good."); + stage = 100; + break; + } + break; + case 12: + interpreter.sendOptions("Select one.","I want a kebab, please.", "Could I have one of those crazy hot kebabs of yours?","Would you sell me that bottle of special kebab sauce?", "What is the difference between the standard and extra hot?","I need some information."); + stage = 13; + break; + case 13: + switch(buttonId){ + case 1: + player("I want a kebab, please."); + stage = 20; + break; + case 2: + player("Could I have one of those crazy hot kebabs of yours?"); + stage = 30; + break; + case 3: + player("Would you sell me that bottle of special kebab sauce?"); + stage = 40; + break; + case 4: + player("What is the difference between the standard and extra hot?"); + stage = 50; + break; + case 5: + player("I need some information."); + stage = 60; + break; + } + break; + case 20: + npc("That will be 3 coins please."); + if(player.getInventory().contains(995,3)) { + stage = 21; + } else { + stage = 25; + } + break; + case 21: + npc("Here you go."); + player.getInventory().remove(new Item(995,3)); + player.getInventory().add(new Item(1971)); + stage = 22; + break; + case 22: + npc("Is there anything else I can do for you?"); + stage = 10; + break; + case 25: + player("I seem to have not brought enough money with me. Sorry."); + stage = 22; + break; + case 30: + npc("A super kebab it is so. Be careful, they really are as hot as","they are made out to be."); + stage = 31; + break; + case 31: + player("Sure, sure."); + stage = 32; + break; + case 32: + npc("Here you go."); + player.getInventory().add(new Item(4608)); + stage = 33; + break; + case 33: + player("Thanks."); + stage = 22; + break; + case 40: + if(!player.getInventory().containsItem(new Item(4610))) { + npc("Well, that depends on what you have in mind."); + stage = 41; + break; + } else { + npc("I already gave it to you!"); + stage = 22; + break; + } + case 41: + player("Set yourself at east, I have no intention of setting up a","rival kebab shop."); + stage = 42; + break; + case 42: + npc("Well, then, what do you want it for?"); + stage = 43; + break; + case 43: + player("I don't know, but I think I could have a little fun with it."); + stage = 44; + break; + case 44: + npc("You're not going to put it in drunken Ali's drink"," now, are you? That's what happened last time","I gave someone the sauce."); + stage = 45; + break; + case 45: + player("No, that would be a bit cliche, I think I'll come up with","something more original."); + stage = 46; + break; + case 46: + npc("Just be careful with it, it's potent enough to give a camel","the runs."); + player.getInventory().add(new Item(4610)); + stage = 47; + break; + case 47: + player("Thank you very much."); + stage = 22; + break; + case 50: + npc("If I told you that I would have to kill you. Kebab sales is","a cut-throat industry. The extra-hot kebab gives","me the competitive edge on the rest and if I were to","divulge my secrets to every passing adventurer, well it"); + stage = 51; + break; + case 51: + npc("would soon disappear."); + stage = 52; + break; + case 52: + player("So there's no difference except the sauce you use then!"); + stage = 53; + break; + case 53: + npc("Shh! Keep your voice down. You should have told me you","were from the union."); + stage = 22; + break; + case 60: + npc("If information is what you need, there are many better"," people to ask than myself who could help you. One of the","town's street urchins or perhaps the local drunk.","I may be many things to many people, but a"); + stage = 61; + break; + case 61: + npc("gossip I am not."); + stage = 22; + break; + case 100: + end(); + break; + } + return true; + } + @Override + public int[] getIds() {return new int[] {1865};} +} diff --git a/Server/src/main/content/region/desert/pollniv/dialogue/AliTheMayorDialogue.kt b/Server/src/main/content/region/desert/pollniv/dialogue/AliTheMayorDialogue.kt new file mode 100644 index 0000000..b1108b7 --- /dev/null +++ b/Server/src/main/content/region/desert/pollniv/dialogue/AliTheMayorDialogue.kt @@ -0,0 +1,59 @@ +package content.region.desert.pollniv.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable + +/** + * @author qmqz + */ + +@Initializable +class AliTheMayorDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npc( + FacialExpression.FRIENDLY,"Welcome adventurer to the town of Pollnivneach,", + "the gateway to Menaphos and Al-Kharid. My name is Ali", + "and I'm the mayor of this town.", + "I hope you enjoy your stay here.") + stage = 0 + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> player( + FacialExpression.FRIENDLY, "Thank you.", + "That is the warmest welcome I've had anywhere", + "for a while at least. People generally treat", + "travelling adventurers with suspicion.").also { stage++ } + 1 -> npc( + FacialExpression.FRIENDLY,"All are welcome here, such is the way", + "of things in border regions.", + "Now more than ever I suppose.").also { stage++ } + 2 -> player(FacialExpression.FRIENDLY,"What do you mean by that?").also { stage++ } + 3 -> npc(FacialExpression.FRIENDLY,"There's trouble in town, and a lot of ", "villagers have left as a result.").also { stage++ } + 4 -> player(FacialExpression.FRIENDLY,"I'm looking for someone called Ali.").also { stage++ } + 5 -> npc(FacialExpression.FRIENDLY,"I doubt that's easy in Pollnivneach.").also { stage++ } + 6 -> player(FacialExpression.FRIENDLY,"Well can you help me?").also { stage++ } + 7 -> npc( + FacialExpression.FRIENDLY,"I'm more than a little busy at the moment, ", + "I'm sure there are plenty of people ", "in town who could help you.").also { stage = 99 } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return AliTheMayorDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(1870) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/pollniv/dialogue/AliTheOperator.kt b/Server/src/main/content/region/desert/pollniv/dialogue/AliTheOperator.kt new file mode 100644 index 0000000..d2c6ff0 --- /dev/null +++ b/Server/src/main/content/region/desert/pollniv/dialogue/AliTheOperator.kt @@ -0,0 +1,69 @@ +package content.region.desert.pollniv.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable + +/** + * @author qmqz + */ + +@Initializable +class AliTheOperator(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + player(FacialExpression.FRIENDLY,"Hello, good sir.") + stage = 0 + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> npc(FacialExpression.ANNOYED,"What do you want?").also { stage++ } + 1 -> player(FacialExpression.HALF_ASKING,"I'm just new in town and have a few questions.").also { stage++ } + 2 -> npc(FacialExpression.ASKING,"What do you want to know?").also { stage++ } + + 3 -> options ("Tell me about yourself.", "Tell me about the other people in the town.", "I'm looking for Ali.").also { stage++ } + 4 -> when(buttonId){ + 1 -> npc( + FacialExpression.ANNOYED, "That information is available on a need to know basis", + "and right now, you don't need to know.").also { stage = 10 } + 2 -> npc( + FacialExpression.SUSPICIOUS,"Sheep, ready for the slau... ", + "hang on I shouldn't be saying..., ", "listen I don't want to talk about them.").also { stage = 10 } + 3 -> npc( + FacialExpression.ANNOYED,"You will have to be a lot more specific if ", + "you want help finding him. ", "Everyone here is called Ali.").also { stage = 30 } + } + + 10 -> npc(FacialExpression.HALF_ASKING,"Can I help you with anything else?").also { stage++ } + + 11 -> options ("Yes I'd like to ask you about something else.", "No thanks.").also { stage++ } + 12 -> when(buttonId) { + 1 -> npc(FacialExpression.ASKING,"What do you want to know?").also { stage = 3 } + 2 -> end() + } + + 30 -> player( + FacialExpression.HALF_ASKING,"I've discovered that. Well he has an uncle called", + "Ali Morrisane, a market vendor in Al Kharid and","that's all I really know about him.").also { stage++ } + 31 -> npc( + FacialExpression.ANNOYED,"Say no more. I too am looking for him. ", + "The little tyke robbed me too. If we work together,", "perhaps we can catch him and teach him ","a lesson.").also { stage = 10 } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return AliTheOperator(player) + } + + override fun getIds(): IntArray { + return intArrayOf(1902) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/pollniv/dialogue/BlackJackSeller.java b/Server/src/main/content/region/desert/pollniv/dialogue/BlackJackSeller.java new file mode 100644 index 0000000..bab4965 --- /dev/null +++ b/Server/src/main/content/region/desert/pollniv/dialogue/BlackJackSeller.java @@ -0,0 +1,42 @@ +package content.region.desert.pollniv.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; + +/** + * Stand-in dialogue for Black Jack Seller til blackjacking/the quest is implemented + * @author ceik + */ +@Initializable +public class BlackJackSeller extends DialoguePlugin { + public BlackJackSeller(){ + /** + * empty. + */ + } + public BlackJackSeller(Player player){super(player);} + + @Override + public DialoguePlugin newInstance(Player player){return new BlackJackSeller(player);} + + @Override + public boolean open(Object... args){ + npc("I'm not interested in selling to you. Not yet..."); + stage = 0; + return true; + } + + @Override + public boolean handle(int intefaceId, int objectId){ + switch(stage){ + case 0: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() {return new int[] {2548};} +} diff --git a/Server/src/main/content/region/desert/pollniv/dialogue/DesertBandit.java b/Server/src/main/content/region/desert/pollniv/dialogue/DesertBandit.java new file mode 100644 index 0000000..6eaaa9f --- /dev/null +++ b/Server/src/main/content/region/desert/pollniv/dialogue/DesertBandit.java @@ -0,0 +1,59 @@ +package content.region.desert.pollniv.dialogue; + +import core.cache.def.impl.NPCDefinition; +import core.plugin.Initializable; +import core.game.dialogue.DialoguePlugin; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Plugin; + +/** + * Stand-in for bandit dialogue until blackjacking is implemented + * @author ceik + */ + +@Initializable +public class DesertBandit extends OptionHandler { + public Plugin newInstance(Object arg) throws Throwable { + new BanditDialogue().init(); + NPCDefinition.forId(6388).getHandlers().put("option:talk-to",this); + return this; + } + public boolean handle(Player player, Node node, String options){ + NPC npc = (NPC) node; + if(npc.getId() == 6388){ + if (options.equals("talk-to")){ + player.getDialogueInterpreter().open(6388); + } + } + return true; + } + + public class BanditDialogue extends DialoguePlugin { + public BanditDialogue() { + /** + * Empty. + */ + } + public BanditDialogue(Player player){super(player);} + + @Override + public DialoguePlugin newInstance(Player player){return new BanditDialogue(player);} + + @Override + public boolean open(Object... args){ + npc("Go away."); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId){ + end(); + return true; + } + @Override + public int[] getIds() {return new int[] {6388};} + } +} diff --git a/Server/src/main/content/region/desert/pollniv/dialogue/StreetUrchinDialogue.java b/Server/src/main/content/region/desert/pollniv/dialogue/StreetUrchinDialogue.java new file mode 100644 index 0000000..ff307b6 --- /dev/null +++ b/Server/src/main/content/region/desert/pollniv/dialogue/StreetUrchinDialogue.java @@ -0,0 +1,39 @@ +package content.region.desert.pollniv.dialogue; + +import core.plugin.Initializable; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; + +/** + * Handles the street urchin npc TODO: Add more dialogue after/during the quest when it is implemented. + * @author ceik + */ +@Initializable +public class StreetUrchinDialogue extends DialoguePlugin { + public StreetUrchinDialogue(){ + /** + * Empty + */ + } + + public StreetUrchinDialogue(Player player){super(player);} + + @Override + public DialoguePlugin newInstance(Player player){return new StreetUrchinDialogue(player);} + + public boolean open(Object... args){ + player.getDialogueInterpreter().sendDialogue("This child doesn't seem interested in you."); + return true; + } + + public boolean handle(int interfaceId, int buttonId){ + switch(stage){ + case 0: + end(); + break; + } + return true; + } + @Override + public int[] getIds(){return new int[] {6357};} +} diff --git a/Server/src/main/content/region/desert/pollniv/handlers/SnakeCharmerBasket.java b/Server/src/main/content/region/desert/pollniv/handlers/SnakeCharmerBasket.java new file mode 100644 index 0000000..49b940a --- /dev/null +++ b/Server/src/main/content/region/desert/pollniv/handlers/SnakeCharmerBasket.java @@ -0,0 +1,110 @@ +package content.region.desert.pollniv.handlers; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Handles Ali the Snake Charmer + * @author ceik + */ +@Initializable +public class SnakeCharmerBasket extends UseWithHandler { + public SnakeCharmerBasket() { + super(995); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + new AliTheSnakeCharmer().init(); + addHandler(6230, OBJECT_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + if (player.getInventory().containsItem(new Item(995, 3))) { + player.getInventory().remove(new Item(995, 3)); + player.getDialogueInterpreter().open(1872, true); + } + return true; + } + + public class AliTheSnakeCharmer extends DialoguePlugin { + public AliTheSnakeCharmer() { + /** + * empty. + */ + } + + public AliTheSnakeCharmer(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new AliTheSnakeCharmer(player); + } + + @Override + public boolean open(Object... args) { + if (args.length > 0) { + player("Wow a snake charmer. Can I have a go? Please?"); + stage = 5; + return true; + } + player("Wow a snake charmer. Can I have a go? Please?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + player.getDialogueInterpreter().sendDialogue("The snake charmer fails to acknowledge you,","he seems too deep into the music to notice you."); + stage = 4; + break; + case 4: + end(); + break; + case 5: + player.getDialogueInterpreter().sendDialogue("The snake charmer snaps out of his trance","and directs his full attention to you."); + stage = 6; + break; + case 6: + player(FacialExpression.JOLLY, "Wow a snake charmer. Can I have a go? Please?"); + stage = 7; + break; + case 7: + if(!player.getInventory().containsItems(new Item(4605),new Item(4606)) && !player.getBank().containItems(4605,4606)) { + if (player.getInventory().freeSlots() >= 2) { + player.getInventory().add(new Item(4605)); + player.getInventory().add(new Item(4606)); + } else { + GroundItemManager.create(new Item(4605), player.getLocation()); + GroundItemManager.create(new Item(4606), player.getLocation()); + } + npc(FacialExpression.ANNOYED, "If it means that you'll leave me alone, I would give you"," my snake charming super starter kit complete","with flute and basket."); + } else { + npc(FacialExpression.ANGRY,"I already gave you one!"); + } + stage = 4; + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[]{1872}; + } + } +} diff --git a/Server/src/main/content/region/desert/quest/curseofzaros/CurseOfZaros.kt b/Server/src/main/content/region/desert/quest/curseofzaros/CurseOfZaros.kt new file mode 100644 index 0000000..a57abef --- /dev/null +++ b/Server/src/main/content/region/desert/quest/curseofzaros/CurseOfZaros.kt @@ -0,0 +1,189 @@ +package content.region.desert.quest.curseofzaros + +import core.game.dialogue.* +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player + +/** + * Curse of Zaros is a miniquest with no quest points or final dialogue + * + * Players get the ghostly set for fashionscape. + */ +class CurseOfZaros { + companion object { + const val attributePathNumber = "/save:miniquest:curseofzaros-pathnumber" // 1 of 3. + const val attributeValdezSpoke = "/save:miniquest:curseofzaros-valdezspoke" + const val attributeRennardSpoke = "/save:miniquest:curseofzaros-rennardspoke" + const val attributeKharrimSpoke = "/save:miniquest:curseofzaros-kharrimspoke" + const val attributeLennissaSpoke = "/save:miniquest:curseofzaros-lennissaspoke" + const val attributeDhalakSpoke = "/save:miniquest:curseofzaros-dhalakspoke" + const val attributeViggoraSpoke = "/save:miniquest:curseofzaros-viggoraspoke" + + // Ghostly Robes lost: http://youtu.be/YcwYOqfG1Ys + + fun withoutGhostspeak(d: DialogueLabeller) { + fun label(label: String) { d.label(label) } + fun loadLabel(player: Player, label: String) { d.loadLabel(player, label) } + fun player(vararg messages: String) { d.player(ChatAnim.NEUTRAL, *messages) } + fun npc(vararg messages: String) { d.npc(ChatAnim.NEUTRAL, *messages) } + fun exec(callback: (player: Player, npc: NPC) -> Unit) { d.exec(callback) } + + label("noghostspeak") + exec { player, npc -> + loadLabel(player, "noghostspeak" + (1..8).random()) + } + + label("noghostspeak1") + player("Hello there.") + npc("Wooo? Woooo woo woooooo wooooo woooowooo wooo woooooo woo!") + player("You don't say?") + npc("Woo! WOO WOOOOO WOOWOOWOO WOO WOOOOO!") + player("You don't say!") + npc("Wooowoowoooooo.... Woowoowoo? Woooo, wooowoo wooowooowooo!") + player("Well, I guess you didn't say.") + + label("noghostspeak2") + player("Hello there.") + npc("Wooo? Woooo woo woooooo wooooo woooowooo wooo woooooo woo!") + player("Yeah, I don't want to brag, but seriously: I am SOOOO rich....") + npc("Woo! WOO WOOOOO WOOWOOWOO WOO WOOOOO!") + player("Yeah, I know they say money doesn't bring you happiness, but sometimes I just like to open my bank account and look at all of the stuff I own and just think to myself:") + player("Wow. I am soooooo rich.") + npc("Wooowoowoooooo.... Woowoowoo? Woooo, wooowoo wooowooowooo!") + player("Well, us rich alive people don't want to waste all day spending time with you poor dead people, because I'm just sooooo rich I have to go now, and very possibly make myself even richer.") + player("See ya around ghosty!") + + label("noghostspeak3") + player("Hello there.") + npc("Wooo? Woooo woo woooooo wooooo woooowooo wooo woooooo woo!") + player("Yeah, I heard about that, ha-ha-ha!") + npc("Woo! WOO WOOOOO WOOWOOWOO WOO WOOOOO!") + player("With a MACKEREL? Ouch!") + npc("Wooowoowoooooo.... Woowoowoo? Woooo, wooowoo wooowooowooo!") + player("Well, it was fun. Let's do it again sometime.") + + label("noghostspeak4") + player("Hello there.") + npc("Wooo? Woooo woo woooooo wooooo woooowooo wooo woooooo woo!") + player("Why, thank you very much!") + npc("Woo! WOO WOOOOO WOOWOOWOO WOO WOOOOO!") + player("I know, but what are you going to do?") + npc("Wooowoowoooooo.... Woowoowoo? Woooo, wooowoo wooowooowooo!") + player("Well, I guess that's always true in the long run. See you around, weird invisible dead person!") + + label("noghostspeak5") + player("Hello there.") + npc("Wooo? Woooo woo woooooo wooooo woooowooo wooo woooooo woo!") + player("Yeah it's not bad, but I prefer cooked chicken.") + npc("Woo! WOO WOOOOO WOOWOOWOO WOO WOOOOO!") + player("Maybe, but nothing beats a home cooked pie!") + player("Man, I love pie!") + npc("Wooowoowoooooo.... Woowoowoo? Woooo, wooowoo wooowooowooo!") + player("You don't say? I never knew that. Well, I must be going, see you around.") + + // This is peak 2009 memez + label("noghostspeak6") + player("Hello there.") + npc("Wooo? Woooo woo woooooo wooooo woooowooo wooo woooooo woo!") + player("We get signal!") + npc("Woo! WOO WOOOOO WOOWOOWOO WOO WOOOOO!") + player("Somebody set up us the bomb!") + npc("Wooowoowoooooo.... Woowoowoo? Woooo, wooowoo wooowooowooo!") + player("You have no chance to survive make your time.") + npc("Woo?") + player("All your base are belong to us.") + + label("noghostspeak7") + player("Hey, don't think you can talk to me like that!") + npc("Woo! WOO WOOOOO WOOWOOWOO WOO WOOOOO!") + player("Are you threatening me?") + npc("Wooowoowoooooo.... Woowoowoo? Woooo, wooowoo wooowooowooo!") + player("Just because you're already dead, doesn't mean I can't find a way to hurt you ghosty!") + + label("noghostspeak8") + player("No, I've never been there in my life and CERTAINLY didn't steal anything when I was!") + npc("Woo! WOO WOOOOO WOOWOOWOO WOO WOOOOO!") + player("Are you calling me a liar?!?! I have never stolen a thing in my life, and I resent the implication that I am the kind of morally depraved individual that would steal someone else's hard earned") + player("money from their very pockets!") + player("Or cakes. Or fur. Repeatedly. For long periods at a time.") + npc("Wooowoowoooooo.... Woowoowoo? Woooo, wooowoo wooowooowooo!") + player("Well if you are going to take that attitude, then I have nothing further to say on the matter, and bid you good day!") + } + + + fun wrongPath(d: DialogueLabeller) { + fun label(label: String) { d.label(label) } + fun loadLabel(player: Player, label: String) { d.loadLabel(player, label) } + fun player(vararg messages: String) { d.player(ChatAnim.NEUTRAL, *messages) } + fun npc(vararg messages: String) { d.npc(ChatAnim.NEUTRAL, *messages) } + fun exec(callback: (player: Player, npc: NPC) -> Unit) { d.exec(callback) } + + label("wrongpath") + exec { player, npc -> + loadLabel(player, "wrongpath" + (1..7).random()) + } + + label("wrongpath1") + player("Hello there.") + npc("The endless tragedy of fate...", "Why must you torment me so?") + player("Alright, alright, calm down, calm down. All I said was 'hello'!") + + label("wrongpath2") + player("Hello there.") + npc("You can see me?") + player("Uh... yes?") + npc("And you understand my words?") + player("Well, most of them...") + npc("This is incredible! How can such a thing have come to pass?") + player("What can I say? I'm a professional.") + + label("wrongpath3") + player("Hello there.") + npc("Hello back at you.") + player("So what's a nice ghost like you doing in a place like this?") + npc("I suppose you think that's funny?") + player("Well... Mildly amusing I guess.") + npc("I don't think I want to talk to you anymore.") + + label("wrongpath4") + player("Hello there.") + npc("Hello stranger. It is rare indeed that I meet one who can see my presence, let alone one who can understand my words.") + player("Soooo.... Is it fun being a ghost?") + npc("Does it look like fun to you?") + player("Erm... Well, yes actually.") + npc("Then you are a fool, and I will waste no more words upon you.") + player("What, not even 'goodbye'?") + npc(" ") + player("Sheesh, what a grouch. You'd think you'd have more of a sense of humour being dead and all.") + + label("wrongpath5") + player("Hello there.") + npc("Mortal... Take heed of my example, and waste not your life, lest you may suffer the same fate as myself...") + player("Huh? You mean someone did this to you?") + npc("You have ascertained the truth in my words...") + player("So who did it to you? And why?") + npc("Events of moons past, I remember not clearly...") + player("Fine help you are then.") + + label("wrongpath6") + player("Hello there.") + npc("Hello stranger.") + player("So.... Invisible ghost haunting the same place for thousands of years, huh?") + npc("You have no idea...") + player("Well, bad luck and all that. See ya around!") + + label("wrongpath7") + player("Hello there.") + npc("Hello.") + player("So you're a ghost, huh?") + npc("Apparently.") + player("In which case I only have one thing to say to you:") + npc("...what?") + player("Guess you don't have the amulet of humanspeak, huh?") + npc("...huh?") + player("Yeah, that's right. WOO! WOOOWOOO WOO WOOOOWOO! Got no comeback for that, have you?") + npc("You are very strange...") + + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/curseofzaros/MysteriousGhostDhalakDialogue.kt b/Server/src/main/content/region/desert/quest/curseofzaros/MysteriousGhostDhalakDialogue.kt new file mode 100644 index 0000000..d8c89c1 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/curseofzaros/MysteriousGhostDhalakDialogue.kt @@ -0,0 +1,149 @@ +package content.region.desert.quest.curseofzaros + +import core.api.* +import core.game.dialogue.ChatAnim +import core.game.dialogue.DialogueLabeller +import core.game.dialogue.DialogueOption +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class MysteriousGhostDhalakDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return MysteriousGhostDhalakDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, MysteriousGhostDhalakDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(2385, 2386, 2387) + } +} + +class MysteriousGhostDhalakDialogueFile : DialogueLabeller() { + override fun addConversation() { + exec { player, npc -> + if (inEquipment(player, Items.GHOSTSPEAK_AMULET_552) || inEquipment(player, Items.GHOSTSPEAK_AMULET_4250)){ + if (2384 + getAttribute(player, CurseOfZaros.attributePathNumber, 0) == npc.id) { + if (getAttribute(player, CurseOfZaros.attributeDhalakSpoke, false)) { + if (inInventory(player, Items.GHOSTLY_HOOD_6109) || inEquipment(player, Items.GHOSTLY_HOOD_6109)) { + loadLabel(player, "subsequenttime") + } else { + loadLabel(player, "lostghostlything") + } + } else { + loadLabel(player, "firsttime") + } + } else { + loadLabel(player, "wrongpath") + } + } else { + loadLabel(player, "noghostspeak") + } + } + + CurseOfZaros.withoutGhostspeak(this) + + CurseOfZaros.wrongPath(this) + + label("firsttime") + player("Hello Dhalak.") + npc("You see my form, hear my words, and know my name, yet your face I recognise not...") + npc("Be you some mighty sorcerer to bind me so?") + player("Um... Well, not really...") // player("Well, I don't mean to brag, but I guess I am with my level 99 magic...") if you are 99 lvl magic but calm the fuck down showoff + player("But that is besides the point. It is not I who has trapped you here as a ghost.") + npc("Then how comes it to be that you know my name stranger?") + player("Lennissa told me about you, and where to find you?") + npc("Lennissa? Oh that poor sweet girl... Has my foolishness cursed her as well as myself???") + player("Your foolishness?") + npc("The story shames me stranger, I wouldst rather keep it unto myself.") + options( + DialogueOption("tellmeyourstory", "Tell me your story", skipPlayer = true), + DialogueOption("goodbye", "Goodbye then", skipPlayer = true), + ) + + label("goodbye") + player("Well, that's all fascinating, but I just don't particularly care. Bye-bye.") + + label("tellmeyourstory") + player("Look, I don't want to force you into telling me, but perhaps sharing it with someone might relieve your guilt?") + npc("Aye... Perhaps it might at that.") + npc("So what has Lennissa told you of the events of the day this curse befell me?") + player("Well, she told me that she was working as an undercover agent of Saradomin amongst the followers of some 'Empty Lord', and when news of the theft of a god-weapon reached her, she passed the message on to") + player("you instead of taking it to Saradomin because she was scared her cover might be blown.") + npc("Aye, that is a fair account of events...") + player("But I don't understand why you didn't take her message to Saradomin?") + npc("Stranger, my foolishness was a result of my respect for Saradomin, not as a result of any attempted treachery!") + player("So why didn't you pass on Lennissa's message? As I understand it something happened with that staff that could have been avoided if you had passed her message on!") + npc("(sigh) I know not what occurred with that god-weapon, but I have my suspicions...") + npc("Let me explain myself. I was Lennissa's immediate superior, and I was often her contact for missions.") + npc("Because of this role, I had access to a larger picture of what was happening than she herself did, and I was not only well aware that her presence amongst the enemy camp had been detected, but I was also well aware that") + npc("there was a growing faction amongst them who were plotting to overthrow their master.") + player("Their master being...?") + npc("That I will not tell you. I will tempt the fates no more than I already have done.") + npc("But anyway, it had come to my attention that the Mahjarrat who had been liberated from the control of Icthlarin did not much appreciate one form of slavery to another, and under the leadership of the mighty") + npc("Zamorak were making plans to overthrow their master and take his power for themselves.") + npc("Now, as powerful, long-lived and evil as they were, they were still just mortal, and I made the decision that it would be of benefit to my Lord Saradomin for his mightiest rival to be distracted by such internal conflicts.") + player("So that is why you decided not to pass the report from Lennissa on?") + npc("Yes, but my guilt is more than simply inaction...") + npc("I knew that with such a weapon, Zamorak would be capable of launching an attack that could actually stand a chance of success, but I also knew that he would never be able to get a chance to use it in a battle for") + npc("being a god-weapon its very presence would have sung out to their leader.") + player("I'm guessing you did something about that, then?") + npc("Indeed I did. To my eternal shame, I decided that I would assist Zamorak and his henchmen in their battle, by secretly casting a spell of concealment upon the staff so that") + npc("they might use it secretly against their master.") + player("So Zamorak knew about this?") + npc("No, nobody except myself, and now you, knew that I cast such a spell....") + npc("Had I known what a threat to my Lord Saradomin Zamorak would later become, I wouldst have taken the message to Saradomin immediately! Alas, it is all too easy to see your mistakes after you") + npc("have made them...") + player("I'm confused. What exactly happened with this staff anyway? And why have all these various random people been cursed because of it?") + npc("I cannot answer your question with anything other than my own suppositions, but I do know of one who might be able to, and if any man deserved to be cursed for their actions that day, it was he!") + player("Who are you speaking of?") + npc("His name was Viggora. He was an evil man, brutal and vicious, and deadly with a blade.") + npc("He was one of the few humans Zamorak allowed to rise to a position of power amongst his rebels, possibly because he imitated those same qualities of Zamorak.") + npc("If anyone knows what Zamorak did with that god- weapon to have caused this curse to have befallen us, it would have been he, for he would have been fighting on Zamorak's very right hand side in their rebellion.") + npc("Please, if this curse can be lifted, find Viggora and find out what he has wrought upon us! I have no wealth nor magic to aid you, but take my hood as reward;") + exec { player, npc -> + setAttribute(player, CurseOfZaros.attributeDhalakSpoke, true) + addItemOrDrop(player, Items.GHOSTLY_HOOD_6109) + } + npc("it has served me well these centuries past, and may bring you luck.") + player("Where would you suggest I look for Viggora?") + exec { player, npc -> + // 1 of 3 paths. + loadLabel(player, "curseofzaros" + getAttribute(player, CurseOfZaros.attributePathNumber, 0)) + } + + label("subsequenttime") + player("Dhalak, where can I find the swordsman Viggora?") + exec { player, npc -> + // 1 of 3 paths. + loadLabel(player, "curseofzaros" + getAttribute(player, CurseOfZaros.attributePathNumber, 0)) + } + + label("curseofzaros1") + npc("Ah, the evil swordsman Viggora... A rogue like him would probably flock to his own kind.") + player("Okay, well I'll try and find him for you then.") + + label("curseofzaros2") + npc("Ah, the evil swordsman Viggora... Perhaps he has returned to his castle in the dark lands?") + player("Okay, well I'll try and find him for you then.") + + label("curseofzaros3") + npc("Ah, the evil swordsman Viggora... Paddewwa was where he fought many battles, perhaps he has returned to one of his old haunts?") + player("Okay, well I'll try and find him for you then.") + + + label("lostghostlything") + + player(ChatAnim.SAD, "Could I have that hat again? I seem to have misplaced it", "somewhere...") + exec { player, npc -> + addItemOrDrop(player, Items.GHOSTLY_HOOD_6109) + } + npc("Certainly, I am not sure how, but it returned to me by", "some magic or other.") + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/curseofzaros/MysteriousGhostKharrimDialogue.kt b/Server/src/main/content/region/desert/quest/curseofzaros/MysteriousGhostKharrimDialogue.kt new file mode 100644 index 0000000..4d825f1 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/curseofzaros/MysteriousGhostKharrimDialogue.kt @@ -0,0 +1,143 @@ +package content.region.desert.quest.curseofzaros + +import core.api.* +import core.game.dialogue.ChatAnim +import core.game.dialogue.DialogueLabeller +import core.game.dialogue.DialogueOption +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class MysteriousGhostKharrimDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return MysteriousGhostKharrimDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, MysteriousGhostKharrimDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(2388, 2389, 2390) + } +} + +class MysteriousGhostKharrimDialogueFile : DialogueLabeller() { + override fun addConversation() { + exec { player, npc -> + if (inEquipment(player, Items.GHOSTSPEAK_AMULET_552) || inEquipment(player, Items.GHOSTSPEAK_AMULET_4250)){ + if (2387 + getAttribute(player, CurseOfZaros.attributePathNumber, 0) == npc.id) { + if (getAttribute(player, CurseOfZaros.attributeKharrimSpoke, false)) { + if (inInventory(player, Items.GHOSTLY_BOOTS_6106) || inEquipment(player, Items.GHOSTLY_BOOTS_6106)) { + loadLabel(player, "subsequenttime") + } else { + loadLabel(player, "lostghostlything") + } + } else { + loadLabel(player, "firsttime") + } + } else { + loadLabel(player, "wrongpath") + } + } else { + loadLabel(player, "noghostspeak") + } + } + + CurseOfZaros.withoutGhostspeak(this) + + CurseOfZaros.wrongPath(this) + + label("firsttime") + player("Hello. So you must be Kharrim the messenger.") + npc("How do you know my name, stranger?") + player("Well now... I had a very interesting chat with Rennard the thief.") + player("It seems you redirected his message regarding a certain god-weapon for your own ends.") + npc("So THAT is what this is about... I should have known the deal was too good to have no repercussions...") + player("It seems as though you might be responsible for this curse that has befallen you by not delivering Rennard's message to the correct person.") + npc("Ha! That is not a truthful assessment of the story... You might think differently if you had heard my side of events.") + options( + DialogueOption("tellmeyourstory", "Tell me your story", skipPlayer = true), + DialogueOption("goodbye", "Goodbye then", skipPlayer = true), + ) + + label("goodbye") + player("Well, that's all fascinating, but I just don't particularly care. Bye-bye.") + + label("tellmeyourstory") + player("Please let me hear your side of the story then...") + npc("Well, if you have spoken to Rennard, then you will know that he had somehow managed to obtain a very valuable weapon, and was looking for buyers.") + npc("What he probably didn't tell you, was that he met me in a drunken stupor in some smoke filled tavern, and I offered to arrange a purchaser for his item, in exchange for a small finders fee.") + player("So you knew what the staff was?") + npc("The god-staff of Armadyl? Well, of course I did.") + npc("Honestly, you would have to be pretty slow-witted to not recognise a legendary artefact such as that.") + player("Wait, I don't understand, Rennard said that he had a buyer already in mind, and that you diverted his message to a General Zamorak instead?") + npc("Ha! Here is a word of advice for you adventurer; Never trust the words of a drunk.") + npc("Whatever he might have thought he was doing with it, in the end all that happened was he left me to arrange a purchaser for the item.") + player("So you thought you would offer it to General Zamorak?") + npc("Ah yes, Lord Zamorak. He was merely a mortal back then, you know?") + npc("Yet I could see great things in store for him even then. He had a kind of brilliant ruthlessness... And that special kind of vicious streak you see so rarely...") + npc("Well anyway, when given the task of selling a weapon forged by the very gods themselves, I naturally thought of Zamorak as a potential buyer.") + npc("I was a messenger in his employ anyway, so it was a mere trifle to find him and deliver the news, and I knew of his particular interest in armour and weaponry of all kinds.") + npc("Yes, he was always quite the connoisseur when it came to weaponry...") + npc("But I digress. I let Lord Zamorak know that there was some drunken fool with an artefact of incredible power that could probably be bought off with a few jewels and trinkets,") + npc("and he escorted me to the tavern and made the purchase there and then.") + npc("It was a satisfactory deal all around, I got a share of the sale price from Rennard, and I greatly increased my prestige amongst Zamorak and his followers.") + npc("But maybe... Perhaps the events that followed were responsible for my cursed state...") + player("Events that followed?") + npc("I can not tell you of them precisely, for I myself was not there to witness them.") + npc("I am after all, simply a messenger. When... 'it' happened, I was busy elsewhere delivering a message from Zamorak to the rest of his Mahjarrat ilk.") + player("When 'it' happened? What was 'it'?") + npc("As I have explained, I was not there, and I do not know what Zamorak did with the staff, but whatever it was resulted in his banishment by the other gods for many years.") + npc("The very strange thing was that Saradomin must have known about it, whatever it was, before it even happened...") + player("Really? Why do you say that?") + npc("Well, it was the contents of the message I was returning to Zamorak;") + npc("Lucien seemed quite certain that there was a spy for Saradomin somewhere amongst his followers named Lennissa.") + npc("If whatever happened to the staff caused this curse to befall me, then it is certain that she too would have been afflicted, because she would have been in the very heart of the action.") + npc("Hmmm....") + npc("You have given me much to think on adventurer. I would like to reward you with my sturdy messenger boots, may they aid you in your travels.") + exec { player, npc -> + setAttribute(player, CurseOfZaros.attributeKharrimSpoke, true) + addItemOrDrop(player, Items.GHOSTLY_BOOTS_6106) + } + player("But where can I find this Lennissa?") + npc("Ah yes, the whereabouts of the treacherous Lennissa...") + exec { player, npc -> + // 1 of 3 paths. + loadLabel(player, "curseofzaros" + getAttribute(player, CurseOfZaros.attributePathNumber, 0)) + } + + label("subsequenttime") + player("Hello again Kharrim.") + player("Can you remind me where to find Lennissa?") + npc("Ah yes, the whereabouts of the treacherous Lennissa...") + exec { player, npc -> + // 1 of 3 paths. + loadLabel(player, "curseofzaros" + getAttribute(player, CurseOfZaros.attributePathNumber, 0)) + } + + label("curseofzaros1") + npc("Well, she was always sickeningly obedient to Saradomin, so I would expect her to have run to some great place of worship of him if she was affected by the curse to try and gain his blessing.") + player("Okay, well I'll try and find her for you then.") + + label("curseofzaros2") + npc("According to Lucien's intelligence report, she had been uncovered as a spy by her constant use of ships to ferry information...") + npc("It is entirely possible she would be located somewhere coastal to this day!") + player("Okay, well I'll try and find her for you then.") + + label("curseofzaros3") + npc("Well, we knew little about her or she would have been caught and exposed as a traitor and a spy, but Lucien did mention that he had evidence that she was a great fan of ball games...") + player("Okay, well I'll try and find her for you then.") + + + label("lostghostlything") + player(ChatAnim.SAD, "I lost those boots you gave me...", "Can I have some more please?") + exec { player, npc -> + addItemOrDrop(player, Items.GHOSTLY_BOOTS_6106) + } + npc(ChatAnim.SAD, "How strange...", "They seemed to return to me when you lost them...") + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/curseofzaros/MysteriousGhostLennissaDialogue.kt b/Server/src/main/content/region/desert/quest/curseofzaros/MysteriousGhostLennissaDialogue.kt new file mode 100644 index 0000000..74c3657 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/curseofzaros/MysteriousGhostLennissaDialogue.kt @@ -0,0 +1,155 @@ +package content.region.desert.quest.curseofzaros + +import core.api.* +import core.game.dialogue.ChatAnim +import core.game.dialogue.DialogueLabeller +import core.game.dialogue.DialogueOption +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class MysteriousGhostLennissaDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return MysteriousGhostLennissaDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, MysteriousGhostLennissaDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(2391, 2392, 2393) + } +} + +class MysteriousGhostLennissaDialogueFile : DialogueLabeller() { + override fun addConversation() { + exec { player, npc -> + if (inEquipment(player, Items.GHOSTSPEAK_AMULET_552) || inEquipment(player, Items.GHOSTSPEAK_AMULET_4250)){ + if (2390 + getAttribute(player, CurseOfZaros.attributePathNumber, 0) == npc.id) { + if (getAttribute(player, CurseOfZaros.attributeLennissaSpoke, false)) { + if (inInventory(player, Items.GHOSTLY_ROBE_6108) || inEquipment(player, Items.GHOSTLY_ROBE_6108)) { + loadLabel(player, "subsequenttime") + } else { + loadLabel(player, "lostghostlything") + } + } else { + loadLabel(player, "firsttime") + } + } else { + loadLabel(player, "wrongpath") + } + } else { + loadLabel(player, "noghostspeak") + } + } + + CurseOfZaros.withoutGhostspeak(this) + + CurseOfZaros.wrongPath(this) + + label("firsttime") + player("Hello. You would be Lennissa, I take it?") + npc("Who are you? Where did you hear that name? How comes it that you can see and speak to me?") + player("Well, a ghost called Kharrim directed me towards you.") + npc("So that weasel Kharrim has been blighted by this curse too?") + npc("Ha, a good thing too. If anybody deserved such a fate it would be one such as him.") + player("I guess you didn't get along then?") + npc("No, evil scum such as he should never have been allowed to walk this world.") + npc("What lies has he told you to come here? Have you come to try and kill me?") + player("Well, I'm not sure I could if I tried, but that is not why I have come to you.") + npc("Then speak, and speak well, for I may yet be dead, but am still a danger to those who cross me.") + player("Actually, I'm trying to work out why all of you invisible ghosts seem to have been cursed.") + player("I'm not sure how exactly, but the trail seems to have led me to you...") + npc("That makes no sense... I served Saradomin faithfully my entire life, then all of a sudden I find myself reduced to this state!") + player("Well, it seems as though that may have been the cause...") + npc("What? Explain yourself.") + player("As I understand it, it was something to do with the Staff of Armadyl, and your refusal to tell Saradomin that it had been stolen...") + npc("What? But... But that is not how it happened at all!") + options( + DialogueOption("tellmeyourstory", "Tell me your story", skipPlayer = true), + DialogueOption("goodbye", "Goodbye then", skipPlayer = true), + ) + + label("goodbye") + player("Well, that's all fascinating, but I just don't particularly care. Bye-bye.") + + label("tellmeyourstory") + player("Then please, go ahead and tell me the events of that day in your own words...") + npc("Let me see... I had been working as a spy for my Lord Saradomin, amongst the forces of... the Empty Lord.") + player("'The Empty Lord'? Who is that?") + npc("I will not give you his name, for to do so would give him power here.") + npc("Let us just say that he was a fearsome deity, whose strength was greater than all the gods we knew of on this realm at the time.") + npc("It is probably worth mentioning that at this time we had no knowledge of the mysterious nature god Guthix.") + player("So he was stronger than Saradomin?") + npc("As Saradomin was, yes. As Saradomin is now? Who can say?") + player("I see... Please, continue.") + npc("As I say, I was working as a spy within the very camp of my Lord's enemies.") + npc("I knew that should I have been caught, I risked being killed upon the spot, but my combat skills were always formidable, and if truth be told, there was a fair amount of dissent amongst... 'his' followers anyway.") + player("How do you mean 'dissent'?") + npc("Ah, to not understand this, you must have led a sheltered life...") + npc("Let me tell you this: Evil will always breed more evil, and will never be satisfied with what it has.") + npc("The Empty Lord chose to ally himself with the dark creatures of this world, fully aware that their own natures would cause them to rally against his rule, and take every opportunity they could to betray him.") + npc("This has always been the nature of evil. Perhaps he thought his power could prevent such treachery?") + npc("This allowed me freedom amongst their camp, for it was always easy to point the finger of suspicion at some unsuspecting necromancer or foolish Mahjarrat if it seemed as though my activities had been discovered.") + npc("Similarly, should I ever be caught in the act of my sabotage, it was all too easy to bribe whoever found me or persuade them into believing it was just some minor treachery of my own, rather than my work for my") + npc("Lord Saradomin.") + player("Okay... Well, that makes sense, but I don't understand what the Staff of Armadyl had to do with this...?") + npc("As I have told you, the Empty Lord was extremely powerful, but not so powerful that he could rule over the other deities of this world without opposition.") + npc("Should he have made a move against any other god, then he could still have been easily brought down by the combined efforts of the others.") + npc("The theft of Armadyl's staff changed this however.") + npc("If he had taken possession of this god-weapon, then his power would have been so great that he could have overthrown all on this world, and made it into his own image!") + npc("I could not allow such a thing to happen!") + npc("I went immediately to my comrade Dhalak, the mage, and told him that a message had come to the lair offering this weapon for sale!") + npc("I knew that as soon as my Lord Saradomin heard this, he would contact Armadyl to inform them of the theft, and the matter would have been resolved quickly and discreetly.") + player("So you passed this information to Dhalak instead of taking it to Saradomin yourself?") + npc("To my eternal shame, I indeed failed my Lord Saradomin...") + npc("I could not risk taking the message directly, for I feared my disguise had been uncovered.") + npc("Lucien particularly had been taking an unhealthy interest in my activities, and I had a gut feeling that to make any obvious moves against the Empty Lord would have been my undoing.") + npc("But Dhalak was a noble man! I cannot believe that he would not have taken my message immediately to Lord Saradomin!") + player("Well, it seems like he didn't, but I don't know why not...") + npc("Please adventurer, discover what foul fate must have befallen him for him to have neglected his duty!") + npc("I have not much to offer as reward, but for these spare robes I wore while on assignment...") + exec { player, npc -> + setAttribute(player, CurseOfZaros.attributeLennissaSpoke, true) + addItemOrDrop(player, Items.GHOSTLY_ROBE_6108) + } + npc("Please find him and discover why I am cursed like this!") + player("Where would I be able to find this Dhalak then?") + exec { player, npc -> + // 1 of 3 paths. + loadLabel(player, "curseofzaros" + getAttribute(player, CurseOfZaros.attributePathNumber, 0)) + } + + label("subsequenttime") + player("Hello Lennissa. Can you remind me where to find Dhalak?") + exec { player, npc -> + // 1 of 3 paths. + loadLabel(player, "curseofzaros" + getAttribute(player, CurseOfZaros.attributePathNumber, 0)) + } + + label("curseofzaros1") + npc("Dhalak? Well, he was always a knowlegeable mage, so if this curse has befallen him as well, I would suspect he would be researching how to free himself of it.") + npc("I would look for a library to find him if I were you.") + player("Okay, well I'll try and find him for you then.") + + label("curseofzaros2") + npc("Dhalak? He was always a loyal follower of Saradomin... I think he would have found an altar to Saradomin so that he may pray for this curse to be lifted.") + player("Okay, well I'll try and find him for you then.") + + label("curseofzaros3") + npc("Dhalak? I know not where, but he would try and make the most of his situation if he has been cursed, and find a place to lift his spirits!") + player("Okay, well I'll try and find him for you then.") + + + label("lostghostlything") + player(ChatAnim.SAD, "Could I have that rob bottom again? I seem to have", "misplaced it somewhere...") + exec { player, npc -> + addItemOrDrop(player, Items.GHOSTLY_ROBE_6108) + } + npc(ChatAnim.SAD, "Certainly, I am not sure how, but it returned to me by", "some magic or other.") + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/curseofzaros/MysteriousGhostRennardDialogue.kt b/Server/src/main/content/region/desert/quest/curseofzaros/MysteriousGhostRennardDialogue.kt new file mode 100644 index 0000000..83f8383 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/curseofzaros/MysteriousGhostRennardDialogue.kt @@ -0,0 +1,151 @@ +package content.region.desert.quest.curseofzaros + +import core.api.* +import core.game.dialogue.ChatAnim +import core.game.dialogue.DialogueLabeller +import core.game.dialogue.DialogueOption +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class MysteriousGhostRennardDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return MysteriousGhostRennardDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, MysteriousGhostRennardDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(2382, 2383, 2384) + } +} + +class MysteriousGhostRennardDialogueFile : DialogueLabeller() { + override fun addConversation() { + exec { player, npc -> + if (inEquipment(player, Items.GHOSTSPEAK_AMULET_552) || inEquipment(player, Items.GHOSTSPEAK_AMULET_4250)){ + if (2381 + getAttribute(player, CurseOfZaros.attributePathNumber, 0) == npc.id) { + if (getAttribute(player, CurseOfZaros.attributeRennardSpoke, false)) { + if (inInventory(player, Items.GHOSTLY_GLOVES_6110) || inEquipment(player, Items.GHOSTLY_GLOVES_6110)) { + loadLabel(player, "subsequenttime") + } else { + loadLabel(player, "lostghostlything") + } + } else { + loadLabel(player, "firsttime") + } + } else { + loadLabel(player, "wrongpath") + } + } else { + loadLabel(player, "noghostspeak") + } + } + + CurseOfZaros.withoutGhostspeak(this) + + CurseOfZaros.wrongPath(this) + + label("firsttime") + player("Hello. You must be Rennard.") + npc("What be this? You both see me and hear me, and also know my name?") + npc("Tell me what devilry brings you here, and be quick about it afore I gut you like a fish!") + player("Well, apart from the fact I ain't scared of no ghost, I am here because I have spoken to Valdez.") + npc("Valdez? Who be that? Some foul necromancer?") + player("No, he was a ghost I met near Glarial's tomb.") + player("He seems convinced that the artefact you stole from him is responsible for him becoming cursed to be an invisible ghost.") + player("Seems like he might be onto something too, given the state of you.") + npc("A curse ye say... Aye, that makes sense...") + npc("And there was I thinking my fate be the fault of the thieving and murdering I spent me life a-doing...") + npc("So it all began the day I stole that staff, ye say? Aye, that be a story I have never told another soul...") + options( + DialogueOption("tellmeyourstory", "Tell me your story", skipPlayer = true), + DialogueOption("goodbye", "Goodbye then", skipPlayer = true), + ) + + label("goodbye") + player("Well, that's all fascinating, but I just don't particularly care. Bye-bye.") + + label("tellmeyourstory") + player("Why don't you tell me what happened? I might be able to help...") + npc("Well, I was making me merry way along, having just pulled off a glorious jewellery heist from a bunch of stinking dwarves...") + player("Hey, that's no way to talk about dwarves! Some of my best friends are short!") + npc("Ah, yer misunderstand me [lad/lass], I wasn't generalising about the whole dwarf species, I had just stolen a bundle of jewels from a very specific group of dwarves who happened to have an odious stench about them!") + player("Oh. Well I guess that's okay then. Please continue.") + npc("Well, as I headed on me merry way, hoping the foul odours that lingered in me nostrils would soon pass, I see in front of me this explorer fella, all decked out in in his fine clothing, and carrying some long package") + npc("bundled in rags.") + npc("So I says to meself, 'Rennard', I says, 'Rennard, why would some fella all dressed in his finery be carrying something wrapped in dirty rags?'.") + npc("So I thinks to meself a little more, 'Rennard', I thinks, 'Rennard, maybe that fella has something valuable in there, and he covered it in dirty rags so it don't look so valuable'.") + npc("So I coshed this fella round the back of his head with me bag of jewels, picked up his package and was on me merry way afore he comes to.") + player("So what happened then?") + npc("Well, I makes me way to the closest tavern I knew of that catered to my sort of people...") + player("You mean thieves?") + npc("Right ye are, so I makes me way to the nearest friendly tavern, and unwraps the bundle to see what it had inside.") + player("The Staff of Armadyl?") + npc("Was it? Ah, I never knew that...") + npc("Anysways, I unwraps this staff, and sees it be a god- weapon; I may be just a common thief, but I recognises a weapon not made by mortal hands when I sees one.") + player("So what did you do then?") + npc("Well, I knew such a weapon would be of great value to...") + npc("Now that's funny. Can't remember his name, now. The powerful god, lived in the North-east. Took the Mahjarrat away from under Icthlarin's") + npc("control.") + npc("Anyway, I hired me a messenger to go off and let him know I had something I was prepared to sell that I thought he'd be interested in...") + npc("Now WHY can't I remember his name? Very odd that...") + player("So you sold the staff to this god you can't remember?") + npc("Well, that's the other funny thing... He never showed up, he sent some General or other instead.") + npc("Hmmm... You know... Thinking back on that, I'm getting the feeling that messenger did a little doublecross of his own, and took") + npc("me message to the wrong fella.") + player("So what was this General's name?") + npc("His name was Zamorak. I remember thinking at the time it was odd, because the fella was a mighty powerful warrior, but was never fully trusted by...") + npc("WHY can't I remember his name???") + player("So you suspect the messenger might have taken the message to the wrong person? So you think it was an accident or deliberate?") + npc("Well that I can't tell ya, but if something happened to get me cursed, it's likely the messenger would know what more than me.") + npc("His name was Kharrim, and if he caused me to be stuck like this, I'm gonna fillet him like a dog, ghost or no!") + npc("I tell ye what, you've given me much to think about so I'd like to offer yer a gift; Here, take these, they were the gloves I stole me first cake with, they might bring yer some luck.") + exec { player, npc -> + setAttribute(player, CurseOfZaros.attributeRennardSpoke, true) + addItemOrDrop(player, Items.GHOSTLY_GLOVES_6110) + } + player("Where can I find this Kharrim then?") + exec { player, npc -> + // 1 of 3 paths. + loadLabel(player, "curseofzaros" + getAttribute(player, CurseOfZaros.attributePathNumber, 0)) + } + + label("subsequenttime") + player("Hello again Rennard.") + npc("Ah, it be you again! What can I do fer ya?") + player("Can you tell me where I can find Kharrim again?") + exec { player, npc -> + // 1 of 3 paths. + loadLabel(player, "curseofzaros" + getAttribute(player, CurseOfZaros.attributePathNumber, 0)) + } + + label("curseofzaros1") + npc("Kharrim the messenger... Well, he was always a devoted follower of old General Zamorak, and if I remember rightly Zamorak set up a small base in an old temple near Dareeyak...") + npc("You might want to check around there.") + player("Okay, well I'll try and find him for you then.") + + label("curseofzaros2") + npc("Kharrim the messenger... Last I'd heard of him, he'd headed off to Carrallagar to seek his fortune. Ya might want to check around there somewhere.") + player("Okay, well I'll try and find him for you then.") + + label("curseofzaros3") + npc("Kharrim the messenger... The last I'd heard of that weasel he was claiming he'd found some underground deposit of runite ore guarded by demons and dragons.") + npc("I suspect he was pulling some scam or other, but if you know of such a place, that might be a good place to start checking.") + player("Okay, well I'll try and find him for you then.") + + + label("lostghostlything") + player(ChatAnim.SAD, "I lost those gloves you gave me...", "Can I have some more please?") + exec { player, npc -> + addItemOrDrop(player, Items.GHOSTLY_GLOVES_6110) + } + npc(ChatAnim.SAD, "It seems as though the curse that keeps me here", "extends to my very clothing...") + npc("Here, take them, some evil power returned them to", "me...") + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/curseofzaros/MysteriousGhostValdezDialogue.kt b/Server/src/main/content/region/desert/quest/curseofzaros/MysteriousGhostValdezDialogue.kt new file mode 100644 index 0000000..0383402 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/curseofzaros/MysteriousGhostValdezDialogue.kt @@ -0,0 +1,136 @@ +package content.region.desert.quest.curseofzaros + +import core.api.* +import core.game.dialogue.ChatAnim +import core.game.dialogue.DialogueLabeller +import core.game.dialogue.DialogueOption +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class MysteriousGhostValdezDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return MysteriousGhostValdezDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, MysteriousGhostValdezDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(2381) // wrong const SICK_LOOKING_SHEEP_4_2381 -> should be correct MYSTERIOUS_GHOST_2381 + } +} + +class MysteriousGhostValdezDialogueFile : DialogueLabeller() { + override fun addConversation() { + exec { player, npc -> + if (inEquipment(player, Items.GHOSTSPEAK_AMULET_552) || inEquipment(player, Items.GHOSTSPEAK_AMULET_4250)){ + if (getAttribute(player, CurseOfZaros.attributeValdezSpoke, false)) { + if (inInventory(player, Items.GHOSTLY_ROBE_6107) || inEquipment(player, Items.GHOSTLY_ROBE_6107)) { + loadLabel(player, "subsequenttime") + } else { + loadLabel(player, "lostghostlything") + } + } else { + loadLabel(player, "firsttime") + } + } else { + loadLabel(player, "noghostspeak") + } + } + + CurseOfZaros.withoutGhostspeak(this) + + label("firsttime") + player("Hello.") + npc(ChatAnim.EXTREMELY_SHOCKED, "H-hello!") + player(ChatAnim.THINKING, "So what's up?") + npc(ChatAnim.EXTREMELY_SHOCKED, "I cannot believe it!", "You can see me?", "You understand my words?") + player("Sure can.", "So why are you hanging around here?") + npc(ChatAnim.SAD, "My tale is one of woe...", "No doubt you will have little interest in hearing it...") + npc(ChatAnim.SAD, "Though it has been so many moons since last I had", "company in this endless non-life...") + options( + DialogueOption("tellmeyourstory", "Tell me your story", skipPlayer = true), + DialogueOption("goodbye", "Goodbye then", skipPlayer = true), + ) + + label("goodbye") + player("Well, that's all fascinating, but I just don't particularly care. Bye-bye.") + + label("tellmeyourstory") + player("Well, actually I would like to know what happened to you to turn you into an invisible ghost.") + player(ChatAnim.SUSPICIOUS, "If only so I can make sure it doesn't happen to me...") + npc("My name is Valdez. I served my Lord Saradomin faithfully for many years, as an explorer of this strange land we had been brought to.") + npc("I remember the day this curse fell upon me clearly... I had just discovered a huge temple, hidden below the ground, of one of Saradomin's compatriots.") + npc("I am unsure who had built it, or why they had left it seemingly abandoned, but inside I located a great treasure...") + npc("It was the godstaff of Armadyl.", "Oh, how I rue my choice that day!") + player("Choice?") + npc("Aye, stranger.", "I chose that day to take it so that my Lord Saradomin's", "power and prestige could be increased by its possession.") + npc("A god-weapon!", "Do you have any comprehension of the difficulty and", "rarity in obtaining such a thing?") + npc("To find such an artefact of power just lying around, it is almost incomprehensible...") + npc("So it was there in that deserted temple that I made my", "choice.", "I took the staff, and left that temple for Entrana", "immediately.") + npc("This was the cause of my cursed state.") + player("What, you mean you gave it to Saradomin and in return he cursed you???") + player("Seems kind of ungrateful if you ask me...") + npc("No stranger, you misunderstand completely...", "Firstly my gracious Lord would never treat anyone in", "such a manner;", "If he felt it was beyond my bounds as a mere mortal") + npc("to hold such an artefact, he would simply have commanded me to return it to whence I had claimed it, and I being eternally loyal would have obeyed without question...") + player("And secondly?") + npc("And secondly, I never managed to pass the artefact on to my Lord...") + npc("The vile thief Rennard accosted me as I made my way to Entrana, and after defeating me with a sneak attack, plundered the staff from my person, and left me for dead...") + npc("I do not know what became of the staff, but I can feel in my very bones that whatever its final fate was, it is somehow related to this curse upon me...") + player("Wow", "Tough break.") + npc("I am sorry to bore you with my tale stranger, please allow me to compound my rudeness by asking you for one favour, small to perform?") + player("Eh, I won't make any promises, but if it's nothing too annoying I guess I can help you out.") + npc("Many thanks stranger, this existence tortures me...") + npc("I need you to find Rennard and if he has the staff yet reclaim it, or find out what hideous deed he performed to curse me so!") + npc("I have nothing I may offer you save this piece of clothing, please take it as payment...") + exec { player, npc -> + setAttribute(player, CurseOfZaros.attributeValdezSpoke, true) + // Set the path to follow. + setAttribute(player, CurseOfZaros.attributePathNumber, (1..3).random()) + addItemOrDrop(player, Items.GHOSTLY_ROBE_6107) + } + player("Where can I find this Rennard then?") + exec { player, npc -> + // 1 of 3 paths. + loadLabel(player, "curseofzaros" + getAttribute(player, CurseOfZaros.attributePathNumber, 0)) + } + + label("subsequenttime") + npc("Thank you for hearing my tale...", "It has been so lonely here...") + player("Can you remind me where to find the thief Rennard who caused this curse to befall you again?") + npc("Of course...") + exec { player, npc -> + // 1 of 3 paths. + loadLabel(player, "curseofzaros" + getAttribute(player, CurseOfZaros.attributePathNumber, 0)) + } + + label("curseofzaros1") + npc("Ah, the infamous Rennard...", "The last I had heard of him, he had sought passage on", "a ship crewed by none but the most dastardly lowly", "pirates...") + npc("I also heard that this ship had been caught in a violent", "storm, and stranded upon rocks, where the pirates then", "made their home...") + player("Okay, well I'll try and find him for you then.") + + label("curseofzaros2") + npc("Ah, the infamous Rennard...", "The last I had heard of that vile thief, he had joined a", "group of bandits in an evil land to the North-east of", "here, where they had made their home living outside of") + npc("the reach of the authorities that pursued them...") + player("Okay, well I'll try and find him for you then.") + + label("curseofzaros3") + npc("Ah, the infamous Rennard...", "The last I had heard of that vile thief, he had joined a", "group of bandits in a barren land to the South-east of", "here, where they prey upon the unsuspecting visitors to") + npc("the desert awaiting the return of their dark master...") + player("Okay, well I'll try and find him for you then.") + + + label("lostghostlything") + player(ChatAnim.SAD, "I lost that Robe top you gave me...", "Can I have another please?") + exec { player, npc -> + addItemOrDrop(player, Items.GHOSTLY_ROBE_6107) + } + npc(ChatAnim.SAD, "It seems as though the curse that keeps me here", "extends to my very clothing...") + npc("Here, take it, the moment you lost it, it returned to", "me...") + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/curseofzaros/MysteriousGhostViggoraDialogue.kt b/Server/src/main/content/region/desert/quest/curseofzaros/MysteriousGhostViggoraDialogue.kt new file mode 100644 index 0000000..d5464ee --- /dev/null +++ b/Server/src/main/content/region/desert/quest/curseofzaros/MysteriousGhostViggoraDialogue.kt @@ -0,0 +1,188 @@ +package content.region.desert.quest.curseofzaros + +import core.api.* +import core.game.dialogue.ChatAnim +import core.game.dialogue.DialogueLabeller +import core.game.dialogue.DialogueOption +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class MysteriousGhostViggoraDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return MysteriousGhostViggoraDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, MysteriousGhostViggoraDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(2394, 2395, 2396) + } +} + +class MysteriousGhostViggoraDialogueFile : DialogueLabeller() { + override fun addConversation() { + exec { player, npc -> + if (inEquipment(player, Items.GHOSTSPEAK_AMULET_552) || inEquipment(player, Items.GHOSTSPEAK_AMULET_4250)){ + if (2393 + getAttribute(player, CurseOfZaros.attributePathNumber, 0) == npc.id) { + if (getAttribute(player, CurseOfZaros.attributeViggoraSpoke, false)) { + if (inInventory(player, Items.GHOSTLY_CLOAK_6111) || inEquipment(player, Items.GHOSTLY_CLOAK_6111)) { + loadLabel(player, "subsequenttime") + } else { + loadLabel(player, "lostghostlything") + } + } else { + loadLabel(player, "firsttime") + } + } else { + loadLabel(player, "wrongpath") + } + } else { + loadLabel(player, "noghostspeak") + } + } + + CurseOfZaros.withoutGhostspeak(this) + + CurseOfZaros.wrongPath(this) + + label("firsttime") + player("So... You must be the infamous Viggora.") + npc("Hold thy tongue varlet! Speak fast, how come you to find me here, and how doth you understand mine speech?") + player("You want me to hold my tongue and tell you how I found you?") + npc("Cease thy chatter and respond to my demand!") + player("Cease my chatter AND respond to your demand?") + npc("I warn thee knave, this curse upon me hath not improved my temper, these centuries past...") + player("Well, it's actually about that curse that I have come to speak to you.") + npc("Oh, be that so? Then forgive my swift anger, and speak to me of how you plan to break this curse.") + player("Erm... I didn't actually mention anything about breaking the curse...") + npc("Then what lets you dare speak to me?") + player("Well, I heard of your name from a mage called Dhalak, and I'm trying to find out what exactly caused the curse to befall him, and you as well apparently.") + npc("Ha! So the weak-willed mage was cursed along with me?") + npc("Well now, that is an interesting turn of events... Then am I to assume that Valdez, Rennard, Kharrim and Lennissa were also cursed along with me?") + player("...How did you know that?") + npc("Ha ha ha! Oh, the curse cut deeper than I had previously thought!") + npc("Stranger, this news has brought me a ray of sunshine in an otherwise dreary millennium! Please, ask any question you wish!") + options( + DialogueOption("tellmeyourstory", "Tell me your story", skipPlayer = true), + DialogueOption("goodbye", "Goodbye then", skipPlayer = true), + ) + + label("goodbye") + player("Well, that's all fascinating, but I just don't particularly care. Bye-bye.") + + label("tellmeyourstory") + player("Erm... Thanks, I think. So what exactly happened on that day you were all cursed?") + player("I know that Valdez discovered the Staff of Armadyl, was robbed by Rennard, who then sent Kharrim to tell Zamorak of it.") + player("Meanwhile Lennissa heard of the sale, and informed Dhalak who placed an enchantment upon it so that its power would be hidden.") + player("I still don't know what happened with the staff to cause this curse, or what you had to do with it though...") + npc("Well stranger, rest yourself awhile, and I will recount a tale of the events of that day, for I was one of the few actually there when it happened...") + player("When what happened?") + npc("When my Lord Zamorak first got his taste of godhood!") + player("Wow. Sounds like quite the dinner party anecdote.") + npc("You can take the snide venom out of your voice whelp, you came to me; 'twas not the other way round.") + player("Okay, okay. Please continue.") + npc("Well now, let us see... As you may have heard tell, my affiliation lay with General Zamorak, a mighty warrior of the Mahjarrat tribe, and my skill on the battlefield had quickly brought") + npc("me to his attention.") + npc("So pleased was he with my bloodlust that he promoted me on the battlefield once to serve in his honour guard, and let me tell you, this was a rare honour indeed, for I was the only human chosen to take such a position.") + player("Really?") + npc("Oh yes, the dragon riders, Mahjarrat, demons and vampyre warriors made up the bulk of the force, but I wager I was their equal in all ways of combat.") + npc("Ha, when I think of someone like Lucien struggling to lift a blade, in some ways I was even their better!") + player("Please continue.") + npc("Well anyway... Myself and the rest of Zamoraks honour guard were formulating stratagems in our battle-tent, when that sneaky messenger Kharrim came in offering to sell us") + npc("the god-staff of Armadyl!") + npc("Naturally, we suspected that this was some trick by our Lord to test our loyalty...") + player("Yes, who was your lord? Everyone has been very evasive about that...") + npc("Quiet fool, all things in their course; You are disrupting my train of thought!") + player("Sorry...") + npc("Well anyway, we thought it was too good to be true, yet when we visited this scummy tavern we were amazed to discover there was no trick, no test of loyalty, no hidden trap:") + npc("Somehow this fool had actually managed to obtain the god-staff of Armadyl!") + npc("Its power was incredible, you could almost feel the energies crackling around it in the air!") + player("So what happened then?") + npc("Well, with such a weapon, the plans we had been developing for a rebellion against our lord could finally be put into action, but we knew that we would have to act swiftly, before he heard that we had a weapon") + npc("capable of defeating him, and we would have to act decisively, for even amongst our group there were still those loyal to the lord - such as that pathetic fool Azzanadra.") + player("So JUST WHO WAS this lord you speak of?") + npc("And I tell thee again, I will say when it is appropriate, now do not disrupt my tale!") + player("Okay, carry on then...") + npc("So anyway, Lord Zamorak and his most trusted compatriots, namely myself, Hazeel, Drakan, Thammaron and Zemouregal made plans to overthrow our lord using the god-weapon, and by pledging") + npc("allegiance to Zamorak as our master, were each to be given a large piece of land as our own in return.") + npc("We decided to move immediately, before anyone got cold feet, or any other parties could interfere in our work, and made haste towards the castle where our Lord lived.") + npc("If Lucien had not been otherwise occupied, he would have probably accompanied us with his magicks, but it turned out the foolish Dhalak had made his involvement unnecessary with some spells of his own allowing us to") + npc("get close enough to the castle with the staff without the Empty Lord being able to sense its presence.") + player("So your lord was the one that cursed you?") + npc("I am coming to that... So anyway, we made our way to the castle, under the pretense that we had war plans against Saradomin and the other deities to discuss.") + npc("As usual, our lord was guarded well, but this was why Zamorak had brought his most trusted fighters with him.") + npc("While we distracted the Empty Lord with our feints and attacks, and kept his bodyguards busy, Lord Zamorak outflanked him, unsheathed the staff and plunged it into his back!") + npc("Ah, it was a glorious sight... At that moment I was reminded for whom I fought, and why General Zamorak had earned his nickname 'the scourge' upon the battlefield...") + player("And the next thing you know you were cursed?") + npc("No, it was not quite that simple... The Empty Lord turned away from our battle, eyes burning with hatred, and towards Zamorak instead. Seeing this, we all fought with extra vigour, so that") + npc("General Zamorak would not face our lord alone, but we were outnumbered by many hundreds of warriors and demons, and could not reach him to assist him!") + player("So what then?") + npc("Why, it was the Empty Lord versus Zamorak, in single combat! And the sight of the battle will be with me forever more...") + npc("The Empty Lord was a powerful god, stronger than any of the others awake at that time, possibly even as strong as Guthix is, and Zamorak was but a mortal: A Mahjarrat warrior all the same, with all of the") + npc("strength and power that that entails, but mortal nonetheless, but to see him fight, you would not think of him as a 'mere' anything...") + npc("He was war itself! Flurry after flurry of blows he rained upon the Empty Lord, and the very castle walls shook and quivered with their power, but the Empty Lord would not fall!") + npc("Even with the weapon of a god embedded in his back, he fought on, and with each blow our victory seemed less and less certain...") + player("So what then?") + npc("Well, then a miracle happened. Or luck. Or natural justice.") + npc("You can call it what you want, but as the Empty Lords hands wrapped tightly around Zamorak's throat, Lord Zamorak, kicking and screaming defiantly and radiant in his anger until the very last, plunged towards the") + npc("Empty Lord, who seemed to lose his footing slightly, and fell in such a way so that the staff plunged deeper into his body, but also impaled Lord Zamorak with it at the same time...") + npc("And then...") + player("And then what?") + npc("And then nothing. There was a sudden flash of bright light, and then a sudden blink of cold darkness, and it was over.") + npc("Zamorak stood over the Empty Lord who was slowly... fading from existence... And as he faded, it seemed as though... It almost seemed as though Zamorak became more real,") + npc("more solid than he had been before...") + npc("And as the Empty Lord faded from this world completely, I heard his voice, almost a whisper upon the wind, cursing all who had helped Zamorak in his victory, which as you now tell me seems to have been all who") + npc("were responsible for the staff ending up in Zamorak's hands at the castle.") + npc("As I heard it, I saw that I too was fading, just as the Empty Lord had, and I called to my brethren for their assistance, but they could no longer hear my words, nor see my form.") + npc("It was then that the other gods appeared and banished Zamorak from the world completely for daring to kill one of their kind, although as it turned out it didn't quite work out that way for them, when he returned") + npc("stronger than ever, a god himself.") + npc("But the god wars were another story entirely...") + player("But... I don't understand... If it was Zamorak who used the weapon, then why was it only you who were cursed?") + player("And the other people who were cursed, why them? Why not the other Mahjarrat for example?") + player("And just who was this 'Empty Lord' you keep speaking of?") + npc("Well, in my life I was nothing but a warrior. I had no hidden knowledge, I didn't especially care about the gods or their magics, and I certainly didn't respect them.") + npc("Now in my... I suppose this is my death. I am but a shade on the wind, unnoticed by all who pass me, until today anyway, and the only answer I can give you is that the others who were with me, the") + npc("Mahjarrats and the Vampyre, they were beings of magic.") + npc("It runs through their very veins, and ebbs through their bones.") + npc("Who knows why the curse fell as it did? Perhaps as a mere human I was more susceptible to it, when they were not. Perhaps they too are cursed, but their life spans are so") + npc("long that it will be millennia before they feel it upon them. Perhaps because it did not affect them, it extended backwards through time, to the moment the staff was") + npc("taken from its rightful place, and all who had known of its theft were cursed too. Perhaps there are others also cursed, who played no part in this tale, and were merely unlucky enough to be") + npc("in the wrong place at the wrong time...") + npc("I don't know. Things do not always happen for a reason, just as tales do not always end with all of the loose ends neatly tied up and all answers supplied.") + npc("I have simply told you the events I was witness to, for I can do no more.") + npc("You have cheered me no end to let me know that this curse that has afflicted me has not left me alone here, in this void between worlds.") + exec { player, npc -> + setAttribute(player, CurseOfZaros.attributeViggoraSpoke, true) + addItemOrDrop(player, Items.GHOSTLY_CLOAK_6111) + } + npc("Perhaps I will hunt down these others who have also been cursed as I was, but I feel I must reward you for your efforts; Here, take my cloak, it is drenched in the blood of a") + npc("thousand foes, and may bring you luck in battle.") + player("So how can I break this curse?") + npc("Who knows? If it was the death curse of the Empty Lord, there may be no way to break it.") + npc("If it was not his death curse, and he is still alive but not on this world, then the only way to break it may be to bring him back here;") + npc("But I would rather stay cursed than suffer under his rule again...") + player("But WHO was this 'Empty Lord'? WHAT was his NAME?") + npc("You do not know? You have not guessed yet?") + npc("He was Zaros.") + + label("subsequenttime") + player("Hello.") + npc("Hello yourself.") + player("I really liked your little story. Can you tell me another one?") + player("Preferably something with a big fight and lots of explosions!") + npc("...You are a very strange young @g[man/woman].") + + label("lostghostlything") + player(ChatAnim.SAD, "Can I have that cloak back?") + exec { player, npc -> + addItemOrDrop(player, Items.GHOSTLY_CLOAK_6111) + } + npc("Hmph.", "I suppose.") + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/ArchaeologistDialogue.kt b/Server/src/main/content/region/desert/quest/deserttreasure/ArchaeologistDialogue.kt new file mode 100644 index 0000000..397cd05 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/ArchaeologistDialogue.kt @@ -0,0 +1,211 @@ +package content.region.desert.quest.deserttreasure + +import content.global.handlers.iface.BookInterface +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +/** Known in RS3 as Asgarnia Smith */ +class ArchaeologistDialogue(player: Player? = null) : DialoguePlugin(player){ + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player!!, ArchaeologistDialogueFile(), npc) + return false + } + override fun newInstance(player: Player?): DialoguePlugin { + return ArchaeologistDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.ARCHAEOLOGIST_1918) + } +} + +class ArchaeologistDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + + b.onQuestStages(DesertTreasure.questName, 0) + .player(FacialExpression.FRIENDLY,"Hello there.") + .branch { player -> + return@branch if (DesertTreasure.hasRequirements(player)) { 1 } else { 0 } + }.let{ branch -> + // Failure branch + branch.onValue(0) + .line("He seems to be lost in his own thoughts...") + .end() + return@let branch // Return DialogueBranchBuilder instead of DialogueBuilder to forward the success branch. + }.onValue(1) // Success branch + .npc(FacialExpression.FRIENDLY, "Howdy stranger. What brings you out to these parts?") + .let { path -> + val originalPath = b.placeholder() + path.goto(originalPath) + originalPath.builder().options().let { optionBuilder -> + optionBuilder.option("What are you doing here?") + .player("Nothing much - What are you doing here?", "It doesn't seem like there's much to do out here in the", "desert!") + .npc("Well, that's where you'd be wrong.", "I work for the Archaeological Society of Varrock, and", "have been excavating around here recently.") + .npcl("Was there something you specifically wanted?") + .goto(originalPath) + optionBuilder.option("Do you have any quests?") + .player(FacialExpression.FRIENDLY, "Do you have any quests?", "Call it a hunch, but you look like the type of man who", "might...") + .npc(FacialExpression.HALF_THINKING, "Well, it's funny you should say that.", "I'm not sure if I would really call it a quest as such,", "but I found this ancient stone tablet in one of my", "excavations, and it would really help me out if you") + .npc(FacialExpression.FRIENDLY, "could go and take it back to the digsite for me and get", "it examined.") + .npc(FacialExpression.NEUTRAL, "It's very old, and I don't recognise and of the", "inscriptions on it.") + .options().let { optionBuilder2 -> + optionBuilder2.option("Yes, I'll help you.") + .betweenStage { df, player, _, _ -> + addItemOrDrop(player, Items.ETCHINGS_4654) + } + .player("Sure, I was heading that way anyway.", "Any particular person at the digsite you want me to", "talk to?") + .npc(FacialExpression.NEUTRAL, "His name's Terry Balando. Give it to nobody but him.", "I'm sorry, I can't entrust you with the actual tablet I", "found, but it is far too valuable to give away, but I took", "these etchings - they should be enough for him to make") + .npc(FacialExpression.NEUTRAL, "a preliminary translation on.", "Come back and let me know what he says, I would hate", "to waste my time excavating anything that isn't worth", "my time as a world famous archaeologist!") + .endWith { _, player -> + if(getQuestStage(player, DesertTreasure.questName) == 0) { + setQuestStage(player, DesertTreasure.questName, 1) + } + } + optionBuilder2.option("No thanks, I don't want to help.") + .playerl("No thanks. Playing delivery boy doesn't really sound like much fun to me. ") + .npcl(" Well, okay. Can't say as I blame you for thinking that. I'll go take it there myself later I guess.") + .end() + } + optionBuilder.option("Who are you?") + .playerl(FacialExpression.THINKING, "Who are you, anyway?") + .npc(FacialExpression.EXTREMELY_SHOCKED, "You don't recognize me???", "I am the world famous Asgarnia Smith, Archaeologist", "extraordinaire!") + .npc(FacialExpression.HALF_THINKING, "I am the one who discovered the long forgotten", "Temple of Ikov!", "The one who unearthed the strange trap filled arena", "in Brimhaven!") + .npc(FacialExpression.HALF_THINKING, "I'm the leading archaeological expert of our time!", "I was voted archaeologist of the year four years", "running by the Varrock Herald! Are you REALLY", "sure you've never heard of me?") + .playerl(FacialExpression.THINKING, "No, I really haven't.") + .npc(FacialExpression.EXTREMELY_SHOCKED, "Well then, I'm confused.", "Why did you come over and speak to me if you don't", "know who I am? What do you want?") + .goto(originalPath) + optionBuilder.option("Nothing really.") + .playerl("Nothing really. I'm just wandering around for no good reason.") + .npcl("Uh-huh. Well, if you'll excuse me, I have a lot more work to do before I can bed down for the night.") + .end() + } + } + + + b.onQuestStages(DesertTreasure.questName, 1,2) + .npcl("So what did Terry Balando say about those etchings? Did he give you a translation for me?") + .playerl("Um...yeah...about that... I kind of didn't go and speak to him yet...") + .npcl("Well what are you waiting for? A written invitation? All I want you to do is take those etchings up to the digsite for me!") + .playerl("Okay, I'll do that then.") + .end() + + b.onQuestStages(DesertTreasure.questName, 3) + .playerl("Hello there.") + .npcl("So what did Terry Balando say about those etchings? Did he give you a translation for me?") + .branch { player -> + return@branch if (inInventory(player, Items.TRANSLATION_4655)) { 1 } else { 0 } + }.let{ branch -> + // Failure branch + branch.onValue(0) + .playerl("Yeah, he did. But I don't have it with me.") + .npcl("...") + .npcl("I see.") + .npcl("Well could you go and get me that translation? It could be vital!") + .end() + return@let branch // Return DialogueBranchBuilder instead of DialogueBuilder to forward the success branch. + }.onValue(1) // Success branch + .playerl("Yeah, he did. I have it here in this book.") + .npcl("Did you take a read of this? It will do you good to understand how this profession works. Here, have a read.") + .options().let { optionBuilder -> + optionBuilder.option("Read book") + .endWith { _, player -> + BookInterface.openBook(player, BookInterface.FANCY_BOOK_3_49, TranslationBook.Companion::display) + } + return@let optionBuilder + } + .option("Don't read book") + .playerl("Yeah, I did. Kind of boring really.") + .npcl("Excellent. Just give me a moment to read this, and talk to me again in a second.") + .endWith { _, player -> + if(getQuestStage(player, DesertTreasure.questName) == 3) { + removeItem(player, Items.TRANSLATION_4655) // remove if exists + setQuestStage(player, DesertTreasure.questName, 4) + } + } + + b.onQuestStages(DesertTreasure.questName, 4) + .playerl("Hello there.") + .npcl("Hmmm. Interesting. It seems to me like there's some kind of treasure hidden out in the desert.") + .npcl("So what do you say? Fancy being a treasure hunter like me?") + .playerl("Uh... don't you mean archaeologist?") + .npcl("Yeeees... An archaeologist...") + .npcl("It's all this hot sun getting to me I think.") + .npcl("Well anyway, let's just assume there is a treasure hidden in the desert somewhere, and let's just say for the sake of argument that maybe if I found a big stash of gold and treasure I wouldn't necessarily just hand it") + .npcl("all over to the Museum of Varrock.") + .npcl("Let's also say, purely hypothetically, that if there were such a big stash of treasure and someone were to help me find it, then that hypothetical personal might be entitled to, oh, let's say a purely for the sake of") + .npcl("argument thirty percent split...") + .playerl("Fifty percent.") + .npcl("That's right!") + .npcl("A purely for the sake of argument fifty-fifty split on this hypothetical treasure, should it exist...") + .npcl("Do you see where I'm going with this?") + .playerl("You want me to help you find some treasure for a fifty percent share, as long as I don't tell anybody, and your reputation as an esteemed archaeologist with the Museum of Varrock remains intact, and nobody") + .playerl("discovers you're actually just a treasure hunter?") + .npcl("Uh... yes, but the way you said it makes it sound like I'm doing something wrong...") + .npcl("So what do you say? Partners?") + .options() + .let { optionBuilder -> + optionBuilder.option("Help him") + .playerl("Well... I guess nobody is really going to lose out on anything, and we don't even know if there is any treasure...") + .playerl("Aw, go on then. Count me in.") + .npcl("Good @g[lad,lass]! Well, if we split up we'll be able to find treasure quicker.") + .npcl("I'll continue searching around here in this Bedabin Camp, you head due South to the Bandit Village. If either of us find anything, we'll come find each other and say what, okay?") + .npcl("You head due South, see what you can find out about this tablet.") + .endWith { _, player -> + if(getQuestStage(player, DesertTreasure.questName) == 4) { + setQuestStage(player, DesertTreasure.questName, 5) + } + } + optionBuilder.option("Don't help him") + .playerl("This all sounds very immoral, and I don't want any part of your seedy little schemes.") + .npcl("Aw, c'mon, cut me a break here man! Look, nobody is really getting hurt, right? This treasure is either going to lie around in some underground ruin, or lie around in some museum for") + .npcl("people to look at!") + .npcl("It makes sense for the people to go to all the risk to get a little payback for it, right? Besides, anything of real historical value we can hand over to the museum - we'll just keep the cash for") + .npcl("ourselves!") + .npcl("C'mon... what do you say? Partners?") + .options() + .let { optionBuilder -> + optionBuilder.option("Help him") + .playerl("Well... I guess nobody is really going to lose out on anything, and we don't even know if there is any treasure...") + .playerl("Aw, go on then. Count me in.") + .npcl("Good @g[lad,lass]! Well, if we split up we'll be able to find treasure quicker.") + .npcl("I'll continue searching around here in this Bedabin Camp, you head due South to the Bandit Village. If either of us find anything, we'll come find each other and say what, okay?") + .npcl("You head due South, see what you can find out about this tablet.") + .endWith { _, player -> + if(getQuestStage(player, DesertTreasure.questName) == 4) { + setQuestStage(player, DesertTreasure.questName, 5) + } + } + optionBuilder.option("Don't help him") + .playerl("I don't trust anything about your little scheme, including you! I want nothing to do with this!") + .npcl("Eh, you'll come running back when you realize just how much money we could be talking here.") + .npcl("I'll see you again when you come crawling back, begging to be cut in on the deal.") + .end() + } + } + + b.onQuestStages(DesertTreasure.questName, 5) + .playerl("Hello there.") + .npcl("Hello again. You find any signs of that treasure yet?") + .playerl("Not yet...") + .npcl("Well, head south to that bandit camp. I bet if there's anything out here, they'll know about it. Don't let on it might be valuable though! Those thieves will steal it as soon as look at you!") + + b.onQuestStages(DesertTreasure.questName, 6,7,8) + .playerl("Hello there.") + .npcl("Hello again. You find any signs of that treasure yet?") + .playerl("Not as such... Although I think I'm onto something of a promising lead...") + .playerl("Did you ever hear of something called the Diamonds of Azzanadra?") + .npcl("Diamonds of Azzanadra? That sounds very promising indeed!") + .playerl("So you have heard of them?") + .npcl("Nope, never heard of them before, but you said diamonds! Diamonds are always promising!") + + + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/AzzanadraDialogue.kt b/Server/src/main/content/region/desert/quest/deserttreasure/AzzanadraDialogue.kt new file mode 100644 index 0000000..c8401ac --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/AzzanadraDialogue.kt @@ -0,0 +1,59 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.SpellBookManager +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class AzzanadraDialogue(player: Player? = null) : DialoguePlugin(player){ + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player!!, AzzanadraDialogueFile(), npc) + return false + } + override fun newInstance(player: Player?): DialoguePlugin { + return AzzanadraDialogue(player) + } + override fun getIds(): IntArray { + /* This is wrong SCARABS_1970 should be AZZANADRA_1970 */ + return intArrayOf(NPCs.SCARABS_1970, NPCs.AZZANADRA_1971) + } +} + +class AzzanadraDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + + b.onQuestStages(DesertTreasure.questName, 10) + .npcl(FacialExpression.OLD_DEFAULT, "I knew they could not trap me here for long!") + .npcl(FacialExpression.OLD_DEFAULT, "Well done, soldier, tell me, how goes the battle?") + .playerl(FacialExpression.THINKING, "Battle?") + .npcl(FacialExpression.OLD_DEFAULT, "You do not know of the battle?") + .npcl(FacialExpression.OLD_DEFAULT, "More time must have passed than I had thought...") + .npcl(FacialExpression.OLD_DEFAULT, "Tell me, what news of great Paddewwa? Do the shining spires of Lassar still stand? And what of glorious Annakarl? The fortress is still intact?") + .player("Uh...", "Sorry, I've never heard of them...") + .npcl(FacialExpression.OLD_SAD, "No!") + .npcl(FacialExpression.OLD_SAD, "My lord... What has become of you? I cannot hear your voice in my mind anymore!") + .npcl(FacialExpression.OLD_DEFAULT, "My thanks to you brave warrior for your help in freeing me from this accursed tomb, but it seems I have much to do to make amends.") + .npcl(FacialExpression.OLD_DEFAULT, "If the shining cities no longer stand, then it means that we must have failed my lord...") + .npcl(FacialExpression.OLD_DEFAULT, "How long have I been trapped here? Master... Have you truly been dispatched from this world?") + .npcl(FacialExpression.OLD_DEFAULT, "Warrior, for your efforts in freeing me, I offer you the gift of knowledge.") + .npcl(FacialExpression.OLD_DEFAULT, "I bestow upon you the ancient magicks, taught me by my Lord before his disappearance, may you use them well in battle for our people!") + .npcl(FacialExpression.OLD_DEFAULT, "They will replace the knowledge you previously had, but you may switch between them by praying at the altar in this room at any time.") + .npcl(FacialExpression.OLD_DEFAULT, "I trust that we shall meet again adventurer, I offer you the blessings of myself and my master in all of your endeavours!") + .npcl(FacialExpression.OLD_DEFAULT, "Now, I must leave you, for there must be some trace of my master's power left somewhere. Feel free to use the portal I shall create to return here easily in the future!") + .endWith { _, player -> + if(getQuestStage(player, DesertTreasure.questName) == 10) { + sendMessage(player,"A strange wisdom has filled your mind...") + finishQuest(player, DesertTreasure.questName) + player.spellBookManager.setSpellBook(SpellBookManager.SpellBook.ANCIENT) + player.spellBookManager.update(player) + } + } + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/BartenderDialogue.kt b/Server/src/main/content/region/desert/quest/deserttreasure/BartenderDialogue.kt new file mode 100644 index 0000000..2e3e789 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/BartenderDialogue.kt @@ -0,0 +1,155 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class BartenderDialogue(player: Player? = null) : DialoguePlugin(player){ + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player!!, BartenderDialogueFile(), npc) + return false + } + override fun newInstance(player: Player?): DialoguePlugin { + return BartenderDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.BARTENDER_1921) + } +} +class BartenderDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + + b.onQuestStages(DesertTreasure.questName, 0,1,2,3,4) + .npcl(FacialExpression.ANNOYED, "Get out of here. I have nothing to say to the likes of you.") + .end() + + b.onQuestStages(DesertTreasure.questName, 5) + .branch { player -> + return@branch if (getAttribute(player, DesertTreasure.attributeBoughtBeer, false)) { 1 } else { 0 } + }.let{ branch -> + branch.onValue(1) + .npcl("You've had your drink, now get out of here. I have nothing to say to the-") + .playerl("No, Wait! Look, I'm here on an archaeological expedition for the Museum of Varrock.") + .playerl("I am only here looking for artefacts...") + .npcl("Oh really? Our inheritance is only sand and death. What do you expect to find out here in this desert forsaken by the gods?") + .options() + .let { optionBuilder -> + optionBuilder.option("I heard about treasure...") + .playerl("As I understand it there's some kind of hidden treasure in these parts...") + .npcl("Look around @g[pal,lady]. Does it looks like there's any treasure near here?") + .npcl("If I were you I'd get lost before someone takes a dislike to your face and removes it for you.") + .end() + + optionBuilder.option("I heard about four diamonds...") + .playerl("I heard a rumour about four diamonds or crystals...") + .npcl("The four diamonds of Azzanadra??? How came you to know of this?") + .playerl("You've heard of them then?") + .npcl("It's just a fairy tale for children. Maybe one of the village elders might know more, but it's not really something I care about.") + .npcl("Now get out of here, your sort isn't welcome in my bar.") + .endWith { _, player -> + if(getQuestStage(player, DesertTreasure.questName) == 5) { + setQuestStage(player, DesertTreasure.questName, 6) + } + } + + optionBuilder.option("I heard about a fortress...") + .playerl("Certain things have led me to believe there may be some kind of ruined fortress around here...") + .npcl("Doubt it. What in the world would someone need to guard against in the middle of this desert?") + .npcl("A bad attack of sand? I think you're on the wrong track, mister so-called archaeologist.") + .end() + } + + branch.onValue(0) + .npcl("If you're not buying anything, I have nothing to say to you.") + .options() + .let { optionBuilder -> + optionBuilder.option("Ask about Desert Treasure") + .playerl("As I understand it there's some kind of hidden treasure in these parts...") + .npcl("Look around @g[pal,lady]. Does it looks like there's any treasure near here?") + .npcl("If I were you I'd get lost before someone takes a dislike to your face and removes it for you.") + .end() + optionBuilder.option("Buy a drink") + .branch { player -> + return@branch if (inInventory(player, Items.COINS_995, 650)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(1) + .npcl("What's that? You wanna buy a beer? It'll cost ya 650 coins.") + .options() + .let { optionBuilder -> + optionBuilder.option("Buy a beer") + .betweenStage { _, player, _, _ -> + if (removeItem(player, Item(Items.COINS_995, 650))) { + addItemOrDrop(player, Items.BANDITS_BREW_4627) + setAttribute(player, DesertTreasure.attributeBoughtBeer, true) + } + } + .npcl("There you go. Now get out, we don't like your sort around here.") + .end() + optionBuilder.option("Don't buy anything") + .npcl("Get out of my bar then! We don't like your sort round here!") + .end() + } + + branch.onValue(0) + .npcl("You ain't got the 650 coins it costs to buy it, and I'm glad 'cos I didn't want to serve you anyway.") + .end() + } + + } + } + + + b.onQuestStages(DesertTreasure.questName, 6,7,8,9,10,11) + .branch { player -> + return@branch if (getAttribute(player, DesertTreasure.attributeBoughtBeer, false)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(1) + .npcl("You've had your drink, now get out of here. I have nothing to say to the-") + .playerl("No, Wait! Look, I'm here on an archaeological expedition for the Museum of Varrock.") + .playerl("I am only here looking for artefacts...") + .npcl("Oh really? Our inheritance is only sand and death. What do you expect to find out here in this desert forsaken by the gods?") + .options() + .let { optionBuilder -> + optionBuilder.option("I heard about treasure...") + .playerl("As I understand it there's some kind of hidden treasure in these parts...") + .npcl("Look around @g[pal,lady]. Does it looks like there's any treasure near here?") + .npcl("If I were you I'd get lost before someone takes a dislike to your face and removes it for you.") + .end() + + optionBuilder.option("I heard about four diamonds...") + .playerl("I heard a rumour about four diamonds or crystals...") + .npcl("The four diamonds of Azzanadra??? How came you to know of this?") + .playerl("You've heard of them then?") + .npcl("It's just a fairy tale for children. Maybe one of the village elders might know more, but it's not really something I care about.") + .npcl("Now get out of here, your sort isn't welcome in my bar.") + .end() + + optionBuilder.option("I heard about a fortress...") + .playerl("Certain things have led me to believe there may be some kind of ruined fortress around here...") + .npcl("Doubt it. What in the world would someone need to guard against in the middle of this desert?") + .npcl("A bad attack of sand? I think you're on the wrong track, mister so-called archaeologist.") + .end() + + optionBuilder.option("I heard of the Diamonds of Azzanadra.") + .playerl("Tell me all you know about the Diamonds of Azzanadra.") + .npcl("Not that I think it's any of your business, but when I was a child I remember hearing the legend.") + .npcl("I don't recall it particularly well, other than they are said to contain an incredible power.") + .npcl("If you really want to hear more about it you'd be best off finding someone who cares about the past, and the history of this area, and stop bothering me.") + .end() + } + } + + b.onQuestStages(DesertTreasure.questName, 100) + .npcl("So you're the @g[fella,lass] that freed Azzanadra, huh? Fair play to ya. What will you have?") + .end() + + } +} diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/DamisBehavior.kt b/Server/src/main/content/region/desert/quest/deserttreasure/DamisBehavior.kt new file mode 100644 index 0000000..c8b9af6 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/DamisBehavior.kt @@ -0,0 +1,81 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.interaction.QueueStrength +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class DamisBehavior : NPCBehavior(NPCs.DAMIS_1974, NPCs.DAMIS_1975) { + + var clearTime = 0 + + override fun canBeAttackedBy(self: NPC, attacker: Entity, style: CombatStyle, shouldSendMessage: Boolean): Boolean { + if (attacker is Player) { + if (attacker == getAttribute(self, "target", null)) { + return true + } + sendMessage(attacker, "It's not after you...") + } + return false + } + + override fun tick(self: NPC): Boolean { + val player: Player? = getAttribute(self, "target", null) + if (clearTime++ > 800) { + clearTime = 0 + if (player != null) { + sendMessage(player, "Damis has vanished once more into the shadows...") + removeAttribute(player, DesertTreasure.attributeDamisInstance) + } + poofClear(self) + } + return true + } + + override fun beforeDamageReceived(self: NPC, attacker: Entity, state: BattleState) { + if (attacker is Player) { + if (state.estimatedHit + Integer.max(state.secondaryHit, 0) >= self.skills.lifepoints && self.id == NPCs.DAMIS_1974) { + state.estimatedHit = self.skills.lifepoints + 1 + state.secondaryHit = -1 + + transformNpc(self, NPCs.DAMIS_1975, 500) + self.skills.lifepoints = self.skills.maximumLifepoints + sendChat(self, "Armour... is for restraint, not... protection...") + queueScript(self, 2, QueueStrength.NORMAL) { stage: Int -> + sendChat(self, "Now I show... you... my true power!") + self.properties.attackSpeed = 3 + return@queueScript stopExecuting(self) + } + } + } + } + + override fun beforeAttackFinalized(self: NPC, victim: Entity, state: BattleState) { + // In second form, drain prayer by 5. + if (self.id == NPCs.DAMIS_1975) { + victim.skills.decrementPrayerPoints(5.0) + } + } + + + + override fun onDeathFinished(self: NPC, killer: Entity) { + if (killer is Player) { + if (self.id == NPCs.DAMIS_1975) { + if (DesertTreasure.getSubStage(killer, DesertTreasure.attributeShadowStage) == 3) { + GroundItemManager.create(Item(Items.SHADOW_DIAMOND_4673), self.location, killer) + DesertTreasure.setSubStage(killer, DesertTreasure.attributeShadowStage, 100) + removeAttribute(killer, DesertTreasure.attributeFareedInstance) + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/DesertTreasure.kt b/Server/src/main/content/region/desert/quest/deserttreasure/DesertTreasure.kt new file mode 100644 index 0000000..f23f6e0 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/DesertTreasure.kt @@ -0,0 +1,544 @@ +package content.region.desert.quest.deserttreasure + +import content.data.Quests +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import org.rs09.consts.Items + +/** + * Desert Treasure Quest + * + * https://www.youtube.com/watch?v=INaSdOAHdT8: Jesus fucking devil best shit on planet fuckall 31:57 + * https://www.youtube.com/watch?v=LAoOISdsX4w: This guy did the best initial quest journal and then ignored the rest. + * https://www.youtube.com/watch?v=3cyU36qNBpI: one impt quest log part in the front. + * https://www.youtube.com/watch?v=pY-Czja2lE4: Good shit part 2 6:24 + * https://www.youtube.com/watch?v=NB1-m_hoTPk: Blur ass quest log. + * https://www.youtube.com/watch?v=bcy54b6NnJs: Blur ass quest log. + * https://www.youtube.com/watch?v=J_dfMXFz3WQ: Blur ass quest log. + * https://www.youtube.com/watch?v=7n0OcHUNFHc: Blur ass quest log 1:07. + * https://www.youtube.com/@Gunz4Range/videos + * https://www.youtube.com/watch?v=baQ6oJOk7Gc + * https://www.youtube.com/watch?v=u0C2zW6mrcc: Blur ass ending quest log 3:23 + * https://www.youtube.com/watch?v=SUzM0WKY6jk: 1:03 + * https://www.youtube.com/watch?v=3AA5fkkBW-I: 2:05 + * + * https://www.youtube.com/watch?v=ofRV2-h3Dug: 17:21 27:45 + * + * if (VARPBIT[358] == 15) return 2; if (VARPBIT[358] == 0) return 0; return 1; }; if (arg0 == 13) + */ +@Initializable +class DesertTreasure : Quest(Quests.DESERT_TREASURE,45, 44, 3, 440, 358, 0, 1, 15){ + + companion object { + val questName = Quests.DESERT_TREASURE + /** This is an important varbit as it is literally controlling the Quest varbit (440 Varp 0-14 bits -> 358 Varbit )*/ + const val varbitDesertTreasure = 358 // 10-15-Eblis 1924 shows up other values Eblis disappears. This is tied to the quest. + + // Desert Treasure Start + const val attributeBoughtBeer = "/save:quest:deserttreasure-boughtbeer" + const val attributeCountMagicLogs = "/save:quest:deserttreasure-countmagiclogs" + const val attributeCountSteelBars = "/save:quest:deserttreasure-countsteelbars" + const val attributeCountMoltenGlass = "/save:quest:deserttreasure-countmoltenglass" + const val attributeCountBones = "/save:quest:deserttreasure-countbones" + const val attributeCountAshes = "/save:quest:deserttreasure-countashes" + const val attributeCountCharcoal = "/save:quest:deserttreasure-countcharocal" + const val attributeCountBloodRune = "/save:quest:deserttreasure-countbloodrune" + const val varbitMirrors = 392 // Set to 1 to show mirrors, they are cactuses before desert treasure. + + // Blood Diamond + const val attributeBloodStage = "/save:quest:deserttreasure-bloodstage" + const val attributeDessousInstance = "quest:deserttreasure-dessousinstance" + + // Smoke Diamond + const val attributeSmokeStage = "/save:quest:deserttreasure-smokestage" + const val attributeUnlockedGate = "/save:quest:deserttreasure-unlockedgate" + const val attributeFareedInstance = "quest:deserttreasure-fareedinstance" + const val varbitStandingTorchNorthEast = 360 // North East standing torch 6406 + const val varbitStandingTorchSouthEast = 361 // South East standing torch 6408 + const val varbitStandingTorchSouthWest = 362 // South West standing torch 6410 + const val varbitStandingTorchNorthWest = 363 // North West standing torch 6412 + + // Ice Diamond + const val attributeIceStage = "/save:quest:deserttreasure-icestage" + const val attributeTrollKillCount = "/save:quest:deserttreasure-iciclecount" + const val attributeKamilInstance = "quest:deserttreasure-kamilinstance" + const val varbitFrozenFather = 380 // 0-frozen 1-defrosted | Base: 1943 Iced: 1944 Broke: 1948 Reunion: 1947 + const val varbitFrozenMother = 381 // 0-frozen 1-defrosted | Base: 1945 Iced: 1946 Broke: 1950 Reunion: 1949 + const val varbitChildReunite = 382 // 0-frozen 4-reunited 5-reunited 6-varbitfails/ends (This varbit seems to manage ice stages...) + // 0 - start, 1 - feed the crying child, 2 - fought kamil, 3 - unfreeze dad/mum, 4 - reunite, 5 - all chat complete. + const val varbitCaveEntrance = 378 // 6446 0 - 6 6441 + + // Shadow Diamond + const val attributeShadowStage = "/save:quest:deserttreasure-shadowstage" + const val attributeDamisWarning = "quest:deserttreasure-damiswarning" + const val attributeDamisInstance = "quest:deserttreasure-damisinstance" + const val varbitRingOfVisibility = 393 // Set to 1 to show ladder and other cool stuff when wearing ring of visibility. + + // Desert Treasure End + const val attributeBloodDiamondInserted = "/save:quest:deserttreasure-blooddiamondinserted" + const val attributeSmokeDiamondInserted = "/save:quest:deserttreasure-smokediamondinserted" + const val attributeIceDiamondInserted = "/save:quest:deserttreasure-icediamondinserted" + const val attributeShadowDiamondInserted = "/save:quest:deserttreasure-shadowdiamondinserted" + const val varbitBloodObelisk = 390 + const val varbitSmokeObelisk = 387 + const val varbitIceObelisk = 389 + const val varbitShadowObelisk = 388 + + fun completedAllSubstages(player: Player): Boolean { + return getSubStage(player, attributeBloodStage) == 100 && + getSubStage(player, attributeSmokeStage) == 100 && + getSubStage(player, attributeIceStage) == 100 && + getSubStage(player, attributeShadowStage) == 100 + } + + fun getSubStage(player: Player, attributeName: String): Int { + return getAttribute(player, attributeName, 0) + } + + fun setSubStage(player: Player, attributeName: String, value: Int) { + return setAttribute(player, attributeName, value) + } + + fun hasRequirements(player: Player): Boolean { + return arrayOf( + hasLevelStat(player, Skills.SLAYER, 10), + hasLevelStat(player, Skills.FIREMAKING, 50), + hasLevelStat(player, Skills.MAGIC, 50), + hasLevelStat(player, Skills.THIEVING, 53), + isQuestComplete(player, Quests.THE_DIG_SITE), + isQuestComplete(player, Quests.THE_TOURIST_TRAP), + isQuestComplete(player, Quests.TEMPLE_OF_IKOV), + isQuestComplete(player, Quests.PRIEST_IN_PERIL), + isQuestComplete(player, Quests.WATERFALL_QUEST), + isQuestComplete(player, Quests.TROLL_STRONGHOLD), + ).all { it } + } + } + + override fun drawJournal(player: Player, stage: Int) { + super.drawJournal(player, stage) + var line = 12 + var stage = getStage(player) + + var started = getQuestStage(player, questName) > 0 + + if(!started){ + line(player,"I can start this quest by speaking to !!The Archaeologist??", line++) + line(player,"who is exploring the !!Bedabin Camp?? South West of the", line++) + line(player,"!!Shantay Pass??.", line++) + line(player,"To complete this quest I will need:", line++) + line(player, "Level 10 Slayer", line++, hasLevelStat(player, Skills.SLAYER, 10)) + line(player, "Level 50 Firemaking", line++, hasLevelStat(player, Skills.FIREMAKING, 50)) + line(player, "Level 50 Magic", line++, hasLevelStat(player, Skills.MAGIC, 50)) + line(player, "Level 53 Thieving", line++, hasLevelStat(player, Skills.THIEVING, 53)) + line(player,"I must have completed the following quests:", line++) // After - I have completed all of the required quests: + line(player, "The Digsite Quest", line++, isQuestComplete(player, Quests.THE_DIG_SITE)) + line(player, "The Tourist Trap", line++, isQuestComplete(player, Quests.THE_TOURIST_TRAP)) + line(player, "The Temple of Ikov", line++, isQuestComplete(player, Quests.TEMPLE_OF_IKOV)) + line(player, "Priest In Peril", line++, isQuestComplete(player, Quests.PRIEST_IN_PERIL)) + line(player, "Waterfall Quest", line++, isQuestComplete(player, Quests.WATERFALL_QUEST)) + line(player, "Troll Stronghold", line++, isQuestComplete(player, Quests.TROLL_STRONGHOLD)) + } else { + + if (stage >= 2) { + line(player, "I took some etchings of a stone tablet discovered by the", line++, true) + line(player, "archaeologist in the desert to Terry Balando at the", line++, true) + line(player, "Varrock digsite.", line++, true) + } else if (stage >= 1) { + line(player, "The !!archaeologist?? has given me some !!etchings from a??", line++, false) + line(player, "!!stone tablet?? that he discovered in the desert somewhere,", line++, false) + line(player, "and asked me to take it to an archaeological expert called", line++, false) + line(player, "!!Terry Balando?? at the Varrock !!digsite??.", line++, false) + } + + if (stage >= 4) { + line(player, "He made a rough translation, which I returned to the", line++, true) + line(player, "archaeologist.", line++, true) + } else if (stage == 3) { + line(player, "Terry Balando made some quick !!translation notes?? of the", line++, false) + line(player, "tablet and asked me to return them to the !!archaeologist?? in", line++, false) + line(player, "the !!Bedabin Camp??.", line++, false) + } else if (stage == 2) { + line(player, "I should get the !!translation notes?? from !!Terry Balando??", line++, false) + } + + if(stage >= 5) { + line(player, "The archaeologist I met in the desert seemed to think that", line++, true) + line(player, "there was some hidden treasure in the desert somewhere,", line++, true) + line(player, "I agreed to help him find it in return for a fifty percent", line++, true) + line(player, "share of whatever we found.", line++, true) + } else if (stage == 4) { + line(player, "I should find out what the !!archaeologist?? has to say about", line++, false) + line(player, "the !!translation notes??.", line++, false) + } + + if (stage >= 6) { + line(player, "I headed South and found a Bandit Camp.", line++, true) + } else if (stage >= 5) { + line(player, "I should head South to the !!Bandit Camp?? and try to find out", line++, false) + line(player, "more about this !!treasure??.", line++, false) + } + + if (stage >= 7) { + line(player, "I asked around the Bandit Camp and discovered someone", line++, true) + line(player, "who was willing to help me find the diamonds, by using a", line++, true) + line(player, "magic spell and some scrying glasses.", line++, true) + } else if (stage >= 6) { + line(player, "After some searching, the barman let slip some", line++, true) + line(player, "information about the 'Four Diamonds of Azzanadra'.", line++, true) + line(player, "I should ask around the !!Bandit Camp?? and see if anyone", line++, false) + line(player, "else has any information about the !!Four Diamonds of??", line++, false) + line(player, "!!Azzanadra??", line++, false) + } + + if (stage >= 10 || (stage >= 9 && completedAllSubstages(player))) { + // This disappears after you find all the diamonds. + } else if (stage >= 8) { + line(player, "I brought Eblis the ingredients so that he could cast the", line++, true) + line(player, "spell to see the places touched by the magic of the", line++, true) + line(player, "diamonds.", line++, true) + } else if (stage >= 7) { + // Crosses out gradually as you SUBMIT them. + line(player, "To make the scrying glasses I need to bring the following", line++, false) + // Crosses out with "I have brought him all xxx(6 Steel bars)" + line(player, "items to Eblis:", line++, false) + line(player, "!!12 Magic logs??", line++, false) + line(player, "!!6 Steel bars??", line++, false) + line(player, "!!6 Molten glass??", line++, false) + line(player, "To cast the spell I will need to bring Eblis:", line++, false) + // Crosses out with "I have brought him xxx(some bones)" + line(player, "!!Some bones??", line++, false) + line(player, "!!Some ash??", line++, false) + line(player, "!!Some charcoal??", line++, false) + line(player, "!!A blood rune??", line++, false) + } + + if (stage >= 10 || (stage >= 9 && completedAllSubstages(player))) { + // This disappears after you find all the diamonds. + } else if (stage >= 9 && !completedAllSubstages(player)) { + // This was supposed to disappear... youtu.be/J4cQMY66MI4 is old but disagrees + line(player, "I headed East into the desert and used the scrying", line++, true) + line(player, "glasses set up for me there by Eblis to try and find the", line++, true) + line(player, "Four Diamonds of Azzanadra.", line++, true) + line++ + } else if (stage >= 8) { + line(player, "I should head !!East into the desert?? and meet Eblis where he", line++, false) + line(player, "has set up the scrying glasses, and use them to try and", line++, false) + line(player, "track down the !!Four Diamonds of Azzanadra??.", line++, false) + line++ + } + + + // The huge one with sub quests. + if (stage >= 9 && completedAllSubstages(player)) { + line(player, "I found all four diamonds using this spell.", line++, true) + } else if (stage == 9) { + line++ + // DIAMOND OF BLOOD (DESSOUS) + // Dessous returns to his grave, bored of toying with you. // https://youtu.be/7CvfS7pypso + if (getSubStage(player, attributeBloodStage) == 100) { + line(player, "I defeated a vampire named Dessous to claim the Diamond", line++, true) + line(player, "of Blood.", line++, true) + } else if (getSubStage(player, attributeBloodStage) >= 1) { + // ZSOCwWEwimM 4:25 helped the first line. + line(player, "I discovered that the location of the Diamond of Blood was", line++, true) + line(player, "somewhere in Morytania, and in the possession of a", line++, true) + line(player, "vampire warrior named Dessous.", line++, true) + + if (getSubStage(player, attributeBloodStage) >= 3) { + line(player, "I don't fully trust Malek, but he has agreed to help me kill", line++, true) + line(player, "Dessous.", line++, true) + + line(player, "I made a special blessed pot, filled with blood, garlic and", line++, true) + line(player, "spices, which I used to lure Dessous from his tomb.", line++, true) + line(player, "I managed to defeat the vampire warrior Dessous, but", line++, true) + line(player, "there was no sign of the Diamond of Blood anywhere.", line++, true) + line(player, "I should find out what game !!Malek?? has been playing with", line++, false) + line(player, "me, and where I can actually find the !!Diamond of Blood??.", line++, false) + } else if (getSubStage(player, attributeBloodStage) >= 2) { + line(player, "I don't fully trust Malek, but he has agreed to help me kill", line++, true) + line(player, "Dessous.", line++, true) + + // None of these lines cross out when you do it. So it remains like this. + line(player, "Apparently I can find an old !!assistant of Count Draynor?? in", line++, false) + line(player, "the !!sewers of Draynor Village??, who will be able to help me", line++, false) + line(player, "make a !!sacrificial pot??", line++, false) + line(player, "I then need to take that !!sacrificial pot?? to !!Entrana?? and get", line++, false) + line(player, "it blessed by the !!head priest??", line++, false) + line(player, "When I have done that, I should return to !!Malak??, and he will", line++, false) + line(player, "provide me with some !!fresh blood??", line++, false) + line(player, "I then need to add !!garlic?? and !!spices?? to the pot in order to", line++, false) + line(player, "lure Dessous from his tomb.", line++, false) + line(player, "When I have done all of this, I must !!kill Dessous!??", line++, false) + } else if (getSubStage(player, attributeBloodStage) >= 1) { + line(player, "I should speak to !!Malek?? again and find out how exactly I", line++, false) + line(player, "can kill !!Dessous??.", line++, false) // This doesn't stay + } + } else if (getSubStage(player, attributeBloodStage) == 0) { + line(player, "I can use the !!scrying glasses?? to help find the", line++, false) + line(player, "!!Diamond of Blood??.", line++, false) + } + + line++ + // DIAMOND OF SMOKE (FAREED) + // Fareed has lost interest in you, and returned to his flames. + if (getSubStage(player, attributeSmokeStage) == 100) { + line(player, "I defeated a fire warrior, and now have the Diamond of", line++, true) + line(player, "Smoke.", line++, true) + } else if (getSubStage(player, attributeSmokeStage) >= 1) { + line(player, "I entered a smokey well and lit up the path. I found a", line++, true) // Derived. + line(player, "key in a chest.", line++, true) // Derived. + line(player, "I should find out what the !!key?? unlocks.", line++, false) // Derived. + } else if (getSubStage(player, attributeSmokeStage) == 0) { + // This doesn't change to stage 1 even when you are lighting the fires... + line(player, "I can use the !!scrying glasses?? to help find the", line++, false) + line(player, "!!Diamond of Smoke??.", line++, false) + } + + line++ + // DIAMOND OF ICE (KAMIL) + // Kamil vanishes on an icy wind... + if (getSubStage(player, attributeIceStage) == 100) { + line(player, "I defeated a warrior named Kamil, and now have the", line++, true) + line(player, "Diamond of Ice.", line++, true) + } else if (getSubStage(player, attributeIceStage) >= 1) { + // https://www.youtube.com/watch?v=F5F6Ds-T1P8 28:52 + line(player, "I met a crying ice troll child to the North of Trollheim.", line++, true) + if (getSubStage(player, attributeIceStage) >= 3) { + line(player, "I managed to cheer him up slightly with a sweet treat.", line++, true) + line(player, "After speaking with him, I discovered that his parents had", line++, true) + line(player, "been hurt by a 'bad man' who had the Diamond of Ice, and I", line++, true) + line(player, "agreed to help him rescue them.", line++, true) + line(player, "While heading through the icy area, I was attacked by an", line++, true) + line(player, "ice warrior named Kamil, and managed to defeat him.", line++, true) + line(player, "Was this the 'bad man' the troll child has spoken of?", line++, true) + line(player, "I should head further into the icy area to try and find", line++, false) + line(player, "them.", line++, false) + } else if (getSubStage(player, attributeIceStage) >= 2) { + line(player, "I managed to cheer him up slightly with a sweet treat.", line++, true) + line(player, "After speaking with him, I discovered that his parents had", line++, true) + line(player, "been hurt by a 'bad man' who had the Diamond of Ice, and I", line++, true) + line(player, "agreed to help him rescue them.", line++, true) + line(player, "I should head further into the icy area to try and find", line++, false) + line(player, "them.", line++, false) + } else if (getSubStage(player, attributeIceStage) >= 1) { + line(player, "I should cheer him up with something sweet.", line++, false) // Derived + } + } else if (getSubStage(player, attributeIceStage) == 0) { + line(player, "I can use the !!scrying glasses?? to help find the", line++, false) + line(player, "!!Diamond of Ice??.", line++, false) + } + + line++ + // DIAMOND OF SHADOW (DAMIS) + // Damis has vanished once more into the shadows... + if (getSubStage(player, attributeShadowStage) == 100) { + line(player, "I defeated a warrior named Damis, and now have the", line++, true) + line(player, "Diamond of Shadow.", line++, true) + } else if (getSubStage(player, attributeShadowStage) >= 1) { + line(player, "A travelling merchant named Rasolo had some information", line++, true) + line(player, "about the Diamond of Shadow.", line++, true) + line(player, "Apparently it was owned by an invisible warrior, who I", line++, true) + line(player, "needed a special ring to see.", line++, true) + line(player, "Rasolo owned such a ring, but would only trade it in return", line++, true) + line(player, "for a gilded cross stolen from him by a bandit named.", line++, true) + line(player, "Laheeb.", line++, true) + if (getSubStage(player, attributeShadowStage) >= 3) { + line(player, "I found Laheeb's treasure chest, and managed to bypass", line++, true) + line(player, "the traps on it to take the gilded cross, which I returned to", line++, true) + line(player, "Rasolo.", line++, true) + line(player, "In return, he gave me the Ring of Visibility.", line++, true) + line(player, "I should put the !!Ring of Visibility?? on and try and find the", line++, false) + line(player, "hidden home of !!Damis?? - Rasolo suggested it was very", line++, false) + line(player, "close by to where he is...", line++, false) + } else if (getSubStage(player, attributeShadowStage) >= 2) { + line(player, "I found Laheeb's treasure chest, and managed to bypass", line++, true) + line(player, "the traps on it to take the gilded cross.", line++, true) + line(player, "I need to return the !!gilded cross?? to !!Rasolo??.", line++, false) // Derived + } else if (getSubStage(player, attributeShadowStage) >= 1) { + line(player, "I need to find !!Laheeb's loot?? and retrieve the stolen !!gilded??", line++, false) + line(player, "!!cross??.", line++, false) + } + } else if (getSubStage(player, attributeShadowStage) == 0) { + line(player, "I can use the !!scrying glasses?? to help find the", line++, false) + line(player, "!!Diamond of Shadow??.", line++, false) + } + } + + // If you hold a diamond too long a stranger will try to kill you. + // https://oldschool.runescape.wiki/w/Transcript:Stranger + // After defeating the stranger + // player(THINKING, "I wonder what that was all about?") + + // After all 4 diamonds + // Player dialogue("I should make sure I have all four diamonds with me", "before speaking to Eblis again.") + + if (stage >= 10) { + // This disappears after you place all the diamonds. + } else if (stage >= 9 && completedAllSubstages(player)) { + line(player, "Now that I have recovered all of the !!Diamonds of??", line++, false) + line(player, "!!Azzanadra?? I should take them all to !!Eblis?? and find out what.", line++, false) + line(player, "is so special about them.", line++, false) + // This is the current message even AFTER you speak to Eblis... baQ6oJOk7Gc + } + + if (stage >= 11) { + // This disappears at the end of this quest. + } else if (stage >= 10) { + line(player, "I should explore the !!pyramid?? and see what !!treasure?? awaits", line++, false) + line(player, "me!", line++, false) + } + + if (stage >= 100) { + line(player, "At the heart of the pyramid I found a strange being, who", line++, true) + line(player, "gave me some powerful new magic spells.", line++, true) + line(player, "I can switch between my old spells and my new spells any", line++, true) + line(player, "time by using the altar there, and can avoid the traps by", line++, true) + line(player, "using the secret passage.", line++, true) + line++ + line++ + line(player,"QUEST COMPLETE!", line) + } + } + } + + override fun reset(player: Player) { + setVarbit(player, varbitChildReunite, 0, true) + + removeAttribute(player, attributeBoughtBeer) + removeAttribute(player, attributeCountMagicLogs) + removeAttribute(player, attributeCountSteelBars) + removeAttribute(player, attributeCountMoltenGlass) + removeAttribute(player, attributeCountBones) + removeAttribute(player, attributeCountAshes) + removeAttribute(player, attributeCountCharcoal) + removeAttribute(player, attributeCountBloodRune) + setVarbit(player, varbitMirrors, 0, true) + + removeAttribute(player, attributeBloodStage) + removeAttribute(player, attributeDessousInstance) + + removeAttribute(player, attributeSmokeStage) + removeAttribute(player, attributeFareedInstance) + removeAttribute(player, attributeUnlockedGate) + setVarbit(player, varbitStandingTorchNorthEast, 0, true) + setVarbit(player, varbitStandingTorchSouthEast, 0, true) + setVarbit(player, varbitStandingTorchSouthWest, 0, true) + setVarbit(player, varbitStandingTorchNorthWest, 0, true) + + removeAttribute(player, attributeIceStage) + removeAttribute(player, attributeKamilInstance) + removeAttribute(player, attributeTrollKillCount) + setVarbit(player, varbitFrozenFather, 0, true) // 0-frozen 1-defrosted + setVarbit(player, varbitFrozenMother, 0, true) // 0-frozen 1-defrosted + setVarbit(player, varbitChildReunite, 0, true) // 0-frozen 4-reunited 5-reunited 6-varbitfails/ends (This varbit seems to manage ice stages...) + setVarbit(player, varbitCaveEntrance, 0, true) // 6446 0 - 6 6441 + + removeAttribute(player, attributeShadowStage) + removeAttribute(player, attributeDamisInstance) + removeAttribute(player, attributeDamisWarning) + setVarbit(player, varbitRingOfVisibility, 0, true) // Set to 1 to show ladder when wearing ring of visibility. + + removeAttribute(player, attributeBloodDiamondInserted) + removeAttribute(player, attributeSmokeDiamondInserted) + removeAttribute(player, attributeIceDiamondInserted) + removeAttribute(player, attributeShadowDiamondInserted) + setVarbit(player, varbitBloodObelisk, 0, true) + setVarbit(player, varbitSmokeObelisk, 0, true) + setVarbit(player, varbitIceObelisk, 0, true) + setVarbit(player, varbitShadowObelisk, 0, true) + } + + + override fun finish(player: Player) { + var ln = 10 + super.finish(player) + player.packetDispatch.sendString("You have completed the Desert Treasure Quest!", 277, 4) + player.packetDispatch.sendItemZoomOnInterface(Items.ANCIENT_STAFF_4675, 240, 277, 5) + + drawReward(player,"3 Quest Points", ln++) + drawReward(player,"20,000 Magic XP", ln++) + drawReward(player,"Ancient Magicks", ln) + + player.skills.addExperience(Skills.MAGIC, 20000.0) + } + + override fun setStage(player: Player, stage: Int) { + super.setStage(player, stage) + this.updateVarps(player) + } + + override fun updateVarps(player: Player) { + + // Ice: Cave Entrance Varbit + setVarbit(player, varbitCaveEntrance, getAttribute(player,attributeTrollKillCount, 0)) + + // Shadow: Ring of Visibility Ladder Varbit + if (inEquipment(player, Items.RING_OF_VISIBILITY_4657)) { + setVarbit(player, varbitRingOfVisibility, 1) + } else { + setVarbit(player, varbitRingOfVisibility, 0) + } + + // Obelisks Varbits + if (getAttribute(player, attributeBloodDiamondInserted, 0) == 1) { + setVarbit(player, varbitBloodObelisk, 1) + } else { + setVarbit(player, varbitBloodObelisk, 0) + } + + if (getAttribute(player, attributeSmokeDiamondInserted, 0) == 1) { + setVarbit(player, varbitSmokeObelisk, 1) + } else { + setVarbit(player, varbitSmokeObelisk, 0) + } + + if (getAttribute(player, attributeIceDiamondInserted, 0) == 1) { + setVarbit(player, varbitIceObelisk, 1) + } else { + setVarbit(player, varbitIceObelisk, 0) + } + + if (getAttribute(player, attributeShadowDiamondInserted, 0) == 1) { + setVarbit(player, varbitShadowObelisk, 1) + } else { + setVarbit(player, varbitShadowObelisk, 0) + } + + // Special Varbit for Ice Stage + if (getAttribute(player, attributeIceStage, 0) > 5) { + setVarbit(player, varbitChildReunite, 5) + } else { + setVarbit(player, varbitChildReunite, 0) + } + + // Stage Varbits + if(getQuestStage(player, questName) == 0) { + setVarbit(player, varbitDesertTreasure, 0, true) + setVarbit(player, varbitMirrors, 0, true) + } + if(getQuestStage(player, questName) in 1..7) { + setVarbit(player, varbitDesertTreasure, 1, true) + setVarbit(player, varbitMirrors, 0, true) + } + if(getQuestStage(player, questName) in 8..9) { + setVarbit(player, varbitDesertTreasure, 10, true) + setVarbit(player, varbitMirrors, 1, true) + } + if(getQuestStage(player, questName) == 10) { + setVarbit(player, varbitDesertTreasure, 13, true) + setVarbit(player, varbitMirrors, 1, true) + } + if(getQuestStage(player, questName) >= 100) { + setVarbit(player, varbitDesertTreasure, 15, true) + setVarbit(player, varbitMirrors, 1, true) + } + } + + override fun newInstance(`object`: Any?): Quest { + return this + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/DesertTreasureListeners.kt b/Server/src/main/content/region/desert/quest/deserttreasure/DesertTreasureListeners.kt new file mode 100644 index 0000000..3115efd --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/DesertTreasureListeners.kt @@ -0,0 +1,464 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.activity.Cutscene +import core.game.global.action.DoorActionHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.world.map.Location +import org.rs09.consts.Items +import org.rs09.consts.Scenery + +class DesertTreasureListeners : InteractionListener { + + companion object { + fun allDiamondsInserted(player: Player): Boolean{ + return getAttribute(player, DesertTreasure.attributeBloodDiamondInserted, 0) == 1 && + getAttribute(player, DesertTreasure.attributeSmokeDiamondInserted, 0) == 1 && + getAttribute(player, DesertTreasure.attributeIceDiamondInserted, 0) == 1 && + getAttribute(player, DesertTreasure.attributeShadowDiamondInserted, 0) == 1 + } + } + var temp = 6517 + + override fun defineListeners() { + + // THE MIRRORS + on(Scenery.MYSTICAL_MIRROR_6423, SCENERY, "look-into") { player, node -> + SouthMirrorLookCutscene(player).start() + return@on true + } + on(Scenery.MYSTICAL_MIRROR_6425, SCENERY, "look-into") { player, node -> + SouthWestMirrorLookCutscene(player).start() + return@on true + } + on(Scenery.MYSTICAL_MIRROR_6427, SCENERY, "look-into") { player, node -> + NorthWestMirrorLookCutscene(player).start() + return@on true + } + on(Scenery.MYSTICAL_MIRROR_6429, SCENERY, "look-into") { player, node -> + NorthMirrorLookCutscene(player).start() + return@on true + } + on(Scenery.MYSTICAL_MIRROR_6431, SCENERY, "look-into") { player, node -> + NorthEastMirrorLookCutscene(player).start() + return@on true + } + on(Scenery.MYSTICAL_MIRROR_6433, SCENERY, "look-into") { player, node -> + SouthEastMirrorLookCutscene(player).start() + return@on true + } + + + // THE OBELISKS + onUseWith(IntType.SCENERY, intArrayOf(Items.ICE_DIAMOND_4671, Items.SMOKE_DIAMOND_4672, Items.SHADOW_DIAMOND_4673), Scenery.OBELISK_6483) { player, used, with -> + sendMessage(player, "That doesn't appear to be the correct diamond...") + return@onUseWith true + } + onUseWith(IntType.SCENERY, Items.BLOOD_DIAMOND_4670, Scenery.OBELISK_6483) { player, used, with -> + if (getDynLevel(player, Skills.MAGIC) > 50) { + if (removeItem(player, used)) { + sendMessage(player, "The diamond is absorbed into the pillar.") + setVarbit(player, DesertTreasure.varbitBloodObelisk, 1) + setAttribute(player, DesertTreasure.attributeBloodDiamondInserted, 1) + if (allDiamondsInserted(player)) { + sendMessage(player, "The force preventing access to the Pyramid has now vanished.") + if (getQuestStage(player, DesertTreasure.questName) == 9) { + setQuestStage(player, DesertTreasure.questName, 10) + } + } + } + } else { + sendMessage(player, "You are not a powerful enough mage to breach the protective aura.") + sendMessage(player, "You need a magic level of at least 50 to enter the Pyramid.") + } + return@onUseWith true + } + onUseWith(IntType.SCENERY, intArrayOf(Items.BLOOD_DIAMOND_4670, Items.ICE_DIAMOND_4671, Items.SHADOW_DIAMOND_4673), Scenery.OBELISK_6486) { player, used, with -> + sendMessage(player, "That doesn't appear to be the correct diamond...") + return@onUseWith true + } + onUseWith(IntType.SCENERY, Items.SMOKE_DIAMOND_4672, Scenery.OBELISK_6486) { player, used, with -> + if (getDynLevel(player, Skills.MAGIC) > 50) { + if (removeItem(player, used)) { + sendMessage(player, "The diamond is absorbed into the pillar.") + setVarbit(player, DesertTreasure.varbitSmokeObelisk, 1) + setAttribute(player, DesertTreasure.attributeSmokeDiamondInserted, 1) + if (allDiamondsInserted(player)) { + sendMessage(player, "The force preventing access to the Pyramid has now vanished.") + if (getQuestStage(player, DesertTreasure.questName) == 9) { + setQuestStage(player, DesertTreasure.questName, 10) + } + } + } + } else { + sendMessage(player, "You are not a powerful enough mage to breach the protective aura.") + sendMessage(player, "You need a magic level of at least 50 to enter the Pyramid.") + } + return@onUseWith true + } + onUseWith(IntType.SCENERY, intArrayOf(Items.BLOOD_DIAMOND_4670, Items.SMOKE_DIAMOND_4672, Items.SHADOW_DIAMOND_4673), Scenery.OBELISK_6489) { player, used, with -> + sendMessage(player, "That doesn't appear to be the correct diamond...") + return@onUseWith true + } + onUseWith(IntType.SCENERY, Items.ICE_DIAMOND_4671, Scenery.OBELISK_6489) { player, used, with -> + if (getDynLevel(player, Skills.MAGIC) > 50) { + if (removeItem(player, used)) { + sendMessage(player, "The diamond is absorbed into the pillar.") + setVarbit(player, DesertTreasure.varbitIceObelisk, 1) + setAttribute(player, DesertTreasure.attributeIceDiamondInserted, 1) + if (allDiamondsInserted(player)) { + sendMessage(player, "The force preventing access to the Pyramid has now vanished.") + if (getQuestStage(player, DesertTreasure.questName) == 9) { + setQuestStage(player, DesertTreasure.questName, 10) + } + } + } + } else { + sendMessage(player, "You are not a powerful enough mage to breach the protective aura.") + sendMessage(player, "You need a magic level of at least 50 to enter the Pyramid.") + } + return@onUseWith true + } + onUseWith(IntType.SCENERY, intArrayOf(Items.BLOOD_DIAMOND_4670, Items.ICE_DIAMOND_4671, Items.SMOKE_DIAMOND_4672), Scenery.OBELISK_6492) { player, used, with -> + sendMessage(player, "That doesn't appear to be the correct diamond...") + return@onUseWith true + } + onUseWith(IntType.SCENERY, Items.SHADOW_DIAMOND_4673, Scenery.OBELISK_6492) { player, used, with -> + if (getDynLevel(player, Skills.MAGIC) > 50) { + if (removeItem(player, used)) { + sendMessage(player, "The diamond is absorbed into the pillar.") + setVarbit(player, DesertTreasure.varbitShadowObelisk, 1) + setAttribute(player, DesertTreasure.attributeShadowDiamondInserted, 1) + if (allDiamondsInserted(player)) { + sendMessage(player, "The force preventing access to the Pyramid has now vanished.") + if (getQuestStage(player, DesertTreasure.questName) == 9) { + setQuestStage(player, DesertTreasure.questName, 10) + } + } + } + } else { + sendMessage(player, "You are not a powerful enough mage to breach the protective aura.") + sendMessage(player, "You need a magic level of at least 50 to enter the Pyramid.") + } + return@onUseWith true + } + + // THE DOOR + on(intArrayOf(Scenery.PYRAMID_ENTRANCE_6545, Scenery.PYRAMID_ENTRANCE_6547), SCENERY, "open") { player, node -> + if (allDiamondsInserted(player)) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else { + sendMessage(player, "A mystical power has sealed this door...") + } + return@on true + } + + // THE LADDERS + on(Scenery.LADDER_6497, SCENERY, "climb-down") { player, node -> + teleport(player, Location(2913, 4954, 3)) + return@on true + } + on(Scenery.LADDER_6504, SCENERY, "climb-up") { player, node -> + teleport(player, Location(3233, 2898, 0)) + return@on true + } + + on(Scenery.LADDER_6498, SCENERY, "climb-down") { player, node -> + teleport(player, Location(2846, 4964, 2)) + return@on true + } + on(Scenery.LADDER_6503, SCENERY, "climb-up") { player, node -> + teleport(player, Location(2909, 4963, 3)) + return@on true + } + + on(Scenery.LADDER_6499, SCENERY, "climb-down") { player, node -> + teleport(player, Location(2782, 4972, 1)) + return@on true + } + on(Scenery.LADDER_6502, SCENERY, "climb-up") { player, node -> + teleport(player, Location(2845, 4973, 2)) + return@on true + } + + on(Scenery.LADDER_6500, SCENERY, "climb-down") { player, node -> + teleport(player, Location(3233, 9293, 0)) + return@on true + } + on(Scenery.LADDER_6501, SCENERY, "climb-up") { player, node -> + teleport(player, Location(2783, 4941, 1)) + return@on true + } + + on((6512..6517).toIntArray(), SCENERY, "search") { player, node -> + // Technically there is loot, but I'm lazy as hell. + sendMessage(player, "You don't find anything interesting.") + return@on true + } + + // After Quest + + // Backdoor + on(Scenery.TUNNEL_6481, SCENERY, "enter") { player, node -> + if (isQuestComplete(player, DesertTreasure.questName)){ + teleport(player, Location(3233, 9313, 0)) + } else { + sendMessage(player, "This passage does not seem to lead anywhere...") // https://youtu.be/uNkBucGaqac + } + return@on true + } + + // Portal, which only appears after DT + on(Scenery.PORTAL_6551, SCENERY, "use") { player, node -> + teleport(player, Location(3233, 2887, 0)) + return@on true + } + + } +} + + +// https://www.youtube.com/watch?v=yMwp78OI2y8 + +// Ice Troll +class NorthMirrorLookCutscene(player: Player) : Cutscene(player) { + + override fun setup() { + setExit(player.location.transform(0, 0, 0)) + loadRegion(11322) + } + + override fun runStage(stage: Int) { + when (stage) { + 0 -> { + fadeToBlack() + timedUpdate(4) + } + 1 -> { + teleport(player, 5, 27) + moveCamera(5, 27, 1000) + rotateCamera(6, 27, 1000) + timedUpdate(1) + } + 2 -> { + openInterface(player, 155) + closeOverlay() + timedUpdate(6) + } + 3-> { + closeInterface(player) + fadeToBlack() + timedUpdate(4) + } + 4-> { + end(false){ + fadeFromBlack() + // resetCamera() + } + } + } + } +} + +// Canifis +class NorthEastMirrorLookCutscene(player: Player) : Cutscene(player) { + + override fun setup() { + setExit(player.location.transform(0, 0, 0)) + loadRegion(13878) + } + + override fun runStage(stage: Int) { + when (stage) { + 0 -> { + fadeToBlack() + timedUpdate(4) + } + 1 -> { + teleport(player, 47, 31) + moveCamera(47, 31, 1000) + rotateCamera(43, 31, 1000) + timedUpdate(1) + } + 2 -> { + openInterface(player, 155) + closeOverlay() + timedUpdate(6) + } + 3-> { + closeInterface(player) + fadeToBlack() + timedUpdate(4) + } + 4-> { + end(false){ + fadeFromBlack() + // resetCamera() + } + } + } + } +} + +// Smoke Dungeon +class SouthEastMirrorLookCutscene(player: Player) : Cutscene(player) { + + override fun setup() { + setExit(player.location.transform(0, 0, 0)) + loadRegion(13102) + } + + override fun runStage(stage: Int) { + when (stage) { + 0 -> { + fadeToBlack() + timedUpdate(4) + } + 1 -> { + teleport(player, 36, 20) + moveCamera(36, 20, 1000) + rotateCamera(44, 20, 1000) + timedUpdate(1) + } + 2 -> { + openInterface(player, 155) + closeOverlay() + timedUpdate(6) + } + 3-> { + closeInterface(player) + fadeToBlack() + timedUpdate(4) + } + 4-> { + end(false){ + fadeFromBlack() + // resetCamera() + } + } + } + } +} + +// Pyramid +class SouthMirrorLookCutscene(player: Player) : Cutscene(player) { + + override fun setup() { + setExit(player.location.transform(0, 0, 0)) + loadRegion(12845) + } + + override fun runStage(stage: Int) { + when (stage) { + 0 -> { + fadeToBlack() + timedUpdate(4) + } + 1 -> { + teleport(player, 33, 41) + moveCamera(33, 41, 1000) + rotateCamera(33, 39, 990) + timedUpdate(1) + } + 2 -> { + openInterface(player, 155) + closeOverlay() + timedUpdate(6) + } + 3-> { + closeInterface(player) + fadeToBlack() + timedUpdate(4) + } + 4-> { + end(false){ + fadeFromBlack() + // resetCamera() + } + } + } + } +} + +// Bedabin +class SouthWestMirrorLookCutscene(player: Player) : Cutscene(player) { + + override fun setup() { + setExit(player.location.transform(0, 0, 0)) + loadRegion(12590) + } + + override fun runStage(stage: Int) { + when (stage) { + 0 -> { + fadeToBlack() + timedUpdate(4) + } + 1 -> { + teleport(player, 40, 39) + moveCamera(40, 39, 1200) + rotateCamera(10, 39, 1200) + timedUpdate(1) + } + 2 -> { + openInterface(player, 155) + closeOverlay() + timedUpdate(6) + } + 3-> { + closeInterface(player) + fadeToBlack() + timedUpdate(4) + } + 4-> { + end(false){ + fadeFromBlack() + // resetCamera() + } + } + } + } +} + +// Rasolo +class NorthWestMirrorLookCutscene(player: Player) : Cutscene(player) { + + override fun setup() { + setExit(player.location.transform(0, 0, 0)) + loadRegion(10037) + } + + override fun runStage(stage: Int) { + when (stage) { + 0 -> { + fadeToBlack() + timedUpdate(4) + } + 1 -> { + teleport(player, 56, 40) + moveCamera(56, 40, 1400) + rotateCamera(56, 35, 1000) + timedUpdate(1) + } + 2 -> { + openInterface(player, 155) + closeOverlay() + timedUpdate(6) + } + 3-> { + closeInterface(player) + fadeToBlack() + timedUpdate(4) + } + 4-> { + end(false){ + fadeFromBlack() + // resetCamera() + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/DessousBehavior.kt b/Server/src/main/content/region/desert/quest/deserttreasure/DessousBehavior.kt new file mode 100644 index 0000000..5c521e6 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/DessousBehavior.kt @@ -0,0 +1,142 @@ +package content.region.desert.quest.deserttreasure + +import content.region.kandarin.quest.templeofikov.TempleOfIkov +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.interaction.QueueStrength +import core.game.node.entity.Entity +import core.game.node.entity.combat.* +import core.game.node.entity.combat.equipment.SwitchAttack +import core.game.node.entity.impl.Projectile +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.prayer.PrayerType +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +class DessousMeleeBehavior : NPCBehavior(NPCs.DESSOUS_1914, NPCs.DESSOUS_1915) { + + var clearTime = 0 + + override fun canBeAttackedBy(self: NPC, attacker: Entity, style: CombatStyle, shouldSendMessage: Boolean): Boolean { + if (attacker is Player) { + if (attacker == getAttribute(self, "target", null)) { + return true + } + sendMessage(attacker, "It's not after you...") + } + return false + } + + override fun tick(self: NPC): Boolean{ + // Dessous just continually hisses independently of projectile fires. + if (self.id == NPCs.DESSOUS_1915 && self.properties.combatPulse.isInCombat) { + animate(self, Animation(1914)) + } + // This is probably the prayer flicking nonsense. + val player: Player? = getAttribute(self, "target", null) + if (self.id == NPCs.DESSOUS_1914 && player != null && player.prayer.get(PrayerType.PROTECT_FROM_MELEE)) { + self.transform(NPCs.DESSOUS_1915) + Graphics.send(Graphics(86), self.location) + } else if (self.id == NPCs.DESSOUS_1915 && player != null && (player.prayer.get(PrayerType.PROTECT_FROM_MAGIC) || player.prayer.get(PrayerType.PROTECT_FROM_MISSILES))) { + self.transform(NPCs.DESSOUS_1914) + Graphics.send(Graphics(86), self.location) + } + if (clearTime++ > 800) { + self.transform(NPCs.DESSOUS_1914) + clearTime = 0 + if (player != null) { + removeAttribute(player, DesertTreasure.attributeDessousInstance) + sendMessage(player, "Dessous returns to his grave, bored of toying with you.") + } + poofClear(self) + } + return false + } + + override fun getSwingHandlerOverride(self: NPC, original: CombatSwingHandler): CombatSwingHandler { + if (self.id == NPCs.DESSOUS_1915) { + // 2 x 5HP (One Magic, One Ranged) + return CombatHandler() + } else { + // Fast melee attack 3 ticks up to 19HP + return original + } + } + + override fun beforeAttackFinalized(self: NPC, victim: Entity, state: BattleState) { + // Teleport nearer, if too far. + if (victim is Player) { + if (victim.location.getDistance(self.location) >= 5) { + Graphics.send(Graphics(86), self.location) + self.properties.teleportLocation = victim.location + Graphics.send(Graphics(86), self.location) + } + } + } + + override fun onDeathFinished(self: NPC, killer: Entity) { + if (killer is Player) { + val player = killer + if (DesertTreasure.getSubStage(player, DesertTreasure.attributeBloodStage) == 2) { + DesertTreasure.setSubStage(player, DesertTreasure.attributeBloodStage, 3) + } + removeAttribute(player, DesertTreasure.attributeDessousInstance) + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> player(FacialExpression.ANGRY, "Well that's Dessous dead, but where is the Diamond he", "was supposed to have?").also { stage++ } + 1 -> playerl(FacialExpression.ANGRY, "If Malak lied to me about it, he is going to pay!").also { + stage = END_DIALOGUE + } + } + } + }) + } + } + + /** Handler for ranged. */ + class CombatHandler : MultiSwingHandler( + SwitchAttack(CombatStyle.MAGIC.swingHandler, null), + SwitchAttack(CombatStyle.RANGE.swingHandler, null) + ) { + override fun swing(entity: Entity?, victim: Entity?, state: BattleState?): Int { + if (entity is NPC && victim is Player) { + val projectile = Projectile.create( + victim.location.transform(Location(intArrayOf(3, -3).random(),intArrayOf(3, -3).random())), + victim.location, + 350, + 0, + 0, + 0, + 60, + 0, + 255 + ) + // 2 x 5HP (One Magic, One Ranged) + state!!.estimatedHit = 5 + state.secondaryHit = 5 // I have no idea what I'm doing + queueScript(entity, 0, QueueStrength.STRONG) { stage: Int -> + when (stage) { + 0 -> { + sendChat(entity, "Hssssssssssss") + projectile.send() + return@queueScript delayScript(entity, entity.location.getDistance(victim.location).toInt()) + } + 1 -> { + return@queueScript stopExecuting(entity) + } + else -> return@queueScript stopExecuting(entity) + } + } + + } + return super.swing(entity, victim, state) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/DiamondOfBloodListeners.kt b/Server/src/main/content/region/desert/quest/deserttreasure/DiamondOfBloodListeners.kt new file mode 100644 index 0000000..8105aeb --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/DiamondOfBloodListeners.kt @@ -0,0 +1,134 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import core.game.world.map.Direction +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +class DiamondOfBloodListeners : InteractionListener { + override fun defineListeners() { + + // Silver pot conversions + onUseWith(ITEM, Items.SILVER_POT_4660, Items.SPICE_2007) { player, used, with -> + sendMessage(player, "You add some spices to the pot.") + if(removeItem(player, used) && removeItem(player, with)) { + addItemOrDrop(player, Items.SILVER_POT_4664) + } + return@onUseWith true + } + onUseWith(ITEM, Items.SILVER_POT_4660, Items.GARLIC_POWDER_4668) { player, used, with -> + sendMessage(player, "You add some crushed garlic to the pot.") + if(removeItem(player, used) && removeItem(player, with)) { + addItemOrDrop(player, Items.SILVER_POT_4662) + } + return@onUseWith true + } + onUseWith(ITEM, Items.SILVER_POT_4662, Items.SPICE_2007) { player, used, with -> + sendMessage(player, "You add some spices to the pot.") + if(removeItem(player, used) && removeItem(player, with)) { + addItemOrDrop(player, Items.SILVER_POT_4666) + } + return@onUseWith true + } + onUseWith(ITEM, Items.SILVER_POT_4664, Items.GARLIC_POWDER_4668) { player, used, with -> + sendMessage(player, "You add some crushed garlic to the pot.") + if(removeItem(player, used) && removeItem(player, with)) { + addItemOrDrop(player, Items.SILVER_POT_4666) + } + return@onUseWith true + } + // Blessed pot conversions + onUseWith(ITEM, Items.BLESSED_POT_4661, Items.SPICE_2007) { player, used, with -> + sendMessage(player, "You add some spices to the pot.") + if(removeItem(player, used) && removeItem(player, with)) { + addItemOrDrop(player, Items.BLESSED_POT_4665) + } + return@onUseWith true + } + onUseWith(ITEM, Items.BLESSED_POT_4661, Items.GARLIC_POWDER_4668) { player, used, with -> + sendMessage(player, "You add some crushed garlic to the pot.") + if(removeItem(player, used) && removeItem(player, with)) { + addItemOrDrop(player, Items.BLESSED_POT_4663) + } + return@onUseWith true + } + onUseWith(ITEM, Items.BLESSED_POT_4663, Items.SPICE_2007) { player, used, with -> + sendMessage(player, "You add some spices to the pot.") + if(removeItem(player, used) && removeItem(player, with)) { + addItemOrDrop(player, Items.BLESSED_POT_4667) + } + return@onUseWith true + } + onUseWith(ITEM, Items.BLESSED_POT_4665, Items.GARLIC_POWDER_4668) { player, used, with -> + sendMessage(player, "You add some crushed garlic to the pot.") + if(removeItem(player, used) && removeItem(player, with)) { + addItemOrDrop(player, Items.BLESSED_POT_4667) + } + return@onUseWith true + } + + // You need to crush the garlic. + onUseWith(ITEM, intArrayOf(Items.SILVER_POT_4660, Items.BLESSED_POT_4661, Items.SILVER_POT_4662, Items.BLESSED_POT_4663, Items.SILVER_POT_4664, Items.BLESSED_POT_4665, Items.SILVER_POT_4666, Items.BLESSED_POT_4667 ), Items.GARLIC_1550) { player, used, with -> + sendMessage(player, "You need to crush the garlic before adding it to the pot.") + return@onUseWith true + } + + // Dessous jumps out. + onUseWith(SCENERY, Items.BLESSED_POT_4667, Scenery.VAMPIRE_TOMB_6437) { player, used, with -> + val prevNpc = getAttribute(player, DesertTreasure.attributeDessousInstance, null) + if (prevNpc != null) { + prevNpc.clear() + } + sendMessage(player, "You pour the blood from the pot onto the tomb.") + removeItem(player, used) + val scenery = with.asScenery() + // Swap to a splittable vampire tomb scenery. + replaceScenery(scenery, Scenery.VAMPIRE_TOMB_6438, Animation(1915).duration) + // Vampire Tomb breaks open. + animateScenery(player, scenery, 1915) + // 8 Bat projectiles + spawnProjectile(Location(3570, 3402), Location(3570, 3404), 350, 0, 0, 0, 60, 0) + spawnProjectile(Location(3570, 3402), Location(3570, 3400), 350, 0, 0, 0, 60, 0) + spawnProjectile(Location(3570, 3402), Location(3568, 3402), 350, 0, 0, 0, 60, 0) + spawnProjectile(Location(3570, 3402), Location(3572, 3402), 350, 0, 0, 0, 60, 0) + spawnProjectile(Location(3570, 3402), Location(3568, 3404), 350, 0, 0, 0, 60, 0) + spawnProjectile(Location(3570, 3402), Location(3572, 3404), 350, 0, 0, 0, 60, 0) + spawnProjectile(Location(3570, 3402), Location(3568, 3400), 350, 0, 0, 0, 60, 0) + spawnProjectile(Location(3570, 3402), Location(3572, 3400), 350, 0, 0, 0, 60, 0) + val npc = NPC(NPCs.DESSOUS_1914) + queueScript(player, 1, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + // Projectile gfx for Dessous to jump out. + spawnProjectile(Location(3570, 3402), Location(3570, 3405), 351, 0, 0, 0, 40, 0) + return@queueScript delayScript(player, 1) + } + 1 -> { + npc.isRespawn = false + npc.isWalks = false + npc.location = Location(3570, 3405, 0) + npc.direction = Direction.NORTH + setAttribute(player, DesertTreasure.attributeDessousInstance, npc) + setAttribute(npc, "target", player) + + npc.init() + npc.attack(player) + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + + //sendGraphics(350, Location(3570, 3402)) + //sendGraphics(351, Location(3570, 3402)) + return@onUseWith true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/DiamondOfIceListeners.kt b/Server/src/main/content/region/desert/quest/deserttreasure/DiamondOfIceListeners.kt new file mode 100644 index 0000000..9ee2c5b --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/DiamondOfIceListeners.kt @@ -0,0 +1,168 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +class DiamondOfIceListeners : InteractionListener { + override fun defineListeners() { + onUseWith(IntType.NPC, Items.CHOCOLATE_CAKE_1897, NPCs.BANDIT_1932 /* should be NPCs.TROLL_CHILD_1932 */) { player, used, with -> + if (removeItem(player, used)) { + if (DesertTreasure.getSubStage(player, DesertTreasure.attributeIceStage) == 0) { + DesertTreasure.setSubStage(player, DesertTreasure.attributeIceStage, 1) + } + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> player("Hey there little troll...", "Take this and dry those tears...").also { stage++ } + 1 -> npc(FacialExpression.OLD_NEARLY_CRYING, "(sniff)").also { + stage = END_DIALOGUE + } + } + } + }, with as NPC) + } + return@onUseWith true + } + + on(intArrayOf(Scenery.ICE_GATE_5043, Scenery.ICE_GATE_5044), SCENERY, "go-through") { player, node -> + + if ((getQuestStage(player, DesertTreasure.questName) == 9 && + DesertTreasure.getSubStage(player, DesertTreasure.attributeIceStage) > 1) || + getQuestStage(player, DesertTreasure.questName) >= 10) { + sendMessage(player, "You squeeze through the large icy bars of the gate.") + // Anim 3272 to squeeze through? + if(player.location.x > 2838) { + teleport(player, Location(2837, 3739, 0)) + } else { + teleport(player, Location(2839, 3739, 0)) + } + } else { + // j_SdwOX1JWg + sendDialogueLines(player, "The bars are frozen tightly shut and a sturdy layer of ice prevents", "you from slipping through.") + } + return@on true + } + + on(Scenery.CAVE_ENTRANCE_6441, SCENERY, "enter") { player, node -> + lock(player, 3) + animate(player, 2796) // Crawling + queueScript(player, 3, QueueStrength.SOFT) { + teleport(player, Location(2874, 3720, 0)) + return@queueScript stopExecuting(player) + } + return@on true + } + + on(Scenery.CAVE_ENTRANCE_6446, SCENERY, "enter") { player, node -> + sendMessage(player, "The entrance to the cave is covered in too much ice to get through.") + return@on true + } + + on(Scenery.CAVE_EXIT_6447, SCENERY, "enter") { player, node -> + lock(player, 3) + animate(player, 2796) // Crawling + queueScript(player, 3, QueueStrength.SOFT) { + teleport(player, Location(2867, 3719, 0)) + return@queueScript stopExecuting(player) + } + return@on true + } + + on(Scenery.ICE_LEDGE_6455, SCENERY, "use") { player, node -> + + if ((getQuestStage(player, DesertTreasure.questName) == 9 && + DesertTreasure.getSubStage(player, DesertTreasure.attributeIceStage) >= 3) || + getQuestStage(player, DesertTreasure.questName) >= 10) { + if (inEquipment(player, Items.SPIKED_BOOTS_3107)) { + teleport(player, Location(2838, 3803, 1)) + } else { + sendPlayerDialogue(player, "I don't think I'll make much headway along that icy slope without some spiked boots...") + } + } else { + sendMessage(player, "You have not defeated Kamil yet.") + } + return@on true + } + + on(intArrayOf(Scenery.ICE_GATE_6461, Scenery.ICE_GATE_6462), SCENERY, "go-through") { player, node -> + + teleport(player, Location(2852, 3810, 2)) + return@on true + } + + // This is 1943 as base + on(NPCs.ICE_BLOCK_1944, NPC, "talk-to") { player, node -> + sendDialogueLines(player, "There is a thick layer of ice covering this troll.", "You will have to find some way of shattering it.") + return@on true + } + on(NPCs.ICE_BLOCK_1944, NPC, "smash-ice") { player, node -> + player.attack(node) + return@on true + } + + // This is 1945 as base + on(NPCs.ICE_BLOCK_1946, NPC, "talk-to") { player, node -> + sendDialogueLines(player, "There is a thick layer of ice covering this troll.", "You will have to find some way of shattering it.") + return@on true + } + on(NPCs.ICE_BLOCK_1946, NPC, "smash-ice") { player, node -> + player.attack(node) + return@on true + } + } +} + +/** This is while you are walking up the ice path. **/ +class ComicalTrippingIceArea : MapArea { + override fun defineAreaBorders(): Array { + return arrayOf( + ZoneBorders(2815, 3775, 2880, 3839, 1), + ZoneBorders(2815, 3775, 2880, 3839, 2) + ) + } + + override fun entityStep(entity: Entity, location: Location, lastLocation: Location) { + if (entity is Player) { + if ((1..10).random() == 1) { + lock(entity, 2) + stopWalk(entity) + animate(entity, 767) + } + } + } +} + +class IceAreaAttack : MapArea { + override fun defineAreaBorders(): Array { + return arrayOf(ZoneBorders(2850, 3750, 2880, 3770)) + } + + override fun areaEnter(entity: Entity) { + if (entity is Player && + getQuestStage(entity, DesertTreasure.questName) == 9 && + DesertTreasure.getSubStage(entity, DesertTreasure.attributeIceStage) == 2 && + getAttribute(entity, DesertTreasure.attributeKamilInstance, null) == null + ) { + sendMessage(entity, "You can feel an evil presence nearby...") + val npc = NPC.create(NPCs.KAMIL_1913, Location(2857, 3754, 0)) + setAttribute(entity, DesertTreasure.attributeKamilInstance, npc) + setAttribute(npc, "target", entity) + npc.isRespawn = false + npc.init() + npc.attack(entity) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/DiamondOfShadowListeners.kt b/Server/src/main/content/region/desert/quest/deserttreasure/DiamondOfShadowListeners.kt new file mode 100644 index 0000000..615a9b2 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/DiamondOfShadowListeners.kt @@ -0,0 +1,265 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import core.tools.END_DIALOGUE +import core.tools.RandomFunction +import core.tools.START_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +class DiamondOfShadowListeners : InteractionListener { + + companion object { + + fun roll(player: Player): Boolean { + + val chance = RandomFunction.randomDouble(1.0, 100.0) + val successChance = RandomFunction.getSkillSuccessChance(52.0, 128.0, getDynLevel(player, Skills.THIEVING)) + + return chance < successChance + } + + fun pickAttempt(player: Player, picklockItem: Item?) { + queueScript(player, 0, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + sendMessage(player, "You attempt to pick the first lock...") + return@queueScript delayScript(player, 1) + } + + 1 -> { + if (roll(player)) { + sendMessage(player, "...You successfully picked the first lock!") + return@queueScript delayScript(player, 1) + } else { + if(picklockItem != null) { + removeItem(player, picklockItem) + } else { + removeItem(player, Items.LOCKPICK_1523) + } + sendMessage(player, "...and fail. The locking mechanism has reset itself.") + sendMessage(player, "Your lock pick snapped while attempting to pick the lock.") + impact(player, 3) + applyPoison(player, player, 6) + return@queueScript stopExecuting(player) + } + } + + 2 -> { + sendMessage(player, "You attempt to pick the second lock...") + return@queueScript delayScript(player, 1) + } + + 3 -> { + if (roll(player)) { + sendMessage(player, "...You successfully picked the second lock!") + return@queueScript delayScript(player, 1) + } else { + if(picklockItem != null) { + removeItem(player, picklockItem) + } else { + removeItem(player, Items.LOCKPICK_1523) + } + sendMessage(player, "...and fail. The locking mechanism has reset itself.") + sendMessage(player, "Your lock pick snapped while attempting to pick the lock.") + impact(player, 3) + applyPoison(player, player, 6) + return@queueScript stopExecuting(player) + } + } + + 4 -> { + sendMessage(player, "You attempt to pick the final lock...") + return@queueScript delayScript(player, 1) + } + + 5 -> { + if (roll(player)) { + sendMessage(player, "You managed to pick the final lock.") + return@queueScript delayScript(player, 1) + } else { + if(picklockItem != null) { + removeItem(player, picklockItem) + } else { + removeItem(player, Items.LOCKPICK_1523) + } + sendMessage(player, "...and fail. The locking mechanism has reset itself.") + sendMessage(player, "Your lock pick snapped while attempting to pick the lock.") + impact(player, 3) + applyPoison(player, player, 6) + return@queueScript stopExecuting(player) + } + } + + 6 -> { + if (DesertTreasure.getSubStage(player, DesertTreasure.attributeShadowStage) == 1) { + DesertTreasure.setSubStage(player, DesertTreasure.attributeShadowStage, 2) + } + return@queueScript stopExecuting(player) + } + + else -> return@queueScript stopExecuting(player) + } + } + } + } + + override fun defineListeners() { + + // Hidden entrance to the shadow dungeon. + on(Scenery.LADDER_6561, SCENERY, "climb-down") { player, node -> + teleport(player, Location(2630, 5072)) + return@on true + } + + /** This will open up a lot of other places. Maybe have this in a general file? */ + onEquip(Items.RING_OF_VISIBILITY_4657) { player, _ -> + + if((DesertTreasure.getSubStage(player, DesertTreasure.attributeShadowStage) >= 3 && + getQuestStage(player, DesertTreasure.questName) >= 9) || + getQuestStage(player, DesertTreasure.questName) >= 10) { + + setVarbit(player, DesertTreasure.varbitRingOfVisibility, 1) + return@onEquip true + } + sendMessage(player, "You need to complete part of Desert Treasure to equip this.") + return@onEquip false + } + + onUnequip(Items.RING_OF_VISIBILITY_4657) { player, _ -> + setVarbit(player, DesertTreasure.varbitRingOfVisibility, 0) + return@onUnequip true + } + + + + on(Scenery.SECURE_CHEST_6448, SCENERY, "open") { player, node -> + if (DesertTreasure.getSubStage(player, DesertTreasure.attributeShadowStage) == 1) { + if (inInventory(player, Items.LOCKPICK_1523)) { + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + START_DIALOGUE -> dialogue("Your skill as a thief allows you to see some kind of elaborate booby", "trapped locking mechanism on this chest.").also { stage++ } + 1 -> showTopics( + Topic(FacialExpression.NEUTRAL, "Yes", 2, true), + Topic(FacialExpression.NEUTRAL, "No", END_DIALOGUE, true), + title = "Try to open the chest?" + ) + 2 -> end().also { + if (inInventory(player, Items.LOCKPICK_1523)) { + pickAttempt(player, null) + } else { + sendMessage(player, "You need a lockpick in order to attempt this.") + } + } + } + } + }) + } else { + sendMessage(player, "You need a lockpick in order to attempt this.") + } + } else if ((DesertTreasure.getSubStage(player, DesertTreasure.attributeShadowStage) >= 2 && + getQuestStage(player, DesertTreasure.questName) >= 9) || + getQuestStage(player, DesertTreasure.questName) >= 10) { + if (inInventory(player, Items.GILDED_CROSS_4674)) { + sendMessage(player, "The chest is empty.") + } else { + replaceScenery(node as core.game.node.scenery.Scenery, 6449, 2) + sendMessage(player, "Inside the chest, hidden under some rags, you find a Gilded Cross.") + addItemOrDrop(player, Items.GILDED_CROSS_4674) + } + } else { + sendPlayerDialogue(player, "These bandits are hostile enough without me trying to rob them!") + } + return@on true + } + + onUseWith(SCENERY, Items.LOCKPICK_1523, Scenery.SECURE_CHEST_6448) { player, used, with -> + if (DesertTreasure.getSubStage(player, DesertTreasure.attributeShadowStage) == 1) { + pickAttempt(player, used as Item) + } else if((DesertTreasure.getSubStage(player, DesertTreasure.attributeShadowStage) >= 2 && + getQuestStage(player, DesertTreasure.questName) >= 9) || + getQuestStage(player, DesertTreasure.questName) >= 10) { + sendMessage(player, "The chest is unlocked.") + } else { + sendPlayerDialogue(player, "These bandits are hostile enough without me trying to rob them!") + } + return@onUseWith true + } + + } +} + +class ShadowDungeonWarning : MapArea { + override fun defineAreaBorders(): Array { + return arrayOf(ZoneBorders(2726, 5072, 2728, 5072)) + } + + override fun areaEnter(entity: Entity) { + if (entity is Player) { + if ( + getQuestStage(entity, DesertTreasure.questName) == 9 && + DesertTreasure.getSubStage(entity, DesertTreasure.attributeShadowStage) == 3 && + getAttribute(entity, DesertTreasure.attributeDamisWarning, false) + ) { + sendMessage(entity, "A voice seems to come from the walls around you;") + sendMessage(entity, "'You... do not be... long in this... place") + sendMessage(entity, "Turn... back now, or... prepare... to meet your... doom'") + getAttribute(entity, DesertTreasure.attributeDamisWarning, true) + } else if ( + getQuestStage(entity, DesertTreasure.questName) == 9 && + DesertTreasure.getSubStage(entity, DesertTreasure.attributeShadowStage) == 100 + ) { + if (!inInventory(entity, Items.SHADOW_DIAMOND_4673) && !inBank(entity, Items.SHADOW_DIAMOND_4673)) { + sendMessage(entity, "The Diamond of Shadow seems to have mystically found its way back here...") + GroundItemManager.create(Item(Items.SHADOW_DIAMOND_4673), Location(2739, 5088, 0), entity) + } + } + } + } +} + +class ShadowDungeonAttack : MapArea { + override fun defineAreaBorders(): Array { + return arrayOf(ZoneBorders(2731, 5085, 2748, 5097)) + } + + override fun areaEnter(entity: Entity) { + if (entity is Player) { + if (getQuestStage(entity, DesertTreasure.questName) == 9) { + if (DesertTreasure.getSubStage(entity, DesertTreasure.attributeShadowStage) == 3 && + getAttribute(entity, DesertTreasure.attributeDamisInstance, null) == null + ) { + val npc = NPC.create(NPCs.DAMIS_1974, Location(2739, 5088, 0)) + setAttribute(entity, DesertTreasure.attributeDamisInstance, npc) + setAttribute(npc, "target", entity) + npc.isRespawn = false + npc.walkRadius = 30 + npc.init() + npc.attack(entity) + sendChat(npc, "You should have listened to me!") + } + } else if (DesertTreasure.getSubStage(entity, DesertTreasure.attributeShadowStage) >= 100) { + if (!inInventory(entity, Items.SHADOW_DIAMOND_4673) && !inBank(entity, Items.SHADOW_DIAMOND_4673)) { + sendMessage(entity, "The Diamond of Shadow seems to have mystically found its way back here...") + GroundItemManager.create(Item(Items.SHADOW_DIAMOND_4673), Location(2739, 5088, 0), entity) + } + } + } + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/DiamondOfSmokeListeners.kt b/Server/src/main/content/region/desert/quest/deserttreasure/DiamondOfSmokeListeners.kt new file mode 100644 index 0000000..279b6d1 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/DiamondOfSmokeListeners.kt @@ -0,0 +1,180 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.global.action.DoorActionHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import core.game.system.timer.RSTimer +import core.game.world.map.Location +import core.tools.secondsToTicks +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +class DiamondOfSmokeListeners : InteractionListener { + companion object { + const val timerIdentifierTorchNE = "deserttreasureNEtorch" + const val timerIdentifierTorchSE = "deserttreasureSEtorch" + const val timerIdentifierTorchSW = "deserttreasureSWtorch" + const val timerIdentifierTorchNW = "deserttreasureNWtorch" + + fun checkAllTorchesLit(player: Player) : Boolean { + return getVarbit(player, DesertTreasure.varbitStandingTorchNorthEast) == 1 && + getVarbit(player, DesertTreasure.varbitStandingTorchSouthEast) == 1 && + getVarbit(player, DesertTreasure.varbitStandingTorchSouthWest) == 1 && + getVarbit(player, DesertTreasure.varbitStandingTorchNorthWest) == 1 + } + } + + override fun defineListeners() { + on(Scenery.BURNT_CHEST_6420, SCENERY, "open") { player, node -> + if (checkAllTorchesLit(player)) { + if (DesertTreasure.getSubStage(player, DesertTreasure.attributeSmokeStage) == 0) { + DesertTreasure.setSubStage(player, DesertTreasure.attributeSmokeStage, 1) + } + } + if (DesertTreasure.getSubStage(player, DesertTreasure.attributeSmokeStage) >= 1) { + replaceScenery(node as core.game.node.scenery.Scenery, 6421, 2) + addItemOrDrop(player, Items.WARM_KEY_4656) + sendMessage(player, "You open the chest and take a key.") + } else { + sendDialogueLines(player, "There seems to be no way to open this chest. Engraved where the", "keyhole should be is a message:", "'Light the path, and find the key...'") + } + return@on true + } + + on(intArrayOf(Scenery.GATE_6451, Scenery.GATE_6452), SCENERY, "open") { player, node -> + if (getQuestStage(player, DesertTreasure.questName) == 9) { + // Set attributeUnlockedGate to true if warm key and first time unlocking the gate. + if (!getAttribute(player, DesertTreasure.attributeUnlockedGate, false) && inInventory(player, Items.WARM_KEY_4656)) { + if(removeItem(player, Items.WARM_KEY_4656)) { + sendMessage(player, "You unlock the gate and enter the room.") + setAttribute(player, DesertTreasure.attributeUnlockedGate, true) + } + } + // Fight if unlocked gate, drop recovery diamond if done. + if (getAttribute(player, DesertTreasure.attributeUnlockedGate, false)) { + if (DesertTreasure.getSubStage(player, DesertTreasure.attributeSmokeStage) == 1 && + getAttribute(player, DesertTreasure.attributeFareedInstance, null) == null) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + val npc = core.game.node.entity.npc.NPC.create(NPCs.FAREED_1977, Location(3315, 9376, 0)) + setAttribute(player, DesertTreasure.attributeFareedInstance, npc) + setAttribute(npc, "target", player) + npc.isRespawn = false + npc.init() + npc.attack(player) + sendChat(npc, "You dare trespass in my realm?") + } else if (DesertTreasure.getSubStage(player, DesertTreasure.attributeSmokeStage) >= 100) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + if (!inInventory(player, Items.SMOKE_DIAMOND_4672) && !inBank(player, Items.SMOKE_DIAMOND_4672)) { + sendMessage(player, "The Diamond of Smoke seems to have mystically found its way back here...") + GroundItemManager.create(Item(Items.SMOKE_DIAMOND_4672), Location(3315, 9376, 0), player) + } + } + } else { + sendMessage(player, "The gate is locked.") + } + + } else if (getQuestStage(player, DesertTreasure.questName) in 9..100) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else { + sendMessage(player, "The gate is locked.") + } + return@on true + } + + + on(Scenery.A_DARK_HOLE_31367, SCENERY, "enter") { player, node -> + // You have to come from the Pollnivneach Slayer Dungeon, then this will tele you back. + sendDialogueLines(player, "This hole leads to a maze of other passages. Without knowing where", "you are headed, there's no chance of reaching anywhere interesting.") + return@on true + } + + // NE Standing Torch + onUseWith(IntType.SCENERY, Items.TINDERBOX_590, Scenery.STANDING_TORCH_6406, Scenery.STANDING_TORCH_6413) { player, used, with -> + if (getDynLevel(player, Skills.FIREMAKING) < 50) { + sendMessage(player, "You need a firemaking level of 50 to light this torch.") + return@onUseWith true + } + setVarbit(player, DesertTreasure.varbitStandingTorchNorthEast, 1) + sendMessage(player, "You light the torch.") + if (checkAllTorchesLit(player)) { + sendMessage(player, "The path is lit, now claim the key...") + } + removeTimer(player, timerIdentifierTorchNE) + registerTimer(player, StandingTorchTimer(timerIdentifierTorchNE, DesertTreasure.varbitStandingTorchNorthEast)) + return@onUseWith true + } + + // SE Standing Torch + onUseWith(IntType.SCENERY, Items.TINDERBOX_590, Scenery.STANDING_TORCH_6408, Scenery.STANDING_TORCH_6414) { player, used, with -> + if (getDynLevel(player, Skills.FIREMAKING) < 50) { + sendMessage(player, "You need a firemaking level of 50 to light this torch.") + return@onUseWith true + } + setVarbit(player, DesertTreasure.varbitStandingTorchSouthEast, 1) + sendMessage(player, "You light the torch.") + if (checkAllTorchesLit(player)) { + sendMessage(player, "The path is lit, now claim the key...") + } + removeTimer(player, timerIdentifierTorchSE) + registerTimer(player, StandingTorchTimer(timerIdentifierTorchSE, DesertTreasure.varbitStandingTorchSouthEast)) + return@onUseWith true + } + + // SW Standing Torch + onUseWith(IntType.SCENERY, Items.TINDERBOX_590, Scenery.STANDING_TORCH_6410, Scenery.STANDING_TORCH_6415) { player, used, with -> + if (getDynLevel(player, Skills.FIREMAKING) < 50) { + sendMessage(player, "You need a firemaking level of 50 to light this torch.") + return@onUseWith true + } + setVarbit(player, DesertTreasure.varbitStandingTorchSouthWest, 1) + sendMessage(player, "You light the torch.") + if (checkAllTorchesLit(player)) { + sendMessage(player, "The path is lit, now claim the key...") + } + removeTimer(player, timerIdentifierTorchSW) + registerTimer(player, StandingTorchTimer(timerIdentifierTorchSW, DesertTreasure.varbitStandingTorchSouthWest)) + return@onUseWith true + } + + // NW Standing Torch + onUseWith(IntType.SCENERY, Items.TINDERBOX_590, Scenery.STANDING_TORCH_6412, Scenery.STANDING_TORCH_6416) { player, used, with -> + if (getDynLevel(player, Skills.FIREMAKING) < 50) { + sendMessage(player, "You need a firemaking level of 50 to light this torch.") + return@onUseWith true + } + setVarbit(player, DesertTreasure.varbitStandingTorchNorthWest, 1) + sendMessage(player, "You light the torch.") + if (checkAllTorchesLit(player)) { + sendMessage(player, "The path is lit, now claim the key...") + } + removeTimer(player, timerIdentifierTorchNW) + registerTimer(player, StandingTorchTimer(timerIdentifierTorchNW, DesertTreasure.varbitStandingTorchNorthWest)) + return@onUseWith true + } + } +} + +class StandingTorchTimer(private val timerIdentifier: String = "deserttreasureunknowntimer", private val torchVarbit: Int = 0) : RSTimer(secondsToTicks(150), timerIdentifier) { + override fun run(entity: Entity): Boolean { + if (entity is Player) { + when(timerIdentifier) { + DiamondOfSmokeListeners.timerIdentifierTorchNE -> sendMessage(entity, "The North-east torch burns out...") + DiamondOfSmokeListeners.timerIdentifierTorchSE -> sendMessage(entity, "The South-east torch burns out...") + DiamondOfSmokeListeners.timerIdentifierTorchSW -> sendMessage(entity, "The South-west torch burns out...") + DiamondOfSmokeListeners.timerIdentifierTorchNW -> sendMessage(entity, "The North-west torch burns out...") + else -> sendMessage(entity, "The torch burns out...") + } + setVarbit(entity, torchVarbit, 0) + } + entity.timers.removeTimer(this) + return true + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/EblisDialogue.kt b/Server/src/main/content/region/desert/quest/deserttreasure/EblisDialogue.kt new file mode 100644 index 0000000..11608e5 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/EblisDialogue.kt @@ -0,0 +1,328 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class EblisDialogue(player: Player? = null) : DialoguePlugin(player){ + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player!!, EblisDialogueFile(), npc) + return false + } + override fun newInstance(player: Player?): DialoguePlugin { + return EblisDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.EBLIS_1923) + } + +} +class EblisDialogueFile : DialogueBuilderFile() { + + companion object { + fun checkAllGiven(player: Player): Boolean { + return (getAttribute(player, DesertTreasure.attributeCountMagicLogs, 0) >= 12 && + getAttribute(player, DesertTreasure.attributeCountSteelBars, 0) >= 6 && + getAttribute(player, DesertTreasure.attributeCountMoltenGlass, 0) >= 6 && + getAttribute(player, DesertTreasure.attributeCountBones, 0) >= 1 && + getAttribute(player, DesertTreasure.attributeCountAshes, 0) >= 1 && + getAttribute(player, DesertTreasure.attributeCountCharcoal, 0) >= 1 && + getAttribute(player, DesertTreasure.attributeCountBloodRune, 0) >= 1) + } + } + + override fun create(b: DialogueBuilder) { + + b.onQuestStages(DesertTreasure.questName, 0,1,2,3,4) + .npcl("Leave us to our fate. We care nothing for the world that betrayed us, or those that come from it.") + .end() + + b.onQuestStages(DesertTreasure.questName, 5,6) + .playerl("Hello. I represent the Museum of Varrock, and I have reason to believe there may be some kinds of artefacts of historical significance in the nearby area...") + .npcl("Ah yes. The only time people care about our existence is when they think they have something to gain from us.") + .npcl("I have nothing to say to you. You and your kind are not welcome here.") + .playerl("Please, if I can just have a few minutes of your time to ask some questions...?") + .npcl("(sigh) I suppose I can spare you that. What do you wish to know about?") + .options() + .let { optionBuilder -> + optionBuilder.option("Why is this village so hostile?") + .playerl("Why are all of the people here so hostile? You would think I was asking you for money instead of just for answers to a few questions...") + .npcl("It is a long story, and I doubt you have much interest in hearing it. Your sort never are, you just take what you can of ours, and then abandon us once more to the desert.") + .options() + .let { optionBuilder2 -> + optionBuilder2.option("No, I want to hear this story.") + .playerl("Actually, I'd be quite interested to hear what it is you have to say to excuse the attitude everybody in this village seems to have.") + .npcl("Ah, it all begun many generations ago, when our ancestors were the proud rulers of these lands...") + .npcl("My ancestors lived far to the North of here, and our lands stretched from the sea in the East to the river Lum, and the mountain of ice. From coast to coast, North to South, our domain was absolute.") + .npcl("Our god was kind to us, and blessed us with prosperity and happiness, and in return we were merciless to his enemies wherever we found them.") + .npcl("Then came the betrayal.") + .npcl("Our god was banished, leaving us helpless to our fates.") + .npcl("Without his protection, we were forced to fend for ourselves once more, against the enemies that sought to destroy us through their petty jealousies.") + .npcl("But we did not succumb without fighting! The spiteful Saradomin and pathetic Zamorak warred with each other, but the hatred they had for each other was as nothing to the hatred they held towards us!") + .npcl("With each battle they waged, we lost more and more land, unable to fight on all fronts, and were pushed further and further South into this gods-forsaken desert.") + .npcl("Our greatest hero, Azzanadra, was finally trapped in a strange stone structure to the South of here, and bound within by terrible powers...") + .npcl("And with that our lands, our homes, our very lives were stolen from us! Too weak to reclaim what was rightfully ours, we made our homes here, knowing that someday Azzanadra will") + .npcl("return with his magnificent power, and bring us back to our former glory...") + .playerl("So you're upset because of something that happened hundreds of years ago?") + .playerl("Seems to me like maybe you should find some closure, and let the past go...") + .npcl("The insults heaped upon my race will never be forgotten, will never be forgiven and will never again be overlooked.") + .npcl("Someday, a harsh wind will blow upon this land, uncovering the wrongs of the past, and we will get back what is rightfully ours. Until such a day we will bide our time here, and will") + .npcl("always be ready with our blades for our righteous vengeance.") + .end() + + optionBuilder2.option("I don't care about your story.") + .playerl("I don't really care what your story is to be honest, there is no excuse for such rudeness or hostility.") + .playerl("I have done nothing wrong to you, but everybody here treats me like I have committed some great crime against the village.") + .npcl("That is because, from our point of view, you have.") + .playerl("What? Just because I entered your village?") + .npcl("You have no right to be here! You have no right to the life you have, for it was taken at our expense!") + .playerl("Whatever... No wonder all you loonies live out here in the desert by yourselves.") + .end() + } + + optionBuilder.option("Do you know anything about treasure near here?") + .playerl("I was wondering if you knew anything about some treasure somewhere around here?") + .playerl("I have some evidence that there might be some kind of treasure hidden very close to this village...") + .npcl("If I knew of any treasure I would not choose to spend my life in this gods-forsaken desert.") + .end() + + optionBuilder.option("Do you know anything about a fortress near here?") + .playerl("Do you know anything about some kind of fortress nearby? I have reason to believe there is, or at least used to be, some kind of fortress very close to here...") + .npcl("Nobody would build anything in this wasteland unless they were forced to, to survive.") + .npcl("I know of no fortress, I know of no reason why anyone would ever bother doing anything out here in the desert.") + .end() + + + // This will only show up after you've talked to the bartender. + optionBuilder.optionIf("Tell me of the four diamonds of Azzanadra.") { player -> + return@optionIf getQuestStage(player, DesertTreasure.questName) == 6 + } + .playerl("So tell me... Did you ever hear of something called the Diamonds of Azzanadra?") + .npcl("This is the treasure which you seek???") + .npcl("Please accept my apologies noble @g[sir,madam]! I thought you were but some opportunistic thief, looking to steal what heritage we have left! Now I see that you are in fact a brave adventurer,") + .npcl("looking to restore our glories back upon us!") + .playerl("Uh... yeah... So anyway, you have heard of them?") + .npcl("Heard of them? Of course I have heard of them! They are the legacy of the great Mahjarrat hero, Azzanadra!") + .playerl("So... do you have any idea where they might be? I have a feeling they will be very valuable.") + .playerl("Uh, valuable as historical artefacts I mean, obviously.") + .npcl("They were stolen by warriors of the false god Zamorak generations ago. When you find the warriors, you will find the diamonds.") + .npcl("I suspect they will not willingly part with such objects of power however.") + .npc("Beware too, for these warriors are very powerful;", "they have taken the powers of the diamonds into themselves!") + .playerl("How do you mean?") + .npcl("Each diamond has an elemental quality...") + .npcl("There is the Diamond of Blood, the Diamond of Ice, the Diamond of Smoke and the Diamond of Shadow.") + .npcl("You should expect the warriors to have taken some aspect of these diamonds as their own...") + .playerl("Do you have any idea how I could track down these warriors somehow, then?") + .npcl("There is an ancient spell I know of that may spy upon such power... But it will require a few ingredients for it to work.") + .npcl("Should you be willing to get these ingredients for me, I will be able to locate the rough area where each of these warriors has taken refuge. The spell is imprecise, but it should help you get on the") + .npcl("right track in your search.") + .npcl("Is your desire for our freedom strong enough? Will you gather the ingredients for this spell for me?") + .options() + .let { optionBuilder2 -> + + optionBuilder2.option("Yes") + // The quest should jump to the next stage here, but I didn't want to write some weird if else here. + .playerl("Sure, what do you need?") + .npcl("For this spell, I will need to make some scrying glasses. I will need enough so that we can view the realm in its entirety.") + .npcl("When enchanted, the scrying glass will be able to let us view any area that has been influenced by the presence of the Diamonds of Azzanadra.") + .playerl("Okay, but what exactly do you need for this spell?") + .npcl("Well, six scrying glasses should be sufficient. For each scrying glass, I will need two magic logs, a steel bar and some molten glass. This makes a total of 12 magic logs, 6 pieces of molten") + .npcl("glass, and 6 steel bars.") + .npcl("In addition, for the actual spell to enchant the glasses, I will require one set of normal bones, some ash, some charcoal and a single blood rune.") + .npcl("Do you understand me, adventurer?") + .playerl("Quick question; what kind of bones do you need?") + .npcl("Standard bones. Other types of bones are of no use to me in this spell.") + .options() + .let { optionBuilder3 -> + optionBuilder3.option("Yes, I will go get those for you.") + .playerl("It's a slightly odd collection of ingredients, but I shouldn't have too much trouble getting those for you.") + .endWith { _, player -> + if(getQuestStage(player, DesertTreasure.questName) == 6) { + setQuestStage(player, DesertTreasure.questName, 7) + } + } + + optionBuilder3.option("No, please repeat those ingredients.") + .npcl("Before I can complete the spell I will still need the following items;") + .npc("12 magic logs", "6 steel bars", "6 molten glass") + .npc("1 bones,", "1 ashes,", "1 charcoal", "and 1 blood rune.") // This is sic authentic trash dialogue. + .endWith { _, player -> + if(getQuestStage(player, DesertTreasure.questName) == 6) { + setQuestStage(player, DesertTreasure.questName, 7) + } + } + + } + + optionBuilder2.option("No") + .playerl("Actually I don't feel like going on a shopping trip for you right now.") + .npcl("As you wish. I should have known not to get my hopes up that our long cursed life may soon be at an end...") + .end() + } + + optionBuilder.option("Nothing thanks.") + .playerl("Actually, there was nothing I really wanted to ask you about.") + .npcl("Yes, it is exactly like your sort to waste my time in such a way.") + .end() + } + + b.onQuestStages(DesertTreasure.questName, 7) + // Branch to check + + .branch { player -> + return@branch if (checkAllGiven(player)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(1) + .npcl("Excellent! Those are all the ingredients I need to create the scrying glasses.") + .npcl("I will find a suitable spot in the desert to the East of here, and set them up. When you are ready to begin your search, please come and find me there, I will show you how to utilise the") + .npcl("mirrors to find the diamonds.") + .endWith { _, player -> + if(getQuestStage(player, DesertTreasure.questName) == 7) { + setQuestStage(player, DesertTreasure.questName, 8) + } + } + + branch.onValue(0) + .npcl("Before I can complete the spell I will still need the following items;") + .manualStage { df, player, _, _ -> + df.interpreter!!.sendDialogues(npc!!.id, FacialExpression.NEUTRAL, + "" + (12 - getAttribute(player, DesertTreasure.attributeCountMagicLogs, 0)) + " magic logs", + "" + (6 - getAttribute(player, DesertTreasure.attributeCountSteelBars, 0)) + " steel bars", + "" + (6 - getAttribute(player, DesertTreasure.attributeCountMoltenGlass, 0)) + " molten glass") + } + .manualStage { df, player, _, _ -> + df.interpreter!!.sendDialogues(npc!!.id, FacialExpression.NEUTRAL, + "" + (1 - getAttribute(player, DesertTreasure.attributeCountBones, 0)) + " bones,", + "" + (1 - getAttribute(player, DesertTreasure.attributeCountAshes, 0)) + " ashes,", + "" + (1 - getAttribute(player, DesertTreasure.attributeCountCharcoal, 0)) + " charcoal", + "and " + (1 - getAttribute(player, DesertTreasure.attributeCountBloodRune, 0)) + " blood rune.") // This is sic authentic trash dialogue. + } + .end() + } + + b.onQuestStages(DesertTreasure.questName, 8,9,10) + .npcl("Meet me again in the desert East of here, I will use these ingredients to create a scrying glass for you.") + .end() + + b.onQuestStages(DesertTreasure.questName, 100) + .npcl("Meet me again in the desert East of here.") + .end() + + } +} + +class EblisCollectionsListeners : InteractionListener { + override fun defineListeners() { + + onUseWith(IntType.NPC, intArrayOf(Items.MAGIC_LOGS_1513, Items.MAGIC_LOGS_1514), NPCs.EBLIS_1923) { player, used, with -> + for(i in 0..11) { + if (inInventory(player, used.id)) { + if (getAttribute(player, DesertTreasure.attributeCountMagicLogs, 0) < 12) { + if (removeItem(player, used.id)) { + setAttribute(player, DesertTreasure.attributeCountMagicLogs, + getAttribute(player, DesertTreasure.attributeCountMagicLogs, 0) + 1) + sendMessage(player, "You hand over a magic log.") + } + } else { + break + } + } else { + break + } + } + return@onUseWith true + } + + onUseWith(IntType.NPC, intArrayOf(Items.STEEL_BAR_2353, Items.STEEL_BAR_2354), NPCs.EBLIS_1923) { player, used, with -> + for(i in 0..5) { + if (inInventory(player, used.id)) { + if (getAttribute(player, DesertTreasure.attributeCountSteelBars, 0) < 6) { + if (removeItem(player, used.id)) { + setAttribute(player, DesertTreasure.attributeCountSteelBars, + getAttribute(player, DesertTreasure.attributeCountSteelBars, 0) + 1) + sendMessage(player, "You hand over a steel bar.") + } + } else { + break + } + } else { + break + } + } + return@onUseWith true + } + + onUseWith(IntType.NPC, intArrayOf(Items.MOLTEN_GLASS_1775, Items.MOLTEN_GLASS_1776), NPCs.EBLIS_1923) { player, used, with -> + for(i in 0..5) { + if (inInventory(player, used.id)) { + if (getAttribute(player, DesertTreasure.attributeCountMoltenGlass, 0) < 6) { + if (removeItem(player, used.id)) { + setAttribute(player, DesertTreasure.attributeCountMoltenGlass, + getAttribute(player, DesertTreasure.attributeCountMoltenGlass, 0) + 1) + sendMessage(player, "You hand over some molten glass.") + } + } else { + break + } + } else { + break + } + } + return@onUseWith true + } + + onUseWith(IntType.NPC, intArrayOf(Items.BONES_526, Items.BONES_527), NPCs.EBLIS_1923) { player, used, with -> + if (getAttribute(player, DesertTreasure.attributeCountBones, 0) < 1) { + if (removeItem(player, used.id)) { + setAttribute(player, DesertTreasure.attributeCountBones, + getAttribute(player, DesertTreasure.attributeCountBones, 0) + 1) + sendNPCDialogue(player, NPCs.EBLIS_1923, "Thank you, those are enough bones for the spell.") + } + } + return@onUseWith true + } + + onUseWith(IntType.NPC, intArrayOf(Items.ASHES_592, Items.ASHES_593), NPCs.EBLIS_1923) { player, used, with -> + if (getAttribute(player, DesertTreasure.attributeCountAshes, 0) < 1) { + if (removeItem(player, used.id)) { + setAttribute(player, DesertTreasure.attributeCountAshes, + getAttribute(player, DesertTreasure.attributeCountAshes, 0) + 1) + sendNPCDialogue(player, NPCs.EBLIS_1923, "Thank you, that is enough ash for the spell.") + } + } + return@onUseWith true + } + + onUseWith(IntType.NPC, intArrayOf(Items.CHARCOAL_973, Items.CHARCOAL_974), NPCs.EBLIS_1923) { player, used, with -> + if (getAttribute(player, DesertTreasure.attributeCountCharcoal, 0) < 1) { + if (removeItem(player, used.id)) { + setAttribute(player, DesertTreasure.attributeCountCharcoal, + getAttribute(player, DesertTreasure.attributeCountCharcoal, 0) + 1) + sendNPCDialogue(player, NPCs.EBLIS_1923, "Thank you, that is enough charcoal for the spell.") + } + } + return@onUseWith true + } + + onUseWith(IntType.NPC, intArrayOf(Items.BLOOD_RUNE_565), NPCs.EBLIS_1923) { player, used, with -> + if (getAttribute(player, DesertTreasure.attributeCountBloodRune, 0) < 1) { + if (removeItem(player, used.id)) { + setAttribute(player, DesertTreasure.attributeCountBloodRune, + getAttribute(player, DesertTreasure.attributeCountBloodRune, 0) + 1) + sendNPCDialogue(player, NPCs.EBLIS_1923, "Thank you, that blood rune should be sufficient for the spell.") + } + } + return@onUseWith true + } + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/EblisMirrorsDialogue.kt b/Server/src/main/content/region/desert/quest/deserttreasure/EblisMirrorsDialogue.kt new file mode 100644 index 0000000..43bec25 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/EblisMirrorsDialogue.kt @@ -0,0 +1,127 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class EblisMirrorsDialogue(player: Player? = null) : DialoguePlugin(player){ + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player!!, EblisMirrorsDialogueFile(), npc) + return false + } + override fun newInstance(player: Player?): DialoguePlugin { + return EblisMirrorsDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.EBLIS_1924, NPCs.EBLIS_1925) + } +} +class EblisMirrorsDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + + b.onQuestStages(DesertTreasure.questName, 8) + .npcl("Ah, so you got here at last.") + .npc("As you may noticed, I have made the mirrors for", "the spell, and cast the enchantment upon them.") + .npc("By simply looking into each mirror, you will be able to", "see the area where the trace magics from the Diamonds", "of Azzanadra are emanating from.") + .npc("Unfortunately, I cannot narrow the search closer with", "this kind of spell, but if you search the areas shown to", "you, you may be able to find some clues leading you to", "the evil warriors of Zamorak who stole the diamonds in") + .npc("the first place.") + .player(FacialExpression.THINKING, "So you can't be anymore specific about where to look", "for these warriors and their diamonds?") + .npc("I'm afraid not, other than the direction that the mirror", "is facing will be approximately the direction you will", "need to head in.") + .npc("Make sure to come and speak to me when you have", "retrieved all four diamonds.") + .endWith { _, player -> + if (getQuestStage(player, DesertTreasure.questName) == 8) { + setQuestStage(player, DesertTreasure.questName, 9) + } + } + + b.onQuestStages(DesertTreasure.questName, 9, 10) + .branch { player -> + return@branch if (DesertTreasure.completedAllSubstages(player)) { + 1 + } else { + 0 + } + }.let { branch -> + branch.onValue(1) + .player(FacialExpression.THINKING, "So I have all four of these Diamonds of Azzanadra, now", "what?") + .npc("Azzanadra was our greatest ever hero.", "He was unkillable, and the cowardly traitors who stole", "our lands did not know what to do with him, for his", "hatred for them was as strong as his magics.") + .npc(FacialExpression.SAD, "In the end, they cast a spell upon him, to trap him in", "the stone structure to the South of here.") + .npc(FacialExpression.ANNOYED, "They stole his very life force, the essence of his power,", "and trapped it within four crystals - the very same", "Four Diamonds which you have now recovered from", "the brigands who stole from us.") + .npc(FacialExpression.ANNOYED, "The four pillars surrounding the structure are keeping", "the containment spell intact.", "By placing a diamond into each, you will breach the", "magical defenses and begin to restore Azzanadra's") + .npcl(FacialExpression.ANNOYED, "power, and be able to enter the structure.") + .npcl("Go, place the diamonds, and free my lord Azzanadra!") + .npc(FacialExpression.FRIENDLY, "The path will be hard, for his prison is full of traps", "and danger to prevent his rescue, but he will reward you", "beyond your wildest dreams when freed!") + .npc("Quickly...", "After all these centuries, Lord Azzanadra is nearly free!", "You must spare no time, place the Diamonds upon the", "pillars and enter the pyramid so that you may free him!") + .end() + + branch.onValue(0) + .playerl("So can you give me any help on where to find these warriors and their diamonds?") + .npcl("No, the magic used in this spell is powerful, but inaccurate. The direction the scrying glass faces is roughly the direction you will find the warrior, but I'm afraid I") + .npcl("can't be any more help than that.") + .playerl("I don't understand why there are six mirrors when there are only four diamonds...") + .npcl("As I say, the enchantment is very inaccurate.") + .npcl("I can only focus upon the aura the diamonds have left behind them, so any place where the Diamonds were present for a significant period of time will still be shown - such as the Bandit Camp where I make my home.") + .npcl("My apologies, but magic is an inaccurate art in many respects.") + .npcl("Don't forget to come back here when you have collected all four diamonds.") + .end() + } + + b.onQuestStages(DesertTreasure.questName, 100) + .branch { player -> + if (inInventory(player, Items.ANCIENT_STAFF_4675)) { + 1 + } else { + 0 + } + }.let { branch -> + branch.onValue(1) + .playerl("Hello again.") + .npcl("Greetings. I await the return of my Lord Azzanadra and of our god. I do not know why, but I feel this spot has some significance...") + .end() + + branch.onValue(0) + .npcl("So have you spoken to my Lord Azzanadra yet?") + .playerl("Yes I have.") + .npcl("And what words did he have for his followers?") + .playerl("Er... He didn't really mention you at all, but he did teach me some cool new magic spells.") + .npcl("It is understandable perhaps... His poor mind must be addled after all of those years of confinement, he would not willingly ignore his followers...") + .npcl("Anyway, if he has taught you our ancient magics, you may be interested in purchasing an ancient heirloom that was passed down to me. My ancestor fought in the ancient battles using the") + .npcl("magic of our god. This heirloom will help you with the speed of your spell-casting.") + .npcl("Normally I could not bear to part with such a priceless relic, but for your help in freeing my Lord Azzanadra, I will be prepared to sell it to you for a mere 80,000 gold.") + .npcl("Are you interested?") + .options() + .let { optionBuilder -> + optionBuilder.option("Yes please") + .branch { player -> + if (inInventory(player, Items.COINS_995, 80000)) { 1 } else { 0 } + } + .let { branch2 -> + branch2.onValue(1) + .npcl("Take care of it, it is the only heirloom from those times I possess, although rumour has it many of our ancient warriors were buried with identical weapons so that they could continue to fight for my Lord in their deaths.") + .endWith { _, player -> + if (removeItem(player, Item(Items.COINS_995, 80000))) { + addItemOrDrop(player, Items.ANCIENT_STAFF_4675) + } + } + + branch2.onValue(0) + .linel("You don't have enough money to buy that.") + .end() + } + + optionBuilder.option("No thanks") + .playerl("No, not really.") + .npcl("As you wish. Bear my offer in mind should you ever change your decision, I will remain here.") + .end() + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/FareedBehavior.kt b/Server/src/main/content/region/desert/quest/deserttreasure/FareedBehavior.kt new file mode 100644 index 0000000..be98d96 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/FareedBehavior.kt @@ -0,0 +1,76 @@ +package content.region.desert.quest.deserttreasure + +import content.global.skill.magic.modern.WaterSpell +import core.api.* +import core.game.container.impl.EquipmentContainer +import core.game.global.action.EquipHandler +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class FareedBehavior : NPCBehavior(NPCs.FAREED_1977) { + + var clearTime = 0 + + override fun canBeAttackedBy(self: NPC, attacker: Entity, style: CombatStyle, shouldSendMessage: Boolean): Boolean { + if (attacker is Player) { + if (attacker == getAttribute(self, "target", null)) { + return true + } + sendMessage(attacker, "It's not after you...") + } + return false + } + + override fun tick(self: NPC): Boolean { + val player: Player? = getAttribute(self, "target", null) + if (clearTime++ > 800) { + clearTime = 0 + if (player != null) { + sendMessage(player, "Fareed has lost interest in you, and returned to his flames.") + removeAttribute(player, DesertTreasure.attributeFareedInstance) + } + poofClear(self) + } + return true + } + + override fun beforeDamageReceived(self: NPC, attacker: Entity, state: BattleState) { + if (state.style == CombatStyle.MAGIC && state.spell !is WaterSpell) { + state.neutralizeHits() + } + } + + override fun beforeAttackFinalized(self: NPC, victim: Entity, state: BattleState) { + if (victim is Player) { + if (!inEquipment(victim, Items.ICE_GLOVES_1580)) { + val weapon = getItemFromEquipment(victim, EquipmentSlot.WEAPON) + if(weapon != null) { + EquipHandler.unequip(victim, EquipmentContainer.SLOT_WEAPON, weapon.id) + } +// val weapon = getItemFromEquipment(victim, EquipmentSlot.WEAPON) +// if(weapon != null && removeItem(victim, weapon.id, Container.EQUIPMENT)) { +// addItemOrDrop(victim, weapon.id) +// } + sendMessage(victim, "The heat from the warrior causes you to drop your weapon.") + } + } + } + + override fun onDeathFinished(self: NPC, killer: Entity) { + if (killer is Player) { + addItemOrDrop(killer, Items.SMOKE_DIAMOND_4672) + sendMessage(killer, "You take the Diamond of Smoke from the ashes of the warrior.") + if (DesertTreasure.getSubStage(killer, DesertTreasure.attributeSmokeStage) == 1) { + DesertTreasure.setSubStage(killer, DesertTreasure.attributeSmokeStage, 100) + removeAttribute(killer, DesertTreasure.attributeFareedInstance) + } + } + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/FatherAndMotherTrollBehavior.kt b/Server/src/main/content/region/desert/quest/deserttreasure/FatherAndMotherTrollBehavior.kt new file mode 100644 index 0000000..5b4eeed --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/FatherAndMotherTrollBehavior.kt @@ -0,0 +1,75 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.dialogue.FacialExpression +import core.game.interaction.QueueStrength +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import org.rs09.consts.NPCs + +class FatherTrollBehavior : NPCBehavior(NPCs.ICE_TROLL_1943 /** WRONG NAME ITS ICE_BLOCK */) { + + override fun canBeAttackedBy(self: NPC, attacker: Entity, style: CombatStyle, shouldSendMessage: Boolean): Boolean { + return attacker is Player + } + override fun beforeDamageReceived(self: NPC, attacker: Entity, state: BattleState) { + if (attacker is Player) { + self.properties.combatPulse.stop() + attacker.properties.combatPulse.stop() + if (state.estimatedHit + Integer.max(state.secondaryHit, 0) >= self.skills.lifepoints) { + state.estimatedHit = self.skills.lifepoints + 1 + state.secondaryHit = -1 + self.skills.lifepoints = self.skills.maximumLifepoints // Reset life of ice block + + setVarbit(attacker, DesertTreasure.varbitFrozenFather, 1) + if (getVarbit(attacker, DesertTreasure.varbitFrozenMother) == 1) { + setVarbit(attacker, DesertTreasure.varbitChildReunite, 4) + queueScript(self, 1, QueueStrength.NORMAL) { stage: Int -> + openDialogue(attacker, ChatFatherAndMotherTrollDialogueFile()) + return@queueScript stopExecuting(self) + } + } else { + queueScript(self, 1, QueueStrength.NORMAL) { stage: Int -> + sendNPCDialogue(attacker, NPCs.TROLL_FATHER_1948, "Oh thank you! It was really cold in there! But please, you must free my wife as well! Our son is depending on us!", FacialExpression.OLD_CALM_TALK2) + return@queueScript stopExecuting(self) + } + } + } + } + } +} + +class MotherTrollBehavior : NPCBehavior(NPCs.ICE_BLOCK_1945) { + override fun canBeAttackedBy(self: NPC, attacker: Entity, style: CombatStyle, shouldSendMessage: Boolean): Boolean { + return attacker is Player + } + override fun beforeDamageReceived(self: NPC, attacker: Entity, state: BattleState) { + if (attacker is Player) { + self.properties.combatPulse.stop() + attacker.properties.combatPulse.stop() + if (state.estimatedHit + Integer.max(state.secondaryHit, 0) >= self.skills.lifepoints) { + state.estimatedHit = self.skills.lifepoints + 1 + state.secondaryHit = -1 + self.skills.lifepoints = self.skills.maximumLifepoints // Reset life of ice block + + setVarbit(attacker, DesertTreasure.varbitFrozenMother, 1) + if (getVarbit(attacker, DesertTreasure.varbitFrozenFather) == 1) { + setVarbit(attacker, DesertTreasure.varbitChildReunite, 4) + queueScript(self, 1, QueueStrength.NORMAL) { stage: Int -> + openDialogue(state.attacker!!.asPlayer(), ChatFatherAndMotherTrollDialogueFile()) + return@queueScript stopExecuting(self) + } + } else { + queueScript(self, 1, QueueStrength.NORMAL) { stage: Int -> + sendNPCDialogue(attacker, NPCs.TROLL_MOTHER_1950, "Wow, thanks for breaking me out of that ice! But please, my husband is still trapped in there!", FacialExpression.OLD_CALM_TALK2) + return@queueScript stopExecuting(self) + } + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/FatherAndMotherTrollDialogue.kt b/Server/src/main/content/region/desert/quest/deserttreasure/FatherAndMotherTrollDialogue.kt new file mode 100644 index 0000000..a83eded --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/FatherAndMotherTrollDialogue.kt @@ -0,0 +1,170 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.dialogue.* +import core.game.interaction.QueueStrength +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.Components +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +// Base: 1943 Iced: 1944 Broke: 1948 Reunion: 1947 +// Base: 1945 Iced: 1946 Broke: 1950 Reunion: 1949 + +@Initializable +class FatherTrollDialogue(player: Player? = null) : DialoguePlugin(player){ + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + if (DesertTreasure.getSubStage(player, DesertTreasure.attributeIceStage) == 3 && + getVarbit(player, DesertTreasure.varbitFrozenFather) == 1 && + getVarbit(player, DesertTreasure.varbitFrozenMother) == 1) { + openDialogue(player!!, ChatFatherAndMotherTrollDialogueFile(), npc) + } else if (DesertTreasure.getSubStage(player, DesertTreasure.attributeIceStage) == 3) { + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> npcl(FacialExpression.OLD_CALM_TALK2, "Oh thank you! It was really cold in there! But please, you must free my wife as well! Our son is depending on us!").also { stage = END_DIALOGUE } + } + } + }, npc) + } else if (DesertTreasure.getSubStage(player, DesertTreasure.attributeIceStage) == 4) { + openDialogue(player!!, ChatFatherAndMotherTrollAfterDialogueFile(), npc) + } else if ((getQuestStage(player, DesertTreasure.questName) == 9 && + DesertTreasure.getSubStage(player, DesertTreasure.attributeIceStage) >= 5) || + getQuestStage(player, DesertTreasure.questName) >= 10) { + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> npcl(FacialExpression.OLD_CALM_TALK2, "Thanks again for freeing me from that ice block! I might be a troll, but it was real uncomfortable in there!").also { stage = END_DIALOGUE } + } + } + }, npc) + } + return false + } + override fun newInstance(player: Player?): DialoguePlugin { + return FatherTrollDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(1943) + } +} + +@Initializable +class MotherTrollDialogue(player: Player? = null) : DialoguePlugin(player){ + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + println(getQuestStage(player, DesertTreasure.questName) == 9 && + DesertTreasure.getSubStage(player, DesertTreasure.attributeIceStage) >= 5) + if (DesertTreasure.getSubStage(player, DesertTreasure.attributeIceStage) == 3 && + getVarbit(player, DesertTreasure.varbitFrozenFather) == 1 && + getVarbit(player, DesertTreasure.varbitFrozenMother) == 1) { + openDialogue(player!!, ChatFatherAndMotherTrollDialogueFile(), npc) + } else if (DesertTreasure.getSubStage(player, DesertTreasure.attributeIceStage) == 3) { + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> npcl(FacialExpression.OLD_CALM_TALK2, "Wow, thanks for breaking me out of that ice! But please, my husband is still trapped in there!").also { stage = END_DIALOGUE } + } + } + }, npc) + } else if (DesertTreasure.getSubStage(player, DesertTreasure.attributeIceStage) == 4) { + openDialogue(player!!, ChatFatherAndMotherTrollAfterDialogueFile(), npc) + } else if ((getQuestStage(player, DesertTreasure.questName) == 9 && + DesertTreasure.getSubStage(player, DesertTreasure.attributeIceStage) >= 5) || + getQuestStage(player, DesertTreasure.questName) >= 10) { + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> npcl(FacialExpression.OLD_CALM_TALK2, "Thanks again for freeing me from that ice block! I don't know what my little snookums would have done without us!").also { stage = END_DIALOGUE } + } + } + }, npc) + } + return false + } + override fun newInstance(player: Player?): DialoguePlugin { + return MotherTrollDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.TROLL_MOTHER_1950) + } +} + +class ChatFatherAndMotherTrollDialogueFile : DialogueFile() { + // We gon do like this as the old way allows to easily jump between npcs. + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> npcl(NPCs.TROLL_FATHER_1948, FacialExpression.OLD_CALM_TALK2, "Phew! Am I glad to be out of that big ice cube! Are you okay too darling?").also { stage++ } + 1 -> npcl(NPCs.TROLL_MOTHER_1950, FacialExpression.OLD_CALM_TALK2, "Yes, I thought we were done for! Why ever did that nasty Kamil freeze us up there anyway?").also { stage++ } + 2 -> playerl("He must have been trying to protect his Diamond...").also { stage++ } + 3 -> npcl(NPCs.TROLL_FATHER_1948, FacialExpression.OLD_CALM_TALK2, "You mean that diamond I found the other day belonged to him? But why didn't he just ask for it back? It's not like I really want it or anything!").also { stage++ } + 4 -> npcl(NPCs.TROLL_FATHER_1948, FacialExpression.OLD_CALM_TALK2, "And how did you know we had that diamond anyway, fleshy?").also { stage++ } + 5 -> playerl("Your son told me. That's why I rescued you, it is very important that I have that diamond...").also { stage++ } + 6 -> npcl(NPCs.TROLL_MOTHER_1950, FacialExpression.OLD_CALM_TALK2, "Ooohhhhh, my poor baby! He must have been so worried about us...").also { stage++ } + 7 -> npcl(NPCs.TROLL_FATHER_1948, FacialExpression.OLD_CALM_TALK2, "Yes, but he certainly inherited his Dad's smarts!").also { stage++ } + 8 -> npcl(NPCs.TROLL_FATHER_1948, FacialExpression.OLD_CALM_TALK2, "If he'd told this fleshy that he had the Diamond and not us, we might never have been rescued!").also { stage++ } + 9 -> playerl("Wait... what? That stupid little troll kid had the diamond all along?").also { stage++ } + 10 -> npcl(NPCs.TROLL_MOTHER_1950, FacialExpression.OLD_CALM_TALK2, "Don't you talk about my baby like that!").also { stage++ } + 11 -> npcl(NPCs.TROLL_FATHER_1948, FacialExpression.OLD_CALM_TALK2, "Now, now dear, all's well that ends well. We've been freed and this fleshy has certainly earned himself that diamond.").also { stage++ } + 12 -> npcl(NPCs.TROLL_FATHER_1948, FacialExpression.OLD_CALM_TALK2, "Let's get out of this terrible place and see our son!").also { + stage++ + if (DesertTreasure.getSubStage(player!!, DesertTreasure.attributeIceStage) == 3) { + DesertTreasure.setSubStage(player!!, DesertTreasure.attributeIceStage, 4) + } + } + + 13 -> { + queueScript(player!!, 0, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + closeOverlay(player!!) + openOverlay(player!!, Components.FADE_TO_BLACK_120) + return@queueScript delayScript(player!!, 6) + } + 1 -> { + teleport(player!!, Location(2836, 3739, 0)) + return@queueScript delayScript(player!!, 1) + } + 2 -> { + openOverlay(player!!, Components.FADE_FROM_BLACK_170) + return@queueScript delayScript(player!!, 6) + } + 3 -> { + closeOverlay(player!!) + openDialogue(player!!, ChatFatherAndMotherTrollAfterDialogueFile()) + return@queueScript stopExecuting(player!!) + } + else -> return@queueScript stopExecuting(player!!) + } + } + end() + } + } + } +} + +class ChatFatherAndMotherTrollAfterDialogueFile : DialogueFile() { + // We gon do like this as the old way allows to easily jump between npcs. + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> npcl(NPCs.TROLL_CHILD_1933, FacialExpression.OLD_CALM_TALK2, "Mommy! Daddy! You're free!").also { stage++ } + 1 -> npc(NPCs.TROLL_FATHER_1948, FacialExpression.OLD_CALM_TALK1, "That's right son, and it's all thanks to this brave", "adventurer here.", "Now, make sure you hand over that diamond he was", "looking for.").also { stage++ } + 2 -> npcl(NPCs.TROLL_FATHER_1948, FacialExpression.OLD_CALM_TALK1, "It has been nothing but trouble for us, let's just get back to our cave and have dinner.").also { stage++ } + 3 -> npcl(NPCs.TROLL_MOTHER_1950, FacialExpression.OLD_CALM_TALK2, "That's right son, it's your favorite tonight too! A big plate of raw mackerel!").also { stage++ } + 4 -> npcl(NPCs.TROLL_CHILD_1933, FacialExpression.OLD_CALM_TALK2, "RAW MACKEREL! YUMMY!").also { stage++ } + 5 -> npcl(NPCs.TROLL_CHILD_1933, FacialExpression.OLD_CALM_TALK1, "Here ya go mister! Thanks for getting my mom and dad away from the bad man!").also { + stage++ + if (DesertTreasure.getSubStage(player!!, DesertTreasure.attributeIceStage) in 3 .. 4) { + addItemOrDrop(player!!, Items.ICE_DIAMOND_4671) + DesertTreasure.setSubStage(player!!, DesertTreasure.attributeIceStage, 100) + } + } + 6 -> playerl("Don't worry about it, just as long as I don't have to go back into that blizzard.").also { + stage = END_DIALOGUE + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/IceTrollBehavior.kt b/Server/src/main/content/region/desert/quest/deserttreasure/IceTrollBehavior.kt new file mode 100644 index 0000000..1146559 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/IceTrollBehavior.kt @@ -0,0 +1,35 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import org.rs09.consts.NPCs + +class IceTrollBehavior : NPCBehavior(*iceTrollIds) { + companion object { + private val iceTrollIds = intArrayOf( + NPCs.ICE_TROLL_1936, + NPCs.ICE_TROLL_1937, + NPCs.ICE_TROLL_1938, + NPCs.ICE_TROLL_1939, + NPCs.ICE_TROLL_1940, + NPCs.ICE_TROLL_1941, + NPCs.ICE_TROLL_1942, + ) + } + + override fun onDeathFinished(self: NPC, killer: Entity) { + if (killer is Player) { + if (getQuestStage(killer, DesertTreasure.questName) >= 9) { + val currentIceTrollKill = getAttribute(killer, DesertTreasure.attributeTrollKillCount, 0) + if (currentIceTrollKill < 5) { + setAttribute(killer, DesertTreasure.attributeTrollKillCount, currentIceTrollKill + 1) + setVarbit(killer, DesertTreasure.varbitCaveEntrance, getAttribute(killer, DesertTreasure.attributeTrollKillCount, 0)) + sendMessage(killer, "A chunk of ice falls away from the cave entrance...") + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/IceTrollDialogue.kt b/Server/src/main/content/region/desert/quest/deserttreasure/IceTrollDialogue.kt new file mode 100644 index 0000000..ac37cb4 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/IceTrollDialogue.kt @@ -0,0 +1,35 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class IceTrollDialogue (player: Player? = null) : DialoguePlugin(player){ + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player!!, IceTrollDialogueFile(), npc) + return false + } + override fun newInstance(player: Player?): DialoguePlugin { + return IceTrollDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.ICE_TROLL_1935) + } + +} +class IceTrollDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + + b.onPredicate { _ -> true } + .npc(FacialExpression.OLD_LAUGH1, "Hur hur hur!", "Well look here, a puny fleshy human!") + .npc(FacialExpression.OLD_LAUGH1, "You should beware of the icy wind that runs through", "this valley, it will bring a fleshy like you to a cold end", "indeed!") + .end() + } + +} diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/KamilBehavior.kt b/Server/src/main/content/region/desert/quest/deserttreasure/KamilBehavior.kt new file mode 100644 index 0000000..e5ddbda --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/KamilBehavior.kt @@ -0,0 +1,79 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.combat.* +import core.game.node.entity.combat.equipment.SwitchAttack +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import core.game.world.update.flag.context.Animation +import core.tools.RandomFunction +import org.rs09.consts.NPCs + +// https://www.youtube.com/watch?v=xeu6Ncmt1fY + +class KamilBehavior : NPCBehavior(NPCs.KAMIL_1913) { + + var clearTime = 0 + + override fun canBeAttackedBy(self: NPC, attacker: Entity, style: CombatStyle, shouldSendMessage: Boolean): Boolean { + if (attacker is Player) { + if (attacker == getAttribute(self, "target", null)) { + return true + } + sendMessage(attacker, "It's not after you...") + } + return false + } + + override fun tick(self: NPC): Boolean { + val player: Player? = getAttribute(self, "target", null) + if (clearTime++ > 800) { + clearTime = 0 + if (player != null) { + sendMessage(player, "Kamil vanishes on an icy wind...") + removeAttribute(player, DesertTreasure.attributeKamilInstance) + } + poofClear(self) + } + return true + } + + override fun onDeathFinished(self: NPC, killer: Entity) { + if (killer is Player) { + if (DesertTreasure.getSubStage(killer, DesertTreasure.attributeIceStage) == 2) { + DesertTreasure.setSubStage(killer, DesertTreasure.attributeIceStage, 3) + removeAttribute(killer, DesertTreasure.attributeKamilInstance) + sendPlayerDialogue(killer, "Well, that must have been the 'bad man' that the troll kid was on about... His parents must be up ahead somewhere.") + } + } + } + + override fun getSwingHandlerOverride(self: NPC, original: CombatSwingHandler): CombatSwingHandler { + return KamilCombatHandler() + } +} + +// All these combat shit is the most trash level thing to use or decipher. +class KamilCombatHandler: MultiSwingHandler( + SwitchAttack(CombatStyle.MELEE.swingHandler, null), +) { + override fun impact(entity: Entity?, victim: Entity?, state: BattleState?) { + if (victim is Player) { + // This is following RevenantCombatHandler.java, no idea if this is good. + // I can't be bothered to fix fucking frozen. The player can hit through frozen. What the fuck is frozen for then, to glue his fucking legs??? + if (RandomFunction.roll(3) && !hasTimerActive(victim, "frozen") && !hasTimerActive(victim, "frozen:immunity")) { + registerTimer(victim, spawnTimer("frozen", 7, true)) + sendMessage(victim, "You've been frozen!") + sendChat(entity as NPC, "Sallamakar Ro!") // Salad maker roll. + sendGraphics(539, victim.location) + victim.properties.combatPulse.stop() // Force the victim to stop fighting. Whatever. + // Audio? + }else { + animate(entity!!, Animation(440)) + } + } + super.impact(entity, victim, state) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/MalakDialogue.kt b/Server/src/main/content/region/desert/quest/deserttreasure/MalakDialogue.kt new file mode 100644 index 0000000..37ccfdc --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/MalakDialogue.kt @@ -0,0 +1,262 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.combat.ImpactHandler.HitsplatType +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class MalakDialogue(player: Player? = null) : DialoguePlugin(player){ + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player!!, MalakDialogueFile(), npc) + return false + } + override fun newInstance(player: Player?): DialoguePlugin { + return MalakDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.MALAK_1920) + } +} + +class MalakDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onQuestStages(DesertTreasure.questName, 0,1,2,3,4,5,6,7,8) + .npc("Away from me, dog.", "I have business to discuss with the barkeeper.") + .end() + + + b.onQuestStages(DesertTreasure.questName, 9) + .branch { player -> + if (DesertTreasure.getSubStage(player, DesertTreasure.attributeBloodStage) == 1) { + return@branch 0 // Same branch as 0 + } + return@branch DesertTreasure.getSubStage(player, DesertTreasure.attributeBloodStage) + }.let { branch -> + branch.onValue(0) + .npcl("A human, eh? Give me one good reason why I should not just take you to Lord Drakan now.") + // There's a ring of charos dialogue here, but its one line and doesn't change anything... + .npcl("You had better make it a good one too, or you will not survive the night, I'll wager.") + .let { builder -> + val returnJoin = b.placeholder() + builder.goto(returnJoin) + return@let returnJoin.builder() + .options() + .let { optionBuilder -> + val continuePath = b.placeholder() + optionBuilder.option("I am here to worship Zamorak") + .playerl("I am here to worship the almighty Zamorak! Yay! Go Zamorak!") + .npcl("I see. You are a moron. You have probably settled right in with the rest of the idiots in this pathetic excuse for a village.") + .npcl("Unfortunately for you, that is not a good enough reason to explain your presence here.") + .npcl("Now tell me the reason for your coming here, or I will ensure you suffer a horrible fate indeed.") + .goto(returnJoin) + + optionBuilder.option("I am here to praise Lord Drakan") + .playerl("I am here only to serve the mighty Drakan. Yup, Drakan, he's the man.") + .npcl("I see. I would perhaps be more inclined to believe you if I could not smell the death blood of his brother Draynor upon you.") + .npcl("What are you real intentions here?") + // "If the player has not completed Vampyre Slayer" but I'm lazy again + // .npcl("Really? That is interesting, that you would want to give your life by tresspassing in this land for such an unbelievable reason.") + // .npcl("Now speak, what is your purpose in coming here?") + .goto(returnJoin) + + optionBuilder.option("I am here to worship you, oh mighty Malak") + .playerl("I am here only to serve the mighty Drakan.") + .playerl("I came here looking for you, oh mighty Malak, so that I might serve your glory.") + .npcl("Please. Do not think that I am so vain and foolish as to allow you to avoid my question with such obvious sycophancy.") + .npcl("Now tell me the reason behind your being here, or I will ensure that you suffer.") + .goto(returnJoin) + + optionBuilder.option("I am here to kill Lord Drakan") + .playerl("I am here to kill Lord Drakan, and every stinking one of his vampyre brood!") + .npcl("Hah! Most entertaining, human!") + .npcl("Now tell me the reason you are here, or we shall soon see who will be killing whom.") + .goto(returnJoin) + + optionBuilder.option("I am looking for a special Diamond...") + .playerl("I am here looking for a special diamond... I have reason to believe it is somewhere in this vicinity, and it is probably in the possession of a warrior of Zamorak.") + .playerl("I'm fairly sure it will have some kind of magical aura or something too. I don't suppose you've seen it, or know where it might be?") + .npcl("Interesting... Well perhaps we can come to a little... arrangement, human.") + .npcl("I may have information that may assist you, but you in turn will have to do something for me. What do you say? Do you think we could come to some form of") + .npcl("agreement?") + .playerl("Well, what kind of something? No offence, but you're not exactly the trustworthy type...") + .npcl("Ah, you have a healthy sense of paranoia, I see. It is not a particularly unfair request on my part...") + .npcl("All I ask is that you ensure that the current owner of the diamond is killed. For my part, I will let you know his whereabouts, and how exactly to kill him.") + .npcl("When he is dead, you may take the diamond from his corpse and do with it what you will. I have no interest in such baubles.") + .npcl("So what say you? A life for a diamond. As a mark of good faith, I will give you some information free:") + .npcl("The current owner of this diamond is named Dessous.") + .betweenStage { df, player, _, _ -> + if (DesertTreasure.getSubStage(player, DesertTreasure.attributeBloodStage) == 0) { + DesertTreasure.setSubStage(player, DesertTreasure.attributeBloodStage, 1) + } + } + .options("Agree to this arrangement?") + .let { optionBuilder2 -> + optionBuilder2.option("Yes") + .betweenStage { df, player, _, _ -> + if (DesertTreasure.getSubStage(player, DesertTreasure.attributeBloodStage) == 1) { + DesertTreasure.setSubStage(player, DesertTreasure.attributeBloodStage, 2) + } + } + .playerl("Well... I can't see any drawback. Okay, I accept your offer. Now tell me what you know.") + .goto(continuePath) + + optionBuilder2.option("No") + .playerl("I don't trust you, or anything you say. I'm afraid I have to decline.") + .npcl("As you wish human. I doubt anybody near here knows of the diamond you seek, however.") + .npcl("If you wish to claim it as your own, you have little choice but to accept my bargain. I will wait here until such time as you change your mind.") + .end() + } + return@let continuePath.builder() + } + } + .npcl("What I know? Hah! After you have been alive for as long as I, the things I know are enough to fill a library.") + .npcl("I'm afraid you will need to be a little more specific.") + .let { builder -> + val returnJoin = b.placeholder() + builder.goto(returnJoin) + returnJoin.builder() + .options() + .let { optionBuilder -> + optionBuilder.option("Why do you want Dessous dead?") + .playerl("I don't see exactly how this bargain benefits you... Why exactly do you want Dessous killed anyway?") + .npcl("That is an impertinent question to demand from myself.") + .npcl("However, if it will help seal our deal, I will let you know some of the details.") + .npcl("As you may or may not know, myself and my blood kin are the rulers of this land, all serving under Lord Drakan. However, we tend not to die of old age or similar") + .npcl("natural causes, which means that to gain another Lords tithe or land, there often need to be...") + .npcl("Unnatural causes of death involved. Let us just say, that Dessous is in control of some land that I myself would like some say in, and that it is not in my interest to be seen to be responsible for the") + .npcl("death of a fellow Lord.") + .npcl("It would however be extremely advantageous to myself should some random human adventurer take it upon themself to remove this rival for me... Do you understand?") + .playerl("Yes... I think so...") + .npcl("Good, we understand each other then. We will both benefit from the death of Dessous.") + .goto(returnJoin) + + optionBuilder.option("Where can I find Dessous?") + .playerl("Where can I find this Dessous?") + .npcl("He currently resides in a graveyard to the South-East of here. You will not be able to move the gravestone which he lies beneath however, you will need to find some way to") + .npcl("lure him out from his tomb.") + .playerl("And how exactly would I go about doing that?") + .npcl("Well, he is a vampyre, so fresh blood would almost certainly entice him out.") + .npcl("However, even though he is a frail and decrepit example of our species, he will be able to kill a weakling human such as yourself extremely easily. Having him in a bloodlust as he does so, will not make") + .npcl("your job any easier.") + .goto(returnJoin) + + optionBuilder.option("How can I kill Dessous?") + .playerl("So what advice can you give me on killing Dessous?") + .npcl("As ancient and weak as Dessous is, he is still more than a match for the likes of you.") + .npcl("That is, assuming you were to fight him fairly.") + .npcl("My proposal would be for you to even the odds up a little bit...") + .playerl("How would I go about doing that?") + .npcl("Well, my plan would be as follows. First, take a silver bar to the man living in the sewers in Draynor. He was an assistant to Count Draynor in some of his...") + .npcl("more interesting experiments many years past. Tell him you need a sacrificial offering pot. He will know what you speak of, it is a unique type of container used in various ancient vampyric ceremonies.") + .npcl("Then take the pot to Entrana and get it blessed by the Head Monk. This will lend the pot some holy power.") + .npcl("If you then bring that silver pot back to me, I will provide you with some fresh blood, to put into it. To that pot of blood, you will add some crushed garlic, and some spice to disguise the smell.") + .npcl("Use that pot of blood upon Dessous' tomb, and he will be unable to resist rising and drinking from it.") + .npcl("The combination of garlic, silver, and blessings from Saradomin will act upon him as a poison, and allow you to kill him.") + .npcl("This is just my suggestion of course, you may ignore it if you wish, although I offer no guarantees of your ability to defeat him otherwise.") + .npcl("Was there anything else you wanted?") + .goto(returnJoin) + + optionBuilder.option("Actually, I don't need to know anything.") + .playerl("Never mind, I will figure out all I need to know by myself.") + .npcl("As you wish. Come and see me when you have managed to kill Dessous.") + .end() + } + } + + branch.onValue(2) + .branch { player -> + return@branch if(inInventory(player, Items.BLESSED_POT_4659) || inInventory(player, Items.SILVER_POT_4658)) { 1 } else { 0} + }.let { branch2 -> + branch2.onValue(1) + .player("I found Ruantun in Draynors sewers.", "He made me this pot, now where can I get some fresh", "blood to fill it with?") + .betweenStage { df, player, _, _ -> + sendMessage(player, "Malak cuts you and pours some of your blood into the pot.") + if (removeItem(player, Items.SILVER_POT_4658)) { + addItemOrDrop(player, Items.SILVER_POT_4660) + } else if (removeItem(player, Items.BLESSED_POT_4659)) { + addItemOrDrop(player, Items.BLESSED_POT_4661) + } + animate(npc!!, 1264) + player.impactHandler.manualHit(player, 5, HitsplatType.NORMAL) + } + .linel("Malak cuts you and pours some of your blood into the pot.") // Supposed to be a sendMessage not a dialogue, but why... + .playerl("Ow!") + .npcl("There you go. As fresh as it gets.") + .playerl("Thanks for nothing.") + .npcl("Come and speak to me again when you have managed to kill Dessous.") + .end() + + branch2.onValue(0) + .npcl("Why are you still here? I notice Dessous still lives.") + .options() + .let { optionBuilder -> + optionBuilder.option("Where can I find Dessous?") + .playerl("Where can I find this Dessous?") + .npcl("He currently resides in a graveyard to the South-East of here. You will not be able to move the gravestone which he lies beneath however, you will need to find some way to") + .npcl("lure him out from his tomb.") + .playerl("And how exactly would I go about doing that?") + .npcl("Come and see my when you have prepared a silver ritual pot in the manner I have told you.") + .npcl("I will ensure that you get some fresh blood that you may taint with garlic and spices, to lure our Dessous.") + .end() + + optionBuilder.option("How do I kill Dessous again?") + .playerl("How am I supposed to kill Dessous again?") + .npcl("Take a silver bar to the man in the Draynor sewers. He will fashion a ritualistic pot for you, which you should then take to Entrana and get blessed.") + .npcl("When you have done that, come back here and speak to me, I will provide you with some fresh blood which you will then crush some garlic into, and then add some spices to hide the garlic.") + .npcl("In this way, you will be able to lure him from his tomb and he should be sufficiently weakened to be vulnerable to your attacks.") + .end() + + optionBuilder.option("Actually, I don't need to know anything.") + .playerl("Never mind, I will figure out all I need to know by myself.") + .npcl("As you wish. Come and see me when you have managed to kill Dessous.") + .end() + } + } + + branch.onValue(3) + .npcl("Ah, the wandering hero returns! I take it you have dispatched poor old Dessous for me?") + .playerl("Quit playing games with me, Malak. I want that diamond, and I want it now!") + .betweenStage { df, player, _, _ -> + if (DesertTreasure.getSubStage(player, DesertTreasure.attributeBloodStage) == 3) { + addItemOrDrop(player, Items.BLOOD_DIAMOND_4670) + DesertTreasure.setSubStage(player, DesertTreasure.attributeBloodStage, 100) + } + } + .npcl("Do not take that tone of voice with me, meat. You should be thankful I have allowed you your life.") + .npcl("Here, take your precious little bauble.") + .npcl("I will take that silver pot from you as well, humans are not meant to possess such artefacts. Now get out of my sight, our deal is complete, and if I see you here again I will not hesistate to take you to") + .npcl("Lord Drakan.") + .npcl("He will be extremely pleased to meet the murderer of poor Dessous, I suspect.") + .end() + + branch.onValue(100) + .branch { player -> + return@branch if(!inInventory(player, Items.BLOOD_DIAMOND_4670)) { 1 } else { 0 } + }.let { branch2 -> + branch2.onValue(1) + .playerl("Where is the Diamond of Blood? I know you have it!") + .betweenStage { df, player, _, _ -> + addItemOrDrop(player, Items.BLOOD_DIAMOND_4670) + } + .npcl("Do not take that tone of voice with me, meat. Here, take your bauble. I have no use for it.") + .end() + + branch2.onValue(0) + .npcl("Be lucky I have let you live, meat. Our deal is done, I wish no further dealing with you.") + .end() + + } + } + + b.onQuestStages(DesertTreasure.questName, 10,11,12,13,100) + .npcl("Be lucky I have let you live, meat. Our deal is done, I wish no further dealing with you.") + .end() + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/MummyNPC.kt b/Server/src/main/content/region/desert/quest/deserttreasure/MummyNPC.kt new file mode 100644 index 0000000..d5fed9d --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/MummyNPC.kt @@ -0,0 +1,18 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import org.rs09.consts.NPCs + +class MummyNPC : NPCBehavior(NPCs.MUMMY_1958) { + var clearTime = 0 + + override fun tick(self: NPC): Boolean { + if (clearTime++ > 100) { + clearTime = 0 + poofClear(self) + } + return true + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/PyramidArea.kt b/Server/src/main/content/region/desert/quest/deserttreasure/PyramidArea.kt new file mode 100644 index 0000000..2a28610 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/PyramidArea.kt @@ -0,0 +1,319 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.interaction.QueueStrength +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.world.map.Direction +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import core.tools.RandomFunction +import org.rs09.consts.Components +import org.rs09.consts.NPCs + +class PyramidArea { + companion object { + /** All The Sarcophagus Locations */ + val sarcophagusList = arrayOf( + // Level 1 + Location(2901, 4946, 3), + Location(2902, 4969, 3), + Location(2903, 4961, 3), + Location(2909, 4954, 3), + Location(2913, 4950, 3), + Location(2916, 4954, 3), + Location(2917, 4951, 3), + Location(2917, 4959, 3), + Location(2918, 4963, 3), + // Level 2 + Location(2831, 4962, 2), + Location(2837, 4970, 2), + Location(2843, 4964, 2), + Location(2847, 4947, 2), + Location(2858, 4956, 2), + Location(2858, 4973, 2), + Location(2864, 4942, 2), + Location(2868, 4948, 2), + Location(2869, 4968, 2), + // Level 3 + Location(2759, 4962, 1), + Location(2760, 4956, 1), + Location(2763, 4966, 1), + Location(2764, 4941, 1), + Location(2765, 4936, 1), + Location(2765, 4940, 1), + Location(2767, 4945, 1), + Location(2768, 4947, 1), + Location(2771, 4944, 1), + Location(2774, 4947, 1), + Location(2776, 4941, 1), + Location(2786, 4974, 1), + Location(2787, 4964, 1), + Location(2790, 4968, 1), + Location(2791, 4977, 1), + Location(2798, 4947, 1), + Location(2798, 4952, 1), + Location(2800, 4960, 1), + Location(2802, 4940, 1), + Location(2806, 4936, 1), + Location(2806, 4942, 1), + Location(2810, 4968, 1), + Location(2810, 4975, 1), + // Level 4 + Location(3208, 9315, 0), + Location(3211, 9330, 0), + Location(3217, 9295, 0), + Location(3218, 9281, 0), + Location(3221, 9313, 0), + Location(3221, 9320, 0), + Location(3221, 9324, 0), + Location(3222, 9281, 0), + Location(3225, 9308, 0), + Location(3225, 9310, 0), + Location(3226, 9312, 0), + Location(3226, 9318, 0), + Location(3227, 9288, 0), + Location(3229, 9309, 0), + Location(3231, 9297, 0), + Location(3233, 9309, 0), + Location(3234, 9297, 0), + Location(3234, 9330, 0), + Location(3236, 9302, 0), + Location(3237, 9309, 0), + Location(3240, 9312, 0), + Location(3240, 9318, 0), + Location(3241, 9282, 0), + Location(3242, 9302, 0), + Location(3246, 9282, 0), + Location(3246, 9308, 0), + Location(3246, 9324, 0), + Location(3247, 9323, 0), + Location(3249, 9293, 0), + Location(3250, 9324, 0), + Location(3251, 9323, 0), + Location(3251, 9330, 0), + Location(3251, 9337, 0), + Location(3252, 9330, 0), + Location(3252, 9337, 0), + Location(3253, 9301, 0), + Location(3254, 9324, 0), + Location(3255, 9323, 0), + Location(3255, 9330, 0), + Location(3255, 9337, 0), + Location(3256, 9330, 0), + Location(3256, 9337, 0), + Location(3257, 9289, 0), + Location(3259, 9310, 0), + Location(3259, 9313, 0), + ) + + val safeZone = ZoneBorders(3227, 9310, 3239, 9320) + + // Direction.NORTH - LEFT + // rot 0 - LEFT + // rot 1 - NORTH + // rot 2 - RIGHT + // rot 3 - SOUTH + /** Sarcophagus Opening Location (Note, they are all wrongly mapped due to Scenery) */ + fun getNewLocation(direction: Direction): Location { + return when (direction) { + Direction.NORTH -> Location(-1, 0) + Direction.WEST -> Location(0, -1) + Direction.EAST -> Location(0, 1) + Direction.SOUTH -> Location(1, 0) + else -> Location(0, 0) + } + } + + /** Sarcophagus Opening Facing (Note, they are all wrongly mapped due to Scenery) */ + fun getNewFacing(direction: Direction): Direction { + return when (direction) { + Direction.NORTH -> Direction.NORTH + Direction.WEST -> Direction.NORTH_WEST + Direction.SOUTH -> Direction.WEST + Direction.EAST -> Direction.NORTH_EAST + else -> direction + } + } + + fun nearSarcophagus(loc: Location): Location? { + for (sarcoph in sarcophagusList) { + if(loc.withinDistance(sarcoph, 3)) { + return sarcoph + } + } + return null + } + + /** Trapdoor randomly throws you out of the Pyramid. */ + fun trapdoorTrap(player: Player) { + stopWalk(player) + player.walkingQueue.reset() + forceWalk(player, Location(3233, 2887, 0), "") + lock(player, 8) + sendMessage(player, "You accidentally trigger a trap...") + // addScenery(6521, location) -> animateScenery(scenery, 1939), but 6522 does it for you. + val pitfallScenery = addScenery(6522, player.location) // Scenery - Trapdoor Scenery + animate(player, 1950) // Anim - Player Falling Animation + queueScript(player, 4, QueueStrength.SOFT) { stage -> + player.walkingQueue.reset() + when (stage) { + 0 -> { + sendGraphics(354, player.location) // Gfx - Puff of Smoke + closeOverlay(player) + openOverlay(player, Components.FADE_TO_BLACK_120) + return@queueScript delayScript(player, 2) + } + 1 -> { + removeScenery(pitfallScenery) + teleport(player, Location(3233, 2887, 0)) + sendMessage(player, "...and tumble unharmed outside the pyramid.") + closeOverlay(player) + openOverlay(player, Components.FADE_FROM_BLACK_170) + stopWalk(player) + player.walkingQueue.reset() + // animate(player, ??) // Anim - Player Getting Up https://www.youtube.com/watch?v=95OvIPFYCwg + return@queueScript delayScript(player, 3) + } + 2 -> { + player.walkingQueue.reset() + forceWalk(player, Location(3233, 2887, 0), "") + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + } + + /** Mummies randomly spawns out of a sarcophagus. */ + fun spawnMummy(player: Player, sarcophagusLocation: Location) { + val sarcophagusScenery = getScenery(sarcophagusLocation) ?: return + val locationInFront = sarcophagusScenery.location.transform(getNewLocation(sarcophagusScenery.direction)) + // There are 6 sarcophagus, 6512 - 6517 with different door designs. + // They map nicely to 6506 - 6511 and act like a door. + // 6505 is the underlying hole scenery after the door opens, but it is done for you. + replaceScenery( + sarcophagusScenery, + sarcophagusScenery.id - 6, + 5, + getNewFacing(sarcophagusScenery.direction), + locationInFront + ) + val mummyNpc = NPC(NPCs.MUMMY_1958) + mummyNpc.isRespawn = false + mummyNpc.isWalks = false + mummyNpc.isAggressive = true + mummyNpc.location = sarcophagusScenery.location + mummyNpc.init() + mummyNpc.walkingQueue.addPath(locationInFront.x, locationInFront.y) + sendChat(mummyNpc, "Rawr!") + lock(player, 1) + stopWalk(player) + queueScript(player, 2, QueueStrength.SOFT) { stage -> + stopWalk(player) + mummyNpc.walkingQueue.addPath(locationInFront.x, locationInFront.y) + mummyNpc.isWalks = true + mummyNpc.isAggressive = true + mummyNpc.attack(player) + return@queueScript stopExecuting(player) + } + + } + + /** Scarabs randomly spawns somewhere near you. */ + fun spawnScarabs(player: Player) { + stopWalk(player) + lock(player, 3) + val scarabsLocation = Location.getRandomLocation(player.location, 3, true) + sendGraphics(356, scarabsLocation) // Gfx - Cracks before scarab appears. + val scarabNpc = NPC(NPCs.SCARABS_1969) + stopWalk(player) + queueScript(player, 2, QueueStrength.STRONG) { stage -> + stopWalk(player) + when (stage) { + 0 -> { + scarabNpc.isRespawn = false + scarabNpc.isWalks = false + scarabNpc.location = scarabsLocation + scarabNpc.init() + animate(scarabNpc, 1949) // Anim - Scarabs appearing from ground. + return@queueScript delayScript(player, 3) + } + 1 -> { + scarabNpc.isWalks = true + scarabNpc.isAggressive = true + scarabNpc.attack(player) + return@queueScript stopExecuting(player) + } + } + return@queueScript stopExecuting(player) + } + } + } +} + +class PyramidAreaFirstThree: MapArea { + + override fun defineAreaBorders(): Array { + return arrayOf( + getRegionBorders(11597), + getRegionBorders(11341), + getRegionBorders(11085), + ) + } + + override fun entityStep(entity: Entity, location: Location, lastLocation: Location) { + if (entity is Player) { + val averageLevel = ( + getDynLevel(entity, Skills.AGILITY) + + getDynLevel(entity, Skills.THIEVING) + ) / 2.0 + val randomValue = RandomFunction.randomDouble(99.5) + + if ((1..20).random() == 1) { + // A mummy would jump out if you walk near a sarcophagus of 2 radius. + val sarcoph = PyramidArea.nearSarcophagus(entity.location) + if (sarcoph != null) { + PyramidArea.spawnMummy(entity, sarcoph) + } + } + + if ((1..80).random() == 2) { + PyramidArea.spawnScarabs(entity) + } + if (randomValue > averageLevel && (1..128).random() == 1) { + PyramidArea.trapdoorTrap(entity) + } + } + } +} + +class PyramidAreaFinal: MapArea { + + override fun defineAreaBorders(): Array { + return arrayOf( + getRegionBorders(12945), + ) + } + + override fun entityStep(entity: Entity, location: Location, lastLocation: Location) { + if (entity is Player) { + if (!PyramidArea.safeZone.insideBorder(entity.location)) { // Safezone is talking to Azzanadra. + if ((1..20).random() == 1) { + // A mummy would jump out if you walk near a sarcophagus of 2 radius. + val sarcoph = PyramidArea.nearSarcophagus(entity.location) + if (sarcoph != null) { + PyramidArea.spawnMummy(entity, sarcoph) + } + } + if ((1..80).random() == 2) { + PyramidArea.spawnScarabs(entity) + } + } + + // No Trapdoor For The Final Level + } + } +} diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/RasoloDialogue.kt b/Server/src/main/content/region/desert/quest/deserttreasure/RasoloDialogue.kt new file mode 100644 index 0000000..273dd5d --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/RasoloDialogue.kt @@ -0,0 +1,217 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +@Initializable +class RasoloDialogue(player: Player? = null) : DialoguePlugin(player){ + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player!!, RasoloDialogueFile(), npc) + return false + } + override fun newInstance(player: Player?): DialoguePlugin { + return RasoloDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.RASOLO_1972) + } +} + +class RasoloDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + + b.onQuestStages(DesertTreasure.questName, 0,1,2,3,4,5,6,7,8) + .npc("Greetings friend.", "I am Rasolo, the famous merchant.", "Would you care to see my wares?") + .options() + .let { optionBuilder -> + optionBuilder.option("Yes") + .endWith { _, player -> + openNpcShop(player, npc!!.id) + } + optionBuilder.option("No") + .playerl("No, not really.") + .npcl("As you wish. I will travel wherever the business takes me.") + .end() + } + + b.onPredicate { player -> + DesertTreasure.getSubStage(player, DesertTreasure.attributeShadowStage) == 0 && + getQuestStage(player, DesertTreasure.questName) >= 9 + } + .npc("Greetings friend.", "I am Rasolo, the famous merchant.", "Would you care to see my wares?") + .options() + .let { optionBuilder -> + optionBuilder.option("Yes") + .endWith { _, player -> + openNpcShop(player, npc!!.id) + } + optionBuilder.option("No") + .playerl("No, not really.") + .npcl("As you wish. I will travel wherever the business takes me.") + .end() + + optionBuilder.option("Ask about the Diamonds of Azzanadra") + .playerl("No, actually I was looking for something specific...") + .npcl("Hmmmm? And what would that be?") + .playerl("I am looking for one of the Diamonds of Azzanadra. I have reason to believe it may be somewhere around here...") + .npcl("Ahhh... The Shadow Diamond...") + .npcl("I know the object of which you speak. It is guarded by a fearsome warrior known as Damis, they say, who lives in the shadows, invisible to prying eyes...") + .playerl("How can I find this 'Damis' then?") + .npcl("Well now... perhaps we can help each other out here.") + .npcl("I have in my possession a small trinket, a ring, that allows its wearer to see the unseen...") + .playerl("How much do you want for it?") + .npcl("Ah, but it is not for sale... As such...") + .npcl("I am offering to trade it for an item that was rightfully mine, but that was stolen by a bandit named Laheeb.") + .npcl("The item is question is a gilded cross, that has some sentimental value to myself. I wish for you to recover this item for me, and I will happily let you have my ring of visibility.") + .playerl("Where can I find this Laheeb?") + .npcl("Well, as a travelling merchant I have roamed these lands for many years...") + .npcl("To the far east of here there is an area that is dry and barren like the desert... it is called...") + .playerl("Al Kharid?") + .npcl("...Yes, Al Kharid. Now to the south of Al Kharid there is a passageway, it is called the...") + .playerl("Shantay Pass.") + .npcl("...Yes. I didn't realise you had travelled there yourself.") + .npcl("Anyway, when you have gone through the Shantay Pass, you will find yourself in a hostile desert... You will need to bring water with you to keep your life. Now, to the south-west of this pass, you will find a small") + .npcl("village...") + .playerl("The Bedabin camp.") + .npcl(FacialExpression.ANNOYED, "If you know where Laheeb lives, why did you ask me?") + .playerl("I don't. Sorry, please continue.") + .npcl("Well, okay then. Anyway, south of this encampment there is an area where few have ever been... It is a village of murderous bandits, and treacherous") + .npcl("thieves... This is where Laheeb makes his home.") + .npcl("He will have hidden his stolen treasure somewhere in that village, I am sure of it. When you find his loot, you will find my gilded cross. Return it to me, and I will reward you with my ring") + .npcl("of visibility, so that you may find Damis. Does this seem fair to you?") + .options() + .let { optionBuilder2 -> + optionBuilder2.option("Yes") + .playerl("Not a problem. I'll be back with your cross before you know it.") + .endWith { _, player -> + if (DesertTreasure.getSubStage(player, DesertTreasure.attributeShadowStage) == 0) { + DesertTreasure.setSubStage(player, DesertTreasure.attributeShadowStage, 1) + } + } + optionBuilder2.option("No") + .playerl("Sounds like too much effort to me. I'll find this Damis by myself.") + .npcl("As you wish.") + .end() + } + } + + b.onPredicate { player -> + DesertTreasure.getSubStage(player, DesertTreasure.attributeShadowStage) in 1 .. 2 && + getQuestStage(player, DesertTreasure.questName) >= 9 + } + .npcl("Have you retrieved my gilded cross for me yet?") + .branch { player -> + if (DesertTreasure.getSubStage(player, DesertTreasure.attributeShadowStage) == 2 && inInventory(player, Items.GILDED_CROSS_4674)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(0) + .playerl("No, not yet...") + .npcl("Well what seems to be the problem?") + .options() + .let { optionBuilder -> + optionBuilder.option("Where can I find Laheeb?") + .playerl("Where can I find this Laheeb?") + .npcl("Well, as a travelling merchant I have roamed these lands for many years...") + .npcl("To the far east of here there is an area that is dry and barren like the desert... it is called...") + .playerl("Al Kharid?") + .npcl("...Yes, Al Kharid. Now to the south of Al Kharid there is a passageway, it is called the...") + .playerl("Shantay Pass.") + .npcl("...Yes. I didn't realise you had travelled there yourself.") + .npcl("Anyway, when you have gone through the Shantay Pass, you will find yourself in a hostile desert... You will need to bring water with you to keep your life. Now, to the south-west of this pass, you will find a small") + .npcl("village...") + .playerl("The Bedabin camp.") + .npcl("If you know where Laheeb lives, why did you ask me?") + .playerl("I don't. Sorry, please continue.") + .npcl("Well, okay then. Anyway, south of this encampment there is an area where few have ever been... It is a village of murderous bandits, and treacherous") + .npcl("thieves... This is where Laheeb makes his home.") + .end() + optionBuilder.option("Can't I just buy your ring?") + .playerl("Can't I just buy your ring?") + .npcl("No, it is not for sale. Some things are more important than money, and the return of my gilded cross is one of them.") + .end() + optionBuilder.option("Is Damis near here, then?") + .playerl("Is Damis near here, then?") + .npcl("You would be surprised to know just how close he is...") + .end() + } + branch.onValue(1) + .playerl("Yes I have!") + .npcl("Excellent, excellent. Here, take this ring. While you wear it, you will be able to see the things that live in shadows...") + .npcl("And you will be able to find the entrance to Damis' lair.") + .endWith { _, player -> + if (removeItem(player, Items.GILDED_CROSS_4674)) { + if (DesertTreasure.getSubStage(player, DesertTreasure.attributeShadowStage) == 2) { + addItemOrDrop(player, Items.RING_OF_VISIBILITY_4657) + DesertTreasure.setSubStage(player, DesertTreasure.attributeShadowStage, 3) + } + } + } + } + + b.onPredicate { player -> + DesertTreasure.getSubStage(player, DesertTreasure.attributeShadowStage) == 3 && + getQuestStage(player, DesertTreasure.questName) >= 9 + } + .npcl("So how goes your quest? Did you managed to find the Diamond you were looking for yet?") + .branch { player -> + if (inInventory(player, Items.RING_OF_VISIBILITY_4657)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(1) + .playerl("Not yet...") + .npcl("Well, his lair is very close to here. I suggest you look around for it.") + .end() + + branch.onValue(0) + .playerl("I lost that ring you gave me...") + .npcl("Then by all means, take another. Only a foolish merchant would give away his only stock!") + .endWith { _, player -> + addItem(player, Items.RING_OF_VISIBILITY_4657) + } + } + + + b.onPredicate { player -> + DesertTreasure.getSubStage(player, DesertTreasure.attributeShadowStage) > 3 && + getQuestStage(player, DesertTreasure.questName) >= 9 || getQuestStage(player, DesertTreasure.questName) >= 10 + } + .npcl("Many thanks for returning my heirloom to me, adventurer. Would you like to buy something?") + .options() + .let { optionBuilder -> + optionBuilder.option("Yes") + .endWith { _, player -> + openNpcShop(player, npc!!.id) + } + optionBuilder.option("No") + .playerl("No, not really.") + .npcl("As you wish. I will travel wherever the business takes me.") + .end() + + optionBuilder.optionIf("I lost that ring you gave me...") { player -> + return@optionIf !inInventory(player, Items.RING_OF_VISIBILITY_4657) + } + .playerl("I lost that ring you gave me...") + .npcl("Then by all means, take another. Only a foolish merchant would give away his only stock!") + .endWith { _, player -> + addItem(player, Items.RING_OF_VISIBILITY_4657) + } + } + + } +} + +class RasoloTradeListeners : InteractionListener { + override fun defineListeners() { + on(NPCs.RASOLO_1972, NPC, "trade") { player, node -> + openNpcShop(player, node.id) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/RuantunDialogue.kt b/Server/src/main/content/region/desert/quest/deserttreasure/RuantunDialogue.kt new file mode 100644 index 0000000..89fa635 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/RuantunDialogue.kt @@ -0,0 +1,83 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class RuantunDialogue(player: Player? = null) : DialoguePlugin(player){ + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player!!, RuantunDialogueFile(), npc) + return false + } + override fun newInstance(player: Player?): DialoguePlugin { + return RuantunDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.RUANTUN_1916) + } +} + +class RuantunDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + + b.onQuestStages(DesertTreasure.questName, 0,1,2,3,4,5,6,7,8) + .playerl("Hello.") + .npcl(FacialExpression.OLD_NORMAL, "You ssshould not be down here...") + .options() + .let { optionBuilder -> + optionBuilder.option("Who are you?") + .playerl("Who are you?") + .npcl(FacialExpression.OLD_NORMAL, "My name isss unimportant... I live only to ssserve my massster.") + .playerl("Um... Okay then.") + .end() + + optionBuilder.option("Why are you down here?") + .playerl("Why are you down here?") + .npcl(FacialExpression.OLD_NORMAL, "Thisss isss where I belong... Beingsss sssuch as myssself cannot abide in the light... It is in the darknesss where we find our homesss...") + .playerl("Uh... Okay then.") + .end() + + optionBuilder.option("Can I use your anvil?") + .playerl("Can I use your anvil?") + .npcl(FacialExpression.OLD_NORMAL, "Of courssse you may... I have very little ussse for it nowadaysss...") + .playerl("Uh... Thanks, I guess.") + .end() + } + + b.onQuestStages(DesertTreasure.questName, 9, 10, 100) + // Technically should happen after talking to Malak, but nah. + .playerl("Hello.") + .npcl(FacialExpression.OLD_NORMAL, "You sshould not be down here...") + .playerl("Are you an assistant to Count Draynor?") + .npc(FacialExpression.OLD_NORMAL, "I usssed to have that honour...", "Why do you ssseek me?") + .branch { player -> + return@branch if (inInventory(player, Items.SILVER_BAR_2355)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(1) + .playerl("I have a silver bar with me, I was wondering if you could make it into a 'sacrificial offering pot' for me?") + .betweenStage { df, player, _, _ -> + if (removeItem(player, Items.SILVER_BAR_2355)) { + addItemOrDrop(player, Items.SILVER_POT_4658) + } + } + .npc(FacialExpression.OLD_NORMAL, "Yesss, of courssse...", "There you are, put it to good usssse...") + .end() + + branch.onValue(0) + .playerl("I understand that you can make me a 'sacrificial offering pot' if I bring you a bar of silver?") + .npcl(FacialExpression.OLD_NORMAL, "And where did you hear thisss?") + .playerl("It was from Malak in Canifis.") + .npc(FacialExpression.OLD_NORMAL, "Ah, I sssee...", "Yesss, I know how to make sssuch an item...", "It has been many yearsss sssince I have needed to however...") + .npcl(FacialExpression.OLD_NORMAL, "It is not my wisssh to quessstion your desssire for sssuch an item, I wasss merely sssurprisssed that one sssuch as you would make sssuch a requessst...") + .npcl(FacialExpression.OLD_NORMAL, "I will happily make you thisss pot, but you mussst bring me a bar of sssilver... Alasss, I can no longer collect my own ingredientsss, and mussst remain here...") + .end() + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/ScarabNPC.kt b/Server/src/main/content/region/desert/quest/deserttreasure/ScarabNPC.kt new file mode 100644 index 0000000..93dd60d --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/ScarabNPC.kt @@ -0,0 +1,18 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import org.rs09.consts.NPCs + +class ScarabNPC : NPCBehavior(NPCs.SCARABS_1969) { + var clearTime = 0 + + override fun tick(self: NPC): Boolean { + if (clearTime++ > 100) { + clearTime = 0 + poofClear(self) + } + return true + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/TranslationBook.kt b/Server/src/main/content/region/desert/quest/deserttreasure/TranslationBook.kt new file mode 100644 index 0000000..b9ff24e --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/TranslationBook.kt @@ -0,0 +1,185 @@ +package content.region.desert.quest.deserttreasure + +import content.global.handlers.iface.BookInterface +import content.global.handlers.iface.BookLine +import content.global.handlers.iface.Page +import content.global.handlers.iface.PageSet +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import org.rs09.consts.Items + +class TranslationBook : InteractionListener { + + companion object { + private val TITLE = "Translation Primer" + private val CONTENTS = arrayOf( + PageSet( + Page( + BookLine("This is a rough", 55), + BookLine("translation of the stone", 56), + BookLine("tablet brought to me by", 57), + BookLine("courier earlier today.", 58), + BookLine("", 59), + BookLine("", 60), + BookLine("The cuneiforms of this", 61), + BookLine("particular tablet are far", 62), + BookLine("different to anything I", 63), + BookLine("have previously seen in", 64), + BookLine("my career as an", 65) + ), + Page( + BookLine("archaeological expert.", 66), + BookLine("", 67), + BookLine("Where possible I have", 68), + BookLine("given as accurate a", 69), + BookLine("translation as possible, but", 70), + BookLine("some of the words I have", 71), + BookLine("attempted to translate", 72), + BookLine("hold different meanings", 73), + BookLine("depending upon their", 74), + BookLine("intonation and context;", 75), + BookLine("Due to my unfamiliarity", 76) + ) + ), + PageSet( + Page( + BookLine("with this language, I have", 55), + BookLine("given possible translations", 56), + BookLine("for these words wherever", 57), + BookLine("I have encountered them.", 58), + BookLine("Wherever I have a word", 59), + BookLine("n brackets, it is a word", 60), + BookLine("which has many meanings", 61), + BookLine("depending on the context,", 62), + BookLine("although the general", 63), + BookLine("meaning should be clear", 64), + BookLine("to even a casual study.", 65) + ), + Page( + BookLine("", 66), + BookLine("", 67), + BookLine("Hopefully this translation", 68), + BookLine("will help you in your", 69), + BookLine("excavations Asgarnia, and", 70), + BookLine("as usual I look forward", 71), + BookLine("to seeing what relics you", 72), + BookLine("bring back to the", 73), + BookLine("Museum of Varrock this", 74), + BookLine("time!", 75), + BookLine("Your friend, as always,", 76) + ), + ), + PageSet( + Page( + BookLine("Terry Balando", 55), + BookLine("", 56), + BookLine("", 57), + BookLine("", 58), + BookLine("", 59), + BookLine("", 60), + BookLine("", 61), + BookLine("", 62), + BookLine("", 63), + BookLine("", 64), + BookLine("", 65) + ), + Page( + BookLine("Translation follows:", 66), + BookLine("", 67), + BookLine("", 68), + BookLine("(There are some missing", 69), + BookLine("sentence fragments here,", 70), + BookLine("presumably from a stone", 71), + BookLine("tablet preceding this one", 72), + BookLine("which you have not yet", 73), + BookLine("discovered)", 74), + BookLine("", 75), + BookLine("...the permanent", 76) + ) + ), + PageSet( + Page( + BookLine("(exile/journey) of the", 55), + BookLine("people ended.", 56), + BookLine("And so it came to pass,", 57), + BookLine("that deep in the", 58), + BookLine("(fiery/uncomfortable)", 59), + BookLine("desert, the gods", 60), + BookLine("(argued/decided) amongst", 61), + BookLine("themselves that the", 62), + BookLine("(fortress/home) would be", 63), + BookLine("the (selected/chosen) place", 64), + BookLine("that would", 65) + ), + Page( + BookLine("(imprison/conceal) the", 66), + BookLine("(wealth/power).", 67), + BookLine("Thus (guarded/protected)", 68), + BookLine("by the (unusually archaic", 69), + BookLine("word here, I believe it", 70), + BookLine("means either the sick or", 71), + BookLine("the dead depending on", 72), + BookLine("context) and", 73), + BookLine("(defended/trapped) by the", 74), + BookLine("(diamonds/crystals) of", 75), + BookLine("(this word is", 76) + ) + ), + PageSet( + Page( + BookLine("untranslatable). So it was", 55), + BookLine("that the gods left the four", 56), + BookLine("(diamonds/crystals) as the", 57), + BookLine("(key/secret).", 58), + BookLine("(Guarded/Protected) by", 59), + BookLine("the (again, this word has", 60), + BookLine("no modern equivalent)", 61), + BookLine("and held by the", 62), + BookLine("(worthy/strong) so that", 63), + BookLine("the (wealth/power) might", 64), + BookLine("forever be", 65) + ), + Page( + BookLine("(imprisoned/concealed).", 66), + BookLine("", 67), + BookLine("", 68), + BookLine("", 69), + BookLine("", 70), + BookLine("", 71), + BookLine("", 72), + BookLine("", 73), + BookLine("", 74), + BookLine("", 75), + BookLine("", 76) + ) + ), + PageSet( + Page( + BookLine("There seems to be some", 55), + BookLine("further missing", 56), + BookLine("information continued", 57), + BookLine("onto a further tablet, but", 58), + BookLine("from this preliminary", 59), + BookLine("translation I think you", 60), + BookLine("may be onto something", 61), + BookLine("very big indeed!", 62), + BookLine("", 63), + BookLine("", 64), + BookLine("", 65) + ), + ), + ) + fun display(player: Player, pageNum: Int, buttonID: Int) : Boolean { + BookInterface.pageSetup(player, BookInterface.FANCY_BOOK_3_49, TITLE, CONTENTS) + return true + } + } + + override fun defineListeners() { + on(Items.TRANSLATION_4655, IntType.ITEM, "read") { player, _ -> + BookInterface.openBook(player, BookInterface.FANCY_BOOK_3_49, ::display) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/deserttreasure/TrollChildDialogue.kt b/Server/src/main/content/region/desert/quest/deserttreasure/TrollChildDialogue.kt new file mode 100644 index 0000000..24cedf3 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/deserttreasure/TrollChildDialogue.kt @@ -0,0 +1,142 @@ +package content.region.desert.quest.deserttreasure + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class TrollChildDialogue(player: Player? = null) : DialoguePlugin(player){ + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player!!, TrollChildDialogueFile(), npc) + return false + } + override fun newInstance(player: Player?): DialoguePlugin { + return TrollChildDialogue(player) + } + override fun getIds(): IntArray { + // NPCs.BANDIT_1932 is wrong, should be NPCs.TROLL_CHILD_1932 + // NPCs.TROLL_CHILD_1933, NPCs.TROLL_CHILD_1934 are varbit controlled 1932 instances. + return intArrayOf(NPCs.BANDIT_1932) + } +} +class TrollChildDialogueFile : DialogueBuilderFile() { + + companion object { + fun dialogueBeforeQuestCrying(builder: DialogueBuilder): DialogueBuilder { + // From https://youtu.be/AJaHuCuxfFg 15:19 + return builder + .playerl("Hello there.") + .line("The troll child is crying to itself.", "It is ignoring you completely.") + } + fun dialogueStillCrying(builder: DialogueBuilder): DialogueBuilder { + return builder + .playerl("Hello there.") + .npcl(FacialExpression.OLD_NEARLY_CRYING,"Waaaaaaa!") + .line("This troll seems very upset about something.", "Maybe some sweet food would take his mind off things?") + } + fun dialogueStoppedCrying(builder: DialogueBuilder): DialogueBuilder { + return builder + .playerl("Hello there.") + .npc(FacialExpression.OLD_SAD,"-sniff-","H-hello there.") + .playerl("Why so sad, little troll?") + .npc(FacialExpression.OLD_NEARLY_CRYING,"It was the bad man!", "He hurt my mommy and daddy!", "He made them all freezey!") + .playerl("Bad man...?") + .npcl(FacialExpression.OLD_NEARLY_CRYING,"He said it was because they stole his diamond! But they never did! They found it, and didn't know who it belonged to!") + .npcl(FacialExpression.OLD_NEARLY_CRYING,"My mommy always told me stealing is wrong, they would never steal from someone!") + .npcl(FacialExpression.OLD_NEARLY_CRYING,"Then he did some wavey hand thing and my mommy and daddy got frozified!") + .playerl("A diamond you say? Listen, I think I might be able to help your parents, but I need that Diamond in return.") + .npcl(FacialExpression.OLD_NEARLY_CRYING,"-sniff- I don't think they really wanted it anyway, they would have given it back to the bad man if he'd asked before freezifying them...") + .npcl(FacialExpression.OLD_NEARLY_CRYING,"I give you my promise mister that if you unfreeze my mommy and daddy, you can have the stupid diamond.") + .npcl(FacialExpression.OLD_NEARLY_CRYING,"Do we have a deal?") + } + fun dialogueYesToHelp(builder: DialogueBuilder): DialogueBuilder { + return builder + .playerl("Absolutely. Don't worry kid, I'll get your parents back to you safe and sound.") + } + fun dialogueNoToHelp(builder: DialogueBuilder): DialogueBuilder { + return builder + .playerl("Sorry, I can't make any promises about that, and I don't think I have the time to waste trying to defrost some stupid ice trolls.") + .npcl(FacialExpression.OLD_NEARLY_CRYING,"Waaaaaaa!") + } + fun dialogueHaveYouFreedThem(builder: DialogueBuilder): DialogueBuilder { + return builder + .npcl(FacialExpression.OLD_SAD,"You didn't free my mommy and daddy yet?") + .player("Not yet...") + .npc(FacialExpression.OLD_SAD,"Please try harder!", "I love my mommy and daddy!") + } + fun dialogueThankYou(builder: DialogueBuilder): DialogueBuilder { + return builder + .npc(FacialExpression.OLD_CALM_TALK1, "Thanks for all of your help!", "I'm surprised you managed to survive the blizzard,", "being a thin skinned fleshy and all!") + .player("What can I say?", "I'm a lot tougher than I look.") + } + fun dialogueLostDiamond(builder: DialogueBuilder): DialogueBuilder { + return builder + .playerl("I lost that diamond of Ice you gave me...") + .npcl(FacialExpression.OLD_CALM_TALK1, "That's okay, it blew back on an icy wind... It's almost like it wants to stay here! Here, take it back, you've earned it.") + } + } + + override fun create(b: DialogueBuilder) { + // Dialogue Logic + b.onQuestStages(DesertTreasure.questName, 0,1,2,3,4,5,6,7,8) + .let{dialogueBeforeQuestCrying(it)} + .end() + + b.onQuestStages(DesertTreasure.questName, 9) + .branch { player -> + return@branch DesertTreasure.getSubStage(player, DesertTreasure.attributeIceStage) + }.let { branch -> + // Branch on sub-stages. + branch.onValue(0) + .let{dialogueStillCrying(it)} + .end() + + branch.onValue(1) + .let{dialogueStoppedCrying(it)} + .options().let { optionBuilder -> + optionBuilder.option("Yes") + .let{dialogueYesToHelp(it)} + .endWith { _, player -> + if (DesertTreasure.getSubStage(player, DesertTreasure.attributeIceStage) == 1) { + DesertTreasure.setSubStage(player, DesertTreasure.attributeIceStage, 2) + } + } + optionBuilder.option("No") + .let{dialogueNoToHelp(it)} + .end() + } + + branch.onValue(2) + .let{dialogueHaveYouFreedThem(it)} + .end() + + branch.onValue(3) + .let{dialogueHaveYouFreedThem(it)} + .end() + + branch.onValue(4) + .let{dialogueHaveYouFreedThem(it)} + .end() + + branch.onValue(100) + .branch { player -> + return@branch if (!inInventory(player, Items.ICE_DIAMOND_4671)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(1) + .let{dialogueLostDiamond(it)} + .endWith { _, player -> + addItemOrDrop(player, Items.ICE_DIAMOND_4671) + } + branch.onValue(0) + .let{dialogueThankYou(it)} + .end() + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/icthlarinslittlehelper/WandererDialogue.java b/Server/src/main/content/region/desert/quest/icthlarinslittlehelper/WandererDialogue.java new file mode 100644 index 0000000..956ba25 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/icthlarinslittlehelper/WandererDialogue.java @@ -0,0 +1,49 @@ +package content.region.desert.quest.icthlarinslittlehelper; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; + +/** + * @author Ethan Kyle Millard + * @since Tue, October 09, 2018 @ 9:02 PM + */ +public class WandererDialogue extends DialoguePlugin { + + public WandererDialogue() { + } + + public WandererDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new WandererDialogue(player); + } + + @Override + public boolean open(Object... args) { + player ("Good day, wanderer."); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage){ + case 0: + npc ("Hello to you too adventurer."); + next(); + break; + case 1: + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] {}; + + + } +} diff --git a/Server/src/main/content/region/desert/quest/shadowofthestorm/DarklightListener.kt b/Server/src/main/content/region/desert/quest/shadowofthestorm/DarklightListener.kt new file mode 100644 index 0000000..1daba31 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/shadowofthestorm/DarklightListener.kt @@ -0,0 +1,21 @@ +package content.region.desert.quest.shadowofthestorm + +import core.api.addItem +import core.api.hasRequirement +import core.api.removeItem +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import org.rs09.consts.Items +import content.data.Quests + +class DarklightListener : InteractionListener { + override fun defineListeners() { + onUseWith(IntType.ITEM, Items.BLACK_MUSHROOM_INK_4622, Items.SILVERLIGHT_2402) { player, used, with -> + if (!hasRequirement(player, Quests.SHADOW_OF_THE_STORM) || (!player.inventory.contains(Items.BLACK_MUSHROOM_INK_4622, 1) && (!player.inventory.contains(Items.SILVERLIGHT_2402, 1)))) + return@onUseWith false + if (removeItem(player, used.id) && removeItem(player, with.id)) + addItem(player, Items.DARKLIGHT_6746) + return@onUseWith true + } + } +} diff --git a/Server/src/main/content/region/desert/quest/thegolem/TheGolemDialogue.kt b/Server/src/main/content/region/desert/quest/thegolem/TheGolemDialogue.kt new file mode 100644 index 0000000..c1331e6 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/thegolem/TheGolemDialogue.kt @@ -0,0 +1,134 @@ +package content.region.desert.quest.thegolem + +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import content.data.Quests + +@Initializable +public final class ClayGolemDialoguePlugin(player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return ClayGolemDialoguePlugin(player) + } + override fun open(vararg objects: Any?): Boolean { + npc = objects[0] as NPC + player.dialogueInterpreter.open(ClayGolemDialogueFile(), npc) + return true + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + return false + } + override fun getIds(): IntArray { + return intArrayOf(1907, NPCs.BROKEN_CLAY_GOLEM_1908, NPCs.DAMAGED_CLAY_GOLEM_1909, NPCs.CLAY_GOLEM_1910) + } +} + +class ClayGolemDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + val opt1 = b.onQuestStages(Quests.THE_GOLEM, 0) + .npc("Damage... severe...", "task... incomplete...") + .options() + opt1 + .optionIf("Shall I try to repair you?") { player -> return@optionIf player.questRepository.getQuest(Quests.THE_GOLEM).hasRequirements(player) } + .playerl("Shall I try to repair you?") + .npcl("Repairs... needed...") + .endWith(){ _, player -> if (player.questRepository.getStage(Quests.THE_GOLEM) < 1 ) { setQuestStage(player, Quests.THE_GOLEM, 1) } } + opt1 + .option("I'm not going to find a conversation here!") + .playerl("I'm not going to find a conversation here!") + .end() + b.onQuestStages(Quests.THE_GOLEM, 1) + .npcl("Repairs... needed...") + .end() + b.onQuestStages(Quests.THE_GOLEM, 2) + .npcl("Damage repaired...") + .npcl("Thank you. My body and mind are fully healed.") + .npcl("Now I must complete my task by defeating the great enemy.") + .playerl("What enemy?") + .npcl("A great demon. It broke through from its dimension to attack the city.") + .npcl("The golem army was created to fight it. Many were destroyed, but we drove the demon back!") + .npcl("The demon is still wounded. You must open the portal so that I can strike the final blow and complete my task.") + .endWith() { _, player -> setQuestStage(player, Quests.THE_GOLEM, 3) } + b.onQuestStages(Quests.THE_GOLEM, 3) + .npcl("The demon is still wounded. You must open the portal so that I can strike the final blow and complete my task.") + .end() + b.onQuestStages(Quests.THE_GOLEM, 4) + .npcl("My task is incomplete. You must open the portal so I can defeat the great demon.") + .playerl("It's ok, the demon is dead!") + .npcl("The demon must be defeated...") + .playerl("No, you don't understand. I saw the demon's skeleton. It must have died of its wounds.") + .npcl("Demon must be defeated! Task incomplete.") + .endWith() { _, player -> setQuestStage(player, Quests.THE_GOLEM, 5) } + b.onQuestStages(Quests.THE_GOLEM, 5) + .npcl("Task incomplete.") + .playerl("Oh, how am I going to convince you?") + .endWith() { _, player -> setQuestStage(player, Quests.THE_GOLEM, 6) } + b.onQuestStages(Quests.THE_GOLEM, 6, 7) + .npcl("My task is incomplete. You must open the portal so I can defeat the great demon.") + .playerl("I already told you, he's dead!") + .npcl("Task incomplete.") + .playerl("Oh, how am I going to convince you?") + .endWith() { df, player -> if(player.questRepository.getStage(Quests.THE_GOLEM) < 7) { setQuestStage(player, Quests.THE_GOLEM, 7) } } + } +} + +class ClayGolemProgramDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onQuestStages(Quests.THE_GOLEM, 8) + .npc("New instructions...", "Updating program...") + .npcl("Task complete!") + .npcl("Thank you. Now my mind is at rest.") + .endWith() { _, player -> finishQuest(player, Quests.THE_GOLEM) } + } +} + +class CuratorHaigHalenGolemDialogue : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + val opt1 = b.onQuestStages(Quests.THE_GOLEM, 3) + .npcl("Ah yes, a very impressive artefact. The people of that city were excellent sculptors.") + .npcl("It's in the display case upstairs.") + .playerl("No, I need to take it away with me.") + .npcl("What do you want it for?") + .options() + opt1 + .option("I want to open a portal to the lair of an elder-demon.") + .playerl("I want to open a portal to the lair of an elder-demon.") + .npcl("Good heavens! I'd never let you do such a dangerous thing.") + .end() + opt1 + .option("Well, I, er, just want it.") + .playerl("Well, I, er, just want it.") + .end() + } +} + +val LETTER_LINES = arrayOf( + "", + "", + "Dearest Varmen,", + "I hope this finds you well. Here are the books you asked for", + "There has been an exciting development closer to home --", + "another city from the same period has been discovered east", + "of Varrock, and we are starting a huge excavation project", + "here. I don't know if the museum will be able to finance your", + "expedition as well as this one, so I fear your current trip will be", + "the last.", + "May Saradomin grant you a safe journey home", + "Your loving Elissa.", + ) + +val DISPLAY_CASE_TEXT = arrayOf("3rd age - yr 3000-4000", + "", + "This statuette was found in an underground", + "temple in the ruined city of Uzer, which was", + "destroyed late in the 3rd Age, suddenly, due to", + "causes unknown. It probably represents one of", + "the clay golems that the craftsmen of the city", + "built as warriors and servants. The statuette", + "was originally part of a mechanism whose", + "purpose is unknown.") diff --git a/Server/src/main/content/region/desert/quest/thegolem/TheGolemQuest.kt b/Server/src/main/content/region/desert/quest/thegolem/TheGolemQuest.kt new file mode 100644 index 0000000..89d485f --- /dev/null +++ b/Server/src/main/content/region/desert/quest/thegolem/TheGolemQuest.kt @@ -0,0 +1,446 @@ +package content.region.desert.quest.thegolem + +import core.api.* +import core.game.node.Node +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.node.scenery.Scenery +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.plugin.Initializable +import core.tools.RandomFunction +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.interaction.InterfaceListener +import core.game.world.GameWorld +import content.data.Quests + +@Initializable +class TheGolemQuest : Quest(Quests.THE_GOLEM, 70, 69, 1, 437, 0, 1, 10) { + override fun newInstance(`object`: Any?): Quest { + return this + } + + override fun drawJournal(player: Player, stage: Int) { + super.drawJournal(player, stage) + var ln = 11 + if(stage == 0) { + line(player, "I can start this quest by talking to the golem who is in the:", ln++, false) + line(player, "Ruined city of !!Uzer??, which is in the desert to the east of", ln++, false) + line(player, "the !!Shantay Pass.", ln++, false) + line(player, "I will need to have !!level 20 crafting?? and !!level 25 thieving", ln++, false) + } + if(stage >= 1) { + line(player, "I've found the golem, and offered to repair it.", ln++, stage > 1) + } + if(stage >= 2) { + line(player, "I've repaired the golem with some soft clay.", ln++, stage > 2) + } + if(stage >= 3) { + line(player, "The golem wants me to open a portal to help it defeat", ln++, stage > 3) + line(player, "the demon that attacked its city.", ln++, stage > 3) + } + val readLetter = player.getAttribute("the-golem:read-elissa-letter", false) + val readBook = player.getAttribute("the-golem:varmen-notes-read", false) + if(readLetter) { + line(player, "I've found a letter that mentions !!The Digsite", ln++, readBook) + } + if(readBook) { + line(player, "I've found a book that mentions that golems are programmed by", ln++, stage > 7) + line(player, "writing instructions on papyrus with a phoenix quill pen.", ln++, stage > 7) + } + val hasStatuette = TheGolemListeners.hasStatuette(player) + val doorOpen = player.getAttribute("the-golem:door-open", false) + if(hasStatuette) { + line(player, "I've acquired a statuette that fits a mechanism in the ruins", ln++, doorOpen) + line(player, " of !!Uzer?? from the Varrock museum.", ln++, doorOpen) + } + val seenDemon = player.getAttribute("the-golem:seen-demon", false) + if(doorOpen) { + line(player, "I've opened the portal in the ruins of Uzer.", ln++, seenDemon) + } + if(seenDemon) { + line(player, "It turns out that the demon is already dead!", ln++, stage > 4) + line(player, "I should tell the golem the good news.", ln++, stage > 4) + } + if(stage > 4) { + line(player, "The demon doesn't think its task is complete.", ln++, stage > 7) + } + if(stage >= 100) { + line(player, "%%QUEST COMPLETE!&&", ln++, false) + } + } + + override fun hasRequirements(player: Player): Boolean { + return player.skills.getStaticLevel(Skills.CRAFTING) >= 20 && player.skills.getStaticLevel(Skills.THIEVING) >= 25 + } + + override fun finish(player: Player?) { + super.finish(player) + player ?: return + var ln = 10 + player.packetDispatch.sendItemZoomOnInterface(Items.STATUETTE_4618,230,277,5) + drawReward(player, "1 quest point", ln++) + drawReward(player, "1,000 Crafting XP",ln++) + drawReward(player, "1,000 Theiving XP", ln++) + rewardXP(player, Skills.CRAFTING, 3000.0) + rewardXP(player, Skills.THIEVING, 2000.0) + } + + override fun updateVarps(player: Player) { + TheGolemListeners.updateVarps(player) + } +} + +@Initializable +class ClayGolemNPC : AbstractNPC { + constructor() : super(NPCs.BROKEN_CLAY_GOLEM_1908, null, true) {} + private constructor(id: Int, location: Location) : super(id, location) {} + + override fun construct(id: Int, location: Location, vararg objects: Any?): AbstractNPC { + return ClayGolemNPC(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(1907, NPCs.BROKEN_CLAY_GOLEM_1908, NPCs.DAMAGED_CLAY_GOLEM_1909, NPCs.CLAY_GOLEM_1910) + } +} + +class LetterListener : InterfaceListener { + override fun defineInterfaceListeners() { + onOpen(220) { player, component -> + val lines: Array = player.getAttribute("ifaces:220:lines", arrayOf()) + for(i in 0 until Math.min(lines.size, 15)) { + setInterfaceText(player, lines[i], 220, i+1) + //setInterfaceText(player, "${i}", 220, i+1) + } + return@onOpen true + } + } +} + +class DisplayCaseListener : InterfaceListener { + override fun defineInterfaceListeners() { + onOpen(534) { player, component -> + //player.packetDispatch.sendModelOnInterface(25576, 534, 5, 650) + val model = player.getAttribute("ifaces:534:model", 0) + player.packetDispatch.sendModelOnInterface(model, 534, 4, 461) + //player.packetDispatch.sendModelOnInterface(25576, 534, 12, 973) + setInterfaceText(player, DISPLAY_CASE_TEXT.joinToString("
"), 534, 2) + setInterfaceText(player, "30", 534, 85) + return@onOpen true + } + } +} + +class TheGolemListeners : InteractionListener { + fun repairGolem(player: Player): Boolean { + if(player.questRepository.getStage(Quests.THE_GOLEM) == 1) { + var clayUsed = player.getAttribute("the-golem:clay-used", 0) + val msg = when(clayUsed) { + 0 -> "You apply some clay to the golem's wounds. The clay begins to harden in the hot sun." + 1 -> "You fix the golem's legs." + 2 -> "The golem is nearly whole." + 3 -> "You repair the golem with a final piece of clay." + else -> null + } + if(removeItem(player, Item(Items.SOFT_CLAY_1761, 1))) { + if(msg != null) { + sendItemDialogue(player, Items.SOFT_CLAY_1761, msg) + } + clayUsed = Math.min(clayUsed + 1, 4) + player.setAttribute("/save:the-golem:clay-used", clayUsed) + updateVarps(player) + if(clayUsed == 4) { + setQuestStage(player, Quests.THE_GOLEM, 2) + } + } + } + return true + } + + fun takeThroneGems(player: Player) { + if(player.getAttribute("the-golem:gems-taken", false)) { + return + } + if(!player.inventory.containsAtLeastOneItem(Items.HAMMER_2347) || !player.inventory.containsAtLeastOneItem(Items.CHISEL_1755)) { + player.sendMessage("You need a hammer and chisel to remove the gems.") + return + } + if(!(player.inventory.freeSlots() >= 6)) { + player.sendMessage("You don't have enough free space to remove all six gems.") + return + } + player.setAttribute("/save:the-golem:gems-taken", true) + updateVarps(player) + for(item in arrayOf(Items.SAPPHIRE_1607, Items.EMERALD_1605, Items.RUBY_1603)) { + player.inventory.add(Item(item, 2)) + } + sendItemDialogue(player, Items.RUBY_1603, "You prize the gems from the demon's throne.") + } + + companion object { + @JvmStatic + fun hasStatuette(player: Player): Boolean { + return player.inventory.containsAtLeastOneItem(4618) || player.bank.containsAtLeastOneItem(4618) || player.getAttribute("the-golem:placed-statuette", false) + } + + @JvmStatic + fun initializeStatuettes(player: Player) { + if(!player.getAttribute("the-golem:statuette-rotation:initialized", false)) { + for(i in 0 until 4) { + player.setAttribute("/save:the-golem:statuette-rotation:${i}", RandomFunction.random(2)) + } + player.setAttribute("/save:the-golem:statuette-rotation:initialized", true) + } + } + + @JvmStatic + fun updateVarps(player: Player) { + val clayUsed = player.getAttribute("the-golem:clay-used", 0) + val gemsTaken = if(player.getAttribute("the-golem:gems-taken", false)) { 1 } else { 0 } + val statuetteTaken = if(hasStatuette(player)) { 1 } else { 0 } + val statuettePlaced = if(player.getAttribute("the-golem:placed-statuette", false)) { 1 } else { 0 } + initializeStatuettes(player) + val rotation0 = player.getAttribute("the-golem:statuette-rotation:0", 0) + val rotation1 = player.getAttribute("the-golem:statuette-rotation:1", 0) + val rotation2 = player.getAttribute("the-golem:statuette-rotation:2", 0) + val rotation3 = player.getAttribute("the-golem:statuette-rotation:3", 0) + val doorOpen = player.getAttribute("the-golem:door-open", false) + var clientStage = 0 + if(player.questRepository.getStage(Quests.THE_GOLEM) > 0) { + clientStage = Math.max(clientStage, 1) + } + if(doorOpen) { + clientStage = Math.max(clientStage, 5) + } + if(player.questRepository.getStage(Quests.THE_GOLEM) >= 100) { + clientStage = Math.max(clientStage, 10) + } + setVarbit(player, 346, clientStage) + setVarbit(player, 348, clayUsed) + setVarbit(player, 354, gemsTaken) + setVarbit(player, 355, statuetteTaken) + setVarbit(player, 349, rotation0) + setVarbit(player, 350, rotation1) + setVarbit(player, 351, rotation2) + setVarbit(player, 352, statuettePlaced * (rotation3 + 1)) + } + } + + fun pickpocketCurator(player: Player, node: Node): Boolean { + if(player.inventory.containsAtLeastOneItem(4617) || player.bank.containsAtLeastOneItem(4617)) { + player.sendMessage("You have no reason to do that.") + return true + } + sendItemDialogue(player, 4617, "You steal a tiny key.") + addItemOrDrop(player, 4617, 1) + return true + } + + fun displayCase(player: Player, node: Scenery): Boolean { + val model = node.definition.modelIds[0] + player.setAttribute("ifaces:534:model", model) + openInterface(player, 534) + return true + } + + fun openDisplayCase(player: Player, node: Node): Boolean { + if(!player.inventory.containsAtLeastOneItem(4617)) { + player.sendMessage("You can't open the display case without the key.") + return true + } + if(hasStatuette(player)) { + return true + } + addItemOrDrop(player, 4618, 1) + updateVarps(player) + return true + } + + fun placeStatuette(player: Player): Boolean { + + if(player.inventory.remove(Item(4618))) { + player.sendMessage("You insert the statuette into the alcove.") + player.setAttribute("/save:the-golem:placed-statuette", true) + updateVarps(player) + } + return true + } + + fun turnStatuette(player: Player, node: Scenery): Boolean { + if(player.getAttribute("the-golem:door-open", false)) { + player.sendMessage("You've already opened the door.") + return true + } + val index = when(node.wrapper.id) { + 6303 -> 0 + 6304 -> 1 + 6305 -> 2 + 6306 -> 3 + else -> return true + } + initializeStatuettes(player) + val rotation = 1 - player.getAttribute("the-golem:statuette-rotation:${index}", 0) + val dir = if(rotation == 0) { "right" } else { "left" } + player.sendMessage("You turn the statuette to the ${dir}.") + player.setAttribute("the-golem:statuette-rotation:${index}", rotation) + checkDoor(player) + updateVarps(player) + return true + } + + fun checkDoor(player: Player) { + if(!player.getAttribute("the-golem:door-open", false)) { + val rotation0 = player.getAttribute("the-golem:statuette-rotation:0", 0) + val rotation1 = player.getAttribute("the-golem:statuette-rotation:1", 0) + val rotation2 = player.getAttribute("the-golem:statuette-rotation:2", 0) + val rotation3 = player.getAttribute("the-golem:statuette-rotation:3", 0) + val placed = player.getAttribute("the-golem:placed-statuette", false) + if(rotation0 == 1 && rotation1 == 1 && rotation2 == 0 && rotation3 == 0 && placed) { + player.sendMessage("The door grinds open.") + player.setAttribute("/save:the-golem:door-open", true) + } + } + } + + fun mortarOnMushroom(player: Player): Boolean { + if(!player.inventory.containsAtLeastOneItem(Items.VIAL_229)) { + player.sendMessage("You need a vial to do that.") + return true + } + if(player.inventory.remove(Item(Items.BLACK_MUSHROOM_4620, 1)) && player.inventory.remove(Item(Items.VIAL_229, 1))) { + sendItemDialogue(player, Items.BLACK_MUSHROOM_INK_4622, "You crush the mushroom and pour the juice into a vial.") + player.inventory.add(Item(Items.BLACK_MUSHROOM_INK_4622, 1)) + } + return true + } + + fun featherOnInk(player: Player): Boolean { + if(player.inventory.remove(Item(Items.PHOENIX_FEATHER_4621, 1))) { + sendItemDialogue(player, Items.PHOENIX_QUILL_PEN_4623, "You dip the phoenix feather into the ink.") + player.inventory.add(Item(Items.PHOENIX_QUILL_PEN_4623, 1)) + } + return true + } + + fun penOnPapyrus(player: Player): Boolean { + if(!player.getAttribute("the-golem:varmen-notes-read", false)) { + player.sendMessage("You don't know what to write.") + return true + } + if(player.inventory.remove(Item(Items.PAPYRUS_970, 1))) { + sendItemDialogue(player, Items.GOLEM_PROGRAM_4624, "You write on the papyrus:
YOUR TASK IS DONE") + player.inventory.add(Item(Items.GOLEM_PROGRAM_4624, 1)) + } + return true + } + + fun implementOnGolem(player: Player): Boolean { + if(!player.getAttribute("the-golem:varmen-notes-read", false)) { + player.sendMessage("You don't know what that would do.") + return true + } + if(player.questRepository.getStage(Quests.THE_GOLEM) == 7) { + player.sendMessage("You insert the key and the golem's skull hinges open.") + setQuestStage(player, Quests.THE_GOLEM, 8) + } + return true + } + + fun programOnGolem(player: Player, used: Node, with: Node): Boolean { + player.dialogueInterpreter.open(ClayGolemProgramDialogueFile(), with) + return true + } + + + override fun defineDestinationOverrides() { + addClimbDest(Location.create(3492, 3089, 0), Location.create(2722, 4886, 0)) + addClimbDest(Location.create(2721, 4884, 0), Location.create(3491, 3090, 0)) + setDest(IntType.SCENERY, intArrayOf(34978), "climb-down") { _, _ -> return@setDest Location.create(3491, 3090, 0) } + setDest(IntType.SCENERY, intArrayOf(6372), "climb-up") { _, _ -> return@setDest Location.create(2722, 4886, 0) } + } + + override fun defineListeners() { + onUseWith(IntType.NPC, Items.SOFT_CLAY_1761, 1907) { player, used, with -> return@onUseWith repairGolem(player) } + on(34978, IntType.SCENERY, "climb-down") { player, node -> core.game.global.action.ClimbActionHandler.climb(player, core.game.global.action.ClimbActionHandler.CLIMB_DOWN, core.game.global.action.SpecialLadders.getDestination(node.location)); return@on true } + on(6372, IntType.SCENERY, "climb-up") { player, node -> core.game.global.action.ClimbActionHandler.climb(player, core.game.global.action.ClimbActionHandler.CLIMB_UP, core.game.global.action.SpecialLadders.getDestination(node.location)); return@on true } + on(4615, IntType.ITEM, "read") { player, node -> + player.setAttribute("ifaces:220:lines", LETTER_LINES) + player.setAttribute("/save:the-golem:read-elissa-letter", true) + openInterface(player, 220) + return@on true + } + on(35226, IntType.SCENERY, "search") { player, node -> + player.packetDispatch.sendMessage("You search the bookcase.") + val readLetter = player.getAttribute("the-golem:read-elissa-letter", false) + if(!player.inventory.containsAtLeastOneItem(4616) && !player.bank.containsAtLeastOneItem(4616) && readLetter) { + sendItemDialogue(player, 4616, "You find Varmen's expedition notes.") + addItemOrDrop(player, 4616, 1) + } else { + player.packetDispatch.sendMessage("You find nothing of interest.") + } + return@on true + } + on(6363, IntType.SCENERY, "open") { player, node -> player.sendMessage("The door doesn't open."); return@on true } + on(6364, IntType.SCENERY, "enter") { player, node -> + player.sendMessage("You step into the portal.") + if(!player.getAttribute("the-golem:seen-demon", false)) { + player.sendMessage("The room is dominated by a colossal horned skeleton!") + player.setAttribute("/save:the-golem:seen-demon", true) + setQuestStage(player, Quests.THE_GOLEM, 4) + } + teleport(player, Location.create(3552, 4948, 0)) + return@on true + } + on(6282, IntType.SCENERY, "enter") { player, node -> + player.sendMessage("You step into the portal.") + teleport(player, Location.create(2722, 4911, 0)) + return@on true + } + onUseWith(IntType.SCENERY, Items.HAMMER_2347, 6301) { player, _, _ -> takeThroneGems(player); return@onUseWith true } + onUseWith(IntType.SCENERY, Items.CHISEL_1755, 6301) { player, _, _ -> takeThroneGems(player); return@onUseWith true } + on(646, IntType.NPC, "pickpocket") { player, node -> return@on pickpocketCurator(player, node) } + on(intArrayOf(24627, 24550), IntType.SCENERY, "study") { player, node -> return@on displayCase(player, node as Scenery) } + on(24627, IntType.SCENERY, "open") { player, node -> return@on openDisplayCase(player, node) } + onUseWith(IntType.SCENERY, 4618, 6309) { player, used, with -> return@onUseWith placeStatuette(player) } + on(intArrayOf(6307, 6308), IntType.SCENERY, "turn") { player, node -> turnStatuette(player, node as Scenery) } + onUseWith(IntType.ITEM, 233, 4620) { player, used, with -> return@onUseWith mortarOnMushroom(player) } + onUseWith(IntType.ITEM, 4621, 4622) { player, used, with -> return@onUseWith featherOnInk(player) } + onUseWith(IntType.ITEM, 970, 4623) { player, used, with -> return@onUseWith penOnPapyrus(player) } + onUseWith(IntType.NPC, 4619, 1907) { player, used, with -> return@onUseWith implementOnGolem(player) } + onUseWith(IntType.NPC, 4624, 1907) { player, used, with -> return@onUseWith programOnGolem(player, used, with) } + on(1911, IntType.NPC, "grab-feather") { player, node -> + if(player.getAttribute("the-golem:varmen-notes-read", false)) { + player.lock() + GameWorld.Pulser.submit(object : Pulse(){ + var counter = 0 + override fun pulse(): Boolean { + when(counter++){ + 0 -> { + player.sendMessage("You attempt to grab the pheonix's tail-feather.") + player.animator.animate(Animation(881)) + } + 3 -> { + player.sendMessage("You grab a tail-feather.") + player.inventory.add(Item(Items.PHOENIX_FEATHER_4621)) + player.unlock() + return true + } + } + return false + } + }) + } else { + player.sendMessage("You have no reason to take the phoenix's feathers.") + } + return@on true + } + } +} diff --git a/Server/src/main/content/region/desert/quest/thegolem/VarmensNotes.kt b/Server/src/main/content/region/desert/quest/thegolem/VarmensNotes.kt new file mode 100644 index 0000000..75cafd2 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/thegolem/VarmensNotes.kt @@ -0,0 +1,298 @@ +package content.region.desert.quest.thegolem + +import content.global.handlers.iface.BookInterface +import content.global.handlers.iface.BookLine +import content.global.handlers.iface.Page +import content.global.handlers.iface.PageSet +import core.api.setAttribute +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.game.node.entity.player.Player +import org.rs09.consts.Items + +/** + * Varmen's Notes Book + * @author ovenbreado + */ +class VarmensNotes : InteractionListener { + companion object { + + private val TITLE = "The Ruins of Uzer" + val CONTENTS = arrayOf( + PageSet( + Page( + BookLine("Septober 19:", 55), + BookLine("The nomads were right:", 56), + BookLine("there is a city here,", 57), + BookLine("probably buried for", 58), + BookLine("millenia and revealed by", 59), + BookLine("the random motions of", 60), + BookLine("the sand. The", 61), + BookLine("architecture is impressive", 62), + BookLine("even in ruin, and must", 63), + BookLine("once have been amazing.", 64), + BookLine("One puzzling factor is the", 65), + ), + Page( + BookLine("pottery -- there are", 66), + BookLine("fragments all over the", 67), + BookLine("ruins, surely too much", 68), + BookLine("for a city even of this", 69), + BookLine("size. We have set up", 70), + BookLine("camp and will do a proper", 71), + BookLine("survey tomorrow.", 72), + ) + ), + PageSet( + Page( + BookLine("Septober 20:", 55), + BookLine("The meaning of the", 56), + BookLine("pottery was explained", 57), + BookLine("today in a most", 58), + BookLine("surprising manner. We", 59), + BookLine("found a mostly-intact clay", 60), + BookLine("statue buried up to its", 61), + BookLine("waist in sand, and as", 62), + BookLine("soon as we dug it out, it", 63), + BookLine("started to walk around! It", 64), + BookLine("is a clay golem, built by", 65), + ), + Page( + BookLine("the city's inhabitants and", 66), + BookLine("dormant all this time. Its", 67), + BookLine("head is badly damaged", 68), + BookLine("and it is", 69), + BookLine("uncommunicative, but its", 70), + BookLine("existence tells us that the", 71), + BookLine("city's inhabitants were", 72), + BookLine("expert magical craftsmen.", 73), + BookLine("The huge kilns in some", 74), + BookLine("of the buildings indicate", 75), + BookLine("that at some point before", 76), + ) + ), + PageSet( + Page( + BookLine("its destruction the whole", 55), + BookLine("city was converted to the", 56), + BookLine("manufacture of these", 57), + BookLine("golems.", 58), + BookLine("", 59), + BookLine("We have also examined", 60), + BookLine("the carvings on the large", 61), + BookLine("building in the centre.", 62), + BookLine("These are symbols", 63), + BookLine("depicting several of the", 64), + BookLine("ancient gods, including", 65), + ), + Page( + BookLine("Saradomin, Zamorak, and", 66), + BookLine("Armadyl, but there is", 67), + BookLine("another prominent symbol", 68), + BookLine("that I cannot identify. As", 69), + BookLine("it seems we will need to", 70), + BookLine("be here for longer than I", 71), + BookLine("had thought, I have sent", 72), + BookLine("to Elissa for books on", 73), + BookLine("golems and religious", 74), + BookLine("symbols.", 75), + ) + ), + PageSet( + Page( + BookLine("Septober 21:", 55), + BookLine("As we examine the ruins", 56), + BookLine("one thing becomes", 57), + BookLine("increasingly clear: most", 58), + BookLine("of the damage was not", 59), + BookLine("due to weathering. The", 60), + BookLine("buildings were destroyed", 61), + BookLine("by force, as if torn down", 62), + BookLine("by giant hands.", 63), + ), + Page( + BookLine("Septober 22:", 66), + BookLine("A breakthrough! We have", 67), + BookLine("found the staircase into", 68), + BookLine("the lower levels of the", 69), + BookLine("temple. This part has", 70), + BookLine("been untouched by the", 71), + BookLine("elements, and the", 72), + BookLine("carvings here are more", 73), + BookLine("intact, especially four", 74), + BookLine("beautiful statuettes in", 75), + BookLine("alcoves framing the large", 76), + ) + ), + PageSet( + Page( + BookLine("door. I have removed one", 55), + BookLine("of them. The door will", 56), + BookLine("not open. I am glad I", 57), + BookLine("sent for a book on", 58), + BookLine("symbols, as the", 59), + BookLine("unidentified symbol is", 60), + BookLine("even more prominent", 61), + BookLine("here, especially on the", 62), + BookLine("door.", 63), + ), + Page( + BookLine("Septober 23:", 66), + BookLine("Our messenger returned", 67), + BookLine("with the books I asked for", 68), + BookLine("and a letter from Elissa.", 69), + BookLine("It is unfortunate that the", 70), + BookLine("museum will not be able", 71), + BookLine("to finance a full-scale", 72), + BookLine("excavation here as well as", 73), + BookLine("the one closer to Varrock,", 74), + BookLine("although I am of course", 75), + BookLine("pleased that the other city", 76), + ) + ), + PageSet( + Page( + BookLine("has been uncovered. But", 55), + BookLine("with the books I am able", 56), + BookLine("to piece together more of", 57), + BookLine("the story of this city.", 58), + BookLine("", 59), + BookLine("The unidentified symbol", 60), + BookLine("in the ruins is that of the", 61), + BookLine("demon Thammaron, who", 62), + BookLine("was Zamorak's chief", 63), + BookLine("lieutenant during the", 64), + BookLine("godwars of the Third", 65), + ), + Page( + BookLine("Age. With that", 66), + BookLine("information I can say", 67), + BookLine("with confidence that these", 68), + BookLine("are the ruins of Uzer, an", 69), + BookLine("advanced human", 70), + BookLine("civilization said to have", 71), + BookLine("been destroyed towards", 72), + BookLine("the end of the Third Age", 73), + BookLine("(roughly 2,500 years", 74), + BookLine("ago). It was allied with", 75), + BookLine("Saradomin and enjoyed", 76), + ) + ), + PageSet( + Page( + BookLine("his protection, as well as", 55), + BookLine("that of its own mages and", 56), + BookLine("warriors. Thammaron was", 57), + BookLine("able to open a portal from", 58), + BookLine("his own domain straight", 59), + BookLine("into the heart of the city,", 60), + BookLine("bypassing its defences.", 61), + BookLine("With Saradomin's help the", 62), + BookLine("army of Uzer was able to", 63), + BookLine("drive Thammaron back,", 64), + BookLine("but the record ends at", 65), + ), + Page( + BookLine("that point and it has", 66), + BookLine("always been assumed that", 67), + BookLine("a later attack, either by", 68), + BookLine("Thammaron or by", 69), + BookLine("Zamorak's other forces,", 70), + BookLine("finished the city off.", 71), + BookLine("", 72), + BookLine("Examining the door", 73), + BookLine("again, I now see that it is", 74), + BookLine("exactly the sort of door", 75), + BookLine("that could be used to seal", 76), + ) + ), + PageSet( + Page( + BookLine("Thammaron's portal. I am", 55), + BookLine("suddently glad I was not", 56), + BookLine("able to open it! I surmise", 57), + BookLine("that the army of golems", 58), + BookLine("was created in order to", 59), + BookLine("fight the demon, since", 60), + BookLine("Uzer's army had been", 61), + BookLine("wiped out and", 62), + BookLine("Saradomin's forces were", 63), + BookLine("increasingly stretched.", 64), + BookLine("However, this approach", 65), + ), + Page( + BookLine("evidently failed, since the", 66), + BookLine("city was eventually", 67), + BookLine("destroyed.", 68), + BookLine("", 69), + BookLine("The art of the", 70), + BookLine("construction of golems", 71), + BookLine("has been lost since the", 72), + BookLine("Third Age, and, although", 73), + BookLine("they are sometimes", 74), + BookLine("discovered lying dormant", 75), + BookLine("in the ground, no", 76), + ) + ), + PageSet( + Page( + BookLine("concerted effort has been", 55), + BookLine("made to regain it, thanks", 56), + BookLine("largely to the modern", 57), + BookLine("Saradomist Church's view", 58), + BookLine("of them as unnatural.", 59), + BookLine("This view is without", 60), + BookLine("foundation, as golems are", 61), + BookLine("neither good nor evil but", 62), + BookLine("follow instructions they", 63), + BookLine("are given to the letter", 64), + BookLine("and without imagination,", 65), + ), + Page( + BookLine("indeed experiencing", 66), + BookLine("extreme discomfort for as", 67), + BookLine("long as a task assigned to", 68), + BookLine("them remains incomplete.", 69), + BookLine("Some golems were", 70), + BookLine("constructed to obey", 71), + BookLine("verbal instructions, but", 72), + BookLine("the main method of", 73), + BookLine("instruction was to place", 74), + BookLine("magical words into the", 75), + BookLine("golem's skull cavity.", 76), + ) + ), + PageSet( + Page( + BookLine("These were written on", 55), + BookLine("papyrus using a naturally", 56), + BookLine("occurring source of ink,", 57), + BookLine("and their magical power", 58), + BookLine("derived from the use of a", 59), + BookLine("phoenix tail feather as a", 60), + BookLine("pen. These would be used", 61), + BookLine("for long-term or", 62), + BookLine("important tasks, and", 63), + BookLine("would override any verbal", 64), + BookLine("instructions.", 65), + ) + ) + ) + private fun display(player: Player, pageNum: Int, buttonID: Int) : Boolean { + BookInterface.pageSetup(player, BookInterface.FANCY_BOOK_3_49, TITLE, CONTENTS) + if (BookInterface.isLastPage(pageNum, CONTENTS.size)) { + player.setAttribute("/save:the-golem:varmen-notes-read", true) + } + return true + } + } + + override fun defineListeners() { + on(Items.VARMENS_NOTES_4616, IntType.ITEM, "read") { player, _ -> + BookInterface.openBook(player, BookInterface.FANCY_BOOK_3_49, ::display) + return@on true + } + } + + +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/quest/thetouristrap/AlShabimDialogue.java b/Server/src/main/content/region/desert/quest/thetouristrap/AlShabimDialogue.java new file mode 100644 index 0000000..4afd560 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/thetouristrap/AlShabimDialogue.java @@ -0,0 +1,310 @@ +package content.region.desert.quest.thetouristrap; + +import content.data.Quests; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; + +/** + * The dialogue used for the al shabim npc. + * @author 'Vexia + * @version 1.0 + */ +public final class AlShabimDialogue extends DialoguePlugin { + + /** + * The bronze darts item. + */ + private static final Item BRONZE_DARTS = new Item(806, 6); + + /** + * The quest instance. + */ + private Quest quest; + + /** + * Constructs a new {@code AlShabimDialogue} {@code Object}. + */ + public AlShabimDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code AlShabimDialogue} {@code Object}. + * @param player the player. + */ + public AlShabimDialogue(final Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new AlShabimDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + quest = player.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP); + switch (quest.getStage(player)) { + default: + npc("Hello Effendi!"); + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (quest.getStage(player)) { + case 54:// build tool. + switch (stage) { + case 0: + if (player.getInventory().containsItem(TouristTrap.PROTOTYPE_DART)) { + npc("Wonderful, I see you have made the new weapon!"); + stage = 20; + } else { + if (!player.hasItem(TouristTrap.BEDABIN_KEY)) { + player("I seemed to have lost the key..."); + stage++; + } else { + npc("Have you figured out the plans yet?"); + stage = 3; + } + } + break; + case 1: + npc("Ahh Effendi, it's a good thing I have a spare!"); + stage++; + break; + case 2: + player.getInventory().add(TouristTrap.BEDABIN_KEY, player); + interpreter.sendItemMessage(TouristTrap.BEDABIN_KEY, "Al Shabim gives you a key."); + stage = 11; + break; + case 3: + player("No, not yet."); + stage = 11; + break; + case 11: + end(); + break; + case 20: + interpreter.sendItemMessage(TouristTrap.PROTOTYPE_DART, "You show Al Shabim the prototype dart."); + ; + stage++; + break; + case 21: + npc("This is truly fantastic Effendi!"); + stage++; + break; + case 22: + if (player.getInventory().containsItem(TouristTrap.TECHNICAL_PLANS)) { + npc("We will take the technical plans for the weapon as well."); + stage++; + } else { + player.getInventory().remove(TouristTrap.TECHNICAL_PLANS); + npc("We are forever grateful for this gift. My advisor have", "discovered some secrets which we will share with you."); + stage = 25; + } + break; + case 23: + interpreter.sendItemMessage(TouristTrap.TECHNICAL_PLANS, "You hand over the technical plans for the weapon."); + stage++; + break; + case 24: + player.getInventory().remove(TouristTrap.TECHNICAL_PLANS); + npc("We are forever grateful for this gift. My advisor have", "discovered some secrets which we will share with you."); + stage++; + break; + case 25: + interpreter.sendDialogue("Al Shabim's advisors show you some advanced techniques for making", "the new weapon."); + stage++; + break; + case 26: + npc("Please accept this selection of six bronze throwing darts", "as a token of our appreciation."); + stage++; + break; + case 27: + player.getInventory().add(BRONZE_DARTS, player); + interpreter.sendItemMessage(806, "You receive six bronze throwing darts from Al Shabim."); + stage = player.getInventory().containsItem(TouristTrap.BEDABIN_KEY) ? 28 : 29; + break; + case 28: + player.getInventory().remove(TouristTrap.BEDABIN_KEY); + npc("I'll take that key off your hands as well effendi! Many", "thanks."); + stage++; + break; + case 29: + quest.setStage(player, 60); + player.getInventory().remove(TouristTrap.PROTOTYPE_DART); + player.getInventory().add(TouristTrap.TENTI_PINEAPPLE); + interpreter.sendItemMessage(806, "*** Dart Construction ***", "Congratulations! You can now construct darts."); + stage++; + break; + } + break; + case 50: + switch (stage) { + case 0: + npc("I am Al Shabim, greetings on behalf of the Bedabin", "nomads. Now... what can I do for you?"); + stage++; + break; + case 1: + player("I am looking for a pineapple."); + stage++; + break; + case 2: + npc("Oh yes, well that is interesting. Our sweet pineapples", "are renowned throughout the whole of Kharid! and I'll", "give you one if you do me a favour?"); + stage++; + break; + case 3: + player("Oh yes?"); + stage++; + break; + case 4: + npc("Captain Siad at the mining camp is holding some secret", "information. It is very important to us and we would", "like you to get it for us. It gives details of an", "interesting, yet ancient weapon."); + stage++; + break; + case 5: + npc("We would gladly share this information with you. All", "you have to do is gain access to his private room", "upstairs. We have a key for the chest that contains this", "information. Are you interested in our deal?"); + stage++; + break; + case 6: + player("Yes, I'm interested."); + stage++; + break; + case 7: + npc("That's great Effendi!"); + stage++; + break; + case 8: + npc("Here is a copy of the key that should give you access", "to the chest."); + stage++; + break; + case 9: + quest.setStage(player, 51); + player.getInventory().add(TouristTrap.BEDABIN_KEY, player); + interpreter.sendItemMessage(TouristTrap.BEDABIN_KEY, "Al Shabim gives you a key."); + stage++; + break; + } + break; + case 51: + case 52: + case 53: + switch (stage) { + case 0: + if (player.getInventory().containsItem(TouristTrap.TECHNICAL_PLANS)) { + npc("Aha! I see you have the plans. This is great! However,", "these plans do indeed look very technical. My people", "have further need of your skills."); + stage = 20; + } else { + if (!player.hasItem(TouristTrap.BEDABIN_KEY)) { + player("I seemed to have lost the key..."); + stage++; + } else { + npc("Have you found the plans yet?"); + stage = 3; + } + } + break; + case 1: + npc("Ahh Effendi, it's a good thing I have a spare!"); + stage++; + break; + case 2: + player.getInventory().add(TouristTrap.BEDABIN_KEY, player); + interpreter.sendItemMessage(TouristTrap.BEDABIN_KEY, "Al Shabim gives you a key."); + stage = 11; + break; + case 3: + player("No, sorry. I'm still looking for them."); + stage++; + break; + case 4: + npc("Okay, Effendi!"); + stage = 11; + break; + case 10: + npc("Bring us back the plans inside the chest, they should be", "sealed. All haste to you Effendi!"); + stage = 11; + break; + case 11: + end(); + break; + case 20: + npc("If you can help us to manufacture this item, we will", "share its secret with you. Does this deal interest you", "effendi?"); + stage++; + break; + case 21: + player("Yes, I'm very interested."); + stage++; + break; + case 22: + npc("Okay Effendi, you need to follow the plans. You will", "need some special tools for this... There is an anvil in", "the other tent. You have my permission to use it, but", "show the plans to the guard."); + stage++; + break; + case 23: + quest.setStage(player, 54); + end(); + break; + } + break; + case 100: + case 60: + case 70: + case 80: + case 90: + switch (stage) { + case 0: + if (quest.getStage(player) == 60 && !player.hasItem(TouristTrap.TENTI_PINEAPPLE)) { + player.getInventory().add(TouristTrap.TENTI_PINEAPPLE, player); + interpreter.sendItemMessage(TouristTrap.TENTI_PINEAPPLE, "You receive a tasty looking pineapple from Al Shabim."); + stage++; + stage = 32; + break; + } + npc("Many thanks with helping previously Effendi!"); + stage++; + break; + case 30: + npc("Oh, and here is your pineapple!"); + stage++; + break; + case 31: + interpreter.sendItemMessage(TouristTrap.TENTI_PINEAPPLE, "You receive a tasty looking pineapple from Al Shabim."); + stage++; + break; + case 32: + end(); + break; + case 1: + end(); + break; + } + break; + default: + switch (stage) { + case 0: + player("Hi"); + stage++; + break; + case 1: + end(); + break; + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 832 }; + } + +} diff --git a/Server/src/main/content/region/desert/quest/thetouristrap/AnaDialogue.java b/Server/src/main/content/region/desert/quest/thetouristrap/AnaDialogue.java new file mode 100644 index 0000000..efb9497 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/thetouristrap/AnaDialogue.java @@ -0,0 +1,337 @@ +package content.region.desert.quest.thetouristrap; + +import content.data.Quests; +import core.game.dialogue.DialoguePlugin; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.plugin.Plugin; +import core.plugin.ClassScanner; + +/** + * The dialogue plugin used to handle the ana npc. + * @author 'Vexia + * @version 1.0 + */ +public final class AnaDialogue extends DialoguePlugin { + + /** + * The quest instance. + */ + private Quest quest; + + /** + * Constructs a new {@code AnaDialogue} {@code Object}. + */ + public AnaDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code AnaDialogue} {@code Object}. + * @param player the player. + */ + public AnaDialogue(final Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new AnaDialogue(player); + } + + @Override + public void init() { + super.init(); + ClassScanner.definePlugin(new AnaNPC()); + ClassScanner.definePlugin(new AnaBarrelHandler()); + } + + @Override + public boolean open(Object... args) { + quest = player.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP); + if ((quest.getStage(player) == 71 || quest.getStage(player) == 72) && args.length > 1) { + player.getDialogueInterpreter().sendDialogue("You see a barrel coming to the surface. Before too long you haul it", "onto the side. The barrel seems quite heavy and you hear a muffled", "sound coming from inside."); + stage = 400; + return true; + } + switch (quest.getStage(player)) { + case 98: + switch (stage) { + case 0: + npc("Great! Thanks for getting me out of that mine! And", "that barrel wasn't too bad anyway! Pop by again", "sometime, I'm sure we'll have a barrel of laughs!"); + stage++; + break; + } + break; + case 60: + player("Hello!"); + break; + case 61: + if (args.length > 1) { + npc("Hey, what do you think you're doing?"); + stage = 20; + return true; + } + player("Hello again!"); + break; + default: + player.getPacketDispatch().sendMessage("This slave does not appear interested in talking to you."); + end(); + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (quest.getStage(player)) { + case 98: + switch (stage) { + case 1: + npc("Oh! I nearly forgot! Here's a key I found in the", "tunnels. It might be some use to you, not sure what", "it opens. Sorry, but I have to go now."); + stage++; + break; + case 2: + interpreter.sendItemMessage(TouristTrap.WROUGHT_IRON_KEY, "Ana gives you a wrought iron key..."); + stage++; + break; + case 3: + player.getInventory().add(TouristTrap.WROUGHT_IRON_KEY, player); + player.getPacketDispatch().sendMessage("Ana spots Irena and waves..."); + NPC irena = RegionManager.getNpc(player, 4986); + irena.sendChat("Hi Ana!"); + quest.setStage(player, 98); + end(); + player.getDialogueInterpreter().open(4986, irena); + break; + } + break; + case 71: + switch (stage) { + case 400: + interpreter.sendDialogues(823, null, "Get me OUT OF HERE!"); + stage++; + break; + case 401: + quest.setStage(player, 72); + end(); + break; + } + break; + case 61: + switch (stage) { + case 0: + npc("Hello there, how's it going? Do you have a plan to get", "out of here yet?"); + stage++; + break; + case 1: + player("Well, I'm working on it, have you got any suggestions?"); + stage++; + break; + case 2: + npc("Hmmm."); + stage++; + break; + case 3: + npc("No, sorry..."); + stage++; + break; + case 4: + npc("The only thing that gets out of here is the rock that we", "mine."); + stage++; + break; + case 5: + npc("Not even the dead get a decent funeral. Bodies are", "just thrown down disused mine holes. It's very", "disrespectful..."); + stage++; + break; + case 6: + player("How does the rock get out?"); + stage++; + break; + case 7: + npc("Well, we mine it in this section, then someone scoops it", "into a barrel. The barrels are loaded onto a mine cart.", "Then they're deposited near the surface lift."); + stage++; + break; + case 8: + npc("I have no idea where they go from there. But that's", "not going to help us, is it?"); + stage++; + break; + case 9: + player("Where would I get one of those barrels from?"); + stage++; + break; + case 10: + npc("Well, you would get one from around by the life area.", "But why would you want one of those?"); + stage++; + break; + case 11: + player("I could try to sneak you out if you were in a barrel!"); + stage++; + break; + case 12: + npc("There is no way you are getting me into a barrel. No", "WAY! Do you understand?"); + stage++; + break; + case 13: + player("Well, we'll see, it might be the only way."); + stage++; + break; + case 14: + end(); + break; + case 20:// barrel dialogue. + if (player.getInventory().remove(TouristTrap.BARREL)) { + player.sendChat("Shush... It's for your own good!"); + player.getInventory().add(TouristTrap.ANNA_BARREL); + close(); + player.lock(3); + GameWorld.getPulser().submit(new Pulse(3, player) { + @Override + public boolean pulse() { + interpreter.sendDialogues(823, null, "-- You manage to squeeze Ana into the barrel, --", "-- despite her many complaints. --", "I djont fit in dis bawwel... Wet me out!!"); + stage++; + return true; + } + }); + } + break; + case 21: + end(); + break; + } + break; + case 60: + switch (stage) { + case 0: + npc("Hello there, I don't think I've seen you before."); + stage++; + break; + case 1: + player("What's your name?"); + stage++; + break; + case 2: + npc("My name? Oh, how sweet, my name is Ana. I come from", "Al-Kharid though we've only recently moved there. I was", "born, and did most of my growing up, in Varrock. I", "thought the desert might be interesting. What a surprise"); + stage++; + break; + case 3: + npc("I got!"); + stage++; + break; + case 4: + player("Do you want to go back to Al-Kharid?"); + stage++; + break; + case 5: + npc("Sure, I miss my Mum, her name is Irena and she is", "probably waiting for me. How do you propose we get out", "of here though?"); + stage++; + break; + case 6: + npc("I'm sure you've noticed the many square jawed guards", "around here. You look like you can handle yourself", "but I have my doubts that you can take them all on!"); + stage++; + break; + case 7: + quest.setStage(player, 61); + end(); + break; + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 822 }; + } + + /** + * The use with handler for the barrel on ana. + * @author 'Vexia + * @version 1.0 + */ + public static final class AnaBarrelHandler extends UseWithHandler { + + /** + * Constructs a new {@code AnaBarrelHandler} {@code Object}. + */ + public AnaBarrelHandler() { + super(TouristTrap.BARREL.getId()); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(822, NPC_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + final Quest quest = player.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP); + switch (quest.getStage(player)) { + case 61: + player.getDialogueInterpreter().open(822, event.getUsedWith(), true); + break; + default: + return false; + } + return true; + } + + } + + /** + * The ana npc. + * @author 'Vexia + * @version 1.0 + */ + public static final class AnaNPC extends AbstractNPC { + + /** + * Constructs a new {@code AnaNPC} {@code Object}. + */ + public AnaNPC() { + super(0, null); + } + + /** + * Constructs a new {@code AnaNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + public AnaNPC(int id, Location location) { + super(id, location); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new AnaNPC(id, location); + } + + @Override + public boolean isHidden(final Player player) { + Quest quest = player.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP); + if (quest.getStage(player) > 61) { + return true; + } + return player.getInventory().containsItem(TouristTrap.ANNA_BARREL) || player.getBank().containsItem(TouristTrap.ANNA_BARREL); + } + + @Override + public int[] getIds() { + return new int[] { 822 }; + } + + } +} diff --git a/Server/src/main/content/region/desert/quest/thetouristrap/BedabinNomadDialogue.java b/Server/src/main/content/region/desert/quest/thetouristrap/BedabinNomadDialogue.java new file mode 100644 index 0000000..420714f --- /dev/null +++ b/Server/src/main/content/region/desert/quest/thetouristrap/BedabinNomadDialogue.java @@ -0,0 +1,204 @@ +package content.region.desert.quest.thetouristrap; + +import content.data.Quests; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; + +/** + * The dialogue plugin used for the bedabin nomad npcs. + * @author 'Vexia + * @version 1.0 + */ +public final class BedabinNomadDialogue extends DialoguePlugin { + + /** + * The quest instance. + */ + private Quest quest; + + /** + * Constructs a new {@code BedabinNomadDialogue} {@code Object}. + */ + public BedabinNomadDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code BedabinNomadDialogue} {@code Object}. + * @param player the player. + */ + public BedabinNomadDialogue(final Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new BedabinNomadDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + quest = player.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP); + switch (npc.getId()) { + case 834:// guard + switch (quest.getStage(player)) { + default: + npc("Sorry, but you can't use the tent without permission."); + break; + case 54: + if (player.getInventory().containsItem(TouristTrap.TECHNICAL_PLANS)) { + player("Al Shabim said I could enter, here are the plans!"); + stage++; + } else { + npc("Sorry, but you can't use the tent without permission."); + } + break; + case 100: + npc("Sorry, but you can't use the tent without permission. But", "thanks for all your help with the Bedabin people."); + break; + } + break; + case 833:// nomad + case 1239:// fighter + npc("Hello Effendi! How can I help you?"); + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (npc.getId()) { + case 834:// guard + switch (quest.getStage(player)) { + default: + end(); + break; + case 54: + switch (stage) { + case 0: + end(); + break; + case 1: + npc("Okay, go ahead."); + stage = 2; + break; + case 2: + end(); + final Scenery door = RegionManager.getObject(new Location(3169, 3046, 0)); + if (door.getId() != 2701) + SceneryBuilder.replace(door, door.transform(2701), 2); + player.getWalkingQueue().reset(); + player.getWalkingQueue().addPath(3169, 3046); + player.getPacketDispatch().sendMessage("You walk into the tent."); + break; + } + break; + case 100: + end(); + break; + } + break; + case 833:// nomad + switch (stage) { + case 0: + options("What is this place?", "Where is Shantay Pass?", "What do you have to sell?", "Okay, thanks."); + stage++; + break; + case 1: + switch (buttonId) { + case 1: + player("What is this place?"); + stage = 10; + break; + case 2: + player("Where is Shantay pass?"); + stage = 20; + break; + case 3: + npc.openShop(player); + end(); + break; + case 4: + player("Okay, thanks."); + stage = 40; + break; + } + case 10: + npc("This is the camp of Bedabin. Talk to our leader, Al", "Shabim, he'll be happy to chat. We can sell you very", "reasonably priced water..."); + stage++; + break; + case 11: + end(); + break; + case 20: + npc("It is North East of here effendi, across the trackless", "desert. It will be a thirsty trip."); + stage = 41; + break; + case 40: + case 41: + end(); + break; + } + break; + case 1239:// fighter + switch (stage) { + case 0: + options("What is this place?", "Where is Shantay Pass?", "Okay, thanks."); + stage++; + break; + case 1: + switch (buttonId) { + case 1: + player("What is this place?"); + stage = 10; + break; + case 2: + player("Where is Shantay pass?"); + stage = 20; + break; + case 3: + player("Okay, thanks."); + stage = 40; + break; + } + break; + case 10: + npc("This is the camp of Bedabin. Talk to our leader, Al", "Shabim, he'll be happy to chat. We can sell you very", "reasonably priced water..."); + stage++; + break; + case 11: + end(); + break; + case 20: + npc("It is North East of here effendi, across the trackless", "desert. It will be a thirsty trip."); + stage = 41; + break; + case 40: + case 41: + end(); + break; + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { /** bedabin nomad guard */ + 834, /** bedabin nomad */ + 833, /** bedabin nomad fighter */ + 1239 }; + } + +} diff --git a/Server/src/main/content/region/desert/quest/thetouristrap/CaptainSiadDialogue.java b/Server/src/main/content/region/desert/quest/thetouristrap/CaptainSiadDialogue.java new file mode 100644 index 0000000..9de225a --- /dev/null +++ b/Server/src/main/content/region/desert/quest/thetouristrap/CaptainSiadDialogue.java @@ -0,0 +1,135 @@ +package content.region.desert.quest.thetouristrap; + +import content.data.Quests; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; + +/** + * The dialogue used for the captain siad npc. + * @author 'Vexia + * @version 1.0 + */ +public final class CaptainSiadDialogue extends DialoguePlugin { + + /** + * The quest instance. + */ + private Quest quest; + + /** + * Constructs a new {@code CaptainSiadDialogue} {@code Object}. + */ + public CaptainSiadDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code CaptainSiadDialogue} {@code Object}. + * @param player the player. + */ + public CaptainSiadDialogue(final Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new CaptainSiadDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + quest = player.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP); + switch (quest.getStage(player)) { + default: + player.getPacketDispatch().sendMessage("The captain looks up from his work as you address him."); + npc("What are you doing in here?"); + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (quest.getStage(player)) { + case 52: + switch (stage) { + case 0: + player("I wanted to have a chat?"); + stage++; + break; + case 1: + npc("You don't belong in here, get out!"); + stage++; + break; + case 2: + player("You seem to have a lot of books!"); + stage++; + break; + case 3: + npc("Yes, I do. Now please get to the point?"); + stage++; + break; + case 4: + player("So, you're interested in sailing?"); + stage++; + break; + case 5: + interpreter.sendDialogue("The captain's interest seems to perk up."); + stage++; + break; + case 6: + npc("Well, yes actually... It's been a passion of mine for", "some years..."); + stage++; + break; + case 7: + player("I could tell by the cut of your jib."); + stage++; + break; + case 8: + npc("Oh yes? Really?"); + stage++; + break; + case 9: + npc("Well, I was quite a catch in my day you know!"); + stage++; + break; + case 10: + interpreter.sendDialogue("The captain starts rambling on about his days as a salty sea dog. He", "looks quite distracted..."); + stage++; + break; + case 11: + end(); + quest.setStage(player, 53); + break; + } + break; + default: + switch (stage) { + case 0: + player("I wanted to have a chat?"); + stage++; + break; + case 1: + npc("You don't belong in here, get out!"); + stage++; + break; + case 2: + end(); + break; + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 831 }; + } + +} diff --git a/Server/src/main/content/region/desert/quest/thetouristrap/DesertGuardDialogue.java b/Server/src/main/content/region/desert/quest/thetouristrap/DesertGuardDialogue.java new file mode 100644 index 0000000..9c9a083 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/thetouristrap/DesertGuardDialogue.java @@ -0,0 +1,370 @@ +package content.region.desert.quest.thetouristrap; + +import java.util.List; + +import content.data.Quests; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.plugin.ClassScanner; +import core.tools.RandomFunction; + +/** + * Represents the mining desert camp guard dialogue. + * @author 'Vexia + * @version 1.0 + */ +public final class DesertGuardDialogue extends DialoguePlugin { + + /** + * Represents the quest. + */ + private Quest quest; + + /** + * Constructs a new {@code DesertGuardDialogue} {@code Object}. + */ + public DesertGuardDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code DesertGuardDialogue} {@code Object}. + * @param player the player. + */ + public DesertGuardDialogue(final Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new DesertGuardDialogue(player); + } + + @Override + public void init() { + super.init(); + ClassScanner.definePlugin(new DesertGuardNPC()); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + quest = player.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP); + switch (npc.getId()) { + case 5001: + switch (quest.getStage(player)) { + default: + npc("What are you looking at?"); + break; + case 40: + npc("Yeah, what do you want?"); + break; + case 50: + case 51: + case 52: + case 53: + case 54: + if (player.getInventory().containsItem(TouristTrap.TENTI_PINEAPPLE)) { + player("Hey... I have something for you!"); + stage = 0; + } else { + npc("Do you have my tenti pineapple yet?"); + stage = 10; + } + break; + case 60: + case 70: + case 80: + case 90: + case 100: + if (stage == 60) { + end(); + return true; + } + npc("That pineapple was just delicious, many thanks. I don't", "suppose you could get me another? -- The guard looks at", "you pleadingly."); + break; + } + break; + default: + switch (quest.getStage(player)) { + default: + npc("What are you looking at?"); + break; + } + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (npc.getId()) { + case 5001: + switch (quest.getStage(player)) { + case 51: + case 52: + case 53: + case 54: + switch (stage) { + case 0: + interpreter.sendItemMessage(TouristTrap.TENTI_PINEAPPLE, "You show the Tenti pineapple to the guard."); + stage++; + break; + case 1: + if (player.getInventory().remove(TouristTrap.TENTI_PINEAPPLE)) { + quest.setStage(player, 60); + npc("Great! Just what I've been looking for! Mmmmmmm...", "Delicious! This is so nice! Mmmmm, *SLURP*", "Yummmm... Oh yes, this is great."); + stage = 10; + } + break; + case -10: + player("Sorry, I don't have it yet."); + stage = -11; + break; + case -11: + end(); + break; + case 10: + player("So, can I go through now please?"); + stage++; + break; + case 11: + npc("Yes, yes, of course... a deal's a deal!"); + stage++; + break; + case 12: + end(); + break; + } + break; + case 50: + switch (stage) { + case 0: + interpreter.sendItemMessage(TouristTrap.TENTI_PINEAPPLE, "You show the Tenti pineapple to the guard."); + stage++; + break; + case 1: + if (player.getInventory().remove(TouristTrap.TENTI_PINEAPPLE)) { + quest.setStage(player, 60); + npc("Great! Just what I've been looking for! Mmmmmmm...", "Delicious!! This is so nice! Mmmmm, *SLURP*", "Yummmm... Oh yes, this is great."); + stage = 10; + } + break; + case 10: + player("Sorry, I don't have it yet."); + stage++; + break; + case 11: + end(); + break; + } + break; + case 40: + switch (stage) { + case 0: + player("I'd like to mine in a different area."); + stage++; + break; + case 1: + npc("Oh, you want to work in another area of the mine eh?", "-- The guard seems pleased with his rhetorical question.--", "Well, I can understand that! A change is as good as a", "rest they say."); + stage++; + break; + case 2: + player("Yes sir, you're quite right sir."); + stage++; + break; + case 3: + npc("Of course I'm right. And what goes around comes", "around as they say. And it's been absolutely ages since", "I've had anything different to eat."); + stage++; + break; + case 4: + npc("What I wouldn't give for some whole, fresh, ripe and", "juicy pineapple for a change. And those Tenti's have the", "best pineapple in this entire area."); + stage++; + break; + case 5: + interpreter.sendDialogue("The guard winks at you."); + stage++; + break; + case 6: + npc("I'm sure you get my meaning..."); + stage++; + break; + case 7: + player("Yes sir, we understand each other perfectly."); + stage++; + break; + case 8: + npc("Okay, good the. And remember, I prefer my", "pineapples whole, not chopped up with all the juice gone."); + stage++; + break; + case 9: + interpreter.sendDialogue("The guard moves back to his post and winks at you knowingly."); + stage++; + break; + case 10: + quest.setStage(player, 50); + end(); + break; + } + break; + case 100: + case 60: + switch (stage) { + case 0: + player("You must be joking! The last one I got you cost me", "double shifts working copper ore! You should be", "grateful you got one at all."); + stage++; + break; + case 1: + end(); + break; + case 10: + player("So, can I go through now please?"); + stage++; + break; + case 11: + npc("Yes, yes, of course... a deal's a deal!"); + stage++; + break; + case 12: + end(); + break; + } + break; + default: + end(); + break; + } + break; + default: + switch (quest.getStage(player)) { + default: + end(); + break; + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 4993, 4994, 4995, 4996, 4997, 4998, 4999, 5000, 5001 }; + } + + /** + * The desert guard npc. + * @author 'Vexia + */ + public static final class DesertGuardNPC extends AbstractNPC { + + /** + * Represents the last check. + */ + private int lastCheck; + + /** + * Constructs a new {@code DesertGuardNPC} {@code Object}. + */ + public DesertGuardNPC() { + super(0, null); + } + + /** + * Constructs a new {@code DesertGuardNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + public DesertGuardNPC(int id, Location location) { + super(id, location); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new DesertGuardNPC(id, location); + } + + @Override + public void tick() { + if (lastCheck < GameWorld.getTicks()) { + lastCheck = GameWorld.getTicks() + RandomFunction.random(50, 150); + if (!inCombat()) { + warn(); + } + } + super.tick(); + } + + /** + * Method used to warn players whom are breaking rules. + */ + private void warn() { + final List players = RegionManager.getLocalPlayers(this); + for (final Player player : players) { + if (player.getAttribute("guard-warning", 0) > GameWorld.getTicks() || !player.getZoneMonitor().isInZone("mining camp") || player.inCombat() || !player.getLocation().withinDistance(this.getLocation(), 8)) { + continue; + } + if (TouristTrap.inJail(player)) { + continue; + } + if (!TouristTrap.hasSlaveClothes(player)) { + player.setAttribute("guard-warning", GameWorld.getTicks() + 300); + player.lock(); + GameWorld.getPulser().submit(new Pulse(1, this, player) { + int count; + + @Override + public boolean pulse() { + switch (++count) { + case 1: + face(player); + if (!TouristTrap.hasSlaveClothes(player)) { + sendChat("Hey, they're interesting clothes!"); + player.getPacketDispatch().sendMessage("Guard: You're no slave."); + } else { + sendChat("Hey - you with the armour!"); + player.getPacketDispatch().sendMessage("Guard: Hey - You with the armour!"); + } + break; + case 5: + if (!TouristTrap.hasSlaveClothes(player)) { + sendChat("You're no slave."); + player.getPacketDispatch().sendMessage("Guard: What are you doing in here?"); + } else { + sendChat("You're not allowed in here!"); + player.getPacketDispatch().sendMessage("Guard: You're not allowed in here!"); + } + break; + case 8: + sendChat("Intel the cell you go! I hope this teaches you a lesson."); + getProperties().getCombatPulse().attack(player); + break; + case 10: + if (!TouristTrap.inJail(player)) { + TouristTrap.jail(player); + } + break; + } + return false; + } + }); + break; + } + } + } + + @Override + public int[] getIds() { + return new int[] { 4993, 4994, 4995, 4996, 4997, 4998, 4999, 5000, 5001, 5002 }; + } + + } +} diff --git a/Server/src/main/content/region/desert/quest/thetouristrap/IrenaDialogue.java b/Server/src/main/content/region/desert/quest/thetouristrap/IrenaDialogue.java new file mode 100644 index 0000000..8788371 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/thetouristrap/IrenaDialogue.java @@ -0,0 +1,238 @@ +package content.region.desert.quest.thetouristrap; + +import content.data.Quests; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; + +/** + * Represents the irena dialogue used during tourist trap. + * @author 'Vexia + * @version 1.0 + */ +public final class IrenaDialogue extends DialoguePlugin { + + /** + * The array of skills to choose. + */ + private static final int[] SKILLS = new int[] { Skills.FLETCHING, Skills.AGILITY, Skills.SMITHING, Skills.THIEVING }; + + /** + * Represents the quest. + */ + private Quest quest; + + /** + * Constructs a new {@code IrenaDialogue} {@code Object}. + */ + public IrenaDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code IrenaDialogue} {@code Object}. + * @param player the player. + */ + public IrenaDialogue(final Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new IrenaDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + quest = player.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP); + if (quest.getStage(player) == 95 && player.getInventory().containsItem(TouristTrap.ANNA_BARREL)) { + npc("Hey, great you've found Ana!"); + stage = 900; + return true; + } + switch (quest.getStage(player)) { + case 98: + npc("Thank you very much for returning my daughter to", "me. I'm really very grateful... I would like to reward", "you for your bravery and daring."); + stage++; + break; + case 0: + interpreter.sendDialogue("Irena seems to be very upset and cries as you approach her."); + break; + case 100: + case 95: + case 99: + player.getPacketDispatch().sendMessage("Irena seems happy now that her daughter has returned home."); + npc("Thanks so much for returning my daughter to me.", "I expect that she will go on another trip soon though.", "She is the adventurous type... a bit like yourself really!", "Okay, see you around then!"); + break; + default: + npc("*Sob* Have you found my daughter yet?"); + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 900: + interpreter.sendDialogues(823, null, "-- You show Irena the barrel with Ana in it. --", "Hey great, there's my Mum!"); + stage++; + return true; + case 901: + player.getInventory().remove(TouristTrap.ANNA_BARREL); + end(); + quest.setStage(player, 98); + player.getDialogueInterpreter().open(822); + return true; + } + switch (quest.getStage(player)) { + case 98:// reward. + switch (stage) { + case 1: + npc("I can offer you increased knowledge in two of the", "following areas."); + stage++; + break; + case 2: + options("Fletching.", "Agility.", "Smithing.", "Thieving."); + stage++; + break; + case 3: + player.setAttribute("first-skill", buttonId); + npc("Okay, now choose your second skills."); + stage++; + break; + case 4: + options("Fletching.", "Agility.", "Smithing.", "Thieving."); + stage++; + break; + case 5: + player.setAttribute("second-skill", buttonId); + npc("Okay, that's all the skills I can teach you!"); + stage++; + break; + case 6: + int skills[] = new int[] { SKILLS[player.getAttribute("first-skill", 0) - 1], SKILLS[player.getAttribute("second-skill", 0) - 1] }; + for (int i : skills) { + player.getSkills().addExperience(i, 4650); + } + quest.finish(player); + end(); + break; + } + break; + case 0: + switch (stage) { + case 0: + if (quest.hasRequirements(player)) { + npc("Boo hoo! Oh dear, my only daughter...."); + stage++; + } else { + npc("Boo hoo! Go away!"); + stage = 99; + } + break; + case 1: + player("What's the matter?"); + stage++; + break; + case 2: + npc("Oh dear... my daughter, Ana, has gone missing in the", "desert. I fear that she is lost, or perhaps... *sob* even", "worse."); + stage++; + break; + case 3: + player("When did she go into the desert?"); + stage++; + break; + case 4: + npc("*Sob* she went in there just a few days ago, *Sob*", "she said she would be back yesterday."); + stage++; + break; + case 5: + npc("*Sob* And she's not..."); + stage++; + break; + case 6: + player("Is there a reward if I get her back?"); + stage++; + break; + case 7: + npc("Well, yes, you'll have my gratitude young man."); + stage++; + break; + case 8: + npc("And I'm sure that Ana will also be very pleased! And I", "may see if I can get a small reward together... But I", "cannot promise anything. So does that mean that you'll", "look for her then?"); + stage++; + break; + case 9: + player("Okay Irena, calm down. I'll get your daughter back for", "you."); + stage++; + break; + case 10: + npc("That would be great! That's really very nice of you!", "She was wearing a red silk scarf when she left."); + stage++; + break; + case 11: + npc("Are you 'really' sure you want to do this? I mean, go", "on this quest?"); + stage++; + break; + case 12: + player("Yes, I'll go on this quest!"); + stage++; + break; + case 13: + npc("Oh thank you! You've made me a very happy mother, I", "just hope it's not too late!"); + stage++; + break; + case 14: + player("Do you have any other hints on where she may have", "gone?"); + stage++; + break; + case 15: + npc("I did go looking for her myself and I came across some", "footprints just a little way south. I'm worried that they", "lead to the desert mining camp."); + stage++; + break; + case 16: + quest.start(player); + end(); + break; + case 99: + end(); + break; + } + break; + case 10: + switch (stage) { + case 0: + player("No, not yet."); + stage++; + break; + case 1: + npc("Please! Hurry up."); + stage++; + break; + case 2: + end(); + break; + } + break; + case 100: + case 95: + case 99: + player.getPacketDispatch().sendMessage("Irena goes back to work."); + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 4986 }; + } + +} diff --git a/Server/src/main/content/region/desert/quest/thetouristrap/MaleSlaveDialogue.java b/Server/src/main/content/region/desert/quest/thetouristrap/MaleSlaveDialogue.java new file mode 100644 index 0000000..269f418 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/thetouristrap/MaleSlaveDialogue.java @@ -0,0 +1,365 @@ +package content.region.desert.quest.thetouristrap; + +import content.data.Quests; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.tools.RandomFunction; + +/** + * The dialogue for the male slave at the desert camp. + * @author 'Vexia + * @version 1.0 + */ +public final class MaleSlaveDialogue extends DialoguePlugin { + + /** + * The quest instance. + */ + private Quest quest; + + /** + * Constructs a new {@code MaleSlaveDialogue} {@code Object}. + */ + public MaleSlaveDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code MaleSlaveDialogue} {@code Object}. + * @param player the player. + */ + public MaleSlaveDialogue(final Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new MaleSlaveDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + quest = player.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP); + switch (npc.getShownNPC(player).getId()) { + case 4985: + case 825: + switch (quest.getStage(player)) { + case 40: + npc("Do you want to trade clothes now?"); + break; + case 30: + npc("Hello again, do you want to try and unlock my chains?", "I'd really appreciate it!"); + break; + case 20: + npc("You look like a new 'recruit'. How long have you been", "here?"); + break; + case 100: + npc("Oh bother, I was caught by the guards again... Listen, if", "you can get me some Desert Clothes, I'll trade you for my", "slave clothes again... Do you want to trade?"); + break; + default: + npc("Please, just leave me alone my life is", "terrible as it is."); + break; + } + break; + case 826: + switch (quest.getStage(player)) { + default: + npc("Yay! I'm finally free."); + stage = 0; + break; + } + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (npc.getShownNPC(player).getId()) { + case 4985: + case 825: + switch (quest.getStage(player)) { + case 30: + switch (stage) { + case 0: + player("Yeah, okay, let's give it a go."); + stage++; + break; + case 1: + quest.setStage(player, 40); + npc("Great! You did it! Do you want to trade clothes now?"); + stage = 0; + break; + } + break; + case 40: + switch (stage) { + case 0: + player("Yes, I'll trade."); + stage = 11; + break; + case 11: + if (!TouristTrap.hasDesertClothes(player)) { + npc("I need desert boots, a desert robe and a desert", "shirt if you want these clothes off me."); + stage++; + } else { + npc("Great! You have the Desert Clothes! -- the slave starts", "undressing right in front of you -- Okay, here's the", "clothes, I won't need them anymore."); + stage += 2; + } + break; + case 12: + end(); + break; + case 13: + interpreter.sendItemMessage(1845, "The slave gives you his dirty, flea infested robe."); + stage++; + break; + case 14: + interpreter.sendItemMessage(1844, "The slave gives you his muddy, sweat soaked shirt."); + stage++; + break; + case 15: + interpreter.sendItemMessage(1846, "The slave gives you a smelly pair of decomposing boots."); + stage++; + break; + case 16: + if (player.getEquipment().remove(TouristTrap.DESERT_CLOTHES)) { + stage++; + npc("Right, I'm off! Good luck!"); + TouristTrap.addConfig(player, (1 << 4)); + for (Item item : TouristTrap.SLAVE_CLOTHES) { + player.getEquipment().add(item, true, false); + } + player.getPacketDispatch().sendMessages("The slave takes your desert robe.", "The slave takes your desert shirt.", "The slave takes your desert boots."); + } + break; + case 17: + player("Yeah, good luck to you too!"); + break; + } + break; + case 20: + switch (stage) { + case 0: + player("I've just arrived."); + stage++; + break; + case 1: + npc("Yeah, it looks like it as well. It's a shame that I won't be", "around long enough to get to know you. I'm making a", "break for it today. I have a plan to get out of here! It's", "amazing in its sophistication."); + stage++; + break; + case 2: + player("Oh yes, that sounds interesting."); + stage++; + break; + case 3: + npc("Yes, it is actually. I have all the details figured out", "except for one."); + stage++; + break; + case 4: + player("What's that then?"); + stage++; + break; + case 5: + npc("-- The slave rattles the chains on his arms loudly. --", "These bracelets, I can't seem to get them off. If I", "could get them off, I'd be able to climb my way out of", "here."); + stage++; + break; + case 6: + player("I can try to undo them for you."); + stage++; + break; + case 7: + npc("Really, that would be great... --The slave looks at you", "strangely. -- Hang on a minute... I suppose you want", "something for doing this?"); + stage++; + break; + case 8: + npc("The last time I did a trade in this place, I nearly lost", "the shirt from my back!"); + stage++; + break; + case 9: + player("It's funny you should say that actually."); + stage++; + break; + case 10: + npc("-- the slave looks at you blankly. --"); + stage++; + break; + case 11: + npc("Yeah, go on!"); + stage++; + break; + case 12: + player("If I can get the chains off, you have to give me", "something, okay?"); + stage++; + break; + case 13: + npc("Sure, what do you want?"); + stage++; + break; + case 14: + player("I want your clothes!"); + stage++; + break; + case 15: + npc("Blimey!"); + stage++; + break; + case 16: + player("I can dress like a slave and gain access to the mine", "area to scout it out."); + stage++; + break; + case 17: + npc("You're either incredibly brave or incredibly stupid. But", "what would I wear if you take my clothes? Get me", "some nice desert clothes and I'll think about it?"); + stage++; + break; + case 18: + npc("Do you still want to try and undo the locks for me?"); + stage++; + break; + case 19: + player("Yeah, okay, let's give it a go."); + stage++; + break; + case 20: + npc("Great!"); + stage++; + break; + case 21: + interpreter.sendDialogue("You use some nearby bits of wood and wire to try and pick the lock."); + stage++; + break; + case 22: + final int random = RandomFunction.random(3); + if (random == 1) { + interpreter.sendDialogue("You didn't manage to pick the lock this time would you like another", "go?"); + stage++; + } else if (random == 2) { + interpreter.sendDialogue("A nearby guard spots you!"); + stage = 24; + } else { + quest.setStage(player, 40); + npc("Great! You did it! Do you want to trade clothes now?"); + stage = 0; + } + break; + case 23: + player("Yeah, I'll give it another go."); + stage = 21; + break; + case 24: + player.lock(); + interpreter.sendDialogues(getIds()[0], null, true, "Oh oh!"); + GameWorld.getPulser().submit(new Pulse(4, player) { + int counter; + + @Override + public boolean pulse() { + switch (++counter) { + case 1: + interpreter.sendDialogues(4993, null, true, "Oi, what are you two doing?"); + break; + case 2: + end(); + player.getPacketDispatch().sendMessage("Slave: Oh oh!"); + player.getPacketDispatch().sendMessage("Guard: Oi, what are you two doing?"); + ; + player.getPacketDispatch().sendMessage("The guards search you!"); + break; + case 3: + player.getPacketDispatch().sendMessage("You are roughed up by the guards and manhandled into a cell."); + break; + case 4: + player.unlock(); + quest.setStage(player, 30); + player.getProperties().setTeleportLocation(Location.create(3285, 3034, 0)); + return true; + } + return false; + } + }); + stage++; + break; + case 25: + interpreter.sendDialogues(4993, null, true, "Oi, what are you two doing?"); + break; + } + break; + case 100: + switch (stage) { + case 0: + player("Yes, I'll trade."); + stage++; + break; + case 1: + if (!TouristTrap.hasDesertClothes(player)) { + npc("I need desert boots, a desert robe and a desert", "shirt if you want these clothes off me."); + stage++; + break; + } + npc("Great! You have the Desert Clothes! -- the slave starts", "undressing right in front of you -- Okay, here's the", "clothes, I won't need them anymore."); + stage = 13; + break; + case 2: + end(); + break; + case 13: + interpreter.sendItemMessage(1845, "The slave gives you his dirty, flea infested robe."); + stage++; + break; + case 14: + interpreter.sendItemMessage(1844, "The slave gives you his muddy, sweat soaked shirt."); + stage++; + break; + case 15: + interpreter.sendItemMessage(1846, "The slave gives you a smelly pair of decomposing boots."); + stage++; + break; + case 16: + if (player.getEquipment().remove(TouristTrap.DESERT_CLOTHES)) { + stage++; + npc("Right, I'm off! Good luck!"); + TouristTrap.addConfig(player, (1 << 4)); + player.getEquipment().add(TouristTrap.SLAVE_CLOTHES); + player.getPacketDispatch().sendMessages("The slave takes your desert robe.", "The slave takes your desert shirt.", "The slave takes your desert boots."); + } + break; + case 17: + player("Yeah, good luck to you too!"); + break; + } + break; + default: + switch (stage) { + case 0: + end(); + break; + } + break; + } + break; + case 826: + switch (quest.getStage(player)) { + default: + end(); + break; + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 825, 826, 4985 }; + } + +} diff --git a/Server/src/main/content/region/desert/quest/thetouristrap/MercenaryCaptainDialogue.java b/Server/src/main/content/region/desert/quest/thetouristrap/MercenaryCaptainDialogue.java new file mode 100644 index 0000000..e020f67 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/thetouristrap/MercenaryCaptainDialogue.java @@ -0,0 +1,210 @@ +package content.region.desert.quest.thetouristrap; + +import content.data.Quests; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.Entity; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.world.map.Location; +import core.plugin.ClassScanner; + +/** + * Represents the mercenary captain dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +public final class MercenaryCaptainDialogue extends DialoguePlugin { + + /** + * Represents the quest. + */ + private Quest quest; + + /** + * Constructs a new {@code MercenaryCaptainDialogue} {@code Object}. + */ + public MercenaryCaptainDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code MercenaryCaptainDialogue} {@code Object}. + * @param player the player. + */ + public MercenaryCaptainDialogue(final Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new MercenaryCaptainDialogue(player); + } + + @Override + public void init() { + super.init(); + ClassScanner.definePlugin(new MercenaryCaptain()); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + quest = player.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP); + switch (quest.getStage(player)) { + case 11: + interpreter.sendDialogue("You approach the Mercenary Captain."); + break; + default: + npc("What are you doing here?"); + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (quest.getStage(player)) { + default: + switch (stage) { + case 0: + player("Nothing, just passing by."); + stage++; + break; + case 1: + end(); + break; + } + break; + case 11: + switch (stage) { + case 0: + player("Wow! A real captain!"); + stage++; + break; + case 1: + npc("Be off effendi, you are not wanted around here."); + stage++; + break; + case 2: + player("I'd love to work for a tough guy like you!"); + stage++; + break; + case 3: + npc("Hmmm, oh yes, what can you do?"); + stage++; + break; + case 4: + player("Can't I do something for a strong Captain like you?"); + stage++; + break; + case 5: + interpreter.sendDialogue("The Captain ponders a moment and then looks at you critically."); + stage++; + break; + case 6: + npc("You could bring me the head of Al Zaba Bhasim."); + stage++; + break; + case 7: + npc("He is the leader of the notorious desert bandits, they", "plague us daily. You should find them west of here.", "You should have no problem in finishing them all off.", "Do this for me and maybe I will consider helping you."); + stage++; + break; + case 8: + player("Sorry Sir, I don't think I can do that."); + stage++; + break; + case 9: + npc("Hmm, well yes, I did consider that you might not be", "right for the job. be off with you then before I turn", "my men loose on you."); + stage++; + break; + case 10: + player("It's a funny captain who can't fight his own battles!"); + stage++; + break; + case 11: + interpreter.sendDialogue("The men around you fall silent and the Captain silently fumes. All", "eyes turn to the Captain..."); + stage++; + break; + case 12: + npc("Very well, if you're challenging me, let's get on with it!"); + stage++; + break; + case 13: + interpreter.sendDialogue("The guards gather around to watch the fight."); + stage++; + break; + case 14: + end(); + npc.getProperties().getCombatPulse().attack(player); + break; + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 830 }; + } + + /** + * The mercenary captain npc. + * @author 'Vexia + */ + public static final class MercenaryCaptain extends AbstractNPC { + + /** + * Constructs a new {@code MercenaryCaptain} {@code Object}. + */ + public MercenaryCaptain() { + super(0, null); + } + + /** + * Constructs a new {@code MercenaryCaptain} {@code Object}. + * @param id the id.. + * @param location the location. + */ + public MercenaryCaptain(int id, Location location) { + super(id, location); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new MercenaryCaptain(id, location); + } + + @Override + public void finalizeDeath(Entity killer) { + super.finalizeDeath(killer); + if (killer instanceof Player) { + final Player player = (Player) killer; + final Quest quest = player.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP); + switch (quest.getStage(player)) { + case 0: + case 10: + + break; + default: + if (!player.getInventory().containsItem(TouristTrap.METAL_KEY) && !player.getBank().containsItem(TouristTrap.METAL_KEY)) { + player.getInventory().add(TouristTrap.METAL_KEY, player); + player.getDialogueInterpreter().sendItemMessage(TouristTrap.METAL_KEY, "The mercenary captain drops a metal key on the floor.", "You quickly grab the key and add it to your inventory."); + } + quest.setStage(player, 20); + break; + } + } + } + + @Override + public int[] getIds() { + return new int[] { 830 }; + } + + } +} diff --git a/Server/src/main/content/region/desert/quest/thetouristrap/MercenaryDialogue.java b/Server/src/main/content/region/desert/quest/thetouristrap/MercenaryDialogue.java new file mode 100644 index 0000000..4f06320 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/thetouristrap/MercenaryDialogue.java @@ -0,0 +1,205 @@ +package content.region.desert.quest.thetouristrap; + +import content.data.Quests; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; + +/** + * Represents the mercenary dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +public final class MercenaryDialogue extends DialoguePlugin { + + /** + * Represents the coins item to bribe. + */ + private static final Item COINS = new Item(995, 5); + + /** + * Represents the quest. + */ + private Quest quest; + + /** + * Constructs a new {@code MercenaryDialogue} {@code Object}. + */ + public MercenaryDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code MercenaryDialogue} {@code Object}. + * @param player the player. + */ + public MercenaryDialogue(final Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new MercenaryDialogue(player); + } + + @Override + public boolean open(Object... args) { + quest = player.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP); + switch (quest.getStage(player)) { + default: + npc("What are you doing here?"); + break; + case 10: + npc("Yeah, what do you want?"); + break; + case 100: + npc("What are you looking at?"); + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (quest.getStage(player)) { + default: + switch (stage) { + case 0: + player("Nothing, just passing by."); + stage++; + break; + case 1: + end(); + break; + } + break; + case 10: + switch (stage) { + case 0: + player("I'm looking for a woman called Ana, have you seen her?"); + stage++; + break; + case 1: + npc("No, now get lost!"); + stage++; + break; + case 2: + player("Perhaps five gold coins will help you remember?"); + stage++; + break; + case 3: + npc("Well, it certainly will help!"); + stage = 4; + break; + case 4: + if (!player.getInventory().containsItem(COINS)) { + player("Sorry, I don't seem to have enough coins."); + stage++; + break; + } + if (player.getInventory().remove(COINS)) { + interpreter.sendItemMessage(COINS, "-- The guard takes the five gold coins. --"); + stage = 6; + } + break; + case 5: + end(); + break; + case 6: + npc("Now then, what did you want to know?"); + stage++; + break; + case 7: + player("I'm looking for a woman called Ana, have you seen her?"); + stage++; + break; + case 8: + npc("Hmm, well, we get a lot of people in here. But not", "many women through... Saw one come in last week...."); + stage++; + break; + case 9: + npc("But I don't know if it's the woman you're looking for?"); + stage++; + break; + case 10: + player("What are you guarding?"); + stage = 11; + break; + case 11: + npc("Well, if you have to know, we're making sure that no", "prisoners get out. -- The guard gives you a", "disapproving look. -- And to make sure that", "unauthorised people don't get in."); + stage = 12; + break; + case 12: + npc("-- The guard looks around nervously. -- You'd better", "go soon before the Captain orders us to kill you."); + stage++; + break; + case 13: + player("Does the Captain order you to kill a lot of people?"); + stage++; + break; + case 14: + npc("-- The guard snorts. -- *Snort* Just about anyone", "who talks to him."); + stage++; + break; + case 15: + npc("Unless he has a use for you, he'll probably just order", "us to kill you. And it's such a horrible job cleaning up", "the mess afterwards."); + stage++; + break; + case 16: + player("Not to mention the senseless waste of human life."); + stage++; + break; + case 17: + npc("Huh? Them's your words, not mine."); + stage++; + break; + case 18: + player("It doesn't sound as if you respect your Captain much."); + stage++; + break; + case 19: + interpreter.sendDialogue("-- The guard looks around conspiratorially. --"); + stage++; + break; + case 20: + npc("Well, to be honest. We think he's not exactly as brave", "as he makes out. But we have to follow his orders. If", "someone called him a coward, or managed to trick him", "into a one-on-one duel many of us bet that he'd be"); + stage++; + break; + case 21: + npc("beaten."); + stage++; + break; + case 22: + player("And how could I trick him into a one-on-one duel?"); + stage++; + break; + case 23: + npc("Like all cowards, he likes to be made to feel important.", "If anyone insults him outright, he just gets us to do his", "dirty work. However, if he thinks he's better than you,", "if you compliment him, he may feel that he can defeat"); + stage = 24; + break; + case 24: + npc("you. And if he initiated a duel, all the men agreed that", "they wouldn't intervene. We think he'd be slaughtered", "in double quick time."); + stage++; + break; + case 25: + quest.setStage(player, 11); + end(); + break; + } + break; + case 100: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 4989, 4990, 4991, 4992 }; + } + +} diff --git a/Server/src/main/content/region/desert/quest/thetouristrap/MineSlaveNPC.java b/Server/src/main/content/region/desert/quest/thetouristrap/MineSlaveNPC.java new file mode 100644 index 0000000..c0e77e0 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/thetouristrap/MineSlaveNPC.java @@ -0,0 +1,60 @@ +package content.region.desert.quest.thetouristrap; + +import core.game.node.entity.npc.AbstractNPC; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.tools.RandomFunction; + +/** + * The mining slave npc at the desert camp. + * @author 'Vexia + */ +public final class MineSlaveNPC extends AbstractNPC { + + /** + * The random force chats to say. + */ + private static final String[] CHATS = new String[] { "I'm sick of this place.", "What I wouldn't give for a good nights rest.", "I feel so weak I could faint.", "I didn't want to be a miner anyway.", "Ooh my back.", "I'm rich in experience, poor in wealth.", "I can' think straight, i'm so tired." }; + + /** + * The delay until the next chat. + */ + private int delay; + + /** + * Constructs a new {@code MineSlaveNPC} {@code Object}. + */ + public MineSlaveNPC() { + super(0, null); + } + + /** + * Constructs a new {@code MineSlaveNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + public MineSlaveNPC(int id, Location location) { + super(id, location); + delay = GameWorld.getTicks() + RandomFunction.random(20, 100); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new MineSlaveNPC(id, location); + } + + @Override + public void tick() { + if (delay < GameWorld.getTicks()) { + sendChat(CHATS[RandomFunction.random(CHATS.length)]); + delay = GameWorld.getTicks() + RandomFunction.random(20, 100); + } + super.tick(); + } + + @Override + public int[] getIds() { + return new int[] { 4975, 4976, 4977, 4978 }; + } + +} diff --git a/Server/src/main/content/region/desert/quest/thetouristrap/MinecartDriverDialogue.java b/Server/src/main/content/region/desert/quest/thetouristrap/MinecartDriverDialogue.java new file mode 100644 index 0000000..a748227 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/thetouristrap/MinecartDriverDialogue.java @@ -0,0 +1,217 @@ +package content.region.desert.quest.thetouristrap; + +import content.data.Quests; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; + +/** + * The dialogue plugin used to handle the minecart driver. + * @author 'Vexia + * @version 1.0 + */ +public final class MinecartDriverDialogue extends DialoguePlugin { + + /** + * The coins item. + */ + private static final Item COINS = new Item(995, 100); + + /** + * The quest npc. + */ + private Quest quest; + + /** + * Constructs a new {@code MinecartDriverDialogue} {@code Object}. + * @param player the player. + */ + public MinecartDriverDialogue(final Player player) { + super(player); + } + + /** + * Constructs a new {@code MinecartDriverDialogue} {@code Object}. + */ + public MinecartDriverDialogue() { + /** + * empty. + */ + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new MinecartDriverDialogue(player); + } + + @Override + public boolean open(Object... args) { + quest = player.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP); + switch (quest.getStage(player)) { + case 90: + npc("Quickly, get in the back of the cart."); + break; + case 80: + interpreter.sendDialogue("The cart driver seems to be fastidiously cleaning his cart.", "It doesn't look as if he wants to be disturbed."); + break; + default: + player("Hello!"); + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (quest.getStage(player)) { + case 90: + switch (stage) { + case 0: + player("Okay, sorry."); + stage++; + break; + case 1: + end(); + break; + case 24: + end(); + break; + } + break; + case 80: + switch (stage) { + case 0: + player("Nice cart."); + stage++; + break; + case 1: + interpreter.sendDialogue("The cart driver looks around at you and tries to weigh you up."); + stage++; + break; + case 2: + npc("Hmmm."); + stage++; + break; + case 3: + interpreter.sendDialogue("He tuts to himself and starts checking the wheels."); + stage++; + break; + case 4: + player("One wagon wheel says to the other, 'I'll see you", "around'."); + stage++; + break; + case 5: + npc("-- The cart driver smirks a little. --"); + stage++; + break; + case 6: + interpreter.sendDialogue("He starts checking the steering on the cart."); + stage++; + break; + case 7: + player("One good turn deserves another."); + stage++; + break; + case 8: + interpreter.sendDialogue("The cart driver smiles a bit and then turns to you."); + stage++; + break; + case 9: + npc("Are you trying to get me fired?"); + stage++; + break; + case 10: + player("Fired.... no, shot perhaps!"); + stage++; + break; + case 11: + npc("Ha ha ha! -- The cart driver checks that", "guards aren't watching. -- What're you in fer?"); + stage++; + break; + case 12: + player("In for a penny in for a pound."); + stage++; + break; + case 13: + interpreter.sendDialogue("The cart drivers laughs at your pun..."); + stage++; + break; + case 14: + npc("Ha ha ha, oh stop it!"); + stage++; + break; + case 15: + interpreter.sendDialogue("The cart driver seems much happier now."); + stage++; + break; + case 16: + npc("What can I do for you anyway?"); + stage++; + break; + case 17: + player("Well, you see, it's like this..."); + stage++; + break; + case 18: + npc("Yeah!"); + stage++; + break; + case 19: + player("There's ten gold in it for you if you leave now no", "questions asked."); + stage++; + break; + case 20: + npc("If you're going to bribe me, at least make it worth my", "while. Now, let's say 100 Gold pieces should we? Ha ha", "ha!"); + stage++; + break; + case 21: + player("A hundred it is!"); + stage++; + break; + case 22: + npc("Great!"); + stage++; + break; + case 23: + if (!player.getInventory().containsItem(COINS)) { + player.getPacketDispatch().sendMessage("You need 100 gold coins."); + end(); + return true; + } + if (player.getInventory().remove(COINS)) { + quest.setStage(player, 90); + npc("Okay, get in the back of the cart then!"); + stage++; + } + break; + case 24: + end(); + break; + } + break; + default: + switch (stage) { + case 0: + npc("Hello, what do you want?"); + stage++; + break; + case 1: + player("Nothing, just passing by."); + stage++; + break; + case 2: + end(); + break; + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 841 }; + } + +} diff --git a/Server/src/main/content/region/desert/quest/thetouristrap/MiningCampZone.java b/Server/src/main/content/region/desert/quest/thetouristrap/MiningCampZone.java new file mode 100644 index 0000000..ae06c8e --- /dev/null +++ b/Server/src/main/content/region/desert/quest/thetouristrap/MiningCampZone.java @@ -0,0 +1,114 @@ +package content.region.desert.quest.thetouristrap; + +import content.data.Quests; +import core.game.interaction.Option; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneBuilder; +import core.plugin.Plugin; + +/** + * The map zone for the mining camp. + * @author 'Vexia + * @version 1.0 + */ +public final class MiningCampZone extends MapZone implements Plugin { + + /** + * Constructs a new {@code MiningCampZone} {@code Object}. + */ + public MiningCampZone() { + super("mining camp", true); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ZoneBuilder.configure(this); + return this; + } + + @Override + public boolean enter(Entity entity) { + return super.enter(entity); + } + + @Override + public boolean leave(Entity e, boolean logout) { + if (!logout && e instanceof Player) { + if (checkAnna((Player) e)) { + return false; + } + } + return super.leave(e, logout); + } + + @Override + public boolean interact(Entity e, final Node node, Option option) { + switch (option.getName()) { + case "Equip": + case "Wear": + final Player player = (Player) e; + GameWorld.getPulser().submit(new Pulse(1, player) { + @Override + public boolean pulse() { + if (TouristTrap.isJailable(player)) { + TouristTrap.jail(player, "Hey! What do you think you're doing!?"); + } + return true; + } + }); + break; + } + return super.interact(e, node, option); + } + + @Override + public boolean teleport(Entity entity, final int type, Node node) { + if (entity instanceof Player && type != -1) { + return !checkAnna((Player) entity); + } else { + return super.teleport(entity, type, node); + } + } + + /** + * Checks for anna. + * @param p the player. + * @return {@code True} if removed. + */ + public boolean checkAnna(final Player p) { + final Quest quest = p.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP); + if (p.getAttribute("ana-delay", 0) > GameWorld.getTicks()) { + return false; + } + if (quest.getStage(p) > 60 && quest.getStage(p) < 95 && p.getInventory().containsItem(TouristTrap.ANNA_BARREL)) { + p.getInventory().remove(TouristTrap.ANNA_BARREL); + p.lock(5); + TouristTrap.addConfig(p, (1 << 4)); + quest.setStage(p, 61); + p.getProperties().setTeleportLocation(Location.create(3285, 3034, 0)); + p.getPacketDispatch().sendMessage("The guards spot anna and throw you in jail."); + return true; + } + return false; + } + + @Override + public void configure() { + register(new ZoneBorders(3274, 3014, 3305, 3041)); + register(new ZoneBorders(3260, 9408, 3331, 9472)); + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + +} diff --git a/Server/src/main/content/region/desert/quest/thetouristrap/RowdySlaveNPC.java b/Server/src/main/content/region/desert/quest/thetouristrap/RowdySlaveNPC.java new file mode 100644 index 0000000..0146e4f --- /dev/null +++ b/Server/src/main/content/region/desert/quest/thetouristrap/RowdySlaveNPC.java @@ -0,0 +1,92 @@ +package content.region.desert.quest.thetouristrap; + +import core.cache.def.impl.NPCDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.world.map.Location; +import core.plugin.Plugin; +import core.plugin.ClassScanner; +import core.tools.RandomFunction; + +/** + * The rowdy slave npc. + * @author 'Vexia + * @version 1.0 + */ +public final class RowdySlaveNPC extends AbstractNPC { + + /** + * The chats to say when talked to. + */ + private static final String[] CHATS = new String[] { "Oi! Are you looking at me?", "I'm going to teach you some respect!", "Hey, you're in for a good beating!" }; + + /** + * Constructs a new {@code RowdySlaveNPC} {@code Object}. + */ + public RowdySlaveNPC() { + super(0, null); + } + + /** + * Constructs a new {@code RowdySlaveNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + public RowdySlaveNPC(int id, Location location) { + super(id, location); + this.setAggressive(true); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new RowdySlaveNPC(id, location); + } + + @Override + public void finalizeDeath(Entity killer) { + super.finalizeDeath(killer); + if (killer instanceof Player) { + final Player player = (Player) killer; + GroundItemManager.create(new Item(526), getLocation(), player); + if (!TouristTrap.hasSlaveClothes(player) && !player.getEquipment().containsItems(TouristTrap.SLAVE_CLOTHES)) { + player.getPacketDispatch().sendMessages("The slave drops his shirt.", "The slave drops his robe.", "The slave drops his boots."); + for (Item i : TouristTrap.SLAVE_CLOTHES) { + GroundItemManager.create(i, getLocation(), player); + } + } + } + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ClassScanner.definePlugin(new OptionHandler() { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + NPCDefinition.forId(getIds()[0]).getHandlers().put("option:talk-to", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + ((NPC) node).sendChat(CHATS[RandomFunction.random(CHATS.length)]); + ((NPC) node).attack(player); + return true; + } + + }); + return super.newInstance(arg); + } + + @Override + public int[] getIds() { + return new int[] { 827 }; + } + +} diff --git a/Server/src/main/content/region/desert/quest/thetouristrap/TouristTrap.java b/Server/src/main/content/region/desert/quest/thetouristrap/TouristTrap.java new file mode 100644 index 0000000..75f4d61 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/thetouristrap/TouristTrap.java @@ -0,0 +1,307 @@ +package content.region.desert.quest.thetouristrap; + +import core.game.component.Component; +import core.game.container.impl.EquipmentContainer; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.zone.ZoneBorders; +import core.plugin.Initializable; +import core.plugin.ClassScanner; + +import static core.api.ContentAPIKt.*; +import content.data.Quests; + +/** + * The main type for the tourist trap quest. + * @author Aero + * @author Vexia + * + */ +@Initializable +public final class TouristTrap extends Quest { + /** + * The metal key item. + */ + public static final Item METAL_KEY = new Item(1839); + + /** + * The desert gear items. + */ + public static final Item[] DESERT_CLOTHES = new Item[] { new Item(1833), new Item(1835), new Item(1837) }; + + /** + * The slave clothes items. + */ + public static final Item[] SLAVE_CLOTHES = new Item[] { new Item(1846), new Item(1844), new Item(1845) }; + + /** + * Teh tenti pineapple item. + */ + public static final Item TENTI_PINEAPPLE = new Item(1851); + + /** + * The cell door key item. + */ + public static final Item CELL_DOOR_KEY = new Item(1840); + + /** + * The wrought iron key item. + */ + public static final Item WROUGHT_IRON_KEY = new Item(1843); + + /** + * The bedabin key item. + */ + public static final Item BEDABIN_KEY = new Item(1852); + + /** + * The config id for this quest. + */ + public static final int CONFIG_ID = 907; + + /** + * The technical plans item. + */ + public static final Item TECHNICAL_PLANS = new Item(1850); + + /** + * The prototype dart tip item. + */ + public static final Item PROTOTYPE_DART_TIP = new Item(1853); + + /** + * The prototype dart item. + */ + public static final Item PROTOTYPE_DART = new Item(1849); + + /** + * The barrel item. + */ + public static final Item BARREL = new Item(1841); + + /** + * The anna barrel item. + */ + public static final Item ANNA_BARREL = new Item(1842); + + /** + * The jail location. + */ + public static final Location JAIL = Location.create(3285, 3034, 0); + + /** + * The zone borders. + */ + public static final ZoneBorders JAIL_BORDER = new ZoneBorders(3284, 3032, 3287, 3037); + + /** + * The slots to check for items on. + */ + public static final int[] SLOTS = new int[] { EquipmentContainer.SLOT_WEAPON, EquipmentContainer.SLOT_FEET, EquipmentContainer.SLOT_SHIELD, EquipmentContainer.SLOT_HAT, EquipmentContainer.SLOT_CHEST, EquipmentContainer.SLOT_LEGS }; + + /** + * Constructs a new {@code TouristTrap} {@code Object}. + */ + public TouristTrap() { + super(Quests.THE_TOURIST_TRAP, 123, 122, 2, 197, 0, 1, 30); + } + + @Override + public Quest newInstance(Object object) { + ClassScanner.definePlugins(new TouristTrapPlugin(), new AnaDialogue(), new CaptainSiadDialogue(), new DesertGuardDialogue(), new IrenaDialogue(), new MaleSlaveDialogue(), new MercenaryCaptainDialogue(), new MercenaryDialogue(), new MinecartDriverDialogue(), new MineSlaveNPC(), new MiningCampZone(), new RowdySlaveNPC(), new AlShabimDialogue(), new BedabinNomadDialogue()); + return this; + } + + @Override + public void drawJournal(Player player, int stage) { + super.drawJournal(player, stage); + switch (getStage(player)) { + case 0: + line(player, "I can start this quest by speaking to Irena after I have

gone through the Shantay Pass, South of Al-Kharid.

To complete this quest I need:-

" + (player.getSkills().getStaticLevel(Skills.FLETCHING) > 9 ? "" : "") + "Level 10 Fletching

" + (player.getSkills().getStaticLevel(Skills.SMITHING) > 19 ? "" : "") + "Level 20 Smithing" + (hasRequirements(player) ? "

I have all the requirements to begin and complete this

quest." : ""), 11); + break; + case 10: + case 11: + case 30: + case 40: + line(player, "Irena was distraught that her daughter Ana had vanished

somewhere in the desert, and I agreed to help find her.

I need to head into the desert and search for Ana", 11); + break; + case 50: + line(player, "Irena was distraught that her daughter Ana had vanished

somewhere in the desert, and I agreed to help find her.

I need to find the guard a Tenti Pineapple for the guard.", 11); + break; + case 51: + case 52: + line(player, "Irena was distraught that her daughter Ana had vanished

somewhere in the desert, and I agreed to help find her.

I have found a way to get Tenti Pineapple I need to find

the research plans that Captain Siad has.", 11); + break; + case 53: + line(player, "Irena was distraught that her daughter Ana had vanished

somewhere in the desert, and I agreed to help find her.

I have found a way to get Tenti Pineapple

I found the technical plans Al Shabim was looking for.", 11); + break; + case 54: + line(player, "Irena was distraught that her daughter Ana had vanished

somewhere in the desert, and I agreed to help find her.

I have found a way to get Tenti Pineapple

I need to manufacture the Prototype weapon for Al Shabim.", 11); + break; + case 60: + line(player, "Irena was distraught that her daughter Ana had vanished

somewhere in the desert, and I agreed to help find her.

I manufactured the Prototype weapon and received

a tasty Tenti Pineapple.", 11); + break; + case 61: + line(player, "Irena was distraught that her daughter Ana had vanished

somewhere in the desert, and I agreed to help find her.

I finally found Anna. I just need to find a way to smuggle

her out of here.", 11); + break; + case 71: + line(player, "Irena was distraught that her daughter Ana had vanished

somewhere in the desert, and I agreed to help find her.

I need to operate the Winch to lift Ana back up here.", 11); + break; + case 72: + line(player, "Irena was distraught that her daughter Ana had vanished

somewhere in the desert, and I agreed to help find her.

I need to get Ana from one of the barrels lifted.", 11); + break; + case 80: + line(player, "Irena was distraught that her daughter Ana had vanished

somewhere in the desert, and I agreed to help find her.

I loaded Ana into the Cart I now need to get the cart driver

to transport it.", 11); + break; + case 90: + line(player, "Irena was distraught that her daughter Ana had vanished

somewhere in the desert, and I agreed to help find her.

I payed the Mine cart driver and he agreed to smuggle me and Anna

out of the Mining camp.", 11); + break; + case 95: + case 98: + line(player, "Irena was distraught that her daughter Ana had vanished

somewhere in the desert, and I agreed to help find her.

I smuggled both me and Anna from the Mining camp. I should

go tell Irena straight away.", 11); + break; + case 100: + line(player, "Irena was distraught that her daughter Ana had vanished

somewhere in the desert, and I agreed to help find her.

I returned Ana back to her mother and was rewarded

with a key and the knowledge in two skills.



QUEST COMPLETE!", 11); + break; + default: + line(player, "Irena was distraught that her daughter Ana had vanished

somewhere in the desert, and I agreed to help find her.

I need to head into the desert and search for Ana", 11); + break; + } + } + + @Override + public void finish(Player player) { + super.finish(player); + player.getPacketDispatch().sendString("2 Quest Points", 277, 8+ 2); + player.getPacketDispatch().sendString("4650 XP in each of the two skills", 277, 9+ 2); + player.getPacketDispatch().sendString("Ability to make throwing darts", 277, 10+ 2); + player.getPacketDispatch().sendString("Access to desert mining camp", 277, 11+ 2); + player.getPacketDispatch().sendString("mithril and adamantite rocks.", 277, 12+ 2); + player.getPacketDispatch().sendItemZoomOnInterface(806, 230, 277, 3+ 2); + player.getQuestRepository().syncronizeTab(player); + player.getInventory().remove(new Item(1842, player.getInventory().getAmount(ANNA_BARREL))); + player.getBank().remove(new Item(1842, player.getBank().getAmount(ANNA_BARREL))); + } + + /** + * Sends the player to jail. + * @param player the player. + */ + public static void jail(final Player player, String dialogue) { + player.getDialogueInterpreter().sendDialogues(4999, null, dialogue); + player.lock(); + GameWorld.getPulser().submit(new Pulse(1) { + int counter; + + @Override + public boolean pulse() { + switch (counter++) { + case 1: + player.lock(); + player.getInterfaceManager().openOverlay(new Component(115)); + break; + case 3: + player.getProperties().setTeleportLocation(Location.create(3285, 3034, 0)); + player.getPacketDispatch().sendMessage("You are roughed up by the guards and manhandled into a cell."); + player.getInterfaceManager().closeOverlay(); + player.getInterfaceManager().close(); + player.unlock(); + return true; + } + return false; + } + }); + } + + /** + * Jails a player. + * @param player the player. + */ + public static void jail(final Player player) { + jail(player, "Hey you! You're not supposed to be in here!"); + } + + /** + * Checks if the player is jailable. + * @param player the player. + * @return {@code True} if so. + */ + public static boolean isJailable(final Player player) { + if (inJail(player)) { + return false; + } + if (player.getEquipment().itemCount() > 3 || (!hasDesertClothes(player) && !hasSlaveClothes(player))) { + for (int i : SLOTS) { + if (player.getEquipment().get(i) != null) { + return true; + } + } + } + return false; + } + + /** + * Adds a config value pertaining to this quest. + * @param player the player. + */ + public static void addConfig(final Player player, final int value) { + setVarp(player, CONFIG_ID, value, true); + } + + /** + * Checks if the player has desert gear. + * @param player the player. + * @return {@code True} if so. + */ + public static boolean hasDesertClothes(final Player player) { + for (Item i : DESERT_CLOTHES) { + if (!player.getEquipment().containsItem(i)) { + return false; + } + } + return true; + } + + /** + * Checks if the player has slave clothes. + * @param player the player. + * @return {@code True} if so. + */ + public static boolean hasSlaveClothes(final Player player) { + for (Item i : SLAVE_CLOTHES) { + if (!player.getEquipment().containsItem(i)) { + return false; + } + } + return true; + } + + /** + * Checks if the player has armour. + * @param player the player. + * @return + */ + public static boolean hasArmour(final Player player) { + return player.getEquipment().itemCount() > 0 && !hasDesertClothes(player) && !hasSlaveClothes(player); + } + + /** + * Checks if the player is in jail. + * @param player the player. + * @return {@code True} if so. + */ + public static boolean inJail(final Player player) { + return JAIL_BORDER.insideBorder(player); + } + + @Override + public boolean hasRequirements(Player player) { + return player.getSkills().getStaticLevel(Skills.FLETCHING) > 9 && player.getSkills().getStaticLevel(Skills.SMITHING) > 19; + } + +} diff --git a/Server/src/main/content/region/desert/quest/thetouristrap/TouristTrapPlugin.java b/Server/src/main/content/region/desert/quest/thetouristrap/TouristTrapPlugin.java new file mode 100644 index 0000000..463d612 --- /dev/null +++ b/Server/src/main/content/region/desert/quest/thetouristrap/TouristTrapPlugin.java @@ -0,0 +1,1701 @@ +package content.region.desert.quest.thetouristrap; + +import content.data.Quests; +import core.cache.def.impl.AnimationDefinition; +import core.cache.def.impl.NPCDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.game.component.Component; +import core.game.activity.ActivityManager; +import core.game.activity.ActivityPlugin; +import core.game.activity.CutscenePlugin; +import core.game.dialogue.DialogueInterpreter; +import core.game.dialogue.DialoguePlugin; +import core.game.global.action.ClimbActionHandler; +import core.game.global.action.DoorActionHandler; +import core.game.node.entity.skill.SkillPulse; +import content.global.skill.smithing.smelting.Bar; +import content.global.skill.agility.AgilityHandler; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.OptionHandler; +import core.game.interaction.UseWithHandler; +import core.game.node.Node; +import core.game.node.entity.combat.ImpactHandler.HitsplatType; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.map.build.DynamicRegion; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; +import core.plugin.ClassScanner; +import core.tools.RandomFunction; + +import content.region.desert.quest.thetouristrap.TouristTrapPlugin.AnnaCartHandler.AnnaCartCutscene; +import content.region.desert.quest.thetouristrap.TouristTrapPlugin.BedabinAnvilHandler.AnnaWinchHandler; + +import static core.api.ContentAPIKt.*; + +/** + * Represents the plugin used to handle interactions for tourist trap. + * + * @author 'Vexia + * @version 1.0 + */ +public final class TouristTrapPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(2673).getHandlers().put("option:open", this); + SceneryDefinition.forId(2674).getHandlers().put("option:open", this); + SceneryDefinition.forId(2673).getHandlers().put("option:search", this); + SceneryDefinition.forId(2674).getHandlers().put("option:search", this); + SceneryDefinition.forId(2688).getHandlers().put("option:open", this); + SceneryDefinition.forId(2688).getHandlers().put("option:search", this); + SceneryDefinition.forId(2687).getHandlers().put("option:open", this); + SceneryDefinition.forId(2687).getHandlers().put("option:search", this); + SceneryDefinition.forId(2685).getHandlers().put("option:open", this); + SceneryDefinition.forId(2685).getHandlers().put("option:open", this); + SceneryDefinition.forId(2686).getHandlers().put("option:search", this); + SceneryDefinition.forId(2686).getHandlers().put("option:search", this); + SceneryDefinition.forId(18958).getHandlers().put("option:search", this); + SceneryDefinition.forId(18958).getHandlers().put("option:look at", this); + SceneryDefinition.forId(18959).getHandlers().put("option:search", this); + SceneryDefinition.forId(18959).getHandlers().put("option:look at", this); + SceneryDefinition.forId(18888).getHandlers().put("option:look at", this); + SceneryDefinition.forId(18888).getHandlers().put("option:operate", this); + SceneryDefinition.forId(36748).getHandlers().put("option:talk-to", this); + SceneryDefinition.forId(18869).getHandlers().put("option:bend", this); + SceneryDefinition.forId(18870).getHandlers().put("option:escape", this); + SceneryDefinition.forId(2689).getHandlers().put("option:open", this); + SceneryDefinition.forId(1528).getHandlers().put("option:open", this); + SceneryDefinition.forId(1529).getHandlers().put("option:close", this); + SceneryDefinition.forId(18899).getHandlers().put("option:search", this); + SceneryDefinition.forId(18899).getHandlers().put("option:look at", this); + SceneryDefinition.forId(18878).getHandlers().put("option:search", this); + SceneryDefinition.forId(18878).getHandlers().put("option:look at", this); + SceneryDefinition.forId(18879).getHandlers().put("option:search", this); + SceneryDefinition.forId(18879).getHandlers().put("option:look at", this); + SceneryDefinition.forId(18898).getHandlers().put("option:search", this); + SceneryDefinition.forId(18898).getHandlers().put("option:look at", this); + SceneryDefinition.forId(18902).getHandlers().put("option:search", this); + SceneryDefinition.forId(18871).getHandlers().put("option:climb", this); + SceneryDefinition.forId(18923).getHandlers().put("option:climb-up", this); + SceneryDefinition.forId(18924).getHandlers().put("option:climb-down", this); + SceneryDefinition.forId(2676).getHandlers().put("option:open", this); + SceneryDefinition.forId(2675).getHandlers().put("option:open", this); + SceneryDefinition.forId(2676).getHandlers().put("option:watch", this); + SceneryDefinition.forId(2675).getHandlers().put("option:watch", this); + SceneryDefinition.forId(2690).getHandlers().put("option:open", this); + SceneryDefinition.forId(2691).getHandlers().put("option:open", this); + SceneryDefinition.forId(2698).getHandlers().put("option:walk through", this); + SceneryDefinition.forId(2699).getHandlers().put("option:walk through", this); + SceneryDefinition.forId(2677).getHandlers().put("option:open", this); + SceneryDefinition.forId(2678).getHandlers().put("option:search", this); + SceneryDefinition.forId(2684).getHandlers().put("option:search", this); + SceneryDefinition.forId(2684).getHandlers().put("option:look at", this); + SceneryDefinition.forId(2680).getHandlers().put("option:search", this); + SceneryDefinition.forId(2680).getHandlers().put("option:look-in", this); + SceneryDefinition.forId(2681).getHandlers().put("option:search", this); + SceneryDefinition.forId(2681).getHandlers().put("option:look in", this); + SceneryDefinition.forId(18962).getHandlers().put("option:search", this); + SceneryDefinition.forId(18962).getHandlers().put("option:look in", this); + SceneryDefinition.forId(18963).getHandlers().put("option:search", this); + SceneryDefinition.forId(18963).getHandlers().put("option:look in", this); + SceneryDefinition.forId(18951).getHandlers().put("option:look at", this); + SceneryDefinition.forId(18951).getHandlers().put("option:use", this); + SceneryDefinition.forId(2684).getHandlers().put("option:search", this); + SceneryDefinition.forId(2684).getHandlers().put("option:look at", this); + SceneryDefinition.forId(18875).getHandlers().put("option:inspect", this); + NPCDefinition.forId(830).getHandlers().put("option:watch", this); + NPCDefinition.forId(4975).getHandlers().put("option:talk-to", this); + NPCDefinition.forId(4976).getHandlers().put("option:talk-to", this); + NPCDefinition.forId(4977).getHandlers().put("option:talk-to", this); + NPCDefinition.forId(4978).getHandlers().put("option:talk-to", this); + NPCDefinition.forId(5002).getHandlers().put("option:talk-to", this); + TouristTrap.TECHNICAL_PLANS.getDefinition().getHandlers().put("option:read", this); + TouristTrap.ANNA_BARREL.getDefinition().getHandlers().put("option:look", this); + TouristTrap.ANNA_BARREL.getDefinition().getHandlers().put("option:drop", this); + ClassScanner.definePlugin(new BedabinKeyHandler()); + ClassScanner.definePlugin(new BedabinAnvilHandler()); + ClassScanner.definePlugin(new BarrelDialogue()); + ClassScanner.definePlugin(new WinchDialogue()); + ClassScanner.definePlugin(new MineCartDialogue()); + ClassScanner.definePlugin(new AnnaCartHandler()); + ClassScanner.definePlugin(new AnnaCartCutscene()); + ClassScanner.definePlugin(new AnnaWinchHandler()); + ClassScanner.definePlugin(new WinchCutscene()); + ClassScanner.definePlugin(new CartDialogue()); + return this; + } + + @Override + public boolean handle(final Player player, Node node, String option) { + final Quest quest = player.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP); + final int id = node.getId(); + switch (option) { + case "read": + player.getDialogueInterpreter().sendDialogue("The plans look very technical! But you can see that this item will", "require a bronze bar and at least 10 feathers."); + break; + case "watch": + switch (id) { + case 2676: + case 2675: + player.getDialogueInterpreter().sendDialogue("You watch the doors for some time. You notice that only slaves seem", "to do down there. You might be able to sneak down if you pass as a", "slave."); + break; + default: + player.getDialogueInterpreter().sendDialogue("You watch the Mercenary Captain for some time. He has a large", "metal key attached to his belt. You notice that he usually gets his", "men to do his dirty work."); + break; + } + break; + case "walk through": + switch (id) { + case 2698: + case 2699: + if (quest.getStage(player) < 60) { + player.getDialogueInterpreter().sendDialogues(5001, null, "Hey you! You're not allowed in there."); + break; + } + if (!TouristTrap.hasSlaveClothes(player)) { + player.getDialogueInterpreter().sendDialogues(5001, null, "Hey you're not a slave!"); + break; + } + player.getProperties().setTeleportLocation(player.getLocation().transform(player.getLocation().getX() >= 3284 ? -4 : 4, 0, 0)); + player.getPacketDispatch().sendMessages("You walk into the darkness of the cavern...", "... and emerge in a different part of this huge underground complex."); + break; + } + break; + case "look": + player.getDialogueInterpreter().sendDialogues(823, null, "Let me out of here, I feel sick!"); + break; + case "drop": + player.getDialogueInterpreter().sendDialogues(823, null, "Don't let me out!"); + break; + case "open": + switch (id) { + case 2688: + case 2687: + if (!player.getInventory().containsItem(TouristTrap.WROUGHT_IRON_KEY)) { + player.getPacketDispatch().sendMessage("This gate looks like it needs a key to open it."); + break; + } + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + break; + case 2686: + case 2685: + player.getDialogueInterpreter().sendDialogues(4999, null, "Hey, move away from the gate. There's nothing", "interesting for you here."); + break; + case 2677: + if (!player.getInventory().containsItem(TouristTrap.BEDABIN_KEY)) { + player.getPacketDispatch().sendMessage("This chest needs a key to unlock it."); + break; + } + if (quest.getStage(player) <= 54 && quest.getStage(player) != 53) { + player.getPacketDispatch().sendMessage("The captain spots you before you manage to open the chest..."); + player.lock(3); + GameWorld.getPulser().submit(new Pulse(2, player) { + @Override + public boolean pulse() { + player.getDialogueInterpreter().open(831, RegionManager.getNpc(player, 831)); + return true; + } + }); + } else if (quest.getStage(player) == 53) { + if (!player.hasItem(TouristTrap.TECHNICAL_PLANS)) { + player.getDialogueInterpreter().sendItemMessage(TouristTrap.TECHNICAL_PLANS, "While the Captain's distracted, you quickly unlock the", "chest with the Bedabins' copy of the key. You take out", "the plans."); + player.getInventory().add(TouristTrap.TECHNICAL_PLANS, player); + } + } + break; + case 2690: + case 2691: + player.setAttribute("ana-delay", GameWorld.getTicks() + 2); + player.getProperties().setTeleportLocation(Location.create(3301, 3035, 0)); + break; + case 2676: + case 2675: + if (!TouristTrap.hasSlaveClothes(player)) { + player.getDialogueInterpreter().sendDialogues(4997, null, "Watch it! Only slaves can travel into the mine."); + break; + } + player.setAttribute("ana-delay", GameWorld.getTicks() + 2); + player.getProperties().setTeleportLocation(Location.create(3278, 9427, 0)); + player.getDialogueInterpreter().sendDialogue("The huge doors open into a dark, dank and smelly tunnel. The", "associated smells of a hundred sweaty miners greets your nostrils.", "And your ears ring with the 'CLANG CLANG CLANG' as metal hits", "rock."); + break; + case 2674: + case 2673: + if (quest.getStage(player) > 60 && quest.getStage(player) < 98 && player.getInventory().containsItem(TouristTrap.ANNA_BARREL)) { + player.lock(); + player.getDialogueInterpreter().sendDialogues(4999, null, true, "Would you like me to take that heavy barrel", "for you?"); + GameWorld.getPulser().submit(new Pulse(4, player) { + int counter; + + @Override + public boolean pulse() { + switch (++counter) { + case 1: + player.getDialogueInterpreter().sendDialogues(player, null, "No, please don't."); + break; + case 2: + player.getDialogueInterpreter().close(); + player.getPacketDispatch().sendMessage("The guards search you!"); + break; + case 3: + player.getPacketDispatch().sendMessage("You are roughed up by the guards and manhandled into a cell."); + break; + case 4: + player.unlock(); + player.getInventory().remove(TouristTrap.ANNA_BARREL); + TouristTrap.addConfig(player, (1 << 4)); + quest.setStage(player, 61); + player.getProperties().setTeleportLocation(Location.create(3285, 3034, 0)); + return true; + } + return false; + } + }); + return true; + } + if (node.getLocation().withinDistance(new Location(3273, 3028, 0)) && !((player.getLocation().getX() >= 3274))) { + if (!player.getInventory().containsItem(TouristTrap.METAL_KEY)) { + player.getPacketDispatch().sendMessage("The gate needs a key in order to be opened."); + return true; + } + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + player.getPacketDispatch().sendMessage("The guards search you thoroughly as you go through the gates."); + return true; + } + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + break; + case 2689: + if (!player.getInventory().containsItem(TouristTrap.CELL_DOOR_KEY)) { + player.getPacketDispatch().sendMessage("The door seems to be pretty locked."); + break; + } + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + break; + case 1528: + SceneryBuilder.replace((Scenery) node, ((Scenery) node).transform(1529)); + break; + } + break; + case "close": + if (id == 1529) { + SceneryBuilder.replace((Scenery) node, ((Scenery) node).transform(1528)); + } + break; + case "look-in": + case "look in": + switch (id) { + case 2681: + case 18962: + case 18963: + player.getDialogueInterpreter().sendDialogue("This looks like an empty mining barrel. Slaves use this to load up the", "rocks and stones that they're mining."); + break; + case 2680: + player.getDialogueInterpreter().sendDialogue("You search the full barrel... It's full of rocks."); + break; + } + break; + case "use": + if (id == 18951) { + player.getDialogueInterpreter().open("winch dialogue"); + } + break; + case "search": + switch (id) { + case 2688: + case 2687: + player.getDialogueInterpreter().sendDialogue("These wrought iron gates look like they're designed to keep people out.", "it looks like you'll need a key to get past these."); + break; + case 2686: + case 2685: + player.getDialogueInterpreter().sendDialogue("It looks as if this is where very difficult prisoners are sent as a", "punishment."); + break; + case 2681: + case 18962: + case 18963: + player.getDialogueInterpreter().open("barrel dialogue", node); + break; + case 2680:// barrel of rocks. + player.getDialogueInterpreter().sendDialogue("This looks like a full mining barrel. Slaves use this to load up the", "rocks and stones that they're mining. This barrel is full of rocks."); + break; + case 2684:// cart + player.getDialogueInterpreter().open("cart dialogue", node); + break; + case 2678: + if (quest.getStage(player) == 51) { + quest.setStage(player, 52); + } + player.getDialogueInterpreter().sendItemMessage(9904, "You notice several books on the subject of sailing."); + break; + case 2673: + case 2674: + player.getDialogueInterpreter().sendDialogue("You see what looks like a mining compound. There seems to be people", "mining rocks. They look as if they're chained to the rocks and they're", "being watched over by the guards. It's not a very happy place."); + break; + case 18958: + case 18959: + if (quest.getStage(player) == 90) { + player.getDialogueInterpreter().open("ana cart dialogue"); + break; + } + player.getPacketDispatch().sendMessage("This looks like a mine cart which takes barrels out of the encampment to Al Kharid."); + break; + case 18899: + case 18898: + case 18878: + case 18879: + player.getDialogueInterpreter().sendDialogue("You search the footsteps more closely. You can see that there are", "five sets of footprints. One set of footprints seem lighter than the", "others. The four other footsteps were made by heavier people", "with boots."); + break; + case 18902: + if (hasItem(player, TouristTrap.CELL_DOOR_KEY)) { + player.getInventory().add(TouristTrap.CELL_DOOR_KEY, player); + player.getDialogueInterpreter().sendItemMessage(TouristTrap.CELL_DOOR_KEY, "You find a cell door key."); + break; + } else if (hasItem(player, TouristTrap.WROUGHT_IRON_KEY) && player.getQuestRepository().isComplete(Quests.THE_TOURIST_TRAP)) { + player.getInventory().add(TouristTrap.WROUGHT_IRON_KEY, player); + player.getDialogueInterpreter().sendItemMessage(TouristTrap.WROUGHT_IRON_KEY, "You find the key to the main gate."); + break; + } + player.getPacketDispatch().sendMessage("You search the captains desk while he's not looking..."); + player.getPacketDispatch().sendMessage("...but you find nothing of interest."); + break; + } + break; + case "operate": + if (quest.getStage(player) != 71) { + player.getDialogueInterpreter().sendDialogue("There doesn't seem anything to lift."); + break; + } + ActivityManager.start(player, "winch cutscene", false); + break; + case "look at": + switch (id) { + case 18888: + player.getDialogueInterpreter().sendDialogue("This looks like a winch, it probably brings rocks up from", "underground."); + break; + case 18951: + player.getDialogueInterpreter().sendDialogue("This looks like a lift of some sort. You see barrels of rocks being", "placed on the lift and they're hauled up to the surface."); + break; + case 2684: + if (node.getLocation().getX() == 3318) { + player.getDialogueInterpreter().sendDialogue("This mine cart is being loaded up with new rocks and stone.", "It gets sent to a different section of the mine for unloading."); + break; + } + player.getDialogueInterpreter().sendDialogue("This cart is being unloaded into this section of the mine. Before being", "sent back to another section for another load."); + break; + case 18958: + case 18959: + player.getDialogueInterpreter().sendDialogue("A sturdy looking cart for carrying barrels of rocks out of ", "the mining camp."); + break; + case 18900: + case 18899: + case 18898: + case 18887: + case 18886: + case 18885: + case 18884: + case 18883: + case 18882: + case 18881: + case 18880: + case 18879: + case 18878: + case 18877: + player.getDialogueInterpreter().sendDialogue("This looks like some disturbed sand. Footsteps seem to be heading off", "towards the South."); + break; + } + break; + case "talk-to": + switch (id) { + case 5002: + ((NPC) node).sendChat("Move along please, don't want any trouble today!"); + break; + case 36748: + player.getDialogueInterpreter().sendDialogues(player, null, "Mmm... looks like that camel would make a nice kebab."); + break; + case 4975: + case 4977: + case 4978: + case 4976: + ((NPC) node).sendChat("Hey leave me alone, can't you see that i'm busy?"); + break; + } + break; + case "bend": + player.animate(Animation.create(5037)); + GameWorld.getPulser().submit(new Pulse(5, player) { + @Override + public boolean pulse() { + player.getPacketDispatch().sendMessage("You bend the bars back."); + setVarp(player, 907, getVarp(player, 907) + 1); + return true; + } + }); + break; + case "escape": + player.getPacketDispatch().sendMessage("You prepare to squeeze through the bars."); + AgilityHandler.forceWalk(player, 0, player.getLocation(), player.getLocation().transform(player.getLocation().getX() <= node.getLocation().getX() ? 1 : -1, 0, 0), Animation.create(5038), 4, 0.0, null); + break; + case "climb": + player.getPacketDispatch().sendMessage("You scrape your hands and knees as you climb up."); + AgilityHandler.forceWalk(player, 0, player.getLocation(), Location.create(3279, 3037, 0), Animation.create(5041), 10, 0, null); + GameWorld.getPulser().submit(new Pulse(3, player) { + @Override + public boolean pulse() { + player.getAnimator().reset(); + return true; + } + }); + break; + case "climb-up": + if (id == 18923) { + if (player.getLocation().getX() <= 3278) { + return true; + } + player.animate(Animation.create(5039)); + GameWorld.getPulser().submit(new Pulse(6, player) { + @Override + public boolean pulse() { + player.getAnimator().reset(); + player.getProperties().setTeleportLocation(Location.create(3278, 3037, 0)); + return true; + } + }); + } + break; + case "climb-down": + if (id == 18924) { + if (player.getLocation().getX() <= 3273) { + return true; + } + AgilityHandler.forceWalk(player, 0, player.getLocation(), Location.create(3270, 3039, 0), Animation.create(5040), 20, 0, null); + GameWorld.getPulser().submit(new Pulse(3, player) { + @Override + public boolean pulse() { + player.getAnimator().reset(); + return true; + } + }); + } + break; + case "inspect": + if (id == 18875) { + sendDialogue(player, "You remember that Irena mentioned something about Ana wearing a red scarf before she left for the desert."); + } + break; + } + return true; + } + + @Override + public boolean isWalk(final Player player, Node node) { + return !(node instanceof Item); + } + + @Override + public boolean isWalk() { + return false; + } + + @Override + public Location getDestination(Node node, Node n) { + if (n.getId() == 18923) { + return new Location(3279, 3037, 0); + } + return null; + } + + /** + * Checks if the player contains an item. + * + * @param player the player. + * @param item the item. + * @return the item. + */ + private boolean hasItem(final Player player, final Item item) { + return !player.getInventory().containsItem(item) && !player.getBank().containsItem(item); + } + + /** + * The winch dialogue plugin. + * + * @author 'Vexia + * @version 1.0 + */ + public static final class WinchDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code WinchDialogue} {@code Object}. + */ + public WinchDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code WinchDialogue} {@code Object}. + * + * @param player the player. + */ + public WinchDialogue(final Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new WinchDialogue(player); + } + + @Override + public boolean open(Object... args) { + if (args.length >= 1) { + interpreter.sendDialogue("The guard notices the barrel (with Ana in it) that you're carrying."); + stage = 500; + return true; + } + interpreter.sendDialogues(4999, null, "Hey there, what do you want?"); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 500:// winch + interpreter.sendDialogues(5002, null, "Hey, that Barrel looks heavy, do you need a hand?"); + stage++; + break; + case 501: + player("Yes please."); + stage++; + break; + case 502: + interpreter.sendDialogue("The guard comes over and helps you. He takes one end of the", "barrel."); + stage++; + break; + case 503: + interpreter.sendDialogues(5002, null, "Blimey! This is heavy!"); + stage++; + break; + case 504: + interpreter.sendDialogues(823, null, "Why you cheeky....!"); + stage++; + break; + case 505: + interpreter.sendDialogues(5002, null, "- The guard looks around surprised at Ana's outburst. -", "What was that?"); + stage++; + break; + case 506: + player("Oh, it was nothing."); + stage++; + break; + case 507: + interpreter.sendDialogues(5002, null, "I could have sworn I heard something!"); + stage++; + break; + case 508: + interpreter.sendDialogues(823, null, "Yes you did you ignoramus."); + stage++; + break; + case 509: + interpreter.sendDialogues(5002, null, "What was that you said?"); + stage++; + break; + case 510: + player("I said you were very gregarious!"); + stage++; + break; + case 511: + interpreter.sendDialogues(823, null, "You creep!"); + stage++; + break; + case 512: + interpreter.sendDialogues(5002, null, "Oh, right, how very nice of you to say so.", "-- The guard seems flattered. --"); + stage++; + break; + case 513: + interpreter.sendDialogues(5002, null, "Anyway, let's get this barrel up to the surface, plenty", "more work for you to do!"); + stage++; + break; + case 514: + interpreter.sendDialogue("The guard places the barrel carefully on the lift platform."); + stage++; + break; + case 515: + interpreter.sendDialogues(5002, null, "Oh, there's no one operating the lift up top, hope this", "barrel isn't urgent? You'd better get back to work!"); + stage = 516; + break; + case 516: + player.getInventory().remove(TouristTrap.ANNA_BARREL); + player.getBank().remove(TouristTrap.ANNA_BARREL); + player.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP).setStage(player, 71); + end(); + break; + case 0: + options("What is this thing?", "Can I use this?"); + stage++; + break; + case 1: + switch (buttonId) { + case 1: + player("What is this thing?"); + stage = 10; + break; + case 2: + player("Can I use this?"); + stage = 20; + break; + } + break; + case 10: + interpreter.sendDialogues(4999, null, "It is quite clearly a lift. Any fool can see that it's used to", "transport rock to the surface."); + stage++; + break; + case 11: + case 21: + end(); + break; + case 20: + interpreter.sendDialogues(4999, null, "Of course not, you'd be doing me out of a job. Anyway", "you haven't got any barrels that need to go to", "the surface."); + stage++; + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[]{DialogueInterpreter.getDialogueKey("winch dialogue")}; + } + + } + + /** + * The use with handler for anna on the cart. + * + * @author 'Vexia + * @version 1.0 + */ + public static final class AnnaCartHandler extends UseWithHandler { + + /** + * Constructs a new {@code AnnaCartHandler} {@code Object}. + */ + public AnnaCartHandler() { + super(TouristTrap.ANNA_BARREL.getId()); + } + + @Override + public Plugin newInstance(Object arg) { + addHandler(2684, OBJECT_TYPE, this); + addHandler(18958, OBJECT_TYPE, this); + return this; + } + + @Override + public boolean handle(final NodeUsageEvent event) { + final Player player = event.getPlayer(); + final Quest quest = player.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP); + if (event.getUsedWith().getId() == 18958) {// cart + if (quest.getStage(player) == 72) { + player.lock(4); + player.animate(Animation.create(5050)); + GameWorld.getPulser().submit(new Pulse(3, player) { + @Override + public boolean pulse() { + player.getInventory().remove(event.getUsedItem()); + TouristTrap.addConfig(player, 4096 + (2048 + (1 << 4))); + quest.setStage(player, 80); + player.getDialogueInterpreter().sendDialogue("You place Ana (In the barrel) carefully on the cart. This was the last", "barrel to go on the cart, but the cart driver doesn't seem to be", "any rush to get going. And the desert heat will soon get to Ana."); + return true; + } + }); + } + return true; + } + if (!event.getUsedWith().getLocation().equals(Location.create(3318, 9430, 0))) { + return false; + } + if (quest.getStage(player) != 61) { + return false; + } + player.getDialogueInterpreter().sendDialogue("You carefully place Ana in the barrel into the mine", "cart. Soon the cart moves out of sight and then it", "returns."); + player.setAttribute("ana-delay", GameWorld.getTicks() + 100000000); + ActivityManager.start(player, "ana cart", false); + return true; + } + + /** + * The ana cart cutscene plugin. + * + * @author 'Vexia + * @version 1.0 + */ + public static final class AnnaCartCutscene extends CutscenePlugin { + + /** + * The paths. + */ + private static final Location[][] PATHS = new Location[][]{{Location.create(3315, 9417, 0), Location.create(3317, 9417, 0), Location.create(3318, 9418, 0), Location.create(3318, 9428, 0)}, {Location.create(3318, 9430, 0), Location.create(3318, 9418, 0), Location.create(3317, 9417, 0), Location.create(3316, 9417, 0), Location.create(3314, 9417, 0), Location.create(3303, 9417, 0)}}; + + /** + * Constructs a new {@code AnnaCartCutscene} {@code Object}. + */ + public AnnaCartCutscene() { + super("ana cart"); + } + + /** + * Constructs a new {@code AnnaCartCutscene} {@code Object}. + * + * @param player the player. + */ + public AnnaCartCutscene(final Player player) { + super("ana cart"); + this.player = player; + } + + @Override + public void open() { + super.open(); + player.setAttribute("ana-delay", GameWorld.getTicks() + 100000000); + player.faceLocation(base.transform(54, 22, 0)); + GameWorld.getPulser().submit(new Pulse(1, player) { + int counter; + NPC cart; + + @Override + public boolean pulse() { + switch (++counter) { + case 1: + player.animate(Animation.create(5052)); + break; + case 3: + SceneryBuilder.remove(RegionManager.getObject(base.transform(54, 22, 0))); + cart = NPC.create(4980, base.transform(54, 22, 0)); + cart.init(); + break; + case 4: + cart.getWalkingQueue().reset(); + for (Location l : PATHS[1]) { + Location loc = base.transform(l.getLocalX(), l.getLocalY(), 0); + cart.getWalkingQueue().addPath(loc.getX(), loc.getY()); + } + break; + case 18: + cart.clear(); + break; + case 22: + cart = NPC.create(4981, base.transform(51, 9, 0)); + cart.init(); + cart.getWalkingQueue().reset(); + for (Location l : PATHS[0]) { + Location loc = base.transform(l.getLocalX(), l.getLocalY(), 0); + cart.getWalkingQueue().addPath(loc.getX(), loc.getY()); + } + break; + case 33: + player.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP).setStage(player, 70); + player.getInventory().remove(TouristTrap.ANNA_BARREL); + player.removeAttribute("ana-delay"); + AnnaCartCutscene.this.stop(true); + return true; + } + return false; + } + }); + } + + @Override + public ActivityPlugin newInstance(Player p) { + return new AnnaCartCutscene(p); + } + + @Override + public Location getSpawnLocation() { + return null; + } + + @Override + public Location getStartLocation() { + return base.transform(54, 23, 0); + } + + @Override + public void configure() { + region = DynamicRegion.create(13203); + setRegionBase(); + registerRegion(region.getId()); + } + } + } + + /** + * The cart dialogue plugin. + * + * @author 'Vexia + * @version 1.0 + */ + public static final class CartDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code CartDialogue} {@code Object}. + * + * @param player the player. + */ + public CartDialogue(final Player player) { + super(player); + } + + /** + * Constructs a new {@code CartDialogue} {@code Object}. + */ + public CartDialogue() { + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new CartDialogue(player); + } + + @Override + public boolean open(Object... args) { + interpreter.sendDialogue("There is space on the cart for you get on, would you like to try?"); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + options("Yes, I'll get on.", "No, I've got other plans."); + stage++; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogue("You decide to climb onto the cart."); + stage++; + break; + case 2: + end(); + break; + } + break; + case 2: + player.lock(); + player.animate(ClimbActionHandler.CLIMB_UP); + GameWorld.getPulser().submit(new Pulse(1, player) { + int counter; + + @Override + public boolean pulse() { + switch (counter++) { + case 1: + player.getInterfaceManager().openOverlay(new Component(115)); + break; + case 4: + player.getDialogueInterpreter().sendDialogue("As soon as you get on the cart, it starts to move.", "Before too long you are past the gates. You jump off", "the cart taking Ana with you."); + break; + case 6: + player.unlock(); + player.getInterfaceManager().closeOverlay(); + player.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP).setStage(player, 95); + player.getInterfaceManager().close(); + player.getProperties().setTeleportLocation(Location.create(3258, 3029, 0)); + player.getInventory().add(TouristTrap.ANNA_BARREL); + return true; + } + return false; + } + }); + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[]{DialogueInterpreter.getDialogueKey("ana cart dialogue")}; + } + + } + + /** + * The minecart dialogue plugin. + * + * @author 'Vexia + * @version 1.0 + */ + public static final class MineCartDialogue extends DialoguePlugin { + + /** + * The failing animation of getting in the cart. + */ + private static final Animation FAIL_ANIMATION = new Animation(5048); + + /** + * The jumping animation. + */ + private static final Animation JUMP_ANIMATION = new Animation(5049); + + /** + * The cart. + */ + private Scenery cart; + + /** + * Constructs a new {@code MineCartDialogue} {@code Object}. + */ + public MineCartDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code MineCartDialogue} {@code Object}. + * + * @param player the player. + */ + public MineCartDialogue(final Player player) { + super(player); + } + + @Override + public void init() { + super.init(); + ClassScanner.definePlugin(new MiningCartCutscene()); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new MineCartDialogue(player); + } + + @Override + public boolean open(Object... args) { + cart = (Scenery) args[0]; + if (player.getInventory().containsItem(TouristTrap.ANNA_BARREL)) { + player("There's not enough room for both of us."); + stage = -1; + return true; + } + interpreter.sendDialogue("You search the mine cart..."); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case -1: + end(); + break; + case 0: + interpreter.sendDialogue("There may be just enough space to squeeze yourself into the cart.", "Would you like to try?"); + stage++; + break; + case 1: + options("Yes, of course.", "No thanks, it looks pretty dangerous."); + stage++; + break; + case 2: + switch (buttonId) { + case 1: + end(); + enterCart(player); + break; + case 2: + end(); + break; + } + break; + } + return true; + } + + /** + * Method used to enter the cart. + * + * @param player the player. + */ + public void enterCart(final Player player) { + if (RandomFunction.random(3) == 1) { + player.lock(FAIL_ANIMATION.getDelay()); + player.animate(FAIL_ANIMATION); + player.getImpactHandler().manualHit(player, 2, HitsplatType.NORMAL); + player.getPacketDispatch().sendMessages("You fail to fit yourself into the cart in time before it starts its journey.", "You bang your head on the cart as you try to jump in."); + } else { + GameWorld.getPulser().submit(new Pulse(3, player) { + @Override + public boolean pulse() { + player.animate(JUMP_ANIMATION); + return true; + } + }); + ActivityManager.start(player, "mining cart", false, cart.getLocation().getX() == 3303 ? 0 : 1); + } + } + + /** + * The mining cart cutscene plugin. + * + * @author 'Vexia + * @version 1.0 + */ + public static final class MiningCartCutscene extends CutscenePlugin { + + /** + * The paths. + */ + private static final Location[][] PATHS = new Location[][]{{Location.create(3303, 9417, 0), Location.create(3316, 9417, 0), Location.create(3317, 9417, 0), Location.create(3318, 9418, 0), Location.create(3318, 9430, 0)}, {Location.create(3318, 9430, 0), Location.create(3318, 9418, 0), Location.create(3317, 9417, 0), Location.create(3303, 9417, 0)}}; + + /** + * The path index. + */ + private int index; + + /** + * Constructs a new {@code MiningCartCutscene} {@code Object}. + */ + public MiningCartCutscene() { + super("mining cart"); + } + + /** + * Constructs a new {@code MiningCartCutscene} {@code Object}. + * + * @param player the player. + */ + public MiningCartCutscene(final Player player) { + super("mining cart"); + this.player = player; + } + + @Override + public boolean start(final Player player, boolean login, Object... args) { + index = (int) args[0]; + return super.start(player, login, args); + } + + @Override + public void open() { + SceneryBuilder.remove(RegionManager.getObject(base.getLocation().transform(getPath()[0].getLocalX(), getPath()[0].getLocalY(), 0))); + SceneryBuilder.remove(RegionManager.getObject(base.getLocation().transform(getPath()[getPath().length - 1].getLocalX(), getPath()[getPath().length - 1].getLocalY(), 0))); + player.getAppearance().setAnimations(Animation.create(211)); + player.getAppearance().setRidingMinecart(true); + player.getAppearance().sync(); + player.getWalkingQueue().reset(); + for (Location l : getPath()) { + Location loc = base.transform(l.getLocalX(), l.getLocalY(), 0); + player.getWalkingQueue().addPath(loc.getX(), loc.getY(), true); + } + GameWorld.getPulser().submit(new Pulse(22, player) { + @Override + public boolean pulse() { + player.setAttribute("real-end", index == 0 ? Location.create(3319, 9431, 0) : Location.create(3303, 9416, 0)); + player.setAttribute("cutscene:original-loc", index == 0 ? Location.create(3319, 9431, 0) : Location.create(3303, 9416, 0)); + MiningCartCutscene.this.stop(true); + return true; + } + }); + } + + @Override + public void end() { + super.end(); + player.getAppearance().setDefaultAnimations(); + player.getAppearance().setRidingMinecart(false); + player.getAppearance().sync(); + } + + @Override + public void fade() { + if (index == 0) { + player.getDialogueInterpreter().sendDialogue("You appear in a large open room with what looks like lots of miners", "working away. This is a very rough looking area, the miners look like", "they're on their last legs."); + } else { + player.getDialogueInterpreter().sendDialogue("You appear back in the barrel loading room. A nearby slave looks", "surprised to see you popping out of the cart."); + } + } + + @Override + public ActivityPlugin newInstance(Player p) { + return new MiningCartCutscene(p); + } + + @Override + public Location getSpawnLocation() { + return null; + } + + @Override + public Location getStartLocation() { + return base.transform(getPath()[0].getLocalX(), getPath()[0].getLocalY(), 0); + } + + @Override + public void configure() { + region = DynamicRegion.create(13203); + setRegionBase(); + registerRegion(region.getId()); + } + + /** + * Gets the path index. + * + * @return the location. + */ + public Location[] getPath() { + return PATHS[index]; + } + } + + @Override + public int[] getIds() { + return new int[]{DialogueInterpreter.getDialogueKey("cart dialogue")}; + } + + } + + /** + * The winch cutscene plugin. + * + * @author 'Vexia + * @version 1.0 + */ + public static final class WinchCutscene extends CutscenePlugin { + + /** + * Constructs a new {@code WinchCutscene} {@code Object}. + */ + public WinchCutscene() { + super("winch cutscene"); + } + + /** + * Constructs a new {@code WinchCutscene} {@code Object}. + * + * @param player the player. + */ + public WinchCutscene(final Player player) { + super("winch cutscene"); + this.player = player; + } + + @Override + public ActivityPlugin newInstance(Player p) { + return new WinchCutscene(p); + } + + @Override + public void open() { + super.open(); + player.getPacketDispatch().sendMessage("You try to operate the winch."); + player.faceLocation(base.transform(15, 9, 0)); + player.animate(Animation.create(5054)); + GameWorld.getPulser().submit(new Pulse(AnimationDefinition.forId(5054).getDurationTicks(), player) { + @Override + public boolean pulse() { + TouristTrap.addConfig(player, 2048 + (1 << 4)); + WinchCutscene.this.stop(true); + player.getDialogueInterpreter().open(822, true, true); + return true; + } + }); + } + + @Override + public Location getSpawnLocation() { + return null; + } + + @Override + public Location getStartLocation() { + return base.transform(16, 10, 0); + } + + @Override + public void configure() { + region = DynamicRegion.create(13103); + setRegionBase(); + registerRegion(region.getId()); + } + + } + + /** + * The use with handler on the chest. + * + * @author 'Vexia + * @version 1.0 + */ + public static final class BedabinKeyHandler extends UseWithHandler { + + /** + * Constructs a new {@code BedabinKeyHandler} {@code Object}. + */ + public BedabinKeyHandler() { + super(TouristTrap.BEDABIN_KEY.getId()); + } + + @Override + public Plugin newInstance(Object arg) { + addHandler(2677, OBJECT_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + player.getDialogueInterpreter().open(831, RegionManager.getNpc(player, 831)); + return true; + } + + } + + /** + * The barrel dialogue plugin. + * + * @author 'Vexia + * @version 1.0 + */ + public static final class BarrelDialogue extends DialoguePlugin { + + /** + * The scenery barrel. + */ + private Scenery barrel; + + /** + * The quest. + */ + private Quest quest; + + /** + * Constructs a new {@code BarrelDialogue} {@code Object}. + */ + public BarrelDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code BarrelDialogue} {@code Object}. + * + * @param player the player. + */ + public BarrelDialogue(final Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new BarrelDialogue(player); + } + + @Override + public boolean open(Object... args) { + barrel = (Scenery) args[0]; + quest = player.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP); + if ((quest.getStage(player) == 70 || quest.getStage(player) == 72) && !player.hasItem(TouristTrap.ANNA_BARREL)) { + interpreter.sendDialogue("You search the barrels and find Ana."); + stage = 400; + return true; + } + if (player.getInventory().containsItem(TouristTrap.BARREL)) { + player.getPacketDispatch().sendMessage("You can only manage to have one of these at a time."); + end(); + return true; + } + interpreter.sendItemMessage(TouristTrap.BARREL, "This barrel is quite big. but you may be able to carry one. Would you like to take one?"); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 400:// finding anna. + interpreter.sendDialogues(823, null, "Let me out!"); + stage++; + break; + case 401: + if (!player.getInventory().hasSpaceFor(TouristTrap.ANNA_BARREL)) { + end(); + return true; + } + player.getPacketDispatch().sendMessage("You pick up Ana in a Barrel."); + player.getInventory().add(TouristTrap.ANNA_BARREL); + end(); + break; + case 402: + end(); + break; + case 0: + options("Yeah, cool!", "No thanks."); + stage++; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendItemMessage(TouristTrap.BARREL, "You take the barrel, it's not heavy, just awkward."); + stage = 3; + break; + case 2: + end(); + break; + } + break; + case 3: + end(); + player.getInventory().add(TouristTrap.BARREL, player); + SceneryBuilder.remove(barrel); + GameWorld.getPulser().submit(new Pulse(40) { + @Override + public boolean pulse() { + SceneryBuilder.add(barrel); + return true; + } + }); + break; + + } + return true; + } + + @Override + public int[] getIds() { + return new int[]{DialogueInterpreter.getDialogueKey("barrel dialogue")}; + } + + } + + /** + * The use with handler for the bedabin anvil. + * + * @author 'Vexia + * @version 1.0 + */ + public static final class BedabinAnvilHandler extends UseWithHandler { + + /** + * Constructs a new {@code BedabinAnvilHandler} {@code Object}. + */ + public BedabinAnvilHandler() { + super(2349); + } + + @Override + public Plugin newInstance(Object arg) { + addHandler(2672, OBJECT_TYPE, this); + ClassScanner.definePlugin(new PrototypeDartHandler()); + ClassScanner.definePlugin(new BedabinAnvilDialogue()); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + final Quest quest = player.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP); + if (quest.getStage(player) == 54 && player.getInventory().containsItem(TouristTrap.TECHNICAL_PLANS)) { + player.getDialogueInterpreter().open("bedabin-anvil"); + return true; + } else { + player.getPacketDispatch().sendMessage("You need technical plans in order to do this."); + } + return true; + } + + /** + * The handler used to handle the anna barrel on the winch. + * + * @author 'Vexia + * @version 1.0 + */ + public static final class AnnaWinchHandler extends UseWithHandler { + + /** + * Constructs a new {@code AnnaWinchHandler} {@code Object}. + */ + public AnnaWinchHandler() { + super(TouristTrap.ANNA_BARREL.getId()); + } + + @Override + public Plugin newInstance(Object arg) { + addHandler(18951, OBJECT_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + final Quest quest = player.getQuestRepository().getQuest(Quests.THE_TOURIST_TRAP); + if (!event.getUsedWith().getLocation().equals(Location.create(3292, 9423, 0))) { + return false; + } + if (quest.getStage(player) == 70) { + player.getDialogueInterpreter().open("winch dialogue", true); + return true; + } + return false; + } + + } + + /** + * The prototype dart creation handler. + * + * @author 'Vexia + * @version 1.0 + */ + public static final class PrototypeDartHandler extends UseWithHandler { + + /** + * Constructs a new {@code PrototypeDartHandler} {@code Object}. + */ + public PrototypeDartHandler() { + super(314); + } + + @Override + public Plugin newInstance(Object arg) { + addHandler(TouristTrap.PROTOTYPE_DART_TIP.getId(), ITEM_TYPE, this); + ClassScanner.definePlugin(new ProtoTypeDialogue()); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + player.getDialogueInterpreter().open("prototype dart"); + return true; + } + + /** + * The prototype dialogue plugin. + * + * @author 'Vexia + * @version 1.0 + */ + public static final class ProtoTypeDialogue extends DialoguePlugin { + + /** + * The feathers item. + */ + private static final Item FEATHERS = new Item(314, 10); + + /** + * Constructs a new {@code ProtoTypeDialogue} {@code Object}. + * + * @param player the player. + */ + public ProtoTypeDialogue(final Player player) { + super(player); + } + + /** + * Constructs a new {@code ProtoTypeDialogue} {@code Object}. + */ + public ProtoTypeDialogue() { + /** + * empty. + */ + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new ProtoTypeDialogue(player); + } + + @Override + public boolean open(Object... args) { + if (!player.getInventory().containsItem(FEATHERS)) { + interpreter.sendDialogue("You need 10 feathers in order to do this."); + stage = 10; + return false; + } + interpreter.sendItemMessage(314, "You try to attach feathers to the bronze dart tip."); + stage = 1; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 1: + interpreter.sendDialogue("Following the plans is tricky, but you persevere."); + stage++; + break; + case 2: + interpreter.sendItemMessage(TouristTrap.PROTOTYPE_DART, "You successfully attach the feathers to the dart tip."); + stage++; + break; + case 3: + player.getInventory().remove(FEATHERS, TouristTrap.PROTOTYPE_DART_TIP); + player.getInventory().add(TouristTrap.PROTOTYPE_DART); + end(); + break; + case 4: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[]{DialogueInterpreter.getDialogueKey("prototype dart")}; + } + + } + } + + /** + * The bedabin dialogue plugin handler. + * + * @author 'Vexia + * @version 1.0 + */ + public static final class BedabinAnvilDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code BedabinAnvilDialogue} {@code Object}. + */ + public BedabinAnvilDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code BedabinAnvilDialogue} {@code Object}. + * + * @param player the player. + */ + public BedabinAnvilDialogue(final Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new BedabinAnvilDialogue(player); + } + + @Override + public boolean open(Object... args) { + if (!player.getInventory().containsItem(TouristTrap.TECHNICAL_PLANS)) { + player.getPacketDispatch().sendMessage("You need the plans to do this."); + return false; + } + player.getDialogueInterpreter().sendItemMessage(TouristTrap.TECHNICAL_PLANS, "Do you want to follow the technical plans ?"); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + options("Yes. I'd like to try.", "No, not just yet."); + stage++; + break; + case 1: + switch (buttonId) { + case 1: + end(); + player.getPulseManager().run(new ProtoTypePulse(player)); + break; + case 2: + end(); + break; + } + break; + } + return true; + } + + /** + * The skill pulse used to make a prototype dart. + * + * @author 'Vexia + * @version 1.0 + */ + public static final class ProtoTypePulse extends SkillPulse { + + /** + * The hammer item. + */ + private static final Item HAMMER = new Item(2347); + + /** + * The ticks passed. + */ + private int ticks; + + /** + * Constructs a new {@code ProtoTypePulse} {@code Object}. + * + * @param player the player. + */ + public ProtoTypePulse(Player player) { + super(player, null); + } + + @Override + public boolean checkRequirements() { + if (!player.getInventory().hasSpaceFor(TouristTrap.PROTOTYPE_DART_TIP)) { + player.getPacketDispatch().sendMessage("Not enough inventory space."); + return false; + } + if (!player.getInventory().containsItem(HAMMER)) { + player.getPacketDispatch().sendMessage("You need a hammer in order to work metal with."); + return false; + } + return player.getInventory().containsItem(Bar.BRONZE.getProduct()); + } + + @Override + public void animate() { + if (ticks % 4 == 0) { + player.animate(Animation.create(898)); + } + } + + @Override + public boolean reward() { + if (++ticks % 4 != 0) { + return false; + } + if (ticks == 4) { + player.getDialogueInterpreter().sendPlainMessage(true, "You begin experimenting in forging the weapon..."); + } else if (ticks == 8) { + player.getInventory().remove(Bar.BRONZE.getProduct()); + player.getInventory().add(TouristTrap.PROTOTYPE_DART_TIP); + player.getDialogueInterpreter().sendItemMessage(TouristTrap.PROTOTYPE_DART_TIP, "You follow the plans carefully, and after some careful", "work, you finally manage to forge a sharp, pointed...", "dart tip."); + return true; + } + return false; + } + + @Override + public void stop() { + super.stop(); + } + + } + + @Override + public int[] getIds() { + return new int[]{DialogueInterpreter.getDialogueKey("bedabin-anvil")}; + } + + } + } +} diff --git a/Server/src/main/content/region/desert/sophanem/dialogue/EmbalmerDialogue.kt b/Server/src/main/content/region/desert/sophanem/dialogue/EmbalmerDialogue.kt new file mode 100644 index 0000000..99ee9e3 --- /dev/null +++ b/Server/src/main/content/region/desert/sophanem/dialogue/EmbalmerDialogue.kt @@ -0,0 +1,41 @@ +package content.region.desert.sophanem.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class EmbalmerDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npc(FacialExpression.SUSPICIOUS,"What are you doing?").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> playerl(FacialExpression.FRIENDLY, "I have this acne potion which I thought might help ease your itching.").also { stage++ } + 1 -> npcl(FacialExpression.ANNOYED, "If I thought that these spots could be cured by some potion, I would have mixed up one myself before now.").also { stage++ } + 2 -> player(FacialExpression.SAD, "Sorry, I was just trying to help.").also { stage = 99 } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return EmbalmerDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.EMBALMER_1980) + } +} diff --git a/Server/src/main/content/region/desert/sophanem/dialogue/KlenterNPC.java b/Server/src/main/content/region/desert/sophanem/dialogue/KlenterNPC.java new file mode 100644 index 0000000..70e046b --- /dev/null +++ b/Server/src/main/content/region/desert/sophanem/dialogue/KlenterNPC.java @@ -0,0 +1,35 @@ +package content.region.desert.sophanem.dialogue; + +import core.plugin.Initializable; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; + +/** + * Handles the Klenter NPC, which should be invisible until a quest stage has been reached. Will do that when quest is added. + * @author ceik + */ +@Initializable +public class KlenterNPC extends DialoguePlugin { + public KlenterNPC(){ + /** + * Empty + */ + } + public KlenterNPC(Player player){super(player);} + + @Override + public DialoguePlugin newInstance(Player player){return new KlenterNPC(player);} + + @Override + public boolean open(Object... args){ + npc("OOOOoOOOoOO"); + return true; + } + + @Override + public boolean handle(int interfaceId,int buttonId){ + return true; + } + @Override + public int[] getIds(){return new int[] {2014};} +} diff --git a/Server/src/main/content/region/desert/sophanem/dialogue/SphinxDialogue.java b/Server/src/main/content/region/desert/sophanem/dialogue/SphinxDialogue.java new file mode 100644 index 0000000..0d94a49 --- /dev/null +++ b/Server/src/main/content/region/desert/sophanem/dialogue/SphinxDialogue.java @@ -0,0 +1,113 @@ +package content.region.desert.sophanem.dialogue; + +import core.plugin.Initializable; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; + +/** + * Handles Sphinx dialogue + * @author ceik + */ +@Initializable +public final class SphinxDialogue extends DialoguePlugin { + public SphinxDialogue() { + /** + * Empty + */ + } + public SphinxDialogue(Player player){super(player);} + + @Override + public DialoguePlugin newInstance(Player player) { + return new SphinxDialogue(player); + } + + @Override + public boolean open(Object... args){ + npc = (NPC) args[0]; + if(player.getFamiliarManager().hasPet() && player.getFamiliarManager().getFamiliar().getId() >= 761 && player.getFamiliarManager().getFamiliar().getId() < 767){ + player("Good day."); + stage = 50; + } else { + player("Good day."); + stage = 0; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId){ + switch(stage){ + case 0: + npc("You have the feel of a cat person","about you. Do you look after one?"); + stage = 1; + break; + case 1: + interpreter.sendOptions("Select one.","Yes, but I don't bring it to harsh places like this.","No, you are mistaken.","Yes, but I have left mine in the bank."); + stage = 2; + break; + case 2: + switch(buttonId){ + case 1: + player("Yes, but I don't bring it to harsh places like this."); + stage = 3; + break; + case 2: + player("No, you are mistaken."); + stage = 5; + break; + case 3: + player("Yes, but I have left mine in the bank."); + stage = 7; + break; + } + break; + case 3: + npc(FacialExpression.SAD,"A pity, they can be of great help in","some adventures. I would like to talk to","your cat. Would you bring it to me?"); + stage = 4; + break; + case 4: + player("I might, but I have a few things to sort out first."); + stage = 10; + break; + case 5: + npc(FacialExpression.SUSPICIOUS,"Really? I'm generally quite good at knowing","these things."); + stage = 10; + break; + case 7: + npc(FacialExpression.AFRAID,"What? That's no place for a cat!"); + stage = 10; + break; + case 10: + end(); + break; + case 50: + player.getDialogueInterpreter().sendDialogue("The Sphinx ignores you."); + stage = 51; + break; + case 51: + npc("Ah, how interesting... a cat. Come here to","me, kitty."); + stage = 52; + break; + case 52: + player.getFamiliarManager().getFamiliar().sendChat("Meow"); + stage = 53; + break; + case 53: + player.getDialogueInterpreter().sendDialogue("The Sphinx and the cat have a chat."); + stage = 54; + break; + case 54: + //TODO : Add dialogue for quest-related bits after the quests are added, ends here for now. + end(); + break; + } + return true; + } + @Override + public int[] getIds() { + return new int[] { 1990 }; + } +} diff --git a/Server/src/main/content/region/desert/sophanem/dialogue/TarikDialogue.kt b/Server/src/main/content/region/desert/sophanem/dialogue/TarikDialogue.kt new file mode 100644 index 0000000..ac6aaa0 --- /dev/null +++ b/Server/src/main/content/region/desert/sophanem/dialogue/TarikDialogue.kt @@ -0,0 +1,83 @@ +package content.region.desert.sophanem.dialogue + +import core.api.sendDialogue +import core.api.setAttribute +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs +import core.tools.END_DIALOGUE + +@Initializable +class TarikDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun open(vararg args: Any?): Boolean { + npcl(FacialExpression.WORRIED, "Ouch!") + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage) + { + 0 -> playerl(FacialExpression.HALF_WORRIED, "Are you alright?").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "I'm fine, I'm fine. Just a scratch.").also { stage++ } + 2 -> options("Who are you then?","How did you injure yourself?","Do you know anything about this pyramid?").also { stage++ } + 3 -> when(buttonId) { + 1 -> playerl(FacialExpression.FRIENDLY, "Who are you then?").also { stage = 10 } + 2 -> playerl(FacialExpression.HALF_WORRIED, "How did you injure yourself?").also { stage = 20 } + 3 -> playerl(FacialExpression.HALF_ASKING, "So what's in the pyramid?").also { stage = 30 } + } + + //Who are you + 10 -> npcl(FacialExpression.FRIENDLY, "Me? I'm Tarik.").also { stage++ } + 11 -> playerl(FacialExpression.HALF_ASKING, "That hat you're wearing doesn't look like it comes from around here?").also { stage++ } + 12 -> npcl(FacialExpression.FRIENDLY, "It was a present, my employer thought it would suit me. I'm not sure what it does, though it does keep the sun off very well.").also { stage++ } + 13 -> playerl(FacialExpression.FRIENDLY, "Who is your employer then?").also { stage++ } + 14 -> npcl(FacialExpression.FRIENDLY, "Simon Templeton, though I haven't seen him since the town gates were closed off.").also { stage++ } + 15 -> playerl(FacialExpression.HALF_THINKING, "Simon Templeton ... that name seems familiar?").also { stage++ } + 16 -> npcl(FacialExpression.FRIENDLY, "He's an archaeologist, I worked as an assistant for him. Though I work for myself now.").also { stage++ } + 17 -> playerl(FacialExpression.FRIENDLY, "So what have you been up to?").also { stage++ } + 18 -> npcl(FacialExpression.FRIENDLY, "Simon suggested that there might be riches to be found in that pyramid over there.").also { stage = 30 } + + //How did you injure yourself + 20 -> npcl(FacialExpression.NEUTRAL, "I've been investigating that pyramid over there.").also { stage = 30 } + + //Do you know anything about this pyramid? + 30 -> npcl(FacialExpression.HALF_THINKING, "Well, I'm not sure. First of all there's something odd about the doors on the place. There's four of them - but three of them lead to an empty tomb. The other one is guarded by something.").also { stage++ } + 31 -> npcl(FacialExpression.THINKING, "If I make it through the door there's a Mummy waiting. But which door the right one is seems to change, it's all quite confusing.").also { stage++ } + 32 -> playerl(FacialExpression.HALF_ASKING, "What about this Mummy?").also { stage++ } + 33 -> npcl(FacialExpression.FRIENDLY, "I don't think he likes people. However he does allow you to enter some of the rooms in the tomb. They are dangerous though.").also { stage++ } + 34 -> playerl(FacialExpression.HAPPY, "Bah, I laugh in the face of danger!").also { stage++ } + 35 -> npcl(FacialExpression.FRIENDLY, "Well, if you go into that pyramid then you'll be laughing a lot then. It's full of poisonous snakes and scarabs, and rather nasty Mummies as well. You could die in there.").also { stage++ } + 36 -> npcl(FacialExpression.FRIENDLY, "I managed to get into one room, but the next room was harder. My lockpicking skills weren't good enough, maybe I should have brought a lockpick.").also { stage++ } + 37 -> sendDialogue(player, "The first room in the pyramid requires a thieving level of 21. Each subsequent room requires an extra 10 levels to enter.").also { stage++ } + 38 -> npcl(FacialExpression.NEUTRAL, "There are also lots of poisonous snakes in the urns. They'll bite you if they can. You might be able to charm them if you know how. I'd bring some antipoison anyway if I were you.").also { stage++ } + 39 -> playerl(FacialExpression.FRIENDLY, "It all sounds like fun to me. So is there anything valuable in there?").also { stage++ } + 40 -> npcl(FacialExpression.NEUTRAL, "There are lots of artefacts, you should be able to sell them on the black market, I mean, to a legitimate trader, for some money.").also { stage++ } + 41 -> playerl(FacialExpression.NEUTRAL, "You mean Simon Templeton?").also { stage++ } + 42 -> npcl(FacialExpression.NEUTRAL, "Well, he's a 'legitimate' as you can get, if you can get out of this city and get to him.").also { stage++ } + 43 -> playerl(FacialExpression.FRIENDLY, "I'll find a way. Is there anything else of value in there?").also { stage++ } + 44 -> npcl(FacialExpression.SUSPICIOUS, "I have heard a rumour that there is a valuable magic sceptre in there as well.").also { stage++ } + 45 -> playerl(FacialExpression.HALF_THINKING, "Ah, now you have piqued my interest. What do you know about this sceptre?").also { stage++ } + 46 -> npcl(FacialExpression.SUSPICIOUS, "Not a lot. It is apparently made of gold and covered in jewels, and used to be owned by one of Tumeken's sons.").also { stage++ } + 47 -> playerl(FacialExpression.HALF_ASKING, "Tumeken?").also { setAttribute(player, "/save:tarik-spoken-to", true); stage++ } + 48 -> npcl(FacialExpression.NEUTRAL, "Tumeken, the sun god and head of the gods. His sons were the rulers, chosen by him to rule in his name.").also { stage++ } + 49 -> playerl(FacialExpression.HALF_THINKING, "So these sons were rich and powerful then? This sceptre should be pretty good then.").also { stage++ } + 50 -> npcl(FacialExpression.NEUTRAL, "Hmmm. Well it is supposed to have some magical powers.").also { stage++ } + 51 -> playerl(FacialExpression.HALF_ASKING, "Magical powers? This sounds good. What are they?").also { stage++ } + 52 -> npcl(FacialExpression.LAUGH, "I'll let you know when I find it!").also { stage++ } + 53 -> playerl(FacialExpression.ANNOYED, "Not if I find it first!").also { stage++ } + 54 -> npcl(FacialExpression.FRIENDLY, "Hey! If you find it I deserve a share of the profits! You wouldn't have known it existed without my help.").also { stage++ } + 55 -> playerl(FacialExpression.NEUTRAL, "I'll think about it... Right, I think I'd better investigate this place.").also { stage = END_DIALOGUE } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.TARIK_4478) + } + + override fun newInstance(player: Player?): DialoguePlugin { + return TarikDialogue(player) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/desert/sophanem/handlers/SophanemPlugin.java b/Server/src/main/content/region/desert/sophanem/handlers/SophanemPlugin.java new file mode 100644 index 0000000..219c1ca --- /dev/null +++ b/Server/src/main/content/region/desert/sophanem/handlers/SophanemPlugin.java @@ -0,0 +1,59 @@ +package content.region.desert.sophanem.handlers; + +import core.cache.def.impl.SceneryDefinition; +import core.game.global.action.ClimbActionHandler; +import core.game.global.action.DoorActionHandler; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; + +import static core.api.ContentAPIKt.hasRequirement; +import content.data.Quests; + +/** + * The plugin for handling stuff in Sophanem. + * @author jamix77, Player Name + * + */ +@Initializable +public class SophanemPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(20277).getHandlers().put("option:climb-up", this); + SceneryDefinition.forId(20275).getHandlers().put("option:climb-down", this); + SceneryDefinition.forId(20391).getHandlers().put("option:open", this); + SceneryDefinition.forId(28514).getHandlers().put("option:open", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + final int id = node instanceof Scenery ? ((Scenery) node).getId() : ((Item) node).getId(); + switch (id) { + case 20275: + if (!hasRequirement(player, Quests.CONTACT)) { + break; + } + ClimbActionHandler.climb(player, new Animation(827), Location.create(2799, 5160, 0)); + break; + case 20277: + ClimbActionHandler.climb(player, new Animation(828), Location.create(3315,2796,0)); + break; + case 20391: + case 28514: + if (!hasRequirement(player, Quests.ICTHLARINS_LITTLE_HELPER)) { + break; + } + DoorActionHandler.handleDoor(player, (Scenery) node); + break; + } + return true; + } +} diff --git a/Server/src/main/content/region/desert/sophanem/handlers/WallShortcut.java b/Server/src/main/content/region/desert/sophanem/handlers/WallShortcut.java new file mode 100644 index 0000000..4e335a0 --- /dev/null +++ b/Server/src/main/content/region/desert/sophanem/handlers/WallShortcut.java @@ -0,0 +1,66 @@ +package content.region.desert.sophanem.handlers; + +import core.cache.def.impl.SceneryDefinition; +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.impl.ForceMovement; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; + +/** + * Handles the Sophanem wall shortcut + * @author ceik + */ +@Initializable +public final class WallShortcut extends OptionHandler { + + private static final Animation CLIMB_DOWN = Animation.create(2589); + + private static final Animation CRAWL_THROUGH = Animation.create(2590); + + private static final Animation CLIMB_UP = Animation.create(2591); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(6620).getHandlers().put("option:climb-through", this); + return null; + } + + @Override + public boolean handle(final Player player, Node node, String option) { + if (player.getSkills().getLevel(Skills.AGILITY) < 21) { + player.getDialogueInterpreter().sendDialogue("You need an Agility level of at least 21 to do this."); + return true; + } + player.lock(4); + final Scenery o = (Scenery) node; + if (o.getId() == 6620) { + ForceMovement.run(player, Location.create(3320, 2796, 0), o.getLocation(), CLIMB_DOWN); + GameWorld.getPulser().submit(new Pulse(1, player) { + int count; + + @Override + public boolean pulse() { + switch (++count) { + case 2: + player.animate(CRAWL_THROUGH); + player.getProperties().setTeleportLocation(Location.create(3324, 2796, 0)); + break; + case 3: + ForceMovement.run(player, Location.create(3324, 2796, 0), Location.create(3324, 2796, 0), CLIMB_UP); + return true; + } + return false; + } + }); + } + return true; + } +} diff --git a/Server/src/main/content/region/desert/ullek/handlers/UllekListeners.kt b/Server/src/main/content/region/desert/ullek/handlers/UllekListeners.kt new file mode 100644 index 0000000..f2b7904 --- /dev/null +++ b/Server/src/main/content/region/desert/ullek/handlers/UllekListeners.kt @@ -0,0 +1,42 @@ +package content.region.desert.ullek.handlers + +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Scenery + +class UllekListeners : InteractionListener { + override fun defineListeners() { + on(Scenery.STAIRS_DOWN_28481, IntType.SCENERY, "enter") { player, _ -> + player.properties.teleportLocation = Location.create(3448, 9252, 1) + return@on true + } + on(Scenery.EXIT_28401, IntType.SCENERY, "leave through") { player, _ -> + player.properties.teleportLocation = Location.create(3412, 2848, 1) + return@on true + } + on(Scenery.FALLEN_PILLAR_28516, IntType.SCENERY, "climb") { player, _ -> + player.properties.teleportLocation = Location.create(3419, 2801, 0) + return@on true + } + on(Scenery.FALLEN_PILLAR_28515, IntType.SCENERY, "climb") { player, _ -> + player.properties.teleportLocation = Location.create(3419, 2803, 1) + return@on true + } + on(Scenery.REEDS_28474, IntType.SCENERY, "push through") { player, node -> + animate(player, 7633) + animateScenery(node as core.game.node.scenery.Scenery, 7634) + queueScript(player, animationDuration(Animation(7633)), QueueStrength.SOFT) { + val newLoc = node.location.transform(Location.getDelta(player.location, node.location)) + player.walkingQueue.reset() + player.walkingQueue.addPath(newLoc.x, newLoc.y) + + return@queueScript stopExecuting(player) + } + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/dialogue/CaptainBentleyDialogue.java b/Server/src/main/content/region/fremennik/dialogue/CaptainBentleyDialogue.java new file mode 100644 index 0000000..b74d3fc --- /dev/null +++ b/Server/src/main/content/region/fremennik/dialogue/CaptainBentleyDialogue.java @@ -0,0 +1,117 @@ +package content.region.fremennik.dialogue; + +import core.game.component.Component; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.net.packet.PacketRepository; +import core.net.packet.context.MinimapStateContext; +import core.plugin.Initializable; +import core.net.packet.out.MinimapState; + +/** + * Handles the captain bentley dialogue. + * @author Vexia + */ +@Initializable +public class CaptainBentleyDialogue extends DialoguePlugin { + + /** + * If we're on the isle. + */ + private boolean onIsle; + + /** + * Constructs a new {@Code CaptainBentleyDialogue} {@Code + * Object} + */ + public CaptainBentleyDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@Code CaptainBentleyDialogue} {@Code + * Object} + * @param player the player. + */ + public CaptainBentleyDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new CaptainBentleyDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + onIsle = npc.getLocation().getRegionId() == 8508; + npc("Hi, would you like to travel to " + (onIsle ? "Pirate's Cove" : "Lunar Isle") + "?"); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + options("Yes, please.", "No, thanks."); + stage++; + break; + case 1: + end(); + if (buttonId == 1) { + travel(player, !onIsle ? Location.create(2131, 3900, 2) : Location.create(2216, 3797, 2)); + return true; + } + break; + } + return true; + } + + /** + * Travels to a location. + * @param location the location. + */ + private void travel(final Player player, final Location location) { + player.lock(); + GameWorld.getPulser().submit(new Pulse(1, player) { + int counter; + + @Override + public boolean pulse() { + switch (counter++) { + case 1: + player.lock(); + player.getInterfaceManager().openOverlay(new Component(115)); + break; + case 3: + PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 2)); + break; + case 4: + player.getProperties().setTeleportLocation(location); + break; + case 5: + player.getInterfaceManager().closeOverlay(); + player.getInterfaceManager().close(); + PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 0)); + player.unlock(); + return true; + } + return false; + } + + }); + } + + @Override + public int[] getIds() { + return new int[] { 4540 }; + } + +} diff --git a/Server/src/main/content/region/fremennik/dialogue/JossikDialogue.java b/Server/src/main/content/region/fremennik/dialogue/JossikDialogue.java new file mode 100644 index 0000000..2af173c --- /dev/null +++ b/Server/src/main/content/region/fremennik/dialogue/JossikDialogue.java @@ -0,0 +1,178 @@ +package content.region.fremennik.dialogue; + +import core.game.dialogue.DialoguePlugin; +import content.data.GodBook; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; + +import java.util.ArrayList; +import java.util.List; + +import static core.api.ContentAPIKt.addItemOrDrop; +import static core.api.ContentAPIKt.hasAnItem; + +/** + * Handles the dialogue for Jossik. + * @author Vexia + */ +@Initializable +public class JossikDialogue extends DialoguePlugin { + + /** + * The uncompleted list of books. + */ + private List uncompleted; + + /** + * Constructs a new {@code JossikDialogue} {@code Object} + */ + public JossikDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code JossikDialogue} {@code Object} + * @param player the player. + */ + public JossikDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new JossikDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + npc("Hello again, adventurer.", "What brings you this way?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + options("Can I see your wares?", "Have you found any prayerbooks?"); + stage++; + break; + case 1: + if (buttonId == 1) { + player("Can I see your wares?"); + stage = 10; + } else { + player("Have you found any prayerbooks?"); + stage = 20; + } + break; + case 20: + boolean missing = false; + for (GodBook book : GodBook.values()) { + if (player.getSavedData().getGlobalData().hasCompletedGodBook(book) && hasAnItem(player, book.getBook().getId(), true).getContainer() == null) { + // i.e.: if you have a completed book on file but you lost it + missing = true; + addItemOrDrop(player, book.getBook().getId(), 1); + } + } + int damaged = player.getSavedData().getGlobalData().getGodBook(); + if (damaged != -1 && hasAnItem(player, GodBook.values()[damaged].getDamagedBook().getId(), true).getContainer() == null) { + // i.e.: if you have an uncompleted book on file but you lost it + missing = true; + addItemOrDrop(player, GodBook.values()[damaged].getDamagedBook().getId(), 1); + } + if (missing) { + npc("As a matter of fact, I did! This book washed up on the", "beach, and I recognised it as yours!"); + stage = 23; + return true; + } + uncompleted = new ArrayList<>(3); + for (GodBook book : GodBook.values()) { + if (!player.getSavedData().getGlobalData().hasCompletedGodBook(book)) { + uncompleted.add(book); + } + } + boolean hasUncompleted = false; + for (GodBook book : GodBook.values()) { + if (hasAnItem(player,book.getDamagedBook().getId(), true).getContainer() != null) { + // i.e.: you have an uncompleted book on file and you still have it -> do not allow the player to get a new one, GL #2035 + hasUncompleted = true; + } + } + if (uncompleted.isEmpty() || hasUncompleted) {// all completed. + npc("No, sorry adventurer, I haven't."); + stage = 23; + return true; + } + npc("Funnily enough I have! I found some books in caskets", "just the other day! I'll sell one to you for 5000 coins;", "what do you say?"); + stage++; + break; + case 21: + String[] names = new String[uncompleted.size() + 1]; + for (int i = 0; i < uncompleted.size(); i++) { + names[i] = uncompleted.get(i).getName(); + } + names[names.length - 1] = "Don't buy anything."; + options(names); + stage++; + break; + case 22: + if (buttonId - 1 > uncompleted.size() - 1) { + player("Don't buy anything."); + stage = 23; + break; + } + if (!player.getInventory().contains(995, 5000)) { + player("Sorry, I don't seem to have enough coins."); + stage = 23; + break; + } + if (player.getInventory().freeSlots() == 0) { + player("Sorry, I don't have enough inventory space."); + stage = 23; + break; + } + GodBook purchase = uncompleted.get(buttonId - 1); + if (purchase != null && player.getInventory().remove(new Item(995, 5000))) { + npc("Here you go!"); + player.getSavedData().getGlobalData().setGodBook(purchase.ordinal()); + player.getInventory().add(purchase.getDamagedBook(), player); + stage = 23; + } else { + end(); + } + break; + case 23: + end(); + break; + case 10: + npc("Sure thing!", "I think you'll agree, my prices are remarkable!"); + stage++; + break; + case 11: + npc.openShop(player); + end(); + break; + } + return true; + } + + /** + * Checks if the player has a god book. + * @return {@code True} if so. + */ + public boolean hasGodBook() { + return true; + } + + @Override + public int[] getIds() { + return new int[] { 1334, 1335 }; + } + +} diff --git a/Server/src/main/content/region/fremennik/dialogue/LokarSearunnerDialogue.java b/Server/src/main/content/region/fremennik/dialogue/LokarSearunnerDialogue.java new file mode 100644 index 0000000..19e6396 --- /dev/null +++ b/Server/src/main/content/region/fremennik/dialogue/LokarSearunnerDialogue.java @@ -0,0 +1,151 @@ +package content.region.fremennik.dialogue; + +import core.game.component.Component; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.net.packet.PacketRepository; +import core.net.packet.context.MinimapStateContext; +import core.plugin.Initializable; +import core.net.packet.out.MinimapState; +import static core.api.ContentAPIKt.hasRequirement; +import content.data.Quests; + +/** + * Handles the lokar searunner dialogue. + * @author Vexia + */ +@Initializable +public class LokarSearunnerDialogue extends DialoguePlugin { + + /** + * The location of Rellekka. + */ + private static final Location RELEKKA = new Location(2621, 3687, 0); + + /** + * The pirate's minigame. + */ + private static final Location PIRATES_COVE = new Location(2213, 3794, 0); + + /** + * Constructs a new {@Code LokarSearunnerDialogue} {@Code + * Object} + */ + public LokarSearunnerDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@Code LokarSearunnerDialogue} {@Code + * Object} + * @param player the player. + */ + public LokarSearunnerDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new LokarSearunnerDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + switch (npc.getId()) { + case 4536: + npc("Hi, would you like to take a boat trip to Rellekka?"); + break; + case 4537: + npc("Hi, would you like to take a boat trip to Pirates' Cove?"); + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (npc.getId()) { + case 4536: + switch (stage) { + case 0: + options("Yes, please.", "No, thanks."); + stage++; + break; + case 1: + end(); + if (buttonId == 1) { + travel(player, RELEKKA); + return true; + } + break; + } + break; + case 4537: + switch (stage) { + case 0: + options("Yes, please.", "No, thanks."); + stage++; + break; + case 1: + end(); + if (buttonId == 1) { + travel(player, PIRATES_COVE); + return true; + } + break; + } + break; + } + return true; + } + + /** + * Travels to a location. + * @param location the location. + */ + private void travel(final Player player, final Location location) { + if (!hasRequirement(player, Quests.LUNAR_DIPLOMACY)) + return; + player.lock(); + GameWorld.getPulser().submit(new Pulse(1, player) { + int counter; + + @Override + public boolean pulse() { + switch (counter++) { + case 1: + player.lock(); + player.getInterfaceManager().openOverlay(new Component(115)); + break; + case 3: + PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 2)); + break; + case 4: + player.getProperties().setTeleportLocation(location); + break; + case 5: + PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 0)); + player.getInterfaceManager().close(); + player.getInterfaceManager().closeOverlay(); + player.unlock(); + return true; + } + return false; + } + + }); + } + + @Override + public int[] getIds() { + return new int[] { 4536, 4537 }; + } + +} diff --git a/Server/src/main/content/region/fremennik/diary/FremennikAchievementDiary.kt b/Server/src/main/content/region/fremennik/diary/FremennikAchievementDiary.kt new file mode 100644 index 0000000..51d1609 --- /dev/null +++ b/Server/src/main/content/region/fremennik/diary/FremennikAchievementDiary.kt @@ -0,0 +1,358 @@ +package content.region.fremennik.diary + +import content.global.handlers.iface.FairyRing +import content.minigame.barbassault.CaptainCainDialogue +import content.region.fremennik.jatizso.dialogue.TowerGuardDialogue +import content.region.fremennik.rellekka.dialogue.HuntingExpertRellekkaDialogue +import content.region.fremennik.rellekka.quest.thefremenniktrials.ChieftanBrundt +import core.api.inBorders +import core.api.inEquipment +import core.game.diary.AreaDiaryTask +import core.game.diary.DiaryEventHookBase +import core.game.diary.DiaryLevel +import core.game.event.* +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.SpellBookManager +import core.game.node.entity.player.link.diary.DiaryType +import core.game.node.entity.skill.Skills +import core.game.world.map.zone.ZoneBorders +import org.rs09.consts.* +import content.data.Quests + +class FremennikAchievementDiary : DiaryEventHookBase(DiaryType.FREMENNIK) { + companion object { + private const val ATTRIBUTE_SEAWEED_PICKED = "diary:fremennik:seaweed-picked" + private const val ATTRIBUTE_ROCK_CRAB_KILLCOUNT = "diary:fremennik:rock-crabs-killed" + private const val ATTRIBUTE_BARBARIAN_FISHING_TRAINING = "barbtraining:fishing" + private const val ATTRIBUTE_BARBARIAN_HUNTING_TRAINING = "barbtraining:hunting" + private const val ATTRIBUTE_DAGANNOTHS_KILLCOUNT = "diary:fremennik:dagannoths-killed" + + private val WINDSWEPT_TREE_AREA = ZoneBorders(2743, 3718, 2750, 3737) + private val YRSA_SHOP_BORDERS = ZoneBorders(2622, 3672, 2626, 3676) + private val RELLEKKA_HUNTING_AREA = ZoneBorders(2723, 3776, 2743, 3796) + private val ECTERNIA_TREE_AREA = ZoneBorders(2592, 3887,2620, 3899) + private val RELLEKKA_BLACKSMITH_AREA = ZoneBorders(2616, 3658, 2621, 3668) + + private val FISHING_SPOTS = arrayOf( + NPCs.FISHING_SPOT_309, NPCs.FISHING_SPOT_334, + NPCs.FISHING_SPOT_324, NPCs.FISHING_SPOT_322 + ) + + private val ROCK_CRABS = arrayOf( + NPCs.ROCK_CRAB_1265, NPCs.ROCK_CRAB_1267 + ) + + private val CAVE_CRAWLERS = arrayOf( + NPCs.CAVE_CRAWLER_1600, NPCs.CAVE_CRAWLER_1601, + NPCs.CAVE_CRAWLER_1602, NPCs.CAVE_CRAWLER_1603 + ) + + private val DAGANNOTHS = arrayOf( + NPCs.DAGANNOTH_2455, NPCs.DAGANNOTH_2456, + NPCs.DAGANNOTH_PRIME_2882, NPCs.DAGANNOTH_REX_2883, NPCs.DAGANNOTH_SUPREME_2881 + ) + + private val ICE_TROLLS = arrayOf( + NPCs.ICE_TROLL_RUNT_5521, NPCs.ICE_TROLL_MALE_5522, NPCs.ICE_TROLL_FEMALE_5523, NPCs.ICE_TROLL_GRUNT_5524, + NPCs.ICE_TROLL_RUNT_5525, NPCs.ICE_TROLL_MALE_5526, NPCs.ICE_TROLL_FEMALE_5527, NPCs.ICE_TROLL_GRUNT_5528, + NPCs.ICE_TROLL_RUNT_5473, NPCs.ICE_TROLL_MALE_5474, NPCs.ICE_TROLL_FEMALE_5475, NPCs.ICE_TROLL_GRUNT_5476 + ) + + object EasyTasks { + const val SLAYER_CAVE_KILL_CAVE_CRAWLER = 0 + const val KILL_5_ROCK_CRABS = 1 + const val MAINLAND_FIND_HIGHEST_TREE = 2 + const val BARBARIAN_ASSAULT_VIEW_REWARDS = 3 + const val OTTO_GODBLESSED_LEARN_BARBARIAN_FISHING = 4 + const val PICK_3_SEAWEED = 5 + const val FIND_HUNTING_EXPERT = 6 + const val PIER_CATCH_FISH = 7 + const val GATE_OBELISK_RECHARGE_POINTS = 8 + const val KILL_ADULT_BLACK_UNICORN = 9 + } + + object MediumTasks { + const val LEARN_HISTORY_FROM_CHIEFTAIN_BRUNDT = 0 + const val TOWER_GUARDS_WATCH_SHOUTING_MATCH = 1 + const val INTERACT_WITH_PET_ROCK = 2 + const val MAKE_3_VIALS = 3 + const val CHARM_FOSSEGRIMEN_RAW_BASS = 4 + const val KILL_ICE_TROLL_WHILE_WEARING_YAK_ARMOR = 5 + const val MAKE_CHEESE_WITH_CHURN = 6 + const val DIAL_FAIRY_RING_MOUNTAINTOP = 7 + const val BROWSE_BOOT_COLORS_YRSA = 8 + const val HUNT_SABRE_TOOTHED_KYATT = 9 + const val STEAL_FISH_FROM_STALL = 10 + } + + object HardTasks { + const val KILL_3_DAGANNOTHS = 0 + const val FREMENNIK_HONORIFIC_ARMOR = 1 + const val COMPLETE_BARBARIAN_OUTPOST_AGILITY_COURSE = 2 + const val LUNAR_ISLE_MINE_PURE_ESSENCE = 3 + const val MAKE_BARBARIAN_PYRE_SHIP_ARCTIC_PINE = 4 + const val CATCH_TUNE_WITHOUT_HARPOON = 5 + const val BAKE_PIE_WITH_MAGIC = 6 + const val KILL_MITHRIL_DRAGON = 7 + const val GET_MAHOGANY_FROM_ETCETERIA = 8 + } + } + + override val areaTasks get() = arrayOf( + AreaDiaryTask( + WINDSWEPT_TREE_AREA, + DiaryLevel.EASY, + EasyTasks.MAINLAND_FIND_HIGHEST_TREE + ) + ) + + override fun onAttributeSet(player: Player, event: AttributeSetEvent) { + when (event.attribute) { + "/save:$ATTRIBUTE_BARBARIAN_FISHING_TRAINING" -> { + if (event.value !is Boolean) return + + if (event.value) { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.OTTO_GODBLESSED_LEARN_BARBARIAN_FISHING + ) + } + } + } + } + + override fun onDialogueOpened(player: Player, event: DialogueOpenEvent) { + when (event.dialogue) { + is CaptainCainDialogue -> { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.BARBARIAN_ASSAULT_VIEW_REWARDS + ) + } + + is HuntingExpertRellekkaDialogue -> { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.FIND_HUNTING_EXPERT + ) + } + } + } + + override fun onDialogueOptionSelected(player: Player, event: DialogueOptionSelectionEvent) { + when (event.dialogue) { + is TowerGuardDialogue -> { + if (event.currentStage == 10) { + finishTask( + player, + DiaryLevel.MEDIUM, + MediumTasks.TOWER_GUARDS_WATCH_SHOUTING_MATCH + ) + } + } + + is ChieftanBrundt -> { + if (event.currentStage == 615){ + finishTask( + player, + DiaryLevel.MEDIUM, + MediumTasks.LEARN_HISTORY_FROM_CHIEFTAIN_BRUNDT + ) + } + } + } + } + + override fun onResourceProduced(player: Player, event: ResourceProducedEvent) { + when (player.viewport.region.id) { + 10553 -> if (event.source.id in FISHING_SPOTS) { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.PIER_CATCH_FISH + ) + } else if (event.itemId == Items.CHEESE_1985) { + finishTask( + player, + DiaryLevel.MEDIUM, + MediumTasks.MAKE_CHEESE_WITH_CHURN + ) + } else if (event.source.id == Scenery.FISH_STALL_4277) { + finishTask( + player, + DiaryLevel.MEDIUM, + MediumTasks.STEAL_FISH_FROM_STALL + ) + } + + /* After Royal trouble quest + 10300 -> when (event.itemId) { + Items.MAHOGANY_LOGS_6332 -> { + if (inBorders(player, ECTERNIA_TREE_AREA)) { + finishTask( + player, + DiaryLevel.HARD, + HardTasks.GET_MAHOGANY_FROM_ETCETERIA + ) + } + } + }*/ + } + } + + override fun onNpcKilled(player: Player, event: NPCKillEvent) { + when (player.viewport.region.id) { + 10042, 10554 -> if (event.npc.id in ROCK_CRABS) { + progressIncrementalTask( + player, + DiaryLevel.EASY, + EasyTasks.KILL_5_ROCK_CRABS, + ATTRIBUTE_ROCK_CRAB_KILLCOUNT, + 5 + ) + } + + 11164 -> if (event.npc.id in CAVE_CRAWLERS) { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.SLAYER_CAVE_KILL_CAVE_CRAWLER + ) + } + + 10808, 10809 -> if (event.npc.id == NPCs.BLACK_UNICORN_133) { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.KILL_ADULT_BLACK_UNICORN + ) + } + + 9886, 10142, 11589 -> if (event.npc.id in DAGANNOTHS) { + progressIncrementalTask( + player, + DiaryLevel.HARD, + HardTasks.KILL_3_DAGANNOTHS, + ATTRIBUTE_DAGANNOTHS_KILLCOUNT, + 3 + ) + } + + 6995 -> if (event.npc.id == NPCs.MITHRIL_DRAGON_5363) { + finishTask( + player, + DiaryLevel.HARD, + HardTasks.KILL_MITHRIL_DRAGON + ) + } + + 9276, 9532 -> if (event.npc.id in ICE_TROLLS && inEquipment(player, Items.YAK_HIDE_ARMOUR_10822,1)) { + finishTask( + player, + DiaryLevel.MEDIUM, + MediumTasks.KILL_ICE_TROLL_WHILE_WEARING_YAK_ARMOR + ) + } + } + } + + override fun onPickedUp(player: Player, event: PickUpEvent) { + when (player.viewport.region.id) { + 10810 -> if (event.itemId == Items.SEAWEED_401) { + progressIncrementalTask( + player, + DiaryLevel.EASY, + EasyTasks.PICK_3_SEAWEED, + ATTRIBUTE_SEAWEED_PICKED, + 3 + ) + } + } + } + + override fun onFairyRingDialed(player: Player, event: FairyRingDialEvent) { + if (event.fairyRing == FairyRing.DKS) { + finishTask( + player, + DiaryLevel.MEDIUM, + MediumTasks.DIAL_FAIRY_RING_MOUNTAINTOP + ) + } + } + + override fun onSummoningPointsRecharged(player: Player, event: SummoningPointsRechargeEvent) { + when (player.viewport.region.id) { + 10552 -> if (event.obelisk.id == Scenery.SMALL_OBELISK_29944) { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.GATE_OBELISK_RECHARGE_POINTS + ) + } + } + } + + override fun onInteracted(player: Player, event: InteractionEvent) { + when (player.viewport.region.id) { + 10811 -> if (event.target.id == Scenery.COLLAPSED_TRAP_19233 && inBorders(player, RELLEKKA_HUNTING_AREA) && event.option == "dismantle") { + finishTask( + player, + DiaryLevel.MEDIUM, + MediumTasks.HUNT_SABRE_TOOTHED_KYATT + ) + } + } + + if (event.option == "watch-shouting") { + finishTask( + player, + DiaryLevel.MEDIUM, + MediumTasks.TOWER_GUARDS_WATCH_SHOUTING_MATCH + ) + } + + if (event.target.id == Items.PET_ROCK_3695 && event.option == "interact") { + finishTask( + player, + DiaryLevel.MEDIUM, + MediumTasks.INTERACT_WITH_PET_ROCK + ) + } + + // You can alternatively browse her regular clothing store to complete the task, no purchase necessary. + if (event.target.id == NPCs.YRSA_1301 && event.option == "trade" && player.questRepository.isComplete(Quests.THE_FREMENNIK_TRIALS) && inBorders(player, YRSA_SHOP_BORDERS)) { + finishTask( + player, + DiaryLevel.MEDIUM, + MediumTasks.BROWSE_BOOT_COLORS_YRSA + ) + } + } + + override fun onSpellCast(player: Player, event: SpellCastEvent) { + if (event.spellBook == SpellBookManager.SpellBook.LUNAR && event.spellId == 15) { + finishTask( + player, + DiaryLevel.HARD, + HardTasks.BAKE_PIE_WITH_MAGIC + ) + } + } + + override fun onButtonClicked(player: Player, event: ButtonClickEvent) { + when { + inBorders(player, RELLEKKA_BLACKSMITH_AREA) -> { + if (event.iface == Components.CRAFTING_GLASS_542 && event.buttonId == 38 && player.skills.getLevel(Skills.CRAFTING) >= 33) { + finishTask( + player, + DiaryLevel.MEDIUM, + MediumTasks.MAKE_3_VIALS + ) + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/handlers/FremmenikPlugin.java b/Server/src/main/content/region/fremennik/handlers/FremmenikPlugin.java new file mode 100644 index 0000000..ccfb066 --- /dev/null +++ b/Server/src/main/content/region/fremennik/handlers/FremmenikPlugin.java @@ -0,0 +1,30 @@ +package content.region.fremennik.handlers; + +import core.cache.def.impl.NPCDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.plugin.Plugin; + +/** + * Handles the fremmenik plugin. + * @author Vexia + */ +public class FremmenikPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + NPCDefinition.forId(5508).getHandlers().put("option:ferry-neitiznot", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + switch (option) { + case "ferry-neitiznot": + return true; + } + return true; + } + +} diff --git a/Server/src/main/content/region/fremennik/handlers/HonourGuardGFI.kt b/Server/src/main/content/region/fremennik/handlers/HonourGuardGFI.kt new file mode 100644 index 0000000..d828062 --- /dev/null +++ b/Server/src/main/content/region/fremennik/handlers/HonourGuardGFI.kt @@ -0,0 +1,40 @@ +package content.region.fremennik.handlers + +import core.api.* +import core.game.node.entity.npc.AbstractNPC +import core.game.world.map.Location +import core.plugin.Initializable +import core.tools.RandomFunction +import org.rs09.consts.NPCs + +@Initializable +class HonourGuardGFI : AbstractNPC { + //Constructor spaghetti because Arios I guess + constructor() : super(NPCs.HONOUR_GUARD_5514, null, true) {} + private constructor(id: Int, location: Location) : super(id, location) {} + + override fun construct(id: Int, location: Location, vararg objects: Any?): AbstractNPC { + return HonourGuardGFI(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.HONOUR_GUARD_5514,NPCs.HONOUR_GUARD_5515,NPCs.HONOUR_GUARD_5516,NPCs.HONOUR_GUARD_5517) + } + + override fun tick() { + if(isActive && !inCombat() && RandomFunction.roll(10)){ + val localTrolls = findLocalNPCs(this, intArrayOf(NPCs.ICE_TROLL_FEMALE_5523, NPCs.ICE_TROLL_MALE_5522, NPCs.ICE_TROLL_RUNT_5521, NPCs.ICE_TROLL_GRUNT_5524)) + localTrolls.forEach{troll -> + if(troll.location.withinDistance(location,6)) { + attack(troll) + return super.tick() + } + } + } + if(!isActive){ + properties.combatPulse.stop() + } + return super.tick() + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/handlers/LightHousePlugin.java b/Server/src/main/content/region/fremennik/handlers/LightHousePlugin.java new file mode 100644 index 0000000..b704a4b --- /dev/null +++ b/Server/src/main/content/region/fremennik/handlers/LightHousePlugin.java @@ -0,0 +1,46 @@ +package content.region.fremennik.handlers; + +import core.cache.def.impl.SceneryDefinition; +import core.game.global.action.DoorActionHandler; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Handles the light house plugin. + * @author Vexia + */ +@Initializable +public class LightHousePlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(4577).getHandlers().put("option:walk-through", this); + SceneryDefinition.forId(4383).getHandlers().put("option:climb", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + switch (node.getId()) { + case 4577: + DoorActionHandler.handleDoor(player, node.asScenery()); + return true; + case 4383: + return false; + } + return true; + } + + @Override + public Location getDestination(Node node, Node n) { + if (n.getName().equals("Door")) { + return DoorActionHandler.getDestination((Entity) node, n.asScenery()); + } + return null; + } +} diff --git a/Server/src/main/content/region/fremennik/handlers/TarBarrelListener.kt b/Server/src/main/content/region/fremennik/handlers/TarBarrelListener.kt new file mode 100644 index 0000000..18abaf1 --- /dev/null +++ b/Server/src/main/content/region/fremennik/handlers/TarBarrelListener.kt @@ -0,0 +1,50 @@ +package content.region.fremennik.handlers + +import core.game.node.scenery.SceneryBuilder +import core.game.node.item.Item +import core.tools.RandomFunction +import org.rs09.consts.Items +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +/** + * @author Woah, with love + * Item(s): + * Swamp tar - ID: 1939 + * Object(s): + * Tar barrel (full) - ID: 16860 | Tar barrel (empty) - ID: 16688 + * Option(s): + * "Take-from" + */ +class TarBarrelListener : InteractionListener { + + val FULL_TAR_BARREL_16860 = 16860 + val EMPTY_TAR_BARREL_16688 = 16688 + val EMPTY_BARREL_STRING = "The barrel became empty!" + + override fun defineListeners() { + + on(FULL_TAR_BARREL_16860, IntType.SCENERY, "take-from") { player, node -> + val incrementAmount = RandomFunction.random(83, 1000) + + if (player.inventory.isFull) { + player.sendMessage("Not enough space in your inventory!") + return@on true + } + + if (node.asScenery().charge >= 0) { + node.asScenery().charge = node.asScenery().charge - incrementAmount + player.inventory.add(Item(Items.SWAMP_TAR_1939)) + + if (node.asScenery().charge <= 0) { + player.sendMessage(EMPTY_BARREL_STRING) + SceneryBuilder.replace(node.asScenery(), node.asScenery().transform(EMPTY_TAR_BARREL_16688), 38) + node.asScenery().charge = 1000 + } + } + + return@on true + } + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/jatizso/dialogue/CitizenDialogue.kt b/Server/src/main/content/region/fremennik/jatizso/dialogue/CitizenDialogue.kt new file mode 100644 index 0000000..a964ae5 --- /dev/null +++ b/Server/src/main/content/region/fremennik/jatizso/dialogue/CitizenDialogue.kt @@ -0,0 +1,58 @@ +package content.region.fremennik.jatizso.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs +import core.tools.END_DIALOGUE + +@Initializable +class CitizenDialogue(player: Player? = null) : DialoguePlugin(player) { + val stages = intArrayOf(0, 100, 200, 300) + override fun newInstance(player: Player?): DialoguePlugin { + return CitizenDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + stage = stages.random() + handle(0,0) + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> playerl(FacialExpression.NEUTRAL, "It's a bit grey round here, isn't it?").also { stage++ } + 1 -> npcl(FacialExpression.NEUTRAL, "It gets you down after a while, you know. There are 273 shades of grey, you know, and we have them all.").also { stage++ } + 2 -> playerl(FacialExpression.NEUTRAL, "That's grey-t.").also { stage++ } + 3 -> npcl(FacialExpression.SAD, "That attempt at humour merely made me more depressed. Leave me alone.").also { stage = END_DIALOGUE } + + 100 -> playerl(FacialExpression.NEUTRAL, "Cheer up! It's not the end of the world.").also { stage++ } + 101 -> npcl(FacialExpression.SAD, "I'd prefer that, if it meant I didn't have to talk to people as inanely happy as you.").also { stage++ } + 102 -> playerl(FacialExpression.AMAZED, "Whoa! I think you need to get out more.").also { stage = END_DIALOGUE } + + 200 -> playerl(FacialExpression.NEUTRAL, "How's the King treating you then?").also { stage++ } + 201 -> npcl(FacialExpression.SAD, "Like serfs.").also { stage++ } + 202 -> playerl(FacialExpression.HALF_THINKING, "Serf?").also { stage++ } + 203 -> npcl(FacialExpression.SAD, "Yes, you know - peons, plebs, the downtrodden. He treats us like his own personal possessions.").also { stage++ } + 204 -> playerl(FacialExpression.NEUTRAL, "You should leave this place.").also { stage++ } + 205 -> npcl(FacialExpression.SAD, "I keep trying to save up enough to leave, but the King keeps taxing us! We have no money left." ).also { stage++ } + 206 -> playerl(FacialExpression.SAD, "Oh dear." ).also { stage = END_DIALOGUE } + + 300 -> playerl(FacialExpression.HALF_THINKING, "How are you today?").also { stage++ } + 301 -> npcl(FacialExpression.SAD, "**sigh**").also { stage++ } + 302 -> playerl(FacialExpression.ASKING, "That good? Everyone around here seems a little depressed. ").also { stage++ } + 303 -> npcl(FacialExpression.SAD, "**sigh**").also { stage++ } + 304 -> playerl(FacialExpression.HALF_THINKING, "And not particularly talkative.").also { stage++ } + 305 -> npcl(FacialExpression.SAD, "**sigh**").also { stage++ } + 306 -> playerl(FacialExpression.HALF_THINKING,"I'll leave you to your sighing. It looks like you have plenty to do." ).also { stage = END_DIALOGUE } + + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.LENSA_5494, NPCs.SASSILIK_5496, NPCs.FREYGERD_5493) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/jatizso/dialogue/EricDialogue.kt b/Server/src/main/content/region/fremennik/jatizso/dialogue/EricDialogue.kt new file mode 100644 index 0000000..de6d0b8 --- /dev/null +++ b/Server/src/main/content/region/fremennik/jatizso/dialogue/EricDialogue.kt @@ -0,0 +1,31 @@ +package content.region.fremennik.jatizso.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class EricDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player?): DialoguePlugin { + return EricDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npcl(FacialExpression.HALF_GUILTY, "Spare us a few coppers mister") + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + playerl(FacialExpression.ANGRY, "NO!") + stage = END_DIALOGUE + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.ERIC_5499) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/jatizso/dialogue/GruvaPatrullDialogue.kt b/Server/src/main/content/region/fremennik/jatizso/dialogue/GruvaPatrullDialogue.kt new file mode 100644 index 0000000..cdaec8a --- /dev/null +++ b/Server/src/main/content/region/fremennik/jatizso/dialogue/GruvaPatrullDialogue.kt @@ -0,0 +1,34 @@ +package content.region.fremennik.jatizso.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs +import core.tools.END_DIALOGUE + +@Initializable +class GruvaPatrullDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player?): DialoguePlugin { + return GruvaPatrullDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npcl(FacialExpression.FRIENDLY,"Ho! Outerlander.") + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> playerl(FacialExpression.HALF_ASKING, "What's down the scary-looking staircase?").also { stage++ } + 1 -> npcl(FacialExpression.NEUTRAL, "These are the stairs down to the mining caves. There are rich veins of many types down there, and miners too. Though be careful; some of the trolls occasionally sneak into the far end of the cave.").also { stage++ } + 2 -> playerl(FacialExpression.NEUTRAL, "Thanks. I'll look out for them.").also { stage = END_DIALOGUE } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.GRUVA_PATRULL_5500) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/jatizso/dialogue/HringHringDialogue.kt b/Server/src/main/content/region/fremennik/jatizso/dialogue/HringHringDialogue.kt new file mode 100644 index 0000000..b7c7a58 --- /dev/null +++ b/Server/src/main/content/region/fremennik/jatizso/dialogue/HringHringDialogue.kt @@ -0,0 +1,55 @@ +package content.region.fremennik.jatizso.dialogue + +import core.api.openNpcShop +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class HringHringDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun newInstance(player: Player?): DialoguePlugin { + return HringHringDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npcl( + FacialExpression.FRIENDLY, + " Oh, hello again. Want some ore?" + ).also { stage = START_DIALOGUE } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> options("I'll have a look.", "Not right now.").also { stage++ } + 1 -> when (buttonId) { + 1 -> playerl( + FacialExpression.FRIENDLY, + "I'll have a look." + ).also { stage++ } + + 2 -> playerl( + FacialExpression.FRIENDLY, + "Not right now." + ).also { stage = END_DIALOGUE } + } + + 2 -> { + openNpcShop(player, NPCs.HRING_HRING_5483) + end() + } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.HRING_HRING_5483) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/jatizso/dialogue/LeftieRightieDialogue.kt b/Server/src/main/content/region/fremennik/jatizso/dialogue/LeftieRightieDialogue.kt new file mode 100644 index 0000000..b2c3b14 --- /dev/null +++ b/Server/src/main/content/region/fremennik/jatizso/dialogue/LeftieRightieDialogue.kt @@ -0,0 +1,32 @@ +package content.region.fremennik.jatizso.dialogue + +import core.api.* +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import org.rs09.consts.NPCs +import core.game.dialogue.DialogueFile +import core.tools.END_DIALOGUE + +class LeftieRightieDialogue() : DialogueFile() { + val rightie = NPCs.GUARD_5491 + val leftie = NPC(NPCs.GUARD_5492) + override fun handle(componentID: Int, buttonID: Int) { + when(stage){ + 0 -> npcl(FacialExpression.NEUTRAL, "Are you all right? Leftie?").also { stage++ } + 1 -> npc2("No, I'm on the left.").also { stage++ } + 2 -> npcl(FacialExpression.NEUTRAL, "Only from your perspective. Someone entering the gate should call you Rightie, right Leftie?").also { stage++ } + 3 -> npc2("Right, Rightie. So you'd be Leftie not Rightie, right?").also { stage++ } + 4 -> npcl(FacialExpression.NEUTRAL, "That's right Leftie, that's right.").also { stage++ } + 5 -> npc2("Rightie-oh Rightie, or should I call you Leftie?").also { stage++ } + 6 -> npcl(FacialExpression.NEUTRAL, "No, Rightie's fine Leftie.").also { stage++ } + 7 -> playerl(FacialExpression.ANGRY, "Aaagh! Enough! If either of you mention left or right in my presence I'll have to scream! Can I come through the gate?" ).also { stage++ } + 8 -> npc2("Don't let us stop you.").also { stage++ } + 9 -> npcl(FacialExpression.NEUTRAL, "Yes, head right on in, sir.").also { stage++ } + 10 -> playerl(FacialExpression.ANGRY, "You said it! You said it! ARRRRRRRRGH!").also { stage = END_DIALOGUE } + } + } + + fun npc2(messages: String){ + sendNormalDialogue(leftie, FacialExpression.NEUTRAL, *splitLines(messages)) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/jatizso/dialogue/MinerDialogue.kt b/Server/src/main/content/region/fremennik/jatizso/dialogue/MinerDialogue.kt new file mode 100644 index 0000000..8a92123 --- /dev/null +++ b/Server/src/main/content/region/fremennik/jatizso/dialogue/MinerDialogue.kt @@ -0,0 +1,61 @@ +package content.region.fremennik.jatizso.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs +import core.tools.END_DIALOGUE + +@Initializable +class MinerDialogue(player: Player? = null) : DialoguePlugin(player) { + val stages = intArrayOf(0, 100, 200, 300, 400, 500) + override fun newInstance(player: Player?): DialoguePlugin { + return MinerDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + stage = stages.random() + handle(0,0) + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> npcl(FacialExpression.SAD, "I've been here for two days straight. When I close my eyes, I see rocks.").also { stage++ } + 1 -> playerl(FacialExpression.HALF_ASKING, "Why would anyone stay here for so long?").also { stage++ } + 2 -> npcl(FacialExpression.NEUTRAL, "I fear the outside. I fear the big light.").also { stage++ } + 3 -> playerl(FacialExpression.HALF_GUILTY, "Oh dear. Being underground for so long may have driven you mad.").also { stage = END_DIALOGUE } + + 100 -> npcl(FacialExpression.NEUTRAL, "My back is killing me!").also { stage++ } + 101 -> playerl(FacialExpression.HALF_GUILTY, "Could be worse, it could be the trolls killing you." ).also { stage++ } + 102 -> npcl(FacialExpression.NEUTRAL, "How very droll.").also { stage++ } + 103 -> playerl(FacialExpression.NEUTRAL, "No, troll.").also { stage++ } + 104 -> npcl(FacialExpression.SAD, "Bah! I resist your attempts at jollity.").also { stage = END_DIALOGUE } + + 200 -> npcl(FacialExpression.SCARED, "Gah! Trolls everywhere. There's no escape!").also { stage++ } + 201 -> playerl(FacialExpression.HALF_THINKING, "You could just leave the mine.").also { stage++ } + 202 -> npcl(FacialExpression.NEUTRAL, "Oh, I'd never thought of that.").also { stage = END_DIALOGUE } + + 300 -> playerl(FacialExpression.HALF_ASKING, "How's your prospecting going?").also { stage++ } + 301 -> npcl(FacialExpression.LAUGH, "Mine's been going pretty well.").also { stage++ } + 302 -> playerl(FacialExpression.HALF_THINKING, "...").also { stage++ } + 303 -> npcl(FacialExpression.LAUGH, "Mine? Mine...you get it?").also { stage++ } + 304 -> playerl(FacialExpression.HALF_THINKING, "Oh, I got it. That doesn't make it funny though.").also { stage++ } + 305 -> npcl(FacialExpression.NEUTRAL, "Suit yourself.").also { stage = END_DIALOGUE } + + 400 -> npcl(FacialExpression.NEUTRAL, "High hoe, High hoe!").also { stage++ } + 401 -> playerl(FacialExpression.ASKING, "Why are you singing about farming implements at altitude?").also { stage++ } + 402 -> npcl(FacialExpression.NEUTRAL, "I don't know, I've never thought about it. Ask my Dad, he taught me the song.").also { stage = END_DIALOGUE } + + 500 -> npcl(FacialExpression.NEUTRAL, "This place rocks!").also { stage++ } + 501 -> playerl(FacialExpression.HALF_THINKING, "No it doesn't, it stays perfectly still.").also { stage++ } + 502 -> npcl(FacialExpression.HALF_THINKING, "Bah! Be quiet, pedant." ).also { stage = END_DIALOGUE } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.MINER_5497, NPCs.MINER_5498) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/jatizso/dialogue/MordGunnarsDialogue.kt b/Server/src/main/content/region/fremennik/jatizso/dialogue/MordGunnarsDialogue.kt new file mode 100644 index 0000000..e4ed6b6 --- /dev/null +++ b/Server/src/main/content/region/fremennik/jatizso/dialogue/MordGunnarsDialogue.kt @@ -0,0 +1,51 @@ +package content.region.fremennik.jatizso.dialogue + +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs +import content.region.fremennik.rellekka.handlers.RellekkaDestination +import content.region.fremennik.rellekka.handlers.RellekkaUtils +import core.tools.END_DIALOGUE +import core.api.* +import content.data.Quests + +@Initializable +class MordGunnarsDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin(player) { + override fun newInstance(player: Player?): core.game.dialogue.DialoguePlugin { + return MordGunnarsDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + if(npc.id == NPCs.MORD_GUNNARS_5481){ + npcl(core.game.dialogue.FacialExpression.FRIENDLY, "Would you like to sail to Jatizso?") + } else { + npcl(core.game.dialogue.FacialExpression.FRIENDLY, "Would you like to sail back to Rellekka?") + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> options("Yes, please.", "No, thanks.").also { stage++ } + 1 -> when(buttonId){ + 1 -> playerl(core.game.dialogue.FacialExpression.FRIENDLY, "Yes, please!").also { stage++ } + 2 -> playerl(core.game.dialogue.FacialExpression.FRIENDLY, "No, thank you.").also { stage = END_DIALOGUE } + } + + 2 -> { + end() + if (!hasRequirement(player, Quests.THE_FREMENNIK_TRIALS)) + return true + RellekkaUtils.sail(player, if(npc.id == NPCs.MORD_GUNNARS_5481) RellekkaDestination.RELLEKKA_TO_JATIZSO else RellekkaDestination.JATIZSO_TO_RELLEKKA) + } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.MORD_GUNNARS_5482, NPCs.MORD_GUNNARS_5481) + } + +} diff --git a/Server/src/main/content/region/fremennik/jatizso/dialogue/TowerGuardDialogue.kt b/Server/src/main/content/region/fremennik/jatizso/dialogue/TowerGuardDialogue.kt new file mode 100644 index 0000000..1840513 --- /dev/null +++ b/Server/src/main/content/region/fremennik/jatizso/dialogue/TowerGuardDialogue.kt @@ -0,0 +1,50 @@ +package content.region.fremennik.jatizso.dialogue + +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs +import core.game.interaction.IntType +import core.game.interaction.InteractionListeners +import core.tools.END_DIALOGUE + +@Initializable +class TowerGuardDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin(player) { + override fun newInstance(player: Player?): core.game.dialogue.DialoguePlugin { + return TowerGuardDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + playerl(core.game.dialogue.FacialExpression.HALF_ASKING, "What are you doing here?") + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> npc(core.game.dialogue.FacialExpression.NEUTRAL, "I'M ON SHOUTING DUTY!").also { stage++ } + 1 -> playerl(core.game.dialogue.FacialExpression.HALF_THINKING, "No need to shout.").also { stage++ } + 2 -> npc(core.game.dialogue.FacialExpression.NEUTRAL, "I'M SORRY I'VE BEEN SHOUTING","INSULTS SO LONG I CAN'T HELP IT!").also { stage++ } + 3 -> playerl(core.game.dialogue.FacialExpression.HALF_THINKING, "Who are you insulting?").also { stage++ } + 4 -> npc(core.game.dialogue.FacialExpression.NEUTRAL, "THE TOWER IN ${if(npc.id == NPCs.GUARD_5489) "NEITIZNOT" else "JATIZSO"}.","THEY SHOUT INSULTS BACK.").also { stage++ } + 5 -> playerl(core.game.dialogue.FacialExpression.ASKING, "Err, why?" ).also { stage++ } + 6 -> npc(core.game.dialogue.FacialExpression.NEUTRAL, "THE ${if(npc.id == NPCs.GUARD_5489) "KING" else "BURGHER"} TELLS US TO.").also { stage++ } + 7 -> playerl(core.game.dialogue.FacialExpression.HALF_THINKING, "Your ${if(npc.id == NPCs.GUARD_5489) "King" else "Burgher"} is a strange person.").also { stage++ } + 8 -> options("Can I watch? I'm curious.", "Oh well, I'd better get going.").also { stage++ } + 9 -> when(buttonId){ + 1 -> playerl(core.game.dialogue.FacialExpression.ASKING, "Can I watch? I'm curious.").also { stage++ } + 2 -> playerl(core.game.dialogue.FacialExpression.HALF_THINKING, "Oh well, I'd better get going.").also { stage = END_DIALOGUE } + } + 10 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "IF YOU LIKE!").also { + stage = END_DIALOGUE + InteractionListeners.run(NPCs.GUARD_5489, IntType.NPC, "watch-shouting", player, npc) + } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.GUARD_5489, NPCs.GUARD_5490) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/jatizso/handlers/IceTrollJatizsoCaves.kt b/Server/src/main/content/region/fremennik/jatizso/handlers/IceTrollJatizsoCaves.kt new file mode 100644 index 0000000..99820f6 --- /dev/null +++ b/Server/src/main/content/region/fremennik/jatizso/handlers/IceTrollJatizsoCaves.kt @@ -0,0 +1,32 @@ +package content.region.fremennik.jatizso.handlers + +import core.api.* +import core.game.node.entity.npc.AbstractNPC +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class IceTrollJatizsoCaves : AbstractNPC { + //Constructor spaghetti because Arios I guess + constructor() : super(NPCs.ICE_TROLL_MALE_5474, null, true) {} + private constructor(id: Int, location: Location) : super(id, location) {} + + override fun construct(id: Int, location: Location, vararg objects: Any?): AbstractNPC { + return IceTrollJatizsoCaves(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.ICE_TROLL_MALE_5474,NPCs.ICE_TROLL_RUNT_5473,NPCs.ICE_TROLL_FEMALE_5475) + } + + override fun tick() { + val nearbyMiner = findLocalNPC(this, NPCs.MINER_5497) ?: return super.tick() + if(!inCombat() && nearbyMiner.location.withinDistance(location, 8)){ + attack(nearbyMiner) + } + super.tick() + } + + +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/jatizso/handlers/JatizsoListeners.kt b/Server/src/main/content/region/fremennik/jatizso/handlers/JatizsoListeners.kt new file mode 100644 index 0000000..65824ab --- /dev/null +++ b/Server/src/main/content/region/fremennik/jatizso/handlers/JatizsoListeners.kt @@ -0,0 +1,153 @@ +package content.region.fremennik.jatizso.handlers + +import core.api.* +import core.game.node.entity.npc.NPC +import core.game.system.task.Pulse +import core.game.world.map.Direction +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import org.rs09.consts.NPCs +import content.region.fremennik.jatizso.dialogue.LeftieRightieDialogue +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import org.rs09.consts.Sounds + +class JatizsoListeners : InteractionListener { + val GATES_CLOSED = intArrayOf(21403,21405) + val NORTH_GATE_ZONE = ZoneBorders(2414,3822,2417,3825) + val WEST_GATE_ZONE = ZoneBorders(2386,3797,2390,3801) + val SOUTH_GAE_ZONE = ZoneBorders(2411,3795,2414,3799) + val BELL = 21394 + val TOWER_GUARDS = intArrayOf(NPCs.GUARD_5490, NPCs.GUARD_5489) + val GUARDS = intArrayOf(NPCs.GUARD_5491, NPCs.GUARD_5492) + val KING_CHEST = intArrayOf(21299,21300) + val LINES = arrayOf( + arrayOf( + "YOU WOULDN'T KNOW HOW TO FIGHT A TROLL IF IT CAME UP AND BIT YER ARM OFF", + "YAK LOVERS", + "CALL THAT A TOWN? I'VE SEEN BETTER HAMLETS!", + "AND YOUR FATHER SMELLED OF WINTERBERRIES!", + "WOODEN BRIDGES ARE RUBBISH!", + "OUR KING'S BETTER THAN YOUR BURGHER!", + ), + arrayOf( + "YOU WOULDN'T KNOW HOW TO SHAVE A YAK IF YOUR LIFE DEPENDED ON IT", + "MISERABLE LOSERS", + "YOUR MOTHER WAS A HAMSTER!", + "AT LEAST WE HAVE SOMETHING OTHER THAN SMELLY FISH!", + "AT LEAST WE CAN COOK!", + ) + ) + override fun defineListeners() { + on(GATES_CLOSED, IntType.SCENERY, "open"){ player, node -> + if(NORTH_GATE_ZONE.insideBorder(player)){ + if(node.id == GATES_CLOSED.first()){ + val other = getScenery(node.location.transform(1, 0, 0)) ?: return@on true + replaceScenery(node.asScenery(), node.id + 1, -1, Direction.EAST) + replaceScenery(other.asScenery(), other.id - 1, -1, Direction.NORTH_EAST) + } else { + val other = getScenery(node.location.transform(-1, 0, 0)) ?: return@on true + replaceScenery(node.asScenery(), node.id + 1, -1, Direction.NORTH_EAST) + replaceScenery(other.asScenery(), other.id, -1, Direction.EAST) + } + } else if(WEST_GATE_ZONE.insideBorder(player)){ + if(node.id == GATES_CLOSED.first()){ + val other = getScenery(node.location.transform(0, 1, 0)) ?: return@on true + replaceScenery(node.asScenery(), node.id + 1, -1, Direction.WEST) + replaceScenery(other.asScenery(), other.id + 1, -1, Direction.NORTH) + } else { + val other = getScenery(node.location.transform(0, -1, 0)) ?: return@on true + replaceScenery(node.asScenery(), node.id + 1, -1, Direction.NORTH) + replaceScenery(other.asScenery(), other.id + 1, -1, Direction.WEST) + } + } else if(SOUTH_GAE_ZONE.insideBorder(player)){ + if(node.id == GATES_CLOSED.first()){ + val other = getScenery(node.location.transform(-1, 0, 0)) ?: return@on true + replaceScenery(node.asScenery(), node.id + 1, -1, Direction.SOUTH) + replaceScenery(other.asScenery(), other.id - 1, -1, Direction.EAST) + } else { + val other = getScenery(node.location.transform(1, 0, 0)) ?: return@on true + replaceScenery(node.asScenery(), node.id + 1, -1, Direction.EAST) + replaceScenery(other.asScenery(), other.id, -1, Direction.SOUTH) + } + } + playAudio(player, Sounds.NICEDOOR_OPEN_81) + return@on true + } + + on(TOWER_GUARDS, IntType.NPC, "watch-shouting"){ player, _ -> + val local = findLocalNPC(player, NPCs.GUARD_5489) + lock(player, 200) + face(local!!, Location.create(2371, 3801, 2)) + local.asNpc().isRespawn = false + submitIndividualPulse(player, object : Pulse(4){ + var id = NPCs.GUARD_5489 + var counter = 0 + val other = findLocalNPC(player, getOther(NPCs.GUARD_5489)) + + override fun start() { + other?.isRespawn = false + } + + override fun pulse(): Boolean { + val npc = findLocalNPC(player, id) ?: return false + val index = when(id){ + NPCs.GUARD_5489 -> 0 + else -> 1 + } + if(index == 1 && counter == 5) return true + sendChat(npc, LINES[index][counter]) + if(npc.id != NPCs.GUARD_5489) counter++ + id = getOther(id) + return false + } + + override fun stop() { + unlock(player) + other?.isRespawn = true + local.asNpc().isRespawn = true + super.stop() + } + + fun getOther(npc: Int): Int{ + return when(npc){ + NPCs.GUARD_5489 -> NPCs.GUARD_5490 + NPCs.GUARD_5490 -> NPCs.GUARD_5489 + else -> NPCs.GUARD_5489 + } + } + }) + return@on true + } + + on(BELL, IntType.SCENERY, "ring-bell"){ player, _ -> + playAudio(player, Sounds.STEEL_15) + sendMessage(player, "You ring the warning bell, but everyone ignores it!") + return@on true + } + + on(GUARDS, IntType.NPC, "talk-to"){ player, node -> + player.dialogueInterpreter.open(LeftieRightieDialogue(), NPC(NPCs.GUARD_5491)) + return@on true + } + + on(KING_CHEST, IntType.SCENERY, "open"){ player, node -> + sendPlayerDialogue(player, "I probably shouldn't mess with that.", core.game.dialogue.FacialExpression.HALF_THINKING) + return@on true + } + + setDest(IntType.NPC, NPCs.MAGNUS_GRAM_5488){ _, _ -> + return@setDest Location.create(2416, 3801, 0) + } + + //Climb handling for the ladders in the towers around the city walls. + addClimbDest(Location.create(2388, 3804, 0),Location.create(2387, 3804, 2)) + addClimbDest(Location.create(2388, 3804, 2),Location.create(2387, 3804, 0)) + addClimbDest(Location.create(2388, 3793, 0),Location.create(2387, 3793, 2)) + addClimbDest(Location.create(2388, 3793, 2),Location.create(2387, 3793, 0)) + addClimbDest(Location.create(2410, 3823, 0),Location.create(2410, 3824, 2)) + addClimbDest(Location.create(2410, 3823, 2),Location.create(2410, 3824, 0)) + addClimbDest(Location.create(2421, 3823, 0),Location.create(2421, 3824, 2)) + addClimbDest(Location.create(2421, 3823, 2),Location.create(2421, 3824, 0)) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/lunarisle/dialogue/BabaYagaDialogue.kt b/Server/src/main/content/region/fremennik/lunarisle/dialogue/BabaYagaDialogue.kt new file mode 100644 index 0000000..b597ce4 --- /dev/null +++ b/Server/src/main/content/region/fremennik/lunarisle/dialogue/BabaYagaDialogue.kt @@ -0,0 +1,55 @@ +package content.region.fremennik.lunarisle.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + * Does not include Lunar Diplomacy dialogue + */ + +@Initializable +class BabaYagaDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + player(FacialExpression.FRIENDLY,"Hello there.").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> npc(FacialExpression.ASKING, "Ah, a stranger to our island. How can I help?").also { stage ++ } + 1 -> options("Have you got anything to trade?", "It's a very interesting house you have here.", "I'm good thanks, bye.").also { stage ++ } + + 2 -> when(buttonId) { + 1 -> end().also { npc.openShop(player) } + 2 -> playerl(FacialExpression.ASKING, "It's a very interesting house you have here. Does he have a name?").also { stage = 10 } + 3 -> end() + } + + 10 -> npc(FacialExpression.FRIENDLY, "Why of course. It's Berty.").also { stage++ } + 11 -> player(FacialExpression.THINKING, "Berty? Berty the Chicken leg house?").also { stage++ } + 12 -> npc(FacialExpression.LAUGH, "Yes.").also { stage++ } + 13 -> player(FacialExpression.ASKING, "May I ask why?").also { stage++ } + 14 -> npcl(FacialExpression.LAUGH, "It just has that certain ring to it, don't you think? Beeerteeee!").also { stage++ } + 15 -> player(FacialExpression.HALF_WORRIED, "You're ins...").also { stage++ } + 16 -> npc("Insane? Very.").also { stage = 99 } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return BabaYagaDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.BABA_YAGA_4513) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/lunarisle/dialogue/BouquetMacHyacinthDialogue.kt b/Server/src/main/content/region/fremennik/lunarisle/dialogue/BouquetMacHyacinthDialogue.kt new file mode 100644 index 0000000..29f0632 --- /dev/null +++ b/Server/src/main/content/region/fremennik/lunarisle/dialogue/BouquetMacHyacinthDialogue.kt @@ -0,0 +1,77 @@ +package content.region.fremennik.lunarisle.dialogue + +import core.api.teleport +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.TeleportManager +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import java.util.concurrent.Executors +import java.util.concurrent.TimeUnit + +/** + * @author qmqz + */ + +@Initializable +class BouquetMacHyacinthDialogue(player: Player? = null) : DialoguePlugin(player){ + + private val Rellekka = Location.create(2663, 3644, 0) + private var teled = false + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + + if (!teled) { + if (player.inventory.contains(Items.SEAL_OF_PASSAGE_9083, 1) || player.equipment.contains(Items.SEAL_OF_PASSAGE_9083, 1)) { + player(FacialExpression.FRIENDLY, "Hi! What are you up to?").also { stage = 0 } + } else { + player(FacialExpression.FRIENDLY, "Hi, I...").also { stage = 5 } + } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> npc(FacialExpression.FRIENDLY,"Watering the pretty flowers, you want to help?").also { stage++ } + 1 -> playerl(FacialExpression.HALF_WORRIED, "I don't have time to water flowers, I have people to save!").also { stage++ } + 2 -> npcl(FacialExpression.NEUTRAL, "Pft, you should take time to enjoy the simple things.").also { stage++ } + 3 -> player(FacialExpression.NEUTRAL, "I'm not a simple person.").also { stage++ } + 4 -> npc(FacialExpression.LAUGH, "So it seems.").also { stage = 99 } + + 5 -> npc(FacialExpression.ANNOYED, "What are you doing here, Fremennik?!").also { stage++ } + 6 -> player(FacialExpression.WORRIED, "I have a seal of pass...").also { stage++ } + 7 -> npc(FacialExpression.ANNOYED, "No you do not! Begone!").also { stage++ } + 8 -> teleport(player, Rellekka, TeleportManager.TeleportType.LUNAR).also { wait1() } + + 99 -> end() + } + return true + } + + private fun wait1() { + Executors.newSingleThreadScheduledExecutor().schedule({ + if (player.location.isInRegion(Rellekka.regionId)) { + playerl( + FacialExpression.WORRIED, + "Ooops. Suppose I need a seal of passage when I'm walking around that island." + ).also { end() } + } else { + wait1() + } + }, 1, TimeUnit.SECONDS) + } + + override fun newInstance(player: Player?): DialoguePlugin { + return BouquetMacHyacinthDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.BOUQUET_MAC_HYACINTH_4526) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/lunarisle/dialogue/CabinBoyDialogue.kt b/Server/src/main/content/region/fremennik/lunarisle/dialogue/CabinBoyDialogue.kt new file mode 100644 index 0000000..4ce80ae --- /dev/null +++ b/Server/src/main/content/region/fremennik/lunarisle/dialogue/CabinBoyDialogue.kt @@ -0,0 +1,72 @@ +package content.region.fremennik.lunarisle.dialogue + +import core.api.addItemOrDrop +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +/** + * @author qmqz + * Must have Lunar Diplomacy completed for the emerald lens + */ + +@Initializable +class CabinBoyDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + + if (player.inventory.contains(Items.EMERALD_LENS_9066, 1) || player.bank.contains(Items.EMERALD_LENS_9066, 1)) { + playerl(FacialExpression.FRIENDLY, "So you've plucked up the courage to come and confront that girl!").also { stage = 0 } + } else { + player(FacialExpression.FRIENDLY, "Hi.").also { stage = 20 } + } + + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> npc(FacialExpression.CHILD_FRIENDLY, "That I did, that I did!").also { stage++ } + 1 -> player(FacialExpression.ASKING, "And?").also { stage++ } + 2 -> npcl(FacialExpression.CHILD_FRIENDLY, "She turned out to be really nice! She's joining us to become a pirate!").also { stage++ } + 3 -> playerl(FacialExpression.HALF_WORRIED, "Really? And you're not sceptical about this? You know, after what she did last time?").also { stage++ } + 4 -> npc(FacialExpression.CHILD_SUSPICIOUS, "She---has---no---spell---on---me.").also { stage++ } + 5 -> player(FacialExpression.HALF_THINKING, "Huh? Why are you talking like that?").also { stage++ } + 6 -> npc(FacialExpression.CHILD_THINKING, "Like what?").also { stage++ } + 7 -> playerl(FacialExpression.HALF_ASKING, "Like someone else was talking for you. Are you sure she hasn't put a spell on you again? Did she wave a watch in front of your face? You know, tell you to look deep into her eyes?").also { stage++ } + 8 -> npc(FacialExpression.CHILD_SUSPICIOUS, "She---has---no---spell---on---me.").also { stage++ } + 9 -> playerl(FacialExpression.HALF_THINKING, "I think you've been hypnotised. I wonder what happens if I click my fingers?").also { + player.sendChat("*click*").also { stage++ } + } + 10 -> npc(FacialExpression.CHILD_SAD, "*Cluck* *cluck* *bwaarrk*").also { stage++ } + 11 -> npc(FacialExpression.CHILD_SAD, "").also { stage++ } + 12 -> player(FacialExpression.WORRIED, "Oh dear. Oh well, I'm sure you'll learn one day.").also { stage = 99 } + + 20 -> npc(FacialExpression.CHILD_FRIENDLY, "I bet you're after another lens!").also { stage++ } + 21 -> player(FacialExpression.HALF_THINKING, "How could you possibly know that?").also { stage++ } + 22 -> npcl(FacialExpression.CHILD_FRIENDLY, "Hey, I think I'm learning a thing or two from these Moon Clan ladies.").also { stage++ } + 23 -> options("Please", "No thanks").also { stage++ } + 24 -> when (buttonId) { + 1 -> player(FacialExpression.HALF_ASKING, "Oi! I need another lens, boy.").also { stage = 25} + 2 -> player(FacialExpression.SUSPICIOUS, "I think I'll pass. But thanks..").also { stage = 99 } + } + 25 -> npc(FacialExpression.CHILD_FRIENDLY, "Huh, oh ok, I suppose I owe you one.").also { addItemOrDrop(player, Items.EMERALD_LENS_9066, 1) }.also { stage = 99 } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return CabinBoyDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.CABIN_BOY_4539) + } +} diff --git a/Server/src/main/content/region/fremennik/lunarisle/dialogue/MelenaMoonlanderDialogue.kt b/Server/src/main/content/region/fremennik/lunarisle/dialogue/MelenaMoonlanderDialogue.kt new file mode 100644 index 0000000..4992dbf --- /dev/null +++ b/Server/src/main/content/region/fremennik/lunarisle/dialogue/MelenaMoonlanderDialogue.kt @@ -0,0 +1,64 @@ +package content.region.fremennik.lunarisle.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class MelenaMoonlanderDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + player(FacialExpression.FRIENDLY,"Hello there.").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> npcl(FacialExpression.FRIENDLY, "Hi. Welcome to the general store. How might I help you?").also { stage++ } + + 1 -> options("What can you sell me?", "I have a question...", "I'm good thanks, bye.").also { stage++ } + + 2 -> when (buttonId) { + 1 -> end().also { npc.openShop(player) } + 2 -> player(FacialExpression.HALF_ASKING, "I have a question...").also { stage = 11 } + 3 -> player(FacialExpression.FRIENDLY, "I'm good thanks, bye.").also { stage = 99 } + } + + 11 -> npc(FacialExpression.FRIENDLY, "About magic of course.").also { stage++ } + 12 -> player(FacialExpression.SUSPICIOUS, "Sorry?").also { stage++ } + 13 -> npcl(FacialExpression.FRIENDLY, "I said about magic of course. You know, in response to your question.").also { stage++ } + 14 -> player(FacialExpression.HALF_THINKING, "But I didn't ask anything yet.").also { stage++ } + 15 -> npcl(FacialExpression.FRIENDLY, "Yes, but you were thinking of asking me how I was floating.").also { stage++ } + 16 -> player(FacialExpression.AMAZED, "That's true! How could you possibly know that?").also { stage++ } + 17 -> npc(FacialExpression.HALF_THINKING, "Don't you realise we can read your mind.").also { stage++ } + 18 -> player(FacialExpression.SUSPICIOUS, "Oh, of course. How do you manage to do that?").also { stage++ } + 19 -> npcl(FacialExpression.FRIENDLY, "It's quite simple, everyone has a resonance that is responded to by the moon. This resonance changes depending on what we are thinking. You can tune yourself in to listen to this").also { stage++ } + 20 -> npcl(FacialExpression.FRIENDLY, "resonance with practice - it's a life long quest for the members of the Moon Clan, but its especially easy to read with outsiders like yourself,").also { stage++ } + 21 -> npc(FacialExpression.FRIENDLY, "as you are far louder and unguarded.").also { stage++ } + 22 -> player(FacialExpression.SUSPICIOUS, "I see. I best be careful what I think of then.").also { stage++ } + 23 -> player(FacialExpression.WORRIED, "...").also { stage++ } + 24 -> player(FacialExpression.THINKING, "...").also { stage++ } + 25 -> npc(FacialExpression.DISGUSTED_HEAD_SHAKE, "That's disgusting!").also { stage++ } + 26 -> player(FacialExpression.SAD, "Sorry.").also { stage = 99 } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return MelenaMoonlanderDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.MELANA_MOONLANDER_4516) + } +} diff --git a/Server/src/main/content/region/fremennik/lunarisle/dialogue/PaulinePolarisDialogue.kt b/Server/src/main/content/region/fremennik/lunarisle/dialogue/PaulinePolarisDialogue.kt new file mode 100644 index 0000000..a0ede38 --- /dev/null +++ b/Server/src/main/content/region/fremennik/lunarisle/dialogue/PaulinePolarisDialogue.kt @@ -0,0 +1,48 @@ +package content.region.fremennik.lunarisle.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + * Does not include Lunar Diplomacy dialogue + */ + +@Initializable +class PaulinePolarisDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + player(FacialExpression.FRIENDLY,"Hello there.").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> npc(FacialExpression.ASKING, "Ah, a stranger to our island. How can I help?").also { stage ++ } + 1 -> playerl(FacialExpression.FRIENDLY, "Well, I've actually come here on a diplomatic mission. I want to try and settle some of the disputes between the Fremenniks and your clan.").also { stage++ } + 2 -> npcl(FacialExpression.FRIENDLY, "The Rremenniks? Pah! They are just too ignorant and stubborn to listen to anything we have to say - how can we possibly associate with a race that won't listen?").also { stage++ } + 3 -> playerl(FacialExpression.FRIENDLY, "I think they are very eager to listen, but they feel like you are keeping secrets from them.").also { stage++ } + 4 -> npc(FacialExpression.HALF_THINKING, "Secrets?").also { stage++ } + 5 -> playerl(FacialExpression.HALF_ASKING, "Yes, as in your magic ways. To be honest, I think it is fear of the unknown.").also { stage++ } + 6 -> npcl(FacialExpression.FRIENDLY, "Well, when the day comes that a Fremennik can prove they have the patience and interest in learning our ways, then we will perhaps share our secrets.").also { stage++ } + 7 -> player(FacialExpression.FRIENDLY, "I'm hoping I might be able to achieve that.").also { stage++ } + 8 -> npc(FacialExpression.FRIENDLY, "Good luck. It's far from simple.").also { stage = 99 } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return PaulinePolarisDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.PAULINE_POLARIS_4514) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/lunarisle/dialogue/RimaeSirsalisDialogue.kt b/Server/src/main/content/region/fremennik/lunarisle/dialogue/RimaeSirsalisDialogue.kt new file mode 100644 index 0000000..6046a79 --- /dev/null +++ b/Server/src/main/content/region/fremennik/lunarisle/dialogue/RimaeSirsalisDialogue.kt @@ -0,0 +1,62 @@ +package content.region.fremennik.lunarisle.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class RimaeSirsalisDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + player(FacialExpression.FRIENDLY,"Hello there.").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> options("What can you sell me?", "Do you have any use for suqah teeth or hides?", "It's a very interesting island you have here.", "I'm good thanks, bye.").also { stage++ } + + 1 -> when (buttonId) { + 1 -> end().also { npc.openShop(player) } + 2 -> player(FacialExpression.HALF_ASKING, "Do you have any use for suqah teeth or hides?").also { stage = 5 } + 3 -> npcl(FacialExpression.FRIENDLY, "Why thank you. It's been our haven for a great many generations.").also { stage = 10 } + 4 -> player(FacialExpression.FRIENDLY, "I'm good thanks, bye.").also { stage = 99 } + } + + 5 -> npcl(FacialExpression.FRIENDLY, "Most certainly! The hides are great for making clothes and the teeth are particularly useful for broaches, necklaces and the like. But I won't accept them from anyone.").also { stage = 99 } + + 10 -> playerl(FacialExpression.FRIENDLY, "Everything seems to have a magical feel to it.").also { stage++ } + 11 -> npcl(FacialExpression.FRIENDLY, "Of course. We integrate magic into all areas of our lives. It is a part of everyone, so why deny it? It's best to make the most of this innate gift we have all been given.").also { stage++ } + 12 -> player(FacialExpression.FRIENDLY, "What sort of things do you use your magic for?").also { stage++ } + 13 -> npcl(FacialExpression.FRIENDLY, "Take a look around. We use it in our day to day lives, from making a cup of tea to travelling around the island.").also { stage++ } + 14 -> npcl(FacialExpression.FRIENDLY, "You see our ancestors were the ones that found the first rune essence and put it to use! The various factions were eventually created,").also { stage++ } + 15 -> npcl(FacialExpression.FRIENDLY, "with people having different ideas on how the essence should be used (or not in some cases!)").also { stage++ } + 16 -> player(FacialExpression.FRIENDLY, "What has kept you so secluded on this island?").also { stage++ } + 17 -> npcl(FacialExpression.FRIENDLY, "It may be a bit beyond you, but although magic comes from within, we are all strongly linked to the moon and the").also { stage++ } + 18 -> npc(FacialExpression.FRIENDLY, "effects it has on us cannot be denied!").also { stage++ } + 19 -> player(FacialExpression.FRIENDLY, "It can't?").also { stage++ } + 20 -> npcl(FacialExpression.FRIENDLY, "Of course not. This very island has a great link to our moon, which helps us understand ourselves - especially our dreams,").also { stage++ } + 21 -> npc(FacialExpression.FRIENDLY, "which is the path to understanding magic.").also { stage++ } + 22 -> playerl(FacialExpression.FRIENDLY, "I think I will just have to take your word on that.").also { stage = 99 } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return RimaeSirsalisDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.RIMAE_SIRSALIS_4518) + } +} diff --git a/Server/src/main/content/region/fremennik/lunarisle/dialogue/SeleneDialog.kt b/Server/src/main/content/region/fremennik/lunarisle/dialogue/SeleneDialog.kt new file mode 100644 index 0000000..8e0f00f --- /dev/null +++ b/Server/src/main/content/region/fremennik/lunarisle/dialogue/SeleneDialog.kt @@ -0,0 +1,79 @@ +package content.region.fremennik.lunarisle.dialogue + +import core.api.teleport +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.TeleportManager +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import java.util.concurrent.Executors +import java.util.concurrent.TimeUnit + +/** + * @author qmqz + */ + +@Initializable +class SeleneDialog(player: Player? = null) : DialoguePlugin(player){ + + private val Rellekka = Location.create(2663, 3644, 0) + private var teled = false + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + + if (!teled) { + if (player.inventory.contains(Items.SEAL_OF_PASSAGE_9083, 1) || player.equipment.contains(Items.SEAL_OF_PASSAGE_9083, 1)) { + player(FacialExpression.FRIENDLY, "Can you tell me a bit about your people?").also { stage = 0; } + } else { + player(FacialExpression.FRIENDLY, "Hi, I...").also { stage = 10 } + } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> npc(FacialExpression.FRIENDLY,"Ok. Like what?").also { stage++ } + 1 -> player(FacialExpression.HALF_ASKING, "How about the values of the Moon clan!").also { stage++ } + 2 -> npcl(FacialExpression.NEUTRAL, "Let me see... We value knowledge of self because it is this that gives us our strength! It is most important!").also { stage++ } + 3 -> playerl(FacialExpression.FRIENDLY, "Well... I know things about myself. I know I like hot chocolate!").also { stage++ } + 4 -> npcl(FacialExpression.LAUGH, "I was meaning something a little deeper than that. We also like to see someone listen. You know how they say a wise man listens?").also { stage++ } + 5 -> player(FacialExpression.HALF_WORRIED, "....").also { stage++ } + 6 -> npc(FacialExpression.HALF_WORRIED, "Did you hear me?").also { stage++ } + 7 -> player(FacialExpression.HALF_WORRIED, ".... I'm listening.").also { stage++ } + 8 -> npc(FacialExpression.HALF_WORRIED, "Most wise.").also { stage++ } + 9 -> player(FacialExpression.HALF_WORRIED, "Huh?").also { stage = 99 } + + 10 -> npc(FacialExpression.ANNOYED, "What are you doing here, Fremennik?!").also { stage++ } + 11 -> player(FacialExpression.WORRIED, "I have a seal of pass...").also { stage++ } + 12 -> npc(FacialExpression.ANNOYED, "No you do not! Begone!").also { stage++ } + 13 -> teleport(player, Rellekka, TeleportManager.TeleportType.LUNAR).also { wait1() } + + 99 -> end() + } + return true + } + + private fun wait1() { + Executors.newSingleThreadScheduledExecutor().schedule({ + if (player.location.isInRegion(Rellekka.regionId)) { + playerl(FacialExpression.WORRIED, "Ooops. Suppose I need a seal of passage when I'm walking around that island.").also { end() } + } else { + wait1() + } + }, 1, TimeUnit.SECONDS) + } + + override fun newInstance(player: Player?): DialoguePlugin { + return SeleneDialog(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.SELENE_4517) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/lunarisle/dialogue/SirsalBankerDialogue.kt b/Server/src/main/content/region/fremennik/lunarisle/dialogue/SirsalBankerDialogue.kt new file mode 100644 index 0000000..ebe225e --- /dev/null +++ b/Server/src/main/content/region/fremennik/lunarisle/dialogue/SirsalBankerDialogue.kt @@ -0,0 +1,209 @@ +package content.region.fremennik.lunarisle.dialogue + +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.IronmanMode +import core.plugin.Initializable +import org.rs09.consts.NPCs +import core.game.dialogue.IfTopic +import core.game.dialogue.Topic +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE + +/** + * Handles Sirsal banker dialogue tree. + * + * @author vddCore + */ +@Initializable +class SirsalBankerDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + START_DIALOGUE -> if (hasSealOfPassage(player)) { + if (hasIronmanRestriction(player, IronmanMode.ULTIMATE)) { + npcl( + FacialExpression.NEUTRAL, + "My apologies, dear ${if (player.isMale) "sir" else "madam"}, " + + "our services are not available for Ultimate ${if (player.isMale) "Ironmen" else "Ironwomen"}" + ).also { stage = END_DIALOGUE } + } else { + + npcl( + FacialExpression.NEUTRAL, + "Good day, how may I help you?" + ).also { + if (hasAwaitingGrandExchangeCollections(player)) { + stage++ + } else { + stage += 2 + } + } + } + } else { + playerl(FacialExpression.HALF_WORRIED, "Hi, I...") + stage = 30 + } + + 1 -> npcl( + FacialExpression.NEUTRAL, + "Before we go any further, I should inform you that you " + + "have items ready for collection from the Grand Exchange." + ).also { stage++ } + + 2 -> showTopics( + Topic(FacialExpression.NEUTRAL, "I'd like to access my bank account, please.", 10), + IfTopic( + FacialExpression.NEUTRAL, + "I'd like to switch to my ${getBankAccountName(player, true)} bank account.", + 13, + hasActivatedSecondaryBankAccount(player) + ), + IfTopic( + FacialExpression.NEUTRAL, + "I'd like to open a secondary bank account.", + 20, + !hasActivatedSecondaryBankAccount(player) + ), + Topic(FacialExpression.NEUTRAL, "I'd like to check my PIN settings.", 11), + Topic(FacialExpression.NEUTRAL, "I'd like to collect items.", 12), + Topic(FacialExpression.ASKING, "What is this place?", 3), + ) + + 3 -> npcl( + FacialExpression.NEUTRAL, + "This is a branch of the Bank of Gielinor. We have branches in many towns." + ).also { stage++ } + + 4 -> playerl( + FacialExpression.ASKING, + "And what do you do?" + ).also { stage++ } + + 5 -> npcl( + FacialExpression.NEUTRAL, + "We will look after your items and money for you. " + + "Leave your valuables with us if you want to keep them safe." + ).also { stage = END_DIALOGUE } + + 10 -> { + openBankAccount(player) + end() + } + + 11 -> { + openBankPinSettings(player) + end() + } + + 12 -> { + openGrandExchangeCollectionBox(player) + end() + } + + 13 -> { + toggleBankAccount(player) + + npcl( + FacialExpression.NEUTRAL, + "Your active bank account has been switched. " + + "You can now access your ${getBankAccountName(player)} account." + ).also { stage = END_DIALOGUE } + } + + 20 -> npcl( + FacialExpression.NEUTRAL, + "Certainly. We offer secondary accounts to all our customers." + ).also { stage++ } + + 21 -> npcl( + FacialExpression.NEUTRAL, + "The secondary account comes with a standard fee of 5,000,000 coins. The fee is non-refundable " + + "and account activation is permanent." + ).also { stage++ } + + 22 -> npcl( + FacialExpression.NEUTRAL, + "If your inventory does not contain enough money to cover the costs, we will complement " + + "the amount with the money inside your primary bank account." + ).also { stage++ } + + 23 -> npcl( + FacialExpression.ASKING, + "Knowing all this, would you like to proceed with opening your secondary bank account?" + ).also { stage++ } + + 24 -> showTopics( + Topic(FacialExpression.NEUTRAL, "Yes, I am still interested.", 25), + Topic(FacialExpression.NEUTRAL, "Actually, I've changed my mind.", 26) + ) + + 25 -> { + when (activateSecondaryBankAccount(player)) { + SecondaryBankAccountActivationResult.ALREADY_ACTIVE -> { + npcl( + FacialExpression.NEUTRAL, + "Your bank account was already activated, there is no need to pay twice." + ).also { stage = END_DIALOGUE } + } + + SecondaryBankAccountActivationResult.INTERNAL_FAILURE -> { + npcl( + FacialExpression.NEUTRAL, + "I must apologize, the transaction was not successful. Please check your " + + "primary bank account and your inventory - if there's money missing, please " + + "screenshot your chat box and contact the game developers." + ).also { stage = END_DIALOGUE } + } + + SecondaryBankAccountActivationResult.NOT_ENOUGH_MONEY -> { + npcl( + FacialExpression.NEUTRAL, + "It appears that you do not have the money necessary to cover the costs " + + "associated with opening a secondary bank account. I will be waiting here " + + "until you do." + ).also { stage = END_DIALOGUE } + } + + SecondaryBankAccountActivationResult.SUCCESS -> { + npcl( + FacialExpression.NEUTRAL, + "Your secondary bank account has been opened and can be accessed through any " + + "of the Bank of Gielinor's employees. Thank you for choosing our services." + ).also { stage = END_DIALOGUE } + } + } + } + + 26 -> npcl( + FacialExpression.NEUTRAL, + "Very well. Should you decide a secondary bank account is needed, do not hesitate to " + + "contact any of the Bank of Gielinor's stationary employees. We will be happy to help." + ).also { stage = END_DIALOGUE } + + 30 -> npcl( + FacialExpression.ANNOYED, + "What are you doing here, Fremennik?!" + ).also { stage++ } + + 31 -> playerl( + FacialExpression.WORRIED, + "I have a Seal of Pass..." + ).also { stage++ } + + 32 -> npcl( + FacialExpression.ANGRY, + "No you don't! Begone!" + ).also { stage = END_DIALOGUE } + + /* TODO: Is the above related to Lunar Diplomacy? */ + } + + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.SIRSAL_BANKER_4519) + } +} diff --git a/Server/src/main/content/region/fremennik/lunarisle/handlers/LunarIslePlugin.java b/Server/src/main/content/region/fremennik/lunarisle/handlers/LunarIslePlugin.java new file mode 100644 index 0000000..42f28bc --- /dev/null +++ b/Server/src/main/content/region/fremennik/lunarisle/handlers/LunarIslePlugin.java @@ -0,0 +1,43 @@ +package content.region.fremennik.lunarisle.handlers; + +import core.cache.def.impl.NPCDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.TeleportManager.TeleportType; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * The plugin used to handle the interactions on Lunar Isle (Moonclan island). + * @author Splinter + * @version 1.0 + */ +@Initializable +public final class LunarIslePlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(16777).getHandlers().put("option:close", this); + SceneryDefinition.forId(16774).getHandlers().put("option:open", this); + NPCDefinition.forId(4512).getHandlers().put("option:go-inside", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + final int id = node.getId(); + switch (id) { + case 16777: + case 16774: + player.getTeleporter().send(Location.create(2101, 3926, 0), TeleportType.FAIRY_RING); + break; + case 4512: + player.getTeleporter().send(Location.create(2451, 4645, 0), TeleportType.FAIRY_RING); + break; + } + return true; + } +} diff --git a/Server/src/main/content/region/fremennik/neitiznot/dialogue/AnnaIsaakson.java b/Server/src/main/content/region/fremennik/neitiznot/dialogue/AnnaIsaakson.java new file mode 100644 index 0000000..2585f7d --- /dev/null +++ b/Server/src/main/content/region/fremennik/neitiznot/dialogue/AnnaIsaakson.java @@ -0,0 +1,56 @@ +package content.region.fremennik.neitiznot.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; + +/** + * Replacement for the Anna Isaakson .asc file + * @author ceik + */ + +@Initializable +public class AnnaIsaakson extends DialoguePlugin { + public AnnaIsaakson(){ + /** + * Empty on purpose + */ + } + public AnnaIsaakson(Player player){super(player);} + + @Override + public DialoguePlugin newInstance(Player player){return new AnnaIsaakson(player);} + + @Override + public boolean open(Object... args) { + npc("Hello visitor, how are you?"); + stage = 1; + return true; + } + + @Override + public final boolean handle(int interfaceId, int buttonId){ + switch(stage){ + case 1: + player("Better than expected. Its a lot...nicer...here than I was", "expecting. Everyone seems pretty happy."); + stage = 2; + break; + case 2: + npc("Of course, the Burgher is strong and wise, and looks", "after us well"); + stage = 3; + break; + case 3: + player("I think some of those Jatizso citizens have got", "the wrong idea about this place."); + stage = 10; + break; + case 10: + end(); + break; + } + return true; + } + @Override + public int[] getIds() { + return new int[] { 5512 }; + } +} diff --git a/Server/src/main/content/region/fremennik/neitiznot/dialogue/FridleifShieldsonDialogue.kt b/Server/src/main/content/region/fremennik/neitiznot/dialogue/FridleifShieldsonDialogue.kt new file mode 100644 index 0000000..c94e5c0 --- /dev/null +++ b/Server/src/main/content/region/fremennik/neitiznot/dialogue/FridleifShieldsonDialogue.kt @@ -0,0 +1,32 @@ +package content.region.fremennik.neitiznot.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class FridleifShieldsonDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player?): DialoguePlugin { + return FridleifShieldsonDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npcl(FacialExpression.FRIENDLY, "Greetings!") + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> playerl(FacialExpression.FRIENDLY, "Hello!").also { stage = END_DIALOGUE } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.FRIDLEIF_SHIELDSON_5505) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/neitiznot/dialogue/GunnarHoldstromDialogue.kt b/Server/src/main/content/region/fremennik/neitiznot/dialogue/GunnarHoldstromDialogue.kt new file mode 100644 index 0000000..5a2e9f1 --- /dev/null +++ b/Server/src/main/content/region/fremennik/neitiznot/dialogue/GunnarHoldstromDialogue.kt @@ -0,0 +1,34 @@ +package content.region.fremennik.neitiznot.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs +import core.tools.END_DIALOGUE + +@Initializable +class GunnarHoldstromDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player?): DialoguePlugin { + return GunnarHoldstromDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npcl(FacialExpression.HAPPY, "Ah, isn't it a lovely day?") + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> playerl(FacialExpression.ASKING, "It's not bad. What puts you in such a good mood?").also { stage++ } + 1 -> npcl(FacialExpression.HAPPY, "Oh, I just love my job. The smell of the sea breeze, the smell of the arctic pine sap, the smell of the yaks. I find it all so bracing.").also { stage++ } + 2 -> playerl(FacialExpression.ASKING, "Bracing? Hmmm. I think I might have chosen a different word.").also { stage = END_DIALOGUE } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.GUNNAR_HOLDSTROM_5511) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/neitiznot/dialogue/JofridrMordstatterDialogue.kt b/Server/src/main/content/region/fremennik/neitiznot/dialogue/JofridrMordstatterDialogue.kt new file mode 100644 index 0000000..3188fd3 --- /dev/null +++ b/Server/src/main/content/region/fremennik/neitiznot/dialogue/JofridrMordstatterDialogue.kt @@ -0,0 +1,47 @@ +package content.region.fremennik.neitiznot.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs +import core.tools.END_DIALOGUE + +@Initializable +class JofridrMordstatterDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player?): DialoguePlugin { + return JofridrMordstatterDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npcl(FacialExpression.NEUTRAL, "Hello there. Would you like to see the goods I have for sale?") + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> options("Yes please, Jofridr.", "No thank you, Jofridr.", "Why do you have so much wool in your store?").also { stage++ } + 1 -> when (buttonId) { + 1 -> playerl(FacialExpression.NEUTRAL, "Yes please, Jofridr.").also { stage = END_DIALOGUE }.also { npc.openShop(player) } + 2 -> playerl(FacialExpression.NEUTRAL, "No thank you, Jofridr.").also { stage = 5 } + 3 -> playerl(FacialExpression.THINKING, "Why do you have so much wool in your store? I haven't seen any sheep anywhere.").also { stage = 11} + } + 5 -> npcl(FacialExpression.NEUTRAL,"Fair thee well.").also { stage = END_DIALOGUE } + + 11 -> npcl(FacialExpression.FRIENDLY,"Ah, I have contacts on the mainland. I have a sailor friend who brings me crates of wool on a regular basis.").also { stage++ } + 12 -> playerl(FacialExpression.ASKING,"What do you trade for it?").also { stage++ } + 13 -> npcl(FacialExpression.FRIENDLY,"Rope of course! What else can we sell? Fish would go off before it got so far south.").also { stage++ } + 14 -> playerl(FacialExpression.ASKING,"Where does all this rope go?").also { stage++ } + 15 -> npcl(FacialExpression.THINKING,"Err, I don't remember the name of the place very well. Dreinna? Drennor? Something like that.").also { stage++ } + 16 -> playerl(FacialExpression.NEUTRAL,"That's very interesting. Thanks Jofridr.").also { stage = END_DIALOGUE } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.JOFRIDR_MORDSTATTER_5509) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/neitiznot/dialogue/KjedeligUppsenDialogue.kt b/Server/src/main/content/region/fremennik/neitiznot/dialogue/KjedeligUppsenDialogue.kt new file mode 100644 index 0000000..e0e0b64 --- /dev/null +++ b/Server/src/main/content/region/fremennik/neitiznot/dialogue/KjedeligUppsenDialogue.kt @@ -0,0 +1,32 @@ +package content.region.fremennik.neitiznot.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class KjedeligUppsenDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player?): DialoguePlugin { + return KjedeligUppsenDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npcl(FacialExpression.NEUTRAL, "I'm guarding the king, I cannot speak.") + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> playerl(FacialExpression.NEUTRAL, "Sorry.").also { stage = END_DIALOGUE } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.KJEDELIG_UPPSEN_5518) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/neitiznot/dialogue/LisseIsaaksonDialogue.kt b/Server/src/main/content/region/fremennik/neitiznot/dialogue/LisseIsaaksonDialogue.kt new file mode 100644 index 0000000..b99892d --- /dev/null +++ b/Server/src/main/content/region/fremennik/neitiznot/dialogue/LisseIsaaksonDialogue.kt @@ -0,0 +1,38 @@ +package content.region.fremennik.neitiznot.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs +import core.tools.END_DIALOGUE + +@Initializable +class LisseIsaaksonDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player?): DialoguePlugin { + return LisseIsaaksonDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npcl(FacialExpression.FRIENDLY, "Hello, visitor!") + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> playerl(FacialExpression.ASKING, "Hello. What are you up to?").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "Ah, I was about to collect some yak's milk to make yak cheese.").also { stage++ } + 2 -> playerl(FacialExpression.HALF_WORRIED, "Eughr! Though I am curious. Can I try some?").also { stage++ } + 3 -> npcl(FacialExpression.SAD, "Sorry, no. The last outlander who ate my cheese was ill for a month.").also { stage++ } + 4 -> playerl(FacialExpression.ASKING, "So why don't you get ill as well?").also { stage++ } + 5 -> npcl(FacialExpression.FRIENDLY, "Well, we eat yak milk products every day, from when we're born. So I suppose we're used to it. Anyway I should stop yakking - haha - and get on with my work.").also { stage++ } + 6 -> playerl(FacialExpression.HAPPY, "I'm glad to see that puns are common everywhere in Gielinor; even here.").also { stage = END_DIALOGUE } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.LISSE_ISAAKSON_5513) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/neitiznot/dialogue/MawnisBurowgarDialogue.java b/Server/src/main/content/region/fremennik/neitiznot/dialogue/MawnisBurowgarDialogue.java new file mode 100644 index 0000000..29ae5a1 --- /dev/null +++ b/Server/src/main/content/region/fremennik/neitiznot/dialogue/MawnisBurowgarDialogue.java @@ -0,0 +1,105 @@ +package content.region.fremennik.neitiznot.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +/** + * Handles the mawnis burowgar dialogue. + * @author Vexia + */ +public class MawnisBurowgarDialogue extends DialoguePlugin { + + /** + * The helmet of neitiznot. + */ + private static final Item HELM = new Item(10828); + + /** + * Constructs a new {@code MawnisBurowgarDialogue} {@code Object} + */ + public MawnisBurowgarDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code MawnisBurowgarDialogue} {@code Object} + * @param player the player. + */ + public MawnisBurowgarDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new MawnisBurowgarDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc("It makes me proud to know that the helm of my", "ancestors will be worn in battle."); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + npc("I thank you on behalf of all my kinsmen Talvald."); + stage++; + break; + case 1: + if (player.hasItem(HELM) || player.hasItem(new Item(10843))) { + end(); + break; + } + player("Ah yes, about that beautiful helmet."); + stage++; + break; + case 2: + npc("You mean the priceless heirloom that I have to you as", "a sign of my trust and gratitude?"); + stage++; + break; + case 3: + player("Err yes, that one. I may have mislaid it."); + stage++; + break; + case 4: + npc("It's a good job I have alert and loyal men who notice", "when something like this is left lying around and picks it", "up."); + stage++; + break; + case 5: + npc("I'm afraid I'm going to have to charge you a", "50,000GP handling cost."); + stage++; + break; + case 6: + if (!player.getInventory().contains(995, 50000)) { + player("I don't have that much money on me."); + stage++; + break; + } + if (player.getInventory().remove(new Item(995, 50000))) { + player.getInventory().add(HELM, player); + interpreter.sendItemMessage(HELM, "The Burgher hands you his crown."); + stage = 8; + } + break; + case 7: + npc("Well, come back when you do."); + stage++; + break; + case 8: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 5504 }; + } + +} diff --git a/Server/src/main/content/region/fremennik/neitiznot/dialogue/MortenHoldstromDialogue.kt b/Server/src/main/content/region/fremennik/neitiznot/dialogue/MortenHoldstromDialogue.kt new file mode 100644 index 0000000..5d44c59 --- /dev/null +++ b/Server/src/main/content/region/fremennik/neitiznot/dialogue/MortenHoldstromDialogue.kt @@ -0,0 +1,38 @@ +package content.region.fremennik.neitiznot.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs +import core.tools.END_DIALOGUE + +@Initializable +class MortenHoldstromDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player?): DialoguePlugin { + return MortenHoldstromDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npcl(FacialExpression.NEUTRAL, "Good day to you.") + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> playerl(FacialExpression.ASKING, "Hello. What are you up to?").also { stage++ } + 1 -> npcl(FacialExpression.HAPPY, "Ah, today is a surströmming day! The herring I buried six months ago is ready to be dug up.").also { stage++ } + 2 -> playerl(FacialExpression.DISGUSTED, "Eughr! What are you going to do with it?").also { stage++ } + 3 -> npcl(FacialExpression.HAPPY, "Eat it, of course! It will be fermented just-right by now.").also { stage++ } + 4 -> playerl(FacialExpression.ASKING, "Fermented? You eat rotten fish?").also { stage++ } + 5 -> npcl(FacialExpression.HAPPY, "Hmmm, tasty. I'm guessing you don't want to come round and try it?").also { stage++ } + 6 -> playerl(FacialExpression.ANNOYED, "You guess correctly.").also { stage = END_DIALOGUE } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.MORTEN_HOLDSTROM_5510) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/neitiznot/dialogue/SlugHemliggsenDialogue.kt b/Server/src/main/content/region/fremennik/neitiznot/dialogue/SlugHemliggsenDialogue.kt new file mode 100644 index 0000000..5959779 --- /dev/null +++ b/Server/src/main/content/region/fremennik/neitiznot/dialogue/SlugHemliggsenDialogue.kt @@ -0,0 +1,31 @@ +package content.region.fremennik.neitiznot.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class SlugHemliggsenDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player?): DialoguePlugin { + return SlugHemliggsenDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npcl(FacialExpression.WORRIED, "Shhh. Go away. I'm not allowed to talk to you.") + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + playerl(FacialExpression.ANNOYED, "Fine, whatever ...") + stage = END_DIALOGUE + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.SLUG_HEMLIGSSEN_5520) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/neitiznot/dialogue/ThakkradSigmundsonDialogue.kt b/Server/src/main/content/region/fremennik/neitiznot/dialogue/ThakkradSigmundsonDialogue.kt new file mode 100644 index 0000000..6ecb151 --- /dev/null +++ b/Server/src/main/content/region/fremennik/neitiznot/dialogue/ThakkradSigmundsonDialogue.kt @@ -0,0 +1,32 @@ +package content.region.fremennik.neitiznot.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class ThakkradSigmundsonDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player?): DialoguePlugin { + return ThakkradSigmundsonDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npcl(FacialExpression.FRIENDLY, "Greetings! I can cure your Yak Hides if you'd like!") + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> playerl(FacialExpression.FRIENDLY, "Good to know!").also { stage = END_DIALOGUE } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.THAKKRAD_SIGMUNDSON_5506) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/neitiznot/dialogue/ThakkradYakDialogue.java b/Server/src/main/content/region/fremennik/neitiznot/dialogue/ThakkradYakDialogue.java new file mode 100644 index 0000000..340cb2b --- /dev/null +++ b/Server/src/main/content/region/fremennik/neitiznot/dialogue/ThakkradYakDialogue.java @@ -0,0 +1,144 @@ +package content.region.fremennik.neitiznot.dialogue; + +import core.game.dialogue.DialogueInterpreter; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +/** + * Handles the thakkrad yak dialogue. + * @author Vexia + */ +public class ThakkradYakDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code ThakkradYakDialogue} {@code Object} + */ + public ThakkradYakDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code ThakkradYakDialogue} {@code Object} + * @param player the player. + */ + public ThakkradYakDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new ThakkradYakDialogue(player); + } + + @Override + public boolean open(Object... args) { + options("Cure my yak-hide, please.", "Nothing, thanks."); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + switch (buttonId) { + case 1: + player("Cure my yak-hide, please."); + stage = 4; + break; + case 2: + player("Nothing, thanks."); + stage++; + break; + } + break; + case 1: + interpreter.sendDialogues(5506, null, "See you later."); + stage++; + break; + case 2: + interpreter.sendDialogues(5506, null, "You won't find anyone else who can cure yak-hide."); + stage++; + break; + case 3: + end(); + break; + case 4: + interpreter.sendDialogues(5506, null, "I will cure yak-hide for a fee of 5 gp per hide."); + stage++; + break; + case 5: + if (!player.getInventory().contains(10818, 1)) { + interpreter.sendDialogues(5506, null, "You have no yak-hide to cure."); + stage = 7; + break; + } + if (!player.getInventory().contains(995, 5)) { + interpreter.sendDialogues(5506, null, "You don't have enough gold to pay me!"); + stage = 7; + break; + } + options("Cure all my hides.", "Cure one hide.", "Cure no nide.", "Can you cure any other type of leather?"); + stage++; + break; + case 6: + switch (buttonId) { + case 1: + case 2: + cure(player, buttonId == 2 ? 1 : player.getInventory().getAmount(10818)); + stage = 8; + break; + case 3: + interpreter.sendDialogues(5506, null, "Bye!"); + stage = 7; + break; + case 4: + interpreter.sendDialogues(5506, null, "Other types of leather? Why would you need any other", "type of leather?"); + stage = 40; + break; + } + break; + case 7: + end(); + break; + case 40: + player("I'll take that as a no then."); + stage = 7; + break; + case 8: + end(); + break; + } + return true; + } + + /** + * Cures the yak hide. + * @param player the player. + * @param amount the amount. + * @return {@code True} if cured. + */ + private boolean cure(Player player, int amount) { + if (!player.getInventory().contains(995, 5 * amount)) { + interpreter.sendDialogues(5506, null, "You don't have enough gold to pay me!"); + return false; + } + if (player.getInventory().remove(new Item(995, 5 * amount))) { + for (int i = 0; i < amount; i++) { + if (player.getInventory().remove(new Item(10818))) { + player.getInventory().add(new Item(10820)); + } + } + } + player("There you go!"); + return true; + } + + @Override + public int[] getIds() { + return new int[] { DialogueInterpreter.getDialogueKey("thakkrad-yak") }; + } + +} diff --git a/Server/src/main/content/region/fremennik/neitiznot/dialogue/TrogenKonungardeDialogue.kt b/Server/src/main/content/region/fremennik/neitiznot/dialogue/TrogenKonungardeDialogue.kt new file mode 100644 index 0000000..83eec86 --- /dev/null +++ b/Server/src/main/content/region/fremennik/neitiznot/dialogue/TrogenKonungardeDialogue.kt @@ -0,0 +1,32 @@ +package content.region.fremennik.neitiznot.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class TrogenKonungardeDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player?): DialoguePlugin { + return TrogenKonungardeDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npcl(FacialExpression.NEUTRAL, "I'm guarding the king, I cannot speak.") + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> playerl(FacialExpression.NEUTRAL, "Sorry.").also { stage = END_DIALOGUE } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.TROGEN_KONUNGARDE_5519) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/neitiznot/handlers/NeitiznotListeners.kt b/Server/src/main/content/region/fremennik/neitiznot/handlers/NeitiznotListeners.kt new file mode 100644 index 0000000..26fc6f6 --- /dev/null +++ b/Server/src/main/content/region/fremennik/neitiznot/handlers/NeitiznotListeners.kt @@ -0,0 +1,39 @@ +package content.region.fremennik.neitiznot.handlers + +import core.api.* +import core.game.node.Node +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.world.map.Location +import core.game.world.map.zone.MapZone +import core.game.world.map.zone.ZoneBorders +import org.rs09.consts.NPCs +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +class NeitiznotListeners : InteractionListener { + val STUMP = 21305 + + override fun defineListeners() { + + on(STUMP, IntType.SCENERY, "cut-wood"){ player, _ -> + sendPlayerDialogue(player, "I should probably leave this alone.", core.game.dialogue.FacialExpression.HALF_THINKING) + return@on true + } + + val zone = object : MapZone("Yakzone", true){ + override fun handleUseWith(player: Player, used: Item?, with: Node?): Boolean { + if(with is NPC && with.id == NPCs.YAK_5529){ + sendMessage(player, "The cow doesn't want that.") + return true + } + return false + } + } + + registerMapZone(zone, ZoneBorders(2313,3786,2331,3802)) + addClimbDest(Location.create(2363, 3799, 0), Location.create(2364, 3799, 2)) + addClimbDest(Location.create(2363, 3799, 2), Location.create(2362, 3799, 0)) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/neitiznot/handlers/NeitiznotZone.java b/Server/src/main/content/region/fremennik/neitiznot/handlers/NeitiznotZone.java new file mode 100644 index 0000000..a609cbb --- /dev/null +++ b/Server/src/main/content/region/fremennik/neitiznot/handlers/NeitiznotZone.java @@ -0,0 +1,65 @@ +package content.region.fremennik.neitiznot.handlers; + +import content.region.fremennik.neitiznot.dialogue.MawnisBurowgarDialogue; +import content.region.fremennik.neitiznot.dialogue.ThakkradYakDialogue; +import core.game.interaction.Option; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBuilder; +import core.plugin.Plugin; +import core.plugin.Initializable; +import core.plugin.ClassScanner; + +/** + * Handles the neitiznot zone. + * @author Vexia + */ +@Initializable +public class NeitiznotZone extends MapZone implements Plugin { + + /** + * Constructs a new {@code NeitiznotZone} {@code Object} + */ + public NeitiznotZone() { + super("Neitiznot zone", true); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ZoneBuilder.configure(this); + ClassScanner.definePlugins(new MawnisBurowgarDialogue(), new ThakkradYakDialogue(), new YakArmourPlugin(), new YakArmourPlugin()); + return this; + } + + @Override + public boolean interact(Entity e, Node target, Option option) { + if (e instanceof Player) { + Player player = e.asPlayer(); + switch (target.getId()) { + case 21301: + player.getBank().open(); + return true; + case 5506: + if (option.getName().equals("Craft-goods")) { + player.getDialogueInterpreter().open("thakkrad-yak"); + return true; + } + break; + } + } + return super.interact(e, target, option); + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public void configure() { + registerRegion(9275); + } + +} diff --git a/Server/src/main/content/region/fremennik/neitiznot/handlers/YakArmourPlugin.java b/Server/src/main/content/region/fremennik/neitiznot/handlers/YakArmourPlugin.java new file mode 100644 index 0000000..1354708 --- /dev/null +++ b/Server/src/main/content/region/fremennik/neitiznot/handlers/YakArmourPlugin.java @@ -0,0 +1,146 @@ +package content.region.fremennik.neitiznot.handlers; + +import core.game.dialogue.SkillDialogueHandler; +import core.game.dialogue.SkillDialogueHandler.SkillDialogue; +import core.game.node.entity.skill.SkillPulse; +import core.game.node.entity.skill.Skills; +import content.global.skill.crafting.armour.LeatherCrafting; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; + +/** + * Handles the crafting of yak armour. + * @author Vexia + */ +public class YakArmourPlugin extends UseWithHandler { + + /** + * The body item. + */ + private static final Item BODY = new Item(10822); + + /** + * The legs item. + */ + private static final Item LEGS = new Item(10824); + + /** + * Constructs a new {@code YakArmourPlugin} {@code Object} + */ + public YakArmourPlugin() { + super(1733); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(10820, ITEM_TYPE, this); + return this; + } + + @Override + public boolean handle(final NodeUsageEvent event) { + final Player player = event.getPlayer(); + SkillDialogueHandler dialogue = new SkillDialogueHandler(player, SkillDialogue.TWO_OPTION, LEGS, BODY) { + + @Override + public void create(final int amount, int index) { + player.getPulseManager().run(new YakArmourPulse(player, index == 1 ? BODY : LEGS, index, amount)); + } + + @Override + public int getAll(int index) { + return player.getInventory().getAmount(event.getUsedItem()); + } + + }; + dialogue.open(); + return true; + } + + /** + * Handles the crafting of yak armour. + * @author Vexia + */ + public class YakArmourPulse extends SkillPulse { + + /** + * The index. + */ + private final int index; + private final int YAK_BODY_INDEX = 1; + + /** + * The ticks. + */ + private int ticks; + + /** + * The amount. + */ + private int amount; + + /** + * Constructs a new {@code YakArmourPulse} {@code Object} + * @param player the player. + * @param node the node. + * @param index the index. + */ + public YakArmourPulse(Player player, Item node, int index, int amount) { + super(player, node); + this.index = index; + this.amount = amount; + } + + @Override + public boolean checkRequirements() { + int level = (index == YAK_BODY_INDEX ? 46 : 43); + if (player.getSkills().getLevel(Skills.CRAFTING) < level) { + player.getDialogueInterpreter().sendDialogue("You need a Crafting level of at least " + level + " in order to do this."); + return false; + } + if (!player.getInventory().contains(LeatherCrafting.NEEDLE, 1)) { + return false; + } + if (!player.getInventory().containsItem(LeatherCrafting.THREAD)) { + player.getDialogueInterpreter().sendDialogue("You need some thread to make anything out of leather."); + return false; + } + int reqAmount = index == YAK_BODY_INDEX ? 2 : 1; + if (!player.getInventory().contains(10820, reqAmount)) { + player.getDialogueInterpreter().sendDialogue("You don't have the required amount of yak-hide in order to do this."); + return false; + } + player.getInterfaceManager().close(); + return true; + } + + @Override + public void animate() { + if (ticks % 5 == 0) { + player.animate(Animation.create(1249)); + } + } + + @Override + public boolean reward() { + if (++ticks % 5 != 0) { + return false; + } + int reqAmount = index == YAK_BODY_INDEX ? 2 : 1; + if (player.getInventory().remove(new Item(10820, reqAmount))) { + player.getInventory().add(node); + player.getSkills().addExperience(Skills.CRAFTING, 32, true); + LeatherCrafting.decayThread(player); + player.sendMessage("You make " + node.getName().toLowerCase() + "."); + } + amount--; + return amount < 1; + } + + } + +} diff --git a/Server/src/main/content/region/fremennik/neitiznot/handlers/YakNPC.kt b/Server/src/main/content/region/fremennik/neitiznot/handlers/YakNPC.kt new file mode 100644 index 0000000..d7ab413 --- /dev/null +++ b/Server/src/main/content/region/fremennik/neitiznot/handlers/YakNPC.kt @@ -0,0 +1,30 @@ +package content.region.fremennik.neitiznot.handlers + +import core.game.node.entity.npc.AbstractNPC +import core.game.world.map.Location +import core.plugin.Initializable +import core.tools.RandomFunction +import org.rs09.consts.NPCs + +@Initializable +class YakNPC : AbstractNPC { + //Constructor spaghetti because Arios I guess + constructor() : super(NPCs.ICE_TROLL_MALE_5474, null, true) {} + private constructor(id: Int, location: Location) : super(id, location) {} + + override fun construct(id: Int, location: Location, vararg objects: Any?): AbstractNPC { + return YakNPC(id,location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.YAK_5529) + } + + override fun tick() { + if(RandomFunction.roll(20)){ + sendChat("Moo") + } + super.tick() + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/rellekka/dialogue/BjornAndEldgrimDialogues.kt b/Server/src/main/content/region/fremennik/rellekka/dialogue/BjornAndEldgrimDialogues.kt new file mode 100644 index 0000000..47b7a42 --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/dialogue/BjornAndEldgrimDialogues.kt @@ -0,0 +1,53 @@ +package content.region.fremennik.rellekka.dialogue + +import core.api.isQuestComplete +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs +import core.tools.END_DIALOGUE +import content.data.Quests + +/** + * @author qmqz + */ + +@Initializable +class BjornAndEldgrimDialogues(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + if (!isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS)) { + player(FacialExpression.FRIENDLY, "Hello there.").also { stage = 0 } + } else if (isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS)) { + npc(FacialExpression.DRUNK, "Hey! Itsh you again! Whatshyerfashe!").also { stage = 10 } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> npcl(FacialExpression.DRUNK, "Hey! scheck it out! Itsh an outerlandub! Yer shud go shpeak to the chieftain!").also { stage++ } + 1 -> player(FacialExpression.ASKING, "The who?").also { stage++ } + 2 -> npcl(FacialExpression.DRUNK, "That guy over there by that stuff! (hic) Yeh, abshoultely! He's da bosh!").also { stage = END_DIALOGUE } + + 10 -> player(FacialExpression.ASKING, "${player.username}?").also { stage++ } + 11 -> npcl(FacialExpression.DRUNK, "Nah nah nah, not them, the other one, whatshyerfashe!").also { stage++ } + 12 -> player(FacialExpression.ASKING, "${player.getAttribute("fremennikname","fremmyname")}?").also { stage++ } + 13 -> npc(FacialExpression.DRUNK, "Thatsh what I said diddle I?").also { stage++ } + 14 -> player(FacialExpression.ASKING, "Um.... okay. I'll leave you to your drinking.").also { stage++ } + 15 -> npc(FacialExpression.DRUNK, "Thanksh pal! You're alright!").also { stage = END_DIALOGUE } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return BjornAndEldgrimDialogues(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.BJORN_1284, NPCs.ELDGRIM_1285) + } +} diff --git a/Server/src/main/content/region/fremennik/rellekka/dialogue/BlaninDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/dialogue/BlaninDialogue.kt new file mode 100644 index 0000000..52a931e --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/dialogue/BlaninDialogue.kt @@ -0,0 +1,45 @@ +package content.region.fremennik.rellekka.dialogue + +import core.api.isQuestComplete +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs +import core.tools.END_DIALOGUE +import content.data.Quests + +/** + * @author qmqz + */ + +@Initializable +class BlaninDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + if (!isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS)) { + player(FacialExpression.FRIENDLY, "Good day.").also { stage = 0 } + } else { + player(FacialExpression.FRIENDLY, "That's one less thing to worry about.").also { stage = 10 } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> npc(FacialExpression.FRIENDLY, "Good day to you, sir.").also { stage = END_DIALOGUE } + 10 -> npc(FacialExpression.FRIENDLY, "Glad I could help.").also { stage = END_DIALOGUE } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return BlaninDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.BLANIN_2940) + } +} diff --git a/Server/src/main/content/region/fremennik/rellekka/dialogue/CouncilWorkerDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/dialogue/CouncilWorkerDialogue.kt new file mode 100644 index 0000000..c540850 --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/dialogue/CouncilWorkerDialogue.kt @@ -0,0 +1,44 @@ +package content.region.fremennik.rellekka.dialogue + +import content.region.fremennik.rellekka.quest.thefremenniktrials.CouncilWorkerFTDialogue +import core.api.getQuestStage +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.diary.DiaryType +import core.plugin.Initializable +import content.data.Quests + +@Initializable +class CouncilWorkerDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin(player){ + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + if(getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) in 1..99){ + player.dialogueInterpreter.open((CouncilWorkerFTDialogue(1))) + } + else if(player.achievementDiaryManager.getDiary(DiaryType.FREMENNIK).isComplete(0, true)){ + player.dialogueInterpreter.open((CouncilWorkerDiaryDialogue())) + } + else{ + player(FacialExpression.FRIENDLY,"Hello.") + npc(FacialExpression.FRIENDLY,"How do. You planning on crossing this here bridge and heading up to Rellekka then?").also { stage = 0 } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> end() + } + return true + } + + override fun newInstance(player: Player?): core.game.dialogue.DialoguePlugin { + return CouncilWorkerDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(1287) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/rellekka/dialogue/CouncilWorkerDiaryDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/dialogue/CouncilWorkerDiaryDialogue.kt new file mode 100644 index 0000000..a4600a3 --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/dialogue/CouncilWorkerDiaryDialogue.kt @@ -0,0 +1,56 @@ +package content.region.fremennik.rellekka.dialogue + +import core.api.* +import core.game.dialogue.FacialExpression +import org.rs09.consts.Items +import core.game.dialogue.DialogueFile +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import core.game.node.entity.player.link.diary.AchievementDiary +import core.game.node.entity.player.link.diary.DiaryType + +const val COUNCIL_WORKER = 1287 + +class CouncilWorkerDiaryDialogue() : DialogueFile() { + + override fun handle(componentID: Int, buttonID: Int) { + //todo all this dialogue is inauthentic and sucks, this is just a patch to fix the absolutely garbage and incorrect way of granting the diary rewards that doesn't even give the lamp. -Ceik June 2023 + when (stage) { + START_DIALOGUE -> { + player(FacialExpression.FRIENDLY, "About my achievement diary...");stage++ + } + 1 -> { + if (!AchievementDiary.hasClaimedLevelRewards(player, DiaryType.FREMENNIK, 0)) { + AchievementDiary.flagRewarded(player, DiaryType.FREMENNIK, 0) + npc(COUNCIL_WORKER, "You have completed the Fremennik Easy Diary!") + stage++ + } else if (AchievementDiary.canReplaceReward(player, DiaryType.FREMENNIK, 0)) { + player(FacialExpression.FRIENDLY, "I need a new pair of boots.") + stage = 10 + } + //player.achievementDiaryManager.getDiary(DiaryType.FREMENNIK).setLevelRewarded(0) + } + 2 -> { + player?.let { + sendItemDialogue( + it, + Items.FREMENNIK_SEA_BOOTS_1_14571, + "The worker hands you some old sea boots." + );stage++ + } + } + 3 -> { + npc( + COUNCIL_WORKER, + "You can now use Peer the Seer to deposit your items!" + ).also { stage = END_DIALOGUE } + } + + 10 -> { + npc(COUNCIL_WORKER, "Sure!") + AchievementDiary.grantReplacement(player, DiaryType.FREMENNIK, 0) + stage = 2 + } + } + } +} diff --git a/Server/src/main/content/region/fremennik/rellekka/dialogue/DronDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/dialogue/DronDialogue.kt new file mode 100644 index 0000000..d2f2066 --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/dialogue/DronDialogue.kt @@ -0,0 +1,45 @@ +package content.region.fremennik.rellekka.dialogue + +import core.api.isQuestComplete +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs +import core.tools.END_DIALOGUE +import content.data.Quests + +/** + * @author qmqz + */ + +@Initializable +class DronDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + if (!isQuestComplete(player, Quests.MAKING_HISTORY)) { + player(FacialExpression.FRIENDLY, "Excuse me.").also { stage = 0 } + } else { + player(FacialExpression.FRIENDLY, "Excuse me.").also { stage = 10 } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> npc(FacialExpression.ANNOYED, "Leave me or I'll destroy you!").also { stage = END_DIALOGUE } + 10 -> npc(FacialExpression.ANNOYED, "You have your answers, now go away!").also { stage = END_DIALOGUE } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return DronDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.DRON_2939) + } +} diff --git a/Server/src/main/content/region/fremennik/rellekka/dialogue/FishmongerRellekkaDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/dialogue/FishmongerRellekkaDialogue.kt new file mode 100644 index 0000000..ae89665 --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/dialogue/FishmongerRellekkaDialogue.kt @@ -0,0 +1,44 @@ +package content.region.fremennik.rellekka.dialogue + +import core.api.isQuestComplete +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs +import core.tools.END_DIALOGUE +import content.data.Quests + +/** + * @author qmqz + */ + +@Initializable +class FishmongerRellekkaDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + if (!isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS)) { + npc(FacialExpression.ANNOYED, "I don't sell to outerlanders.").also { stage = END_DIALOGUE } + } else { + npcl(FacialExpression.FRIENDLY,"Hello there, ${player.getAttribute("fremennikname","fremmyname")}. Looking for fresh fish?").also { stage = 0 } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> end().also { npc.openShop(player) } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return FishmongerRellekkaDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.FISH_MONGER_1315) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/rellekka/dialogue/FurTraderDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/dialogue/FurTraderDialogue.kt new file mode 100644 index 0000000..a117d29 --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/dialogue/FurTraderDialogue.kt @@ -0,0 +1,44 @@ +package content.region.fremennik.rellekka.dialogue + +import core.api.isQuestComplete +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs +import core.tools.END_DIALOGUE +import content.data.Quests + +/** + * @author qmqz + */ + +@Initializable +class FurTraderDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + if (!isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS)) { + npc(FacialExpression.ANNOYED, "I don't sell to outerlanders.").also { stage = END_DIALOGUE } + } else { + npcl(FacialExpression.FRIENDLY,"Welcome back, ${player.getAttribute("fremennikname","fremmyname")}. Have you seen the furs I have today?").also { stage = 10 } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 10 -> end().also { npc.openShop(player) } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return FurTraderDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.FUR_TRADER_1316) + } +} diff --git a/Server/src/main/content/region/fremennik/rellekka/dialogue/HuntingExpertRellekkaDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/dialogue/HuntingExpertRellekkaDialogue.kt new file mode 100644 index 0000000..baa10c5 --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/dialogue/HuntingExpertRellekkaDialogue.kt @@ -0,0 +1,89 @@ +package content.region.fremennik.rellekka.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs +import core.game.dialogue.Topic +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE + +/** + * Represents the dialogue plugin used for the Hunting Expert in the Rellekkan Hunter area + * @author vddcore + */ +@Initializable +class HuntingExpertRellekkaDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun newInstance(player: Player): DialoguePlugin { + return HuntingExpertRellekkaDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + + npcl( + FacialExpression.HAPPY, + "Good day, you seem to have a keen eye. " + + "Maybe even some hunter's blood in that body of yours?" + ) + + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + START_DIALOGUE -> showTopics( + Topic(FacialExpression.ASKING, "Is there anything you can teach me?", 1), + Topic(FacialExpression.NEUTRAL, "Nevermind.", END_DIALOGUE) + ) + + 1 -> npcl( + FacialExpression.FRIENDLY, + "I can teach you how to hunt." + ).also { stage++ } + + 2 -> playerl( + FacialExpression.THINKING, + "What kind of creatures can I hunt?" + ).also { stage++ } + + 3 -> npcl( + FacialExpression.FRIENDLY, + "Many creatures in many ways. You need to make some traps " + + "and catch birds!" + ).also { stage++ } + + 4 -> playerl( + FacialExpression.HALF_ASKING, + "Birds?" + ).also { stage++ } + + 5 -> npcl( + FacialExpression.ANNOYED, + "Yes, birds! Like the ones here!" + ).also { stage++ } + + 6 -> npcl( + FacialExpression.ANNOYED, + "Look. Just... Get some hunting gear and go set up some traps." + ).also { stage++ } + + 7 -> playerl( + FacialExpression.HALF_ROLLING_EYES, + "Is that it?" + ).also { stage++ } + + 8 -> npcl( + FacialExpression.FURIOUS, + "JUST GO DO IT!" + ).also { stage = END_DIALOGUE } + } + return true + } + + override fun getIds(): IntArray + = intArrayOf(NPCs.HUNTING_EXPERT_5112) +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/rellekka/dialogue/IngridHradsonDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/dialogue/IngridHradsonDialogue.kt new file mode 100644 index 0000000..ba86e5b --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/dialogue/IngridHradsonDialogue.kt @@ -0,0 +1,50 @@ +package content.region.fremennik.rellekka.dialogue + +import core.api.isQuestComplete +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs +import core.tools.END_DIALOGUE +import content.data.Quests + +/** + * @author qmqz + */ + +@Initializable +class IngridHradsonDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + if (!isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS)) { + npcl(FacialExpression.ANNOYED, "Outlander, I have work to be getting on with... Please stop bothering me.").also { stage = END_DIALOGUE } + } else if (isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS) && !isQuestComplete(player, Quests.OLAFS_QUEST)) { + npc(FacialExpression.FRIENDLY, "Good afternoon! How do you like our village?").also { stage = 0 } + } else if (isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS) && isQuestComplete(player, Quests.OLAFS_QUEST)) { + npc(FacialExpression.ASKING, "Hello again! Have you any word from my husband?").also { stage = 10 } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> playerl(FacialExpression.FRIENDLY, "It's lovely. You have a fine collection of goats.").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "We polish them every day to get them nice and clean.").also { stage = END_DIALOGUE } + + 10 -> playerl(FacialExpression.HALF_GUILTY, "Err, no, not yet. It takes a while for the messages to reach me you know.").also { stage++ } + 11 -> npcl(FacialExpression.FRIENDLY, "Well, when you do, tell him we'll be more than happy to see him again.").also { stage = END_DIALOGUE } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return IngridHradsonDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.INGRID_HRADSON_3696) + } +} diff --git a/Server/src/main/content/region/fremennik/rellekka/dialogue/JarvaldDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/dialogue/JarvaldDialogue.kt new file mode 100644 index 0000000..b4dfcbd --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/dialogue/JarvaldDialogue.kt @@ -0,0 +1,205 @@ +package content.region.fremennik.rellekka.dialogue + +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.interaction.QueueStrength +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.world.map.Location +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import content.data.Quests + + +/** + * @author Player Name + */ + +@Initializable +class JarvaldDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + val travelOption = args.size > 1 + val fremname = player.getAttribute("fremennikname","lebron james") + if (npc.id == NPCs.JARVALD_2438) { + // We're on Waterbirth Island + if (isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS)) { + if (travelOption) { + npc("So what say you, stay here for the hunt,","or return home to sweet Rellekka to feast","and drink with your tribe?").also { stage = 201 } + } else { + npc("Ah, ${fremname}! Such glorious battle","makes you feel glad of life, does it not?").also { stage = 220 } + } + } else { + if (travelOption) { + npc("Have you had your fill of the hunt and wish to return,", "or are you still feeling the joy of the cull?").also { stage = 201 } + } else { + npc("Ah, you live yet, outerlander!").also { stage = 200 } + } + } + } else { + // We're in Rellekka + if (isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS)) { + if (travelOption) { + npc("Of course, ${fremname}! Your presence is more than welcome","on this cull! You wish to leave now?").also { stage = 131 } + } else { + npc("Greetings, ${fremname}!").also { stage = if (fremname == "Jarvald") 100 else 102 } + } + } else { + if (travelOption) { + npc("So do you have the 1,000 coins for my service, and are", "you ready to leave?").also { stage = 41 } + } else if (isQuestInProgress(player, Quests.THE_FREMENNIK_TRIALS, 1, 100)) { + player("Hi, I don't suppose you are a member of", "the council of elders are you?").also { stage = 0 } + } else { + npc("What do you want from me outerlander?", "It is our policy not to associate with those not of our", "tribe.").also { stage = 3 } + } + } + } + return true + } + + fun sail(to: Boolean) { + lock(player, 5) + closeAllInterfaces(player) + openInterface(player, 224) + queueScript(player, 5, QueueStrength.SOFT) { + closeInterface(player) + unlock(player) + if (to) { + player.teleport(Location.create(2544, 3759, 0)) + sendDialogue("The ship arrives at Waterbirth Island.") + } else { + player.teleport(Location.create(2620, 3685, 0)) + sendDialogue("The ship arrives at Rellekka.") + } + return@queueScript stopExecuting(player) + } + } + + override fun handle(interfaceId: Int, buttonID: Int): Boolean { + val fremname = player.getAttribute("fremennikname","lebron james") + when (stage) { + 0 -> npc("No, outerlander, I have never had the honour to be asked.").also { stage++ } + 1 -> npc("I am but a lowly warrior, fighting for my people","wherever threats may appear against us...").also { stage++ } + 2 -> npc("So what do you want from me, outerlander?").also { stage++ } + 3 -> options("Where is your chieftain?", "What Jarvald is doing.", "Nothing").also { stage++ } + 4 -> when (buttonID) { + 1 -> player("Where is your chieftain?", "I find it highly discriminatory to refuse to talk to", "someone on the grounds that they are not part of your", "tribe.").also { stage++ } + 2 -> player("So what are you doing here?").also { stage = if (getVarp(player, 520) == 0) 10 else 40 } + 3 -> player("Actually, I don't think I have","anything to speak to you about...").also { stage = END_DIALOGUE } + } + 5 -> npc("I don't rightly understand your speech outerlander, but", "my loyality is with Chieftain Brundt.").also { stage++ } + 6 -> npc("He resides in our longhall; it is the large building over", "there, you should speak to him for he speaks for us all.").also { stage++ } + 7 -> end().also { stage = END_DIALOGUE } + 10 -> npc("This should not concern you, outerlander.", "I am awaiting other Fremenniks to join me on an", "expedition to Waterbirth Island.").also { stage++ } + 11 -> options("Waterbirth Island?", "Can I come?", "Nice hat!", "Ok, 'bye.").also { stage++ } + 12 -> when (buttonID) { + 1 -> npc("It is a small crescent-shaped island","just north-west of here, outerlander.").also { stage++ } + 2 -> player("Can I come?").also { stage = 20 } + 3 -> player("Hey, I have to say, that's a fine looking","hat you are wearing there.").also { stage = 30 } + 4 -> player("Wow, you Fremenniks sure know how to party.","Well, see ya around.").also { stage = END_DIALOGUE } + } + 13 -> npc("We have many legends about it,","such as the tale of the broken sky,","and the day of the green seas.").also { stage++ } + 14 -> npc("The reason I am travelling there is more serious","Fremennik business, however. I doubt an outerlander","would be interested.").also { stage++ } + 15 -> options("Can I come?", "Nice hat!", "Ok, 'bye.").also { stage++ } + 16 -> when (buttonID) { + 1 -> player("Can I come?").also { stage = 20 } + 2 -> player("Hey, I have to say, that's a fine looking","hat you are wearing there.").also { stage = 30 } + 3 -> player("Wow, you Fremenniks sure know how to party.","Well, see ya around.").also { stage = END_DIALOGUE } + } + 20 -> npc("An outerlander join us on an honoured hunt???").also { stage++ } + 21 -> npc("Well....", "I guess...", "I might be able to allow you to join us, although it is a", "breach of many of our customs...").also { stage++ } + 22 -> player("Oh, pleeeeease?", "I really LOVE killing stuff!").also { stage++ } + 23 -> npc("Well...", "I remain unconvinced that it would be wise to allow an", "outerlander to join us in such dangerous battle, but", "your ethusiasm seems genuine enough...").also { stage++ } + 24 -> npc("I will allow you to escort us, but you must pay me a", "sum of money first.").also { stage++ } + 25 -> player("What?", "That's outrageous, why charge me money?", "And, uh, how much does it cost me?").also { stage++ } + 26 -> npc("Ah, the outerlanders have stolen from my people for", "many years, in this way you can help my community", "with a small amount of money...").also { stage++ } + 27 -> npc("Let us say...", "1,000 coins.", "Payable in advance, of course.").also { stage++ } + 28 -> npc("For this I will take you to Waterbirth Island on my", "boat, and will bring you back here when you have had", "your fill of the hunt.", "Assuming you are still alive to wish to leave, of course.").also { setVarp(player, 520, 1 shl 13, true) }.also{ stage = END_DIALOGUE } + 29 -> npc("Wow, you Fremenniks sure know how to party.","Well, see ya around.").also { stage = END_DIALOGUE } + 30 -> npc("It is actually a helm, outerlander,","but the sentiment is appreciated nonetheless.").also { stage = END_DIALOGUE } + 40 -> npc("So do you have the 1,000 coins for my service, and are", "you ready to leave?").also { stage++ } + 41 -> options("YES", "NO").also { stage++ } + 42 -> when (buttonID) { + 1 -> if (player.inventory.contains(Items.COINS_995, 1000)) { + if (player.inventory.remove(Item(Items.COINS_995, 1000))) { + sail(true) + } + } else { + player("Sorry, I don't have enough coins.").also { stage = END_DIALOGUE } + } + 2 -> player("No, actually I have some stuff to do here first.").also { stage++ } + } + 43 -> npc("As you wish.", "Come and see me when your bloodlust needs sating.").also { stage = END_DIALOGUE } + 100 -> npc("Ah, and what a glorious name that is! Worthy of only the finest warriors!").also { stage++ } + 101 -> player("Heh. Yup, you're right there.").also { stage++ } + + 102 -> npc("So what brings you back to fair Rellekka?","It has been too long since you have drunk in the longhall","with us and sang of your battles!").also { stage++ } + 103 -> options("What Jarvald is doing.", "Nothing").also { stage++ } + 104 -> when (buttonID) { + 1 -> player("So what are you doing here?").also { stage = if (getVarp(player, 520) and (1 shl 13) == 0) 105 else 130 } + 2 -> player("Actually, I don't think I have","anything to speak to you about...").also { stage = END_DIALOGUE } + } + 105 -> npc("You have not heard, ${fremname}?","I am leading an expedition to Waterbirth Island!").also { stage++ } + 106 -> options("Waterbirth Island?", "Can I come?", "Nice hat!", "Ok, 'bye.").also { stage++ } + 107 -> when (buttonID) { + 1 -> npc("You have not ever travelled to Waterbirth Island, ${fremname}?","I am surprised, it is a place of outstanding natural beauty.").also { stage++ } + 2 -> player("Can I come?").also { stage = 130 } + 3 -> player("Hey, I have to say, that's a fine looking","hat you are wearing there.").also { stage = 140 } + 4 -> player("Wow, you Fremenniks sure know how to party. Well, see ya around.").also { stage = END_DIALOGUE } + } + 108 -> npc("Or at least it used to be! But things have now changed...").also { stage++ } + 109 -> player("Changed? How do you mean, changed?").also { stage++ } + 110 -> npc("It seems as though the sea-beasts known to us as","the dagger-mouths have begun their hatching once again...","And there may be others of their ilk there too.").also { stage++ } + 111 -> player("Dagger-mouths?").also { stage++ } + 112 -> npc("Aye, the dagger-mouths! The vile creatures lived","near here once, but we had thought them all driven back","to the ocean depths many moons past.").also { stage++ } + 113 -> npc("I can only imagine a dagger-mouth queen has nested","somewhere nearby and spawned her foul brood","under the sea once more, and some of them have","migrated to fair Waterbirth Island.").also { stage++ } + 114 -> player("So you're scared they might attack Rellekka?").also { stage++ } + 115 -> npc("Scared? Ha ha ha!").also { stage++ } + 116 -> npc("You wound us with your questioning, ${fremname}!").also { stage++ } + 117 -> npc("We are glad the dagger-mouths have returned to","these shores, for it means we will get the chance","to hunt them once again as our ancestors did!").also { stage++ } + 118 -> npc("When treated in the correct manner, the creatures'","remains can be used to make fine battleworthy armour!").also { setVarp(player, 520, 1 shl 13, true) }.also{ stage++ } + 119 -> options("Can I come?", "Nice hat!", "Ok, 'bye.").also { stage++ } + 120 -> when (buttonID) { + 1 -> player("Can I come?").also { stage = 130 } + 2 -> player("Hey, I have to say, that's a fine looking","hat you are wearing there.").also { stage = 140 } + 3 -> player("Wow, you Fremenniks sure know how to party. Well, see ya around.").also { stage = END_DIALOGUE } + } + 130 -> npc("Of course, ${fremname}! Your presence is more than welcome","on this cull! You wish to leave now?").also { stage++ } + 131 -> options("YES", "NO").also { stage++ } + 132 -> when (buttonID) { + 1 -> sail(true) + 2 -> player("No, actually I have some stuff to do here first.").also { stage = 43 } + } + 140 -> npc("Aye, that it is ${fremname}!","Skulgrimen fashioned it for me from the carcass of one","of the monsters on Waterbirth Island after our last hunt!").also { stage++ } + 141 -> npc("I hope to kill enough creatures to fashion some fine","armour as well when next we leave!").also { stage++ } + 142 -> options("Waterbirth Island?", "Can I come?", "Ok, 'bye.").also { stage++ } + 143 -> when (buttonID) { + 1 -> npc("You have not ever travelled to Waterbirth Island, ${fremname}?","I am surprised, it is a place of outstanding natural beauty.").also { stage = 108 } + 2 -> player("Can I come?").also { stage = 130 } + 3 -> player("Wow, you Fremenniks sure know how to party.","Well, see ya around.").also { stage = END_DIALOGUE } + } + 200 -> npc("Have you had your fill of the hunt and wish to return,", "or are you still feeling the joy of the cull?").also { stage++ } + 201 -> options("I wish to return to Rellekka.", "I want to stay here.").also { stage++ } + 202 -> when (buttonID) { + 1 -> player("I wish to return to Rellekka.").also { stage++ } + 2 -> player("I want to stay here.").also { stage = 210 } + } + 203 -> npc("Then let us away;", "There will be death to bring here another day!").also{ sail(false) } + 210 -> npc("Ha Ha Ha! A true huntsman at heart!").also { stage++ } + 211 -> npc("I myself have killed over a hundred of the dagger-","mouths, and did not think it too many!").also { stage = END_DIALOGUE } + 220 -> npc("So what say you, stay here for the hunt,","or return home to sweet Rellekka to feast","and drink with your tribe?").also { stage = 201 } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return JarvaldDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.JARVALD_2435, NPCs.JARVALD_2436, NPCs.JARVALD_2437, NPCs.JARVALD_2438) + } +} diff --git a/Server/src/main/content/region/fremennik/rellekka/dialogue/LonghallBouncerDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/dialogue/LonghallBouncerDialogue.kt new file mode 100644 index 0000000..296b0a7 --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/dialogue/LonghallBouncerDialogue.kt @@ -0,0 +1,45 @@ +package content.region.fremennik.rellekka.dialogue + +import core.api.isQuestComplete +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs +import core.tools.END_DIALOGUE +import content.data.Quests + +/** + * @author qmqz + */ + +@Initializable +class LonghallBouncerDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + if (!isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS)) { + npcl(FacialExpression.ANNOYED, "Hey, outerlander. You can't go through there. Talent only, backstage.").also { stage = END_DIALOGUE } + } else{ + npcl(FacialExpression.ANNOYED, "You can't go through there. Talent only, backstage.").also { stage = 0 } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> player(FacialExpression.PANICKED, "But I'm a Bard!").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "No you're not. I saw your performance. I was paid well to keep you from ever setting foot on stage here again.").also { stage = END_DIALOGUE } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return LonghallBouncerDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.LONGHALL_BOUNCER_1278) + } +} diff --git a/Server/src/main/content/region/fremennik/rellekka/dialogue/MariaGunnarsDialogue.java b/Server/src/main/content/region/fremennik/rellekka/dialogue/MariaGunnarsDialogue.java new file mode 100644 index 0000000..b998fa8 --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/dialogue/MariaGunnarsDialogue.java @@ -0,0 +1,98 @@ +package content.region.fremennik.rellekka.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import content.region.fremennik.rellekka.handlers.RellekkaDestination; +import content.region.fremennik.rellekka.handlers.RellekkaUtils; + +import static core.api.ContentAPIKt.hasRequirement; +import content.data.Quests; + +/** + * Handles the maria gunnars dialogue. + * @author Vexia + */ +public class MariaGunnarsDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code MariaGunnarsDialogue} {@code Object} + */ + public MariaGunnarsDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code MariaGunnarsDialogue} {@code Object} + * @param player the player. + */ + public MariaGunnarsDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new MariaGunnarsDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + npc("Welcome, Talvald. Do you have any questions?"); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + options("Can you ferry me to " + (npc.getId() == 5508 ? "Neitiznot?" : "Relleka") + "?", "I just stopped to say 'hello'."); + stage++; + break; + case 1: + if (buttonId == 1) { + player("Can you ferry me to " + (npc.getId() == 5508 ? "Neitiznot?" : "Relleka") + "?"); + stage++; + } else { + player("I just stopped to say 'hello'."); + stage = 4; + } + break; + case 2: + npc("Let's set sail then."); + stage++; + break; + case 3: + end(); + if (!hasRequirement(player, Quests.THE_FREMENNIK_TRIALS)) + break; + if (npc.getId() == 5508) { + RellekkaUtils.sail(player, RellekkaDestination.RELLEKKA_TO_NEITIZNOT); + } else { + RellekkaUtils.sail(player, RellekkaDestination.NEITIZNOT_TO_RELLEKKA); + } + break; + case 4: + npc("Thanks!"); + stage++; + break; + case 5: + player("I may be back later."); + stage++; + break; + case 6: + end(); + npc.sendChat("Bye"); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 5508, 5507 }; + } + +} diff --git a/Server/src/main/content/region/fremennik/rellekka/dialogue/ReesoDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/dialogue/ReesoDialogue.kt new file mode 100644 index 0000000..9636f23 --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/dialogue/ReesoDialogue.kt @@ -0,0 +1,42 @@ +package content.region.fremennik.rellekka.dialogue + +import core.api.isQuestComplete +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs +import core.tools.END_DIALOGUE +import content.data.Quests + +/** + * @author qmqz + */ + +@Initializable +class ReesoDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + if (!isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS)) { + npcl(FacialExpression.ANNOYED, "Please do not disturb me, outerlander. I have much to do.").also { stage = END_DIALOGUE } + } else { + npcl(FacialExpression.STRUGGLE, "Sorry, ${player.getAttribute("fremennikname","fremmyname")}, I must get on with my work.").also { stage = END_DIALOGUE } + } + + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return ReesoDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.REESO_3116) + } +} diff --git a/Server/src/main/content/region/fremennik/rellekka/dialogue/TalkToChiefDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/dialogue/TalkToChiefDialogue.kt new file mode 100644 index 0000000..6c37173 --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/dialogue/TalkToChiefDialogue.kt @@ -0,0 +1,48 @@ +package content.region.fremennik.rellekka.dialogue + +import core.api.isQuestComplete +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs +import core.tools.END_DIALOGUE +import content.data.Quests + +/** + * @author qmqz + * There is no available dialogue for after The Fremennik Trials, + * only after Hero's Welcome which isn't in this revision. + */ + +@Initializable +class TalkToChiefDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + if (!isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS)) { + npcl(FacialExpression.ANNOYED, "I cannot speak to you outerlander! Talk to Brundt, the Chieftain!").also { stage = END_DIALOGUE } + } else { + player(FacialExpression.FRIENDLY, "Hello.").also { stage = 0 } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> npc(FacialExpression.FRIENDLY, "Hello to you, too!").also { stage = END_DIALOGUE } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return TalkToChiefDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.BORROKAR_1307, NPCs.FREIDIR_1306, NPCs.INGA_1314, + NPCs.JENNELLA_1312, NPCs.LANZIG_1308, NPCs.PONTAK_1309, + NPCs.SASSILIK_1313) + } +} diff --git a/Server/src/main/content/region/fremennik/rellekka/dialogue/VolfOlasfsonDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/dialogue/VolfOlasfsonDialogue.kt new file mode 100644 index 0000000..3153122 --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/dialogue/VolfOlasfsonDialogue.kt @@ -0,0 +1,49 @@ +package content.region.fremennik.rellekka.dialogue + +import core.api.isQuestComplete +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs +import core.tools.END_DIALOGUE +import content.data.Quests + +/** + * @author qmqz + */ + +@Initializable +class VolfOlasfsonDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + if (!isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS)) { + npc(FacialExpression.ANNOYED, "Sorry, outlander, but I have things to be doing.").also { stage = END_DIALOGUE } + } else if (isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS) && !isQuestComplete(player, Quests.OLAFS_QUEST)) { + npc(FacialExpression.FRIENDLY, "Hello there. Enjoying the view?").also { stage = 0 } + } else if (isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS) && isQuestComplete(player, Quests.OLAFS_QUEST)) { + npcl(FacialExpression.ASKING, "Hello again, friend! Does my father send any word... or treasures like before?").also { stage = 10 } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> player(FacialExpression.FRIENDLY, "Yes I am. You have a lovely yurt.").also { stage++ } + 1 -> npc(FacialExpression.FRIENDLY, "Thanks! I exercise it regularly.").also { stage = END_DIALOGUE } + + 10 -> playerl(FacialExpression.HALF_GUILTY, "Not today, but if he does, you will be the first to know.").also { stage = END_DIALOGUE } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return VolfOlasfsonDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.VOLF_OLAFSON_3695) + } +} diff --git a/Server/src/main/content/region/fremennik/rellekka/dialogue/WaitingOnTheShowDialogues.kt b/Server/src/main/content/region/fremennik/rellekka/dialogue/WaitingOnTheShowDialogues.kt new file mode 100644 index 0000000..d9b9fd9 --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/dialogue/WaitingOnTheShowDialogues.kt @@ -0,0 +1,35 @@ +package content.region.fremennik.rellekka.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class WaitingOnTheShowDialogues(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npc(FacialExpression.ANNOYED, "Shhh! I'm waiting for the show!").also { stage = END_DIALOGUE } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return WaitingOnTheShowDialogues(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.FRIDGEIR_1277, NPCs.OSPAK_1274, NPCs.STYRMIR_1275) + } +} diff --git a/Server/src/main/content/region/fremennik/rellekka/handlers/FremennikGuards.kt b/Server/src/main/content/region/fremennik/rellekka/handlers/FremennikGuards.kt new file mode 100644 index 0000000..5e56fa0 --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/handlers/FremennikGuards.kt @@ -0,0 +1,32 @@ +package content.region.fremennik.rellekka.handlers + +import core.api.* +import core.game.node.entity.npc.AbstractNPC +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class FremennikGuards : AbstractNPC { + //Constructor spaghetti because Arios I guess + constructor() : super(NPCs.GUARD_5489, null, true) {} + private constructor(id: Int, location: Location) : super(id, location) {} + + override fun construct(id: Int, location: Location, vararg objects: Any?): AbstractNPC { + return FremennikGuards(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.GUARD_5489, NPCs.GUARD_5490) + } + + override fun tick() { + if(this.isRespawn) { + when (id) { + NPCs.GUARD_5489 -> if (getWorldTicks() % 5 == 0) sendChat(this, "JATIZSO!") + NPCs.GUARD_5490 -> if (getWorldTicks() % 8 == 0) sendChat(this, "NEITIZNOT!") + } + } + super.tick() + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/rellekka/handlers/RellekkaListeners.kt b/Server/src/main/content/region/fremennik/rellekka/handlers/RellekkaListeners.kt new file mode 100644 index 0000000..cac9e67 --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/handlers/RellekkaListeners.kt @@ -0,0 +1,79 @@ +package content.region.fremennik.rellekka.handlers + +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.world.map.Location +import org.rs09.consts.NPCs +import content.data.Quests + +/** + * File to be used for anything Rellekka related. + * Handles the snow kebbit stairs up and down. + * @author Ceikry + */ + +class RellekkaListeners : InteractionListener { + + val UP1A = Location.create(2715, 3798, 0) + val UP1B = Location.create(2716, 3798, 0) + val UP2A = Location.create(2726, 3801, 0) + val UP2B = Location.create(2727, 3801, 0) + + val DOWN1A = Location.create(2715, 3802, 1) + val DOWN1B = Location.create(2716, 3802, 1) + val DOWN2A = Location.create(2726, 3805, 1) + val DOWN2B = Location.create(2727, 3805, 1) + val STAIRS = intArrayOf(19690,19691) + + override fun defineListeners() { + on(STAIRS, IntType.SCENERY, "ascend","descend"){ player, node -> + if(player.location.y < 3802){ + player.properties.teleportLocation = when(player.location.x){ + 2715 -> DOWN1A + 2716 -> DOWN1B + 2726 -> DOWN2A + 2727 -> DOWN2B + else -> player.location + } + } else { + player.properties.teleportLocation = when(player.location.x) { + 2715 -> UP1A + 2716 -> UP1B + 2726 -> UP2A + 2727 -> UP2B + else -> player.location + } + } + return@on true + } + + on(NPCs.MARIA_GUNNARS_5508, IntType.NPC, "ferry-neitiznot"){ player, _ -> + if (!hasRequirement(player, Quests.THE_FREMENNIK_TRIALS)) + return@on true + RellekkaUtils.sail(player, RellekkaDestination.RELLEKKA_TO_NEITIZNOT) + playJingle(player, 171) + return@on true + } + + on(NPCs.MARIA_GUNNARS_5507, IntType.NPC, "ferry-rellekka"){ player, node -> + RellekkaUtils.sail(player, RellekkaDestination.NEITIZNOT_TO_RELLEKKA) + playJingle(player, 171) + return@on true + } + + on(NPCs.MORD_GUNNARS_5481, IntType.NPC, "ferry-jatizso"){ player, node -> + if (!hasRequirement(player, Quests.THE_FREMENNIK_TRIALS)) + return@on true + RellekkaUtils.sail(player, RellekkaDestination.RELLEKKA_TO_JATIZSO) + playJingle(player, 171) + return@on true + } + + on(NPCs.MORD_GUNNARS_5482, IntType.NPC, "ferry-rellekka"){ player, node -> + RellekkaUtils.sail(player, RellekkaDestination.JATIZSO_TO_RELLEKKA) + playJingle(player, 171) + return@on true + } + } +} diff --git a/Server/src/main/content/region/fremennik/rellekka/handlers/RellekkaUtils.kt b/Server/src/main/content/region/fremennik/rellekka/handlers/RellekkaUtils.kt new file mode 100644 index 0000000..9f8da9c --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/handlers/RellekkaUtils.kt @@ -0,0 +1,35 @@ +package content.region.fremennik.rellekka.handlers + +import core.api.* +import core.game.node.entity.player.Player +import core.game.system.task.Pulse +import core.game.world.map.Location +import org.rs09.consts.Components + +object RellekkaUtils { + @JvmStatic + fun sail(player: Player, destination: RellekkaDestination){ + lock(player, 100) + openOverlay(player, 115) + openInterface(player, Components.MISC_SHIPJOURNEY_224) + animateInterface(player, Components.MISC_SHIPJOURNEY_224, 7, destination.shipAnim) + + val animDuration = animationDuration(getAnimation(destination.shipAnim)) + submitWorldPulse(object : Pulse(animDuration){ + override fun pulse(): Boolean { + teleport(player, destination.destLoc) + closeInterface(player) + closeOverlay(player) + unlock(player) + return true + } + }) + } +} + +enum class RellekkaDestination(val destName: String, val destLoc: Location, val shipAnim: Int){ + RELLEKKA_TO_JATIZSO("Jatizso", Location.create(2421, 3781, 0), 5766), + JATIZSO_TO_RELLEKKA("Rellekka", Location.create(2644, 3710, 0), 5767), + RELLEKKA_TO_NEITIZNOT("Neitiznot",Location(2310, 3782, 0), 5764), + NEITIZNOT_TO_RELLEKKA("Rellekka", Location(2644, 3710, 0), 5765) +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/rellekka/handlers/RellekkaZone.java b/Server/src/main/content/region/fremennik/rellekka/handlers/RellekkaZone.java new file mode 100644 index 0000000..4698885 --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/handlers/RellekkaZone.java @@ -0,0 +1,209 @@ +package content.region.fremennik.rellekka.handlers; + +import content.region.fremennik.rellekka.dialogue.MariaGunnarsDialogue; +import core.cache.def.impl.SceneryDefinition; +import core.game.system.task.Pulse; +import core.plugin.Initializable; +import content.global.skill.agility.AgilityHandler; +import core.game.interaction.Option; +import core.game.interaction.OptionHandler; +import core.game.component.Component; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.impl.ForceMovement; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.world.map.Location; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneBuilder; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; +import kotlin.Unit; +import core.game.world.GameWorld; +import core.plugin.ClassScanner; + +/** + * Handles the rellekka zone. + * @author Vexia + */ +@Initializable +public final class RellekkaZone extends MapZone implements Plugin { + + /** + * Constructs a new {@code RellekkaZone} {@code Object}. + */ + public RellekkaZone() { + super("rellekka", true); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ZoneBuilder.configure(this); + ClassScanner.definePlugins(new RellekaOptionHandler(), new MariaGunnarsDialogue()); + ClassScanner.definePlugin(new OptionHandler() { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + return true; + } + + }); + return this; + } + + @Override + public boolean interact(Entity e, Node target, Option option) { + if (e instanceof Player) { + final Player player = (Player) e; + switch (target.getId()) { + case 4306: + case 4310: + case 4309: + case 4304: + case 4308: + player.sendMessage("Only Fremenniks may use this " + target.getName().toLowerCase() + "."); + return true; + /* + * case 1301: player.sendMessage("Only Fremenniks may " + + * (option.equals("Trade") ? "buy clothes here" : + * "change their shoes here") + "."); return true; + */ + //case 4148: + // player.getDialogueInterpreter().sendDialogues(1278, null, "Hey, outerlander. You can't go through there. Talent", "only, backstage."); + // return true; + case 100: + player.getDialogueInterpreter().sendDialogue("You try to open the trapdoor but it won't budge! It looks like the", "trapdoor can only be opened from the other side."); + return true; + case 2435: + case 2436: + case 2437: + case 2438: + if (option.getName().equals("Travel")) { + player.getDialogueInterpreter().open(target.getId(), target, true); + return true; + } + break; + } + } + return super.interact(e, target, option); + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public void configure() { + register(new ZoneBorders(2602, 3639, 2739, 3741)); + } + + /** + * Sails a player using the relleka ships. + * @param player the player. + * @param name the name. + * @param destination the destination. + */ + public static void sail(final Player player, final String name, final Location destination) { + player.lock(); + player.getInterfaceManager().open(new Component(224)); + player.logoutListeners.put("rellekka-sail", player1 -> { + player1.setLocation(destination); + return Unit.INSTANCE; + }); + GameWorld.getPulser().submit(new Pulse(1, player) { + int count; + + @Override + public boolean pulse() { + switch (++count) { + case 5: + player.unlock(); + player.getInterfaceManager().close(); + player.getProperties().setTeleportLocation(destination); + player.getDialogueInterpreter().sendDialogue("The ship arrives at " + name + "."); + player.logoutListeners.remove("rellekka-sail"); + return true; + } + return false; + } + + }); + } + + /** + * Handles options related to relleka. + * @author Vexia + */ + public static final class RellekaOptionHandler extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(4616).getHandlers().put("option:cross", this); + SceneryDefinition.forId(4615).getHandlers().put("option:cross", this); + SceneryDefinition.forId(5847).getHandlers().put("option:climb-over", this); + SceneryDefinition.forId(5008).getHandlers().put("option:enter",this); + SceneryDefinition.forId(15116).getHandlers().put("option:climb-down", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + switch (option) { + case "cross": + switch (node.getId()) { + case 4616: + case 4615: + crossRellekaBridge(player, (Scenery) node); + break; + } + break; + case "climb-over": + switch (node.getId()) { + case 5847: + AgilityHandler.forceWalk(player, -1, player.getLocation(), player.getLocation().transform(0, player.getLocation().getY() <= 3657 ? 3 : -3, 0), Animation.create(839), 20, 1, null, 0); + break; + } + break; + case "enter": + switch(node.getId()){ + case 5008: + player.getProperties().setTeleportLocation(Location.create(2773, 10162, 0)); + break; + } + break; + case "climb-down": + switch(node.getId()){ + case 15116: + player.getProperties().setTeleportLocation(Location.create(2509, 10245, 0)); + break; + } + break; + } + return true; + } + + /** + * Crosses the relleka bridge. + * @param player the player. + * @param node the node. + */ + private void crossRellekaBridge(Player player, Scenery node) { + boolean east = node.getId() == 4616; + player.lock(2); + if (player.getLocation().equals(node.getLocation())) { + AgilityHandler.forceWalk(player, -1, player.getLocation(), player.getLocation().transform(east ? -2 : 2, 0, 0), Animation.create(1115), 20, 1.0, null, 1); + return; + } + AgilityHandler.forceWalk(player, -1, player.getLocation(), player.getLocation().transform(east ? -1 : 1, 0, 0), ForceMovement.WALK_ANIMATION, 10, 0.0, null); + AgilityHandler.forceWalk(player, -1, player.getLocation().transform(east ? -1 : 1, 0, 0), player.getLocation().transform(east ? -3 : 3, 0, 0), Animation.create(1115), 20, 1.0, null, 1); + } + + } +} diff --git a/Server/src/main/content/region/fremennik/rellekka/handlers/RockCrabNPC.java b/Server/src/main/content/region/fremennik/rellekka/handlers/RockCrabNPC.java new file mode 100644 index 0000000..0c3efc8 --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/handlers/RockCrabNPC.java @@ -0,0 +1,114 @@ +package content.region.fremennik.rellekka.handlers; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.npc.agg.AggressiveBehavior; +import core.game.node.entity.npc.agg.AggressiveHandler; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.tools.RandomFunction; + +/** + * Handles the rock crab npc. + * @author Vexia + */ +@Initializable +public final class RockCrabNPC extends AbstractNPC { + /** + * The aggresive behavior. + */ + private static final AggressiveBehavior AGGRO_BEHAVIOR = new AggressiveBehavior() { + @Override + public boolean ignoreCombatLevelDifference() { + return true; + } + @Override + public boolean canSelectTarget(Entity entity, Entity target) { + return super.canSelectTarget(entity, target) && + entity.getLocation().withinDistance(target.getLocation(), 3); + } + }; + + @Override + public void onAttack(Entity target) { + this.aggressor = true; + this.target = target; + if(getId() == getOriginalId()) { + this.transform(getOriginalId() - 1); + } + } + + /** + * If currently an aggressor. + */ + private boolean aggressor; + + /** + * The target. + */ + private Entity target; + + /** + * Constructs a new {@code RockCrabNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + public RockCrabNPC(int id, Location location) { + super(id, location, false); + super.setAggressiveHandler(new AggressiveHandler(this, AGGRO_BEHAVIOR)); + this.setAggressive(true); + this.setWalks(false); + } + + /** + * Constructs a new {@code RockCrabNPC} {@code Object}. + */ + public RockCrabNPC() { + super(-1, null); + } + + @Override + public void handleTickActions() { + super.handleTickActions(); + if ((aggressor && !inCombat() && target.getLocation().getDistance(this.getLocation()) > 12) || isInvisible()) { + reTransform(); + aggressor = false; + target = null; + getWalkingQueue().reset(); + setWalks(false); + } + } + + @Override + public void sendImpact(BattleState state) { + if (state.getEstimatedHit() >= 3 && RandomFunction.random(30) != 5) { + state.setEstimatedHit(0); + } + if (state.getEstimatedHit() == 2 && RandomFunction.random(30) != 5) { + state.setEstimatedHit(0); + } + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new RockCrabNPC(id, location); + } + + /** + * Gets the transform id. + * @return the id. + */ + private int getTransformId() { + if (getId() != super.getOriginalId()) { + return getOriginalId(); + } + return getId() - 1; + } + + @Override + public int[] getIds() { + return new int[] { 1266, 1268, 2453, 2890 }; + } + +} diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/AskeladdenDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/AskeladdenDialogue.kt new file mode 100644 index 0000000..5267323 --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/AskeladdenDialogue.kt @@ -0,0 +1,146 @@ +package content.region.fremennik.rellekka.quest.thefremenniktrials + +import core.game.node.entity.player.Player +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.item.Item +import core.plugin.Initializable +import org.rs09.consts.Items +import content.data.Quests + +@Initializable +//Disabled because the quest isn't done yet. +class AskeladdenDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun open(vararg args: Any?): Boolean { + player?.let { + if(player.inventory.contains(3709,1)){ + playerl(FacialExpression.ASKING,"I thought you really liked the long hall?") + stage = 27 + return true + } + else if(player?.getAttribute("sigmund-steps", 0) == 13){ + playerl(FacialExpression.ASKING,"I don't suppose you have any idea where I could find a written promise from Askeladden to stay out of the Longhall?") + stage = 15 + return true + } + else if(player?.getAttribute("sigmundreturning",false) == true){ + playerl(FacialExpression.ASKING,"I've lost one of the items I was supposed to be trading.") + stage = 35 + return true + } + else if(player.questRepository.isComplete(Quests.THE_FREMENNIK_TRIALS)){ + playerl(FacialExpression.HAPPY,"Hello again Askeladden.") + stage = 40 + return true + } + else if (it.questRepository.getStage(Quests.THE_FREMENNIK_TRIALS) > 0) { + player("Hello there.") + stage = 0 + return true + } + else if(it.getAttribute("fremtrials:lalli-talkedto",false)!!){ + player("Hello there. I understand you managed to get some", "golden wool from Lalli?") + stage = 0 + return true + } + else{ + playerl(FacialExpression.HAPPY,"Hello there.") + stage = 55 + return true + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return AskeladdenDialogue(player) + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> npc(FacialExpression.CHILD_LOUDLY_LAUGHING, "HAHAHA! Yeah, that Lalli... what a maroon!").also { stage++ } + 1 -> player("So how did you manage to get the wool?").also { stage++ } + 2 -> npc(FacialExpression.CHILD_FRIENDLY, "Well, as you know, I am doing the same trials that you", "are as part of my test of manhood, and that troll is the", "only one who can get that wool.").also { stage++ } + 3 -> npc(FacialExpression.CHILD_NORMAL, "You might have noticed he's kind of... messed in the", "head buddy! He's real paranoid about people stealing his", "golden apples, isn't he?").also { stage++ } + 4 -> player(FacialExpression.HALF_ASKING,"Indeed he is. So how did you manage to get some", "golden wool from him?").also { stage++ } + 5 -> npc(FacialExpression.CHILD_NORMAL, "It was easy buddy! I persuaded him he needed a pet to", "help him guard his apples. A pet that would never sleep!", "A pet that would never need food or exercise!").also { stage++ } + 6 -> npc(FacialExpression.CHILD_NORMAL, "A pet that would never need him to clean up its... well,", "you know, buddy. A pet that would always be loyal to", "him! A faithful companion for life!").also { stage++ } + 7 -> player(FacialExpression.HALF_ASKING, "What pet is this then?").also { stage++ } + 8 -> npc(FacialExpression.CHILD_LOUDLY_LAUGHING, "A pet ROCK!").also { stage++ } + 9 -> npc(FacialExpression.CHILD_NORMAL, "Man, can you believe that stupid troll traded me some", "of his golden wool for a worthless ROCK?").also { stage++ } + 10 -> npc(FacialExpression.CHILD_FRIENDLY, "Buddy, I hafta say: if brains were explosives, that troll", "wouldn't have enough to blow his nose!").also { stage++ } + 11 -> player(FacialExpression.HALF_ASKING, "Do you have any spare rocks then?").also { stage++ } + 12 -> npc(FacialExpression.CHILD_NEUTRAL, "Sure thing buddy, although I have to say, I doubt even", "that troll is stupid enough to fall for the SAME trick", "TWICE in a row! You can try anyways though!").also { + player.inventory.add(Item(Items.PET_ROCK_3695)) + player.setAttribute("/save:fremtrials:askeladden-talkedto",true) + stage = 1000} + + 15 -> npcl(FacialExpression.CHILD_LOUDLY_LAUGHING,"What? I can't believe she asked you to get a written promise from me to stay out!").also { stage++ } + 16 -> playerl(FacialExpression.NEUTRAL,"Yup, she really did.").also { stage++ } + 17 -> npcl(FacialExpression.CHILD_FRIENDLY,"Awwwwwww.... but the longhall is just SO MUCH FUN! I'd live there if I could! I suppose you really need that promise to help become a Fremennik, huh?").also { stage++ } + 18 -> playerl(FacialExpression.NEUTRAL,"Yeah, I really do...").also { stage++ } + 19 -> npcl(FacialExpression.CHILD_FRIENDLY,"Well I'll tell you what buddy; As it's you, I'll give you that written promise. All I ask in return for it is a measly 5000 gold. What do you say?").also { stage++ } + 20 -> options("Yes","No").also { stage++ } + 21 -> when(buttonId){ + 1 -> if(player?.inventory?.contains(995,5000)!! && !player.inventory.isFull){ + playerl(FacialExpression.HAPPY,"That's all you want in return? Sure thing. Here you go.") + stage = 22 + }else stage = 25 + 2 -> stage = 25 + } + 22 -> npcl(FacialExpression.CHILD_FRIENDLY,"Done, and done. Let me know if you got any more cash burning a hole in your pocket I can relieve you of, buddy.").also { + player?.inventory?.remove(Item(Items.COINS_995,5000)) + player?.inventory?.add(Item(Items.PROMISSORY_NOTE_3709)) + player?.incrementAttribute("sigmund-steps",1) + stage = 1000 + } + 25 -> playerl(FacialExpression.SAD,"I don't think so... That's really quite a lot of money...").also { stage++ } + 26 -> npcl(FacialExpression.CHILD_LOUDLY_LAUGHING,"Hey, suit yourself buddy. You change your mind, the bank of Askeladden is open for deposits 24 hours a day! Eh-heh- heh-heh-heh.").also { stage = 1000 } + + 27 -> npcl(FacialExpression.CHILD_FRIENDLY,"I do!").also { stage++ } + 28 -> playerl(FacialExpression.ASKING,"Then why did you sign this guarantee that you will never enter it again?").also { stage++ } + 29 -> npcl(FacialExpression.CHILD_FRIENDLY,"Aha! It is because I am cunning! That guarantee says that Askeladden will never enter the longhall again!").also { stage++ } + 30 -> npcl(FacialExpression.CHILD_FRIENDLY,"But when I have completed my Fremennik trials, and passed my trial of manhood,").also { stage++ } + 31 -> npcl(FacialExpression.CHILD_LOUDLY_LAUGHING,"I will be given a new name, as is our custom, and will therefore not be Askeladden anymore!").also { stage++ } + 32 -> npcl(FacialExpression.CHILD_LOUDLY_LAUGHING,"That guarantee isn't worth the paper it's written on!! You didn't think I would give up going to the longhall for only 5000 did you?").also { stage++ } + 33 -> playerl(FacialExpression.ANNOYED,"Knowing you, I guess I didn't.").also { stage = 1000 } + + 35 -> npcl(FacialExpression.CHILD_NORMAL,"That's a shame. You should speak to the merchant.").also { stage = 1000 } + + 40 -> npcl(FacialExpression.CHILD_FRIENDLY,"Hey buddy! That ain't my name no more! My new Fremennik name is Larravak! What's yours?").also { stage++ } + 41 -> playerl(FacialExpression.HAPPY,"My Fremennik name is ${player.getAttribute("fremennikname","lebron james")}.").also { stage++ } + 42 -> npcl(FacialExpression.CHILD_LOUDLY_LAUGHING,"Ha! Ain't as good as my name buddy! So what can I do ya for?").also { stage++ } + 43 -> options("Ask about things to do","Ask for a new pet rock").also { stage++ } + 44 -> when(buttonId){ + 1 -> playerl(FacialExpression.ASKING,"So, Askeladd- sorry, Larravak; What is there to do around here now that we are both Fremenniks?").also { stage++ } + 2 -> playerl(FacialExpression.ASKING,"Can I have another pet rock? I lost mine...").also { stage = 50 } + } + 45 -> npcl(FacialExpression.CHILD_THINKING,"I guess you could do a bit of shopping. We got fresh fish at the docks, and some armour and weapons at Skulgrimen's place.").also { stage++ } + 46 -> playerl(FacialExpression.HAPPY,"Okay, thanks.").also { stage = 1000 } + + 50 -> npcl(FacialExpression.CHILD_FRIENDLY,"Sure thing buddy! I'd say take better care of this one, but it's just a rock! I have hundreds of them! Go wild!").also { + player.inventory.add(Item(Items.PET_ROCK_3695)) + stage = 1000 + } + + 55 -> npcl(FacialExpression.CHILD_FRIENDLY,"Hey there, buddy. You're an outerlander, huh? I'm not really supposed to talk to you.").also { stage++ } + 56 -> playerl(FacialExpression.ASKING,"Why not?").also { stage++ } + 57 -> npcl(FacialExpression.CHILD_THINKING,"I dunno buddy. Some stupid tradition or other. We're always told not to talk to outerlanders unless the Chieftain has allowed it.").also { stage++ } + 58 -> playerl(FacialExpression.ASKING,"The Chieftain? Who is that?").also { stage++ } + 59 -> npcl(FacialExpression.CHILD_FRIENDLY,"His names Brundt, buddy. He's a real boring guy. You can find him in the long hall there.").also { stage++ } + 60 -> playerl(FacialExpression.ASKING,"Can you take me to see him?").also { stage++ } + 61 -> npcl(FacialExpression.CHILD_FRIENDLY,"Sorry buddy, I'm not allowed into the long hall. Don't worry, he's easy to spot. He's the one in the fancy helmet. Oh, and he only has one eye.").also { stage++ } + 62 -> playerl(FacialExpression.ASKING,"He's a cyclops?").also { stage++ } + 63 -> npcl(FacialExpression.CHILD_NORMAL,"Nah, nah, nah... He just wears an eyepatch! Well, see ya around buddy!").also { stage = 1000 } + + + 1000 -> end() + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(2439) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/ChieftanBrundtDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/ChieftanBrundtDialogue.kt new file mode 100644 index 0000000..ac6cc0c --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/ChieftanBrundtDialogue.kt @@ -0,0 +1,351 @@ +package content.region.fremennik.rellekka.quest.thefremenniktrials + +import core.api.* +import core.game.node.item.Item +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.tools.END_DIALOGUE +import kotlin.random.Random + +import org.rs09.consts.* +import content.data.Quests + +@Initializable +class ChieftanBrundt(player: Player? = null) : DialoguePlugin(player){ + val gender = if (player?.isMale == true){"brother"} else "sister" + val fName = player?.getAttribute("fremennikname","bringle") + + override fun open(vararg args: Any?): Boolean { + if(player?.inventory?.contains(3701,1) == true){ + playerl(FacialExpression.HAPPY,"I got Sigli's hunting map for you.") + stage = 515 + return true + } + else if(player?.inventory?.contains(3708,1) == true){ + playerl(FacialExpression.ASKING,"So cutting sales tax isn't going to ruin your economy here or anything?") + stage = 520 + return true + } + else if(player?.getAttribute("sigmundreturning",false) == true){ + playerl(FacialExpression.ASKING,"I've got this trade item. Is it for you?") + stage = 525 + return true + } + if(player?.getAttribute("sigmund-steps",0) == 5){ + playerl(FacialExpression.ASKING,"I don't suppose you have any idea where I could find a map to unspoiled hunting grounds, do you?") + stage = 510 + return true + } + else if(player?.getAttribute("sigmund-steps",0) == 4){ + playerl(FacialExpression.ASKING,"I don't suppose you have any idea where I could find a guarantee of a reduction on sales taxes, do you?") + stage = 500 + return true + } + else if (getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) > 0 && player.getAttribute("fremtrials:votes",0) >= 7) { + npcl(FacialExpression.HAPPY," Greetings again outerlander! How goes your attempts to gain votes with the council of elders?") + stage = 545 + return true + } + else if (getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) > 0 && player.getAttribute("fremtrials:votes",0) in 3..6) { + npcl(FacialExpression.HAPPY," Greetings again outerlander! How goes your attempts to gain votes with the council of elders?") + stage = 540 + return true + } + else if (getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) > 0 && player.getAttribute("fremtrials:votes",0) == 1) { + npcl(FacialExpression.HAPPY," Greetings again outerlander! How goes your attempts to gain votes with the council of elders?") + stage = 535 + return true + } + else if (getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) > 0 && player.getAttribute("fremtrials:votes",-1) == 0) { + npcl(FacialExpression.HAPPY," Greetings again outerlander! How goes your attempts to gain votes with the council of elders?") + stage = 530 + return true + } + else if(player.questRepository.isComplete(Quests.THE_FREMENNIK_TRIALS)){ + npcl(FacialExpression.HAPPY,"Hello again, $gender $fName. I hope your travels have brought you wealth and joy! What compels you to visit me on this day?") + stage = 600 + return true + } + else if(player?.questRepository?.getStage(Quests.THE_FREMENNIK_TRIALS)!! == 0) { + npc("Greetings outerlander!") + stage = 0 + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + //Pre-Quest + 0 -> { options("What is this place?", "Why will no-one talk to me?", "Do you have any quests?", "Nice hat!");stage++} + 1 -> when(buttonId){ + 1 -> playerl(FacialExpression.HAPPY,"What is this place?").also { stage ++ } + 2 -> playerl(FacialExpression.ASKING,"Why will no-one talk to me?").also { stage = 5 } + 3 -> player("Do you have any quests?").also {stage = 300} + 4 -> playerl(FacialExpression.HAPPY,"Nice hat!").also { stage = 15 } + } + 2 -> npcl(FacialExpression.HAPPY,"This place? Why, this is Relleka! Homeland of all Fremennik! I do not recognise your face outerlander; Where do you come from?").also { stage++ } + 3 -> playerl(FacialExpression.HAPPY,"Hmmm... I will not press the issue then outerlander. How may my tribe and I help you?").also { stage = 0 } + + 5 -> npcl(FacialExpression.HAPPY,"Do not take it personally, outerlander! We are a simple people, and it is our experience that keeping ourselves to ourselves is best.").also { stage++ } + 6 -> npcl(FacialExpression.HAPPY,"This is why speaking to outerlanders is forbidden.").also { stage++ } + 7 -> npcl(FacialExpression.HAPPY,"We do not wish to enter war with the outerlanders and their strange magics, so we limit all unauthorised communication.").also { stage++ } + 8 -> playerl(FacialExpression.ASKING,"Then how come you're talking to me?").also { stage++ } + 9 -> npcl(FacialExpression.HAPPY,"Ah, this is because I am the chieftan. I am the one who authorised contact. You will not find many of my tribe so forthcoming with you, as I.").also { stage++ } + 10 -> playerl(FacialExpression.ASKING,"Is there a way for you to authorise your tribe to talk to me then?").also { stage++ } + 11 -> npcl(FacialExpression.HAPPY,"Well, there is one way... but I doubt it is of any interest to you.").also { stage = 0 } + + 15 -> npcl(FacialExpression.ANNOYED,"Don't mock me outerlander; this helm has saved my life more times than I care to recall right now.").also { stage = 1000 } + + + //Do you have any quests? + 300 -> {npc("Quests, you say outerlander? Well, I would not call it a","quest as such, but if you are brave of heart and strong","of body, perhaps..."); stage++} + 301 -> {npc("No, you would not be interested. Forget I said","anything, outerlander."); stage++ } + 302 -> {options("Yes, I am interested.","No, I'm not interested."); stage++ } + 303 -> when(buttonId){ + 1 -> {player("Actually, I would be very interested to hear what you","have to offer."); stage = 310 } + 2 -> {player("No, I'm not interested."); stage = END_DIALOGUE } + } + + //Yes, I am interested in what you have to say. + 310 -> {npc("You would? These are unusual sentiments to hear from","an outerlander! My suggestion was going to be that if","you crave adventure and battle,"); stage++} + 311 -> {npc("and your heart sings for glory, then perhaps you would","be interested in joining our clan, and becoming a","Fremennik yourself?");stage++} + 312 -> {player("What would that involve exactly?");stage++} + 313 -> {npc("Well, there are two ways to become a member of our","clan and call yourself a Fremennik: be born a","Fremennik, or be voted in by our council of elders.");stage++} + 314 -> {player("Well, I think I've missed the first way, but how can I","get the council of elders to vote to let me join your","clan?");stage++} + 315 -> {npc("Well, that I cannot answer myself. You will need to","speak to each of them and see what they require of you","as proof of your dedication.");stage++} + 316 -> {npc("There are twelve council members around this village;","you will need to gain a majority vote of at least seven","councillors in your favor.");stage++} + 317 -> {npc("So, what say you? Give me the word and I will tell all","of my tribe of your intentions, be they yes or nay.");stage++} + 318 -> {options("I want to become a Fremennik!","I don't want to become a Fremennik.");stage++} + 319 -> when(buttonId){ + 1 -> {player("I think I would enjoy the challenge of becoming an","honorary Fremennik. Where and how do I start?");stage = 320} + 2 -> {player("That sounds too complicated to me.");stage = 322} + } + + //I think I would enjoy the challenge of becoming an honorary fremennik + 320 -> {npc("As I say outerlander, you must find and speak to the","twelve members of the council of elders, and see what","tasks they might set you.");stage++} + 321 -> {npc("If you can gain the support of seven of the twelve, then","you will be accepted as one of us without question.");stage = 1000;player?.questRepository?.getQuest(Quests.THE_FREMENNIK_TRIALS)?.start(player)} + + //That sounds too complicated for me. + 322 -> {npc("Well, that's what I expect from an outerlander.");stage = 1000} + + //No, I'm not interested + 340 -> TODO("Not implemented yet") + + 500 -> npcl(FacialExpression.THINKING,"A reduction on sales taxes? Why, I am the only one in the Fremennik who may authorise such a thing. What does an outerlander want with that?").also { stage++ } + 501 -> playerl(FacialExpression.HAPPY,"Actually, it's not for me. I need to get it as part of my trials").also { stage++ } + 502 -> npcl(FacialExpression.THINKING,"Hmmm. Interesting. Your trials seem to be very different to those I took as a young lad.").also { stage++ } + 503 -> npcl(FacialExpression.NEUTRAL,"Well, I am not adverse in principle to giving a slight tax break to our shops.").also { stage++ } + 504 -> npcl(FacialExpression.THINKING,"There will of course be a shortfall in the tribe's income, that will need to be made up for elsewhere, however.").also { stage++ } + 505 -> npcl(FacialExpression.ASKING,"How about this. For many years Sigli has been the only one in the tribe who knows the locations of the best hunting grounds where game is easiest to catch.").also { stage++ } + 506 -> npcl(FacialExpression.ASKING,"If you can persuade him to let the entire tribe know these hunting grounds, then we can increase productivity within the tribe, and any shortfall caused by lowering sales taxes will be covered.").also { stage++ } + 507 -> npcl(FacialExpression.HAPPY,"I think this is a more than fair arrangement to make, dont you?").also { stage++ } + 508 -> playerl(FacialExpression.HAPPY,"Yeah, that sounds very fair.").also { stage++ } + 509 -> npcl(FacialExpression.HAPPY,"Speak to Sigli then, and you may have my promise to reduce our sales taxes. And best of luck with the rest of your trials.").also { + player?.incrementAttribute("sigmund-steps",1) + stage = 1000 + } + + 510 -> npcl(FacialExpression.ANNOYED,"Ah, outerlander... if you wish to become a Fremennik you should try and pay more attention to what people tell you... ").also { stage++ } + 511 -> npcl(FacialExpression.ANNOYED,"Sigli the hunter is the only one who knows of such hunting grounds. Go and request his knowledge.").also { stage = 1000 } + + 515 -> npcl(FacialExpression.HAPPY,"Excellent work outerlander! And so quickly, too! Here, you may take my financial report promising reduced sales taxes on all goods.").also { + removeItem(player,3701) + addItem(player,3708) + stage = 1000 + } + + 520 -> npcl(FacialExpression.HAPPY,"Not at all outerlander; now that we have Sigli's map we can increase the amount of hunts we run, and make up any shortfall that way.").also { stage = 1000 } + + 525 -> npcl(FacialExpression.ANNOYED,"Not unless it's a map of the hunting grounds.").also { stage = 1000 } + + 530 -> playerl(FacialExpression.HAPPY,"I don't have any votes yet.").also { stage++ } + 531 -> npcl(FacialExpression.HAPPY,"Go and speak to the twelve members of the council of elders who live in this village. I am sure at least a few will be prepared to vote for you.").also { stage = 550 } + + 535 -> playerl(FacialExpression.HAPPY,"I only have one vote so far.").also { stage++ } + 536 -> npcl(FacialExpression.HAPPY,"Hmmm... well that is certainly a good start I would say. Keep up the good work!").also { stage++ } + 537 -> npcl(FacialExpression.HAPPY,"Remember: You need to get at least seven council votes to be accepted as a member of the Fremennik.").also { stage = 550 } + + 540 -> playerl(FacialExpression.HAPPY,"I only have ${player.getAttribute("fremtrials:votes",0)} votes so far.").also { stage++ } + 541 -> npcl(FacialExpression.HAPPY,"Hmmm... you are doing very well so far, outerlander. Keep up the good work!").also { stage = 537 } + + 545 -> playerl(FacialExpression.HAPPY,"I have seven members of the council prepared to vote in my favour now!").also { stage++ } + 546 -> npcl(FacialExpression.HAPPY,"I know outerlander, for I have been closely monitoring your progress so far!").also {stage++} + 547 -> npcl(FacialExpression.HAPPY,"Then let us put the formality aside, and let me personally welcome you into the Fremennik! May you bring us honour!").also { + player.setAttribute("/save:fremennikname", GenerateFremennikName()) + stage = 560 + } + + 550 -> npcl(FacialExpression.HAPPY,"If you need any help with your trials, I suggest you speak to Askeladden. He is currently doing his own trials of manhood to become a true Fremennik.").also { stage = END_DIALOGUE } + + 560 -> npcl(FacialExpression.HAPPY,"From this day onward, you are outerlander no more! In honour of your acceptance into the Fremennik, you gain a new name: ${player.getAttribute("fremennikname","how did u break this")}.").also { + cleanupAttributes(player) + player.questRepository.getQuest(Quests.THE_FREMENNIK_TRIALS).finish(player) + stage = 1000 + } + + 600 -> options("I just came to say hello.","Do you have any quests?","Nice hat!","Can I hear the history of your people?", "Can I have a seal of passage?").also { stage++ } + 601 -> when(buttonId){ + 1 -> playerl(FacialExpression.HAPPY,"I just came by to say hello.").also { stage++ } + 2 -> playerl(FacialExpression.ASKING,"Do you have any quests?").also { stage = 605 } + 3 -> playerl(FacialExpression.HAPPY,"Nice hat!").also { stage = 610 } + 4 -> playerl(FacialExpression.ASKING,"Can I hear the history of your people?").also { stage = 615 } + 5 -> playerl(FacialExpression.HAPPY, "Can I have a seal of passage?").also { stage = 1200 } + } + 602 -> npcl(FacialExpression.HAPPY,"Well met, $gender $fName. it is always good to see your face in glorious Rellekka once more!").also { stage = 1000 } + + 605 -> npcl(FacialExpression.HAPPY,"Not at the moment, $fName. Rest assured, should your services to the Fremennik be required, I will call upon you").also { stage = 1000 } + + 610 -> npcl(FacialExpression.HAPPY,"Aye that it is, $gender $fName. Should you desire one of your own, you should go to Skulgrimen's shop and see what they have available!").also { stage = 1000 } + + 615 -> npcl(FacialExpression.HAPPY,"Why, of course, $fName! Do not say 'your people' like that, for you are now a Fremennik yourself! What did you want to hear of?").also { stage++ } + 616 -> options("Tell me of the finding of Koschei","Tell me of the lands to the North","Tell me of the outerlanders","Don't tell me anything").also { stage++ } + 617 -> when(buttonId){ + 1 -> playerl(FacialExpression.HAPPY,"I'm interested in finding out about that mysterious warrior I fought as part of Thorvalds' combat trial. His name is Koschei I believe.").also { stage++ } + 2 -> playerl(FacialExpression.HAPPY,"I would like to hear of the lands across the ocean to the North.").also { stage = 635 } + 3 -> playerl(FacialExpression.HAPPY,"I would like to hear a little of the history between the Fremenniks and the outerlanders.").also { stage = 645 } + 4 -> playerl(FacialExpression.HAPPY,"Actually, history isn't really my thing.").also { stage = 665 } + } + + 618 -> npcl(FacialExpression.HAPPY,"Ah... the deathless one... We do not even know if Koschei is his name, when we found him he had no memory,").also { stage++ } + 619 -> npcl(FacialExpression.HAPPY,"he was simply repeating that single word. Whatever happened to him must have rattled his soul so hard that his memory ran away from him,").also { stage++ } + 620 -> npcl(FacialExpression.HAPPY,"and he has not yet found its hiding place.").also { stage++ } + 621 -> playerl(FacialExpression.ASKING,"So how exactly did you find him?").also { stage++ } + 622 -> npcl(FacialExpression.HAPPY,"Well, it was a raiding party like any other. We had just struck one of the smaller northern islands to harvest supplies by combat, as our laws allow,").also { stage++ } + 623 -> npcl(FacialExpression.HAPPY,"when we saw a figure in the icey waters. As we were at least a 3 week sail from any port, and saw no other ships nearby, he must have been there some time.").also { stage++ } + 624 -> npcl(FacialExpression.HAPPY,"We could not leave someone to the cold death of the ocean, even an outerlander, so we fished him aboard. He muttered continually, but his words made no sense.").also { stage++ } + 625 -> npcl(FacialExpression.HAPPY,"He had no clothes or possessions with him, and seemed to have been burnt somehow before he had landed in the water. I cannot help but wonder what burnt him,").also { stage++ } + 626 -> npcl(FacialExpression.HAPPY,"for as you may have seen, he is incredibly powerful and resistant to damage by any means I know of! Anyway, we decided to bring him back to Rellekka,").also { stage++ } + 627 -> npcl(FacialExpression.HAPPY,"for he did not seem of good health or sound mind, and simply repeated the word Koschei over and over. Yrsa tended to him for many weeks, until one day it was as though a new soul had entered his burnt and broken body.").also { stage++ } + 628 -> npcl(FacialExpression.HAPPY,"He suddenly left her house one day, fully healed, and able to speak to us as though nothing had happened to him.").also { stage++ } + 629 -> npcl(FacialExpression.HAPPY,"He still had no recollection of how he had come to be in the icey ocean, or of who he was, or where he had come from, but this did not matter to us or him.").also { stage++ } + 630 -> npcl(FacialExpression.HAPPY,"He took his trials of adulthood, as you did, and has been a boon to our clan ever since. Someday I fear he may regain his memory, and leave us for his past...").also { stage++ } + 631 -> npcl(FacialExpression.HAPPY,"But I will always respect any decision he decides to make should that day ever come upon us. Until then, he is more than welcome to stay here.").also { stage++ } + 632 -> npcl(FacialExpression.HAPPY,"So, $fName, was there anything more you wished to hear?").also { stage = 616 } + + 635 -> npcl(FacialExpression.HAPPY,"Well, I think the best thing for you would be to go to the docks and ask to join one of our longboats on a journey. My affairs are concentrated mostly on Rellekka,").also { stage++ } + 636 -> npcl(FacialExpression.HAPPY,"So my knowledge is not great, but I will happily share what little I do know with you, $fName. North of this town the atmosphere becomes bitterly cold.").also { stage++ } + 637 -> npcl(FacialExpression.HAPPY,"There are a number of small inhabited islands that we have sea routes with. The largest of these is possibly Miscellania,").also { stage++ } + 638 -> npcl(FacialExpression.HAPPY,"Although I hear that there has been some recent incident with their monarch, but I don't know the details.").also { stage++ } + 639 -> npcl(FacialExpression.HAPPY,"There is also of course the island of the moon clan, who change with the tides. They are our bitterest enemies, and we are currently at war with them.").also { stage++ } + 640 -> npcl(FacialExpression.HAPPY,"They are an evil people, equally cursed and blessed by the magic in their blood. Beyond those islands, there is the large frozen wasteland we call Acheron.").also { stage++ } + 641 -> npcl(FacialExpression.HAPPY,"It is an inhospitable land, and you will need an agile and sturdy body just to keep alive in its perils.").also { stage++ } + 642 -> npcl(FacialExpression.HAPPY,"As I say, my knowledge outside of this town is rather limited, and I know no more than this.").also { stage++ } + 643 -> npcl(FacialExpression.HAPPY,"Was there anything else you wished to hear tell of?").also { stage = 616 } + + 645 -> npcl(FacialExpression.HAPPY,"Ah, now that is something I know a great deal about. Believe it or not, all outerlanders were once originally Fremenniks.").also { stage++ } + 646 -> npcl(FacialExpression.HAPPY,"When first man came to these lands all were Fremenniks, and followed our ways. We lived a happy life, and never settled in one place for long.").also { stage++ } + 647 -> npcl(FacialExpression.HAPPY,"We travelled by boat along the coastlines, never taking more from the land than could be regrown by the same time in the following year.").also { stage++ } + 648 -> npcl(FacialExpression.HAPPY,"However, many moons past, some of our tribesmen were weary of constantly travelling the lands, and decided to build themselves permanent homes.").also { stage++ } + 649 -> npcl(FacialExpression.HAPPY,"Unfortunately, the other races that had also migrated here did not like this. They waged war against us at every opportunity.").also { stage++ } + 650 -> npcl(FacialExpression.HAPPY,"We were driven mostly to the coastlines, where we could escape by boat when attacked. Remember, at this time we had no real way to defend against constant attack.").also { stage++ } + 651 -> npcl(FacialExpression.HAPPY,"Then one day one of our Seers, whose full name has been lost in the telling of this tale, discovered a cave full of strange rocks.").also { stage++ } + 652 -> npcl(FacialExpression.HAPPY,"This rock would never be consumed, no matter how much we took, and sparkled at its peak, and broke off in small and regular sized chunks when mined.").also { stage++ } + 653 -> npcl(FacialExpression.HAPPY,"Stranger than this, we found that these rocks would become filled with power when taken to certain places across this land! There was a terrible argument in our tribe!").also { stage++ } + 654 -> npcl(FacialExpression.HAPPY,"Some said that we should take as many of these rocks as we could, and use them in defending against our enemies' attacks!").also { stage++ } + 655 -> npcl(FacialExpression.HAPPY,"Others said that we had found a place that belonged only to the gods, and that should we steal what was not ours we would find only torment and misery.").also { stage++ } + 656 -> npcl(FacialExpression.HAPPY,"We voted on this, and decided that it was in the best interests of the tribe to leave these strange rocks where they lay, for the gods can be spiteful and cruel,").also { stage++ } + 657 -> npcl(FacialExpression.HAPPY,"especially to those who do not treat them with the respect they desire. Some of our number refused to accept this ruling by our council however.").also { stage++ } + 658 -> npcl(FacialExpression.HAPPY,"They began to mine these rocks, and set up transport systems to the various places of power that enchanted them. They even created temples at each of these places!").also { stage++ } + 659 -> npcl(FacialExpression.HAPPY,"This was going too far! We had no choice, but to expel them from our tribe forever!").also { stage++ } + 660 -> npcl(FacialExpression.HAPPY,"We turned our backs upon them, and let them know they would never be welcome back to our tribes until they had released themselves from the rocks.").also { stage++ } + 661 -> npcl(FacialExpression.HAPPY,"This is the tale of how the outerlanders came about; through stealing from the gods, and from betraying our ideals. This is why we show them no trust.").also { stage++ } + 662 -> npcl(FacialExpression.HAPPY,"Was there something else you wished to hear?").also { stage = 616 } + + 665 -> npcl(FacialExpression.HAPPY,"Well let me know should you wish to hear our lore and histories. We value them highly.").also { stage = 1000 } + + 1200 -> npcl(FacialExpression.HALF_THINKING, "Well, I ought not to give you such things lightly...").also { stage++ } + 1201 -> npcl(FacialExpression.HALF_THINKING, "I suppose I can grant you one temporarily, provided you meet certain requirements.").also { stage++ } + 1202 -> npcl(FacialExpression.HAPPY, "Very well, $fName! Let me look you over and see if you're strong enough for this boon.").also { stage++ } + 1203 -> { + if (!hasRequirement(player, Quests.LUNAR_DIPLOMACY) || player!!.hasItem(Item(Items.SEAL_OF_PASSAGE_9083))) + npcl(FacialExpression.HALF_GUILTY, "I'm sorry, $fName. You just don't have the experience needed for this gift. Please come back when you've learned more.").also { stage = END_DIALOGUE } + else + npcl(FacialExpression.HAPPY, "Yes, yes... I see it. You've got the strength and wisdom for this gift. Please, take this. For now.").also { stage++ } + } + 1204 -> { + sendItemDialogue (player, Items.SEAL_OF_PASSAGE_9083, "Chieftan Brundt hands you a Seal of Passage.") + addItem(player, Items.SEAL_OF_PASSAGE_9083) + stage = END_DIALOGUE + } + + 1000 -> end() + } + return true + } + + + override fun newInstance(player: Player?): DialoguePlugin { + return ChieftanBrundt(player) + } + + override fun getIds(): IntArray { + return intArrayOf(1294) + } + +} + +fun GenerateFremennikName(): String { + val namePrefixes = arrayOf( + "Bal", + "Bar", + "Dal", + "Dar", + "Den", + "Dok", + "Jar", + "Jik", + "Lar", + "Rak", + "Ral", + "Ril", + "Sig", + "Tal", + "Thor", + "Ton" + ) + val nameSuffixes = arrayOf( + "dar", + "dor", + "dur", + "kal", + "kar", + "kir", + "kur", + "lah", + "lak", + "lim", + "lor", + "rak", + "rar", + "tin", + "ton", + "tor", + "vald" + ) + val randomPrefix = Random.nextInt(0, 15) + val randomSuffix = Random.nextInt(0, 16) + + return "${namePrefixes[randomPrefix]}${nameSuffixes[randomSuffix]}" +} + +fun cleanupAttributes(player: Player){ + player.removeAttribute("PeerStarted") + player.removeAttribute("housepuzzlesolved") + player.removeAttribute("fremtrials:peer-vote") + player.removeAttribute("fremtrials:votes") + player.removeAttribute("fremtrials:sigmund-vote") + player.removeAttribute("fremtrials:manni-vote") + player.removeAttribute("fremtrials:swensen-vote") + player.removeAttribute("fremtrials:olaf-accepted") + player.removeAttribute("fremtrials:lalli-talkedto") + player.removeAttribute("fremtrials:askeladden-talkedto") + player.removeAttribute("hasWool") + player.removeAttribute("lyreConcertPlayed") + player.removeAttribute("fremtrials:olaf-vote") + player.removeAttribute("fremtrials:sigli-accepted") + player.removeAttribute("fremtrials:thorvald-vote") + player.removeAttribute("fremtrials:sigli-vote") + player.removeAttribute("riddlesolved") +} diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/CouncilWorkerFTDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/CouncilWorkerFTDialogue.kt new file mode 100644 index 0000000..f9b6223 --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/CouncilWorkerFTDialogue.kt @@ -0,0 +1,53 @@ +package content.region.fremennik.rellekka.quest.thefremenniktrials + +import core.api.* +import org.rs09.consts.Items +import core.game.dialogue.DialogueFile +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import content.data.Quests + +const val COUNCIL_WORKER = 1287 + +class CouncilWorkerFTDialogue(val questStage: Int, var isBeerInteraction: Boolean = false, val beerId: Int? = null) : DialogueFile(){ + + override fun handle(componentID: Int, buttonID: Int) { + + if(isBeerInteraction){ + when(stage){ + START_DIALOGUE -> {npc(COUNCIL_WORKER,"Oh, thank you much ${if(player!!.isMale) "sir" else "miss"}");stage++} + 1 -> { + npc(COUNCIL_WORKER,"Ta very much like. That'll hit the spot nicely.. Here,","You can have this. I picked it up as a souvenir on me","last holz.") + if(beerId != null){ + if(removeItem(player!!, beerId)){ + addItem(player!!, Items.STRANGE_OBJECT_3713) + } + } else if(removeItem(player!!, Items.BEER_3803) || removeItem(player!!, Items.BEER_1917)) { + addItem(player!!, Items.STRANGE_OBJECT_3713) + } + stage = END_DIALOGUE + } + } + } + + else if(questStage in 1..99){ + when(stage){ + START_DIALOGUE -> + if(getQuestStage(player!!, Quests.THE_FREMENNIK_TRIALS) > 0) { + player("I know this is an odd question, but are you","a member of the elder council?"); stage = 1 + } else { + end() + } + 1 -> {npc(COUNCIL_WORKER,"'fraid not, ${if(player!!.isMale) "sir" else "miss"}."); stage++} + 2 -> {npc(COUNCIL_WORKER,"Say, would you do me a favor? I'm quite parched.","If you bring me a beer, I'll make it worthwhile.");stage++} + 3 -> if(inInventory(player!!,Items.BEER_3803) || inInventory(player!!,Items.BEER_1917)) { + player("Oh, I have one here! Take it.") + stage = 0 + isBeerInteraction = true + } else { + end() + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/Draugen.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/Draugen.kt new file mode 100644 index 0000000..d8bc9b6 --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/Draugen.kt @@ -0,0 +1,34 @@ +package content.region.fremennik.rellekka.quest.thefremenniktrials + +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.Item + +class Draugen(val player: Player) : NPC(1279,player.location?.transform(1,0,0)){ + + override fun init() { + super.init() + isRespawn = false + } + + override fun handleTickActions() { + super.handleTickActions() + if(!properties.combatPulse.isAttacking){ + properties.combatPulse.attack(player) + } + if (!player.isActive) { + removeAttribute(player, "fremtrials:draugen-spawned") + this.clear() + } + } + + override fun finalizeDeath(killer: Entity?) { + super.finalizeDeath(killer) + setAttribute(player, "/save:fremtrials:draugen-killed",true) + removeAttribute(player, "fremtrials:draugen-loc") + removeItem(player, Item(3696), Container.INVENTORY) + addItem(player, 3697, 1, Container.INVENTORY) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/FishermanDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/FishermanDialogue.kt new file mode 100644 index 0000000..c0c3f4f --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/FishermanDialogue.kt @@ -0,0 +1,88 @@ +package content.region.fremennik.rellekka.quest.thefremenniktrials + +import core.api.addItem +import core.api.isQuestComplete +import core.api.removeItem +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import content.data.Quests + +@Initializable +class FishermanDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + if(player?.inventory?.contains(3704,1) == true){ + playerl(FacialExpression.HAPPY,"Here. I got you your map.") + stage = 15 + return true + } + else if(player?.inventory?.contains(3703,1) == true){ + playerl(FacialExpression.ASKING,"I don't see what's so special about this so called exotic fish.") + stage = 16 + return true + } + else if(player?.getAttribute("sigmundreturning",false) == true){ + playerl(FacialExpression.ASKING,"Is this trade item for you?") + stage = 17 + return true + } + if(player?.getAttribute("sigmund-steps", 0) == 8){ + playerl(FacialExpression.ASKING,"I don't suppose you have any idea where I could find a map of deep sea fishing spots do you?") + stage = 10 + return true + } + else if(player?.getAttribute("sigmund-steps", 0) == 7){ + playerl(FacialExpression.ASKING,"I don't suppose you have any idea where I could find an exotic and extremely odd fish, do you?") + stage = 1 + return true + } else if (isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS)){ + player(FacialExpression.FRIENDLY, "Hello there.").also { stage = 100 } + } else if (!isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS)) { + player(FacialExpression.FRIENDLY, "Hello there.").also { stage = 200 } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 1 -> npcl(FacialExpression.AMAZED,"Ah, so even outerlanders have heard of my amazing catch the other day!").also { stage++ } + 2 -> playerl(FacialExpression.THINKING,"You have it? Can I trade you something for it?").also { stage++ } + 3 -> npcl(FacialExpression.HAPPY,"As exotic looking as it is, it is bad eating. I will happily trade it if you can find me the secret map of the best fishing spots that the navigator has hidden away.").also { stage++ } + 4 -> playerl(FacialExpression.AMAZED,"Is that all?").also { stage++ } + 5 -> npcl(FacialExpression.HAPPY,"Indeed it is, outerlander. The only reason I sit out here in the cold all day long is so I don't have to pay his outrageous prices.").also { stage++ } + 6 -> npcl(FacialExpression.HAPPY,"By getting me his copy of that map, I will finally be self sufficient. I might even make a profit!").also { stage++ } + 7 -> playerl(FacialExpression.THINKING,"I'll see what I can do.").also { + player?.incrementAttribute("sigmund-steps",1) + stage = 1000 + } + 10 -> npcl(FacialExpression.ANNOYED,"You should pay attention when I speak! I already told you, that rip off navigator has it, and I want it!").also { stage = 1000 } + + 15 -> npcl(FacialExpression.HAPPY,"Great work outerlander! With this, I can finally catch enough fish to make an honest living from it! Here, have the stupid fish.").also { + removeItem(player,3704) + addItem(player,3703) + stage = 1000 + } + + 16 -> npcl(FacialExpression.ANNOYED,"Me neither, outerlander. That is why I gave it to you.").also { stage = 1000 } + + 17 -> npcl(FacialExpression.ANNOYED,"I don't think so.").also { stage = 1000 } + + 100 -> npcl(FacialExpression.FRIENDLY, "Welcome back, ${if (player.isMale) "brother " else "sister "}${player.getAttribute("fremennikname","fremmyname")}. It has been too long since last we spoke! The fish are really biting today!").also { stage = END_DIALOGUE } + 200 -> npcl(FacialExpression.ANNOYED, "Don't talk to me outerlander. Anything you have to say to me, you can say to the Chieftain. Goodbye.").also { stage = END_DIALOGUE } + + 1000 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return FishermanDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(1302) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/FremennikSailorDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/FremennikSailorDialogue.kt new file mode 100644 index 0000000..84f9263 --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/FremennikSailorDialogue.kt @@ -0,0 +1,80 @@ +package content.region.fremennik.rellekka.quest.thefremenniktrials + +import core.api.addItem +import core.api.removeItem +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable + +@Initializable +class SailorDialogue (player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + if(player?.inventory?.contains(3699,1) == true){ + playerl(FacialExpression.HAPPY,"You'll be glad to know I have had a love song written just for you by Olaf. So can I have that flower of yours now?") + stage = 15 + } + else if(player?.inventory?.contains(3698,1) == true){ + playerl(FacialExpression.ASKING,"So tell me... who is this woman that you are trying to impress anyway?") + stage = 20 + return true + } + else if(player?.getAttribute("sigmundreturning",false) == true){ + playerl(FacialExpression.ASKING,"I've got an item to trade.") + stage = 25 + return true + } + else if(player?.getAttribute("sigmund-steps",0) == 2){ + playerl(FacialExpression.ASKING,"I don't suppose you have any idea where I could find a love ballad, do you?") + stage = 10 + return true + } + else if(player?.getAttribute("sigmund-started",false)!!){ + playerl(FacialExpression.ASKING,"I don't suppose you have any idea where I could find a unique flower from across the sea, do you?") + stage = 1 + return true + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 1 -> npcl(FacialExpression.HAPPY,"Ah! Even the outerlanders have heard of my mysterious flower! I found it in a country far far away from here!").also { stage++ } + 2 -> playerl(FacialExpression.ASKING,"Can I buy it from you?").also { stage++ } + 3 -> npcl(FacialExpression.NEUTRAL,"I'm afraid not, outerlander. There is a woman in this village whose heart I seek to capture, and I think giving her this strange flower might be my best bet with her.").also { stage++ } + 4 -> playerl(FacialExpression.THINKING,"Maybe you could let me have the flower and do something else to impress her?").also { stage++ } + 5 -> npcl(FacialExpression.HAPPY,"Hmm... that is not a totally stupid idea outerlander. I know she is a lover of music, and a romantic ballad might be just the thing with which to woo her.").also { stage++ } + 6 -> npcl(FacialExpression.THINKING,"Unfortunately I don't have a musical bone in my entire body, so someone else will have to write it for me.").also { stage++ } + 7 -> playerl(FacialExpression.ASKING,"So if I can find someone to write you a romantic ballad, you will give me your flower?").also { stage++ } + 8 -> npcl(FacialExpression.HAPPY,"That sounds like a fair deal to me, outerlander.").also { + player.incrementAttribute("sigmund-steps",1) + stage = 1000 + } + 10 -> npcl(FacialExpression.NEUTRAL,"Well, the only musician I know of in these parts would be that terrible bard Olaf... Ask him.").also { stage = 1000 } + + 15 -> npcl(FacialExpression.HAPPY,"Oh. It's by Olaf? Hmm. Well, a deal's a deal. I just hope it's better than the usual rubbish he comes up with, or my chances are worse than ever.").also { + removeItem(player,3699) + addItem(player,3698) + stage = 1000 + } + + 20 -> npcl(FacialExpression.HAPPY,"It's Thora, the longhall barkeep. Please don't tell her though. She's not like the rest of the Fremennik girls, she has a secret desire to see the world.").also { stage++ } + 21 -> npcl(FacialExpression.HAPPY,"Being a sailor, I can really relate to that.").also { stage = 1000 } + + 25 -> npcl(FacialExpression.HAPPY,"Remember, it's not for me unless it's a love ballad.") + + 1000 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return SailorDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(1385) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/FremennikTrials.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/FremennikTrials.kt new file mode 100644 index 0000000..ec693af --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/FremennikTrials.kt @@ -0,0 +1,99 @@ +package core.game.content.quest.fremtrials + +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import org.rs09.consts.Items +import content.data.Quests + +@Initializable +class FremennikTrials : Quest(Quests.THE_FREMENNIK_TRIALS,64,63,3,347,0,1,10){ + + class SkillRequirement(val skill: Int?, val level: Int?) + + val requirements = arrayListOf() + + override fun drawJournal(player: Player?, stage: Int) { + super.drawJournal(player, stage) + var line = 11 + val started = player?.questRepository?.getStage(Quests.THE_FREMENNIK_TRIALS)!! > 0 + + if(!started){ + line(player,"Requirements to complete quest:",line++) + line += 1 + line(player,"Level 40 Woodcutting",line++, player.skills.getStaticLevel(Skills.WOODCUTTING) >= 40) + line(player,"Level 40 Crafting",line++,player.skills.getStaticLevel(Skills.CRAFTING) >= 40) + line(player,"Level 25 Fletching",line++,player.skills.getStaticLevel(Skills.FLETCHING) >= 25) + line(player,"I must also be able to defeat a !!level 69 enemy?? and must",line++) + line(player,"not be afraid of !!combat without any weapons or armour.",line++) + line += 1 + line(player,"I can start this quest by speaking to !!Chieftan Brundt?? on",line++) + line(player,"the !!Fremennik Longhall,?? which is in the town of !!Rellekka?? to",line++) + line(player,"the north of !!Sinclair Mansion??.",line) + } + else if(started && stage != 100){ + line(player,"In order to join the Fremenniks, I need to",line++) + line(player,"!!earn the approval?? of !!7 members?? of the elder council.",line++) + line(player,"I've written down the members who I can try to help:",line++) + line(player,"Manni the Reveller",line++,player.getAttribute("fremtrials:manni-vote",false)) + line(player,"Swensen the Navigator",line++,player.getAttribute("fremtrials:swensen-vote",false)) + line(player,"Sigli the Huntsman",line++,player.getAttribute("fremtrials:sigli-vote",false)) + line(player,"Olaf the Bard",line++,player.getAttribute("fremtrials:olaf-vote",false)) + line(player,"Thorvald the Warrior",line++,player.getAttribute("fremtrials:thorvald-vote",false)) + line(player,"Sigmund the Merchant",line++,player.getAttribute("fremtrials:sigmund-vote",false)) + line(player,"Peer the Seer",line++,player.getAttribute("fremtrials:peer-vote",false)) + val voteCount = player.getAttribute("fremtrials:votes",0) + var voteText = "${voteCount} votes" + if (voteCount === 1) { + voteText = "1 vote" + } + line(player,"So far I have gotten ${voteText}.",line++) + } + else if(stage == 100){ + line(player,"I made my way to the far north of !!Kandarin?? and found",line++) + line(player,"the Barbarian hometown of !!Rellekka??. The tribe that live",line++) + line(player,"there call themselves the !!Fremennik??, and offerred me the",line++) + line(player,"chance to join them if I could pass their trials.",line++) + line += 1 + line(player,"I managed to persuade !!seven?? of the !!twelve?? council of",line++) + line(player,"elders to vote for me at their next meeting. and become an",line++) + line(player,"honorary member of the !!Fremennik??.",line++) + line += 1 + line(player,"---QUEST COMPLETE---",line++) + line(player,"They also gave me a new name:",line++) + line(player,player.getAttribute("fremennikname","hingerdinger lmao"),line++) + } + } + + override fun finish(player: Player?) { + super.finish(player) + player ?: return + var ln = 10 + player.packetDispatch.sendItemZoomOnInterface(Items.FREMENNIK_HELM_3748, 235, 277, 5) + drawReward(player, "3 Quest points, 2.8k XP in:", ln++) + drawReward(player, "Strength, Defence, Attack,",ln++) + drawReward(player, "Hitpoints, Fishing, Thieving,", ln++) + drawReward(player, "Agility,Crafting, Fletching,", ln++) + drawReward(player, "Woodcutting",ln++) + player.skills.addExperience(Skills.STRENGTH, 2812.4) + player.skills.addExperience(Skills.DEFENCE, 2812.4) + player.skills.addExperience(Skills.ATTACK, 2812.4) + player.skills.addExperience(Skills.HITPOINTS, 2812.4) + player.skills.addExperience(Skills.FISHING, 2812.4) + player.skills.addExperience(Skills.THIEVING, 2812.4) + player.skills.addExperience(Skills.AGILITY, 2812.4) + player.skills.addExperience(Skills.CRAFTING, 2812.4) + player.skills.addExperience(Skills.FLETCHING, 2812.4) + player.skills.addExperience(Skills.WOODCUTTING, 2812.4) + player.questRepository.syncronizeTab(player) + } + + override fun newInstance(`object`: Any?): Quest { + requirements.add(SkillRequirement(Skills.FLETCHING,25)) + requirements.add(SkillRequirement(Skills.CRAFTING,40)) + requirements.add(SkillRequirement(Skills.WOODCUTTING,40)) + return this + } + +} diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/HunterTalismanListener.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/HunterTalismanListener.kt new file mode 100644 index 0000000..8cab68f --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/HunterTalismanListener.kt @@ -0,0 +1,108 @@ +package content.region.fremennik.rellekka.quest.thefremenniktrials + +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.system.task.Pulse +import core.game.world.map.Location +import org.rs09.consts.Items +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.game.world.GameWorld.Pulser +import kotlin.math.abs +import kotlin.math.atan2 + +class HunterTalismanListener : InteractionListener { + + val TALISMAN = Items.HUNTERS_TALISMAN_3696 + + override fun defineListeners() { + + on(TALISMAN, IntType.ITEM, "locate"){ player, _ -> + var locationString = getAttribute(player,"fremtrials:draugen-loc","none") + if(locationString == "none"){ + val newLoc = possibleLocations.random() + setAttribute(player, "/save:fremtrials:draugen-loc","${newLoc.x},${newLoc.y}") + locationString = "${newLoc.x},${newLoc.y}" + } + val locationComponents = locationString?.split(",") + val draugenLoc = Location(Integer.parseInt(locationComponents?.get(0)),Integer.parseInt(locationComponents?.get(1))) + + if(player.location?.withinDistance(draugenLoc,5)!!){ + sendDialogue(player, "The Draugen is nearby, be careful!") + Pulser.submit(DraugenPulse(player)) + } else { + val neededDirection = draugenLoc.getDirection(player as Entity) + sendMessage(player, "The talisman pulls you to the $neededDirection") + } + return@on true + } + + } + + class DraugenPulse(val player: Player) : Pulse(){ + var count = 0 + override fun pulse(): Boolean { + when(count++){ + 3 -> { + if(getAttribute(player, "fremtrials:draugen-spawned", false)) return true + Draugen(player).init() + setAttribute(player, "fremtrials:draugen-spawned", true) + return true + } + } + return false + } + } + + val possibleLocations = listOf(Location(2625,3608), + Location(2602,3628), + Location(2668,3714), + Location(2711,3602), + Location(2664,3592)) + + + fun Location.getDirection(entity: Entity): String{ + val loc: Location = this + val difX: Double = (loc.x - entity.location.x).toDouble() + val difY: Double = (loc.y - entity.location.y).toDouble() + val angle = Math.toDegrees(atan2(difX,difY)) + val NORTH = 0.toDouble() + val SOUTH = 180.toDouble() + val EAST = (-90).toDouble() + val WEST = 90.toDouble() + val NORTHEAST = (-135).toDouble() + val NORTHWEST = 135.toDouble() + val SOUTHEAST = (-45).toDouble() + val SOUTHWEST = 45.toDouble() + if(diff(angle,NORTH) < 3){ + return "north" + } + if(diff(angle,SOUTH) < 3){ + return "south" + } + if(diff(angle,EAST) < 3){ + return "west" + } + if(diff(angle,WEST) < 3){ + return "east" + } + if(diff(angle,SOUTHEAST) < 45){ + return "north-west" + } + if(diff(angle,SOUTHWEST) < 45){ + return "north-east" + } + if(diff(angle,NORTHEAST) < 45){ + return "south-west" + } + if(diff(angle,NORTHWEST) < 45){ + return "south-east" + } + return "Dunno. ${angle}" + } + + fun diff(x: Double,y: Double): Double{ + return abs(x - y) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/KoscheiNPC.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/KoscheiNPC.kt new file mode 100644 index 0000000..1a936e7 --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/KoscheiNPC.kt @@ -0,0 +1,210 @@ +package content.region.fremennik.rellekka.quest.thefremenniktrials + +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.player.Player +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import core.game.world.GameWorld.Pulser +import core.game.world.repository.Repository + +/** + * Handles the Koschei npc. + * @author NixWigton + */ +class KoscheiNPC constructor(id: Int = 0, location: Location? = null, session: KoscheiSession? = null) : + AbstractNPC(id, location) { + + /** + * The session. + */ + val session: KoscheiSession? + + /** + * The Koschei type. + */ + var type: KoscheiType? + + /** + * If the fight has commenced. + */ + var isCommenced = false + + /** + * Constructs a new `KoscheiNPC` `Object`. + */ + init { + this.isWalks = true + this.session = session + this.isRespawn = false + type = KoscheiType.forId(id) + } + + override fun init() { + super.init() + + /** + * Ensure the player is in the arena then spawn. + */ + if (session?.player?.location?.regionId == 10653) + Pulser.submit(KoscheiSpawnPulse(session.player, this)) + else session?.close() + } + + override fun handleTickActions() { + super.handleTickActions() + if (session == null) { + return + } + if (!session.player.isActive) { + clear() + return + } + if (isCommenced && !properties.combatPulse.isAttacking) { + properties.combatPulse.attack(session.player) + } + } + + override fun startDeath(killer: Entity) { + if (killer === session!!.player) { + if (type !== KoscheiType.FOURTH_FORM) { + type!!.transform(this, session!!.player) + } else { + session?.player?.sendMessage("Congratulations! You have completed the warriors trial!") + session?.player?.setAttribute("/save:fremtrials:thorvald-vote",true) + session?.player?.setAttribute("/save:fremtrials:votes", session.player.getAttribute("fremtrials:votes", 0) + 1) + session?.player?.removeAttribute("fremtrials:warrior-accepted") + addItemOrDrop(session?.player!!, Items.FREMENNIK_BLADE_3757, 1) + session.close() + } + return + } + super.startDeath(killer) + } + + override fun sendImpact(state: BattleState?) { + if (type == KoscheiType.FOURTH_FORM) { + if (session?.player?.skills?.lifepoints!! < 2) { + session.player.fullRestore() + properties.combatPulse.stop() + Pulser.submit(FightEndPulse(session.player, this)) + return + } else { + session.player.skills?.decrementPrayerPoints(session.player.skills?.prayerPoints!!) + } + } + super.sendImpact(state) + } + + override fun construct(id: Int, location: Location, vararg objects: Any): AbstractNPC { + return KoscheiNPC(id, location, null) + } + + override fun isAttackable(entity: Entity, style: CombatStyle, message: Boolean): Boolean { + if (session == null) { + return false + } + return session.player == entity + } + + override fun canSelectTarget(target: Entity): Boolean { + if (target is Player) { + if (target != session!!.player) { + return false + } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.KOSCHEI_THE_DEATHLESS_1290, NPCs.KOSCHEI_THE_DEATHLESS_1291, NPCs.KOSCHEI_THE_DEATHLESS_1292, NPCs.KOSCHEI_THE_DEATHLESS_1293) + } + + /** + * Represents a Koschei type. + * @author NixWigton + */ + enum class KoscheiType(var npcId: Int, var appearMessage: String?, vararg var appearDialogues: String?) { + FIRST_FORM(NPCs.KOSCHEI_THE_DEATHLESS_1290, "You must prove yourself... now!"), + SECOND_FORM(NPCs.KOSCHEI_THE_DEATHLESS_1291, "This is only the beginning; you can't beat me!", "It seems you have some idea of combat after all,", "outerlander! I will not hold back so much this time!"), + THIRD_FORM(NPCs.KOSCHEI_THE_DEATHLESS_1292, "Foolish mortal; I am unstoppable.", "Impressive start... But now we fight for real!"), + FOURTH_FORM(NPCs.KOSCHEI_THE_DEATHLESS_1293, "Aaaaaaaarrgghhhh! The power!", "You show some skill at combat... I will hold back no", "longer! This time you lose your prayer however, and", "fight like a warrior!"); + + /** + * Transforms the new npc. + */ + fun transform(koschei: KoscheiNPC, player: Player) { + val newType = next() + koschei.lock() + player.properties.combatPulse.stop() + koschei.properties.combatPulse.stop() + koschei.walkingQueue.queue.clear() + koschei.animate(Animation(1057)) + koschei.type = newType + koschei.transform(newType.npcId) + Pulser.submit(KoscheiSpawnPulse(player, koschei)) + } + + /** + * Gets the next type. + * @return the type. + */ + operator fun next(): KoscheiType { + return values()[ordinal + 1] + } + + companion object { + /** + * Gets the Koschei type for the id. + * @param id the id. + * @return the Koschei type. + */ + fun forId(id: Int): KoscheiType? { + for (type in values()) { + if (type.npcId == id) { + return type + } + } + return null + } + } + } + + class KoscheiSpawnPulse(val player: Player?, val koschei: KoscheiNPC) : Pulse() { + var counter = 0 + override fun pulse(): Boolean { + when(counter++) { + 0 -> koschei.face(player).also { koschei.unlock(); player?.face(koschei) } + 1 -> if (koschei.type?.appearDialogues?.size!! > 0) { + player?.dialogueInterpreter?.sendDialogues(NPCs.KOSCHEI_THE_DEATHLESS_1291, core.game.dialogue.FacialExpression.NEUTRAL, *koschei.type!!.appearDialogues) + } else { counter = 4 } + 4 -> koschei.attack(player).also { if (koschei.type?.appearMessage?.isNotEmpty() == true) { koschei.sendChat(koschei.type?.appearMessage) }} + } + return false + } + } + + class FightEndPulse(val player: Player?, val koschei: KoscheiNPC) : Pulse() { + var counter = 0 + override fun pulse(): Boolean { + when(counter++) { + 0 -> player?.lock().also { player?.animate(Animation(1332)).also { player?.sendMessage("Oh dear you are...") }} + 1 -> player?.setAttribute("/save:fremtrials:thorvald-vote",true).also { + player?.setAttribute("/save:fremtrials:votesplayer", player.getAttribute("fremtrials:votesplayer", 0) + 1) + player?.removeAttribute("fremtrials:warrior-accepted") + } + 3 -> player?.teleport(Location.create(2666,3694,1)).also { koschei.session?.close() } + 4 -> player?.sendMessage("...still alive somehow?") + 6 -> player?.dialogueInterpreter?.open(NPCs.THORVALD_THE_WARRIOR_1289, Repository.findNPC(NPCs.THORVALD_THE_WARRIOR_1289), this) + 7 -> player?.unlock().also { player?.sendMessage("Congratulations! You have passed the warrior's trial!") } + } + return false + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/KoscheiSession.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/KoscheiSession.kt new file mode 100644 index 0000000..6e2b44e --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/KoscheiSession.kt @@ -0,0 +1,71 @@ +package content.region.fremennik.rellekka.quest.thefremenniktrials + +import core.game.node.entity.player.Player +import org.rs09.consts.NPCs + +/** + * Represents a session with Koschei. + * @author NixWigton + */ +class KoscheiSession( + /** + * The player. + */ + val player: Player +) { + /** + * The Koschei npc. + */ + private val koschei: KoscheiNPC = KoscheiNPC( + NPCs.KOSCHEI_THE_DEATHLESS_1290, + player.location?.transform(1,0,0), + this + ) + + /** + * Constructs a new `KoscheiSession` `Object`. + * @param player the player. + */ + init { + if (player.getExtension(KoscheiSession::class.java) != null) { + player.removeExtension(KoscheiSession::class.java) + } + player.addExtension(KoscheiSession::class.java, this) + } + + /** + * Starts the session. + */ + fun start() { + koschei.init() + player.unlock() + } + + /** + * Closes the session. + */ + fun close() { + koschei.clear() + player.removeExtension(KoscheiSession::class.java) + } + + companion object { + /** + * Creates the Koschei session. + * @param player the player. + * @return the session. + */ + fun create(player: Player): KoscheiSession { + return KoscheiSession(player) + } + + /** + * Gets the Koschei session. + * @param player the player. + * @return the session. + */ + fun getSession(player: Player): KoscheiSession { + return player.getExtension(KoscheiSession::class.java) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/LalliDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/LalliDialogue.kt new file mode 100644 index 0000000..a6d1f37 --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/LalliDialogue.kt @@ -0,0 +1,167 @@ +package content.region.fremennik.rellekka.quest.thefremenniktrials + +import core.api.addItem +import core.api.inInventory +import core.api.removeItem +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.item.Item +import org.rs09.consts.Items +import content.data.Quests + +@Initializable +class LalliDialogue(player: Player? = null) : DialoguePlugin(player){ + override fun open(vararg args: Any?): Boolean { + player?.let { + println(it.getAttribute("lalliEatStew", false)) + if (it.questRepository.isComplete(Quests.THE_FREMENNIK_TRIALS)){ + playerl(FacialExpression.NEUTRAL,"Hello there.") + stage = 100 + return true + } + if (it.getAttribute("lalliStewCabbageAdded", false)!! && it.getAttribute("lalliStewOnionAdded", false)!! && it.getAttribute("lalliStewPotatoAdded", false)!! && it.getAttribute("lalliStewRockAdded", false)!!){ + npcl(FacialExpression.OLD_NORMAL,"It am ready now?") + stage = 60 + return true + } + if(it.getAttribute("lalliStewCabbageAdded", false)!! || it.getAttribute("lalliStewOnionAdded", false)!! || it.getAttribute("lalliStewPotatoAdded", false)!! || it.getAttribute("lalliStewRockAdded", false)!!){ + npcl(FacialExpression.OLD_NORMAL,"It am ready now?") + stage = 58 + return true + } + if (it.getAttribute("lalliEatStew", false)!!){ + playerl(FacialExpression.NEUTRAL,"Hello there.") + stage = 65 + return true + } + if (it.getAttribute("hasWool", false)!!){ + playerl(FacialExpression.NEUTRAL,"Hello there.") + stage = 75 + return true + } + if (it.getAttribute("fremtrials:askeladden-talkedto", false)!!) { + player("Hello there.") + stage = 50 + return true + } + if(player.questRepository.isComplete(Quests.THE_FREMENNIK_TRIALS)){ + playerl(FacialExpression.HAPPY,"Hello there.") + stage = 100 + return true + } + if (it.questRepository.getStage(Quests.THE_FREMENNIK_TRIALS) > 0) { + player("Hello there.").also { stage = 0; return true } + } + } + return true + } + + + + override fun newInstance(player: Player?): DialoguePlugin { + return LalliDialogue(player) + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> npc(FacialExpression.OLD_SNEAKY,"Bah! Puny humans always try steal Lalli's golden","apples! You go away now!").also { stage++ } + 1 -> player(FacialExpression.ANNOYED,"Actually, I'm not after your golden apples. I was","wondering if I could have some golden wool, I need it","to string a lyre.").also { stage++ } + 2 -> npc(FacialExpression.OLD_SNEAKY,"Ha! You not fool me human! Me am smart! Other","trolls so jealous of how brainy I are, they kick me out","of camp and make me live down here in cave! But me","have last funny!").also { stage++ } + 3 -> npc(FacialExpression.OLD_SNEAKY,"Me find golden apples on tree and me build wall to stop","anyone who not Lalli eating lovely golden apples! Did","me not tell you I are smart?").also { stage++ } + 4 -> player("Yes, yes, you are incredibly clever. Now please can I","have some golden wool?").also { stage++ } + 5 -> npc(FacialExpression.OLD_SNEAKY,"Hmm, me think you not really think I are clever. Me","think you is trying to trick Lalli. Me not like you as much","as other human. He give me present. I give him wool.").also { stage++ } + 6 -> options("Other human?","No, honest, you're REALLY clever.","Can I give you a present?").also { stage++ } + 7 -> when(buttonId){ + 1 -> player("Other human? You mean someone else has been here","and you gave them wool?").also { stage = 10 } + 2 -> player("No, honest, you're REALLY clever!").also { stage = 20 } + 3 -> player("Can I give you a present.").also { stage = 30 } + } + + //Other human? + 10 -> npc(FacialExpression.OLD_SNEAKY,"Human call itself Askeladden! It not trick Lalli. Lalli do","good deal with human! Stupid human get some dumb","wool, but did not get golden apples!").also { stage++ } + 11 -> player("I see... okay, well, bye!").also { player.setAttribute("/save:fremtrials:lalli-talkedto",true); stage = 1000 } + + //Honest, you're clever + 20 -> npc(FacialExpression.OLD_SNEAKY,"Me no believe you tell truth. Go away.").also { stage = 1000 } + + //Can I give you a present + 30 -> npc(FacialExpression.OLD_SNEAKY,"Me think about that.").also { stage = 1000 } + + 50 -> npc(FacialExpression.OLD_SNEAKY,"Bah! Puny humans always try steal Lalli's golden","apples! You go away now!").also { stage++ } + 51 -> player("Wait! I have something that might interest you... a pet", "rock!").also { stage++ } + 52 -> npc(FacialExpression.OLD_LAUGH2, "Hah! You think me stupid or something human? Me", "already got one! Me don't want lots of baby rocks either,", "so me don't want another one around the place!").also { stage++ } + 53 -> player(FacialExpression.HALF_CRYING,"Please... all I want is some of your golden wool...").also { stage++ } + 54 -> npc(FacialExpression.OLD_SNEAKY, "Stupid human think he can trick me into giving away", "some golden apples! Hah! Golden apples is all me got to", "eat. you not get them. no way!").also { stage++ } + 55 -> player(FacialExpression.HALF_THINKING, "Hmm... So you're hungry? I think I will have the", "perfect thing for you to eat... I just need to get myself", "an onion, a potato, and a cabbage...").also { stage++ } + 56 -> interpreter.sendDialogue("You have a cunning plan to trick this troll. You need your pet rock,", "a cabbage, a potato and an onion.").also { player.removeAttribute("fremtrials:fremtrials:lalli-talkedto");stage = 1000 } + + 58 -> playerl(FacialExpression.NEUTRAL,"Not just yet...").also { stage = 1000 } + + 60 -> playerl(FacialExpression.HAPPY,"Indeed it is. Try it and see.").also { stage++ } + 61 -> npcl(FacialExpression.OLD_HAPPY,"Hmm... YUM! That are delicious! Me never know human know to make soup out of stone? It some special stone?").also { stage++ } + 62 -> playerl(FacialExpression.NEUTRAL,"Indeed it is. But I'm willing to trade it.").also { stage++ } + 63 -> npcl(FacialExpression.OLD_SNEAKY,"Let me think about that, me like to think.").also { + player.setAttribute("/save:lalliEatStew",true) + player.removeAttribute("lalliStewOnionAdded") + player.removeAttribute("lalliStewPotatoAdded") + player.removeAttribute("lalliStewCabbageAdded") + player.removeAttribute("lalliStewRockAdded") + stage = 1000 + } + + 65 -> npcl(FacialExpression.OLD_HAPPY,"Your soup very tasty, human! But me still not want trade golden apples for your stone. Me think pet rock get jealous.").also { stage++ } + 66 -> playerl(FacialExpression.ANGRY,"I. DON'T. WANT. ANY. GOLDEN. APPLES. ALL. I. WANT. IS. A. GOLDEN. FLEECE.").also { stage++ } + 67 -> npcl(FacialExpression.OLD_ALMOST_CRYING,"Gee, sorry human, all you have do is ask, me not need you to shout. You act like you think Lalli am stupid or something...").also { + if(player.inventory.isFull){ + stage = 68 + }else{ + stage = 70 + } + } + 68 -> npcl(FacialExpression.OLD_NORMAL,"Me would give you golden fleece if me think you have enough room in your inventory.").also { stage = 1000 } + 70 -> npcl(FacialExpression.OLD_HAPPY,"Here you go. Hah! Me trick you Human! All you got is worthless golden fleece! Me got very rare soup-making stone!").also { stage = 71 } + 71 -> playerl(FacialExpression.HAPPY,"Glad you're happy Lalli!").also { + player.inventory.add(Item(Items.GOLDEN_FLEECE_3693)) + player.setAttribute("/save:hasWool",true) + player.removeAttribute("lalliEatStew") + stage = 1000 + } + 75 -> npcl(FacialExpression.OLD_HAPPY,"Hah! How you like worthless golden fleece! Me very like rare soup-making stone!").also { stage++ } + 76 -> playerl(FacialExpression.HAPPY,"Oh it's great, thank you again for the fleece Lalli, I hope you're enjoying your soup").also { stage = 1000 } + + 100 -> npcl(FacialExpression.OLD_HAPPY,"Ha! Stupid human! You no get any golden apples! Even though me much like stone soup!").also { stage++ } + 101 -> playerl(FacialExpression.ASKING,"Can I please have some more golden wool?").also { stage++ } + 102 -> npcl(FacialExpression.OLD_HAPPY,"Me will sell you some golden wool, but me no sell you any golden apples!").also { stage++ } + 103 -> playerl(FacialExpression.HAPPY,"How much for the golden wool?").also { stage++ } + 104 -> npcl(FacialExpression.OLD_HAPPY,"Me want 1000 coins! You pay or go!").also { + stage = if(inInventory(player,Items.COINS_995,1000)){ + 105 + } + else 115 + } + 105 -> options("Pay","Don't pay").also { stage++ } + 106 -> when(buttonId){ + 1 -> playerl(FacialExpression.HAPPY,"Is that all? Here you go!").also { + removeItem(player,Item(Items.COINS_995,1000)) + addItem(player,Items.GOLDEN_FLEECE_3693) + stage++ + } + 2 -> npcl(FacialExpression.OLD_HAPPY,"You no pay, then you go! You no get any golden apples!").also { stage = 1000 } + } + 107 -> npcl(FacialExpression.OLD_HAPPY,"Ha! Stupid human think he buy golden apples, but he actually get stupid wool! Hahaha!").also { stage = 1000 } + + 115 -> playerl(FacialExpression.THINKING,"I don't even have that much cash on me...").also { stage++ } + 116 -> npcl(FacialExpression.OLD_NORMAL,"Well stupid bad trade human don't get no wool then! Or any golden apples!").also { stage = 1000 } + + 1000 -> end() + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(1270) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/LonghallStageZone.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/LonghallStageZone.kt new file mode 100644 index 0000000..0f94254 --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/LonghallStageZone.kt @@ -0,0 +1,40 @@ +package content.region.fremennik.rellekka.quest.thefremenniktrials + +import core.game.node.entity.Entity +import core.game.world.map.zone.MapZone +import core.game.world.map.zone.ZoneBorders +import core.game.world.map.zone.ZoneBuilder +import core.plugin.Initializable +import core.plugin.Plugin + +@Initializable +class LonghallStageZone : MapZone("LonghallStageZone",true), Plugin { + + override fun newInstance(arg: Any?): LonghallStageZone { + ZoneBuilder.configure(this) + return this + } + + override fun configure() { + super.register(ZoneBorders(2655,3682,2662,3685)) + } + + override fun enter(e: Entity?): Boolean { + if (e != null && e.isPlayer) { + e.setAttribute("onStage",true) + } + return super.enter(e) + } + + override fun leave(e: Entity?, logout: Boolean): Boolean { + if (e != null && e.isPlayer) { + e.removeAttribute("onStage") + } + return super.leave(e, logout) + } + + override fun fireEvent(identifier: String?, vararg args: Any?): Any { + return Unit + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/ManniDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/ManniDialogue.kt new file mode 100644 index 0000000..425c617 --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/ManniDialogue.kt @@ -0,0 +1,203 @@ +package content.region.fremennik.rellekka.quest.thefremenniktrials + +import core.api.addItem +import core.api.getQuestStage +import core.api.removeItem +import core.game.node.entity.impl.Animator +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.game.world.GameWorld +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.plugin.Initializable +import org.rs09.consts.Items +import content.data.Quests + +@Initializable +class ManniDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin(player){ + var curNPC: NPC? = NPC(0,Location(0,0,0)) + override fun open(vararg args: Any?): Boolean { + curNPC = args[0] as? NPC + if(player?.questRepository?.getStage(Quests.THE_FREMENNIK_TRIALS)!! > 0){ + if(player?.inventory?.contains(3707, 1) == true){ + playerl(core.game.dialogue.FacialExpression.HAPPY,"Hey. I got your cocktail for you.") + stage = 170 + return true + } + else if(player?.inventory?.contains(3706,1) == true){ + playerl(core.game.dialogue.FacialExpression.ASKING,"So it doesn't bother you at all that you just gave up your place here for one drink?") + stage = 180 + return true + } + else if(player?.getAttribute("sigmundreturning",false) == true){ + playerl(core.game.dialogue.FacialExpression.ASKING,"Is this trade item for you?") + stage = 165 + return true + } + else if(player?.getAttribute("sigmund-steps", 0) == 12){ + playerl(core.game.dialogue.FacialExpression.ASKING,"I don't suppose you have any idea where I could find the longhall barkeeps' legendary cocktail, do you?") + stage = 162 + return true + } + else if(player?.getAttribute("sigmund-steps", 0) == 11){ + playerl(core.game.dialogue.FacialExpression.ASKING,"I don't suppose you have any idea where I could find a token to allow a seat at the champions table, do you?") + stage = 150 + return true + } + else if(player?.getAttribute("fremtrials:manni-accepted",false) == true) { + if (player?.inventory?.containsItem(Item(3712)) == true || player?.inventory?.containsItem(Item(3711)) == true) { + npc("Ah, I see you have your keg of beer. Are ye ready to", "drink against each other?") + stage = 101 + return true + } else { + npc("Come back when you're ready to begin", "the contest.") + stage = 1000 + return true + } + } + else if (getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) > 0 && player?.getAttribute("fremtrials:manni-vote",false) == true) { + npc("Ye have my vote!") + stage = 1000 + return true + } + else if(player.questRepository.isComplete(Quests.THE_FREMENNIK_TRIALS)){ + playerl(core.game.dialogue.FacialExpression.HAPPY,"Howdy!") + stage = 190 + return true + } + player("Hello there!") + stage = 0 + return true + } + else { + playerl(core.game.dialogue.FacialExpression.HAPPY,"Hello there!") + stage = 200 + return true + } + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> {npc("Hello outerlander. I overheard your conversation with","Brundt just now. You wish to become a member of the","Fremennik?");stage++} + 1 -> {player("That's right! Why, are you on the counsel?");stage++} + 2 -> {npc("Do not let my drink-ssussed appearance fool you, I","earnt my place on the council many years past.I am","always glad to see new blood enter our tribe, and will","happily vote for you.");stage++} + 3 -> {player("Great!");stage++} + 4 -> {npc("Providing you can pass a little test for me. As a","Fremennik, you will need to show cunning, stamina,","fastitude, and an iron constitution. I know of only one","way to test all of these.");stage++} + 5 -> {player("And what's that?");stage++} + 6 -> {npc("Why, a drinking contest!");stage++} + 7 -> {npc("The task is simple enough! You versus me, a stiff drink","each, last man standing wins the trial. So what say you?");stage++} + 8 -> {options("Yes","No");stage++} + 9 -> when(buttonId){ + 1 -> {player("A drinking contest? Easy. Set them up, and I'll knock","them back.");stage++} + 2 -> {player("I don't like the sound of that.");stage = 12} + } + + //Yes + 10 -> {npc("When you are ready to begin, go and pick up a keg","from that table over there, and come back here.");stage++} + 11 -> {npc("We start when you have your keg of beer with you","and finish when one of us can drink no more and","yields.");stage = 1000;player?.setAttribute("/save:fremtrials:manni-accepted",true)} + + //No + 12 -> {npc("That's a shame."); stage = 1000} + + + //Begin drinking competition + 101 -> {options("Yes","No");stage++} + 102 -> when(buttonId){ + 1 -> {player("Yes, let's start this drinking contest!");stage++} + 2 -> {player("No, I don't think I am.");stage = 1000} + } + 103 -> {npc("As you wish outerlander; I will drink first, then you will","drink.");stage++} + 104 -> { + GameWorld.submit(DrinkingPulse(player,curNPC,player?.getAttribute("fremtrials:keg-mixed",false))); end()} + + //Sigmund stuff + 150 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"As a matter of fact, I do. I have one right here. I earnt my place here at the longhall for surviving over 5000 battles and raiding parties.").also { stage++ } + 151 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Due to my contribution to the tribe, I am now permitted to spend my days here in the longhall listening to the epic tales of the bard, and drinking beer.").also { stage++ } + 152 -> playerl(core.game.dialogue.FacialExpression.HAPPY,"Cool. That sounds pretty sweet! So I guess you don't want to give it away?").also { stage++ } + 153 -> npcl(core.game.dialogue.FacialExpression.SAD,"I think it sounds better than it actually is outerlander. I miss my glory days of combat on the battlefield.").also { stage++ } + 154 -> npcl(core.game.dialogue.FacialExpression.SAD,"And to tell you the truth, the beer here isn't great, and the bards' music is lousy. I would happily give up my token if it were not for the one thing that keeps me here.").also { stage++ } + 155 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Our barkeep is one of the best in the world, and has worked in taverns across the land. When she was younger, she experimented a lot with her drinks").also { stage++ } + 156 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"and invented a cocktail so alcoholic and tasty that it has become something of a legend to all who enjoy a drink.").also { stage++ } + 157 -> npcl(core.game.dialogue.FacialExpression.SAD,"Unfortunately, she decided that cocktails were not a suitable drink for Fremennik warriors, and vowed to never again make it.").also { stage++ } + 158 -> npcl(core.game.dialogue.FacialExpression.SAD,"I have been here every day since she returned, hoping that someday she might change her mind and I might try this legendary cocktail for myself. Alas, it has never come to pass...").also { stage++ } + 159 -> npcl(core.game.dialogue.FacialExpression.SAD,"If you can persuade her to make me her legendary cocktail, I will be happy to never let another drop of alcohol pass my lips, and will give you my champions token.").also { stage++ } + 160 -> playerl(core.game.dialogue.FacialExpression.THINKING,"That's all?").also { stage++ } + 161 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL,"That is all.").also { + player?.incrementAttribute("sigmund-steps",1) + stage = 1000 + } + 162 -> npcl(core.game.dialogue.FacialExpression.ANNOYED,"Uh... yes, the longhall barkeep has it. So could you get me my drink now please?").also { stage = 1000 } + + 165 -> npcl(core.game.dialogue.FacialExpression.ANNOYED,"Not me, no.").also { stage = 1000 } + 170 -> npcl(core.game.dialogue.FacialExpression.AMAZED,"...It is true! The legendary cocktail! I have waited for this day ever since I first started drinking!").also { + removeItem(player,3707) + addItem(player,3706) + stage++ + } + 171 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Here outerlander, you may take my token. I will happily give up my place at the longhalls table of champions just for a taste of this exquisite beverage!").also { stage++ } + 172 -> playerl(core.game.dialogue.FacialExpression.ASKING,"It's just a drink...").also { stage++ } + 173 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"No, it is an artform. A drink such as this should be appreciated, and admired.").also { stage++ } + 174 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"It is like a fine painting, or a tasteful sculpture. If what I hear is true, then all other drinks become like unpalatable water in comparison to this!").also { stage++ } + 175 -> playerl(core.game.dialogue.FacialExpression.HAPPY,"I guess you're happy with the trade then!").also { stage = 1000 } + + 180 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Ah, but it was not just any drink... It was the finest cocktail ever created! Now that I have tasted it, I need never drink again, for my tastebuds will never be so excited!").also { stage++ } + 181 -> playerl(core.game.dialogue.FacialExpression.ASKING,"So it was nice?").also { stage++ } + 182 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"It was... exquisite!").also { stage++ } + 183 -> playerl(core.game.dialogue.FacialExpression.ASKING,"What did it taste of, then?").also { stage++ } + 184 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Mostly tomato juice.").also { stage = 1000 } + + 190 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Hey! It's ${player.getAttribute("fremennikname","clyde smilers")}! Let me buy you a drink!").also { + addItem(player, Items.BEER_1917) + stage++ } + 191 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"There ya go! Anyone who can drink like you earns my respect!").also { stage = 1000 } + + 200 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Do not think me rude outerlander, but our customs forbid me talking to you. All contact with outerlanders must be vetted by our chieftain, Brundt.").also { stage++ } + 201 -> playerl(core.game.dialogue.FacialExpression.ASKING,"Where is this Brundt?").also { stage++ } + 202 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"He is standing just over there. He will speak for the tribe.").also { stage = 1000 } + + + 1000 -> end() + } + return true + } + + class DrinkingPulse(val player: Player?,val npc: NPC?, val lowAlcohol: Boolean? = false) : Pulse(){ + var counter = 0 + override fun pulse(): Boolean { + if(!lowAlcohol!!){ + when(counter++){ + 0 -> {player?.lock();npc?.lock(); npc?.isNeverWalks = true} + 1 -> {player?.face(npc); npc?.face(player)} + 3 -> npc?.animator?.animate(Animation(1330,Animator.Priority.HIGH)) + 5 -> {player?.animator?.animate(Animation(1330,Animator.Priority.HIGH)); player?.inventory?.remove(Item(3711))} + 7 -> player?.dialogueInterpreter?.sendDialogues(player, core.game.dialogue.FacialExpression.DRUNK,"Ish no fair!! I canna drink another drop! I alsho","feel veddy, veddy ill...") + 15 -> player?.dialogueInterpreter?.sendDialogues(npc, core.game.dialogue.FacialExpression.DRUNK,"I guessh I win then ouddaladder! (hic) Niche try,","anyway!") + 16 -> {player?.unlock(); npc?.unlock(); player?.face(player);npc?.face(npc); npc?.isNeverWalks = false; return true} + } + } else { + when(counter++){ + 0 -> {player?.lock();npc?.lock(); npc?.isNeverWalks = true} + 1 -> {player?.face(npc); npc?.face(player)} + 3 -> npc?.animator?.animate(Animation(1330,Animator.Priority.HIGH)) + 5 -> {player?.animator?.animate(Animation(1330,Animator.Priority.HIGH)); player?.inventory?.remove(Item(3711))} + 7 -> player?.dialogueInterpreter?.sendDialogues(player, core.game.dialogue.FacialExpression.HAPPY,"Aaaah, lovely stuff. So you want to get the next round","in, or shall I? You don't look so good there!") + 15 -> player?.dialogueInterpreter?.sendDialogues(npc, core.game.dialogue.FacialExpression.DRUNK,"Wassha? Guh? You drank that whole keg! But it dinnna","affect you at all! I conshede! You can probably","outdrink me!") + 21 -> player?.dialogueInterpreter?.sendDialogues(npc, core.game.dialogue.FacialExpression.DRUNK,"I jusht can't (hic) believe it! Thatsh shome might fine","drinking legs you got! Anyone who can drink like","THAT getsh my vote atta somsh.... coumah... gets my","vote!") + 22 -> {player?.unlock(); npc?.unlock(); player?.face(player);npc?.face(npc); npc?.isNeverWalks = false;player?.removeAttribute("fremtrials:cherrybomb");player?.removeAttribute("fremtrials:manni-accepted");player?.removeAttribute("fremtrials:keg-mixed"); player?.setAttribute("/save:fremtrials:manni-vote",true); player?.setAttribute("/save:fremtrials:votes",player.getAttribute("fremtrials:votes",0) + 1); return true} + } + } + return false + } + } + + override fun newInstance(player: Player?): core.game.dialogue.DialoguePlugin { + return ManniDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(1286) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/OlafTheBard.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/OlafTheBard.kt new file mode 100644 index 0000000..baffb11 --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/OlafTheBard.kt @@ -0,0 +1,166 @@ +package content.region.fremennik.rellekka.quest.thefremenniktrials + +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import content.data.Quests + +@Initializable +class OlafTheBard(player: Player? = null) : DialoguePlugin(player){ + override fun open(vararg args: Any?): Boolean { + if(player.inventory.contains(3700,1)){ + playerl(FacialExpression.HAPPY,"Hello Olaf. Do you have a beautiful love song written for me?") + stage = 65 + } + else if(player.inventory.contains(3699,1)){ + playerl(FacialExpression.ASKING,"So you think this song is pretty good then?") + stage = 70 + return true + } + else if(player?.getAttribute("sigmundreturning",false) == true){ + playerl(FacialExpression.ASKING,"I've got a trade item; is it for you?") + stage = 75 + return true + } + else if(player?.getAttribute("sigmund-steps",0) == 3){ + playerl(FacialExpression.ASKING,"I don't suppose you have any idea where I could find some custom sturdy boots, do you?") + stage = 60 + return true + } + else if(player?.getAttribute("sigmund-steps",0)!! == 2){ + playerl(FacialExpression.ASKING,"I don't suppose you have any idea where I could find a love ballad, do you?") + stage = 50 + return true + } + else if(player?.getAttribute("lyreConcertPlayed",false)!!){ + playerl(FacialExpression.HAPPY,"So can I rely on your vote with the council of elders in my favour?") + stage = 40 + return true + } + else if(player?.getAttribute("fremtrials:olaf-accepted",false)!!){ + npc("I can't wait to see your performance.") + stage = 1000 + return true + } + else if(player.questRepository.isComplete(Quests.THE_FREMENNIK_TRIALS)){ + npcl(FacialExpression.HAPPY,"Hello again to you, ${player.getAttribute("fremennikname","schlonko")}. Us bards should stick together, what can I do for you?") + stage = 98 + return true + } + else if(getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) > 0){ + npc("Hello? Yes? You want something outerlander?") + stage = 0 + return true + } + else{ + playerl(FacialExpression.HAPPY,"Hello there. So you're a bard?") + stage = 150 + return true + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> player("Are you a member of the council?").also { stage++ } + 1 -> npc("Why, indeed I am, outerlander! My talents as an","exemplary musician made it difficult for them not to","accept me! Why do you wish to know this?").also { stage++ } + 2 -> player("Well, I ask because I am currently doing the","Fremennik trials so as to join you clan. I need seven","of the twelve council of elders to vote for me.").also { stage++ } + 3 -> npc("Ahhh... and you wish to earn my vote? I will gladly","accept you as a Fremennik should you be able to prove","yourself to have a little musical ability!").also { stage++ } + 4 -> player("So how would I do that?").also { stage++ } + 5 -> npc("Why, by playing in our longhall! All you need to do is","impress the revellers there with a few verses of an epic","of your own creation!").also { stage++ } + 6 -> npc("So what say you outerlander? Are you up for the","challenge?").also { stage++ } + 7 -> options("Yes","No").also { stage++ } + 8 -> when(buttonId){ + 1 -> player("Sure! This certainly sounds pretty easy to accomplish.","I'll have your vote in no time!").also { stage++ } + 2 -> player("No, that sounds like too much work.").also { stage = 1000 } + } + + //Yes + 9 -> npc("That is great news outerlander! We always need more","music lovers here!").also { stage++;player?.setAttribute("/save:fremtrials:olaf-accepted",true) } + 10 -> player("So how would I go about writing this epic?").also { stage++ } + 11 -> npc("Well, first of all you are going to need an instrument.","Like all true bards you are going to have to make this","yourself.").also { stage++ } + 12 -> player("How do I make an instrument?").also { stage++ } + 13 -> npc("Well, it is a long and drawn-out process. Just east of","this village there is an unusually musical tree that can","be used to make very high quality instruments.").also { stage++ } + 14 -> npc("Cut a piece from it, and then carve it into a special","shape that will allow you to string it. Using a knife as","you would craft any other wooden object would be best","for this.").also { stage++ } + 15 -> player("Then what do I need to do?").also { stage++ } + 16 -> npc("Next you will need to string your lyre. There is a troll","to the South-east who has some golden wool. I would","not recommend using anything else to string your lyre","with.").also { stage++ } + 17 -> player("Anything else?").also { stage++ } + 18 -> npc("Well, when you have crafted your lyre you will need","the blessing of the Fossegrimen to tune your lyre to","perfection before you even consider a public","performance.").also { stage++ } + 19 -> player("Who or what is Fossegrimen?").also { stage++ } + 20 -> npc("Fossegrimen is a lake spirit that lives just a little way","South-west of this village. Make her an offering of fish,","and you will then be ready for your performance.").also { stage++ } + 21 -> npc("Make sure you give her a suitable offering however. If","the offering is found to be unworthy, then you may","find yourself unable to play your lyre with any skill at","all!").also { stage++ } + 22 -> player("So what would be a worthy offering?").also { stage++ } + 23 -> npc("A raw shark, manta ray, or sea turtle should be","sufficient as an offering.").also { stage++ } + 24 -> player("Ok, what else do I need to do?").also { stage++ } + 25 -> npc("When you have crafted your lyre and been blessed by","Fossegrimen, then you will finally be ready to make","your performance to the revellers at the longhall.").also { stage++ } + 26 -> npc("Head past the bouncers and onto the stage, and then","begin to play. If all goes well, you should find the music","spring to your mind and sing your own epic on the","spot").also { stage++ } + 27 -> npc("I will observe both you and the audience, and if you","show enough talent, I will happily vote in your favour at","the council of elders.").also { stage++ } + 28 -> npc("Is that clear enough, outerlander? Would you like me","to repeat anything?").also { stage++ } + 29 -> player("No thanks. I think I've got it.").also { stage = 1000 } + + 40 -> npcl(FacialExpression.HAPPY,"You have a truly poetic soul! Anyone who can compose such a beautiful epic, and then perform it so flawlessly can only bring good to our clan!").also { stage++ } + 41 -> playerl(FacialExpression.THINKING,"Erm... so that's a yes, then?").also { stage++ } + 42 -> npcl(FacialExpression.HAPPY,"Absolutely! We must collaborate together on a duet sometime, don't you think?").also { + setAttribute(player, "/save:fremtrials:olaf-vote",true) + setAttribute(player, "/save:fremtrials:votes",getAttribute(player, "fremtrials:votes",0) + 1) + stage = 1000 + } + + + //Sigmund bullshit + 50 -> npcl(FacialExpression.HAPPY," Well, as official Fremennik bard, it falls within my remit to compose all music for the tribe. I am fully versed in all the various types of romantic music.").also { stage++ } + 51 -> playerl(FacialExpression.HAPPY,"Great! Can you write me one then?").also { stage++ } + 52 -> npcl(FacialExpression.THINKING,"Well... Normally I would be thrilled at the chance to show my skill as a poet in composing a seductively romantic ballad...").also { stage++ } + 53 -> playerl(FacialExpression.ANNOYED,"Let me guess; Here comes the 'but'.").also { stage++ } + 54 -> npcl(FacialExpression.SAD,"...but unfortunately I cannot concentrate fully upon my work recently.").also { stage++ } + 55 -> playerl(FacialExpression.ASKING,"Why is that then?").also { stage++ } + 56 -> npcl(FacialExpression.NEUTRAL,"It is these old worn out shoes of mine... As a bard I am expected to wander the lands, singing of the glorious battles of our warriors.").also { stage++ } + 57 -> npcl(FacialExpression.NEUTRAL,"If you can find me a pair of sturdy boots to replace these old worn out ones of mine, I will be happy to spend the time on composing you a romantic ballad.").also { + player?.incrementAttribute("sigmund-steps",1) + stage = 1000 + } + 60 -> npcl(FacialExpression.ANNOYED,"I'm sorry outerlander... If I did, I would not trouble you to go and find them for me, would I?").also { stage = 1000 } + + 65 -> npcl(FacialExpression.HAPPY,"That depends outerlander... Do you have some new boots for me? My feet get so tired roaming the land...").also { stage++ } + 66 -> playerl(FacialExpression.HAPPY,"As a matter of fact - I do!").also { + removeItem(player,3700) + addItem(player,3699) + stage++ + } + 67 -> npcl(FacialExpression.HAPPY,"Oh! Superb! Those are great! They're just what I was looking for! Here, take this song with my compliments! It is one of my finest works yet!").also { stage = 1000 } + + 70 -> npcl(FacialExpression.HAPPY,"Ahhh.... outerlander... it is the most beautiful romantic ballad I have ever been inspired to write...").also { stage++ } + 71 -> npcl(FacialExpression.HAPPY,"Only a woman with a heart of icy stone could fail be to be moved by its beauty!").also { stage++ } + 72 -> playerl(FacialExpression.HAPPY,"Thanks! That sounds perfect!").also { stage = 1000 } + + 75 -> npcl(FacialExpression.HAPPY,"Only if it's a new pair of boots.").also { stage = 1000 } + + 98 -> options("I was wondering...","I forget now...").also { stage++ } + 99 -> when(buttonId){ + 1 -> playerl(FacialExpression.ASKING,"I was wondering... Can I learn to play my lyre again?").also { stage++ } + 2 -> playerl(FacialExpression.THINKING,"I forget now...").also { stage = 1000 } + } + + 100 -> npcl(FacialExpression.HAPPY, "Well that is an interesting question. Let me let you into a little secret. If you make another offering to the Fossegrimen you will learn a secret melody.").also { stage++ } + 101 -> playerl(FacialExpression.ASKING,"What kind of melody?").also { stage++ } + 102 -> npcl(FacialExpression.HAPPY,"It is the song of Rellekka. When you play it, it will bring you back to this town where you are in this world.").also { stage++ } + 103 -> npcl(FacialExpression.HAPPY,"We often go adventuring with bards for precisely this reason. No matter where we have ended up we can return safe and sound to home.").also { stage++ } + 104 -> playerl(FacialExpression.HAPPY,"Thanks, Olaf!").also { stage = 1000 } + + 150 -> npcl(FacialExpression.HAPPY,"I am afraid I cannot speak to outerlanders. Besides, I am busy composing an epic.").also { stage = 1000 } + + 1000 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return OlafTheBard(player) + } + + override fun getIds(): IntArray { + return intArrayOf(1269) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/PeerTheSeerDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/PeerTheSeerDialogue.kt new file mode 100644 index 0000000..58714b2 --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/PeerTheSeerDialogue.kt @@ -0,0 +1,262 @@ +package content.region.fremennik.rellekka.quest.thefremenniktrials + +import core.api.addItem +import core.api.dumpContainer +import core.api.getQuestStage +import core.api.removeItem +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.diary.DiaryType +import core.plugin.Initializable +import core.tools.RandomFunction +import core.tools.END_DIALOGUE +import kotlin.random.Random +import content.data.Quests + +@Initializable +class PeerTheSeerDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin(player) { + val predictionOne = arrayOf("one","two","three","four","five","six","seven","eight","ten") + val predictionTwo = arrayOf("black","blue","brown","cyan","green","pink","purple","red","yellow") + val predictionThree = arrayOf("fire giant","ghosts","giant","goblin","green dragon","hobgoblin","lesser demon","moss giant","ogre","zombie") + val predictionFour = arrayOf("Al Kharid","Ardougne","Burthorpe","Canifis","Catherby","Falador","Karamja","Varrock","The Wilderness","Yanille") + val predictionFive = arrayOf("battleaxe","crossbow","dagger","javelin","long sword","mace","scimitar","spear","warhammer") + val predictionSix = arrayOf("Agility","Cooking","Crafting","Fishing","Fletching","Herblore","Mining","Runecrafting","Thieving") + val PREDICTIONS = arrayOf( + "You will find luck today with the number ${predictionOne[RandomFunction.getRandom(8)]}.", + "The colour ${predictionTwo[RandomFunction.getRandom(8)]} will bring you luck this day.", + "The enemy called ${predictionThree[RandomFunction.getRandom(9)]} is your lucky totem this day.", + "The place called ${predictionFour[RandomFunction.getRandom(9)]} will be worth your time to visit.", + "The stars tell me that you should use a ${predictionFive[RandomFunction.getRandom(8)]} in combat today.", + "You would be wise to train the skill ${predictionSix[RandomFunction.getRandom(8)]}") + var prediction = RandomFunction.getRandom(5) + + override fun open(vararg args: Any?): Boolean { + if(player.inventory.contains(3710,1)){ + playerl(core.game.dialogue.FacialExpression.HAPPY,"Can I have a weather forecast now please?") + stage = 15 + return true + } + else if(player.inventory.contains(3705,1)){ + playerl(core.game.dialogue.FacialExpression.ASKING,"So, about this forecast...") + stage = 20 + return true + } + else if(player.getAttribute("sigmundreturning",false) == true){ + playerl(core.game.dialogue.FacialExpression.ASKING,"I've got an item to trade but I don't know if it's for you.") + stage = 26 + return true + } + else if(player.getAttribute("sigmund-steps", 0) == 10){ + playerl(core.game.dialogue.FacialExpression.ASKING,"I don't suppose you have any idea where I could find a brave and powerful warrior to act as a bodyguard?") + stage = 8 + return true + } + else if(player.getAttribute("sigmund-steps", 0) == 9){ + playerl(core.game.dialogue.FacialExpression.ASKING,"I don't suppose you have any idea where I could find a weather forecast from the Fremennik Seer do you?") + stage = 1 + return true + } + else if(player.getAttribute("PeerStarted",false) && !player.inventory.isEmpty || !player.equipment.isEmpty){ + npcl(core.game.dialogue.FacialExpression.SAD,"Uuuh... What was that dark presence I felt?") + stage = 100 + return true + } + else if(player.getAttribute("PeerStarted",false) && player.inventory.isEmpty && player.equipment.isEmpty){ + npcl(core.game.dialogue.FacialExpression.SAD,"Uuuh... What was that dark presence I felt?") + stage = 110 + return true + } + else if (getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) > 0 && player.getAttribute("fremtrials:peer-vote",false)) { + npcl(core.game.dialogue.FacialExpression.SAD,"Uuuh... What was that dark presence I felt?") + stage = 120 + return true + } + else if(player.questRepository.isComplete(Quests.THE_FREMENNIK_TRIALS)){ + npcl(core.game.dialogue.FacialExpression.SAD,"Uuuh... What was that dark presence I felt?") + stage = 150 + return true + } + else if(getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) > 0){ + npcl(core.game.dialogue.FacialExpression.SAD,"Uuuh... What was that dark presence I felt?") + stage = 50 + return true + } + if (getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) == 0) { + npc(core.game.dialogue.FacialExpression.SAD,"Uuuh... What was that dark presence I felt?").also { stage = 300 } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 1 -> npcl(core.game.dialogue.FacialExpression.ANNOYED,"Er.... Yes, because I AM the Fremennik Seer.").also { stage++ } + 2 -> playerl(core.game.dialogue.FacialExpression.ASKING,"Can I have a weather forecast then please?").also { stage++ } + 3 -> npcl(core.game.dialogue.FacialExpression.THINKING,"You require a divination of the weather? This is a simple matter for me, but I will require something in return from you for this small service.").also { stage++ } + 4 -> playerl(core.game.dialogue.FacialExpression.ASKING,"I knew you were going to say that...").also { stage++ } + 5 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Do not fret, outerlander; it is a fairly simple matter. I require a bodyguard for protection. Find someone willing to offer me this service.").also { stage++ } + 6 -> playerl(core.game.dialogue.FacialExpression.ASKING,"That's all?").also { stage++ } + 7 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"That is all.").also { + player?.incrementAttribute("sigmund-steps",1) + stage = 1000 + } + 10 -> npcl(core.game.dialogue.FacialExpression.ANNOYED,"If I did, then I would simply have asked them myself now, wouldn't I, outerlander?").also { stage = 1000 } + + 15 -> npcl(core.game.dialogue.FacialExpression.ANNOYED,"I have already told you outerlander; You may have a reading from me when I have a signed contract from a warrior guaranteeing my protection.").also { stage++ } + 16 -> playerl(core.game.dialogue.FacialExpression.HAPPY,"Yeah, I know; I have one right here from Thorvald.").also { + removeItem(player,3710) + addItem(player,3705) + stage++ + } + 17 -> npcl(core.game.dialogue.FacialExpression.AMAZED,"You have not only persuaded one of the Fremennik to act as a servant to me, but you have enlisted the aid of mighty Thorvald himself???").also { stage++ } + 18 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"You may take this forecast with my blessing outerlander. You have offered me the greatest security I can imagine.").also { stage = 1000 } + + 20 -> npcl(core.game.dialogue.FacialExpression.THINKING,"Yes, outerlander?").also { stage++ } + 21 -> playerl(core.game.dialogue.FacialExpression.ASKING,"I still don't know why you didn't just let me have one anyway in the first place. Surely it means nothing to you?").also { stage++ } + 22 -> npcl(core.game.dialogue.FacialExpression.THINKING,"That is not true, outerlander. Although I see glimpses of the future all of the time, using my powers brings the attention of the gods to me.").also { stage++ } + 23 -> npcl(core.game.dialogue.FacialExpression.THINKING,"Some of the gods are spiteful and cruel, and I fear if I use my powers too much then I will meet with unpredictable accidents.").also { stage++ } + 24 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"This is why I needed protection.").also { stage++ } + 25 -> playerl(core.game.dialogue.FacialExpression.THINKING,"Okay... I... think I understand...").also { stage = 1000 } + + 26 -> npcl(core.game.dialogue.FacialExpression.ANNOYED,"Not me, I'm afraid.").also { stage++ } + + //The Seer's Trial + 50 -> npcl(core.game.dialogue.FacialExpression.AMAZED,"!").also { stage++ } + 51 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Ahem, sorry about that. Hello outerlander. What do you want?").also { stage++ } + 52 -> playerl(core.game.dialogue.FacialExpression.ASKING,"Hello. I'm looking for members of the council of elders to vote for me to become a Fremennik.").also { stage++ } + 53 -> npcl(core.game.dialogue.FacialExpression.THINKING,"Are you now? Well that is interesting. Usually outerlanders do not concern themselves with our ways like that.").also { stage++ } + 54 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"I am one of the members of the council of elders, and should you be able to prove to me that you have something to offer my clan I will vote in your favour at the next meeting.").also { stage++ } + 55 -> playerl(core.game.dialogue.FacialExpression.ASKING,"How can I prove that to you?").also { stage++ } + 56 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Well, I have but a simple test. This building behind me is my house. Inside I have constructed a puzzle.").also { stage++ } + 57 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"As a Seer to the clan, I value intelligence very highly, so you may think of it as an intelligence test of sorts.").also { stage++ } + 58 -> playerl(core.game.dialogue.FacialExpression.THINKING,"An intelligence test? I thought barbarians were stupid!").also { stage++ } + 59 -> npcl(core.game.dialogue.FacialExpression.ANNOYED,"That is the opinion that outerlanders usually hold of my people, it is true. But that is because people often confuse knowledge with wisdom.").also { stage++ } + 60 -> npcl(core.game.dialogue.FacialExpression.ANNOYED,"My puzzle tests not what you know, but what you can work out. All members of our clan have been tested when they took their trials.").also { stage++ } + 61 -> playerl(core.game.dialogue.FacialExpression.ASKING,"So what exactly does this puzzle consist of, then?").also { stage++ } + 62 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Well, firstly you must enter my house with no items, weapons or armour. Then it is a simple matter of entering through one door and leaving by the other.").also { stage++ } + 63 -> playerl(core.game.dialogue.FacialExpression.ASKING,"I can't take anything in there with me?").also { stage++ } + 64 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"That is correct outerlander. Everything you need to complete the puzzle you will find inside the building. Nothing more.").also { stage++ } + 65 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"So what say you outerlander? You think you have the wit to earn yourself my vote?").also { stage++ } + 66 -> options("Yes","No").also { stage++ } + 67 -> when(buttonId){ + 1 ->{ playerl(core.game.dialogue.FacialExpression.HAPPY,"Yes, I accept your challenge, I have one small question, however...") + player?.setAttribute("/save:PeerStarted",true) + player?.setAttribute("/save:PeerRiddle", Random.nextInt(0,3)) + stage = 70 + } + 2 ->{ playerl(core.game.dialogue.FacialExpression.HAPPY,"No, thinking about stuff isn't really my 'thing'. I'd rather go kill something. I'll find someone else to vote for me") + stage++ + } + } + //No to challenge + 68 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"As you wish, outerlander.").also { stage = 1000 } + + //Yes to challenge + 70 -> npcl(core.game.dialogue.FacialExpression.ASKING,"Yes outerlander?").also { stage++ } + 71 -> playerl(core.game.dialogue.FacialExpression.THINKING,"Well... you say I can bring nothing with me when I enter your house...").also { stage++ } + 72 -> npcl(core.game.dialogue.FacialExpression.ANNOYED,"Yes outerlander??").also { stage++ } + 73 -> playerl(core.game.dialogue.FacialExpression.THINKING,"Well...").also { stage++ } + 74 -> npcl(core.game.dialogue.FacialExpression.ANGRY,"Yes, outerlander???").also { stage++ } + 75 -> playerl(core.game.dialogue.FacialExpression.ASKING,"Where is the nearest bank?").also { stage++ } + 76 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Ah, I see your problem outerlander. The nearest bank to here is the place known to outerlanders as the Seers Village.").also { stage++ } + 77 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"It is some way South. I do however have an alternative, should you wish to take it.").also { stage++ } + 78 -> playerl(core.game.dialogue.FacialExpression.ASKING,"And what is that?").also { stage++ } + 79 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"I can store all the weapons, armour and items that you have upon you directly into your bank account.").also { stage++ } + 80 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"This will tax what little magic I possess however, so you will have to travel to the bank to withdraw them again.").also { stage++ } + 81 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"What say you outerlander? Do you wish me to do this for you?").also { stage++ } + 82 -> options("Yes","No").also { stage++ } + 83 -> when(buttonId){ + 1 -> { + val slotAmount = player.inventory.itemCount() + player.equipment.itemCount() + if (slotAmount < player.bank.freeSlots()){ + npcl(core.game.dialogue.FacialExpression.HAPPY,"The task is done. I wish you luck with your test, outerlander.") + dumpContainer(player,player.inventory) + dumpContainer(player,player.equipment) + stage = 1000 + } + else { + npcl(core.game.dialogue.FacialExpression.SAD,"I am sorry outerlander, the spell is not working. I believe you may have some objects that you cannot bank with you") + stage = 1000 + } + } + 2 -> playerl(core.game.dialogue.FacialExpression.HAPPY,"No thanks. Nobody touches my stuff but me!").also { stage++ } + } + + //No to banking + 84 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"As you wish, outerlander. You may attempt my little task when you have deposited your equipment in the bank").also { + stage = 1000 + } + + //Yes to banking but cannot bank + 90 -> npcl(core.game.dialogue.FacialExpression.SAD,"I am sorry outerlander, the spell is not working. I believe you may have some objects that you cannot bank with you").also { + stage = 1000 + } + + //Returning after accepting with items. + 100 -> npcl(core.game.dialogue.FacialExpression.AMAZED,"!").also { stage++ } + 101 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Ahem, sorry about that. Hello outerlander. What do you want?").also { stage++ } + 102 -> playerl(core.game.dialogue.FacialExpression.ASKING,"So I can bring nothing with me when I enter your house?").also { stage++ } + 103 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"That is correct outerlander, but as I say, I can use my small skill in magic to send your items directly into your bank account from here.").also { stage++ } + 104 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"You will need to manually go to the bank to withdraw them again however.").also { stage++ } + 105 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Would you like me to perform this small spell upon you, outerlander?").also { stage = 82 } + + //Returning after accepting without items. + 110 -> npcl(core.game.dialogue.FacialExpression.AMAZED,"!").also { stage++ } + 111 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Ahem, sorry about that. Hello outerlander. What do you want?").also { stage++ } + 112 -> playerl(core.game.dialogue.FacialExpression.ASKING,"So I just have to enter by one door of your house, and leave by the other?").also { stage++ } + 113 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"That is correct outerlander. Be warned it is not as easy as it may at first sound...").also { stage = 1000 } + + //After completing the Seer's Trial. + 120 -> npcl(core.game.dialogue.FacialExpression.AMAZED,"!").also { stage++ } + 121 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Ahem, sorry about that.").also { stage++ } + 122 -> playerl(core.game.dialogue.FacialExpression.HAPPY,"So you will vote for me at the council?").also { stage++ } + 123 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Absolutely, outerlander. Your wisdom in passing my test marks you as worthy in my eyes.").also { stage = 1000 } + + + //After The Fremennik Trials + 150 -> npcl(core.game.dialogue.FacialExpression.AMAZED,"!").also { stage++ } + 151 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Ahem, sorry about that.").also { + stage = if(player.achievementDiaryManager.getDiary(DiaryType.FREMENNIK).isComplete(0)){ + 200 + }else 152 + } + 152 -> playerl(core.game.dialogue.FacialExpression.HAPPY,"Hello Peer.").also { stage++ } + 153 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Greetings to you, brother ${player.getAttribute("fremennikname","dingle")}! What brings you to see me again?").also { stage++ } + 154 -> options("Can you tell my future?","Nothing really.").also{stage++} + 155 -> when(buttonId){ + 1 -> playerl(core.game.dialogue.FacialExpression.ASKING,"I was wondering if you could give me a reading on my future...?").also { stage++ } + 2 -> playerl(core.game.dialogue.FacialExpression.HAPPY,"Nothing really, I just stopped by to say hello").also { stage = 160 } + } + 156 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Ah, you would like a prediction? I do not see that that would be so difficult... Wait a moment...").also { + stage++ + } + 157 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Here is your prediction: ${PREDICTIONS[prediction]}").also { stage = 1000 } + + 160 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Well, hello to you too!").also { stage = 1000 } + + + 200 -> options("Deposit service","Can you tell my future?","Nothing really.").also{ stage++ } + 201 -> when(buttonId){ + 1 -> playerl(core.game.dialogue.FacialExpression.HAPPY,"Could you deposit some things for me, please?").also { stage++ } + 2 -> playerl(core.game.dialogue.FacialExpression.ASKING,"I was wondering if you could give me a reading on my future...?").also { stage = 156 } + 3 -> playerl(core.game.dialogue.FacialExpression.HAPPY,"Nothing really, I just stopped by to say hello").also { stage = 160 } + } + 202 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Of course, ${player.getAttribute("fremennikname","dingle")}. I am always happy to aid those who have earned the right to wear Fremennik sea boots.").also { + player.bank.openDepositBox() + stage = 1000 + } + + 300 -> npc(core.game.dialogue.FacialExpression.NEUTRAL,"!").also { stage++ } + 301 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL,"Ahem, sorry about that. I have no interest in talking to you just now outerlander.").also { stage = END_DIALOGUE } + + 1000 -> end() + } + return true + } + + override fun newInstance(player: Player?): core.game.dialogue.DialoguePlugin { + return PeerTheSeerDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(1288) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/PoisonSalesman.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/PoisonSalesman.kt new file mode 100644 index 0000000..f214c66 --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/PoisonSalesman.kt @@ -0,0 +1,104 @@ +package content.region.fremennik.rellekka.quest.thefremenniktrials + +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import content.data.Quests + +@Initializable +class PoisonSalesman(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + options("Talk about the Murder Mystery Quest","Talk about the The Fremennik Trials") + stage = START_DIALOGUE + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + //val murderMysteryStage = player.questRepository.isComplete(Quests.MURDER_MYSTERY) + val fremennikTrialsStage = player.questRepository.getStage(Quests.THE_FREMENNIK_TRIALS) + + when (stage) { + START_DIALOGUE -> when (buttonId) { + 1 -> { player("Err... nevermind"); stage = END_DIALOGUE } + 2 -> { player("Hello."); stage = 10 } + } + + //The Fremennik Trials + 10 -> { + /**when (fremennikTrialsStage) { + 0 -> { npc("Come see me if you ever need low-alcohol beer!"); stage = END_DIALOGUE } + }*/ + if(fremennikTrialsStage == 0){ + npc("Come see me if you ever need low-alcohol beer!"); stage = END_DIALOGUE + } + else if(fremennikTrialsStage > 30){ + npc("Thanks for buying out all that low-alcohol beer!"); stage = END_DIALOGUE + } else if(fremennikTrialsStage > 0){ + npc("Howdy! You seem like someone with discerning taste!","Howsabout you try my brand new range of alcohol?"); stage++ + } + } + 11 -> { player("Didn't you used to sell poison?"); stage++ } + 12 -> { npc("That I did indeed! Peter Potter's Patented","Multipurpose poison! A miracle of modern apothecarys!","My exclusive concoction has been tested on..."); stage++ } + 13 -> { player("Uh, yeah. I've already heard the sales pitch."); stage++ } + 14 -> { npc("Sorry stranger, old habits die hard I guess."); stage++ } + 15 -> { player("So you don't sell poison anymore?"); stage++ } + 16 -> { npc("Well I would, but I ran out of stock. Business wasn't","helped with that stuff that happened up at the Sinclair","Mansion much either, I'll be honest."); stage++ } + 17 -> { npc("So, being the man of enterprise that I am I decided to","branch out a little bit!"); stage++ } + 18 -> { player("Into alcohol?"); stage++ } + 19 -> { npc("Absolutely! The basic premise between alcohol and poison","is pretty much the same, after all! The difference is that","my alcohol has a unique property others do not!"); stage++ } + 20 -> { player("And what is that?"); stage++ } + 21 -> { sendDialogue("The salesman takes a deep breath."); stage++ } + 22 -> { npc("Ever been too drunk to find your own home? Ever","wished that you could party away all night long, and","still wake up fresh as a daisy the next morning?"); stage++ } + 23 -> { npc("Thanks to the miracles of modern magic we have come","up with just the solution you need! Peter Potter's","Patented Party Potions!"); stage++ } + 24 -> { npc("It looks just like beer! It tastes just like beer! It smells","just like beer! But... it's not beer!"); stage++ } + 25 -> { npc("Our mages have mused for many moments to bring","you this miracle of modern magic! It has all the great","tastes you'd expect, but contains absolutely no alcohol!"); stage++ } + 26 -> { npc("That's right! You can drink Peter Potter's Patented","Party Potion as much as you want, and suffer","absolutely no ill effects whatsoever!"); stage++ } + 27 -> { npc("The clean fresh taste you know you can trust, from","the people who brought you: Peter Potters Patented","multipurpose poison, Pete Potters peculiar paint packs"); stage++ } + 28 -> { npc("and Peter Potters paralyzing panic pins. Available now","from all good stockists! Ask your local bartender now,","and experience the taste revolution of the century!"); stage++ } + 29 -> { sendDialogue("He seems to have finished for the time being."); stage++ } + 30 -> { player("So.. when you say 'all good stockists'..."); stage++ } + 31 -> { npc("Yes?"); stage++ } + 32 -> { player("How many inns actually sell this stuff?"); stage++ } + 33 -> { npc("Well.. nobody has actually bought any yet. Everyone I","try and sell it to always asks me what exactly the point","of beer that has absolutely no effect on you is."); stage++ } + 34 -> { player("So what is the point?"); stage++ } + 35 -> { npc("Well... Um... Er... Hmmm. You, er, don't get drunk."); stage++ } + 36 -> { player("I see..."); stage++ } + 37 -> { npc("Aw man.. you don't want any now do you? I've really","tried to push this product, but I just don't think the","world is ready for beer that doesn't get you drunk."); stage++ } + 38 -> { npc("I'm a man ahead of my time I tell you! It's not that","my products are bad, it's that they're too good for the","market!"); stage++ } + 39 -> { player("Actually, I would like some. How much do you want for it?"); stage++ } + 40 -> { npc("Y-you would??? Um, okay! I knew I still had the old","salesmans skills going on!"); stage++ } + 41 -> { npc("I will sell you a keg of it for only 250 gold pieces! So","What do you say?"); stage++ } + 42 -> { options("Yes","No"); stage++ } + 43 -> when(buttonId){ + 1 -> { player("Yes please!"); stage++ } + 2 -> { player("No, thanks."); stage = END_DIALOGUE } + } + //Yes + 44 -> if(player?.inventory?.containsItem(Item(995,250)) == true){ + player?.inventory?.remove(Item(995,250)) + player?.inventory?.add(Item(3712)) + npc("Here you go.") + stage = END_DIALOGUE + } else { + player("I don't seem to have enough.") + stage++ + } + 45 -> { npc("Well come back when you do!"); stage = END_DIALOGUE } + END_DIALOGUE -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return PoisonSalesman(player) + } + + override fun getIds(): IntArray { + return intArrayOf(820) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/SeerLockInterfaceListener.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/SeerLockInterfaceListener.kt new file mode 100644 index 0000000..6be622d --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/SeerLockInterfaceListener.kt @@ -0,0 +1,165 @@ +package content.region.fremennik.rellekka.quest.thefremenniktrials + +import core.api.sendMessage +import core.game.interaction.InterfaceListener + +class SeerLockInterfaceListener : InterfaceListener { + + override fun defineInterfaceListeners() { + val LETTERONEBACK = 39 + val LETTERONEFORWARD = 40 + val LETTERTWOBACK = 35 + val LETTERTWOFORWARD = 36 + val LETTERTHREEBACK = 31 + val LETTERTHREEFORWARD = 32 + val LETTERFOURBACK = 27 + val LETTERFOURFORWARD = 28 + val ENTER = 1 + val EXIT = 2 + val DOORLOCKINTERFACE = 298 + val LETTERS = arrayOf("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z") +// + onOpen(DOORLOCKINTERFACE){player, component -> + player.packetDispatch.sendVarcUpdate(618, 0) + player.packetDispatch.sendVarcUpdate(619, 0) + player.packetDispatch.sendVarcUpdate(620, 0) + player.packetDispatch.sendVarcUpdate(621, 0) + player.packetDispatch.sendIfaceSettings(0, 2, 298, 0, 1) + player.setAttribute("riddle-letter-one",0) + player.setAttribute("riddle-letter-two",0) + player.setAttribute("riddle-letter-three",0) + player.setAttribute("riddle-letter-four",0) + return@onOpen true + } +// + onClose(DOORLOCKINTERFACE){player, component -> + player.removeAttribute("riddle-letter-one") + player.removeAttribute("riddle-letter-two") + player.removeAttribute("riddle-letter-three") + player.removeAttribute("riddle-letter-four") + return@onClose true + } +// + on(DOORLOCKINTERFACE){player, component, opcode, buttonID, slot, itemID -> + when(buttonID){ + LETTERONEBACK ->{ + if(player.getAttribute("riddle-letter-one",0) == 0){ + player.setAttribute("riddle-letter-one",25) + } + else{ + (player.incrementAttribute("riddle-letter-one",-1)) + } + } + LETTERONEFORWARD ->{ + if(player.getAttribute("riddle-letter-one",0) == 25){ + player.setAttribute("riddle-letter-one",0) + } + else{ + (player.incrementAttribute("riddle-letter-one",1)) + } + } + LETTERTWOBACK ->{ + if(player.getAttribute("riddle-letter-two",0) == 0){ + player.setAttribute("riddle-letter-two",25) + } + else{ + (player.incrementAttribute("riddle-letter-two",-1)) + } + } + LETTERTWOFORWARD ->{ + if(player.getAttribute("riddle-letter-two",0) == 25){ + player.setAttribute("riddle-letter-two",0) + } + else{ + (player.incrementAttribute("riddle-letter-two",1)) + } + } + LETTERTHREEBACK ->{ + if(player.getAttribute("riddle-letter-three",0) == 0){ + player.setAttribute("riddle-letter-three",25) + } + else{ + (player.incrementAttribute("riddle-letter-three",-1)) + } + } + LETTERTHREEFORWARD ->{ + if(player.getAttribute("riddle-letter-three",0) == 25){ + player.setAttribute("riddle-letter-three",0) + } + else{ + (player.incrementAttribute("riddle-letter-three",1)) + } + } + LETTERFOURBACK ->{ + if(player.getAttribute("riddle-letter-four",0) == 0){ + player.setAttribute("riddle-letter-four",25) + } + else{ + (player.incrementAttribute("riddle-letter-four",-1)) + } + } + LETTERFOURFORWARD ->{ + if(player.getAttribute("riddle-letter-four",0) == 25){ + player.setAttribute("riddle-letter-four",0) + } + else{ + (player.incrementAttribute("riddle-letter-four",1)) + } + } + ENTER -> { + val letterOne = LETTERS[player.getAttribute("riddle-letter-one", 0)] + val letterTwo = LETTERS[player.getAttribute("riddle-letter-two", 0)] + val letterThree = LETTERS[player.getAttribute("riddle-letter-three", 0)] + val letterFour = LETTERS[player.getAttribute("riddle-letter-four", 0)] + when (player.getAttribute("PeerRiddle", 0)) { + 0 -> { + if (letterOne == "L" && letterTwo == "I" && letterThree == "F" && letterFour == "E") { + sendMessage(player, "You have solved the riddle!") + player.removeAttribute("PeerRiddle") + player.setAttribute("/save:riddlesolved", true) + player.interfaceManager.close() + } else { + sendMessage(player, "You have failed to solve the riddle.") + player.interfaceManager.close() + } + } + 1 -> { + if (letterOne == "M" && letterTwo == "I" && letterThree == "N" && letterFour == "D") { + sendMessage(player, "You have solved the riddle!") + player.removeAttribute("PeerRiddle") + player.setAttribute("/save:riddlesolved", true) + player.interfaceManager.close() + } else { + sendMessage(player, "You have failed to solve the riddle.") + player.interfaceManager.close() + } + } + 2 -> { + if (letterOne == "T" && letterTwo == "I" && letterThree == "M" && letterFour == "E") { + sendMessage(player, "You have solved the riddle!") + player.removeAttribute("PeerRiddle") + player.setAttribute("/save:riddlesolved", true) + player.interfaceManager.close() + } else { + sendMessage(player, "You have failed to solve the riddle.") + player.interfaceManager.close() + } + } + 3 -> { + if (letterOne == "W" && letterTwo == "I" && letterThree == "N" && letterFour == "D") { + sendMessage(player, "You have solved the riddle!") + player.removeAttribute("PeerRiddle") + player.setAttribute("/save:riddlesolved", true) + player.interfaceManager.close() + } else { + sendMessage(player, "You have failed to solve the riddle.") + player.interfaceManager.close() + } + } + } + } + } + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/SeersHouseListeners.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/SeersHouseListeners.kt new file mode 100644 index 0000000..684eece --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/SeersHouseListeners.kt @@ -0,0 +1,1076 @@ +package content.region.fremennik.rellekka.quest.thefremenniktrials + +import content.data.Quests +import core.api.* +import core.game.node.entity.impl.Animator +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.audio.Audio +import core.game.node.scenery.Scenery +import core.game.node.scenery.SceneryBuilder +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items +import core.game.dialogue.DialogueFile +import core.game.global.action.DoorActionHandler +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import org.rs09.consts.NPCs +import org.rs09.consts.Sounds + +class SeersHouseListeners : InteractionListener { + + val WESTDOOR = 4165 + val EASTDOOR = 4166 + val WESTLADDER = 4163 + val EASTLADDER = 4164 + val WESTTRAPDOOR = getScenery(2631, 3663, 2)!! + val EASTTRAPDOOR = getScenery(2636, 3663, 2)!! + val TAP = 4176 + val COOKINGRANGE = 4172 + val DRAIN = 4175 + val CUPBOARD = 4178 + val BALANCECHEST = 4170 + val UNICORNHEAD = 4181 + val SOUTHBOXES = 4183 + val CHEST = intArrayOf (4167,4168) + val SOUTHCRATES = 4186 + val EASTCRATES = 4185 + val EASTBOXES = 4184 + val FROZENTABLE = 4169 + val BOOKCASE = 4171 + val BULLSHEAD = 4182 + val MURAL = 4179 + + val OLDREDDISK = Items.OLD_RED_DISK_9947 + val WOODENDISK = Items.WOODEN_DISK_3744 + val REDHERRING = Items.RED_HERRING_3742 + val BLUETHREAD = Items.THREAD_3719 + val PICK = Items.PICK_3720 + val SHIPTOY = Items.SHIP_TOY_3721 + val MAGNET = Items.MAGNET_3718 + val REDGOOP = Items.STICKY_RED_GOOP_3746 + val REDDISK = Items.RED_DISK_3743 + val VASELID = Items.VASE_LID_3737 + val VASE = Items.VASE_3734 + val FULLVASE = Items.VASE_OF_WATER_3735 + val FROZENVASE = Items.FROZEN_VASE_3736 + val SEALEDEMPTYVASE = Items.SEALED_VASE_3738 + val SEALEDFULLVASE = Items.SEALED_VASE_3739 + val FROZENKEY = Items.FROZEN_KEY_3741 + val SEERSKEY = Items.SEERS_KEY_3745 + val EMPTYBUCKET = Items.EMPTY_BUCKET_3727 + val ONEFIFTHBUCKET = Items.ONE_5THS_FULL_BUCKET_3726 + val TWOFIFTHBUCKET = Items.TWO_5THS_FULL_BUCKET_3725 + val THREEFIFTHBUCKET = Items.THREE_5THS_FULL_BUCKET_3724 + val FOURFIFTHBUCKET = Items.FOUR_5THS_FULL_BUCKET_3723 + val FULLBUCKET = Items.FULL_BUCKET_3722 + val FROZENBUCKET = Items.FROZEN_BUCKET_3728 + val EMPTYJUG = Items.EMPTY_JUG_3732 + val ONETHIRDJUG = Items.ONE_THIRDRDS_FULL_JUG_3731 + val TWOTHIRDJUG = Items.TWO_THIRDSRDS_FULL_JUG_3730 + val FULLJUG = Items.FULL_JUG_3729 + val FROZENJUG = Items.FROZEN_JUG_3733 + + val JUGS = intArrayOf( + Items.EMPTY_JUG_3732, + Items.ONE_THIRDRDS_FULL_JUG_3731, + Items.TWO_THIRDSRDS_FULL_JUG_3730, + Items.FULL_JUG_3729 + ) + + val BUCKETS = intArrayOf( + Items.EMPTY_BUCKET_3727, + Items.ONE_5THS_FULL_BUCKET_3726, + Items.TWO_5THS_FULL_BUCKET_3725, + Items.THREE_5THS_FULL_BUCKET_3724, + Items.FOUR_5THS_FULL_BUCKET_3723, + Items.FULL_BUCKET_3722 + ) + + val DISKS = intArrayOf( + Items.OLD_RED_DISK_9947, + Items.RED_DISK_3743 + ) + + val EASTZONE = ZoneBorders(2635, 3662, 2637, 3664, 2) + + val WESTZONE = ZoneBorders(2630, 3662, 2632, 3664, 2) + + override fun defineListeners() { + + on(WESTDOOR, IntType.SCENERY, "open"){ player, node -> + if(!player.getAttribute("PeerStarted",false)){ + sendDialogue(player,"You should probably talk to the owner of this home.") + } + if (getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) > 0 && getAttribute(player, "fremtrials:peer-vote", false)) + { + sendDialogue(player, "I don't need to go through that again.") + return@on true + } + else if(player.getAttribute("PeerRiddle",5) < 5){ + player.dialogueInterpreter.open(DoorRiddleDialogue(player), Scenery(WESTDOOR,node.location)) + } + else if(player.getAttribute("riddlesolved",false)) { + val insideHouse = (player.location == Location.create(2631, 3666, 0)) + if(insideHouse) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + player.inventory.clear() + } else if(player.inventory.isEmpty && player.equipment.isEmpty) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else { + openDialogue(player, NPCs.PEER_THE_SEER_1288, findNPC(NPCs.PEER_THE_SEER_1288)!!) + } + } + return@on true + } + + on(WESTLADDER, IntType.SCENERY, "Climb-up") { player, node -> + core.game.global.action.ClimbActionHandler.climb(player, Animation(828), Location.create(2631, 3664, 2)) + return@on true + } + + on(WESTTRAPDOOR.id, IntType.SCENERY, "Climb-down") { player, node -> + if(player.location.x < 2634){ + core.game.global.action.ClimbActionHandler.climb(player, Animation(828), Location.create(2631, 3664, 0)) + } + else if(player.location.x > 2634){ + core.game.global.action.ClimbActionHandler.climb(player, Animation(828), Location.create(2636, 3664, 0)) + } + return@on true + } + + on(WESTTRAPDOOR.id, IntType.SCENERY, "Close") { player, node -> + SceneryBuilder.replace(node.asScenery(), node.asScenery().transform(4174)) + return@on true + } + + on(WESTTRAPDOOR.id, IntType.SCENERY, "Open") { player, node -> + SceneryBuilder.replace(node.asScenery(), node.asScenery().transform(4173)) + return@on true + } + + on(EASTTRAPDOOR.id, IntType.SCENERY, "Open") { player, node -> + SceneryBuilder.replace(node.asScenery(), node.asScenery().transform(4173)) + return@on true + } + + on(EASTTRAPDOOR.id, IntType.SCENERY, "Close") { player, node -> + SceneryBuilder.replace(node.asScenery(), node.asScenery().transform(4174)) + return@on true + } + + on(EASTTRAPDOOR.id, IntType.SCENERY, "Climb-down") { player, node -> + if(player.location.x > 2634){ + core.game.global.action.ClimbActionHandler.climb(player, Animation(828), Location.create(2636, 3664, 0)) + } + return@on true + } + + on(EASTLADDER, IntType.SCENERY, "Climb-Up") { player, node -> + core.game.global.action.ClimbActionHandler.climb(player, Animation(828), Location.create(2636, 3664, 2)) + return@on true + } + + on(CUPBOARD, IntType.SCENERY, "Search") { player, node -> + sendMessage(player,"You search the cupboard...") + if(player.inventory.contains(EMPTYBUCKET,1)){ + sendMessage(player,"You find nothing of interest.") + } + else{ + addItem(player,EMPTYBUCKET) + sendMessage(player,"You find a bucket with a number five painted on it.") + } + return@on true + } + + on(BALANCECHEST, IntType.SCENERY, "Open") { player, node -> + sendDialogue(player,"This chest is securely locked shut. There is some kind of balance attached to the lock, and a number four is painted just above it.") + return@on true + } + + on(BOOKCASE, IntType.SCENERY, "Search") { player, node -> + sendMessage(player,"You search the bookcase...") + if(player.inventory.contains(REDHERRING,1)){ + sendMessage(player,"You find nothing of interest.") + } + else{ + addItem(player,REDHERRING) + sendMessage(player,"Hidden behind some old books, you find a red herring.") + } + return@on true + } + + on(SOUTHBOXES, IntType.SCENERY, "Search"){ player, node -> + sendMessage(player,"You search the boxes...") + if(player.inventory.contains(BLUETHREAD,1)){ + sendMessage(player,"You find nothing of interest.") + } + else{ + addItem(player,BLUETHREAD) + sendMessage(player,"You find some thread hidden inside.") + } + return@on true + } + + on(CHEST, IntType.SCENERY, "Open"){ player, node -> + SceneryBuilder.replace(node.asScenery(), node.asScenery().transform(4168)) + return@on true + } + + on(CHEST, IntType.SCENERY, "Close"){ player, node -> + SceneryBuilder.replace(node.asScenery(), node.asScenery().transform(4167)) + return@on true + } + + on(CHEST, IntType.SCENERY, "Search"){ player, node -> + sendMessage(player,"You search the chest...") + if(player.inventory.contains(EMPTYJUG,1)){ + sendMessage(player,"You find nothing of interest.") + } + else{ + addItem(player,EMPTYJUG) + sendMessage(player,"You find a jug with a number three painted on it") + } + return@on true + } + + on(EASTCRATES, IntType.SCENERY, "Search") { player, node -> + sendMessage(player,"You search the crates...") + if(player.inventory.contains(PICK,1)){ + sendMessage(player,"You find nothing of interest.") + } + else{ + addItem(player,PICK) + sendMessage(player,"You find a small pick hidden inside.") + } + return@on true + } + + on(SOUTHCRATES, IntType.SCENERY, "Search") { player, node -> + sendMessage(player,"You search the crates...") + if(player.inventory.contains(SHIPTOY,1)){ + sendMessage(player,"You find nothing of interest.") + } + else{ + addItem(player,SHIPTOY) + sendMessage(player,"You findd a toy ship hidden inside") + } + return@on true + } + + on(BULLSHEAD, IntType.SCENERY, "Study") { player, node -> + player.dialogueInterpreter.open(BullHeadDialogue(player)) + return@on true + } + + on(UNICORNHEAD, IntType.SCENERY, "Study") { player, node -> + player.dialogueInterpreter.open(UnicornHeadDialogue(player)) + return@on true + } + + onUseWith(IntType.SCENERY,REDHERRING,COOKINGRANGE) { player, used, with -> + player.animate(Animation(883,Animator.Priority.HIGH)) + playAudio(player, Sounds.FRY_2577) + removeItem(player,REDHERRING) + addItem(player,REDGOOP) + sendDialogue(player,"As you cook the herring on the stove, the colouring on it peels off separately as a red sticky goop...") + return@onUseWith true + } + + onUseWith(IntType.ITEM,REDGOOP,WOODENDISK) { player, used, with -> + removeItem(player, WOODENDISK) + removeItem(player, REDGOOP) + addItem(player,REDDISK) + sendMessage(player,"You coat the wooden coin with the sticky red goop.") + return@onUseWith true + } + + on(MURAL, IntType.SCENERY, "Study") { player, node -> + sendMessage(player,"The mural feels like something is missing.") + return@on true + } + + onUseWith(IntType.SCENERY, BUCKETS, TAP) { player, bucket, _ -> + when(bucket.id){ + 3727 ->{ + removeItem(player,EMPTYBUCKET) + addItem(player,FULLBUCKET) + sendMessage(player,"You fill the bucket from the tap.") + return@onUseWith true + } + ONEFIFTHBUCKET ->{ + removeItem(player,ONEFIFTHBUCKET) + addItem(player,FULLBUCKET) + sendMessage(player,"You fill the bucket from the tap.") + } + TWOFIFTHBUCKET ->{ + removeItem(player,TWOFIFTHBUCKET) + addItem(player,FULLBUCKET) + sendMessage(player,"You fill the bucket from the tap.") + } + THREEFIFTHBUCKET ->{ + removeItem(player,THREEFIFTHBUCKET) + addItem(player,FULLBUCKET) + sendMessage(player,"You fill the bucket from the tap.") + } + FOURFIFTHBUCKET ->{ + removeItem(player,FOURFIFTHBUCKET) + addItem(player,FULLBUCKET) + sendMessage(player,"You fill the bucket from the tap.") + } + FULLBUCKET ->{ + sendMessage(player,"The bucket is already full!") + } + else -> sendMessage(player,"FUCKFUCKFUCKFUCK") + } + return@onUseWith true + } + + onUseWith(IntType.SCENERY, JUGS, TAP) { player, used, with -> + when(used.id){ + EMPTYJUG ->{ + removeItem(player,EMPTYJUG) + addItem(player,FULLJUG) + sendMessage(player,"You fill the jug from the tap.") + } + ONETHIRDJUG ->{ + removeItem(player,ONETHIRDJUG) + addItem(player,FULLJUG) + sendMessage(player,"You fill the jug from the tap.") + } + TWOTHIRDJUG ->{ + removeItem(player,TWOTHIRDJUG) + addItem(player,FULLJUG) + sendMessage(player,"You fill the jug from the tap.") + } + FULLJUG ->{ + sendMessage(player,"The jug is already full!") + } + } + return@onUseWith true + } + + onUseWith(IntType.SCENERY, BUCKETS, DRAIN) { player, used, with -> + when(used.id){ + EMPTYBUCKET ->{ + sendMessage(player,"The bucket is already empty!") + } + ONEFIFTHBUCKET ->{ + removeItem(player,ONEFIFTHBUCKET) + addItem(player,EMPTYBUCKET) + sendMessage(player,"You empty the bucket down the drain.") + } + TWOFIFTHBUCKET ->{ + removeItem(player,TWOFIFTHBUCKET) + addItem(player,EMPTYBUCKET) + sendMessage(player,"You empty the bucket down the drain.") + } + THREEFIFTHBUCKET ->{ + removeItem(player,THREEFIFTHBUCKET) + addItem(player,EMPTYBUCKET) + sendMessage(player,"You empty the bucket down the drain.") + } + FOURFIFTHBUCKET ->{ + removeItem(player,FOURFIFTHBUCKET) + addItem(player,EMPTYBUCKET) + sendMessage(player,"You empty the bucket down the drain.") + } + FULLBUCKET ->{ + removeItem(player,FULLBUCKET) + addItem(player,EMPTYBUCKET) + sendMessage(player,"You empty the bucket down the drain.") + } + } + return@onUseWith true + } + + onUseWith(IntType.SCENERY, JUGS, DRAIN) { player, used, with -> + when(used.id){ + EMPTYJUG ->{ + sendMessage(player,"The jug is already empty!") + } + ONETHIRDJUG ->{ + removeItem(player,ONETHIRDJUG) + addItem(player,EMPTYJUG) + sendMessage(player,"You empty the jug down the drain.") + } + TWOTHIRDJUG ->{ + removeItem(player,TWOTHIRDJUG) + addItem(player,EMPTYJUG) + sendMessage(player,"You empty the jug down the drain.") + } + FULLJUG ->{ + removeItem(player,FULLJUG) + addItem(player,EMPTYJUG) + sendMessage(player,"You empty the jug down the drain.") + } + } + return@onUseWith true + } + + onUseWith(IntType.SCENERY, FOURFIFTHBUCKET, BALANCECHEST) { player, used, with -> + removeItem(player,FOURFIFTHBUCKET) + addItem(player,VASE) + sendMessage(player,"You place the bucket on the scale.") + sendMessage(player,"It is a perfect counterweight and balances precisely.") + sendMessage(player,"You take a strange looking vase out of the chest.") + return@onUseWith true + } + + onUseWith(IntType.SCENERY, DISKS, MURAL) { player, used, with -> + when(used.id){ + REDDISK ->{ + if(player.getAttribute("olddiskplaced",false)){ + removeItem(player,REDDISK) + addItem(player,VASELID) + sendDialogue(player,"You put the red disk into the empty hole on the mural. It is a perfect fit! The centre of the mural appears to have become loose.") + } + else if(player.getAttribute("reddiskplaced",false)){ + sendMessage(player,"You already have a disk in that spot") + } + else{ + removeItem(player, REDDISK) + sendMessage(player,"You put the red disk into the empty hold on the mural.") + sendMessage(player, "It's a perfect fit!") + player.setAttribute("reddiskplaced",true) + } + } + OLDREDDISK -> { + if(player.getAttribute("reddiskplaced", false)) { + removeItem(player, OLDREDDISK) + addItem(player, VASELID) + sendDialogue(player, "You put the red disk into the empty hole on the mural. It is a perfect fit! The centre of the mural appears to have become loose.") + } + else if(player.getAttribute("olddiskplaced", false)) { + sendMessage(player, "You already have a disk in that spot") + } + else{ + removeItem(player, OLDREDDISK) + sendMessage(player, "You put the red disk into the empty hold on the mural.") + sendMessage(player, "It's a perfect fit!") + player.setAttribute("olddiskplaced", true) + } + } + } + return@onUseWith true + } + + onUseWith(IntType.SCENERY, BUCKETS, BALANCECHEST) { player, used, with -> + when(used.id){ + EMPTYBUCKET ->{ + player.animate(Animation(883,Animator.Priority.HIGH)) + sendMessage(player,"You place the bucket on the scale") + sendMessage(player,"It is too light to balance it properly") + } + ONEFIFTHBUCKET ->{ + player.animate(Animation(883,Animator.Priority.HIGH)) + sendMessage(player,"You place the bucket on the scale") + sendMessage(player,"It is too light to balance it properly") + } + TWOFIFTHBUCKET ->{ + player.animate(Animation(883,Animator.Priority.HIGH)) + sendMessage(player,"You place the bucket on the scale") + sendMessage(player,"It is too light to balance it properly") + } + THREEFIFTHBUCKET ->{ + player.animate(Animation(883,Animator.Priority.HIGH)) + sendMessage(player,"You place the bucket on the scale") + sendMessage(player,"It is too light to balance it properly") + } + FOURFIFTHBUCKET ->{ + player.animate(Animation(883,Animator.Priority.HIGH)) + sendMessage(player,"You place the bucket on the scale") + sendMessage(player,"It is a perfect counterweight and balances precisely.") + sendMessage(player,"You take a strange looking vase out of the chest.") + addItem(player,VASE) + } + FULLBUCKET ->{ + player.animate(Animation(883,Animator.Priority.HIGH)) + sendMessage(player,"You place the bucket on the scale") + sendMessage(player,"It is too heavy to balance it properly") + } + } + return@onUseWith true + } + + onUseWith(IntType.SCENERY, JUGS, BALANCECHEST) { player, used, with -> + when(used.id){ + EMPTYJUG ->{ + player.animate(Animation(883,Animator.Priority.HIGH)) + sendMessage(player,"You place the jug on the scale") + sendMessage(player,"It is too light to balance it properly") + } + ONETHIRDJUG ->{ + player.animate(Animation(883,Animator.Priority.HIGH)) + sendMessage(player,"You place the jug on the scale") + sendMessage(player,"It is too light to balance it properly") + } + TWOTHIRDJUG ->{ + player.animate(Animation(883,Animator.Priority.HIGH)) + sendMessage(player,"You place the jug on the scale") + sendMessage(player,"It is too light to balance it properly") + } + FULLJUG ->{ + player.animate(Animation(883,Animator.Priority.HIGH)) + sendMessage(player,"You place the jug on the scale") + sendMessage(player,"It is too light to balance it properly") + } + } + return@onUseWith true + } + + onUseWith(IntType.SCENERY, BUCKETS, FROZENTABLE) { player, used, with -> + when(used.id){ + EMPTYBUCKET -> sendMessage(player,"Your empty bucket gets very cold on the icy table.") + FULLBUCKET -> { + player.animate(Animation(883,Animator.Priority.HIGH)) + removeItem(player,FULLBUCKET) + addItem(player,FROZENBUCKET) + sendMessage(player,"They icy table immediately freezes the water in your bucket.") + } + } + return@onUseWith true + } + + onUseWith(IntType.SCENERY, JUGS, FROZENTABLE) { player, used, with -> + when(used.id){ + EMPTYJUG -> sendMessage(player,"Your empty jug gets very cold on the icy table.") + FULLJUG -> { + player.animate(Animation(883,Animator.Priority.HIGH)) + removeItem(player,FULLJUG) + addItem(player,FROZENJUG) + sendMessage(player,"The icy table immediately freezes the water in your jug.") + } + } + return@onUseWith true + } + + onUseWith(IntType.ITEM,BUCKETS,*JUGS) { player, used, with -> + when(used.id){ + ONEFIFTHBUCKET -> { + when(with.id){ + EMPTYJUG ->{ + removeItem(player,ONEFIFTHBUCKET) + removeItem(player,EMPTYJUG) + addItem(player,EMPTYBUCKET) + addItem(player,ONETHIRDJUG) + sendMessage(player,"You empty the bucket into the jug") + } + ONETHIRDJUG ->{ + removeItem(player,ONEFIFTHBUCKET) + removeItem(player,ONETHIRDJUG) + addItem(player,EMPTYBUCKET) + addItem(player,TWOTHIRDJUG) + sendMessage(player,"You empty the bucket into the jug") + } + TWOTHIRDJUG ->{ + removeItem(player,ONEFIFTHBUCKET) + removeItem(player,TWOTHIRDJUG) + addItem(player,EMPTYBUCKET) + addItem(player,FULLJUG) + sendMessage(player,"You fill the jug to the brim.") + } + FULLJUG -> sendMessage(player,"The jug is already full!") + } + } + TWOFIFTHBUCKET -> { + when(with.id){ + EMPTYJUG ->{ + removeItem(player,TWOFIFTHBUCKET) + removeItem(player,EMPTYJUG) + addItem(player,EMPTYBUCKET) + addItem(player,TWOTHIRDJUG) + sendMessage(player,"You empty the bucket into the jug") + } + ONETHIRDJUG ->{ + removeItem(player,TWOFIFTHBUCKET) + removeItem(player,ONETHIRDJUG) + addItem(player,EMPTYBUCKET) + addItem(player,FULLJUG) + sendMessage(player,"You fill the jug to the brim.") + } + TWOTHIRDJUG ->{ + removeItem(player,TWOFIFTHBUCKET) + removeItem(player,TWOTHIRDJUG) + addItem(player,ONEFIFTHBUCKET) + addItem(player,FULLJUG) + sendMessage(player,"You fill the jug to the brim.") + } + FULLJUG ->sendMessage(player,"The jug is already full!") + } + } + THREEFIFTHBUCKET -> { + when(with.id){ + EMPTYJUG ->{ + removeItem(player,THREEFIFTHBUCKET) + removeItem(player,EMPTYJUG) + addItem(player,EMPTYBUCKET) + addItem(player,FULLJUG) + sendMessage(player,"You fill the jug to the brim.") + } + ONETHIRDJUG ->{ + removeItem(player,THREEFIFTHBUCKET) + removeItem(player,ONETHIRDJUG) + addItem(player,ONEFIFTHBUCKET) + addItem(player,FULLJUG) + sendMessage(player,"You fill the jug to the brim.") + } + TWOTHIRDJUG ->{ + removeItem(player,THREEFIFTHBUCKET) + removeItem(player,TWOTHIRDJUG) + addItem(player,TWOFIFTHBUCKET) + addItem(player,FULLJUG) + sendMessage(player,"You fill the jug to the brim.") + } + FULLJUG ->sendMessage(player,"The jug is already full!") + } + } + FOURFIFTHBUCKET -> { + when(with.id){ + EMPTYJUG ->{ + removeItem(player,FOURFIFTHBUCKET) + removeItem(player,EMPTYJUG) + addItem(player,ONEFIFTHBUCKET) + addItem(player,FULLJUG) + sendMessage(player,"You fill the jug to the brim.") + } + ONETHIRDJUG ->{ + removeItem(player,FOURFIFTHBUCKET) + removeItem(player,ONETHIRDJUG) + addItem(player,TWOFIFTHBUCKET) + addItem(player,FULLJUG) + sendMessage(player,"You fill the jug to the brim.") + } + TWOTHIRDJUG ->{ + removeItem(player,FOURFIFTHBUCKET) + removeItem(player,TWOTHIRDJUG) + addItem(player,THREEFIFTHBUCKET) + addItem(player,FULLJUG) + sendMessage(player,"You fill the jug to the brim.") + } + FULLJUG ->sendMessage(player,"The jug is already full!") + } + } + FULLBUCKET -> { + when(with.id){ + EMPTYJUG ->{ + removeItem(player,FULLBUCKET) + removeItem(player,EMPTYJUG) + addItem(player,TWOFIFTHBUCKET) + addItem(player,FULLJUG) + sendMessage(player,"You fill the jug to the brim.") + } + ONETHIRDJUG ->{ + removeItem(player,FULLBUCKET) + removeItem(player,ONETHIRDJUG) + addItem(player,THREEFIFTHBUCKET) + addItem(player,FULLJUG) + sendMessage(player,"You fill the jug to the brim.") + } + TWOTHIRDJUG ->{ + removeItem(player,FULLBUCKET) + removeItem(player,TWOTHIRDJUG) + addItem(player,FOURFIFTHBUCKET) + addItem(player,FULLJUG) + sendMessage(player,"You fill the jug to the brim.") + } + FULLJUG ->sendMessage(player,"The jug is already full!") + } + } + } + return@onUseWith true + } + + onUseWith(IntType.ITEM,JUGS,*BUCKETS) { player, used, with -> + when(used.id){ + ONETHIRDJUG->{ + when(with.id){ + EMPTYBUCKET ->{ + removeItem(player,ONETHIRDJUG) + removeItem(player,EMPTYBUCKET) + addItem(player,EMPTYJUG) + addItem(player,ONEFIFTHBUCKET) + sendMessage(player,"You empty the jug into the bucket.") + } + ONEFIFTHBUCKET ->{ + removeItem(player,ONETHIRDJUG) + removeItem(player,ONEFIFTHBUCKET) + addItem(player,EMPTYJUG) + addItem(player,TWOFIFTHBUCKET) + sendMessage(player,"You empty the jug into the bucket.") + } + TWOFIFTHBUCKET ->{ + removeItem(player,ONETHIRDJUG) + removeItem(player,TWOFIFTHBUCKET) + addItem(player,EMPTYJUG) + addItem(player,THREEFIFTHBUCKET) + sendMessage(player,"You empty the jug into the bucket.") + } + THREEFIFTHBUCKET ->{ + removeItem(player,ONETHIRDJUG) + removeItem(player,THREEFIFTHBUCKET) + addItem(player,EMPTYJUG) + addItem(player,FOURFIFTHBUCKET) + sendMessage(player,"You empty the jug into the bucket.") + } + FOURFIFTHBUCKET ->{ + removeItem(player,ONETHIRDJUG) + removeItem(player,FOURFIFTHBUCKET) + addItem(player,EMPTYJUG) + addItem(player,FULLBUCKET) + sendMessage(player,"You fill the bucket to the brim.") + } + FULLBUCKET -> sendMessage(player,"The bucket is already full!") + } + } + TWOTHIRDJUG->{ + when(with.id){ + EMPTYBUCKET ->{ + removeItem(player,TWOTHIRDJUG) + removeItem(player,EMPTYBUCKET) + addItem(player,TWOFIFTHBUCKET) + addItem(player,EMPTYJUG) + sendMessage(player,"You empty the jug into the bucket.") + } + ONEFIFTHBUCKET ->{ + removeItem(player,TWOTHIRDJUG) + removeItem(player,ONEFIFTHBUCKET) + addItem(player,THREEFIFTHBUCKET) + addItem(player,EMPTYJUG) + sendMessage(player,"You empty the jug into the bucket.") + } + TWOFIFTHBUCKET ->{ + removeItem(player,TWOTHIRDJUG) + removeItem(player,TWOFIFTHBUCKET) + addItem(player,FOURFIFTHBUCKET) + addItem(player,EMPTYJUG) + sendMessage(player,"You empty the jug into the bucket.") + } + THREEFIFTHBUCKET ->{ + removeItem(player,TWOTHIRDJUG) + removeItem(player,THREEFIFTHBUCKET) + addItem(player,FULLBUCKET) + addItem(player,EMPTYJUG ) + sendMessage(player,"You fill the bucket to the brim.") + } + FOURFIFTHBUCKET ->{ + removeItem(player,TWOTHIRDJUG) + removeItem(player,FOURFIFTHBUCKET) + addItem(player,FULLBUCKET) + addItem(player,ONETHIRDJUG) + sendMessage(player,"You fill the bucket to the brim.") + } + FULLBUCKET -> sendMessage(player,"The bucket is already full!") + } + } + FULLJUG->{ + when(with.id){ + EMPTYBUCKET ->{ + removeItem(player,FULLJUG) + removeItem(player,EMPTYBUCKET) + addItem(player,THREEFIFTHBUCKET) + addItem(player,EMPTYJUG) + sendMessage(player,"You empty the jug into the bucket.") + } + ONEFIFTHBUCKET ->{ + removeItem(player,FULLJUG) + removeItem(player,ONEFIFTHBUCKET) + addItem(player,FOURFIFTHBUCKET) + addItem(player,EMPTYJUG) + sendMessage(player,"You empty the jug into the bucket.") + } + TWOFIFTHBUCKET ->{ + removeItem(player,FULLJUG) + removeItem(player,TWOFIFTHBUCKET) + addItem(player,FULLBUCKET) + addItem(player,EMPTYJUG) + sendMessage(player,"You fill the bucket to the brim.") + } + THREEFIFTHBUCKET ->{ + removeItem(player,FULLJUG) + removeItem(player,THREEFIFTHBUCKET) + addItem(player,FULLBUCKET) + addItem(player,ONETHIRDJUG) + sendMessage(player,"You fill the bucket to the brim.") + } + FOURFIFTHBUCKET ->{ + removeItem(player,FULLJUG) + removeItem(player,FOURFIFTHBUCKET) + addItem(player,FULLBUCKET) + addItem(player,TWOTHIRDJUG) + sendMessage(player,"You fill the bucket to the brim.") + } + FULLBUCKET -> sendMessage(player,"The bucket is already full!") + } + } + } + return@onUseWith true + } + + on(VASE, IntType.ITEM, "Shake") { player, node -> + sendDialogue(player,"You shake the strangely shaped Vase. From the sound of it there is something metallic inside, but the neck of th vase is too narrow for it to come out.") + return@on true + } + + onUseWith(IntType.ITEM,PICK,VASE) { player, used, with -> + sendMessage(player,"The pick wouldn't be strong enough to break the vase open.") + return@onUseWith true + } + + onUseWith(IntType.ITEM,MAGNET,VASE) { player, used, with -> + sendMessage(player,"You use the magnet on the vase. The metallic object inside moves.") + sendMessage(player,"The neck of the vase is too thin for thee object to come out of the vase.") + return@onUseWith true + } + + onUseWith(IntType.SCENERY, VASE, TAP) { player, used, with -> + removeItem(player,VASE) + addItem(player,FULLVASE) + sendMessage(player,"You fill the strange looking vase with water.") + return@onUseWith true + } + + onUseWith(IntType.ITEM,FULLJUG,VASE) { player, used, with -> + removeItem(player,FULLJUG) + removeItem(player,VASE) + addItem(player,EMPTYJUG) + addItem(player,FULLVASE) + sendMessage(player,"You fill the vase with water.") + return@onUseWith true + } + + on(FULLVASE, IntType.ITEM, "Shake") { player, node -> + sendDialogue(player,"You shake the strangely shaped vase. The water inside it sloshes a little. Some spills out of the neck of the vase.") + return@on true + } + + onUseWith(IntType.ITEM,VASE,VASELID) { player, used, with -> + removeItem(player,VASE) + removeItem(player,VASELID) + addItem(player,SEALEDEMPTYVASE) + sendMessage(player,"You screw the lid on tightly.") + return@onUseWith true + } + + onUseWith(IntType.ITEM,FULLVASE,VASELID) { player, used, with -> + removeItem(player,FULLVASE) + removeItem(player,VASELID) + addItem(player,SEALEDFULLVASE) + sendMessage(player,"You screw the lid on tightly.") + return@onUseWith true + } + + on(SEALEDEMPTYVASE, IntType.ITEM, "Remove-lid") { player, node -> + removeItem(player,SEALEDEMPTYVASE) + addItem(player,VASE) + addItem(player,VASELID) + sendMessage(player,"You unscrew the lid from the vase.") + return@on true + } + + on(SEALEDFULLVASE, IntType.ITEM, "Remove-lid") { player, node -> + removeItem(player,SEALEDFULLVASE) + addItem(player,VASE) + addItem(player,VASELID) + sendMessage(player,"You unscrew the lid from the vase.") + return@on true + } + + onUseWith(IntType.SCENERY, FULLVASE, FROZENTABLE) { player, used, with -> + player.animate(Animation(883,Animator.Priority.HIGH)) + removeItem(player,FULLVASE) + addItem(player,FROZENVASE) + sendMessage(player,"The icy table immediately freezes the water in your vase.") + return@onUseWith true + } + + onUseWith(IntType.SCENERY, SEALEDFULLVASE, FROZENTABLE) { player, used, with -> + player.animate(Animation(883,Animator.Priority.HIGH)) + removeItem(player,SEALEDFULLVASE) + addItem(player,FROZENKEY) + sendMessage(player,"The water expands as it freezes, and shatters the vase.") + sendMessage(player,"You are left with a key encased in ice.") + return@onUseWith true + } + + onUseWith(IntType.SCENERY, FROZENBUCKET, COOKINGRANGE) { player, used, with -> + player.animate(Animation(883,Animator.Priority.HIGH)) + playAudio(player, Sounds.FRY_2577) + removeItem(player,FROZENBUCKET) + addItem(player,EMPTYBUCKET) + sendMessage(player,"You place the frozen bucket on the range. The ice turns to steam.") + return@onUseWith true + } + + onUseWith(IntType.SCENERY, FROZENJUG, COOKINGRANGE) { player, used, with -> + player.animate(Animation(883,Animator.Priority.HIGH)) + playAudio(player, Sounds.FRY_2577) + removeItem(player,FROZENJUG) + addItem(player,EMPTYJUG) + sendMessage(player,"You place the frozen jug on the range. The ice turns to steam.") + return@onUseWith true + } + + onUseWith(IntType.SCENERY, FROZENVASE, COOKINGRANGE) { player, used, with -> + player.animate(Animation(883,Animator.Priority.HIGH)) + playAudio(player, Sounds.FRY_2577) + removeItem(player,FROZENVASE) + addItem(player,VASE) + sendMessage(player,"You place the frozen vase on the range. The ice turns into steam.") + return@onUseWith true + } + + onUseWith(IntType.SCENERY, FROZENKEY, COOKINGRANGE) { player, used, with -> + player.animate(Animation(883,Animator.Priority.HIGH)) + playAudio(player, Sounds.FRY_2577) + removeItem(player,FROZENKEY) + addItem(player,SEERSKEY) + sendMessage(player,"The heat of the range melts the ice around the key.") + return@onUseWith true + } + + on(EASTDOOR, IntType.SCENERY, "Open") { player, node -> + if(player.inventory.contains(SEERSKEY,1)){ + player.setAttribute("/save:housepuzzlesolved",true) + player.inventory.clear() + DoorActionHandler.handleAutowalkDoor(player,node.asScenery()) + player.setAttribute("/save:fremtrials:peer-vote",true) + player.setAttribute("/save:fremtrials:votes",player.getAttribute("fremtrials:votes",0) + 1) + sendNPCDialogue(player,1288,"Incredible! To have solved my puzzle so quickly! I have no choice but to vote in your favour!") + } + else sendMessage(player,"This door is locked tightly shut.") + return@on true + } + + } +} + +class BullHeadDialogue(player:Player) : DialogueFile() { + + private val WOODENDISK = Items.WOODEN_DISK_3744 + + val p = player + + override fun handle(componentID: Int, buttonID: Int) { + when(stage){ + 0 -> sendDialogue(p,"You notice there is something unusual about the right eye of this bulls' head...").also { + if(p.inventory.contains(WOODENDISK,1)){ + stage = 10 + }else stage = 1 + } + 1 -> sendDialogue(p,"It is not an eye at all, but some kind of disk made of wood. You take it from the head").also { + addItem(p,WOODENDISK) + stage = 1000 + } + 10 -> sendMessage(p,"It's unusual because you've already taken it!").also { stage = 1000 } + 1000 -> end() + } + } +} + +class UnicornHeadDialogue(player:Player) : DialogueFile() { + + private val OLDREDDISK = Items.OLD_RED_DISK_9947 + + val p = player + + override fun handle(componentID: Int, buttonID: Int) { + when(stage){ + 0 -> sendDialogue(p,"You notice there is something unusual about the left eye of this unicorn head...").also { + if(p.inventory.contains(OLDREDDISK,1)){ + stage = 10 + }else stage = 1 + } + 1 -> sendDialogue(p,"It is not an eye at all, but some kind of redd coloured disk. You take it from the head").also { + addItem(p,OLDREDDISK) + stage = 1000 + } + 10 -> sendMessage(p,"It's unusual because you've already taken it!").also { stage = 1000 } + 1000 -> end() + } + } +} + +class DoorRiddleDialogue(player: Player) : DialogueFile() { + + private val RIDDLEONE = arrayOf( + "My first is in the well, but not at sea.", + "My second in 'I', but not in 'me'.", + "My third is in flies, but insects not found.", + "My last is in earth, but not in the ground.", + "My whole when stolen from you, caused you death.", + "What am I?" + ) + + private val RIDDLETWO = arrayOf( + "My first is in mage, but not in wizard.", + "My second in goblin, and also in lizard.", + "My third is in night, but not in the day.", + "My last is in fields, but not in the hay.", + "My whole is the most powerful tool you will ever possess.", + "What am I?" + ) + + private val RIDDLETHREE = arrayOf( + "My first is in water, and also in tea.", + "My second in fish, but not in the sea.", + "My third in mountains, but not underground.", + "My last is in strike, but not in pound.", + "My whole crushes mountains, drains rivers, and destroys civilisations.", + "All that live fear my passing.", + "What am I?" + ) + + private val RIDDLEFOUR = arrayOf( + "My first is in wizard, but not in a mage.", + "My second in jail, but not in a cage.", + "My third is in anger, but not in a rage.", + "My last in a drawing, but not on a page.", + "My whole helps to make bread, let birds fly and boats sail.", + "What am I?" + ) + + private val RIDDLEANSWER = arrayOf("LIFE","MIND","TIME","WIND") + + val p = player + + val riddle = when(p.getAttribute("PeerRiddle",0)){ + 0 -> RIDDLEONE + 1 -> RIDDLETWO + 2 -> RIDDLETHREE + 3 -> RIDDLEFOUR + else -> RIDDLEONE + } + + var init = true + + override fun handle(componentID: Int, buttonID: Int) { + if(init){ + stage = 1 + init = false + } + when(stage){ + 1 -> sendDialogue(player!!,"There is a combination lock on this door. Above the lock you can see that there is a metal plaque with a riddle on it.").also { stage = 5 } + 5 -> options("Read the riddle","Solve the riddle","Forget it").also { stage = 10 } + 10 -> when(buttonID){ + 1 -> dialogue(riddle[0],riddle[1],riddle[2],riddle[3]).also { stage = 20 } + 2 -> { + openInterface(p,298) + end() + } + 3 -> end() + } + 15 ->{ + dialogue(riddle[0],riddle[1],riddle[2],riddle[3]) + stage = 20 + } + 20 -> if(riddle.contentEquals(RIDDLETHREE)){ + dialogue(riddle[4],riddle[5],riddle[6]).also { stage = 1000 } + }else{ + dialogue(riddle[4],riddle[5]).also { stage = 1000 } + } + 1000 -> end() + } + } +} diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/SigliTheHuntsman.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/SigliTheHuntsman.kt new file mode 100644 index 0000000..3ccd4e4 --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/SigliTheHuntsman.kt @@ -0,0 +1,160 @@ +package content.region.fremennik.rellekka.quest.thefremenniktrials + +import core.api.addItem +import core.api.getQuestStage +import core.api.removeItem +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import content.data.Quests + +@Initializable +class SigliTheHuntsman(player: Player? = null) : DialoguePlugin(player){ + override fun open(vararg args: Any?): Boolean { + if(player?.inventory?.contains(3702,1) == true){ + npcl(FacialExpression.HAPPY,"Greetings outerlander.") + stage = 165 + return true + } + else if(player?.inventory?.contains(3701,1) == true){ + playerl(FacialExpression.ASKING,"So you really don't mind giving this away to me?") + stage = 170 + return true + } + else if(player?.getAttribute("sigmundreturning",false) == true){ + playerl(FacialExpression.ASKING,"I have an item to trade.") + stage = 175 + return true + } + if(player?.getAttribute("sigmund-steps", 0) == 6){ + npcl(FacialExpression.HAPPY,"Greetings outerlander.") + stage = 160 + return true + } + else if(player?.getAttribute("sigmund-steps", 0) == 5){ + npcl(FacialExpression.HAPPY,"Greetings outerlander.") + stage = 150 + return true + } + else if (getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) > 0 && player?.getAttribute("fremtrials:sigli-vote",false)!!) { + npc("You have my vote!") + stage = 1000 + return true + } + if(player?.getAttribute("fremtrials:draugen-killed",false)!!){ + npc("I saw the entire hunt. Let me take that talisman from","you, I would be honored to speak out for you to our","council of elders after such a hunt, outerlander.") + stage = 100 + return true + } + else if(player.questRepository.isComplete(Quests.THE_FREMENNIK_TRIALS)){ + playerl(FacialExpression.HAPPY,"Hello again Sigli.") + stage = 180 + return true + } + else if(getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) > 0){ + npc("What do you want outerlander?") + stage = 0 + return true + } + else{ + npcl(FacialExpression.HAPPY,"I do not speak to outerlanders. If you have anything of import to say, go and speak to the Chieftain.") + stage = 1000 + return true + } + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> player("Are you a member of the council?").also{stage++} + 1 -> npc("The Fremennik council of elders? I am pleased to say","that I am. My value as a huntsman is recognized by","my position there.").also { stage++ } + 2 -> player("I was wondering if I could persuade you to vouch for","me as a member of your clan?").also { stage++ } + 3 -> npc("You? ... well... I am not totally against the idea","outerlander. If you can demonstrate some hunting skills","then perhaps I may offer my vote.").also { stage++ } + 4 -> player("How can I prove my hunting skills to you? I can go","kill, like, a hundred chickens for you right now!").also { stage++ } + 5 -> npc("Chickens? You think that would impress me?").also { stage++ } + 6 -> player("Cows then? I can kill cows until, er, the cows come","home.").also { stage++ } + 7 -> npc("No. The prey I have in mind for you to prove your","worth to me is something far more dangerous. Far","more difficult. Far more deadly.").also { stage++ } + 8 -> player("Not... Giant Rats?!?!").also { stage++ } + 9 -> npc("I suspect you are mocking me outerlander. You will","need to prove your skill as a hunter to me by tracking","and defeating... The Draugen.").also { stage++ } + 10 -> options("What's a Draugen?","Forget it.").also { stage++ } + 11 -> when(buttonId){ + 1 -> player("What's a Draugen? Some kind of cheap rip-","off of a dragon?").also { stage++ } + 2 -> player("Forget it.").also { stage = 1000 } + } + + //What's a Draugen + 12 -> npc("Hmmm.. No, the words are slightly similar I suppose,","but they are very different creatures.").also { stage++ } + 13 -> npc("The Draugen is an evil ghost from Fremennik","mythology, that devours souls of those brave","warriors who meet their ends at sea.").also { stage++ } + 14 -> npc("It stalks the coastlines, invisible to all. It brings us bad","fortunes, and curses our journeys across the seas. It is","also unkillable by normal means.").also { stage++ } + 15 -> player("...Let me get this straight; You want me to hunt an","unkillable, invincible, and invisible enemy? How am I","supposed to do that?").also { stage++ } + 16 -> npc("Well outerlander, should you accept my challenge I will","show you a special hunter's trick that will help you. Do","you accept the challenge?").also { stage++ } + 17 -> options("Yes","No").also { stage++ } + 18 -> when(buttonId){ + 1 -> player("Well, I need every vote I can get in the council of","elders, but this certainly sounds impossible to do...").also { stage++ } + 2 -> player("No, I don't think I will.").also { stage = 1000 } + } + + //Yes + 19 -> npc("Not at all outerlander. The Draugen is indeed","impossible to kill but that is not the same as being","impossible to fight against.").also { stage++ } + 20 -> npc("Every time he takes a Fremennik life, he gains in","power, so to keep it from becoming too powerful we","hunters hunt it and steal its life force.").also { stage++ } + 21 -> npc("We do this with a special talisman. Here, take it, it will","let you track the Draugen while it's invisible, and when","you defeat it will absorb its essence.").also { stage++; player?.inventory?.add(Item(3696)) } + 22 -> npc("I want you to track the Draugen, defeat it, and store","its essence in that talisman for me. If you can do this","important task for my clan, I will vote for you.").also { stage++ } + 23 -> npc("Take care of the talisman, and see me when you have","completed this task.").also{stage = 1000; player?.setAttribute("/save:fremtrials:sigli-accepted",true)} + + //Draugen killed + 100 -> player("Thanks!").also { + player.removeAttribute("fremtrials:draugen-killed") + player.setAttribute("/save:fremtrials:sigli-vote",true) + player?.setAttribute("/save:fremtrials:votes",player.getAttribute("fremtrials:votes",0) + 1) + player?.inventory?.remove(Item(3697)) + stage = 1000 + } + + 150 -> playerl(FacialExpression.ASKING,"I don't suppose you have any idea where I could find a map to unspoiled hunting grounds, do you?").also { stage++ } + 151 -> npcl(FacialExpression.HAPPY,"Well, of course I do. I wouldn't be much of a huntsman if I didn't know where to find my prey now, would I outerlander?").also { stage++ } + 152 -> playerl(FacialExpression.ASKING,"No, I guess not. So can I have it?").also { stage++ } + 153 -> npcl(FacialExpression.ANNOYED,"Directions to my hunting grounds could mean the end of my livelihood. The only way I would be prepared to give them up would be...").also { stage++ } + 154 -> playerl(FacialExpression.THINKING,"What? Power? Money? Women? Wine?").also { stage++ } + 155 -> npcl(FacialExpression.HAPPY,"...a new string for my hunting bow. Not just any bowstring; I need a custom bowstring, balanced for my bow precisely to keep my hunt competitive.").also { stage++ } + 156 -> npcl(FacialExpression.HAPPY,"Only in this way would I allow the knowledge of my hunting grounds to be passed on to strangers.").also { stage++ } + 157 -> playerl(FacialExpression.THINKING,"So where would I get that?").also { stage++ } + 158 -> npcl(FacialExpression.HAPPY,"I have no idea. But then again, I'm happy with my old bowstring and being the only person who knows where my hunting ground is.").also { + player?.incrementAttribute("sigmund-steps",1) + stage = 1000 + } + 160 -> playerl(FacialExpression.ASKING,"I don't suppose you have any idea where I could find a finely balanced custom bowstring, do you?").also { stage++ } + 161 -> npcl(FacialExpression.ANNOYED,"If I knew I would not have asked you to go and get me one, now would I?").also { stage = 1000 } + + 165 -> playerl(FacialExpression.HAPPY,"Here. I have your bowstring. Give me your map to the hunting grounds.").also { + removeItem(player,3702) + addItem(player,3701) + stage++ + } + 166 -> npcl(FacialExpression.HAPPY,"Well met, outerlander. I see some hunting potential within you. Here, take my map, I was getting too dependent on it for my skill anyway.").also { stage = 1000 } + + 170 -> npcl(FacialExpression.HAPPY,"No outerlander... it is hard to explain. That map makes my role as huntsman too easy. I fear my skills are becoming dulled.").also { stage++ } + 171 -> npcl(FacialExpression.HAPPY,"Now I must track my prey once more. To begin again from scratch... I feel this may keep me sharp.").also { stage = 1000 } + + 175 -> npcl(FacialExpression.ANNOYED,"Not the one I want, outerlander.").also { stage = 1000 } + + 180 -> npcl(FacialExpression.HAPPY,"Hello again to you ${player.getAttribute("fremennikname","spinky")}. How goes the hunt?").also { stage++ } + 181 -> playerl(FacialExpression.ASKING,"They hunt? I've already done your task! That's why I'm a Fremennik now!").also { stage++ } + 182 -> npcl(FacialExpression.HAPPY,"You think so do you? The Draugen is always out there, just as I and my hunters are always on its trail to keep it at bay. The hunt will never end until I do.").also { stage = 1000 } + + 1000 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return SigliTheHuntsman(player) + } + + + + override fun getIds(): IntArray { + return intArrayOf(1281) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/SigmundDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/SigmundDialogue.kt new file mode 100644 index 0000000..b4804f0 --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/SigmundDialogue.kt @@ -0,0 +1,148 @@ +package content.region.fremennik.rellekka.quest.thefremenniktrials + +import core.api.addItem +import core.api.getQuestStage +import core.api.removeItem +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import content.data.Quests + +@Initializable +class SigmundDialogue (player: Player? = null) : DialoguePlugin(player) { + + private val QUEST_ITEMS = intArrayOf(3709,3707,3706,3710,3705,3704,3703,3702,3701,3708,3700,3699,3698) + + val gender = if(player?.isMale == true){ + "brother" + }else "sister" + + val fName = player?.getAttribute("fremennikname","uhhh fucking uhhh geoff lol") + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + if(player.questRepository.isComplete(Quests.THE_FREMENNIK_TRIALS)){ + playerl(FacialExpression.HAPPY,"Hello there!") + stage = 50 + return true + } + else if (getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) <= 0) { + playerl(FacialExpression.HAPPY,"Hello there!") + stage = 60 + return true + } + if(player?.inventory?.contains(3698,1) == true){ + playerl(FacialExpression.HAPPY,"Here's that flower you wanted.") + stage = 30 + return true + } + else if(player?.getAttribute("sigmundreturning",false) == true && !player.inventory.containsAtLeastOneItem(QUEST_ITEMS)){ + npcl(FacialExpression.ASKING,"So... how goes it outerlander? Did you manage to obtain my flower for me yet? Or do you lack the necessary merchanting skills?") + stage = 35 + return true + } + if(player?.getAttribute("sigmund-started",false)!!){ + playerl(FacialExpression.HAPPY,"Hello there!") + stage = 25 + return true + } + else if (getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) > 0 && !player?.getAttribute("fremtrials:sigmund-vote",false)!!) { + playerl(FacialExpression.HAPPY,"Hello there!") + stage = 1 + return true + } + else if(player?.getAttribute("fremtrials:sigmund-vote",false) == true){ + playerl(FacialExpression.HAPPY,"Hello there!") + stage = 40 + return true + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 1 -> npcl(FacialExpression.NEUTRAL,"Hello outlander.").also { stage++ } + 2 -> playerl(FacialExpression.NEUTRAL,"Are you a member of the council?").also { stage++ } + 3 -> npcl(FacialExpression.NEUTRAL,"That I am outlander; it is a position that brings my family and I pride.").also { stage++ } + 4 -> playerl(FacialExpression.NEUTRAL,"I was wondering if I can count on your vote at the council of elders?").also { stage++ } + 5 -> npcl(FacialExpression.THINKING,"You wish to become a Fremennik? I may be persuaded to swing my vote to your favor, but you will first need to do a little task for me.").also { stage++ } + 6 -> playerl(FacialExpression.ANNOYED,"How did I know it wouldn't be that simple for your vote?").also { stage++ } + 7 -> npcl(FacialExpression.NEUTRAL,"Calm yourself outerlander. It is but a small task really... I simply require a flower.").also { stage++ } + 8 -> playerl(FacialExpression.ASKING,"A flower? What's the catch?").also { stage++ } + 9 -> npcl(FacialExpression.NEUTRAL,"The catch? Well, it is not just any flower. Someone in this town has an extremely unique flower from a far off land that they picked up on their travels.").also { stage++ } + 10 -> npcl(FacialExpression.NEUTRAL,"I would like you to demonstrate your merchanting skills to me by persuading them to part with it, and then give it to me for my vote.").also { stage++ } + 11 -> playerl(FacialExpression.THINKING,"Well... I guess that doesn't sound too hard.").also { stage++ } + 12 -> npcl(FacialExpression.HAPPY,"Excellent! You will obtain this flower for me, then?").also { stage++ } + 13 -> options("Yes","No").also { stage++ } + 14 -> when(buttonId){ + 1 -> playerl(FacialExpression.ASKING,"Okay. I don't think this will be too difficult. Any suggestions on where to start looking for this flower?").also { + player?.setAttribute("/save:sigmund-started",true) + player?.setAttribute("/save:sigmund-steps",1) + stage++ } + 2 -> playerl(FacialExpression.ANNOYED,"You know what? No. This all sounds like a lot of hassle to me, and frankly I just can't be bothered with it right now. I'll go get someone else to vote for me.").also { stage = 20 } + } + 15 -> npcl(FacialExpression.THINKING,"Ah, well outerlander, if I knew where to start looking I would simply do it myself!").also { stage++ } + 16 -> playerl(FacialExpression.ANNOYED,"No help at ALL?").also { stage++ } + 17 -> npcl(FacialExpression.NEUTRAL,"We are a very insular clan, so I would not expect you to have to leave this town to find whatever you need.").also { stage = 1000 } + + //No + 20 -> npcl(FacialExpression.NEUTRAL,"As you wish outlander. If you change your mind, come and see me again; I am very interested in getting my hands on that flower").also { stage = 1000 } + + 25 -> npcl(FacialExpression.ASKING,"So... how goes it outerlander? Did you manage to obtain my flower for me yet? Or do you lack the necessary merchanting skills?").also { stage++ } + 26 -> playerl(FacialExpression.ASKING,"I'm still working on it... Do you have any suggestion where to start looking for it?").also { stage++ } + 27 -> npcl(FacialExpression.THINKING," I suggest you ask around the other Fremennik in the town. A good merchant will find exactly what their customer needs somewhere.").also { stage = 1000 } + + 30 -> npcl(FacialExpression.AMAZED,"Incredible! Your merchanting skills might even match my own! I have no choice but to recommend you to the council of elders!").also { + removeItem(player,3698) + player?.removeAttribute("sigmund-steps") + player?.removeAttribute("sigmund-started") + player?.removeAttribute("sigmundreturning") + player?.setAttribute("/save:fremtrials:votes",player.getAttribute("fremtrials:votes",0) + 1) + player?.setAttribute("/save:fremtrials:sigmund-vote",true) + stage = 1000 + } + + 35 -> playerl(FacialExpression.ASKING,"I'm still working on it... Do you have any suggestion where to start looking for it?").also { stage++ } + 36 -> npcl(FacialExpression.ASKING,"I suggest you ask around the other Fremennik in the town. A good merchant will find exactly what their customer needs somewhere.").also { stage++ } + 37 -> playerl(FacialExpression.ASKING,"I was making some trades, but then I lost the goods...").also { stage++ } + 38 -> npcl(FacialExpression.THINKING,"Hmmm... well try and start again at the beginning. And try to be more careful of your wares in future.").also { + addItem(player, Items.PROMISSORY_NOTE_3709) + stage = 1000 } + + 40 -> npcl(FacialExpression.HAPPY,"Hello again outerlander! I am amazed once more at your apparent skill at merchanting!").also { stage++ } + 41 -> playerl(FacialExpression.HAPPY,"So I can count on your vote at the council of elders?").also { stage++ } + 42 -> npcl(FacialExpression.HAPPY,"Absolutely, outerlander. Your merchanting skills will be a real boon to the Fremennik.").also { stage = 1000 } + + 50 -> npcl(FacialExpression.HAPPY,"Greetings again $gender $fName! What can I do for you this day?").also { stage++ } + 51 -> options("Can I see your wares?","Nothing thanks").also { stage++ } + 52 -> when(buttonId){ + 1 -> playerl(FacialExpression.HAPPY,"Can I see your wares?").also { stage++ } + 2 -> playerl(FacialExpression.HAPPY,"Nothing thanks").also { stage = 55 } + } + 53 -> npcl(FacialExpression.HAPPY,"Certainly, $fName.").also { + npc.openShop(player) + stage = 1000 + } + + 55 -> npcl(FacialExpression.HAPPY,"Well, feel free to stop by anytime you wish $fName. You are always welcome here!").also { stage = 1000 } + + 60 -> npcl(FacialExpression.HAPPY,"Hello outerlander. By the laws of our tribe, I am afraid I may not speak to you without the express permission of the chieftain.").also { stage++ } + 61 -> playerl(FacialExpression.ASKING,"Where would I find him?").also { stage++ } + 62 -> npcl(FacialExpression.HAPPY,"In the longhall, outerlander.").also { stage = 1000 } + + 1000 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return SigmundDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(1282) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/SkulgrimenDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/SkulgrimenDialogue.kt new file mode 100644 index 0000000..e4ec8ec --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/SkulgrimenDialogue.kt @@ -0,0 +1,104 @@ +package content.region.fremennik.rellekka.quest.thefremenniktrials + +import core.api.addItem +import core.api.removeItem +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import content.data.Quests + +@Initializable +class SkulgrimenDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + if(player?.inventory?.contains(3703,1) == true){ + playerl(FacialExpression.HAPPY,"Hi there. I got your fish, so can I have that bowstring for Sigli now?") + stage = 20 + return true + } + else if(player?.inventory?.contains(3702,1) == true){ + playerl(FacialExpression.ASKING,"So about this bowstring... was it hard to make or something?") + stage = 25 + return true + } + else if(player?.getAttribute("sigmundreturning",false) == true){ + playerl(FacialExpression.ASKING,"Is this trade item for you?") + stage = 26 + return true + } + if(player?.getAttribute("sigmund-steps", 0) == 7){ + playerl(FacialExpression.ASKING,"I don't suppose you have any idea where I could find an exotic and extremely odd fish, do you?") + stage = 15 + return true + } + else if(player?.getAttribute("sigmund-steps", 0) == 6){ + playerl(FacialExpression.ASKING,"I don't suppose you have any idea where I could find a finely balanced custom bowstring, do you?") + stage = 1 + return true + } + else if(player.questRepository.isComplete(Quests.THE_FREMENNIK_TRIALS)){ + npcl(FacialExpression.HAPPY,"Hello again, ${player.getAttribute("fremennikname","ringo")}. Come to see what's for sale?") + stage = 1001 + return true + } + else{ + playerl(FacialExpression.HAPPY,"Hello!") + stage = 100 + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 1 -> npcl(FacialExpression.THINKING,"Aye, I have a few in stock. What would an outerlander be wanting with equipment like that?").also { stage++ } + 2 -> playerl(FacialExpression.HAPPY,"It's for Sigli. It needs to be weighted precisely to suit his hunting bow.").also { stage++ } + 3 -> npcl(FacialExpression.HAPPY,"For Sigli eh? Well, I made his bow in the first place, so I'll be able to select the right string for you... just one small problem.").also { stage++ } + 4 -> playerl(FacialExpression.THINKING,"What's that?").also { stage++ } + 5 -> npcl(FacialExpression.THINKING,"This string you'll be wanting... Very special it is. Take a lot of time to recreate. Not sure you have the cash for it.").also { stage++ } + 6 -> playerl(FacialExpression.THINKING,"Then maybe you'll accept something else...?").also { stage++ } + 7 -> npcl(FacialExpression.HAPPY,"Heh. Good thinking outerlander. Well, it's true, there is more to life than just making money. Making weapons is good money, but it's not why I do it. I'll tell you what.").also { stage++ } + 8 -> npcl(FacialExpression.HAPPY,"I heard a rumour that one of the fishermen down by the docks caught some weird looking fish as they were fishing the other day. From what I hear this fish is unique.").also { stage++ } + 9 -> npcl(FacialExpression.HAPPY,"From what I hear this fish is unique. Nobody's ever seen its like before. This intrigues me. I'd like to have it for myself.").also { stage++ } + 10 -> npcl(FacialExpression.HAPPY,"Make a good trophy. You get me that fish, I give you the bowstring. What do you say? We got a deal?").also { stage++ } + 11 -> playerl(FacialExpression.HAPPY,"Sounds good to me.").also { + player?.incrementAttribute("sigmund-steps",1) + stage = 1000 + } + 15 -> npcl(FacialExpression.EXTREMELY_SHOCKED,"What? There's another one?").also { stage++ } + 16 -> playerl(FacialExpression.ANNOYED,"Er... no, it's the one for you that I'm looking for...").also { stage++ } + 17 -> npcl(FacialExpression.ANNOYED,"Ah. I see. I already told you. Some guy down by the docks was bragging. Best ask there, I reckon.").also { stage = 1000 } + + 20 -> npcl(FacialExpression.HAPPY,"Ohh... That's a nice fish. Very pleased. Here. Take the bowstring. You fulfilled agreement. Only fair I do same. Good work outerlander.").also { + removeItem(player,3703) + addItem(player,3702) + stage++ + } + 21 -> playerl(FacialExpression.HAPPY,"Thanks!").also { stage = 1000 } + + 25 -> npcl(FacialExpression.HAPPY,"Not hard. Just a trick to it. Takes skill to learn, but when learnt, easy. Sigli will be happy. Finest bowstring on continent. Will suit his needs perfectly.").also { stage = 1000 } + + 26 -> npcl(FacialExpression.ANNOYED,"Not for me, I'm afraid.").also { stage = 1000 } + + 100 -> npcl(FacialExpression.HAPPY,"Sorry. I can't sell weapons to outerlanders. Wouldn't be right. Against our beliefs.").also { stage = 1000 } + + 1000 -> end() + 1001 ->{ + end() + npc.openShop(player) + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return SkulgrimenDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(1303) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/SwensenTheNavigator.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/SwensenTheNavigator.kt new file mode 100644 index 0000000..b2f5aad --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/SwensenTheNavigator.kt @@ -0,0 +1,154 @@ +package content.region.fremennik.rellekka.quest.thefremenniktrials + +import core.api.addItem +import core.api.getQuestStage +import core.api.removeItem +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import content.data.Quests + +@Initializable +class SwensenTheNavigator(player: Player? = null) : DialoguePlugin(player){ + val gender = if (player?.isMale == true){"brother"} else "sister" + val fName = player?.getAttribute("fremennikname","doug hug'em") + override fun open(vararg args: Any?): Boolean { + if(player?.inventory?.contains(3705,1) == true){ + playerl(FacialExpression.HAPPY,"I would like your map of fishing spots.") + stage = 120 + return true + } + else if(player?.inventory?.contains(3704,1) == true){ + playerl(FacialExpression.ASKING,"If this map of fishing spots is so valuable, why did you give it away to me so easily?") + stage = 125 + return true + } + else if(player?.getAttribute("sigmundreturning",false) == true){ + playerl(FacialExpression.ASKING,"I have a trade item here.") + stage = 130 + return true + } + if(player?.getAttribute("sigmund-steps", 0) == 9){ + npcl(FacialExpression.HAPPY,"Greetings outerlander.") + stage = 115 + return true + } + else if(player?.getAttribute("sigmund-steps", 0) == 8){ + npcl(FacialExpression.HAPPY,"Greetings outerlander.") + stage = 105 + return true + } + if(player?.getAttribute("fremtrials:maze-complete",false) == true){ + npc("Outerlander! You have finished my maze!","I am genuinely impressed!") + stage = 100 + return true + } else if(player?.getAttribute("fremtrials:swensen-vote",false) == true){ + npc("You have my vote!") + stage = 1000 + return true + } + else if(player.questRepository.isComplete(Quests.THE_FREMENNIK_TRIALS)){ + playerl(FacialExpression.HAPPY,"Hello!") + stage = 140 + return true + } + else if (getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) > 0) { + player("Hello!") + stage = 0 + return true + } + else{ + playerl(FacialExpression.HAPPY,"Hello!") + stage = 145 + return true + } + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> {player("I am trying to become a member of the Fremennik","clan! The Chieftan told me that I may be able to gain","your vote at the council of elders?");stage++} + 1 -> {npc("You wish to stop being an outerlander? I can","understand that! I have no reason why I would prevent","you becoming a Fremennik...");stage++} + 2 -> {npc("...but you must first pass a little test for me to prove","you are worthy.");stage++} + 3 -> {player("What kind of test?");stage++} + 4 -> {npc("Well, I serve our clan as a navigator. The seas can be","a fearful place when you know not where you are","heading.");stage++} + 5 -> {npc("Should something happen to me, all members of our","tribe have some basic sense of direction so that they","may always return safely home.");stage++} + 6 -> {npc("If you are able to demonstrate to me that you too have","a good sense of direction then I will recommend you to","the rest of the council of elders immediately.");stage++} + 7 -> {player("Well, how would I go about showing that?");stage++} + 8 -> {npc("Ah, a simple task! Below this building I have constructed","a maze; should you be able to walk from one side to the","other that will be proof to me.");stage++} + 9 -> {npc("You wish to try my challenge?");stage++} + 10 -> {options("Yes","No");stage++} + 11 -> when(buttonId){ + 1 -> {player("A maze? Is that all? Sure, it sounds simple enough.");stage++} + 2 -> {player("No, that sounds too hard.");stage = 1000} + } + + //Yes + 12 -> {npc("I will warn you outerlander, this maze was designed by","myself, and is of the most fiendish complexity!");stage++} + 13 -> {player("Oh really? Watch and learn...");stage = 1000;player?.setAttribute("/save:fremtrials:swensen-accepted",true)} + + //After maze + 100 -> {player("So does that mean I can rely on your vote at the","council of elders to allow me into your village?");stage++} + 101 -> {npc("Of course outerlander! I am nothing if not a man of","my word!");stage++} + 102 -> { + player("Thanks!") + player?.removeAttribute("fremtrials:maze-complete") + player?.removeAttribute("fremtrials:swensen-accepted") + player?.setAttribute("/save:fremtrials:swensen-vote",true) + player?.setAttribute("/save:fremtrials:votes",player.getAttribute("fremtrials:votes",0) + 1) + stage = 1000 + } + + //Sigmund subquest + 105 -> playerl(FacialExpression.ASKING,"I don't suppose you have any idea where I could find a map of deep sea fishing spots do you?").also { stage++ } + 106 -> npcl(FacialExpression.HAPPY,"Hmmm? Why of course! As the navigator for the Fremennik I keep all of our maps secure right here.").also { stage++ } + 107 -> playerl(FacialExpression.HAPPY,"Great! Can I have it?").also { stage++ } + 108 -> npcl(FacialExpression.ANNOYED,"Have it? Just like that? I think not outerlander. This map shows all of the prime fishing locations nearby. It is very valuable to our clan. I am afraid I can not just give it away.").also { stage++ } + 109 -> playerl(FacialExpression.THINKING,"Perhaps I can trade you something for it?").also { stage++ } + 110 -> npcl(FacialExpression.ANNOYED,"A trade? For a map of the best fishing spots in a hundred leagues? I will trade it for no less than a weather forecast from our Seer.").also { stage++ } + 111 -> npcl(FacialExpression.THINKING,"As a navigator, the weather is extremely important for plotting the best course. Unfortunately the Seer is always too busy to help me with a forecast.").also { stage++ } + 112 -> playerl(FacialExpression.ASKING,"Where could I get a weather forecast from then?").also { stage++ } + 113 -> npcl(FacialExpression.ANNOYED,"I just told you: from the Seer. You will need to persuade him to take the time to make a forecast somehow.").also { + player?.incrementAttribute("sigmund-steps",1) + stage = 1000 + } + 115 -> playerl(FacialExpression.THINKING,"I don't suppose you have any idea where I could find a weather forecast from the Fremennik Seer do you?").also { stage++ } + 116 -> npcl(FacialExpression.ANNOYED,"Uh... from the Seer perhaps?").also { stage = 1000 } + + 120 -> npcl(FacialExpression.ANNOYED,"I have already told you outerlander; I will not exchange it for anything other than a divination on the weather from our seer himself!").also { stage++ } + 121 -> playerl(FacialExpression.HAPPY,"What, like this one I have here?").also { stage++ } + 122 -> npcl(FacialExpression.AMAZED,"W-what...? I don't believe it! How did you...?").also { stage++ } + 123 -> npcl(FacialExpression.HAPPY,"I suppose it doesn't matter, you have my gratitude outerlander! With this forecast I will be able to plan a safe course for our next raiding expedition!").also { + removeItem(player,3705) + addItem(player,3704) + stage++ + } + 124 -> npcl(FacialExpression.HAPPY,"Here, outerlander; you may take my map of local fishing patterns with my gratitude!").also { stage = 1000 } + + 125 -> npcl(FacialExpression.HAPPY,"Hmmm? Well, firstly it will be of value to our entire clan, so I have lost nothing from giving it to you.").also { stage++ } + 126 -> npcl(FacialExpression.HAPPY,"The other reason is of course that I have already memorised it, so I can make myself another copy whenever I want!").also { stage = 1000 } + + 130 -> npcl(FacialExpression.ANNOYED,"It isn't for me, I'm afraid.").also { stage = 1000 } + + 140 -> npcl(FacialExpression.HAPPY,"Greetings to you $gender $fName. How fare you today?").also { stage++ } + 141 -> playerl(FacialExpression.HAPPY,"I am fine thanks Swensen. How are you doing?").also { stage++ } + 142 -> npcl(FacialExpression.HAPPY,"I am fine too!").also { stage = 1000 } + + 145 -> npcl(FacialExpression.HAPPY,"Hello outerlander. This is my home, I would be grateful if you would leave.").also { stage++ } + 146 -> playerl(FacialExpression.THINKING,"Oh. Okay.").also { stage++ } + 147 -> npcl(FacialExpression.HAPPY,"I am sorry outerlander, I will not offer you hospitality until my Chieftain has vouched for your honesty. This is our way.").also { stage = 1000 } + + 1000 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return SwensenTheNavigator(player) + } + + override fun getIds(): IntArray { + return intArrayOf(1283) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/TFTInteractionListeners.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/TFTInteractionListeners.kt new file mode 100644 index 0000000..51331c1 --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/TFTInteractionListeners.kt @@ -0,0 +1,497 @@ +package content.region.fremennik.rellekka.quest.thefremenniktrials + +import core.api.* +import core.game.container.impl.EquipmentContainer.SLOT_WEAPON +import core.game.node.entity.impl.Animator +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.diary.DiaryType +import core.game.node.entity.player.link.music.MusicEntry +import core.game.node.entity.skill.Skills +import content.global.skill.gather.woodcutting.WoodcuttingSkillPulse +import core.game.node.scenery.Scenery +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.map.RegionManager +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.game.system.config.ItemConfigParser +import core.game.world.GameWorld.Pulser +import content.data.Quests +import core.game.interaction.QueueStrength + +class TFTInteractionListeners : InteractionListener { + + private val BEER = intArrayOf(Items.BEER_3803,Items.BEER_1917) + private val WORKER = NPCs.COUNCIL_WORKMAN_1287 + private val FISH_ALTAR = 4141 + private val FISH = intArrayOf(Items.RAW_SHARK_383,Items.RAW_SEA_TURTLE_395,Items.RAW_MANTA_RAY_389) + private val LOW_ALC_KEG = Items.LOW_ALCOHOL_KEG_3712 + private val KEG = Items.KEG_OF_BEER_3711 + private val TINDERBOX = Items.TINDERBOX_590 + private val CHERRY_BOMB = Items.STRANGE_OBJECT_3713 + private val LIT_BOMB = Items.LIT_STRANGE_OBJECT_3714 + private val PIPE = 4162 + private val PORTALIDs = intArrayOf(2273,2274,2506,2507,2505,2503,2504,5138) + private val SWENSEN_LADDER = 4158 + private val SWAYING_TREE = 4142 + private val KNIFE = Items.KNIFE_946 + private val TREE_BRANCH = Items.BRANCH_3692 + private val LYRE_IDs = intArrayOf(14591,14590,6127,6126,6125,3691,3690) + private val THORVALD_LADDER = 34286 + private val THORVALD_LADDER_LOWER = 4188 + private val LALLIS_STEW = 4149 + private val UNSTRUNG_LYRE = Items.UNSTRUNG_LYRE_3688 + private val GOLDEN_FLEECE = Items.GOLDEN_FLEECE_3693 + private val GOLDEN_WOOL = Items.GOLDEN_WOOL_3694 + private val LONGHALL_BACKDOOR = 4148 + private val SHOPNPCS = intArrayOf(NPCs.YRSA_1301,NPCs.SKULGRIMEN_1303,NPCs.THORA_THE_BARKEEP_1300,NPCs.SIGMUND_THE_MERCHANT_1282,NPCs.FISH_MONGER_1315) + private val SPINNING_WHEEL_IDS = intArrayOf(2644,4309,8748,20365,21304,25824,26143,34497,36970,37476) + private val STEW_INGREDIENT_IDS = intArrayOf(Items.POTATO_1942,Items.ONION_1957,Items.CABBAGE_1965,Items.PET_ROCK_3695) + + override fun defineListeners() { + onUseWith(IntType.NPC,BEER,WORKER){ player, beer, _ -> + player.dialogueInterpreter.open(CouncilWorkerFTDialogue(0,true,beer.id), NPC(WORKER)) + return@onUseWith true + } + + onUseWith(IntType.SCENERY, FISH, FISH_ALTAR){ player, fish, _ -> + if(inInventory(player,Items.LYRE_3689) || inInventory(player,Items.ENCHANTED_LYRE_3690)) { + Pulser.submit(SpiritPulse(player, fish.id)) + } else { + sendMessage(player,"I should probably have my lyre with me.") + } + return@onUseWith true + } + + onUseWith(IntType.ITEM,LOW_ALC_KEG,KEG){ player, _, _ -> + if(!getAttribute(player,"fremtrials:keg-mixed",false)){ + if(getAttribute(player,"fremtrials:cherrybomb",false)) { + removeItem(player,LOW_ALC_KEG) + setAttribute(player,"/save:fremtrials:keg-mixed", true) + sendMessage(player,"The cherry bomb in the pipe goes off.") + RegionManager.getLocalEntitys(player).stream().forEach { e -> e.sendChat("What was THAT??") } + sendMessage(player,"You mix the kegs together.") + } else { + player.dialogueInterpreter?.sendDialogue("I can't do this right now. I should create","a distraction.") + } + } else return@onUseWith false + return@onUseWith true + } + + onUseWith(IntType.ITEM,TINDERBOX,CHERRY_BOMB){ player, _, _ -> + if(removeItem(player,CHERRY_BOMB)){ + addItem(player,LIT_BOMB) + sendMessage(player,"You light the strange object.") + } + return@onUseWith true + } + + onUseWith(IntType.ITEM,KNIFE,TREE_BRANCH){ player, _, _ -> + if (!player.skills.hasLevel(Skills.CRAFTING,40)) { + sendDialogue(player, "You need 40 crafting to do this!") + return@onUseWith true + } + if (inInventory(player,KNIFE)) + Pulser.submit(BranchFletchingPulse(player)) + else + sendMessage(player,"You need a knife to do this.") + return@onUseWith true + } + + onUseWith(IntType.SCENERY, STEW_INGREDIENT_IDS, LALLIS_STEW){ player, stewIngredient, _ -> + when(stewIngredient.id){ + Items.ONION_1957 -> { + sendDialogue(player,"You added an onion to the stew") + setAttribute(player,"/save:lalliStewOnionAdded",true) + removeItem(player,stewIngredient) + } + Items.POTATO_1942 -> { + sendDialogue(player,"You added a potato to the stew") + setAttribute(player,"/save:lalliStewPotatoAdded",true) + removeItem(player,stewIngredient) + } + Items.CABBAGE_1965 -> { + sendDialogue(player,"You added a cabbage to the stew") + setAttribute(player,"/save:lalliStewCabbageAdded",true) + removeItem(player,stewIngredient) + } + Items.PET_ROCK_3695 -> { + sendDialogue(player,"You added your dear pet rock to the stew") + setAttribute(player,"/save:lalliStewRockAdded",true) + removeItem(player,stewIngredient) + } + } + return@onUseWith true + } + + onUseWith(IntType.SCENERY,GOLDEN_FLEECE,*SPINNING_WHEEL_IDS){ player, _, _ -> + if(removeItem(player,GOLDEN_FLEECE)){ + addItem(player,GOLDEN_WOOL) + animate(player,896) + sendDialogue(player,"You spin the Golden Fleece into a ball of Golden Wool") + } + return@onUseWith true + } + + onUseWith(IntType.ITEM,UNSTRUNG_LYRE,GOLDEN_WOOL){ player, _, _ -> + if(player.getSkills().getLevel(Skills.FLETCHING) >= 25){ + if(removeItem(player,GOLDEN_WOOL) && + removeItem(player,Items.UNSTRUNG_LYRE_3688)){ + animate(player,1248) + addItem(player,Items.LYRE_3689) + sendDialogue(player,"You string the Lyre with the Golden Wool.") + } + } else sendDialogue(player,"You need 25 fletching to do this!") + return@onUseWith true + } + + on(LONGHALL_BACKDOOR, IntType.SCENERY, "open"){ player, door -> + when { + getAttribute(player,"LyreEnchanted",false) -> { + sendNPCDialogue(player,1278,"Yeah you're good to go through. Olaf tells me you're some kind of outerlander bard here on tour. I doubt you're worse than Olaf is.") + core.game.global.action.DoorActionHandler.handleAutowalkDoor(player,door.asScenery()) + } + getAttribute(player,"lyreConcertPlayed",false) || isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS) -> { + core.game.global.action.DoorActionHandler.handleAutowalkDoor(player,door.asScenery()) + } + else -> { + sendNPCDialogue(player,1278,"I didn't give you permission to go backstage!") + } + } + return@on true + } + + on(LYRE_IDs, IntType.ITEM, "play"){ player, lyre -> + if(getAttribute(player,"onStage",false) && !getAttribute(player,"lyreConcertPlayed",false)){ + playLyreConcert(player, lyre.id) + } else if(getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) < 20 || !isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS)){ + sendMessage(player,"You lack the knowledge to play this.") + } else if(LYRE_IDs.isLast(lyre.id)){ + sendMessage(player,"Your lyre is out of charges!") + } else if (player.isTeleBlocked) { + sendMessage(player, "A magical force has stopped you from teleporting.") + } else if(removeItem(player,lyre.asItem())){ + addItem(player,LYRE_IDs.getNext(lyre.id)) + Pulser.submit(TelePulse(player)) + } + return@on true + } + + on(PIPE, IntType.SCENERY, "put-inside"){ player, _ -> + if(inInventory(player,LIT_BOMB)){ + sendMessage(player,"You stuff the lit object into the pipe.") + setAttribute(player,"/save:fremtrials:cherrybomb",true) + removeItem(player,LIT_BOMB) + } else { + sendMessage(player,"What am I supposed to put in there? A shoe?") + } + return@on true + } + + on(PORTALIDs, IntType.SCENERY, "use"){ player, portal -> + player.properties?.teleportLocation = when(portal.id){ + 2273 -> DestRoom(2639, 10012, 2645, 10018).getCenter() + 2274 -> DestRoom(2650, 10034, 2656, 10040).getCenter() + 2506 -> DestRoom(2662, 10023, 2669, 10029).getCenter() + 2507 -> DestRoom(2626, 10023, 2633, 10029).getCenter() + 2505 -> DestRoom(2650, 10001, 2656, 10007).getCenter() + 2503 -> DestRoom(2662, 10012, 2668, 10018).getCenter() + 2504 -> { + setAttribute(player,"/save:fremtrials:maze-complete",true) + DestRoom(2662, 10034, 2668, 10039).getCenter() + } + else -> getRandomLocation(player) + } + return@on true + } + + on(SWENSEN_LADDER, IntType.SCENERY, "climb-down") { player, _ -> + if (!getAttribute(player,"fremtrials:swensen-accepted",false)) { + sendNPCDialogue(player,1283,"Where do you think you're going?", core.game.dialogue.FacialExpression.ANGRY) + return@on true + } + core.game.global.action.ClimbActionHandler.climb(player, Animation(828), Location.create(2631, 10006, 0)) + return@on true + } + + on(THORVALD_LADDER, IntType.SCENERY, "climb-down") { player, _ -> + if (isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS) || getAttribute(player, "fremtrials:thorvald-vote", false)) { + sendMessage(player,"You have no reason to go back down there.") + return@on true + } else if (!getAttribute(player,"fremtrials:warrior-accepted",false)) { + player.dialogueInterpreter?.sendDialogues(NPCs.THORVALD_THE_WARRIOR_1289, core.game.dialogue.FacialExpression.ANGRY, + "Outerlander... do not test my patience. I do not take", + "kindly to people wandering in here and acting as though", + "they own the place." + ) + return@on true + } else if (hasEquippableItems(player)) { + player.dialogueInterpreter?.sendDialogues(NPCs.THORVALD_THE_WARRIOR_1289, core.game.dialogue.FacialExpression.ANGRY, + "You may not enter the battleground with any armour", + "or weaponry of any kind." + ) + player.dialogueInterpreter.addAction { _, _ -> + player.dialogueInterpreter?.sendDialogues(NPCs.THORVALD_THE_WARRIOR_1289, core.game.dialogue.FacialExpression.ANGRY, + "If you need to place your equipment into your bank", + "account, I recommend that you speak to the seer. He", + "knows a spell that will do that for you." + ) + } + return@on true + } + + if (player.getExtension(KoscheiSession::class.java) != null) { + KoscheiSession.getSession(player).close() + } + core.game.global.action.ClimbActionHandler.climb(player, Animation(828), Location.create(2671, 10099, 2)) + Pulser.submit(KoscheiPulse(player)) + return@on true + } + + on(THORVALD_LADDER_LOWER, IntType.SCENERY, "climb-up") { player, _ -> + if (player.getExtension(KoscheiSession::class.java) != null) { + KoscheiSession.getSession(player).close() + } + core.game.global.action.ClimbActionHandler.climb(player, Animation(828), Location.create(2666, 3694, 0)) + return@on true + } + + on(SWAYING_TREE, IntType.SCENERY, "cut-branch"){ player, node -> + player.pulseManager.run(WoodcuttingSkillPulse(player, node as Scenery)) + return@on true + } + + on(SHOPNPCS, IntType.NPC, "Trade") { player, npc -> + if(isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS)){ + npc.asNpc().openShop(player) + } else when(npc.id){ + NPCs.THORA_THE_BARKEEP_1300 -> sendDialogue(player,"Only Fremenniks may buy drinks here.") + NPCs.SKULGRIMEN_1303 -> sendDialogue(player,"Only Fremenniks may purchase weapons and armour here.") + NPCs.SIGMUND_THE_MERCHANT_1282 -> sendDialogue(player,"Only Fremenniks may trade with this merchant.") + NPCs.YRSA_1301 -> sendDialogue(player,"Only Fremenniks may buy clothes here.") + NPCs.FISH_MONGER_1315 -> sendDialogue(player,"Only Fremenniks may purchase fish here.") + } + return@on true + } + } + + class DestRoom(val swx: Int, val swy: Int, val nex: Int, val ney: Int) + + fun DestRoom.getCenter(): Location { + return Location((swx + nex) / 2, (swy + ney) / 2).transform(1,0,0) + } + + fun getRandomLocation(player: Player?): Location{ + var obj: Scenery? = null + + while(obj?.id != 5138) { + val objects = player?.viewport?.chunks?.random()?.random()?.objects + obj = objects?.random()?.random() + if(obj == null || obj.location?.equals(Location(0,0,0))!!){ + continue + } + } + return obj.location + } + + fun hasEquippableItems(player: Player?): Boolean { + val container = arrayOf(player!!.inventory, player.equipment) + for (c in container) { + for (i in c.toArray()) { + if (i == null) { + continue + } + if (i.name.lowercase().contains(" rune")) { + return true + } + var slot: Int = i.definition.getConfiguration(ItemConfigParser.EQUIP_SLOT, -1) + if (slot == -1 && i.definition.getConfiguration(ItemConfigParser.WEAPON_INTERFACE, -1) != -1) { + slot = SLOT_WEAPON + } + if (slot >= 0) { + return true + } + } + } + return false + } + + class SpiritPulse(val player: Player, val fish: Int) : Pulse(){ + var counter = 0 + val npc = NPC(1273, player.location) + val sea_boots = intArrayOf(Items.FREMENNIK_SEA_BOOTS_1_14571,Items.FREMENNIK_SEA_BOOTS_2_14572,Items.FREMENNIK_SEA_BOOTS_3_14573) + val hasboots = player.equipment.containsAtLeastOneItem(sea_boots) + override fun pulse(): Boolean { + when(counter++){ + 0 -> { + npc.init() + player.lock() + removeItem(player,fish) + } + 1 -> npc.moveStep() + 2 -> npc.face(player).also { player.face(npc) } + 3 -> player.dialogueInterpreter?.sendDialogues(npc, + core.game.dialogue.FacialExpression.HAPPY,"I will kindly accept this offering, and","bestow upon you a gift in return.") + 4 -> if(!removeItem(player,Items.LYRE_3689)) { removeItem(player,Items.ENCHANTED_LYRE_3690) } + 5 -> if(hasboots) when(fish){ + 383 -> addItem(player, Items.ENCHANTED_LYRE3_6126) + 389 -> addItem(player, Items.ENCHANTED_LYRE5_14590) + 395 -> addItem(player, Items.ENCHANTED_LYRE6_14591) + } else when(fish){ + 383 -> addItem(player, Items.ENCHANTED_LYRE2_6125) + 389 -> addItem(player, Items.ENCHANTED_LYRE3_6126) + 395 -> addItem(player, Items.ENCHANTED_LYRE4_6127) + } + 6 -> player.unlock() + 10 -> npc.clear().also { + setAttribute(player,"/save:LyreEnchanted",true) + return true } + } + return false + } + } + + fun playLyreConcert(player: Player, lyre: Int) { + val GENERIC_LYRICS = arrayOf( + "${player.username?.capitalize()} is my name,", + "I haven't much to say", + "But since I have to sing this song.", + "I'll just go ahead and play." + ) + val CHAMPS_LYRICS = arrayOf( + "The thought of lots of questing,", + "Leaves some people unfulfilled,", + "But I have done my simple best, in", + "Entering the Champions Guild." + ) + val HEROES_LYRICS = arrayOf( + "When it comes to fighting", + "I hit my share of zeroes", + "But I'm well respected at", + "the Guild reserved for Heroes," + ) + val LEGENDS_LYRICS = arrayOf( + "I cannot even start to list", + "The amount of foes I've killed.", + "I will simply tell you this:", + "I've joined the Legends' Guild!" + ) + val questPoints = getQuestPoints(player) + val champGuild = player.achievementDiaryManager?.hasCompletedTask(DiaryType.VARROCK, 1, 1)?: false + val legGuild = questPoints >= 111 + val heroGuild = questPoints >= 5 + val masteredAmount = player.getSkills()?.masteredSkills!! > 0 + var SKILLNAME = getMasteredSkillNames(player) + + val LYRICS = when { + masteredAmount -> { + arrayOf( + "When people speak of training,", + "Some people think they're fine.", + "But they just all seem jealous that", + "My ${SKILLNAME.random()}'s ninety-nine!" + ) + } + legGuild -> LEGENDS_LYRICS + heroGuild -> HEROES_LYRICS + champGuild -> CHAMPS_LYRICS + else -> GENERIC_LYRICS + } + + queueScript(player, 0, QueueStrength.SOFT) { stage -> + when (stage) { + 0 -> { + player.lock() + animate(player,1318,true) + return@queueScript delayScript(player, 1) + } + 2 -> { + animate(player,1320,true) + player.musicPlayer.play(MusicEntry.forId(165)) + return@queueScript delayScript(player, 1) + } + 4 -> { + animate(player,1320,true) + player.musicPlayer.play(MusicEntry.forId(164)) + sendChat(player,LYRICS[0]) + } + 6 -> { + animate(player,1320,true) + player.musicPlayer.play(MusicEntry.forId(164)) + sendChat(player,LYRICS[1]) + } + 8 -> { + animate(player,1320,true) + player.musicPlayer.play(MusicEntry.forId(164)) + sendChat(player,LYRICS[2]) + } + 10 ->{ + animate(player,1320,true) + player.musicPlayer.play(MusicEntry.forId(164)) + sendChat(player,LYRICS[3]) + } + 14 ->{ + setAttribute(player,"/save:lyreConcertPlayed",true) + removeAttribute(player, "/save:LyreEnchanted") + if (removeItem(player,lyre)) { + addItem(player, Items.ENCHANTED_LYRE_3690) + } + player.unlock() + return@queueScript stopExecuting(player) + } + } + return@queueScript delayScript(player, 1) + } + } + + class BranchFletchingPulse(val player: Player) : Pulse(){ + var counter = 0 + override fun pulse(): Boolean { + when(counter++){ + 0 -> player.animator?.animate(Animation(1248)).also { player.lock() } + 3 -> { + if(removeItem(player,Items.BRANCH_3692)) + addItem(player,Items.UNSTRUNG_LYRE_3688) + player.unlock() + return true + } + } + return false + } + } + + class TelePulse(val player: Player) : Pulse(){ + var counter = 0 + override fun pulse(): Boolean { + when(counter++){ + 0 -> { + player.lock() + player.animator.animate(Animation(9600, Animator.Priority.VERY_HIGH), Graphics(1682)) + } + 6 -> player.properties.teleportLocation = Location(2661, 3646, 0) + 7 -> player.unlock().also { return true } + } + return false + } + } + + class KoscheiPulse(val player: Player) : Pulse() { + var counter = 0 + override fun pulse(): Boolean { + when(counter++) { + 0 -> sendMessage(player,"Explore this battleground and find your foe...") + 20 -> { + if (player.getExtension(KoscheiSession::class.java) != null) + return true + KoscheiSession.create(player).start().also { return true } + } + } + return false + } + } +} diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/ThoraDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/ThoraDialogue.kt new file mode 100644 index 0000000..51159d5 --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/ThoraDialogue.kt @@ -0,0 +1,130 @@ +package content.region.fremennik.rellekka.quest.thefremenniktrials + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.Items +import content.data.Quests + +@Initializable +class ThoraDialogue(player: Player? = null) : DialoguePlugin(player){ + val fName = player?.getAttribute("fremennikname","name jeff") + var curNPC: NPC? = NPC(0, Location(0,0,0)) + override fun open(vararg args: Any?): Boolean { + curNPC = args[0] as? NPC + npc = args[0] as NPC + if(player.inventory.contains(3707,1)){ + playerl(FacialExpression.ASKING,"Thanks for making me this cocktail. Why don't you make them anymore normally?") + stage = 35 + } + else if(player.inventory.contains(3709,1)){ + playerl(FacialExpression.HAPPY,"Hi! Can I please have one of your legendary cocktails now?") + stage = 25 + } + else if(player?.getAttribute("sigmundreturning",false) == true){ + playerl(FacialExpression.ASKING,"I'm trying to remember who I was meant to give this trade item to.") + stage = 30 + } + else if(player?.getAttribute("sigmund-steps", 0) == 13){ + playerl(FacialExpression.ASKING,"I don't suppose you have any idea where I could find a written promise from Askeladden to stay out of the Longhall?") + stage = 20 + } + else if(player?.getAttribute("sigmund-steps", 0) == 12){ + playerl(FacialExpression.ASKING,"I don't suppose you have any idea where I could find the longhall barkeeps' legendary cocktail, do you?") + stage = 1 + } + else if(player.questRepository.isComplete(Quests.THE_FREMENNIK_TRIALS)){ + npcl(FacialExpression.HAPPY,"Hello again, $fName. I suppose you want a drink? Or are you going to try another scam with that terrible Askeladden again?") + stage = 50 + } + else{ + playerl(FacialExpression.HAPPY,"Hello there.") + stage = 60 + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 1 -> npcl(FacialExpression.AMAZED,"How did you hear about that? I didn't think anybody knew about that.").also { stage++ } + 2 -> npcl(FacialExpression.HAPPY,"Well, it is true that in my younger years as a barkeep, I wandered the lands trying various alcoholic delicacies.").also { stage++ } + 3 -> npcl(FacialExpression.HAPPY,"Do know how many different types of alcohol there are here in Gielinor? Lots!").also { stage++ } + 4 -> npcl(FacialExpression.HAPPY,"Well, anyway, I used a fusion of various drinks from all around the world to create the greatest cocktail ever made!").also { stage++ } + 5 -> npcl(FacialExpression.HAPPY,"Of course, when my wander lust was gone, and I returned to Rellekka to serve as barkeep here, I gave all that up.").also { stage++ } + 6 -> playerl(FacialExpression.ASKING,"But you still remember how to make it, right?").also { stage++ } + 7 -> npcl(FacialExpression.HAPPY,"Of course.").also { stage++ } + 8 -> playerl(FacialExpression.ASKING,"And you have all the ingredients here? I don't need to go chasing round the world for obscure ingredients to make it?").also { stage++ } + 9 -> npcl(FacialExpression.ASKING,"No, I have them all here. Why?").also { stage++ } + 10 -> playerl(FacialExpression.ASKING,"Can you make me your legendary cocktail then?").also { stage++ } + 11 -> npcl(FacialExpression.SAD,"I would rather not; it is a reminder of a life I left behind when I came back.").also { stage++ } + 12 -> playerl(FacialExpression.ASKING,"Any way I could change your mind?").also { stage++ } + 13 -> npcl(FacialExpression.THINKING,"You need this to become a Fremennik, right? Well, you seem okay for an outerlander, it would be a shame to see you fail. You know Askeladden?").also { stage++ } + 14 -> playerl(FacialExpression.THINKING,"That kid outside? Sure.").also { stage++ } + 15 -> npcl(FacialExpression.ANGRY,"He is nothing but a pest. He keeps sneaking in and stealing beer.").also { stage++ } + 16 -> npcl(FacialExpression.ANGRY,"I shudder to think what he will be like when he has passed his trial of manhood, and is allowed in here legitimately.").also { stage++ } + 17 -> npcl(FacialExpression.ANGRY,"If you can get him to sign a contract promising that he will NEVER EVER EVER darken my doorway here again, you get the drink.").also { stage++ } + 18 -> playerl(FacialExpression.ASKING,"Any idea how I can get him to do that?").also { stage++ } + 19 -> npcl(FacialExpression.HAPPY,"Knowing that little horror, he'll probably be willing to in exchange for some cash. You should go ask him yourself though.").also { + player?.incrementAttribute("sigmund-steps",1) + stage = 1000 + } + 20 -> npcl(FacialExpression.ANNOYED,"Well, as I say, you should talk to him about that. Knowing the little runt as I do though He'll probably do it for the cash.").also {stage++} + + 25 -> npcl(FacialExpression.AMAZED,"What?!?! I can't believe you... Let me look at that... Askeladden would NEVER... Gosh. It looks legitimate.").also { + player?.inventory?.remove(Item(Items.PROMISSORY_NOTE_3709)) + player?.inventory?.add(Item(Items.LEGENDARY_COCKTAIL_3707)) + player?.setAttribute("/save:sigmundreturning",true) + stage++ + } + 26 -> npcl(FacialExpression.HAPPY,"Here you go, on the house! You have made my life SO much easier! Knowing that little monster won't be bugging me in here all the time anymore!").also { stage++ } + 27 -> npcl(FacialExpression.HAPPY,"That little weasel will have to abide by this written promise that Askeladden can never ever enter the Longhall again! He can't get round this one!").also { stage++ } + 28 -> playerl(FacialExpression.SUSPICIOUS,"Uh... yeah... yeah, you probably won't see someone called Askeladden coming in here...").also { stage = 1000 } + + 30 -> npcl(FacialExpression.NEUTRAL,"If it's not the note from Askeladden it isn't me, I'm afraid.").also { stage = 1000 } + + 35 -> npcl(FacialExpression.SAD,"Ah... when I gave up my travels across the world many years back, to return to my expected role as longhall barkeep,").also { stage++ } + 36 -> npcl(FacialExpression.SAD,"as my mother, and her mother, were before me, I gave up a lot of the freedom I had found in the outside world.").also { stage++ } + 37 -> npcl(FacialExpression.SAD,"I know it is our custom to shun outerlanders and their ways, but I didn't find them as bad as the stories say.").also { stage++ } + 38 -> npcl(FacialExpression.SAD,"Sometimes I feel as though we Fremennik live in a prison that we have constructed for ourselves,").also { stage++ } + 39 -> npcl(FacialExpression.SAD,"and that WE are the outerlanders, out here on the edge of the world...").also { stage++ } + 40 -> npcl(FacialExpression.SAD,"I'm sorry, I think it is part of the job of Longhall barkeep to get philosophical about things ocassionally.").also { stage++ } + 41 -> npcl(FacialExpression.HAPPY,"I wish you all the best of luck with your trials, outerlander.").also { stage++ } + 42 -> npcl(FacialExpression.HAPPY,"When you have finished, perhaps you will come back here, and we can share a drink over tales of the outside world?").also { stage++ } + 43 -> playerl(FacialExpression.HAPPY,"Thanks, I'd like that.").also { stage = 1000 } + + 50 -> playerl(FacialExpression.THINKING,"Scam? Oh... You mean his promise to not come in here anymore?").also { stage++ } + 51 -> npcl(FacialExpression.ANNOYED,"Yes. Yes I do. I should have never trusted him not to come in here, even with that written promise. Anyway, do you want a drink or not?").also { stage++ } + 52 -> options("Yes please","No thanks").also { stage++ } + 53 -> when(buttonId){ + 1 -> playerl(FacialExpression.HAPPY,"Yes please").also { + npc.openShop(player) + stage = 1000 + } + 2 -> playerl(FacialExpression.HAPPY,"No thanks.").also { stage++ } + } + 54 -> npcl(FacialExpression.HAPPY,"Okay then.").also { stage = 1000 } + + 60 -> npcl(FacialExpression.HAPPY,"Hello yourself, outerlander. A little out of the way up here, aren't you?").also { stage++ } + 61 -> npcl(FacialExpression.HAPPY,"I would love to stop and chat with you, but unfortunately we have a custom that no Fremennik may speak with the outerlanders without the permission of our chieftain. Don't take it personally.").also { stage++ } + 62 -> npcl(FacialExpression.HAPPY,"The Chieftain is stood just over there, his name is Brundt. I suggest you go and introduce yourself.").also { stage++ } + 63 -> npcl(FacialExpression.ASKING,"You wouldn't want to go making any enemies because you weren't aware of our customs now, would you?").also { stage++ } + 64 -> playerl(FacialExpression.THINKING,"No, I guess not. Thanks anyway.").also { stage++ } + 65 -> npcl(FacialExpression.HAPPY,"Not a problem, outerlander. It's always nice to see a new face in the long hall; it happens so rarely.").also { stage = 1000 } + + 1000 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return ThoraDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(1300) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/ThorvaldDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/ThorvaldDialogue.kt new file mode 100644 index 0000000..af0ed44 --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/ThorvaldDialogue.kt @@ -0,0 +1,207 @@ +package content.region.fremennik.rellekka.quest.thefremenniktrials + +import core.api.addItem +import core.api.getQuestStage +import core.api.removeItem +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs +import content.data.Quests + +@Initializable +class ThorvaldDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin(player){ + override fun open(vararg args: Any?): Boolean { + if(player?.inventory?.contains(3706,1) == true){ + playerl(core.game.dialogue.FacialExpression.HAPPY,"I would like your contract to offer your services as a bodyguard.") + stage = 215 + return true + } + else if(player?.inventory?.contains(3710,1) == true){ + playerl(core.game.dialogue.FacialExpression.ASKING,"You didn't take much persuading to 'lower' yourself to a bodyguard.") + stage = 220 + return true + } + else if(player?.getAttribute("sigmundreturning",false) == true){ + playerl(core.game.dialogue.FacialExpression.ASKING,"Is this item for you?") + stage = 214 + return true + } + else if(player?.getAttribute("sigmund-steps", 0) == 11){ + playerl(core.game.dialogue.FacialExpression.ASKING,"I don't suppose you have any idea where I could find the token to allow your seat at the champions table?") + stage = 211 + return true + } + else if(player?.getAttribute("sigmund-steps", 0) == 10){ + playerl(core.game.dialogue.FacialExpression.ASKING,"I don't suppose you have any idea where I could find a brave and powerful warrior to act as a bodyguard?") + stage = 200 + return true + } + else if (args.size > 1) { + npcl(core.game.dialogue.FacialExpression.FRIENDLY, "Hahaha! Well fought outerlander! Now come down from there, you have passed my trial with flying colours!") + stage = 150 + return true + } + else if (player?.questRepository?.isComplete(Quests.THE_FREMENNIK_TRIALS)!!) { + playerl(core.game.dialogue.FacialExpression.FRIENDLY, "Howdy Thorvald!") + stage = 0 + return true + } + else if (getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) > 0 && player!!.getAttribute("fremtrials:thorvald-vote", false)!!) { + playerl(core.game.dialogue.FacialExpression.FRIENDLY, "So can I count on your vote at the council of elders now Thorvald?") + stage = 160 + return true + } + else if(player.questRepository.isComplete(Quests.THE_FREMENNIK_TRIALS)){ + playerl(core.game.dialogue.FacialExpression.HAPPY,"Howdy Thorvald!") + stage = 250 + return true + } + else if(getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) == 0){ + npcl(core.game.dialogue.FacialExpression.ANNOYED, "Leave me be, outerlander. I have nothing to say to the likes of you.") + stage = 1000 + return true + } + else if (getQuestStage(player, Quests.THE_FREMENNIK_TRIALS) > 0 && !player!!.getAttribute("fremtrials:thorvald-vote", false)!!) { + if (player!!.getAttribute("fremtrials:warrior-accepted", false)!!) { + options("What do I have to do again?", "Who is my opponent?", "Can't I do something else?") + stage = 100 + return true + } else { + playerl(core.game.dialogue.FacialExpression.FRIENDLY, "Hello!") + stage = 60 + return true + } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + //After The Fremennik Trials + 0 -> npcl(core.game.dialogue.FacialExpression.FRIENDLY, "And greetings to you too. It is good to see new blood entering the Fremennik; we gain our strength by bringing new warriors into the tribe.").also { stage = 1000 } + + //Warrior Trial + 60 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "Hello yourself, outerlander. What brings you to dare speak to a mighty Fremennik warrior such as myself?").also { stage++ } + 61 -> playerl(core.game.dialogue.FacialExpression.HALF_ASKING, "Erm... are you a member of the council?").also { stage++ } + 62 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "The Fremennik council of elders? Why, of course I am. I am recognised as one the clans mightiest warriors.").also { stage++ } + 63 -> npcl(core.game.dialogue.FacialExpression.HALF_ASKING, "What is it to you outerlander?").also { stage++ } + 64 -> playerl(core.game.dialogue.FacialExpression.NEUTRAL, "Well... I was wondering if you could vote for me to become a Fremennik.").also { stage++ } + 65 -> npcl(core.game.dialogue.FacialExpression.LAUGH, "An outerlander wishes to become a Fremennik!?!? Ha! That is priceless!").also { stage++ } + 66 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "Well, let us say that I am not totally against this concept. As a warrior, I appreciate the value of brave and powerful warriors to our clan, and even though you may be an outerlander,").also { stage++ } + 67 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "I will not hold this against you if you can prove yourself to be fierce of heart in a combat situation to me.").also { stage++ } + 68 -> playerl(core.game.dialogue.FacialExpression.NEUTRAL, "So how can I prove that? You want to fight me? Come on then, bring it on! Right here, right now, buddy!").also { stage++ } + 69 -> npcl(core.game.dialogue.FacialExpression.LOUDLY_LAUGHING, "Hahahahaha! You certainly show some spirit for an outerlander!").also { stage++ } + 70 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "But spirit does not always make a good warrior. It takes both skill and spirit to be so. I have a test that I give all Fremenniks on their path to be a member of the clan.").also { stage++ } + 71 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "My test will challenge both your combat prowess and your bravery equally. Should you pass it you will earn my vote at the council, and more importantly my respect for you as a warrior.").also { stage++ } + 72 -> npcl(core.game.dialogue.FacialExpression.HALF_ASKING, "So what say you, outerlander? Are you prepared for the battle?").also { stage++ } + 73 -> options("Yes", "No").also { stage++ } + 74 -> when(buttonId){ + 1 -> playerl(core.game.dialogue.FacialExpression.EVIL_LAUGH, "Am I prepared? I'll show you what combat's all about, you big sissy barbarian type guy!").also { player.setAttribute("/save:fremtrials:warrior-accepted",true); stage = 80 } + 2 -> playerl(core.game.dialogue.FacialExpression.NEUTRAL, "No thanks, I'm pretty sure that I can find someone else to vote for me.").also { stage = 90 } + } + //Yes + 80 -> npcl(core.game.dialogue.FacialExpression.LAUGH, "Hahahahaha! I'm beginning to like you already, outerlander!").also { stage++ } + 81 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "Then allow me to present you with my challenge; This ladder here will take you to a place of combat. I have placed a special warrior down there to challenge you.").also { stage++ } + 82 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "Battle him to the death, and you will pass my challenge. If at any point you wish to leave combat, simply climb back up the ladder, to leave that place. If you leave you will of course fail the test.").also { stage++ } + 83 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "You may retry my test in the future if you fail, but you must stay down there until the death if you wish for my vote at the council. You must defeat him three times to prove that you are worthy.").also { stage++ } + 84 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "The fourth time that you fight him will be to the death, so do not show cowardice.").also { stage++ } + 85 -> playerl(core.game.dialogue.FacialExpression.EVIL_LAUGH, "Is that all? It will be easy!").also { stage++ } + 86 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "No, there is one more important rule; You may not enter the battleground with any armour or weaponry of any kind.").also { stage++ } + 87 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "If you need to place your equipment into your bank account, I recommend that you speak to the seer, who knows a spell that will do that for you.").also { stage = 1000 } + + //No thanks + 90 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "Hmm, not so brave after all, outerlander? Perhaps it is for the best. I doubt you have what it takes to pass my challenge.").also { stage = 1000 } + + //Warrior Trial Accepted Not Completed + 100 -> when(buttonId){ + 1 -> playerl(core.game.dialogue.FacialExpression.HALF_ASKING, "So what do I have to do to earn your vote at the council again?").also { stage = 110 } + 2 -> playerl(core.game.dialogue.FacialExpression.HALF_ASKING, "So, who is my opponent?").also { stage = 120 } + 3 -> playerl(core.game.dialogue.FacialExpression.HALF_ASKING, "I don't really like fighting that much... Isn't there something else I can do to earn your vote at the council of elders?").also { stage = 130 } + } + //What do I have to do again? + 110 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "I will not offer my vote to anybody whose bravery in combat I do not trust completely. You must go down that ladder and fight your foe to the death.").also { stage = 1000 } + + //Who is my opponent? + 120 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "Ah, a wise question before entering combat. His name is Koschei the deathless. He is something of a mystery, even to us.").also { stage++ } + 121 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "On one of our regular raiding parties, our longship discovered a man in the frozen waters far north-east of here. We took him aboard our ship, thinking he must be dead.").also { stage++ } + 122 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "To our amazement he was perfectly healthy, even though he must have been in those deadly icey waters for many weeks.").also { stage++ } + 123 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "He has no memory of who he is, or how he came to be there, except for his own name: Koschei. We named him 'The Deathless' because he is seemingly unkillable!").also { stage++ } + 124 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "Any combat technique used against him, he learns instantly! He also apparently can heal himself from any wound at will!").also { stage++ } + 125 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "When he attacks, his weapon moves like a whirlwind! He can hide his combat level from his opponents at will as well!").also { stage++ } + 126 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "He is truly a horribly fierce opponent to face! I am only glad that he has chosen to stay here with us!").also { stage++ } + 127 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "The daylight makes him feel weak, so we have built him his own battleground beneath this building, where he can train his fiercesome skills without being disturbed.").also { stage++ } + 128 -> playerl(core.game.dialogue.FacialExpression.LAUGH, "But he can't REALLY be unkillable...").also { stage++ } + 129 -> playerl(core.game.dialogue.FacialExpression.SUSPICIOUS, "...can he?").also { stage++ } + 130 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "Some say he cannot die, for he has hidden his heart outside of his body to be kept forever safe in a duck egg.").also { stage++ } + 131 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "Others say he has been cursed by the gods to wander this land forever, never knowing any peace in his life, but only combat.").also { stage++ } + 132 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "Some claim that the sword he carries is the source of all his power, and if he should lose it, then exactly one minute later, he will turn back into his true form; A weakened, lame, old man.").also { stage++ } + 133 -> playerl(core.game.dialogue.FacialExpression.HALF_ASKING, "And what do you believe?").also { stage++ } + 134 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "I believe you shouldn't look a gift horse in the mouth. He is a fearfully powerful warrior, but more importantly; He is on OUR side, not against us.").also { stage++ } + 135 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "He is content testing the battle skills of anyone taking their Fremennik trials of manhood, and I am content knowing that should an enemy ever invade").also { stage++ } + 136 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "our town, while our warriors are out on a raiding party, Koschei will be able to hold off ANY invader long enough for us to make our return.").also { stage = 1000} + + //Can't I do something else? + 140 -> npcl(core.game.dialogue.FacialExpression.FRIENDLY, "Yes of course outerlander! If you bring me five raw sardines then I will vote for you instead!").also { stage++ } + 141 -> playerl(core.game.dialogue.FacialExpression.EXTREMELY_SHOCKED, "REALLY?!?!?").also { stage++ } + 142 -> npcl(core.game.dialogue.FacialExpression.LOUDLY_LAUGHING, "HAHAHAHAHAHA! No, of course not! You are stupid, even by outerlander standards!").also { stage++ } + 143 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "If you want my vote, you must pass my trial. It is as simple as that.").also { stage = 1000 } + + //Warrior Trial Completed - after the fight + 150 -> playerl(core.game.dialogue.FacialExpression.NEUTRAL, "But... I don't understand... I did not manage to beat Koschei...").also { stage++ } + 151 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "I did not say you had to, outerlander! All I asked was that you fought to the death! And you did! The death was your own!").also { stage++ } + 152 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "I was not interested in how strong you are! I was interested in how BRAVE you are!").also { stage++ } + 153 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "You fought a superior enemy to your very last breath - THAT is bravery.").also { stage++ } + 154 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "I would be honoured to represent you to the council as worthy of being a Fremennik after watching that superb battle!").also { stage = 1000 } + + //Warrior Trial Completed + 160 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "Absolutely! I watched the entire battle, and was extremely impressed with your bravery in combat!").also { stage = 1000 } + + //Sigmund stuff + 200 -> npcl(core.game.dialogue.FacialExpression.ANNOYED,"Know you not who I am outerlander? There are none more brave or powerful than me amongst all the Fremennik!").also { stage++ } + 201 -> npcl(core.game.dialogue.FacialExpression.ANGRY,"The role of bodyguard is below me, as a noble warrior. You might as well ask me to babysit the children!").also { stage++ } + 202 -> playerl(core.game.dialogue.FacialExpression.THINKING,"Is there no way you would do this for me?").also { stage++ } + 203 -> npcl(core.game.dialogue.FacialExpression.ANNOYED,"There is but one way outerlander. Since I was steeled in battle, I have dreamt of earning my place at the Champions Table in the Long Hall.").also { stage++ } + 204 -> npcl(core.game.dialogue.FacialExpression.ANNOYED,"It is a tradition amongst us that the bravest and strongest are honoured with a table of champions to drink and feast all that they can in our Long Hall.").also { stage++ } + 205 -> npcl(core.game.dialogue.FacialExpression.ANNOYED,"Unfortunately, there are only a fixed number of places available at the table, and these places were all filled many moons ago by others.").also { stage++ } + 206 -> npcl(core.game.dialogue.FacialExpression.ANNOYED,"Although my worthiness is undeniable, the only way I may take my place is if one of those already there die, or give up their place to me voluntarily.").also { stage++ } + 207 -> playerl(core.game.dialogue.FacialExpression.THINKING,"So you want me to go kill one of them off for you? Make it look like an accident?").also { stage++ } + 208 -> npcl(core.game.dialogue.FacialExpression.EXTREMELY_SHOCKED,"WHAT? No, no, not at all! I am shocked you would suggest such a thing!").also { stage++ } + 209 -> npcl(core.game.dialogue.FacialExpression.THINKING,"If you can persuade one of the Revellers to give up their Champions' Token to you so that I might take their place, you may have my contract as a bodyguard.").also { stage++ } + 210 -> playerl(core.game.dialogue.FacialExpression.HAPPY,"Okay, I'll see what I can do.").also { + player?.incrementAttribute("sigmund-steps",1) + stage = 1000 + } + 211 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"You will need to persuade one of the revellers in the Long Hall to give up their token, and their place, in deference to my own worthiness somehow.").also { stage = 1000 } + + 214 -> npcl(core.game.dialogue.FacialExpression.ANNOYED,"I'm afraid not, outerlander.").also { stage = 1000 } + + 215 -> npcl(core.game.dialogue.FacialExpression.ANGRY,"Oh you would, would you outerlander? I have already told you, I will not demean myself with such a baby sitting job until I can sit in the Longhall with pride.").also { stage++ } + 216 -> playerl(core.game.dialogue.FacialExpression.HAPPY,"It's a good thing I have the Champions' Token right here then, isn't it?").also { stage++ } + 217 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Ah... well this is a different matter. With that token I can claim my rightful place as a champion in the Long hall!").also { stage++ } + 218 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Here outerlander, I can suffer the indignity of playing babysitter if it means that I can then revel with my warrior equals in the Long Hall afterwards!").also { + removeItem(player,3706) + addItem(player,3710) + stage++ + } + 219 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Here outerlander, take this contract; I will fulfill it to my utmost.").also { stage = 1000 } + + 220 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"You misunderstand, outerlander. Normally I will only battle for a noble cause, but have never been recognised as a true champion here.").also { stage++ } + 221 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"With this Champion's token, I can stand alongside my warrior brethren in the Long Hall, and revel in the glories of past victories together!").also { stage = 1000 } + + 250 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"And greetings to you too. It is good to see new blood entering the Fremennik; we gain our strength by bringing new warriors into the tribe.").also { stage = 1000 } + + + 1000 -> end() + } + return true + } + + override fun newInstance(player: Player?): core.game.dialogue.DialoguePlugin { + return ThorvaldDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.THORVALD_THE_WARRIOR_1289) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/YrsaDialogue.kt b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/YrsaDialogue.kt new file mode 100644 index 0000000..a515d5d --- /dev/null +++ b/Server/src/main/content/region/fremennik/rellekka/quest/thefremenniktrials/YrsaDialogue.kt @@ -0,0 +1,106 @@ +package content.region.fremennik.rellekka.quest.thefremenniktrials + +import core.api.addItem +import core.api.removeItem +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import content.data.Quests + +@Initializable +class YrsaDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + if(player?.inventory?.contains(3708,1) == true){ + playerl(FacialExpression.HAPPY,"Hello. Can I have those boots now? Here is a written statement from Brundt outlining future tax burdens upon Fremennik merchants and shopkeepers for the year.") + stage = 15 + return true + } + else if(player?.inventory?.contains(3700,1) == true){ + playerl(FacialExpression.ASKING,"Hey, these shoes look pretty comfy. Think you could make me a pair like them?") + stage = 20 + return true + } + else if(player?.getAttribute("sigmundreturning",false) == true){ + playerl(FacialExpression.ASKING,"I have this trade item but I can't remember who it's for.") + stage = 25 + return true + } + if(player?.getAttribute("sigmund-steps",0) == 4){ + playerl(FacialExpression.ASKING,"I don't suppose you have any idea where I could find a guarantee of a reduction on sales taxes, do you?") + stage = 10 + return true + } + else if(player?.getAttribute("sigmund-steps",0) == 3){ + playerl(FacialExpression.ASKING,"I don't suppose you have any idea where I could find some custom sturdy boots, do you?") + stage = 1 + return true + } + else if(player.questRepository.isComplete(Quests.THE_FREMENNIK_TRIALS)){ + npcl(FacialExpression.HAPPY,"Welcome to my clothes shop. I can change your shoes, or I've got a fine selection of clothes for sale.") + stage = 30 + //Uncomment this out when we got the shoe shop up and running + //npcl(FacialExpression.HAPPY,"Welcome to my clothes shop. I can change your shows, or I've got a fine selection of clothes for sale") + return true + } + else { + playerl(FacialExpression.HAPPY,"Hello!") + stage = 35 + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 1 -> npcl(FacialExpression.THINKING,"Well, I don't usually have many shoes in stock here in my little clothes shop... I will be able to make you up a pair if you are really desperate though?").also { stage++ } + 2 -> playerl(FacialExpression.NEUTRAL,"They're not for me... I need them for Olaf.").also { stage++ } + 3 -> npcl(FacialExpression.ANGRY,"Oh, that foolish bard... Why didn't he just ask me to make him some? It is his stupid pride, I believe! I will tell you what I will do outlander.").also { stage++ } + 4 -> npcl(FacialExpression.ASKING,"I know that you must have the ear of the chieftain for him to consider you as worthy of becoming a Fremennik by trial.").also { stage++ } + 5 -> npcl(FacialExpression.HAPPY,"I will make you a pair of sturdy boots for Olaf if you will persuade him to reduce the sales tax placed upon all Fremennik shopkeepers. It does nothing but hurt my business now.").also { stage++ } + 6 -> playerl(FacialExpression.NEUTRAL,"Okay, I will see what I can do").also { + player?.incrementAttribute("sigmund-steps",1) + stage = 1000 + } + 10 -> npcl(FacialExpression.NEUTRAL,"Yes I do outerlander. Only the Chieftain may permit such a thing. Talk to him.").also { stage = 1000 } + + 15 -> npcl(FacialExpression.HAPPY,"Certainly! Let me have a look at what he has written here, just give me a moment...").also { + removeItem(player,3708) + addItem(player,3700) + stage++ + } + 16 -> npcl(FacialExpression.HAPPY,"Yes, that all appears in order. Tell Olaf to come to me next time for shoes!").also { stage = 1000 } + + 20 -> npcl(FacialExpression.HAPPY,"Maybe if you pass your trial and become a full fledged member of the Fremennik...").also { stage = 1000 } + + 25 -> npcl(FacialExpression.ANNOYED,"Not me, I'm afraid.").also { stage = 1000 } + + 30 -> options("I'd like to buy some clothes","Nothing, thanks.").also { stage++ } + 31 -> when(buttonId){ + 1 -> playerl(FacialExpression.HAPPY,"I'd like to buy some clothes").also { + npc.openShop(player) + stage = 1000 + } + 2 -> playerl(FacialExpression.HAPPY,"Nothing, thanks.").also { stage++ } + } + 32 -> npcl(FacialExpression.HAPPY,"As you wish.").also { stage = 1000 } + + 35 -> npcl(FacialExpression.HAPPY,"I'm sorry outerlander, I cannot sell you any clothes. Our customs forbid it.").also { stage = 1000 } + + 1000 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return YrsaDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(1301) + } + + +} \ No newline at end of file diff --git a/Server/src/main/content/region/fremennik/waterbirth/handlers/DagannothKingNPC.java b/Server/src/main/content/region/fremennik/waterbirth/handlers/DagannothKingNPC.java new file mode 100644 index 0000000..e928e61 --- /dev/null +++ b/Server/src/main/content/region/fremennik/waterbirth/handlers/DagannothKingNPC.java @@ -0,0 +1,217 @@ +package content.region.fremennik.waterbirth.handlers; + +import java.util.List; + +import content.data.BossKillCounter; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.tools.RandomFunction; + +/** + * Represents a dagannoth king npc. + * @author Vexia + */ +public final class DagannothKingNPC extends AbstractNPC { + + /** + * The type of dag. + */ + private DagType type; + + /** + * Constructs a new {@Code DagannothKingNPC} {@Code Object} + */ + public DagannothKingNPC() { + super(-1, null); + } + + /** + * Constructs a new {@Code DagannothKingNPC} {@Code Object} + * @param id the id. + * @param location the location. + */ + public DagannothKingNPC(int id, Location location) { + super(id, location); + } + + @Override + public void init() { + type = DagType.forId(getId()); + super.init(); + } + + @Override + public void checkImpact(BattleState state) { + CombatStyle style = state.getStyle(); + if (style == null) { + style = state.getAttacker().getProperties().getCombatPulse().getStyle(); + } + if (type.isImmune(style)) { + state.neutralizeHits(); + } + } + + @Override + public double getLevelMod(Entity entity, Entity victim) { + if (type == DagType.PRIME) { + return 3.5; + } + return 0.0; + } + + @Override + public void sendImpact(BattleState state) { + if (state.getEstimatedHit() > type.getMaxHit()) { + state.setEstimatedHit(RandomFunction.random(type.getMaxHit() - 5, type.getMaxHit())); + } + if (type != DagType.REX && RandomFunction.random(5) <= 2) { + List players = RegionManager.getLocalPlayers(this, 9); + if (players.size() <= 1) { + return; + } + Player newP = players.get(RandomFunction.random(players.size())); + if (newP != null) { + getProperties().getCombatPulse().stop(); + getAggressiveHandler().setPauseTicks(2); + attack(newP); + } + } + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new DagannothKingNPC(id, location); + } + + @Override + public int[] getIds() { + return new int[] { 2881, 2882, 2883 }; + } + + @Override + public void finalizeDeath(Entity killer) { + super.finalizeDeath(killer); + if (getId() == 2881 || getId() == 2882 || getId() == 2883) { + BossKillCounter.addtoKillcount((Player) killer, this.getId()); + } + } + + /** + * ß A king type. + * @author Vexia + */ + public enum DagType { + SUPREME(2881, CombatStyle.RANGE, CombatStyle.MELEE, CombatStyle.MAGIC, 30), PRIME(2882, CombatStyle.MAGIC, CombatStyle.RANGE, CombatStyle.MELEE, 61), REX(2883, CombatStyle.MELEE, CombatStyle.MAGIC, CombatStyle.RANGE, 28); + + /** + * The npc id. + */ + private final int id; + + /** + * The combat style. + */ + private final CombatStyle style; + + /** + * The style he is weak to. + */ + private final CombatStyle weakStyle; + + /** + * The style he is immunned to. + */ + private final CombatStyle immuneStyle; + + /** + * The max hit. + */ + private final int maxHit; + + /** + * Constructs a new {@Code DagType} {@Code Object} + * @param id the id. + * @param style the style. + * @param weakStyle the weak style. + * @parmam immuneStyle the style. + * @param maxHit the max hit. + */ + private DagType(int id, CombatStyle style, CombatStyle weakStyle, CombatStyle immuneStyle, int maxHit) { + this.id = id; + this.style = style; + this.weakStyle = weakStyle; + this.immuneStyle = immuneStyle; + this.maxHit = maxHit; + } + + /** + * Gets the maxHit. + * @return the maxHit + */ + public int getMaxHit() { + return maxHit; + } + + /** + * Gets a dag type. + * @param id the id. + * @return the type. + */ + public static DagType forId(int id) { + for (DagType type : values()) { + if (type.getId() == id) { + return type; + } + } + return null; + } + + /** + * Checks if the dag is immune to a style. + * @param style the style. + * @return {@code True} if so. + */ + public boolean isImmune(CombatStyle style) { + return style == immuneStyle || style == this.style; + } + + /** + * Gets the id. + * @return the id + */ + public int getId() { + return id; + } + + /** + * Gets the style. + * @return the style + */ + public CombatStyle getStyle() { + return style; + } + + /** + * Gets the immuneStyle. + * @return the immuneStyle + */ + public CombatStyle getImmuneStyle() { + return immuneStyle; + } + + /** + * Gets the weakStyle. + * @return the weakStyle + */ + public CombatStyle getWeakStyle() { + return weakStyle; + } + + } + +} diff --git a/Server/src/main/content/region/fremennik/waterbirth/handlers/SpinolypNPC.java b/Server/src/main/content/region/fremennik/waterbirth/handlers/SpinolypNPC.java new file mode 100644 index 0000000..7836a1c --- /dev/null +++ b/Server/src/main/content/region/fremennik/waterbirth/handlers/SpinolypNPC.java @@ -0,0 +1,166 @@ +package content.region.fremennik.waterbirth.handlers; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.spell.CombatSpell; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.InteractionType; +import core.game.node.entity.combat.equipment.SwitchAttack; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.world.map.Location; +import core.tools.RandomFunction; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.node.entity.combat.MultiSwingHandler; + +import static core.api.ContentAPIKt.*; + +/** + * Represents a spinolyp npc. + * @author Vexia + */ +public final class SpinolypNPC extends AbstractNPC { + + /** + * The swing handler. + */ + private static final CombatSwingHandler SWING_HANDLER = new SpinolpySwingHandler(); + + /** + * Constructs a new {@Code SpinolypNPC} {@Code Object} + */ + public SpinolypNPC() { + this(-1, null); + } + + /** + * Constructs a new {@Code SpinolypNPC} {@Code Object} + * @param id the id. + * @param location the location. + */ + public SpinolypNPC(int id, Location location) { + super(id, location); + super.setAggressive(true); + super.setNeverWalks(true); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new SpinolypNPC(id, location); + } + + @Override + public CombatSwingHandler getSwingHandler(boolean swing) { + return SWING_HANDLER; + } + + @Override + public void init() { + super.init(); + super.getLocks().lockMovement(Integer.MAX_VALUE); + setSpell(); + getAggressiveHandler().setAllowTolerance(false); + } + + /** + * Sets the spell. + */ + public void setSpell() { + CombatSpell spell = (CombatSpell) SpellBook.MODERN.getSpell(14); + getProperties().setSpell(spell); + getProperties().setAutocastSpell(spell); + } + + @Override + public void sendImpact(BattleState state) { + if (state.getEstimatedHit() == 0 && RandomFunction.random(15) < 2) { + state.setEstimatedHit(RandomFunction.random(1, 11)); + } + if (state.getEstimatedHit() > 11) { + state.setEstimatedHit(RandomFunction.random(3, 9)); + } + } + + @Override + public int[] getIds() { + return new int[] { 2894, 2896 }; + } + + /** + * Handles the spinolpys swings. + * @author Vexia + */ + public static final class SpinolpySwingHandler extends MultiSwingHandler { + + /** + * Constructs a new {@Code SpinolpySwingHandler} {@Code + * Object} + */ + public SpinolpySwingHandler() { + super(new SwitchAttack(CombatStyle.MAGIC.getSwingHandler(), null), new SwitchAttack(CombatStyle.RANGE.getSwingHandler(), null)); + } + + @Override + public InteractionType canSwing(Entity entity, Entity victim) { + InteractionType type = super.canSwing(entity, victim); + if (type == InteractionType.MOVE_INTERACT) { + type = InteractionType.NO_INTERACT; + } + return type; + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + int swing = super.swing(entity, victim, state); + if (getType() == CombatStyle.MAGIC) { + setSpell(entity); + } + return swing; + } + + @Override + public int getCombatDistance(Entity e, Entity v, int distance) { + return 12; + } + + @Override + public int calculateDefence(Entity v, Entity e) { + // Spinolyps' attack always targets ranged defence + return CombatStyle.RANGE.getSwingHandler().calculateDefence(v, e); + } + + @Override + public void visualize(Entity entity, Entity victim, BattleState state) { + super.visualize(entity, victim, state); + if (state.getStyle() == CombatStyle.MAGIC) { + setSpell(entity); + CombatSpell spell = (CombatSpell) SpellBook.MODERN.getSpell(14); + state.setSpell(spell); + } + state.getStyle().getSwingHandler().visualize(entity, victim, state); + entity.getAnimator().forceAnimation(entity.getProperties().getAttackAnimation()); + } + + @Override + public void impact(Entity entity, Entity victim, BattleState state) { + super.impact(entity, victim, state); + if (super.getType() == CombatStyle.MAGIC && state.getEstimatedHit() > 0) { + victim.getSkills().decrementPrayerPoints(1); + } else { + if (RandomFunction.random(20) == 5) { + applyPoison(victim, entity, 30); + } + } + } + + /** + * Sets the spell. + */ + public void setSpell(Entity e) { + CombatSpell spell = (CombatSpell) SpellBook.MODERN.getSpell(14); + e.getProperties().setSpell(spell); + e.getProperties().setAutocastSpell(spell); + } + } + +} diff --git a/Server/src/main/content/region/fremennik/waterbirth/handlers/WaterBirthDungeonZone.java b/Server/src/main/content/region/fremennik/waterbirth/handlers/WaterBirthDungeonZone.java new file mode 100644 index 0000000..1a5a352 --- /dev/null +++ b/Server/src/main/content/region/fremennik/waterbirth/handlers/WaterBirthDungeonZone.java @@ -0,0 +1,429 @@ +package content.region.fremennik.waterbirth.handlers; + +import java.util.ArrayList; +import java.util.List; + +import core.cache.def.impl.NPCDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.game.dialogue.DialogueAction; +import core.game.global.action.ClimbActionHandler; +import core.game.node.entity.skill.Skills; +import core.game.interaction.Option; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneBuilder; +import core.game.world.map.zone.ZoneRestriction; +import core.game.world.repository.Repository; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.plugin.ClassScanner; +import org.rs09.consts.Items; + +/** + * Handles the waterbirth dungeon zone. + * @author Vexia + */ +@Initializable +public final class WaterBirthDungeonZone extends MapZone implements Plugin { + + /** + * The door support locations. + */ + private static final Location[] DOOR_SUPPORTS = new Location[] { Location.create(2545, 10145, 0), Location.create(2543, 10143, 0), Location.create(2545, 10141, 0) }; + + /** + * Constructs a new {@code WaterBirthDungeonZone} {@code Object}. + */ + public WaterBirthDungeonZone() { + super("Water birth dungeon", true, ZoneRestriction.RANDOM_EVENTS); + ClassScanner.definePlugin(new DagannothKingNPC()); + ClassScanner.definePlugin(new DoorSupportNPC()); + ClassScanner.definePlugin(new DungeonOptionHandler()); + ClassScanner.definePlugin(new SpinolypNPC()); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ZoneBuilder.configure(this); + return this; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public boolean move(Entity e, Location from, Location to) { + for (Location location : DOOR_SUPPORTS) { + if (location.equals(to)) { + List npcs = RegionManager.getLocalNpcs(location, 0); + NPC npc = null; + if (npcs.size() != 0) { + npc = npcs.get(0); + } + if (npc != null && npc instanceof DoorSupportNPC) { + DoorSupportNPC door = (DoorSupportNPC) npc; + if (door.getId() != door.getOriginalId()) { + return true; + } + } + return false; + } + } + if (e instanceof Player) { + final Player p = (e.asPlayer()); + if (p.getLocation().equals(new Location(2545, 10144, 0)) || p.getLocation().equals(new Location(2545, 10142, 0))) { + final List eggs = new ArrayList<>(20); + NPC n = Repository.findNPC(new Location(2546, 10142, 0)); + if (n != null && n.getId() == 2449) { + eggs.add(n); + } + n = Repository.findNPC(new Location(2546, 10144, 0)); + if (n != null && n.getId() == 2449) { + eggs.add(n); + } + if (eggs.size() == 0) { + return true; + } + for (NPC npc : eggs) { + if (npc.getAttribute("transforming", 0) > GameWorld.getTicks()) { + return true; + } + npc.setAttribute("transforming", GameWorld.getTicks() + 3); + } + GameWorld.getPulser().submit(new Pulse(1) { + int counter; + + @Override + public boolean pulse() { + switch (++counter) { + case 1: + for (NPC n : eggs) { + n.transform(n.getId() + 1); + } + break; + case 3: + final List spawns = new ArrayList<>(20); + for (NPC n : eggs) { + n.transform(n.getId() + 1); + NPC spawn = NPC.create(2454, n.getLocation().transform(-1, 0, 0)); + spawn.init(); + spawn.setWalks(true); + spawn.setAggressive(true); + spawn.setRespawn(false); + spawn.attack(p); + spawns.add(spawn); + } + GameWorld.getPulser().submit(new Pulse(GameWorld.getSettings().isDevMode() ? 10 : 45) { + + @Override + public boolean pulse() { + for (NPC n : eggs) { + n.reTransform(); + } + for (NPC spawn : spawns) { + if (spawn.isActive() && !spawn.inCombat()) { + spawn.clear(); + } + } + return true; + } + + }); + break; + } + return counter == 3; + } + + }); + } + } + return super.move(e, from, to); + } + + @Override + public boolean interact(Entity e, Node target, Option option) { + if (e instanceof Player) { + final Player player = (Player) e; + switch (target.getId()) { + case 8966: + player.getProperties().setTeleportLocation(Location.create(2523, 3740, 0)); + return true; + case 10193: + player.getProperties().setTeleportLocation(new Location(2545, 10143, 0)); + return true; + case 10177: + switch (option.getName()) { + case "Climb": + player.getDialogueInterpreter().sendOptions("Select an Option", "Climb Up.", "Climb Down."); + player.getDialogueInterpreter().addAction(new DialogueAction() { + + @Override + public void handle(Player player, int buttonId) { + switch (buttonId) { + case 1: + ClimbActionHandler.climb(player, ClimbActionHandler.CLIMB_UP, new Location(2544, 3741, 0)); + break; + case 2: + ClimbActionHandler.climb(player, ClimbActionHandler.CLIMB_DOWN, new Location(1799, 4406, 3)); + break; + } + } + + }); + break; + case "Climb-down": + ClimbActionHandler.climb(player, ClimbActionHandler.CLIMB_DOWN, new Location(1799, 4406, 3)); + break; + case "Climb-up": + ClimbActionHandler.climb(player, ClimbActionHandler.CLIMB_UP, new Location(2544, 3741, 0)); + break; + } + return true; + case 10217: + player.sendMessage("You need to have completed Horror from the Deep in order to do this."); + return true; + case 10230: + player.teleport(Location.create(2899, 4450, 0)); + return true; + case 10229: + player.teleport(Location.create(1912, 4367, 0)); + return true; + } + } + return super.interact(e, target, option); + } + + @Override + public void configure() { + register(new ZoneBorders(2423, 10090, 2585, 10195)); + registerRegion(7236); + registerRegion(7492); + registerRegion(7748); + registerRegion(11589); + } + + /** + * Handles the dungeon options. + * @author Vexia + */ + public static final class DungeonOptionHandler extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(8958).getHandlers().put("option:open", this); + SceneryDefinition.forId(8959).getHandlers().put("option:open", this); + SceneryDefinition.forId(8960).getHandlers().put("option:open", this); + NPCDefinition.forId(2440).getHandlers().put("option:destroy", this); + NPCDefinition.forId(2443).getHandlers().put("option:destroy", this); + NPCDefinition.forId(2446).getHandlers().put("option:destroy", this); + for (Location l : DOOR_SUPPORTS) { + SceneryBuilder.remove(RegionManager.getObject(l)); + } + return this; + } + + /** + * function to handle activation of pressure pads + * allows both players and pet rocks to activate the pad + */ + private boolean pressurePadActivated(Player player, Location location) { + if (RegionManager.getLocalPlayers(location,0).size() > 0) { + return true; + } + if (RegionManager.getRegionPlane(location).getItem(Items.PET_ROCK_3695,location,player) != null) { + return true; + } + return false; + } + + @Override + public boolean handle(Player player, Node node, String option) { + switch (node.getId()) { + case 8958: + case 8959: + case 8960: + boolean behind = player.getLocation().getX() >= 2492; + if (!behind) { + if (!pressurePadActivated(player,node.getLocation().transform(-1, 0, 0)) || !pressurePadActivated(player,node.getLocation().transform(-1, 2, 0))) { + player.sendMessage("You cannot see a way to open this door..."); + break; + } + } + if (!node.isActive()) { + return true; + } + SceneryBuilder.replace(node.asScenery(), node.asScenery().transform(8962), 30); + break; + case 2440: + case 2443: + case 2446: + int x = node.getLocation().getX(); + int y = node.getLocation().getY(); + boolean canAttack = true; + if (x == 2545 && y == 10145 && player.getLocation().getY() > y) {// top + // north + canAttack = false; + } else if (x == 2543 && y == 10143 && player.getLocation().getX() < x) {// middle + canAttack = false; + } else if (x == 2545 && y == 10141 && player.getLocation().getY() < y) {// south + canAttack = false; + } + if (!canAttack) { + player.sendMessage("The door is propped securely shut from this side..."); + break; + } + player.attack(node); + break; + } + return true; + } + + @Override + public Location getDestination(Node node, Node n) { + if (n.getName().equals("Door-support")) { + Player player = node.asPlayer(); + if (player.getProperties().getCombatPulse().getStyle() != CombatStyle.MELEE) { + return node.getLocation(); + } + } + return null; + } + } + + /** + * Represents a door support npc. + * @author Vexia + */ + public static final class DoorSupportNPC extends AbstractNPC { + + /** + * The death spawn. + */ + private long deathSpawn = -1; + + /** + * Constructs a new {@Code DoorSupportNPC} {@Code Object} + */ + public DoorSupportNPC() { + super(-1, null); + } + + /** + * Constructs a new {@Code DoorSupportNPC} {@Code Object} + * @param id the id. + * @param location the location. + */ + public DoorSupportNPC(int id, Location location) { + super(id, location); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new DoorSupportNPC(id, location); + } + + @Override + public void init() { + lock(); + super.init(); + getSkills().setStaticLevel(Skills.HITPOINTS, 1); + getSkills().setLevel(Skills.HITPOINTS, 1); + getSkills().setLifepoints(1); + getProperties().setDeathAnimation(new Animation(-1)); + } + + @Override + public void handleTickActions() { + if (deathSpawn != -1 && deathSpawn < GameWorld.getTicks()) { + deathSpawn = -1; + transform(getOriginalId()); + getSkills().setStaticLevel(Skills.HITPOINTS, 1); + getSkills().setLevel(Skills.HITPOINTS, 1); + getSkills().setLifepoints(1); + fullRestore(); + getSkills().heal(100); + } + } + + @Override + public boolean face(Entity entity) { + return false; + } + + @Override + public boolean faceLocation(Location locatin) { + return false; + } + + @Override + public void checkImpact(BattleState state) { + getSkills().setStaticLevel(Skills.HITPOINTS, 1); + getSkills().setLevel(Skills.HITPOINTS, 1); + getSkills().setLifepoints(1); + getSkills().setLifepoints(1); + state.setEstimatedHit(1); + lock(); + getWalkingQueue().reset(); + } + + @Override + public boolean canStartCombat(Entity victim) { + return false; + } + + @Override + public void commenceDeath(Entity killer) { + getAnimator().reset(); + transform(getOriginalId() + 1); + lock(); + } + + @Override + public void finalizeDeath(Entity killer) { + getAnimator().reset(); + transform(getOriginalId() + 2); + deathSpawn = GameWorld.getTicks() + 55; + lock(); + + } + + @Override + public boolean isAttackable(Entity entity, CombatStyle style, boolean message) { + if (getId() != getOriginalId()) { + return false; + } + if (entity.getLocation().getDistance(getLocation()) <= 3) { + if (entity instanceof Player) { + Player player = entity.asPlayer(); + if(message) { + player.sendMessage("The door is propped securely shut from this side..."); + } + } + return false; + } + return style != CombatStyle.MELEE; + } + + @Override + public int[] getIds() { + return new int[] { 2440, 2443, 2446 }; + } + + } +} diff --git a/Server/src/main/content/region/fremennik/waterbirth/handlers/WaterBirthIslandZone.java b/Server/src/main/content/region/fremennik/waterbirth/handlers/WaterBirthIslandZone.java new file mode 100644 index 0000000..7d4db29 --- /dev/null +++ b/Server/src/main/content/region/fremennik/waterbirth/handlers/WaterBirthIslandZone.java @@ -0,0 +1,102 @@ +package content.region.fremennik.waterbirth.handlers; + +import core.game.component.Component; +import core.game.interaction.Option; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneBuilder; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Handles the waterbirth island zone. + * @author Vexia + */ +@Initializable +public final class WaterBirthIslandZone extends MapZone implements Plugin { + + /** + * Constructs a new {@code WaterBirthIslandZone} {@code Object}. + */ + public WaterBirthIslandZone() { + super("Water birth island", true); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ZoneBuilder.configure(this); + return this; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public boolean interact(Entity e, Node target, Option option) { + if (e instanceof Player) { + final Player player = (Player) e; + switch (target.getId()) { + case 2438: + if (option.getName().equals("Travel")) { + player.getDialogueInterpreter().open(target.getId(), target, true); + return true; + } + break; + case 8929: + player.getInterfaceManager().open(new Component(574)); + return true; + case 8930: + player.getProperties().setTeleportLocation(new Location(2545, 10143, 0)); + return true; + } + } + return super.interact(e, target, option); + } + + @Override + public boolean enter(Entity e) { + if (e instanceof Player) { + final Player player = (Player) e; + player.getInterfaceManager().openOverlay(new Component(482)); + } + return true; + } + + @Override + public boolean leave(Entity e, boolean logout) { + if (e instanceof Player) { + ((Player) e).getInterfaceManager().closeOverlay(); + } + return true; + } + + @Override + public boolean actionButton(Player player, int interfaceId, int buttonId, int slot, int itemId, int opcode) { + switch (interfaceId) { + case 574: + switch (buttonId) { + case 17: + player.getInterfaceManager().close(); + player.getProperties().setTeleportLocation(Location.create(2443, 10146, 0)); + break; + case 18: + player.getInterfaceManager().close(); + break; + } + break; + } + return super.actionButton(player, interfaceId, buttonId, slot, itemId, opcode); + } + + @Override + public void configure() { + register(new ZoneBorders(2487, 3711, 2565, 3776)); + } + +} diff --git a/Server/src/main/content/region/kandarin/ardougne/dialogue/ArdougneBakerDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/dialogue/ArdougneBakerDialogue.kt new file mode 100644 index 0000000..b5a0805 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/dialogue/ArdougneBakerDialogue.kt @@ -0,0 +1,49 @@ +package content.region.kandarin.ardougne.dialogue + +import core.api.openNpcShop +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class ArdougneBakerDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun newInstance(player: Player?): DialoguePlugin { + return ArdougneBakerDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npcl( + FacialExpression.HAPPY, + "Good day, monsieur. Would you like ze nice freshly-baked bread? Or perhaps a nice piece of cake?" + ).also { stage = START_DIALOGUE } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> options("Let's see what you have.", "No thank you.").also { stage++ } + 1 -> when (buttonId) { + 1 -> { + openNpcShop(player, NPCs.BAKER_571) + end() + } + + 2 -> playerl( + FacialExpression.FRIENDLY, "No thank you." + ).also { stage = END_DIALOGUE } + } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.BAKER_571) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/dialogue/BrotherKojoDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/dialogue/BrotherKojoDialogue.kt new file mode 100644 index 0000000..c085837 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/dialogue/BrotherKojoDialogue.kt @@ -0,0 +1,29 @@ +package content.region.kandarin.ardougne.dialogue + +import content.region.kandarin.ardougne.quest.clocktower.BrotherKojoDialogueFile +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * Brother Kojo main dialogue. + * @author ovenbread + */ +@Initializable +class BrotherKojoDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + // Fallback to default. Always the start of Clocktower quest + openDialogue(player!!, BrotherKojoDialogueFile(), npc) + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return BrotherKojoDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.BROTHER_KOJO_223) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/dialogue/CaptainBarnabyListener.kt b/Server/src/main/content/region/kandarin/ardougne/dialogue/CaptainBarnabyListener.kt new file mode 100644 index 0000000..066aeba --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/dialogue/CaptainBarnabyListener.kt @@ -0,0 +1,55 @@ +package content.region.kandarin.ardougne.dialogue + +import content.global.travel.ship.Ships +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.item.Item +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + + +class CaptainBarnabyListener : InteractionListener { + override fun defineListeners() { + on(NPCs.CAPTAIN_BARNABY_4974, IntType.NPC, "talk-to") { player, npc -> + openDialogue(player,CaptainBarnabyDialogue(), npc) + return@on true + } + on(NPCs.CAPTAIN_BARNABY_4974, IntType.NPC, "pay-fare") { player, _ -> + if (removeItem(player,Item(Items.COINS_995,30))) { + sendMessage(player,"You pay 30 coins and board the ship.") + playJingle(player, 171) + Ships.ARDOUGNE_TO_BRIMHAVEN.sail(player) + } else { + sendMessage(player,"You don't have enough coins.") + } + return@on true + } + } +} + +class CaptainBarnabyDialogue : DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> npcl("Do you want to go on a trip to Brimhaven?").also { stage += 1 } + 1 -> npcl( "The trip will cost you 30 coins.").also { stage += 1 } + 2 -> options("Yes please.", "No, thank you.").also { stage += 1 } + 3 -> when (buttonID) { + 1 -> playerl("Yes please.").also { stage = 10 } + 2 -> playerl("No, thank you.").also { stage = END_DIALOGUE } + } + 10 -> { + if (removeItem(player!!,Item(Items.COINS_995,30))) { + sendMessage(player!!,"You pay 30 coins and board the ship.") + playJingle(player!!, 171) + Ships.ARDOUGNE_TO_BRIMHAVEN.sail(player) + stage = END_DIALOGUE + } else{ + playerl("Sorry, I don't seem to have enough coins.").also{ stage = END_DIALOGUE } + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/dialogue/ChadwellDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/dialogue/ChadwellDialogue.kt new file mode 100644 index 0000000..118e67f --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/dialogue/ChadwellDialogue.kt @@ -0,0 +1,47 @@ +package content.region.kandarin.ardougne.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class ChadwellDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npc(FacialExpression.FRIENDLY,"Good day. What can I get you?").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> options("Let's see what you've got.", "Nothing thanks.").also { stage++ } + 1 -> when (buttonId) { + 1 -> player(FacialExpression.FRIENDLY, "Let's see what you've got.").also { stage = 5 } + 2 -> player(FacialExpression.FRIENDLY, "Nothing thanks.").also { stage = 10 } + } + + 5 -> end().also { npc.openShop(player) } + + 10 -> npc(FacialExpression.FRIENDLY, "Okay then.").also { stage = 99 } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return ChadwellDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.CHADWELL_971) + } +} diff --git a/Server/src/main/content/region/kandarin/ardougne/dialogue/FurTraderDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/dialogue/FurTraderDialogue.kt new file mode 100644 index 0000000..0eafd5c --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/dialogue/FurTraderDialogue.kt @@ -0,0 +1,50 @@ +package content.region.kandarin.ardougne.dialogue + +import core.api.openNpcShop +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class FurTraderDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun newInstance(player: Player?): DialoguePlugin { + return FurTraderDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npcl( + FacialExpression.ASKING, "Would you like to trade in fur?" + ).also { stage = START_DIALOGUE } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> options("Yes.", "No.").also { stage++ } + 1 -> when (buttonId) { + 1 -> { + openNpcShop(player, NPCs.FUR_TRADER_573) + end() + } + + 2 -> playerl( + FacialExpression.HALF_GUILTY, "No, thanks." + ).also { stage = END_DIALOGUE } + + } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.FUR_TRADER_573) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/dialogue/GemMerchantDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/dialogue/GemMerchantDialogue.kt new file mode 100644 index 0000000..b7e2fd4 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/dialogue/GemMerchantDialogue.kt @@ -0,0 +1,40 @@ +package content.region.kandarin.ardougne.dialogue + +import core.api.openNpcShop +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class GemMerchantDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun newInstance(player: Player?): DialoguePlugin { + return GemMerchantDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npcl( + FacialExpression.HAPPY, "Here, look at my lovely gems." + ).also { stage = START_DIALOGUE } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> { + openNpcShop(player, NPCs.GEM_MERCHANT_570) + end() + } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.GEM_MERCHANT_570) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/dialogue/IorwerthsMessageScroll.kt b/Server/src/main/content/region/kandarin/ardougne/dialogue/IorwerthsMessageScroll.kt new file mode 100644 index 0000000..c5990fe --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/dialogue/IorwerthsMessageScroll.kt @@ -0,0 +1,21 @@ +package content.region.kandarin.ardougne.dialogue + +import core.api.openInterface +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import org.rs09.consts.Components +import org.rs09.consts.Items + +class IorwerthsMessageScroll : InteractionListener { + // Receive from the Lord Iorwerth after killing King Tyras in Regicide quest. + override fun defineListeners() { + val kingsmessage = Components.KINGS_LETTER_V2_463 + val iorwerthsscroll = Items.IORWERTHS_MESSAGE_3207 + on(iorwerthsscroll, IntType.ITEM, "read") { player, _ -> + openInterface(player, kingsmessage) + player.packetDispatch.sendString("Your Majesty King Lathas
Your man did well. The path is now open for the dark lord to enter this realm. You will yet live to see Camelot crushed under foot.", kingsmessage, 1) + player.packetDispatch.sendString("Warmaster Iorwerth", kingsmessage, 2) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/dialogue/KingsMessageScroll.kt b/Server/src/main/content/region/kandarin/ardougne/dialogue/KingsMessageScroll.kt new file mode 100644 index 0000000..474d3fa --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/dialogue/KingsMessageScroll.kt @@ -0,0 +1,21 @@ +package content.region.kandarin.ardougne.dialogue + +import core.api.openInterface +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import org.rs09.consts.Components +import org.rs09.consts.Items + +class KingsMessageScroll : InteractionListener { + // Receive from the King's messenger some time after completing the Underground Pass quest. + override fun defineListeners() { + val kingsmessage = Components.KINGS_LETTER_V2_463 + val kingsscroll = Items.KINGS_MESSAGE_3206 + on(kingsscroll, IntType.ITEM, "read") { player, _ -> + openInterface(player, kingsmessage) + player.packetDispatch.sendString("Squire ${player.username}
You are needed to serve the Kingdom of Kandarin. At last our magi have reopened the well of voyage. We must discuss your next commission.", kingsmessage, 1) + player.packetDispatch.sendString("His Majesty King Lathas", kingsmessage, 2) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/dialogue/MonkeyChildThingZooDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/dialogue/MonkeyChildThingZooDialogue.kt new file mode 100644 index 0000000..4aa655a --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/dialogue/MonkeyChildThingZooDialogue.kt @@ -0,0 +1,71 @@ +package content.region.kandarin.ardougne.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class MonkeyChildThingZooDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npc(FacialExpression.FRIENDLY,"").also { stage = 0 } + if (!player.equipment.contains(Items.MSPEAK_AMULET_4021, 1)) { + npc(FacialExpression.OLD_LAUGH1, "Eeekeek ookeek!").also { stage = 99 } + } else { + var a = 1..5 + when(a.random()) { + 1 -> npc(FacialExpression.OLD_LAUGH1, "Arr!").also { stage = 10 } + 2 -> npcl(FacialExpression.OLD_LAUGH1, "Let me go, can't ye hear them? Howlin' in the dark...").also { stage = 20 } + 3 -> npcl(FacialExpression.OLD_DEFAULT, "I'm not goin' back in that brewery, not fer all the Bitternuts I can carry!").also { stage = 99 } + 4 -> npc(FacialExpression.OLD_DEFAULT, "Are ye here for...the stuff?").also { stage = 30 } + 5 -> npc(FacialExpression.OLD_DISTRESSED, "Arr! Yer messin with me monkey plunder!").also { stage = 40 } + } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + + 10 -> player(FacialExpression.JOLLY, "Arr!").also { stage++ } + 11 -> npc(FacialExpression.OLD_LAUGH1, "Arr!").also { stage++ } + 12 -> player(FacialExpression.JOLLY, "Arr!").also { stage++ } + 13 -> npc(FacialExpression.OLD_LAUGH1, "Arr!").also { stage++ } + 14 -> player(FacialExpression.JOLLY, "Arr!").also { stage++ } + 15 -> npc(FacialExpression.OLD_LAUGH1, "Arr!").also { stage++ } + 16 -> player(FacialExpression.JOLLY, "Arr!").also { stage++ } + 17 -> npc(FacialExpression.OLD_LAUGH1, "Bored now...").also { stage = 99 } + + 20 -> player(FacialExpression.ASKING, "What do you mean?").also { stage++ } + 21 -> npc(FacialExpression.OLD_DISTRESSED, "I'm not hangin' around te be killed!").also { stage++ } + 22 -> npc(FacialExpression.OLD_DISTRESSED, "The Horrors, the Horrors!").also { stage = 99 } + + 30 -> player(FacialExpression.ASKING, "What?").also { stage++ } + 31 -> npc(FacialExpression.OLD_DEFAULT, "You know...the 'special' bananas?").also { stage++ } + 32 -> player(FacialExpression.ASKING, "No... why do you ask?").also { stage++ } + 33 -> npc(FacialExpression.OLD_SAD, "No reason. Have a nice day.").also { stage = 99 } + + 40 -> player(FacialExpression.ASKING, "What?").also { stage = 99 } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return MonkeyChildThingZooDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.MONKEY_4363) + } +} diff --git a/Server/src/main/content/region/kandarin/ardougne/dialogue/PenguinKeeperDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/dialogue/PenguinKeeperDialogue.kt new file mode 100644 index 0000000..9a6ccdf --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/dialogue/PenguinKeeperDialogue.kt @@ -0,0 +1,62 @@ +package content.region.kandarin.ardougne.dialogue + +import core.api.addItem +import core.api.getDynLevel +import core.api.hasAnItem +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class PenguinKeeperDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun getIds(): IntArray { + return intArrayOf(NPCs.PENGUIN_KEEPER_6891) + } + + companion object{ + const val YES = 20 + const val NO = 40 + const val FULL = 50 + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> playerl(FacialExpression.FRIENDLY, "Hello there. How are the penguins doing today?").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "They are doing fine, thanks.").also{ + if (getDynLevel(player, Skills.SUMMONING) < 30 || hasAnItem(player, Items.PENGUIN_EGG_12483).exists()) + stage = END_DIALOGUE + else + stage++ + } + 2 -> npcl(FacialExpression.HALF_ASKING,"Actually, you might be able to help me with something - if you are interested.").also { stage++ } + 3 -> playerl(FacialExpression.ASKING, "What do you mean?").also { stage++ } + 4 -> npcl(FacialExpression.NEUTRAL, "Well, you see, the penguins have been laying so many eggs recently that we can't afford to raise them all ourselves.").also { stage++ } + 5 -> npcl(FacialExpression.ASKING, " You seem to know a bit about raising animals - would you like to raise a penguin for us? ").also { stage++ } + 6 -> showTopics( + Topic("Yes, of course.", YES), + Topic("No thanks.", NO) + ) + + YES -> npcl(FacialExpression.HAPPY, "Wonderful!").also { + if (addItem(player, Items.PENGUIN_EGG_12483)) + stage++ + else + stage = FULL + } + YES + 1 -> npcl(FacialExpression.HAPPY, "Here you go - this egg will hatch into a baby penguin.").also { stage++ } + YES + 2 -> npcl(FacialExpression.HAPPY, "They eat raw fish and aren't particularly fussy about anything, so it won't be any trouble to raise.").also { stage++ } + YES + 3 -> playerl(FacialExpression.HAPPY, "Okay, thank you very much.").also { stage = END_DIALOGUE } + + NO -> npcl(FacialExpression.NEUTRAL, " Fair enough. The offer still stands if you change your mind. ").also { stage = END_DIALOGUE } + + FULL -> npcl(FacialExpression.SAD, "You don't have inventory space though.").also { stage = END_DIALOGUE } + } + return true + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/dialogue/ShopKeeperDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/dialogue/ShopKeeperDialogue.kt new file mode 100644 index 0000000..94051be --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/dialogue/ShopKeeperDialogue.kt @@ -0,0 +1,62 @@ +package content.region.kandarin.ardougne.dialogue + +import content.region.kandarin.dialogue.ShopKeeperDialogue +import core.api.openNpcShop +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class ShopKeeperDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun newInstance(player: Player?): DialoguePlugin { + return content.region.kandarin.ardougne.dialogue.ShopKeeperDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npcl( + FacialExpression.FRIENDLY, + "Hello, you look like a bold adventurer. You've come to the right place for adventurers' equipment." + ).also { stage = START_DIALOGUE } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> options( + "Oh, that sounds interesting.", + "How should I use your shop?", + "No, sorry, I've come to the wrong place." + ).also { stage++ } + + 1 -> when (buttonId) { + 1 -> { + openNpcShop(player, NPCs.AEMAD_590) + end() + } + + 2 -> npcl( + FacialExpression.HAPPY, + "I'm glad you ask! You can buy as many of the items stocked as you wish. You can also sell most items to the shop." + ).also { stage = END_DIALOGUE } + + 3 -> npcl( + FacialExpression.HALF_GUILTY, "Hmph. Well, perhaps next time you'll need something from me?" + ).also { stage = END_DIALOGUE } + + } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.AEMAD_590, NPCs.KORTAN_591) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/dialogue/SilkMerchantPlugin.java b/Server/src/main/content/region/kandarin/ardougne/dialogue/SilkMerchantPlugin.java new file mode 100644 index 0000000..616a942 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/dialogue/SilkMerchantPlugin.java @@ -0,0 +1,220 @@ +package content.region.kandarin.ardougne.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.plugin.Initializable; +import core.game.world.map.RegionManager; + +/** + * Handles the SilkMerchantPlugin dialogue. + * @author 'Vexia + */ +@Initializable +public class SilkMerchantPlugin extends DialoguePlugin { + + /** + * Represents the silk item. + */ + private final Item SILK = new Item(950); + + /** + * Represents the noted silk item. + */ + private final Item NOTED_SILK = new Item(951); + + public SilkMerchantPlugin() { + + } + + public SilkMerchantPlugin(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[] { 574 }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + if (player.getInventory().containsItem(SILK)) { + interpreter.sendDialogues(player, FacialExpression.FRIENDLY, "Hello. I have some fine silk from Al-Kharid to sell to", "you."); + stage = 1; + } else if (player.getInventory().containsItem(NOTED_SILK)) { + interpreter.sendDialogues(player, FacialExpression.ASKING, "I've got some silk here. Will you buy it?"); + stage = 100; + } else { + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Sorry, I don't have any silk."); + stage = 200; + } + break; + case 200: + end(); + break; + case 201: + end(); + break; + case 1: + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Ah, I may be interested in that. What sort of price were", "you looking at per piece of silk?"); + stage = 2; + break; + case 2: + interpreter.sendOptions("Select an Option", "20 coins.", "30 coins.", "120 coins.", "200 coins."); + stage = 3; + break; + case 3: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.FRIENDLY, "20 coins."); + stage = 1000; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.FRIENDLY, "30 coins."); + stage = 2000; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.FRIENDLY, "120 coins."); + stage = 300; + break; + case 4: + interpreter.sendDialogues(player, FacialExpression.FRIENDLY, "200 coins."); + stage = 400; + break; + } + break; + case 1000: + case 2000: + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "That price is fine by me! Hand over your silk."); + stage = stage == 1000 ? 1010 : 1011; + break; + case 1010: + buy(20); + break; + case 1011: + buy(30); + break; + case 300: + case 400: + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "You'll never get that much for it. I'll be generous and", "give you 50 for it."); + stage = 500; + break; + case 500:// use this for selling. + interpreter.sendOptions("Select an Option", "Ok, I guess 50 will do.", "I'll give it to you for 60.", "No, that is not enough."); + stage = 501; + break; + case 501: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.FRIENDLY, "Ok, I guess 50 will do."); + stage = 510; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HAPPY, "I'll give it to you for 60."); + stage = 520; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No, that is not enough."); + stage = 530; + break; + } + break; + case 510: + buy(50); + break; + case 520: + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "You drive a hard bargain, but", "I guess that will have to do."); + stage = 521; + break; + case 521: + buy(60); + break; + case 530: + end(); + break; + case 100: + interpreter.sendDialogues(npc, null, "Silk? You're not carrying any silk."); + stage = 101; + break; + case 101: + interpreter.sendDialogues(player, null, "Yes I am."); + stage = 102; + break; + case 102: + interpreter.sendDialogues(npc, null, "No, you're carrying " + player.getInventory().getAmount(NOTED_SILK) + " bits of paper that say they", "can be exchanged for silk at a bank or general store.", "I'm not buying those. Fetch me some real silk, then", "we'll trade."); + stage = 103; + break; + case 103: + interpreter.sendDialogues(player, null, "Oh, alright."); + stage = 104; + break; + case 104: + end(); + break; + } + return true; + } + + /** + * Method used to buy silk. + * @param price + */ + public final void buy(int price) { + end(); + int amt = player.getInventory().getAmount(SILK); + Item remove = new Item(SILK.getId(), amt); + if (!player.getInventory().containsItem(remove)) { + return; + } + if (player.getInventory().remove(remove)) { + player.getInventory().add(new Item(995, price * amt)); + } + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new SilkMerchantPlugin(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + if (player.getSavedData().getGlobalData().getSilkSteal() > System.currentTimeMillis()) { + end(); + for (NPC npc : RegionManager.getLocalNpcs(player.getLocation(), 8)) { + if (!npc.getProperties().getCombatPulse().isAttacking() && npc.getId() == 32) { + npc.sendChat("Hey! Get your hands off there!"); + npc.getProperties().getCombatPulse().attack(player); + break; + } + } + GameWorld.getPulser().submit(new Pulse(1) { + int count = 0; + + @Override + public boolean pulse() { + if (count == 0) + npc.sendChat("You're the one who stole something from me!"); + if (count == 2) { + npc.sendChat("Guards guards!"); + return true; + } + count++; + return false; + } + + }); + return false; + } + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "I buy silk. If you ever want to", "sell any silk, bring it here."); + stage = 0; + return true; + } +} diff --git a/Server/src/main/content/region/kandarin/ardougne/dialogue/SilkTradeDialogue.java b/Server/src/main/content/region/kandarin/ardougne/dialogue/SilkTradeDialogue.java new file mode 100644 index 0000000..dc2a5b1 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/dialogue/SilkTradeDialogue.java @@ -0,0 +1,147 @@ +package content.region.kandarin.ardougne.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.game.node.item.Item; + +/** + * Handles the SilkTradeDialogue dialogue. + * @author 'Vexia + */ +@Initializable +public class SilkTradeDialogue extends DialoguePlugin { + + public SilkTradeDialogue() { + + } + + public SilkTradeDialogue(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[] { 539 }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "How much are they?", "No, silk doesn't suit me."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_ASKING, "How much are they?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No, silk doesn't suit me."); + stage = 2000; + break; + + } + + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "3gp."); + stage = 11; + break; + case 11: + interpreter.sendOptions("Select an Option", "No, that's too much for me.", "Okay, that sounds good."); + stage = 12; + break; + case 12: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No, that's too much for me."); + stage = 110; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Okay, that sounds good."); + stage = 6000; + break; + + } + break; + case 110: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "2gp and that's as low as I'll go."); + stage = 111; + break; + case 111: + interpreter.sendDialogues(npc, FacialExpression.ANNOYED, "I'm not selling it for any less. You'll only go and sell it", "in Varrock for a profit."); + stage = 113; + break; + case 113: + interpreter.sendOptions("Select an Option", "2gp sounds good.", "No really, I don't want it."); + stage = 114; + break; + case 114: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HAPPY, "2gp sounds good."); + stage = 1000; + break; + case 2: + + break; + + } + break; + case 1000: + if (player.getInventory().contains(995, 2) && player.getInventory().freeSlots() != 0) { + player.getInventory().remove(new Item(995, 2)); + player.getInventory().add(new Item(950, 1)); + interpreter.sendDialogue("You buy some silk for 2gp."); + stage = 1001; + } else if (player.getInventory().freeSlots() == 0) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I don't have enough room, sorry."); + stage = 2000; + } else if (!player.getInventory().contains(995, 2)) { + end(); + player.getPacketDispatch().sendMessage("You need 2 gold coins to buy silk."); + } + break; + case 1001: + end(); + break; + case 2000: + end(); + break; + case 6000: + if (player.getInventory().contains(995, 3) && player.getInventory().freeSlots() != 0) { + player.getInventory().remove(new Item(995, 3)); + player.getInventory().add(new Item(950, 1)); + interpreter.sendDialogue("You buy some silk for 3gp."); + stage = 1001; + } else if (player.getInventory().freeSlots() == 0) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I don't have enough room, sorry."); + stage = 2000; + } else if (!player.getInventory().contains(995, 3)) { + end(); + player.getPacketDispatch().sendMessage("You need 3 gold coins to buy silk."); + } + break; + } + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new SilkTradeDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Do you want to buy any fine silks?"); + stage = 0; + return true; + } +} diff --git a/Server/src/main/content/region/kandarin/ardougne/dialogue/SilverMechantPlugin.java b/Server/src/main/content/region/kandarin/ardougne/dialogue/SilverMechantPlugin.java new file mode 100644 index 0000000..045a51c --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/dialogue/SilverMechantPlugin.java @@ -0,0 +1,68 @@ +package content.region.kandarin.ardougne.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Handles the SilverMechantPlugin dialogue. + * @author 'Vexia + */ +@Initializable +public class SilverMechantPlugin extends DialoguePlugin { + + public SilverMechantPlugin() { + + } + + public SilverMechantPlugin(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[] { 569 }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "Yes please.", "No, thank you."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + end(); + npc.openShop(player); + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "No, thank you."); + stage = 20; + break; + } + break; + case 20: + end(); + break; + } + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new SilverMechantPlugin(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Silver! Silver! Best prices for buying and selling in all", "Kandarin!"); + stage = 0; + return true; + } +} diff --git a/Server/src/main/content/region/kandarin/ardougne/dialogue/SpiceSellerPlugin.java b/Server/src/main/content/region/kandarin/ardougne/dialogue/SpiceSellerPlugin.java new file mode 100644 index 0000000..593d0ac --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/dialogue/SpiceSellerPlugin.java @@ -0,0 +1,69 @@ +package content.region.kandarin.ardougne.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Handles the SpiceSellerPlugin dialogue. + * @author 'Vexia + */ +@Initializable +public class SpiceSellerPlugin extends DialoguePlugin { + + public SpiceSellerPlugin() { + + } + + public SpiceSellerPlugin(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[] { 572 }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "Yes.", "No."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + end(); + npc.openShop(player); + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No, thanks."); + stage = 20; + break; + + } + break; + case 20: + end(); + break; + } + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new SpiceSellerPlugin(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Are you interested in buying or selling spice?"); + stage = 0; + return true; + } +} diff --git a/Server/src/main/content/region/kandarin/ardougne/dialogue/ZookeeperDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/dialogue/ZookeeperDialogue.kt new file mode 100644 index 0000000..c4ff1a8 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/dialogue/ZookeeperDialogue.kt @@ -0,0 +1,82 @@ +package content.region.kandarin.ardougne.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + * Does not include treasure trails dialogue + */ + +@Initializable +class ZookeeperDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + player(FacialExpression.FRIENDLY,"Hi!").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> { + npc(FacialExpression.FRIENDLY, "Welcome to the Ardougne Zoo! How can I help you?").also { stage++ } + } + 1 -> { + options("Do you have any quests for me?", "Where did you get the animals from?").also { stage++ } + } + + 2 -> when (buttonId) { + 1 -> player(FacialExpression.FRIENDLY, "Do you have any quests for me?").also { stage = 10 } + 2 -> player(FacialExpression.FRIENDLY, "Where did you get the animals from?").also { stage = 20 } + } + + 10 -> { + npc(FacialExpression.FRIENDLY, "Not at the moment.", + "The explorers that come back from far away lands tell", + "such amazing tales. Make sure you keep eyes and ears", + "open as you may find new places to explore!").also { stage++ } + } + + 11 -> { + player(FacialExpression.FRIENDLY, "Ooh, I will!").also { stage = 99 } + } + + 20 -> { + npc(FacialExpression.FRIENDLY, "We get them from all over the place!", + "The most exotic creatures have been brought", + "back by explorers and sold to us.").also { stage++ } + } + + 21 -> { + player(FacialExpression.HALF_ASKING, "Where on Gielinor did you get that scary", + "looking Cyclops?!").also { stage++ } + } + + 22 -> { + npc(FacialExpression.LAUGH, "Yes he is scary looking!").also { stage++ } + } + + 23 -> { + npc(FacialExpression.FRIENDLY, "He's from a very far away land, we couldn't", + "find out more as the explorer who brought", + "him back died shortly afterwards!").also { stage = 99 } + } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return ZookeeperDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.ZOO_KEEPER_28) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/handlers/WildernessLeverPlugin.java b/Server/src/main/content/region/kandarin/ardougne/handlers/WildernessLeverPlugin.java new file mode 100644 index 0000000..117dbf5 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/handlers/WildernessLeverPlugin.java @@ -0,0 +1,367 @@ +package content.region.kandarin.ardougne.handlers; + +import core.ServerConstants; +import core.cache.def.impl.SceneryDefinition; +import core.plugin.Initializable; +import core.game.dialogue.DialogueInterpreter; +import core.game.dialogue.DialoguePlugin; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.TeleportManager; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; +import core.plugin.ClassScanner; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playAudio; +import static content.region.wilderness.handlers.WildernessGateHandlerKt.enterDeepWilderness; + +/** + * Handles wilderness levers. + * @author 'Vexia, Player Name + * @version 1.0 + */ +@Initializable +public final class WildernessLeverPlugin extends OptionHandler { + + /** + * The animation used when pulling a lever. + */ + private static final Animation PULL_ANIMATION = new Animation(2140); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (LeverSets set : LeverSets.values()) { + for (int id : set.getIds()) { + SceneryDefinition.forId(id).getHandlers().put("option:pull", this); + } + } + ClassScanner.definePlugin(new LeverDialogue()); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + final Scenery object = (Scenery) node; + final LeverSets set = LeverSets.forId(object.getId()); + if (!set.canPull(player, object)) { + return true; + } + set.pull(player, set.getIndex(object.getId())); + if (set.getTransformId() != -1) { + SceneryBuilder.replace(object, object.transform(set.getTransformId()), 2); + } + return true; + } + + /** + * Method used to pull a lever. + * @param player the player. + * @param lever the lever. + */ + private static void pullLever(final Player player, final LeverSets lever, final int index) { + player.lock(2); + player.animate(lever.getAnimation()); + playAudio(player, Sounds.LEVER_2400); + GameWorld.getPulser().submit(new Pulse(2, player) { + @Override + public boolean pulse() { + if (player.timers.getTimer("teleblock") == null) { + lever.message(player, index); + lever.teleport(player, lever.getLocation(index)); + } else { + player.getPacketDispatch().sendMessage("A magical force has stopped you from teleporting."); + } + return true; + } + }); + } + + /** + * Represents a set of levers. + * @author 'Vexia + */ + public enum LeverSets { + ARDY("wilderness", 1814, 1815, Location.create(2561, 3311, 0), Location.create(3154, 3923, 0)) { + @Override + public void pull(final Player player, final int index, boolean force) { + if (index == 0 && !force) { + player.getDialogueInterpreter().open("wilderness-lever", this, getId(index)); + } else { + pullLever(player, this, index); + } + } + }, + + MAGE_BANK("mage's cave", 5959, 5960, Location.create(3090, 3956, 0), Location.create(2539, 4712, 0)), ARENA("arena", 9706, 9707, Location.create(3105, 3956, 0), Location.create(3105, 3951, 0)) { + @Override + public boolean canPull(Player player, Scenery object) { + if (!player.getSavedData().getActivityData().hasKilledKolodion() && object.getId() == 9706) { + player.getDialogueInterpreter().sendDialogues(905, null, "You're not allowed in there. Come downstairs if you", "want to enter my arena."); + return false; + } + return super.canPull(player, object); + } + + @Override + public Animation getAnimation() { + return new Animation(2142); + } + + @Override + public int getTransformId() { + return -1; + } + }; + + /** + * The name. + */ + private final String name; + + /** + * The lever ids. + */ + private final int ids[]; + + /** + * The locations to teleport to. + */ + private final Location[] locations; + + /** + * Constructs a new {@code LeverSets} {@code Object}. + * @param ids the ids. + */ + private LeverSets(String name, int[] ids, Location... locations) { + this.name = name; + this.ids = ids; + this.locations = locations; + } + + /** + * Constructs a new {@code LeverSets} {@code Object}. + * @param first the first id. + * @param second the second id. + * @param locations the locations. + */ + private LeverSets(String name, int first, int second, Location... locations) { + this(name, new int[] { first, second }, locations); + } + + /** + * Called when a lever object is interacted with. + * @param player the player. + * @param index the index. + * @param force if a forced teleport. + */ + public void pull(final Player player, final int index, boolean force) { + pullLever(player, this, index); + } + + /** + * Used as a wrapper method for {@link #pull(Player, int)}. + * @param player the player. + * @param index the index. + */ + public void pull(final Player player, final int index) { + pull(player, index, false); + } + + /** + * Sends the lever messages on teleporting. + * @param player the player. + * @param index the index. + */ + public void message(final Player player, final int index) { + player.getPacketDispatch().sendMessages("You pull the lever...", "...And teleport " + (index == 0 ? "into" : "out of") + " the " + name + "."); + } + + /** + * Teleports a player to a location. + * @param player the player. + * @param location the location. + */ + public void teleport(final Player player, Location location) { + player.getTeleporter().send(location, TeleportManager.TeleportType.NORMAL, TeleportManager.WILDY_TELEPORT); + } + + /** + * Checks if the player can pull the lever. + * @param player the player. + * @return {@code True} if so. + */ + public boolean canPull(Player player, Scenery object) { + return true; + } + + /** + * Gets the animation. + * @return the animation. + */ + public Animation getAnimation() { + return PULL_ANIMATION; + } + + /** + * Gets the transform id. + * @return the id. + */ + public int getTransformId() { + return 1817; + } + + /** + * Gets the index by the id. + * @param id the id. + * @return the index. + */ + public int getIndex(int id) { + for (int i = 0; i < ids.length; i++) { + if (ids[i] == id) { + return i; + } + } + return -1; + } + + /** + * Gets a lever set by the id. + * @param id the id. + * @return the set. + */ + public static LeverSets forId(int id) { + for (LeverSets set : values()) { + for (int i : set.getIds()) { + if (i == id) { + return set; + } + } + } + return null; + } + + /** + * Gets the location. + * @param index the index. + * @return the location. + */ + public Location getLocation(int index) { + return locations[index == 0 ? 1 : 0]; + } + + /** + * Gets the id. + * @param index the index. + * @return the id. + */ + public int getId(int index) { + return ids[index]; + } + + /** + * Gets the ids. + * @return The ids. + */ + public int[] getIds() { + return ids; + } + + /** + * Gets the location. + * @return The location. + */ + public Location[] getLocations() { + return locations; + } + } + + /** + * Handles the wilderness lever dialogues. + * @author 'Vexia + * @version 1.0 + */ + public static final class LeverDialogue extends DialoguePlugin { + + /** + * The lever set. + */ + private LeverSets lever; + + /** + * The object id. + */ + private int id; + + /** + * Constructs a new {@code LeverDialogue} {@code Object}. + */ + public LeverDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code LeverDialogue} {@code Object}. + * @param player the player. + */ + public LeverDialogue(final Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new LeverDialogue(player); + } + + @Override + public boolean open(Object... args) { + lever = (LeverSets) args[0]; + id = (int) args[1]; + if (ServerConstants.ENHANCED_DEEP_WILDERNESS) { + enterDeepWilderness(player, (player) -> { + lever.pull(player, lever.getIndex(id), true); + return null; + }, "Pulling the lever will teleport you into the deep wilderness."); + } else { + interpreter.sendDialogue("Warning! Pulling the lever will teleport you deep into the wilderness."); + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + options("Yes I'm brave.", "Eep! The wilderness... No thank you."); + stage++; + break; + case 1: + switch (buttonId) { + case 1: + lever.pull(player, lever.getIndex(id), true); + end(); + break; + case 2: + end(); + break; + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { DialogueInterpreter.getDialogueKey("wilderness-lever") }; + } + + } +} diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/FightArena.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/FightArena.kt new file mode 100644 index 0000000..9c97b71 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/FightArena.kt @@ -0,0 +1,103 @@ +package content.region.kandarin.ardougne.quest.arena + +import core.api.addItemOrDrop +import core.api.rewardXP +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import org.rs09.consts.Items.COINS_995 +import content.data.Quests + +@Initializable +class FightArena : Quest(Quests.FIGHT_ARENA, 61, 60, 2, 17, 0, 1, 14) { + override fun newInstance(`object`: Any?): Quest { return this } + override fun drawJournal(player: Player?, stage: Int) { + super.drawJournal(player, stage) + var line = 11 + player ?: return + if (stage == 0) { + line(player, "I can start this quest by speaking to !!Lady Servil?? just", line++) + line(player, "!!North-West?? of the !!Khazard Port??.", line++) + line += 1 + line(player, "I must be able to defeat a !!level 137?? enemy.", line++, player.properties.combatLevel >= 89) + line++ + } + if (stage >= 10) { + line += 1 + line(player, "I encountered a distraught Lady Servil, who said that her son and", line++, stage > 10) + line(player, "husband had been kidnapped by the evil General Khazard,", line++, stage > 10) + line(player, "and were being forced to fight in his fight arena.", line++, stage > 10) + line += 1 + line(player, "I headed to the arena to try and find Lady Servil's son and husband.", line++, stage > 10) + line++ + } + if (stage >= 20) { + line(player, "I found some Khazard armour in the armoury, on the north-east edge of", line++, stage > 20) + line(player, "town. I used it to disguise myself as a guard so I could look around", line++, stage > 20) + line++ + } + if (stage >= 35) { + line(player, "I found Lady Servil's son, Jeremy Servil, in one of the prison cells.", line++, stage > 40) + line(player, "He told me that a bald, fat, lazy guard", line++, stage > 40) + line(player, "with a goatee was in charge of the keys.", line++, stage > 40) + line++ + } + if (stage >= 50) { + line(player, "I found the guard Jeremy mentioned. He said that he'd like a drink,", line++, stage > 55) + line(player, "but too much Khali brew would make him fall asleep.", line++, stage > 55) + line++ + } + if (stage >= 60) { + line(player, "I plied the lazy guard with some Khali brew and he passed out.", line++, stage > 67) + line(player, "I was able to get his keys.", line++, stage > 67) + line++ + } + if (stage >= 68) { + line(player, "I found and freed Jeremy, who told me that his father", line++, stage > 69) + line(player, "had been taken to fight in the Fight Arena. We went there to save him.", line++, stage > 69) + line++ + } + if (stage >= 71) { + line(player, "I had to fight a large ogre to stop it killing Sir Servil.", line++, stage > 72) + line(player, "When I'd defeated it, General Khazard had locked me up.", line++, stage > 72) + line++ + } + if (stage >= 88) { + line(player, "I was led to the fight arena and forced to fight a colossal scorpion,", line++, stage > 88) + line(player, "followed by Khazard's monstrous pet dog called Bouncer.", line++, stage > 90) + line++ + } + if (stage >= 91) { + line(player, "General Khazard released the Servils, but he was so angry", line++, stage >= 99) + line(player, "that I'd killed Bouncer that he came to fight me himself.", line++, stage >= 99) + line++ + } + if (stage >= 99) { + line(player, "I escaped from the arena and returned to Lady Servil", line++, stage == 100) + line(player, "She thanked me profusely and rewarded me for my help.", line++, stage == 100) + line++ + } + if (stage == 100) { + line++ + line(player, "%%QUEST COMPLETE!&&", line) + } + } + + override fun finish(player: Player?) { + super.finish(player) + player ?: return + var ln = 10 + + player.packetDispatch.sendItemZoomOnInterface(COINS_995, 230, 277, 5) + + drawReward(player, "2 Quest Point", ln++) + drawReward(player, "1000 gold coins", ln++) + drawReward(player, "12,175 Attack XP", ln++) + drawReward(player, "2,175 Thieving XP", ln++) + + rewardXP(player, Skills.ATTACK, 12175.0) + rewardXP(player, Skills.THIEVING, 2175.0) + addItemOrDrop(player, COINS_995, 1000) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/FightArenaListeners.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/FightArenaListeners.kt new file mode 100644 index 0000000..8e45263 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/FightArenaListeners.kt @@ -0,0 +1,286 @@ +package content.region.kandarin.ardougne.quest.arena + +import content.region.kandarin.ardougne.quest.arena.dialogue.* +import content.region.kandarin.ardougne.quest.arena.npc.GeneralNPC +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.global.action.DoorActionHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.npc.NPC +import core.game.world.map.Location +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery +import content.data.Quests + +class FightArenaListeners : InteractionListener { + companion object { + + const val GENERAL = NPCs.GENERAL_KHAZARD_258 + const val BARMAN = NPCs.KHAZARD_BARMAN_259 + const val KELVIN = NPCs.KELVIN_260 + const val JOE = NPCs.JOE_261 + const val FIGHTSLAVE = NPCs.FIGHTSLAVE_262 + const val HENGARD = NPCs.HENGRAD_263 + const val JEREMY_A = NPCs.JEREMY_SERVIL_265 + const val JEREMY_B = NPCs.JEREMY_SERVIL_266 + const val JUSTIN = NPCs.JUSTIN_SERVIL_267 + + const val CELL_DOOR_1 = Scenery.PRISON_DOOR_79 + const val CELL_DOOR_2 = Scenery.PRISON_DOOR_80 + const val MAIN_DOOR = Scenery.DOOR_81 + const val CENTER_DOOR = Scenery.DOOR_82 + + const val A_LAZY_GUARD_1 = Scenery.A_LAZY_KHAZARD_GUARD_41494 + const val A_LAZY_GUARD_2 = Scenery.A_LAZY_KHAZARD_GUARD_41496 + const val A_LAZY_GUARD_3 = Scenery.A_LAZY_KHAZARD_GUARD_41497 + + val FULL_ARMOR_STAND = Scenery.A_SUIT_OF_ARMOUR_41490 + val FULL_ARMOR_STAND_1 = getScenery(2619, 3196, 0) + val ONLY_ARMOR_STAND = Scenery.A_SUIT_OF_ARMOUR_41506 + val ONLY_HELM_STAND = Scenery.A_SUIT_OF_ARMOUR_41507 + val EMPTY_STAND = Scenery.A_SUIT_OF_ARMOUR_41508 + + private const val HELMET = Items.KHAZARD_HELMET_74 + private const val ARMOR = Items.KHAZARD_ARMOUR_75 + private const val CELL_KEY = Items.KHAZARD_CELL_KEYS_76 + + val Jeremy = NPC(NPCs.JEREMY_SERVIL_265, Location.create(2616,3167,0)) + val General = GeneralNPC(NPCs.GENERAL_KHAZARD_258, Location.create(2605,3156,0)) + } + + init { + Jeremy.init() + Jeremy.isWalks = true + + General.init() + General.isWalks = true + } + + override fun defineListeners() { + + on(GENERAL, IntType.NPC, "talk-to") { player, npc -> + openDialogue(player, GeneralKhazardDialogue(), npc) + return@on true + } + + on(BARMAN, IntType.NPC, "talk-to") { player, npc -> + openDialogue(player, KhazardBarmanDialogue(), npc) + return@on true + } + + on(JEREMY_A, IntType.NPC, "talk-to") { player, npc -> + openDialogue(player, JeremyServilADialogue(), npc) + return@on true + } + + on(JEREMY_B, IntType.NPC, "talk-to") { player, npc -> + openDialogue(player, JeremyServilBDialogue(), npc) + return@on true + } + + on(HENGARD, IntType.NPC, "talk-to") { player, npc -> + openDialogue(player, HengradDialogue(), npc) + return@on true + } + + on(A_LAZY_GUARD_1, SCENERY, "talk-to") { player, node -> + openDialogue(player, ALazyGuardDialogue(), node) + return@on true + } + on(A_LAZY_GUARD_3, SCENERY, "talk-to") { player, node -> + openDialogue(player, ALazyGuardDialogue(), node) + return@on true + } + + on(JUSTIN, IntType.NPC, "talk-to") { player, npc -> + openDialogue(player, JustinServilDialogue(), npc) + return@on true + } + + on(FULL_ARMOR_STAND, IntType.SCENERY, "borrow") { player, _ -> + if (player.questRepository.getStage(Quests.FIGHT_ARENA) >= 10 && !inEquipmentOrInventory(player, HELMET) && !inEquipmentOrInventory(player, ARMOR) && freeSlots(player) >= 2) { + replaceScenery(FULL_ARMOR_STAND_1!!.asScenery(), EMPTY_STAND, 10,location(2619, 3196, 0)) + sendMessage(player, "You borrow the suit of armour. It looks like it's just your size.") + addItem(player, ARMOR, 1) + addItem(player, HELMET, 1) + } else if (!inEquipmentOrInventory(player, ARMOR) && freeSlots(player) >= 1){ + replaceScenery(FULL_ARMOR_STAND_1!!.asScenery(), ONLY_HELM_STAND, 10,location(2619, 3196, 0)) + addItem(player, ARMOR, 1) + sendMessage(player, "You borrow the suit of helmet. It looks like it's just your size.") + } else if (!inEquipmentOrInventory(player, HELMET) && freeSlots(player) >= 1){ + replaceScenery(FULL_ARMOR_STAND_1!!.asScenery(), ONLY_ARMOR_STAND, 10,location(2619, 3196, 0)) + addItem(player, HELMET, 1) + sendMessage(player, "You could borrow this suit of armour if you had space in your inventory.") + } else if (freeSlots(player) == 0) { + sendMessage(player, "You could borrow this suit of armour if you had space in your inventory.") + } else { + sendMessage(player, "Nothing interesting happens.") + } + return@on true + } + + on(A_LAZY_GUARD_2, IntType.SCENERY, "steal-keys") { player, _ -> + player.faceLocation(location(2618, 3144, 0)) + setVarbit(player,5627,3, true) + animate(player, 2286) + addItemOrDrop(player, CELL_KEY) + sendMessage(player, "You pick up the keys from the table.") + return@on true + } + + on(MAIN_DOOR, IntType.SCENERY, "open") { player, maingate -> + when (player.location.y) { + 3171 -> DoorActionHandler.handleAutowalkDoor(player, maingate.asScenery()) + 3172 -> { + if (allInEquipment(player, HELMET, ARMOR)) { + openDialogue(player, EastDoorSupportDialogue()) + } else { + sendPlayerDialogue(player, "This door appears to be locked.") + } + return@on true + } + } + when (player.location.x) { + 2585 -> DoorActionHandler.handleAutowalkDoor(player, maingate.asScenery()) + 2584 -> { + if (allInEquipment(player, HELMET, ARMOR)) { + openDialogue(player, WestDoorSupportDialogue()) + } else { + sendPlayerDialogue(player, "This door appears to be locked.") + } + return@on true + } + } + return@on true + } + + onUseWith(IntType.SCENERY, CELL_KEY, CELL_DOOR_2) { player, _, _ -> + openDialogue(player, JeremyServilADialogue()) + return@onUseWith true + } + + onUseWith(IntType.SCENERY, CELL_KEY, CELL_DOOR_1) { player, _, _ -> + if (player.questRepository.getStage(Quests.FIGHT_ARENA) >= 68){ + sendDialogue(player, "I don't want to attract too much attention by freeing all the prisoners. I need to find Jeremy and he's not in this cell.") + } else { + sendMessage(player, "The cell gate is securely locked.") + } + return@onUseWith false + } + + on(CELL_DOOR_1, IntType.SCENERY, "open") { player, _ -> + sendMessage(player, "the cell gate is securely locked.") + return@on false + } + + on(CELL_DOOR_2, IntType.SCENERY, "open") { player, _ -> + sendMessage(player, "the cell gate is securely locked.") + return@on false + } + + on(CENTER_DOOR, IntType.SCENERY, "open") { player, node -> + if (player.questRepository.getStage(Quests.FIGHT_ARENA) >= 91) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else if (player.questRepository.getStage(Quests.FIGHT_ARENA) < 91) { + sendNPCDialogue(player, NPCs.KHAZARD_GUARD_255, "And where do you think you're going? Only General Khazard decides who fights in the arena. Get out of here.", FacialExpression.ANNOYED) + } else { + sendMessage(player, "The gate is locked.") + } + return@on true + } + } + + override fun defineDestinationOverrides() { + + setDest(IntType.NPC, intArrayOf(JEREMY_A), "talk-to") { _, _ -> + return@setDest Location.create(2617, 3167, 0) + } + + setDest(IntType.NPC, intArrayOf(BARMAN), "talk-to") { _, _ -> + return@setDest Location.create(2566, 3142, 0) + } + + setDest(IntType.NPC, intArrayOf(FIGHTSLAVE), "talk-to") { player, _ -> + if (inBorders(player, 2585, 3139, 2605, 3148)) { + return@setDest Location.create(2595, 3141, 0) + } else if (inBorders(player, 2616, 3162, 2617, 3165)) { + return@setDest Location.create(2617, 3163, 0) + } else { + return@setDest Location.create(2617, 3159, 0) + } + } + + setDest(IntType.NPC, intArrayOf(KELVIN), "talk-to") { _, _ -> + return@setDest Location.create(2589, 3141, 0) + } + + setDest(IntType.NPC, intArrayOf(JOE), "talk-to") { _, _ -> + return@setDest Location.create(2589, 3141, 0) + } + + setDest(IntType.NPC, intArrayOf(HENGARD), "talk-to") { _, _ -> + return@setDest Location.create(2600, 3142, 0) + } + + setDest(IntType.SCENERY, intArrayOf(CENTER_DOOR), "open") { player, _ -> + if (inBorders(player, 2604, 3152, 2607, 3155)) { + return@setDest Location.create(2605, 3153, 0) + } else { + return@setDest Location.create(2607, 3151, 0) + } + } + + setDest(IntType.SCENERY, intArrayOf(A_LAZY_GUARD_2), "steal-keys") { _, _ -> + return@setDest Location.create(2619, 3143, 0) + } + + } + + class EastDoorSupportDialogue : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + npc = NPC(NPCs.KHAZARD_GUARD_257) + when (stage) { + 0 -> { + face(player!!, location(2617, 3170, 0)) + playerl(FacialExpression.NEUTRAL, "This door appears to be locked.").also { stage++ } + } + + 1 -> { + face(player!!, location(2603, 3155, 0)) + npcl(FacialExpression.NEUTRAL, "Nice observation guard. You could have just asked to be let in like a normal person.").also { stage++ } + } + 2 -> { + end() + lock(player!!, 2) + setQuestStage(player!!, Quests.FIGHT_ARENA, 20) + DoorActionHandler.handleAutowalkDoor(player, getScenery(2617, 3172, 0)) + } + } + } + } + + class WestDoorSupportDialogue : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + npc = NPC(NPCs.KHAZARD_GUARD_257) + when (stage) { + 0 -> { + face(player!!, location(2585, 3141, 0)) + playerl(FacialExpression.NEUTRAL, "This door appears to be locked.").also { stage++ } + } + 1 -> { + face(player!!, location(2603, 3155, 0)) + npcl(FacialExpression.NEUTRAL, "Nice observation guard. You could have just asked to be let in like a normal person.").also { stage++ } + } + 2 -> { + end() + lock(player!!, 2) + setQuestStage(player!!, Quests.FIGHT_ARENA, 20) + DoorActionHandler.handleAutowalkDoor(player, getScenery(2584, 3141, 0)) + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/cutscenes/EscapeCutscene.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/cutscenes/EscapeCutscene.kt new file mode 100644 index 0000000..8c5321b --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/cutscenes/EscapeCutscene.kt @@ -0,0 +1,143 @@ +package content.region.kandarin.ardougne.quest.arena.cutscenes + +import content.region.kandarin.ardougne.quest.arena.FightArenaListeners.Companion.Jeremy +import content.region.kandarin.ardougne.quest.arena.npc.OgreNPC.Companion.spawnOgre +import core.api.* +import core.game.activity.Cutscene +import core.game.dialogue.FacialExpression +import core.game.global.action.DoorActionHandler +import core.game.node.entity.player.Player +import core.game.world.map.Direction +import core.game.world.map.Location + +class EscapeCutscene(player: Player) : Cutscene(player) { + override fun setup() { + setExit(location(2603, 3155, 0)) + if (player.settings.isRunToggled) { + player.settings.toggleRun() + } + } + + override fun runStage(stage: Int) { + when (stage) { + + 0 -> { + move(Jeremy, 56, 31) + timedUpdate(3) + } + + 1 -> { + player.faceLocation(location(56, 31, 0)) + animate(player, 2098) + timedUpdate(4) + } + + 2 -> { + move(player, 57, 32) + timedUpdate(-1) + } + + 3 -> { + DoorActionHandler.handleAutowalkDoor(Jeremy, getObject(57, 31, 0)) + player.faceLocation(location(57, 28, 0)) + timedUpdate(3) + } + + 4 -> { + move(Jeremy, 57, 31) + timedUpdate(1) + } + + 5 -> { + sendChat(Jeremy, "I'll run ahead.") + move(Jeremy, 57, 20) + timedUpdate(5) + } + + 6 -> { + teleport(Jeremy, 56, 31) + loadRegion(10289) + addNPC(JEREMYRESCUE, 41, 17, Direction.NORTH) + addNPC(GENERAL, 45, 19, Direction.NORTH) + addNPC(OGRE, 48, 30, Direction.NORTH) + addNPC(JUSTIN, 41, 32, Direction.EAST) + timedUpdate(-1) + } + + 7 -> { + moveCamera(47, 20) + rotateCamera(45, 15) + teleport(player, 47, 15) + timedUpdate(2) + } + + 8 -> { + DoorActionHandler.handleAutowalkDoor(player, getObject(46, 16)) + moveCamera(41, 26, 300, 4) + rotateCamera(45, 15, 300, 4) + timedUpdate(-1) + } + + 9 -> { + move(player, 44, 17) + timedUpdate(2) + } + + 10 -> { + move(player, 43, 18) + timedUpdate(1) + } + + 11 -> { + move(player, 43, 19) + timedUpdate(3) + } + + 12 -> { + player.faceLocation(getNPC(JEREMYRESCUE)!!.location) + sendPlayerDialogue(player, "Jeremy, where's your father?",FacialExpression.HALF_ASKING) + timedUpdate(2) + } + + 13 -> { + getNPC(JEREMYRESCUE)!!.faceLocation(player.location) + move(getNPC(JUSTIN)!!, 42, 32) + sendNPCDialogue(player, JEREMYRESCUE, "Quick help him! That beast will kill him. He's too old to fight.") + teleport(getNPC(OGRE)!!, 45, 30) + timedUpdate(2) + } + + 14 -> { + moveCamera(42, 26) + rotateCamera(42, 26) + timedUpdate(-1) + } + + 15 -> { + move(getNPC(OGRE)!!, 43, 31) + timedUpdate(4) + } + + 16 -> { + getNPC(OGRE)!!.faceLocation(getNPC(JUSTIN)!!.location) + animate(getNPC(OGRE)!!, 359, true) + animate(getNPC(JUSTIN)!!, 404, true) + timedUpdate(2) + } + + 17 -> { + end { + spawnOgre(player) + } + } + } + } + + companion object { + private const val GENERAL = 258 + private const val JEREMYRESCUE = 266 + private const val JUSTIN = 267 + private const val OGRE = 270 + } +} + diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/cutscenes/JailCutscene.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/cutscenes/JailCutscene.kt new file mode 100644 index 0000000..cbfca60 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/cutscenes/JailCutscene.kt @@ -0,0 +1,76 @@ +package content.region.kandarin.ardougne.quest.arena.cutscenes + +import content.region.kandarin.ardougne.quest.arena.dialogue.HengradDialogue +import core.api.* +import core.game.activity.Cutscene +import core.game.global.action.DoorActionHandler +import core.game.node.entity.player.Player +import core.game.world.map.Direction + +class JailCutscene(player: Player) : Cutscene(player) { + override fun setup() { + setExit(location(2600, 3142, 0)) + if (player.settings.isRunToggled) { + player.settings.toggleRun() + } + loadRegion(10289) + } + + override fun runStage(stage: Int) { + when (stage) { + + 0 -> { + addNPC(KHAZARD_GUARD, 48, 5, Direction.WEST) + teleport(player, 46, 5) + timedUpdate(1) + } + + 1 -> { + moveCamera(43, 4) + rotateCamera(41, 5) + timedUpdate(1) + } + + 2 -> { + move(player, 45, 5) + timedUpdate(1) + } + + 3 -> { + move(player, 40, 5) + move(getNPC(KHAZARD_GUARD)!!, 41, 5) + timedUpdate(6) + } + + 4 -> { + animate(getNPC(KHAZARD_GUARD)!!, 2098) + DoorActionHandler.handleAutowalkDoor(player, getObject(40, 5)) + timedUpdate(5) + } + + 5 -> { + move(player, 40, 6) + face(player, getNPC(KHAZARD_GUARD)!!) + move(getNPC(KHAZARD_GUARD)!!, 40, 5) + timedUpdate(2) + } + + 6 -> { + face(getNPC(KHAZARD_GUARD)!!, player) + sendNPCDialogue(player, KHAZARD_GUARD, "The General seems to have taken a liking to you. He'd normally kill imposters like you without a second thought.") + timedUpdate(3) + } + + 7 -> { + end { + openDialogue(player, HengradDialogue()) + } + } + } + } + + companion object { + private const val KHAZARD_GUARD = 257 + } +} + diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/cutscenes/SecondFightCutscene.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/cutscenes/SecondFightCutscene.kt new file mode 100644 index 0000000..85a41b0 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/cutscenes/SecondFightCutscene.kt @@ -0,0 +1,148 @@ +package content.region.kandarin.ardougne.quest.arena.cutscenes + +import content.region.kandarin.ardougne.quest.arena.npc.ScorpionNPC.Companion.spawnScorpion +import core.api.animate +import core.api.location +import core.api.sendChat +import core.game.activity.Cutscene +import core.game.global.action.DoorActionHandler +import core.game.node.entity.player.Player +import core.game.world.map.Direction + +class SecondFightCutscene(player: Player) : Cutscene(player) { + override fun setup() { + setExit(location(2603, 3155, 0)) + if (player.settings.isRunToggled) { + player.settings.toggleRun() + } + addNPC(GUARD, 36, 5, Direction.EAST) + addNPC(SCORPION, 47, 23, Direction.WEST) + + } + + override fun runStage(stage: Int) { + when (stage) { + + 0 -> { + move(getNPC(GUARD)!!, 39, 5) + sendChat(getNPC(GUARD)!!, "Right you, move it.") + timedUpdate(4) + } + + 1 -> { + move(player, 40, 6) + timedUpdate(1) + } + + 2 -> { + animate(getNPC(GUARD)!!, 805) + timedUpdate(2) + } + + 3 -> { + DoorActionHandler.handleAutowalkDoor(player, getObject(40, 5)) + timedUpdate(2) + } + + 4 -> { + move(player, 42, 5) + timedUpdate(2) + } + + 5 -> { + move(player, 43, 6) + move(getNPC(GUARD)!!, 43, 6) + timedUpdate(-1) + } + + 6 -> { + move(player, 47, 15) + timedUpdate(1) + } + + 7 -> { + move(getNPC(GUARD)!!, 43, 6) + timedUpdate(2) + } + + 8 -> { + move(getNPC(GUARD)!!, 48, 7) + timedUpdate(6) + } + + 9 -> { + move(getNPC(GUARD)!!, 48, 14) + timedUpdate(8) + } + + 10 -> { + sendChat(getNPC(GUARD)!!, "Get out! there.") + DoorActionHandler.handleAutowalkDoor(player, getObject(46, 16)) + move(getNPC(GUARD)!!, 47, 15) + timedUpdate(1) + } + + 11 -> { + move(player, 43, 19) + timedUpdate(2) + } + + 12 -> { + move(getNPC(GUARD)!!, 48, 14) + timedUpdate(1) + } + + 13 -> { + dialogueUpdate("From above you hear a voice..... 'Ladies and gentlemen! Let today's first fight between the outsider and everyone's favourite scorpion commence.'") + timedUpdate(4) + } + + 14 -> { + loadRegion(10289) + addNPC(SCORPION, 47, 23, Direction.WEST) + teleport(player, 43, 19) + timedUpdate(1) + } + + 15 -> { + moveCamera(42, 23) + rotateCamera(46, 23) + timedUpdate(1) + } + + 16 -> { + DoorActionHandler.handleAutowalkDoor(getNPC(SCORPION)!!, getObject(46, 24)) + DoorActionHandler.handleAutowalkDoor(getNPC(SCORPION)!!, getObject(46, 23)) + timedUpdate(1) + } + + 17 -> { + move(getNPC(SCORPION)!!, 45, 20) + moveCamera(37, 23, 300, 5) + rotateCamera(43, 23, 300, 5) + timedUpdate(2) + } + + 18 -> { + move(getNPC(SCORPION)!!, 44, 20) + timedUpdate(1) + } + + 19 -> { + move(getNPC(SCORPION)!!, 42, 20) + timedUpdate(3) + } + + 20 -> { + end { + spawnScorpion(player) + } + } + } + } + + companion object { + const val GUARD = 257 + const val SCORPION = 271 + } +} diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/cutscenes/ThirdFightCutscene.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/cutscenes/ThirdFightCutscene.kt new file mode 100644 index 0000000..f978147 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/cutscenes/ThirdFightCutscene.kt @@ -0,0 +1,68 @@ +package content.region.kandarin.ardougne.quest.arena.cutscenes + +import content.region.kandarin.ardougne.quest.arena.npc.BouncerNPC.Companion.spawnBouncer +import core.game.activity.Cutscene +import core.game.global.action.DoorActionHandler +import core.game.node.entity.player.Player +import core.game.world.map.Direction + +class ThirdFightCutscene(player: Player) : Cutscene(player) { + + override fun setup() { + setExit(player.location.transform(0, 0, 0)) + if (player.settings.isRunToggled) { + player.settings.toggleRun() + } + loadRegion(10289) + addNPC(BOUNCER, 47, 26, Direction.WEST) + } + + override fun runStage(stage: Int) { + when (stage) { + + 0 -> { + teleport(player, 43, 19) + timedUpdate(1) + } + + 1 -> { + moveCamera(43, 27, 300, 100) + moveCamera(42, 27, 300, 100) + rotateCamera(46, 27, 300, 100) + timedUpdate(2) + } + + 2 -> { + DoorActionHandler.handleAutowalkDoor(getNPC(BOUNCER)!!, getObject(46, 26)) + timedUpdate(2) + } + + 3 -> { + move(getNPC(BOUNCER)!!, 45, 26) + moveCamera(37, 27, 300, 5) + rotateCamera(44, 27, 300, 5) + timedUpdate(2) + } + + 4 -> { + move(getNPC(BOUNCER)!!, 44, 26) + timedUpdate(1) + } + + 5 -> { + move(getNPC(BOUNCER)!!, 42, 26) + timedUpdate(3) + } + + 6 -> { + end { + spawnBouncer(player) + } + } + } + } + + companion object { + const val BOUNCER = 269 + } +} diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/ALazyGuardDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/ALazyGuardDialogue.kt new file mode 100644 index 0000000..2a4ffa5 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/ALazyGuardDialogue.kt @@ -0,0 +1,114 @@ +package content.region.kandarin.ardougne.quest.arena.dialogue + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.item.Item +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.Items.KHALI_BREW_77 +import org.rs09.consts.Items.KHAZARD_CELL_KEYS_76 +import org.rs09.consts.NPCs + +class ALazyGuardDialogue : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + npc = NPC(NPCs.A_LAZY_KHAZARD_GUARD_8498) + when (getQuestStage(player!!, Quests.FIGHT_ARENA)) { + + in 40..49 -> when (stage) { + 0 -> { + player!!.faceLocation(location(2617, 3144, 0)) + playerl(FacialExpression.NEUTRAL, "Long live General Khazard!").also { stage++ } + } + 1 -> npcl(FacialExpression.FRIENDLY, "Erm.. yes.. quite right.").also { stage++ } + 2 -> npcl(FacialExpression.FRIENDLY, "Have you come to laugh at the fight slaves? I used to really enjoy it, but after a while they become quite boring. ").also { stage++ } + 3 -> npcl(FacialExpression.FRIENDLY, "Now I just want a decent drink. Mind you, too much Khali brew and I'll fall asleep.").also { stage++ } + 4 -> { + end() + setQuestStage(player!!, Quests.FIGHT_ARENA, 50) + } + } + + + in 50..59 -> when (stage) { + 0 -> if (!allInEquipment(player!!, Items.KHAZARD_HELMET_74, Items.KHAZARD_ARMOUR_75)) { + player!!.faceLocation(location(2617, 3144, 0)) + npcl(FacialExpression.DRUNK, "Go away. Thish areash resh... restricted! We don't like strangersh, 'specially ones who sway. Oooh!").also { stage = END_DIALOGUE } + } else { + player!!.faceLocation(location(2617, 3144, 0)) + playerl(FacialExpression.NEUTRAL, "Hello, how's the job?").also { stage++ } + } + 1 -> npcl(FacialExpression.DRUNK, "Please, leave me alone. I'm sure the walls never used to sway that much.").also { stage = END_DIALOGUE } + } + + + in 60..67 -> when (stage) { + 0 -> { + setVarbit(player!!, 5627, 0) + player!!.faceLocation(location(2617, 3144, 0)) + playerl(FacialExpression.FRIENDLY, "Hello again.").also { stage++ } + } + 1 -> npcl(FacialExpression.NEUTRAL, "Bored, bored, bored. You'd think the slaves would be more entertaining? Selfish the lot of them.").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "Do you still fancy a drink?").also { stage++ } + 3 -> npcl(FacialExpression.HAPPY, "I really shouldn't... oh... ok then just the one.").also { stage++ } + 4 -> if (player!!.inventory.remove(Item(KHALI_BREW_77))) { + sendItemDialogue(player!!, KHALI_BREW_77, "You hand a bottle of Khali brew to the guard. He takes a mouthful of the drink.").also { stage = 5 } + setVarbit(player!!, 5627, 1, true) // swap beer to Khali brew + } else { + npcl(FacialExpression.NEUTRAL, "Now I just want a decent drink. Mind you, too much Khali brew and I'll fall asleep.").also { stage = END_DIALOGUE } + } + 5 -> npcl(FacialExpression.DRUNK, "Blimey this stuff is pretty good. It's not too strong is it?").also { stage++ } + 6 -> playerl(FacialExpression.HALF_GUILTY, "No, not at all. You'll be fine.").also { stage++ } + 7 -> sendDialogue(player!!, "The guard quickly finishes the rest of the bottle and begins to sway slightly.").also { stage++ } + 8 -> npcl(FacialExpression.HAPPY, "That is some gooood stuff... yeah... wooh yeah!").also { stage++ } + 9 -> playerl(FacialExpression.HALF_WORRIED, "Are you alright?").also { stage++ } + 10 -> npcl(FacialExpression.DRUNK, "Yeesshh, hiccup! Oooh, maybe I sshould relax for a while.").also { stage++ } + 11 -> playerl(FacialExpression.NEUTRAL, "Good idea. I'll look after the prisoners.").also { stage++ } + 12 -> npcl(FacialExpression.DRUNK, "Yeesh, yes that shounds reasonable. Here, hiccup', take the keysch. Any trouble, you give... you givem a good beating.").also { stage++ } + 13 -> playerl(FacialExpression.NEUTRAL, "No problem. I'll keep them in line.").also { stage++ } + 14 -> { + end() + setVarbit(player!!, 5627, 2) + setQuestStage(player!!, Quests.FIGHT_ARENA, 68) + } + } + + + in 68..99 -> when (stage) { + 0 -> if (player!!.inventory.containItems(KHAZARD_CELL_KEYS_76)) { + setVarbit(player!!, 5627, 0) + player!!.faceLocation(location(2617, 3144, 0)) + playerl(FacialExpression.HALF_ASKING, "Hello, how's the job?").also { stage = 1 } + } else { + setVarbit(player!!, 5627, 0) + player!!.faceLocation(location(2617, 3144, 0)) + playerl(FacialExpression.HALF_GUILTY, "Hi, er.. I lost the keys.").also { stage = 2 } + } + 1 -> npcl(FacialExpression.DRUNK, "Please, leave me alone. I'm sure the walls never used to sway that much.").also { stage = END_DIALOGUE } + 2 -> npcl(FacialExpression.DRUNK, "What?! You're foolish...").also { stage++ } + 3 -> npcl(FacialExpression.DRUNK, "...and I'm drunk. Here, take my spare set.").also { stage++ } + 4 -> { + end() + setVarbit(player!!, 5627, 3) + player!!.inventory.add(Item(KHAZARD_CELL_KEYS_76)) + sendMessage(player!!, "You pick up the keys from the table.") + } + } + + 100 -> when(stage){ + 0 ->{ + setVarbit(player!!, 5627, 0) + player!!.faceLocation(location(2617, 3144, 0)) + playerl(FacialExpression.HALF_ASKING, "Hello, how's the job?").also { stage++ } + } + 1 -> npcl(FacialExpression.DRUNK, "Please, leave me alone. I'm sure the walls never used to sway that much.").also { stage++ } + 2 -> { + end() + setVarbit(player!!, 5627, 3) + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/FightslaveDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/FightslaveDialogue.kt new file mode 100644 index 0000000..5bac222 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/FightslaveDialogue.kt @@ -0,0 +1,40 @@ +package content.region.kandarin.ardougne.quest.arena.dialogue + +import core.api.allInEquipment +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class FightslaveDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + if (allInEquipment(player, Items.KHAZARD_HELMET_74, Items.KHAZARD_ARMOUR_75)) { + playerl(FacialExpression.FRIENDLY, "Do you know of a Justin or Jeremy in this arena?").also { stage = 0 } + } else { + playerl(FacialExpression.FRIENDLY, "Do you know of a Justin or Jeremy in this arena?").also { stage = 1 } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> npcl(FacialExpression.FRIENDLY, "Please leave me alone.").also { stage = END_DIALOGUE } + 1 -> npcl(FacialExpression.AFRAID, "I've not met anybody in here by that name.").also { stage = END_DIALOGUE } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return FightslaveDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.FIGHTSLAVE_262) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/GeneralKhazardDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/GeneralKhazardDialogue.kt new file mode 100644 index 0000000..11b516b --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/GeneralKhazardDialogue.kt @@ -0,0 +1,131 @@ +package content.region.kandarin.ardougne.quest.arena.dialogue + +import content.data.Quests +import content.region.kandarin.ardougne.quest.arena.FightArenaListeners.Companion.General +import content.region.kandarin.ardougne.quest.arena.cutscenes.JailCutscene +import content.region.kandarin.ardougne.quest.arena.cutscenes.ThirdFightCutscene +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.world.map.RegionManager +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class GeneralKhazardDialogue : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + npc = NPC(NPCs.GENERAL_KHAZARD_258) + when (getQuestStage(player!!, Quests.FIGHT_ARENA)) { + + in 68..70 -> when(stage){ + 0 -> npcl(FacialExpression.FRIENDLY, "Out of the way, guard! I don't tolerate disruption when I'm watching slaves being slaughtered.").also { stage = END_DIALOGUE } + } + + 71 -> when (stage) { + 0 -> if (!anyInEquipment(player!!, Items.KHAZARD_HELMET_74, Items.KHAZARD_ARMOUR_75)) { + face(player!!, findNPC(NPCs.GENERAL_KHAZARD_258)!!, 1) + sendPlayerDialogue(player!!, "General Khazard?").also { stage = 2 } + } else { + face(player!!, findNPC(NPCs.GENERAL_KHAZARD_258)!!, 1) + face(findNPC(NPCs.GENERAL_KHAZARD_258)!!, player!!,1) + sendNPCDialogue(player!!, NPCs.GENERAL_KHAZARD_258, "Who dares enter my home? You? A feeble traveller?", FacialExpression.OLD_DEFAULT).also { stage = 6 } + } + 2 -> npcl(FacialExpression.OLD_DEFAULT, "What do you want guard? I'm a busy man.").also { stage++ } + 3 -> playerl(FacialExpression.FRIENDLY, "Of course sir.").also { stage++ } + 4 -> npcl(FacialExpression.OLD_DEFAULT, "In the last two hundred years, I have survived all horrors imaginable. Now it is my turn to cover this land in darkness. One day you shall see, all will quake on hearing my name.").also { stage++ } + 5 -> npcl(FacialExpression.OLD_DEFAULT, "Now leave me.").also { stage = END_DIALOGUE } + 6 -> playerl(FacialExpression.ASKING, "Feeble?!").also { stage++ } + 7 -> npcl(FacialExpression.OLD_DEFAULT, "Get out! Whoever let you in shall be severely punished for this.").also { stage = END_DIALOGUE } + } + + 72 -> when (stage) { + 0 -> { + lockInteractions(player!!, 2) + face(player!!, findNPC(NPCs.JUSTIN_SERVIL_267)!!, 1) + face(findNPC(NPCs.JUSTIN_SERVIL_267)!!, player!!, 1) + sendNPCDialogue(player!!, NPCs.JUSTIN_SERVIL_267, "You saved my life and my son's, I am eternally in your debt brave traveller.").also { stage++ } + } + 1 -> { + face(findNPC(NPCs.GENERAL_KHAZARD_258)!!, player!!, 1) + npcl(FacialExpression.OLD_DEFAULT, "Haha, well done, well done that was rather entertaining. I am the great General Khazard, and the two men you just 'saved' are my property.").also { stage++ } + } + 2 -> { + face(player!!, findNPC(NPCs.GENERAL_KHAZARD_258)!!, 1) + playerl(FacialExpression.ANGRY, "They belong to nobody.").also { stage++ } + } + 3 -> npcl(FacialExpression.OLD_DEFAULT, "Well, I suppose we could find some arrangement for their freedom... hmmm?").also { stage++ } + 4 -> playerl(FacialExpression.ASKING, "What do you mean?").also { stage++ } + 5 -> npcl(FacialExpression.OLD_DEFAULT, "I'll let them go, but you must stay and fight for me. You'll make me double the gold if you manage to last a few fights.").also { stage++ } + 6 -> npcl(FacialExpression.OLD_ANGRY1, "Guards! Take " + (if (player!!.isMale) "him" else "her") + " to the cells.").also { stage++ } + 7 -> { + end() + JailCutscene(player!!).start() + setAttribute(player!!, "spawn-scorpion", true) + sendMessage(player!!, "A guard grabs the keys to the cell doors.") + } + } + + 87 -> when (stage) { + 0 -> { + face(findNPC(NPCs.GENERAL_KHAZARD_258)!!, player!!) + face(player!!, findNPC(NPCs.GENERAL_KHAZARD_258)!!, 1) + npcl(FacialExpression.OLD_ANGRY1, "How dare you speak to me, you are a slave of this arena now.").also { stage = END_DIALOGUE } + } + } + + 88 -> when (stage) { + 0 -> { + end() + JailCutscene(player!!).start() + setAttribute(player!!, "spawn-scorpion", true) + } + } + + 89 -> when (stage) { + 0 -> { + lockInteractions(player!!, 2) + face(findNPC(NPCs.GENERAL_KHAZARD_258)!!, player!!, 1) + face(player!!, findNPC(NPCs.GENERAL_KHAZARD_258)!!, 1) + npcl(FacialExpression.OLD_ANGRY1, "Not bad, not bad at all. I think you need a tougher challenge. Time for my puppy. Guards! Guards! Bring on Bouncer!").also { stage++ } + } + 1 -> sendDialogue(player!!, "From above you hear a voice..... 'Ladies and gentlemen! Today's second round of battle is between the outsider and Bouncer.'").also { stage++ } + 2 -> { + end() + setAttribute(player!!, "spawn-bouncer", true) + ThirdFightCutscene(player!!).start() + } + } + + 91 -> when (stage) { + 0 -> { + lockInteractions(player!!, 4) + npcl(FacialExpression.OLD_NEARLY_CRYING, "Nooooo! Bouncer! How dare you? You've taken the life of my old friend. Now you'll suffer traveller, prepare to meet your maker.").also { stage++ } + face(player!!, findNPC(NPCs.GENERAL_KHAZARD_258)!!, 1) + } + 1 -> playerl(FacialExpression.ANNOYED, "You agreed to let the Servils go if I stayed to fight.").also { stage++ } + 2 -> npcl(FacialExpression.OLD_DEFAULT, "Indeed. I obviously underestimated you, although you still pale in comparsion to the might of General Khazard.").also { stage++ } + 3 -> npcl(FacialExpression.OLD_NEARLY_CRYING, "You shall see that I am not cowardlly enough to make false promises. They may go.").also { stage++ } + 4 -> npcl(FacialExpression.OLD_EVIL_LAUGH, "You however have coused me much trouble today. You must remain here so that I may at least have the pleasure of killing you myself.").also { stage++ } + 5 -> { + end() + setQuestStage(player!!, Quests.FIGHT_ARENA, 97) + RegionManager.getNpc(player!!.location, NPCs.GENERAL_KHAZARD_258, 15) + General.attack(player!!) + } + } + + 100 -> when (stage) { + 0 -> { + face(player!!, findNPC(NPCs.GENERAL_KHAZARD_258)!!, 1) + playerl(FacialExpression.ANNOYED, "Didn't I kill you?").also { stage++ } + } + 1 -> { + face(findNPC(NPCs.GENERAL_KHAZARD_258)!!, player!!, 1) + npcl(FacialExpression.FRIENDLY,"You might not believe, it, young one, but you can't kill me.").also { stage = END_DIALOGUE } + } + + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/GuardsDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/GuardsDialogue.kt new file mode 100644 index 0000000..77fd6c1 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/GuardsDialogue.kt @@ -0,0 +1,159 @@ +package content.region.kandarin.ardougne.quest.arena.dialogue + +import core.api.allInEquipment +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import content.data.Quests + + +@Initializable +class GuardsDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + if (player.questRepository.getStage(Quests.FIGHT_ARENA) == 100) { + npcl(FacialExpression.FRIENDLY, "It's you! I don't believe it. You beat the General! You are a traitor to the uniform!").also { stage = END_DIALOGUE } + } else if (allInEquipment(player, Items.KHAZARD_HELMET_74, Items.KHAZARD_ARMOUR_75)) { + playerl(FacialExpression.FRIENDLY, "Hello.").also { stage = 0 } + } else { + playerl(FacialExpression.FRIENDLY, "Hi.").also { stage = 2 } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> npcl(FacialExpression.ASKING, "Can I help you stranger?").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "Oh, you're a guard as well. That's ok then. We don't like strangers around here").also { stage = END_DIALOGUE } + } + when (stage) { + 2 -> npcl(FacialExpression.ANNOYED, "I don't know you stranger. Get off our land.").also { stage = END_DIALOGUE + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return GuardsDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.KHAZARD_GUARD_253) + } +} + +@Initializable +class KhazardGuard254Dialogue(player: Player? = null) : DialoguePlugin(player) { + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + if (player.questRepository.getStage(Quests.FIGHT_ARENA) == 100) { + npcl(FacialExpression.FRIENDLY, "It's you! I don't believe it. You beat the General! You are a traitor to the uniform!").also { stage = END_DIALOGUE } + } else if (allInEquipment(player, Items.KHAZARD_HELMET_74, Items.KHAZARD_ARMOUR_75)) { + playerl(FacialExpression.FRIENDLY, "Hello.").also { stage = 0 } + } else { + playerl(FacialExpression.FRIENDLY, "Hi.").also { stage = 7 } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> npcl(FacialExpression.FRIENDLY, "I've never seen you around here before!").also { stage++ } + 1 -> playerl(FacialExpression.FRIENDLY, "Long live General Khazard!").also { stage++ } + 2 -> npcl(FacialExpression.FRIENDLY, "Erm.. yes.. soldier, I take it you're new around here?").also { stage++ } + 3 -> playerl(FacialExpression.FRIENDLY, "You could say that.").also { stage++ } + 4 -> npcl(FacialExpression.FRIENDLY, "Khazard died two hundred years ago. However his dark spirit remains in the form of the undead maniac General Khazard. Remember he is your master, always watching.").also { stage++ } + 5 -> npcl(FacialExpression.FRIENDLY, "Got that newbie?").also { stage++ } + 6 -> playerl(FacialExpression.FRIENDLY, "Undead, maniac, master. Got it, loud and clear.").also { stage = END_DIALOGUE } + 7 -> npcl(FacialExpression.ANNOYED, "This area is restricted. Leave now! OUT! And don't come back.").also { stage++ } + 8 -> options("I apologise, I stumbled in here by mistake.", "You have no right to tell me where I can and cannot go.").also { stage++ } + 9 -> when(buttonId){ + 1 -> playerl(FacialExpression.HALF_WORRIED, "I apologise, I stumbled in here by mistake.").also { stage = 10 } + 2 -> playerl(FacialExpression.HALF_WORRIED, "You have no right to tell me where I can and cannot go.").also { stage = 11 } + } + 10 -> npcl(FacialExpression.FRIENDLY, "Well, don't just stand there - get out of here!").also { stage = END_DIALOGUE } + 11 -> npcl(FacialExpression.FRIENDLY, "Fair enough. Let's do this the hard way.").also { stage = END_DIALOGUE } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return KhazardGuard254Dialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.KHAZARD_GUARD_254) + } +} + +@Initializable +class KhazardGuard255Dialogue(player: Player? = null) : DialoguePlugin(player) { + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + if (player.questRepository.getStage(Quests.FIGHT_ARENA) == 100) { + npcl(FacialExpression.FRIENDLY, "It's you! I don't believe it. You beat the General! You are a traitor to the uniform!").also { stage = END_DIALOGUE } + } else if (allInEquipment(player, Items.KHAZARD_HELMET_74, Items.KHAZARD_ARMOUR_75)) { + playerl(FacialExpression.FRIENDLY, "Hello.").also { stage = 0 } + } else { + playerl(FacialExpression.FRIENDLY, "Hi.").also { stage = 2 } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> npcl(FacialExpression.ASKING, "Can I help you stranger?").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "Oh, you're a guard as well. That's ok then. We don't like strangers around here.").also { stage = END_DIALOGUE } + 2 -> npcl(FacialExpression.ANNOYED, "This area is restricted, leave now!").also { stage++ } + 3 -> npcl(FacialExpression.ANGRY, "OUT! And don't come back!").also { stage = END_DIALOGUE } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return KhazardGuard255Dialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.KHAZARD_GUARD_255) + } +} + +@Initializable +class KhazardGuard256Dialogue(player: Player? = null) : DialoguePlugin(player) { + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + if (allInEquipment(player, Items.KHAZARD_HELMET_74, Items.KHAZARD_ARMOUR_75)) { + playerl(FacialExpression.FRIENDLY, "Hello.").also { stage = 0 } + } else if (player.questRepository.getStage(Quests.FIGHT_ARENA) == 100) { + npcl(FacialExpression.FRIENDLY, "It's you! I don't believe it. You beat the General! You are a traitor to the uniform!").also { stage = END_DIALOGUE } + } else { + playerl(FacialExpression.FRIENDLY, "Hi.").also { stage = 3 } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> npcl(FacialExpression.ANGRY, "Despicable thieving scum, that was good armour. Did you see anyone around here soldier?").also { stage++ } + 1 -> playerl(FacialExpression.SILENT, "Me? No, no one!").also { stage++ } + 2 -> npcl(FacialExpression.SUSPICIOUS, "Hmmmm").also { stage = END_DIALOGUE } + 3 -> npcl(FacialExpression.ANNOYED, "I don't know who you are. Get out of my house stranger.").also { stage = END_DIALOGUE } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return KhazardGuard256Dialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.KHAZARD_GUARD_256) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/HengradDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/HengradDialogue.kt new file mode 100644 index 0000000..bd31acf --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/HengradDialogue.kt @@ -0,0 +1,49 @@ +package content.region.kandarin.ardougne.quest.arena.dialogue + +import content.data.Quests +import content.region.kandarin.ardougne.quest.arena.cutscenes.SecondFightCutscene +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import org.rs09.consts.NPCs + +class HengradDialogue : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + npc = NPC(NPCs.HENGRAD_263) + when (getQuestStage(player!!, Quests.FIGHT_ARENA)) { + + in 72..87 -> when (stage) { + 0 -> { + lockInteractions(player!!, 10) + face(findNPC(NPCs.HENGRAD_263)!!,player!!, 1) + npcl(FacialExpression.AFRAID, "Are you ok stranger?").also { stage++ } + } + 1 -> { + face(player!!,findNPC(NPCs.HENGRAD_263)!!, 1) + playerl(FacialExpression.FRIENDLY, "I'm fine thanks.").also { stage++ } + } + 2 -> npcl(FacialExpression.ASKING, " So Khazard got his hand on you too?").also { stage++ } + 3 -> playerl(FacialExpression.HALF_WORRIED, " I'm afraid so.").also { stage++ } + 4 -> npcl(FacialExpression.FRIENDLY, " If you're lucky you may last as long as me.").also { stage++ } + 5 -> playerl(FacialExpression.ASKING, " How long have you been here?").also { stage++ } + 6 -> npcl(FacialExpression.FRIENDLY, " I've been in Khazard's prisons ever since I can remember. I was a child when his men kidnapped me. My whole life as been spent killing and fighting, all in the hope that, one day, I might escape.").also { stage++ } + 7 -> playerl(FacialExpression.FRIENDLY, "Don't give up.").also { stage++ } + 8 -> npcl(FacialExpression.FRIENDLY, "Thanks friend.").also { stage++ } + 9 -> npcl(FacialExpression.SILENT, "Wait... Shhh, the guard is coming. Looks like you'll be going into the arena. Good luck, friend.").also { stage++ } + 10 -> { + end() + SecondFightCutscene(player!!).start() + setQuestStage(player!!, Quests.FIGHT_ARENA, 88) + } + } + + 88 -> when (stage) { + 0 -> { + end() + SecondFightCutscene(player!!).start() + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/JeremyServilADialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/JeremyServilADialogue.kt new file mode 100644 index 0000000..e92454d --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/JeremyServilADialogue.kt @@ -0,0 +1,61 @@ +package content.region.kandarin.ardougne.quest.arena.dialogue + +import content.data.Quests +import content.region.kandarin.ardougne.quest.arena.cutscenes.EscapeCutscene +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +class JeremyServilADialogue : DialogueFile() { + + override fun handle(componentID: Int, buttonID: Int) { + npc = NPC(NPCs.JEREMY_SERVIL_265) + when (getQuestStage(player!!, Quests.FIGHT_ARENA)) { + + 20 -> when (stage) { + 0 -> { + face(player!!, findNPC(NPCs.JEREMY_SERVIL_265)!!, 1) + playerl(FacialExpression.FRIENDLY, "Hello.").also { stage++ } + } + 1 -> { + face(findNPC(NPCs.JEREMY_SERVIL_265)!!, player!!, 1) + npcl(FacialExpression.FRIENDLY, "Please " + (if (player!!.isMale) "Sir" else "Madam") + ", don't hurt me.").also { stage++ } + } + 2 -> playerl(FacialExpression.FRIENDLY, "Sshh. This uniform is a disguise. I'm here to help. Where do they keep the keys?").also { stage++ } + 3 -> npcl(FacialExpression.FRIENDLY, "The guard always keeps hold of them.").also { stage++ } + 4 -> playerl(FacialExpression.FRIENDLY, "Don't lose heart, I'll be back.").also { stage++ } + 5 -> { + end() + setQuestStage(player!!, Quests.FIGHT_ARENA, 40) + } + } + + in 68..89 -> when (stage) { + 0 -> { + face(player!!, findNPC(NPCs.JEREMY_SERVIL_265)!!, 2) + playerl(FacialExpression.FRIENDLY, "Jeremy look, I have the keys.").also { stage++ } + } + 1 -> { + face(findNPC(NPCs.JEREMY_SERVIL_265)!!, player!!, 2) + npcl(FacialExpression.AMAZED, "Wow! Please set me free, then we can find my dad. I overheard a guard talking. I think they're taken him to the arena.").also { stage++ } + } + 2 -> playerl(FacialExpression.NEUTRAL, "Ok, we'd better hurry.").also { stage++ } + 3 -> { + end() + setAttribute(player!!, "spawn-ogre", true) + EscapeCutscene(player!!).start() + } + } + + in 90..100 -> when (stage) { + 0 -> { + face(player!!, findNPC(NPCs.JEREMY_SERVIL_265)!!, 1) + npcl(FacialExpression.FRIENDLY, "You need to kill the creatures in the arena").also { stage = END_DIALOGUE } + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/JeremyServilBDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/JeremyServilBDialogue.kt new file mode 100644 index 0000000..7f87687 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/JeremyServilBDialogue.kt @@ -0,0 +1,74 @@ +package content.region.kandarin.ardougne.quest.arena.dialogue + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +class JeremyServilBDialogue : DialogueFile() { + + override fun handle(componentID: Int, buttonID: Int) { + npc = NPC(NPCs.JEREMY_SERVIL_266) + when (getQuestStage(player!!, Quests.FIGHT_ARENA)) { + + in 1..84 -> when (stage) { + 0 -> { + face(player!!, findNPC(NPCs.JEREMY_SERVIL_266)!!, 1) + playerl(FacialExpression.FRIENDLY, "Don't worry, I'll get us out of here.").also { stage++ } + } + 1 -> npcl(FacialExpression.FRIENDLY, "Thanks, traveller. I'm sorry that you too are a subject of this arena.").also { stage = END_DIALOGUE } + } + + in 85..97 -> when (stage) { + 0 -> { + lockInteractions(player!!, 1) + face(player!!, findNPC(NPCs.JEREMY_SERVIL_266)!!, 1) + playerl(FacialExpression.FRIENDLY, "You and you father can return to Lady Servil.").also { stage++ } + } + 1 -> npcl(FacialExpression.FRIENDLY, "Thank you, we are truly indebted to you.").also { stage++ } + 2 -> { + end() + setQuestStage(player!!, Quests.FIGHT_ARENA, 99) + } + } + + + 98 -> when (stage) { + 0 -> { + face(player!!, findNPC(NPCs.JEREMY_SERVIL_266)!!, 1) + sendPlayerDialogue(player!!, "Khazard is dead, you and you father can return to Lady Servil.").also { stage++ } + } + 1 -> { + face(findNPC(NPCs.JEREMY_SERVIL_266)!!,player!!, 1) + npcl(FacialExpression.FRIENDLY, "Thank you, we are truly indebted to you.").also { stage++ } + } + 2 -> { + end() + setQuestStage(player!!, Quests.FIGHT_ARENA, 99) + } + } + + 100 -> when (stage) { + 0 -> { + face(player!!, findNPC(NPCs.JEREMY_SERVIL_266)!!, 1) + playerl(FacialExpression.FRIENDLY, "Hiya kiddo! You're looking a lot happier now.").also { stage++ } + } + 1 -> { + face(findNPC(NPCs.JEREMY_SERVIL_266)!!,player!!, 1) + npcl(FacialExpression.FRIENDLY,"Thank you " + (if (player!!.isMale) "Sir" else "Madam") + " I saw you fighting in the arena. You were brilliant! You were like POW! and then you got hit, but you were like too hard and didn't care and then you like hit him again and KERPLOW! Then the big scary dog came out, but you weren't scared and you like smacked him as well, and then you...").also { stage++ } + } + 2 -> playerl(FacialExpression.FRIENDLY, "Jeremy, calm down. Player doesn't need to hear everything " + (if (player!!.isMale) "He" else "She") + " did. " + (if (player!!.isMale) "He" else "She") + " was there when it happened, remember.").also { stage++ } + 3 -> sendNPCDialogue(player!!, NPCs.LADY_SERVIL_264, "I was rather enjoying it, actually.").also { stage++ } + 4 -> npcl(FacialExpression.FRIENDLY, "Yeah, but mum... ${player!!.username} was so cool. " + (if (player!!.isMale) "He" else "She") + " was like BAM! BASH! SPLAT! When I grow up, I wanna be a hero as well.").also { stage++ } + 5 -> playerl(FacialExpression.FRIENDLY, "I'm sure you will be. You showed a lot of bravery in the arena, young lad. If you work hard to complete your squire training, you'll be a worthy knight. Trust me, I can tell these things.").also { stage++ } + 6 -> npcl(FacialExpression.FRIENDLY, "Yeah! I'm gonna be the bravest knight in the world! After you, of course.").also { stage++ } + 7 -> sendNPCDialogue(player!!, NPCs.JUSTIN_SERVIL_267, "Thank you again, ${player!!.username}. You have saved my family and given young Jeremy here a new hero.").also { stage++ } + 8 -> playerl(FacialExpression.FRIENDLY, "I'm glad I could help. Have a good journey home and farewell.").also { stage++ } + 9 -> npcl(FacialExpression.HAPPY, "See ya!").also { stage = END_DIALOGUE } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/JoeDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/JoeDialogue.kt new file mode 100644 index 0000000..a220a48 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/JoeDialogue.kt @@ -0,0 +1,46 @@ +package content.region.kandarin.ardougne.quest.arena.dialogue + +import core.api.allInEquipment +import core.api.sendNPCDialogue +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class JoeDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + if (allInEquipment(player, Items.KHAZARD_HELMET_74, Items.KHAZARD_ARMOUR_75)) { + playerl(FacialExpression.FRIENDLY, "Do you know of a Justin or Jeremy in this arena?").also { stage = 0 } + } else { + playerl(FacialExpression.FRIENDLY, "Do you know of a Justin or Jeremy in this arena?").also { stage = 3 } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> sendNPCDialogue(player, NPCs.JOE_261, "If we did, why would we tell you guard?", FacialExpression.ANNOYED).also { stage++ } + 1 -> sendNPCDialogue(player, NPCs.KELVIN_260, "Until our last breath, our every action will be against Khazard. Never will we help you.", FacialExpression.ANNOYED).also { stage++ } + 2 -> sendNPCDialogue(player, NPCs.JOE_261, "I spit on Khazard's grave, and all who do his bidding.", FacialExpression.ANNOYED).also { stage = END_DIALOGUE } + 3 -> sendNPCDialogue(player, NPCs.KELVIN_260, "I have heard of those of whom you speak. But I fear it may be too late.", FacialExpression.HALF_GUILTY).also { stage++ } + 4 -> sendNPCDialogue(player, NPCs.JOE_261, "It is said that Khazard has a personal vendetta against those two, their time is therefore short.", FacialExpression.FRIENDLY).also { stage++ } + 5 -> sendNPCDialogue(player, NPCs.KELVIN_260, "You're a brave " + (if (player!!.isMale) "Sir" else "Madam") + ". If the guards get you, you'll be in here next.", FacialExpression.HALF_WORRIED).also { stage = END_DIALOGUE } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return JoeDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.KELVIN_260, NPCs.JOE_261) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/JustinServilDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/JustinServilDialogue.kt new file mode 100644 index 0000000..3244d30 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/JustinServilDialogue.kt @@ -0,0 +1,72 @@ +package content.region.kandarin.ardougne.quest.arena.dialogue + +import content.data.Quests +import core.api.face +import core.api.findNPC +import core.api.getQuestStage +import core.api.sendNPCDialogue +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +class JustinServilDialogue : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + npc = NPC(NPCs.JUSTIN_SERVIL_267) + when (getQuestStage(player!!, Quests.FIGHT_ARENA)) { + + in 1..68 -> when (stage) { + 0 -> playerl(FacialExpression.FRIENDLY, "Hello.").also { stage++ } + 1 -> { + face(findNPC(NPCs.JUSTIN_SERVIL_267)!!, player!!, 1) + npcl(FacialExpression.FRIENDLY, "You've incurred the anger of Khazard himself. He won't let any of us go easily.").also { stage = END_DIALOGUE } + } + + } + + in 69..71 -> when (stage) { + 0 -> { + face(findNPC(NPCs.JUSTIN_SERVIL_267)!!, player!!, 1) + playerl(FacialExpression.FRIENDLY, "Lady Servil sent me to rescue you and your son. Come on, we have to get out of here.").also { stage++ } + } + 1 -> npcl(FacialExpression.FRIENDLY, "I'm too old to fight. I'm afraid you'll have to kill that ogre by yourself.").also { stage = END_DIALOGUE } + } + + 72 -> when (stage) { + 0 -> { + face(findNPC(NPCs.JUSTIN_SERVIL_267)!!, player!!, 1) + playerl(FacialExpression.FRIENDLY, "Are you alright").also { stage++ } + } + 1 -> npcl(FacialExpression.FRIENDLY, "You saved my life and my son's. I am eternally in your debt brave traveller.").also { stage = END_DIALOGUE } + } + + in 73..89 -> when (stage) { + 0 -> { + face(findNPC(NPCs.JUSTIN_SERVIL_267)!!, player!!, 1) + playerl(FacialExpression.FRIENDLY, "Don't worry, I'll get us out of here.").also { stage++ } + } + 1 -> npcl(FacialExpression.NEUTRAL, "You've incurred the anger of Khazard yourself now. He won't let any of us go easily.").also { stage = END_DIALOGUE } + } + + in 90..99 -> when (stage) { + 0 -> { + face(findNPC(NPCs.JUSTIN_SERVIL_267)!!, player!!, 1) + npcl(FacialExpression.NEUTRAL, " You saved my life and my son's, I am eternally in your debt brave taveller.").also { stage = END_DIALOGUE } + } + } + + 100 -> when (stage) { + 0 -> { + face(findNPC(NPCs.JUSTIN_SERVIL_267)!!, player!!, 1) + npcl(FacialExpression.FRIENDLY, "Thank you again, ${player!!.username}. You have saved me and my boy from an awful fate.").also { stage++ } + } + 1 -> sendNPCDialogue(player!!, NPCs.JEREMY_SERVIL_266, "Yeah, you were ace. I wanna be jus' like you.").also { stage++ } + 2 -> npcl(FacialExpression.FRIENDLY, "If you do well in your studies and work hard, maybe you will be.").also { stage++ } + 3 -> sendNPCDialogue(player!!, NPCs.JEREMY_SERVIL_266, "Daaad, studying's so boooooooring! I wanna hit things.").also { stage++ } + 4 -> npcl(FacialExpression.FRIENDLY, "I'm sure ${player!!.username} studied hard when he was younger.").also { stage++ } + 5 -> playerl(FacialExpression.FRIENDLY, "That's right, son, you should do as your father says. Anyway, I should go now, have a safe journey home. And you, young lad, work hard and stay out of trouble - at least until you're a little older.").also { stage = END_DIALOGUE } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/KhazardBarmanDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/KhazardBarmanDialogue.kt new file mode 100644 index 0000000..48ff869 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/KhazardBarmanDialogue.kt @@ -0,0 +1,71 @@ +package content.region.kandarin.ardougne.quest.arena.dialogue + +import content.data.Quests +import core.api.addItem +import core.api.getQuestStage +import core.api.removeItem +import core.api.setQuestStage +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.item.Item +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.Items.COINS_995 +import org.rs09.consts.NPCs + +class KhazardBarmanDialogue : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + npc = NPC(NPCs.KHAZARD_BARMAN_259) + when (getQuestStage(player!!, Quests.FIGHT_ARENA)) { + in 0..49 -> { + when (stage) { + 0 -> playerl(FacialExpression.HAPPY, "Hello. I'll have a beer please.").also { stage = 1 } + 1 -> npcl(FacialExpression.FRIENDLY, "There you go, that's two gold coins.").also { stage = 2 } + 2 -> if (removeItem(player!!, Item(COINS_995, 2))) { + end() + addItem(player!!, Items.BEER_1917, 1) + stage = END_DIALOGUE + } else { + end() + playerl(FacialExpression.STRUGGLE, "Oh, I don't have enough money with me.").also { stage = END_DIALOGUE } + } + } + } + + in 50..100 -> { + when (stage) { + 0 -> playerl(FacialExpression.HAPPY, "Hello.").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "Hi, what can I get you? We have a range of quality brews.").also { stage++ } + 2 -> options("I'll have a beer please.", "I'd like a Khali brew please.", "Got any news?").also { stage++ } + 3 -> when (buttonID) { + 1 -> playerl(FacialExpression.NEUTRAL, "I'll have a beer please.").also { stage = 4 } + 2 -> playerl(FacialExpression.NEUTRAL, "I'd like a Khali brew please.").also { stage = 7 } + 3 -> playerl(FacialExpression.ASKING, "Got any news?").also { stage = 5 } + } + 4 -> npcl(FacialExpression.FRIENDLY, "There you go, that's two gold coins.").also { stage = 8 } + 5 -> npcl(FacialExpression.NEUTRAL, "If you want to see the action around here you should visit the famous Khazard fight arena. I've seen some grand battles in my time. Ogres, goblins, even dragons have fought there.").also { stage++ } + 6 -> npcl(FacialExpression.WORRIED, "Although you have to feel sorry for some of the slaves sent in there.").also { stage = END_DIALOGUE } + 7 -> npcl(FacialExpression.FRIENDLY, "There you go, that's five gold coins. I suggest lying down before you drink it. That way you have less distance to collapse.").also { stage = 9 } + 8 -> if (removeItem(player!!, Item(COINS_995, 2))){ + end() + addItem(player!!, Items.BEER_1917, 1) + stage = END_DIALOGUE + } else { + end() + playerl(FacialExpression.STRUGGLE, "Oh, I don't have enough money with me.").also { stage = END_DIALOGUE } + } + 9 -> if (removeItem(player!!, Item(COINS_995, 5))){ + end() + addItem(player!!, Items.KHALI_BREW_77, 1) + setQuestStage(player!!, Quests.FIGHT_ARENA, 60) + stage = END_DIALOGUE + } else { + end() + playerl(FacialExpression.STRUGGLE, "Oh, I don't have enough money with me.").also { stage = END_DIALOGUE } + } + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/LadyServilDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/LadyServilDialogue.kt new file mode 100644 index 0000000..fc30c1c --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/LadyServilDialogue.kt @@ -0,0 +1,100 @@ +package content.region.kandarin.ardougne.quest.arena.dialogue + +import core.api.getQuestStage +import core.api.setQuestStage +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs +import content.data.Quests +@Initializable +class LadyServilDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + playerl(FacialExpression.FRIENDLY, "Hi there, looks like you're in some trouble.") + if (player.questRepository.getStage(Quests.FIGHT_ARENA) == 10) { + playerl(FacialExpression.FRIENDLY, "Hello Lady Servil.") + } else if (player.questRepository.getStage(Quests.FIGHT_ARENA) == 30) { + playerl(FacialExpression.FRIENDLY, "Lady Servil, I have managed to infiltrate General Khazard's arena.") + } else if (player.questRepository.getStage(Quests.FIGHT_ARENA) == 70) { + playerl(FacialExpression.FRIENDLY, "Lady Servil. I freed your son, however he has returned to the arena to help your husband.").also { stage++ } + } else { + playerl(FacialExpression.FRIENDLY, "Hello Lady Servil.") + } + return true + } + + override fun handle(componentID: Int, buttonID: Int): Boolean { + when (getQuestStage(player!!, Quests.FIGHT_ARENA)) { + + 0 -> when (stage) { + 0 -> npcl(FacialExpression.SAD, "Oh I wish this broken cart was my only problem. *sob* I've got to find my family.. **sob**").also { stage++ } + 1 -> options("I hope you can. good luck.", "Can I help you?").also { stage++ } + 2 -> when (buttonID) { + 1 -> playerl(FacialExpression.NEUTRAL, "I hope you can, good luck.").also { stage = END_DIALOGUE } + 2 -> playerl(FacialExpression.FRIENDLY, "Can I help you?").also { stage++ } + } + 3 -> npcl(FacialExpression.SAD, "Would you? Please?").also { stage++ } + 4 -> npcl(FacialExpression.SAD, "I'm Lady Servil, and my husband is Sir Servil. We were travelling north together with our son Jeremy when we were ambushed by General Khazard's men.").also { stage++ } + 5 -> playerl(FacialExpression.HALF_ASKING, "General Khazard?").also { stage++ } + 6 -> npcl(FacialExpression.SAD, "He's been after me even since I declined his hand in marriage.").also { stage++ } + 7 -> npcl(FacialExpression.SAD, "Now he's kidnapped my husband and son to fight in his battle arena to the south of here. I hate to think what he'll do to them. He's a sick and twisted man.").also { stage++ } + 8 -> playerl(FacialExpression.FRIENDLY, "I'll try my best to return your family.").also { stage++ } + 9 -> { + end() + setQuestStage(player!!, Quests.FIGHT_ARENA, 10) + npcl(FacialExpression.SAD, "Please do. My family is wealthy and can reward you handsomely. I'll be waiting here for you.").also { stage = END_DIALOGUE } + } + } + + + in 1..10 -> when (stage) { + 0 -> npcl(FacialExpression.SAD, "Brave traveller, please... bring back my family.").also { stage = END_DIALOGUE } + } + + in 11..20 -> when (stage) { + 0 -> npcl(FacialExpression.WORRIED, "Have you had any luck with freeing my family?").also { stage++ } + 1 -> playerl(FacialExpression.HAPPY, "I've managed to get a guard's uniform, hopefully I can infiltrate the arena.").also { stage++ } + 2 -> npcl(FacialExpression.SAD, "Please hurry.").also { stage = END_DIALOGUE } + } + + + in 21..30 -> when (stage) { + 0 -> npcl(FacialExpression.ASKING, "And my family?").also { stage++ } + 1 -> playerl(FacialExpression.NEUTRAL, "I'm working on it.").also { stage++ } + 2 -> npcl(FacialExpression.SAD, "Please hurry.").also { stage = END_DIALOGUE } + } + + + in 31..98 -> when (stage) { + 0 -> npcl(FacialExpression.WORRIED, "Oh no, they won't stand a chance. Please go back and help.").also { stage = END_DIALOGUE } + } + + + 99 -> when (stage) { + 0 -> npcl(FacialExpression.AMAZED, "You're alive, I thought Khazard's men had taken you.").also { stage++ } + 1 -> npcl(FacialExpression.HAPPY, "My son and husband are safe and recovering at home. Without you they would certainly be dead. I am truly grateful for your service.").also { stage++ } + 2 -> npcl(FacialExpression.FRIENDLY, "All I can offer in return is material wealth. Please take these coins as a sign of my gratitude.").also { stage++ } + 3 -> { + end() + player!!.questRepository.getQuest(Quests.FIGHT_ARENA).finish(player) + } + } + + 100 -> when (stage) { + 0 -> npcl(FacialExpression.FRIENDLY, "Oh hello my dear. My husband and son are resting while I wait for the cart fixer.").also { stage++ } + 1 -> playerl(FacialExpression.FRIENDLY, "I hope he's not too long.").also { stage++ } + 2 -> npcl(FacialExpression.FRIENDLY, "Thanks again for everything.").also { stage = END_DIALOGUE } + } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.LADY_SERVIL_264) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/LocalDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/LocalDialogue.kt new file mode 100644 index 0000000..84382f9 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/dialogue/LocalDialogue.kt @@ -0,0 +1,53 @@ +package content.region.kandarin.ardougne.quest.arena.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs +import content.data.Quests + +@Initializable +class LocalDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + if (player.questRepository.getStage(Quests.FIGHT_ARENA) == 100) { + npcl(FacialExpression.FRIENDLY, "Hey, you're the guy from the arena! How'd you get out?").also { stage = END_DIALOGUE } + } else if (player.questRepository.getStage(Quests.FIGHT_ARENA) in 91..99) { + playerl(FacialExpression.FRIENDLY, "Hello.").also { stage = 9 } + } else if (player.questRepository.getStage(Quests.FIGHT_ARENA) >= 10) { + playerl(FacialExpression.FRIENDLY, "Hello.").also { stage = 0 } + } else { + playerl(FacialExpression.FRIENDLY, "Hello.").also { stage = 7 } + } + return true + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> npcl(FacialExpression.FRIENDLY, "I heard the Servil family are fighting soon. Should be very entertaining.").also { stage++ } + 1 -> npcl(FacialExpression.ASKING, "Hello stranger, are you new to these parts?").also { stage++ } + 2 -> playerl(FacialExpression.ASKING, "I suppose I am.").also { stage++ } + 3 -> npcl(FacialExpression.ASKING, "What's your business?").also { stage++ } + 4 -> playerl(FacialExpression.ASKING, "Just visiting friends in the cells.").also { stage++ } + 5 -> npcl(FacialExpression.LAUGH, "Visiting, that's funny.").also { stage++ } + 6 -> npcl(FacialExpression.FRIENDLY, "Only Khazard guards are allowed to see prisoners. Unless you know where to get some Khazard armour, you won't be visiting anyone.").also { stage = END_DIALOGUE } + 7 -> npcl(FacialExpression.ASKING, "Hello stranger, are you new to these parts? You look lost.").also { stage++ } + 8 -> npcl(FacialExpression.HALF_THINKING, "I suppose you're here for the fight arena? There are some rich folk fighting tomorrow. Should be entertaining.").also { stage = END_DIALOGUE } + 9 -> npcl(FacialExpression.FRIENDLY, "You're the guy who beat Bouncer! Amazing! That makes you a champion to many, but you'd better get out of here while you still can. General Khazard liked that brute and will be after you.").also { stage++ } + 10 -> playerl(FacialExpression.FRIENDLY, "He tried, but I killed him. You are safe now.").also { stage++ } + 11 -> npcl(FacialExpression.FRIENDLY, "Sadly, you can't kill what is already dead. He's probably still out there, somewhere.").also { stage = END_DIALOGUE } + + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return LocalDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.LOCAL_268) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/npc/BouncerNPC.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/npc/BouncerNPC.kt new file mode 100644 index 0000000..f79aefc --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/npc/BouncerNPC.kt @@ -0,0 +1,64 @@ +package content.region.kandarin.ardougne.quest.arena.npc + +import content.region.kandarin.ardougne.quest.arena.dialogue.GeneralKhazardDialogue +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.player.Player +import core.game.system.task.Pulse +import core.game.world.GameWorld +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.NPCs +import content.data.Quests + +@Initializable +class BouncerNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id, location) { + var clearTime = 0 + override fun construct(id: Int, location: Location, vararg objects: Any): AbstractNPC { + return BouncerNPC(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.BOUNCER_269) + } + + override fun handleTickActions() { + super.handleTickActions() + if (clearTime++ > 300) poofClear(this) + } + + companion object { + fun spawnBouncer(player: Player) { + val bouncer = BouncerNPC(NPCs.BOUNCER_269) + bouncer.location = location(2604, 3160, 0) + bouncer.isWalks = true + bouncer.isAggressive = true + bouncer.isActive = false + + if (bouncer.asNpc() != null && bouncer.isActive && getAttribute(player, "spawn-bouncer", false)) { + bouncer.properties.teleportLocation = bouncer.properties.spawnLocation + } + bouncer.isActive = true + GameWorld.Pulser.submit(object : Pulse(2, bouncer) { + override fun pulse(): Boolean { + bouncer.init() + bouncer.attack(player) + return true + } + }) + } + } + + override fun finalizeDeath(killer: Entity?) { + if (killer is Player) { + if (getQuestStage(killer, Quests.FIGHT_ARENA) >= 89) { + setQuestStage(killer, Quests.FIGHT_ARENA, 91) + } + removeAttribute(killer, "spawn-bouncer") + openDialogue(killer, GeneralKhazardDialogue()) + } + clear() + super.finalizeDeath(killer) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/npc/GeneralNPC.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/npc/GeneralNPC.kt new file mode 100644 index 0000000..700876e --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/npc/GeneralNPC.kt @@ -0,0 +1,41 @@ +package content.region.kandarin.ardougne.quest.arena.npc + +import content.region.kandarin.ardougne.quest.arena.FightArenaListeners.Companion.General +import content.region.kandarin.ardougne.quest.arena.dialogue.JeremyServilBDialogue +import core.api.openDialogue +import core.api.getQuestStage +import core.api.setQuestStage +import core.game.node.entity.Entity +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.NPCs +import content.data.Quests + +@Initializable +class GeneralNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id, location) { + override fun construct(id: Int, location: Location, vararg objects: Any): AbstractNPC { + return GeneralNPC(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.GENERAL_KHAZARD_258) + } + + override fun handleTickActions() { + super.handleTickActions() + General.asNpc().isRespawn = true + General.respawnTick = 10 + } + + override fun finalizeDeath(killer: Entity?) { + if (killer is Player) { + if (getQuestStage(killer, Quests.FIGHT_ARENA) == 97) { + setQuestStage(killer, Quests.FIGHT_ARENA, 98) + } + openDialogue(killer, JeremyServilBDialogue()) + } + super.finalizeDeath(killer) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/npc/OgreNPC.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/npc/OgreNPC.kt new file mode 100644 index 0000000..67e2ae7 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/npc/OgreNPC.kt @@ -0,0 +1,66 @@ +package content.region.kandarin.ardougne.quest.arena.npc + +import content.region.kandarin.ardougne.quest.arena.dialogue.GeneralKhazardDialogue +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.player.Player +import core.game.system.task.Pulse +import core.game.world.GameWorld +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.NPCs +import content.data.Quests + +@Initializable +class OgreNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id, location) { + var clearTime = 0 + override fun construct(id: Int, location: Location, vararg objects: Any): AbstractNPC { + return OgreNPC(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.KHAZARD_OGRE_270) + } + + override fun handleTickActions() { + super.handleTickActions() + if (clearTime++ > 300) poofClear(this) + } + + companion object { + fun spawnOgre(player: Player) { + val ogre = OgreNPC(NPCs.KHAZARD_OGRE_270) + ogre.location = location(2603, 3166, 0) + ogre.isWalks = true + ogre.isAggressive = true + ogre.isActive = false + + if (ogre.asNpc() != null && ogre.isActive && getAttribute(player, "spawn-ogre", false)) { + ogre.properties.teleportLocation = ogre.properties.spawnLocation + } + ogre.isActive = true + GameWorld.Pulser.submit(object : Pulse(2, ogre) { + override fun pulse(): Boolean { + ogre.init() + ogre.attack(player) + registerHintIcon(player, ogre) + return true + } + }) + } + } + + override fun finalizeDeath(killer: Entity?) { + if (killer is Player) { + if (getQuestStage(killer, Quests.FIGHT_ARENA) == 68 || getQuestStage(killer, Quests.FIGHT_ARENA) == 88) { + setQuestStage(killer, Quests.FIGHT_ARENA, 72) + } + clearHintIcon(killer) + removeAttribute(killer, "spawn-ogre") + openDialogue(killer, GeneralKhazardDialogue()) + } + clear() + super.finalizeDeath(killer) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/arena/npc/ScorpionNPC.kt b/Server/src/main/content/region/kandarin/ardougne/quest/arena/npc/ScorpionNPC.kt new file mode 100644 index 0000000..1644649 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/arena/npc/ScorpionNPC.kt @@ -0,0 +1,64 @@ +package content.region.kandarin.ardougne.quest.arena.npc + +import content.region.kandarin.ardougne.quest.arena.dialogue.GeneralKhazardDialogue +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.player.Player +import core.game.system.task.Pulse +import core.game.world.GameWorld +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.NPCs +import content.data.Quests + +@Initializable +class ScorpionNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id, location) { + var clearTime = 0 + override fun construct(id: Int, location: Location, vararg objects: Any): AbstractNPC { + return ScorpionNPC(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.KHAZARD_SCORPION_271) + } + + override fun handleTickActions() { + super.handleTickActions() + if (clearTime++ > 300) poofClear(this) + } + + companion object { + fun spawnScorpion(player: Player) { + val scorpion = ScorpionNPC(NPCs.KHAZARD_SCORPION_271) + scorpion.location = location(2604, 3159, 0) + scorpion.isWalks = true + scorpion.isAggressive = true + scorpion.isActive = false + + if (scorpion.asNpc() != null && scorpion.isActive && getAttribute(player, "spawn-scorpion", false)) { + scorpion.properties.teleportLocation = scorpion.properties.spawnLocation + } + scorpion.isActive = true + GameWorld.Pulser.submit(object : Pulse(2, scorpion) { + override fun pulse(): Boolean { + scorpion.init() + scorpion.attack(player) + return true + } + }) + } + } + + override fun finalizeDeath(killer: Entity?) { + if (killer is Player) { + if (getQuestStage(killer, Quests.FIGHT_ARENA) == 88) { + setQuestStage(killer, Quests.FIGHT_ARENA, 89) + } + removeAttribute(killer, "spawn-scorpion") + openDialogue(killer, GeneralKhazardDialogue()) + } + clear() + super.finalizeDeath(killer) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/biohazard/dialogue/KilronDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/biohazard/dialogue/KilronDialogue.kt new file mode 100644 index 0000000..83be1b4 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/biohazard/dialogue/KilronDialogue.kt @@ -0,0 +1,51 @@ +package content.region.kandarin.ardougne.quest.biohazard.dialogue + +import content.data.Quests +import core.api.getQuestStage +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class KilronDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + playerl(FacialExpression.FRIENDLY, "Hello there.") + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + if (getQuestStage(player, Quests.BIOHAZARD) > 0){ + when(stage){ + 0 -> playerl(FacialExpression.FRIENDLY, "Hello Kilron.").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "Hello traveller. Do you need to go back over?").also { stage++ } + 2 -> showTopics( + Topic("Not yet Kilron.", 4), + Topic("Yes I do.", 5) + ) + 4 -> npcl(FacialExpression.FRIENDLY, "Okay, just give me the word.").also { stage = END_DIALOGUE } + 5 -> npcl(FacialExpression.FRIENDLY, "Okay, quickly now!").also { stage = END_DIALOGUE } + } + + } + else { + when (stage) { + 0 -> npcl(FacialExpression.FRIENDLY, "Hello.").also { stage++ } + 1 -> playerl(FacialExpression.FRIENDLY, "How are you?").also { stage++ } + 2 -> npcl(FacialExpression.FRIENDLY, "Busy.").also { stage = END_DIALOGUE } + } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.KILRON_349) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/biohazard/dialogue/MournerBossDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/biohazard/dialogue/MournerBossDialogue.kt new file mode 100644 index 0000000..0bad783 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/biohazard/dialogue/MournerBossDialogue.kt @@ -0,0 +1,149 @@ +package content.region.kandarin.ardougne.quest.biohazard.dialogue + +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.interaction.QueueStrength +import core.game.node.entity.Entity +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + + +/** + * For some reason the level 13 mourner upstairs is called the boss + * And despite the fact that other NPCs say there's one sick person upstairs they're 2 up there. + * + * We should be using key 423 but that got incorrectly used for Lost Tribe + */ + +@Initializable +class MournerBossDialogue(player: Player? = null) : DialoguePlugin(player) { + + companion object{ + const val HOLD_BREATH = 10 + const val PRAY = 20 + const val FATAL = 30 + const val HAVE_KEY = 40 + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + if (inEquipment(player!!, Items.DOCTORS_GOWN_430)){ + playerl(FacialExpression.FRIENDLY, "Hello there.").also { stage = if (hasAnItem(player!!, Items.KEY_5010).exists()) HAVE_KEY else START_DIALOGUE + 1 } + return true + } + else { + sendDialogue("The mourner doesn't feel like talking.").also { stage = END_DIALOGUE } + return false + } + } + + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + START_DIALOGUE + 1 -> npcl(FacialExpression.ASKING, "A doctor? At last! I don't know what I've eaten but I feel like I'm on death's door.").also { stage++ } + START_DIALOGUE + 2 -> playerl(FacialExpression.NEUTRAL, "Hmm... interesting, sounds like food poisoning.").also { stage++ } + // Jagex didn't include a question mark here + START_DIALOGUE + 3 -> npcl(FacialExpression.ASKING, "Yes, I'd figured that out already. What can you give me to help.").also { stage++ } + START_DIALOGUE + 4 -> showTopics( + Topic("Just hold your breath and count to ten.", HOLD_BREATH), + Topic("The best I can do is pray for you.", PRAY), + Topic("There's nothing I can do, it's fatal.", FATAL) + ) + + + HOLD_BREATH -> npcl(FacialExpression.SUSPICIOUS, "What? How will that help? What kind of doctor are you?").also { stage++ } + HOLD_BREATH + 1 -> player(FacialExpression.HALF_GUILTY, "Erm... I'm new, I just started.").also { stage++ } + HOLD_BREATH + 2 -> npcl(FacialExpression.ANGRY, "You're no doctor!").also { + stage = END_DIALOGUE + fight(player) + } + + PRAY -> npcl(FacialExpression.ANGRY, "Pray for me? You're no doctor... You're an imposter!").also { + stage = END_DIALOGUE + fight(player) + } + + FATAL -> npcl(FacialExpression.PANICKED, "No, I'm too young to die! I've never even had a girlfriend.").also { stage++ } + FATAL + 1 -> playerl(FacialExpression.SAD, "That's life for you.").also { stage++ } + FATAL + 2 -> npcl(FacialExpression.ASKING, "Wait a minute, where's your equipment?").also { stage++ } + FATAL + 3 -> playerl(FacialExpression.HALF_GUILTY, "It's erm... at home.").also { stage++ } + FATAL + 4 -> npcl(FacialExpression.ANGRY, "You're no doctor!").also { + stage = END_DIALOGUE + fight(player) + } + + HAVE_KEY -> npcl(FacialExpression.NEUTRAL, "Sorry, I'd like to be left in peace.").also { stage = END_DIALOGUE } + + } + + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.MOURNER_370) + } + + private fun fight(player: Player){ + queueScript(player) { stage: Int -> + if (stage == 1){ + npc.attack(player) + return@queueScript stopExecuting(player) + } + return@queueScript delayScript(player, 1) + } + } +} + +/** + * Handles the key drop from the mourner boss + */ +@Initializable +class MournerBossNPC : AbstractNPC { + var target: Player? = null + private val supportRange: Int = 5 + + //Constructor spaghetti because Arios I guess + constructor() : super(NPCs.MOURNER_370, null, true) {} + private constructor(id: Int, location: Location) : super(id, location) {} + override fun construct(id: Int, location: Location, vararg objects: Any): AbstractNPC { + return MournerBossNPC(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.MOURNER_370) + } + + override fun finalizeDeath(killer: Entity?) { + val p = killer as Player + if (!hasAnItem(p, Items.KEY_5010).exists()){ + queueScript(p, 1, QueueStrength.NORMAL){ stage: Int -> + when(stage){ + 0 -> { + sendMessage(p, "You search the mourner...") + } + 2 ->{ + sendMessage(p, "and find a key.") + // If the player doesn't have space bad luck + // They can kill another mourner boss + // todo change this key and fix lost tribe key at the same time + // It should be 423 here and 5010 over there + // addItemOrDrop(p, Items.KEY_5010) + return@queueScript stopExecuting(p) + } + } + return@queueScript delayScript(p, 1) + } + } + super.finalizeDeath(killer) + } + +} diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/clocktower/BrotherKojoDialogueFile.kt b/Server/src/main/content/region/kandarin/ardougne/quest/clocktower/BrotherKojoDialogueFile.kt new file mode 100644 index 0000000..c06a155 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/clocktower/BrotherKojoDialogueFile.kt @@ -0,0 +1,109 @@ +package content.region.kandarin.ardougne.quest.clocktower + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE + +class BrotherKojoDialogueFile : DialogueFile() { + + override fun handle(componentID: Int, buttonID: Int) { + if (getAttribute(player!!, ClockTower.attributeAskKojoAboutRats, false) && !getAttribute(player!!, ClockTower.attributeRatsPoisoned, false)) { + when (stage) { + START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "I've found the white cog! But it's locked behind a gate. There's rats everywhere!").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "Rats again?! Kill them! Kill them all!").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "But how do I open the gate? Do you have a key?").also { stage++ } + 3 -> npcl(FacialExpression.FRIENDLY, "Get rid of the rats! I'm sure I left some rat poison down there!").also { stage++ } + 4 -> playerl(FacialExpression.FRIENDLY, "I guess I better go and deal with the rat problem...").also { + stage = END_DIALOGUE + } + } + return + } + when (getQuestStage(player!!, Quests.CLOCK_TOWER)) { + 0 -> { + when (stage) { + START_DIALOGUE -> player(FacialExpression.FRIENDLY, "Hello monk.").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "Hello adventurer. My name is Brother Kojo. Do you happen to know the time?").also { stage++ } + 2 -> player(FacialExpression.SAD, "No, sorry, I don't.").also { stage++ } + 3 -> npcl(FacialExpression.NEUTRAL, "Exactly! This clock tower has recently broken down, and without it nobody can tell the correct time. I must fix it before the town people become too angry!").also { stage++ } + 4 -> npcl(FacialExpression.ASKING, "I don't suppose you could assist me in the repairs? I'll pay you for your help.").also { stage++ } + 5 -> showTopics( + Topic(FacialExpression.FRIENDLY, "Ok old monk, what can I do?", 30), + Topic(FacialExpression.ASKING, "So... how much reward are we talking then?", 10), + Topic(FacialExpression.FRIENDLY, "Not now old monk.", 20), + ) + + 10 -> npcl(FacialExpression.STRUGGLE, "Well, I'm only a monk so I'm not exactly rich, but I assure you I will give you a fair reward for the time spent assisting me in repairing the clock.").also { stage = 4 } + + 20 -> npcl(FacialExpression.FRIENDLY, "OK then. Come back and let me know if you change your mind.").also { stage = END_DIALOGUE } + + 30 -> npc(FacialExpression.HAPPY, "Oh, thank you kind ${if (player!!.isMale) "sir" else "madam"}!", + "In the cellar below, you'll find four cogs.", + "They're too heavy for me, but you should be able to", + "carry them one at a time.").also { stage++ } + + 31 -> npcl(FacialExpression.THINKING, "I know one goes on each floor... but I can't exactly remember which goes where specifically. Oh well, I'm sure you can figure it out fairly easily.").also { stage++ } + 32 -> player(FacialExpression.FRIENDLY, "Well, I'll do my best.").also { stage++ } + 33 -> npcl(FacialExpression.HAPPY, "Thank you again! And remember to be careful, the cellar is full of strange beasts!").also { + stage = END_DIALOGUE + setQuestStage(player!!, Quests.CLOCK_TOWER, 1) + } + } + } + 1 -> { + when (stage) { + START_DIALOGUE -> npcl(FacialExpression.ASKING, "Oh hello, are you having trouble? The cogs are in four rooms below us. Place one cog on a pole on each of the four tower levels.").also { stage++ } + 1 -> showTopics( + Topic(FacialExpression.FRIENDLY, "Can I have a hint?", 2), + Topic(FacialExpression.ASKING, "I'll carry on looking.", END_DIALOGUE), + ) + 2 -> showTopics( + Topic(FacialExpression.FRIENDLY, "Have you any idea where I might find the red cog?", 3), + Topic(FacialExpression.FRIENDLY, "Have you any idea where I might find the blue cog?", 3), + Topic(FacialExpression.FRIENDLY, "Have you any idea where I might find the black cog?", 3), + Topic(FacialExpression.FRIENDLY, "Have you any idea where I might find the white cog?", 3), + ) + 3 -> npcl(FacialExpression.FRIENDLY, "If I knew, I wouldn't ask you to find it. It's in the basement somewhere.").also { stage = 1 } + } + } + 2 -> { + when (stage) { + START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "I've placed a cog!").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "That's great. Come see me when you've done the other three.").also { stage = END_DIALOGUE } + } + } + 3 -> { + when (stage) { + START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Two down!").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "Two to go.").also { stage = END_DIALOGUE } + } + } + 4 -> { + when (stage) { + START_DIALOGUE -> npcl(FacialExpression.FRIENDLY, "One left.").also { stage = END_DIALOGUE } + } + } + in 5 .. 10 -> { + when (stage) { + START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "I have replaced all the cogs!").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "Really..? Wait, listen! Well done, well done! Yes yes yes, you've done it! You ARE clever!").also { stage++ } + 2 -> npcl(FacialExpression.FRIENDLY, "The townsfolk will all be able to know the correct time now! Thank you so much for all of your help! And as promised, here is your reward!").also { stage++ } + 3 -> { + end() + finishQuest(player!!, Quests.CLOCK_TOWER) + } + } + } + 100 -> { + when (stage) { + START_DIALOGUE -> npcl(FacialExpression.FRIENDLY, "Oh hello there traveller. You've done a grand job with the clock. It's just like new.").also { stage = END_DIALOGUE } + } + } + } + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/clocktower/ClockTower.kt b/Server/src/main/content/region/kandarin/ardougne/quest/clocktower/ClockTower.kt new file mode 100644 index 0000000..2be89b1 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/clocktower/ClockTower.kt @@ -0,0 +1,74 @@ +package content.region.kandarin.ardougne.quest.clocktower + +import core.api.addItemOrDrop +import core.api.getAttribute +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.plugin.Initializable +import org.rs09.consts.Items +import content.data.Quests + +/** + * https://www.youtube.com/watch?v=Cl68Z0bsRq4 + */ +@Initializable +class ClockTower : Quest(Quests.CLOCK_TOWER,38, 37, 1, 10, 0, 1, 8) { + companion object { + const val attributeBlueCog = "/save:quest:clocktower-bluecogplaced" + const val attributeBlackCog = "/save:quest:clocktower-blackcogplaced" + const val attributeWhiteCog = "/save:quest:clocktower-whitecogplaced" + const val attributeRedCog = "/save:quest:clocktower-redcogplaced" + const val attributeBlackCogCooled = "/save:quest:clocktower-blackcogcooled" + const val attributeRatsPoisoned = "/save:quest:clocktower-poisonplaced" + const val attributeAskKojoAboutRats = "quest:clocktower-askkojoaboutrats" + } + + override fun drawJournal(player: Player?, stage: Int) { + super.drawJournal(player, stage) + + var line = 12 + var stage = getStage(player) + + when (stage) { + 0 -> { + line(player, "I can start this quest by speaking to !!Brother Kojo?? at the", line++) + line(player, "!!Clock Tower?? which is located !!South?? of !!Ardougne??", line++) + } + + in 1 .. 10 -> { + line(player, "I spoke to Brother Kojo at the Clock Tower South of", line++, true) + line(player, "Ardougne and agreed to help him repair the clock.", line++, true) + line(player,"To repair the clock I need to find the four coloured cogs", line++, false) + line(player,"and place them on the four correctly coloured spindles.", line++, false) + line(player, if (getAttribute(player!!, attributeBlueCog, false)) "I placed the !!Blue Cog?? on it's !!spindle??." else "I haven't placed the !!Blue Cog?? on it's !!spindle?? yet.", line++, getAttribute(player!!, attributeBlueCog, false)) + line(player, if (getAttribute(player!!, attributeBlackCog, false)) "I placed the !!Black Cog?? on it's !!spindle??." else "I haven't placed the !!Black Cog?? on it's !!spindle?? yet.", line++, getAttribute(player!!, attributeBlackCog, false)) + line(player, if (getAttribute(player!!, attributeWhiteCog, false)) "I placed the !!White Cog?? on it's !!spindle??." else "I haven't placed the !!White Cog?? on it's !!spindle?? yet.", line++, getAttribute(player!!, attributeWhiteCog, false)) + line(player, if (getAttribute(player!!, attributeRedCog, false)) "I placed the !!Red Cog?? on it's !!spindle??." else "I haven't placed the !!Red Cog?? on it's !!spindle?? yet.", line++, getAttribute(player!!, attributeRedCog, false)) + } + + 100 -> { + line(player, "I spoke to Brother Kojo at the Clock Tower South of", line++, true) + line(player, "I have placed all four cogs successfully on the spindles.", line++, true) + line(player,"Brother Kojo was grateful for all my help and rewarded me.", line++, true) + line++ + line(player,"QUEST COMPLETE!", line) + } + } + } + + override fun finish(player: Player) { + var ln = 10 + super.finish(player) + player.packetDispatch.sendString("You have completed the Clock Tower Quest!", 277, 4) + player.packetDispatch.sendItemZoomOnInterface(Items.COINS_995, 240, 277, 5) + + drawReward(player,"1 Quest Point", ln++) + drawReward(player,"500 coins", ln++) + + addItemOrDrop(player, Items.COINS_995, 500) + } + + override fun newInstance(`object`: Any?): Quest { + return this + } +} diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/clocktower/ClockTowerListeners.kt b/Server/src/main/content/region/kandarin/ardougne/quest/clocktower/ClockTowerListeners.kt new file mode 100644 index 0000000..a769bac --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/clocktower/ClockTowerListeners.kt @@ -0,0 +1,294 @@ +package content.region.kandarin.ardougne.quest.clocktower + +import content.data.Quests +import core.api.* +import core.game.global.action.DoorActionHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.item.GroundItem +import core.game.node.item.Item +import core.game.world.map.Direction +import core.game.world.map.Location +import core.game.world.map.path.Pathfinder +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +class ClockTowerListener : InteractionListener { + + companion object { + val DOWN_ANIMATION = Animation(2140) + val UP_ANIMATION = Animation(2139) + } + + override fun defineListeners() { + onUseWith(IntType.SCENERY, intArrayOf(Items.WHITE_COG_20, Items.BLACK_COG_21, Items.BLUE_COG_22, Items.RED_COG_23), Scenery.CLOCK_SPINDLE_25) { player, _, _ -> + sendMessage(player, "The cog doesn't seem to fit.") + return@onUseWith true + } + + onUseWith(IntType.SCENERY, intArrayOf(Items.WHITE_COG_20, Items.BLACK_COG_21, Items.BLUE_COG_22, Items.RED_COG_23), Scenery.CLOCK_SPINDLE_26) { player, _, _ -> + sendMessage(player, "The cog doesn't seem to fit.") + return@onUseWith true + } + + onUseWith(IntType.SCENERY, intArrayOf(Items.WHITE_COG_20, Items.BLACK_COG_21, Items.BLUE_COG_22, Items.RED_COG_23), Scenery.CLOCK_SPINDLE_27) { player, _, _ -> + sendMessage(player, "The cog doesn't seem to fit.") + return@onUseWith true + } + + onUseWith(IntType.SCENERY, intArrayOf(Items.WHITE_COG_20, Items.BLACK_COG_21, Items.BLUE_COG_22, Items.RED_COG_23), Scenery.CLOCK_SPINDLE_28) { player, _, _ -> + sendMessage(player, "The cog doesn't seem to fit.") + return@onUseWith true + } + + onUseWith(IntType.SCENERY, Items.WHITE_COG_20, Scenery.CLOCK_SPINDLE_31) { player, _, _ -> + if (!getAttribute(player, ClockTower.attributeWhiteCog, false)) { + if (removeItem(player, Items.WHITE_COG_20)) { + sendMessage(player, "The cog fits perfectly.") + setAttribute(player, ClockTower.attributeWhiteCog, true) + if (!isQuestComplete(player, Quests.CLOCK_TOWER)) { + setQuestStage( + player, + Quests.CLOCK_TOWER, + getQuestStage(player, Quests.CLOCK_TOWER) + 1 + ) + } + } + } else { + sendMessage(player, "The cog has already been placed.") + } + return@onUseWith true + } + + onUseWith(IntType.SCENERY, Items.BLACK_COG_21, Scenery.CLOCK_SPINDLE_30) { player, _, _ -> + if (!getAttribute(player, ClockTower.attributeBlackCog, false)) { + if (removeItem(player, Items.BLACK_COG_21)) { + sendMessage(player, "The cog fits perfectly.") + setAttribute(player, ClockTower.attributeBlackCog, true) + if (!isQuestComplete(player, Quests.CLOCK_TOWER)) { + setQuestStage( + player, + Quests.CLOCK_TOWER, + getQuestStage(player, Quests.CLOCK_TOWER) + 1 + ) + } + } + } else { + sendMessage(player, "The cog has already been placed.") + } + return@onUseWith true + } + + onUseWith(IntType.SCENERY, Items.BLUE_COG_22, Scenery.CLOCK_SPINDLE_32) { player, _, _ -> + if (!getAttribute(player, ClockTower.attributeBlueCog, false)) { + if (removeItem(player, Items.BLUE_COG_22)) { + sendMessage(player, "The cog fits perfectly.") + setAttribute(player, ClockTower.attributeBlueCog, true) + if (!isQuestComplete(player, Quests.CLOCK_TOWER)) { + setQuestStage( + player, + Quests.CLOCK_TOWER, + getQuestStage(player, Quests.CLOCK_TOWER) + 1 + ) + } + } + } else { + sendMessage(player, "The cog has already been placed.") + } + return@onUseWith true + } + + onUseWith(IntType.SCENERY, Items.RED_COG_23, Scenery.CLOCK_SPINDLE_29) { player, _, _ -> + if (!getAttribute(player, ClockTower.attributeRedCog, false)) { + if (removeItem(player, Items.RED_COG_23)) { + sendMessage(player, "The cog fits perfectly.") + setAttribute(player, ClockTower.attributeRedCog, true) + if (!isQuestComplete(player, Quests.CLOCK_TOWER)) { + setQuestStage( + player, + Quests.CLOCK_TOWER, + getQuestStage(player, Quests.CLOCK_TOWER) + 1 + ) + } + } + } else { + sendMessage(player, "The cog has already been placed.") + } + return@onUseWith true + } + + // The lever to the rats + val levers = intArrayOf(Scenery.LEVER_33, Scenery.LEVER_34) + on(levers, IntType.SCENERY, "pull") { player, node -> + val leverScenery = node.asScenery() + // This one opens the first and only gate + if (leverScenery.location.equals(2591, 9661, 0)) { + if (leverScenery.id == Scenery.LEVER_33) { + val metalGate = getScenery(2595, 9657, 0)!! + val location = metalGate.location.transform(1, 0, 0) + face(player, Location.create(2591, 9660, 0)) + animate(player, UP_ANIMATION) + replaceScenery(metalGate, Scenery.GATE_37, -1, Direction.WEST, location) + replaceScenery(leverScenery, Scenery.LEVER_34, -1) + } else if (leverScenery.id == Scenery.LEVER_34) { + val metalGateOpen = getScenery(2596, 9657, 0)!! + val location = metalGateOpen.location.transform(-1, 0, 0) + face(player, Location.create(2591, 9660, 0)) + animate(player, DOWN_ANIMATION) + replaceScenery(metalGateOpen, Scenery.GATE_37, -1, Direction.SOUTH, location) + replaceScenery(leverScenery, Scenery.LEVER_33, -1) + } + } + if (leverScenery.location.equals(2593, 9661, 0)) { + // This one doesn't do anything https://www.youtube.com/watch?v=2FXiYftAX9A + // The second gate is fixed and is not a Scenery + if (leverScenery.id == Scenery.LEVER_34) { + face(player, Location.create(2593, 9660, 0)) + animate(player, DOWN_ANIMATION) + replaceScenery(leverScenery, Scenery.LEVER_33, -1) + } else if (leverScenery.id == Scenery.LEVER_33) { + face(player, Location.create(2593, 9660, 0)) + animate(player, UP_ANIMATION) + replaceScenery(leverScenery, Scenery.LEVER_34, -1) + } + } + return@on true + } + + // The gate to the rats + on(Scenery.GATE_37, IntType.SCENERY, "open") { player, _ -> + sendMessage(player, "The door doesn't seem to open from here...") + return@on true + } + + // Poison the rats + onUseWith(IntType.SCENERY, Items.RAT_POISON_24, Scenery.FOOD_TROUGH_40) { player, _, _ -> + if (getAttribute(player, ClockTower.attributeRatsPoisoned, false)) { + sendDialogue(player, "The gate has already been damaged, you see no reason to cause more suffering.") + return@onUseWith true + } + if (removeItem(player, Items.RAT_POISON_24)) { + val loc = location(2579, 9656, 0) // Location of the gate + sendMessage(player, "The rats swarm towards the poisoned food...") + sendMessage(player, "... and devour it hungrily.") + sendMessage(player, "You see them smashing against the gates in a panic.") + sendMessage(player, "They seem to be dying.") + setAttribute(player, ClockTower.attributeRatsPoisoned, true) + runTask(player, 1) { + val rats = findLocalNPCs(player, intArrayOf(NPCs.DUNGEON_RAT_224)) + rats.forEach { rat -> + if (rat.location.withinDistance(loc, 20)) { + var xDeath = 0 + var yDeath = -1 + for (rat in rats) { + + Pathfinder.find(rat.location, location(loc.x + xDeath, loc.y + yDeath, loc.z), true, Pathfinder.SMART).walk(rat) + xDeath++ + if (xDeath == 4) { + xDeath = 0 + yDeath++ + } + } + runTask(rat, 15) { + rat.startDeath(null) + } + } + } + } + } + return@onUseWith true + } + + // Gate to White Cog (after rats die) + on(Scenery.GATE_39, IntType.SCENERY, "go-through") { player, node -> + if (getAttribute(player, ClockTower.attributeRatsPoisoned, false)) { + sendDialogueLines(player, "The death throws of the rats seem to have shaken the door loose of", "its hinges. You pick it up and go through.") + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else { + sendPlayerDialogue(player, "It won't open. Maybe the monk knows how to open this door?") + setAttribute(player, ClockTower.attributeAskKojoAboutRats, true) + } + return@on true + } + + // Wall to Blue Cog + on(Scenery.WALL_1586, IntType.SCENERY, "push") { player, node -> + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + return@on true + } + + on(Items.WHITE_COG_20, IntType.GROUNDITEM, "take") { player, groundItem -> + if (inInventory(player, Items.WHITE_COG_20) || inInventory(player, Items.BLACK_COG_21) || inInventory(player, Items.BLUE_COG_22) || inInventory(player, Items.RED_COG_23)) { + sendDialogue(player, "The cogs are too heavy to carry more than one at a time.") + } else if (hasSpaceFor(player, Item(Items.WHITE_COG_20))) { + addItem(player, Items.WHITE_COG_20) + removeGroundItem(groundItem as GroundItem) + } + return@on true + } + + onUseWith(IntType.GROUNDITEM, Items.BUCKET_OF_WATER_1929, Items.BLACK_COG_21) { player, _, _ -> + if (removeItem(player, Items.BUCKET_OF_WATER_1929)) { + addItem(player, Items.BUCKET_1925) + sendDialogue(player, "You pour water over the cog. It quickly cools down enough to take.") + setAttribute(player, ClockTower.attributeBlackCogCooled, true) + } + return@onUseWith true + } + + on(Items.BLACK_COG_21, IntType.GROUNDITEM, "take") { player, groundItem -> + if (inInventory(player, Items.WHITE_COG_20) || inInventory(player, Items.BLACK_COG_21) || inInventory(player, Items.BLUE_COG_22) || inInventory(player, Items.RED_COG_23)) { + sendDialogue(player, "The cogs are too heavy to carry more than one at a time.") + return@on true + } + if (hasSpaceFor(player, Item(Items.BLACK_COG_21)) && getAttribute(player, ClockTower.attributeBlackCogCooled, false)) { + addItem(player, Items.BLACK_COG_21) + removeGroundItem(groundItem as GroundItem) + return@on true + } + if (!inInventory(player, Items.BUCKET_OF_WATER_1929, 1) && !inEquipment(player, Items.ICE_GLOVES_1580)) { + sendDialogue(player, "The cog is red hot from the flames. You cannot pick it up.") + return@on true + } + if (hasSpaceFor(player, Item(Items.BLACK_COG_21)) && (inInventory(player, Items.BUCKET_OF_WATER_1929, 1) || inEquipment(player, Items.ICE_GLOVES_1580)) && !getAttribute(player, ClockTower.attributeBlackCogCooled, false)) { + // Picking up the Black Cog requires dousing it in water or using ice gloves + if (!inEquipment(player, Items.ICE_GLOVES_1580) && removeItem(player, Items.BUCKET_OF_WATER_1929)) { + sendDialogue(player, "You pour water over the cog. It quickly cools down enough to take.") + addItem(player, Items.BUCKET_1925) + addItem(player, Items.BLACK_COG_21) + setAttribute(player, ClockTower.attributeBlackCogCooled, true) + removeGroundItem(groundItem as GroundItem) + } else if (inEquipment(player, Items.ICE_GLOVES_1580) && !inInventory(player, Items.BUCKET_OF_WATER_1929)) { + sendDialogue(player, "You grab the cog with your ice gloves. It quickly cools down enough to take.") + setAttribute(player, ClockTower.attributeBlackCogCooled, true) + removeGroundItem(groundItem as GroundItem) + addItem(player, Items.BLACK_COG_21) + } + } + return@on true + } + + on(Items.BLUE_COG_22, IntType.GROUNDITEM, "take") { player, groundItem -> + if (inInventory(player, Items.WHITE_COG_20) || inInventory(player, Items.BLACK_COG_21) || inInventory(player, Items.BLUE_COG_22) || inInventory(player, Items.RED_COG_23)) { + sendDialogue(player, "The cogs are too heavy to carry more than one at a time.") + } else if (hasSpaceFor(player, Item(Items.BLUE_COG_22))) { + addItem(player, Items.BLUE_COG_22) + removeGroundItem(groundItem as GroundItem) + } + return@on true + } + + on(Items.RED_COG_23, IntType.GROUNDITEM, "take") { player, groundItem -> + if (inInventory(player, Items.WHITE_COG_20) || inInventory(player, Items.BLACK_COG_21) || inInventory(player, Items.BLUE_COG_22) || inInventory(player, Items.RED_COG_23)) { + sendDialogue(player, "The cogs are too heavy to carry more than one at a time.") + } else if (hasSpaceFor(player, Item(Items.RED_COG_23))) { + addItem(player, Items.RED_COG_23) + removeGroundItem(groundItem as GroundItem) + } + return@on true + } + + } +} diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/monksfriend/BrotherCedricNPC.kt b/Server/src/main/content/region/kandarin/ardougne/quest/monksfriend/BrotherCedricNPC.kt new file mode 100644 index 0000000..64d4a7f --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/monksfriend/BrotherCedricNPC.kt @@ -0,0 +1,122 @@ +package content.region.kandarin.ardougne.quest.monksfriend + +import core.api.getQuestStage +import core.api.sendItemDialogue +import core.api.setQuestStage +import core.game.node.entity.npc.NPC +import core.game.node.item.Item +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import core.game.dialogue.DialogueFile +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.tools.END_DIALOGUE +import content.data.Quests + +/** + * Handles BrotherCedricDialogue Dialogue + * @author Kya + */ +class BrotherCedricDialogue : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + val questStage = getQuestStage(player!!, Quests.MONKS_FRIEND) + when { + questStage < 30 -> { + when(stage) { + 0 -> playerl(core.game.dialogue.FacialExpression.HAPPY, "Hello.").also{stage++} + 1 -> npcl(core.game.dialogue.FacialExpression.DRUNK, "Honey, money, woman and wine!").also{stage++} + 2 -> playerl(core.game.dialogue.FacialExpression.HALF_ASKING, "Are you ok?").also{stage++ } + 3 -> npcl(core.game.dialogue.FacialExpression.DRUNK, "Yesshh...hic up...beautiful!").also{stage++} + 4 -> playerl(core.game.dialogue.FacialExpression.NEUTRAL, "Take care old monk.").also{ stage++ } + 5 -> npcl(core.game.dialogue.FacialExpression.DRUNK, "La..di..da..hic..up!").also{stage = END_DIALOGUE } + } + } + questStage == 30 -> { + when(stage){ + 0 -> playerl(core.game.dialogue.FacialExpression.HAPPY, "Brother Cedric are you okay?").also{stage++} + 1 -> npcl(core.game.dialogue.FacialExpression.DRUNK, "Yeesshhh, I'm very, very drunk..hic..up..").also{stage++} + 2 -> playerl(core.game.dialogue.FacialExpression.NEUTRAL, "Brother Omad needs the wine for the party.").also{stage++} + 3 -> npcl(core.game.dialogue.FacialExpression.SAD, "Oh dear, oh dear, I knew I had to do something!").also{stage = END_DIALOGUE }.also{ setQuestStage(player!!, Quests.MONKS_FRIEND, 40) } + } + } + questStage == 40 -> { + when(stage){ + 0 -> playerl(core.game.dialogue.FacialExpression.HAPPY, "Are you okay?").also{stage++} + 1 -> npcl(core.game.dialogue.FacialExpression.DRUNK, "Hic up! Oh my head! I need a jug of water.").also{stage++} + 2 -> if (player!!.inventory.containItems(Items.JUG_OF_WATER_1937)){ + playerl(core.game.dialogue.FacialExpression.FRIENDLY, "Cedric! Here, drink! I have some water.").also{stage=10} + } else { + playerl(core.game.dialogue.FacialExpression.NEUTRAL, "I'll see if I can get some.").also{stage = 3} + } + 3 -> npcl(core.game.dialogue.FacialExpression.DRUNK, "Thanks! *hic*").also{stage = END_DIALOGUE } + 10 -> npcl(core.game.dialogue.FacialExpression.DRUNK, "Good stuff, my head's spinning!").also {stage++} + 11 -> { + sendItemDialogue(player!!, Items.JUG_OF_WATER_1937, "You hand the monk a jug of water.") + stage=0 + player!!.inventory.remove(Item(Items.JUG_OF_WATER_1937)) + setQuestStage(player!!, Quests.MONKS_FRIEND, 41) + } + } + } + questStage == 41 -> { + when(stage){ + 0 -> npcl(core.game.dialogue.FacialExpression.HAPPY, "Aah! That's better!").also{stage++} + 1 -> npcl(core.game.dialogue.FacialExpression.HAPPY, "Now I just need to fix this cart and we can go party.").also {stage++} + 2 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "Could you help?").also{stage++} + 3 -> options( + "No, I've helped enough monks today!", + "Yes, I'd be happy to!").also{stage++} + 4 -> when(buttonID){ + 1 -> playerl(core.game.dialogue.FacialExpression.ANGRY, "No, I've helped enough monks today!").also{stage++} + 2 -> playerl(core.game.dialogue.FacialExpression.FRIENDLY, "Yes, I'd be happy to!").also{stage=10} + } + 5 -> npcl(core.game.dialogue.FacialExpression.HAPPY, "In that case I'd better drink more wine! It helps me think.").also {stage= END_DIALOGUE } + 10 -> npcl(core.game.dialogue.FacialExpression.HAPPY, "Excellent, I just need some wood.").also{stage++} + 11 -> playerl(core.game.dialogue.FacialExpression.NEUTRAL, "Ok, I'll see what I can find.").also{stage = END_DIALOGUE }.also{setQuestStage(player!!, Quests.MONKS_FRIEND, 42)} + } + } + questStage == 42 -> { + when(stage){ + 0 -> npcl(core.game.dialogue.FacialExpression.HALF_ASKING, "Did you manage to get some wood?").also{stage++} + 1 -> if (player!!.inventory.containItems(Items.LOGS_1511)){ + sendItemDialogue(player!!, Items.LOGS_1511, "You hand Cedric some logs.") + stage=2 + } else { + playerl(core.game.dialogue.FacialExpression.SAD, "Not yet, I'm afraid.").also{stage = END_DIALOGUE } + } + 2 -> playerl(core.game.dialogue.FacialExpression.HAPPY, "Here you go!").also{stage++} + 3 -> npcl(core.game.dialogue.FacialExpression.HAPPY, "Well done! Now I'll fix this cart. You head back to Brother Omad and tell him I'll be there soon.").also{stage++} + 4 -> playerl(core.game.dialogue.FacialExpression.HAPPY, "Ok! I'll see you later!").also{ + stage= END_DIALOGUE + player!!.inventory.remove(Item(Items.LOGS_1511)) + setQuestStage(player!!, Quests.MONKS_FRIEND, 50) + } + } + } + questStage == 50 -> { + when(stage){ + 0 -> playerl(core.game.dialogue.FacialExpression.HAPPY, "Hello Cedric.").also{stage++} + 1 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "Hi, I'm almost done here. Could you tell Omad that I'll be back soon?").also{stage = END_DIALOGUE } + } + } + questStage == 100 -> { + when(stage){ + 0 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "Brother Omad sends you his thanks! He won't be in a fit state to thank you in person.").also{stage = END_DIALOGUE } + } + } + } + } +} + +/** + * Handles BrotherCedricListener to launch the dialogue + * @author Kya + */ +class BrotherCedricListener : InteractionListener { + override fun defineListeners() { + on(NPCs.BROTHER_CEDRIC_280, IntType.NPC, "talk-to"){ player, _ -> + player.dialogueInterpreter.open(BrotherCedricDialogue(), NPC(NPCs.BROTHER_CEDRIC_280)) + return@on true + } + } +} diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/monksfriend/BrotherOmadNPC.kt b/Server/src/main/content/region/kandarin/ardougne/quest/monksfriend/BrotherOmadNPC.kt new file mode 100644 index 0000000..bea3883 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/monksfriend/BrotherOmadNPC.kt @@ -0,0 +1,221 @@ +package content.region.kandarin.ardougne.quest.monksfriend + +import core.api.* +import core.game.node.entity.npc.NPC +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.map.RegionManager +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import core.game.dialogue.DialogueFile +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.game.world.GameWorld.Pulser +import core.tools.END_DIALOGUE +import content.data.Quests + + +/** +* Handles BrotherOmadDialogue Dialogue +* @author Kya +*/ +class BrotherOmadDialogue : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + val questStage = getQuestStage(player!!, Quests.MONKS_FRIEND) + when (questStage) { + 0 -> { + when(stage) { + 0 -> playerl(core.game.dialogue.FacialExpression.HAPPY, "Hello there. What's wrong?").also { stage++ } + 1 -> npcl(core.game.dialogue.FacialExpression.SAD, "*yawn*...oh, hello...*yawn* I'm sorry! I'm just so tired! I haven't slept in a week!").also { stage++ } + 2 -> options( + "Why can't you sleep, what's wrong?", + "Sorry! I'm too busy to hear your problems!").also { stage++ } + 3 -> when (buttonID) { + 1 -> playerl(core.game.dialogue.FacialExpression.HALF_ASKING, "Why can't you sleep, what's wrong?").also { stage++ } + 2 -> playerl(core.game.dialogue.FacialExpression.FRIENDLY, "Sorry! I'm too busy to hear your problems!").also { stage = END_DIALOGUE } + } + 4 -> npcl(core.game.dialogue.FacialExpression.SAD, "It's brother Androe's son! With his constant: Waaaaaah! Waaaaaaaaah! Androe said it's natural, but it's so annoying!").also { stage++ } + + 5 -> playerl(core.game.dialogue.FacialExpression.NEUTRAL, "I suppose that's what kids do.").also { stage++ } + 6 -> npcl(core.game.dialogue.FacialExpression.SAD, "He was fine, up until last week! Thieves broke in! They stole his favourite sleeping blanket!").also { stage++ } + 7 -> npcl(core.game.dialogue.FacialExpression.SAD, "Now he won't rest until it's returned... ...and that, means neither can I!").also { stage++ } + 8 -> options( + "Can I help at all?", + "I'm sorry to hear that! I hope you find his blanket.").also { stage++ } + 9 -> when (buttonID) { + 1 -> playerl(core.game.dialogue.FacialExpression.HALF_ASKING, "Can I help at all?").also { stage++ } + 2 -> playerl(core.game.dialogue.FacialExpression.FRIENDLY, "I'm sorry to hear that! I hope you find his blanket.").also { stage = END_DIALOGUE } + } + 10 -> npcl(core.game.dialogue.FacialExpression.HALF_WORRIED, "Please do. We won't be able to help you as we are peaceful men but we would be grateful for your help!").also { stage++ } + 11 -> playerl(core.game.dialogue.FacialExpression.HALF_ASKING, "Where are they?").also { stage++ } + 12 -> npcl(core.game.dialogue.FacialExpression.SAD, "They hide in a secret cave in the forest. It's hidden under a ring of stones. Please, bring back the blanket!").also { stage = END_DIALOGUE }.also { player!!.questRepository.getQuest(Quests.MONKS_FRIEND).start(player) }.also { player!!.questRepository.syncronizeTab(player) } + } + } + 10 -> { + when(stage) { + 0 -> playerl(core.game.dialogue.FacialExpression.HAPPY, "Hello.").also{stage = 20 } + 20 -> npcl(core.game.dialogue.FacialExpression.SAD, "*yawn*...oh, hello again...*yawn*").also{stage++ } + 21 -> npcl(core.game.dialogue.FacialExpression.SAD, "Please tell me you have the blanket.").also{stage++} + 22 -> if(player!!.inventory.containItems(Items.CHILDS_BLANKET_90)){ + playerl(core.game.dialogue.FacialExpression.HAPPY, "Yes! I've recovered it from the clutches of the evil thieves!").also{stage = 30} + } else { + playerl(core.game.dialogue.FacialExpression.SAD, "I'm afraid not.").also{stage++} + } + 23 -> npcl(core.game.dialogue.FacialExpression.SAD, "I need some sleep!").also{stage = END_DIALOGUE } + 30 -> { + sendItemDialogue(player!!, Items.CHILDS_BLANKET_90, "You hand the monk the childs blanket.") + stage=31 + } + 31 -> npcl(core.game.dialogue.FacialExpression.HAPPY, "Really, that's excellent, well done! Maybe now I will be able to get some rest.").also{stage++} + 32 -> npcl(core.game.dialogue.FacialExpression.SAD, "*yawn*..I'm off to bed! Farewell brave traveller!").also{player!!.inventory.remove(Item(Items.CHILDS_BLANKET_90)) + setQuestStage(player!!, Quests.MONKS_FRIEND, 20); stage = END_DIALOGUE + } + } + } + 20 -> { + when(stage) { + 0 -> playerl(core.game.dialogue.FacialExpression.HAPPY, "Hello, how are you?").also{stage = 30 } + 30 -> npcl(core.game.dialogue.FacialExpression.HAPPY, "Much better now I'm sleeping well! Now I can organise the party.").also{stage++} + 31 -> playerl(core.game.dialogue.FacialExpression.HAPPY, "Ooh! What party?").also{stage++} + 32 -> npcl(core.game.dialogue.FacialExpression.HAPPY, "The son of Brother Androe's birthday party. He's going to be one year old!").also {stage++} + 33 -> playerl(core.game.dialogue.FacialExpression.HAPPY, "That's sweet!").also{stage++ } + 34 -> npcl(core.game.dialogue.FacialExpression.HAPPY, "It's also a great excuse for a drink!").also{stage++} + 35 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "We just need Brother Cedric to return with the wine.").also{stage++} + 36 -> options( + "Who's Brother Cedric?", + "Enjoy it! I'll see you soon!").also { stage++} + 37 -> when(buttonID){ + 1 -> playerl(core.game.dialogue.FacialExpression.HALF_ASKING, "Who's Brother Cedric?").also{stage++} + 2 -> playerl(core.game.dialogue.FacialExpression.FRIENDLY, "Enjoy it! I'll see you soon!").also{stage = 998} + } + 998 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "Take care traveller.").also{stage = END_DIALOGUE } + 38 -> npcl(core.game.dialogue.FacialExpression.FRIENDLY, "Cedric is a member of the order too. We sent him out three days ago to collect wine. But he didn't return!").also{stage++} + 39 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "He most probably got drunk and lost in the forest!").also{stage++} + 40 -> options( + "I've no time for that, sorry.", + "Where should I look?", + "Can I come to the party?").also { stage++} + 41 -> when(buttonID){ + 1 -> playerl(core.game.dialogue.FacialExpression.NEUTRAL, "I've no time for that, sorry.").also {stage = 996} + 2 -> playerl(core.game.dialogue.FacialExpression.HALF_ASKING, "Where should I look?").also {stage++} + 3 -> playerl(core.game.dialogue.FacialExpression.HALF_ASKING, "Can I come to the party?").also{stage = 997} + } + 996 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "Okay traveller, take care.").also{stage = END_DIALOGUE } + 997 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "Of course, but we need the wine first.").also{stage = END_DIALOGUE } + 42 -> npcl(core.game.dialogue.FacialExpression.FRIENDLY, "Oh, he won't be far. Probably out in the forest.").also{stage++} + 43 -> playerl(core.game.dialogue.FacialExpression.FRIENDLY, "Ok, I'll go and find him.").also { stage = END_DIALOGUE }.also{ + setQuestStage( + player!!, + Quests.MONKS_FRIEND, + 30 + )} + } + } + 30 -> { + when(stage) { + 0 -> playerl(core.game.dialogue.FacialExpression.HAPPY, "Hello brother Omad.").also{stage = 50} + 50 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "Hello adventurer, have you found Brother Cedric?").also{stage++} + 51 -> playerl(core.game.dialogue.FacialExpression.SAD, "Not yet.").also{stage++} + 52 -> npcl(core.game.dialogue.FacialExpression.FRIENDLY, "Well, keep looking, we need that wine!").also{stage = END_DIALOGUE } + } + } + 40 -> { + when(stage) { + 0 -> npcl(core.game.dialogue.FacialExpression.HAPPY, "Hello adventurer, have you found Brother Cedric?").also{stage = 60} + 60 -> playerl(core.game.dialogue.FacialExpression.NEUTRAL, "Yes I've seen him, he's a bit drunk!").also{stage++} + 61 -> npcl(core.game.dialogue.FacialExpression.FRIENDLY, "Well, try your best to get him back here!").also{stage = END_DIALOGUE } + } + } + 41, 42 -> { + when(stage) { + 0 -> playerl(core.game.dialogue.FacialExpression.HAPPY, "Hello again brother Omad.").also{stage = 70} + 70 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "Hello adventurer, where's Brother Cedric?").also{stage++} + 71 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "He's having a bit of trouble with his cart.").also{stage++} + 72 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "Hmmm! Maybe you could help?").also{stage = END_DIALOGUE } + } + } + 50 -> { + when(stage) { + 0 -> playerl(core.game.dialogue.FacialExpression.HAPPY, "Hi Omad, Brother Cedric is on his way!").also{stage = 80} + 80 -> npcl(core.game.dialogue.FacialExpression.HAPPY, "Good! Good! Now we can party!").also{stage++} + 81 -> npcl(core.game.dialogue.FacialExpression.HAPPY, "I have little to repay you with, but I'd like to offer you some rune stones. But first, let's party!").also{stage++} + 82 -> sendDialogue(player!!, "Brother Omad gives you 8 Law Runes").also{stage++} + 83 -> playerl(core.game.dialogue.FacialExpression.HAPPY, "Thanks Brother Omad!").also{stage++} + 84 -> { + commenceMonkParty(true) + end() + } + } + } + 100 -> { + commenceMonkParty(false) + } + } + } + + private fun commenceMonkParty(questComplete : Boolean) { + val brotherOmad: NPC? = RegionManager.getNpc(Location(2604, 3209, 0), 279, 6) + val monk: NPC? = RegionManager.getNpc(Location(2609, 3207, 0), 281, 6) + + // Spawn balloons when PartyRoom code is fixed. + + Pulser.submit(object : Pulse(1) { + var count = 0 + override fun pulse(): Boolean { + when (count) { + 1 -> { + brotherOmad!!.sendChat("Party!") + brotherOmad.animator.animate(Animation(866)) // Dance + + } + 3 -> { + player!!.sendChat("Woop!") + player!!.animator.animate(Animation(866)) // Dance + } + 5 -> { + monk!!.sendChat("Yeah!") + monk.animator.animate(Animation(2106)) // Jig + } + 7 -> brotherOmad!!.sendChat("Let's boogie!") + 9 -> player!!.sendChat("Oh, baby!") + 11 -> monk!!.sendChat("GO!") + 13 -> { + brotherOmad!!.sendChat("Get down!") + brotherOmad.animator.animate(Animation(2108)) // Headbang + } + 15 -> player!!.sendChat("Feel the rhythm!") + 17 -> monk!!.sendChat("Dance!") + 19 -> brotherOmad!!.sendChat("Oh my!") + 21 -> { + player!!.sendChat("Watch me go!") + player!!.animator.animate(Animation(861)) // Laugh + } + 23 -> { + monk!!.sendChat("You go!") + monk.animator.animate(Animation(2109)) // Jump for joy + } + 25 -> if (questComplete) { + player!!.questRepository.getQuest(Quests.MONKS_FRIEND).finish(player) + } + } + count++ + return false + } + }) + } +} + +/** + * Handles BrotherCedricListener to launch the dialogue + * @author Kya + */ +class BrotherOmadListener : InteractionListener { + override fun defineListeners() { + on(NPCs.BROTHER_OMAD_279, IntType.NPC, "talk-to"){ player, _ -> + player.dialogueInterpreter.open(BrotherOmadDialogue(), NPC(NPCs.BROTHER_OMAD_279)) + return@on true + } + } +} diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/monksfriend/MonasteryMonkNPC.kt b/Server/src/main/content/region/kandarin/ardougne/quest/monksfriend/MonasteryMonkNPC.kt new file mode 100644 index 0000000..cfe48d0 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/monksfriend/MonasteryMonkNPC.kt @@ -0,0 +1,45 @@ +package content.region.kandarin.ardougne.quest.monksfriend + +import core.game.node.entity.npc.NPC +import org.rs09.consts.NPCs +import core.game.dialogue.DialogueFile +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.tools.END_DIALOGUE +import content.data.Quests + +/** +* Handles MonasteryMonkDialogue Dialogue +* @author Kya +*/ +class MonasteryMonkDialogue : DialogueFile() { + override fun handle(interfaceId: Int, buttonId: Int) { + var questStage = player!!.questRepository.getStage(Quests.MONKS_FRIEND) + if (questStage == 0){ + when(stage) { + 0 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL,"Peace brother.").also { stage = END_DIALOGUE } + } + } else if (questStage < 100) { + when(stage) { + 0 -> npcl(core.game.dialogue.FacialExpression.FRIENDLY,"*yawn*").also{stage = END_DIALOGUE } + } + } else { + when(stage) { + 0 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Can't wait for the party!").also{stage = END_DIALOGUE } + } + } + } +} + +/** + * Handles BrotherCedricListener to launch the dialogue + * @author Kya + */ +class MonasteryMonkListener : InteractionListener { + override fun defineListeners() { + on(NPCs.MONK_281, IntType.NPC, "talk-to"){ player, _ -> + player.dialogueInterpreter.open(MonasteryMonkDialogue(), NPC(NPCs.MONK_281)) + return@on true + } + } +} diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/monksfriend/MonksFriend.kt b/Server/src/main/content/region/kandarin/ardougne/quest/monksfriend/MonksFriend.kt new file mode 100644 index 0000000..c559c6a --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/monksfriend/MonksFriend.kt @@ -0,0 +1,69 @@ +package content.region.kandarin.ardougne.quest.monksfriend + + +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.plugin.Initializable +import org.rs09.consts.Items +import content.data.Quests + +/** +* Represents the "Monk's Friend" quest. +* @author Kya +*/ + +@Initializable +class MonksFriend: Quest(Quests.MONKS_FRIEND, 89, 88, 1, 30, 0, 1, 80) { + + override fun newInstance(`object`: Any?): Quest { + return this + } + + override fun drawJournal(player: Player?, stage: Int) { + super.drawJournal(player, stage) + var line = 11 + player?: return + if(stage == 0){ + line(player, "I can start this quest by speaking to !!Brother Omad?? in the", line++) + line(player, "!!Monastery?? south of !!Ardougne??.", line++) + line++ + } + if(stage == 10){ + line(player, "Brother Omad asked me to recover a child's blanket.", line++) + } + if(stage >= 20){ + line(player, "Brother Omad asked me to recover a child's blanket, I ", line++, true) + line(player, "found the secret cave and gave back the blanket.", line++, true) + + } + if(stage ==30){ + line(player, "I agreed to find !!Brother Cedric.?? he is somewhere in the", line++) + line(player, "!!forest?? south of !!Ardougne??", line++) + } + if(stage >= 50){ + line(player, "I found Brother Cedric in the forest south of Ardougne.", line++, true) + line(player, "I sobered him up and I helped him fix his cart.", line++, true) + } + if(stage == 100){ + line(player, "I had a party with the Monks. There were party balloons and we danced the night away!", line++, true) + line++ + line(player, "%%QUEST COMPLETE!&&", line++) + } + } + + override fun finish(player: Player?) { + super.finish(player) + player ?: return + var ln = 10 + player.packetDispatch.sendItemZoomOnInterface(Items.LAW_RUNE_563, 230, 277, 5) + drawReward(player,"1 Quest Point", ln++) + drawReward(player,"8 Law Runes", ln++) + drawReward(player,"2000 Woodcutting XP", ln++) + + rewardXP(player, Skills.WOODCUTTING, 2000.0) + player.inventory.add(Item(563, 8)) + } +} diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/PlagueCity.kt b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/PlagueCity.kt new file mode 100644 index 0000000..d34a890 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/PlagueCity.kt @@ -0,0 +1,114 @@ +package content.region.kandarin.ardougne.quest.plaguecity + +import content.data.Quests +import core.api.addItemOrDrop +import core.api.removeAttributes +import core.api.rewardXP +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import org.rs09.consts.Items + +@Initializable +class PlagueCity : Quest(Quests.PLAGUE_CITY, 98, 97, 1, 165, 0, 1, 29) { + override fun newInstance(`object`: Any?): Quest { return this } + override fun drawJournal(player: Player?, stage: Int) { + super.drawJournal(player, stage) + var line = 11 + player ?: return + + if (stage == 0) { + line++ + line(player, "I can start this quest by speaking to !!Edmond?? who is in !!East??", line++, false) + line(player, "!!Ardougne??",line++, false) + line++ + line(player, "There aren't any requirements for this quest.", line++, false) + } + + if (stage >= 1) { + line++ + line(player, "I've spoken to Edmond, he's asked me to", line++, stage >= 2) + line(player, "help find his daughter Elena.", line++, stage >= 2) + line++ + } + + if (stage >= 2) { + line++ + line(player, "Alrena has given me a gas mask to protect me", line++, stage >= 3) + line(player, "from the plague while in West Ardougne.", line++, stage >= 3) + line++ + } + + if (stage >= 3) { + line++ + line(player, "She's making a spare which will be in the wardrobe.", line++, stage >= 4) + line(player, "I've spoken to Edmond about getting into West Ardougne.", line++, stage >= 4) + } + + if (stage >= 4) { + line++ + line(player, "I've softened the ground in Edmond's garden enough to dig.", line++, stage >= 5) + } + + if (stage >= 5) { + line++ + line(player, "I've dug a tunnel into the sewers.", line++, stage >= 6) + } + + if (stage >= 6) { + line++ + line(player, "I've managed to clear the way into West Ardougne.", line++, stage >= 7) + } + + if (stage >= 9) { + line++ + line(player, "I've spoken to Jethick, he thinks Elena was staying with the", line++, stage >= 11) + line(player, "Rehnison Family, in a timber house to the north of the city.", line++, stage >= 11) + } + + if (stage >= 11) { + line++ + line(player, "I've spoken to Milli about Elena,", line++, stage >= 12) + line(player, "she says Elena was taken into one of the Plague Houses.", line++, stage >= 12) + } + + if (stage >= 15) { + line++ + line(player, "Bravek might give me clearance if I make his Hangover Cure.", line++, stage >= 16) + } + + if (stage >= 16) { + line++ + line(player, "I've given Bravek the Hangover Cure and he has", line++, stage >= 17) + line(player, "given me a warrant to enter the plague House.", line++, stage >= 17) + } + + if (stage >= 99) { + line++ + line(player, "I've freed Elena from the Plague House.", line++, stage == 100) + } + + if (stage == 100) { + line++ + line(player, "I've spoken to Edmond and he thanked me", line++, true) + line(player, "for rescuing his daughter Elena.", line++, true) + line++ + line(player, "QUEST COMPLETE!", line, false) + } + } + + override fun finish(player: Player?) { + super.finish(player) + player ?: return + var ln = 10 + + player.packetDispatch.sendItemZoomOnInterface(Items.GAS_MASK_1506, 230, 277, 5) + drawReward(player, "1 Quest Point", ln++) + drawReward(player, "2,425 Mining XP", ln++) + drawReward(player, "An Ardougne Teleport Scroll", ln) + rewardXP(player, Skills.MINING, 2425.0) + addItemOrDrop(player, Items.A_MAGIC_SCROLL_1505) + removeAttributes(player, "/save:elena:dig", "/save:elena:bucket") + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/PlagueCityListeners.kt b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/PlagueCityListeners.kt new file mode 100644 index 0000000..1b38557 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/PlagueCityListeners.kt @@ -0,0 +1,430 @@ +package content.region.kandarin.ardougne.quest.plaguecity + +import content.data.Quests +import content.region.kandarin.ardougne.quest.plaguecity.dialogue.mourners.MournerKidnapDialogueFile +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.global.action.DoorActionHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.world.map.Direction +import core.game.world.map.Location +import core.game.world.update.flag.context.Graphics +import core.tools.END_DIALOGUE +import org.rs09.consts.* +import core.game.node.scenery.Scenery as SceneryNode + +class PlagueCityListeners : InteractionListener { + companion object { + + const val BUCKET_USES_ATTRIBUTE = "/save:elena:bucket" + const val ARDOUGNE_TELE_ATTRIBUTE = "/save:Ardougne:teleport" + + private const val TRYING_TO_OPEN_GRILL = 3192 + private const val POUR_THE_WATER = 2283 + private const val CLIMB_LADDER = 828 + private const val GO_INTO_PIPE = 10580 + private const val TIE_THE_ROPE = 3191 + private const val DIG_WITH_SPADE = 830 + + } + + override fun defineListeners() { + + on(NPCs.BILLY_REHNISON_723, IntType.NPC, "talk-to") { player, _ -> + sendMessage(player, "Billy isn't interested in talking.") + return@on true + } + + on(Scenery.MANHOLE_2543, IntType.SCENERY, "open") { player, node -> + replaceScenery(node.asScenery(), Scenery.MANHOLE_2544, -1) + addScenery(Scenery.MANHOLE_COVER_2545, Location(node.location.x, node.location.y-1, 0),0,10) + sendMessage(player, "You pull back the manhole cover.") + return@on true + } + + on(Scenery.MANHOLE_COVER_2545, IntType.SCENERY, "close") { player, node -> + removeScenery(node.asScenery()) + getScenery(location(node.location.x, node.location.y+1, 0))?.let { replaceScenery(it, Scenery.MANHOLE_2543, -1) } + sendMessage(player, "You close the manhole cover.") + return@on true + } + + on(Scenery.MANHOLE_2544, IntType.SCENERY, "climb-down") { player, _ -> + teleport(player, Location(2514, 9739, 0)) + face(player, Location.create(2514, 9740)) + sendMessage(player, "You climb down through the manhole.") + return@on true + } + + on(Scenery.DOOR_2528, IntType.SCENERY, "open") { player, node -> + if (getQuestStage(player, Quests.PLAGUE_CITY) >= 13) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else { + sendNPCDialogue(player, NPCs.BRAVEK_711,"Go away, I'm busy! I'm... Umm... In a meeting!") + // This typo is authentic + sendMessage(player, "The door won't open") + } + return@on true + } + + on(Scenery.MUD_PILE_2533, IntType.SCENERY, "climb") { player, _ -> + animate(player, CLIMB_LADDER) + queueScript(player, 2){ + teleport(player, Location(2566, 3332)) + sendDialogue(player, "You climb up the mud pile.") + return@queueScript true + } + return@on true + } + + on(Scenery.DUG_HOLE_11417, IntType.SCENERY, "Climb-down") { player, _ -> + teleport(player, Location(2518, 9759)) + sendDialogue(player, "You climb down the tunnel into the sewer.") + return@on true + } + + on(Items.A_MAGIC_SCROLL_1505, IntType.ITEM, "read") { player, item -> + if (removeItem(player, item)){ + if (getAttribute(player, ARDOUGNE_TELE_ATTRIBUTE, false)){ + sendGraphics(Graphics(157,96), player.location) + impact(player, 0) + sendMessage(player, "The scroll explodes.") + addItem(player, Items.ASHES_592) + } + else{ + sendItemDialogue(player, Items.A_MAGIC_SCROLL_1505, "You memorise what is written on the scroll.") + sendDialogue(player, "You can now cast the Ardougne Teleport spell provided you have the required runes and magic level.") + setAttribute(player, ARDOUGNE_TELE_ATTRIBUTE, true) + } + return@on true + } + return@on false + } + + on(Items.A_SCRUFFY_NOTE_1508, IntType.ITEM, "read") { player, _ -> + sendMessage(player, "You guess it really says something slightly different.") + openInterface(player, 222).also { scruffyNote(player) } + return@on true + } + + class KidnapDoorDialogue : DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + + when(stage) { + 0 -> { + // Face the door + face(player!!, Location.create(player!!.location.x, 3270, 0)) + sendDialogue(player!!, "The door won't open. You notice a black cross on the door.").also { stage++ } + } + 1 -> openDialogue(player!!, MournerKidnapDialogueFile(), NPC(NPCs.MOURNER_3216)) + } + } + + } + + on(Scenery.DOOR_35991, IntType.SCENERY, "open") { player, node -> + if (getQuestStage(player, Quests.PLAGUE_CITY) > 16) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } + else { + // Make sure we are standing in front of the door + forceWalk(player, Location.create(node.location.x, node.location.y), "smart") + openDialogue(player, KidnapDoorDialogue()) + } + return@on true + } + + on(Scenery.WARDROBE_2525, IntType.SCENERY, "search") { player, _ -> + if(getQuestStage(player, Quests.PLAGUE_CITY) >= 2){ + if (!hasAnItem(player, Items.GAS_MASK_1506).exists()){ + if(freeSlots(player) == 0) { + sendItemDialogue(player, Items.GAS_MASK_1506, "You find a protective mask but you don't have enough room to take it.") + return@on true + } + else { + sendItemDialogue(player, Items.GAS_MASK_1506, "You find a protective mask.") + addItem(player, Items.GAS_MASK_1506) + return@on true + } + } + } + // The player should not be given a mask for whatever reason + sendMessage(player, "You search the wardrobe but you find nothing.") + return@on false + } + + onUseWith(IntType.SCENERY, Items.BUCKET_OF_WATER_1929, Scenery.MUD_PATCH_11418) { player, _, _ -> + if (getAttribute(player, BUCKET_USES_ATTRIBUTE, 0) in 0..2 && removeItem(player, Items.BUCKET_OF_WATER_1929)) { + animate(player, POUR_THE_WATER) + sendDialogueLines(player, "You pour water onto the soil.", "The soil softens slightly." + ) + player.incrementAttribute(BUCKET_USES_ATTRIBUTE, 1) + addItem(player, Items.BUCKET_1925) + return@onUseWith true + } else if (getAttribute(player, BUCKET_USES_ATTRIBUTE, 0) == 3 && removeItem(player, Items.BUCKET_OF_WATER_1929)) { + animate(player, POUR_THE_WATER) + player.incrementAttribute(BUCKET_USES_ATTRIBUTE, 1) + sendDialogueLines(player, + "You pour water onto the soil.", + "The soil is now soft enough to dig into." + ) + setAttribute(player, "/save:elena:dig", true) + addItem(player, Items.BUCKET_1925) + } else { + sendDialogue(player, "You don't need to pour on any more water the soil is soft enough already.") + } + return@onUseWith true + } + + + onDig(Location.create(2566, 3332, 0)){ player: Player -> + dig(player) + } + + onUseWith(IntType.SCENERY, Items.SPADE_952, Scenery.MUD_PATCH_11418) { player, _, _ -> + dig(player) + return@onUseWith true + } + + on(Scenery.GRILL_11423, IntType.SCENERY, "open") { player, _ -> + if (getQuestStage(player, Quests.PLAGUE_CITY) == 4) { + sendDialogue(player, "The grill is too secure. You can't pull it off alone.") + animate(player, TRYING_TO_OPEN_GRILL) + setQuestStage(player, Quests.PLAGUE_CITY, 5) + } else { + sendDialogue(player, "There is a grill blocking your way") + } + return@on true + } + + on(Scenery.PIPE_2542, IntType.SCENERY, "climb-up") { player, _ -> + if (getQuestStage(player, Quests.PLAGUE_CITY) >= 7) { + if (inEquipment(player, Items.GAS_MASK_1506)){ + animate(player, GO_INTO_PIPE,true) + queueScript(player, 3) { + teleport(player, Location(2529, 3304, 0)) + sendDialogue(player, "You climb up through the sewer pipe.") + return@queueScript stopExecuting(player) + } + forceMove(player, Location(2514, 9739, 0), Location(2514, 9734, 0), 0, 5,Direction.SOUTH) + } + else { + sendNPCDialogue(player, NPCs.EDMOND_714, "I can't let you enter the city without your gas mask on.") + } + } + else { + sendDialogue(player, "There is a grill blocking your way") + } + return@on true + } + + onUseWith(IntType.SCENERY, Items.ROPE_954, Scenery.PIPE_2542) { player, _, _ -> + sendPlayerDialogue(player, "Maybe I should try opening it first.") + return@onUseWith true + } + + onUseWith(IntType.SCENERY, Items.ROPE_954, Scenery.GRILL_11423) { player, _, _ -> + if(removeItem(player, Items.ROPE_954)) { + queueScript(player, 1) { stage: Int -> + when (stage) { + 0 -> forceWalk(player, Location.create(2514, 9740, 0), "SMART") + 2 -> face(player, Location.create(2514, 9739, 0), -1) + 3 -> { + animate(player, TIE_THE_ROPE) + setVarbit(player, 1787, 5, true) // Tied rope to the grill. + } + + 4 -> { + setQuestStage(player, Quests.PLAGUE_CITY, 6) + sendItemDialogue( + player, + Items.ROPE_954, + "You tie the end of the rope to the sewer pipe's grill." + ) + return@queueScript stopExecuting(player) + } + } + return@queueScript delayScript(player, 1) + } + return@onUseWith true + } else { + sendMessage(player, "Nothing interesting happens.") + } + return@onUseWith true + } + + class TedRehnisonDoors : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + npc = NPC(NPCs.TED_REHNISON_721) + when (stage) { + 0 -> { + npcl(FacialExpression.FRIENDLY, "Go away. We don't want any.").also { + if(hasAnItem(player!!, Items.BOOK_1509).exists()){ + stage++ + } else { + stage = END_DIALOGUE } + } + } + 1 -> playerl(FacialExpression.NEUTRAL, "I'm a friend of Jethick's, I have come to return a book he borrowed.").also { stage++ } + // todo change this back after sendItemDialogue is fixed for having a single line before See #1885 + 2 -> npc(FacialExpression.FRIENDLY, "", "Oh... why didn't you say, come in then.", "").also { stage++ } + 3 -> sendItemDialogue(player!!, Items.BOOK_1509, "You hand the book to Ted as you enter.").also { + DoorActionHandler.handleAutowalkDoor(player, getScenery(2531, 3328, 0)) + setQuestStage(player!!, Quests.PLAGUE_CITY, 9) + removeItem(player!!, Items.BOOK_1509) + stage++ + } + 4 -> npcl(FacialExpression.NEUTRAL, "Thanks, I've been missing that.").also { stage = END_DIALOGUE } + } + } + } + + on(Scenery.DOOR_2537, IntType.SCENERY, "open") { player, node -> + if (getQuestStage(player, Quests.PLAGUE_CITY) >= 9) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else { + openDialogue(player, TedRehnisonDoors()) + } + return@on true + } + + on(Scenery.BARREL_2530, IntType.SCENERY, "search") { player, _ -> + if (inInventory(player, Items.A_SMALL_KEY_1507)) { + sendMessage(player, "You don't find anything interesting.") + return@on true + } else { + sendItemDialogue(player, Items.A_SMALL_KEY_1507, "You find a small key in the barrel.") + addItem(player, Items.A_SMALL_KEY_1507) + } + } + + on(Scenery.SPOOKY_STAIRS_2522, IntType.SCENERY, "walk-down") { player, _ -> + sendMessage(player, "You walk down the stairs...") + teleport(player, Location.create(2537, 9671)) + return@on true + } + + on(Scenery.SPOOKY_STAIRS_2523, IntType.SCENERY, "walk-up") { player, _ -> + teleport(player, Location.create(2536, 3271, 0)) + sendMessage(player, "You walk up the stairs...") + return@on true + } + + class ElenaDoorDialogue : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + npc = NPC(NPCs.ELENA_3215) + when (stage) { + 0 -> sendDialogue(player!!, "The door is locked.").also { stage++ } + 1 -> npcl(FacialExpression.CRYING, "Hey get me out of here please!").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "I would do but I don't have a key.").also { stage++ } + 3 -> npcl(FacialExpression.SAD, "I think there may be one around somewhere. I'm sure I heard them stashing it somewhere.").also { stage++ } + 4 -> options("Have you caught the plague?", "Okay, I'll look for it.").also { stage++ } + 5 -> when (buttonID) { + 1 -> playerl(FacialExpression.WORRIED, "Have you caught the plague?").also { stage = 6 } + 2 -> playerl(FacialExpression.NEUTRAL, "Okay, I'll look for it.").also { stage = END_DIALOGUE } + } + 6 -> npcl(FacialExpression.HALF_WORRIED, "No, I have none of the symptoms.").also { stage++ } + 7 -> playerl(FacialExpression.THINKING, "Strange, I was told this house was plague infected.").also { stage++ } + 8 -> npcl(FacialExpression.THINKING, "I suppose that was a cover up by the kidnappers.").also { stage = END_DIALOGUE } + } + } + } + + onUseWith(IntType.SCENERY, Items.A_SMALL_KEY_1507, Scenery.DOOR_2526) { player, _, node -> + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + sendDialogue(player, "You unlock the door.") + return@onUseWith true + } + + on(Scenery.DOOR_2526, IntType.SCENERY, "open") { player, node -> + if (getQuestStage(player, Quests.PLAGUE_CITY) >= 99 || hasAnItem(player, Items.A_SMALL_KEY_1507).exists()) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else { + openDialogue(player, ElenaDoorDialogue()) + } + return@on true + } + + onUseWith(IntType.NPC, Items.HANGOVER_CURE_1504, NPCs.BRAVEK_711) { player, _, _ -> + openDialogue(player, NPCs.BRAVEK_711) + return@onUseWith true + } + + on(Scenery.DOOR_2054, IntType.SCENERY, "open"){ player, node -> + if (isQuestComplete(player, Quests.PLAGUE_CITY)){ + DoorActionHandler.handleDoor(player, node as SceneryNode) + } + else{ + sendMessage(player, "This door is locked") + } + return@on true + } + + } + + private fun dig(p : Player) { + if (getAttribute(p, "/save:elena:dig", false)) { + // Only remove the counter now that you have dug a hole + removeAttribute(p, BUCKET_USES_ATTRIBUTE) + queueScript(p, 1) { stage: Int -> + when (stage) { + 0 -> sendItemDialogue( + p, Items.SPADE_952, + "You dig deep into the soft soil... Suddenly it crumbles away!" + ) + + 1 -> animate(p, DIG_WITH_SPADE) + 3 -> { + teleport(p, Location(2518, 9759)) + setQuestStage(p, Quests.PLAGUE_CITY, 4) + setVarbit(p, Vars.VARBIT_QUEST_PLAGUE_CITY_EDMOND_TUNNELS, 1) + setVarbit(p, Vars.VARBIT_QUEST_PLAGUE_CITY_MUD_PILE, 1) + sendDialogueLines( + p, + "You fall through...", + "...you land in the sewer.", + "Edmond follows you down the hole." + ) + // We've dug the hole so don't keep track + removeAttribute(p, "/save:elena:dig") + return@queueScript stopExecuting(p) + } + } + return@queueScript delayScript(p, 1) + + } + } else { + sendMessage(p, "Nothing interesting happens.") + } + } + + private fun scruffyNote(player: Player) { + val scruffynotes = + arrayOf( + "Got a bncket of nnilk", + "Tlen grind sorne lhoculate", + "vnith a pestal and rnortar", + "ald the grourd dlocolate to tho milt", + "finales add 5cme snape gras5", + ) + setInterfaceText(player, scruffynotes.joinToString("
"), 222, 5) + } + + override fun defineDestinationOverrides() { + setDest(IntType.SCENERY, intArrayOf(Scenery.GRILL_11423), "open") { _, _ -> + return@setDest Location.create(2514, 9739, 0) + } + + setDest(IntType.SCENERY, intArrayOf(Scenery.PIPE_2542), "climb-up") { _, _ -> + return@setDest Location.create(2514, 9739, 0) + } + + setDest(IntType.SCENERY, intArrayOf(Scenery.MANHOLE_2544), "climb-down") { _, node -> + return@setDest Location.create(node.location.x, node.location.y+1, 0) + } + } +} diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/UndergroundCutscene.kt b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/UndergroundCutscene.kt new file mode 100644 index 0000000..eea5f2f --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/UndergroundCutscene.kt @@ -0,0 +1,124 @@ +package content.region.kandarin.ardougne.quest.plaguecity + +import content.data.Quests +import core.api.* +import core.game.activity.Cutscene +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.world.map.Direction +import core.game.world.map.Location + +class UndergroundCutscene(player: Player) : Cutscene(player) { + + override fun setup() { + setExit(Location.create(2514, 9740,0)) + if (player.settings.isRunToggled) { + player.settings.toggleRun() + } + loadRegion(10136) + addNPC(EDMOND, 18, 13, Direction.SOUTH) + } + + + override fun runStage(stage: Int) { + when (stage) { + + 0 -> { + fadeToBlack() + timedUpdate(5) + } + + 1 -> { + teleport(player, 18, 12) + setVarbit(player, 1787, 2, true) // Grill removal. + timedUpdate(1) + } + + 2 -> { + move(player, 18, 12) + face(player, base.transform(18, 11, 0)) + // You have to remove the stubborn previous sceneries before adding your own. + removeScenery(getScenery(base.transform(18, 11, 0))!!) + removeScenery(getScenery(base.transform(18, 12, 0))!!) + removeScenery(getScenery(base.transform(18, 13, 0))!!) + // Add the rope sceneries to animate. + addScenery(11416, base.transform(18, 11, 0),2,10) + addScenery(11412, base.transform(18, 12, 0),2,10) + addScenery(11414, base.transform(18, 13, 0),2,10) + fadeFromBlack() + moveCamera(21, 16) + rotateCamera(18, 13) + timedUpdate(4) + } + + 3 -> { + animate(getNPC(EDMOND)!!, ROPE_PULL) + animate(player, ROPE_PULL) + animateScenery(player, getScenery(base.transform(18, 11, 0))!!, 3189) + animateScenery(player, getScenery(base.transform(18, 12, 0))!!, 3188) + animateScenery(player, getScenery(base.transform(18, 13, 0))!!, 3188) + sendChat(player, "1... 2... 3... Pull!") + timedUpdate(6) + } + + 4 -> { + face(player, getNPC(EDMOND)!!.location) + timedUpdate(2) + } + + 5 -> { + dialogueUpdate(EDMOND, FacialExpression.FRIENDLY, "Once you're in the city look for a man called Jethick, he's an old friend and should help you. Send", hide=true) + sendChat(getNPC(EDMOND)!!, "Once you're in the city") + timedUpdate(4) + } + + 6 -> { + sendChat(getNPC(EDMOND)!!, "look for a man called") + timedUpdate(4) + } + + 7 -> { + sendChat(getNPC(EDMOND)!!, "Jethick, he's an old friend") + timedUpdate(4) + } + + 8 -> { + sendChat(getNPC(EDMOND)!!, "and should help you. Send") + timedUpdate(4) + } + + 9 -> { + dialogueUpdate(EDMOND, FacialExpression.FRIENDLY, "him my regards, I haven't seen him since before Elena was born.", hide=true) + sendChat(getNPC(EDMOND)!!, "him my regards, I haven't") + timedUpdate(4) + } + + 10 -> { + sendChat(getNPC(EDMOND)!!, "seen him since before") + timedUpdate(4) + } + + 11 -> { + sendChat(getNPC(EDMOND)!!, "Elena was born.") + timedUpdate(4) + } + + 12 -> { + sendChat(player, "Alright, thanks I will.") + // todo change this to true once no continue button player model size is fixed + sendPlayerDialogue(player,"Alright, thanks I will.", hide = false) + timedUpdate(2) + } + 13 -> { + end { + setQuestStage(player, Quests.PLAGUE_CITY, 7) + } + } + } + } + + companion object { + private const val EDMOND = 714 + private const val ROPE_PULL = 3187 + } +} diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/AlrenaDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/AlrenaDialogue.kt new file mode 100644 index 0000000..56384c4 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/AlrenaDialogue.kt @@ -0,0 +1,155 @@ +package content.region.kandarin.ardougne.quest.plaguecity.dialogue + +import content.data.Quests +import content.region.kandarin.ardougne.quest.plaguecity.PlagueCityListeners +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class AlrenaDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + if (player.questRepository.getStage(Quests.PLAGUE_CITY) == 1) { + // playerl formats this weirdly + player(FacialExpression.FRIENDLY, "Hello, Edmond has asked me to help find your","daughter.").also { stage++ } + } else { + playerl(FacialExpression.FRIENDLY, "Hello Madam.").also { stage++ } + } + return true + } + + override fun handle(componentID: Int, buttonID: Int): Boolean { + when (getQuestStage(player!!, Quests.PLAGUE_CITY)) { + + 0 -> when (stage) { + 1 -> npcl(FacialExpression.NEUTRAL, "Oh, hello there.").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "Are you ok?").also { stage++ } + 3 -> npcl(FacialExpression.NEUTRAL, "Not too bad... I've just got some troubles on my mind...").also { stage = END_DIALOGUE } + } + + 1 -> when (stage) { + 1 -> npcl(FacialExpression.NEUTRAL, "Yes he told me. I've begun making your special gas mask, but I need some dwellberries to finish it.").also { stage++ } + 2 -> if (inInventory(player!!, Items.DWELLBERRIES_2126)) { + playerl(FacialExpression.NEUTRAL, "Yes I've got some here.").also { stage++ } + } else { + npcl(FacialExpression.FRIENDLY, "The place to look is in McGrubor's Wood to the west of Seers village.").also { stage = 8 } + } + 3 -> { + sendItemDialogue(player!!, Items.DWELLBERRIES_2126, "You give the dwellberries to Alrena.").also { stage++ } + removeItem(player!!, Items.DWELLBERRIES_2126) + } + // sendDialogue formats this weirdly + 4 -> sendDialogueLines(player!!, "Alrena crushes the berries into a smooth paste. She then smears the", "paste over a strange mask.").also { stage++ } + // npcl formats this weirdly + 5 -> npc(FacialExpression.FRIENDLY, "There we go, all done. While in West Ardougne you", "must wear this at all times, or you could catch the","plague.").also { stage++ } + 6 -> { + setQuestStage(player!!, Quests.PLAGUE_CITY, 2) + addItem(player!!, Items.GAS_MASK_1506) + sendItemDialogue(player!!, Items.GAS_MASK_1506, "Alrena gives you the mask.").also { stage++ } + // Jump down to quest stage 2 from here + } + 8 -> playerl(FacialExpression.NEUTRAL, "Ok, I'll go and get some.").also { stage = END_DIALOGUE } + } + + 2 -> when (stage) { + 1 -> npcl(FacialExpression.FRIENDLY, "Hello darling, I think Edmond had a good idea of how to get into West Ardougne, you should hear his idea.").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "Alright I'll go and see him now.").also { stage = END_DIALOGUE } + + // This gets entered from quest stage 1 + 7 -> npcl(FacialExpression.FRIENDLY, "I'll make a spare mask. I'll hide it in the wardrobe in case the mourners come in.").also { stage = END_DIALOGUE } + } + + 3 -> when (stage) { + 1 -> if (player.getAttribute(PlagueCityListeners.BUCKET_USES_ATTRIBUTE, 0) == 1) { + npcl(FacialExpression.FRIENDLY, "Hello darling, how's that tunnel coming along?").also { stage = 5 } + } else { + npcl(FacialExpression.FRIENDLY, "How's the tunnel going?").also { stage++ } + } + 2 -> playerl(FacialExpression.FRIENDLY, "I'm getting there.").also { stage++ } + 3 -> npcl(FacialExpression.FRIENDLY, "One of the mourners has been sniffing around asking questions about you and Edmond, you should keep an eye out for him.").also { stage++ } + 4 -> playerl(FacialExpression.FRIENDLY, "Ok, thanks for the warning.").also { stage = END_DIALOGUE } + 5 -> playerl(FacialExpression.FRIENDLY, "I just need to soften the soil a little more and then we'll start digging.").also { stage = END_DIALOGUE } + } + + 4 -> when (stage) { + 1 -> npcl(FacialExpression.FRIENDLY, "Hi, have you managed to get through to West Ardougne?").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "Not yet, but I should be going soon.").also { stage++ } + 3 -> npcl(FacialExpression.FRIENDLY, "Make sure you wear your mask while you're over there! I can't think of a worse way to die.").also { stage++ } + 4 -> playerl(FacialExpression.FRIENDLY, "Ok, thanks for the warning.").also { stage = END_DIALOGUE } + } + + 5 -> when (stage) { + 1 -> npcl(FacialExpression.FRIENDLY, "Hello, any word on Elena?").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "Not yet I'm afraid.").also { stage++ } + 3 -> npcl(FacialExpression.FRIENDLY, "Is there anything else I can do to help?").also { stage++ } + 4 -> playerl(FacialExpression.FRIENDLY, "It's alright, I'll get her back soon.").also { stage++ } + 5 -> if(inEquipment(player, Items.GAS_MASK_1506)) { + npcl(FacialExpression.FRIENDLY, "That's the spirit, dear.").also { stage = END_DIALOGUE } + } else { + npcl(FacialExpression.FRIENDLY, "That's the spirit, dear. Don't forget that there's a spare gas mask in the wardrobe if you need one.").also { stage = END_DIALOGUE } + } + } + + in 6..7 -> when (stage) { + 1 -> npcl(FacialExpression.FRIENDLY, "Hi, have you managed to get through to West Ardougne?").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "Not yet, but I should be going soon.").also { stage++ } + 3 -> npcl(FacialExpression.FRIENDLY, "Make sure you wear your mask while you're over there! I can't think of a worse way to die.").also { stage++ } + 4 -> if(inEquipment(player, Items.GAS_MASK_1506)) { + playerl(FacialExpression.FRIENDLY, "Okay, thanks for the warning.").also { stage = END_DIALOGUE } + } else { + npcl(FacialExpression.FRIENDLY, "Don't forget, I've got a spare one hidden in the wardrobe if you need it.").also { stage++ } + } + 5 -> playerl(FacialExpression.FRIENDLY, "Great, thanks Alrena!").also { stage = END_DIALOGUE } + } + + in 8..14 -> when (stage) { + 1 -> npcl(FacialExpression.FRIENDLY, "Hello, any word on Elena?").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "Not yet I'm afraid.").also { stage++ } + 3 -> npcl(FacialExpression.FRIENDLY, "Is there anything else I can do to help?").also { stage++ } + 4 -> playerl(FacialExpression.FRIENDLY, "Do you have a picture of Elena?").also { stage++ } + 5 -> npcl(FacialExpression.FRIENDLY, " Yes. There should be one in the house somewhere. Let me know if you need anything else.").also { stage = END_DIALOGUE } + } + + 15 -> when (stage) { + 1 -> npcl(FacialExpression.FRIENDLY, "Hello, any word on Elena?").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "Not yet I'm afraid, I need to find some Snape grass first, any idea where I'd find some?").also { stage++ } + 3 -> npcl(FacialExpression.FRIENDLY, "It's not common round here, though I hear it's easy to find by the coast south west of Falador.").also { stage++ } + 4 -> playerl(FacialExpression.FRIENDLY, "Thanks, I'll go take a look.").also { stage++ } + 5 -> playerl(FacialExpression.FRIENDLY, "I also need to get some chocolate powder for a hangover cure for the city warder.").also { stage++ } + 6 -> npcl(FacialExpression.FRIENDLY, "Well I don't have any chocolate, but this may help.").also { stage++ } + 7 -> sendItemDialogue(player!!, Items.PESTLE_AND_MORTAR_233, "Alrena hands you a pestle and mortar.").also { + addItem(player!!, Items.PESTLE_AND_MORTAR_233) + stage++ + } + 8 -> playerl(FacialExpression.FRIENDLY, "Thanks.").also { stage = END_DIALOGUE } + } + + in 16 .. 98 -> when(stage){ + 1 -> npcl(FacialExpression.WORRIED, "Hello, any word on Elena?").also { stage++ } + 2 -> playerl(FacialExpression.NEUTRAL, "Not yet I'm afraid.").also { stage++ } + 3 -> npcl(FacialExpression.WORRIED, "Is there anything else I can do to help?").also { stage++ } + 4 -> playerl(FacialExpression.SAD, "Sorry but not right now.").also {stage = END_DIALOGUE } + + } + + 99 -> when (stage) { + 1 -> npcl(FacialExpression.NEUTRAL, "Thank you, thank you! Elena beat you back by minutes.").also { stage = END_DIALOGUE } + } + + 100 -> when (stage) { + 1 -> npcl(FacialExpression.FRIENDLY, "Thank you for rescuing my daughter! Elena has told me of your bravery in entering a house that could have been plague infected. I can't thank you enough!").also { stage = END_DIALOGUE } + } + } + return true + } + + override fun getIds(): IntArray = intArrayOf(NPCs.ALRENA_710) +} diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/BravekDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/BravekDialogue.kt new file mode 100644 index 0000000..3eeb1e3 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/BravekDialogue.kt @@ -0,0 +1,156 @@ +package content.region.kandarin.ardougne.quest.plaguecity.dialogue + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class BravekDialogue(player: Player? = null) : DialoguePlugin(player) { + + companion object{ + const val SPEAK_ANOTHER_DAY = 10 + const val WAITING_FOR_CURE = 20 + const val CURED = 30 + const val IMPORTANT = 50 + const val DRINK_TOO_MUCH = 60 + const val CURE = 70 + const val WHAT_HELP = 80 + const val ALL_PEOPLE_SAY = 90 + const val NOT_LISTEN = 100 + const val INTEREST = 110 + const val WEAK_LEADER = 120 + } + + override fun open(vararg args: Any?): Boolean { + npc = if (args[0] is Int) NPC(args[0] as Int) else args[0] as NPC + when(getQuestStage(player, Quests.PLAGUE_CITY)){ + in 0..13 -> npcl(FacialExpression.ANNOYED, "My head hurts! I'll speak to you another day...").also { stage = SPEAK_ANOTHER_DAY } + 14 -> npcl(FacialExpression.ANNOYED, " Uurgh! My head still hurts too much to think straight. " + + "Oh for one of Trudi's hangover cures!").also { stage = if(hasAnItem(player, Items.HANGOVER_CURE_1504).exists()) WAITING_FOR_CURE else END_DIALOGUE } + 15 -> npcl(FacialExpression.FRIENDLY, "Ah now, what was it you wanted me to do for you?").also { stage = WHAT_HELP } + else -> npcl(FacialExpression.FRIENDLY, "Thanks again for the hangover cure.").also { stage = if(hasAnItem(player, Items.WARRANT_1503).exists() || getQuestStage(player, Quests.PLAGUE_CITY) >= 99) CURED else WHAT_HELP } + + } + return true + } + + override fun handle(componentID: Int, buttonID: Int): Boolean { + when (stage){ + + SPEAK_ANOTHER_DAY -> showTopics( + Topic("This is really important though!", IMPORTANT), + Topic("Ok, goodbye.", END_DIALOGUE) + ) + + IMPORTANT -> npc(FacialExpression.ANNOYED, + "I can't possibly speak to you with my head spinning like", + "this... I went a bit heavy on the drink again last night.", + "Curse my herbalist, she made the best hang over cures.", + "Darn inconvenient of her catching the plague.").also { stage++ } + IMPORTANT + 1 -> showTopics( + Topic("Ok, goodbye.", END_DIALOGUE), + Topic(" You shouldn't drink so much then!", DRINK_TOO_MUCH), + Topic("Do you know what's in the cure?", CURE) + ) + + DRINK_TOO_MUCH -> npcl(FacialExpression.ANNOYED, "Well positions of responsibility are hard, " + + "I need something to take my mind off things... Especially with the problems this place has.").also { stage++ } + DRINK_TOO_MUCH + 1 -> showTopics( + Topic("Ok, goodbye.", END_DIALOGUE), + Topic("Do you know what's in the cure?", CURE), + Topic("I don't think drink is the solution.", DRINK_TOO_MUCH+2) + ) + DRINK_TOO_MUCH + 2 -> npcl(FacialExpression.ANNOYED, "Uurgh! My head still hurts too much to think straight. Oh for one of Trudi's hangover cures!").also { stage = END_DIALOGUE } + + CURE -> npc(FacialExpression.NEUTRAL, + "Hmmm let me think... Ouch! Thinking isn't clever. Ah", + "here, she did scribble it down for me.").also { stage++ } + CURE + 1 -> { + if(hasSpaceFor(player!!, Item(Items.A_SCRUFFY_NOTE_1508))) { + sendItemDialogue( + player!!, + Items.A_SCRUFFY_NOTE_1508, + "Bravek hands you a tatty piece of paper." + ).also { stage++ } + } + else{ + sendItemDialogue(player!!, Items.A_SCRUFFY_NOTE_1508, "Bravek waves a note in front of you but you do not have space for it").also { stage = END_DIALOGUE } + } + } + CURE + 2 ->{ + addItem(player!!, Items.A_SCRUFFY_NOTE_1508) + setQuestStage(player!!, Quests.PLAGUE_CITY, 14) + end() + } + + WAITING_FOR_CURE -> playerl(FacialExpression.NEUTRAL, "Try this.").also { stage++ } + WAITING_FOR_CURE + 1 -> { + animate(npc, 1330) // Drink hangover cure. + findLocalNPC(player!!, NPCs.BRAVEK_711)!!.sendChat("Grruurgh!") + sendItemDialogue(player!!, Items.HANGOVER_CURE_1504, "You give Bravek the hangover cure. Bravek gulps down the foul-looking liquid.").also { stage++ } + setQuestStage(player, Quests.PLAGUE_CITY, 15) + removeItem(player, Items.HANGOVER_CURE_1504) + } + WAITING_FOR_CURE + 2 -> npcl(FacialExpression.HAPPY, "Ooh that's much better! Thanks, that's the clearest my head has felt in a month." + + "Ah now, what was it you wanted me to do for you?" + ).also { stage = WHAT_HELP } + + WHAT_HELP -> playerl(FacialExpression.ASKING, "I need to rescue a kidnap victim called Elena. She's being held in a plague house, I need permission to enter.").also { stage++ } + WHAT_HELP + 1 -> npcl(FacialExpression.HALF_GUILTY, "Well the mourners deal with that sort of thing...").also { stage++ } + WHAT_HELP + 2 -> showTopics( + Topic("Ok, I'll go speak to them.", END_DIALOGUE), + Topic("Is that all anyone says around here?", ALL_PEOPLE_SAY), + Topic("They won't listen to me!", NOT_LISTEN, skipPlayer = true) + ) + + ALL_PEOPLE_SAY -> npcl(FacialExpression.HALF_GUILTY, "Well, they know best about plague issues.").also { stage++ } + ALL_PEOPLE_SAY + 1 -> showTopics( + Topic("Don't you want to take an interest in it at all?", INTEREST), + Topic("They won't listen to me!", NOT_LISTEN, skipPlayer = true) + ) + + INTEREST -> npcl(FacialExpression.HALF_GUILTY, "Nope, I don't wish to take a deep interest in plagues. That stuff is too scary for me!").also { stage++ } + INTEREST + 1 -> showTopics( + Topic("I see why people say you're a weak leader.", WEAK_LEADER), + Topic("Ok, I'll talk to the mourners.", END_DIALOGUE), + Topic("They won't listen to me!", NOT_LISTEN, skipPlayer = true) + ) + + WEAK_LEADER -> npcl(FacialExpression.ANNOYED, "Bah, people always criticise their leaders but delegating is the only way to lead. I delegate all plague issues to the mourners.").also { stage++ } + WEAK_LEADER + 1 -> playerl(FacialExpression.ANNOYED, "This whole city is a plague issue!").also { stage = END_DIALOGUE } + + NOT_LISTEN -> playerl(FacialExpression.ANNOYED, "They won't listen to me! They say I'm not properly equipped to go in the house, though I do have a very effective gas mask.").also { stage++ } + // npcl does not work + NOT_LISTEN + 1 -> npc(FacialExpression.ANNOYED, + "Hmmm, well I guess they're not taking the issue of a", + "kidnapping seriously enough. They do go a bit far", + "sometimes. I've heard of Elena, she has helped us a lot...", + "Ok, I'll give you this warrant to enter the house." + ).also { stage++ } + NOT_LISTEN + 2 -> { + if (freeSlots(player!!) == 0) { + sendItemDialogue(player!!, Items.WARRANT_1503, "Bravek waves a warrant at you, but you don't have room to take it.").also { stage = END_DIALOGUE } + } else { + sendItemDialogue(player!!, Items.WARRANT_1503, "Bravek hands you a warrant.").also { stage = END_DIALOGUE } + addItem(player!!, Items.WARRANT_1503) + setQuestStage(player!!, Quests.PLAGUE_CITY, 16) + } + } + + CURED -> playerl(FacialExpression.FRIENDLY, "Not a problem, happy to help out.").also { stage++ } + CURED + 1 -> npcl(FacialExpression.FRIENDLY, " I'm just having a little drop of whisky, then I'll feel really good.").also { stage = END_DIALOGUE } + } + return true + } + + override fun getIds(): IntArray = intArrayOf(NPCs.BRAVEK_711) +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/ClerkDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/ClerkDialogue.kt new file mode 100644 index 0000000..639cd0a --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/ClerkDialogue.kt @@ -0,0 +1,98 @@ +package content.region.kandarin.ardougne.quest.plaguecity.dialogue + +import content.data.Quests +import core.api.getQuestStage +import core.api.setQuestStage +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.IfTopic +import core.game.dialogue.Topic +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class ClerkDialogue(player: Player? = null) : DialoguePlugin(player) { + + companion object{ + const val TALK_AGAIN = 10 + + const val THROUGH_DOOR = 20 + const val PERMISSION = 30 + const val QUESTIONS = 40 + const val URGENT = 60 + const val RUN_EVERYTHING = 70 + const val WHEN_AVAILABLE = 80 + const val DISTURBED = 90 + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + if (getQuestStage(player, Quests.PLAGUE_CITY) < 13) + npcl(FacialExpression.NEUTRAL, "Hello, welcome to the Civic Office of West Ardougne. How can I help you?").also { stage = QUESTIONS } + else + npcl(FacialExpression.FRIENDLY, "Bravek will see you now but keep it short!").also { stage = TALK_AGAIN } + + return true + } + + override fun handle(componentID: Int, buttonID: Int): Boolean { + + when(stage){ + + QUESTIONS -> showTopics( + IfTopic("I need permission to enter a plague house.", PERMISSION, getQuestStage(player, Quests.PLAGUE_CITY) > 11), + Topic("Who is through that door?", THROUGH_DOOR), + Topic("I'm just looking thanks.", END_DIALOGUE), + ) + + // npcl does not wordwrap right + PERMISSION -> npc(FacialExpression.NEUTRAL, "Rather you than me! The mourners normally deal with", + "that stuff, you should speak to them. Their headquarters","are right near the city gate.").also { stage++ } + PERMISSION + 1 -> showTopics( + Topic("I'll try asking them then.", END_DIALOGUE), + Topic("Surely you don't let them run everything for you?", RUN_EVERYTHING), + Topic("This is urgent though!", URGENT, skipPlayer = true) + ) + + RUN_EVERYTHING -> npcl(FacialExpression.NEUTRAL, " Well, they do know what they're doing here. " + + "If they did start doing something badly Bravek, the city warder, would have the power to override them. " + + "I can't see that happening though.").also { stage++ } + RUN_EVERYTHING + 1 -> showTopics( + Topic("I'll try asking them then.", END_DIALOGUE), + Topic("Can I speak to Bravek anyway?", DISTURBED) + ) + + URGENT -> playerl(FacialExpression.PANICKED, " This is urgent though! Someone's been kidnapped and is being held in a plague house!").also { stage++ } + URGENT+ 1 -> npcl(FacialExpression.NEUTRAL, "I'll see what I can do I suppose.").also { stage++ } + URGENT + 2 -> npcl(FacialExpression.NEUTRAL, " Mr Bravek, there's a ${if (player.isMale) "man" else "lady"} here who really needs to speak to you.").also { + stage++ + npc = NPC(NPCs.BRAVEK_711) + } + URGENT + 3 -> npc(FacialExpression.ANNOYED, " I suppose they can come in then. If they keep it short.").also { + stage = END_DIALOGUE + setQuestStage(player, Quests.PLAGUE_CITY, 13) + } + + THROUGH_DOOR -> npcl(FacialExpression.NEUTRAL, "The city warder Bravek is in there.").also { stage++ } + THROUGH_DOOR + 1 -> playerl(FacialExpression.ASKING, " Can I go in?").also { stage = DISTURBED } + + DISTURBED -> npcl(FacialExpression.NEUTRAL, " He has asked not to be disturbed.").also { stage++ } + DISTURBED + 1 -> showTopics( + IfTopic("This is urgent though!", URGENT, getQuestStage(player, Quests.PLAGUE_CITY) > 11, skipPlayer = true), + Topic("Ok, I'll leave him alone.", END_DIALOGUE), + Topic("Do you know when he will be available?", WHEN_AVAILABLE) + ) + + WHEN_AVAILABLE -> npcl(FacialExpression.NEUTRAL, " Oh I don't know, an hour or so maybe.").also { stage = END_DIALOGUE } + + TALK_AGAIN -> playerl(FacialExpression.FRIENDLY, "Thanks, I won't take much of his time.").also { stage = END_DIALOGUE } + } + + return true + } + + override fun getIds(): IntArray = intArrayOf(NPCs.CLERK_713) +} diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/EdmondDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/EdmondDialogue.kt new file mode 100644 index 0000000..8b88a5c --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/EdmondDialogue.kt @@ -0,0 +1,268 @@ +package content.region.kandarin.ardougne.quest.plaguecity.dialogue + +import content.data.Quests +import content.region.kandarin.ardougne.quest.plaguecity.PlagueCityListeners +import content.region.kandarin.ardougne.quest.plaguecity.UndergroundCutscene +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class EdmondDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + val questStage = getQuestStage(player, Quests.PLAGUE_CITY) + npc = args[0] as NPC + if(inEquipmentOrInventory(player, Items.GAS_MASK_1506) && (questStage == 2)) { + playerl(FacialExpression.FRIENDLY, "Hi Edmond, I've got the gas mask now.").also { stage++ } + } + else if (questStage == 4) { + // npcl not formatted quite right + npc(FacialExpression.FRIENDLY, "I think it's the pipe to the south that comes up in West", "Ardougne.").also { stage++ } + + } + else if(questStage == 5){ + playerl( FacialExpression.NEUTRAL, + "Edmond, I can't get through to West Ardougne! There's an iron grill blocking my way, I can't pull it off alone." + ).also { stage++ } + + } + else if(questStage == 6){ + // playerl not formatted quite right + player(FacialExpression.NEUTRAL, "I've tied a rope to the grill over there, will you help me","pull it off?").also { stage++ } + + } + else if(questStage > 2) { + playerl(FacialExpression.FRIENDLY, "Hello Edmond.").also { stage++ } + } + else { + playerl(FacialExpression.FRIENDLY, "Hello old man.").also { stage++ } + } + return true + } + + override fun handle(componentID: Int, buttonID: Int): Boolean { + when (getQuestStage(player!!, Quests.PLAGUE_CITY)) { + + 0 -> when (stage) { + 1 -> npcl(FacialExpression.NEUTRAL, "Sorry, I can't stop to talk...").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "Why, what's wrong?").also { stage++ } + 3 -> npcl( + FacialExpression.FRIENDLY, + "I've got to find my daughter. I pray that she is still alive..." + ).also { stage++ } + + 4 -> options("What's happened to her?", "Well, good luck finding her.").also { stage++ } + 5 -> when (buttonID) { + 1 -> playerl(FacialExpression.FRIENDLY, "What's happened to her?").also { stage = 6 } + 2 -> playerl(FacialExpression.FRIENDLY, "Well, good luck finding her.").also { + stage = END_DIALOGUE + } + } + // npcl does not word wrap correctly + 6 -> npc( + FacialExpression.NEUTRAL, + "Elena's a missionary and a healer. Three weeks ago she", + "managed to cross the Ardougne wall... No-one's allowed", + "to cross the wall in case they spread the plague. But", + "after hearing the screams of suffering she felt she had" + ).also { stage++ } + + 7 -> npcl( + FacialExpression.NEUTRAL, + "to help. She said she'd be gone for a few days but we've heard nothing since." + ).also { stage++ } + + 8 -> options( + "Tell me more about the plague.", + "Can I help find her?", + "I'm sorry, I have to go." + ).also { stage++ } + + 9 -> when (buttonID) { + 1 -> playerl(FacialExpression.FRIENDLY, "Tell me more about the plague.").also { stage = 10 } + 2 -> playerl(FacialExpression.FRIENDLY, "Can I help find her?").also { stage = 11 } + 3 -> playerl(FacialExpression.FRIENDLY, "I'm sorry, I have to go.").also { stage = END_DIALOGUE } + } + + 10 -> npcl( + FacialExpression.FRIENDLY, + "The mourners can tell you more than me. They're the only ones allowed to cross the border. I do know the plague is a horrible way to go... That's why Elena felt she had to go help." + ).also { stage = 8 } + + 11 -> npcl( + FacialExpression.FRIENDLY, + "Really, would you? I've been working on a plan to get into West Ardougne, but I'm too old and tired to carry it through. If you're going into West Ardougne you'll need protection from the plague. My wife made a" + ).also { stage++ } + + 12 -> npcl( + FacialExpression.FRIENDLY, + "special gas mask for Elena with dwellberries rubbed into it. Dwellberries help repel the virus! We need some more though..." + ).also { stage++ } + + 13 -> playerl(FacialExpression.ASKING, "Where can I find these dwellberries?").also { stage++ } + 14 -> npcl( + FacialExpression.FRIENDLY, + "The only place I know of is McGrubor's Wood just north of the Rangers' Guild." + ).also { stage++ } + + 15 -> playerl(FacialExpression.FRIENDLY, "Ok, I'll go and get some.").also { stage++ } + 16 -> npcl( + FacialExpression.NEUTRAL, + "The foresters keep a close eye on it, but there is a back way in." + ).also { stage++ } + + 17 -> { + end() + setQuestStage(player!!, Quests.PLAGUE_CITY, 1) + } + } + + 1 -> when (stage) { + 1 -> npcl(FacialExpression.NEUTRAL, "Have you got the dwellberries yet?").also { stage++ } + 2 -> if (!inInventory(player, Items.DWELLBERRIES_2126)) { + playerl(FacialExpression.FRIENDLY, "Sorry, I'm afraid not.").also { stage = 3 } + } else { + playerl(FacialExpression.FRIENDLY, "Yes I've got some here.").also { stage = 6 } + } + + 3 -> npcl( + FacialExpression.NEUTRAL, + "You'll probably find them in McGrubor's Wood it's just west of Seers village." + ).also { stage++ } + + 4 -> playerl(FacialExpression.NEUTRAL, "Ok, I'll go and get some.").also { stage++ } + 5 -> npcl( + FacialExpression.NEUTRAL, + "The foresters keep a close eye on it, but there is a back way in." + ).also { stage = END_DIALOGUE } + + 6 -> npcl(FacialExpression.NEUTRAL, "Take them to my wife Alrena, she's inside.").also { + stage = END_DIALOGUE + } + } + + 2 -> when (stage) { + // npcl formats this wrong + 1 -> npc( + FacialExpression.NEUTRAL, + "Good stuff, now for the digging. Beneath us are the", + "Ardougne sewers, there you'll find", + "access to West Ardougne." + ).also { stage++ } + + 2 -> npc( + FacialExpression.NEUTRAL, "The problem is the soil is rock hard. You'll need to pour", + "on several buckets of water to soften it up. I'll keep an", + "eye out for the mourners." + ).also { stage++ } + + 3 -> { + end() + setQuestStage(player!!, Quests.PLAGUE_CITY, 3) + } + } + + 3 -> when (stage) { + 1 -> if (player!!.getAttribute("/save:elena:dig", false) == true) { + playerl(FacialExpression.NEUTRAL, "I've soaked the soil with water.").also { stage = 3 } + } else { + npcl(FacialExpression.FRIENDLY, "How's it going?").also { stage = 2 } + } + + 2 -> if (player.getAttribute(PlagueCityListeners.BUCKET_USES_ATTRIBUTE, 0) == 1) { + playerl( + FacialExpression.NEUTRAL, + "I still need to pour three more buckets of water on the soil." + ).also { stage = END_DIALOGUE } + } else if (player.getAttribute(PlagueCityListeners.BUCKET_USES_ATTRIBUTE, 0) == 2) { + playerl( + FacialExpression.NEUTRAL, + "I still need to pour two more buckets of water on the soil." + ).also { stage = END_DIALOGUE } + } else if (player.getAttribute(PlagueCityListeners.BUCKET_USES_ATTRIBUTE, 0) == 3) { + playerl( + FacialExpression.NEUTRAL, + "I still need to pour one more bucket of water on the soil." + ).also { stage = END_DIALOGUE } + } + + 3 -> npcl( + FacialExpression.FRIENDLY, + "That's great, it should be soft enough to dig through now." + ).also { stage = END_DIALOGUE } + } + + 4 -> when (stage) { + 1 -> playerl(FacialExpression.NEUTRAL, "Alright I'll check it out.").also { stage = END_DIALOGUE } + } + + 5 -> when (stage) { + 1 -> npcl( + FacialExpression.NEUTRAL, + "If you get some rope you could tie to the grill, then we could both pull it at the same time." + ).also { stage = END_DIALOGUE } + } + + 6 -> when(stage){ + 1 -> npcl(FacialExpression.NEUTRAL, "Alright, let's get to it...").also { stage++ } + 2 -> end().also{ UndergroundCutscene(player!!).start() } + } + 7-> when (stage) { + 1 -> npcl(FacialExpression.NEUTRAL, "Have you found Elena yet?").also { stage++ } + 2 -> playerl(FacialExpression.NEUTRAL, "Not yet, it's a big city over there.").also { stage++ } + 3 -> npcl(FacialExpression.FRIENDLY, "Don't forget to look for my friend Jethick. He may be able to help.").also { stage = END_DIALOGUE } + } + + 8 -> when (stage) { + 1 -> npcl(FacialExpression.NEUTRAL, "Have you found Elena yet?").also { stage++ } + 2 -> playerl(FacialExpression.NEUTRAL, "Not yet, it's a big city over there. Do you have a picture of Elena?").also { stage++ } + 3 -> npcl(FacialExpression.FRIENDLY, "There should be a picture of Elena in the house. Please find her quickly, I hope it's not too late.").also { stage = END_DIALOGUE } + } + + // No source for this branch + in 9..98 -> when(stage) { + 1 -> npcl(FacialExpression.NEUTRAL, "Have you found Elena yet?").also { stage++ } + 2 -> playerl(FacialExpression.SAD, "Not yet.").also { stage++ } + 3 -> npcl(FacialExpression.WORRIED, "Please find her quickly, I hope it's not too late.").also { stage = END_DIALOGUE } + } + + 99 -> when (stage) { + 1 -> npcl(FacialExpression.NEUTRAL, "Thank you, thank you! Elena beat you back by minutes.").also { stage++ } + 2 -> npcl(FacialExpression.NEUTRAL, "Now I said I'd give you a reward. What can I give you as a reward I wonder?").also { stage++ } + 3 -> npcl(FacialExpression.NEUTRAL, "Here take this magic scroll, I have little use for it but it may help you.").also { stage++ } + 4 -> { + end() + player!!.questRepository.getQuest(Quests.PLAGUE_CITY).finish(player) + } + } + + 100 -> when (stage) { + 1 -> npcl(FacialExpression.FRIENDLY, "Ah hello again, and thank you again for rescuing my daughter.").also { + stage = if ( + getAttribute(player, PlagueCityListeners.ARDOUGNE_TELE_ATTRIBUTE, false) + || hasAnItem(player, Items.A_MAGIC_SCROLL_1505).exists()) 5 else 2 + } + 2 -> showTopics( + Topic("Do you have any more of those scrolls?", 3), + Topic("No problem.", END_DIALOGUE) + ) + 3 -> npcl(FacialExpression.FRIENDLY, "Here take this magic scroll, I have little use for it but it may help you.").also { + stage = END_DIALOGUE + addItemOrDrop(player!!, Items.A_MAGIC_SCROLL_1505) + } + 5 -> playerl(FacialExpression.NEUTRAL, "No problem.").also { stage = END_DIALOGUE } + } + } + return true + } + + override fun getIds(): IntArray = intArrayOf(NPCs.EDMOND_3213, NPCs.TUNNEL_EDMOND_3214) +} diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/JethickDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/JethickDialogue.kt new file mode 100644 index 0000000..4ab027d --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/JethickDialogue.kt @@ -0,0 +1,87 @@ +package content.region.kandarin.ardougne.quest.plaguecity.dialogue + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class JethickDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + if (player.questRepository.getStage(Quests.PLAGUE_CITY) in 0..11) { + npcl(FacialExpression.FRIENDLY, "Hello I don't recognise you. We don't get many newcomers around here.").also { stage++ } + } else if (player.questRepository.getStage(Quests.PLAGUE_CITY) >= 12) { + npcl(FacialExpression.FRIENDLY,"Hello. We don't get many newcomers around here.").also { stage = END_DIALOGUE } + } + return true + } + + override fun handle(componentID: Int, buttonID: Int): Boolean { + when (getQuestStage(player!!, Quests.PLAGUE_CITY)) { + + in 0..1 -> when (stage) { + 1 -> npcl(FacialExpression.FRIENDLY, "Well King Tyras has wandered off into the west kingdom. He doesn't care about the mess he's left here. The city warder Bravek is in charge at the moment... He's not much better.").also { stage = END_DIALOGUE } + } + + in 7..9 -> when (stage) { + 1 -> options("Hi, I'm looking for a woman from East Ardougne.", "So who's in charge here?").also { stage++ } + 2 -> when (buttonID) { + // This line is authentically different than the question you click + 1 -> playerl(FacialExpression.FRIENDLY, "Hi, I'm looking for a woman from East Ardougne called Elena.").also { stage = 3 } + 2 -> playerl(FacialExpression.FRIENDLY, "So who's in charge here?").also { stage = END_DIALOGUE } + } + // word wrap is wrong with npcl + 3 -> npc(FacialExpression.FRIENDLY, "East Ardougnian women are easier to find in East", + "Ardougne. Not many would come to West Ardougne to", + "find one. Although the name is familiar, what does she", + "look like?").also { stage++ } + 4 -> if (inInventory(player!!, Items.PICTURE_1510)) { + sendItemDialogue(player!!, Items.PICTURE_1510, "You show Jethick the picture.").also { stage = 7 } + } else { + playerl(FacialExpression.NEUTRAL, "Um... brown hair... in her twenties...").also { stage++ } + } + 5 -> npcl(FacialExpression.NEUTRAL, "Hmm, that doesn't narrow it down a huge amount... I'll need to know more than that, or see a picture?").also { stage = END_DIALOGUE } + + // npcl doesn't wrap right + 7 -> npc(FacialExpression.FRIENDLY, "She came over here to help to aid plague victims. I", + "think she is staying over with the Rehnison family. They", + "live in the small timbered building at the far north side", + "of town. I've not seen her around here in a while,").also { stage++ } + 8 -> npcl(FacialExpression.FRIENDLY, "mind. ").also { stage++ } + 9 -> npcl(FacialExpression.FRIENDLY, "I don't suppose you could run me a little errand while you're over there? I borrowed this book from them, can you return it?").also { stage++ } + 10 -> options("Yes, I'll return it for you.", "No, I don't have time for that.").also { stage++ } + 11 -> when (buttonID) { + 1 -> playerl(FacialExpression.NEUTRAL, "Yes, I'll return it for you.").also { stage = 12 } + 2 -> playerl(FacialExpression.NEUTRAL, "No, I don't have time for that.").also { stage = END_DIALOGUE } + } + 12 -> if(freeSlots(player) == 0) { + end() + sendItemDialogue(player!!, Items.BOOK_1509, "Jethick shows you the book, but you don't have room to take it.") + stage = END_DIALOGUE + } else { + end() + sendItemDialogue(player!!, Items.BOOK_1509, "Jethick gives you a book.") + addItem(player!!, Items.BOOK_1509) + stage = END_DIALOGUE + } + } + + in 10..11 -> when (stage) { + 1 -> playerl(FacialExpression.FRIENDLY, "I'm looking for a woman from East Ardougne called Elena.").also { stage++ } + 2 -> npcl(FacialExpression.FRIENDLY,"Ah yes. She came over here to help the plague victims. I think she is staying over with the Rehnison family.").also { stage++ } + 3 -> npcl(FacialExpression.FRIENDLY, "They live in the small timbered building at the far north side of town. I've not seen her around here in a while, mind.").also { stage = END_DIALOGUE } + } + } + return true + } + + override fun getIds(): IntArray = intArrayOf(NPCs.JETHICK_725) +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/KidnappedElenaDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/KidnappedElenaDialogue.kt new file mode 100644 index 0000000..2fe574b --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/KidnappedElenaDialogue.kt @@ -0,0 +1,45 @@ +package content.region.kandarin.ardougne.quest.plaguecity.dialogue + +import content.data.Quests +import core.api.setQuestStage +import core.api.setVarbit +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs +import org.rs09.consts.Vars + +@Initializable +class KidnappedElenaDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + if (player.questRepository.getStage(Quests.PLAGUE_CITY) >= 16) { + playerl(FacialExpression.FRIENDLY, "Hi, you're free to go! Your kidnappers don't seem to be about right now.").also { stage = 1 } + } else { + npcl(FacialExpression.FRIENDLY, "Go and see my father, I'll make sure he adequately rewards you. Now I'd better leave while I still can.").also { stage = END_DIALOGUE } + } + return true + } + + override fun handle(componentID: Int, buttonID: Int): Boolean { + when (stage) { + 1 -> npcl(FacialExpression.FRIENDLY, "Thank you, being kidnapped was so inconvenient. I was on my way back to East Ardougne with some samples, I want to see if I can diagnose a cure for this plague.").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "Well you can leave via the manhole near the gate.").also { stage++ } + 3 -> npcl(FacialExpression.FRIENDLY, "Go and see my father, I'll make sure he adequately rewards you. Now I'd better leave while I still can.").also { stage++ } + 4 -> { + end() + setQuestStage(player!!, Quests.PLAGUE_CITY, 99) + setVarbit(player, Vars.VARBIT_QUEST_PLAGUE_CITY_RESCUE_ELENA, 1) + setVarbit(player, Vars.VARBIT_QUEST_PLAGUE_CITY_EDMOND_TUNNELS, 0) + stage = END_DIALOGUE + } + } + return true + } + + override fun getIds(): IntArray = intArrayOf(NPCs.KIDNAPPED_ELENA_715) +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/MarthaRehnisonDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/MarthaRehnisonDialogue.kt new file mode 100644 index 0000000..4b2aa05 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/MarthaRehnisonDialogue.kt @@ -0,0 +1,48 @@ +package content.region.kandarin.ardougne.quest.plaguecity.dialogue + +import content.data.Quests +import core.api.getQuestStage +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class MarthaRehnisonDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + if (player.questRepository.getStage(Quests.PLAGUE_CITY) == 9) { + playerl(FacialExpression.NEUTRAL, "Hi, I hear a woman called Elena is staying here.").also { stage++ } + } else { + npcl(FacialExpression.FRIENDLY, "Any luck finding Elena yet?").also { stage++ } + } + return true + } + + override fun handle(componentID: Int, buttonID: Int): Boolean { + when (getQuestStage(player!!, Quests.PLAGUE_CITY)) { + + 9 -> when (stage) { + 1 -> npcl(FacialExpression.FRIENDLY, "Yes she was staying here, but slightly over a week ago she was getting ready to go back.").also { stage++ } + 2 -> npcl(FacialExpression.FRIENDLY, "However she never managed to leave. My daughter Milli was playing near the west wall when she saw some shadowy figures jump out and grab her. Milli is upstairs if you wish to speak to her.").also { stage = END_DIALOGUE } + } + + in 10..98 -> when (stage) { + 1 -> playerl(FacialExpression.FRIENDLY, "Not yet...").also { stage++ } + 2 -> npcl(FacialExpression.FRIENDLY, "I wish you luck, she did a lot for us.").also { stage = END_DIALOGUE } + } + + in 99..100 -> when (stage) { + 1 -> playerl(FacialExpression.FRIENDLY, "Yes, she is safe at home now.").also { stage++ } + 2 -> npcl(FacialExpression.FRIENDLY, "That's good to hear, she helped us a lot.").also { stage = END_DIALOGUE } + } + } + return true + } + + override fun getIds(): IntArray = intArrayOf(NPCs.MARTHA_REHNISON_722) +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/MilliRehnisonDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/MilliRehnisonDialogue.kt new file mode 100644 index 0000000..3f5fe54 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/MilliRehnisonDialogue.kt @@ -0,0 +1,57 @@ +package content.region.kandarin.ardougne.quest.plaguecity.dialogue + +import content.data.Quests +import core.api.getQuestStage +import core.api.setQuestStage +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class MilliRehnisonDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + if (player.questRepository.getStage(Quests.PLAGUE_CITY) == 9) { + playerl(FacialExpression.FRIENDLY, "Hello. Your parents say you saw what happened to Elena...").also { stage++ } + } else { + npcl(FacialExpression.CHILD_FRIENDLY, "Any luck finding Elena yet?").also { stage++ } + } + return true + } + + override fun handle(componentID: Int, buttonID: Int): Boolean { + when (getQuestStage(player!!, Quests.PLAGUE_CITY)) { + + 9 -> when(stage) { + // Wordwrap doesn't match using npcl + 1 -> npc(FacialExpression.CHILD_SAD, "*sniff* Yes I was near the south east corner when I", + "saw Elena walking by. I was about to run to greet her", + "when some men jumped out. They shoved a sack over", + "her head and dragged her into a building.").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "Which building?").also { stage++ } + 3 -> npcl(FacialExpression.CHILD_NORMAL, "It was the boarded up building with no windows in the south east corner of West Ardougne.").also { + stage = END_DIALOGUE + setQuestStage(player!!, Quests.PLAGUE_CITY, 11) + } + } + + in 10..98 -> when (stage) { + 1 -> playerl(FacialExpression.FRIENDLY, "Not yet...").also { stage++ } + 2 -> npcl(FacialExpression.CHILD_FRIENDLY, "I wish you luck, she did a lot for us.").also { stage = END_DIALOGUE } + } + + in 99..100 -> when (stage) { + 1 -> playerl(FacialExpression.FRIENDLY, "Yes, she is safe at home now.").also { stage++ } + 2 -> npcl(FacialExpression.CHILD_FRIENDLY, "That's good to hear, she helped us a lot.").also { stage = END_DIALOGUE } + } + } + return true + } + + override fun getIds(): IntArray = intArrayOf(NPCs.MILLI_REHNISON_724) +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/TedRehnisonDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/TedRehnisonDialogue.kt new file mode 100644 index 0000000..b26c60d --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/TedRehnisonDialogue.kt @@ -0,0 +1,51 @@ +package content.region.kandarin.ardougne.quest.plaguecity.dialogue + +import content.data.Quests +import core.api.getQuestStage +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class TedRehnisonDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + if (player.questRepository.getStage(Quests.PLAGUE_CITY) == 9) { + playerl(FacialExpression.NEUTRAL, "Hi, I hear a woman called Elena is staying here.").also { stage++ } + } else if (player.questRepository.getStage(Quests.PLAGUE_CITY) > 9) { + npcl(FacialExpression.FRIENDLY, "Any luck finding Elena yet?").also { stage++ } + } else { + npcl(FacialExpression.FRIENDLY, "Go away. We don't want any.").also { stage = END_DIALOGUE } + } + return true + } + + override fun handle(componentID: Int, buttonID: Int): Boolean { + when (getQuestStage(player!!, Quests.PLAGUE_CITY)) { + + 9 -> when (stage) { + 1 -> npcl(FacialExpression.FRIENDLY, "Yes she was staying here, but slightly over a week ago she was getting ready to go back. However she never managed to leave. My daughter Milli was playing near the west wall when she saw some shadowy figures jump").also { stage++ } + 2 -> npc(FacialExpression.FRIENDLY, "out and grab her. Milli is upstairs if you wish to speak", "to her.").also { stage = END_DIALOGUE } + } + + in 10..98 -> when (stage) { + 1 -> playerl(FacialExpression.FRIENDLY, "Not yet...").also { stage++ } + 2 -> npcl(FacialExpression.FRIENDLY, "I wish you luck, she did a lot for us.").also { stage = END_DIALOGUE } + } + + in 99..100 -> when (stage) { + 1 -> playerl(FacialExpression.FRIENDLY, "Yes, she is safe at home now.").also { stage++ } + 2 -> npcl(FacialExpression.FRIENDLY, "That's good to hear, she helped us a lot.").also { stage = END_DIALOGUE } + } + } + return true + } + + override fun getIds(): IntArray = intArrayOf(NPCs.TED_REHNISON_721) + +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/mourners/MournerArdougneWallDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/mourners/MournerArdougneWallDialogue.kt new file mode 100644 index 0000000..83b1c9d --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/mourners/MournerArdougneWallDialogue.kt @@ -0,0 +1,61 @@ +package content.region.kandarin.ardougne.quest.plaguecity.dialogue.mourners + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +/** + * This is the Mourner patrolling close to the wall in E Ardougne + */ +@Initializable +class MournerArdougneWallDialogue(player: Player? = null) : DialoguePlugin(player){ + + companion object{ + const val START_DIALOGUE = 0 + const val PLAGUE = 20 + const val SYMPTOMS = 40 + } + + override fun open(vararg args: Any?): Boolean { + playerl(FacialExpression.NEUTRAL, "Hi.").also { stage = START_DIALOGUE } + return true + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + START_DIALOGUE -> npcl(FacialExpression.NEUTRAL, " What are you up to?").also { stage++ } + START_DIALOGUE + 1 -> playerl(FacialExpression.NEUTRAL, " Just sight-seeing.").also { stage++ } + START_DIALOGUE + 2 -> npcl(FacialExpression.NEUTRAL, "This is no place for sight-seeing. Don't you know there's been a plague outbreak?").also { stage++ } + START_DIALOGUE + 3 -> playerl(FacialExpression.NEUTRAL, " Yes, I had heard.").also { stage++ } + START_DIALOGUE + 4 -> npcl(FacialExpression.NEUTRAL, " Then I suggest you leave as soon as you can.").also { stage++ } + START_DIALOGUE + 5 -> showTopics( + Topic("What brought the plague to Ardougne?", PLAGUE), + Topic("What are the symptoms of the plague?", SYMPTOMS), + Topic("Thanks for the advice.", END_DIALOGUE), + ) + + PLAGUE -> npcl(FacialExpression.NEUTRAL, " It's all down to King Tyras of West Ardougne. " + + "'Rather than protecting his people he spends his time in the lands to the West. ").also { stage++ } + PLAGUE + 1 -> npcl(FacialExpression.NEUTRAL, "When he returned last he brought the plague with him then left before the problem became serious.").also { stage++ } + PLAGUE + 2 -> playerl(FacialExpression.ASKING, " Does he know how bad the situation is now?").also { stage++ } + PLAGUE + 3 -> npcl(FacialExpression.ANGRY, " If he did he wouldn't care. I believe he wants his people to suffer, he's an evil man.").also { stage++ } + PLAGUE + 4 -> playerl(FacialExpression.EXTREMELY_SHOCKED, " Isn't that treason?").also { stage++ } + PLAGUE + 5 -> npcl(FacialExpression.DISGUSTED_HEAD_SHAKE, " He's not my king.").also { stage = END_DIALOGUE } + + SYMPTOMS -> npcl(FacialExpression.NEUTRAL, "The first signs are typical flu symptoms. These tend to be followed by severe nightmares, horrifying hallucinations which drive many to madness.").also { stage++ } + SYMPTOMS + 1 -> playerl(FacialExpression.DISGUSTED, "Sounds nasty.").also { stage++ } + SYMPTOMS + 2 -> npcl(FacialExpression.NEUTRAL, " It gets worse. Next the victim's blood changes into a thick black tar-like liquid, at this point they're past help.").also { stage++ } + SYMPTOMS + 3 -> npcl(FacialExpression.NEUTRAL, "Their skin is cold to the touch, the victim is now brain dead. Their body however lives on driven by the virus, roaming like a zombie, spreading itself further wherever possible.").also { stage++ } + SYMPTOMS + 4 -> playerl(FacialExpression.DISGUSTED_HEAD_SHAKE, " I think I've heard enough.").also { stage = END_DIALOGUE } + + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.MOURNER_719) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/mourners/MournerEdmondHouseDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/mourners/MournerEdmondHouseDialogue.kt new file mode 100644 index 0000000..97d62f0 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/mourners/MournerEdmondHouseDialogue.kt @@ -0,0 +1,115 @@ +package content.region.kandarin.ardougne.quest.plaguecity.dialogue.mourners + +import content.data.Quests +import core.api.getQuestStage +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +/** + * This is for the mourner wandering around Edmonds house + */ + +@Initializable +class MournerEdmondHouseDialogue(player: Player? = null) : DialoguePlugin(player){ + + companion object { + const val BEFORE_PLAGUE_CITY = 10 + const val BEFORE_GAS_MASK = 20 + const val BEFORE_SOFTEN_GROUND = 30 + const val SYMPTOMS1 = 40 + const val FEEL_FINE = 50 + const val PLAGUE_SOURCE1 = 60 + const val BEFORE_DIG = 70 + const val AFTER_DIG = 80 + const val AFTER_ENTER_W_ARDOUGNE = 90 + } + + override fun open(vararg args: Any?): Boolean { + when (getQuestStage(player, Quests.PLAGUE_CITY)){ + 0 -> playerl(FacialExpression.NEUTRAL, "Hello there.").also { stage = BEFORE_PLAGUE_CITY } + 1 -> playerl(FacialExpression.NEUTRAL, "Hello.").also { stage = BEFORE_GAS_MASK } + 2 -> playerl(FacialExpression.NEUTRAL, "Hello.").also { stage = BEFORE_SOFTEN_GROUND } + 3 -> playerl(FacialExpression.NEUTRAL, "Hello.").also { stage = BEFORE_DIG } + 4 -> playerl(FacialExpression.NEUTRAL, "Hello there.").also { stage = AFTER_DIG } + else -> playerl(FacialExpression.NEUTRAL, "Hello.").also { stage = AFTER_ENTER_W_ARDOUGNE } + } + return true + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + BEFORE_PLAGUE_CITY -> npcl(FacialExpression.NEUTRAL, "Do you have a problem traveller?").also { stage++ } + BEFORE_PLAGUE_CITY + 1 -> playerl(FacialExpression.ASKING, "No, I just wondered why you're wearing that outfit... Is it fancy dress?").also { stage++ } + BEFORE_PLAGUE_CITY + 2 -> npcl(FacialExpression.NEUTRAL, "No! It's for protection.").also { stage++ } + BEFORE_PLAGUE_CITY + 3 -> playerl(FacialExpression.ASKING, "Protection from what?").also { stage++ } + BEFORE_PLAGUE_CITY + 4 -> npcl(FacialExpression.NEUTRAL, "The plague of course...").also { stage = END_DIALOGUE } + + BEFORE_GAS_MASK -> npcl(FacialExpression.NEUTRAL, "What do you want?").also { stage++ } + BEFORE_GAS_MASK + 1 -> showTopics( + Topic("Who are you?", BEFORE_GAS_MASK + 3), + Topic("Nothing, just being polite.", BEFORE_GAS_MASK + 2) + ) + BEFORE_GAS_MASK + 2 -> npcl(FacialExpression.NEUTRAL, "Hmmm, ok then. Be on your way.").also { stage = END_DIALOGUE } + BEFORE_GAS_MASK + 3 -> npcl(FacialExpression.NEUTRAL, "I'm a mourner. It's my job to help heal the plague victims of West Ardougne and to make sure the disease is contained.").also { stage++ } + BEFORE_GAS_MASK + 4 -> playerl(FacialExpression.THINKING, "Very noble of you.").also { stage++ } + BEFORE_GAS_MASK + 5 -> npcl(FacialExpression.NEUTRAL, "If you come down with any symptoms such as flu or nightmares let me know immediately.").also { stage = END_DIALOGUE } + + BEFORE_SOFTEN_GROUND -> npcl(FacialExpression.NEUTRAL, "Are you ok?").also { stage++ } + BEFORE_SOFTEN_GROUND + 1 -> playerl(FacialExpression.NEUTRAL, "Yes, I'm fine thanks.").also { stage++ } + BEFORE_SOFTEN_GROUND + 2 -> npcl(FacialExpression.NEUTRAL, "Have you experienced any plague symptoms?").also { stage++ } + BEFORE_SOFTEN_GROUND + 3 -> showTopics( + Topic("What are the symptoms?", SYMPTOMS1), + Topic("No, I feel fine", FEEL_FINE), + Topic("No, but can you tell me where the plague came from?", PLAGUE_SOURCE1) + ) + + SYMPTOMS1 -> npcl(FacialExpression.NEUTRAL, "First you'll come down with heavy flu, this is usually followed by horrifying nightmares.").also { stage++ } + SYMPTOMS1 + 1 -> playerl(FacialExpression.HALF_WORRIED, "I used to have nightmares when I was younger.").also { stage++ } + SYMPTOMS1 + 2 -> npcl(FacialExpression.NEUTRAL, "Not like these I assure you. Soon after a thick black liquid will seep from your nose and eyes.").also { stage++ } + SYMPTOMS1 + 3 -> playerl(FacialExpression.HALF_WORRIED, "Yuck!").also { stage++ } + SYMPTOMS1 + 4 -> npcl(FacialExpression.HALF_WORRIED, "When it gets to that stage there's nothing we can do for you.").also { stage = END_DIALOGUE } + + FEEL_FINE -> npcl(FacialExpression.NEUTRAL, "Well if you take a turn for the worse let me know straight away.").also { stage++ } + FEEL_FINE + 1 -> playerl(FacialExpression.HALF_WORRIED, "Can you cure it then?").also { stage++ } + FEEL_FINE + 2 -> npcl(FacialExpression.NEUTRAL, "No... But you will have to be treated.").also { stage++ } + FEEL_FINE + 3 -> playerl(FacialExpression.WORRIED, "Treated?").also { stage++ } + FEEL_FINE + 4 -> npcl(FacialExpression.NEUTRAL, "We have to take measures to contain the disease. " + + "That's why you must let us know immediately if you take a turn for the worse.").also { stage = END_DIALOGUE } + + PLAGUE_SOURCE1 -> npcl(FacialExpression.NEUTRAL, "It all started when King Tyras of West Ardougne came back from one of his visits to the lands west of here.").also { stage++ } + PLAGUE_SOURCE1 + 1 -> npcl(FacialExpression.NEUTRAL, "Some of his men must have unknowingly caught it out there and brought it back with them").also { stage = END_DIALOGUE } + + BEFORE_DIG -> npcl(FacialExpression.ASKING, "What are you up to with old man Edmond?").also { stage++ } + BEFORE_DIG + 1 -> playerl(FacialExpression.HALF_GUILTY, "Nothing, we've just been chatting.").also { stage++ } + BEFORE_DIG + 2 -> npcl(FacialExpression.ASKING, "What about his daughter?").also { stage++ } + BEFORE_DIG + 3 -> playerl(FacialExpression.HALF_GUILTY, "Oh, you know about that then?").also { stage++ } + BEFORE_DIG + 4 -> npcl(FacialExpression.NEUTRAL, "We know about everything that goes on in Ardougne. We have to if we are to contain the plague.").also { stage++ } + BEFORE_DIG + 5 -> playerl(FacialExpression.HALF_ASKING, "Have you see his daughter recently?").also { stage++ } + BEFORE_DIG + 6 -> npcl(FacialExpression.NEUTRAL, "I imagine she's caught the plague. Either way she won't be allowed out of West Ardougne, the risk is too great.").also { stage = END_DIALOGUE } + + AFTER_DIG -> npcl(FacialExpression.ASKING, "Been digging have we?").also { stage++ } + AFTER_DIG + 1 -> playerl(FacialExpression.HALF_GUILTY, "What do you mean?").also { stage++ } + AFTER_DIG + 2 -> npcl(FacialExpression.NEUTRAL, "Your hands are covered in mud.").also { stage++ } + AFTER_DIG + 3 -> playerl(FacialExpression.HALF_GUILTY, "Oh that...").also { stage++ } + AFTER_DIG + 4 -> npcl(FacialExpression.THINKING, "Funny, you don't look like the gardening type.").also { stage++ } + AFTER_DIG + 5 -> playerl(FacialExpression.NEUTRAL, "Oh no, I love gardening! It's my favorite pastime.").also { stage = END_DIALOGUE } + + AFTER_ENTER_W_ARDOUGNE -> npcl(FacialExpression.ASKING, " What are you up to?").also { stage++ } + AFTER_ENTER_W_ARDOUGNE + 1 -> playerl(FacialExpression.HALF_GUILTY, "Nothing.").also { stage++ } + AFTER_ENTER_W_ARDOUGNE + 2 -> npcl(FacialExpression.SUSPICIOUS, "I don't trust you.").also { stage++ } + AFTER_ENTER_W_ARDOUGNE + 3 -> playerl(FacialExpression.NEUTRAL, "You don't have to.").also { stage++ } + AFTER_ENTER_W_ARDOUGNE + 4 -> npcl(FacialExpression.SUSPICIOUS, "If I find you attempting to cross the wall I'll make sure you never return.").also { stage = END_DIALOGUE } + + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.MOURNER_718) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/mourners/MournerGuardDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/mourners/MournerGuardDialogue.kt new file mode 100644 index 0000000..529554c --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/mourners/MournerGuardDialogue.kt @@ -0,0 +1,93 @@ +package content.region.kandarin.ardougne.quest.plaguecity.dialogue.mourners + +import content.data.Quests +import core.api.getQuestStage +import core.api.setQuestStage +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class MournerGuardDialogue : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + npc = NPC(NPCs.MOURNER_717) + when (getQuestStage(player!!, Quests.PLAGUE_CITY)) { + + in 8..10 -> when (stage) { + 0 -> npcl(FacialExpression.FRIENDLY, "Hmmm, how did you get over here? You're not one of this rabble. Ah well, you'll have to stay. Can't risk you going back now.").also { stage++ } + 1 -> options("So what's a mourner?", "I haven't got the plague though...", "I'm looking for a woman named Elena.").also { stage++ } + 2 -> when (buttonID) { + 1 -> playerl(FacialExpression.FRIENDLY, "So what's a mourner?").also { stage = 3 } + 2 -> playerl(FacialExpression.FRIENDLY, "I haven't got the plague though...").also { stage = 6 } + 3 -> playerl(FacialExpression.FRIENDLY, "I'm looking for a woman named Elena.").also { stage = 7 } + } + 3 -> npcl(FacialExpression.NEUTRAL, "We're working for King Lathas of East Ardougne. He has tasked us with containing the accursed plague sweeping West Ardougne.").also { stage++ } + 4 -> npcl(FacialExpression.NEUTRAL, "We also do our best to ease these people's suffering. We're nicknamed mourners because we spend a lot of time at plague victim funerals, no one else is allowed to risk attending.").also { stage++ } + 5 -> npcl(FacialExpression.NEUTRAL, "It's a demanding job, and we get little thanks from the people here.").also { stage = 1 } + 6 -> npcl(FacialExpression.NEUTRAL, "Can't risk you being a carrier. That protective clothing you have isn't regulation issue. It won't meet safety standards.").also { stage = 1 } + 7 -> npcl(FacialExpression.NEUTRAL, "Ah yes, I've heard of her. A healer I believe. She must be mad coming over here voluntarily.").also { stage++ } + 8 -> npcl(FacialExpression.NEUTRAL, "I hear rumours she has probably caught the plague now. Very tragic, a stupid waste of life.").also { stage = END_DIALOGUE } + } + + 11 -> when (stage) { + 0 -> player!!.dialogueInterpreter.sendDialogue("The door won't open.", "You notice a black cross on the door.").also { stage++ } + 1 -> npcl(FacialExpression.NEUTRAL, "I'd stand away from there. That black cross means that house has been touched by the plague.").also { stage++ } + 2 -> options("But I think a kidnap victim is in here.", "I fear not a mere plague.", "Thanks for the warning.").also { stage++ } + 3 -> when (buttonID) { + 1 -> playerl(FacialExpression.FRIENDLY, "But I think a kidnap victim is in here.").also { stage = 5 } + 2 -> playerl(FacialExpression.FRIENDLY, "I fear not a mere plague.").also { stage = 5 } + 3 -> playerl(FacialExpression.FRIENDLY, "Thanks for the warning.").also { stage = 4 } + + } + 4 -> playerl(FacialExpression.FRIENDLY, "Thanks for the warning.").also { stage = END_DIALOGUE } + 5 -> npcl(FacialExpression.FRIENDLY, "That's irrelevant. You don't have clearance to go in there.").also { stage++ } + 6 -> playerl(FacialExpression.NEUTRAL, "How do I get clearance?").also { stage++ } + 7 -> npcl(FacialExpression.NEUTRAL, "Well you'd need to apply to the head mourner, or I suppose Bravek the city warder.").also { stage++ } + 8 -> npcl(FacialExpression.NEUTRAL, "I wouldn't get your hopes up though.").also { stage++ } + 9 -> { + end() + setQuestStage(player!!, Quests.PLAGUE_CITY, 12) + stage = END_DIALOGUE + } + } + + in 13..15 -> when (stage) { + 0 -> npcl(FacialExpression.FRIENDLY, "Hmmm, how did you get over here? You're not one of this rabble. Ah well, you'll have to stay. Can't risk you going back now.").also { stage++ } + 1 -> options("I need clearance to enter a plague house.", "So what's a mourner?", "I haven't got the plague though...", "I'm looking for a woman named Elena.").also { stage++ } + 2 -> when (buttonID) { + 1 -> playerl(FacialExpression.FRIENDLY, "I need clearance to enter a plague house. It's in the south east corner of West Ardougne.").also { stage = 9 } + 2 -> playerl(FacialExpression.FRIENDLY, "So what's a mourner?").also { stage = 3 } + 3 -> playerl(FacialExpression.FRIENDLY, "I haven't got the plague though...").also { stage = 6 } + 4 -> playerl(FacialExpression.FRIENDLY, "I'm looking for a woman named Elena.").also { stage = 7 } + } + 3 -> npcl(FacialExpression.NEUTRAL, "We're working for King Lathas of East Ardougne. He has tasked us with containing the accursed plague sweeping West Ardougne.").also { stage++ } + 4 -> npcl(FacialExpression.NEUTRAL, "We also do our best to ease these people's suffering. We're nicknamed mourners because we spend a lot of time at plague victim funerals, no one else is allowed to risk attending.").also { stage++ } + 5 -> npcl(FacialExpression.NEUTRAL, "It's a demanding job, and we get little thanks from the people here.").also { stage = 1 } + 6 -> npcl(FacialExpression.NEUTRAL, "Can't risk you being a carrier. That protective clothing you have isn't regulation issue. It won't meet safety standards.").also { stage = 1 } + 7 -> npcl(FacialExpression.NEUTRAL, "Ah yes, I've heard of her. A healer I believe. She must be mad coming over here voluntarily.").also { stage++ } + 8 -> npcl(FacialExpression.NEUTRAL, "I hear rumours she has probably caught the plague now. Very tragic, a stupid waste of life.").also { stage = END_DIALOGUE } + 9 -> npcl(FacialExpression.DISGUSTED, "You must be nuts, absolutely not!").also { stage++ } + 10 -> options("There's a kidnap victim inside!", "I've got a gas mask though...", "Yes, I'm utterly crazy.").also { stage++ } + 11 -> when (buttonID) { + 1 -> playerl(FacialExpression.FRIENDLY, "There's a kidnap victim inside!").also { stage = 12 } + 2 -> playerl(FacialExpression.FRIENDLY, "I've got a gas mask though...").also { stage = 13 } + 3 -> playerl(FacialExpression.FRIENDLY, "Yes, I'm utterly crazy.").also { stage = 17 } + } + 12 -> npcl(FacialExpression.FRIENDLY, "Well they're as good as dead then, no point in trying to save them.").also { stage = END_DIALOGUE } + 13 -> npcl(FacialExpression.FRIENDLY, "It's not regulation. Anyway you're not properly trained to deal with the plague.").also { stage++ } + 14 -> playerl(FacialExpression.FRIENDLY, "How do I get trained?").also { stage++ } + 15 -> npcl(FacialExpression.FRIENDLY, "It requires a strict 18 months of training.").also { stage++ } + 16 -> playerl(FacialExpression.FRIENDLY, "I don't have that sort of time.").also { stage = END_DIALOGUE } + 17 -> playerl(FacialExpression.FRIENDLY, "Yes, I'm utterly crazy.").also { stage++ } + 18 -> npcl(FacialExpression.FRIENDLY, "You're wasting my time, I have a lot of work to do!").also { stage = END_DIALOGUE } + } + + in 16..100 -> when (stage) { + 0 -> npcl(FacialExpression.FRIENDLY, "I'd stand away from there. That black cross means that house has been touched by the plague.").also { stage = END_DIALOGUE } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/mourners/MournerKidnapDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/mourners/MournerKidnapDialogue.kt new file mode 100644 index 0000000..671b7d3 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/plaguecity/dialogue/mourners/MournerKidnapDialogue.kt @@ -0,0 +1,184 @@ +package content.region.kandarin.ardougne.quest.plaguecity.dialogue.mourners + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.global.action.DoorActionHandler +import core.game.interaction.QueueStrength +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.game.world.map.RegionManager +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +/** + * These are the mourners guarding the kidnap building + */ +@Initializable +class MournerKidnapDialogue(player: Player? = null) :DialoguePlugin(player) { + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, MournerKidnapDialogueFile(), npc) + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.MOURNER_3216) + } +} + +/** + * Most of the work is in the dialogue file so the player can access this by trying to enter the room + */ +class MournerKidnapDialogueFile : DialogueFile(){ + + companion object { + const val KIDNAP = 10 + const val FEAR = 30 + const val CLEARANCE = 40 + + var closeMourner : NPC? = null + var farMourner : NPC? = null + + val eDoor: Location = Location.create(2540, 3273, 0) + val wDoor: Location = Location.create(2533, 3273, 0) + + var east = false + + } + override fun handle(componentID: Int, buttonID: Int) { + // Figure out who we are. It needs to be this since we can enter this dialogue from a door + // Do this for the first time regardless of where we are + if (stage == 0) { + RegionManager.getLocalNpcs(player!!, 2).forEach { + if (it.id == NPCs.MOURNER_3216) { + closeMourner = it + resetFace(closeMourner!!) + face(closeMourner!!, player!!) + face(player!!, closeMourner!!) + } + } + + east = player!!.location.x > 2537 + } + if (hasAnItem(player!!, Items.WARRANT_1503).exists()){ + when (stage){ + 0 -> npcl( + FacialExpression.NEUTRAL, + " I'd stand away from there. That black cross means that house has been touched by the plague." + ).also { stage++ } + + 1 -> playerl(FacialExpression.FRIENDLY, " I have a warrant from Bravek to enter here.").also { stage++ } + 2 -> npcl(FacialExpression.HALF_WORRIED, " This is highly irregular. Please wait...").also { stage++ } + 3 -> { + // Look further for the other one + RegionManager.getLocalNpcs(player!!, 10).forEach { + if (it.id == NPCs.MOURNER_3216 && it != closeMourner){ + farMourner = it + resetFace(farMourner!!) + } + } + + // I don't know why the queue has to be on this mourner to get both talking + val mournerQueue = if (east) farMourner else closeMourner + + queueScript(mournerQueue!!, 1, QueueStrength.WEAK) { animStage: Int -> + when(animStage){ + 0 -> { + end() + forceWalk(player!!, if (east) eDoor else wDoor, "smart") + face(closeMourner!!, farMourner!!) + // Legit typo + sendChat(closeMourner!!, "Hay... I got someone here with a warrant from Bravek, what should we do?") + // Immediately set the quest stage in case the player clicks again + if (getQuestStage(player!!, Quests.PLAGUE_CITY) < 17){ + setQuestStage(player!!, Quests.PLAGUE_CITY, 17) + } + return@queueScript delayScript(mournerQueue, 1) + } + 3 -> { + face(farMourner!!, closeMourner!! ) + sendChat(farMourner!!, "Well you can't let them in...") + return@queueScript delayScript(mournerQueue, 1) + } + 5 -> { + resetFace(player!!) + return@queueScript delayScript(mournerQueue, 1) + } + 6 -> { + // only walk the player if they have not walked themselves through + if (player!!.location.y > 3272) + DoorActionHandler.handleAutowalkDoor(player, getScenery (if (east) eDoor else wDoor)) + sendDialogue(player!!, "You wait until the mourner's back is turned and sneak into the building.").also { stage = END_DIALOGUE} + resetFace(closeMourner!!) + resetFace(farMourner!!) + return@queueScript delayScript(mournerQueue, 1) + } + 10 -> { + // Face north again + face(closeMourner!!, Location.create(closeMourner!!.location.x, 3275, 0)) + face(farMourner!!, Location.create(farMourner!!.location.x, 3275, 0)) + return@queueScript stopExecuting(mournerQueue) + } + } + return@queueScript delayScript(mournerQueue, 1) + } + + } + + } + } + else { + + when (stage) { + 0 -> npcl( + FacialExpression.NEUTRAL, + " I'd stand away from there. That black cross means that house has been touched by the plague." + ).also { stage = if (getQuestStage(player!!, Quests.PLAGUE_CITY) == 11) stage + 1 else END_DIALOGUE } + + 1 -> showTopics( + Topic("But I think a kidnap victim is in here.", KIDNAP), + Topic("I fear not a mere plague.", FEAR), + Topic("Thanks for the warning.", END_DIALOGUE), + ) + + KIDNAP -> npcl( + FacialExpression.NEUTRAL, + "Sounds unlikely, even kidnappers wouldn't go in there. Even if someone is in there, they're probably dead by now." + ).also { stage++ } + + KIDNAP + 1 -> showTopics( + Topic("Good point.", END_DIALOGUE), + Topic("I want to check anyway.", KIDNAP + 2) + ) + + KIDNAP + 2 -> npcl(FacialExpression.NEUTRAL, "You don't have clearance to go in there.").also { + stage = CLEARANCE + } + + FEAR -> npcl( + FacialExpression.NEUTRAL, + " That's irrelevant. You don't have clearance to go in there." + ).also { stage = CLEARANCE } + + CLEARANCE -> playerl(FacialExpression.ASKING, " How do I get clearance?").also { stage++ } + CLEARANCE + 1 -> npcl( + FacialExpression.NEUTRAL, + " Well you'd need to apply to the head mourner, or I suppose Bravek the city warder." + ).also { stage++ } + + CLEARANCE + 2 -> npcl(FacialExpression.NEUTRAL, " I wouldn't get your hopes up though.").also { + stage = END_DIALOGUE + setQuestStage(player!!, Quests.PLAGUE_CITY, 12) + } + } + } + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/sheepherder/GateInteractionHandler.java b/Server/src/main/content/region/kandarin/ardougne/quest/sheepherder/GateInteractionHandler.java new file mode 100644 index 0000000..af008a0 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/sheepherder/GateInteractionHandler.java @@ -0,0 +1,53 @@ +package content.region.kandarin.ardougne.quest.sheepherder; + +import core.game.interaction.DestinationFlag; +import core.game.interaction.MovementPulse; +import core.game.node.Node; +import core.game.node.entity.impl.PulseType; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.game.dialogue.FacialExpression; +import core.game.interaction.PluginInteraction; +import core.game.interaction.PluginInteractionManager; + + +@Initializable +public class GateInteractionHandler extends PluginInteraction { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + setIds(new int[]{167,166}); + PluginInteractionManager.register(this, PluginInteractionManager.InteractionType.OBJECT); + return this; + } + + @Override + public boolean handle(Player player, Node node) { + switch(node.getId()){ + case 167: + case 166: + return handleGate(player,node); + } + return false; + } + + public boolean handleGate(Player player, Node obj){ + if(!player.getEquipment().containsAll(SheepHerder.PLAGUE_BOTTOM.getId(),SheepHerder.PLAGUE_TOP.getId())) { + player.getPulseManager().run(new MovementPulse(player, DestinationFlag.OBJECT.getDestination(player, obj)) { + @Override + public boolean pulse() { + player.getDialogueInterpreter().sendDialogues(SheepHerder.FARMER_BRUMTY, FacialExpression.SUSPICIOUS, "You can't enter without your protective gear!", "Can't have you spreading the plague!"); + return true; + } + }, PulseType.STANDARD); + return true; + } + return false; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } +} diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/sheepherder/HalgriveDialogue.java b/Server/src/main/content/region/kandarin/ardougne/quest/sheepherder/HalgriveDialogue.java new file mode 100644 index 0000000..4f3dee3 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/sheepherder/HalgriveDialogue.java @@ -0,0 +1,183 @@ +package content.region.kandarin.ardougne.quest.sheepherder; + +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.game.dialogue.DialoguePlugin; +import core.api.*; +import org.rs09.consts.Items; +import content.data.Quests; + +@Initializable +public class HalgriveDialogue extends DialoguePlugin { + public HalgriveDialogue(){ + //empty + } + + public HalgriveDialogue(Player player){super(player);} + + @Override + public DialoguePlugin newInstance(Player player) { + return new HalgriveDialogue(player); + } + + @Override + public boolean open(Object... args) { + if(player.getQuestRepository().getStage(Quests.SHEEP_HERDER) < 10) { + player("Hello. How are you?"); + stage = 0; + return true; + } else { + npc("Have you managed to find and dispose of those four","plague-bearing sheep yet?"); + stage = 200; + return true; + } + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch(stage){ + case 0: + npc("I've been better."); + stage++; + break; + case 1: + options("What's wrong?","That's life for you."); + stage++; + break; + case 2: + switch(buttonId){ + case 1: + player("What's wrong?"); + stage = 10; + break; + case 2: + player("That's life for you."); + stage = 108; + break; + } + break; + case 10: + npc("You may or may not be aware, but a plague has","spread across Western Ardougne. Now, so far, our","efforts to contain it have been largely successful, for the","most part."); + stage++; + break; + case 11: + npc("However, four sheep recently escaped from a farm near","the city. When they were found, we noticed that they","were strangely discoloured, so we asked the mourners","to examine them."); + stage++; + break; + case 12: + npc("They found that the sheep had become infected with the","plague."); + stage++; + break; + case 13: + npc("As the councillor responsible for public health and safety","here in East Ardougne I am looking for someone to","herd these sheep into a safe enclosure, kill them quickly","and cleanly and then dispose of the remains hygienically"); + stage++; + break; + case 14: + npc("in a special incinerator."); + stage++; + break; + case 15: + npc("Unfortunately nobody wants to risk catching the plague,","and I am unable to find someone willing to undertake","this mission for me."); + stage++; + break; + case 16: + options("I can do that for you.","That's not a job for me."); + stage++; + break; + case 17: + switch(buttonId){ + case 1: + player("I can do that for you."); + stage = 100; + break; + case 2: + player("That's not a job for me."); + stage = 108; + break; + } + break; + case 100: + npc("Y-you will??? That is excellent news! Head to the","enclosure we have set up on Farmer Brumty's land to","the north of the city; the four infected sheep should still","be somewhere in that vicinity. Before you will be allowed"); + stage++; + break; + case 101: + npc("to enter the enclosure, however, you must ensure you","have some kind of protective clothing to prevent","contagion."); + stage++; + break; + case 102: + player("Where can I find some protective clothing then?"); + stage++; + break; + case 103: + npc("Doctor Orbon wears it when conducting mercy","missions to the infected parts of the city. You should be","able to find him in the chapel just north of here. Please","also take this poisoned sheep feed; we believe poisoning"); + stage++; + break; + case 104: + npc("the sheep will minimise the risk of airborne","contamination, and is of course also more humane to","the sheep."); + stage++; + break; + case 105: + player.getQuestRepository().getQuest(Quests.SHEEP_HERDER).start(player); + player.getDialogueInterpreter().sendDialogue("The councillor gives you some poisoned sheep feed."); + player.getInventory().add(SheepHerder.POISON); + stage++; + break; + case 106: + player("How will I know which sheep are infected?"); + stage++; + break; + case 107: + npc("The poor creatures have developed strangely discoloured","wool and flesh. You should have no trouble spotting","them."); + stage++; + break; + case 108: + end(); + break; + case 200: + if(player.getAttribute("sheep_herder:all_dead",false)){ + player("Yes, I have."); + stage = 205; + } else { + player("No, I haven't."); + stage++; + } + break; + case 201: + npc("Well, please do hurry!"); + stage++; + break; + case 202: + if (ContentAPIKt.hasAnItem(player, Items.SHEEP_FEED_279).getContainer() != null){ + player("I'll do my best sir."); + stage = 108; + } else { + player("Some more sheep poison would be appreciated..."); + stage++; + } + break; + case 203: + ContentAPIKt.addItemOrDrop(player, Items.SHEEP_FEED_279, 1); + npc("Certainly adventurer. Please hurry!"); + stage = 108; + break; + case 205: + npc("Excellent work adventurer! Please let me reimburse","you the 100 gold it cost you to purchase your","protective clothing."); + stage++; + break; + case 206: + npc("And in recognition of your service to the public health","of Ardougne please accept this further 3000 coins as a","reward."); + stage++; + break; + case 207: + player.getQuestRepository().getQuest(Quests.SHEEP_HERDER).finish(player); + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] {289} ; + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/sheepherder/HerderSheepNPC.java b/Server/src/main/content/region/kandarin/ardougne/quest/sheepherder/HerderSheepNPC.java new file mode 100644 index 0000000..8576e3f --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/sheepherder/HerderSheepNPC.java @@ -0,0 +1,63 @@ +package content.region.kandarin.ardougne.quest.sheepherder; + +import core.game.interaction.MovementPulse; +import core.game.node.entity.Entity; +import core.game.node.entity.npc.NPC; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.path.Pathfinder; + +public class HerderSheepNPC extends NPC { + int ticksTilReturn = 0; + Location spawnLocation; + + public HerderSheepNPC(int id, Location location) { + super(id, location); + this.spawnLocation = location; + this.setNeverWalks(false); + this.unlock(); + this.setRespawn(true); + } + + @Override + public void handleTickActions() { + if(getAttribute("recently-prodded",false)) { + if(getLocation().withinDistance(Location.create(2593, 3362, 0),2)){ + getProperties().setTeleportLocation(Location.create(2599, 3360, 0)); + } + if (ticksTilReturn < GameWorld.getTicks()) { + sendChat("Baa"); + this.getPulseManager().run(new MovementPulse(this, spawnLocation) { + @Override + public boolean pulse() { + return true; + } + }); + this.removeAttribute("recently-prodded"); + } + } else { + if(nextWalk < GameWorld.getTicks() && !getPulseManager().hasPulseRunning()){ + setNextWalk(); + Location to = getMovementDestination(); + if (canMove(to)) { + Pathfinder.find(this, to, true, Pathfinder.DUMB).walk(this); + } + } + } + } + + public void moveTo(Location l){ + this.getPulseManager().run(new MovementPulse(this,l) { + @Override + public boolean pulse() { + return true; + } + }); + } + + @Override + public void finalizeDeath(Entity killer) { + this.setRespawnTick(GameWorld.getTicks() + 100); + super.finalizeDeath(killer); + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/sheepherder/IncineratorHandler.java b/Server/src/main/content/region/kandarin/ardougne/quest/sheepherder/IncineratorHandler.java new file mode 100644 index 0000000..dd6a044 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/sheepherder/IncineratorHandler.java @@ -0,0 +1,69 @@ +package content.region.kandarin.ardougne.quest.sheepherder; + +import core.game.interaction.DestinationFlag; +import core.game.interaction.MovementPulse; +import core.game.interaction.NodeUsageEvent; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.game.interaction.PluginInteraction; +import core.game.interaction.PluginInteractionManager; + +import java.util.Objects; + +@Initializable +public class IncineratorHandler extends PluginInteraction { + @Override + public Plugin newInstance(Object arg) throws Throwable { + setIds(new int[] {SheepHerder.RED_SHEEP_BONES.getId(), SheepHerder.GREEN_SHEEP_BONES.getId(), SheepHerder.BLUE_SHEEP_BONES.getId(),SheepHerder.YELLOW_SHEEP_BONES.getId()}); + PluginInteractionManager.register(this, PluginInteractionManager.InteractionType.USEWITH); + return this; + } + + @Override + public boolean handle(Player player, NodeUsageEvent event) { + Node n = event.getUsedWith(); + if(n instanceof Scenery){ + Scenery obj = (Scenery) n; + if (n.getId() == 165) { + player.getPulseManager().run(new MovementPulse(player, DestinationFlag.OBJECT.getDestination(player,obj)) { + @Override + public boolean pulse() { + player.lock(2); + player.getInventory().remove(event.getUsedItem()); + player.getAnimator().reset(); + player.getAnimator().animate(new Animation(3243)); + switch (Objects.requireNonNull(event.getUsedItem()).getId()) { + case 280: + player.setAttribute("/save:sheep_herder:red_dead", true); + break; + case 281: + player.setAttribute("/save:sheep_herder:green_dead", true); + break; + case 282: + player.setAttribute("/save:sheep_herder:blue_dead", true); + break; + case 283: + player.setAttribute("/save:sheep_herder:yellow_dead", true); + break; + } + if (player.getAttribute("sheep_herder:red_dead", false) && player.getAttribute("sheep_herder:green_dead", false) && player.getAttribute("sheep_herder:blue_dead", false) && player.getAttribute("sheep_herder:yellow_dead", false)) { + player.setAttribute("/save:sheep_herder:all_dead", true); + } + return true; + } + }); + return true; + } + } + return false; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } +} diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/sheepherder/OrbonDialogue.java b/Server/src/main/content/region/kandarin/ardougne/quest/sheepherder/OrbonDialogue.java new file mode 100644 index 0000000..55efedc --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/sheepherder/OrbonDialogue.java @@ -0,0 +1,99 @@ +package content.region.kandarin.ardougne.quest.sheepherder; + +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.game.dialogue.DialoguePlugin; +import content.data.Quests; + +@Initializable +public class OrbonDialogue extends DialoguePlugin { + public OrbonDialogue(){ + //empty + } + public OrbonDialogue(Player player){super(player);} + + + @Override + public DialoguePlugin newInstance(Player player) { + return new OrbonDialogue(player); + } + + @Override + public boolean open(Object... args) { + if(player.getQuestRepository().getStage(Quests.SHEEP_HERDER) == 10){ + player("Hello doctor. I need to acquire some protective clothing","so that I can dispose of some escaped sheep infected","with the plague."); + stage = 100; + return true; + } else { + player.sendMessage("He doesn't seem interested in talking with you right now."); + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch(stage){ + case 100: + npc("Protective clothing? I'm afraid I only have the one suit","which I made myself to prevent infection from the","contaminated patients I treat."); + stage++; + break; + case 101: + npc("I suppose I could sell you this one and make myself","another, but it would cost you at least 100 gold so that","I could afford a replacement."); + stage++; + break; + case 102: + options("Sorry doc, that's too much.","Ok, I'll take it."); + stage++; + break; + case 103: + switch(buttonId){ + case 1: + player("Sorry doc, that's too much."); + stage = 120; + break; + case 2: + player("Ok, I'll take it."); + stage++; + break; + } + break; + case 104: + if(player.getInventory().containsItem(new Item(995,100))){ + player.getInventory().remove(new Item(995,100)); + if(!player.getInventory().add(SheepHerder.PLAGUE_BOTTOM, SheepHerder.PLAGUE_TOP)){ + GroundItemManager.create(SheepHerder.PLAGUE_TOP,player.getLocation(),player); + GroundItemManager.create(SheepHerder.PLAGUE_BOTTOM,player.getLocation(),player); + } + player.getDialogueInterpreter().sendDialogue("You give Doctor Orbon 100 coins. Doctor Orbon hands over a","protective suit."); + stage++; + break; + } else { + player("I would love to, but I don't have enough.."); + stage = 120; + break; + } + case 105: + npc("These should protect you from infection."); + stage++; + break; + case 106: + end(); + break; + case 120: + npc("That's unfortunate."); + stage++; + break; + case 121: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] {290}; + } +} diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/sheepherder/ProdActionHandler.java b/Server/src/main/content/region/kandarin/ardougne/quest/sheepherder/ProdActionHandler.java new file mode 100644 index 0000000..a9385fa --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/sheepherder/ProdActionHandler.java @@ -0,0 +1,80 @@ +package content.region.kandarin.ardougne.quest.sheepherder; + +import core.game.interaction.DestinationFlag; +import core.game.interaction.MovementPulse; +import core.game.interaction.Option; +import core.game.node.Node; +import core.game.node.entity.impl.PulseType; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.tools.RandomFunction; +import core.game.interaction.PluginInteraction; +import core.game.interaction.PluginInteractionManager; + +@Initializable +public class ProdActionHandler extends PluginInteraction { + + @Override + public boolean handle(Player player, NPC npc, Option option) { + HerderSheepNPC n = (HerderSheepNPC) npc; + if(option.getName().toLowerCase().equals("prod")){ + player.getPulseManager().run(new MovementPulse(player,getDestination(player,n)) { + @Override + public boolean pulse() { + handleProd(player,n); + return true; + } + }, PulseType.STANDARD); + return true; + } + return false; + } + + public Location getDestination(Player p, Node n){ + return DestinationFlag.ENTITY.getDestination(p,n); + } + + public void handleProd(Player p, HerderSheepNPC n){ + p.faceLocation(n.getLocation()); + Pulse prodPulse = new Pulse() { + @Override + public boolean pulse() { + if(p.getEquipment().containsItem(SheepHerder.CATTLE_PROD)){ + p.getAnimator().reset(); + p.getAnimator().animate(new Animation(412)); + int diffX = n.getLocation().getX() - p.getLocation().getX(); + int diffY = n.getLocation().getY() - p.getLocation().getY(); + int steps = RandomFunction.random(3,5); + Location destination = n.getLocation().transform((diffX) * steps, (diffY) * steps,0); + n.sendChat("BAAAAA!"); + n.moveTo(destination); + n.setAttribute("recently-prodded",true); + n.ticksTilReturn = GameWorld.getTicks() + 20; + return true; + } else { + p.sendMessage("You can't prod a sheep with your bare hands."); + return true; + } + } + }; + p.getPulseManager().run(prodPulse); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + setIds(new int[] {SheepHerder.RED_SHEEP,SheepHerder.BLUE_SHEEP,SheepHerder.GREEN_SHEEP,SheepHerder.YELLOW_SHEEP}); + PluginInteractionManager.register(this, PluginInteractionManager.InteractionType.NPC); + return this; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } +} diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/sheepherder/SheepHerder.java b/Server/src/main/content/region/kandarin/ardougne/quest/sheepherder/SheepHerder.java new file mode 100644 index 0000000..75ed87d --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/sheepherder/SheepHerder.java @@ -0,0 +1,148 @@ +package content.region.kandarin.ardougne.quest.sheepherder; + +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.plugin.Initializable; +import org.rs09.consts.Items; + +import java.util.HashMap; +import content.data.Quests; + +@Initializable +public class SheepHerder extends Quest { + public static Item CATTLE_PROD = new Item(Items.CATTLEPROD_278); + public static Item POISON = new Item(279); + public static Item PLAGUE_TOP = new Item(284); + public static Item PLAGUE_BOTTOM = new Item(285); + public static Item RED_SHEEP_BONES = new Item(Items.SHEEP_BONES_1_280); + public static Item GREEN_SHEEP_BONES = new Item(Items.SHEEP_BONES_2_281); + public static Item BLUE_SHEEP_BONES = new Item(Items.SHEEP_BONES_3_282); + public static Item YELLOW_SHEEP_BONES = new Item(Items.SHEEP_BONES_4_283); + public static int RED_SHEEP = 2345; + public static int GREEN_SHEEP = 2346; + public static int BLUE_SHEEP = 2347; + public static int YELLOW_SHEEP = 2348; + public static int FARMER_BRUMTY = 291; + + public static HashMap boneMap = new HashMap<>(); + static{ + boneMap.put(RED_SHEEP,RED_SHEEP_BONES); + boneMap.put(GREEN_SHEEP,GREEN_SHEEP_BONES); + boneMap.put(YELLOW_SHEEP,YELLOW_SHEEP_BONES); + boneMap.put(BLUE_SHEEP,BLUE_SHEEP_BONES); + } + + public SheepHerder(){super(Quests.SHEEP_HERDER,113,112,4,60,0,1,3);} + + @Override + public void drawJournal(Player player, int stage) { + boolean hasGear = (player.getInventory().containsItem(PLAGUE_BOTTOM) && player.getInventory().containsItem(PLAGUE_TOP) || (player.getEquipment().containsItem(PLAGUE_BOTTOM) && player.getEquipment().containsItem(PLAGUE_TOP))) || stage >= 20; + int line = 12; + boolean sheepDead = player.getAttribute("sheep_herder:all_dead",false); + super.drawJournal(player, stage); + if(stage == 0){ + line(player,"I can start this quest by speaking to !!Councillor Halgrive??", line++); + line(player, "near to the !!Zoo?? in !!East Ardougne??.", line++); + } else { + line(player,"Councillor Halgrive asked me to dispose of four plague", line++, true); + line(player,"bearing sheep just north of Ardougne and I accepted.", line++, true); + line(player,"He gave me some poisoned sheep feed to do this.", line++, true); + if(hasGear) { + line(player, "I bought some protective clothing from Dr. Orbon in the", line++, true); + line(player, "chapel north of Ardougne Zoo. I could now kill the sheep.", line++, true); + } else { + line(player, "!!Councillor Halgrive?? said I should speak to !!Doctor Orbon??", line++); + line(player, "about getting some protective gear.", line++); + } + if(stage == 10) { + // This is not authentic. +// line(player, "I need to !!locate the diseased sheep?? and corral them !!into the pen??", line++,sheepDead); +// line(player, "After which, I need to !!poison them?? and !!incinerate their bones.??", line++,sheepDead); + line++; + if (sheepDead) { + line(player, "I equipped a prod and then I used it to to herd the diseased", line++, true); + line(player, "sheep to a pen where I could safely kill them and", line++, true); + line(player, "incinerate their bones.", line++, true); + line(player,"I should return to !!Councillor Halgrive?? to collect the reward", line++); + line(player,"he has promised me for my hard work.", line++); + } else { + if (player.getAttribute("sheep_herder:red_dead", false)) { + line(player, "I have killed the first sheep and incinerated its bones.", line++, true); + } else { + line(player, "I must find the first sheep and herd it to the special pen.", line++); + } + if (player.getAttribute("sheep_herder:green_dead", false)) { + line(player, "I have killed the second sheep and incinerated its bones.", line++, true); + } else { + line(player, "I must find the second sheep and herd it to the special", line++); + line(player, "pen.", line++); + } + if (player.getAttribute("sheep_herder:blue_dead", false)) { + line(player, "I have killed the third sheep and incinerated its bones.", line++, true); + } else { + line(player, "I must find the third sheep and herd it to the special pen.", line++); + } + if (player.getAttribute("sheep_herder:yellow_dead", false)) { + line(player, "I have killed the fourth sheep and incinerated its bones.", line++, true); + } else { + line(player, "I must find the fourth sheep and herd it to the special pen.", line++); + } + } + } + + if(stage >= 100) { + line(player, "I equipped a prod to herd the diseased sheep and then I", line++, true); + line(player, "used it to incinerate all four plagued sheep.", line++, true); + line(player, "I returned to let Councillor Halgrive know that the plagued", line++, true); + line(player, "sheep were no more and claimed my reward.", line++, true); + line++; + line(player, "%%QUEST COMPLETE!&&", line++, false); + } + } + } + + @Override + public void finish(Player player) { + int ln = 10; + super.finish(player); + player.getPacketDispatch().sendItemZoomOnInterface(995, 230, 277, 5); + drawReward(player,"4 Quest Points",ln++); + drawReward(player,"3100 coins",ln++); + player.removeAttribute("sheep_herder:red_dead"); + player.removeAttribute("sheep_herder:blue_dead"); + player.removeAttribute("sheep_herder:green_dead"); + player.removeAttribute("sheep_herder:yellow_dead"); + player.removeAttribute("sheep_herder:all_dead"); + player.getInventory().add(new Item(995,3100)); + } + + @Override + public Quest newInstance(Object object) { + new HerderSheepNPC(RED_SHEEP, Location.create(2609, 3343, 0)).init(); + new HerderSheepNPC(RED_SHEEP,Location.create(2610, 3344, 0)).init(); + new HerderSheepNPC(RED_SHEEP,Location.create(2609, 3345, 0)).init(); + new HerderSheepNPC(RED_SHEEP,Location.create(2615, 3343, 0)).init(); + new HerderSheepNPC(GREEN_SHEEP,Location.create(2622, 3366, 0)).init(); + new HerderSheepNPC(GREEN_SHEEP,Location.create(2622, 3366, 0)).init(); + new HerderSheepNPC(GREEN_SHEEP,Location.create(2619, 3371, 0)).init(); + new HerderSheepNPC(GREEN_SHEEP,Location.create(2617, 3365, 0)).init(); + new HerderSheepNPC(YELLOW_SHEEP,Location.create(2610, 3390, 0)).init(); + new HerderSheepNPC(YELLOW_SHEEP,Location.create(2613, 3389, 0)).init(); + new HerderSheepNPC(YELLOW_SHEEP,Location.create(2606, 3391, 0)).init(); + new HerderSheepNPC(YELLOW_SHEEP,Location.create(2608, 3387, 0)).init(); + new HerderSheepNPC(BLUE_SHEEP,Location.create(2559, 3388, 0)).init(); + new HerderSheepNPC(BLUE_SHEEP,Location.create(2562, 3388, 0)).init(); + new HerderSheepNPC(BLUE_SHEEP,Location.create(2563, 3383, 0)).init(); + new HerderSheepNPC(BLUE_SHEEP,Location.create(2570, 3381, 0)).init(); + NPC Brumty = new NPC(FARMER_BRUMTY,Location.create(2594,3357,0)); + Brumty.setWalks(false); + Brumty.setRespawn(true); + Brumty.init(); + Brumty.setDirection(Direction.NORTH); + return this; + } +} diff --git a/Server/src/main/content/region/kandarin/ardougne/quest/sheepherder/SheepPoisonHandler.java b/Server/src/main/content/region/kandarin/ardougne/quest/sheepherder/SheepPoisonHandler.java new file mode 100644 index 0000000..585210c --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/quest/sheepherder/SheepPoisonHandler.java @@ -0,0 +1,85 @@ +package content.region.kandarin.ardougne.quest.sheepherder; + +import core.game.interaction.DestinationFlag; +import core.game.interaction.MovementPulse; +import core.game.interaction.NodeUsageEvent; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItemManager; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.game.interaction.PluginInteraction; +import core.game.interaction.PluginInteractionManager; + +@Initializable +public class SheepPoisonHandler extends PluginInteraction { + @Override + public Plugin newInstance(Object arg) throws Throwable { + setIds(new int[]{SheepHerder.POISON.getId()}); + PluginInteractionManager.register(this, PluginInteractionManager.InteractionType.USEWITH); + return null; + } + + @Override + public boolean handle(Player player, NodeUsageEvent event) { + Node n = event.getUsedWith(); + if(n instanceof HerderSheepNPC){ + if (withinBorders(n.getLocation(),Location.create(2595, 3364, 0),Location.create(2609, 3351, 0))){ + handlePoisoning(player,(HerderSheepNPC) n); + return true; + } + } + return false; + } + + public void handlePoisoning(Player p, HerderSheepNPC n){ + p.lock(1); + Pulse deathPulse = new Pulse() { + int counter = 0; + @Override + public boolean pulse() { + switch(counter){ + case 0: + p.getDialogueInterpreter().sendDialogue("You feed some poisoned sheep food to the sheep.","It happily eats it."); + counter++; + break; + case 1: + n.getAnimator().animate(new Animation(5336)); + counter++; + break; + case 2: + p.getDialogueInterpreter().sendDialogue("You watch as the sheep collapses dead onto the floor."); + counter++; + break; + case 3: + n.getProperties().setTeleportLocation(n.spawnLocation); + GroundItemManager.create(SheepHerder.boneMap.get(n.getId()),n.getLocation(),p); + return true; + } + return false; + } + }; + p.getPulseManager().run(new MovementPulse(p, DestinationFlag.ENTITY.getDestination(p,n)) { + @Override + public boolean pulse() { + p.faceLocation(n.getLocation()); + GameWorld.getPulser().submit(deathPulse); + return true; + } + }); + } + + + private boolean withinBorders(Location toCheck, Location sW, Location nE){ + return (toCheck.getX() >= sW.getX() && toCheck.getX() <= nE.getX()) && (toCheck.getY() <= sW.getY() && toCheck.getY() >= nE.getY()); + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } +} diff --git a/Server/src/main/content/region/kandarin/ardougne/westardougne/MournerUtilities.kt b/Server/src/main/content/region/kandarin/ardougne/westardougne/MournerUtilities.kt new file mode 100644 index 0000000..461a15a --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/westardougne/MournerUtilities.kt @@ -0,0 +1,57 @@ +package content.region.kandarin.ardougne.westardougne + +import core.api.EquipmentSlot +import core.api.allInEquipment +import core.api.getItemFromEquipment +import core.api.inEquipment +import core.game.node.entity.player.Player +import org.rs09.consts.Items + +object MournerUtilities { + + const val NO_GEAR = 0 + const val JUST_MASK = 1 + const val JUST_GEAR = 2 + const val EXTRA_GEAR = 3 + + /** + * Check if the player is wearing just mourner gear + * @return 0 incomplete gear 1 mask only 2 complete gear only 3 complete gear with extras + */ + fun wearingMournerGear(player: Player): Int { + // Check that the play has all of these items + if (inEquipment(player, Items.GAS_MASK_1506)) { + // We have a mask + if (!allInEquipment( + player, Items.MOURNER_TOP_6065, Items.MOURNER_TROUSERS_6067, + Items.MOURNER_BOOTS_6069, Items.MOURNER_GLOVES_6068, Items.MOURNER_CLOAK_6070 + ) + ) { + // We have only a mask + return JUST_MASK + } + else { + // Check if we have other gear + + // These use up slots 0, 1, 4, 7, 9, 10. Check the others are empty + val mournerSlots = arrayOf( + EquipmentSlot.HEAD, EquipmentSlot.CAPE, EquipmentSlot.CHEST, + EquipmentSlot.LEGS, EquipmentSlot.HANDS, EquipmentSlot.FEET + ) + for (slot in EquipmentSlot.values()) { + // Skip the slots that we know have the gear equipped + if (mournerSlots.contains(slot)) continue + if (getItemFromEquipment(player, slot) != null) { + return EXTRA_GEAR + } + } + return JUST_GEAR + } + + } + else { + // We don't even have a mask + return NO_GEAR + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/CarlaDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/CarlaDialogue.kt new file mode 100644 index 0000000..a3431f6 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/CarlaDialogue.kt @@ -0,0 +1,52 @@ +package content.region.kandarin.ardougne.westardougne.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class CarlaDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + playerl(FacialExpression.FRIENDLY, "Hello there.").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> npcl(FacialExpression.SAD, "Oh, hello.").also { stage++ } + 1 -> playerl(FacialExpression.FRIENDLY, "You seem upset... What's wrong?").also { stage++ } + 2 -> npcl(FacialExpression.FRIENDLY, "That's awful, I'm sorry.").also { stage++ } + 3 -> npcl(FacialExpression.FRIENDLY, "It would be easier to cope with if I could have spent his last few days with him.").also { stage = 4 } + 4 -> playerl(FacialExpression.FRIENDLY, "Why didn't you?").also { stage++ } + 5 -> npcl(FacialExpression.SAD, "Those mourners came and whisked him away. He didn't even seem that ill, I thought it was a common cold. But the mourners said he was infected and had to be taken away. Two days later the mourners returned and told me he had died.").also { stage++ } + 6 -> playerl(FacialExpression.FRIENDLY, "Again, I'm sorry. Life can be harsh.").also { stage++ } + 7 -> options("Where did the plague come from?", "Have there been many victims of the plague?", "I hope things get easier for you.").also { stage++ } + 8 -> when(buttonId) { + 1 -> playerl(FacialExpression.ASKING, "Where did the plague come from?").also { stage = 9 } + 2 -> playerl(FacialExpression.ASKING, "Have there been many victims of the plague?").also { stage = 10 } + 3 -> playerl(FacialExpression.ASKING, "I hope things get easier for you.").also { stage = 13 } + } + 9 -> npcl(FacialExpression.SAD, "It's down to King Tyras. He and his men brought the plague here from the darklands, and then left us to suffer. One day he'll pay for what he's done!").also { stage = 8 } + 10 -> npcl(FacialExpression.SAD, "You could say that... I've heard reports that half of West Ardougne is infected! Many have lost friends and family...").also { stage++ } + 11 -> playerl(FacialExpression.FRIENDLY, "It sounds an awful way to live.").also { stage++ } + 12 -> npcl(FacialExpression.FRIENDLY, "People are very depressed and scared. I've never met anyone fully infected though. I suppose we should be grateful to the mourners for that.").also { stage = END_DIALOGUE } + 13 -> npcl(FacialExpression.SAD, "Me too...").also { stage = END_DIALOGUE } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return CarlaDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.CARLA_712) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/ChildDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/ChildDialogue.kt new file mode 100644 index 0000000..210d0ee --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/ChildDialogue.kt @@ -0,0 +1,35 @@ +package content.region.kandarin.ardougne.westardougne.dialogue + +import content.region.kandarin.ardougne.westardougne.MournerUtilities +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class ChildDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + playerl(FacialExpression.FRIENDLY, "Hello there.").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + val noun = if (MournerUtilities.wearingMournerGear(player) > MournerUtilities.JUST_MASK) "mourners" else "strangers" + npcl(FacialExpression.CHILD_NORMAL, "I'm not allowed to speak with $noun.").also { stage = END_DIALOGUE } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return ChildDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.CHILD_356, NPCs.CHILD_355) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/CivilianDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/CivilianDialogue.kt new file mode 100644 index 0000000..dcf6f73 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/CivilianDialogue.kt @@ -0,0 +1,181 @@ +package content.region.kandarin.ardougne.westardougne.dialogue + +import content.region.kandarin.ardougne.westardougne.MournerUtilities +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + + +val cats = intArrayOf( + Items.PET_CAT_1561, + Items.PET_CAT_1562, + Items.PET_CAT_1563, + Items.PET_CAT_1564, + Items.PET_CAT_1565, + Items.PET_CAT_1566, + Items.OVERGROWN_CAT_1567, + Items.OVERGROWN_CAT_1568, + Items.OVERGROWN_CAT_1569, + Items.OVERGROWN_CAT_1570, + Items.OVERGROWN_CAT_1571, + Items.OVERGROWN_CAT_1572, + // todo implement these cats then uncomment this + // otherwise you get an exception which just steals your cat for no runes + // Items.LAZY_CAT_6549, + // Items.LAZY_CAT_6550, + // Items.LAZY_CAT_6551, + // Items.LAZY_CAT_6552, + // Items.LAZY_CAT_6553, + // Items.LAZY_CAT_6554, + // Items.WILY_CAT_6555, + // Items.WILY_CAT_6556, + // Items.WILY_CAT_6557, + // Items.WILY_CAT_6558, + // Items.WILY_CAT_6559, + // Items.WILY_CAT_6560, +) + +@Initializable +class CivilianDialogue(player: Player? = null) : DialoguePlugin(player) { + + companion object { + // Any of these + + + const val DIAG1 = 10 + const val DIAG2 = 20 + const val DIAG3 = 30 + + const val NO_CAT = 40 + const val BUY_CATS = 50 + const val REJECT_DEAL = 80 + const val WITCH_CAT = 90 + + const val MOURNER = 100 + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + if (MournerUtilities.wearingMournerGear(player) > MournerUtilities.JUST_MASK){ + playerl(FacialExpression.NEUTRAL, "Hello.").also { stage = MOURNER } + } + else { + when (npc.id) { + NPCs.CIVILIAN_785 -> playerl(FacialExpression.NEUTRAL, "Hello there.").also { stage = DIAG1 } + NPCs.CIVILIAN_786 -> playerl(FacialExpression.NEUTRAL, "Hi there.").also { stage = DIAG2 } + NPCs.CIVILIAN_787 -> player(FacialExpression.NEUTRAL, "Hello there.").also { stage = DIAG3 } + } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + DIAG1 -> npcl(FacialExpression.HALF_GUILTY, "Oh hello, I'm sorry, I'm a bit worn out.").also { stage++ } + DIAG1 + 1 -> playerl(FacialExpression.NEUTRAL, "Busy day?").also { stage++ } + DIAG1 + 2 -> npcl(FacialExpression.HALF_GUILTY, "Oh, It's those mice! They're everywhere! " + + "What I really need is a cat. But they're hard to come by nowadays.").also { + stage = checkCat() + } + + DIAG2 -> npcl(FacialExpression.NEUTRAL, "Good day to you traveller.").also { stage++ } + DIAG2 + 1 -> playerl(FacialExpression.NEUTRAL, "What are you up to?").also { stage++ } + DIAG2 + 2 -> npcl(FacialExpression.NEUTRAL, "Chasing mice as usual! It's all I seem to do nowadays.").also { stage++ } + DIAG2 + 3 -> playerl(FacialExpression.NEUTRAL, "You must waste a lot of time?").also { stage++ } + DIAG2 + 4 -> npcl(FacialExpression.HALF_WORRIED, "Yes, but what can you do? It's not like there's many cats around here!").also{ stage = checkCat() + } + + DIAG3 -> npcl(FacialExpression.HALF_WORRIED, "I'm a bit busy to talk right now, sorry.").also { stage++ } + DIAG3 + 1 -> playerl(FacialExpression.NEUTRAL, "Why? What are you doing?").also { stage++ } + DIAG3 + 2 -> npcl(FacialExpression.HALF_WORRIED, "Trying to kill these mice! What I really need is a cat!").also { stage = checkCat() } + + NO_CAT -> playerl(FacialExpression.HALF_WORRIED, "No, you're right, you don't see many around.").also { stage = END_DIALOGUE } + + BUY_CATS -> showTopics( + Topic("I have a cat that I could sell.", BUY_CATS + 1), + Topic("Nope, they're not easy to get hold of.", END_DIALOGUE) + ) + // intentional whitespace typo + BUY_CATS + 1 -> npcl(FacialExpression.ASKING, "You don't say, is that it ?").also { stage++ } + BUY_CATS + 2 -> playerl(FacialExpression.HAPPY, "Say hello to a real mouse killer!").also { stage++ } + BUY_CATS + 3 -> npcl(FacialExpression.HALF_ASKING, "Hmmm, not bad, not bad at all. Looks like it's a lively one.").also { stage++ } + BUY_CATS + 4 -> playerl(FacialExpression.HALF_GUILTY, "Erm...kind of...").also { stage++ } + BUY_CATS + 5 -> npcl(FacialExpression.FRIENDLY, "I don't have much in the way of money. I do have these!").also { stage++ } + BUY_CATS + 6 -> sendDialogue("The peasant shows you a sack of Death Runes.").also { stage++ } + BUY_CATS + 7 -> npcl(FacialExpression.ASKING, "The dwarves bring them from the mine for us. Tell you what, I'll give you 100 Death Runes for the cat.").also { stage++ } + BUY_CATS + 8 -> showTopics( + Topic("Nope, I'm not parting for that.", REJECT_DEAL), + Topic("Ok then, you've got a deal.", BUY_CATS+9) + ) + BUY_CATS + 9 -> { + npcl(FacialExpression.HAPPY, "Great! Hand over the cat and I'll give you the runes.").also { + stage = END_DIALOGUE + for (cat in cats) { + if (removeItem(player, cat)){ + player.familiarManager.removeDetails(cat) + addItem(player, Items.DEATH_RUNE_560, 100) + break + } + } + } + } + + REJECT_DEAL -> npcl(FacialExpression.HALF_GUILTY, "Well, I'm not giving you anymore!").also { stage = END_DIALOGUE } + + WITCH_CAT -> playerl(FacialExpression.HAPPY, "I have a cat...look!").also { stage++ } + WITCH_CAT + 1 -> npcl(FacialExpression.HALF_WORRIED, "Hmmm...doesn't look like it's seen daylight in years. That's not going to catch any mice!").also { stage = END_DIALOGUE } + + + MOURNER -> npcl(FacialExpression.ANGRY, "If you Mourners really wanna help, why don't you do something about these mice?!").also { stage = END_DIALOGUE } + } + return true + } + + private fun checkCat(): Int { + return if (anyInInventory(player, *cats)) BUY_CATS + else if (inInventory(player, Items.WITCHS_CAT_1491)) WITCH_CAT + else NO_CAT + + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.CIVILIAN_785, NPCs.CIVILIAN_786, NPCs.CIVILIAN_787) + } +} + + +class CatTrade : InteractionListener{ + override fun defineListeners() { + + class CatTradeDialogue : DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + when (stage){ + 0 -> sendDialogue(player!!, "You hand over the cat. You are given 100 Death Runes.").also { stage++ } + 1 -> npcl(FacialExpression.HAPPY, "Great, thanks for that!").also { stage++ } + 2 -> playerl(FacialExpression.NEUTRAL, "That's ok, take care.").also { stage = END_DIALOGUE } + } + } + } + onUseWith(IntType.NPC, cats, NPCs.CIVILIAN_785, NPCs.CIVILIAN_786, NPCs.CIVILIAN_787){ player, used, with -> + if(removeItem(player, used)){ + val dialogue = CatTradeDialogue() + // Remove the cat + player.familiarManager.removeDetails(used.id) + addItem(player, Items.DEATH_RUNE_560, 100) + openDialogue(player, dialogue, with as NPC) + } + + return@onUseWith true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/HeadMournerDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/HeadMournerDialogue.kt new file mode 100644 index 0000000..65671e9 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/HeadMournerDialogue.kt @@ -0,0 +1,115 @@ +package content.region.kandarin.ardougne.westardougne.dialogue + +import content.data.Quests +import content.region.kandarin.ardougne.quest.plaguecity.PlagueCity +import content.region.kandarin.ardougne.westardougne.MournerUtilities +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.IfTopic +import core.game.dialogue.Topic +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs +import kotlin.properties.Delegates + +@Initializable +class HeadMournerDialogue(player: Player? = null) : DialoguePlugin(player) { + + companion object { + const val CLEARANCE = 40 + const val WHATS_A_MOURNER = 10 + const val NO_PLAGUE = 20 + const val ELENA = 30 + + const val CRAZY = 50 + const val KIDNAP = 60 + const val MASK = 70 + + var mourningGear by Delegates.notNull() + + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + mourningGear = MournerUtilities.wearingMournerGear(player) + if(mourningGear < MournerUtilities.JUST_GEAR){ + npcl(FacialExpression.ANGRY, "How did you get into West Ardougne? " + + "Ah well you'll have to stay, can't risk you spreading the plague outside.").also { stage++ } + } + else{ + npcl(FacialExpression.NEUTRAL, "Ahh... A new recruit.").also { stage++ } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(mourningGear){ + MournerUtilities.NO_GEAR, MournerUtilities.JUST_MASK -> when(stage){ + START_DIALOGUE + 1 -> showTopics( + IfTopic("I need clearance to enter a plague house.", CLEARANCE, + !isQuestComplete(player, Quests.PLAGUE_CITY) && (getQuestStage(player, Quests.PLAGUE_CITY) > 11)), + Topic("So what's a mourner?", WHATS_A_MOURNER), + Topic("I haven't got the plague though. ", NO_PLAGUE), + IfTopic("I'm looking for a woman named Elena.", ELENA, !isQuestComplete(player, Quests.PLAGUE_CITY)) + ) + + CLEARANCE -> npcl(FacialExpression.DISGUSTED, "You must be nuts, absolutely not!").also { stage++ } + CLEARANCE + 1 -> showTopics( + Topic("There's a kidnap victim inside!", KIDNAP), + Topic("I've got a gas mask though...", MASK), + Topic("Yes, I'm utterly crazy.", CRAZY) + ) + + KIDNAP -> npcl(FacialExpression.FRIENDLY, "Well they're as good as dead then, no point in trying to save them.").also { stage = END_DIALOGUE } + + MASK -> npcl(FacialExpression.FRIENDLY, "It's not regulation. Anyway you're not properly trained to deal with the plague.").also { stage++ } + MASK + 1 -> playerl(FacialExpression.FRIENDLY, "How do I get trained?").also { stage++ } + MASK + 2 -> npcl(FacialExpression.FRIENDLY, "It requires a strict 18 months of training.").also { stage++ } + MASK + 3 -> playerl(FacialExpression.FRIENDLY, "I don't have that sort of time.").also { stage = END_DIALOGUE } + + CRAZY -> npcl(FacialExpression.FRIENDLY, "You're wasting my time, I have a lot of work to do!").also { stage = END_DIALOGUE } + + WHATS_A_MOURNER -> npcl(FacialExpression.NEUTRAL, + "We're working for King Lathas of East Ardougne trying to contain the accursed plague sweeping West Ardougne." + + " We also do our best to ease these people's suffering.").also { stage++ } + WHATS_A_MOURNER + 1 -> npcl(FacialExpression.NEUTRAL, "We're nicknamed mourners because we spend a lot of" + + " time at plague victim funerals, no-one else is allowed to risk the funerals." + + " It's a demanding job, and we get little thanks from the people here.").also { stage = END_DIALOGUE } + + NO_PLAGUE -> npcl(FacialExpression.ANNOYED, "Can't risk you being a carrier. That protective clothing you have isn't regulation issue. It won't meet safety standards.").also { stage = END_DIALOGUE } + + ELENA -> npcl( + FacialExpression.NEUTRAL, + "Ah yes, I've heard of her. A healer I believe. She must be mad coming over here voluntarily." + ).also { stage++ } + + ELENA + 1 -> npcl( + FacialExpression.SAD, + "I hear rumours she has probably caught the plague now. Very tragic, a stupid waste of life." + ).also { stage = END_DIALOGUE } + + } + + MournerUtilities.JUST_GEAR, MournerUtilities.EXTRA_GEAR -> when(stage){ + START_DIALOGUE+1 ->playerl(FacialExpression.ASKING, " How do you know I'm new?").also { stage++ } + START_DIALOGUE+2 -> npcl(FacialExpression.NEUTRAL, "Because all the old members of the guard know to report to the real Head Mourner, not me.").also { if (mourningGear == MournerUtilities.EXTRA_GEAR) stage++ else stage+=2 } + START_DIALOGUE+3 -> npcl(FacialExpression.ANNOYED, "Also, none of the old timers use non-regulation gear.").also { stage++ } + START_DIALOGUE+4 -> playerl(FacialExpression.ASKING, " You're not the real overseer here?").also { stage++ } + START_DIALOGUE+5 -> npcl(FacialExpression.NEUTRAL, "No, I am just a front man, our true head is far too busy to deal with the requests of the citizens, so I conduct the day to day business here.").also { stage++ } + START_DIALOGUE+6 -> npcl(FacialExpression.NEUTRAL, "You should go and report in" + if(mourningGear == MournerUtilities.EXTRA_GEAR) ", I would lose the non-regulation gear as well if I were you." else "." ).also { stage++ } + START_DIALOGUE+7 -> playerl(FacialExpression.FRIENDLY, "Okay, thanks.").also { stage = END_DIALOGUE } + } + } + return true + } + + + override fun getIds(): IntArray { + return intArrayOf(NPCs.HEAD_MOURNER_716) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/ManWomanDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/ManWomanDialogue.kt new file mode 100644 index 0000000..a86698f --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/ManWomanDialogue.kt @@ -0,0 +1,81 @@ +package content.region.kandarin.ardougne.westardougne.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.RandomFunction +import org.rs09.consts.NPCs + +@Initializable +class ManWomanDialogue(player: Player? = null) : DialoguePlugin(player) { + + companion object { + const val DIAG1 = 10 + const val DIAG2 = 20 + const val DIAG3 = 30 + const val DIAG4 = 40 + const val DIAG5 = 50 + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + val path = RandomFunction.random(1, 6) + val msg = when(path){ + 1,5 -> "Good day." + 2 -> "Hi there." + 3, 4 -> "Hello, how's it going?" + else -> "Hello" + } + + playerl(FacialExpression.FRIENDLY, msg).also { stage = path * 10 } + + return true + } + + override fun handle(componentID: Int, buttonID: Int): Boolean { + when (stage){ + DIAG1 -> npcl(FacialExpression.HALF_ASKING, "An outsider! Can you get me out of this hell hole?").also { stage++ } + DIAG1 + 1 -> playerl(FacialExpression.SAD, "Sorry, that's not what I'm here to do.").also { stage = END_DIALOGUE } + + DIAG2 -> npcl(FacialExpression.ANNOYED, "Go away. People from the outside shut us in like animals. I have nothing to say to you.").also { stage = END_DIALOGUE } + + DIAG3 -> npcl(FacialExpression.SAD, "Life is tough.").also { stage++ } + DIAG3 + 1 -> showTopics( + Topic("Yes, living in a plague city must be hard.", DIAG3 + 2), + Topic("I'm sorry to hear that.", DIAG3 + 3), + Topic("I'm looking for a lady called Elena.", DIAG3 + 4) + ) + DIAG3 + 2 -> npcl(FacialExpression.HALF_GUILTY, "Plague? Pah, that's no excuse for the treatment we've received. It's obvious pretty quickly if someone has the plague. I'm thinking about making a break for it. I'm perfectly healthy, not gonna infect anyone.").also { stage = END_DIALOGUE } + DIAG3 + 3 -> npcl(FacialExpression.SAD, "Well, aint much either you or me can do about it.").also { stage = END_DIALOGUE } + DIAG3 + 4 -> npcl(FacialExpression.NEUTRAL, "I've not heard of her. Old Jethick knows a lot of people, maybe he'll know where you can find her.").also { stage = END_DIALOGUE } + + DIAG4 -> npcl(FacialExpression.ANNOYED, "Bah, those mourners... they're meant to be helping us, but I think they're doing more harm here than good. They won't even let me send a letter out to my family.").also{ stage++} + DIAG4 + 1 -> showTopics( + Topic("Have you seen a lady called Elena around here?", DIAG4 + 2), + Topic("You should stand up to them more.", DIAG4 + 3) + ) + DIAG4 + 2 -> npcl(FacialExpression.SAD, "Yes, I've seen her. Very helpful person. Not for the last few days though... I thought maybe she'd gone home.").also { stage = END_DIALOGUE } + DIAG4 + 3 -> npcl(FacialExpression.HALF_GUILTY, " Oh I'm not one to cause a fuss.").also { stage = END_DIALOGUE } + + DIAG5 -> npcl(FacialExpression.ANGRY, "We don't have good days here anymore. Curse King Tyras.").also { stage++ } + DIAG5 + 1 -> showTopics( + Topic("Oh ok, bad day then.", END_DIALOGUE), + Topic("Why, what has he done?", DIAG5 + 2), + Topic("I'm looking for a woman called Elena.", DIAG5 + 3) + ) + DIAG5 + 2 -> npcl(FacialExpression.ANGRY, "His army curses our city with this plague then wanders off again, leaving us to clear up the pieces.").also { stage = END_DIALOGUE } + DIAG5 + 3 -> npcl(FacialExpression.NEUTRAL, "Not heard of her.").also { stage = END_DIALOGUE } + } + return true + } + + override fun getIds(): IntArray { + + return intArrayOf(NPCs.MAN_728, NPCs.MAN_729, NPCs.MAN_351, + NPCs.WOMAN_352, NPCs.WOMAN_353, NPCs.WOMAN_354, NPCs.WOMAN_360, NPCs.WOMAN_361, NPCs.WOMAN_362, NPCs.WOMAN_363) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/MournerDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/MournerDialogue.kt new file mode 100644 index 0000000..da0ef56 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/MournerDialogue.kt @@ -0,0 +1,114 @@ +package content.region.kandarin.ardougne.westardougne.dialogue + +import content.data.Quests +import content.region.kandarin.ardougne.quest.plaguecity.PlagueCity +import content.region.kandarin.ardougne.westardougne.MournerUtilities.EXTRA_GEAR +import content.region.kandarin.ardougne.westardougne.MournerUtilities.JUST_GEAR +import content.region.kandarin.ardougne.westardougne.MournerUtilities.JUST_MASK +import content.region.kandarin.ardougne.westardougne.MournerUtilities.NO_GEAR +import content.region.kandarin.ardougne.westardougne.MournerUtilities.wearingMournerGear +import core.api.getQuestStage +import core.game.dialogue.* +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class MournerDialogue(player: Player? = null) : DialoguePlugin(player) { + + companion object{ + const val WHATS_A_MOURNER = 10 + const val NO_PLAGUE = 20 + const val ELENA = 30 + + const val CONVO_1 = 40 + const val CONVO_2 = 50 + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(wearingMournerGear(player)){ + NO_GEAR, JUST_MASK -> { + if (npc.id == NPCs.MOURNER_717) { + when (stage) { + 0 -> npcl( + FacialExpression.HALF_ASKING, + "Hmmm, how did you get over here? You're not one of this rabble. Ah well, you'll have to stay. Can't risk you going back now." + ).also { stage++ } + + 1 -> showTopics( + Topic("So what's a mourner?", WHATS_A_MOURNER), + Topic("I haven't got the plague though... ", NO_PLAGUE), + IfTopic( + "I'm looking for a woman named Elena.", + ELENA, + getQuestStage(player, Quests.PLAGUE_CITY) in (6..98) + ) + ) + + WHATS_A_MOURNER -> npcl( + FacialExpression.NEUTRAL, + "We're working for King Lathas of East Ardougne trying to contain the accursed plague sweeping West Ardougne." + + " We also do our best to ease these people's suffering." + ).also { stage++ } + + WHATS_A_MOURNER + 1 -> npcl( + FacialExpression.NEUTRAL, "We're nicknamed mourners because we spend a lot of" + + " time at plague victim funerals, no-one else is allowed to risk the funerals." + + " It's a demanding job, and we get little thanks from the people here." + ).also { stage = END_DIALOGUE } + + ELENA -> npcl( + FacialExpression.NEUTRAL, + "Ah yes, I've heard of her. A healer I believe. She must be mad coming over here voluntarily." + ).also { stage++ } + + ELENA + 1 -> npcl( + FacialExpression.SAD, + "I hear rumours she has probably caught the plague now. Very tragic, a stupid waste of life." + ).also { stage = END_DIALOGUE } + + NO_PLAGUE -> npcl( + FacialExpression.ANNOYED, + "Can't risk you being a carrier. That protective clothing you have isn't regulation issue. It won't meet safety standards." + ).also { stage = END_DIALOGUE } + } + } + else{ + npcl(FacialExpression.ANNOYED, "Stand back citizen, do not approach me.").also { stage = END_DIALOGUE } + } + + } + JUST_GEAR -> { + when(stage){ + 0 -> playerl(FacialExpression.NEUTRAL, "Hello.").also { + stage = if((0..1).random() > 0) CONVO_1 else CONVO_2 + } + + CONVO_1 -> npcl(FacialExpression.NEUTRAL, "Good day. Are you in need of assistance?").also { stage++ } + CONVO_1 + 1 -> playerl(FacialExpression.NEUTRAL, " Yes, but I don't think you can help.").also { stage++ } + CONVO_1 + 2 -> npcl(FacialExpression.NEUTRAL, " You will be surprised at how much help the brute force of the Guard can be.").also { stage++ } + CONVO_1 + 3 -> playerl(FacialExpression.NEUTRAL, " Well I'll be sure to ask if I'm in need of some muscle.").also { stage = END_DIALOGUE } + + CONVO_2 -> npcl(FacialExpression.ANNOYED, " Good day. Are you in need of assistance?").also { stage++ } + CONVO_2 + 1 -> playerl(FacialExpression.NEUTRAL, " No, I just wanted to talk to a friendly face.").also { stage++ } + CONVO_2 + 2 -> npcl(FacialExpression.ANGRY, " Do I look friendly to you? I really must work on my scowl more.").also { stage = END_DIALOGUE } + } + + } + EXTRA_GEAR -> { + when(stage){ + 0 -> npcl(FacialExpression.ANNOYED, "You should know better than to wear non-regulation gear.").also { stage++ } + 1 -> playerl(FacialExpression.HALF_GUILTY, "Sorry, I'm new around here.").also { stage++ } + 2 -> npcl(FacialExpression.ANNOYED, "Well, you know the drill - lose the gear, I will let it pass this time.").also { stage = END_DIALOGUE } + } + } + } + + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.MOURNER_717, NPCs.MOURNER_348, NPCs.MOURNER_347, NPCs.MOURNER_371, NPCs.MOURNER_369) + } +} diff --git a/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/NurseSarahDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/NurseSarahDialogue.kt new file mode 100644 index 0000000..fd7fbcd --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/NurseSarahDialogue.kt @@ -0,0 +1,38 @@ +package content.region.kandarin.ardougne.westardougne.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class NurseSarahDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + playerl(FacialExpression.FRIENDLY, "Hello there.").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> npcl(FacialExpression.FRIENDLY, "Hello my dear, how are you feeling?").also { stage++ } + 1 -> playerl(FacialExpression.FRIENDLY, "I'm ok thanks.").also { stage++ } + 2 -> npcl(FacialExpression.FRIENDLY, "Well in that case I'd better get back to work. Take care.").also { stage++ } + 3 -> playerl(FacialExpression.FRIENDLY, "You too.").also { stage = END_DIALOGUE } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return NurseSarahDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.NURSE_SARAH_373) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/PriestDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/PriestDialogue.kt new file mode 100644 index 0000000..4728846 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/PriestDialogue.kt @@ -0,0 +1,35 @@ +package content.region.kandarin.ardougne.westardougne.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class PriestDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + playerl(FacialExpression.FRIENDLY, "Hello there.").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> npcl(FacialExpression.FRIENDLY, "I wish there was more I could do for these people.").also { stage = END_DIALOGUE } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return PriestDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.PRIEST_358) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/RecruiterDialogue.kt b/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/RecruiterDialogue.kt new file mode 100644 index 0000000..3e53af8 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/westardougne/dialogue/RecruiterDialogue.kt @@ -0,0 +1,38 @@ +package content.region.kandarin.ardougne.westardougne.dialogue + +import core.api.sendNPCDialogue +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class RecruiterDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npcl(FacialExpression.FRIENDLY, "Citizens of West Ardougne. Who will join the Royal Army of Ardougne? It is a very noble cause. Fight alongside King Tyras, crusading in the darklands of the west!").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> sendNPCDialogue(player, NPCs.MAN_726, "Plague bringer!").also { stage++ } + 1 -> sendNPCDialogue(player, NPCs.MAN_726, "King Tyras is scum!").also { stage++ } + 2 -> npcl(FacialExpression.FRIENDLY, "Tyras will be informed of these words of treason!").also { stage = END_DIALOGUE } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return RecruiterDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.RECRUITER_720) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/westardougne/handlers/MainGatesListener.kt b/Server/src/main/content/region/kandarin/ardougne/westardougne/handlers/MainGatesListener.kt new file mode 100644 index 0000000..82a8cd5 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/westardougne/handlers/MainGatesListener.kt @@ -0,0 +1,32 @@ +package content.region.kandarin.ardougne.westardougne.handlers + +import content.data.Quests +import core.api.* +import core.game.global.action.DoorActionHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.world.map.Location +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +class MainGatesListener : InteractionListener { + + override fun defineListeners() { + on(intArrayOf(Scenery.ARDOUGNE_WALL_DOOR_9738, Scenery.ARDOUGNE_WALL_DOOR_9330), IntType.SCENERY, "open") { player, node -> + if (hasRequirement(player, Quests.BIOHAZARD)) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else if(inBorders(player, 2556, 3298, 2557, 3301)){ + lock(player,2) + sendMessage(player, "You pull on the large wooden doors...") + queueScript(player,2){ + sendMessage(player, "...but they will not open.") + return@queueScript stopExecuting(player) + } + } else { + face(player, Location.create(2559, 3302, 0)) + sendNPCDialogue(player, NPCs.MOURNER_2349, "Oi! What are you doing? Get away from there!") + } + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/westardougne/handlers/MournerHQDoors.kt b/Server/src/main/content/region/kandarin/ardougne/westardougne/handlers/MournerHQDoors.kt new file mode 100644 index 0000000..2c540b0 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/westardougne/handlers/MournerHQDoors.kt @@ -0,0 +1,66 @@ +package content.region.kandarin.ardougne.westardougne.handlers + +import content.data.Quests +import content.region.kandarin.ardougne.quest.plaguecity.PlagueCity +// import core.api.hasAnItem +import core.api.isQuestComplete +import core.api.openDialogue +import core.api.teleport +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.global.action.DoorActionHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.npc.NPC +import core.game.world.map.Location +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs +// import org.rs09.consts.Items +import org.rs09.consts.Scenery + +class MournerHQDoors : InteractionListener { + + override fun defineListeners() { + class MournerHQDialogue : DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + npc = NPC(NPCs.MOURNER_347) + // todo check only the mourner gear is equipped + when (stage){ + START_DIALOGUE -> npcl(FacialExpression.ANNOYED, "Who are you? Go away!").also { stage = END_DIALOGUE } + // Wearing extra gear + /* + Mourner: You should know better than to wear non-regulation gear. + Player: Sorry, I'm new around here. + Mourner: Well, you know the drill - lose the gear, I will let it pass this time. + */ + } + + } + } + + // Front door + on(Scenery.DOOR_2036, IntType.SCENERY, "open"){ player, node-> + //todo after Mourning's End I is implemented make this check for wearing mourner gear + if(isQuestComplete(player, Quests.PLAGUE_CITY)){ + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } + else{ + openDialogue(player, MournerHQDialogue()) + } + return@on true + } + + on(Scenery.TRAPDOOR_8783, IntType.SCENERY, "open"){ player, _-> + // https://youtu.be/P-ns2kyvIGs?si=_DfI-V8KCyNoRtss&t=560 + //todo after Mourning's End II is implemented make this check for a New Key 6104 + // if(hasAnItem(player, Items.NEW_KEY_6104).exists()){ + teleport(player, Location.create(2044,4649, 0)) + //} + //else{ + // sendMessage(player, "The trapdoor appears locked") + //} + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/ardougne/westardougne/handlers/SarahsBox.kt b/Server/src/main/content/region/kandarin/ardougne/westardougne/handlers/SarahsBox.kt new file mode 100644 index 0000000..191c4dc --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/westardougne/handlers/SarahsBox.kt @@ -0,0 +1,38 @@ +package content.region.kandarin.ardougne.westardougne.handlers + +import content.data.Quests +import content.region.kandarin.ardougne.quest.plaguecity.PlagueCity +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.item.Item +import org.rs09.consts.Items +import org.rs09.consts.Scenery + +class SarahsBox : InteractionListener { + override fun defineListeners() { + + on(Scenery.BOX_2062, IntType.SCENERY, "open") { _, node -> + val box = node as core.game.node.scenery.Scenery + replaceScenery(box, Scenery.BOX_2063, -1) + return@on true + } + + on(Scenery.BOX_2063, IntType.SCENERY, "search"){ player, _ -> + if(isQuestComplete(player, Quests.PLAGUE_CITY)){ + if(hasSpaceFor(player, Item(Items.DOCTORS_GOWN_430)) && !hasAnItem(player, Items.DOCTORS_GOWN_430).exists()){ + sendMessage(player, "You find a medical gown in the box.") + addItem(player, Items.DOCTORS_GOWN_430) + return@on true + } + } + sendMessage(player, "You search the box but find nothing") + return@on true + } + + on(Scenery.BOX_2063, IntType.SCENERY, "close") { _, node -> + replaceScenery(node.asScenery(), Scenery.BOX_2062, -1) + return@on true + } + } +} diff --git a/Server/src/main/content/region/kandarin/ardougne/westardougne/handlers/WearMaskListener.kt b/Server/src/main/content/region/kandarin/ardougne/westardougne/handlers/WearMaskListener.kt new file mode 100644 index 0000000..7ed43f7 --- /dev/null +++ b/Server/src/main/content/region/kandarin/ardougne/westardougne/handlers/WearMaskListener.kt @@ -0,0 +1,42 @@ +package content.region.kandarin.ardougne.westardougne.handlers + +import content.data.Quests +import core.api.inBorders +import core.api.isQuestComplete +import core.api.openDialogue +import core.api.sendDialogue +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.interaction.InteractionListener +import core.tools.END_DIALOGUE +import org.rs09.consts.Items + +class WearMaskListener : InteractionListener { + override fun defineListeners() { + onUnequip(Items.GAS_MASK_1506){ player, _ -> + if (isQuestComplete(player, Quests.BIOHAZARD)){ + return@onUnequip true + } + else{ + if( + inBorders(player, 2511, 3266, 2556, 3334) || + inBorders(player, 2464, 3281, 2511, 3334) || + inBorders(player, 2461, 3281,2463, 3322) || + inBorders(player, 2435, 3307, 2463, 3322) + ){ + openDialogue(player, MaskChat()) + return@onUnequip false + } + return@onUnequip true + } + } + } +} + +class MaskChat : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + playerl(FacialExpression.WORRIED, "I should probably keep the gas mask on whilst I'm in West Ardougne.").also { stage = END_DIALOGUE } + } + +} + diff --git a/Server/src/main/content/region/kandarin/barcrawl/BarcrawlDialogue.java b/Server/src/main/content/region/kandarin/barcrawl/BarcrawlDialogue.java new file mode 100644 index 0000000..26f913e --- /dev/null +++ b/Server/src/main/content/region/kandarin/barcrawl/BarcrawlDialogue.java @@ -0,0 +1,96 @@ +package content.region.kandarin.barcrawl; + +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.plugin.Initializable; +import core.game.world.GameWorld; +import core.game.dialogue.DialogueInterpreter; +import core.game.dialogue.DialoguePlugin; + +/** + * The barcrawl diaogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class BarcrawlDialogue extends DialoguePlugin { + + /** + * The npc id being used. + */ + private BarcrawlType type; + + /** + * The npc id. + */ + private int npcId; + + /** + * Constructs a new {@code BarcrawlDialogue} {@code Object}. + * @param player the player. + */ + public BarcrawlDialogue(final Player player) { + super(player); + } + + /** + * Constructs a new {@code BarcrawlDialogue} {@code Object}. + */ + public BarcrawlDialogue() { + /** + * empty. + */ + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new BarcrawlDialogue(player); + } + + @Override + public boolean open(Object... args) { + npcId = (Integer) args[0]; + type = (BarcrawlType) args[1]; + player("I'm doing Alfred Grimhand's Barcrawl."); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npcId, null, type.getDialogue()[0]); + stage = type.getDialogue().length > 1 ? 1 : 2; + break; + case 1: + interpreter.sendDialogues(npcId, null, type.getDialogue()[1]); + stage++; + break; + case 2: + end(); + if (!player.getInventory().containsItem(type.getCoins())) { + break; + } + type.message(player, true); + player.getInventory().remove(type.getCoins()); + BarcrawlManager.getInstance(player).complete(type.ordinal()); + player.lock(6); + GameWorld.getPulser().submit(new Pulse(6, player) { + @Override + public boolean pulse() { + type.message(player, false); + type.effect(player); + return true; + } + }); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { DialogueInterpreter.getDialogueKey("barcrawl dialogue") }; + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/barcrawl/BarcrawlManager.java b/Server/src/main/content/region/kandarin/barcrawl/BarcrawlManager.java new file mode 100644 index 0000000..95f1a41 --- /dev/null +++ b/Server/src/main/content/region/kandarin/barcrawl/BarcrawlManager.java @@ -0,0 +1,186 @@ +package content.region.kandarin.barcrawl; + +import core.api.LoginListener; +import core.api.PersistPlayer; +import core.game.component.Component; +import core.game.node.entity.player.Player; + +import core.game.node.item.Item; +import org.jetbrains.annotations.NotNull; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; + +/** + * Manages the players barcrawl quest. + * @author 'Vexia + */ +public final class BarcrawlManager implements LoginListener, PersistPlayer { + + /** + * The barcrawl card. + */ + public static final Item BARCRAWL_CARD = new Item(455); + + /** + * The name of bars. + */ + public static final String[] NAMES = new String[] { "BlueMoon Inn", "Blueberry's Bar", "Dead Man's Chest", "Dragon Inn", "Flying Horse Inn", "Foresters Arms", "Jolly Boar Inn", "Karamja Spirits bar", "Rising Sun Inn", "Rusty Anchor Inn" }; + + /** + * The component used to draw the completed bars on. + */ + public static final Component COMPONENT = new Component(220); + + /** + * The player. + */ + private final Player player; + + /** + * The bars completed. + */ + private final boolean[] bars = new boolean[10]; + + /** + * If the quest has been started. + */ + private boolean started; + + /** + * Constructs a new {@code BarcrawlManager} {@code Object}. + * @param player the player. + */ + public BarcrawlManager(final Player player) { + this.player = player; + } + + public BarcrawlManager() {this.player = null;} + + @Override + public void login(@NotNull Player player) { + BarcrawlManager instance = new BarcrawlManager(player); + player.setAttribute("barcrawl-inst", instance); + } + + @Override + public void parsePlayer(@NotNull Player player, @NotNull JSONObject data) { + JSONObject bcData = (JSONObject) data.get("barCrawl"); + if(bcData == null) return; + JSONArray barsVisisted = (JSONArray) bcData.get("bars"); + BarcrawlManager instance = getInstance(player); + instance.started = (boolean) bcData.get("started"); + for(int i = 0; i < barsVisisted.size(); i++){ + instance.bars[i] = (boolean) barsVisisted.get(i); + } + } + + @Override + public void savePlayer(@NotNull Player player, @NotNull JSONObject save) { + BarcrawlManager instance = getInstance(player); + JSONObject barCrawl = new JSONObject(); + barCrawl.put("started", instance.started); + JSONArray barsVisited = new JSONArray(); + for(boolean visited : instance.bars) + barsVisited.add(visited); + barCrawl.put("bars",barsVisited); + save.put("barCrawl",barCrawl); + } + + /** + * Method used to read the card. + */ + public void read() { + if (isFinished()) { + player.getPacketDispatch().sendMessage("You are too drunk to be able to read the barcrawl card."); + ; + return; + } + player.getInterfaceManager().open(COMPONENT); + drawCompletions(); + } + + /** + * Draws the completed bars on the interface. + */ + private void drawCompletions() { + player.getPacketDispatch().sendString("The Official Alfred Grimhand Barcrawl!", 220, 1); + boolean complete; + for (int i = 0; i < bars.length; i++) { + complete = bars[i]; + player.getPacketDispatch().sendString((complete ? "" : "") + NAMES[i] + " - " + (complete ? "Complete!" : "Not Completed..."), 220, 3 + i); + } + } + + /** + * Completes a bar challenge. + * @param index the index. + */ + public void complete(int index) { + bars[index] = true; + } + + /** + * Checks if the barcrawl quest is completed. + * @return {@code True} if so. + */ + public boolean isFinished() { + for (int i = 0; i < bars.length; i++) { + if (!isCompleted(i)) { + return false; + } + } + return true; + } + + /** + * Resets the bars. + */ + public void reset() { + started = false; + for (int i = 0; i < bars.length; i++) { + bars[i] = false; + } + } + + /** + * Checks if a bar is completed. + * @param index the index. + * @return {@code True} if completed. + */ + public boolean isCompleted(int index) { + return bars[index]; + } + + /** + * Checks if the player has the card. + * @return the card. + */ + public boolean hasCard() { + return player.getInventory().containsItem(BARCRAWL_CARD) || player.getBank().containsItem(BARCRAWL_CARD); + } + + /** + * Gets the started. + * @return The started. + */ + public boolean isStarted() { + return started; + } + + /** + * Sets the started. + * @param started The started to set. + */ + public void setStarted(boolean started) { + this.started = started; + } + + public boolean[] getBars() { + return bars; + } + + public static BarcrawlManager getInstance(Player player) + { + return player.getAttribute("barcrawl-inst", new BarcrawlManager()); + } +} diff --git a/Server/src/main/content/region/kandarin/barcrawl/BarcrawlType.java b/Server/src/main/content/region/kandarin/barcrawl/BarcrawlType.java new file mode 100644 index 0000000..0ae18f6 --- /dev/null +++ b/Server/src/main/content/region/kandarin/barcrawl/BarcrawlType.java @@ -0,0 +1,357 @@ +package content.region.kandarin.barcrawl; + +import core.game.node.entity.combat.ImpactHandler; +import core.game.node.entity.player.Player; +import core.game.node.entity.skill.Skills; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.net.packet.PacketRepository; +import core.net.packet.context.CameraContext; +import core.net.packet.out.CameraViewPacket; +import core.tools.StringUtils; +import core.game.world.GameWorld; + +/** + * A barcrawl type npc. + * + * @author 'Vexia + * @version 1.0 + */ +public enum BarcrawlType { + BLUE_MOON(733, 50, "Uncle Humphrey's Gutrot", new String[]{"Oh no not another of you guys. These barbarian", "barcrawls cause too much damage to my bar."}, new String[]{"You're going to have to pay me 50 gold for the Uncle", "Humphrey's Gutrot."}) { + @Override + public void effect(final Player player) { + player.sendChat("Blearrgh!"); + player.getImpactHandler().manualHit(player, 1, ImpactHandler.HitsplatType.NORMAL); + addBonus(player, 1, Skills.ATTACK, Skills.DEFENCE, Skills.STRENGTH, Skills.SMITHING); + } + + @Override + public void message(final Player player, boolean start) { + if (!start) { + player.getPacketDispatch().sendMessages("Your insides feel terrible.", "The bartender signs your card."); + } else { + player.getPacketDispatch().sendMessages("You buy some " + getName() + ".", "You drink the " + getName() + "."); + } + } + }, + BLUEBERRY_BAR(848, 10, "Fire Toad Blast", new String[]{"Ah, you've come to the best stop on your list! I'll give", "you my famous Fire Toad last! It'll cost you 10", "coins."}) { + @Override + public void effect(final Player player) { + player.getImpactHandler().manualHit(player, 1, ImpactHandler.HitsplatType.NORMAL); + } + + @Override + public void message(final Player player, boolean start) { + if (!start) { + player.getPacketDispatch().sendMessage("Blueberry signs your card."); + } else { + super.message(player, start); + player.getPacketDispatch().sendMessage("Your mouth and throat burns as you gulp it down."); + } + } + + }, + DEADMAN_CHEST(735, 15, "Supergrog", new String[]{"Haha time to be breaking out the old Supergrog. That'll", "be 15 coins please."}) { + @Override + public void effect(final Player player) { + addBonus(player, 1, Skills.ATTACK, Skills.DEFENCE, Skills.HERBLORE, Skills.CONSTRUCTION, Skills.PRAYER); + } + + @Override + public void message(final Player player, boolean start) { + if (!start) { + player.getPacketDispatch().sendMessages("You stagger backwards.", "You think you see 2 bartenders signing 2 barcrawl cards."); + } else { + player.getPacketDispatch().sendMessages("The bartender serves you a glass of strange thick dark liquid.", "You wince and drink it."); + } + } + + }, + DRAGON_INN(739, 12, "Fire Brandy", new String[]{"I suppose you'll be wanting some Fire Brandy. That'll", "cost you 12 coins."}) { + @Override + public void effect(final Player player) { + addBonus(player, 1, Skills.ATTACK, Skills.DEFENCE); + } + + @Override + public void message(final Player player, boolean start) { + if (!start) { + player.getPacketDispatch().sendMessages("Your vision blurs and you stagger slightly.", "You can just about make out the bartender signing your barcrawl card."); + } else { + player.getPacketDispatch().sendMessages("The bartender hands you a small glass and sets light to the contents.", "You blow out the flame and drink it."); + } + } + + }, + FLYING_HORSE_INN(737, 8, "Heart Stopper", new String[]{"Fancy a bit of Heart Stopper then do you? It'll only be", "8 coins."}) { + @Override + public void effect(final Player player) { + player.getImpactHandler().manualHit(player, (int) (player.getSkills().getLevel(Skills.HITPOINTS) * 0.15), ImpactHandler.HitsplatType.NORMAL); + } + + @Override + public void message(final Player player, boolean start) { + if (!start) { + player.getPacketDispatch().sendMessages("You clutch your chest.", "Through your tears you see the bartender...", "signing your barcrawl card."); + } else { + player.getPacketDispatch().sendMessages("The bartender hands you a shot of Heart Stopper.", "You grimace and drink it."); + } + } + }, + FORESTERS_ARMS(738, 18, "Liverbane Ale", new String[]{"Oh you're a barbarian then. Now which of these barrels", "contained the Liverbane Ale? That'll be 18 coins please."}) { + @Override + public void effect(final Player player) { + addBonus(player, Skills.ATTACK, Skills.DEFENCE, Skills.FLETCHING, Skills.FIREMAKING, Skills.WOODCUTTING); + } + + @Override + public void message(final Player player, boolean start) { + if (!start) { + player.getPacketDispatch().sendMessages("The room seems to be swaying.", "The bartender scrawls his signature on your card."); + } else { + player.getPacketDispatch().sendMessages("The bartender gives you a glass of Liverbane Ale.", "You gulp it down."); + } + } + + }, + JOLLY_BOAR(731, 10, "Olde Suspiciouse", new String[]{"Ah, there seems to be a fair few doing that one these", "days. My supply of Olde suspiciouse is starting to run", "low, it'll cost you 10 coins."}) { + @Override + public void effect(final Player player) { + addBonus(player, 1, Skills.ATTACK, Skills.DEFENCE, Skills.STRENGTH, Skills.MINING, Skills.CRAFTING, Skills.MAGIC); + player.getImpactHandler().manualHit(player, 1, ImpactHandler.HitsplatType.NORMAL); + player.getDialogueInterpreter().sendDialogues(player, null, "Thanksh very mush..."); + } + + @Override + public void message(final Player player, boolean start) { + if (!start) { + player.getPacketDispatch().sendMessages("Your head is spinning.", "The bartender signs your card."); + } else { + player.getPacketDispatch().sendMessages("You buy a pint of Olde Suspiciouse.", "You gulp it down."); + } + } + }, + KARAMJA_SPIRITS(568, 7, "Ape Bite Liqueur", new String[]{"Ah, you'll be wanting some Ape Bite Liqueur then. It's", "got a lovely bannana taste, and it'll only cost you 7", "coins."}) { + @Override + public void effect(final Player player) { + addBonus(player, 1, Skills.ATTACK, Skills.DEFENCE); + } + + @Override + public void message(final Player player, boolean start) { + if (!start) { + player.getPacketDispatch().sendMessages("Zamo signs your card."); + player.getDialogueInterpreter().sendDialogues(player, null, "Mmmmm, dat was luverly..."); + } else { + player.getPacketDispatch().sendMessages("You buy some Ape Bite liqueur.", "You swirl it around and swallow it."); + } + } + + }, + RISING_SUNN_INN(new int[]{3217, 736}, 70, "Hand of Death Cocktail", new String[]{"Heehee, this'll be fun!"}, new String[]{"You'll be after our Hand of Death cocktail, then. Lots", "of expensive parts to the cocktail, though, so it will cost", "you 70 coins."}) { + @Override + public void effect(final Player player) { + addBonus(player, 1, Skills.ATTACK, Skills.DEFENCE, Skills.RANGE, Skills.FIREMAKING); + player.getImpactHandler().manualHit(player, 1, ImpactHandler.HitsplatType.NORMAL); + } + + @Override + public void message(final Player player, boolean start) { + if (!start) { + player.getPacketDispatch().sendMessages("The barmaid giggles.", "The barmaid signs your card."); + } else { + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraContext.CameraType.SHAKE, 4, 4, 1, 4, 4)); + GameWorld.getPulser().submit(new Pulse(3, player) { + @Override + public boolean pulse() { + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraContext.CameraType.RESET, 4, 4, 1, 4, 4)); + return true; + } + }); + player.getPacketDispatch().sendMessages("You buy a Hand of Death cocktail.", "You drink the cocktail.", "You stumble around the room."); + } + } + }, + RUSTY_ANCHOR_INN(734, 8, "Black Skull Ale", new String[]{"Okay, one Black Skull Ale coming up. Eight coins, please."}) { + @Override + public void effect(final Player player) { + player.sendChat("Hiccup!"); + } + + @Override + public void message(final Player player, boolean start) { + if (!start) { + super.message(player, start); + } else { + player.getPacketDispatch().sendMessages("You buy a Black Skull Ale...", "You drink your Black Skull Ale...", "Your vision blurs."); + } + } + }; + + /** + * The npc id. + */ + private final int[] npc; + + /** + * The name. + */ + private final String name; + + /** + * The coin required. + */ + private final Item coins; + + /** + * The dialogue to use. + */ + private final String[][] dialogue; + + /** + * Constructs a new {@code BarcrawlType} {@code Object}. + * + * @param npc the npc. + * @param name the name. + * @param coins the coins. + * @param dialogue the dialogue. + */ + private BarcrawlType(int npc, Item coins, String name, String[][] dialogue) { + this.npc = new int[]{npc}; + this.name = name; + this.coins = coins; + this.dialogue = dialogue; + } + + /** + * Constructs a new {@code BarcrawlType} {@code Object}. + * + * @param npc the npc. + * @param coins the coins. + */ + private BarcrawlType(int npc, int coins, final String name, String[] first, String[] second) { + this.npc = new int[]{npc}; + this.name = name; + this.coins = new Item(995, coins); + this.dialogue = new String[][]{first, second}; + } + + /** + * Constructs a new {@code BarcrawlType} {@code Object}. + * + * @param npc the npc. + * @param coins the coins. + * @param first the first dial. + * @param second the second dial. + */ + private BarcrawlType(int[] npc, int coins, String name, String[] first, String[] second) { + this.npc = npc; + this.name = name; + this.coins = new Item(995, coins); + this.dialogue = new String[][]{first, second}; + } + + /** + * Constructs a new {@code BarcrawlType} {@code Object}. + * + * @param npc the npc. + * @param coins the coins. + */ + private BarcrawlType(int npc, int coins, String name, String[] first) { + this.npc = new int[]{npc}; + this.name = name; + this.coins = new Item(995, coins); + this.dialogue = new String[][]{first}; + } + + /** + * Method used to effect the player. + * + * @param player the player. + */ + public void effect(final Player player) { + + } + + /** + * Method used to message the player. + * + * @param player the player. + * @param start or finish. + */ + public void message(final Player player, boolean start) { + if (!start) { + player.getPacketDispatch().sendMessage("The bartender signs your card."); + } else { + player.getPacketDispatch().sendMessage("You buy a " + (StringUtils.isPlusN(getName()) ? "an" : "a") + " " + getName() + "."); + } + } + + /** + * Method used to a skill bonus. + * + * @param player the player. + * @param amount the amount. + * @param skills the skills. + */ + public void addBonus(final Player player, int amount, final int... skills) { + for (int i : skills) { + player.getSkills().updateLevel(i, -amount, 0); + } + } + + /** + * Gets the bar crawl type. + * + * @param id the id. + * @return the type. + */ + public static BarcrawlType forId(int id) { + for (BarcrawlType type : values()) { + for (int npc : type.getNpc()) { + if (npc == id) { + return type; + } + } + } + return null; + } + + /** + * Gets the npc. + * + * @return The npc. + */ + public int[] getNpc() { + return npc; + } + + /** + * Gets the coins. + * + * @return The coins. + */ + public Item getCoins() { + return coins; + } + + /** + * Gets the dialogue. + * + * @return The dialogue. + */ + public String[][] getDialogue() { + return dialogue; + } + + /** + * Gets the name. + * + * @return The name. + */ + public String getName() { + return name; + } + +} diff --git a/Server/src/main/content/region/kandarin/catherby/dialogue/ArheinDialogue.kt b/Server/src/main/content/region/kandarin/catherby/dialogue/ArheinDialogue.kt new file mode 100644 index 0000000..3300e43 --- /dev/null +++ b/Server/src/main/content/region/kandarin/catherby/dialogue/ArheinDialogue.kt @@ -0,0 +1,188 @@ +package content.region.kandarin.catherby.dialogue +import core.api.* +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import core.tools.StringUtils +import org.rs09.consts.NPCs +import core.ServerStore +import core.game.dialogue.Topic +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import content.region.kandarin.seers.quest.merlinsquest.ArheinMCDialogue +import content.data.Quests + + +/** + * @author lila + */ + +/** + * Arhein dialogue + * This class handles all dialogue from the Catherby dock NPC Arhein. + * + * Arhein is relevant to: + * Merlin's Crystal quest + * crafting/glassmaking - via selling seaweed + * farming/supercompost - via selling pineapples + */ + +@Initializable +class ArheinDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin(player) { + + val limits = mapOf( + Items.PINEAPPLE_2114 to 40, + Items.SEAWEED_401 to 80 + ) + val period = "daily" + + // this function handles Arhein's specialty stock (pineapple and seaweed) transactions. + fun getGoods(requestedItem: Int, requestedAmount: Int): Int { + val price = 2 + val afford = player.getInventory().getAmount(Items.COINS_995) / price + var realamount = minOf(requestedAmount, afford) + val exactafford = (realamount == afford) && (afford == freeSlots(player) + 1) + realamount = minOf(realamount,if(exactafford) realamount else freeSlots(player)) + realamount = ServerStore.getNPCItemAmount(NPCs.ARHEIN_563, requestedItem, limits.getOrDefault(requestedItem,0), player, realamount, period) + if (removeItem(player, Item(Items.COINS_995, realamount * price), Container.INVENTORY)) { + if (addItem(player, requestedItem, realamount, Container.INVENTORY)) { + ServerStore.addNPCItemAmount(NPCs.ARHEIN_563, requestedItem, limits.getOrDefault(requestedItem,0), player, realamount, period) + return realamount + } + } + return 0 + } + // this function handles selecting which of the specialty stock items (pineapple or seaweed) to use. + fun selectGoods(requestedItem: Int) { + this.goods = requestedItem + this.stock = ServerStore.getNPCItemStock(NPCs.ARHEIN_563,this.goods,limits.getOrDefault(this.goods,0),player,period) + } + + // some class variables that handle the special stock (pineapples and seaweed) + private var goods = Items.PINEAPPLE_2114 + private var goodsMessage = "" + private var goodsName = "" + private var stock = 0 + + /** Arhein Dialogue Opener + * If the opener is called with nontrivial arguments, then this indicates that the player tried to board the ship without permission. + * In that case, Arhein tells the player to bugger off. + * Otherwise, start the normal dialogue. + * Before all this, we check and initialize some important information for Arhein's specialty stock. + */ + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + + if (args.size > 1) { + npcl(core.game.dialogue.FacialExpression.ANGRY, "Hey buddy! Get away from my ship alright?") + stage = 701 + } else { + npcl(core.game.dialogue.FacialExpression.HAPPY, "Hello! Would you like to trade? I've a variety of wares for sale!") + stage = 1 + } + return true + } + + /** Arhein Dialogue Handler + * Handler for the dialogue. the handler determines dialogue content and flow, + * as well as some specialty operations to handle special things like quest progress and specialty stock. + */ + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage) { + 1 -> showTopics( + Topic("Let's Trade.", 7), + Topic("I hear that you sell pineapples.",800), + Topic("I hear that you sell seaweed.",900), + Topic("No thank you.", END_DIALOGUE), + Topic("Is that your ship?", 100) + ) + 7 -> npc.openShop(player).also { stage = END_DIALOGUE } + 100 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "Yes, I use it to make deliveries to my customers up and down the coast. These crates here are all ready for my next trip.").also { stage++ } + 101 -> showTopics( + Topic("Where do you deliver to?",120), + Topic("Are you rich then?", 110), + Topic("Do you deliver to the fort just down the coast?",500) + ) + 110 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "Business is going reasonably well... I wouldn't say I was the richest of merchants ever, but I'm doing fairly well all things considered.").also { stage = END_DIALOGUE } + 120 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "Various places up and down the coast. Mostly Karamja and Port Sarim.").also { stage++ } + 121 -> showTopics( + Topic("I don't suppose I could get a lift anywhere?",140), + Topic("Well, good luck with your business.",130) + ) + 130 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Thanks buddy!").also { stage = END_DIALOGUE } + 140 -> npcl(core.game.dialogue.FacialExpression.GUILTY,"Sorry pal, but I'm afraid I'm not quite ready to sail yet.").also { stage++ } + 141 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL,"I'm waiting on a big delivery of candles which I need to deliver further along the coast.").also { stage = END_DIALOGUE } + 500 -> npcl(core.game.dialogue.FacialExpression.HALF_THINKING, "Yes, I do have orders to deliver there from time to time. I think I may have some bits and pieces for them when I leave here next actually.").also { + val queststage = player.questRepository.getStage(Quests.MERLINS_CRYSTAL) + if(queststage == 30 || queststage == 40) { + loadFile(ArheinMCDialogue(queststage)) + } else { + stage = END_DIALOGUE + } + } + 701 -> playerl(core.game.dialogue.FacialExpression.GUILTY,"Yeah... uh... sorry...").also{ stage = END_DIALOGUE } + 800 -> { + // Pineapples + selectGoods(Items.PINEAPPLE_2114) + // and now the conditional block to handle cases + if(stock==0) { + npcl(core.game.dialogue.FacialExpression.SAD,"Actually, I've run out. Come back tomorrow and I should have some more.") + stage = END_DIALOGUE + } else { + // approximately authentic dialogue prompt for buying pineapples from arhein. (closest known dialogues do not make grammatical sense when spliced.) + this.goodsMessage = "I certainly do! I've got ${stock} in stock, going for 2 coins each. How many would you like?" + npcl(core.game.dialogue.FacialExpression.HAPPY,this.goodsMessage) + this.goodsName = if(stock==1) getItemName(this.goods) else StringUtils.plusS(getItemName(this.goods)) + stage = 1200 + } + } + 900 -> { + // Seaweed + selectGoods(Items.SEAWEED_401) + // and now the conditional block to handle cases + if(stock==0) { + npcl(core.game.dialogue.FacialExpression.SAD,"Actually, I've run out. Come back tomorrow and I should have some more.") + stage = END_DIALOGUE + } else { + // approximately authentic dialogue prompt for buying seaweed from arhein. (closest known dialogues do not make grammatical sense when spliced.) + this.goodsMessage = "I certainly do! I've ${stock} at the moment and they cost 2 coins each. How many would you like?" + npcl(core.game.dialogue.FacialExpression.HAPPY,this.goodsMessage) + this.goodsName = getItemName(this.goods) + stage = 1200 + } + } + 1200 -> { + // arhein specialty items sales + val goodsPrompt = "Arhein has ${this.stock} ${this.goodsName}. How many would you like to buy?" + sendInputDialogue(player,InputType.AMOUNT, goodsPrompt) { value -> + val amountReceived = getGoods(this.goods,Integer.parseInt(value.toString())) + var exitMsg = "" + if(amountReceived==this.stock) { + exitMsg = "Here you go! I've run out for now. Come again tomorrow and I should have more." + } else if (amountReceived>0) { + // inauthentic exit dialogue for arhein's pineapple/seaweed sales. documented dialogue that i found indicates that there is no exit message. + // i kept the spirit of arhein's personality, using "buddy!" that is known from another line. + exitMsg = "Here you go, buddy!" + } else { + // same deal here, inauthentic exit dialogue based on arhein's authentic personality. + exitMsg = "Take care, buddy!" + } + npcl(core.game.dialogue.FacialExpression.HAPPY,exitMsg) + } + stage = END_DIALOGUE + } + } + return true + } + + + // finale funz - newInstance, getIds + override fun newInstance(player: Player?): core.game.dialogue.DialoguePlugin { + return ArheinDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.ARHEIN_563) + } +} + diff --git a/Server/src/main/content/region/kandarin/catherby/dialogue/HarryDialogue.java b/Server/src/main/content/region/kandarin/catherby/dialogue/HarryDialogue.java new file mode 100644 index 0000000..1ecf54b --- /dev/null +++ b/Server/src/main/content/region/kandarin/catherby/dialogue/HarryDialogue.java @@ -0,0 +1,237 @@ +package content.region.kandarin.catherby.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import org.rs09.consts.Items; +import core.game.node.entity.npc.NPC; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the dialogue plugin used for the harry npc. + * + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class HarryDialogue extends DialoguePlugin { + private final static int FISHBOWL_EMPTY = Items.FISHBOWL_6667; + private final static int FISHBOWL_WATER = Items.FISHBOWL_6668; + private final static int FISHBOWL_SEAWEED = Items.FISHBOWL_6669; + + private final static int FISHBOWL_BLUE = Items.FISHBOWL_6670; + private final static int FISHBOWL_GREEN = Items.FISHBOWL_6671; + private final static int FISHBOWL_SPINE = Items.FISHBOWL_6672; + + private final static int TINY_NET = Items.TINY_NET_6674; + + /** + * Constructs a new {@code HarryDialogue} {@code Object}. + */ + public HarryDialogue() { + } + + /** + * Constructs a new {@code HarryDialogue} {@code Object}. + * + * @param player the player. + */ + public HarryDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new HarryDialogue(player); + } + + private boolean needsFish() { + return player.getInventory().containsAtLeastOneItem(FISHBOWL_SEAWEED); + } + + private boolean needsSeaWeed() { + return player.getInventory().containsAtLeastOneItem(FISHBOWL_WATER); + } + + private boolean needsFood() { + return player.getInventory().containsAtLeastOneItem(new int[] {FISHBOWL_SEAWEED, FISHBOWL_BLUE, FISHBOWL_GREEN, FISHBOWL_SPINE}); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Welcome! You can buy Fishing equipment at my store.", "We'll also give you a good price for any fish that you", "catch."); + if (needsFish() || needsSeaWeed()) { + stage = 10; + } else if (needsFood()) { + stage = 20; + } else { + stage = 0; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 999: + end(); + break; + case 0: + options("Let's see what you've got, then.", "Sorry, I'm not interested."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + player("Let's see what you've got, then."); + stage++; + break; + case 2: + player("Sorry, I'm not interested."); + stage = 999; + break; + } + break; + case 2: + end(); + npc.openShop(player); + break; + case 10: + options("Let's see what you've got, then.", "Can I get a fish for this bowl?", "Do you have any fishfood?", "Sorry, I'm not interested."); + stage++; + break; + case 11: + switch (buttonId) { + case 1: + player("Let's see what you've got, then."); + stage = 2; + break; + case 2: + player("Can I get a fish for this bowl?"); + stage = 30; + break; + case 3: + player("Do you have any fishfood?"); + stage = 40; + break; + case 4: + player("Sorry, I'm not interested."); + stage = 999; + break; + } + break; + case 20: + options("Let's see what you've got, then.", "Do you have any fishfood?", "Sorry, I'm not interested."); + stage++; + break; + case 21: + switch (buttonId) { + case 1: + player("Let's see what you've got, then."); + stage = 2; + break; + case 2: + player("Do you have any fishfood?"); + stage = 40; + break; + case 3: + player("Sorry, I'm not interested."); + stage = 999; + break; + } + break; + case 30: + if (!needsFish()) { // ergo, needsSeaWeed() == true + npc("Sorry, you need to put some seaweed into the bowl", "first."); + stage++; + } else { + npc("Yes you can!"); + stage = 33; + } + break; + case 31: + player("Seaweed?"); + stage++; + break; + case 32: + npc("Yes, the fish seem to like it. Come and see me when", "you have put some in the bowl."); + stage = 999; + break; + case 33: + npc("I can see that you have a nicely filled fishbowl there to", "use, and you can catch a fish from my aquarium if", "you want."); + stage++; + break; + case 34: + npc("You will need a special net to do this though, and I sell", "them for 10 gold."); + stage++; + break; + case 35: + options("I'll take it!", "No thanks, later maybe");//[sic] no punctuation on last option + stage++; + break; + case 36: + switch (buttonId) { + case 1: + player("I'll take it!"); + stage++; + break; + case 2: + player("No thanks, later maybe"); + stage = 999; + break; + } + break; + case 37: + if (player.getInventory().getAmount(995) >= 10) { + if (!player.getInventory().hasSpaceFor(new Item(TINY_NET))) { + npc("Here you... oh."); + stage = 38; + } else { + npc("Here you go!"); + if (player.getInventory().remove(new Item(995, 10))) { + player.getInventory().add(new Item(TINY_NET)); + player.getPacketDispatch().sendMessage("Harry sells you a tiny net!"); + } + stage = 999; + } + } else { + npc("Well, I'll be happy to give you the net once you", "have the cash, but not before!"); + stage = 999; + } + break; + case 38: + npc("Well, you don't seem to have any free space for", "this right now. Come back later when you do."); + stage = 999; + break; + case 40: + npc("Sorry, I'm all out. I used up the last of it feeding the", "fish in the aquarium."); + stage++; + break; + case 41: + npc("I have some empty boxes though, they have the", "ingredients written on the back. I'm sure if you pick up", "a pestle and mortar you will be able to make your own."); + stage++; + break; + case 42: + npc("Here. I can hardly charge you for an empty box."); + player.getInventory().add(new Item(Items.AN_EMPTY_BOX_6675)); + if (needsFood() && !needsSeaWeed()) { + stage++; + } else { + stage = 999; + } + break; + case 43: + npc("Take good care of that fish!"); + stage = 999; + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[]{576}; + } +} diff --git a/Server/src/main/content/region/kandarin/catherby/dialogue/HicktonDialogue.java b/Server/src/main/content/region/kandarin/catherby/dialogue/HicktonDialogue.java new file mode 100644 index 0000000..b0c0103 --- /dev/null +++ b/Server/src/main/content/region/kandarin/catherby/dialogue/HicktonDialogue.java @@ -0,0 +1,128 @@ +package content.region.kandarin.catherby.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.global.Skillcape; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the hickton dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class HicktonDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code HicktonDialogue} {@code Object}. + */ + public HicktonDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code HicktonDialogue} {@code Object}. + * @param player the player. + */ + public HicktonDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new HicktonDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Welcome to Hickton's Archery Emporium. Do you", "want to see my wares?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + if (Skillcape.isMaster(player, Skills.FLETCHING)) { + interpreter.sendOptions("Select an Option", "Can I buy a Skillcape of Fletching?", "Yes, please.", "No, I prefer to bash things close up."); + stage = 100; + } else { + interpreter.sendOptions("Select an Option", "Yes, please.", "No, I prefer to bash things close up."); + stage = 1; + } + break; + case 1: + switch (buttonId) { + case 1: + end(); + npc.openShop(player); + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.EVIL_LAUGH, "No, I prefer to bash things close up."); + stage = 20; + break; + } + break; + case 20: + end(); + break; + case 100: + switch (buttonId) { + case 1: + player("Can I buy a Skillcape of Fletching?"); + stage = -99; + break; + case 2: + end(); + npc.openShop(player); + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.EVIL_LAUGH, "No, I prefer to bash things close up."); + stage = 20; + break; + } + break; + case -99: + npc("You will have to pay a fee of 99,000 gp."); + stage = 101; + break; + case 101: + options("Yes, here you go.", "No, thanks."); + stage = 102; + break; + case 102: + switch (buttonId) { + case 1: + player("Yes, here you go."); + stage = 103; + break; + case 2: + end(); + break; + } + break; + case 103: + if (Skillcape.purchase(player, Skills.FLETCHING)) { + npc("There you go! Enjoy."); + } + stage = 104; + break; + case 104: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 575 }; + } +} diff --git a/Server/src/main/content/region/kandarin/catherby/dialogue/VanessaDialogue.java b/Server/src/main/content/region/kandarin/catherby/dialogue/VanessaDialogue.java new file mode 100644 index 0000000..f1ed25b --- /dev/null +++ b/Server/src/main/content/region/kandarin/catherby/dialogue/VanessaDialogue.java @@ -0,0 +1,77 @@ +package content.region.kandarin.catherby.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Handles the VanessaDialogue dialogue. + * @author 'Vexia + */ +@Initializable +public class VanessaDialogue extends DialoguePlugin { + + public VanessaDialogue() { + + } + + public VanessaDialogue(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[] { 2305 }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "What are you selling?", "Can you give me any Farming advice?", "I'm okay, thank you."); + stage = 10; + break; + case 10: + switch (buttonId) { + case 1: + end(); + npc.openShop(player); + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_ASKING, "Can you give me any Farming advice?"); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.FRIENDLY, "I'm okay, thank you."); + stage = 30; + break; + + } + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Yes - ask a gardener."); + stage = 30; + break; + case 30: + end(); + break; + } + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new VanessaDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Hello. How can I help you?"); + stage = 0; + return true; + } +} diff --git a/Server/src/main/content/region/kandarin/dialogue/AstronomyBook.kt b/Server/src/main/content/region/kandarin/dialogue/AstronomyBook.kt new file mode 100644 index 0000000..80df6aa --- /dev/null +++ b/Server/src/main/content/region/kandarin/dialogue/AstronomyBook.kt @@ -0,0 +1,130 @@ +package content.region.kandarin.dialogue + +import content.global.handlers.iface.BookInterface +import content.global.handlers.iface.BookLine +import content.global.handlers.iface.Page +import content.global.handlers.iface.PageSet +import core.ServerConstants +import core.api.setAttribute +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items + +@Initializable +class AstronomyBook : InteractionListener { + companion object { + private val TITLE = "The tales of Scorpius" + private val CONTENTS = arrayOf( + PageSet( + Page( + BookLine("A History of Astronomy", 55), + BookLine("in ${ServerConstants.SERVER_NAME}.", 56), + BookLine("", 57), + BookLine("At the start of the 4th age,", 58), + BookLine("a learned man by the", 59), + BookLine("name of Scorpius, known well", 60), + BookLine("for his powers of vision and", 61), + BookLine("magic, sought communion with", 62), + BookLine("the gods of the world.", 63), + BookLine("So many unanswered questions", 64), + BookLine("had he that devoted his entire", 65), + ), + Page( + BookLine("life to this cause.", 66), + BookLine("After many years of study,", 67), + BookLine("seeking knowledge from the", 68), + BookLine("wise of that time, he developed", 69), + BookLine("a machine infused with", 70), + BookLine("magical power, infused with", 71), + BookLine("the ability to pierce", 72), + BookLine("into the heavens - a huge eye", 73), + BookLine("that gave the user", 74), + BookLine("incredible site, like never", 75), + BookLine("seen before.", 76), + ) + ), + PageSet( + Page( + BookLine("As time passed, Scorpius", 55), + BookLine("grew adept at using his", 56), + BookLine("specialized skills, and followed", 57), + BookLine("the movements of stars", 58), + BookLine("in ${ServerConstants.SERVER_NAME}, which are", 59), + BookLine("mapped and named, and still", 60), + BookLine("used to this day.", 61), + BookLine("", 62), + BookLine("Before long, Scorpius", 63), + BookLine("used his knowledge", 64), + BookLine("for predicting the future,", 65), + ), + Page( + BookLine("and, in turn, he called upon", 66), + BookLine("the dark knowledge of", 67), + BookLine("Zamorakian worshipers", 68), + BookLine("to further his cause. Living", 69), + BookLine("underground, the followers", 70), + BookLine("of the dark god remained", 71), + BookLine("until the civilization of", 72), + BookLine("Ardougne grew in strength", 73), + BookLine("and control.", 74), + ) + ), + PageSet( + Page( + BookLine("The kings of that time", 55), + BookLine("worked to banish the", 56), + BookLine("Zamorakian followers in", 57), + BookLine("the area, hiding all", 58), + BookLine("reference to Scorpius's", 59), + BookLine("invention, due to", 60), + BookLine("its 'evil nature'.", 61), + BookLine("", 62), + BookLine("Years later, when the", 63), + BookLine("minds of the kings lent", 64), + BookLine("more towards the research", 65), + ), + Page( + BookLine("of the unknown, the plans", 66), + BookLine("of Scorpius were uncovered", 67), + BookLine("and the heavenly eye", 68), + BookLine("constructed again. Since then,", 69), + BookLine("many have studied the ways of", 70), + BookLine("the astronomer, Scorpius", 71), + BookLine("and in his memory a grave", 72), + BookLine("was constructed near the", 73), + BookLine("Observatory. Some claim his", 74), + BookLine("ghost still wanders nearby,", 75), + BookLine("in torment as he seeks", 76), + ) + ), + PageSet( + Page( + BookLine("the secrets of the heavens", 55), + BookLine("that can never be solved.", 56), + BookLine("Tales tell that he will", 57), + BookLine("grant those adept in the", 58), + BookLine("arts of the astronomer a", 59), + BookLine("blessing of unusual power.", 60), + BookLine("", 61), + BookLine("Here ends the tale of", 62), + BookLine("how astronomy entered", 63), + BookLine("the known world.", 64), + ) + ), + ) + } + + private fun display(player: Player, pageNum: Int, buttonID: Int): Boolean { + BookInterface.pageSetup(player, BookInterface.FANCY_BOOK_3_49, TITLE, CONTENTS) + return true + } + + override fun defineListeners() { + on(Items.ASTRONOMY_BOOK_600, IntType.ITEM, "read") { player, _ -> + BookInterface.openBook(player, BookInterface.FANCY_BOOK_3_49, ::display) + return@on true + } + } +} diff --git a/Server/src/main/content/region/kandarin/dialogue/BindingBook.kt b/Server/src/main/content/region/kandarin/dialogue/BindingBook.kt new file mode 100644 index 0000000..3318d90 --- /dev/null +++ b/Server/src/main/content/region/kandarin/dialogue/BindingBook.kt @@ -0,0 +1,149 @@ +package content.region.kandarin.dialogue + +import content.global.handlers.iface.BookInterface +import content.global.handlers.iface.BookLine +import content.global.handlers.iface.Page +import content.global.handlers.iface.PageSet +import core.api.setAttribute +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items + +@Initializable +class BindingBook : InteractionListener { + companion object { + private val TITLE = "Book of Binding" + private val CONTENTS = arrayOf( + PageSet( + Page( + BookLine(" Book of Binding:", 60), + BookLine(" A treatise on Demons", 61), + ), + Page( + BookLine("", 67), + BookLine(" -- Indexo --", 68), + BookLine(" Arcana: I", 71), + BookLine(" Instructo: II", 72), + BookLine(" Defeati: III", 73), + BookLine(" Enchanto: IIII", 74), + ) + ), + PageSet( + Page( + BookLine("Arcana I: Use holy water to", 55), + BookLine("determine possession. Slight", 56), + BookLine("appearance changes may be", 57), + BookLine("perceived when doused.", 58), + BookLine("", 59), + BookLine("Legendary Silverlight will help", 60), + BookLine("to defeat any demon by", 61), + BookLine("weakening it.", 62), + ), + Page( + BookLine("Arcana II: Be wary of any", 66), + BookLine("demon, it may have special", 67), + BookLine("forms of attack.", 68), + BookLine("", 69), + BookLine("Use an Octagram of fire", 70), + BookLine("to confine unearthly", 71), + BookLine("creatures of the underworld", 72), + BookLine("- the perfect geometry", 73), + BookLine("confuses them.", 74), + BookLine("", 75), + BookLine("Eximus", 76), + ) + ), + PageSet( + Page( + BookLine("Instructo: Creation of holy", 55), + BookLine("water must be undertaken", 56), + BookLine("with determination and urgency.", 57), + BookLine("", 58), + BookLine("Take to yourself empty vials", 59), + BookLine("free of all liquids.", 60), + BookLine("", 61), + BookLine("Read warily the enchantment", 62), + BookLine("contained here within in order", 63), + BookLine("to magick the vial", 64), + ), + Page( + BookLine("for the holding of holy or", 66), + BookLine("sacred water.", 67), + BookLine("", 68), + BookLine("Take utmost care as you", 69), + BookLine("enchant them. With great care", 70), + BookLine("and precision place the sacred", 71), + BookLine("water into the magicked vial", 73), + BookLine("and stopper it.", 74), + BookLine("", 75), + BookLine("Eximus", 76), + ) + ), + PageSet( + Page( + BookLine("Defeati... Ye dreaded", 55), + BookLine("demon will be of unholy", 56), + BookLine("power and abilities.", 57), + BookLine("", 58), + BookLine("Present thyself before", 59), + BookLine("the possessed with good", 60), + BookLine("intent and ready manner.", 61), + BookLine("", 62), + BookLine("With least obstruction", 63), + BookLine("and utmost solemnity hold", 64), + BookLine("open the pages of this", 65), + ), + Page( + BookLine("great tome in order that", 66), + BookLine("the goodlight falls upon", 67), + BookLine("the victim completely.", 68), + BookLine("Be thee prepared in every", 69), + BookLine("capacity, for the demon's", 70), + BookLine("tricks and wiles will outwit", 71), + BookLine("the unready man. Attack with", 72), + BookLine("vigour and zest if thee hopes", 73), + BookLine("to see another day.", 74), + BookLine("", 75), + BookLine("Eximus", 76), + ) + ), + PageSet( + Page( + BookLine("Enchanto...", 55), + BookLine("", 56), + BookLine("Possessus valius emptious,", 57), + BookLine("projectus spellicus avoir valius", 58), + BookLine("magicus.", 59), + BookLine("", 60), + BookLine("Castus enchant avoir createur", 61), + BookLine("valius magicus holious avour", 62), + BookLine("defeati Demonicus Absolutus.", 63), + BookLine("", 64), + BookLine("Demonicus Absolutus.", 65), + ), + Page( + BookLine("Extralias projectus Magicus", 66), + BookLine("Holarius Attackanie demonicus", 67), + BookLine("Absolutus distancie airus", 68), + BookLine("throwus armiues.", 69), + BookLine("", 70), + BookLine("Eximus", 71), + ) + ), + ) + } + + private fun display(player: Player, pageNum: Int, buttonID: Int): Boolean { + BookInterface.pageSetup(player, BookInterface.FANCY_BOOK_3_49, TITLE, CONTENTS) + return true + } + + override fun defineListeners() { + on(Items.BINDING_BOOK_730, IntType.ITEM, "read") { player, _ -> + BookInterface.openBook(player, BookInterface.FANCY_BOOK_3_49, ::display) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/dialogue/EniolaDialogue.kt b/Server/src/main/content/region/kandarin/dialogue/EniolaDialogue.kt new file mode 100644 index 0000000..de5a3e3 --- /dev/null +++ b/Server/src/main/content/region/kandarin/dialogue/EniolaDialogue.kt @@ -0,0 +1,167 @@ +package content.region.kandarin.dialogue + +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.IronmanMode +import core.plugin.Initializable +import org.rs09.consts.Components +import org.rs09.consts.NPCs +import core.game.dialogue.Topic +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE + +@Initializable +class EniolaDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + START_DIALOGUE -> if (hasIronmanRestriction(player, IronmanMode.ULTIMATE)) { + npcl( + FacialExpression.NEUTRAL, + "My apologies, dear ${if (player.isMale) "sir" else "madam"}, " + + "our services are not available for Ultimate ${if (player.isMale) "Ironmen" else "Ironwomen"}." + ).also { stage = END_DIALOGUE } + } + else { + npcl( + FacialExpression.NEUTRAL, + "Good day, how may I help you?" + ).also { + if (hasAwaitingGrandExchangeCollections(player)) { + stage++ + } else { + stage += 2 + } + } + } + + 1 -> npcl( + FacialExpression.NEUTRAL, + "Before we go any further, I should inform you that you " + + "have items ready for collection from the Grand Exchange." + ).also { stage++ } + + 2 -> playerl(FacialExpression.ASKING, "Who are you?") + .also { stage++ } + + 3 -> npcl( + FacialExpression.NEUTRAL, + "How frightfully rude of me, my dear ${if (player.isMale) "sir" else "lady"}. " + + "My name is Eniola and I work for that excellent enterprise, the Bank of Gielinor." + ).also { stage++ } + + 4 -> showTopics( + Topic(FacialExpression.HALF_THINKING, "If you work for the bank, what are you doing here?", 10), + Topic(FacialExpression.NEUTRAL, "I'd like to access my bank account, please.", 30), + Topic(FacialExpression.NEUTRAL, "I'd like to check my PIN settings.", 31), + Topic(FacialExpression.NEUTRAL, "I'd like to see my collection box.", 32), + Topic(FacialExpression.NEUTRAL, "Never mind.", END_DIALOGUE) + ) + + 10 -> npcl( + FacialExpression.NEUTRAL, + "My presence here is the start of a new enterprise of travelling banks. " + + "I, and others like me, will provide you with the convenience of having " + + "bank facilities where they will be of optimum use to you." + ).also { stage++ } + + 11 -> playerl( + FacialExpression.ASKING, + "So... What are you doing here?" + ).also { stage++ } + + 12 -> npcl( + FacialExpression.HALF_GUILTY, + "The Z.M.I. - that is - the Zamorakian Magical Institute, required my services " + + "upon discovery of this altar." + ).also { stage++ } + + 13 -> npcl( + FacialExpression.HALF_GUILTY, + "We at the Bank of Gielinor are a neutral party and are willing to offer our " + + "services regardless of affiliation. So that is why I am here." + ).also { stage++ } + + 14 -> playerl( + FacialExpression.ASKING, + "Can I access my bank account by speaking to you?" + ).also { stage++ } + + 15 -> npcl( + FacialExpression.NEUTRAL, + "Of course, dear ${if (player.isMale) "sir" else "lady"}. However, I must inform you " + + "that because the Z.M.I. are paying for my services, they require anyone not part of " + + "the Institute to pay an access fee to open their bank account." + ).also { stage++ } + + 16 -> npcl( + FacialExpression.NEUTRAL, + "But, as our goal as travelling bankers is to make our customers' lives more convenient, " + + "we have accomodated to your needs." + ).also { stage++ } + + 17 -> npcl( + FacialExpression.NEUTRAL, + "We know you will be busy creating runes and do not wish " + + "to carry money with you." + ).also { stage++ } + + 18 -> npcl( + FacialExpression.NEUTRAL, + "The charge to open your account is the small amount of twenty of one type of rune. " + + "The type of rune is up to you." + ).also { stage++ } + + 19 -> npcl( + FacialExpression.HALF_ASKING, + "Would you like to pay the price of twenty runes to open " + + "your bank account?" + ).also { stage++ } + + 20 -> showTopics( + Topic(FacialExpression.NEUTRAL, "Yes, please.", 30), + Topic(FacialExpression.SUSPICIOUS, "Let me open my account and then I'll give you the runes.", 21), + Topic(FacialExpression.ANNOYED, "No way! I'm not paying to withdraw my own stuff.", 22) + ) + + 21 -> npcl( + FacialExpression.NEUTRAL, + "It's not that I don't trust you, old ${if (player.isMale) "chap" else "girl"}, " + + "but as the old adage goes: 'Payment comes before friends'." + ).also { stage = END_DIALOGUE } + + 22 -> npcl( + FacialExpression.NEUTRAL, + "I'm sorry to hear that, dear ${if (player.isMale) "sir" else "madam"}. " + ).also { stage++ } + + 23 -> npcl( + FacialExpression.NEUTRAL, + "Should you reconsider, because I believe this service offers excellent " + + "value for the price, do not hesitate to contact me." + ).also { stage = END_DIALOGUE } + + 30 -> { + setAttribute(player, "zmi:bankaction", "open") + openInterface(player, Components.BANK_CHARGE_ZMI_619) + end() + } + + 31 -> { + openBankPinSettings(player) + end() + } + + 32 -> { + setAttribute(player, "zmi:bankaction", "collect") + openInterface(player, Components.BANK_CHARGE_ZMI_619) + end() + } + } + + return true + } + + override fun getIds(): IntArray = intArrayOf(NPCs.ENIOLA_6362) +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/dialogue/EniolaListener.kt b/Server/src/main/content/region/kandarin/dialogue/EniolaListener.kt new file mode 100644 index 0000000..9a7656d --- /dev/null +++ b/Server/src/main/content/region/kandarin/dialogue/EniolaListener.kt @@ -0,0 +1,37 @@ +package content.region.kandarin.dialogue + +import core.api.openInterface +import core.api.restrictForIronman +import core.api.setAttribute +import core.game.node.entity.player.link.IronmanMode +import org.rs09.consts.Components +import org.rs09.consts.NPCs +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +/** + * Handles special banking interactions for Eniola at ZMI altar area. + * + * @author vddCore + */ +class EniolaListener : InteractionListener { + override fun defineListeners() { + on(NPCs.ENIOLA_6362, IntType.NPC, "bank") { player, _ -> + restrictForIronman(player, IronmanMode.ULTIMATE) { + setAttribute(player, "zmi:bankaction", "open") + openInterface(player, Components.BANK_CHARGE_ZMI_619) + } + + return@on true + } + + on(NPCs.ENIOLA_6362, IntType.NPC, "collect") { player, _ -> + restrictForIronman(player, IronmanMode.ULTIMATE) { + setAttribute(player, "zmi:bankaction", "collect") + openInterface(player, Components.BANK_CHARGE_ZMI_619) + } + + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/dialogue/GalahadDialogue.java b/Server/src/main/content/region/kandarin/dialogue/GalahadDialogue.java new file mode 100644 index 0000000..f7ab01f --- /dev/null +++ b/Server/src/main/content/region/kandarin/dialogue/GalahadDialogue.java @@ -0,0 +1,79 @@ +package content.region.kandarin.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.plugin.Initializable; +import org.rs09.consts.Items; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.item.Item; + +/** + * Handles the Galahad dialogue + * @author afaroutdude + */ +@Initializable +public class GalahadDialogue extends DialoguePlugin { + + /** + * Represnets the bow item. + */ + private final Item TEA = new Item(Items.CUP_OF_TEA_712); + + public GalahadDialogue() {} + + public GalahadDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new GalahadDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + npc("Welcome to my home. It's rare for me to have guests!", "Would you like a cup of tea? I'll just put the kettle on."); + stage = 2; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 999: + end(); + break; + case 2: + sendDialogue("Brother Galahad hangs a kettle over the fire."); + stage++; + break; + case 3: + // This stage seems to break off based on the quest Holy Grail + // https://www.youtube.com/watch?v=XPTkSDyKpWs + player("Do you get lonely out here on your own?"); + stage++; + break; + case 4: + npc("Sometimes I do, yes. Still not many people to share my", + "solidarity with, as most of the religious men around here", + "are worshippers of Saradomin. Half a moment, your cup", + "of tea is ready."); + stage++; + break; + case 5: + sendDialogue("Brother Galahad gives you a cup of tea."); + player.getInventory().add(TEA); + player.getAchievementDiaryManager().finishTask(player, DiaryType.SEERS_VILLAGE, 0, 2); + stage = 999; + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 218 }; + } +} diff --git a/Server/src/main/content/region/kandarin/dialogue/GiannesCookBook.kt b/Server/src/main/content/region/kandarin/dialogue/GiannesCookBook.kt new file mode 100644 index 0000000..e663c99 --- /dev/null +++ b/Server/src/main/content/region/kandarin/dialogue/GiannesCookBook.kt @@ -0,0 +1,338 @@ +package content.region.kandarin.dialogue + +import content.global.handlers.iface.BookInterface +import content.global.handlers.iface.BookLine +import content.global.handlers.iface.Page +import content.global.handlers.iface.PageSet +import core.api.setAttribute +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items + +@Initializable +class GiannesCookBook : InteractionListener { + companion object { + private val TITLE = "Gianne's cook book" + private val CONTENTS = arrayOf( + PageSet( + Page( + BookLine("Chocolate Bomb", 55), + BookLine("", 56), + BookLine("Knead a ball of Gianne", 57), + BookLine("dough into a gnomebowl mould.", 58), + BookLine("Bake this briefly. Decadently", 59), + BookLine("add four bars of chocolate", 60), + BookLine("to the bowl and top with", 61), + BookLine("one sprig of equa leaves.", 62), + BookLine("Bake the bowl in the oven", 63), + BookLine("to melt the chocolate.", 64), + BookLine("Then mix in two big dollops", 65), + ), + Page( + BookLine("of cream and finally sprinkle", 66), + BookLine("chocolate dust all over.", 67), + BookLine("Chocolate is a relatively", 68), + BookLine("recent cooking ingredient", 69), + BookLine("for gnomes, having been", 70), + BookLine("imported from human lands.", 71), + ) + ), + PageSet( + Page( + BookLine("Tangled Toad's Legs", 55), + BookLine("", 56), + BookLine("Shape a portion of fresh Gianne", 57), + BookLine("dough into a gnomebowl mould.", 58), + BookLine("Bake this until it is", 59), + BookLine("slightly springy.", 60), + BookLine("Add to the bowl...", 61), + BookLine("", 62), + BookLine("4 pairs of toad's legs", 63), + BookLine("2 portions of cheese", 64), + BookLine("2 sprigs of equa leaves", 65), + ), + Page( + BookLine("2 dashes of gnome spice", 66), + BookLine("1 bunch of dwellberries.", 67), + BookLine("", 68), + BookLine("Bake the dish in the oven", 69), + BookLine("once more prior to serving.", 70), + BookLine("Tangled Toads Legs was", 71), + BookLine("a special dish created", 72), + BookLine("by gnome chef Deelie to", 73), + BookLine("celebrate the first ", 74), + BookLine("Healthorg the Great Day.", 75), + ) + ), + PageSet( + Page( + BookLine("Worm Hole", 55), + BookLine("", 56), + BookLine("Starting with a gnomebowl", 57), + BookLine("mould, shape a portion of", 58), + BookLine("fresh Gianne dough into a", 59), + BookLine("rough bowl. Bake this", 60), + BookLine("until it is firm to the", 61), + BookLine("touch. Add to the bowl", 62), + BookLine("four king worms, two onions", 63), + BookLine("and a dash of gnome spices.", 64), + BookLine("Bake the bowl in the", 65), + ), + Page( + BookLine("oven once more.", 66), + BookLine("To finish the dish simply", 67), + BookLine("add a topping of equa leaves.", 68), + BookLine("Worms are specially flavoured", 69), + BookLine("by gnomes as they", 70), + BookLine("purportedly add virility.", 71), + ) + ), + PageSet( + Page( + BookLine("Veg Ball", 55), + BookLine("", 56), + BookLine("As with all gnomebowl dishes,", 57), + BookLine("throw a ball of fresh Gianne", 58), + BookLine("dough into a mould. Bake this", 59), + BookLine("as usual. Bake this briefly.", 60), + BookLine("Add to the bowl two onions,", 61), + BookLine("two potatoes and a dash", 62), + BookLine("of gnome spices. Bake the bowl", 63), + BookLine("in the oven once more.", 64), + BookLine("To finish simply top with equa", 65), + ), + Page( + BookLine("leaves. Vegetable dishes are", 66), + BookLine("seen as luxurious food, since", 67), + BookLine("for most of gnome history", 68), + BookLine("growing vegetables was harder", 69), + BookLine("than finding toads and worms.", 70), + ) + ), + PageSet( + Page( + BookLine("Worm Crunchies", 55), + BookLine("", 56), + BookLine("Using a crunchy tray,", 57), + BookLine("form a portion of Gianne", 58), + BookLine("dough into small evenly", 59), + BookLine("sized balls. Heat these briefly", 60), + BookLine("in an oven. Mix into the", 61), + BookLine("dough balls two king worms,", 62), + BookLine("one sprig of equa leaves", 63), + BookLine("and a shake of gnome spices.", 64), + BookLine("Bake the crunchies for a", 65), + ), + Page( + BookLine("short time in the oven.", 66), + BookLine("Sprinkle generously with", 67), + BookLine("gnome spices to finish.", 68), + BookLine("Crunchies were invented", 69), + BookLine("accidentally by Pukkamay,", 70), + BookLine("who was Dellie's assistant", 71), + BookLine("before his sacking. He started", 72), + BookLine("a successful crunch making", 73), + BookLine("business before dying in a", 74), + BookLine("bizarre Terrorbird accident.", 75), + ) + ), + PageSet( + Page( + BookLine("Choc Chip Crunchies", 55), + BookLine("", 56), + BookLine("Fill up a crunchy tray with", 57), + BookLine("balls of Gianne dough. Heat", 58), + BookLine("these briefly in a warm oven.", 59), + BookLine("Break up two bars of chocolate", 60), + BookLine("and mix these with the balls", 61), + BookLine("of dough. Next add a little", 62), + BookLine("gnome spice to each ball.", 63), + BookLine("Bake the crunchies for a", 64), + BookLine("short time in the oven.", 65), + ), + Page( + BookLine("Top the crunchies with a", 66), + BookLine("sprinkling of chocolate", 67), + BookLine("dust to finish.", 68), + BookLine("(A large chocolate stain", 69), + BookLine("covers the rest of the page.)", 70), + ) + ), + PageSet( + Page( + BookLine("Spicy Crunchies", 55), + BookLine("", 56), + BookLine("Using a crunchy tray,", 57), + BookLine("form a portion of Gianne", 58), + BookLine("dough into small evenly", 59), + BookLine("sized balls. Heat these briefly", 60), + BookLine("in a warm oven.", 61), + BookLine("Add a generous shake", 62), + BookLine("of spice and two sprigs of", 63), + BookLine("equa leaves to the dough balls.", 64), + BookLine("Bake the crunchies for a", 65), + ), + Page( + BookLine("short time in the oven.", 66), + BookLine("Sprinkle a load more gnome", 67), + BookLine("spice over the cookies to finish.", 68), + BookLine("", 69), + BookLine("The special mix of herbs", 70), + BookLine("and spices in gnome spice", 71), + BookLine("is a closely guarded secret.", 72), + BookLine("It is rumoured to contain", 73), + BookLine("(the rest is scribbled out)", 74), + ) + ), + PageSet( + Page( + BookLine("Toad Crunchies", 55), + BookLine("", 56), + BookLine("Fill a crunchy tray with", 57), + BookLine("Gianne dough as normal.", 58), + BookLine("Heat these briefly in a", 59), + BookLine("warm oven. Mix into", 60), + BookLine("the dough balls two pairs", 61), + BookLine("of toad's legs and a", 62), + BookLine("shake of gnome spices.", 63), + BookLine("Bake the crunchies for a short", 64), + BookLine("time in the oven.", 65), + ), + Page( + BookLine("Finish the crunchies with", 66), + BookLine("a sprinkling of equa leaves.", 67), + BookLine("", 68), + BookLine("When Pukkamay first made", 69), + BookLine("toad crunchies, everyone", 70), + BookLine("thought he was mad.", 71), + BookLine("'Chewy toads, in crunchies?", 72), + BookLine("It'll never work' they said", 73), + BookLine("- how wrong they were...", 74), + ) + ), + PageSet( + Page( + BookLine("Worm Batta", 55), + BookLine("", 56), + BookLine("First take some fresh", 57), + BookLine("Gianne dough and place it", 58), + BookLine("in a batta tin. Bake the", 59), + BookLine("dough until it is lightly", 60), + BookLine("browned. Take one king worm,", 61), + BookLine("some gnome spice and", 62), + BookLine("a little cheese. Add these", 63), + BookLine("to the batta before briefly", 64), + BookLine("baking it in the oven once more.", 65), + ), + Page( + BookLine("Finish the batta with a", 66), + BookLine("topping of equa leaves.", 67), + BookLine("Battas are usually cooked by", 68), + BookLine("gnome mother during the", 69), + BookLine("cold winter months.", 70), + ) + ), + PageSet( + Page( + BookLine("Toad's Legs Batta", 55), + BookLine("", 56), + BookLine("Mould some Gianne dough", 57), + BookLine("into a batta tin.", 58), + BookLine("Bake the tin until it", 59), + BookLine("is almost cooked. Next add", 60), + BookLine("some prime toad's legs,", 61), + BookLine("a sprig of equa leaves", 62), + BookLine("and some spice along with", 63), + BookLine("some cheese to the batta.", 64), + BookLine("Bake the batta in the oven", 65), + ), + Page( + BookLine("once more and serve hot.", 66), + BookLine("Toads legs battas are", 67), + BookLine("sometimes called Toad in", 68), + BookLine("the Hole. Apparently there", 69), + BookLine("is a similar human dish", 70), + BookLine("that uses sausages. How odd.", 71), + ) + ), + PageSet( + Page( + BookLine("Cheese & Tomato Batta", 55), + BookLine("", 56), + BookLine("Place some Gianne dough in a", 57), + BookLine("batta tin. Bake it as normal.", 58), + BookLine("Top the plain batta with equal", 59), + BookLine("quantities of cheese and tomato.", 60), + BookLine("Place the batta in the oven", 61), + BookLine("once more until all the cheese", 62), + BookLine("has melted. Finish the dish with", 63), + BookLine("a sprinkling of equa leaves.", 64), + BookLine("The combination of cheese", 65), + ), + Page( + BookLine("and tomato was discovered", 66), + BookLine("by the explorer Wingstone", 67), + BookLine("while was visiting the human", 68), + BookLine("lands. Apparently it's used", 69), + BookLine("a lot in a strange flat", 70), + BookLine("human dish called a pizza.", 71), + ) + ), + PageSet( + Page( + BookLine("Fruit Batta", 55), + BookLine("", 56), + BookLine("Prepare Gianne dough in", 57), + BookLine("a batta tin as normal. Bake", 58), + BookLine("the dough for a short while.", 59), + BookLine("Top the batta with chunks of", 60), + BookLine("pineapple, orange and lime.", 61), + BookLine("Lay four sprigs of", 62), + BookLine("equa leaves on top of the", 63), + BookLine("batta before baking it in", 64), + BookLine("the oven once more. Finish", 65), + ), + Page( + BookLine("the batta with a sprinkling", 66), + BookLine("of gnome spices. Battas are", 67), + BookLine("normally savoury dish,", 68), + BookLine("and the fruit batta is definitely", 69), + BookLine("an acquired taste.", 70), + ) + ), + PageSet( + Page( + BookLine("Vegetable Batta", 55), + BookLine("", 56), + BookLine("Place some Gianne dough in a", 57), + BookLine("batta tin and bake as normal.", 58), + BookLine("Add to the plain batta two", 59), + BookLine("tomatoes, one onion, one", 60), + BookLine("cabbage and some dwellberries.", 61), + BookLine("Top the batta with cheese and", 62), + BookLine("briefly place it in the oven", 63), + BookLine("once more. Finish the dish with", 64), + BookLine("with a sprinkling of equa leaves.", 65), + ), + Page( + BookLine("There's no better batta", 66), + BookLine("than a vegetable batta.", 67), + ) + ), + ) + } + + private fun display(player: Player, pageNum: Int, buttonID: Int): Boolean { + BookInterface.pageSetup(player, BookInterface.FANCY_BOOK_3_49, TITLE, CONTENTS) + return true + } + + override fun defineListeners() { + on(Items.GIANNES_COOK_BOOK_2167, IntType.ITEM, "read") { player, _ -> + BookInterface.openBook(player, BookInterface.FANCY_BOOK_3_49, ::display) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/dialogue/OttoGodblessedDialogue.kt b/Server/src/main/content/region/kandarin/dialogue/OttoGodblessedDialogue.kt new file mode 100644 index 0000000..dd08655 --- /dev/null +++ b/Server/src/main/content/region/kandarin/dialogue/OttoGodblessedDialogue.kt @@ -0,0 +1,91 @@ +package content.region.kandarin.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs +import core.game.dialogue.Topic +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE + +/** + * Represents the dialogue plugin used for Otto + * @author vddCore + */ +@Initializable +class OttoGodblessedDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun newInstance(player: Player): DialoguePlugin { + return OttoGodblessedDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + + npcl( + FacialExpression.HAPPY, + "Good day, you seem a hearty warrior. " + + "Maybe even some barbarian blood in that body of yours?" + ) + + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + START_DIALOGUE -> showTopics( + Topic(FacialExpression.ASKING, "Is there anything you can teach me?", 1), + Topic(FacialExpression.NEUTRAL, "Nevermind.", END_DIALOGUE) + ) + + 1 -> npcl( + FacialExpression.FRIENDLY, + "I can teach you how to fish." + ).also { stage++ } + + 2 -> playerl( + FacialExpression.HALF_ROLLING_EYES, + "Oh, that's pretty underwhelming. But uhhh, okay!" + ).also { stage++ } + + 3 -> npcl( + FacialExpression.FRIENDLY, + "Alright, so here's what you gotta do: you need to grab a pole and some bait, and then... " + + "Fling it into the water!" + ).also { stage++ } + + 4 -> playerl( + FacialExpression.HALF_ASKING, + "The whole... Pole?" + ).also { stage++ } + + 5 -> npcl( + FacialExpression.ANNOYED, + "No, not the whole pole!" + ).also { stage++ } + + 6 -> npcl( + FacialExpression.ANNOYED, + "Look. Just... Grab the pole from under my bed and go click on that fishing spot." + ).also { stage++ } + + 7 -> playerl( + FacialExpression.STRUGGLE, + "...click?" + ).also { stage++ } + + 8 -> npcl( + FacialExpression.FURIOUS, + "JUST GO DO IT!" + ).also { + stage = END_DIALOGUE + player.setAttribute("/save:barbtraining:fishing", true) + } + } + return true + } + + override fun getIds(): IntArray = intArrayOf(NPCs.OTTO_GODBLESSED_2725) +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/dialogue/ShamansTomeBook.kt b/Server/src/main/content/region/kandarin/dialogue/ShamansTomeBook.kt new file mode 100644 index 0000000..9559fa9 --- /dev/null +++ b/Server/src/main/content/region/kandarin/dialogue/ShamansTomeBook.kt @@ -0,0 +1,55 @@ +package content.region.kandarin.dialogue + +import content.global.handlers.iface.BookInterface +import content.global.handlers.iface.BookLine +import content.global.handlers.iface.Page +import content.global.handlers.iface.PageSet +import core.api.setAttribute +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items + +@Initializable +class ShamansTomeBook : InteractionListener { + companion object { + private val TITLE = "Shaman's Tome" + private val CONTENTS = arrayOf( + PageSet( + Page( + BookLine("You read the ancient", 55), + BookLine("shaman's tome.", 56), + BookLine("It is written in a strange sort", 57), + BookLine("of language but you manage", 58), + BookLine("a rough translation.", 59), + BookLine("", 60), + BookLine("...scattered are my hopes that", 61), + BookLine("I will ever be released from", 62), + BookLine("this flaming Octagram, it is", 63), + BookLine("the only thing which will", 64), + BookLine("contain this beast within.", 65), + ), + Page( + BookLine("Although its grip over me is", 66), + BookLine("weakened with magic, it is", 67), + BookLine("hopeless to know if a", 68), + BookLine("saviour would guess this.", 69), + BookLine("I am doomed...", 70), + ) + ), + ) + } + + private fun display(player: Player, pageNum: Int, buttonID: Int): Boolean { + BookInterface.pageSetup(player, BookInterface.FANCY_BOOK_3_49, TITLE, CONTENTS) + return true + } + + override fun defineListeners() { + on(Items.SHAMANS_TOME_729, IntType.ITEM, "read") { player, _ -> + BookInterface.openBook(player, BookInterface.FANCY_BOOK_3_49, ::display) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/dialogue/ShopKeeperDialogue.kt b/Server/src/main/content/region/kandarin/dialogue/ShopKeeperDialogue.kt new file mode 100644 index 0000000..cc0713e --- /dev/null +++ b/Server/src/main/content/region/kandarin/dialogue/ShopKeeperDialogue.kt @@ -0,0 +1,55 @@ +package content.region.kandarin.dialogue + +import core.api.openNpcShop +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class ShopKeeperDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun newInstance(player: Player?): DialoguePlugin { + return ShopKeeperDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npcl( + FacialExpression.HAPPY, "Can I help you at all?" + ).also { stage = START_DIALOGUE } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> options( + "Yes, please. I'd like to see your stock.", "No thanks, I must be going now." + ).also { stage++ } + + 1 -> when (buttonId) { + 1 -> playerl( + FacialExpression.FRIENDLY, "Yes, please. I'd like to see your stock." + ).also { stage++ } + + 2 -> playerl( + FacialExpression.FRIENDLY, "No thanks, I must be going now." + ).also { stage = END_DIALOGUE } + } + + 2 -> { + openNpcShop(player, NPCs.SHOPKEEPER_555) + end() + } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.SHOPKEEPER_555) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/dialogue/StankersDialogue.java b/Server/src/main/content/region/kandarin/dialogue/StankersDialogue.java new file mode 100644 index 0000000..5e419f6 --- /dev/null +++ b/Server/src/main/content/region/kandarin/dialogue/StankersDialogue.java @@ -0,0 +1,203 @@ +package content.region.kandarin.dialogue; + +import core.game.dialogue.DialoguePlugin; +import org.rs09.consts.Items; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.AchievementDiary; +import core.game.node.entity.player.link.diary.DiaryType; +import core.plugin.Initializable; +import core.game.node.item.Item; + +/** + * Handles the Galahad dialogue + * @author afaroutdude + * https://chisel.weirdgloop.org/dialogue/content/486329 + * https://www.youtube.com/watch?v=XPTkSDyKpWs + */ +@Initializable +public class StankersDialogue extends DialoguePlugin { + + private final Item POISON_CHALICE = new Item(Items.POISON_CHALICE_197); + + public StankersDialogue() {} + + public StankersDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new StankersDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + npc("Hello bold adventurer."); + stage = 1; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + int level = 1; + + switch (stage) { + case 999: + end(); + break; + case 1: + options("Are these your trucks?", "Hello Stankers.","Talk about Achievement Diary."); + stage++; + break; + case 2: + switch (buttonId) { + case 1: + player("Are these your trucks?"); + stage = 10; + break; + case 2: + player("Hello Mr. Stankers."); + stage = 20; + break; + case 3: + if (AchievementDiary.canReplaceReward(player, DiaryType.SEERS_VILLAGE, level)) { + player("I seem to have lost my seers' headband..."); + stage = 80; + break; + } + else if (AchievementDiary.hasClaimedLevelRewards(player, DiaryType.SEERS_VILLAGE, level)) { + player("Can you remind me what my headband does?"); + stage = 90; + break; + } + else if (AchievementDiary.canClaimLevelRewards(player, DiaryType.SEERS_VILLAGE, level)) { + player("Hi. I've completed the Medium tasks in my Achievement", "Diary. Can I have a reward?"); + stage = 200; + break; + } + else { + player("Hi! Can you help me out with the Achievement Diary", "tasks?"); + stage = 101; + break; + } + } + break; + case 10: + npc("Yes, I use them to transport coal over the river.", + "I will let other people use them too, I'm a nice", + "person like that..."); + stage++; + break; + case 11: + npc("Just put coal in a truck and I'll move it down to","my depot over the river."); + stage = 999; + break; + case 20: + npc("Would you like a poison chalice?"); + stage++; + break; + case 21: + options("Yes please.","What's a poison chalice?","No thank you."); + stage++; + break; + case 22: + switch (buttonId) { + case 1: + player("Yes please."); + stage = 30; + break; + case 2: + player("What's a poison chalice?"); + stage = 40; + break; + case 3: + player("No thank you."); + stage = 1; + break; + } + break; + case 30: + end(); + player.getInventory().add(POISON_CHALICE); + player.sendMessage("Stankers hands you a glass of strangely coloured liquid..."); + break; + case 40: + npc("It's an exciting drink I've invented. I don't know", + "what it tastes like, I haven't tried it myself."); + stage++; + break; + case 41: + options("Yes please.","No thank you."); + stage++; + break; + case 42: + switch (buttonId) { + case 1: + player("Yes please."); + stage = 30; + break; + case 2: + player("No thank you."); + stage = 1; + break; + } + break; + + case 80: + AchievementDiary.grantReplacement(player, DiaryType.SEERS_VILLAGE, level); + npc("Here's your replacement. Please be more careful."); + stage = 999; + break; + case 90: + npc("Your headband will help you get experience when", "woodcutting maple trees, and an extra log or two when", "cutting normal trees. I've also told Geoff to increase"); + stage++; + break; + case 91: + npc("your flax allowance in acknowledgement of your", "standing."); + stage = 999; + break; + case 100: + npc("I certainly do - we have a set of tasks spanning Seers'", "Village, Catherby, Hemenster and the Sinclair Mansion.", "Just complete the tasks listed in the Achievement Diary", "and they will be ticked off automatically."); + stage = 999; + break; + case 101: + npc("I'm afraid not. It is important that adventurers", "complete the tasks unaided. That way, only the truly", "worthy collect the spoils."); + stage = 999; + break; + case 200: + npc("Well done! Yes, I have a reward for you. I'll just", "anoint your headband with one of my mixtures. Oh and", "here's an old lamp I had lying around."); + stage++; + break; + case 201: + if (!player.hasItem(AchievementDiary.getRewards(DiaryType.SEERS_VILLAGE, level)[0])) { + npc("I need your headband to anoint it! Come back when", "you have it."); + stage = 999; + } else { + AchievementDiary.flagRewarded(player, DiaryType.SEERS_VILLAGE, level); + sendDialogue("Stankers produces a chalice containing a vile-looking concoction that", "he pours all over your headband."); + stage++; + } + break; + case 202: + player("Erm, thank you... I guess."); + stage++; + break; + case 203: + npc("Don't worry, it may be a little sticky for a while, but", "now your headband will help you get experience when", "woodcutting maple trees, and an extra log or two when", "cutting normal trees. I'll also tell Geoff - erm - Flax to"); + stage++; + break; + case 204: + npc("increase your flax allowance in acknowledgement of your", "standing."); + stage=999; + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 383 }; + } +} diff --git a/Server/src/main/content/region/kandarin/dialogue/ThormacDialogue.kt b/Server/src/main/content/region/kandarin/dialogue/ThormacDialogue.kt new file mode 100644 index 0000000..f21493f --- /dev/null +++ b/Server/src/main/content/region/kandarin/dialogue/ThormacDialogue.kt @@ -0,0 +1,59 @@ +package content.region.kandarin.dialogue + +import content.region.kandarin.quest.scorpioncatcher.SCThormacDialogue +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import content.data.Quests + +@Initializable +class ThormacDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun getIds(): IntArray { + return intArrayOf(NPCs.THORMAC_389) + } + + companion object { + const val COMPLETED_QUEST = 1000 + const val ENCHANT_DIALOGUE = 2000 + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + if (isQuestComplete(player, Quests.SCORPION_CATCHER)){ + npc(FacialExpression.HAPPY, "Thank you for rescuing my scorpions.").also {stage = COMPLETED_QUEST} + } + else{ + openDialogue(player, SCThormacDialogue(getQuestStage(player, Quests.SCORPION_CATCHER)), npc) + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + COMPLETED_QUEST -> showTopics( + Topic(FacialExpression.HAPPY, "That's okay.", END_DIALOGUE), + Topic(FacialExpression.NEUTRAL, "You said you'd enchant my battlestaff for me", ENCHANT_DIALOGUE) + ) + + ENCHANT_DIALOGUE -> { + val cost = if (player.equipment.contains(Items.SEERS_HEADBAND_14631, 1)) 27 else 40 + npcl(FacialExpression.HAPPY, "Yes, it'll cost you $cost,000 coins for the materials needed though. " + + "Which sort of staff did you want enchanting?").also { stage++ } + } + ENCHANT_DIALOGUE + 1 -> { + end() + player.interfaceManager.openComponent(332) + } + + } + return true + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/feldip/dialogue/HuntingExpert.java b/Server/src/main/content/region/kandarin/feldip/dialogue/HuntingExpert.java new file mode 100644 index 0000000..e69ff69 --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/dialogue/HuntingExpert.java @@ -0,0 +1,277 @@ +package content.region.kandarin.feldip.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +/** + * Represents the hunting experience dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class HuntingExpert extends DialoguePlugin { + + /** + * Represents the items used for buying skillcapes. + */ + private static final Item[] ITEMS = new Item[] { new Item(9948), new Item(9949), new Item(9950) }; + + /** + * Represents the coins item. + */ + private static final Item COINS = new Item(995, 99000); + + /** + * Constructs a new {@code HuntingExpert} {@code Object}. + */ + public HuntingExpert() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code HuntingExper} {@code Object}. + * @param player the player. + */ + public HuntingExpert(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new HuntingExpert(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Whoah there, stranger, careful where you're walking. I", "almost clobbered you there; thought you were a larupia", "or something."); + stage = 1; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 1: + interpreter.sendOptions("Select an Option", "What are you doing here?", "What's a laurpia?", "What is that cool cape you're wearing?", "Ahh, leave me alone you crazy killing person."); + stage = 2; + break; + case 2: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What are you doing here?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What's a laurpia?"); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What is that cool cape you're wearing?"); + stage = 30; + break; + case 4: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Ahh, leave me alone you crazy killing person."); + stage = 140; + break; + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Me? Oh, I'm just having some fun, capturing wild", "animals, living on the edge, stuff like that."); + stage = 11; + break; + case 11: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hey, want me to teach you how to catch the critters", "around here? Ain't come across anything yet that I", "couldn't capture."); + stage = 12; + break; + case 12: + interpreter.sendOptions("Select an Option", "Okay, where's a good place to start?", "What sort of things are there to catch around here?", "How can I improve my chances of making a capture?", "How can I get clothes and equipment like yours?", "I think I'll give it a miss right now."); + stage = 13; + break; + case 13: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Ok, where's a good place to start?"); + stage = 100; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What sort of things are there to catch around here?"); + stage = 110; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "How can I improve my chances of making a capture?"); + stage = 120; + break; + case 4: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Where can I get clothes and equipment like yours?"); + stage = 130; + break; + case 5: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I think I'll give it a miss right now, thanks."); + stage = 150; + break; + } + break; + case 100: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Your easiest bet around here is probably to go for some", "of the birds. Go for crimson swifts; they're the", "bright red ones that hang around near the coast.", "They're as obliging as can be, or maybe they're just"); + stage = 101; + break; + case 101: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "plain dumb, but either way they just seem to throw", "themselves into traps half the time."); + stage = 102; + break; + case 102: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What sort of trap should I use?"); + stage = 103; + break; + case 103: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Just use a strandard bird snare and you'll be fine. You", "can get them in any decent shop that sells Hunter", "gear."); + stage = 104; + break; + case 104: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "How do they work, then?"); + stage = 105; + break; + case 105: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Well, they're kind of sneaky, really. You've got a tall", "post with what appears to be a little perch sticking out", "the side. Now, that the bird will see this as somewhere to sit", "but the perch is actually rigged such that when the bird"); + stage = 106; + break; + case 106: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "lands on it, it'll drop away."); + stage = 107; + break; + case 107: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Futher, as the perch drops, it releases a noose that", "tightens around the bird's feet and captures it. Neat", "huh?"); + stage = 108; + break; + case 110: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "What're you interested in? You've got anything from", "birds for begginers up to laurpias for the pros, not to", "mention weasels, butterflies, barb-tails and chinchompas."); + stage = 111; + break; + case 111: + end(); + break; + case 120: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "There are four key factors that will affect your", "chances: what bait you use, how close to the trap you", "are, your appearance and your smell."); + stage = 121; + break; + case 121: + end(); + break; + case 130: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Well, the equipment isn't too hard to get hold of. You've", "got specialist shops like Aleck's in Yanille that'll see you", "right. He's a bit pricey, mind, but it's pretty decent kit."); + stage = 131; + break; + case 131: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "The clothing is a tad trickier to get hold of, the", "materials required being rather difficult to seperate from", "their relucant owners."); + stage = 132; + break; + case 132: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "But, if you can get the furs, there are shops like the", "tailor's in east Varrock that can help you."); + stage = 133; + break; + case 133: + end(); + break; + case 140: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Heh, well I guess it's not everyone's thing."); + stage = 141; + break; + case 150: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Suit yourself!"); + stage = 151; + break; + case 151: + end(); + break; + case 108: + end(); + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "What's a laurpia? You don't know? You mean you", "really don't recognise the significance of these clothes", "I'm wearing?"); + stage = 21; + break; + case 21: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Well, they're certainly decorative...what about them?"); + stage = 22; + break; + case 22: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Well, these are the furs from a laurpia. Caught the", "creature myself I did, and these make me blend in", "better, see?"); + stage = 23; + break; + case 23: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "If you want to be successful as a hunter you've got to", "be as stealthy as a kyatt, as quiet as a mouse and blend", "in like a, well like a larupia, I guess!"); + stage = 24; + break; + case 24: + end(); + break; + case 30: + if (player.getSkills().getLevel(Skills.HUNTER) < 99) { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "This? It's a Hunter's Skillcape. It shows that I am a", "true master of the art of Hunting. If you ever manage", "to train your Hunter skill to it maximu level then I", "could sell you one."); + stage = 31; + } else { + interpreter.sendDialogues(npc, null, "An adventurer whom possesses the same level", "of Hunter as me, would you be interested in buying", "a skillcape of Hunter for 99,000 gold coins ?"); + stage = 35; + } + break; + case 31: + end(); + break; + case 35: + interpreter.sendOptions("Select an Option", "Yes, please.", "No, thank you."); + stage = 36; + break; + case 36: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, null, "Yes, please."); + stage = 38; + break; + case 2: + interpreter.sendDialogues(player, null, "Yes, please."); + stage = 99; + break; + } + break; + case 38: + if (!player.getInventory().contains(995, 99000)) { + interpreter.sendDialogues(player, null, "Sorry, I dont have that amount of money."); + stage = 99; + break; + } else { + if (player.getInventory().freeSlots() < 2) { + interpreter.sendDialogues(player, null, "Sorry, I don't seem to have enough inventory space."); + stage = 99; + break; + } + if (!player.getInventory().containsItem(COINS)) { + end(); + return true; + } + if (player.getInventory().remove(COINS)) { + player.getInventory().add(player.getSkills().getMasteredSkills() > 1 ? ITEMS[1] : ITEMS[0], ITEMS[2]); + interpreter.sendDialogues(npc, null, "There you go! Enjoy adventurer."); + stage = 99; + } + } + break; + case 99: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 5113 }; + } +} diff --git a/Server/src/main/content/region/kandarin/feldip/gutanoth/handlers/BogrogPlugin.java b/Server/src/main/content/region/kandarin/feldip/gutanoth/handlers/BogrogPlugin.java new file mode 100644 index 0000000..c66f8e3 --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/gutanoth/handlers/BogrogPlugin.java @@ -0,0 +1,142 @@ +package content.region.kandarin.feldip.gutanoth.handlers; + +import core.cache.def.impl.NPCDefinition; +import core.game.component.Component; +import core.game.container.access.InterfaceContainer; +import core.plugin.Initializable; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.skill.Skills; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Plugin; +import core.plugin.ClassScanner; +import kotlin.Unit; + +import static core.api.ContentAPIKt.*; + +/** + * Handles the bogrog npc. + * @author Vexia + */ +@Initializable +public final class BogrogPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + NPCDefinition.forId(4472).getHandlers().put("option:swap", this); + ClassScanner.definePlugin(new BogrogDialogue()); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + switch (option) { + case "swap": + openSwap(player); + break; + } + return true; + } + + /** + * Opens the swap interface. + * @param player the player. + */ + private void openSwap(Player player) { + if (player.getSkills().getStaticLevel(Skills.SUMMONING) < 21) { + player.sendMessage("You need a Summoning level of at least 21 in order to do that."); + return; + } else { + sendItemSelect(player, new String[] { "Value", "Swap 1", "Swap 5", "Swap 10", "Swap X" }, true, (slot, index) -> { + BogrogPouchSwapper.handle(player, index, slot); + return Unit.INSTANCE; + }); + } + } + + /** + * Handles the bogrog dialogue. + * @author Vexia + */ + public final class BogrogDialogue extends DialoguePlugin { + + /** + * Constructs a new {@Code BogrogDialogue} {@Code Object} + */ + public BogrogDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@Code BogrogDialogue} {@Code Object} + * @param player the player. + */ + public BogrogDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new BogrogDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + npc("Hey, yooman, what you wanting?"); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + options("Can I buy some summoning supplies?", "Are you interested in buying pouch pouches or scrolls?"); + stage++; + break; + case 1: + switch (buttonId) { + case 1: + player("Can I buy some summoning supplies?"); + stage = 10; + break; + case 2: + player("Are you interested in buying pouch pouches or scrolls?"); + stage = 20; + break; + } + break; + case 10: + npc("Hur, hur, hur! Yooman's gotta buy lotsa stuff if yooman", "wants ta train good!"); + stage++; + break; + case 11: + npc.openShop(player); + end(); + break; + case 20: + npc("Des other ogre's stealin' Bogrog's stock. Gimmie pouches", "and scrolls and yooman gets da shardies."); + stage++; + break; + case 21: + player("Ok."); + stage++; + break; + case 22: + openSwap(player); + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 4472 }; + } + } +} diff --git a/Server/src/main/content/region/kandarin/feldip/gutanoth/handlers/BogrogPouchSwapper.kt b/Server/src/main/content/region/kandarin/feldip/gutanoth/handlers/BogrogPouchSwapper.kt new file mode 100644 index 0000000..90dbfbe --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/gutanoth/handlers/BogrogPouchSwapper.kt @@ -0,0 +1,82 @@ +package content.region.kandarin.feldip.gutanoth.handlers + +import core.api.* +import core.game.component.Component +import core.game.node.entity.player.Player +import content.global.skill.summoning.SummoningPouch +import content.global.skill.summoning.SummoningScroll +import core.game.node.item.Item +import core.game.world.map.zone.ZoneBorders +import kotlin.math.ceil +import kotlin.math.floor + +/** + * Handles swapping pouches/scrolls for shards. + * We decided to use the GE set exchange interface for this because it's the only one we could find + * that allowed us to do what we needed. Jagex did the same thing as far as we can tell. + * @author Ceikry + */ +object BogrogPouchSwapper { + //Opcodes for item options + private const val OP_VALUE = 0 + private const val OP_SWAP_1 = 1 + private const val OP_SWAP_5 = 2 + private const val OP_SWAP_10 = 3 + private const val OP_SWAP_X = 4 + + private const val SPIRIT_SHARD = 12183 + + //GE Zone borders because shitty hack lol + private val GEBorders = ZoneBorders(3151,3501,3175,3477) + + @JvmStatic + fun handle(player: Player, optionIndex: Int, slot: Int): Boolean{ + val item = player.inventory.get(slot) ?: return false + return when(optionIndex){ + OP_VALUE -> sendValue(item.id,player) + OP_SWAP_1 -> swap(player, 1, item.id) + OP_SWAP_5 -> swap(player, 5, item.id) + OP_SWAP_10 -> swap(player, 10, item.id) + OP_SWAP_X -> true.also{ + sendInputDialogue(player, InputType.AMOUNT, "Enter the amount:"){value -> + swap(player, value as Int, item.id) + } + } + else -> false + } + } + + private fun swap(player: Player, amount: Int, itemID: Int): Boolean{ + var amt = amount + val value = getValue(itemID) + if(value == 0.0){ + return false + } + val inInventory = player.inventory.getAmount(itemID) + if(amount > inInventory) + amt = inInventory + player.inventory.remove(Item(itemID,amt)) + player.inventory.add(Item(SPIRIT_SHARD, floor(value * amt).toInt())) + return true + } + + private fun sendValue(itemID: Int, player: Player): Boolean{ + val value = getValue(itemID) + if(value == 0.0){ + return false + } + + player.sendMessage("Bogrog will give you ${floor(value).toInt()} shards for that.") + return true + } + + private fun getValue(itemID: Int): Double{ + var item = SummoningPouch.get(itemID) + var isScroll = false + if(item == null) item = SummoningPouch.get(Item(itemID).noteChange) + if(item == null) item = SummoningPouch.get(SummoningScroll.forItemId(itemID)?.pouch ?: -1).also { isScroll = true } + item ?: return 0.0 + var shardQuantity = item.items[item.items.size - 1].amount * 0.7 + return if(isScroll) shardQuantity / 20.0 else ceil(shardQuantity) + } +} diff --git a/Server/src/main/content/region/kandarin/feldip/gutanoth/handlers/GutanothChestPlugin.kt b/Server/src/main/content/region/kandarin/feldip/gutanoth/handlers/GutanothChestPlugin.kt new file mode 100644 index 0000000..c98daee --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/gutanoth/handlers/GutanothChestPlugin.kt @@ -0,0 +1,83 @@ +package content.region.kandarin.feldip.gutanoth.handlers + +import core.game.node.scenery.Scenery +import core.game.node.scenery.SceneryBuilder +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.game.world.GameWorld +import java.util.concurrent.TimeUnit + +private const val CHEST = 2827 +class GutanothChestInteractionHandler : InteractionListener { + + override fun defineListeners() { + + on(CHEST, IntType.SCENERY, "open"){ player, node -> + val delay = player.getAttribute("gutanoth-chest-delay", 0L) + GameWorld.Pulser.submit(ChestPulse(player,System.currentTimeMillis() > delay, node as Scenery)) + return@on true + } + + } + + class ChestPulse(val player: Player, val isLoot: Boolean, val chest: Scenery): Pulse(){ + var ticks = 0 + override fun pulse(): Boolean { + when(ticks++){ + 0 -> { + player.lock() + player.animator.animate(Animation(536)) + SceneryBuilder.replace(chest, Scenery(2828, chest.location, chest.rotation), 5) + } + 2 -> {lootChest(player)} + 3 -> {player.unlock(); return true} + } + return false + } + + + fun lootChest(player: Player){ + if (isLoot) { + player.setAttribute("/save:gutanoth-chest-delay", System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(15)) + } else { + player.sendMessage("You open the chest and find nothing.") + return + } + val reward = Rewards.values().random() + player.sendChat(reward.message) + when(reward.type){ + Type.ITEM -> if(!player.inventory.add(Item(reward.id))) GroundItemManager.create(Item(reward.id),player.location) + Type.NPC -> { + val npc = NPC(reward.id) + npc.location = player.location + npc.isAggressive = true + npc.isRespawn = false + npc.properties.combatPulse.attack(player) + npc.init() + } + } + } + + enum class Rewards(val id: Int, val type: Type, val message: String){ + BONES(Items.BONES_2530, Type.ITEM, "Oh! Some bones. Delightful."), + EMERALD(Items.EMERALD_1605, Type.ITEM, "Ooh! A lovely emerald!"), + ROTTEN_APPLE(Items.ROTTEN_APPLE_1984, Type.ITEM, "Oh, joy, spoiled fruit! My favorite!"), + CHAOS_DWARF(119, Type.NPC, "You've gotta be kidding me, a dwarf?!"), + RAT(47, Type.NPC, "Eek!"), + SCORPION(1477, Type.NPC, "Zoinks!"), + SPIDER(1004, Type.NPC, "Awh, a cute lil spidey!") + } + + enum class Type { + ITEM, + NPC + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/feldip/ooglog/dialogue/BalneaDialogue.kt b/Server/src/main/content/region/kandarin/feldip/ooglog/dialogue/BalneaDialogue.kt new file mode 100644 index 0000000..2df29fe --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/ooglog/dialogue/BalneaDialogue.kt @@ -0,0 +1,52 @@ +package content.region.kandarin.feldip.ooglog.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE + +/** + * Provides dialogue tree for Balnea NPC involved in the + * "As a First Resort..." quest. + * + * @author vddCore + */ +@Initializable +class BalneaDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + START_DIALOGUE -> playerl( + FacialExpression.FRIENDLY, + "Hi there!" + ).also { stage++ } + + 1 -> npcl( + FacialExpression.NEUTRAL, + "I'm ever so busy at the moment; please come back after the grand opening." + ).also { stage++ } + + 2 -> playerl( + FacialExpression.HALF_ASKING, + "What grand reopening?" + ).also { stage++ } + + 3 -> npcl( + FacialExpression.ANNOYED, + "I'm sorry, I really can't spare the time to talk to you." + ).also { stage++ } + + 4 -> playerl( + FacialExpression.THINKING, + "Uh, sure." + ).also { stage = END_DIALOGUE } + } + + /* TODO: "As a First Resort" quest dialogue file is required here. */ + return true + } + + override fun getIds(): IntArray = intArrayOf(NPCs.BALNEA_7047) +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/feldip/ooglog/dialogue/OgressBankerDialogue.kt b/Server/src/main/content/region/kandarin/feldip/ooglog/dialogue/OgressBankerDialogue.kt new file mode 100644 index 0000000..045e018 --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/ooglog/dialogue/OgressBankerDialogue.kt @@ -0,0 +1,78 @@ +package content.region.kandarin.feldip.ooglog.dialogue + +import core.api.sendNPCDialogue +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE + +/** + * Provides dialogue tree for the Ogress Bankers in the city of Oo'glog. + * + * @author vddCore + */ +@Initializable +class OgressBankerDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun getIds(): IntArray = intArrayOf( + NPCs.OGRESS_BANKER_7049, + NPCs.OGRESS_BANKER_7050 + ) + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + START_DIALOGUE -> npcl( + FacialExpression.ANNOYED, + "..." + ).also { stage++ } + + 1 -> playerl( + FacialExpression.ANNOYED, + "Excuse me, can I get some service here, please?" + ).also { stage++ } + + 2 -> npcl( + FacialExpression.ANGRY, + "GRAAAAAH! You go away, human! Me too busy with training to talk to puny thing like you." + ).also { stage++ } + + 3 -> sendNPCDialogue( + player, + NPCs.BALNEA_7047, + "I do apologise, sir. We're temporarily unable to meet your banking needs.", + FacialExpression.NEUTRAL, + ).also { stage++ } + + 4 -> sendNPCDialogue( + player, + NPCs.BALNEA_7047, + "We'll be open as soon as we realize our customer experience goals " + + "and can guarantee the high standards of service that you expect from all " + + "branches of the Bank of Gielinor.", + FacialExpression.NEUTRAL + ).also { stage++ } + + 5 -> playerl( + FacialExpression.THINKING, + "What did you just say to me?" + ).also { stage++ } + + 6 -> sendNPCDialogue( + player, + NPCs.BALNEA_7047, + "We're closed until I can teach these wretched creatures some manners.", + FacialExpression.ANNOYED + ).also { stage++ } + + 7 -> playerl( + FacialExpression.NEUTRAL, + "Ah, right. Good luck with that." + ).also { stage = END_DIALOGUE } + } + + /* TODO: "As a First Resort..." quest dialogue file is required here. */ + return true + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/feldip/quest/chompybird/BloatedToadNPC.kt b/Server/src/main/content/region/kandarin/feldip/quest/chompybird/BloatedToadNPC.kt new file mode 100644 index 0000000..49a0746 --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/quest/chompybird/BloatedToadNPC.kt @@ -0,0 +1,168 @@ +package content.region.kandarin.feldip.quest.chompybird + +import core.api.* + +import org.rs09.consts.NPCs +import org.rs09.consts.Items +import org.rs09.consts.Graphics + +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.game.system.command.Privilege +import core.plugin.Initializable +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.world.map.zone.ZoneBorders +import core.game.world.map.RegionManager +import core.game.world.map.Location +import core.tools.RandomFunction +import content.data.Quests + +@Initializable +class BloatedToadNPC : AbstractNPC { + constructor() : super(NPCs.BLOATED_TOAD_1014, null, true) {} + private constructor(id: Int, location: Location) : super(id, location) {} + + var ticksToLive = 100 + var chompySpawned = false + + override fun construct(id: Int, location: Location, vararg objects: Any?): AbstractNPC { + val npc = BloatedToadNPC(id, location) + npc.isWalks = false + npc.isNeverWalks = true + npc.isRespawn = false + return npc + } + + override fun getIds() : IntArray { + return intArrayOf(NPCs.BLOATED_TOAD_1014) + } + + override fun handleTickActions() { + super.handleTickActions() + + if (ticksToLive-- <= 0) { + val toDamage = RegionManager.getLocalEntitys(this.location, 2) + + for (entity in toDamage) { + if (entity == this) continue + impact(entity, RandomFunction.random(1, 3)) + } + + sendGraphics(Graphics.TOAD_DETONATION_240, this.location) + + clear() + } + + if (!chompySpawned && RandomFunction.random(20) == 5) { //Arbitrary random number matching (ryan: updated this from 1/5 to 1/20 because 1/5 was debug stuff.) + val chompy = NPC.create(NPCs.CHOMPY_BIRD_1550, this.location) + val spawn = getPathableRandomLocalCoordinate(chompy, 4, this.location, 3) + if (spawn == null || spawn == this.location) return + + val owner = getAttribute("owner", null) ?: return + + chompy.isRespawn = false + chompy.location = spawn + chompy.setAttribute("owner", owner) + chompy.setAttribute("toad", this) + chompy.walkingQueue.update() + + chompy.init() + sendChat(chompy, "Squawk!") + clearHintIcon(owner) + registerHintIcon(owner, chompy) + chompySpawned = true + ticksToLive = 100 + } + } + +} + + +class BloatedToadListeners : InteractionListener, StartupListener, Commands { + lateinit var borders: ZoneBorders + val extraBorders = ArrayList() + + override fun startup() { + borders = ZoneBorders(2368, 2944, 2687, 3071) + borders.addException(ZoneBorders.forRegion(10287)) + borders.addException(ZoneBorders.forRegion(10031)) + borders.addException(ZoneBorders.forRegion(9775)) + } + + override fun defineCommands() { + define("toadzone", Privilege.MODERATOR, "", "Toad inflation.") {player, _ -> + val swloc = player.location.transform(-15,-15,0) + val neloc = player.location.transform(15,15,0) + val newBorders = ZoneBorders(swloc.x, swloc.y, neloc.x, neloc.y) + extraBorders.add(newBorders) + for (i in 0 until 10) { + val npc = NPC(NPCs.SWAMP_TOAD_1013, newBorders.randomLoc) + npc.isRespawn = true + npc.isWalks = true + npc.isNeverWalks = false + npc.init() + } + } + + define("toadbomb", Privilege.ADMIN, "", "Toad detoadation.") {player, _ -> + val swloc = player.location.transform(-5,-5,0) + val neloc = player.location.transform(5,5,0) + for (x in swloc.x until neloc.x) { + for (y in swloc.y until neloc.y) { + val npc = BloatedToadNPC().construct(NPCs.BLOATED_TOAD_1014, Location.create(x, y, swloc.z)) + npc.isNeverWalks = true + npc.isWalks = false + (npc as BloatedToadNPC).ticksToLive = 5 + npc.init() + } + } + } + } + + override fun defineListeners() { + on(Items.BLOATED_TOAD_2875, IntType.ITEM, "drop") { player, used -> + val quest = player.questRepository.getQuest(Quests.BIG_CHOMPY_BIRD_HUNTING) + val inExtraBorder = extraBorders.filter { it.insideBorder(player) }.count() > 0 + + if (!borders.insideBorder(player) && !inExtraBorder) { + sendPlayerDialogue(player, "I probably wouldn't catch many chompies here.") + return@on true + } + + if (quest.getStage(player) < 30) { + sendPlayerDialogue(player, "I don't know what you want from me.") + return@on true + } + + if (quest.getStage(player) in 30..40) { + if (player.location == Location.create(2635, 2966, 0) || player.location == Location.create(2636, 2966, 0)){ + quest.setStage(player, 40) + } else { + sendPlayerDialogue(player, "I should probably put this where Rantz told me.") + return@on true + } + } + + if (removeItem(player, used.asItem())) { + val toad = core.game.node.entity.npc.NPC.create(NPCs.BLOATED_TOAD_1014, player.location) + setAttribute(toad, "owner", player) + toad.init() + } + return@on true + } + + on(Items.BLOATED_TOAD_2875, IntType.ITEM, "release") { player, used -> + removeItem(player, used.asItem()) + sendPlayerDialogue(player, "Free the fat toadsies!") + return@on true + } + + on(Items.BLOATED_TOAD_2875, IntType.ITEM, "release all") { player, used -> + removeAll(player, used.asItem()) + sendPlayerDialogue(player, "Free the fat toadsies!") + return@on true + } + } +} diff --git a/Server/src/main/content/region/kandarin/feldip/quest/chompybird/ChompyBird.kt b/Server/src/main/content/region/kandarin/feldip/quest/chompybird/ChompyBird.kt new file mode 100644 index 0000000..2ca5b50 --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/quest/chompybird/ChompyBird.kt @@ -0,0 +1,327 @@ +package content.region.kandarin.feldip.quest.chompybird + +import core.api.* + +import org.rs09.consts.Vars +import org.rs09.consts.Items +import org.rs09.consts.Animations +import org.rs09.consts.Graphics +import org.rs09.consts.NPCs + +import core.plugin.Initializable +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.node.item.Item +import core.game.node.entity.skill.Skills +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.world.update.flag.context.Graphics as Gfx + +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.game.system.config.NPCConfigParser +import core.game.world.GameWorld + +import kotlin.math.min +import java.util.Random +import content.data.Quests + +@Initializable +class ChompyBird : Quest(Quests.BIG_CHOMPY_BIRD_HUNTING, 35, 34, 2, Vars.VARP_QUEST_CHOMPY, 0, 1, 65), InteractionListener { + companion object { + val CAVE_ENTRANCE = Location.create(2646, 9378, 0) + val CAVE_EXIT = Location.create(2630, 2997, 0) + val TOAD_LOCATION = Location.create(2636, 2966, 0) + val ATTR_ING_RANTZ = "/save:chompybird:rantz-ingredient" + val ATTR_ING_BUGS = "/save:chompybird:bugs-ingredient" + val ATTR_ING_FYCIE = "/save:chompybird:fycie-ingredient" + val ATTR_BUGS_ASKED = "/save:chompybird:bugs-asked" + val ATTR_FYCIE_ASKED = "/save:chompybird:fycie-asked" + } + + override fun drawJournal(player: Player, stage: Int) { + super.drawJournal(player, stage) + + var ln = 11 + + if (stage == 0) { + line(player, "To start this quest I will need:", ln++, false) + line(player, "Level 5 !!Fletching??", ln++, getStatLevel(player, Skills.FLETCHING) >= 5) + line(player, "Level 30 !!Cooking??", ln++, getStatLevel(player, Skills.COOKING) >= 30) + line(player, "Level 30 !!Ranged??", ln++, getStatLevel(player, Skills.RANGE) >= 30) + line(player, "Ability to defend against !!level 64 wolves?? and !!level 70 ogres??for short periods of time.", ln++, false) + } else { + if (stage == 10) { + line(player, "Rantz needs me to make 'stabbers'. To do this I need:", ln++, false) + line(player, "- !!Achey Logs??", ln++, false) + line(player, "- !!Wolf Bones??", ln++, false) + line(player, "- !!Feathers??", ln++, false) + line(player, "I then must turn the !!achey logs?? into !!ogre shafts??,", ln++, false) + line(player, "attach !!feathers?? to these !!shafts??, and then tip them", ln++, false) + line(player, "with !!wolf bones?? chiseled into !!tips??.", ln++, false) + line(player, "At least, that's what I think he was getting at.", ln++, false) + } else if (stage > 10) { + line(player, "I created 'stabbers' for Rantz.", ln++, true) + } + + if (stage == 20) { + line(player, "Rantz needs me to obtain a bloated swamp toad.", ln++, false) + line(player, "To do this, I need to take !!billows?? from the !!locked", ln++, false) + line(player, "!!chest?? in his cave, and then head to the !!swamp to", ln++, false) + line(player, "!!the south??. There, I should !!use the billows?? on the", ln++, false) + line(player, "!!swamp bubbles?? to fill them with swamp gas. Then I can", ln++, false) + line(player, "use the !!billows?? to fill the !!swamp toads?? with gas.", ln++, false) + } else if (stage > 20) { + line(player, "I learned how to collect swamp gas and conduct toad inflation.", ln++, true) + } + + if (stage == 30) { + line(player, "Rantz needs me to place the swamp toad to bait out a 'chompy'.", ln++, false) + } else if (stage > 30) { + line(player, "I learned how to use the toads to bait chompies.", ln++, true) + } + + if (stage == 40) { + line(player, "I should return to Rantz and let him know.", ln++, false) + } + + if (stage == 50) { + line(player, "Rantz keeps missing the birds. Perhaps I should try.", ln++, false) + } else if (stage > 50) { + line(player, "Rantz gave me his bow so that I could try to catch a chompy.", ln++, true) + } + + if (stage == 60) { + line(player, "I should use what I've learned to try to bait and kill a chompy bird.", ln++, false) + } + + if (stage == 70) { + line(player, "I managed to hunt and kill a chompy bird, and now Rantz wants", ln++, false) + line(player, "me to cook the bird for him! And to make it even worse, he and", ln++, false) + line(player, "his children want special ingredients! Those are listed below:", ln++, false) + line(player, "- Rantz wants: !!${getItemName(getAttribute(player, ATTR_ING_RANTZ, -1))}??", ln++, false) + line(player, "- ${if(getAttribute(player, ATTR_BUGS_ASKED, false)) "Bugs wants: !!${getItemName(getAttribute(player, ATTR_ING_BUGS, -1))}??" else "I still need to ask !!Bugs??."}", ln++, false) + line(player, "- ${if(getAttribute(player, ATTR_FYCIE_ASKED, false)) "Fycie wants: !!${getItemName(getAttribute(player, ATTR_ING_FYCIE, -1))}??" else "I still need to ask !!Fycie??."}", ln++, false) + } else if (stage > 70) { + line(player, "I seasoned and cooked the chompy bird for Rantz and his kids.", ln++, true) + line(player, "%%QUEST COMPLETE!&&", ln++, false) + } + } + } + + override fun finish(player: Player?) { + super.finish(player) + player ?: return + + var ln = 10 + player.packetDispatch.sendItemZoomOnInterface(Items.OGRE_BOW_2883, 230, 277, 5) + drawReward(player, "2 Quest Points, 262 Fletching", ln++) + drawReward(player, "XP, 1470 Cooking XP, 735", ln++) + drawReward(player, "Ranged XP", ln++) + drawReward(player, "Ogre Bow", ln++) + drawReward(player, "Ability to make Ogre Arrows", ln++) + rewardXP(player, Skills.FLETCHING, 262.0) + rewardXP(player, Skills.COOKING, 1470.0) + rewardXP(player, Skills.RANGE, 735.0) + removeItem(player, Items.SEASONED_CHOMPY_2882) + removeAttribute(player, ATTR_ING_BUGS) + removeAttribute(player, ATTR_BUGS_ASKED) + removeAttribute(player, ATTR_ING_RANTZ) + removeAttribute(player, ATTR_ING_FYCIE) + removeAttribute(player, ATTR_FYCIE_ASKED) + } + + override fun newInstance(`object`: Any?): Quest { return this } + + override fun defineListeners() { + val filledBellows = intArrayOf(Items.OGRE_BELLOWS_3_2872, Items.OGRE_BELLOWS_2_2873, Items.OGRE_BELLOWS_1_2874) + + on(3379, IntType.SCENERY, "enter") { player, _ -> + teleport(player, CAVE_ENTRANCE) + sendMessage(player, "You walk through the cave entrance into a dimly lit cave.") + return@on true + } + + on(intArrayOf(32068, 32069), IntType.SCENERY, "pass-through") { player, _ -> + teleport(player, CAVE_EXIT) + sendMessage(player, "You walk back out of the darkness of the cave into daylight.") + return@on true + } + + on(3377, IntType.SCENERY, "unlock") { player, node -> + if (freeSlots(player) == 0) { + sendMessage(player, "You don't have enough space to do that.") + return@on true + } + if (amountInInventory(player, Items.OGRE_BELLOWS_2871) > 0) { + sendDialogue(player, "I don't need another set of bellows.") + return@on true + } + sendMessage(player, "You strain to lift the rock off the chest.") + sendChat(player, "Humph!") + runTask(player, 2) { + if (Random().nextBoolean()) { + sendMessage(player, "But it's just too heavy for you.") + sendMessage(player, "The experience has left you feeling temporarily weakened.") + sendChat(player, "ARRRGH") + adjustLevel(player, Skills.STRENGTH, -1) + } else { + replaceScenery(node.asScenery(), node.id + 1, 5) + sendChat(player, "I guess this is what an ogre would call a locked chest.") + sendItemDialogue(player, Items.OGRE_BELLOWS_2871, "You take the bellows from the chest.") + addItem(player, Items.OGRE_BELLOWS_2871) + } + } + + return@on true + } + + onUseWith(IntType.SCENERY, Items.RAW_CHOMPY_2876, 3375) { player, used, _ -> + val rantzIngredient = getAttribute(player, ATTR_ING_RANTZ, -1) + val bugsIngredient = getAttribute(player, ATTR_ING_BUGS, -1) + val fycieIngredient = getAttribute(player, ATTR_ING_FYCIE, -1) + + if (rantzIngredient == -1) { + sendDialogue(player, "I don't have a reason to do this yet.") + return@onUseWith true + } + + if ( + amountInInventory(player, rantzIngredient) > 0 + && amountInInventory(player, bugsIngredient) > 0 + && amountInInventory(player, fycieIngredient) > 0 + ) { + lock(player, 5) + setVarbit(player, Vars.VARBIT_QUEST_CHOMPY_SPITROAST, 1) + animate(player, Animations.HUMAN_COOKING_RANGE_896) + sendMessage(player, "You carefully place the chompy bird on the spit-roast.") + sendMessage(player, "You add the other ingredients and cook the food.") + runTask(player, 4) { + setVarbit(player, Vars.VARBIT_QUEST_CHOMPY_SPITROAST, 0) + sendItemDialogue( + player, + Items.SEASONED_CHOMPY_2882, + "You use the ${getItemName(rantzIngredient).lowercase()}, ${getItemName(bugsIngredient).lowercase()} and the ${getItemName(fycieIngredient)} with the chompy bird to make a seasoned chompy." + ) + if ( + removeItem(player, used.asItem()) + && removeItem(player, rantzIngredient) + && removeItem(player, bugsIngredient) + && removeItem(player, fycieIngredient) + ) addItem(player, Items.SEASONED_CHOMPY_2882) + sendMessage(player, "Eventually the chompy is cooked") + sendMessage(player, "It has been deliciously seasoned to taste wonderful for ogres.") + } + } else { + sendDialogue(player, "I don't have all the ingredients I need yet.") + player.debug("Required Items: $rantzIngredient, $bugsIngredient, $fycieIngredient") + } + + return@onUseWith true + } + + onUseWith(IntType.SCENERY, Items.OGRE_BELLOWS_2871, 684) { player, used, _ -> + if (removeItem(player, used.asItem())) { + lock(player, 2) + visualize(player, Animations.HUMAN_USING_BELLOWS_1026, Gfx(Graphics.USING_BELLOWS, 80)) + addItem(player, Items.OGRE_BELLOWS_3_2872) + sendMessage(player, "You fill the bellows with swamp gas.") + } + return@onUseWith true + } + + onUseWith(IntType.NPC, filledBellows, NPCs.SWAMP_TOAD_1013) { player, used, with -> + val hasTooManyToads = amountInInventory(player, Items.BLOATED_TOAD_2875) >= 3 + + if (hasTooManyToads) { + sendMessage(player, "One of your toads manages to escape.") + removeItem(player, Items.BLOATED_TOAD_2875) + } + + sendChat(player, "Come here toady!") + sendMessage(player, "You manage to catch the toad and inflate it with swamp gas.") + visualize(player, Animations.HUMAN_USING_BELLOWS_1026, Gfx(Graphics.USING_BELLOWS, 80)) + animate(with.asNpc(), Animations.TOAD_INFLATION_1019) + runTask(player, 2) { + if (removeItem(player, used.asItem())) { + if (filledBellows.isLast(used.id)) { + addItem(player, Items.OGRE_BELLOWS_2871) + } else { + addItem(player, filledBellows.getNext(used.id)) + } + addItem(player, Items.BLOATED_TOAD_2875) + with.asNpc().respawnTick = GameWorld.ticks + with.asNpc().definition.getConfiguration(NPCConfigParser.RESPAWN_DELAY, 34) + } + } + return@onUseWith true + } + + onUseWith(IntType.ITEM, Items.WOLF_BONES_2859, Items.CHISEL_1755) { player, used, with -> + val maxAmount = amountInInventory(player, used.id) + + if (getStage(player) == 0) { + sendMessage(player, "You must have started Big Chompy Bird Hunting to make these.") + return@onUseWith true + } + + if (getStatLevel(player, Skills.FLETCHING) < 5) { + sendMessage(player, "You need a Fletching level of 5 to make these.") + return@onUseWith true + } + + fun process() { + if (removeItem(player, Item(used.id))) { + addItem(player, Items.WOLFBONE_ARROWTIPS_2861, 4) + rewardXP(player, Skills.FLETCHING, 2.5) + } + } + + sendSkillDialogue(player) { + create { id, amount -> + var actualAmount = min(amount, maxAmount) + runTask( + player, + delay = 2, + repeatTimes = actualAmount, + task = ::process + ) + } + withItems(Item(Items.WOLFBONE_ARROWTIPS_2861, 5)) + } + + return@onUseWith true + } + + onUseWith(IntType.ITEM, Items.WOLFBONE_ARROWTIPS_2861, Items.FLIGHTED_OGRE_ARROW_2865) { player, used, with -> + fun getMaxAmount(_unused: Int = 0): Int { + val tips = amountInInventory(player, Items.WOLFBONE_ARROWTIPS_2861) + val shafts = amountInInventory(player, Items.FLIGHTED_OGRE_ARROW_2865) + return min(tips, shafts) + } + + fun process() { + val amountThisIter = min(6, getMaxAmount()) + if (removeItem(player, Item(used.id, amountThisIter)) && removeItem(player, Item(with.id, amountThisIter))) { + addItem(player, Items.OGRE_ARROW_2866, amountThisIter) + sendMessage(player, "You make $amountThisIter ogre arrows.") + rewardXP(player, Skills.FLETCHING, 6.0) + } + } + + sendSkillDialogue(player) { + create { id, amount -> + runTask( + player, + delay = 2, + repeatTimes = min(amount, getMaxAmount() / 6 + 1), + task = ::process + ) + } + calculateMaxAmount(::getMaxAmount) + withItems(Item(Items.OGRE_ARROW_2866, 5)) + } + return@onUseWith true + } + + } +} diff --git a/Server/src/main/content/region/kandarin/feldip/quest/chompybird/ChompyBirdDialogues.kt b/Server/src/main/content/region/kandarin/feldip/quest/chompybird/ChompyBirdDialogues.kt new file mode 100644 index 0000000..054159f --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/quest/chompybird/ChompyBirdDialogues.kt @@ -0,0 +1,462 @@ +package content.region.kandarin.feldip.quest.chompybird + +import core.api.* + +import org.rs09.consts.NPCs +import org.rs09.consts.Items + +import core.tools.END_DIALOGUE +import core.game.dialogue.DialogueFile +import core.game.dialogue.Topic +import core.game.dialogue.IfTopic +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression + +import core.tools.RandomFunction +import core.plugin.Initializable +import core.game.node.item.Item +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import content.data.Quests + +@Initializable +class RantzDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun getIds() : IntArray { + return intArrayOf(NPCs.RANTZ_1010) + } + + override fun newInstance(player: Player?) : DialoguePlugin { + return RantzDialogue(player) + } + + override fun open(vararg args: Any?) : Boolean { + npc = args[0] as NPC + + val chompyBird = player.questRepository.getQuest(Quests.BIG_CHOMPY_BIRD_HUNTING) + val chompyStage = chompyBird.getStage(player) + + val hasOgreBow = inInventory(player, Items.OGRE_BOW_2883) || inEquipment(player, Items.OGRE_BOW_2883) || inBank(player, Items.OGRE_BOW_2883) + + if (stage in 60 until 100 && !hasOgreBow) { + stage = 201 + player.dialogueInterpreter.handle(0,0) + return true + } + + when (chompyStage) { + in 0 until 100 -> loadFile(RantzChompyBirdDialogue(chompyBird)) + } + + player.dialogueInterpreter.handle(0,0) + + return true + } + + override fun handle(componentId: Int, buttonId: Int) : Boolean { + when(stage) { + 0 -> npcl(FacialExpression.OLD_NORMAL, "Creature done good, cooking da chompy. Maybe you wants a free hatsie? Rantz got lots of hatsies for chompy shooters.").also { stage++ } + 1 -> options("What are these 'hatsies'?", "Okay, show me your 'hatsies'.", "No thanks.").also { stage++ } + 2 -> when(buttonId) { + 1 -> playerl(FacialExpression.FRIENDLY, "What are these 'hatsies'?").also { stage = 3 } + 2 -> playerl(FacialExpression.FRIENDLY, "Okay, show me your 'hatsies'.").also { stage = 100 } + 3 -> playerl(FacialExpression.FRIENDLY, "No thanks.").also { stage = END_DIALOGUE } + } + 3 -> npcl(FacialExpression.OLD_NORMAL, "Creature stupid? Hatsies to wear on head, make you look good. Huh huh huh.").also { stage++ } + 4 -> playerl(FacialExpression.FRIENDLY, "Ah, I see, you're offering me hats.").also { stage++ } + 5 -> npcl(FacialExpression.OLD_NORMAL, "Dat's what Rantz said. You want hatsies or not?").also { stage = 1 } + + 100 -> { + val hasBow = inInventory(player, Items.OGRE_BOW_2883) || inEquipment(player, Items.OGRE_BOW_2883) + + if (!hasBow) { + npcl(FacialExpression.OLD_NORMAL, "Stupid creature. Me need bow to see how many chompy creature kill. Bring bow.") + stage = 200 + return true + } + + val hats = ChompyHat.getApplicableHats(player) + if (hats.isEmpty()) { + npcl(FacialExpression.OLD_NORMAL, "Sorry, creature, no hatsies for you. Come back when kill more chompy.") + } else { + val spaces = freeSlots(player) + if (spaces < hats.size) { + for (i in 0 until spaces) addItem(player, hats[i]) + npcl(FacialExpression.OLD_NORMAL, "There all hats you can fit, creature. Come back when have more room for hatsies.") + } else { + for (hat in hats) addItem(player, hat) + npcl(FacialExpression.OLD_NORMAL, "There all hats, creature. Come back when kill more chompy. Unless you kill all chompy already.") + } + } + stage = END_DIALOGUE + } + + 200 -> showTopics( + IfTopic("About that...", 201, !inBank(player, Items.OGRE_BOW_2883)), + Topic("Okay.", END_DIALOGUE) + ) + + 201 -> npcl(FacialExpression.OLD_NORMAL, "Yes, creature?").also { stage++ } + 202 -> playerl(FacialExpression.HALF_GUILTY, "I lost my bow.").also { stage++ } + 203 -> npcl(FacialExpression.OLD_NORMAL, "Haha! Stupid creature! That okay, me can sell new one.").also { stage++ } + 204 -> playerl(FacialExpression.FRIENDLY, "Really? How much?").also { stage++ } + 205 -> npcl(FacialExpression.OLD_NORMAL, "Hmm.. let me think...").also { stage++ } + 206 -> { + val cost = RandomFunction.random(500,550) + setAttribute(player, "/save:chompybird:new-bow-cost", cost) + npcl(FacialExpression.OLD_NORMAL, "Me think $cost shiny coins be ok.") + stage++ + } + + 207 -> showTopics( + IfTopic( + "Okay.", 208, + amountInInventory(player, Items.COINS_995) >= getAttribute(player, "chompybird:new-bow-cost", 500) + ), + Topic("No thank you...", END_DIALOGUE) + ) + + 208 -> { + if (removeItem(player, Item(Items.COINS_995, getAttribute(player, "chompybird:new-bow-cost", 500)))) { + addItemOrDrop(player, Items.OGRE_BOW_2883) + npcl(FacialExpression.OLD_NORMAL, "There you go, creature, now hunt chompy.") + } else { + playerl(FacialExpression.FRIENDLY, "Actually, I can't afford it right now.") + } + stage = END_DIALOGUE + } + } + return true + } +} + +@Initializable +class BugsDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun getIds() : IntArray { + return intArrayOf(NPCs.BUGS_1012) + } + + override fun newInstance(player: Player?) : DialoguePlugin { + return BugsDialogue(player) + } + + override fun open(vararg args: Any?) : Boolean { + npc = args[0] as NPC + + val chompyBird = player.questRepository.getQuest(Quests.BIG_CHOMPY_BIRD_HUNTING) + val chompyStage = chompyBird.getStage(player) + + when (chompyStage) { + in 0 until 100 -> loadFile(BugsChompyBirdDialogue(chompyBird)) + } + + player.dialogueInterpreter.handle(0,0) + + return true + } + + override fun handle(componentId: Int, buttonId: Int) : Boolean { + return true + } +} + +@Initializable +class FycieDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun getIds() : IntArray { + return intArrayOf(NPCs.FYCIE_1011) + } + + override fun newInstance(player: Player?) : DialoguePlugin { + return FycieDialogue(player) + } + + override fun open(vararg args: Any?) : Boolean { + npc = args[0] as NPC + + val chompyBird = player.questRepository.getQuest(Quests.BIG_CHOMPY_BIRD_HUNTING) + val chompyStage = chompyBird.getStage(player) + + when (chompyStage) { + in 0 until 100 -> loadFile(FycieChompyBirdDialogue(chompyBird)) + } + + player.dialogueInterpreter.handle(0,0) + + return true + } + + override fun handle(componentId: Int, buttonId: Int) : Boolean { + return true + } +} + +class BugsChompyBirdDialogue(val quest: Quest) : DialogueFile() { + override fun handle(componentId: Int, buttonId: Int) { + when (quest.getStage(player)) { + in 0 until 20 -> npcl(FacialExpression.OLD_NORMAL, "You's better talk to Dad, him chasey sneaky da chompy.").also { stage = END_DIALOGUE } + in 20 until 70 -> handleBellowsDialogue(player, buttonId) + in 70 until 90 -> handleIngredientDialogue(player, buttonId) + } + } + + private fun handleBellowsDialogue(player: Player?, buttonId: Int) { + when(stage) { + 0 -> playerl("Rantz said that you play with the fatsy toadies, what are they?").also { stage++ } + 1 -> npcl(FacialExpression.OLD_NORMAL, "Oh, we sometimes use da blower on da toadies but Dad don't let us get in da locked box no more. He he it was good fun making da toadies fat on da swamp gas.").also { stage = END_DIALOGUE } + } + } + + private fun handleIngredientDialogue(player: Player?, buttonId: Int) { + val bugsIngredient = getAttribute(player!!, ChompyBird.ATTR_ING_BUGS, -1) + when(stage) { + 0 -> npcl(FacialExpression.OLD_NORMAL, "Dad say's you's making da chompy for us! Slurp! Me's has to have ${getItemName(bugsIngredient)} wiv mine! Chompy is our favourite yummms!").also { stage = END_DIALOGUE } + } + setAttribute(player!!, ChompyBird.ATTR_BUGS_ASKED, true) + } +} + +class FycieChompyBirdDialogue(val quest: Quest) : DialogueFile() { + override fun handle(componentId: Int, buttonId: Int) { + when (quest.getStage(player)) { + in 0 until 70 -> npcl(FacialExpression.OLD_NORMAL, "You's better talk to Dad, We not talk to wierdly 'umans.").also { stage = END_DIALOGUE } + in 70 until 90 -> handleIngredientDialogue(player, buttonId) + } + } + + private fun handleIngredientDialogue(player: Player?, buttonId: Int) { + val fycieIngredient = getAttribute(player!!, ChompyBird.ATTR_ING_FYCIE, -1) + when(stage) { + 0 -> npcl(FacialExpression.OLD_NORMAL, "Dad say's you's roasting da chompy for us! Slurp! Me's wants ${getItemName(fycieIngredient)} wiv mine! Yummy can't wait to eats it.").also { stage = END_DIALOGUE } + } + setAttribute(player!!, ChompyBird.ATTR_FYCIE_ASKED, true) + } +} + +class RantzChompyBirdDialogue(val quest: Quest) : DialogueFile() { + override fun handle(componentId: Int, buttonId: Int) { + when (quest.getStage(player)) { + 0 -> handleQuestStartDialogue(player, buttonId) + in 20 until 30 -> handleToadsiesDialogue(player, buttonId) + in 30 until 40 -> handlePlaceToadsiesDialogue(player, buttonId) + in 40 until 50 -> handlePlacedBaitDialogue(player, buttonId) + in 50 until 60 -> handleRantzSucksDialogue(player, buttonId) + in 60 until 70 -> handleWaitingForChompyDialogue(player, buttonId) + in 70 until 80 -> handleWaitingForCookedChompy(player, buttonId) + else -> handleImpatienceDialogue(player, buttonId) + } + } + + private fun handleQuestStartDialogue(player: Player?, buttonId: Int) { + when(stage) { + 0 -> npcl(FacialExpression.OLD_NORMAL, "Hey you creature! Make some stabbers! I wanna hunt da chompy?").also { stage++ } + 1 -> options("What are 'stabbers'?", "What's a 'chompy'?", "Ok, I'll make you some 'stabbers'.", "Er, make your own 'stabbers'!").also { stage++ } + 2 -> when(buttonId) { + 1 -> playerl("What are 'stabbers'?").also { stage = 3 } + 2 -> playerl("What's a 'chompy'?").also { stage = 7 } + 3 -> playerl("Ok, I'll make you some 'stabbers'.").also { stage = 10 } + 4 -> playerl("Er, make your own 'stabbers'!").also { stage = END_DIALOGUE } + } + 3 -> npcl(FacialExpression.OLD_NORMAL, "For da stabbie chucker, I's wanna hunt da chompy! Creature knows what Rantz wants... ...flyin' to stabbie da chompy!").also { stage++ } + 4 -> npcl(FacialExpression.OLD_NORMAL, "The ogre shows you a huge but crude bow and then starts to nod energetically in an effort to help you understand.").also { stage++ } + 5 -> playerl("I think I understand. You want me to make some arrows for you?").also { stage++ } + 6 -> npcl(FacialExpression.OLD_NORMAL, "Yeah, is what Rantz sayed, make da stabbers for da stabby chucker!").also { stage = 1 } + 7 -> npcl(FacialExpression.OLD_NORMAL, "Da chompy is der bestest yummies for Rantz, Fycie and Bugs! We's looking for da yummies all da time. Da chompy is a big flapper, Rantz want's stabbers to sneaky, sneaky, stick da chompy.").also { stage++ } + 8 -> playerl("Ah, so 'da chompy' is some kind of bird?").also { stage++ } + 9 -> npcl(FacialExpression.OLD_NORMAL, "Yeah, is what Rantz sayed, Da chompy is da big flapper and is bestest yummies. But Rantz needs stabbers to stick da chompy... Will creatures make dem stabbers for us?").also {stage = 1 } + 10 -> npcl(FacialExpression.OLD_NORMAL, "Good you creature, you need sticksies from achey tree and stabbies from dog bones.").also { stage = END_DIALOGUE; quest.start(player) } + } + } + + private fun handleImpatienceDialogue(player: Player?, buttonId: Int) { + val hasArrows = amountInInventory(player!!, Items.OGRE_ARROW_2866) > 0 + + when(stage) { + 0 -> npcl(FacialExpression.OLD_NORMAL, "Hey you creature... Have you made me da stabbers? I wanna stick da chompy?").also { stage++ } + + 1 -> { + if (!hasArrows) { + playerl("Er not exactly?").also { stage++ } + } else { + playerl(FacialExpression.ANNOYED, "Well, yes actually, as you asked so nicely. Here you go! Here's your 'stabbers'.") + stage = 100 + } + } + + 2 -> npcl(FacialExpression.OLD_NORMAL, "You do stabbers quick!...quick!.. Or Rantz make stabbers for Rantz and then practice for chompy sticking on creature!").also { stage++ } + 3 -> options("How do I make the 'stabbers' again?", "Ok, I'll make the 'stabbers' for you.").also { stage++ } + 4 -> when(buttonId) { + 1 -> playerl("How do I make the 'stabbers' again?").also { stage = 5 } + 2 -> playerl("Ok, I'll make the 'stabbers' for you.").also { stage = END_DIALOGUE } + } + 5 -> npcl(FacialExpression.OLD_NORMAL, "Grrr creature... you's no good stabber maker! You's make da stabbie bit from da dog bones, and get da sticksies from da Achey tree... simple see! Oh and da flufgies from da flappers as well!").also { stage++ } + 6 -> playerl("Oh, so I need logs from the achey tree, bones from a canine... and feather?").also { stage++ } + 7 -> npcl(FacialExpression.OLD_NORMAL, "Is just what Rantz sayed!").also { stage++ } + 8 -> npcl(FacialExpression.OLD_NORMAL, "The hulking ogre nods excitedly.").also { stage = END_DIALOGUE } + + 100 -> { + sendItemDialogue(player!!, Item(Items.OGRE_ARROW_2866, 20), "Rantz takes six ogre arrows off you.") + removeItem(player!!, Item(Items.OGRE_ARROW_2866, 6)) + stage++ + } + + 101 -> { + npcl(FacialExpression.OLD_NORMAL, "Ahh, der creature has dem...goodly, goodly. Now us can stick der chompy bird...") + stage = 4 //Skips to "How do we make the chompsys come?" in the dialogue below + quest.setStage(player, 20) + } + } + } + + private fun handleToadsiesDialogue(player: Player?, buttonId: Int) { + val hasToads = amountInInventory(player!!, Items.BLOATED_TOAD_2875) > 0 + + when(stage) { + 0 -> npcl(FacialExpression.OLD_NORMAL, "Hey you creature you still here?").also { stage++ } + 1 -> npcl(FacialExpression.OLD_NORMAL, "Da chompy still not coming! We need da fatsy toady to get da chompy, do you got it? Do you got da fatsy toady? Then we can sneaky, sneaky stick da chompy.").also { stage++ } + 2 -> { + if (hasToads) { + playerl("Yes, I have a 'fatsy toady' for you, here look!") + stage = 100 + } else { + playerl("No I haven't got the 'fatsy toady' yet!").also { stage++ } + } + } + 3 -> npcl(FacialExpression.OLD_NORMAL, "Dat's a pidy... but maybe Rantz can help da creature?").also { stage++ } + 4 -> options("How do we make the chompys come?", "What are 'fatsy toadies'?", "Where do we put the fatsy toadies?", "What do you mean 'sneaky..sneaky.. stick da chompy?'", "Ok, thanks.").also { stage++ } + 5 -> when(buttonId) { + 1 -> playerl("How do we make the chompys come?").also { stage = 6 } + 2 -> playerl("What are 'fatsy toadies'?").also { stage = 8 } + 3 -> playerl("Where do we put the fatsy toadies?").also { stage = 9 } + 4 -> playerl("What do you mean 'sneaky..sneaky.. stick da chompy?'").also { stage = 12 } + 5 -> playerl("Ok, thanks.").also { stage = END_DIALOGUE } + } + 6 -> npcl(FacialExpression.OLD_NORMAL, "Chompys love da fatsy toadies. Toadies get big on der swamp gas and der chomys are licking der lips for em as me is licking lips for da chompy. Da chompys don't like da smaller toadies from nearby swampy.").also { stage++ } + 7 -> npcl(FacialExpression.OLD_NORMAL, "Dey's fussie eaters like Rantz. Fycie an Bugs play with toadies and blower dey's all times making fatsy toadies.").also { stage = 4 } + 8 -> npcl(FacialExpression.OLD_NORMAL, "Fatsy toadies are da chompy burds bestest yumms. But da toadies here are too small for da chompy. You've godda make da toadies big and round!").also { stage = 4 } + 9 -> npcl(FacialExpression.OLD_NORMAL, "Over der!").also { stage++ } + 10 -> npcl(FacialExpression.OLD_NORMAL, "The ogre points to a small clearing to da south.").also { stage++ } + 11 -> npcl(FacialExpression.OLD_NORMAL, "Ok creature? You got dat? Over here by der no tree's place.").also { stage = 4 } + 12 -> npcl(FacialExpression.OLD_NORMAL, "Duh! You creature is a bit stoopid yes? Us needs to sneaky, sneaky.. and stick da chompy! Den we can eat da chompy!").also { stage = 4 } + + 100 -> sendItemDialogue(player!!, Items.BLOATED_TOAD_2875, "You show the bloated toad to Rantz. He nods with approval.").also { stage++ } + 101 -> npcl(FacialExpression.OLD_NORMAL, "Dat's a good fatsy toady, now we's need to put it for da chompy to come.").also { stage++ } + 102 -> { + playerl("Where do I put the 'fatsy toadies'?").also { stage++ } + quest.setStage(player, 30) + stage = 0 + } + } + } + + private fun handlePlaceToadsiesDialogue(player: Player?, buttonId: Int) { + npcl(FacialExpression.OLD_NORMAL, "Over 'dere creature, put da toadies over der! ~ The ogre points to a clearing to the south. ~") + clearHintIcon(player!!) + registerHintIcon(player!!, ChompyBird.TOAD_LOCATION, 5) //TODO: ADD OFFSETS WHEN WE UNFUCK ARIOS'S MISTAKES, YEET + stage = END_DIALOGUE + } + + private fun handlePlacedBaitDialogue(player: Player?, buttonId: Int) { + when(stage) { + 0 -> playerl("There you go, I've placed the bait.").also { stage++ } + 1 -> npcl(FacialExpression.OLD_NORMAL, "Goodz me now waits for da chompy! It shouldn't be long now. Sneaky...sneaky...").also { stage++ } + 2 -> playerl("Yes, I know...stick da chompy!").also { stage++ } + 3 -> npcl(FacialExpression.OLD_NORMAL, "Hey.. you's creature, is da fatsy toady still dere? Go get more fatsy toadies if dey all gone!").also { stage++ } + 4 -> playerl("What? I have to get more bait if there's none there? Does this Chompy Bird even exist I wonder?").also { stage = END_DIALOGUE } + } + } + + private fun handleRantzSucksDialogue(player: Player?, buttonId: Int) { + when(stage) { + 0 -> playerl("Hey there, you keep missing the chompy bird.").also { stage++ } + 1 -> npcl(FacialExpression.OLD_NORMAL, "I knows, I keeps missing... because your stabbers are worserer at flying than a dead dog.").also { stage++ } + 2 -> options("Oh, keep trying then... you might hit one through pure luck.", "Come on, let me have a go...").also { stage++ } + 3 -> when(buttonId) { + 1 -> playerl("Oh, keep trying then... you might hit one through pure luck.").also { stage = END_DIALOGUE } + 2 -> playerl("Come on, let me have a go...").also { stage = 4 } + } + 4 -> npcl(FacialExpression.OLD_NORMAL, "No, is Rantz stabby thrower... you too weedy...").also { stage++ } + 5 -> options("I'm actually quite strong... please let me try.", "Oh suit yourself, you'll just have to go hungry.").also { stage++ } + 6 -> when(buttonId) { + 1 -> playerl("I'm actually quite strong... please let me try.").also { stage = 7 } + 2 -> playerl("Oh suit yourself, you'll just have to go hungry.").also { stage = END_DIALOGUE } + } + 7 -> npcl(FacialExpression.OLD_NORMAL, "Oh, ok... I lend you other stabby thrower... but creature don't better cry when it hurts itself.").also { stage++ } + 8 -> { + sendItemDialogue(player!!, Items.OGRE_BOW_2883, "Rantz hands over an ogre bow. It's huge! You can barely drawn back the string!") + addItemOrDrop(player!!, Items.OGRE_BOW_2883) + stage = END_DIALOGUE + quest.setStage(player, 60) + } + } + } + + private fun handleWaitingForChompyDialogue(player: Player?, buttonId: Int) { + val hasChompyBird = amountInInventory(player!!, Items.RAW_CHOMPY_2876) > 0 + + assignRandomIngredients(player ?: return) + val rantzIngredient = getAttribute(player, ChompyBird.ATTR_ING_RANTZ, -1) + + when(stage) { + 0 -> npcl(FacialExpression.OLD_NORMAL, "Hey You! Got da chompy yet?").also { stage++ } + 1 -> { + if (hasChompyBird) { + playerl("Yep, here's your chompy Bird!") + stage = 100 + } else { + playerl("Not yet!").also { stage++ } + } + } + 2 -> npcl(FacialExpression.OLD_NORMAL, "Well hurry up and get some, we is hungry!").also { stage = END_DIALOGUE } + + 100 -> sendItemDialogue(player!!, Items.RAW_CHOMPY_2876, "You show Rantz the freshly plucked chompy carcass.").also { stage++ } + 101 -> npcl(FacialExpression.OLD_NORMAL, "Dat's a great chompy, you musta got a lucky shot wiv da stabbie chucker.").also { stage++ } + 102 -> npcl(FacialExpression.OLD_NORMAL, "Okay's now you's needs to cook da chompy! Slurp! You's can cook it's over der! ~Rantz points to a nearby spit roast.~").also { stage++ } + 103 -> npcl(FacialExpression.OLD_NORMAL, "But's we's particular about our chompy yumms. Me's wants ${getItemName(rantzIngredient)} wiv mine! Fycie and Bugs want something wiv der's as well, go and ask 'em wat dey want.").also { stage++ } + 104 -> playerl("What! Now I've got the chompy bird, you expect me to cook it as well?").also { stage++ } + 105 -> npcl(FacialExpression.OLD_NORMAL, "Yep, da spit's over der! Last time Rantz did yummies, got very bad, did bad things to food.. and belly.").also { stage++ } + 106 -> { + playerl("HUH!").also { stage = END_DIALOGUE } + quest.setStage(player, 70) + } + } + } + + private fun handleWaitingForCookedChompy(player: Player?, buttonId: Int) { + val hasCookedChompy = amountInInventory(player!!, Items.SEASONED_CHOMPY_2882) > 0 + + when (stage) { + 0 -> npcl(FacialExpression.OLD_NORMAL, "Hey You! Cook da chompy yet?").also { stage++ } + 1 -> { + if (hasCookedChompy) { + playerl("Yep, here you go, here's your cooked chompy bird.") + stage = 100 + } else { + playerl("Not yet!").also { stage++ } + } + } + 2 -> npcl(FacialExpression.OLD_NORMAL, "Well hurry up, we is hungry!").also { stage = END_DIALOGUE } + + 100 -> sendItemDialogue(player!!, Items.SEASONED_CHOMPY_2882, "You hand over the cooked chompy bird to Rantz.").also { stage++ } + 101 -> npcl(FacialExpression.OLD_NORMAL, "Hey hey! We got da delicious chompy bird Yay! This looks really tasty as well!").also { stage++ } + 102 -> npcl(FacialExpression.OLD_NORMAL, "Tank's very much for da chompy... Fycie an Bugs like very much da chompy yumms!").also { stage++ } + 103 -> sendDialogue(player, "~The family of ogres sit down together~").also { stage++ } + 104 -> sendDialogue(player, "~and enjoy your well cooked chompy bird.~").also { stage++ } + 105 -> playerl("It's my pleasure!").also { stage = END_DIALOGUE; quest.finish(player) } + } + } + + private fun assignRandomIngredients(player: Player) { + val possibleIngredients = arrayListOf( + Items.ONION_1957, + Items.DOOGLE_LEAVES_1573, + Items.EQUA_LEAVES_2128, + Items.TOMATO_1982, + Items.POTATO_1942, + Items.CABBAGE_1965 + ) + + setAttribute(player, ChompyBird.ATTR_ING_RANTZ, possibleIngredients.random().also { possibleIngredients.remove(it) }) + setAttribute(player, ChompyBird.ATTR_ING_BUGS, possibleIngredients.random().also { possibleIngredients.remove(it) }) + setAttribute(player, ChompyBird.ATTR_ING_FYCIE, possibleIngredients.random().also { possibleIngredients.remove(it) }) + } +} diff --git a/Server/src/main/content/region/kandarin/feldip/quest/chompybird/ChompyBirdNPC.kt b/Server/src/main/content/region/kandarin/feldip/quest/chompybird/ChompyBirdNPC.kt new file mode 100644 index 0000000..337f30a --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/quest/chompybird/ChompyBirdNPC.kt @@ -0,0 +1,173 @@ +package content.region.kandarin.feldip.quest.chompybird + +import core.api.* + +import org.rs09.consts.NPCs +import org.rs09.consts.Items +import org.rs09.consts.Animations + +import core.plugin.Initializable +import core.tools.RandomFunction +import core.game.system.task.Pulse + +import core.game.node.Node +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.combat.BattleState +import core.game.node.entity.combat.CombatStyle + +import core.game.world.map.Location +import core.game.world.map.path.Pathfinder +import core.game.interaction.MovementPulse +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.game.world.update.flag.context.Animation + +@Initializable +class ChompyBirdNPC : AbstractNPC, InteractionListener { + constructor() : super(NPCs.CHOMPY_BIRD_1550, null, true) + private constructor(id: Int, location: Location) : super(id, location) {} + + var timeToLive = 100 + + override fun init() { + super.init() + val toad = getAttribute("toad", null) + animate(Animation(Animations.CHOMPY_SPAWN_6766)) + + if (toad != null) { + submitIndividualPulse(this, object : MovementPulse(this, toad, Pathfinder.SMART) { + var bufferTicks = 7 + override fun pulse() : Boolean { + if (bufferTicks-- == 0) { + setAttribute("toad_eaten", true) + toad.clear() + return true + } + return false + } + }) + } + } + + override fun construct(id: Int, location: Location, vararg objects: Any?): AbstractNPC { + val npc = ChompyBirdNPC(id, location) + npc.isRespawn = false + return npc + } + + override fun getIds() : IntArray { + return intArrayOf(NPCs.CHOMPY_BIRD_1550) + } + + override fun isAttackable(entity: Entity, style: CombatStyle, message: Boolean) : Boolean { + if (entity !is Player) return true + + var attackable = super.isAttackable(entity, style, message) + val hasOgreBow = inEquipment(entity, Items.OGRE_BOW_2883) + + if (!hasOgreBow) { + sendMessage(entity, "You need an ogre bow to hunt chompy birds.") + } + + return attackable && hasOgreBow + } + + override fun attack(node: Node) {} + + override fun checkImpact(state: BattleState) { + super.checkImpact(state) + if (getAttribute("toad_eaten", false) || state.attacker.id == NPCs.RANTZ_1010) { + impactHandler.disabledTicks = 10 + locks.lockInteractions(10) + sendChat("Squawk!") + submitWorldPulse(object : Pulse(2) { + var counter = 0 + override fun pulse() : Boolean { + when (counter++) { + 1 -> animate(Animation(Animations.CHOMPY_FLY_AWAY_6767)) + 2 -> clear() + 3 -> return true + } + return false + } + }) + } else { + sendChat("Screech!") + } + } + + override fun tick() { + if (this.inCombat() && this.skills.lifepoints > 0) { + val newLoc = this.location.transform( + RandomFunction.random(-2,2), + RandomFunction.random(-2,2), + 0 + ) + submitIndividualPulse(this, object : MovementPulse(this, newLoc, Pathfinder.DUMB) { + override fun pulse() : Boolean { return true } + }) + } + super.tick() + } + + override fun handleTickActions() { + if (id == NPCs.CHOMPY_BIRD_1550) { + if (getAttribute("toad_eaten", false)) { + super.handleTickActions() + } + if (timeToLive-- <= 0) { + animate(Animation(Animations.CHOMPY_FLY_AWAY_6767)) + runTask(this, 2) { clear() } + timeToLive = 100 + } + } else { + if (timeToLive-- <= 0) + clear() + } + } + + override fun finalizeDeath(killer: Entity) { + properties.teleportLocation = null + val newSelf = transform(NPCs.CHOMPY_BIRD_1016) + newSelf.isNeverWalks = true + newSelf.isWalks = false + newSelf.walkRadius = 0 + timeToLive = 200 + + this.pulseManager.clear() + this.walkingQueue.reset() + + if (killer is Player) { + sendMessage(killer, "You scratch a notch on your bow for the chompy bird kill.") + val old = killer.getAttribute("chompy-kills", 0) + killer.setAttribute("/save:chompy-kills", old + 1) + ChompyHat.checkForNewRank(killer) + } + } + + override fun defineListeners() { + on(NPCs.CHOMPY_BIRD_1016, IntType.NPC, "pluck") { player, node -> + val bird = node.asNpc() + + if (!bird.getAttribute("plucked", false)) { + addItem(player, Items.FEATHER_314, RandomFunction.random(25, 32)) + produceGroundItem(player, Items.BONES_526, 1, bird.location) + produceGroundItem(player, Items.RAW_CHOMPY_2876, 1, bird.location) + bird.clear() + } + + bird.setAttribute("plucked", true) + + return@on true + } + + on(intArrayOf(Items.OGRE_BOW_2883, Items.COMP_OGRE_BOW_4827), IntType.ITEM, "check kills") { player, _ -> + val amount = player.getAttribute("chompy-kills", 0) + sendDialogue(player, "You have killed $amount chompy birds.") + return@on true + } + } +} diff --git a/Server/src/main/content/region/kandarin/feldip/quest/chompybird/ChompyHat.kt b/Server/src/main/content/region/kandarin/feldip/quest/chompybird/ChompyHat.kt new file mode 100644 index 0000000..7e09f00 --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/quest/chompybird/ChompyHat.kt @@ -0,0 +1,73 @@ +package content.region.kandarin.feldip.quest.chompybird + +import core.api.* +import core.tools.colorize + +import org.rs09.consts.Items + +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player + +import java.util.* + +enum class ChompyHat(val id: Int, val kills: Int, val rankName: String) { + O_BOWMAN(Items.CHOMPY_BIRD_HAT_2978, 30, "an Ogre Bowman"), + BOWMAN(Items.CHOMPY_BIRD_HAT_2979, 40, "a Bowman"), + O_YEOMAN(Items.CHOMPY_BIRD_HAT_2980, 50, "an Ogre Yeoman"), + YEOMAN(Items.CHOMPY_BIRD_HAT_2981, 70, "a Yeoman"), + O_MARKSMAN(Items.CHOMPY_BIRD_HAT_2982, 95, "an Ogre Marksman"), + MARKSMAN(Items.CHOMPY_BIRD_HAT_2983, 125, "a Marksman"), + O_WOODSMAN(Items.CHOMPY_BIRD_HAT_2984, 170, "an Ogre Woodsman"), + WOODSMAN(Items.CHOMPY_BIRD_HAT_2985, 225, "a Woodsman"), + O_FORESTER(Items.CHOMPY_BIRD_HAT_2986, 300, "an Ogre Forester"), + FORESTER(Items.CHOMPY_BIRD_HAT_2987, 400, "a Forester"), + O_BOWMASTER(Items.CHOMPY_BIRD_HAT_2988, 550, "an Ogre Bowmaster"), + BOWMASTER(Items.CHOMPY_BIRD_HAT_2989, 700, "a Bowmaster"), + O_EXPERT(Items.CHOMPY_BIRD_HAT_2990, 1000, "an Ogre Expert"), + EXPERT(Items.CHOMPY_BIRD_HAT_2991, 1300, "an Expert"), + O_DA(Items.CHOMPY_BIRD_HAT_2992, 1700, "an Ogre Dragon Archer"), + DA(Items.CHOMPY_BIRD_HAT_2993, 2250, "a Dragon Archer"), + EO_DA(Items.CHOMPY_BIRD_HAT_2994, 3000, "an Expert Ogre Dragon Archer"), + E_DA(Items.CHOMPY_BIRD_HAT_2995, 4000, "an Expert Dragon Archer"); + + companion object { + val killMap = values().map { it.kills to it }.toMap() + + fun checkForNewRank(player: Player) { + val kills = getAttribute(player, "chompy-kills", 0) + val newRank = killMap[kills] ?: return + + sendDialogueLines(player, + colorize("%B*** Congratulations! $kills Chompies! ***"), + colorize("%R~ You're ${newRank.rankName} ~") + ) + } + + fun getApplicableHats(player: Player) : List { + val kills = getAttribute(player, "chompy-kills", 0) + val hats = ArrayList() + for (hat in values()) { + if (hat.kills > kills) break + if (inInventory(player, hat.id) || inEquipment(player, hat.id) || inBank(player, hat.id)) continue + hats.add(hat.id) + } + return hats + } + } +} + +class ChompyEquipListener : InteractionListener { + override fun defineListeners() { + ChompyHat.values().forEach { hat -> + onEquip(hat.id) {player, node -> + val kills = getAttribute(player, "chompy-kills", 0) + if (kills < hat.kills) { + sendItemDialogue(player, node.id, "You haven't earned this!") + removeItem(player, node.asItem()) + return@onEquip false + } + return@onEquip true + } + } + } +} diff --git a/Server/src/main/content/region/kandarin/feldip/quest/chompybird/RantzNPC.kt b/Server/src/main/content/region/kandarin/feldip/quest/chompybird/RantzNPC.kt new file mode 100644 index 0000000..f0f1ca4 --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/quest/chompybird/RantzNPC.kt @@ -0,0 +1,44 @@ +package content.region.kandarin.feldip.quest.chompybird + +import core.api.* + +import org.rs09.consts.NPCs + +import core.plugin.Initializable +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.player.Player +import core.game.world.map.Location +import content.data.Quests + +@Initializable +class RantzNPC : AbstractNPC { + constructor() : super(NPCs.RANTZ_1010, null, true) + private constructor(id: Int, location: Location) : super(id, location) + + override fun construct(id: Int, location: Location, vararg objects: Any?) : AbstractNPC { + return RantzNPC(id, location) + } + + override fun getIds() : IntArray { + return intArrayOf(NPCs.RANTZ_1010) + } + + override fun handleTickActions() { + super.handleTickActions() + val chompy = findLocalNPC(this, NPCs.CHOMPY_BIRD_1550) as? ChompyBirdNPC ?: return + + val owner = getAttribute(chompy, "owner", null) ?: return + val quest = owner.questRepository.getQuest(Quests.BIG_CHOMPY_BIRD_HUNTING) + + if (quest.getStage(owner) !in 40..50 || chompy.getAttribute("attacked", false)) return + + sendChat("Hey, dere's da chompy, I's gonna shoot it.") + sendMessage(owner, "Rantz: Hey, dere's da chompy, I's gonna shoot it.") + sendMessage(owner, "Rantz keeps missing the chompy bird.") + sendMessage(owner, "Rantz: Grrr...de'ese arrows are rubbish.") + + attack(chompy) + chompy.setAttribute("attacked", true) + quest.setStage(owner, 50) + } +} diff --git a/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/BartenderDialogueFile.kt b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/BartenderDialogueFile.kt new file mode 100644 index 0000000..b93f3a8 --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/BartenderDialogueFile.kt @@ -0,0 +1,62 @@ +package content.region.kandarin.feldip.quest.zogreflesheaters + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.FacialExpression +import org.rs09.consts.Items + +class BartenderDialogueFile(private val dialogueNum: Int = 0) : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + + b.onPredicate { _ -> dialogueNum == 1 } + .branch { player -> + return@branch if (getAttribute(player, ZogreFleshEaters.attributeAskedAboutTankard, false)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(0) + .playerl("Hello there, I found this tankard in an ogre tomb cavern. It has the emblem of this Inn on it and I wondered if you knew anything about it?") + .npcl("Oh yes, this is Brentle's mug...I'm surprised he left it just lying around down some cave. He's quite protective of it.") + .playerl("Brentle you say? So you knew him then?") + .npcl("Yeah, this belongs to 'Brentle Vahn', he's quite a common customer, though I've not seen him in a while.") + .npcl(FacialExpression.THINKING, "He was talking to some shifty looking wizard the other day. I don't know his name, but I'd recognise him if I saw him.") + .playerl("Hmm, I'm sorry to tell you this, but Brentle Vahn is dead - I believe he was murdered.") + .npcl(FacialExpression.EXTREMELY_SHOCKED, "Noooo! I'm shocked...") + .npcl("...but not surprised. He was a good customer...but I knew he would sell his sword arm and do many a dark deed if paid enough.") + .npcl(FacialExpression.SAD, "If you need help bringing the culprit to justice, you let me know.") + .endWith { _, player -> + setAttribute(player, ZogreFleshEaters.attributeAskedAboutTankard, true) + } + branch.onValue(1) + .playerl("Hello again. Can you tell me what you know about this tankard again please?") + .npcl("Oh yes, Brentle's tankard. Yeah, you've shown me this already. It belonged to Brentle Vahn, he was quite a common customer, though I've not seen him in a while.") + .npcl("He was talking to some shifty looking wizard the other day. I don't know his name, but I'd recognise him if I saw him.") + .npcl(FacialExpression.SAD, "If you need help bringing the culprit to justice, you let me know.") + .end() + } + + b.onPredicate { _ -> dialogueNum == 2 } + .iteml(Items.SITHIK_PORTRAIT_4814, "You show the portrait to the Inn keeper.") + .npcl("Yeah, that's the guy who was talking to Brentle Vahn the other day! Look at those eyes, never a more shifty looking pair will you ever see!") + .playerl("Hmm, you've just identified the man who I think sent Brentle Vahn to his death.") + .playerl("I'm trying to bring him to justice with the Wizards' Guild grand secretary. Do you think you could sign this portrait to say that he was talking to Brentle Vahn.") + .npcl("I can and I will!") + .betweenStage { df, player, _, _ -> + if (removeItem(player, Items.SITHIK_PORTRAIT_4814)) { + addItemOrDrop(player, Items.SIGNED_PORTRAIT_4816) + } + } + .iteml(Items.SIGNED_PORTRAIT_4816, "The Dragon Inn bartender signs the portrait.") + .playerl("Many thanks for your help, it's really very good of you.") + .npcl("Not at all, just doing my part.") + .end() + + + b.onPredicate { _ -> dialogueNum == 3 } + .iteml(Items.SITHIK_PORTRAIT_4815, "You show the sketch to the Inn keeper.") + .npcl("Who's that? I mean, I guess it's a picture of a person isn't it? Sorry...you've got me? And before you ask, you're not putting it up on my wall!") + .playerl("It's a portrait of Sithik Ints...don't you recognise him?") + .npcl("I'm sorry, I really am, but I just don't see it...can you make a better picture?") + .playerl("I'll try...") + .end() + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/GrishDialogue.kt b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/GrishDialogue.kt new file mode 100644 index 0000000..7e518f0 --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/GrishDialogue.kt @@ -0,0 +1,184 @@ +package content.region.kandarin.feldip.quest.zogreflesheaters + +import content.region.kandarin.quest.templeofikov.TempleOfIkov +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class GrishDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return GrishDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, GrishDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.GRISH_2038) + } +} +class GrishDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onQuestStages(ZogreFleshEaters.questName, 0) + .playerl(FacialExpression.FRIENDLY, "Hello there, what's going on here?") + .npcl(FacialExpression.OLD_NORMAL, "Hey yous creature...wha's you's doing here? Yous be cleverer to be running so da sickies from da zogres don't dead ya.") + + .let { builder -> + val returnJoin = b.placeholder() + returnJoin.builder() + .options() + .let { optionBuilder -> + optionBuilder.option_playerl("I'm just looking around thanks.") + .npcl(FacialExpression.OLD_NORMAL, "Yous creature won'ts see muchly in dis place...just da zogries coming wiv da sickies.") + .goto(returnJoin) + optionBuilder.option_playerl("What do you mean sickies?") + .npc(FacialExpression.OLD_NORMAL, "Da zogries comin wiv da sickies...yous get bashed by da", "zogries and get da sickies...den you gonna be like da", "zogries.") + .playerl(FacialExpression.FRIENDLY, "Sorry, I just don't understand...") + .betweenStage { df, player, _, _ -> + animate(npc!!, 2090) + setAttribute(player, ZogreFleshEaters.attributeAskedAboutSickies, true) + } + .npc(FacialExpression.OLD_NORMAL, "Da sickies is when yous creature goes like orange till", "green and then goes 'Urggghhhh!'", "~ Grish imitates falling down with only the white of his", "eyes visible. ~") + .goto(returnJoin); + optionBuilder.option_playerl("What are Zogres?") + .npcl(FacialExpression.OLD_NORMAL, "a Zogres are da bigun nasties wiv da sickies, deys old pals of Grish but deys jig in Jiggig when dey's full home is deep in da dirt, dey's is not da same dead'uns like was before.") + .goto(returnJoin); + optionBuilder.optionIf("Can I help in any way?") { player -> return@optionIf getAttribute(player, ZogreFleshEaters.attributeAskedAboutSickies, false) } + .playerl(FacialExpression.FRIENDLY, "Can I help in any way?") + .branch { player -> + return@branch if (ZogreFleshEaters.requirements(player)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(0) + .npcl(FacialExpression.OLD_NORMAL, "Sorry, yous creatures, but yous is too green behind da ears for dis job Grish finks.") + .playerl(FacialExpression.ANGRY, "No, I'm not!") + .npcl(FacialExpression.OLD_ANGRY1, "Yes you are!") + .playerl(FacialExpression.ANGRY, "No, I'm not!") + .npcl(FacialExpression.OLD_ANGRY1, "Yes you are and that's final!") + .end() + branch.onValue(1) + .npcl(FacialExpression.OLD_NORMAL, "Yes creatures...yous does good fings for Grish and learn why Zogries at Jiggig and den get da Zogries back in da ground.") + .playerl("Oh, so you want me to find out why the Zogres have appeared and then find a way of burying them?") + .npcl(FacialExpression.OLD_NORMAL, "Is what Grish says! But dis is da biggy danger fing yous creatures...yous be geddin' sickies most surely...yous needs be ready..wiv da foodies un da glug-glugs.") + .playerl("Right, so you think there's a good chance that I can get ill from this, so I need to get some food and something to drink?") + .npcl(FacialExpression.OLD_NORMAL, "Yea creatures, yous just say what Grish says...not know own wordies creature?") + .options() + .let { optionBuilder -> + optionBuilder.option_playerl("Hmm, sorry, it sounds a bit too dangerous.") + .npcl(FacialExpression.OLD_NORMAL, "Yous creature is not a stoopid one...stays out of dere, like clever Grish. Yous can paint circles on chest and be da Shaman too!") + .playerl("Hmm, is it too late to reconsider?") + .end() + optionBuilder.option_playerl("Ok, I'll check things out then and report back.") + .npcl(FacialExpression.OLD_NORMAL, "Is yous creatures really, really sure yous wanna do dis creatures..we's got no glug-glugs for da sickies? We's knows nuffin for da going of da sickies?") + .options() + .let { optionBuilder2 -> + optionBuilder2.option_playerl("Yes, I'm really sure!") + .npcl(FacialExpression.OLD_NORMAL,"Dats da good fing yous creature...yous does Grish a good fing. But yous know dat yous get sickies and mebe get dead!") + .playerl("If that's your idea of a pep talk, I have to say that it leaves a lot to be desired.") + .npcl(FacialExpression.OLD_NORMAL,"Yous creatures is alus says funny stuff...speaks proper like Grish!") + .manualStage() { df, player, _, _ -> + sendDoubleItemDialogue(player, Items.COOKED_CHOMPY_2878, Items.SUPER_RESTORE3_3026, "Grish hands you some food and two potions.") + } + .npcl(FacialExpression.OLD_NORMAL,"Der's yous go creatures...da best me's do for yous...and be back wivout da sickies.") + .endWith { _, player -> + if(getQuestStage(player, ZogreFleshEaters.questName) == 0) { + // Trying to prevent players from spamming to get more super restores. + addItemOrDrop(player, Items.COOKED_CHOMPY_2878, 3) + addItemOrDrop(player, Items.SUPER_RESTORE3_3026, 2) + setQuestStage(player, ZogreFleshEaters.questName, 1) + } + } + optionBuilder2.option_playerl("Hmm, sorry, it sounds a bit too dangerous.") + .npcl(FacialExpression.OLD_NORMAL, "Yous creature is not a stoopid one...stays out of dere, like clever Grish. Yous can paint circles on chest and be da Shaman too!") + .end() + } + } + + } + optionBuilder.option_playerl("Sorry, I have to go.") + .end() + } + } + + b.onQuestStages(ZogreFleshEaters.questName, 1,2,3,4,5,6) + .npcl(FacialExpression.OLD_NORMAL, "Yous creature dun da fing yet? Da zogries going in da dirt full home?") + .playerl("Nope, I haven't figured out why the zogres are here yet.") + .end() + + b.onQuestStages(ZogreFleshEaters.questName, 7) + .npcl(FacialExpression.OLD_NORMAL,"Yous creature dun da fing yet? Da zogries going in da ground?") + .playerl("I found who's responsible for the Zogres being here.") + .npcl(FacialExpression.OLD_NORMAL,"Where is da creature? Me's wants to squeeze him till he's a deadun...") + .playerl("The person responsible is a wizard named 'Sithik Ints' and he's going to be in serious trouble. He told me that the spell which raised the zogres from the ground will last forever.") + .playerl("I'm sorry to say, but you'll have to move the site of your ceremonial dancing somewhere else.") + .npcl(FacialExpression.OLD_NORMAL,"Dat is da bad fing creature...we's needs new Jiggig for da fallin' down jig.") + .playerl("Yes, that's right, you'll need to create a new ceremonial dance area.") + .npcl(FacialExpression.OLD_NORMAL,"Urghhh...not good fing creature, yous gotta get da ogrish old fings for da making new jiggig special. You's creature needs da key for getting in da low bury place.") + .betweenStage { df, player, _, _ -> + addItemOrDrop(player, Items.OGRE_GATE_KEY_4839) + } + .iteml(Items.OGRE_GATE_KEY_4839, "Grish gives you a crudely crafted key.") + .playerl("Oh, so you want me to go back in there and look for something for you?") + .npcl(FacialExpression.OLD_NORMAL,"Yeah creature, yous gotta get da ogrish old fings for da making new jiggig and proper in da special way.") + .endWith { _, player -> + if(getQuestStage(player, ZogreFleshEaters.questName) == 7) { + setQuestStage(player, ZogreFleshEaters.questName, 8) + } + } + + b.onQuestStages(ZogreFleshEaters.questName, 8) + .npcl(FacialExpression.OLD_NORMAL, "Hey, you's creature got da old fings?") + .branch { player -> + return@branch if (inInventory(player, Items.OGRE_GATE_KEY_4839)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(1) + .playerl("Nope, not yet.") + .npcl(FacialExpression.OLD_NORMAL, "Yous gets 'em quick tho, cos we'ze wonna do da new Jiggig place...") + .end() + branch.onValue(0) + .playerl("I lost the key you gave me.") + .betweenStage { df, player, _, _ -> + addItemOrDrop(player, Items.OGRE_GATE_KEY_4839) + } + .iteml(Items.OGRE_GATE_KEY_4839, "Grish gives you a crudely crafted key.") + .end() + } + + b.onQuestStages(ZogreFleshEaters.questName, 9) + .branch { player -> + return@branch if (inInventory(player, Items.OGRE_ARTEFACT_4818)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(0) + .npcl(FacialExpression.OLD_NORMAL, "Hey, you's creature got da old fings?") + .playerl("No sorry, I don't have them yet.") + .npcl(FacialExpression.OLD_NORMAL, "Yous creatures get dem for me soon doh, yes?") + .end() // There's all the default dialogue here, but I'm lazy again. + + branch.onValue(1) + .npcl(FacialExpression.OLD_NORMAL, "Hey, you's creature got da old fings?") + .playerl("Yeah, I have them here!") + .npcl(FacialExpression.OLD_NORMAL, "Dat is da goodly fing yous creature, now's we's can make da new Jiggig place away from zogries! Yous been da big helpy fing yous creature, Grish wishin' yous good stuff for da next fings for creature.") + .npcl(FacialExpression.OLD_HAPPY, "~ Grish seems very pleased about the return of the artefacts. ~") + .playerl("Thanks, that's very nice of you!") + .endWith { _, player -> + if (removeItem(player, Items.OGRE_ARTEFACT_4818)) { + if (getQuestStage(player, ZogreFleshEaters.questName) == 9) { + finishQuest(player, ZogreFleshEaters.questName) + } + } + } + } + + b.onQuestStages(ZogreFleshEaters.questName, 100) + .playerl("How's everything going now?") + .npcl(FacialExpression.OLD_NORMAL,"All da zogries stayin' in da oldie Jiggig, we's gonna do da new Jiggig someways else. Yous creature da good- un for geddin' da oldie fings...") + // More default dialogue, but lazy. + .end() + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/GrugDialogue.kt b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/GrugDialogue.kt new file mode 100644 index 0000000..6081288 --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/GrugDialogue.kt @@ -0,0 +1,31 @@ +package content.region.kandarin.feldip.quest.zogreflesheaters + +import core.api.openDialogue +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class GrugDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return GrugDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, GrugDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.GRUG_2041) + } +} +class GrugDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onPredicate { _ -> true } + .npcl(FacialExpression.OLD_NORMAL, "Ukk...I's dun fer...me's don't feel legsies anymore!") + .end() + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/JiggigListeners.kt b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/JiggigListeners.kt new file mode 100644 index 0000000..718e26e --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/JiggigListeners.kt @@ -0,0 +1,27 @@ +package content.region.kandarin.feldip.quest.zogreflesheaters + +import core.api.* +import core.game.dialogue.FacialExpression +import core.game.interaction.InteractionListener +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +class JiggigListeners : InteractionListener { + override fun defineListeners() { + on(Scenery.OGRE_COFFIN_6848, SCENERY, "open") { player, node -> + // https://youtu.be/HnRcW2iM8es + replaceScenery(node as core.game.node.scenery.Scenery, Scenery.OGRE_COFFIN_6890, 10) + return@on true + } + + on(NPCs.UGLUG_NAR_2039, NPC, "trade") { player, node -> + if (getAttribute(player, ZogreFleshEaters.attributeOpenUglugNarShop, false)) { + openNpcShop(player, NPCs.UGLUG_NAR_2039) + } else { + sendNPCDialogue(player, NPCs.UGLUG_NAR_2039, "Me's not got no glug-glugs to sell, yous bring me da sickies glug-glug den me's open da stufsies for ya.", FacialExpression.OLD_NORMAL) + } + return@on true + } + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/OgreGuardDialogue.kt b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/OgreGuardDialogue.kt new file mode 100644 index 0000000..6f51936 --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/OgreGuardDialogue.kt @@ -0,0 +1,73 @@ +package content.region.kandarin.feldip.quest.zogreflesheaters + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.interaction.QueueStrength +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class OgreGuardDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return OgreGuardDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, OgreGuardDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.OGRE_GUARD_2042) + } +} +class OgreGuardDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + + b.onQuestStages(ZogreFleshEaters.questName, 0) + .npcl(FacialExpression.OLD_NORMAL, "Yous needs ta stay away from dis place... yous get da sickies and mebe yous goes to dead if yous da unlucky fing.") + .playerl("Ok, thanks.") + .end() + + b.onQuestStages(ZogreFleshEaters.questName, 1) + .npcl(FacialExpression.OLD_NORMAL, "Yous needs ta stay away from dis place... yous get da sickies and mebe yous goes to dead if yous da unlucky fing.") + .playerl(FacialExpression.FRIENDLY, "But Grish has asked me to look into this place and find out why all the undead ogres are here.") + .npcl(FacialExpression.OLD_NORMAL, "Ok, dat is da big, big scary, danger fing! You's sure you's wants to go in?") + .playerl(FacialExpression.FRIENDLY, "Yes, I'm sure.") + .npcl(FacialExpression.OLD_NORMAL, "Ok, I opens da stoppa's for yous creature.") + .endWith { _, player -> + lock(player, 4) + face(npc!!, Location(2456, 3049, 0)) + // Lesson learnt here, endWith kills the npc object so tie the queueScript with the npc instead, not the player. + queueScript(npc!!, 2, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + animate(npc!!, 2102) + return@queueScript delayScript(npc!!, Animation(2102).duration) + } + 1 -> { + if(getQuestStage(player, ZogreFleshEaters.questName) == 1) { + setQuestStage(player, ZogreFleshEaters.questName, 2) + } + setVarbit(player, ZogreFleshEaters.varbitGateBashed, 1) + unlock(player) + face(npc!!, player.location) + sendNPCDialogue(player, NPCs.OGRE_GUARD_2042, "Ok der' yous goes!", FacialExpression.OLD_NORMAL) + return@queueScript stopExecuting(npc!!) + } + else -> return@queueScript stopExecuting(npc!!) + } + } + } + + b.onQuestStages(ZogreFleshEaters.questName, 2,3,4,5,6,7,8,9,10,100) + .npcl(FacialExpression.OLD_NORMAL, "Hey yous tryin' not to get da sickies else yous be da sick-un and mebe get to be a dead-un if yous be da unlucky fing.") + .playerl(FacialExpression.FRIENDLY, "Don't worry, I know how to take care of myself.") + .end() + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/PilgDialogue.kt b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/PilgDialogue.kt new file mode 100644 index 0000000..6eee48f --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/PilgDialogue.kt @@ -0,0 +1,31 @@ +package content.region.kandarin.feldip.quest.zogreflesheaters + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class PilgDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return PilgDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, PilgDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.PILG_2040) + } +} +class PilgDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onPredicate { _ -> true } + .npcl(FacialExpression.OLD_NORMAL, "Dey got me in da belly, mees gutsies feel like had a dead dead dog dinner.") + .end() + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/SithikIntsDialogue.kt b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/SithikIntsDialogue.kt new file mode 100644 index 0000000..7892518 --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/SithikIntsDialogue.kt @@ -0,0 +1,388 @@ +package content.region.kandarin.feldip.quest.zogreflesheaters + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.npc.NPC +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.tools.END_DIALOGUE +import core.tools.RandomFunction +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +/** This NPC is a scenery. */ +//@Initializable +//class SithikIntsDialogue (player: Player? = null) : DialoguePlugin(player) { +// override fun newInstance(player: Player): DialoguePlugin { +// return SithikIntsDialogue(player) +// } +// override fun handle(interfaceId: Int, buttonId: Int): Boolean { +// openDialogue(player, SithikIntsDialogueFile(), npc) +// return false +// } +// override fun getIds(): IntArray { +// return intArrayOf(NPCs.SITHIK_INTS_2061, NPCs.SITHIK_INTS_2062) +// } +//} +class SithikIntsDialogue : InteractionListener { + override fun defineListeners() { + on(Scenery.SITHIK_INTS_6888, SCENERY, "talk-to") { player, node -> + openDialogue(player, SithikIntsDialogueFile(), NPC(NPCs.SITHIK_INTS_2061)) + return@on true + } + on(Scenery.SITHIK_INTS_6889, SCENERY, "talk-to") { player, node -> + openDialogue(player, SithikIntsOgreFormDialogueFile(), NPC(NPCs.SITHIK_INTS_2062)) + return@on true + } + + on(Scenery.DRAWERS_6875, SCENERY, "search") { player, node -> + if (getQuestStage(player, ZogreFleshEaters.questName) <= 2) { + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> sendNPCDialogue(player, NPCs.SITHIK_INTS_2061, "Hey! What do you think you're doing?", FacialExpression.ANNOYED).also { stage++ } + 1 -> sendPlayerDialogue(player, "Erk! I'd better not start rifling through peoples things without permission.").also { stage = END_DIALOGUE } + } + } + }) + } else if (getQuestStage(player, ZogreFleshEaters.questName) in 3..4 && + (!inInventory(player, Items.BOOK_OF_PORTRAITURE_4817) || + !inInventory(player, Items.PAPYRUS_970) || + !inInventory(player, Items.CHARCOAL_973) + )) { + if (hasSpaceFor(player, Item(Items.BOOK_OF_PORTRAITURE_4817, 3))) { + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> { + if (!inInventory(player, Items.PAPYRUS_970) && !inInventory(player, Items.CHARCOAL_973)) { + sendDoubleItemDialogue(player, Items.CHARCOAL_973, Items.PAPYRUS_970, "You find some charcoal and papyrus.") + addItemOrDrop(player, Items.PAPYRUS_970) + addItemOrDrop(player, Items.CHARCOAL_973) + stage++ + } else if (!inInventory(player, Items.PAPYRUS_970)) { + sendItemDialogue(player, Items.PAPYRUS_970, "You find some papyrus.") + addItemOrDrop(player, Items.PAPYRUS_970) + stage++ + } else if (!inInventory(player, Items.CHARCOAL_973)) { + sendItemDialogue(player, Items.CHARCOAL_973, "You find some charcoal.") + addItemOrDrop(player, Items.CHARCOAL_973) + stage++ + } else { + sendItemDialogue(player, Items.BOOK_OF_PORTRAITURE_4817, "You also find a book on portraiture.") + addItemOrDrop(player, Items.BOOK_OF_PORTRAITURE_4817) + stage = END_DIALOGUE + } + } + 1 -> { + sendItemDialogue(player, Items.BOOK_OF_PORTRAITURE_4817, "You also find a book on portraiture.") + addItemOrDrop(player, Items.BOOK_OF_PORTRAITURE_4817) + stage = END_DIALOGUE + } + } + } + }) + } else { + sendDialogue(player, "You see some items in the drawer, but you need 3 free inventory spaces to take them.") + } + } else { + sendMessage(player, "You search but find nothing of significance.") + } + return@on true + } + + on(Scenery.CUPBOARD_6876, SCENERY, "search") { player, node -> + if (getQuestStage(player, ZogreFleshEaters.questName) <= 2) { + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> sendNPCDialogue(player, NPCs.SITHIK_INTS_2061, "Hey! What do you think you're doing?", FacialExpression.ANNOYED).also { stage++ } + 1 -> sendPlayerDialogue(player, "Erk! I'd better not start rifling through peoples things without permission.").also { stage = END_DIALOGUE } + } + } + }) + } else if (getQuestStage(player, ZogreFleshEaters.questName) in 3..4 && !inInventory(player, Items.NECROMANCY_BOOK_4837)) { + if (hasSpaceFor(player, Item(Items.NECROMANCY_BOOK_4837))) { + addItemOrDrop(player, Items.NECROMANCY_BOOK_4837) + sendItemDialogue(player, Items.NECROMANCY_BOOK_4837, "You find a book on Necromancy.") + setAttribute(player, ZogreFleshEaters.attributeFoundNecromanticBook, true) + } else { + sendDialogue(player, "You see an item in the cupboard, but you don't have space to put it in your inventory.") + } + } else { + sendMessage(player, "You search but find nothing of significance.") + } + return@on true + } + + onUseWith(IntType.SCENERY, Items.NECROMANCY_BOOK_4837, Scenery.SITHIK_INTS_6888) { player, used, with -> + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> sendPlayerDialogue(player,"Aha! A necromantic book! What's this doing here then?").also { stage++ } + 1 -> sendItemDialogue(player, Items.NECROMANCY_BOOK_4837, "You show the Necromantic book to Sithik.").also { stage++ } + 2 -> sendNPCDialogue(player, NPCs.SITHIK_INTS_2061, "Oh..I'm not quite sure actually...where did you find that then?").also { stage++ } + 3 -> sendPlayerDialogue(player,"I found it in this cupboard! What do you have to say for yourself?").also { stage++ } + 4 -> sendNPCDialogue(player, NPCs.SITHIK_INTS_2061, "Oh yes, that's right...I remember now. It's for my research, there's nothing really dangerous about it, unless it falls into the wrong hands. I'm sure it's pretty safe with me.").also { stage++ } + 5 -> sendPlayerDialogue(player,"Hmmm, likely story!").also { stage = END_DIALOGUE } + } + } + }) + return@onUseWith true + } + + on(Scenery.WARDROBE_6877, SCENERY, "search") { player, node -> + if (getQuestStage(player, ZogreFleshEaters.questName) <= 2) { + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> sendNPCDialogue(player, NPCs.SITHIK_INTS_2061, "Hey! What do you think you're doing?", FacialExpression.ANNOYED).also { stage++ } + 1 -> sendPlayerDialogue(player, "Erk! I'd better not start rifling through peoples things without permission.").also { stage = END_DIALOGUE } + } + } + }) + } else if (getQuestStage(player, ZogreFleshEaters.questName) in 3..4 && !inInventory(player, Items.BOOK_OF_HAM_4829)) { + if (hasSpaceFor(player, Item(Items.BOOK_OF_HAM_4829))) { + addItemOrDrop(player, Items.BOOK_OF_HAM_4829) + sendItemDialogue(player, Items.BOOK_OF_HAM_4829, "You find a book on Philosophy written by the 'Human's Against Monsters' leader, Johanhus Albrect.") + setAttribute(player, ZogreFleshEaters.attributeFoundHamBook, true) + } else { + sendDialogue(player, "You see an item in the wardrobe, but you don't have space to put it in your inventory.") + } + } else { + sendMessage(player, "You search but find nothing of significance.") + } + return@on true + } + + onUseWith(IntType.SCENERY, Items.BOOK_OF_HAM_4829, Scenery.SITHIK_INTS_6888) { player, used, with -> + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> sendPlayerDialogue(player,"What's this then?").also { stage++ } + 1 -> sendItemDialogue(player, Items.BOOK_OF_HAM_4829, "You show the HAM book to Sithik.").also { stage++ } + 2 -> sendNPCDialogue(player, NPCs.SITHIK_INTS_2061, "What do you mean? It's a book by the respected HAM leader Johanhus Ulsbrecht, that man speaks for a lot of people who are unhappy with the current state of affairs.").also { stage++ } + 3 -> sendNPCDialogue(player, NPCs.SITHIK_INTS_2061, "Can you honestly tell me that you've not had to fight for your life against the odd monster or two?").also { stage++ } + 4 -> sendPlayerDialogue(player,"Hmm, that may be true, but I don't universally hate all monsters, whereas I have a sneaking suspicion that you do...and ogres in particular!").also { stage++ } + 5 -> sendNPCDialogue(player, NPCs.SITHIK_INTS_2061, "Hmm, that's an interesting theory, care to back it up with any facts?").also { stage = END_DIALOGUE } + } + } + }) + return@onUseWith true + } + + onUseWith(IntType.SCENERY, Items.PAPYRUS_970, Scenery.SITHIK_INTS_6888) { player, used, with -> + if(inInventory(player, Items.CHARCOAL_973)) { + if (removeItem(player, used)) { + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> sendNPCDialogue(player, NPCs.SITHIK_INTS_2061, "Oh lovely! You're making my portrait! Let me see it afterwards!", FacialExpression.FRIENDLY).also { stage++ } + 1 -> sendDialogue(player, "You begin sketching the irritable Sithik.").also { animate(player, 909); stage++ } + 2 -> { + val skill = Skills.CRAFTING + val level: Int = getDynLevel(player, skill) + getFamiliarBoost(player, skill) + val ratio = RandomFunction.getSkillSuccessChance(0.0, 80.0, level) + + if (ratio > 0.5) { + // Passed + sendItemDialogue(player, Items.SITHIK_PORTRAIT_4814, "You get a portrait of Sithik.") + addItemOrDrop(player, Items.SITHIK_PORTRAIT_4814) + } else { + // Failed + sendItemDialogue(player, Items.SITHIK_PORTRAIT_4815, "You get a portrait of Sithik.") + addItemOrDrop(player, Items.SITHIK_PORTRAIT_4815) + } + setAttribute(player, ZogreFleshEaters.attributeMadePortrait, true) + stage = END_DIALOGUE + } + } + } + }) + } + } else { + sendDialogue(player, "You have no charcoal with which to sketch this subject.") + } + return@onUseWith true + } + + onUseWith(IntType.SCENERY, Items.BOOK_OF_PORTRAITURE_4817, Scenery.SITHIK_INTS_6888) { player, used, with -> + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> sendPlayerDialogue(player,"Oh, so explain this then?").also { stage++ } + 1 -> sendItemDialogue(player, Items.BOOK_OF_PORTRAITURE_4817, "You show the book on portraiture to Sithik.").also { stage++ } + 2 -> sendNPCDialogue(player, NPCs.SITHIK_INTS_2061, "It's my hobby...I'm interested in portraiture, but all art in general. It's fun, you should try it.").also { stage++ } + 3 -> sendPlayerDialogue(player,"How do I do it...").also { stage++ } + 4 -> sendNPCDialogue(player, NPCs.SITHIK_INTS_2061, "Well...you could start by reading the book!").also { stage = END_DIALOGUE } + } + } + }) + return@onUseWith true + } + + onUseWith(IntType.SCENERY, Items.SITHIK_PORTRAIT_4814, Scenery.SITHIK_INTS_6888) { player, used, with -> + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> sendPlayerDialogue(player, "Here you go, what do you think?").also { stage++ } + 1 -> sendItemDialogue(player, Items.SITHIK_PORTRAIT_4814, "You show the sketch...").also { stage++ } + 2 -> sendNPCDialogue(player, NPCs.SITHIK_INTS_2061, "Hmmm, well it's not the most flattering of portraits, but I like the 'honesty' of the work...well done.").also { stage = END_DIALOGUE } + } + } + }) + return@onUseWith true + } + + onUseWith(IntType.SCENERY, Items.SITHIK_PORTRAIT_4815, Scenery.SITHIK_INTS_6888) { player, used, with -> + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> sendPlayerDialogue(player, "Here you go, what do you think?").also { stage++ } + 1 -> sendItemDialogue(player, Items.SITHIK_PORTRAIT_4815, "You show the sketch...").also { stage++ } + 2 -> sendNPCDialogue(player, NPCs.SITHIK_INTS_2061, "Hmmm, well it's an interesting interpretation, but not really classic realist representation is it? It's not my favourite, but I like the 'truth' of the work...well done.").also { stage = END_DIALOGUE } + } + } + }) + return@onUseWith true + } + + on(Items.CUP_OF_TEA_4838, ITEM, "take") { player, node -> + sendNPCDialogue(player, NPCs.SITHIK_INTS_2061, "Hey! What do you think you're doing? Leave my tea alone!", FacialExpression.ANNOYED) + return@on true + } + + onUseWith(IntType.SCENERY, Items.STRANGE_POTION_4836, Scenery.SITHIK_INTS_6888) { player, used, with -> + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> sendPlayerDialogue(player,"Here, try some of this potion, it'll make you feel better!").also { stage++ } + 1 -> sendNPCDialogue(player, NPCs.SITHIK_INTS_2061, "Err, yuck...no way am I taking any potions or medication off you...I don't trust you!").also { stage = END_DIALOGUE } + } + } + }) + return@onUseWith true + } + + onUseWith(IntType.GROUNDITEM, Items.STRANGE_POTION_4836, Items.CUP_OF_TEA_4838) { player, _, with -> + if(getQuestStage(player, ZogreFleshEaters.questName) == 5) { + if (removeItem(player, Items.STRANGE_POTION_4836)) { + sendItemDialogue(player, Items.STRANGE_POTION_4836, "You pour some of the potion into the cup. Zavistic said it may take some time to have an effect.") + addItemOrDrop(player, Items.SAMPLE_BOTTLE_3377) + } + setQuestStage(player, ZogreFleshEaters.questName, 6) + } + return@onUseWith true + } + } +} + +class SithikIntsDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onQuestStages(ZogreFleshEaters.questName, 0, 1, 2) + .npcl(FacialExpression.ANNOYED, "Hey... who gave you permission to come in here! Get out, get out I say.") + .playerl("Alright, alright... keep your night cap on.") + .end() + + b.onQuestStages(ZogreFleshEaters.questName, 3, 4, 5, 6) + .npcl(FacialExpression.ANNOYED, "Hey... who gave you permission to come in here! Get out, get out I say.") + .playerl("Zavistic Rarve said that I could come and talk to you and ask you a few questions.") + .betweenStage { df, player, _, _ -> + if (getQuestStage(player, ZogreFleshEaters.questName) == 3) { + setQuestStage(player, ZogreFleshEaters.questName, 4) + } + } + .npcl(FacialExpression.ANNOYED, "Oh, Zavistic...why...why would he send you to me?") + + .let { builder -> + val returnJoin = b.placeholder() + returnJoin.builder() + .options() + .let { optionBuilder -> + optionBuilder.option_playerl("Do you know anything about the undead ogres at Jiggig?") + .npcl("Er...undead ogres...no, sorry, no idea what you're talking about there.") + .playerl("Hmm, is that right...") + .npcl("Well, yes, yes it is. If I knew something, I'd tell you.") + .npcl("Anyway, dead ogres you say? How strange? That must be a strange sight?") + .playerl("Very well, if you don't know anything about it, you won't mind if I look around then?") + .npcl("Well,err....well, actually yes I do mind...it's my place and I don't want strangers going through my things.") + .goto(returnJoin) + + optionBuilder.option_playerl("What do you do?") + .npcl("I'm a scholarly student of the magical arts. When I was younger I used to be an adventurer, probably just like yourself. But I lost interest in the constant fighting, looting and gaining abilities.") + .npcl("Instead I decided to focus my attention and time to study the purer form of the lost arts.") + .playerl("The lost arts? What are they?") + .npcl("Ignorant people call them the 'dark arts'. I'm talking about Necromancy, the power to bring the dead back to life - the power of the gods! Surely the most awesome power known to man.") + .playerl("Hmm, well I guess I must be an ignorant person then, because bringing the dead back to life sounds very unnatural.") + .goto(returnJoin) + + optionBuilder.option_playerl("Do you mind if I look around?") + .npcl("Well,err....well, actually yes I do mind...it's my place and I don't want strangers going through my things.") + .playerl("Well, I'm going to have a look around anyway, if you're not involved in this whole thing, you won't have anything to hide.") + .npcl("Why, if I was a few years younger I'd give you a good hiding!") + .playerl("I'm sure!") + .goto(returnJoin) + + optionBuilder.option_playerl("Ok, thanks.") + .end() + } + builder.goto(returnJoin) + } + } +} + +class SithikIntsOgreFormDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + + b.onQuestStages(ZogreFleshEaters.questName, 7,8,9,100) + /* + There are some after first time dialogue, but who reads this... + .npcl("Arghhhh..what do you want now...you've turned me into a beast!") + .playerl("I've got some questions for you...and you'd better answer them well or else!") + .npcl("Ok, ok, I'll tell you anything, just turn me back into a human again!") + */ + .npcl(FacialExpression.OLD_DEFAULT, "Arghhhh..what's happened to me...you beast!") + .playerl("It's your own fault, you shouldn't have lied about your involvement with the undead Ogres at Jiggig. The potion will wear off once you've told the truth!") + .npcl(FacialExpression.OLD_DEFAULT, "Ok, ok, I admit it, I got Brentle Vahn to cast the spell to put an end to those awful Ogres...they're just disgusting creatures...") + .playerl("Ok, that's a start...now I want some answers.") + .let { builder -> + val returnJoin = b.placeholder() + returnJoin.builder() + .options() + .let { optionBuilder -> + optionBuilder.option("How do I remove the effects of the spell from the area?") + .playerl("How do I remove the effects of the spell from the area? The ogres want to get their ceremonial dance area back and can't do that with undead walking all over it.") + .npcl(FacialExpression.OLD_DEFAULT, "Unfortunately you can't. The spell is permanent, it will last forever, the only option you have is to move the ceremonial area.") + .playerl("You're an evil man and I'm going to make you pay for this...you can stay like that forever as far as I'm concerned.") + .npcl(FacialExpression.OLD_DEFAULT, "No...no, let me try to make amends...please I can help you. Just don't leave me like this.") + .goto(returnJoin) + + optionBuilder.option_playerl("How do I get rid of the undead ogres?") + .npcl(FacialExpression.OLD_DEFAULT, "Ok, similar spells have been cast before and the only way to deal with the resulting creatures is to cordon off the area and not go in there again.") + .npcl(FacialExpression.OLD_DEFAULT, "The undead creatures usually manifest some sort of disease so it's best to attack them from a distance with a ranged weapon.") + .npcl(FacialExpression.OLD_DEFAULT, "Normal missiles like arrows and darts do very little damage to them because they're designed to destroy internal organs. This is a waste of time with undead creatures like undead ogres.") + .playerl("Yeah, clearly so what should we use?") + .npcl(FacialExpression.OLD_DEFAULT, "From my research it looks like a flat ended arrow was designed called a 'Brutal arrow'. This does large amounts of crushing damage to the creature. You can make them by using larger arrows.") + .npcl(FacialExpression.OLD_DEFAULT, "I think some Ogre hunters make them. But instead of adding an arrow tip, you hammer a large nail into the end of the shaft.") + .goto(returnJoin) + + optionBuilder.option_playerl("How do I get rid of the disease?") + .npcl(FacialExpression.OLD_DEFAULT, "My research shows that two jungle based herbs can be used, one is found near river tributaries and looks like a vine, the other is found in caves and grows on the wall.") + .npcl(FacialExpression.OLD_DEFAULT, "It's quite well camouflaged so it's unlikely that you'll find it.") + .playerl("We'll see about that!") + .goto(returnJoin) + + optionBuilder.option_playerl("Sorry, I have to go.") + .npcl(FacialExpression.OLD_DEFAULT, "But...you can't just leave me here like this!") + .end() + } + builder.goto(returnJoin) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/SkogreBehavior.kt b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/SkogreBehavior.kt new file mode 100644 index 0000000..4b309bb --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/SkogreBehavior.kt @@ -0,0 +1,39 @@ +package content.region.kandarin.feldip.quest.zogreflesheaters + +import core.api.getOrStartTimer +import core.api.inEquipment +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import core.game.system.timer.impl.Disease +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class SkogreBehavior : NPCBehavior(*skogreIds) { + companion object { + private val skogreIds = intArrayOf( + NPCs.SKOGRE_2050, + NPCs.SKOGRE_2056, + NPCs.SKOGRE_2057, + ) + } + + override fun beforeDamageReceived(self: NPC, attacker: Entity, state: BattleState) { + if (attacker is Player) { + if (inEquipment(attacker, Items.COMP_OGRE_BOW_4827)) { + return + } + state.estimatedHit = (state.estimatedHit * 0.25).toInt() + if (state.secondaryHit > 0) { + state.secondaryHit = (state.secondaryHit * 0.25).toInt() + } + } + } + + override fun beforeAttackFinalized(self: NPC, victim: Entity, state: BattleState) { + val disease = getOrStartTimer(victim, 10) + disease.hitsLeft = 10 + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/SlashBashBehavior.kt b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/SlashBashBehavior.kt new file mode 100644 index 0000000..169984c --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/SlashBashBehavior.kt @@ -0,0 +1,92 @@ +package content.region.kandarin.feldip.quest.zogreflesheaters + +import content.global.handlers.item.equipment.special.DragonfireSwingHandler +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.combat.CombatSwingHandler +import core.game.node.entity.combat.MultiSwingHandler +import core.game.node.entity.combat.equipment.SwitchAttack +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.system.timer.impl.Disease +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import core.tools.RandomFunction +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class SlashBashBehavior : NPCBehavior(NPCs.SLASH_BASH_2060) { + override fun canBeAttackedBy(self: NPC, attacker: Entity, style: CombatStyle, shouldSendMessage: Boolean): Boolean { + if (attacker is Player) { + if (attacker == getAttribute(self, "target", null)) { + return true + } + sendMessage(attacker, "It's not after you...") + } + return false + } + + override fun beforeAttackFinalized(self: NPC, victim: Entity, state: BattleState) { + if (victim is Player) { + val disease = getOrStartTimer(victim, 25) + disease.hitsLeft = 25 + } + } + + override fun beforeDamageReceived(self: NPC, attacker: Entity, state: BattleState) { + if (attacker is Player) { + if (inEquipment(attacker, Items.COMP_OGRE_BOW_4827)) { + return + } + state.estimatedHit = (state.estimatedHit * 0.25).toInt() + if (state.secondaryHit > 0) { + state.secondaryHit = (state.secondaryHit * 0.25).toInt() + } + } + } + + override fun onDropTableRolled(self: NPC, killer: Entity, drops: ArrayList) { + super.onDropTableRolled(self, killer, drops) + if (killer is Player && getQuestStage(killer, ZogreFleshEaters.questName) == 8) { + drops.add(Item(Items.ZOGRE_BONES_4812, 2)) + drops.add(Item(Items.OURG_BONES_4834, 3)) + drops.add(Item(Items.OGRE_ARTEFACT_4818)) + setQuestStage(killer, ZogreFleshEaters.questName, 9) + removeAttribute(killer, ZogreFleshEaters.attributeSlashBashInstance) + } + } + + var clearTime = 0 + override fun tick(self: NPC): Boolean { + val player: Player? = getAttribute(self, "target", null) + // You have 500 ticks to kill this guy + if (clearTime++ > 500) { + poofClear(self) + clearTime = 0 + if (player != null) { + removeAttribute(player, ZogreFleshEaters.attributeSlashBashInstance) + } + + } + return true + } + + /** MELEE Swing */ + private val COMBAT_HANDLER = MultiSwingHandler(SwitchAttack(CombatStyle.MELEE.swingHandler, Animation(359))) + /** RANGE Swing (Projectile) */ + private val COMBAT_HANDLER_FAR = MultiSwingHandler(SwitchAttack(CombatStyle.RANGE.swingHandler, Animation(359), Graphics(499))) + + override fun getSwingHandlerOverride(self: NPC, original: CombatSwingHandler): CombatSwingHandler { + val victim = self.properties.combatPulse.getVictim() ?: return original + if (victim !is Player) return original + + return if (victim.location.getDistance(self.location) >= 2) + COMBAT_HANDLER_FAR + else + COMBAT_HANDLER + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/UglugNarDialogue.kt b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/UglugNarDialogue.kt new file mode 100644 index 0000000..aab0bfe --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/UglugNarDialogue.kt @@ -0,0 +1,78 @@ +package content.region.kandarin.feldip.quest.zogreflesheaters + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class UglugNarDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return UglugNarDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, UglugNarDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.UGLUG_NAR_2039) + } +} +class UglugNarDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onQuestStages(ZogreFleshEaters.questName, 0) + .options() + .let { optionBuilder -> + optionBuilder.option_playerl("Hey, what's going on here?") + .npcl(FacialExpression.OLD_NORMAL, "Dem's dead ogre's come out of the ground...dey's makin' da rest of us into sick-ums ...and dead-uns.") + .playerl("That doesn't sound good!") + .npcl(FacialExpression.OLD_NORMAL, "Grish want's da person go down der - see what's what!") + .end() + optionBuilder.option_playerl("What are you selling?") + .npcl(FacialExpression.OLD_NORMAL, "Me's not got no glug-glugs to sell, yous bring me da sickies glug-glug den me's open da stufsies for ya.") + .end() + optionBuilder.option_playerl("Ok, thanks.") + .end() + } + + b.onQuestStages(ZogreFleshEaters.questName, 1,2,3,4,5,6,7,8,9,10,100) + .options() + .let { optionBuilder -> + optionBuilder.option_playerl("Hello again.") + .branch { player -> + return@branch if (getAttribute(player, ZogreFleshEaters.attributeOpenUglugNarShop, false)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(1) + .npcl(FacialExpression.OLD_NORMAL, "Hey yous creature...yous did good fings gedin that glug-glugs for da sickies! All is ogries pepels are not gettin dead cos of you.") + .end() + branch.onValue(0) + .npcl(FacialExpression.OLD_NORMAL, "Hey yous creature...yous still here?") + .playerl("Yeah, I'm going to help Grish by figuring out what went on here.") + .npcl(FacialExpression.OLD_NORMAL, "If yous finds somefin for da sickies, yous brings to me...and I's give you bright pretties, den me make more for alls pepels.") + .playerl("Hmm, ok. I'll try to bear that in mind.") + .end() + } + + optionBuilder.option_playerl("What are you selling?") + .branch { player -> + return@branch if (getAttribute(player, ZogreFleshEaters.attributeOpenUglugNarShop, false)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(1) + .npcl(FacialExpression.OLD_NORMAL, "Me's showin' you da stufsies for yous creatures!") + .endWith { _, player -> + openNpcShop(player, npc!!.id) + } + branch.onValue(0) + .npcl(FacialExpression.OLD_NORMAL, "Me's not got no glug-glugs to sell, yous bring me da sickies glug-glug den me's open da stufsies for ya.") + .end() + } + + optionBuilder.option_playerl("Ok, thanks.") + .end() + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/ZavisticRarveDialogueFile.kt b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/ZavisticRarveDialogueFile.kt new file mode 100644 index 0000000..1954334 --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/ZavisticRarveDialogueFile.kt @@ -0,0 +1,290 @@ +package content.region.kandarin.feldip.quest.zogreflesheaters + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.node.item.Item +import org.rs09.consts.Items + +class ZavisticRarveDialogueFile : DialogueBuilderFile() { + + companion object { + private fun hasEvidences(player: Player): Int { + var count = 0 + if (inInventory(player, Items.NECROMANCY_BOOK_4837)) { count++ } + if (inInventory(player, Items.BOOK_OF_HAM_4829)) { count++ } + if (inInventory(player, Items.DRAGON_INN_TANKARD_4811)) { count++ } + if (inInventory(player, Items.SIGNED_PORTRAIT_4816)) { count++ } + return count + } + + fun dialogueBlackPrismAndTornPage(builder: DialogueBuilder): DialogueBuilder { + return builder + .playerl("There's some undead ogre activity over at Jiggig, I've found some clues, I wondered if you'd have a look at them.") + .manualStage() { df, player, _, _ -> + sendDoubleItemDialogue(player, Items.BLACK_PRISM_4808, Items.TORN_PAGE_4809, "You show the prism and the necromantic half page to the aged wizard.") + } + .npcl("Hmmm, now this is interesting! Where did you get these from?") + .playerl("I got them from a nearby Ogre tomb, it's recently been infested with zombie ogres and I'm trying to work out what happened there.") + .npcl("This is very troubling @name, very troubling indeed. While it's permitted for learned members of our order to research the 'dark arts', it's absolutely forbidden to make use of such magic.") + .playerl("Do you have any leads on people that I might talk to regarding this?") + .npcl("Well a wizard by the name of 'Sithik Ints' was doing some research in this area. He may know something about it. He's lodged at that guest house to the North, though he's ill and isn't able to leave his room.") + .npcl("Why not go and talk to him, poke around a bit and see if anything comes up. Let me know how you get on. However, I doubt that 'Sithik' had anything to do with it.") + .npcl("Hmm, that black prism seems to have some magical protection. Once you've finished with this item, bring it back to me would you. I may have a reward for you.") + } + + fun dialogueGoodPortrait(builder: DialogueBuilder): DialogueBuilder { + return builder + .playerl("Look, I made a portrait of Sithik.") + .iteml(Items.SITHIK_PORTRAIT_4814, "You show the portrait of Sithik to Zavistic.") + .npcl("Hmm, great...but I already know what he looks like!") + } + + fun dialogueBadPortrait(builder: DialogueBuilder): DialogueBuilder { + return builder + .playerl("Look, I made a portrait of Sithik.") + .iteml(Items.SITHIK_PORTRAIT_4815, "You show the sketch...") + .npcl("Who the demonikin is that? Is it meant to be a portrait of Sithik, it doesn't look anything like him!") + } + + // Too lazy to do this, but this gets mentioned whenever you've shown him one of the evidence (but not all). + fun dialogueSeenEvidenceBefore(builder: DialogueBuilder): DialogueBuilder { + return builder + .npcl("Yeah, you've shown me this before...if this is all the evidence you have?") + .playerl("Please just look at it again...") + .npcl("Ok, let me look then.") + } + } + + override fun create(b: DialogueBuilder) { + b.onQuestStages(ZogreFleshEaters.questName, 2) + .let { content.region.kandarin.yanille.dialogue.ZavisticRarveDialogueFile.dialogueInitialTalk(it) } + .branch { player -> + return@branch if (inInventory(player, Items.BLACK_PRISM_4808) && inInventory(player, Items.TORN_PAGE_4809) ) { + 3 + } else if (inInventory(player, Items.BLACK_PRISM_4808) ) { + 2 + } else if (inInventory(player, Items.TORN_PAGE_4809) ) { + 1 + } else { + 0 + } + }.let { branch -> + branch.onValue(3) + .let{ dialogueBlackPrismAndTornPage(it) } + .endWith { _, player -> + if(getQuestStage(player, ZogreFleshEaters.questName) == 2) { + setQuestStage(player, ZogreFleshEaters.questName, 3) + } + } + + branch.onValue(2) + .playerl("There's some undead ogre activity over at 'Jiggig', and the ogres have asked me to look into it. I think I've found a clue and I wonder if you could take a look at it for me?") + .iteml(Items.BLACK_PRISM_4808, "You show the black prism to the aged wizard.") + .npcl("Hmmm, well this is an uncommon spell component. On its own it's useless, but with certain necromantic spells it can be very powerful. Did you find anything else there?") + .branch { player -> + return@branch if (inInventory(player, Items.DRAGON_INN_TANKARD_4811)) { 1 } else { 0 } + }.let { branch2 -> + val returnJoin = b.placeholder() + branch2.onValue(0) + .goto(returnJoin) + branch2.onValue(1) + .iteml(Items.DRAGON_INN_TANKARD_4811, "You show the tankard to Zavistic.") + .playerl("Well, I found this...") + .npcl("Hmmm, no, that's not really associated with this to be honest. Did you find anything else there?") + .goto(returnJoin) + return@let returnJoin.builder() + } + .playerl("Not really.") + .npcl("I don't know what to say then, there isn't enough to go on with the clues you've shown me so far. I'd suggest going back to search a bit more, but you may just be wasting your time?") + .npcl("Hmm, but this prism does seem to have some magical protection. Once you've finished with this item, bring it back to me would you? I may have a reward for you!") + .playerl("Sure...I mean, I'll try if I remember.") + .end() + + branch.onValue(1) + .playerl("There's some undead ogre activity over at Jiggig, I've found a clue that you may be able to help with.") + .iteml(Items.TORN_PAGE_4809, "You show the necromantic half page to the aged wizard.") + .npcl("Hmm, this is a half torn spell page, it requires another spell component to be effective. Did you find anything else there?") + .branch { player -> + return@branch if (inInventory(player, Items.DRAGON_INN_TANKARD_4811)) { 1 } else { 0 } + }.let { branch2 -> + val returnJoin = b.placeholder() + branch2.onValue(0) + .goto(returnJoin) + branch2.onValue(1) + .iteml(Items.DRAGON_INN_TANKARD_4811, "You show the tankard to Zavistic.") + .playerl("Well, I found this...") + .npcl("Hmmm, no, that's not really associated with this to be honest. Did you find anything else there?") + .goto(returnJoin) + return@let returnJoin.builder() + } + .playerl("Not really.") + .npcl("I don't know what to say then, there isn't enough to go on with the clues you've shown me so far. I'd suggest going back to search a bit more, but you may just be wasting your time?") + .end() + + branch.onValue(0) + .let { builder -> + content.region.kandarin.yanille.dialogue.ZavisticRarveDialogueFile.defaultTalk(builder) + } + } + + + b.onQuestStages(ZogreFleshEaters.questName, 3,4) + .let { content.region.kandarin.yanille.dialogue.ZavisticRarveDialogueFile.dialogueInitialTalk(it) } + .let { builder -> + val returnJoin = b.placeholder() + builder.goto(returnJoin) + return@let returnJoin.builder().options() + .let { optionBuilder -> + val continuePath = b.placeholder() + optionBuilder.option("What did you say I should do?") + .playerl("What did you say I should do?") + .npcl("You should go and have a chat with Sithik Ints, he's in that house just to the north. He's a lodger and has a room upstairs. Just tell him that I sent you to see him. He should be fine once you've mentioned my name.") + .goto(returnJoin) + optionBuilder.option_playerl("Where is Sithik?") + .npcl("He's in that house just to the north, less than a few seconds walk away. He's a lodger and has a room upstairs...he's not very well though.") + .goto(returnJoin) + optionBuilder.optionIf("I have an item that I'd like you to look at.") { player -> return@optionIf hasEvidences(player) == 1 } + .goto(continuePath) + optionBuilder.optionIf("I have an item that I'd like you to look at.") { player -> return@optionIf hasEvidences(player) > 1 } + .goto(continuePath) + optionBuilder.option("I want to ask about the magic guild") + .let { content.region.kandarin.yanille.dialogue.ZavisticRarveDialogueFile.defaultTalk(it) } + optionBuilder.option_playerl("Sorry, I have to go.") + .end() + + return@let continuePath.builder() + } + } + .branch { player -> + return@branch if (inInventory(player, Items.NECROMANCY_BOOK_4837) ) { 1 } else { 0 } + }.let { branch -> + val continuePath = b.placeholder() + branch.onValue(1) + .iteml(Items.NECROMANCY_BOOK_4837, "You show the Necromancy book to Zavistic.") + .playerl("I have this necromancy book as evidence that Sithik is involved with the undead ogres at Jiggig.") + .npcl("Ok, so he's researching necromancy...it doesn't mean anything in itself.") + .playerl("Yes, but if you look, you can see that there is a half torn page which matches the page I found at Jiggig.") + .npcl("Hmm, yes, but someone could have stolen that from him and then gone and cast it without his permission or to try and deliberately implicate him.") + .goto(continuePath) + branch.onValue(0) + .goto(continuePath) + return@let continuePath.builder() + } + .branch { player -> + return@branch if (inInventory(player, Items.BOOK_OF_HAM_4829) ) { 1 } else { 0 } + }.let { branch -> + val continuePath = b.placeholder() + branch.onValue(1) + .iteml(Items.BOOK_OF_HAM_4829, "You show the HAM book to Zavistic.") + .playerl("Look, this book proves that Sithik hates all monsters and most likely Ogres with a passion.") + .npcl("So what, hating monsters isn't a crime in itself...although I suppose that it does give a motive if Sithik was involved. On its own, it's not enough evidence though.") + .goto(continuePath) + branch.onValue(0) + .goto(continuePath) + return@let continuePath.builder() + } + .branch { player -> + return@branch if (inInventory(player, Items.DRAGON_INN_TANKARD_4811) ) { 1 } else { 0 } + }.let { branch -> + val continuePath = b.placeholder() + branch.onValue(1) + .iteml(Items.DRAGON_INN_TANKARD_4811, "You show the dragon Inn Tankard to Zavistic.") + .playerl("This is the tankard I found on the remains of Brentle Vahn!") + .npcl("That doesn't mean anything in itself, you could have gotten that from anywhere. Even from the Dragon Inn tavern! There isn't anything to link Brentle Vahn with Sithik Ints.") + .goto(continuePath) + branch.onValue(0) + .goto(continuePath) + return@let continuePath.builder() + } + .branch { player -> + return@branch if (inInventory(player, Items.SIGNED_PORTRAIT_4816) ) { 1 } else { 0 } + }.let { branch -> + val continuePath = b.placeholder() + branch.onValue(1) + .iteml(Items.SIGNED_PORTRAIT_4816, "You show the signed portrait of Sithik to Zavistic.") + .playerl("This is a portrait of Sithik, signed by the landlord of the Dragon Inn saying that he saw Sithik and Brentle Vahn together.") + .npcl("Hmmm, well that is interesting.") + .goto(continuePath) + branch.onValue(0) + .goto(continuePath) + return@let continuePath.builder() + } + .branch { player -> + return@branch if (hasEvidences(player) == 4) { 1 } else { 0 } + }.let { branch -> + branch.onValue(0) + .npcl("However, there isn't enough evidence for me to take the issue further at this point. If you find any further evidence bring it to me.") + .end() + return@let branch + } + .onValue(1) + .npcl("And I'm starting to think that Sithik may be involved. Here, take this potion and give some to Sithik. It'll bring on a change which should solicit some answers - tell him the effects won't revert until he's told the truth.") + .iteml(Items.STRANGE_POTION_4836 ,"Zavistic hands you a strange looking potion bottle and takes all the evidence you've accumulated so far.") + .endWith { _, player -> + if(getQuestStage(player, ZogreFleshEaters.questName) in 3..4) { + if (removeItem(player, Items.NECROMANCY_BOOK_4837) && + removeItem(player, Items.BOOK_OF_HAM_4829) && + removeItem(player, Items.DRAGON_INN_TANKARD_4811) && + removeItem(player, Items.SIGNED_PORTRAIT_4816)) { + addItemOrDrop(player, Items.STRANGE_POTION_4836) + } + setQuestStage(player, ZogreFleshEaters.questName, 5) + } + } + b.onQuestStages(ZogreFleshEaters.questName, 5) + .let { content.region.kandarin.yanille.dialogue.ZavisticRarveDialogueFile.dialogueInitialTalk(it) } + .npcl("Have you used that potion yet?") + .branch { player -> + return@branch if (inInventory(player, Items.STRANGE_POTION_4836) ) { 1 } else { 0 } + }.let { branch -> + branch.onValue(1) + .playerl("No, not yet, what was I supposed to do again?") + .npcl("Try to use the potion on Sithik somehow, he should undergo an interesting transformation, though you'll probably want to leave the house in case there are any side effects. Then go back and question Sithik and tell") + .npcl("him the effects won't wear off until he tells the truth. In fact, that's not exactly true, but I'm sure it'll be an extra incentive to get him to be honest.") + .let { builder -> + content.region.kandarin.yanille.dialogue.ZavisticRarveDialogueFile.defaultTalk(builder) + } + branch.onValue(0) + .playerl("Well, actually, I've lost it, could I have another one please?") + .npcl("Sure, but don't lose it this time.") + .iteml(Items.STRANGE_POTION_4836 ,"Zavistic hands you a bottle of strange potion.") + .endWith { _, player -> + addItemOrDrop(player, Items.STRANGE_POTION_4836) + } + } + + + b.onQuestStages(ZogreFleshEaters.questName, 6,7,8,9) + .let { content.region.kandarin.yanille.dialogue.ZavisticRarveDialogueFile.dialogueInitialTalk(it) } + .npcl("Don't you worry about Sithik, he's not likely to be moving from his bed for a long time. When he eventually does get better, he's going to be sent before a disciplinary tribunal, then we'll sort out what's what.") + .playerl("Thanks for your help with all of this.") + .npcl("Ooohh, no thanks required. It's I who should be thanking you my friend...your investigative mind has shown how vigilant we really should be for this type of evil use of the magical arts.") + .let { builder -> + content.region.kandarin.yanille.dialogue.ZavisticRarveDialogueFile.defaultTalk(builder) + } + } +} + +/** Dialogues when you use stuff on him. */ +class ZavisticRarveUseItemsDialogueFile(private val dialogueNum: Int = 0) : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + + // SITHIK_PORTRAIT_4814 + b.onPredicate { _ -> dialogueNum == 3 } + .let{ZavisticRarveDialogueFile.dialogueGoodPortrait(it)} + .end() + + // SITHIK_PORTRAIT_4815 + b.onPredicate { _ -> dialogueNum == 4 } + .let{ZavisticRarveDialogueFile.dialogueBadPortrait(it)} + .end() + + // SIGNED_PORTRAIT_4816 + b.onPredicate { _ -> dialogueNum == 5 } + // That would continue the conversation as above if you normally talk to him. + .end() + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/ZogreBehavior.kt b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/ZogreBehavior.kt new file mode 100644 index 0000000..1e00271 --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/ZogreBehavior.kt @@ -0,0 +1,47 @@ +package content.region.kandarin.feldip.quest.zogreflesheaters + +import core.api.getOrStartTimer +import core.api.inEquipment +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import core.game.system.timer.impl.Disease +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class ZogreBehavior : NPCBehavior(*zogreIds) { + companion object { + private val zogreIds = intArrayOf( + NPCs.ZOGRE_2044, + NPCs.ZOGRE_2045, + NPCs.ZOGRE_2046, + NPCs.ZOGRE_2047, + NPCs.ZOGRE_2048, + NPCs.ZOGRE_2049, + NPCs.ZOGRE_2051, + NPCs.ZOGRE_2052, + NPCs.ZOGRE_2053, + NPCs.ZOGRE_2054, + NPCs.ZOGRE_2055, + ) + } + + override fun beforeDamageReceived(self: NPC, attacker: Entity, state: BattleState) { + if (attacker is Player) { + if (inEquipment(attacker, Items.COMP_OGRE_BOW_4827)) { + return + } + state.estimatedHit = (state.estimatedHit * 0.25).toInt() + if (state.secondaryHit > 0) { + state.secondaryHit = (state.secondaryHit * 0.25).toInt() + } + } + } + + override fun beforeAttackFinalized(self: NPC, victim: Entity, state: BattleState) { + val disease = getOrStartTimer(victim, 10) + disease.hitsLeft = 10 + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/ZogreFleshEaters.kt b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/ZogreFleshEaters.kt new file mode 100644 index 0000000..6ed8c90 --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/ZogreFleshEaters.kt @@ -0,0 +1,353 @@ +package content.region.kandarin.feldip.quest.zogreflesheaters + +import content.data.Quests +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import org.rs09.consts.Items + +/** + * Zogre Flesh Eaters Quest + * + * 1 - Talked to Grish + * 2 - Smashed Barricade + * 2 Cont' - Collected Stuff Underground + * A - Black Prism from Coffin + * B - Half Torn Page from Broken Lecturn + * C - Tankard from Backpack (Kill the Zombie which turns out to be Brentle Vahn) + * 3 - Talked to Zavistic Rarve with A & B only, points to where Sithik Ints is + * 4 - Talked to Sithik and challenged to incriminate him + * 4 Cont' - Collected Evidence + * A - Tankard from 2C after talking to Innkeeper + * B - Portrait of Sithik using papyrus and charcoal with questionable drawing skills + * C - Book of HAM philosophy from drawer + * D - Necromantic book + * 5 - Incriminate Sithik to Zavistic Rarve and given potion + * 6 - Turned Sithik into an Ogre with potion + * 7 - Talked to Grish + * 8 - Get Key from Grish + * 9 - Killed Slash Bash + * 100 - Returned to Grish with Ogre Artifact + * + * This quest journal is the worst; there's typos, and it is out of order. + * + * if (VARPBIT[487] > 12) return 2; if (VARPBIT[487 == 0) return 0; return 1; }; + * define_varbit 487 455 0 4 + * + */ +@Initializable +class ZogreFleshEaters : Quest(Quests.ZOGRE_FLESH_EATERS, 40, 39, 1, 455, 0, 1, 13) { + companion object { + val questName = Quests.ZOGRE_FLESH_EATERS + const val varbitGateBashed = 496 + const val varbitOgreCoffin = 488 + const val varbitSithikOgre = 495 + + const val attributeAskedAboutSickies = "quest:zogreflesheaters-askedaboutsickies" + + // 2A + const val attributeSearchedCoffin = "/save:quest:zogreflesheaters-searchedcoffin" + const val attributeBrokeLockCoffin = "/save:quest:zogreflesheaters-brokelockcoffin" + const val attributeOpenedCoffin = "/save:quest:zogreflesheaters-openedcoffin" // You can fail apparently... + const val attributeFoundBlackPrism = "/save:quest:zogreflesheaters-foundblackprism" + // 2B + const val attributeFoundHalfTornPage = "/save:quest:zogreflesheaters-foundhalftornpage" + // 2C + const val attributeFoughtZombie = "/save:quest:zogreflesheaters-foughtzombie" + const val attributeFoundTankard = "/save:quest:zogreflesheaters-foundtankard" + // 4A + const val attributeAskedAboutTankard = "quest:zogreflesheaters-askedabouttankard" + // 4B + const val attributeMadePortrait = "/save:quest:zogreflesheaters-madeportrait" + // 4C + const val attributeFoundHamBook = "/save:quest:zogreflesheaters-foundhambook" + // 4D + const val attributeFoundNecromanticBook = "/save:quest:zogreflesheaters-foundnecromanticbook" + + const val attributeSlashBashInstance = "/save:quest:zogreflesheaters-slashbashinstance" + + // Open Uglug Nar Shop with Relicym balm + const val attributeOpenUglugNarShop = "/save:quest:zogreflesheaters-openuglugnarshop" + + fun requirements(player: Player): Boolean { + return arrayOf( + hasLevelStat(player, Skills.RANGE, 30), + hasLevelStat(player, Skills.SMITHING, 4), + hasLevelStat(player, Skills.HERBLORE, 8), + isQuestComplete(player, Quests.JUNGLE_POTION), + isQuestComplete(player, Quests.BIG_CHOMPY_BIRD_HUNTING), + ).all { it } + } + } + + override fun drawJournal(player: Player, stage: Int) { + super.drawJournal(player, stage) + var line = 11 + var stage = getStage(player) + + var started = getQuestStage(player, questName) > 0 + + if (!started) { + line(player, "I can !!start?? this quest by talking to !!Grish?? at the Ogrish", line++, false) + line(player, "ceremonial dance place called !!Jiggig??.", line++, false) + line(player, "To start this !!quest?? I should complete these quests:-", line++, false) + line(player, "!!Jungle Potion.??", line++, isQuestComplete(player, Quests.JUNGLE_POTION)) + line(player, "!!Big Chompy Bird Hunting.??", line++, isQuestComplete(player, Quests.BIG_CHOMPY_BIRD_HUNTING)) + line(player, "It would help if I had the following skills levels:-", line++, false) + line(player, "!!Ranged level : 30??", line++, hasLevelStat(player, Skills.RANGE, 30)) + line(player, "!!Fletching level : 30??", line++, hasLevelStat(player, Skills.FLETCHING, 30)) + line(player, "!!Smithing level : 4??", line++, hasLevelStat(player, Skills.SMITHING, 4)) + line(player, "!!Herblore level : 8??", line++, hasLevelStat(player, Skills.HERBLORE, 8)) + line(player, "Must be able to defeat a !!level 111?? foe.", line++, false) + } else if (stage < 100) { + + line(player, "I started this quest by talking to Grish, he asked me to", line++, true) + line(player, "check out the underground area where some Zombie ogres", line++, true) + line(player, "(Zogres) were coming from.", line++, true) + + if (stage >= 2) { + line(player, "I have to find a way into the ceremonial dance area and", line++, true) + line(player, "then underground.", line++, true) + line(player, "I persuaded a guard to let me past, I only had to mention", line++, true) + line(player, "Grish's name and the guard smashed the barricade down. I", line++, true) + line(player, "can enter now.", line++, true) + } else if (stage >= 1) { + line(player, "I have to find a way into the ceremonial dance area and", line++, false) + line(player, "then underground.", line++, false) + } + + if (stage >= 2) { + // Set 2A (Stays) + if (getAttribute(player, attributeFoundBlackPrism, false) || stage >= 3) { + line(player, "I have searched a coffin, it had a funny looking hole at the", line++, true) + line(player, "side.", line++, true) + line(player, "I have forced the lock on a coffin, maybe I can open it", line++, true) + line(player, "now?", line++, true) + line(player, "I've !!opened?? the !!coffin?? and retrieved a !!black prism??, this", line++, stage >= 3) + line(player, "may be useful.", line++, stage >= 3) + } else if (getAttribute(player, attributeOpenedCoffin, false)) { + line(player, "I have searched a coffin, it had a funny looking hole at the", line++, true) + line(player, "side.", line++, true) + line(player, "I have forced the lock on a coffin, maybe I can open it", line++, true) + line(player, "now?", line++, true) + line(player, "I've !!opened?? the !!coffin??, maybe there's something in it.", line++, false) + } else if (getAttribute(player, attributeBrokeLockCoffin, false)) { + line(player, "I have searched a coffin, it had a funny looking hole at the", line++, true) + line(player, "side.", line++, true) + line(player, "I have forced the lock on a !!coffin??, maybe I can open it", line++, false) + line(player, "now?", line++, false) + } else if (getAttribute(player, attributeSearchedCoffin, false)) { + line(player, "I have searched a coffin, it had a funny looking hole at the", line++, true) + line(player, "side.", line++, true) + } + } + + if (stage >= 2) { + // Set 2B (Stays) + if (getAttribute(player, attributeFoundHalfTornPage, false) || stage >= 3) { + line(player, "I found a !!half torn page?? from a !!necromatic spellbook??,", line++, stage >= 3) + line(player, "maybe this is a !!clue???", line++, stage >= 3) + } + } + + // 4 - This is the weirdest shit that is out of place. (Stays) This appears after talking to Sithik Int. + if (stage >= 4) { + line(player, "I have shown the prism and torn page to the grand", line++, true) + line(player, "secretary of the wizards guild.", line++, true) + } + + // Set 2C (Does not stay) + if (stage in 2..4 && getAttribute(player, attributeFoundTankard, false)) { + line(player, "I killed a !!human zombie?? which dropped a !!backpack??. The", line++, stage >= 3) + line(player, "!!backpack?? had the name !!'B. Vahn'?? on it, inside the !!backpack??", line++, stage >= 3) + line(player, "I found a !!tankard??.", line++, stage >= 3) + } else if (stage in 2..4 && getAttribute(player, attributeFoughtZombie, false)) { + line(player, "I killed a !!human zombie?? which dropped a !!backpack??.", line++, stage >= 3) + } + + // Stays until you find all the 3X stuff above. + if (stage in 2..4 && !(getAttribute(player, attributeFoundBlackPrism, false) && + getAttribute(player, attributeFoundHalfTornPage, false) && + getAttribute(player, attributeFoundTankard, false))) { + line(player, "I need to find out what happened here.", line++, false) // Cleared when the 3 sets above are done. + } + + // Set 4A (Does not stay) + if (stage in 2..4 && getAttribute(player, attributeAskedAboutTankard, false)) { + line(player, "The 'Dragon Inn' !!Innkeeper?? says the tankard belongs to", line++, false) + line(player, "one of his locals called !!Brentle Vahn??. He was seen talking", line++, false) + line(player, "to a !!wizard?? the other day.", line++, false) // Cleared after handed in with the rest + } + + // 3 Zavistic Rarve seen prism and page - lines disappears right after... + if (stage == 3) { + line(player, "I have shown the !!prism?? and the !!necromantic page?? to", line++, false) + line(player, "Zavistic Rarve. He's told me about a !!wizard?? named", line++, false) + line(player, "!!Sithik Ints?? who might have some information.", line++, false) + } + + // 4 Spoken with Sithik + if (stage >= 4) { + line(player, "I've spoken to !!Sithik??, I need to see if he was !!involved??", line++, stage >= 5) + line(player, "with the !!Undead Ogres at 'Jiggig'?? in some way.", line++, stage >= 5) + } + + // Only stays for 4 + if (stage == 4) { + if (getAttribute(player, attributeMadePortrait, false)) { + line(player, "I've made a !!portrait?? of !!Sithik??...not sure what this will do?", line++, false) + } + if (getAttribute(player, attributeFoundHamBook, false)) { + line(player, "I've found a !!book?? on !!HAM philosophy??...what does this prove?", line++, false) + } + if (getAttribute(player, attributeFoundNecromanticBook, false)) { + line(player, "I've found a !!necromantic book??...what does this prove?", line++, false) + } + } + + // 4 - Who the hell knows why this is here. (Stays) This appears after getting the potion. + if (stage >= 5) { + line(player, "I've talked to Zavistic Rarve regarding the prism and the", line++, true) + line(player, "torn page, he gave some information on a student called", line++, true) + line(player, "Sithik Ints, he may know more about what's happening", line++, true) + line(player, "here.", line++, true) + } + + // Beyond this is legit + if (stage >= 5) { + line(player, "Zavistic has given me some sort of !!potion??, apparently I", line++, stage >= 6) + line(player, "need to give it to !!Sithik??.", line++, stage >= 6) + } + + if (stage >= 7) { + line(player, "I came back into Sithik's room to find that he had been", line++, true) + line(player, "turned into an Ogre!", line++, true) + } else if (stage >= 6) { + line(player, "I have put some of the !!potion?? into !!Sithik's tea??, the !!potion??", line++, false) + line(player, "will take some time to act. Perhaps I should !!get out of??", line++, false) + line(player, "!!here?? in case there are any !!side effects???", line++, false) + } + + if (stage >= 8) { + line(player, "Sithik has told me how to make 'brutal arrows', which", line++, true) + line(player, "should be more effective against Zogres.", line++, true) + + line(player, "Sithik has given me some pointers on how I can make a", line++, true) + line(player, "cure disease potion, though I'm still not sure exactly which", line++, true) + line(player, "herbs I should use.", line++, true) + } else if (stage >= 7) { + line(player, "!!Sithik?? has told me that there is no way I can remove the", line++, false) + line(player, "effects of the !!necromantic curse spell?? from the !!Jiggig??", line++, false) + line(player, "area. I'll have to go back and let !!Grish?? know.", line++, false) + + line(player, "!!Sithik?? has told me how to make !!'brutal arrows'??, which", line++, false) + line(player, "should be more !!effective?? against !!Zogres??.", line++, false) + + line(player, "!!Sithik?? has given me some pointers on how I can make a", line++, false) + line(player, "!!cure disease potion??, though I'm still not sure exactly which", line++, false) + line(player, "!!herbs?? I should use.", line++, false) + } + + if (stage >= 9) { + line(player, "I've told Grish to relocated the dance area, but he needs", line++, true) + line(player, "me to get something from the tomb to so that he can do", line++, true) // "tomb to so" is authentic [sic] + line(player, "this.", line++, true) + line(player, "I need to go back into the tomb and look for some 'old'", line++, true) + line(player, "items that Grish has asked for.", line++, true) + line(player, "I should return the !!artifact?? to !!Grish??.", line++, false) + } else if (stage >= 8) { + line(player, "I've told Grish to relocated the dance area, but he needs", line++, true) + line(player, "me to get something from the tomb to so that he can do", line++, true) // "tomb to so" is authentic [sic] + line(player, "this.", line++, true) + line(player, "I need to go back into the !!tomb?? and look for some !!'old'??", line++, false) + line(player, "!!items?? that !!Grish?? has asked for.", line++, false) + } + + } else { + // The ending is COMPLETELY replaced from this entire shitshow of a quest log. + line(player, "I talked to Grish in the Jiggig area which is swarming with", line++, true) + line(player, "Zombie Ogres (Zogres) These disgusting creatures carry", line++, true) + line(player, "disease and are quite dangerous so the Ogres weren't", line++, true) + line(player, "too keen to try and sort them out.", line++, true) + + line(player, "I talked to an ogre called Grish who asked me to look into", line++, true) + line(player, "the problem. After some searching around in a tomb, I", line++, true) + line(player, "found some clues which pointed me to the human", line++, true) + line(player, "habitation of Yannile.", line++, true) + + line(player, "With the help of Zavistic Rarve, the grand secretary of", line++, true) + line(player, "the Wizards guild I was able to piece the clues together", line++, true) + line(player, "and discover that a Wizard named 'Sithik Ints' was", line++, true) + line(player, "responsible.", line++, true) + + line(player, "Unfortunately I couldn't remove the curse from the area,", line++, true) + line(player, "however, I was able to return some important artefacts to", line++, true) + line(player, "Grish, who can now set up a new ceremonial dance area for", line++, true) + line(player, "the ogres of Gu' Tanoth.", line++, true) + + line(player, "Sithik Ints also told me how to make Brutal arrows which are", line++, true) + line(player, "more effective against Zogres, and he also told me how to", line++, true) + line(player, "make a disease balm.", line++, true) + line++ + line(player,"QUEST COMPLETE!", line) + } + } + + override fun reset(player: Player) { + setVarp(player, varbitGateBashed, 0, true) + removeAttribute(player, attributeAskedAboutSickies) + removeAttribute(player, attributeSearchedCoffin) + removeAttribute(player, attributeBrokeLockCoffin) + removeAttribute(player, attributeOpenedCoffin) + removeAttribute(player, attributeFoundBlackPrism) + removeAttribute(player, attributeFoundHalfTornPage) + removeAttribute(player, attributeFoughtZombie) + removeAttribute(player, attributeFoundTankard) + removeAttribute(player, attributeAskedAboutTankard) + removeAttribute(player, attributeMadePortrait) + removeAttribute(player, attributeFoundHamBook) + removeAttribute(player, attributeFoundNecromanticBook) + removeAttribute(player, attributeOpenUglugNarShop) + + } + override fun finish(player: Player) { + var ln = 10 + super.finish(player) + player.packetDispatch.sendString("You have completed Zogre Flesh Eaters!", 277, 4) + player.packetDispatch.sendItemZoomOnInterface(Items.OGRE_ARTEFACT_4818, 240, 277, 5) + + drawReward(player,"1 Quest Point.", ln++) + drawReward(player,"Can now make Brutal Arrows", ln++) + drawReward(player,"and cure disease potions.", ln++) + drawReward(player,"2000 Ranged, Fletching and", ln++) + drawReward(player,"Herblore XP", ln++) + + player.skills.addExperience(Skills.RANGE, 2000.0) + player.skills.addExperience(Skills.FLETCHING, 2000.0) + player.skills.addExperience(Skills.HERBLORE, 2000.0) + } + + override fun setStage(player: Player, stage: Int) { + super.setStage(player, stage) + this.updateVarps(player) + } + + override fun updateVarps(player: Player) { + if(getQuestStage(player, questName) >= 2) { + setVarbit(player, varbitGateBashed, 1, true) + } else { + setVarbit(player, varbitGateBashed, 0, true) + } + if(getQuestStage(player, questName) >= 7) { + setVarbit(player, varbitSithikOgre, 1, true) + } else { + setVarbit(player, varbitSithikOgre, 0, true) + } + } + + override fun newInstance(`object`: Any?): Quest { + return this + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/ZogreFleshEatersListeners.kt b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/ZogreFleshEatersListeners.kt new file mode 100644 index 0000000..bd16a02 --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/ZogreFleshEatersListeners.kt @@ -0,0 +1,382 @@ +package content.region.kandarin.feldip.quest.zogreflesheaters + +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.global.action.DoorActionHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.world.map.Direction +import core.game.world.map.Location +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +class ZogreFleshEatersListeners : InteractionListener { + + companion object { + @JvmStatic + fun ladderMakesSithikTurnIntoOgre(player: Player) { + if(getQuestStage(player, ZogreFleshEaters.questName) == 6) { + setQuestStage(player, ZogreFleshEaters.questName, 7) + setVarbit(player, ZogreFleshEaters.varbitSithikOgre, 1) + } + } + } + + override fun defineListeners() { + // Stairs and doors + on(Scenery.STAIRS_6841, SCENERY, "climb-down") { player, node -> + sendMessage(player, "You climb down the steps.") + if (node.location == Location(2443, 9417, 2)) { + teleport(player, Location(2442, 9417, 0)) + } else { + teleport(player, Location(2477, 9437, 2)) + } + return@on true + } + on(Scenery.STAIRS_6842, SCENERY, "climb-up") { player, node -> + sendMessage(player, "You climb up the steps.") + if (node.location == Location(2443, 9417, 0)) { + teleport(player, Location(2447, 9417, 2)) + } else { + teleport(player, Location(2485, 3045, 0)) + } + return@on true + } + on(Scenery.OGRE_STONE_DOOR_6871, SCENERY, "open") { player, node -> + if (getQuestStage(player, ZogreFleshEaters.questName) >= 9) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else if (inInventory(player, Items.OGRE_GATE_KEY_4839)) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + sendMessage(player, "You use the Ogre Tomb Key to unlock the door.") + } else { + sendMessage(player, "The door is locked.") + } + return@on true + } + + on(Scenery.OGRE_STONE_DOOR_6872, SCENERY, "open") { player, node -> + if (getQuestStage(player, ZogreFleshEaters.questName) >= 9) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else if (inInventory(player, Items.OGRE_GATE_KEY_4839)) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + sendMessage(player, "You use the Ogre Tomb Key to unlock the door.") + } else { + sendMessage(player, "The door is locked.") + } + return@on true + } + + // Stage 2 + on(Scenery.CRUSHED_BARRICADE_6881, SCENERY, "climb-over") { player, node -> + if (player.location.x < 2456) { + val distance = player.location.getDistance(Location(2457, 3049, 0)).toInt() + forceMove(player, player.location, Location(2457, 3049, 0), 0, distance * 15, null, 1236) + } else { + val distance = player.location.getDistance(Location(2455, 3049, 0)).toInt() + forceMove(player, player.location, Location(2455, 3049, 0), 0, distance * 15, null, 1236) + } + return@on true + } + on(Scenery.CRUSHED_BARRICADE_6882, SCENERY, "climb-over") { player, node -> + if (player.location.x < 2456) { + val distance = player.location.getDistance(Location(2457, 3048, 0)).toInt() + forceMove(player, player.location, Location(2457, 3048, 0), 0, distance * 15, null, 1236) + } else { + val distance = player.location.getDistance(Location(2455, 3048, 0)).toInt() + forceMove(player, player.location, Location(2455, 3048, 0), 0, distance * 15, null, 1236) + } + return@on true + } + + // Stage 2A + on(Scenery.OGRE_COFFIN_6844, SCENERY, "search") { player, node -> + if (getVarbit(player, ZogreFleshEaters.varbitOgreCoffin) == 0) { + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> sendDialogueLines(player, "You search the coffin and find a small geometrically shaped hole in", "the side. It looks as if this hole was made with a considerable amount", "of force, maybe the thing which made the hole is still inside?").also { stage++ } + 1 -> sendDialogueLines(player, "The lock looks quite crude, with some skill and a slender blade, you", "may be able to force it.").also { stage = END_DIALOGUE } + } + } + }) + } else if (getVarbit(player, ZogreFleshEaters.varbitOgreCoffin) == 1) { + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> sendDialogueLines(player, "The lid looks heavy, but now that you've unlocked it, you may be", "able to lift it. You prepare yourself.").also { stage++ } + 1 -> playerl("Urrrgggg.").also { sendChat(player, "Urrrgggg."); stage++ } + 2 -> playerl("Aarrrgghhh!").also { sendChat(player, "Aarrrgghhh!"); stage++ } + // Supposed to have a failure state here. + 3 -> playerl("Raarrrggggg! Yes!").also { sendChat(player, "Raarrrggggg! Yes!"); stage++ } + 4 -> sendDialogueLines(player, "You eventually manage to lift the lid.").also { + setVarbit(player, ZogreFleshEaters.varbitOgreCoffin, 3, true) + stage = END_DIALOGUE + } + } + } + }) + } + return@on true + } + onUseWith(IntType.SCENERY, Items.KNIFE_946, Scenery.OGRE_COFFIN_6844) { player, _, _ -> + sendItemDialogue(player, Items.KNIFE_946, + "With some skill you manage to slide the blade along the lock edge and click into place the teeth of the primitive mechanism.") + setVarbit(player, ZogreFleshEaters.varbitOgreCoffin, 1, true) + return@onUseWith true + } + + on(Scenery.OGRE_COFFIN_6845, SCENERY, "search") { player, node -> + sendItemDialogue(player, Items.BLACK_PRISM_4808, + "You find a creepy looking black prism inside.") + addItemOrDrop(player, Items.BLACK_PRISM_4808) + return@on true + } + + on(Items.BLACK_PRISM_4808, ITEM, "look-at") { player, node -> + sendItemDialogue(player, Items.BLACK_PRISM_4808, + "It looks like a smokey black gem of some sort...very creepy. Some magical force must have prevented it from being shattered when it hit the coffin.") + return@on true + } + + // Stage 2B + on(Scenery.BROKEN_LECTURN_6846, SCENERY, "search") { player, node -> + sendMessage(player, "You search the broken down lecturn.") + if (inInventory(player, Items.TORN_PAGE_4809)) { + sendMessage(player, "You find nothing.") + } else { + sendItemDialogue(player, Items.TORN_PAGE_4809, + "You find a half torn page...it has spidery writing all over it.") + addItemOrDrop(player, Items.TORN_PAGE_4809) + } + return@on true + } + + on(Items.TORN_PAGE_4809, ITEM, "read") { player, node -> + sendDialogue(player, "You don't manage to understand all of it as there is only a half page here. But it seems the spell was used to place a curse on an area and for all time raise the dead.") + return@on true + } + + // Stage 2C + on(Scenery.SKELETON_6893, SCENERY, "search") { player, node -> + if (getQuestStage(player, ZogreFleshEaters.questName) >= 2){ + if (getAttribute(player, ZogreFleshEaters.attributeFoughtZombie, false)) { + + if (inInventory(player, Items.RUINED_BACKPACK_4810)) { + sendMessage(player, "You find nothing on the corpse.") + } else { + sendMessage(player, "You find another backpack.") + addItemOrDrop(player, Items.RUINED_BACKPACK_4810) + } + } else { + // Zombie time. + sendMessage(player, "Something screams into life right in front of you.") + val npc = NPC(NPCs.ZOMBIE_1826) + npc.isRespawn = false + npc.isWalks = false + npc.location = Location(2442, 9459, 2) + npc.direction = Direction.NORTH + npc.init() + npc.attack(player) + } + } else { + // At no point should this be reached since you need to start the quest anyway. + sendMessage(player, "You find nothing on the corpse.") + } + return@on true + } + on(Items.RUINED_BACKPACK_4810, ITEM, "open") { player, node -> + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> { + sendItemDialogue(player, Items.RUINED_BACKPACK_4810, + "Just before you open the backpack, you notice a small leather patch with the moniker: 'B.Vahn', on it.").also { stage++ } + sendItemZoomOnInterface(player, 241, 1, Items.RUINED_BACKPACK_4810, 230) + } + 1 -> sendItemDialogue(player, Items.DRAGON_INN_TANKARD_4811, + "You find an interesting looking tankard.").also { + setAttribute(player, ZogreFleshEaters.attributeFoundTankard, true) + if(removeItem(player, node)) { + addItem(player, Items.ROTTEN_FOOD_2959) + addItem(player, Items.KNIFE_946) + addItem(player, Items.DRAGON_INN_TANKARD_4811) + } + stage++ + } + 2 -> sendDoubleItemDialogue(player, Items.KNIFE_946, Items.ROTTEN_FOOD_2959, "You find a knife and some rotten food, the backpack is ripped to shreds.").also { + sendMessage(player, "You find a knife and some rotten food.") + sendMessage(player, "You find an interesting looking tankard.") + stage = END_DIALOGUE + } + } + } + }) + return@on true + } + + + on(Items.DRAGON_INN_TANKARD_4811, ITEM, "look-at") { player, node -> + sendItemDialogue(player, Items.DRAGON_INN_TANKARD_4811, + "A stout ceramic tankard with a Dragon Emblem on the side, the words, 'Ye Olde Dragon Inn' are inscribed in the bottom.") + return@on true + } + + // Zavistic Bell, Stage 2,3,4,5,6 and on (Actually should be standalone. + on(Scenery.BELL_6847, SCENERY, "ring") { player, node -> + sendMessage(player, "You ring the bell.") + // TODO: Make Zavistic appear at the bell area. + openDialogue(player, content.region.kandarin.yanille.dialogue.ZavisticRarveDialogueFile(), NPC(NPCs.ZAVISTIC_RARVE_2059)) + return@on true + } + + // Stage 4A + onUseWith(IntType.NPC, Items.DRAGON_INN_TANKARD_4811, NPCs.BARTENDER_739) { player, used, with -> + openDialogue(player, BartenderDialogueFile(1), with as NPC) + return@onUseWith true + } + onUseWith(IntType.NPC, Items.SITHIK_PORTRAIT_4814, NPCs.BARTENDER_739) { player, used, with -> + // The good portrait + openDialogue(player, BartenderDialogueFile(2), with as NPC) + return@onUseWith true + } + onUseWith(IntType.NPC, Items.SITHIK_PORTRAIT_4815, NPCs.BARTENDER_739) { player, used, with -> + // The bad portrait + openDialogue(player, BartenderDialogueFile(3), with as NPC) + return@onUseWith true + } + on(Items.SIGNED_PORTRAIT_4816, ITEM, "look-at") { player, node -> + sendItemDialogue(player, Items.SIGNED_PORTRAIT_4816, + "You see an image of Sithik with a message underneath 'I, the bartender of the Dragon Inn, do swear that this is a true likeness of the wizzy who was talking to Brentle Vahn, my customer the other day.'") + return@on true + } + onUseWith(IntType.NPC, Items.SITHIK_PORTRAIT_4814, NPCs.ZAVISTIC_RARVE_2059) { player, used, with -> + // The good portrait + openDialogue(player, ZavisticRarveUseItemsDialogueFile(3), with as NPC) + return@onUseWith true + } + onUseWith(IntType.NPC, Items.SITHIK_PORTRAIT_4815, NPCs.ZAVISTIC_RARVE_2059) { player, used, with -> + // The bad portrait + openDialogue(player, ZavisticRarveUseItemsDialogueFile(4), with as NPC) + return@onUseWith true + } + + + // Stage 4B + on(Items.BOOK_OF_PORTRAITURE_4817, ITEM, "read") { player, node -> + sendDialogueLines(player, + "All interested artisans should really consider taking up the hobby of", + "portraiture. To do so, one uses a piece of papyrus on the intended", + "subject to initiate a likeness drawing activity.") + return@on true + } + + // Stage 4C + on(Items.BOOK_OF_HAM_4829, ITEM, "read") { player, node -> + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> { + sendDialogue(player, + "You read this book for a while, it seems to be some sort of political "+ + "manifesto about how the king doesn't do enough to safeguard the "+ + "citizens of the realm from the monsters that still thrive within the "+ + "borders. ").also { stage++ } + // This is the original, but it is too big for this to handle. +// sendDialogueLines(player, +// "You read this book for a while, it seems to be some sort of political", +// "manifesto about how the king doesn't do enough to safeguard the", +// "citizens of the realm from the monsters that still thrive within the", +// "borders. It sends out a rallying to all people who would want to", +// "stop monsters, to join the HAM movement.").also { stage++ } + } + 1 -> sendDialogue(player, "It sends out a rallying to all people who would want to stop monsters, to join the HAM movement.").also { stage++ } + 2 -> sendPlayerDialogue(player, "Hmm, Sithik must really hate monsters then, I wonder if he hates ogres in particular?").also { + stage = END_DIALOGUE + } + } + } + }) + return@on true + } + + // Stage 4D + on(Items.NECROMANCY_BOOK_4837, ITEM, "read") { player, node -> + sendDialogueLines(player, + "This book uses very strange language and some", + "incomprehensible symbols. It has a very dark and evil feeling to", + "it. As you're looking through the book, you notice that", + "one of the pages has been torn and half of it is missing.") + return@on true + } + + onUseWith(IntType.ITEM, Items.NECROMANCY_BOOK_4837, Items.TORN_PAGE_4809) { player, _, _ -> + sendDoubleItemDialogue(player, Items.NECROMANCY_BOOK_4837, Items.TORN_PAGE_4809, + "The torn page matches exactly the part where a torn out page is missing from the book. You feel sure that this page came from this book.") + return@onUseWith true + } + + // Uglug Nar Shop + onUseWith(IntType.NPC, intArrayOf(Items.RELICYMS_BALM1_4848, Items.RELICYMS_BALM2_4846, Items.RELICYMS_BALM3_4844, Items.RELICYMS_BALM4_4842), NPCs.UGLUG_NAR_2039) { player, used, with -> + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> sendItemDialogue(player, used.id,"You show the potion to Uglug Nar.").also { stage++ } + 1 -> playerl("Hey, here you go! I brought you some of the potion which should cure the disease. You said that you would buy some from me.").also { + if (getAttribute(player, ZogreFleshEaters.attributeOpenUglugNarShop, false)) { + stage = 2 + } else { + stage = 3 + } + } + 2 -> sendNPCDialogue(player, NPCs.UGLUG_NAR_2039, "Yous creatures is da funny ones... yous already solds me's ones now..and us can now sell un to yous!", FacialExpression.OLD_NORMAL).also { stage = END_DIALOGUE } + 3 -> sendNPCDialogue(player, NPCs.UGLUG_NAR_2039, "Yous creatures done da good fing...yous get many bright pretties for dis...!", FacialExpression.OLD_NORMAL).also { stage++ } + 4 -> sendDoubleItemDialogue(player, Item(Items.COINS_995, 1000), used as Item, "You sell the potion and get 1000 coins in return.").also { + if (removeItem(player, used)) { + addItemOrDrop(player, Items.COINS_995, 1000) + setAttribute(player, ZogreFleshEaters.attributeOpenUglugNarShop, true) + } + stage = END_DIALOGUE + } + } + } + }) + return@onUseWith true + } + + // Stage 8 to 9 + on(Scenery.STAND_6897, SCENERY, "search") { player, node -> + if (getQuestStage(player, ZogreFleshEaters.questName) == 8 && + getAttribute(player, ZogreFleshEaters.attributeSlashBashInstance, null) == null + ) { + // Zombie time. + sendMessage(player, "Something stirs behind you!") + val npc = NPC(NPCs.SLASH_BASH_2060) + setAttribute(player, ZogreFleshEaters.attributeSlashBashInstance, npc) + setAttribute(npc, "target", player) + npc.isRespawn = false + npc.isWalks = false + npc.location = Location(2478, 9446, 0) + npc.direction = Direction.EAST + npc.init() + npc.attack(player) + } else if (getQuestStage(player, ZogreFleshEaters.questName) > 8) { + if (inInventory(player, Items.OGRE_ARTEFACT_4818)) { + sendMessage(player, "You find nothing on the stand.") + } else { + sendMessage(player, "You find another artifact.") + addItemOrDrop(player, Items.OGRE_ARTEFACT_4818) + } + } else { + // At no point should this be reached since you need to start the quest anyway. + sendMessage(player, "You find nothing on the stand.") + } + return@on true + } + } +} diff --git a/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/ZogrePotionAndFletchingListeners.kt b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/ZogrePotionAndFletchingListeners.kt new file mode 100644 index 0000000..ca14c0f --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/ZogrePotionAndFletchingListeners.kt @@ -0,0 +1,109 @@ +package content.region.kandarin.feldip.quest.zogreflesheaters + +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import org.rs09.consts.Items +import kotlin.math.min + +public enum class BrutalArrows(val nailItem: Int, val level: Int, val product: Int, val exp: Double) { + BRONZE_BRUTAL(Items.BRONZE_NAILS_4819, 7, Items.BRONZE_BRUTAL_4773, 8.4), + IRON_BRUTAL(Items.IRON_NAILS_4820, 18, Items.IRON_BRUTAL_4778, 15.6), + STEEL_BRUTAL(Items.STEEL_NAILS_1539, 33, Items.STEEL_BRUTAL_4783, 30.6), + BLACK_BRUTAL(Items.BLACK_NAILS_4821, 38, Items.BLACK_BRUTAL_4788, 39.0), + MITHRIL_BRUTAL(Items.MITHRIL_NAILS_4822, 49, Items.MITHRIL_BRUTAL_4793, 45.0), + ADAMANT_BRUTAL(Items.ADAMANTITE_NAILS_4823, 62, Items.ADAMANT_BRUTAL_4798, 61.2), + RUNE_BRUTAL(Items.RUNE_NAILS_4824, 77, Items.RUNE_BRUTAL_4803, 75.0) + ; + + companion object { + @JvmField + val nailItemMap = values().associateBy { it.nailItem } + val nailItemArray = nailItemMap.values.map { it.nailItem }.toIntArray() + } +} +/** + * This handles potions and fletching related to zogre flesh eaters. + * + * Relicym's Balm is unique to zogre flesh eaters. + * Maybe move this to herblore when it can handle quest requirements better. + */ +class ZogrePotionAndFletchingListeners : InteractionListener { + + override fun defineListeners() { + // ROGUES_PURSE_POTIONUNF_4840 is already in UnfinishedPotion.java + onUseWith(IntType.ITEM, Items.ROGUES_PURSE_POTIONUNF_4840, Items.CLEAN_SNAKE_WEED_1526) { player, used, with -> + if (!hasLevelStat(player, Skills.HERBLORE, 8)) { + sendMessage(player, "You need a herblore level of 8 to make this mix.") + return@onUseWith true + } + if (getQuestStage(player, ZogreFleshEaters.questName) < 7) { + sendMessage(player, "You need to have partially completed Zogre Flesh Eaters to make this mix.") + return@onUseWith true + } + + if(removeItem(player, used) && removeItem(player, with)) { + sendMessage(player, "You add the snake weed to the rogues purse solution and make Relicyms Balm.") + addItem(player, Items.RELICYMS_BALM4_4842) + rewardXP(player, Skills.HERBLORE, 40.0) + } + return@onUseWith true + } + + // FletchingListeners.kt + // ACHEY_TREE_LOGS_2862 -> UNSTRUNG_COMP_BOW_4825 -> COMP_OGRE_BOW_4827 + // Requirement to wield comp ogre bow. + onEquip(Items.COMP_OGRE_BOW_4827) { player, _ -> + if (getQuestStage(player, ZogreFleshEaters.questName) >= 8){ + return@onEquip true + } + sendMessage(player, "You need to complete part of Zogre Flesh Eaters to equip this.") + return@onEquip false + } + + + onUseWith(IntType.ITEM, BrutalArrows.nailItemArray, Items.FLIGHTED_OGRE_ARROW_2865) { player, used, with -> + fun getMaxAmount(_unused: Int = 0): Int { + val tips = amountInInventory(player, used.id) + val shafts = amountInInventory(player, with.id) + return min(tips, shafts) + } + + fun process() { + val amountThisIter = min(6, getMaxAmount()) + if (removeItem(player, Item(used.id, amountThisIter)) && removeItem(player, Item(with.id, amountThisIter))) { + addItem(player, BrutalArrows.nailItemMap[used.id]!!.product, amountThisIter) + sendMessage(player, "You make $amountThisIter brutal arrows.") + rewardXP(player, Skills.FLETCHING, BrutalArrows.nailItemMap[used.id]!!.exp) + } + } + + if (getQuestStage(player, ZogreFleshEaters.questName) < 7) { + sendMessage(player, "You need to complete part of Zogre Flesh Eaters to make these.") + return@onUseWith true + } + + if (getStatLevel(player, Skills.FLETCHING) < BrutalArrows.nailItemMap[used.id]!!.level) { + sendMessage(player, "You need a Fletching level of " + BrutalArrows.nailItemMap[used.id]!!.level + " to make these.") + return@onUseWith true + } + + sendSkillDialogue(player) { + create { id, amount -> + runTask( + player, + delay = 2, + repeatTimes = min(amount, getMaxAmount() / 6 + 1), + task = ::process + ) + } + calculateMaxAmount(::getMaxAmount) + withItems(Item(BrutalArrows.nailItemMap[used.id]!!.product, 5)) + } + return@onUseWith true + } + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/ZombieBrentleVahnBehavior.kt b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/ZombieBrentleVahnBehavior.kt new file mode 100644 index 0000000..d244854 --- /dev/null +++ b/Server/src/main/content/region/kandarin/feldip/quest/zogreflesheaters/ZombieBrentleVahnBehavior.kt @@ -0,0 +1,40 @@ +package content.region.kandarin.feldip.quest.zogreflesheaters + +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.system.timer.impl.Disease +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +/** The zombie you have to fight when you click on the skeleton. */ +class ZombieBrentleVahnBehavior : NPCBehavior(NPCs.ZOMBIE_1826) { + + override fun beforeAttackFinalized(self: NPC, victim: Entity, state: BattleState) { + val disease = getOrStartTimer(victim, 10) + disease.hitsLeft = 10 + } + + override fun onDropTableRolled(self: NPC, killer: Entity, drops: ArrayList) { + super.onDropTableRolled(self, killer, drops) + // Drops backpack when killed. + if (killer is Player && getQuestStage(killer, ZogreFleshEaters.questName) in 2..4) { + drops.add(Item(Items.RUINED_BACKPACK_4810)) + setAttribute(killer, ZogreFleshEaters.attributeFoughtZombie, true) + } + } + + var clearTime = 0 + override fun tick(self: NPC): Boolean { + // You have 400 ticks to kill this guy + if (clearTime++ > 400) { + clearTime = 0 + poofClear(self) + } + return true + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/gnomestronghold/dialogue/AluftGianneJrDialogue.kt b/Server/src/main/content/region/kandarin/gnomestronghold/dialogue/AluftGianneJrDialogue.kt new file mode 100644 index 0000000..685abce --- /dev/null +++ b/Server/src/main/content/region/kandarin/gnomestronghold/dialogue/AluftGianneJrDialogue.kt @@ -0,0 +1,51 @@ +package content.region.kandarin.gnomestronghold.dialogue + +import content.minigame.gnomecooking.GC_BASE_ATTRIBUTE +import content.minigame.gnomecooking.GC_TUT_PROG +import core.game.component.Component +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable + +@Initializable +class AluftGianneJrDialogue(player: Player? = null) : DialoguePlugin(player) { + var tutorialStage = -1 + + override fun newInstance(player: Player?): DialoguePlugin { + return AluftGianneJrDialogue(player) + } + + override fun npc(vararg messages: String?): Component { + return super.npc(FacialExpression.OLD_NORMAL,*messages) + } + + override fun open(vararg args: Any?): Boolean { + tutorialStage = player.getAttribute("$GC_BASE_ATTRIBUTE:$GC_TUT_PROG",-1) + if(tutorialStage == -1){ + player("Hey can I get a job here?").also { stage = 0 } + } else { + npc("Having fun?").also { stage = 1000 } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> npc("Sure, go talk to my dad. I'll put","a good word in!").also { stage++ } + 1 -> player(FacialExpression.THINKING,"Th-thanks...?").also { stage++ } + 2 -> { + end() + player.setAttribute("/save:$GC_BASE_ATTRIBUTE:$GC_TUT_PROG",0) + } + + 1000 -> end() + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(4572) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/gnomestronghold/dialogue/AluftGianneSnrDialogue.kt b/Server/src/main/content/region/kandarin/gnomestronghold/dialogue/AluftGianneSnrDialogue.kt new file mode 100644 index 0000000..8d0c10e --- /dev/null +++ b/Server/src/main/content/region/kandarin/gnomestronghold/dialogue/AluftGianneSnrDialogue.kt @@ -0,0 +1,198 @@ +package content.region.kandarin.gnomestronghold.dialogue + +import content.minigame.gnomecooking.* +import core.game.component.Component +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.plugin.Initializable +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch +import org.rs09.consts.Items +import core.game.world.GameWorld +import core.tools.colorize +import java.util.concurrent.TimeUnit + +val gnomeItems = arrayOf( + Items.FRUIT_BATTA_2277,Items.TOAD_BATTA_2255,Items.CHEESE_PLUSTOM_BATTA_2259,Items.WORM_BATTA_2253,Items.VEGETABLE_BATTA_2281, +Items.CHOCOLATE_BOMB_2185,Items.VEG_BALL_2195,Items.TANGLED_TOADS_LEGS_2187,Items.WORM_HOLE_2191,Items.TOAD_CRUNCHIES_2217,Items.WORM_CRUNCHIES_2205,Items.CHOCCHIP_CRUNCHIES_2209,Items.SPICY_CRUNCHIES_2213,Items.FRUIT_BLAST_9514,Items.DRUNK_DRAGON_2092,Items.CHOC_SATURDAY_2074, +Items.SHORT_GREEN_GUY_9510,Items.BLURBERRY_SPECIAL_9520,Items.PINEAPPLE_PUNCH_9512,Items.WIZARD_BLIZZARD_9508) + +val ALUFT_ALOFT_BOX = Item(Items.ALUFT_ALOFT_BOX_9477) + +@Initializable +class AluftGianneSnrDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin(player) { + var tutorialProgress = -1 + var tutorialComplete = false + + override fun newInstance(player: Player?): core.game.dialogue.DialoguePlugin { + return AluftGianneSnrDialogue(player) + } + + override fun npc(vararg messages: String?): Component { + return super.npc(core.game.dialogue.FacialExpression.OLD_NORMAL,*messages) + } + + override fun open(vararg args: Any?): Boolean { + tutorialComplete = player.getAttribute("$GC_BASE_ATTRIBUTE:$GC_TUT_FIN",false) + tutorialProgress = player.getAttribute("$GC_BASE_ATTRIBUTE:$GC_TUT_PROG",-1) + + if(tutorialComplete){ + npc("Hello, adventurer. How can I help you?") + stage = 300 + return true + } + + if(tutorialProgress == -1){ + npc("Who are you and what do you want?") + stage = 1000 + return true + } + + if(tutorialProgress == 0){ + npc("Hello, adventurer. I heard from my son","that you'd like to do some work.") + stage = 0 + return true + } + + npc("Hello, adventurer. How goes the training?") + stage = tutorialProgress + + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> player(core.game.dialogue.FacialExpression.HAPPY,"Yes, how do I get started?").also { stage++ } + 1 -> npc("Well first thing's first I need to teach","you how to cook!").also { stage++ } + 2 -> player(core.game.dialogue.FacialExpression.THINKING,"But I already-").also { stage++ } + 3 -> npc("Stop whatever it is you're saying, no one knows","how to cook gnome food except gnomes!").also { stage++ } + 4 -> player("Alright, go on...").also{stage++} + 5 -> npc("Alright, first thing I want you to do is","make me a toad batta. Here's all the","ingredients, now get to work!").also { stage++ } + 6 -> { + end() + val items = arrayOf(Item(Items.BATTA_TIN_2164),Item(Items.GIANNE_DOUGH_2171),Item(Items.EQUA_LEAVES_2128),Item(Items.GNOME_SPICE_2169),Item(Items.CHEESE_1985), Item(Items.TOADS_LEGS_2152)) + if(!player.inventory.hasSpaceFor(*items)){ + player.dialogueInterpreter.sendDialogue("You don't have space for the items.") + } else { + player.inventory.add(*items) + player.setAttribute("/save:$GC_BASE_ATTRIBUTE:$GC_TUT_PROG",10) + } + } + + //Toad Batta completion check + 10 -> { + if(player.inventory.containsItem(Item(Items.TOAD_BATTA_2255))){ + player("Very well! I have the batta right here!").also { stage = 11 } + } else { + player("Not well, I haven't got the batta yet.").also { stage = 1000 } + } + } + 11 -> npc("Very well, hand it over then!").also { stage++ } + 12 -> { + player.inventory.remove(Item(Items.TOAD_BATTA_2255)) + player.setAttribute("/save:$GC_BASE_ATTRIBUTE:$GC_TUT_PROG",13) + player.dialogueInterpreter.sendDialogue("You hand over the toad batta.").also { stage++ } + } + 13 -> npc("Very nicely done. Now I would like you to make me","toad crunchies. Here's everything you need.").also { stage++ } + 14 -> { + end() + val items = arrayOf(Item(Items.CRUNCHY_TRAY_2165),Item(Items.EQUA_LEAVES_2128),Item(Items.GIANNE_DOUGH_2171),Item(Items.TOADS_LEGS_2152,2)) + if(!player.inventory.hasSpaceFor(*items)){ + player.dialogueInterpreter.sendDialogue("You don't have enough space for the items.") + } else { + player.inventory.add(*items) + player.setAttribute("/save:$GC_BASE_ATTRIBUTE:$GC_TUT_PROG",15) + } + } + + //Toad Crunchies completion check + 15 -> { + if(player.inventory.containsItem(Item(Items.TOAD_CRUNCHIES_2217))){ + player("Very well! I have the crunchies right here!").also { stage = 16 } + } else { + player("Not well, I haven't got the crunchies yet.").also { stage = 1000 } + } + } + + 16 -> npc("Very well, hand it over then!").also { stage++ } + 17 -> { + player.inventory.remove(Item(Items.TOAD_CRUNCHIES_2217)) + player.setAttribute("/save:$GC_BASE_ATTRIBUTE:$GC_TUT_PROG",18) + player.dialogueInterpreter.sendDialogue("You hand over the toad crunchies.").also { stage++ } + } + 18 -> npc("Very nice indeed. Now I'd like you to go see my friend","Blurberry at the bar.").also { stage = 1000 } + + + //Dialogue for getting jobs + 300 -> options("I'd like to take on a hard job.","I'd like an easy job please.").also { stage++ } + 301 -> end().also{ when (buttonId) { + 1 -> getJob(GnomeTipper.LEVEL.HARD) + 2 -> getJob(GnomeTipper.LEVEL.EASY) + }} + + 1000 -> end() + + else -> player("Uhhhh, good.").also { stage = 1000 } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(850) + } + + private fun getJob(level: GnomeTipper.LEVEL){ + if(!player.inventory.containsItem(ALUFT_ALOFT_BOX) && !player.bank.containsItem(ALUFT_ALOFT_BOX)){ + player.inventory.add(ALUFT_ALOFT_BOX) + } + if(player.getAttribute("$GC_BASE_ATTRIBUTE:$GC_JOB_ORDINAL",-1) != -1){ + player.dialogueInterpreter.sendDialogue("You already have a job.") + } else { + GlobalScope.launch { + var job = GnomeCookingJob.values().random() + while (job.level != level) { + job = GnomeCookingJob.values().random() + } + val item = Item(gnomeItems.random()) + player.setAttribute("$GC_BASE_ATTRIBUTE:$GC_JOB_ORDINAL", job.ordinal) + player.setAttribute("$GC_BASE_ATTRIBUTE:$GC_NEEDED_ITEM", item) + player.dialogueInterpreter.sendDialogue("I need to deliver a ${item.name.toLowerCase()} to ${NPC(job.npc_id).name.toLowerCase()},", "who is ${job.tip}") + GameWorld.Pulser.submit(GnomeRestaurantPulse(player, if (level == GnomeTipper.LEVEL.HARD) 11L else 6L)) + } + } + } + + internal class GnomeRestaurantPulse(val player: Player,val minutes: Long): Pulse(){ + var endTime = 0L + var timerMsgSent = false + init { + endTime = System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(minutes) + } + + override fun pulse(): Boolean{ + val isComplete = player.getAttribute("$GC_BASE_ATTRIBUTE:$GC_JOB_ORDINAL",-1) == -1 + + val minsLeft = TimeUnit.MILLISECONDS.toMinutes(endTime - System.currentTimeMillis()) + + if(minsLeft % 2L == 0L && !timerMsgSent){ + timerMsgSent = true + player.sendMessage(colorize("%RYou have $minsLeft minutes remaining on your job.")) + } else if(minsLeft % 2L != 0L) { + timerMsgSent = false + } + + if(System.currentTimeMillis() >= endTime){ + player.sendMessage(colorize("%RYou have run out of time and your job has expired.")) + player.removeAttribute("$GC_BASE_ATTRIBUTE:$GC_JOB_ORDINAL") + player.removeAttribute("$GC_BASE_ATTRIBUTE:$GC_JOB_COMPLETE") + player.removeAttribute("$GC_BASE_ATTRIBUTE:$GC_NEEDED_ITEM") + return true + } + + return isComplete + } + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/gnomestronghold/dialogue/BlurberryDialogue.kt b/Server/src/main/content/region/kandarin/gnomestronghold/dialogue/BlurberryDialogue.kt new file mode 100644 index 0000000..83c5449 --- /dev/null +++ b/Server/src/main/content/region/kandarin/gnomestronghold/dialogue/BlurberryDialogue.kt @@ -0,0 +1,92 @@ +package content.region.kandarin.gnomestronghold.dialogue + +import content.minigame.gnomecooking.GC_BASE_ATTRIBUTE +import content.minigame.gnomecooking.GC_TUT_FIN +import content.minigame.gnomecooking.GC_TUT_PROG +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import org.rs09.consts.Items + +@Initializable +class BlurberryDialogue(player: Player? = null): DialoguePlugin(player) { + var tutorialProgress = -1 + var tutorialComplete = false + + override fun newInstance(player: Player?): DialoguePlugin { + return BlurberryDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + tutorialComplete = player.getAttribute("$GC_BASE_ATTRIBUTE:$GC_TUT_FIN",false) + tutorialProgress = player.getAttribute("$GC_BASE_ATTRIBUTE:$GC_TUT_PROG",-1) + + if(tutorialProgress == 18){ + npc("Yes, you, Aluft said you would be coming.") + stage = 0 + return true + } + + if(tutorialComplete){ + npc("I do hope you're enjoying your work!") + stage = 1000 + return true + } + + npc("Hello, have you made that drink for me?") + stage = tutorialProgress + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> player("Yes! What is it I need to do?").also { stage++ } + 1 -> npc("Well, I'd like to show you how to make","a drink.").also { stage++ } + 2 -> player("Woah, sounds like fun!").also{ stage++ } + 3 -> npc("Alright, then, let's get to it!").also { stage++ } + 4 -> npc("I want you to make me a fruit blast. Simple drink!").also{ stage++ } + 5 -> npc("Here's everything you need.").also { stage++ } + 6 -> { + end() + val items = arrayOf(Item(Items.KNIFE_946),Item(Items.COCKTAIL_SHAKER_2025),Item(Items.COCKTAIL_GLASS_2026),Item(Items.PINEAPPLE_2114),Item(Items.LEMON_2102,2), Item(Items.ORANGE_2108)) + if(player.inventory.hasSpaceFor(*items)){ + player.inventory.add(*items) + player.setAttribute("/save:$GC_BASE_ATTRIBUTE:$GC_TUT_PROG",20) + } else { + player.dialogueInterpreter.sendDialogue("You don't have enough room for the items.") + } + } + + 20 -> { + if(player.inventory.containsItem(Item(Items.FRUIT_BLAST_9514))){ + player("Yes, yes I have! Here you go.").also { stage++ } + } else { + player("No I have not.").also { stage = 1000 } + } + } + + 21 -> { + player.dialogueInterpreter.sendDialogue("You hand over the fruit blast.") + player.inventory.remove(Item(Items.FRUIT_BLAST_9514)) + player.setAttribute("/save:$GC_BASE_ATTRIBUTE:$GC_TUT_PROG",22) + stage++ + } + + 22 -> npc("Excellent, I think you're ready to go on the job!").also { stage++ } + 23 -> { + npc("Go back and speak with Aluft now.") + player.setAttribute("/save:$GC_BASE_ATTRIBUTE:$GC_TUT_FIN",true) + stage = 1000 + } + + 1000 -> end() + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(848) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/gnomestronghold/dialogue/GnomeTrainerPlugin.java b/Server/src/main/content/region/kandarin/gnomestronghold/dialogue/GnomeTrainerPlugin.java new file mode 100644 index 0000000..8549ba9 --- /dev/null +++ b/Server/src/main/content/region/kandarin/gnomestronghold/dialogue/GnomeTrainerPlugin.java @@ -0,0 +1,112 @@ +package content.region.kandarin.gnomestronghold.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.tools.RandomFunction; + +/** + * Represents the dialogue plugin used for the gnome trainer. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class GnomeTrainerPlugin extends DialoguePlugin { + + /** + * Constructs a new {@code GnomeTrainerPlugin} {@code Object}. + */ + public GnomeTrainerPlugin() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code GnomeTrainerPlugin} {@code Object}. + * @param player the player. + */ + public GnomeTrainerPlugin(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new GnomeTrainerPlugin(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + int rand = RandomFunction.random(0, 3); + switch (rand) { + case 0: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello there."); + stage = 0; + break; + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello, what is this place?"); + stage = 3; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello how are you?"); + stage = 7; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "This is fun!"); + stage = 10; + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "This isn't a grannies' tea party, let's see some sweat", "human. Go! Go! Go!"); + stage = 1; + break; + case 1: + end(); + break; + case 3: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "This, my friend, is where we train. Here we improve", "out agility. It's an essential skill."); + stage = 4; + break; + case 4: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "It looks easy enough."); + stage = 5; + break; + case 5: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "If you complete the course in order from the slippery", "log to the end, your agility will increase much faster", "than by repeating just one obstacle."); + stage = 6; + break; + case 6: + end(); + break; + case 7: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I'm amazed by how much humans chat. The sign over", "there says training area, not pointless conversation area."); + stage = 8; + break; + case 8: + end(); + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "This is training soldier. If you want fun go make some", "cocktails."); + stage = 11; + break; + case 11: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 162 }; + } +} diff --git a/Server/src/main/content/region/kandarin/gnomestronghold/handlers/GnomeStrongholdPlugin.java b/Server/src/main/content/region/kandarin/gnomestronghold/handlers/GnomeStrongholdPlugin.java new file mode 100644 index 0000000..3356cca --- /dev/null +++ b/Server/src/main/content/region/kandarin/gnomestronghold/handlers/GnomeStrongholdPlugin.java @@ -0,0 +1,131 @@ +package content.region.kandarin.gnomestronghold.handlers; + +import core.cache.def.impl.SceneryDefinition; +import core.game.node.entity.skill.Skills; +import content.global.skill.agility.AgilityHandler; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.impl.ForceMovement; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.map.path.Pathfinder; +import core.game.world.GameWorld; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Handles Gnome stronghold options. + * @author Emperor + */ +@Initializable +public final class GnomeStrongholdPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(190).getHandlers().put("option:open", this); + SceneryDefinition.forId(1967).getHandlers().put("option:open", this); + SceneryDefinition.forId(1968).getHandlers().put("option:open", this); + SceneryDefinition.forId(9316).getHandlers().put("option:climb",this); + SceneryDefinition.forId(9317).getHandlers().put("option:climb",this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + Scenery object = (Scenery) node; + switch (object.getId()) { + case 9316: + case 9317: + final boolean scale = player.getLocation().getY() <= object.getLocation().getY(); + final Location end = object.getLocation().transform(scale ? 3 : -3, scale ? 6 : -6, 0); + if (!player.getSkills().hasLevel(Skills.AGILITY, 37)) { + player.getPacketDispatch().sendMessage("You must be level 37 agility or higher to climb down the rocks."); + break; + } + if (!scale) { + ForceMovement.run(player, player.getLocation(), end, Animation.create(740), Animation.create(740), Direction.SOUTH, 13).setEndAnimation(Animation.RESET); + } else { + ForceMovement.run(player, player.getLocation(), end, Animation.create(1148), Animation.create(1148), Direction.SOUTH, 13).setEndAnimation(Animation.RESET); + } + break; + case 1967: + case 1968: + openTreeDoor(player, object); + return true; + case 190: + openGates(player, object); + return true; + } + return true; + } + + /** + * Opens the tree doors. + * @param player the player. + * @param object the object. + */ + private void openTreeDoor(final Player player, final Scenery object) { + if (object.getCharge() == 88) { + return; + } + object.setCharge(88); + SceneryBuilder.replace(object, object.transform(object.getId() == 1967 ? 1969 : 1970), 4); + AgilityHandler.walk(player, -1, player.getLocation(), player.getLocation().transform(0, player.getLocation().getY() <= 3491 ? 2 : -2, 0), new Animation(1426), 0, null); + GameWorld.getPulser().submit(new Pulse(4) { + @Override + public boolean pulse() { + object.setCharge(1000); + return true; + } + }); + } + + /** + * Opens the stronghold gates. + * @param player The player. + * @param object The door. + */ + private void openGates(Player player, final Scenery object) { + if (object.getCharge() == 0) { + return; + } + object.setCharge(0); + SceneryBuilder.replace(object, object.transform(191), 4); + SceneryBuilder.add(new Scenery(192, Location.create(2462, 3383, 0)), 4); + Location start = Location.create(2461, 3382, 0); + Location end = Location.create(2461, 3385, 0); + if (player.getLocation().getY() > object.getLocation().getY()) { + Location s = start; + start = end; + end = s; + } + Pathfinder.find(player, end).walk(player); + GameWorld.getPulser().submit(new Pulse(4) { + @Override + public boolean pulse() { + object.setCharge(1000); + return true; + } + }); + } + + @Override + public Location getDestination(Node node, Node n) { + if (n instanceof Scenery) { + switch (((Scenery) n).getId()) { + case 190: + if (node.getLocation().getY() < n.getLocation().getY()) { + return Location.create(2461, 3382, 0); + } + return Location.create(2461, 3385, 0); + } + } + return null; + } + +} diff --git a/Server/src/main/content/region/kandarin/guilds/FishingGuild.java b/Server/src/main/content/region/kandarin/guilds/FishingGuild.java new file mode 100644 index 0000000..673f615 --- /dev/null +++ b/Server/src/main/content/region/kandarin/guilds/FishingGuild.java @@ -0,0 +1,151 @@ +package content.region.kandarin.guilds; + +import core.cache.def.impl.SceneryDefinition; +import core.plugin.Initializable; +import core.game.dialogue.DialoguePlugin; +import core.game.global.Skillcape; +import core.game.global.action.DoorActionHandler; +import core.game.node.entity.skill.Skills; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.world.map.Location; +import core.plugin.Plugin; + +/** + * Represents the plugin used for the fishing guild. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class FishingGuild extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(2025).getHandlers().put("option:open", this); + new MasterFisherDialogue().init(); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + switch (option) { + case "open": + switch (node.getId()) { + case 2025: + if (player.getSkills().getDynamicLevels()[Skills.FISHING] < 68 && player.getLocation().withinDistance(new Location(2611, 3394, 0))) { + player.getDialogueInterpreter().sendDialogues(308, null, "Hello, I'm afraid only the top fishers are allowed to use", "our premier fishing facilities."); + return true; + } + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + break; + } + break; + } + return true; + } + + /** + * Represents the master fisher dialogue. + * @author 'Vexia + * @version 1.0 + */ + public final class MasterFisherDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code MasterFisherDialogue} {@code Object}. + */ + public MasterFisherDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code MasterFisherDialogue} {@code Object}. + * @param player the player. + */ + public MasterFisherDialogue(final Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new MasterFisherDialogue(player); + } + + @Override + public boolean open(Object... args) { + if (!Skillcape.isMaster(player, Skills.FISHING)) { + npc("Hello, I'm afraid only the top fishers are allowed to use", "our premier fishing facilities."); + } else { + npc("Hello, only the top fishers are allowed to use", "our premier fishing facilities and you seem", "to meet the criteria. Enjoy!"); + } + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + if (Skillcape.isMaster(player, Skills.FISHING)) { + player("Can I buy a Skillcape of Fishing?"); + stage = 4; + } else { + player("Can you tell me about that skillcape you're wearing?"); + stage = 1; + } + break; + case 1: + npc("I'm happy to, my friend. This beautiful cape was", "presented to me in recognition of my skills and", "experience as a fisherman and I was asked to be the", "head of this guild at the same time. As the best"); + stage = 2; + break; + case 2: + npc("fisherman in the guild it is my duty to control who has", "access to the guild and to say who can buy similar", "skillcapes."); + stage = 3; + break; + case 3: + end(); + break; + case 4: + npc("Certainly! Right when you pay me 99000 coins."); + stage = 5; + break; + case 5: + options("Okay, here you go.", "No, thanks."); + stage = 6; + break; + case 6: + switch (buttonId) { + case 1: + player("Okay, here you go."); + stage = 7; + break; + case 2: + end(); + break; + } + break; + case 7: + if (Skillcape.purchase(player, Skills.FISHING)) { + npc("There you go! Enjoy."); + } + stage = 8; + + break; + case 8: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 308 }; + } + + } +} diff --git a/Server/src/main/content/region/kandarin/guilds/WizardGuildPlugin.java b/Server/src/main/content/region/kandarin/guilds/WizardGuildPlugin.java new file mode 100644 index 0000000..1322bf1 --- /dev/null +++ b/Server/src/main/content/region/kandarin/guilds/WizardGuildPlugin.java @@ -0,0 +1,407 @@ +package content.region.kandarin.guilds; + +import static core.api.ContentAPIKt.*; +import core.cache.def.impl.NPCDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.game.dialogue.DialoguePlugin; +import core.game.global.Skillcape; +import core.game.global.action.ClimbActionHandler; +import core.game.global.action.DoorActionHandler; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.skill.Skills; +import core.game.node.scenery.Scenery; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.plugin.Plugin; +import content.global.travel.EssenceTeleport; +import content.data.Quests; + +/** + * Represents the wizard guild plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class WizardGuildPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(1600).getHandlers().put("option:open", this); + SceneryDefinition.forId(1601).getHandlers().put("option:open", this); + NPCDefinition.forId(462).getHandlers().put("option:teleport", this); + SceneryDefinition.forId(2154).getHandlers().put("option:open", this); + SceneryDefinition.forId(2155).getHandlers().put("option:open", this); + SceneryDefinition.forId(1722).getHandlers().put("option:climb-up", this); + new WizardDistentorDialogue().init(); + new ProfessorImblewynDialogue().init(); + new WizardFrumsconeDialogue().init(); + new RobeStoreDialogue().init(); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + final int id = node instanceof Scenery ? ((Scenery) node).getId() : ((NPC) node).getId(); + switch (option) { + case "climb-up": + switch (id) { + case 1722: + if (node.getLocation().equals(new Location(2590, 3089, 0))) { + ClimbActionHandler.climb(player, null, Location.create(2591, 3092, 1)); + } else { + ClimbActionHandler.climbLadder(player, (Scenery) node, option); + } + break; + } + break; + case "open": + switch (id) { + case 1600: + case 1601: + if (getDynLevel(player, Skills.MAGIC) < 66) { + player.getDialogueInterpreter().sendDialogue("You need a Magic level of at least 66 to enter."); + return true; + } + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + break; + case 2155: + case 2154: + player.getDialogueInterpreter().sendDialogues(460, null, "You can't attack the Zombies in the room, my Zombies", "are for magic target practice only and should be", "attacked from the other side of the fence."); + break; + } + break; + case "teleport": + if (!player.getQuestRepository().isComplete(Quests.RUNE_MYSTERIES)) { + player.getPacketDispatch().sendMessage("You need to have completed the Rune Mysteries Quest to use this feature."); + return true; + } + EssenceTeleport.teleport(((NPC) node), player); + return true; + } + return true; + } + + /** + * Represents the wizard distentor dialogue. + * @author 'Vexia + * @version 1.0 + */ + public final class WizardDistentorDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code WizardDistentorDialogue} {@code Object}. + */ + public WizardDistentorDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code WizardDistentorDialogue} {@code Object}. + * @param player the player. + */ + public WizardDistentorDialogue(final Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new WizardDistentorDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + npc("Welcome to the Magicians' Guild!"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + player("Hello there."); + stage = 1; + break; + case 1: + npc("What can I do for you?"); + stage = 2; + break; + case 2: + if (!player.getQuestRepository().isComplete(Quests.RUNE_MYSTERIES)) { + player("Nothing thanks, I'm just looking around."); + stage = 4; + return true; + } + options("Nothing thanks, I'm just looking around.", "Can you teleport me to Rune Essence?"); + stage = 3; + break; + case 3: + switch (buttonId) { + case 1: + player("Nothing thanks, I'm just looking around."); + stage = 4; + break; + case 2: + player("Can you teleport me to the Rune Essence?"); + stage = 6; + break; + } + break; + case 4: + npc("That's fine with me."); + stage = 5; + break; + case 5: + end(); + break; + case 6: + end(); + EssenceTeleport.teleport(npc, player); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 462 }; + } + + } + + /** + * Represents the wizard distentor dialogue. + * @author 'Vexia + * @version 1.0 + */ + public final class ProfessorImblewynDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code ProfessorImblewynDialogue} {@code Object}. + */ + public ProfessorImblewynDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code ProfessorImblewynDialogue} {@code Object}. + * @param player the player. + */ + public ProfessorImblewynDialogue(final Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new ProfessorImblewynDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + player("I didn't realise gnomes were interested in magic."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + npc("Gnomes are interested in everything, lad."); + stage = 1; + break; + case 1: + player("Of course."); + stage = 2; + break; + case 2: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 4586 }; + } + + } + + /** + * Represents the dialogue plugin used for the wizard frumscone. + * @author 'Vexia + * @version 1.0 + */ + public final class WizardFrumsconeDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code WizardFrumsconeDialogue} {@code Object}. + * @param player the player. + */ + public WizardFrumsconeDialogue(final Player player) { + super(player); + } + + /** + * Constructs a new {@code WizardFrumsconeDialogue} {@code Object}. + */ + public WizardFrumsconeDialogue() { + /** + * empty. + */ + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new WizardFrumsconeDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc("Do you like my magic Zombies? Feel free to kill them,", "there's plenty more where these came from!"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + end(); + return true; + } + + @Override + public int[] getIds() { + return new int[] { 460 }; + } + + } + + /** + * Represents the dialogue plugin used for the robe storew owner. + * @author 'Vexia + * @version 1.0 + */ + public final class RobeStoreDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code RobeStoreDialogue} {@code Object}. + * @param player the player. + */ + public RobeStoreDialogue(final Player player) { + super(player); + } + + /** + * Constructs a new {@code RobeStoreDialogue} {@code Object}. + */ + public RobeStoreDialogue() { + /** + * empty. + */ + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new RobeStoreDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + if (Skillcape.isMaster(player, Skills.MAGIC)) { + options("Ask about Skillcape.", "Something else"); + stage = 6; + } else { + npc("Welcome to the Magic Guild Store. Would you like to", "buy some magic supplies?"); + stage = 0; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + options("Yes please.", "No thank you."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + player("Yes please."); + stage = 4; + break; + case 2: + player("No thank you."); + stage = 3; + break; + } + break; + case 3: + end(); + break; + case 4: + end(); + npc.openShop(player); + break; + case 6: + switch (buttonId) { + case 1: + player("Can I buy a Skillcape of Magic?"); + stage = 7; + break; + case 2: + npc("Welcome to the Magic Guild Store. Would you like to", "buy some magic supplies?"); + stage = 0; + break; + } + break; + case 7: + npc("Certinaly! Right when you give me 99000 coins."); + stage = 8; + break; + case 8: + options("Okay, here you go.", "No, thanks."); + stage = 9; + break; + case 9: + switch (buttonId) { + case 1: + player("Okay, here you go."); + stage = 10; + break; + case 2: + end(); + break; + } + break; + case 10: + if (Skillcape.purchase(player, Skills.MAGIC)) { + npc("There you go! Enjoy."); + } + stage = 11; + break; + case 11: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 1658 }; + } + + } +} diff --git a/Server/src/main/content/region/kandarin/handlers/BeehivePlugin.java b/Server/src/main/content/region/kandarin/handlers/BeehivePlugin.java new file mode 100644 index 0000000..3308b3e --- /dev/null +++ b/Server/src/main/content/region/kandarin/handlers/BeehivePlugin.java @@ -0,0 +1,77 @@ +package content.region.kandarin.handlers; + +import core.cache.def.impl.SceneryDefinition; +import org.rs09.consts.Items; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.combat.ImpactHandler; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.plugin.Plugin; + +@Initializable +public class BeehivePlugin extends OptionHandler { + private static final Item REPELLANT = new Item(Items.INSECT_REPELLENT_28); + private static final Item BUCKET = new Item(Items.BUCKET_1925); + private static final Item BUCKET_OF_WAX = new Item(Items.BUCKET_OF_WAX_30); + private static final Item HONEYCOMB = new Item(12156); + + @Override + public boolean handle(Player player, Node node, String option) { + if (!player.getInventory().containsItem(REPELLANT)) { + player.getPacketDispatch().sendMessage("The bees fly out of the hive and sting you!"); + player.getImpactHandler().manualHit(player, 2, ImpactHandler.HitsplatType.NORMAL, 1); + GameWorld.getPulser().submit(new Pulse(2, player) { + @Override + public boolean pulse() { + player.getPacketDispatch().sendMessage("Maybe you can clear them out somehow."); + return true; + } + }); + } else { + switch (option) { + case "take-from": + if (!player.getInventory().containsItem(BUCKET)) { + player.getPacketDispatch().sendMessage("You need a bucket to do that."); + } else { + player.getInventory().remove(BUCKET); + player.getInventory().add(BUCKET_OF_WAX); + player.getPacketDispatch().sendMessage("You fill your bucket with wax from the hive."); + } + break; + case "take-honey": + if (!player.getInventory().hasSpaceFor(HONEYCOMB)) { + player.getPacketDispatch().sendMessage("You don't have enough space in your inventory."); + } else { + player.getInventory().add(HONEYCOMB); + player.getPacketDispatch().sendMessage("You take a chunk of honeycomb from the hive."); + } + break; + } + } + return true; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(68).getHandlers().put("option:take-from", this); + SceneryDefinition.forId(68).getHandlers().put("option:take-honey", this); + return this; + } + + @Override + public Location getDestination(Node mover, Node node) { + Location west = node.getCenterLocation().transform(Direction.WEST, 1); + Location east = node.getCenterLocation().transform(Direction.EAST, 1); + if (mover.getLocation().getDistance(east) <= mover.getLocation().getDistance(west)) { + return east; + } else { + return west; + } + } +} diff --git a/Server/src/main/content/region/kandarin/handlers/SinclairFlourBarrelPlugin.java b/Server/src/main/content/region/kandarin/handlers/SinclairFlourBarrelPlugin.java new file mode 100644 index 0000000..a3b5ecd --- /dev/null +++ b/Server/src/main/content/region/kandarin/handlers/SinclairFlourBarrelPlugin.java @@ -0,0 +1,83 @@ +package content.region.kandarin.handlers; + +import core.cache.def.impl.SceneryDefinition; +import org.rs09.consts.Items; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.OptionHandler; +import core.game.interaction.UseWithHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.plugin.ClassScanner; + + +/** + * Plugin that enables getting flour from barrel in Sinclair mansion kitchen. + * @author afaroutdude + */ +@Initializable +public final class SinclairFlourBarrelPlugin extends OptionHandler { + private final static Item EMPTY_POT = new Item(Items.EMPTY_POT_1931); + private static final Item FLOUR = new Item(Items.POT_OF_FLOUR_1933); + + @Override + public boolean handle(Player player, Node node, String option) { + return getFlour(player, (Scenery) node); + } + + public boolean getFlour(final Player player, final Scenery object) { + if (!player.getInventory().containsItem(EMPTY_POT)) { + player.getPacketDispatch().sendMessage("I need an empty pot to hold the flour in."); + return true; + } + if (player.getInventory().remove(EMPTY_POT)) { + player.lock(3); + player.getInventory().add(FLOUR); + player.getPacketDispatch().sendMessage("You take some flour from the barrel."); + + // Seers achievement diary + if (!player.getAchievementDiaryManager().getDiary(DiaryType.SEERS_VILLAGE).isComplete(0,5)) { + if (player.getAttribute("diary:seers:sinclair-flour", 0) >= 4) { + player.setAttribute("/save:diary:seers:sinclair-flour", 5); + player.getAchievementDiaryManager().getDiary(DiaryType.SEERS_VILLAGE).updateTask(player,0,5,true); + } else { + player.setAttribute("/save:diary:seers:sinclair-flour", player.getAttribute("diary:seers:sinclair-flour", 0) + 1); + } + } + + player.getPacketDispatch().sendMessage("There's still plenty of flour left."); + + return true; + } + return false; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(26122).getHandlers().put("option:take from", this); + ClassScanner.definePlugin(new FlourHandler()); + return this; + } + + private class FlourHandler extends UseWithHandler { + + public FlourHandler() { + super(EMPTY_POT.getId()); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(26122, OBJECT_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + return getFlour(event.getPlayer(), event.getUsedWith().asScenery()); + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/handlers/StoneCircleZone.kt b/Server/src/main/content/region/kandarin/handlers/StoneCircleZone.kt new file mode 100644 index 0000000..c276acc --- /dev/null +++ b/Server/src/main/content/region/kandarin/handlers/StoneCircleZone.kt @@ -0,0 +1,48 @@ +package content.region.kandarin.handlers + +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.world.map.zone.MapZone +import core.game.world.map.zone.ZoneBorders +import core.game.world.map.zone.ZoneBuilder +import core.plugin.Initializable +import core.plugin.Plugin +import core.api.* + +/** + * Handles the stone circle zone south of Ardougne. + * @author Kya + */ +@Initializable +class StoneCircleZone : MapZone("stone circle", true), Plugin { + /** + * Constructs a new `StoneCircleZone` `Object`. + */ + override fun configure() { + register(ZoneBorders(2558, 3219, 2559, 3225)) + register(ZoneBorders(2560, 3219, 2564, 3225)) + } + + override fun fireEvent(identifier: String?, vararg args: Any?): Any? { + return null + } + + override fun newInstance(arg: Any?): Plugin { + ZoneBuilder.configure(this) + return this + } + + override fun enter(e: Entity): Boolean { + if (e is Player) { + setVarbit(e, 4833, 1) + } + return super.enter(e) + } + + override fun leave(e: Entity, logout: Boolean): Boolean { + if (!logout && e is Player) { + setVarbit(e, 4833, 0) + } + return super.leave(e, logout) + } +} diff --git a/Server/src/main/content/region/kandarin/pisc/dialogue/ArnoldLydsporDialogue.kt b/Server/src/main/content/region/kandarin/pisc/dialogue/ArnoldLydsporDialogue.kt new file mode 100644 index 0000000..1fd3905 --- /dev/null +++ b/Server/src/main/content/region/kandarin/pisc/dialogue/ArnoldLydsporDialogue.kt @@ -0,0 +1,115 @@ +package content.region.kandarin.pisc.dialogue + +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.IronmanMode +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import core.game.dialogue.IfTopic +import core.game.dialogue.Topic +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE + +/** + * Provides the regular dialogue for Arnold Lydspor. + * TODO: Swan Song quest will need a special case handling. + * + * @author vddCore + */ +@Initializable +class ArnoldLydsporDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + START_DIALOGUE -> npcl( + FacialExpression.FRIENDLY, + "Ah, you come back! What you want from Arnold, heh?" + ).also { stage++ } + + 1 -> showTopics( + IfTopic( + FacialExpression.ASKING, + "Can you open my bank account, please?", + 2, + !hasIronmanRestriction(player, IronmanMode.ULTIMATE) + ), + + IfTopic( + FacialExpression.NEUTRAL, + "I'd like to check my bank PIN settings.", + 3, + !hasIronmanRestriction(player, IronmanMode.ULTIMATE) + ), + IfTopic( + FacialExpression.NEUTRAL, + "I'd like to collect items.", + 4, + !hasIronmanRestriction(player, IronmanMode.ULTIMATE) + ), + Topic(FacialExpression.ASKING, "Would you like to trade?", 5), + Topic(FacialExpression.FRIENDLY, "Nothing, I just came to chat.", 7) + ) + + 2 -> { + openBankAccount(player) + end() + } + + 3 -> { + openBankPinSettings(player) + end() + } + + 4 -> { + openGrandExchangeCollectionBox(player) + end() + } + + 5 -> npcl( + FacialExpression.FRIENDLY, + "Ja, I have wide range of stock..." + ).also { stage++ } + + 6 -> { + openNpcShop(player, NPCs.ARNOLD_LYDSPOR_3824) + end() + } + + 7 -> npcl(FacialExpression.FRIENDLY, + "Ah, that is nice - always I like to chat, but " + + "Herr Caranos tell me to get back to work! " + + "Here, you been nice, so have a present." + ).also { stage++ } + + 8 -> sendItemDialogue( + player, + Items.CABBAGE_1965, + "Arnold gives you a cabbage." + ).also { + addItemOrDrop(player, Items.CABBAGE_1965) + stage++ + } + + 9 -> playerl( + FacialExpression.HALF_THINKING, + "A cabbage?" + ).also { stage++ } + + 10 -> npcl( + FacialExpression.HAPPY, + "Ja, cabbage is good for you!" + ).also { stage++ } + + 11 -> playerl( + FacialExpression.NEUTRAL, + "Um... Thanks!" + ).also { stage = END_DIALOGUE } + } + + return true + } + + override fun getIds(): IntArray = intArrayOf(NPCs.ARNOLD_LYDSPOR_3824) +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/pisc/dialogue/FranklinCaranosDialogue.kt b/Server/src/main/content/region/kandarin/pisc/dialogue/FranklinCaranosDialogue.kt new file mode 100644 index 0000000..6ae06da --- /dev/null +++ b/Server/src/main/content/region/kandarin/pisc/dialogue/FranklinCaranosDialogue.kt @@ -0,0 +1,41 @@ +package content.region.kandarin.pisc.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class FranklinCaranosDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + START_DIALOGUE -> npcl( + FacialExpression.FRIENDLY, + "Hello again, " + player.username + "." + ).also { stage++ } + + 1 -> playerl( + FacialExpression.ASKING, + "Hello. How's the repair work going?" + ).also { stage++ } + + 2 -> npcl( + FacialExpression.NEUTRAL, + "I'm working on it. I can always do with more iron sheets, so if you've got any more, I'll give you 20 gp per sheet." + ).also { stage++ } + + 3 -> playerl( + FacialExpression.NEUTRAL, + "Thanks, I'll remember that." + ).also { stage = END_DIALOGUE } + } + + return true + } + + override fun getIds(): IntArray = intArrayOf((NPCs.FRANKLIN_CARANOS_3823)) +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/pisc/dialogue/HermanCaranosDialogue.kt b/Server/src/main/content/region/kandarin/pisc/dialogue/HermanCaranosDialogue.kt new file mode 100644 index 0000000..4e11718 --- /dev/null +++ b/Server/src/main/content/region/kandarin/pisc/dialogue/HermanCaranosDialogue.kt @@ -0,0 +1,57 @@ +package content.region.kandarin.pisc.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class HermanCaranosDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + START_DIALOGUE -> playerl( + FacialExpression.FRIENDLY, + "Hiya Hermie!" + ).also { stage++ } + + 1 -> npcl( + FacialExpression.FRIENDLY, + "Ah, " + player.username + "! How's the fishing going?" + ).also { stage++ } + + 2 -> playerl( + FacialExpression.NEUTRAL, + "Still working on it. How's the Colony?" + ).also { stage++ } + + 3 -> npcl( + FacialExpression.HAPPY, + "Flourishing, now that the colonists are coming back! Soon all the finest restaurants will be serving monkfish!" + ).also { stage++ } + + 4 -> npcl( + FacialExpression.ANNOYED, + "It's a pity those skeletons you brought here haven't gone away again, though. They're in the dormitories, which is rather annoying! So please take a little time to kick 'em around a bit." + ).also { stage++ } + + 5 -> npcl( + FacialExpression.ANNOYED, + "Oh, and please don't call me Hermie." + ).also { stage++ } + + 6 -> playerl( + FacialExpression.LAUGH, + "Whatever you like, Hermie!" + ).also { stage = END_DIALOGUE } + } + + return true + } + + override fun getIds(): IntArray = intArrayOf(NPCs.HERMAN_CARANOS_3822) + +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/pisc/dialogue/MathiasFlaconryDialogue.java b/Server/src/main/content/region/kandarin/pisc/dialogue/MathiasFlaconryDialogue.java new file mode 100644 index 0000000..dd3a27b --- /dev/null +++ b/Server/src/main/content/region/kandarin/pisc/dialogue/MathiasFlaconryDialogue.java @@ -0,0 +1,159 @@ +package content.region.kandarin.pisc.dialogue; + +import core.game.container.impl.EquipmentContainer; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.game.node.item.Item; + +/** + * Handles the MathiasFlaconryDialogue dialogue. + * @author 'Vexia + */ +@Initializable +public class MathiasFlaconryDialogue extends DialoguePlugin { + + public MathiasFlaconryDialogue() { + } + + public MathiasFlaconryDialogue(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[] { 5093 }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 90: + interpreter.sendOptions("Select an Option", "Ok, that seems reasonable.", "I'm not interested then, thanks."); + stage = 91; + break; + case 91: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Ok, that seems reasonable."); + stage = 95; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'm not interested then, thanks."); + stage = 323; + break; + + } + break; + case 323: + end(); + break; + case 95: + if (player.getBank().containsItem(FALCON) || player.getEquipment().containsItem(FALCON) || player.getInventory().containsItem(FALCON)) { + interpreter.sendDialogues(5093, FacialExpression.HALF_GUILTY, "You already have a falcon!"); + stage = 99; + return true; + } + if (player.getEquipment().get(EquipmentContainer.SLOT_HANDS) != null || player.getEquipment().get(EquipmentContainer.SLOT_SHIELD) != null || player.getEquipment().get(EquipmentContainer.SLOT_WEAPON) != null) { + interpreter.sendDialogues(5093, FacialExpression.HALF_GUILTY, "Sorry, free your hands, weapon, and shield slot first."); + stage = 99; + break; + } + if (player.getInventory().contains(995, 500)) { + player.getInventory().remove(new Item(995, 500)); + player.getEquipment().add(new Item(10024), true, false); + interpreter.sendDialogue("The falconer gives you a large leather glove and brings one of the", "smaller birds over to land on it."); + stage = 97; + } else { + end(); + player.getPacketDispatch().sendMessage("You need 500 gold goins."); + } + break; + case 97: + interpreter.sendDialogues(5093, FacialExpression.HALF_GUILTY, "Don't worry: I'll keep and eye on you to make sure", "you don't upset it roo much."); + stage = 99; + break; + case 99: + end(); + break; + case 500: + interpreter.sendDialogues(5093, FacialExpression.HALF_GUILTY, "Greetings. Can I help you at all?"); + stage = 501; + break; + case 501: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Could I have a go with your bird?"); + stage = 502; + break; + case 502: + if (player.getSkills().getLevel(Skills.HUNTER) < 43) { + npc("Try coming back when you're more experienced", "I wouldn't want my birds being injured."); + stage = 967; + return true; + } + interpreter.sendDialogues(5093, FacialExpression.HALF_GUILTY, "Training falcons is a lot of work and I", "doubt you're up to the task. However, I suppose", "I could let you try hunting with one."); + stage = 503; + break; + case 503: + interpreter.sendDialogues(5093, FacialExpression.HALF_GUILTY, "I have some tamer birds that I occasionally lend to rich", "noblemen who consider it a sufficiently refined sport for", "their tastes. and you look like the kind who might", "appreciate a good hunt."); + stage = 90; + break; + case 900: + interpreter.sendOptions("Select an Option", "Yes, please.", "No thank you."); + stage = 901; + break; + case 901: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, null, "Yes, please."); + stage = 920; + break; + case 2: + end(); + break; + } + break; + case 920: + player.getBank().remove(FALCON, new Item(10023)); + player.getInventory().remove(new Item(10023), FALCON); + player.getEquipment().add(FALCON, true, false); + interpreter.sendDialogue("The falconer gives you a large leather glove and brings one of the", "smaller birds over to land on it."); + stage = 97; + break; + case 967: + end(); + break; + } + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new MathiasFlaconryDialogue(player); + } + + private final Item FALCON = new Item(10024); + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + boolean quick = false; + if (player.getEquipment().contains(10023, 1)) { + interpreter.sendDialogues(5093, null, "Oh, it looks like you've lost your falcon.", "Would you like a new one?"); + stage = 900; + return true; + } + if (args.length == 2) + quick = true; + if (quick) { + interpreter.sendDialogues(5093, FacialExpression.HALF_GUILTY, "If you wish to try falconry, I request a small fee. How", "does 500 gold coins sound?"); + stage = 90; + return true; + } + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello there."); + stage = 500; + return true; + } +} diff --git a/Server/src/main/content/region/kandarin/pisc/handlers/SeaweedNetHandler.kt b/Server/src/main/content/region/kandarin/pisc/handlers/SeaweedNetHandler.kt new file mode 100644 index 0000000..4ae4df1 --- /dev/null +++ b/Server/src/main/content/region/kandarin/pisc/handlers/SeaweedNetHandler.kt @@ -0,0 +1,52 @@ +package content.region.kandarin.pisc.handlers + +import core.api.* +import core.game.node.item.Item +import core.game.node.scenery.Scenery +import core.game.node.scenery.SceneryBuilder +import core.game.system.task.Pulse +import org.rs09.consts.Animations +import org.rs09.consts.Items +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import content.data.Quests + +class SeaweedNetHandler : InteractionListener { + + override fun defineListeners() { + on(NET, IntType.SCENERY, "Take-from"){ player, node -> + if (!isQuestComplete(player, Quests.SWAN_SONG)) + { + sendMessage(player, "You must complete Swan Song first.") + } + else if (!hasSpaceFor(player, Item(Items.SEAWEED_401, 1))) { + sendMessage(player, "You do not have space in your inventory.") + } + else { + submitIndividualPulse(player, object : Pulse() { + private var tick = 0 + override fun pulse(): Boolean { + when(tick++){ + 0 -> { + animate(player, Animations.HUMAN_BURYING_BONES_827) // no idea what animation is supposed to be used, can't even find a video of this content + } + 1 -> { + if (addItem(player, Items.SEAWEED_401)) { + SceneryBuilder.replace(node.asScenery(), Scenery(EMPTY_NET, node.location, node.asScenery().rotation),5) // osrs wiki says 3 second respawn timer + } + return true + } + } + return false + } + }) + } + return@on true + } + } + + companion object { + private const val NET = 14973 + private const val EMPTY_NET = 14972 + } +} diff --git a/Server/src/main/content/region/kandarin/quest/dwarfcannon/CaptainLawgofDialogue.java b/Server/src/main/content/region/kandarin/quest/dwarfcannon/CaptainLawgofDialogue.java new file mode 100644 index 0000000..ae586a3 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/dwarfcannon/CaptainLawgofDialogue.java @@ -0,0 +1,493 @@ +package content.region.kandarin.quest.dwarfcannon; + +import content.data.Quests; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; + +import static core.api.ContentAPIKt.*; + +/** + * Handles captains lawgof dialogue. + * @author Vexia + */ +public class CaptainLawgofDialogue extends DialoguePlugin { + + /** + * The quest instance. + */ + private Quest quest; + + /** + * Constructs a new {@Code CaptainLawgofDialogue} {@Code + * Object} + */ + public CaptainLawgofDialogue() { + /** + * empty + */ + } + + /** + * Constructs a new {@Code CaptainLawgofDialogue} {@Code + * Object} + * @param player the player. + */ + public CaptainLawgofDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new CaptainLawgofDialogue(player); + } + + @Override + public boolean open(Object... args) { + quest = player.getQuestRepository().getQuest(Quests.DWARF_CANNON); + switch (quest.getStage(player)) { + case 80: + player("Hi."); + break; + case 50: + npc("How are you doing in there, trooper? We've been", "trying our best with that thing, but I just haven't got", "the patience."); + break; + case 40: + player("Hello, has Lollk returned yet?"); + break; + default: + player("Hello."); + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (quest.getStage(player)) { + case 0: + switch (stage) { + case 0: + npc("Guthix be praised, the cavalry has arrived! Hero, how", "would you like to be made an honorary member of the", "Black Guard?"); + stage++; + break; + case 1: + player("The Black Guard, what's that?"); + stage++; + break; + case 2: + npc("Hawhaw! 'What's that' " + (player.getAppearance().isMale() ? "he" : "she") + " asks, what a sense of", "humour! The Black Guard is the finest regiment in the", "dwarven army. Only the best of the best are allowed to", "join it and then they receive months of rigorous"); + stage++; + break; + case 3: + npc("training. However, we are currently in need of a hero,", "so for a limited time only I'm offering you, a human, a", "chance to join this prestigious regiment. What do you", "say?"); + stage++; + break; + case 4: + player("Sure, I'd be honoured to join."); + stage++; + break; + case 5: + quest.start(player); + npc("That's the spirit! Now trooper, we have no time to waste", "- the goblins are attacking from the forests to the", "South. There are so many of them, they are", "overwhelming my men and breaking through our"); + stage = 100; + break; + } + break; + case 10: + switch (stage) { + case 0: + if (DwarfCannon.allRailsFixed(player)) { + npc("Well done, trooper! The goblins seems to have stopped", "getting in. I think you've done the job!"); + stage = 105; + break; + } + npc("Hello, trooper, how are you doing with those railings?"); + stage++; + break; + case 1: + player("I'm getting there."); + stage++; + break; + case 2: + npc("The goblins are still getting in, so there must still be", "some broken railings."); + stage++; + break; + case 3: + if (!player.hasItem(new Item(14))) { + player("But I'm out of railings..."); + stage = 5; + break; + } + player("Don't worry, I'll find them soon enough."); + stage++; + break; + case 4: + end(); + break; + case 5: + npc("That's okay, we've got plenty, here you go."); + stage++; + break; + case 6: + player.getPacketDispatch().sendMessage("The Dwarf Captain gives you another railing."); + player.getInventory().add(new Item(14), player); + end(); + break; + case 100: + npc("perimeter defences; could you please try to fix the", "stockade by replacing the broken rails with these new", "ones?"); + stage++; + break; + case 101: + player("Sure, sounds easy enough..."); + stage++; + break; + case 102: + player.getInventory().add(new Item(14, 6), player); + player.getDialogueInterpreter().sendDialogue("The Dwarf Captain gives you six railings."); + stage++; + break; + case 103: + npc("Report back to me once you've fixed the railings."); + stage++; + break; + case 104: + player("Yes Sir, Captain!"); + end(); + break; + case 105: + player("Great, I'll be getting on then."); + stage++; + break; + case 106: + npc("What? I'll have you jailed for desertion!"); + stage++; + break; + case 107: + npc("Besides, I have another commission for you. Just", "before the goblins over-ran us we lost contact with our", "watch tower to the South, that's why the goblins", "managed to catch us unawares. I'd like you to perform."); + stage++; + break; + case 108: + npc("a covert operation into enemy territory, to check up on", "the guards we have stationed there."); + stage++; + break; + case 109: + npc("They should have reported in by now ..."); + stage++; + break; + case 110: + player("Okay, I'll see what I can find out."); + stage++; + break; + case 111: + npc("Excellent! I have two men there, the dwarf-in-charge is", "called Gilob, find him and tell him that I'll send him a", "relief guard just as soon as we mop up these remaining", "goblins."); + stage++; + break; + case 112: + setVarp(player, 0, 3, true); + quest.setStage(player, 20); + end(); + break; + } + break; + case 20: + switch (stage) { + case 0: + if (player.getInventory().containsItem(DwarfCannon.DWARF_REMAINS)) { + npc("Have you been to the watch tower yet?"); + stage = 4; + break; + } + npc("Hello, any news from the watchman?"); + stage++; + break; + case 1: + player("Not yet."); + stage++; + break; + case 2: + npc("Well, as quick as you can then."); + stage++; + break; + case 3: + end(); + break; + case 4: + player("I have some terrible news for you Captain, the goblins", "over ran the tower, your guards fought well but were", "overwhelmed."); + stage++; + break; + case 5: + interpreter.sendItemMessage(DwarfCannon.DWARF_REMAINS, "You give the Dwarf Captain his subordinate's remains..."); + stage++; + break; + case 6: + npc("I can't believe it, Gilob was the finest lieutenant I had!", "We'll give him a fitting funeral, but what of his", "command? His son, Lollk, was with him. Did you find", "his body too?"); + stage++; + break; + case 7: + player("No, there was only one body there, I searched pretty", "well."); + stage++; + break; + case 8: + npc("The goblins must have taken him. Please traveller, seek", "out the goblin's hideout and return the lad to us. They", "always attack from the South-west, so they must be", "based down there."); + stage++; + break; + case 9: + player("Okay, I'll see if I can find their hideout."); + stage++; + break; + case 10: + end(); + setVarp(player, 0, 5, true); + player.getInventory().remove(DwarfCannon.DWARF_REMAINS); + quest.setStage(player, 30); + break; + } + break; + case 30: + switch (stage) { + case 0: + npc("Trooper, have you managed to find the goblins' base?"); + stage++; + break; + case 1: + player("Not yet I'm afraid, but I'll keep looking..."); + stage++; + break; + case 2: + end(); + break; + } + break; + case 40: + switch (stage) { + case 0: + npc("He has, and I thank you from the bottom of my heart", "- without you he'd be a goblin barbecue!"); + stage++; + break; + case 1: + player("Always a please to help."); + stage++; + break; + case 2: + npc("In that case could I ask one more favour of you..."); + stage++; + break; + case 3: + npc("When the goblins attacked us some of them managed to", "slip past my guards and sabotage our cannon. I don't", "have anybody who understands how it works, could you,", "have a look at it and see if you could get it working for"); + stage++; + break; + case 4: + npc("us, please?"); + stage++; + break; + case 5: + player("Okay, I'll see what I can do."); + stage++; + break; + case 6: + npc("Thank you, take this toolkit, you'll need it..."); + stage++; + break; + case 7: + npc("Report back to me if you manage to fix it."); + stage++; + break; + case 8: + player.getInventory().add(DwarfCannon.TOOL_KIT, player); + setVarp(player, 0, 7); + quest.setStage(player, 50); + end(); + break; + } + break; + case 50: + switch (stage) { + case 0: + player("It's not an easy job, but I'm getting there."); + stage++; + break; + case 1: + if (!player.hasItem(DwarfCannon.TOOL_KIT)) { + player("I'm afraid I lost the toolkit..."); + stage = 3; + break; + } + npc("Good stuff, let me know if you have any luck. If we", "manage to get that thing working, those goblins will be", "no trouble at all."); + stage++; + break; + case 2: + end(); + break; + case 3: + npc("That was silly... never mind, here you go."); + stage++; + break; + case 4: + end(); + player.sendMessage("The Dwarf Captain gives you another toolkit."); + player.getInventory().add(DwarfCannon.TOOL_KIT, player); + break; + } + break; + case 60: + switch (stage) { + case -1: + end(); + break; + case 0: + npc("Hello there trooper, how's things?"); + stage++; + break; + case 1: + player("Well, I think I've done it, take a look..."); + stage++; + break; + case 2: + if (!player.getInventory().contains(1, 1)) { + npc("Bring me back the toolkit please."); + stage = -1; + break; + } + npc("That's fantastic, well done!"); + stage++; + break; + case 3: + npc("Well I don't believe it, it seems to be working perfectly!", "I seem to have underestimated you, trooper!"); + stage++; + break; + case 4: + player("Not bad for an adventurer eh?"); + stage++; + break; + case 5: + npc("Not bad at all, your effort is appreciated, my friend.", "Now, if I could figure what the thing uses as ammo..."); + stage++; + break; + case 6: + npc("The Black Guard forgot to send instructions. I know I", "said that was the last favour, but..."); + stage++; + break; + case 7: + player("What now?"); + stage++; + break; + case 8: + npc("I can't leave this post, could you go to the Black Guard", "base and find out what this thing actually shoots?"); + stage++; + break; + case 9: + player("Okay then, just for you!"); + stage++; + break; + case 10: + npc("That's great, we were lucky you came along when you", "did. The base is located just South of the Ice Mountain."); + stage++; + break; + case 11: + npc("You'll need to speak to Nulodion, the Dwarf Cannon", "engineer. He's the Weapons Development Chief for the", "Black Guard, so if anyone knows how to fire this thing,", "it'll be him."); + stage++; + break; + case 12: + player("Okay, I'll see what I can do."); + stage++; + break; + case 13: + player.getInventory().remove(DwarfCannon.TOOL_KIT); + player.sendMessage("You give the toolkit back to Captain Lawgof."); + setVarp(player, 0, 9, true); + quest.setStage(player, 70); + end(); + break; + } + break; + case 80: + switch (stage) { + case 0: + npc("Hello trooper, any word from the Cannon Engineer?"); + stage++; + break; + case 1: + player("Yes, I have spoken to him."); + stage++; + break; + case 2: + if (!player.getInventory().containsItem(DwarfCannon.MOULD) || !player.getInventory().containsItem(DwarfCannon.NULODION_NOTES)) { + player("He gave me some items to give you... but I seem to", "have lost something."); + stage++; + } else { + player("He gave me an ammo mould and some notes to give to", "you..."); + stage = 6; + } + break; + case 3: + npc("If you could go back and get another, I'd appreciate it."); + stage++; + break; + case 4: + player("Oh, okay then."); + stage++; + break; + case 5: + end(); + break; + case 6: + npc("Aah, of course, we make the ammo! This is great, now", "we will be able to defend ourselves. I don't know how to", "thank you..."); + stage++; + break; + case 7: + player("You could give me a cannon..."); + stage++; + break; + case 8: + npc("Hah! You'd be lucky, those things are worth a fortune."); + stage++; + break; + case 9: + npc("I'll tell you what, I'll write to the Cannon", "Engineer requesting him to sell you one. He controls", "production of the cannons."); + stage++; + break; + case 10: + npc("He won't be able to give you one, but for the right", "price, I'm sure he'll sell one to you."); + stage++; + break; + case 11: + player("Hmmm... sounds interesting, I might take you up on", "that."); + stage++; + break; + case 12: + quest.finish(player); + end(); + break; + } + break; + case 100: + switch (stage) { + case 0: + npc("Well hello there, how you doing?"); + stage++; + break; + case 1: + player("Not bad, yourself?"); + stage++; + break; + case 2: + npc("I'm great now, those goblins can't get close with this", "cannon blasting at them!"); + stage++; + break; + case 3: + end(); + break; + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 208 }; + } + +} diff --git a/Server/src/main/content/region/kandarin/quest/dwarfcannon/CaptainLawgofNPC.java b/Server/src/main/content/region/kandarin/quest/dwarfcannon/CaptainLawgofNPC.java new file mode 100644 index 0000000..3626828 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/dwarfcannon/CaptainLawgofNPC.java @@ -0,0 +1,52 @@ +package content.region.kandarin.quest.dwarfcannon; + +import core.game.node.entity.npc.AbstractNPC; +import core.game.world.map.Location; +import core.tools.RandomFunction; + +/** + * Handles the captain lawgof npc. + * @author Vexia + */ +public class CaptainLawgofNPC extends AbstractNPC { + + /** + * The force chats. + */ + private static final String[] CHATS = new String[] { "Don't just stand there, do something!", "Stop dawdling solider! You're in the army now!", "Hurry up on that patrol route, trooper!", "Keep an eye open for goblins!" }; + + /** + * Constructs a new {@Code CaptainLawgofNPC} {@Code Object} + * @param id the id. + * @param location the location. + */ + public CaptainLawgofNPC(int id, Location location) { + super(id, location); + } + + /** + * Constructs a new {@Code CaptainLawgofNPC} {@Code Object} + */ + public CaptainLawgofNPC() { + super(-1, null); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new CaptainLawgofNPC(id, location); + } + + @Override + public void handleTickActions() { + super.handleTickActions(); + if (RandomFunction.random(100) < 3) { + sendChat(RandomFunction.getRandomElement(CHATS)); + } + } + + @Override + public int[] getIds() { + return new int[] { 208 }; + } + +} diff --git a/Server/src/main/content/region/kandarin/quest/dwarfcannon/DwarfCannon.java b/Server/src/main/content/region/kandarin/quest/dwarfcannon/DwarfCannon.java new file mode 100644 index 0000000..8268ced --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/dwarfcannon/DwarfCannon.java @@ -0,0 +1,130 @@ +package content.region.kandarin.quest.dwarfcannon; + +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.ClassScanner; +import core.game.node.entity.skill.Skills; + +import static core.api.ContentAPIKt.*; +import content.data.Quests; + +/** + * Represents the dwarf cannon quest. + * @author Vexia + */ +@Initializable +public class DwarfCannon extends Quest { + /** + * The dwarf remain item. + */ + public static final Item DWARF_REMAINS = new Item(0); + + /** + * The tool kit item. + */ + public static final Item TOOL_KIT = new Item(1); + + /** + * The nulodion notes. + */ + public static final Item NULODION_NOTES = new Item(3); + + /** + * The mould item. + */ + public static final Item MOULD = new Item(4); + public static int[] railVarbits = new int[] { 2240, 2241, 2242, 2243, 2244, 2245 }; + + /** + * Constructs a new {@Code DwarfCannon} {@Code Object} + */ + public DwarfCannon() { + super(Quests.DWARF_CANNON, 49, 48, 1); + } + + @Override + public Quest newInstance(Object object) { + ClassScanner.definePlugin(new LollkDialogue()); + ClassScanner.definePlugin(new NulodionDialogue()); + ClassScanner.definePlugin(new CaptainLawgofNPC()); + ClassScanner.definePlugin(new CaptainLawgofDialogue()); + ClassScanner.definePlugin(new DwarfCannonPlugin()); + return this; + } + + @Override + public void drawJournal(Player player, int stage) { + super.drawJournal(player, stage); + switch (stage) { + case 0: + line(player, "I can start this quest by speaking to Lawgof the DwarvenCaptain of the Black Watch , he is defending an areaNorth-west of the Fishing Guild against goblin attack.", 11); + break; + case 10: + line(player, "I have spoken to Captain Lawgof, he recruited me into theBlack Guard and asked me to help the dwarves." + (allRailsFixed(player) ? "I have repaired all the broken railings,I should report back to Captain Lawgof." : "My first task is to fix the broken railingsin the dwarves defensive perimeter."), 11); + break; + case 20: + line(player, "I have spoken to Captain Lawgof, he recruited me into theBlack Guard and asked me to help the dwarves." + (player.hasItem(DWARF_REMAINS) ? "I went to the watchtower where I found the remains ofGilob.I should take them back to Captain Lawgof." : "I have repaired all the broken railings,Captain Lawgof has asked me to check up on his guards atthe watchtower to the South of this camp."), 11); + break; + case 30: + line(player, "I have spoken to Captain Lawgof, he recruited me into theBlack Guard and asked me to help the dwarves.I gave the remains to Captain Lawgof.he sent me to find the Goblin base, South-east of thecamp.", 11); + break; + case 40: + line(player, "I have spoken to Captain Lawgof, he recruited me into theBlack Guard and asked me to help the dwarves.I have rescued Lollk and sent him back to the Captain.I need to speak to Captain Lawgof again.", 11); + break; + case 50: + line(player, "I have spoken to Captain Lawgof, he recruited me into theBlack Guard and asked me to help the dwarves.Captain Lawgof has asked me to fix the multicannon.", 11); + break; + case 60: + line(player, "I have spoken to Captain Lawgof, he recruited me into theBlack Guard and asked me to help the dwarves.I've fixed the broken multicannon,I need to speak to Captain Lawgof again.", 11); + break; + case 70: + line(player, "I have spoken to Captain Lawgof, he recruited me into theBlack Guard and asked me to help the dwarves.Captain Lawgof asked me to find Nulodion the Engineer, heneeds to know what ammunition the multicannon fires.", 11); + break; + case 80: + line(player, "I have spoken to Captain Lawgof, he recruited me into theBlack Guard and asked me to help the dwarves.I've spoken to Nulodion,He gave me an ammo mould and notesI need to speak to Captain Lawgof again.", 11); + break; + case 100: + line(player, "I have spoken to Captain Lawgof, he recruited me into theBlack Guard and asked me to help the dwarves.I've helped the dwarves keep out the Goblins, and foundthe remains of their friend.I fixed the cannon and got a mould for Captain Lawgof.I can now buy a multicannon from Nulodion as a reward.QUEST COMPLETE!", 11); + break; + } + } + + @Override + public void start(Player player) { + super.start(player); + setVarp(player, 0, 1); + } + + @Override + public void finish(Player player) { + super.finish(player); + player.getPacketDispatch().sendString("1 Quest Point", 277, 8 + 2); + player.getPacketDispatch().sendString("750 Crafting XP", 277, 9 + 2); + player.getPacketDispatch().sendString("Permission to purchase and", 277, 10 + 2); + player.getPacketDispatch().sendString("use the Dwarf Multicannon", 277, 11 + 2); + player.getPacketDispatch().sendItemZoomOnInterface(TOOL_KIT.getId(), 235, 277, 3 + 2); + player.getSkills().addExperience(Skills.CRAFTING, 750); + player.getQuestRepository().syncronizeTab(player); + } + + @Override + public int[] getConfig(Player player, int stage) { + int val = 0; + if (stage >= 100) { + val = 11; + } else if (stage > 0 && stage < 100) { + val = getVarp(player, 0); + } + return new int[] { 0, val }; + } + + public static boolean allRailsFixed (Player player) { + for (int i = 0; i < 6; i++) { + if (getVarbit(player, railVarbits[i]) != 1) + return false; + } + return true; + } +} diff --git a/Server/src/main/content/region/kandarin/quest/dwarfcannon/DwarfCannonPlugin.java b/Server/src/main/content/region/kandarin/quest/dwarfcannon/DwarfCannonPlugin.java new file mode 100644 index 0000000..309895c --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/dwarfcannon/DwarfCannonPlugin.java @@ -0,0 +1,478 @@ +package content.region.kandarin.quest.dwarfcannon; + +import content.data.Quests; +import core.cache.def.impl.SceneryDefinition; +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.dialogue.DialogueAction; +import core.game.global.action.ClimbActionHandler; +import core.game.global.action.DoorActionHandler; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.OptionHandler; +import core.game.interaction.UseWithHandler; +import core.game.node.Node; +import core.game.node.entity.combat.ImpactHandler.HitsplatType; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import core.tools.Log; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; +import core.tools.RandomFunction; +import core.game.node.scenery.Scenery; + +import static core.api.ContentAPIKt.*; + +/** + * Handles the dwarf cannon quest interactions. + * @author Vexia + */ +public class DwarfCannonPlugin extends OptionHandler { + + /** + * The lollk npc. + */ + private static NPC lollk; + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(3).getHandlers().put("option:open", this); + SceneryDefinition.forId(5).getHandlers().put("option:inspect", this); + SceneryDefinition.forId(2).getHandlers().put("option:enter", this); + SceneryDefinition.forId(13).getHandlers().put("option:climb-over", this); + SceneryDefinition.forId(15601).getHandlers().put("option:inspect", this); + for (int i = 15; i < 21; i++) { + SceneryDefinition.forId(i).getHandlers().put("option:inspect", this); + } + SceneryDefinition.forId(15596).getHandlers().put("option:take", this); + SceneryDefinition.forId(1).getHandlers().put("option:search", this); + UseWithHandler.addHandler(5, UseWithHandler.OBJECT_TYPE, new UseWithHandler(1) { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + final Quest quest = player.getQuestRepository().getQuest(Quests.DWARF_CANNON); + if (quest.getStage(player) > 50) { + player.getDialogueInterpreter().sendDialogues(player, null, "This should work nicely now that I've fixed it."); + return true; + } + //setVarp(player, 1, 2041, true); + setVarp(player, 0, 8, true); + player.getQuestRepository().getQuest(Quests.DWARF_CANNON).setStage(player, 60); + player.sendMessage("Well done! You've fixed the cannon! Better go and tell Captain Lawgof."); + /* + * Component component = new Component(409); + * component.setPlugin(new ToolKitHandler()); + * event.getPlayer().getConfigManager().set(1, 2016);//reset + * event.getPlayer().getInterfaceManager(). open(component); + */ + return true; + } + + }); + return this; + } + + @Override + public boolean handle(final Player player, final Node node, String option) { + final Quest quest = player.getQuestRepository().getQuest(Quests.DWARF_CANNON); + switch (node.getId()) { + case 3: + if (!node.getLocation().equals(new Location(3015, 3453, 0))) { + return DoorActionHandler.handleAutowalkDoor(player, node.asScenery()); + } + if (quest.getStage(player) < 70) { + player.sendMessage("The door is locked."); + break; + } + return DoorActionHandler.handleAutowalkDoor(player, node.asScenery()); + case 5: + if (quest.getStage(player) == 50) { + player.getDialogueInterpreter().sendDialogues(player, null, "I guess I'd better fix it with the toolkit I was given."); + break; + } else if (quest.getStage(player) > 50) { + player.getDialogueInterpreter().sendDialogues(player, null, "This should work nicely now that I've fixed it."); + break; + } + player.getDialogueInterpreter().sendDialogue("The Black Guard sent Lawgof this cannon to help defend the mines", "against the goblins."); + break; + case 2: + player.animate(Animation.create(845)); + player.teleport(new Location(2619, 9797, 0), 2); + break; + case 13: + ClimbActionHandler.climb(player, new Animation(828), new Location(2623, 3391, 0)); + break; + case 15601: + if (node.getId() != node.asScenery().getWrapper().getId()) { + player.getDialogueInterpreter().sendDialogues(player, null, "I think I've already fixed this one."); + } + return true; + case 15: + case 16: + case 17: + case 18: + case 19: + case 20: + int index = 15 - node.getId(); + final int shift = 10 - (20 - node.getId()); + player.faceLocation(node.getLocation()); + player.getDialogueInterpreter().sendDialogue("The railing is broken and needs to be replaced."); + player.getDialogueInterpreter().addAction(new DialogueAction() { + @Override + public void handle(final Player player, int buttonId) { + if (quest.getStage(player) < 10) { + return; + } + if (!player.getInventory().contains(14, 1)) { + player.getDialogueInterpreter().sendDialogues(player, null, "I'm not going to be able to fix this without a new", "railing. Lawgof should have some spare ones."); + return; + } + player.sendMessage("You attempt to replace the broken railing..."); + if (!player.getInventory().contains(2347, 1)) { + player.sendMessage("You will need a hammer to fix the railings."); + return; + } + player.animate(Animation.create(4190)); + player.getPulseManager().run(new Pulse(1, player) { + int count; + boolean failed = RandomFunction.random(5) == 2; + + @Override + public boolean pulse() { + switch (++count) { + case 1: + if (RandomFunction.random(3) == 1) { + player.sendChat("Urrghh!"); + } + break; + case 3: + if (failed) { + player.sendChat("Ow!"); + player.getImpactHandler().manualHit(player, 2, HitsplatType.NORMAL); + } + break; + case 5: + if (failed) { + player.sendMessage("You accidentally crush your hand in the railing."); + return true; + } + player.getInventory().remove(new Item(14)); + player.sendMessage("The railing is now fixed."); + setVarbit(player, ((Scenery) node).getDefinition().getVarbitID(), 1, true); + if (DwarfCannon.allRailsFixed(player)) { + player.getDialogueInterpreter().sendDialogues(player, null, "I've fixed all these railings now."); + } + return true; + } + return false; + } + + }); + } + }); + break; + case 15596: + if (player.hasItem(DwarfCannon.DWARF_REMAINS)) { + player.getDialogueInterpreter().sendDialogues(player, null, "What? Carrying one set of Dwarf remains is enough..."); + return true; + } + player.getDialogueInterpreter().sendDialogues(player, null, "I had better take these remains."); + player.getDialogueInterpreter().addAction(new DialogueAction() { + + @Override + public void handle(Player player, int buttonId) { + if (!player.getInventory().hasSpaceFor(DwarfCannon.DWARF_REMAINS)) { + return; + } + setVarp(player, 0, 4, true); + player.getInventory().add(DwarfCannon.DWARF_REMAINS); + } + + }); + break; + case 1: + if (quest.getStage(player) != 30 || isSpawned()) { + player.sendMessage("You search the crate but find nothing."); + return true; + } + quest.setStage(player, 40); + setVarp(player, 0, 6, true); + spawnLollk(player); + break; + } + return true; + } + + + /** + * Spawns the lollk npc. + * @param player the player. + */ + private void spawnLollk(Player player) { + player.sendMessages("You search the crate...", "Inside you see a dwarf child, tied up!", "You untie the child."); + lollk.setInvisible(false); + lollk.sendChat("Hooray!"); + GameWorld.getPulser().submit(new Pulse(150, lollk) { + + @Override + public boolean pulse() { + lollk.setInvisible(true); + return true; + } + + }); + } + + /** + * Checks if lollk is spawned. + * @return {@code True} if so. + */ + private boolean isSpawned() { + if (lollk == null) { + lollk = NPC.create(207, new Location(2571, 9851, 0)); + lollk.init(); + lollk.setInvisible(true); + lollk.setWalks(false); + } + return !lollk.isInvisible(); + } + + @Override + public Location getDestination(Node node, Node n) { + if (n.getId() == 3) { + return DoorActionHandler.getDestination(node.asPlayer(), n.asScenery()); + } else if (n.getId() == 15601) { + if (n.getLocation().equals(new Location(2565, 3456, 0))) { + return new Location(2566, 3456, 0); + } + } + return null; + } + + /** + * Handles the tool kit. + * @author Vexia + */ + public static final class ToolKitHandler extends ComponentPlugin { + + /** + * The selected tool. + */ + private Tool tool; + + /** + * The toggled parts. + */ + private boolean[] toggled = new boolean[3]; + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.forId(409).setPlugin(this); + return null; + } + + @Override + public boolean handle(final Player player, Component component, int opcode, int button, int slot, int itemId) { + Tool tool = Tool.forId(button); + if (tool != null) { + this.tool = tool.select(player); + return true; + } + if (this.tool == null) { + player.sendMessage("You need to select a tool first."); + return true; + } + Part part = Part.forId(button); + if (part == null) { + log(this.getClass(), Log.ERR, "Unhandled part id - " + button + "!"); + return true; + } + if (this.tool.getPart() != part) { + player.sendMessage("This is the wrong tool to fix this part."); + return true; + } + toggled[part.ordinal()] = !toggled[part.ordinal()]; + part.interact(player, this.tool, toggled[part.ordinal()]); + if (toggled[0] && toggled[1] && toggled[2]) { + player.lock(5); + + //setVarp(player, 1, 2041, true); + //setVarp(player, 0, 8, true); + player.getQuestRepository().getQuest(Quests.DWARF_CANNON).setStage(player, 60); + player.sendMessage("Well done! You've fixed the cannon! Better go and tell Captain Lawgof."); + GameWorld.getPulser().submit(new Pulse(5, player) { + @Override + public boolean pulse() { + player.getInterfaceManager().close(); + return true; + } + }); + } + //player.sendMessage("Interacting with a part. Toggled=" + toggled[part.ordinal()] + ", configVal=" + player.getConfigManager().get(1) + "."); + return true; + } + + /** + * A tool. + * @author Vexia + */ + public static enum Tool { + WRENCH(1, 2017, Part.GEAR), PLIERS(2, 2018, Part.SAFETY_SWITCH), HOOK(3, 2020, Part.SPRING); + + /** + * The button. + */ + private final int button; + + /** + * The config value. + */ + private final int configValue; + + /** + * The part the tool fixes. + */ + private final Part part; + + /** + * Constructs a new {@Code Tool} {@Code Object} + * @param button the button. + * @param configValue the config value. + * @param part the part to fix. + */ + private Tool(int button, int configValue, Part part) { + this.button = button; + this.configValue = configValue; + this.part = part; + } + + /** + * Selects a tool. + * @param player the player. + */ + public Tool select(Player player) { + //setVarp(player, 1, configValue); + return this; + } + + /** + * Gets a tool. + * @param id the id. + * @return the tool. + */ + public static Tool forId(int id) { + for (Tool tool : values()) { + if (tool.getButton() == id) { + return tool; + } + } + return null; + } + + /** + * Gets the button. + * @return the button + */ + public int getButton() { + return button; + } + + /** + * Gets the configValue. + * @return the configValue + */ + public int getConfigValue() { + return configValue; + } + + /** + * Gets the part. + * @return the part + */ + public Part getPart() { + return part; + } + + } + + /** + * A part of the cannon. + * @author Vexia + */ + public static enum Part { + SPRING(8, 2025), SAFETY_SWITCH(7, 2026), GEAR(9, 2036); + + /** + * The button of the part. + */ + private final int button; + + /** + * The config value. + */ + private final int configValue; + + /** + * Constructs a new {@Code Part} {@Code Object} + * @param button the button. + * @param configValue the config value. + */ + private Part(int button, int configValue) { + this.button = button; + this.configValue = configValue; + } + + /** + * Handles the interaction of a part. + * @param player the player. + * @param tool the tool. + * @param toggled if toggled on. + */ + public void interact(Player player, Tool tool, boolean toggled) { + //setVarp(player, 1, toggled ? getConfigValue() : tool.getConfigValue()); + } + + /** + * Gets the part. + * @param id the id. + * @return the part. + */ + public static Part forId(int id) { + for (Part part : values()) { + if (part.getButton() == id) { + return part; + } + } + return null; + } + + /** + * Gets the button. + * @return the button + */ + public int getButton() { + return button; + } + + /** + * Gets the configValue. + * @return the configValue + */ + public int getConfigValue() { + return configValue; + } + + } + } +} diff --git a/Server/src/main/content/region/kandarin/quest/dwarfcannon/LollkDialogue.java b/Server/src/main/content/region/kandarin/quest/dwarfcannon/LollkDialogue.java new file mode 100644 index 0000000..08cedde --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/dwarfcannon/LollkDialogue.java @@ -0,0 +1,93 @@ +package content.region.kandarin.quest.dwarfcannon; + +import content.data.Quests; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; + +/** + * Handles captains lawgof dialogue. + * @author Vexia + */ +public class LollkDialogue extends DialoguePlugin { + + /** + * The quest instance. + */ + private Quest quest; + + /** + * Constructs a new {@Code LollkDialogue} {@Code Object} + */ + public LollkDialogue() { + /** + * empty + */ + } + + /** + * Constructs a new {@Code LollkDialogue} {@Code Object} + * @param player the player. + */ + public LollkDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new LollkDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + quest = player.getQuestRepository().getQuest(Quests.DWARF_CANNON); + switch (quest.getStage(player)) { + case 40: + npc("Thank the heavens, you saved me!", "I thought I'd be goblin lunch for sure!"); + break; + default: + player.sendMessage("The dwarf doesn't seem interested in talking to you."); + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (quest.getStage(player)) { + case 40: + switch (stage) { + case 0: + player("Are you ok?"); + stage++; + break; + case 1: + npc("I think so, I'd better run off home."); + stage++; + break; + case 2: + player("That's right, you get going. I'll catch up."); + stage++; + break; + case 3: + npc("Thanks again, brave adventurer."); + stage++; + break; + case 4: + npc.setInvisible(true); + end(); + break; + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 207 }; + } + +} diff --git a/Server/src/main/content/region/kandarin/quest/dwarfcannon/NulodionDialogue.java b/Server/src/main/content/region/kandarin/quest/dwarfcannon/NulodionDialogue.java new file mode 100644 index 0000000..05ac29b --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/dwarfcannon/NulodionDialogue.java @@ -0,0 +1,337 @@ +package content.region.kandarin.quest.dwarfcannon; + +import content.data.Quests; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; + +import static core.api.ContentAPIKt.*; + +/** + * Handles captains lawgof dialogue. + * @author Vexia + */ +public class NulodionDialogue extends DialoguePlugin { + + /** + * The cannon pieces. + */ + private static final Item[] CANNON_PIECES = new Item[] { new Item(6), new Item(8), new Item(10), new Item(12) }; + + /** + * The quest. + */ + private Quest quest; + + /** + * Constructs a new {@Code NulodionDialogue} {@Code Object} + */ + public NulodionDialogue() { + /** + * empty + */ + } + + /** + * Constructs a new {@Code NulodionDialogue} {@Code Object} + * @param player the player. + */ + public NulodionDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new NulodionDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + quest = player.getQuestRepository().getQuest(Quests.DWARF_CANNON); + switch (quest.getStage(player)) { + case 70: + player("Hello there."); + break; + default: + player("Hello again."); + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (quest.getStage(player)) { + case 70: + switch (stage) { + case 0: + npc("Can I help you?"); + stage++; + break; + case 1: + player("Captain Lawgof sent me. He's having trouble with his", "cannon."); + stage++; + break; + case 2: + npc("Of course, we forgot to send the ammo mould!"); + stage++; + break; + case 3: + player("It fires a mould?"); + stage++; + break; + case 4: + npc("Don't be silly - the ammo's made by using a mould.", "Here, take these to him. The instructions explain", "everything."); + stage++; + break; + case 5: + player("That's great, thanks."); + stage++; + break; + case 6: + npc("Thank you, adventurer. The Dwarf Black Guard will", "remember this."); + stage++; + break; + case 7: + setVarp(player, 0, 10); + quest.setStage(player, 80); + player.sendMessage("The Cannon Engineer gives you some notes and a mould."); + player.getInventory().add(DwarfCannon.NULODION_NOTES, player); + player.getInventory().add(DwarfCannon.MOULD, player); + end(); + break; + } + break; + case 80: + switch (stage) { + case 0: + if (!player.hasItem(DwarfCannon.NULODION_NOTES)) { + player("I've lost the notes."); + stage = 100; + break; + } + if (!player.hasItem(DwarfCannon.MOULD)) { + player("I've lost the cannonball mould."); + stage = 102; + break; + } + npc("So has the Captain figured out how to work the cannon", "yet?"); + stage++; + break; + case 1: + player("Not yet, but I'm sure he will."); + stage++; + break; + case 2: + npc("If you can get those items to him it'll be a great help."); + stage++; + break; + case 3: + end(); + break; + case 100: + npc("Here, take these..."); + stage++; + break; + case 101: + player.sendMessage("The Cannon Engineer gives you some more notes."); + player.getInventory().add(DwarfCannon.NULODION_NOTES, player); + end(); + break; + case 102: + npc("Deary me, you are trouble. Here, take this one."); + stage++; + break; + case 103: + player.sendMessage("The Cannon Engineer gives you another mould."); + player.getInventory().add(DwarfCannon.MOULD, player); + end(); + break; + } + break; + default: + switch (stage) { + case 0: + npc("Hello traveller, how's things?"); + stage++; + break; + case 1: + player("Not bad thanks, yourself?"); + stage++; + break; + case 2: + npc("I'm good, just working hard as usual..."); + stage++; + break; + case 3: + options("I was hoping you might sell a cannon?", "Well, take care of yourself then.", "I want to know more about the cannon.", "I've lost my cannon."); + stage++; + break; + case 4: + switch (buttonId) { + case 1: + player("I was hoping you might sell me a cannon?"); + stage = 10; + break; + case 2: + player("Well, take care of yourself then."); + stage = 20; + break; + case 3: + player("I want to know more about the cannon."); + stage = 30; + break; + case 4: + player("I've lost my cannon."); + stage = 40; + break; + } + break; + case 10: + npc("Hmmmmmmm..."); + stage++; + break; + case 11: + npc("I shouldn't really, but as you helped us so much, well, I", "could sort something out. I'll warn you though, they", "don't come cheap!"); + stage++; + break; + case 12: + player("How much?"); + stage++; + break; + case 13: + npc("For the full setup, 750,000 coins. Or I can sell you", "the separate parts... but it'll cost extra!"); + stage++; + break; + case 14: + player("That's not cheap!"); + stage++; + break; + case 15: + options("Okay, I'll take a cannon please.", "Can I look at the separate parts please?", "Sorry, that's too much for me.", "Have you any ammo or instructions to sell?"); + stage++; + break; + case 16: + switch (buttonId) { + case 1: + player("Okay, I'll take a cannon please."); + stage = 110; + break; + case 2: + player("Can I look at the separate parts please?"); + stage = 120; + break; + case 3: + player("Sorry, that's too much for me."); + stage = 130; + break; + case 4: + player("Have you any ammo or instructions to sell?"); + stage = 140; + break; + } + break; + case 20: + npc("Indeed I will adventurer."); + stage++; + break; + case 21: + end(); + break; + case 30: + npc("There's only so much I can tell you, adventurer.", "We've been working on this little beauty for some time", "now."); + stage++; + break; + case 31: + player("Is it effective?"); + stage++; + break; + case 32: + npc("In short bursts it's very effective, the most destructive", "weapon to date. The cannon automatically targets", "monsters close by. You just have to make the ammo", "and let rip."); + stage++; + break; + case 33: + end(); + break; + case 40: + npc("That's unfortunate... but don't worry, I can sort you", "out."); + stage++; + break; + case 41: + if (player.getSavedData().getActivityData().isLostCannon()) { + npc("There you go, take better care next time."); + stage = 43; + break; + } + npc("Oh dear, I'm only allowed to replace cannons that were", "stolen in reward. I'm sorry, but you'll have to buy a", "new set."); + stage++; + break; + case 43: + player.getSavedData().getActivityData().setLostCannon(false); + for (Item i : CANNON_PIECES) { + player.getInventory().add(i, player); + } + end(); + break; + case 42: + end(); + break; + case 110: + npc("Okay then, but keep it quiet... This thing's top secret!"); + stage++; + break; + case 111: + if (!player.getInventory().contains(995, 750000)) { + player("Oops, I don't have enough money."); + stage++; + break; + } + if (player.getInventory().remove(new Item(995, 750000))) { + for (Item i : CANNON_PIECES) { + player.getInventory().add(i, player); + } + } + npc("There you go adventurer, I hope you enjoy this", "fine work of craftsmanship."); + stage = 113; + break; + case 112: + npc("Sorry, I can't go any lower than that."); + stage++; + break; + case 113: + end(); + break; + case 120: + npc("Of course!"); + stage++; + break; + case 121: + end(); + npc.openShop(player); + break; + case 130: + npc("Fair enough, it's too much for most of us."); + stage++; + break; + case 131: + end(); + break; + case 140: + npc("Of course!"); + stage = 121; + break; + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 209 }; + } + +} diff --git a/Server/src/main/content/region/kandarin/quest/dwarfcannon/NulodionsNotes.kt b/Server/src/main/content/region/kandarin/quest/dwarfcannon/NulodionsNotes.kt new file mode 100644 index 0000000..9d9aea8 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/dwarfcannon/NulodionsNotes.kt @@ -0,0 +1,42 @@ +package content.region.kandarin.quest.dwarfcannon + +import content.global.handlers.iface.BookInterface +import content.global.handlers.iface.BookLine +import content.global.handlers.iface.Page +import content.global.handlers.iface.PageSet +import core.api.setAttribute +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items + +@Initializable +class NulodionsNotes : InteractionListener { + companion object { + private val TITLE = "Nulodion's notes" + private val CONTENTS = arrayOf( + PageSet( + Page( + BookLine("Ammo for the Dwarf Multi", 55), + BookLine("Cannon must be made from", 56), + BookLine("steel bars. The bars must be", 57), + BookLine("heated in a furnace and used", 58), + BookLine("with the ammo mould.", 59), + ) + ), + ) + } + + private fun display(player: Player, pageNum: Int, buttonID: Int): Boolean { + BookInterface.pageSetup(player, BookInterface.FANCY_BOOK_3_49, TITLE, CONTENTS) + return true + } + + override fun defineListeners() { + on(Items.NULODIONS_NOTES_3, IntType.ITEM, "read") { player, _ -> + BookInterface.openBook(player, BookInterface.FANCY_BOOK_3_49, ::display) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/dwarfcannon/dmc/CannonTimer.kt b/Server/src/main/content/region/kandarin/quest/dwarfcannon/dmc/CannonTimer.kt new file mode 100644 index 0000000..064c341 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/dwarfcannon/dmc/CannonTimer.kt @@ -0,0 +1,34 @@ +package content.region.kandarin.quest.dwarfcannon.dmc + +import core.api.* +import core.tools.* +import core.game.system.timer.* +import core.game.node.entity.Entity +import core.game.node.entity.player.Player + +class CannonTimer : RSTimer (1, "dmc:timer") { + lateinit var dmcHandler: DMCHandler + var ticksUntilDecay = 2500 + var isFiring = false + + override fun run (entity: Entity) : Boolean { + if (entity !is Player) + return false + if (!dmcHandler.cannon.isActive()) + return false + if (isFiring) + isFiring = dmcHandler.rotate() + if (--ticksUntilDecay == 500) { + sendMessage (entity, colorize("%RYour cannon is about to decay.")) + } else if (ticksUntilDecay == 0) { + dmcHandler.explode(true) + } + return ticksUntilDecay > 0 && dmcHandler.cannon.isActive() + } + + override fun getTimer (vararg args: Any) : RSTimer { + val t = retrieveInstance() as CannonTimer + t.dmcHandler = args[0] as DMCHandler + return t + } +} diff --git a/Server/src/main/content/region/kandarin/quest/dwarfcannon/dmc/DMCHandler.java b/Server/src/main/content/region/kandarin/quest/dwarfcannon/dmc/DMCHandler.java new file mode 100644 index 0000000..9b7d236 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/dwarfcannon/dmc/DMCHandler.java @@ -0,0 +1,288 @@ +package content.region.kandarin.quest.dwarfcannon.dmc; + +import core.api.LogoutListener; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.ImpactHandler.HitsplatType; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.audio.Audio; +import core.game.node.entity.skill.Skills; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.map.zone.ZoneRestriction; +import core.game.world.update.flag.context.Animation; +import core.tools.RandomFunction; +import org.jetbrains.annotations.NotNull; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.world.GameWorld; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.*; + +/** + * Handles a player's Dwarf Multi-cannon. + * @author Emperor + */ +public final class DMCHandler implements LogoutListener { + + /** + * The player. + */ + private final Player player; + + /** + * The cannon object. + */ + private Scenery cannon; + + /** + * The amount of cannonballs loaded. + */ + private int cannonballs; + + /** + * The current direction. + */ + private DMCRevolution direction = DMCRevolution.NORTH; + + private CannonTimer timer; + + public DMCHandler() { + this.player = null; + } + + /** + * Constructs a new {@code DMCHandler} {@code Object} + * @param player The player owning the cannon. + */ + public DMCHandler(final Player player) { + this.player = player; + } + + /** + * Rotates the cannon. + * @return {@code True} if the cannon should stop rotating. + */ + public boolean rotate() { + if (cannonballs < 1) { + player.getPacketDispatch().sendMessage("Your cannon has run out of ammo!"); + return false; + } + player.getPacketDispatch().sendSceneryAnimation(cannon, Animation.create(direction.getAnimationId())); + Location l = cannon.getLocation().transform(1, 1, 0); + playGlobalAudio(l, Sounds.MCANNON_TURN_2877); + direction = DMCRevolution.values()[(direction.ordinal() + 1) % DMCRevolution.values().length]; + for (NPC npc : RegionManager.getLocalNpcs(l, 10)) { + if (direction.isInSight(npc.getLocation().getX() - l.getX(), npc.getLocation().getY() - l.getY()) && npc.isAttackable(player, CombatStyle.RANGE, false) && CombatSwingHandler.isProjectileClipped(npc, l, false)) { + int speed = (int) (25 + (l.getDistance(npc.getLocation()) * 10)); + Projectile.create(l, npc.getLocation(), 53, 40, 36, 20, speed, 0, 128).send(); + playGlobalAudio(l, Sounds.MCANNON_FIRE_1667); + cannonballs--; + int hit = 0; + if (player.getSwingHandler(false).isAccurateImpact(player, npc, CombatStyle.RANGE, 1.2, 1.0)) { + hit = RandomFunction.getRandom(30); + } + player.getSkills().addExperience(Skills.RANGE, hit * 2); + npc.getImpactHandler().manualHit(player, hit, HitsplatType.NORMAL, (int) Math.ceil(l.getDistance(npc.getLocation()) * 0.3)); + npc.attack(player); + break; + } + } + return true; + } + + /** + * Starts rotating the cannon. + */ + public void startFiring() { + if (cannon == null || !cannon.isActive()) { + player.getPacketDispatch().sendMessage("You don't have a cannon active."); + return; + } + if (timer.isFiring()) { + timer.setFiring(false); + return; + } + if (cannonballs < 1) { + int amount = player.getInventory().getAmount(new Item(2)); + if (amount < 1) { + player.getPacketDispatch().sendMessage("Your cannon is out of cannonballs."); + return; + } + int toUse = 30 - cannonballs; + if(toUse > amount){ + toUse = amount; + } + if(toUse > 0){ + cannonballs = toUse; + player.getPacketDispatch().sendMessage("You load the cannon with " + toUse + " cannonballs."); + player.getInventory().remove(new Item(2, toUse)); + } else { + player.sendMessage("Your cannon is already fully loaded."); + } + } + timer.setFiring(true); + } + + /** + * Makes the cannon explode. + */ + public void explode(boolean decay) { + if (!cannon.isActive()) { + return; + } + player.sendMessage("Your cannon has " + (decay ? "decayed" : "been destroyed") + "!"); + for (Player p : RegionManager.getLocalPlayers(player)) { + p.getPacketDispatch().sendPositionedGraphic(189, 0, 1, cannon.getLocation()); + } + clear(false); + } + + /** + * Constructs the cannon. + */ + public static void construct(final Player player) { + final Location spawn = RegionManager.getSpawnLocation(player, new Scenery(6, player.getLocation())); + if (spawn == null) { + player.getPacketDispatch().sendMessage("There's not enough room for your cannon."); + return; + } + if (player.getZoneMonitor().isRestricted(ZoneRestriction.CANNON)) { + player.getPacketDispatch().sendMessage("You can't set up a cannon here."); + return; + } + final DMCHandler handler = new DMCHandler(player); + player.setAttribute("dmc", handler); + player.getPulseManager().clear(); + player.getWalkingQueue().reset(); + player.lock(9); + player.faceLocation(spawn.transform(Direction.NORTH_EAST)); + GameWorld.getPulser().submit(new Pulse(2, player) { + int count = 0; + Scenery object = null; + + @Override + public boolean pulse() { + player.animate(Animation.create(827)); + if (!player.getInventory().remove(new Item(6 + (count * 2)))) { + for (int i = count - 1; i >= 0; i--) { + player.getInventory().add(new Item(6 + (i * 2))); + } + if (object != null) { + SceneryBuilder.remove(object); + } + return true; + } + switch (count) { + case 0: + object = SceneryBuilder.add(new Scenery(7, spawn)); + player.getPacketDispatch().sendMessage("You place the cannon base on the ground."); + break; + case 1: + player.getPacketDispatch().sendMessage("You add the stand."); + break; + case 2: + player.getPacketDispatch().sendMessage("You add the barrels."); + break; + case 3: + player.getPacketDispatch().sendMessage("You add the furnace."); + SceneryBuilder.remove(object); + handler.configure(SceneryBuilder.add(object = object.transform(6))); + handler.timer = (CannonTimer) spawnTimer ("dmc:timer", handler); + registerTimer (player, handler.timer); + return true; + } + playGlobalAudio(player.getLocation(), Sounds.MCANNON_SETUP_2876); + if(count != 0) { + SceneryBuilder.remove(object); + SceneryBuilder.add(object = object.transform(object.getId() + 1)); + } + return ++count == 4; + } + }); + } + + /** + * Configures the cannon. + * @param cannon The cannon. + */ + public void configure(Scenery cannon) { + this.cannon = cannon; + } + + @Override + public void logout(@NotNull Player player) { + if(player.getAttribute("dmc") != null) + { + DMCHandler handler = player.getAttribute("dmc"); + handler.clear(false); + } + } + + /** + * Clears the cannon. + * @param pickup If the cannon is getting picked up. + */ + public void clear(boolean pickup) { + SceneryBuilder.remove(cannon); + player.removeAttribute("dmc"); + if (!pickup) { + player.getSavedData().getActivityData().setLostCannon(true); + return; + } + for (int i = 0; i < 4; i++) { + player.getInventory().add(new Item(12 - (i * 2))); + } + if (cannonballs > 0) { + player.getInventory().add(new Item(2, cannonballs)); + cannonballs = 0; + } + } + + /** + * Gets the player. + * @return the player + */ + public Player getPlayer() { + return player; + } + + /** + * Gets the cannon. + * @return the cannon + */ + public Scenery getCannon() { + return cannon; + } + + /** + * Sets the cannon. + * @param cannon the cannon to set. + */ + public void setCannon(Scenery cannon) { + this.cannon = cannon; + } + + /** + * Gets the cannonballs. + * @return the cannonballs + */ + public int getCannonballs() { + return cannonballs; + } + + /** + * Sets the bacannonballs. + * @param cannonballs the cannonballs to set. + */ + public void setCannonballs(int cannonballs) { + this.cannonballs = cannonballs; + } + +} diff --git a/Server/src/main/content/region/kandarin/quest/dwarfcannon/dmc/DMCManual.kt b/Server/src/main/content/region/kandarin/quest/dwarfcannon/dmc/DMCManual.kt new file mode 100644 index 0000000..fa22f2b --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/dwarfcannon/dmc/DMCManual.kt @@ -0,0 +1,95 @@ +package content.region.kandarin.quest.dwarfcannon.dmc + +import content.global.handlers.iface.BookInterface +import content.global.handlers.iface.BookLine +import content.global.handlers.iface.Page +import content.global.handlers.iface.PageSet +import core.api.setAttribute +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items + +@Initializable +class DMCManual : InteractionListener { + companion object { + private val TITLE = "Dwarf multicannon manual" + private val CONTENTS = arrayOf( + PageSet( + Page( + BookLine("Constructing the cannon", 55), + BookLine("", 56), + BookLine("To construct the cannon, firstly", 57), + BookLine("set down the base of the cannon", 58), + BookLine("firmly onto the ground, next add", 59), + BookLine("the Dwarf stand to the cannon", 60), + BookLine("base then add the Barrels. Lastly", 61), + BookLine("add the Furnace, which powers", 62), + BookLine("the cannon. You should now have", 63), + BookLine("a fully set up Multi Cannon to", 64), + BookLine("splat nasty creatures!", 65), + ), + Page( + BookLine("Making ammo", 66), + BookLine("", 67), + BookLine("The ammo for the cannon", 68), + BookLine("is made from steel bars.", 69), + BookLine("Firstly you must heat up a", 70), + BookLine("steel bar in a furnace.", 71), + BookLine("Now pour the molten steel", 72), + BookLine("into a cannon ammo mould.", 73), + BookLine("You should now have a ready", 74), + BookLine("to fire Multi cannon ball.", 75), + ) + ), + PageSet( + Page( + BookLine("Firing the Cannon", 55), + BookLine("", 56), + BookLine("The cannon will only fire", 57), + BookLine("when monsters are available", 58), + BookLine("to target. If you are carrying", 59), + BookLine("enough ammo the cannon will", 60), + BookLine("fire up to 30 rounds before it", 61), + BookLine("runs out and stops. The", 62), + BookLine("cannon will automatically target", 63), + BookLine("non friendly creatures.", 64), + ), + Page( + BookLine("Dwarf Cannon Warranty", 66), + BookLine("", 67), + BookLine("If your cannon is stolen or", 68), + BookLine("has been lost, after or during", 69), + BookLine("being being set up, the Dwarf", 70), + BookLine("engineer will replace the parts,", 71), + BookLine("however cannon parts that", 72), + BookLine("were given away or dropped", 73), + BookLine("will not be replaced for free.", 74), + BookLine("It is only possible to operate", 75), + BookLine("one cannon at a time.", 76), + ) + ), + PageSet( + Page( + BookLine("By order", 55), + BookLine("of the members of the noble", 56), + BookLine("Dwarven Black Guard.", 57), + ) + ), + ) + } + + private fun display(player: Player, pageNum: Int, buttonID: Int): Boolean { + BookInterface.pageSetup(player, BookInterface.FANCY_BOOK_3_49, TITLE, CONTENTS) + return true + } + + + override fun defineListeners() { + on(Items.INSTRUCTION_MANUAL_5, IntType.ITEM, "read") { player, _ -> + BookInterface.openBook(player, BookInterface.FANCY_BOOK_3_49, ::display) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/dwarfcannon/dmc/DMCRevolution.java b/Server/src/main/content/region/kandarin/quest/dwarfcannon/dmc/DMCRevolution.java new file mode 100644 index 0000000..ff9f8ce --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/dwarfcannon/dmc/DMCRevolution.java @@ -0,0 +1,88 @@ +package content.region.kandarin.quest.dwarfcannon.dmc; + +/** + * The DMC aiming directions. + * @author Emperor + */ +public enum DMCRevolution { + + NORTH(515) { + @Override + public boolean isInSight(int offsetX, int offsetY) { + return offsetY > 0 && Math.abs(offsetX) <= offsetY; + } + }, + NORTH_EAST(516) { + @Override + public boolean isInSight(int offsetX, int offsetY) { + return offsetY > 0 && offsetX > 0; + } + }, + EAST(517) { + @Override + public boolean isInSight(int offsetX, int offsetY) { + return offsetX > 0 && Math.abs(offsetY) <= offsetX; + } + }, + SOUTH_EAST(518) { + @Override + public boolean isInSight(int offsetX, int offsetY) { + return offsetY < 0 && offsetX > 0; + } + }, + SOUTH(519) { + @Override + public boolean isInSight(int offsetX, int offsetY) { + return offsetY < 0 && Math.abs(offsetX) <= -offsetY; + } + }, + SOUTH_WEST(520) { + @Override + public boolean isInSight(int offsetX, int offsetY) { + return offsetY < 0 && offsetX < 0; + } + }, + WEST(521) { + @Override + public boolean isInSight(int offsetX, int offsetY) { + return offsetX < 0 && Math.abs(offsetY) <= -offsetX; + } + }, + NORTH_WEST(514) { + @Override + public boolean isInSight(int offsetX, int offsetY) { + return offsetY > 0 && offsetX < 0; + } + }; + + /** + * The animation id. + */ + private final int animationId; + + /** + * Constructs a new {@Code DMCRevolution} {@Code Object} + * @param animationId The animation id. + */ + private DMCRevolution(int animationId) { + this.animationId = animationId; + } + + /** + * Gets the animationId. + * @return the animationId + */ + public int getAnimationId() { + return animationId; + } + + /** + * Checks if the offsets are in the line of sight for the current direction. + * @param offsetX The x-offset. + * @param offsetY The y-offset. + * @return {@code True} if so. + */ + public boolean isInSight(int offsetX, int offsetY) { + return false; + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/dwarfcannon/dmc/DMCZone.java b/Server/src/main/content/region/kandarin/quest/dwarfcannon/dmc/DMCZone.java new file mode 100644 index 0000000..7f1327e --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/dwarfcannon/dmc/DMCZone.java @@ -0,0 +1,55 @@ +package content.region.kandarin.quest.dwarfcannon.dmc; + +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneBuilder; +import core.game.world.map.zone.ZoneRestriction; +import core.plugin.Plugin; + +/** + * A restricted DMC zone. + * @author Vexia + */ +public class DMCZone extends MapZone implements Plugin { + + /** + * Constructs a new {@code DMCZone} {@code Object} + */ + public DMCZone() { + super("DMC Zone", true, ZoneRestriction.CANNON); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ZoneBuilder.configure(this); + return this; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public void configure() { + // dwarven mine + registerRegion(11929); + registerRegion(12185); + registerRegion(12184); + // WG: + register(new ZoneBorders(2838, 3536, 2875, 3555)); + // KQ: + registerRegion(13972); + // ice mountain + register(new ZoneBorders(2995, 3465, 3022, 3509)); + // Fremmy dungeon + register(new ZoneBorders(2690, 9934, 2831, 10050)); + // entrana + registerRegion(11316); + // black knight fortrss + registerRegion(12086); + // KBD + registerRegion(9033); + } + +} diff --git a/Server/src/main/content/region/kandarin/quest/dwarfcannon/dmc/DwarfMultiCannonPlugin.java b/Server/src/main/content/region/kandarin/quest/dwarfcannon/dmc/DwarfMultiCannonPlugin.java new file mode 100644 index 0000000..0fbe401 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/dwarfcannon/dmc/DwarfMultiCannonPlugin.java @@ -0,0 +1,126 @@ +package content.region.kandarin.quest.dwarfcannon.dmc; + +import core.cache.def.impl.ItemDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.OptionHandler; +import core.game.interaction.UseWithHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.info.Rights; +import core.game.node.item.Item; +import core.plugin.Plugin; +import core.plugin.Initializable; +import core.plugin.ClassScanner; +import content.data.Quests; + +/** + * Handles the Dwarf multi-cannon. + * @author Emperor + */ +@Initializable +public final class DwarfMultiCannonPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ItemDefinition.forId(6).getHandlers().put("option:set-up", this); + SceneryDefinition.forId(6).getHandlers().put("option:fire", this); + SceneryDefinition.forId(6).getHandlers().put("option:pick-up", this); + SceneryDefinition.forId(7).getHandlers().put("option:pick-up", this); + SceneryDefinition.forId(8).getHandlers().put("option:pick-up", this); + SceneryDefinition.forId(9).getHandlers().put("option:pick-up", this); + UseWithHandler.addHandler(6, UseWithHandler.OBJECT_TYPE, new UseWithHandler(2) { + @Override + public Plugin newInstance(Object arg) throws Throwable { + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + DMCHandler handler = event.getPlayer().getAttribute("dmc"); + if (handler != null && handler.getCannon() == event.getUsedWith()) { + int maxAmount = 30; + int amount = maxAmount - handler.getCannonballs(); + if(amount < 0 || amount > 30) { + handler.setCannonballs(0); + amount = maxAmount - handler.getCannonballs(); + } + if (amount > 0) { + if (amount > event.getUsedItem().getAmount()) { + amount = event.getUsedItem().getAmount(); + } + if (event.getPlayer().getInventory().remove(new Item(2, amount))) { + handler.setCannonballs(handler.getCannonballs() + amount); + event.getPlayer().getPacketDispatch().sendMessage("You load the cannon with " + amount + " cannonballs."); + return true; + } + } + event.getPlayer().getPacketDispatch().sendMessage("Your cannon is already full loaded."); + return true; + } + event.getPlayer().getPacketDispatch().sendMessage("This is not your cannon."); + return true; + } + + }); + ClassScanner.definePlugin(new DMCZone()); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + if (node instanceof Item) { + if (!player.getInventory().containItems(6, 8, 10, 12)) { + player.getPacketDispatch().sendMessage("You don't have all the cannon components!"); + return true; + } + if (!player.getQuestRepository().isComplete(Quests.DWARF_CANNON) && player.getDetails().getRights() != Rights.ADMINISTRATOR) { + player.getPacketDispatch().sendMessage("You have to complete the Dwarf Cannon to know how to use this."); + return true; + } + if (player.getAttribute("dmc") != null) { + player.getPacketDispatch().sendMessage("You cannot construct more than one cannon at a time."); + player.getPacketDispatch().sendMessage("If you have lost your cannon, go and see the dwarf cannon engineer."); + return true; + } + DMCHandler.construct(player); + return true; + } + switch (option) { + case "fire": + DMCHandler handler = player.getAttribute("dmc"); + if (handler != null && handler.getCannon() == node) { + handler.startFiring(); + return true; + } + player.getPacketDispatch().sendMessage("This is not your cannon."); + return true; + case "pick-up": + handler = player.getAttribute("dmc"); + if (handler != null && handler.getCannon() == node) { + int count = 4; + if (handler.getCannonballs() > 0 && !player.getInventory().contains(2, 1)) { + count++; + } + if (player.getInventory().freeSlots() < count) { + player.getPacketDispatch().sendMessage("You don't have enough space in your inventory."); + return true; + } + player.getPacketDispatch().sendMessage("You pick up the cannon."); + handler.clear(true); + return true; + } + /* + * if (player.getDetails().getRights() == Rights.ADMINISTRATOR) { + * ObjectBuilder.remove((GameObject) node); + * player.removeAttribute("dmc"); for (int i = 3; i >= 0; i--) { + * player.getInventory().add(new Item(6 + (i * 2))); } return true; + * } + */ + player.getPacketDispatch().sendMessage("This is not your cannon."); + return true; + } + return false; + } + +} diff --git a/Server/src/main/content/region/kandarin/quest/fishingcontest/BigDaveDialogue.java b/Server/src/main/content/region/kandarin/quest/fishingcontest/BigDaveDialogue.java new file mode 100644 index 0000000..d677eb5 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/fishingcontest/BigDaveDialogue.java @@ -0,0 +1,96 @@ +package content.region.kandarin.quest.fishingcontest; + +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.game.dialogue.DialoguePlugin; + + +/** + * Handles the SinisterStrangerDialogue dialogue. + * @author Woah + */ +@Initializable +public class BigDaveDialogue extends DialoguePlugin { + + public BigDaveDialogue(){ + //empty + } + + public BigDaveDialogue(Player player){super(player);} + + @Override + public DialoguePlugin newInstance(Player player) { + return new BigDaveDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + npc("Hey lad! Always nice to see a fresh face!"); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + + case 0: + interpreter.sendOptions("Choose an option:", "So you're the champ?", "Can I fish here instead of you?", "Do you have any tips for me?"); + stage++; + break; + + case 1: + switch (buttonId) { + case 1: + player("So you're the champ?"); + stage = 10; + break; + case 2: + player("Can I fish here instead of you?"); + stage = 20; + break; + case 3: + player("Do you have any tips for me?"); + stage = 30; + break; + } + break; + + + case 9: + end(); + break; + + case 10: + npc("That's right, lad!", "Ain't nobody better at fishing round here", "than me! That's for sure!"); + stage = 9; + break; + + case 20: + npc("Sorry lad! This is my lucky spot!"); + stage = 9; + break; + + case 30: + npc("Why would I help you? I wanna stay the best!", "I'm not givin' away my secrets like", "old Grandpa Jack does!"); + stage++; + break; + case 31: + player("Who's Grandpa Jack?"); + stage++; + break; + case 32: + npc("You really have no clue do you!", "He won this competition four years in a row!", "He lives in the house just outside the gate."); + stage = 9; + break; + + } + return true; + } + + @Override + public int[] getIds() { + return new int[]{228}; + } +} diff --git a/Server/src/main/content/region/kandarin/quest/fishingcontest/BonzoDialogue.java b/Server/src/main/content/region/kandarin/quest/fishingcontest/BonzoDialogue.java new file mode 100644 index 0000000..8ed55ae --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/fishingcontest/BonzoDialogue.java @@ -0,0 +1,147 @@ +package content.region.kandarin.quest.fishingcontest; + +import core.game.node.entity.player.link.quest.QuestRepository; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; +import core.game.activity.ActivityManager; +import core.game.dialogue.DialoguePlugin; +import content.data.Quests; + + +@Initializable +public final class BonzoDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code BonzoDialogue} {@code Object}. + */ + public BonzoDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code BonzoDialogue} {@code Object}. + * @param player + */ + public BonzoDialogue(Player player) { + super(player); + } + + @Override + public boolean open(Object... args) { + if(args.length < 2) { + if(player.getInventory().containsItem(FishingContest.FISHING_ROD)) { + npc("Roll up, roll up! Enter the great Hemenster", "Fishing Contest! Only 5gp entrance fee!"); + stage = 0; + } else { + npc("Sorry, lad, but you need a fishing","rod to compete."); + stage = 100; + } + } else { + npc("Ok folks, time's up! Let's see who caught","the biggest fish!"); + stage = 1000; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + options("I'll enter the competition please.", "No thanks, I'll just watch the fun."); + stage++; + break; + case 1: + switch (buttonId) { + case 1: + player("I'll enter the competition please."); + if (player.getAttribute("fishing_competition:garlic-stuffed", false)) { + stage = 50; + } else { + stage = 10; + } + break; + case 2: + player("No thanks, I'll just watch the fun."); + stage = 100; + break; + } + break; + case 10: + npc("Marvelous!"); + stage++; + break; + case 11: + if (player.getInventory().remove(new Item(995, 5))) { + stage = 20; + player.getDialogueInterpreter().sendDialogue("You pay Bonzo 5 coins"); + break; + } else { + player("I don't have the 5gp though..."); + stage++; + break; + } + case 12: + npc("No pay, no play."); + stage = 100; + break; + case 20: + npc("Ok, we've got all the fishermen! It's time", "to roll! Ok, nearly everyone is in their", "place already. You fish in the spot by the"); + stage++; + break; + case 21: + npc("willow tree, and the Sinister Stranger, you fish by the pipes."); + stage++; + break; + case 22: + player.getDialogueInterpreter().sendDialogue("Your fishing competition spot is by the willow tree."); + stage++; + break; + case 23: + ActivityManager.start(player, "Fishing Contest Cutscene", false); + end(); + break; + case 100: + end(); + break; + case 1000: + if (player.getInventory().containsItem(FishingContest.RAW_GIANT_CARP)) { + player("I have a fish."); + stage++; + } else { + npc("And our winner is... the stranger who", "was fishing over by the pipes!"); + stage = 100; + } + break; + case 1001: + player.getDialogueInterpreter().sendDialogue("You hand over your fish."); + stage++; + break; + case 1002: + npc("We have a new winner! The", "heroic-looking person who was fishing", "by the pipes has caught the biggest carp I've", "seen since Grandpa Jack used to compete!"); + stage++; + break; + case 1003: + player.getDialogueInterpreter().sendDialogue("You are given the Hemenester fishing trophy!"); + player.getInventory().add(FishingContest.FISHING_TROPHY); + player.getInventory().remove(FishingContest.RAW_GIANT_CARP); + player.getQuestRepository().setStage(QuestRepository.getQuests().get(Quests.FISHING_CONTEST),20); + stage = 100; + break; + } + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new BonzoDialogue(player); + } + + @Override + public int[] getIds() { + return new int[] { 225 }; + } +} diff --git a/Server/src/main/content/region/kandarin/quest/fishingcontest/DwarfDialogue.java b/Server/src/main/content/region/kandarin/quest/fishingcontest/DwarfDialogue.java new file mode 100644 index 0000000..6e56d58 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/fishingcontest/DwarfDialogue.java @@ -0,0 +1,247 @@ +package content.region.kandarin.quest.fishingcontest; + +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItemManager; +import core.plugin.Initializable; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import content.data.Quests; + +@Initializable +public class DwarfDialogue extends DialoguePlugin { + public DwarfDialogue(){ + //empty + } + public DwarfDialogue(Player player){super(player);} + + @Override + public DialoguePlugin newInstance(Player player) { + return new DwarfDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + int questStage = player.getQuestRepository().getStage(Quests.FISHING_CONTEST); + if(player.getQuestRepository().getStage(Quests.FISHING_CONTEST) == 100){ + npc(FacialExpression.OLD_NORMAL,"Welcome, oh great fishing champion!","Feel free to pop by and use","our tunnel any time!"); + stage = 2500; + return true; + } + if((questStage < 20 && questStage > 0) && !player.getInventory().containsItem(FishingContest.FISHING_PASS)){ + player("I lost my fishing pass..."); + stage = 1000; + return true; + } + if(player.getInventory().containsItem(FishingContest.FISHING_TROPHY) && player.getAttribute("fishing_contest:won",false)){ + npc(FacialExpression.OLD_NORMAL,"Have you won yet?"); + stage = 2000; + return true; + } + if(player.getQuestRepository().getStage(Quests.FISHING_CONTEST) >= 10 && !player.getAttribute("fishing_contest:won",false)){ + npc(FacialExpression.OLD_NORMAL,"Have you won yet?"); + stage = 1500; + return true; + } + npc(FacialExpression.OLD_NORMAL,"Hmph! What do you want?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch(stage){ + case 0: + player("I was wondering what was down that tunnel?"); + stage++; + break; + case 1: + npc(FacialExpression.OLD_NORMAL,"You can't go down there!"); + stage++; + break; + case 2: + options("I didn't want to anyway.","Why not?"); + stage++; + break; + case 3: + switch(buttonId){ + case 1: + player("I didn't want to anyway."); + stage = 10; + break; + case 2: + player("Why not?"); + stage = 21; + break; + } + break; + case 10: + npc(FacialExpression.OLD_NORMAL,"Good. Because you can't."); + stage++; + break; + case 11: + player("Because I don't want to."); + stage++; + break; + case 12: + npc(FacialExpression.OLD_NORMAL,"Because you can't. So that's fine."); + stage++; + break; + case 13: + player("Yes it is."); + stage++; + break; + case 14: + npc(FacialExpression.OLD_NORMAL,"Yes. Fine."); + stage++; + break; + case 15: + player("Absolutely."); + stage++; + break; + case 16: + npc(FacialExpression.OLD_NORMAL,"Well then."); + stage = 100; + break; + case 20: + player("Why not?"); + stage++; + break; + case 21: + npc(FacialExpression.OLD_NORMAL,"This is the home of the Mountain Dwarves.","How would you like it if I","wanted to take a shortcut through your home?"); + stage++; + break; + case 22: + options("Ooh... is this a short cut to somewhere?","Oh, sorry, I hadn't realized it was private.","If you were my friend I wouldn't mind it."); + stage++; + break; + case 23: + switch(buttonId) { + case 1: + player("Ooh... is this a short cut to somewhere?"); + stage = 30; + break; + case 2: + player("Oh, sorry, I hadn't realized it was private."); + stage = 40; + break; + case 3: + player("If you were my friend I wouldn't mind it."); + stage = 50; + break; + } + break; + case 30: + npc(FacialExpression.OLD_NORMAL,"Well, it is a lot easier to go this way", "to get past White Wolf Mountain than through", "those wolf filled passes."); + stage = 22; + break; + case 40: + npc(FacialExpression.OLD_NORMAL,"Well, it is."); + stage = 22; + break; + case 50: + npc(FacialExpression.OLD_NORMAL,"Yes, but I don't even know you."); + stage++; + break; + case 51: + player("Well, let's be friends!"); + stage++; + break; + case 52: + npc(FacialExpression.OLD_NORMAL,"I don't make friends easily.","People need to earn my trust first."); + stage++; + break; + case 53: + player("And how am I to do that?"); + stage++; + break; + case 54: + npc(FacialExpression.OLD_NORMAL,"My, we are the persistent one aren't we?","Well, there's a certain gold artefact we're after.","We dwarves are big fans of gold! This artefact","is the first prize at the Hemenster fishing competition."); + stage++; + break; + case 55: + npc(FacialExpression.OLD_NORMAL,"Fortunately we have acquired a pass to enter","that competition... Unfortunately Dwarves don't","make good fisherman. Okay, I entrust you with our","competition pass."); + stage++; + break; + case 56: + npc(FacialExpression.OLD_NORMAL,"Don't forget to take some gold","with you for the entrance fee."); + stage++; + break; + case 57: + player.getDialogueInterpreter().sendDialogue("You got the Fishing Contest Pass!"); + if(!player.getInventory().add(FishingContest.FISHING_PASS)){ + GroundItemManager.create(FishingContest.FISHING_PASS,player.getLocation()); + } + player.getQuestRepository().getQuest(Quests.FISHING_CONTEST).start(player); + stage++; + break; + case 58: + npc(FacialExpression.OLD_NORMAL,"Go to Hemenster and do us proud!"); + stage = 100; + break; + case 100: + end(); + break; + case 1000: + npc(FacialExpression.OLD_NORMAL,"Hmm. It's a good job they sent us spares.","There you go. Try not to lose that one."); + player.getInventory().add(FishingContest.FISHING_PASS); + stage++; + break; + case 1001: + player("No, it takes preparation to win","fishing competitions."); + stage++; + break; + case 1002: + npc(FacialExpression.OLD_NORMAL,"Maybe that's where we are going wrong","when we try fishing?"); + stage++; + break; + case 1003: + player("Probably."); + stage++; + break; + case 1004: + npc(FacialExpression.OLD_NORMAL,"Maybe we should talk to that old Jack","fella near the competition, everyone","seems to be ranting about him."); + stage = 100; + break; + case 2000: + player("Yes, I have!"); + stage++; + break; + case 2001: + npc(FacialExpression.OLD_NORMAL,"Well done! That's brilliant, do you have","the trophy?"); + stage++; + break; + case 2002: + player("Yep, I have it right here!"); + stage++; + break; + case 2003: + npc(FacialExpression.OLD_NORMAL,"Oh, it's even more shiny and gold than","I thought possible..."); + stage++; + break; + case 2004: + player.getQuestRepository().getQuest(Quests.FISHING_CONTEST).finish(player); + player.getInventory().remove(FishingContest.FISHING_TROPHY); + end(); + break; + case 1500: + player("No, I haven't."); + stage++; + break; + case 1501: + end(); + break; + case 2500: + player("Thanks, I think I will stop by."); + stage = 100; + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] {232,3679}; + } +} diff --git a/Server/src/main/content/region/kandarin/quest/fishingcontest/FenceInteraction.java b/Server/src/main/content/region/kandarin/quest/fishingcontest/FenceInteraction.java new file mode 100644 index 0000000..bc6f158 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/fishingcontest/FenceInteraction.java @@ -0,0 +1,81 @@ +package content.region.kandarin.quest.fishingcontest; + +import core.game.interaction.MovementPulse; +import core.game.node.Node; +import core.game.node.entity.impl.PulseType; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.game.interaction.PluginInteraction; +import core.game.interaction.PluginInteractionManager; + +@Initializable +public class FenceInteraction extends PluginInteraction { + @Override + public Plugin newInstance(Object arg) throws Throwable { + setIds(new int[]{51}); + PluginInteractionManager.register(this, PluginInteractionManager.InteractionType.OBJECT); + return this; + } + + @Override + public boolean handle(Player player, Node node) { + player.getPulseManager().run(new MovementPulse(player, node.asScenery().getLocation().transform(player.getLocation().getX() == node.getLocation().getX() ? 0 : -1, 0, 0)) { + @Override + public boolean pulse() { + GameWorld.getPulser().submit(new SqueezePulse(player)); + return true; + } + }, PulseType.STANDARD); + return true; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + public class SqueezePulse extends Pulse { + Player player; + Location start,end; + Animation walk; + public SqueezePulse(Player p){ + this.player = p; + if(player.getLocation().equals(Location.create(2661, 3500, 0))){ + start = Location.create(2661, 3500, 0); + end = Location.create(2662, 3500, 0); + } else { + start = Location.create(2662, 3500, 0); + end = Location.create(2661, 3500, 0); + } + walk = new Animation(2240); + } + int counter = 0; + + @Override + public boolean pulse() { + switch(counter++){ + case 0: + player.getAnimator().reset(); + player.lock(); + player.faceLocation(end); + break; + case 1: + player.getAnimator().animate(new Animation(2594)); + break; + case 2: + player.getProperties().setTeleportLocation(end); + player.getAnimator().animate(new Animation(2595)); + break; + case 4: + player.unlock(); + return true; + } + return false; + } + } +} diff --git a/Server/src/main/content/region/kandarin/quest/fishingcontest/FishingContest.java b/Server/src/main/content/region/kandarin/quest/fishingcontest/FishingContest.java new file mode 100644 index 0000000..9e01f55 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/fishingcontest/FishingContest.java @@ -0,0 +1,88 @@ +package content.region.kandarin.quest.fishingcontest; + +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import content.data.Quests; + +@Initializable +public class FishingContest extends Quest { + public FishingContest(){super(Quests.FISHING_CONTEST,62,61,1,11,0,1,5);} + public static final Item FISHING_ROD = new Item(307); + public static final Item FISHING_PASS = new Item(27); + public static final Item RED_VINE_WORM = new Item(25); + public static final Item RAW_GIANT_CARP = new Item(338); + public static final Item GIANT_CARP = new Item(337); + public static final Item FISHING_TROPHY = new Item(26); + public static final Item GARLIC = new Item(1550); + public static final Item SPADE = new Item(952); + + // Winner is stranger in black if you did not do the garlic. + // https://www.youtube.com/watch?v=6zL7M8mCL30 + + @Override + public void drawJournal(Player player, int stage) { + int line = 12; + super.drawJournal(player, stage); + + if (stage == 0) { + line(player, "I can start this quest by speaking to the !!Dwarves?? at the", line++); + line(player, "tunnel entrances on either side of !!White Wolf Mountain??.", line++); + line(player,"!!I must have level 10 fishing.??", line++, player.getSkills().getLevel(Skills.FISHING) >= 10); + } else if ( stage < 100 ) { + line(player, "The Dwarves will let me use the tunnel through White Wolf", line++, true); + line(player, "Mountain if I can will the Hemenster Fishing Competition.", line++, true); + + if (stage >= 20) { + line(player,"I easily won the contest by catching some Giant Carp.", line++, false); + } else if (stage >= 10) { + // https://youtu.be/z4MfANC2KqI + line(player, "They gave me a !!Fishing Contest Pass?? to enter the contest.", line++, false); + line(player, "I need to bring them back the !!Hemenster Fishing Trophy??.", line++, false); + } + + if (stage >= 100) { + + } else if (stage >= 20) { + // https://youtu.be/rysJl-DRihE + line(player, "I should take back the !!Trophy?? back to the !!Dwarf?? at the side of", line++, false); + line(player, "!!White Wolf Mountain?? and claim my !!reward??.", line++, false); + } + + } else { + // https://youtu.be/u5Osw_jas4A + line(player, "The Dwarves' wanted me to earn their friendship by winning", line++, true); + line(player, "the Hemenster Fishing Competition.", line++, true); + line(player, "I scared away a vampyre with some garlic and easily won the", line++, true); + line(player, "contest by catching some Giant Carp.", line++, true); + line++; + line(player,"%%QUEST COMPLETE!&&", line++); + line++; + line(player, "As a reward for getting the Fishing Competition Trophy the", line++, false); + line(player, "Dwarves will let me use their tunnel to travel quickly and", line++, false); + line(player, "safely under White Wolf Mountain anytime I wish.", line++, false); + } + } + + @Override + public void finish(Player player) { + int ln = 10; + super.finish(player); + player.getPacketDispatch().sendItemZoomOnInterface(FISHING_TROPHY.getId(), 230, 277, 5); + // https://youtu.be/8dK362LbYdE + drawReward(player,"1 Quest Point",ln++); + drawReward(player,"2437 Fishing XP",ln++); + drawReward(player,"Access to Tunnel shortcut",ln); + player.removeAttribute("fishing_contest:garlic"); + player.removeAttribute("fishing_contest:won"); + player.removeAttribute("fishing_contest:pass-shown"); + player.getSkills().addExperience(Skills.FISHING,2437); + } + + @Override + public Quest newInstance(Object object) { + return this; + } +} diff --git a/Server/src/main/content/region/kandarin/quest/fishingcontest/FishingContestCutscene.java b/Server/src/main/content/region/kandarin/quest/fishingcontest/FishingContestCutscene.java new file mode 100644 index 0000000..b5ea211 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/fishingcontest/FishingContestCutscene.java @@ -0,0 +1,190 @@ +package content.region.kandarin.quest.fishingcontest; + +import core.game.interaction.MovementPulse; +import core.game.node.entity.Entity; +import core.game.node.entity.impl.PulseType; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.build.DynamicRegion; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.game.activity.ActivityPlugin; +import core.game.activity.CutscenePlugin; + +@Initializable +public class FishingContestCutscene extends CutscenePlugin { + + public final int S_STRANGER = 3678; + public final int BIG_DAVE = 228; + + public FishingContestCutscene(){super("Fishing Contest Cutscene");} + + public FishingContestCutscene(Player player){ + super("Fishing Contest Cutscene"); + this.player = player; + } + + @Override + public ActivityPlugin newInstance(Player p) throws Throwable { + return new FishingContestCutscene(p); + } + + @Override + public boolean start(Player player, boolean login, Object... args) { + NPC Bonzo = NPC.create(225,base.transform(17,45,0));//base.transform(145,45,0)); + NPC Stranger = NPC.create(S_STRANGER,base.transform(14,51,0)); + NPC Dave = NPC.create(BIG_DAVE,base.transform(9,34,0)); + Bonzo.init(); + Stranger.init(); + Dave.init(); + Bonzo.faceLocation(base.transform(16,45,0)); + Stranger.faceLocation(base.transform(13,51,0)); + Dave.faceLocation(base.transform(8,34,0)); + this.npcs.add(Bonzo); + this.npcs.add(Dave); + this.npcs.add(Stranger); + player.faceLocation(base.transform(6,43,0)); + return super.start(player, login, args); + } + + @Override + public void register() { + register(new ZoneBorders(2623, 3426,2644, 3448)); + super.register(); + } + + @Override + public void open() { + player.setAttribute("cutscene:original-loc", Location.create(2639, 3437, 0)); + player.setAttribute("real-end", Location.create(2639, 3437, 0)); + //PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraContext.CameraType.POSITION, player.getLocation().getX(), player.getLocation().getY(), 450, 1, 100)); + //PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraContext.CameraType.ROTATION, player.getLocation().getX() - 15, player.getLocation().getY() + -55, 450, 1, 100)); + if(player.getAttribute("fishing_contest:garlic",false)){ + NPC stranger = npcs.get(2); + stranger.sendChat("What is this smell??"); + GameWorld.getPulser().submit(new SwitchPulse()); + } else { + GameWorld.getPulser().submit(new FishingPulse()); + } + player.lock(); + } + + private class FishingPulse extends Pulse{ + int counter = 0; + @Override + public boolean pulse() { + switch(counter++){ + case 6: + for(NPC n : npcs){ + n.faceLocation(n.getLocation().transform(Direction.WEST,1)); + n.getAnimator().animate(new Animation(622)); + } + player.faceLocation(player.getLocation().transform(Direction.WEST,1)); + player.getAnimator().animate(new Animation(622)); + break; + case 12: + if(player.getAttribute("fishing_contest:garlic",false) && player.getInventory().containsItem(FishingContest.RED_VINE_WORM)){ + player.getInventory().remove(FishingContest.RED_VINE_WORM); + player.getInventory().add(FishingContest.RAW_GIANT_CARP); + player.setAttribute("/save:fishing_contest:won",true); + player.getWalkingQueue().setRunDisabled(false); + } + GameWorld.getPulser().submit(getEndPulse()); + break; + case 15: + GameWorld.getPulser().submit(new Pulse(){ + int counter = 0; + @Override + public boolean pulse() { + switch(counter++){ + case 2: + player.faceLocation(Location.create(2642, 3437, 0)); + break; + case 4: + player.getDialogueInterpreter().open(225,true,true); + return true; + } + return false; + } + }); + return true; + } + return false; + } + } + + @Override + public boolean leave(Entity e, boolean logout) { + return true;//super.leave(e, logout); + } + + @Override + public void stop(boolean fade) { + super.stop(fade); + } + + public class SwitchPulse extends Pulse{ + NPC stranger = npcs.get(2); + int counter = 0; + @Override + public boolean pulse() { + switch (counter++) { + case 1: + stranger.getPulseManager().run(new MovementPulse(stranger, base.getLocation().transform(8, 42, 0)) { + @Override + public boolean pulse() { + player.getWalkingQueue().setRunDisabled(true); + return true; + } + }, PulseType.STANDARD); + break; + case 12: + stranger.sendChat("You're switching with me. Go."); + break; + case 16: + player.getPulseManager().run(new MovementPulse(player, base.getLocation().transform(14, 51, 0)) { + @Override + public boolean pulse() { + player.getDialogueInterpreter().sendDialogue("Your spot is now by the pipes."); + return true; + } + }, PulseType.STANDARD); + break; + case 22: + stranger.getPulseManager().run(new MovementPulse(stranger, base.getLocation().transform(7, 43, 0)) { + @Override + public boolean pulse() { + return true; + } + },PulseType.STANDARD); + GameWorld.getPulser().submit(new FishingPulse()); + return true; + } + return false; + } + } + + + + @Override + public Location getStartLocation() { + return base.transform(7,43,0); + } + + @Override + public Location getSpawnLocation() { + return null; + } + + @Override + public void configure() { + region = DynamicRegion.create(10549); + setRegionBase(); + registerRegion(region.getId()); + } +} diff --git a/Server/src/main/content/region/kandarin/quest/fishingcontest/FishingSpotInteraction.java b/Server/src/main/content/region/kandarin/quest/fishingcontest/FishingSpotInteraction.java new file mode 100644 index 0000000..c9449af --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/fishingcontest/FishingSpotInteraction.java @@ -0,0 +1,73 @@ +package content.region.kandarin.quest.fishingcontest; + +import core.game.interaction.MovementPulse; +import core.game.interaction.Option; +import core.game.node.entity.impl.PulseType; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.game.dialogue.FacialExpression; +import core.game.interaction.PluginInteraction; +import core.game.interaction.PluginInteractionManager; + +@Initializable +public class FishingSpotInteraction extends PluginInteraction { + @Override + public boolean handle(Player player, NPC npc, Option option) { + Location npc_loc = npc.getLocation(); + if(!player.getAttribute("fishing_contest:fee-paid",false)) { + if(npc_loc.equals(new Location(2637, 3444, 0))) { + player.getPulseManager().run(new MovementPulse(player, npc.getLocation().transform(1, 0, 0)) { + @Override + public boolean pulse() { + player.getDialogueInterpreter().sendDialogues(3677, FacialExpression.NEUTRAL, "I think you will find that is","my spot."); + return true; + } + }, PulseType.STANDARD); + return true; + } else if (npc_loc.equals(2630, 3435, 0)){ + player.getPulseManager().run(new MovementPulse(player, npc.getLocation().transform(1, 0, 0)) { + @Override + public boolean pulse() { + player.getDialogueInterpreter().sendDialogues(225, FacialExpression.NEUTRAL, "Hey, you need to pay to enter the", "competition first! Only 5gp entrance fee!"); + return true; + } + }, PulseType.STANDARD); + return true; + } else if (npc_loc.equals(Location.create(2632, 3427, 0))){ + player.getPulseManager().run(new MovementPulse(player, npc.getLocation().transform(1, 0, 0)) { + @Override + public boolean pulse() { + player.getDialogueInterpreter().sendDialogues(228, FacialExpression.NEUTRAL, "I think you will find that is my spot."); + return true; + } + },PulseType.STANDARD); + return true; + } else if(npc_loc.equals(Location.create(2627,3415,0))) { + player.getPulseManager().run(new MovementPulse(player, npc.getLocation().transform(1, 0, 0)) { + @Override + public boolean pulse() { + player.getDialogueInterpreter().sendDialogues(228, FacialExpression.NEUTRAL, "I think you will find that is my spot."); + return true; + } + }, PulseType.STANDARD); + return true; + } + } + return false; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + setIds(new int[]{309}); + PluginInteractionManager.register(this, PluginInteractionManager.InteractionType.NPC); + return this; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } +} diff --git a/Server/src/main/content/region/kandarin/quest/fishingcontest/ForesterDialogue.java b/Server/src/main/content/region/kandarin/quest/fishingcontest/ForesterDialogue.java new file mode 100644 index 0000000..0815774 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/fishingcontest/ForesterDialogue.java @@ -0,0 +1,43 @@ +package content.region.kandarin.quest.fishingcontest; + +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.game.dialogue.DialoguePlugin; + + +/** + * Handles the SinisterStrangerDialogue dialogue. + * @author Woah + */ +@Initializable +public class ForesterDialogue extends DialoguePlugin { + + public ForesterDialogue() { + //empty + } + + public ForesterDialogue(Player player){super(player);} + + @Override + public DialoguePlugin newInstance(Player player) { + return new ForesterDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + npc("Yeah? What do you want?"); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + return true; + } + + @Override + public int[] getIds() { + return new int[] {231}; + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/fishingcontest/GarlicPipeInteraction.java b/Server/src/main/content/region/kandarin/quest/fishingcontest/GarlicPipeInteraction.java new file mode 100644 index 0000000..5771f2d --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/fishingcontest/GarlicPipeInteraction.java @@ -0,0 +1,73 @@ +package content.region.kandarin.quest.fishingcontest; + +import core.game.interaction.MovementPulse; +import core.game.interaction.NodeUsageEvent; +import core.game.node.Node; +import core.game.node.entity.impl.PulseType; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.plugin.Plugin; +import org.rs09.consts.Items; +import core.game.interaction.PluginInteraction; +import core.game.interaction.PluginInteractionManager; +import content.data.Quests; + +@Initializable +public class GarlicPipeInteraction extends PluginInteraction { + @Override + public Plugin newInstance(Object arg) throws Throwable { + setIds(new int[]{FishingContest.GARLIC.getId(),41}); + PluginInteractionManager.register(this, PluginInteractionManager.InteractionType.USEWITH); + PluginInteractionManager.register(this, PluginInteractionManager.InteractionType.OBJECT); + return this; + } + + @Override + public boolean handle(Player player, NodeUsageEvent event) { + + if(event.getUsed() instanceof Item && event.getUsedWith() instanceof Scenery){ + Scenery usedWith = event.getUsedWith().asScenery(); + Item used = event.getUsedItem(); + + if(used.getId() == Items.GARLIC_1550 && usedWith.getId() == 41 && usedWith.getLocation().equals(Location.create(2638, 3446, 0)) && player.getQuestRepository().getStage(Quests.FISHING_CONTEST) > 0){ + player.getPulseManager().run(new MovementPulse(player, usedWith.getLocation().transform(0, -1, 0)) { + @Override + public boolean pulse() { + player.getDialogueInterpreter().sendDialogue("You stuff the garlic into the pipe."); + player.getInventory().remove(new Item(Items.GARLIC_1550)); + player.setAttribute("fishing_contest:garlic",true); + return true; + } + }, PulseType.STANDARD); + return true; + } + } + return false; + } + + @Override + public boolean handle(Player player, Node node) { + if(node instanceof Scenery){ + Scenery object = node.asScenery(); + if(object.getId() == 41 && object.getLocation().equals(Location.create(2638, 3446, 0)) && player.getAttribute("fishing_contest:garlic",false)){ + player.getPulseManager().run(new MovementPulse(player, object.getLocation().transform(0, -1, 0)) { + @Override + public boolean pulse() { + player.getDialogueInterpreter().sendDialogue("This is the pipe I stuffed that garlic into."); + return true; + } + }, PulseType.STANDARD); + return true; + } + } + return false; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } +} diff --git a/Server/src/main/content/region/kandarin/quest/fishingcontest/GateInteraction.java b/Server/src/main/content/region/kandarin/quest/fishingcontest/GateInteraction.java new file mode 100644 index 0000000..7a79ca9 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/fishingcontest/GateInteraction.java @@ -0,0 +1,77 @@ +package content.region.kandarin.quest.fishingcontest; + +import core.game.interaction.MovementPulse; +import core.game.node.Node; +import core.game.node.entity.impl.PulseType; +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.game.interaction.PluginInteraction; +import core.game.interaction.PluginInteractionManager; +import content.data.Quests; + +@Initializable +public class GateInteraction extends PluginInteraction { + + @Override + public boolean handle(Player player, Node node) { + switch(node.getId()){ + case 47: + case 48: + return handleGate(player,node); + case 52: + case 53: + return handleGruborGate(player,node); + } + return false; + } + + public boolean handleGate(Player player, Node node){ + if(!player.getAttribute("fishing_contest:pass-shown",false) || player.getQuestRepository().getStage(Quests.FISHING_CONTEST) < 10) { + player.getPulseManager().run(new MovementPulse(player, node.asScenery().getLocation().transform(1, 0, 0)) { + @Override + public boolean pulse() { + if(player.getQuestRepository().getStage(Quests.FISHING_CONTEST) >= 10){ + player.sendMessage("You should give your pass to Morris."); + } else { + player.sendMessage("You need a fishing pass to fish here."); + } + return true; + } + }, PulseType.STANDARD); + return true; + } else { + if(!player.getInventory().containsItem(FishingContest.FISHING_ROD)){ + player.getDialogueInterpreter().sendDialogue("I should probably get a rod from","Grandpa Jack before starting."); + } + } + return false; + } + + public boolean handleGruborGate(Player player, Node node){ + if(node.getLocation().withinDistance(Location.create(2650, 3469, 0),4)) { + player.getPulseManager().run(new MovementPulse(player, node.asScenery().getLocation().transform(0,-1 , 0)) { + @Override + public boolean pulse() { + player.getDialogueInterpreter().sendDialogue("This gate is locked."); + return true; + } + }, PulseType.STANDARD); + return true; + } + return false; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + setIds(new int[]{47,48,52,53}); + PluginInteractionManager.register(this, PluginInteractionManager.InteractionType.OBJECT); + return this; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } +} diff --git a/Server/src/main/content/region/kandarin/quest/fishingcontest/JoshuaDialogue.java b/Server/src/main/content/region/kandarin/quest/fishingcontest/JoshuaDialogue.java new file mode 100644 index 0000000..40a26dd --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/fishingcontest/JoshuaDialogue.java @@ -0,0 +1,96 @@ +package content.region.kandarin.quest.fishingcontest; + +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.game.dialogue.DialoguePlugin; + + +/** + * Handles the SinisterStrangerDialogue dialogue. + * @author Woah + */ +@Initializable +public class JoshuaDialogue extends DialoguePlugin { + + public JoshuaDialogue() { + //empty + } + + public JoshuaDialogue(Player player){super(player);} + + @Override + public DialoguePlugin newInstance(Player player) { + return new JoshuaDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + npc("Yeah? What do you want?"); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + + case 0: + interpreter.sendOptions("Choose an option:", "Um... nothing really...", "Can I fish here instead of you?", "Do you have any tips for me?"); + stage++; + break; + + case 1: + switch (buttonId) { + case 1: + player("Um... nothing really..."); + stage = 10; + break; + case 2: + player("Can I fish here instead of you?"); + stage = 20; + break; + case 3: + player("Do you have any tips for me?"); + stage = 30; + break; + } + break; + + + case 9: + end(); + break; + + case 10: + npc("Quit bugging me then, dude!", "I got me some fish to catch!"); + stage = 9; + break; + + case 20: + npc("nuh uh dude. Less talk, more fishing!"); + stage = 9; + break; + + case 30: + npc("Dude! Why should I help you?", "You like, might beat me!", "I'm not giving away my secrets like that", "dude Grandpa Jack does!"); + stage++; + break; + case 31: + player("Who's Grandpa Jack?"); + stage++; + break; + case 32: + npc("Who's Grandpa Jack you say!", "He won this competition four years in a row!", "He lives in the house just outside the gate."); + stage = 9; + break; + + } + return true; + } + + @Override + public int[] getIds() { + return new int[] {229}; + } +} diff --git a/Server/src/main/content/region/kandarin/quest/fishingcontest/MorrisDialogue.java b/Server/src/main/content/region/kandarin/quest/fishingcontest/MorrisDialogue.java new file mode 100644 index 0000000..1c145b1 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/fishingcontest/MorrisDialogue.java @@ -0,0 +1,79 @@ +package content.region.kandarin.quest.fishingcontest; + +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; + +@Initializable +public final class MorrisDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code MorrisDialogue} {@code Object}. + */ + public MorrisDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code MorrisDialogue} {@code Object}. + * @param player the player. + */ + public MorrisDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new MorrisDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What are you sitting around here for?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I'm making sure only those with a competition pass enter", "the fishing contest."); + stage++; + break; + case 1: + if(player.getInventory().containsItem(FishingContest.FISHING_PASS)){ + player("I have one here..."); + stage++; + break; + } else { + end(); + break; + } + case 2: + player.getDialogueInterpreter().sendDialogue("You show Morris your pass."); + stage ++; + break; + case 3: + npc("Move on through. Talk to Bonzo","to enter the competition."); + player.setAttribute("/save:fishing_contest:pass-shown",true); + player.getInventory().remove(FishingContest.FISHING_PASS); + stage = 100; + break; + case 100: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 227 }; + } +} diff --git a/Server/src/main/content/region/kandarin/quest/fishingcontest/SinisterStrangerDialogue.java b/Server/src/main/content/region/kandarin/quest/fishingcontest/SinisterStrangerDialogue.java new file mode 100644 index 0000000..bd3e90e --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/fishingcontest/SinisterStrangerDialogue.java @@ -0,0 +1,194 @@ +package content.region.kandarin.quest.fishingcontest; + +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; +import core.game.dialogue.DialoguePlugin; + +/** + * Handles the SinisterStrangerDialogue dialogue. + * @author Woah + */ + +@Initializable +public class SinisterStrangerDialogue extends DialoguePlugin { + + public SinisterStrangerDialogue() { + + } + + public SinisterStrangerDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { return new SinisterStrangerDialogue(player); } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + npc("..."); + return true; + } + + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Choose an option:", "...?", "Who are you?", "So... you like fishing?"); + stage++; + break; + + case 1: + switch (buttonId) { + case 1: + player("...?"); + stage = 10; + break; + case 2: + player("Who are you?"); + stage = 20; + break; + case 3: + player("So... you like fishing?"); + stage = 30; + break; + } break; + + case 2: + interpreter.sendOptions("Choose an option:", "You're a vampire aren't you?", "Is it nice there?", "So you like fishing?"); + stage++; + break; + + + case 3: + switch (buttonId) { + case 1: + player("You're a vampire aren't you?"); + stage = 21; + break; + case 2: + player("Is it nice there?"); + stage = 50; + break; + case 3: + player("So you like fishing?"); + stage = 30; + break; + } break; + + + case 4: + interpreter.sendOptions("Choose an option:", "You're a vampire aren't you?", "So you like fishing?", "Well, good luck with the fishing."); + stage++; + break; + + case 5: + switch (buttonId) { + case 1: + player("You're a vampire aren't you?"); + stage = 21; + break; + case 2: + player("So you like fishing?"); + stage = 30; + break; + case 3: + player("Well, good luck with the fishing."); + stage = 70; + break; + } break; + + case 6: + interpreter.sendOptions("Choose an option:", "You're a vampire aren't you?", "If you get thirsty you should drink something.", "Well, good luck with the fishing."); + stage++; + break; + + case 7: + switch (buttonId) { + case 1: + player("You're a vampire aren't you?"); + stage = 21; + break; + case 2: + player("If you get thirsty you should drink something."); + stage = 40; + break; + case 3: + player("Well, good luck with the fishing."); + stage = 70; + break; + } break; + + + case 9: + end(); + break; + + case 10: + npc("..."); + stage++; + break; + case 11: + player("......?"); + stage++; + break; + case 12: + npc("......"); + stage = 9; + break; + + case 20: + npc("My name is Vlad.", "I come from far avay,", "vere the sun iz not so bright."); + stage = 2; + break; + + case 21: + npc("Just because I can't stand ze smell ov garlic", "and I don't like bright sunlight doesn't", "necessarily mean I'm ein vampire!"); + stage = 9; + break; + + + case 30: + npc("My doctor told me to take up ein velaxing hobby.", "Vhen I am stressed I tend to get ein little"); + stage++; + break; + case 31: + npc("... thirsty."); + stage = 6; + break; + + case 40: + npc("I tsink I may do zat soon..."); + stage = 9; + break; + + + + case 50: + npc("It is vonderful!", "Zev omen are beautiful und ze nights are long!"); + stage = 4; + break; + + case 70: + npc("Luck haz notsing to do vith it.", "It is all in ze technique."); + stage = 9; + break; + + + + + + } + return true; + } + + + + + @Override + public int[] getIds() { + return new int[] { 3677 }; + } +} diff --git a/Server/src/main/content/region/kandarin/quest/fishingcontest/StairInteraction.java b/Server/src/main/content/region/kandarin/quest/fishingcontest/StairInteraction.java new file mode 100644 index 0000000..97daa72 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/fishingcontest/StairInteraction.java @@ -0,0 +1,60 @@ +package content.region.kandarin.quest.fishingcontest; + +import core.game.interaction.MovementPulse; +import core.game.node.Node; +import core.game.node.entity.impl.PulseType; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.game.interaction.PluginInteraction; +import core.game.interaction.PluginInteractionManager; +import core.game.world.repository.Repository; +import content.data.Quests; + +@Initializable +public class StairInteraction extends PluginInteraction { + @Override + public boolean handle(Player player, Node node) { + if(!player.getQuestRepository().isComplete(Quests.FISHING_CONTEST)) { + Scenery object = node.asScenery(); + switch (object.getId()) { + case 57: + handleStairs(player,232,object); + return true; + case 55: + handleStairs(player,3679,object); + return true; + } + } + return false; + } + + private void handleStairs(Player player, int npc_id, Scenery object){ + player.getPulseManager().run(new MovementPulse(player,object.getLocation().transform(0,2,0)) { + @Override + public boolean pulse() { + NPC n = Repository.findNPC(npc_id); + if (n == null) { + player.sendMessage("Are you in a world without NPCs? What did you do?"); + return true; + } + player.getDialogueInterpreter().open(npc_id, n); + return true; + } + }, PulseType.STANDARD); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + setIds(new int[]{57,55}); + PluginInteractionManager.register(this, PluginInteractionManager.InteractionType.OBJECT); + return this; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } +} diff --git a/Server/src/main/content/region/kandarin/quest/fishingcontest/VineInteraction.java b/Server/src/main/content/region/kandarin/quest/fishingcontest/VineInteraction.java new file mode 100644 index 0000000..17ceb59 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/fishingcontest/VineInteraction.java @@ -0,0 +1,52 @@ +package content.region.kandarin.quest.fishingcontest; + +import core.game.interaction.MovementPulse; +import core.game.node.Node; +import core.game.node.entity.impl.PulseType; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.game.interaction.PluginInteraction; +import core.game.interaction.PluginInteractionManager; +import content.data.Quests; + +@Initializable +public class VineInteraction extends PluginInteraction { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + setIds(new int[]{58,2989,2990,2991,2992,2993,2994,2013}); + PluginInteractionManager.register(this, PluginInteractionManager.InteractionType.OBJECT); + return this; + } + + @Override + public boolean handle(Player player, Node node) { + if(node instanceof Scenery){ + if(player.getQuestRepository().getStage(Quests.FISHING_CONTEST) > 0 && player.getQuestRepository().getStage(Quests.FISHING_CONTEST) < 100){ + player.getPulseManager().run(new MovementPulse(player, node.asScenery().getLocation().transform(0, 0, 0)) { + @Override + public boolean pulse() { + if(player.getInventory().containsItem(FishingContest.SPADE)) { + player.getAnimator().animate(new Animation(830)); + player.getDialogueInterpreter().sendDialogue("You find some worms."); + player.getInventory().add(FishingContest.RED_VINE_WORM); + } else { + player.getDialogueInterpreter().sendDialogue("The ground looks promising around these vines.","Perhaps you should dig."); + } + return true; + } + }, PulseType.STANDARD); + return true; + } + } + return false; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } +} diff --git a/Server/src/main/content/region/kandarin/quest/fishingcontest/grandpaJack.java b/Server/src/main/content/region/kandarin/quest/fishingcontest/grandpaJack.java new file mode 100644 index 0000000..2a89313 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/fishingcontest/grandpaJack.java @@ -0,0 +1,271 @@ +package content.region.kandarin.quest.fishingcontest; + +import core.game.node.entity.npc.NPC; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; +import core.game.dialogue.DialoguePlugin; + +/** + * Represents the dialogue plugin used for the grandpaJack npc. + * @author Woah + * @note finish with fishing contests. + **/ +@Initializable +public final class grandpaJack extends DialoguePlugin { + + + + /** + * Constructs a new {@code grandpaJack} {@code Object}. + * @param player + */ + public grandpaJack(final Player player) { + super(player); + } + + /** + * Constructs a new {@code grandpaJack} {@code Object}. + */ + public grandpaJack() { + /** + * empty. + */ + } + + + @Override + public DialoguePlugin newInstance(Player player) { + return new grandpaJack(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + npc("Hello young'on!", "Come to visit old Grandpa Jack? I can tell ye stories", " for sure. I used to be the best fisherman these parts", "have seen!"); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + + case 0: + interpreter.sendOptions("Choose an option:", "Tell me a story then.", "Are you entering the fishing competition?", "Sorry, I don't have time now.", "Can I buy one of your fishing rods?", "I've forgotten how to fish, can you remind me?"); + stage++; + break; + + case 1: + switch (buttonId) { + case 1: + player("Tell me a story then."); + stage = 10; + break; + case 2: + player("Are you entering the fishing competition?"); + stage = 20; + break; + case 3: + player("Sorry, I don't have time now."); + stage = 35; + break; + case 4: + player("Can I buy one of your fishing rods?"); + stage = 40; + break; + case 5: + player("I've forgotten how to fish, can you remind me?"); + stage = 50; + break; + } + break; + + case 4: + interpreter.sendOptions("Choose an option:", "I don't suppose you could give me any hints?", "That's less competition for me then."); + stage++; + break; + + case 5: + switch (buttonId) { + case 1: + player("I don't suppose you could give me any hints?"); + stage = 22; + break; + case 2: + player("That's less competition for me then."); + stage = 30; + break; + } + break; + + case 6: + interpreter.sendOptions("Choose an option:", "Very fair, I'll buy that rod!", "That's too rich for me, I'll go to Catherby."); + stage++; + break; + + case 7: + switch (buttonId) { + case 1: + player("Very fair, I'll buy that rod!"); + if(player.getInventory().containsItem(new Item(995,5))){ + stage = 42; + } else { + stage = 60; + } + break; + case 2: + player("That's too rich for me, I'll go to Catherby."); + stage = 44; + break; + } + break; + + + //CASE 9 is break + case 9: + end(); + break; + + + //Case 1 Option 1 - Tell me a story then. + case 10: + npc("Well, when I were a young man we used", "to take fishing trips over to Catherby.", "The fishing over there, now that was something!"); + stage++; + break; + case 11: + npc("Anyway, we decided to do a bit of fishing with our nets,", "I wasn't having the best of days turning up", "nothing but old boots and bits of seaweed."); + stage++; + break; + case 12: + npc("Then my net suddenly got really heavy!", "I pulled it up... To my amazement", "I'd caught this little chest thing!"); + stage++; + break; + case 13: + npc("Even more amazing was when I opened it", "it contained a diamond the size of a radish!", "That's the best catch I've ever had!"); + stage = 0; + break; + + + //Case 1 Option 2 - Are you entering the fishing competition? + case 20: + npc("Ah... the Hemenster fishing competition..."); + stage++; + break; + + case 21: + npc(" I know all about that... I won that four years straight!", "I'm too old for that lark now though..."); + stage = 4; + break; + + //Case 5 Option 1 - I don't suppose you could give me any hints? + case 22: + npc("Well, you sometimes get these really big fish in the", "water just by the outflow pipes."); + stage++; + break; + case 23: + npc("I think they're some kind of carp..."); + stage++; + break; + case 24: + npc("Try to get a spot round there. ", "The best sort of bait for them is red vine worms."); + stage++; + break; + case 25: + npc("I used to get those from McGrubor's wood, north of", "here. Just dig around in the red vines up there but be", "careful of the guard dogs."); + stage++; + break; + case 26: + player("There's this weird creepy guy who says he's not a", "vampire using that spot. He keeps winning too."); + stage++; + break; + case 27: + npc("Ahh well, I'm sure you'll find something to put him off.", "After all, there must be a kitchen around here with", "some garlic in it, perhaps in Seers Village or Ardougne.", "If he's pretending to be a vampire then he can pretend"); + stage++; + break; + case 28: + npc("to be scared of garlic!"); + stage++; + break; + case 29: + player("You're right! Thanks Jack!"); + stage = 9;//End + break; + + //Case 5 Option 2 - That's less competition for me then. + case 30: + npc("Why you young whippersnapper!", "If I was twenty years younger I'd show you something that's for sure!"); + stage = 0; + break; + + //Case 1 Option 3 - Sorry, I don't have time now. + case 35: + npc("Sigh... Young people - always in such a rush. "); + stage = 9; + break; + + //Case 1 Option 4 - Can I buy one of your fishing rods? + case 40: + npc("Of course you can young man. Let's see now...", "I think 5 gold is a fair price for a rod which" , "has won the Fishing contest before eh?"); + stage = 6; + break; + + //Case 7 Option 1 - Very fair, I'll buy that rod! (player has 5 gp) + case 42: + npc("Excellent choice!"); + player.getInventory().remove(new Item(995, 5)); + player.getInventory().add(FishingContest.FISHING_ROD, player);// + stage = 9; + break; + + + //Case 7 Option 2 - That's too rich for me, I'll go to Catherby. + case 44: + npc("If you're sure... passing up an opportunity of a lifetime you are."); + stage = 9; + break; + + //Case 1 Option 5 - I've forgotten how to fish, can you remind me? + case 50: + npc("Of course! Let me see now... You'll need a rod and bait.", "You can fish with a net too, but not in the competition."); + stage++; + break; + case 51: + player("Ok... I think I can get those in Catherby."); + stage++; + break; + case 52: + npc("Then simply find yourself a fishing spot, ", "either in the competition near here, or wherever you can.", "I recommend net fishing in Catherby."); + stage++; + break; + case 53: + npc("Net or Lure the fish in the fishing spot", "by clicking on it and then be patient..."); + stage++; + break; + case 54: + player("It's that simple?"); + stage++; + break; + case 55: + npc("Yep! Go get em tiger."); + stage = 0; + break; + + //Case 7 Option 1 - Very fair, I'll buy that rod! (not enough gp) + case 60: + player("I don't have enough money for that,", "I'll go get some and come back."); + stage++; + break; + case 61: + npc("Right you are. I'll be here. "); + stage = 9; + break; + } + return true; + } + + + @Override + public int[] getIds() { + return new int[] { 230 }; + } +} diff --git a/Server/src/main/content/region/kandarin/quest/grandtree/AnitaDialogue.kt b/Server/src/main/content/region/kandarin/quest/grandtree/AnitaDialogue.kt new file mode 100644 index 0000000..4d9c58b --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/grandtree/AnitaDialogue.kt @@ -0,0 +1,49 @@ +package content.region.kandarin.quest.grandtree + +import content.data.Quests +import core.api.addItemOrDrop +import core.api.getQuestStage +import core.api.sendDialogue +import core.game.dialogue.DialogueFile +import core.game.node.item.Item +import core.tools.END_DIALOGUE +import org.rs09.consts.Items + +class AnitaDialogue : DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + when(getQuestStage(player!!, Quests.THE_GRAND_TREE)){ + 60 -> { + if(player!!.hasItem(Item(Items.GLOUGHS_KEY_788)) && stage < 12){ + when(stage){ + 0 -> npcl("Have you taken that key to Glough yet?").also { stage++ } + 1 -> playerl("No, I'm still carrying it around.").also { stage++ } + 2 -> npcl("Oh. Please take it to Glough!").also { stage = END_DIALOGUE } + } + } else { + when(stage){ + 0 -> playerl("Hello there.").also { stage++ } + 1 -> npcl("Oh hello, I've seen you with the King.").also { stage++ } + 2 -> playerl("Yes, I'm helping him with a problem.").also { stage++ } + 3 -> npcl("You must know my boyfriend Glough then?").also { stage++ } + 4 -> playerl("Indeed!").also { stage++ } + 5 -> npcl("Could you do me a favour?").also { stage++ } + 6 -> options("I suppose so.","No, I'm busy.").also { stage++ } + 7 -> when(buttonID){ + 1 -> playerl("I suppose so.").also { stage = 10 } + 2 -> playerl("No, I'm busy.").also { stage = END_DIALOGUE } + } + 10 -> playerl("I suppose so.").also { stage++ } + 11 -> npcl("Please give this key to Glough, he left it here last night.").also { stage++ } + 12 -> sendDialogue(player!!, "Anita gives you a key.").also { + addItemOrDrop(player!!, Items.GLOUGHS_KEY_788) + stage++ + } + 13 -> npcl("Thanks a lot.").also { stage++ } + 14 -> playerl("No... thank you!").also { stage = END_DIALOGUE } + } + } + } + } + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/grandtree/BlackDemonCutscene.kt b/Server/src/main/content/region/kandarin/quest/grandtree/BlackDemonCutscene.kt new file mode 100644 index 0000000..2afe9f1 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/grandtree/BlackDemonCutscene.kt @@ -0,0 +1,88 @@ +package content.region.kandarin.quest.grandtree + +import content.region.misthalin.dorgeshuun.quest.thelosttribe.LostTribeCutscene +import core.ServerConstants +import core.api.openDialogue +import core.api.sendChat +import core.api.sendDialogue +import core.api.sendMessage +import core.game.activity.Cutscene +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.world.map.Direction +import core.game.world.map.Location +import core.game.global.action.DoorActionHandler +import core.game.node.entity.npc.NPC +import org.rs09.consts.NPCs + +class BlackDemonCutscene(player: Player) : Cutscene(player) { + override fun setup() { + setExit(Location.create(2491, 9864, 0)) + if(player.settings.isRunToggled){ + player.settings.toggleRun() + } + loadRegion(9882) + addNPC(NPCs.GLOUGH_671, 48, 8, Direction.WEST) + addNPC(NPCs.BLACK_DEMON_677, 43, 9, Direction.EAST) + } + + override fun runStage(stage: Int) { + when(stage) + { + 0 -> { + fadeToBlack() + timedUpdate(6) + } + 1 -> { + fadeFromBlack() + teleport(player, 59, 8) + moveCamera(55, 8) + rotateCamera(0, 0) + sendChat(player, "Hello?") + player.face(getNPC(NPCs.GLOUGH_671)!!) + timedUpdate(3) + } + 2 -> { + moveCamera(48, 8) + sendChat(player, "Anybody?") + timedUpdate(3) + } + 3 -> { + sendChat(player, "Glough?") + move(getNPC(NPCs.GLOUGH_671)!!, 52, 8) + timedUpdate(10) + } + 4 -> { + moveCamera(55, 4,2000) + rotateCamera(55, 6) + timedUpdate(4) + } + 5 -> { + move(player, 53, 8) + playerDialogueUpdate(FacialExpression.SCARED, "Glough?") + } + 6 -> { + dialogueUpdate(NPCs.GLOUGH_671, FacialExpression.ANGRY, "You really are becoming a headache! Well, at least now you can die knowing you were right, it will save me having to hunt you down like all the other human filth of " + ServerConstants.SERVER_NAME + "!") + } + 7 -> { + playerDialogueUpdate(FacialExpression.SCARED, "You're crazy, Glough!") + } + 8 -> { + dialogueUpdate(NPCs.GLOUGH_671, FacialExpression.ANGRY, "Bah! Well, soon you'll see, the gnomes are ready to fight. In three weeks this tree will be dead wood, in ten weeks it will be 30 battleships! Finally we will rid the world of the disease called humanity!") + } + 9 -> { + playerDialogueUpdate(FacialExpression.SCARED, "What makes you think I'll let you get away with it?") + } + 10 -> { + moveCamera(47,9) + rotateCamera(40, 9) + dialogueUpdate(NPCs.GLOUGH_671, FacialExpression.ANGRY, "Fool...meet my little friend!") + } + 11 -> { + end{ + BlackDemonNPC(NPCs.BLACK_DEMON_677, Location.create(2485, 9864, 0)).init() + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/grandtree/BlackDemonNPC.kt b/Server/src/main/content/region/kandarin/quest/grandtree/BlackDemonNPC.kt new file mode 100644 index 0000000..1123214 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/grandtree/BlackDemonNPC.kt @@ -0,0 +1,34 @@ +package content.region.kandarin.quest.grandtree + +import content.data.Quests +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.npc.AbstractNPC +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.NPCs +import core.game.interaction.InteractionListener + +@Initializable +class BlackDemonNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id,location), InteractionListener { + + override fun construct(id: Int, location: Location?, vararg objects: Any?): AbstractNPC { + return BlackDemonNPC(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.BLACK_DEMON_677) + } + + override fun defineListeners() { + } + + override fun finalizeDeath(killer: Entity?) { + // In the event that this npcID is used somewhere else... + if(killer!!.asPlayer().location.regionId == 9882) { + setQuestStage(killer!!.asPlayer(), Quests.THE_GRAND_TREE, 98) + this.isRespawn = false + } + super.finalizeDeath(killer) + } +} diff --git a/Server/src/main/content/region/kandarin/quest/grandtree/CaptainErrdoDialogue.kt b/Server/src/main/content/region/kandarin/quest/grandtree/CaptainErrdoDialogue.kt new file mode 100644 index 0000000..2b225bb --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/grandtree/CaptainErrdoDialogue.kt @@ -0,0 +1,78 @@ +package content.region.kandarin.quest.grandtree + +import content.data.Quests +import content.global.travel.glider.Gliders +import core.api.getQuestStage +import core.api.teleport +import core.game.component.Component +import core.game.dialogue.DialogueFile +import core.game.world.map.Location +import core.tools.END_DIALOGUE + +class CaptainErrdoDialogue: DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + when(getQuestStage(player!!, Quests.THE_GRAND_TREE)){ + 55 -> { + if(player!!.location.regionId == 11567){ + when(stage){ + 0 -> npcl("Sorry about that.").also { stage++ } + 1 -> npcl("That turbulence over the Karamja Volcano was a bit unexpected, and the area round here isn't well suited for emergency landing.").also { stage++ } + 2 -> npcl("Still! we're still alive that's the main thing. Are you okay?").also { stage++ } + 3 -> playerl("I'm fine, I can't say the same for your glider!").also { stage++ } + 4 -> npcl("I don't think I can fix this. Looks like we'll be heading back by foot. I might see if I can find Penwie while I'm here, I believe he's charting the area.").also { stage++ } + 5 -> playerl("Where's the shipyard from here?").also { stage++ } + 6 -> npcl("I think I saw some buildings on the coast east of here while we were crashing. I'd have a look there.").also { stage++ } + 7 -> npcl("Take care adventurer!").also { stage++ } + 8 -> playerl("Take care little man.").also { stage = END_DIALOGUE } + } + } else if (player!!.location.regionId == 9782){ + when(stage){ + 0 -> npcl("Hi. The king said that you need to leave?").also { stage++ } + 1 -> playerl("Apparently, humans are invading!").also { stage++ } + 2 -> npcl("I find that hard to believe. I have lots of human friends.").also { stage++ } + 3 -> playerl("I don't understand it either!").also { stage++ } + 4 -> npcl("So, where to?").also { stage++ } + 5 -> options("Take me to Karamja please!", "Not anywhere for now!").also { stage++ } + 6 -> when(buttonID){ + 1 -> playerl("Take me to Karamja, please.").also { stage++ } + 2 -> playerl("Not anywhere for now.").also { stage = 10 } + } + 7 -> npcl("Okay, you're the boss! Hold on tight, it'll be a rough ride.").also { + teleport(player!!, Location.create(2917, 3054, 0)) + stage = END_DIALOGUE + } + 10 -> npcl("Okay. I'll be here for when you're ready.").also { stage = END_DIALOGUE } + } + } else { + // We are talking to another gnome outside the stronghold during the quest. + when(stage) { + 0 -> playerl("May you fly me somewhere on your glider?").also { stage++ } + 1 -> npcl("I only fly friends of the gnomes!").also { + stage = END_DIALOGUE + } + } + } + } + 100 -> { + when(stage){ + 0 -> playerl("May you fly me somewhere on your glider?").also { stage++ } + 1 -> npcl("If you wish.").also { + stage = END_DIALOGUE + player!!.interfaceManager.open(Component(138)) + Gliders.sendConfig(npc, player) + + } + } + } + else -> { + when(stage){ + 0 -> playerl("May you fly me somewhere on your glider?").also { stage++ } + 1 -> npcl("I only fly friends of the gnomes!").also { + stage = END_DIALOGUE + } + } + } + } + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/grandtree/CharlieDialogue.kt b/Server/src/main/content/region/kandarin/quest/grandtree/CharlieDialogue.kt new file mode 100644 index 0000000..d4af658 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/grandtree/CharlieDialogue.kt @@ -0,0 +1,124 @@ +package content.region.kandarin.quest.grandtree + +import content.data.Quests +import core.ServerConstants +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.global.action.DoorActionHandler +import core.game.node.entity.npc.NPC +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.game.world.GameWorld +import core.game.world.map.Direction +import core.game.world.map.Location +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class CharlieDialogue : DialogueFile() { + + override fun handle(componentID: Int, buttonID: Int) { + when (getQuestStage(player!!, Quests.THE_GRAND_TREE)) { + 46 -> { + when (stage) { + 0 -> playerl("Tell me. Why would you want to kill the Grand Tree?").also { stage++ } + 1 -> npcl("What do you mean?").also { stage++ } + 2 -> playerl("Don't tell me, you just happened to be caught carrying Daconia rocks!").also { stage++ } + 3 -> npcl("All I know is that I did what I was asked.").also { stage++ } + 4 -> playerl("I don't understand.").also { stage++ } + 5 -> npcl("Glough paid me to go to this gnome on a hill. I gave the gnome a seal and he gave me some Daconia rocks to give to Glough.").also { stage++ } + 6 -> npcl("I've been doing it for weeks, this time though Glough locked me up here! I just don't understand it.").also { stage++ } + 7 -> playerl("Sounds like Glough is hiding something.").also { stage++ } + 8 -> npcl("I don't know what he's up to. If you want to find out, you'd better search his home.").also { stage++ } + 9 -> playerl("OK. Thanks Charlie.").also { stage++ } + 10 -> npcl("Good luck!").also { + setQuestStage(player!!, Quests.THE_GRAND_TREE, 47) + stage = END_DIALOGUE + } + } + } + 47 -> { + when (stage) { + 0 -> npcl("Hello adventurer. Have you figured out what's going on?").also { stage++ } + 1 -> playerl("No idea.").also { stage++ } + 2 -> npcl("To get to the bottom of this you'll need to search Glough's home.").also { stage = END_DIALOGUE } + } + } + 50 -> { + when(stage) { + 0 -> npcl("So they got you as well?").also { stage++ } + 1 -> playerl("It's Glough! He's trying to cover something up.").also { stage++ } + 2 -> npcl("I shouldn't tell you this adventurer. But if you want to get to the bottom of this you should go and talk to the Karamja Shipyard foreman.").also { stage++ } + 3 -> playerl("Why?").also { stage++ } + 4 -> npcl("Glough sent me to Karamja to meet him. I delivered a large amount of gold. For what? I don't know. He may be able to tell you what Glough's up to. That's if you can get out of here. You'll find him").also { stage++ } + 5 -> npcl("in the Karamja Shipyard, east of Shilo Village. Be careful! If he discovers you're not working for Glough, there'll be trouble! The seamen use the password Ka-Lu-Min.").also { stage++ } + 6 -> playerl("Thanks, Charlie!").also { + stage = END_DIALOGUE + GameWorld.Pulser.submit(object : Pulse(0) { + var count = 0 + val npc = NPC.create(NPCs.KING_NARNODE_SHAREEN_670, Location.create(2467, 3496, 3), null) + override fun pulse(): Boolean { + when (count) { + 0 -> { + // Spawn in narnode + npc.init() + lock(player!!,10) + forceWalk(npc, player!!.location.transform(Direction.EAST, 2), "SMART") + } + + 2 -> { + sendNPCDialogue(player!!, npc.id,"Traveller, please accept my apologies! Glough had no right to arrest you! I just think he's scared of humans. Let me get you out of there.") + } + + 4 -> { + DoorActionHandler.handleAutowalkDoor(player!!, + getScenery(2465,3496,3) + ) + openDialogue(player!!,KingNarnodeUpstairsDialogue(), npc) + } + 8 -> { + unlock(player!!) + npc.clear() + setQuestStage(player!!, Quests.THE_GRAND_TREE, 55) + return true + } + } + count++ + return false + } + }) + } + } + } + 55 -> { + if(player!!.hasItem(Item(Items.LUMBER_ORDER_787))){ + when(stage) { + 0 -> playerl("How are you doing, Charlie?").also { stage++ } + 1 -> npcl("I've been better.").also { stage++ } + 2 -> playerl("Glough has some plan to rule ${ServerConstants.SERVER_NAME}!").also { stage++ } + 3 -> npcl("I wouldn't put it past him, the gnome's crazy!").also { stage++ } + 4 -> playerl("I need some proof to convince the King.").also { stage++ } + 5 -> npcl("Hmm...you could be in luck! Before Glough had me locked up I heard him mention that he'd left his chest keys at his girlfriend's.").also { stage++ } + 6 -> playerl("Where does she live?").also { stage++ } + 7 -> npcl("Just west of the toad swamp.").also { stage++ } + 8 -> playerl("OK, I'll see what I can find.").also { + setQuestStage(player!!, Quests.THE_GRAND_TREE, 60) + stage = END_DIALOGUE + } + } + } else { + when(stage) { + 0 -> playerl("I can't figure this out Charlie!").also { stage++ } + 1 -> npcl("Go and see the foreman in the Karamja jungle, there's a shipyard there, you might find some clues. Don't forget the password is Ka-Lu-Min;").also { stage++ } + 2 -> npcl("Tf they realise that you're not working for Glough there'll be trouble!").also { stage = END_DIALOGUE } + + } + } + } else -> { + when(stage){ + 0 -> sendDialogue(player!!, "The prisoner is in no mood to talk.").also { stage = END_DIALOGUE } + } + } + } + } +} diff --git a/Server/src/main/content/region/kandarin/quest/grandtree/ForemanNPC.kt b/Server/src/main/content/region/kandarin/quest/grandtree/ForemanNPC.kt new file mode 100644 index 0000000..1977a47 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/grandtree/ForemanNPC.kt @@ -0,0 +1,140 @@ +package content.region.kandarin.quest.grandtree + +import content.data.Quests +import core.ServerConstants +import core.api.* +import core.game.component.Component +import core.game.dialogue.DialogueFile +import core.game.interaction.IntType +import core.game.node.entity.Entity +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import core.game.interaction.InteractionListener +import core.game.system.task.Pulse +import core.game.world.GameWorld +import core.game.world.map.RegionManager +import core.tools.END_DIALOGUE +import org.rs09.consts.Components + +@Initializable +class ForemanNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id,location), InteractionListener { + + override fun construct(id: Int, location: Location?, vararg objects: Any?): AbstractNPC { + return ForemanNPC(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.FOREMAN_674) + } + + override fun defineListeners() { + on(this.ids, IntType.NPC, "talk-to"){ player, npc -> + openDialogue(player, ForemanDialogue(), npc) + return@on true + } + } + + override fun finalizeDeath(killer: Entity?) { + if(getQuestStage(killer as Player, Quests.THE_GRAND_TREE) == 55) { + sendMessage(killer,"The foreman drops a piece of paper as he dies.") + produceGroundItem(killer, Items.LUMBER_ORDER_787, 1, this.location) + } + super.finalizeDeath(killer) + } +} + +class ForemanDialogue: DialogueFile(){ + private fun attackPlayer(){ + val foreman = RegionManager.getNpc(player!!.location, NPCs.FOREMAN_674, 6) + foreman!!.attack(player!!) + } + override fun handle(componentID: Int, buttonID: Int) { + when(stage){ + 0 -> playerl("Hello, are you in charge?").also { stage++ } + 1 -> npcl("That's right, and you are...?").also { stage++ } + 2 -> playerl("Glough sent me to check on how you are doing.").also { stage++ } + 3 -> npcl("Right. Glough sent a human?").also { stage++ } + 4 -> playerl("His gnomes are busy.").also { stage++ } + 5 -> npcl("Hmm... in that case we'd better go to my office. Follow me.").also { + val foremanOffice = Location.create(2954, 3024, 0) + GameWorld.Pulser.submit(object : Pulse(0) { + var count = 0 + override fun pulse(): Boolean { + when (count) { + 0 -> { + player!!.interfaceManager.closeOverlay() + player!!.interfaceManager.openOverlay(Component(Components.FADE_TO_BLACK_120)) + } + 2 -> { + teleport(player!!,foremanOffice) + player!!.interfaceManager.closeOverlay() + player!!.interfaceManager.openOverlay(Component(Components.FADE_FROM_BLACK_170)) + return true + } + } + count++ + return false + } + }) + stage++ + } + 6 -> npcl("Tell me again why you're here.").also { stage++ } + 7 -> playerl("Er... Glough sent me?").also { stage++ } + 8 -> npcl("By the way how is Glough? Still with his wife?").also { stage++ } + 9 -> options("Yes, they're getting on great.","Always arguing as usual!","Sadly his wife is no longer with us!").also { stage++ } + 10 -> when(buttonID){ + 1 -> playerl("Yes, they're getting on great.").also { stage++ } + 2 -> playerl("Always arguing as usual!").also { stage++ } + 3 -> playerl("Sadly his wife is no longer with us!").also { stage = 20 } + } + 11 -> npcl("Really? That's odd, considering she died last year. Die, imposter!").also { + attackPlayer() + stage = END_DIALOGUE + } + 20 -> npcl("Right answer. I have to watch for imposters. What's Glough's favourite dish?").also { stage++ } + 21 -> options("He loves tangled toads legs.","He loves worm holes.","He loves choc bombs.").also { stage++ } + 22 -> when(buttonID){ + 1 -> playerl("He loves tangled toads legs.").also { stage++ } + 2 -> playerl("He loves worm holes.").also { stage = 30 } + 3 -> playerl("He loves choc bombs.").also { stage++ } + } + 23 -> npcl("Our survey said.... Bzzzzzz! Wrong answer!").also { + attackPlayer() + stage = END_DIALOGUE + } + 30 -> npcl("OK. Just one more. What's the name of his new girlfriend?").also { stage++ } + 31 -> options("Anita.","Alia.","Elena.").also { stage++ } + 32 -> when(buttonID){ + 1 -> playerl("Anita.").also { stage = 35 } + 2 -> playerl("Alia.").also { stage++ } + 3 -> playerl("Elena.").also { stage++ } + } + 33 -> npcl("You almost had me fooled! Die, imposter!").also { + attackPlayer() + stage = END_DIALOGUE + } + 35 -> npcl("Well, well, you do know Glough. Sorry for the interrogation but I'm sure you understand.").also { stage++ } + 36 -> playerl("Of course, security is paramount.").also { stage++ } + 37 -> npcl("As you can see things are going well.").also { stage++ } + 38 -> playerl("Indeed.").also { stage++ } + 39 -> npcl("When I was asked to build a fleet large enough to invade Port Sarim and carry 300 gnome troops I said: 'If anyone can, I can.'").also { stage++ } + 40 -> playerl("That's a lot of troops!").also { stage++ } + 41 -> npcl("True, but if the gnomes are really going to take over " + ServerConstants.SERVER_NAME + " they'll need at least that.").also { stage++ } + 42 -> playerl("Take over?").also { stage++ } + 43 -> npcl("Of course, why else would Glough want 30 battleships? Between you and me I don't think he stands a chance.").also { stage++ } + 44 -> playerl("No?").also { stage++ } + 45 -> npcl("I mean, for the kind of battleships Glough's ordered I'll need tons and tons of lumber! Still, if he says he can supply the wood I'm sure he can! Anyway, here's the order for the lumber.").also { stage++ } + 46 -> sendDialogue(player!!, "The Foreman gives you the Lumber order.").also { + addItemOrDrop(player!!,Items.LUMBER_ORDER_787) + stage++ + } + 47 -> playerl("OK. I'll head off and give this order to Glough.").also { + stage = END_DIALOGUE + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/grandtree/GloughDialogue.kt b/Server/src/main/content/region/kandarin/quest/grandtree/GloughDialogue.kt new file mode 100644 index 0000000..496184c --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/grandtree/GloughDialogue.kt @@ -0,0 +1,117 @@ +package content.region.kandarin.quest.grandtree + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.system.task.Pulse +import core.game.world.GameWorld +import core.game.world.map.Direction +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.tools.END_DIALOGUE + +class GloughDialogue : DialogueFile() { + + override fun handle(componentID: Int, buttonID: Int) { + when (getQuestStage(player!!, Quests.THE_GRAND_TREE)) { + 40 -> { + when (stage) { + 0 -> playerl("Hello.").also { stage++ } + 1 -> sendDialogue(player!!,"The gnome is munching on a worm hole.").also { stage++ } + 2 -> npcl("Can I help human? Can't you see I'm eating?!").also { stage++ } + 3 -> sendDialogue(player!!,"The gnome continues to eat.").also { stage++ } + 4 -> playerl("The King asked me to inform you that the Daconia rocks have been taken!").also { stage++ } + 5 -> npcl("Surely not!").also { stage++ } + 6 -> playerl("Apparently a human took them from Hazelmere. Hazelmere believed him; he had the King's seal!").also { stage++ } + 7 -> npcl("I should've known! The humans are going to invade!").also { stage++ } + 8 -> playerl("Never!").also { stage++ } + 9 -> npcl("Your type can't be trusted! I'll take care of this! Go back to the King.").also { + setQuestStage(player!!, Quests.THE_GRAND_TREE, 45) + stage = END_DIALOGUE + } + } + } + 47 -> { + when(stage){ + 0 -> playerl("Glough! I don't know what you're up to but I know you paid Charlie to get those rocks!").also { stage++ } + 1 -> npcl("You're a fool human! You have no idea what's going on.").also { stage++ } + 2 -> playerl("I know the Grand Tree's dying! And I think you're part of the reason.").also { stage++ } + 3 -> npcl("How dare you accuse me! I'm the head tree guardian! Guards! Guards!").also { stage++ } + 4 -> { + GameWorld.Pulser.submit(object : Pulse(0) { + var count = 0 + val npc = NPC.create(163,Location.create(2477, 3462, 1), null) + val ladderClimbAnimation = Animation(828) + val cell = Location.create(2464, 3496, 3) + override fun pulse(): Boolean { + when (count) { + 0 -> { + // Spawn in the gnome guard + lock(player!!, 10) + npc.init() + forceWalk(npc, player!!.location.transform(Direction.WEST,2), "SMART") + player!!.dialogueInterpreter.sendDialogues(npc, FacialExpression.ANNOYED, "Come with me!") + } + 2 -> { + // Walk to the ladder + forceWalk(npc, Location.create(2476, 3462, 1), "SMART") + } + 4 -> { + unlock(player!!) + forceWalk(player!!, Location.create(2477, 3463, 1), "SMART") + } + 6 -> { + player!!.faceLocation(Location.create(2476, 3463, 1)) + } + 7 -> { + player!!.animator.animate(ladderClimbAnimation) + } + 8 -> { + npc.clear() + setQuestStage(player!!, Quests.THE_GRAND_TREE, 50) + teleport(player!!, cell) + player!!.unlock() + return true + } + } + count++ + return false + } + }).also { stage = END_DIALOGUE } + } + } + } + 55 -> { + when(stage){ + 0 -> playerl("I know what you're up to Glough!").also { stage++ } + 1 -> npcl("You have no idea human!").also { stage++ } + 2 -> playerl("You may be able to make a fleet but the tree gnomes will never follow you into battle against humans.").also { stage++ } + 3 -> npcl("So, you know more than I thought! The gnomes fear humanity more than any other race. I just need to give them a push in the right direction. There's nothing you can do traveller! Leave before it's too late!").also { stage++ } + 4 -> playerl("King Narnode won't allow it!").also { stage++ } + 5 -> npcl("The King's a fool and a coward! He'll bow to me! You'll soon be back in that cage!").also { stage = END_DIALOGUE } + } + } + 60 -> { + when(stage){ + 0 -> playerl("I'm going to stop you, Glough!").also { stage++ } + 1 -> npcl("You're becoming quite annoying traveller!").also { stage++ } + 2 -> npcl("Glough is searching his pockets.").also { stage++ } + 3 -> npcl("Where are that darn key?").also { stage++ } + 4 -> npcl("Leave human, before I have you put in the cage!").also { stage = END_DIALOGUE } + } + } + else -> { + when (stage) { + 0 -> playerl("Hello there!").also { stage++ } + 1 -> npcl("You shouldn't be here human!").also { stage++ } + 2 -> playerl("What do you mean?").also { stage++ } + 3 -> npcl("The Gnome Stronghold is for gnomes alone!").also { stage++ } + 4 -> playerl("Surely not!").also { stage++ } + 5 -> npcl("We don't need your sort round here!").also { stage = END_DIALOGUE } + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/grandtree/GloughsJournal.kt b/Server/src/main/content/region/kandarin/quest/grandtree/GloughsJournal.kt new file mode 100644 index 0000000..e6c57f0 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/grandtree/GloughsJournal.kt @@ -0,0 +1,133 @@ +package content.region.kandarin.seers.quest.elementalworkshop + +import content.global.handlers.iface.BookInterface +import content.global.handlers.iface.BookLine +import content.global.handlers.iface.Page +import content.global.handlers.iface.PageSet +import core.api.setAttribute +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import org.rs09.consts.Items + +/** + * Gloughs Journal book handler for The Grand Tree quest + * + * @author crop & szu & ovenbreado + */ +class GloughsJournal : InteractionListener { + companion object { + private val TITLE = "Glough's Journal" + private val CONTENTS = arrayOf( + PageSet( + Page( + BookLine("The migration failed!", 55), + BookLine("After spending half", 56), + BookLine("a century hiding", 57), + BookLine("underground you", 58), + BookLine("you would think", 59), + BookLine("that the great", 60), + BookLine("migration would have", 61), + BookLine("improved life on", 62), + BookLine("Gielinor for tree gnomes.", 63), + BookLine("However, rather", 64), + BookLine("than the great liberation", 65), + ), + Page( + BookLine("promised to us by", 65), + BookLine("King Healthorg at the", 66), + BookLine("end of the last age,", 67), + BookLine("we have been forced", 68), + BookLine("to live in hiding,", 69), + BookLine("up trees or in the", 70), + BookLine("gnome maze, laughed", 71), + BookLine("at and mocked by man.", 72), + BookLine("Living in constant", 73), + BookLine("fear of human aggression", 74), + BookLine("we are in a no better", 75), + ) + ), + PageSet( + Page( + BookLine("we are in a no better", 55), + BookLine("situation now than", 56), + BookLine("when we lived", 57), + BookLine("in the caves!", 58), + BookLine("Change must come soon!", 59), + BookLine("They must be stopped!", 60), + BookLine("Today I heard of three", 61), + BookLine("more gnomes slain", 62), + BookLine("by Khazard's human", 63), + BookLine("troops for fun,", 64), + BookLine("I can't control", 65), + ), + Page( + BookLine("my anger!", 66), + BookLine("Humanity seems to", 67), + BookLine("have acquired a", 68), + BookLine("level of arrogance", 69), + BookLine("comparable to that", 70), + BookLine("of Zamorak, killing", 71), + BookLine("and pillaging at will!", 72), + BookLine("We are small and at", 73), + BookLine("heart not warriors", 74), + BookLine("but something must", 75), + ) + ), + PageSet( + Page( + BookLine("be done! We will", 55), + BookLine("pick up arms and", 56), + BookLine("go forth into the", 57), + BookLine("human world! We will", 58), + BookLine("defend ourselves and", 59), + BookLine("we will pursue justice", 60), + BookLine("for all gnomes who", 61), + BookLine("fell at the hands", 62), + BookLine("of humans!", 63), + BookLine("Gaining support.", 64), + BookLine("", 65), + ), + Page( + BookLine("Some of the local", 66), + BookLine("gnomes seem strangely", 67), + BookLine("deluded about humans,", 68), + BookLine("many actually believe", 69), + BookLine("that humans are not", 70), + BookLine("all naturally evil", 71), + BookLine("but instead vary", 72), + BookLine("from person to person.", 73), + BookLine("This sort of talk", 74), + BookLine("could be the end", 75), + ) + ), + PageSet( + Page( + BookLine("for the tree gnomes", 55), + BookLine("and I must continue", 56), + BookLine("to convince my fellow", 57), + BookLine("gnome folk the cold", 58), + BookLine("truth about these", 59), + BookLine("human creatures!", 60), + BookLine("How they will not", 61), + BookLine("stop until all gnome", 62), + BookLine("life is destroyed!", 63), + BookLine("Unless we can ", 64), + BookLine("destroy them first!", 65), + ) + ) + ) + + private fun display(player: Player, pageNum: Int, buttonID: Int): Boolean { + BookInterface.pageSetup(player, BookInterface.FANCY_BOOK_3_49, TITLE, CONTENTS) + return true + } + } + + override fun defineListeners() { + on(Items.GLOUGHS_JOURNAL_785, IntType.ITEM, "read") { player, _ -> + BookInterface.openBook(player, BookInterface.FANCY_BOOK_3_49, ::display) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/grandtree/GrandTreeListeners.kt b/Server/src/main/content/region/kandarin/quest/grandtree/GrandTreeListeners.kt new file mode 100644 index 0000000..8548efe --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/grandtree/GrandTreeListeners.kt @@ -0,0 +1,222 @@ +package content.region.kandarin.quest.grandtree + +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import core.game.node.scenery.Scenery +import core.game.node.scenery.SceneryBuilder +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Sounds +import content.data.Quests + +class GrandTreeListeners: InteractionListener { + + val roots = arrayOf( + Location(2467,9896,0), + Location(2468,9890,0), + Location(2465,9891,0), + Location(2465,9891,0), + Location(2473,9897,0), + ) + + val hazelmerescroll = Items.HAZELMERES_SCROLL_786 + + val hazelmerescrollText = arrayOf( + "Es lemanto meso pro eis prit ta Cinqo mond.", + "Mi lovos ta lemanto Daconia arpos", + "et Daconia arpos eto meriz ta priw!", + ) + + fun unlockTUZODoor(player: Player) { + if (getAttribute(player, "/save:grandtree:twig1", false) && + getAttribute(player, "/save:grandtree:twig2", false) && + getAttribute(player, "/save:grandtree:twig3", false) && + getAttribute(player, "/save:grandtree:twig4", false) + ){ + sendDialogue(player,"With a grinding of machinery, a trapdoor snaps open!") + //SceneryBuilder.replace(Scenery(2444, Location(2487,3464,2), 22 , 2), Scenery(2445, Location(2487,3464,2), 22 , 2),20) + } + } + + override fun defineDestinationOverrides() { + setDest(IntType.NPC, intArrayOf(NPCs.CHARLIE_673),"talk-to"){ player, _ -> + return@setDest player.location + } + } + + override fun defineListeners() { + on(NPCs.KING_NARNODE_SHAREEN_670, IntType.NPC, "talk-to"){ player, npc -> + val aboveground = 9782 + if(player.location.regionId == aboveground) + openDialogue(player, KingNarnodeDialogue(), npc) + else + openDialogue(player, KingNarnodeUnderGroundDialogue(), npc) + return@on true + } + on(NPCs.HAZELMERE_669, IntType.NPC, "talk-to"){ player, npc -> + openDialogue(player, HazelmereDialogue(), npc) + return@on true + } + on(NPCs.GLOUGH_671, IntType.NPC, "talk-to"){ player, npc -> + openDialogue(player, GloughDialogue(), npc) + return@on true + } + on(intArrayOf(NPCs.SHIPYARD_WORKER_675, NPCs.SHIPYARD_WORKER_38, NPCs.SHIPYARD_WORKER_39), IntType.NPC, "talk-to"){ player, npc -> + openDialogue(player, ShipyardWorkerGenericDialogue(), npc) + return@on true + } + on(NPCs.CHARLIE_673, IntType.NPC, "talk-to"){ player, npc -> + openDialogue(player, CharlieDialogue(), npc) + return@on true + } + on(NPCs.CAPTAIN_ERRDO_3811, IntType.NPC, "talk-to"){ player, npc -> + openDialogue(player, CaptainErrdoDialogue(), npc) + return@on true + } + on(NPCs.ANITA_672, IntType.NPC, "talk-to"){ player, npc -> + openDialogue(player, AnitaDialogue(), npc) + return@on true + } + on(hazelmerescroll, IntType.ITEM, "read") { player, node -> + hazelmereScroll(player, node.asItem()) + return@on true + } + + on(2444, IntType.SCENERY, "open"){ player, node -> + if(node.location == Location(2487,3464,2) && !isQuestComplete(player, Quests.THE_GRAND_TREE)){ + if(getAttribute(player, "/save:grandtree:twig1", false) && + getAttribute(player, "/save:grandtree:twig2", false) && + getAttribute(player, "/save:grandtree:twig3", false) && + getAttribute(player, "/save:grandtree:twig4", false)){ + player.animator.animate(Animation(828)) + BlackDemonCutscene(player).start() + } + } + return@on true + } + + on(2446, IntType.SCENERY, "open"){ player, node -> + if(node.location == Location(2463, 3497, 0) && isQuestComplete( + player!!, + Quests.THE_GRAND_TREE + )){ + player.animator.animate(Animation(828)) + // Go to tunnels + teleport(player, Location(2464, 9897, 0)) + } + return@on true + } + + onUseWith(IntType.SCENERY, 788, 2436){ player, used, with -> + SceneryBuilder.replace(Scenery(2436, Location(2482,3462,1)),Scenery(2437, Location(2482,3462,1)),2) + sendDialogue(player,"You found a scroll!") + addItemOrDrop(player, Items.INVASION_PLANS_794) + if(getQuestStage(player!!, Quests.THE_GRAND_TREE) < 60) + setQuestStage(player!!, Quests.THE_GRAND_TREE, 60) + return@onUseWith true + } + onUseWith(IntType.SCENERY, Items.TWIGS_789, 2440){ player, used, with -> + setAttribute(player, "/save:grandtree:twig1", true) + removeItem(player, used.asItem()) + GroundItemManager.create(used.asItem(), with.location, player) + unlockTUZODoor(player) + return@onUseWith true + } + onUseWith(IntType.SCENERY, Items.TWIGS_790, 2441){ player, used, with -> + setAttribute(player, "/save:grandtree:twig2", true) + removeItem(player, used.asItem()) + GroundItemManager.create(used.asItem(), with.location, player) + unlockTUZODoor(player) + return@onUseWith true + } + onUseWith(IntType.SCENERY, Items.TWIGS_791, 2442){ player, used, with -> + setAttribute(player, "/save:grandtree:twig3", true) + removeItem(player, used.asItem()) + GroundItemManager.create(used.asItem(), with.location, player) + unlockTUZODoor(player) + return@onUseWith true + } + onUseWith(IntType.SCENERY, Items.TWIGS_792, 2443){ player, used, with -> + setAttribute(player, "/save:grandtree:twig4", true) + removeItem(player, used.asItem()) + GroundItemManager.create(used.asItem(), with.location, player) + unlockTUZODoor(player) + return@onUseWith true + } + // Removing twigs + on(Items.TWIGS_789, IntType.GROUNDITEM, "take"){ player, node -> + setAttribute(player, "/save:grandtree:twig1", false) + return@on true + } + on(Items.TWIGS_790, IntType.GROUNDITEM, "take"){ player, node -> + setAttribute(player, "/save:grandtree:twig2", false) + return@on true + } + on(Items.TWIGS_791, IntType.GROUNDITEM, "take"){ player, node -> + setAttribute(player, "/save:grandtree:twig3", false) + return@on true + } + on(Items.TWIGS_792, IntType.GROUNDITEM, "take"){ player, node -> + setAttribute(player, "/save:grandtree:twig4", false) + return@on true + } + on(2435, IntType.SCENERY, "search"){ player, _ -> + if(getQuestStage(player, Quests.THE_GRAND_TREE) == 47){ + sendItemDialogue(player, Items.GLOUGHS_JOURNAL_785,"You've found Glough's Journal!") + addItemOrDrop(player, Items.GLOUGHS_JOURNAL_785) + } + return@on true + } + + // Roots for Daconia rock + on(32319, IntType.SCENERY, "search"){ player, node -> + if(getQuestStage(player, Quests.THE_GRAND_TREE) < 99 || player.hasItem(Item(Items.DACONIA_ROCK_793))){ return@on true; } + // RNG for which root the rock is under + if(node.location == roots[getAttribute(player,"grandtree:rock",1)]){ + sendItemDialogue(player, Item(Items.DACONIA_ROCK_793), "You've found a Daconia rock!") + addItemOrDrop(player,Items.DACONIA_ROCK_793) + } + return@on true + } + // Gate Karamja + on(2439, IntType.SCENERY, "open"){ player, _ -> + openDialogue(player, ShipyardWorkerDialogue(), NPC(NPCs.SHIPYARD_WORKER_675)) + return@on true + } + on(2438, IntType.SCENERY, "open"){ player, _ -> + openDialogue(player, ShipyardWorkerDialogue(), NPC(NPCs.SHIPYARD_WORKER_675)) + return@on true + } + on(2451, IntType.SCENERY, "push"){ player, roots -> + if (hasRequirement(player, Quests.THE_GRAND_TREE)) { + val outsideMine = player.location == Location.create(2467, 9903, 0) || player.location == Location.create(2468, 9903, 0) + if(outsideMine) { + forceMove(player, player.location, player.location.transform(0, 2, 0), 25, 60, null, 819) + } else { + forceMove(player, player.location, player.location.transform(0, -2, 0), 25, 60, null, 819) + } + animate(player, 2572, false) + animateScenery(roots.asScenery(), 452) + playAudio(player, Sounds.TANGLEVINE_APPEAR_2316) + } + return@on true + } + } + + private fun hazelmereScroll(player: Player, item: Item) { + val id = item.id + openInterface(player, 222).also { + when (id) { + hazelmerescroll -> setInterfaceText(player, hazelmerescrollText.joinToString("
"), 222, 6) + } + } + } +} + diff --git a/Server/src/main/content/region/kandarin/quest/grandtree/HazelmereDialogue.kt b/Server/src/main/content/region/kandarin/quest/grandtree/HazelmereDialogue.kt new file mode 100644 index 0000000..ab59a6b --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/grandtree/HazelmereDialogue.kt @@ -0,0 +1,47 @@ +package content.region.kandarin.quest.grandtree + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.node.item.Item +import core.tools.END_DIALOGUE +import org.rs09.consts.Items + +class HazelmereDialogue : DialogueFile() { + + override fun handle(componentID: Int, buttonID: Int) { + when (getQuestStage(player!!, Quests.THE_GRAND_TREE)) { + 10 -> { + if(player!!.hasItem(Item(Items.BARK_SAMPLE_783))){ + when (stage) { + 0 -> sendDialogue(player!!,"The mage starts to speak but all you hear is").also { stage++ } + 1 -> npcl("Blah. Blah, blah, blah, blah...blah!").also { stage++ } + 2 -> sendDialogue(player!!,"You give the bark sample to Hazelmere. The mage carefully examines the sample.").also { stage++ } + 3 -> npcl("Blah, blah...Daconia...blah, blah.").also { stage++ } + 4 -> playerl("Can you write this down and I'll try and translate it?").also { stage++ } + 5 -> npcl("Blah, blah?").also { stage++ } + 6 -> sendDialogue(player!!,"You make a writing motion. The mages scribbles something down on a scroll. Hazelmere has given you the scroll.").also { + if(removeItem(player!!, Items.BARK_SAMPLE_783)){ + addItemOrDrop(player!!, Items.HAZELMERES_SCROLL_786) + } + setQuestStage(player!!, Quests.THE_GRAND_TREE, 20) + stage = END_DIALOGUE + } + } + } + } + 20 -> { + when (stage) { + 0 -> npcl("Blah, blah....Daconia...blah, blah.").also { stage++ } + 1 -> sendDialogue(player!!,"You still can't understand Hazelmere. The mage wrote it down for you on a scroll.").also { + if(!player!!.hasItem(Item(Items.HAZELMERES_SCROLL_786))){ + addItemOrDrop(player!!, Items.HAZELMERES_SCROLL_786) + } + stage = END_DIALOGUE + } + } + } + else -> npcl("Blah, blah...blah, blah.").also { stage = END_DIALOGUE } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/grandtree/KingNarnodeDialogue.kt b/Server/src/main/content/region/kandarin/quest/grandtree/KingNarnodeDialogue.kt new file mode 100644 index 0000000..5cbf678 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/grandtree/KingNarnodeDialogue.kt @@ -0,0 +1,507 @@ +package content.region.kandarin.quest.grandtree + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.interaction.MovementPulse +import core.game.node.entity.impl.PulseType +import core.game.node.item.Item +import core.game.node.scenery.Scenery +import core.game.node.scenery.SceneryBuilder +import core.game.system.task.Pulse +import core.game.world.GameWorld +import core.game.world.map.Direction +import core.game.world.map.Location +import core.game.world.map.RegionManager +import core.game.world.map.path.Pathfinder +import core.game.world.update.flag.context.Animation +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class KingNarnodeDialogue : DialogueFile() { + + val trapdoorLocation = Location(2464,3497,0) + val closedTrapDoor = Scenery(2446, Location(2463,3497,0), 22, 0) + val openedTrapDoor = Scenery(2445, Location(2463,3497,0), 22, 0) + val tunnels = Location(2464, 9897, 0) + val ladderClimbAnimation = Animation(828) + + fun leadDownLadder(){ + // Animate Narnode to walk to the trapdoor and climb the ladder + GameWorld.Pulser.submit(object : Pulse(0) { + var count = 0 + override fun pulse(): Boolean { + when (count) { + 0 -> { + forceWalk(player!!, trapdoorLocation, "SMART") + lock(player!!,10) + npc!!.pulseManager.run(object : MovementPulse(npc, player, Pathfinder.SMART) { + override fun pulse(): Boolean { + return false + } + }, PulseType.STANDARD) + npc!!.sendChat("Down here!") + SceneryBuilder.replace(closedTrapDoor,openedTrapDoor,10) + } + 4 -> { + player!!.faceLocation(trapdoorLocation.transform(Direction.WEST, 1)) + player!!.animator.animate(ladderClimbAnimation) + } + 5 -> { + teleport(player!!, tunnels) + npc!!.pulseManager.clear() + } + 7 -> { + // We are now underground + val undergroundNarnode = RegionManager.getNpc(player!!.location, NPCs.KING_NARNODE_SHAREEN_670, 16) + forceWalk(undergroundNarnode!!,player!!.location.transform(Direction.EAST,1), "SMART") + unlock(player!!) + openDialogue(player!!, KingNarnodeUnderGroundDialogue(), undergroundNarnode) + } + 10 -> return true + } + count++ + return false + } + }) + } + override fun handle(componentID: Int, buttonID: Int) { + when (getQuestStage(player!!, Quests.THE_GRAND_TREE)) { + 0 -> { + when (stage) { + 0 -> npcl("Welcome Traveller. I am King Narnode. It's nice to see an outsider.").also { stage++ } + 1 -> playerl("Hi! It seems to be a very busy settlement.").also{ stage++ } + 2 -> npcl("For now.").also { stage++ } + 3 -> options("You seem worried, what's up?","I'll be off now.").also { stage++ } + 4 -> when (buttonID) { + 1 -> playerl("You seem worried, what's up?").also { stage = 5 } + 2 -> playerl("I'll be off now.").also { stage = 25 } + } + 5 -> npcl("Traveller, can I speak to you in strictest confidence?").also { stage++ } + 6 -> playerl("Of course sire.").also { stage++ } + 7 -> npcl("Not here, follow me.").also { + stage = END_DIALOGUE + // Animate Narnode to walk to the trapdoor and climb the ladder + leadDownLadder() + } + 25 -> npcl("Enjoy your stay with us. There are many things to see in my kingdom.").also { stage = END_DIALOGUE } + } + } + 10 -> { + when (stage) { + 0 -> { + // Did the player destroy/drop the quest items + if(!player!!.hasItem(Item(Items.BARK_SAMPLE_783)) || !player!!.hasItem(Item(Items.TRANSLATION_BOOK_784))) { + npcl("You dropped something I gave you earlier. Please take better care of my thing!") + if(!player!!.hasItem(Item(Items.BARK_SAMPLE_783))) { + addItemOrDrop(player!!,Items.BARK_SAMPLE_783) + } + if(!player!!.hasItem(Item(Items.TRANSLATION_BOOK_784))) { + addItemOrDrop(player!!,Items.TRANSLATION_BOOK_784) + } + stage = END_DIALOGUE + } else { + npcl("Traveller, any word from Hazelmere?") + stage++ + } + } + 1 -> playerl("Not yet.").also { stage = END_DIALOGUE } + } + } + 20 -> { + when (stage) { + 0 -> npcl("Welcome Traveller. I am King Narnode. It's nice to see an outsider.").also { + // Reset correct answered options + setAttribute(player!!, "/save:grandtree:opt1", false) + setAttribute(player!!, "/save:grandtree:opt2", false) + setAttribute(player!!, "/save:grandtree:opt3", false) + stage++ + } + 1 -> playerl("Hello again, Your Highness.").also{ stage++ } + 2 -> npcl("Hello Traveller, did you speak to Hazelmere?").also { stage++ } + 3 -> playerl("Yes! I managed to find him.").also{ stage++ } + 4 -> npcl("Do you understand what he said?").also { stage++ } + 5 -> options("I think so!","No, I need to go back.").also { stage++ } + 6 -> when (buttonID) { + 1 -> playerl("I think so!").also { stage = 10 } + 2 -> playerl("No, I need to go back.").also { stage = END_DIALOGUE } + } + 10 -> npcl("So what did he say?").also { stage++ } + 11 -> options("King Narnode must be stopped, he is a madman!","Praise be to the great Zamorak!", "Do you have any bread? I do like bread.", "The time has come to attack!","None of the above.").also { stage++ } + 12 -> when (buttonID) { + 1 -> playerl("King Narnode must be stopped, he is a madman!").also { stage++ } + 2 -> playerl("Praise be to the great Zamorak!").also { stage++ } + 3 -> playerl("Do you have any bread? I do like bread.").also { stage++ } + 4 -> playerl("The time has come to attack!").also { stage++ } + 5 -> options("The tree is fine, you have nothing to fear.","You must come and see me!", "The tree needs watering as there has been drought.","Grave danger lies ahead, only the bravest will linger.","None of the above.").also { stage = 20 } + } + 13 -> options("The tree is fine, you have nothing to fear.","You must come and see me!", "The tree needs watering as there has been drought.","Grave danger lies ahead, only the bravest will linger.","None of the above.").also { stage = 20 } + 20 -> when (buttonID) { + 1 -> playerl("The tree is fine, you have nothing to fear.").also { stage++ } + 2 -> playerl("You must come and see me!").also { stage++ } + 3 -> playerl("The tree needs watering as there has been drought.").also { stage++ } + 4 -> playerl("Grave danger lies ahead, only the bravest will linger.").also { stage++ } + 5 -> options("Time is of the essence! We must move quickly.","There is no need for haste, just send a runner.", "A man came to me with the King's seal.","You must act now, or we will all die!","None of the above.").also { stage = 30 } + } + 21 -> options("Time is of the essence! We must move quickly.","There is no need for haste, just send a runner.", "Time passes us by.","You must act now, or we will all die!","None of the above.").also { stage = 31 } + // Right + 30 -> when (buttonID) { + 1 -> playerl("Time is of the essence! We must move quickly.").also { stage = 33 } + 2 -> playerl("There is no need for haste, just send a runner.").also { stage = 33 } + 3 -> playerl("A man came to me with the King's seal.").also { + setAttribute(player!!, "/save:grandtree:opt1", true) + stage = 32 + } + 4 -> playerl("You must act now, or we will all die!").also { stage = 33 } + 5 -> options("Only Adamantite is any use.","You must use force!", "Use a bucket of milk from a scared cow.","Take this banana to him, he will understand.","None of the above.").also { stage = 41 } + } + // Wrong + 31 -> when (buttonID) { + 1 -> playerl("Time is of the essence! We must move quickly.").also { stage = 33 } + 2 -> playerl("There is no need for haste, just send a runner.").also { stage = 33 } + 3 -> playerl("Time passes us by.").also { stage = 33 } + 4 -> playerl("You must act now, or we will all die!").also { stage = 33 } + 5 -> options("Only Adamantite is any use.","You must use force!", "Use a bucket of milk from a scared cow.","Take this banana to him, he will understand.","None of the above.").also { stage = 41 } + } + 32 -> options("I gave the man Daconia rocks.","You must use force!", "Use a bucket of milk from a scared cow.","Take this banana to him, he will understand.","None of the above.").also { stage = 40 } + 33 -> options("Only Adamantite is any use.","You must use force!", "Use a bucket of milk from a scared cow.","Take this banana to him, he will understand.","None of the above.").also { stage = 41 } + // Right + 40 -> when (buttonID) { + 1 -> playerl("I gave the man Daconia rocks.").also { + setAttribute(player!!, "/save:grandtree:opt2", true) + stage = 42 + } + 2 -> playerl("You must use force!").also { stage = 43 } + 3 -> playerl("Use a bucket of milk from a scared cow.").also { stage = 43 } + 4 -> playerl("Take this banana to him, he will understand.").also { stage = 43 } + 5 -> options("All with be fine on the third night.","You must wait till the second night.", "Nothing will help us now!","The tree will die in five days!").also { stage = 51 } + } + // Wrong + 41 -> when (buttonID) { + 1 -> playerl("Only Adamantite is any use.").also { stage = 43 } + 2 -> playerl("You must use force!").also { stage = 43 } + 3 -> playerl("Use a bucket of milk from a scared cow.").also { stage = 43 } + 4 -> playerl("Take this banana to him, he will understand.").also { stage = 43 } + 5 -> options("All with be fine on the third night.","You must wait till the second night.", "Nothing will help us now!","The tree will die in five days!").also { stage = 51 } + } + 42 -> options("All with be fine on the third night.","You must wait till the second night.", "Nothing will help us now!","And Daconia rocks will kill the tree!").also { stage = 50 } + 43 -> options("All with be fine on the third night.","You must wait till the second night.", "Nothing will help us now!","The tree will die in five days!").also { stage = 51 } + // Right + 50 -> when (buttonID) { + 1 -> playerl("All with be fine on the third night.").also { stage = 52 } + 2 -> playerl("You must wait till the second night.").also { stage = 52 } + 3 -> playerl("Nothing will help us now!").also { stage = 52 } + 4 -> playerl("And Daconia rocks will kill the tree!").also { + setAttribute(player!!, "/save:grandtree:opt3", true) + stage = 52 + } + } + // Wrong + 51 -> when (buttonID) { + 1 -> playerl("All with be fine on the third night.").also { stage++ } + 2 -> playerl("You must wait till the second night.").also { stage++ } + 3 -> playerl("Nothing will help us now!").also { stage++ } + 4 -> playerl("The tree will die in five days!").also { stage++ } + } + 52 -> { + if(getAttribute(player!!, "/save:grandtree:opt1", false) + && getAttribute(player!!, "/save:grandtree:opt2", false) + && getAttribute(player!!, "/save:grandtree:opt3", false)){ + npcl("Of course! I should've known! Someone must've forged my royal seal. Hazelmere thought I sent him for the Daconia stones!").also { stage = 60 } + } else { + npcl("Wait a minute! That doesn't sound like Hazelmere! Are you sure you translated correctly?").also { stage++ } + } + } + 53 -> playerl("Erm...I think so.").also { stage++ } + 54 -> npcl(" I'm sorry Traveller but this is no good. The translation must be perfect or the information's no use. Please come back when you know exactly what Hazelmere said.").also { stage = END_DIALOGUE } + 60 -> playerl("What are Daconia stones?").also { stage++ } + 61 -> npcl("Hazelmere created the Daconia stones. They are a safety measure, in case the tree grew out of control. They're the only thing that can kill the tree.").also { stage++ } + 62 -> npcl("This is terrible! The stones must be recovered!").also { stage++ } + 63 -> playerl("Can I help?").also { stage++ } + 64 -> npcl("First, I must warn the tree guardians. Please, could you tell the chief tree guardian, Glough. He lives in a tree house just in front of the Grand Tree.").also { stage++ } + 65 -> npcl("If he's not there he will be at his girlfriend Anita's place. Meet me back here once you've told him.").also { stage++ } + 66 -> playerl("Ok! I'll be back soon.").also { + setQuestStage(player!!, Quests.THE_GRAND_TREE, 40) + stage = END_DIALOGUE + } + } + } + 40 -> { + when(stage) { + 0 -> npcl("Hello Traveller, did you speak to Glough?").also { stage++ } + 1 -> playerl("Not yet.").also { stage++ } + 2 -> npcl("OK. He lives just in front of the Grand Tree. Let me know when you've talked to him.").also{ stage = END_DIALOGUE } + } + } + 45 -> { + when(stage) { + 0 -> playerl("Hello, Your Highness. Have you any news on the Daconia stones?").also { stage++ } + 1 -> npcl("It's OK Traveller, thanks to Glough! He found a human sneaking around! He had three Daconia rocks on him!").also { stage++ } + 2 -> playerl("Wow! That was quick!").also { stage++ } + 3 -> npcl("Yes Glough really knows what he's doing. The human has been detained until we know who else is involved. Maybe Glough was right, maybe humans are invading!").also { stage++ } + 4 -> playerl("I doubt it, can I speak to the prisoner?").also { stage++ } + 5 -> npcl("Certainly. He's on the top level of the tree. Be careful, it's a long way down!").also { + setQuestStage(player!!, Quests.THE_GRAND_TREE, 46) + stage = END_DIALOGUE + } + } + } + 46 -> { + when(stage){ + 0 -> npcl("Hello Traveller. If you wish to talk to the prisoner go to the top of the tree, you'll find him there.").also { stage++ } + 1 -> playerl("Thanks.").also { stage = END_DIALOGUE } + } + } + 55 -> { + when(stage){ + 0 -> playerl("King Narnode, I need to talk!").also { stage++ } + 1 -> npcl("Traveller, what are you doing here? The stronghold has been put on full alert! It's not safe for you here!").also { stage++ } + 2 -> playerl("Your Highness, I believe Glough is killing the trees in order to make a mass fleet of warships!").also { stage++ } + 3 -> npcl("That's an absurd accusation!").also { stage++ } + 4 -> playerl("His hatred for humanity is stronger than you know!").also { stage++ } + 5 -> npcl("That's enough Traveller, you sound as paranoid as him! Traveller please leave! It's bad enough having one human locked up.").also { stage = END_DIALOGUE } + } + } + 60 -> { + if(player!!.hasItem(Item(Items.INVASION_PLANS_794))){ + when(stage){ + 0 -> playerl("Hi, Your Highness, did you think about what I said?").also { stage++ } + 1 -> npcl("Look, if you're right about Glough I would have him arrested but there's no reason for me to think he's lying.").also { stage++ } + 2 -> playerl("Look, I found this at Glough's home!").also { stage++ } + 3 -> sendDialogue(player!!, "You give the King the invasion plans.").also { stage++ } + 4 -> npcl("If these are to be believed then this is terrible! But it's not proof, anyone could have made these. Traveller, I understand your concern.").also { stage++ } + 5 -> npcl("I had guards search Glough's house but they found nothing suspicious, just these odd twigs.").also { stage++ } + 6 -> sendDialogue(player!!, "The King has given you some twigs lashed together.").also{ + addItemOrDrop(player!!, Items.TWIGS_789) + addItemOrDrop(player!!, Items.TWIGS_790) + addItemOrDrop(player!!, Items.TWIGS_791) + addItemOrDrop(player!!, Items.TWIGS_792) + stage++ + } + 7 -> npcl("On the other hand, if Glough's right about the humans we will need an army of gnomes to protect ourselves. ").also { stage++ } + 8 -> npcl("So I've decided to allow Glough to raise a mighty gnome army. The Grand Tree's still slowly dying. If it is human sabotage we must respond!").also{ + setQuestStage(player!!, Quests.THE_GRAND_TREE, 70) + removeItem(player!!, Item(Items.INVASION_PLANS_794), Container.INVENTORY) + stage = END_DIALOGUE + } + } + } else { + when(stage){ + 0 -> playerl("Hello, Your Highness.").also { stage++ } + 1 -> npcl("Please Traveller, if the gnomes see me talking to you they'll revolt against me.").also { stage++ } + 2 -> playerl("That's crazy!").also { stage++ } + 3 -> npcl("Glough's scared the whole town, he expects the humans to attack any day. He's even begun to recruit hundreds of gnome soldiers.").also { stage++ } + 4 -> playerl("Don't you understand he's creating his own army?!").also { stage++ } + 5 -> npcl("Please Traveller, leave before it's too late!").also { stage = END_DIALOGUE } + } + } + } + 70 -> { + when(stage){ + 0 -> npcl("Please Traveller, take my advice and leave!").also { + if(!player!!.hasItem(Item(Items.TWIGS_789)) || !player!!.hasItem(Item(Items.TWIGS_790)) || !player!!.hasItem(Item(Items.TWIGS_791)) || !player!!.hasItem(Item(Items.TWIGS_792))) { + stage++ + } else { + stage = END_DIALOGUE + } + } + 1 -> playerl("I've lost those twigs you gave me.").also{ stage++ } + 2 -> { + if(player!!.inventory.freeSlots() < 4) { + npcl("Hmm. Looks like you can't carry anymore. Put 4 things down and come back to me.").also { stage = END_DIALOGUE } + } else { + npcl("King Narnode gives you 4 twigs.").also { + addItemOrDrop(player!!, Items.TWIGS_789) + addItemOrDrop(player!!, Items.TWIGS_790) + addItemOrDrop(player!!, Items.TWIGS_791) + addItemOrDrop(player!!, Items.TWIGS_792) + stage = END_DIALOGUE + } + } + } + } + } + 98,99 -> { + leadDownLadder() + } + 100 -> { + when (stage) { + 0 -> npcl("Thanks again for your help!").also { stage = END_DIALOGUE } + } + } + } + } +} + +class KingNarnodeUpstairsDialogue : DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + when(stage){ + 0 -> playerl("I don't think you can trust Glough, Your Highness. He seems to have an unnatural hatred for humans.").also { stage++ } + 1 -> npcl("I know he can be a bit extreme at times. But he's the best tree guardian I have, he has made the gnomes paranoid about humans though.").also { stage++ } + 2 -> npcl("I'm afraid Glough has placed guards on the front gate to stop you escaping! Let my glider pilot fly you away until things calm down around here.").also { stage++ } + 3 -> playerl("Well, OK.").also { stage++ } + 4 -> npcl("I'm sorry again Traveller!").also { stage = END_DIALOGUE } + } + } + +} + +class KingNarnodeUnderGroundDialogue : DialogueFile() { + private fun leadUpLadder(){ + val ladderLoc = Location.create(2464, 9897, 0) + val ladderClimbAnimation = Animation(828) + val ladderExit = Location.create(2464, 3497, 0) + GameWorld.Pulser.submit(object : Pulse(0) { + var count = 0 + override fun pulse(): Boolean { + when (count) { + 0 -> { + forceWalk(player!!, ladderLoc, "SMART") + lock(player!!,10) + npc!!.pulseManager.run(object : MovementPulse(npc, player, Pathfinder.SMART) { + override fun pulse(): Boolean { + return false + } + }, PulseType.STANDARD) + npc!!.sendChat("Up here!") + } + 4 -> { + player!!.faceLocation(ladderLoc.transform(Direction.WEST, 1)) + player!!.animator.animate(ladderClimbAnimation) + } + 5 -> { + teleport(player!!, ladderExit) + npc!!.pulseManager.clear() + unlock(player!!) + } + 10 -> return true + } + count++ + return false + } + }) + } + override fun handle(componentID: Int, buttonID: Int) { + when(getQuestStage(player!!, Quests.THE_GRAND_TREE)) { + 98 -> when (stage) { + 0 -> npcl("Traveller, you're wounded! What happened?").also { stage++ } + 1 -> playerl("It's Glough! He set a demon on me!").also { stage++ } + 2 -> npcl("What?! Glough?! With a demon?!").also { stage++ } + 3 -> playerl("Glough has a store of Daconia rocks further up the passage! He's been accessing the roots from a secret passage at his home.").also { stage++ } + 4 -> npcl("Never! Not Glough! He's a good gnome at heart! Guard!").also { stage++ } + 5 -> sendNPCDialogue(player!!, NPCs.GNOME_GUARD_163,"Sire!").also{ stage++ } + 6 -> npcl("Go and check out that passage!").also { stage++ } + 7 -> sendNPCDialogue(player!!, NPCs.GNOME_GUARD_163,"We found Glough hiding under a horde of Daconia rocks!").also{ stage++ } + 8 -> playerl("That's what I've been trying to tell you! Glough's been fooling you!").also { stage++ } + 9 -> npcl("I... I don't know what to say! How could I have been so blind?! Guard! Call off the military training! The humans are not attacking!").also { stage++ } + 10 -> sendNPCDialogue(player!!, NPCs.GNOME_GUARD_163,"Yes sir!").also{ stage++ } + 11 -> npcl("You have my full apologies Traveller! And my gratitude! A reward will have to wait though, the tree is still dying!").also {stage++} + 12 -> npcl("The guards are clearing Glough's rock supply now but there must be more Daconia hidden somewhere in the roots! Help us search, we have little time!").also { + setQuestStage(player!!, Quests.THE_GRAND_TREE, 99) + // position of the daconia rock + if(getAttribute(player!!,"treegnome:rock",0) == 0){ + val answer = (1..5).random() + setAttribute(player!!,"/save:treegnome:rock",answer) + } + stage = END_DIALOGUE + } + } + + 99 -> { + if(player!!.hasItem(Item(Items.DACONIA_ROCK_793))){ + when(stage){ + 0 -> npcl("Traveller, have you managed to find the Daconia?").also { stage++ } + 1 -> playerl("Is this it?").also { stage++ } + 2 -> npcl("Yes! Excellent, well done!").also { stage++ } + 3 -> sendDialogue(player!!,"You give the King the Daconia rock.").also { stage++ } + 4 -> npcl("It's incredible, the tree's health is improving already! I don't know what to say, we owe you so much! To think Glough had me fooled all along!").also { stage++ } + 5 -> playerl("All that matters now is that humans and gnomes can live together in peace!").also { stage++ } + 6 -> npcl("I'll drink to that! From now on I vow to make this stronghold a welcoming place for all! I'll grant you access to all our facilities.").also { stage++ } + 7 -> playerl("Thanks! I think!").also { stage++ } + 8 -> npcl("It should make your stay here easier. You can use the spirit tree to transport yourself, as well as the gnome glider. I also give you access to our mine.").also { stage++ } + 9 -> playerl("Mine?").also { stage++ } + 10 -> npcl("Very few know of the secret mine under the Grand Tree. If you push on the roots just to my north they will separate and let you pass.").also { stage++ } + 11 -> playerl("Strange!").also { stage++ } + 12 -> npcl("That's magic trees for you! All the best Traveller and thanks again!").also { stage++ } + 13 -> playerl("You too, Your Highness!").also { + finishQuest(player!!, Quests.THE_GRAND_TREE) + removeItem(player!!, Items.DACONIA_ROCK_793) + stage = END_DIALOGUE + } + } + } else { + when (stage) { + 0 -> npcl("Traveller, have you managed to find the Daconia?").also { stage++ } + 1 -> playerl("No sign of it so far.").also { stage++ } + 2 -> npcl("The tree will still die if we don't find it! It could be anywhere!").also { stage++ } + 3 -> playerl("Don't worry, Your Highness! We'll find it!").also { stage = END_DIALOGUE } + } + } + } + 100 -> { + when (stage) { + 0 -> npcl("Thanks again for your help!").also { stage = END_DIALOGUE } + } + } + + else -> when (stage) { + 0 -> npcl("Down here.").also { stage++ } + 1 -> playerl("So what is this place?").also { stage++ } + 2 -> npcl("These, my friend, are the foundations of the stronghold.").also { stage++ } + 3 -> playerl("They look like roots to me.").also { stage++ } + 4 -> npcl("Not just any roots Traveller! These were created by gnome mages eons ago, since then they have grown to become a mighty stronghold!").also { stage++ } + 5 -> playerl("Impressive. What exactly is the problem?").also { stage++ } + 6 -> npcl("In the last two months our tree guardians have reported continuing deterioration of the Grand Tree's health. I've never seen this before! It could be the end for us all!").also { stage++ } + 7 -> playerl("You mean the tree is ill?").also { stage++ } + 8 -> npcl(" In effect yes. Would you be willing to help us discover what is happening to the tree?").also { stage++ } + 9 -> options("I'm sorry, I don't want to get involved.", "I'd be happy to help!").also { stage++ } + 10 -> when (buttonID) { + 1 -> playerl("I'm sorry, I don't want to get involved.").also { stage = 15 } + 2 -> playerl("I'd be happy to help!").also { stage = 20 } + } + + 15 -> npcl("I understand Traveller. Please keep this to yourself.").also { stage++ } + 16 -> playerl("Of course.").also { stage++ } + 17 -> npcl("I'll show you the way back up.").also { stage++ } + 18 -> { + npcl("Up here.") + leadUpLadder() + stage = END_DIALOGUE + } + + 20 -> npcl("Thank Guthix for your arrival! The first task is to find out what's killing the tree.").also { stage++ } + 21 -> playerl("Do you have an idea?").also { stage++ } + 22 -> npcl("My top tree guardian, Glough, believes it's human sabotage. I'm not so sure! The only way to know for sure is to talk to Hazelmere.").also { stage++ } + 23 -> playerl("Who's Hazelmere?").also { stage++ } + 24 -> npcl("Hazelmere is one of the mages that created the Grand Tree. He is the only one that has survived from that time. Take this bark sample to him, he will be able to help!").also { stage++ } + 25 -> sendItemDialogue( + player!!, + Items.BARK_SAMPLE_783, + "The king shows you a sample of bark." + ).also { stage++ } + + 26 -> npcl("The mage only talks in the old tongue, you'll need this.").also { stage++ } + 27 -> sendItemDialogue( + player!!, + Items.TRANSLATION_BOOK_784, + "The king shows you a translation book." + ).also { stage++ } + + 28 -> playerl("What is it?").also { stage++ } + 29 -> npcl("It's a translation book, you'll need it to translate what Hazelmere says. Do that carefully! His words are our only hope!").also { stage++ } + 30 -> npcl("You'll find his dwellings high upon a towering hill, on an island east of Yanille. I'll show you the way back up.").also { stage++ } + 31 -> if (player!!.inventory.freeSlots() >= 2) { + npcl("Up here.") + stage = END_DIALOGUE + setQuestStage(player!!, Quests.THE_GRAND_TREE, 10) + addItemOrDrop(player!!, Items.BARK_SAMPLE_783) + addItemOrDrop(player!!, Items.TRANSLATION_BOOK_784) + leadUpLadder() + } else { + npcl("You don't have inventory space for my book or the bark! Clear some space and speak to me again") + }.also { stage = END_DIALOGUE } + } + } + } +} diff --git a/Server/src/main/content/region/kandarin/quest/grandtree/ShipyardWorkerDialogue.kt b/Server/src/main/content/region/kandarin/quest/grandtree/ShipyardWorkerDialogue.kt new file mode 100644 index 0000000..1487b30 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/grandtree/ShipyardWorkerDialogue.kt @@ -0,0 +1,118 @@ +package content.region.kandarin.quest.grandtree + +import content.data.Quests +import core.api.getAttribute +import core.api.getQuestStage +import core.api.setAttribute +import core.game.dialogue.DialogueFile +import core.game.global.action.DoorActionHandler +import core.game.node.scenery.Scenery +import core.game.world.map.Location +import core.tools.END_DIALOGUE + +class ShipyardWorkerDialogue : DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + when(stage){ + 0 -> npcl("Hey you! What are you up to?").also { + if(getQuestStage(player!!, Quests.THE_GRAND_TREE) == 55) { + setAttribute(player!!, "/save:grandtree:opt1", false) + setAttribute(player!!, "/save:grandtree:opt2", false) + setAttribute(player!!, "/save:grandtree:opt3", false) + } + stage++ + } + 1 -> playerl("I'm trying to open the gate!").also { stage++ } + 2 -> npcl("I can see that! Why?").also { stage++ } + 3 -> options("I'm from the Ministry of Health and Safety.","Glough sent me.","I'm just looking around.").also { stage++ } + 4 -> when(buttonID){ + 1 -> playerl("I'm from the Ministry of Health and Safety.").also { stage = 40} + 2 -> playerl("Glough sent me.").also{ stage = 50} + 3 -> playerl("I'm just looking around.").also { stage = 10 } + } + 10 -> playerl("I'm just looking around.").also { stage++ } + 11 -> npcl("This ain't a museum! Leave now!").also { stage++ } + 12 -> playerl("I'll leave when I choose!").also { stage++ } + 13 -> npcl("Well you're not on the list so you're not coming in. Go away.").also { stage++ } + 14 -> playerl("Well I'll just stand here then until you let me in.").also { stage++ } + 15 -> npcl("You do that!").also { stage++ } + 16 -> playerl("I will!").also { stage++ } + 17 -> npcl("Yeah?").also { stage++ } + 18 -> playerl("Yeah!").also { stage++ } + 19 -> npcl("...").also { stage++ } + 20 -> playerl("...").also { stage++ } + 21 -> playerl("So are you going to let me in then?").also { stage++ } + 22 -> npcl("No.").also { stage++ } + 23 -> playerl("...").also { stage++ } + 24 -> npcl("...").also { stage++ } + 25 -> playerl("You bored yet?").also { stage++ } + 26 -> npcl("No, I can stand here all day.").also { stage++ } + 27 -> playerl("...").also { stage++ } + 28 -> npcl("...").also { stage++ } + 29 -> playerl("Alright you win. I'll find another way in.").also { stage++ } + 30 -> npcl("No you won't.").also { stage++ } + 31 -> playerl("Yes I will.").also { stage++ } + 32 -> npcl("I'm not starting that again. Maybe if I ignore you you'll go away...").also { stage = + END_DIALOGUE + } + 40 -> npcl("Never 'erd of 'em.").also { stage++ } + 41 -> playerl("You will respect my authority!").also { stage++ } + 42 -> npcl("Get out of here before I give you a beating!").also { stage = END_DIALOGUE } + 50 -> npcl("Hmm... really? What for?").also { stage++ } + 51 -> playerl("You're wasting my time! Take me to your superior!").also { stage++ } + 52 -> npcl("OK. Password.").also { stage++ } + 53 -> options("Ka.","Ko.","Ke.").also { stage++ } + 54 -> when(buttonID){ + 1 -> playerl("Ka.").also { + setAttribute(player!!, "/save:grandtree:opt1", true) + stage++ + } + 2 -> playerl("Ko.").also { stage++ } + 3 -> playerl("Ke.").also { stage++ } + } + 55 -> options("Lo.","Lu.","Le.").also { stage++ } + 56 -> when(buttonID){ + 1 -> playerl("Lo.").also { stage++ } + 2 -> playerl("Lu.").also { + setAttribute(player!!, "/save:grandtree:opt2", true) + stage++ + } + 3 -> playerl("Le.").also { stage++ } + } + 57 -> options("Mon.","Min.","Men.").also { stage++ } + 58 -> when(buttonID){ + 1 -> playerl("Mon.").also { stage++ } + 2 -> playerl("Min.").also { + setAttribute(player!!, "/save:grandtree:opt3", true) + stage++ + } + 3 -> playerl("Men.").also { stage++ } + } + // Correct answer Ka-Lu-Min: + 59 -> { + if(getAttribute(player!!, "/save:grandtree:opt1", false) + && getAttribute(player!!, "/save:grandtree:opt2", false) + && getAttribute(player!!, "/save:grandtree:opt3", false) + ) { + DoorActionHandler.autowalkFence(player!!, Scenery(2438, Location(2945, 3041, 0)), 3727, 3728) + npcl("Sorry to have kept you.").also { stage = END_DIALOGUE } + } else { + npcl("You have no idea!").also { stage = END_DIALOGUE } + } + } + } + } +} + +class ShipyardWorkerGenericDialogue: DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + when(stage){ + 0 -> playerl("Hello.").also { stage++ } + 1 -> npcl("Hello matey!").also { stage++ } + 2 -> playerl("How are you?").also { stage++ } + 3 -> npcl("Tired!").also { stage++ } + 4 -> playerl("You shouldn't work so hard!").also { stage = END_DIALOGUE } + } + } + +} + diff --git a/Server/src/main/content/region/kandarin/quest/grandtree/TheGrandTree.kt b/Server/src/main/content/region/kandarin/quest/grandtree/TheGrandTree.kt new file mode 100644 index 0000000..c1b7400 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/grandtree/TheGrandTree.kt @@ -0,0 +1,99 @@ +package content.region.kandarin.quest.grandtree + +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.plugin.Initializable +import org.rs09.consts.Items +import content.data.Quests + +@Initializable +class TheGrandTree: Quest(Quests.THE_GRAND_TREE, 71, 70, 5, 150, 0, 1, 160) { + override fun newInstance(`object`: Any?): Quest { + return this + } + + override fun finish(player: Player?) { + super.finish(player) + player ?: return + var ln = 10 + player.packetDispatch.sendItemZoomOnInterface(Items.DACONIA_ROCK_793, 230, 277, 5) + drawReward(player,"5 Quest Points", ln++) + drawReward(player,"7900 Agility XP", ln++) + drawReward(player,"18,400 Attack XP", ln++) + drawReward(player,"2150 Magic XP", ln++) + player.skills.addExperience(Skills.AGILITY, 7900.0) + player.skills.addExperience(Skills.ATTACK, 18400.0) + player.skills.addExperience(Skills.MAGIC, 2150.0) + player.questRepository.syncronizeTab(player) + } + + override fun drawJournal(player: Player?, stage: Int) { + super.drawJournal(player, stage) + var line = 12 + player?: return + line(player, "I can start this quest at the !!Grand Tree?? in the !!Gnome??", line++, stage > 0) + line(player, "!!Stronghold?? by speaking to !!King Narnode Shareen.??", line++, stage > 0) + line++ + if(stage == 0) { + line(player, "I must have:", line++) + line(player, "!!Level 25 Agility.??", line++) + line(player, "!!High enough combat to defeat a level 172 demon.??", line++) + } + if(stage >= 10){ + line(player, "King Narnode Shareen suspects sabotage on the Grand Tree and", line++, stage > 10) + line(player, "wants to confirm it by consulting with Hazelmere.", line++, stage > 10) + line++ + line(player, "Hazelmere's dwelling is located on a towering hill, on an island ", line++, stage > 10) + line(player, "east of Yanille.", line++, stage > 10) + line++ + } + if(stage >= 20){ + line(player, "Report back to King Narnode Shareen.", line++, stage > 20) + line++ + } + if(stage >= 40){ + line(player, "King Narnode suspects that someone has forged his royal seal.", line++, stage > 40) + line(player, "Find Glough and notify him about the situation.", line++, stage > 40) + line++ + } + if(stage >= 45){ + line(player, "Glough says the humans are going to invade! Report back to the king.", line++, stage > 45) + line++ + } + if(stage >= 46){ + line(player, "Talk to the prisoner at the top of the tree", line++, stage > 46) + line++ + } + if(stage >= 47){ + line(player, "Search Glough's home for clues.", line++, stage > 47) + line++ + } + if(stage >= 55){ + line(player, "Glough has placed guards on the front gate to stop you escaping!", line++, stage > 55) + line(player, "Use King Narnode's glider pilot fly you away until things calm down.", line++, stage > 55) + if(player.hasItem(Item(Items.LUMBER_ORDER_787))){ + line(player, "Bring the lumber order to Charlie", line++, stage > 55) + } + line++ + + } + if(stage >= 60){ + line(player, "Search Glough's girlfriend's house for his chest keys.", line++, stage > 60) + } + if(stage >= 60){ + if(player.hasItem(Item(Items.GLOUGHS_KEY_788))){ + line(player, "Find a use for Gloughs key and report back to the king.", line++, stage > 60) + } + } + if(stage >= 70){ + line(player, "Find a use for the strange twigs from King Narnode Shareen.", line++, stage > 70) + } + if(stage == 100){ + line++ + line(player,"QUEST COMPLETE!", line) + } + } + +} diff --git a/Server/src/main/content/region/kandarin/quest/grandtree/TranslationBook.kt b/Server/src/main/content/region/kandarin/quest/grandtree/TranslationBook.kt new file mode 100644 index 0000000..a4c5c7b --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/grandtree/TranslationBook.kt @@ -0,0 +1,139 @@ +package content.region.kandarin.quest.grandtree + +import content.global.handlers.iface.BookInterface +import content.global.handlers.iface.BookLine +import content.global.handlers.iface.Page +import content.global.handlers.iface.PageSet +import core.api.setAttribute +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import org.rs09.consts.Items + +/** + * Translation Book handler for The Grand Tree quest + * + * @author crop & szu & ovenbreado + */ +class TranslationBook : InteractionListener { + companion object { + private val TITLE = "Translation Book" + private val CONTENTS = arrayOf( + PageSet( + Page( + BookLine("Gnome", 55), + BookLine("English translation", 56), + BookLine("written by Anita", 57), + BookLine("", 58), + BookLine("This text contains", 59), + BookLine("the ancient Gnome words", 60), + BookLine("I have managed to", 61), + BookLine("translate thus far.", 62), + BookLine("", 63), + ), + Page( + BookLine("-A-", 66), + BookLine("arpos: rocks", 67), + BookLine("ando: gate", 68), + BookLine("andra: city", 69), + BookLine("ataris: cow", 70), + BookLine("-C-", 71), + BookLine("cef: threat", 72), + BookLine("cheray: lazy", 73), + BookLine("Cinqo: King", 74), + BookLine("cretor: bucket", 75), + ) + ), + PageSet( + Page( + BookLine("-E-", 55), + BookLine("eis: me", 56), + BookLine("es: a", 57), + BookLine("et: and", 58), + BookLine("eto: will", 59), + BookLine("-G-", 60), + BookLine("gandius: jungle", 61), + BookLine("Gal: All", 62), + BookLine("gentis: leaf", 63), + BookLine("gutus: banana", 64), + BookLine("gomondo: branch", 65), + ), + Page( + BookLine("-H-", 66), + BookLine("har: old", 67), + BookLine("harij: harpoon", 68), + BookLine("hewo: grass", 69), + BookLine("", 70), + BookLine("-I-", 71), + BookLine("ip: you", 72), + BookLine("imindus: quest", 73), + BookLine("irno: translate", 74), + BookLine("", 75), + ) + ), + PageSet( + Page( + BookLine("-K-", 55), + BookLine("kar: no", 56), + BookLine("kai: boat", 57), + BookLine("ko: sail", 58), + BookLine("", 59), + BookLine("-L-", 60), + BookLine("lauf: eye", 61), + BookLine("laquinay: common sense", 62), + BookLine("lemanto: man", 63), + BookLine("lemantolly: stupid man", 64), + BookLine("lovos: gave", 65), + ), + Page( + BookLine("-M-", 66), + BookLine("meriz: kill", 67), + BookLine("mina: time(s)", 68), + BookLine("mos: coin", 69), + BookLine("mi: I", 70), + BookLine("mond: seal", 71), + BookLine("", 72), + ) + ), + PageSet( + Page( + BookLine("-P-", 55), + BookLine("por: long", 56), + BookLine("prit: with", 57), + BookLine("priw: tree", 58), + BookLine("pro: to", 59), + BookLine("", 60), + BookLine("-Q-", 61), + BookLine("Qui: guard", 62), + BookLine("Quir: guardian", 63), + BookLine("-R-", 64), + BookLine("rentos: agility", 65), + ), + Page( + BookLine("-S-", 66), + BookLine("sarko: Begone", 67), + BookLine("sind: big", 68), + BookLine("", 69), + BookLine("-T-", 70), + BookLine("ta: the", 71), + BookLine("tuzo: open", 72), + BookLine("-U-", 73), + BookLine("Undri: lands", 74), + BookLine("Umesco: Soul", 75), + ) + ) + ) + + private fun display(player:Player, pageNum: Int, buttonID: Int) : Boolean { + BookInterface.pageSetup(player, BookInterface.FANCY_BOOK_3_49, TITLE, CONTENTS) + return true + } + } + + override fun defineListeners() { + on(Items.TRANSLATION_BOOK_784, IntType.ITEM, "read") { player, _ -> + BookInterface.openBook(player, BookInterface.FANCY_BOOK_3_49, ::display) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/scorpioncatcher/SCPeksaDialogue.kt b/Server/src/main/content/region/kandarin/quest/scorpioncatcher/SCPeksaDialogue.kt new file mode 100644 index 0000000..79df6ce --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/scorpioncatcher/SCPeksaDialogue.kt @@ -0,0 +1,41 @@ +package content.region.kandarin.quest.scorpioncatcher + +import core.api.setQuestStage +import core.game.dialogue.DialogueFile +import core.game.dialogue.Topic +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import content.data.Quests + +class SCPeksaDialogue(val questStage: Int) : DialogueFile() { + + companion object { + const val ASK_ABOUT_SCORPION = START_DIALOGUE + const val ASK_FOR_HELP = 20 + const val THANK_YOU = 30 + + } + + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + // Word wrap issues + ASK_ABOUT_SCORPION -> npc("Now how could you know about that, I wonder?", "Mind you, I don't have it anymore.").also { stage++ } + ASK_ABOUT_SCORPION + 1 -> npcl(" I gave it as a present to my brother Ivor when I visited our outpost in the west.").also { stage++ } + ASK_ABOUT_SCORPION + 2 -> npcl("Well, actually I hid it in his bed so it would nip him. It was a bit of a surprise gift.").also { stage++ } + + ASK_ABOUT_SCORPION + 3 -> showTopics( + Topic("So where is this outpost?", ASK_FOR_HELP), + Topic("Thanks for the information", THANK_YOU, true) + ) + + ASK_FOR_HELP -> npcl("Its a fair old trek to the west, across the White Wolf Mountains. Then head west, north-west until you see the axes and horned helmets.").also { stage= + THANK_YOU } + + THANK_YOU -> { + playerl("Thanks for the information").also { stage++ } + setQuestStage(player!!, Quests.SCORPION_CATCHER, ScorpionCatcher.QUEST_STATE_PEKSA_HELP) + } + THANK_YOU + 1 -> npcl ("No problems! Tell Ivor I said hi!").also { stage = END_DIALOGUE } + } + } +} diff --git a/Server/src/main/content/region/kandarin/quest/scorpioncatcher/SCSeerDialogue.kt b/Server/src/main/content/region/kandarin/quest/scorpioncatcher/SCSeerDialogue.kt new file mode 100644 index 0000000..a15b267 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/scorpioncatcher/SCSeerDialogue.kt @@ -0,0 +1,79 @@ +package content.region.kandarin.quest.scorpioncatcher + +import content.region.kandarin.seers.dialogue.SeerDialogue +import core.api.sendDialogue +import core.api.setQuestStage +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import content.data.Quests + +class SCSeerDialogue(val questStage: Int, private val dialogueEntry: Int) : DialogueFile() { + + companion object { + const val FIRST_SCORPION_HELP = 20 + const val FIRST_SCORPION_THORMAC = 30 + const val FIRST_SCORPION_GUIDE = 40 + const val OTHER_SCORPIONS = 50 + + + // There are many ways that this dialogue can be entered + const val ENTRY_HELP = SeerDialogue.SC_QUEST_HELP + const val ENTRY_FRIEND = SeerDialogue.SC_QUEST_FRIEND + const val ENTRY_OTHERS = SeerDialogue.SC_QUEST_OTHER_SCORPIONS + + } + + + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + START_DIALOGUE -> when (dialogueEntry){ + ENTRY_HELP -> npcl("Well you have come to the right place. I am a master of animal detection.").also { stage = FIRST_SCORPION_HELP } + ENTRY_FRIEND -> npcl(FacialExpression.NEUTRAL, "What does the old fellow want?").also { stage = FIRST_SCORPION_THORMAC } + // word wrap doesn't work again + ENTRY_OTHERS -> npc(FacialExpression.NEUTRAL, "Well, I've checked my looking glass. There seems to be", + "a kharid scorpion in a little village to the east,", + "surrounded by lots of uncivilized-looking warriors.", + "Some kind of merchant there seems to have picked it up.").also { stage = OTHER_SCORPIONS } + else -> { + println("Invalid entry to SCSeerDialogue $dialogueEntry") + end() + } + } + + FIRST_SCORPION_THORMAC -> playerl( + FacialExpression.NEUTRAL, + "He's lost his valuable lesser Kharid scorpions." + ).also { stage++ } + FIRST_SCORPION_THORMAC + 1 -> npcl( + FacialExpression.HAPPY, + "Well you have come to the right place. I am a master of animal detection." + ).also { stage = FIRST_SCORPION_GUIDE } + + FIRST_SCORPION_HELP -> npcl("Do you need to locate any particular scorpion? Scorpions are a creature somewhat in abundance.").also { stage++ } + FIRST_SCORPION_HELP + 1 -> playerl("I'm looking for some lesser Kharid scorpions. They belong to Thormac the Sorcerer.").also { + stage = FIRST_SCORPION_GUIDE + } + + FIRST_SCORPION_GUIDE -> npcl(FacialExpression.HAPPY, "Let me look into my looking glass.").also { stage++ } + FIRST_SCORPION_GUIDE + 1 -> sendDialogue(player!!, "The Seer produces a small mirror.").also { stage++ } + FIRST_SCORPION_GUIDE + 2 -> sendDialogue(player!!, "The Seer gazes into the mirror.").also { stage++ } + FIRST_SCORPION_GUIDE + 3 -> sendDialogue(player!!, "The Seer smooths his hair with his hand.").also { stage++ } + FIRST_SCORPION_GUIDE + 4 -> npcl("I can see a scorpion that you seek. It would appear to be near some nasty spiders. I can see two coffins there as well.").also { stage++ } + FIRST_SCORPION_GUIDE + 5 -> npcl("The scorpion seems to be going through some crack in the wall. Its gone into some sort of secret room.").also { stage++ } + FIRST_SCORPION_GUIDE + 6 -> npcl("Well see if you can find the scorpion then, and I'll try and get you some information on the others.").also { + setQuestStage(player!!, Quests.SCORPION_CATCHER, ScorpionCatcher.QUEST_STATE_DARK_PLACE) + stage = END_DIALOGUE + } + + OTHER_SCORPIONS -> npcl ("That's all I can tell about that scorpion.").also { stage++ } + OTHER_SCORPIONS + 1 -> playerl("Any more scorpions?").also { stage++ } + OTHER_SCORPIONS + 2 -> npcl ("It's good that you should ask. I have information on the last scorpion for you.").also { stage++ } + OTHER_SCORPIONS + 3 -> npcl ("It seems to be in some sort of upstairs room. There seems to be some sort of brown clothing lying on a table.").also { + setQuestStage(player!!, Quests.SCORPION_CATCHER, ScorpionCatcher.QUEST_STATE_OTHER_SCORPIONS) + stage = END_DIALOGUE + } + } + } +} diff --git a/Server/src/main/content/region/kandarin/quest/scorpioncatcher/SCThormacDialogue.kt b/Server/src/main/content/region/kandarin/quest/scorpioncatcher/SCThormacDialogue.kt new file mode 100644 index 0000000..bd4b91b --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/scorpioncatcher/SCThormacDialogue.kt @@ -0,0 +1,133 @@ +package content.region.kandarin.quest.scorpioncatcher + +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import core.ServerConstants +import core.api.* +import core.game.dialogue.Topic +import core.game.node.item.Item +import org.rs09.consts.Items +import content.data.Quests + +class SCThormacDialogue(val questStage: Int) : DialogueFile() { + + companion object { + const val ASK_FOR_HELP = 10 + const val HOW_TO_CATCH = 30 + const val WHY_SHOULD_I_START = 50 + + const val WAITING_FOR_SCORPIONS = 100 + const val GIVE_ANOTHER_CAGE = 110 + + const val GOT_THEM_ALL = 200 + const val FULL_INVENTORY = 300 + } + + + override fun handle(componentID: Int, buttonID: Int) { + when (stage){ + START_DIALOGUE -> if (questStage == 0) { + npcl(FacialExpression.FRIENDLY, "Hello I am Thormac the Sorcerer, " + + "I don't suppose you could be of assistance to me?").also { stage = ASK_FOR_HELP } + } + else { + npcl(FacialExpression.NEUTRAL, "How goes your quest?").also { + stage = if (hasAnItem(player!!, Items.SCORPION_CAGE_463).exists()){ + // Player has all the scorpions caught + GOT_THEM_ALL + } else { + WAITING_FOR_SCORPIONS + } + } + } + + ASK_FOR_HELP -> showTopics( + Topic(FacialExpression.HAPPY,"What do you need assistance with?", ASK_FOR_HELP+1), + Topic(FacialExpression.NEUTRAL, "I'm a little busy.", END_DIALOGUE) + ) + ASK_FOR_HELP+1 -> npcl(FacialExpression.WORRIED, " I've lost my pet scorpions. " + + "They're lesser Kharid scorpions, a very rare breed.").also { stage++ } + ASK_FOR_HELP+2 -> npcl(FacialExpression.WORRIED, "I left their cage door open, now I don't know where they've gone.").also { stage++ } + ASK_FOR_HELP+3 -> npcl(FacialExpression.WORRIED, "There's three of them, and they're quick little beasties. " + + "They're all over " + ServerConstants.SERVER_NAME + ".").also { stage++ } + ASK_FOR_HELP+4 -> showTopics( + Topic(FacialExpression.ASKING, "So how would I go about catching them then?", HOW_TO_CATCH), + Topic(FacialExpression.ASKING, "What's in it for me?", WHY_SHOULD_I_START), + Topic(FacialExpression.NEUTRAL, "I'm not interested then.", END_DIALOGUE) + ) + + WHY_SHOULD_I_START -> npcl(FacialExpression.WORRIED, "Well I suppose I can aid you with my skills as a staff sorcerer. " + + "Most battlestaffs around here are a bit puny. I can beef them up for you a bit.").also { + // Need to recheck the quest stage since it may have been changed in this dialogue + if(getQuestStage(player!!, Quests.SCORPION_CATCHER) == 0) stage++ + else stage = END_DIALOGUE + } + WHY_SHOULD_I_START+1 -> showTopics( + Topic(FacialExpression.ASKING, "So how would I go about catching them then?", HOW_TO_CATCH), + Topic(FacialExpression.NEUTRAL, "I'm not interested then.", END_DIALOGUE) + ) + + HOW_TO_CATCH -> npcl(FacialExpression.WORRIED, "Well I have a scorpion cage here which you can " + + "use to catch them in.").also { + if (hasSpaceFor(player!!,Item(Items.SCORPION_CAGE_456))) stage++ + else stage = FULL_INVENTORY + } + HOW_TO_CATCH+1 -> { + sendItemDialogue(player!!, Items.SCORPION_CAGE_456, "Thormac gives you a cage.").also { stage++ } + startQuest(player!!, Quests.SCORPION_CATCHER) + addItem(player!!, Items.SCORPION_CAGE_456) + } + HOW_TO_CATCH+2 -> npcl(FacialExpression.WORRIED, "If you go up to the village of Seers, to the North of " + + "here, one of them will be able to tell you where the scorpions are now.").also { stage++ } + HOW_TO_CATCH+3 -> showTopics( + Topic(FacialExpression.ASKING, "What's in it for me?", WHY_SHOULD_I_START), + Topic(FacialExpression.NEUTRAL, "Ok, I will do it then.", END_DIALOGUE ) + ) + + + WAITING_FOR_SCORPIONS -> { + if (!hasAnItem(player!!, arrayOf(Items.SCORPION_CAGE_456, Items.SCORPION_CAGE_457, Items.SCORPION_CAGE_458, + Items.SCORPION_CAGE_459, Items.SCORPION_CAGE_460, Items.SCORPION_CAGE_461, + Items.SCORPION_CAGE_462), false).exists()){ + playerl(FacialExpression.SAD, "I've lost my cage.").also { stage = GIVE_ANOTHER_CAGE } + } + else{ + playerl(FacialExpression.NEUTRAL, "I've not caught all the scorpions yet.").also { stage++ } + } + } + WAITING_FOR_SCORPIONS+1 -> npcl(FacialExpression.WORRIED, "Well remember to go speak to the Seers" + + " North of here, if you need any help.").also { stage = END_DIALOGUE } + + GIVE_ANOTHER_CAGE -> { + player!!.inventory.add(Item(Items.SCORPION_CAGE_456)) + // Clear all attributes keeping track of the scorpions + player!!.removeAttribute("scorpion_catcher:caught_taverly") + player!!.removeAttribute("scorpion_catcher:caught_barb") + player!!.removeAttribute("scorpion_catcher:caught_monk") + npcl(FacialExpression.NEUTRAL, "Ok, here's another cage. You're almost as bad" + + " at losing things as me.").also { stage = END_DIALOGUE } + } + + GOT_THEM_ALL -> { + playerl ("I have retrieved all your scorpions.").also { stage++ } + } + GOT_THEM_ALL+1 ->{ + npcl(FacialExpression.HAPPY, "Aha, my little scorpions home at last!").also { stage++ } + player!!.inventory.remove(Item(Items.SCORPION_CAGE_463)) + + // Don't need to keep track of which scorpions have been caught anymore + player!!.removeAttribute("scorpion_catcher:caught_taverly") + player!!.removeAttribute("scorpion_catcher:caught_barb") + player!!.removeAttribute("scorpion_catcher:caught_monk") + } + GOT_THEM_ALL+2 ->{ + end().also { finishQuest(player!!, Quests.SCORPION_CATCHER) } + } + + + FULL_INVENTORY -> npcl("You don't have space to hold a cage").also { stage = END_DIALOGUE } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/scorpioncatcher/SCWallListener.kt b/Server/src/main/content/region/kandarin/quest/scorpioncatcher/SCWallListener.kt new file mode 100644 index 0000000..864f2ce --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/scorpioncatcher/SCWallListener.kt @@ -0,0 +1,37 @@ +package content.region.kandarin.quest.scorpioncatcher + +import core.api.getQuestStage +import core.api.sendMessage +import core.game.global.action.DoorActionHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.world.map.Location +import org.rs09.consts.Scenery +import content.data.Quests + +class SCWallListener : InteractionListener { + + override fun defineListeners() { + on(Scenery.OLD_WALL_2117, IntType.SCENERY, "search"){ player, node -> + // You can only go through if you are doing the quest + //https://youtu.be/crc-47rwjvE?feature=shared&t=841 + // Otherwise the crack reverts back to normal + // Doesn't make any sense but that's authentic... + if ((ScorpionCatcher.QUEST_STATE_DARK_PLACE .. 99).contains(getQuestStage(player, Quests.SCORPION_CATCHER))) { + // Check what side the player is on and teleport them to the other + if (player.location == Location(2875, 9799, 0)){ + sendMessage(player, "You've found a secret door") + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } + else{ + // We're leaving the room + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } + } + else{ + sendMessage(player, "You search the wall but find nothing.") + } + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/scorpioncatcher/ScorpionCatcher.kt b/Server/src/main/content/region/kandarin/quest/scorpioncatcher/ScorpionCatcher.kt new file mode 100644 index 0000000..ba9cc40 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/scorpioncatcher/ScorpionCatcher.kt @@ -0,0 +1,148 @@ +package content.region.kandarin.quest.scorpioncatcher + +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import org.rs09.consts.Items +import content.data.Quests + +@Initializable +class ScorpionCatcher : Quest(Quests.SCORPION_CATCHER, 108, 107, 1, 76, 0, 1, 6) { + companion object { + const val QUEST_STATE_NOT_STARTED = 0 + const val QUEST_STATE_TALK_SEERS = 10 + const val QUEST_STATE_DARK_PLACE = 20 + const val QUEST_STATE_OTHER_SCORPIONS = 30 + const val QUEST_STATE_PEKSA_HELP = 40 + const val QUEST_STATE_DONE = 100 + + const val ATTRIBUTE_TAVERLY = "scorpion_catcher:caught_taverly" + const val ATTRIBUTE_BARB = "scorpion_catcher:caught_barb" + const val ATTRIBUTE_MONK = "scorpion_catcher:caught_monk" + + } + + override fun newInstance(`object`: Any?): Quest { + return this + } + + override fun drawJournal(player: Player?, stage: Int) { + super.drawJournal(player, stage) + + var ln = 12 + + val caughtTaverly = player!!.getAttribute(ATTRIBUTE_TAVERLY, false) + val caughtBarb = player.getAttribute(ATTRIBUTE_BARB, false) + val caughtMonk = player.getAttribute(ATTRIBUTE_MONK, false) + + if (stage == QUEST_STATE_NOT_STARTED){ + line(player, "I can start this quest by speaking to !!Thormac?? who is in the", ln++) + line(player, "!!Sorcerer's Tower?? south-west of !!Catherby??", ln++) + ln++ //blank line + line(player, "Requirements:", ln++) + line(player, "Level 31 Prayer", ln, player.skills.staticLevels[Skills.PRAYER] >= 31) + } else { + line(player, "I've spoken to Thormac in the Sorcerer's Tower south-west", ln++, true) + line(player, "of Catherby. He's lost his pet Kharid Scorpions and needs", ln++, true) + line(player, "my help to find them.", ln++, true) + + // 10 -> 20 + if (stage >= QUEST_STATE_DARK_PLACE) { + ln++ + line(player, "I've spoken to a Seer and been given the location of one", ln++, true) + line(player, "of the Kharid Scorpions.", ln++, true) + } else if (stage >= QUEST_STATE_TALK_SEERS) { + ln++ + line(player, "I need to go to the !!Seers' Village?? and talk to the !!Seer??", ln++) + line(player, "about the lost !!Kharid Scorpions??.", ln++) + } + + // 20 -> 20 + 1st Scorpion + if (stage >= QUEST_STATE_DARK_PLACE && caughtTaverly || stage >= QUEST_STATE_OTHER_SCORPIONS) { + ln++ + line(player, "The first Kharid Scorpion is in a secret room near some", ln++, true) + line(player, "nasty spiders with two coffins nearby.", ln++, true) + } else if (stage >= QUEST_STATE_DARK_PLACE) { + ln++ + line(player, "The first !!Kharid Scorpion?? is in a secret room near some", ln++) + line(player, "!!nasty spiders?? with two !!coffins?? nearby.", ln++) + // Jan 21, 2010 version has a slightly updated but similar location. +// line(player, "The first !!Kharid Scorpion?? is in a !!dark place between a lake??", ln++) +// line(player, "and a !!holy island??. It will be close when you enter.", ln++) + ln++ + line(player, "I'll need to talk to a !!Seer?? again one I've caught the first", ln++) + line(player, "!!Kharid Scorpion??.", ln++) + } + + // 20 + 1st Scorpion -> 30 + if (stage >= QUEST_STATE_OTHER_SCORPIONS) { + // This line disappears when the you talk to the Seer again. + } else if (stage >= QUEST_STATE_DARK_PLACE && caughtTaverly){ + // Todo check this line + ln++ + line(player, "I should go back to the Seer and ask about the other", ln++) + line(player, "scorpions.", ln++) + } + + // 30 -> 40 + if (stage >= QUEST_STATE_OTHER_SCORPIONS){ + ln++ + val barb_strike = caughtBarb || (stage == QUEST_STATE_PEKSA_HELP) + line(player, "The second !!Kharid Scorpion?? has been in a !!village of??", ln++, barb_strike || stage == QUEST_STATE_DONE) + line(player, "!!uncivilised-looking warriors in the east??. It's been picked up", ln++, barb_strike || stage == QUEST_STATE_DONE) + line(player, "by some sort of !!merchant??.", ln++, barb_strike || stage == QUEST_STATE_DONE) + // Jan 21, 2010 version has a slightly updated but similar location. +// line(player, "The second !!Kharid Scorpion?? was once in a !!village two??", ln++, barb_strike || stage == QUEST_STATE_DONE) +// line(player, "!!canoe trips from lumbridge??. A !!shopkeeper?? there picked it up.", ln++, barb_strike || stage == QUEST_STATE_DONE) + if (stage == QUEST_STATE_PEKSA_HELP){ + // todo check this block + ln++ + line(player, "I spoke with !!Peksa?? who said he sent it to his brother", ln++, caughtBarb) + line(player, "at the !!Barbarian outpost.??", ln++, caughtBarb) + } + ln++ + line(player, "The third !!Kharid Scorpion?? is in some sort of !!upstairs room??", ln++, caughtMonk || stage == QUEST_STATE_DONE) + line(player, "with !!brown clothing on a table??.", ln++, caughtMonk || stage == QUEST_STATE_DONE) + // Jan 21, 2010 version has a slightly updated but similar location. +// line(player, "The third !!Kharid Scorpion?? is in an !!upstairs room?? with !!brown??", ln++, caughtMonk || stage == QUEST_STATE_DONE) +// line(player, "!!clothing on a table?? The clothing is adorned with a golden", ln++, caughtMonk || stage == QUEST_STATE_DONE) +// line(player, "four-pointed star. You should start looking where monks", ln++, caughtMonk || stage == QUEST_STATE_DONE) +// line(player, "reside.", ln++, caughtMonk || stage == QUEST_STATE_DONE) + } + + // 40 -> 100 + if (stage == QUEST_STATE_DONE) { + // This line disappears when you complete the quest. + } else if (caughtBarb && caughtTaverly && caughtMonk && stage >= QUEST_STATE_OTHER_SCORPIONS){ + ln++ + line(player, "I need to take the !!Kharid Scorpions?? to !!Thormac??.", ln) + } + + // 100 + if (stage == QUEST_STATE_DONE) { + ln++ + line(player, "I've spoken to Thormac and he thanked me for finding his", ln++, true) + line(player, "pet Kharid Scorpions.", ln++, true) + ln++ + ln++ + line(player, "QUEST COMPLETE!", ln) + return + } + + } + } + + override fun finish(player: Player?) { + var ln = 10 + super.finish(player) + player!!.packetDispatch.sendString("You have completed the Scorpion Catcher Quest!", 277, 4) + player.packetDispatch.sendItemZoomOnInterface(Items.SCORPION_CAGE_463, 240, 277, 5) + + drawReward(player, "1 Quest Point", ln++) + drawReward(player, "6625 Strength XP", ln) + + player.skills.addExperience(Skills.STRENGTH, 6625.0) + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/scorpioncatcher/ScorpionCatcherUseListener.kt b/Server/src/main/content/region/kandarin/quest/scorpioncatcher/ScorpionCatcherUseListener.kt new file mode 100644 index 0000000..8759e24 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/scorpioncatcher/ScorpionCatcherUseListener.kt @@ -0,0 +1,342 @@ +package content.region.kandarin.quest.scorpioncatcher + +import content.region.kandarin.quest.scorpioncatcher.ScorpionCatcher.Companion.ATTRIBUTE_TAVERLY +import content.region.kandarin.quest.scorpioncatcher.ScorpionCatcher.Companion.ATTRIBUTE_BARB +import content.region.kandarin.quest.scorpioncatcher.ScorpionCatcher.Companion.ATTRIBUTE_MONK +import core.api.addItem +import core.game.node.item.Item +import core.api.removeItem +import core.api.runTask +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.system.config.NPCConfigParser +import core.game.world.GameWorld +import org.rs09.consts.Items +import org.rs09.consts.NPCs + + +class ScorpionCatcherUseListener : InteractionListener { + + override fun defineListeners() { + /** + * List of cages + * Talvery Barbarian Monk + * TBM + * 456 --- + * 457 O-- + * 458 00- + * 459 -0- + * 460 -00 + * 461 --0 + * 462 0-0 + * 463 000 + * + * Scorpions + * 385 - Barbarian + * 386 - Taverly + * 387 - Monastery + */ + + /** + * Good captures + */ + + /** + * Empty cage on Taverly scorpion + */ + + // todo check this message + val haveAlready = "You already have this scorpion in this cage." + val catchMessage = "You catch a scorpion!" + + onUseWith(IntType.NPC, Items.SCORPION_CAGE_456, NPCs.KHARID_SCORPION_386){ player, used, with -> + removeItem(player, Item(used.id, 1)) + addItem(player, Items.SCORPION_CAGE_457) + player.sendMessage(catchMessage) + // This is the first time taverly has been caught + if (!player.getAttribute(ATTRIBUTE_TAVERLY, false)){ + player.setAttribute("/save:$ATTRIBUTE_TAVERLY", true) + } + runTask(player, 2) { + with.asNpc().respawnTick = + GameWorld.ticks + with.asNpc().definition.getConfiguration(NPCConfigParser.RESPAWN_DELAY, 34) + } + return@onUseWith true + } + /** + * Barbarian cage on Taverly scorpion + */ + onUseWith(IntType.NPC, Items.SCORPION_CAGE_459, NPCs.KHARID_SCORPION_386){ player, used, with -> + removeItem(player, Item(used.id, 1)) + addItem(player, Items.SCORPION_CAGE_458) + player.sendMessage(catchMessage) + // This is the first time taverly has been caught + if (!player.getAttribute(ATTRIBUTE_TAVERLY, false)){ + player.setAttribute("/save:$ATTRIBUTE_TAVERLY", true) + } + runTask(player, 2) { + with.asNpc().respawnTick = + GameWorld.ticks + with.asNpc().definition.getConfiguration(NPCConfigParser.RESPAWN_DELAY, 34) + } + return@onUseWith true + } + /** + * Monk cage on Taverly scorpion + */ + onUseWith(IntType.NPC, Items.SCORPION_CAGE_461, NPCs.KHARID_SCORPION_386){ player, used, with -> + removeItem(player, Item(used.id, 1)) + addItem(player, Items.SCORPION_CAGE_462) + player.sendMessage(catchMessage) + // This is the first time taverly has been caught + if (!player.getAttribute(ATTRIBUTE_TAVERLY, false)){ + player.setAttribute("/save:$ATTRIBUTE_TAVERLY", true) + } + runTask(player, 2) { + with.asNpc().respawnTick = + GameWorld.ticks + with.asNpc().definition.getConfiguration(NPCConfigParser.RESPAWN_DELAY, 34) + } + return@onUseWith true + } + /** + * Others on Taverly scorpion + */ + onUseWith(IntType.NPC, Items.SCORPION_CAGE_460, NPCs.KHARID_SCORPION_386){ player, used, with -> + removeItem(player, Item(used.id, 1)) + addItem(player, Items.SCORPION_CAGE_463) + player.sendMessage(catchMessage) + // This is the first time taverly has been caught + if (!player.getAttribute(ATTRIBUTE_TAVERLY, false)){ + player.setAttribute("/save:$ATTRIBUTE_TAVERLY", true) + } + runTask(player, 2) { + with.asNpc().respawnTick = + GameWorld.ticks + with.asNpc().definition.getConfiguration(NPCConfigParser.RESPAWN_DELAY, 34) + } + return@onUseWith true + } + + /** + * Empty cage on barbarian agility course scorpion + */ + onUseWith(IntType.NPC, Items.SCORPION_CAGE_456, NPCs.KHARID_SCORPION_385){ player, used, with -> + removeItem(player, Item(used.id, 1)) + addItem(player, Items.SCORPION_CAGE_459) + player.sendMessage(catchMessage) + // This is the first time barbarian has been caught + if (!player.getAttribute(ATTRIBUTE_BARB, false)){ + player.setAttribute("/save:$ATTRIBUTE_BARB", true) + } + runTask(player, 2) { + with.asNpc().respawnTick = + GameWorld.ticks + with.asNpc().definition.getConfiguration(NPCConfigParser.RESPAWN_DELAY, 34) + } + return@onUseWith true + } + /** + * Cage with Taverly scorpion on barbarian scorpion + */ + onUseWith(IntType.NPC, Items.SCORPION_CAGE_457, NPCs.KHARID_SCORPION_385) { player, used, with -> + removeItem(player, Item(used.id, 1)) + addItem(player, Items.SCORPION_CAGE_458) + player.sendMessage(catchMessage) + // This is the first time barbarian has been caught + if (!player.getAttribute(ATTRIBUTE_BARB, false)){ + player.setAttribute("/save:$ATTRIBUTE_BARB", true) + } + runTask(player, 2) { + with.asNpc().respawnTick = + GameWorld.ticks + with.asNpc().definition.getConfiguration(NPCConfigParser.RESPAWN_DELAY, 34) + } + return@onUseWith true + } + /** + * Cage with Monk scorpion on barbarian scorpion + */ + onUseWith(IntType.NPC, Items.SCORPION_CAGE_461, NPCs.KHARID_SCORPION_385) { player, used, with -> + removeItem(player, Item(used.id, 1)) + addItem(player, Items.SCORPION_CAGE_460) + player.sendMessage(catchMessage) + // This is the first time barbarian has been caught + if (!player.getAttribute(ATTRIBUTE_BARB, false)){ + player.setAttribute("/save:$ATTRIBUTE_BARB", true) + } + runTask(player, 2) { + with.asNpc().respawnTick = + GameWorld.ticks + with.asNpc().definition.getConfiguration(NPCConfigParser.RESPAWN_DELAY, 34) + } + return@onUseWith true + } + + /** + * Others on barbarian scorpion + */ + onUseWith(IntType.NPC, Items.SCORPION_CAGE_462, NPCs.KHARID_SCORPION_385) { player, used, with -> + removeItem(player, Item(used.id, 1)) + addItem(player, Items.SCORPION_CAGE_463) + player.sendMessage(catchMessage) + // This is the first time barbarian has been caught + if (!player.getAttribute(ATTRIBUTE_BARB, false)){ + player.setAttribute("/save:$ATTRIBUTE_BARB", true) + } + runTask(player, 2) { + with.asNpc().respawnTick = + GameWorld.ticks + with.asNpc().definition.getConfiguration(NPCConfigParser.RESPAWN_DELAY, 34) + } + return@onUseWith true + } + + + /** + * Empty on Monk scorpion + */ + onUseWith(IntType.NPC, Items.SCORPION_CAGE_456, NPCs.KHARID_SCORPION_387) { player, used, with -> + removeItem(player, Item(used.id, 1)) + addItem(player, Items.SCORPION_CAGE_461) + player.sendMessage(catchMessage) + // This is the first time the monastery has been caught + if (!player.getAttribute(ATTRIBUTE_MONK, false)){ + player.setAttribute("/save:$ATTRIBUTE_MONK", true) + } + runTask(player, 2) { + with.asNpc().respawnTick = + GameWorld.ticks + with.asNpc().definition.getConfiguration(NPCConfigParser.RESPAWN_DELAY, 34) + } + return@onUseWith true + } + + /** + * Taverly cage on Monk scorpion + */ + onUseWith(IntType.NPC, Items.SCORPION_CAGE_457, NPCs.KHARID_SCORPION_387) { player, used, with -> + removeItem(player, Item(used.id, 1)) + addItem(player, Items.SCORPION_CAGE_462) + player.sendMessage(catchMessage) + // This is the first time the monastery has been caught + if (!player.getAttribute(ATTRIBUTE_MONK, false)){ + player.setAttribute("/save:$ATTRIBUTE_MONK", true) + } + runTask(player, 2) { + with.asNpc().respawnTick = + GameWorld.ticks + with.asNpc().definition.getConfiguration(NPCConfigParser.RESPAWN_DELAY, 34) + } + return@onUseWith true + } + + /** + * Barbarian cage on Monk scorpion + */ + onUseWith(IntType.NPC, Items.SCORPION_CAGE_459, NPCs.KHARID_SCORPION_387) { player, used, with -> + removeItem(player, Item(used.id, 1)) + addItem(player, Items.SCORPION_CAGE_460) + player.sendMessage(catchMessage) + // This is the first time the monastery has been caught + if (!player.getAttribute(ATTRIBUTE_MONK, false)){ + player.setAttribute("/save:$ATTRIBUTE_MONK", true) + } + runTask(player, 2) { + with.asNpc().respawnTick = + GameWorld.ticks + with.asNpc().definition.getConfiguration(NPCConfigParser.RESPAWN_DELAY, 34) + } + return@onUseWith true + } + + /** + * Others on Monk scorpion + */ + onUseWith(IntType.NPC, Items.SCORPION_CAGE_458, NPCs.KHARID_SCORPION_387) { player, used, with -> + removeItem(player, Item(used.id, 1)) + addItem(player, Items.SCORPION_CAGE_463) + player.sendMessage(catchMessage) + // This is the first time the monastery has been caught + if (!player.getAttribute(ATTRIBUTE_MONK, false)){ + player.setAttribute("/save:$ATTRIBUTE_MONK", true) + } + runTask(player, 2) { + with.asNpc().respawnTick = + GameWorld.ticks + with.asNpc().definition.getConfiguration(NPCConfigParser.RESPAWN_DELAY, 34) + } + return@onUseWith true + } + + + /** + * Player being stupid and trying to recatch one they have already + */ + + /** + * Taverly + */ + // Just Taverly + onUseWith(IntType.NPC, Items.SCORPION_CAGE_457, NPCs.KHARID_SCORPION_386){ player, _, _ -> + player.sendMessage(haveAlready) + return@onUseWith true + } + // Taverly and Barb + onUseWith(IntType.NPC, Items.SCORPION_CAGE_458, NPCs.KHARID_SCORPION_386){ player, _, _ -> + player.sendMessage(haveAlready) + return@onUseWith true + } + // Taverly and Monk + onUseWith(IntType.NPC, Items.SCORPION_CAGE_462, NPCs.KHARID_SCORPION_386){ player, _, _ -> + player.sendMessage(haveAlready) + return@onUseWith true + } + // All + onUseWith(IntType.NPC, Items.SCORPION_CAGE_463, NPCs.KHARID_SCORPION_386){ player, _, _ -> + player.sendMessage(haveAlready) + return@onUseWith true + } + + + /** + * Barbarian + */ + // Just Barb + onUseWith(IntType.NPC, Items.SCORPION_CAGE_459, NPCs.KHARID_SCORPION_385){ player, _, _ -> + player.sendMessage(haveAlready) + return@onUseWith true + } + // Barb and Taverly + onUseWith(IntType.NPC, Items.SCORPION_CAGE_458, NPCs.KHARID_SCORPION_385){ player, _, _ -> + player.sendMessage(haveAlready) + return@onUseWith true + } + // Barb and Monk + onUseWith(IntType.NPC, Items.SCORPION_CAGE_460, NPCs.KHARID_SCORPION_385){ player, _, _ -> + player.sendMessage(haveAlready) + return@onUseWith true + } + // All + onUseWith(IntType.NPC, Items.SCORPION_CAGE_463, NPCs.KHARID_SCORPION_385){ player, _, _ -> + player.sendMessage(haveAlready) + return@onUseWith true + } + + /** + * Monastery + */ + // Just Monk + onUseWith(IntType.NPC, Items.SCORPION_CAGE_461, NPCs.KHARID_SCORPION_387){ player, _, _ -> + player.sendMessage(haveAlready) + return@onUseWith true + } + // Monk and Taverly + onUseWith(IntType.NPC, Items.SCORPION_CAGE_462, NPCs.KHARID_SCORPION_387){ player, _, _ -> + player.sendMessage(haveAlready) + return@onUseWith true + } + // Monk and Barb + onUseWith(IntType.NPC, Items.SCORPION_CAGE_460, NPCs.KHARID_SCORPION_387){ player, _, _ -> + player.sendMessage(haveAlready) + return@onUseWith true + } + // All + onUseWith(IntType.NPC, Items.SCORPION_CAGE_463, NPCs.KHARID_SCORPION_387){ player, _, _ -> + player.sendMessage(haveAlready) + return@onUseWith true + } + + } + + +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/templeofikov/BridgeAgility.kt b/Server/src/main/content/region/kandarin/quest/templeofikov/BridgeAgility.kt new file mode 100644 index 0000000..f2b9e83 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/templeofikov/BridgeAgility.kt @@ -0,0 +1,37 @@ +package content.region.kandarin.quest.templeofikov + +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.combat.ImpactHandler +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders + +class BridgeAgility: MapArea { + companion object { + private fun checkWeightOrFailBridge(entity: Entity) { + // If player weighs more than 0kg at any point on the bridge, the bridge breaks. + // The boots of lightness may be needed here as it makes the player -4kg lighter. + if (entity is Player && entity.settings.weight > 0) { + entity.impactHandler.manualHit(entity, 20, ImpactHandler.HitsplatType.NORMAL) + sendMessage(entity, "The bridge gives way under your weight!") + sendChat(entity, "Ow! Hot! Hot!") + sendMessage(entity, "Good thing that lava was shallow!") + entity.teleport(Location.create(2647, 9826, 0)) + } + } + } + + override fun defineAreaBorders(): Array { + return arrayOf(ZoneBorders(2648, 9828, 2649, 9829)) + } + override fun areaEnter(entity: Entity) { + checkWeightOrFailBridge(entity) + } + override fun areaLeave(entity: Entity, logout: Boolean) { + checkWeightOrFailBridge(entity) + } + override fun entityStep(entity: Entity, location: Location, lastLocation: Location) { + checkWeightOrFailBridge(entity) + } +} diff --git a/Server/src/main/content/region/kandarin/quest/templeofikov/FireWarriorOfLesarkusDialogue.kt b/Server/src/main/content/region/kandarin/quest/templeofikov/FireWarriorOfLesarkusDialogue.kt new file mode 100644 index 0000000..2272e2e --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/templeofikov/FireWarriorOfLesarkusDialogue.kt @@ -0,0 +1,37 @@ +package content.region.kandarin.quest.templeofikov + +import core.game.dialogue.* +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class FireWarriorOfLesarkusDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return FireWarriorOfLesarkusDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage) { + START_DIALOGUE -> npcl(FacialExpression.ANGRY, "Who dares to enter the Temple of Ikov!").also { stage++ } + 1 -> showTopics( + Topic(FacialExpression.ANGRY, "A mighty hero!", 2), + Topic(FacialExpression.FRIENDLY, "A humble pilgrim.", 4), + ) + 2 -> npcl(FacialExpression.ANGRY, "Pathetic fool! Prepare to die!").also { stage++ } + 3 -> { + npc!!.attack(player) + end() + } + 4 -> npcl(FacialExpression.ANGRY, "I haven't seen a pilgrim for thousands of years!").also { stage++ } + 5 -> npcl(FacialExpression.ANGRY, "Temple is closed!").also { + stage = END_DIALOGUE + } + } + return false + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.FIRE_WARRIOR_OF_LESARKUS_277) + } +} diff --git a/Server/src/main/content/region/kandarin/quest/templeofikov/FireWarriorOfLesarkusNPC.kt b/Server/src/main/content/region/kandarin/quest/templeofikov/FireWarriorOfLesarkusNPC.kt new file mode 100644 index 0000000..5dbcbb4 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/templeofikov/FireWarriorOfLesarkusNPC.kt @@ -0,0 +1,73 @@ +package content.region.kandarin.quest.templeofikov + +import content.data.Quests +import core.api.* +import core.game.dialogue.FacialExpression +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.player.Player +import core.game.world.map.Location +import org.rs09.consts.NPCs + +class FireWarriorOfLesarkusNPC(id: Int = 0, val player: Player?, location: Location? = null) : AbstractNPC(id, location) { + var clearTime = 0 + // Technically not constructed this way since this is invoked on load. + override fun construct(id: Int, location: Location, vararg objects: Any): AbstractNPC { + return FireWarriorOfLesarkusNPC(id, null, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.FIRE_WARRIOR_OF_LESARKUS_277) + } + + override fun handleTickActions() { + super.handleTickActions() + // You have 240 ticks to kill this guy or touch the door again. + if (clearTime++ > 240) { + removeAttribute(player!!, TempleOfIkov.attributeWarriorInstance) + poofClear(this) + } + } + + override fun isAttackable(entity: Entity, style: CombatStyle, message: Boolean): Boolean { + val attackable = super.isAttackable(entity, style, message) + val player = entity.asPlayer() + //attributeWarriorInstance + return attackable + } + + override fun checkImpact(state: BattleState) { + super.checkImpact(state) + val player = state.attacker.asPlayer() + val opponent = this + println(state.ammunition) + if (state.ammunition != null && state.ammunition.itemId == 78) { + // Only ice arrows will damage warrior. + } else { + // If it is the wrong combat or ammunition, deny all damage. + player.properties.combatPulse.stop() + if (state.estimatedHit > -1) { + state.estimatedHit = 0 + } + if (state.secondaryHit > -1) { + state.secondaryHit = 0 + } + runTask(player, 0) { + sendNPCDialogue(player, opponent.id, "Your puny weapons do nothing against me human! Come back when you can give me a real fight!", FacialExpression.ANGRY) + } + } + } + + override fun finalizeDeath(entity: Entity) { + if (entity is Player) { + val player = entity.asPlayer() + removeAttribute(player, TempleOfIkov.attributeWarriorInstance) + if(getQuestStage(player, Quests.TEMPLE_OF_IKOV) == 3) { + setQuestStage(player, Quests.TEMPLE_OF_IKOV, 4) + } + super.finalizeDeath(player) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/templeofikov/GuardianOfArmadylBehavior.kt b/Server/src/main/content/region/kandarin/quest/templeofikov/GuardianOfArmadylBehavior.kt new file mode 100644 index 0000000..846c520 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/templeofikov/GuardianOfArmadylBehavior.kt @@ -0,0 +1,31 @@ +package content.region.kandarin.quest.templeofikov + +import content.data.Quests +import core.api.isQuestComplete +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.tools.RandomFunction +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class GuardianOfArmadylBehavior : NPCBehavior(*guardianOfArmadylIds) { + companion object { + private val guardianOfArmadylIds = intArrayOf( + NPCs.GUARDIAN_OF_ARMADYL_274, + NPCs.GUARDIAN_OF_ARMADYL_275 + ) + } + + override fun onDropTableRolled(self: NPC, killer: Entity, drops: ArrayList) { + super.onDropTableRolled(self, killer, drops) + // Drops Pendant of Armadyl after quest complete when killed. + if (killer is Player && isQuestComplete(killer, Quests.TEMPLE_OF_IKOV)) { + if(RandomFunction.roll(4)) { + drops.add(Item(Items.ARMADYL_PENDANT_87)) + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/templeofikov/GuardianOfArmadylDialogue.kt b/Server/src/main/content/region/kandarin/quest/templeofikov/GuardianOfArmadylDialogue.kt new file mode 100644 index 0000000..c890062 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/templeofikov/GuardianOfArmadylDialogue.kt @@ -0,0 +1,164 @@ +package content.region.kandarin.quest.templeofikov + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class GuardianOfArmadylDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return GuardianOfArmadylDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, GuardianOfArmadylDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.GUARDIAN_OF_ARMADYL_274, NPCs.GUARDIAN_OF_ARMADYL_275) + } +} + +class GuardianOfArmadylDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onPredicate { _ -> true } + .branch { player -> + return@branch if (inEquipment(player, Items.PENDANT_OF_LUCIEN_86)) { 1 } else { 0 } + }.let{ branch -> + // Failure branch + branch.onValue(1) + .npcl("Thou is a foul agent of Lucien! Such an agent must die!") + .endWith { _, player -> + npc!!.attack(player) + } + return@let branch // Return DialogueBranchBuilder instead of DialogueBuilder to forward the success branch. + }.onValue(0) // Success branch + .npcl("Thou hast ventured deep into the tunnels, you have reached the temple of our master. It is many ages since a pilgrim has come here.") + .options() + .let { optionBuilder -> + val returnJoin = b.placeholder() + + optionBuilder.option("I seek the Staff of Armadyl.") + .playerl(FacialExpression.FRIENDLY, "I seek the Staff of Armadyl.") + .npcl(FacialExpression.FRIENDLY, "We are the guardians of the staff, our fathers were guardians and our fathers' fathers before that. Why dost thou seek it?") + .options() + .let { optionBuilder2 -> + optionBuilder2.option_playerl("Lucien will give me a grand reward for it!") + .npcl(FacialExpression.FRIENDLY, "Thou art working for that spawn of evil?! Fool! You must be cleansed to save your soul!") + .goto(returnJoin) + optionBuilder2.option_playerl("Give it to me!") + .npcl(FacialExpression.FRIENDLY, "The staff is sacred! You will not have it!") + .endWith { _, player -> + npc!!.attack(player) + } + optionBuilder2.option_playerl("I collect rare and powerful artefacts.") + .npcl(FacialExpression.FRIENDLY, "Your worldly greed has darkened your soul!") + .endWith { _, player -> + npc!!.attack(player) + } + } + + optionBuilder.option_playerl("Out of my way fool!") + .npcl(FacialExpression.FRIENDLY, "I may be a fool but I will not step aside!") + .options() + .let { optionBuilder2 -> + optionBuilder2.option_playerl("Why not?!") + .npcl(FacialExpression.FRIENDLY, "Only members of our order are allowed to handle the staff.") + .end() + optionBuilder2.option_playerl("Then you must die!") + .endWith { _, player -> + npc!!.attack(player) + } + optionBuilder2.option_playerl("You're right, I will go now.") + .npcl(FacialExpression.FRIENDLY, "That is a wise decision. Stay a while and let your soul be cleansed!") + .end() + } + + optionBuilder.option_playerl("What are your kind and what are you doing here?") + .npcl(FacialExpression.FRIENDLY, "We are the Guardians of Armadyl. We have kept the temple safe for many ages. The evil in the dungeons seek what lies here. The Mahjarrat are the worst.") + .options() + .let { optionBuilder2 -> + optionBuilder2.option_playerl("What is the Armadyl?") + .npcl(FacialExpression.FRIENDLY, "Armadyl is the god we serve. We have been charged with guarding his sacred artifacts until he requires them.") + .options() + .let { optionBuilder3 -> + optionBuilder3.option_playerl("Ah ok, thanks.") + .npcl(FacialExpression.FRIENDLY, "Go in peace.") + .end() + optionBuilder3.option("Someone told me there were only three gods.") + .playerl(FacialExpression.FRIENDLY, "Someone told me there were only three gods. Saradomin, Zamorak and Guthix.") + .npcl(FacialExpression.FRIENDLY, "Saradominists. Bleh. They only acknowledge those three. There are at least twenty gods!") + .end() + } + + optionBuilder2.option_playerl("Who are the Mahjarrat?") + .npcl(FacialExpression.FRIENDLY, "They are ancient and powerful beings! They are very evil! It is said that they once dominated this plane of existence, Zamorak was supposedly of their blood. They are far fewer in number now.") + .npcl(FacialExpression.FRIENDLY, "Some still have presence in this world in their liche forms. Mahjarrat such as Lucien and Azzanadra would become very powerful if they came into possession of the Staff of Armadyl.") + .options() + .let { optionBuilder3 -> + optionBuilder3.option("Did you say Lucien?") + .playerl(FacialExpression.FRIENDLY, "Did you say Lucien? It was Lucien that asked me to get the staff!") + .npcl(FacialExpression.FRIENDLY, "You are a fool to be working for Lucien! Your soul must be cleansed to save you!") + .goto(returnJoin) + optionBuilder3.option_playerl("I hope you're doing a good job then!") + .npcl(FacialExpression.FRIENDLY, "Do not fear! We are devoted to our charge!") + .end() + } + + optionBuilder2.option_playerl("Wow! You must be really old!") + .npcl(FacialExpression.ANGRY, "No! I am not old! My family has guarded the staff for many generations.") + .end() + } + return@let returnJoin.builder() + } // continue the path here for Lucien.options() + .options() + .let { optionBuilder -> + optionBuilder.option("How dare you call me a fool!") + .playerl(FacialExpression.ANGRY, "How dare you call me a fool! I will work for whom I want!") + .npcl(FacialExpression.ANGRY, "We must cleanse the temple!") + .endWith { _, player -> + npc!!.attack(player) + } + optionBuilder.option_playerl("I just thought of something I must do!") + .npcl(FacialExpression.ANGRY, "An agent of evil cannot be allowed to leave!") + .endWith { _, player -> + npc!!.attack(player) + } + optionBuilder.option_playerl("You're right, it's time for my yearly bath.") + .line("The guardian splashes holy water over you.") + .npcl(FacialExpression.FRIENDLY, "You have been cleansed!") + .npcl(FacialExpression.FRIENDLY, "Lucien must not get hold of the staff! He would become too powerful!") + .npcl(FacialExpression.FRIENDLY, "Hast thou come across the undead necromancer? It was he that raised an army of the undead against Varrock a generation ago. If you know where he is you can help us defeat him.") + .options() + .let { optionBuilder2 -> + optionBuilder2.option_playerl("Ok! I'll help!") + .npcl(FacialExpression.FRIENDLY, "So he is close by?") + .playerl(FacialExpression.FRIENDLY, "Yes!") + .npcl(FacialExpression.FRIENDLY, "He must be gaining in power again. If you can defeat him he will be banished from this plane for a while. You will need this pendant to attack him.") + .item(Items.ARMADYL_PENDANT_87, "The guardian has given you a pendant.") + .endWith { _, player -> + setAttribute(player, TempleOfIkov.attributeChosenEnding, 1) + if (getQuestStage(player, Quests.TEMPLE_OF_IKOV) == 5) { + setQuestStage(player, Quests.TEMPLE_OF_IKOV, 6) + } + addItemOrDrop(player, Items.ARMADYL_PENDANT_87) + } + optionBuilder2.option_playerl("No! I shall not turn against my employer!") + .npcl(FacialExpression.ANGRY, "Fool! You will die for your sins!") + .endWith { _, player -> + npc!!.attack(player) + } + optionBuilder2.option_playerl("I need time to think.") + .npcl(FacialExpression.FRIENDLY, "Linger a while and be at peace.") + .end() + } + } + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/templeofikov/LucienDialogue.kt b/Server/src/main/content/region/kandarin/quest/templeofikov/LucienDialogue.kt new file mode 100644 index 0000000..c093d13 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/templeofikov/LucienDialogue.kt @@ -0,0 +1,121 @@ +package content.region.kandarin.quest.templeofikov + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class LucienDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return LucienDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, LucienDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.LUCIEN_273) + } +} + +class LucienDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onQuestStages(Quests.TEMPLE_OF_IKOV, 100) + .playerl("I thought I killed you?!") + .npcl("Ha! Ha! Ha!") + .npcl("You can not kill me human!") + .branch { player -> + return@branch if (inInventory(player, Items.PENDANT_OF_LUCIEN_86)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(1) + .end() + branch.onValue(0) + .playerl("I've lost the pendant you gave me.") + .npcl("Have another, it will remind you of my power!") + .betweenStage { df, player, _, _ -> + addItemOrDrop(player, Items.PENDANT_OF_LUCIEN_86) + } + .item(Items.PENDANT_OF_LUCIEN_86, "Lucien has given you another pendant!") + .end() + } + b.onQuestStages(Quests.TEMPLE_OF_IKOV, 1, 2, 3, 4, 5, 6, 7) + .npcl("I told you not to meet me here again!") + .branch { player -> + return@branch if (inInventory(player, Items.PENDANT_OF_LUCIEN_86)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(1) + .playerl("Sorry! Can you remind me of my mission?") + .npcl("My patience grows thin hero!") + .npcl("I need the Staff of Armadyl. It's in the Temple of Ikov, near Hemenster, north east of here.") + .playerl("I'm up for it!") + .end() + branch.onValue(0) + .playerl("I've lost the pendant you gave me.") + .npcl("Imbecile!") + .betweenStage { df, player, _, _ -> + addItemOrDrop(player, Items.PENDANT_OF_LUCIEN_86) + } + .item(Items.PENDANT_OF_LUCIEN_86, "Lucien has given you another pendant!") + .end() + } + + b.onQuestStages(Quests.TEMPLE_OF_IKOV, 0) + .npcl("I seek a hero to go on an important mission!") + .options().let { optionBuilder -> + val returnJoin = b.placeholder() + optionBuilder.option("I'm a mighty hero!") + .playerl(FacialExpression.ANGRY, "I'm a mighty hero!") + .goto(returnJoin) + optionBuilder.option_playerl("Yep, lots of heros about these days.") + .npcl("Well, if you see any be sure to point them in my direction.") + .end() + return@let returnJoin.builder() + } + .npcl("I require the Staff of Armadyl. It is in the deserted Temple of Ikov, near Hemenster, north east of here.") + .npcl("Take care hero! There is a dangerous monster somewhere in the temple!") + .let{ builder -> + val returnJoin = b.placeholder() + returnJoin.builder() + .options() + .let { optionBuilder -> + optionBuilder.option_playerl("Why can't you get it yourself?") + .npcl("The guardians of the Staff of Armadyl fear me!") + .npcl("They have set up a magical barrier which even my power cannot overcome!") + .goto(returnJoin) + optionBuilder.option("That sounds like a laugh!") + .playerl(FacialExpression.FRIENDLY, "That sounds like a laugh!") + .npcl("It's not as easy as it sounds. The monster can only be killed with a weapon of ice. There are many other dangers.") + .playerl(FacialExpression.FRIENDLY, "I'm up for it!") + .npcl("Take this pendant. Without it you will not be enter the Chamber of Fear.") + .betweenStage { df, player, _, _ -> + addItemOrDrop(player, Items.PENDANT_OF_LUCIEN_86) + } + .item(Items.PENDANT_OF_LUCIEN_86, "Lucien has given you a pendant!") + .npcl("I cannot stay here much longer. ") + .npcl("I will be west of the Grand Exchange in Varrock. I have a small holding up there.") + .endWith { _, player -> + if (getQuestStage(player, Quests.TEMPLE_OF_IKOV) == 0) { + setQuestStage(player, Quests.TEMPLE_OF_IKOV, 1) + } + } + optionBuilder.option_playerl("Oh no! Sounds far too dangerous!") + .npcl("Wimp! Call yourself a hero?! My daughter is more a hero than you!") + .end() + optionBuilder.option_playerl("What's the reward?!") + .npcl("I see you are the mercenary type.") + .playerl("It's a living.") + .npcl("I will reward you well if you bring me the staff.") + .goto(returnJoin) + return@let optionBuilder + } + return@let builder.goto(returnJoin) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/templeofikov/LucienEndingDialogue.kt b/Server/src/main/content/region/kandarin/quest/templeofikov/LucienEndingDialogue.kt new file mode 100644 index 0000000..2ba1dd6 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/templeofikov/LucienEndingDialogue.kt @@ -0,0 +1,65 @@ +package content.region.kandarin.quest.templeofikov + +import content.data.Quests +import core.api.* +import core.game.dialogue.* +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class LucienEndingDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return LucienEndingDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, LucienEndingDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.LUCIEN_272) + } +} + +class LucienEndingDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onQuestStages(Quests.TEMPLE_OF_IKOV, 100) + .endWith { _, player -> + // After quest is over: https://www.youtube.com/watch?v=81DXjfsFcMM + sendMessage(player, "You feel that fighting this individual will be of little practical use.") + sendMessage(player, "You have completed the Temple of Ikov quest.") + } + b.onQuestStages(Quests.TEMPLE_OF_IKOV, 1, 2, 3, 4, 5, 6, 7) + .npcl(FacialExpression.FRIENDLY, "Have you got the Staff of Armadyl yet?") + .branch { player -> + return@branch if (inInventory(player, Items.STAFF_OF_ARMADYL_84)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(1) + .options() + .let { optionBuilder -> + optionBuilder.option_playerl("Yes! Here it is.") + .betweenStage { _, player, _, _ -> + removeItem(player, Items.STAFF_OF_ARMADYL_84) + } + .iteml(Items.STAFF_OF_ARMADYL_84, "You give Lucien the Staff of Armadyl.") + .npcl(FacialExpression.FRIENDLY, "Muhahahhahahaha!") + .npcl(FacialExpression.FRIENDLY, "I can feel the power of the staff running through me! I will be more powerful and they shall bow down to me!") + .npcl(FacialExpression.FRIENDLY, "I suppose you want your reward? I shall grant you much power!") + .endWith { _, player -> + if(getQuestStage(player, Quests.TEMPLE_OF_IKOV) == 6) { + finishQuest(player, Quests.TEMPLE_OF_IKOV) + } + } + optionBuilder.option_playerl("No, not yet.") + .end() + } + branch.onValue(0) + .playerl(FacialExpression.FRIENDLY, "No, not yet.") + .end() + } + b.onPredicate { _ -> true } + .npcl("Not here. Meet me at the Flying Horse Inn in East Ardougne.") + .end() + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/templeofikov/LucienEndingNPC.kt b/Server/src/main/content/region/kandarin/quest/templeofikov/LucienEndingNPC.kt new file mode 100644 index 0000000..18e8e42 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/templeofikov/LucienEndingNPC.kt @@ -0,0 +1,55 @@ +package content.region.kandarin.quest.templeofikov + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.node.entity.Entity +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class LucienEndingNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id, location) { + override fun construct(id: Int, location: Location, vararg objects: Any): AbstractNPC { + return LucienEndingNPC(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.LUCIEN_272) + } + + override fun isAttackable(entity: Entity, style: CombatStyle, message: Boolean): Boolean { + val attackable = super.isAttackable(entity, style, message) + val player = entity.asPlayer() + if (inEquipment(player, Items.ARMADYL_PENDANT_87)) { + return attackable + } + sendNPCDialogue(player, this.ids[0], "You don't want to attack me. I am your friend.") + return false + } + + override fun finalizeDeath(entity: Entity) { + if (entity is Player) { + val player = entity.asPlayer() + openDialogue(player, object : DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + when(stage){ + 0 -> npcl("You have defeated me for now! I shall reappear in the North!").also { stage++ } + 1 -> end().also { + if(getQuestStage(player, Quests.TEMPLE_OF_IKOV) == 6) { + finishQuest(player, Quests.TEMPLE_OF_IKOV) + } + } + } + } + }, NPC(NPCs.LUCIEN_272)) + + super.finalizeDeath(player) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/templeofikov/TempleOfIkov.kt b/Server/src/main/content/region/kandarin/quest/templeofikov/TempleOfIkov.kt new file mode 100644 index 0000000..ebfc477 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/templeofikov/TempleOfIkov.kt @@ -0,0 +1,203 @@ +package content.region.kandarin.quest.templeofikov + +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import org.rs09.consts.Items +import content.data.Quests + +/** + * Temple of Ikov Quest + * + * This is the quest where the journal after completion is a barren wasteland of a useless log. + * One of the worst logs I've ever had the pleasure/pain of doing. + * + * 1 - Talked to Lucien (Lucien pendant) + * 2 - Entered chamber of fear (North Fence) + * 3 - Toggled lever(with disabling trap) + * 4 - Killed fire warrior (comes with trying to open the back door) + * 5 - Winelda given 20 fukkin Limpwurt + * 6 - Good (Armadyl pendant), Bad (Took the Staff of Armadyl) + * 7,100 - Good (Killed Lucien), Bad (Gave Lucien staff) + * + * In parallel (all before 4, log disappears after 4) + * A - Took boots + * B - Cross bridge and found lever + * C - Attached lever to switch near entrance lever + * D - Found ice arrows + */ +@Initializable +class TempleOfIkov : Quest(Quests.TEMPLE_OF_IKOV, 121, 120, 1,26, 0, 1, 80 /* 80 or 90 since there's 2 endings */) { + + companion object { + const val attributeChosenEnding = "/save:quest:templeofikov-chosenending" + + const val attributeDisabledTrap = "/save:quest:templeofikov-disabledtrap" + const val attributeTalkedToWinelda = "/save:quest:templeofikov-talkedtowinelda" + + const val attributeCrossedBridge = "/save:quest:templeofikov-crossedbridge" + const val attributeIceChamberAccess = "/save:quest:templeofikov-icechamberaccess" + const val attributeIceArrows = "/save:quest:templeofikov-icearrows" + + const val attributeRandomChest = "quest:templeofikov-randomChest" + const val attributeWarriorInstance = "quest:templeofikov-warriorInstance" + } + override fun drawJournal(player: Player, stage: Int) { + super.drawJournal(player, stage) + var line = 12 + var stage = getStage(player) + + var started = getQuestStage(player, Quests.TEMPLE_OF_IKOV) > 0 + + if (!started) { + line(player, "I can start this quest at the !!Flying Horse Inn?? in !!Ardougne??", line++, false) + line(player, "by speaking to !!Lucien??", line++, false) + line++ + line(player, "To start this quest I will need:", line++, false) + line(player, "Level 42 !!Thieving??", line++, hasLevelStat(player, Skills.THIEVING, 42)) + line(player, "Level 40 !!Ranged??", line++, hasLevelStat(player, Skills.RANGE, 40)) + line(player, "Ability to defeat a level 84 enemy with Ranged.", line++, false) + limitScrolling(player, line, true) + } else { + if (stage >= 2) { + line(player, "Lucien has asked me to retrieve the !!Staff of Armadyl?? from", line++, true) + line(player, "from the !!Temple of Ikov??. The entrance is near !!Hemenster??. He has", line++, true) + line(player, "given me a !!pendant?? so I can enter the !!chamber of fear??.", line++, true) + } else if (stage >= 1) { + line(player, "Lucien has asked me to retrieve the !!Staff of Armadyl?? from", line++, false) + line(player, "from the !!Temple of Ikov??. The entrance is near !!Hemenster??. He has", line++, false) + line(player, "given me a !!pendant?? so I can enter the !!chamber of fear??.", line++, false) + } + + if (stage == 2) { + line(player, "I have entered the chamber of fear.", line++, true) + + } + if (stage == 3) { + line(player, "I have entered the chamber of fear. I found a trap on a", line++, true) + line(player, "lever and have disabled it. I pulled the lever.", line++, true) + } + + // This is a whole side part of retrieving ice arrows that would disappear once you reach stage 4. + if (stage < 4) { + // This is questionable. It's seen in 2014, but seems to be a "side thing". It tracks that you've obtained ice arrows. Derived from RS3. + if (getAttribute(player, attributeIceArrows, false)) { + line(player, "I have found some boots that make me lighter. I made it", line++, true) + line(player, "across the lava bridge and found a lever. I fit the lever", line++, true) + line(player, "into the bracket and pulled the lever. I found arrows", line++, true) + line(player, "made of ice in a chest.", line++, true) + } else if (getAttribute(player, attributeIceChamberAccess, false)) { + line(player, "I have found some boots that make me lighter. I made it", line++, true) + line(player, "across the lava bridge and found a lever. I fit the lever", line++, true) + line(player, "into the bracket and pulled the lever.", line++, true) + } else if (getAttribute(player, attributeCrossedBridge, false)) { + line(player, "I have found some boots that make me lighter. I made it", line++, true) + line(player, "across the lava bridge and found a lever.", line++, true) + } + } + + // Derived. Need sources. + if (stage in 2..3) { + line++ + line(player, "I need to find the entrance to the !!Temple of Ikov??", line++, false) + } + + if (stage == 4) { + line(player, "I have entered the chamber of fear. I found a trap on a", line++, true) + line(player, "lever and have disabled it. I pulled the lever. I went into", line++, true) + line(player, "another chamber and was attacked by a Fire Warrior! I", line++, true) + line(player, "killed it using arrows made of ice and my trusty bow.", line++, true) + } + if (stage == 4 && getAttribute(player, attributeTalkedToWinelda, false) ) { + line++ + // This will never show up crossed. https://www.youtube.com/watch?v=OKYM2oFOUtk 5:18 + line(player, "My path is blocked by lava. !!Winelda?? will teleport me across", line++, false) + line(player, "if I get her !!twenty limpwurt roots??.", line++, false) + } + if (stage == 5) { + line(player, "I have entered the chamber of fear. I found a trap on a", line++, true) + line(player, "lever and have disabled it. I pulled the lever. I went into", line++, true) + line(player, "another chamber and was attacked by a Fire Warrior! I", line++, true) + line(player, "killed it using arrows made of ice and my trusty bow.", line++, true) + } + + if (stage == 6 && getAttribute(player, attributeChosenEnding, 0) == 1 ) { + line(player, "I have entered the chamber of fear. I found a trap on a", line++, true) + line(player, "lever and have disabled it. I pulled the lever. I went into", line++, true) + line(player, "another chamber and was attacked by a Fire Warrior! I", line++, true) + line(player, "killed it using arrows made of ice and my trusty bow.", line++, true) + line++ + line(player, "I agreed to help the !!Guardians of Armadyl??, I will kill !!Lucien??.", line++, false) + line(player, "The guardians gave me a !!pendant?? that I will need to enable", line++, false) + line(player, "me to attack him.", line++, false) + } + + if (stage == 6 && getAttribute(player, attributeChosenEnding, 0) == 2 ) { + line(player, "I have entered the chamber of fear. I found a trap on a", line++, true) + line(player, "lever and have disabled it. I pulled the lever. I went into", line++, true) + line(player, "another chamber and was attacked by a Fire Warrior! I", line++, true) + line(player, "killed it using arrows made of ice and my trusty bow.", line++, true) + line++ + // Derived. Need sources. + line(player, "I recovered the !!Staff of Armadyl?? from the !!Temple of Ikov??.", line++, false) + line(player, "!!Lucien?? is staying at his house west of the !!Grand Exchange??", line++, false) + line(player, "in !!Varrock??.", line++, false) + } + + if (stage >= 100) { + if (getAttribute(player, attributeChosenEnding, 0) == 1) { + //end quest kill lucien https://www.youtube.com/watch?v=cePHhIOqsqg 19:40 + line++ + line(player, "I agreed to help the Guardians of Armadyl, I killed Lucien", line++, true) + line(player, "and banished him from this plane!", line++, true) + } + + if (getAttribute(player, attributeChosenEnding, 0) == 2) { + //end quest helped lucien + line++ + line(player, "I recovered the Staff of Armadyl from the Temple of Ikov.", line++, true) + line(player, "Lucien was staying at his house west of the Grand Exchange", line++, true) + line(player, "in Varrock. He said that the staff had made him more", line++, true) + line(player, "powerful!", line++, true) + } + + line++ + line(player,"QUEST COMPLETE!", line) + } + limitScrolling(player, line, false) + } + } + + override fun reset(player: Player) { + removeAttribute(player, attributeChosenEnding) + removeAttribute(player, attributeDisabledTrap) + removeAttribute(player, attributeTalkedToWinelda) + removeAttribute(player, attributeCrossedBridge) + removeAttribute(player, attributeIceArrows) + removeAttribute(player, attributeIceChamberAccess) + } + + override fun finish(player: Player) { + var ln = 10 + super.finish(player) + when (getAttribute(player, attributeChosenEnding, 0)){ + 1 -> player.packetDispatch.sendString("Temple of Ikov Quest completed for Armadyl!", 277, 4) + 2 -> player.packetDispatch.sendString("Temple of Ikov Quest completed for Lucien!", 277, 4) + else -> player.packetDispatch.sendString("Temple of Ikov Quest completed!!", 277, 4) + } + player.packetDispatch.sendItemZoomOnInterface(Items.YEW_LONGBOW_855,230,277,5) + + drawReward(player, "1 Quest Point", ln++) + drawReward(player, "10,500 Ranged XP", ln++) + drawReward(player, "8,000 Fletching XP", ln++) + + rewardXP(player, Skills.RANGE, 10500.0) + rewardXP(player, Skills.FLETCHING, 8000.0) + } + + override fun newInstance(`object`: Any?): Quest { + return this + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/templeofikov/TempleOfIkovListeners.kt b/Server/src/main/content/region/kandarin/quest/templeofikov/TempleOfIkovListeners.kt new file mode 100644 index 0000000..f513997 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/templeofikov/TempleOfIkovListeners.kt @@ -0,0 +1,261 @@ +package content.region.kandarin.quest.templeofikov + +import content.data.Quests +import content.global.skill.agility.AgilityHandler +import core.api.* +import core.game.global.action.DoorActionHandler +import core.game.global.action.PickupHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength +import core.game.node.entity.skill.Skills +import core.game.node.item.GroundItem +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.game.world.map.Direction +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +class TempleOfIkovListeners : InteractionListener { + + companion object { + val chestLocations = + arrayOf(Location(2710, 9850, 0), + Location(2719, 9838, 0), + Location(2729, 9850, 0), + Location(2747, 9848, 0), + Location(2738, 9835, 0), + Location(2745, 9821, 0)) + } + + override fun defineDestinationOverrides() { + // B - C (fucking lever is on an angle) + setDest(IntType.SCENERY, intArrayOf(Scenery.LEVER_87), "pull") { _, _ -> + return@setDest Location.create(2671, 9805, 0) + } + } + + override fun defineListeners() { + + // This is the trap door falling area. + addClimbDest(Location.create(2682, 9849, 0), Location.create(2665, 9849, 0)) + + // Shiny key to back of McGrubor's Wood. THIS MUST BE LOCKED UP + on(Scenery.DOOR_99, SCENERY, "open") { player, node -> + if (inInventory(player, Items.SHINY_KEY_85)){ + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else { + sendMessage(player, "The door is locked.") + } + return@on true + } + onUseWith(SCENERY, Items.SHINY_KEY_85, Scenery.DOOR_99) { player, used, with -> + DoorActionHandler.handleAutowalkDoor(player, with.asScenery()) + return@onUseWith true + } + + // 1 - 2 Walk past the gate. You must always wear the pendant to get past this gate. + on(intArrayOf(Scenery.GATE_94, Scenery.GATE_95), SCENERY, "open") { player, node -> + if (inEquipment(player, Items.PENDANT_OF_LUCIEN_86)){ + if(getQuestStage(player, Quests.TEMPLE_OF_IKOV) == 1) { + setQuestStage(player, Quests.TEMPLE_OF_IKOV, 2) + } + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else { + sendMessage(player, "As you reach to open the door a great terror overcomes you!") + } + return@on true + } + + // 2: Trapdoor exit + on(Scenery.TRAPDOOR_100, SCENERY, "open") { player, node -> + sendDialogueLines(player, "You try to open the trapdoor but it won't budge! It looks like the", "trapdoor can only be opened from the other side.") + sendMessage(player, "You try to open the trapdoor but it won't budge!") + sendMessage(player, "It looks like the trapdoor can only be opened from the other side.") + return@on true + } + + + // 2 - 3: Lever with trapdoor pull. + on(Scenery.LEVER_91, SCENERY, "pull") { player, node -> + replaceScenery(node.asScenery(), 88, 3) + animate(player, Animation(2140)) + if (getAttribute(player, TempleOfIkov.attributeDisabledTrap, false)) { + if(getQuestStage(player, Quests.TEMPLE_OF_IKOV) == 2) { + setQuestStage(player, Quests.TEMPLE_OF_IKOV, 3) + } + } else { + AgilityHandler.fail(player, 2, Location.create(2682, 9855, 0), Animation(770), 20, "You slip and fall to the pit below.") + } + return@on true + } + + // 2: Lever with trapdoor search. If you do not have level 42 thieving, you cannot proceed. + on(Scenery.LEVER_91, SCENERY, "Search for traps") { player, node -> + if (getDynLevel(player, Skills.THIEVING) >= 42) { + sendDialogueLines(player, "You find a trap on the lever! You disable the trap.") + setAttribute(player, TempleOfIkov.attributeDisabledTrap, true) + } else { + // This is the best video. It shows that you can start the quest even if you didn't meet reqs. + // It also shows what happens if you tried to disarm without level 42 Thieving. + // https://www.youtube.com/watch?v=I28nZxZAd58 + sendDialogueLines(player, "You find nothing.") + } + return@on true + } + + // A: Obtain boots. + // Note that the room is "dark". There are two areas. + // You switch between them if you have light or not. + // The light lets you see further into the room + // https://www.youtube.com/watch?v=6ZGpJNeGLJ0 + // sendDialogue("Hmm...bit dark down here! I'm not going to venture far!") + + + // B: Attach lever, authentic if you log out, the lever is lost, and you have to do that bridge again + onUseWith(SCENERY, Items.LEVER_83, Scenery.LEVER_BRACKET_86) { player, used, with -> + removeItem(player, used) + replaceScenery(with.asScenery(), Scenery.LEVER_87, 20) + sendDialogue(player, "You fit the lever into the bracket.") + return@onUseWith true + } + + // B to C: Pull down on lever + on(Scenery.LEVER_87, SCENERY, "pull") { player, node -> + face(player, Location.create(2671, 9803, 0)) + animate(player, Animation(2140)) + replaceScenery(node.asScenery(), 88, 3) // Scenery.88 is the downward lever. + setAttribute(player, TempleOfIkov.attributeIceChamberAccess, true) + queueScript(player, 6, QueueStrength.NORMAL) { + replaceScenery(node.asScenery(), Scenery.LEVER_BRACKET_86, -1) + return@queueScript stopExecuting(player) + } + sendDialogue(player, "You hear the clunking of some hidden machinery.") + return@on true + } + + // C: Gate opens after attached lever + on(intArrayOf(Scenery.GATE_89, Scenery.GATE_90), SCENERY, "open") { player, node -> + if (getAttribute(player, TempleOfIkov.attributeIceChamberAccess, false) || getQuestStage( + player, + Quests.TEMPLE_OF_IKOV + ) >= 4){ + // To be nice, you can "reset" the chest location by opening the gate. + // This is a failsafe if the attribute gets "stuck", although I doubt it will happen. + setAttribute(player, TempleOfIkov.attributeRandomChest, chestLocations.random()) + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else { + sendDialogue(player, "The door won't open!") + } + return@on true + } + + // D: Chest open + on(Scenery.CLOSED_CHEST_35122, SCENERY, "open") { player, node -> + animate(player, 536) + replaceScenery(node as core.game.node.scenery.Scenery, Scenery.OPEN_CHEST_35123, -1) + return@on true + } + + // D: Chest shut + on(Scenery.OPEN_CHEST_35123, SCENERY, "shut") { player, node -> + animate(player, 536) + replaceScenery(node as core.game.node.scenery.Scenery, Scenery.CLOSED_CHEST_35122, -1) + return@on true + } + + // D: Chest search. I assure you this is the worst feature of this goddamn quest. + // 1/6 of the chests are randomly chosen to have 1-5 ice arrows, and it REMEMBERS... + // So clicking on the same one doesn't randomize it. Good luck and fuck you. + on(Scenery.OPEN_CHEST_35123, SCENERY, "search") { player, node -> + if (getAttribute(player, TempleOfIkov.attributeRandomChest, null) == null) { + setAttribute(player, TempleOfIkov.attributeRandomChest, chestLocations.random()) + } + if (getAttribute(player, TempleOfIkov.attributeRandomChest, null) == node.location){ + removeAttribute(player, TempleOfIkov.attributeRandomChest) + val randomAmount = (1..5).random() + addItemOrDrop(player, Items.ICE_ARROWS_78, randomAmount) + sendItemDialogue(player, Item(Items.ICE_ARROWS_78, randomAmount), "You found some ice arrows!") + setAttribute(player, TempleOfIkov.attributeIceArrows, true) + } else { + sendMessage(player, "You search the chest, but find nothing.") + } + return@on true + } + + // 3: Allow access to Fire Warrior Door after pulling the lever + on(Scenery.DOOR_92, SCENERY, "open") { player, node -> + removeAttribute(player, TempleOfIkov.attributeWarriorInstance) + if (getQuestStage(player, Quests.TEMPLE_OF_IKOV) >= 3){ + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else { + sendMessage(player, "The door won't open.") + } + return@on true + } + + + // 3 - 4: Calls for the Fire Warrior, allows passing when Fire Warrior is defeated. + on(Scenery.DOOR_93, SCENERY, "open") { player, node -> + if (getQuestStage(player, Quests.TEMPLE_OF_IKOV) >= 4){ + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else { + if (getAttribute(player, TempleOfIkov.attributeWarriorInstance, null) == null) { + val npc = FireWarriorOfLesarkusNPC(NPCs.FIRE_WARRIOR_OF_LESARKUS_277, player, Location(2646, 9866, 0)) + npc.init() + npc.isRespawn = false + npc.isWalks = false + npc.location = Location(2646, 9866, 0) + npc.direction = Direction.NORTH + submitIndividualPulse(player, object : Pulse() { + var counter = 0 + override fun pulse(): Boolean { + when (counter++) { + 0 -> { + sendChat(npc, "You will not pass!") + } + 2 -> { + sendChat(npc, "Amitus! Setitii!") + spawnProjectile(npc, player, 127) // Launch fire projectile + } + 4 -> { + npc.isWalks = true + return true + } + } + return false + } + }) + + setAttribute(player, TempleOfIkov.attributeWarriorInstance, npc) + // This npc doesn't attack you immediately nor is aggressive at the start. + } else { + sendMessage(player, "The door won't open.") + } + } + return@on true + } + + on(Items.STAFF_OF_ARMADYL_84, IntType.GROUNDITEM,"take") { player, node -> + if (getQuestStage(player, Quests.TEMPLE_OF_IKOV) >= 6 && getAttribute(player, TempleOfIkov.attributeChosenEnding, 0) == 1){ + sendMessage(player, "You decide not to steal the staff as you have agreed to help the Guardians") + } + val npcs = findLocalNPCs(player, intArrayOf(NPCs.GUARDIAN_OF_ARMADYL_274, NPCs.GUARDIAN_OF_ARMADYL_275), 4) + if (npcs.isNotEmpty()) { + sendChat(npcs[0], "That is not thine to take!") + npcs[0].attack(player) + } else { + if(getQuestStage(player, Quests.TEMPLE_OF_IKOV) == 5) { + setQuestStage(player, Quests.TEMPLE_OF_IKOV, 6) + setAttribute(player, TempleOfIkov.attributeChosenEnding, 2) + } + PickupHandler.take(player, node as GroundItem) + } + return@on true + } + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/templeofikov/WineldaDialogue.kt b/Server/src/main/content/region/kandarin/quest/templeofikov/WineldaDialogue.kt new file mode 100644 index 0000000..aa34d7d --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/templeofikov/WineldaDialogue.kt @@ -0,0 +1,111 @@ +package content.region.kandarin.quest.templeofikov + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class WineldaDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return WineldaDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, WineldaDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.WINELDA_276) + } +} + +class WineldaDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onQuestStages(Quests.TEMPLE_OF_IKOV, 5, 6, 7, 100) + .playerl(FacialExpression.FRIENDLY, "Hi again. Could you do the honours again please?") + .npcl(FacialExpression.FRIENDLY, "Certainly! We helps those that helps poor Winelda!") + .endWith { _, player -> + // There's a cutscene, but I'm lazy man. + teleport(player, Location(2664, 9876, 0)) + } + + b.onPredicate { player -> getAttribute(player, TempleOfIkov.attributeTalkedToWinelda, false) } + .npcl("Have you got roots for poor Winelda?") + .branch { player -> + if (inInventory(player, Items.LIMPWURT_ROOT_225)) { + if (amountInInventory(player, Items.LIMPWURT_ROOT_225) >= 20) { + return@branch 2 + } + return@branch 1 + } + return@branch 0 + }.let{ branch -> + branch.onValue(2) + .playerl(FacialExpression.FRIENDLY, "Yes, I've got them.") + .betweenStage { _, player, _, _ -> + removeItem(player, Item(Items.LIMPWURT_ROOT_225, 20)) + } + .iteml(Items.LIMPWURT_ROOT_225, "You give Winelda the limpwurt roots.") + .npcl(FacialExpression.FRIENDLY, "Good! Good! My potion is nearly ready! Bubble, bubble, toil and trouble!") + .npcl(FacialExpression.FRIENDLY, "Now we shows them ours magic! Hold on tight!") + .endWith { _, player -> + if(getQuestStage(player, Quests.TEMPLE_OF_IKOV) == 4) { + setQuestStage(player, Quests.TEMPLE_OF_IKOV, 5) + } + // There's a cutscene, but I'm lazy man. + teleport(player, Location(2664, 9876, 0)) + } + branch.onValue(1) + .playerl(FacialExpression.FRIENDLY, "I've got some limpwurt roots!") + .npcl(FacialExpression.FRIENDLY, "We needs 20 rooteses!") + .end() + branch.onValue(0) + .playerl(FacialExpression.FRIENDLY, "How many did you need again?") + .npcl(FacialExpression.FRIENDLY, "We needs 20 Limpwurt roots for pot.") + .end() + } + + b.onPredicate { _ -> true } + .npcl(FacialExpression.FRIENDLY, "Hehe! We see you're in a pickle!") + .npcl("Wants to be getting over the nasty lava do we?") + .options() + .let { optionBuilder -> + optionBuilder.option_playerl("Nah, not bothered!") + .npcl(FacialExpression.FRIENDLY, "Hehe! Ye'll come back! They always come back!") + .end() + optionBuilder.option_playerl("Yes we do!") + .npcl(FacialExpression.FRIENDLY, "Mocking us are we? Clever one aren't we?") + .npcl(FacialExpression.FRIENDLY, "I'm knowing some magic trickesses! I could get over easy as that!") + .npcl(FacialExpression.FRIENDLY, "Don't tell them! They always come! They pester poor Winelda!") + .playerl(FacialExpression.FRIENDLY, "If you're such a great witch, get me over!") + .npcl(FacialExpression.FRIENDLY, "See! They pester Winelda!") + .playerl(FacialExpression.FRIENDLY, "I can do something for you!") + .npcl(FacialExpression.FRIENDLY, "Good! Don't pester! Help!") + .npcl(FacialExpression.FRIENDLY, "Get Winelda 20 limpwurt roots for my pot.") + .npcl(FacialExpression.FRIENDLY, "Then we shows them some magic!") + .endWith { _, player -> + setAttribute(player, TempleOfIkov.attributeTalkedToWinelda, true) + } + optionBuilder.option_playerl("Yes I do!") + .npcl(FacialExpression.FRIENDLY, "I'm knowing some magic trickesses! I could get over easy as that!") + .npcl(FacialExpression.FRIENDLY, "Don't tell them! They always come! They pester poor Winelda!") + .playerl(FacialExpression.FRIENDLY, "If you're such a great witch, get me over!") + .npcl(FacialExpression.FRIENDLY, "See! They pester Winelda!") + .playerl(FacialExpression.FRIENDLY, "I can do something for you!") + .npcl(FacialExpression.FRIENDLY, "Good! Don't pester! Help!") + .npcl(FacialExpression.FRIENDLY, "Get Winelda 20 limpwurt roots for my pot.") + .npcl(FacialExpression.FRIENDLY, "Then we shows them some magic!") + .endWith { _, player -> + setAttribute(player, TempleOfIkov.attributeTalkedToWinelda, true) + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/tree/BallistaDialogue.kt b/Server/src/main/content/region/kandarin/quest/tree/BallistaDialogue.kt new file mode 100644 index 0000000..afc028e --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/tree/BallistaDialogue.kt @@ -0,0 +1,47 @@ +package content.region.kandarin.quest.tree + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueFile +import core.tools.END_DIALOGUE + +class BallistaDialogue : DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + val questStage = getQuestStage(player!!, Quests.TREE_GNOME_VILLAGE) + if (questStage > 30) { + when (stage) { + 0 -> sendDialogue(player!!, "The Khazard stronghold has already been breached.").also { stage = END_DIALOGUE } + } + } else if (questStage != 30) return + + val tracker1 = getAttribute(player!!, "/save:treegnome:tracker1", false) + val tracker2 = getAttribute(player!!, "/save:treegnome:tracker2", false) + val tracker3 = getAttribute(player!!, "/save:treegnome:tracker3", false) + + if(tracker1 && tracker2 && tracker3) { + when(stage){ + 0 -> playerl("That tracker gnome was a bit vague about the x coordinate! What could it be?").also { stage++ } + 1 -> interpreter!!.sendOptions("Enter the x-coordinate of the stronghold", + "0001","0002","0003","0004").also { stage++ } + 2 -> { + sendDialogue(player!!, "You entered the height and y coordinates you got from the tracker gnomes.") + val answer = getAttribute(player!!,"treegnome:xcoord",1) + when (buttonID) { + answer -> { + sendDialogue(player!!, "The huge spear flies through the air and screams down directly into the Khazard stronghold. A deafening crash echoes over the battlefield as the front entrance is reduced to rubble.") + setQuestStage(player!!, Quests.TREE_GNOME_VILLAGE, 31) + } + else -> sendDialogue(player!!, "The huge spear completely misses the Khazard stronghold!") + } + stage = END_DIALOGUE + } + } + } else { + when(stage){ + 0 -> sendDialogue(player!!,"You enter some random coordinates.").also { stage++ } + 1 -> sendDialogue(player!!,"The huge spear completely misses the Khazard stronghold!").also { stage++ } + 2 -> playerl("I've got no hope of hitting the stronghold without knowing any of the coordinates. Maybe I should ask Montai's tracker gnomes for more coordinates.").also { stage = END_DIALOGUE } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/tree/CommanderMontaiDialogue.kt b/Server/src/main/content/region/kandarin/quest/tree/CommanderMontaiDialogue.kt new file mode 100644 index 0000000..cc79075 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/tree/CommanderMontaiDialogue.kt @@ -0,0 +1,107 @@ +package content.region.kandarin.quest.tree + +import content.data.Quests +import core.api.* +import org.rs09.consts.Items +import core.game.dialogue.DialogueFile +import core.tools.END_DIALOGUE + +class CommanderMontaiDialogue : DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + val questStage = getQuestStage(player!!, Quests.TREE_GNOME_VILLAGE) + if (questStage == 10) { + when(stage) { + 0 -> playerl("Hello.").also { stage++ } + 1 -> npcl("Hello traveller, are you here to help or just to watch?").also { stage++ } + 2 -> playerl("I've been sent by King Bolren to retrieve the orb of protection.").also { stage++ } + 3 -> npcl("Excellent we need all the help we can get.").also { stage++ } + 4 -> npcl("I'm Commander Montai. The orb is in the Khazard stronghold to the north, but until we weaken their defences we can't get close.").also { stage++ } + 5 -> playerl("What can I do?").also { stage++ } + 6 -> npcl("Firstly we need to strengthen our own defences. We desperately need wood to make more battlements, once the battlements are gone it's all over. Six loads of normal logs should do it.").also { stage++ } + 7 -> options("Ok, I'll gather some wood.", "Sorry, I no longer want to be involved.").also { stage++ } + 8 -> when (buttonID) { + 1 -> playerl("Ok, I'll gather some wood.").also { stage = 10 } + 2 -> playerl("Sorry, I no longer want to be involved.").also { stage = 9 } + } + 9 -> npcl("That's a shame, we could have done with your help.").also { stage = END_DIALOGUE } + 10 -> npcl("Please be as quick as you can, I don't know how much longer we can hold out.").also { + setQuestStage(player!!, Quests.TREE_GNOME_VILLAGE, 20) + stage = END_DIALOGUE + } + } + } else if (questStage == 20) { + if(inInventory(player!!, Items.LOGS_1511,6)){ + when(stage) { + 0 -> playerl("Hello.").also { stage++ } + 1 -> npcl("Hello again, we're still desperate for wood soldier.").also { stage++ } + 2 -> playerl("I have some here. (You give six loads of logs to the commander.)").also{ stage++ } + 3 -> { + // Remove the 6 normal logs + for(i in 1..6) { removeItem(player!!,Items.LOGS_1511) } + setQuestStage(player!!, Quests.TREE_GNOME_VILLAGE, 25) + npcl("That's excellent, now we can make more defensive battlements. Give me a moment to organize the troops and then come speak to me. I'll inform you of our next phase of attack.") + stage = END_DIALOGUE + } + } + } else { + when(stage) { + 0 -> playerl("Hello.").also { stage++ } + 1 -> npcl("Hello again, we're still desperate for wood soldier. We need six loads of normal logs.").also { stage++ } + 2 -> playerl("I'll see what I can do.").also { stage++ } + 3 -> npcl("Thank you.").also { stage = END_DIALOGUE } + } + } + } else if (questStage == 25) { + when(stage) { + 0 -> playerl("How are you doing Montai?").also { stage++ } + 1 -> npcl("We're hanging in there soldier. For the next phase of our attack we need to breach their stronghold.").also { stage++ } + 2 -> npcl("The ballista can break through the stronghold wall, and then we can advance and seize back the orb.").also { stage++ } + 3 -> playerl("So what's the problem?").also { stage++ } + 4 -> npcl("From this distance we can't get an accurate enough shot. We need the correct coordinates of the stronghold for a direct hit. I've sent out three tracker gnomes to gather them.").also { stage++ } + 5 -> playerl("Have they returned?").also { stage++ } + 6 -> npcl("I'm afraid not, and we're running out of time. I need you to go into the heart of the battlefield, find the trackers, and bring back the coordinates.").also { stage++ } + 7 -> npcl("Do you think you can do it?").also { stage++ } + 8 -> options("No, I've had enough of your battle.", "I'll try my best.").also { stage++ } + 9 -> when(buttonID) { + 1 -> playerl("No, I've had enough of your battle.").also { stage = 10 } + 2 -> playerl("I'll try my best.").also { stage = 11 } + } + 10 -> npcl("I understand, this isn't your fight.").also { stage = END_DIALOGUE } + 11 -> npcl("Thank you, you're braver than most.").also { stage++ } + 12 -> npcl("I don't know how long I will be able to hold out. Once you have the coordinates come back and fire the ballista right into those monsters.").also { stage++ } + 13 -> npcl("If you can retrieve the orb and bring safety back to my people, none of the blood spilled on this field will be in vain.").also { + setQuestStage(player!!, Quests.TREE_GNOME_VILLAGE, 30) + stage = END_DIALOGUE + } + } + } else if (questStage == 30) { + when(stage) { + 0 -> playerl("Hello.").also { stage++ } + 1 -> npcl("Hello warrior. We need the coordinates for a direct hit from the ballista.").also { stage++ } + 2 -> npcl("Once you have a direct hit you will be able to enter the stronghold and retrieve the orb.").also { stage = END_DIALOGUE } + } + } else if (questStage == 31) { + if(inInventory(player!!,Items.ORB_OF_PROTECTION_587)){ + when(stage) { + 0 -> playerl("I have the orb of protection.").also { stage++ } + 1 -> npcl("Incredible, for a human you really are something.").also { stage++ } + 2 -> playerl("Thanks... I think!").also { stage++ } + 3 -> npcl("I'll stay here with my troops and try and hold Khazard's men back. You return the orb to the gnome village. Go as quick as you can, the village is still unprotected.").also { stage = END_DIALOGUE } + } + + } else { + when(stage) { + 0 -> playerl("I've breached the stronghold.").also { stage++ } + 1 -> npcl("I saw, that was a beautiful sight. The Khazard troops didn't know what hit them.").also { stage++ } + 2 -> npcl("Now is the time to retrieve the orb. It's all in your hands. I'll be praying for you.").also { stage = END_DIALOGUE } + } + } + } else if (questStage != 0){ + when(stage) { + 0 -> playerl("Hello Montai, how are you?").also { stage++ } + 1 -> npcl("I'm ok, this battle is going to take longer to win than I expected. The Khazard troops won't give up even without the orb.").also { stage++ } + 2 -> playerl("Hang in there.").also { stage = END_DIALOGUE } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/tree/ElkoyDialogue.kt b/Server/src/main/content/region/kandarin/quest/tree/ElkoyDialogue.kt new file mode 100644 index 0000000..1356248 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/tree/ElkoyDialogue.kt @@ -0,0 +1,170 @@ +package content.region.kandarin.quest.tree + +import content.data.Quests +import core.api.* +import core.game.component.Component +import core.game.node.entity.player.Player +import core.game.system.task.Pulse +import core.game.world.map.Location +import org.rs09.consts.Components +import org.rs09.consts.Items +import core.game.dialogue.DialogueFile +import content.region.kandarin.quest.tree.TreeGnomeVillage.Companion.mazeEntrance +import content.region.kandarin.quest.tree.TreeGnomeVillage.Companion.mazeVillage +import core.game.world.GameWorld.Pulser +import core.tools.END_DIALOGUE + +class ElkoyDialogue : DialogueFile(){ + fun travelCutscene(player: Player, location: Location){ + sendDialogue(player,"Elkoy escorts you through the maze...") + Pulser.submit(object : Pulse(0) { + var count = 0 + override fun pulse(): Boolean { + when (count) { + 0 -> { + player.interfaceManager.closeOverlay() + player.interfaceManager.openOverlay(Component(Components.FADE_TO_BLACK_120)) + } + 2 -> { + teleport(player,location) + player.interfaceManager.closeOverlay() + player.interfaceManager.openOverlay(Component(Components.FADE_FROM_BLACK_170)) + return true + } + } + count++ + return false + } + }) + } + override fun handle(componentID: Int, buttonID: Int) { + val questStage = getQuestStage(player!!, Quests.TREE_GNOME_VILLAGE) + val locY = player!!.location.y + val followLocation = if(locY > 3161) "village" else "exit" + when { + inInventory(player!!, Items.ORBS_OF_PROTECTION_588) && followLocation == "exit" -> { + when(stage) { + 0 -> playerl("Hello Elkoy. I have the orb.").also { stage++ } + 1 -> npcl("Take it to King Bolren, I'm sure he'll be pleased to see you.").also { stage++ } + 2 -> options("Alright, I'll do that.", "Can you guide me out of the maze now?").also { stage++ } + 3 -> when(buttonID) { + 1 -> playerl("Alright, I'll do that.").also { stage = END_DIALOGUE } + 2 -> playerl("Can you guide me out of the maze now?").also { stage = 4 } + } + 4 -> npcl("If you like, but please take the orb to King Bolren soon.").also { stage++ } + 5 -> { + travelCutscene(player!!, mazeEntrance) + stage++ + } + 6 -> npcl("Here we are. Please don't lose the orb!").also { stage = END_DIALOGUE } + } + } + inInventory(player!!, Items.ORB_OF_PROTECTION_587) -> { + when(stage) { + 0 -> playerl("Hello Elkoy.").also { stage++ } + 1 -> npcl("You're back! And the orb?").also { stage++ } + 2 -> playerl("I have it here.").also { stage++ } + 3 -> { + if(locY > 3161){ + npcl("You're our saviour. Please return it to the village and we are all saved. Would you like me to show you the way to the village?").also { stage++ } + } else { + npcl("Take the orb to King Bolren, I'm sure he'll be pleased to see you.").also { stage = END_DIALOGUE } + } + } + 4 -> options("Yes please.", "No thanks Elkoy.").also { stage++ } + 5 -> when(buttonID) { + 1 -> playerl("Yes please.").also { stage = 7 } + 2 -> playerl("No thanks Elkoy.").also { stage = 6 } + } + 6 -> npcl("Ok then, take care.").also { stage = END_DIALOGUE } + 7 -> travelCutscene(player!!, mazeVillage).also { stage++ } + 8 -> npcl("Here we are. Take the orb to King Bolren, I'm sure he'll be pleased to see you.").also { stage = END_DIALOGUE } + } + } + inInventory(player!!, Items.ORBS_OF_PROTECTION_588) || questStage == 100 -> { + when(stage) { + 0 -> playerl("Hello Elkoy.").also { stage++ } + 1 -> npcl("You truly are a hero.").also { stage++ } + 2 -> playerl("Thanks.").also { stage++ } + 3 -> npcl("You saved us by defeating the warlord. I'm humbled and wish you well.").also { stage++ } + 4 -> npcl("Would you like me to show you the way to the ${followLocation}?").also { stage++ } + 5 -> options("Yes please.", "No thanks Elkoy.").also { stage++ } + 6 -> when(buttonID) { + 1 -> playerl("Yes please.").also { stage = 8 } + 2 -> playerl("No thanks Elkoy.").also { stage = 7 } + } + 7 -> npcl("Ok then, take care.").also { stage = END_DIALOGUE } + 8 -> { + if(followLocation == "village") { + travelCutscene(player!!, mazeVillage) + stage = 10 + } + else { + travelCutscene(player!!, mazeEntrance) + stage++ + } + } + 9 -> npcl("Here we are. Have a safe journey.").also { stage = END_DIALOGUE } + 10 -> npcl("Here we are. Feel free to have a look around.").also { stage = END_DIALOGUE } + } + } + questStage == 0 -> { + when(stage) { + 0 -> playerl("Hello there.").also { stage++ } + 1 -> npcl("Hello, welcome to our maze. I'm Elkoy the tree gnome.").also { stage++ } + 2 -> playerl("I haven't heard of your sort.").also { stage++ } + 3 -> npcl("There's not many of us left. Once you could find tree gnomes anywhere in the world, now we hide in small groups to avoid capture.").also { stage++ } + 4 -> playerl("Capture from whom?").also { stage++ } + 5 -> npcl("Tree gnomes have been hunted for so called 'fun' since as long as I can remember.").also { stage++ } + 6 -> npcl("Our main threat nowadays are General Khazard's troops. They know no mercy, but are also very dense. They'll never find their way through our maze.").also { stage++ } + 7 -> npcl("Have fun.").also { stage = END_DIALOGUE } + } + } + questStage in 1..39 -> { + when (stage) { + 0 -> npcl("Oh my! The orb, they have the orb. We're doomed.").also { stage++ } + 1 -> playerl("Perhaps I'll be able to get it back for you.").also { stage++ } + 2 -> npcl("Would you like me to show you the way to the ${followLocation}?").also { stage++ } + 3 -> options("Yes please.", "No thanks Elkoy.").also { stage++ } + 4 -> when (buttonID) { + 1 -> playerl("Yes please.").also { stage = 6 } + 2 -> playerl("No thanks Elkoy.").also { stage = 5 } + } + 5 -> npcl("Ok then, take care.").also { stage = END_DIALOGUE } + 6 -> { + if(followLocation == "village") + travelCutscene(player!!, mazeVillage) + else + travelCutscene(player!!, mazeEntrance) + stage++ + } + 7 -> npcl("Here we are. I hope you get the orb back soon.").also { stage = END_DIALOGUE } + } + } + questStage == 40 -> { + when(stage) { + 0 -> playerl("Hello Elkoy.").also { stage++ } + 1 -> npcl("Did you hear? Khazard's men have pillaged the village! They slaughtered many, and took the other orbs in an attempt to lead us out of the maze. When will the misery end?").also { stage++ } + 2 -> npcl("Would you like me to show you the way to the ${followLocation}?").also { stage++ } + 3 -> options("Yes please.", "No thanks Elkoy.").also { stage++ } + 4 -> when(buttonID) { + 1 -> playerl("Yes please.").also { stage = 6 } + 2 -> playerl("No thanks Elkoy.").also { stage = 5 } + } + 5 -> npcl("Ok then, take care.").also { stage = END_DIALOGUE } + 6 -> { + if(followLocation == "village") { + travelCutscene(player!!, mazeVillage) + stage = 8 + } else { + travelCutscene(player!!, mazeEntrance) + stage++ + } + } + 7 -> npcl("Please try to get our orbs back for us, otherwise the village is doomed!").also { stage = END_DIALOGUE } + 8 -> npcl("Here we are. Despite what has happened here, I hope you feel welcome.").also { stage = END_DIALOGUE } + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/tree/KhazardWarlordDialogue.kt b/Server/src/main/content/region/kandarin/quest/tree/KhazardWarlordDialogue.kt new file mode 100644 index 0000000..b70b644 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/tree/KhazardWarlordDialogue.kt @@ -0,0 +1,32 @@ +package content.region.kandarin.quest.tree + +import content.data.Quests +import core.api.getQuestStage +import core.game.dialogue.DialogueFile +import core.tools.END_DIALOGUE + +class KhazardWarlordDialogue : DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + val questStage = getQuestStage(player!!, Quests.TREE_GNOME_VILLAGE) + if(questStage == 31){ + when(stage) { + 0 -> playerl("Hello there.").also { stage++ } + 1 -> npcl("You think you're so clever. You know nothing!").also { stage++ } + 2 -> playerl("What?").also { stage++ } + 3 -> npcl("I'll crush you and those pesky little green men!").also { stage = END_DIALOGUE } + } + } else if (questStage == 40) { + when(stage) { + 0 -> playerl("You there, stop!").also { stage++ } + 1 -> npcl("Go back to your pesky little green friends.").also { stage++ } + 2 -> playerl("I've come for the orbs.").also { stage++ } + 3 -> npcl("You're out of your depth traveller. These orbs are part of a much larger picture.").also { stage++ } + 4 -> playerl("They're stolen goods, now give them here!").also { stage++ } + 5 -> npcl("Ha, you really think you stand a chance? I'll crush you.").also { + npc!!.attack(player!!) + stage = END_DIALOGUE + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/tree/KhazardWarlordNPC.kt b/Server/src/main/content/region/kandarin/quest/tree/KhazardWarlordNPC.kt new file mode 100644 index 0000000..7366127 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/tree/KhazardWarlordNPC.kt @@ -0,0 +1,37 @@ +package content.region.kandarin.quest.tree + +import content.data.Quests +import core.api.addItemOrDrop +import core.api.getQuestStage +import core.api.sendDialogue +import core.game.node.entity.Entity +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import core.game.interaction.InteractionListener + +@Initializable +class KhazardWarlordNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id,location), InteractionListener { + + override fun construct(id: Int, location: Location?, vararg objects: Any?): AbstractNPC { + return KhazardWarlordNPC(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.KHAZARD_WARLORD_477) + } + + override fun defineListeners() { + } + + override fun finalizeDeath(killer: Entity?) { + if(getQuestStage(killer as Player, Quests.TREE_GNOME_VILLAGE) == 40) { + sendDialogue(killer,"As the warlord falls to the ground, a ghostly vapour floats upwards from his battle-worn armour. You search his satchel and find the orbs of protection.") + addItemOrDrop(killer, Items.ORBS_OF_PROTECTION_588) + } + super.finalizeDeath(killer) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/tree/KingBolrenDialogue.kt b/Server/src/main/content/region/kandarin/quest/tree/KingBolrenDialogue.kt new file mode 100644 index 0000000..73c26fc --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/tree/KingBolrenDialogue.kt @@ -0,0 +1,201 @@ +package content.region.kandarin.quest.tree + +import content.data.Quests +import core.api.* +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.map.RegionManager +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import core.game.dialogue.DialogueFile +import content.region.kandarin.quest.tree.TreeGnomeVillage.Companion.mazeEntrance +import core.game.world.GameWorld +import core.tools.END_DIALOGUE + +class KingBolrenDialogue : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + val questStage = getQuestStage(player!!, Quests.TREE_GNOME_VILLAGE) + when { + questStage < 10 -> { + when (stage) { + 0 -> playerl("Hello.").also { stage++ } + 1 -> npcl("Well hello stranger. My name's Bolren, I'm the king of the tree gnomes.").also { stage++ } + 2 -> npcl("I'm surprised you made it in, maybe I made the maze too easy.").also { stage++ } + 3 -> playerl("Maybe.").also { stage++ } + 4 -> npcl("I'm afraid I have more serious concerns at the moment. Very serious.").also { stage++ } + 5 -> options("I'll leave you to it then.", "Can I help at all?").also { stage++ } + 6 -> when (buttonID) { + 1 -> playerl("I'll leave you to it then.").also { stage = 7 } + 2 -> playerl("Can I help at all?").also { stage = 8 } + } + 7 -> npcl("Ok, take care.").also { stage = END_DIALOGUE } + 8 -> npcl("I'm glad you asked.").also { stage++ } + 9 -> npcl("The truth is my people are in grave danger. We have always been protected by the Spirit Tree. No creature of dark can harm us while its three orbs are in place.").also { stage++ } + 10 -> npcl("We are not a violent race, but we fight when we must. Many gnomes have fallen battling the dark forces of Khazard to the North.").also { stage++ } + 11 -> npcl("We became desperate, so we took one orb of protection to the battlefield. It was a foolish move.").also { stage++ } + 12 -> npcl("Khazard troops seized the orb. Now we are completely defenceless.").also { stage++ } + 13 -> playerl("How can I help?").also { stage++ } + 14 -> npcl("You would be a huge benefit on the battlefield. If you would go there and try to retrieve the orb, my people and I will be forever grateful.").also { stage++ } + 15 -> options("I would be glad to help.", "I'm sorry but I won't be involved.").also { stage++ } + 16 -> when (buttonID) { + 1 -> playerl("I would be glad to help.").also { stage = 18 } + 2 -> playerl("I'm sorry but I won't be involved.").also { stage = 17 } + } + 17 -> npcl("Ok then, travel safe.").also { stage = END_DIALOGUE } + 18 -> npcl("Thank you. The battlefield is to the north of the maze. Commander Montai will inform you of their current situation.").also { stage++ } + 19 -> npcl("That is if he's still alive.").also { stage++ } + 20 -> npcl("My assistant shall guide you out. Good luck friend, try your best to return the orb.").also { + stage++ + } + 21 -> { + teleport(player!!, mazeEntrance) + sendNPCDialogue(player!!, NPCs.ELKOY_5179, "We're out of the maze now. Please hurry, we must have the orb if we are to survive.") + setQuestStage(player!!, Quests.TREE_GNOME_VILLAGE, 10) + stage = END_DIALOGUE + } + } + } + questStage < 31 -> { + when (stage) { + 0 -> playerl("Hello Bolren.").also { stage++ } + 1 -> npcl("Hello traveller, we must retrieve the orb. It's being held by Khazard troops north of here.").also { stage++ } + 2 -> playerl("Ok, I'll try my best.").also { stage = END_DIALOGUE } + } + } + questStage == 31 -> { + if(inInventory(player!!,Items.ORB_OF_PROTECTION_587)){ + when(stage) { + 0 -> playerl("I have the orb.").also { stage++ } + 1 -> npcl("Oh my... The misery, the horror!").also { stage++ } + 2 -> playerl("King Bolren, are you OK?").also { stage++ } + 3 -> npcl("Thank you traveller, but it's too late. We're all doomed.").also { stage++ } + 4 -> playerl("What happened?").also { stage++ } + 5 -> npcl("They came in the night. I don't know how many, but enough.").also { stage++ } + 6 -> playerl("Who?").also { stage++ } + 7 -> npcl("Khazard troops. They slaughtered anyone who got in their way. Women, children, my wife.").also { stage++ } + 8 -> playerl("I'm sorry.").also { stage++ } + 9 -> npcl("They took the other orbs, now we are defenceless.").also { stage++ } + 10 -> playerl("Where did they take them?").also { stage++ } + 11 -> npcl("They headed north of the stronghold. A warlord carries the orbs.").also { stage++ } + 12 -> options("I will find the warlord and bring back the orbs.", "I'm sorry but I can't help.").also { stage++ } + 13 -> when(buttonID) { + 1 -> playerl("I will find the warlord and bring back the orbs.").also { stage = 15 } + 2 -> playerl("I'm sorry but I can't help.").also { stage = 14 } + } + 14 -> npcl("I understand, this isn't your battle.").also { stage = END_DIALOGUE } + 15 -> npcl("You are brave, but this task will be tough even for you. I wish you the best of luck. Once again you are our only hope.").also { stage++ } + 16 -> npcl("I will safeguard this orb and pray for your safe return. My assistant will guide you out.").also { + stage++ + } + 17 -> { + if(removeItem(player!!,Items.ORB_OF_PROTECTION_587)){ + teleport(player!!,mazeEntrance) + setQuestStage(player!!, Quests.TREE_GNOME_VILLAGE, 40) + sendNPCDialogue(player!!, NPCs.ELKOY_5179, "Good luck friend.") + } + stage = END_DIALOGUE + } + } + } else { + when(stage) { + 0 -> playerl("Hello Bolren.").also { stage++ } + 1 -> npcl("Do you have the orb?").also { stage++ } + 2 -> playerl("No, I'm afraid not.").also { stage++ } + 3 -> npcl("Please, we must have the orb if we are to survive.").also { stage = END_DIALOGUE } + } + } + } + questStage == 40 -> { + if(inInventory(player!!,Items.ORBS_OF_PROTECTION_588)){ + when(stage) { + 0 -> playerl("Bolren, I have returned.").also { stage++ } + 1 -> npcl("You made it back! Do you have the orbs?").also { stage++ } + 2 -> playerl("I have them here.").also { stage++ } + 3 -> npcl("Hooray, you're amazing. I didn't think it was possible but you've saved us.").also { stage++ } + 4 -> npcl("Once the orbs are replaced we will be safe once more. We must begin the ceremony immediately.").also { stage++ } + 5 -> playerl("What does the ceremony involve?").also { stage++ } + 6 -> npcl("The spirit tree has looked over us for centuries. Now we must pay our respects.").also { stage++ } + 7 -> sendDialogue(player!!,"The gnomes begin to chant. Meanwhile, King Bolren holds the orbs of protection out in front of him.").also { stage++ } + 8 -> { + // Orbs fly up, gnomes chant, spirit tree animates + GameWorld.Pulser.submit(object : Pulse(0) { + var count = 0 + val orbsOfProtection = 79 + val spiritTreeWithOrbs = Animation(333) + val gnomeSpots = listOf(Location(2542, 3172, 0),Location(2541, 3171, 0),Location(2542, 3167, 0),Location(2541, 3168, 0)) + val spiritTree = getScenery(2543,3168,0) + override fun pulse(): Boolean { + when (count) { + 0 -> { + forceWalk(player!!,Location(2542, 3170, 0),"DUMB") + } + 2 -> { + player!!.faceLocation(Location(2543,3170,0)) + for((i, spot) in gnomeSpots.withIndex()){ + val gnome = RegionManager.getNpc(spot, NPCs.LOCAL_GNOME_484, 1) + gnome!!.faceLocation(Location(2543,3169,0)) + gnome.animate(Animation(197)) + if(i < 2) + gnome.sendChat("En tanai.") + else + gnome.sendChat("Su tana.") + } + + } + 3 -> { + player!!.packetDispatch.sendGraphic(orbsOfProtection) + } + 5 -> { + player!!.packetDispatch.sendSceneryAnimation(spiritTree, spiritTreeWithOrbs, false) + sendDialogue(player!!,"The orbs of protection come to rest gently in the branches of the ancient spirit tree.") + return true + } + } + count++ + return false + } + }) + // This loops back to the start of the handle.. + if(removeItem(player!!,Items.ORBS_OF_PROTECTION_588)){ + setQuestStage(player!!, Quests.TREE_GNOME_VILLAGE, 99) + } + stage = 0 + } + } + } else { + when(stage) { + 0 -> playerl("Bolren, I have returned.").also { stage++ } + 1 -> npcl("You made it back! Do you have the orbs?").also { stage++ } + 2 -> playerl("No, I'm afraid not.").also { stage++ } + 3 -> npcl("Please, we must have the orb if we are to survive.").also { stage = END_DIALOGUE } + } + } + } + questStage == 99 -> { + when(stage){ + 0 -> npcl("Now at last my people are safe once more. We can live in peace again.").also { stage++ } + 1 -> playerl("I'm pleased I could help.").also { stage++ } + 2 -> npcl("You are modest brave traveller.").also { stage++ } + 3 -> npcl("Please, for your efforts take this amulet. It's made from the same sacred stone as the orbs of protection. It will help keep you safe on your journeys.").also { stage++ } + 4 -> playerl("Thank you King Bolren.").also { stage++ } + 5 -> npcl("The tree has many other powers, some of which I cannot reveal. As a friend of the gnome people, I can now allow you to use the tree's magic to teleport to other trees grown from related seeds.").also { + finishQuest(player!!, Quests.TREE_GNOME_VILLAGE) + stage = END_DIALOGUE + } + } + } + isQuestComplete(player!!, Quests.TREE_GNOME_VILLAGE) -> { + when(stage) { + 0 -> playerl("Hello again Bolren.").also { stage++ } + 1 -> npcl("Well hello, it's good to see you again.").also { stage = if (hasAnItem(player!!, Items.GNOME_AMULET_589).container != null) END_DIALOGUE else 2 } + 2 -> playerl("I've lost my amulet.").also { stage++ } + 3 -> npcl("Oh dear. Here, take another. We are truly indebted to you.").also { + addItemOrDrop(player!!, Items.GNOME_AMULET_589) + stage = END_DIALOGUE + } + } + } + } + } +} diff --git a/Server/src/main/content/region/kandarin/quest/tree/LieutenantSchepburDialogue.kt b/Server/src/main/content/region/kandarin/quest/tree/LieutenantSchepburDialogue.kt new file mode 100644 index 0000000..7f29582 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/tree/LieutenantSchepburDialogue.kt @@ -0,0 +1,18 @@ +package content.region.kandarin.quest.tree + +import core.game.dialogue.DialogueFile +import core.tools.END_DIALOGUE + +class LieutenantSchepburDialogue : DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + when(stage) { + 0 -> npcl("Move into position lads! eh? Who are you and what do you want?").also { stage++ } + 1 -> playerl("Who are you then?").also { stage++ } + 2 -> npcl("Lieutenant Schepbur, commanding officer of the new Armoured Tortoise Regiment.").also { stage++ } + 3 -> playerl("There's only two tortoises here, that's hardly a regiment.").also { stage++ } + 4 -> npcl("This is just the beginning! Gnome breeders and trainers are already working to expand the number of units. Soon we'll have hundreds of these beauties, nay thousands! And they will not only carry mages and").also { stage++ } + 5 -> npcl("archers but other fiendish weapons of destruction of gnome devising. An army of giant tortoises will march upon this battlefield and rain the fire of our wrath upon all our enemies! Nothing will be able to stop us!").also { stage++ } + 6 -> playerl("Oooookayy...... I'll leave you to it then....").also { stage = END_DIALOGUE } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/tree/LocalGnomeDialogue.kt b/Server/src/main/content/region/kandarin/quest/tree/LocalGnomeDialogue.kt new file mode 100644 index 0000000..b788135 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/tree/LocalGnomeDialogue.kt @@ -0,0 +1,13 @@ +package content.region.kandarin.quest.tree + +import core.game.dialogue.DialogueFile +import core.tools.END_DIALOGUE + +class LocalGnomeDialogue : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> playerl("Hello little man.").also { stage++ } + 1 -> npcl("Little man stronger than big man. Hee hee, lardi dee, lardi da.").also { stage = END_DIALOGUE } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/tree/RemsaiDialogue.kt b/Server/src/main/content/region/kandarin/quest/tree/RemsaiDialogue.kt new file mode 100644 index 0000000..79b70b8 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/tree/RemsaiDialogue.kt @@ -0,0 +1,50 @@ +package content.region.kandarin.quest.tree + +import content.data.Quests +import core.api.inInventory +import core.api.getQuestStage +import org.rs09.consts.Items +import core.game.dialogue.DialogueFile +import core.tools.END_DIALOGUE + +class RemsaiDialogue : DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + val questStage = getQuestStage(player!!, Quests.TREE_GNOME_VILLAGE) + when { + inInventory(player!!,Items.ORBS_OF_PROTECTION_588) -> { + when(stage) { + 0 -> playerl("I've returned.").also { stage++ } + 1 -> npcl("You're back, well done brave adventurer. Now the orbs are safe we can perform the ritual for the spirit tree. We can live in peace once again.").also { stage = END_DIALOGUE } + } + } + inInventory(player!!, Items.ORB_OF_PROTECTION_587) -> { + when(stage) { + 0 -> playerl("Hello Remsai.").also { stage++ } + 1 -> npcl("Hello, did you find the orb?").also { stage++ } + 2 -> playerl("I have it here.").also { stage++ } + 3 -> npcl("You're our saviour.").also { stage = END_DIALOGUE } + } + } + questStage < 40 -> { + when(stage) { + 0 -> playerl("Hello Remsai.").also { stage++ } + 1 -> npcl("Hello, did you find the orb?").also { stage++ } + 2 -> playerl("No, I'm afraid not.").also { stage++ } + 3 -> npcl("Please, we must have the orb if we are to survive.").also { stage = END_DIALOGUE } + } + } + questStage == 40 -> { + when(stage) { + 0 -> playerl("Are you ok?").also { stage++ } + 1 -> npcl("Khazard's men came. Without the orb we were defenceless. They killed many and then took our last hope, the other orbs. Now surely we're all doomed. Without them the spirit tree is useless.").also { stage = END_DIALOGUE } + } + } + questStage > 40 -> { + when(stage) { + 0 -> playerl("I've returned.").also { stage++ } + 1 -> npcl("You're back, well done brave adventurer. Now the orbs are safe we can perform the ritual for the spirit tree. We can live in peace once again.").also { stage = END_DIALOGUE } + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/tree/TrackerGnomeOneDialogue.kt b/Server/src/main/content/region/kandarin/quest/tree/TrackerGnomeOneDialogue.kt new file mode 100644 index 0000000..6ad5e30 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/tree/TrackerGnomeOneDialogue.kt @@ -0,0 +1,47 @@ +package content.region.kandarin.quest.tree + +import content.data.Quests +import core.api.* +import org.rs09.consts.Items +import core.game.dialogue.DialogueFile +import core.tools.END_DIALOGUE + +class TrackerGnomeOneDialogue : DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + val questStage = getQuestStage(player!!, Quests.TREE_GNOME_VILLAGE) + when { + questStage >= 40 -> { + when (stage) { + 0 -> playerl("Hello").also { stage++ } + 1 -> npcl("When will this battle end? I feel like I've been fighting forever.").also { stage = END_DIALOGUE } + } + } + questStage > 30 -> { + if(inInventory(player!!, Items.ORB_OF_PROTECTION_587)){ + when(stage) { + 0 -> playerl("How are you tracker?").also { stage++ } + 1 -> npcl("Now we have the orb I'm much better. They won't stand a chance without it.").also { stage = END_DIALOGUE } + } + } else { + when(stage) { + 0 -> playerl("Hello again.").also { stage++ } + 1 -> npcl("Well done, you've broken down their defences. This battle must be ours.").also { stage = END_DIALOGUE } + } + } + } + questStage == 30 -> { + when (stage) { + 0 -> playerl("Do you know the coordinates of the Khazard stronghold?").also { stage++ } + 1 -> npcl("I managed to get one, although it wasn't easy.").also { stage++ } + 2 -> sendDialogue(player!!, "The gnome tells you the height coordinate.").also { + setAttribute(player!!, "/save:treegnome:tracker1", true) + stage++ + } + 3 -> playerl("Well done.").also { stage++ } + 4 -> npcl("The other two tracker gnomes should have the other coordinates if they're still alive.").also { stage++ } + 5 -> playerl("OK, take care.").also { stage = END_DIALOGUE } + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/tree/TrackerGnomeThreeDialogue.kt b/Server/src/main/content/region/kandarin/quest/tree/TrackerGnomeThreeDialogue.kt new file mode 100644 index 0000000..3007013 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/tree/TrackerGnomeThreeDialogue.kt @@ -0,0 +1,68 @@ +package content.region.kandarin.quest.tree + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueFile +import core.tools.END_DIALOGUE + +class TrackerGnomeThreeDialogue : DialogueFile(){ + + private val xcoordMap = mapOf( + 1 to "Less than my hands.", + 2 to "More than my head, less than my fingers.", + 3 to "More than we but less than our feet.", + 4 to "My legs and your legs.") + + override fun handle(componentID: Int, buttonID: Int) { + val questStage = getQuestStage(player!!, Quests.TREE_GNOME_VILLAGE) + when { + questStage == 30 -> { + when(stage) { + 0 -> playerl("Are you OK?").also { stage++ } + 1 -> npcl("OK? Who's OK? Not me! Hee hee!").also { stage++ } + 2 -> playerl("What's wrong?").also { stage++ } + 3 -> npcl("You can't see me, no one can. Monsters, demons, they're all around me!").also { stage++ } + 4 -> playerl("What do you mean?").also { stage++ } + 5 -> npcl("They're dancing, all of them, hee hee.").also { stage++ } + 6 -> sendDialogue(player!!,"He's clearly lost the plot.").also { stage++ } + 7 -> playerl("Do you have the coordinate for the Khazard stronghold?").also { stage++ } + 8 -> npcl("Who holds the stronghold?").also { stage++ } + 9 -> playerl("What?").also { stage++ } + 10 -> { + // Generate the x coordinate answer + if(getAttribute(player!!,"treegnome:xcoord",0) == 0){ + val answer = (1..4).random() + npcl(xcoordMap[answer]) + setAttribute(player!!,"/save:treegnome:xcoord",answer) + } else { + npcl(xcoordMap[getAttribute(player!!,"treegnome:xcoord",1)]) + } + stage++ + } + 11 -> playerl("You're mad").also { stage++ } + 12 -> npcl("Dance with me, and Khazard's men are beat.").also { stage++ } + 13 -> sendDialogue(player!!,"The toll of war has affected his mind.").also { stage++ } + 14 -> playerl("I'll pray for you little man.").also { stage++ } + 15 -> npcl("All day we pray in the hay, hee hee.").also { + setAttribute(player!!, "/save:treegnome:tracker3", true) + stage = END_DIALOGUE + } + } + } + questStage == 31 -> { + when(stage) { + 0 -> playerl("Hello again.").also { stage++ } + 1 -> npcl("Don't talk to me, you can't see me. No one can, just the demons.").also { stage = END_DIALOGUE } + } + } + questStage > 31 -> { + when(stage) { + 0 -> playerl("Hello").also { stage++ } + 1 -> npcl("I feel dizzy, where am I? Oh dear, oh dear I need some rest.").also { stage++ } + 2 -> playerl("I think you do.").also { stage = END_DIALOGUE } + } + } + } + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/tree/TrackerGnomeTwoDialogue.kt b/Server/src/main/content/region/kandarin/quest/tree/TrackerGnomeTwoDialogue.kt new file mode 100644 index 0000000..6a84593 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/tree/TrackerGnomeTwoDialogue.kt @@ -0,0 +1,51 @@ +package content.region.kandarin.quest.tree + +import content.data.Quests +import core.api.* +import org.rs09.consts.Items +import core.game.dialogue.DialogueFile +import core.tools.END_DIALOGUE + +class TrackerGnomeTwoDialogue : DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + val questStage = getQuestStage(player!!, Quests.TREE_GNOME_VILLAGE) + when { + questStage == 30 -> { + when (stage) { + 0 -> playerl("Are you OK?").also { stage++ } + 1 -> npcl("They caught me spying on the stronghold. They beat and tortured me.").also { stage++ } + 2 -> npcl("But I didn't crack. I told them nothing. They can't break me!").also { stage++ } + 3 -> playerl("I'm sorry little man.").also { stage++ } + 4 -> npcl("Don't be. I have the position of the stronghold!").also { stage++ } + 5 -> sendDialogue(player!!, "The gnome tells you the y coordinate.").also { + setAttribute(player!!, "/save:treegnome:tracker2", true) + stage++ + } + 6 -> playerl("Well done.").also { stage++ } + 7 -> npcl("Now leave before they find you and all is lost.").also { stage++ } + 8 -> playerl("Hang in there.").also { stage++ } + 9 -> npcl("Go!").also { stage = END_DIALOGUE } + } + } + questStage >= 40 -> { + when(stage) { + 0 -> playerl("Hello").also { stage++ } + 1 -> npcl("When will this battle end? I feel like I've been locked up my whole life.").also { stage = END_DIALOGUE } + } + } + questStage > 30 -> { + if(inInventory(player!!,Items.ORB_OF_PROTECTION_587)){ + when(stage) { + 0 -> playerl("How are you tracker?").also { stage++ } + 1 -> npcl("Now we have the orb I'm much better. Soon my comrades will come and free me.").also { stage = END_DIALOGUE } + } + } else { + when(stage) { + 0 -> playerl("Hello again.").also { stage++ } + 1 -> npcl("Well done, you've broken down their defences. This battle must be ours.").also { stage = END_DIALOGUE } + } + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/tree/TreeGnomeVillage.kt b/Server/src/main/content/region/kandarin/quest/tree/TreeGnomeVillage.kt new file mode 100644 index 0000000..14f0489 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/tree/TreeGnomeVillage.kt @@ -0,0 +1,96 @@ +package content.region.kandarin.quest.tree + +import core.api.addItemOrDrop +import core.api.inInventory +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.Items +import content.data.Quests + +@Initializable +class TreeGnomeVillage: Quest(Quests.TREE_GNOME_VILLAGE, 125, 124, 2, 111, 0, 1, 9) { + override fun newInstance(`object`: Any?): Quest { + return this + } + + override fun finish(player: Player?) { + super.finish(player) + player ?: return + var ln = 10 + player.packetDispatch.sendItemZoomOnInterface(Items.GNOME_AMULET_589, 230, 277, 5) + drawReward(player,"2 Quest Points", ln++) + drawReward(player,"11,450 Attack XP", ln++) + drawReward(player,"Gnome Amulet of Protection", ln) + player.skills.addExperience(Skills.ATTACK, 11450.0) + addItemOrDrop(player,Items.GNOME_AMULET_589) + player.questRepository.syncronizeTab(player) + } + + override fun drawJournal(player: Player?, stage: Int) { + super.drawJournal(player, stage) + var line = 12 + player?: return + if(stage == 0){ + line(player, "You can start this quest by speaking to !!King Bolren?? in the", line++, stage > 0) + line(player, "!!Tree Gnome Village??", line++, stage > 0) + line++ + } + if(stage >= 10){ + line(player, "King Bolren said that one of their orbs of", line++, stage > 10) + line(player, "protection has been stolen by Khazard troops.", line++, stage > 10) + line(player, "Commander Montai, North !!of the maze, can help you get?? it", line++, stage > 10) + line++ + } + if (stage >= 20) { + line(player, "Commander Montai has asked you to gather !!6 normal logs??", line++, stage > 20) + line(player, "to make more battlements.", line++, stage > 20) + line++ + } + if (stage == 25) { + line(player, "You should ask Commander Montai for further instruction.", line++) + line++ + } + if (stage >= 30) { + line(player, "Commander Montai needs help locating his !!tracker gnomes?? to", line++,stage > 30) + line(player, "gather the coordinates to strike the Khazard stronghold", line++, stage > 30) + line(player, "You must speak with:", line++, stage > 30) + line(player, "Tracker Gnome 1", line++, player.getAttribute("treegnome:tracker1",false)) + line(player, "Tracker Gnome 2", line++, player.getAttribute("treegnome:tracker2",false)) + line(player, "Tracker Gnome 3", line++, player.getAttribute("treegnome:tracker3",false)) + line++ + } + if (stage >= 31) { + line(player, "The ballista opened a hole in the !!Khazard stronghold??.", line++, stage > 31) + line(player, "Commander Montai says the !!Orb of Protection?? should be in there", line++, stage > 31) + line++ + } + if (inInventory(player,Items.ORB_OF_PROTECTION_587)) { + line(player, "You've retrieved the orb! You should return it to !!King Bolren??", line++) + } + if (stage >= 40) { + line(player, "Khazard troops took the other !!Orbs of Protection?? ", line++, stage > 40) + line(player, "They were headed north of the stronghold.", line++, stage > 40) + line(player,"A warlord carries the orbs.",line++, stage > 40) + line++ + } + if (inInventory(player,Items.ORBS_OF_PROTECTION_588)) { + line(player, "You've retrieved the orbs!", line++) + line(player, "You should return them it to !!King Bolren??",line++) + } + if (stage >= 99) { + line(player,"You have returned the orbs!", line++, stage > 99) + line(player, "Speak with King Bolren for a reward!", line++, stage > 99) + line++ + } + if (stage == 100) { + line(player,"%%QUEST COMPLETE!&&", line, stage > 99) + } + } + companion object { + val mazeVillage = Location(2515,3159,0) + val mazeEntrance = Location(2504,3192,0) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/tree/TreeGnomeVillageListeners.kt b/Server/src/main/content/region/kandarin/quest/tree/TreeGnomeVillageListeners.kt new file mode 100644 index 0000000..71471bf --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/tree/TreeGnomeVillageListeners.kt @@ -0,0 +1,177 @@ +package content.region.kandarin.quest.tree + +import content.data.Quests +import core.api.* +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import content.global.skill.agility.AgilityHandler +import core.game.node.scenery.Scenery +import core.game.node.scenery.SceneryBuilder +import core.game.system.task.Pulse +import core.game.world.map.Direction +import core.game.world.map.Location +import core.game.world.map.RegionManager +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import core.game.dialogue.DialogueFile +import content.region.kandarin.quest.tree.TreeGnomeVillage.Companion.mazeEntrance +import content.region.kandarin.quest.tree.TreeGnomeVillage.Companion.mazeVillage +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.game.world.GameWorld + +class TreeGnomeVillageListeners : InteractionListener { + private val ballista = 2181 + private val crumbledWall = 12762 + private val closedChest = 2183 + private val looseRailing = 2186 + private val openedChest = 2182 + private val strongholdDoor = 2184 + + override fun defineDestinationOverrides() { + setDest(IntType.NPC, intArrayOf(NPCs.TRACKER_GNOME_2_482),"talk-to"){ _, _ -> + return@setDest Location.create(2524, 3256, 0) + } + } + + override fun defineListeners() { + on(NPCs.KING_BOLREN_469, IntType.NPC, "talk-to"){ player, npc -> + openDialogue(player, KingBolrenDialogue(), npc) + return@on true + } + on(NPCs.ELKOY_5179, IntType.NPC, "talk-to"){ player, npc -> + openDialogue(player, ElkoyDialogue(), npc) + return@on true + } + on(NPCs.ELKOY_5182, IntType.NPC, "talk-to"){ player, npc -> + openDialogue(player, ElkoyDialogue(), npc) + return@on true + } + on(NPCs.ELKOY_5182, IntType.NPC, "follow"){ player, _ -> + ElkoyDialogue().travelCutscene(player, if (player.location.y > 3161) mazeVillage else mazeEntrance) + return@on true + } + on(NPCs.COMMANDER_MONTAI_470, IntType.NPC, "talk-to"){ player, npc -> + openDialogue(player, CommanderMontaiDialogue(), npc) + return@on true + } + on(NPCs.TRACKER_GNOME_1_481, IntType.NPC, "talk-to"){ player, npc -> + openDialogue(player, TrackerGnomeOneDialogue(), npc) + return@on true + } + on(NPCs.TRACKER_GNOME_2_482, IntType.NPC, "talk-to"){ player, npc -> + openDialogue(player, TrackerGnomeTwoDialogue(), npc) + return@on true + } + on(NPCs.TRACKER_GNOME_3_483, IntType.NPC, "talk-to"){ player, npc -> + openDialogue(player, TrackerGnomeThreeDialogue(), npc) + return@on true + } + on(NPCs.KHAZARD_WARLORD_477, IntType.NPC, "talk-to"){ player, npc -> + openDialogue(player, KhazardWarlordDialogue(), npc) + return@on true + } + on(NPCs.REMSAI_472, IntType.NPC, "talk-to"){ player, npc -> + openDialogue(player, RemsaiDialogue(), npc) + return@on true + } + on(NPCs.LOCAL_GNOME_484, IntType.NPC, "talk-to"){ player, npc -> + openDialogue(player, LocalGnomeDialogue(), npc) + return@on true + } + on(ballista, IntType.SCENERY, "fire"){ player, _ -> + openDialogue(player, BallistaDialogue()) + return@on true + } + on(looseRailing, IntType.SCENERY, "squeeze-through"){ player, _ -> + squeezeThrough(player) + return@on true + } + on(crumbledWall, IntType.SCENERY, "climb-over"){ player, _ -> + openDialogue(player, ClimbWall()) + return@on true + } + on(closedChest, IntType.SCENERY, "open"){ player, node -> + replaceScenery(node.asScenery(), openedChest, -1) + val upperGuard: NPC = RegionManager.getNpc(player.location, NPCs.KHAZARD_COMMANDER_478, 6) ?: return@on true + upperGuard.sendChat("Oi. You! Get out of there.") + upperGuard.attack(player) + return@on true + } + on(openedChest, IntType.SCENERY, "search"){ player, _ -> + if (getQuestStage(player, Quests.TREE_GNOME_VILLAGE) >= 31) { + if (!hasAnItem(player, Items.ORB_OF_PROTECTION_587).exists()) { + sendDialogue(player, "You search the chest. Inside you find the gnomes' stolen orb of protection.") + addItemOrDrop(player, Items.ORB_OF_PROTECTION_587) + return@on true + } + } + sendMessage(player, "You search the chest but find nothing.") + return@on false + } + on(openedChest, IntType.SCENERY, "close"){ _, node -> + replaceScenery(node.asScenery(), closedChest, -1) + return@on true + } + on(strongholdDoor, IntType.SCENERY, "open"){ player, node -> + if(player.location.y >= 3251){ + core.game.global.action.DoorActionHandler.handleAutowalkDoor(player, node as Scenery) + } + return@on true + } + on(NPCs.LIEUTENANT_SCHEPBUR_3817, IntType.NPC, "talk-to"){ player, node -> + openDialogue(player, LieutenantSchepburDialogue(),node) + return@on true + } + } + + fun squeezeThrough(player: Player){ + val dest = if (player.location.y >= 3161) + player.location.transform(Direction.SOUTH, 1) + else + player.location.transform(Direction.NORTH, 1) + + forceMove(player, player.location, dest, 0, 80, anim = 3844) + } + + private class ClimbWall : DialogueFile() { + val climbAnimation = Animation(839) + val wallLoc = Location(2509,3253,0) + override fun handle(componentID: Int, buttonID: Int) { + if(getQuestStage(player!!, Quests.TREE_GNOME_VILLAGE) > 30){ + val northSouth = if (player!!.location.y <= wallLoc.y) Direction.NORTH else Direction.SOUTH + when(stage){ + 0 -> sendDialogue(player!!,"The wall has been reduced to rubble. It should be possible to climb over the remains").also{ stage++ } + 1 -> AgilityHandler.forceWalk(player!!, -1, player!!.location, player!!.location.transform(northSouth, 2), climbAnimation, 20, 0.0, null).also { + end() + if(northSouth == Direction.SOUTH) return + val lowerGuard: NPC = RegionManager.getNpc(player!!.location, NPCs.KHAZARD_COMMANDER_478, 6) ?: return + GameWorld.Pulser.submit(object : Pulse(0) { + var count = 0 + override fun pulse(): Boolean { + when (count) { + 0 -> { + player!!.lock(4) + lowerGuard.sendChat("What? How did you manage to get in here.") + } + 2 -> { + player!!.sendChat("I've come for the orb.") + } + 3 -> { + lowerGuard.sendChat("I'll never let you take it.") + lowerGuard.attack(player) + player!!.unlock() + return true + } + } + count++ + return false + } + }) + } + } + } + } + } +} diff --git a/Server/src/main/content/region/kandarin/quest/waterfall/AlmeraDialogue.java b/Server/src/main/content/region/kandarin/quest/waterfall/AlmeraDialogue.java new file mode 100644 index 0000000..6d3f2be --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/waterfall/AlmeraDialogue.java @@ -0,0 +1,150 @@ +package content.region.kandarin.quest.waterfall; + +import content.data.Quests; +import core.game.dialogue.DialogueInterpreter; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; + +/** + * Handles Almera's Dialogue for the Waterfall Quest. + * @author Splinter + */ +public class AlmeraDialogue extends DialoguePlugin { + + public AlmeraDialogue() { + + } + + public AlmeraDialogue(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[] { DialogueInterpreter.getDialogueKey("almera_dialogue"), 304 }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + final Quest quest = player.getQuestRepository().getQuest(Quests.WATERFALL_QUEST); + switch (stage) { + /* Main dialogue sequence */ + case 0: + if (quest.getStage(player) == 0) { + interpreter.sendDialogues(304, FacialExpression.ASKING, "Ah, hello there. Nice to see an outsider for a change,", "are you busy? I have a problem."); + stage = 1; + } else if (quest.getStage(player) == 10) { + interpreter.sendDialogues(304, FacialExpression.JOLLY, "Hello brave adventurer, have you seen my boy yet?"); + stage = 200; + } else if (quest.getStage(player) >= 20) { + interpreter.sendDialogues(304, FacialExpression.JOLLY, "Well hello, you're still around then."); + stage = 202; + } else { + + } + break; + case 1: + interpreter.sendOptions("Select an Option", "I'm afraid I'm in a rush.", "How can I help?"); + stage = 2; + break; + case 2: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'm afraid I am in a rush."); + stage = 99; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "How can I help?"); + stage = 3; + break; + } + break; + case 3: + interpreter.sendDialogues(304, FacialExpression.DISGUSTED, "It's my son Hudon, he's always getting into trouble, the", "boy's convinced there's hidden treasure in the river and", "I'm a bit worried about his safety, the poor lad can't", "even swim."); + stage = 4; + break; + case 4: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I could go and take a look for you if you like?"); + stage = 5; + break; + case 5: + interpreter.sendDialogues(304, FacialExpression.DISGUSTED, "Would you? You are kind. You can use the small raft", "out back if you wish, do be careful, the current down", "stream is very strong."); + quest.start(player); + stage = 100; + break; + case 6: + interpreter.sendDialogues(304, FacialExpression.HALF_GUILTY, "Perhaps you can speak to Hadley a further bit down", "south for more information on how to find the treasure."); + stage = 100; + break; + case 7: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I did it, I found the treasure under the waterfall!"); + stage = 8; + break; + case 8: + interpreter.sendDialogues(304, FacialExpression.HALF_GUILTY, "Ah, very well done, adventurer!", "My boy Hudon was searching for that treasure too."); + stage = 9; + break; + case 9: + interpreter.sendDialogues(304, FacialExpression.HALF_GUILTY, "Maybe you could share it with him, he's just a boy."); + stage = 10; + break; + case 10: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "On second thought, I really have to go."); + stage = 100; + break; + + case 99: + interpreter.sendDialogues(304, FacialExpression.HALF_GUILTY, "Oh okay, never mind."); + stage = 100; + break; + case 100: + end(); + break; + case 200: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'm afraid not, but I'm sure he hasn't gone far."); + stage = 201; + break; + case 201: + interpreter.sendDialogues(304, FacialExpression.HALF_GUILTY, "I do hope so, you can't be too careful these days."); + stage = 100; + break; + case 202: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I saw Hudon by the river but he refused to come back", "with me."); + stage = 203; + break; + case 203: + interpreter.sendDialogues(304, FacialExpression.HALF_GUILTY, "Yes he told me, the foolish lad came in drenched to the", "bone, he had fallen into the waterfall, lucky he wasn't", "killed! Now he can spend the rest of the summer in his", "room."); + stage = 204; + break; + case 204: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Any ideas on what I could do while I'm here?"); + stage = 205; + break; + case 205: + interpreter.sendDialogues(304, FacialExpression.HALF_GUILTY, "Why don't you visit the tourist centre south of the", "waterfall?"); + stage = 100; + break; + } + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new AlmeraDialogue(player); + } + + @Override + public boolean open(Object... args) { + final Quest quest = player.getQuestRepository().getQuest(Quests.WATERFALL_QUEST); + if (quest.getStage(player) == 100) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello Almera."); + stage = 7; + } else { + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Hello."); + stage = 0; + } + return true; + } +} diff --git a/Server/src/main/content/region/kandarin/quest/waterfall/BaxtorianBook.kt b/Server/src/main/content/region/kandarin/quest/waterfall/BaxtorianBook.kt new file mode 100644 index 0000000..fe92e91 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/waterfall/BaxtorianBook.kt @@ -0,0 +1,160 @@ +package content.region.kandarin.quest.waterfall + +import content.data.Quests +import content.global.handlers.iface.BookInterface +import content.global.handlers.iface.BookLine +import content.global.handlers.iface.Page +import content.global.handlers.iface.PageSet +import core.api.setAttribute +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import org.rs09.consts.Items + +/** + * Baxtorian Book + * @author ovenbreado + * @author Splinter + */ +class BaxtorianBook : InteractionListener { + + companion object { + private val TITLE = "Book on Baxtorian" + private val CONTENTS = arrayOf( + PageSet( + Page( + BookLine("The missing relics", 55), + BookLine("", 56), + BookLine(" Many artefacts of", 57), + BookLine("elven history were lost", 58), + BookLine("after the fourth age. The", 59), + BookLine("greatest loss to our", 60), + BookLine("collections of elf history", 61), + BookLine("were the hidden treasures", 62), + BookLine("of Baxtorian.", 63), + BookLine(" Some believe these", 64), + BookLine("treasures are still", 65) + ), + Page( + BookLine("unclaimed, but it is more", 66), + BookLine("commonly believed that", 67), + BookLine("dwarf miners recovered", 68), + BookLine("the treasure at the", 69), + BookLine("beginning of the third", 70), + BookLine("age. Another great loss", 71), + BookLine("was Glarial's pebble, a key", 72), + BookLine("which allowed her family", 73), + BookLine("to visit her tomb.", 74), + BookLine(" The stone was taken", 75), + BookLine("by a gnome family over a", 76) + ) + ), + PageSet( + Page( + BookLine("century ago. It is", 55), + BookLine("believed that the gnomes'", 56), + BookLine("descendant Golrie still has", 57), + BookLine("the stone hidden in the", 58), + BookLine("caves under the gnome", 59), + BookLine("tree village.", 60), + BookLine("", 61), + BookLine("The sonnet of Baxtorian", 62), + BookLine("", 63), + BookLine("The love between", 64), + BookLine("Baxtorian and Glarial was", 65) + ), Page( + BookLine("said to have lasted over a", 66), + BookLine("century. They lived a", 67), + BookLine("peaceful life learning and", 68), + BookLine("teaching the laws of", 69), + BookLine("nature. When Baxtorian's", 70), + BookLine("kingdom was invaded by", 71), + BookLine("the dark forces he left on", 72), + BookLine("a five year campaign. He", 73), + BookLine("returned to find his", 74), + BookLine("people slaughtered and his", 75), + BookLine("wife taken by the enemy.", 76) + ) + ), + PageSet( + Page( + BookLine(" After years of", 55), + BookLine("searching for his love he", 56), + BookLine("finally gave up and", 57), + BookLine("returned to the home he", 58), + BookLine("made for Glarial under", 59), + BookLine("the Baxtorian Waterfall.", 60), + BookLine("Once he entered he", 61), + BookLine("never returned. Only", 62), + BookLine("Glarial had the power to", 63), + BookLine("also enter the waterfall.", 64), + BookLine(" Since Baxtorian", 65) + ), + Page( + BookLine("entered no one but her", 66), + BookLine("can follow him in, it's as if", 67), + BookLine("the powers of nature still", 68), + BookLine("work to protect him.", 69), + BookLine("", 70), + BookLine("The power of nature", 71), + BookLine("", 72), + BookLine(" Glarial and Baxtorian", 73), + BookLine("were masters of nature.", 74), + BookLine("Trees would grow, hills", 75), + BookLine("form and rivers flood on", 76) + ) + ), + PageSet( + Page( + BookLine("their command. Baxtorian", 55), + BookLine("in particular had", 56), + BookLine("perfected rune lore. It", 57), + BookLine("was said that he could", 58), + BookLine("uses the stones to control", 59), + BookLine("water, earth, and air.", 60), + BookLine("", 61), + BookLine("Ode to eternity", 62), + BookLine("", 63), + BookLine("A short piece written by", 64), + BookLine("Baxtorian himself.", 65) + ), + Page( + BookLine("", 66), + BookLine("What care I for this", 67), + BookLine("mortal coil,", 68), + BookLine("where treasures are yet", 69), + BookLine("so frail,", 70), + BookLine("for it is you that is my", 71), + BookLine("life blood,", 72), + BookLine("the wine to my holy grail", 73), + BookLine("and if I see the", 74), + BookLine("judgement day,", 75), + BookLine("when the gods fill the air", 76) + ) + ), + PageSet( + Page( + BookLine("with dust,", 55), + BookLine("I'll happily choke on your", 56), + BookLine("memory,", 57), + BookLine("as my kingdom turns to", 58), + BookLine("rust", 59) + ) + ) + ) + private fun display(player: Player, pageNum: Int, buttonID: Int) : Boolean { + BookInterface.pageSetup(player, BookInterface.FANCY_BOOK_3_49, TITLE, CONTENTS) + if (player.questRepository.getQuest(Quests.WATERFALL_QUEST).getStage(player) == 20) { + player.questRepository.getQuest(Quests.WATERFALL_QUEST).setStage(player, 30) + } + return true + } + } + + override fun defineListeners() { + on(Items.BOOK_ON_BAXTORIAN_292, IntType.ITEM, "read") { player, _ -> + BookInterface.openBook(player, BookInterface.FANCY_BOOK_3_49, ::display) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/waterfall/GolrieDialogue.java b/Server/src/main/content/region/kandarin/quest/waterfall/GolrieDialogue.java new file mode 100644 index 0000000..f16af0e --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/waterfall/GolrieDialogue.java @@ -0,0 +1,108 @@ +package content.region.kandarin.quest.waterfall; + +import core.game.dialogue.DialogueInterpreter; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +import static core.api.ContentAPIKt.*; + +/** + * Handles Golrie's Dialogue for the Waterfall quest + * @author Splinter + */ +public class GolrieDialogue extends DialoguePlugin { + + public GolrieDialogue() { + + } + + public GolrieDialogue(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[] { DialogueInterpreter.getDialogueKey("golrie_dialogue"), 306 }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 100: + end(); + break; + + /* Main dialogue sequence */ + case 0: + interpreter.sendDialogues(306, FacialExpression.OLD_NORMAL, "That's me. I've been stuck in here for weeks, those", "goblins are trying to steal my family's heirlooms. My", "grandad gave me all sorts of old junk."); + stage = 1; + break; + case 1: + interpreter.sendDialogues(player, FacialExpression.ASKING, "Do you mind if I have a look?"); + stage = 2; + break; + case 2: + interpreter.sendDialogues(306, FacialExpression.OLD_HAPPY, "No, of course not."); + stage = 3; + break; + case 3: + //TODO: Possibly change this to chat message + interpreter.sendDialogue("You look amongst the junk on the floor."); + if (hasAnItem(player, 294).getContainer() != null) { + stage = 50; + } else { + stage = 4; + } + break; + case 4: + //TODO: Possibly change this to chat message + interpreter.sendDialogue("Mixed with the junk on the floor you find Glarial's pebble."); + stage = 5; + break; + case 5: + //TODO: Possibly change to HAPPY + interpreter.sendDialogues(player, FacialExpression.ASKING, "Could I take this old pebble?"); + stage = 6; + break; + case 6: + interpreter.sendDialogues(306, FacialExpression.OLD_NORMAL, "Oh that, yes have it, it's just some old elven junk I", "believe."); + player.getInventory().add(new Item(294, 1)); + stage = 7; + break; + case 7: + //TODO: Possibly change this to chat message + interpreter.sendDialogue("You give the key to Golrie."); + stage = 8; + break; + case 8: + interpreter.sendDialogues(306, FacialExpression.OLD_HAPPY, "Thanks a lot for the key traveller. I think I'll wait in", "here until those goblins get bored and leave."); + player.getInventory().remove(new Item(293, 1)); + stage = 9; + break; + case 9: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "OK... Take care Golrie."); + stage = 100; + break; + case 50: + //TODO: Possibly change this to chat message + interpreter.sendDialogue("You find nothing of interest."); + stage = 100; + break; + } + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new GolrieDialogue(player); + } + + @Override + public boolean open(Object... args) { + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Hello, is your name Golrie?"); + stage = 0; + return true; + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/waterfall/HadleyDialogue.java b/Server/src/main/content/region/kandarin/quest/waterfall/HadleyDialogue.java new file mode 100644 index 0000000..6ac9e47 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/waterfall/HadleyDialogue.java @@ -0,0 +1,80 @@ +package content.region.kandarin.quest.waterfall; + +import core.game.dialogue.DialogueInterpreter; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.player.Player; +import core.game.world.GameWorld; + +/** + * Handles Almera's Dialogue for the Waterfall Quest. + * @author Splinter + */ +public class HadleyDialogue extends DialoguePlugin { + + public HadleyDialogue() { + + } + + public HadleyDialogue(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[] { DialogueInterpreter.getDialogueKey("hadley_dialogue"), 302 }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 100: + end(); + break; + + /* Main dialogue sequence */ + case 0: + if (player.getInventory().contains(292, 1)) { + interpreter.sendDialogues(302, FacialExpression.HALF_GUILTY, "I hope you're enjoying your stay, there should be lots", "of useful information in that book: places to go, people to", "see."); + stage = 100; + } else { + interpreter.sendDialogues(302, FacialExpression.HALF_GUILTY, "Are you on holiday? If so you've come to the right", "place. I'm Hadley the tourist guide, anything you need", "to know just ask me. We have some of the most unspoilt", "wildlife and scenery in " + GameWorld.getSettings().getName() + "."); + stage = 1; + } + break; + case 1: + interpreter.sendDialogues(302, FacialExpression.HALF_GUILTY, "People come from miles around to fish in the clear lakes", "or to wander the beautiful hill sides."); + stage = 2; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "It is quite pretty."); + stage = 3; + break; + case 3: + interpreter.sendDialogues(302, FacialExpression.HALF_GUILTY, "Surely pretty is an understatement kind " + (player.isMale() ? "Sir. " : "Lady. ") + "Beautiful,", "amazing or possibly life-changing would be more suitable", "wording. Have you seen the Baxtorian waterfall?", "Named after the elf king who was buried underneath."); + stage = 4; + break; + case 4: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Thanks then, goodbye."); + stage = 5; + break; + case 5: + interpreter.sendDialogues(302, FacialExpression.HALF_GUILTY, "Enjoy your visit."); + stage = 100; + break; + } + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new HadleyDialogue(player); + } + + @Override + public boolean open(Object... args) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello there."); + stage = 0; + return true; + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/waterfall/HudonDialogue.java b/Server/src/main/content/region/kandarin/quest/waterfall/HudonDialogue.java new file mode 100644 index 0000000..e8c3262 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/waterfall/HudonDialogue.java @@ -0,0 +1,123 @@ +package content.region.kandarin.quest.waterfall; + +import content.data.Quests; +import core.game.dialogue.DialogueInterpreter; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; + +/** + * Handles Hudon's Dialogue for the Waterfall Quest. + * @author Splinter + */ +public class HudonDialogue extends DialoguePlugin { + + public HudonDialogue() { + + } + + public HudonDialogue(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[] { DialogueInterpreter.getDialogueKey("hudon_dialogue"), 305 }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + final Quest quest = player.getQuestRepository().getQuest(Quests.WATERFALL_QUEST); + switch (stage) { + + case 100: // Generic end to the dlg + end(); + break; + case 101: // Generic end to the dlg + player.getPacketDispatch().sendMessage("Hudon is refusing to leave the waterfall."); + end(); + break; + + /* Main dialogue sequence */ + case 0: + if (quest.getStage(player) == 10) { + interpreter.sendDialogues(305, FacialExpression.CHILD_NORMAL, "It looks like you need the help."); + stage = 1; + } + break; + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Your mum sent me to find you."); + stage = 2; + break; + case 2: + interpreter.sendDialogues(305, FacialExpression.CHILD_NORMAL, "Don't play nice with me, I know you're looking for the", "treasure too."); + stage = 3; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Where is this treasure you talk of?"); + stage = 4; + break; + case 4: + interpreter.sendDialogues(305, FacialExpression.CHILD_SUSPICIOUS, "Just because I'm small doesn't mean I'm dumb! If I", "told you, you would take it all for yourself."); + stage = 5; + break; + case 5: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Maybe I could help."); + stage = 6; + break; + case 6: + interpreter.sendDialogues(305, FacialExpression.CHILD_NORMAL, "I'm fine alone."); + quest.setStage(player, 20); + stage = 101; + break; + case 20: + interpreter.sendDialogues(305, FacialExpression.CHILD_NORMAL, "I'll find that treasure soon, just you wait and see."); + if (quest.getStage(player) == 100) { + stage = 21; + } else { + stage = 100; + } + break; + case 21: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I hate to break it to you kid, but I found the treasure."); + stage = 22; + break; + case 22: + interpreter.sendDialogues(305, FacialExpression.CHILD_NORMAL, "Wha- are you serious? Are you going to at least share?"); + stage = 23; + break; + case 23: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No."); + stage = 24; + break; + case 24: + interpreter.sendDialogues(305, FacialExpression.CHILD_NORMAL, "Aww, come on... I helped you find it.", "This isn't fair!"); + stage = 25; + break; + case 25: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Life ain't fair kid."); + stage = 100; + break; + } + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new HudonDialogue(player); + } + + @Override + public boolean open(Object... args) { + final Quest quest = player.getQuestRepository().getQuest(Quests.WATERFALL_QUEST); + if (quest.getStage(player) >= 20) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "So you're still here."); + stage = 20; + } else { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello son, are you okay? You need help?"); + stage = 0; + } + return true; + } +} diff --git a/Server/src/main/content/region/kandarin/quest/waterfall/MithrilSeedsDialogue.java b/Server/src/main/content/region/kandarin/quest/waterfall/MithrilSeedsDialogue.java new file mode 100644 index 0000000..4a6c28e --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/waterfall/MithrilSeedsDialogue.java @@ -0,0 +1,96 @@ +package content.region.kandarin.quest.waterfall; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; + +/** + * Represents the dialogue plugin used for mithril seeds. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class MithrilSeedsDialogue extends DialoguePlugin { + + /** + * Represents the animation to use. + */ + private static final Animation ANIMATION = new Animation(827); + + /** + * Represents the flower object. + */ + private Scenery flower; + + /** + * Constructs a new {@code MithrilSeedPluginDialogue}. + */ + public MithrilSeedsDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code MithrilSeedPluginDialogue}. + */ + public MithrilSeedsDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new MithrilSeedsDialogue(player); + } + + @Override + public boolean open(Object... args) { + flower = (Scenery) args[0]; + player.getDialogueInterpreter().sendOptions("Select an Option", "Pick the flowers.", "Leave the flowers."); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (interfaceId) { + case 228: // Options chatbox interface id. + switch (buttonId) { + case 1: // First option + player.lock(2); + player.faceLocation(flower.getFaceLocation(player.getLocation())); + player.animate(ANIMATION); + GameWorld.getPulser().submit(new Pulse(2, player, flower) { + @Override + public boolean pulse() { + Item reward = new Item(2460 + ((flower.getId() - 2980) << 1)); + if (reward == null || !player.getInventory().hasSpaceFor(reward)) { + player.getPacketDispatch().sendMessage("Not enough space in your inventory!"); + return true; + } + if (SceneryBuilder.remove(flower)) { + player.getInventory().add(reward); + player.getPacketDispatch().sendMessage("You pick the flowers."); + } + return true; + } + }); + break; + } + break; + } + end(); + return true; + } + + @Override + public int[] getIds() { + return new int[] { 1 << 16 | 1 }; + } + +} diff --git a/Server/src/main/content/region/kandarin/quest/waterfall/MithrilSeedsPlugin.java b/Server/src/main/content/region/kandarin/quest/waterfall/MithrilSeedsPlugin.java new file mode 100644 index 0000000..b085e42 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/waterfall/MithrilSeedsPlugin.java @@ -0,0 +1,92 @@ +package content.region.kandarin.quest.waterfall; + +import core.cache.def.impl.ItemDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.tools.RandomFunction; + +/** + * Represents the plugin used for mithril seeds. + * @author 'Vexia + * @version 1.2 + */ +@Initializable +public final class MithrilSeedsPlugin extends OptionHandler { + + /** + * Represents the item to use. + */ + private static final Item ITEM = new Item(299, 1); + + /** + * Represents the common flower ids. + */ + private static final int FLOWERS[] = { 2980, 2981, 2982, 2983, 2984, 2985, 2986 }; + + /** + * Represents the rare flower ids. + */ + private static final int RARE[] = new int[] { 2987, 2988 }; + + /** + * Represents the animation. + */ + private static final Animation ANIMATION = new Animation(827); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ItemDefinition.forId(299).getHandlers().put("option:plant", this); + return this; + } + + @Override + public boolean handle(final Player player, Node node, String option) { + if (player.getAttribute("delay:plant", -1) > GameWorld.getTicks()) { + return true; + } + if (RegionManager.getObject(player.getLocation()) != null) { + player.getPacketDispatch().sendMessage("You can't plant a flower here."); + return true; + } + player.animate(ANIMATION); + player.getInventory().remove(ITEM); + final Scenery object = SceneryBuilder.add(new Scenery(getFlower(RandomFunction.random(100) == 1 ? RARE : FLOWERS), player.getLocation()), 100); + player.moveStep(); + player.lock(3); + player.getPulseManager().run(new Pulse(1, player) { + @Override + public boolean pulse() { + player.faceLocation(object.getFaceLocation(player.getLocation())); + player.getDialogueInterpreter().open(1 << 16 | 1, object); + return true; + } + }); + player.setAttribute("delay:plant", GameWorld.getTicks() + 3); + player.getPacketDispatch().sendMessage("You open the small mithril case and drop a seed by your feet."); + return true; + } + + @Override + public boolean isWalk() { + return false; + } + + /** + * Gets a random flower from an array. + * @return the flower. + */ + public static int getFlower(int[] array) { + return array[RandomFunction.random(array.length)]; + } + +} diff --git a/Server/src/main/content/region/kandarin/quest/waterfall/WaterFall.java b/Server/src/main/content/region/kandarin/quest/waterfall/WaterFall.java new file mode 100644 index 0000000..33030e2 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/waterfall/WaterFall.java @@ -0,0 +1,85 @@ +package content.region.kandarin.quest.waterfall; + +import content.data.Quests; +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import core.plugin.ClassScanner; + +/** + * The main type for the waterfall quest. + * @author Splinter + */ +@Initializable +public class WaterFall extends Quest { + /** + * Constructs a new {@code WaterFall} {@code Object}. + */ + public WaterFall() { + super(Quests.WATERFALL_QUEST, 65, 64, 1, 65, 0, 1, 10); + } + + @Override + public void drawJournal(Player player, int stage) { + super.drawJournal(player, stage); + switch (stage) { + case 0: + line(player, "I can start this quest by speaking to Almera in her house next to the Baxtorian Falls.I need to be able to fight Level 84 Giants.", 12); + break; + case 10: + line(player, "I spoke to Almera in a house close to the Baxtorianwaterfall. Her son was missing so I offered to help findhim. The boy, Hudon's looking for treasure in the waterfall.", 12); + break; + case 20: + line(player, "I spoke to Almera in a house close to the Baxtorianwaterfall. Her son was missing so I offered to help findhim. The boy, Hudon's looking for treasure in the waterfall.I found Hudon a short raft ride down the river. He isconvinced there is treasure here somewhere. Maybe Ineed to do a little research.", 12); + break; + case 30: + if (player.getInventory().containsItem(new Item(294, 1))) { + line(player, "I spoke to Almera in a house close to the Baxtorianwaterfall. Her son was missing so I offered to help findhim. The boy, Hudon's looking for treasure in the waterfall.I found Hudon a short raft ride down the river. He isconvinced there is treasure here somewhere. Maybe Ineed to do a little research.I found a book in the tourist office about Baxtorian. Thebook tells of a sad love story about 2 elf lovers. It endswith Baxtorian withdrawing to his home under the waterfallafter his wife dies. It is told that only Glarial could entertheir home.The book also mentions Glarial's tomb and a pebble, itappears that the pebble is used to enter the tomb.From what I understand Glarial's pebble was hidden in a cave under the Tree Gnome Village by Golrie's ancestors.", 12); + } else { + line(player, "I spoke to Almera in a house close to the Baxtorianwaterfall. Her son was missing so I offered to help findhim. The boy, Hudon's looking for treasure in the waterfall.I found Hudon a short raft ride down the river. He isconvinced there is treasure here somewhere. Maybe Ineed to do a little research.I found a book in the tourist office about Baxtorian. Thebook tells of a sad love story about 2 elf lovers. It endswith Baxtorian withdrawing to his home under the waterfallafter his wife dies. It is told that only Glarial could entertheir home.The book also mentions Glarial's tomb and a pebble, itappears that the pebble is used to enter the tomb.From what I understand Glarial's pebble was hidden in a cave under the Tree Gnome Village by Golrie's ancestors.", 12); + } + if (player.getInventory().containsItem(new Item(295, 1)) || player.getEquipment().containsAtLeastOneItem(295)) { + line(player, "I spoke to Almera in a house close to the Baxtorianwaterfall. Her son was missing so I offered to help findhim. The boy, Hudon's looking for treasure in the waterfall.I found Hudon a short raft ride down the river. He isconvinced there is treasure here somewhere. Maybe Ineed to do a little research.I found a book in the tourist office about Baxtorian. Thebook tells of a sad love story about 2 elf lovers. It endswith Baxtorian withdrawing to his home under the waterfallafter his wife dies. It is told that only Glarial could entertheir home.The book also mentions Glarial's tomb and a pebble, itappears that the pebble is used to enter the tomb.From what I understand Glarial's pebble was hidden in a cave under the Tree Gnome Village by Golrie's ancestors.Inside the tomb I found Glarial's amulet and ashes.", 12); + } + if (player.getLocation().getY() >= 9902) { + line(player, "I spoke to Almera in a house close to the Baxtorianwaterfall. Her son was missing so I offered to help findhim. The boy, Hudon's looking for treasure in the waterfall.I found Hudon a short raft ride down the river. He isconvinced there is treasure here somewhere. Maybe Ineed to do a little research.I found a book in the tourist office about Baxtorian. Thebook tells of a sad love story about 2 elf lovers. It endswith Baxtorian withdrawing to his home under the waterfallafter his wife dies. It is told that only Glarial could entertheir home.The book also mentions Glarial's tomb and a pebble, itappears that the pebble is used to enter the tomb.From what I understand Glarial's pebble was hidden in a cave under the Tree Gnome Village by Golrie's ancestors.Inside the tomb I found Glarial's amulet and ashes.I finally got access to the derelict home of Baxtorian. Thedoor must have been keyed to Glarial's amulet.I have found a room containing the Chalice of Eternity. Thechalice is suspended in midair just out of reach.", 12); + } + break; + case 100: + line(player, "I spoke to Almera in a house close to the Baxtorianwaterfall. Her son was missing so I offered to help findhim. The boy, Hudon's looking for treasure in the waterfall.I found Hudon a short raft ride down the river. He isconvinced there is treasure here somewhere. Maybe Ineed to do a little research.I found a book in the tourist office about Baxtorian. Thebook tells of a sad love story about 2 elf lovers. It endswith Baxtorian withdrawing to his home under the waterfallafter his wife dies. It is told that only Glarial could entertheir home.The book also mentions Glarial's tomb and a pebble, itappears that the pebble is used to enter the tomb.From what I understand Glarial's pebble was hidden in a cave under the Tree Gnome Village by Golrie's ancestors.Inside the tomb I found Glarial's amulet and ashes.I finally got access to the derelict home of Baxtorian. Thedoor must have been keyed to Glarial's amulet.I have found a room containing the Chalice of Eternity. Thechalice is suspended in midair just out of reach. Using Glarial's ashes as a counterweight, I was able toremove the treasure that had been left in the chalice.QUEST COMPLETE!", 12); + break; + } + } + + @Override + public void finish(Player player) { + super.finish(player); + player.getQuestRepository().syncronizeTab(player); + + player.getPacketDispatch().sendString("1 Quest Point", 277, 8+ 2); + player.getPacketDispatch().sendString("13,750 Strength XP", 277, 9+ 2); + player.getPacketDispatch().sendString("13,750 Attack XP", 277, 10+ 2); + player.getPacketDispatch().sendString("2 diamonds", 277, 11+ 2); + player.getPacketDispatch().sendString("2 gold bars", 277, 12+ 2); + player.getPacketDispatch().sendString("40 Mithril seeds", 277, 13+ 2); + player.getPacketDispatch().sendString("You have completed the Waterfall Quest!", 277, 2+ 2); + player.getPacketDispatch().sendItemZoomOnInterface(1601, 230, 277, 3+ 2); + player.getSkills().addExperience(Skills.STRENGTH, 13750); + player.getSkills().addExperience(Skills.ATTACK, 13750); + player.getInventory().add(new Item(1601, 2));// diamonds + player.getInventory().add(new Item(2357, 2));// gold bars + player.getInventory().add(new Item(299, 40));// seeds + + setStage(player, 100); + player.getQuestRepository().syncronizeTab(player); + } + + @Override + public Quest newInstance(Object object) { + ClassScanner.definePlugins(new AlmeraDialogue(), new GolrieDialogue(), new HadleyDialogue(), new HudonDialogue(), new WaterfallPlugin(), new WaterfallTreeDialogue()); + return this; + } + +} diff --git a/Server/src/main/content/region/kandarin/quest/waterfall/WaterfallListeners.kt b/Server/src/main/content/region/kandarin/quest/waterfall/WaterfallListeners.kt new file mode 100644 index 0000000..eb99eef --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/waterfall/WaterfallListeners.kt @@ -0,0 +1,23 @@ +package content.region.kandarin.quest.waterfall + +import core.game.world.map.Location +import org.rs09.consts.NPCs +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +class WaterfallListeners : InteractionListener { + + val HUDON = NPCs.HUDON_305 + override fun defineListeners() { + on(HUDON, IntType.NPC, "talk-to"){ player, node -> + player.dialogueInterpreter.open(HUDON,node.asNpc()) + return@on true + } + } + + override fun defineDestinationOverrides() { + setDest(IntType.NPC,HUDON){ _, _ -> + return@setDest Location.create(2512, 3481, 0) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/waterfall/WaterfallPlugin.java b/Server/src/main/content/region/kandarin/quest/waterfall/WaterfallPlugin.java new file mode 100644 index 0000000..2a10ebe --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/waterfall/WaterfallPlugin.java @@ -0,0 +1,584 @@ +package content.region.kandarin.quest.waterfall; + +import java.util.ArrayList; +import java.util.List; + +import content.data.Quests; +import core.cache.def.impl.ItemDefinition; +import core.cache.def.impl.NPCDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.game.dialogue.FacialExpression; +import core.game.global.action.ClimbActionHandler; +import core.game.global.action.DoorActionHandler; +import content.global.skill.agility.AgilityHandler; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.OptionHandler; +import core.game.interaction.UseWithHandler; +import core.game.node.Node; +import core.game.node.entity.combat.ImpactHandler.HitsplatType; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; +import kotlin.Unit; +import core.plugin.ClassScanner; + +import static core.api.ContentAPIKt.*; + +/** + * Master plugin file for the Waterfall quest. + * + * This is one of the most disgusting files I have ever seen. -Ceikry + * + * @author Splinter + * @version 1.0 - Feb 28th, 2015 + */ +public final class WaterfallPlugin extends OptionHandler { + + /** + * The rope + */ + public final static Item ROPE = new Item(954); + + /** + * The first ket + */ + public final static Item KEY = new Item(293); + + /** + * The second key + */ + public final static Item KEY_2 = new Item(298); + + /** + * The glarial's pebble + */ + public final static Item PEBBLE = new Item(294); + + /** + * The glarial's amulet + */ + public final static Item AMULET = new Item(295); + + /** + * The glarial's urn + */ + public final static Item URN = new Item(296); + + /** + * The glarial's urn + */ + public final static Item URN_EMPTY = new Item(297); + + /** + * Air rune + */ + public final static Item AIR_RUNE = new Item(556, 6); + + /** + * Water rune + */ + public final static Item WATER_RUNE = new Item(555, 6); + + /** + * Earth rune + */ + public final static Item EARTH_RUNE = new Item(557, 6); + + /** + * The swimmer swimming. + */ + private static final List SWIMMERS = new ArrayList<>(20); + + /** + * The ropes. + */ + private static final List ROPES = new ArrayList<>(20); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ClassScanner.definePlugin(new WaterfallUseWithHandler()); + NPCDefinition.forId(305).getHandlers().put("option:talk-to", this); + SceneryDefinition.forId(1987).getHandlers().put("option:board", this); + SceneryDefinition.forId(2020).getHandlers().put("option:climb", this); + SceneryDefinition.forId(2022).getHandlers().put("option:get in", this); + SceneryDefinition.forId(10283).getHandlers().put("option:swim", this); + SceneryDefinition.forId(1996).getHandlers().put("option:swim to", this); + SceneryDefinition.forId(1989).getHandlers().put("option:search", this); + SceneryDefinition.forId(1990).getHandlers().put("option:search", this); + SceneryDefinition.forId(1991).getHandlers().put("option:open", this); + SceneryDefinition.forId(37247).getHandlers().put("option:open", this); + SceneryDefinition.forId(32711).getHandlers().put("option:open", this); + SceneryDefinition.forId(33046).getHandlers().put("option:open", this); + SceneryDefinition.forId(42313).getHandlers().put("option:open",this); + SceneryDefinition.forId(33047).getHandlers().put("option:search", this); + SceneryDefinition.forId(33047).getHandlers().put("option:close", this); + SceneryDefinition.forId(33066).getHandlers().put("option:search", this); + SceneryDefinition.forId(1999).getHandlers().put("option:search", this); + SceneryDefinition.forId(42319).getHandlers().put("option:climb-up", this); + SceneryDefinition.forId(2002).getHandlers().put("option:open", this); + SceneryDefinition.forId(1992).getHandlers().put("option:read", this); + SceneryDefinition.forId(2014).getHandlers().put("option:take treasure", this); + return this; + } + + @Override + public boolean handle(final Player player, Node node, String option) { + final int id = node.getId(); + final Quest quest = player.getQuestRepository().getQuest(Quests.WATERFALL_QUEST); + if (quest == null) { + player.sendMessage("Error! Waterfall quest cannot be found."); + return true; + } + switch (id) { + case 37247: + player.getPacketDispatch().sendMessage("The door opens..."); + player.getPulseManager().run(new Pulse(2, player) { + @Override + public boolean pulse() { + if ((player.getEquipment().containsAtLeastOneItem(295) || player.getInventory().contains(295, 1)) || player.getQuestRepository().isComplete(Quests.WATERFALL_QUEST)) { + player.getPacketDispatch().sendMessage("You walk through the door."); + player.teleport(new Location(2575, 9861)); + } else { + player.getPacketDispatch().sendMessage("The cave floods and washes you away!"); + player.teleport(new Location(2527, 3413)); + } + return true; + } + }); + break; + case 1992: + player.lock(16); + player.getPacketDispatch().sendMessage("The grave is covered in elven script.", 1); + player.getPacketDispatch().sendMessage("Some of the writing is in common tongue, it reads:", 3); + player.getPacketDispatch().sendMessage("Here lies Glarial, wife of Baxtorian,", 6); + player.getPacketDispatch().sendMessage("true friend of nature in life and death.", 9); + player.getPacketDispatch().sendMessage("May she now rest knowing", 12); + player.getPacketDispatch().sendMessage("only visitors with peaceful intent can enter.", 15); + break; + case 2014: + if (quest.getStage(player) != 100) { + player.getPacketDispatch().sendMessage("The cavern floods!"); + player.lock(6); + player.getPulseManager().run(new Pulse(5, player) { + @Override + public boolean pulse() { + player.teleport(new Location(2566, 9901)); + player.getPacketDispatch().sendMessage("You are washed out of the chalice room."); + player.removeAttribute("waterfall_placed_runes"); + return true; + } + }); + } else { + player.getPacketDispatch().sendMessage("You have already looted the treasure."); + } + break; + case 1999:// Second key (in the actual waterfall dungeon) + if (inInventory(player, 298,1) || quest.getStage(player) < 30) { + sendMessage(player, "You search the crate and find nothing."); + } else if (quest.getStage(player) >= 30 && !inInventory(player,298, 1)) { + sendMessage(player, "You find a large key."); + addItemOrDrop(player, 298, 1); + } + break; + case 2002:// + if (player.getLocation().equals(new Location(2568, 9893))) { + player.getPacketDispatch().sendMessage("The door is locked."); + } else if (node.getLocation().equals(new Location(2566, 9901)) || player.getLocation().equals(new Location(2568, 9894, 0))) { + if (quest.getStage(player) >= 100 && node.getLocation().equals(new Location(2566, 9901)) && player.getLocation().equals(new Location(2566, 9901))) { + player.teleport(new Location(2604, 9901)); + } else { + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + } + } + if (node.getLocation().equals(new Location(2604, 9900))) { + player.teleport(new Location(2566, 9901)); + player.removeAttribute("waterfall_placed_runes"); + } + break; + case 33046: + SceneryBuilder.add(new Scenery(33047, Location.create(2530, 9844, 0), 10, 1)); + break; + case 42319: + if (node.getLocation().equals(new Location(2556, 9844))) { + ClimbActionHandler.climb(player, new Animation(828), Location.create(2557, 3444, 0)); + } else { + ClimbActionHandler.climbLadder(player, (Scenery) node, option); + } + break; + case 33047: + switch (option) { + case "open": + case "search": + if (quest.getStage(player) >= 30) { + if (!player.hasItem(new Item(295))) { + player.getPacketDispatch().sendMessage("You search the chest and find a small amulet."); + player.getInventory().add(new Item(295, 1)); + } else { + player.getPacketDispatch().sendMessage("You search the chest and find nothing."); + } + } + break; + case "close": + SceneryBuilder.add(new Scenery(33046, Location.create(2530, 9844, 0), 10, 1)); + break; + } + break; + case 33066: + if (quest.getStage(player) >= 30) { + if (!player.getInventory().contains(296, 1)) { + player.getPacketDispatch().sendMessage("You search the coffin and inside you find an urn full of ashes."); + player.getInventory().add(new Item(296, 1)); + } else { + player.getPacketDispatch().sendMessage("You search the coffin and find nothing."); + } + } + break; + case 32711: + player.teleport(new Location(2511, 3463)); + break; + case 2020: + player.getDialogueInterpreter().open("waterfall_tree_dialogue", 0); + break; + case 305: + player.getDialogueInterpreter().open(305, ((NPC) node)); + break; + case 1990: + if (inInventory(player,293, 1) || quest.getStage(player) < 30) { + sendMessage(player,"You search the crate and find nothing."); + } else if (quest.getStage(player) >= 30 && !inInventory(player,293, 1)) { + sendMessage(player, "You find a large key."); + addItemOrDrop(player,293, 1); + } + break; + case 1991: + if (player.getLocation().getY() >= 9576) { + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + player.getPacketDispatch().sendMessage("You open the gate and walk through."); + } else if (player.getInventory().contains(293, 1) && player.getLocation().getY() < 9576) { + player.getPacketDispatch().sendMessage("The gate is locked. You need to use the key on the door to enter."); + } else { + player.getDialogueInterpreter().sendDialogues(306, FacialExpression.HALF_GUILTY, "Hello? Ah yes, the door is still locked.", "If you want to get in here, you'll need to find the key", "that I hid in some crates in the eastern room."); + } + break; + case 1989: + if (player.getInventory().contains(292, 1) || quest.getStage(player) != 20) { + player.getPacketDispatch().sendMessage("You search the bookcase and find nothing of interest."); + break; + } else if (!player.hasItem(new Item(292)) && quest.getStage(player) == 20) { + player.getInventory().add(new Item(292, 1)); + player.getPacketDispatch().sendMessage("You search the bookcase and find a book named 'Book on Baxtorian'"); + } + break; + case 10283: + case 1996: + player.logoutListeners.put("waterfall", player1 -> { + player1.setLocation(player.getLocation().transform(0,0,0)); + return Unit.INSTANCE; + }); + player.getPacketDispatch().sendGraphic(68); + player.lock(6); + AgilityHandler.walk(player, -1, player.getLocation(), new Location(2512, 3471, 0), Animation.create(164), 0, null); + player.getPacketDispatch().sendMessage("It looks like a long distance, but you swim out into the water."); + player.getPacketDispatch().sendMessage("The current is too strong, you feel yourself being pulled under", 3); + player.getPulseManager().run(new Pulse(6, player) { + @Override + public boolean pulse() { + player.getPacketDispatch().sendMessage("You are washed downstream but feel lucky to be alive."); + player.teleport(new Location(2527, 3413)); + return true; + } + }); + break; + case 2022:// Barrel + player.getPacketDispatch().sendMessage("You get in the barrel and start rocking."); + player.getPacketDispatch().sendMessage("The barrel falls off the ledge."); + player.teleport(new Location(2527, 3413)); + break; + case 1987:// Raft + if (quest.getStage(player) >= 10) { + player.getPacketDispatch().sendMessage("You board the small raft", 2); + player.lock(13); + player.getPacketDispatch().sendMessage("and push off down stream.", 6); + player.getPacketDispatch().sendMessage("The raft is pulled down stream by strong currents", 9); + player.getPulseManager().run(new Pulse(12, player) { + @Override + public boolean pulse() { + player.getPacketDispatch().sendMessage("You crash into a small land mound."); + player.teleport(new Location(2512, 3481)); + return true; + } + }); + } else { + player.getDialogueInterpreter().sendDialogue("You have no reason to board this raft."); + } + return true; + } + return true; + } + + @Override + public Location getDestination(Node node, Node n) { + if (n instanceof NPC) { + NPC npc = ((NPC) n); + if (npc.getId() == 305) { + return Location.create(2512, 3481, 0); + } + } + if (n instanceof Scenery) { + Scenery obj = ((Scenery) n); + if (obj.getId() == 1996 || obj.getId() == 1997) { + return Location.create(2512, 3476, 0); + } + } + return null; + } + + @Override + public boolean isWalk(Player player, Node node) { + return !(node instanceof Item); + } + + @Override + public boolean isWalk() { + return false; + } + + public void handleObjects(boolean add, final Player player) {// very ugly + // code + if (add) { + ROPES.add(new Scenery(1997, Location.create(2512, 3468, 0), 10, 0)); + ROPES.add(new Scenery(1998, Location.create(2512, 3469, 0), 10, 0)); + ROPES.add(new Scenery(1998, Location.create(2512, 3470, 0), 10, 0)); + ROPES.add(new Scenery(1998, Location.create(2512, 3471, 0), 10, 0)); + ROPES.add(new Scenery(1998, Location.create(2512, 3472, 0), 10, 0)); + ROPES.add(new Scenery(1998, Location.create(2512, 3473, 0), 10, 0)); + ROPES.add(new Scenery(1998, Location.create(2512, 3474, 0), 10, 0)); + ROPES.add(new Scenery(1998, Location.create(2512, 3475, 0), 10, 0)); + for (Scenery rope : ROPES) { + SceneryBuilder.add(rope); + } + } else { + for (Scenery rope : ROPES) { + SceneryBuilder.remove(rope); + } + ROPES.clear(); + SceneryBuilder.add(new Scenery(1996, Location.create(2512, 3468, 0), 10, 0)); + + } + } + + /** + * Handles the runestone graphic. + * @param player the player. + */ + public void playRunestoneGraphics(final Player player) { + player.getPacketDispatch().sendGlobalPositionGraphic(580, new Location(2562, 9914)); + player.getPacketDispatch().sendGlobalPositionGraphic(580, new Location(2562, 9912)); + player.getPacketDispatch().sendGlobalPositionGraphic(580, new Location(2562, 9910)); + player.getPacketDispatch().sendGlobalPositionGraphic(580, new Location(2569, 9914)); + player.getPacketDispatch().sendGlobalPositionGraphic(580, new Location(2569, 9912)); + player.getPacketDispatch().sendGlobalPositionGraphic(580, new Location(2569, 9910)); + } + + /** + * Handles using items on objects for the quest. + * @author Splinter + */ + public class WaterfallUseWithHandler extends UseWithHandler { + + private final int[] OBJECTS = new int[] { 1996, 1997, 2020, 1991, 1992, 2002, 2006, 2014, 2004 }; + + /** + * Constructs a new {@Code WaterfallUseWithItemHandler} {@Code + * Object} + */ + public WaterfallUseWithHandler() { + super(ROPE.getId(), KEY.getId(), PEBBLE.getId(), KEY_2.getId(), AMULET.getId(), URN.getId(), AIR_RUNE.getId(), EARTH_RUNE.getId(), WATER_RUNE.getId()); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (int id : OBJECTS) { + addHandler(id, OBJECT_TYPE, this); + } + return this; + } + + @Override + public Location getDestination(Player playa, Node n) { + if (n instanceof Scenery) { + Scenery obj = (Scenery) n; + if (obj.getId() == 1996 || obj.getId() == 1997) { + return Location.create(2512, 3476, 0); + } + } + return null; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + Item useditem = event.getUsedItem(); + final Quest quest = player.getQuestRepository().getQuest(Quests.WATERFALL_QUEST); + final Scenery object = (Scenery) event.getUsedWith(); + + if (useditem.getId() == ROPE.getId() && object.getId() == 1996 || object.getId() == 1997) { + player.lock(8); + player.animate(Animation.create(774)); + SWIMMERS.add(player); + if (SWIMMERS.size() == 0 || ROPES.size() == 0) { + handleObjects(true, player); + } + player.logoutListeners.put("waterfall", player1 -> { + player1.setLocation(player.getLocation().transform(0,0,0)); + return Unit.INSTANCE; + }); + player.getPulseManager().run(new Pulse(2, player) { + @Override + public boolean pulse() { + player.faceLocation(new Location(2512, 3468, 0)); + AgilityHandler.walk(player, -1, player.getLocation(), new Location(2512, 3469, 0), Animation.create(273), 0, null); + player.getPulseManager().run(new Pulse(8, player) { + @Override + public boolean pulse() { + player.teleport(new Location(2513, 3468)); + player.faceLocation(new Location(2512, 3468, 0)); + player.animate(Animation.create(780)); + player.logoutListeners.remove("waterfall"); + return true; + } + + @Override + public void stop() { + super.stop(); + if (SWIMMERS.remove(player) && SWIMMERS.size() == 0) { + handleObjects(false, player); + } + } + }); + return true; + } + }); + } + + if (useditem.getId() == ROPE.getId() && object.getId() == 2020) { + player.getPacketDispatch().sendMessage("You tie the rope to the tree and let yourself down on the ledge."); + player.teleport(new Location(2511, 3463)); + } + + if (useditem.getId() == KEY.getId() && object.getId() == 1991) { + player.getPacketDispatch().sendMessage("The key fits the gate."); + player.getPacketDispatch().sendMessage("You open the gate and walk through."); + DoorActionHandler.handleAutowalkDoor(player, object); + } + + if (useditem.getId() == KEY_2.getId() && object.getId() == 2002 && !object.getLocation().equals(new Location(2566, 9901))) { + player.getPacketDispatch().sendMessage("You open the door and walk through."); + DoorActionHandler.handleAutowalkDoor(player, object); + } + + if (useditem.getId() == PEBBLE.getId() && object.getId() == 1992 && ItemDefinition.canEnterEntrana(player)) { + if (player.getFamiliarManager().hasFamiliar()) { + sendMessage(player, "You can't take a follower into the tomb."); + return false; + } + player.getPacketDispatch().sendMessage("You place the pebble in the gravestone's small indent."); + player.getPacketDispatch().sendMessage("It fits perfectly."); + player.getPacketDispatch().sendMessage("You hear a loud creak.", 4); + player.getPacketDispatch().sendMessage("The stone slab slides back revealing a ladder down.", 7); + player.getPacketDispatch().sendMessage("You climb down to an underground passage.", 12); + player.getPulseManager().run(new Pulse(13, player) { + @Override + public boolean pulse() { + player.getSkills().setPrayerPoints(0); + player.teleport(new Location(2555, 9844)); + return true; + } + }); + } else if (!ItemDefinition.canEnterEntrana(player) && useditem.getId() == PEBBLE.getId() && object.getId() == 1992) { + player.getPacketDispatch().sendMessage("You place the pebble in the gravestone's small indent."); + player.getPacketDispatch().sendMessage("It fits perfectly."); + player.getPacketDispatch().sendMessage("But nothing happens.", 4); + } + + if ((useditem.getId() == AIR_RUNE.getId() || useditem.getId() == EARTH_RUNE.getId() || useditem.getId() == WATER_RUNE.getId()) && object.getId() == 2004) { + if (player.getInventory().contains(555, 6) && player.getInventory().contains(556, 6) && player.getInventory().contains(557, 6)) { + if (player.getAttribute("waterfall_placed_runes") != null) { + player.getPacketDispatch().sendMessage("You have already placed the runes on the pillars."); + return false; + } + playRunestoneGraphics(player); + player.getPacketDispatch().sendMessage("You place one of each runestone on all six of the pillars."); + player.setAttribute("waterfall_placed_runes", 1); + player.getInventory().remove(new Item(AIR_RUNE.getId(), 6)); + player.getInventory().remove(new Item(EARTH_RUNE.getId(), 6)); + player.getInventory().remove(new Item(WATER_RUNE.getId(), 6)); + } else { + player.getPacketDispatch().sendMessage("You do not have enough runestones to place on the pillars."); + } + } + + if (useditem.getId() == AMULET.getId() && object.getId() == 2006 && quest.getStage(player) != 100 && !player.getLocation().equals(new Location(2603, 9914))) { + if (player.getAttribute("waterfall_placed_runes") == null) { + player.getPacketDispatch().sendMessage("You place the amulet around the neck of the statue."); + player.lock(4); + player.getPulseManager().run(new Pulse(3, player) { + @Override + public boolean pulse() { + player.getPacketDispatch().sendGraphic(74); + player.getImpactHandler().manualHit(player, 20, HitsplatType.NORMAL); + player.getPacketDispatch().sendMessage("Rocks fall from the ceiling and hit you in the head."); + return true; + } + }); + } else if (player.getAttribute("waterfall_placed_runes") != null) { + player.lock(7); + player.getInventory().remove(AMULET); + player.getPacketDispatch().sendMessage("You place the amulet around the neck of the statue."); + player.getPacketDispatch().sendMessage("You hear a loud rumble from beneath...", 3); + player.getPacketDispatch().sendMessage("The ground raises up before you!", 6); + player.getPulseManager().run(new Pulse(6, player) { + @Override + public boolean pulse() { + player.teleport(new Location(2603, 9914)); + return true; + } + }); + } + } + + if (useditem.getId() == URN.getId() && object.getId() == 2014 && quest.getStage(player) != 100) { + if (player.getInventory().freeSlots() < 5) { + player.getPacketDispatch().sendMessage("You'll need 5 free inventory slots to take Glarial's treasure."); + return false; + } else { + player.lock(10); + player.getInventory().remove(URN); + player.getInventory().add(URN_EMPTY); + player.getPacketDispatch().sendMessage("You carefully pour the ashes into the chalice"); + player.getPacketDispatch().sendMessage("as you remove the Treasure of Baxtorian", 3); + player.getPacketDispatch().sendMessage("The chalice remains standing.", 6); + player.getPacketDispatch().sendMessage("Inside you find a mithril case", 6); + player.getPacketDispatch().sendMessage("containing 40 seeds,", 6); + player.getPacketDispatch().sendMessage("two diamonds and two gold bars.", 6); + player.getPulseManager().run(new Pulse(8, player) { + @Override + public boolean pulse() { + quest.finish(player); + return true; + } + }); + + } + } + return true; + } + } +} diff --git a/Server/src/main/content/region/kandarin/quest/waterfall/WaterfallTreeDialogue.java b/Server/src/main/content/region/kandarin/quest/waterfall/WaterfallTreeDialogue.java new file mode 100644 index 0000000..54b39a0 --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/waterfall/WaterfallTreeDialogue.java @@ -0,0 +1,80 @@ +package content.region.kandarin.quest.waterfall; + +import core.game.dialogue.DialogueInterpreter; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.combat.ImpactHandler.HitsplatType; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; + +/** + * Handles the dialogue for the tree on the edge of the Waterfall. + * @author Splinter + */ +public class WaterfallTreeDialogue extends DialoguePlugin { + + public WaterfallTreeDialogue() { + + } + + public WaterfallTreeDialogue(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[] { DialogueInterpreter.getDialogueKey("waterfall_tree_dialogue") }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + + case 100: // Generic end to the dlg + end(); + break; + + /* Main dialogue sequence */ + case 0: + player.getDialogueInterpreter().sendOptions("Select an Option", "Climb down anyway", "Back away"); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + end(); + player.getPacketDispatch().sendMessage("You climb down the tree"); + player.animate(new Animation(828)); + player.getPulseManager().run(new Pulse(4, player) { + @Override + public boolean pulse() { + player.getPacketDispatch().sendMessage("and lose your grip."); + player.getPacketDispatch().sendMessage("You get washed away in the current."); + player.teleport(new Location(2527, 3413)); + player.getImpactHandler().manualHit(player, 8, HitsplatType.NORMAL); + return true; + } + }); + break; + case 2: + player.getDialogueInterpreter().sendDialogue("You leave the tree alone."); + stage = 100; + break; + } + } + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new WaterfallTreeDialogue(player); + } + + @Override + public boolean open(Object... args) { + player.getDialogueInterpreter().sendDialogue("It would be difficult to get down this tree without using a rope", "on it first."); + stage = 0; + return true; + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/quest/whileguthixsleeps/WhileGuthixSleeps.kt b/Server/src/main/content/region/kandarin/quest/whileguthixsleeps/WhileGuthixSleeps.kt new file mode 100644 index 0000000..10ea45b --- /dev/null +++ b/Server/src/main/content/region/kandarin/quest/whileguthixsleeps/WhileGuthixSleeps.kt @@ -0,0 +1,106 @@ +package content.region.kandarin.quest.whileguthixsleeps + +import core.api.getQuestStage +import core.api.hasLevelStat +import core.api.isQuestComplete +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import org.rs09.consts.Items +import content.data.Quests + +/** + * While Guthix Sleeps Quest + * + * Not completed. Here is the quest journal in color. https://www.youtube.com/watch?v=lOwoy45ywwA + * Uncomment the @Initializable when it's done. + * + */ +//@Initializable +class WhileGuthixSleeps : Quest(Quests.WHILE_GUTHIX_SLEEPS, 161, 160, 5, 5491, 0, 1, 900) { + + override fun drawJournal(player: Player, stage: Int) { + super.drawJournal(player, stage) + var line = 12 + var stage = getStage(player) + + var started = getQuestStage(player, Quests.WHILE_GUTHIX_SLEEPS) > 0 + + if (!started) { + line(player, "I can start this quest by speaking to !!Radimus Erkle?? in the", line++, false) + line(player, "!!Legends' Guild??, which is located in the !!north-east?? of", line++, false) + line(player, "!!Ardougne??", line++, false) + line++ + line(player, "To complete this quest, I need:", line++, false) + line(player, "!!Level 65 Defence??", line++, hasLevelStat(player, Skills.DEFENCE, 65)) + line(player, "!!Level 75 Magic??", line++, hasLevelStat(player, Skills.MAGIC, 75)) + line(player, "!!Level 65 Herblore??", line++, hasLevelStat(player, Skills.HERBLORE, 65)) + line(player, "!!Level 60 Thieving??", line++, hasLevelStat(player, Skills.THIEVING, 60)) + line(player, "!!Level 55 Hunter??", line++, hasLevelStat(player, Skills.HUNTER, 55)) + line(player, "!!Level 65 Farming??", line++, hasLevelStat(player, Skills.FARMING, 65)) + line(player, "!!Level 23 Summoning??", line++, hasLevelStat(player, Skills.SUMMONING, 23)) + line(player, "I also need to have completed the following quests:", line++, false) + line( + player, + "!!Recipe for Disaster??", + line++, + isQuestComplete(player, Quests.RECIPE_FOR_DISASTER) + ) + line( + player, + "!!Mourning's Ends Part II - The Temple of Light??", + line++, + isQuestComplete(player, Quests.MOURNINGS_END_PART_II) + ) + line(player, "!!Swan Song??", line++, isQuestComplete(player, Quests.SWAN_SONG)) + line( + player, + "!!Zogre Flesh Eaters??", + line++, + isQuestComplete(player, Quests.ZOGRE_FLESH_EATERS) + ) + line(player, "!!Path of Glouphrie??", line++, isQuestComplete(player, Quests.THE_PATH_OF_GLOUPHRIE)) + line(player, "!!Summer's End??", line++, isQuestComplete(player, Quests.SUMMERS_END)) + line(player, "!!Legends' Quest??", line++, isQuestComplete(player, Quests.LEGENDS_QUEST)) + line(player, "!!Dream Mentor??", line++, isQuestComplete(player, Quests.DREAM_MENTOR)) + line( + player, + "!!Hand in the Sand??", + line++, + isQuestComplete(player, Quests.THE_HAND_IN_THE_SAND) + ) + line(player, "!!Tears of Guthix??", line++, isQuestComplete(player, Quests.TEARS_OF_GUTHIX)) + line(player, "!!King's Ransom??", line++, isQuestComplete(player, Quests.KINGS_RANSOM)) + line( + player, + "!!Defender of Varrock??", + line++, + isQuestComplete(player, Quests.DEFENDER_OF_VARROCK) + ) + line(player, "!!Be eligible for entry to the Warriors' Guild??", line++) + line(player, "!!Defeated Bork in the Chaos Tunnels??", line++) + line(player, "!!And gain a total of 270 quest points.??", line++) + line(player, "I have all the !!stats?? and !!requirements?? needed to start and", line++) + line(player, "complete this quest.", line++) + } + } + + override fun finish(player: Player) { + var ln = 10 + super.finish(player) + player.packetDispatch.sendString("You have completed While Guthix Sleeps!", 277, 4) + player.packetDispatch.sendItemZoomOnInterface(Items.LONGBOW_839, 230, 277, 5) + + drawReward(player, "5 Quest Points", ln++) + drawReward(player, "Lump of dragon metal.", ln++) + drawReward(player, "5000 coins.", ln++) + drawReward(player, "Talk to Idria to receive 4 x", ln++) + drawReward(player, "100,000 XP.", ln++) + drawReward(player, "Opportunity to loot Movario's", ln++) + drawReward(player, "base", ln++) + } + + override fun newInstance(`object`: Any?): Quest { + return this + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/seers/dialogue/CamelotGuardDialogue.java b/Server/src/main/content/region/kandarin/seers/dialogue/CamelotGuardDialogue.java new file mode 100644 index 0000000..d8f8562 --- /dev/null +++ b/Server/src/main/content/region/kandarin/seers/dialogue/CamelotGuardDialogue.java @@ -0,0 +1,57 @@ +package content.region.kandarin.seers.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the dialogue plugin used for the camelot guards. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class CamelotGuardDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code CamelotGuardDialogue} {@code Object}. + */ + public CamelotGuardDialogue() { + /** + * empty. + */ + } + + public CamelotGuardDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new CamelotGuardDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Welcome to the Seer's Village courthouse. Court", "is not in session today, so you're not allowed downstairs."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 812 }; + } +} diff --git a/Server/src/main/content/region/kandarin/seers/dialogue/FionellaDialogue.kt b/Server/src/main/content/region/kandarin/seers/dialogue/FionellaDialogue.kt new file mode 100644 index 0000000..ea78bf7 --- /dev/null +++ b/Server/src/main/content/region/kandarin/seers/dialogue/FionellaDialogue.kt @@ -0,0 +1,56 @@ +package content.region.kandarin.seers.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * Dialogue for + * @author qmqz + */ + +@Initializable +class FionellaDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npc(FacialExpression.FRIENDLY,"Can I help you at all?").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + + 0 -> { + options("Yes please. What are you selling?", "No thanks.").also { stage++ } + } + + 1 -> when(buttonId){ + 1 -> { + player(FacialExpression.FRIENDLY, "Yes please. What are you selling?").also { stage = 10 } + } + + 2 -> { + player(FacialExpression.FRIENDLY, "No thanks.").also { stage = 99 } + } + } + + 10 -> npc(FacialExpression.FRIENDLY, "Take a look.").also { stage = 100 } + + 99 -> end() + 100 -> end().also { npc.openShop(player) } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return FionellaDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.FIONELLA_932) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/seers/dialogue/GeoffreyDialogue.kt b/Server/src/main/content/region/kandarin/seers/dialogue/GeoffreyDialogue.kt new file mode 100644 index 0000000..87eac97 --- /dev/null +++ b/Server/src/main/content/region/kandarin/seers/dialogue/GeoffreyDialogue.kt @@ -0,0 +1,78 @@ +package content.region.kandarin.seers.dialogue + +import core.Util +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.diary.DiaryType +import core.game.node.item.Item +import core.plugin.Initializable +import org.rs09.consts.Items + +@Initializable +class GeoffreyDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun open(vararg args: Any?): Boolean { + val diary = player.achievementDiaryManager.getDiary(DiaryType.SEERS_VILLAGE) + if (diary.levelRewarded.any()) { + player("Hello there. Are you Geoff-erm-Flax? I've been told that", "you'll give me some flax.") + // If 1 day has not passed since last flax reward + if (player.getAttribute("diary:seers:flax-timer", 0) > System.currentTimeMillis()) { + stage = 98 + return true + } + // If player cannot receive flax reward + if (!player.inventory.hasSpaceFor(Item(Items.FLAX_1780, 1))) { + stage = 99 + return true + } + // Determine flax reward by seers diary reward status + when (diary.reward) { + -1 -> stage = 999 + 0 -> stage = 100 + 1 -> stage = 101 + 2 -> stage = 102 + } + } else { + player("Hello there. You look busy.") + stage = 0 + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return GeoffreyDialogue(player) + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 999 -> end() + 0 -> npc("Yes, I am very busy. Picking GLORIOUS flax.", "The GLORIOUS flax won't pick itself. So I pick it.", "I pick it all day long.").also { stage++ } + 1 -> player("Wow, all that flax must really mount up. What do you do with it all?").also { stage++ } + 2 -> npc("I give it away! I love picking the GLORIOUS flax,", "but, if I let it all mount up, I wouldn't have any", "room for more GLORIOUS flax.").also { stage++ } + 3 -> player("So, you're just picking the flax for fun? You must", "really like flax.").also { stage++ } + 4 -> npc("'Like' the flax? I don't just 'like' flax. The", "GLORIOUS flax is my calling, my reason to live.", "I just love the feeling of it in my hands!").also { stage++ } + 5 -> player("Erm, okay. Maybe I can have some of your spare flax?").also { stage++ } + 6 -> npc("No. I don't trust outsiders. Who knows what depraved", "things you would do with the GLORIOUS flax? Only", "locals know how to treat it right.").also { stage++ } + 7 -> player("I know this area! It's, erm, Seers' Village. There's", "a pub and, er, a bank.").also { stage++ } + 8 -> npc("Pah! You call that local knowledge? Perhaps if you", "were wearing some kind of item from one of the", "seers, I might trust you.").also { stage = 999 } + + 98 -> npc("I've already given you your GLORIOUS flax", "for the day. Come back tomorrow.").also { stage = 999 } // TODO find accurate dialogue + 99 -> npc("Yes, but your inventory is full. Come back", "when you have some space for GLORIOUS flax.").also { stage = 999 } // TODO find accurate dialogue + 100 -> {rewardFlax(30, "Yes. The seers have instructed me to give you an", "allowance of 30 GLORIOUS flax a day. I'm not going", "to argue with them, so here you go.")} // TODO find accurate dialogue + 101 -> {rewardFlax(60, "Yes. Stankers has instructed me to give you an", "allowance of 60 GLORIOUS flax a day. I'm not going", "to argue with a dwarf, so here you go.")} // TODO find accurate dialogue + 102 -> {rewardFlax(120, "Yes. Sir Kay has instructed me to give you an", "allowance of 120 GLORIOUS flax a day. I'm not going", "to argue with a knight, so here you go.")} + } + return true + } + + fun rewardFlax(n: Int, vararg messages: String): Unit { + npc(*messages) + player.inventory.add(Item(Items.FLAX_1780, n)) + player.setAttribute("/save:diary:seers:flax-timer", Util.nextMidnight(System.currentTimeMillis())) + stage = 999 + } + + override fun getIds(): IntArray { + return intArrayOf(8590) + } + +} diff --git a/Server/src/main/content/region/kandarin/seers/dialogue/IgnatiusVulcanDialogue.java b/Server/src/main/content/region/kandarin/seers/dialogue/IgnatiusVulcanDialogue.java new file mode 100644 index 0000000..2d5a757 --- /dev/null +++ b/Server/src/main/content/region/kandarin/seers/dialogue/IgnatiusVulcanDialogue.java @@ -0,0 +1,250 @@ +package content.region.kandarin.seers.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.global.Skillcape; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.tools.RandomFunction; + +/** + * Represents the dialogue used for ignatius vulcan. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class IgnatiusVulcanDialogue extends DialoguePlugin { + + /** + * Represents the animation to use. + */ + private static final Animation ANIMATION = new Animation(733, Priority.HIGH); + + /** + * Constructs a new {@code IgnatiusVulcanDialogue} {@code Object}. + */ + public IgnatiusVulcanDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code IgnatiusVulcanDialogue} {@code Object}. + * @param player the player. + */ + public IgnatiusVulcanDialogue(final Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new IgnatiusVulcanDialogue(player); + } + + @Override + public void init() { + super.init(); + try { + new IgnatiusVulcanNPC().newInstance(null); + } catch (Throwable e) { + e.printStackTrace(); + } + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + npc("Can I help you at all?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + if (Skillcape.isMaster(player, Skills.FIREMAKING)) { + options("Who are you?", "Could I buy a Skillcape of Firemaking?", "No, thanks."); + stage = 100; + } else { + options("Who are you?", "What is that cape you're wearing?", "No, thanks."); + stage = 1; + } + break; + case 100: + switch (buttonId) { + case 1: + player("Who are you?"); + stage = 10; + break; + case 2: + player("Could I buy a Skillcape of Firemaking?"); + stage = 101; + break; + case 3: + player("No, thanks."); + stage = 30; + break; + } + break; + case 101: + npc("Certainly! Right when you give me 99000 coins."); + stage = 102; + break; + case 102: + options("Okay, here you go.", "No, thanks."); + stage = 103; + break; + case 103: + switch (buttonId) { + case 1: + player("Okay, here you go."); + stage = 104; + break; + case 2: + end(); + break; + } + break; + case 104: + if (Skillcape.purchase(player, Skills.FIREMAKING)) { + npc("There you go! Enjoy."); + } + stage = 105; + break; + case 105: + end(); + break; + case 1: + switch (buttonId) { + case 1: + player("Who are you?"); + stage = 10; + break; + case 2: + player("What is that cape you're wearing?"); + stage = 20; + break; + case 3: + player("No, thanks."); + stage = 30; + break; + } + break; + case 10: + npc("My name is Ignatius Vulcan. Once I was - like you -", "an adventurer, but that was before I realised the", "beauty and power of flame! Just look at this..."); + stage = 11; + break; + case 11: + createFire(npc, player.getLocation()); + player.moveStep(); + player.sendChat("Yeeouch!"); + npc("Stare into the flame and witness the purity and power", "of fire! As my attraction to flame grew, so did my skills", "at firelighting. I began to neglect my combat skills, my", "Mining skills and my questing. Who needs such"); + stage = 12; + break; + case 12: + npc("mundane skills when one can harness the power of fire?", "After years of practice I am now the acknowledged", "master of Flame! Everything must be purified by fire!"); + stage = 13; + break; + case 13: + player("Okaaay! err, I'll be going now. Umm, get better soon."); + stage = 14; + break; + case 14: + end(); + break; + case 20: + npc("This is a Skillcape of Firemaking. I was given it in", "recognition of my skill as the greatest firemaker in the", "lands! I AM the Master of Flame!"); + stage = 21; + break; + case 21: + player("Hmm, I'll be going now. Keep a sharp look out for", "those men with their white jackets!"); + stage = 22; + break; + case 22: + end(); + break; + case 30: + end(); + break; + } + return true; + } + + /** + * Method used to create an ignatius fire. + */ + public static void createFire(final NPC npc, final Location location) { + npc.getWalkingQueue().reset(); + npc.getAnimator().forceAnimation(ANIMATION); + if (RegionManager.getObject(location) == null) { + final Scenery fire = new Scenery(2732, location); + SceneryBuilder.add(fire, RandomFunction.random(100, 130)); + npc.faceLocation(fire.getLocation()); + } + } + + @Override + public int[] getIds() { + return new int[] { 4946 }; + } + + /** + * Represents the ignatius vulcan npc as a representation. + * @author 'Vexia + * @version 1.0 + */ + public final class IgnatiusVulcanNPC extends AbstractNPC { + + /** + * Represents the time till the last fire. + */ + private int lastFire; + + /** + * Constructs a new {@code IgnatiusVulcanNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + public IgnatiusVulcanNPC(int id, Location location) { + super(id, location, true); + } + + /** + * Constructs a new {@code IgnatiusVulcanNPC} {@code Object}. + */ + public IgnatiusVulcanNPC() { + super(0, null); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new IgnatiusVulcanNPC(id, location); + } + + @Override + public void tick() { + if (lastFire < GameWorld.getTicks()) { + createFire(this, getLocation()); + lastFire = GameWorld.getTicks() + RandomFunction.random(50, 200); + } + super.tick(); + } + + @Override + public int[] getIds() { + return new int[] { 4946 }; + } + + } +} diff --git a/Server/src/main/content/region/kandarin/seers/dialogue/LegendsGuardDialogue.kt b/Server/src/main/content/region/kandarin/seers/dialogue/LegendsGuardDialogue.kt new file mode 100644 index 0000000..8cacba2 --- /dev/null +++ b/Server/src/main/content/region/kandarin/seers/dialogue/LegendsGuardDialogue.kt @@ -0,0 +1,47 @@ +package content.region.kandarin.seers.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable + +/** + * Dialogue for Legends Guards at the Legends Guild + * @author qmqz + */ +@Initializable +class LegendsGuardDialogue(player: Player? = null) : DialoguePlugin(player){ + fun gender (male : String = "sir", female : String = "madam") = if (player.isMale) male else female + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npc(FacialExpression.FRIENDLY,"! ! ! Attention ! ! !") + stage = 0 + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> npc(FacialExpression.FRIENDLY,"Legends Guild Member Approaching").also { stage++ } + 1 -> npc(FacialExpression.FRIENDLY,"Welcome "+ gender() + "!", "I hope you enjoy your time in the Legends Guild.").also { stage = 99 } + + //while doing legend's quest + 10 -> npc(FacialExpression.FRIENDLY,"I hope the quest is going well " + gender() + ".").also { stage = 99 } + + //after the legend's quest is done + 20 -> npc(FacialExpression.FRIENDLY,"Legends Guild Member Approaching!").also { stage = 99 } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return LegendsGuardDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(398, 399) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/seers/dialogue/PhantuwtiFantstuwiFarSight.java b/Server/src/main/content/region/kandarin/seers/dialogue/PhantuwtiFantstuwiFarSight.java new file mode 100644 index 0000000..aaaa62e --- /dev/null +++ b/Server/src/main/content/region/kandarin/seers/dialogue/PhantuwtiFantstuwiFarSight.java @@ -0,0 +1,103 @@ +package content.region.kandarin.seers.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Handles the PhantuwtiFantstuwiFarSight dialogue. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class PhantuwtiFantstuwiFarSight extends DialoguePlugin { + + /** + * Constructs a new {@code PhantuwtiFantstuwiFarSight} {@code Object}. + */ + public PhantuwtiFantstuwiFarSight() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code PhantuwtiFantstuwiFarSight} {@code Object}. + * @param player the player. + */ + public PhantuwtiFantstuwiFarSight(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new PhantuwtiFantstuwiFarSight(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendOptions("Select an Option", "Hello, what is this place?", "What do you do here?", "Do you have any quests?", "Ok, thanks."); + stage = 0; + return true; + } + + @Override + public int[] getIds() { + return new int[] { 1798 }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.ASKING, "Hello, what is this place?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_ASKING, "What do you do here?"); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_ASKING, "Do you have any quests?"); + stage = 30; + break; + case 4: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Ok, thanks."); + stage = 40; + break; + + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "This is Seers Village! We're an organisation of mystically", "gifted people with the power of foresight...we see things", "that have yet to come to pass."); + stage = 11; + break; + case 11: + interpreter.sendOptions("Select an Option", "Hello, what is this place?", "What do you do here?", "Do you have any quests?", "Ok, thanks."); + stage = 0; + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "A lot of our time is spent addressing everyday sorts of", "things, plus we meditate a lot and enhance our", "powers of mystical foresight."); + stage = 31; + break; + case 30: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Unfortunately no, sorry, but if adventure is what you", "seek, try checking through your quest list!"); + stage = 31; + break; + case 31: + interpreter.sendOptions("Select an Option", "Hello, what is this place?", "What do you do here?", "Do you have any quests?", "Ok, thanks."); + stage = 0; + break; + case 40: + end(); + break; + } + return true; + } + +} diff --git a/Server/src/main/content/region/kandarin/seers/dialogue/SeerBartenderDialogue.java b/Server/src/main/content/region/kandarin/seers/dialogue/SeerBartenderDialogue.java new file mode 100644 index 0000000..d55659f --- /dev/null +++ b/Server/src/main/content/region/kandarin/seers/dialogue/SeerBartenderDialogue.java @@ -0,0 +1,156 @@ +package content.region.kandarin.seers.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.game.node.item.Item; + +/** + * Handles the SeerBartenderDialogur dialogue. + * @author 'Vexia + */ +@Initializable +public class SeerBartenderDialogue extends DialoguePlugin { + + public SeerBartenderDialogue() { + + } + + public SeerBartenderDialogue(Player player) { + super(player); + } + + public void buy(int item, int ammount) { + if (player.getInventory().freeSlots() == 0) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I don't seem to have room, sorry."); + stage = 99; + } + if (!player.getInventory().contains(995, ammount)) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Sorry, I don't seem to have enough coins."); + stage = 99; + } else { + end(); + player.getInventory().remove(new Item(995, ammount)); + player.getInventory().add(new Item(item, 1)); + if (item == 1917) { + player.getPacketDispatch().sendMessage("You buy a beer."); + } else if (item == 2327) { + player.getPacketDispatch().sendMessage("You buy a nice hot meat pie."); + } else { + player.getPacketDispatch().sendMessage("You buy a bowl of home made stew."); + } + } + } + + @Override + public int[] getIds() { + return new int[] { 738, 737 }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "What do you have?", "Beer please.", "I don't really want anything thanks."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What do you have?"); + stage = 30; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Beer please."); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I don't really want anything thanks."); + stage = 67; + break; + + } + break; + case 67: + end(); + break; + case 30: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Well we have beer, or if you want some food, we have", "our home made stew and meat pies."); + stage = 31; + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "One beer comng up. Ok, that'll be two coins."); + stage = 101; + break; + case 10: + end(); + break; + case 31: + interpreter.sendOptions("Select an Option", "Beer please.", "I'll try the meat pie.", "Could I have some stew please?", "I don't really want anything thanks."); + stage = 32; + break; + case 32: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Beer please."); + stage = 100; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'll try the meat pie."); + stage = 200; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Could I have some stew please?"); + stage = 300; + break; + case 4: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I don't really want anything thanks."); + stage = 99; + break; + + } + break; + case 99: + end(); + break; + case 100: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "One beer comng up. Ok, that'll be two coins."); + stage = 101; + break; + case 101: + buy(1917, 2); + break; + case 200: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Okay, that will be 16 coins."); + stage = 201; + break; + case 201: + buy(2327, 16); + break; + case 300: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "A bowl of stew, that'll be 20 coins please."); + stage = 301; + break; + case 301: + buy(2003, 20); + break; + } + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new SeerBartenderDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Good morning, what would you like?"); + stage = 0; + return true; + } +} diff --git a/Server/src/main/content/region/kandarin/seers/dialogue/SeerDialogue.kt b/Server/src/main/content/region/kandarin/seers/dialogue/SeerDialogue.kt new file mode 100644 index 0000000..c4d8a4e --- /dev/null +++ b/Server/src/main/content/region/kandarin/seers/dialogue/SeerDialogue.kt @@ -0,0 +1,108 @@ +package content.region.kandarin.seers.dialogue + +import content.region.kandarin.seers.diary.SeerDiaryDialogue +import content.region.kandarin.quest.scorpioncatcher.SCSeerDialogue +import content.region.kandarin.quest.scorpioncatcher.ScorpionCatcher +import core.api.getAttribute +import core.api.getQuestStage +import core.api.isQuestInProgress +import core.api.openDialogue +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs +import core.game.dialogue.Topic +import content.data.Quests + + + +@Initializable +class SeerDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun getIds(): IntArray { + return intArrayOf(NPCs.SEER_388) + } + + companion object { + const val OTHER_TOPIC = 10 + const val DIARY = 20 + const val SC_QUEST = 30 + + const val SC_QUEST_HELP = 40 + const val SC_QUEST_FRIEND = 50 + const val SC_QUEST_OTHER_SCORPIONS = 60 + + const val MANY_GREETINGS = 70 + const val POWER = 80 + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npcl(FacialExpression.WORRIED, "Uh, what was that dark force? I've never sensed anything like it...").also { stage = START_DIALOGUE } // https://www.youtube.com/watch?v=mYsxit46rGo May 14 2010 + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + val scorpionCatcherQuestStage = getQuestStage(player, Quests.SCORPION_CATCHER) + when (stage) { + START_DIALOGUE -> + npcl(FacialExpression.NEUTRAL, "Anyway, sorry about that.").also { stage++ } + START_DIALOGUE+1 -> { + if (isQuestInProgress(player, Quests.SCORPION_CATCHER, 1, 99)) { + showTopics( + Topic("Talk about Scorpion Catcher.", SC_QUEST, true), + Topic("Talk about Achievement Diary.", DIARY, true) + ) + } + else { + showTopics( + Topic("Talk about something else.", OTHER_TOPIC, true), + Topic("Talk about achievement diary.", DIARY, true) + ) + } + } + + SC_QUEST -> { + if (scorpionCatcherQuestStage == ScorpionCatcher.QUEST_STATE_TALK_SEERS) { + showTopics( + Topic("I need to locate some scorpions.", SC_QUEST_HELP,), + Topic("Your friend Thormac sent me to speak to you.", SC_QUEST_FRIEND,), + Topic("I seek knowledge and power!", POWER) + ) + } + else if ((scorpionCatcherQuestStage == ScorpionCatcher.QUEST_STATE_DARK_PLACE) and + getAttribute(player!!, ScorpionCatcher.ATTRIBUTE_TAVERLY, false) + ) { + playerl( + FacialExpression.NEUTRAL, + "Hi, I have retrieved the scorpion from near the spiders." + ).also { stage = SC_QUEST_OTHER_SCORPIONS } + } + else { + npcl(FacialExpression.NEUTRAL, "Good luck finding those scorpions.").also { stage = END_DIALOGUE } + } + } + SC_QUEST_HELP, SC_QUEST_FRIEND, SC_QUEST_OTHER_SCORPIONS -> { + // Use the current stage value as the entry point to Seers + openDialogue(player, SCSeerDialogue(scorpionCatcherQuestStage, stage), npc) + } + + OTHER_TOPIC -> showTopics( + Topic("Many greetings.", MANY_GREETINGS), + Topic("I seek knowledge and power!", POWER) + ) + DIARY -> openDialogue(player, SeerDiaryDialogue(), npc) + + MANY_GREETINGS -> npcl(FacialExpression.NEUTRAL, + "Remember, whenever you set out to do something, something else must be done first.").also { stage = END_DIALOGUE } + + POWER -> npcl(FacialExpression.NEUTRAL, "Knowledge comes from experience, power comes from battleaxes.").also { stage = END_DIALOGUE } + + } + return true + } +} diff --git a/Server/src/main/content/region/kandarin/seers/diary/SeerDiaryDialogue.kt b/Server/src/main/content/region/kandarin/seers/diary/SeerDiaryDialogue.kt new file mode 100644 index 0000000..e0eb617 --- /dev/null +++ b/Server/src/main/content/region/kandarin/seers/diary/SeerDiaryDialogue.kt @@ -0,0 +1,87 @@ +package content.region.kandarin.seers.diary + +import core.api.sendItemDialogue +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.link.diary.AchievementDiary +import core.game.node.entity.player.link.diary.DiaryType +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE + +class SeerDiaryDialogue : DialogueFile() { + + companion object { + + const val LOST_HEAD_BAND = 20 + const val HEAD_BAND_HELP = 30 + const val CLAIM_HEAD_BAND = 40 + const val ASK_FOR_HELP = 50 + } + + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + START_DIALOGUE ->{ + if (AchievementDiary.canReplaceReward(player, DiaryType.SEERS_VILLAGE, 0)) { + playerl(FacialExpression.SAD, "I seem to have lost my seers' headband...").also { + stage = LOST_HEAD_BAND + } + } else if (AchievementDiary.hasClaimedLevelRewards(player, DiaryType.SEERS_VILLAGE, 0)) { + playerl(FacialExpression.ASKING, "Can you remind me what my headband does?").also { + stage = HEAD_BAND_HELP + } + } else if (AchievementDiary.canClaimLevelRewards(player, DiaryType.SEERS_VILLAGE, 0)) { + playerl( + FacialExpression.HAPPY, + "Hi. I've completed the Easy tasks in my Achievement Diary." + ).also { + stage = CLAIM_HEAD_BAND + } + } else { + playerl(FacialExpression.ASKING, "Do you have an Achievement Diary for me?").also { + stage = ASK_FOR_HELP + } + } + } + + + LOST_HEAD_BAND -> { + if (AchievementDiary.grantReplacement(player, DiaryType.SEERS_VILLAGE, 0)) + npcl(FacialExpression.ANNOYED, "Here's your replacement. Please be more careful.").also { + stage = END_DIALOGUE + } + else + // This line is just guessed + npcl(FacialExpression.HALF_GUILTY, "It seems your inventory is full").also { stage = END_DIALOGUE } + } + HEAD_BAND_HELP -> npcl(FacialExpression.NEUTRAL, "Your headband marks you as an honourary seer. Geoffrey - who works in the field to the south - will give you free flax every day.").also { + stage = END_DIALOGUE + } + + // This has to be npc otherwise wordwrap goes wrong and extends to 5 lines + ASK_FOR_HELP -> npc(FacialExpression.HAPPY, "I certainly do - we have a set of tasks spanning Seers'", "Village, Catherby, Hemenster and the Sinclair Mansion.", + "Just complete the tasks listed in the Achievement Diary", "and they will be ticked off automatically.").also { stage++ } + ASK_FOR_HELP + 1 -> playerl(FacialExpression.ASKING, "Can you help me out with the Achievement Diary tasks?").also { stage++ } + ASK_FOR_HELP + 2 -> npcl(FacialExpression.SAD, + "I'm afraid not. It is important that adventurers complete the tasks unaided. That way, only the truly worthy collect the spoils.").also { + stage = END_DIALOGUE + } + + CLAIM_HEAD_BAND -> npcl(FacialExpression.HAPPY, "Well done, adventurer. You are clearly a "+(if (player!!.isMale) "man" else "woman")+" of great wisdom. I have a gift for you.").also { stage++ } + CLAIM_HEAD_BAND + 1 -> { + if (!AchievementDiary.flagRewarded(player, DiaryType.SEERS_VILLAGE, 0)) { + npcl(FacialExpression.NEUTRAL, "Come back when you have two free inventory slots.").also { + stage = END_DIALOGUE + } + } else { + sendItemDialogue(player!!, AchievementDiary.getRewards(DiaryType.SEERS_VILLAGE, 0)[0], + "The seer hands you a strange-looking headband and a rusty lamp.").also { stage++ } + } + } + CLAIM_HEAD_BAND + 2 -> npcl(FacialExpression.HAPPY, "You are now an honourary seer and Geoffrey - who works in the field to the south - will give you free flax every day. Don't call him 'Geoffrey' though: he prefers to be known as 'Flax'.").also { stage++ } + CLAIM_HEAD_BAND + 3 -> playerl(FacialExpression.ASKING, "Flax? What sort of name is that for a person?").also { stage++ } + CLAIM_HEAD_BAND + 4 -> npcl(FacialExpression.NEUTRAL, "I know, I know. The poor boy is a simple soul - he just really loves picking flax. A little too much, I fear.").also { + stage = END_DIALOGUE + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/seers/diary/SeersVillageAchievementDiary.kt b/Server/src/main/content/region/kandarin/seers/diary/SeersVillageAchievementDiary.kt new file mode 100644 index 0000000..b42c764 --- /dev/null +++ b/Server/src/main/content/region/kandarin/seers/diary/SeersVillageAchievementDiary.kt @@ -0,0 +1,355 @@ +package content.region.kandarin.seers.diary + +import content.global.handlers.iface.FairyRing +import content.global.handlers.item.withnpc.PoisonChaliceOnKingArthurDialogue +import core.api.inBorders +import core.api.inEquipment +import core.game.diary.DiaryEventHookBase +import core.game.diary.DiaryLevel +import core.game.event.* +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.diary.DiaryType +import core.game.node.item.Item +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +class SeersVillageAchievementDiary : DiaryEventHookBase(DiaryType.SEERS_VILLAGE) { + companion object { + private const val ATTRIBUTE_CUT_YEW_COUNT = "diary:seers:cut-yew" + private const val ATTRIBUTE_BASS_CAUGHT = "diary:seers:bass-caught" + private const val ATTRIBUTE_SHARK_CAUGHT_COUNT = "diary:seers:shark-caught" + private const val ATTRIBUTE_SHARK_COOKED_COUNT = "diary:seers:shark-cooked" + private const val ATTRIBUTE_ELEMENTAL_KILL_FLAGS = "diary:seers:elemental-kills" + private const val ATTRIBUTE_ARCHER_KILL_FLAGS = "diary:seers:archer-kills" + private const val ATTRIBUTE_COAL_TRUCK_FULL = "diary:seers:coal-truck-full" + private const val ATTRIBUTE_FLAX_PICKED = "diary:seers:flax-picked" + + private val SEERS_VILLAGE_AREA = ZoneBorders(2687, 3455, 2742, 3507) + private val SEERS_BANK_AREA = ZoneBorders(2721, 3490, 2730, 3493) + private val SEERS_COAL_TRUCKS_AREA = ZoneBorders(2690, 3502, 2699, 3508) + + private val RANGING_GUILD_LOCATION = Location(2657, 3439) + + private val COMBAT_BRACELETS = arrayOf( + Items.COMBAT_BRACELET_11126, Items.COMBAT_BRACELET4_11118, + Items.COMBAT_BRACELET3_11120, Items.COMBAT_BRACELET2_11122, + Items.COMBAT_BRACELET1_11124 + ) + + private val RANGING_GUILD_ARCHERS = arrayOf( + NPCs.TOWER_ARCHER_688, NPCs.TOWER_ARCHER_689, + NPCs.TOWER_ARCHER_690, NPCs.TOWER_ARCHER_691 + ) + + private val WORKSHOP_ELEMENTALS = arrayOf( + NPCs.FIRE_ELEMENTAL_1019, NPCs.EARTH_ELEMENTAL_1020, + NPCs.AIR_ELEMENTAL_1021, NPCs.WATER_ELEMENTAL_1022 + ) + + private val CHURN_PRODUCT = arrayOf( + Items.CHEESE_1985, Items.POT_OF_CREAM_2130, Items.PAT_OF_BUTTER_6697 + ) + + object EasyTasks { + const val PICK_5_FLAX = 0 + const val WALK_CLOCKWISE_AROUND_MYSTERIOUS_STATUE = 1 + const val SIR_GALAHAD_MAKE_TEA = 2 + const val TAKE_POISON_TO_KING_ARTHUR = 3 + const val SPIN_5_BOW_STRINGS = 4 + const val SINCLAIR_MANSION_FILL_5_POTS_WITH_FLOUR = 5 + const val FORESTERS_ARMS_GIVE_5_LOCALS_GLASS_OF_CIDER = 6 + const val PLANT_JUTE = 7 + const val SINCLAIR_MANSION_USE_CHURN = 8 + const val BUY_CANDLE = 9 + const val PRAY_AT_ALTAR = 10 + const val CATCH_MACKEREL = 11 + } + + object MediumTasks { + const val SINCLAIR_MANSION_USE_FREMENNIK_SHORTCUT = 0 + const val THORMAC_SORCERER_TALK_ABOUT_MYSTIC_STAVES = 1 + const val TRANSPORT_FULL_LOAD_OF_COAL = 2 + const val FIND_HIGHEST_POINT = 3 + const val DEFEAT_EACH_ELEMENTAL_TYPE = 4 + const val TELEPORT_TO_CAMELOT = 5 + const val RANGING_GUILD_KILL_EACH_TOWER_GUARD = 6 + const val RANGING_GUILD_JUDGE_1000_ARCHERY_TICKETS = 7 + const val RANGING_GUILD_BUY_SOMETHING_FOR_TICKETS = 8 + const val USE_FAMILIAR_TO_LIGHT_MAPLE_LOGS = 9 + const val HARRY_GET_PET_FISH = 10 + const val CATHERBY_CATCH_AND_COOK_BASS = 11 + } + + object HardTasks { + const val RANGING_GUILD_TELEPORT = 0 + const val CUT_5_YEW_LOGS = 1 + const val FLETCH_MAGIC_SHORTBOW_INSIDE_BANK = 2 + const val ENTER_SEERS_COURTHOUSE_WITH_PIETY = 3 + const val DIAL_FAIRY_RING_MCGRUBORS_WOOD = 4 + const val LIGHT_MAGIC_LOG = 5 + const val HIGH_ALCH_MAGIC_SHORTBOW_INSIDE_BANK = 6 + const val CATHERBY_CATCH_5_SHARKS = 7 + const val CATHERBY_COOK_5_SHARKS_WITH_COOKING_GAUNTLETS = 8 + const val CHARGE_5_WATER_ORBS_AT_ONCE = 9 + const val GRAPPLE_FROM_WATER_OBELISK_TO_CATHERBY_SHORE = 10 + } + } + + override fun onResourceProduced(player: Player, event: ResourceProducedEvent) { + if (event.source.id == Scenery.OBELISK_OF_WATER_2151 && event.amount >= 5) { + finishTask( + player, + DiaryLevel.HARD, + HardTasks.CHARGE_5_WATER_ORBS_AT_ONCE + ) + } + + when (player.viewport.region.id) { + 10805 -> if (event.itemId == Items.FLAX_1779) { + progressIncrementalTask( + player, + DiaryLevel.EASY, + EasyTasks.PICK_5_FLAX, + ATTRIBUTE_FLAX_PICKED, + 5 + ) + } + + 10806 -> if (event.itemId == Items.YEW_LOGS_1515) { + progressIncrementalTask( + player, + DiaryLevel.HARD, + HardTasks.CUT_5_YEW_LOGS, + ATTRIBUTE_CUT_YEW_COUNT, + 5 + ) + } + + 10807 -> if (event.itemId in CHURN_PRODUCT) { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.SINCLAIR_MANSION_USE_CHURN + ) + } + + 11317 -> when (event.itemId) { + Items.RAW_MACKEREL_353 -> { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.CATCH_MACKEREL + ) + } + + Items.RAW_BASS_363 -> { + fulfillTaskRequirement( + player, + DiaryLevel.MEDIUM, + MediumTasks.CATHERBY_CATCH_AND_COOK_BASS, + ATTRIBUTE_BASS_CAUGHT + ) + } + + Items.BASS_365 -> { + whenTaskRequirementFulfilled(player, ATTRIBUTE_BASS_CAUGHT) { + finishTask( + player, + DiaryLevel.MEDIUM, + MediumTasks.CATHERBY_CATCH_AND_COOK_BASS + ) + } + } + + Items.RAW_SHARK_383 -> { + progressIncrementalTask( + player, + DiaryLevel.HARD, + HardTasks.CATHERBY_CATCH_5_SHARKS, + ATTRIBUTE_SHARK_CAUGHT_COUNT, + 5 + ) + } + + Items.SHARK_385 -> { + if (inEquipment(player, Items.COOKING_GAUNTLETS_775)) { + progressIncrementalTask( + player, + DiaryLevel.HARD, + HardTasks.CATHERBY_COOK_5_SHARKS_WITH_COOKING_GAUNTLETS, + ATTRIBUTE_SHARK_COOKED_COUNT, + 5 + ) + } + } + } + } + } + + override fun onNpcKilled(player: Player, event: NPCKillEvent) { + when (player.viewport.region.id) { + 10906 -> if (event.npc.id in WORKSHOP_ELEMENTALS) { + progressFlaggedTask( + player, + DiaryLevel.MEDIUM, + MediumTasks.DEFEAT_EACH_ELEMENTAL_TYPE, + ATTRIBUTE_ELEMENTAL_KILL_FLAGS, + 1 shl (event.npc.id - NPCs.FIRE_ELEMENTAL_1019), + 0xF + ) + } + + 10549 -> if (event.npc.id in RANGING_GUILD_ARCHERS) { + progressFlaggedTask( + player, + DiaryLevel.MEDIUM, + MediumTasks.RANGING_GUILD_KILL_EACH_TOWER_GUARD, + ATTRIBUTE_ARCHER_KILL_FLAGS, + /* Thanks for sequential NPC IDs, Jagex! */ + 1 shl (event.npc.id - NPCs.TOWER_ARCHER_688), + 0xF + ) + } + } + } + + override fun onTeleported(player: Player, event: TeleportEvent) { + when (event.source) { + is Item -> if (event.source.id in COMBAT_BRACELETS) { + if (event.location == RANGING_GUILD_LOCATION) { + finishTask( + player, + DiaryLevel.HARD, + HardTasks.RANGING_GUILD_TELEPORT + ) + } + } + } + } + + override fun onFireLit(player: Player, event: LitFireEvent) { + when { + inBorders(player, SEERS_VILLAGE_AREA) -> { + if (event.logId == Items.MAGIC_LOGS_1513) { + finishTask( + player, + DiaryLevel.HARD, + HardTasks.LIGHT_MAGIC_LOG + ) + } + } + } + } + + override fun onInteracted(player: Player, event: InteractionEvent) { + when { + inBorders(player, SEERS_COAL_TRUCKS_AREA) -> { + whenTaskRequirementFulfilled(player, ATTRIBUTE_COAL_TRUCK_FULL) { + if (event.option == "remove-coal") { + finishTask( + player, + DiaryLevel.MEDIUM, + MediumTasks.TRANSPORT_FULL_LOAD_OF_COAL + ) + } + } + } + } + } + + override fun onDialogueOptionSelected(player: Player, event: DialogueOptionSelectionEvent) { + when (event.dialogue) { + is PoisonChaliceOnKingArthurDialogue -> { + if (event.currentStage == 4) { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.TAKE_POISON_TO_KING_ARTHUR + ) + } + } + } + } + + override fun onAttributeSet(player: Player, event: AttributeSetEvent) { + when (event.attribute) { + "/save:coal-truck-inventory" -> { + if (event.value !is Int) return + + if (event.value >= 120) { + fulfillTaskRequirement( + player, + DiaryLevel.MEDIUM, + MediumTasks.TRANSPORT_FULL_LOAD_OF_COAL, + ATTRIBUTE_COAL_TRUCK_FULL + ) + } + } + } + } + + override fun onItemAlchemized(player: Player, event: ItemAlchemizationEvent) { + if (inBorders(player, SEERS_BANK_AREA)) { + if (event.itemId == Items.MAGIC_SHORTBOW_861 && event.isHigh) { + finishTask( + player, + DiaryLevel.HARD, + HardTasks.HIGH_ALCH_MAGIC_SHORTBOW_INSIDE_BANK + ) + } + } + } + + override fun onFairyRingDialed(player: Player, event: FairyRingDialEvent) { + if (event.fairyRing == FairyRing.ALS) { + finishTask( + player, + DiaryLevel.HARD, + HardTasks.DIAL_FAIRY_RING_MCGRUBORS_WOOD + ) + } + } + + override fun onItemPurchasedFromShop(player: Player, event: ItemShopPurchaseEvent) { + if (event.itemId == Items.CANDLE_36 && player.viewport.region.id == 11061) { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.BUY_CANDLE + ) + } + + if (event.currency.id == Items.ARCHERY_TICKET_1464) { + finishTask( + player, + DiaryLevel.MEDIUM, + MediumTasks.RANGING_GUILD_BUY_SOMETHING_FOR_TICKETS + ) + } + } + + override fun onInterfaceOpened(player: Player, event: InterfaceOpenEvent) { + if (event.component.id == 332) { + finishTask( + player, + DiaryLevel.MEDIUM, + MediumTasks.THORMAC_SORCERER_TALK_ABOUT_MYSTIC_STAVES + ) + } + } + + override fun onPrayerPointsRecharged(player: Player, event: PrayerPointsRechargeEvent) { + if (player.viewport.region.id == 10806) { + if (event.altar.id == Scenery.ALTAR_409 || event.altar.id == Scenery.ALTAR_19145) { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.PRAY_AT_ALTAR + ) + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/seers/handlers/BuyCrateOptionPlugin.java b/Server/src/main/content/region/kandarin/seers/handlers/BuyCrateOptionPlugin.java new file mode 100644 index 0000000..0c9f81e --- /dev/null +++ b/Server/src/main/content/region/kandarin/seers/handlers/BuyCrateOptionPlugin.java @@ -0,0 +1,32 @@ +package content.region.kandarin.seers.handlers; + +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.game.shops.Shops; +import core.game.system.config.ShopParser; + +/** + * Represents the buy crate option plugin for the seers village city. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class BuyCrateOptionPlugin extends OptionHandler { + + @Override + public boolean handle(Player player, Node node, String option) { + Shops.openId(player, 93); + return true; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(6839).getHandlers().put("option:buy", this); + return this; + } + +} diff --git a/Server/src/main/content/region/kandarin/seers/handlers/CamelotNodePlugin.java b/Server/src/main/content/region/kandarin/seers/handlers/CamelotNodePlugin.java new file mode 100644 index 0000000..cdf3aff --- /dev/null +++ b/Server/src/main/content/region/kandarin/seers/handlers/CamelotNodePlugin.java @@ -0,0 +1,53 @@ +package content.region.kandarin.seers.handlers; + +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the plugin used to handle nodes related to camelot. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class CamelotNodePlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(26017).getHandlers().put("option:climb-down", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + final int id = ((Scenery) node).getId(); + switch (id) { + case 26017: + player.getPacketDispatch().sendMessage("Court is not in session."); + break; + } + return true; + } + + @Override + public Location getDestination(Node node, Node n) { + if (n instanceof Scenery) { + int id = ((Scenery) n).getId(); + switch (id) { + case 993: + if (node.getLocation().getX() <= 2638) { + return Location.create(2637, 3350, 0); + } else { + return Location.create(2640, 3350, 0); + } + } + } + return null; + } + +} diff --git a/Server/src/main/content/region/kandarin/seers/handlers/MysteriousStatueZone.kt b/Server/src/main/content/region/kandarin/seers/handlers/MysteriousStatueZone.kt new file mode 100644 index 0000000..6d62923 --- /dev/null +++ b/Server/src/main/content/region/kandarin/seers/handlers/MysteriousStatueZone.kt @@ -0,0 +1,106 @@ +package content.region.kandarin.seers.handlers + +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.game.world.map.zone.MapZone +import core.game.node.entity.player.link.diary.DiaryType +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import core.game.world.map.zone.ZoneBuilder +import core.plugin.Plugin + +@Initializable +class MysteriousStatueZone : MapZone("mysterious-statue", true), Plugin { + + val northWest = Location.create(2739, 3492, 0) + val northEast = Location.create(2742, 3492, 0) + val southEast = Location.create(2742, 3489, 0) + val southWest = Location.create(2739, 3489, 0) + + + override fun newInstance(arg: Any?): MysteriousStatueZone { + ZoneBuilder.configure(this) + return this + } + + override fun configure() { + super.register(ZoneBorders(2739,3492,2742,3489)) + } + + override fun enter(e: Entity?): Boolean { + return super.enter(e) + } + + override fun fireEvent(identifier: String?, vararg args: Any?): Any { + return Unit + } + + override fun locationUpdate(e: Entity?, last: Location?) { + if (e is Player && !e.isArtificial) { + val player = e.asPlayer() + if(!player.achievementDiaryManager.hasCompletedTask(DiaryType.SEERS_VILLAGE,0,1 ) && player.getAttribute("seersStatueProgress",-1) !in 0..3 ){ + player.setAttribute("seersStatueProgress",0) + println("statue started") + }else{ + when(player.location){ + northWest ->{ + if(player.getAttribute("seersStatueProgress",-1) == 0){ + player.setAttribute("seersStatueProgress",1) + println("location 1 of 4 finished") + println(player.getAttribute("seersStatueProgress",-1)) + }else if(player.getAttribute("seersStatueProgress",-1) in 2..3){ + player.setAttribute("seersStatueProgress",0) + println("location progress reset") + } + } + northEast ->{ + if(player.getAttribute("seersStatueProgress",0) == 1){ + player.setAttribute("seersStatueProgress",2) + println("location 2 of 4 finished") + }else if(player.getAttribute("seersStatueProgress",0) != 1){ + player.setAttribute("seersStatueProgress",0) + println("location progress reset") + } + } + southEast ->{ + if(player.getAttribute("seersStatueProgress",0) == 2){ + player.setAttribute("seersStatueProgress",3) + println("location 3 of 4 finished") + }else if(player.getAttribute("seersStatueProgress",0) != 2){ + player.setAttribute("seersStatueProgress",0) + println("location progress reset") + } + } + southWest ->{ + if(player.getAttribute("seersStatueProgress",0) == 3){ + player.setAttribute("seersStatueProgress",4) + println("location 4 of 4 finished") + }else if(player.getAttribute("seersStatueProgress",0) != 3){ + player.setAttribute("seersStatueProgress",0) + println("location progress reset") + } + } + } + } + if(player.getAttribute("seersStatueProgress",0) == 4){ + player.achievementDiaryManager.finishTask(player,DiaryType.SEERS_VILLAGE,0,1) + player.setAttribute("seersStatueComplete",true) + player.removeAttribute("seersStatueProgress") + } + } + super.locationUpdate(e, last) + } + + override fun leave(e: Entity?, logout: Boolean): Boolean { + if(e is Player && !e.isArtificial){ + val player = e.asPlayer() + if(!player.getAttribute("seersStatueComplete",false) && player.getAttribute("seersStatueProgress",-0) in 0..3){ + player.removeAttribute("seersStatueProgress") + super.leave(e, logout) + }else return super.leave(e, logout) + } + return super.leave(e, logout) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/seers/handlers/RangingGuildPlugin.java b/Server/src/main/content/region/kandarin/seers/handlers/RangingGuildPlugin.java new file mode 100644 index 0000000..5589a4d --- /dev/null +++ b/Server/src/main/content/region/kandarin/seers/handlers/RangingGuildPlugin.java @@ -0,0 +1,1212 @@ +package content.region.kandarin.seers.handlers; + +import java.util.List; + +import core.cache.def.impl.SceneryDefinition; +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.container.impl.EquipmentContainer; +import core.plugin.Initializable; +import org.rs09.consts.Items; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.link.diary.DiaryType; +import core.plugin.ClassScanner; +import core.tools.RandomFunction; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.global.Skillcape; +import core.game.global.action.ClimbActionHandler; +import core.game.global.action.DoorActionHandler; +import core.game.node.entity.skill.Skills; +import content.global.skill.crafting.TanningProduct; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.combat.equipment.Ammunition; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.system.task.Pulse; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; + +import static core.api.ContentAPIKt.*; + +/** + * Represents the plugin used for the ranging guild. + * + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class RangingGuildPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(2514).getHandlers().put("option:open", this); + SceneryDefinition.forId(2511).getHandlers().put("option:climb-up", this); + SceneryDefinition.forId(2512).getHandlers().put("option:climb-down", this); + SceneryDefinition.forId(2513).getHandlers().put("option:fire-at", this); + new RangingGuildDoorman().init(); + new GuardDialogue().init(); + new LeatherWorkerDialogue().init(); + new ArmourSalesman().init(); + new TribalWeaponSalesman().init(); + new BowArrowSalesman().init(); + new WarningInterface().newInstance(arg); + new CompetitionJudge().init(); + ClassScanner.definePlugin(new TowerArcher()); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + final int id = node instanceof Scenery ? ((Scenery) node).getId() : 0; + switch (option) { + case "fire-at": + if (player.getArcheryTargets() <= 0) { + player.getDialogueInterpreter().sendDialogues(693, null, "Sorry, you may only use the targets for the", "competition, not for practicing."); + return true; + } + if (!player.getEquipment().containsItem(new Item(882)) + || player.getEquipment().get(EquipmentContainer.SLOT_WEAPON) == null + || (!player.getEquipment().get(EquipmentContainer.SLOT_WEAPON).getDefinition().getName().toLowerCase().contains("shortbow") + && !player.getEquipment().get(EquipmentContainer.SLOT_WEAPON).getDefinition().getName().toLowerCase().contains("longbow"))) { + player.sendMessage("You must have bronze arrows and a bow equipped."); + return true; + } + player.getPulseManager().run(new ArcheryCompetitionPulse(player, (Scenery) node)); + break; + case "open": + switch (id) { + case 2514: + if (player.getLocation().getY() >= 3438) { + if (player.getSkills().getStaticLevel(Skills.RANGE) < 40) { + player.getDialogueInterpreter().sendDialogue("You need a Ranging level of 40 to enter here."); + return true; + } + } + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node, player.getLocation().getY() >= 3438 ? Location.create(2659, 3437, 0) : Location.create(2657, 3439, 0)); + break; + } + break; + case "climb-up": + switch (id) { + case 2511: + player.setAttribute("ladder", node); + player.getInterfaceManager().open(new Component(564)); + break; + } + break; + case "climb-down": + switch (id) { + case 2512: + ClimbActionHandler.climb(player, null, Location.create(2668, 3427, 0)); + break; + } + break; + } + return true; + } + + @Override + public Location getDestination(Node node, Node n) { + if (n instanceof Scenery) { + if (((Scenery) n).getDefinition().hasAction("open")) { + if (((Scenery) n).getId() == 2514) { + if (node.getLocation().getY() >= 3438) { + return Location.create(2657, 3439, 0); + } else { + return Location.create(2659, 3437, 0); + } + } + return DoorActionHandler.getDestination((Player) node, (Scenery) n); + } + if (((Scenery) n).getId() == 2513) + return Location.create(2673, 3420, 0); + } + return null; + } + + /** + * Represents the dialogue used for the ranging guild door man. + * + * @author 'Vexia + * @version 1.0 + */ + public class RangingGuildDoorman extends DialoguePlugin { + + /** + * Constructs a new {@code RangingGuildDoorman} {@code Object}. + */ + public RangingGuildDoorman() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code RangingGuildDoorman} {@code Object}. + * + * @param player the player. + */ + public RangingGuildDoorman(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new RangingGuildDoorman(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello there."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Greetings. If you are an experienced archer, you may", "want to visit the guild here..."); + stage = 1; + break; + case 1: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[]{679}; + } + } + + /** + * Represents the tribal weapon salseman dialogue. + * + * @author 'Vexia + * @version 1.0 + */ + public final class TribalWeaponSalesman extends DialoguePlugin { + + /** + * Constructs a new {@code TribalWeaponSalesman} {@code Object}. + */ + public TribalWeaponSalesman() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code TribalWeaponSalesman} {@code Object}. + * + * @param player the player. + */ + public TribalWeaponSalesman(final Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new TribalWeaponSalesman(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + player("Hello there."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + npc("Greetings, traveller. Are you interested in any throwing", "weapons?"); + stage = 1; + break; + case 1: + options("Yes I am.", "Not really."); + stage = 2; + break; + case 2: + switch (buttonId) { + case 1: + player("Yes I am."); + stage = 10; + break; + case 2: + player("Not really."); + stage = 20; + break; + } + break; + case 10: + npc("That is a good thing."); + stage = 11; + break; + case 11: + end(); + npc.openShop(player); + break; + case 20: + npc("No bother to me."); + stage = 21; + break; + case 21: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[]{692}; + } + + } + + /** + * Represents the guard dialogue. + * + * @author 'Vexia + * @version 1.0 + */ + public final class GuardDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code GuardDialogue} {@code Object}. + */ + public GuardDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code GuardDialogue} {@code Object}. + * + * @param player the player. + */ + public GuardDialogue(final Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new GuardDialogue(player); + } + + @Override + public boolean open(Object... args) { + player("Hello there."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + npc("Greetings, traveller. Enjoy the time at the Ranging", "Guild."); + stage = 1; + break; + case 1: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[]{678}; + } + + } + + /** + * Represents the leather workers dialogue. + * + * @author 'Vexia + * @version 1.0 + */ + public final class LeatherWorkerDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code LeatherWorkerDialogue} {@code Object}. + */ + public LeatherWorkerDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code LeatherWorkerDialogue} {@code Object}. + * + * @param player the player. + */ + public LeatherWorkerDialogue(final Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new LeatherWorkerDialogue(player); + } + + @Override + public boolean open(Object... args) { + player("Hello."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + npc("Can I help you?"); + stage = 1; + break; + case 1: + options("What do you do here?", "No thanks."); + stage = 2; + break; + case 2: + switch (buttonId) { + case 1: + player("What do you do here?"); + stage = 10; + break; + case 2: + player("No thanks."); + stage = 20; + break; + } + break; + case 10: + npc("Well, I can cure plain cowhides into pieces of leather", "ready for crafting."); + stage = 11; + break; + case 11: + npc("I work with ordinary, hard or dragonhide leather and", "also snakeskin."); + stage = 12; + break; + case 12: + end(); + TanningProduct.open(player, 680); + break; + case 20: + npc("Suit yourself."); + stage = 21; + break; + case 21: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[]{680}; + } + + } + + /** + * Represents the armour salesman dialogue. + * + * @author 'Vexia + * @version 1.0 + */ + public final class ArmourSalesman extends DialoguePlugin { + + /** + * Constructs a new {@code ArmourSalesman} {@code Object}. + */ + public ArmourSalesman() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code ArmourSalesman} {@code Object}. + * + * @param player the player. + */ + public ArmourSalesman(final Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new ArmourSalesman(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + player("Good day to you."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + npc("And to you. Can I help you?"); + stage = 1; + break; + case 1: + if (Skillcape.isMaster(player, Skills.RANGE)) { + options("What do you do here?", "I'd like to see what you sell.", "Can I buy a Skillcape of Range?", "I've seen enough, thanks."); + stage = 100; + } else { + options("What do you do here?", "I'd like to see what you sell.", "I've seen enough, thanks."); + stage = 2; + } + break; + case 2: + switch (buttonId) { + case 1: + player("What do you do here?"); + stage = 10; + break; + case 2: + player("I'd like to see what you sell."); + stage = 20; + break; + case 3: + player("I've seen enough, thanks."); + stage = 30; + break; + } + break; + case 10: + npc("I am a supplier of leather armours and accessories. Ask", "and I will tell you what I know."); + stage = 11; + break; + case 11: + options("Tell me about your armours.", "Tell me about your accessories.", "I've seen enough, thanks."); + stage = 12; + break; + case 12: + switch (buttonId) { + case 1: + player("Tell me about your armours."); + stage = 13; + break; + case 2: + player("Tell me about your accessories."); + stage = 15; + break; + case 3: + player("I've seen enough, thanks."); + stage = 30; + break; + } + break; + case 13: + npc("I have normal, studded and hard types."); + stage = 14; + break; + case 14: + case 31: + case 105: + end(); + break; + case 15: + npc("Ah yes we have a new range of accessories in stock.", "Essential items for an archer like you."); + stage = 14; + break; + case 20: + npc("Indeed, cast your eyes on my wares, adventurer."); + stage = 21; + break; + case 21: + end(); + npc.openShop(player); + break; + case 30: + npc("Very good, adventurer."); + stage = 31; + break; + case 100: + switch (buttonId) { + case 1: + player("What do you do here?"); + stage = 10; + break; + case 2: + player("I'd like to see what you sell."); + stage = 20; + break; + case 3: + player("Can I buy a Skillcape of Range?"); + stage = 101; + break; + case 4: + player("I've seen enough, thanks."); + stage = 30; + break; + } + break; + case 101: + npc("Certainly! Right when you give me 99000 coins."); + stage = 102; + break; + case 102: + options("Okay, here you go.", "No, thanks."); + stage = 103; + break; + case 103: + switch (buttonId) { + case 1: + player("Okay, here you go."); + stage = 104; + break; + case 2: + end(); + break; + } + break; + case 104: + if (Skillcape.purchase(player, Skills.RANGE)) { + npc("There you go! Enjoy."); + } + stage = 105; + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[]{682}; + } + + } + + /** + * Represents the dialogue plugin used for the bow and arrow salesman. + * + * @author 'Vexia + * @version 1.0 + */ + public final class BowArrowSalesman extends DialoguePlugin { + + /** + * Constructs a new {@code BowArrowSalesman} {@code Object}. + */ + public BowArrowSalesman() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code BowArrowSalesman} {@code Object}. + * + * @param player the player. + */ + public BowArrowSalesman(final Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new BowArrowSalesman(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + player("Hello."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + npc("A fair day, traveller. Would you like to see my wares?"); + stage = 1; + break; + case 1: + options("Yes please.", "No thanks."); + stage = 2; + break; + case 2: + switch (buttonId) { + case 1: + end(); + npc.openShop(player); + + break; + case 2: + end(); + break; + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[]{683}; + } + + } + + /** + * Represents the waring interface used in the guild. + * + * @author 'Vexia + * @version 1.0 + */ + public final class WarningInterface extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.forId(564).setPlugin(this); + return this; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + switch (button) { + case 17: + ClimbActionHandler.climb(player, null, Location.create(2668, 3427, 2)); + player.getInterfaceManager().close(); + List npcs = RegionManager.getLocalNpcs(Location.create(2668, 3427, 2)); + String dir = ""; + for (NPC n : npcs) { + if (n.getId() >= 684 && n.getId() <= 687) { + switch (n.getId()) { + case 684: + dir = "north"; + break; + case 685: + dir = "east"; + break; + case 686: + dir = "south"; + break; + case 687: + dir = "west"; + break; + } + n.sendChat("The " + dir + " tower is occupied, get them!"); + } + } + break; + case 18: + player.getInterfaceManager().close(); + break; + } + return true; + } + + } + + /** + * Represents the competition judge. + * + * @author afaroutdude + */ + public final class CompetitionJudge extends DialoguePlugin { + + /** + * Constructs a new {@code CompetitionJudge} {@code Object}. + * + * @param player the player. + */ + public CompetitionJudge(final Player player) { + super(player); + } + + /** + * Constructs a new {@code CompetitionJudge} {@code Object}. + */ + public CompetitionJudge() { + /** + * empty. + */ + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new CompetitionJudge(player); + } + + @Override + public boolean open(Object... args) { + if (player.getInventory().getAmount(1464) >= 1000 + && !player.getAchievementDiaryManager().hasCompletedTask(DiaryType.SEERS_VILLAGE, 1, 7)) { + npc("Wow! I see that you've got yourself a whole load of ", "archery tickets. Well done!"); + player.getAchievementDiaryManager().finishTask(player, DiaryType.SEERS_VILLAGE, 1, 7); + stage = -1; + } else if (player.getArcheryTargets() > 0) { + npc("Hello again, do you need reminding of the rules?"); + stage = 20; + } else if (player.getArcheryTotal() == 0) { + npc("Hello there, would you like to take part in the", + "archery competition? It only costs 200 coins to", + "enter."); + stage = 0; + } else { + int reward = player.getArcheryTotal() / 10; + npc("Well done. Your score is: " + player.getArcheryTotal() + ".", + "For that score you will receive " + reward + " Archery tickets."); + player.setArcheryTargets(-1); + player.setArcheryTotal(0); + if (!player.getInventory().add(new Item(1464, reward))) { + player.getBank().add(new Item(1464, reward)); + player.sendMessage("Your reward was sent to your bank."); + } + stage = 999; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 999: + end(); + break; + case -1: + if (player.getArcheryTargets() > 0) { + npc("Hello again, do you need reminding of the rules?"); + stage = 20; + } else if (player.getArcheryTotal() == 0) { + npc("Hello there, would you like to take part in the", + "archery competition? It only costs 200 coins to", + "enter."); + stage = 0; + } else { + int reward = player.getArcheryTotal() / 10; + npc("Well done. Your score is: " + player.getArcheryTotal() + ".", + "For that score you will receive " + reward + " Archery tickets."); + if (!player.getInventory().add(new Item(1464, reward))) { + player.getBank().add(new Item(1464, reward)); + player.sendMessage("Your reward was sent to your bank."); + } + stage = 999; + } + break; + case 0: + options("Sure, I'll give it a go.", "What are the rules?", "No thanks."); + stage++; + break; + case 1: + switch (buttonId) { + case 1: + player("Sure, I'll give it a go."); + stage = 2; + break; + case 2: + player("What are the rules?"); + stage = 5; + break; + case 3: + player("No thanks."); + stage = 999; + break; + } + break; + case 2: + npc("Great! That will be 200 coins then please."); + stage++; + break; + case 3: + if (player.getInventory().getAmount(995) < 200) { + player("Oops, I don't have enough coins on me..."); + stage++; + } else { + end(); + player.getPacketDispatch().sendMessage("You pay the judge and he gives you 10 bronze arrows."); + player.getInventory().remove(new Item(995, 200)); + player.getInventory().add(new Item(882, 10)); + player.setArcheryTargets(10); + player.setArcheryTotal(0); + } + break; + case 4: + npc("Never mind, come back when you've got enough."); + stage = 999; + break; + case 5: + case 22: + npc("The rules are very simple:"); + stage++; + break; + case 6: + case 23: + npc("You're given 10 shots at the targets, for each hit", "you will receive points. At the end you'll be", "rewarded 1 ticket for every 10 points."); + stage++; + break; + case 7: + npc("The tickets can be exchanged for goods from our stores.", "Do you want to give it a go? Only 200 coins."); + stage++; + break; + case 8: + options("Sure, I'll give it a go.", "No thanks."); + stage++; + break; + case 9: + switch (buttonId) { + case 1: + player("Sure, I'll give it a go."); + stage = 2; + break; + case 3: + player("No thanks."); + stage = 999; + break; + } + break; + case 20: + int arrows = player.getInventory().getAmount(Items.BRONZE_ARROW_882) + + player.getEquipment().getAmount(Items.BRONZE_ARROW_882); + if (arrows < 1) { + player("Well, I actually don't have any more arrows. Could I", "get some more?"); + stage = 25; + } else { + options("Yes please.", "No thanks, I've got it.", "How am I doing so far?"); + stage++; + } + break; + case 21: + switch (buttonId) { + case 1: + player("Yes please."); + stage++; + break; + case 2: + player("No thanks, I've got it."); + stage = 30; + break; + case 3: + player("How am I doing so far?"); + stage = 40; + break; + } + break; + case 24: + npc("The tickets can be exchanged for goods from our stores.", "Good Luck!"); + stage = 999; + break; + case 25: + npc("Ok, but it'll cost you 100 coins."); + stage++; + break; + case 26: + options("Sure, I'll take some.", "No thanks."); + stage++; + break; + case 27: + switch (buttonId) { + case 1: + player("Sure, I'll take some."); + stage++; + break; + case 2: + player("No thanks."); + stage = 999; + break; + } + break; + case 28: + if (player.getInventory().getAmount(995) < 100) { + player("Oops, I don't have enough coins on me..."); + stage++; + } else { + end(); + player.getPacketDispatch().sendMessage("You pay the judge and he gives you 10 bronze arrows."); + player.getInventory().remove(new Item(995, 100)); + player.getInventory().add(new Item(882, 10)); + } + break; + case 30: + npc("Glad to hear it, good luck!"); + stage = 999; + break; + case 40: + String msg; + if (player.getArcheryTotal() <= 0) { + msg = "You haven't started yet."; + } else if (player.getArcheryTotal() <= 80) { + msg = "Not bad, keep going."; + } else { + msg = "You're pretty good, keep it up."; + } + npc("So far your score is: " + player.getArcheryTotal(), msg); + stage = 999; + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[]{693}; + } + + } + + /** + * Represents the tower advisors. + * + * @author afaroutdude + */ + public final class TowerAdvisor extends DialoguePlugin { + + /** + * Constructs a new {@code TowerAdvisor} {@code Object}. + * + * @param player the player. + */ + public TowerAdvisor(final Player player) { + super(player); + } + + /** + * Constructs a new {@code TowerAdvisor} {@code Object}. + */ + public TowerAdvisor() { + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new TowerAdvisor(player); + } + + @Override + public boolean open(Object... args) { + player("Hello there, what do you do here?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 999: + end(); + case 0: + npc("Hi. We are in charge of this practice area."); + stage++; + break; + case 1: + player("This is a practice area?"); + break; + case 2: + npc("Surrounding us are four towers. Each tower contains", + "trained archers of a different level. You'll notice", + "it's quite a distance, so you'll need a longbow."); + stage++; + break; + case 3: + int rangeLevel = player.getSkills().getLevel(Skills.RANGE); + if (rangeLevel < 50) { // north + npc("As you're not very skilled, I advise you to practice", + "on the north tower. That'll provide the best", + "challenge for you."); + } else if (rangeLevel < 60) { // east + npc("You appear to be somewhat skilled with a bow, so I", + "advise you to practice on the south tower. That'll", + "provide the best challenge for you."); + } else if (rangeLevel < 70) { // south + npc("You appear to be fairly skilled with a bow, so I", + "advise you to practice on the south tower. That'll", + "provide the best challenge for you."); + } else { // west + npc("Looks like you're very skilled, so I advise you to", + "practice on the west tower. That'll provide the best", + "challenge for you."); + } + stage = 999; + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[]{684, 685, 686, 687}; + } + + } + + + /** + * Represents all the tower archers + * + * @author afaroutdude + */ + public final class TowerArcher extends AbstractNPC { + + public TowerArcher() { + super(-1, null); + } + public TowerArcher(int id, Location location) { + super(id, location); + } + + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new TowerArcher(id, location); + } + + @Override + public int[] getIds() { + return new int[]{688, 689, 690, 691}; + } + } + + /** + * Represents the archery target pulse. + * + * @author Jamix77 + */ + public static final class ArcheryCompetitionPulse extends Pulse { + + /** + * Represents the player instance. + */ + private final Player player; + + /** + * Represents the scenery. + */ + private final Scenery object; + + /** + * Constructs a new {@code ArcheryCompetitionPulse} {@code Object}. + * + * @param player the player. + * @param object the object. + */ + public ArcheryCompetitionPulse(final Player player, final Scenery object) { + super(1, player, object); + this.player = player; + this.object = object; + } + + private void showInterface(int points, int arrowsLeft, int target, String msg) { + player.getInterfaceManager().openComponent(325); + setVarp(player, 156, 11 - arrowsLeft); + setVarp(player, 157, points); + setVarp(player, 158, target); + player.getPacketDispatch().sendString(msg, 325, 32); + } + + @Override + public boolean pulse() { + if (player.getArcheryTargets() <= 0) { + return true; + } + if (getDelay() == 1) { + setDelay(player.getProperties().getAttackSpeed()); + } + if (player.getEquipment().remove(new Item(Items.BRONZE_ARROW_882, 1))) { + Projectile p = Ammunition.get(Items.BRONZE_ARROW_882).getProjectile().transform(player, object.getLocation()); + p.setEndLocation(object.getLocation()); + p.setEndHeight(25); + p.send(); + player.animate(new Animation(426)); + player.lock(getDelay()); + + int level = player.getSkills().getLevel(Skills.RANGE); + int bonus = player.getProperties().getBonuses()[14]; + double prayer = 1.0; + prayer += player.getPrayer().getSkillBonus(Skills.RANGE); + double cumulativeStr = Math.floor(level * prayer); + /*if (player.getProperties().getAttackStyle().getStyle() == WeaponInterface.STYLE_RANGE_ACCURATE) { + cumulativeStr += 3; + } else if (player.getProperties().getAttackStyle().getStyle() == WeaponInterface.STYLE_LONG_RANGE) { + cumulativeStr += 1; + }*/ + cumulativeStr *= 1.0; + int hit = (int) ((14 + cumulativeStr + (bonus / 8) + ((cumulativeStr * bonus) * 0.016865))) / 10 + 1; + hit = hit + RandomFunction.randomSign(RandomFunction.random(3)); + + int target = Math.max(0, 13 - hit); + int points = 0; + String msg = ""; + switch (target) { + case 0: + points = 100; + msg = "Bulls-Eye!"; + break; + case 1: + points = 50; + msg = "Hit Yellow!"; + break; + case 2: + case 3: + case 4: + points = 30; + msg = "Hit Red!"; + break; + case 5: + case 6: + case 7: + case 8: + points = 20; + msg = "Hit Blue!"; + break; + case 9: + case 10: + points = 10; + msg = "Hit Black!"; + break; + case 11: + case 12: + case 13: + points = 0; + msg = "Missed!"; + break; + } + int xp = points / 2; + + player.getSkills().addExperience(Skills.RANGE, xp, true); + player.setArcheryTotal(player.getArcheryTotal() + points); + player.setArcheryTargets(player.getArcheryTargets() - 1); + player.debug("Hit: " + hit); + player.debug("You have " + player.getArcheryTargets() + " targets left."); + player.debug("You have " + player.getArcheryTotal() + " score."); + + showInterface(player.getArcheryTotal(), player.getArcheryTargets(), target, msg); + + return true; //player.getArcheryTargets() <= 0; + } else { + return true; + } + } + + } + +} diff --git a/Server/src/main/content/region/kandarin/seers/handlers/SeersCourthouseZone.kt b/Server/src/main/content/region/kandarin/seers/handlers/SeersCourthouseZone.kt new file mode 100644 index 0000000..9fd5ce1 --- /dev/null +++ b/Server/src/main/content/region/kandarin/seers/handlers/SeersCourthouseZone.kt @@ -0,0 +1,26 @@ +package content.region.kandarin.seers.handlers + +import core.api.MapArea +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.diary.DiaryType +import core.game.node.entity.player.link.prayer.PrayerType +import core.game.world.map.zone.MapZone +import core.game.world.map.zone.ZoneBorders +import core.game.world.map.zone.ZoneBuilder +import core.plugin.Initializable +import core.plugin.Plugin + +class SeersCourthouseZone : MapArea { + override fun defineAreaBorders(): Array { + return arrayOf(ZoneBorders(2735,3471,2736,3471)) + } + + override fun areaEnter(entity: Entity) { + if(entity is Player && !entity.isArtificial){ + if(!entity.achievementDiaryManager.hasCompletedTask(DiaryType.SEERS_VILLAGE,2,3) && entity.prayer.active.contains(PrayerType.PIETY)){ + entity.achievementDiaryManager.finishTask(entity,DiaryType.SEERS_VILLAGE,2,3) + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop/BatteredBookHandler.kt b/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop/BatteredBookHandler.kt new file mode 100644 index 0000000..f46fcfd --- /dev/null +++ b/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop/BatteredBookHandler.kt @@ -0,0 +1,39 @@ +package content.region.kandarin.seers.quest.elementalworkshop + +import content.global.handlers.iface.BookInterface +import core.api.setQuestStage +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import org.rs09.consts.Items +import content.data.Quests + +/** + * Battered book handler for the Elemental Workshop I quest + * + * @author Woah, with love + */ +class BatteredBookHandler : InteractionListener { + + companion object { + private val TITLE = "Book of the elemental shield" + private val CONTENTS = EWUtils.PAGES + + private fun display(player:Player, pageNum: Int, buttonID: Int) : Boolean { + BookInterface.pageSetup(player, BookInterface.FANCY_BOOK_3_49, TITLE, CONTENTS) + if (BookInterface.isLastPage(pageNum, CONTENTS.size)) { + if (EWUtils.currentStage(player) == 0) { + setQuestStage(player, Quests.ELEMENTAL_WORKSHOP_I, 1) + } + } + return true + } + } + + override fun defineListeners() { + on(Items.BATTERED_BOOK_2886, IntType.ITEM, "read") { player, _ -> + BookInterface.openBook(player, BookInterface.FANCY_BOOK_3_49, ::display) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop/EWListeners.kt b/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop/EWListeners.kt new file mode 100644 index 0000000..f992cb7 --- /dev/null +++ b/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop/EWListeners.kt @@ -0,0 +1,607 @@ +package content.region.kandarin.seers.quest.elementalworkshop + +import core.api.* +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import org.rs09.consts.* +import content.region.kandarin.seers.quest.elementalworkshop.EWUtils.BELLOWS_STATE +import content.region.kandarin.seers.quest.elementalworkshop.EWUtils.FURNACE_STATE +import content.region.kandarin.seers.quest.elementalworkshop.EWUtils.LEFT_WATER_CONTROL_STATE +import content.region.kandarin.seers.quest.elementalworkshop.EWUtils.RIGHT_WATER_CONTROL_STATE +import content.region.kandarin.seers.quest.elementalworkshop.EWUtils.WATER_WHEEL_STATE +import content.region.kandarin.seers.quest.elementalworkshop.EWUtils.currentStage +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.tools.Log +import content.data.Quests + +/** + * Listeners for the Elemental Workshop I quest + * + * @author Woah, with love + */ +class EWListeners : InteractionListener { + + /* Items */ + private val batteredBook = Item(Items.BATTERED_BOOK_2886) + private val batteredKey = Item(Items.BATTERED_KEY_2887) + private val slashedBook = Item(Items.SLASHED_BOOK_9715) + private val emptyStoneBowl = Item(Items.A_STONE_BOWL_2888) + private val fullStoneBowl = Item(Items.A_STONE_BOWL_2889) + private val elementalOre = Item(Items.ELEMENTAL_ORE_2892) + private val elementalMetal = Item(Items.ELEMENTAL_METAL_2893) + private val elementalShield = Item(Items.ELEMENTAL_SHIELD_2890) + private val bellowFixReqItems = intArrayOf( + Items.NEEDLE_1733, + Items.THREAD_1734, + Items.LEATHER_1741 + ) + private val elementalShieldReqItems = intArrayOf( + Items.SLASHED_BOOK_9715, + Items.HAMMER_2347, + Items.ELEMENTAL_METAL_2893 + ) + + /* Scenery */ + private val bookcase = Scenery.BOOKCASE_26113 + private val lavaTrough = intArrayOf( + Scenery.LAVA_TROUGH_18519, Scenery.LAVA_TROUGH_18520, + Scenery.LAVA_TROUGH_18521, Scenery.LAVA_TROUGH_18522, + Scenery.LAVA_TROUGH_18523 + ) + // Handling for on/off state (one obj id for both left and right) + private val waterControls = intArrayOf( + Scenery.WATER_CONTROLS_18509, Scenery.WATER_CONTROLS_18510 + ) + + /* Animations */ + private val turnWaterControlAnimation = Animation(Animations.HUMAN_TURN_LARGE_VALVE_4861) + private val fillStoneBowlAnimation = Animation(Animations.HUMAN_FILL_STONE_BOWL_4862) + private val fixBellowsAnimation = Animation(Animations.HUMAN_SEW_LARGE_SCENERY_4862) + private val smeltElementalBar = Animation(Animations.HUMAN_FURNACE_SMELTING_3243) + private val smithElementalShield = Animation(Animations.HUMAN_COOKING_RANGE_896) + + /* Sound effects */ + private val fillStoneBowlSFX = Sounds.FILL_STONE_BOWL_1537 + private val fillFurnaceWithLavaSFX = Sounds.FILL_FURNACE_WITH_LAVA_1538 + private val pullLeverResetGatesSFX = Sounds.PULL_LEVER_RESET_GATE_1540 + private val turnWaterControlsSFX = Sounds.TURN_METAL_WATER_VALVE + private val pullLeverEnabledSFX = Sounds.PULL_LEVER_ENABLED_1547 + private val pullLeverDisabledSFX = Sounds.PULL_LEVER_DISABLED_1548 + private val bellowLeverSFX = Sounds.PULL_LEVER_GENERAL_2400 + private val smithElementalShieldSFX = Sounds.ANVIL_4_2721 + + /* In-game locations */ + private val leftWaterControlsLocation = Location.create(2713, 9907, 0) + private val rightWaterControlsLocation = Location.create(2726, 9907, 0) + + /* Special interactions */ + private val furnaceIDS = intArrayOf(4304, 6189, 11010, 11666, 12100, 12809, 14921, 18497, 26814, 30021, 30510, 36956, 37651) + + private val DISABLED = 0 + private val ENABLED = 1 + + override fun defineListeners() { + /* * * * * * * * * * * * * * * * * * * + * Seers Village House listeners * + * * * * * * * * * * * * * * * * * */ + // Bookcase (quest start) + on(Scenery.BOOKCASE_26113, IntType.SCENERY, "search") { player, _ -> + val stage = currentStage(player) + + if (stage < 3) { + // Player already has battered book in inventory + if (player.inventory.containsItem(batteredBook)) { + sendItemDialogue( + player, Item(Items.BATTERED_BOOK_2886), "There is a book here titled 'The Elemental Shield'. " + + "It can stay here, as you have a copy in your backpack." + ) + return@on true + } + // Player needs to receive a battered book + sendItemDialogue(player, Item(Items.BATTERED_BOOK_2886), "You find a book titled 'The Elemental Shield'.") + addItem(player, batteredBook.id) + return@on true + } + + // --- AFTER QUEST START --- + if (player.inventory.containsItem(slashedBook)) { + sendItemDialogue(player, Item(Items.SLASHED_BOOK_9715), + "There is a book here titled 'The Elemental Shield'. " + + "It can stay here, as you have a copy in your backpack." + ) + if (player.inventory.addIfDoesntHave(batteredKey)) { + sendItemDialogue(player, Item(Items.BATTERED_KEY_2887),"You also find a key.") + } + return@on true + } + + sendItemDialogue(player, Item(Items.SLASHED_BOOK_9715), "You find a book titled 'The Elemental Shield'.") + addItem(player, slashedBook.id) + if (player.inventory.addIfDoesntHave(batteredKey)) { + sendItemDialogue(player, Item(Items.BATTERED_KEY_2887),"You also find a key.") + } + return@on true + } + + // Knife on Battered book -> Slashed book + Battered key + onUseWith(IntType.ITEM, Items.KNIFE_946, Items.BATTERED_BOOK_2886) { player, _, with -> + val stage = currentStage(player) + if (stage >= 1) { + lock(player, 2) + player.pulseManager.run(object : Pulse() { + var count = 0 + override fun pulse(): Boolean { + when (count) { + 0 -> sendMessage(player, "You make a small cut in the spine of the book.") + 1 -> { + sendMessage(player, "Inside you find a small, old, battered key.") + replaceSlot(player, with.asItem().slot, slashedBook) + addItemOrDrop(player, Items.BATTERED_KEY_2887) + setQuestStage(player, Quests.ELEMENTAL_WORKSHOP_I, 3) + return true + } + } + count++ + return false + } + }) + return@onUseWith true + } else { + sendMessage(player, "Nothing interesting happens.") + return@onUseWith true + } + } + + + /* * * * * * * * * * * * * * * * * * * + * Seers Village Smithy listeners * + * * * * * * * * * * * * * * * * * */ + // Odd looking wall handler + on(intArrayOf(Scenery.ODD_LOOKING_WALL_26114, Scenery.ODD_LOOKING_WALL_26115), IntType.SCENERY, "open") { player, wall -> + // Nothing interesting happens if quest wasn't started. + if (currentStage(player) < 1) { + sendMessage(player, "Nothing interesting happens.") + return@on true + } + // Player is allowed to exit without key + if (player.location == Location.create(2710, 3496, 0) || player.location == Location.create(2709, 3496, 0)) { + core.game.global.action.DoorActionHandler.handleAutowalkDoor(player, wall.asScenery()) + return@on true + } + // Player does not have battered key in inventory + if (!inInventory(player, Items.BATTERED_KEY_2887)) { + sendMessage(player, "You see a small hole in the wall but no way to open it.") + return@on true + } + // Increment quest stage + if (getQuestStage(player, Quests.ELEMENTAL_WORKSHOP_I) < 5) { + setQuestStage(player, Quests.ELEMENTAL_WORKSHOP_I, 5) + } + // Allow player through the wall + sendMessage(player, "You use the battered key to open the doors.") + core.game.global.action.DoorActionHandler.handleAutowalkDoor(player, wall.asScenery()) + return@on true + } + + on(Scenery.STAIRCASE_3415, IntType.SCENERY, "climb-down") { player, _ -> + val stage = currentStage(player) + // Prevent player from somehow skipping beginning quest stages + if (stage < 1) { + sendMessage(player, "Nothing interesting happens.") + return@on true + } + // Move player to downstairs location + teleport(player, Location.create(2716, 9888, 0)) + // If it is the players first time in the workshop + if (stage < 6) { + sendPlayerDialogue(player, + "Now to explore this area thoroughly, to find what " + + "forgotten secrets it contains.", core.game.dialogue.FacialExpression.NEUTRAL) + setQuestStage(player, Quests.ELEMENTAL_WORKSHOP_I, 7) + } + return@on true + } + + on(Scenery.STAIRCASE_3416, IntType.SCENERY, "climb-up") { player, _ -> + teleport(player, Location.create(2709, 3498, 0)) + return@on true + } + + + /* * * * * * * * * * * * * * * * + * Workshop Area listeners * + * * * * * * * * * * * * * * */ + // Center hatch, inaccessible + // NOTE: REMOVE ME/ADD CORRECT CHECKS FOR ELEMENTAL WORKSHOP II + on(Scenery.HATCH_18595, IntType.SCENERY, "open") { player, _ -> + sendDialogue(player, "You're unable to open the locked hatch.") + return@on true + } + + // Stone bowl box, player can get more at any time + on(Scenery.BOXES_3397, IntType.SCENERY, "search") { player, _ -> + // If the player doesn't have a stone bowl in their inventory + if (player.inventory.addIfDoesntHave(emptyStoneBowl)) { + sendMessage(player, "You find a stone bowl.") + } else { + sendMessage(player, "It's empty.") + } + return@on true + } + + // Needle crate, player can only receive once + on(Scenery.CRATE_3400, IntType.SCENERY, "search") { player, _ -> + if (!getAttribute(player, "/save:ew1:got_needle", false)) { + setAttribute(player, "/save:ew1:got_needle", true) + addItem(player, Items.NEEDLE_1733) + sendMessage(player, "You find a needle.") + } else { + sendMessage(player, "You search the crate but find nothing.") + } + return@on true + } + + // Leather crate, player can only receive once + on(Scenery.CRATE_3394, IntType.SCENERY, "search") { player, _ -> + if (!getAttribute(player, "/save:ew1:got_leather", false)) { + setAttribute(player, "/save:ew1:got_leather", true) + addItem(player, Items.LEATHER_1741) + sendMessage(player, "You find some leather.") + } else { + sendMessage(player, "You search the crate but find nothing.") + } + return@on true + } + + // Workbenches/Anvil + onUseWith(IntType.SCENERY, Items.ELEMENTAL_METAL_2893, Scenery.WORKBENCH_3402) { player, used, workbench -> + // Warn player their smithing level is too low to make the shield + if (player.skills.getLevel(Skills.SMITHING) < 20) { + sendMessage(player, "You need a smithing level of 20 to create an elemental shield.") + return@onUseWith true + } + // Warn player they don't have the required book in their inventory + if (!player.inventory.containsAtLeastOneItem(intArrayOf(Items.SLASHED_BOOK_9715, Items.BATTERED_BOOK_2886))) { + sendDialogue(player, "This workbench is too complicated. You need instructions to follow.") + return@onUseWith true + } + // Warn player they don't have a hammer in their inventory + if (!inInventory(player, Items.HAMMER_2347)) { + sendDialogue(player, "You don't have a tool available to shape the metal.") + return@onUseWith true + } + // Sanity error check (Should never get thrown) + if (!player.inventory.containsAll(*elementalShieldReqItems)) { + log(this::class.java, Log.ERR, "${player.username} tried to forge an elemental shield without all the required items.") + return@onUseWith false + } + // Successfully smith the elemental shield + lock(player, (animationDuration(smithElementalShield) + 2)) + runTask(player) { + face(player, workbench) + animate(player, smithElementalShield) + playAudio(player, smithElementalShieldSFX) + replaceSlot(player, used.asItem().slot, elementalShield) + rewardXP(player, Skills.SMITHING, 20.0) + sendMessage(player, "Following the instructions in the book you make an elemental shield.") + } + // Check to see if the quest is completed, if not, complete the quest + if (!player.questRepository.getQuest(Quests.ELEMENTAL_WORKSHOP_I).isCompleted(player)) { + player.questRepository.getQuest(Quests.ELEMENTAL_WORKSHOP_I).finish(player) + } + return@onUseWith true + } + + + /* * * * * * * * * * * * * * + * Fire room listeners * + * * * * * * * * * * * * */ + // Lava trough stone bowl (empty) + onUseWith(IntType.SCENERY, Items.A_STONE_BOWL_2888, *lavaTrough) { player, used, trough -> + lock(player, (animationDuration(fillStoneBowlAnimation) + 1)) + runTask(player) { + face(player, trough) + playAudio(player, fillStoneBowlSFX) + animate(player, fillStoneBowlAnimation) + replaceSlot(player, used.asItem().slot, fullStoneBowl) + sendMessage(player, "You fill the bowl with hot lava.") + } + return@onUseWith true + } + + // Lava trough stone bowl (filled with lava) + onUseWith(IntType.SCENERY, fullStoneBowl.id, *lavaTrough) { player, _, _ -> + sendMessage(player, "The bowl is already full of lava.") + return@onUseWith true + } + + // Pour lava into unlit furnace + onUseWith(IntType.SCENERY, fullStoneBowl.id, Scenery.FURNACE_18525) { player, used, _ -> + player.faceLocation(Location.create(2726, 9875, 0)) + lock(player, 3) + submitIndividualPulse(player, object : Pulse() { + var count = 0 + override fun pulse(): Boolean { + when (count) { + 0 -> { + replaceSlot(player, used.asItem().slot, emptyStoneBowl) + playAudio(player, fillFurnaceWithLavaSFX) + sendMessage(player, "You empty the lava into the furnace.") + } + 2 -> { + setVarbit(player, FURNACE_STATE, ENABLED, true) + sendMessage(player, "The furnace bursts to life.") + return true + } + } + count++ + return false + } + }) + return@onUseWith true + } + + // Pour lava into lit furnace + onUseWith(IntType.SCENERY, fullStoneBowl.id, Scenery.FURNACE_18526) { player, used, _ -> + player.faceLocation(Location.create(2726, 9875, 0)) + runTask(player) { + playAudio(player, fillFurnaceWithLavaSFX) + replaceSlot(player, used.asItem().slot, emptyStoneBowl) + sendMessage(player, "The lava makes little difference to the furnace's searing heat.") + } + return@onUseWith true + } + + // Use elemental ore on lit furnace + onUseWith(IntType.SCENERY, Items.ELEMENTAL_ORE_2892, Scenery.FURNACE_18526) { player, _, _ -> + player.faceLocation(Location.create(2726, 9875, 0)) + // Warn player their smithing level is too low to smelt the ore + if (player.skills.getLevel(Skills.SMITHING) < 20) { + sendMessage(player, "You need a smithing level of 20 to smelt elemental ore.") + return@onUseWith true + } + // Warn player the bellows must be on so the furnace is properly heated + if (!EWUtils.bellowsEnabled(player)) { + sendMessage(player, "The furnace needs to be hotter to be of any use.") + return@onUseWith true + } + // Warn player they don't have enough coal to smelt the bar + if (amountInInventory(player, Items.COAL_453) < 4) { + sendMessage(player, "You need four heaps of coal to smelt elemental ore.") + return@onUseWith true + } + + val barSmeltingDuration = animationDuration(smeltElementalBar) + lock(player, barSmeltingDuration + 2) + // Run the "smelting" pulse + submitIndividualPulse(player, object : Pulse() { + var count = 0 + override fun pulse(): Boolean { + when (count) { + 0 -> { + removeItem(player, Item(Items.COAL_453, 4)) + removeItem(player, elementalOre) + animate(player, Animations.HUMAN_FURNACE_SMELTING_3243) + sendMessage(player, "You place the elemental ore and four heaps of coal into the furnace.") + } + barSmeltingDuration -> { + addItem(player, Items.ELEMENTAL_METAL_2893) + sendMessage(player, "You retrieve a bar of elemental metal.") + rewardXP(player, Skills.SMITHING, 7.0) + return true + } + } + count++ + return false + } + }) + return@onUseWith true + } + + /* Special Interactions: + * onUseWith FURNACE scenery (this handler) + * onUseWith BLAST FURNACE BELT (this handler) + * onCast SUPERHEAT spell (ModernListeners.kt) + * SKIPPED DUE TO SPAGHETTI: on BLAST FURNACE BELT "put-ore-on" (BlastfurnaceListeners.kt) + */ + onUseWith(IntType.SCENERY, Items.ELEMENTAL_ORE_2892, *furnaceIDS) { player, _, _ -> + sendMessage(player, "This furnace is not hot enough to smelt elemental ore.") + return@onUseWith true + } + onUseWith(IntType.SCENERY, Items.ELEMENTAL_ORE_2892, Scenery.CONVEYOR_BELT_9100) { player, _, _ -> + sendMessage(player, "There would be no point in smelting that.") + return@onUseWith true + } + + /* * * * * * * * * * * * * * + * Water room listeners * + * * * * * * * * * * * * */ + // Water controls + on(waterControls, IntType.SCENERY, "turn") { player, _ -> + // Notify player they can't change water control values while water wheel is running + if (EWUtils.waterWheelEnabled(player)) { + sendMessage(player, "Now that the water wheel is running, the valve seems locked off.") + return@on true + } + + // Varbit offset + val offset: Int + // Whether it is enabled or disabled (used for xor toggle) + val enabled: Int + when (player.location) { + // Check left control + leftWaterControlsLocation -> { + offset = LEFT_WATER_CONTROL_STATE + enabled = EWUtils.leftWaterControlBit(player) xor 0x1 + } + // Check right control + rightWaterControlsLocation -> { + offset = RIGHT_WATER_CONTROL_STATE + if (EWUtils.leftWaterControlEnabled(player)) { + enabled = 0 + } else { + enabled = EWUtils.rightWaterControlBit(player) xor 0x1 + } + } + // Sanity control check + else -> { + offset = -1 + enabled = 0 + log(this::class.java, Log.ERR, "Unhandled location when determining enabled water controls! ${player.location}") + return@on false + } + } + + // Run the turn valve pulse + lock(player, (animationDuration(turnWaterControlAnimation) + 1)) + submitIndividualPulse(player, object : Pulse() { + var count = 0 + override fun pulse(): Boolean { + when (count) { + 0 -> { + playAudio(player, turnWaterControlsSFX) + animate(player, turnWaterControlAnimation) + sendMessage(player, "You turn the handle.") + } + 3 -> { + setVarbit(player, offset, enabled, true) + return true + } + } + count++ + return false + } + }) + return@on true + } + + // Water wheel lever handler + on(Scenery.LEVER_3406, IntType.SCENERY, "pull") { player, lever -> + // Default will happen no matter what + lock(player, 2) + sendMessage(player, "You pull the lever") + replaceScenery(lever.asScenery(), Scenery.LEVER_3417, 2) + + // Check to see if the water wheel is running + if (EWUtils.waterWheelEnabled(player)) { + playAudio(player, pullLeverDisabledSFX) + sendMessage(player, "You hear the sound of a water wheel coming to a standstill.") + setVarbit(player, WATER_WHEEL_STATE, DISABLED, true) + setVarbit(player, BELLOWS_STATE, DISABLED, true) + return@on true + } + + // Check to reset both valves to the "off" position if both aren't green + if (!EWUtils.leftWaterControlEnabled(player) || !EWUtils.rightWaterControlEnabled(player)) { + playAudio(player, pullLeverResetGatesSFX) + sendMessage(player, "You hear the sound of the flow gates resetting.") + setVarbit(player, LEFT_WATER_CONTROL_STATE, DISABLED, true) + setVarbit(player, RIGHT_WATER_CONTROL_STATE, DISABLED, true) + return@on true + } + + // If both of the above are false, the water wheel can start running + playAudio(player, pullLeverEnabledSFX) + sendMessage(player, "You hear the sound of a water wheel starting up.") + setVarbit(player, WATER_WHEEL_STATE, ENABLED, true) + return@on true + } + + + /* * * * * * * * * * * * * * + * Air room listeners * + * * * * * * * * * * * * */ + on(Scenery.BELLOWS_18516, IntType.SCENERY, "fix") { player, bellows -> + player.faceLocation(Location.create(2736, 9883, 0)) + // Warn player bellows are already fixed + if (getAttribute(player, "/save:ew1:bellows_fixed", false)) { + sendMessage(player, "The bellows already look fixed to you.") + return@on true + } + // Warn player they don't have a high enough crafting level + if (player.skills.getLevel(Skills.CRAFTING) < 20) { + sendMessage(player, "You need a crafting level of 20 to fix the bellows.") + return@on true + } + // Warn player they don't have the required items + bellowFixReqItems.forEach { reqItem -> + if (!player.inventory.contains(reqItem, 1)) { + val missingItemMsg = when (reqItem) { + Items.NEEDLE_1733 -> "a needle" + Items.THREAD_1734 -> "some thread" + Items.LEATHER_1741 -> "a piece of leather" + else -> "NULL" // Should never be called; no sense in making an enum + } + sendMessage(player, "You need $missingItemMsg to fix the bellows.") + return@on true + } + } + // If the player has all the requirements to fix the bellows + lock(player, (animationDuration(fixBellowsAnimation) + 1)) + runTask(player) { + removeItem(player, Items.LEATHER_1741) + removeItem(player, Item(Items.THREAD_1734, 1)) + animate(player, fixBellowsAnimation) + sendMessage(player, "You stitch the leather over the hole in the bellows.") + setAttribute(player, "/save:ew1:bellows_fixed", true) + } + return@on true + } + + on(Scenery.LEVER_3409, IntType.SCENERY, "pull") { player, lever -> + // Warn player they have to fix the bellows before pulling the lever + if (!getAttribute(player, "/save:ew1:bellows_fixed", false)) { + sendPlayerDialogue(player, "I shouldn't risk damaging the bellows any further.") + return@on true + } + // Pull the lever checks + lock(player, 2) + sendMessage(player, "You pull the lever") + replaceScenery(lever.asScenery(), Scenery.LEVER_3417, 2) + playAudio(player, bellowLeverSFX) + + // Warn player the water wheel is not running + if (!EWUtils.waterWheelEnabled(player)) { + sendMessage(player, "Nothing happens; the lever resets itself.") + return@on true + } + // Bellows lever "OFF" state + if (EWUtils.bellowsEnabled(player)) { + sendMessage(player, "The bellows stop pumping air.") + setVarbit(player, BELLOWS_STATE, DISABLED, true) + return@on true + } + + // Bellows lever "ON" state + sendMessage(player, "The bellows pump air down the pipe.") + setVarbit(player, BELLOWS_STATE, ENABLED, true) + return@on true + } + } + override fun defineDestinationOverrides() { + setDest(IntType.SCENERY, intArrayOf(Scenery.FURNACE_18525, Scenery.FURNACE_18526), "use") { _, _ -> + return@setDest Location.create(2724,9875) + } + setDest(IntType.SCENERY, intArrayOf(Scenery.BELLOWS_18516), "fix") { _, _ -> + return@setDest Location.create(2733, 9884, 0) + } + setDest(IntType.SCENERY, intArrayOf(Scenery.ODD_LOOKING_WALL_26115), "open") { player, _ -> + if (inBorders(player, 2709, 3496, 2711, 3498)) { + return@setDest Location.create(2709, 3496, 0) + } else { + return@setDest Location.create(2709, 3495, 0) + } + } + setDest(IntType.SCENERY, intArrayOf(Scenery.ODD_LOOKING_WALL_26114), "open") { player, _ -> + if (inBorders(player, 2709, 3496, 2711, 3498)) { + return@setDest Location.create(2710, 3496, 0) + } else { + return@setDest Location.create(2710, 3495, 0) + } + } + } +} diff --git a/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop/EWUtils.kt b/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop/EWUtils.kt new file mode 100644 index 0000000..a2629fc --- /dev/null +++ b/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop/EWUtils.kt @@ -0,0 +1,107 @@ +package content.region.kandarin.seers.quest.elementalworkshop + +import content.global.handlers.iface.BookLine +import content.global.handlers.iface.Page +import content.global.handlers.iface.PageSet +import core.game.node.entity.player.Player +import core.api.* +import content.data.Quests + +/** + * Utils for the Elemental Workshop I quest + * Book/Varp/Method Utils + * + * @author Woah, with love + */ +object EWUtils { + /** + * Represents the array of pages for both the BATTERED_BOOK and SLASHED_BOOK. + */ + val PAGES = arrayOf( + PageSet( + Page( + BookLine("Within the pages of this", 55), + BookLine("book you will find the", 56), + BookLine("secret to working the", 57), + BookLine("very elements themselves.", 58), + BookLine("Early in the fifth age, a", 59), + BookLine("new ore was discovered.", 60), + BookLine("This ore has a unique", 61), + BookLine("property of absorbing,", 62), + BookLine("transforming or focusing", 63), + BookLine("elemental energy. A", 64), + BookLine("workshop was erected", 65), + ), + Page( + BookLine("close by to work this new", 66), + BookLine("material. The workshop", 67), + BookLine("was set up for artisans", 68), + BookLine("and inventors to be able", 69), + BookLine("to come and create", 70), + BookLine("devices made from the", 71), + BookLine("unique ore, found only in", 72), + BookLine("the village of the Seers.", 73) + ) + ), + PageSet( + Page( + BookLine("After some time of", 55), + BookLine("successful industry the", 56), + BookLine("true power of this ore", 57), + BookLine("became apparent, as", 58), + BookLine("greater and more", 59), + BookLine("powerful weapons were", 60), + BookLine("created. Realising the", 61), + BookLine("threat this posed, the magi", 62), + BookLine("of the time closed down", 63), + BookLine("the workshop and bound", 64), + BookLine("it under lock and key,", 65) + ), + Page( + BookLine("also trying to destroy all", 66), + BookLine("knowledge of ", 67), + BookLine("manufacturing processes.", 68), + BookLine("Yet this book remains and", 69), + BookLine("you may still find a way", 70), + BookLine("to enter the workshop", 71), + BookLine("within this leather bound", 72), + BookLine("volume.", 73), + ) + ) + ) + + /* OFFSETS */ + const val LEFT_WATER_CONTROL_STATE = 2058 + const val RIGHT_WATER_CONTROL_STATE = 2059 + const val WATER_WHEEL_STATE = 2060 + const val FURNACE_STATE = 2062 + const val BELLOWS_STATE = 2063 + + fun leftWaterControlBit(player: Player): Int { + return getVarbit(player, LEFT_WATER_CONTROL_STATE) + } + + fun rightWaterControlBit(player: Player): Int { + return getVarbit(player, RIGHT_WATER_CONTROL_STATE) + } + + fun leftWaterControlEnabled(player: Player): Boolean { + return getVarbit(player, LEFT_WATER_CONTROL_STATE) == 1 + } + + fun rightWaterControlEnabled(player: Player): Boolean { + return getVarbit(player, RIGHT_WATER_CONTROL_STATE) == 1 + } + + fun waterWheelEnabled(player: Player): Boolean { + return getVarbit(player, WATER_WHEEL_STATE) == 1 + } + + fun bellowsEnabled(player: Player): Boolean { + return getVarbit(player, BELLOWS_STATE) == 1 + } + + fun currentStage(player: Player): Int { + return player.questRepository.getStage(Quests.ELEMENTAL_WORKSHOP_I) + } +} diff --git a/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop/ElementalRockNPC.kt b/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop/ElementalRockNPC.kt new file mode 100644 index 0000000..a1a759e --- /dev/null +++ b/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop/ElementalRockNPC.kt @@ -0,0 +1,97 @@ +package content.region.kandarin.seers.quest.elementalworkshop + +import core.api.getTool +import core.api.sendDialogue +import core.game.node.entity.Entity +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.skill.Skills +import content.data.skill.SkillingTool +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.plugin.Initializable +import org.rs09.consts.NPCs +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +/** + * Npc(s): + * Earth elemental - ID: 4910 (Attack-able form) + * Elemental rock - ID: 4911 (Sleeping "mine-able" form) + * Option(s): + * "Mine" + * + * @author Woah, with love + */ +@Initializable +class ElementalRockNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id,location), InteractionListener { + + private val ELEMENTAL_ROCK_TRANSFORMATION_4865 = Animation(4865) + + // Sanity transform back to elemental rock + override fun init() { + isWalks = false + isNeverWalks = true + transform(NPCs.ELEMENTAL_ROCK_4911) + super.init() + } + + override fun construct(id: Int, location: Location?, vararg objects: Any?): AbstractNPC { + return ElementalRockNPC(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.EARTH_ELEMENTAL_4910, NPCs.ELEMENTAL_ROCK_4911) + } + + // The NPC stays in their upright form when the player + // stops attacking and can walk around + override fun defineListeners() { + on(ids, IntType.NPC, "Mine") { player, node -> + val tool: SkillingTool? = getTool(player, true) + // Check to see if the player can proc the NPC + if (tool == null) { + sendDialogue(player, "You do not have a pickaxe which you have the Mining level to use.") + return@on true + } + // Warn player they don't have a high enough mining level + if (player.skills.getStaticLevel(Skills.MINING) < 20) { + sendDialogue(player, "You need a mining level of at least 20 to mine elemental ore.") + return@on true + } + // Transform the current NPC to 4910 (monster form) + pulseManager.run(object : Pulse() { + var count = 0 + override fun pulse(): Boolean { + when (count) { + // Play the transformation Animation + 0 -> node.asNpc().animate(ELEMENTAL_ROCK_TRANSFORMATION_4865) + // Yell at the player and transform into the combat NPC 4910 + 1 -> { + node.asNpc().sendChat("Grr... Ge'roff us!") + node.asNpc().transform(NPCs.EARTH_ELEMENTAL_4910) + } + // Start attacking the player + 3 -> { + node.asNpc().attack(player) + node.asNpc().isNeverWalks = false + node.asNpc().isWalks = true + return true + } + } + count++ + return false + } + }) + return@on true + } + } + + // Reset back to rock NPC + override fun finalizeDeath(killer: Entity?) { + isWalks = false + isNeverWalks = true + transform(NPCs.ELEMENTAL_ROCK_4911) + super.finalizeDeath(killer) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop/ElementalWorkshopQuest.kt b/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop/ElementalWorkshopQuest.kt new file mode 100644 index 0000000..cb7ea78 --- /dev/null +++ b/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop/ElementalWorkshopQuest.kt @@ -0,0 +1,145 @@ +package content.region.kandarin.seers.quest.elementalworkshop + +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.Vars +import core.game.system.command.Privilege +import content.data.Quests + +/** + * Elemental Workshop I + * + * Original Development Team: + * Developer: Dylan C + * Graphics: Tom W + * Quality Assurance: Andrew C + * Audio: Ian T + * + * RS2 Rework Team: + * Developer: Dylan C + * Graphics: Tom W + * Quality Assurance: Andrew C + * QuestHelp: Rob M + * + * 2009Scape adaptation: + * @author Woah, with love + */ +@Initializable +class ElementalWorkshopQuest : Quest(Quests.ELEMENTAL_WORKSHOP_I, 52, 51, 1), Commands { + + override fun newInstance(`object`: Any?): Quest { + return this + } + + override fun drawJournal(player: Player?, stage: Int) { + super.drawJournal(player, stage) + player ?: return + var line = 11 + if (stage == 0) { + line(player, "I can start this quest by reading a", line++) + line(player, "!!book?? found in !!Seers village??.", line++) + line++ + line(player, "Minimum requirements:", line++) + line(player, if (player.skills.getStaticLevel(Skills.MINING) >= 20) "---Level 20 Mining/--" else "!!Level 20 Mining??", line++) + line(player, if (player.skills.getStaticLevel(Skills.SMITHING) >= 20) "---Level 20 Smithing/--" else "!!Level 20 Smithing??", line++) + line(player, if (player.skills.getStaticLevel(Skills.CRAFTING) >= 20) "---Level 20 Crafting/--" else "!!Level 20 Crafting??", line++) + } else { + // Player read through book on bookshelf + if (stage < 100) { + if (stage >= 1) { + line(player, "---I have found a battered book in a house in Seers Village./--", line++) + line(player, "---It tells of magic ore and a workshop created to fashion it./--", line++) + line++ + if (stage <= 2) { + line(player, "Where is the workshop and how do I get in?", line++) + } + } + + if (stage >= 3) { + line(player, "---Cutting open the spine of the book with a knife,/--", line++) + line(player, "---I found a key hidden under the leather binding./--", line++) + line++ + if (stage <= 4) { + line(player, "Where is the workshop and how do I get in?", line++) + } + } + + if (stage >= 5) { + line(player, "---I have found a secret door in the Seers Village smithy/--", line++) + line++ + line(player, "---Where is the workshop and how do I get in?/--", line++) + line++ + } + + // Player climbed down staircase + if (stage == 7) { + line(player, "There is obviously lots to do here.", line++) + } + } else { + line(player, "---I have found a battered book in a house in Seers Village./--", line++) + line(player, "---It tells of magic ore and a workshop created to fashion it./--", line++) + line++ + line(player, "---After fixing up the old workshop machinery, collecting ore", line++) + line(player, "---and smelting it I was able to create an Elemental Shield./--", line++) + line++ + line(player, "%%QUEST COMPLETE!&&", line++) + } + } + } + + override fun finish(player: Player?) { + super.finish(player) + player ?: return + player.packetDispatch.sendString("1 Quest Point,", 277, 8 + 2) + player.packetDispatch.sendString("5,000 Crafting XP", 277, 9 + 2) + player.packetDispatch.sendString("5,000 Smithing XP", 277, 10 + 2) + player.packetDispatch.sendString("The ability to make", 277, 11 + 2) + player.packetDispatch.sendString("elemental shields.", 277, 12 + 2) + player.packetDispatch.sendItemZoomOnInterface(Items.ELEMENTAL_SHIELD_2890, 235, 277, 3 + 2) + player.skills.addExperience(Skills.CRAFTING, 5000.0) + player.skills.addExperience(Skills.SMITHING, 5000.0) + player.questRepository.syncronizeTab(player) + } + + override fun getConfig(player: Player?, stage: Int): IntArray { + if (stage >= 100) return intArrayOf(Vars.VARP_QUEST_ELEMENTAL_WORKSHOP, 1048576) + if (stage > 0) return intArrayOf(Vars.VARP_QUEST_ELEMENTAL_WORKSHOP, 3) + else return intArrayOf(Vars.VARP_QUEST_ELEMENTAL_WORKSHOP, 0) + } + + override fun defineCommands() { + define("resetew", Privilege.ADMIN) { player, _ -> + setAttribute(player, "/save:ew1:got_needle", false) + setAttribute(player, "/save:ew1:got_leather", false) + setAttribute(player, "/save:ew1:bellows_fixed", false) + player.questRepository.setStageNonmonotonic(player.questRepository.forIndex(52), 0) + setVarp(player, Vars.VARP_QUEST_ELEMENTAL_WORKSHOP, 0) + player.teleport(Location.create(2715, 3481, 0)) + player.inventory.clear() + addItem(player, Items.KNIFE_946) + addItem(player, Items.BRONZE_PICKAXE_1265) + addItem(player, Items.NEEDLE_1733) + addItem(player, Items.THREAD_1734) + addItem(player, Items.LEATHER_1741) + addItem(player, Items.HAMMER_2347) + addItem(player, Items.COAL_453, 4) + } + define("readyew", Privilege.ADMIN) { player, _ -> + val enabled = 1 + setAttribute(player, "/save:ew1:got_needle", true) + setAttribute(player, "/save:ew1:got_leather", true) + setAttribute(player, "/save:ew1:bellows_fixed", true) + player.questRepository.setStageNonmonotonic(player.questRepository.forIndex(52), 95) + setVarbit(player, EWUtils.BELLOWS_STATE, enabled, true) + setVarbit(player, EWUtils.FURNACE_STATE, enabled, true) + setVarbit(player, EWUtils.WATER_WHEEL_STATE, enabled, true) + setVarbit(player, EWUtils.RIGHT_WATER_CONTROL_STATE, enabled, true) + setVarbit(player, EWUtils.LEFT_WATER_CONTROL_STATE, enabled, true) + } + } +} diff --git a/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop/SlashedBookHandler.kt b/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop/SlashedBookHandler.kt new file mode 100644 index 0000000..01f24b0 --- /dev/null +++ b/Server/src/main/content/region/kandarin/seers/quest/elementalworkshop/SlashedBookHandler.kt @@ -0,0 +1,31 @@ +package content.region.kandarin.seers.quest.elementalworkshop + +import content.global.handlers.iface.BookInterface +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import org.rs09.consts.Items + +/** + * Slashed book handler for the Elemental Workshop I quest + * + * @author Woah, with love + */ +class SlashedBookHandler : InteractionListener { + companion object { + private val TITLE = "Book of the elemental shield" + private val CONTENTS = EWUtils.PAGES + + private fun display(player:Player, pageNum: Int, buttonID: Int) : Boolean { + BookInterface.pageSetup(player, BookInterface.FANCY_BOOK_3_49, TITLE, CONTENTS) + return true + } + } + + override fun defineListeners() { + on(Items.SLASHED_BOOK_9715, IntType.ITEM, "read") { player, _ -> + BookInterface.openBook(player, BookInterface.FANCY_BOOK_3_49, ::display) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/ArheinMCDialogue.kt b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/ArheinMCDialogue.kt new file mode 100644 index 0000000..1309b55 --- /dev/null +++ b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/ArheinMCDialogue.kt @@ -0,0 +1,30 @@ +package content.region.kandarin.seers.quest.merlinsquest + +import core.game.dialogue.FacialExpression +import core.game.dialogue.DialogueFile +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import content.data.Quests + +/** + * @author lila + */ + +/** + * This class handles dialogue for Arhein for the Merlin's Crystal quest + */ + +class ArheinMCDialogue (val questStage: Int) : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + START_DIALOGUE -> playerl(FacialExpression.NEUTRAL, "Can you drop me off on the way down please?").also { stage++ } + 1 -> { + npcl(FacialExpression.ANNOYED,"I don't think Sir Mordred would like that. He wants as few outsiders visiting as possible. I wouldn't want to lose his business.") + val quest = player!!.questRepository.getQuest(Quests.MERLINS_CRYSTAL) + player!!.questRepository.setStage(quest, 40) + stage = END_DIALOGUE + } + } + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/BeggarDialogue.java b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/BeggarDialogue.java new file mode 100644 index 0000000..286b845 --- /dev/null +++ b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/BeggarDialogue.java @@ -0,0 +1,145 @@ +package content.region.kandarin.seers.quest.merlinsquest; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import content.data.Quests; + +/** + * Represents the dialogue plugin used for king arthur. + * @author 'Vexia + * @author Splinter + * @version 2.0 + */ +public final class BeggarDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code KingArthurDialogue} {@code Object}. + */ + public BeggarDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code KingArthurDialogue} {@code Object}. + * @param player the player. + */ + public BeggarDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new BeggarDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.SCARED, "Please kind " + (player.isMale() ? "sir" : "lady") + "... my family and I are starving..."); + player.lock(); + stage = 1; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + final Quest quest = player.getQuestRepository().getQuest(Quests.MERLINS_CRYSTAL); + switch (stage) { + case 1: + if (quest.getStage(player) == 60 && player.getAttribute("beggar_npc") != null) { + interpreter.sendDialogues(252, FacialExpression.HALF_GUILTY, "Could you find it in your heart to spare me a simple", "loaf of bread?"); + stage = 2; + } else { + interpreter.sendDialogue("Despite the fact that he is starving,", "he does not feel like speaking to you at the moment."); + stage = 15; + } + break; + case 2: + player.getDialogueInterpreter().sendOptions("Select an Option", "Yes certainly.", "No, I don't have any bread with me."); + stage = 3; + break; + case 3: + switch (buttonId) { + case 1: + player("Yes, certainly."); + stage = 4; + break; + case 2: + player("No, I don't have any bread with me."); + stage = 15; + break; + } + break; + case 4: + if (player.getInventory().contains(2309, 1)) { + interpreter.sendDialogue("You give the bread to the beggar."); + player.getInventory().remove(new Item(2309, 1)); + stage = 5; + } else { + player("... except I don't have any bread on me at the moment..."); + stage = 9; + } + break; + case 5: + npc("Thank you very much!"); + stage = 6; + break; + case 6: + interpreter.sendDialogue("The beggar has turned into the Lady of the Lake!"); + stage = 7; + break; + case 7: + interpreter.sendDialogues(250, FacialExpression.HALF_GUILTY, "Well done. You have passed my test."); + npc.transform(250); + stage = 8; + break; + case 8: + npc("Here is Excalibur, guard it well."); + stage = 16; + break; + case 9: + npc("Well, if you get some, you know where to come."); + stage = 15; + break; + case 15: + player.unlock(); + end(); + break; + case 16: + player.unlock(); + player.getInventory().add(new Item(35, 1), player); + quest.setStage(player, 70); + end(); + npc.clear(); + break; + } + return true; + } + + @Override + public boolean close() { + if (npc.getId() != npc.getOriginalId()) { + npc.reTransform(); + } + return super.close(); + } + + @Override + public void end() { + if (npc.getId() != npc.getOriginalId()) { + npc.reTransform(); + } + super.end(); + } + + @Override + public int[] getIds() { + return new int[] { 252 }; + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/CandleMakerDialogue.java b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/CandleMakerDialogue.java new file mode 100644 index 0000000..46b402e --- /dev/null +++ b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/CandleMakerDialogue.java @@ -0,0 +1,214 @@ +package content.region.kandarin.seers.quest.merlinsquest; + +import core.cache.def.impl.NPCDefinition; +import core.game.dialogue.DialoguePlugin; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import core.plugin.Plugin; +import core.game.shops.Shops; +import core.plugin.ClassScanner; +import content.data.Quests; + +/** + * Represents the dialogue plugin used to handle the candle maker npc. + * @author 'Vexia + * @author Splinter + * @version 1.0 + */ +public final class CandleMakerDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code CandleMakerDialogue} {@code Object}. + */ + public CandleMakerDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code CandleMakerDialogue} {@code Object}. + * @param player the player. + */ + public CandleMakerDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new CandleMakerDialogue(player); + } + + @Override + public void init() { + super.init(); + ClassScanner.definePlugin(new OptionHandler() { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + NPCDefinition.forId(getIds()[0]).getHandlers().put("option:trade", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + NPC npc = node.asNpc(); + Quest quest = player.getQuestRepository().getQuest(Quests.MERLINS_CRYSTAL); + if (quest.getStage(player) > 60) { + Shops.openId(player, 56); + } else { + npc.openShop(player); + } + return true; + } + + }); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + npc("Hi! Would you be interested in some of my fine", "candles?"); + stage = 2; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + final Quest quest = player.getQuestRepository().getQuest(Quests.MERLINS_CRYSTAL); + switch (stage) { + case 2: + if (quest.getStage(player) == 50 || quest.getStage(player) == 60) {// the player has defeated mordred and learned about the black candles + options("Have any black candles?", "Yes, let me see your stock.", "No thanks."); + stage = 3; + } else if (quest.getStage(player) > 60) {// they're farther along in the quest + options("Have any black candles?", "Yes, let me see your stock.", "No thanks."); + stage = 25; + } else {// they haven't started the quest or are too low + options("Yes, let me see your stock.", "No thanks."); + stage = 10; + } + break; + case 3: + switch (buttonId) { + case 1: + player("Have you got any black candles?"); + stage = 4; + break; + case 2: + player("Yes, let me see your stock."); + stage = 30; + break; + case 3: + player("No thank you."); + stage = 40; + break; + } + break; + case 4: + npc("BLACK candles???"); + stage = 5; + break; + case 5: + npc("Hmmm. In the candle making trade, we have a tradition", "that it's very bad luck to make black candles."); + stage = 6; + break; + case 6: + npc("VERY bad luck."); + stage = 7; + break; + case 7: + player("I will pay good money for one."); + stage = 8; + break; + case 8: + npc("I still dunno..."); + stage = 9; + break; + case 9: + npc("Tell you what. I'll supply you with a black candle..."); + stage = 11; + break; + case 11: + npc("IF you can bring me a bucket FULL of wax."); + stage = 40; + break; + case 10: + switch (buttonId) { + case 1: + player("Yes, let me see your stock."); + stage = 30; + break; + case 2: + player("No thank you."); + stage = 40; + break; + } + break; + case 25: + switch (buttonId) { + case 1: + npc("Ah, you again. You're quite a trend setter. Can't believe", "the number of black candle requests I've had since you", "came. I couldn't pass up a business opportunity like that,", "bad luck or no. So I'm selling them now. Would you be"); + stage = 26; + break; + case 2: + player("Yes, let me see your stock."); + stage = 30; + break; + case 3: + player("No thank you."); + stage = 40; + break; + } + break; + case 26: + npc("interested in purchasing another?"); + stage = 27; + break; + case 27: + options("Yes, let me see your stock.", "No thanks."); + stage = 10; + break; + case 30: + end(); + if (quest.getStage(player) > 60) { + Shops.openId(player, 56); + } else { + npc.openShop(player); + } + break; + case 40: + if (quest.getStage(player) == 50 && player.getInventory().contains(MerlinCrystalPlugin.BUCKET_OF_WAX.getId(), 1)) { + npc("Wha- what's that? You've already got a bucket of wax!"); + stage = 41; + } else { + end(); + } + break; + case 41: + npc("Give it 'ere and I'll trade you for a black candle."); + stage = 42; + break; + case 42: + interpreter.sendDialogue("You hand over a bucket of wax in exchange for a black candle."); + player.getInventory().remove(new Item(MerlinCrystalPlugin.BUCKET_OF_WAX.getId(), 1)); + player.getInventory().add(new Item(MerlinCrystalPlugin.BLACK_CANDLE.getId(), 1)); + stage = 43; + break; + case 43: + end(); + break; + + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 562 }; + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/CrateCutscenePlugin.java b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/CrateCutscenePlugin.java new file mode 100644 index 0000000..aab24ce --- /dev/null +++ b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/CrateCutscenePlugin.java @@ -0,0 +1,108 @@ +package content.region.kandarin.seers.quest.merlinsquest; + +import core.game.activity.ActivityPlugin; +import core.game.activity.CutscenePlugin; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.world.map.Location; +import core.game.world.map.build.DynamicRegion; + +/** + * Handles the crate cutscene plugin. + * @author Vexia + */ +public class CrateCutscenePlugin extends CutscenePlugin { + + /** + * The dialogue plugin. + */ + private DialoguePlugin dialogue; + + /** + * Constructs a new {@code CrateCutscenePlugin} {@code Object} + */ + public CrateCutscenePlugin() { + super("Merlin Crate Cutscene", false); + } + + /** + * Constructs a new {@code CrateCutscenePlugin} {@code Object} + * @param player the player. + */ + public CrateCutscenePlugin(Player player) { + this(); + this.player = player; + } + + @Override + public boolean start(Player player, boolean login, Object... args) { + setDialogue((DialoguePlugin) args[0]); + return super.start(player, login, args); + } + + @Override + public void open() { + super.open(); + player.setAttribute("cutscene", this); + player.getDialogueInterpreter().sendDialogue("You wait."); + } + + @Override + public void stop(boolean fade) { + end(); + } + + @Override + public boolean leave(Entity entity, boolean logout) { + if (logout && entity.isPlayer()) { + entity.setLocation(Location.create(2778, 3401, 0)); + } + return super.leave(entity, logout); + } + + @Override + public ActivityPlugin newInstance(Player p) throws Throwable { + return new CrateCutscenePlugin(p); + } + + @Override + public Location getStartLocation() { + return base.transform(18, 25, 0); + } + + @Override + public Location getSpawnLocation() { + return Location.create(2778, 3401, 0); + } + + @Override + public void configure() { + region = DynamicRegion.create(12609); + setRegionBase(); + registerRegion(region.getId()); + SceneryBuilder.add(new Scenery(65, base.transform(18, 25, 0), 0, 0)); + SceneryBuilder.add(new Scenery(65, base.transform(19, 25, 0), 0, 4)); + SceneryBuilder.add(new Scenery(65, base.transform(18, 24, 0), 0, 1)); + SceneryBuilder.add(new Scenery(65, base.transform(18, 26, 0), 0, 3)); + } + + /** + * Gets the dialogue. + * @return the dialogue + */ + public DialoguePlugin getDialogue() { + return dialogue; + } + + /** + * Sets the dialogue. + * @param dialogue the dialogue to set. + */ + public void setDialogue(DialoguePlugin dialogue) { + this.dialogue = dialogue; + } + +} diff --git a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/KingArthurDialogue.java b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/KingArthurDialogue.java new file mode 100644 index 0000000..ea84952 --- /dev/null +++ b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/KingArthurDialogue.java @@ -0,0 +1,150 @@ +package content.region.kandarin.seers.quest.merlinsquest; + +import org.rs09.consts.Items; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.item.Item; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import content.data.Quests; + +/** + * Represents the dialogue plugin used for king arthur. + * + * @author 'Vexia + * @author Splinter + * @version 2.0 + */ +public final class KingArthurDialogue extends DialoguePlugin { + final static Item POISON_CHALICE = new Item(Items.POISON_CHALICE_197); + + /** + * Constructs a new {@code KingArthurDialogue} {@code Object}. + */ + public KingArthurDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code KingArthurDialogue} {@code Object}. + * + * @param player the player. + */ + public KingArthurDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new KingArthurDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + if (args.length > 1 + && args[1] instanceof Item + && ((Item) args[1]).equals(POISON_CHALICE) + && player.getInventory().remove(POISON_CHALICE)) { + if (!player.getAchievementDiaryManager().getDiary(DiaryType.SEERS_VILLAGE).isComplete(0, 3)) { + player.getAchievementDiaryManager().getDiary(DiaryType.SEERS_VILLAGE).updateTask(player, 0, 3, true); + } + npc("You have chosen... poorly."); + stage = 80; + return true; + } else { + Quest quest = player.getQuestRepository().getQuest(Quests.MERLINS_CRYSTAL); + if (quest.getStage(player) == 99) { + player("I have freed Merlin from his crystal!"); + stage = 900; + return true; + } + if (quest.getStage(player) == 100) { + npc("Thank you for all of your help!"); + stage = 999; + return true; + } + if (quest.getStage(player) <= 0) { + npc("Welcome to my court. I am King Arthur."); + stage = 0; + } else { + npc("If you're having any troubles talk to the other", "knights around the room."); + stage = 9; + } + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + Quest quest = player.getQuestRepository().getQuest(Quests.MERLINS_CRYSTAL); + switch (stage) { + case 900: + end(); + quest.finish(player); + break; + case 999: + end(); + break; + case 0: + player("I want to become a knight of the round table!"); + stage = 1; + break; + case 1: + npc("Well, in that case I think you need to go on a quest to", "prove yourself worthy."); + stage = 2; + break; + case 2: + npc("My knights all appreciate a good quest."); + stage = 3; + break; + case 3: + interpreter.sendDialogues(npc, FacialExpression.DISGUSTED, "Unfortunately, our current quest is to rescue Merlin."); + stage = 4; + break; + case 4: + interpreter.sendDialogues(npc, FacialExpression.THINKING, "Back in England, he got himself trapped in some sort of", + "magical Crystal. We've moved him from the cave we", + "found him in and now he's upstairs in his tower."); + stage = 5; + break; + case 5: + player("I will see what I can do then."); + quest.start(player); + stage = 6; + break; + case 6: + npc("Talk to my knights if you need any help."); + stage = 999; + break; + case 80: + player("Excuse me?"); + stage++; + break; + case 81: + npc("Sorry, I meant to say 'thank you.' Most refreshing."); + stage++; + break; + case 82: + player("Are you sure that stuff is safe to drink?"); + stage++; + break; + case 83: + npc("Oh yes, Stankers' creations may be dangerous for those", + "with weak constitutions, but, personally, I find", + "them rather invigorating."); + stage = 999; + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[]{251}; + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/MerlinCrystal.java b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/MerlinCrystal.java new file mode 100644 index 0000000..15a6c5c --- /dev/null +++ b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/MerlinCrystal.java @@ -0,0 +1,98 @@ +package content.region.kandarin.seers.quest.merlinsquest; + +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.plugin.Initializable; +import core.plugin.ClassScanner; +import content.data.Quests; + +/** + * Represents the merlin's crystal quest. + * @author Splinter + */ +@Initializable +public final class MerlinCrystal extends Quest { + + /** + * Constructs a new {@code MerlinCrystal} {@code Object}. + */ + public MerlinCrystal() { + super(Quests.MERLINS_CRYSTAL, 87, 86, 6, 14, 0, 1, 7); + } + + @Override + public void drawJournal(Player player, int stage) { + super.drawJournal(player, stage); + switch (stage) { + case 0:// not started + line(player, "I can start this quest by speaking to King Arthur at Camelot Castle, just North West of CatherbyI must be able to defeat a level 37 enemy", 11); + break; + case 10:// after talking to arthur + line(player, "I spoke to King Arthur and he said I would be worthy of becoming a Knight of the Round Table if I could free Merlinfrom a giant crystal that he has been trapped in." + " I should ask the other Knights if they have any advice forme on how I should go about doing this.", 11); + break; + case 20:// upon talking to kay/gawain and learning how merlin got trapped + line(player, "I spoke to King Arthur and he said I would be worthy of becoming a Knight of the Round Table if I could free Merlinfrom a giant crystal that he has been trapped in." + "Gawain told me it was the work of Morgan Le Faye.", 11); + break; + case 30:// after talking to lancelot + case 40:// after talking to arhein + line(player, "I spoke to King Arthur and he said I would be worthy of becoming a Knight of the Round Table if I could free Merlinfrom a giant crystal that he has been trapped in." + "Gawain told me it was the work of Morgan Le Faye.I told Lancelot of Gawain's suspicions, and he told me thatMordred's Fortress is not completely impenetrable." + "There might be a way to enter with a delivery by sea...", 11); + break; + case 50:// defeated mordred + line(player, "I spoke to King Arthur and he said I would be worthy of becoming a Knight of the Round Table if I could free Merlinfrom a giant crystal that he has been trapped in." + "Gawain told me it was the work of Morgan Le Faye.I told Lancelot of Gawain's suspicions, and he told me thatMordred's Fortress is not completely impenetrable." + "There might be a way to enter with a delivery by sea...I have broken into Keep Le Faye and slain Sir Mordred." + "Morgan Le Faye disclosed the secret of how to free Merlin. I'll need the sword Excalibur and a lit black candle first." + "According to Morgan, the Lady of the Lake has thesword that can be used to free Merlin.", 11); + break; + case 60:// talking to lady of the lake + line(player, "I spoke to King Arthur and he said I would be worthy of becoming a Knight of the Round Table if I could free Merlinfrom a giant crystal that he has been trapped in." + "Gawain told me it was the work of Morgan Le Faye.I told Lancelot of Gawain's suspicions, and he told me thatMordred's Fortress is not completely impenetrable." + "There might be a way to enter with a delivery by sea...I have broken into Keep Le Faye and slain Sir Mordred." + "Morgan Le Faye disclosed the secret of how to free Merlin.I'll need the sword Excalibur and a lit black candle." + "The Lady of the Lake told me she had the Excalibur but I'd have to meet her in the jewellery store" + " in Port Sarimbefore she'd give it to me.", 11); + break; + case 70:// after actually obtaining excalibur + line(player, "I spoke to King Arthur and he said I would be worthy of becoming a Knight of the Round Table if I could free Merlinfrom a giant crystal that he has been trapped in." + "Gawain told me it was the work of Morgan Le Faye.I told Lancelot of Gawain's suspicions, and he told me thatMordred's Fortress is not completely impenetrable." + "There might be a way to enter with a delivery by sea...I have broken into Keep Le Faye and slain Sir Mordred." + "Morgan Le Faye disclosed the secret of how to free Merlin.I'll need the sword Excalibur and a lit black candle." + "The Lady of the Lake told me she had the Excalibur but I'd have to visit the jewellery store" + " in Port Sarim first." + "I have the sword Excalibur and can free Merlin from the crystal." + "I must now memorize an incantation inscribed on a Chaos altarthat is located somewhere in the world in order to banish" + "the spirit." + "I will also need to find some bat bones and drop themon the magical symbol to the North East of Camelot." + "after I have learned the incantation.", 11); + break; + case 80:// after reading the incantation + line(player, "I spoke to King Arthur and he said I would be worthy of becoming a Knight of the Round Table if I could free Merlinfrom a giant crystal that he has been trapped in." + "Gawain told me it was the work of Morgan Le Faye.I told Lancelot of Gawain's suspicions, and he told me thatMordred's Fortress is not completely impenetrable." + "There might be a way to enter with a delivery by sea...I have broken into Keep Le Faye and slain Sir Mordred." + "Morgan Le Faye disclosed the secret of how to free Merlin.I'll need the sword Excalibur and a lit black candle." + "The Lady of the Lake told me she had the Excalibur but I'd have to visit the jewellery store" + " in Port Sarim first." + "I have the sword Excalibur and can free Merlin from the crystal." + "I must now memorize an incantation inscribed on a Chaos altarthat is located somewhere in the world in order to banish" + "the spirit." + " I managed to find the Chaos Altar that Morgan described." + "The incantation is 'Snarthon Candtrick Termanto'." + "I now need to find some bat bones and drop themon the magical symbol to the North East of Camelot.", 11); + break; + case 90: + line(player, "I spoke to King Arthur and he said I would be worthy of becoming a Knight of the Round Table if I could free Merlinfrom a giant crystal that he has been trapped in." + "Gawain told me it was the work of Morgan Le Faye.I told Lancelot of Gawain's suspicions, and he told me thatMordred's Fortress is not completely impenetrable." + "There might be a way to enter with a delivery by sea...I have broken into Keep Le Faye and slain Sir Mordred." + "Morgan Le Faye disclosed the secret of how to free Merlin.I'll need the sword Excalibur and a lit black candle." + "The Lady of the Lake told me she had the Excalibur but I'd have to visit the jewellery store" + " in Port Sarim first." + "I have the sword Excalibur and can free Merlin from the crystal." + "I must now memorize an incantation inscribed on a Chaos altarthat is located somewhere in the world in order to banish" + "the spirit.Now is your time to free Merlin!", 11); + break; + case 99: + line(player, "I spoke to King Arthur and he said I would be worthy of becoming a Knight of the Round Table if I could free Merlinfrom a giant crystal that he has been trapped in." + "Gawain told me it was the work of Morgan Le Faye.I told Lancelot of Gawain's suspicions, and he told me thatMordred's Fortress is not completely impenetrable." + "There might be a way to enter with a delivery by sea...I have broken into Keep Le Faye and slain Sir Mordred." + "Morgan Le Faye disclosed the secret of how to free Merlin.I'll need the sword Excalibur and a lit black candle." + "The Lady of the Lake told me she had the Excalibur but I'd have to visit the jewellery store" + " in Port Sarim first." + "I have the sword Excalibur and can free Merlin from the crystal." + "I must now memorize an incantation inscribed on a Chaos altarthat is located somewhere in the world in order to banish" + "the spirit.Speak to King Arthur for a reward.", 11); + break; + case 100: + line(player, "You helped King Arthur free Merlin from the crystal.QUEST COMPLETE!", 11); + break; + } + } + + @Override + public void finish(Player player) { + super.finish(player); + player.getPacketDispatch().sendString("6 Quest Points", 277, 8+ 2); + player.getPacketDispatch().sendString("Excalibur", 277, 9+ 2); + player.getPacketDispatch().sendItemZoomOnInterface(35, 235, 277, 3+ 2); + player.getQuestRepository().syncronizeTab(player); + } + + @Override + public boolean hasRequirements(Player player) { + return true; + } + + @Override + public Quest newInstance(Object object) { + ClassScanner.definePlugins(new CrateCutscenePlugin(), + new MerlinCrystalPlugin(), + new BeggarDialogue(), + new CandleMakerDialogue(), + new KingArthurDialogue(), + new MerlinCrystalOptionPlugin(), + new SirKayDialogue(), + new SirLancelotDialogue(), + new SirLucan(), + new SirMordredNPC(), + new SirPalomedes(), + new SirGawainDialogue(), + new TheLadyOfTheLake(), + new ThrantaxDialogue(), + new RenegadeKnightDialogue()); + return this; + } + +} diff --git a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/MerlinCrystalOptionPlugin.java b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/MerlinCrystalOptionPlugin.java new file mode 100644 index 0000000..82a53c4 --- /dev/null +++ b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/MerlinCrystalOptionPlugin.java @@ -0,0 +1,49 @@ +package content.region.kandarin.seers.quest.merlinsquest; + +import core.cache.def.impl.NPCDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.scenery.Scenery; +import core.plugin.Plugin; +import content.data.Quests; + +/** + * Represents the quest node plugin handler. + * @author Splinter + */ +public class MerlinCrystalOptionPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + NPCDefinition.forId(247).getHandlers().put("option:attack", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + final Quest quest = player.getQuestRepository().getQuest(Quests.MERLINS_CRYSTAL); + int id = node instanceof Scenery ? ((Scenery) node).getId() : ((NPC) node).getId(); + switch (id) { + case 247: + if (quest.getStage(player) < 40) { + player.getProperties().getCombatPulse().stop(); + player.getPacketDispatch().sendMessage("You have no reason to attack this valiant knight."); + return true; + } + if (quest.getStage(player) == 40) { + player.getProperties().getCombatPulse().attack(node); + } + if (quest.getStage(player) > 40) { + player.getProperties().getCombatPulse().stop(); + player.getPacketDispatch().sendMessage("You've already bested Sir Mordred in combat."); + return true; + } + break; + } + return true; + } + +} diff --git a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/MerlinCrystalPlugin.java b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/MerlinCrystalPlugin.java new file mode 100644 index 0000000..e90ecbf --- /dev/null +++ b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/MerlinCrystalPlugin.java @@ -0,0 +1,526 @@ +package content.region.kandarin.seers.quest.merlinsquest; + +import core.cache.def.impl.SceneryDefinition; +import core.game.activity.ActivityManager; +import core.game.activity.CutscenePlugin; +import core.game.dialogue.DialogueInterpreter; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.global.action.ClimbActionHandler; +import core.game.global.action.DoorActionHandler; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.OptionHandler; +import core.game.interaction.UseWithHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Plugin; +import core.plugin.ClassScanner; +import content.data.Quests; + +/** + * Handles the Merlin's Crystal Dialogue/Interactions. + * @author Splinter + */ +public final class MerlinCrystalPlugin extends OptionHandler { + + /** + * The empty folder item. + */ + public final static Item REPELLENT = new Item(28); + + /** + * The empty folder item. + */ + public static final Item BUCKET = new Item(1925); + + /** + * The empty folder item. + */ + public static final Item BUCKET_OF_WAX = new Item(30); + + /** + * The empty folder item. + */ + public static final Item BLACK_CANDLE = new Item(38); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ClassScanner.definePlugin(new MerlinCrystalDialogue()); + ClassScanner.definePlugin(new MerlinCrystalItemHandler()); + SceneryDefinition.forId(63).getHandlers().put("option:hide-in", this); + SceneryDefinition.forId(40026).getHandlers().put("option:climb-up", this); + SceneryDefinition.forId(72).getHandlers().put("option:open", this); + SceneryDefinition.forId(71).getHandlers().put("option:open", this); + SceneryDefinition.forId(71).getHandlers().put("option:knock-at", this); + SceneryDefinition.forId(72).getHandlers().put("option:knock-at", this); + SceneryDefinition.forId(62).getHandlers().put("option:smash", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + final Quest quest = player.getQuestRepository().getQuest(Quests.MERLINS_CRYSTAL); + final int id = node instanceof Item ? ((Item) node).getId() : node instanceof Scenery ? ((Scenery) node).getId() : ((NPC) node).getId(); + switch (id) { + case 62: + if (quest.getStage(player) == 90 && player.getEquipment().contains(35, 1)) { + player.sendMessages("You attempt to smash the crystal...", "... and it shatters under the force of Excalibur!"); + player.animate(Animation.create(390)); + player.lock(); + SceneryBuilder.remove(node.asScenery(), 60); + quest.setStage(player, 99); + final NPC merlin = NPC.create(249, Location.create(2767, 3493, 2)); + merlin.init(); + player.getDialogueInterpreter().open(merlin.getId(), merlin); + GameWorld.getPulser().submit(new Pulse(100, player, merlin) { + + @Override + public boolean pulse() { + return true; + } + + @Override + public void stop() { + super.stop(); + if (merlin != null && merlin.isActive()) { + merlin.clear(); + } + } + + }); + } else { + player.sendMessage("You need something stronger to smash it."); + } + return true; + case 63: + player.getDialogueInterpreter().open("merlin_dialogue"); + return true; + case 71: + case 72: + if (quest.getStage(player) == 10) { + player.getDialogueInterpreter().sendDialogue("The door is securely locked."); + } + else if (quest.getStage(player) < 50) { + switch(option) { + case "open": + player.getDialogueInterpreter().sendDialogue("The door is securely locked. You will have to find", "another way in."); + break; + case "knock-at": + player.getDialogueInterpreter().open("renegade-knight"); + break; + } + } else { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()); + } + return true; + case 40026: + if (player.getLocation().withinDistance(Location.create(3013, 3245, 0)) && quest.getStage(player) == 60 && player.getAttribute("beggar_npc") == null) { + NPC npc = new BeggarNPC(player, Location.create(3012, 3248, 1)); + npc.init(); + player.setAttribute("beggar_npc", 1); + npc.setAttribute("beggar_owner", player.getUsername()); + ClimbActionHandler.climb(player, new Animation(828), Location.create(3013, 3245, 1)); + } else { + ClimbActionHandler.climbLadder(player, (Scenery) node, option); + return true; + } + return true; + } + return true; + } + + @Override + public Location getDestination(Node node, Node n) { + return null; + } + + /** + * Handles the dialogue + * @author Splinter + */ + public final class MerlinCrystalDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code JogreCavernDialogue} {@code Object}. + */ + public MerlinCrystalDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code JogreCavernDialogue} {@code Object}. + * @param player the player. + */ + public MerlinCrystalDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new MerlinCrystalDialogue(player); + } + + @Override + public boolean open(Object... args) { + final Quest quest = player.getQuestRepository().getQuest(Quests.MERLINS_CRYSTAL); + if (quest.getStage(player) == 99) { + npc = (NPC) args[0]; + npc("Thank you! Thank you! Thank you!"); + stage = 900; + return true; + } + if (quest.getStage(player) == 40 && player.getLocation().withinDistance(new Location(2801, 3442, 0), 2)) { + player.getDialogueInterpreter().sendDialogue("The crate is empty. It's just about big enough to hide inside."); + stage = 0; + } + if (quest.getStage(player) == 50 && player.getLocation().withinDistance(new Location(2770, 3402, 2), 8)) { + interpreter.sendDialogues(248, FacialExpression.SCARED, "STOP! Please... spare my son."); + player.lock(); + stage = 34; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 900: + npc("It's not fun being trapped in a giant crystal!"); + stage++; + break; + case 901: + npc("Go speak to King Arthur, I'm sure he'll reward you!"); + stage++; + break; + case 902: + interpreter.sendDialogue("You have set Merlin free. Now talk to King Arthur."); + stage++; + break; + case 903: + end(); + player.unlock(); + npc.clear(); + break; + case 0: + player.getDialogueInterpreter().sendOptions("Hide inside the crate?", "Yes.", "No."); + stage++; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogue("You climb inside the crate and wait."); + player.lock(); + player.animate(new Animation(827)); + stage = 10; + break; + case 2: + interpreter.sendDialogue("You leave the empty crate alone."); + stage = 200; + break; + } + break; + case 10: + ActivityManager.start(player, "Merlin Crate Cutscene", false, this); + stage = 11; + break; + case 11: + interpreter.sendDialogue("And wait..."); + stage = 13; + break; + case 13: + interpreter.sendDialogue("You hear voices outside the crate.", "Is this your crate Arnhein?"); + stage = 14; + break; + case 14: + interpreter.sendDialogue("Yeah I think so. Pack it aboard as soon as you can.", "I'm on a tight schedule for deliveries!"); + stage = 15; + break; + case 15: + interpreter.sendDialogue("You feel the crate being lifted", "Oof. Wow, this is pretty heavy!", "I never knew candles weighed so much!"); + stage = 16; + break; + case 16: + interpreter.sendDialogue("Quit your whining, and stow it in the hold."); + stage = 17; + break; + case 17: + interpreter.sendDialogue("You feel the crate being put down inside the ship."); + stage = 18; + break; + case 18: + interpreter.sendDialogue("You wait..."); + stage = 19; + break; + case 19: + interpreter.sendDialogue("And wait..."); + stage = 20; + break; + case 20: + interpreter.sendDialogue("Casting off!"); + stage = 21; + break; + case 21: + interpreter.sendDialogue("You feel the ship start to move."); + stage = 22; + break; + case 22: + interpreter.sendDialogue("Feels like you're now out at sea."); + stage = 23; + break; + case 23: + interpreter.sendDialogue("The ship comes to a stop."); + stage = 24; + break; + case 24: + interpreter.sendDialogue("Unload Mordred's deliveries onto the jetty.", "Aye-aye cap'n!"); + stage = 25; + break; + case 25: + interpreter.sendDialogue("You feel the crate being lifted."); + stage = 26; + break; + case 26: + interpreter.sendDialogue("You can hear someone mumbling outside the crate.", "...stupid Arhein... making me... candles...", "never weigh THIS much....hurts....union about this!..."); + stage = 27; + break; + case 27: + interpreter.sendDialogue("...if....MY ship be different!...", "stupid Arhein..."); + stage = 28; + break; + case 28: + interpreter.sendDialogue("You feel the crate being put down."); + stage = 29; + break; + case 29: + player.getDialogueInterpreter().sendOptions("Get out of the crate?", "Yes.", "No."); + stage = 30; + break; + case 30: + switch (buttonId) { + case 1: + interpreter.sendDialogue("You climb out of the crate."); + stage = 31; + break; + case 2: + interpreter.sendDialogue("You decide to stay in the crate."); + stage = 32; + break; + } + break; + case 31: + CutscenePlugin p = player.getAttribute("cutscene", null); + if (p != null) { + p.stop(false); + } + if (player.getQuestRepository().getQuest(Quests.MERLINS_CRYSTAL).getStage(player) == 30) { + player.getQuestRepository().getQuest(Quests.MERLINS_CRYSTAL).setStage(player, 40); + } + player.unlock(); + player.getProperties().setTeleportLocation(Location.create(2778, 3401, 0)); + end(); + break; + case 32: + interpreter.sendDialogue("You wait..."); + stage = 33; + break; + case 33: + interpreter.sendDialogue("And wait..."); + stage = 29; + break; + case 34: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Tell me how to untrap Merlin and I might."); + stage = 35; + break; + case 35: + interpreter.sendDialogues(248, FacialExpression.HALF_GUILTY, "You have guessed correctly that I'm responsible for", "that."); + stage = 36; + break; + case 36: + interpreter.sendDialogues(248, FacialExpression.HALF_GUILTY, "I suppose I can live with that fool Merlin being loose", "for the sake of my son."); + stage = 37; + break; + case 37: + interpreter.sendDialogues(248, FacialExpression.HALF_GUILTY, "Setting him free won't be easy though."); + stage = 38; + break; + case 38: + interpreter.sendDialogues(248, FacialExpression.HALF_GUILTY, "You will need to find a magic symbol as close to the", "crystal as you can find."); + stage = 39; + break; + case 39: + interpreter.sendDialogues(248, FacialExpression.HALF_GUILTY, "You will then need to drop some bat's bones on the", "magic symbol while holding a lit black candle."); + stage = 40; + break; + case 40: + interpreter.sendDialogues(248, FacialExpression.HALF_GUILTY, "This will summon a mighty spirit named Thrantax."); + stage = 41; + break; + case 41: + interpreter.sendDialogues(248, FacialExpression.HALF_GUILTY, "You will need to bind him with magic words."); + stage = 42; + break; + case 42: + interpreter.sendDialogues(248, FacialExpression.HALF_GUILTY, "Then you will need the sword Excalibur with which the", "spell was bound in order to shatter the crystal."); + stage = 43; + break; + case 43: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Where can I find the sword Excalibur?"); + stage = 44; + break; + case 44: + interpreter.sendDialogues(248, FacialExpression.HALF_GUILTY, "The lady of the lake has it. I don't know if she'll give it", "to you though, she can be rather temperamental."); + stage = 45; + break; + case 45: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What are these magic words?"); + stage = 46; + break; + case 46: + interpreter.sendDialogues(248, FacialExpression.HALF_GUILTY, "You will find the magic words at the base of one of the", "chaos altars."); + stage = 47; + break; + case 47: + interpreter.sendDialogues(248, FacialExpression.HALF_GUILTY, "Which chaos altar I cannot remember."); + stage = 48; + break; + case 48: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Okay, I can do all of that."); + stage = 49; + break; + case 49: + NPC n = player.getAttribute("morgan", null); + if (n != null) { + n.graphics(Graphics.create(86)); + n.clear(); + } + interpreter.sendDialogue("Morgan Le Faye vanishes."); + player.unlock(); + stage = 200; + break; + case 200: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { DialogueInterpreter.getDialogueKey("merlin_dialogue"), 248, 249 }; + } + } + + /** + * Handles the beggar NPC. + * @author Vexia + */ + public final class BeggarNPC extends NPC { + + /** + * The player. + */ + private final Player player; + + /** + * Constructs a new {@code AnimatedArmour} {@code Object}. + * @param player The player. + * @param location The location to spawn. + */ + protected BeggarNPC(Player player, Location location) { + super(252, location); + this.player = player; + } + + @Override + public boolean isHidden(final Player player) { + if (player.getQuestRepository().getQuest(Quests.MERLINS_CRYSTAL).getStage(player) == 60 && this.getAttribute("beggar_owner", "").equals(player.getUsername())) { + return false; + } + return true; + } + + @Override + public void handleTickActions() { + if (player != null && (!player.isActive())) { + clear(); + } + } + + @Override + public void init() { + super.init(); + } + + @Override + public void clear() { + super.clear(); + player.getHintIconManager().clear(); + } + } + + /** + * Used for item handling during the quest. + * @author Adam Rodrigues + */ + public static class MerlinCrystalItemHandler extends UseWithHandler { + + /** + * The object id of the beehives + */ + private static final int[] OBJECTS = new int[] { 68 }; + + /** + * Constructs a new {@Code MerlinCrystalItemHandler} {@Code + * Object} + */ + public MerlinCrystalItemHandler() { + super(REPELLENT.getId(), BUCKET.getId()); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (int id : OBJECTS) { + addHandler(id, OBJECT_TYPE, this); + } + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + Player player = event.getPlayer(); + Item useditem = event.getUsedItem(); + final Scenery object = (Scenery) event.getUsedWith(); + + if (useditem != null && player.getAttribute("cleared-beehives", false) && useditem.getId() == REPELLENT.getId() && object.getId() == 68) { + player.getDialogueInterpreter().sendDialogue("You have already cleared the hive of its bees.", "You can now safely collect wax from the hive."); + } + + if (useditem != null && useditem.getId() == REPELLENT.getId() && object.getId() == 68 && player.getAttribute("cleared-beehives", false)) { + player.getDialogueInterpreter().sendDialogue("You pour insect repellent on the beehive. You see the bees leaving the", "hive."); + player.setAttribute("cleared-beehives", true); + } + + if (useditem != null && useditem.getId() == BUCKET.getId() && player.getAttribute("cleared-beehives", false)) { + player.getDialogueInterpreter().sendDialogue("You get some wax from the beehive."); + player.getInventory().remove(new Item(BUCKET.getId(), 1)); + player.getInventory().add(new Item(BUCKET_OF_WAX.getId(), 1)); + } else if (useditem != null && useditem.getId() == BUCKET.getId() && !player.getAttribute("cleared-beehives", false)) { + player.getDialogueInterpreter().sendDialogue("It would be dangerous to stick the bucket into the hive while", "the bees are still in it. Perhaps you can clear them out", "somehow."); + } + + return true; + } + } +} diff --git a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/MerlinListeners.kt b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/MerlinListeners.kt new file mode 100644 index 0000000..3a24ee3 --- /dev/null +++ b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/MerlinListeners.kt @@ -0,0 +1,41 @@ +package content.region.kandarin.seers.quest.merlinsquest + +import core.api.* +import core.game.interaction.* +import core.game.world.map.Location +import core.game.world.map.Direction +import core.game.global.action.DropListener +import core.game.node.entity.npc.NPC +import core.game.node.entity.impl.ForceMovement +import org.rs09.consts.Items +import content.data.Quests + +class MerlinListeners : InteractionListener { + private val BONE_DROP_LOCATION = Location(2780, 3515, 0) + + override fun defineListeners() { + on (Items.BAT_BONES_530, IntType.ITEM, "drop") { player, node -> + val merlinStage = getQuestStage(player, Quests.MERLINS_CRYSTAL) + var doingQuest = player.location == BONE_DROP_LOCATION && merlinStage == 80 + var hasAuxiliaryRequirements = inInventory(player, Items.LIT_BLACK_CANDLE_32) && getAttribute(player, "thrantax_npc", null) == null + + if (doingQuest && hasAuxiliaryRequirements) { + ForceMovement.run(player, player.location.transform(-2, 0, 0)).direction = Direction.EAST + var npc = ThrantaxNPC(player, Location(2780, 3515, 0)) + npc.player = player + npc.init() + npc.isRespawn = false + setAttribute(player, "thrantax_npc", npc) + setAttribute(npc, "thrantax_owner", player.username) + player.dialogueInterpreter.open("thrantax_dialogue", 34, 248) + return@on true + } else if (doingQuest) { + sendDialogue(player, "You'll need to light the black candle before the spirit will appear.") + return@on true + } + + DropListener.drop(player, node.asItem()) + return@on true + } + } +} diff --git a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/RenegadeKnightDialogue.java b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/RenegadeKnightDialogue.java new file mode 100644 index 0000000..1750d17 --- /dev/null +++ b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/RenegadeKnightDialogue.java @@ -0,0 +1,86 @@ +package content.region.kandarin.seers.quest.merlinsquest; + +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.dialogue.DialogueInterpreter; +import core.game.dialogue.DialoguePlugin; + +public class RenegadeKnightDialogue extends DialoguePlugin { + public RenegadeKnightDialogue() {} + public RenegadeKnightDialogue(Player player) {super(player);} + + @Override + public DialoguePlugin newInstance(Player player) { + return new RenegadeKnightDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = new NPC(237); + + sendDialogue("You knock at the door. You hear a voice from", "inside..."); + stage = 0; + + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch(stage) { + case 999: + end(); + break; + case 0: + player("Um..."); + stage++; + break; + case 1: + options("Pizza Delivery!", "Have you ever thought about letting Saradomin into your life?", "Can I interest you in some double glazing?", "Would you like to buy some lucky heather?"); + stage++; + break; + case 2: + switch(buttonId) { + case 1: + player("Pizza delivery!"); + stage = 3; + break; + case 2: + player("Have you ever thought about letting Saradomin into", "your life? I have some pamphlets you may be", "interested in reading and discussing with me."); + stage = 4; + break; + case 3: + player("Can I interest you in some double glazing? An old", "castle like this must get very draughty in the", "winter..."); + stage = 5; + break; + case 4: + player("Would you like to buy some lucky heather?"); + stage = 4; + break; + } + break; + case 3: + npc("We didn't order any Pizza. Get lost!"); + stage = 10; + break; + case 4: + npc("No. Go away."); + stage = 10; + break; + case 5: + npc("No. Get out of here before I run you through."); + stage = 10; + break; + case 10: + sendDialogue("It looks like you'll have to find another way in..."); + stage = 999; + break; + + } + return true; + } + + @Override + public int[] getIds() { + return new int[]{ DialogueInterpreter.getDialogueKey("renegade-knight") }; + } +} diff --git a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/SirGawainDialogue.java b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/SirGawainDialogue.java new file mode 100644 index 0000000..0f3d5b8 --- /dev/null +++ b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/SirGawainDialogue.java @@ -0,0 +1,180 @@ +package content.region.kandarin.seers.quest.merlinsquest; + +import core.game.node.entity.player.link.quest.Quest; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import content.data.Quests; + +/** + * Represents the dialogue plugin used for Sir Gawain. + * + * @author afaroutdude + */ +public final class SirGawainDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code KingArthurDialogue} {@code Object}. + */ + public SirGawainDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code KingArthurDialogue} {@code Object}. + * + * @param player the player. + */ + public SirGawainDialogue(Player player) { + super(player); + } + + private Quest quest; + + @Override + public DialoguePlugin newInstance(Player player) { + return new SirGawainDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + quest = player.getQuestRepository().getQuest(Quests.MERLINS_CRYSTAL); + + npc("Good day to you " + (player.isMale() ? "sir" : "madam") + "!"); + stage = 0; + + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + + switch (stage) { + case 999: + end(); + break; + case 0: + switch(quest.getStage(player)) { + case 0: + options("Good day.", "Know you of any quests sir knight?"); + stage = 1; + break; + case 10: + options("Good day.", "Any ideas on how to get Merlin out of that crystal?", "Do you know how Merlin got trapped?"); + stage = 2; + break; + case 20: + options("Any idea how to get into Morgan Le Faye's stronghold?", "Hello again."); + stage = 3; + break; + case 50: + player("Any ideas on finding Excalibur?"); + stage = 4; + break; + default: + end(); + break; + } + case 1: + switch(buttonId) { + case 1: + player("Good day."); + stage = 999; + break; + case 2: + player("Know you of any quests sir knight?"); + stage = 5; + break; + } + break; + case 2: + switch(buttonId) { + case 1: + player("Good day."); + stage = 999; + break; + case 2: + player("Any ideas on how to get Merlin out of that crystal?"); + stage = 6; + break; + case 3: + player("Do you know how Merlin got trapped?"); + stage = 7; + break; + } + break; + case 3: + switch(buttonId) { + case 1: + player("Any idea how to get into Morgan Le Faye's stronghold?"); + stage = 12; + break; + case 2: + player("Hello again."); + stage = 999; + break; + } + break; + case 4: + npc("Unfortunately not, adventurer."); + stage = 999; + break; + case 5: + npc("The king is the man to talk to if you want a quest."); + stage = 999; + break; + case 6: + npc("I'm a little stumped myself. We've tried opening it", "with anything and everything!"); + stage = 999; + break; + case 7: + npc("I would guess this is the work of the evil", "Morgan Le Faye!"); + stage++; + break; + case 8: + player("And where could I find her?"); + stage++; + break; + case 9: + npc("She lives in her stronghold to the south of here,", "guarded by some renegade knights led by Sir Mordred."); + quest.setStage(player, 20); + player.getQuestRepository().syncronizeTab(player); + stage++; + break; + case 10: + options("Any idea how to get into Moran Le Faye's stronghold?", "Thank you for the information."); + stage++; + break; + case 11: + switch(buttonId) { + case 1: + player("Any idea how to get into Moran Le Faye's stronghold?"); + stage = 12; + break; + case 2: + player("Thank you for the information."); + stage = 13; + break; + } + break; + case 12: + npc("No, you've got me stumped there..."); + stage = 999; + break; + case 13: + npc("It is the least I can do."); + stage = 999; + break; + + } + return true; + } + + @Override + public int[] getIds() { + return new int[]{240}; + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/SirKayDialogue.java b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/SirKayDialogue.java new file mode 100644 index 0000000..594645e --- /dev/null +++ b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/SirKayDialogue.java @@ -0,0 +1,210 @@ +package content.region.kandarin.seers.quest.merlinsquest; + +import core.game.node.entity.player.link.diary.AchievementDiary; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.entity.player.link.quest.Quest; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import content.data.Quests; + +/** + * Represents the dialogue plugin used for Sir Kay. + * + * @author afaroutdude + */ +public final class SirKayDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code KingArthurDialogue} {@code Object}. + */ + public SirKayDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code KingArthurDialogue} {@code Object}. + * + * @param player the player. + */ + public SirKayDialogue(Player player) { + super(player); + } + + private Quest quest; + + @Override + public DialoguePlugin newInstance(Player player) { + return new SirKayDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + quest = player.getQuestRepository().getQuest(Quests.MERLINS_CRYSTAL); + + options("Hello.", "Talk about achievement diary."); + stage = 0; + + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + int level = 2; + + switch (stage) { + case 999: + end(); + break; + case 0: + switch(buttonId) { + case 1: + player("Hello."); + stage = 1; + break; + case 2: + if (AchievementDiary.canReplaceReward(player, DiaryType.SEERS_VILLAGE, level)) { + player("I seem to have lost my seers' headband..."); + stage = 80; + break; + } + else if (AchievementDiary.hasClaimedLevelRewards(player, DiaryType.SEERS_VILLAGE, level)) { + player("Can you remind me what my headband does?"); + stage = 90; + break; + } + else if (AchievementDiary.canClaimLevelRewards(player, DiaryType.SEERS_VILLAGE, level)) { + player("Greetings, Sir Kay. I have completed all of the Hard", "tasks in my Achievement Diary. May I have a reward?"); + stage = 200; + break; + } + else { + player("Hi! Can you help me out with the Achievement Diary", "tasks?"); + stage = 101; + break; + } + } + break; + case 1: + npc("Good morrow " + (player.isMale() ? "sirrah" : "madam") + "!"); + stage++; + break; + case 2: + switch(quest.getStage(player)) { + case 0: + player("Morning. Know where an adventurer has to go to", "find a quest around here?"); + stage = 3; + break; + case 10: + player("Any ideas on getting Merlin out of that crystal?"); + stage = 4; + break; + case 20: + player("Any ideas on getting into Mordred's fort?"); + stage = 5; + break; + case 50: + player("Any ideas on finding Excalibur?"); + stage = 4; + break; + case 100: + npc("Many thanks for your assistance in restoring Merlin", "to his former freedom!"); + stage = 10; + break; + default: + end(); + break; + } + break; + case 3: + npc("An adventurer eh? There is no service finer than", "serving the bountiful King Arthur, and I happen to", "know there's an important quest to fulfill."); + stage = 999; + break; + case 4: + npc("Unfortunately not, " + (player.isMale() ? "sirrah" : "madam") + "."); + stage = 999; + break; + case 5: + npc("Mordred... So you think he may be involved with", "the curse upon Merlin?"); + stage++; + break; + case 6: + player("Good a guess as any right?"); + stage++; + break; + case 7: + npc("I think you may be on to something there.", "Unfortunately his fortress is impregnable!"); + stage++; + break; + case 8: + player("... I'll figure something out."); + stage = 999; + break; + case 10: + player("Hey, no problem."); + stage = 999; + break; + + case 80: + AchievementDiary.grantReplacement(player, DiaryType.SEERS_VILLAGE, level); + npc("Here's your replacement. Please be more careful."); + stage = 999; + break; + case 90: + npc("Your headband will help you get experience when", "woodcutting maple trees, and an extra log or two when", "cutting normal trees. I've also told Geoff to increase"); + stage++; + break; + case 91: + npc("your flax allowance in acknowledgement of your", "standing."); + stage = 999; + break; + case 100: + npc("I certainly do - we have a set of tasks spanning Seers'", "Village, Catherby, Hemenster and the Sinclair Mansion.", "Just complete the tasks listed in the Achievement Diary", "and they will be ticked off automatically."); + stage = 999; + break; + case 101: + npc("I'm afraid not. It is important that adventurers", "complete the tasks unaided. That way, only the truly", "worthy collect the spoils."); + stage = 999; + break; + case 200: + npc("Well done, young " + (player.isMale() ? "sir" : "madam") + ". You must be a mighty", "adventurer indeed to have completed the Hard tasks."); + stage++; + break; + case 201: + if (!player.hasItem(AchievementDiary.getRewards(DiaryType.SEERS_VILLAGE, level)[0])) { + npc("I need your headband. Come back when", "you have it."); + stage = 999; + } else { + AchievementDiary.flagRewarded(player, DiaryType.SEERS_VILLAGE, level); + sendDialogue("You hand Sir Kay your headband and he concentrates for a", "moment. Some mysterious knightly energy passes through his hands", "and he gives the headband back to you, along with an old lamp."); + stage++; + } + break; + case 202: + npc("You will find that your headband now blesses you with", "the power to spin fabrics at extreme speed in Seers'", "Village. I will also instruct Geoff-erm-Flax to offer you", "a far larger flax allowance. Use your new powers"); + stage++; + break; + case 203: + npc("wisely."); + stage++; + break; + case 204: + player("Thank you, Sir Kay, I'll try not to harm anyone with", "my spinning."); + stage++; + break; + case 205: + npc("You are most welcome. You may also find that the", "Lady of the Lake is prepared to reward you for your", "services if you wear the headband in her presence."); + stage=999; + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[]{241}; + } +} diff --git a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/SirLancelotDialogue.java b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/SirLancelotDialogue.java new file mode 100644 index 0000000..b8d5b8d --- /dev/null +++ b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/SirLancelotDialogue.java @@ -0,0 +1,97 @@ +package content.region.kandarin.seers.quest.merlinsquest; + +import core.game.node.entity.player.link.quest.Quest; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import content.data.Quests; + +/** + * Represents the dialogue plugin used for king arthur. + * @author 'Vexia + * @author Splinter + * @version 2.0 + */ +public final class SirLancelotDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code KingArthurDialogue} {@code Object}. + */ + public SirLancelotDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code KingArthurDialogue} {@code Object}. + * @param player the player. + */ + public SirLancelotDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new SirLancelotDialogue(player); + } + + private Quest quest; + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + npc("Greetings! I am Sir Lancelot, the greatest Knight in the", "land! What do you want?"); + + quest = player.getQuestRepository().getQuest(Quests.MERLINS_CRYSTAL); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + // TODO more accurate dialogue https://2009scape.wiki/w/Transcript:Merlin%27s_Crystal#Sir_Lancelot + switch (stage) { + case 0: + if (quest.getStage(player) >= 20 && quest.getStage(player) < 50) { + player("Any idea on how to get into Morgan Le Faye's", "stronghold?"); + stage = 1; + } else { + player("You're a little full of yourself, aren't you?"); + stage = 16; + } + break; + case 1: + npc("That stronghold is built in a strong defensive position."); + stage = 2; + break; + case 2: + npc("There are two ways in that I know of, the large heavy", "front doors, and the sea entrance, only penetrable by", "boat."); + stage = 3; + break; + case 3: + npc("They take all their deliveries by boat."); + quest.setStage(player, 30); + player.getQuestRepository().syncronizeTab(player); + stage = 15; + break; + case 15: + end(); + break; + case 16: + npc("I have every right to be proud of myself."); + stage = 17; + break; + case 17: + npc("My prowess in battle is world renowned!"); + stage = 15; + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 239 }; + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/SirLucan.java b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/SirLucan.java new file mode 100644 index 0000000..2732d56 --- /dev/null +++ b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/SirLucan.java @@ -0,0 +1,94 @@ +package content.region.kandarin.seers.quest.merlinsquest; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import content.data.Quests; + +/** + * Handles the dialogue for Sir Lucan + * @author Splinter + * @author Vexia + */ +public class SirLucan extends DialoguePlugin { + + /** + * Constructs a new {@code SirLucan} {@code Object} + */ + public SirLucan() { + /* + * empty. + */ + } + + /** + * Constructs a new {@code SirLucan} {@code Object} + * @param player the player. + */ + public SirLucan(Player player) { + super(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hello there adventurer."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + Quest quest = player.getQuestRepository().getQuest(Quests.MERLINS_CRYSTAL); + if (quest.getStage(player) == 100) { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Congratulations on freeing Merlin!"); + stage = 20; + } else if (quest.getStage(player) >= 10 && quest.getStage(player) < 50) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Any suggestions on freeing Merlin?"); + stage = 1; + } else { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I am afraid I have no time to chat."); + stage = 20; + } + break; + case 1: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I've tried all the weapons I can find, yet none are", "powerful enough to break his crystal prison..."); + stage = 2; + break; + case 2: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Perhaps the mighty Excalibur would be strong enough..."); + stage = 3; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Excalibur eh? Where would I find that?"); + stage = 4; + break; + case 4: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "The Lady of the Lake is looking after it I believe... but", "I know not where she resides currently."); + stage = 5; + break; + case 5: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Thanks. I'll try and find someone who does."); + stage = 20; + break; + case 20: + end(); + break; + } + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new SirLucan(player); + } + + @Override + public int[] getIds() { + return new int[] { 245 }; + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/SirMordredNPC.java b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/SirMordredNPC.java new file mode 100644 index 0000000..6065a1b --- /dev/null +++ b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/SirMordredNPC.java @@ -0,0 +1,90 @@ +package content.region.kandarin.seers.quest.merlinsquest; + +import core.game.node.entity.Entity; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Graphics; +import content.data.Quests; + +/** + * Handles Sir Mordred + * @author Vexia + * @author Splinter + */ +public class SirMordredNPC extends AbstractNPC { + + /** + * The NPC ids of NPCs using this plugin. + */ + private static final int[] ID = { 247 }; + + /** + * Constructs a new {@code AlKharidWarriorPlugin} {@code Object}. + */ + public SirMordredNPC() { + super(0, null); + } + + /** + * Constructs a new {@code SirMordredNPC} {@code Object} + * @param id the id. + * @param location the location. + */ + private SirMordredNPC(int id, Location location) { + super(id, location); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new SirMordredNPC(id, location); + } + + @Override + public void finalizeDeath(final Entity killer) { + super.finalizeDeath(killer); + super.getProperties().getCombatPulse().stop(); + super.getSkills().setLifepoints(50); + if (killer != null && killer.isPlayer()) { + final Player p = ((Player) killer); + Quest quest = p.getQuestRepository().getQuest(Quests.MERLINS_CRYSTAL); + if (quest.getStage(p) == 40) { + quest.setStage(p, 50); + p.getQuestRepository().syncronizeTab(p); + p.getDialogueInterpreter().open("merlin_dialogue", 34, 248); + final NPC npc = NPC.create(248, p.getLocation()); + p.setAttribute("morgan", npc); + npc.init(); + npc.graphics(Graphics.create(86)); + npc.moveStep(); + npc.face(p); + GameWorld.getPulser().submit(new Pulse(100, p, npc) { + + @Override + public boolean pulse() { + return true; + } + + @Override + public void stop() { + super.stop(); + if (npc != null && npc.isActive()) { + npc.clear(); + } + } + + }); + } + } + } + + @Override + public int[] getIds() { + return ID; + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/SirPalomedes.java b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/SirPalomedes.java new file mode 100644 index 0000000..50b4e2d --- /dev/null +++ b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/SirPalomedes.java @@ -0,0 +1,77 @@ +package content.region.kandarin.seers.quest.merlinsquest; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import content.data.Quests; + +/** + * Handles the SirPalomedes dialogue. + * @author Vexia + */ +public class SirPalomedes extends DialoguePlugin { + + /** + * Constructs a new {@code SirPalomedes} {@code Object} + */ + public SirPalomedes() { + /* + * empty. + */ + } + + /** + * Constructs a new {@code SirPalomedes} {@code Object} + * @param player the player. + */ + public SirPalomedes(Player player) { + super(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hello there adventurer, what do you want of me?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + Quest quest = player.getQuestRepository().getQuest(Quests.MERLINS_CRYSTAL); + if (quest.getStage(player) == 100) { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Congratulations on freeing Merlin!"); + stage = 20; + } else if (quest.getStage(player) >= 10 && quest.getStage(player) < 50) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'd like some advice on breaking that Crystal Merlin's", "trapped in."); + stage = 1; + } else { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I am afraid I have no time to chat."); + stage = 20; + } + break; + case 1: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Sorry, I cannot help you with that."); + stage = 20; + break; + case 20: + end(); + break; + } + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new SirPalomedes(player); + } + + @Override + public int[] getIds() { + return new int[] { 3787 }; + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/TheLadyOfTheLake.kt b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/TheLadyOfTheLake.kt new file mode 100644 index 0000000..e1ed69c --- /dev/null +++ b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/TheLadyOfTheLake.kt @@ -0,0 +1,161 @@ +package content.region.kandarin.seers.quest.merlinsquest + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.diary.DiaryType +import core.game.node.item.Item +import org.rs09.consts.Items +import content.data.Quests + +/** + * Handles the LadyOfTheLake dialogue. + * + * @author Vexia + * @author Splinter + * @author pain + */ +class TheLadyOfTheLake(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any): Boolean { + npc = args[0] as NPC + stage = if (!player.hasItem(Item(35, 1))) { + npc("Good day to you, " + (if (player.isMale) "sir" else "madam") + ".") + 0 + } else if(player.achievementDiaryManager.getDiary(DiaryType.SEERS_VILLAGE).isComplete(2) + && player.equipment.contains(14631,1) && player.equipment.contains(35,1)){ + npcl(FacialExpression.HAPPY,"I am the Lady of the Lake.") + 110 + } + else { + npc("Good day to you, " + (if (player.isMale) "sir" else "madam") + ".") + 699 + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + val quest = player.questRepository.getQuest(Quests.MERLINS_CRYSTAL) + when (stage) { + 0 -> options("Who are you?", "I seek the sword Excalibur.", "Good day.").also { stage = 1 } + 1 -> when (buttonId) { + 1 -> player("Who are you?").also { stage = 100 } + 2 -> player("I seek the sword Excalibur.").also { + if (quest.getStage(player) < 50) { + stage = 250 + } else { + stage = 161 + } + } + 3 -> player("Good day.").also { stage = 10000 } + } + 100 -> npcl(FacialExpression.HAPPY,"I am the Lady of the Lake.").also { stage = 145 } + 110 -> player("And I'm-").also { stage++ } + 111 -> npc( + "You're " + player.username + ". And I see from the sign you", + "wear that you have earned the trust of Sir Kay." + ).also { stage++ } + 112 -> player("It was nothing.. really...").also { stage++ } + 113 -> npc("You shall be rewarded handsomely!").also { stage++ } + 114 -> { + interpreter.sendItemMessage( + Items.EXCALIBUR_35, + "The Lady of the Lake reaches out and touches the", + "blade Excalibur which seems to vibrate with new power." + ).also { + if (player.inventory.containsAtLeastOneItem(Items.EXCALIBUR_35)) { + player.inventory.remove(Item(Items.EXCALIBUR_35)) + player.inventory.add(Item(14632)) + } + else if (player.equipment.containsAtLeastOneItem(Items.EXCALIBUR_35)) { + player.equipment.remove(Item(Items.EXCALIBUR_35)) + player.equipment.add(Item(14632), true, false) + } + stage++ + } + } + 115 -> player("What does this do then?").also { stage++ } + 116 -> npc( + "I made the blade more powerful, and also gave it a", + "rather healthy effect when you use the special." + ).also { stage++ } + 117 -> player("Thanks!").also { stage = 10000 } + 145 -> options("I seek the sword Excalibur.", "Good day.").also { stage = 150 } + 150 -> when (buttonId) { + 1 -> { + player("I seek the sword Excalibur.") + if (quest.getStage(player) < 50) { + stage = 250 + } else { + stage = 161 + } + } + 2 -> player("Good day.").also { stage = 10000 } + } + 161 -> if (quest.getStage(player) == 50 || quest.getStage(player) == 60) { // they haven't proven themselves yet + npc("Aye, I have that artefact in my possession.").also { stage = 300 } + } else if (quest.getStage(player) >= 70) { + npc( + "... But you have already proved thyself to be worthy", + "of wielding it once already. I shall return it to you", + "if you can prove yourself to still be worthy.").also { stage = 162 } + } + 162 -> player("... And how can I do that?").also { stage = 163 } + 163 -> npc("Why, by proving yourself to be above material goods.").also { stage = 164 } + + 164 -> npc("500 coins ought to do it.").also { stage = 166 } + 166 -> if (player.inventory.contains(995, 500)) { + player("Ok, here you go.").also { stage = 168 } + } else { + player("I don't have that kind of money...").also { stage = 167 } + } + 167 -> npc("Well, come back when you do.").also { stage = 10000 } + 168 -> if (player.inventory.freeSlots() == 0) { + player("Sorry, I don't seem to have enough inventory space.").also { stage = 10000 } + } else if (player.inventory.contains(995, 500)) { + player.inventory.remove(Item(995, 500)) + player.inventory.add(Item(35, 1)) + npc( + "You are still worthy to wield Excalibur! And thanks", + "for the cash! I felt like getting a new haircut!" + ) + stage = 170 + } else { + player("I don't have that kind of money...").also { stage = 167 } + } + 170 -> interpreter.sendDialogue("The lady of the Lake hands you Excalibur.").also { stage = 10000 } + + 250 -> npc("I am afraid I do not know what you are talking about.").also { stage = 10000 } + + 300 -> npc("'Tis very valuable, and not an artefact to be given", "away lightly.").also { stage = 301 } + 301 -> npc("I would want to give it away only to one who is worthy", "and good.").also { stage = 302 } + 302 -> player("And how am I meant to prove that?").also { stage = 303 } + 303 -> npc("I shall set a test for you.").also { stage = 304 } + 304 -> npc( + "First I need you to travel to Port Sarim. Then go to", + "the upstairs room of the jeweller's shop there." + ).also { stage = 305 } + 305 -> player("Ok. That seems easy enough.").also { + quest.setStage(player, 60) + stage = 10000 + } + 699 -> options("Who are you?", "Good day.").also { stage = 700 } + 700 -> when (buttonId) { + 1 -> player("Who are you?").also { stage = 720 } + 2 -> player("Good day.").also { stage = 10000 } + } + 720 -> npc("I am the Lady of the Lake.").also { stage = 10000 } + 10000 -> end() + } + return true + } + + override fun newInstance(player: Player): DialoguePlugin { + return TheLadyOfTheLake(player) + } + + override fun getIds(): IntArray { + return intArrayOf(250) + } +} diff --git a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/ThrantaxDialogue.java b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/ThrantaxDialogue.java new file mode 100644 index 0000000..d30d76d --- /dev/null +++ b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/ThrantaxDialogue.java @@ -0,0 +1,159 @@ +package content.region.kandarin.seers.quest.merlinsquest; + +import core.game.dialogue.DialogueInterpreter; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import content.data.Quests; + +/** + * Handles the thrantax dialogue. + * @author Vexia + * @author Splinter + */ +public class ThrantaxDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code ThrantaxDialogue} {@code Object} + */ + public ThrantaxDialogue() { + /* + * empty. + */ + } + + /** + * Constructs a new {@code ThrantaxDialogue} {@code Object} + * @param player the player. + */ + public ThrantaxDialogue(Player player) { + super(player); + } + + @Override + public boolean open(Object... args) { + interpreter.sendDialogue("Suddenly a mighty spirit appears!"); + player.lock(); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + final Quest quest = player.getQuestRepository().getQuest(Quests.MERLINS_CRYSTAL); + switch (stage) { + case 0: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Now what were those magic words again?"); + stage = 1; + break; + case 1: + interpreter.sendOptions("Select an Option", "Snarthtrick Candanto Termon", "Snarthon Candtrick Termanto", "Snarthanto Cando Termtrick"); + stage = 2; + break; + case 2: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Snarthtrick..."); + stage = 100; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Snarthon..."); + stage = 201; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Snarthanto..."); + stage = 300; + break; + } + break; + case 100: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Candanto..."); + stage = 101; + break; + case 101: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Termon!"); + stage = 500; + break; + case 200: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Candtrick..."); + stage = 201; + break; + case 201: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Termanto!"); + stage = 203; + break; + case 300: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Cando..."); + stage = 301; + break; + case 301: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Termtrick!"); + stage = 500; + break; + case 203: + interpreter.sendDialogues(238, FacialExpression.HALF_GUILTY, "GRAAAAAARGH!"); + stage = 204; + break; + case 204: + interpreter.sendDialogues(238, FacialExpression.HALF_GUILTY, "Thou hast me in thine control. So that I mayst return", "from whence I came, I must grant thee a boon."); + stage = 205; + break; + case 205: + interpreter.sendDialogues(238, FacialExpression.HALF_GUILTY, "What dost thou wish of me?"); + stage = 206; + break; + case 206: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I wish you to free Merlin from his giant crystal!"); + stage = 207; + break; + case 207: + interpreter.sendDialogues(238, FacialExpression.HALF_GUILTY, "GRAAAAAARGH!"); + stage = 208; + break; + case 208: + interpreter.sendDialogues(238, FacialExpression.HALF_GUILTY, "The deed is done."); + stage = 209; + break; + case 209: + interpreter.sendDialogues(238, FacialExpression.HALF_GUILTY, "Thou mayst now shatter Merlin's Crystal with", "Excalibur,"); + stage = 210; + break; + case 210: + interpreter.sendDialogues(238, FacialExpression.HALF_GUILTY, "and I can once more rest. Begone! And leave me once", "more in peace."); + stage = 1000; + break; + case 303: + break; + case 500: + end(); + player.getPacketDispatch().sendMessage("That was the incorrect incantation. The spirit attacks!"); + player.unlock(); + NPC npc = player.getAttribute("thrantax_npc", null); + if (npc != null) { + npc.attack(player); + } + player.removeAttribute("thrantax_npc"); + end(); + break; + case 1000: + player.removeAttribute("thrantax_npc"); + player.unlock(); + quest.setStage(player, 90); + end(); + break; + } + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new ThrantaxDialogue(player); + } + + @Override + public int[] getIds() { + return new int[] { DialogueInterpreter.getDialogueKey("thrantax_dialogue"), 238 }; + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/ThrantaxNPC.java b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/ThrantaxNPC.java new file mode 100644 index 0000000..16efc79 --- /dev/null +++ b/Server/src/main/content/region/kandarin/seers/quest/merlinsquest/ThrantaxNPC.java @@ -0,0 +1,69 @@ +package content.region.kandarin.seers.quest.merlinsquest; + +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.node.entity.npc.NPC; +import core.game.world.map.Location; +import content.data.Quests; + +/** + * Handles the thrantax npc. + * @author Vexia + */ +public class ThrantaxNPC extends NPC { + + /** + * The player. + */ + public Player player; + + /** + * Constructs a new {@code AnimatedArmour} {@code Object}. + * @param player The player. + * @param location The location to spawn. + */ + protected ThrantaxNPC(Player player, Location location) { + super(238, location); + this.player = player; + } + + @Override + public boolean isHidden(final Player player) { + if (player.getQuestRepository().getQuest(Quests.MERLINS_CRYSTAL).getStage(player) == 80 && this.getAttribute("thrantax_owner", "").equals(player.getUsername())) { + return false; + } + return true; + } + + @Override + public void init() { + super.init(); + } + + @Override + public void handleTickActions() { + if (player != null && !player.isActive() || player != null && !player.getLocation().withinDistance(getLocation(), 20)) { + clear(); + } + super.handleTickActions(); + } + + @Override + public void finalizeDeath(Entity entity) { + if (entity instanceof Player) { + Player p = entity.asPlayer(); + super.finalizeDeath(p); + } + } + + @Override + public boolean canAttack(Entity entity) { + return getAttribute("thrantax_owner", entity) == entity; + } + + @Override + public void clear() { + super.clear(); + player.getHintIconManager().clear(); + } +} diff --git a/Server/src/main/content/region/kandarin/witchhaven/dialogue/BaileyDialogue.kt b/Server/src/main/content/region/kandarin/witchhaven/dialogue/BaileyDialogue.kt new file mode 100644 index 0000000..67d446a --- /dev/null +++ b/Server/src/main/content/region/kandarin/witchhaven/dialogue/BaileyDialogue.kt @@ -0,0 +1,24 @@ +package content.region.kandarin.witchhaven.dialogue + +import content.region.kandarin.witchhaven.quest.seaslug.BaileyDialogueFile +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class BaileyDialogue(player: Player? = null) : DialoguePlugin(player){ + override fun newInstance(player: Player): DialoguePlugin { + return BaileyDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player!!, BaileyDialogueFile(), npc) + return true + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.BAILEY_695) + } +} diff --git a/Server/src/main/content/region/kandarin/witchhaven/dialogue/BrotherMaledictDialogue.kt b/Server/src/main/content/region/kandarin/witchhaven/dialogue/BrotherMaledictDialogue.kt new file mode 100644 index 0000000..72e26af --- /dev/null +++ b/Server/src/main/content/region/kandarin/witchhaven/dialogue/BrotherMaledictDialogue.kt @@ -0,0 +1,38 @@ +package content.region.kandarin.witchhaven.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + * Does not take quests into consideration + */ + +@Initializable +class BrotherMaledictDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npc(FacialExpression.FRIENDLY,"The blessings of Saradomin be with you child.").also { stage = 99 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return BrotherMaledictDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.BROTHER_MALEDICT_4878) + } +} diff --git a/Server/src/main/content/region/kandarin/witchhaven/dialogue/CarolineDialogue.kt b/Server/src/main/content/region/kandarin/witchhaven/dialogue/CarolineDialogue.kt new file mode 100644 index 0000000..cc3b0ad --- /dev/null +++ b/Server/src/main/content/region/kandarin/witchhaven/dialogue/CarolineDialogue.kt @@ -0,0 +1,29 @@ +package content.region.kandarin.witchhaven.dialogue + +import content.region.kandarin.witchhaven.quest.seaslug.CarolineDialogueFile +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class CarolineDialogue(player: Player? = null) : DialoguePlugin(player){ + override fun newInstance(player: Player): DialoguePlugin { + return CarolineDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + // Fallback to default. Always the start of Sea Slug + openDialogue(player!!, CarolineDialogueFile(), npc) + return true + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.CAROLINE_696) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/witchhaven/dialogue/ColONiallDialogue.kt b/Server/src/main/content/region/kandarin/witchhaven/dialogue/ColONiallDialogue.kt new file mode 100644 index 0000000..5dddfe2 --- /dev/null +++ b/Server/src/main/content/region/kandarin/witchhaven/dialogue/ColONiallDialogue.kt @@ -0,0 +1,56 @@ +package content.region.kandarin.witchhaven.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + * Does not take quest into consideration + */ + +@Initializable +class ColONiallDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + player(FacialExpression.FRIENDLY,"Hello there.").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> npc(FacialExpression.FRIENDLY, "Hello. What can I do for you?").also { stage++ } + 1 -> player(FacialExpression.FRIENDLY, "Oh, I'm just wondering what you're doing.").also { stage++ } + 2 -> npc(FacialExpression.FRIENDLY, "A spot of fishing.").also { stage++ } + 3 -> player(FacialExpression.FRIENDLY, "That doesn't look much like a fishing rod.").also { stage++ } + 4 -> npc(FacialExpression.FRIENDLY, "That my friend, depends on what you're fishing for.").also { stage++ } + 5 -> player(FacialExpression.FRIENDLY, "And what would that be?").also { stage++ } + 6 -> npcl(FacialExpression.FRIENDLY, "A little of this, a little of that; the usual things.").also { stage++ } + 7 -> player(FacialExpression.FRIENDLY, "Have you caught much?").also { stage++ } + 8 -> npc(FacialExpression.FRIENDLY, "The odd bite here and there. Hmm.").also { stage++ } + 9 -> player(FacialExpression.FRIENDLY, "What?").also { stage++ } + 10 -> npcl(FacialExpression.FRIENDLY, "You look like a capable lad. Tell you what, when you've got a bit more experience under your belt, get yourself over to Falador.").also { stage++ } + 11 -> player(FacialExpression.FRIENDLY, "What's in Falador?").also { stage++ } + 12 -> npcl(FacialExpression.FRIENDLY, "An old friend of mine. You'll find him sitting on a bench in Falador Park. See what he can do for you.").also { stage++ } + 13 -> player(FacialExpression.FRIENDLY, "What's his name? Who should I say sent me?").also { stage++ } + 14 -> npcl(FacialExpression.FRIENDLY, "None of that matters if you can find him and if you're ready my name isn't necessary.").also { stage++ } + 15 -> player(FacialExpression.FRIENDLY, "Oh right. I'll get going then. Goodbye.").also { stage++ } + 16 -> npc(FacialExpression.FRIENDLY, "Goodbye and good luck.").also { stage = 99 } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return ColONiallDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.COL_ONIALL_4872) + } +} diff --git a/Server/src/main/content/region/kandarin/witchhaven/dialogue/EzekialLovecraftDialogue.kt b/Server/src/main/content/region/kandarin/witchhaven/dialogue/EzekialLovecraftDialogue.kt new file mode 100644 index 0000000..4f9c68f --- /dev/null +++ b/Server/src/main/content/region/kandarin/witchhaven/dialogue/EzekialLovecraftDialogue.kt @@ -0,0 +1,64 @@ +package content.region.kandarin.witchhaven.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + * Does not take quests into consideration + */ + +@Initializable +class EzekialLovecraftDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npcl(FacialExpression.FRIENDLY,"Well hello there; welcome to our little village. Pray, stay awhile.").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> options("What do you do here?", "Can I buy some fishing supplies please?", "You are a bit too strange for me. Bye.").also { stage++ } + + 1 -> when (buttonId) { + 1 -> player(FacialExpression.ASKING, "What do you do here?").also { stage = 10 } + 2 -> player(FacialExpression.HALF_ASKING, "Can I buy some fishing supplies please?").also { stage = 25 } + 3 -> player(FacialExpression.ANNOYED, "You are a bit too strange for me. Bye.").also { stage = 30 } + } + + 10 -> npcl(FacialExpression.FRIENDLY, "I supply the local fishermen with the tools and bait they need to do their job.").also { stage++ } + 11 -> player(FacialExpression.FRIENDLY, "Interesting. Have you been doing it long?").also { stage++ } + 12 -> npcl(FacialExpression.FRIENDLY, "Why yes, all of my life. I took over from my father, who inherited the business from his father and so on. In fact, there have been Lovecraft's selling bait for over ten generations.").also { stage++ } + 13 -> player(FacialExpression.FRIENDLY, "Wow, that's some lineage.").also { stage++ } + 14 -> npcl(FacialExpression.LAUGH, "Oh yes, we have a long and interesting family history. For one reason or another the Lovecraft's have always been bait sellers or writers.").also { stage++ } + 15 -> playerl(FacialExpression.FRIENDLY, "Hmm, yes well. I'm sure it's all fascinating, but I...").also { stage++ } + 16 -> npcl(FacialExpression.FRIENDLY, "Oh very, very fascinating, for instance my great grandfather Howard...").also { stage++ } + 17 -> playerl(FacialExpression.HALF_ROLLING_EYES, "Yawn. Oh, I'm sorry but I really must be getting on. I think my giraffe needs feeding.").also { stage++ } + 18 -> npc(FacialExpression.HALF_ASKING, "Your?").also { stage++ } + 19 -> playerl(FacialExpression.ANNOYED, "Giraffe. Sorry, but he gets cranky without enough sugar. Bye now!").also { stage++ } + 20 -> npc(FacialExpression.FRIENDLY, "Oh right, goodbye.").also { stage = 99 } + + 25 -> end().also { npc.openShop(player) } + + 30 -> npc(FacialExpression.FRIENDLY, "Sniff. Yes, everyone says that.").also { stage = 99 } + + + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return EzekialLovecraftDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.EZEKIAL_LOVECRAFT_4856) + } +} diff --git a/Server/src/main/content/region/kandarin/witchhaven/dialogue/HolgartDialogue.kt b/Server/src/main/content/region/kandarin/witchhaven/dialogue/HolgartDialogue.kt new file mode 100644 index 0000000..5f7432e --- /dev/null +++ b/Server/src/main/content/region/kandarin/witchhaven/dialogue/HolgartDialogue.kt @@ -0,0 +1,26 @@ +package content.region.kandarin.witchhaven.dialogue + +import content.region.kandarin.witchhaven.quest.seaslug.HolgartDialogueFile +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class HolgartDialogue(player: Player? = null) : DialoguePlugin(player){ + override fun newInstance(player: Player): DialoguePlugin { + return HolgartDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + // Fallback to default. Always the start of Sea Slug + openDialogue(player!!, HolgartDialogueFile(), npc) + return true + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.HOLGART_700) + // return intArrayOf(NPCs.HOLGART_4866) + } +} diff --git a/Server/src/main/content/region/kandarin/witchhaven/dialogue/HolgartIslandDialogue.kt b/Server/src/main/content/region/kandarin/witchhaven/dialogue/HolgartIslandDialogue.kt new file mode 100644 index 0000000..883bdd7 --- /dev/null +++ b/Server/src/main/content/region/kandarin/witchhaven/dialogue/HolgartIslandDialogue.kt @@ -0,0 +1,27 @@ +package content.region.kandarin.witchhaven.dialogue + +import content.region.kandarin.witchhaven.quest.seaslug.HolgartIslandDialogueFile +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +// This is to handle when Holgart is on the fishing platform. +@Initializable +class HolgartIslandDialogue(player: Player? = null) : DialoguePlugin(player){ + override fun newInstance(player: Player): DialoguePlugin { + return HolgartIslandDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + // Fallback to default. Always the start of Sea Slug + openDialogue(player!!, HolgartIslandDialogueFile(), npc) + return true + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.HOLGART_698) + // return intArrayOf(NPCs.HOLGART_4866) + } +} diff --git a/Server/src/main/content/region/kandarin/witchhaven/dialogue/HolgartPlatformDialogue.kt b/Server/src/main/content/region/kandarin/witchhaven/dialogue/HolgartPlatformDialogue.kt new file mode 100644 index 0000000..3ac3027 --- /dev/null +++ b/Server/src/main/content/region/kandarin/witchhaven/dialogue/HolgartPlatformDialogue.kt @@ -0,0 +1,27 @@ +package content.region.kandarin.witchhaven.dialogue + +import content.region.kandarin.witchhaven.quest.seaslug.HolgartPlatformDialogueFile +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +// This is to handle when Holgart is on the fishing platform. +@Initializable +class HolgartPlatformDialogue(player: Player? = null) : DialoguePlugin(player){ + override fun newInstance(player: Player): DialoguePlugin { + return HolgartPlatformDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + // Fallback to default. Always the start of Sea Slug + openDialogue(player!!, HolgartPlatformDialogueFile(), npc) + return true + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.HOLGART_699, NPCs.FISHERMAN_4871) + // return intArrayOf(NPCs.HOLGART_4866) + } +} diff --git a/Server/src/main/content/region/kandarin/witchhaven/dialogue/JebDialogue.kt b/Server/src/main/content/region/kandarin/witchhaven/dialogue/JebDialogue.kt new file mode 100644 index 0000000..970d61f --- /dev/null +++ b/Server/src/main/content/region/kandarin/witchhaven/dialogue/JebDialogue.kt @@ -0,0 +1,38 @@ +package content.region.kandarin.witchhaven.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + * Does not take quest into consideration + */ + +@Initializable +class JebDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npc(FacialExpression.FRIENDLY,"Hello there.").also { stage = 99 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return JebDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.JEB_4895) + } +} diff --git a/Server/src/main/content/region/kandarin/witchhaven/dialogue/KennithDialogue.kt b/Server/src/main/content/region/kandarin/witchhaven/dialogue/KennithDialogue.kt new file mode 100644 index 0000000..2ad5de6 --- /dev/null +++ b/Server/src/main/content/region/kandarin/witchhaven/dialogue/KennithDialogue.kt @@ -0,0 +1,45 @@ +package content.region.kandarin.witchhaven.dialogue + +import content.region.kandarin.witchhaven.quest.seaslug.KennithDialogueFile +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.NPCs + +class KennithDialogue : InteractionListener { + + override fun defineListeners() { + on(NPCs.KENNITH_4864, IntType.NPC, "talk-to"){ player, npc -> + openDialogue(player, KennithDialogueFile(), npc) + return@on true + } + } + + // Because Kennith is behind the counter + override fun defineDestinationOverrides() { + setDest(IntType.NPC, intArrayOf(NPCs.KENNITH_4864),"talk-to"){ _, _ -> + return@setDest Location.create(2765, 3286, 1) + } + } +} + +// INSTEAD OF THIS as Kennith is unreachable. +//@Initializable +//class KennithDialogue(player: Player? = null) : DialoguePlugin(player){ +// override fun newInstance(player: Player): DialoguePlugin { +// return KennithDialogue(player) +// } +// override fun handle(interfaceId: Int, buttonId: Int): Boolean { +// // Fallback to default. Always the start of Sea Slug +// openDialogue(player!!, KennithDialogueFile(), npc) +// return true +// } +// override fun getIds(): IntArray { +// // Base is CAROLINE_697 (Should be named KENNITH_697) +// return intArrayOf(NPCs.CAROLINE_697, NPCs.KENNITH_4864) +// } +//} diff --git a/Server/src/main/content/region/kandarin/witchhaven/dialogue/KentDialogue.kt b/Server/src/main/content/region/kandarin/witchhaven/dialogue/KentDialogue.kt new file mode 100644 index 0000000..25b3c44 --- /dev/null +++ b/Server/src/main/content/region/kandarin/witchhaven/dialogue/KentDialogue.kt @@ -0,0 +1,24 @@ +package content.region.kandarin.witchhaven.dialogue + +import content.region.kandarin.witchhaven.quest.seaslug.KentDialogueFile +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class KentDialogue(player: Player? = null) : DialoguePlugin(player){ + override fun newInstance(player: Player): DialoguePlugin { + return KentDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + // Fallback to default. Always the start of Sea Slug + openDialogue(player!!, KentDialogueFile(), npc) + return true + } + override fun getIds(): IntArray { + // Base is CAROLINE_697 (Should be named KENNITH_697) + return intArrayOf(NPCs.KENT_701) + } +} diff --git a/Server/src/main/content/region/kandarin/witchhaven/dialogue/MayorHobbDialogue.kt b/Server/src/main/content/region/kandarin/witchhaven/dialogue/MayorHobbDialogue.kt new file mode 100644 index 0000000..dafb2f8 --- /dev/null +++ b/Server/src/main/content/region/kandarin/witchhaven/dialogue/MayorHobbDialogue.kt @@ -0,0 +1,38 @@ +package content.region.kandarin.witchhaven.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + * Does not take quest into consideration + */ + +@Initializable +class MayorHobbDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npcl(FacialExpression.FRIENDLY,"Well hello there; welcome to our little village. Pray, stay awhile.").also { stage = 99 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return MayorHobbDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.MAYOR_HOBB_4874) + } +} diff --git a/Server/src/main/content/region/kandarin/witchhaven/dialogue/WitchavenVillagerDialogue.kt b/Server/src/main/content/region/kandarin/witchhaven/dialogue/WitchavenVillagerDialogue.kt new file mode 100644 index 0000000..8bb49bd --- /dev/null +++ b/Server/src/main/content/region/kandarin/witchhaven/dialogue/WitchavenVillagerDialogue.kt @@ -0,0 +1,83 @@ +package content.region.kandarin.witchhaven.dialogue + +import core.api.openDialogue +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class WitchavenVillagerDialogue(player: Player? = null) : DialoguePlugin(player){ + override fun newInstance(player: Player): DialoguePlugin { + return WitchavenVillagerDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + // Fallback to default. Always the start of Sea Slug + openDialogue(player!!, WitchavenVillagerDialogueFile(), npc) + return true + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.WITCHAVEN_VILLAGER_4883, NPCs.WITCHAVEN_VILLAGER_4884, + NPCs.WITCHAVEN_VILLAGER_4885, NPCs.WITCHAVEN_VILLAGER_4886, + NPCs.WITCHAVEN_VILLAGER_4887, NPCs.WITCHAVEN_VILLAGER_4888) + } +} + +class WitchavenVillagerDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onPredicate { _ -> true } + .player(FacialExpression.FRIENDLY, "Hello there.") + .branch { player -> + return@branch (0 .. 4).random() + }.let { branch -> + branch.onValue(0) + .npcl("What have you got to be so cheerful about?") + .playerl("Well, it's another nice day.") + .npcl("Ha! Try worrying about how you feed a family with no job. Then tell me how nice the day is!") + .playerl("Okay, I guess I've caught you at a bad time. Goodbye.") + .end() + + branch.onValue(1) + .npcl("Hmm? Oh, hello there.") + .playerl("Are you okay? You seem a bit preoccupied.") + .npcl("It's nothing stranger. No need to concern yourself.") + .end() + + branch.onValue(2) + .npcl("Spare a coin mister?") + .playerl("What do you need it for?") + .npcl("For a poor unemployed fisherman what needs to eat.") + .playerl("Why don't you just fish for some food?") + .npcl("Err... Goodbye mister.") + .end() + + branch.onValue(3) + .npcl("Can you believe they did this to us?") + .playerl("Wha...") + .npcl("I mean, what did they think would happen?") + .playerl("Who...") + .npcl("Building that whacking great Fishing Platform just off the coast.") + .playerl("Fish...") + .npcl("Dratted thing stole all of our trade.") + .playerl("Excuse...") + .npcl("I'm sorry, I'm too angry to speak right now. Goodbye") + .end() + + branch.onValue(4) + .npcl("With our nets and gear we're faring,") + .npcl("On the wild and wasteful ocean,") + .npcl("It's there on the deep that we harvest and reap our bread,") + .npcl("As we hunt the bonny shoals of herring.") + .playerl("That's a lovely song.") + .npcl("Aye lad, and sing it every day we did.") + .npcl("'Till the Fishing Platform came and ruined everything.") + .playerl("Oh, I'm sorry.") + .npcl("No need lad, it not be your fault.") + .end() + } + + } +} diff --git a/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/BaileyDialogueFile.kt b/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/BaileyDialogueFile.kt new file mode 100644 index 0000000..9b6399d --- /dev/null +++ b/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/BaileyDialogueFile.kt @@ -0,0 +1,68 @@ +package content.region.kandarin.witchhaven.quest.seaslug + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.FacialExpression +import org.rs09.consts.Items + +class BaileyDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onQuestStages(Quests.SEA_SLUG, 0, 1, 2, 3, 4) + .playerl(FacialExpression.FRIENDLY, "Hello there.") + .npcl(FacialExpression.SCARED, "What? Who are you? Come inside quickly!") + .npcl(FacialExpression.SCARED, "What are you doing here?") + .playerl("I'm trying to find out what happened to a boy named Kennith.") + .npcl("Oh you mean Kent's son. He's around somewhere, probably hiding if he knows what's good for him.") + .playerl(FacialExpression.THINKING, "Hiding from what? What's got you so frightened?") + .npcl("Haven't you seen all those things out there?") + .playerl(FacialExpression.THINKING, "The sea slugs?") + .npcl(FacialExpression.SUSPICIOUS, "It all began about a week ago. We pulled up a haul of deep sea flatfish. Mixed in with them we found these slug things, but thought nothing of it.") + .npcl(FacialExpression.SUSPICIOUS, "Not long after that my friends began to change, now they spend all day pulling in hauls of fish, only to throw back the fish and keep those nasty sea slugs.") + .npcl(FacialExpression.SUSPICIOUS, "What am I supposed to do with those? I haven't figured out how to kill one yet. If I put them near the stove they squirm and jump away.") + .playerl(FacialExpression.THINKING, "I doubt they would taste too good.") + .npcl(FacialExpression.ANGRY, "This is no time for humour.") + .playerl("I'm sorry, I didn't mean to upset you.") + .npcl(FacialExpression.SCARED, "That's okay. I just can't shake the feeling that this is the start of something... Terrible.") + .end() + + b.onQuestStages(Quests.SEA_SLUG, 5) + .playerl("Hello.") + .npcl(FacialExpression.EXTREMELY_SHOCKED, "Oh, thank the gods it's you. They've all gone mad I tell you, one of the fishermen tried to throw me into the sea!") + .playerl("They're all being controlled by the sea slugs.") + .npcl("I figured as much.") + .playerl("I need to get Kennith off this platform, but I can't get past the fishermen.") + .npcl("The sea slugs are scared of heat... I figured that out when I tried to cook them.") + .npcl("Here.") + .betweenStage { _, player, _, _ -> + addItemOrDrop(player, Items.UNLIT_TORCH_596) + } + .iteml(Items.UNLIT_TORCH_596, "Bailey gives you a torch.") + .npcl("I doubt the fishermen will come near you if you can get this torch lit. The only problem is all the wood and flint are damp... I can't light a thing!") + .endWith() { df, player -> + if(getQuestStage(player, Quests.SEA_SLUG) == 5) { + setQuestStage(player, Quests.SEA_SLUG, 6) + } + } + + // We aren't going to give you a spare torch. Go get an unlit torch somewhere else. + b.onQuestStages(Quests.SEA_SLUG, 6, 7, 8) + .playerl("Hello.") + .npcl("Oh, thank the gods it's you. They've all gone mad I tell you, one of the fishermen tried to throw me into the sea!") + .playerl("They're all being controlled by the sea slugs.") + .npcl("I figured as much.") + .playerl("I need to get Kennith off this platform, but I can't get past the fishermen.") + .npcl("The sea slugs are scared of heat... I figured that out when I tried to cook them.") + .npcl("I doubt the fishermen will come near you if you can get this torch lit. The only problem is all the wood and flint are damp... I can't light a thing!") + .end() + + b.onQuestStages(Quests.SEA_SLUG, 9, 10, 100) + .playerl("I've managed to light the torch.") + .npcl("Well done traveller, you'd better get Kennith out of here soon. The fishermen are becoming stranger by the minute, and they keep pulling up those blasted sea slugs.") + .playerl("Don't worry I'm working on it.") + .npcl("Just be sure to watch your back. The fishermen seem to have taken notice of you.") + .end() + + } +} diff --git a/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/CarolineDialogueFile.kt b/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/CarolineDialogueFile.kt new file mode 100644 index 0000000..bd68928 --- /dev/null +++ b/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/CarolineDialogueFile.kt @@ -0,0 +1,71 @@ +package content.region.kandarin.witchhaven.quest.seaslug + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.FacialExpression +import core.game.node.entity.skill.Skills + +class CarolineDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onQuestStages(Quests.SEA_SLUG, 0) + .playerl(FacialExpression.FRIENDLY, "Hello there.") + .npcl(FacialExpression.SAD, "Is there any chance you could help me?") + .playerl(FacialExpression.THINKING, "What's wrong?") + .npcl("It's my husband, he works on a fishing platform. Once a month he takes our son, Kennith, out with him.") + .npcl(FacialExpression.THINKING, "They usually write to me regularly, but I've heard nothing all week. It's very strange.") + .playerl("Maybe the post was lost!") + .npcl(FacialExpression.THINKING, "Maybe, but no-one's heard from the other fishermen on the platform. Their families are becoming quite concerned.") + .branch { player -> + return@branch if (hasLevelStat(player, Skills.FIREMAKING, 30)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(0) + .npcl("However, I don't think you are ready to visit the platform.") + .line("You need Level 30 Firemaking to start the Sea Slug quest.") + .end() + return@let branch.onValue(1) + } + .npcl(FacialExpression.HALF_THINKING, "Is there any chance you could visit the platform and find out what's going on?") + .options().let { optionBuilder -> + optionBuilder.option_playerl("I suppose so, how do I get there?") + .npcl("That's very good of you @name. My friend Holgart will take you there.") + .playerl("Ok, I'll go and see if they're ok.") + .npcl("I'll reward you for your time. It'll give me peace of mind to know Kennith and my husband, Kent, are safe.") + .endWith() { df, player -> + if(getQuestStage(player, Quests.SEA_SLUG) == 0) { + setQuestStage(player, Quests.SEA_SLUG, 1) + } + } + optionBuilder.option_playerl("I'm sorry, I'm too busy.") + .npcl(FacialExpression.SAD, "That's a shame.") + .playerl("Bye.") + .npcl("Bye.") + .end() + } + + b.onQuestStages(Quests.SEA_SLUG, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + .playerl("Hello Caroline.") + .npcl("Brave @name, have you any news about my son and his father?") + .playerl("I'm working on it now Caroline.") + .npcl("Please bring them back safe and sound.") + .playerl("I'll do my best.") + .end() + + b.onQuestStages(Quests.SEA_SLUG, 11) + .playerl("Hello.") + .npcl("Brave @name, you've returned!") + .npcl("Kennith told me about the strange goings-on at the platform. I had no idea it was so serious.") + .npcl("I could have lost my son and my husband if it wasn't for you.") + .playerl("We found Kent stranded on an island.") + .npcl("Yes. Holgart told me and sent a rescue party out. Kent's back home now, resting with Kennith. I don't think he'll be doing any fishing for a while.") + .npcl("Here, take these Oyster pearls as a reward. They're worth quite a bit and can be used to make lethal crossbow bolts.") + .playerl(FacialExpression.FRIENDLY, "Thanks!") + .npcl(FacialExpression.FRIENDLY, "Thank you. Take care of yourself @name.") + .endWith() { df, player -> + if(getQuestStage(player, Quests.SEA_SLUG) == 11) { + finishQuest(player, Quests.SEA_SLUG) + } + } + } +} diff --git a/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/FishermanDialogue.kt b/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/FishermanDialogue.kt new file mode 100644 index 0000000..ba344e5 --- /dev/null +++ b/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/FishermanDialogue.kt @@ -0,0 +1,102 @@ +package content.region.kandarin.witchhaven.quest.seaslug + +import core.api.* +import core.game.dialogue.* +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class FishermanDialogue(player: Player? = null) : DialoguePlugin(player){ + override fun newInstance(player: Player): DialoguePlugin { + return FishermanDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + // Fallback to default. Always the start of Sea Slug + openDialogue(player!!, FishermanDialogueFile(), npc) + return true + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.FISHERMAN_702, NPCs.FISHERMAN_703, NPCs.FISHERMAN_704) + } +} + +class FishermanDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onPredicate { _ -> true } + .player(FacialExpression.FRIENDLY, "Hello there.") + .line("Their eyes are staring vacantly into space.") + .branch { player -> + return@branch (1 .. 1).random() + }.let { branch -> + branch.onValue(0) + .npc(FacialExpression.AMAZED, "Ye mariners all, as ye pass by,") + .npc(FacialExpression.AMAZED, "Come in and drink if you are dry,") + .npc(FacialExpression.AMAZED, "Come spend, me lads, your money brisk,") + .npc(FacialExpression.AMAZED, "And pop your nose in a jug of this.") + .player("You're not fooling anyone you know.") + .npc(FacialExpression.AMAZED, "We fooled you easily enough.") + .end() + + branch.onValue(1) + .npcl(FacialExpression.AMAZED,"You are not part of our family...") + .playerl("Umm. Not last time I checked.") + .npcl(FacialExpression.AMAZED,"Soon you will be... Soon you will...") + .end() + + branch.onValue(2) + .npcl(FacialExpression.AMAZED,"Keep away human... Leave or face the deep blue...") + .playerl("Pardon?") + .npcl(FacialExpression.AMAZED,"You will all end up in the blue... Deep deep under the blue...") + .end() + + branch.onValue(3) + .npcl(FacialExpression.AMAZED,"Lost to us.. She is Lost to us...") + .playerl("Who is lost?") + .npcl(FacialExpression.AMAZED,"Trapped by the light... Lost and trapped...") + .playerl("Ermm... So you don't want to tell me then?") + .npcl(FacialExpression.AMAZED,"Trapped... In stone and darkness...") + .end() + + branch.onValue(4) + .npcl(FacialExpression.AMAZED,"Must find family...") + .playerl("What?") + .npcl(FacialExpression.AMAZED,"Soon we will all be together...") + .playerl("Are you ok?") + .npcl(FacialExpression.AMAZED,"Must find family... They are all under the blue... Deep deep under the blue...") + .playerl("Ermm... I'll leave you to it then.") + .end() + + branch.onValue(5) + .npcl(FacialExpression.AMAZED,"Free of the deep blue we are...") + .npcl(FacialExpression.AMAZED,"We must find...") + .playerl("Yes?") + .npcl(FacialExpression.AMAZED,"a new home...") + .npcl(FacialExpression.AMAZED,"We must leave this place...") + .playerl("Where will you go?") + .npcl(FacialExpression.AMAZED,"Away.. Away to her...") + .playerl("Riiight.") + .end() + + branch.onValue(6) + .npcl(FacialExpression.AMAZED,"Below the deep, deep blue she waits...") + .playerl("Who waits?") + .npcl(FacialExpression.AMAZED,"They came to her with fire and faith...") + .playerl("Who? Who came to who?") + .npcl(FacialExpression.AMAZED,"Too many... Too many...") + .playerl("Too many what? Make sense!") + .npcl(FacialExpression.AMAZED,"Locked away for all eternity...") + .playerl("You'd better start making sense Sonny Jim or I'll...") + .npcl(FacialExpression.AMAZED,"Free... Soon to be free...") + .end() + + branch.onValue(7) + .npcl(FacialExpression.AMAZED,"Must escape the blue.. Deep deep blue") + .playerl("Pardon?") + .npcl(FacialExpression.AMAZED,"Family... Under the blue... Must escape the blue...") + .end() + } + } +} diff --git a/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/HolgartDialogueFile.kt b/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/HolgartDialogueFile.kt new file mode 100644 index 0000000..559ce73 --- /dev/null +++ b/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/HolgartDialogueFile.kt @@ -0,0 +1,101 @@ +package content.region.kandarin.witchhaven.quest.seaslug + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.FacialExpression +import org.rs09.consts.Items + +class HolgartDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onQuestStages(Quests.SEA_SLUG, 0) + .playerl(FacialExpression.FRIENDLY, "Hello.") + .npcl(FacialExpression.FRIENDLY, "Well hello @g[m'lad,m'laddy]. Beautiful day isn't it?") + .playerl("Not bad I suppose.") + .npcl("Just smell that sea air... beautiful.") + .playerl(FacialExpression.THINKING, "Hmm... lovely...") + .end() + + b.onQuestStages(Quests.SEA_SLUG, 1) + .npcl(FacialExpression.FRIENDLY, "Hello, m'hearty.") + .playerl("I would like a ride on your boat to the fishing platform.") + .npcl(FacialExpression.SAD, "I'm afraid it isn't sea worthy, it's full of holes. To fill the holes I'll need some swamp paste.") + .playerl(FacialExpression.THINKING, "Swamp paste?") + .npcl("Yes, swamp tar mixed with flour and heated over a fire.") + .branch { player -> + return@branch if (inInventory(player, Items.SWAMP_PASTE_1941)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(0) + .playerl("Where can I find swamp tar?") + .npcl("Unfortunately the only supply of swamp tar is in the swamps below Lumbridge. It's too far for an old man like me to travel.") + .npcl("If you make me some swamp paste I'll give you a ride in my boat.") + .playerl("I'll see what I can do.") + .endWith() { df, player -> + if(getQuestStage(player, Quests.SEA_SLUG) == 1) { + setQuestStage(player, Quests.SEA_SLUG, 2) + } + } + branch.onValue(1) + .npcl("In fact, unless me nose be mistaken, you've got some in yer pack.") + .playerl("Oh yes, I forgot about that stuff. Can you use it?") + .npcl("Aye @g[lad,lass]. That be perfect.") + .betweenStage { _, player, _, _ -> + removeItem(player, Items.SWAMP_PASTE_1941) + } + .iteml(Items.SWAMP_PASTE_1941, "You give Holgart the swamp paste.") + // Cutscene + .endWith() { df, player -> + if(getQuestStage(player, Quests.SEA_SLUG) == 1) { + setQuestStage(player, Quests.SEA_SLUG, 3) + } + } + } + + b.onQuestStages(Quests.SEA_SLUG, 2) + .playerl(FacialExpression.FRIENDLY, "Hello.") + .npcl("Hello, m'hearty. Did you manage to make some swamp paste?") + .branch { player -> + return@branch if (inInventory(player, Items.SWAMP_PASTE_1941)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(0) + .playerl("I'm afraid not.") + .npcl("It's simply swamp tar mixed with flour heated over a fire. Unfortunately the only supply of swamp tar is in the swamps below Lumbridge.") + .npcl("I can't fix my row boat without it.") + .playerl("Ok, I'll try to find some.") + .end() + branch.onValue(1) + .playerl("Yes, I have some here.") + .betweenStage { _, player, _, _ -> + removeItem(player, Items.SWAMP_PASTE_1941) + } + .iteml(Items.SWAMP_PASTE_1941, "You give Holgart the swamp paste.") + // Cutscene + .endWith() { df, player -> + if(getQuestStage(player, Quests.SEA_SLUG) == 2) { + setQuestStage(player, Quests.SEA_SLUG, 3) + } + } + + } + + + b.onQuestStages(Quests.SEA_SLUG, 3, 4, 5, 6, 7, 8, 9, 10, 11, 100) + .playerl(FacialExpression.FRIENDLY, "Hello, Holgart.") + .npcl("Hello again land lover. There's some strange goings on, on that platform, I tell you.") + .options().let { optionBuilder -> + optionBuilder.option("Will you take me there?") + .playerl(FacialExpression.THINKING, "Will you take me there?") + .npcl("Of course m'hearty. If that's what you want.") + .endWith() { df, player -> + SeaSlugListeners.seaslugBoatTravel(player, 0) + } + + optionBuilder.option_playerl("I'm keeping away from there.") + .npcl("Fair enough m'hearty.") + .end() + } + + + } +} diff --git a/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/HolgartIslandDialogueFile.kt b/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/HolgartIslandDialogueFile.kt new file mode 100644 index 0000000..49ab8c4 --- /dev/null +++ b/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/HolgartIslandDialogueFile.kt @@ -0,0 +1,22 @@ +package content.region.kandarin.witchhaven.quest.seaslug + +import content.data.Quests +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.FacialExpression + +class HolgartIslandDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onQuestStages(Quests.SEA_SLUG, 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 100) + .playerl("We'd better get back to the platform so we can see what's going on.") + .npcl(FacialExpression.SUSPICIOUS, "You're right. It all sounds pretty creepy.") + .endWith() { df, player -> + SeaSlugListeners.seaslugBoatTravel(player, 3) + } + b.onQuestStages(Quests.SEA_SLUG, 4) + .playerl("Where are we?") + .npc("Someway off mainland still. You'd better see if me old", "matey's okay.") + .end() + + } +} diff --git a/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/HolgartPlatformDialogueFile.kt b/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/HolgartPlatformDialogueFile.kt new file mode 100644 index 0000000..f967889 --- /dev/null +++ b/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/HolgartPlatformDialogueFile.kt @@ -0,0 +1,41 @@ +package content.region.kandarin.witchhaven.quest.seaslug + +import content.data.Quests +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.FacialExpression + +class HolgartPlatformDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onQuestStages(Quests.SEA_SLUG, 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 100) + .playerl(FacialExpression.FRIENDLY, "Hey, Holgart.") + .npcl("Have you had enough of this place yet? It's really starting to scare me.") + .options().let { optionBuilder -> + optionBuilder.option_playerl("Okay, let's go back.") + .endWith() { df, player -> + SeaSlugListeners.seaslugBoatTravel(player, 1) + } + optionBuilder.option_playerl("No, I'm going to stay a while.") + .npcl("Okay... you're the boss.") + .end() + } + + b.onQuestStages(Quests.SEA_SLUG, 4) + .playerl("Holgart, something strange is going on here.") + .npcl("You're telling me, none of the sailors seem to remember who I am.") + .playerl("Apparently Kennith's father left for help a couple of days ago.") + .npcl("That's a worry, no-one's heard from him on shore. Come on, we'd better go look for him.") + .endWith() { df, player -> + SeaSlugListeners.seaslugBoatTravel(player, 2) + } + + b.onQuestStages(Quests.SEA_SLUG, 11) + .playerl("Did you get the kid back to shore?") + .npcl("Yes, he's safe and sound with his parents. Your turn to return to land now adventurer.") + .playerl("Looking forward to it.") + .endWith() { df, player -> + SeaSlugListeners.seaslugBoatTravel(player, 1) + } + + } +} diff --git a/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/KennithDialogueFile.kt b/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/KennithDialogueFile.kt new file mode 100644 index 0000000..a12f2e9 --- /dev/null +++ b/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/KennithDialogueFile.kt @@ -0,0 +1,69 @@ +package content.region.kandarin.witchhaven.quest.seaslug + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.FacialExpression + +class KennithDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onQuestStages(Quests.SEA_SLUG, 0, 1, 2, 3) + .playerl(FacialExpression.THINKING, "Are you okay young one?") + .npcl(FacialExpression.CHILD_SAD, "No, I want daddy!") + .playerl("Where is your father?") + .npcl(FacialExpression.CHILD_SAD, "He went to get help days ago.") + .npcl(FacialExpression.CHILD_SAD, "The nasty fishermen tried to throw me and daddy into the sea. So he told me to hide here.") + .playerl("That's good advice, you stay here and I'll go try and find your father.") + .endWith() { df, player -> + if(getQuestStage(player, Quests.SEA_SLUG) == 3) { + setQuestStage(player, Quests.SEA_SLUG, 4) + } + } + b.onQuestStages(Quests.SEA_SLUG, 4, 5, 6) + .playerl(FacialExpression.THINKING, "Are you okay?") + .npcl(FacialExpression.CHILD_SAD, "I want to see daddy!") + .playerl("I'm working on it.") + .end() + + b.onQuestStages(Quests.SEA_SLUG, 7) + .playerl("Hello Kennith, are you okay?") + .npcl(FacialExpression.CHILD_SAD, "No, I want my daddy.") + .playerl("You'll be able to see him soon. First we need to get you back to land, come with me to the boat.") + .npcl(FacialExpression.CHILD_SURPRISED, "No!") + .playerl("What, why not?") + .npcl(FacialExpression.CHILD_SURPRISED, "I'm scared of those nasty sea slugs. I won't go near them.") + .playerl("Okay, you wait here and I'll go figure another way to get you out.") + .endWith() { df, player -> + if(getQuestStage(player, Quests.SEA_SLUG) == 7) { + setQuestStage(player, Quests.SEA_SLUG, 8) + } + } + + b.onQuestStages(Quests.SEA_SLUG, 8) + // This stage is unfortunately left out. You can't interact with Kennith authentically. + .end() + + b.onQuestStages(Quests.SEA_SLUG, 9) + .playerl("Kennith, I've made an opening in the wall. You can come out through there.") + .npcl(FacialExpression.CHILD_THINKING, "Are there any sea slugs on the other side?") + .playerl("Not one.") + .npcl(FacialExpression.CHILD_THINKING, "How will I get downstairs?") + .playerl("I'll figure that out in a moment.") + .npcl(FacialExpression.CHILD_NORMAL, "Ok, when you have I'll come out.") + .endWith() { df, player -> + if(getQuestStage(player, Quests.SEA_SLUG) == 9) { + setQuestStage(player, Quests.SEA_SLUG, 10) + } + } + + b.onQuestStages(Quests.SEA_SLUG, 10) + // This stage is also unfortunately left out. You can't interact with Kennith authentically. + .end() + + b.onQuestStages(Quests.SEA_SLUG, 11, 100) + // Kennith is varp swapped out, so is no longer here. + .end() + + } +} diff --git a/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/KentDialogueFile.kt b/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/KentDialogueFile.kt new file mode 100644 index 0000000..1e9fee5 --- /dev/null +++ b/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/KentDialogueFile.kt @@ -0,0 +1,41 @@ +package content.region.kandarin.witchhaven.quest.seaslug + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.FacialExpression + +class KentDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onQuestStages(Quests.SEA_SLUG, 0, 1, 2, 3, 4, 5, 6) + .npcl("Oh thank Saradomin! I thought I'd be left out here forever.") + .playerl("Your wife sent me out to find you and your boy. Kennith's fine by the way, he's on the platform.") + .npcl("I knew the row boat wasn't sea worthy. I couldn't risk bringing him along but you must get him off that platform.") + .playerl("What's going on here?") + .npcl("Five days ago we pulled in a huge catch. As well as fish we caught small slug like creatures, hundreds of them.") + .npcl("That's when the fishermen began to act strange.") + .npcl("It was the sea slugs, they attack themselves to your body and somehow take over the mind of the carrier.") + .npcl("I told Kennith to hide until I returned but I was washed up here.") + .npcl("Please go back and get my boy, you can send help for me later.") + .npcl(FacialExpression.EXTREMELY_SHOCKED, "@name wait!") + .betweenStage { _, player, _, _ -> + visualize(npc!!, 4807, 790) + sendMessage(player, "*slooop*") + sendMessage(player, "He pulls a sea slug from under your top.") + } + .npcl("A few more minutes and that thing would have full control of your body.") + .playerl(FacialExpression.EXTREMELY_SHOCKED, "Yuck! Thanks Kent.") + .endWith() { df, player -> + if(getQuestStage(player, Quests.SEA_SLUG) == 4) { + setQuestStage(player, Quests.SEA_SLUG, 5) + } + } + + b.onQuestStages(Quests.SEA_SLUG, 5, 6, 7, 8, 9, 10, 11, 100) + .playerl("Hello.") + .npcl("Oh my, I must get back to shore.") + .end() + + } +} diff --git a/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/SeaSlug.kt b/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/SeaSlug.kt new file mode 100644 index 0000000..ef34242 --- /dev/null +++ b/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/SeaSlug.kt @@ -0,0 +1,186 @@ +package content.region.kandarin.witchhaven.quest.seaslug + +import content.data.Quests +import core.api.* +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import org.rs09.consts.Items + +/** + * Sea Slug Quest + * + * Note that the varp 159 controls the quest AND some environments: + * The BADLY_REPAIRED_WALL_18381 disappears after varp 159 is set to 9 + * KENNITH_4864 disappears after varp 159 is set to 11 + * KENNITH_4865 (but ID 4864) appears after varp 159 is set to 11 + * + * https://www.youtube.com/watch?v=lf83SACuIDw (This is amazing) + * https://www.youtube.com/watch?v=VnghpKbUqKw + * https://www.youtube.com/watch?v=thHuATlGYag + * https://www.youtube.com/watch?v=VR91Rbyuou4 (This has many other unvisited paths) + */ +@Initializable +class SeaSlug : Quest(Quests.SEA_SLUG, 109, 108, 1,159, 0, 1, 12) { + + companion object { + const val questVarp = 159 + } + override fun drawJournal(player: Player, stage: Int) { + super.drawJournal(player, stage) + var line = 12 + var stage = getStage(player) + + var started = getQuestStage(player, Quests.SEA_SLUG) > 0 + + if (!started) { + line(player, "I can start this quest by speaking to !!Caroline?? who is !!East??", line++, false) + line(player, "!!of Ardougne??.", line++, false) + line++ + line(player, "Requirements:", line++, false) + // I think this is an old line. I saw it being the other line for 30 Firemaking reqs. + line(player, "You'll need level 30 !!Firemaking??", line++, hasLevelStat(player, Skills.FIREMAKING, 30)) + // line(player, "!!Level 30 Firemaking??", line++, hasLevelStat(player, Skills.FIREMAKING, 30)) + } else { + line(player, "I have spoken to Caroline and agreed to help", line++, true) + line++ + + if (stage >= 3) { + line(player, "I gave Holgart the Swamp Paste and his boat is now ready", line++, true) + line(player, "to take me to the Fishing Platform", line++, true) + } else if (stage >= 2) { + // authentic from https://www.youtube.com/watch?v=VnghpKbUqKw + line(player, "I've spoken to !!Holgart?? but his boat is broken", line++, false) + line(player, "He needs me to bring him some !!Swamp Paste??", line++, false) + line++ + line(player, "I can make !!Swamp Paste?? by mixing !!Swamp Tar?? with !!Flour?? and", line++, false) + line(player, "then heating the mixture on a !!Fire??", line++, false) + line(player, "I can find !!Swamp Tar?? in the !!Swamp South of Lumbridge??", line++, false) + line++ + line(player, "I need to get to the !!Fishing Platform?? and find out what's", line++, false) + line(player, "happened to Kent and Kennith", line++, false) + } else if (stage >= 1) { + // derived + line(player, "I need to speak to !!Holgart??.", line++, false) + } + + if (stage >= 5) { + line++ + line(player, "I've found Kennith, he's hiding behind some boxes.", line++, true) + line++ + line(player, "I've found Kent on a small island", line++, true) + } else if (stage >= 4) { + line++ + line(player, "I've found Kennith, he's hiding behind some boxes.", line++, true) + line++ + line(player, "I need to find !!Kent??", line++, false) + } else if (stage >= 3) { + line++ + line(player, "I need to find !!Kent?? and !!Kennith??", line++, false) + } + + if (stage >= 9) { + line++ + line(player, "!!Kent?? has asked me to help !!Kennith?? escape", line++, true) + } else if (stage >= 5) { + line++ + line(player, "!!Kent?? has asked me to help !!Kennith?? escape", line++, false) + } + + if (stage >= 9) { + line(player, "After speaking to Bailey, I found that Sea Slugs are", line++, true) + line(player, "afraid of heat.", line++, true) + line(player, "I should find a way of lighting this damp torch.", line++, true) + } else if (stage >= 6) { + line(player, "After speaking to !!Bailey??, I found that Sea Slugs are", line++, false) + line(player, "afraid of heat.", line++, false) + line(player, "I should find a way of lighting this damp torch.", line++, false) + } + + if (stage >= 8) { + // Disappears + } else if (stage >= 7) { + // Derived + line(player, "I should talk to !!Kennith??", line++, false) + } + + if (stage >= 9) { + line(player, "I've created an opening to let Kennith escape", line++, true) + } else if (stage >= 8) { + // Derived + line(player, "I need to find a way to get !!Kennith?? out", line++, false) + } + + if (stage >= 10) { + line++ + line(player, "Kennith can't get downstairs without some help", line++, true) + } else if (stage >= 9) { + // Derived + line++ + line(player, "I should talk to !!Kennith?? again", line++, false) + } + + + if (stage >= 11) { + line++ + line(player, "I've used the Crane to lower Kennith into the boat", line++, true) + } else if (stage >= 10) { + line++ + line(player, "!!Kennith?? won't go near the !!Sea Slugs??", line++, false) + line(player, "I need to find another way to get him out", line++, false) + } + + if (stage >= 100) { + line++ + line(player, "I've spoken to Caroline and she thanked me for", line++, true) + line(player, "rescuing her family from the Sea Slugs", line++, true) + } else if (stage >= 11) { + line++ + line(player, "I need to take the boat back to shore and talk to !!Caroline??", line++, false) + } + + if (stage >= 100) { + line++ + line(player,"QUEST COMPLETE!", line) + } + } + + } + + override fun reset(player: Player) { + // removeAttribute(player, attributeTalkedToHolgart) + } + + override fun finish(player: Player) { + var ln = 10 + super.finish(player) + player.packetDispatch.sendString("You have completed Sea Slug!", 277, 4) + player.packetDispatch.sendItemZoomOnInterface(Items.SEA_SLUG_1466,230,277,5) + + drawReward(player, "1 Quest Point", ln++) + drawReward(player, "7175 Fishing XP", ln++) + drawReward(player, "Oyster pearls", ln++) + + rewardXP(player, Skills.FISHING, 7175.0) + addItemOrDrop(player, Items.OYSTER_PEARLS_413) + } + + override fun setStage(player: Player, stage: Int) { + super.setStage(player, stage) + this.updateVarps(player) + } + + override fun updateVarps(player: Player) { + // The quest stages are perfectly aligned with the varp since the varp controls npcs and sceneries + if (getQuestStage(player, Quests.SEA_SLUG) >= 12) { + setVarp(player, questVarp, 12, true) // Except for stage 100 which is varp set to 12 obviously. + } else { + setVarp(player, questVarp, getQuestStage(player, Quests.SEA_SLUG), true) + } + } + + override fun newInstance(`object`: Any?): Quest { + return this + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/SeaSlugListeners.kt b/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/SeaSlugListeners.kt new file mode 100644 index 0000000..79a1b10 --- /dev/null +++ b/Server/src/main/content/region/kandarin/witchhaven/quest/seaslug/SeaSlugListeners.kt @@ -0,0 +1,196 @@ +package content.region.kandarin.witchhaven.quest.seaslug + +import content.data.Quests +import core.api.* +import core.game.global.action.ClimbActionHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength +import core.game.node.entity.combat.ImpactHandler +import core.game.node.entity.combat.ImpactHandler.HitsplatType +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.world.map.Location +import org.rs09.consts.Components +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +class SeaSlugListeners : InteractionListener { + + companion object { + + // The boat travels are animated nicely for you by un-hiding child 10 - 13 + val BOAT_TRAVEL_CHILD = arrayOf(10, 11, 12, 13) + val BOAT_TRAVEL_TICKS = arrayOf(5, 9, 8, 7) + val BOAT_TRAVEL_DESTINATION = arrayOf( + Location(2782, 3273), // From LAND to PLATFORM + Location(2721, 3304), // From PLATFORM to LAND + Location(2800, 3320), // From PLATFORM to ISLAND + Location(2782, 3273), // From ISLAND to PLATFORM + ) + val BOAT_TRAVEL_DIALOGUE = arrayOf( + "You arrive at the fishing platform.", // From LAND to PLATFORM + "The boat arrives at Witchaven.", // From PLATFORM to LAND + "You arrive on a small island.", // From PLATFORM to ISLAND + "You arrive at the fishing platform.", // From ISLAND to PLATFORM + ) + + fun seaslugBoatTravel(player: Player, travelIndex: Int) { + if (travelIndex == 0) { + // Prevent bringing lit torches. + while(removeItem(player, Items.LIT_TORCH_594)) { + sendMessage(player, "Your torch goes out on the crossing.") + addItemOrDrop(player, Items.UNLIT_TORCH_596) + } + } + queueScript(player, 0, QueueStrength.SOFT) { stage: Int -> + when(stage){ + 0 -> { + closeOverlay(player) + openOverlay(player, Components.FADE_TO_BLACK_120) + lock(player, 2) + return@queueScript delayScript(player, 1) + } + 1 -> { + teleport(player, BOAT_TRAVEL_DESTINATION[travelIndex]) + openOverlay(player, Components.SEASLUG_BOAT_TRAVEL_461) + setComponentVisibility(player, Components.SEASLUG_BOAT_TRAVEL_461, BOAT_TRAVEL_CHILD[travelIndex], false) + lock(player, BOAT_TRAVEL_TICKS[travelIndex]) + return@queueScript delayScript(player, BOAT_TRAVEL_TICKS[travelIndex]) + } + 2 -> { + sendDialogue(player, BOAT_TRAVEL_DIALOGUE[travelIndex]) + player.interfaceManager.closeOverlay() + openOverlay(player, Components.FADE_FROM_BLACK_170) + return@queueScript stopExecuting(player) + } + } + return@queueScript stopExecuting(player) + } + } + + } + override fun defineListeners() { + // https://www.youtube.com/watch?v=VR91Rbyuou4 + // Your tinderbox is damp from the sea crossing. It won't light here. + // Your torch goes out on the crossing. + + onUseWith(IntType.ITEM, Items.SWAMP_TAR_1939, Items.POT_OF_FLOUR_1933){ player, used, with -> + val toRemove = Item(used.id, 1, used.asItem().slot) + if(removeItem(player, toRemove) && removeItem(player, with)) { + sendMessage(player, "You mix the flour with the swamp tar.") + sendMessage(player, "It mixes into a paste.") + addItemOrDrop(player, Items.EMPTY_POT_1931) + addItemOrDrop(player, Items.RAW_SWAMP_PASTE_1940) + } + return@onUseWith true + } + + // You can only cook it using firewood. + // sendMessage(player, "You can't cook that in a range.") + onUseWith(SCENERY, Items.RAW_SWAMP_PASTE_1940, Scenery.FIRE_2732) { player, used, with -> + val toRemove = Item(used.id, 1, used.asItem().slot) + if(removeItem(player, toRemove)) { + sendMessage(player, "You warm the paste over the fire. It thickens into a sticky goo.") + addItemOrDrop(player, Items.SWAMP_PASTE_1941) + } + return@onUseWith true + } + + + on(Scenery.LADDER_18324, IntType.SCENERY, "climb-up") { player, _ -> + if (getQuestStage(player, Quests.SEA_SLUG) in 5..6) { + if (getQuestStage(player, Quests.SEA_SLUG) == 6 && inInventory(player, Items.LIT_TORCH_594)) { + setQuestStage(player, Quests.SEA_SLUG, 7) + ClimbActionHandler.climb(player, ClimbActionHandler.CLIMB_UP, Location(2784, 3285, 1)) + } else { + animate(player, 4785) + sendMessage(player, "You attempt to climb up the ladder.") + sendMessage(player, "The fisherman approach you...") + sendMessage(player, "and smack you on the head with a fishing rod!") + sendMessage(player, "Ouch!") + sendChat(player, "Ouch!") + player.impactHandler.manualHit(player, 4, ImpactHandler.HitsplatType.NORMAL) + } + } else { + ClimbActionHandler.climb(player, ClimbActionHandler.CLIMB_UP, Location(2784, 3285, 1)) + } + return@on true + } + on(Scenery.LADDER_18325, IntType.SCENERY, "climb-down") { player, _ -> + ClimbActionHandler.climb(player, ClimbActionHandler.CLIMB_DOWN, Location(2784, 3287, 0)) + return@on true + } + + on(Scenery.BADLY_REPAIRED_WALL_18381, IntType.SCENERY, "kick") { player, _ -> + if(getQuestStage(player, Quests.SEA_SLUG) == 8) { + animate(player, 4804) + sendMessage(player, "You kick the loose panel.") + sendMessage(player, "The wood is rotted and crumbles away...") + sendMessage(player, "... leaving an opening big enough for Kennith to climb through.") + setQuestStage(player, Quests.SEA_SLUG, 9) + } else { + // https://youtu.be/OM-akv7oIZ0 2:41 + sendMessage(player, "You kick the loose panel...") + sendMessage(player, "... but nothing interesting happens.") + } + return@on true + } + + on(Scenery.CRANE_18327, IntType.SCENERY, "rotate") { player, node -> + if(getQuestStage(player, Quests.SEA_SLUG) == 10) { + // This is supposed to be a cutscene, but goddamn do I hate programming cutscenes. + lock(player, 6) + player.dialogueInterpreter.sendPlainMessage(true, "Kennith scrambles through the broken wall...") + replaceScenery(node as core.game.node.scenery.Scenery, Scenery.CRANE_18326, 6) + animateScenery(node as core.game.node.scenery.Scenery, 4798) + setQuestStage(player, Quests.SEA_SLUG, 11) + queueScript(player, 6, QueueStrength.SOFT) { stage: Int -> + sendDialogue(player, "Down below, you see Holgart collect the boy from the crane and lead him away to safety.") + return@queueScript stopExecuting(player) + } + } else { + sendMessage(player, "You rotate the crane around.") + animateScenery(node as core.game.node.scenery.Scenery, 4796) + } + return@on true + } + + onUseWith(IntType.ITEM, Items.DAMP_STICKS_1467, Items.BROKEN_GLASS_1469){ player, used, with -> + if(removeItem(player, used)) { + visualize(player, 4809, 791) + addItemOrDrop(player, Items.DRY_STICKS_1468) + } + return@onUseWith true + } + + onUseWith(IntType.ITEM, Items.DRY_STICKS_1468, Items.UNLIT_TORCH_596){ player, bolt, tip -> + addItemOrDrop(player, Items.LIT_TORCH_594) + return@onUseWith true + } + + on(Items.DRY_STICKS_1468, ITEM, "rub-together") { player, _ -> + sendMessage(player, "You rub together the dry sticks and the sticks catch alight.") + if(removeItem(player, Items.UNLIT_TORCH_596)) { + sendMessage(player, "You place the smouldering twigs to your torch.") + sendMessage(player, "Your torch lights.") + addItemOrDrop(player, Items.LIT_TORCH_594) + } + return@on true + } + + + on(NPCs.SEA_SLUG_1006, IntType.NPC, "take") { player, _ -> + sendMessage(player, "You pick up the sea slug.") + sendMessage(player, "It sinks its teeth deep into your hand.") + sendMessage(player, "You drop the sea slug.") + sendChat(player, "Ouch!") + impact(player, 3, HitsplatType.NORMAL) + return@on true + } + + } + + +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/yanille/dialogue/AleckDialogue.java b/Server/src/main/content/region/kandarin/yanille/dialogue/AleckDialogue.java new file mode 100644 index 0000000..9eb3ebe --- /dev/null +++ b/Server/src/main/content/region/kandarin/yanille/dialogue/AleckDialogue.java @@ -0,0 +1,104 @@ +package content.region.kandarin.yanille.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the plugin dialogue used for the aleck npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class AleckDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code AleckDialogue} {@code Object}. + */ + public AleckDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code AleckDialogue} {@code Object}. + * @param player the player. + */ + public AleckDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new AleckDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + player("Hello."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + npc("Hello, hello, and a most warm welcome to my Hunter", "Emporium. We have everything the discerning Hunter", "could need."); + stage = 1; + break; + case 1: + npc("Would you like me to show you our range of", "equipment? Or was there something specific you were", "after?"); + stage = 2; + break; + case 2: + interpreter.sendOptions("Select an Option", "Ok, let's see what you've got.", "I'm not interested, thanks.", "Who's that guy over there?"); + stage = 3; + break; + case 3: + switch (buttonId) { + case 1: + player("Ok, let's see what you've got!"); + stage = 10; + break; + case 2: + player("I'm not interested, thanks."); + stage = 20; + break; + case 3: + player("Who's that guy over there?"); + stage = 30; + break; + + } + break; + case 10: + end(); + npc.openShop(player); + break; + case 20: + end(); + break; + case 30: + npc("Him? I think he might be crazy. Either that or he's", "seeking attention."); + stage = 31; + break; + case 31: + npc("He keeps trying to sell me these barmy looking weapons", "he's invented. I can't see them working, personally."); + stage = 32; + break; + case 32: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 5110 }; + } +} diff --git a/Server/src/main/content/region/kandarin/yanille/dialogue/FenitasDialogue.java b/Server/src/main/content/region/kandarin/yanille/dialogue/FenitasDialogue.java new file mode 100644 index 0000000..a562fe4 --- /dev/null +++ b/Server/src/main/content/region/kandarin/yanille/dialogue/FenitasDialogue.java @@ -0,0 +1,66 @@ +package content.region.kandarin.yanille.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the fenitas dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class FenitasDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code FenitasDialogue} {@code Object}. + */ + public FenitasDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code FenitasDialogue} {@code Object}. + * @param player the player. + */ + public FenitasDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new FenitasDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Would you like to buy some cooking equipment?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(player, FacialExpression.HAPPY, "Yes please."); + stage = 1; + break; + case 1: + end(); + npc.openShop(player); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 593 }; + } +} diff --git a/Server/src/main/content/region/kandarin/yanille/dialogue/LeonDialogue.kt b/Server/src/main/content/region/kandarin/yanille/dialogue/LeonDialogue.kt new file mode 100644 index 0000000..f5e3b24 --- /dev/null +++ b/Server/src/main/content/region/kandarin/yanille/dialogue/LeonDialogue.kt @@ -0,0 +1,134 @@ +package content.region.kandarin.yanille.dialogue + +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.IfTopic +import core.game.dialogue.Topic +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class LeonDialogue (player: Player? = null) : DialoguePlugin(player) { + + companion object { + const val WHAT_IS_THIS_PLACE = 10 + const val BUY_GEAR = 20 + const val ABOUT_CBOW = 30 + const val ABOUT_AMMO = 40 + const val BYE = 50 + const val CRAZY = 60 + const val TRADE = 70 + const val MAKE_OWN_AMMO = 80 + const val CRAFT_AMMO = 90 + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + if (hasAnItem(player, Items.HUNTERS_CROSSBOW_10156).exists()) npcl(FacialExpression.HAPPY, "Oh, hey, you have one of my crossbows! How's it working for you?") + else sendItemDialogue(player, Items.HUNTERS_CROSSBOW_10156,"Leon is gazing intently at the crossbow in his hands.") + return true + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> showTopics( + IfTopic("It's okay, thanks.", 0, hasAnItem(player, Items.HUNTERS_CROSSBOW_10156).exists()), + Topic("What is this place?", WHAT_IS_THIS_PLACE), + Topic("Can you tell me about your crossbow?", ABOUT_CBOW), + Topic("Tell me about the ammo for your crossbow.", ABOUT_AMMO), + Topic("I'll be off now, excuse me.", BYE), + + ) + + WHAT_IS_THIS_PLACE -> npcl(FacialExpression.NEUTRAL, "This is Aleck's Hunter Emporium. Basically, it's just a shop with a fancy name; you can buy various weapons and traps here.").also { stage++ } + WHAT_IS_THIS_PLACE + 1 -> showTopics( + Topic("Can I buy some equipment from the shop then?", BUY_GEAR), + Topic("Can you tell me about your crossbow?", ABOUT_CBOW), + Topic("Tell me about the ammo for your crossbow.", ABOUT_AMMO), + Topic("I'll be off now, excuse me.", BYE) + ) + + BUY_GEAR -> npcl(FacialExpression.NEUTRAL, "Oh, this isn't my shop; the owner is Aleck over there behind the counter.").also { stage++ } + BUY_GEAR + 1 -> npcl(FacialExpression.NEUTRAL, "I experiment with weapon designs. I'm here because I've been trying to convince people to back my research and maybe sell some of my products - like this one I'm holding - in their shops.").also { stage++ } + BUY_GEAR + 2 -> npcl(FacialExpression.SAD, "Aleck doesn't seem to be interested, though.").also { stage++ } + BUY_GEAR + 3 -> showTopics( + Topic("Can you tell me about your crossbow?", ABOUT_CBOW), + Topic("Tell me about the ammo for your crossbow.", ABOUT_AMMO), + Topic("I'll be off now, excuse me.", BYE) + ) + + ABOUT_CBOW -> npcl(FacialExpression.HAPPY, "It's good, isn't it? I designed it to incorporate the bones of various animals in its construction.").also { stage++ } + ABOUT_CBOW + 1 -> npcl(FacialExpression.HAPPY, "It's a fair bit faster than an ordinary crossbow too; it'll take you far less time to reload between shots.").also { stage++ } + ABOUT_CBOW + 2 -> showTopics( + Topic("That's crazy, it'll never work!", CRAZY), + Topic("That sounds good. Let's trade.", TRADE) + ) + + CRAZY -> npcl(FacialExpression.HALF_THINKING, "That's what they said about my wind-powered mouse traps, too.").also { stage++ } + CRAZY + 1 -> playerl(FacialExpression.HALF_WORRIED, "And did they work?").also { stage++ } + CRAZY + 2 -> npcl(FacialExpression.HALF_THINKING, "Well, they only ran into problems because people kept insisting on trying to use them indoors.").also { stage++ } + CRAZY + 3 -> npcl(FacialExpression.HAPPY, "Anyway, I think my crossbow invention is showing a lot more promise.").also { stage = 0 } + + TRADE -> { + end() + openNpcShop(player, npc.id) + } + + ABOUT_AMMO -> npcl(FacialExpression.NEUTRAL, "Ah, I admit as a result of its... er... unique construction, it won't take just any old bolts.").also { stage++ } + ABOUT_AMMO + 1 -> npcl(FacialExpression.NEUTRAL, "If you can supply the materials and a token fee, I'd be happy to make some for you.").also { stage++ } + ABOUT_AMMO + 2 -> npcl(FacialExpression.NEUTRAL, "I need kebbit spikes, lots of 'em. Not all kebbits have spikes, mind you. You'll be wanting prickly kebbits or, even better, razor-backed kebbits to get material hard enough.").also { stage++ } + ABOUT_AMMO + 3 -> showTopics( + Topic("Can't I just make my own?", MAKE_OWN_AMMO), + Topic("Okay, can you make ammo for me?", CRAFT_AMMO) + ) + + MAKE_OWN_AMMO -> npcl(FacialExpression.HALF_THINKING, "Yes, I suppose you could, although you'll need a steady hand with a knife and a chisel.").also { stage++ } + MAKE_OWN_AMMO + 1 -> npcl(FacialExpression.HALF_THINKING, "The bolts have an unusual diameter, but basically you'll just need to be able to carve kebbit spikes into straight shafts.").also { stage++ } + MAKE_OWN_AMMO + 2 -> npcl(FacialExpression.NEUTRAL, "Meanwhile, since you're here, I can make some for you if you have the materials.").also { stage = 0 } + + // OSRS suggests this may be inauthentic and there should be a make x interface. + // No 2009 sources found saying that though + CRAFT_AMMO -> npcl(FacialExpression.NEUTRAL, "Sure what type of bolts do you want?").also { stage++ } + CRAFT_AMMO + 1 -> showTopics( + Topic("Kebbit bolts.", CRAFT_AMMO + 2), + Topic("Long kebbit bolts.", CRAFT_AMMO + 3) + ) + CRAFT_AMMO + 2 -> { + if (hasAnItem(player!!, Items.KEBBIT_SPIKE_10105).exists() && inInventory(player, Items.COINS_995, 20)){ + if(removeItem(player, Items.KEBBIT_SPIKE_10105) && removeItem(player, Item(Items.COINS_995, 20))){ + addItem(player, Items.KEBBIT_BOLTS_10158, 6) + sendItemDialogue(player, Items.KEBBIT_BOLTS_10158, "You hand the weapon designer one spike and 20 coins. In return he presents you with 6 bolts.").also { stage = END_DIALOGUE } + } + } + else{ + sendItemDialogue(player, Items.KEBBIT_SPIKE_10105, "You need 1 kebbit spike and 20 coins to make 6 kebbit bolts.").also { stage = END_DIALOGUE } + } + } + CRAFT_AMMO + 3 -> { + if (hasAnItem(player!!, Items.LONG_KEBBIT_SPIKE_10107).exists() && inInventory(player, Items.COINS_995, 24)){ + if(removeItem(player, Items.LONG_KEBBIT_SPIKE_10107) && removeItem(player, Item(Items.COINS_995, 40))){ + addItem(player, Items.LONG_KEBBIT_BOLTS_10159, 6) + sendItemDialogue(player, Items.LONG_KEBBIT_BOLTS_10159, "You hand the weapon designer one long spike and 40 coins. In return he presents you with 6 long bolts.").also { stage = END_DIALOGUE } + } + } + else{ + sendItemDialogue(player, Items.LONG_KEBBIT_SPIKE_10107, "You need 1 long kebbit spike and 40 coins to make 6 kebbit bolts.").also { stage = END_DIALOGUE } + } + } + + BYE -> npcl(FacialExpression.NEUTRAL, "Well, if you ever find yourself in need of that innovative edge, you can always find me here.").also { stage++ } + BYE + 1 -> playerl(FacialExpression.HALF_ROLLING_EYES, "...thanks").also { stage = END_DIALOGUE } + } + + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.LEON_5111) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/yanille/dialogue/MagicStoreDialogue.java b/Server/src/main/content/region/kandarin/yanille/dialogue/MagicStoreDialogue.java new file mode 100644 index 0000000..ba13e7c --- /dev/null +++ b/Server/src/main/content/region/kandarin/yanille/dialogue/MagicStoreDialogue.java @@ -0,0 +1,77 @@ +package content.region.kandarin.yanille.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the magic store dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class MagicStoreDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code MagicStoreDialogue} {@code Object}. + * @param player the player. + */ + public MagicStoreDialogue(final Player player) { + super(player); + } + + /** + * Constructs a new {@code MagicStoreDialogue} {@code Object}. + */ + public MagicStoreDialogue() { + /** + * empty. + */ + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new MagicStoreDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + npc("Welcome to the Magic Guild Store. Would you like to", "buy some magic supplies?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + options("Yes please.", "No thank you."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + player("Yes please."); + stage = 10; + break; + case 2: + end(); + break; + } + break; + case 10: + end(); + npc.openShop(player); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 461 }; + } + +} diff --git a/Server/src/main/content/region/kandarin/yanille/dialogue/ZavisticRarveDialogue.kt b/Server/src/main/content/region/kandarin/yanille/dialogue/ZavisticRarveDialogue.kt new file mode 100644 index 0000000..9ccbedc --- /dev/null +++ b/Server/src/main/content/region/kandarin/yanille/dialogue/ZavisticRarveDialogue.kt @@ -0,0 +1,120 @@ +package content.region.kandarin.yanille.dialogue + +import content.region.kandarin.feldip.quest.zogreflesheaters.ZogreFleshEaters +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class ZavisticRarveDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return ZavisticRarveDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, ZavisticRarveDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.ZAVISTIC_RARVE_2059) + } +} +class ZavisticRarveDialogueFile : DialogueBuilderFile() { + + companion object { + fun dialogueInitialTalk(builder: DialogueBuilder) : DialogueBuilder { + return builder + .branch { player -> + return@branch if (getQuestStage(player, ZogreFleshEaters.questName) > 3 /* || hand in the sand quest */) { + 1 + } else { + 0 + } + }.let { branch2 -> + val returnJoin = builder.placeholder() + branch2.onValue(1) + .npcl("What are you doing...Oh, it's you...sorry...didn't realise...what can I do for you?") + // There is a fork here if you are doing hand in the sand. + .goto(returnJoin) + branch2.onValue(0) + .npcl("What are you doing bothering me? Don't you think some of us have work to do?") + .playerl("I thought you were here to help?") + .npcl("Well... I am, I suppose, anyway... we're very busy here, hurry up, what do you want?") + .goto(returnJoin) + return@let returnJoin.builder() + } + } + + fun dialogueInitialTalkViaBell(builder: DialogueBuilder) : DialogueBuilder { + return builder + .branch { player -> + return@branch if (getQuestStage(player, ZogreFleshEaters.questName) > 3 /* || hand in the sand quest */) { + 1 + } else { + 0 + } + }.let { branch2 -> + val returnJoin = builder.placeholder() + branch2.onValue(1) + .npcl("What are you doing...Oh, it's you...sorry...didn't realise...what can I do for you?") + .goto(returnJoin) + branch2.onValue(0) + .npcl("What are you doing ringing that bell?! Don't you think some of us have work to do?") + .playerl("But I was told to ring the bell if I wanted some attention.") + .npcl("Well...anyway...we're very busy here, hurry up what do you want?") + .goto(returnJoin) + return@let returnJoin.builder() + } + } + + fun defaultTalk(continueBuilder: DialogueBuilder) { + continueBuilder.let { builder -> + val returnJoin = builder.placeholder() + returnJoin.builder() + .options() + .let { optionBuilder -> + optionBuilder.option_playerl("What is there to do in the Wizards' Guild?") + .npcl("This is the finest wizards' establishment in the land.") + .npcl("We have magic portals to the other towers of wizardry around Gielinor.") + .npcl("We have a particularly wide collection of runes in our rune shop.") + .npcl("We sell some of the finest mage robes in the land and we have a training area full of zombies for you to practice your magic on.") + .goto(returnJoin) + optionBuilder.option_playerl("What are the requirements to get in the Wizards' Guild?") + .npcl("You need a magic level of 66, the high magic energy level is too dangerous for anyone below that level.") + .goto(returnJoin) + optionBuilder.option_playerl("What do you do in the Guild?") + .npcl("I'm the Grand Secretary for the Wizards' Guild, I have lots of correspondence to keep up with, as well as attending to the discipline of the more problematic guild members.") + .goto(returnJoin) + optionBuilder.option_playerl("Ok, thanks.") + .end() + } + builder.goto(returnJoin) + } + } + } + + + override fun create(b: DialogueBuilder) { + + b.onPredicate { player -> isQuestComplete(player, ZogreFleshEaters.questName) } + .let { dialogueInitialTalk(it) } + .let { defaultTalk(it) } + + // This is during the ZogreFleshEaters quest + b.onPredicate { player -> isQuestInProgress(player, ZogreFleshEaters.questName, 2, 99) } + .manualStage() { df, player, _, _ -> + openDialogue(player, content.region.kandarin.feldip.quest.zogreflesheaters.ZavisticRarveDialogueFile(), npc!!) + } + .end() + + b.onPredicate { _ -> true } + .let { dialogueInitialTalk(it) } + .let { defaultTalk(it) } + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/kandarin/yanille/handlers/YanilleAgilityDungeon.kt b/Server/src/main/content/region/kandarin/yanille/handlers/YanilleAgilityDungeon.kt new file mode 100644 index 0000000..509ea4e --- /dev/null +++ b/Server/src/main/content/region/kandarin/yanille/handlers/YanilleAgilityDungeon.kt @@ -0,0 +1,189 @@ +package content.region.kandarin.yanille.handlers + +import core.api.* +import org.rs09.consts.Items +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.game.node.entity.skill.Skills +import content.global.skill.agility.AgilityHandler +import core.game.node.entity.combat.BattleState +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.node.scenery.Scenery +import core.game.node.scenery.SceneryBuilder +import core.game.system.task.Pulse +import core.game.world.GameWorld +import core.game.world.map.Direction +import core.game.world.map.Location +import core.game.world.map.zone.MapZone +import core.game.world.map.zone.ZoneBorders +import core.game.world.map.zone.ZoneBuilder +import core.game.world.update.flag.context.Animation +import core.plugin.Initializable +import core.tools.RandomFunction + +/** + * The herb items. + */ +val SINISTER_CHEST_HERBS = arrayOf(Item(205, 2), Item(207, 3), Item(209), Item(211), Item(213), Item(219)) + +public class YanilleAgilityDungeonListeners : InteractionListener { + override fun defineListeners() { + ZoneBuilder.configure(YanilleAgilityDungeon()) + + on(1728, IntType.SCENERY, "climb-down") { player, _ -> + player.teleport(Location(2620, 9565, 0)) + return@on true + } + on(1729, IntType.SCENERY, "climb-up") { player, _ -> + player.teleport(Location(2620, 9496, 0)) + return@on true + } + on(2316, IntType.SCENERY, "climb-up") { player, _ -> + player.teleport(Location.create(2569, 9525, 0)) + return@on true + } + on(intArrayOf(2318, 2317), IntType.SCENERY, "climb-up", "climb-down") { player, target -> + if (player.skills.getLevel(Skills.AGILITY) < 67) { + player.dialogueInterpreter.sendDialogue("You need an Agility level of at least 67 in order to do this.") + return@on true + } + val loc = if (target.id == 2317) { Location(2615, 9503, 0) } else { Location(2617, 9572, 0) } + core.game.global.action.ClimbActionHandler.climb(player, if(target.id == 2317) { core.game.global.action.ClimbActionHandler.CLIMB_UP } else { core.game.global.action.ClimbActionHandler.CLIMB_DOWN }, loc) + player.sendMessage("You climb " + if(target.id == 2317) { "up" } else { "down" } + " the pile of rubble...") + player.skills.addExperience(Skills.AGILITY, 5.5, true) + return@on true + } + on(intArrayOf(35969, 2303), IntType.SCENERY, "walk-across") { player, target -> + handleBalancingLedge(player, target.asScenery()) + return@on true + } + on(377, IntType.SCENERY, "open") { player, target -> + if (!player.inventory.contains(Items.SINISTER_KEY_993, 1)) { + player.sendMessage("The chest is locked.") + } else { + if (player.getInventory().freeSlots() == 0) { + player.sendMessage("You don't have enough inventory space.") + return@on true + } + player.lock(1) + if(player.inventory.remove(Item(Items.SINISTER_KEY_993, 1))) { + player.sendMessages("You unlock the chest with your key...", "A foul gas seeps from the chest") + applyPoison (player, player, 2) + for(item in SINISTER_CHEST_HERBS) { + addItemOrDrop(player, item.id, item.amount) + } + SceneryBuilder.replace(target.asScenery(), target.asScenery().transform(target.id + 1), 5) + } + } + return@on true + } + on(378, IntType.SCENERY, "search") { player, _ -> + player.sendMessage("The chest is empty.") + return@on true + } + on(378, IntType.SCENERY, "shut") { player, _ -> + return@on true + } + + } + + /** + * Handles the balancing ledge. + * @param player the player. + * @param object the object. + */ + fun handleBalancingLedge(player: Player, scenery: Scenery) { + if (player.skills.getLevel(Skills.AGILITY) < 40) { + player.getDialogueInterpreter().sendDialogue("You need an Agility level of at least 40 in order to do this.") + return + } + val dir = Direction.getLogicalDirection(player.location, scenery.location) + val diff = if(player.location.y == 9512) { 0 } else { 1 } + var end = scenery.location + var xp = 0.0 + if (AgilityHandler.hasFailed(player, 40, 0.01)) { + player.lock(3) + GameWorld.Pulser.submit(object : Pulse(2, player) { + override public fun pulse(): Boolean { + AgilityHandler.fail(player, 1, Location(2572, 9570, 0), Animation.create(761 - diff), RandomFunction.random(1, 3), "You lost your balance!") + return true + } + }) + } else { + xp = 22.5 + end = scenery.location.transform(dir.getStepX() * 7, dir.getStepY() * 7, 0) + } + AgilityHandler.walk(player, -1, player.location, end, Animation.create(157 - diff), xp, null) + } + +} + +/** + * Handles the salarin twisted npc. + * @author Vexia + */ +@Initializable +public class SalarinTwistedNPC : AbstractNPC { + + /** + * The spell ids. + */ + val SPELL_IDS = intArrayOf( 1, 4, 6, 8 ) + + /** + * Constructs a new {@Code SalarinTwistedNPC} {@Code + * Object} + */ + public constructor(): super(-1, null) {} + + /** + * Constructs a new {@Code SalarinTwistedNPC} {@Code + * Object} + * @param id the id. + * @param location the location. + */ + public constructor(id: Int, location: Location) : super(id, location) { + super.setAggressive(true) + } + + override public fun construct(id: Int, location: Location, vararg objects: Any?): AbstractNPC { + return SalarinTwistedNPC(id, location) + } + + override fun checkImpact(state: BattleState) { + if (state.style != CombatStyle.MAGIC) { + state.neutralizeHits() + return + } + if (state.spell == null) { + state.neutralizeHits() + return + } + val spell = state.spell + for (id in SPELL_IDS) { + if (id == spell.spellId) { + state.estimatedHit = state.maximumHit + return + } + } + state.neutralizeHits() + } + + override public fun getIds(): IntArray { + return intArrayOf(205) + } + +} + +/** + * Handles the yanille agility dungeon. + * @author Vexia + */ +public class YanilleAgilityDungeon : MapZone("Yanille agility", true) { + override public fun configure() { + register(ZoneBorders(2544, 9481, 2631, 9587)) + } +} diff --git a/Server/src/main/content/region/karamja/brimhaven/dialogue/BrimhavenBartenderDialogue.java b/Server/src/main/content/region/karamja/brimhaven/dialogue/BrimhavenBartenderDialogue.java new file mode 100644 index 0000000..2316105 --- /dev/null +++ b/Server/src/main/content/region/karamja/brimhaven/dialogue/BrimhavenBartenderDialogue.java @@ -0,0 +1,140 @@ +package content.region.karamja.brimhaven.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.game.node.item.Item; + +/** + * Represents the dialogue plugin used for the brimhaven bartender. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class BrimhavenBartenderDialogue extends DialoguePlugin { + + /** + * Represents the grog item. + */ + private static final Item GROG = new Item(1915); + + /** + * Represents the rum item. + */ + private static final Item RUM = new Item(8940); + + /** + * Represents the coins item. + */ + private static final Item COINS = new Item(995, 3); + + /** + * Represents the amount of coins to buy a pin of rum. + */ + private static final Item RUM_COINS = new Item(995, 27); + + /** + * Constructs a new {@code BrimhavenBartenerDialogue.java} {@code Object}. + */ + public BrimhavenBartenderDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code BrimhavenBartenerDialogue.java} {@code Object}. + * @param player the player. + */ + public BrimhavenBartenderDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new BrimhavenBartenderDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Yohoho me hearty what would you like to drink?"); + stage = 99; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 99: + interpreter.sendOptions("Select an Option", "Nothing, thank you.", "A pint of Grog please.", "A bottle of rum please."); + stage = 0; + break; + case 0: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.FRIENDLY, "Nothing, thank you."); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HAPPY, "A pint of Grog please.."); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HAPPY, "A bottle of rum please."); + stage = 30; + break; + } + break; + case 10: + end(); + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "One grog coming right up, that'll be three coins."); + stage = 21; + break; + case 21: + if (!player.getInventory().containsItem(COINS)) { + interpreter.sendDialogues(player, null, "Sorry, I don't seem to have enough coins."); + stage = 22; + return true; + } + if (!player.getInventory().remove(COINS)) { + interpreter.sendDialogues(player, null, "Sorry, I don't seem to have enough coins."); + stage = 22; + return true; + } + if (player.getInventory().add(GROG)) { + player.getPacketDispatch().sendMessage("You buy a pint of Grog."); + end(); + } + break; + case 22: + end(); + break; + case 30: + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "That'll be 27 coins."); + stage = 31; + break; + case 31: + if (!player.getInventory().remove(RUM_COINS)) { + interpreter.sendDialogues(player, null, "Sorry, I don't seem to have enough coins."); + stage = 22; + return true; + } + if (player.getInventory().add(RUM)) { + end(); + player.getPacketDispatch().sendMessage("You buy a bottle of rum."); + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 735 }; + } +} diff --git a/Server/src/main/content/region/karamja/brimhaven/dialogue/BrimhavenPirateDialogue.java b/Server/src/main/content/region/karamja/brimhaven/dialogue/BrimhavenPirateDialogue.java new file mode 100644 index 0000000..0c1c3cd --- /dev/null +++ b/Server/src/main/content/region/karamja/brimhaven/dialogue/BrimhavenPirateDialogue.java @@ -0,0 +1,65 @@ +package content.region.karamja.brimhaven.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the brimhaven pirate dialogue. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class BrimhavenPirateDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code BrimhavenPirateDialogue} {@code Object}. + */ + public BrimhavenPirateDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code BrimhavenPirateDialogue} {@code Object}. + * @param player the player. + */ + public BrimhavenPirateDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new BrimhavenPirateDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello!"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Man overboard!"); + stage = 2; + break; + case 2: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 183, 6349, 6350, 6346, 6347, 6348, 799 }; + } +} diff --git a/Server/src/main/content/region/karamja/brimhaven/dialogue/CapnIzzyDialogue.kt b/Server/src/main/content/region/karamja/brimhaven/dialogue/CapnIzzyDialogue.kt new file mode 100644 index 0000000..c74885e --- /dev/null +++ b/Server/src/main/content/region/karamja/brimhaven/dialogue/CapnIzzyDialogue.kt @@ -0,0 +1,159 @@ +package content.region.karamja.brimhaven.dialogue + +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.global.Skillcape +import core.game.node.entity.npc.NPC +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class CapnIzzyDialogue(private val it: Int) : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (it) { + 0 -> when (stage) { + 0 -> playerl(FacialExpression.HAPPY, "Ahoy Cap'n!").also { stage++ } + 1 -> npcl(FacialExpression.HAPPY, "Ahoy there!").also { stage++ } + 2 -> npcl(NPCs.PARROT_4535, FacialExpression.ANGRY, "Avast ye scurvy swabs!").also { stage++ } + 3 -> playerl(FacialExpression.THINKING, "Huh?").also { stage++ } + 4 -> npcl(FacialExpression.HAPPY, "Don't mind me parrot, he's Cracked Jenny's Tea Cup!").also { stage++ } + + 5 -> { + if (Skillcape.isMaster(player!!, Skills.AGILITY)) { + options( + "What is this place?", + "What do I do in the arena?", + "I'd like to use the Agility Arena, please.", + "Is it true you sell the Skillcape of Agility?", + "See you later." + ).also { stage++ } + } else { + options( + "What is this place?", + "What do I do in the arena?", + "I'd like to use the Agility Arena, please.", + "Can you tell me a bit about the Skillcape of Agility, please?", + "See you later." + ).also { stage = 7 } + } + } + + 6 -> when (buttonID) { + 1 -> playerl(FacialExpression.NEUTRAL, "What is this place?").also { stage = 10 } + 2 -> playerl(FacialExpression.NEUTRAL, "What do I do in the arena?").also { stage = 20 } + 3 -> playerl(FacialExpression.NEUTRAL, "I'd like to use the Agility Arena, please.").also { stage = 30 } + 4 -> playerl(FacialExpression.HALF_ASKING, "May I buy a Skillcape of Agility, please?").also { stage = 40 } + 5 -> playerl(FacialExpression.NEUTRAL, "See you later.").also { stage = END_DIALOGUE } + } + + 7 -> when (buttonID) { + 1 -> playerl(FacialExpression.NEUTRAL, "What is this place?").also { stage = 10 } + 2 -> playerl(FacialExpression.NEUTRAL, "What do I do in the arena?").also { stage = 20 } + 3 -> playerl(FacialExpression.NEUTRAL, "I'd like to use the Agility Arena, please.").also { stage = 30 } + 4 -> playerl(FacialExpression.NEUTRAL, "Can you tell me a bit about the Skillcape of Agility, please?").also { stage = 50 } + 5 -> playerl(FacialExpression.NEUTRAL, "See you later.").also { stage = END_DIALOGUE } + } + + 10 -> npcl(FacialExpression.NEUTRAL, "This, me hearty, is the entrance to the Brimhaven, Agility Arena!").also { stage++ } + 11 -> npcl(FacialExpression.NEUTRAL, "I were diggin for buried treasure when I found it! Amazed I was! It was a sight to behold!").also { stage++ } + 12 -> npcl(FacialExpression.NEUTRAL, "It were the biggest thing I'd ever seen! it must've been at least a league from side to side!").also { stage++ } + 13 -> npcl(FacialExpression.NEUTRAL, "It made me list, I were that excited!").also { stage++ } + 14 -> npcl(FacialExpression.NEUTRAL, "I'd found a huge cave with all these platforms. I reckon it be an ancient civilisation that made it. I had " + + "to be mighty careful as there was these traps everywhere! Dangerous it was!").also { stage++ } + + 15 -> npcl(FacialExpression.NEUTRAL, "Entrance is only 200 coins!").also { stage = 5 } + 20 -> npcl(FacialExpression.NEUTRAL, "Well, me hearty, it's simple. Ye can cross between two platforms by using the traps or obstacles " + + "strung across 'em. Try and make your way to the pillar that is indicated by the flashing arrow.").also { stage++ } + 21 -> npcl(FacialExpression.NEUTRAL, "Ye receive tickets for tagging more than one pillar in a row. So ye won't get a ticket from the " + + "first pillar but ye will for every platform ye tag in a row after that.").also { stage++ } + 22 -> npcl(FacialExpression.NEUTRAL, "If ye miss a platform ye will miss out on the next ticket so try and get every platform you can! " + + "When ye be done, take the tickets to Jackie over there and she'll exchange them for more stuff!").also { stage++ } + 23 -> playerl(FacialExpression.NEUTRAL, "Thanks!").also { stage = 5 } + 30 -> npcl(FacialExpression.NEUTRAL, "Aye, entrance be 200 coins.").also { stage++ } + 31 -> npcl(NPCs.PARROT_4535, FacialExpression.ANGRY, "Pieces of eight!").also { stage++ } + 32 -> npcl(FacialExpression.AMAZED, "A word of warning me hearty! There are dangerous traps down there!").also { stage++ } + 33 -> options("Ok, here's 200 coins.", "Never mind.").also { stage++ } + 34 -> when (buttonID) { + 1 -> playerl(FacialExpression.NEUTRAL, "Ok, here's 200 coins.").also { stage++ } + 2 -> playerl(FacialExpression.NEUTRAL, "Never mind.").also { stage = END_DIALOGUE } + } + + 35 -> { + if (!getAttribute(player!!, "capn_izzy", false)) { + if (inInventory(player!!, Items.COINS_995, 200) && removeItem(player!!, Item(Items.COINS_995, 200))) { + sendItemDialogue(player!!, Items.COINS_6964, "You give Cap'n Izzy 200 coins.").also { stage++ } + npcl(FacialExpression.HAPPY, "May the wind be in ye sails!").also { stage = END_DIALOGUE } + sendMessage(player!!, "You give Cap'n Izzy 200 coins.") + setAttribute(player!!, "/save:capn_izzy", true) + } else { + end() + sendMessage(player!!, "You don't have the 200 coin entrance fee.") + } + } else { + npcl(FacialExpression.NEUTRAL, "Avast there, ye've already paid!").also { stage = END_DIALOGUE } + } + } + + 40 -> npcl(FacialExpression.NEUTRAL, "Most certainly, I think it'll really suit you. All that remains to be done is pay me 99000 gold!").also { stage++ } + 41 -> options("I'm afraid I can't afford that.", "Certainly, here you go.").also { stage++ } + 42 -> when (buttonID) { + 1 -> playerl(FacialExpression.NEUTRAL, "I'm afraid I can't afford that.").also { stage++ } + 2 -> playerl(FacialExpression.HAPPY, "Certainly, here you go.").also { stage = 44 } + } + + 43 -> npcl(FacialExpression.NEUTRAL, "So sad, too bad. Go and pickpocket some wealthy people and come back here once you're richer.").also { stage = END_DIALOGUE } + 44 -> { + when { + (!inInventory(player!!, Items.COINS_995, 99000)) -> { + playerl(FacialExpression.NEUTRAL, "But, unfortunately, I don't have enough money with me.").also { stage = 45 } + } + + (freeSlots(player!!)) < 2 -> { + npcl(FacialExpression.NEUTRAL, "Unfortunately all Skillcapes are only available with a free hood, it's part of a skill promotion deal; " + + "buy one get one free, you know. So you'll need to free up some inventory space before I can sell you one.").also { stage = END_DIALOGUE } + } + + else -> { + Skillcape.purchase(player!!, Skills.AGILITY) + npcl(FacialExpression.HAPPY, "Excellent! That cape really does suit you.").also { stage = END_DIALOGUE } + } + } + } + + 45 -> npcl(FacialExpression.NEUTRAL, "Well, come back and see me when you do.").also { stage = END_DIALOGUE } + // The below text was too long when using npcl's automatic line splitting. + 50 -> sendNormalDialogue( + NPC(NPCs.CAPN_IZZY_NO_BEARD_437), + FacialExpression.NEUTRAL, + "Aye, to be sure! The Skillcape of Agility be the symbol", + "of the master of dexterity! One who wears it can climb", + "like a cat, run like the wind and jump like...err, well", + "jump like a jumping thing!" + ).also { stage++ } + 51 -> npcl(FacialExpression.NEUTRAL, "Now, be there anything else ye'd like to know?").also { stage = 5 } + } + + 1 -> when (stage) { + 0 -> npcl(NPCs.PARROT_4535, FacialExpression.ANGRY, "Clap him in irons!").also { stage++ } + 1 -> npcl(NPCs.CAPN_IZZY_NO_BEARD_437, FacialExpression.NEUTRAL, "Ahoy there! Pay up first!").also { stage = END_DIALOGUE } + } + + 2 -> { + if (!getAttribute(player!!, "capn_izzy", false)) { + if (inInventory(player!!, Items.COINS_995, 200) && removeItem(player!!, Item(Items.COINS_995, 200))) { + sendItemDialogue(player!!, Items.COINS_6964, "You give Cap'n Izzy the 200 coin entrance fee.").also { stage = END_DIALOGUE } + sendMessage(player!!, "You give Cap'n Izzy the 200 coin entrance fee.") + setAttribute(player!!, "/save:capn_izzy", true) + } else { + sendMessage(player!!, "You don't have the 200 coin entrance fee.") + } + } else { + npcl(NPCs.CAPN_IZZY_NO_BEARD_437, FacialExpression.NEUTRAL, "Avast there, ye've already paid!").also { stage = END_DIALOGUE } + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/karamja/brimhaven/dialogue/DavonDialogue.java b/Server/src/main/content/region/karamja/brimhaven/dialogue/DavonDialogue.java new file mode 100644 index 0000000..e202dd5 --- /dev/null +++ b/Server/src/main/content/region/karamja/brimhaven/dialogue/DavonDialogue.java @@ -0,0 +1,96 @@ +package content.region.karamja.brimhaven.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the dialogue plugin used for the davon npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class DavonDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code DavonDialogue} {@code Object}. + */ + public DavonDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code DavonDialogue} {@code Object}. + * @param player the player. + */ + public DavonDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new DavonDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.SUSPICIOUS, "Pssst! Come here if you want to do some amulet", "trading."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "What are you selling?", "What do you mean pssst?", "Why don't you ever restock some types of amulets?"); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HAPPY, "What are you selling?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.SUSPICIOUS, "What do you mean pssst?"); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_ASKING, "Why don't you ever restock some types of amulets?"); + stage = 30; + break; + } + break; + case 10: + end(); + npc.openShop(player); + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.SUSPICIOUS, "Errr, I was...I was clearing my throat."); + stage = 21; + break; + case 21: + end(); + break; + case 30: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Some of these amulets are very hard to get. I have to", "wait until an adventurer supplies me."); + stage = 31; + break; + case 31: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 588 }; + } +} diff --git a/Server/src/main/content/region/karamja/brimhaven/dialogue/LubufuDialogue.java b/Server/src/main/content/region/karamja/brimhaven/dialogue/LubufuDialogue.java new file mode 100644 index 0000000..0ad3444 --- /dev/null +++ b/Server/src/main/content/region/karamja/brimhaven/dialogue/LubufuDialogue.java @@ -0,0 +1,107 @@ +package content.region.karamja.brimhaven.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the lubufu dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class LubufuDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code LubufuDialogue} {@code Object}. + */ + public LubufuDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code LubufuDialogue} {@code Object}. + * @param player the player. + */ + public LubufuDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new LubufuDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Watch where you're going, young whippersnapper!"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "I wasn't going anywhere...", "What's a whippersnapper?", "Who are you?"); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I wasn't going anywhere..."); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What's a whippersnapper?"); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Who are you?"); + stage = 30; + break; + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Well then go away from here!"); + stage = 11; + break; + case 11: + end(); + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "It's a whip. Which snaps. Like me. Now leave!"); + stage = 21; + break; + case 21: + end(); + break; + case 30: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I am Lubufu - the only fisherman who knows the secret", "of the Karambwan!"); + stage = 31; + break; + case 31: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What's a Karambwan?"); + stage = 32; + break; + case 32: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "What a foolish question! Now leave!"); + stage = 33; + break; + case 33: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 1171 }; + } +} diff --git a/Server/src/main/content/region/karamja/brimhaven/dialogue/PirateJackieDialogue.kt b/Server/src/main/content/region/karamja/brimhaven/dialogue/PirateJackieDialogue.kt new file mode 100644 index 0000000..e9ecfd2 --- /dev/null +++ b/Server/src/main/content/region/karamja/brimhaven/dialogue/PirateJackieDialogue.kt @@ -0,0 +1,120 @@ +package content.region.karamja.brimhaven.dialogue + +import core.api.openInterface +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.link.diary.AchievementDiary +import core.game.node.entity.player.link.diary.DiaryType +import core.tools.END_DIALOGUE +import org.rs09.consts.Components +import org.rs09.consts.NPCs + +class PirateJackieDialogue : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> playerl(FacialExpression.NEUTRAL, "Ahoy there!").also { stage++ } + 1 -> npcl(FacialExpression.NEUTRAL, "Ahoy!").also { stage++ } + 2 -> options( + "What is this place?", + "What do you do?", + "I'd like to trade in my tickets, please.", + "I have a question about my Achievement Diary.", + "See you later." + ).also { stage++ } + + 3 -> when (buttonID) { + 1 -> playerl(FacialExpression.NEUTRAL, "What is this place?").also { stage = 10 } + 2 -> playerl(FacialExpression.NEUTRAL, "What do you do?").also { stage = 20 } + 3 -> playerl(FacialExpression.NEUTRAL, "I'd like to trade in my tickets, please.").also { stage = 30 } + 4 -> playerl(FacialExpression.NEUTRAL, "I have a question about my Achievement Diary.").also { + stage = 40 + } + + 5 -> playerl(FacialExpression.NEUTRAL, "See you later.").also { stage = END_DIALOGUE } + } + + 10 -> npcl(FacialExpression.NEUTRAL, "Welcome to the Brimhaven Agility Arena!").also { stage++ } + 11 -> npcl( + FacialExpression.NEUTRAL, + "If ye want to know more talk to Cap'n Izzy, he found it!" + ).also { stage = END_DIALOGUE } + + 20 -> npcl( + FacialExpression.NEUTRAL, + "I be the Jack o' tickets. I exchange the tickets ye collect in the Agility Arena for " + + "more stuff. Ye can obtain more agility experience or some items ye won't find anywhere else!" + ).also { stage++ } + + 21 -> playerl(FacialExpression.NEUTRAL, "Sounds good!").also { stage = END_DIALOGUE } + 30 -> { + npcl(FacialExpression.NEUTRAL, "Aye, ye be on the right track.").also { stage = END_DIALOGUE } + end() + openInterface(player!!, Components.AGILITYARENA_TRADE_6) + } + + 40 -> when { + AchievementDiary.canClaimLevelRewards(player!!, DiaryType.KARAMJA, 0) -> + playerl(FacialExpression.NEUTRAL, "I've done all the easy tasks in my Karamja Achievement Diary.").also { stage = 410 } + + AchievementDiary.canReplaceReward(player, DiaryType.KARAMJA, 0) -> + playerl(FacialExpression.NEUTRAL, "I've seemed to have lost my gloves..").also { stage = 420 } + + else -> options( + "What is the Achievement Diary?", + "What are the rewards?", + "How do I claim the rewards?", + "See you later." + ).also { stage++ } + } + + 41 -> when (buttonID) { + 1 -> playerl(FacialExpression.NEUTRAL, "What is the Achievement Diary?").also { stage = 430 } + 2 -> playerl(FacialExpression.NEUTRAL, "What are the rewards?").also { stage = 440 } + 3 -> playerl(FacialExpression.NEUTRAL, "How do I claim the rewards?").also { stage = 450 } + 4 -> playerl(FacialExpression.NEUTRAL, "See you later.").also { stage = END_DIALOGUE } + } + + 410 -> npcl(FacialExpression.NEUTRAL, "Arr, ye have that, I see yer list. I s'pose ye'll be wanting yer reward then!").also { stage++ } + + 411 -> playerl(FacialExpression.NEUTRAL, "Yes please.").also { stage++ } + 412 -> { + AchievementDiary.flagRewarded(player, DiaryType.KARAMJA, 0) + npcl(FacialExpression.NEUTRAL, + "These 'ere Karamja gloves be a symbol of yer explorin' on the island. All the merchants will recognise" + + " 'em when yer wear 'em and mabe give ye a little discount. I'll ave a word with some of the seafarin' folk who ").also { stage++ } + } + + 413 -> npcl(FacialExpression.NEUTRAL, "sail to Port Sarim and Ardougne, so they'll take ye on board half price if year wearin' them. Arrr, take this" + + " lamp I found washed ashore too.").also { stage++ } + + 414 -> playerl(FacialExpression.NEUTRAL, "Wow, thanks!").also { stage = 40 } + 420 -> { + AchievementDiary.grantReplacement(player, DiaryType.KARAMJA, 0) + npcl(FacialExpression.NEUTRAL, "Arr matey, have another pair. Ye better be more careful this time.").also { stage = 40 } + } + + 430 -> npcl( + FacialExpression.NEUTRAL, + "It's a diary that helps you keep track of particular achievements. Here on Karamja it can help " + + "you discover some quite useful things. Eventually, with enough exploration, the people of Karamja will reward you.").also { stage++ } + + 431 -> npcl(FacialExpression.NEUTRAL, "You can see what tasks you have listed by clicking on the green button in the Quest List.").also { stage = 40 } + // The below text was too long when using npcl's automatic line splitting. + 440 -> sendNormalDialogue( + NPC(NPCs.PIRATE_JACKIE_THE_FRUIT_1055), + FacialExpression.NEUTRAL, + "Well, there's three different pairs of Karamja gloves,", + "which match up with the three levels of difficulty. Each", + "has the same rewards as the previous level, and an", + "additional one too... but I won't spoil your surprise." + ).also { stage++ } + + 441 -> npcl(FacialExpression.NEUTRAL, + "Rest assured, the people of Karamja are happy to see you visiting the island.").also { stage = 40 } + + 450 -> npcl(FacialExpression.NEUTRAL, "To claim the different Karamja gloves, speak to Kaleb Paramaya in Shilo Village, one of the jungle " + + "foresters near the Kharazi Jungle, or me.").also { stage = 40 } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/karamja/brimhaven/dialogue/SandyDialogue.java b/Server/src/main/content/region/karamja/brimhaven/dialogue/SandyDialogue.java new file mode 100644 index 0000000..736424e --- /dev/null +++ b/Server/src/main/content/region/karamja/brimhaven/dialogue/SandyDialogue.java @@ -0,0 +1,48 @@ +package content.region.karamja.brimhaven.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Handles the SandyDialogue dialogue. + * @author 'Vexia + */ +@Initializable +public class SandyDialogue extends DialoguePlugin { + + public SandyDialogue() { + + } + + public SandyDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new SandyDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Nice day for sand isn't it?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + end(); + return true; + } + + @Override + public int[] getIds() { + return new int[] { 3110 }; + } +} diff --git a/Server/src/main/content/region/karamja/brimhaven/dialogue/SanibochDialogue.java b/Server/src/main/content/region/karamja/brimhaven/dialogue/SanibochDialogue.java new file mode 100644 index 0000000..0ed5006 --- /dev/null +++ b/Server/src/main/content/region/karamja/brimhaven/dialogue/SanibochDialogue.java @@ -0,0 +1,184 @@ +package content.region.karamja.brimhaven.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.game.node.item.Item; +import org.rs09.consts.Items; + +/** + * Handles the SanibochDialogue dialogue. + * @author Emperor + * @author 'Vexia + */ +@Initializable +public class SanibochDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code SanibochDialogue} {@code Object}. + */ + public SanibochDialogue() { + + } + + /** + * Constructs a new {@code SanibochDialogue} {@code Object}. + * @param player The player. + */ + public SanibochDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new SanibochDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + stage = args.length > 1 ? (Integer) args[1] : 0; + if (stage == 0) { + interpreter.sendDialogues(1595, FacialExpression.HALF_GUILTY, "Good day to you bwana."); + } else { + handle(0, 0); + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "Can I go through that door please?", "Where does this strange entrance lead?", "Good day to you too.", "I'm impressed, that tree is growing on that shed."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + player("Can I go through that door please?"); + stage = 10; + break; + case 2: + player("Where does this strange entrance lead?"); + stage = 20; + break; + case 3: + player("Good day to you too."); + stage = -1; + break; + case 4: + player("I'm impressed, that tree is growing on that shed."); + stage = 40; + break; + } + break; + case 10: + if (player.getAttribute("saniboch:paid", false)) { + npc("Most certainly, you have already given me lots of nice", "coins."); + stage = -1; + break; + } + npc("Most certainly, but I must charge you the sum of 875", "coins first."); + stage = 11; + break; + case 11: + if (!player.getInventory().contains(995, 875)) { + player("I don't have the money on me at the moment."); + stage = -1; + break; + } + options("Ok, here's 875 coins.", "Never mind.", "Why is it worth the entry cost?"); + stage = 12; + break; + case 12: + switch (buttonId) { + case 1: + player("Ok, here's 875 coins."); + stage = 32; + break; + case 2: + player("Never mind."); + stage = -1; + break; + case 3: + player("Why is it worth the entry cost?"); + stage = 30; + break; + } + break; + case 20: + npc("To a huge fearsome dungeon, populated by giants and", "strange dogs. Adventurers come from all around to", "explore its depths."); + stage = 21; + break; + case 21: + npc("I know not what lies deeper in myself, for my skills in", "agility and woodcutting are inadequate."); + stage = -1; + break; + case 30: + npc("It leads to a huge fearsome dungeon, populated by", "giants and strange dogs. Adventurers come from all", "around to explore its depths."); + stage = 31; + break; + case 31: + npc("I know not what lies deeper in myself, for my skills in", "agility and woodcutting are inadequate, but I hear tell", "of even greater dangers deeper in."); + stage = -1; + break; + case 32: + Item item = new Item(995, 875); + if (player.getInventory().remove(item)) { + player.getPacketDispatch().sendMessage("You pay Saniboch 875 coins."); + player.setAttribute("saniboch:paid", true); + interpreter.sendItemMessage(Items.COINS_6964, "You give Saniboch 875 coins."); + stage = 33; + break; + } + end(); + break; + case 33: + npc("Many thanks. You may now pass the door. May your", "death be a glorious one!"); + stage = -1; + break; + case 35: + if (player.getAttribute("saniboch:paid", false)) { + npc("You have already given me lots of nice coins, you may", "go in."); + stage = -1; + break; + } + if (!player.getInventory().contains(995, 875)) { + player("I don't have the money on me at the moment."); + stage = 36; + break; + } + stage = 12; + handle(interfaceId, 1); + break; + case 36: + npc("Well this is a dungeon for the more wealthy discerning", "adventurer, be gone with your riff raff."); + stage = 37; + break; + case 37: + player("But you don't even have clothes, how can you seriously", "call anyone riff raff."); + stage = 38; + break; + case 38: + npc("Hummph."); + stage = -1; + break; + case 40: + npc("My employer tells me it is an uncommon sort of tree", "called the Fyburglars tree."); + stage = -1; + break; + case -1: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 1595 }; + } +} diff --git a/Server/src/main/content/region/karamja/brimhaven/handlers/BrimhavenDungeonListeners.kt b/Server/src/main/content/region/karamja/brimhaven/handlers/BrimhavenDungeonListeners.kt new file mode 100644 index 0000000..2e39db2 --- /dev/null +++ b/Server/src/main/content/region/karamja/brimhaven/handlers/BrimhavenDungeonListeners.kt @@ -0,0 +1,94 @@ +package content.region.karamja.brimhaven.handlers + +import content.global.skill.agility.AgilityHandler +import core.api.* +import core.game.dialogue.FacialExpression +import core.game.global.action.ClimbActionHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.link.diary.DiaryType +import core.game.node.entity.skill.Skills +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +class BrimhavenDungeonListeners : InteractionListener { + + val ENTRANCE = Scenery.DUNGEON_ENTRANCE_5083 + val EXIT = Scenery.EXIT_5084 + val SANIBOCH = NPCs.SANIBOCH_1595 + val VINES = intArrayOf(5103,5104,5105,5106,5107) + val STEPPING_STONES = intArrayOf(5110,5111) + val STAIRS = intArrayOf(5094,5096,5097,5098) + val LOGS = intArrayOf(5088,5090) + + override fun defineListeners() { + on(ENTRANCE, IntType.SCENERY, "enter"){ player, node -> + if (getAttribute(player, "saniboch:paid", false) || player.achievementDiaryManager.getDiary(DiaryType.KARAMJA).isComplete()) { + ClimbActionHandler.climb(player, ClimbActionHandler.CLIMB_UP, location(2713, 9564, 0)) + removeAttribute(player, "saniboch:paid") + } else { + sendNPCDialogue(player, SANIBOCH, "You can't go in there without paying!", FacialExpression.NEUTRAL) + } + return@on true + } + + on(EXIT, IntType.SCENERY, "leave"){ player, _ -> + player.properties.teleportLocation = Location.create(2745, 3152, 0) + return@on true + } + + on(STAIRS, IntType.SCENERY, "walk-up","walk-down"){ player, node -> + BrimhavenUtils.handleStairs(node.asScenery(), player) + return@on true + } + + on(STEPPING_STONES, IntType.SCENERY, "jump-from"){ player, node -> + BrimhavenUtils.handleSteppingStones(player, node.asScenery()) + return@on true + } + + on(VINES, IntType.SCENERY, "chop-down"){ player, node -> + BrimhavenUtils.handleVines(player, node.asScenery()) + return@on true + } + + on(SANIBOCH, IntType.NPC, "pay"){ player, node -> + player.dialogueInterpreter.open(SANIBOCH,node.asNpc(),10) + return@on true + } + + on(LOGS, IntType.SCENERY, "walk-across"){ player, node -> + + if (player.skills.getLevel(Skills.AGILITY) < 30) { + player.packetDispatch.sendMessage("You need an agility level of 30 to cross this.") + return@on true + } + + if(node.id == 5088){ + AgilityHandler.walk( + player, + -1, + player.location, + Location.create(2687, 9506, 0), + Animation.create(155), + 0.0, + null + ) + } else { + AgilityHandler.walk( + player, + -1, + player.location, + Location.create(2682, 9506, 0), + Animation.create(155), + 0.0, + null + ) + } + + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/karamja/brimhaven/handlers/BrimhavenListeners.kt b/Server/src/main/content/region/karamja/brimhaven/handlers/BrimhavenListeners.kt new file mode 100644 index 0000000..e2b43bc --- /dev/null +++ b/Server/src/main/content/region/karamja/brimhaven/handlers/BrimhavenListeners.kt @@ -0,0 +1,106 @@ +package content.region.karamja.brimhaven.handlers + +import content.region.karamja.brimhaven.dialogue.CapnIzzyDialogue +import content.region.karamja.brimhaven.dialogue.PirateJackieDialogue +import core.api.* +import core.game.dialogue.FacialExpression +import core.game.global.action.ClimbActionHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.world.repository.Repository +import org.rs09.consts.Components +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +class BrimhavenListeners : InteractionListener { + companion object { + /** + * Represents the ladder that exits the Agility Arena. + */ + private const val AGILITY_ARENA_EXIT_LADDER = Scenery.LADDER_3618 + + /** + * Represents the ladder that enters the Agility Arena. + */ + private const val AGILITY_ARENA_ENTRANCE_LADDER = Scenery.LADDER_3617 + + /** + * Represents the area inside Brimhaven Agility Arena. + */ + private val AGILITY_ARENA = location(2805, 9589, 3) + + /** + * Represents the area within the hut outside the Brimhaven Agility Arena. + */ + private val AGILITY_ARENA_HUT = location(2809, 3193, 0) + + /** + * Represents the agility ticket exchange interface/component. + */ + private const val TICKET_EXCHANGE_IFACE = Components.AGILITYARENA_TRADE_6 + + /** + * Represents the back door of the Shrimp and Parrot restaurant used in the Heroes' Quest. + */ + private const val RESTAURANT_REAR_DOOR = Scenery.DOOR_1591 + + /** + * Represents Lubufu's karambwan fishing spot unlocked in Tai Bwo Wannai Trio. + */ + private const val KARAMBWAN_FISHING_SPOT = NPCs.FISHING_SPOT_1178 + } + + override fun defineListeners() { + on(AGILITY_ARENA_EXIT_LADDER, IntType.SCENERY, "climb-up") { player, _ -> + ClimbActionHandler.climb(player, ClimbActionHandler.CLIMB_UP, AGILITY_ARENA_HUT) + return@on true + } + + on(AGILITY_ARENA_ENTRANCE_LADDER, IntType.SCENERY, "climb-down") { player, _ -> + if (!getAttribute(player, "capn_izzy", false)) { + openDialogue(player, CapnIzzyDialogue(1)) + return@on true + } else { + ClimbActionHandler.climb(player, ClimbActionHandler.CLIMB_DOWN, AGILITY_ARENA) + removeAttribute(player, "capn_izzy") + } + return@on true + } + + on(NPCs.CAPN_IZZY_NO_BEARD_437, IntType.NPC, "talk-to") { player, node -> + openDialogue(player, CapnIzzyDialogue(0), node) + return@on true + } + + on(NPCs.CAPN_IZZY_NO_BEARD_437, IntType.NPC, "pay") { player, node -> + openDialogue(player, CapnIzzyDialogue(2), node) + return@on true + } + + on(NPCs.PIRATE_JACKIE_THE_FRUIT_1055, IntType.NPC, "talk-to") { player, node -> + openDialogue(player, PirateJackieDialogue(), node) + return@on true + } + + on(NPCs.PIRATE_JACKIE_THE_FRUIT_1055, IntType.NPC, "trade") { player, _ -> + openInterface(player, TICKET_EXCHANGE_IFACE) + return@on true + } + + on(RESTAURANT_REAR_DOOR, IntType.SCENERY, "open") { player, _ -> + sendMessage(player, "You try and open the door...") + sendMessage(player, "The door is locked tight, I can't open it.") + return@on true + } + + on(KARAMBWAN_FISHING_SPOT, IntType.NPC, "fish") { player, _ -> + sendNPCDialogue( + player, + NPCs.LUBUFU_1171, + "Keep off my fishing spot, whippersnapper!", + FacialExpression.FURIOUS + ) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/karamja/brimhaven/handlers/BrimhavenUtils.kt b/Server/src/main/content/region/karamja/brimhaven/handlers/BrimhavenUtils.kt new file mode 100644 index 0000000..2aaefa2 --- /dev/null +++ b/Server/src/main/content/region/karamja/brimhaven/handlers/BrimhavenUtils.kt @@ -0,0 +1,107 @@ +package content.region.karamja.brimhaven.handlers + +import core.api.* +import core.game.node.scenery.Scenery +import core.game.node.scenery.SceneryBuilder +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.diary.DiaryType +import core.game.node.entity.skill.Skills +import content.global.skill.agility.AgilityHandler +import content.data.skill.SkillingTool +import core.game.system.task.Pulse +import core.game.world.map.Direction +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.game.world.GameWorld + +object BrimhavenUtils { + fun getVineDestination(player: Player, node: Scenery): Location { + if (node.rotation % 2 != 0) { + return if (player.location.x > node.location.x) { + node.location.transform(-1, 0, 0) + } else node.location.transform(1, 0, 0) + } + return if (player.location.y > node.location.y) { + node.location.transform(0, -1, 0) + } else node.location.transform(0, 1, 0) + } + + fun handleStairs(node: Scenery, player: Player){ + when(node.id){ + 5094 -> core.game.global.action.ClimbActionHandler.climb(player, null, Location.create(2643, 9594, 2)) + 5096 -> core.game.global.action.ClimbActionHandler.climb(player, null, Location.create(2649, 9591, 0)) + 5097 -> { + // Climb the stairs within Brimhaven Dungeon + player.achievementDiaryManager.finishTask(player, DiaryType.KARAMJA, 1, 16) + core.game.global.action.ClimbActionHandler.climb(player, null, Location.create(2636, 9510, 2)) + } + 5098 -> core.game.global.action.ClimbActionHandler.climb(player, null, Location.create(2636, 9517, 0)) + } + } + + fun handleSteppingStones(player: Player, node: Scenery){ + if (player.skills.getLevel(Skills.AGILITY) < 12) { + player.packetDispatch.sendMessage("You need an agility level of 12 to cross this.") + return + } + player.lock(12) + val dir = AgilityHandler.forceWalk(player, -1, player.location, node.location, Animation.create(769), 10, 0.0, null).direction + val loc = player.location + + registerLogoutListener(player, "steppingstone"){p -> + teleport(p, loc) + } + + GameWorld.Pulser.submit(object : Pulse(3, player) { + var stage = if (dir == Direction.NORTH) -1 else 0 + var direction = dir + override fun pulse(): Boolean { + val l = player.location + when (stage++) { + 1 -> direction = Direction.get(direction.toInteger() + 1 and 3) + 3 -> direction = Direction.get(direction.toInteger() - 1 and 3) + 5 -> if (direction == Direction.NORTH) { + return true + } + } + if (stage == 6) { + player.achievementDiaryManager.finishTask(player, DiaryType.KARAMJA, 1, 15) + } + AgilityHandler.forceWalk(player, -1, l, l.transform(direction), Animation.create(769), 10, 0.0, null) + return stage == 6 + } + + override fun stop() { + clearLogoutListener(player, "steppingstone") + super.stop() + } + }) + } + + fun handleVines(player: Player, node: Scenery){ + val level: Int = 10 + (node.id - 5103) * 6 + if (player.skills.getLevel(Skills.WOODCUTTING) < level) { + player.packetDispatch.sendMessage("You need a woodcutting level of $level to chop down this vine.") + return + } + val tool = SkillingTool.getHatchet(player) + if (tool == null) { + player.packetDispatch.sendMessage("You don't have an axe to cut these vines.") + return + } + player.animate(tool.animation) + player.pulseManager.run(object : Pulse(3, player) { + override fun pulse(): Boolean { + if (SceneryBuilder.replace(node.asScenery(), node.asScenery().transform(0), 2)) { + val destination = getVineDestination(player,node.asScenery()) + player.lock(3) + player.walkingQueue.reset() + // Chop the vines to gain deeper access to Brimhaven Dungeon + player.achievementDiaryManager.finishTask(player, DiaryType.KARAMJA, 1, 14) + player.walkingQueue.addPath(destination.x, destination.y, true) + } + return true + } + }) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/karamja/brimhaven/handlers/SanibochPlugin.java b/Server/src/main/content/region/karamja/brimhaven/handlers/SanibochPlugin.java new file mode 100644 index 0000000..2c2e049 --- /dev/null +++ b/Server/src/main/content/region/karamja/brimhaven/handlers/SanibochPlugin.java @@ -0,0 +1,29 @@ +package content.region.karamja.brimhaven.handlers; + +import core.cache.def.impl.NPCDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Handles Saniboch's options. + * @author Emperor + */ +@Initializable +public final class SanibochPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + NPCDefinition.forId(1595).getHandlers().put("option:pay", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + player.getDialogueInterpreter().open(1595, null, 35); + return false; + } + +} diff --git a/Server/src/main/content/region/karamja/dialogue/CaptainShanksDialogue.java b/Server/src/main/content/region/karamja/dialogue/CaptainShanksDialogue.java new file mode 100644 index 0000000..ddf3f18 --- /dev/null +++ b/Server/src/main/content/region/karamja/dialogue/CaptainShanksDialogue.java @@ -0,0 +1,170 @@ +package content.region.karamja.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.plugin.Initializable; +import org.rs09.consts.Items; +import content.global.travel.ship.Ships; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.tools.RandomFunction; + +/** + * Represents the captain barnaby dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class CaptainShanksDialogue extends DialoguePlugin { + + private Item coins; + private static final Item TICKET = new Item(Items.SHIP_TICKET_621); + + /** + * Constructs a new {@code CaptainShanksDialogue} {@code Object}. + */ + public CaptainShanksDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code CaptainShanksDialogue} {@code Object}. + * @param player the player. + */ + public CaptainShanksDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new CaptainShanksDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + npc("Hello there shipmate! I sail to Khazard Port and", "to Port Sarim. Where are you bound?"); + if (!player.getInventory().containsAtLeastOneItem(TICKET)) { + stage = -1; + } else { + stage = 0; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 999: + end(); + break; + case -1: + coins = new Item(995, RandomFunction.random(20, 50)); + npc("I see you don't have a ticket for the ship, my", "colleague normally only sells them in Shilo village.", "But I could sell you one for a small additional", "charge. Shall we say " + coins.getAmount() + " gold pieces?"); + stage = 3; + break; + case 0: + options("Khazard Port please.", "Port Sarim please.", "Nowhere just at the moment thanks."); + stage++; + break; + case 1: + switch(buttonId) { + case 1: + player("Khazard Port please."); + if (!player.getInventory().containsItem(TICKET)) { + stage = -1; + } else { + stage = 10; + } + break; + case 2: + player("Port Sarim please."); + if (!player.getInventory().containsItem(TICKET)) { + stage = -1; + } else { + stage = 20; + } + break; + case 3: + player("Nowhere just at the moment thanks."); + stage++; + break; + } + break; + case 2: + npc("Very well then me old shipmate, Just let me know", "if you change your mind."); + stage = 999; + break; + case 3: + interpreter.sendOptions("Buy a ticket for " + coins.getAmount() + " gold pieces.", "Yes, I'll buy a ticket for the ship.", "No thanks, not just at the moment."); + stage++; + break; + case 4: + switch(buttonId) { + case 1: + player("Yes, I'll buy a ticket for the ship."); + stage = 6; + break; + case 2: + player("No thanks, not just at the moment."); + stage++; + break; + } + break; + case 5: + npc("Very well me old shipmate, come back if you change", "your mind now."); + stage = 999; + break; + case 6: + if (!player.getInventory().containsItem(coins)) { + npc("Sorry me old ship mate, but you seem to be", "financially challenged at the moment. Come back", "when your coffers are full!"); + stage = 999; + } else if (!player.getInventory().hasSpaceFor(new Item(Items.SHIP_TICKET_621))) { + npc("Sorry me old ship mate, it looks like you haven't", "got enough space for a ticket. Come back when", "you've got rid of some of that junk."); + stage = 999; + } else { + npc("It's a good deal and no mistake. Here you go me old", "shipmate, here's your ticket."); + player.getInventory().remove(coins); + player.getInventory().add(new Item(Items.SHIP_TICKET_621)); + stage++; + } + break; + case 7: + npc("Ok, now you have your ticket, do you want to sail", "anywhere?"); + stage++; + break; + case 8: + interpreter.sendOptions("Captain Shanks asks, 'Do you want to sail anywhere?'", "Khazard Port please.", "Port Sarim please.", "Nowhere just at the moment thanks."); + stage = 1; + break; + case 10: + npc("Very well then me old shipmate, I'll just take your ticket and then we'll set sail."); + stage = 11; + break; + case 11: + end(); + if (player.getInventory().remove(TICKET)) { + Ships.sail(player, Ships.CAIRN_ISLAND_TO_PORT_KHAZARD); + } + break; + case 20: + npc("Very well then me old shipmate, I'll just take your ticket and then we'll set sail."); + stage = 21; + break; + case 21: + end(); + if (player.getInventory().remove(TICKET)) { + Ships.sail(player, Ships.CAIRN_ISLAND_TO_PORT_SARIM); + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 518 }; + } +} diff --git a/Server/src/main/content/region/karamja/dialogue/CustomsOfficerDialogue.java b/Server/src/main/content/region/karamja/dialogue/CustomsOfficerDialogue.java new file mode 100644 index 0000000..b32c1bf --- /dev/null +++ b/Server/src/main/content/region/karamja/dialogue/CustomsOfficerDialogue.java @@ -0,0 +1,222 @@ +package content.region.karamja.dialogue; + +import content.global.travel.ship.Ships; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.game.world.map.Location; + +import static core.api.ContentAPIKt.*; +import content.data.Quests; + +/** + * Represents the dialogue plugin used to handle the customs officer. + * @author Vexia + */ +@Initializable +public final class CustomsOfficerDialogue extends DialoguePlugin { + + /** + * Represents the locations to check where we're. + */ + private static final Location[] LOCATIONS = new Location[] { Location.create(2771, 3227, 0), Location.create(2954, 3147, 0) }; + + /** + * Represents the illegal rum. + */ + private static final Item RUM = new Item(431); + + /** + * Constructs a new {@code CustomsOfficer} {@code Object}. + */ + public CustomsOfficerDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code CustomsOfficer} {@code Object}. + * @param player the player. + */ + public CustomsOfficerDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new CustomsOfficerDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + if (args.length > 1) { + if (player.getQuestRepository().isComplete(Quests.PIRATES_TREASURE)) { + if (player.getInventory().containsItem(RUM)) { + interpreter.sendDialogues(npc, null, "Aha, trying to smuggle rum are we?"); + stage = 900; + return true; + } + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Well you've got some odd stuff, but it's all legal. Now", "you need to pay a boarding charge of " + getPrice() + " coins."); + stage = 121; + return true; + } + } + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Can I help you?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "Can I journey on this ship?", "Does Karamja have unusual customs then?"); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Can I journey on this ship?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Does Karamja have unusual customs then?"); + stage = 20; + break; + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "You need to be searched before you can board?"); + stage = 11; + break; + case 11: + interpreter.sendOptions("Select an Option", "Why?", "Search away, I have nothing to hide.", "You're not putting your hands on my things!"); + stage = 12; + break; + case 12: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Why?"); + stage = 110; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Search away, I have nothing to hide."); + stage = 120; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "You're not putting your hands on my things!"); + stage = 130; + break; + } + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I'm not that sort of customs officer."); + stage = 21; + break; + case 21: + end(); + break; + case 110: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Because Asgarnia has banned the import of intoxicating", "spirits."); + stage = 111; + break; + case 111: + end(); + break; + case 120: + if (player.getInventory().containsItem(RUM)) { + interpreter.sendDialogues(npc, null, "Aha, trying to smuggle rum are we?"); + stage = 900; + return true; + } + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Well you've got some odd stuff, but it's all legal. Now", "you need to pay a boarding charge of " + getPrice() + " coins."); + stage = 121; + break; + case 121: + interpreter.sendOptions("Select an Option", "Ok.", "Oh, I'll not bother then."); + stage = 122; + break; + case 900: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Umm... it's for personal use?"); + stage = 901; + break; + case 901: + for (int i = 0; i < player.getInventory().getAmount(RUM); i++) { + player.getInventory().remove(RUM); + } + player.getPacketDispatch().sendMessage("The customs officer confiscates your rum."); + player.getPacketDispatch().sendMessage("You will need to find some way to smuggle it off the island..."); + end(); + break; + case 122: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Ok."); + stage = 210; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Oh, I'll not bother then."); + stage = 220; + break; + } + break; + case 210:// money + Item coins = new Item(995, getPrice()); + if (!player.getInventory().containsItem(coins)) { + interpreter.sendDialogues(player, null, "Sorry, I don't seem to have enough coins."); + stage = 220; + return true; + } + if (!player.getInventory().remove(coins)) { + interpreter.sendDialogues(player, null, "Sorry, I don't seem to have enough coins."); + stage = 220; + return true; + } + end(); + Ships ship = null; + if (player.getLocation().getDistance(LOCATIONS[0]) < 40) { + ship = Ships.BRIMHAVEN_TO_ARDOUGNE; + } + if (player.getLocation().getDistance(LOCATIONS[1]) < 40) { + ship = Ships.KARAMJAMA_TO_PORT_SARIM; + } + player.getPacketDispatch().sendMessage("You pay " + getPrice() + " coins and board the ship."); + ship.sail(player); + if(ship == Ships.BRIMHAVEN_TO_ARDOUGNE) { + playJingle(player, 171); + } else { + playJingle(player, 172); + } + break; + case 220: + end(); + break; + case 130: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "You're not getting on this ship then."); + stage = 131; + break; + case 131: + end(); + break; + } + return true; + } + + /** + * Gets the price of the fare. + * @return the price. + */ + public int getPrice() { + return player.getAchievementDiaryManager().getKaramjaGlove() != -1 ? 15 : 30; + } + + @Override + public int[] getIds() { + return new int[] { 380 }; + } +} diff --git a/Server/src/main/content/region/karamja/dialogue/JungleForesterDialogue.java b/Server/src/main/content/region/karamja/dialogue/JungleForesterDialogue.java new file mode 100644 index 0000000..23946f8 --- /dev/null +++ b/Server/src/main/content/region/karamja/dialogue/JungleForesterDialogue.java @@ -0,0 +1,145 @@ +package content.region.karamja.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.AchievementDiary; +import core.game.node.entity.player.link.diary.DiaryType; +import core.plugin.Initializable; + +/** + * Represents the dialoge used for a jungle forester. + * @author Vexia + */ +@Initializable +public class JungleForesterDialogue extends DialoguePlugin { + /** + * Constructs a new {@code KalebParamaya} {@code Object} + */ + public JungleForesterDialogue() { + /* + * empty. + */ + } + + /** + * Constructs a new {@code KalebParamaya} {@code Object} + * @param player the player. + */ + public JungleForesterDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new JungleForesterDialogue(player); + } + + @Override + public boolean open(Object... args) { + player("I have a question about my Achievement Diary."); + stage = 41; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 41: + if (AchievementDiary.canClaimLevelRewards(player, DiaryType.KARAMJA, 2)) { + player("I've done all the hard tasks in my Karamja", "Achievement Diary."); + stage = 440; + break; + } + if (AchievementDiary.canReplaceReward(player, DiaryType.KARAMJA, 2)) { + player("I've seemed to have lost my gloves.."); + stage = 450; + break; + } + options("What is the Achievement Diary?", "What are the rewards?", "How do I claim the rewards?", "See you later."); + stage++; + break; + case 42: + switch (buttonId) { + case 1: + player("What is the Achievement Diary?"); + stage = 410; + break; + case 2: + player("What are the rewards?"); + stage = 420; + break; + case 3: + player("How do I claim the rewards?"); + stage = 430; + break; + case 4: + end(); + break; + } + break; + case 440: + npc("Yes I see that, you'll be wanting your", "reward then I assume?"); + stage++; + break; + case 441: + player("Yes please."); + stage++; + break; + case 442: + AchievementDiary.flagRewarded(player, DiaryType.KARAMJA, 2); + npc("These Karamja gloves are a symbol of your explorin'", "on the island. All the merchants will recognise them", "and mabe give you a discount. I'll", "have a word with some of the seafarin' folk who sail to"); + stage += 2; + case 443: + npc("Port Sarim and Ardougne, so they'll take you on board", "half price if you're wearing them. Ttake this lamp I", "found washed ashore too."); + stage++; + break; + case 444: + player("Wow, thanks!"); + stage = 41; + break; + case 450: + AchievementDiary.grantReplacement(player, DiaryType.KARAMJA, 2); + npc("You better be more careful this time."); + stage = 41; + break; + case 410: + npc("It's a diary that helps you keep track of particular", "achievements. Here on Karamja it can help you", "discover some quite useful things. Eventually, with", "enough exploration, the people of Karamja will reward"); + stage++; + break; + case 411: + npc("you."); + stage++; + break; + case 412: + npc("You can see what tasks you have listed by clicking on", "the green button in the Quest List."); + stage = 41; + break; + case 420: + npc("Well, there's three different pairs of Karamja gloves,", "which match up with the three levels of difficulty. Each", "has the same rewards as the previous level, and an", "additional one too... but I won't spoil your surprise."); + stage++; + break; + case 421: + npc("Rest assured, the people of Karamja are happy to see", "you visiting the island."); + stage = 41; + break; + case 430: + npc("Just complete the tasks so they're all ticked off, then", "you can claim yer reward. Most of them are", "straightforward; you might find some require quests to", "be started, if not finished."); + stage++; + break; + case 431: + npc("To claim the different Karamja gloves, speak to Pirate", "Jackie the Fruit in Brim Haven, one of the jungle foresters", "near the Kharazi Jungle, or me."); + stage = 41; + break; + case 50: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 401, 402 }; + } + +} diff --git a/Server/src/main/content/region/karamja/dialogue/KaramjaManDialogue.kt b/Server/src/main/content/region/karamja/dialogue/KaramjaManDialogue.kt new file mode 100644 index 0000000..80d89ad --- /dev/null +++ b/Server/src/main/content/region/karamja/dialogue/KaramjaManDialogue.kt @@ -0,0 +1,46 @@ +package content.region.karamja.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class KaramjaManDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun newInstance(player: Player?): DialoguePlugin { + return KaramjaManDialogue(player) + } + + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + playerl( + FacialExpression.FRIENDLY, "Hello, how's it going?" + ).also { stage = START_DIALOGUE } + return true + } + + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> npcl( + FacialExpression.HALF_GUILTY, + "Not too bad, but I'm a little worried about the increase of goblins these days." + ).also { stage++ } + + 1 -> playerl( + FacialExpression.HAPPY, "Don't worry, I'll kill them." + ).also { stage = END_DIALOGUE } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.MAN_3915) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/karamja/dialogue/LuthasDialogue.java b/Server/src/main/content/region/karamja/dialogue/LuthasDialogue.java new file mode 100644 index 0000000..8692e3a --- /dev/null +++ b/Server/src/main/content/region/karamja/dialogue/LuthasDialogue.java @@ -0,0 +1,158 @@ +package content.region.karamja.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItem; +import core.game.node.item.GroundItemManager; +import core.plugin.Initializable; +import core.game.node.item.Item; + +/** + * Represents the dialogue plugin used for the luthas npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class LuthasDialogue extends DialoguePlugin { + + /** + * Represents the coins item. + */ + private static final Item COINS = new Item(995, 30); + + /** + * Constructs a new {@code LuthasDialogue} {@code Object}. + */ + public LuthasDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code LuthasDialogue} {@code Object}. + * @param player the player. + */ + public LuthasDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new LuthasDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + if (player.getSavedData().getGlobalData().isLuthasTask()) { + final int current = player.getSavedData().getGlobalData().getKaramjaBananas(); + if (current >= 10) { + interpreter.sendDialogues(player, FacialExpression.FRIENDLY, "I've filled a crate with bananas."); + stage = 905; + return true; + } + interpreter.sendDialogues(npc, FacialExpression.HALF_ASKING, "Have you completed your task yet?"); + stage = 900; + return true; + } + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Hello I'm Luthas, I run the banana plantation here."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "Could you offer me employment on your plantation?", "That customs officer is annoying isn't he?"); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.ASKING, "Could you offer me employment on your plantation?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.SUSPICIOUS, "That customs officer is annoying isn't she?"); + stage = 20; + break; + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Yes, I can sort something out. There's a crate ready to", "be loaded onto the ship."); + stage = 11; + break; + case 11: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "You wouldn't believe the demand for bananas from", "Wydin's shop over in Port Sarim. I think this is the", "third crate I've shipped him this month.."); + stage = 12; + break; + case 12: + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "If you could go fill it up with bananas, I'll pay you 30", "gold."); + stage = 13; + player.getSavedData().getGlobalData().setLuthasTask(true); + break; + case 13: + end(); + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "Well I know her pretty well. She doesn't cause me any", "trouble any more"); + stage = 21; + break; + case 21: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "She doesn't even search my export crates anymore.", "She knows they only contain bananas."); + stage = 22; + break; + case 22: + interpreter.sendDialogues(player, FacialExpression.SUSPICIOUS, "Really? How interesting. Whereabouts do you send", "those to?"); + stage = 23; + break; + case 23: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "There is a little shop over in Port Sarim that buys", "them up by the crate. I believe it is run by a man", "called Wydin."); + stage = 24; + break; + case 24: + end(); + break; + case 900: + int amt = player.getSavedData().getGlobalData().getKaramjaBananas(); + if (amt < 30) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No, the crate isn't full yet."); + stage = 901; + } else { + + } + break; + case 901: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "Well come back when it is."); + stage = 21; + break; + case 905: + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Well done, here's your payment."); + stage = 906; + break; + case 906: + end(); + player.getPacketDispatch().sendMessage("Luthas hands you 30 coins."); + player.getSavedData().getGlobalData().setKaramjaBannanas(0); + player.getSavedData().getGlobalData().setLuthasTask(false); + if (player.getAttribute("stashed-rum", false)) { + player.removeAttribute("stashed-rum"); + player.setAttribute("/save:wydin-rum", true); + } + if (!player.getInventory().add(COINS)) { + GroundItemManager.create(new GroundItem(COINS, player.getLocation(), player)); + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 379 }; + } +} diff --git a/Server/src/main/content/region/karamja/dialogue/MonkeyDialogue.kt b/Server/src/main/content/region/karamja/dialogue/MonkeyDialogue.kt new file mode 100644 index 0000000..8e91178 --- /dev/null +++ b/Server/src/main/content/region/karamja/dialogue/MonkeyDialogue.kt @@ -0,0 +1,41 @@ +package content.region.karamja.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class MonkeyDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun newInstance(player: Player?): DialoguePlugin { + return MonkeyDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + playerl( + FacialExpression.ASKING, "Hey little man, how's it goin'?" + ).also { stage = START_DIALOGUE } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> npc("Ukkuk oook! Eeek aka, ahh aka gonk.").also { stage++ } + + 1 -> playerl( + FacialExpression.HALF_GUILTY, "Yeah." + ).also { stage = END_DIALOGUE } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.MONKEY_2301) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/karamja/dialogue/MusaPointShopDialogue.kt b/Server/src/main/content/region/karamja/dialogue/MusaPointShopDialogue.kt new file mode 100644 index 0000000..d84d4bc --- /dev/null +++ b/Server/src/main/content/region/karamja/dialogue/MusaPointShopDialogue.kt @@ -0,0 +1,49 @@ +package content.region.karamja.dialogue + +import core.api.openNpcShop +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class MusaPointShopDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun newInstance(player: Player?): DialoguePlugin { + return MusaPointShopDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npcl( + FacialExpression.FRIENDLY, "Can I help you at all?" + ).also { stage = START_DIALOGUE } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> options("Yes please. What are you selling?", "No thanks.").also { stage++ } + + 1 -> when (buttonId) { + 1 -> { + openNpcShop(player, NPCs.SHOPKEEPER_532) + end() + } + + 2 -> playerl( + FacialExpression.FRIENDLY, "No thanks." + ).also { stage = END_DIALOGUE } + } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.SHOPKEEPER_532, NPCs.SHOP_ASSISTANT_533) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/karamja/dialogue/ZamboDialogue.kt b/Server/src/main/content/region/karamja/dialogue/ZamboDialogue.kt new file mode 100644 index 0000000..23323d0 --- /dev/null +++ b/Server/src/main/content/region/karamja/dialogue/ZamboDialogue.kt @@ -0,0 +1,54 @@ +package content.region.karamja.dialogue + +import core.api.openNpcShop +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class ZamboDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun newInstance(player: Player?): DialoguePlugin { + return ZamboDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npcl( + FacialExpression.ASKING, + " Hey, are you wanting to try some of my fine wines and spirits? All brewed locally on Karamja." + ).also { stage = START_DIALOGUE } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> options("Yes, please.", "No, thank you.").also { stage++ } + + 1 -> when (buttonId) { + 1 -> playerl( + FacialExpression.FRIENDLY, "Yes, please." + ).also { stage++ } + + 2 -> playerl( + FacialExpression.FRIENDLY, "No, thank you." + ).also { stage = END_DIALOGUE } + } + + 2 -> { + openNpcShop(player, NPCs.ZAMBO_568) + end() + } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.ZAMBO_568) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/karamja/diary/KaramjaAchievementDiary.kt b/Server/src/main/content/region/karamja/diary/KaramjaAchievementDiary.kt new file mode 100644 index 0000000..cda3164 --- /dev/null +++ b/Server/src/main/content/region/karamja/diary/KaramjaAchievementDiary.kt @@ -0,0 +1,204 @@ +package content.region.karamja.diary + +import core.game.event.NPCKillEvent +import core.game.event.PickUpEvent +import core.game.event.ResourceProducedEvent +import core.api.inBorders +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.diary.DiaryType +import core.game.world.map.zone.ZoneBorders +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import core.game.diary.DiaryEventHookBase +import core.game.diary.DiaryLevel + +class KaramjaAchievementDiary : DiaryEventHookBase(DiaryType.KARAMJA) { + companion object { + private const val ATTRIBUTE_SEAWEED_PICKED = "diary:karamja:seaweed-picked" + private const val ATTRIBUTE_PALM_LEAF_PICKED = "diary:karamja:palm-leaf-picked" + private const val ATTRIBUTE_BANANA_PICKED = "diary:karamja:banana-picked" + + private val MAIN_ISLAND_AREA = ZoneBorders(2749, 2886, 2972, 3132) + private val BANANA_FISHING_SPOT_AREA = ZoneBorders(2923, 3173, 2928, 3182) + private val TAI_BWO_WANNAI_WOODCUTTING_AREA = ZoneBorders(2817, 3076, 2829, 3090) + + private val KET_ZEKS = arrayOf( + NPCs.KET_ZEK_2743, + NPCs.KET_ZEK_2744 + ) + + private val METAL_DRAGONS = arrayOf( + NPCs.BRONZE_DRAGON_1590, + NPCs.IRON_DRAGON_1591, + NPCs.STEEL_DRAGON_1592 + ) + + object EasyTasks { + const val PICK_5_BANANAS = 0 + const val TRAVEL_TO_MOSS_GIANTS_VIA_ROPESWING = 1 + const val BRIMHAVEN_MINE_GOLD = 2 + const val MUSA_POINT_CHARTER_SHIP_TO_PORT_SARIM = 3 + const val BRIMHAVEN_CHARTER_SHIP_TO_ARDOUGNE = 4 + const val CAIRN_ISLE_VISIT = 5 + const val USE_FISHING_SPOTS_BANANA_PLANTATION = 6 + const val PICK_5_SEAWEED = 7 + const val ATTEMPT_TZHAAR_FIGHT_PITS_OR_FIGHT_CAVE = 8 + const val POTHOLE_DUNGEON_KILL_JOGRE = 9 + } + + object MediumTasks { + const val BRIMHAVEN_CLAIM_AGILITY_ARENA_TICKET = 0 + const val FIND_HIDDEN_WALL_BELOW_VOLCANO = 1 + const val CRANDOR_ISLAND_VISIT = 2 + const val USE_VIGROY_HAJEDY_CARTS = 3 + const val TAI_BWO_WANNAI_EARN_FULL_FAVOR = 4 + const val COOK_SPIDER_ON_STICK = 5 + const val CAIRN_ISLE_CHARTER_LADY_OF_THE_WAVES = 6 + const val CUT_TEAK_TREE = 7 + const val CUT_MAHOGANY_TREE = 8 + const val CATCH_KARAMBWAN = 9 + const val EXCHANGE_GEMS_TUBER_TRADING_STICKS_FOR_MACHETE = 10 + const val GNOME_GLIDE_TO_KARAMJA = 11 + const val BRIMHAVEN_GROW_HEALTHY_FRUIT_TREE = 12 + const val TRAP_HORNED_GRAAHK = 13 + const val BRIMHAVEN_DUNGEON_CHOP_VINES = 14 + const val BRIMHAVEN_DUNGEON_CROSS_LAVA_STEPPING_STONES = 15 + const val BRIMHAVEN_DUNGEON_CLIMB_STAIRS = 16 + const val CHARTER_SHIP_EAST = 17 + const val MINE_RED_TOPAZ = 18 + } + + object HardTasks { + const val FIGHT_PITS_BECOME_CHAMPION = 0 + const val FIGHT_CAVE_KILL_KET_ZEK = 1 + const val EAT_OOMLIE_WRAP = 2 + const val CRAFT_NATURE_RUNES = 3 + const val COOK_KARAMBWAN_PROPERLY = 4 + const val KHARAZI_JUNGLE_KILL_DEATHWING = 5 + const val VOLCANO_USE_CROSSBOW_SHORTCUT_SOUTH = 6 + const val PICK_5_PALM_LEAVES = 7 + const val DURADEL_LAPALOK_GET_SLAYER_TASK = 8 + const val BRIMHAVEN_DUNGEON_KILL_METAL_DRAGON = 9 + } + } + + override fun onResourceProduced(player: Player, event: ResourceProducedEvent) { + when (player.viewport.region.id) { + 10802 -> if (event.itemId == Items.GOLD_ORE_444) { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.BRIMHAVEN_MINE_GOLD + ) + } + + 11310, 11410 -> if (event.itemId == Items.UNCUT_RED_TOPAZ_1629) { + finishTask( + player, + DiaryLevel.MEDIUM, + MediumTasks.MINE_RED_TOPAZ + ) + } + + 11569 -> if (event.itemId == Items.BANANA_1963) { + progressIncrementalTask( + player, + DiaryLevel.EASY, + EasyTasks.PICK_5_BANANAS, + ATTRIBUTE_BANANA_PICKED, + 5 + ) + } + } + + when { + inBorders(player, BANANA_FISHING_SPOT_AREA) -> { + when (event.source.id) { + NPCs.FISHING_SPOT_323, + NPCs.FISHING_SPOT_333 -> { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.USE_FISHING_SPOTS_BANANA_PLANTATION + ) + } + } + } + + inBorders(player, TAI_BWO_WANNAI_WOODCUTTING_AREA) -> { + when (event.itemId) { + Items.MAHOGANY_LOGS_6332 -> { + finishTask( + player, + DiaryLevel.MEDIUM, + MediumTasks.CUT_MAHOGANY_TREE + ) + } + + Items.TEAK_LOGS_6333 -> { + finishTask( + player, + DiaryLevel.MEDIUM, + MediumTasks.CUT_TEAK_TREE + ) + } + } + } + } + } + + override fun onNpcKilled(player: Player, event: NPCKillEvent) { + when (player.viewport.region.id) { + 10899, 10900 -> if (event.npc.id in METAL_DRAGONS) { + finishTask( + player, + DiaryLevel.HARD, + HardTasks.BRIMHAVEN_DUNGEON_KILL_METAL_DRAGON + ) + } + + 11412 -> if (event.npc.id == NPCs.JOGRE_113) { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.POTHOLE_DUNGEON_KILL_JOGRE + ) + } + + /* Ket-Zek only appears in an instanced Fight Cave area. */ + else -> if (event.npc.id in KET_ZEKS) { + finishTask( + player, + DiaryLevel.HARD, + HardTasks.FIGHT_CAVE_KILL_KET_ZEK + ) + } + } + } + + override fun onPickedUp(player: Player, event: PickUpEvent) { + when { + inBorders(player, MAIN_ISLAND_AREA) -> { + if (event.itemId == Items.SEAWEED_401) { + progressIncrementalTask( + player, + DiaryLevel.EASY, + EasyTasks.PICK_5_SEAWEED, + ATTRIBUTE_SEAWEED_PICKED, + 5 + ) + } + + if (event.itemId == Items.PALM_LEAF_2339) { + progressIncrementalTask( + player, + DiaryLevel.HARD, + HardTasks.PICK_5_PALM_LEAVES, + ATTRIBUTE_PALM_LEAF_PICKED, + 5 + ) + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/karamja/handlers/BananaCrateDialogue.java b/Server/src/main/content/region/karamja/handlers/BananaCrateDialogue.java new file mode 100644 index 0000000..a7eaeb4 --- /dev/null +++ b/Server/src/main/content/region/karamja/handlers/BananaCrateDialogue.java @@ -0,0 +1,86 @@ +package content.region.karamja.handlers; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.game.world.update.flag.context.Animation; + +/** + * Represents the banana crate dialogue. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class BananaCrateDialogue extends DialoguePlugin { + + /** + * Represents the dialogue id. + */ + public static final int ID = 9682749; + + /** + * Represents the animation to use. + */ + private static final Animation ANIMATION = new Animation(832); + + /** + * Represents the banana item. + */ + private static final Item BANANA = new Item(1963); + + /** + * Constructs a new {@code BananaCrateDialogue} {@code Object}. + */ + public BananaCrateDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code BananaCrateDialogue} {@code Object}. + * @param player the player. + */ + public BananaCrateDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new BananaCrateDialogue(player); + } + + @Override + public boolean open(Object... args) { + interpreter.sendOptions("Do you want to take a banana?", "Yes.", "No."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + switch (buttonId) { + case 1: + if (player.getInventory().add(BANANA)) { + player.animate(ANIMATION); + player.getPacketDispatch().sendMessage("You take a banana."); + } + end(); + break; + case 2: + end(); + break; + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { ID }; + } +} diff --git a/Server/src/main/content/region/karamja/handlers/CairnIslandZone.java b/Server/src/main/content/region/karamja/handlers/CairnIslandZone.java new file mode 100644 index 0000000..b56d6ab --- /dev/null +++ b/Server/src/main/content/region/karamja/handlers/CairnIslandZone.java @@ -0,0 +1,44 @@ +package content.region.karamja.handlers; + +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneBuilder; +import core.plugin.Initializable; +import core.plugin.Plugin; + +@Initializable +public class CairnIslandZone extends MapZone implements Plugin { + + public CairnIslandZone() { + super("cairn-island", true); + } + + @Override + public void configure() { + register(new ZoneBorders(2752, 2963, 2774, 2992)); + } + + @Override + public boolean enter(Entity entity) { + // Explore Cairn Island to the west of Karamja + if (entity.isPlayer()) { + Player player = entity.asPlayer(); + player.getAchievementDiaryManager().finishTask(player, DiaryType.KARAMJA, 0, 5); + } + return super.enter(entity); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ZoneBuilder.configure(this); + return this; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } +} diff --git a/Server/src/main/content/region/karamja/handlers/CustomsOfficerPlugin.java b/Server/src/main/content/region/karamja/handlers/CustomsOfficerPlugin.java new file mode 100644 index 0000000..a29ad6b --- /dev/null +++ b/Server/src/main/content/region/karamja/handlers/CustomsOfficerPlugin.java @@ -0,0 +1,38 @@ +package content.region.karamja.handlers; + +import core.cache.def.impl.NPCDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; +import content.data.Quests; + +/** + * Represents the customs officer plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class CustomsOfficerPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + NPCDefinition.forId(380).getHandlers().put("option:pay-fare", this); + NPCDefinition.forId(381).getHandlers().put("option:pay-fare", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + if (!player.getQuestRepository().isComplete(Quests.PIRATES_TREASURE)) { + player.getDialogueInterpreter().open(((NPC) node).getId(), ((NPC) node)); + player.getPacketDispatch().sendMessage("You may only use the Pay-fare option after completing Pirate's Treasure."); + return true; + } + player.getDialogueInterpreter().open(((NPC) node).getId(), ((NPC) node), true); + return true; + } + +} diff --git a/Server/src/main/content/region/karamja/handlers/JungleBushHandler.kt b/Server/src/main/content/region/karamja/handlers/JungleBushHandler.kt new file mode 100644 index 0000000..8e44621 --- /dev/null +++ b/Server/src/main/content/region/karamja/handlers/JungleBushHandler.kt @@ -0,0 +1,59 @@ +package content.region.karamja.handlers + +import core.api.inEquipmentOrInventory +import core.api.inInventory +import core.game.node.scenery.Scenery +import core.game.node.scenery.SceneryBuilder +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.game.world.GameWorld + +/** + * Handles the chopping down of dense jungle, mainly to grant access to the Kharazi Jungle. + * @author Ceikry + */ +class JungleBushHandler : InteractionListener { + val chopped_bush = 2895 + val chop_a = Animation(910) + val chop_b = Animation(2382) + val ids = intArrayOf(2892,2893) + + override fun defineListeners() { + + on(ids, IntType.SCENERY, "chop-down"){ player, node -> + val toChop = node.asScenery() + if(checkRequirement(player)){ + GameWorld.Pulser.submit(object : Pulse(0){ + var ticks = 0 + override fun pulse(): Boolean { + when(ticks++){ + 0 -> player.animator.animate(chop_a).also { player.lock() } + 1 -> player.animator.animate(chop_b) + 2 -> SceneryBuilder.replace(toChop, Scenery(chopped_bush, toChop.location, toChop.rotation),20) + 3 -> {player.walkingQueue.reset(); player.walkingQueue.addPath(toChop.location.x, toChop.location.y,true)} + 4 -> player.unlock().also { return true } + } + return false + } + }) + } else { + player.sendMessage("You need a machete to get through this dense jungle.") + } + return@on true + } + + } + + private fun checkRequirement(player: Player): Boolean{ + val machete = Item(Items.MACHETE_975) + val jade_machete = Item(Items.JADE_MACHETE_6315) + val opal_machete = Item(Items.OPAL_MACHETE_6313) + val red_topaz_machete = Item(Items.RED_TOPAZ_MACHETE_6317) + return inEquipmentOrInventory(player, machete.id) || inEquipmentOrInventory(player, jade_machete.id) || inEquipmentOrInventory(player, opal_machete.id) || inEquipmentOrInventory(player, red_topaz_machete.id) + } +} diff --git a/Server/src/main/content/region/karamja/handlers/KaramjaListeners.kt b/Server/src/main/content/region/karamja/handlers/KaramjaListeners.kt new file mode 100644 index 0000000..3ef1178 --- /dev/null +++ b/Server/src/main/content/region/karamja/handlers/KaramjaListeners.kt @@ -0,0 +1,117 @@ +package content.region.karamja.handlers + +import core.api.* +import core.game.global.action.ClimbActionHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength +import core.game.node.item.Item +import org.rs09.consts.* + +class KaramjaListeners : InteractionListener { + companion object { + /** + * Represents the Musa Point dungeon location. + */ + private val MUSA_POINT_DUNGEON = location(2856, 9567, 0) + + /** + * Represents the volcano rim location. + */ + private val VOLCANO_RIM = location(2856, 3167, 0) + + /** + * Represents the rocks used to enter the Musa Point dungeon. + */ + private const val MUSA_POINT_DUNGEON_ENTRANCE = Scenery.ROCKS_492 + + /** + * Represents the rope used to exit the Musa Point dungeon. + */ + private const val MUSA_POINT_DUNGEON_EXIT = Scenery.CLIMBING_ROPE_1764 + + /** + * Represents the pineapple plant objects. + */ + private val PINEAPPLE_PLANT = intArrayOf( + Scenery.PINEAPPLE_PLANT_1408, Scenery.PINEAPPLE_PLANT_1409, + Scenery.PINEAPPLE_PLANT_1410, Scenery.PINEAPPLE_PLANT_1411, + Scenery.PINEAPPLE_PLANT_1412, Scenery.PINEAPPLE_PLANT_1413 + ) + private const val PICK_PINEAPPLE_ANIMATION = 2282 + private const val PINEAPPLE = Items.PINEAPPLE_2114 + + private const val SHAKE_TREE_ANIMATION = 2572 + private const val PALM_LEAF = Items.PALM_LEAF_2339 + private const val PALM_TREE_FULL = Scenery.LEAFY_PALM_TREE_2975 + private const val PALM_TREE_EMPTY = Scenery.LEAFY_PALM_TREE_2976 + } + + override fun defineListeners() { + on(MUSA_POINT_DUNGEON_ENTRANCE, IntType.SCENERY, "climb-down") { player, _ -> + ClimbActionHandler.climb(player, ClimbActionHandler.CLIMB_DOWN, MUSA_POINT_DUNGEON) + sendMessage(player, "You climb down through the pot hole.") + return@on true + } + + on(MUSA_POINT_DUNGEON_EXIT, IntType.SCENERY, "climb-up") { player, _ -> + ClimbActionHandler.climb(player, ClimbActionHandler.CLIMB_UP, VOLCANO_RIM) + sendMessage(player, "You climb up the hanging rope...") + sendMessage(player, "You appear on the volcano rim.") + return@on true + } + + on(PINEAPPLE_PLANT, IntType.SCENERY, "pick") { player, node -> + // TODO: Convert FieldPickingPlugin to Kotlin & include this. + if (!hasSpaceFor(player, Item(PINEAPPLE))) { + sendMessage(player, "You don't have enough space in your inventory.") + return@on true + } + if (node.id == Scenery.PINEAPPLE_PLANT_1413) { + sendMessage(player, "There are no pineapples left on this plant.") + return@on true + } + val last: Boolean = node.id == Scenery.PINEAPPLE_PLANT_1412 + if (addItem(player, PINEAPPLE)) { + animate(player, PICK_PINEAPPLE_ANIMATION) + playAudio(player, Sounds.PICK_2581, 30) + replaceScenery(node.asScenery(), node.id + 1, if (last) 270 else 40) + sendMessage(player, "You pick a pineapple.") + } + return@on true + } + + on(Scenery.BANANA_TREE_2078, IntType.SCENERY, "search") { player, _ -> + // TODO: Convert FieldPickingPlugin to Kotlin & include this. + sendMessage(player, "There are no bananas left on the tree.") + return@on true + } + + on(PALM_TREE_FULL, IntType.SCENERY, "Shake") { player, node -> + queueScript(player, 0, QueueStrength.WEAK) { stage: Int -> + when (stage) { + 0 -> { + lock(player, 2) + face(player, node) + animate(player, SHAKE_TREE_ANIMATION) + sendMessage(player, "You give the tree a good shake.") + replaceScenery(node.asScenery(), PALM_TREE_EMPTY, 60) + return@queueScript delayScript(player, 2) + } + 1 -> { + produceGroundItem( + player, + PALM_LEAF, + 1, + getPathableRandomLocalCoordinate(player, 1, node.location) + ) + sendMessage(player, "A palm leaf falls to the ground.") + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/karamja/handlers/MossGiantRopePlugin.java b/Server/src/main/content/region/karamja/handlers/MossGiantRopePlugin.java new file mode 100644 index 0000000..ed17bbc --- /dev/null +++ b/Server/src/main/content/region/karamja/handlers/MossGiantRopePlugin.java @@ -0,0 +1,50 @@ +package content.region.karamja.handlers; + +import core.cache.def.impl.SceneryDefinition; +import core.game.node.entity.skill.Skills; +import content.global.skill.agility.AgilityHandler; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Handles the rope swing to the moss giants. + * @author Vexia + */ +@Initializable +public class MossGiantRopePlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(2322).getHandlers().put("option:swing-on", this); + SceneryDefinition.forId(2323).getHandlers().put("option:swing-on", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + if (!player.getLocation().withinDistance(node.getLocation(), 4)) { + player.sendMessage("I can't reach that."); + return true; + } + if (player.getSkills().getStaticLevel(Skills.AGILITY) < 10) { + player.getDialogueInterpreter().sendDialogue("You need an Agility level of at least 10 in order to do that."); + return true; + } + Location end = node.getId() == 2322 ? Location.create(2704, 3209, 0) : Location.create(2709, 3205, 0); + player.getPacketDispatch().sendSceneryAnimation(node.asScenery(), Animation.create(497), true); + AgilityHandler.forceWalk(player, 0, player.getLocation(), end, Animation.create(751), 50, 22, "You skillfully swing across.", 1); + player.getAchievementDiaryManager().finishTask(player, DiaryType.KARAMJA, 0, 1); + return true; + } + + @Override + public Location getDestination(Node node, Node n) { + return n.getId() == 2322 ? Location.create(2709, 3209, 0) : Location.create(2705, 3205, 0); + } +} diff --git a/Server/src/main/content/region/karamja/handlers/TribesmanNPC.java b/Server/src/main/content/region/karamja/handlers/TribesmanNPC.java new file mode 100644 index 0000000..184357c --- /dev/null +++ b/Server/src/main/content/region/karamja/handlers/TribesmanNPC.java @@ -0,0 +1,48 @@ +package content.region.karamja.handlers; + +import core.game.node.entity.npc.AbstractNPC; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.game.system.config.NPCConfigParser; + +/** + * Represents the tribesamn npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class TribesmanNPC extends AbstractNPC { + + /** + * Represents the npc ids. + */ + private static final int[] IDS = new int[] { 191, 2496, 2497 }; + + /** + * Constructs a new {@code TribesmanNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + public TribesmanNPC(int id, Location location) { + super(id, location, true); + getDefinition().getHandlers().put(NPCConfigParser.POISONOUS, true); + } + + /** + * Constructs a new {@code TribesmanNPC} {@code Object}. + */ + public TribesmanNPC() { + super(0, null); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new TribesmanNPC(id, location); + } + + @Override + public int[] getIds() { + return IDS; + } + +} diff --git a/Server/src/main/content/region/karamja/quest/junglepotion/JunglePotion.java b/Server/src/main/content/region/karamja/quest/junglepotion/JunglePotion.java new file mode 100644 index 0000000..5639c3b --- /dev/null +++ b/Server/src/main/content/region/karamja/quest/junglepotion/JunglePotion.java @@ -0,0 +1,270 @@ +package content.region.karamja.quest.junglepotion; + +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import content.global.skill.herblore.Herbs; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.update.flag.context.Animation; +import core.plugin.ClassScanner; +import core.tools.RandomFunction; +import core.tools.StringUtils; + +import static core.api.ContentAPIKt.*; +import content.data.Quests; + +/** + * The main type or the jungle potion quest. + * @author Vexia + * + */ +@Initializable +public final class JunglePotion extends Quest { + + /** + * Constructs a new {@code JunglePotion} {@code Object}. + */ + public JunglePotion() { + super(Quests.JUNGLE_POTION, 81, 80, 1, 175, 0, 1, 12); + } + + @Override + public Quest newInstance(Object object) { + ClassScanner.definePlugin(new TrufitusDialogue()); + ClassScanner.definePlugin(new JunglePotionPlugin.JogreCavernDialogue()); + ClassScanner.definePlugin(new JunglePotionPlugin()); + return this; + } + + @Override + public void drawJournal(Player player, int stage) { + super.drawJournal(player, stage); + switch (stage) { + case 0: + line(player, "I can start this quest by speaking to Trufitus Shakayawho lives in the main hut in Tai Bwo Wannaivillage on the island of Karamja.", 11); + break; + case 10: + case 20: + case 30: + case 40: + case 50: + JungleObjective objective = JungleObjective.forStage(stage); + if (player.getInventory().containsItem(objective.getHerb().getProduct())) { + line(player, "I spoke to Trufitus, he needs to commune with thegods, he's asked me to help him by collecting herbs.I picked some fresh " + objective.getName() + " for Trufitus.I need to give the " + objective.getName() + " to Trufitus.", 11); + return; + } + line(player, "I spoke to Trufitus, he needs to commune with thegods, he's asked me to help him by collecting herbs.I need to pick some fresh " + objective.getName() + " for Trufitus.", 11); + break; + case 60: + line(player, "I spoke to Trufitus, he needs to commune with thegods, he's asked me to help him by collecting herbs.I have given Trufitus Snakeweed, Ardrigal,Sito Foil, Volencia moss and Rogues purse.Trufitus needs to commune with the gods.I should speak to Trufitus.", 11); + break; + case 100: + line(player, "Trufitus Shakaya of the Tai Bwo Wannai village neededsome jungle herbs in order to make a potion which wouldhelp him commune with the gods. I collected five lotsof jungle herbs for him and he was able tocommune with the gods.As a reward he showed me some herblore techniques.QUEST COMPLETE!", 11); + break; + } + } + + @Override + public void finish(Player player) { + super.finish(player); + player.getPacketDispatch().sendString("1 Quest Point", 277, 8 + 2); + player.getPacketDispatch().sendString("775 Herblore XP", 277, 9 + 2); + player.getPacketDispatch().sendItemZoomOnInterface(Herbs.VOLENCIA_MOSS.getProduct().getId(), 235, 277, 3 + 2); + player.getSkills().addExperience(Skills.HERBLORE, 775); + player.getQuestRepository().syncronizeTab(player); + setVarbit(player, 897, 2); + setVarbit(player, 898, 2); + setVarbit(player, 899, 2); + setVarbit(player, 900, 2); + setVarbit(player, 896, 2, true); + } + + @Override + public int[] getConfig(Player player, int stage) { + if(stage == 0) return new int []{175,0}; + if(stage == 100) return new int [] {175,15}; + if(stage > 0) return new int [] {175,1}; + return new int [] {175,15}; + } + + /** + * An objective during the quest. + * @author Vexia + */ + public static enum JungleObjective { + JUNGLE_VINE(2575, Herbs.SNAKE_WEED, 10, "It grows near vines in an area to the south west where", "the ground turns soft and the water kisses your feet.") { + @Override + public void search(final Player player, final Scenery object) { + final Animation animation = Animation.create(2094); + player.animate(animation); + player.getPulseManager().run(new Pulse(animation.getDefinition().getDurationTicks(), player, object) { + @Override + public boolean pulse() { + boolean success = RandomFunction.random(3) == 1; + if (success) { + switchObject(object); + findHerb(player); + return true; + } + player.animate(animation); + return false; + } + }); + } + }, + PALM_TREE(2577, Herbs.ARDRIGAL, 20, "You are looking for Ardrigal. It is related to the palm", "and grows in its brothers shady profusion."), SITO_FOIL(2579, Herbs.SITO_FOIL, 30, "You are looking for Sito Foil, and it grows best where", "the ground has been blackened by the living flame."), VOLENCIA_MOSS(2581, Herbs.VOLENCIA_MOSS, 40, "You are looking for Volencia Moss. It clings to rocks", "for its existence. It is difficult to see, so you must", "search for it well."), ROGUES_PURSE(32106, Herbs.ROGUES_PURSE, 50, "It inhabits the darkness of the underground, and grows", "in the caverns to the north. A secret entrance to the", "caverns is set into the northern cliffs, be careful Bwana.") { + @Override + public void search(final Player player, final Scenery object) { + final Animation animation = Animation.create(2097); + player.animate(animation); + player.getPulseManager().run(new Pulse(animation.getDefinition().getDurationTicks(), player, object) { + @Override + public boolean pulse() { + boolean success = RandomFunction.random(4) == 1; + if (success) { + switchObject(object); + findHerb(player); + return true; + } + player.animate(animation, 1); + return false; + } + }); + } + }; + + /** + * The object id. + */ + private final int objectId; + + /** + * The herb. + */ + private final Herbs herb; + + /** + * The stage required to search this. + */ + private final int stage; + + /** + * The objective clue. + */ + private final String[] clue; + + /** + * Constructs a new {@code Searchable} {@code Object}. + * @param objectId the object id. + * @param herb the herb. + * @param stage the stage.. + */ + private JungleObjective(int objectId, Herbs herb, int stage, final String... clue) { + this.objectId = objectId; + this.herb = herb; + this.stage = stage; + this.clue = clue; + } + + /** + * Handles the search function of the objective. + * @param player the player. + * @param object the object. + */ + public void search(final Player player, final Scenery object) { + findHerb(player); + switchObject(object); + } + + /** + * Switches the object's id. + * @param object the object. + */ + public void switchObject(Scenery object) { + if (object.isActive()) { + SceneryBuilder.replace(object, object.transform(object.getId() + 1), 80); + } + } + + /** + * Finds a herb. + * @param player the player. + */ + public void findHerb(final Player player) { + player.getInventory().add(getHerb().getHerb()); + player.getDialogueInterpreter().sendItemMessage(getHerb().getHerb(), "You find a herb."); + } + + /** + * Gets the jungle objective. + * @param stage the stage. + * @return the objective. + */ + public static JungleObjective forStage(int stage) { + for (JungleObjective o : values()) { + if (o.getStage() == stage) { + return o; + } + } + return null; + } + + /** + * Gets a searchable by the object id. + * @param objectId the object id. + * @return the searchable. + */ + public static JungleObjective forId(int objectId) { + for (JungleObjective s : values()) { + if (s.getObjectId() == objectId) { + return s; + } + } + return null; + } + + /** + * Gets the name of the herb objective. + * @return the name. + */ + public String getName() { + return StringUtils.formatDisplayName(herb.getProduct().getName().replace("Clean", "").trim()); + } + + /** + * Gets the objectId. + * @return The objectId. + */ + public int getObjectId() { + return objectId; + } + + /** + * Gets the herb. + * @return The herb. + */ + public Herbs getHerb() { + return herb; + } + + /** + * Gets the stage. + * @return The stage. + */ + public int getStage() { + return stage; + } + + /** + * Gets the clue. + * @return The clue. + */ + public String[] getClue() { + return clue; + } + } + +} diff --git a/Server/src/main/content/region/karamja/quest/junglepotion/JunglePotionPlugin.java b/Server/src/main/content/region/karamja/quest/junglepotion/JunglePotionPlugin.java new file mode 100644 index 0000000..5828060 --- /dev/null +++ b/Server/src/main/content/region/karamja/quest/junglepotion/JunglePotionPlugin.java @@ -0,0 +1,161 @@ +package content.region.karamja.quest.junglepotion; + +import content.data.Quests; +import core.cache.def.impl.SceneryDefinition; +import core.game.dialogue.DialogueInterpreter; +import core.game.dialogue.DialoguePlugin; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.world.map.Location; +import core.plugin.Plugin; + +import content.region.karamja.quest.junglepotion.JunglePotion.JungleObjective; + +/** + * Handles any interactions of the jungle potion quest. + * @author Vexia + */ +public final class JunglePotionPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(2584).getHandlers().put("option:search", this); + SceneryDefinition.forId(2585).getHandlers().put("option:climb", this); + for (JungleObjective s : JungleObjective.values()) { + SceneryDefinition.forId(s.getObjectId()).getHandlers().put("option:search", this); + } + SceneryBuilder.add(new Scenery(2585, Location.create(2828, 9522, 0), 8, 0)); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + final Quest quest = player.getQuestRepository().getQuest(Quests.JUNGLE_POTION); + switch (node.getId()) { + case 2584: + player.getDialogueInterpreter().open("jogre_dialogue"); + return true; + case 2585: + player.getDialogueInterpreter().open("jogre_dialogue", true, true); + return true; + } + switch (option) { + case "search": + search(player, quest, (Scenery) node, JungleObjective.forId(node.getId())); + break; + } + return true; + } + + /** + * Searches an object for a herb. + * @param player the player. + * @param quest the quest. + * @param object the object. + * @param objective the searchable. + */ + private void search(final Player player, Quest quest, final Scenery object, final JungleObjective objective) { + if (quest.getStage(player) < objective.getStage()) { + player.sendMessage("Unfortunately, you find nothing of interest."); + return; + } + if (player.getInventory().freeSlots() < 1) { + player.sendMessage("You don't have enough inventory space."); + return; + } + player.sendMessage("You search the " + object.getName().toLowerCase() + "..."); + objective.search(player, object); + } + + @Override + public Location getDestination(Node n, Node node) { + if (node.getId() == 2585) { + return Location.create(2830, 9521, 0); + } + return null; + } + + /** + * Handles the jogre cavern dialogue. + * @author Vexia + */ + public static final class JogreCavernDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code JogreCavernDialogue} {@code Object}. + */ + public JogreCavernDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code JogreCavernDialogue} {@code Object}. + * @param player the player. + */ + public JogreCavernDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new JogreCavernDialogue(player); + } + + @Override + public boolean open(Object... args) { + if (args.length > 1) { + interpreter.sendDialogue("You attempt to climb the rocks back out."); + stage = 13; + return true; + } + interpreter.sendDialogue("You search the rocks... You find an entrance into some caves."); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + options("Yes, I'll enter the cave.", "No thanks, I'll give it a miss."); + stage++; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogue("You decide to enter the caves. You climb down several steep rock", "faces into the cavern below."); + stage = 10; + break; + case 2: + interpreter.sendDialogue("You decide to stay where you are!"); + stage = 11; + break; + } + break; + case 10: + end(); + player.getProperties().setTeleportLocation(Location.create(2830, 9520, 0)); + break; + case 11: + end(); + break; + case 13: + end(); + player.getProperties().setTeleportLocation(Location.create(2823, 3120, 0)); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { DialogueInterpreter.getDialogueKey("jogre_dialogue") }; + } + + } +} diff --git a/Server/src/main/content/region/karamja/quest/junglepotion/TrufitusDialogue.java b/Server/src/main/content/region/karamja/quest/junglepotion/TrufitusDialogue.java new file mode 100644 index 0000000..267bef0 --- /dev/null +++ b/Server/src/main/content/region/karamja/quest/junglepotion/TrufitusDialogue.java @@ -0,0 +1,366 @@ +package content.region.karamja.quest.junglepotion; + +import content.data.Quests; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; + +import content.region.karamja.quest.junglepotion.JunglePotion.JungleObjective; + +/** + * Handles the trufitus dialogue. + * + * @author Vexia + */ +public final class TrufitusDialogue extends DialoguePlugin { + + /** + * The objective. + */ + private JungleObjective objective; + + /** + * The quest instance. + */ + private Quest quest; + + /** + * Constructs a new {@code TrufitusDialogue} {@code Object}. + */ + public TrufitusDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code TrufitusDialogue} {@code Object}. + * + * @param player the player. + */ + public TrufitusDialogue(final Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new TrufitusDialogue(player); + } + + @Override + public boolean open(Object... args) { + quest = player.getQuestRepository().getQuest(Quests.JUNGLE_POTION); + switch (quest.getStage(player)) { + case 0: + npc("Greetings Bwana! I am Trufitus Shakaya of the Tai", "Bwo Wannai village."); + break; + case 10: + case 20: + case 30: + case 40: + case 50: + objective = JungleObjective.forStage(quest.getStage(player)); + npc("Hello, Bwana, do you have the " + objective.getName() + "?"); + break; + case 60: + interpreter.sendDialogue("Trufitus shows you some techniques in Herblore. You gain some", "experience in Herblore."); + break; + case 100: + if (!player.getAttribute("trufitus-post-jp", false)) { + npc("My greatest respect Bwana, I have communed with", "my gods and the future"); + player.setAttribute("/save:trufitus-post-jp", true); + stage = 0; + } else { + player("Hello Bwana!"); + stage = 10; + } + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (quest.getStage(player)) { + case 0: + switch (stage) { + case 0: + npc("Welcome to our humble village."); + stage++; + break; + case 1: + options("What does Bwana mean?", "Tai Bwo Wannai? What does that mean?", "It's a nice village, where is everyone?"); + stage++; + break; + case 2: + switch (buttonId) { + case 1: + player("What does Bwana mean?"); + stage = 10; + break; + case 2: + player("Tai Bwo Wannai? What does that mean?"); + stage = 20; + break; + case 3: + player("It's a nice village, where is everyone?"); + stage = 30; + break; + } + break; + case 10: + npc("Gracious sir, it means friend. And friends come in", "peace. I assume that you come in peace?"); + stage++; + break; + case 11: + player("Yes, of course I do."); + stage++; + break; + case 12: + npc("Well, that is good news, as I have a proposition for", "you."); + stage++; + break; + case 13: + player("A proposition eh? Sounds interesting!"); + stage++; + break; + case 14: + npc("I hoped you would think so. My people are afraid to", "stay in the village."); + stage++; + break; + case 15: + npc("They have returned to the jungle and I need to", "commune with the gods"); + stage++; + break; + case 16: + npc("to see what fate befalls us. You can help me by", "collecting some herbs that I need."); + stage++; + break; + case 17: + player("Me? How Can I help?"); + stage = 33; + break; + case 20: + npc("it means 'small clearing in the jungle' but it is now the", "name of our village."); + stage++; + break; + case 21: + player("It's a nice village, where is everyone?"); + stage = 30; + break; + case 30: + npc("My people are afraid to stay in the village. They have", "returned to the jungle. I need to commune with the", "gods to see what fate befalls us."); + stage++; + break; + case 31: + npc("You may be able to help with this."); + stage++; + break; + case 32: + player("Me? How Can I help?"); + stage++; + break; + case 33: + npc("I need to make a special brew! A potion that helps", "to commune with the gods. For this potion, I need", "special herbs, that are only found deep in the jungle."); + stage++; + break; + case 34: + npc("I can only guide you so far as the herbs are not easy", "to find. With some luck, you will find each herb in turn", "and bring it to me. I will then give you details of where", "to find the next herb."); + stage++; + break; + case 35: + npc("In return for this great favour I will give you training", "in Herblore."); + stage++; + break; + case 36: + player("It sounds like just the challenge for me. And it would", "make a nice break from killing things!"); + stage++; + break; + case 37: + npc("That is excellent Bwana! The first herb that you need", "to gather is called"); + stage++; + break; + case 38: + npc("Snake Weed."); + stage++; + break; + case 39: + npc("It grows near vines in an area to the south west where"); + stage++; + break; + case 40: + npc("the ground turns soft and the water kisses your feet."); + stage++; + break; + case 41: + quest.start(player); + end(); + break; + } + break; + case 10: + case 20: + case 30: + case 40: + case 50: + switch (stage) { + case 0: + options("Of course!", "Not yet, sorry, what's the clue again?"); + stage++; + break; + case 1: + switch (buttonId) { + case 1: + player("Of course!"); + stage = 10; + break; + case 2: + player("Not yet, sorry, what's the clue again?"); + stage = 20; + break; + } + break; + case 10: + if (!player.getInventory().containsItem(objective.getHerb().getProduct())) { + npc("Please, don't try to deceive me."); + stage = 11; + } else { + if (player.getInventory().remove(objective.getHerb().getProduct())) { + quest.setStage(player, quest.getStage(player) + 10); + interpreter.sendItemMessage(objective.getHerb().getProduct(), "You give the " + objective.getName() + " to Trufitus."); + stage = 50; + } + } + break; + case 11: + npc("I really need that " + objective.getName() + " if I am to make this", "potion."); + stage++; + break; + case 12: + end(); + break; + case 20: + npc(objective.getClue()); + stage = 11; + break; + case 50: + objective = JungleObjective.forStage(quest.getStage(player)); + switch (quest.getStage(player)) { + case 20: + npc("Great, you have the Snake Weed! Many thanks. Ok,", "the next herb is called " + objective.getName() + ". It is related to the palm", "and crows to the east in its brother's shady profusion."); + stage = 200; + break; + case 30: + npc("Great, you have the Ardrigal! Many thanks."); + stage = 300; + break; + case 40: + npc("Well done Bwana, just two more herbs to collect."); + stage = 400; + break; + case 50: + npc("Ah Volencia Moss, beautiful. One final herb and the", "potion will be complete."); + stage = 500; + break; + } + break; + case 200: + npc("To the east you will find a small peninsula, it is just", "after the cliffs come down to meet the sands, here is", "where you should search for it."); + ; + stage++; + break; + case 201: + end(); + break; + case 300: + npc("You are doing well Bwana. The next herb is called Sito", "Foil, and it grows best where the ground has been", "blackened by the living flame."); + stage++; + break; + case 301: + end(); + break; + case 400: + npc("The next herb is called Volencia Moss. It clings to", "rocks for its existence. It is difficult to see, so you", "must search for it well."); + stage++; + break; + case 401: + npc("It prefers rocks of high metal content and a frequently", "disturbed environment. There is some, I believe to the", "south east of this village."); + stage++; + break; + case 402: + end(); + break; + case 500: + npc("This is the most difficult to find as it is inhabits the", "darkness of the underground. It is called Rogues", "Purse, and is only to be found in caverns"); + stage++; + break; + case 501: + npc("in the northern part of this island. A secret entrance to", "the caverns is set int the northern cliffs of this land.", "Take care Bwana as it may be dangerous."); + stage++; + break; + case 502: + end(); + break; + } + break; + case 60: + switch (stage) { + case 50: + npc("Most excellent Bwana! You have returned all the herbs", "to me and, I can finish the preparations for the potion,", "and at last divine with the gods."); + stage = 600; + break; + case 600: + npc("Many blessings on you! I must now prepare, please", "excuse me while I make the arrangements."); + stage = -1; + break; + case -1: + interpreter.sendDialogue("Trufitus shows you some techniques in Herblore. You gain some", "experience in Herblore."); + stage++; + break; + case 0: + quest.finish(player); + end(); + break; + } + break; + case 100: + switch (stage) { + case 0: + npc("looks good for my people. We are happy now that the", "gods are not angry with us."); + stage++; + break; + case 1: + npc("With some blessings we will be safe here."); + stage++; + break; + case 2: + npc("You should deliver the good news to Bwana Timfraku,", "Chief of Tai Bwo Wannai. He lives in a raised hut not", "far from here."); + stage++; + break; + case 3: + end(); + break; + case 10: + npc("Greetings! I hope things are going well for you now.", "I have no new information since we last spoke."); + stage++; + break; + case 11: + npc("Needless to say, that if something does come up I", "will certainly get in touch directly."); + stage = 3; + break; + } + break; + } + return true; + } + //merlin + //ptreas + //prince alli + //roving elves + + @Override + public int[] getIds() { + return new int[]{740}; + } + +} diff --git a/Server/src/main/content/region/karamja/quest/tribaltotem/ArdougneGuideBook.kt b/Server/src/main/content/region/karamja/quest/tribaltotem/ArdougneGuideBook.kt new file mode 100644 index 0000000..74ce79e --- /dev/null +++ b/Server/src/main/content/region/karamja/quest/tribaltotem/ArdougneGuideBook.kt @@ -0,0 +1,124 @@ +package content.region.karamja.quest.tribaltotem + +import content.global.handlers.iface.BookInterface +import content.global.handlers.iface.BookLine +import content.global.handlers.iface.Page +import content.global.handlers.iface.PageSet +import core.api.setAttribute +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import org.rs09.consts.Items + +/** + * Ardougne Guide Book + * https://www.youtube.com/watch?v=-Qburz3T00o + * @author ovenbreado + * @author Splinter + * @author Phil + */ +class ArdougneGuideBook : InteractionListener { + companion object { + private val TITLE = "Tourist Guide to Ardougne" + private val CONTENTS = arrayOf( + PageSet( + Page( + BookLine("Introduction", 57), + BookLine("This book is your guide to", 59), + BookLine("the vibrant city of Ardougne.", 60), + BookLine("Ardougne is known as an", 61), + BookLine("exciting modern city located", 62), + BookLine("on the sun drenched southern", 63), + BookLine("coast of Kandarin", 64), + ), + Page( + BookLine("Ardougne: City of Shopping!", 66), + BookLine("Come sample the delights of", 67), + BookLine("the Ardougne market - the", 68), + BookLine("biggest in the known world!", 69), + BookLine("From spices to silk, there", 70), + BookLine("is something here for", 71), + BookLine("everybody! Other popular", 72), + BookLine("shopping destinations in", 73), + BookLine("the area include the Armoury", 74), + BookLine("and the ever popular", 75), + BookLine("Adventurers' supply store.", 76) + ) + ), + PageSet( + Page( + BookLine("Ardougne: City of Fun!", 55), + BookLine("If you're looking for", 56), + BookLine("entertainment in Ardougne,", 57), + BookLine("why not pay a visit to the", 58), + BookLine("Ardougne City zoo? Or relax", 59), + BookLine("with a drink in the ever", 60), + BookLine("popular Flying Horse Inn?", 61), + BookLine("And for the adventurous,", 62), + BookLine("there are always rats to be", 63), + BookLine("slaughtered in the expansive", 64), + BookLine("and vermin-ridden sewers", 65) + ), + Page( + BookLine("There is something truly", 66), + BookLine("for everybody here!", 67) + ) + ), + PageSet( + Page( + BookLine("Ardougne: City of History!", 55), + BookLine("Ardougne is renowned as an", 56), + BookLine("important city of historical", 57), + BookLine("interest. One historic building", 58), + BookLine("is the magnificent Handelmort", 59), + BookLine("Mansion, currently owned by", 60), + BookLine("Lord Francis Kurt Handelmort.", 61), + BookLine("Also of historical interest is", 62), + BookLine("Ardougne Castle in the east of", 63), + BookLine("the city recently opened to the", 64), + BookLine("public. And of course the Holy", 65) + ), + Page( + BookLine("Order of Paladins still wander", 66), + BookLine("the streets of Ardougne, and", 67), + BookLine("are often of interest to", 68), + BookLine("tourists.", 69) + ) + ), + PageSet( + Page( + BookLine("Further Fields", 55), + BookLine("", 56), + BookLine("The area surrounding Ardougne", 57), + BookLine("is also of great interest to", 58), + BookLine("the cultural tourist. If you", 59), + BookLine("want to go further afield, why", 60), + BookLine("not have a look at the ominous", 61), + BookLine("Pillars of Zanash, the", 62), + BookLine("mysterious marble pillars", 63), + BookLine("located just West of the city?", 64), + BookLine("Or perhaps the town of Brimhaven,", 65) + ), + Page( + BookLine("on the exotic island of Karamja?", 66), + BookLine("It's only a short boat trip with", 67), + BookLine("regular transport leaving from", 68), + BookLine("Ardougne harbor at all times", 69), + BookLine("of the day, all year round.", 70) + ) + ) + ) + + private fun display(player:Player, pageNum: Int, buttonID: Int) : Boolean { + BookInterface.pageSetup(player, BookInterface.FANCY_BOOK_3_49, TITLE, CONTENTS) + return true + } + } + + override fun defineListeners() { + on(Items.GUIDE_BOOK_1856, IntType.ITEM, "read") { player, _ -> + BookInterface.openBook(player, BookInterface.FANCY_BOOK_3_49, ::display) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/karamja/quest/tribaltotem/CrompertyDialogue.kt b/Server/src/main/content/region/karamja/quest/tribaltotem/CrompertyDialogue.kt new file mode 100644 index 0000000..54ec527 --- /dev/null +++ b/Server/src/main/content/region/karamja/quest/tribaltotem/CrompertyDialogue.kt @@ -0,0 +1,135 @@ +package content.region.karamja.quest.tribaltotem + +import core.game.node.entity.impl.Projectile +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import core.plugin.Initializable +import org.rs09.consts.NPCs +import content.global.travel.EssenceTeleport +import core.ServerConstants +import core.api.playAudio +import core.game.world.GameWorld +import org.rs09.consts.Sounds +import content.data.Quests + +@Initializable +class CrompertyDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npcl(core.game.dialogue.FacialExpression.HAPPY,"Hello, ${player.username}, I'm Cromperty. Sedridor has told me about you. As a wizard and an inventor he has aided me in my great invention!") + stage = 0 + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> options("Two jobs? that's got to be tough","So what have you invented?","Can you teleport me to the Rune Essence?").also { stage++ } + 1 -> when(buttonId){ + 1 -> playerl(core.game.dialogue.FacialExpression.HAPPY,"Two jobs? That's got to be tough.").also { stage = 5 } + 2 -> playerl(core.game.dialogue.FacialExpression.ASKING,"So, what have you invented?").also { stage = 10 } + 3 -> playerl(core.game.dialogue.FacialExpression.HAPPY,"Can you teleport me to the Rune Essence?").also { + if(player.questRepository.isComplete(Quests.RUNE_MYSTERIES)){ + EssenceTeleport.teleport(npc,player) + end() + } + else stage = 2 + } + } + 2 -> npcl(core.game.dialogue.FacialExpression.THINKING,"I have no idea what you're talking about.") + 5 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Not when you combine them it isn't! Invent MAGIC things!").also { stage++ } + 6 -> options("So what have you invented?","Well I shall leave you to your inventing").also { stage++ } + 7 -> when(buttonId){ + 1 -> playerl(core.game.dialogue.FacialExpression.ASKING,"So, what have you invented?").also { stage = 10 } + 2 -> playerl(core.game.dialogue.FacialExpression.HAPPY,"Well I shall leave you to your inventing").also { stage++ } + } + 8 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Thanks for dropping by! Stop again anytime!").also { stage = 1000 } + + 10 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Ah! My latest invention is my patent pending teleportation block! It emits a low level magical signal,").also { stage++ } + 11 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"that will allow me to locate it anywhere in the world, and teleport anything directly to it! I hope to revolutionize the entire teleportation system!").also { stage++ } + 12 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Don't you think I'm great? Uh, I mean it's great?").also { stage++ } + 13 -> options("So where is the other block?","Can I be teleported please?").also { stage++ } + 14 -> when(buttonId){ + 1 -> playerl(core.game.dialogue.FacialExpression.ASKING,"So where is the other block?").also { stage = 15 } + 2 -> playerl(core.game.dialogue.FacialExpression.ASKING,"Can I be teleported please?").also { stage = 25 } + } + + 15 -> npcl(core.game.dialogue.FacialExpression.THINKING,"Well... Hmm. I would guess somewhere between here and the Wizards' Tower in Misthalin.").also { stage++ } + 16 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"All I know is that it hasn't got there yet as the wizards there would have contacted me.").also { stage++ } + 17 -> npcl(core.game.dialogue.FacialExpression.THINKING,"I'm using the RPDT for delivery. They assured me it would be delivered promptly.").also { stage++ } + 18 -> playerl(core.game.dialogue.FacialExpression.ASKING,"Who are the RPDT?").also { stage++ } + 19 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"The ${ServerConstants.SERVER_NAME} Parcel Delivery Team. They come very highly recommended.").also { stage++ } + 20 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Their motto is: \"We aim to deliver your stuff at some point after you have paid us!\"").also { stage = 1000 } + + 25 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"By all means! I'm afraid I can't give you any specifics as to where you will come out however. Presumably wherever the other block is located.").also { stage++ } + 26 -> options("Yes, that sounds good. Teleport me!","That sounds dangerous. Leave me here.").also { stage++ } + 27 -> when(buttonId){ + 1 -> playerl(core.game.dialogue.FacialExpression.HAPPY,"Yes, that sounds good. Teleport me!").also { stage = 30 } + 2 -> playerl(core.game.dialogue.FacialExpression.THINKING,"That sounds dangerous. Leave me here.").also { stage++ } + } + 28 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"As you wish.").also { stage = 1000 } + + 30 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Okey dokey! Ready?").also { + stage = if(player.questRepository.hasStarted(Quests.TRIBAL_TOTEM) && player.questRepository.getStage(Quests.TRIBAL_TOTEM) < 50) { + 35 + } + else 31 + } + 31 -> npcl(core.game.dialogue.FacialExpression.THINKING,"Hmmm... that's odd... I can't seem to get a signal...").also { stage++ } + 32 -> playerl(core.game.dialogue.FacialExpression.SAD,"Oh well, never mind.").also { stage = 1000 } + + 35 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Okay, I got a signal. Get ready!").also { + TribalTotemTeleport(player, npc) + end() + } + + 1000 -> end() + } + return true + } + + override fun newInstance(player: Player?): core.game.dialogue.DialoguePlugin { + return CrompertyDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(844,NPCs.WIZARD_CROMPERTY_2328) + } + + fun TribalTotemTeleport(player : Player, npc: NPC) { + val LOCATIONS = arrayOf(Location.create(2649, 3272, 0),Location.create(2642, 3321, 0)) + npc.animate(Animation(437)) + npc.faceTemporary(player, 1) + npc.graphics(Graphics(108)) + player.lock() + playAudio(player, Sounds.CURSE_ALL_125, 0, 1) + Projectile.create(npc, player, 109).send() + npc.sendChat("Dipsolum sententa sententi!") + GameWorld.Pulser.submit(object : Pulse(1) { + var counter = 0 + var delivered = player.questRepository.getStage(Quests.TRIBAL_TOTEM) >= 25 + override fun pulse(): Boolean { + when(counter++){ + 2 -> { + if(delivered) { + player.questRepository.getQuest(Quests.TRIBAL_TOTEM).setStage(player,30) + player.properties.teleportLocation = LOCATIONS[1] + } + else player.properties.teleportLocation = LOCATIONS[0] + } + 3 ->{ + player.graphics(Graphics(110)) + player.unlock() + return true + } + } + return false + } + }) + } +} + diff --git a/Server/src/main/content/region/karamja/quest/tribaltotem/HoracioDialogue.kt b/Server/src/main/content/region/karamja/quest/tribaltotem/HoracioDialogue.kt new file mode 100644 index 0000000..09cc8ae --- /dev/null +++ b/Server/src/main/content/region/karamja/quest/tribaltotem/HoracioDialogue.kt @@ -0,0 +1,59 @@ +package content.region.karamja.quest.tribaltotem + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import content.data.Quests + +@Initializable +class HoracioDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + if(player.questRepository.hasStarted(Quests.TRIBAL_TOTEM)){ + npcl(FacialExpression.HAPPY,"It's a fine day to be out in a garden, isn't it? ") + stage = 5 + } + else{ + npcl(FacialExpression.HAPPY,"It's a fine day to be out in a garden, isn't it? ") + stage = 0 + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> playerl(FacialExpression.HAPPY,"Yes it's very nice.").also { stage++ } + 1 -> npcl(FacialExpression.HAPPY,"Days like these make me glad to be alive!").also { stage = 1000 } + + 5 -> playerl(FacialExpression.ASKING,"So... who are you?").also { stage++ } + 6 -> npcl(FacialExpression.HAPPY,"My name is Horacio Dobson. I'm a gardener to Lord Handlemort.").also { stage++ } + 7 -> npcl(FacialExpression.HAPPY,"Take a look around this beautiful garden, all of this is my handiwork.").also { stage++ } + 8 -> options("So... do you garden round the back too?","Do you need any help?").also { stage++ } + 9 -> when(buttonId){ + 1 -> playerl(FacialExpression.THINKING,"So... do you garden round the back, too?").also { stage = 10 } + 2 -> playerl(FacialExpression.ASKING,"Do you need any help?").also { stage = 20 } + } + + 10 -> npcl(FacialExpression.HAPPY,"That I do!").also { stage++ } + 11 -> playerl(FacialExpression.ASKING,"Doesn't all of the security around the house get in your way then?").also { stage++ } + 12 -> npcl(FacialExpression.HAPPY,"Ah. I'm used to all that. I have my keys, the guard dogs know me, and I know the combination to the door lock.").also { stage++ } + 13 -> npcl(FacialExpression.HAPPY,"It's rather easy, it's his middle name.").also { stage++ } + 14 -> playerl(FacialExpression.ASKING,"Whose middle name?").also { stage++ } + 15 -> npcl(FacialExpression.ANNOYED,"Hum. I probably shouldn't have said that. Forget I mentioned it.").also { stage = 1000 } + + 20 -> npcl(FacialExpression.ANNOYED,"Trying to muscle in on my job, eh? I'm more than happy to do this all by myself!").also { stage = 1000 } + + 1000 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return HoracioDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(845) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/karamja/quest/tribaltotem/KangaiMauDialogue.kt b/Server/src/main/content/region/karamja/quest/tribaltotem/KangaiMauDialogue.kt new file mode 100644 index 0000000..1e72fbd --- /dev/null +++ b/Server/src/main/content/region/karamja/quest/tribaltotem/KangaiMauDialogue.kt @@ -0,0 +1,92 @@ +package content.region.karamja.quest.tribaltotem + +import core.api.isQuestComplete +import core.api.removeItem +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import content.data.Quests + +@Initializable +class KangaiMauDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + if(!player.questRepository.hasStarted(Quests.TRIBAL_TOTEM)){ + npcl(FacialExpression.HAPPY,"Hello. I'm Kangai Mau of the Rantuki Tribe.") + stage = 0 + } else if(isQuestComplete(player, Quests.TRIBAL_TOTEM)) { + npcl(FacialExpression.HAPPY, "Many greetings esteemed thief.") + stage = 40 + } + else if(player.inventory.containsAtLeastOneItem(Items.TOTEM_1857)){ + npcl(FacialExpression.ASKING,"Have you got our totem back?") + stage = 35 + } + else if(player.questRepository.hasStarted(Quests.TRIBAL_TOTEM)){ + npcl(FacialExpression.ASKING,"Have you got our totem back?") + stage = 30 + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> options("And what are you doing here in Brimhaven?","I'm in search of adventure!","Who are the Rantuki tribe?").also { stage++ } + 1 -> when(buttonId){ + 1 -> playerl(FacialExpression.ASKING,"And what are you doing here in Brimhaven?").also { stage = 5 } + 2 -> playerl(FacialExpression.HAPPY,"I'm in search of adventure!").also { stage = 15 } + 3 -> playerl(FacialExpression.ASKING,"Who are the Rantuki Tribe?").also { stage = 10 } + } + + 5 -> npcl(FacialExpression.HAPPY,"I'm looking for someone brave to go on important mission. Someone skilled in thievery and sneaking about.").also { stage++ } + 6 -> npcl(FacialExpression.HAPPY,"I am told I can find such people in Brimhaven.").also { stage++ } + 7 -> playerl(FacialExpression.HAPPY,"Yep. I have heard there are many of that type here.").also { stage++ } + 8 -> npcl(FacialExpression.THINKING,"Let's hope I find them.").also { stage = 1000 } + + 10 -> npcl(FacialExpression.HAPPY,"A proud and noble tribe of Karamja.").also { stage++ } + 11 -> npcl(FacialExpression.ANGRY,"But now we are few, as men come from across, steal our land, and settle on our hunting grounds").also { stage = 1000 } + + 15 -> npcl(FacialExpression.HAPPY,"Adventure is something I may be able to give. I need someone to go on a mission to the city of Ardougne.").also { stage++ } + 16 -> npcl(FacialExpression.HAPPY,"There you will find the house of Lord Handlemort. In his house he has our tribal totem. We need it back.").also { stage++ } + 17 -> playerl(FacialExpression.ASKING,"Why does he have it?").also { stage++ } + 18 -> npcl(FacialExpression.ANGRY,"Lord Handlemort is an Ardougnese explorer which means he think he have the right to come to my tribal home,").also { stage++ } + 19 -> npcl(FacialExpression.ANGRY,"steal our stuff and put in his private museum.").also { stage++ } + 20 -> playerl(FacialExpression.THINKING,"How can I find Handlemoret's house? Ardougne IS a big place...").also { stage++ } + 21 -> npcl(FacialExpression.ANNOYED,"I don't know Ardougne. You tell me.").also { stage++ } + 22 -> playerl(FacialExpression.HAPPY,"Ok, I will get it back.").also { + player.questRepository.getQuest(Quests.TRIBAL_TOTEM).start(player) + player.questRepository.getQuest(Quests.TRIBAL_TOTEM).setStage(player, 10) + stage++ + } + 23 -> npcl(FacialExpression.HAPPY,"Best of luck with that adventurer").also { stage = 1000 } + + 30 -> playerl(FacialExpression.SAD,"Not yet, sorry.").also { stage = 1000 } + + 35 -> playerl(FacialExpression.HAPPY,"Yes I have.").also { stage++ } + 36 -> npcl(FacialExpression.HAPPY,"You have??? Many thanks brave adventurer! Here, have some freshly cooked Karamjan fish, caught specially by my tribe.").also { stage++ } + 37 -> sendDialogue("You hand over the totem").also { + if(!isQuestComplete(player, Quests.TRIBAL_TOTEM) && removeItem(player, Items.TOTEM_1857)) { + player.questRepository.getQuest(Quests.TRIBAL_TOTEM).finish(player) + stage = 1000 + } else { + stage = 1000 + } + } + + 40 -> player(FacialExpression.NEUTRAL, "Hey.").also { stage = 1000 } + + 1000 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return KangaiMauDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(846) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/karamja/quest/tribaltotem/RPDTEmployeeDialogue.kt b/Server/src/main/content/region/karamja/quest/tribaltotem/RPDTEmployeeDialogue.kt new file mode 100644 index 0000000..2bd9330 --- /dev/null +++ b/Server/src/main/content/region/karamja/quest/tribaltotem/RPDTEmployeeDialogue.kt @@ -0,0 +1,42 @@ +package content.region.karamja.quest.tribaltotem + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs +import content.data.Quests + +@Initializable +class RPDTEmployeeDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun open(vararg args: Any?): Boolean { + npcl(FacialExpression.HAPPY,"Welcome to R.P.D.T.!") + stage = if(player.questRepository.getStage(Quests.TRIBAL_TOTEM) == 20){ + 5 + }else 0 + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> playerl(FacialExpression.HAPPY,"Thank you very much.").also { stage = 1000 } + + 5 -> playerl(FacialExpression.ASKING,"So, when are you going to deliver this crate?").also { stage++ } + 6 -> npcl(FacialExpression.THINKING,"Well... I guess we could do it now...").also { + player.questRepository.getQuest(Quests.TRIBAL_TOTEM).setStage(player,25) + stage = 1000 + } + + 1000 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return RPDTEmployeeDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.RPDT_EMPLOYEE_843) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/karamja/quest/tribaltotem/TTDoorCodeInterfaceListener.kt b/Server/src/main/content/region/karamja/quest/tribaltotem/TTDoorCodeInterfaceListener.kt new file mode 100644 index 0000000..372a51f --- /dev/null +++ b/Server/src/main/content/region/karamja/quest/tribaltotem/TTDoorCodeInterfaceListener.kt @@ -0,0 +1,146 @@ +package content.region.karamja.quest.tribaltotem + +import core.api.closeInterface +import core.api.sendMessage +import core.api.setInterfaceText +import core.game.world.map.Location +import core.game.interaction.InterfaceListener + +class TTDoorCodeInterfaceListener : InterfaceListener { + + override fun defineInterfaceListeners() { + val LETTERONEBACK = 17 + val LETTERONEFORWARD = 18 + val LETTERTWOBACK = 19 + val LETTERTWOFORWARD = 20 + val LETTERTHREEBACK = 21 + val LETTERTHREEFORWARD = 22 + val LETTERFOURBACK = 23 + val LETTERFOURFORWARD = 24 + val ENTER = 27 + val EXIT = 28 + val DOORLOCKINTERFACE = 369 + val LETTERS = arrayOf("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z") + + onOpen(DOORLOCKINTERFACE) { player, component -> + player.setAttribute("tt-letter-one", 0) + player.setAttribute("tt-letter-two", 0) + player.setAttribute("tt-letter-three", 0) + player.setAttribute("tt-letter-four", 0) + return@onOpen true + } + + onClose(DOORLOCKINTERFACE) { player, component -> + player.removeAttribute("tt-letter-one") + player.removeAttribute("tt-letter-two") + player.removeAttribute("tt-letter-three") + player.removeAttribute("tt-letter-four") + return@onClose true + } + + on(DOORLOCKINTERFACE) { player, component, opcode, buttonID, slot, itemID -> + when (buttonID) { + LETTERONEBACK -> { + if (player.getAttribute("tt-letter-one", 0) == 0) { + player.setAttribute("tt-letter-one", 25) + setInterfaceText(player, LETTERS[player.getAttribute("tt-letter-one", 0)], DOORLOCKINTERFACE, 13) + } else { + (player.incrementAttribute("tt-letter-one", -1)) + setInterfaceText(player, LETTERS[player.getAttribute("tt-letter-one", 0)], DOORLOCKINTERFACE, 13) + } + } + + LETTERONEFORWARD -> { + if (player.getAttribute("tt-letter-one", 0) == 25) { + player.setAttribute("tt-letter-one", 0) + setInterfaceText(player, LETTERS[player.getAttribute("tt-letter-one", 0)], DOORLOCKINTERFACE, 13) + } else { + (player.incrementAttribute("tt-letter-one", 1)) + setInterfaceText(player, LETTERS[player.getAttribute("tt-letter-one", 0)], DOORLOCKINTERFACE, 13) + } + } + + LETTERTWOBACK -> { + if (player.getAttribute("tt-letter-two", 0) == 0) { + player.setAttribute("tt-letter-two", 25) + setInterfaceText(player, LETTERS[player.getAttribute("tt-letter-two", 0)], DOORLOCKINTERFACE, 14) + } else { + (player.incrementAttribute("tt-letter-two", -1)) + setInterfaceText(player, LETTERS[player.getAttribute("tt-letter-two", 0)], DOORLOCKINTERFACE, 14) + } + } + + LETTERTWOFORWARD -> { + if (player.getAttribute("tt-letter-two", 0) == 25) { + player.setAttribute("tt-letter-two", 0) + setInterfaceText(player, LETTERS[player.getAttribute("tt-letter-two", 0)], DOORLOCKINTERFACE, 14) + } else { + (player.incrementAttribute("tt-letter-two", 1)) + setInterfaceText(player, LETTERS[player.getAttribute("tt-letter-two", 0)], DOORLOCKINTERFACE, 14) + } + } + + LETTERTHREEBACK -> { + if (player.getAttribute("tt-letter-three", 0) == 0) { + player.setAttribute("tt-letter-three", 25) + setInterfaceText(player, LETTERS[player.getAttribute("tt-letter-three", 0)], DOORLOCKINTERFACE, 15) + } else { + (player.incrementAttribute("tt-letter-three", -1)) + setInterfaceText(player, LETTERS[player.getAttribute("tt-letter-three", 0)], DOORLOCKINTERFACE, 15) + } + } + + LETTERTHREEFORWARD -> { + if (player.getAttribute("tt-letter-three", 0) == 25) { + player.setAttribute("tt-letter-three", 0) + setInterfaceText(player, LETTERS[player.getAttribute("tt-letter-three", 0)], DOORLOCKINTERFACE, 15) + } else { + (player.incrementAttribute("tt-letter-three", 1)) + setInterfaceText(player, LETTERS[player.getAttribute("tt-letter-three", 0)], DOORLOCKINTERFACE, 15) + } + } + + LETTERFOURBACK -> { + if (player.getAttribute("tt-letter-four", 0) == 0) { + player.setAttribute("tt-letter-four", 25) + setInterfaceText(player, LETTERS[player.getAttribute("tt-letter-four", 0)], DOORLOCKINTERFACE, 16) + } else { + (player.incrementAttribute("tt-letter-four", -1)) + setInterfaceText(player, LETTERS[player.getAttribute("tt-letter-four", 0)], DOORLOCKINTERFACE, 16) + } + } + + LETTERFOURFORWARD -> { + if (player.getAttribute("tt-letter-four", 0) == 25) { + player.setAttribute("tt-letter-four", 0) + setInterfaceText(player, LETTERS[player.getAttribute("tt-letter-four", 0)], DOORLOCKINTERFACE, 16) + } else { + (player.incrementAttribute("tt-letter-four", 1)) + setInterfaceText(player, LETTERS[player.getAttribute("tt-letter-four", 0)], DOORLOCKINTERFACE, 16) + } + } + + ENTER -> { + val letterOne = LETTERS[player.getAttribute("tt-letter-one", 0)] + val letterTwo = LETTERS[player.getAttribute("tt-letter-two", 0)] + val letterThree = LETTERS[player.getAttribute("tt-letter-three", 0)] + val letterFour = LETTERS[player.getAttribute("tt-letter-four", 0)] + + if (letterOne == "K" && letterTwo == "U" && letterThree == "R" && letterFour == "T") { + player.setAttribute("/save:TT:DoorUnlocked",true) + sendMessage(player, "You hear a satisfying click, signifying that the door has been unlocked") + closeInterface(player) + } + else { + sendMessage(player,"You hear a satisfying click, and then a worrying thunk.") + sendMessage(player,"The floor opens up beneath you sending you plummeting down") + sendMessage(player,"to the sewers.") + player.teleport(Location.create(2641, 9721, 0)) + closeInterface(player) + } + } + } + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/karamja/quest/tribaltotem/TribalTotemListeners.kt b/Server/src/main/content/region/karamja/quest/tribaltotem/TribalTotemListeners.kt new file mode 100644 index 0000000..33ab1eb --- /dev/null +++ b/Server/src/main/content/region/karamja/quest/tribaltotem/TribalTotemListeners.kt @@ -0,0 +1,108 @@ +package content.region.karamja.quest.tribaltotem + +import core.api.* +import core.game.node.entity.skill.Skills +import core.game.node.scenery.SceneryBuilder +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import content.data.Quests + +class TribalTotemListeners : InteractionListener { + + val frontDoor = 2706 + val wizCrate = 2707 + val realCrate = 2708 + val label = Items.ADDRESS_LABEL_1858 + val lockedDoor = 2705 + val stairs = 2711 + val closedChest = 2709 + val openChest = 2710 + + override fun defineListeners() { + on(frontDoor, IntType.SCENERY, "Open"){ player, door -> + if(player.questRepository.getStage(Quests.TRIBAL_TOTEM) >= 35){ + core.game.global.action.DoorActionHandler.handleAutowalkDoor(player,door.asScenery()) + } + sendMessage(player,"The door is locked shut.") + return@on true + } + + on(realCrate, IntType.SCENERY, "Investigate"){ player, node -> + if(player.questRepository.getStage(Quests.TRIBAL_TOTEM) in 1..19 && !player.inventory.containsAtLeastOneItem(Items.ADDRESS_LABEL_1858)){ + sendDialogue(player,"There is a label on this crate. It says; To Lord Handelmort, Handelmort Mansion Ardogune.You carefully peel it off and take it.") + addItem(player,Items.ADDRESS_LABEL_1858,1) + } + else if(player.questRepository.getStage(Quests.TRIBAL_TOTEM) in 1..19 && player.inventory.containsAtLeastOneItem(Items.ADDRESS_LABEL_1858)){ + sendDialogue(player,"There was a label on this crate, but it's gone now since you took it!") + } + return@on true + } + + on(wizCrate, IntType.SCENERY, "Investigate"){ player, node -> + sendDialogue(player,"There is a label on this crate: Senior Patents Clerk, Chamber of Invention, The Wizards' Tower, Misthalin. The crate is securely fastened shut and ready for delivery.") + return@on true + } + + onUseWith(IntType.SCENERY,label,wizCrate){ player, used, with -> + sendDialogue(player,"You carefully place the delivery address label over the existing label, covering it completely.") + removeItem(player,label) + player.questRepository.getQuest(Quests.TRIBAL_TOTEM).setStage(player,20) + return@onUseWith true + } + + on(lockedDoor, IntType.SCENERY, "Open"){ player, node -> + if(player.getAttribute("TT:DoorUnlocked",false) == true){ + core.game.global.action.DoorActionHandler.handleAutowalkDoor(player,node.asScenery()) + }else{ + openInterface(player,369) + } + return@on true + } + + on(stairs, IntType.SCENERY, "Climb-up"){ player, node -> + if(player.getAttribute("TT:StairsChecked",false)){ + core.game.global.action.ClimbActionHandler.climb(player, Animation(828), Location.create(2629, 3324, 1)) + } + else{ + sendMessage(player,"You set off a trap and the stairs give way under you, dropping you into the sewers.") + player.teleport(Location.create(2641, 9721, 0)) + } + return@on true + } + + on(stairs, IntType.SCENERY, "Investigate"){ player, node -> + if(player.getSkills().getStaticLevel(Skills.THIEVING) >= 21){ + sendDialogue(player,"Your trained senses as a thief enable you to see that there is a trap in these stairs. You make a note of its location for future reference when using these stairs") + player.setAttribute("/save:TT:StairsChecked",true) + }else{ + sendDialogue(player,"You don't see anything out of place on these stairs.") + } + return@on true + } + + on(closedChest, IntType.SCENERY, "Open"){ player, node -> + SceneryBuilder.replace(node.asScenery(), node.asScenery().transform(2710)) + return@on true + } + + on(openChest, IntType.SCENERY, "Close"){ player, node -> + SceneryBuilder.replace(node.asScenery(), node.asScenery().transform(2709)) + return@on true + } + + on(openChest, IntType.SCENERY, "Search"){ player, node -> + if(!player.inventory.containsAtLeastOneItem(Items.TOTEM_1857)){ + sendDialogue(player,"Inside the chest you find the tribal totem.") + addItem(player,Items.TOTEM_1857) + } + else{ + sendDialogue(player,"Inside the chest you don't find anything because you already took the totem!") + } + return@on true + } + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/karamja/quest/tribaltotem/TribalTotemQuest.kt b/Server/src/main/content/region/karamja/quest/tribaltotem/TribalTotemQuest.kt new file mode 100644 index 0000000..13c0775 --- /dev/null +++ b/Server/src/main/content/region/karamja/quest/tribaltotem/TribalTotemQuest.kt @@ -0,0 +1,83 @@ +package content.region.karamja.quest.tribaltotem + +import core.api.rewardXP +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import core.plugin.Initializable +import org.rs09.consts.Items +import content.data.Quests + +@Initializable +class TribalTotem : Quest(Quests.TRIBAL_TOTEM,126,125,1,200,0,1,5){ + class SkillRequirement(val skill: Int?, val level: Int?) + + val requirements = arrayListOf() + + override fun drawJournal(player: Player?, stage: Int) { + super.drawJournal(player, stage) + var line = 11 + val started = player?.questRepository?.getStage(Quests.TRIBAL_TOTEM)!! > 0 + + if(!started){ + line(player,"I can start this quest by speaking to !!Kangai Mau?? in",line++) + line(player,"!!Shrimp & Parrot?? restaurant in Brimhaven.",line++) + line += 1 + line(player,"To complete this quest I need:",line++) + line(player,"!!Level 21 Theiving??",line++, player?.skills?.getStaticLevel(Skills.THIEVING)!! >= 21) + } + else if(started && stage != 100){ + if(stage >= 10){ + line(player,"I agreed to help !!Kangai Mau?? on Brimhaven recover",line++,stage>15) + line(player,"the tribal totem stolen from his village by",line++,stage>15) + line(player,"!!Lord Handelmort??.",line++,stage>10) + } + if(stage >= 20){ + line(player,"I found a package due for delivery to !!Lord Handelmort??",line++,stage>25) + line(player,"at the !!G.P.D.T. Depot??, and swapped the label for the",line++,stage>25) + line(player,"!!Wizard Cromperty's?? experimental teleport block.",line++,stage>25) + } + if(stage >= 30){ + line(player,"I got the !!G.P.D.T.?? men to deliver the teleport block to",line++,stage>35) + line(player,"!!Lord Handelmort?? and teleported myself inside.",line++,stage>35) + } + } + else if(stage == 100){ + if(stage == 100){ + line(player,"After bypassing the traps and security inside the mansion I was able",line++) + line(player,"to reclaim the totem, and take it back to !!Kangai Mau??, who rewarded",line++) + line(player,"me for all of my help.",line++) + line += 1 + line(player,"QUEST COMPLETE!",line++ +1) + } + } + } + + override fun finish(player: Player?) { + super.finish(player) + player ?: return + var ln = 10 + player.packetDispatch.sendItemZoomOnInterface(Items.TOTEM_1857,230,277,5) + drawReward(player,"1 Quest point",ln++) + drawReward(player,"1,775 Thieving XP",ln++) + drawReward(player,"5 Swordfish",ln++) + rewardXP(player,Skills.THIEVING,1775.0) + if(!player.inventory.add(Item(Items.SWORDFISH_373,5))){ + GroundItemManager.create(Item(Items.SWORDFISH_373,5),player) + } + cleanTTAttributes(player) + } + + override fun newInstance(`object`: Any?): Quest { + requirements.add(SkillRequirement(Skills.THIEVING, 21)) + return this + } + + private fun cleanTTAttributes(player: Player){ + player.removeAttribute("TT:StairsChecked") + player.removeAttribute("TT:DoorUnlocked") + } + +} diff --git a/Server/src/main/content/region/karamja/shilo/dialogue/CrumpledScroll.kt b/Server/src/main/content/region/karamja/shilo/dialogue/CrumpledScroll.kt new file mode 100644 index 0000000..fc35f25 --- /dev/null +++ b/Server/src/main/content/region/karamja/shilo/dialogue/CrumpledScroll.kt @@ -0,0 +1,37 @@ +package content.region.karamja.shilo.dialogue + +import core.api.openInterface +import core.api.setInterfaceText +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import org.rs09.consts.Items + +class CrumpledScroll : InteractionListener { + // Receive during the Shilo Village quest. + companion object { + private const val MESSAGE_SCROLL = 222 + val CRUMPLED_SCROLL_TEXT = arrayOf( + "Rashiliyia's rage went unchecked. She killed", + "", + "without mercy for revenge of her son's life. Like", + "", + "a spectre through the night she entered houses", + "", + "and one by one quietly strangled life from the", + "", + "occupants. It is said that only a handful survived,", + "", + "protected by the necklace wards to keep the Witch", + "", + "Queen at bay." + ) + } + + override fun defineListeners() { + on(Items.CRUMPLED_SCROLL_608, IntType.ITEM, "read") { player, _ -> + openInterface(player, MESSAGE_SCROLL) + setInterfaceText(player, CRUMPLED_SCROLL_TEXT.joinToString("
"), MESSAGE_SCROLL, 3) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/karamja/shilo/dialogue/FernaheiDialogue.kt b/Server/src/main/content/region/karamja/shilo/dialogue/FernaheiDialogue.kt new file mode 100644 index 0000000..3a2655a --- /dev/null +++ b/Server/src/main/content/region/karamja/shilo/dialogue/FernaheiDialogue.kt @@ -0,0 +1,55 @@ +package content.region.karamja.shilo.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class FernaheiDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npc(FacialExpression.FRIENDLY,"Welcome to Fernahei's Fishing Shop Bwana!", + "Would you like to see my items?").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> { + options("Yes please!", "No, but thanks for the offer.").also { stage++ } + } + + 1 -> when (buttonId) { + 1 -> player(FacialExpression.FRIENDLY, "Yes, please.").also { stage = 10 } + 2 -> player(FacialExpression.FRIENDLY, "No, but thanks for the offer.").also { stage = 20 } + } + + 10 -> { + end().also { npc.openShop(player) } + } + + 20 -> { + npc(FacialExpression.FRIENDLY, "That's fine, and thanks for your interest.").also { stage = 99 } + } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return FernaheiDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.FERNAHEI_517) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/karamja/shilo/dialogue/KalebParamaya.java b/Server/src/main/content/region/karamja/shilo/dialogue/KalebParamaya.java new file mode 100644 index 0000000..977ee10 --- /dev/null +++ b/Server/src/main/content/region/karamja/shilo/dialogue/KalebParamaya.java @@ -0,0 +1,146 @@ +package content.region.karamja.shilo.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.AchievementDiary; +import core.game.node.entity.player.link.diary.DiaryType; +import core.plugin.Initializable; + +/** + * Represents the dialoge used for kaleb paramaya. + * @author Vexia + */ +@Initializable +public class KalebParamaya extends DialoguePlugin { + /** + * Constructs a new {@code KalebParamaya} {@code Object} + */ + public KalebParamaya() { + /* + * empty. + */ + } + + /** + * Constructs a new {@code KalebParamaya} {@code Object} + * @param player the player. + */ + public KalebParamaya(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new KalebParamaya(player); + } + + @Override + public boolean open(Object... args) { + player("I have a question about my Achievement Diary."); + stage = 41; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 41: + if (AchievementDiary.canClaimLevelRewards(player, DiaryType.KARAMJA, 1)) { + player("I've done all the medium tasks in my Karamja", "Achievement Diary."); + stage = 440; + break; + } + if (AchievementDiary.canReplaceReward(player, DiaryType.KARAMJA, 1)) { + player("I've seemed to have lost my gloves.."); + stage = 450; + break; + } + options("What is the Achievement Diary?", "What are the rewards?", "How do I claim the rewards?", "See you later."); + stage++; + break; + case 42: + switch (buttonId) { + case 1: + player("What is the Achievement Diary?"); + stage = 410; + break; + case 2: + player("What are the rewards?"); + stage = 420; + break; + case 3: + player("How do I claim the rewards?"); + stage = 430; + break; + case 4: + end(); + break; + } + break; + case 440: + npc("Yes I see that, you'll be wanting your", "reward then I assume?"); + stage++; + break; + case 441: + player("Yes please."); + stage++; + break; + case 442: + AchievementDiary.flagRewarded(player, DiaryType.KARAMJA, 1); + npc("These Karamja gloves are a symbol of your explorin'", "on the island. All the merchants will recognise them", "and mabe give you a discount. I'll", "have a word with some of the seafarin' folk who sail to"); + stage++; + break; + case 443: + npc("Port Sarim and Ardougne, so they'll take you on board", "half price if you're wearing them. Ttake this lamp I", "found washed ashore too."); + stage++; + break; + case 444: + player("Wow, thanks!"); + stage = 41; + break; + case 450: + AchievementDiary.grantReplacement(player, DiaryType.KARAMJA, 1); + npc("You better be more careful this time."); + stage = 41; + break; + case 410: + npc("It's a diary that helps you keep track of particular", "achievements. Here on Karamja it can help you", "discover some quite useful things. Eventually, with", "enough exploration, the people of Karamja will reward"); + stage++; + break; + case 411: + npc("you."); + stage++; + break; + case 412: + npc("You can see what tasks you have listed by clicking on", "the green button in the Quest List."); + stage = 41; + break; + case 420: + npc("Well, there's three different pairs of Karamja gloves,", "which match up with the three levels of difficulty. Each", "has the same rewards as the previous level, and an", "additional one too... but I won't spoil your surprise."); + stage++; + break; + case 421: + npc("Rest assured, the people of Karamja are happy to see", "you visiting the island."); + stage = 41; + break; + case 430: + npc("Just complete the tasks so they're all ticked off, then", "you can claim yer reward. Most of them are", "straightforward; you might find some require quests to", "be started, if not finished."); + stage++; + break; + case 431: + npc("To claim the different Karamja gloves, speak to Pirate", "Jackie the Fruit in Brim Haven, one of the jungle foresters", "near the Kharazi Jungle, or me."); + stage = 41; + break; + case 50: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 512 }; + } + +} diff --git a/Server/src/main/content/region/karamja/shilo/dialogue/ObliDialogue.kt b/Server/src/main/content/region/karamja/shilo/dialogue/ObliDialogue.kt new file mode 100644 index 0000000..6299c94 --- /dev/null +++ b/Server/src/main/content/region/karamja/shilo/dialogue/ObliDialogue.kt @@ -0,0 +1,51 @@ +package content.region.karamja.shilo.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class ObliDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npc(FacialExpression.FRIENDLY,"Welcome to Obli's General Store Bwana!", + "Would you like to see my items?").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> { + options("Yes please!", "No, but thanks for the offer.").also { stage++ } + } + + 1 -> when (buttonId) { + 1 -> player(FacialExpression.FRIENDLY, "Yes, please.").also { stage = 10 } + 2 -> player(FacialExpression.FRIENDLY, "No, but thanks for the offer.").also { stage = 99 } + } + + 10 -> { + end().also { npc.openShop(player) } + } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return ObliDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.OBLI_516) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/karamja/shilo/dialogue/SeravelDialogue.java b/Server/src/main/content/region/karamja/shilo/dialogue/SeravelDialogue.java new file mode 100644 index 0000000..2f30097 --- /dev/null +++ b/Server/src/main/content/region/karamja/shilo/dialogue/SeravelDialogue.java @@ -0,0 +1,102 @@ +package content.region.karamja.shilo.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; +import org.rs09.consts.Items; + +@Initializable +public class SeravelDialogue extends DialoguePlugin { + public SeravelDialogue() { + } + public SeravelDialogue(Player player) { + super(player); + } + + private static final Item COINS = new Item(995, 20); + private static final Item TICKET = new Item(Items.SHIP_TICKET_621); + + @Override + public DialoguePlugin newInstance(Player player) { + return new SeravelDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + player("Hello."); + stage = -1; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 999: + end(); + break; + case -1: + npc("Hello Bwana. Are you interested in buying a ticket", "for the 'Lady of the Waves'?"); + stage++; + break; + case 0: + options("Yes, that sounds great!", "No thanks.", "Tell me more about the ship."); + stage++; + break; + case 1: + switch (buttonId) { + case 1: + player("Yes, that sounds great!"); + stage = 10; + break; + case 2: + player("No thanks."); + stage = 20; + break; + case 3: + player("Tell me more about the ship."); + stage = 30; + break; + } + break; + case 10: + if (player.getInventory().containsItem(COINS)) { + if (player.getInventory().hasSpaceFor(TICKET)) { + npc("Great, nice doing business with you."); + player.getInventory().remove(COINS); + player.getInventory().add(TICKET); + } else { + npc("Sorry Bwana, you don't have enough space. Come back", "when you do!"); + } + } else { + npc("Sorry Bwana, you don't have enough money. Come back", "when you have 25 Gold Pieces."); + } + stage = 999; + break; + case 20: + npc("Fair enough Bwana, let me know if you change your", "mind."); + stage = 999; + break; + case 30: + npc("It's a ship that can take you to either Port Sarim", "or Port Khazard. The ship lies west of Shilo Village", "and south of Cairn Island."); + stage++; + break; + case 31: + npc("The tickets cost 25 Gold Pieces. Would you like to", "purchase a ticket Bwana?"); + stage++; + break; + case 32: + options("Yes, that sounds great!", "No thanks."); + stage = 1; + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 514 }; + } +} diff --git a/Server/src/main/content/region/karamja/shilo/dialogue/TatteredScroll.kt b/Server/src/main/content/region/karamja/shilo/dialogue/TatteredScroll.kt new file mode 100644 index 0000000..2e4a1b8 --- /dev/null +++ b/Server/src/main/content/region/karamja/shilo/dialogue/TatteredScroll.kt @@ -0,0 +1,34 @@ +package content.region.karamja.shilo.dialogue + +import content.global.handlers.iface.ScrollInterface +import content.global.handlers.iface.ScrollLine +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import org.rs09.consts.Components +import org.rs09.consts.Items + +class TatteredScroll : InteractionListener { + // Receive during the Shilo Village quest. + companion object { + private const val SCROLL_INTERFACE = Components.MESSAGESCROLL_220 + val TATTERED_SCROLL_TEXT = arrayOf( + ScrollLine("Bervirius, son of King Danthalas, was killed in battle. His",3), + ScrollLine("devout Mother Rashiliyia was so heartbroken that she swore",4), + ScrollLine("fealty to Zamorak if he would return her son to her. Bervirius",5), + ScrollLine("returned as an undead creature and terrorized the King and",6), + ScrollLine("Queen. Many guards died fighting the Undead Bervirius.",7), + ScrollLine("Eventually the undead Bervirius was set on fire and soon only",8), + ScrollLine("the bones remained.His remains were taken far to the South,",9), + ScrollLine("and then towards the setting sun to a tomb that is surrounded",10), + ScrollLine("by and level with the sea. The only remedy for containing the",11), + ScrollLine("spirits of witches and undead.",12), + ) + } + + override fun defineListeners() { + on(Items.TATTERED_SCROLL_607, IntType.ITEM, "read") { player, _ -> + ScrollInterface.scrollSetup(player, SCROLL_INTERFACE, TATTERED_SCROLL_TEXT) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/karamja/shilo/handlers/BrokenCartBypass.java b/Server/src/main/content/region/karamja/shilo/handlers/BrokenCartBypass.java new file mode 100644 index 0000000..e06e1ad --- /dev/null +++ b/Server/src/main/content/region/karamja/shilo/handlers/BrokenCartBypass.java @@ -0,0 +1,59 @@ +package content.region.karamja.shilo.handlers; + +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; + +import static core.api.ContentAPIKt.hasRequirement; +import content.data.Quests; + + +/** + * Temporarily fix to allow people into shilo village by foot until the Shilo Village quest is added + * addresses #92 + * @author ceik + */ +@Initializable +public class BrokenCartBypass extends OptionHandler { + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(2216).getHandlers().put("option:look-at",this); + return this; + } + + public final void jumpOver(Player player, String options, final Location location){ + player.lock(); + player.animate(new Animation(839)); + player.getImpactHandler().setDisabledTicks(4); + GameWorld.getPulser().submit(new Pulse(1, player) { + @Override + public boolean pulse() { + player.unlock(); + player.getProperties().setTeleportLocation(location); + player.getAnimator().reset(); + return true; + } + }); + } + public final boolean handle(Player player, Node node, String options){ + if (!hasRequirement(player, Quests.SHILO_VILLAGE)) + return true; + Location location = new Location(0,0); + Location playerloc = new Location(player.getLocation().getX(),player.getLocation().getY()); + if(options.equals("look-at")) { + if (playerloc.getX() > 2878) { + location = new Location(2876, 2952); + } else if (playerloc.getX() < 2879) { + location = new Location(2880, 2952); + } + } + jumpOver(player,options,location); + return true; + } +} diff --git a/Server/src/main/content/region/karamja/shilo/handlers/ShiloCart.kt b/Server/src/main/content/region/karamja/shilo/handlers/ShiloCart.kt new file mode 100644 index 0000000..1b15bbc --- /dev/null +++ b/Server/src/main/content/region/karamja/shilo/handlers/ShiloCart.kt @@ -0,0 +1,121 @@ +package content.region.karamja.shilo.handlers + +import core.api.* +import core.game.component.Component +import core.game.dialogue.DialogueFile +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.link.diary.DiaryType +import core.game.node.item.Item +import core.game.world.map.Location +import core.tools.END_DIALOGUE +import org.rs09.consts.Components +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import content.data.Quests + +class ShiloCart : InteractionListener { + + override fun defineListeners() { + + val BRIMHAVEN_CART = 2230 + val SHILO_CART = 2265 + + // Cart IN Brimhaven + on(BRIMHAVEN_CART, IntType.SCENERY, "board") { player, _ -> + openDialogue(player, CartTravelDialogue(), NPC(NPCs.HAJEDY_510)) + return@on true + } + on(BRIMHAVEN_CART, IntType.SCENERY, "pay-fare") { player, _ -> + openDialogue(player, CartQuickPay(), NPC(NPCs.HAJEDY_510)) + return@on true + } + + // Hajedy + on(NPCs.HAJEDY_510, IntType.NPC, "talk-to") { player, _ -> + openDialogue(player, CartTravelDialogue(), NPC(NPCs.HAJEDY_510)) + return@on true + } + on(NPCs.HAJEDY_510, IntType.NPC, "pay-fare") { player, _ -> + openDialogue(player, CartQuickPay(), NPC(NPCs.HAJEDY_510)) + return@on true + } + + + // Cart IN Shilo + on(SHILO_CART, IntType.SCENERY, "board") { player, _ -> + openDialogue(player, CartTravelDialogue(), NPC(NPCs.VIGROY_511)) + return@on true + } + on(SHILO_CART, IntType.SCENERY, "pay-fare") { player, _ -> + openDialogue(player, CartQuickPay(), NPC(NPCs.VIGROY_511)) + return@on true + } + + // Vigroy + on(NPCs.VIGROY_511, IntType.NPC, "talk-to") { player, npc -> + openDialogue(player, CartTravelDialogue(), npc) + return@on true + } + on(NPCs.VIGROY_511, IntType.NPC, "pay-fare") { player, npc -> + openDialogue(player, CartQuickPay(), npc) + return@on true + } + } +} + +class CartQuickPay : DialogueFile(){ + override fun handle(interfaceId: Int, buttonId: Int) { + if (!hasRequirement(player!!, Quests.SHILO_VILLAGE)) return; + val shilo = npc?.id == 510; + when (stage) { + 0 -> if(inInventory(player!!,Items.COINS_995,10)){ + sendDialogue(player!!,"You pay the fare and hand 10 gold coins to "+ (npc?.name ?: "") +".").also { stage++ } + } else { + sendMessage(player!!,"You don't have enough coins.").also { stage = END_DIALOGUE } + } + 1 -> { + if(removeItem(player!!,Item(Items.COINS_995,10))){ + queueScript(player!!, 1, QueueStrength.SOFT) { Qstage: Int -> + when(Qstage){ + 0 -> { + player!!.interfaceManager.closeOverlay() + player!!.interfaceManager.openOverlay(Component(Components.FADE_TO_BLACK_120)) + return@queueScript keepRunning(player!!) + } + 1 -> { + teleport(player!!, if (shilo) Location.create(2834, 2951, 0) else Location.create(2780, 3212, 0)) + player!!.interfaceManager.closeOverlay() + player!!.interfaceManager.openOverlay(Component(Components.FADE_FROM_BLACK_170)) + player!!.achievementDiaryManager.finishTask(player, DiaryType.KARAMJA, 1, 3) + sendDialogue(player!!,"You feel tired from the journey, but at least you didn't have to walk all that distance.").also { stage = END_DIALOGUE } + } + } + return@queueScript stopExecuting(player!!) + } + } + stage = END_DIALOGUE; + } + } + } +} + +class CartTravelDialogue : DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + if (!hasRequirement(player!!, Quests.SHILO_VILLAGE)) return; + val shilo = npc?.id == 510; + when (stage) { + 0 -> npcl("I am offering a cart ride to " + (if (shilo) "Shilo Village" else "Brimhaven") + " if you're interested? It will cost 10 gold coins. Is that Ok?").also { stage++ } + 1 -> if (inInventory(player!!,Items.COINS_995,10)) { + playerl("Yes please, I'd like to go to " + (if (shilo) "Shilo Village" else "Brimhaven") + ".").also { stage++ } + } else{ + playerl("Sorry, I don't seem to have enough coins.").also{ stage = END_DIALOGUE } + } + 2 -> npcl("Great! Just hop into the cart then and we'll go!").also { stage++ } + 3 -> sendDialogue(player!!,"You hop into the cart and the driver urges the horses on. You take a taxing journey through the jungle to " + (if (shilo) "Shilo Village" else "Brimhaven") + ".").also { stage++ } + 4 -> openDialogue(player!!,CartQuickPay(),npc!!) + } + } +} diff --git a/Server/src/main/content/region/karamja/taibwo/dialogue/GabootyDialogue.kt b/Server/src/main/content/region/karamja/taibwo/dialogue/GabootyDialogue.kt new file mode 100644 index 0000000..a590492 --- /dev/null +++ b/Server/src/main/content/region/karamja/taibwo/dialogue/GabootyDialogue.kt @@ -0,0 +1,134 @@ +package content.region.karamja.taibwo.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.game.shops.Shops + +/** + * Dialogue for Gabooty + * @author qmqz + */ +@Initializable +class GabootyDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + player(FacialExpression.FRIENDLY, "What do you do here?").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> npc(FacialExpression.FRIENDLY,"Not much really... I run a local shop which earns", "me a few trading sticks, but that's about it.", "I keep myself to myself really.").also { stage++ } + 1 -> player(FacialExpression.FRIENDLY, "What are trading sticks?").also { stage++ } + 2 -> npc(FacialExpression.FRIENDLY, + "They're the local currency Bwana, ", + "it's used in Tai Bwo Wannai, there's usually", + "some odd jobs that need doing around the village", + "which you could do to earn some trading sticks.").also { stage++ } + 3 -> npc(FacialExpression.FRIENDLY, + "Or, if you have something which the local villagers", + "might like, you could sell it to me and I'll pay", + "you for it in trading sticks.").also { stage++ } + + 4 -> interpreter.sendOptions("Select an Option", + "What sort of things do the local villagers like?", + "You run a shop?", + "I want to ask another question.", + "Ok, thanks.").also { stage++ } + + 5 -> + when (buttonId) { + 1 -> player("What sort of things do the local villagers like?").also { stage = 10 } + 2 -> player("You run a shop?").also { stage = 21 } + 3 -> player("I want to ask another question.").also { stage = 23 } + 4 -> player("Ok, thanks.").also { stage = 99 } + } + + 10 -> npc(FacialExpression.FRIENDLY, + "Gnome cocktails! It's amazing but we all just love them!", + "Luckily I've managed to get stocks of the gnome made", + "cocktails and I supply those to my favourite customers.", + "However, many of the customers really like the cocktails").also { stage++ } + 11 -> npc(FacialExpression.FRIENDLY, + "made by the adventurers passing through this way.", + "If you ever happen to have any, bring them my way! ", + "I'll give you a good deal on it that's for sure!").also { stage++ } + 12 -> player(FacialExpression.FRIENDLY, "How did the villagers ever get to try any gnome cocktails?").also { stage++ } + 13 -> npc(FacialExpression.FRIENDLY, + "I think it was that gnome pilot who crashed his glider,", + "perhaps he had a little mini-bar on board?", + "Come to think about it, you'd expect the little guy to get ", + "his stuff together and move on out of here wouldn't you?").also { stage++ } + 14 -> npc(FacialExpression.FRIENDLY, "He must love the jungle to have stayed here so long!").also { stage = 4 } + + 21 -> npc(FacialExpression.FRIENDLY, + "Yes, it's the Tai Bwo cooperative... catchy name huh!", + "We sell a few local village trinkets and tools.", + "Also, there are a few items that we're actually", + "looking to stock for the locals' sake.").also { stage++ } + 22 -> npc(FacialExpression.FRIENDLY, + "If you happen across any of them please bring them to me,", + "I'll pay a good price for them.", + "I'm sure you'll find the prices very reasonable.").also { stage++ } + 23 -> interpreter.sendOptions("Select an Option", + "What are trading sticks?", + "You run a shop?", + "Can I take a look at what you have to sell?", + "Why do you only take one sort of Gnome cocktail?", + "I want to ask another question.").also { stage++ } + + 24 -> + when (buttonId) { + 1 -> player("What are trading sticks?").also { stage = 2 } + 2 -> player("You run a shop?").also { stage = 21 } + 3 -> player("Can I take a look at what you have to sell?").also { stage = 30 } + 4 -> player("Why do you only take one sort of Gnome cocktail?").also { stage = 40 } + 5 -> player("I want to ask another question.").also { stage = 4 } + } + + 30 -> npc(FacialExpression.FRIENDLY, "Sure you can...which shop would you like to see?", + "The Cooperative or Drinks store?").also { stage++ } + + 31 ->interpreter.sendOptions("Select an Option", + "The Cooperative", + "The Drinks Store", + "None thanks...").also { stage++ } + + 32 -> + when (buttonId) { //gotta add shops + 1 -> player("The Cooperative").also { stage = 90 } + 2 -> player("The Drinks Store").also { stage = 91 } + 3 -> player("None thanks...").also { stage = 99 } + } + + 40 -> npc(FacialExpression.FRIENDLY, "It's funny that, actually. I've managed to get a ", + "good deal with the pilot of that gnome glider. He can supply", + "me directly now. However, it's really interesting that the ", + "local villagers really like the gnome cocktails made by the").also { stage++ } + 41 -> npc(FacialExpression.FRIENDLY, "adventurers passing through this way.").also { stage++ } + 42 -> player(FacialExpression.FRIENDLY, "Why, what's the difference?").also { stage++ } + 43 -> npc(FacialExpression.FRIENDLY, "I think it may just be that they're made fresher,", + "or there is a slight twist in the flavour of the drink,", + "you know, a little more of this, a little less of that, it all", + "adds up and makes for an interesting tipple!").also { stage = 23 } + + 90 -> end().also { Shops.openId(player,226) } + 91 -> end().also { Shops.openId(player,227) } + 99 -> end() + } + + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return GabootyDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(2519, 2520, 2521) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/karamja/taibwo/dialogue/JiminuaDialogue.java b/Server/src/main/content/region/karamja/taibwo/dialogue/JiminuaDialogue.java new file mode 100644 index 0000000..d2bf7aa --- /dev/null +++ b/Server/src/main/content/region/karamja/taibwo/dialogue/JiminuaDialogue.java @@ -0,0 +1,148 @@ +package content.region.karamja.taibwo.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.plugin.Initializable; +import org.rs09.consts.Items; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.npc.NPC; +import core.game.node.item.Item; +import core.game.node.entity.player.Player; +import core.plugin.Plugin; +import core.plugin.ClassScanner; + +/** + * Represents the jiminua dialogue plugin. + * + * @author 'afaroutdude + */ +@Initializable +public final class JiminuaDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code JiminuaDialogue} {@code Object}. + */ + public JiminuaDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code JiminuaDialogue} {@code Object}. + * + * @param player the player. + */ + public JiminuaDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + ClassScanner.definePlugin(new JiminuaUnnoteHandler()); + return new JiminuaDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + npc("Welcome to Jiminua's Jungle Store, Can I help you", "at all?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 999: + end(); + break; + case 0: + options("Yes please. What are you selling?", "How should I use your shop?", "Can you un-note any of my items?", "No thanks."); + stage++; + break; + case 1: + switch (buttonId) { + case 1: + player("Yes please. What are you selling?"); + stage = 10; + break; + case 2: + player("How should I use your shop?"); + stage = 20; + break; + case 3: + player("Can you un-note any of my items?"); + stage = 30; + break; + case 4: + player("No thanks."); + stage = 999; + break; + } + break; + case 10: + npc("Take a good look."); + stage++; + break; + case 11: + end(); + npc.openShop(player); + break; + case 20: + npc("I'm glad you ask! You can buy as many of the items", "stocked as you wish. You can also sell most items", "to the shop."); + stage = 999; + break; + case 30: + npc("I can un-note pure essence, but nothing else. Just", "give me the notes you wish to exchange."); + stage = 999; + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[]{560}; + } + + private static final class JiminuaUnnoteHandler extends UseWithHandler { + public JiminuaUnnoteHandler() { + super(Items.PURE_ESSENCE_7937); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(560, NPC_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + Player player = event.getPlayer(); + assert (event.getUsedItem().getId() == Items.PURE_ESSENCE_7937); + int ess = player.getInventory().getAmount(Items.PURE_ESSENCE_7937); + int coins = player.getInventory().getAmount(Items.COINS_995); + int freeSpace = player.getInventory().freeSlots(); + + if (ess == 0) { + player.getDialogueInterpreter().sendDialogues(560, FacialExpression.HALF_GUILTY, "You don't have any essence for me to un-note."); + return true; + } else if (freeSpace == 0) { + player.getDialogueInterpreter().sendDialogues(560, FacialExpression.HALF_GUILTY, "You don't have any free space."); + return true; + } else if (coins <= 1) { + player.getDialogueInterpreter().sendDialogues(560, FacialExpression.HALF_GUILTY, "I charge 2 gp to un-note each pure essence."); + return true; + } + + int unnote = Math.min(Math.min(freeSpace, ess), coins / 2); + player.getInventory().remove(new Item(Items.PURE_ESSENCE_7937, unnote)); + player.getInventory().remove(new Item(Items.COINS_995, 2 * unnote)); + player.getInventory().add(new Item(Items.PURE_ESSENCE_7936, unnote)); + player.getPacketDispatch().sendMessage("You hand Jiminua some notes and coins, and she hands you back pure essence."); + return true; + } + } +} diff --git a/Server/src/main/content/region/karamja/taibwo/handlers/GabootyTrade.java b/Server/src/main/content/region/karamja/taibwo/handlers/GabootyTrade.java new file mode 100644 index 0000000..135a78f --- /dev/null +++ b/Server/src/main/content/region/karamja/taibwo/handlers/GabootyTrade.java @@ -0,0 +1,54 @@ +package content.region.karamja.taibwo.handlers; + +import core.cache.def.impl.NPCDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.game.shops.Shops; +import core.game.system.config.ShopParser; + +/** + * Represents the plugin used for trading with Gabooty + * + * @author 'qmqz + * @version 1.0 + */ +@Initializable +public final class GabootyTrade extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + NPCDefinition.forId(2521).getHandlers().put("option:talk-to", this); + NPCDefinition.forId(2521).getHandlers().put("option:trade-co-op", this); + NPCDefinition.forId(2521).getHandlers().put("option:trade-drinks", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + final NPC npc = (NPC) node; + switch (npc.getId()) { + case 2519: + case 2520: + case 2521: + switch (option) { + case "talk-to": + player.getDialogueInterpreter().open(2521, node.asNpc()); + return true; + + case "trade-co-op": + Shops.openId(player, 226); + return true; + + case "trade-drinks": + Shops.openId(player, 254); + return true; + } + break; + } + return true; + } +} diff --git a/Server/src/main/content/region/karamja/tzhaar/handlers/TzHaarMejJah.java b/Server/src/main/content/region/karamja/tzhaar/handlers/TzHaarMejJah.java new file mode 100644 index 0000000..09653c5 --- /dev/null +++ b/Server/src/main/content/region/karamja/tzhaar/handlers/TzHaarMejJah.java @@ -0,0 +1,313 @@ +package content.region.karamja.tzhaar.handlers; + +import core.game.dialogue.DialogueInterpreter; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; +import core.game.world.GameWorld; + +/** + * Handles the TzHaarMejJal dialogue. + * @author 'Vexia + * @author Empathy + * @author Logg + */ +@Initializable +public class TzHaarMejJah extends DialoguePlugin { + private static final Item APPEARANCE_FEE = new Item(6529, 8000); // 8000 tokkul, about the same as you get from failing jad + + public TzHaarMejJah() { + + } + + public TzHaarMejJah(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new TzHaarMejJah(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "You want help JalYt-Ket-" + player.getUsername() + "?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + if (GameWorld.getSettings().getJad_practice_enabled()) { + if (player.getAttribute("fc_practice_jad", false)) { + interpreter.sendOptions("Select an Option", player.getInventory().containItems(6570) ? "I have a fire cape here." : "What is this place?", "What did you call me?", "About my challenge...", "No I'm fine thanks."); + } else { + interpreter.sendOptions("Select an Option", player.getInventory().containItems(6570) ? "I have a fire cape here." : "What is this place?", "What did you call me?", "I want to challenge Jad directly.", "No I'm fine thanks."); + } + } else { + interpreter.sendOptions("Select an Option", player.getInventory().containItems(6570) ? "I have a fire cape here." : "What is this place?", "What did you call me?", "No I'm fine thanks."); + } + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + if (player.getInventory().containItems(6570)) { + interpreter.open(DialogueInterpreter.getDialogueKey("firecape-exchange"), npc); + break; + } + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What is this place?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What did you call me?"); + stage = 20; + break; + case 3: + if (GameWorld.getSettings().getJad_practice_enabled()) { + if (player.getAttribute("fc_practice_jad", false)) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "About my challenge..."); + stage = 64; + } else { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "The challenge is too long.", "I want to challenge Jad directly."); + stage = 50; + } + } else { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No I'm fine thanks."); + stage = 30; + } + break; + case 4: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No I'm fine thanks."); + stage = 30; + break; + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "This is the fight caves, TzHaar-Xil made it for practice,", "but many JalYt come here to fight too.", "Just enter the cave and make sure you're prepared."); + stage = 11; + break; + case 11: + interpreter.sendOptions("Select an Option", "Are there any rules?", "Ok thanks."); + stage = 12; + break; + case 12: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Are there any rules?"); + stage = 14; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Ok thanks."); + stage = 13; + break; + } + break; + case 13: + end(); + break; + case 14: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Rules? Survival is the only rule in there."); + stage = 15; + break; + case 15: + interpreter.sendOptions("Select an Option", "Do I win anything?", "Sounds good."); + stage = 16; + break; + case 16: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Do I win anything?"); + stage = 17; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Sounds good."); + stage = 13; + break; + + } + break; + case 17: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "You ask a lot of questions.", "Might give you TokKul if you last long enough."); + stage = 18; + break; + case 18: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "..."); + stage = 19; + break; + case 19: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Before you ask, TokKul is like your Coins."); + stage = 500; + break; + case 500: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Gold is like you JalYt, soft and easily broken, we use", "hard rock forged in fire like TzHaar!"); + stage = 501; + break; + case 501: + end(); + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Are you not JalYt-Ket?"); + stage = 21; + break; + case 21: + interpreter.sendOptions("Select an Option", "What's a 'JalYt-Ket'?", "I guess so...", "No I'm not!"); + stage = 22; + break; + case 22: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What's a 'JalYt-Ket'?"); + stage = 100; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I guess so..."); + stage = 200; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No I'm not!"); + stage = 300; + break; + } + break; + case 100: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "That what you are... you tough and strong no?"); + stage = 101; + break; + case 101: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Well yes I suppose I am..."); + stage = 102; + break; + case 102: + end(); + break; + case 200: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I guess so...."); + stage = 201; + break; + case 201: + end(); + break; + case 300: + end(); + break; + case 30: + end(); + break; + + case 50: + interpreter.sendDialogues(npc, FacialExpression.DISGUSTED_HEAD_SHAKE, "I thought you strong and tough", "but you want skip endurance training?"); + stage = 57; + break; + case 57: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "Maybe you not JalYt-Ket afterall."); + stage = 58; + break; + case 58: + interpreter.sendOptions("Select an Option", "I don't have time for it, man.", "No, I'm JalYt-Ket!"); + stage = 51; + break; + case 51: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I don't have time for it, man."); + stage = 52; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No, I'm JalYt-Ket! I swear!", "I'll do the training properly."); + stage = 30; + break; + } + break; + case 52: + interpreter.sendDialogues(npc, FacialExpression.DISGUSTED_HEAD_SHAKE, "JalYt, you know you not get reward","if you not do training properly, ok?"); + stage = 56; + break; + case 56: + interpreter.sendOptions("Select an Option", "That's okay, I don't need a reward.", "Oh, nevermind then."); + stage = 53; + break; + case 53: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "That's okay, I don't need a reward."); + stage = 54; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Oh, nevermind then."); + stage = 30; + break; + } + break; + case 54: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "I just wanna fight the big guy."); + stage = 55; + break; + case 55: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "Okay JalYt.","TzTok-Jad not show up for just anyone."); + stage = 59; + break; + case 59: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "You give 8000 TokKul, TzTok-Jad know you serious.", "You get it back if you victorious."); + stage = 60; + break; + case 60: + interpreter.sendOptions("Select an Option", "That's fair, here's 8000 TokKul.", "I don't have that much on me, but I'll go get it.", "TzTok-Jad must be old and tired to not just accept my challenge."); + stage = 61; + case 61: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "That's fair, here's 8000 TokKul."); + if (!player.getInventory().containsItem(APPEARANCE_FEE)) { + stage = 62; + break; + } + if (player.getInventory().remove(APPEARANCE_FEE)) { + stage = 69; + } else { + stage = 62; + } + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I don't have that much on me, but I'll go get it."); + stage = 30; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "TzTok-Jad must be old and tired", "to not just accept my challenge."); + stage = 63; + break; + } + break; + case 62: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "JalYt, you not have the TokKul.", "You come back when you are serious."); + stage = 30; + break; + case 63: + interpreter.sendDialogues(npc, FacialExpression.ANGRY, "JalYt-Mor, you the old and tired one.", "You the one not want to do proper training."); + stage = 30; + break; + case 64: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "TzTok-Jad is waiting for you.", "Do not make TzTok-Jad wait long."); + stage = 30; + break; + case 69: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "Okay JalYt. Enter cave when you are prepared.", "You find TzTok-Jad waiting for JalYt challenger."); + player.setAttribute("fc_practice_jad", true); + stage = 30; + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { DialogueInterpreter.getDialogueKey("tzhaar-mej"), 2617 }; + } +} diff --git a/Server/src/main/content/region/karamja/tzhaar/handlers/TzHaarMejKah.java b/Server/src/main/content/region/karamja/tzhaar/handlers/TzHaarMejKah.java new file mode 100644 index 0000000..97a62c9 --- /dev/null +++ b/Server/src/main/content/region/karamja/tzhaar/handlers/TzHaarMejKah.java @@ -0,0 +1,158 @@ +package content.region.karamja.tzhaar.handlers; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Handles the TzHaarMejKah dialogue. + * @author 'Vexia + */ +@Initializable +public class TzHaarMejKah extends DialoguePlugin { + + public TzHaarMejKah() { + + } + + public TzHaarMejKah(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new TzHaarMejKah(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "You want help JalYt-Ket-" + player.getUsername() + "?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "What is this place?", "Who's the current champion?", "What did you call me?", "No I'm fine thanks."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What is this place?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Who's the current champion?"); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What did you call me?"); + stage = 30; + break; + case 4: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No I'm fine thanks."); + stage = 40; + break; + + } + break; + case 40: + end(); + break; + case 30: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Are you not JalYt-Ket?"); + stage = 31; + break; + case 31: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I guess so..."); + stage = 32; + break; + case 32: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Well then, no problems."); + stage = 13; + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "This is the fight pit, TzHaar-Xil made it for their sport", "but many JalYt come here to fight too.", "If you are wanting to fight then enter the cage, you", "will be summoned when the next round is ready to begin."); + stage = 11; + break; + case 11: + interpreter.sendOptions("Select an Option", "Are there any rules?", "Ok thanks."); + stage = 12; + break; + case 12: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Are there any rules?"); + stage = 14; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Ok thanks."); + stage = 13; + break; + } + break; + case 13: + end(); + break; + case 14: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "No rules, you use whatever you want. Last person", "standing wins and is declared champion, they stay in", "the pit for the next fight."); + stage = 15; + break; + case 15: + interpreter.sendOptions("Select an Option", "Do I win anything?", "Sounds good."); + stage = 16; + break; + case 16: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Do I win anything?"); + stage = 17; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Sounds good."); + stage = 13; + break; + } + break; + case 17: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "You ask a lot of questions.", "Champion gets TokKul as reward, but more fights the more", "TokKul they get."); + stage = 18; + break; + case 18: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "..."); + stage = 19; + break; + case 19: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Before you ask, TokKul is like your coins."); + stage = 400; + break; + case 400: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Gold is like you JalYt, soft and easily broken, we use", "hard rock forged in fire like TzHaar!"); + stage = 401; + break; + case 401: + end(); + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ah that would be " + npc.getAttribute("fp_champn", "JalYt-Ket-Emperor")); + stage = 21; + break; + case 21: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 2618 }; + } +} diff --git a/Server/src/main/content/region/karamja/tzhaar/handlers/TzRekJadNPC.java b/Server/src/main/content/region/karamja/tzhaar/handlers/TzRekJadNPC.java new file mode 100644 index 0000000..2c59939 --- /dev/null +++ b/Server/src/main/content/region/karamja/tzhaar/handlers/TzRekJadNPC.java @@ -0,0 +1,263 @@ +package content.region.karamja.tzhaar.handlers; + +import core.cache.def.impl.NPCDefinition; +import core.game.dialogue.DialogueInterpreter; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.repository.Repository; +import core.plugin.Plugin; +import core.plugin.ClassScanner; +import core.plugin.Initializable; +import core.tools.RandomFunction; + +/** + * Handles everything in regards to jad pet. + * @author Empathy + * + */ +@Initializable +public class TzRekJadNPC extends OptionHandler { + + /** + * The tzhaar mej id. + */ + private static final int TZHAAR_MEJ_ID = 2617; + + /** + * The firecape item. + */ + private static final Item FIRECAPE = new Item(6570); + + /** + * The tokkul item. + */ + private static final Item TOKKUL = new Item(6529); + + /** + * The jad item. + */ + private static final Item JAD_PET = new Item(14828); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + NPCDefinition.forId(TZHAAR_MEJ_ID).getHandlers().put("option:exchange fire cape", this); + ClassScanner.definePlugins(new TzhaarMejJalDialogue(), new TzRekJadDialogue()); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + switch (option) { + case "exchange fire cape": + player.getDialogueInterpreter().open(DialogueInterpreter.getDialogueKey(player.getInventory().containsItem(FIRECAPE) ? "firecape-exchange" : "tzhaar-mej"), node.asNpc()); + break; + } + return true; + } + + /** + * Handles the TzhaarMejJal Dialogue to gamble for jad pet. + * @author Empathy + * + */ + public final class TzhaarMejJalDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code TzhaarMejJalDialogue} {@code Object}. + */ + public TzhaarMejJalDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code TzhaarMejJalDialogue} {@code Object}. + * + * @param player the player. + */ + public TzhaarMejJalDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new TzhaarMejJalDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I have a fire cape here."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Sell your fire cape?", "Yes, sell it for 8,000 TokKul.", "No, keep it.", "Bargain for TzRek-Jad."); + stage = 1; + break; + case 1: + switch(buttonId) { + case 1: + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, player.getInventory().containsItems(FIRECAPE) ? "Hand your cape here, young JalYte." : "You not have firecape, JalYt."); + stage = 10; + break; + case 2: + end(); + break; + case 3: + interpreter.sendOptions("Sacrifice your firecape?", "Yes, I know I won't get my cape back.", "No, I like my cape!"); + stage = 20; + break; + } + break; + case 10: + if (player.getInventory().containsItem(FIRECAPE)) { + if (player.getInventory().remove(FIRECAPE)) { + TOKKUL.setAmount(8000); + player.getInventory().add(TOKKUL); + TOKKUL.setAmount(1); + } + } + end(); + break; + case 20: + switch (buttonId) { + case 1: + if (player.hasItem(JAD_PET)) { + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "Best you train one TzRek-Jad only."); + stage = 21; + break; + } + if (player.getFamiliarManager().hasFamiliar()) { + if (player.getFamiliarManager().getFamiliar().getId() == 8650) { + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "Best you train one TzRek-Jad only."); + stage = 21; + break; + } + } + if (player.getInventory().remove(FIRECAPE)) { + int r = RandomFunction.getRandom(200); + if (r == 1) { + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "You lucky. Better train him good else TzTok-Jad find", "you, JalYt."); + if (!player.getFamiliarManager().hasFamiliar()) { + player.getFamiliarManager().summon(JAD_PET, true); + player.sendNotificationMessage("You have a funny feeling like you're being followed."); + } else if (player.getInventory().freeSlots() > 0) { + player.getInventory().add(JAD_PET); + player.sendNotificationMessage("You feel something weird sneaking into your backpack."); + } + Repository.sendNews(player.getUsername() + " now commands a miniature TzTok-Jad!"); + } else { + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "You not lucky. Maybe next time, JalYt."); + } + } + stage = 21; + break; + case 2: + end(); + break; + } + break; + case 21: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { DialogueInterpreter.getDialogueKey("firecape-exchange") }; + } + } + + /** + * Handles the TzRekJad dialogue. + * @author Empathy + * + */ + public final class TzRekJadDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code TzRekJadDialogue} {@code Object}. + */ + public TzRekJadDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code TzRekJadDialogue} {@code Object}. + * + * @param player the player. + */ + public TzRekJadDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new TzRekJadDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + int i = RandomFunction.getRandom(1); + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, i == 1 ? "Do you miss your people?" : "Are you hungry?"); + stage = (i == 1 ? 0 : 5); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "Mej-TzTok-Jad Kot-Kl!"); + stage = 1; + break; + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No.. I don't think so."); + stage = 2; + break; + case 2: + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "Jal-Zek Kl?"); + stage = 3; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No, no, I wouldn't hurt you."); + stage = 4; + break; + case 4: + end(); + break; + case 5: + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "Kl-Kra!"); + stage = 6; + break; + case 6: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Ooookay..."); + stage = 4; + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 8650 }; + } + } + +} diff --git a/Server/src/main/content/region/karamja/tzhaar/handlers/TzhaarCityPlugin.java b/Server/src/main/content/region/karamja/tzhaar/handlers/TzhaarCityPlugin.java new file mode 100644 index 0000000..669df92 --- /dev/null +++ b/Server/src/main/content/region/karamja/tzhaar/handlers/TzhaarCityPlugin.java @@ -0,0 +1,203 @@ +package content.region.karamja.tzhaar.handlers; + +import core.cache.def.impl.SceneryDefinition; +import core.game.activity.ActivityManager; +import core.game.dialogue.DialoguePlugin; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the plugin used for tzhaar city. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class TzhaarCityPlugin extends OptionHandler { + + /** + * Represents the locations to use. + */ + private static final Location[] LOCATIONS = new Location[] { Location.create(2480, 5175, 0), Location.create(2866, 9571, 0) }; + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(31284).getHandlers().put("option:enter", this); //karamja cave. + SceneryDefinition.forId(9359).getHandlers().put("option:enter", this); //tzhaar exit + SceneryDefinition.forId(9356).getHandlers().put("option:enter", this); + SceneryDefinition.forId(9369).getHandlers().put("option:pass", this); + SceneryDefinition.forId(31292).getHandlers().put("option:go-through", this); //unimplemented door near fairy ring + new TzhaarDialogue().init(); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + int id = ((Scenery) node).getId(); + switch (option) { + case "enter": + switch (id) { + case 31284: + player.getProperties().setTeleportLocation(LOCATIONS[0]); + break; + case 9359: + player.getProperties().setTeleportLocation(LOCATIONS[1]); + break; + case 9356: + if (player.getFamiliarManager().hasFamiliar()) { + player.getPacketDispatch().sendMessage("You can't enter this with a follower."); + break; + } + ActivityManager.start(player, "fight caves", false); + break; + } + break; + case "pass": + switch (id) { + case 9369: + ActivityManager.start(player, "fight pits", false); + break; + } + break; + case "go-through": + switch (id) { + case 31292: + return false; + } + break; + } + return true; + } + + /** + * Represents the dialogue plugin used for the tzhaar npcs. + * @author 'Vexia + * @version 1.0 + */ + public static final class TzhaarDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code TzhaarDialogue} {@code Object}. + */ + public TzhaarDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code TzhaarDialogue} {@code Object}. + * @param player the player. + */ + public TzhaarDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new TzhaarDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + npc("Can I help you JalYt-Ket-" + player.getUsername() + "?"); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + options("What do you have to trade?", "What did you call me?", "No I'm fine thanks."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + end(); + npc.openShop(player); + break; + case 2: + player("What did you call me?"); + stage = 20; + break; + case 3: + player("No I'm fine thanks."); + stage = 30; + break; + } + break; + case 10: + break; + case 20: + npc("Are you not JalYt-Ket?"); + stage = 21; + break; + case 21: + options("What's a 'JalYt-Ket'?", "I guess so...", "No I'm not!"); + stage = 22; + break; + case 22: + switch (buttonId) { + case 1: + player("What's a 'JalYt-Ket'?"); + stage = 100; + break; + case 2: + player("I guess so..."); + stage = 120; + break; + case 3: + player("No I'm not!"); + stage = 130; + break; + } + break; + case 100: + npc("That what you are... you tough and strong no?"); + stage = 101; + break; + case 101: + player("Well yes I suppose I am..."); + stage = 102; + break; + case 102: + npc("Then you JalYt-Ket!"); + stage = 103; + break; + case 103: + end(); + break; + case 120: + npc("Well then, no problems."); + stage = 121; + break; + case 121: + end(); + break; + case 130: + end(); + break; + case 23: + end(); + break; + case 30: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 2620, 2622, 2623 }; + } + + } +} diff --git a/Server/src/main/content/region/karamja/tzhaar/handlers/TzhaarFightCaveNPC.java b/Server/src/main/content/region/karamja/tzhaar/handlers/TzhaarFightCaveNPC.java new file mode 100644 index 0000000..1fd8b7f --- /dev/null +++ b/Server/src/main/content/region/karamja/tzhaar/handlers/TzhaarFightCaveNPC.java @@ -0,0 +1,348 @@ +package content.region.karamja.tzhaar.handlers; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.node.entity.combat.InteractionType; +import core.game.node.entity.combat.ImpactHandler.HitsplatType; +import core.game.node.entity.combat.equipment.ArmourSet; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.npc.NPC; +import core.game.system.task.Pulse; +import core.game.world.map.Location; +import core.game.world.map.MapDistance; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.tools.RandomFunction; + +/** + * Represents a fight caves NPC. + * @author Emperor + */ +public final class TzhaarFightCaveNPC extends AbstractNPC { + + /** + * The NPC ids. + */ + private static final int[] NPC_IDS = { 2734, 2735, 2736, 2737, 2738, 2739, 2740, 2741, 2742, 2743, 2744, 2745, 2746 }; + + /** + * The combat reward. + */ + private CombatAction combatAction; + + /** + * The activity plugin object. + */ + private TzhaarFightCavesPlugin activity; + + /** + * If the NPC has spawned minions yet (used for Jad). + */ + private boolean spawnedMinions; + + /** + * Constructs a new {@code TzhaarFightCaveNPC} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + public TzhaarFightCaveNPC(int id, Location location, TzhaarFightCavesPlugin activity) { + super(id, location); + this.activity = activity; + } + + /** + * Constructs a new {@code TzhaarFightCaveNPC} {@code Object}. + */ + public TzhaarFightCaveNPC() { + super(2734, null); + } + + @Override + public CombatSwingHandler getSwingHandler(boolean swing) { + return combatAction; + } + + @Override + public void tick() { + super.tick(); + if (getId() != 2746 && activity != null && !getProperties().getCombatPulse().isAttacking()) { + getProperties().getCombatPulse().attack(activity.getPlayer()); + face(activity.getPlayer()); + } + } + + @Override + public void configure() { + super.configure(); + CombatStyle style = CombatStyle.MELEE; + if (getId() == 2739 || getId() == 2740) { + style = CombatStyle.RANGE; + } else if (getId() == 2743 || getId() == 2744 || getId() == 2745) { + style = CombatStyle.MAGIC; + } + super.setAggressive(false); + super.aggressiveHandler = null; + combatAction = new CombatAction(this, style); + getProperties().setCombatTimeOut(Integer.MAX_VALUE); + super.setWalkRadius(64); + if (activity != null) { + activity.activeNPCs.add(this); + if (getId() != 2746) { + getProperties().getCombatPulse().attack(activity.getPlayer()); + } + } + } + @Override + public boolean shouldPreventStacking(Entity mover) { + return mover instanceof TzhaarFightCaveNPC; + } + + /** + * Heals the NPC. + * @param amount The amount to heal. + */ + public void heal(int amount) { + if (getSkills().heal(amount) > 0 && getId() == 2745) { + spawnedMinions = false; + } + } + + @Override + public void onImpact(final Entity entity, final BattleState state) { + if (getId() == 2746) { + getPulseManager().run(new Pulse(1, entity) { + @Override + public boolean pulse() { + getProperties().getCombatPulse().attack(entity); + return true; + } + }); + return; + } + super.onImpact(entity, state); + if (getId() == 2736 || getId() == 2737) { + if (state.getStyle() == CombatStyle.MELEE && getSkills().getLifepoints() > 0) { + entity.getImpactHandler().manualHit(this, 1 + (state.getEstimatedHit() / 10), HitsplatType.NORMAL, 1); + } + } else if (getId() == 2745 && !spawnedMinions && getSkills().getLifepoints() < (getSkills().getMaximumLifepoints() >> 1)) { + spawnedMinions = true; + if (activity != null) { + for (int i = activity.activeNPCs.size() - 1; i < 4; i++) { + TzhaarFightCaveNPC npc = activity.spawn(2746); + npc.getProperties().getCombatPulse().attack(this); + npc.setAttribute("fc_jad", this); + } + } + } + } + + @Override + public int getWalkRadius() { + return 64; + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new TzhaarFightCaveNPC(id, location, null); + } + + @Override + public int[] getIds() { + return NPC_IDS; + } + + /** + * Handles a fight cave NPC's combat reward. + * @author Emperor + */ + static class CombatAction extends CombatSwingHandler { + + /** + * The NPC instance. + */ + private TzhaarFightCaveNPC npc; + + /** + * The main combat style. + */ + private CombatStyle main; + + /** + * The current combat style. + */ + private CombatStyle style; + + /** + * If the NPC is TzTok-Jad. + */ + boolean jad; + + /** + * Constructs a new {@code TzhaarFightCaveNPC} {@code Object}. + * @param npc The NPC. + * @param main The main combat style. + */ + public CombatAction(TzhaarFightCaveNPC npc, CombatStyle main) { + super(main); + this.npc = npc; + this.jad = npc.getId() == 2745; + this.main = main; + this.style = getType(); + } + + @Override + public InteractionType canSwing(Entity entity, Entity victim) { + if (getType() != CombatStyle.MELEE) { + if (!isProjectileClipped(entity, victim, false)) { + return InteractionType.NO_INTERACT; + } + int distance = MapDistance.RENDERING.getDistance(); + if (victim.getCenterLocation().withinDistance(entity.getCenterLocation(), getCombatDistance(entity, victim, distance)) && super.canSwing(entity, victim) != InteractionType.NO_INTERACT) { + entity.getWalkingQueue().reset(); + return InteractionType.STILL_INTERACT; + } + return InteractionType.NO_INTERACT; + } + if(getType() != null) + return getType().getSwingHandler().canSwing(entity, victim); + else return InteractionType.NO_INTERACT; + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + if(super.getType() != null) + style = super.getType(); + int ticks = 1; + if (jad) { + main = CombatStyle.values()[1 + RandomFunction.RANDOM.nextInt(2)]; + } + if (main != CombatStyle.MELEE) { + style = main; + if (CombatStyle.MELEE.getSwingHandler().canSwing(entity, victim) != InteractionType.NO_INTERACT && RandomFunction.random(10) < 4) { + style = CombatStyle.MELEE; + } else { + ticks += (int) Math.ceil(entity.getLocation().getDistance(victim.getLocation()) * 0.4); + } + } + int max = calculateHit(entity, victim, 1.0); + int hit = 0; + boolean heal = victim instanceof NPC || ((npc.getId() == 2741 || npc.getId() == 2742) && RandomFunction.RANDOM.nextInt(4) < 1); + if (((NPC) entity).getId() == 2746) { + NPC j = (NPC) entity.getAttribute("fc_jad", entity); + if (entity.getLocation().withinDistance(j.getCenterLocation(), (j.size() >> 1) + 1) && RandomFunction.random(4) < 2) { + heal = true; + state.setVictim(j); + victim = j; + } + } + state.setStyle(heal ? null : style); + if (heal || isAccurateImpact(entity, victim)) { + state.setMaximumHit(max); + hit = RandomFunction.random(max) + (heal ? 5 : 0); + } + state.setEstimatedHit(hit); + return ticks; + } + + @Override + public void adjustBattleState(Entity entity, Entity victim, BattleState state) { + + } + + @Override + public void visualize(Entity entity, Entity victim, BattleState state) { + if (state == null || state.getStyle() == null) { + return; + } + switch (state.getStyle()) { + case MELEE: + entity.animate(entity.getProperties().getAttackAnimation()); + break; + case RANGE: + if (jad) { + entity.visualize(new Animation(9276, Priority.HIGH), Graphics.create(1625)); + } else { + Projectile.ranged(entity, victim, 1616, 41, 36, 50, 15).send(); + entity.animate(new Animation(9243, Priority.HIGH)); + } + break; + case MAGIC: + if (jad) { + Projectile.create(entity, victim, 1627, 96, 36, 70, (int) (victim.getLocation().getDistance(entity.getLocation()) * 10 + 52)).send(); + entity.visualize(new Animation(9300, Priority.HIGH), Graphics.create(1626)); + } else { + Projectile.magic(entity, victim, 1623, 41, 36, 50, 15).send(); + entity.visualize(new Animation(9266, Priority.HIGH), Graphics.create(1622)); + } + break; + } + } + + @Override + public void impact(Entity entity, Entity victim, BattleState state) { + if (state != null && state.getStyle() != null && victim.hasProtectionPrayer(state.getStyle())) { + state.setEstimatedHit(0); + } + if (state != null && state.getStyle() == null) { + NPC n = victim instanceof NPC ? ((NPC) victim) : (NPC) npc.activity.getPlayer().getProperties().getCombatPulse().getVictim(); + if (!(n instanceof TzhaarFightCaveNPC)) { + n = npc; + } + ((TzhaarFightCaveNPC) n).heal(state.getEstimatedHit()); + n.graphics(new Graphics(444, 96)); + return; + } + if (state != null && state.getEstimatedHit() > 0) { + state.setEstimatedHit(formatHit(victim, state.getEstimatedHit())); + if (((NPC) entity).getId() == 2734 || ((NPC) entity).getId() == 2735) { + victim.getSkills().decrementPrayerPoints(state.getEstimatedHit()); + } else if (jad && state.getStyle() != CombatStyle.MELEE) { + victim.graphics(Graphics.create(157)); + } + } + style.getSwingHandler().impact(entity, victim, state); + } + + @Override + public void visualizeImpact(Entity entity, Entity victim, BattleState state) { + if (state != null && state.getStyle() == null) { + return; + } else if (state != null && state.getStyle() == CombatStyle.MAGIC && !jad) { + victim.graphics(Graphics.create(1624)); + } else if (state != null && jad && state.getStyle() == CombatStyle.RANGE) { + victim.graphics(Graphics.create(451)); + } + style.getSwingHandler().visualizeImpact(entity, victim, state); + } + + @Override + public int calculateAccuracy(Entity entity) { + return style.getSwingHandler().calculateAccuracy(entity); + } + + @Override + public int calculateDefence(Entity victim, Entity attacker) { + return style.getSwingHandler().calculateDefence(victim, attacker); + } + + @Override + public int calculateHit(Entity entity, Entity victim, double modifier) { + return style.getSwingHandler().calculateHit(entity, victim, modifier); + } + + @Override + public ArmourSet getArmourSet(Entity e) { + return style.getSwingHandler().getArmourSet(e); + } + + @Override + public double getSetMultiplier(Entity e, int skillId) { + return style.getSwingHandler().getSetMultiplier(e, skillId); + } + + } +} diff --git a/Server/src/main/content/region/karamja/tzhaar/handlers/TzhaarFightCavesPlugin.java b/Server/src/main/content/region/karamja/tzhaar/handlers/TzhaarFightCavesPlugin.java new file mode 100644 index 0000000..e1baca7 --- /dev/null +++ b/Server/src/main/content/region/karamja/tzhaar/handlers/TzhaarFightCavesPlugin.java @@ -0,0 +1,336 @@ +package content.region.karamja.tzhaar.handlers; + +import content.global.skill.slayer.SlayerManager; +import core.game.event.NPCKillEvent; +import core.game.activity.ActivityPlugin; +import content.data.BossKillCounter; +import core.game.interaction.Option; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.entity.skill.Skills; +import content.global.skill.slayer.Tasks; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.system.task.Pulse; +import core.game.world.map.Location; +import core.game.world.map.build.DynamicRegion; +import core.game.world.map.zone.ZoneRestriction; +import core.plugin.Initializable; +import core.tools.RandomFunction; +import core.game.world.GameWorld; +import core.game.world.repository.Repository; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +/** + * Handles the Tzhaar Fight caves plugin. + * @author Emperor + */ +@Initializable +public final class TzhaarFightCavesPlugin extends ActivityPlugin { + + /** + * The waves data. + */ + private static final int[][] WAVES = { { 2734, 0 }, { 2736, 2 }, { 2739, 6 }, { 2741, 14 }, { 2743, 30 }, { 2745, 62 } }; + + /** + * The spawn location offsets. + */ + private static final Location[] SPAWN_LOCATIONS = { Location.create(8, 44, 0), Location.create(38, 47, 0), Location.create(5, 9, 0), Location.create(46, 21, 0), Location.create(28, 28, 0), }; + + /** + * The currently active NPCs. + */ + public List activeNPCs = new ArrayList<>(20); + + /** + * Constructs a new {@code TzhaarFightCavesPlugin} {@code Object}. + */ + public TzhaarFightCavesPlugin() { + this(null); + } + + /** + * Constructs a new {@code TzhaarFightCavesPlugin} {@code Object}. + * @param player The player. + */ + public TzhaarFightCavesPlugin(Player player) { + super("fight caves", true, true, true, ZoneRestriction.CANNON, ZoneRestriction.RANDOM_EVENTS); + super.player = player; + } + + @Override + public void register() { + try { + new TzhaarFightCaveNPC().newInstance(null); + } catch (Throwable e) { + e.printStackTrace(); + } + } + + @Override + public boolean canLogout(Player p) { + if (!p.getAttribute("fc_safe_logout", false)) { + p.setAttribute("fc_safe_logout", true); + p.getPacketDispatch().sendMessage("Your logout request has been received. The minigame will be paused at the end"); + p.getPacketDispatch().sendMessage("of this wave."); + p.getPacketDispatch().sendMessage("If you try to logout before that, you will have to repeat this wave."); + return false; + } + return super.canLogout(p); + } + + @Override + public boolean start(final Player player, boolean login, Object... args) { + player.getAchievementDiaryManager().finishTask(player, DiaryType.KARAMJA, 0, 8); + this.player = player; + player.lock(3); + int offsetX = player.getAttribute("fc_offset", 45 << 8) >> 8; + int offsetY = player.getAttribute("fc_offset", 61) & 0xff; + player.removeAttribute("fc_offset"); + player.getProperties().setTeleportLocation(getBase().transform(offsetX, offsetY, 0)); + Pulse pulse; + boolean practice = player.getAttribute("fc_practice_jad", false); + if (!login && !practice) { + final int wave = 0; + player.setAttribute("fc_wave", wave); + player.getWalkingQueue().reset(); + pulse = new Pulse(1, player) { + int count = 0; + + @Override + public boolean pulse() { + if (count++ == 0) { + player.getWalkingQueue().reset(); + player.getWalkingQueue().addPath(getBase().getX() + 44, getBase().getY() + 49, true); + player.getWalkingQueue().addPath(getBase().getX() + 32, getBase().getY() + 32, true); + player.getDialogueInterpreter().sendDialogues(2617, null, "You're on your own now, JalYt.", "Prepare to fight for your life!"); + } else if (count == 16) { + spawnWave(wave); + return true; + } + return false; + } + }; + } else { + if (practice) { + player.setAttribute("fc_wave", 62); + } + if (player.getAttribute("fc_wave", 0) == 62) { + player.getDialogueInterpreter().sendDialogues(2617, null, "Look out, here comes TzTok-Jad!"); + } + pulse = new Pulse(16, player) { + @Override + public boolean pulse() { + spawnWave(player.getAttribute("fc_wave", 0)); + return true; + } + }; + } + player.setAttribute("fc:pulse", pulse); + GameWorld.getPulser().submit(pulse); + return true; + } + + /** + * Leaves the fight caves activity. + * @param player The player. + * @param wave The current wave. + */ + public void leave(Player player, int wave) { + activeNPCs.clear(); + player.getProperties().setTeleportLocation(getSpawnLocation()); + player.getSkills().restore(); + player.timers.removeTimer("poison"); + player.timers.removeTimer("disease"); + player.timers.removeTimer("teleblock"); + player.getSettings().updateRunEnergy(-100); + boolean practice = player.getAttribute("fc_practice_jad", false); + if (wave == 63) { + if (!practice) { + if (!player.getInventory().add(new Item(6570))) { + GroundItemManager.create(new Item(6570), getSpawnLocation(), player); + } + } else { + // give player the appearance fee back + int amount = 8000; + if (!player.getInventory().add(new Item(6529, amount))) { + GroundItemManager.create(new Item(6529, amount), getSpawnLocation(), player); + } + } + player.getPacketDispatch().sendMessage("You were victorious!"); + if (!practice) { + BossKillCounter.addtoKillcount(player, 2745); + if (SlayerManager.getInstance(player).getTask() == Tasks.JAD) { + player.getSkills().addExperience(Skills.SLAYER, 25000); + SlayerManager.getInstance(player).clear(); + player.sendMessage("You receive 25,000 slayer experience for defeating TzTok-Jad."); + } + player.getDialogueInterpreter().sendDialogues(2617, null, "You even defeated TzTok-Jad, I am most impressed!", "Please accept this gift as a reward."); + Repository.sendNews(player.getUsername() + " has been victorious in defeating TzTok-Jad for a firecape!"); + } else { + player.getDialogueInterpreter().sendDialogues(2617, null, "You defeated TzTok-Jad. I am most impressed!", "Here is you TokKul back.", "Maybe next time you do all training, and get real reward..."); + } + } else if (wave <= 1) { + player.getDialogueInterpreter().sendDialogues(2617, null, "Well I suppose you tried... better luck next time."); + } else { + if (!practice) { + player.getDialogueInterpreter().sendDialogues(2617, null, "Well done in the cave, here, take TokKul as reward."); + } else { + player.getDialogueInterpreter().sendDialogues(2617, null, "You both impatient and also failure.", "Better luck next time."); + } + } + + if (!practice) { + int amount = wave << 7; + if (amount > 0 && !player.getInventory().add(new Item(6529, amount))) { + GroundItemManager.create(new Item(6529, amount), getSpawnLocation(), player); + } + } + + } + + @Override + public boolean enter(final Entity e) { + e.setAttribute("fight_caves", true); + return super.enter(e); + } + + @Override + public boolean leave(final Entity e, boolean logout) { + unregisterRegion(region.getId()); + if (logout) { + Location l = player.getLocation(); + player.setAttribute("/save:fc_offset", (l.getX() - getBase().getX()) << 8 | (l.getY() - getBase().getY())); + } else { + player.removeAttribute("fc_offset"); + player.removeAttribute("fc_wave"); + player.removeAttribute("fc_practice_jad"); + player.removeAttribute("fc_safe_logout"); + Pulse pulse = player.getAttribute("fc:pulse"); + if (pulse != null) { + pulse.stop(); + player.removeAttribute("fc:pulse"); + } + } + player.removeAttribute("fight_caves"); + return super.leave(e, logout); + } + + @Override + public boolean death(Entity e, Entity killer) { + if (e instanceof NPC) { + NPC n = (NPC) e; + if (n.getId() == 2736 || n.getId() == 2737) { + new TzhaarFightCaveNPC(2738, n.getLocation(), this).init(); + new TzhaarFightCaveNPC(2738, n.getLocation().transform(1, 0, 0), this).init(); + } + if (activeNPCs.contains(n)) { + activeNPCs.remove(n); + if (n.getId() == 2745) { + player.setAttribute("/save:fc_wave", 63); + leave((Player) killer, 63); + } else if (activeNPCs.isEmpty()) { + final int wave = player.getAttribute("fc_wave", 0) + 1; + player.setAttribute("/save:fc_wave", wave); + if (player.getAttribute("fc_safe_logout", false)) { + player.getPacketDispatch().sendLogout(); + } else { + if (wave == 62) { + player.getDialogueInterpreter().sendDialogues(2617, null, "Look out, here comes TzTok-Jad!"); + } + Pulse pulse = new Pulse(9, player) { + @Override + public boolean pulse() { + spawnWave(wave); + return true; + } + }; + player.setAttribute("fc:pulse", pulse); + GameWorld.getPulser().submit(pulse); + } + } + } + e.clear(); + } else { + leave((Player) e, e.getAttribute("fc_wave", 0)); + } + + /* Kludge to fix this plugin overriding the base NPC death finalization + * resulting in not dispatching the proper NPC kill event. */ + if (e instanceof NPC) + killer.dispatch(new NPCKillEvent(e.asNpc())); + return true; + } + + /** + * Spawns the wave for the player. + * @param wave The wave to spawn. + */ + public void spawnWave(int wave) { + player.setAttribute("/save:fc_wave", wave); + int count = wave; + for (int i = WAVES.length - 1; i >= 0; i--) { + if (count >= WAVES[i][1]) { + if (count > WAVES[i][1] * 2) { + spawn(WAVES[i][0] + 1); + count -= (WAVES[i][1] + 1); + } + spawn(WAVES[i][0]); + count -= WAVES[i][1] + 1; + } + } + player.getPacketDispatch().sendMessage("Current wave: " + (wave + 1) + "."); + } + + /** + * Spawns a tzhaar NPC. + * @param npcId The NPC. + * @return The NPC. + */ + public TzhaarFightCaveNPC spawn(int npcId) { + Random r = RandomFunction.RANDOM; + Location l = SPAWN_LOCATIONS[r.nextInt(SPAWN_LOCATIONS.length)]; + TzhaarFightCaveNPC npc = new TzhaarFightCaveNPC(npcId, getBase().transform(l).transform(r.nextInt(8), r.nextInt(8), 0), this); + npc.init(); + return npc; + } + + @Override + public boolean interact(Entity e, Node target, Option option) { + if (target instanceof Scenery && ((Scenery) target).getId() == 9357) { + leave((Player) e, e.getAttribute("fc_wave", 0)); + player.removeAttribute("fc_wave"); + player.removeAttribute("fc_offset"); + player.removeAttribute("fc_practice_jad"); + return true; + } + return false; + } + + @Override + public ActivityPlugin newInstance(Player p) throws Throwable { + return new TzhaarFightCavesPlugin(p); + } + + @Override + public Location getSpawnLocation() { + return Location.create(2438, 5169, 0); + } + + @Override + public void configure() { + region = DynamicRegion.create(9551); + setRegionBase(); + registerRegion(region.getId()); + region.setMusicId(473); + } + +} diff --git a/Server/src/main/content/region/karamja/tzhaar/handlers/TzhaarFightPitsPlugin.java b/Server/src/main/content/region/karamja/tzhaar/handlers/TzhaarFightPitsPlugin.java new file mode 100644 index 0000000..5070b76 --- /dev/null +++ b/Server/src/main/content/region/karamja/tzhaar/handlers/TzhaarFightPitsPlugin.java @@ -0,0 +1,456 @@ +package content.region.karamja.tzhaar.handlers; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Random; + +import core.game.component.Component; +import core.game.container.impl.EquipmentContainer; +import core.game.activity.ActivityPlugin; +import core.plugin.Initializable; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.skill.Skills; +import core.game.interaction.Option; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.DeathTask; +import core.game.node.entity.combat.ImpactHandler.HitsplatType; +import core.game.node.entity.impl.ForceMovement; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneRestriction; +import core.tools.RandomFunction; + +import static core.api.ContentAPIKt.*; + +/** + * Handles the Tzhaar Fight pits. + * @author Emperor + */ +@Initializable +public final class TzhaarFightPitsPlugin extends ActivityPlugin { + + /** + * The zone where players battle. + */ + private static final ZoneBorders WAR_ZONE = new ZoneBorders(2368, 5120, 2420, 5168); + + /** + * The lobby list. + */ + private static final List LOBBY_PLAYERS = new ArrayList<>(20); + + /** + * The players in battle list. + */ + private static final List WAR_PLAYERS = new ArrayList<>(20); + + /** + * The interface id. + */ + private static final int INTERFACE_ID = 373; + + /** + * The skull id. + */ + private static final int SKULL_ID = 1; + + /** + * The minutes elapsed in the minigame (resets depending on the game + * schedule). + */ + private static int minutes = 0; + + /** + * The amount of tokkul to receive. + */ + private static int tokkulAmount; + + /** + * The last player who's won the pits. + */ + private static Player lastVictor; + + /** + * The pulse used. + */ + private static final Pulse PULSE = new Pulse(100) { + @Override + public boolean pulse() { + if (++minutes == 3) { + startGameSession(); + } else if (minutes == 4) { + sendDialogue("FIGHT!"); + } else if ((minutes - 0) > 4) { + spawnWave(); + } + return false; + } + }; + + /** + * Sends a dialogue to all players in battle. + * @param string The string. + */ + private static void sendDialogue(String string) { + for (Player p : WAR_PLAYERS) { + p.getDialogueInterpreter().sendDialogues(2618, FacialExpression.HALF_GUILTY, string); + } + } + + /** + * Constructs a new {@code TzhaarFightPitsPlugin} {@code Object}. + */ + public TzhaarFightPitsPlugin() { + super("fight pits", false, true, true, ZoneRestriction.CANNON); + } + + @Override + public boolean continueAttack(Entity e, Node target, CombatStyle style, boolean message) { + if (target instanceof Player && !WAR_PLAYERS.contains(target)) { + return false; // Safety check + } + if (minutes < 4 && e instanceof Player) { + ((Player) e).getPacketDispatch().sendMessage("The fight hasn't started yet."); + } + return minutes > 3; + } + + /** + * Removes an entity from the war zone. + * @param e The entity. + */ + public void removeFromBattle(Entity e) { + if (WAR_PLAYERS.remove(e)) { + if (WAR_PLAYERS.size() < 2) { + if (!WAR_PLAYERS.isEmpty()) { + resetLastVictor(); + lastVictor = WAR_PLAYERS.get(0); + // Become the Champion of the Fight Pits + if (lastVictor != null) { + lastVictor.getAchievementDiaryManager().finishTask(lastVictor, DiaryType.KARAMJA, 2, 0); + addTokkul(lastVictor); + lastVictor.getAppearance().setSkullIcon(SKULL_ID); + lastVictor.updateAppearance(); + lastVictor.getPacketDispatch().sendString("Current Champion: " + getChampionName(), INTERFACE_ID, 0); + resetDamagePulse(lastVictor); + } + RegionManager.forId(9552).getPlanes()[0].getNpcs().get(0).setAttribute("fp_champn", getChampionName()); + } + minutes = 0; + } + sendPlayersRemaining(WAR_PLAYERS.size() - 1); + } + if (e instanceof Player && !LOBBY_PLAYERS.contains(e)) { + LOBBY_PLAYERS.add(player = (Player) e); + player.getSkullManager().setSkullCheckDisabled(false); + player.getSkullManager().setWilderness(false); + player.getInterfaceManager().closeOverlay(); + player.getInteraction().remove(Option._P_ATTACK); + if (player.getAppearance().getSkullIcon() == SKULL_ID) { + player.getAppearance().setSkullIcon(-1); + player.updateAppearance(); + } + } + } + + /** + * Resets the damage pulse. + * @param e The entity. + */ + public static void resetDamagePulse(Entity e) { + Pulse pl = e.getAttribute("fp_pulse", null); + if (pl != null) { + pl.stop(); + e.removeAttribute("fp_pulse"); + } + } + + /** + * Resets the last victor. + */ + private void resetLastVictor() { + List npcs = new ArrayList<>(RegionManager.forId(9552).getPlanes()[0].getNpcs()); + for (NPC n : npcs) { + if (n.getId() == 2734 || n.getId() == 2739) { + n.clear(); + } + } + if (lastVictor == null || !lastVictor.isActive()) { + return; + } + if (lastVictor.getAppearance().getSkullIcon() == SKULL_ID) { + player.getAppearance().setSkullIcon(-1); + player.updateAppearance(); + } + } + + @Override + public boolean death(Entity e, Entity killer) { + if (e instanceof Player) { + removeFromBattle(e); + } + return false; + } + + @Override + public boolean start(Player player, boolean login, Object... args) { + player.getAchievementDiaryManager().finishTask(player, DiaryType.KARAMJA, 0, 8); + if (!login) { + player.setAttribute("fight_pits", true); + ForceMovement.run(player, Location.create(2399, 5177, 0), Location.create(2399, 5175, 0)); + return true; + } + if (WAR_ZONE.insideBorder(player.getLocation().getX(), player.getLocation().getY())) { + player.getProperties().setTeleportLocation(Location.create(2399, 5177, 0)); + } + return false; + } + + @Override + public boolean enter(Entity e) { + if (e instanceof Player) { + if (!e.getAttribute("fight_pits", false)) { + return false; + } + LOBBY_PLAYERS.add((Player) e); + } + return super.enter(e); + } + + @Override + public boolean leave(Entity e, boolean logout) { + if (WAR_PLAYERS.contains(e)) { + removeFromBattle(e); + } + LOBBY_PLAYERS.remove(e); + if (logout) { + e.setLocation(Location.create(2399, 5177, 0)); + } + if (e instanceof Player && (player = (Player) e).getAppearance().getSkullIcon() == SKULL_ID) { + player.getAppearance().setSkullIcon(-1); + player.updateAppearance(); + } + return super.leave(e, logout); + } + + @Override + public boolean interact(Entity e, Node target, Option option) { + if (target instanceof Scenery) { + Scenery o = (Scenery) target; + if (o.getId() == 9369) { + ForceMovement.run(e, Location.create(2399, 5175, 0), Location.create(2399, 5177, 0)); + return true; + } + if (o.getId() == 9368) { + if (WAR_PLAYERS.contains(e)) { + removeFromBattle(e); + ForceMovement.run(e, Location.create(2399, 5167, 0), Location.create(2399, 5169, 0)); + return true; + } + ((Player) e).getPacketDispatch().sendMessage("This vent is too hot for you to pass!"); + return true; + } + } + return false; + } + + @Override + public Location getSpawnLocation() { + Random r = RandomFunction.RANDOM; + int x = 2395 + r.nextInt(8); + int y = 5170 + r.nextInt(5); + if (x == 2399 && y == 5172) { + y--; + } + return Location.create(x, y, 0); + } + + @Override + public void configure() { + register(new ZoneBorders(2368, 5120, 2420, 5176)); + PULSE.start(); + GameWorld.getPulser().submit(PULSE); + } + + @Override + public ActivityPlugin newInstance(Player p) throws Throwable { + return this; + } + + /** + * Spawns a wave in the fight pits minigame. + */ + private static void spawnWave() { + int stage = (minutes - 4) / 5; + switch (stage) { + case 1: + for (Player p : WAR_PLAYERS) { + for (int i = 0; i < 2 + ((minutes - 4) >> 2); i++) { + NPC n = NPC.create(2734, getZoneDestination()); + n.init(); + n.setAggressive(true); + n.setDefaultBehavior(); + n.getProperties().getCombatPulse().attack(p); + } + } + break; + case 2: + for (Player p : WAR_PLAYERS) { + for (int i = 0; i < 2 + ((minutes - 4) >> 2); i++) { + NPC n = NPC.create(2739, getZoneDestination()); + n.init(); + n.getProperties().getCombatPulse().attack(p); + } + } + break; + case 3: + for (final Player p : WAR_PLAYERS) { + Pulse pl = new Pulse(1, p) { + int count = 0; + + @Override + public boolean pulse() { + if (DeathTask.isDead(p)) { + return true; + } + p.getImpactHandler().manualHit(p, 1, HitsplatType.NORMAL); + p.getImpactHandler().manualHit(p, 1, HitsplatType.NORMAL); + return ++count == 100; + } + }; + p.setAttribute("fp_pulse", pl); + GameWorld.getPulser().submit(pl); + } + break; + } + } + + /** + * Starts a new game session. + */ + private static void startGameSession() { + if (LOBBY_PLAYERS.size() + WAR_PLAYERS.size() < 2) { + minutes = 2; + if (LOBBY_PLAYERS.size() == 1) { + LOBBY_PLAYERS.get(0).getPacketDispatch().sendMessage("There's not enough players to start the game."); + } + return; + } + tokkulAmount = 0; + String victor = null; + if (lastVictor != null) { + victor = "Current Champion: " + getChampionName();// JalYt-Mej-" + + // lastVictor.getUsername(); + } + int size = (LOBBY_PLAYERS.size() + WAR_PLAYERS.size()) - 1; + if (!WAR_PLAYERS.isEmpty()) { + setVarp(WAR_PLAYERS.get(0), 560, size); + } + for (Iterator it = LOBBY_PLAYERS.iterator(); it.hasNext();) { + Player p = it.next(); + if (p != null && p.isActive()) { + WAR_PLAYERS.add(p); + p.getInterfaceManager().openOverlay(new Component(INTERFACE_ID)); + if (victor != null) { + p.getPacketDispatch().sendString(victor, INTERFACE_ID, 0); + } + p.getSkullManager().setSkullCheckDisabled(true); + p.getSkullManager().setWilderness(true); + setVarp(p, 560, size); + p.getProperties().setTeleportLocation(getZoneDestination()); + p.getInteraction().set(Option._P_ATTACK); + tokkulAmount += p.getProperties().getCurrentCombatLevel(); + } + it.remove(); + } + sendDialogue("Wait for my signal before fighting."); + } + + /** + * Gets the Tzhaar name of the current champion. + * @return The champion name. + */ + private static String getChampionName() { + int strength = lastVictor.getSkills().getStaticLevel(Skills.STRENGTH); + int defence = lastVictor.getSkills().getStaticLevel(Skills.DEFENCE); + int count = 0; + for (int i = 5; i < 23; i++) { + int skill; + if ((skill = lastVictor.getSkills().getStaticLevel(i)) > strength && skill > defence) { + if (++count == 5) { + return "JalYt-Hur-" + lastVictor.getUsername(); + } + } + } + int skill = lastVictor.getSkills().getHighestCombatSkillId(); + switch (skill) { + case Skills.ATTACK: + case Skills.STRENGTH: + return "JalYt-Ket-" + lastVictor.getUsername(); + case Skills.RANGE: + return "JalYt-Xil-" + lastVictor.getUsername(); + case Skills.MAGIC: + return "JalYt-Mej-" + lastVictor.getUsername(); + } + return "JalYtHur-" + lastVictor.getUsername(); + } + + /** + * Adds the tokkul. + * @param p The player to receive the tokkul. + */ + public static void addTokkul(Player p) { + int amount = tokkulAmount; + if (p.getEquipment().getNew(EquipmentContainer.SLOT_CAPE).getId() == 6570) { + amount *= 2; + } + if (amount > 0) { + if (!p.getInventory().add(new Item(6529, amount))) { + p.getPacketDispatch().sendMessage("Your Tokkul reward was added to your bank."); + p.getBank().add(new Item(6529, amount)); + } + } + } + + /** + * Gets the teleport destination in the war zone. + * @return The location. + */ + private static Location getZoneDestination() { + switch (RandomFunction.randomize(5)) { + case 0: + return Location.create(2384 + RandomFunction.random(29), 5133 + RandomFunction.random(4), 0); + case 1: + return Location.create(2410 + RandomFunction.random(4), 5140 + RandomFunction.random(18), 0); + case 2: + return Location.create(2392 + RandomFunction.random(11), 5141 + RandomFunction.random(26), 0); + case 3: + return Location.create(2383 + RandomFunction.random(3), 5141 + RandomFunction.random(15), 0); + case 4: + return Location.create(2392 + RandomFunction.random(12), 5145 + RandomFunction.random(20), 0); + } + return null; + } + + /** + * Sends the foes remaining count to all players. + * @param value The value. + */ + public static void sendPlayersRemaining(int value) { + for (Player p : WAR_PLAYERS) { + setVarp(p, 560, value); + } + } + +} diff --git a/Server/src/main/content/region/karamja/tzhaar/handlers/TzhaarZone.java b/Server/src/main/content/region/karamja/tzhaar/handlers/TzhaarZone.java new file mode 100644 index 0000000..dc3b2e1 --- /dev/null +++ b/Server/src/main/content/region/karamja/tzhaar/handlers/TzhaarZone.java @@ -0,0 +1,40 @@ +package content.region.karamja.tzhaar.handlers; + +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneBuilder; +import core.game.world.map.zone.ZoneRestriction; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Handles the tzhaar zone. + * @author Vexia + */ +@Initializable +public class TzhaarZone extends MapZone implements Plugin { + + /** + * Constructs a new {@code TzhaarZone} {@code Object} + */ + public TzhaarZone() { + super("Tzhaar zone", true, ZoneRestriction.CANNON); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ZoneBuilder.configure(this); + return this; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public void configure() { + register(new ZoneBorders(2369, 5054, 2549, 5188)); + } + +} diff --git a/Server/src/main/content/region/misc/apeatoll/dialogue/bananaplantation/BonzaraDialogue.kt b/Server/src/main/content/region/misc/apeatoll/dialogue/bananaplantation/BonzaraDialogue.kt new file mode 100644 index 0000000..5eee207 --- /dev/null +++ b/Server/src/main/content/region/misc/apeatoll/dialogue/bananaplantation/BonzaraDialogue.kt @@ -0,0 +1,54 @@ +package content.region.misc.apeatoll.dialogue.bananaplantation + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class BonzaraDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npcl(FacialExpression.OLD_DEFAULT,"It looks like you're trying to escape. Would you like some help?").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> options("Yes", "No").also { stage++ } + 1 -> when (buttonId) { + 1 -> player(FacialExpression.WORRIED, "I ... uh ... yes.").also { stage = 10 } + 2 -> playerl(FacialExpression.ASKING, "No thank you. Who are you by the way?").also { stage = 20 } + } + + 10 -> npc(FacialExpression.OLD_DEFAULT, "Right you are.").also { stage++ } + 11 -> { + end() + //teleport to ape atoll + } + + 20 -> npcl(FacialExpression.OLD_DEFAULT, "Never mind that child. You should worry more about who you are and the nature of the forces that have driven you here.").also { stage++ } + 21 -> player(FacialExpression.THINKING, "I'll ... keep that in mind, thanks.").also { stage++ } + 22 -> npc(FacialExpression.OLD_DEFAULT, "We WILL meet again, " + player.username + ".").also { stage++ } + 23 -> player(FacialExpression.SUSPICIOUS, "Ok...").also { stage = 99 } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return BonzaraDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.BONZARA_1468) + } +} diff --git a/Server/src/main/content/region/misc/apeatoll/dialogue/dungeon/ZooknockDialogue.kt b/Server/src/main/content/region/misc/apeatoll/dialogue/dungeon/ZooknockDialogue.kt new file mode 100644 index 0000000..c84225b --- /dev/null +++ b/Server/src/main/content/region/misc/apeatoll/dialogue/dungeon/ZooknockDialogue.kt @@ -0,0 +1,145 @@ +package content.region.misc.apeatoll.dialogue.dungeon + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + * using temporary variables until quest is actually added + */ + +@Initializable +class ZooknockDialogue(player: Player? = null) : DialoguePlugin(player){ + + + var fr = FacialExpression.FRIENDLY + var neu = FacialExpression.NEUTRAL + var ask = FacialExpression.ASKING + var nor = FacialExpression.OLD_NORMAL + var ntalk1 = FacialExpression.OLD_CALM_TALK1 + var ntalk2 = FacialExpression.OLD_CALM_TALK2 + + var hasSpokenToZook = false + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + if (!hasSpokenToZook) { + player(ask, "Hello?").also { stage = 1 } + } else { + options("What do we need for the monkey amulet?", "What do we need for the monkey talisman?").also { stage = 57 } + } + + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 1 -> npc(ntalk1, "A human ... here? What business have you on Ape Atoll?").also { stage++ } + 2 -> playerl(neu, "I am on a mission for King Narode Shareen of the Gnomes.").also { stage++ } + 3 -> playerl(neu, "I have been sent to investigate the whereabouts of the 10th squad of his Royal Guard, which went missing during a recent mission to Karamja.").also { stage++ } + 4 -> npc(ntalk1, "Well you've found us - what's left of us, that is.").also { stage++ } + 5 -> npcl(ntalk2, "I am Zooknock, the 10th squad mage. These are Bunkwicker and Waymottin, two of our finest sappers. I assme you will want to know how we got here?").also { stage++ } + 6 -> player(neu, "Of course.").also { stage++ } + 7 -> npcl(ntalk1, "Your story first, human. What possessed you to travel to this forsaken island?").also { stage++ } + 8 -> playerl(neu, "I am currently in the service of your King. I was the human who exposed Glough's warfaring plans and defeated his demon.").also { stage++ } + 9 -> playerl(neu, "As far as I understand, the 10th squad were sent to oversee the decomission of Glough's shipyard in east Karamja.").also { stage++ } + 10 -> playerl(neu, "Rumour has it you were blown off course. The King worried as to your fate, and sent me to investigate.").also { stage++ } + 11 -> npc(ntalk1, "You were sent alone?").also { stage++ } + 12 -> playerl(neu, "No, I have been accompanied by Flight Commander Waydar. We flew south on a special type of glider and landed on a small island to our east.").also { stage++ } + 13 -> npcl(ntalk2, "The so called Crash Island. We left there one of our number, Lumdo, to guard our gliders until our return.").also { stage++ } + 14 -> player(neu, "Yes, we have met. He ferried me across to the atoll.").also { stage++ } + 15 -> npcl(FacialExpression.OLD_ANGRY1, "He did!? He was explicitly ordered to guard the gliders! How did this happen? Who is guarding the gliders now?").also { stage++ } + 16 -> playerl(ntalk1, "Waydar ordered him to leave his post. He is guarding the gliders himself.").also { stage++ } + 17 -> npcl(ntalk2, "Flight Commander Waydar you said? For some reason that name is familiar...").also { stage++ } + 18 -> player(ask, "So why are you here?").also { stage++ } + 19 -> npcl(ntalk2, "The rumours are correct. We were indeed blown off course. Fortunately, we managed to find a small island to steer our gliders towards, else we surely would have drowned.").also { stage++ } + 20 -> playerl(neu, "Then you gathered enough wood to fashion two boats. Your Sergeant and the rest of the 10th squad took the larger boat to this island, leaving Lumdo to guard the gliders and the other boat...").also { stage++ } + 21 -> npc(ntalk1, "Correct. I assume Lumdo told you this?").also { stage++ } + 22 -> player(ask, "Yes. What happened when you landed here?").also { stage++ } + 23 -> npcl(ntalk2, "We split up into several small groups to search the island for potential gnome glider launch sites. Whilst we knew the island to be inhabited, we did not expect its occupants to be quite so ... militant.").also { stage++ } + 24 -> player(FacialExpression.THINKING, "...").also { stage++ } + 25 -> npcl(ntalk1, "Monkeys. Lots of monkeys. They are unlike any other type of monkey we've come across. A far cry from the usual wild variety, these were armed with high quality weaponry and uncanny tactical ability.").also { stage++ } + 26 -> npcl(ntalk2, "We were overwhelmed in numbers. Some of us managed to escape, but the rest were taken captive.").also { stage++ } + 27 -> player(ask, "Who survived?").also { stage++ } + 28 -> npcl(ntalk1, "Myself, the Sergeant, Bunwicker and Waymottin here. Karam, our assassin, probably managed to escape - he usually does.").also { stage++ } + 29 -> player(ask, "And of the rest?").also { stage++ } + 30 -> npcl(ntalk1, "Lumo, Bunkdo and Carado were captured, as I said. We believe they are being held in the jail. We are working on a way to release them. I have sensed there lies a cavern to the north.").also { stage++ } + 31 -> npcl(ntalk2, "We are attempting to tunnel to this northern cavern and then move upwards from there.").also { stage++ } + 32 -> player(ask, "Why don't you just go overground?").also { stage++ } + 33 -> npcl(ntalk2, "We have considered this, but every entrance seems to be excessively guarded.").also { stage++ } + 34 -> player(ask, "I see.").also { stage++ } + 35 -> playerl(ask, "I have spoken to your Sergeant. He believes that the best way to rescue the rest of your squad with the minimum of casualties is to have an insider - a monkey working for us.").also { stage++ } + 36 -> npc(ntalk1, "Aha. He wants me to turn you into a monkey.").also { stage++ } + 37 -> player(ask, "Actually, it was more along the lines of a disguise...").also { stage++ } + 38 -> npcl(ntalk1, "I think you misunderstand, human. Do you know why you were sent here?").also { stage++ } + 39 -> player(ask, "King Narode Shareen asked me to...").also { stage++ } + 40 -> npcl(ntalk1, "Indeed. However, King Narode Shareen is still in contact with Garkor! You were sent here because Garkot specifically asked Narode for you!").also { stage++ } + 41 -> player(ask, "Why wasn't I told?").also { stage++ } + 42 -> npcl(ntalk2, "Before you arrived on this island, that information would have endangered both yourself and the mission.").also { stage++ } + 43 -> player(ask, "But why a human? Why me?").also { stage++ } + 44 -> npcl(ntalk1, "Garkor had long decided that we need a monkey insider. I have the necessary magic to perform the shapeshifting spell, but we needed a human to transform.").also { stage++ } + 45 -> player(ask, "Why don't you just transform a gnome?").also { stage++ } + 46 -> npcl(ntalk2, "It has been tried in the past, but the results were far from ... satisfactory. Although we, like you, are related to the monkeys, the link is too weak for a successful transformation.").also { stage++ } + 47 -> npc(ntalk1, "That is why we need you.").also { stage++ } + 48 -> player(ask, "Right. What do I have to do?").also { stage++ } + 49 -> npcl(ntalk1, "There will be two aspects to your transformation. We must first arrange it so that you are able to understand and communicate with the monkeys.").also { stage++ } + 50 -> npcl(ntalk2, "We must also transform your body so that you may pass amongst them unnoticed.").also { stage++ } + 51 -> npcl(ntalk1, "So that the effects of my spells are not permanent, I will invest their power into magical items which you must find. You can then use them at your will.").also { stage++ } + 52 -> player(ask, "What kind of items?").also { stage++ } + 53 -> npcl(ntalk2, "For the spells to take full effect, they will have to be in some way related to the monkeys.").also { stage++ } + 54 -> npcl(ntalk1, "I suggest that I invest the ability to communicate with the monkeys in an authentic monkey amulet.").also { stage++ } + 55 -> { + hasSpokenToZook = true + npcl(ntalk1, "Similarily, the transformation spell should be stored in a monkey talisman of some kind.").also { stage++ } + } + 56 -> options("What do we need for the monkey amulet?", "What do we need for the monkey talisman?").also { stage++ } + 57 -> when (buttonId) { + 1 -> player(ask, "What do we need for the monkey amulet?").also { stage = 60 } + 2 -> player(ask, "What do we need for the monkey talisman?").also { stage = 100 } + } + + 60 -> npcl(ntalk1, "We need a gold bar, a monkey amulet mould and something to do monkey speech.").also { stage++ } + 61 -> options("Where do I find the gold bar?", "Where do I find a monkey amulet mould?", "Where do I find something to do with monkey speech?", "I'll be back later.").also { stage++ } + 62 -> when (buttonId) { + 1 -> player(ask, "Where do I find the gold bar?").also { stage = 70 } + 2 -> player(ask, "Where do I find a monkey amulet mould?").also { stage = 80 } + 3 -> player(ask, "Where do I find something to do with monkey speech?").also { stage = 90 } + 4 -> player(neu, "I'll be back later.").also { stage = 99 } + } + + 70 -> npcl(ntalk1, "I am not sure. You look wealthy enough to know the answer to that question anyway.").also { stage = 61 } + 80 -> npcl(ntalk1, "They ought to be for sale in the village, but be careful: you probably will not be able to walk straight in and buy one.").also { stage = 61 } + 90 -> npc(ntalk2, "I don't know. I'm sure you'll think of something.").also { stage = 61 } + + 100 -> npcl(nor, "We need some kind of monkey remains as well as an authentic magical monkey talisman.").also { stage++ } + 101 -> options("Where do I find monkey remains?", "Where do I find a magical monkey talisman?", "I'll be back later.").also { stage++ } + 102 -> when (buttonId) { + 1 -> player(ask, "Where do I find monkey remains?").also { stage = 110 } + 2 -> player(ask, "Where do I find a magical monkey talisman?").also { stage = 120 } + 3 -> player(neu, "I'll be back later.").also { stage = 99 } + } + + 110 -> npcl(nor, "I'll leave that to your better judgement... However, bear in mind the type of remain might affect the type of monkey you become...").also { stage++ } + 111 -> player(ask, "What if I need to be another type of monkey?").also { stage++ } + 112 -> npcl(ntalk1, "Then bring me different monkey remains and another talisman.").also { stage = 101} + + 120 -> npcl(ntalk2, "There ought to be something in the village. I cannot be sure, as I have not spent much time there.").also { stage = 101 } + + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return ZooknockDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.ZOOKNOCK_1425) + } +} diff --git a/Server/src/main/content/region/misc/apeatoll/dialogue/dungeon/ZooknockDialogueFile.kt b/Server/src/main/content/region/misc/apeatoll/dialogue/dungeon/ZooknockDialogueFile.kt new file mode 100644 index 0000000..7fa68c0 --- /dev/null +++ b/Server/src/main/content/region/misc/apeatoll/dialogue/dungeon/ZooknockDialogueFile.kt @@ -0,0 +1,93 @@ +package content.region.misc.apeatoll.dialogue.dungeon + +import content.global.handlers.item.withnpc.ZooknockListener +import core.api.addItemOrDrop +import core.api.sendDoubleItemDialogue +import core.api.sendItemDialogue +import core.game.node.entity.npc.NPC +import org.rs09.consts.Items +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression + +/** + * @author qmqz + * todo will need to check quest stages for what's been handed over and whatnot + */ + +class ZooknockDialogueFile(val it: Int) : DialogueFile() { + + var i = ZooknockListener() + var n = NPC(i.zooknock) + var itemUsed = it + var hasGivenGoldBar = false + var hasGivenDentures = false + var hasGivenMould = false + + override fun handle(interfaceId: Int, buttonId: Int) { + npc = n + + when (stage) { + 0 -> when (itemUsed) { + i.goldBar -> { + if (!hasGivenGoldBar) { + player(FacialExpression.ASKING, "What do you think of this?").also { stage = 10 } + hasGivenGoldBar = true + } + } + + i.monkeyAmuletMould -> { + if (!hasGivenMould) { + player(FacialExpression.ASKING, "What do you think of this?").also { stage = 20 } + hasGivenMould = true + } + } + + i.monkeyDentures -> { + if (!hasGivenDentures) { + player(FacialExpression.ASKING, "What do you think of this?").also { stage = 30 } + } + } + } + + 10 -> sendItemDialogue(player!!, Items.GOLD_BAR_2357, "You hand Zooknock the gold bar.").also { stage++ } + 11 -> npc(FacialExpression.OLD_CALM_TALK1, "Nicely done.").also { stage++ } + 12 -> { + if (!hasGivenDentures && !hasGivenMould && hasGivenGoldBar) { + npcl(FacialExpression.OLD_CALM_TALK1, "We still need the monkey amulet mould and something to do with monkey speech.").also { stage = 99 } + } + } + + 20 -> sendItemDialogue(player!!, Items.MAMULET_MOULD_4020, "You hand Zooknock the monkey amulet mould.").also { stage++ } + 21 -> npc(FacialExpression.OLD_CALM_TALK1, "Good work.").also { stage++ } + 22 -> { + if (!hasGivenDentures && hasGivenMould && hasGivenGoldBar) { + npcl(FacialExpression.OLD_CALM_TALK1, "We still need something to do with monkey speech.").also { stage = 99 } + } + } + + 30 -> sendItemDialogue(player!!, Items.MSPEAK_AMULET_4021, "You hand Zooknock the magical monkey dentures.").also { stage++ } + 31 -> npc(FacialExpression.OLD_CALM_TALK1, "Good work.").also { stage++ } + 32 -> { + if (hasGivenDentures && hasGivenMould && hasGivenGoldBar) { + npcl(FacialExpression.OLD_CALM_TALK1, "Now listen closely, human. I will cast a spell to enchant this gold bar with the power contained in these monkey dentures.").also { stage = 40 } + } + } + + 40 -> npcl(FacialExpression.OLD_CALM_TALK1, "You must then smith the gold using the monkey amulet mould. However, unless you do this in a place of religious significance to the monkeys, the spirits").also { stage++ } + 41 -> npcl(FacialExpression.OLD_CALM_TALK2, "contained within will likely depart.").also { stage++ } + 42 -> playerl(FacialExpression.FRIENDLY, "Where do I find a place of religious significance to monkeys?").also { stage++ } + 43 -> npcl(FacialExpression.OLD_CALM_TALK1, "Somewhere in the village. It out to be obvious. Now give me a moment.").also { stage++ } + 44 -> { + //zooknock does animation, bla bla bla, waits a few seconds, opens up new next dialog + } + 45 -> { + addItemOrDrop(player!!, Items.ENCHANTED_BAR_4007, 1) + addItemOrDrop(player!!, Items.MAMULET_MOULD_4020, 1) + sendDoubleItemDialogue(player!!, Items.ENCHANTED_BAR_4007, Items.MAMULET_MOULD_4020, "Zooknock hands you back the gold bar and the monkey amulet mould.").also { stage++ } + } + + + 99 -> end() + } + } +} diff --git a/Server/src/main/content/region/misc/apeatoll/dialogue/marim/AberabDialogue.kt b/Server/src/main/content/region/misc/apeatoll/dialogue/marim/AberabDialogue.kt new file mode 100644 index 0000000..5d84c1a --- /dev/null +++ b/Server/src/main/content/region/misc/apeatoll/dialogue/marim/AberabDialogue.kt @@ -0,0 +1,38 @@ +package content.region.misc.apeatoll.dialogue.marim + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable + +/** + * Dialogue for Aberab + * @author qmqz + */ + +@Initializable +class AberabDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npc(FacialExpression.OLD_ANGRY1,"Grr ... Get out of my way...") + stage = 99 + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return AberabDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(1432) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/apeatoll/dialogue/marim/DagaDialogue.kt b/Server/src/main/content/region/misc/apeatoll/dialogue/marim/DagaDialogue.kt new file mode 100644 index 0000000..5be5285 --- /dev/null +++ b/Server/src/main/content/region/misc/apeatoll/dialogue/marim/DagaDialogue.kt @@ -0,0 +1,62 @@ +package content.region.misc.apeatoll.dialogue.marim + +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import core.tools.END_DIALOGUE + +/** + * @author qmqz + * Does not include treasure trails dialogue + */ + +@Initializable +class DagaDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npc(FacialExpression.OLD_DEFAULT,"Would you like to buy or sell some scimitars?").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> options("Yes, please.", "No, thanks.", "Do you have any Dragon Scimitars in stock?").also { stage++ } + + 1 -> when (buttonId) { + 1 -> player(FacialExpression.FRIENDLY, "Yes, please.").also { stage = 10 } + 2 -> player(FacialExpression.FRIENDLY, "No, thanks.").also { stage = END_DIALOGUE } + 3 -> player(FacialExpression.HALF_ASKING, "Do you have any Dragon Scimitars in stock?").also { stage = 30 } + } + + 10 -> end().also { npc.openShop(player) } + + 30 -> npcl(FacialExpression.OLD_DEFAULT, "It just so happens I recently got a fresh delivery, do you want to buy one?").also { stage++ } + 31 -> options("Yes, please.", "No, thanks.").also { stage++ } + + 32 -> when (buttonId) { + 1 -> if (inInventory(player, Items.COINS_995, 100000)) { + end().also { return removeItem(player, Item(Items.COINS_995, 100000)) && addItem(player, Items.DRAGON_SCIMITAR_4587, 1) } + } else { + npcl(FacialExpression.OLD_NORMAL, "Sorry but you don't have enough to buy one, at the moment it costs 100,000 gold coins.").also { stage = END_DIALOGUE } + } + 2 -> player(FacialExpression.FRIENDLY, "No thanks.").also { stage = END_DIALOGUE } + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return DagaDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.DAGA_1434) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/apeatoll/dialogue/marim/ElderGuardDialogue.kt b/Server/src/main/content/region/misc/apeatoll/dialogue/marim/ElderGuardDialogue.kt new file mode 100644 index 0000000..6902cba --- /dev/null +++ b/Server/src/main/content/region/misc/apeatoll/dialogue/marim/ElderGuardDialogue.kt @@ -0,0 +1,63 @@ +package content.region.misc.apeatoll.dialogue.marim + +import core.api.toIntArray +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class ElderGuardDialogue(player: Player? = null) : DialoguePlugin(player){ + + val ids = 4025..4031 + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + + //todo check player pos, if outside, player needs to be unable from entering without speaking, but currently player can clip through monke + var outside = true + //todo check if monke is in the corner + var cornerGuard = false + + if (player.equipment.containsAtLeastOneItem(ids.toIntArray())) { + if (outside) { + npc(FacialExpression.OLD_ANGRY1, "Grrr ... What do you want?").also { stage = 10 } + } else if(cornerGuard){ + npc(FacialExpression.OLD_ANGRY1, "Grrr ... What do you want?").also { stage = 20 } + } else { + npc(FacialExpression.OLD_ANGRY1, "Move!").also { stage = 99 } + } + } else { + //todo monke is gonna knock you out if you don't have a monkey gree gree thang, chicken wang + } + + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 10 -> playerl(FacialExpression.ASKING, "I must speak with Awowogei on a subject of great import.").also { stage ++ } + 11 -> npc(FacialExpression.OLD_NORMAL, "As you wish.").also { stage = 99 } + + 20 -> player(FacialExpression.ASKING, "I would like to leave now.").also { stage ++ } + 21 -> npc(FacialExpression.OLD_NORMAL, "As you wish.").also { stage = 99 } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return ElderGuardDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.ELDER_GUARD_1461, NPCs.ELDER_GUARD_1462) + } +} diff --git a/Server/src/main/content/region/misc/apeatoll/dialogue/marim/MuruwoiDialogue.kt b/Server/src/main/content/region/misc/apeatoll/dialogue/marim/MuruwoiDialogue.kt new file mode 100644 index 0000000..fd621df --- /dev/null +++ b/Server/src/main/content/region/misc/apeatoll/dialogue/marim/MuruwoiDialogue.kt @@ -0,0 +1,39 @@ +package content.region.misc.apeatoll.dialogue.marim + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + * quest dialogue is missing on rs3 and osrs, someone will need to youtube it + */ + +@Initializable +class MuruwoiDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npc(FacialExpression.OLD_ANGRY1,"Grr ... Get out of my way...") + stage = 99 + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return MuruwoiDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.MURUWOI_1450) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/apeatoll/dialogue/marim/PadulahDialogue.kt b/Server/src/main/content/region/misc/apeatoll/dialogue/marim/PadulahDialogue.kt new file mode 100644 index 0000000..2eeed97 --- /dev/null +++ b/Server/src/main/content/region/misc/apeatoll/dialogue/marim/PadulahDialogue.kt @@ -0,0 +1,66 @@ +package content.region.misc.apeatoll.dialogue.marim + +import core.api.openDialogue +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class PadulahDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, PadulahDialogueFile(), npc) + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return PadulahDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.PADULAH_1447) + } +} + +class PadulahDialogueFile: DialogueBuilderFile() { + + override fun create(b: DialogueBuilder) { + b.defaultDialogue().npcl( + "What do you want?" + ).playerl( + FacialExpression.NEUTRAL, + "Oh, nothing in particular really." + ).npcl( + "Well stop distracting me then. I'm meant to be guarding this sacred statue from the temple of Marimbo." + ).options().let { optionsBuilder -> optionsBuilder.option("Where is the temple of Marimbo?") + .npcl( + "You're not from around here are you?" + ).playerl( + FacialExpression.NEUTRAL, + "Actually I'm not. I'm a visitor from foreign lands." + ).npcl( + "Very well, the temple is to the east of the village." + ).end() + optionsBuilder.option("What is the statue of? ") + .npcl( + "It's of Marimbo, you cretin!" + ).playerl( + FacialExpression.NEUTRAL, + "Ah yes. How stupid of me not to see the likeness." + ).end() + optionsBuilder.option("I'll be back later.") + .npcl( + "I wouldn't count on it." + ).playerl( + FacialExpression.WORRIED, + "What?!" + ).npcl( + "Oh, nothing." + ).end() + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/apeatoll/quest/monkeymadness/CrateDialogues.kt b/Server/src/main/content/region/misc/apeatoll/quest/monkeymadness/CrateDialogues.kt new file mode 100644 index 0000000..573a361 --- /dev/null +++ b/Server/src/main/content/region/misc/apeatoll/quest/monkeymadness/CrateDialogues.kt @@ -0,0 +1,163 @@ +package content.region.misc.apeatoll.quest.monkeymadness + +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.node.entity.combat.ImpactHandler +import core.game.node.entity.player.link.TeleportManager +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.tools.RandomFunction +import org.rs09.consts.Items +import java.util.concurrent.Executors +import java.util.concurrent.TimeUnit + +/** + * @author qmqz + */ + +class CrateDialogues(val it: Int) : DialogueFile() { + + private val MMDungeon2 = Location.create(2804, 9168, 0) + + override fun handle(interfaceId: Int, buttonId: Int) { + when (it) { + 0 -> when (stage) { + 0 -> sendItemDialogue(player!!, Items.MAMULET_MOULD_4020, "The crate is full of ... monkey amulet moulds!").also { stage++ } + 1 -> player!!.dialogueInterpreter.sendOptions("Do you wish to take one?", "Yes", "No").also { stage++ } + 2 -> when (buttonId) { + 1 -> { + addItemOrDrop(player!!, Items.MAMULET_MOULD_4020) + end() + } + 2 -> end() + } + } + + 1 -> when (stage) { + 0 -> sendItemDialogue(player!!, Items.THREAD_1734, "The crate is full of ... crafting thread.").also { stage++ } + 1 -> player!!.dialogueInterpreter.sendOptions("Do you wish to take one?", "Yes", "No").also { stage++ } + 2 -> when (buttonId) { + 1 -> { + addItemOrDrop(player!!, Items.THREAD_1734) + end() + } + 2 -> end() + } + } + + 2 -> when (stage) { + 0 -> sendItemDialogue(player!!, Items.MONKEY_DENTURES_4006, "The crate is full of ... magical monkey talking dentures!").also { stage++ } + 1 -> player!!.dialogueInterpreter.sendOptions("Do you wish to take one?", "Yes", "No").also { stage++ } + 2 -> when (buttonId) { + 1 -> { + addItemOrDrop(player!!, Items.MONKEY_DENTURES_4006) + end() + } + 2 -> end() + } + } + + 3 -> when (stage) { + 0 -> sendItemDialogue(player!!, Items.BANANA_1963, "The crate is full of ... bananas.").also { stage++ } + 1 -> player!!.dialogueInterpreter.sendOptions("Do you wish to take one?", "Yes", "No").also { stage++ } + 2 -> when (buttonId) { + 1 -> { + addItemOrDrop(player!!, Items.BANANA_1963) + end() + } + 2 -> end() + } + } + + 4 -> when (stage) { + 0 -> sendDialogue( + player!!, + "You find a hole in the floor under the crate! All you can see is the faint glimmer of light from extremely far below." + ).also { stage++ } + 1 -> player!!.dialogueInterpreter.sendOptions( + "Would you like to go down?", + "Yes, I'm sure.", + "No, not yet." + ).also { stage++ } + 2 -> when (buttonId) { + 1 -> sendDialogue(player!!, "You begin to lower yourself into the hole...").also { stage = 10 } + 2 -> end() + } + 10 -> { + end() + openInterface(player!!, 120) + player!!.pulseManager.run(object : Pulse() { + var counter = 0 + override fun pulse(): Boolean { + when (counter++) { + 3 -> teleport(player!!, MMDungeon2, TeleportManager.TeleportType.INSTANT) + } + return false + } + }) + monkeyMadnessGoIntoBasementDamage() + } + } + + 5 -> when (stage) { + 0 -> sendItemDialogue(player!!, Items.TINDERBOX_590, "The crate is full of ... tinderboxes.").also { stage++ } + 1 -> player!!.dialogueInterpreter.sendOptions("Do you wish to take one?", "Yes", "No").also { stage++ } + 2 -> when (buttonId) { + 1 -> { + addItemOrDrop(player!!, Items.TINDERBOX_590) + end() + } + 2 -> end() + } + } + + 6 -> when (stage) { + 0 -> sendItemDialogue(player!!, Items.EYE_OF_GNOME_4008, "The crate is full of ... slimy gnome eyes!").also { stage++ } + 1 -> player!!.dialogueInterpreter.sendOptions("Do you wish to take one?", "Yes", "No").also { stage++ } + 2 -> when (buttonId) { + 1 -> { + addItemOrDrop(player!!, Items.EYE_OF_GNOME_4008) + end() + } + 2 -> end() + } + } + + 7 -> when (stage) { + 0 -> sendItemDialogue(player!!, Items.HAMMER_2347, "The crate is full of ... hammers.").also { stage++ } + 1 -> player!!.dialogueInterpreter.sendOptions("Do you wish to take one?", "Yes", "No").also { stage++ } + 2 -> when (buttonId) { + 1 -> { + addItemOrDrop(player!!, Items.HAMMER_2347) + end() + } + 2 -> end() + } + } + + + + } + } + + private fun monkeyMadnessGoIntoBasementDamage() { + Executors.newSingleThreadScheduledExecutor().schedule({ + if (player!!.location.isInRegion(MMDungeon2.regionId)) { + player!!.interfaceManager.close() + openInterface(player!!, 170) + + player!!.pulseManager.run(object : Pulse() { + var counter = 0 + override fun pulse(): Boolean { + when (counter++) { + 3 -> player!!.impactHandler.manualHit(player, RandomFunction.random(0, player!!.skills.lifepoints / 2), ImpactHandler.HitsplatType.NORMAL) + } + return false + } + }) + } else { + monkeyMadnessGoIntoBasementDamage() + } + }, 1, TimeUnit.SECONDS) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/apeatoll/quest/monkeymadness/CrateHandler.kt b/Server/src/main/content/region/misc/apeatoll/quest/monkeymadness/CrateHandler.kt new file mode 100644 index 0000000..f6b557a --- /dev/null +++ b/Server/src/main/content/region/misc/apeatoll/quest/monkeymadness/CrateHandler.kt @@ -0,0 +1,125 @@ +package content.region.misc.apeatoll.quest.monkeymadness + +import core.api.openDialogue +import core.api.sendMessage +import core.game.system.task.Pulse +import core.game.world.update.flag.context.Animation +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +/** + * @author qmqz + */ + +class CrateHandler : InteractionListener { + + private val monkeyAmuletMouldCrate = 4724 + private val threadCrate = 4718 + private val monkeyTalkingDentures = 4715 + private val bananaCrate = 4723 + private val monkeyMadnessEntranceDown = 4714 + private val tinderboxCrate = 4719 + private val slimyGnomeEyesCrate = 4716 + private val hammersCrate = 4726 + + override fun defineListeners() { + //searching crates with monkey amulet moulds + on(monkeyAmuletMouldCrate, IntType.SCENERY, "search") { player, node -> + player.animator.animate(Animation(536)) + sendMessage(player, "You search the crate.") + openDialogue(player!!, CrateDialogues(0)) + return@on true + } + + on(threadCrate, IntType.SCENERY, "search") { player, node -> + sendMessage(player, "You search the crate.") + player.pulseManager.run(object : Pulse() { + var counter = 0 + override fun pulse(): Boolean { + when (counter++) { + 3 -> openDialogue(player!!, CrateDialogues(1)) + } + return false + } + }) + return@on true + } + + on(monkeyTalkingDentures, IntType.SCENERY, "search") { player, node -> + sendMessage(player, "You search the crate.") + player.pulseManager.run(object : Pulse() { + var counter = 0 + override fun pulse(): Boolean { + when (counter++) { + 3 -> openDialogue(player!!, CrateDialogues(2)) + } + return false + } + }) + return@on true + } + + on(bananaCrate, IntType.SCENERY, "search") { player, node -> + sendMessage(player, "You search the crate.") + player.pulseManager.run(object : Pulse() { + var counter = 0 + override fun pulse(): Boolean { + when (counter++) { + 3 -> openDialogue(player!!, CrateDialogues(3)) + } + return false + } + }) + return@on true + } + + on(monkeyMadnessEntranceDown, IntType.SCENERY, "search") { player, node -> + sendMessage(player, "You search the crate.") + openDialogue(player!!, CrateDialogues(4)) + return@on true + } + + on(tinderboxCrate, IntType.SCENERY, "search") { player, node -> + sendMessage(player, "You search the crate.") + player.pulseManager.run(object : Pulse() { + var counter = 0 + override fun pulse(): Boolean { + when (counter++) { + 3 -> openDialogue(player!!, CrateDialogues(5)) + } + return false + } + }) + return@on true + } + + on(slimyGnomeEyesCrate, IntType.SCENERY, "search") { player, node -> + sendMessage(player, "You search the crate.") + player.pulseManager.run(object : Pulse() { + var counter = 0 + override fun pulse(): Boolean { + when (counter++) { + 3 -> openDialogue(player!!, CrateDialogues(6)) + } + return false + } + }) + return@on true + } + + on(hammersCrate, IntType.SCENERY, "search") { player, node -> + sendMessage(player, "You search the crate.") + player.pulseManager.run(object : Pulse() { + var counter = 0 + override fun pulse(): Boolean { + when (counter++) { + 3 -> openDialogue(player!!, CrateDialogues(7)) + } + return false + } + }) + return@on true + } + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/crandor/handlers/CrandorZone.java b/Server/src/main/content/region/misc/crandor/handlers/CrandorZone.java new file mode 100644 index 0000000..aeaead0 --- /dev/null +++ b/Server/src/main/content/region/misc/crandor/handlers/CrandorZone.java @@ -0,0 +1,46 @@ +package content.region.misc.crandor.handlers; + +import core.game.node.entity.Entity; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneBuilder; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the crandor zone. + * + * @author Vexia + */ +@Initializable +public class CrandorZone extends MapZone implements Plugin { + + /** + * Constructs a new {@code CrandorZone} {@code Object} + */ + public CrandorZone() { + super("crandor", true); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ZoneBuilder.configure(this); + return this; + } + + @Override + public boolean enter(Entity entity) { + return super.enter(entity); + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public void configure() { + register(new ZoneBorders(2813, 3223, 2864, 3312)); + } + +} diff --git a/Server/src/main/content/region/misc/enchvalley/handlers/EnchantedValleyListeners.kt b/Server/src/main/content/region/misc/enchvalley/handlers/EnchantedValleyListeners.kt new file mode 100644 index 0000000..ddcff97 --- /dev/null +++ b/Server/src/main/content/region/misc/enchvalley/handlers/EnchantedValleyListeners.kt @@ -0,0 +1,48 @@ +package content.region.misc.enchvalley.handlers + +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import content.data.skill.SkillingTool +import core.game.system.task.Pulse +import org.rs09.consts.NPCs +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +class EnchantedValleyListeners : InteractionListener { + val ENCHANTED_V_TREE = 16265 + val TREE_SPIRIT_IDS = intArrayOf(NPCs.TREE_SPIRIT_438,NPCs.TREE_SPIRIT_439,NPCs.TREE_SPIRIT_440,NPCs.TREE_SPIRIT_441,NPCs.TREE_SPIRIT_442,NPCs.TREE_SPIRIT_443) + override fun defineListeners() { + + on(ENCHANTED_V_TREE, IntType.SCENERY, "chop-down"){ player, node -> + val tool: SkillingTool? = SkillingTool.getHatchet(player) + tool ?: player.sendMessage("You lack an axe which you have the Woodcutting level to use.").also { return@on true } + + player.pulseManager.run(object : Pulse(){ + var counter = 0 + val n = getSpirit(player) + override fun pulse(): Boolean { + when(counter++){ + 0 -> player.animator.animate(tool?.animation) + 3 -> { + n.location = player.location + n.init() + n.moveStep() + n.isRespawn = false + } + 4 -> n.attack(player) + } + return false + } + }) + return@on true + } + + } + + fun getSpirit(player: Player): NPC { + val level = player.properties.currentCombatLevel + var index = Math.ceil(level / 20.0).toInt() + if(index >= TREE_SPIRIT_IDS.size) index = TREE_SPIRIT_IDS.size - 1 + return NPC(TREE_SPIRIT_IDS[index]) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/entrana/dialogue/CaveMonk.java b/Server/src/main/content/region/misc/entrana/dialogue/CaveMonk.java new file mode 100644 index 0000000..15e7f88 --- /dev/null +++ b/Server/src/main/content/region/misc/entrana/dialogue/CaveMonk.java @@ -0,0 +1,123 @@ +package content.region.misc.entrana.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.world.map.Location; +import content.data.Quests; + +/** + * Represents the dialogue plugin used for a cave monk. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class CaveMonk extends DialoguePlugin { + + /** + * Represents the dungeon location. + */ + private static final Location DUNGEON = Location.create(2822, 9774, 0); + + /** + * The quest. + */ + private Quest quest; + + /** + * Constructs a new {@code CaveMonk} {@code Object}. + */ + public CaveMonk() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code CaveMonk} {@code Object}. + * @param player the player. + */ + public CaveMonk(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new CaveMonk(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + quest = player.getQuestRepository().getQuest(Quests.LOST_CITY); + switch (quest.getStage(player)) { + case 0: + case 10: + player("Hello, what are you doing here?"); + stage = 100; + break; + default: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Be careful going in there! You are unarmed, and there", "is much evilness lurking down there! The evilness seems", "to block off our contact with our gods,"); + stage = 0; + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 100: + npc("None of your business."); + stage = 101; + break; + case 101: + end(); + break; + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "so our prayers seem to have less effect down there. Oh,", "also, you won't be able to come back this way - This", "ladder only goes one way!"); + stage = 1; + break; + case 1: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "The only exit from the caves below is a portal which", "leads only to the deepest wilderness!"); + stage = 2; + break; + case 2: + interpreter.sendOptions("Select an Option", "I don't think I'm strong enough to enter then.", "Well that is a risk I will have to take."); + stage = 3; + break; + case 3: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I don't think I'm strong enough to enter then."); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Well that is a risk I will have to take."); + stage = 20; + break; + } + break; + case 10: + end(); + break; + case 20: + if (player.getSkills().getLevel(Skills.PRAYER) > 2 && player.getSkills().getPrayerPoints() > 2) { + player.getSkills().decrementPrayerPoints(player.getSkills().getLevel(Skills.PRAYER) - 2); + } + player.getProperties().setTeleportLocation(DUNGEON); + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 656 }; + } +} diff --git a/Server/src/main/content/region/misc/entrana/dialogue/ConeDialogue.java b/Server/src/main/content/region/misc/entrana/dialogue/ConeDialogue.java new file mode 100644 index 0000000..e2ba278 --- /dev/null +++ b/Server/src/main/content/region/misc/entrana/dialogue/ConeDialogue.java @@ -0,0 +1,65 @@ +package content.region.misc.entrana.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the dialogue plugin used for the cone npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class ConeDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code ConeDialogue} {@code Object}. + */ + public ConeDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code ConeDialogue} {@code Object}. + * @param player the player. + */ + public ConeDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new ConeDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hello deary."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Um... hello."); + stage = 1; + break; + case 1: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 217 }; + } +} diff --git a/Server/src/main/content/region/misc/entrana/dialogue/EntranaChurchMonk.java b/Server/src/main/content/region/misc/entrana/dialogue/EntranaChurchMonk.java new file mode 100644 index 0000000..4086b19 --- /dev/null +++ b/Server/src/main/content/region/misc/entrana/dialogue/EntranaChurchMonk.java @@ -0,0 +1,61 @@ +package content.region.misc.entrana.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the entrana church monk. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class EntranaChurchMonk extends DialoguePlugin { + + /** + * Constructs a new {@code EntranaChurchMonk} {@code Object}. + */ + public EntranaChurchMonk() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code EntranaChurchMonk} {@code Object}. + * @param player the player. + */ + public EntranaChurchMonk(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new EntranaChurchMonk(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Greetings traveller."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 222 }; + } +} diff --git a/Server/src/main/content/region/misc/entrana/dialogue/FrincosDialogue.java b/Server/src/main/content/region/misc/entrana/dialogue/FrincosDialogue.java new file mode 100644 index 0000000..cc49de3 --- /dev/null +++ b/Server/src/main/content/region/misc/entrana/dialogue/FrincosDialogue.java @@ -0,0 +1,88 @@ +package content.region.misc.entrana.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the dialogue plugin used for the frinco npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class FrincosDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code FrincosDialogue} {@code Object}. + */ + public FrincosDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code FrincosDialogue} {@code Object}. + * @param player the player. + */ + public FrincosDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new FrincosDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hello, how can I help you?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "What are you selling?", "You can't; I'm beyond help.", "I'm okay, thank you."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What are you selling?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "You can't; I'm beyond help."); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'm okay, thank you."); + stage = 30; + break; + } + break; + case 10: + end(); + npc.openShop(player); + break; + case 20: + end(); + break; + case 30: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 578 }; + } +} diff --git a/Server/src/main/content/region/misc/entrana/dialogue/FritzGlassBlowerDialogue.java b/Server/src/main/content/region/misc/entrana/dialogue/FritzGlassBlowerDialogue.java new file mode 100644 index 0000000..0e28402 --- /dev/null +++ b/Server/src/main/content/region/misc/entrana/dialogue/FritzGlassBlowerDialogue.java @@ -0,0 +1,205 @@ +package content.region.misc.entrana.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItem; +import core.game.node.item.GroundItemManager; +import core.plugin.Initializable; +import core.game.node.item.Item; + +/** + * Represents the dialogue plugin used for the fritz glass blower npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class FritzGlassBlowerDialogue extends DialoguePlugin { + + /** + * Represents the molten glass. + */ + private static final Item MOLTEN_GLASS = new Item(1775); + + /** + * Constructs a new {@code FritzGlassBlowerDialogue} {@code Object}. + */ + public FritzGlassBlowerDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code FritzGlassBlowerDialogue} {@code Object}. + * @param player the player. + */ + public FritzGlassBlowerDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new FritzGlassBlowerDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + if (!player.getSavedData().getGlobalData().isFritzGlass()) { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hello adventurer, welcome to the Entrana furnace."); + stage = 0; + } else { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ah " + player.getUsername() + ", have you come to sell me some molten", "glass?"); + stage = 100; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Would you like me to explain my craft to you?"); + stage = 1; + break; + case 1: + interpreter.sendOptions("Select an Option", "Yes please. I'd be fascinated to hear what you do.", "No thanks, I doubt I'll ever turn my hand to glassblowing."); + stage = 2; + break; + case 2: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Yes please. I'd be fascinated to hear what you do."); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No thanks, I doubt I'll ever turn my hand to glassblowing."); + stage = 22; + break; + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I'm extremely pleased to hear that! I've always wanted", "an apprentice. Let me talk to you through the secrets of", "glassblowing."); + stage = 11; + break; + case 11: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Glass is made from soda ash and silica. We get out", "soda ash by collecting seaweed from the rocks - the", "prevailing currents make the north-west corner of the", "island the best place to find it, it can also be found in"); + stage = 12; + break; + case 12: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "your nets sometimes when you're fishing, on Karamja", "island or at the Piscatoris Fishing Colonly in the nets", "there. To turn seaweed into soda ash, all you need to", "do is burn it on a fire. Feel free to use the range in"); + stage = 13; + break; + case 13: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "my house for that; it's the one directly west of here.", "Next we collect sand from the sandpit that you'll also", "find just west of here, there are other located in", "Yanille and Shilo Village."); + stage = 14; + break; + case 14: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "You'll need a bucket to cary it in. Tell you what, you", "can have this old one of mine."); + stage = 15; + break; + case 15: + if (!player.getInventory().add(new Item(1925))) { + GroundItemManager.create(new GroundItem(new Item(1925), player.getLocation(), player)); + } + player.getSavedData().getGlobalData().setFritzGlass(true); + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Bring the sand and the soda ash back here and melt", "them together in the furnace, and there you have it -", "molten glass!"); + stage = 16; + break; + case 16: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "There are many things you can use the molten glass", "for once you have made it. Depending on how talented", "you are, you could try turning it into something, like a", "fishbowl, for example. If you'd like to try your hand at"); + stage = 17; + break; + case 17: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "the fine art of glassblowing you can use my spare", "glassblowing pipe. I think I left it on the chest of", "drawers in my house this morning."); + stage = 18; + break; + case 18: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Alternatively I am always happy to buy the molten glass", "from you, saves me running about making it for", "myself."); + stage = 19; + break; + case 19: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "That sounds good. How much will you pay me?"); + stage = 20; + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Tell you what, because you've been interested in my", "art, I'll pay you the premium price of 20 gold pieces", "for each piece of molten glass you bring me."); + stage = 21; + break; + case 21: + end(); + break; + case 22: + end(); + break; + case 100: + interpreter.sendOptions("Select an Option", "Yes.", "No."); + stage = 101; + break; + case 101: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Yes."); + stage = 110; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No."); + stage = 120; + break; + } + break; + case 110: + if (!player.getInventory().containsItem(MOLTEN_GLASS)) { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Umm, not much point me trying to pay you for glass", "you don't have, is there?"); + stage = 111; + } else { + int amt = player.getInventory().getAmount(MOLTEN_GLASS); + Item remove = new Item(MOLTEN_GLASS.getId(), amt); + if (!player.getInventory().containsItem(remove)) { + end(); + return true; + } + if (player.getInventory().remove(remove)) { + player.getInventory().add(new Item(995, amt * 20)); + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Pleasure doing business with you " + player.getUsername() + "."); + stage = 118; + } + } + break; + case 111: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Well, actually, if you don't mind..."); + stage = 112; + break; + case 112: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I guess you've never heard of a rhetorical question", "then. I'll make it simple for you. You bring glass, me", "pay shiny gold coins."); + stage = 113; + break; + case 113: + end(); + break; + case 118: + end(); + break; + case 120: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Oh."); + stage = 121; + break; + case 121: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "...errr, well should you get any I'm quite happy to pay", "for it. Remember, I'll pay you 20 gold pieces for each", "piece of molten glass you get for me."); + stage = 122; + break; + case 122: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 4909 }; + } +} diff --git a/Server/src/main/content/region/misc/entrana/dialogue/HighPriestEntranaDialogue.kt b/Server/src/main/content/region/misc/entrana/dialogue/HighPriestEntranaDialogue.kt new file mode 100644 index 0000000..4f177c8 --- /dev/null +++ b/Server/src/main/content/region/misc/entrana/dialogue/HighPriestEntranaDialogue.kt @@ -0,0 +1,72 @@ +package content.region.misc.entrana.dialogue + +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class HighPriestEntranaDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + // Ice gloves were NOT reclaimable till 2017. + START_DIALOGUE -> npcl(FacialExpression.FRIENDLY, "Many greetings. Welcome to our fair island.").also { + if (inInventory(player, Items.SILVER_POT_4658) || + inInventory(player, Items.SILVER_POT_4660) || + inInventory(player, Items.SILVER_POT_4662) || + inInventory(player, Items.SILVER_POT_4664) || + inInventory(player, Items.SILVER_POT_4666)) { + stage = 6 + } else { + stage = 1 + } + } + 1 -> npcl(FacialExpression.FRIENDLY, "You are standing on the holy island of Entrana. It was here that Saradomin first stepped upon Gielinor.").also { stage++ } + 2 -> npcl(FacialExpression.FRIENDLY, "In homage to Saradomin's first arrival, we have built a great church, and devoted the island to those who wish peace for the world.").also { stage++ } + 3 -> npcl(FacialExpression.FRIENDLY, "The inhabitants of this island are mostly monks who spend their time meditating on Saradomin's ways.").also { stage++ } + 4 -> npcl(FacialExpression.FRIENDLY, "Of course, there are now more pilgrims to this holy site, since Saradomin defeated Zamorak in the battle of Lumbridge.").also { stage++ } + 5 -> npcl(FacialExpression.FRIENDLY, "It is good that so many see Saradomin's true glory!").also { stage = END_DIALOGUE } + + 6 -> playerl(FacialExpression.FRIENDLY, "Hi, I was wondering, can you quickly bless this for me?").also { stage++ } + 7 -> npc(FacialExpression.FRIENDLY, "A somewhat strange request, but I see no harm in it.", "There you go.", "May Saradomin walk with you.").also { + if (inInventory(player, Items.SILVER_POT_4658)) { + if (removeItem(player, Items.SILVER_POT_4658)) { + addItemOrDrop(player, Items.BLESSED_POT_4659) + } + } else if (inInventory(player, Items.SILVER_POT_4660)) { + if (removeItem(player, Items.SILVER_POT_4660)) { + addItemOrDrop(player, Items.BLESSED_POT_4661) + } + } else if (inInventory(player, Items.SILVER_POT_4662)) { + if (removeItem(player, Items.SILVER_POT_4662)) { + addItemOrDrop(player, Items.BLESSED_POT_4663) + } + } else if (inInventory(player, Items.SILVER_POT_4664)) { + if (removeItem(player, Items.SILVER_POT_4664)) { + addItemOrDrop(player, Items.BLESSED_POT_4665) + } + } else if (inInventory(player, Items.SILVER_POT_4666)) { + if (removeItem(player, Items.SILVER_POT_4666)) { + addItemOrDrop(player, Items.BLESSED_POT_4667) + } + } + stage = END_DIALOGUE + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return HighPriestEntranaDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.HIGH_PRIEST_216) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/entrana/dialogue/MazionDialogue.kt b/Server/src/main/content/region/misc/entrana/dialogue/MazionDialogue.kt new file mode 100644 index 0000000..60368b2 --- /dev/null +++ b/Server/src/main/content/region/misc/entrana/dialogue/MazionDialogue.kt @@ -0,0 +1,41 @@ +package content.region.misc.entrana.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class MazionDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + when ((1..3).random()) { + 1 -> npc(FacialExpression.FRIENDLY, "Nice weather we're having today!").also { stage = 99 } + 2 -> npc(FacialExpression.FRIENDLY, "Hello, " + player.username + ", fine day today!").also { stage = 99 } + 3 -> npc(FacialExpression.ANNOYED, "Please leave me alone, a parrot stole my banana.").also { stage = 99 } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return MazionDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.MAZION_3114) + } +} diff --git a/Server/src/main/content/region/misc/entrana/handlers/EntranaListeners.kt b/Server/src/main/content/region/misc/entrana/handlers/EntranaListeners.kt new file mode 100644 index 0000000..1053211 --- /dev/null +++ b/Server/src/main/content/region/misc/entrana/handlers/EntranaListeners.kt @@ -0,0 +1,56 @@ +package content.region.misc.entrana.handlers + +import content.global.travel.ship.Ships +import core.api.* +import core.cache.def.impl.ItemDefinition +import core.game.dialogue.DialogueFile +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.diary.DiaryType +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +/** + * Listeners for the Entrana monks' fast-travel option + * @author Player Name + */ + +fun sail(player: Player?, ship: Ships) { + ship.sail(player) + playJingle(player!!, 172) +} + +class EntranaListeners : InteractionListener { + override fun defineListeners() { + for (npc in arrayOf(NPCs.MONK_OF_ENTRANA_2730, NPCs.MONK_OF_ENTRANA_658, NPCs.MONK_OF_ENTRANA_2731)) { + on(npc, IntType.NPC, "take-boat") { player, _ -> + sail(player, Ships.ENTRANA_TO_PORT_SARIM) + return@on true + } + } + + for (npc in arrayOf(NPCs.MONK_OF_ENTRANA_2728, NPCs.MONK_OF_ENTRANA_657, NPCs.MONK_OF_ENTRANA_2729)) { + on(npc, IntType.NPC, "take-boat") { player, _ -> + if (!ItemDefinition.canEnterEntrana(player)) { + openDialogue(player, object : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + this.npc = NPC(npc) + when (stage) { + 0 -> npc("NO WEAPONS OR ARMOUR are permitted on holy", "Entrana AT ALL. We will not allow you to travel there", "in breach of mighty Saradomin's edict.").also { stage++ } + 1 -> npc("Do not try to deceive us again. Come back when you", "have laid down your Zamorakian instruments of death.").also { stage = END_DIALOGUE } + } + } + }) + return@on true + } + sail(player, Ships.PORT_SARIM_TO_ENTRANA) + if (!player.achievementDiaryManager.getDiary(DiaryType.FALADOR).isComplete(0, 14)) { + player.achievementDiaryManager.getDiary(DiaryType.FALADOR).updateTask(player, 0, 14, true) + } + return@on true + } + } + } +} diff --git a/Server/src/main/content/region/misc/entrana/handlers/EntranaObjectPlugin.java b/Server/src/main/content/region/misc/entrana/handlers/EntranaObjectPlugin.java new file mode 100644 index 0000000..d81a1be --- /dev/null +++ b/Server/src/main/content/region/misc/entrana/handlers/EntranaObjectPlugin.java @@ -0,0 +1,47 @@ +package content.region.misc.entrana.handlers; + +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.TeleportManager; +import core.game.world.map.Location; +import core.game.world.repository.Repository; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents a plugin used to handle entrana related objects. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class EntranaObjectPlugin extends OptionHandler { + + /** + * Represents the location to teleport to. + */ + private static final Location LOCATION = Location.create(3208, 3764, 0);// magic door + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(2408).getHandlers().put("option:climb-down", this); + SceneryDefinition.forId(2407).getHandlers().put("option:open", this);// magic door + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + switch (option) { + case "climb-down": + player.getDialogueInterpreter().open(656, Repository.findNPC(656)); + break; + case "open": + player.getPacketDispatch().sendMessage("You feel the world around you dissolve..."); + player.getTeleporter().send(LOCATION, TeleportManager.TeleportType.ENTRANA_MAGIC_DOOR); + break; + } + return true; + } + +} diff --git a/Server/src/main/content/region/misc/etceteria/dialogue/FishmongerEtcDialogue.kt b/Server/src/main/content/region/misc/etceteria/dialogue/FishmongerEtcDialogue.kt new file mode 100644 index 0000000..39f3492 --- /dev/null +++ b/Server/src/main/content/region/misc/etceteria/dialogue/FishmongerEtcDialogue.kt @@ -0,0 +1,37 @@ +package content.region.misc.etceteria.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class FishmongerEtcDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npcl(FacialExpression.FRIENDLY,"Welcome, ${player.getAttribute("fremennikname","fremmyname")}. My fish is fresher than any in Miscellania.").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> end().also { npc.openShop(player) } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return FishmongerEtcDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.FISHMONGER_1369) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/keldagrim/dialogue/AgmundiDialogue.kt b/Server/src/main/content/region/misc/keldagrim/dialogue/AgmundiDialogue.kt new file mode 100644 index 0000000..e67ea19 --- /dev/null +++ b/Server/src/main/content/region/misc/keldagrim/dialogue/AgmundiDialogue.kt @@ -0,0 +1,47 @@ +package content.region.misc.keldagrim.dialogue + +import core.api.openNpcShop +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class AgmundiDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> npc(FacialExpression.OLD_NOT_INTERESTED,"Oh no, not another human... what do you want then?").also { stage++ } + 1 -> player(FacialExpression.ASKING, "Oh, do you get humans here often?").also { stage++ } + 2 -> npc(FacialExpression.OLD_NORMAL, "Not that often, no, but sometimes.").also { stage++ } + 3 -> npc(FacialExpression.OLD_NORMAL, "Of course, since you people are too big for dwarven", "clothes, they typically don't stay very long.").also { stage++ } + 4 -> player(FacialExpression.SUSPICIOUS, "Why don't you make bigger clothes then?").also { stage++ } + 5 -> npc(FacialExpression.OLD_NOT_INTERESTED, "What'd be the point? Besides, I don't make", "these clothes myself.").also { stage++ } + 6 -> showTopics( + Topic(FacialExpression.FRIENDLY, "Who makes these clothes then?", 10), + Topic(FacialExpression.FRIENDLY, "I still want to buy your clothes.", 8, true), + Topic(FacialExpression.FRIENDLY, "So do you have any quests for me?", 20), + ) + 8 -> openNpcShop(player, NPCs.AGMUNDI_2161).also { stage = END_DIALOGUE } + 10 -> npc(FacialExpression.OLD_DEFAULT,"Oh, my sister, she lives in Keldagrim-East.", "Has a little stall on the other side of", "the Kelda.").also { stage++ } + 11 -> npc(FacialExpression.OLD_DEFAULT,"If she only worked a little harder, like me,", "she wouldn't have to live in the sewers of the city.", "Shame really.").also { stage++ } + 12 -> player(FacialExpression.FRIENDLY, "The sewers? Your sister lives in the sewers?").also { stage++ } + 13 -> npc(FacialExpression.OLD_SAD,"Keldagrim-East, such a ghastly place.", "Not civil, polite and clean like we are in the West.").also { stage++ } + 14 -> player(FacialExpression.SUSPICIOUS, "Uh-huh.").also { stage = END_DIALOGUE } + 20 -> npc(FacialExpression.OLD_NOT_INTERESTED,"Quests? Why would I have any quests?").also { stage++ } + 21 -> player(FacialExpression.FRIENDLY, "Oh, just anything to do would be fine.").also { stage++ } + 22 -> npc(FacialExpression.OLD_NOT_INTERESTED,"No, not right now... maybe I'll have something", "for you to do later, but nothing at the moment.").also { stage = END_DIALOGUE } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return AgmundiDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.AGMUNDI_2161) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/keldagrim/dialogue/BarmaidDialogue.kt b/Server/src/main/content/region/misc/keldagrim/dialogue/BarmaidDialogue.kt new file mode 100644 index 0000000..1b23ffe --- /dev/null +++ b/Server/src/main/content/region/misc/keldagrim/dialogue/BarmaidDialogue.kt @@ -0,0 +1,81 @@ +package content.region.misc.keldagrim.dialogue + +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class BarmaidDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + // TODO: Forgettable Tale Dialogue + when(stage){ + START_DIALOGUE -> npcl(FacialExpression.OLD_DEFAULT, "Welcome to the Laughing Miner pub, human traveller.").also { stage++ } + 1 -> showTopics( + Topic(FacialExpression.FRIENDLY, "Who is that man walking around outside?", 2), + Topic(FacialExpression.FRIENDLY, "I'd like a beer please.", 12), + Topic(FacialExpression.FRIENDLY, "I'd like some food please.", 16), + ) + 2 -> npcl(FacialExpression.OLD_DEFAULT, "What man?").also { stage++ } + 3 -> playerl(FacialExpression.FRIENDLY, "I mean the dwarf, the one with the sign.").also { stage++ } + 4 -> npcl(FacialExpression.OLD_DEFAULT, "Oh, him. Yes, we employ him to advertise our pub, he's the cheapest labour we could find. We don't have a lot of money to spare you know, we pay him in beer.").also { stage++ } + 5 -> playerl(FacialExpression.FRIENDLY, "But what's wrong with him?").also { stage++ } + 6 -> npcl(FacialExpression.OLD_DEFAULT, "Well, he's drunk isn't he?").also { stage++ } + 7 -> npcl(FacialExpression.OLD_DEFAULT, "I told you, he's cheap. He couldn't get any other work since the Red Axe fired him. Been drinking ever since.").also { stage++ } + 8 -> playerl(FacialExpression.FRIENDLY, "How did that happen?").also { stage++ } + 9 -> npcl(FacialExpression.OLD_DEFAULT, "I'm not quite sure, I think he kept wearing the wrong coloured cap all the time. They don't much like it if you don't wear your red uniform into work.").also { stage++ } + 10 -> playerl(FacialExpression.FRIENDLY, "They fired him for that??").also { stage++ } + 11 -> npcl(FacialExpression.OLD_DEFAULT, "The Red Axe will fire you for just about anything if they want to.").also { + stage = END_DIALOGUE + } + 12 -> npcl(FacialExpression.OLD_DEFAULT, "That'll be 2 gold coins.").also { stage++ } + 13 -> showTopics( + Topic(FacialExpression.FRIENDLY, "Pay.", 14, true), + Topic(FacialExpression.FRIENDLY, "Don't pay.", 15,true), + ) + 14 -> { + if (!inInventory(player, Items.COINS_995, 2)) { + playerl(FacialExpression.FRIENDLY, "Sorry, I don't have 2 coins on me.").also { stage = END_DIALOGUE } + } else { + if (removeItem(player, Item(Items.COINS_995, 2))) { + addItemOrDrop(player, Items.BEER_1917) + npcl(FacialExpression.OLD_DEFAULT, "Thanks for your custom.").also { stage = END_DIALOGUE } + } + } + } + 15 -> playerl(FacialExpression.FRIENDLY, "Sorry, I changed my mind.").also { stage = END_DIALOGUE } + 16 -> npcl(FacialExpression.OLD_DEFAULT, "I can make you a stew for 20 gold coins.").also { stage++ } + 17 -> showTopics( + Topic(FacialExpression.FRIENDLY, "Pay.", 18, true), + Topic(FacialExpression.FRIENDLY, "Don't pay.", 19,true), + ) + 18 -> { + if (!inInventory(player, Items.COINS_995, 20)) { + playerl(FacialExpression.FRIENDLY, "Sorry, I don't have 20 coins on me.").also { stage = END_DIALOGUE } + } else { + if (removeItem(player, Item(Items.COINS_995, 20))) { + addItemOrDrop(player, Items.STEW_2003) + npcl(FacialExpression.OLD_DEFAULT, "Thanks for your custom.").also { stage = END_DIALOGUE } + } + } + } + 19 -> playerl(FacialExpression.FRIENDLY, "Sorry, I changed my mind.").also { stage = END_DIALOGUE } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return BarmaidDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.BARMAID_2178) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/keldagrim/dialogue/BentamirDialogue.kt b/Server/src/main/content/region/misc/keldagrim/dialogue/BentamirDialogue.kt new file mode 100644 index 0000000..5396162 --- /dev/null +++ b/Server/src/main/content/region/misc/keldagrim/dialogue/BentamirDialogue.kt @@ -0,0 +1,36 @@ +package content.region.misc.keldagrim.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class BentamirDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + START_DIALOGUE -> npcl(FacialExpression.OLD_ANGRY1, "Do you mind? You're in my home.").also { stage++ } + 1 -> playerl(FacialExpression.FRIENDLY, "I'm sorry, should I have knocked?").also { stage++ } + 2 -> npcl(FacialExpression.OLD_ANGRY1, "Very funny, human.").also { stage++ } + 3 -> npcl(FacialExpression.OLD_ANGRY1, "We can't all live in plush houses, you know. But that doesn't mean us mining dwarves don't work hard.").also { stage++ } + 4 -> playerl(FacialExpression.FRIENDLY, "Where do you do your mining?").also { stage++ } + 5 -> npcl(FacialExpression.OLD_NOT_INTERESTED, "Normally the coal mine to the north. We need a lot of coal to keep our steam engines going, you know.").also { stage++ } + 6 -> playerl(FacialExpression.FRIENDLY, "Can I do a bit of mining there as well?").also { stage++ } + 7 -> npcl(FacialExpression.OLD_NOT_INTERESTED, "I'm not sure, but as long as no one notices I don't think anyone is going to care.").also { + stage = END_DIALOGUE + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return BentamirDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.BENTAMIR_2192) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/keldagrim/dialogue/BlackGuardDialogue.kt b/Server/src/main/content/region/misc/keldagrim/dialogue/BlackGuardDialogue.kt new file mode 100644 index 0000000..22d229f --- /dev/null +++ b/Server/src/main/content/region/misc/keldagrim/dialogue/BlackGuardDialogue.kt @@ -0,0 +1,37 @@ +package content.region.misc.keldagrim.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class BlackGuardDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + START_DIALOGUE -> { + var random = arrayOf(1, 2, 3, 4, 5).random() + when (random) { + 1 -> npcl(FacialExpression.OLD_ANGRY3, "Obey the law!").also { stage = END_DIALOGUE } + 2 -> npcl(FacialExpression.OLD_ANGRY3, "Stay out of trouble!").also { stage = END_DIALOGUE } + 3 -> npcl(FacialExpression.OLD_ANGRY3, "Out of the way, human!").also { stage = END_DIALOGUE } + 4 -> npcl(FacialExpression.OLD_ANGRY3, "I'm keeping an eye on you!").also { stage = END_DIALOGUE } + 5 -> end().also{ sendDialogue("The guard ignores you.").also { stage = END_DIALOGUE } } + } + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return BlackGuardDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.BLACK_GUARD_2130, NPCs.BLACK_GUARD_2131, NPCs.BLACK_GUARD_2132, NPCs.BLACK_GUARD_2133, NPCs.BLACK_GUARD_BERSERKER_2134, NPCs.BLACK_GUARD_BERSERKER_2135, NPCs.BLACK_GUARD_BERSERKER_2136) + } +} diff --git a/Server/src/main/content/region/misc/keldagrim/dialogue/BlandebirDialogue.kt b/Server/src/main/content/region/misc/keldagrim/dialogue/BlandebirDialogue.kt new file mode 100644 index 0000000..974f224 --- /dev/null +++ b/Server/src/main/content/region/misc/keldagrim/dialogue/BlandebirDialogue.kt @@ -0,0 +1,51 @@ +package content.region.misc.keldagrim.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class BlandebirDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hello, I wonder if you could help me on this whole brewing thing...").also { stage++ } + 1 -> npcl(FacialExpression.OLD_DEFAULT, "I might be able to - what do you need to know?").also { stage++ } + 2 -> showTopics( + Topic(FacialExpression.FRIENDLY, "How do I brew ales?", 3), + Topic(FacialExpression.FRIENDLY, "How do I brew cider?", 6), + Topic(FacialExpression.FRIENDLY, "What do I do once my ale has matured?", 8), + Topic(FacialExpression.FRIENDLY, "Do you have any spare ale yeast?", 9), + Topic(FacialExpression.FRIENDLY, "That's all I need to know, thanks.", END_DIALOGUE), + ) + 3 -> npcl(FacialExpression.OLD_DEFAULT, "Well first off you need to fill the vat with water - two bucketfuls should do the trick. Then you'll need to put in two handfuls of barley malt - that's roasted barley by the way.").also { stage++ } + 4 -> npcl(FacialExpression.OLD_DEFAULT, "After that you'll be putting your main ingredient in - this will decide which ale it is you're brewing. There should be some good guides around with recipes in.").also { stage++ } + 5 -> npcl(FacialExpression.OLD_DEFAULT, "Lastly you pour a pot full of ale yeast in, which'll start it off fermenting. Then all you have to do is wait for the good stuff.").also { + stage = 2 + } + 6 -> npcl(FacialExpression.OLD_DEFAULT, "First you'll need some apples. You'll need to crush them using this cider-press - four apples should make a full bucket of apple-mush. Take four buckets of mush and fill up the vat.").also { stage++ } + 7 -> npcl(FacialExpression.OLD_DEFAULT, "After that you pour a pot full of ale yeast in, which'll start it off fermenting. Then all you have to do is wait for the good stuff.").also { + stage = 2 + } + 8 -> npcl(FacialExpression.OLD_DEFAULT, "Well, once you've got a full vat of the good stuff, just turn the valve and your barrel will fill up with eight pints of whatever your chosen tipple is. Mind it's an empty barrel, though.").also { + stage = 2 + } + 9 -> npcl(FacialExpression.OLD_DEFAULT, "Well, as a matter of fact I do, although I wouldn't describe it as spare. This ale yeast I've got is the best money can buy, but if you've got a pot I'll fill it for you for 25GP - very cheap as it happens.").also { + stage = 2 + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return BlandebirDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.BLANDEBIR_2321) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/keldagrim/dialogue/BlastFurnaceForemanDialogue.kt b/Server/src/main/content/region/misc/keldagrim/dialogue/BlastFurnaceForemanDialogue.kt new file mode 100644 index 0000000..a6ed126 --- /dev/null +++ b/Server/src/main/content/region/misc/keldagrim/dialogue/BlastFurnaceForemanDialogue.kt @@ -0,0 +1,180 @@ +package content.region.misc.keldagrim.dialogue + +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.player.Player +import core.game.system.task.Pulse +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.Components +import org.rs09.consts.NPCs + +@Initializable +class BlastFurnaceForemanDialogue (player: Player? = null) : DialoguePlugin(player) { + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + START_DIALOGUE -> npcl(FacialExpression.OLD_ANGRY1, "You! Get to work!").also { stage++ } + 1 -> showTopics( + Topic(FacialExpression.FRIENDLY, "What?", 2), + Topic(FacialExpression.FRIENDLY, "Okay.", END_DIALOGUE), + ) + 2 -> npcl(FacialExpression.OLD_DEFAULT, "You are here to help work the blast furnace, aren't you?").also { stage++ } + 3 -> showTopics( + Topic(FacialExpression.FRIENDLY, "What's the blast furnace?", 5), + Topic(FacialExpression.FRIENDLY, "How can I help work the blast furnace?", 10), + Topic(FacialExpression.FRIENDLY, "Can I use the furnace to smelt ore?", 40), + Topic(FacialExpression.FRIENDLY, "Maybe some other time.", 102), + ) + + 5 -> npcl(FacialExpression.OLD_DEFAULT, "The blast furnace is the pinnacle of dwarven metal- processing! Ore goes in the top and comes out as metal bars almost at once! And it's so efficient it only takes half as much coal to purify it as a regular furnace.").also { stage++ } + 6 -> npcl(FacialExpression.OLD_DEFAULT, "But we've got a bit of a labour shortage at the moment, which is why I have to rely on immigrant workers to keep the furnace going. So, are you here to start work?").also { stage++ } + 7 -> showTopics( + Topic(FacialExpression.FRIENDLY, "How can I help work the blast furnace?", 10), + Topic(FacialExpression.FRIENDLY, "Can I use the furnace to smelt ore?", 40), + Topic(FacialExpression.FRIENDLY, "Maybe some other time.", 102), + ) + + 10 -> npcl(FacialExpression.OLD_DEFAULT, "The blast furnace will only work if there is a group of people keeping it going. Let me explain...").also { stage++ } + 11 -> { + openInterface(player, Components.BLAST_FURNACE_PLAN_SCROLL_29) + submitIndividualPulse(player, object : Pulse() { + var flash = true + override fun pulse(): Boolean { + setComponentVisibility(player, Components.BLAST_FURNACE_PLAN_SCROLL_29, 2, flash) + flash = !flash + return false + } + }) + npcl(FacialExpression.OLD_DEFAULT, "Firstly, the stove needs to be kept filled with coal. If this runs out the furnace will not work.") + stage++ + } + 12 -> { + setComponentVisibility(player, Components.BLAST_FURNACE_PLAN_SCROLL_29, 2, false) + submitIndividualPulse(player, object : Pulse() { + var flash = true + override fun pulse(): Boolean { + setComponentVisibility(player, Components.BLAST_FURNACE_PLAN_SCROLL_29, 14, flash) + flash = !flash + return false + } + }) + npcl(FacialExpression.OLD_DEFAULT, "Secondly, someone needs to operate the pump that keeps the hot air blast circulating through the furnace.") + stage++ + } + 13 -> { + setComponentVisibility(player, Components.BLAST_FURNACE_PLAN_SCROLL_29, 14, false) + submitIndividualPulse(player, object : Pulse() { + var flash = true + override fun pulse(): Boolean { + setComponentVisibility(player, Components.BLAST_FURNACE_PLAN_SCROLL_29, 15, flash) + flash = !flash + return false + } + }) + npcl(FacialExpression.OLD_DEFAULT, "Thirdly, someone needs to keep an eye on the temperature gauge. They should tell the pumper to start or stop so that the temperature stays in the right range.") + stage++ + } + 14 -> { + setComponentVisibility(player, Components.BLAST_FURNACE_PLAN_SCROLL_29, 15, false) + submitIndividualPulse(player, object : Pulse() { + var flash = true + override fun pulse(): Boolean { + setComponentVisibility(player, Components.BLAST_FURNACE_PLAN_SCROLL_29, 13, flash) + flash = !flash + return false + } + }) + npcl(FacialExpression.OLD_DEFAULT, "Lastly, someone needs to be on the pedals to power the conveyor belt that puts ore into the furnace.") + stage++ + } + 15 -> npcl(FacialExpression.OLD_DEFAULT, "Someone will also need to be on standby with a hammer in case the machine breaks!").also { stage++ } + 16 -> npcl(FacialExpression.OLD_DEFAULT, "While that's going, anyone else can put their ore on the conveyor belt to have it smelted.").also { stage++ } + 17 -> { + setComponentVisibility(player, Components.BLAST_FURNACE_PLAN_SCROLL_29, 13, false) + closeInterface(player) + showTopics( + Topic(FacialExpression.FRIENDLY, "So what do I get out of it?", 20), + Topic(FacialExpression.FRIENDLY, "Okay I'll get to work.", 101), + Topic(FacialExpression.FRIENDLY, "Maybe some other time.", 102), + ) + } + + 20 -> npcl(FacialExpression.OLD_DEFAULT, "Keeping the furnace going is valuable experience in itself!").also { stage++ } + 21 -> npcl(FacialExpression.OLD_DEFAULT, "Keeping the stove alight will train your Firemaking, working the pump will train your Strength, pedalling the conveyor belt will train your Agility and repairing the furnace will train Crafting.").also { stage++ } + 22 -> npcl(FacialExpression.OLD_DEFAULT, "Plus, everyone working the furnace will get a bit of experience in Smithing whenever anyone smelts ore in it.").also { stage++ } + 23 -> showTopics( + Topic(FacialExpression.FRIENDLY, "So I don't actually get paid then?", 25), + Topic(FacialExpression.FRIENDLY, "Okay I'll get to work.", 101), + Topic(FacialExpression.FRIENDLY, "Maybe some other time.", 102), + ) + + 25 -> npcl(FacialExpression.OLD_ANGRY1, "I offer you the privilege of working on the greatest example of dwarven engineering and you want to be PAID?").also { stage++ } + 26 -> npcl(FacialExpression.OLD_ANGRY2, "If you co-operate with a group of people you can all get your smelting done pretty quickly. Or perhaps some humans who need to do some smelting will pay you, since you humans are all so obsessed with money.").also { stage++ } + 27 -> showTopics( + Topic(FacialExpression.FRIENDLY, "Okay I'll get to work.", 101), + Topic(FacialExpression.FRIENDLY, "Maybe some other time.", 102), + Topic(FacialExpression.FRIENDLY, "No wonder you have a labour shortage if you don't pay your workers!", 30, true), + ) + + 30 -> playerl(FacialExpression.FRIENDLY, "No wonder you have a labour shortage if you don't pay your workers!").also { stage++ } + 31 -> npcl(FacialExpression.OLD_DEFAULT, "What would be the point of making money if I gave it all away to menial workers?").also { stage++ } + 32 -> npcl(FacialExpression.OLD_DEFAULT, "I mean... Money isn't important! What about the greater glory of dwarven engineering? What about the satisfaction of helping others? What about the XP?").also { stage++ } + 33 -> showTopics( + Topic(FacialExpression.FRIENDLY, "Okay I'll get to work.", 101), + Topic(FacialExpression.FRIENDLY, "Maybe some other time.", 102), + ) + + 40 -> npcl(FacialExpression.OLD_DEFAULT, "You can, although you'll need to find some people to work it for you as well. But the furnace is very delicate so I charge a fee for anyone who doesn't have level 60 smithing.").also { stage++ } + 41 -> showTopics( + Topic(FacialExpression.FRIENDLY, "I have level 60!", 45), + Topic(FacialExpression.FRIENDLY, "I don't have level 60.", 51), + ) + + 45 -> npcl(FacialExpression.OLD_DEFAULT, "A human has level 60 smithing? How extraordinary!").also { stage++ } + 46 -> npcl(FacialExpression.OLD_DEFAULT, "Feel free to use the furnace. Remember, you only need half as much coal as with a regular furnace.").also { + stage = END_DIALOGUE + } + // This is inauthentic. Authentic dialogue below. + 51 -> npcl(FacialExpression.OLD_DEFAULT, "Hmm, well, I can't let you use the furnace. You need to have level 60 smithing.").also { + stage = END_DIALOGUE + } + + // These are unreachable until Blast Furnace implements <60 Smithing timeshare. + 52 -> npcl(FacialExpression.OLD_DEFAULT, "Hmm, well, I'll let you use the furnace if you want, but you must pay a fee of 2,500 coins.").also { stage++ } + 53 -> showTopics( + Topic(FacialExpression.FRIENDLY, "Okay.", 55, true), + Topic(FacialExpression.FRIENDLY, "Maybe some other time.", 102), + Topic(FacialExpression.FRIENDLY, "[Charm] How about I give you 1250 coins and I work extra hard?", 70, true), // Ring of Charos(a) + ) + 55 -> playerl(FacialExpression.FRIENDLY, "Okay, here you are.").also { stage++ } + 56 -> npcl(FacialExpression.OLD_DEFAULT, "Okay, you can use the furnace for ten minutes. Remember, you only need half as much coal as with a regular furnace.").also { + stage = END_DIALOGUE + } + + 70 -> playerl(FacialExpression.FRIENDLY, "How about I give you 1250 coins and I work extra hard?").also { stage++ } + 71 -> npcl(FacialExpression.OLD_DEFAULT, "You'll have to work hard enough for two humans if I agree...").also { stage++ } + 72 -> playerl(FacialExpression.FRIENDLY, "Oh, three humans, easily!").also { stage++ } + 73 -> npcl(FacialExpression.OLD_DEFAULT, "Well, okay then - 1250GP it is.").also { stage++ } + + 101 -> npcl(FacialExpression.OLD_DEFAULT, "Splendid!").also { + stage = END_DIALOGUE + } + 102 -> npcl(FacialExpression.OLD_ANGRY1, "Well if you're not here to work, go hang around somewhere else!").also { + stage = END_DIALOGUE + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return BlastFurnaceForemanDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.BLAST_FURNACE_FOREMAN_2553) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/keldagrim/dialogue/BlastFurnaceForemanNPC.kt b/Server/src/main/content/region/misc/keldagrim/dialogue/BlastFurnaceForemanNPC.kt new file mode 100644 index 0000000..f74016a --- /dev/null +++ b/Server/src/main/content/region/misc/keldagrim/dialogue/BlastFurnaceForemanNPC.kt @@ -0,0 +1,42 @@ +package content.region.misc.keldagrim.dialogue + +import core.game.node.entity.npc.AbstractNPC +import core.game.world.map.Location +import core.plugin.Initializable +import core.tools.RandomFunction +import org.rs09.consts.NPCs + +@Initializable +class BlastFurnaceForemanNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id,location) { + companion object { + val MESSAGES = arrayOf( + // Mostly https://youtu.be/hZ_q441esf0 + "Somebody fix the conveyor belt!", // When the drive belt or cogs are broken -> conveyor belt. + "Somebody work the conveyor belt!", + "Somebody fix that pipe!", + "Somebody operate the pump!", + "Somebody refuel the stove!", + "Keep the temperature controlled.", // https://youtu.be/McMNWADwdF8&t=38 + "Work faster!", + "That's, it keep it going." + + ) + } + + override fun construct(id: Int, location: Location?, vararg objects: Any?): AbstractNPC { + return BlastFurnaceForemanNPC(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.BLAST_FURNACE_FOREMAN_2553) + } + + override fun handleTickActions() { + super.handleTickActions() + // TODO: Have chat messages pop up according to the state of the Blast Furnace and not on a dice roll. + if (RandomFunction.random(20) < 1) { + core.api.sendChat(this, MESSAGES.random()) + } + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/keldagrim/dialogue/CartConductorDialogue.kt b/Server/src/main/content/region/misc/keldagrim/dialogue/CartConductorDialogue.kt new file mode 100644 index 0000000..d88d084 --- /dev/null +++ b/Server/src/main/content/region/misc/keldagrim/dialogue/CartConductorDialogue.kt @@ -0,0 +1,88 @@ +package content.region.misc.keldagrim.dialogue + +import core.game.component.Component +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.world.map.Location +import core.plugin.Initializable +import content.region.misc.keldagrim.handlers.KeldagrimCartMethods + +private const val ICE_MOUNTAIN_CONDUCTOR = 2180 +private const val WHITE_WOLF_CONDUCTOR = 2181 +private const val KELDAGRIM_CONDUCTOR = 2182 + +@Initializable +class CartConductorDialogue(player: Player? = null) : DialoguePlugin(player) { + var visitedKeldagrim = false + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> npc("Sorry, but I can only take people","who have been there before.").also { stage = 1000 } + + //Start Ice Mountain (Dwarven Mines) Conductor Dialogue + 100 -> npc("Alright, that'll cost ye 150gp.").also { stage++ } + 101 -> options("Okay, sure.","No, thanks.").also { stage++ } + 102 -> when(buttonId){ + 1 -> end().also { purchaseTrip(player,150) } + 2 -> end() + } + + //Start White Wolf Mountain Conductor Dialogue + 200 -> npc("Alright, that'll cost ye 100gp.").also { stage++ } + 201 -> options("Okay, sure.","No, thanks.").also { stage++ } + 202 -> when(buttonId){ + 1 -> end().also { purchaseTrip(player,100) } + 2 -> end() + } + + //Start Keldagrim Conductor Dialogue + 300 -> npc("Alright, where would ye like to go?").also { stage++ } + 301 -> options("Grand Exchange","White Wolf Mountain","Ice Mountain").also { stage++ } + 302 -> when(buttonId){ + 1 -> KeldagrimCartMethods.leaveKeldagrimTo(player, Location.create(3140, 3507, 0)).also{ end() } + 2 -> KeldagrimCartMethods.leaveKeldagrimTo(player, Location.create(2875, 9871, 0)).also{ end() } + 3 -> KeldagrimCartMethods.leaveKeldagrimTo(player, Location.create(2997, 9837, 0)).also{ end() } + } + 1000 -> end() + } + return true + } + + fun purchaseTrip(player: Player, cost: Int){ + val coins = Item(995,cost) + if(player.inventory.containsItem(coins)){ + player.inventory.remove(coins) + KeldagrimCartMethods.goToKeldagrim(player) + } else { + player.dialogueInterpreter.sendDialogue("You can not afford that.") + } + } + + override fun npc(vararg messages: String?): Component { + return super.npc(FacialExpression.OLD_NORMAL, *messages) + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC //get which conductor specifically is being used + visitedKeldagrim = player.getAttribute("keldagrim-visited",false) //visited keldagrim? + + player("I'd like to use your cart, please.") + when(npc.id){ + ICE_MOUNTAIN_CONDUCTOR -> stage = if(!visitedKeldagrim) 0 else 100 + WHITE_WOLF_CONDUCTOR -> stage = if(!visitedKeldagrim) 0 else 200 + KELDAGRIM_CONDUCTOR -> stage = 300 + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return CartConductorDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(ICE_MOUNTAIN_CONDUCTOR, WHITE_WOLF_CONDUCTOR, KELDAGRIM_CONDUCTOR) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/keldagrim/dialogue/DrunkenDwarfDialogue.kt b/Server/src/main/content/region/misc/keldagrim/dialogue/DrunkenDwarfDialogue.kt new file mode 100644 index 0000000..a2cc6a9 --- /dev/null +++ b/Server/src/main/content/region/misc/keldagrim/dialogue/DrunkenDwarfDialogue.kt @@ -0,0 +1,43 @@ +package content.region.misc.keldagrim.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class DrunkenDwarfDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hello there! Are you alright?").also { stage++ } + 1 -> npcl(FacialExpression.OLD_DRUNK_RIGHT, "Of courshe! Why why why *hic* why shouldn't I be?").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "Hey, you look vaguely familiar... haven't I seen you somewhere before?").also { stage++ } + 3 -> npcl(FacialExpression.OLD_DRUNK_RIGHT, "That'sh not likely... I've been here for eh...").also { stage++ } + 4 -> npcl(FacialExpression.OLD_DRUNK_RIGHT, "I've been here for...").also { stage++ } + 5 -> npcl(FacialExpression.OLD_DRUNK_RIGHT, "Yearsh!").also { stage++ } + 6 -> npcl(FacialExpression.OLD_DRUNK_RIGHT, "I've been looking after thish houshe for my... my coushin? Or wash it my brother? A family member anyway.").also { stage++ } + 7 -> playerl(FacialExpression.FRIENDLY, "And where is this... family member of yours?").also { stage++ } + 8 -> npcl(FacialExpression.OLD_DRUNK_RIGHT, "All over, all over... he shaish he went off to wander all over Gielinor. Don't remember why.").also { stage++ } + 9 -> playerl(FacialExpression.FRIENDLY, "Hmm... I wonder, I may have met him...").also { stage++ } + 10 -> npcl(FacialExpression.OLD_DRUNK_RIGHT, "He comesh back sometimesh... saysh he needsh more kebabsh.").also { stage++ } + 11 -> npcl(FacialExpression.OLD_DRUNK_RIGHT, "Or ish that jusht a dream? Sometimesh I dream kebabsh invade Keldi... Keldu... Keldashomething.").also { stage++ } + 12 -> npcl(FacialExpression.OLD_DRUNK_RIGHT, "When you eatsh them, they take over your mind, they do! An army of mindlesh kebab eating dwarvesh!").also { stage++ } + 13 -> playerl(FacialExpression.FRIENDLY, "Er, yes, well, I think I should be off now.").also { stage++ } + 14 -> npcl(FacialExpression.OLD_DRUNK_RIGHT, "THE KEBABSH WILL COME FOR YOU!").also { + stage = END_DIALOGUE + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return DrunkenDwarfDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.DRUNKEN_DWARF_2203) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/keldagrim/dialogue/DwarfsDialogue.kt b/Server/src/main/content/region/misc/keldagrim/dialogue/DwarfsDialogue.kt new file mode 100644 index 0000000..a2b818a --- /dev/null +++ b/Server/src/main/content/region/misc/keldagrim/dialogue/DwarfsDialogue.kt @@ -0,0 +1,36 @@ +package content.region.misc.keldagrim.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class DwarfsDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + START_DIALOGUE -> { + var random = arrayOf(1, 2, 3, 4, 5).random() + when (random) { + 1 -> npcl(FacialExpression.OLD_DEFAULT, "I hope the goblins are properly maintaining their stretch of track! I'd hate to see them spoil good Dwarven workmanship.").also { stage = END_DIALOGUE } + 2 -> npcl(FacialExpression.OLD_DEFAULT, "You're ${player.username}, aren't you? It's a good job you did helping to get this train link open.").also { stage = END_DIALOGUE } + 3 -> npcl(FacialExpression.OLD_DEFAULT, "Y'know, at first I didn't like the idea of visiting a goblin city, but these cave goblins are alright.").also { stage = END_DIALOGUE } + 4 -> npcl(FacialExpression.OLD_DEFAULT, "These goblins have so much more advanced technology than us. Take a look at their magical lights! We could never create something like them.").also { stage = END_DIALOGUE } + 5 -> npcl(FacialExpression.OLD_DEFAULT, "Dorgesh-Kaan's very nice to visit, but I don't think I'd want to live there.").also { stage = END_DIALOGUE } + } + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return DwarfsDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.DWARF_5880, NPCs.DWARF_5881, NPCs.DWARF_5882, NPCs.DWARF_5883, NPCs.DWARF_5884, NPCs.DWARF_5885) + } +} diff --git a/Server/src/main/content/region/misc/keldagrim/dialogue/DwarvenBoatmanDialogue.kt b/Server/src/main/content/region/misc/keldagrim/dialogue/DwarvenBoatmanDialogue.kt new file mode 100644 index 0000000..c25041d --- /dev/null +++ b/Server/src/main/content/region/misc/keldagrim/dialogue/DwarvenBoatmanDialogue.kt @@ -0,0 +1,152 @@ +package content.region.misc.keldagrim.dialogue + +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.player.Player +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.Components +import org.rs09.consts.NPCs + +@Initializable +class DwarvenBoatmanForthDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + // TODO: This should be replaced with the Giant Dwarf quest + if (!getAttribute(player, "/save:keldagrim-visited", false)) { + when (stage) { + START_DIALOGUE -> npcl(FacialExpression.OLD_HAPPY, "Ho there, human!").also { stage++ } + 1 -> playerl(FacialExpression.FRIENDLY, "${player.username}.").also { stage++ } + 2 -> npcl(FacialExpression.OLD_HAPPY, "Ho there, ${player.username}! Want to take a ride with me?").also { stage++ } + 3 -> playerl(FacialExpression.FRIENDLY, "Where are you going? Across the river?").also { stage++ } + 4 -> npcl(FacialExpression.OLD_HAPPY, "No no, that's what the ferryman is for! I'm going to Keldagrim, my home!").also { stage++ } + 5 -> playerl(FacialExpression.FRIENDLY, "How much will that cost me then?").also { stage++ } + 6 -> npcl(FacialExpression.OLD_HAPPY, "For a human like you, I can do it for free!").also { stage++ } + 7 -> showTopics( + Topic(FacialExpression.FRIENDLY, "That's a deal!", 8), + Topic(FacialExpression.FRIENDLY, "I prefer the mines to the city.", 15), + ) + 8 -> npcl(FacialExpression.OLD_HAPPY, "Excellent! I'm just waiting for my ship to arrive and then we can go.").also { stage++ } + 9 -> npcl(FacialExpression.OLD_HAPPY, "Mind, this trip could take a few minutes! Are you sure you're ready to go as well?").also { stage++ } + 10 -> { + setComponentVisibility(player, 228, 6, true) + setComponentVisibility(player, 228, 9, false) + sendDialogueOptions(player, "(Not Done) Start The Giant Dwarf quest?", "Yes", "No").also { stage++ } + } + 11 -> when (buttonId) { + 1 -> playerl(FacialExpression.FRIENDLY, "Yes, I'm ready and don't mind it taking a few minutes.").also { stage = 12 } + 2 -> playerl(FacialExpression.FRIENDLY, "No, I don't have time right now, I'll be back later.").also { stage = 14 } + } + 12 -> npcl(FacialExpression.OLD_HAPPY, "Well, let's not waste any more time then!").also { stage++ } + 13 -> end().also { + submitWorldPulse(TravelForthPulse(player)) + } + 14 -> npcl(FacialExpression.OLD_HAPPY, "Sure, sure! Come back when you need to!").also { + stage = END_DIALOGUE + } + 15 -> npcl(FacialExpression.OLD_HAPPY, "Well, suit yourself then!").also { + stage = END_DIALOGUE + } + } + } else { + when (stage) { + START_DIALOGUE -> npcl(FacialExpression.OLD_HAPPY, "Hello again, ${player.username}! Want to go back to Keldagrim?").also { stage++ } + 1 -> showTopics( + Topic(FacialExpression.FRIENDLY, "Yes, please take me.", 2), + Topic(FacialExpression.FRIENDLY, "What, on your ship? No way.", 3), + ) + 2 -> end().also { + submitWorldPulse(TravelForthPulse(player)) + } + 3 -> npcl(FacialExpression.OLD_NORMAL, "Hey, it was only a little accident! Calm down!").also { + stage = END_DIALOGUE + } + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return DwarvenBoatmanForthDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.DWARVEN_BOATMAN_2205) //1844,1843 + } +} + +class TravelForthPulse(val player: Player): Pulse(1){ + var counter = 0 + override fun pulse(): Boolean { + when(counter++){ + 0 -> lock(player, 10).also { + openInterface(player, Components.FADE_TO_BLACK_120) + } + 3 -> teleport(player, Location.create(2892, 10225, 0)) + 4 -> { + closeInterface(player) + openInterface(player, Components.FADE_FROM_BLACK_170) + } + 6 -> unlock(player).also { + closeInterface(player) + setAttribute(player, "/save:keldagrim-visited", true) + return true + } + } + return false + } +} + + +@Initializable +class DwarvenBoatmanBackDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + START_DIALOGUE -> npcl(FacialExpression.OLD_HAPPY, "Want me to take you back to the mines?").also { stage++ } + 1 -> showTopics( + Topic(FacialExpression.FRIENDLY, "Yes, please take me.", 2), + Topic(FacialExpression.FRIENDLY, "What, on your ship! No thanks!", 3), + ) + 2 -> end().also { submitWorldPulse(TravelBackPulse(player)) } + 3 -> npcl(FacialExpression.OLD_NORMAL, "Hey now, it was only a slight accident!").also { stage++ } + 4 -> playerl(FacialExpression.FRIENDLY, "A slight accident?? Have you any idea how much time I spent rebuilding that statue?").also { stage++ } + 5 -> npcl(FacialExpression.OLD_NORMAL, "Calm down, calm down! You got what you paid for the trip, didn't you?").also { + stage = END_DIALOGUE + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return DwarvenBoatmanBackDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.DWARVEN_BOATMAN_2206) + } +} + +class TravelBackPulse(val player: Player): Pulse(1){ + var counter = 0 + override fun pulse(): Boolean { + when(counter++){ + 0 -> lock(player, 10).also { + openInterface(player, Components.FADE_TO_BLACK_120) + } + 3 -> teleport(player, Location.create(2838, 10127, 0)) + 4 -> { + closeInterface(player) + openInterface(player, Components.FADE_FROM_BLACK_170) + } + 6 -> unlock(player).also { + closeInterface(player) + return true + } + } + return false + } +} diff --git a/Server/src/main/content/region/misc/keldagrim/dialogue/DwarvenFerrymanDialogue.kt b/Server/src/main/content/region/misc/keldagrim/dialogue/DwarvenFerrymanDialogue.kt new file mode 100644 index 0000000..37e462e --- /dev/null +++ b/Server/src/main/content/region/misc/keldagrim/dialogue/DwarvenFerrymanDialogue.kt @@ -0,0 +1,113 @@ +package content.region.misc.keldagrim.dialogue + +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.world.map.Location +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class DwarvenFerrymanForthDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + START_DIALOGUE -> { + if (!getAttribute(player, "/save:keldagrim-river-forth-crossed", false)) { + npcl(FacialExpression.OLD_DEFAULT, "Hello there, want a ride?").also { stage++ } + } else { + npcl(FacialExpression.OLD_DEFAULT, "Want to cross the river? It's just 2 gold pieces!").also { stage = 6 } + } + } + 1 -> playerl(FacialExpression.FRIENDLY, "A ride, where to?").also { stage++ } + 2 -> npcl(FacialExpression.OLD_DEFAULT, "Across the river, across the river! It's just a short ride!").also { stage++ } + 3 -> playerl(FacialExpression.FRIENDLY, "How much will that cost me?").also { stage++ } + 4 -> npcl(FacialExpression.OLD_DEFAULT, "Haha, you understand us dwarves well, human!").also { stage++ } + 5 -> npcl(FacialExpression.OLD_DEFAULT, "It's just 2 gold pieces! Want to go?").also { stage++ } + 6 -> showTopics( + Topic(FacialExpression.FRIENDLY, "Yes please.", 7), + Topic(FacialExpression.FRIENDLY, "No thanks.", END_DIALOGUE), + ) + 7 -> { + if (!inInventory(player, Items.COINS_995, 2)) { + npcl(FacialExpression.OLD_DEFAULT, "You don't even have 2 gold coins, humans!").also { stage++ } + } else { + if (removeItem(player, Item(Items.COINS_995, 2))) { + setAttribute(player, "/save:keldagrim-river-forth-crossed", true) + end() + teleport(player, Location.create(2836, 10143, 0)) + } + } + } + 8 -> npcl(FacialExpression.OLD_DEFAULT, "Come back later.").also { + stage = END_DIALOGUE + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return DwarvenFerrymanForthDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.DWARVEN_FERRYMAN_1843) + } +} + +// https://youtu.be/KI_f24g0Xl0 +@Initializable +class DwarvenFerrymanBackDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + START_DIALOGUE -> { + if (!getAttribute(player, "/save:keldagrim-river-back-crossed", false)) { + npcl(FacialExpression.OLD_DEFAULT, "Hello, want to cross the river?").also { stage++ } + } else { + npcl(FacialExpression.OLD_DEFAULT, "Want me to take you across? It's just 2 gold pieces!").also { stage = 4 } + } + } + 1 -> playerl(FacialExpression.FRIENDLY, "Are you going to charge me too?").also { stage++ } + 2 -> npcl(FacialExpression.OLD_DEFAULT, "Are you kidding?").also { stage++ } + 3 -> npc(FacialExpression.OLD_DEFAULT, "Of course I am! But it's just 2 gold coins, do you", "want to go?").also { stage++ } + 4 -> showTopics( + Topic(FacialExpression.FRIENDLY, "Yes please.", 5), + Topic(FacialExpression.FRIENDLY, "No thanks.", END_DIALOGUE), + ) + 5 -> { + if (!inInventory(player, Items.COINS_995, 2)) { + npcl(FacialExpression.OLD_DEFAULT, "You don't even have 2 gold coins, humans!").also { stage++ } + } else { + if (removeItem(player, Item(Items.COINS_995, 2))) { + end() + setAttribute(player, "/save:keldagrim-river-back-crossed", true) + teleport(player, Location.create(2864, 10133, 0)) + } + } + } + 6 -> npcl(FacialExpression.OLD_DEFAULT, "Come back later.").also { stage++ } + 7 -> playerl(FacialExpression.FRIENDLY, "But... that means I'm stuck here.").also { stage++ } + 8 -> npcl(FacialExpression.OLD_DEFAULT, "Hmm. I suppose I could make an exception for you this time.").also { stage++ } + 9 -> playerl(FacialExpression.FRIENDLY, "Thanks a lot!").also { stage++ } + 10 -> { + end() + setAttribute(player, "/save:keldagrim-river-back-crossed", true) + teleport(player, Location.create(2864, 10133, 0)) + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return DwarvenFerrymanBackDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.DWARVEN_FERRYMAN_1844) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/keldagrim/dialogue/FactoryManagerDialogue.kt b/Server/src/main/content/region/misc/keldagrim/dialogue/FactoryManagerDialogue.kt new file mode 100644 index 0000000..bc6e164 --- /dev/null +++ b/Server/src/main/content/region/misc/keldagrim/dialogue/FactoryManagerDialogue.kt @@ -0,0 +1,35 @@ +package content.region.misc.keldagrim.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class FactoryManagerDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + START_DIALOGUE -> npcl(FacialExpression.OLD_ANGRY1, "Don't bother me, can't you see I'm busy?").also { stage++ } + 1 -> playerl(FacialExpression.FRIENDLY, "No, I can't... can I go into the factory?").also { stage++ } + 2 -> npcl(FacialExpression.OLD_NORMAL, "You can go in. The Consortium, in their infinite wisdom, has decided to open up the factory to all and sundry.").also { stage++ } + 3 -> playerl(FacialExpression.FRIENDLY, "How come?").also { stage++ } + 4 -> npcl(FacialExpression.OLD_NORMAL, "We've built a new blast furnace and always have a shortage of people to work on it.").also { stage++ } + 5 -> playerl(FacialExpression.FRIENDLY, "I'll have a look, thanks.").also { stage++ } + 6 -> npcl(FacialExpression.OLD_NORMAL, "Just don't go causing any trouble, I still run this factory!").also { + stage = END_DIALOGUE + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return FactoryManagerDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.FACTORY_MANAGER_2171) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/keldagrim/dialogue/FactoryWorkersDialogue.kt b/Server/src/main/content/region/misc/keldagrim/dialogue/FactoryWorkersDialogue.kt new file mode 100644 index 0000000..3acf1ce --- /dev/null +++ b/Server/src/main/content/region/misc/keldagrim/dialogue/FactoryWorkersDialogue.kt @@ -0,0 +1,109 @@ +package content.region.misc.keldagrim.dialogue + +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class FactoryWorkerDialogue1(player: Player? = null) : core.game.dialogue.DialoguePlugin(player) { + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "I'm sorry, I'm looking for the blast furnace?").also { stage++ } + 1 -> npcl(FacialExpression.OLD_ANGRY1, "Do I look like a guide to you?").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "No, you look like a hard-working dwarf, but can you please tell me where the blast furnace is?").also { stage++ } + 3 -> npcl(FacialExpression.OLD_DEFAULT, "Alright, just head down the stairs, it's easy to find.").also { stage++ } + 4 -> playerl(FacialExpression.FRIENDLY, "Thanks.").also { + stage = END_DIALOGUE + } + } + return true + } + + override fun newInstance(player: Player?): core.game.dialogue.DialoguePlugin { + return FactoryWorkerDialogue1(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.FACTORY_WORKER_2172) + } +} + +@Initializable +class FactoryWorkerDialogue2(player: Player? = null) : core.game.dialogue.DialoguePlugin(player) { + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Are you okay?").also { stage++ } + 1 -> npcl(FacialExpression.OLD_ANGRY1, "Don't I look okay?").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "If you were any shorter you wouldn't exist.").also { stage++ } + 3 -> npcl(FacialExpression.OLD_ANGRY1, "Very funny, human.").also { + stage = END_DIALOGUE + } + } + return true + } + + override fun newInstance(player: Player?): core.game.dialogue.DialoguePlugin { + return FactoryWorkerDialogue2(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.FACTORY_WORKER_2173) + } +} + +@Initializable +class FactoryWorkerDialogue3(player: Player? = null) : core.game.dialogue.DialoguePlugin(player) { + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "What are you dwarves doing in this factory?").also { stage++ } + 1 -> npcl(FacialExpression.OLD_ANGRY1, "Working of course, can't you see that?").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "But working on what?").also { stage++ } + 3 -> npcl(FacialExpression.OLD_DEFAULT, "Refining the ore that is being brought into the factory, of course.").also { stage++ } + 4 -> playerl(FacialExpression.FRIENDLY, "And what does that mean?").also { stage++ } + 5 -> npcl(FacialExpression.OLD_ANGRY1, "It means you should stop asking so many questions and get back to work!").also { + stage = END_DIALOGUE + } + } + return true + } + + override fun newInstance(player: Player?): core.game.dialogue.DialoguePlugin { + return FactoryWorkerDialogue3(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.FACTORY_WORKER_2174) + } +} + +@Initializable +class FactoryWorkerDialogue4(player: Player? = null) : core.game.dialogue.DialoguePlugin(player) { + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Who owns this factory?").also { stage++ } + 1 -> npcl(FacialExpression.OLD_DEFAULT, "The Consortium does and that's all you need to know.").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "But what company? I thought there were all these different companies?").also { stage++ } + 3 -> npcl(FacialExpression.OLD_DEFAULT, "Oh yes, all the major companies own this plant. It's too vital to be in the hands of one company alone.").also { stage++ } + 4 -> playerl(FacialExpression.FRIENDLY, "And what exactly are you doing here?").also { stage++ } + 5 -> npcl(FacialExpression.OLD_ANGRY1, "I tire of these questions. Let me get back to work!").also { + stage = END_DIALOGUE + } + } + return true + } + + override fun newInstance(player: Player?): core.game.dialogue.DialoguePlugin { + return FactoryWorkerDialogue4(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.FACTORY_WORKER_2175) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/keldagrim/dialogue/GunslikDialogue.kt b/Server/src/main/content/region/misc/keldagrim/dialogue/GunslikDialogue.kt new file mode 100644 index 0000000..169ab01 --- /dev/null +++ b/Server/src/main/content/region/misc/keldagrim/dialogue/GunslikDialogue.kt @@ -0,0 +1,34 @@ +package content.region.misc.keldagrim.dialogue + +import core.api.openNpcShop +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class GunslikDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + START_DIALOGUE -> npcl(FacialExpression.OLD_DEFAULT, "What can I interest you in? We have something of everything here!").also { stage++ } + 1 -> showTopics( + Topic(FacialExpression.FRIENDLY, "Oh good!", 2), + Topic(FacialExpression.FRIENDLY, "Nothing, thanks.", END_DIALOGUE), + ) + 2 -> end().also{ openNpcShop(player, NPCs.GUNSLIK_2154) } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return GunslikDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.GUNSLIK_2154) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/keldagrim/dialogue/InnKeeperDialogue.kt b/Server/src/main/content/region/misc/keldagrim/dialogue/InnKeeperDialogue.kt new file mode 100644 index 0000000..f341e6d --- /dev/null +++ b/Server/src/main/content/region/misc/keldagrim/dialogue/InnKeeperDialogue.kt @@ -0,0 +1,57 @@ +package content.region.misc.keldagrim.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class InnKeeperDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + player(FacialExpression.FRIENDLY,"Hello.").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> { + npc(FacialExpression.CHILD_NEUTRAL, "Welcome to the King's Axe inn!", "What can I help you with?").also { stage++ } + } + + 1 -> { + player(FacialExpression.ASKING, "Can I have some beer please?").also { stage++ } + } + + 2 -> { + npc(FacialExpression.CHILD_NORMAL, "Go to the bar downstairs.", "I only deal with residents.").also { stage++ } + } + + 3 -> { + player(FacialExpression.THINKING, "Residents? People live here?").also { stage++ } + } + + 4 -> { + npc(FacialExpression.CHILD_LOUDLY_LAUGHING, "No, just guests that stay the night.").also { stage = 99 } + } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return InnKeeperDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.INN_KEEPER_2177) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/keldagrim/dialogue/JorzikDialogue.kt b/Server/src/main/content/region/misc/keldagrim/dialogue/JorzikDialogue.kt new file mode 100644 index 0000000..8844f37 --- /dev/null +++ b/Server/src/main/content/region/misc/keldagrim/dialogue/JorzikDialogue.kt @@ -0,0 +1,46 @@ +package content.region.misc.keldagrim.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +/** + * Jorzik dialogue. + * @author phil lips + */ + +@Initializable +class JorzikDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + START_DIALOGUE -> npc(FacialExpression.OLD_DEFAULT,"Do you want to trade?").also { stage++ } + 1 -> showTopics( + Topic(FacialExpression.FRIENDLY,"What are you selling?",2), + Topic(FacialExpression.FRIENDLY,"No, thanks.", 5) + ) + 2 -> npcl(FacialExpression.OLD_DEFAULT,"The finest smiths from all over Gielinor come here to work, and I buy the fruit of their craft. Armour made from the strongest metals!").also { stage++ } + 3 -> showTopics( + Topic(FacialExpression.FRIENDLY,"Let's have a look, then.",4), + Topic(FacialExpression.FRIENDLY,"No, thanks.", 5) + ) + 4 -> end().also { npc.openShop(player) } + 5 -> npcl(FacialExpression.OLD_DEFAULT,"You just don't appreciate the beauty of fine metalwork.").also { stage = END_DIALOGUE } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return JorzikDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.JORZIK_2565) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/keldagrim/dialogue/KarlDialogue.kt b/Server/src/main/content/region/misc/keldagrim/dialogue/KarlDialogue.kt new file mode 100644 index 0000000..a00e2dc --- /dev/null +++ b/Server/src/main/content/region/misc/keldagrim/dialogue/KarlDialogue.kt @@ -0,0 +1,40 @@ +package content.region.misc.keldagrim.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class KarlDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + START_DIALOGUE -> npcl(FacialExpression.OLD_DEFAULT, "Hello there, human! Come in, come in!").also { stage++ } + 1 -> playerl(FacialExpression.FRIENDLY, "Hi, nice to see you!").also { stage++ } + 2 -> npcl(FacialExpression.OLD_DEFAULT, "Tell me, what brings you here?").also { stage++ } + 3 -> playerl(FacialExpression.FRIENDLY, "Well, first I came to this city just for the adventure and excitement, but then I knocked over this statue, you see. Well, I didn't really knock it over myself, I was on this boat.").also { stage++ } + 4 -> npcl(FacialExpression.OLD_DEFAULT, "A boat! Fascinating, go on!").also { stage++ } + 5 -> playerl(FacialExpression.FRIENDLY, "Yes, well, this boatman was a bit rubbish, or there was something wrong with the ship, I don't know. And then I got arrested by the Black Guard.").also { stage++ } + 6 -> npcl(FacialExpression.OLD_DEFAULT, "Not the Black Guard!").also { stage++ } + 7 -> playerl(FacialExpression.FRIENDLY, "Yes, and they took me to this Veldaban person, who pretended to be really angry but actually he was really nice and he asked me for my help.").also { stage++ } + 8 -> playerl(FacialExpression.FRIENDLY, "And after a whole lot of running around, I finally managed to get the statue to be rebuilt.").also { stage++ } + 9 -> npcl(FacialExpression.OLD_DEFAULT, "Such an interesting tale!").also { stage++ } + 10 -> npcl(FacialExpression.OLD_DEFAULT, "Now how did you come to be in Keldagrim again?").also { stage++ } + 11 -> playerl(FacialExpression.FRIENDLY, "Never mind.").also { + stage = END_DIALOGUE + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return KarlDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.KARL_2195) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/keldagrim/dialogue/KjutDialogue.kt b/Server/src/main/content/region/misc/keldagrim/dialogue/KjutDialogue.kt new file mode 100644 index 0000000..9cd9bdc --- /dev/null +++ b/Server/src/main/content/region/misc/keldagrim/dialogue/KjutDialogue.kt @@ -0,0 +1,79 @@ +package content.region.misc.keldagrim.dialogue + +import content.data.Quests +import core.api.addItemOrDrop +import core.api.inInventory +import core.api.isQuestComplete +import core.api.removeItem +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class KjutDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + START_DIALOGUE -> npcl(FacialExpression.OLD_DEFAULT, "Kebabs! Get your kebabs here! One gold each!").also { stage++ } + 1 -> showTopics( + Topic(FacialExpression.FRIENDLY, "Sure, one kebab please.", 2, true), + Topic(FacialExpression.FRIENDLY, "I'm looking for a drunken dwarf.", 6), + Topic(FacialExpression.FRIENDLY, "Do you have any quests?", 17), + ) + 2 -> { + if (!inInventory(player, Items.COINS_995, 1)) { + playerl(FacialExpression.FRIENDLY, "Sure, one kebab please.").also { stage = 3 } + } else { + if (removeItem(player, Item(Items.COINS_995, 1))) { + addItemOrDrop(player, Items.KEBAB_1971) + playerl(FacialExpression.FRIENDLY, "Sure, one kebab please.").also { stage = END_DIALOGUE } + } + } + } + 3 -> npcl(FacialExpression.OLD_ANGRY1, "Yes? Are you going to give me that one gold coin then?").also { stage++ } + 4 -> playerl(FacialExpression.FRIENDLY, "Sorry, I don't seem to have any money on me.").also { stage++ } + 5 -> npcl(FacialExpression.OLD_DEFAULT, "The bank is Keldagrim-West. Hurry back!").also { + stage = END_DIALOGUE + } + 6 -> { + if (isQuestComplete(player, Quests.FORGETTABLE_TALE)) { + npcl(FacialExpression.OLD_DEFAULT, "I thought you would know plenty!").also { stage = 14 } + } else { + npcl(FacialExpression.OLD_DEFAULT, "Just go out in the streets, they can't be hard to find!").also { stage = 7 } + } + } + 7 -> playerl(FacialExpression.FRIENDLY, "No, a specific drunken dwarf, he keeps harassing me.").also { stage++ } + 8 -> npcl(FacialExpression.OLD_DEFAULT, "That's still not very helpful. But let me see. There is one particularly drunken dwarf just to the northeast of here.").also { stage++ } + 9 -> npcl(FacialExpression.OLD_DEFAULT, "He's scaring away my customers, he says there's something wrong with my kebabs. Quite annoying fellow.").also { stage++ } + 10 -> playerl(FacialExpression.FRIENDLY, "I don't think that's who I mean.").also { stage++ } + 11 -> npcl(FacialExpression.OLD_DEFAULT, "Well, he does have a relative who wanders all over Gielinor. Comes back from time to time to buy more kebabs. Don't see him very often though.").also { stage++ } + 12 -> playerl(FacialExpression.FRIENDLY, "Do you think I'll have any chance of catching him here?").also { stage++ } + 13 -> npcl(FacialExpression.OLD_DEFAULT, "I think he was back here quite recently, so I doubt he'll be back any time soon.").also { + stage = END_DIALOGUE + } + 14 -> playerl(FacialExpression.FRIENDLY, "How do you mean?").also { stage++ } + 15 -> npcl(FacialExpression.OLD_DEFAULT, "Oh come on! You in the Laughing Miner? The whole city knows about you and your dwarven drinking buddies!").also { stage++ } + 16 -> playerl(FacialExpression.FRIENDLY, "Right, right.").also { + stage = END_DIALOGUE + } + 17 -> npcl(FacialExpression.OLD_DEFAULT, "Not really! I have a steady supply of meat coming in through the carts and I don't really need anything else!").also { + stage = END_DIALOGUE + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return KjutDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.KJUT_2198) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/keldagrim/dialogue/NolarDialogue.kt b/Server/src/main/content/region/misc/keldagrim/dialogue/NolarDialogue.kt new file mode 100644 index 0000000..9b8eb4a --- /dev/null +++ b/Server/src/main/content/region/misc/keldagrim/dialogue/NolarDialogue.kt @@ -0,0 +1,35 @@ +package content.region.misc.keldagrim.dialogue + +import core.api.openNpcShop +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class NolarDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + START_DIALOGUE -> npc(FacialExpression.OLD_DEFAULT, "I have a wide variety of crafting tools on offer,", "care to take a look?").also { stage++ } + 1 -> showTopics( + Topic(FacialExpression.FRIENDLY, "Yes please!", 2), + Topic(FacialExpression.FRIENDLY, "No thanks.", END_DIALOGUE), + ) + 2 -> end().also{ openNpcShop(player, NPCs.NOLAR_2158) } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return NolarDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.NOLAR_2158) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/keldagrim/dialogue/OrdanDialogue.kt b/Server/src/main/content/region/misc/keldagrim/dialogue/OrdanDialogue.kt new file mode 100644 index 0000000..701ed5a --- /dev/null +++ b/Server/src/main/content/region/misc/keldagrim/dialogue/OrdanDialogue.kt @@ -0,0 +1,140 @@ +package content.region.misc.keldagrim.dialogue + +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.item.Item +import org.rs09.consts.NPCs +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.Items + +@Initializable +class OrdanDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin(player), InteractionListener { + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + // Dialogue follows https://www.youtube.com/watch?v=mwoA01EYQks a 29 May 2010 capture + when(stage){ + START_DIALOGUE -> npcl(FacialExpression.OLD_HAPPY, "Are you here to smith? Do you want to buy some ore?").also { stage++ } + 1 -> showTopics( + Topic(FacialExpression.FRIENDLY, "Yes please.", 2), + Topic(FacialExpression.FRIENDLY, "Can you un-note any of my items?", 3), + Topic(FacialExpression.FRIENDLY, "No thanks.", 5), + ) + 2 -> openNpcShop(player, NPCs.ORDAN_2564).also { + end() + } + 3 -> npc(FacialExpression.OLD_HAPPY,"I suppose I can un-note any ores that I sell in my", "shop - for a price of course. Just give me the noted ore", "you wish to exchange.").also { + stage++ + } + // This following dialogue is not authentic, but was originally here. + 4 -> npcl(FacialExpression.OLD_HAPPY,"I can even un-note Adamantite and Runite, but you're gonna need deep pockets for that.").also { + stage = END_DIALOGUE + } + 5 -> npcl(FacialExpression.OLD_ANGRY1, "Well don't waste my time then!").also { + stage = END_DIALOGUE + } + } + return true + } + + override fun newInstance(player: Player?): core.game.dialogue.DialoguePlugin { + return OrdanDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.ORDAN_2564) + } + + override fun defineListeners() { + onUseWith(IntType.NPC, OrdanDialogueFile.ORES_TO_UNNOTE_PRICES.keys.toIntArray(), NPCs.ORDAN_2564) { player, noteType, npc -> + openDialogue(player, OrdanDialogueFile(noteType.id, noteType.name), npc.asNpc()) + return@onUseWith true + } + } +} + +class OrdanDialogueFile(private val noteOreId: Int, private val noteOreName: String) : DialogueFile() { + + companion object { + val ORES_TO_UNNOTE_PRICES = hashMapOf( + Items.COPPER_ORE_437 to 10, + Items.TIN_ORE_439 to 10, + Items.IRON_ORE_441 to 8, + Items.SILVER_ORE_443 to 37, + Items.GOLD_ORE_445 to 75, + Items.MITHRIL_ORE_448 to 81, + Items.ADAMANTITE_ORE_450 to 330, + Items.RUNITE_ORE_452 to 1000, + Items.COAL_454 to 22, + ) + } + + // These are instance variables for un-noting dialogue. + var unnoteAmount = 0 + var unnotePrice = 0 + + // Dialogue follows https://www.youtube.com/watch?v=nqwzco2Es7o a 6 Dec 2009 capture + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + START_DIALOGUE -> { + // Swords position iface/child changes according to number of dialogue options. + setComponentVisibility(player!!, 232, 9, false) + setComponentVisibility(player!!, 232, 8, true) + sendDialogueOptions(player!!, "How much $noteOreName would you like to un-note?", "1", "5", "10", "X") + stage++ + } + 1 -> when (buttonID) { + 1 -> { + unnoteAmount = 1 + unnotePrice = 1 * ORES_TO_UNNOTE_PRICES[noteOreId]!! + npcl(FacialExpression.OLD_HAPPY, "I can un-note those for $unnotePrice gold pieces, is that okay?").also { stage++ } + } + 2 -> { + unnoteAmount = 5 + unnotePrice = 5 * ORES_TO_UNNOTE_PRICES[noteOreId]!! + npcl(FacialExpression.OLD_HAPPY, "I can un-note those for $unnotePrice gold pieces, is that okay?").also { stage++ } + } + 3 -> { + unnoteAmount = 10 + unnotePrice = 10 * ORES_TO_UNNOTE_PRICES[noteOreId]!! + npcl(FacialExpression.OLD_HAPPY, "I can un-note those for $unnotePrice gold pieces, is that okay?").also { stage++ } + } + 4 -> sendInputDialogue(player!!, true, "Enter amount:") { value -> + unnoteAmount = value as Int + // For QOL, reduce the amount to the number of free slots in player's inventory. + if (unnoteAmount > freeSlots(player!!)) { + unnoteAmount = freeSlots(player!!) + } + unnotePrice = unnoteAmount * ORES_TO_UNNOTE_PRICES[noteOreId]!! + // Dialogue is to cater to QOL + npcl(FacialExpression.OLD_HAPPY, "I can un-note $unnoteAmount $noteOreName for $unnotePrice gold pieces, is that okay?").also { stage++ } + return@sendInputDialogue + } + } + 2 -> showTopics( + Topic(FacialExpression.FRIENDLY, "It's a deal.", 3), + Topic(FacialExpression.FRIENDLY, "No, that's too expensive.", END_DIALOGUE), + ) + 3 -> { + if (freeSlots(player!!) < unnoteAmount) { + npc(FacialExpression.OLD_NORMAL, "You don't have enough room in your inventory for that", "number of un-noted items. Clear some space and try", "again.").also { stage = END_DIALOGUE } + } else if(amountInInventory(player!!, noteOreId) < unnoteAmount) { + sendDialogueLines(player!!, "You do not have enough notes to un-note", "$unnoteAmount $noteOreName.").also { stage = END_DIALOGUE } + } else if(amountInInventory(player!!, Items.COINS_995) < unnotePrice){ + sendDialogueLines(player!!, "You do not have enough coins to afford un-noting", "$unnoteAmount $noteOreName.").also{ stage = END_DIALOGUE } + } else { + if(removeItem(player!!, Item(Items.COINS_995, unnotePrice), Container.INVENTORY) && removeItem(player!!, Item(noteOreId, unnoteAmount), Container.INVENTORY)) { + addItem(player!!, noteOreId - 1, unnoteAmount) + } + end() + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/keldagrim/dialogue/ReinaldDialogue.kt b/Server/src/main/content/region/misc/keldagrim/dialogue/ReinaldDialogue.kt new file mode 100644 index 0000000..6e746f3 --- /dev/null +++ b/Server/src/main/content/region/misc/keldagrim/dialogue/ReinaldDialogue.kt @@ -0,0 +1,53 @@ +package content.region.misc.keldagrim.dialogue + +import core.api.openInterface +import core.cache.def.impl.NPCDefinition +import core.game.dialogue.DialoguePlugin +import core.game.interaction.OptionHandler +import core.game.node.Node +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.plugin.Plugin +import org.rs09.consts.NPCs + +/** + * File for handling Reinald's dialogue and right-click option + * @author Ceikry + */ +@Initializable +class ReinaldDialogue(player: Player? = null) : DialoguePlugin(player){ + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> npc("Hello, human! Would you like to browse","my little shop of bracelets?").also { stage++ } + 1 -> options("Yes, please!", "No, thanks.").also { stage++ } + 2 -> when(buttonId){ + 1 -> end().also { openInterface(player,593) } + 2 -> end() + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return ReinaldDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.REINALD_2194) + } + +} + +@Initializable +class ReinaldOptionHandler : OptionHandler(){ + override fun handle(player: Player?, node: Node?, option: String?): Boolean { + openInterface(player!!,593) + return true + } + + override fun newInstance(arg: Any?): Plugin { + NPCDefinition.forId(NPCs.REINALD_2194).handlers["option:change-armguards"] = this + return this + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/keldagrim/dialogue/RowdyDwarfDialogue.kt b/Server/src/main/content/region/misc/keldagrim/dialogue/RowdyDwarfDialogue.kt new file mode 100644 index 0000000..40f789e --- /dev/null +++ b/Server/src/main/content/region/misc/keldagrim/dialogue/RowdyDwarfDialogue.kt @@ -0,0 +1,30 @@ +package content.region.misc.keldagrim.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class RowdyDwarfDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + START_DIALOGUE -> npcl(FacialExpression.OLD_DRUNK_LEFT, "Get OUT of my WAY!").also { + stage = END_DIALOGUE + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return RowdyDwarfDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.ROWDY_DWARF_2187) + } +} + diff --git a/Server/src/main/content/region/misc/keldagrim/dialogue/RunvastrDialogue.kt b/Server/src/main/content/region/misc/keldagrim/dialogue/RunvastrDialogue.kt new file mode 100644 index 0000000..77e5d32 --- /dev/null +++ b/Server/src/main/content/region/misc/keldagrim/dialogue/RunvastrDialogue.kt @@ -0,0 +1,34 @@ +package content.region.misc.keldagrim.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class RunvastrDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + START_DIALOGUE -> npcl(FacialExpression.OLD_DEFAULT, "Oh, leave an old dwarf in peace will you?").also { stage++ } + 1 -> playerl(FacialExpression.FRIENDLY, "Why, what's wrong?").also { stage++ } + 2 -> npcl(FacialExpression.OLD_DEFAULT, "Ninenty years down in the mines, and this is all I got out of it. All my life wasted away.").also { stage++ } + 3 -> playerl(FacialExpression.FRIENDLY, "You've still got a nice house, don't you?").also { stage++ } + 4 -> npcl(FacialExpression.OLD_DEFAULT, "A crummy old house in East, that's all my life amounts to.").also { stage++ } + 5 -> playerl(FacialExpression.FRIENDLY, "I'll leave you alone then.").also { + stage = END_DIALOGUE + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return RunvastrDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.RUNVASTR_2190) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/keldagrim/dialogue/SuneDialogue.kt b/Server/src/main/content/region/misc/keldagrim/dialogue/SuneDialogue.kt new file mode 100644 index 0000000..efaa8e6 --- /dev/null +++ b/Server/src/main/content/region/misc/keldagrim/dialogue/SuneDialogue.kt @@ -0,0 +1,33 @@ +package content.region.misc.keldagrim.dialogue + +import core.api.openNpcShop +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class SuneDialogue(player: Player? = null) : DialoguePlugin(player){ + + // This npc travels between Tati's house and the city's marketplace. + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + START_DIALOGUE -> npcl(FacialExpression.OLD_ANGRY1, "Can you leave me alone please? I'm trying to get a bit of rest.").also { + stage = END_DIALOGUE + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return SuneDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.SUNE_2191) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/keldagrim/dialogue/TatiDialogue.kt b/Server/src/main/content/region/misc/keldagrim/dialogue/TatiDialogue.kt new file mode 100644 index 0000000..df4ab14 --- /dev/null +++ b/Server/src/main/content/region/misc/keldagrim/dialogue/TatiDialogue.kt @@ -0,0 +1,54 @@ +package content.region.misc.keldagrim.dialogue + +import core.api.openNpcShop +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class TatiDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + START_DIALOGUE -> npcl(FacialExpression.OLD_ANGRY1, "What'you want?").also { stage++ } + 1 -> showTopics( + Topic(FacialExpression.FRIENDLY, "Do you have any pickaxes?", 2, true), + Topic(FacialExpression.FRIENDLY, "Do you have any quests?", 7, true), + Topic(FacialExpression.FRIENDLY, "Nothing really.", 14), + ) + 2 -> playerl(FacialExpression.FRIENDLY, "Do you-").also { stage++ } + 3 -> npcl(FacialExpression.OLD_ANGRY1, "What? Speak up, I can't hear you!").also { stage++ } + 4 -> playerl(FacialExpression.FRIENDLY, "Uhm... I'm just looking for some pickaxes! Do you have any?").also { stage++ } + 5 -> npcl(FacialExpression.OLD_ANGRY1, "Do I have any pickaxes? Do I? Of course I do, this is a pickaxe shop, isn't it!").also{ stage++ } + 6 -> openNpcShop(player, NPCs.TATI_2160).also { + stage = END_DIALOGUE + } + 7 -> playerl(FacialExpression.FRIENDLY, "Do you-").also { stage++ } + 8 -> npcl(FacialExpression.OLD_ANGRY1, "What? Stop mumbling!").also { stage++ } + 9 -> playerl(FacialExpression.FRIENDLY, "I want a quest!").also { stage++ } + 10 -> npcl(FacialExpression.OLD_ANGRY1, "I don't have any lousy quests... I've got someone who's helping me already!").also { stage++ } + 11 -> npcl(FacialExpression.OLD_ANGRY1, "Well, I say helping... he takes his merry time to do his chores, my son does.").also { stage++ } + 12 -> playerl(FacialExpression.FRIENDLY, "Then perhaps I can help in some way?").also { stage++ } + 13 -> npcl(FacialExpression.OLD_ANGRY1, "Pfft, I doubt it... maybe when my son fouls up again, but not now.").also { + stage = END_DIALOGUE + } + 14 -> npcl(FacialExpression.OLD_ANGRY1, "Then clear off!").also { + stage = END_DIALOGUE + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return TatiDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.TATI_2160) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/keldagrim/dialogue/UlifedDialogue.kt b/Server/src/main/content/region/misc/keldagrim/dialogue/UlifedDialogue.kt new file mode 100644 index 0000000..8de6056 --- /dev/null +++ b/Server/src/main/content/region/misc/keldagrim/dialogue/UlifedDialogue.kt @@ -0,0 +1,31 @@ +package content.region.misc.keldagrim.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class UlifedDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + START_DIALOGUE -> npcl(FacialExpression.OLD_DEFAULT, "Say, aren't you the human who got arrested here the other day, by the boat?").also { stage++ } + 1 -> playerl(FacialExpression.FRIENDLY, "Yes, but we cleared up the whole situation.").also { stage++ } + 2 -> npcl(FacialExpression.OLD_DEFAULT, "Right, right.").also { + stage = END_DIALOGUE + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return UlifedDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.ULIFED_2193) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/keldagrim/handlers/KeldagrimCartMethods.kt b/Server/src/main/content/region/misc/keldagrim/handlers/KeldagrimCartMethods.kt new file mode 100644 index 0000000..20d4d57 --- /dev/null +++ b/Server/src/main/content/region/misc/keldagrim/handlers/KeldagrimCartMethods.kt @@ -0,0 +1,99 @@ +package content.region.misc.keldagrim.handlers + +import core.game.component.Component +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.system.task.Pulse +import core.game.world.map.Direction +import core.game.world.map.Location +import org.rs09.consts.Components +import core.game.world.GameWorld +import core.api.* +import content.data.Quests + +object KeldagrimCartMethods { + @JvmStatic + fun goToKeldagrim(player: Player){ + if (!hasRequirement(player, Quests.THE_GIANT_DWARF)) + return + GameWorld.Pulser.submit(TravelToKeldagrimPulse(player)) + } + + @JvmStatic + fun leaveKeldagrimTo(player: Player, dest: Location){ + if (!hasRequirement(player, Quests.THE_GIANT_DWARF)) + return + GameWorld.Pulser.submit(TravelFromKeldagrimPulse(player,dest)) + } +} + + +class TravelFromKeldagrimPulse(val player: Player, val dest: Location): Pulse(){ + var counter = 0 + override fun pulse(): Boolean { + when(counter++){ + 0 -> player.lock().also { player.interfaceManager.open(Component(Components.FADE_FROM_BLACK_170)) } + 4 -> { + player.properties.teleportLocation = Location.create(2911, 10171, 0) + player.appearance.rideCart(true) + } + 5 -> { + player.walkingQueue.reset() + player.walkingQueue.addPath(2936, 10171) + } + 6 -> { + player.interfaceManager.close(Component(Components.FADE_FROM_BLACK_170)) + player.interfaceManager.open(Component(Components.FADE_FROM_BLACK_170)) + } + 14 -> { + player.interfaceManager.open(Component(Components.FADE_TO_BLACK_120)) + } + 21 -> { + player.walkingQueue.reset() + player.properties.teleportLocation = dest + player.appearance.rideCart(false) + } + 23 -> { + player.interfaceManager.close(Component(Components.FADE_TO_BLACK_120)) + player.interfaceManager.open(Component(Components.FADE_FROM_BLACK_170)) + } + 25 -> { + player.unlock() + player.interfaceManager.close(Component(Components.FADE_FROM_BLACK_170)) + return true + } + } + return false + } +} + +class TravelToKeldagrimPulse(val player: Player) : Pulse(){ + var counter = 0 + var cartNPC = NPC(1544) + override fun pulse(): Boolean { + when(counter++){ + 0 -> player.lock().also { player.interfaceManager.open(Component(115)) } + 3 -> player.properties.teleportLocation = Location.create(2942, 10175, 0).also { player.appearance.rideCart(true) } + 5 -> { + player.walkingQueue.reset() + player.walkingQueue.addPath(2915, 10175) + } + 7 -> { + player.interfaceManager.close(Component(115)) + player.interfaceManager.open(Component(170)) + } + 19 -> { + player.interfaceManager.close(Component(170)) + player.unlock() + player.appearance.rideCart(false) + cartNPC.location = player.location + cartNPC.direction = Direction.WEST + cartNPC.init() + player.properties.teleportLocation = player.location.transform(0,1,0) + } + 33 -> return true.also { cartNPC.clear() } + + } + return false + } +} diff --git a/Server/src/main/content/region/misc/keldagrim/handlers/KeldagrimListeners.kt b/Server/src/main/content/region/misc/keldagrim/handlers/KeldagrimListeners.kt new file mode 100644 index 0000000..2cf8da9 --- /dev/null +++ b/Server/src/main/content/region/misc/keldagrim/handlers/KeldagrimListeners.kt @@ -0,0 +1,19 @@ +package content.region.misc.keldagrim.handlers + +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.world.map.Location +import org.rs09.consts.Scenery + +class KeldagrimListeners : InteractionListener { + override fun defineListeners() { + on(Scenery.DOORWAY_23286, IntType.SCENERY, "enter") { player, _ -> + player.properties.teleportLocation = Location.create(2941, 10179, 0) + return@on true + } + on(Scenery.DOORWAY_23287, IntType.SCENERY, "enter") { player, _ -> + player.properties.teleportLocation = Location.create(2435, 5535, 0) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/keldagrim/handlers/KeldagrimPlugin.kt b/Server/src/main/content/region/misc/keldagrim/handlers/KeldagrimPlugin.kt new file mode 100644 index 0000000..24a7a33 --- /dev/null +++ b/Server/src/main/content/region/misc/keldagrim/handlers/KeldagrimPlugin.kt @@ -0,0 +1,126 @@ +package content.region.misc.keldagrim.handlers + +import content.minigame.blastfurnace.BlastFurnace +import core.api.* +import core.cache.def.impl.SceneryDefinition +import core.game.interaction.OptionHandler +import core.game.node.Node +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.world.map.Location +import core.plugin.Initializable +import core.plugin.Plugin +import core.game.dialogue.DialogueFile +import core.game.dialogue.DialoguePlugin +import core.tools.END_DIALOGUE +import org.rs09.consts.Items + +/** + * File that contains several plugins relating to Keldagrim, + * most notably the KeldagrimOptionHandlers and GETrapdoorDialogue + * Anything that wasn't significant enough for its own individual file, tbh. + * @author Ceikry + */ + +const val GETrapdoorDialogueID = 22381232 + +/** + * Handles various options around keldagrim that weren't significant enough for a separate file + */ +@Initializable +class KeldagrimOptionHandlers : OptionHandler() { + + override fun handle(player: Player?, node: Node?, option: String?): Boolean { + player ?: return false + node ?: return false + option ?: return false + when(option){ + "go-through" -> { + when (node.id) { + 5973 -> player.properties.teleportLocation = Location.create(2838, 10125) + 5998 -> player.properties.teleportLocation = Location.create(2780, 10161) + } + } + "open" -> { + when(node.id){ + 28094 -> player.dialogueInterpreter.open(GETrapdoorDialogueID) + } + } + "enter" -> { + when(node.id){ + 5014 -> player.properties.teleportLocation = Location.create(2730, 3713, 0) + } + } + } + return true + } + + override fun newInstance(arg: Any?): Plugin { + SceneryDefinition.forId(5973).handlers["option:go-through"] = this + SceneryDefinition.forId(5998).handlers["option:go-through"] = this + SceneryDefinition.forId(9084).handlers["option:climb-down"] = this + SceneryDefinition.forId(9138).handlers["option:climb-up"] = this + SceneryDefinition.forId(28094).handlers["option:open"] = this + SceneryDefinition.forId(5014).handlers["option:enter"] = this + return this + } +} + +/** + * Dialogue used for the trapdoor in the grand exchange. + */ +@Initializable +class GETrapdoorDialogue(player: Player? = null) : DialoguePlugin(player){ + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> end() + 10 -> when(buttonId){ + 1 -> KeldagrimCartMethods.goToKeldagrim(player).also { end() } + 2 -> end() + } + } + return true + } + + override fun open(vararg args: Any?): Boolean { + val keldagrimVisited = player.getAttribute("keldagrim-visited",false) + if(keldagrimVisited){ + options("Travel to Keldagrim","Nevermind.") + stage = 10 + } else { + player.dialogueInterpreter.sendDialogue("Perhaps I should visit Keldagrim first.") + stage = 0 + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return GETrapdoorDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(GETrapdoorDialogueID) + } +} + + +class BlastFurnaceDoorDialogue(val fee: Int) : DialogueFile(){ + var init = true + override fun handle(componentID: Int, buttonID: Int) { + when(stage){ + 0 -> sendDialogue(player!!,"You must be Smithing Level 60 or higher in order to enter the Blast Furnace").also { stage++ } + 1 -> sendDialogue(player!!,"However, you may enter for 10 minutes if you pay the entrance fee.
($fee gp)").also { stage++ } + 2 -> options("Yes","No").also { stage++ } + 3 -> when(buttonID){ + 1 -> { + if (removeItem(player!!, Item(Items.COINS_995, fee))) + BlastFurnace.enter(player!!, true) + else + sendDialogue(player!!, "You don't have enough gold to cover the entrance fee!") + stage = END_DIALOGUE + } + 20 -> sendDialogue(player!!,"Then get out of here!").also { stage = END_DIALOGUE } + } + } + } +} diff --git a/Server/src/main/content/region/misc/keldagrim/handlers/ReinaldSmithingEmporiumInterface.kt b/Server/src/main/content/region/misc/keldagrim/handlers/ReinaldSmithingEmporiumInterface.kt new file mode 100644 index 0000000..c6f0a0f --- /dev/null +++ b/Server/src/main/content/region/misc/keldagrim/handlers/ReinaldSmithingEmporiumInterface.kt @@ -0,0 +1,124 @@ +package content.region.misc.keldagrim.handlers + +import core.game.component.Component +import core.game.component.ComponentDefinition +import core.game.component.ComponentPlugin +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import core.plugin.Plugin + +const val REINALD_COMPONENT_ID = 593 +private const val BRACELET_INTERFACE_CHILD_ID = 69 + +//Models to send for various wristguards +private const val SILVER_WRISTGUARDS = 27703 +private const val SILVER_CLASPS = 27704 +private const val SILVER_BANGLES = 27706 +private const val SILVER_BANDING = 27707 +private const val SILVER_BANDS = 27697 +private const val SILVER_ARMGUARDS = 27699 + +private const val GOLD_WRISTGUARDS = 27698 +private const val GOLD_CLASPS = 27708 +private const val GOLD_BANGLES = 27702 +private const val GOLD_BANDING = 27705 +private const val GOLD_BANDS = 27700 +private const val GOLD_ARMGUARDS = 27709 + +private const val NONE = 0 + +private val COINS = Item(995,500) + +//Appearance Indexes for Various Wristguards +//117S 118G 119S 120G 121S 122G 123S 124G 125S 126G M +//159S 160G 161S 162G 163S 164G 165S 166G 167S 168G F +//67SF 68NF 127GF 33SM 34NM 84GM +@Initializable +/** + * Handle's Reinald's bracelet shop + * @author Ceikry + */ +class ReinaldSmithingEmporiumInterface : ComponentPlugin(){ + override fun open(player: Player?, component: Component?) { + super.open(player, component) + //make sure the player can't just close the interface and get it for free (lol) + player?.setAttribute("wrists-look",player.appearance.wrists.look) + player?.toggleWardrobe(true) + component?.setCloseEvent(){pl,_ -> + player?.toggleWardrobe(false) + val orindex = pl.getAttribute("wrists-look", if(pl.isMale) 34 else 68) + val paid = pl.getAttribute("bracelet-paid",false) + if(!paid) { + pl.appearance.wrists.changeLook(orindex) + pl.appearance.sync() + } + pl.removeAttribute("bracelet-paid") + true + } + } + override fun handle(player: Player?, component: Component?, opcode: Int, button: Int, slot: Int, itemId: Int): Boolean { + player ?: return false + when(button){ + 122, + 129 -> sendModel(NONE,player) + 123 -> sendModel(SILVER_WRISTGUARDS,player) + 124 -> sendModel(SILVER_CLASPS,player) + 125 -> sendModel(SILVER_BANGLES,player) + 126 -> sendModel(SILVER_BANDING,player) + 127 -> sendModel(SILVER_BANDS,player) + 128 -> sendModel(SILVER_ARMGUARDS,player) + 130 -> sendModel(GOLD_WRISTGUARDS,player) + 131 -> sendModel(GOLD_CLASPS, player) + 132 -> sendModel(GOLD_BANGLES,player) + 133 -> sendModel(GOLD_BANDING,player) + 134 -> sendModel(GOLD_BANDS,player) + 135 -> sendModel(GOLD_ARMGUARDS,player) + 117 -> confirm(player) + } + return true + } + + fun confirm(player: Player){ + if(player.inventory.containsItem(COINS)){ + player.inventory.remove(COINS) + player.setAttribute("bracelet-paid",true) + player.interfaceManager.close() + } else { + player.dialogueInterpreter.sendDialogue("You can not afford that.") + } + } + + fun sendModel(id: Int, player: Player){ + var appearanceIndex = when(id){ + SILVER_CLASPS -> 117 + GOLD_CLASPS -> 118 + SILVER_BANDS -> 119 + GOLD_BANDS -> 120 + SILVER_ARMGUARDS -> 123 + GOLD_ARMGUARDS -> 124 + SILVER_BANDING -> 121 + GOLD_BANDING -> 122 + SILVER_BANGLES -> 125 + GOLD_BANGLES -> 126 + SILVER_WRISTGUARDS -> if(player.isMale) 33 else 67 + GOLD_WRISTGUARDS -> if(player.isMale) 84 else 127 + NONE -> if(player.isMale) 34 else 68 + else -> 0 + } + if(!player.isMale && id != SILVER_WRISTGUARDS && id != GOLD_WRISTGUARDS && id != NONE){ + appearanceIndex += 42 //Female is almost always 42 higher than male, except for the above cases in the if + } + player.packetDispatch.sendModelOnInterface(id, REINALD_COMPONENT_ID, BRACELET_INTERFACE_CHILD_ID, 1) + player.packetDispatch.sendInterfaceConfig(REINALD_COMPONENT_ID, BRACELET_INTERFACE_CHILD_ID,id == 0) //hide/show bracelet model depending on if 0 or not + player.appearance.wrists.changeLook(appearanceIndex) + player.debug("USING WRIST APPEARANCE ID $appearanceIndex") + player.appearance.sync() + player.packetDispatch.sendPlayerOnInterface(REINALD_COMPONENT_ID,60) + } + + override fun newInstance(arg: Any?): Plugin { + ComponentDefinition.put(REINALD_COMPONENT_ID,this) + return this + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/miscellania/dialogue/AlvissDialogue.kt b/Server/src/main/content/region/misc/miscellania/dialogue/AlvissDialogue.kt new file mode 100644 index 0000000..b3f4f70 --- /dev/null +++ b/Server/src/main/content/region/misc/miscellania/dialogue/AlvissDialogue.kt @@ -0,0 +1,65 @@ +package content.region.misc.miscellania.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class AlvissDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npc(FacialExpression.OLD_DEFAULT,"Good day, sir.").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> { + options("What are you doing down here?", "Good day.").also { stage++ } + } + + 1 -> when(buttonId){ + 1 -> { + player(FacialExpression.FRIENDLY, "What are you doing down here?").also { stage = 10 } + } + + 2 -> { + player(FacialExpression.NEUTRAL, "Good day.").also { stage = 99 } + } + } + + 10 -> { + npc(FacialExpression.OLD_DEFAULT,"I'm waiting for my shift, of course.", + "We can't dig all the time, you know.").also { stage++ } + } + + 11 -> { + npc(FacialExpression.OLD_DEFAULT," I'm also researching the links between the ", + "Fremenniks and the Dwarves.").also { stage++ } + } + + 12 -> { + npc(FacialExpression.OLD_DEFAULT,"I've found that we have some mythology in common.").also { stage = 99 } + } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return AlvissDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.ALVISS_3933) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/miscellania/dialogue/DerrikDialogue.kt b/Server/src/main/content/region/misc/miscellania/dialogue/DerrikDialogue.kt new file mode 100644 index 0000000..4e55e6f --- /dev/null +++ b/Server/src/main/content/region/misc/miscellania/dialogue/DerrikDialogue.kt @@ -0,0 +1,56 @@ +package content.region.misc.miscellania.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * Dialogue for Derrik in Misc. + * @author qmqz + */ + +@Initializable +class DerrikDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npc(FacialExpression.FRIENDLY,"Good day, Sir. Can I help you with anything?").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + + 0 -> { + options("Can I use your anvil?", "Nothing, thanks.").also { stage++ } + } + + 1 -> when(buttonId){ + 1 -> { + player(FacialExpression.ASKING, "Can I use your anvil?").also { stage = 5 } + } + 2 -> { + player(FacialExpression.NEUTRAL, "Nothing, thanks.").also { stage = 99 } + } + } + + 5 -> { + npc(FacialExpression.NEUTRAL, "You may.").also { stage = 99 } + } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return DerrikDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.DERRIK_1376) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/miscellania/dialogue/DonalDialogue.kt b/Server/src/main/content/region/misc/miscellania/dialogue/DonalDialogue.kt new file mode 100644 index 0000000..a7aafe5 --- /dev/null +++ b/Server/src/main/content/region/misc/miscellania/dialogue/DonalDialogue.kt @@ -0,0 +1,52 @@ +package content.region.misc.miscellania.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class DonalDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npc(FacialExpression.OLD_DEFAULT,"What do you want?").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> { + player(FacialExpression.THINKING, "Just wondering if you were still here.").also { stage++ } + } + + 1 -> { + npc(FacialExpression.OLD_DEFAULT, "Of course I'm still here.").also { stage++ } + } + + 2 -> { + npc(FacialExpression.OLD_DISTRESSED, "I'm not going near that crack in the wall again.").also { stage++ } + } + + 3 -> { + npc(FacialExpression.OLD_DISTRESSED, "Rock falls and so on are fine, ", "but sea monsters in caves - never!").also { stage = 99 } + } + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return DonalDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.DONAL_3938) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/miscellania/dialogue/FerdDialogue.kt b/Server/src/main/content/region/misc/miscellania/dialogue/FerdDialogue.kt new file mode 100644 index 0000000..92d0185 --- /dev/null +++ b/Server/src/main/content/region/misc/miscellania/dialogue/FerdDialogue.kt @@ -0,0 +1,66 @@ +package content.region.misc.miscellania.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class FerdDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npc(FacialExpression.OLD_DEFAULT,"Good day, sir.").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> { + player(FacialExpression.THINKING, "What are you doing down here?.").also { stage++ } + } + + 1 -> { + npc(FacialExpression.OLD_DEFAULT, "Shoring up the walls.").also { stage++ } + } + + 2 -> { + player(FacialExpression.ASKING, "What does that do?").also { stage++ } + } + + 3 -> { + npc(FacialExpression.OLD_DEFAULT, "Stops them falling down.").also { stage = 99 } + } + + 4 -> { + player(FacialExpression.ASKING, "Oh, I see.").also { stage++ } + } + + 5 -> { + npc(FacialExpression.OLD_NOT_INTERESTED, "Aye.", + "If you want to chatter, you'd better talk to ", + "Thorodin over there. I'm working.").also { stage = 99 } + } + + 6 -> { + player(FacialExpression.ASKING, "Okay then.").also { stage++ } + } + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return FerdDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.FERD_3937) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/miscellania/dialogue/FinnDialogue.kt b/Server/src/main/content/region/misc/miscellania/dialogue/FinnDialogue.kt new file mode 100644 index 0000000..f9c813a --- /dev/null +++ b/Server/src/main/content/region/misc/miscellania/dialogue/FinnDialogue.kt @@ -0,0 +1,68 @@ +package content.region.misc.miscellania.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * Dialogue for Finn in Misc. + * @author qmqz + */ + +@Initializable +class FinnDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npc(FacialExpression.FRIENDLY,"Can I help you, your Royal Highness?").also { stage = 0 } + stage = 0 + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> { + options("Yes please. What are you selling?", "No thanks.", "What's it like living down here?").also { stage++ } + } + + 1 -> when(buttonId){ + 1 -> { + player(FacialExpression.ASKING, "Yes please. What are you selling?").also { stage = 10 } + } + + 2 -> { + player(FacialExpression.NEUTRAL, "No thanks.").also { stage = 99 } + } + + 3 -> { + player(FacialExpression.ASKING, "What's it like living down here?").also { stage = 20 } + } + } + + 10 -> { + end().also { npc.openShop(player) } + } + + 20 -> { + npc(FacialExpression.HALF_WORRIED, "A lot drier in the winter than it is above ground.").also { stage = 99 } + } + + 99 -> { + end() + } + + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return FinnDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.FINN_3922) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/miscellania/dialogue/FishmongerMiscDialogue.kt b/Server/src/main/content/region/misc/miscellania/dialogue/FishmongerMiscDialogue.kt new file mode 100644 index 0000000..e2ece67 --- /dev/null +++ b/Server/src/main/content/region/misc/miscellania/dialogue/FishmongerMiscDialogue.kt @@ -0,0 +1,43 @@ +package content.region.misc.miscellania.dialogue + +import core.api.isQuestComplete +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs +import content.data.Quests + +/** + * @author qmqz + */ + +@Initializable +class FishmongerMiscDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + if (!isQuestComplete(player, Quests.THRONE_OF_MISCELLANIA)) { + npcl(FacialExpression.FRIENDLY,"Greetings, Sir. Get your fresh fish here! I've heard that the Etceterian fish is stored in a cow shed.").also { stage = 0 } + } else { + npcl(FacialExpression.FRIENDLY,"Greetings, Your Highness. Have some fresh fish! I've heard that the Etceterian fish is stored in a cow shed.").also { stage = 0 } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> end().also { npc.openShop(player) } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return FishmongerMiscDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.FISHMONGER_1393) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/miscellania/dialogue/FlowerGirlDialogue.kt b/Server/src/main/content/region/misc/miscellania/dialogue/FlowerGirlDialogue.kt new file mode 100644 index 0000000..6320d5a --- /dev/null +++ b/Server/src/main/content/region/misc/miscellania/dialogue/FlowerGirlDialogue.kt @@ -0,0 +1,81 @@ +package content.region.misc.miscellania.dialogue + +import core.api.addItemOrDrop +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * Dialogue for the Flower Girl in Misc. + * @author qmqz + */ + +@Initializable +class FlowerGirlDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + + //issues getting throne of miscellania status + /* + when (player.questRepository.getQuest(Quests.THRONE_OF_MISCELLANIA).isCompleted(player)) { + true -> npc(FacialExpression.HAPPY, "Good day, Your Royal Highness.").also { stage = 1 } + false -> npc(FacialExpression.NEUTRAL, "Hello.").also { stage = 1 } + } + */ + npc(FacialExpression.NEUTRAL, "Hello.").also { stage = 1 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 1 -> { + player(FacialExpression.ASKING, "Good day. What are you doing?").also { stage++ } + } + + 2 -> { + /* + when (player.questRepository.getQuest(Quests.THRONE_OF_MISCELLANIA).isCompleted(player)) { + true -> npc(FacialExpression.HAPPY, "I'm selling flowers, 15gp for three. Would you like some, Your Highness?").also { stage++ } + false -> npc(FacialExpression.NEUTRAL, "I'm selling flowers, 15gp for three. Would you like some?").also { stage++ } + } + */ + npc(FacialExpression.NEUTRAL, "I'm selling flowers, 15gp for three. Would you like some?").also { stage++ } + } + + 3 -> { + options("Yes, please.", "No, thank you.").also { stage++ } + } + + 4 -> when(buttonId){ + 1 -> { + if (player.inventory.contains(995,15)) { + npc(FacialExpression.HAPPY, "Thank you! Here you go.").also { stage = 99 } + player.inventory.remove(Item(995, 15)) + addItemOrDrop(player, 2460, 1) + } else { + player(FacialExpression.HALF_THINKING, "I'm sorry, but I don't have 15gp.").also { stage = 99 } + } + } + 2 -> { + player(FacialExpression.NEUTRAL, "No, thank you.").also { stage = 99 } + } + } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return FlowerGirlDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.FLOWER_GIRL_1378) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/miscellania/dialogue/FullangrDialogue.kt b/Server/src/main/content/region/misc/miscellania/dialogue/FullangrDialogue.kt new file mode 100644 index 0000000..c8e0530 --- /dev/null +++ b/Server/src/main/content/region/misc/miscellania/dialogue/FullangrDialogue.kt @@ -0,0 +1,57 @@ +package content.region.misc.miscellania.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class FullangrDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npc(FacialExpression.OLD_DEFAULT,"Good day, sir.").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> { + options("What are you doing down here?", "Good day.").also { stage++ } + } + + 1 -> when(buttonId){ + 1 -> { + player(FacialExpression.FRIENDLY, "What are you doing down here?").also { stage = 10 } + } + + 2 -> { + player(FacialExpression.NEUTRAL, "Good day.").also { stage = 99 } + } + } + + 10 -> { + npc(FacialExpression.OLD_DEFAULT,"I'm working on the digging, of course.", + "It's a small excavation, so only two of us ", + "can work on it at a time.").also { stage = 99 } + } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return FullangrDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.FULLANGR_3934) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/miscellania/dialogue/GreengrocerMiscDialogue.kt b/Server/src/main/content/region/misc/miscellania/dialogue/GreengrocerMiscDialogue.kt new file mode 100644 index 0000000..789d091 --- /dev/null +++ b/Server/src/main/content/region/misc/miscellania/dialogue/GreengrocerMiscDialogue.kt @@ -0,0 +1,41 @@ +package content.region.misc.miscellania.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * Dialogue for the Fishmonger in Misc. + * @author qmqz + */ + +@Initializable +class GreengrocerMiscDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npc(FacialExpression.FRIENDLY,"Welcome, Sir.", + "I sell only the finest and freshest vegetables!").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage){ + 0 -> { + end().also { npc.openShop(player) } + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return GreengrocerMiscDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.GREENGROCER_1394) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/miscellania/dialogue/HallaDialogue.kt b/Server/src/main/content/region/misc/miscellania/dialogue/HallaDialogue.kt new file mode 100644 index 0000000..ca55da3 --- /dev/null +++ b/Server/src/main/content/region/misc/miscellania/dialogue/HallaDialogue.kt @@ -0,0 +1,70 @@ +package content.region.misc.miscellania.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class HallaDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npc(FacialExpression.FRIENDLY,"Welcome to Miscellania's first clothing store!", "We sell clothing made especially for Fremenniks", "and Dwarves.").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> { + npc(FacialExpression.ASKING, "Can I help you with anything, your Royal Highness?").also { stage++ } + } + + 1 -> { + options("I'd like to look at what you have for sale.", "No thank you, I'm fine.", "What's it like living down here?").also { stage++ } + } + + 2 -> when(buttonId){ + 1 -> { + player(FacialExpression.FRIENDLY, "I'd like to look at what you have for sale.").also { stage = 10 } + } + + 2 -> { + player(FacialExpression.NEUTRAL, "No thank you, I'm fine.").also { stage = 99 } + } + + 3 -> { + player(FacialExpression.ASKING, "What's it like living down here?").also { stage = 20 } + } + } + + 10 -> { + end().also { npc.openShop(player) } + } + + 20 -> { + npc(FacialExpression.NEUTRAL, "It's very spacious down here.", "One of the dwarves said that the caves go on for miles!").also { stage++ } + } + 21 -> { + npc(FacialExpression.NEUTRAL, "The only problem I find is that the lighting's not very good,", "which means I make mistakes when cutting cloth.").also { stage = 99 } + } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return HallaDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.HALLA_3921) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/miscellania/dialogue/JariDialogue.kt b/Server/src/main/content/region/misc/miscellania/dialogue/JariDialogue.kt new file mode 100644 index 0000000..94e6c2d --- /dev/null +++ b/Server/src/main/content/region/misc/miscellania/dialogue/JariDialogue.kt @@ -0,0 +1,60 @@ +package content.region.misc.miscellania.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class JariDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npc(FacialExpression.OLD_DEFAULT,"Good day, sir.").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> { + options("What are you doing down here?", "Good day.").also { stage++ } + } + + 1 -> when(buttonId){ + 1 -> { + player(FacialExpression.FRIENDLY, "What are you doing down here?").also { stage = 10 } + } + + 2 -> { + player(FacialExpression.NEUTRAL, "Good day.").also { stage = 99 } + } + } + + 10 -> { + npc(FacialExpression.OLD_DEFAULT,"I'm waiting to work on the digging.").also { stage++ } + } + + 11 -> { + npc(FacialExpression.OLD_HAPPY,"It's the first excavation I've worked on, ", + "and I'm looking forward to it.").also { stage = 99 } + } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return JariDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.JARI_3935) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/miscellania/dialogue/KjallakOnChopDialogue.kt b/Server/src/main/content/region/misc/miscellania/dialogue/KjallakOnChopDialogue.kt new file mode 100644 index 0000000..a8e6742 --- /dev/null +++ b/Server/src/main/content/region/misc/miscellania/dialogue/KjallakOnChopDialogue.kt @@ -0,0 +1,13 @@ +package content.region.misc.miscellania.dialogue + +import core.tools.END_DIALOGUE +import core.game.dialogue.DialogueFile + +class KjallakOnChopDialogue : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when(stage){ + 0 -> npc("Hey! You're not allowed to chop those!").also { stage++ } + 1 -> player("Oh, ok...").also { stage = END_DIALOGUE } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/miscellania/dialogue/MiscCitizenGoodDayDialogue.kt b/Server/src/main/content/region/misc/miscellania/dialogue/MiscCitizenGoodDayDialogue.kt new file mode 100644 index 0000000..7224714 --- /dev/null +++ b/Server/src/main/content/region/misc/miscellania/dialogue/MiscCitizenGoodDayDialogue.kt @@ -0,0 +1,45 @@ +package content.region.misc.miscellania.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class MiscCitizenGoodDayDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + player(FacialExpression.FRIENDLY,"Hello.").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> { + npc(FacialExpression.FRIENDLY, "Good day, Your Royal Highness.").also { stage = 99 } + } + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return MiscCitizenGoodDayDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.ALRIK_1381, NPCs.RUNOLF_3924, + NPCs.BRODDI_1390, NPCs.EINAR_1380, NPCs.INGRID_3926, + NPCs.RAGNAR_1379, NPCs.RAGNVALD_1392, NPCs.RANNVEIG_1386, + NPCs.THORA_3927, NPCs.THORA_1387, NPCs.THORHILD_1382, + NPCs.VALGERD_1388, NPCs.TJORVI_3925 + ) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/miscellania/dialogue/OsvaldDialogue.kt b/Server/src/main/content/region/misc/miscellania/dialogue/OsvaldDialogue.kt new file mode 100644 index 0000000..ad21fb7 --- /dev/null +++ b/Server/src/main/content/region/misc/miscellania/dialogue/OsvaldDialogue.kt @@ -0,0 +1,73 @@ +package content.region.misc.miscellania.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class OsvaldDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npc(FacialExpression.FRIENDLY,"Welcome to the Miscellania food store.","We've only opened recently.").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0-> { + npc(FacialExpression.NEUTRAL, "Would you like to buy anything,", + "your Royal Highness?").also { stage++ } + } + + 1 -> { + options("Could you show me what you have for sale?", + "No thank you, I don't need food just now.", + "What's it like living down here?").also { stage++ } + } + + 2 -> when(buttonId){ + 1 -> { + player(FacialExpression.ASKING, "Could you show me what you have for sale?").also { stage = 10 } + } + + 2 -> { + player(FacialExpression.NEUTRAL, "No thank you, I don't need food just now.").also { end() } + } + + 3 -> { + player(FacialExpression.ASKING, "What's it like living down here?").also { stage = 20 } + } + } + + 10 -> { + end().also { npc.openShop(player) } + } + + 20 -> { + npc(FacialExpression.FRIENDLY, "The town's thriving.", + "I'm sure it'll soon be as busy as Rellekka!").also { stage = 99 } + } + + 99 -> { + end() + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return OsvaldDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.OSVALD_3923) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/miscellania/dialogue/RunaDialogue.kt b/Server/src/main/content/region/misc/miscellania/dialogue/RunaDialogue.kt new file mode 100644 index 0000000..8a13bda --- /dev/null +++ b/Server/src/main/content/region/misc/miscellania/dialogue/RunaDialogue.kt @@ -0,0 +1,77 @@ +package content.region.misc.miscellania.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class RunaDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npc(FacialExpression.FRIENDLY,"Would you like to try some fine Miscellanian ale,", "your Royal Highness?").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> { + npc(FacialExpression.ASKING, "Well I say Miscellanian, but it's actually brewed", "on the mainland.").also { stage++ } + } + + 1 -> { + npc(FacialExpression.FRIENDLY, "Would you like to try some anyway?").also { stage++ } + } + + 2 -> { + options("Yes, please.", "No, thank you.", "What's it like living down here?").also { stage++ } + } + + 3 -> when(buttonId){ + 1 -> { + player(FacialExpression.ASKING, "Yes please.").also { stage = 10 } + } + + 2 -> { + player(FacialExpression.NEUTRAL, "No thank you.").also { stage = 99 } + } + + 3 -> { + player(FacialExpression.ASKING, "What's it like living down here?").also { stage = 20 } + } + } + + 10 -> { + end().also { npc.openShop(player) } + } + + 20 -> { + npc(FacialExpression.HALF_WORRIED, "Business is booming!").also { stage++ } + } + + 21 -> { + npc(FacialExpression.HALF_WORRIED, "Now, if only I hadn't taken a loss to the beer I sold", "to those teenagers.").also { end() } + } + + 99 -> { + end() + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return RunaDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.RUNA_3920) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/miscellania/dialogue/ThorodinDialogue.kt b/Server/src/main/content/region/misc/miscellania/dialogue/ThorodinDialogue.kt new file mode 100644 index 0000000..6cf33d5 --- /dev/null +++ b/Server/src/main/content/region/misc/miscellania/dialogue/ThorodinDialogue.kt @@ -0,0 +1,75 @@ +package content.region.misc.miscellania.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class ThorodinDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npc(FacialExpression.OLD_DEFAULT,"Good day, sir.").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> { + options("What are you doing down here?", "Good day.").also { stage++ } + } + + 1 -> when(buttonId){ + 1 -> { + player(FacialExpression.FRIENDLY, "What are you doing down here?").also { stage = 10 } + } + + 2 -> { + player(FacialExpression.NEUTRAL, "Good day.").also { stage = 99 } + } + } + + 10 -> { + npc(FacialExpression.OLD_DEFAULT,"We're extending the cave so more people can live in it.", + "These Miscellanians aren't so bad.", + "They appreciate the benefits of living underground.").also { stage++ } + } + + 11 -> { + player(FacialExpression.ASKING,"...such as?").also { stage++ } + } + + 12 -> { + npc(FacialExpression.OLD_DEFAULT,"Not getting rained on, for example.", + "Did you do anything about that monster Donal", "was talking about?").also { stage++ } + } + + 13 -> { + player(FacialExpression.FRIENDLY,"It's been taken care of.").also { stage++ } + } + + 14 -> { + npc(FacialExpression.OLD_HAPPY,"Glad to hear it.", + "Now we can get on with excavating.").also { stage = 99 } + } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return ThorodinDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.THORODIN_3936) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/mosle/dialogue/CharleyDialogue.kt b/Server/src/main/content/region/misc/mosle/dialogue/CharleyDialogue.kt new file mode 100644 index 0000000..9461b96 --- /dev/null +++ b/Server/src/main/content/region/misc/mosle/dialogue/CharleyDialogue.kt @@ -0,0 +1,77 @@ +package content.region.misc.mosle.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class CharleyDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + + if (player.inventory.contains(Items.BOOK_O_PIRACY_7144, 1)) { + npc(FacialExpression.FRIENDLY, "I got fish, you got gold?").also { stage = 10 } + } else { + player(FacialExpression.FRIENDLY, "Hello!").also { stage = 0 } + } + + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> npcl(FacialExpression.FRIENDLY, "Arr? Be ye wantin' te go on account with our gang o' fillibusters?").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "The powder monkey be takin' a caulk after gettin' rowdy on bumboo, so there be plenty of room for ye.").also { stage++ } + 2 -> player(FacialExpression.FRIENDLY, "Riiiiight...").also { stage++ } + 3 -> player(FacialExpression.FRIENDLY, "I'll just be over here if you need me.").also { stage = 99 } + + 10 -> options("Yes.", "Yes, but I don't want your fish.", "What happened to your legs?").also { stage++ } + + 11 -> when(buttonId) { + 1 -> player(FacialExpression.FRIENDLY, "Yes.").also { stage = 80 } + 2 -> player(FacialExpression.FRIENDLY, "Yes, but I don't want your fish.").also { stage = 20 } + 3 -> player(FacialExpression.HALF_ASKING, "What happened to your legs?").also { stage = 30 } + } + + 20 -> npcl(FacialExpression.FRIENDLY, "Then what are ye doin' in a fish shop? Looking fer work?").also { stage++ } + 21 -> player(FacialExpression.FRIENDLY, "Possibly, do you have any quests?").also { stage++ } + 22 -> npcl(FacialExpression.HALF_ASKING, "I dunno, I haven't gone through the last catch yet. What sort of a fish is it?").also { stage++ } + 23 -> player(FacialExpression.FRIENDLY, "A quest isn't a type of fish!").also { stage++ } + 24 -> npcl(FacialExpression.FRIENDLY, "Then I don't have any, and yer wastin' my time!").also { stage = 99 } + + 30 -> npcl(FacialExpression.FRIENDLY, "Ye wanna know what happened to my legs?").also { stage++ } + 31 -> npcl(FacialExpression.FRIENDLY, "Yer too much of a lilly-livered, hat wearin' landlubber to know what happened to my legs!").also { stage++ } + 32 -> playerl(FacialExpression.FRIENDLY, "No I'm not! I've seen some freaky stuff! I can take it!").also { stage++ } + 33 -> npcl(FacialExpression.FRIENDLY, "All right, lad, since yer so insistent, I'll tell ye.").also { stage++ } + 34 -> npcl(FacialExpression.FRIENDLY, "See, I was clingin' onto a barrel, me ship havin' just had an encounter with this albatross.").also { stage++ } + 35 -> npcl(FacialExpression.FRIENDLY, "The sea was thrashin' and wild, but not so wild that I didn't see the fins of some sharks closin' in on me.").also { stage++ } + 36 -> npcl(FacialExpression.FRIENDLY, "I managed to yank a sliver of wood from the barrel just as one of them grabbed me from below, but I slipped down the things throat by about two feet before I managed te kill it.").also { stage++ } + 37 -> player(FacialExpression.FRIENDLY, "How did you survive?").also { stage++ } + 38 -> npcl(FacialExpression.FRIENDLY, "A passin' ship saw the sharks and knew there would be survivors in the water. They sent a longboat and picked me up, but not before the sharks had taken off my legs.").also { stage++ } + 39 -> npcl(FacialExpression.FRIENDLY, "And that lad is why they call me two feet Charley, because they found me jammed two feet down a shark's throat.").also { stage++ } + 40 -> player(FacialExpression.DISGUSTED, "I think I'm gonna be sick...").also { stage++ } + 41 -> npcl(FacialExpression.FRIENDLY, "I knew ye couldn't handle the truth!").also { stage = 99 } + + 80 -> end().also { npc.openShop(player) } + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return CharleyDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.CHARLEY_3161) + } +} diff --git a/Server/src/main/content/region/misc/mosle/dialogue/MamaDialogue.java b/Server/src/main/content/region/misc/mosle/dialogue/MamaDialogue.java new file mode 100644 index 0000000..91c1f15 --- /dev/null +++ b/Server/src/main/content/region/misc/mosle/dialogue/MamaDialogue.java @@ -0,0 +1,73 @@ +package content.region.misc.mosle.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the dialouge plugin used for the dward shop. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class MamaDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code DwarfShopDialogue} {@code Object}. + */ + public MamaDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code DwarfShopDialogue} {@code Object}. + * @param player the player. + */ + public MamaDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new MamaDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ar, darlin'! How might ya' Mama help ye?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "I'd like to see what you have", "Nevermind"); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + end(); + npc.openShop(player); + break; + case 2: + end(); + break; + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 3164 }; + } +} diff --git a/Server/src/main/content/region/misc/mosle/dialogue/PatchyDialogue.java b/Server/src/main/content/region/misc/mosle/dialogue/PatchyDialogue.java new file mode 100644 index 0000000..36c74c6 --- /dev/null +++ b/Server/src/main/content/region/misc/mosle/dialogue/PatchyDialogue.java @@ -0,0 +1,73 @@ +package content.region.misc.mosle.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the dialouge plugin used for the dward shop. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class PatchyDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code DwarfShopDialogue} {@code Object}. + */ + public PatchyDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code DwarfShopDialogue} {@code Object}. + * @param player the player. + */ + public PatchyDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new PatchyDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Aye, can I help ye at all?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "Yes please, what are you selling?", "No thanks."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + end(); + npc.openShop(player); + break; + case 2: + end(); + break; + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 4359 }; + } +} diff --git a/Server/src/main/content/region/misc/piratecove/dialogue/BeefyBurnsDialogue.kt b/Server/src/main/content/region/misc/piratecove/dialogue/BeefyBurnsDialogue.kt new file mode 100644 index 0000000..9ee5b70 --- /dev/null +++ b/Server/src/main/content/region/misc/piratecove/dialogue/BeefyBurnsDialogue.kt @@ -0,0 +1,43 @@ +package content.region.misc.piratecove.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class BeefyBurnsDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + player(FacialExpression.HALF_ASKING, "What are you cooking?").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> npc(FacialExpression.LAUGH, "My speciality! What else could I be cooking?").also { stage++ } + 1 -> player(FacialExpression.THINKING, "Ok, and your speciality is...?").also { stage++ } + 2 -> npcl(FacialExpression.LAUGH, "Boiled shark guts with a hint of rosemary and a dash of squid ink.").also { stage++ } + 3 -> player(FacialExpression.FRIENDLY,"I think I'll stick to making my own food.").also { stage++ } + 4 -> npc(FacialExpression.FRIENDLY, "Your loss!").also { stage = 99 } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return BeefyBurnsDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.BEEFY_BURNS_4541) + } +} diff --git a/Server/src/main/content/region/misc/piratecove/dialogue/DaveyBoyDialogue.kt b/Server/src/main/content/region/misc/piratecove/dialogue/DaveyBoyDialogue.kt new file mode 100644 index 0000000..756915a --- /dev/null +++ b/Server/src/main/content/region/misc/piratecove/dialogue/DaveyBoyDialogue.kt @@ -0,0 +1,51 @@ +package content.region.misc.piratecove.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class DaveyBoyDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + when ((1..2).random()) { + 1 -> playerl(FacialExpression.HALF_ASKING, "What does it take to become first mate on a ship?").also { stage = 0 } + 2 -> npcl(FacialExpression.ANNOYED, "It is customary when stowing away on a vessel to not introduce yourself to the Captains First Mate, oh foolish one.").also { stage = 10 } + } + + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> npcl(FacialExpression.LAUGH, "Good question. We have a diplomatic consession at the turn of the financial year. Said pirate is chosen should the existing mate be absent without leave.").also { stage++ } + 1 -> playerl(FacialExpression.THINKING, "I had no idea. I always figured it was all about popularity.").also { stage++ } + 2 -> npc(FacialExpression.FRIENDLY, "It is. I'm just pulling your leg.").also { stage++ } + 3 -> player(FacialExpression.FRIENDLY,"Oh....").also { stage = 99 } + + 10 -> player(FacialExpression.ANNOYED, "Hey! I'm not a stowaway!").also { stage++ } + 11 -> player(FacialExpression.ANNOYED, "That Lokar guy invited me aboard...").also { stage++ } + 12 -> npcl(FacialExpression.FRIENDLY, "I see. Well, don't distract me as I'm making preparations for departure.").also { stage++ } + 13 -> npcl(FacialExpression.FRIENDLY, "Try not to distract any of the crew either, Zamorak knows it's hard enough to get them to do any work around here without strangers wandering round the ship asking them inane questions.").also { stage = 99 } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return DaveyBoyDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.FIRST_MATE_DAVEY_BOY_4543) + } +} diff --git a/Server/src/main/content/region/misc/piratecove/dialogue/EagleEyeShultzDialogue.kt b/Server/src/main/content/region/misc/piratecove/dialogue/EagleEyeShultzDialogue.kt new file mode 100644 index 0000000..ab7083b --- /dev/null +++ b/Server/src/main/content/region/misc/piratecove/dialogue/EagleEyeShultzDialogue.kt @@ -0,0 +1,42 @@ +package content.region.misc.piratecove.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class EagleEyeShultzDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + playerl(FacialExpression.HALF_ASKING, "What do you do for fun on this ship? You know, when you're not doing pirate stuff.").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> npcl(FacialExpression.FRIENDLY, "All sorts! Hide and seek, pin the patch on the pirate, walk the plank!").also { stage++ } + 1 -> playerl(FacialExpression.WORRIED, "What a life! Wait a minute. 'Walk the plank'? Surely that's a bit dangerous?").also { stage++ } + 2 -> npcl(FacialExpression.LAUGH, "Well of course, but where's the fun without a few deaths?").also { stage++ } + 3 -> player(FacialExpression.HALF_THINKING,"I think I'll stick to Runelink.").also { stage = 99 } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return EagleEyeShultzDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.EAGLE_EYE_SHULTZ_4542) + } +} diff --git a/Server/src/main/content/region/misc/piratecove/dialogue/LecherousLeeDialogue.kt b/Server/src/main/content/region/misc/piratecove/dialogue/LecherousLeeDialogue.kt new file mode 100644 index 0000000..5664509 --- /dev/null +++ b/Server/src/main/content/region/misc/piratecove/dialogue/LecherousLeeDialogue.kt @@ -0,0 +1,107 @@ +package content.region.misc.piratecove.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class LecherousLeeDialogue(player: Player? = null) : DialoguePlugin(player){ + + private val conversations = arrayOf (0, 10, 13, 17, 21, 27, 31, 36, 43, 52) + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + player(FacialExpression.FRIENDLY, "Hello.").also { stage = conversations.random() } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> player(FacialExpression.FRIENDLY, "So how's life as a pirate?").also { stage++ } + 1 -> npcl(FacialExpression.LAUGH, "What kind of question is that? How's life as a... I dunno. Whatever it is that you do for a living.").also { stage++ } + 2 -> player(FacialExpression.FRIENDLY,"I'm a freelance troubleshooter.").also { stage++ } + 3 -> npc(FacialExpression.FRIENDLY, "What does that entail then?").also { stage++ } + 4 -> playerl(FacialExpression.FRIENDLY,"Mostly killing things for money and delivering items around the planet for people.").also { stage++ } + 5 -> player(FacialExpression.FRIENDLY,"I collect stuff.").also { stage++ } + 6 -> npc(FacialExpression.FRIENDLY, "So how's that life?").also { stage++ } + 7 -> player(FacialExpression.FRIENDLY,"Can't complain, can't complain...").also { stage++ } + 8 -> npc(FacialExpression.FRIENDLY, "Well, there you go.").also { stage = 99 } + + 10 -> player(FacialExpression.FRIENDLY, "Aren't you a little short for a pirate?").also { stage++ } + 11 -> npcl(FacialExpression.LAUGH, "My mother was a gnome. Apparently it was a very painful birth.").also { stage++ } + 12 -> player(FacialExpression.FRIENDLY,"More info than I wanted, thanks!").also { stage = 99 } + + 13 -> npcl(FacialExpression.FRIENDLY, "Sorry, can't stop, the Captain will have my guts for garters if he catches me slacking off talking to the stowaway.").also { stage++ } + 14 -> player(FacialExpression.FRIENDLY,"I'm not a stowaway! I was invited aboard!").also { stage++ } + 15 -> npcl(FacialExpression.FRIENDLY, "Yeah, whatever guy, it doesn't really matter who you are I'll get in trouble!").also { stage = 99 } + + 17 -> playerl(FacialExpression.FRIENDLY, "You know, I've always wondered what life as a pirate actually entails.").also { stage++ } + 18 -> npcl(FacialExpression.LAUGH, "Well, at the moment it mostly involves being asked random questions by a stowaway.").also { stage++ } + 19 -> playerl(FacialExpression.FRIENDLY,"I'm not a stowaway! I was invited aboard! By Lokar! Ask him!").also { stage++ } + 20 -> npcl(FacialExpression.FRIENDLY, "Hey, whatever pal. Just make sure the captain doesn't catch you, pirates don't like stowaways much.").also { stage = 99 } + + 21 -> npcl(FacialExpression.LAUGH, "Ah, good day to you sirrah! Your face is unfamiliar, did you perhaps join us aboard the ship at Lunar Isle?").also { stage++ } + 22 -> playerl(FacialExpression.FRIENDLY,"No, Lokar offered me a lift in Rellekka actually.").also { stage++ } + 23 -> npcl(FacialExpression.FRIENDLY, "Oh, really? You don't look like a Fremennik to me!").also { stage++ } + 24 -> playerl(FacialExpression.FRIENDLY,"Well... I kind of am, and I kind of aren't. It's a long story.").also { stage++ } + 25 -> npcl(FacialExpression.FRIENDLY, "Sorry I don't have time to hear it then! See you around young fremennik-who-is-not-really-a- fremennik!").also { stage++ } + 26 -> playerl(FacialExpression.FRIENDLY,"'Bye.").also { stage = 99 } + + 27 -> player(FacialExpression.FRIENDLY, "Brrrr! Its cold up here!").also { stage++ } + 28 -> npcl(FacialExpression.LAUGH, "You think this is cold? Up by Acheron it gets so cold that when you talk you see the words freeze in the air in front of you!").also { stage++ } + 29 -> player(FacialExpression.FRIENDLY,"REALLY?").also { stage++ } + 30 -> npcl(FacialExpression.FRIENDLY, "Nah, not really. I was exaggerating for humourous effect. It is very very cold though!").also { stage = 99 } + + + 31 -> npc(FacialExpression.LAUGH, "Hello to you too.").also { stage++ } + 32 -> playerl(FacialExpression.FRIENDLY,"Yar! We be pirates, yar! Avast, ye scurvy land-lubbing lychee!").also { stage++ } + 33 -> npcl(FacialExpression.FRIENDLY, "Please don't talk like that, it is extremely irritating.").also { stage++ } + 34 -> npcl(FacialExpression.FRIENDLY, "Also, please don't call me a lychee, whatever that may be.").also { stage++ } + 35 -> player(FacialExpression.FRIENDLY,"Oh. Okay. Sorry.").also { stage = 99} + + + 36 -> npc(FacialExpression.LAUGH, "ARGH!", "SOUND THE ALARM!", "STOWAWAY ON BOARD!", "STOWAWAY ON BOARD!").also { stage++ } + 37 -> player(FacialExpression.FRIENDLY,"No! I'm not a stowaway! Honest! I was invited here!").also { stage++ } + 38 -> npc(FacialExpression.FRIENDLY, "Oh, sorry, my mistake then.").also { stage++ } + 39 -> npcl(FacialExpression.FRIENDLY, "You must admit you do look a lot like a stowaway though.").also { stage++ } + 40 -> player(FacialExpression.FRIENDLY,"Why, what do they usually look like?").also { stage++ } + 41 -> npc(FacialExpression.FRIENDLY, "Erm... I've never actually met one...").also { stage++ } + 42 -> player(FacialExpression.FRIENDLY,"Okay then...").also { stage = 99 } + + 43 -> npc(FacialExpression.LAUGH, "Hello.").also { stage++ } + 44 -> player(FacialExpression.FRIENDLY,"So... You're a pirate, huh?").also { stage++ } + 45 -> npcl(FacialExpression.FRIENDLY, "It's what it says on my pay-packet at the end of the month.").also { stage++ } + 46 -> player(FacialExpression.FRIENDLY,"How's that working out for you?").also { stage++ } + 47 -> npcl(FacialExpression.FRIENDLY, "Pretty good so far. All the grog and loot that we can plunder, plus full medical including dental.").also { stage++ } + 48 -> player(FacialExpression.FRIENDLY,"You mean you have insurance?").also { stage++ } + 49 -> npcl(FacialExpression.FRIENDLY, "Not as such. If any of us get sick we kidnap a doctor and don't let him go until we're better.").also { stage++ } + 50 -> npcl(FacialExpression.FRIENDLY, "You'd be surprised what an incentive for expert health care that is.").also { stage++ } + 51 -> player(FacialExpression.FRIENDLY,"I can imagine.").also { stage = 99 } + + 52 -> npc(FacialExpression.LAUGH, "Hello there. So what brings you aboard the Lady Zay?").also { stage++ } + 53 -> playerl(FacialExpression.FRIENDLY,"Well, I was planning on visiting the Moon Clan, but I have to say your ship is very impressive.").also { stage++ } + 54 -> npcl(FacialExpression.FRIENDLY, "Aye, she's a beauty alright! The Lady Zay has been my home for many hard months, through storm and sun, and she always gets us to here we were headed!").also { stage++ } + 55 -> playerl(FacialExpression.FRIENDLY,"Yes, she's certainly one of the finest boats I've seen on my travels!").also { stage++ } + 56 -> npc(FacialExpression.FRIENDLY, "That she is lad, that she is.").also { stage = 99 } + + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return LecherousLeeDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.LECHEROUS_LEE_4556) + } +} diff --git a/Server/src/main/content/region/misc/tutisland/dialogue/BankerTutorDialogue.java b/Server/src/main/content/region/misc/tutisland/dialogue/BankerTutorDialogue.java new file mode 100644 index 0000000..c6a1215 --- /dev/null +++ b/Server/src/main/content/region/misc/tutisland/dialogue/BankerTutorDialogue.java @@ -0,0 +1,155 @@ +package content.region.misc.tutisland.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the banker tutor dialogue. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class BankerTutorDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code BankerTutorDialogue} {@code Object}. + * @param player the player. + */ + public BankerTutorDialogue(final Player player) { + super(player); + } + + /** + * Constructs a new {@code BankerTutorDialogue} {@code Object}. + */ + public BankerTutorDialogue() { + /** + * empty. + */ + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new BankerTutorDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = args[0] instanceof NPC ? (NPC) args[0] : null; + npc("Good day, would you like to access your bank account?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + options("How do I use the bank?", "I'd like to access my bank account please.", "I'd like to check my PIN settings."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + options("Using the bank itself.", "Using Bank deposit boxes.", "What's this PIN thing that people keep talking about?", "Goodbye."); + stage = 9; + break; + case 2: + end(); + player.getBank().open(); + break; + case 3: + end(); + player.getBankPinManager().openSettings(); + break; + } + break; + case 9: + switch (buttonId) { + case 1: + player("Using the bank itself. I'm not sure how....?"); + stage = 10; + break; + case 2: + player("Using Bank deposit boxes.... what are they?"); + stage = 20; + break; + case 3: + player("What's this PIN thing that people keep talking about?"); + stage = 30; + break; + case 4: + player("Goodbye."); + stage = 99; + break; + } + break; + case 10: + npc("Speak to any banker and ask to see your bank", "account. If you have set a PIN you will be asked for", "it, then all the belongings you have placed in the bank", "will appear in the window. To withdraw one item, left-"); + stage = 11; + break; + case 11: + npc("click on it once."); + stage = 12; + break; + case 12: + npc("To withdraw many, right-click on the item and select", "from the menu. The same for depositing, left-click on", "the item in your inventory to deposit it in the bank.", "Right-click on it to deposit many of the same items."); + stage = 13; + break; + case 13: + npc("To move things around in your bank: firstly select", "Swap or Insert as your default moving mode, you can", "find these buttons on the bank window itself. Then click", "and drag an item to where you want it to appear."); + stage = 14; + break; + case 14: + npc("You may withdraw 'notes' or 'certificates' when the", "items you are trying to withdraw do not stack in your", "inventory. This will only work for items which are", "tradeable."); + stage = 15; + break; + case 15: + npc("For instance, if you wanted to sell 100 logs to another", "player, they would not fit in one inventory and you", "would need to do multiple trades. Instead, click the", "Note button to do withdraw the logs as 'certs' or 'notes',"); + stage = 16; + break; + case 16: + npc("then withdraw the items you need."); + stage = 99; + break; + case 20: + npc("They look like grey pillars, there's one just over there,", "near the desk. Bank deposit boxes save so much time.", "If you're simply wanting to deposit a single item, 'Use'", "it on the deposit box."); + stage = 21; + break; + case 21: + npc("Otherwise, simply click once on the box and it will give", "you a choice of what to deposit in an interface very", "similar to the bank itself. Very quick for when you're", "simply fishing or mining etc."); + stage = 22; + break; + case 22: + end(); + break; + case 30: + npc("The PIN - Personal Identification Number - can be", "set on your bank account to protect the items there in", "case someone finds out your account password. It", "consists of four numbers that you remember and tell"); + stage = 31; + break; + case 31: + npc("no one."); + stage = 32; + break; + case 32: + npc("So if someone did manage to get your password they", "couldn't steal your items if they were in the bank."); + stage = 33; + break; + case 33: + end(); + break; + case 99: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 4907 }; + } + +} diff --git a/Server/src/main/content/region/misc/tutisland/dialogue/SkipTutorialDialogue.kt b/Server/src/main/content/region/misc/tutisland/dialogue/SkipTutorialDialogue.kt new file mode 100644 index 0000000..3a16f44 --- /dev/null +++ b/Server/src/main/content/region/misc/tutisland/dialogue/SkipTutorialDialogue.kt @@ -0,0 +1,48 @@ +package content.region.misc.tutisland.dialogue + +import core.api.setAttribute +import core.api.teleport +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.NPCs +import content.region.misc.tutisland.handlers.TutorialStage + +/** + * Handles Skippy's skip tutorial dialogue + * @author Ceikry + */ +@Initializable +class SkipTutorialDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player?): DialoguePlugin { + return SkipTutorialDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npcl(FacialExpression.FRIENDLY, "Hey, would you like to skip to the end? Choose wisely! This is the only time you get this choice.") + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> options("Yes, I'd like to skip the tutorial.", "No thanks.").also { stage++ } + 1 -> when(buttonId) + { + 1 -> { + end() + setAttribute(player, "/save:tutorial:stage", 71) + TutorialStage.load(player, 71) + teleport(player, Location.create(3141, 3089, 0)) + } + 2 -> end() + } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.SKIPPY_2796) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/tutisland/dialogue/SurvivalExpertDialogue.kt b/Server/src/main/content/region/misc/tutisland/dialogue/SurvivalExpertDialogue.kt new file mode 100644 index 0000000..21c914b --- /dev/null +++ b/Server/src/main/content/region/misc/tutisland/dialogue/SurvivalExpertDialogue.kt @@ -0,0 +1,119 @@ +package content.region.misc.tutisland.dialogue + +import core.api.addItem +import core.api.inInventory +import core.api.setAttribute +import core.game.component.Component +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import content.region.misc.tutisland.handlers.TutorialStage + +/** + * Handles the survival expert's dialogue + * @author Ceikry + */ +@Initializable +class SurvivalExpertDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player?): DialoguePlugin { + return SurvivalExpertDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + val tutStage = player?.getAttribute("tutorial:stage", 0) ?: 0 + when(tutStage) + { + 4 -> Component.setUnclosable( + player, + interpreter.sendDialogues( + npc, + FacialExpression.FRIENDLY, + "Hello there, newcomer. My name is Brynna. My job is", + "to teach you a few survival tips and tricks. First off", + "we're going to start with the most basic survival skill of", + "all: making a fire." + ) + ) + + 11 -> Component.setUnclosable( + player, + interpreter.sendDialogues( + npc, + FacialExpression.FRIENDLY, + "Well done! Next we need to get some food in our", + "bellies. We'll need something to cook. There are shrimp", + "in the pond there, so let's catch and cook some." + ) + ) + + 5, 14, 15 -> { + if(!inInventory(player, Items.BRONZE_AXE_1351)) + { + player.dialogueInterpreter.sendItemMessage(Items.BRONZE_AXE_1351, "The Survival Expert gives you a spare bronze axe.") + addItem(player, Items.BRONZE_AXE_1351) + } + if(!inInventory(player, Items.TINDERBOX_590)) + { + player.dialogueInterpreter.sendItemMessage(Items.TINDERBOX_590, "The Survival Expert gives you a spare tinderbox.") + addItem(player, Items.TINDERBOX_590) + } + return false + } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(player?.getAttribute("tutorial:stage", 0)) + { + 4 -> when(stage) + { + 0 -> { + Component.setUnclosable( + player, + interpreter.sendDoubleItemMessage( + Items.TINDERBOX_590, + Items.BRONZE_AXE_1351, + "The Survival Guide gives you a tinderbox and a bronze axe!" + ) + ) + addItem(player, Items.TINDERBOX_590) + addItem(player, Items.BRONZE_AXE_1351) + stage++ + } + 1 -> { + end() + setAttribute(player, "tutorial:stage", 5) + TutorialStage.load(player, 5) + } + } + + 11 -> when(stage){ + 0 -> { + Component.setUnclosable( + player, + interpreter.sendItemMessage(303, "The Survival Guide gives you a net!") + ) + addItem(player, Items.SMALL_FISHING_NET_303) + stage++ + } + 1 -> { + end() + setAttribute(player, "tutorial:stage", 12) + TutorialStage.load(player, 12) + } + } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.SURVIVAL_EXPERT_943) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/tutisland/dialogue/TutorialCombatInstructorDialogue.kt b/Server/src/main/content/region/misc/tutisland/dialogue/TutorialCombatInstructorDialogue.kt new file mode 100644 index 0000000..4e73a79 --- /dev/null +++ b/Server/src/main/content/region/misc/tutisland/dialogue/TutorialCombatInstructorDialogue.kt @@ -0,0 +1,95 @@ +package content.region.misc.tutisland.dialogue + +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import content.region.misc.tutisland.handlers.TutorialStage + +/** + * Handles the combat instructor's dialogue + * @author Ceikry + */ +@Initializable +class TutorialCombatInstructorDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player?): DialoguePlugin { + return TutorialCombatInstructorDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + + when(getAttribute(player, "tutorial:stage", 0)) + { + 44 -> playerl(FacialExpression.FRIENDLY, "Hi! My name's ${player.username}.") + 47 -> npcl(FacialExpression.FRIENDLY, "Very good, but that little butter knife isn't going to protect you much. Here, take these.") + 53 -> playerl(FacialExpression.FRIENDLY, "I did it! I killed a giant rat!") + 54 -> { + player.dialogueInterpreter.sendDoubleItemMessage(Items.SHORTBOW_841, Items.BRONZE_ARROW_882, "The Combat Guide gives you some bronze arrows and a shortbow!") + if(!inInventory(player, Items.SHORTBOW_841) && !inEquipment(player, Items.SHORTBOW_841)) + addItem(player, Items.SHORTBOW_841) + if(!inInventory(player, Items.BRONZE_ARROW_882) && !inEquipment(player, Items.BRONZE_ARROW_882)) + addItem(player, Items.BRONZE_ARROW_882, 30) + } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(getAttribute(player, "tutorial:stage", 0)) + { + 44 -> when(stage){ + 0 -> npcl(FacialExpression.ANGRY, "Do I look like I care? To me you're just another newcomer who thinks they're ready to fight.").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "I'm Vannaka, the greatest swordsman alive.").also { stage++ } + 2 -> npcl(FacialExpression.FRIENDLY, "Let's get started by teaching you to wield a weapon.").also { stage++ } + 3 -> { + end() + setAttribute(player, "tutorial:stage", 45) + TutorialStage.load(player, 45) + } + } + + 47 -> when(stage){ + 0 -> { + addItemOrDrop(player, Items.BRONZE_SWORD_1277) + addItemOrDrop(player, Items.WOODEN_SHIELD_1171) + sendDoubleItemDialogue(player, Items.BRONZE_SWORD_1277, Items.WOODEN_SHIELD_1171, "The Combat Guide gives you a bronze sword and a wooden shield!") + stage++ + } + 1 -> { + end() + setAttribute(player, "tutorial:stage", 48) + TutorialStage.load(player, 48) + } + } + + 53 -> when(stage){ + 0 -> npcl(FacialExpression.FRIENDLY, "I saw, ${player.username}. You seem better at this than I thought. Now that you have grasped basic swordplay, let's move on.").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "Let's try some ranged attacking, with this you can kill foes from a distance. Also, foes unable to reach you are as good as dead. You'll be able to attack the rats, without entering the pit.").also { stage++ } + 2 -> { + sendDoubleItemDialogue(player, Items.SHORTBOW_841, Items.BRONZE_ARROW_882, "The Combat Guide gives you some bronze arrows and a shortbow!") + if(!inInventory(player, Items.SHORTBOW_841) && !inEquipment(player, Items.SHORTBOW_841)) + addItem(player, Items.SHORTBOW_841) + if(!inInventory(player, Items.BRONZE_ARROW_882) && !inEquipment(player, Items.BRONZE_ARROW_882)) + addItem(player, Items.BRONZE_ARROW_882, 30) + stage++ + } + 3 -> { + end() + setAttribute(player, "tutorial:stage", 54) + TutorialStage.load(player, 54) + } + } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.COMBAT_INSTRUCTOR_944) + } + +} diff --git a/Server/src/main/content/region/misc/tutisland/dialogue/TutorialFinanceAdvisorDialogue.kt b/Server/src/main/content/region/misc/tutisland/dialogue/TutorialFinanceAdvisorDialogue.kt new file mode 100644 index 0000000..305911a --- /dev/null +++ b/Server/src/main/content/region/misc/tutisland/dialogue/TutorialFinanceAdvisorDialogue.kt @@ -0,0 +1,58 @@ +package content.region.misc.tutisland.dialogue + +import core.api.getAttribute +import core.api.setAttribute +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs +import content.region.misc.tutisland.handlers.TutorialStage +import core.game.world.GameWorld.settings + +/** + * Handles the finance tutor's dialogue + * @author Ceikry + */ +@Initializable +class TutorialFinanceAdvisorDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin(player) { + override fun newInstance(player: Player?): core.game.dialogue.DialoguePlugin { + return TutorialFinanceAdvisorDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + when(getAttribute(player, "tutorial:stage", 0)) + { + 58 -> playerl(core.game.dialogue.FacialExpression.FRIENDLY, "Hello, who are you?") + 59 -> npcl(core.game.dialogue.FacialExpression.FRIENDLY, "Move along, now.").also { return false } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(getAttribute(player, "tutorial:stage", 0)){ + 58 -> when(stage++){ + 0 -> npcl(core.game.dialogue.FacialExpression.FRIENDLY, "I'm the Financial Advisor. I'm here to tell people how to make money.") + 1 -> playerl(core.game.dialogue.FacialExpression.FRIENDLY, "Okay. How can I make money then?") + 2 -> npcl(core.game.dialogue.FacialExpression.HALF_THINKING, "How you can make money? Quite.") + 3 -> npcl(core.game.dialogue.FacialExpression.FRIENDLY, "Well there are three basic ways of making money here: combat, quests, and trading. I will talk you through each of them very quickly.") + 4 -> npcl(core.game.dialogue.FacialExpression.FRIENDLY, "Let's start with combat as it is probably still fresh in your mind. Many enemies, both human and monster will drop items when they die.") + 5 -> npcl(core.game.dialogue.FacialExpression.FRIENDLY, "Now, the next way to earn money quickly is by quests. Many people on " + settings!!.name + " have things they need doing, which they will reward you for.") + 6 -> npcl(core.game.dialogue.FacialExpression.FRIENDLY, "By getting a high level in skills such as Cooking, Mining, Smithing or Fishing, you can create or catch your own items and sell them for pure profit.") + 7 -> npcl(core.game.dialogue.FacialExpression.FRIENDLY, "Lastly, we have jobs you can get from tutors in Lumbridge. These pay very handsomely early on!").also { stage++ } + 8 -> npcl(core.game.dialogue.FacialExpression.FRIENDLY, "Well, that about covers it. Move along now.") + 9 -> { + end() + setAttribute(player, "tutorial:stage", 59) + TutorialStage.load(player, 59) + } + } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.FINANCIAL_ADVISOR_947) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/tutisland/dialogue/TutorialMagicTutorDialogue.kt b/Server/src/main/content/region/misc/tutisland/dialogue/TutorialMagicTutorDialogue.kt new file mode 100644 index 0000000..a92d709 --- /dev/null +++ b/Server/src/main/content/region/misc/tutisland/dialogue/TutorialMagicTutorDialogue.kt @@ -0,0 +1,211 @@ +package content.region.misc.tutisland.dialogue + +import content.global.handlers.iface.RulesAndInfo +import content.region.misc.tutisland.handlers.* +import core.ServerConstants +import core.api.* +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.IronmanMode +import core.game.node.entity.player.link.TeleportManager +import core.game.node.item.Item +import core.game.world.GameWorld +import core.game.world.map.Location +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.worker.ManagementEvents +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import proto.management.JoinClanRequest + +/** + * Handles the magic tutor's dialogue + * @author Ceikry + */ +@Initializable +class TutorialMagicTutorDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin(player) { + private val STARTER_PACK = arrayOf( + Item(1351, 1), + Item(590, 1), + Item(303, 1), + Item(315, 1), + Item(1925, 1), + Item(1931, 1), + Item(2309, 1), + Item(1265, 1), + Item(1205, 1), + Item(1277, 1), + Item(1171, 1), + Item(841, 1), + Item(882, 25), + Item(556, 25), + Item(558, 15), + Item(555, 6), + Item(557, 4), + Item(559, 2) + ) + private val STARTER_BANK = arrayOf(Item(995, 25)) + + override fun newInstance(player: Player?): core.game.dialogue.DialoguePlugin { + return TutorialMagicTutorDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + when(getAttribute(player, "tutorial:stage", 0)) + { + 67 -> playerl(core.game.dialogue.FacialExpression.FRIENDLY, "Hello.") + 69 -> npcl(core.game.dialogue.FacialExpression.FRIENDLY, "Good. This is a list of your spells. Currently you can only cast one offensive spell called Wind Strike. Let's try it out on one of those chickens.") + 70 -> if(!inInventory(player, Items.AIR_RUNE_556) && !inInventory(player, Items.MIND_RUNE_558)) + { + player.dialogueInterpreter.sendDoubleItemMessage(Items.AIR_RUNE_556, Items.MIND_RUNE_558, "You receive some spare runes.") + addItem(player, Items.AIR_RUNE_556, 15) + addItem(player, Items.MIND_RUNE_558, 15) + return false + } + 71 -> npcl(core.game.dialogue.FacialExpression.FRIENDLY, "Alright, last thing. Are you interested in being an ironman or changing your experience rate?") + else -> return false + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(getAttribute(player, "tutorial:stage", 0)) + { + 67 -> when(stage++){ + 0 -> npcl(core.game.dialogue.FacialExpression.FRIENDLY, "Good day, newcomer. My name is Terrova. I'm here to tell you about Magic. Let's start by opening your spell list.") + 1 -> { + end() + setAttribute(player, "tutorial:stage", 68) + TutorialStage.load(player, 68) + } + } + 69 -> when(stage++){ + 0 -> { + sendDoubleItemDialogue(player, Items.AIR_RUNE_556, Items.MIND_RUNE_558, "Terrova gives you 15 air runes and 15 mind runes!") + addItemOrDrop(player, Items.AIR_RUNE_556, 5) + addItemOrDrop(player, Items.MIND_RUNE_558, 5) + } + 1 -> { + end() + setAttribute(player, "tutorial:stage", 70) + TutorialStage.load(player, 70) + } + } + 71 -> when(stage){ + 0 -> options("Set Ironman Mode (current: ${player.ironmanManager.mode.name})", "Change XP Rate (current: ${player.skills.experienceMultiplier}x)", "I'm ready now.").also { stage++ } + 1 -> when(buttonId){ + 1 -> options("None","Standard","Ultimate","Nevermind.").also { stage = 10 } + 2 -> options("1.0x","2.5x","5.0x").also { stage = 20 } + 3 -> npcl(core.game.dialogue.FacialExpression.FRIENDLY, "Well, you're all finished here now. I'll give you a reasonable number of starting items when you leave.").also { stage = 30 } + } + + 10 -> { + stage = 0 + if(buttonId < 5) + { + val mode = when (buttonId - 1) + { + 0 -> IronmanMode.NONE + 1 -> IronmanMode.STANDARD + 2 -> IronmanMode.ULTIMATE + else -> IronmanMode.NONE + } + if (mode != IronmanMode.NONE) stage = 11 + player.dialogueInterpreter.sendDialogue("You set your ironman mode to: ${mode.name}.") + player.ironmanManager.mode = mode + if (player.skills.experienceMultiplier == 10.0) player.skills.experienceMultiplier = 5.0 + } + else + { + handle(interfaceId, 0) + } + } + 11 -> player.dialogueInterpreter.sendPlainMessage(false, *splitLines("WARNING: You have selected an ironman mode. This is an uncompromising mode that WILL completely restrict your ability to trade. This MAY leave you unable to complete certain content, including quests.")).also { stage = 0 } + + 20 -> { + val rates = arrayOf(1.0,2.5,5.0) + val rate = rates[buttonId - 1] + if(rate == 10.0) { + player.dialogueInterpreter.sendDialogue("10.0x is no longer available!") + player.skills.experienceMultiplier = 5.0 + stage = 0 + return true + } + player.dialogueInterpreter.sendDialogue("You set your XP rate to: ${rate}x.") + player.skills.experienceMultiplier = rate + stage = 0 + } + + 30 -> player.dialogueInterpreter.sendOptions("Leave Tutorial Island?", "Yes, I'm ready.", "No, not yet.").also { stage++ } + 31 -> when(buttonId) + { + 1 -> playerl(core.game.dialogue.FacialExpression.FRIENDLY, "I'm ready to go now, thank you.").also { stage = 40 } + 2 -> playerl(core.game.dialogue.FacialExpression.FRIENDLY, "I'm not quite ready to go yet, thank you.").also { stage = END_DIALOGUE } + } + + 40 -> { + setAttribute(player, "/save:tutorial:complete", true) + setVarbit(player, 3756, 0) + setVarp(player, 281, 1000, true) + teleport(player, Location.create(3233, 3230), TeleportManager.TeleportType.NORMAL) + closeOverlay(player) + + player.inventory.clear() + player.bank.clear() + player.equipment.clear() + player.interfaceManager.restoreTabs() + player.interfaceManager.setViewedTab(3) + player.inventory.add(*STARTER_PACK) + player.bank.add(*STARTER_BANK) + + if(player.skills.experienceMultiplier == 10.0) + { + player.skills.experienceMultiplier = 5.0 + } + + //This overwrites the stuck dialogue after teleporting to Lumbridge for some reason + //Dialogue from 2007 or thereabouts + //Original is five lines, but if the same is done here it will break. Need to find another way of showing all this information. + interpreter.sendDialogue( + "Welcome to Lumbridge! To get more help, simply click on the", + "Lumbridge Guide or one of the Tutors - these can be found by looking", + "for the question mark icon on your mini-map. If you find you are lost", + "at any time, look for a signpost or use the Lumbridge Home Port Spell." + ) + stage = 12 + TutorialStage.removeHintIcon(player) + + player.unhook(TutorialKillReceiver) + player.unhook(TutorialFireReceiver) + player.unhook(TutorialResourceReceiver) + player.unhook(TutorialUseWithReceiver) + player.unhook(TutorialInteractionReceiver) + player.unhook(TutorialButtonReceiver) + RulesAndInfo.openFor(player) + + if (GameWorld.settings!!.enable_default_clan) { + player.communication.currentClan = ServerConstants.SERVER_NAME.toLowerCase() + + val clanJoin = JoinClanRequest.newBuilder() + clanJoin.clanName = ServerConstants.SERVER_NAME.toLowerCase() + clanJoin.username = player.name + + ManagementEvents.publish(clanJoin.build()) + } + } + + 12 -> { + player.setAttribute("close_c_", true) + end() + } + } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.MAGIC_INSTRUCTOR_946) + } + +} diff --git a/Server/src/main/content/region/misc/tutisland/dialogue/TutorialMasterChefDialogue.kt b/Server/src/main/content/region/misc/tutisland/dialogue/TutorialMasterChefDialogue.kt new file mode 100644 index 0000000..2db6994 --- /dev/null +++ b/Server/src/main/content/region/misc/tutisland/dialogue/TutorialMasterChefDialogue.kt @@ -0,0 +1,123 @@ +package content.region.misc.tutisland.dialogue + +import core.api.* +import core.game.component.Component +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import content.region.misc.tutisland.handlers.TutorialStage + +/** + * Handles the cooking tutor's dialogue + * @author Ceikry + */ +@Initializable +class TutorialMasterChefDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player?): DialoguePlugin { + return TutorialMasterChefDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + when(getAttribute(player, "tutorial:stage", 0)) + { + 18 -> Component.setUnclosable( + player, + interpreter.sendDialogues( + npc, + FacialExpression.FRIENDLY, + "Ah! Welcome, newcomer. I am the Master Chef, Lev. It", + "is here I will teach you how to cook food truly fit for a", + "king." + ) + ) + + 19,20 -> { + if(!inInventory(player, Items.BREAD_DOUGH_2307)) + { + if(!inInventory(player, Items.BUCKET_OF_WATER_1929)) + { + sendItemDialogue(player, Items.BUCKET_OF_WATER_1929, "The Master Chef gives you another bucket of water.") + addItem(player, Items.BUCKET_OF_WATER_1929) + TutorialStage.load(player, 19) + return false + } + if(!inInventory(player, Items.POT_OF_FLOUR_1933)) + { + sendItemDialogue(player, Items.POT_OF_FLOUR_1933, "The Master Chef gives you another pot of flour.") + addItem(player, Items.POT_OF_FLOUR_1933) + TutorialStage.load(player, 19) + return false + } + } + return false + } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(getAttribute(player, "tutorial:stage", 0)) + { + 18 -> when(stage) + { + 0 -> Component.setUnclosable( + player, + interpreter.sendDialogues( + player, + FacialExpression.HALF_GUILTY, + "I already know how to cook. Brynna taught me just", + "now." + ) + ).also { stage++ } + 1 -> Component.setUnclosable( + player, + interpreter.sendDialogues( + npc, + FacialExpression.LAUGH, + "Hahahahahaha! You call THAT cooking? Some shrimp", + "on an open log fire? Oh, no, no no. I am going to", + "teach you the fine art of cooking bread." + ) + ).also { stage++ } + 2 -> Component.setUnclosable( + player, + interpreter.sendDialogues( + npc, + FacialExpression.FRIENDLY, + "And no fine meal is complete without good music, so", + "we'll cover that while you're here too." + ) + ).also { stage++ } + 3 -> { + Component.setUnclosable( + player, + interpreter.sendDoubleItemMessage( + Items.BUCKET_OF_WATER_1929, + Items.POT_OF_FLOUR_1933, + "The Cooking Guide gives you a bucket of water and a pot of flour." + ) + ) + addItem(player, Items.BUCKET_OF_WATER_1929) + addItem(player, Items.POT_OF_FLOUR_1933) + stage++ + } + 4 -> { + end() + setAttribute(player, "tutorial:stage", 19) + TutorialStage.load(player, 19) + } + } + } + + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.MASTER_CHEF_942) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/tutisland/dialogue/TutorialMiningInstructorDialogue.kt b/Server/src/main/content/region/misc/tutisland/dialogue/TutorialMiningInstructorDialogue.kt new file mode 100644 index 0000000..ad9f6c7 --- /dev/null +++ b/Server/src/main/content/region/misc/tutisland/dialogue/TutorialMiningInstructorDialogue.kt @@ -0,0 +1,107 @@ +package content.region.misc.tutisland.dialogue + +import core.api.addItem +import core.api.getAttribute +import core.api.inInventory +import core.api.setAttribute +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import content.region.misc.tutisland.handlers.TutorialStage + +/** + * Handles the mining tutor's dialogue + * @author Ceikry + */ +@Initializable +class TutorialMiningInstructorDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player?): DialoguePlugin { + return TutorialMiningInstructorDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + when(getAttribute(player, "tutorial:stage", 0)) { + 30 -> npcl(FacialExpression.FRIENDLY, "Hi there. You must be new around here. So what do I call you? 'Newcomer' seems so impersonal, and if we're going to be working together, I'd rather tell you by name.") + 34 -> playerl(FacialExpression.FRIENDLY, "I prospected both types of rock! One set contains tin and the other has copper ore inside.") + 35 -> { + if(!inInventory(player, Items.BRONZE_PICKAXE_1265)) { + addItem(player, Items.BRONZE_PICKAXE_1265) + player.dialogueInterpreter.sendItemMessage(Items.BRONZE_PICKAXE_1265, "Dezzick gives you a bronze pickaxe!") + stage = 3 + } + else { + TutorialStage.load(player, 35) + } + } + 40 -> playerl(FacialExpression.ASKING, "How do I make a weapon out of this?") + 41 -> { + if(!inInventory(player, Items.HAMMER_2347)) { + addItem(player, Items.HAMMER_2347) + player.dialogueInterpreter.sendItemMessage(Items.HAMMER_2347, "Dezzick gives you a hammer!") + stage = 3 + } + else + { + end() + TutorialStage.load(player, 41) + } + } + } + + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(getAttribute(player, "tutorial:stage", 0)) { + 30 -> when(stage) { + 0 -> playerl(FacialExpression.FRIENDLY, "You can call me ${player.username}.").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "Ok then, ${player.username}. My name is Dezzick and I'm a miner by trade. Let's prospect some of these rocks.").also { stage++ } + 2 -> { + end() + setAttribute(player, "tutorial:stage", 31) + TutorialStage.load(player, 31) + } + } + + 34,35 -> when(stage) { + 0 -> npcl(FacialExpression.FRIENDLY, "Absolutely right, ${player.username}. These two ore types can be smelted together to make bronze.").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "So now you know what ore is in the rocks over there, why don't you have a go at mining some tin and copper? Here, you'll need this to start with.").also { stage++ } + 2 -> { + addItem(player, Items.BRONZE_PICKAXE_1265) + player.dialogueInterpreter.sendItemMessage(Items.BRONZE_PICKAXE_1265, "Dezzick gives you a bronze pickaxe!") + stage++ + } + 3 -> { + end() + setAttribute(player, "tutorial:stage", 35) + TutorialStage.load(player, 35) + } + } + + 40,41 -> when(stage){ + 0 -> npcl(FacialExpression.FRIENDLY, "Okay, I'll show you how to make a dagger out of it. You'll be needing this..").also { stage++ } + 1 -> { + addItem(player, Items.HAMMER_2347) + player.dialogueInterpreter.sendItemMessage(Items.HAMMER_2347, "Drezzick gives you a hammer!") + stage++ + } + 2 -> { + end() + setAttribute(player, "tutorial:stage", 41) + TutorialStage.load(player, 41) + } + } + } + + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.MINING_INSTRUCTOR_948) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/tutisland/dialogue/TutorialPrayerDialogue.kt b/Server/src/main/content/region/misc/tutisland/dialogue/TutorialPrayerDialogue.kt new file mode 100644 index 0000000..5278dc6 --- /dev/null +++ b/Server/src/main/content/region/misc/tutisland/dialogue/TutorialPrayerDialogue.kt @@ -0,0 +1,69 @@ +package content.region.misc.tutisland.dialogue + +import core.api.getAttribute +import core.api.setAttribute +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs +import content.region.misc.tutisland.handlers.TutorialStage + +/** + * Handles the prayer guide's dialogue + * @author Ceikry + */ +@Initializable +class TutorialPrayerDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player?): DialoguePlugin { + return TutorialPrayerDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + when(getAttribute(player, "tutorial:stage", 0)) + { + 60 -> npcl(FacialExpression.FRIENDLY, "Greetings! I'd just like to briefly go over two topics with you: Prayer, and Friend's.") + 62 -> npcl(FacialExpression.FRIENDLY, "Prayers have all sorts of wonderful benefits! From boosting defence and damage, to protecting you from outside damage, to saving items on death!") + 65 -> npcl(FacialExpression.FRIENDLY, "For your friend and ignore lists, it's quite simple really! Use your friend list to keep track of players who you like, and ignore those you don't!") + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(getAttribute(player, "tutorial:stage", 0)) + { + 60 -> when(stage++){ + 0 -> playerl(FacialExpression.FRIENDLY, "Alright, sounds fun!") + 1 -> npcl(FacialExpression.FRIENDLY, "Right, so first thing: Prayer. Prayer is trained by offering bones to the gods, and can grant you many boons!") + 2 -> { + end() + setAttribute(player, "tutorial:stage", 61) + TutorialStage.load(player, 61) + } + } + + 62 -> when(stage++){ + 0 -> playerl(FacialExpression.AMAZED, "Very cool!") + 1 -> npcl(FacialExpression.FRIENDLY, "Next up, let's talk about friends.") + 2 -> { + end() + setAttribute(player, "tutorial:stage", 63) + TutorialStage.load(player, 63) + } + } + + 65 -> { + end() + setAttribute(player, "tutorial:stage", 66) + TutorialStage.load(player, 66) + } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.BROTHER_BRACE_954) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/tutisland/dialogue/TutorialQuestGuideDialogue.kt b/Server/src/main/content/region/misc/tutisland/dialogue/TutorialQuestGuideDialogue.kt new file mode 100644 index 0000000..0159288 --- /dev/null +++ b/Server/src/main/content/region/misc/tutisland/dialogue/TutorialQuestGuideDialogue.kt @@ -0,0 +1,122 @@ +package content.region.misc.tutisland.dialogue + +import core.api.getAttribute +import core.api.setAttribute +import core.api.setVarbit +import core.game.component.Component +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Components +import org.rs09.consts.NPCs +import content.region.misc.tutisland.handlers.TutorialStage + +/** + * Handles the quest guide's dialogue + * @author Ceikry + */ +@Initializable +class TutorialQuestGuideDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player?): DialoguePlugin { + return TutorialQuestGuideDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + when(getAttribute(player, "tutorial:stage", 0)) + { + 27 -> Component.setUnclosable( + player, + interpreter.sendDialogues( + npc, + FacialExpression.FRIENDLY, + "Ah. Welcome, adventurer. I'm here to tell you all about", + "quests. Lets start by opening the Quest List." + ) + ) + + 28 -> Component.setUnclosable( + player, + interpreter.sendDialogues( + npc, + FacialExpression.FRIENDLY, + "Now you have the journal open. I'll tell you a bit about", + "it At the moment all the quests are shown in red, which", + "means you have not started them yet." + ) + ) + + else -> return false + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(getAttribute(player, "tutorial:stage", 0)) + { + 27 -> { + Component.setUnclosable( + player, + interpreter.sendPlaneMessageWithBlueTitle( + "Open the Quest Journal.", + "", + "Click on the flashing icon next to your inventory.", + "", + "" + ) + ) + setVarbit(player, 3756, 3) + player.interfaceManager.openTab(Component(Components.QUESTJOURNAL_V2_274)) + } + 28 -> when(stage) + { + 0 -> Component.setUnclosable( + player, + interpreter.sendDialogues( + npc, + FacialExpression.FRIENDLY, + "When you start a quest it will change colour to yellow,", + "and to green when you've finished. This is so you can", + "easily see what's complete, what's started and what's left", + "to begin." + ) + ).also { stage++ } + 1 -> Component.setUnclosable( + player, + interpreter.sendDialogues( + npc, + FacialExpression.FRIENDLY, + "The start of quests are easy to find. Look out for the", + "star icons on the minimap, just like the one you should", + "see marking my house." + ) + ).also { stage++ } + 2 -> Component.setUnclosable( + player, + interpreter.sendDialogues( + npc, + FacialExpression.FRIENDLY, + "There's not a lot more I can tell you about questing.", + "You have to experience the thrill of it yourself to fully", + "understand. You may find some adventure in the caves", + "under my house." + ) + ).also { stage++ } + 3 -> { + end() + setAttribute(player, "tutorial:stage", 29) + TutorialStage.load(player, 29) + } + } + } + + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.QUEST_GUIDE_949) + } + +} diff --git a/Server/src/main/content/region/misc/tutisland/dialogue/TutorialRSGuideDialogue.kt b/Server/src/main/content/region/misc/tutisland/dialogue/TutorialRSGuideDialogue.kt new file mode 100644 index 0000000..4d76536 --- /dev/null +++ b/Server/src/main/content/region/misc/tutisland/dialogue/TutorialRSGuideDialogue.kt @@ -0,0 +1,140 @@ +package content.region.misc.tutisland.dialogue + +import core.api.setAttribute +import core.game.component.Component +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs +import content.region.misc.tutisland.handlers.TutorialStage + +/** + * Handles the RuneSccape guide's dialogue + * @author Ceikry + */ +@Initializable +class TutorialRSGuideDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player?): DialoguePlugin { + return TutorialRSGuideDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + val tutStage = player?.getAttribute("tutorial:stage", 0) ?: 0 + if(tutStage < 2) { + end() + player.dialogueInterpreter.sendDialogues(npc,FacialExpression.HALF_GUILTY,"Greetings! Please follow the onscreen, instructions!") + return false + } else { + Component.setUnclosable( + player, + interpreter.sendDialogues( + npc, + FacialExpression.HALF_GUILTY, + "Greetings! Please follow the onscreen", + "instructions!" + ) + ) + } + + if(tutStage == 2) + { + player.lock() + Component.setUnclosable( + player, + interpreter.sendDialogues( + npc, + FacialExpression.HALF_GUILTY, + "Greetings! I see you are a new arrival to this land. My", + "job is to welcome all new visitors. So welcome!" + ) + ) + stage = 0 + return true + } + else + { + Component.setUnclosable( + player, + interpreter.sendDialogues( + npc, + FacialExpression.HALF_GUILTY, + "Please follow the onscreen instructions!" + ) + ) + return false + } + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage) + { + 0 -> Component.setUnclosable( + player, + interpreter.sendDialogues( + npc, + FacialExpression.FRIENDLY, + "You have already learned the first thing needed to", + "succeed in this world: talking to other people!" + ) + ).also { stage++ } + + 1 -> Component.setUnclosable( + player, + interpreter.sendDialogues( + npc, + FacialExpression.FRIENDLY, + "You will find many inhabitants of this world have useful", + "things to say to you. By clicking on them with your", + "mouse you can talk to them." + ) + ).also { stage++ } + + 2 -> Component.setUnclosable( + player, + interpreter.sendDialogues( + npc, + FacialExpression.FRIENDLY, + "I would also suggest reading through some of the", + "supporting information on the website. There you can", + "find the starter guides, which contain all the", + "additional information you're ever likely to need. they also" + ) + ).also { stage++ } + + 3 -> Component.setUnclosable( + player, + interpreter.sendDialogues( + npc, + FacialExpression.FRIENDLY, + "contain helpful tips to help you on your", + "journey." + ) + ).also { stage++ } + + 4 -> Component.setUnclosable( + player, + interpreter.sendDialogues( + npc, + FacialExpression.FRIENDLY, + "To continue the tutorial go through that door over", + "there and speak to your first instructor!" + ) + ).also { stage++ } + + 5 -> { + end() + player.unlock() + setAttribute(player, "tutorial:stage", 3) + TutorialStage.load(player, 3) + } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.RUNESCAPE_GUIDE_945) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/tutisland/handlers/RatTutorialNPC.java b/Server/src/main/content/region/misc/tutisland/handlers/RatTutorialNPC.java new file mode 100644 index 0000000..56845ac --- /dev/null +++ b/Server/src/main/content/region/misc/tutisland/handlers/RatTutorialNPC.java @@ -0,0 +1,80 @@ +package content.region.misc.tutisland.handlers; + +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.Entity; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.world.map.Location; +import content.data.Quests; + +/** + * Handles the tutorial rat npc. + * @author 'Vexia + */ +@Initializable +public class RatTutorialNPC extends AbstractNPC { + + /** + * The NPC ids of NPCs using this plugin. + */ + private static final int[] ID = { 86 }; + + /** + * Constructs a new {@code AlKharidWarriorPlugin} {@code Object}. + */ + public RatTutorialNPC() { + super(0, null); + this.setAggressive(false); + } + + /** + * Constructs a new {@code AlKharidWarriorPlugin} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + private RatTutorialNPC(int id, Location location) { + super(id, location, true); + } + + @Override + public void init() { + super.init(); + setAggressive(false); + getSkills().setLevel(Skills.HITPOINTS, 5); + getSkills().setStaticLevel(Skills.HITPOINTS, 5); + getSkills().setLifepoints(5); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new RatTutorialNPC(id, location); + } + + @Override + public void tick() { + super.tick(); + } + + @Override + public void finalizeDeath(final Entity killer) { + super.finalizeDeath(killer); + if (!(killer instanceof Player)) { + return; + } + final Player p = ((Player) killer); + if (killer instanceof Player) { + if (p.getQuestRepository().getQuest(Quests.WITCHS_POTION).isStarted(p)) { + GroundItemManager.create(new Item(300), getLocation(), p); + } + } + } + + @Override + public int[] getIds() { + return ID; + } + +} diff --git a/Server/src/main/content/region/misc/tutisland/handlers/SkippyNPC.java b/Server/src/main/content/region/misc/tutisland/handlers/SkippyNPC.java new file mode 100644 index 0000000..828e260 --- /dev/null +++ b/Server/src/main/content/region/misc/tutisland/handlers/SkippyNPC.java @@ -0,0 +1,48 @@ +package content.region.misc.tutisland.handlers; + +import core.game.node.entity.npc.AbstractNPC; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.tools.RandomFunction; + +/** + * Handles the NPC skippy. + * @author Vexia + */ +@Initializable +public class SkippyNPC extends AbstractNPC { + + /** + * Constructs a new {@code SkippyNPC} {@code Object} + * @param id the id. + * @param location the location. + */ + public SkippyNPC(int id, Location location) { + super(id, location); + } + + /** + * Constructs a new {@code SkippyNPC} {@code Object} + */ + public SkippyNPC() { + this(2796, null); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new SkippyNPC(id, location); + } + + @Override + public void tick() { + if (RandomFunction.random(100) < 15) { + sendChat("You can skip the tutorial by talking to me!"); + } + } + + @Override + public int[] getIds() { + return new int[] { 2796 }; + } + +} diff --git a/Server/src/main/content/region/misc/tutisland/handlers/TutorialArea.kt b/Server/src/main/content/region/misc/tutisland/handlers/TutorialArea.kt new file mode 100644 index 0000000..082da76 --- /dev/null +++ b/Server/src/main/content/region/misc/tutisland/handlers/TutorialArea.kt @@ -0,0 +1,10 @@ +package content.region.misc.tutisland.handlers + +import core.api.* +import core.game.world.map.zone.ZoneBorders +import core.game.world.map.zone.ZoneRestriction + +class TutorialArea : MapArea { + override fun defineAreaBorders() : Array { return arrayOf(12079, 12080, 12335, 12336, 12436, 12592).map { ZoneBorders.forRegion(it) }.toTypedArray() } + override fun getRestrictions() : Array { return arrayOf(ZoneRestriction.RANDOM_EVENTS) } +} diff --git a/Server/src/main/content/region/misc/tutisland/handlers/TutorialEventReceivers.kt b/Server/src/main/content/region/misc/tutisland/handlers/TutorialEventReceivers.kt new file mode 100644 index 0000000..655c16d --- /dev/null +++ b/Server/src/main/content/region/misc/tutisland/handlers/TutorialEventReceivers.kt @@ -0,0 +1,326 @@ +package content.region.misc.tutisland.handlers + +import core.api.getAttribute +import core.api.setAttribute +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import content.global.skill.fishing.FishingSpot +import content.global.skill.gather.mining.MiningNode +import content.global.skill.gather.woodcutting.WoodcuttingNode +import core.game.event.* +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +/** + * Event receivers for tutorial island + * @author Ceikry + */ +object TutorialButtonReceiver : EventHook +{ + override fun process(entity: Entity, event: ButtonClickEvent) { + if(entity !is Player) return + + when(getAttribute(entity, "tutorial:stage", 0)) + { + //character design interface, confirm button + 0 -> if(event.iface == 771 && event.buttonId == 362) { + setAttribute(entity, "/save:tutorial:stage", 1) + TutorialStage.load(entity, 1) + } + + //click settings tab SD: 548,24 HD: 746,52 + 1 -> if((event.iface == 548 && event.buttonId == 24) || (event.iface == 746 && event.buttonId == 52)) { + setAttribute(entity, "/save:tutorial:stage", 2) + TutorialStage.load(entity, 2) + } + + //click inventory tab SD: 548,41 HD: 746,44 + 5 -> if((event.iface == 548 && event.buttonId == 41) || (event.iface == 746 && event.buttonId == 44)) { + setAttribute(entity, "tutorial:stage", 6) + TutorialStage.load(entity, 6) + } + + //Click skills tab SD: 548,39 HD: 746,42 + 10 -> if((event.iface == 548 && event.buttonId == 39) || (event.iface == 746 && event.buttonId == 42)) { + setAttribute(entity, "tutorial:stage", 11) + TutorialStage.load(entity, 11) + } + + //Click music tab SD: 548,26 HD: 746,54 + 21 -> if((event.iface == 548 && event.buttonId == 26) || (event.iface == 746 && event.buttonId == 54)) { + setAttribute(entity, "tutorial:stage", 22) + TutorialStage.load(entity, 22) + } + + //Click emote tab SD: 548,25 HD: 746,53 + 23 -> if((event.iface == 548 && event.buttonId == 25) || (event.iface == 746 && event.buttonId == 53)){ + setAttribute(entity, "tutorial:stage", 24) + TutorialStage.load(entity, 24) + } + + //Click any emote + 24 -> if(event.iface == 464){ + setAttribute(entity, "tutorial:stage", 25) + TutorialStage.load(entity, 25) + } + + //click run button + 25 -> if(event.iface == 261 && event.buttonId == 3 || event.iface == 750 && event.buttonId == 1){ + setAttribute(entity, "tutorial:stage", 26) + TutorialStage.load(entity, 26) + } + + //Open quest journal tab SD:548,40 HD:746,43 + 27 -> if((event.iface == 548 && event.buttonId == 40) || (event.iface == 746 && event.buttonId == 43)){ + setAttribute(entity, "tutorial:stage", 28) + TutorialStage.load(entity, 28) + } + + //Open equipment tab SD:548,42 HD:746,45 + 45 -> if((event.iface == 548 && event.buttonId == 42) || (event.iface == 746 && event.buttonId == 45)){ + setAttribute(entity, "tutorial:stage", 46) + TutorialStage.load(entity, 46) + } + + //Open weapon interface SD:548,38 HD:746,41 + 49 -> if((event.iface == 548 && event.buttonId == 38) || (event.iface == 746 && event.buttonId == 41)) { + setAttribute(entity, "tutorial:stage", 50) + TutorialStage.load(entity, 50) + } + + //Open prayer interface SD:548,43 HD:746,46 + 61 -> if((event.iface == 548 && event.buttonId == 43) || (event.iface == 746 && event.buttonId == 46)){ + setAttribute(entity, "tutorial:stage", 62) + TutorialStage.load(entity, 62) + } + + //Open friends tab SD:548,21 HD:746,49 + 63 -> if((event.iface == 548 && event.buttonId == 21) || (event.iface == 746 && event.buttonId == 49)){ + setAttribute(entity, "tutorial:stage", 64) + TutorialStage.load(entity, 64) + } + + //Open ignore list tab SD:548,22 HD:746,50 + 64 -> if((event.iface == 548 && event.buttonId == 22) || (event.iface == 746 && event.buttonId == 50)){ + setAttribute(entity, "tutorial:stage", 65) + TutorialStage.load(entity, 65) + } + + //Open magic tab SD:548,44 HD:746,47 + 68 -> if((event.iface == 548 && event.buttonId == 44) || (event.iface == 746 && event.buttonId == 47)){ + setAttribute(entity, "tutorial:stage", 69) + TutorialStage.load(entity, 69) + } + } + } +} + +object TutorialInteractionReceiver : EventHook +{ + override fun process(entity: Entity, event: InteractionEvent) { + if(entity !is Player) return + + when(getAttribute(entity, "tutorial:stage", 0)) + { + //Click on tree and start chopping + 6 -> if((WoodcuttingNode.forId(event.target.id)?.identifier ?: -1) == 1.toByte()) + { + setAttribute(entity, "tutorial:stage", 7) + TutorialStage.load(entity, 7) + } + + //Click on fishing spot to start fishing + 12 -> if(FishingSpot.forId(event.target.id) != null) + { + setAttribute(entity, "tutorial:stage", 13) + TutorialStage.load(entity, 13) + } + + //Prospect rock - Tin + 31 -> if(MiningNode.forId(event.target.id)?.identifier?.equals(2.toByte()) == true && event.option == "prospect"){ + setAttribute(entity, "tutorial:stage", 32) + TutorialStage.load(entity, 32) + } + + //Prospect rock- Copper + 33 -> if(MiningNode.forId(event.target.id)?.identifier?.equals(1.toByte()) == true && event.option == "prospect"){ + setAttribute(entity, "tutorial:stage", 34) + TutorialStage.load(entity, 34) + } + + //Mine rock - Tin + 35 -> if(MiningNode.forId(event.target.id)?.identifier?.equals(2.toByte()) == true && event.option == "mine"){ + setAttribute(entity, "tutorial:stage", 36) + TutorialStage.load(entity, 36) + } + + //Equip bronze dagger + 46 -> if(event.target.id == Items.BRONZE_DAGGER_1205 && event.option == "equip"){ + setAttribute(entity, "tutorial:stage", 47) + TutorialStage.load(entity, 47) + } + + //Equip sword and shield + 48 -> { + if(event.target.id == Items.BRONZE_SWORD_1277 && event.option == "equip"){ + setAttribute(entity, "/save:tutorial:sword", true) + } + else if(event.target.id == Items.WOODEN_SHIELD_1171 && event.option == "equip"){ + setAttribute(entity, "/save:tutorial:shield", true) + } + if(getAttribute(entity, "tutorial:shield",false) && getAttribute(entity, "tutorial:sword",false)) + { + setAttribute(entity, "tutorial:stage", 49) + TutorialStage.load(entity, 49) + } + } + + //Attack rat + 51 -> if(event.target.id == NPCs.GIANT_RAT_86 && event.option == "attack") { + setAttribute(entity, "tutorial:stage", 52) + TutorialStage.load(entity, 52) + } + + //Open bank + 56 -> if(event.target.name.contains("booth", true) && event.option == "use"){ + setAttribute(entity, "tutorial:stage", 57) + TutorialStage.load(entity, 57) + } + } + } +} + +object TutorialResourceReceiver : EventHook +{ + override fun process(entity: Entity, event: ResourceProducedEvent) { + if(entity !is Player) return + + when(getAttribute(entity, "tutorial:stage", 0)) + { + //Gather some logs + 7 -> if(event.itemId == Items.LOGS_1511) + { + setAttribute(entity, "tutorial:stage", 8) + TutorialStage.load(entity, 8) + } + + //Catch some raw shrimp + 13 -> if(event.itemId == Items.RAW_SHRIMPS_317) + { + setAttribute(entity, "tutorial:stage", 14) + TutorialStage.load(entity, 14) + } + + //Cook a shrimp + 14,15 -> if(event.itemId == Items.BURNT_SHRIMP_7954) + { + setAttribute(entity, "tutorial:stage", 15) + TutorialStage.load(entity, 15) + } + else if(event.itemId == Items.SHRIMPS_315) + { + setAttribute(entity, "tutorial:stage", 16) + TutorialStage.load(entity, 16) + } + + //Make some bread dough + 19 -> if(event.itemId == Items.BREAD_DOUGH_2307) { + setAttribute(entity, "tutorial:stage", 20) + TutorialStage.load(entity, 20) + } + + //Bake some bread + 20 -> if(event.itemId == Items.BREAD_2309 || event.itemId == Items.BURNT_BREAD_2311) { + setAttribute(entity, "tutorial:stage", 21) + TutorialStage.load(entity, 21) + } + + //Mine some tin ore + 36 -> if(event.itemId == Items.TIN_ORE_438){ + setAttribute(entity, "tutorial:stage", 37) + TutorialStage.load(entity, 37) + } + + //Mine some copper ore + 37 -> if(event.itemId == Items.COPPER_ORE_436){ + setAttribute(entity, "tutorial:stage", 38) + TutorialStage.load(entity, 38) + } + + //Make a bronze bar + 38 -> if(event.itemId == Items.BRONZE_BAR_2349){ + setAttribute(entity, "tutorial:stage", 40) + TutorialStage.load(entity, 40) + } + + //Make a bronze dagger + 42 -> if(event.itemId == Items.BRONZE_DAGGER_1205){ + setAttribute(entity, "tutorial:stage", 43) + TutorialStage.load(entity, 43) + } + } + } +} + +object TutorialFireReceiver : EventHook +{ + override fun process(entity: Entity, event: LitFireEvent) { + if(entity !is Player) return + + when(getAttribute(entity, "tutorial:stage", 0)) + { + 9 -> { + setAttribute(entity, "tutorial:stage", 10) + TutorialStage.load(entity, 10) + } + } + } +} + +object TutorialUseWithReceiver : EventHook +{ + override fun process(entity: Entity, event: UseWithEvent) { + if(entity !is Player) return + + + when(getAttribute(entity, "tutorial:stage", 0)) + { + //Start lighting a fire + 8 -> if(event.used == Items.TINDERBOX_590 && event.with == Items.LOGS_1511) { + setAttribute(entity, "tutorial:stage", 9) + TutorialStage.load(entity, 9) + } + + //Use bar on anvil + 41 -> if(event.used == Items.BRONZE_BAR_2349 && event.with == 2783) { + setAttribute(entity, "tutorial:stage", 42) + TutorialStage.load(entity, 42) + } + } + } +} + +object TutorialKillReceiver : EventHook +{ + override fun process(entity: Entity, event: NPCKillEvent) { + if(entity !is Player) return + + when(getAttribute(entity, "tutorial:stage", 0)) + { + 52 -> if(event.npc.id == NPCs.GIANT_RAT_86){ + setAttribute(entity, "tutorial:stage", 53) + TutorialStage.load(entity, 53) + } + + 54 -> if(event.npc.id == NPCs.GIANT_RAT_86){ + setAttribute(entity, "tutorial:stage", 55) + TutorialStage.load(entity, 55) + } + + 70 -> if(event.npc.id == NPCs.CHICKEN_41){ + setAttribute(entity, "tutorial:stage", 71) + TutorialStage.load(entity, 71) + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/tutisland/handlers/TutorialFurnaceListener.kt b/Server/src/main/content/region/misc/tutisland/handlers/TutorialFurnaceListener.kt new file mode 100644 index 0000000..c4139d6 --- /dev/null +++ b/Server/src/main/content/region/misc/tutisland/handlers/TutorialFurnaceListener.kt @@ -0,0 +1,50 @@ +package content.region.misc.tutisland.handlers + +import core.api.* +import core.game.event.ResourceProducedEvent +import core.game.node.entity.skill.Skills +import content.global.skill.smithing.smelting.Bar +import core.game.system.task.Pulse +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items +import org.rs09.consts.Scenery +import core.game.interaction.IntType +import core.game.interaction.InteractionListener + +/** + * Listener for tutorial island furnace + * @author Byte + */ +class TutorialFurnaceListener : InteractionListener { + + companion object { + private val ANIMATION = Animation(833) + + private val ORES = intArrayOf( + Items.TIN_ORE_438, + Items.COPPER_ORE_436 + ) + } + + override fun defineListeners() { + onUseWith(IntType.SCENERY, ORES, Scenery.FURNACE_3044) { player, _, _ -> + if (!inInventory(player, Items.TIN_ORE_438) || !inInventory(player, Items.COPPER_ORE_436)) { + return@onUseWith true + } + + animate(player, ANIMATION) + submitIndividualPulse(player, object: Pulse(2) { + override fun pulse(): Boolean { + removeItem(player, Items.TIN_ORE_438) + removeItem(player, Items.COPPER_ORE_436) + addItem(player, Items.BRONZE_BAR_2349) + rewardXP(player, Skills.SMITHING, Bar.BRONZE.experience) + player.dispatch(ResourceProducedEvent(Items.BRONZE_BAR_2349, 1, player, Items.COPPER_ORE_436)) + return true + } + }) + + return@onUseWith true + } + } +} diff --git a/Server/src/main/content/region/misc/tutisland/handlers/TutorialListeners.kt b/Server/src/main/content/region/misc/tutisland/handlers/TutorialListeners.kt new file mode 100644 index 0000000..c7dd26f --- /dev/null +++ b/Server/src/main/content/region/misc/tutisland/handlers/TutorialListeners.kt @@ -0,0 +1,169 @@ +package content.region.misc.tutisland.handlers + +import core.api.* +import core.game.node.scenery.Scenery +import core.game.system.task.Pulse +import core.game.world.map.Location +import org.rs09.consts.NPCs +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.game.world.repository.Repository + +/** + * Handles tutorial-specific node interactions + * @author Ceikry + */ +class TutorialListeners : InteractionListener { + val GUIDE_HOUSE_DOOR = 3014 + val COOKS_DOOR = 3017 + val COOKS_EXIT = 3018 + val QUEST_ENTER = 3019 + val QUEST_LADDER = 3029 + val QUEST_EXIT_LADDER = 3028 + val COMBAT_EXIT = 3030 + val BANK_EXIT = 3024 + val FINANCE_EXIT = 3025 + val CHURCH_EXIT = 3026 + val FIRST_GATE = intArrayOf(3015,3016) + val COMBAT_GATES = intArrayOf(3020,3021) + val RAT_GATES = intArrayOf(3022, 3023) + + override fun defineListeners() { + on(GUIDE_HOUSE_DOOR, IntType.SCENERY, "open"){ player, door -> + if(getAttribute(player, "tutorial:stage", 0) != 3) + return@on true + + + setAttribute(player, "tutorial:stage", 4) + TutorialStage.load(player, 4) + core.game.global.action.DoorActionHandler.handleAutowalkDoor(player, door as Scenery, Location.create(3098, 3107, 0)) + return@on true + } + + on(FIRST_GATE, IntType.SCENERY, "open"){ player, gate -> + if(getAttribute(player, "tutorial:stage", 0) != 16) + return@on true + + setAttribute(player, "tutorial:stage", 17) + TutorialStage.load(player, 17) + core.game.global.action.DoorActionHandler.handleAutowalkDoor(player, gate as Scenery) + return@on true + } + + on(COOKS_DOOR, IntType.SCENERY, "open"){ player, door -> + if(getAttribute(player, "tutorial:stage", 0) != 17) + return@on true + + setAttribute(player, "tutorial:stage", 18) + TutorialStage.load(player, 18) + core.game.global.action.DoorActionHandler.handleAutowalkDoor(player, door as Scenery) + return@on true + } + + on(COOKS_EXIT, IntType.SCENERY, "open"){ player, door -> + if(getAttribute(player, "tutorial:stage", 0) != 22) + return@on true + + setAttribute(player, "tutorial:stage", 23) + TutorialStage.load(player, 23) + core.game.global.action.DoorActionHandler.handleAutowalkDoor(player, door as Scenery) + return@on true + } + + on(QUEST_ENTER, IntType.SCENERY, "open") { player, door -> + if(getAttribute(player, "tutorial:stage", 0) != 26) + return@on true + + setAttribute(player, "tutorial:stage", 27) + TutorialStage.load(player, 27) + core.game.global.action.DoorActionHandler.handleAutowalkDoor(player, door as Scenery) + return@on true + } + + on(QUEST_LADDER, IntType.SCENERY, "climb-down") { player, ladder -> + if(getAttribute(player, "tutorial:stage", 0) < 29) + return@on true + + if (getAttribute(player, "tutorial:stage", 0) == 29) { + setAttribute(player, "tutorial:stage", 30) + TutorialStage.load(player, 30) + } + core.game.global.action.ClimbActionHandler.climbLadder(player, ladder.asScenery(), "climb-down") + } + + on(QUEST_EXIT_LADDER, IntType.SCENERY, "climb-up") { player, ladder -> + core.game.global.action.ClimbActionHandler.climbLadder(player, ladder.asScenery(), "climb-up") + + submitWorldPulse(object : Pulse(2) { + override fun pulse(): Boolean { + val questTutor = Repository.findNPC(NPCs.QUEST_GUIDE_949) ?: return true + sendChat(questTutor, "What are you doing, ${player.username}? Get back down the ladder.") + return true + } + }) + + return@on true + } + + on(COMBAT_GATES, IntType.SCENERY, "open"){ player, gate -> + if(getAttribute(player, "tutorial:stage", 0) != 43) + return@on true + + setAttribute(player, "tutorial:stage", 44) + TutorialStage.load(player, 44) + core.game.global.action.DoorActionHandler.handleAutowalkDoor(player, gate as Scenery) + } + + on(RAT_GATES, IntType.SCENERY, "open") { player, gate -> + val stage = getAttribute(player, "tutorial:stage", 0) + if(stage !in 50..53){ + player.dialogueInterpreter.sendDialogues(NPCs.COMBAT_INSTRUCTOR_944, core.game.dialogue.FacialExpression.ANGRY, "Oi, get away from there!","Don't enter my rat pen unless I say so!") + return@on true + } + + if(stage == 50) { + setAttribute(player, "tutorial:stage", 51) + TutorialStage.load(player, 51) + } + core.game.global.action.DoorActionHandler.handleAutowalkDoor(player, gate as Scenery) + return@on true + } + + on(COMBAT_EXIT, IntType.SCENERY, "climb-up") { player, ladder -> + if(getAttribute(player, "tutorial:stage", 0) != 55) + return@on true + + setAttribute(player, "tutorial:stage", 56) + TutorialStage.load(player, 56) + core.game.global.action.ClimbActionHandler.climbLadder(player, ladder.asScenery(), "climb-up") + } + + on(BANK_EXIT, IntType.SCENERY, "open") { player, door -> + if(getAttribute(player, "tutorial:stage", 0) != 57) + return@on true + + setAttribute(player, "tutorial:stage", 58) + TutorialStage.load(player, 58) + core.game.global.action.DoorActionHandler.handleAutowalkDoor(player, door as Scenery) + } + + on(FINANCE_EXIT, IntType.SCENERY, "open") { player, door -> + if(getAttribute(player, "tutorial:stage", 0) != 59) + return@on true + + setAttribute(player, "tutorial:stage", 60) + TutorialStage.load(player, 60) + core.game.global.action.DoorActionHandler.handleAutowalkDoor(player, door as Scenery) + } + + on(CHURCH_EXIT, IntType.SCENERY, "open") { player, door -> + if(getAttribute(player, "tutorial:stage", 0) != 66) + return@on true + + setAttribute(player, "tutorial:stage", 67) + TutorialStage.load(player, 67) + core.game.global.action.DoorActionHandler.handleAutowalkDoor(player, door as Scenery) + } + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/tutisland/handlers/TutorialLoginCheck.kt b/Server/src/main/content/region/misc/tutisland/handlers/TutorialLoginCheck.kt new file mode 100644 index 0000000..a123a79 --- /dev/null +++ b/Server/src/main/content/region/misc/tutisland/handlers/TutorialLoginCheck.kt @@ -0,0 +1,28 @@ +package content.region.misc.tutisland.handlers + +import core.api.* +import core.game.node.entity.player.Player +import core.game.system.task.Pulse +import core.game.world.GameWorld + +/** + * Login listener that checks for tutorial completion and loads the current tutorial stage + * @author Ceikry + */ +class TutorialLoginCheck : LoginListener { + override fun login(player: Player) { + if(!getAttribute(player, "tutorial:complete", false)) { + //Disable need to do tutorial for anyone who has already started their account (gained levels or using it as a mule) + if(getAttribute(player, "tutorial:stage", 0) == 0 && (player.skills.totalLevel > 33 || player.bank.itemCount() > 0 || player.inventory.itemCount() > 0)){ + setAttribute(player, "/save:tutorial:complete", true) + return + } + GameWorld.Pulser.submit(object : Pulse(2) { + override fun pulse(): Boolean { + TutorialStage.load(player, getAttribute(player, "tutorial:stage", 0), true) + return true + } + }) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/tutisland/handlers/TutorialStage.kt b/Server/src/main/content/region/misc/tutisland/handlers/TutorialStage.kt new file mode 100644 index 0000000..3ab07f9 --- /dev/null +++ b/Server/src/main/content/region/misc/tutisland/handlers/TutorialStage.kt @@ -0,0 +1,1299 @@ +package content.region.misc.tutisland.handlers + +import core.api.* +import core.game.component.Component +import content.region.misc.tutisland.handlers.iface.CharacterDesign +import core.game.node.Node +import core.game.node.entity.combat.equipment.WeaponInterface +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.HintIconManager +import core.game.system.task.Pulse +import core.game.world.map.Location +import org.rs09.consts.Components +import core.api.Event +import core.game.world.GameWorld.Pulser +import core.game.world.GameWorld.settings +import core.game.world.repository.Repository +import org.rs09.consts.Items + +/** + * Loads stage-relevant tutorial data + * @author Ceikry + */ +object TutorialStage { + /** + * Performs stage actions for the player + * @param player the player to perform the actions on + * @param stage the stage to load + */ + fun load(player: Player, stage: Int, login: Boolean = false){ + if(login) + { + player.hook(Event.ButtonClicked, TutorialButtonReceiver) + player.hook(Event.Interacted, TutorialInteractionReceiver) + player.hook(Event.ResourceProduced, TutorialResourceReceiver) + player.hook(Event.UsedWith, TutorialUseWithReceiver) + player.hook(Event.FireLit, TutorialFireReceiver) + player.hook(Event.NPCKilled, TutorialKillReceiver) + openOverlay(player, Components.TUTORIAL_PROGRESS_371) + player.packetDispatch.sendInterfaceConfig(371, 4, true) + } + + updateProgressBar(player) + + when(stage) + { + 0 -> { + lock(player, 10) + teleport(player, Location.create(3094, 3107, 0)) + hideTabs(player, login) + CharacterDesign.open(player) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "", + "", + "Getting started", + "Please take a moment to design your character.", + "" + ) + ).also { + runTask(player, 10) { + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Getting started", + "To start the tutorial use your left mouse button to click on the", + "" + settings!!.name + " Guide in this room. He is indicated by a flashing", + "yellow arrow above his head. If you can't see him, use your", + "keyboard's arrow keys to rotate the view." + ) + ) + } + } + } + + + 1 -> { + hideTabs(player, login) + player.interfaceManager.openTab(Component(Components.OPTIONS_261)) + setVarbit(player, 3756, 12) + removeHintIcon(player) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "", + "", + "Game options", + "Please click on the flashing spanner icon found at the bottom", + "right of your screen. This will display your game options." + ) + ) + } + + 2 -> { + setVarbit(player, 3756, 0) + hideTabs(player, login) + registerHintIcon(player, Repository.findNPC(945)!!) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendScrollMessageWithBlueTitle( + "Game Options", + "In the interface, you can now see a variety of options such as", + "screen brightness, sound and music volume and whether you", + "want to accept aid from other player's or not. Don't worry", + "about these too much for now; they will become easier as you", + "explore the game. Talk to the " + settings!!.name + " Guide to continue." + ) + ) + } + + 3 -> { + hideTabs(player, login) + removeHintIcon(player) + registerHintIcon(player, Location.create(3098, 3107, 0), 125) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendScrollMessageWithBlueTitle( + "Interacting with scenery", + "You can interact with many items of scenery by simply clicking", + "on them. Right clicking will also give more options. Feel free to", + "try it with the things in this room, then click on the door", + "indicated with the yellow arrow to go though to the next", + "instructor." + ) + ) + } + + 4 -> { + hideTabs(player, login) + removeHintIcon(player) + registerHintIcon(player, Repository.findNPC(943)!!) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Moving around", + "Follow the path to find the next instructor. Clicking on the", + "ground will walk you to that point. You can also navigate by", + "clicking on the minimap in the top-right corner of your screen.", + "Talk to Survival Expert by the pond to continue the tutorial." + ) + ) + } + + 5 -> { + hideTabs(player, login) + player.interfaceManager.openTab(Component(Components.INVENTORY_149)) + setVarbit(player, 3756, 4) + removeHintIcon(player) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Viewing the items that you were given.", + "Click on the flashing backpack icon to the right-hand side of", + "the main window to view your inventory. Your inventory is a list", + "of everything you have in your backpack.", + "" + ) + ) + } + + 6 -> { + hideTabs(player, login) + setVarbit(player, 3756, 4) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Cut down a tree", + "You can click on the backpack icon at any time to view the", + "items that you currently have in your inventory. You will see", + "that you now have an axe in your inventory. Use this to get", + "some logs by clicking on one of the trees in the area." + ) + ) + } + + 7 -> { + hideTabs(player, login) + removeHintIcon(player) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Please wait.", + "", + "Your character is now attempting to cut down the tree. Sit back", + "for a moment while " + (if (player.appearance.isMale) "he" else "she") + " does all the hard work.", + "" + ) + ) + } + + 8 -> { + hideTabs(player, login) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Making a fire", + "Well done! You managed to cut some logs from the tree! Next,", + "use the tinderbox in your inventory to light the logs.", + "First click on the tinderbox to 'use' it.", + "Then click on the logs in your inventory to light them." + ) + ) + } + + 9 -> { + hideTabs(player, login) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Please wait.", + "", + "Your character is now attempting to light the fire.", + "This should only take a few seconds.", + "" + ) + ) + } + + 10 -> { + hideTabs(player, login) + player.interfaceManager.openTab(Component(Components.STATS_320)) + setVarbit(player, 3756, 2) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "You gained some experience.", + "", + "Click on the flashing bar graph icon near the inventory button", + "to see your skill state.", + "" + ) + ) + } + + 11 -> { + hideTabs(player, login) + setVarbit(player, 3756, 2) + registerHintIcon(player, Repository.findNPC(943)!!) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Your skill stats", + "Here you will see how good your skills are. As you move your", + "mouse over any of the icons in this tab, the small yellow popup", + "box will show you the exact amount of experience you have", + "and how much is needed to get to the next level. Speak to the survival guide." + ) + ) + } + + 12 -> { + hideTabs(player, login) + setVarp(player, 406, 2) + removeHintIcon(player) + registerHintIcon(player, Repository.findNPC(952)!!) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Catch some shrimp", + "Click on the bubbling fishing spot, indicated by the flashing", + "arrow. Remember, you can check your inventory by clicking the", + "backpack icon.", + "" + ) + ) + } + + 13 -> { + hideTabs(player, login) + removeHintIcon(player) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Please wait.", + "", + "This should only take a few seconds.", + "As you gain Fishing experience you'll find that there are many", + "types of fish and many ways to catch them." + ) + ) + } + + 14 -> { + hideTabs(player, login) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Cooking your shrimp", + "Now you have caught some shrimp, let's cook it. First light a", + "fire: chop down a tree and then use the tinderbox on the logs.", + "If you've lost your axe or tinderbox Brynna will give you", + "another." + ).also { + if (!inInventory(player, Items.RAW_SHRIMPS_317, 1)) { + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Cooking your shrimp", + "Now right click on the shrimp and select the use option. Next,", + "left click on the fire you just lit. If while doing this you look in", + "the top left of the screen, you will see the instruction that", + "you're giving your character." + ) + ) + } + } + ) + } + + 15 -> { + hideTabs(player, login) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Burning your shrimp", + "You have just burnt your first shrimp. This is normal. As you", + "get more experience in Cooking you will burn stuff less often.", + "Let's try cooking without burning it this time. First catch some", + "more shrimp, then use them on a fire." + ) + ) + } + + 16 -> { + hideTabs(player, login) + registerHintIcon(player, Location.create(3089, 3091, 0), 75) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Well done, you've just cooked your first " + settings!!.name + " meal.", + "If you'd like a recap on anything you've learnt so far, speak to", + "the Survival Expert. You can now move on to the next", + "instructor. Click on the gate shown and follow the path.", + "Remember, you can move the camera with the arrow keys." + ) + ) + } + + 17 -> { + hideTabs(player, login) + removeHintIcon(player) + registerHintIcon(player, Location.create(3078, 3084, 0), 125) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Find your next instructor", + "Follow the path until you get to the door with the yellow arrow", + "above it. Click on the door to open it. Notice the mini map in the", + "top right; this shows a top down view of the area around you.", + "This can also be used for navigation." + ) + ) + } + + 18 -> { + hideTabs(player, login) + removeHintIcon(player) + registerHintIcon(player, Repository.findNPC(942)!!) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Find your next instructor", + "Talk to the chef indicated. He will teach you the more advanced", + "aspects of Cooking such as combining ingredients. He will also", + "teach you about your Music Player.", + "" + ) + ) + } + + 19 -> { + hideTabs(player, login) + removeHintIcon(player) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Making dough", + "This is the base for many of the meals. To make dough we must", + "mix flour and water. First, right click the bucket of water and", + "select use, then left click on the pot of flour.", + "" + ) + ) + } + + 20 -> { + hideTabs(player, login) + registerHintIcon(player, Location.create(3076, 3081, 0), 75) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Cooking dough", + "Now you have made dough, you can cook it. To cook the dough,", + "use it with the range shown by the arrow. If you lose your", + "dough, talk to Lev - he will give you more ingredients.", + "" + ) + ) + } + + 21 -> { + hideTabs(player, login) + removeHintIcon(player) + player.interfaceManager.openTab(Component(Components.MUSIC_V3_187)) + setVarbit(player, 3756, 14) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendScrollMessageWithBlueTitle( + "Cooking dough", + "Well done! Your first loaf of bread. As you gain experience in", + "Cooking, you will be able to make other things like pies, cakes", + "and even kebabs. Now you've got the hang of cooking, let's", + "move on. Click on the flashing icon in the bottom right to see", + "the flashing icon in the bottom right to see the Music Player." + ) + ) + } + + 22 -> { + hideTabs(player, login) + setVarbit(player, 3756, 0) + registerHintIcon(player, Location.create(3072, 3090, 0), 125) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendScrollMessageWithBlueTitle( + "The Music Player", + "From this interface you can control the music that is played.", + "As you explore the world and complete quests, more of the", + "tunes will become unlocked. Once you've examined this menu,", + "use the next door to continue. If you need a recap on anything", + "you've learnt so far, speak to the Master Chef." + ) + ) + } + + 23 -> { + hideTabs(player, login) + setVarbit(player, 3756, 13) + removeHintIcon(player) + player.interfaceManager.openTab(Component(Components.EMOTES_464)) + stopWalk(player) + player.locks.lockMovement(100000) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Emotes", + "", + "Now how about showing some feelings? You will see a flashing", + "icon in the shape of a person. Click on that to access your", + "emotes." + ) + ) + } + + 24 -> { + hideTabs(player, login) + setVarbit(player, 3756, 0) + player.locks.lockMovement(100000) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Emotes", + "For those situations where words don't quite describe how you feel try", + "an emote. Go ahead try one out! You might notice that some of the", + "emotes are grey and cannot be used now. Don't worry! As you", + "progress further into the game you'll gain access to all sorts of things." + ) + ) + } + + 25 -> { + hideTabs(player, login) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Running", + "", + "It's only a short distance to the next guide.", + "Why not try running there? To do this, click on the run icon", + "next to the minimap." + ) + ) + } + + 26 -> { + hideTabs(player, login) + registerHintIcon(player, Repository.findNPC(949)!!) + player.locks.unlockMovement() + Component.setUnclosable( + player, + player.dialogueInterpreter.sendScrollMessageWithBlueTitle( + "Run to the next guide", + "Now that you have the run button turned on, follow the path", + "until you come to the end. You may notice that the number on", + "the button goes down. This is your run energy. If your run", + "energy reaches zero, you'll stop running. Click on the door to", + "pass through it." + ) + ) + } + + 27 -> { + hideTabs(player, login) + removeHintIcon(player) + registerHintIcon(player, Repository.findNPC(949)!!) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Talk with the Quest Guide.", + "", + "He will tell you all about quests.", + "", + "" + ) + ) + } + + 28 -> { + hideTabs(player, login) + setVarbit(player, 3756, 0) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Your Quest Journal", + "", + "This is your Quest Journal, a list of all the quests in the game.", + "Talk to the Quest Guide again for an explanation.", + "" + ) + ) + } + + 29 -> { + hideTabs(player, login) + removeHintIcon(player) + setVarbit(player, 3756, 0) + registerHintIcon(player, Location.create(3088, 3119, 0), 15) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "", + "Moving on", + "It's time to enter some caves. Click on the ladder to go down to", + "the next area.", + "" + ) + ) + } + + 30 -> { + hideTabs(player, login) + removeHintIcon(player) + setVarbit(player, 3756, 0) + registerHintIcon(player, Repository.findNPC(948)!!) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Mining and Smithing", + "", + "Next let's get you a weapon, or more to the point, you can", + "make your first weapon yourself. Don't panic, the Mining", + "Instructor will help you. Talk to him and he'll tell you all about it." + ) + ) + } + + 31 -> { + hideTabs(player, login) + removeHintIcon(player) + registerHintIcon(player, Location.create(3076, 9504, 0), 50) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Prospecting", + "To prospect a mineable rock, just right click it and select the", + "'prospect rock' option. This will tell you the type of ore you can", + " mine from it. Try it now on one of the rocks indicated.", + "" + ) + ) + } + + 32 -> { + hideTabs(player, login) + removeHintIcon(player) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Please wait.", + "", + "Your character is now attempting to prospect the rock. This", + "should only take a few seconds.", + "" + ) + ) + Pulser.submit(object : Pulse(3) { + override fun pulse(): Boolean { + setAttribute(player, "tutorial:stage", 33) + load(player, 33) + return true + } + }) + } + + 33 -> { + hideTabs(player, login) + removeHintIcon(player) + registerHintIcon(player, Location.create(3086, 9501, 0), 50) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "It's tin.", + "", + "So now you know there's tin in the grey rocks, try prospecting the", + "brown ones next.", + "" + ) + ) + } + + 34 -> { + hideTabs(player, login) + removeHintIcon(player) + registerHintIcon(player, Repository.findNPC(948)!!) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "It's copper.", + "", + "Talk to the Mining Instructor to find out about these types of", + "ore and how you can mine them.", + "He'll even give you the required tools.", + ) + ) + } + + 35 -> { + hideTabs(player, login) + removeHintIcon(player) + registerHintIcon(player, Location.create(3076, 9504), 50) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Mining", + "", + "It's quite simple really. All you need to do is right click on the", + "rock and select 'mine' You can only mine when you have a", + "pickaxe. So give it a try: first mine one tin ore.", + ) + ) + } + + 36 -> { + hideTabs(player, login) + removeHintIcon(player) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Please wait.", + "", + "Your character is now attempting to mine the rock.", + "This should only take a few seconds.", + "" + ) + ) + } + + 37 -> { + hideTabs(player, login) + registerHintIcon(player, Location.create(3086, 9501), 50) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Mining", + "", + "Now you have some tin ore you just need some copper ore,", + "then you'll have all you need to create a bronze bar. As you", + "did before right click on the copper rock and select 'mine'." + ) + ) + } + + 38 -> { + hideTabs(player, login) + removeHintIcon(player) + registerHintIcon(player, Location.create(3079, 9496), 75) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Smelting", + "You should now have both some copper and tin ore. So let's", + "smelt them to make a bronze bar. To do this, right click on", + "either tin or copper ore and select use then left click on the", + "furnace. Try it now." + ) + ) + } + + //39 -> {} + + 40 -> { + hideTabs(player, login) + removeHintIcon(player) + registerHintIcon(player, Repository.findNPC(948)!!) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "You've made a bronze bar!", + "", + "Speak to the Mining Instructor and he'll show you how to make", + "it into a weapon.", + "" + ) + ) + } + + 41 -> { + hideTabs(player, login) + removeHintIcon(player) + registerHintIcon(player, Location.create(3083, 9499), 50) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Smithing a dagger", + "To smith you'll need a hammer - like the one you were given by", + "Dezzick - access to an anvil like the one with the arrow over it", + "and enough metal bars to make what you are trying to smith.", + "To start the process, use the bar on one of the anvils." + ) + ) + } + + 42 -> { + hideTabs(player, login) + removeHintIcon(player) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Smithing a dagger.", + "Now you have the Smithing menu open, you will see a list of all", + "the things you can make. Only the dagger can be made at your", + "skill level; this is shown by the white text under it. You'll need", + "to select the dagger to continue." + ) + ) + } + + 43 -> { + hideTabs(player, login) + registerHintIcon(player, Location.create(3095, 9502), 75) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "You've finished in this area.", + "", + "So let's move on. Go through the gates shown by the arrow.", + "Remember, you may need to move the camera to see your", + "surroundings. Speak to the guide for a recap at any time.", + ) + ) + } + + 44 -> { + hideTabs(player, login) + removeHintIcon(player) + registerHintIcon(player, Repository.findNPC(944)!!) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Combat", + "", + "In this area you will find out about combat with swords and", + "bows. Speak to the guide and he will tell you all about it.", + "" + ) + ) + } + + 45 -> { + hideTabs(player, login) + removeHintIcon(player) + runTask(player, 10) { + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Wielding weapons", + "", + "You now have access to a new interface. Click on the flashing", + "icon of a man, the one to the right of your backpack icon.", + "" + ) + ) + }.also { + hideTabs(player, login) + removeHintIcon(player) + player.interfaceManager.openTab(Component(Components.WORNITEMS_387)) + setVarbit(player, 3756, 5) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Worn interface", + "You can see what items you are wearing in the worn equipment", + "to the left of the screen, with their combined statistics on the", + "right. Let's add something. Left click your dagger to 'wield' it.", + "" + ) + ) + } + } + + 46 -> { + hideTabs(player, login) + setVarbit(player, 3756, 0) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "This is your worn inventory.", + "From here you can see what items you have equipped. Let's", + "get one of those slots filled, go back to your inventory and", + "right click your dagger, select wield from the menu.", + "" + ) + ) + } + + 47 -> { + hideTabs(player, login) + removeHintIcon(player) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendScrollMessageWithBlueTitle( + "You're now holding your dagger.", + "Clothes, armour, weapons and many other items are equipped", + "like this. You can unequip items by clicking on the item in the", + "worn equipment. You can close this window by clicking on the", + "small 'x' in the top-right hand corner. Speak to the Combat", + "Instructor." + ) + ) + } + + 48 -> { + hideTabs(player, login) + removeHintIcon(player) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendScrollMessageWithBlueTitle( + "Unequipping items.", + "In your worn inventory panel, right click on the dagger and", + "select the remove option from the drop down list. After you've", + "unequipped the dagger, wield the sword and shield. As you", + "pass the mouse over an item you will see its name appear at", + "the top left of the screen." + ) + ) + } + + 49 -> { + hideTabs(player, login) + setVarbit(player, 3756, 1) + var wepInter = player.getExtension(WeaponInterface::class.java) + if(wepInter == null) + { + wepInter = WeaponInterface(player) + player.addExtension(WeaponInterface::class.java, wepInter) + } + player.interfaceManager.openTab(wepInter) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Combat interface.", + "", + "Click on the flashing crossed swords icon to see the combat", + "interface.", + "" + ) + ) + } + + 50 -> { + hideTabs(player, login) + setVarbit(player, 3756, 0) + registerHintIcon(player, Location.create(3110,9518,0), 75) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendScrollMessageWithBlueTitle( + "This is your combat interface.", + "From this interface you can select the type of attack your", + "character will use. Different monsters have different", + "weaknesses. If you hover your mouse over the buttons, you", + "will see the type of XP you will receive when using each type of", + "attack. Now you have the tools needed for battle why not slay", + "some rats. Click on the gates indicated to continue." + ) + ) + } + + 51 -> { + hideTabs(player, login) + removeHintIcon(player) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Attacking", + "To attack the rat, click it and select the attack option. You", + "will then walk over to it and start hitting it.", + "", + "" + ) + ) + } + + 52 -> { + hideTabs(player, login) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Sit back and watch.", + "While you are fighting you will see a bar over your head. The", + "bar shows how much health you have left. Your opponent will", + "have one too. You will continue to attack the rat until it's dead", + "or you do something else." + ) + ) + } + + 53 -> { + hideTabs(player, login) + removeHintIcon(player) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Well done, you've made your first kill!", + "", + "Pass through the gate and talk to the Combat Instructor; he", + "will give you your next task.", + "" + ) + ) + } + + 54 -> { + hideTabs(player, login) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Rat ranging", + "Now you have a bow and some arrows. Before you can use", + "them you'll need to equip them. Once equipped with the", + "ranging gear try killing another rat. Remember: to attack, right", + "click on the monster and select attack." + ) + ) + } + + 55 -> { + hideTabs(player, login) + removeHintIcon(player) + registerHintIcon(player, Location.create(3111,9526), 50) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Moving on.", + "You have completed the tasks here. To move on, click on the", + "ladder shown. If you need to go over any of what you learnt", + "here, just talk to the Combat Instructor and he'll tell you what", + "he can." + ) + ) + } + + 56 -> { + hideTabs(player, login) + removeHintIcon(player) + registerHintIcon(player, Location.create(3122,3124), 50) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Banking.", + "Follow the path and you will come to the front of a building.", + "This is the 'Bank of " + settings!!.name + "' where you can store all your", + "most valued items. To open your bank box just right click on an", + "open booth indicated and select 'use'." + ) + ) + } + + 57 -> { + hideTabs(player, login) + removeHintIcon(player) + registerHintIcon(player, Location.create(3125, 3124), 75) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "This is your bank box.", + "You can store stuff here for safekeeping. If you die, anything", + "in your bank will be saved. To deposit something, right click it", + "and select 'Deposit-1'. Once you've had a good look, close the", + "window and move on through the door indicated." + ) + ) + } + + 58 -> { + hideTabs(player, login) + removeHintIcon(player) + registerHintIcon(player, Repository.findNPC(947)!!) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Financial advice", + "", + "The guide here will tell you all about making cash. Just click on", + "him to hear what he's got to say.", + "" + ) + ) + } + + 59 -> { + hideTabs(player, login) + removeHintIcon(player) + registerHintIcon(player, Location.create(3130, 3124, 0), 75) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "", + "", + "Continue through the next door.", + "", + "" + ) + ) + } + + 60 -> { + hideTabs(player, login) + removeHintIcon(player) + registerHintIcon(player, Repository.findNPC(954)!!) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Prayer", + "Follow the path to the chapel and enter it.", + "Once inside talk to the monk. He'll tell you all about the Prayer", + "skill.", + "" + ) + ) + } + + 61 -> { + hideTabs(player, login) + removeHintIcon(player) + player.interfaceManager.openTab(Component(Components.PRAYER_271)) + setVarbit(player, 3756, 6) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Your Prayer List", + "", + "Click on the flashing icon to open the Prayer List.", + "", + "" + ) + ) + } + + 62 -> { + hideTabs(player, login) + registerHintIcon(player, Repository.findNPC(954)!!) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "", + "Your Prayer List", + "", + "Talk with Brother Brace and he'll tell you all about prayers.", + "" + ) + ) + } + + 63 -> { + hideTabs(player, login) + removeHintIcon(player) + player.interfaceManager.openTab(Component(Components.FRIENDS2_550)) + setVarbit(player, 3756, 9) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "", + "Friends list", + "You should now see another new icon. Click on the flashing", + "smiling face to open your Friend List.", + "" + ) + ) + } + + 64 -> { + hideTabs(player, login) + setVarbit(player, 3756, 10) + player.interfaceManager.openTab(Component(Components.IGNORE2_551)) + player.interfaceManager.openTab(Component(Components.CLANJOIN_589)) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "This is your Friends List.", + "", + "This will be explained by Brother Brace shortly, but first click", + "on the other flashing face in the interface.", + "" + ) + ) + } + + 65 -> { + hideTabs(player, login) + setVarbit(player, 3756, 0) + registerHintIcon(player, Repository.findNPC(945)!!) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "This is your Ignore List.", + "The two lists, Friends and Ignore - can be very helpful for", + "keeping track of when your friends are online or for blocking", + "messages from people you simply don't like. Speak with", + "Brother Brace and he will tell you more." + ) + ) + } + + 66 -> { + hideTabs(player, login) + removeHintIcon(player) + registerHintIcon(player, Location.create(3122,3102), 75) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "", + "Your final instructor!", + "You're almost finished on tutorial island. Pass through the", + "door to find the path leading to your final instructor.", + "" + ) + ) + } + + 67 -> { + hideTabs(player, login) + removeHintIcon(player) + registerHintIcon(player, Repository.findNPC(946)!!) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Your final instructor!", + "Just follow the path to the Wizard's house, where you will be", + "shown how to cast spells. Just talk with the mage indicated to", + "find out more.", + "" + ) + ) + } + + 68 -> { + hideTabs(player, login) + removeHintIcon(player) + player.interfaceManager.openTab(Component(player.spellBookManager.spellBook)) + setVarbit(player, 3756, 7) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "Open up your final tab.", + "", + "Open up the Magic Spellbook tab by clicking on the flashing", + "icon next to the Prayer List tab you just learned about.", + "" + ) + ) + } + + 69 -> { + hideTabs(player, login) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "", + "This is your spell list.", + "", + "Ask the mage about it.", + "" + ) + ) + } + + 70 -> { + hideTabs(player, login) + registerHintIcon(player, Repository.findNPC(41)!!) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendScrollMessageWithBlueTitle( + "Cast Wind Strike at a chicken.", + "Now you have the runes you should see the Wind Strike icon at the", + "top-left of your spellbook, second in from the left. Walk over", + "to the caged chickens, click the Wind Strike icon and then", + "select one of the chickens to cast it on. It may take several", + "tries." + ) + ) + } + + 71 -> { + removeHintIcon(player) + player.interfaceManager.restoreTabs() + registerHintIcon(player, Repository.findNPC(946)!!) + Component.setUnclosable( + player, + player.dialogueInterpreter.sendPlaneMessageWithBlueTitle( + "You have almost completed the tutorial!", + "", + "All you need to do now is teleport to the mainland. Just speak", + "with Terrova and he'll tell you how to do that.", + "" + ) + ) + } + } + } + + @JvmStatic + public fun hideTabs(player: Player, login: Boolean) + { + val stage = getAttribute(player, "tutorial:stage", 0) + if(login && player.interfaceManager.tabs.isNotEmpty()) + player.interfaceManager.removeTabs(*(0..13).toIntArray()) + + if(stage > 2) + player.interfaceManager.openTab(Component(Components.OPTIONS_261)) + if(stage > 5) + player.interfaceManager.openTab(Component(Components.INVENTORY_149)) + if(stage > 10) + player.interfaceManager.openTab(Component(Components.STATS_320)) + if(stage > 21) + player.interfaceManager.openTab(Component(Components.MUSIC_V3_187)) + if(stage > 23) + player.interfaceManager.openTab(Component(Components.EMOTES_464)) + if(stage > 28) + player.interfaceManager.openTab(Component(Components.QUESTJOURNAL_V2_274)) + if(stage > 45) + player.interfaceManager.openTab(Component(Components.WORNITEMS_387)) + if(stage > 49){ + var wepInter = player.getExtension(WeaponInterface::class.java) + if(wepInter == null) + { + wepInter = WeaponInterface(player) + player.addExtension(WeaponInterface::class.java, wepInter) + } + } + if(stage > 61) + player.interfaceManager.openTab(Component(Components.PRAYER_271)) + if(stage > 63) + player.interfaceManager.openTab(Component(Components.FRIENDS2_550)) + if(stage > 64){ + player.interfaceManager.openTab(Component(Components.IGNORE2_551)) + player.interfaceManager.openTab(Component(Components.CLANJOIN_589)) + } + if(stage > 68) + player.interfaceManager.openTab(Component(player.spellBookManager.spellBook)) + } + + private fun updateProgressBar(player: Player) + { + val stage = getAttribute(player, "tutorial:stage", 0) + val percent = if(stage == 0) 0 else ((stage.toDouble() / 71.0) * 100.0).toInt() + val barPercent = if(stage == 0) 0 else (((percent.toDouble() / 100.0) * 20.0).toInt() + 1) + setVarp(player, 406, barPercent) + setInterfaceText(player, "$percent% Done", 371, 1) + } + + fun removeHintIcon(player: Player) { + val slot = player.getAttribute("tutorial:hinticon", -1) + if (slot < 0 || slot >= HintIconManager.MAXIMUM_SIZE) { + return + } + player.removeAttribute("tutorial:hinticon") + HintIconManager.removeHintIcon(player, slot) + } + + private fun registerHintIcon(player: Player, node: Node) + { + setAttribute(player, "tutorial:hinticon", HintIconManager.registerHintIcon(player, node)) + } + + private fun registerHintIcon(player: Player, location: Location, height: Int) + { + setAttribute(player, "tutorial:hinticon", HintIconManager.registerHintIcon(player, location, 1, -1, player.hintIconManager.freeSlot(), height, 3)) + } +} diff --git a/Server/src/main/content/region/misc/tutisland/handlers/iface/CharacterDesign.java b/Server/src/main/content/region/misc/tutisland/handlers/iface/CharacterDesign.java new file mode 100644 index 0000000..a40f65f --- /dev/null +++ b/Server/src/main/content/region/misc/tutisland/handlers/iface/CharacterDesign.java @@ -0,0 +1,383 @@ +package content.region.misc.tutisland.handlers.iface; + +import core.game.component.CloseEvent; +import core.game.component.Component; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.appearance.Gender; +import core.game.node.item.Item; +import core.tools.RandomFunction; + +import static core.api.ContentAPIKt.*; + +/** + * Represents the class used to handle the character design. + * @author Emperor + * @author Vexia + * + */ +public final class CharacterDesign { + + private static final Item[] STARTER_PACK = new Item[] { new Item(1351, 1), new Item(590, 1), new Item(303, 1), new Item(315, 1), new Item(1925, 1), new Item(1931, 1), new Item(2309, 1), new Item(1265, 1), new Item(1205, 1), new Item(1277, 1), new Item(1171, 1), new Item(841, 1), new Item(882, 25), new Item(556, 25), new Item(558, 15), new Item(555, 6), new Item(557, 4), new Item(559, 2) }; + private static final Item[] STARTER_BANK = new Item[] { new Item( 995, 25)}; + + + /** + * The male head ids. + */ + private static final int[] MALE_HEAD_IDS = {0, 1, 2, 3, 4, 5, 6, 7, 8, 91, 92, 93, 94, 95, 96, 97, 261, 262, 263, 264, 265, 266, 267, 268}; + + /** + * The female head ids. + */ + private static final int[] FEMALE_HEAD_IDS = {45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280}; + + /** + * The male jaw ids. + */ + private static final int[] MALE_JAW_IDS = { 10, 11, 12, 13, 14, 15, 16, 17, 98, 99, 100, 101, 102, 103, 104, 305, 306, 307, 308}; + + /** + * The female jaw ids. + */ + private static final int[] FEMALE_JAW_IDS = { 1000 }; + + /** + * The male torso ids. + */ + private static final int[] MALE_TORSO_IDS = {18, 19, 20, 21, 22, 23, 24, 25, 111, 112, 113, 114, 115, 116 }; + + /** + * The female torso ids. + */ + private static final int[] FEMALE_TORSO_IDS = { 56, 57, 58, 59, 60, 153, 154, 155, 156, 157, 158}; + + /** + * The male arms ids. + */ + private static final int[] MALE_ARMS_IDS = {26, 27, 28, 29, 30, 31, 105, 106, 107, 108, 109, 110}; + + /** + * The female arms ids. + */ + private static final int[] FEMALE_ARMS_IDS = {61, 62, 63, 64, 65, 147, 148, 149, 150, 151, 152 }; + + /** + * The male hands ids. + */ + private static final int[] MALE_HANDS_IDS = {33, 34, 84, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126}; + + /** + * The female hands ids. + */ + private static final int[] FEMALE_HANDS_IDS = {67, 68, 127, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168}; + + /** + * The male legs ids. + */ + private static final int[] MALE_LEGS_IDS = {36, 37, 38, 39, 40, 85, 86, 87, 88, 89, 90}; + + /** + * The female legs ids. + */ + private static final int[] FEMALE_LEGS_IDS = {70, 71, 72, 73, 74, 75, 76, 77, 128, 129, 130, 131, 132, 133, 134 }; + + /** + * The male feet ids. + */ + private static final int[] MALE_FEET_IDS = { 42, 43 }; + + /** + * The female feet ids. + */ + private static final int[] FEMALE_FEET_IDS = { 79, 80 }; + + /** + * The male look ids. + */ + private static final int[][] MALE_LOOK_IDS = { MALE_HEAD_IDS, MALE_JAW_IDS, MALE_TORSO_IDS, MALE_ARMS_IDS, MALE_HANDS_IDS, MALE_LEGS_IDS, MALE_FEET_IDS }; + + /** + * The female look ids. + */ + private static final int[][] FEMALE_LOOK_IDS = { FEMALE_HEAD_IDS, FEMALE_JAW_IDS, FEMALE_TORSO_IDS, FEMALE_ARMS_IDS, FEMALE_HANDS_IDS, FEMALE_LEGS_IDS, FEMALE_FEET_IDS }; + + /** + * The hair colors. + */ + private static final int[] HAIR_COLORS = new int[] {20, 19, 10, 18, 4, 5, 15, 7, 0, 6, 21, 9, 22, 17, 8, 16, 11, 24, 23, 3, 2, 1, 14, 13, 12}; + + /** + * The torso colors. + */ + private static final int[] TORSO_COLORS = new int[] {24, 23, 2, 22, 12, 11, 6, 19, 4, 0, 9, 13, 25, 8, 15, 26, 21, 7, 20, 14, 10, 28, 27, 3, 5, 18, 17, 1, 16}; + + /** + * The leg colors. + */ + private static final int[] LEG_COLORS = new int[] {26, 24, 23, 3, 22, 13, 12, 7, 19, 5, 1, 10, 14, 25, 9, 0, 21, 8, 20, 15, 11, 28, 27, 4, 6, 18, 17, 2, 16}; + + /** + * The feet colors. + */ + private static final int[] FEET_COLORS = new int[] {0, 1, 2, 3, 4, 5}; + + /** + * The skin colors. + */ + private static final int[] SKIN_COLORS = new int[] {7, 6, 5, 4, 3, 2, 1, 0}; + + /** + * Method used to open the design. + * @param player the player. + */ + public static void open(final Player player) { + player.unlock(); + player.removeAttribute("char-design:accepted"); + player.getPacketDispatch().sendPlayerOnInterface(771, 79); + player.getPacketDispatch().sendAnimationInterface(9806, 771, 79); + player.getAppearance().changeGender(player.getAppearance().getGender()); + Component c = player.getInterfaceManager().openComponent(771); + if (c != null) { + c.setCloseEvent(new CloseEvent() { + @Override + public boolean close(Player player, Component c) { // Unclosable! + return player.getAttribute("char-design:accepted", false); + } + }); + } + reset(player); + player.getPacketDispatch().sendInterfaceConfig(771, 22, false); + player.getPacketDispatch().sendInterfaceConfig(771, 92, false); + player.getPacketDispatch().sendInterfaceConfig(771, 97, false); + setVarp(player, 1262, player.getAppearance().isMale() ? 1 : 0); + } + + public static void reopen(final Player player) { + player.removeAttribute("char-design:accepted"); + player.getPacketDispatch().sendPlayerOnInterface(771, 79); + player.getPacketDispatch().sendAnimationInterface(9806, 771, 79); + Component c = player.getInterfaceManager().openComponent(771); + if (c != null) { + c.setCloseEvent((player1, c1) -> { // Unclosable! + return player1.getAttribute("char-design:accepted", false); + }); + } + player.getPacketDispatch().sendInterfaceConfig(771, 22, false); + player.getPacketDispatch().sendInterfaceConfig(771, 92, false); + player.getPacketDispatch().sendInterfaceConfig(771, 97, false); + setVarp(player, 1262, player.getAppearance().isMale() ? 1 : 0); + } + + + /** + * Handles the buttons. + */ + public static boolean handleButtons(Player player, int buttonId) { + switch (buttonId) { + case 37: + case 40: + player.getSettings().toggleMouseButton(); + break; + case 92://hair style + case 93: + changeLook(player, 0, buttonId == 93); + break; + case 97: + case 98://facial hair style + changeLook(player, 1, buttonId == 98); + break; + case 341: + case 342://torso style + changeLook(player, 2, buttonId == 342); + break; + case 345: + case 346://arms style + changeLook(player, 3, buttonId == 346); + break; + case 349: + case 350://wrists style + changeLook(player, 4, buttonId == 350); + break; + case 353: + case 354://legs style + changeLook(player, 5, buttonId == 354); + break; + case 357: + case 358://feet style + changeLook(player, 6, buttonId == 358); + break; + case 49: + case 52://change gender + changeGender(player, buttonId == 49); + break; + case 321://randomize body + randomize(player, false); + return true; + case 169: + randomize(player, true);//randomize hair + return true; + case 362://confirm + confirm(player, true); + return true; + } + if (buttonId >= 100 && buttonId <= 124) { + changeColor(player, 0, HAIR_COLORS, 100, buttonId); + } + if (buttonId >= 189 && buttonId <= 217) { + changeColor(player, 2, TORSO_COLORS, 189, buttonId); + } + if (buttonId >= 248 && buttonId <= 276) { + changeColor(player, 5, LEG_COLORS, 248, buttonId); + } + if (buttonId >= 307 && buttonId <= 312) { + changeColor(player, 6, FEET_COLORS, 307, buttonId); + } + if (buttonId <= 158 && buttonId >= 151) { + changeColor(player, 4, SKIN_COLORS, 158, buttonId); + } + return false; + } + + /** + * Changes the gender of a player. + * @param player The player. + * @param male If we're changing to male. + */ + private static void changeGender(Player player, boolean male) { + player.setAttribute("male", male); + setVarp(player, 1262, male ? 1 : 0); + if (male) { + setVarbit(player, 5008, 1); + setVarbit(player, 5009, 0); + } + else { + setVarbit(player, 5008, 0); + setVarbit(player, 5009, 1); + } + reset(player); + } + + /** + * Changes the look of a player. + * @param player The player. + * @param index The index. + * @param increment If we're incrementing. + */ + private static void changeLook(Player player, int index, boolean increment) { + if (index < 2 && player.getAttribute("first-click:" + index, false) == false) { + player.setAttribute("first-click:" + index, true); + return; + } + player.setAttribute("look-val:" + index, getValue(player, "look", index, (int) player.getAttribute("look:" + index, 0), increment)); + } + + /** + * Changes the color of a player. + * @param player The player. + * @param index The body index. + * @param array The color array. + */ + private static void changeColor(Player player, int index, int[] array, int startId, int buttonId) { + int col = array[Math.abs(buttonId - startId)]; + player.setAttribute("color-val:" + index, array[Math.abs(buttonId - startId)]); + } + + /** + * Resets the players design. + * @param player the player. + */ + private static void reset(Player player) { + for (int i = 0; i < player.getAppearance().getAppearanceCache().length; i++) { + player.removeAttribute("look:" + i); + player.removeAttribute("look-val:" + i); + player.removeAttribute("color-val:" + i); + } + player.removeAttribute("first-click:0"); + player.removeAttribute("first-click:1"); + } + + /** + * Randomizes the player's look. + * @param player the player. + */ + public static void randomize(Player player, boolean head) { + if (head) { + changeLook(player, 0, RandomFunction.random(2) == 1); + changeLook(player, 1, RandomFunction.random(2) == 1); + changeColor(player, 0, HAIR_COLORS, 100, RandomFunction.random(100, 124)); + changeColor(player, 4, SKIN_COLORS, 158, RandomFunction.random(158, 151)); + } else { + for (int i = 0; i < player.getAppearance().getAppearanceCache().length; i++) { + changeLook(player, i, RandomFunction.random(2) == 1); + } + changeColor(player, 2, TORSO_COLORS, 189, RandomFunction.random(189, 217)); + changeColor(player, 5, LEG_COLORS, 248, RandomFunction.random(248, 276)); + changeColor(player, 6, FEET_COLORS, 307, RandomFunction.random(307, 312)); + } + confirm(player, false); + } + + /** + * Confirms the character screen. + * @param player The player. + * @param close If we should close the interface. + */ + private static void confirm(Player player, boolean close) { + if (close) { + player.setAttribute("char-design:accepted", true); + player.getInterfaceManager().close(); + } + player.getAppearance().setGender(player.getAttribute("male", player.getAppearance().isMale()) ? Gender.MALE : Gender.FEMALE); + for (int i = 0; i < player.getAppearance().getAppearanceCache().length; i++) { + player.getAppearance().getAppearanceCache()[i].changeLook(player.getAttribute("look-val:" + i, player.getAppearance().getAppearanceCache()[i].getLook())); + player.getAppearance().getAppearanceCache()[i].changeColor(player.getAttribute("color-val:" + i, player.getAppearance().getAppearanceCache()[i].getColor())); + } + player.getAppearance().sync(); + + } + + /** + * Gets the look value for the index. + * @param player The player. + * @param key The key. + * @param index The index. + * @param currentIndex The current index. + * @param increment The increment. + * @return The look value. + */ + private static int getValue(Player player, String key, int index, int currentIndex, boolean increment) { + int[] array = player.getAttribute("male", player.getAppearance().isMale()) ? MALE_LOOK_IDS[index] : FEMALE_LOOK_IDS[index]; + int val = 0; + if (increment && currentIndex + 1 > array.length -1) { + val = (int) array[0]; + currentIndex = 0; + } else if (!increment && currentIndex -1 < 0) { + val = (int) array[array.length -1]; + currentIndex = array.length -1; + } else if (increment) { + val = (int) array[currentIndex + 1]; + currentIndex++; + } else { + val = (int) array[currentIndex - 1]; + currentIndex--; + } + player.setAttribute(key + ":" + index, currentIndex); + return val; + } + + //Male head ids : Script - 701 [0: 1 1: 2 2: 3 3: 4 4: 5 5: 6 6: 7 7: 8 8: 9 91: 10 92: 11 93: 12 94: 13 95: 14 96: 15 97: 16 261: 17 262: 18 263: 19 264: 20 265: 21 266: 22 267: 23 268: 24 ] + //Female head ids: Script - 689 [45: 1 46: 2 47: 3 48: 4 49: 5 50: 6 51: 7 52: 8 53: 9 54: 10 135: 11 136: 12 137: 13 138: 14 139: 15 140: 16 141: 17 142: 318 143: 19 144: 20 145: 21 146: 22 269: 23 270: 24 271: 25 272: 26 273: 27 274: 28 275: 29 276: 30 277: 31 278: 32 279: 33 280: 34 ] + //Male jaw ids: Script - 703 [10: 1 11: 2 12: 3 13: 4 14: 5 15: 6 16: 7 17: 8 98: 9 99: 10 100: 11 101: 12 102: 13 103: 14 104: 15 305: 16 306: 17 307: 18 308: 19 ] + //Male torso ids: Script - 1128 [19: 1 20: 2 21: 3 22: 4 23: 5 24: 6 25: 7 111: 8 112: 9 113: 10 114: 11 115: 12 116: 13 ] + //Female torso ids: Script - 1129 [57: 1 58: 2 59: 3 60: 4 153: 5 154: 6 155: 7 156: 8 157: 9 158: 10 ] + //Male arm ids: Script - 1130 [27: 1 28: 2 29: 3 30: 4 31: 5 105: 6 106: 7 107: 8 108: 9 109: 10 110: 11 ] + //Female arm ids: Script - 1131 [62: 1 63: 2 64: 3 65: 4 147: 5 148: 6 149: 7 150: 8 151: 9 152: 10 ] + //Male hand ids: Script - 1132 [34: 1 84: 2 117: 3 118: 4 119: 5 120: 6 121: 7 122: 8 123: 9 124: 10 125: 11 126: 12 ] + //Female hand ids: Script - 1133 [68: 1 127: 2 159: 3 160: 4 161: 5 162: 6 163: 7 164: 8 165: 9 166: 10 167: 11 168: 12 ] + //Male leg ids: Script - 1134 [37: 1 38: 2 39: 3 40: 4 85: 5 86: 6 87: 7 88: 8 89: 9 90: 10 ] + //Female leg ids: Script - 1135 [71: 1 72: 2 73: 3 74: 4 75: 5 76: 6 77: 7 128: 8 129: 9 130: 10 131: 11 132: 12 133: 13 134: 14 ] + //Male feet ids: Script - 1136 [43: 1 ] + //Female feet ids: Script - 1137 [80: 1 ] + +} + diff --git a/Server/src/main/content/region/misc/zanaris/dialogue/BlaecDialogue.kt b/Server/src/main/content/region/misc/zanaris/dialogue/BlaecDialogue.kt new file mode 100644 index 0000000..ce6c7f4 --- /dev/null +++ b/Server/src/main/content/region/misc/zanaris/dialogue/BlaecDialogue.kt @@ -0,0 +1,42 @@ +package content.region.misc.zanaris.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class BlaecDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + when ((1..3).random()) { + 1 -> npc(FacialExpression.FRIENDLY,"Wunnerful weather we're having today!").also { stage = 99 } + 2 -> npc(FacialExpression.FRIENDLY,"Greetin's, " + player.username + ", fine day today!").also { stage = 99 } + 3 -> npcl(FacialExpression.ANNOYED,"Please leave me alone, I'm busy trapping the pygmy shrews.").also { stage = 99 } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return BlaecDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.BLAEC_3115) + } +} diff --git a/Server/src/main/content/region/misc/zanaris/dialogue/CoOrdinatorDialogue.kt b/Server/src/main/content/region/misc/zanaris/dialogue/CoOrdinatorDialogue.kt new file mode 100644 index 0000000..2d19084 --- /dev/null +++ b/Server/src/main/content/region/misc/zanaris/dialogue/CoOrdinatorDialogue.kt @@ -0,0 +1,47 @@ +package content.region.misc.zanaris.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class CoOrdinatorDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + player(FacialExpression.FRIENDLY, "Hello, what are you doing?").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> { + when ((1..5).random()) { + 1 -> npcl(FacialExpression.OLD_DISTRESSED,"Sorry, I don't have time for idle chit-chat, I need to find a Winter Fairy to send to Trollheim!").also { stage = 99 } + 2 -> npcl(FacialExpression.OLD_DISTRESSED,"Sorry, I don't have time for idle chit-chat, I need to send a fairy to get little Freddie's tooth!").also { stage = 99 } + 3 -> npcl(FacialExpression.OLD_DISTRESSED,"Sorry, I don't have time for idle chit-chat, I need to send an Autumn Fairy off to Burthorpe!").also { stage = 99 } + 4 -> npcl(FacialExpression.OLD_DISTRESSED,"Sorry, I don't have time to talk, I need to send a Tooth Fairy to visit Sarah-Jane!").also { stage = 99 } + 5 -> npcl(FacialExpression.OLD_DISTRESSED,"Sorry, I don't have time to stop, I need to send a weather fairy off to Etceteria!").also { stage = 99 } + } + } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return CoOrdinatorDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.CO_ORDINATOR_3302) + } +} diff --git a/Server/src/main/content/region/misc/zanaris/dialogue/FairyChefDialogue.kt b/Server/src/main/content/region/misc/zanaris/dialogue/FairyChefDialogue.kt new file mode 100644 index 0000000..8db8031 --- /dev/null +++ b/Server/src/main/content/region/misc/zanaris/dialogue/FairyChefDialogue.kt @@ -0,0 +1,38 @@ +package content.region.misc.zanaris.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class FairyChefDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npcl(FacialExpression.OLD_DEFAULT,"'Ello, sugar. I'm afraid I can't gossip right now, I've got a cake in the oven.").also { stage = 99 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return FairyChefDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.FAIRY_CHEF_3322, NPCs.FAIRY_CHEF_3323) + } +} diff --git a/Server/src/main/content/region/misc/zanaris/dialogue/FairyDialogue.kt b/Server/src/main/content/region/misc/zanaris/dialogue/FairyDialogue.kt new file mode 100644 index 0000000..ff10ef1 --- /dev/null +++ b/Server/src/main/content/region/misc/zanaris/dialogue/FairyDialogue.kt @@ -0,0 +1,53 @@ +package content.region.misc.zanaris.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class FairyDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + when ((1..7).random()) { + 1 -> npcl(FacialExpression.OLD_CALM_TALK1,"Err, hello. Do you have any idea what a Winter Fairy actually does?").also { stage = 10 } + 2 -> npcl(FacialExpression.OLD_DISTRESSED,"Have you got any idea where Burthorpe is? The co-ordinator says I need to go there and paint all the leaves yellow, but I've never heard of that place!").also { stage = 99 } + 3 -> npcl(FacialExpression.OLD_DISTRESSED,"Be careful when you pick mushrooms near the strange ruins to the south. Some of them will try to eat you!").also { stage = 99 } + 4 -> npcl(FacialExpression.OLD_DISTRESSED,"I'm afraid I can't stop to chat. I've just been told to get ready to go to Etceteria for some reason or other!").also { stage = 99 } + 5 -> npcl(FacialExpression.OLD_CALM_TALK2,"Picking mushrooms near the forge will probably end quite badly for you. Not as bad as the ones by the strange ruins to the south though. They're much bigger.").also { stage = 99 } + 6 -> npc(FacialExpression.OLD_DISTRESSED,"Sorry, I can't talk I'm looking for Sarah-Jane!").also { stage = 99 } + 7 -> npc(FacialExpression.OLD_CALM_TALK2,"Is your name Freddie, and are you losing your teeth?").also { stage = 20 } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 10 -> player(FacialExpression.THINKING, "No, no idea at all.").also { stage++ } + 11 -> npcl(FacialExpression.OLD_DISTRESSED,"Oh, pity. Neither do I, but I'm supposed to be one this week.").also { stage = 99 } + + 20 -> player(FacialExpression.THINKING, "Err, no. I'm afraid not.").also { stage++ } + 21 -> npcl(FacialExpression.OLD_CALM_TALK2, "Oh, right. You don't have any idea where I can find him do you?").also { stage++ } + 22 -> player(FacialExpression.NEUTRAL, "No, I don't know that either.").also { stage++ } + 23 -> npcl(FacialExpression.OLD_CALM_TALK1, "Oh, ok then. If you do find out please let me know. The co-ordinator has sent me to find him.").also { stage = 99 } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return FairyDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.FAIRY_4443, NPCs.FAIRY_4444, NPCs.FAIRY_4445, NPCs.FAIRY_4446, NPCs.FAIRY_567, NPCs.FAIRY_57) + } +} diff --git a/Server/src/main/content/region/misc/zanaris/dialogue/FairyFixit.kt b/Server/src/main/content/region/misc/zanaris/dialogue/FairyFixit.kt new file mode 100644 index 0000000..f0e851c --- /dev/null +++ b/Server/src/main/content/region/misc/zanaris/dialogue/FairyFixit.kt @@ -0,0 +1,72 @@ +package content.region.misc.zanaris.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class FairyFixit(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + + //tempvar + //post quest dialogue is missing for rs3 and osrs is too modern, so i'm just gonna use osrs as a placeholder + var completedFairyQueen = false + if (completedFairyQueen) { + npc(FacialExpression.OLD_CALM_TALK1, "Pssst! Human! I've got something for you.").also { stage = 20 } + } else { + npc(FacialExpression.OLD_DISTRESSED, "What is it, human? Busy busy busy!").also { stage = 0 } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> options("Why are you carrying that toolbox?", "I'm okay, thanks.").also { stage++ } + 1 -> when (buttonId){ + 1 -> player(FacialExpression.ASKING,"Why are you carrying that toolbox?").also { stage = 10 } + 2 -> player(FacialExpression.FRIENDLY, "I'm okay, thanks.").also { stage = 99 } + } + + + 10 -> npc(FacialExpression.OLD_DEFAULT, "It's the fizgog! It's picking up cable again!").also { stage++ } + 11 -> playerl(FacialExpression.ASKING, "Uh, right. So is it safe to use the fairy rings then?").also { stage++ } + 12 -> npcl(FacialExpression.OLD_CALM_TALK1, "Sure, as long as you have been given permission to use them. You should just be aware that using the fairy rings sometimes has strange results - the locations that you have been to may").also { stage++ } + 13 -> npcl(FacialExpression.OLD_CALM_TALK2, "affect the locations you are trying to reach. I could fix it by replacing the fizgog and the whosprangit; I've put in a request for some new parts, but they're").also { stage++ } + 14 -> npc(FacialExpression.OLD_CALM_TALK1, "pretty hard to get hold of it seems.").also { stage = 99 } + + 20 -> options("What have you got for me?", "Why are you carrying that toolbox?", "Not interested, thanks.").also { stage++ } + 21 -> when (buttonId) { + 1 -> player(FacialExpression.ASKING, "What have you got for me?").also { stage = 30 } + 2 -> player(FacialExpression.ASKING,"Why are you carrying that toolbox?").also { stage = 10 } + 3 -> player(FacialExpression.NEUTRAL, "Not interested, thanks.").also { stage = 99 } + } + + 30 -> npcl(FacialExpression.OLD_CALM_TALK1, "They said you'd helped cure our Queen. I haven't got a lot of rewards to offer, but my enchantment scrolls might help if you're working with fairy rings in your home.").also { stage++ } + 31 -> { + end() + npc.openShop(player) + } + + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return FairyFixit(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.FAIRY_FIXIT_4455) + } +} diff --git a/Server/src/main/content/region/misc/zanaris/dialogue/FairyQueenDialogue.kt b/Server/src/main/content/region/misc/zanaris/dialogue/FairyQueenDialogue.kt new file mode 100644 index 0000000..7154caa --- /dev/null +++ b/Server/src/main/content/region/misc/zanaris/dialogue/FairyQueenDialogue.kt @@ -0,0 +1,70 @@ +package content.region.misc.zanaris.dialogue + +import core.api.isQuestComplete +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs +import content.data.Quests + +@Initializable +class FairyQueenDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun newInstance(player: Player?): DialoguePlugin { + return FairyQueenDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + + if (!isQuestComplete(player, Quests.FAIRYTALE_II_CURE_A_QUEEN)) { + options( + "How do crops and such survive down here?", "What's so good about this place?" + ).also { stage = START_DIALOGUE } + } else { + playerl( + FacialExpression.ASKING, "Have you managed to work out a plan yet?" + ).also { stage = 3 } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> when (buttonId) { + 1 -> playerl( + FacialExpression.ASKING, "How do crops and such survive down here?" + ).also { stage = 1 } + + 2 -> playerl( + FacialExpression.ASKING, "What's so good about this place?" + ).also { stage = 2 } + } + + 1 -> npcl( + FacialExpression.OLD_DEFAULT, + "Clearly you come from a plane dependent on sunlight. Down here, the plants grow in the aura of faerie." + ).also { stage = END_DIALOGUE } + + 2 -> npcl( + FacialExpression.OLD_DEFAULT, + " Zanaris is a meeting point of cultures. Those from many worlds converge here to exchange knowledge and goods." + ).also { stage = END_DIALOGUE } + + 3 -> npcl( + FacialExpression.OLD_DEFAULT, + "Not yet," + player.username + ", but it looks like we'll need to ask you for your help again, I'm afraid. I'll be able to tell you more once we have finished making our battle plans." + ).also { stage = END_DIALOGUE } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.FAIRY_QUEEN_4437) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/misc/zanaris/dialogue/FairyShopAssistantDialogue.kt b/Server/src/main/content/region/misc/zanaris/dialogue/FairyShopAssistantDialogue.kt new file mode 100644 index 0000000..ea0d18c --- /dev/null +++ b/Server/src/main/content/region/misc/zanaris/dialogue/FairyShopAssistantDialogue.kt @@ -0,0 +1,44 @@ +package content.region.misc.zanaris.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class FairyShopAssistantDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npc(FacialExpression.OLD_HAPPY,"Can I help you at all?").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> options("Yes please. What are you selling?", "No thanks.").also { stage++ } + + 1 -> when (buttonId) { + 1 -> end().also { npc.openShop(player) } + 2 -> player(FacialExpression.NEUTRAL, "No thanks.").also { stage = 99 } + } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return FairyShopAssistantDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.FAIRY_SHOP_ASSISTANT_535, NPCs.FAIRY_SHOPKEEPER_534) + } +} diff --git a/Server/src/main/content/region/misc/zanaris/handlers/EvilChickenLairListener.kt b/Server/src/main/content/region/misc/zanaris/handlers/EvilChickenLairListener.kt new file mode 100644 index 0000000..bdc5698 --- /dev/null +++ b/Server/src/main/content/region/misc/zanaris/handlers/EvilChickenLairListener.kt @@ -0,0 +1,53 @@ +package content.region.misc.zanaris.handlers + +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items +import org.rs09.consts.Scenery +import content.data.Quests + +class EvilChickenLairListener: InteractionListener { + override fun defineListeners() { + + addClimbDest(Location.create(2441, 4381, 0), Location.create(2457, 4380, 0)) + addClimbDest(Location.create(2455, 4380, 0), Location.create(2441, 4381, 0)) + + onUseWith(IntType.SCENERY, Items.RAW_CHICKEN_2138, Scenery.CHICKEN_SHRINE_12093) { player, _, _ -> + if (!hasRequirement(player, Quests.LEGENDS_QUEST)) + return@onUseWith false + + if(removeItem(player,(Item(Items.RAW_CHICKEN_2138)))){ + animate(player, Animation(10100)) + + submitWorldPulse(object : Pulse(1, player) { + override fun pulse(): Boolean { + teleport(player, Location.create(2461, 4356, 0)) + animate(player, Animation(9013)) + return true + } + }) + } + return@onUseWith true + } + onUseWith(IntType.SCENERY, Items.EGG_1944, Scenery.CHICKEN_SHRINE_12093) { player, _, _ -> + sendMessage(player, "Nice idea, but nothing interesting happens.") + return@onUseWith true + } + onUseWith(IntType.SCENERY, Items.ROPE_954, Scenery.TUNNEL_ENTRANCE_12253) { player, _, node -> + if(removeItem(player, Item(Items.ROPE_954))) + replaceScenery(node as core.game.node.scenery.Scenery, Scenery.TUNNEL_ENTRANCE_12254, 100) + return@onUseWith true + } + + on(Scenery.PORTAL_12260, IntType.SCENERY, "use") { player, _ -> + teleport(player, Location.create(2453, 4476, 0)) + return@on true + } + + } +} diff --git a/Server/src/main/content/region/misc/zanaris/handlers/FairyRingPlugin.kt b/Server/src/main/content/region/misc/zanaris/handlers/FairyRingPlugin.kt new file mode 100644 index 0000000..72a003a --- /dev/null +++ b/Server/src/main/content/region/misc/zanaris/handlers/FairyRingPlugin.kt @@ -0,0 +1,68 @@ +package content.region.misc.zanaris.handlers + +import content.global.handlers.iface.FairyRingInterface +import core.api.anyInEquipment +import core.api.hasRequirement +import core.api.openInterface +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.TeleportManager.TeleportType +import core.game.world.map.Location +import org.rs09.consts.Items +import content.data.Quests + +/** + * Handles interactions with fairy rings + * @author Ceikry + */ + +private val RINGS = intArrayOf(12095, 14058, 14061, 14064, 14067, 14070, 14073, 14076, 14079, 14082, 14085, 14088, 14091, 14094, 14097, 14100, 14103, 14106, 14109, 14112, 14115, 14118, 14121, 14124, 14127, 14130, 14133, 14136, 14139, 14142, 14145, 14148, 14151, 14154, 14157, 14160, 16181, 16184, 23047, 27325, 37727) +private const val MAIN_RING = 12128 +private const val ENTRY_RING = 12094 +private const val MARKETPLACE_RING = 12003 + +class FairyRingPlugin : InteractionListener { + + override fun defineListeners() { + + on(RINGS, IntType.SCENERY, "use"){ player, _ -> + if (!fairyMagic(player)) return@on true + val mainRingLocation = Location.create(2412, 4434, 0) + player.teleporter.send(mainRingLocation, TeleportType.FAIRY_RING) + return@on true + } + on(MAIN_RING, IntType.SCENERY, "use"){ player, _ -> + if (!fairyMagic(player)) return@on true + openFairyRing(player) + return@on true + } + on(ENTRY_RING, IntType.SCENERY, "use") { player, _ -> + val lumbridgeSwampShed = Location.create(3203, 3168, 0) + player.teleporter.send(lumbridgeSwampShed, TeleportType.FAIRY_RING) + return@on true + } + on(MARKETPLACE_RING, IntType.SCENERY, "use"){ player, _ -> + val alKharidBank = Location.create(3260, 3156, 0) + player.teleporter.send(alKharidBank, TeleportType.FAIRY_RING) + return@on true + } + + } + + private fun fairyMagic(player: Player) : Boolean { + if (!hasRequirement(player, Quests.FAIRYTALE_I_GROWING_PAINS)) { // should be converted to a FTP2 stage requirement once FTP2 is implemented + player.sendMessage("The fairy ring is inert.") + return false + } + if (!anyInEquipment(player, Items.DRAMEN_STAFF_772, Items.LUNAR_STAFF_9084)) { + player.sendMessage("The fairy ring only works for those who wield fairy magic.") + return false + } + return true + } + + private fun openFairyRing(player: Player) { + openInterface(player, FairyRingInterface.RINGS_IFACE) + } +} diff --git a/Server/src/main/content/region/misc/zanaris/handlers/ZanarisPlugin.java b/Server/src/main/content/region/misc/zanaris/handlers/ZanarisPlugin.java new file mode 100644 index 0000000..4179ab8 --- /dev/null +++ b/Server/src/main/content/region/misc/zanaris/handlers/ZanarisPlugin.java @@ -0,0 +1,189 @@ +package content.region.misc.zanaris.handlers; + +import core.cache.def.impl.SceneryDefinition; +import core.plugin.Initializable; +import core.game.dialogue.DialogueInterpreter; +import core.game.dialogue.DialoguePlugin; +import core.game.global.action.DoorActionHandler; +import content.global.skill.crafting.gem.Gems; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.TeleportManager.TeleportType; +import core.game.node.scenery.Scenery; +import core.game.world.map.Location; +import core.plugin.Plugin; +import core.plugin.ClassScanner; + +/** + * Handles the zanaris city plugin. + * @author Vexia + */ +@Initializable +public final class ZanarisPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ClassScanner.definePlugin(new MagicDoorDialogue()); + SceneryDefinition.forId(12094).getHandlers().put("option:use", this); + SceneryDefinition.forId(12045).getHandlers().put("option:open", this); + SceneryDefinition.forId(12047).getHandlers().put("option:open", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + switch (node.getId()) { + case 12094: + player.getWalkingQueue().reset(); + player.getWalkingQueue().addPath(2452, 4473); + player.getTeleporter().send(Location.create(3201, 3169, 0), TeleportType.FAIRY_RING); + break; + case 12045: + case 12047: + if ((node.getId() == 12045 && node.getLocation().equals(new Location(2469, 4438, 0)) && player.getLocation().getX() >= 2470) || player.getLocation().getY() < 4434 && (node.getId() == 12045 || node.getId() == 12047 && node.getLocation().equals(new Location(2465, 4434, 0))) || node.getId() == 12047 && player.getLocation().getX() >= 2470) { + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + return true; + } + player.getDialogueInterpreter().open(MagicDoorDialogue.NAME, node); + break; + } + return true; + } + + /** + * Handles the magic door dialogue. + * @author Vexia + */ + public final class MagicDoorDialogue extends DialoguePlugin { + + /** + * The dialogue name. + */ + public static final String NAME = "tax door"; + + /** + * The object. + */ + private Scenery door; + + /** + * Constructs a new {@code MagicDoorDialogue} {@code Object}. + */ + public MagicDoorDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code MagicDoorDialogue} {@code Object}. + * @param player the player. + */ + public MagicDoorDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new MagicDoorDialogue(player); + } + + @Override + public boolean open(Object... args) { + door = (Scenery) args[0]; + npc("You may not pass through this door without paying the", "trading tax."); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + player("So how much is the tax?"); + stage++; + break; + case 1: + npc("The cost is one diamond."); + stage++; + break; + case 2: + options("Okay...", "A diamond? Are you crazy?", "I haven't brought my diamonds with me.", "What do you do with all the diamonds you get?"); + stage++; + break; + case 3: + switch (buttonId) { + case 1: + player("Okay..."); + stage = 10; + break; + case 2: + player("A diamond? Are you crazy?"); + stage = 20; + break; + case 3: + player("I haven't brought my diamonds with me."); + stage = 30; + break; + case 4: + player("What do you do with all the diamonds you get?"); + stage = 40; + break; + } + break; + case 10: + if (!player.getInventory().containsItem(Gems.DIAMOND.getGem())) { + player("...but..."); + stage = 11; + } else { + end(); + if (player.getInventory().remove(Gems.DIAMOND.getGem())) { + DoorActionHandler.handleAutowalkDoor(player, door); + player.getPacketDispatch().sendMessage("You give the doorman a diamond."); + } + } + break; + case 11: + player("I haven't brought my diamonds with me."); + stage = 30; + break; + case 20: + npc("Not at all. Those are the rules."); + stage++; + break; + case 21: + end(); + break; + case 30: + npc("No tax, no entry."); + stage++; + break; + case 31: + end(); + break; + case 40: + npc("Ever heard of fairylights? Well how do you think we", "make 'em? First we collect a pile of gems and then we", "get a spider to spin 'em into a long web, we light the", "jewels by imbuing each one with a little bit of magic."); + stage++; + break; + case 41: + player("So you're telling me fairylights are made out of gems?"); + stage++; + break; + case 42: + npc("That's right, how else could we make 'em twinkle so", "beautifully?"); + stage++; + break; + case 43: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 3321, DialogueInterpreter.getDialogueKey(NAME) }; + } + + } +} diff --git a/Server/src/main/content/region/misthalin/barbvillage/dialogue/BarbarianDialogue.java b/Server/src/main/content/region/misthalin/barbvillage/dialogue/BarbarianDialogue.java new file mode 100644 index 0000000..a8573df --- /dev/null +++ b/Server/src/main/content/region/misthalin/barbvillage/dialogue/BarbarianDialogue.java @@ -0,0 +1,87 @@ +package content.region.misthalin.barbvillage.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the dialogue plugin used for barbarians. + * @author 'Vexia + * @version 1.5 + */ +@Initializable +public final class BarbarianDialogue extends DialoguePlugin { + + /** + * Represents the barbarian npc ids. + */ + private static final int[] IDS = new int[] { 12, 3246, 3247, 3248, 3249, 3250, 3251, 3252, 3253, 3255, 3256, 3257, 3258, 3259, 3260, 3261, 3262, 3263, 5909 }; + + /** + * Constructs a new {@code BarbarianDialogue} {@code Object}. + */ + public BarbarianDialogue() { + /** + * empty + */ + } + + /** + * Constructs a new {@code BarbarianDialogue} {@code Object}. + * @param player the player. + */ + public BarbarianDialogue(final Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new BarbarianDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "What do you want, outerlander?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "Let's fight!", "Goodbye."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Let's fight!"); + stage = 20; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Goodbye."); + stage = 10; + break; + } + break; + case 10: + end(); + break; + case 20: + end(); + npc.getProperties().getCombatPulse().attack(player); + break; + } + return true; + } + + @Override + public int[] getIds() { + return IDS; + } + +} diff --git a/Server/src/main/content/region/misthalin/barbvillage/dialogue/GunthorBraveDialogue.java b/Server/src/main/content/region/misthalin/barbvillage/dialogue/GunthorBraveDialogue.java new file mode 100644 index 0000000..79e14b9 --- /dev/null +++ b/Server/src/main/content/region/misthalin/barbvillage/dialogue/GunthorBraveDialogue.java @@ -0,0 +1,57 @@ +package content.region.misthalin.barbvillage.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the gunthor brave dialogue. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class GunthorBraveDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code GunthorBraveDialogue} {@code Object}. + */ + public GunthorBraveDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code GunthorBraveDialogue} {@code Object}. + * @param player the player. + */ + public GunthorBraveDialogue(final Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new GunthorBraveDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + npc("You look funny."); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + npc.getProperties().getCombatPulse().attack(player); + end(); + return true; + } + + @Override + public int[] getIds() { + return new int[] { 199 }; + } + +} diff --git a/Server/src/main/content/region/misthalin/barbvillage/dialogue/LitaraDialogue.java b/Server/src/main/content/region/misthalin/barbvillage/dialogue/LitaraDialogue.java new file mode 100644 index 0000000..6922724 --- /dev/null +++ b/Server/src/main/content/region/misthalin/barbvillage/dialogue/LitaraDialogue.java @@ -0,0 +1,118 @@ +package content.region.misthalin.barbvillage.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the dialogue plugin used for the litara npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class LitaraDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code LitaraDialogue} {@code Object}. + */ + public LitaraDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code LitaraDialogue} {@code Object}. + * @param player the player. + */ + public LitaraDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new LitaraDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hello there. You look lost - are you okay?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "I'm looking for stronghold, or something.", "I'm fine, just passing through."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'm looking for a stronghold, or something."); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'm fine, just passing through."); + stage = 20; + break; + } + + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ahh, the Strnghold of Security. It's down there."); + stage = 11; + break; + case 11: + interpreter.sendDialogue("Litara points to the hole in the ground that looks", "like you could squeeze, through."); + stage = 12; + break; + case 12: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Looks kind of ...deep and dark."); + stage = 13; + break; + case 13: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Yeah, tell that to my brother. He still hasn't come back."); + stage = 14; + break; + case 14: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Your brother?"); + stage = 15; + break; + case 15: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "He's an explorer too. When the miner fell down that hole", "he'd made and came back babbling about treasure, my", "brother went to explore. No one has seen him since."); + stage = 16; + break; + case 16: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Oh, that's not good."); + stage = 17; + break; + case 17: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Lots of people have been down there, but none of them", "have seen him. Let me know if you do, will you?"); + stage = 18; + break; + case 18: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'll certainly keep my eyes open."); + stage = 19; + break; + case 19: + end(); + break; + case 20: + end(); + break; + } + + return true; + } + + @Override + public int[] getIds() { + return new int[] { 4376 }; + } +} diff --git a/Server/src/main/content/region/misthalin/barbvillage/dialogue/PeksaDialogue.kt b/Server/src/main/content/region/misthalin/barbvillage/dialogue/PeksaDialogue.kt new file mode 100644 index 0000000..f40c15c --- /dev/null +++ b/Server/src/main/content/region/misthalin/barbvillage/dialogue/PeksaDialogue.kt @@ -0,0 +1,64 @@ +package content.region.misthalin.barbvillage.dialogue + +import content.region.kandarin.quest.scorpioncatcher.SCPeksaDialogue +import content.region.kandarin.quest.scorpioncatcher.ScorpionCatcher +import core.api.getQuestStage +import core.api.openDialogue +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.IfTopic +import core.game.dialogue.Topic +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs +import content.data.Quests + +@Initializable +class PeksaDialogue(player: Player? = null) : DialoguePlugin(player){ + + companion object { + const val GO_SHOPPING = 10 + const val LEAVE = 20 + const val DIALOGUE_SCORPION_CATCHER = 30 + } + + override fun open(vararg args: Any): Boolean { + npc = args[0] as NPC + npcl(FacialExpression.HALF_GUILTY, "Are you interested in buying or selling a helmet?").also { stage = START_DIALOGUE } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + START_DIALOGUE -> { + showTopics( + Topic("I could be, yes.", GO_SHOPPING), + Topic("No, I'll pass on that.", LEAVE), + IfTopic("I've heard you have a small scorpion in your possession.", DIALOGUE_SCORPION_CATCHER, getQuestStage(player, Quests.SCORPION_CATCHER) == ScorpionCatcher.QUEST_STATE_OTHER_SCORPIONS) + ) + } + + GO_SHOPPING -> { + end() + npc.openShop(player) + } + + LEAVE -> { + npcl(FacialExpression.HALF_GUILTY, "Well, come back if you change your mind.").also { stage = END_DIALOGUE } + } + + DIALOGUE_SCORPION_CATCHER -> { + openDialogue(player, SCPeksaDialogue(getQuestStage(player, Quests.SCORPION_CATCHER)), npc) + } + } + + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.PEKSA_538) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/barbvillage/dialogue/SigurdDialogue.java b/Server/src/main/content/region/misthalin/barbvillage/dialogue/SigurdDialogue.java new file mode 100644 index 0000000..29677bb --- /dev/null +++ b/Server/src/main/content/region/misthalin/barbvillage/dialogue/SigurdDialogue.java @@ -0,0 +1,151 @@ +package content.region.misthalin.barbvillage.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Handles the Sigurd dialogue. + * @author 'Vexia + */ +@Initializable +public class SigurdDialogue extends DialoguePlugin { + + public SigurdDialogue() { + + } + + public SigurdDialogue(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[] { 3329 }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "Who are you?", "Can you teach me about canoeing?"); + stage = 2; + break; + case 2: + + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Who are you?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "It's really quite simple. Just walk down to that", "tree on the water bank and chop it down."); + stage = 24; + break; + } + + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I'm Sigurd the Great and Brainy."); + stage = 11; + break; + case 11: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Why do they call you the Great and Brainy?"); + stage = 12; + break; + case 12: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Because I Iinvented the Log Canoe!"); + stage = 13; + break; + case 13: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Log Canoe?"); + stage = 14; + break; + case 14: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Yeash! Me and my cousins were having a great", "party by the river when we decided to have a", " game of 'Smack The SeasonDefinitions'"); + stage = 15; + break; + case 15: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Smack the SeasonDefinitions?"); + stage = 16; + break; + case 16: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "It's a game were you take it in turnsh shmacking", " a tree. First one to uproot the tree winsh!"); + stage = 17; + break; + case 17: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Anyway, I won the game with a flying tackle.", " The tree came loose and down the river bank I went", " still holding the tree."); + stage = 18; + break; + case 18: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I woke up a few hours later and found myself", "several miles down river. and thatsh how I", "invented the log canoe!"); + stage = 19; + break; + case 19: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "So you invented the 'Log Canoe' by falling into a river", "hugging a tree?"); + stage = 20; + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Well I refined the design from the original", "you know!"); + stage = 21; + break; + case 21: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I cut all the branches off to make it more", "comfortable. I could tell you how to if you like?"); + stage = 22; + break; + case 22: + interpreter.sendOptions("Select an Option", "Yes", "No"); + stage = 23; + break; + case 23: + + switch (buttonId) { + case 1: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "It's really quite simple. Just walk down to that tree", "on the water bank and chop it down."); + stage = 24; + break; + case 2: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Okay, if you change your mind you know where", "to find me."); + stage = 25; + break; + } + + break; + case 24: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Then take your axe to it and shape it how you", "like!"); + stage = 26; + break; + case 26: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "You look like you know your way around a", "tree, you can you can make many canoes."); + stage = 27; + break; + case 27: + end(); + break; + case 25: + end(); + break; + case 100: + break; + } + + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new SigurdDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ha Ha! Hello!"); + stage = 0; + return true; + } +} diff --git a/Server/src/main/content/region/misthalin/barbvillage/handlers/BarbarianNPC.java b/Server/src/main/content/region/misthalin/barbvillage/handlers/BarbarianNPC.java new file mode 100644 index 0000000..def8e11 --- /dev/null +++ b/Server/src/main/content/region/misthalin/barbvillage/handlers/BarbarianNPC.java @@ -0,0 +1,56 @@ +package content.region.misthalin.barbvillage.handlers; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.npc.AbstractNPC; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.tools.RandomFunction; + +/** + * Rerepsents a barbarian npc. + * @author 'Vexia + */ +@Initializable +public final class BarbarianNPC extends AbstractNPC { + + /** + * The NPC ids of NPCs using this plugin. + */ + private static final int[] ID = { 12, 3246, 3247, 3248, 3249, 3250, 3251, 3252, 3253, 3255, 3256, 3257, 3258, 3259, 3260, 3261, 3262, 3263, 5909 }; + + /** + * Constructs a new {@code BarbarianNPC} {@code Object}. + */ + public BarbarianNPC() { + super(0, null, true); + } + + /** + * Constructs a new {@code BarbarianNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + private BarbarianNPC(int id, Location location) { + super(id, location, true); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new BarbarianNPC(id, location); + } + + @Override + public void onImpact(final Entity entity, final BattleState state) { + if (RandomFunction.random(8) == 1) { + sendChat("YEEEEEEEEAARRRGGGGHHHHHHHH"); + } + super.onImpact(entity, state); + } + + @Override + public int[] getIds() { + return ID; + } + +} diff --git a/Server/src/main/content/region/misthalin/barbvillage/stronghold/BoxOfHealthDialogue.java b/Server/src/main/content/region/misthalin/barbvillage/stronghold/BoxOfHealthDialogue.java new file mode 100644 index 0000000..3647f08 --- /dev/null +++ b/Server/src/main/content/region/misthalin/barbvillage/stronghold/BoxOfHealthDialogue.java @@ -0,0 +1,73 @@ +package content.region.misthalin.barbvillage.stronghold; + +import core.api.Container; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.emote.Emotes; +import org.rs09.consts.Items; + +import static core.api.ContentAPIKt.addItem; + +/** + * Represents the dialogue plugin used for the box of health. + * @author 'Vexia + * @version 1.0 + */ +public final class BoxOfHealthDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code BoxOfHealth} {@code Object}. + */ + public BoxOfHealthDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code BoxOfHealth} {@code Object}. + * @param player the player. + */ + public BoxOfHealthDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new BoxOfHealthDialogue(player); + } + + @Override + public boolean open(Object... args) { + interpreter.sendDialogue("The box hinges creak and appear to be forming audible words...."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + if (!addItem(player, Items.COINS_995, 5000, Container.INVENTORY)) { + player.getPacketDispatch().sendMessage("You don't have enough inventory space."); + end(); + break; + } + stage = 1; + interpreter.sendDialogue("...congratulations adventurer, you have been deemed worthy of this", "reward. You have also unlocked the Idea emote!"); + player.getEmoteManager().unlock(Emotes.IDEA); + player.getSavedData().getGlobalData().getStrongHoldRewards()[2] = true; + break; + case 1: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 96878 }; + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/barbvillage/stronghold/CatableponNPC.java b/Server/src/main/content/region/misthalin/barbvillage/stronghold/CatableponNPC.java new file mode 100644 index 0000000..776f5d1 --- /dev/null +++ b/Server/src/main/content/region/misthalin/barbvillage/stronghold/CatableponNPC.java @@ -0,0 +1,75 @@ +package content.region.misthalin.barbvillage.stronghold; + +import core.game.node.entity.combat.spell.CombatSpell; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.equipment.SwitchAttack; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.node.entity.combat.MultiSwingHandler; + +/** + * Represents the catablepon npc type. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class CatableponNPC extends AbstractNPC { + + /** + * Represents the NPC ids of NPCs using this plugin. + */ + private static final int[] ID = { 4397, 4398, 4399 }; + + /** + * Represents the animation to use. + */ + private static final Animation ANIMATION = new Animation(4272); + + /** + * Represents the swing handler. + */ + private final MultiSwingHandler combatHandler = new MultiSwingHandler(new SwitchAttack(CombatStyle.MELEE.getSwingHandler(), null).setUseHandler(true), new SwitchAttack(CombatStyle.MELEE.getSwingHandler(), null).setUseHandler(true), new SwitchAttack(CombatStyle.MELEE.getSwingHandler(), null).setUseHandler(true), new SwitchAttack(CombatStyle.MAGIC.getSwingHandler(), ANIMATION).setUseHandler(true)); + + /** + * Constructs a new {@code CatableponNPC} {@code Object}. + */ + public CatableponNPC() { + super(0, null); + } + + /** + * Constructs a new {@code CatableponNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + private CatableponNPC(int id, Location location) { + super(id, location); + this.setAggressive(true); + } + + @Override + public void configure() { + super.configure(); + super.getProperties().setSpell((CombatSpell) SpellBook.MODERN.getSpell(7)); + super.getProperties().setAutocastSpell((CombatSpell) SpellBook.MODERN.getSpell(7)); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new CatableponNPC(id, location); + } + + @Override + public CombatSwingHandler getSwingHandler(boolean swing) { + return combatHandler; + } + + @Override + public int[] getIds() { + return ID; + } +} diff --git a/Server/src/main/content/region/misthalin/barbvillage/stronghold/CradleOfLifeDialogue.java b/Server/src/main/content/region/misthalin/barbvillage/stronghold/CradleOfLifeDialogue.java new file mode 100644 index 0000000..9ff2f02 --- /dev/null +++ b/Server/src/main/content/region/misthalin/barbvillage/stronghold/CradleOfLifeDialogue.java @@ -0,0 +1,173 @@ +package content.region.misthalin.barbvillage.stronghold; + +import core.game.container.Container; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.emote.Emotes; +import core.game.node.item.Item; + +/** + * Represents the dialogue plugin used for the cradle of life. + * @author 'Vexia + * @version 1.0 + */ +public final class CradleOfLifeDialogue extends DialoguePlugin { + + /** + * Represents the items related to the cradle of life. + */ + private static final Item[] ITEMS = new Item[] { new Item(9005, 1), new Item(9006, 1) }; + + /** + * Constructs a new {@code CradleOfLife} {@code Object}. + */ + public CradleOfLifeDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code CradleOfLife} {@code Object}. + * @param player the player. + */ + public CradleOfLifeDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new CradleOfLifeDialogue(player); + } + + @Override + public boolean open(Object... args) { + if (player.getSavedData().getGlobalData().getStrongHoldRewards()[3] && player.getSavedData().getGlobalData().getStrongHoldRewards()[2] && player.getSavedData().getGlobalData().getStrongHoldRewards()[1] && player.getSavedData().getGlobalData().getStrongHoldRewards()[0]) { + // Unlocks emotes for older accounts who don't have the previous level emotes + player.getEmoteManager().unlock(Emotes.FLAP); + player.getEmoteManager().unlock(Emotes.SLAP_HEAD); + player.getEmoteManager().unlock(Emotes.IDEA); + } + if (player.getInventory().freeSlots() == 0) { + player.getPacketDispatch().sendMessage("You don't have enough inventory space."); + end(); + return true; + } + if (player.getSavedData().getGlobalData().getStrongHoldRewards()[3]) { + interpreter.sendDialogue("As your hand touches the cradle, you hear a voice in your head of a", "million dead adventurers...."); + stage = 100; + return true; + } + interpreter.sendDialogue("As your hand touches the cradle, you hear a voice in your head of a", "million dead adventurers...."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogue("....welcome adventurer... you have a choice...."); + stage = 1; + break; + case 1: + interpreter.sendDoubleItemMessage(9005, 9006, "You can choose between these two pair of boots."); + stage = 2; + break; + case 2: + interpreter.sendDialogue("They will both protect your feet exactly the same, however they look", "very different. You can always come back and get another pair if", "you lose them, or even swap them for the other style!"); + stage = 4; + break; + case 4: + interpreter.sendOptions("Choose your style of boots", "I'll take the colourful ones!", "I'll take the fighting ones!"); + stage = 5; + break; + case 5: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'll take the colourful ones!"); + player.getInventory().add(ITEMS[0]); + player.getEmoteManager().unlock(Emotes.STOMP); + stage = 6; + player.getSavedData().getGlobalData().getStrongHoldRewards()[3] = true; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'll take the fighting ones!"); + player.getInventory().add(ITEMS[1]); + player.getEmoteManager().unlock(Emotes.STOMP); + player.getSavedData().getGlobalData().getStrongHoldRewards()[3] = true; + stage = 6; + break; + } + break; + case 6: + interpreter.sendDialogue("Congratulations! You have succesfully navigated the Stronghold of", "Security and learned to secure your account. You have unlocked", "the 'Stamp Foot' emote. Remember to keep your account secure in", "the future!"); + stage = 7; + break; + case 7: + end(); + break; + + case 100: + if (!player.getInventory().contains(9005, 1) && !player.getBank().contains(900, 1) && !player.getEquipment().contains(9005, 1) && !player.getInventory().contains(9006, 1) && !player.getBank().contains(9006, 1) && !player.getEquipment().contains(9006, 1)) { + interpreter.sendDialogue("You appear to have lost your boots!"); + stage = 101; + } else { + interpreter.sendOptions("Select an Option", "Yes, I'd like the other pair instead please!", "No thanks, I'll keep these!"); + stage = 200; + } + break; + case 200: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Yes, I'd like the other pair instead please!"); + stage = 800; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No thanks, I'll keep these!"); + stage = 900; + break; + } + break; + case 800: + if (!swap(player.getInventory())) { + if (!swap(player.getEquipment())) { + swap(player.getBank()); + } + } + end(); + break; + case 900: + end(); + break; + case 101: + interpreter.sendDialogue("....welcome adventurer... you have a choice...."); + stage = 1; + break; + } + return true; + } + + /** + * Method used to swap a pair of boots. + * @param container the container. + * @return {@code True} if swapped. + */ + public boolean swap(Container container) { + if (container.contains(9005, 1)) { + container.replace(new Item(9006), container.getSlot(ITEMS[0])); + return true; + } + if (container.contains(9006, 1)) { + container.replace(ITEMS[0], container.getSlot(ITEMS[1])); + return true; + } + return false; + } + + @Override + public int[] getIds() { + return new int[] { 96873 }; + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/barbvillage/stronghold/GiftOfPeaceDialogue.java b/Server/src/main/content/region/misthalin/barbvillage/stronghold/GiftOfPeaceDialogue.java new file mode 100644 index 0000000..1adee05 --- /dev/null +++ b/Server/src/main/content/region/misthalin/barbvillage/stronghold/GiftOfPeaceDialogue.java @@ -0,0 +1,73 @@ +package content.region.misthalin.barbvillage.stronghold; + +import core.api.Container; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.emote.Emotes; +import core.game.node.item.Item; +import org.rs09.consts.Items; + +import static core.api.ContentAPIKt.addItem; + +/** + * Represents the gift of peace dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +public final class GiftOfPeaceDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code GiftOfPeaceDialogue} {@code Object}. + */ + public GiftOfPeaceDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code GiftOfPeaceDialogue} {@code Object}. + * @param player the player. + */ + public GiftOfPeaceDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new GiftOfPeaceDialogue(player); + } + + @Override + public boolean open(Object... args) { + interpreter.sendDialogue("The box hinges creak and appear to be forming audible words...."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + if (!addItem(player, Items.COINS_995, 2000, Container.INVENTORY)) { + player.getPacketDispatch().sendMessage("You don't have enough inventory space."); + end(); + break; + } + interpreter.sendDialogue("...congratulations adventurer, you have been deemed worthy of this", "reward. You have also unlocked the Flap emote!"); + stage = 1; + player.getEmoteManager().unlock(Emotes.FLAP); + player.getSavedData().getGlobalData().getStrongHoldRewards()[0] = true; + break; + case 1: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 54678 }; + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/barbvillage/stronghold/GrainOfPlentyDialogue.java b/Server/src/main/content/region/misthalin/barbvillage/stronghold/GrainOfPlentyDialogue.java new file mode 100644 index 0000000..8cef49b --- /dev/null +++ b/Server/src/main/content/region/misthalin/barbvillage/stronghold/GrainOfPlentyDialogue.java @@ -0,0 +1,74 @@ +package content.region.misthalin.barbvillage.stronghold; + +import core.api.Container; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.emote.Emotes; +import core.game.node.item.Item; +import org.rs09.consts.Items; + +import static core.api.ContentAPIKt.addItem; + +/** + * Represents the grain of plenty dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +public final class GrainOfPlentyDialogue extends DialoguePlugin { + + + /** + * Constructs a new {@code GrainOfPlenty} {@code Object}. + */ + public GrainOfPlentyDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code GrainOfPlenty} {@code Object}. + * @param player the player. + */ + public GrainOfPlentyDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new GrainOfPlentyDialogue(player); + } + + @Override + public boolean open(Object... args) { + interpreter.sendDialogue("The grain shifts in the sack, sighing audible words...."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + if (!addItem(player, Items.COINS_995, 3000, Container.INVENTORY)) { + player.getPacketDispatch().sendMessage("You don't have enough inventory space."); + end(); + break; + } + player.getSavedData().getGlobalData().getStrongHoldRewards()[1] = true; + interpreter.sendDialogue("...congratualtions adventurer, you have been deemed worthy of this", "reward. You have also unlocked the Slap Head emote!"); + stage = 1; + player.getEmoteManager().unlock(Emotes.SLAP_HEAD); + break; + case 1: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 56875 }; + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/barbvillage/stronghold/SkullSceptreDialogue.java b/Server/src/main/content/region/misthalin/barbvillage/stronghold/SkullSceptreDialogue.java new file mode 100644 index 0000000..a2926a5 --- /dev/null +++ b/Server/src/main/content/region/misthalin/barbvillage/stronghold/SkullSceptreDialogue.java @@ -0,0 +1,70 @@ +package content.region.misthalin.barbvillage.stronghold; + +import core.game.dialogue.DialoguePlugin; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * @author 'Vexia + */ +@Initializable +public class SkullSceptreDialogue extends DialoguePlugin { + + public SkullSceptreDialogue() { + + } + + public SkullSceptreDialogue(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[] { 78489 }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + end(); + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new SkullSceptreDialogue(player); + } + + @Override + public boolean open(Object... args) { + interpreter.sendItemMessage(9009, "The two halves of the skull fit perfectly."); + if (args.length == 1) { + interpreter.sendItemMessage(9012, "The two halves of the sceptre fit perfectly.");// The + // Sceptre", "appears + // to + // be + // designed + // to + // have + // something + // on + // top."); + return true; + } + if (args.length == 2) { + interpreter.sendItemMessage(9013, "The skull fits perfectly atop the Sceptre.");// The + // Sceptre", "appears + // to + // be + // designed + // to + // have + // something + // on + // top."); + return true; + } + stage = 0; + return true; + } + +} diff --git a/Server/src/main/content/region/misthalin/barbvillage/stronghold/StrongHoldSecurityPlugin.java b/Server/src/main/content/region/misthalin/barbvillage/stronghold/StrongHoldSecurityPlugin.java new file mode 100644 index 0000000..c6de2b3 --- /dev/null +++ b/Server/src/main/content/region/misthalin/barbvillage/stronghold/StrongHoldSecurityPlugin.java @@ -0,0 +1,998 @@ +package content.region.misthalin.barbvillage.stronghold; + +import core.cache.def.impl.SceneryDefinition; +import core.game.component.Component; +import core.game.component.ComponentPlugin; +import core.game.dialogue.DialogueInterpreter; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.global.action.ClimbActionHandler; +import core.game.global.action.DoorActionHandler; +import core.game.interaction.Option; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.music.MusicPlayer; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneBuilder; +import core.game.world.update.flag.context.Animation; +import core.net.packet.PacketRepository; +import core.net.packet.context.MusicContext; +import core.net.packet.out.MusicPacket; +import core.plugin.Plugin; +import core.plugin.ClassScanner; +import core.plugin.Initializable; +import core.tools.RandomFunction; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playAudio; + +/** + * Handles the strong hold of security. + * @author Vexia + */ +@Initializable +public final class StrongHoldSecurityPlugin extends MapZone implements Plugin { + + /** + * The portal data to use. + */ + private static final Object[][] PORTALS = new Object[][] { { 16150, Location.create(1914, 5222, 0) }, { 16082, Location.create(2021, 5223, 0) }, { 16116, Location.create(2146, 5287, 0) }, { 16050, Location.create(2341, 5219, 0) } }; + + /** + * Constructs a new {@code StrongHoldSecurityPlugin} {@code Object}. + */ + public StrongHoldSecurityPlugin() { + super("strong hold of security", true); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ZoneBuilder.configure(this); + ClassScanner.definePlugin(new ExplorerDialogue()); + ClassScanner.definePlugin(new StrongholdDialogue()); + ClassScanner.definePlugin(new GrainOfPlentyDialogue()); + ClassScanner.definePlugin(new GiftOfPeaceDialogue()); + ClassScanner.definePlugin(new CradleOfLifeDialogue()); + ClassScanner.definePlugin(new BoxOfHealthDialogue()); + ClassScanner.definePlugin(new OptionHandler() { + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(16154).getHandlers().put("option:climb-down", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + flagDoor(player, false); + ClimbActionHandler.climb(player, new Animation(828), Location.create(1859, 5243, 0)); + player.getDialogueInterpreter().open(70099, "You squeeze through the hole and find a ladder a few feet down", "leading into the Stronghold of Security."); + return true; + } + }); + return this; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public boolean interact(Entity e, Node target, Option option) { + if (e instanceof Player) { + final Player player = (Player) e; + switch (target.getId()) { + case 16148:// ladder + ladder(player, Location.create(3081, 3421, 0)); + player.getPacketDispatch().sendMessage("You climb up the ladder to the surface."); + return true; + case 16146:// ladder. + ladder(player, new Location(1859, 5243, 0)); + player.getPacketDispatch().sendMessage("You climb the ladder which seems to twist and wind in all directions."); + return true; + case 16078:// ladder + ladder(player, new Location(2042, 5245, 0)); + player.getPacketDispatch().sendMessage("You climb the ladder which seems to twist and wind in all directions."); + return true; + case 16080:// lader + ladder(player, Location.create(1859, 5243, 0)); + return true; + case 16048:// bone chain. + ladder(player, Location.create(3081, 3421, 0)); + player.getPacketDispatch().sendMessage("You climb the ladder which seems to twist and wind in all directions."); + return true; + case 16049:// boney ladder to get to third floor. + ladder(player, Location.create(2123, 5252, 0)); + return true; + case 16112:// third vine. + ladder(player, Location.create(2123, 5252, 0)); + player.getPacketDispatch().sendMessage("You climb the ladder which seems to twist and wind in all directions."); + return true; + case 16114:// third ladder. + ladder(player, Location.create(2042, 5245, 0)); + player.getPacketDispatch().sendMessage("You climb up the ladder to the level above."); + return true; + case 16081:// second ladder going down. + openComponent(player, Location.create(2123, 5252, 0)); + return true; + case 16115:// third ladder going down. + openComponent(player, Location.create(2358, 5215, 0)); + return true; + case 16149:// fourth ladder going down. + openComponent(player, Location.create(2042, 5245, 0)); + return true; + case 16135:// Gift of Peace 1st level + if (player.getSavedData().getGlobalData().hasStrongholdReward(1)) { + player.getDialogueInterpreter().open(70099, "You have already claimed your reward from this level."); + } else { + playAudio(player, Sounds.DOOR_CREAK_61); + PacketRepository.send(MusicPacket.class, new MusicContext(player, 157, true)); + player.getDialogueInterpreter().open(54678); + } + return true; + case 16118:// Box of health 3rd level + if (player.getSavedData().getGlobalData().hasStrongholdReward(3)) { + player.getDialogueInterpreter().open(70099, "You have already claimed your reward from this level."); + } else { + playAudio(player, Sounds.DOOR_CREAK_61); + PacketRepository.send(MusicPacket.class, new MusicContext(player, 177, true)); + player.getDialogueInterpreter().open(96878); + } + return true; + case 16077:// Grain of Plenty 2nd level + if (player.getSavedData().getGlobalData().hasStrongholdReward(2)) { + player.getDialogueInterpreter().open(70099, "You have already claimed your reward from this level."); + } else { + playAudio(player, Sounds.DOOR_CREAK_61); + PacketRepository.send(MusicPacket.class, new MusicContext(player, 179, true)); + player.getDialogueInterpreter().open(56875); + } + return true; + case 16047:// Cradle of Life 4th level + if (!player.getSavedData().getGlobalData().hasStrongholdReward(4)) { + PacketRepository.send(MusicPacket.class, new MusicContext(player, 158, true)); + } + playAudio(player, Sounds.SOS_CHOIR_1246); + player.getDialogueInterpreter().open(96873); + return true; + case 16152:// skeleton + player.getDialogueInterpreter().open(16152); + return true; + case 16150: + case 16082: + case 16116: + case 16050: + handlePortal(player, (Scenery) target); + return true; + case 16123: + case 16124: + case 16126: + case 16127: + case 16065: + case 16066: + case 16067: + case 16068: + case 16089: + case 16090: + case 16092: + case 16043: + case 16044: + case 16045: + case 16046: + handleDoor(player, (Scenery) target); + return true; + } + } + return super.interact(e, target, option); + } + + /** + * Handles a ladder in strong hold. + * @param player the player. + * @param destination the destination. + */ + private void ladder(final Player player, final Location destination) { + ClimbActionHandler.climb(player, new Animation(828), destination); + } + + /** + * Handles a portal. + * @param player the player. + */ + private void handlePortal(final Player player, final Scenery object) { + final int index = getPortalIndex(object.getId()); + if (!player.getSavedData().getGlobalData().hasStrongholdReward(index + 1)) { + player.getPacketDispatch().sendMessage("You are not of sufficient experience to take the shortcut through this level."); + } else { + player.getProperties().setTeleportLocation((Location) PORTALS[index][1]); + player.getPacketDispatch().sendMessage("You enter the portal to be whisked through to the treasure room."); + } + } + + /** + * Handles a stronghold of security door. + * @param player the player. + * @param object the object. + */ + private static void handleDoor(final Player player, final Scenery object) { + final boolean force = isForced(player, object); + if (force || RandomFunction.random(40) < 2) { + openDoor(player, object); + return; + } + player.getDialogueInterpreter().open("strong-hold", object); + } + + /** + * Opens the door. + * @param player the player. + * @param object the object. + */ + private static void openDoor(final Player player, final Scenery object) { + player.lock(3); + player.animate(Animation.create(4282)); + playAudio(player, Sounds.SOS_THROUGH_DOOR_2858); + GameWorld.getPulser().submit(new Pulse(1, player) { + int counter; + + @Override + public boolean pulse() { + switch (++counter) { + case 1: + final java.awt.Point p = DoorActionHandler.getRotationPoint(object.getRotation()); + Location destination = !player.getLocation().equals(object.getLocation()) ? object.getLocation() : object.getLocation().transform((int) p.getX(), (int) p.getY(), 0); + player.getProperties().setTeleportLocation(destination); + break; + case 2: + player.animate(new Animation(4283)); + flagDoor(player, !isFlagged(player)); + return true; + } + return false; + } + }); + } + + /** + * Opens the component. + * @param player the player. + * @param location the location. + */ + private void openComponent(Player player, Location location) { + final Component component = new Component(579); + component.setPlugin(new StrongholdComponentPlugin(location)); + player.getInterfaceManager().open(component); + } + + /** + * Flags a door as set or not. + * @param player the player. + * @param completed if completed. + */ + private static void flagDoor(Player player, boolean completed) { + player.setAttribute("/save:strong-hold:door", completed); + } + + /** + * Checks if the door is flagged. + * @param player the player. + * @return {@code True} if flagged. + */ + private static boolean isFlagged(final Player player) { + return player.getAttribute("strong-hold:door", false); + } + + /** + * Checks if a door is forced to let you through. + * @param player the player. + * @param object the object. + * @return {@code True} if its forced. + */ + private static boolean isForced(final Player player, final Scenery object) { + if (player.inCombat() || player.getProperties().getCombatPulse().isAttacking()) { + return true; + } + return isFlagged(player); + } + + /** + * Gets the portal index. + * @param id the id. + * @return the portal index. + */ + private int getPortalIndex(int id) { + for (int i = 0; i < PORTALS.length; i++) { + if ((int) PORTALS[i][0] == id) { + return i; + } + } + return 0; + } + + @Override + public void configure() { + register(new ZoneBorders(1836, 5174, 1930, 5257));// first level. + register(new ZoneBorders(1977, 5176, 2066, 5265));// second level. + register(new ZoneBorders(2090, 5246, 2197, 5336));// third level. + register(new ZoneBorders(2297, 5166, 2391, 5261));// fourth level. + } + + /** + * Handles the strong hold dialogues. + * @author Vexia + */ + public static final class StrongholdDialogue extends DialoguePlugin { + + /** + * The door being interacted with. + */ + private Scenery door; + + /** + * The npc id. + */ + private int npcId; + + /** + * Constructs a new {@code StrongholdDialogue} {@code Object}. + * @param player the player. + */ + public StrongholdDialogue(final Player player) { + super(player); + } + + /** + * Constructs a new {@code StrongholdDialogue} {@code Object}. + */ + public StrongholdDialogue() { + /** + * empty. + */ + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new StrongholdDialogue(player); + } + + @Override + public boolean open(Object... args) { + door = (Scenery) args[0]; + npcId = getNpcId(door.getName()); + if (player.getLocation().getX() == 1859 && player.getLocation().getY() == 5239 || player.getLocation().getX() == 1858 && player.getLocation().getY() == 5239) { + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Greetings Adventurer. This place is kept safe by the", "spirits within the doors. As you pass through you will be", "asked questions about security. Hopefully you will learn", "much from us."); + stage = 900; + return true; + } + final int rand = RandomFunction.random(0, 18); + switch (rand) { + case 0: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "To pass you must answer me this: What do I do if a", "moderator asks me for my account details?"); + stage = 100; + break; + case 1: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "To pass you must answer me this: My friend uses this", "great add-on program he got from a website, should I?"); + stage = 1000; + break; + case 2: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "To pass you must answer me this: Who is it ok to", "share my account with?"); + stage = 200; + break; + case 3: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "To pass you must answer me this: Why do I need to", "type in recovery questions?"); + stage = 300; + break; + case 4: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "To pass you must answer me this: Who is it ok to", "share my account with?"); + stage = 400; + break; + case 5: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "To pass you must answer me this: Who can I give my", "password to?"); + stage = 500; + break; + case 6: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "To pass you must answer me this: How will " + GameWorld.getSettings().getName() + "", "contact me if I have been chosen to be a moderator?"); + stage = 600; + break; + case 7: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "To pass you must answer me this: How often should", "you change your recovery questions?"); + stage = 700; + break; + case 8: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "To pass you must answer me this: A website says I", "can become a player moderator by giving", "them my password what do I do?"); + stage = 800; + break; + case 9: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "To pass you must answer me this: Will " + GameWorld.getSettings().getName() + " block me", "from saying my PIN in game?"); + stage = 1900; + break; + case 10: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "To pass you must answer me this: Can I leave my", "account logged in while I'm out of the room?"); + stage = 1100; + break; + case 11: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "To pass you must answer me this: Where should I", "enter my " + GameWorld.getSettings().getName() + " Password?"); + stage = 1111; + break; + case 12: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "To pass you must answer me this: What is an", "example of a good bank PIN?"); + stage = 1200; + break; + case 13: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "To pass you must answer me this: What do I do if I", "think I have a keylogger or virus?"); + stage = 1300; + break; + case 14: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "To pass you must answer me this: Recovery answers", "should be..."); + stage = 1400; + break; + case 15: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "To pass you must answer me this: What do you do", "if someone tells you that you have won the " + GameWorld.getSettings().getName() + "", "Lottery and asks for your password or recoveries?"); + stage = 1500; + break; + case 16: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "To pass you must answer me this: What should I", "do if I think someone knows my recoveries?"); + stage = 1600; + break; + case 17: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "To pass you must answer me this: What do you do", "if someone asks you for your password or recoveries", "to make you a player moderator?"); + stage = 1700; + break; + case 18: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "To pass you must answer me this: Where can i", "find cheats for " + GameWorld.getSettings().getName() + "?"); + stage = 1800; + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 900: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Please pass through and begin your adventure, beware", "of the various monsters that dwell within."); + stage = 901; + break; + case 901: + openDoor(player, door); + interpreter.sendDialogues(player, FacialExpression.OLD_NORMAL, "Oh my! I just got sucked through that door... what a", "weird feeling! Still, I guess I should expect it as these", "evidently aren't your average kind of doors.... they talk", "and look creepy!"); + stage = 902; + break; + case 902: + end(); + break; + case 100: + interpreter.sendOptions("Select an Option", "Tell them whatever they want to know.", "Politely tell them no.", "Politely tell them no and then use the 'Report Abuse' button."); + stage = 101; + break; + case 101: + switch (buttonId) { + case 1: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Wrong! Never give your account details to anyone!", "This includes things like recovery answers, contact", "details and passwords. Never use personal details for", "recoveries or bank PINs!"); + stage = 99; + break; + case 2: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Ok! Don't tell them the details. But reporting the", "incident to " + GameWorld.getSettings().getName() + " would help. Use the Report Abuse", "button. Never use personal details for recoveries or", "bank PINs!"); + stage = 69; + break; + case 3: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Correct! Report any attempt to gain your account", "details as it is a very serious breach of " + GameWorld.getSettings().getName() + "'s", "rules. Never use personal details for recoveries or bank", "PINs!"); + stage = 69; + break; + } + break; + case 99: + end(); + break; + case 1000: + interpreter.sendOptions("Select an Option", "No, it might steal my password.", "I'll gave it a try and see if I like it.", "Sure, he's used it alot, so can I."); + stage = 10001; + break; + case 10001: + switch (buttonId) { + case 1: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Correct! The only safe add-on for " + GameWorld.getSettings().getName() + " is the Window", "client available from our " + GameWorld.getSettings().getName() + " Website."); + stage = 69; + break; + case 2: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Wrong! Some programs steal your password without", "you even knowing, this only requires running the", "program once, even if you don't use it."); + stage = 99; + break; + case 3: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Wrong! The program may steal your password and is", "against the rules to use."); + stage = 99; + break; + } + break; + case 200: + + interpreter.sendOptions("Select an Option", "My friends.", "Relatives.", "Nobody."); + stage = 201; + break; + case 201: + switch (buttonId) { + case 1: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Wrong! You account may only be used by you."); + stage = 99; + break; + case 2: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Wrong! Your account may only be used by you."); + stage = 99; + break; + case 3: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Correct! You, can you only may use your account."); + stage = 69; + break; + } + break; + case 300: + interpreter.sendOptions("Select an Option", "To help me recover my password if I forget it or it is stolen.", "To let " + GameWorld.getSettings().getName() + " know more about its players.", "To see if I can type in random letters on my keyboard."); + stage = 301; + break; + case 301: + switch (buttonId) { + case 1: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Correct! Your recovery questions will help " + GameWorld.getSettings().getName() + " staff protect", "and return your account if it is stolen. Never use personal", "details for recoveries or bank PINs!"); + stage = 69; + break; + case 2: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Wrong! " + GameWorld.getSettings().getName() + " values players opinons, but we use polls", "and forums to see what you think. The recoveries are not there to gain personal", "information about anybody but to protect your account.", "Never use personal details"); + stage = 99; + break; + case 3: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Wrong! Typing random letters into your recoveries", "won't help you or the " + GameWorld.getSettings().getName() + " staff - you'll never", "remember them anyway! Never use personal details for", "recoveries or bank PINs!"); + stage = 99; + break; + } + break; + case 400: + interpreter.sendOptions("Select an Option", "My friends", "Relatives", "Nobody"); + stage = 401; + break; + case 401: + switch (buttonId) { + case 1: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Wrong! You account may only be used by you."); + stage = 99; + break; + case 2: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Wrong! You account may only be used by you."); + stage = 99; + break; + case 3: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Correct! You, and you only may use your account."); + stage = 69; + break; + } + break; + case 500: + interpreter.sendOptions("Select an Option", "My friends", "My brother", "Nobody"); + stage = 501; + break; + case 501: + switch (buttonId) { + case 1: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Wrong! Your password should be kept secret from", "everyone. You should *never* give it out under any", "circumstances."); + stage = 99; + break; + case 2: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Wrong! Your password should be kept secret from", "everyone. You should *never* give it out under any", "circumstances."); + stage = 99; + break; + case 3: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Correct! Your password should be kept secret from", "everyone. You should *never* give it out under any", "circumstances."); + stage = 69; + break; + } + break; + case 600: + interpreter.sendOptions("Select an Option", "Email.", "Website popup.", "Game Inbox on the " + GameWorld.getSettings().getName() + " Website."); + stage = 601; + break; + case 601: + switch (buttonId) { + case 1: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Wrong! " + GameWorld.getSettings().getName() + " never uses email to contact you, this is a", "scam and a fake, do not reply to it and delete it", "straight away. " + GameWorld.getSettings().getName() + " will only contact you through your", "Game Inbox avaibale on our website."); + stage = 99; + break; + case 2: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Wrong! " + GameWorld.getSettings().getName() + " would never use such an insecure", "method to pick you. We will contact you through your", "Game Inbox available on our website."); + stage = 99; + break; + case 3: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Correct! We only contact our players via the game", "Inbox which you can access from our " + GameWorld.getSettings().getName() + "", "website."); + stage = 69; + break; + } + break; + case 700: + interpreter.sendOptions("Select an Option", "Never", "Every couple of months", "Every day"); + stage = 701; + break; + case 701: + switch (buttonId) { + case 1: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Never changing your recovery questions will lead to", "an insecure account due to keyloggers or friends knowing", "enough about you to guess them. Don't use personal details for your recoveries."); + stage = 99; + break; + case 2: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Correct! it is the ideal option to change your questions", "but make sure you can remember the answers!", "Don't use personal details for your recoveries."); + stage = 69; + break; + case 3: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Normally recovery questions will take 14 days to", "become active, so there's no point in changing them", "everyday! Don't use personal details for your", "recoveries."); + stage = 99; + break; + } + break; + case 800: + interpreter.sendOptions("Select an Option", "Nothing.", "Give them my password.", "Don't tell them anything and inform " + GameWorld.getSettings().getName() + " through the game website."); + stage = 801; + break; + case 801: + switch (buttonId) { + case 1: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "This is one solution, however someone will fall for", "this scam sooner or later. Tell us about it through", "the " + GameWorld.getSettings().getName() + " website. Remember that moderators are hand", "picked by " + GameWorld.getSettings().getName() + "."); + stage = 69; + break; + case 2: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Wrong! This will almost certainly lead to your accout", "being hijacked. No website can make you a moderator", "as they are hand picked by " + GameWorld.getSettings().getName() + "."); + stage = 99; + break; + case 3: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Correct! By informing us we can have the site taken", "down so other people will not have their accounts", "hijacked by this scam."); + stage = 69; + break; + } + break; + case 1900: + interpreter.sendOptions("Select an Option", "Yes.", "No."); + stage = 1901; + break; + case 1901: + switch (buttonId) { + case 1: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Wrong! " + GameWorld.getSettings().getName() + " does NOT block your PIN so don't type", "it!"); + stage = 99; + break; + case 2: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Correct! " + GameWorld.getSettings().getName() + " will not block your PIN so don't type", "it! Never use personal details for reccoveries or bank", "PINs!"); + stage = 69; + break; + } + break; + case 1100: + interpreter.sendOptions("Select an Option", "Yes.", "No.", "If I'm going to be quick."); + stage = 1101; + break; + case 1101: + switch (buttonId) { + case 1: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Wrong! You should logout in case you are attacked or", "receive a random event. Leaving your character logged", "in can also allow someone to steal your items or entire account!"); + stage = 99; + break; + case 2: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Correct! This is the safest, both in terms of security", "and keeping your items! Leaving you character logged", "in can also allow someone to steal your items or entitre", "account!"); + stage = 69; + break; + case 3: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Wrong! You should logout in case you are attacked or", "receive a random event. Leaving your character logged", "in can also allow someone to steal your items or entire account!"); + stage = 99; + break; + } + break; + case 1111: + interpreter.sendOptions("Select an Opion", "On " + GameWorld.getSettings().getName() + " and all fansites.", "Only on the " + GameWorld.getSettings().getName() + " website.", "On all websites I visit."); + stage = 1112; + break; + case 1112: + switch (buttonId) { + case 1: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Wrong! Always use a unique password purely for your " + GameWorld.getSettings().getName() + " account."); + stage = 99; + break; + case 2: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Correct! Always make sure you are entering your", "password only on the " + GameWorld.getSettings().getName() + " Website as other sites", "may try to steal it."); + stage = 69; + break; + case 3: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Wrong! This is very insecure and will may lead to", "your account being stolen."); + stage = 99; + break; + } + break; + case 1200: + interpreter.sendOptions("Select an Option", "Your real life bank PIN.", "Your birthday.", "The birthday of a famous person or event."); + stage = 1201; + break; + case 1201: + switch (buttonId) { + case 1: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "This is a bad idea as if someone happens to find out your bank", "PIN on " + GameWorld.getSettings().getName() + ", they then have acces to your bank account."); + stage = 99; + break; + case 2: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Not a good idea because you know how many presents", "you get for your birthday. So you can imagine how", "many people know this date. Never use personal details", "for recoveries or bank PINs!"); + stage = 99; + break; + case 3: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Well done! Unless you tell someone, they are unlikely", "to guess who or what you have chosen, and you can", "always look it up, Never use personal details for recoveries or", "bank PINs!"); + stage = 69; + break; + } + break; + case 1300: + interpreter.sendOptions("Select an Option", "Virus scan my computer then change my password and recoveries.", "Change my password and recoveries then virus scan my computer.", "Nothing, it will go away on its own."); + stage = 1301; + break; + case 1301: + switch (buttonId) { + case 1: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Correct! Removing the keylogger must be the priority", "otherwise anything you type can be given away.", "Remember to change your password and recovery", "questions afterwards."); + stage = 69; + break; + case 2: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Wrong! If you change your password and recoveries", "while you still have the keylogger, they will still be", "insecure. Remove the keylogger first. Never use", "personal details for recoveries or bank PINs!"); + stage = 99; + break; + case 3: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Wrong! This could mean your account may be", "accessed by someone else. Remove the keylogger then", "change your password and recoveries. Never use", "personal details for recoveries or bank PINs!"); + stage = 99; + break; + } + break; + case 1400: + interpreter.sendOptions("Select an Option", "Memorable", "Easy to guess", "Random gibberish"); + stage = 1401; + break; + case 1401: + switch (buttonId) { + case 1: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Correct! A good recovery answer that not many people", "will know, you won't forget, will stay the same and that", "you wouldn't accidentally give away. Remember: Don't", "use personal details for your recoveries."); + stage = 69; + break; + case 2: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "This is a bad idea as anyone who knows you could", "guess them. Remember: Don't use personal details for", "your recoveries."); + stage = 99; + break; + case 3: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "This is a bad idea because it is very difficult to", "remember and you won't be able to recover your", "account! Remember: Don't use personal details for", "your recoveries."); + stage = 99; + break; + } + break; + case 1500: + interpreter.sendOptions("Select an Option", "Give them the information they asked for.", "Don't tell them anything and ignore them."); + stage = 1501; + break; + case 1501: + switch (buttonId) { + case 1: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Wrong! There is no " + GameWorld.getSettings().getName() + " Lottery! Never give", "your account details to anyone. Press the 'Report Abuse'", "button and fill in the offending player's name and", "the correct category.", "Don't tell them anything and click the 'Report Abuse' button."); + stage = 99; + break; + case 2: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Quite good. But we should try to stop scammers.", "So please report them using the 'Report Abuse' button."); + stage = 69; + break; + case 3: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Correct! Press the 'Report Abuse' button and", "fill in the offending player's name and the correct category."); + stage = 69; + break; + } + break; + case 1600: + interpreter.sendOptions("Select an Option", "Tell them never to use them.", "Use the Account Managemnt section on the " + GameWorld.getSettings().getName() + " website.", "'Recover a Lost Password' section on the " + GameWorld.getSettings().getName() + " website."); + stage = 1601; + break; + case 1601: + if (buttonId == 1) { + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Wrong! This does nothing to help the security of your", "account. You should reset your questions through", "the'Lost password' link on our website."); + stage = 99; + } else if (buttonId == 2) { + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Wrong! If you use the Account Management section to", "change your recovery questions, it will take 14 days", "to come into effect, someone may have acces to your", "account this time."); + stage = 99; + } else if (buttonId == 3) { + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Correct! If you provide all the correct information", "this will reset your questions within 24 hours and", "make your account secure again."); + stage = 69; + } + break; + case 1700: + interpreter.sendOptions("Select an Option", " Don't give them any information and send an 'Abuse report'.", "Don't tell them anything and ignore them.", "Give them the information they asked for."); + stage = 1701; + break; + case 1701: + switch (buttonId) { + case 1: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Correct! Press the 'Report Abuse' button and fill", "in the offending player's name and the correct", "category."); + stage = 69; + break; + case 2: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Quite good. But we should try to stop scammers.", "So please report them using the 'Report Abuse'", "button."); + stage = 69; + break; + case 3: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Wrong! " + GameWorld.getSettings().getName() + " never ask for your account", "information especially to become a player moderator.", "Press the 'Report Abuse' button and fill in the offending player's", "name and the correct cattegory."); + stage = 99; + break; + } + break; + case 1800: + interpreter.sendOptions("Select an Option", "On the " + GameWorld.getSettings().getName() + " website.", "By searching the internet.", "Nowhere."); + stage = 1801; + break; + case 1801: + switch (buttonId) { + case 1: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Wrong! There are NO " + GameWorld.getSettings().getName() + " cheats coded", "into the game and any sites claiming to have cheats", "are fakes and may lead to your account being stolen if you", "give them your password."); + stage = 99; + break; + case 2: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Wrong! There are NO " + GameWorld.getSettings().getName() + " cheats coded", "into the game and any sites claiming to have cheats", "are fakes and may lead to your account being stolen if you", "give them your password."); + stage = 99; + break; + case 3: + interpreter.sendDialogues(npcId, FacialExpression.OLD_NORMAL, "Correct! There are NO " + GameWorld.getSettings().getName() + " cheats coded into", "the game. Any sites claiming to have cheats are", "fakes and may lead to your account being stolen if you give", "them your password."); + stage = 69; + break; + } + break; + case 69: + end(); + openDoor(player, door); + break; + } + return true; + } + + /** + * Gets the npc id from the door name. + * @param name the name. + * @return the name. + */ + private int getNpcId(String name) { + switch (name) { + case "Gate of War": + return 4377; + case "Rickety door": + return 4378; + case "Oozing barrier": + return 4379; + case "Portal of Death": + return 4380; + } + return 0; + } + + @Override + public int[] getIds() { + return new int[] { DialogueInterpreter.getDialogueKey("strong-hold") }; + } + + } + + /** + * Represents the explorer dialogue. + * @author 'Vexia + * @version 1.0 + */ + public static final class ExplorerDialogue extends DialoguePlugin { + + /** + * Represents the stronghold notes item. + */ + private static final Item STRONGHOLD_NOTES = new Item(9004); + + /** + * Represents the animation specific to pickpocketing. + */ + private static final Animation ANIMATION = new Animation(881); + + /** + * Constructs a new {@code ExplorerDialogue} {@code Object}. + * @param player the player. + */ + public ExplorerDialogue(final Player player) { + super(player); + } + + /** + * Constructs a new {@code ExplorerDialogue} {@code Object}. + */ + public ExplorerDialogue() { + /** + * empty. + */ + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new ExplorerDialogue(player); + } + + @Override + public boolean open(Object... args) { + player.animate(ANIMATION); + if (player.getInventory().containsItem(STRONGHOLD_NOTES) || player.getBank().containsItem(STRONGHOLD_NOTES)) { + player.getPacketDispatch().sendMessage("You don't find anything."); + end(); + return true; + } + interpreter.sendDialogue("You rummage around in the dead explorer's bag....."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogue("You find a book of hand written notes."); + stage = 1; + break; + case 1: + player.getInventory().add(STRONGHOLD_NOTES, player); + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 16152 }; + } + + } + + /** + * Represents the stronghold component plugin. + * @author 'Vexia + * @version 1.0 + */ + public final class StrongholdComponentPlugin extends ComponentPlugin { + + /** + * Represents the destination. + */ + private final Location destination; + + /** + * Constructs a new {@code StrongholdComponentPlugin} {@code Object}. + * @param destination the destination. + */ + public StrongholdComponentPlugin(final Location destination) { + this.destination = destination; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + return this; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + switch (button) { + case 18: + if (player.getInterfaceManager().close()) + player.getDialogueInterpreter().open(8000, "No thanks, I don't want to die!"); + return true; + case 17: + player.getInterfaceManager().close(); + ladder(player, destination); + player.getPacketDispatch().sendMessage("You climb down the ladder to the next level."); + return true; + } + return true; + } + + } +} diff --git a/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/GuardDialogue.kt b/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/GuardDialogue.kt new file mode 100644 index 0000000..0fc1f9d --- /dev/null +++ b/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/GuardDialogue.kt @@ -0,0 +1,164 @@ +package content.region.misthalin.barbvillage.stronghold.playersafety + +import core.api.runTask +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.world.GameWorld.settings +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class GuardDialogue(player: Player? = null) : DialoguePlugin(player) { + + companion object{ + const val DIALOGUE_COMPLETED = START_DIALOGUE + const val DIALOGUE_NOT_COMPLETED = 50 + + } + + override fun open(vararg args: Any?): Boolean { + val hasRead = player.savedData.globalData.hasReadPlaques() + if (hasRead) { + npcl(FacialExpression.HALF_GUILTY, "Can I help you?").also { stage = DIALOGUE_COMPLETED } + } + else { + npcl(FacialExpression.FURIOUS, "Ahem! Can I help you?").also { stage = DIALOGUE_NOT_COMPLETED } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + DIALOGUE_COMPLETED -> { + playerl( + FacialExpression.HALF_GUILTY, "Can I go upstairs?" + ).also { stage++ } + } + + DIALOGUE_COMPLETED + 1 -> { + npcl( + FacialExpression.FURIOUS, + "Yes, citizen. Before you do I am instructed to give " + + "you one final piece of information" + ).also { stage++ } + } + + DIALOGUE_COMPLETED + 2 -> { + playerl(FacialExpression.HALF_GUILTY, "Oh, okay then.").also { stage++ } + } + + DIALOGUE_COMPLETED + 3 -> { + npcl( + FacialExpression.HALF_GUILTY, + "In your travels around " + settings!!.name + ", should you find a player who acts in a " + + "way that breaks on of our rules, you should report them." + ).also { stage++ } + } + + DIALOGUE_COMPLETED + 4 -> { + npcl( + FacialExpression.HALF_GUILTY, + "Reporting is very simple and easy to do. Simply click the Report Abuse button at " + + "the bottom of the screen and you will be shown the following screen:" + ).also { stage++ } + } + + DIALOGUE_COMPLETED + 5 -> { + player.interfaceManager.openComponent(700) + runTask(player, 5) { + if (player != null) { + player.interfaceManager.close() + } + return@runTask + }.also { stage++ } + } + + DIALOGUE_COMPLETED + 6 -> { + npcl( + FacialExpression.HALF_GUILTY, + "Simply enter the player's name in the box and click the rule that the offender was breaking." + ).also { stage++ } + } + + DIALOGUE_COMPLETED + 7 -> { + playerl(FacialExpression.HALF_GUILTY, "Okay. Then what?").also { stage++ } + } + + DIALOGUE_COMPLETED + 8 -> { + npcl( + FacialExpression.HALF_GUILTY, + "That's it! It really is that simple and it only takes a moment to do. " + + "Now you may enter the training centre. Good luck, citizen." + ).also { stage++ } + } + + DIALOGUE_COMPLETED + 9 -> { + playerl(FacialExpression.HALF_GUILTY, "Thanks!").also { stage = END_DIALOGUE } + } + + DIALOGUE_NOT_COMPLETED -> { + playerl( + FacialExpression.HALF_GUILTY, "I'd like to go up to the training centre please." + ).also { stage++ } + } + DIALOGUE_NOT_COMPLETED + 1 -> { + npcl(FacialExpression.FURIOUS, "Sorry, citizen, you can't go up there.").also { stage++ } + } + DIALOGUE_NOT_COMPLETED + 2 -> { + playerl(FacialExpression.OLD_SNEAKY, "Why not?").also { stage++ } + + } + DIALOGUE_NOT_COMPLETED + 3 -> { + npcl( + FacialExpression.ANNOYED, + "You must learn about player safety before entering the training centre." + ).also { stage++ } + } + DIALOGUE_NOT_COMPLETED + 4 -> { + playerl(FacialExpression.HALF_GUILTY, "Oh. How do I do that?").also { stage++ } + } + DIALOGUE_NOT_COMPLETED + 5 -> { + npcl( + FacialExpression.HALF_GUILTY, + "Each of these gublinches have been caught breaking the rules of " + settings!!.name + ". " + + "You should read the plaques on each of their cells to learn what they did wrong." + ).also { stage++ } + + } + DIALOGUE_NOT_COMPLETED + 6 -> { + playerl( + FacialExpression.HALF_GUILTY, + "Oh, right. I can enter the training centre once I have done that?" + ).also { stage++ } + } + DIALOGUE_NOT_COMPLETED + 7 -> { + npcl( + FacialExpression.HALF_GUILTY, + "Yes. Once you have have examined each of the plaques, come and speak to me " + + "and I will tell you about the Report Abuse function." + ).also { stage++ } + } + DIALOGUE_NOT_COMPLETED + 8 -> { + npcl( + FacialExpression.HALF_GUILTY, + "After that, I can let you into the training centre, upstairs." + ).also { stage++ } + } + DIALOGUE_NOT_COMPLETED + 9 -> { + playerl(FacialExpression.HALF_GUILTY, "Okay, thanks for the help.").also { stage = END_DIALOGUE } + player.sendMessage("You need to read the jail plaques before the guard will allow you upstairs.") + } + } + return true + + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.GUARD_7142) + } + + +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/PlayerSafetyTest.kt b/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/PlayerSafetyTest.kt new file mode 100644 index 0000000..98ad672 --- /dev/null +++ b/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/PlayerSafetyTest.kt @@ -0,0 +1,102 @@ +package content.region.misthalin.barbvillage.stronghold.playersafety + +import core.api.* +import core.game.interaction.InterfaceListener +import core.game.node.entity.player.Player +import core.plugin.Initializable + + +// /** +// * Handles the player safety test. +// * Java version +// * @author Tyler Telis +// * @author Vexia +// * Kotlin +// * @author gregf36665 +// */ +@Initializable +class PlayerSafetyTest : InterfaceListener { + + companion object { + private val testQuestions = listOf( + TestQuestion(697, 26, mapOf(4 to 37, 3 to 40, 5 to 43), 4), + TestQuestion(699, 20, mapOf(4 to 31, 3 to 34), 4), + TestQuestion(707, 20, mapOf(3 to 31, 4 to 35, 5 to 35), 3), + TestQuestion(710, 20, mapOf(9 to 31, 10 to 34), 9), + TestQuestion(704, 26, mapOf(10 to 37, 12 to 43, 11 to 40), 10), + // todo figure out why these 2 are not working + // TestQuestion(694, 20, mapOf(12 to 31, 13 to 34), 13), + // TestQuestion(708, 26, mapOf(12 to 31, 13 to 34), 12), + TestQuestion(696, 20, mapOf(4 to 31, 3 to 34, 5 to 34), 4) + + + ) + private var testQuestionNumber = 0 + } + + /** + * Define a new Test Question + * interfaceId: the base ID for the test question + * baseChild: the ID of the Component child + * answers: A map of button press: child to display + * correctOption: The button number for the correct option + */ + class TestQuestion(val interfaceId: Int, val baseChild : Int, val answers : Map, val correctOption: Int){ + + fun showAnswer(player: Player, button : Int){ + setComponentVisibility(player, interfaceId, baseChild, false) + answers[button]?.let { setComponentVisibility(player, interfaceId, it, false) } + return + } + } + + private fun checkAnswer(player: Player, button: Int){ + val question = testQuestions[testQuestionNumber] + question.showAnswer(player, button) + if (button == question.correctOption){ + testQuestionNumber += 1 + } + } + + private fun completedTest(player: Player) { + closeInterface(player) + player.savedData.globalData.testStage = 2 + sendMessage(player,"Well done! You completed the exams.") + sendDialogue(player, "Congratulations! The test has been completed. " + + "Hand the paper in to Professor Henry for marking.") + } + + fun update(player: Player){ + // Close all open interfaces + closeInterface(player) + // Open the correct one now + testQuestions.forEachIndexed(){ index, testQuestion -> + if (index == testQuestionNumber){ + openInterface(player, testQuestion.interfaceId) + } + } + } + + override fun defineInterfaceListeners() { + onOpen(697) { _, _ -> + testQuestionNumber = 0 // Set the testQuestionNumber back to 0 on first launch + return@onOpen true + } + for (question in testQuestions){ + on(question.interfaceId) { player, _, _, buttonID, _, _ -> + if (buttonID in 0..35) { + checkAnswer(player, buttonID) + } + else{ + update(player) + if (testQuestionNumber == testQuestions.size) { + completedTest(player) + return@on true + } + } + return@on true + } + } + } +} + diff --git a/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/ProfessorHenryDialogue.kt b/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/ProfessorHenryDialogue.kt new file mode 100644 index 0000000..50b4b04 --- /dev/null +++ b/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/ProfessorHenryDialogue.kt @@ -0,0 +1,144 @@ +package content.region.misthalin.barbvillage.stronghold.playersafety + +import core.ServerConstants +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.emote.Emotes +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class ProfessorHenryDialogue(player : Player? = null) : DialoguePlugin(player){ + + companion object{ + const val HAND_IN_TEST = 10 + const val MEETING = 100 + const val GET_TEST = 200 + const val iFace = 277 + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage){ + START_DIALOGUE -> { + if (player.savedData.globalData.testStage == 2 && inInventory(player, Items.TEST_PAPER_12626)){ + // The player has the test and has completed it but need it marked + player("Hello, Professor.").also { stage = HAND_IN_TEST} + } + else if (player.savedData.globalData.testStage >= 3){ + // The player has already had their test marked and taken + npcl(FacialExpression.HAPPY, "Good job ${player.name}, you completed the test!").also { stage = END_DIALOGUE } + return true + } + else{ + player(FacialExpression.NEUTRAL, "Hello.").also { stage = MEETING } + } + } + MEETING -> npcl(FacialExpression.ANNOYED, "Hello what?").also { stage++ } + MEETING + 1 -> playerl(FacialExpression.HALF_GUILTY, "Uh...hello there?").also { stage++ } + MEETING + 2 -> npcl(FacialExpression.HALF_GUILTY, "Hello, 'Professor'. Manners cost nothing, you know. " + + "When you're in my classroom, I ask that you use the proper address for my station.").also { stage++ } + MEETING + 3 -> playerl(FacialExpression.HALF_GUILTY, "Your station?").also { stage++ } + MEETING + 4 -> npcl(FacialExpression.HALF_GUILTY, "Yes. It means 'position', so to speak.").also { stage++ } + MEETING + 5 -> playerl(FacialExpression.HALF_GUILTY, "Oh, okay.").also { stage++ } + MEETING + 6 -> npcl(FacialExpression.HALF_GUILTY, "Now, what can I do for you, exactly?").also { stage++ } + MEETING + 7 -> playerl(FacialExpression.HALF_GUILTY, "What is this place?").also { stage++ } + MEETING + 8 -> npcl(FacialExpression.HALF_GUILTY, "This is the Misthalin Training Centre of Excellence. " + + "It is where bold adventurers, such as yourself, can come to learn of the dangers of " + + "the wide world and gain some valuable experience at the same time.").also { stage++ } + MEETING + 9 -> playerl(FacialExpression.HALF_GUILTY, "What can I do here?").also { stage++ } + MEETING + 10 -> npcl(FacialExpression.HALF_GUILTY, "Here you can take part in the Player Safety test: " + + "a set of valuable lessons to learn about staying safe " + + "in ${ServerConstants.SERVER_NAME}.").also { stage++ } + MEETING + 11 -> npcl(FacialExpression.HALF_GUILTY, "I can give you a test paper to take and, once completed, " + + "you can bring it back to me for marking. Would you like to take the test? " + + "It will not cost you anything.").also { stage++ } + MEETING + 12 -> + showTopics( + Topic("Yes, please.", GET_TEST), + Topic("Not right now, thanks.", END_DIALOGUE) + ) + + GET_TEST -> { + if (player.inventory.isFull) { + npcl(FacialExpression.HALF_GUILTY, "It seems your inventory is full.").also { stage = END_DIALOGUE } + } else if (amountInInventory(player, Items.TEST_PAPER_12626) > 0) { + npcl( + FacialExpression.HALF_GUILTY, + "You already have a test, please fill it out and return it to me." + ).also { stage = END_DIALOGUE } + } else { + player.savedData.globalData.testStage = 1 + addItem(player, Items.TEST_PAPER_12626) + npcl( FacialExpression.HALF_GUILTY, "Right then. Here is the test paper. " + + "When you have completed all the questions, bring it back to me for marking." + ).also { stage ++ } + } + } + GET_TEST + 1 -> playerl(FacialExpression.HALF_GUILTY, "Okay, thanks.").also { stage = END_DIALOGUE } + + HAND_IN_TEST -> npcl(FacialExpression.HAPPY, + "Ah, ${player.name}. How's the test going?").also { stage ++ } + HAND_IN_TEST + 1 -> playerl(FacialExpression.NEUTRAL, "I think I've finished.").also { stage++ } + HAND_IN_TEST + 2 -> npcl(FacialExpression.HAPPY, "Excellent! Let me just mark the paper for you then.").also { stage++ } + HAND_IN_TEST + 3 -> npcl(FacialExpression.HAPPY, "Hmm. Uh-huh, yes I see. Good! Yes, that's right.").also{ stage++ } + HAND_IN_TEST + 4-> npcl(FacialExpression.HAPPY, "Excellent! Allow me to reward you for your work. " + + "I have these two old lamps that you may find useful.").also { stage++ } + // This needs to be npc for word wrap + HAND_IN_TEST + 5 -> npc("Also, there is an old jail block connected to the cells", + "below the training centre, which have been overrun with", + "vicious creatures. If you search around the jail cells", + "downstairs, you should find it easily enough.").also { stage++ } + HAND_IN_TEST + 6 -> npcl(FacialExpression.HAPPY, "Now, your rewards.").also { stage++ } + HAND_IN_TEST + 7 ->{ + // Check for at least 1 slot + // Player will get 2 lamps but we will take the test from them + if (freeSlots(player) >= 1){ + showReward().also { stage = END_DIALOGUE } + } + else { + npcl(FacialExpression.SAD, "You do not have space in your inventory for the rewards").also { stage = END_DIALOGUE } + } + } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.PROFESSOR_HENRY_7143) + } + + private fun showReward(){ + // Show the poster tunnel + setVarp(player, 1203, 1 shl 29, true) + player.savedData.globalData.testStage = 3 + + removeItem(player, Items.TEST_PAPER_12626) + addItem(player, Items.ANTIQUE_LAMP_4447, 2) + player.emoteManager.unlock(Emotes.SAFETY_FIRST) + + openInterface(player, iFace) + + // Clear the other lines + for (i in 9.. 18){ + player.packetDispatch.sendString("", iFace, i) + } + + player.packetDispatch.sendString("You have completed the Player Safety test!", iFace, 4) + player.packetDispatch.sendString(player.getQuestRepository().points.toString() + "", iFace, 7) + + player.packetDispatch.sendString("2 Experience lamps", iFace, 9) + player.packetDispatch.sendString("Access to the Stronghold of", iFace, 10) + player.packetDispatch.sendString("Player Safety Dungeon", iFace, 11) + player.packetDispatch.sendString("The Safety First' emote", iFace, 12) + + + sendItemZoomOnInterface(player, iFace, 5, Items.TEST_PAPER_12626) + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/StrongHoldOfPlayerSafetyListener.kt b/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/StrongHoldOfPlayerSafetyListener.kt new file mode 100644 index 0000000..0b4134a --- /dev/null +++ b/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/StrongHoldOfPlayerSafetyListener.kt @@ -0,0 +1,333 @@ +package content.region.misthalin.barbvillage.stronghold.playersafety + + import core.api.* + import core.game.activity.Cutscene + import core.game.component.Component + import core.game.global.action.DoorActionHandler + import core.game.interaction.IntType + import core.game.interaction.InteractionListener + import core.game.interaction.InterfaceListener + import core.game.node.Node + import core.game.node.entity.player.Player + import core.game.node.entity.player.link.emote.Emotes + import core.game.node.scenery.Scenery + import core.game.world.map.Location + import org.rs09.consts.Items + import org.rs09.consts.NPCs + import org.rs09.consts.Scenery as SceneryConst + + +@Suppress("unused") + class StrongHoldOfPlayerSafetyListener : InteractionListener{ + + companion object{ + private val plaquesToIface = mapOf( // Door to interface + SceneryConst.JAIL_DOOR_29595 to 701, + SceneryConst.JAIL_DOOR_29596 to 703, + SceneryConst.JAIL_DOOR_29597 to 711, + SceneryConst.JAIL_DOOR_29598 to 695, + SceneryConst.JAIL_DOOR_29599 to 312, + SceneryConst.JAIL_DOOR_29600 to 706, + SceneryConst.JAIL_DOOR_29601 to 698, + ) + + private val creviceClimbedAttribute = "player_strong:crevice_climbed" + + } + override fun defineListeners() { + + // Test + on(Items.TEST_PAPER_12626, IntType.ITEM, "take exam") { player, _ -> + if (player.savedData.globalData.testStage == 2){ + sendMessage(player, "You have already completed the test. Hand it in to Professor Henry for marking.") + } + else{ + openInterface(player, 697) + } + return@on true + } + + // Students + on(intArrayOf(NPCs.STUDENT_7151, NPCs.STUDENT_7152, NPCs.STUDENT_7153, NPCs.STUDENT_7154, + NPCs.STUDENT_7155, NPCs.STUDENT_7156, NPCs.STUDENT_7157), IntType.NPC, "Talk-to") { player, _ -> + sendMessage(player, "This student is trying to focus on their work.") + return@on true + } + + // Jail teleports + on(SceneryConst.JAIL_ENTRANCE_29603, IntType.SCENERY, "use") { player, _-> + teleport(player, Location.create(3082, 4229, 0)) + return@on true + } + on(SceneryConst.JAIL_ENTRANCE_29602, IntType.SCENERY, "leave") { player, _ -> + teleport(player, Location.create(3074, 3456, 0)) + return@on true + } + on(SceneryConst.STAIRS_29589, IntType.SCENERY, "climb-up") { player, _ -> + if (player.globalData.hasReadPlaques()){ + teleport(player, Location.create(3083, 3452, 0)) + } + else{ + sendMessage(player, "You need to read the jail plaques before the guard will allow you upstairs") + } + + return@on true + } + // Exam room + on(SceneryConst.DOOR_29732, IntType.SCENERY, "open") { player, node -> + if (player.globalData.testStage > 0){ + // The player has talked to the prof + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } + else{ + sendMessage(player, "The door is locked") + } + return@on true + } + on(SceneryConst.STAIRS_29592, IntType.SCENERY, "climb-down") { player, _ -> + teleport(player, Location.create(3086, 4247, 0)) + return@on true + } + + // crevice (and rope) + on(SceneryConst.CREVICE_29728, IntType.SCENERY, "enter"){ player, _ -> + if (getAttribute(player, creviceClimbedAttribute, false)){ + teleport(player, Location.create(3159, 4279, 3)) + } + else{ + // todo find what the crevice should say + sendMessage(player, "There's no way down") + } + return@on true + } + on(SceneryConst.ROPE_29729, IntType.SCENERY, "climb"){ player, _ -> + if (!getAttribute(player, creviceClimbedAttribute, false)){ + setAttribute(player, creviceClimbedAttribute, true) + } + teleport(player, Location.create(3077, 3462, 0)) + return@on true + } + + // Plaques + on(intArrayOf(SceneryConst.JAIL_DOOR_29595, SceneryConst.JAIL_DOOR_29596, SceneryConst.JAIL_DOOR_29597, + SceneryConst.JAIL_DOOR_29598, SceneryConst.JAIL_DOOR_29599, SceneryConst.JAIL_DOOR_29600, + SceneryConst.JAIL_DOOR_29601) , IntType.SCENERY, "Read-plaque on") { player, node -> + read(player, node) + return@on true + } + + // The dungeon + on(SceneryConst.POSTER_29586, IntType.SCENERY, "pull-back") { player, _ -> + sendDialogue(player, "There appears to be a tunnel behind this poster.") + teleport(player, Location.create(3140, 4230, 2)) + return@on true + } + on(SceneryConst.TUNNEL_29623, IntType.SCENERY, "use") {player, _ -> + teleport(player, Location.create(3077, 4235, 0)) + return@on true + } + + on(SceneryConst.AN_OLD_LEVER_29730, IntType.SCENERY, "pull") {player, _ -> + sendMessage(player, "You hear the cogs and gears moving and a distant unlocking sound.") + setVarp(player, 1203, (1 shl 29) or (1 shl 26), true) + return@on true + } + + on(SceneryConst.AN_OLD_LEVER_29731, IntType.SCENERY, "pull") {player, _ -> + sendMessage(player, "You hear cogs and gears moving and the sound of heavy locks falling into place.") + setVarp(player, 1203, 1 shl 29, true) + return@on true + } + + // the same jail door is used in 4 different places + on(SceneryConst.JAIL_DOOR_29624, IntType.SCENERY, "open") { player, _ -> + if (getVarp(player, 1203) and (1 shl 26) == 0) { + // The door is locked + sendMessage(player, "The door seems to be locked by some kind of mechanism.") + return@on true + } + if (player.location.z == 2) { + // Floor 2 to hidden tunnel + teleport(player, Location.create(3177, 4266, 0)) + } + else if (player.location.z == 1){ + // Floor 1 to hidden tunnel + teleport(player, Location.create(3143, 4270, 0)) + } + else { + // Leaving the hidden tunnel + if (player.location.x < 3150){ + // Leaving by the west exit (to floor 1) + teleport(player, Location.create(3142, 4272, 1)) + } + else{ + // Must be exiting by the east exit (to floor 2) + teleport(player, Location.create(3177, 4269, 2)) + } + } + return@on true + } + + // the 4 stairs in the middle of the 1st/2nd floor + // NE + on(SceneryConst.STAIRS_29667, IntType.SCENERY, "climb-down") { player, _ -> + teleport(player, Location.create(3160, 4249, 1)) + return@on true + } + on(SceneryConst.STAIRS_29668, IntType.SCENERY, "climb-up") { player, _ -> + teleport(player, Location.create(3158, 4250, 2)) + return@on true + } + + // SE + on(SceneryConst.STAIRS_29663, IntType.SCENERY, "climb-down") { player, _ -> + teleport(player, Location.create(3160, 4246, 1)) + return@on true + } + on(SceneryConst.STAIRS_29664, IntType.SCENERY, "climb-up") { player, _ -> + teleport(player, Location.create(3158, 4245, 2)) + return@on true + } + + // SW + on(SceneryConst.STAIRS_29655, IntType.SCENERY, "climb-down") { player, _ -> + teleport(player, Location.create(3146, 4246, 1)) + return@on true + } + on(SceneryConst.STAIRS_29656, IntType.SCENERY, "climb-up") { player, _ -> + teleport(player, Location.create(3149, 4244, 2)) + return@on true + } + + // NW + on(SceneryConst.STAIRS_29659, IntType.SCENERY, "climb-down") { player, _ -> + teleport(player, Location.create(3146, 4249, 1)) + return@on true + } + on(SceneryConst.STAIRS_29660, IntType.SCENERY, "climb-up") { player, _ -> + teleport(player, Location.create(3148, 4250, 2)) + return@on true + } + + + // rewards chest + on(SceneryConst.TREASURE_CHEST_29577, IntType.SCENERY, "open"){ player, _ -> + setVarbit(player, 4499, 1, true) + return@on true + } + on(SceneryConst.TREASURE_CHEST_29578, IntType.SCENERY, "search"){ player, _ -> + // Give the player rewards + if (player.globalData.testStage == 3){ + // Check the player has enough slots + if ((freeSlots(player) == 0) or + ((freeSlots(player) == 1) and !inInventory(player, Items.COINS_995))){ + sendDialogue(player, "You do not have enough inventory space!") + } + else{ + player.emoteManager.unlock(Emotes.SAFETY_FIRST) + addItem(player, Items.COINS_995, 10000) + addItem(player, Items.SAFETY_GLOVES_12629) + sendItemDialogue(player, Items.SAFETY_GLOVES_12629, + "You open the chest to find a large pile of gold, along with a pair of safety gloves. ") + + player.globalData.testStage = 4 + } + } + else { + // The player may have lost their gloves + if (hasAnItem(player, Items.SAFETY_GLOVES_12629).exists()){ + sendDialogue(player, "The chest is empty") + } + else{ + if (freeSlots(player) == 0){ + sendDialogue(player, "You do not have enough inventory space!") + } + else { + addItem(player, Items.SAFETY_GLOVES_12629) + sendItemDialogue( + player, Items.SAFETY_GLOVES_12629, + "You open the chest to find a pair of safety gloves. " + ) + } + } + + } + return@on true + } + } + + fun read(player: Player, plaque: Node){ + if (plaque !is Scenery) return + player.interfaceManager.openChatbox(plaquesToIface[plaque.id]!!) + } + + + class PlaqueListener : InterfaceListener { + + var scene : PlaqueCutscene? = null + + override fun defineInterfaceListeners() { + for ((index, iface) in plaquesToIface.values.withIndex()){ + onClose(iface){ player, _ -> + scene?.end(fade = false) + player.globalData.readPlaques[index] = true + return@onClose true + } + + onOpen(iface) { player, component -> + scene = PlaqueCutscene(player, component) + scene?.start(hideMiniMap = false) + return@onOpen true + } + + on(iface) { player, _, _, buttonID, _, _ -> + // If thumbs up is clicked + if (buttonID == 2){ + scene?.incrementStage() + player.interfaceManager.closeChatbox() + } + return@on true + } + } + } + + class PlaqueCutscene(player: Player, val component: Component): Cutscene(player) { + + // Since the component does not know the door's location + // there needs to be some translation from player position + // to the door location. This is component -> rotation (dx, dy) + private val rotationMapping = mapOf( + 701 to listOf(-1, 0), + 703 to listOf(-1, 0), + 711 to listOf(-1, 0), + 695 to listOf(0, 1), + 312 to listOf(1, 0), + 706 to listOf(1, 0), + 698 to listOf(1, 0), + ) + + override fun setup() { + setExit(player.location) + } + + override fun runStage(stage: Int) { + when (stage){ + 0 -> { + // Go to head height + moveCamera(player.location.localX, player.location.localY, 245, speed = 50) + // Spin in the right direction + rotateCamera(player.location.localX + rotationMapping[component.id]!![0], + player.location.localY + rotationMapping[component.id]!![1], + 245, speed = 50) + } + 1 -> { + resetCamera() + } + } + } + + } + + } + + } diff --git a/Server/src/main/content/region/misthalin/dialogue/HoodedMonkDialogue.java b/Server/src/main/content/region/misthalin/dialogue/HoodedMonkDialogue.java new file mode 100644 index 0000000..b1dc3b6 --- /dev/null +++ b/Server/src/main/content/region/misthalin/dialogue/HoodedMonkDialogue.java @@ -0,0 +1,65 @@ +package content.region.misthalin.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the hooded monk dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class HoodedMonkDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code HoodedMonkDialogue} {@code Object}. + */ + public HoodedMonkDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code HoodedMonkDialogue} {@code Object}. + * @param player the player. + */ + public HoodedMonkDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new HoodedMonkDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Excuse me...oh, wait, I thought you were someone else."); + stage = 1; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No problem. Have a good day!"); + stage = 2; + break; + case 2: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 3074 }; + } +} diff --git a/Server/src/main/content/region/misthalin/digsite/dialogue/ArchaeologistcalExpertUsedOnDialogueFile.kt b/Server/src/main/content/region/misthalin/digsite/dialogue/ArchaeologistcalExpertUsedOnDialogueFile.kt new file mode 100644 index 0000000..c16b62b --- /dev/null +++ b/Server/src/main/content/region/misthalin/digsite/dialogue/ArchaeologistcalExpertUsedOnDialogueFile.kt @@ -0,0 +1,126 @@ +package content.region.misthalin.digsite.dialogue + +import content.region.misthalin.digsite.quest.thedigsite.ArchaeologicalExpertListener +import core.api.addItemOrDrop +import core.api.sendDialogue +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.item.Item +import org.rs09.consts.Items +import core.game.dialogue.DialogueFile + +/** + * @author qmqz + */ + +class ArchaeologistcalExpertUsedOnDialogueFile(val it: Int) : DialogueFile() { + + var i = ArchaeologicalExpertListener() + var n = NPC(i.archy) + var itemUsed = it + + override fun handle(interfaceId: Int, buttonId: Int) { + + npc = n + + when (stage) { + + 0 -> when (itemUsed) { + i.staff -> player(FacialExpression.ASKING, "What do you think of this?").also { stage = 100 } + + i.unidentifiedLiquid -> { + replaceAll(i.unidentifiedLiquid, i.nitroglycerin) + npcl(FacialExpression.WORRIED, "This is a VERY dangerous liquid called nitroglycerin. Be careful how you handle it. Don't drop it or it will explode!").also { stage = 99 } + } + + i.nitroglycerin -> player(FacialExpression.ASKING, "Can you tell me any more about this?").also { stage = 110} + i.ammoniumNitrate -> player(FacialExpression.ASKING, "Have a look at this.").also { stage = 120 } + i.nuggets -> player(FacialExpression.ASKING, "I have these gold nuggets...").also { stage = 130 } + i.needle -> player(FacialExpression.NEUTRAL, "I found a needle.").also { stage = 140 } + i.rottenApple -> player(FacialExpression.SAD, "I found these...").also { stage = 150 } + i.brokenGlass -> player(FacialExpression.NEUTRAL, "Have a look at this glass.").also { stage = 160 } + i.brokenArrow -> player(FacialExpression.FRIENDLY, "Have a look at this arrow.").also { stage = 170 } + i.panningTray -> { + if (player!!.inventory.contains(Items.PANNING_TRAY_677,1)) { + npc(FacialExpression.NEUTRAL, "I have no need for panning trays!").also { stage = 99 } + } + if (player!!.inventory.contains(Items.PANNING_TRAY_678,1) || player!!.inventory.contains(Items.PANNING_TRAY_679,1)) { + npc(FacialExpression.NEUTRAL, "Have you searched this tray yet?").also { stage = 180 } + } + } + i.bones -> player(FacialExpression.FRIENDLY, "Have a look at these bones.").also { stage = 190 } + i.buttons -> player(FacialExpression.FRIENDLY, "I found these buttons.").also { stage = 200 } + i.crackedSample -> player(FacialExpression.WORRIED, "I found this rock...").also { stage = 210 } + i.oldTooth -> player(FacialExpression.FRIENDLY, "Hey look at this.").also { stage = 220 } + i.rustySword -> player(FacialExpression.FRIENDLY, "I found an old sword.").also { stage = 230 } + i.brokenStaff -> player(FacialExpression.ASKING, "Have a look at this staff.").also { stage = 240 } + i.brokenArmour -> player(FacialExpression.ASKING, "I found some armour.").also { stage = 250 } + i.damagedArmour -> player(FacialExpression.THINKING, "I found some old armour.").also { stage = 260 } + i.ceramicRemains -> player(FacialExpression.FRIENDLY, "I found some pottery pieces.").also { stage = 270 } + i.beltBuckle -> player(FacialExpression.ASKING, "Have a look at this unusual item...").also { stage = 280 } + i.animalSkull -> player(FacialExpression.FRIENDLY, "Have a look at this.").also { stage = 290 } + i.specialCup -> player(FacialExpression.FRIENDLY, "Have a look at this.").also { stage = 300 } + i.teddy -> player(FacialExpression.FRIENDLY, "Have a look at this.").also { stage = 310 } + i.stoneTablet -> player(FacialExpression.FRIENDLY, "Have a look at this.").also { stage = 320 } + else -> npcl(FacialExpression.FRIENDLY, "I don't think that has any archaeological significance").also { stage = 99 } + } + + + 100 -> npcl(FacialExpression.AMAZED, "That staff is incredible! It's the same symbol that was on that talisman you found here. Does this mean you've found out more about Zaros?").also { stage++ } + + 101 -> playerl( + FacialExpression.FRIENDLY, "I found out that he was banished, and that the people's hero was trapped in a pyramid and...").also { stage++ } + 102 -> npcl(FacialExpression.THINKING, "So you're the one who found out about that. I've heard the story from my friends in the museum. Well done on being able to wield such an impressive symbol.").also { stage++ } + 103 -> npc(FacialExpression.FRIENDLY, "Anyway....").also { stage = 99 } // 500 will be digsite dialog + + 110 -> npcl(FacialExpression.WORRIED, "Nitroglycerin! This is a dangerous substance. This is normally mixed with other chemicals to produce a potent compound.").also { stage++ } + 111 -> npcl(FacialExpression.WORRIED, "Be sure not to drop it! That stuff is highly volatile...").also { stage = 99 } + + 120 -> npcl(FacialExpression.WORRIED, "Really, you do find the most unusual items. I know what this is - it's a strong chemical called ammonium nitrate. Why you want this I'll never know...").also { stage = 99 } + 130 -> { + if (player!!.inventory.getAmount(i.nuggets) >= 3) { + player!!.inventory.remove(Item(i.nuggets, 3)) + addItemOrDrop(player!!, Items.GOLD_ORE_444, 1) + npcl(FacialExpression.FRIENDLY, "Good – that's three; I can exchange them for normal gold now. You can get this refined and make a profit!").also { stage = 131 } + } else if (player!!.inventory.getAmount(i.nuggets) < 3) { + npcl(FacialExpression.FRIENDLY, "I can't do much with these nuggets yet. Come back when you have 3 and I will exchange them for you.").also { stage = 99 } + } + } + 131 -> player(FacialExpression.FRIENDLY, "Excellent!").also { stage = 99 } + 140 -> npcl(FacialExpression.LAUGH, "Hmm, yes; I wondered why this race were so well dressed! It looks like they had mastery of needlework.").also { stage = 99 } + 150 -> npc(FacialExpression.DISGUSTED, "Ew! Throw them away this instant!").also { stage = 99 } + 160 -> npcl(FacialExpression.NEUTRAL, "Hey you should be careful of that. It might cut your fingers, throw it away!").also { stage = 99 } + 170 -> npcl(FacialExpression.AMAZED, "No doubt this arrow was shot by a strong warrior – it's split in half! It is not a valuable object though.").also { stage = 99 } + 180 -> player(FacialExpression.THINKING, "Not that I remember...").also { stage++ } + 181 -> npcl(FacialExpression.DISGUSTED, "It may contain something; I don't want to get my hands dirty.").also { stage++ } + 182 -> sendDialogue(player!!,"The expert hands the tray back to you.").also { stage = 99 } + 190 -> npcl(FacialExpression.FRIENDLY, "Ah, yes – a fine bone example... no noticeable fractures... and in good condition. These are common cow bones, however; they have no archaeological value.").also { stage = 99 } + 200 -> npcl(FacialExpression.THINKING, "Let's have a look. Ah, I think these are from the nobility, perhaps a royal servant?").also { stage = 99 } + 210 -> npcl(FacialExpression.THINKING, "What a shame it's cracked; this looks like it would have been a good sample.").also { stage = 99 } + 220 -> npcl(FacialExpression.LAUGH, "Oh, an old tooth. It looks like it has come from a mighty being. Pity there are no tooth fairies around here!").also { stage = 99 } + 230 -> npcl(FacialExpression.THINKING, "Oh, it's very rusty isn't it? I'm not sure this sword belongs here, it looks very out of place.").also { stage = 99 } + 240 -> npcl(FacialExpression.HALF_THINKING, "Look at this... Interesting... This appears to belong to a cleric of some kind; certainly not a follower of Saradomin, however.").also { stage++ } + 241 -> npcl(FacialExpression.THINKING, "I wonder if there was another civilization here before the Saradominists?").also { stage = 99 } + 250 -> npcl(FacialExpression.AMAZED, "It looks like the wearer of this fought a mighty battle.").also { stage = 99 } + 260 -> npcl(FacialExpression.THINKING, "How unusual. This armour doesn't seem to match with the other finds. Keep looking.").also { stage = 99 } + 270 -> npcl(FacialExpression.FRIENDLY, "Yes, many parts are discovered. The inhabitants of these parts were great potters.").also { stage++ } + 271 -> player(FacialExpression.ASKING, "You mean they were good at using potions?").also { stage++ } + 272 -> npcl(FacialExpression.LAUGH, "No, no, silly. They were known for their skill with clay.").also { stage = 99 } + 280 -> npcl(FacialExpression.THINKING, "Let me see. This is a belt buckle. Not so unusual - I should imagine it came from a guard.").also { stage = 99 } + 290 -> npcl(FacialExpression.THINKING, "Hmm, an interesting find; an animal skull for sure. Another student found one just like this today.").also { stage = 99 } + 300 -> npcl(FacialExpression.THINKING, "Looks like an award cup for some small find. Perhaps it belongs to one of the students?").also { stage = 99 } + 310 -> npcl(FacialExpression.LAUGH, "Why, it looks like a teddy bear to me. Perhaps someone's lucky mascot!").also { stage = 99 } + 320 -> npcl(FacialExpression.NEUTRAL, "I don't need another tablet! One is enough, thank you.").also { stage = 99 } + + 99 -> end() + } + } + + fun replaceAll(originalItem: Int, newItem: Int) { + for (a in 0..player!!.inventory.getAmount(originalItem)) { + if (player!!.inventory.contains(originalItem, 1)) { + player!!.inventory.replace(Item(newItem), player!!.inventory.getSlot(Item(originalItem))) + } + } + } +} diff --git a/Server/src/main/content/region/misthalin/digsite/dialogue/ChemicalsBook.kt b/Server/src/main/content/region/misthalin/digsite/dialogue/ChemicalsBook.kt new file mode 100644 index 0000000..a13b7c8 --- /dev/null +++ b/Server/src/main/content/region/misthalin/digsite/dialogue/ChemicalsBook.kt @@ -0,0 +1,78 @@ +package content.region.misthalin.digsite.dialogue + +import content.global.handlers.iface.BookInterface +import content.global.handlers.iface.BookLine +import content.global.handlers.iface.Page +import content.global.handlers.iface.PageSet +import core.api.setAttribute +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import org.rs09.consts.Items + +class ChemicalsBook : InteractionListener { + companion object { + private val TITLE = "Volatile chemicals Experimental Test Notes" + private val CONTENTS = arrayOf( + PageSet( + Page( + BookLine("Volatile Chemicals:", 55), + BookLine("Experimental Test Notes.", 56), + BookLine("In order to ease the mining", 58), + BookLine("process, my colleagues and", 59), + BookLine("I decided we needed something", 60), + BookLine("stronger than picks to delve", 61), + BookLine("under the surface of the site.", 62), + BookLine("As I already had an", 64), + BookLine("intermediate knowledge", 65), + ), + Page( + BookLine("of Herblore, I experimented", 66), + BookLine("with certain chemicals and", 67), + BookLine("invented a compound of", 68), + BookLine("tremendous power that,", 69), + BookLine("if subjected to a spark,", 70), + BookLine("would literally explode.", 71), + BookLine("We used vials of this", 73), + BookLine("compound with great effect,", 74), + BookLine("as it enabled us to reach", 75), + BookLine("further than ever before.", 76), + ) + ), + PageSet( + Page( + BookLine("Here is what I have left of", 55), + BookLine("the compound's recipe:", 56), + BookLine("1 measure of ammonium", 59), + BookLine("nitrate powder;", 60), + BookLine("1 measure of nitroglycerine;", 62), + BookLine("1 measure of ground charcoal;", 64), + ), + Page( + BookLine("1 measure of ?", 66), + BookLine("Unfortunately the last", 68), + BookLine("ingredient was not noted", 69), + BookLine("down, but we understand", 70), + BookLine("that a certain root grows", 71), + BookLine("around these parts that", 72), + BookLine("was used to very good", 73), + BookLine("effect...", 73), + ) + ), + ) + } + + private fun display(player: Player, pageNum: Int, buttonID: Int): Boolean { + BookInterface.pageSetup( + player, BookInterface.FANCY_BOOK_3_49, TITLE, CONTENTS + ) + return true + } + + override fun defineListeners() { + on(Items.BOOK_ON_CHEMICALS_711, IntType.ITEM, "read") { player, _ -> + BookInterface.openBook(player, BookInterface.FANCY_BOOK_3_49, ::display) + return@on true + } + } +} diff --git a/Server/src/main/content/region/misthalin/digsite/dialogue/EdWoodDialogue.kt b/Server/src/main/content/region/misthalin/digsite/dialogue/EdWoodDialogue.kt new file mode 100644 index 0000000..11c6bb0 --- /dev/null +++ b/Server/src/main/content/region/misthalin/digsite/dialogue/EdWoodDialogue.kt @@ -0,0 +1,25 @@ +package content.region.misthalin.digsite.dialogue + +import core.api.sendChat +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class EdWoodDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + sendChat(npc, arrayOf("Can't stop. Too busy.", "Wonder when I'll get paid.", "Is it lunch break yet?", "Hey I'm working here. I'm working here.", "This work isn't going to do itself.", "Ouch! That was my finger!").random()) + stage = END_DIALOGUE + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return EdWoodDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.ED_WOOD_5964) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/digsite/dialogue/ElissaDialogue.kt b/Server/src/main/content/region/misthalin/digsite/dialogue/ElissaDialogue.kt new file mode 100644 index 0000000..d41dc2d --- /dev/null +++ b/Server/src/main/content/region/misthalin/digsite/dialogue/ElissaDialogue.kt @@ -0,0 +1,101 @@ +package content.region.misthalin.digsite.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class ElissaDialogue(player: Player? = null) : DialoguePlugin(player){ + + var fr = FacialExpression.FRIENDLY + var ask = FacialExpression.ASKING + var ann = FacialExpression.ANNOYED + var neu = FacialExpression.ANNOYED + var ama = FacialExpression.AMAZED + var qb = 2 + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npc(FacialExpression.FRIENDLY,"Hello there.").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + //three quest branches + //normal dialogue + 0 -> (options("What do you do here?", "What is this place?")).also { stage++ } + 1 -> { + when(qb) { + 1 -> player(ask, "What do you do here?").also { stage = 10 } + 2 -> player(ask, "What is this place?").also { stage = 20 } + } + } + + 10 -> npcl(fr, "I am helping with the dig. I am an expert on Third Age architecture.").also { stage = 99 } + 20 -> npcl(ann, "In the Third Age, this was a great city, which would have put Varrock to shame!").also { stage++ } + 21 -> options("I don't know, Varrock is pretty impressive.", "What happened to the city?").also { stage++ } + 22 -> when(buttonId) { + 1 -> player(fr, "I don't know, Varrock is pretty impressive.").also { stage = 30 } + 2 -> player(ask, "What happened to the city?").also { stage = 40 } + } + + 30 -> npcl(ann, "Hmph. I don't think it will look this good when it's been buried in the ground for three thousand years!").also { stage = 99 } + 40 -> npc(neu, "No one knows for sure.").also { stage++ } + 41 -> npcl(neu, "But the The Third Age was a time of destruction, when the gods were violently at war. Many great civilizations were destroyed then.").also { stage = 99 } + + //the golem quest dialogue first time talking + 50 -> (options("What do you do here?", "What is this place?", "I found a letter in the desert with your name on.")).also { stage++ } + 51 -> when (buttonId) { + 1 -> player(ask, "What do you do here?").also { stage = 10 } + 2 -> player(ask, "What is this place?").also { stage = 20 } + 3 -> playerl(fr, "I found a letter in the desert with your name on.").also { stage = 60 } + } + 60 -> npc(ama, "Ah, so you've found the ruins of Uzer.").also { stage++ } + 61 -> npcl(ama, "I wrote that letter to my late husband when he was exploring there.").also { stage++ } + 62 -> npcl(ama, "That was a great city as well, but the museum could only fund one excavation and this one was closer to home.").also { stage++ } + 63 -> npcl(ama, "If you're interested in his expedition, the notes he made are in the library in the Exam Centre.").also { stage = 99 } + + //talking to her again after the initial golem quest dialogue + 70 -> (options("What do you do here?", "What is this place?", "Where did you say the notes were?")).also { stage++ } + 71 -> when (buttonId) { + 1 -> player(ask, "What do you do here?").also { stage = 10 } + 2 -> player(ask, "What is this place?").also { stage = 20 } + 3 -> playerl(fr, "Where did you say the notes were?").also { stage = 80 } + } + + 80 -> npc(fr, "They're on a bookcase in the Exam Centre.").also { stage = 99 } + + //after reading varmen's notes + 90 -> (options("What do you do here?", "What is this place?", "Where is the statuette that Varmen took back from Uzer?")).also { stage++ } + 91 -> when (buttonId) { + 1 -> player(ask, "What do you do here?").also { stage = 10 } + 2 -> player(ask, "What is this place?").also { stage = 20 } + 3 -> playerl(fr, "Where is the statuette that Varmen took back from Uzer?").also { stage = 100 } + } + + 100 -> npc(ask, "The statuette? Oh, yes...").also { stage++ } + 101 -> npcl(neu, "That statuette was the only thing we had to show from that expedition.").also { stage++ } + 102 -> npcl(ask, "It was very worn, but you can still make out a lot of detail. The Uzerians were expert sculptors. It's a pity we only have that small example.").also { stage++ } + 103 -> npc(ask, "Now it's on display in the Varrock museum.").also { stage = 99 } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return ElissaDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.ELISSA_1912) + } +} diff --git a/Server/src/main/content/region/misthalin/digsite/dialogue/ExaminerDialogue.kt b/Server/src/main/content/region/misthalin/digsite/dialogue/ExaminerDialogue.kt new file mode 100644 index 0000000..d9f94df --- /dev/null +++ b/Server/src/main/content/region/misthalin/digsite/dialogue/ExaminerDialogue.kt @@ -0,0 +1,536 @@ +package content.region.misthalin.digsite.dialogue + +import content.data.Quests +import content.region.misthalin.digsite.quest.thedigsite.TheDigSite +import core.api.* +import core.game.dialogue.* +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class ExaminerDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, ExaminerDialogueFile(), npc) + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return ExaminerDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.EXAMINER_618, NPCs.EXAMINER_4566, NPCs.EXAMINER_4567) + } +} +class ExaminerDialogueFile : DialogueBuilderFile() { + + companion object { + + } + + override fun create(b: DialogueBuilder) { + + b.onQuestStages(Quests.THE_DIG_SITE, 100) + .npcl(FacialExpression.HAPPY, "Hello there! My colleague tells me you helped to uncover a hidden altar to the god Zaros.") + .npcl(FacialExpression.HAPPY, "A great scholar and archaeologist indeed! Good health and prosperity to you.") + .options().let { optionBuilder -> + optionBuilder.option("Thanks.") + .player(FacialExpression.HAPPY, "Thanks!") + .end() + optionBuilder.option_playerl("I have lost my trowel.") + .npcl("Deary me... That was a good one as well. It's a good job I have another. Here you go...") + .endWith { _, player -> + addItemOrDrop(player, Items.TROWEL_676) + } + } + + b.onQuestStages(Quests.THE_DIG_SITE, 6, 7, 8, 9, 10, 11, 12) + .branch { player -> if(inInventory(player, Items.TROWEL_676)) { 0 } else { 1 } } + .let{ branch -> + branch.onValue(0) + .npcl(FacialExpression.FRIENDLY, "Well, what are you doing here? Get digging!") + .end() + branch.onValue(1) + .playerl("I have lost my trowel.") + .npcl("Deary me. That was a good one as well. It's a good job I have another. Here you go...") + .endWith { _, player -> + addItemOrDrop(player, Items.TROWEL_676) + } + } + + b.onQuestStages(Quests.THE_DIG_SITE, 5) + .playerl(FacialExpression.FRIENDLY, "Hello.") + .npcl(FacialExpression.FRIENDLY, "Ah, hello again.") + .options().let { optionBuilder -> + val continuePath = b.placeholder() + optionBuilder.option_playerl("I am ready for the last exam...") + .goto(continuePath) + optionBuilder.option_playerl("I am stuck on a question.") + .npcl("Well, well, have you not been doing any studies? I am not giving you the answers, talk to the other students and remember the answers.") + .end() + optionBuilder.option_playerl("Sorry, I didn't mean to disturb you.") + .npcl("Oh, no problem at all.") + .end() + optionBuilder.option_playerl("I have lost my trowel.") + .branch { player -> if(inInventory(player, Items.TROWEL_676)) { 0 } else { 1 } } + .let{ branch -> + branch.onValue(0) + .npcl("Really? Look in your backpack and make sure first.") + .end() + branch.onValue(1) + .npcl("Deary me. That was a good one as well. It's a good job I have another. Here you go...") + .endWith { _, player -> + addItemOrDrop(player, Items.TROWEL_676) + } + } + return@let continuePath.builder() + } + .npcl(FacialExpression.NEUTRAL, "Attention, this is the final part of the Earth Sciences exam: Earth Sciences level 3 - Advanced.") + .npcl(FacialExpression.NEUTRAL, "Question 1 - Sample preparation. Can you tell me how we prepare samples?") + .options().let { optionBuilder -> + val continuePath = b.placeholder() + optionBuilder.recordAttribute(TheDigSite.attributeFirstQuestion) + optionBuilder.optionIf("Samples may be mixed together safely.") { + player -> return@optionIf !getAttribute(player, TheDigSite.attributeStudentPurpleExam3ObtainAnswer, false) } + .playerl("Samples may be mixed together safely.") + .goto(continuePath) + optionBuilder.optionIf("Samples cleaned, and carried only in specimen jars.") { + player -> return@optionIf getAttribute(player, TheDigSite.attributeStudentPurpleExam3ObtainAnswer, false) } + .playerl("Samples cleaned, and carried only in specimen jars.") + .goto(continuePath) + optionBuilder.option_playerl("Sample types catalogued and carried by hand only.").goto(continuePath) + optionBuilder.option_playerl("Samples to be spread thickly with mashed banana.").goto(continuePath) + return@let continuePath.builder() + } + .npcl("Okay, next question...") + .npcl(FacialExpression.NEUTRAL, "Earth Sciences level 3, question 2 - Specimen brush use. What is the proper way to use a specimen brush?") + .options().let { optionBuilder -> + val continuePath = b.placeholder() + optionBuilder.recordAttribute(TheDigSite.attributeSecondQuestion) + optionBuilder.optionIf("Brush quickly using a wet brush.") { + player -> return@optionIf !getAttribute(player, TheDigSite.attributeStudentGreenExam3ObtainAnswer, false) } + .playerl("Brush quickly using a wet brush.") + .goto(continuePath) + optionBuilder.optionIf("Brush carefully and slowly using short strokes.") { + player -> return@optionIf getAttribute(player, TheDigSite.attributeStudentGreenExam3ObtainAnswer, false) } + .playerl("Brush carefully and slowly using short strokes.") + .goto(continuePath) + optionBuilder.option_playerl("Dipped in glue and stuck to a sheep's back.").goto(continuePath) + optionBuilder.option_playerl("Brush quickly and with force.").goto(continuePath) + return@let continuePath.builder() + } + .npcl("Okay, next question...") + .npcl(FacialExpression.NEUTRAL, "Earth Sciences level 3, question 3 - Advanced techniques. Can you describe the technique for handling bones?") + .options().let { optionBuilder -> + val continuePath = b.placeholder() + optionBuilder.recordAttribute(TheDigSite.attributeThirdQuestion) + optionBuilder.optionIf("Bones must not be taken from the site.") { + player -> return@optionIf !getAttribute(player, TheDigSite.attributeStudentBrownExam3ObtainAnswer, false) } + .playerl("Bones must not be taken from the site.") + .goto(continuePath) + optionBuilder.option_playerl("Feed to hungry dogs.").goto(continuePath) + optionBuilder.option_playerl("Bones to be ground and tested for mineral content.").goto(continuePath) + optionBuilder.optionIf("Handle bones very carefully and keep them away from other samples.") { + player -> return@optionIf getAttribute(player, TheDigSite.attributeStudentBrownExam3ObtainAnswer, false) } + .playerl("Handle bones very carefully and keep them away from other samples.") + .goto(continuePath) + return@let continuePath.builder() + } + .npcl("Okay, that concludes the level 3 Earth Sciences exam.") + .npcl(FacialExpression.HAPPY, "Let me add up the results...") + .branch { player -> + var ansCount = 0 + if (getAttribute(player, TheDigSite.attributeFirstQuestion, -1) == 0 && + getAttribute(player, TheDigSite.attributeStudentPurpleExam3ObtainAnswer, false)) { + ansCount++ + } + if (getAttribute(player, TheDigSite.attributeSecondQuestion, -1) == 0 && + getAttribute(player, TheDigSite.attributeStudentGreenExam3ObtainAnswer, false)) { + ansCount++ + } + if (getAttribute(player, TheDigSite.attributeThirdQuestion, -1) == 2 && + getAttribute(player, TheDigSite.attributeStudentBrownExam3ObtainAnswer, false)) { + ansCount++ + } + return@branch ansCount + } + .let { branch -> + + branch.onValue(0) + .npcl(FacialExpression.ANGRY, "I cannot believe this! Absolutely none right at all. I doubt you did any research before you took this exam...") + .playerl(FacialExpression.SAD, "Ah... Yes... Erm.... I think I had better go and revise first!") + .end() + + branch.onValue(1) + .npcl(FacialExpression.FRIENDLY, "You got one question correct. Try harder!") + .playerl(FacialExpression.FRIENDLY, "Oh bother!") + .end() + + branch.onValue(2) + .npcl(FacialExpression.FRIENDLY, "You got two questions correct. A little more study and you will pass it.") + .playerl(FacialExpression.FRIENDLY, "I'm nearly there...") + .end() + + branch.onValue(3) + .npcl(FacialExpression.FRIENDLY, "You got all the questions correct, well done!") + .playerl(FacialExpression.FRIENDLY, "Hooray!") + .betweenStage { _, player, _, _ -> + addItemOrDrop(player, Items.LEVEL_3_CERTIFICATE_693) + } + .npcl(FacialExpression.FRIENDLY, "Congratulations! You have now passed the Earth Sciences level 3 exam. Here is your level 3 certificate.") + .playerl(FacialExpression.FRIENDLY, "I can dig wherever I want now!") + .npcl(FacialExpression.FRIENDLY, "Perhaps you should use your newfound skills to find an artefact on the digsite that will impress the archaeological expert.") + .endWith { _, player -> + if(getQuestStage(player, Quests.THE_DIG_SITE) == 5) { + setQuestStage(player, Quests.THE_DIG_SITE, 6) + } + openInterface(player, 444) + setInterfaceText(player, player.username, 444, 5) + } + + } + + b.onQuestStages(Quests.THE_DIG_SITE, 4) + .playerl(FacialExpression.FRIENDLY, "Hello.") + .npcl(FacialExpression.FRIENDLY, "Hello again.") + .options().let { optionBuilder -> + val continuePath = b.placeholder() + optionBuilder.option_playerl("I am ready for the next exam.") + .goto(continuePath) + optionBuilder.option_playerl("I am stuck on a question.") + .npcl("Well, well, have you not been doing any studies? I am not giving you the answers, talk to the other students and remember the answers.") + .end() + optionBuilder.option_playerl("Sorry, I didn't mean to disturb you.") + .npcl("Oh, no problem at all.") + .end() + optionBuilder.option_playerl("I have lost my trowel.") + .branch { player -> if(inInventory(player, Items.TROWEL_676)) { 0 } else { 1 } } + .let{ branch -> + branch.onValue(0) + .npcl("Really? Look in your backpack and make sure first.") + .end() + branch.onValue(1) + .npcl("Deary me. That was a good one as well. It's a good job I have another. Here you go...") + .endWith { _, player -> + addItemOrDrop(player, Items.TROWEL_676) + } + } + return@let continuePath.builder() + } + .npcl(FacialExpression.NEUTRAL, "Okay, this is the next part of the Earth Sciences exam: Earth Sciences level 2 - Intermediate.") + .npcl(FacialExpression.NEUTRAL, "Question 1 - Sample transportation. Can you tell me how we transport samples?") + .options().let { optionBuilder -> + val continuePath = b.placeholder() + optionBuilder.recordAttribute(TheDigSite.attributeFirstQuestion) + optionBuilder.optionIf("Samples cut and cleaned before transportation.") { + player -> return@optionIf !getAttribute(player, TheDigSite.attributeStudentBrownExam2ObtainAnswer, false) } + .playerl("Samples cut and cleaned before transportation.") + .goto(continuePath) + optionBuilder.option_playerl("Samples ground and suspended in an acid solution.").goto(continuePath) + optionBuilder.option_playerl("Samples to be given to the melon-collecting monkey. ").goto(continuePath) + optionBuilder.optionIf("Samples taken in rough form; kept only in sealed containers.") { + player -> return@optionIf getAttribute(player, TheDigSite.attributeStudentBrownExam2ObtainAnswer, false) } + .playerl("Samples taken in rough form; kept only in sealed containers.") + .goto(continuePath) + return@let continuePath.builder() + } + .npcl("Okay, next question...") + .npcl(FacialExpression.NEUTRAL, "Earth Sciences level 2, question 2 - Handling of finds. What is the proper way to handle finds?") + .options().let { optionBuilder -> + val continuePath = b.placeholder() + optionBuilder.recordAttribute(TheDigSite.attributeSecondQuestion) + optionBuilder.optionIf("Finds must not be handled by anyone.") { + player -> return@optionIf !getAttribute(player, TheDigSite.attributeStudentPurpleExam2ObtainAnswer, false) } + .playerl("Finds must not be handled by anyone.") + .goto(continuePath) + optionBuilder.optionIf("Finds must be carefully handled.") { + player -> return@optionIf getAttribute(player, TheDigSite.attributeStudentPurpleExam2ObtainAnswer, false) } + .playerl("Finds must be carefully handled.") + .goto(continuePath) + optionBuilder.option_playerl("Finds to be given to the site workmen.").goto(continuePath) + optionBuilder.option_playerl("Drop them on the floor and jump on them.").goto(continuePath) + return@let continuePath.builder() + } + .npcl("Okay, next question...") + .npcl(FacialExpression.NEUTRAL, "Earth Sciences level 2, question 3 - Rock pick usage. Can you tell me the proper use for a rock pick?") + .options().let { optionBuilder -> + val continuePath = b.placeholder() + optionBuilder.recordAttribute(TheDigSite.attributeThirdQuestion) + optionBuilder.optionIf("Strike rock repeatedly until powdered.") { + player -> return@optionIf !getAttribute(player, TheDigSite.attributeStudentGreenExam2ObtainAnswer, false) } + .playerl("Strike rock repeatedly until powdered.") + .goto(continuePath) + optionBuilder.option_playerl("Rock pick must be used flat and with strong force.").goto(continuePath) + optionBuilder.optionIf("Always handle with care; strike cleanly on its cleaving point.") { + player -> return@optionIf getAttribute(player, TheDigSite.attributeStudentGreenExam2ObtainAnswer, false) } + .playerl("Always handle with care; strike cleanly on its cleaving point.") + .goto(continuePath) + optionBuilder.option_playerl("Protective clothing to be worn; tools kept away from site.").goto(continuePath) + return@let continuePath.builder() + } + .npcl("Okay, that covers the level 2 Earth Sciences exam.") + .npcl(FacialExpression.HAPPY, "Let me add up your total...") + .branch { player -> + var ansCount = 0 + if (getAttribute(player, TheDigSite.attributeFirstQuestion, -1) == 2 && + getAttribute(player, TheDigSite.attributeStudentBrownExam2ObtainAnswer, false)) { + ansCount++ + } + if (getAttribute(player, TheDigSite.attributeSecondQuestion, -1) == 0 && + getAttribute(player, TheDigSite.attributeStudentPurpleExam2ObtainAnswer, false)) { + ansCount++ + } + if (getAttribute(player, TheDigSite.attributeThirdQuestion, -1) == 1 && + getAttribute(player, TheDigSite.attributeStudentGreenExam2ObtainAnswer, false)) { + ansCount++ + } + return@branch ansCount + } + .let { branch -> + + branch.onValue(0) + .npcl(FacialExpression.ANGRY, "No, no, no! This will not do. They are all wrong. Start again!") + .playerl(FacialExpression.SAD, "Oh no!") + .npcl("More studying for you my @g[boy,girl].") + .end() + + branch.onValue(1) + .npcl(FacialExpression.FRIENDLY, "You got one question correct. At least it's a start.") + .playerl(FacialExpression.FRIENDLY, "Oh well..") + .npcl(FacialExpression.FRIENDLY, "Get out and explore the site, talk to people and learn!") + .end() + + branch.onValue(2) + .npcl(FacialExpression.FRIENDLY, "You got two questions correct. Not too bad, but you can do better...") + .playerl(FacialExpression.FRIENDLY, "Nearly got it.") + .end() + + branch.onValue(3) + .npcl(FacialExpression.FRIENDLY, "You got all the questions correct, well done!") + .playerl(FacialExpression.FRIENDLY, "Great, I'm getting good at this.") + .betweenStage { _, player, _, _ -> + addItemOrDrop(player, Items.LEVEL_2_CERTIFICATE_692) + } + .npcl(FacialExpression.FRIENDLY, "You have now passed the Earth Sciences level 2 intermediate exam. Here is your certificate. Of course, you'll want to get studying for your next exam now!") + .endWith { _, player -> + if(getQuestStage(player, Quests.THE_DIG_SITE) == 4) { + setQuestStage(player, Quests.THE_DIG_SITE, 5) + } + openInterface(player, 441) + setInterfaceText(player, player.username, 441, 5) + } + + } + + b.onQuestStages(Quests.THE_DIG_SITE, 1, 2, 3) + // This is kinda messy due to the dialogue being reused in different stages. + .branch { player -> + if (getQuestStage(player, Quests.THE_DIG_SITE) == 2 && !inInventory(player, Items.SEALED_LETTER_683)){ + return@branch 1 // Reuse quest stage 1 if sealed letter is not in inventory. + } + return@branch getQuestStage(player, Quests.THE_DIG_SITE) + } + .let{ branch -> + val continuePath = b.placeholder() + branch.onValue(1) + .playerl(FacialExpression.FRIENDLY, "Hello.") + .npcl(FacialExpression.FRIENDLY, "Hello again.") + .npcl(FacialExpression.FRIENDLY, "I am still waiting for your letter of recommendation.") + .options().let { optionBuilder -> + optionBuilder.option_playerl("I have lost the letter you gave me.") + .branch { player -> + if (inInventory(player, Items.UNSTAMPED_LETTER_682)){ + return@branch 0 + } else if (inBank(player, Items.UNSTAMPED_LETTER_682)){ + return@branch 1 + } else { + return@branch 2 + } + }.let{ branch -> + branch.onValue(0) + .npcl("Oh now come on. You have it with you!") + .end() + branch.onValue(1) + .npcl("You already have the letter in your bank.") + .end() + branch.onValue(2) + .npcl("That was foolish. Take this one and don't lose it!") + .endWith { _, player -> + addItemOrDrop(player, Items.UNSTAMPED_LETTER_682) + } + return@let branch + } + optionBuilder.option_playerl("Alright I'll try and get it.") + .npcl("I am sure you won't get any problems. Speak to the Curator of Varrock's museum.") + .end() + } + branch.onValue(2) + .playerl(FacialExpression.FRIENDLY, "Hello.") + .npcl(FacialExpression.FRIENDLY, "Hello again.") + .playerl(FacialExpression.FRIENDLY, "Here is the stamped letter you asked for.") + .betweenStage { _, player, _, _ -> + if (inInventory(player, Items.SEALED_LETTER_683)) { + removeItem(player, Items.SEALED_LETTER_683) + } + if(getQuestStage(player, Quests.THE_DIG_SITE) == 2) { + setQuestStage(player, Quests.THE_DIG_SITE, 3) + } + } + .npcl(FacialExpression.NEUTRAL, "Good, good. We will begin the exam...") + .goto(continuePath) + branch.onValue(3) + .playerl(FacialExpression.FRIENDLY, "Hello.") + .npcl(FacialExpression.FRIENDLY, "Hello again. Are you ready for another shot at the exam?") + .options().let { optionBuilder -> + val continuePath2 = b.placeholder() + optionBuilder.option_playerl("Yes, I certainly am. ") + .goto(continuePath) // Continue down below. + optionBuilder.option_playerl("No, not at the moment.") + .npcl(FacialExpression.NEUTRAL, "Okay, take your time if you wish.") + .end() + return@let continuePath2.builder() + } + + + return@let continuePath.builder() + } + .npcl(FacialExpression.NEUTRAL, "Okay, we will start with the first exam: Earth Sciences level 1 - Beginner.") + .npcl(FacialExpression.NEUTRAL, "Question 1 - Earth Sciences overview. Can you tell me what Earth Sciences is?") + .options().let { optionBuilder -> + val continuePath = b.placeholder() + optionBuilder.recordAttribute(TheDigSite.attributeFirstQuestion) + optionBuilder.optionIf("The study of gardening, planing and fruiting vegetation.") { + player -> return@optionIf !getAttribute(player, TheDigSite.attributeStudentGreenExam1ObtainAnswer, false) } + .playerl("The study of gardening, planing and fruiting vegetation.") + .goto(continuePath) + optionBuilder.optionIf("The study of the earth, its contents and history.") { + player -> return@optionIf getAttribute(player, TheDigSite.attributeStudentGreenExam1ObtainAnswer, false) } + .playerl("The study of the earth, its contents and history.") + .goto(continuePath) + optionBuilder.option_playerl("The study of planets and the history of worlds.").goto(continuePath) + optionBuilder.option_playerl("The combination of archaeology and vegetarianism.").goto(continuePath) + return@let continuePath.builder() + } + .npcl("Okay, next question...") + .npcl(FacialExpression.NEUTRAL, "Earth Sciences level 1, question 2 - Eligibility. Can you tell me which people are allowed to use the digsite?") + .options().let { optionBuilder -> + val continuePath = b.placeholder() + optionBuilder.recordAttribute(TheDigSite.attributeSecondQuestion) + optionBuilder.optionIf("Magic users, miners and their escorts.") { + player -> return@optionIf !getAttribute(player, TheDigSite.attributeStudentBrownExam1ObtainAnswer, false) } + .playerl("Magic users, miners and their escorts.") + .goto(continuePath) + optionBuilder.option_playerl("Professors, students and workmen only.").goto(continuePath) + optionBuilder.option_playerl("Local residents, contractors and small pink fish.").goto(continuePath) + optionBuilder.optionIf("All that have passed the appropriate Earth Sciences exam.") { + player -> return@optionIf getAttribute(player, TheDigSite.attributeStudentBrownExam1ObtainAnswer, false) } + .playerl("All that have passed the appropriate Earth Sciences exam.") + .goto(continuePath) + return@let continuePath.builder() + } + .npcl("Okay, next question...") + .npcl(FacialExpression.NEUTRAL, "Earth Sciences level 1, question 3 - Health and safety. Can you tell me the proper safety points when working on a digsite?") + .options().let { optionBuilder -> + val continuePath = b.placeholder() + optionBuilder.recordAttribute(TheDigSite.attributeThirdQuestion) + optionBuilder.optionIf("Heat-resistant clothing to be worn at all times.") { + player -> return@optionIf !getAttribute(player, TheDigSite.attributeStudentPurpleExam1ObtainAnswer, false) } + .playerl("Heat-resistant clothing to be worn at all times.") + .goto(continuePath) + optionBuilder.option_playerl("Rubber chickens to be worn on the head at all times.").goto(continuePath) + optionBuilder.optionIf("Gloves and boots to be warn at all times; proper tools must be used.") { + player -> return@optionIf getAttribute(player, TheDigSite.attributeStudentPurpleExam1ObtainAnswer, false) } + .playerl("Gloves and boots to be warn at all times; proper tools must be used.") + .goto(continuePath) + optionBuilder.option_playerl("Protective clothing to be worn; tools kept away from site.").goto(continuePath) + return@let continuePath.builder() + } + .npcl("Okay, that covers the level 1 Earth Sciences exam.") + .npcl(FacialExpression.HAPPY, "Let's see how you did...") + .branch { player -> + var ansCount = 0 + if (getAttribute(player, TheDigSite.attributeFirstQuestion, -1) == 0 && + getAttribute(player, TheDigSite.attributeStudentGreenExam1ObtainAnswer, false)) { + ansCount++ + } + if (getAttribute(player, TheDigSite.attributeSecondQuestion, -1) == 2 && + getAttribute(player, TheDigSite.attributeStudentBrownExam1ObtainAnswer, false)) { + ansCount++ + } + if (getAttribute(player, TheDigSite.attributeThirdQuestion, -1) == 1 && + getAttribute(player, TheDigSite.attributeStudentPurpleExam1ObtainAnswer, false)) { + ansCount++ + } + return@branch ansCount + } + .let { branch -> + + branch.onValue(0) + .npcl(FacialExpression.ANGRY, "Oh dear me! This is appalling, none correct at all! I suggest you go and study properly.") + .playerl(FacialExpression.SAD, "Oh dear...") + .npcl("Why don't you use the resources here? There are books and the researchers... and you could even ask other students who are also studying for these exams.") + .end() + + branch.onValue(1) + .npcl(FacialExpression.FRIENDLY, "You got one question correct. Better luck next time.") + .playerl(FacialExpression.FRIENDLY, "Oh bother!") + .npcl(FacialExpression.FRIENDLY, "Do some more research. I'm sure other students could help you out.") + .end() + + branch.onValue(2) + .npcl(FacialExpression.FRIENDLY, "You got two questions correct. Not bad, just a little more revision needed.") + .playerl(FacialExpression.FRIENDLY, "Oh well...") + .end() + + branch.onValue(3) + .npcl(FacialExpression.FRIENDLY, "You got all the questions correct. Well done!") + .playerl(FacialExpression.FRIENDLY, "Hey! Excellent!") + .betweenStage { _, player, _, _ -> + addItemOrDrop(player, Items.TROWEL_676) + addItemOrDrop(player, Items.LEVEL_1_CERTIFICATE_691) + } + .npcl(FacialExpression.FRIENDLY, "You have now passed the Earth Sciences level 1 general exam. Here is your certificate to prove it. You also get a decent trowel to dig with. Of course, you'll want to get studying for your next exam now!") + .endWith { _, player -> + // Because of onQuestStages and onPredicate, changing quest stage before the dialogue finishes breaks the flow. + // As every stage, the onQuestStages and onPredicate functions are ran, so changing the values will switch out the stages. + if(getQuestStage(player, Quests.THE_DIG_SITE) == 3) { + setQuestStage(player, Quests.THE_DIG_SITE, 4) + } + openInterface(player, 440) + setInterfaceText(player, player.username, 440, 5) + } + + } + + // Fallback dialogue. + b.onPredicate { _ -> true } + .playerl(FacialExpression.FRIENDLY, "Hello.") + .npcl(FacialExpression.FRIENDLY, "Ah hello there! I am the resident lecturer on antiquities and artefacts. I also set the Earth Sciences exams.") + .playerl(FacialExpression.FRIENDLY, "Earth Sciences?") + .npcl(FacialExpression.FRIENDLY, "That is right dear, the world of 2009Scape holds many wonders beneath its surface. Students come to me to take exams so that they may join in on the archaeological dig going on just north of here.") + .playerl(FacialExpression.FRIENDLY, "So if they don't pass the exams they can't dig at all?") + .npcl(FacialExpression.FRIENDLY, "That's right! We have to make sure that students know enough to be able to dig safely and not damage the artefacts.") + .options().let { optionBuilder -> + optionBuilder.option_playerl("Can I take an exam?") + .npcl(FacialExpression.FRIENDLY, "You can if you get this letter stamped by the Curator of Varrock's museum.") + .betweenStage { _, player, _, _ -> + addItemOrDrop(player, Items.UNSTAMPED_LETTER_682) + } + .playerl(FacialExpression.FRIENDLY, "Why's that then?") + .npcl(FacialExpression.FRIENDLY, "Because he is a very knowledgeable man and employs our archaeological expert. I'm sure he knows a lot about your exploits and can judge whether you'd make a good archaeologist or not.") + .npcl(FacialExpression.FRIENDLY, "Besides, the museum contributes funds to the dig.") + .playerl(FacialExpression.FRIENDLY, "But why are you writing the letter? Shouldn't he?") + .npcl(FacialExpression.FRIENDLY, "He's also a very busy man, so I write the letters and he justs stamps them if he approves.") + .playerl(FacialExpression.FRIENDLY, "Oh, I see. I'll ask him if he'll approve me, and bring my stamped letter back here. Thanks.") + .endWith { _, player -> + if(getQuestStage(player, Quests.THE_DIG_SITE) == 0) { + setQuestStage(player, Quests.THE_DIG_SITE, 1) + } + } + optionBuilder.option_playerl("Interesting...") + .npcl(FacialExpression.FRIENDLY, "You could gain much with an understanding of the world below.") + .end() + } + + } +} diff --git a/Server/src/main/content/region/misthalin/digsite/dialogue/MuseumGuardDialogue.kt b/Server/src/main/content/region/misthalin/digsite/dialogue/MuseumGuardDialogue.kt new file mode 100644 index 0000000..7d72cee --- /dev/null +++ b/Server/src/main/content/region/misthalin/digsite/dialogue/MuseumGuardDialogue.kt @@ -0,0 +1,27 @@ +package content.region.misthalin.digsite.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class MuseumGuardDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage) { + START_DIALOGUE -> npc(FacialExpression.FRIENDLY, "Hello there! Sorry, I can't stop to talk. I'm guarding this", "workman's gate. I'm afraid you can't come through here -", "you'll need to find another way around.").also { + stage = END_DIALOGUE + } + } + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return MuseumGuardDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.MUSEUM_GUARD_5942) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/digsite/dialogue/ResearcherDialogue.kt b/Server/src/main/content/region/misthalin/digsite/dialogue/ResearcherDialogue.kt new file mode 100644 index 0000000..64af6e1 --- /dev/null +++ b/Server/src/main/content/region/misthalin/digsite/dialogue/ResearcherDialogue.kt @@ -0,0 +1,41 @@ +package content.region.misthalin.digsite.dialogue + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class ResearcherDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + if (isQuestComplete(player, Quests.THE_DIG_SITE)){ + when (stage) { + START_DIALOGUE -> npcl(FacialExpression.FRIENDLY, "Hello there. What are you doing here?").also { stage++ } + 1 -> playerl(FacialExpression.FRIENDLY, "Just looking around at the moment.").also { stage++ } + 2 -> npcl(FacialExpression.FRIENDLY, "Well, feel free to talk to me should you come across anything you can't figure out.").also { + stage = END_DIALOGUE + } + } + } else { + when (stage) { + START_DIALOGUE -> npcl(FacialExpression.FRIENDLY, "Hello there. What are you doing here?").also { stage++ } + 1 -> playerl(FacialExpression.FRIENDLY, "Just looking around at the moment.").also { stage++ } + 2 -> npcl(FacialExpression.FRIENDLY, "Well, feel free to talk to me should you come across anything you can't figure out.").also { + stage = END_DIALOGUE + } + } + } + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return ResearcherDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.RESEARCHER_4568) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/ArchaeologicalExpertDialogue.kt b/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/ArchaeologicalExpertDialogue.kt new file mode 100644 index 0000000..3f4ea3d --- /dev/null +++ b/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/ArchaeologicalExpertDialogue.kt @@ -0,0 +1,117 @@ +package content.region.misthalin.digsite.quest.thedigsite + +import content.region.desert.quest.deserttreasure.DesertTreasure +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import org.rs09.consts.NPCs +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items + + +@Initializable +class ArchaeologicalExpertDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, ArchaeologicalExpertDialogueFile(), npc) + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return ArchaeologicalExpertDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.ARCHAEOLOGICAL_EXPERT_619) + } +} +class ArchaeologicalExpertDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + + b.onQuestStages(DesertTreasure.questName, 4,5,6,7,8,9,10,11,12,13,14,15,100) + .npc("Hello again.", "Was that translation any use to Asgarnia?") + .playerl("I think it was, thanks!") + .end() + + b.onQuestStages(DesertTreasure.questName, 3) + .branch { player -> + return@branch if (inInventory(player, Items.TRANSLATION_4655)) { 1 } else { 0 } + }.let { branch -> + branch.onValue(1) + .npc("Hello again.", "Was that translation any use to Asgarnia?") + .playerl(FacialExpression.SUSPICIOUS, "I, uh, kind of didn't take it to him yet...") + .npc(FacialExpression.THINKING, "Whyever not?", "You're the strangest delivery @g[boy,girl] I've ever met!") + .end() + branch.onValue(0) + .playerl("I lost that translation you gave me...") + .npcl("Oh, no matter, I mostly remember what it said anyway! Here you go!") + .endWith { _, player -> + addItemOrDrop(player, Items.TRANSLATION_4655) + } + } + b.onQuestStages(DesertTreasure.questName, 2) + .betweenStage { df, player, _, _ -> + addItemOrDrop(player, Items.TRANSLATION_4655) + } + .npcl("There you go, that book contains the sum of my translating ability. If you would be so kind as to take that back to Asgarnia, I think it will reassure him that he is on the") + .npcl("right track for a find of great archaeological importance!") + .playerl("Wow! You write really quickly don't you?") + .npcl("What can I say? It's a skill I picked up through my many years of taking field notes!") + .endWith { _, player -> + if(getQuestStage(player, DesertTreasure.questName) == 2) { + setQuestStage(player, DesertTreasure.questName, 3) + } + } + + b.onQuestStages(DesertTreasure.questName, 1) + .playerl("Hello, are you Terry Balando?") + .npcl("That's right, who wants to know...?") + .npcl("Ah yes, I recognise you! You're the fellow who found that strange artefact about Zaros for the museum, aren't you? What can I do for you now?") + .playerl("That's right. I was in the desert down by the Bedabin Camp, and I found an archaeologist who asked me to deliver this to you.") + .npcl("You spoke to the legendary Asgarnia Smith??? Quickly, let me see what he had to give you! He is always at the forefront of archaeological breakthroughs!") + .betweenStage { df, player, _, _ -> + removeItem(player, Items.ETCHINGS_4654) // remove if exists + } + .playerl("So what does the inscription say? Anything interesting?") + .npcl("This... this is fascinating! These cuneiforms seem to predate even the settlement we are excavating here... Yes, yes, this is most interesting indeed!") + .playerl("Can you translate it for me?") + .npc("Well, I am not familiar with this particular language, but", "the similarities inherent in the pictographs seem to show", "a prevalent trend towards a syllabary consistent with", "the phonemes we have discovered in this excavation!") + .playerl("Um... So, can you translate it for me or not?") + .npcl("Well, unfortunately this is the only example of this particular language I have ever seen, but I might be able to make a rough translation, of sorts...") + .npcl("It might be slightly obscure on the finer details, but it should be good enough to understand the rough meaning of what was originally written. Please, just wait a moment, I will write up what I can") + .npcl("translate into a journal for you. Then you can take it back to Asgarnia, I think he will be extremely interested in the translation!") + .endWith { _, player -> + if(getQuestStage(player, DesertTreasure.questName) == 1) { + setQuestStage(player, DesertTreasure.questName, 2) + } + } + + // Fallback dialogue. + b.onPredicate { player -> true } + .playerl(FacialExpression.FRIENDLY, "Hello. Who are you?") + .npcl(FacialExpression.FRIENDLY, "Good day to you. My name is Terry Balando, I am an expert archaeologist. I am employed by Varrock Museum to oversee all finds at this site. Anything you find must be reported to me.") + .playerl(FacialExpression.FRIENDLY, "Oh, okay. If I find anything of interest I will bring it here.") + .npcl(FacialExpression.FRIENDLY, "Can I help you at all?") + .options().let { optionBuilder -> + optionBuilder.option_playerl("I have something I need checking out.") + .npcl(FacialExpression.FRIENDLY, "Okay, give it to me and I'll have a look for you.") + .end() + optionBuilder.option_playerl("No thanks.") + .npcl("Good, let me know if you find anything unusual.") + .end() + optionBuilder.option_playerl("Can you tell me anything about the digsite?") + .npcl("Yes, indeed! I am studying the lives of the settlers. During the end of the Third Age, there used to be a great city at the site. Its inhabitants were humans, supporters of the god Saradomin. It's not recorded what happened to the community here. I suspect nobody has lived here for over a millennium!") + .end() + // I lost the letter you gave me. + + optionBuilder.option_playerl("Can you tell me more about the tools an archaeologist uses?") + .npcl(FacialExpression.FRIENDLY, "Of course! Let's see now... Trowels are vital for fine digging work, so you can be careful to not damage or disturb any artefacts. Rock picks are for splitting rocks or scraping away soil.") + .playerl(FacialExpression.FRIENDLY, "What about specimen jars and brushes?") + .npcl(FacialExpression.FRIENDLY, "Those are essential for carefully cleaning and storing smaller samples.") + .playerl(FacialExpression.FRIENDLY, "Where can I get any of these things?") + .npcl(FacialExpression.FRIENDLY, "Well, we've come into a bit more funding of late, so there should be a stock of each of them in the Exam Centre's tools cupboard. We also hand out relevant tools as students complete each level of their Earth Sciences exams.") + .playerl(FacialExpression.FRIENDLY, "Ah, okay, thanks.") + .end() + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/ArchaeologicalExpertListener.kt b/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/ArchaeologicalExpertListener.kt new file mode 100644 index 0000000..296e9fc --- /dev/null +++ b/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/ArchaeologicalExpertListener.kt @@ -0,0 +1,137 @@ +package content.region.misthalin.digsite.quest.thedigsite + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.FacialExpression +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.Item +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class ArchaeologicalExpertListener : InteractionListener { + + + val staff = Items.ANCIENT_STAFF_4675 + val unidentifiedLiquid = Items.UNIDENTIFIED_LIQUID_702 + val nitroglycerin = Items.NITROGLYCERIN_703 + val chemicalPowder = Items.CHEMICAL_POWDER_700 + val ammoniumNitrate = Items.AMMONIUM_NITRATE_701 + val nuggets = Items.NUGGETS_680 + val needle = Items.NEEDLE_1733 + val rottenApple = Items.ROTTEN_APPLE_1984 + val brokenGlass = Items.BROKEN_GLASS_1469 + val brokenArrow = Items.BROKEN_ARROW_687 + val panningTray = Items.PANNING_TRAY_677 + val bones = Items.BONES_526 + val buttons = Items.BUTTONS_688 + val crackedSample = Items.CRACKED_SAMPLE_674 + val oldTooth = Items.OLD_TOOTH_695 + val rustySword = Items.RUSTY_SWORD_686 + val brokenStaff = Items.BROKEN_STAFF_689 + val brokenArmour = Items.BROKEN_ARMOUR_698 + val damagedArmour = Items.DAMAGED_ARMOUR_697 + val ceramicRemains = Items.CERAMIC_REMAINS_694 + val beltBuckle = Items.BELT_BUCKLE_684 + val animalSkull = Items.ANIMAL_SKULL_671 + val specialCup = Items.SPECIAL_CUP_672 + val teddy = Items.TEDDY_673 + val stoneTablet = Items.STONE_TABLET_699 + + val items = intArrayOf(staff, unidentifiedLiquid, nitroglycerin, chemicalPowder, ammoniumNitrate, nuggets, needle, rottenApple, + brokenGlass, brokenArrow, panningTray, bones, buttons, crackedSample, oldTooth, rustySword, brokenStaff, brokenArmour, + damagedArmour, ceramicRemains, beltBuckle, animalSkull, specialCup, teddy, stoneTablet) + + val archy = NPCs.ARCHAEOLOGICAL_EXPERT_619 + + + override fun defineListeners() { + onUseAnyWith(IntType.NPC, NPCs.ARCHAEOLOGICAL_EXPERT_619) { player, used, with -> + openDialogue(player, ArchaeologicalExpertListenerDialogueFile(used.id), with as NPC) + return@onUseAnyWith false + } + } +} +class ArchaeologicalExpertListenerDialogueFile(val it: Int) : DialogueBuilderFile() { + + companion object { + fun replaceAll(player: Player, originalItem: Int, newItem: Int) { + for (a in 0..amountInInventory(player, originalItem)) { + if (inInventory(player, originalItem)) { + replaceSlot(player, player.inventory.getSlot(Item(originalItem)), Item(newItem)) + } + } + } + } + + override fun create(b: DialogueBuilder) { + + b.onPredicate { _ -> it == Items.UNIDENTIFIED_LIQUID_702 } + .player(FacialExpression.THINKING, "Do you know what this is?") + .npcl(FacialExpression.WORRIED, "Where did you get this?") + .player("From one of the barrels at the digsite.") + .npcl(FacialExpression.WORRIED, "This is a VERY dangerous liquid called nitroglycerin. Be careful how you handle it. Don't drop it or it will explode!") + .endWith { _, player -> + replaceAll(player, Items.UNIDENTIFIED_LIQUID_702, Items.NITROGLYCERIN_703) + } + + b.onPredicate { _ -> it == Items.NITROGLYCERIN_703 } + .player(FacialExpression.THINKING, "Can you tell me any more about this?") + .npcl(FacialExpression.WORRIED, "Nitroglycerin! This is a dangerous substance. This is normally mixed with other chemicals to produce a potent compound.") + .npcl(FacialExpression.WORRIED, "Be sure not to drop it! That stuff is highly volatile...") + .end() + + b.onPredicate { _ -> it == Items.CHEMICAL_POWDER_700 } + .player(FacialExpression.THINKING, "Do you know what this powder is?") + .npcl(FacialExpression.WORRIED, "Really, you do find the most unusual items. I know what this is - it's a strong chemical called ammonium nitrate. Why you want this I'll never know...") + .endWith { _, player -> + replaceAll(player, Items.CHEMICAL_POWDER_700, Items.AMMONIUM_NITRATE_701) + } + + // b.onPredicate { _ -> it == Items.AMMONIUM_NITRATE_701 } From youtu.be/mKTBPLdxRSY at 9:57, once ammonium nitrate is identified, it becomes not of any archaeological significance. + + b.onPredicate { _ -> it == Items.ANCIENT_TALISMAN_681 } + .npcl(FacialExpression.FRIENDLY, "Unusual... This object doesn't appear right...") + .npcl(FacialExpression.FRIENDLY, "Hmmm...") + .npcl(FacialExpression.FRIENDLY, "I wonder... Let me check my guide... Could it be? Surely not!") + .npcl(FacialExpression.FRIENDLY, "From the markings on it, it seems to be a ceremonial ornament to a god named...") + .npcl(FacialExpression.FRIENDLY, "...Zaros? I haven't heard much about him before. This is a great discovery; we know very little of the ancient gods that people worshipped.") + .npcl(FacialExpression.FRIENDLY, "There is some strange writing embossed upon it - it says, 'Zaros will return and wreak his vengeance upon Zamorak the pretender.'") + .npcl(FacialExpression.FRIENDLY, "I wonder what it means by that. Some silly superstition, probably.") + .npcl(FacialExpression.FRIENDLY, "Still, I wonder what this is doing around here. I'll tell you what; as you have found this, I will allow you to use the private dig shafts.") + .npcl(FacialExpression.FRIENDLY, "You obviously have a keen eye. Take this letter and give it to one of the workmen, and they will allow you to use them.") + .endWith { _, player -> + if (removeItem(player, Items.ANCIENT_TALISMAN_681)) { + addItemOrDrop(player, Items.INVITATION_LETTER_696) + } + if(getQuestStage(player, Quests.THE_DIG_SITE) == 6) { + setQuestStage(player, Quests.THE_DIG_SITE, 7) + } + } + + b.onPredicate { _ -> it == Items.STONE_TABLET_699 } + .playerl(FacialExpression.FRIENDLY, "I found this in a hidden cavern beneath the site.") + .npcl(FacialExpression.FRIENDLY, "Incredible!") + .playerl(FacialExpression.FRIENDLY, "There is an altar down there. The place is crawling with skeletons!") + .npcl(FacialExpression.FRIENDLY, "Yuck! This is an amazing discovery! All this while we were convinced that no other race had lived here.") + .npcl("It seems the followers of Saradomin have tried to cover up the evidence of this Zaros altar. This whole city must have been built over it!") + .npcl("Thanks for your help; your sharp eyes have spotted what many have missed. Here, take this gold as your reward.") + .item(Items.GOLD_BAR_2357, "The expert gives you two gold bars as payment.") + .endWith { _, player -> + if (removeItem(player, Items.STONE_TABLET_699)) { + if(getQuestStage(player, Quests.THE_DIG_SITE) == 11) { + finishQuest(player, Quests.THE_DIG_SITE) + } + } + } + + // Fallback when item isn't recognizable. + b.onPredicate { _ -> true } + .npcl(FacialExpression.FRIENDLY, "I don't think that has any archaeological significance.") + .end() + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/DigsiteWorkmanDialogue.kt b/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/DigsiteWorkmanDialogue.kt new file mode 100644 index 0000000..38830c4 --- /dev/null +++ b/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/DigsiteWorkmanDialogue.kt @@ -0,0 +1,73 @@ +package content.region.misthalin.digsite.quest.thedigsite + +import content.data.Quests +import core.api.* +import core.game.dialogue.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class DigsiteWorkmanDialogue (player: Player? = null) : DialoguePlugin(player), InteractionListener { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + npc!! + when(stage) { + START_DIALOGUE -> playerl(FacialExpression.FRIENDLY, "Hello!").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "Why hello there! What can I do you for?").also { stage++ } + 2 -> showTopics( + Topic(FacialExpression.FRIENDLY, "What do you do here?", 3), + Topic(FacialExpression.FRIENDLY, "I'm not sure.", 6), + Topic(FacialExpression.FRIENDLY, "Can I dig around here?", 7), + ) + 3 -> npcl(FacialExpression.FRIENDLY, "Well, my job involved digging for finds, cleaning them and transporting them for identification.").also { stage++ } + 4 -> playerl(FacialExpression.FRIENDLY, "Sounds interesting.").also { stage++ } + 5 -> npcl(FacialExpression.FRIENDLY, "I find it very interesting and very rewarding. So glad to see you're taking an interest in the digsite. Hope to see you out here digging sometime!").also { + stage = END_DIALOGUE + } + 6 -> npcl(FacialExpression.FRIENDLY, "Well, let me know when you are and I'll do my very best to help you!").also { + stage = END_DIALOGUE + } + 7 -> npcl(FacialExpression.FRIENDLY, "You can only use a site you have the appropriate exam level for.").also { stage++ } + 8 -> playerl(FacialExpression.FRIENDLY, "Appropriate exam level?").also { stage++ } + 9 -> npcl(FacialExpression.FRIENDLY, "Oh yes, you need to have been trained in the various techniques before you can be allowed to dig for artefacts.").also { stage++ } + 10 -> playerl(FacialExpression.FRIENDLY, "Ah yes, I understand.").also { + stage = END_DIALOGUE + } + } + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return DigsiteWorkmanDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.DIGSITE_WORKMAN_613, NPCs.DIGSITE_WORKMAN_4564, NPCs.DIGSITE_WORKMAN_4565/*, NPCs.DIGSITE_WORKMAN_5958*/) + } + + override fun defineListeners() { + onUseWith(IntType.NPC, Items.INVITATION_LETTER_696, NPCs.DIGSITE_WORKMAN_613, NPCs.DIGSITE_WORKMAN_4564, NPCs.DIGSITE_WORKMAN_4565) { player, used, with -> + openDialogue(player, DigsiteWorkmanDialogueFile(), with as NPC) + return@onUseWith false + } + } +} +class DigsiteWorkmanDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + + // Fallback dialogue. + b.onPredicate { _ -> true } + .playerl(FacialExpression.FRIENDLY, "Here, have a look at this...") + .npc(FacialExpression.FRIENDLY, "I give permission... blah de blah... err. Okay, that's all in", "order, you may use the mineshaft now. I'll hang onto", "this scroll, shall I?") + .endWith { _, player -> + removeItem(player, Items.INVITATION_LETTER_696) + if(getQuestStage(player, Quests.THE_DIG_SITE) == 7) { + setQuestStage(player, Quests.THE_DIG_SITE, 8) + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/DougDeepingDialogue.kt b/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/DougDeepingDialogue.kt new file mode 100644 index 0000000..0756453 --- /dev/null +++ b/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/DougDeepingDialogue.kt @@ -0,0 +1,69 @@ +package content.region.misthalin.digsite.quest.thedigsite + +import core.api.* +import core.game.dialogue.* +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class DougDeepingDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, DougDeepingDialogueFile(), npc) + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return DougDeepingDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.DOUG_DEEPING_614) + } +} + +class DougDeepingDialogueFile : DialogueBuilderFile() { + + override fun create(b: DialogueBuilder) { + b.onPredicate { _ -> true } + .playerl(FacialExpression.FRIENDLY, "Hello.") + .npcl(FacialExpression.FRIENDLY, "Well, well... I have a visitor. What are you doing here?") + .options().let { optionBuilder -> + optionBuilder.option_playerl("I have been invited to research here ") + .npcl(FacialExpression.FRIENDLY, "Indeed, you must be someone special to be allowed down here.") + .options().let { optionBuilder -> + optionBuilder.option_playerl("Do you know where to find a specimen jar?") + .npcl("Hmmm, let me think... Nope, can't help you there, I'm afraid. Try asking at the Exam Centre.") + .end() + optionBuilder.option_playerl("I have things to do...") + .npcl("Of course, don't let me keep you.") + .end() + } + optionBuilder.option_playerl("I'm not really sure.") + .npcl("A miner without a clue - how funny!") + .end() + optionBuilder.option_playerl("I'm here to get rich, rich, rich!") + .npcl("Oh, well, don't forget that wealth and riches aren't everything.") + .end() + optionBuilder.option_playerl("How could I move a large pile of rocks?") + .npcl("There used to be this chap that worked in the other shaft. He was working on an explosive chemical mixture to be used for clearing blocked areas underground.") + .npcl("He left in a hurry one day. Apparently, something in the shaft scared him to death, but he didn't say what.") + .playerl(FacialExpression.FRIENDLY, "Oh?") + .npcl(FacialExpression.FRIENDLY, "Rumour has it he'd been writing a book on his chemical mixture. I'm not sure what was in it, but he left in such a hurry, he probably left something behind in the other dig shaft.") + .npcl("In fact, I still have a chest key he gave me to look after - perhaps it's more useful to you.") + .branch { player -> + if (inInventory(player,Items.CHEST_KEY_709)) { 0 } else { + addItemOrDrop(player, Items.CHEST_KEY_709) + 1 + } + } + .let { branch -> + branch.onValue(0) + .playerl("It's okay, I already have one.") + .end() + branch.onValue(1) + .iteml(Items.CHEST_KEY_709, "Doug hands you a key.") + .end() + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/PanningGuideDialogue.kt b/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/PanningGuideDialogue.kt new file mode 100644 index 0000000..c9a7d38 --- /dev/null +++ b/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/PanningGuideDialogue.kt @@ -0,0 +1,112 @@ +package content.region.misthalin.digsite.quest.thedigsite + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class PanningGuideDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, PanningGuideDialogueFile(), npc) + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return PanningGuideDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.PANNING_GUIDE_620) + } +} +class PanningGuideDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onPredicate { getAttribute(player!!, TheDigSite.attributePanningGuideTea, false) } + .playerl(FacialExpression.FRIENDLY, "Hello, who are you?") + .npcl(FacialExpression.FRIENDLY, "Hello, I am the panning guide. I'm here to teach you how to pan for gold.") + .playerl(FacialExpression.FRIENDLY, "Excellent!") + .npcl(FacialExpression.FRIENDLY, "Let me explain how panning works. First, you need a panning tray. Use the tray in the panning points in the water and then search your tray.") + .npcl("If you find any gold, take it to the archaeological expert up in the museum storage facility. He will calculate its value for you.") + .options() + .let { optionBuilder -> + optionBuilder.option_playerl("Can you tell me more about the tools an archaeologist uses?") + .npcl(FacialExpression.FRIENDLY, "Of course! Let's see now... Rock picks are for splitting rocks or scraping away soil; you can get one from a cupboard in the Exam Centre.") + .playerl(FacialExpression.FRIENDLY, "What about sample jars?") + .npcl(FacialExpression.FRIENDLY, "I think you'll find them scattered about pretty much everywhere, but I know you can get one from a cupboard somewhere in the Exam Centre, just like the rock pick!") + .playerl(FacialExpression.FRIENDLY, "Okay, what about a specimen brush?") + .npcl(FacialExpression.FRIENDLY, "We have a bit of a shortage of those at the moment. You could try borrowing one from a workman on the site... but I don't think they'd give it willingly.") + .playerl(FacialExpression.FRIENDLY, "Sounds like I'll need to be sneaky to get one of those, then... Okay - trowel?") + .npcl(FacialExpression.FRIENDLY, "Ahh... that you must earn by passing your exams! The examiner holds those.") + .playerl(FacialExpression.FRIENDLY, "Anything else?") + .npcl(FacialExpression.FRIENDLY, "If you need something identified or are not sure about something, give it to the archaeological expert in the Exam Centre.") + .playerl(FacialExpression.FRIENDLY, "Ahh, ok thanks.") + .end() + optionBuilder.option_playerl("Thank you!") + .end() + } + + b.onPredicate { _ -> true } + .playerl(FacialExpression.FRIENDLY, "Hello, who are you?") + .npcl(FacialExpression.FRIENDLY, "Hello, I am the panning guide. I teach students how to pan in these waters. They're not permitted to do so until after they've had training and, of course, they must be invited to pan here too.") + .playerl(FacialExpression.FRIENDLY, "So, how do I become invited?") + .npcl(FacialExpression.FRIENDLY, "I'm not supposed to let people pan here unless they have permission. Mind you, I could let you have a go if you're willing to do me a favour...") + .playerl(FacialExpression.FRIENDLY, "What's that?") + .npcl(FacialExpression.FRIENDLY, "Well, to be honest, what I would really like is a nice cup of tea!") + .branch { player -> if (inInventory(player, Items.CUP_OF_TEA_712)) { 1 } else { 0 } } + .let { branch -> + branch.onValue(0) + .playerl(FacialExpression.FRIENDLY, "Tea?") + .npcl(FacialExpression.FRIENDLY, "Absolutely, I'm parched!") + .npcl(FacialExpression.FRIENDLY, "If you could bring me one of those, I would be more than willing to let you pan here. I usually get some from the main campus building, but I'm busy at the moment.") + .end() + branch.onValue(1) + .playerl(FacialExpression.FRIENDLY, "I've some here that you can have.") + .npcl(FacialExpression.FRIENDLY, "Ah! Lovely! You can't beat a good cuppa! You're free to pan all you want.") + .endWith { _, player -> + if(removeItem(player, Items.CUP_OF_TEA_712)) { + setAttribute(player, TheDigSite.attributePanningGuideTea, true) + } + } + } + } +} +class PanningGuideCannotPanDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onPredicate { _ -> true } + .npcl(FacialExpression.ANNOYED, "Hey! You can't pan yet!") + .playerl(FacialExpression.THINKING, "Why not?") + .npcl("We do not allow the uninvited to pan here.") + .options() + .let { optionBuilder -> + optionBuilder.option_playerl("OK, forget it.") + .end() + return@let optionBuilder + } + .option_playerl("So how do I become invited then?") + .npcl(FacialExpression.FRIENDLY, "I'm not supposed to let people pan here unless they have permission. Mind you, I could let you have a go if you're willing to do me a favour.") + .playerl(FacialExpression.FRIENDLY, "What's that?") + .npcl(FacialExpression.FRIENDLY, "Well, to be honest, what I would really like is a nice cup of tea!") + .branch { player -> if (inInventory(player, Items.CUP_OF_TEA_712)) { 1 } else { 0 } } + .let { branch -> + branch.onValue(0) + .playerl(FacialExpression.FRIENDLY, "Tea?") + .npcl(FacialExpression.FRIENDLY, "Absolutely, I'm parched!") + .npcl(FacialExpression.FRIENDLY, "If you could bring me one of those, I would be more than willing to let you pan here. I usually get some from the main campus building, but I'm busy at the moment.") + .end() + branch.onValue(1) + .playerl(FacialExpression.FRIENDLY, "I've some here that you can have.") + .betweenStage { _, player, _, _ -> + if(removeItem(player, Items.CUP_OF_TEA_712)) { + setAttribute(player, TheDigSite.attributePanningGuideTea, true) + } + } + .npcl(FacialExpression.FRIENDLY, "Ah! Lovely! You can't beat a good cuppa! You're free to pan all you want.") + .end() + } + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/StudentsDialogue.kt b/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/StudentsDialogue.kt new file mode 100644 index 0000000..5ac84d0 --- /dev/null +++ b/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/StudentsDialogue.kt @@ -0,0 +1,344 @@ +package content.region.misthalin.digsite.quest.thedigsite + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class StudentGreenDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, StudentGreenDialogueFile(), npc) + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return StudentGreenDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.STUDENT_615) + } +} +class StudentGreenDialogueFile : DialogueBuilderFile() { + + override fun create(b: DialogueBuilder) { + + + b.onQuestStages(Quests.THE_DIG_SITE, 6, 7, 8, 9, 10, 11, 12, 13, 100) + .npcl(FacialExpression.FRIENDLY, " Oh, hi again. News of your find has spread fast; you are quite famous around here now.") + + b.onQuestStages(Quests.THE_DIG_SITE, 5) + .playerl(FacialExpression.FRIENDLY, "Hello there.") + .npcl(FacialExpression.FRIENDLY, "How's it going?") + .playerl(FacialExpression.FRIENDLY, "I need more help with the exam.") + .npcl(FacialExpression.FRIENDLY, "Well, okay, this is what I have learned since I last spoke to you...") + .npcl(FacialExpression.FRIENDLY, "Specimen brush use: Brush carefully and slowly using short strokes.") + .playerl(FacialExpression.FRIENDLY, "Okay, I'll remember that. Thanks for all your help.") + .endWith { _, player -> + setAttribute(player, TheDigSite.attributeStudentGreenExam3ObtainAnswer, true) + } + + b.onQuestStages(Quests.THE_DIG_SITE, 4) + .playerl(FacialExpression.FRIENDLY, "Hello there.") + .npcl(FacialExpression.FRIENDLY, "How's it going?") + .playerl(FacialExpression.FRIENDLY, "I need more help with the exam.") + .npcl(FacialExpression.FRIENDLY, "Well, okay, this is what I have learned since I last spoke to you...") + .npcl(FacialExpression.FRIENDLY, "Correct rock pick usage: Always handle with care; strike the rock cleanly on its cleaving point.") + .playerl(FacialExpression.FRIENDLY, "Okay, I'll remember that.") + .endWith { _, player -> + setAttribute(player, TheDigSite.attributeStudentGreenExam2ObtainAnswer, true) + } + b.onPredicate { player -> getQuestStage(player, Quests.THE_DIG_SITE) == 3 && getAttribute(player, TheDigSite.attributeStudentGreenExam1ObtainAnswer, false)} + .playerl(FacialExpression.FRIENDLY, "Hello there.") + .npcl(FacialExpression.FRIENDLY, "How's it going?") + .playerl(FacialExpression.FRIENDLY, "I need more help with the exam.") + .npcl(FacialExpression.FRIENDLY, "Well, okay, this is what I have learned since I last spoke to you...") + .npcl(FacialExpression.FRIENDLY, "The study of Earth Sciences is: The study of the earth, its contents and history.") + .playerl(FacialExpression.FRIENDLY, "Okay, I'll remember that.") + .endWith { _, player -> + setAttribute(player, TheDigSite.attributeStudentGreenExam1ObtainAnswer, true) + } + b.onPredicate { player -> getQuestStage(player, Quests.THE_DIG_SITE) == 3 && getAttribute(player, TheDigSite.attributeStudentGreenExam1Talked, false)} + .branch { player -> + return@branch if (inInventory(player, Items.ANIMAL_SKULL_671)) { 1 } else { 0 } + }.let{ branch -> + branch.onValue(0) + .playerl(FacialExpression.FRIENDLY, "Hello there. How's the study going?") + .npcl(FacialExpression.FRIENDLY, "Very well, thanks. Have you found my animal skull yet?") + .playerl(FacialExpression.FRIENDLY, "No, sorry, not yet.") + .npcl(FacialExpression.FRIENDLY, "Oh well, I am sure it's been picked up. Couldn't you try looking through some pockets?") + .end() + branch.onValue(1) + .playerl(FacialExpression.FRIENDLY, "Hello there. How's the study going?") + .npcl(FacialExpression.FRIENDLY, "Very well, thanks. Have you found my animal skull yet?") + .betweenStage { _, player, _, _ -> + if (inInventory(player, Items.ANIMAL_SKULL_671)){ + removeItem(player, Items.ANIMAL_SKULL_671) + } + } + .npcl("Oh wow! You've found it! Thank you so much. I'll be glad to tell you what I know about the exam. The study of Earth Sciences is: The study of the earth, its contents and history.") + .endWith { _, player -> + setAttribute(player, TheDigSite.attributeStudentGreenExam1ObtainAnswer, true) + } + return@let branch + } + b.onQuestStages(Quests.THE_DIG_SITE, 3) + .playerl(FacialExpression.FRIENDLY, "Hello there. Can you help me with the Earth Sciences exams at all?") + .npcl(FacialExpression.FRIENDLY, "Well... Maybe I will if you help me with something.") + .playerl(FacialExpression.FRIENDLY, "What's that?") + .npcl(FacialExpression.FRIENDLY, "I have lost my recent good find.") + .playerl(FacialExpression.FRIENDLY, "What does it look like?") + .npcl(FacialExpression.FRIENDLY, "Err... Like an animal skull!") + .playerl(FacialExpression.FRIENDLY, "Well, that's not too helpful, there are lots of those around here. Can you remember where you last had it?") + .npcl(FacialExpression.FRIENDLY, "It was around here for sure. Maybe one of the workmen picked it up?") + .playerl(FacialExpression.FRIENDLY, "Okay, I'll have a look for you.") + .endWith { _, player -> + setAttribute(player, TheDigSite.attributeStudentGreenExam1Talked, true) + } + b.onPredicate { _ -> true } + .playerl(FacialExpression.FRIENDLY, "Hello there.") + .npcl(FacialExpression.FRIENDLY, "Oh, hi. I'm studying hard for an exam.") + .playerl(FacialExpression.FRIENDLY, "What exam is that?") + .npcl(FacialExpression.FRIENDLY, "It's the Earth Sciences exam.") + .playerl(FacialExpression.FRIENDLY, "Interesting....") + .end() + } +} + + +@Initializable +class StudentPurpleDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, StudentPurpleDialogueFile(), npc) + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return StudentPurpleDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.STUDENT_617) + } +} +class StudentPurpleDialogueFile : DialogueBuilderFile() { + + override fun create(b: DialogueBuilder) { + + b.onPredicate { player -> getQuestStage(player, Quests.THE_DIG_SITE) == 5 && getAttribute(player, TheDigSite.attributeStudentPurpleExam3ObtainAnswer, false)} + .playerl(FacialExpression.FRIENDLY, "Hello there.") + .npcl(FacialExpression.FRIENDLY, "How's it going?") + .playerl(FacialExpression.FRIENDLY, "I am stuck on some more exam questions.") + .npcl(FacialExpression.FRIENDLY, "Okay, I'll tell you my latest notes...") + .npcl(FacialExpression.FRIENDLY, "Sample preparation: Samples cleaned, and carried only in specimen jars.") + .playerl(FacialExpression.FRIENDLY, "Great, thanks for your advice.") + .endWith { _, player -> + setAttribute(player, TheDigSite.attributeStudentPurpleExam3ObtainAnswer, true) + } + + b.onPredicate { player -> getQuestStage(player, Quests.THE_DIG_SITE) == 5 && getAttribute(player, TheDigSite.attributeStudentPurpleExam3Talked, false)} + .branch { player -> + return@branch if (inInventory(player, Items.OPAL_1609) || inInventory(player, Items.UNCUT_OPAL_1625)) { 1 } else { 0 } + }.let{ branch -> + branch.onValue(0) + .playerl(FacialExpression.FRIENDLY, "Hello there.") + .npcl(FacialExpression.FRIENDLY, "Oh, hi again. Did you bring me the opal?") + .playerl(FacialExpression.FRIENDLY, "I haven't found one yet.") + .npcl(FacialExpression.FRIENDLY, "Oh, well, tell me when you do. Remember that they can be found around the site; perhaps try panning the river.") + .end() + branch.onValue(1) + .playerl(FacialExpression.FRIENDLY, "Hello there.") + .npcl(FacialExpression.FRIENDLY, "Oh, hi again. Did you bring me the opal?") + .betweenStage { _, player, _, _ -> + if (inInventory(player, Items.UNCUT_OPAL_1625)){ + removeItem(player, Items.UNCUT_OPAL_1625) + return@betweenStage + } + if (inInventory(player, Items.OPAL_1609)){ + removeItem(player, Items.OPAL_1609) + return@betweenStage + } + } + .playerl(FacialExpression.FRIENDLY, "Would an opal look like this by any chance?") + .npcl(FacialExpression.FRIENDLY, "Wow, great, you've found one. This will look beautiful set in my necklace. Thanks for that; now I'll tell you what I know... Sample preparation: Samples cleaned, and carried only in specimen jars.") + .playerl(FacialExpression.FRIENDLY, "Great, thanks for your advice.") + .endWith { _, player -> + setAttribute(player, TheDigSite.attributeStudentPurpleExam3ObtainAnswer, true) + } + return@let branch + } + + b.onQuestStages(Quests.THE_DIG_SITE, 5) + .playerl(FacialExpression.FRIENDLY, "Hello there.") + .npcl(FacialExpression.FRIENDLY, "What, you want more help?") + .playerl(FacialExpression.FRIENDLY, "Err... Yes please!") + .npcl(FacialExpression.FRIENDLY, "Well... it's going to cost you...") + .playerl(FacialExpression.FRIENDLY, "Oh, well how much?") + .npcl(FacialExpression.FRIENDLY, "I'll tell you what I would like: a precious stone. I don't find many of them. My favorite are opals; they are beautiful. Just like me! Tee hee hee!") + .playerl(FacialExpression.FRIENDLY, "Err... OK I'll see what I can do, but I'm not sure where I'd get one.") + .npcl(FacialExpression.FRIENDLY, "Well, I have seen people get them from panning occasionally.") + .playerl(FacialExpression.FRIENDLY, "OK, I'll see what I can turn up for you.") + .endWith { _, player -> + setAttribute(player, TheDigSite.attributeStudentPurpleExam3Talked, true) + } + + b.onQuestStages(Quests.THE_DIG_SITE, 4) + .playerl(FacialExpression.FRIENDLY, "Hello there.") + .npcl(FacialExpression.FRIENDLY, "How's it going?") + .playerl(FacialExpression.FRIENDLY, "I am stuck on some more exam questions.") + .npcl(FacialExpression.FRIENDLY, "Okay, I'll tell you my latest notes...") + .npcl(FacialExpression.FRIENDLY, "Finds handling: Finds must be carefully handled.") + .playerl(FacialExpression.FRIENDLY, "Great, thanks for your advice.") + .endWith { _, player -> + setAttribute(player, TheDigSite.attributeStudentPurpleExam2ObtainAnswer, true) + } + b.onPredicate { player -> getQuestStage(player, Quests.THE_DIG_SITE) == 3 && getAttribute(player, TheDigSite.attributeStudentPurpleExam1ObtainAnswer, false)} + .playerl(FacialExpression.FRIENDLY, "Hello there.") + .npcl(FacialExpression.FRIENDLY, "How's it going?") + .playerl(FacialExpression.FRIENDLY, "I am stuck on some more exam questions.") + .npcl(FacialExpression.FRIENDLY, "Okay, I'll tell you my latest notes...") + .npcl(FacialExpression.FRIENDLY, "The proper health and safety points are: Leather gloves and boots to be warn at all times; proper tools must be used.") + .playerl(FacialExpression.FRIENDLY, "Great, thanks for your advice.") + .endWith { _, player -> + setAttribute(player, TheDigSite.attributeStudentPurpleExam1ObtainAnswer, true) + } + b.onPredicate { player -> getQuestStage(player, Quests.THE_DIG_SITE) == 3 && getAttribute(player, TheDigSite.attributeStudentPurpleExam1Talked, false)} + .branch { player -> + return@branch if (inInventory(player, Items.TEDDY_673)) { 1 } else { 0 } + }.let{ branch -> + branch.onValue(0) + .npcl(FacialExpression.FRIENDLY, "Very well thanks. Have you found my lucky mascot yet?") + .playerl(FacialExpression.FRIENDLY, "No sorry, not yet.") + .npcl(FacialExpression.FRIENDLY, "I'm sure it's just outside the site somewhere...") + .end() + branch.onValue(1) + .playerl(FacialExpression.FRIENDLY, "Hello there.") + .betweenStage { _, player, _, _ -> + if (inInventory(player, Items.TEDDY_673)){ + removeItem(player, Items.TEDDY_673) + } + } + .playerl(FacialExpression.FRIENDLY, "Guess what I found.") + .npcl(FacialExpression.FRIENDLY, "Hey! My lucky mascot! Thanks ever so much. Let me help you with those questions now.") + .npcl(FacialExpression.FRIENDLY, "The proper health and safety points are: Leather gloves and boots to be warn at all times; proper tools must be used.") + .playerl(FacialExpression.FRIENDLY, "Great, thanks for your advice.") + .endWith { _, player -> + setAttribute(player, TheDigSite.attributeStudentPurpleExam1ObtainAnswer, true) + } + return@let branch + } + b.onQuestStages(Quests.THE_DIG_SITE, 3) + .playerl(FacialExpression.FRIENDLY, "Hello there. Can you help me with the Earth Sciences exams at all?") + .npcl(FacialExpression.FRIENDLY, "I can if you help me...") + .playerl(FacialExpression.FRIENDLY, "How can I do that?") + .npcl(FacialExpression.FRIENDLY, "I have lost my teddy bear. He was my lucky mascot.") + .playerl(FacialExpression.FRIENDLY, "Do you know where you dropped him?") + .npcl(FacialExpression.FRIENDLY, "Well, I was doing a lot of walking that day... Oh yes, that's right - a few of us were studying that funny looking relic in the centre of the campus. Maybe I lost my lucky mascot around there, perhaps in a bush?") + .playerl(FacialExpression.FRIENDLY, "Leave it to me, I'll find it.") + .npcl(FacialExpression.FRIENDLY, "Oh, great! Thanks!") + .endWith { _, player -> + setAttribute(player, TheDigSite.attributeStudentPurpleExam1Talked, true) + } + b.onPredicate { _ -> true } + .playerl("Hello there.") + .npcl("Hi there. I'm studying for the Earth Sciences exam.") + .playerl("Interesting... This exam seems to be a popular one!") + } +} + + +@Initializable +class StudentBrownDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, StudentBrownDialogueFile(), npc) + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return StudentBrownDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.STUDENT_616) + } +} +class StudentBrownDialogueFile : DialogueBuilderFile() { + + override fun create(b: DialogueBuilder) { + + b.onQuestStages(Quests.THE_DIG_SITE, 5) + .playerl(FacialExpression.FRIENDLY, "Hello there.") + .npcl(FacialExpression.FRIENDLY, "How's it going?") + .playerl(FacialExpression.FRIENDLY, "There are more exam questions I'm stuck on.") + .npcl(FacialExpression.FRIENDLY, "Hey, I'll tell you what I've learned. That may help.") + .npcl(FacialExpression.FRIENDLY, "The proper technique for handling bones is: Handle bones carefully and keep them away from other samples.") + .playerl(FacialExpression.FRIENDLY, "Thanks for the information.") + .endWith { _, player -> + setAttribute(player, TheDigSite.attributeStudentBrownExam3ObtainAnswer, true) + } + + b.onQuestStages(Quests.THE_DIG_SITE, 4) + .playerl(FacialExpression.FRIENDLY, "Hello there.") + .npcl(FacialExpression.FRIENDLY, "How's it going?") + .playerl(FacialExpression.FRIENDLY, "There are more exam questions I'm stuck on.") + .npcl(FacialExpression.FRIENDLY, "Hey, I'll tell you what I've learned. That may help.") + .npcl(FacialExpression.FRIENDLY, "Correct sample transportation: Samples taken in rough form; kept only in sealed containers.") + .playerl(FacialExpression.FRIENDLY, "Thanks for the information.") + .endWith { _, player -> + setAttribute(player, TheDigSite.attributeStudentBrownExam2ObtainAnswer, true) + } + b.onPredicate { player -> getQuestStage(player, Quests.THE_DIG_SITE) == 3 && getAttribute(player, TheDigSite.attributeStudentBrownExam1ObtainAnswer, false)} + .playerl(FacialExpression.FRIENDLY, "Hello there.") + .npcl(FacialExpression.FRIENDLY, "How's it going?") + .playerl(FacialExpression.FRIENDLY, "There are more exam questions I'm stuck on.") + .npcl(FacialExpression.FRIENDLY, "Hey, I'll tell you what I've learned. That may help.") + .npcl(FacialExpression.FRIENDLY, "Correct sample transportation: Samples taken in rough form; kept only in sealed containers.") + .playerl(FacialExpression.FRIENDLY, "Thanks for the information.") + .endWith { _, player -> + setAttribute(player, TheDigSite.attributeStudentBrownExam1ObtainAnswer, true) + } + b.onPredicate { player -> getQuestStage(player, Quests.THE_DIG_SITE) == 3 && getAttribute(player, TheDigSite.attributeStudentBrownExam1Talked, false)} + .playerl(FacialExpression.FRIENDLY, "Hello there. How's the study going?") + .npcl(FacialExpression.FRIENDLY, "I'm getting there. Have you found my special cup yet?") + .branch { player -> + if (inInventory(player, Items.SPECIAL_CUP_672)){ + removeItem(player, Items.SPECIAL_CUP_672) + return@branch 1 + } else { + return@branch 0 + } + }.let{ branch -> + branch.onValue(0) + .playerl(FacialExpression.FRIENDLY, "No, sorry, not yet.") + .npcl(FacialExpression.FRIENDLY, "Oh dear, I hope it didn't fall into the river. I might never find it again.") + .end() + branch.onValue(1) + .npcl("Oh wow! You've found it! Thank you so much. I'll be glad to tell you what I know about the exam. The study of Earth Sciences is: The study of the earth, its contents and history.") + .endWith { _, player -> + setAttribute(player, TheDigSite.attributeStudentBrownExam1ObtainAnswer, true) + } + return@let branch + } + b.onQuestStages(Quests.THE_DIG_SITE, 3) + .playerl(FacialExpression.FRIENDLY, "Hello there. Can you help me with the Earth Sciences exams at all?") + .npcl(FacialExpression.FRIENDLY, "I can't do anything unless I find my special cup.") + .playerl(FacialExpression.FRIENDLY, "Your what?") + .npcl(FacialExpression.FRIENDLY, "My special cup. I won it for a particularly good find last month.") + .playerl(FacialExpression.FRIENDLY, "Oh, right. So if I find it, you'll help me?") + .npcl(FacialExpression.FRIENDLY, "I sure will!") + .playerl(FacialExpression.FRIENDLY, "Any ideas where it may be?") + .npcl(FacialExpression.FRIENDLY, "All I remember is that I was working near the panning area when I lost it.") + .playerl(FacialExpression.FRIENDLY, "Okay, I'll see what I can do.") + .npcl(FacialExpression.FRIENDLY, "Yeah, maybe the panning guide saw it? I hope I didn't lose it in the water!") + .endWith { _, player -> + setAttribute(player, TheDigSite.attributeStudentBrownExam1Talked, true) + } + b.onPredicate { _ -> true } + .playerl(FacialExpression.FRIENDLY, "Hello there.") + .npcl(FacialExpression.FRIENDLY, "Hello there. As you can see, I am a student.") + .playerl(FacialExpression.FRIENDLY, "What are you doing here?") + .npcl(FacialExpression.FRIENDLY, "I'm studying for the Earth Sciences exam.") + .playerl(FacialExpression.FRIENDLY, "Interesting... Perhaps I should study for it as well.") + } +} diff --git a/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/TheDigSite.kt b/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/TheDigSite.kt new file mode 100644 index 0000000..a32e9f6 --- /dev/null +++ b/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/TheDigSite.kt @@ -0,0 +1,390 @@ +package content.region.misthalin.digsite.quest.thedigsite + +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import org.rs09.consts.Items +import content.data.Quests + +/** + * The Dig Site Quest + * Funny enough, the crossed out quest log doesn't change into the past tense like other quests do. + * I guess this quest is so old, no one was bothered to change the tenses. + * This is working off the low quality quest log in 2008, which is very much different from the current quest log. + + * 1 - Speak to an examiner to start the quest + * 2 - Talked to the curator at Varrock + * 3 - Passed the signed letter back to the examiner + * 4 - Passed Level 1 Exam + * 5 - Passed Level 2 Exam + * 6 - Passed Level 3 Exam + * 7 - Found ANCIENT_TALISMAN_681 to impress expert + * 8 - Gave expert's recommendation letter to a workman + * 9 - Went down any of the digshafts + * 10 - Talked to Doug Deeping to get a key to open a chest + * 11 - Covered rocks with explosives + * 12 - Blew up the rocks (after this, climbing down a digshaft will end up in a different area) + * 100 - Talked to expert after showing him the STONE_TABLET_699 + */ +@Initializable +class TheDigSite : Quest(Quests.THE_DIG_SITE, 47, 46, 2, 131, 0, 1, 9) { + companion object { + const val attributeStudentGreenExam1Talked = "/save:quest:thedigsite-studentgreenexam1talked" + const val attributeStudentGreenExam1ObtainAnswer = "/save:quest:thedigsite-studentgreenexam1obtainanswer" + const val attributeStudentPurpleExam1Talked = "/save:quest:thedigsite-studentpurpleexam1talked" + const val attributeStudentPurpleExam1ObtainAnswer = "/save:quest:thedigsite-studentpurplexam1obtainanswer" + const val attributeStudentBrownExam1Talked = "/save:quest:thedigsite-studentbrownexam1talked" + const val attributeStudentBrownExam1ObtainAnswer = "/save:quest:thedigsite-studentbrownexam1obtainanswer" + const val attributePanningGuideTea = "/save:quest:thedigsite-panningguidetea" + const val attributeStudentGreenExam2ObtainAnswer = "/save:quest:thedigsite-studentgreenexam2obtainanswer" + const val attributeStudentPurpleExam2ObtainAnswer = "/save:quest:thedigsite-studentpurplexam2obtainanswer" + const val attributeStudentBrownExam2ObtainAnswer = "/save:quest:thedigsite-studentbrownexam2obtainanswer" + const val attributeStudentGreenExam3ObtainAnswer = "/save:quest:thedigsite-studentgreenexam3obtainanswer" + const val attributeStudentPurpleExam3ObtainAnswer = "/save:quest:thedigsite-studentpurplexam3obtainanswer" + const val attributeStudentPurpleExam3Talked = "/save:quest:thedigsite-studentpurpleexam3talked" + const val attributeStudentBrownExam3ObtainAnswer = "/save:quest:thedigsite-studentbrownexam3obtainanswer" + + const val attributeRopeNorthEastWinch = "/save:quest:thedigsite-ropenortheastwinch" + const val attributeRopeWestWinch = "/save:quest:thedigsite-ropewestwinch" + + const val attributeFirstQuestion = "quest:thedigsite-firstquestion" + const val attributeSecondQuestion = "quest:thedigsite-secondquestion" + const val attributeThirdQuestion = "quest:thedigsite-thirdquestion" + + const val barrelVarbit = 2547 + const val tabletVarbit = 2548 + } + + override fun reset(player: Player) { + removeAttribute(player, attributeStudentGreenExam1Talked) + removeAttribute(player, attributeStudentGreenExam1ObtainAnswer) + removeAttribute(player, attributeStudentPurpleExam1Talked) + removeAttribute(player, attributeStudentPurpleExam1ObtainAnswer) + removeAttribute(player, attributeStudentBrownExam1Talked) + removeAttribute(player, attributeStudentBrownExam1ObtainAnswer) + removeAttribute(player, attributePanningGuideTea) + removeAttribute(player, attributeStudentGreenExam2ObtainAnswer) + removeAttribute(player, attributeStudentPurpleExam2ObtainAnswer) + removeAttribute(player, attributeStudentBrownExam2ObtainAnswer) + removeAttribute(player, attributeStudentGreenExam3ObtainAnswer) + removeAttribute(player, attributeStudentPurpleExam3Talked) + removeAttribute(player, attributeStudentPurpleExam3ObtainAnswer) + removeAttribute(player, attributeStudentBrownExam3ObtainAnswer) + + removeAttribute(player, attributeRopeNorthEastWinch) + removeAttribute(player, attributeRopeWestWinch) + } + + override fun drawJournal(player: Player, stage: Int) { + super.drawJournal(player, stage) + var line = 11 + var stage = getStage(player) + + var started = getQuestStage(player, Quests.THE_DIG_SITE) > 0 + + if(!started){ + line++ + line(player, "I can start this quest by speaking to the !!Examiner?? at the", line++, false) + line(player, "!!Digsite Exam Centre.??", line++, false) + line(player, "I need the following skill levels:", line++, false) + line(player, "Level 10 Agility", line++, hasLevelStat(player, Skills.AGILITY, 10)) + line(player, "Level 10 Herblore", line++, hasLevelStat(player, Skills.HERBLORE, 10)) + line(player, "Level 25 Thieving", line++, hasLevelStat(player, Skills.THIEVING, 25)) + limitScrolling(player, line, true) + } else { + line(player, "I should speak to an examiner about taking Earth Science", line++, true) + line(player, "Exams.", line++, true) + + if (stage >= 2) { + line(player, "I should take the letter the Examiner has given me to the", line++, true) + line(player, "Curator of Varrock Museum, for his approval.", line++, true) + } else if (stage >= 1) { + line(player, "I should take the !!letter?? the !!Examiner?? has given me to the", line++) + line(player, "!!Curator?? of !!Varrock Museum??, for his approval.", line++) + } + + if (stage >= 3) { + line(player, "I need to return the letter of recommendation from the", line++, true) + line(player, "Curator of Varrock Museum to the Examiner at the Exam", line++, true) + line(player, "Centre for inspection.", line++, true) + } else if (stage >= 2) { + line(player, "I need to return the !!letter of recommendation?? from the", line++) + line(player, "!!Curator?? of !!Varrock Museum?? to the !!Examiner?? at the !!Exam??", line++) + line(player, "!!Centre?? for inspection.", line++) + } + if (stage >= 4) { + line(player, "I need to study for my first exam. Perhaps the students", line++, true) + line(player, "on the site can help?", line++, true) + } else if (stage >= 3) { + line(player, "I need to study for my first exam. Perhaps the students", line++) + line(player, "on the site can help?", line++) + } + if (stage >= 4 || getAttribute(player, attributeStudentGreenExam1Talked, false)) { + line(player, "I need to speak to the student in the green top about the", line++, true) + line(player, "exams.", line++, true) + } else if (stage >= 3) { + line(player, "I need to speak to the student in the green top about the", line++) + line(player, "exams.", line++) + } + if (stage >= 4 || getAttribute(player, attributeStudentPurpleExam1Talked, false)) { + line(player, "I need to speak to the student in the purple shirt about", line++, true) + line(player, "the exams.", line++, true) + } else if (stage >= 3) { + line(player, "I need to speak to the student in the purple shirt about", line++) + line(player, "the exams.", line++) + } + if (stage >= 4 || getAttribute(player, attributeStudentBrownExam1Talked, false)) { + line(player, "I need to speak to the student in the orange top about the", line++, true) + line(player, "exams.", line++, true) + } else if (stage >= 3) { + line(player, "I need to speak to the student in the orange top about the", line++) + line(player, "exams.", line++) + } + + if (stage >= 4 || getAttribute(player, attributeStudentGreenExam1ObtainAnswer, false)) { + line(player, "I have agreed to help the student in the green top.", line++, true) + line(player, "He has lost his Animal Skull and thinks he may have", line++, true) + line(player, "dropped it around the digsite. I need to find it and return it", line++, true) + line(player, "to him. Maybe one of the workmen has picked it up?", line++, true) + } else if (stage >= 3 && getAttribute(player, attributeStudentGreenExam1Talked, false)) { + line(player, "I have agreed to help the student in the green top.", line++) + line(player, "He has lost his !!Animal Skull?? and thinks he may have", line++) + line(player, "dropped it around the digsite. I need to find it and return it", line++) + line(player, "to him. Maybe one of the workmen has picked it up?", line++) + } + if (stage >= 4) { + line(player, "I should talk to him to see if he can help with my exams.", line++, true) + line(player, "He gave me an answer to one of the questions on the first", line++, true) + line(player, "exam.", line++, true) + } else if (stage >= 3 && getAttribute(player, attributeStudentGreenExam1ObtainAnswer, false)) { + line(player, "I should talk to him to see if he can help with my exams.", line++) + line(player, "He gave me an answer to one of the questions on the first", line++) + line(player, "exam.", line++) + } + + if (stage >= 4 || getAttribute(player, attributeStudentPurpleExam1ObtainAnswer, false)) { + line(player, "I have agreed to help the student in the purple skirt.", line++, true) + line(player, "She has lost her Lucky Mascot and thinks she may have", line++, true) + line(player, "dropped it around the large urns on the digsite. I need to", line++, true) + line(player, "find it and return it to her.", line++, true) + } else if (stage >= 3 && getAttribute(player, attributeStudentPurpleExam1Talked, false)) { + line(player, "I have agreed to help the student in the purple skirt.", line++) + line(player, "She has lost her !!Lucky Mascot?? and thinks she may have", line++) + line(player, "dropped it around the large urns on the digsite. I need to", line++) + line(player, "find it and return it to her.", line++) + } + if (stage >= 4) { + line(player, "I should talk to her to see if she can help with my exams.", line++, true) + line(player, "She gave me an answer to one of the questions on the", line++, true) + line(player, "first exam.", line++, true) + } else if (stage >= 3 && getAttribute(player, attributeStudentPurpleExam1ObtainAnswer, false)) { + line(player, "I should talk to her to see if she can help with my exams.", line++) + line(player, "She gave me an answer to one of the questions on the", line++) + line(player, "first exam.", line++) + } + + + if (stage >= 4 || getAttribute(player, attributeStudentBrownExam1ObtainAnswer, false)) { + line(player, "I have agreed to help the student in the orange top.", line++, true) + line(player, "He has lost his Special Cup and thinks he may have", line++, true) + line(player, "dropped it around the tents near the panning site. I need", line++, true) + line(player, "to find it and return it.", line++, true) + } else if (stage >= 3 && getAttribute(player, attributeStudentBrownExam1Talked, false)) { + line(player, "I have agreed to help the student in the orange top.", line++) + line(player, "He has lost his !!Special Cup?? and thinks he may have", line++) + line(player, "dropped it around the tents near the panning site. I need", line++) + line(player, "to find it and return it.", line++) + } + if (stage >= 4) { + line(player, "I should talk to him to see if he can help with my exams.", line++, true) + line(player, "He gave me an answer to one of the questions on the first", line++, true) + line(player, "exam.", line++, true) + } else if (stage >= 3 && getAttribute(player, attributeStudentBrownExam1ObtainAnswer, false)) { + line(player, "I should talk to him to see if he can help with my exams.", line++) + line(player, "He gave me an answer to one of the questions on the first", line++) + line(player, "exam.", line++) + } + + + if (stage >= 4) { + line(player, "I should talk to an examiner to take my first exam. If I", line++, true) + line(player, "have forgotten anything, I can always ask the students", line++, true) + line(player, "again.", line++, true) + line(player, "I have passed my first Earth Science exam.", line++, true) + } else if (stage >= 3 + && getAttribute(player, attributeStudentGreenExam1ObtainAnswer, false) + && getAttribute(player, attributeStudentPurpleExam1ObtainAnswer, false) + && getAttribute(player, attributeStudentBrownExam1ObtainAnswer, false) + ) { + line(player, "I should talk to an examiner to take my first exam. If I", line++) + line(player, "have forgotten anything, I can always ask the students", line++) + line(player, "again.", line++) + } + + if (stage >= 5) { + line(player, "I need to study for my second exam. Perhaps the three", line++, true) + line(player, "students on the digsite can help me again?", line++, true) + } else if (stage >= 4) { + line(player, "I need to study for my second exam. Perhaps the three", line++) + line(player, "students on the digsite can help me again?", line++) + } + if (stage >= 5 || getAttribute(player, attributeStudentGreenExam2ObtainAnswer, false)) { + line(player, "I need to speak to the student in the green top about the", line++, true) + line(player, "exams.", line++, true) + } else if (stage >= 4) { + line(player, "I need to speak to the student in the green top about the", line++) + line(player, "exams.", line++) + } + if (stage >= 5 || getAttribute(player, attributeStudentPurpleExam2ObtainAnswer, false)) { + line(player, "I need to speak to the student in the purple skirt about", line++, true) + line(player, "the exams.", line++, true) + } else if (stage >= 4) { + line(player, "I need to speak to the student in the purple skirt about", line++) + line(player, "the exams.", line++) + } + if (stage >= 5 || getAttribute(player, attributeStudentBrownExam2ObtainAnswer, false)) { + line(player, "I need to speak to the student in the orange top about the", line++, true) + line(player, "exams.", line++, true) + } else if (stage >= 4) { + line(player, "I need to speak to the student in the orange top about the", line++) + line(player, "exams.", line++) + } + if (stage >= 5) { + line(player, "I should talk to an examiner to take my second exam. If I", line++, true) + line(player, "have forgotten anything, I can always ask the students", line++, true) + line(player, "again.", line++, true) + line(player, "I have passed my second Earth Science exam.", line++, true) + } else if (stage >= 4 + && getAttribute(player, attributeStudentGreenExam2ObtainAnswer, false) + && getAttribute(player, attributeStudentPurpleExam2ObtainAnswer, false) + && getAttribute(player, attributeStudentBrownExam2ObtainAnswer, false) + ) { + line(player, "I should talk to an examiner to take my second exam. If I", line++) + line(player, "have forgotten anything, I can always ask the students", line++) + line(player, "again.", line++) + } + + if (stage >= 6) { + line(player, "I should research for my third exam. Perhaps the students", line++, true) + line(player, "can help me again?", line++, true) + } else if (stage >= 5) { + line(player, "I should research for my third exam. Perhaps the students", line++) + line(player, "can help me again?", line++) + } + if (stage >= 6 || getAttribute(player, attributeStudentGreenExam3ObtainAnswer, false)) { + line(player, "I need to speak to the student in the green top about the", line++, true) + line(player, "exams.", line++, true) + } else if (stage >= 5) { + line(player, "I need to speak to the student in the green top about the", line++) + line(player, "exams.", line++) + } + if (stage >= 6 || getAttribute(player, attributeStudentPurpleExam3Talked, false)) { + line(player, "I need to speak to the student in the purple skirt about", line++, true) + line(player, "the exams.", line++, true) + } else if (stage >= 5) { + line(player, "I need to speak to the student in the purple skirt about", line++) + line(player, "the exams.", line++) + } + if (stage >= 6 || getAttribute(player, attributeStudentPurpleExam3ObtainAnswer, false)) { + line(player, "I need to bring her an Opal.", line++, true) // What a cunt + } else if (stage >= 5 && getAttribute(player, attributeStudentPurpleExam3Talked, false)) { + line(player, "I need to bring her an Opal.", line++) + } + if (stage >= 6 || getAttribute(player, attributeStudentBrownExam3ObtainAnswer, false)) { + line(player, "I need to speak to the student in the orange top about the", line++, true) + line(player, "exams.", line++, true) + } else if (stage >= 5) { + line(player, "I need to speak to the student in the orange top about the", line++) + line(player, "exams.", line++) + } + if (stage >= 6) { + line(player, "I should talk to an examiner to take my third exam. If I", line++, true) + line(player, "have forgotten anything, I can always ask the students", line++, true) + line(player, "again.", line++, true) + line(player, "I have passed my third and final Earth Science exam.", line++, true) + } else if (stage >= 5 + && getAttribute(player, attributeStudentPurpleExam3ObtainAnswer, false) + && getAttribute(player, attributeStudentGreenExam3ObtainAnswer, false) + && getAttribute(player, attributeStudentBrownExam3ObtainAnswer, false) + ) { + line(player, "I should talk to an examiner to take my third exam. If I", line++) + line(player, "have forgotten anything, I can always ask the students", line++) + line(player, "again.", line++) + } + + if (stage >= 7) { + line(player, "I need a find from the digsite to impress the Expert.", line++, true) + } else if (stage >= 6) { + line(player, "I need a find from the digsite to impress the Expert.", line++) + } + if (stage >= 8) { + line(player, "I need to take the letter to a workman near a winch.", line++, true) + } else if (stage >= 7) { + line(player, "I need to take the letter to a workman near a winch.", line++) + } + if (stage >= 9) { + line(player, "I need to investigate the dig shafts.", line++, true) + line(player, "I found a secret passageway under the site.", line++, true) + } else if (stage >= 8) { + line(player, "I need to !!investigate the dig shafts??.", line++) + } + if (stage >= 10) { + line(player, "I need to find a way to move the rocks blocking the way in", line++, true) + line(player, "the shaft. Perhaps someone can help me.", line++, true) + line(player, "I covered the rocks in the cave with an explosive", line++, true) + line(player, "compound.", line++, true) + } else if (stage >= 9) { + line(player, "I need to find a way to move the rocks blocking the way in", line++) + line(player, "the shaft. Perhaps someone can help me.", line++) + } + if (stage >= 11) { + line(player, "I need to ignite the explosive compound and blow up the", line++, true) + line(player, "rocks blocking the way.", line++, true) + } else if (stage >= 10) { + line(player, "I need to ignite the explosive compound and blow up the", line++) + line(player, "rocks blocking the way.", line++) + } + if (stage >= 12) { + line(player, "I should look for something interesting in the secret room I", line++, true) + line(player, "found, and show it to the Expert at the Exam Centre.", line++, true) + line(player, "The expert was impressed with the Zarosian tablet that I", line++, true) + line(player, "found, and I also discovered an ancient altar!", line++, true) + line(player, "I was rewarded for my findings.", line++, true) + line(player, "My work here is done.", line++, true) + line(player, "I should also talk to the expert about any other finds.", line++, true) + } else if (stage >= 11) { + line(player, "I should look for something interesting in the secret room I", line++) + line(player, "found, and show it to the !!Expert?? at the Exam Centre.", line++) + } + if (stage >= 100) { + line++ + line(player,"QUEST COMPLETE!", line) + } + limitScrolling(player, line, false) + } + } + + override fun finish(player: Player) { + var ln = 10 + super.finish(player) + player.packetDispatch.sendString("You have completed Digsite Quest!", 277, 4) + // This image is special since it isn't an item, but a standalone model. + player.packetDispatch.sendModelOnInterface(17343, 277, 5, 0) + player.packetDispatch.sendAngleOnInterface(277, 5, 1020, 0, 0) + + drawReward(player, "2 Quest Points", ln++) + drawReward(player, "15,300 Mining XP", ln++) + drawReward(player, "2,000 Herblore XP", ln++) + drawReward(player, "2 Gold Bars", ln) + + rewardXP(player, Skills.MINING, 15300.0) + rewardXP(player, Skills.HERBLORE, 2000.0) + addItemOrDrop(player, Items.GOLD_BAR_2357, 2) + } + + override fun newInstance(`object`: Any?): Quest { + return this + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/TheDigSiteListeners.kt b/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/TheDigSiteListeners.kt new file mode 100644 index 0000000..4704518 --- /dev/null +++ b/Server/src/main/content/region/misthalin/digsite/quest/thedigsite/TheDigSiteListeners.kt @@ -0,0 +1,935 @@ +package content.region.misthalin.digsite.quest.thedigsite + +import content.data.Quests +import content.global.skill.thieving.ThievingListeners +import core.api.* +import core.api.utils.PlayerCamera +import core.api.utils.WeightBasedTable +import core.api.utils.WeightedItem +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength +import core.game.node.entity.Entity +import core.game.node.entity.combat.ImpactHandler +import core.game.node.entity.skill.Skills +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import core.game.world.update.flag.context.Animation +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +class TheDigSiteListeners : InteractionListener { + companion object { + val BENDING_DOWN_ANIMATION = Animation(827) + val TROWEL_ANIMATION = Animation(2272) + val PANNING_ANIMATION = Animation(4593) + + + val trainingDigTable = WeightBasedTable.create( + WeightedItem(0, 0, 0, 8.0, false), + WeightedItem(Items.COINS_995, 1, 1, 1.0, false), + WeightedItem(Items.CHARCOAL_973, 1, 1, 1.0, false), + WeightedItem(Items.BROKEN_ARROW_687, 1, 1, 1.0, false), + WeightedItem(Items.CRACKED_SAMPLE_674, 1, 1, 1.0, false), + WeightedItem(Items.VASE_710, 1, 1, 1.0, false), + ) + val level1DigTable = WeightBasedTable.create( + WeightedItem(0, 0, 0, 2.0, false), + WeightedItem(Items.BUTTONS_688, 1, 1, 1.0, false), + WeightedItem(Items.VASE_710, 1, 1, 1.0, false), + WeightedItem(Items.COPPER_ORE_436, 1, 1, 1.0, false), + WeightedItem(Items.LEATHER_BOOTS_1061, 1, 1, 1.0, false), + WeightedItem(Items.OPAL_1609, 1, 1, 1.0, false), + WeightedItem(Items.OLD_TOOTH_695, 1, 1, 1.0, false), + WeightedItem(Items.ROTTEN_APPLE_1984, 1, 1, 1.0, false), + WeightedItem(Items.BROKEN_GLASS_1469, 1, 1, 1.0, false), + WeightedItem(Items.RUSTY_SWORD_686, 1, 1, 1.0, false), + WeightedItem(Items.BONES_526, 1, 1, 1.0, false), + ) + val level2DigTable = WeightBasedTable.create( + WeightedItem(0, 0, 0, 3.0, false), + WeightedItem(Items.BONES_526, 1, 1, 2.0, false), + WeightedItem(Items.DAMAGED_ARMOUR_697, 1, 1, 1.0, false), + WeightedItem(Items.LEATHER_BOOTS_1061, 1, 1, 1.0, false), + WeightedItem(Items.BOWL_1923, 1, 1, 1.0, false), + WeightedItem(Items.BROKEN_STAFF_689, 1, 1, 1.0, false), + WeightedItem(Items.BROKEN_ARMOUR_698, 1, 1, 1.0, false), + WeightedItem(Items.UNCUT_JADE_1627, 1, 1, 1.0, false), + WeightedItem(Items.BROKEN_GLASS_1469, 1, 1, 1.0, false), + WeightedItem(Items.JUG_1935, 1, 1, 1.0, false), + WeightedItem(Items.EMPTY_POT_1931, 1, 1, 1.0, false), + WeightedItem(Items.CLAY_434, 1, 1, 1.0, false), + WeightedItem(Items.UNCUT_OPAL_1625, 1, 1, 1.0, false), + ) + val level3DigTable = WeightBasedTable.create( + WeightedItem(0, 0, 0, 1.0, false), + WeightedItem(Items.COINS_995, 10, 10, 2.0, false), + WeightedItem(Items.ANCIENT_TALISMAN_681, 1, 1, 1.0, false), // sendItemDialogue "You find a strange talisman." + WeightedItem(Items.BELT_BUCKLE_684, 1, 1, 2.0, false), + WeightedItem(Items.BLACK_MED_HELM_1151, 1, 1, 1.0, false), + WeightedItem(Items.BONES_526, 1, 1, 1.0, false), + WeightedItem(Items.BROKEN_ARMOUR_698, 1, 1, 1.0, false), + WeightedItem(Items.BROKEN_ARROW_687, 1, 1, 1.0, false), + WeightedItem(Items.BROKEN_STAFF_689, 1, 1, 1.0, false), + WeightedItem(Items.BRONZE_SPEAR_1237, 1, 1, 1.0, false), + WeightedItem(Items.BUTTONS_688, 1, 1, 1.0, false), + WeightedItem(Items.CERAMIC_REMAINS_694, 1, 1, 1.0, false), + WeightedItem(Items.CLAY_434, 1, 1, 1.0, false), + WeightedItem(Items.DAMAGED_ARMOUR_697, 1, 1, 1.0, false), + WeightedItem(Items.IRON_KNIFE_863, 1, 1, 1.0, false), + WeightedItem(Items.LEATHER_BOOTS_1061, 1, 1, 1.0, false), + WeightedItem(Items.NEEDLE_1733, 1, 1, 1.0, false), + WeightedItem(Items.OLD_TOOTH_695, 1, 1, 1.0, false), + WeightedItem(Items.PIE_DISH_2313, 1, 1, 1.0, false), + ) + val specimenTrayTable = WeightBasedTable.create( + WeightedItem(0, 0, 0, 2.0, false), + WeightedItem(Items.BONES_526, 1, 1, 2.0, false), + WeightedItem(Items.COINS_995, 1, 1, 1.0, false), + WeightedItem(Items.IRON_DAGGER_1203, 1, 1, 1.0, false), + WeightedItem(Items.CHARCOAL_973, 1, 1, 1.0, false), + WeightedItem(Items.BROKEN_ARROW_687, 1, 1, 1.0, false), + WeightedItem(Items.BROKEN_GLASS_1469, 1, 1, 1.0, false), + WeightedItem(Items.CERAMIC_REMAINS_694, 1, 1, 1.0, false), + WeightedItem(Items.CRACKED_SAMPLE_674, 1, 1, 1.0, false), + ) + + val workmanPickpocketingTable = WeightBasedTable.create( + WeightedItem(Items.SPECIMEN_BRUSH_670, 1, 1, 3.0, false), + WeightedItem(Items.ANIMAL_SKULL_671, 1, 1, 3.0, false), + WeightedItem(Items.COINS_995, 10, 10, 1.0, false), + WeightedItem(Items.ROPE_954, 1, 1, 1.0, false), + WeightedItem(Items.BUCKET_1925, 1, 1, 1.0, false), + WeightedItem(Items.LEATHER_GLOVES_1059, 1, 1, 1.0, false), + WeightedItem(Items.SPADE_952, 1, 1, 1.0, false), + ) + + val workmanPostQuestPickpocketingTable = WeightBasedTable.create( + WeightedItem(Items.SPECIMEN_BRUSH_670, 1, 1, 3.0, false), + WeightedItem(Items.COINS_995, 10, 10, 4.0, false), + WeightedItem(Items.ROPE_954, 1, 1, 1.0, false), + WeightedItem(Items.BUCKET_1925, 1, 1, 1.0, false), + WeightedItem(Items.LEATHER_GLOVES_1059, 1, 1, 1.0, false), + WeightedItem(Items.SPADE_952, 1, 1, 1.0, false), + ) + + val panningTable = WeightBasedTable.create( + WeightedItem(0, 0, 0, 20.0, false), + WeightedItem(Items.COINS_995, 1, 1, 4.0, false), + WeightedItem(Items.NUGGETS_680, 1, 1, 4.0, false), + WeightedItem(Items.OYSTER_407, 1, 1, 3.0, false), + WeightedItem(Items.UNCUT_OPAL_1625, 1, 1, 3.0, false), + WeightedItem(Items.UNCUT_JADE_1627, 1, 1, 3.0, false), + WeightedItem(Items.SPECIAL_CUP_672, 1, 1, 3.0, false), + ) + } + + override fun defineListeners() { + + // 3: Certificate Level 1 + on(Items.LEVEL_1_CERTIFICATE_691, ITEM, "look-at") { player, _ -> + openInterface(player, 440) + setInterfaceText(player, player.username, 440, 5) + return@on true + } + // 3: Certificate Level 2 + on(Items.LEVEL_2_CERTIFICATE_692, ITEM, "look-at") { player, _ -> + openInterface(player, 441) + setInterfaceText(player, player.username, 441, 5) + return@on true + } + // 3: Certificate Level 3 + on(Items.LEVEL_3_CERTIFICATE_693, ITEM, "look-at") { player, _ -> + openInterface(player, 444) + setInterfaceText(player, player.username, 444, 5) + return@on true + } + + // 3 Green: Pickpocket Animal Skull from Digsite Workman + on(intArrayOf(NPCs.DIGSITE_WORKMAN_613, NPCs.DIGSITE_WORKMAN_4564, NPCs.DIGSITE_WORKMAN_4565), NPC, "steal-from") { player, node -> + + if(getStatLevel(player, Skills.THIEVING) < 25){ + player.sendMessage("You need a Thieving level of 25 to do that.") + return@on true + } + if(!workmanPickpocketingTable.canRoll(player)){ + player.sendMessage("You don't have enough inventory space to do that.") + return@on true + } + sendMessage(player, "You attempt to pick the workman's pocket...") + if (getQuestStage(player, Quests.THE_DIG_SITE) == 3) { + player.animator.animate(ThievingListeners.PICKPOCKET_ANIM) + val rollOutcome = ThievingListeners.pickpocketRoll(player, 84.0, 240.0, workmanPickpocketingTable) + if (rollOutcome != null) { + queueScript(player, ThievingListeners.PICKPOCKET_ANIM.duration, QueueStrength.NORMAL) { stage: Int -> + when (stage) { + 0 -> { + if (rollOutcome.size > 0) { + addItemOrDrop(player, rollOutcome[0].id) + when (rollOutcome[0].id){ + Items.ANIMAL_SKULL_671 -> sendItemDialogue(player, Items.ANIMAL_SKULL_671, "You steal an animal skull.") + else -> sendMessage(player, "You steal something.") + } + } else { + sendMessage(player, "You couldn't steal anything.") + } + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + } else { + node.asNpc().face(player) + node.asNpc().animator.animate(ThievingListeners.NPC_ANIM) + sendMessage(player, "You fail to pick the workman's pocket.") + sendChat(node.asNpc(), "What do you think you're doing???") + sendMessage(player, "You have been stunned.") // -1 HP + playHurtAudio(player, 20) + stun(player, 3) + player.impactHandler.manualHit(node.asNpc(), 1, ImpactHandler.HitsplatType.NORMAL) + node.asNpc().face(null) + } + } else { + // When not during quest + player.animator.animate(ThievingListeners.PICKPOCKET_ANIM) + val rollOutcome = ThievingListeners.pickpocketRoll(player, 84.0, 240.0, workmanPostQuestPickpocketingTable) + if (rollOutcome != null) { + queueScript(player, ThievingListeners.PICKPOCKET_ANIM.duration, QueueStrength.NORMAL) { stage: Int -> + when (stage) { + 0 -> { + if (rollOutcome.size > 0) { + addItemOrDrop(player, rollOutcome[0].id) + when (rollOutcome[0].id){ + Items.ANIMAL_SKULL_671 -> sendItemDialogue(player, Items.ANIMAL_SKULL_671, "You steal an animal skull.") + else -> sendMessage(player, "You steal something.") + } + } else { + sendMessage(player, "You couldn't steal anything.") + } + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + } else { + node.asNpc().face(player) + node.asNpc().animator.animate(ThievingListeners.NPC_ANIM) + sendMessage(player, "You fail to pick the workman's pocket.") + sendChat(player, "What do you think you're doing???") + sendMessage(player, "You have been stunned.") // -1 HP + playHurtAudio(player, 20) + stun(player, 3) + player.impactHandler.manualHit(node.asNpc(), 1, ImpactHandler.HitsplatType.NORMAL) + node.asNpc().face(null) + } + } + return@on true + } + + // 3 Purple: Pickpocket student. + on(NPCs.STUDENT_617, NPC, "pickpocket") { player, _ -> + sendDialogue(player, "I don't think I should try to steal from this poor student.") + // Technically you can steal the teddy back from her. But why? + return@on true + } + + // 3 Purple: Search Bush for Teddy Bear (but wrong bushes) + on(Scenery.BUSH_2357, SCENERY, "search") { player, _ -> + sendMessage(player, "You search the bush... You find nothing of interest.") + return@on true + } + // 3 Purple: Search Bush for Teddy Bear (the correct bush) + on(Scenery.BUSH_2358, SCENERY, "search") { player, _ -> + openDialogue(player, object : DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + when(stage){ + 0 -> playerl("Hey, something has been dropped here...").also { + addItemOrDrop(player, Items.TEDDY_673) + stage++ + } + 1 -> sendItemDialogue(player, Items.TEDDY_673, "You find... something.").also { stage = END_DIALOGUE } + } + } + }) + return@on true + } + + + // 8/9: Pouring CHEMICAL_COMPOUND_707 on brick. Transitions to stage 11. + onUseWith(NPC, Items.CUP_OF_TEA_712, NPCs.PANNING_GUIDE_620) { player, used, with -> + if(removeItem(player, used)) { + sendNPCDialogue(player, with.id, "Ah! Lovely! You can't beat a good cuppa! You're free to pan all you want.") + setAttribute(player, TheDigSite.attributePanningGuideTea, true) + } + return@onUseWith true + } + + onUseWith(SCENERY, Items.PANNING_TRAY_677, Scenery.PANNING_POINT_2363) { player, used, with -> + if (getAttribute(player, TheDigSite.attributePanningGuideTea, false)) { + queueScript(player, 0, QueueStrength.NORMAL) { stage: Int -> + when (stage) { + 0 -> { + animate(player, PANNING_ANIMATION) + lock(player, PANNING_ANIMATION.duration) + return@queueScript delayScript(player, PANNING_ANIMATION.duration) + } + + 1 -> { + sendItemDialogue(player, Items.PANNING_TRAY_679, "You lift the full tray from the water") + if (removeItem(player, used)) { + addItemOrDrop(player, Items.PANNING_TRAY_679) + } + return@queueScript stopExecuting(player) + } + + else -> return@queueScript stopExecuting(player) + } + + } + } else { + openDialogue(player, PanningGuideCannotPanDialogueFile(), findNPC(NPCs.PANNING_GUIDE_620)!!) + } + return@onUseWith true + } + // 3 Brown: Search Panning Point for Special Cup + on(Scenery.PANNING_POINT_2363, SCENERY, "pan") { player, _ -> + // + if (getAttribute(player, TheDigSite.attributePanningGuideTea, false)) { + if (inInventory(player, Items.PANNING_TRAY_677)) { + queueScript(player, 0, QueueStrength.NORMAL) { stage: Int -> + when (stage) { + 0 -> { + animate(player, PANNING_ANIMATION) + return@queueScript delayScript(player, PANNING_ANIMATION.duration) + } + + 1 -> { + sendItemDialogue(player, Items.PANNING_TRAY_679, "You lift the full tray from the water.") + if (removeItem(player, Items.PANNING_TRAY_677)) { + addItemOrDrop(player, Items.PANNING_TRAY_679) + } + return@queueScript stopExecuting(player) + } + + else -> return@queueScript stopExecuting(player) + } + } + } else if (inInventory(player, Items.PANNING_TRAY_679)) { + sendPlayerDialogue(player, "I already have a full panning tray; perhaps I should search it first.") + } else { + sendMessage(player, "I need a panning tray to pan the panning point.") + } + } else { + openDialogue(player, PanningGuideCannotPanDialogueFile(), findNPC(NPCs.PANNING_GUIDE_620)!!) + } + return@on true + } + // 3 Brown: Empty tray + on(Items.PANNING_TRAY_677, ITEM, "search") { player, used -> + sendMessage(player, "The panning tray is empty.") + return@on true + } + // 3 Brown: Search Panning Point for Special Cup + on(Items.PANNING_TRAY_679, ITEM, "search") { player, used -> + sendMessage(player, "You search the contents of the tray.") + if(removeItem(player, used)) { + addItemOrDrop(player, Items.PANNING_TRAY_677) + val tableRoll = panningTable.roll() + if (tableRoll.size > 0) { + addItemOrDrop(player, tableRoll[0].id) + when (tableRoll[0].id){ + Items.COINS_995 -> sendItemDialogue(player, Items.COINS_995, "You find some coins within the mud.") + Items.NUGGETS_680 -> sendItemDialogue(player, Items.PANNING_TRAY_678, "You find some gold nuggets within the mud.") + Items.OYSTER_407 -> sendItemDialogue(player, Items.OYSTER_407, "You find an oyster within the mud.") + Items.UNCUT_OPAL_1625 -> sendItemDialogue(player, Items.UNCUT_OPAL_1625, "You find a gem within the mud!") + Items.UNCUT_JADE_1627 -> sendItemDialogue(player, Items.UNCUT_JADE_1627, "You find a gem within the mud!") + Items.SPECIAL_CUP_672 -> sendItemDialogue(player, Items.SPECIAL_CUP_672, "You find a shiny cup covered in mud.") + } + } else { + sendItemDialogue(player, Items.PANNING_TRAY_679, "The tray contains only plain mud.") + } + } + return@on true + } + + // 3-End: Soil trowel digging. Very complex. + onUseWith(SCENERY, Items.TROWEL_676, Scenery.SOIL_2376, Scenery.SOIL_2377, Scenery.SOIL_2378) { player, used, with -> + + val level3DigRight = ZoneBorders(3370, 3437, 3377, 3442) + val level3DigLeft = ZoneBorders(3350, 3404, 3357, 3412) + if (level3DigRight.insideBorder(player.location) || level3DigLeft.insideBorder(player.location)) { + if (getQuestStage(player, Quests.THE_DIG_SITE) >= 6) { + queueScript(player, 0, QueueStrength.NORMAL) { stage: Int -> + when (stage) { + 0 -> { + sendMessage(player, "You dig through the earth.") + animate(player, TROWEL_ANIMATION) + lock(player, TROWEL_ANIMATION.duration) + return@queueScript delayScript(player, TROWEL_ANIMATION.duration) + } + + 1 -> { + val tableRoll = level3DigTable.roll() + if (tableRoll.size > 0) { + addItemOrDrop(player, tableRoll[0].id) + } + sendMessage(player, "You carefully clean your find with the specimen brush.") + return@queueScript stopExecuting(player) + } + + else -> return@queueScript stopExecuting(player) + } + } + } else { + sendNPCDialogue(player, NPCs.DIGSITE_WORKMAN_613, "Oi! What do you think you're doing? There's fragile specimens around here!", FacialExpression.ANGRY) + } + } + + val level2Dig = ZoneBorders(3350, 3424, 3363, 3430) + if (level2Dig.insideBorder(player.location)) { + if (getQuestStage(player, Quests.THE_DIG_SITE) >= 5) { + queueScript(player, 0, QueueStrength.NORMAL) { stage: Int -> + when (stage) { + 0 -> { + sendMessage(player, "You dig through the earth.") + animate(player, TROWEL_ANIMATION) + lock(player, TROWEL_ANIMATION.duration) + return@queueScript delayScript(player, TROWEL_ANIMATION.duration) + } + + 1 -> { + val tableRoll = level2DigTable.roll() + if (tableRoll.size > 0) { + addItemOrDrop(player, tableRoll[0].id) + } + sendMessage(player, "You carefully clean your find with the specimen brush.") + return@queueScript stopExecuting(player) + } + + else -> return@queueScript stopExecuting(player) + } + } + } else { + sendNPCDialogue(player, NPCs.DIGSITE_WORKMAN_613, "Oi! What do you think you're doing? There's fragile specimens around here!", FacialExpression.ANGRY) + } + } + + val level1DigCentre = ZoneBorders(3360, 3402, 3363, 3414) + val level1DigRight = ZoneBorders(3367, 3403, 3372, 3414) + if (level1DigCentre.insideBorder(player.location) || level1DigRight.insideBorder(player.location)) { + if (getQuestStage(player, Quests.THE_DIG_SITE) >= 4) { + queueScript(player, 0, QueueStrength.NORMAL) { stage: Int -> + when (stage) { + 0 -> { + sendMessage(player, "You dig through the earth.") + animate(player, TROWEL_ANIMATION) + lock(player, TROWEL_ANIMATION.duration) + return@queueScript delayScript(player, TROWEL_ANIMATION.duration) + } + + 1 -> { + val tableRoll = level1DigTable.roll() + if (tableRoll.size > 0) { + addItemOrDrop(player, tableRoll[0].id) + } + sendMessage(player, "You carefully clean your find with the specimen brush.") + return@queueScript stopExecuting(player) + } + + else -> return@queueScript stopExecuting(player) + } + } + } else { + sendNPCDialogue(player, NPCs.DIGSITE_WORKMAN_613, "Oi! What do you think you're doing? There's fragile specimens around here!", FacialExpression.ANGRY) + } + } + + val trainingDigLeft = ZoneBorders(3352, 3396, 3357, 3400) + val trainingDigRight = ZoneBorders(3367, 3397, 3372, 3400) + if (trainingDigLeft.insideBorder(player.location) || trainingDigRight.insideBorder(player.location)) { + if (getQuestStage(player, Quests.THE_DIG_SITE) >= 3) { + queueScript(player, 0, QueueStrength.NORMAL) { stage: Int -> + when (stage) { + 0 -> { + sendMessage(player, "You dig through the earth.") + animate(player, TROWEL_ANIMATION) + lock(player, TROWEL_ANIMATION.duration) + return@queueScript delayScript(player, TROWEL_ANIMATION.duration) + } + + 1 -> { + val tableRoll = trainingDigTable.roll() + if (tableRoll.size > 0) { + addItemOrDrop(player, tableRoll[0].id) + // You find a/an ... + sendMessage(player, "You carefully clean your find with the specimen brush.") + } + return@queueScript stopExecuting(player) + } + + else -> return@queueScript stopExecuting(player) + } + } + } + } + + return@onUseWith true + } + + // 8: North East Winch goes to Doug Deeping + on(Scenery.WINCH_2350, SCENERY, "operate") { player, _ -> + if (getQuestStage(player, Quests.THE_DIG_SITE) >= 11) { + sendMessage(player, "You try to climb down the rope...") + sendMessage(player, "You lower yourself into the shaft...") + teleport(player, Location(3369, 9763)) + sendMessage(player, "You find yourself in a cavern...") + } else if (getQuestStage(player, Quests.THE_DIG_SITE) >= 8) { + if (getAttribute(player, TheDigSite.attributeRopeNorthEastWinch, false)) { + sendMessage(player, "You try to climb down the rope...") + sendMessage(player, "You lower yourself into the shaft...") + teleport(player, Location(3369, 9827)) + sendMessage(player, "You find yourself in a cavern...") + } else { + sendMessage(player, "You operate the winch...") + queueScript(player, 2, QueueStrength.NORMAL) { stage: Int -> + sendPlayerDialogue(player, "Hey, I think I could fit down here. I need something to help me get all the way down.") + sendMessage(player, "The bucket descends, but does not reach the bottom.") + return@queueScript stopExecuting(player) + } + } + } else { + openDialogue(player, object : DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + when(stage){ + 0 -> npc(NPCs.DIGSITE_WORKMAN_613, "Sorry; this area is private. The only way you'll get to", "use these is by impressing the archaeological expert up", "at the center.").also {stage++ } + 1 -> npc(NPCs.DIGSITE_WORKMAN_613,"Find something worthwhile and he might let you use the", "winches. Until then, get lost!").also { stage = END_DIALOGUE } + } + } + }) + } + // sendMessage(player, "There is a sign on the winch.") + // sendMessage(player, "Private area - invitation only.") + return@on true + } + + // 8: Tie rope to winch + onUseWith(IntType.SCENERY, Items.ROPE_954, Scenery.WINCH_2350) { player, used, with -> + if (removeItem(player, used)) { + if (getQuestStage(player, Quests.THE_DIG_SITE) >= 8) { + setAttribute(player, TheDigSite.attributeRopeNorthEastWinch, true) + sendMessage(player, "You tie the rope to the bucket.") + } else { + openDialogue(player, object : DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + when(stage){ + 0 -> npc(NPCs.DIGSITE_WORKMAN_613, "Sorry; this area is private. The only way you'll get to", "use these is by impressing the archaeological expert up", "at the center.").also {stage++ } + 1 -> npc(NPCs.DIGSITE_WORKMAN_613,"Find something worthwhile and he might let you use the", "winches. Until then, get lost!").also { stage = END_DIALOGUE } + } + } + }) + } + } + return@onUseWith true + } + + // 8: Climb back out + on(Scenery.ROPE_2352, SCENERY, "climb-up") { player, _ -> + teleport(player, Location(3370, 3427)) + return@on true + } + + // 8: West Winch goes to Skeletons, Explosion and Stone Tablet + on(Scenery.WINCH_2351, SCENERY, "operate") { player, _ -> + if (getQuestStage(player, Quests.THE_DIG_SITE) >= 11) { + sendMessage(player, "You try to climb down the rope...") + sendMessage(player, "You lower yourself into the shaft...") + teleport(player, Location(3352, 9753)) + sendMessage(player, "You find yourself in a cavern...") + } else if (getQuestStage(player, Quests.THE_DIG_SITE) >= 8) { + if (getAttribute(player, TheDigSite.attributeRopeWestWinch, false)) { + sendMessage(player, "You try to climb down the rope...") + sendMessage(player, "You lower yourself into the shaft...") + teleport(player, Location(3352, 9818)) + sendMessage(player, "You find yourself in a cavern...") + } else { + sendMessage(player, "You operate the winch...") + queueScript(player, 2, QueueStrength.NORMAL) { stage: Int -> + sendPlayerDialogue(player, "Hey, I think I could fit down here. I need something to help me get all the way down.") + sendMessage(player, "The bucket descends, but does not reach the bottom.") + return@queueScript stopExecuting(player) + } + } + } else { + openDialogue(player, object : DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + when(stage){ + 0 -> npc(NPCs.DIGSITE_WORKMAN_613, "Sorry; this area is private. The only way you'll get to", "use these is by impressing the archaeological expert up", "at the center.").also {stage++ } + 1 -> npc(NPCs.DIGSITE_WORKMAN_613,"Find something worthwhile and he might let you use the", "winches. Until then, get lost!").also { stage = END_DIALOGUE } + } + } + }) + } + return@on true + } + + + // 8: Tie rope to winch + onUseWith(IntType.SCENERY, Items.ROPE_954, Scenery.WINCH_2351) { player, used, with -> + if (removeItem(player, used)) { + if (getQuestStage(player, Quests.THE_DIG_SITE) >= 8) { + setAttribute(player, TheDigSite.attributeRopeWestWinch, true) + sendMessage(player, "You tie the rope to the bucket.") + } else { + openDialogue(player, object : DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + when(stage){ + 0 -> npc(NPCs.DIGSITE_WORKMAN_613, "Sorry; this area is private. The only way you'll get to", "use these is by impressing the archaeological expert up", "at the center.").also {stage++ } + 1 -> npc(NPCs.DIGSITE_WORKMAN_613,"Find something worthwhile and he might let you use the", "winches. Until then, get lost!").also { stage = END_DIALOGUE } + } + } + }) + } + } + return@onUseWith true + } + + // 8: Climb back out + on(Scenery.ROPE_2353, SCENERY, "climb-up") { player, _ -> + teleport(player, Location(3354, 3417)) + return@on true + } + + + on(Items.INVITATION_LETTER_696, ITEM, "read") { player, _ -> + sendPlayerDialogue(player, "It says, 'I give permission for the bearer... to use the mine shafts on site. - signed Terrance Balando, Archaeological Expert, City of Varrock.") + // LINE SEPARATED : ("It says, 'I give permission for the bearer... to use the", "mine shafts on site. - signed Terrance Balando,", "Archaeological Expert, City of Varrock.'") + return@on true + } + + + // 8: Investigating brick. Transitions to stage 9. + on(Scenery.BRICK_2362, SCENERY, "search") { player, _ -> + if(getQuestStage(player, Quests.THE_DIG_SITE) == 8) { + sendPlayerDialogue(player, "Hmmm, there's a room past these bricks. If I could move them out of the way then I could find out what's inside. Maybe there's someone around here who can help...", FacialExpression.THINKING) + setQuestStage(player, Quests.THE_DIG_SITE, 9) + } + if(getQuestStage(player, Quests.THE_DIG_SITE) == 9) { + sendPlayerDialogue(player, "Hmmm, there's a room past these bricks. If I could move them out of the way then I could find out what's inside. Maybe there's someone around here who can help...", FacialExpression.THINKING) + } + if(getQuestStage(player, Quests.THE_DIG_SITE) == 10) { + sendPlayerDialogue(player, "The brick is covered with the chemicals I made.", FacialExpression.THINKING) + } + return@on true + } + + + // 8/9: Chest open + on(Scenery.CHEST_2361, SCENERY, "search") { player, _ -> + sendMessage(player, "The chest is locked.") + return@on true + } + + // 8/9: Chest open with key + onUseWith(IntType.SCENERY, Items.CHEST_KEY_709, Scenery.CHEST_2361) { player, used, with -> + if (!removeItem(player, used)) { + return@onUseWith false + } + sendMessage(player, "You use the key in the chest.") + animate(player, 536) + replaceScenery(with as core.game.node.scenery.Scenery, Scenery.CHEST_2360, 100) + return@onUseWith true + } + + + // 8/9: Specimen tray mainly to find charcoal. No quest stage limit as long as you have a specimen jar. + on(Scenery.SPECIMEN_TRAY_2375, SCENERY, "search") { player, _ -> + if (inInventory(player, Items.SPECIMEN_JAR_669)) { + sendMessage(player, "You sift through the earth in the tray.") + animate(player, BENDING_DOWN_ANIMATION) + val tableRoll = specimenTrayTable.roll() + if (tableRoll.size > 0) { + addItemOrDrop(player, tableRoll[0].id) + } + } else { + sendMessage(player, "You need to have a specimen jar when you are searching the tray.") + // sendMessage(player, "There must be a workman present when you are searching the tray.") <- authentic, but what does this mean... + } + return@on true + } + + on(Scenery.CHEST_2360, SCENERY, "search") { player, _ -> + addItemOrDrop(player, Items.CHEMICAL_POWDER_700) + sendItemDialogue(player, Items.CHEMICAL_POWDER_700, "You find some unusual powder inside...") + return@on true + } + + // 8/9 Getting unidentified liquid (Do not shift this code down. This somehow gets overwritten.) + onUseWith(SCENERY, Items.VIAL_229, Scenery.BARREL_17297) { player, used, with -> + if(removeItem(player, used)) { + addItemOrDrop(player, Items.UNIDENTIFIED_LIQUID_702) + openDialogue(player, object : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onPredicate { _ -> true } + .item(Items.UNIDENTIFIED_LIQUID_702, "You fill the vial with the liquid.") + .player("I'm not sure what this stuff is. I had better be VERY", "careful with it; I had better not drop it either...") + } + }) + sendMessage(player, "You put the lid back on the barrel just in case it's dangerous.") + setVarbit(player, TheDigSite.barrelVarbit, 0) + } + return@onUseWith true + } + + // 8/9 Barrel open + on(Scenery.BARREL_17296, SCENERY, "search", "open") { player, _ -> + sendPlayerDialogue(player, "Mmmm... The lid is shut tight; I'll have to find something to lever it off.", FacialExpression.THINKING) + return@on true + } + + // 8/9 Barrel opened with trowel + onUseWith(SCENERY, Items.TROWEL_676, Scenery.BARREL_17296) { player, used, with -> + sendPlayerDialogue(player, "Great! It's opened it.") + setVarbit(player, TheDigSite.barrelVarbit, 1) + return@onUseWith true + } + + // 8/9 Open barrel search + on(Scenery.BARREL_17297, SCENERY, "search") { player, _ -> + sendPlayerDialogue(player, "I can't pick this up with my bare hands! I'll need something to put it in. It looks and smells rather dangerous though, so it'll need to be something small and capable of containing dangerous chemicals.", FacialExpression.THINKING) + return@on true + } + + // 8/9 Mixed chem 1 + onUseWith(ITEM, Items.AMMONIUM_NITRATE_701, Items.NITROGLYCERIN_703) { player, used, with -> + if (getStatLevel(player, Skills.HERBLORE) < 10) { + sendMessage(player, "You need level 10 Herblore to combine the chemicals.") + return@onUseWith true + } + sendMessage(player, "You mix the nitrate powder into the liquid.") + sendMessage(player, "It has produced a foul mixture.") + if(removeItem(player, used) && removeItem(player, with)) { + addItemOrDrop(player, Items.MIXED_CHEMICALS_705) + } + return@onUseWith true + } + + // 8/9 Mixed chem 2 + onUseWith(ITEM, Items.MIXED_CHEMICALS_705, Items.GROUND_CHARCOAL_704) { player, used, with -> + if (getStatLevel(player, Skills.HERBLORE) < 10) { + sendMessage(player, "You need level 10 Herblore to combine the chemicals.") + return@onUseWith true + } + sendMessage(player, "You mix the charcoal into the liquid.") + sendMessage(player, "It has produced an even fouler mixture.") + if(removeItem(player, used) && removeItem(player, with)) { + addItemOrDrop(player, Items.MIXED_CHEMICALS_706) + } + return@onUseWith true + } + + // 8/9 Mixed chem 3 + onUseWith(ITEM, Items.MIXED_CHEMICALS_706, Items.ARCENIA_ROOT_708) { player, used, with -> + if (getStatLevel(player, Skills.HERBLORE) < 10) { + sendMessage(player, "You need level 10 Herblore to combine the chemicals.") + return@onUseWith true + } + sendMessage(player, "You mix the root into the mixture.") + sendMessage(player, "You produce a potentially explosive compound.") + sendPlayerDialogue(player, "Excellent! This looks just right!", FacialExpression.HAPPY) + if(removeItem(player, used) && removeItem(player, with)) { + addItemOrDrop(player, Items.CHEMICAL_COMPOUND_707) + } + return@onUseWith true + } + + // 8/9: Pouring CHEMICAL_COMPOUND_707 on brick. Transitions to stage 10. + onUseWith(SCENERY, Items.CHEMICAL_COMPOUND_707, Scenery.BRICK_2362) { player, used, with -> + if (getQuestStage(player, Quests.THE_DIG_SITE) == 9) { + if(removeItem(player, used)) { + addItemOrDrop(player, Items.VIAL_229) + sendMessage(player, "You pour the compound over the bricks...") + sendPlayerDialogue(player, "Ok, the mixture is all over the bricks. I need some way to ignite this compound.", FacialExpression.THINKING) + setQuestStage(player, Quests.THE_DIG_SITE, 10) + } + } + return@onUseWith true + } + + // 10: Lighting brick. Transitions to stage 11. + onUseWith(SCENERY, Items.TINDERBOX_590, Scenery.BRICK_2362) { player, used, with -> + if(getQuestStage(player, Quests.THE_DIG_SITE) == 10) { + setQuestStage(player, Quests.THE_DIG_SITE, 11) + lock(player, 15) + queueScript(player, 0, QueueStrength.NORMAL) { stage: Int -> + when (stage) { + 0 -> { + animate(player, BENDING_DOWN_ANIMATION) + sendMessage(player, "You strike the tinderbox...") + return@queueScript delayScript(player, 2) + } + 1 -> { + sendMessage(player, "Fizz..") + sendPlayerDialogue(player, "Woah! This is going to blow! I'd better run!", FacialExpression.EXTREMELY_SHOCKED) + return@queueScript delayScript(player, BENDING_DOWN_ANIMATION.duration) + } + 2 -> { + // forceWalk(player, Location(3366, 9830, 0), "smart") doesn't work when player is locked. + player.walkingQueue.reset() + player.walkingQueue.addPath(3366, 9830) + + return@queueScript delayScript(player, 8) + } + 3 -> { + PlayerCamera(player).shake(0, 20, 8, 128, 40) + return@queueScript delayScript(player, 4) + } + 4 -> { + PlayerCamera(player).reset() + teleport(player, Location(3366, 9766)) + unlock(player) + sendPlayerDialogue(player, "Wow, that was a big explosion! What's that noise I can hear? Sounds like bones moving or something...", FacialExpression.EXTREMELY_SHOCKED) + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + } + return@onUseWith true + } + + // 12: Stone tablet get. + on(Scenery.STONE_TABLET_17367, SCENERY, "take") { player, _ -> + setVarbit(player, TheDigSite.tabletVarbit, 1) + addItemOrDrop(player,Items.STONE_TABLET_699) + sendMessage(player, "You pick the stone tablet up.") + return@on true + } + + on(Items.STONE_TABLET_699, ITEM, "read") { player, _ -> + sendPlayerDialogue(player, "It says: Tremble mortal, before the altar of our dread lord Zaros.") + return@on true + } + + // Dropping Liquids + on(Items.UNIDENTIFIED_LIQUID_702, ITEM, "empty") { player, node -> + if(removeItem(player, node)) { + addItemOrDrop(player, Items.VIAL_229) + } + sendChat(player, "You very carefully empty out the liquid.") + return@on true + } + + on(Items.UNIDENTIFIED_LIQUID_702, ITEM, "drop") { player, node -> + removeItem(player, node) + impact(player, 25) + sendChat(player, "Ow! The liquid exploded!") + sendMessage(player, "You were injured by the burning liquid.") + return@on true + } + + on(Items.NITROGLYCERIN_703, ITEM, "drop") { player, node -> + removeItem(player, node) + impact(player, 35) + sendChat(player, "Ow! The nitroglycerin exploded!") + sendMessage(player, "You were injured by the burning liquid.") + return@on true + } + + on(Items.MIXED_CHEMICALS_705, ITEM, "drop") { player, node -> + removeItem(player, node) + impact(player, 45) + sendChat(player, "Ow! The liquid exploded!") + sendMessage(player, "You were injured by the burning liquid.") + return@on true + } + + on(Items.MIXED_CHEMICALS_706, ITEM, "drop") { player, node -> + removeItem(player, node) + impact(player, 55) + sendChat(player, "Ow! The liquid exploded!") + sendMessage(player, "You were injured by the burning liquid.") + return@on true + } + + on(Items.CHEMICAL_COMPOUND_707, ITEM, "drop") { player, node -> + removeItem(player, node) + impact(player, 65) + sendChat(player, "Ow! The liquid exploded!") + sendMessage(player, "You were injured by the burning liquid.") + return@on true + } + + // Scenery not tied to quest + + on(intArrayOf(Scenery.GATE_24560, Scenery.GATE_24561), IntType.SCENERY, "open") { player, _ -> + // This gate is only openable when you have completed Digsite and have 153 kudos from the museum. + // We can assume, no one is going to reach that until the museum is fully fleshed out. + // So this gate will stay locked. + sendMessage(player, "You can't go through there, it's for Dig Site workmen only.") + sendChat(findNPC(NPCs.MUSEUM_GUARD_5942) as Entity, "Sorry - workman's gate only.") + return@on true + } + + on(Scenery.CUPBOARD_17303, SCENERY, "search") { player, _ -> + sendItemDialogue(player, Items.SPECIMEN_JAR_669, "You find a specimen jar.") + addItemOrDrop(player, Items.SPECIMEN_JAR_669) + return@on true + } + + on(Scenery.CUPBOARD_35223, SCENERY, "search") { player, _ -> + sendItemDialogue(player, Items.ROCK_PICK_675, "You find a rock pick.") + addItemOrDrop(player, Items.ROCK_PICK_675) + return@on true + } + + on(intArrayOf(Scenery.SACKS_2354, Scenery.SACKS_2355, Scenery.SACKS_2356), SCENERY, "search") { player, _ -> + sendItemDialogue(player, Items.SPECIMEN_JAR_669, "You find a specimen jar.") + addItemOrDrop(player, Items.SPECIMEN_JAR_669) + return@on true + } + + on(Scenery.BOOKCASE_35224, SCENERY, "search") { player, _ -> + sendMessage(player, "You search through the bookcase...") + sendItemDialogue(player, Items.BOOK_ON_CHEMICALS_711, "You find a book on chemicals.") + addItemOrDrop(player, Items.BOOK_ON_CHEMICALS_711) + return@on true + } + + on(Scenery.SIGNPOST_2366, SCENERY, "read") { player, _ -> + sendMessage(player, "This site is for training purposes only.") + return@on true + } + + on(Scenery.SIGNPOST_2367, SCENERY, "read") { player, _ -> + sendMessage(player, "Level 1 digs only.") + return@on true + } + + on(Scenery.SIGNPOST_2368, SCENERY, "read") { player, _ -> + sendMessage(player, "Level 2 digs only.") + return@on true + } + + on(Scenery.SIGNPOST_2369, SCENERY, "read") { player, _ -> + sendMessage(player, "Level 3 digs only.") + return@on true + } + + on(Scenery.SIGNPOST_2370, SCENERY, "read") { player, _ -> + sendMessage(player, "Private dig.") + return@on true + } + + on(Scenery.SIGNPOST_2371, SCENERY, "read") { player, _ -> + sendMessage(player, "Digsite educational centre.") + return@on true + } + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/dorgeshuun/dialogue/BarlakDialogue.kt b/Server/src/main/content/region/misthalin/dorgeshuun/dialogue/BarlakDialogue.kt new file mode 100644 index 0000000..9d37579 --- /dev/null +++ b/Server/src/main/content/region/misthalin/dorgeshuun/dialogue/BarlakDialogue.kt @@ -0,0 +1,247 @@ +package content.region.misthalin.dorgeshuun.dialogue +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class BarlakDialogue(player: Player? = null) : DialoguePlugin(player){ + private var pask = FacialExpression.ASKING + private var pfr = FacialExpression.FRIENDLY + private var pneu = FacialExpression.NEUTRAL + private var nhap = FacialExpression.OLD_HAPPY + private var ntalk1 = FacialExpression.OLD_CALM_TALK1 + private var ntalk2 = FacialExpression.OLD_CALM_TALK2 + + private var curItem = 0 + + val sets = arrayOf( + intArrayOf(Items.LONG_BONE_10976, 1000, 1500, Skills.CONSTRUCTION), + intArrayOf(Items.CURVED_BONE_10977, 2000, 2250, Skills.CONSTRUCTION), + intArrayOf(Items.SNAIL_SHELL_7800, 600, 0, Skills.CONSTRUCTION), + intArrayOf(Items.PERFECT_SNAIL_SHELL_10996, 600, 500, Skills.CRAFTING), + intArrayOf(Items.TORTOISE_SHELL_7939, 600, 0, Skills.CRAFTING), + intArrayOf(Items.PERFECT_SHELL_10995, 600, 500, Skills.CRAFTING), + ) + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + val playerMeetsBoneReqs = getDynLevel(player, Skills.CONSTRUCTION) >= 30 && hasHouse(player) + if (!playerMeetsBoneReqs) { + sendMessage(player, "You require at least level 30 construction and a house to speak to Barlak about bones.") + } + if (playerMeetsBoneReqs && inInventory(player, Items.LONG_BONE_10976, 1)) { + curItem = 0 + npcl(nhap, "Those bones! Those are exactly the sort of thing I need! Will you sell them?").also { stage = 0 } + } else if (playerMeetsBoneReqs && inInventory(player, Items.CURVED_BONE_10977, 1)) { + curItem = 1 + npcl(nhap, "Those bones! Those are exactly the sort of thing I need! Will you sell them?").also { stage = 0 } + } else if (inInventory(player, Items.PERFECT_SHELL_10995, 1)) { + curItem = 5 + npc(ntalk2, "That giant shell... what is it?").also { stage = 120 } + } else if (inInventory(player, Items.TORTOISE_SHELL_7939, 1)) { + curItem = 4 + npc(ntalk2, "That giant shell... what is it?").also { stage = 100 } + } else if (inInventory(player, Items.PERFECT_SNAIL_SHELL_10996, 1)) { + curItem = 3 + npc(ntalk1, "That giant shell... what is it?").also { stage = 60 } + } else if (inInventory(player, Items.SNAIL_SHELL_7800, 1)) { + curItem = 2 + npc(ntalk1, "That giant shell... what is it?").also { stage = 50 } + } else if (playerMeetsBoneReqs) { + npc(nhap, "Bones!").also { stage = 150 } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> npcl(ntalk1, "I'll give you ${getTotalCoinsForCurItem()} gp for the bones you're carrying and for any you have in your bank.").also { stage++ } + 1 -> npcl(ntalk2, "I'll try to teach you something about Construction as well, but it's highly technical so you won't understand if you don't already have level 30 Construction.").also { stage++ } + 2 -> options("Okay.", "No, I'll keep the bones.").also { stage++ } + 3 -> when (buttonId) { + 1 -> player(pfr, "Okay.").also { stage = 10 } + 2 -> player(pneu, "No thanks.").also { stage = 99 } + } + + 10 -> { + exchange() + npc(ntalk1, "Thanks! Now, let me explain...").also { stage = 999 } + } + + 50 -> player(pfr, "It's a giant snail shell!").also { stage++ } + 51 -> npcl(ntalk1, "Hmm... I think I might be able to make something out of them.").also { stage++ } + 52 -> npcl(ntalk2, "I'll give you ${getTotalCoinsForCurItem()} gp for the snail shells you're carrying.").also { stage++ } + 53 -> options("Okay.", "No. I'll keep the bones.").also { stage++ } + 54 -> when (buttonId) { + 1 -> player(pfr, "Okay.").also { stage = 55 } + 2 -> player(pneu, "No thanks.").also { stage = 99 } + } + 55 -> { + exchange() + npcl(ntalk1, "Thanks. If you find any more shells like these, please bring them to me!").also { stage = 99 } + } + 60 -> player(pfr, "It's a giant snail shell!").also { stage++ } + 61 -> { + when (amountInInventory(player, Items.PERFECT_SNAIL_SHELL_10996)) { + 1 -> npcl(ntalk2, "Hmm... I think I might be able to make something out of them, especially that perfect one.").also { stage++ } + else -> npcl(ntalk1, "Hmm... I think I might be able to make something out of them, especially those perfect ones.").also { stage = 70 } + } + } + + 62 -> npcl(ntalk2, "I'll give you ${getTotalCoinsForCurItem()} gp for the snail shell you're carrying, and I'll try to give you some advice on Crafting while I'm at it.").also { stage++ } + 63 -> options("Okay.", "No. I'll keep the bones.").also { stage++ } + 64 -> when (buttonId) { + 1 -> player(pfr, "Okay.").also { stage = 65 } + 2 -> player(pneu, "No thanks.").also { stage = 99 } + } + 65 -> { + npcl(ntalk2, "Thanks! Now, I don't think I could use that for Construction, but maybe I could make something...").also { stage = 1000 } + exchange() + } + + 70 -> npcl(ntalk2, "I'll give you ${getTotalCoinsForCurItem()} gp for the snail shells you're carrying, and I'll try to give you some advice on Crafting while I'm at it.").also { stage++ } + 71 -> options("Okay.", "No. I'll keep the bones.").also { stage++ } + 72 -> when (buttonId) { + 1 -> player(pfr, "Okay.").also { stage = 75 } + 2 -> player(pneu, "No thanks.").also { stage = 99 } + } + 75 -> { + npcl(ntalk2, "Thanks! Now, I don't think I could use that for Construction, but maybe I could make something...").also { stage = 1000 } + exchange() + } + + 100 -> player(pfr, "It's a giant battle tortoise shell!").also { stage++ } + 101 -> npcl(ntalk1, "Hmm... I think I might be able to make something out of them.").also { stage++ } + 102 -> npcl(ntalk2, "I'll give you ${getTotalCoinsForCurItem()} gp for the tortoise shells you're carrying.").also { stage++ } + 103 -> options("Okay.", "No. I'll keep the bones.").also { stage++ } + 104 -> when (buttonId) { + 1 -> player(pfr, "Okay.").also { stage = 105 } + 2 -> player(pneu, "No thanks.").also { stage = 99 } + } + 105 -> { + npcl(ntalk2, "Thanks. If you find any more shells like these, please bring them to me!").also { stage = 130 } + exchange() + } + + 120 -> player(pfr, "It's a perfect shell!").also { stage++ } + 121 -> { + when (amountInInventory(player, Items.PERFECT_SHELL_10995)) { + 1 -> npcl(ntalk2, "Hmm... I think I might be able to make something out of them, especially that perfect one.").also { stage++ } + else -> npcl(ntalk1, "Hmm... I think I might be able to make something out of them, especially those perfect ones.").also { stage++ } + } + } + 122 -> npcl(ntalk2, "I'll give you ${getTotalCoinsForCurItem()} gp for the perfect shell you're carrying, and I'll try to give you some advice on Crafting while I'm at it.").also { stage++ } + 123 -> options("Okay.", "No. I'll keep the bones.").also { stage++ } + 124 -> when (buttonId) { + 1 -> player(pfr, "Okay.").also { stage = 125 } + 2 -> player(pneu, "No thanks.").also { stage = 99 } + } + 125 -> { + npcl(ntalk2, "Thanks! Now, I don't think I could use that for Construction, but maybe I could make something...").also { stage = 1001 } + exchange() + } + + 130 -> { + if (inInventory(player, Items.SNAIL_SHELL_7800, 1)) { + curItem = 2 + npc(ntalk1, "That giant shell... what is it?").also { stage = 50 } + } else if (inInventory(player, Items.PERFECT_SNAIL_SHELL_10996, 1)) { + curItem = 3 + npc(ntalk1, "That giant shell... what is it?").also { stage = 60 } + } else { + end() + } + } + + 150 -> player(FacialExpression.THINKING, "What?").also { stage++ } + 151 -> npc(FacialExpression.OLD_DISTRESSED, "I don't have any bones!").also { stage++ } + 152 -> options("Then how do you stand up?", "What do you need bones for?", "Will you buy anything besides bones?", "What kind of bones do you need?", "Goodbye").also { stage++ } + 153 -> when (buttonId) { + 1 -> player(FacialExpression.THINKING, "Then how do you stand up?").also { stage = 200 } + 2 -> player(FacialExpression.THINKING, "What do you need bones for?").also { stage = 220 } + 3 -> player(FacialExpression.THINKING, "Will you buy anything besides bones?").also { stage = 240 } + 4 -> player(FacialExpression.THINKING, "What kind of bones do you need?").also { stage = 260 } + 5 -> player(pfr, "Goodbye.").also { stage = 280 } + } + + 200 -> npc(FacialExpression.OLD_CALM_TALK1, "What?").also { stage++ } + 201 -> playerl(FacialExpression.FRIENDLY, "How do you stand up if you have no bones? Shouldn't you collapse into a gelatinous blob?").also { stage++ } + 202 -> npc(FacialExpression.OLD_LAUGH1, "Ha, ha, ha, ha, ha!").also { stage = 152 } + + 220 -> npcl(FacialExpression.OLD_LAUGH1, "To stand up properly. Otherwise I'd collapse into a gelatinous blob! Ha, ha, ha, ha, ha! No, seriously, I need bones to use as a Construction material.").also { stage++ } + 221 -> npcl(ntalk1, "We always need big bones to prop up the mine shafts and to make other temporary structures.").also { stage = 152 } + 240 -> npcl(ntalk2, "Well, I've had a few people bring me some interesting giant shells. They say they came from giant snails and giant tortoises. Of course, like the bones, some shells are better than others.").also { stage++ } + 241 -> npcl(ntalk1, "I'll give you 250gp for ordinary shells, but what I really need are perfect shells.").also { stage++ } + 242 -> npcl(ntalk2, "I'll pay double for them and give you a few tips about Crafting too.").also { stage = 152 } + + 260 -> npcl(ntalk1, "Enormous bones, as big as you can get. Not just any big bones will do. Sometimes you might find a particularly long, straight bone. That's the kind of thing I need; I'll give you 1,000gp for one of them.").also { stage++ } + 261 -> npcl(ntalk2, "Occasionally, you might find a long curved bone - these are especially valuable - I'll give you 2,000gp for them. I'll also teach you a bit about how we use the bones in Construction, if you like.").also { stage = 152 } + + 280 -> npc(ntalk2, "Goodbye.").also { stage = 99 } + + 999 -> sendDialogue("Barlak gives you a short lecture and you learn more about Construction.").also { stage = 99 } + 1000 -> sendDialogue("Barlak gives you a short lecture and you learn more about Crafting.").also { stage = 99 } + 1001 -> sendDialogue("Barlak gives you a short lecture and you learn more about Crafting.").also { stage = 130 } + 99 -> end() + } + return true + } + + + private fun exchange() { + val item = getItemForCurItem() + val numToExchange = getNumToExchange() + removeAll(player, item, Container.INVENTORY) + removeAll(player, item, Container.BANK) + addItemOrDrop(player, Items.COINS_995, getCoinsForCurItem() * numToExchange) + rewardXP(player, getSkillForCurItem(), (getXpForCurItem() * numToExchange).toDouble()) + } + + private fun getNumToExchange(): Int { + val itemId = getItemIdForCurItem() + return amountInInventory(player, itemId) + amountInBank(player, itemId) + } + + private fun getTotalCoinsForCurItem(): Int { + return getCoinsForCurItem() * getNumToExchange() + } + + private fun getItemForCurItem(): Item { + return Item(getItemIdForCurItem()) + } + + private fun getItemIdForCurItem(): Int { + return sets[curItem][0] + } + + private fun getCoinsForCurItem(): Int { + return sets[curItem][1] + } + + private fun getXpForCurItem(): Int { + return sets[curItem][2] + } + + private fun getSkillForCurItem(): Int { + return sets[curItem][3] + } + + override fun newInstance(player: Player?): DialoguePlugin { + return BarlakDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.BARLAK_5828) + } +} diff --git a/Server/src/main/content/region/misthalin/dorgeshuun/dialogue/BartakDialogue.kt b/Server/src/main/content/region/misthalin/dorgeshuun/dialogue/BartakDialogue.kt new file mode 100644 index 0000000..3de1e2e --- /dev/null +++ b/Server/src/main/content/region/misthalin/dorgeshuun/dialogue/BartakDialogue.kt @@ -0,0 +1,44 @@ +package content.region.misthalin.dorgeshuun.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class BartakDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npc(FacialExpression.OLD_DISTRESSED,"Oh no! What's broken?").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> player(FacialExpression.ASKING, "What? Nothing's broken?").also { stage++ } + 1 -> npc(FacialExpression.OLD_DISTRESSED, "I'm sorry. I'm just a bit jumpy.").also { stage++ } + 2 -> npcl(FacialExpression.OLD_DISTRESSED, "I'm in charge of all the metalworking of Dorgesh-Kaan. It's a big responsibility!").also { stage++ } + 3 -> npcl(FacialExpression.OLD_DISTRESSED, "If something metal breaks I have to fix it. And lots of things are made of metal!").also { stage++ } + 4 -> player(FacialExpression.FRIENDLY, "Don't worry, I'm sure you're up to the task!").also { stage++ } + 5 -> npc(FacialExpression.OLD_DISTRESSED, "I hope you're right.").also { stage = 99 } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return BartakDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.BARTAK_5778) + } +} diff --git a/Server/src/main/content/region/misthalin/dorgeshuun/dialogue/CrateGoblinDialogue.kt b/Server/src/main/content/region/misthalin/dorgeshuun/dialogue/CrateGoblinDialogue.kt new file mode 100644 index 0000000..614c339 --- /dev/null +++ b/Server/src/main/content/region/misthalin/dorgeshuun/dialogue/CrateGoblinDialogue.kt @@ -0,0 +1,38 @@ +package content.region.misthalin.dorgeshuun.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class CrateGoblinDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npc(FacialExpression.OLD_NORMAL,"Excuse me, I need to deliver this.").also { stage = 99 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return CrateGoblinDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.CRATE_GOBLIN_5784) + } +} diff --git a/Server/src/main/content/region/misthalin/dorgeshuun/dialogue/DartogDialogue.kt b/Server/src/main/content/region/misthalin/dorgeshuun/dialogue/DartogDialogue.kt new file mode 100644 index 0000000..dbf286b --- /dev/null +++ b/Server/src/main/content/region/misthalin/dorgeshuun/dialogue/DartogDialogue.kt @@ -0,0 +1,72 @@ +package content.region.misthalin.dorgeshuun.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + * todo add teleporting when areas are complete + */ + +@Initializable +class DartogDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npc(FacialExpression.OLD_NORMAL,"Hello, surface-dweller.").also { stage = 0 } + return true + } + + private var fr = FacialExpression.FRIENDLY + private var ask = FacialExpression.ASKING + private var nor = FacialExpression.OLD_NORMAL + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage) { + 0 -> options("Who are you?", "Can you show me the way to the mine?", "Can you show me the way to Lumbridge Castle cellar?").also { stage++ } + 1 -> when (buttonId) { + 1 -> player(ask, "Who are you?").also { stage = 10} + 2 -> npcl(nor, "Of course! You're always welcome in our mines!").also { stage = 20 } + 3 -> player(ask, "Can you show me the way to Lumbridge Castle cellar?").also { stage = 50 } + } + + 10 -> npcl(nor, "The council posted me here to guard this new tunnel. I can also give you directions through the tunnels. A hero like you is always welcome in our mines!").also { stage++ } + 11 -> options("Can you show me the way to the mine?", "Can you show me the way to Lumbridge Castle cellar?", "Maybe some other time").also { stage++ } + 12 -> when (buttonId) { + 1 -> player(ask, "Can you show me the way to the mine?").also { stage = 40 } + 2 -> player(ask, "Can you show me the way to Lumbridge Castle cellar?").also { stage = 50 } + 3 -> player(fr, "Maybe some other time.").also { stage = 99 } + } + + 20 -> { + end() + //move player to mine + } + + 40 -> { + npcl(nor, "Of course! You're always welcome in our mines!").also { stage = 99 } + //move player to mine + } + + 50 -> { + npc(nor, "Of course!").also { stage = 99 } + //move to lumby castle celler + } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return DartogDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.DARTOG_4314) + } +} diff --git a/Server/src/main/content/region/misthalin/dorgeshuun/dialogue/DurgokDialogue.kt b/Server/src/main/content/region/misthalin/dorgeshuun/dialogue/DurgokDialogue.kt new file mode 100644 index 0000000..81d78ac --- /dev/null +++ b/Server/src/main/content/region/misthalin/dorgeshuun/dialogue/DurgokDialogue.kt @@ -0,0 +1,54 @@ +package content.region.misthalin.dorgeshuun.dialogue + +import core.api.addItemOrDrop +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class DurgokDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npcl(FacialExpression.OLD_NORMAL,"Frogburger! There's nothing like grilled frog in a bun. Do you want one? Only 10gp!").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> options("Yes, please.", "No, thanks.").also { stage++ } + 1 -> when(buttonId) { + 1 -> player(FacialExpression.FRIENDLY, "Yes please!").also { stage = 10 } + 2 -> player(FacialExpression.FRIENDLY, "No thanks.").also { stage = 99 } + } + + 10 -> if (player.inventory.contains(Items.COINS_995, 10)) { + player.inventory.remove(Item(Items.COINS_995, 10)) + addItemOrDrop(player, Items.FROGBURGER_10962, 1) + npc(FacialExpression.OLD_NORMAL, "There you go.").also { stage = 99 } + } else { + npc(FacialExpression.OLD_NORMAL, "I'm sorry, but you need 10gp for that.").also { stage = 99 } + } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return DurgokDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.DURGOK_5794) + } +} diff --git a/Server/src/main/content/region/misthalin/dorgeshuun/dialogue/MistagDialogue.kt b/Server/src/main/content/region/misthalin/dorgeshuun/dialogue/MistagDialogue.kt new file mode 100644 index 0000000..a05bfeb --- /dev/null +++ b/Server/src/main/content/region/misthalin/dorgeshuun/dialogue/MistagDialogue.kt @@ -0,0 +1,76 @@ +package content.region.misthalin.dorgeshuun.dialogue + +import content.data.Quests +import core.game.component.Component +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import content.region.misthalin.dorgeshuun.quest.thelosttribe.GoblinFollower +import content.region.misthalin.dorgeshuun.quest.thelosttribe.MistagLTDialogue +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE + +@Initializable +class MistagDialogue (player: Player? = null) : DialoguePlugin(player){ + override fun newInstance(player: Player?): DialoguePlugin { + return MistagDialogue(player) + } + + override fun npc(vararg messages: String?): Component { + return npc(FacialExpression.OLD_NORMAL,*messages) + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + val ltStage = player.questRepository.getStage(Quests.THE_LOST_TRIBE) + + if(args.size > 1 && args[1] == "greeting"){ + npc("A human knows ancient greeting?") + loadFile(MistagLTDialogue(true,ltStage)) + return true + } + if(!player.getAttribute("mistag-greeted",false)){ + npc("Who...who are you? How did you get in here?") + stage = -100 + return true + } + + if(ltStage == 45){ + npc("Greetings, friend. I am sorry I panicked when I saw you.") + loadFile(MistagLTDialogue(false,ltStage)) + return true + } else if(ltStage == 50){ + npc("Hello, friend?") + loadFile(MistagLTDialogue(false,ltStage)) + return true + } + + npc("Hello friend!").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + //Pre-greeting + -100 -> npc("Help! A surface dweller this deep in our mines? We will","all be destroyed!").also { stage++ } + -99 -> end() + + //Normal Dialogue + START_DIALOGUE -> options("May I mine the rocks here?","Can you show me the way out?").also { stage++ } + 1 -> when(buttonId){ + 1 -> player("May I mine the rocks here?").also { stage = 10 } + 2 -> player("Can you show me the way out of the mine?").also { stage = 20 } + } + 10 -> npc("Certainly, friend!").also { stage = END_DIALOGUE } + 20 -> npc("Certainly!").also { GoblinFollower.sendToLumbridge(player); stage = END_DIALOGUE } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(2084) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/dorgeshuun/dialogue/randomChildrenDialogue.kt b/Server/src/main/content/region/misthalin/dorgeshuun/dialogue/randomChildrenDialogue.kt new file mode 100644 index 0000000..9063efe --- /dev/null +++ b/Server/src/main/content/region/misthalin/dorgeshuun/dialogue/randomChildrenDialogue.kt @@ -0,0 +1,59 @@ +package content.region.misthalin.dorgeshuun.dialogue + +import core.api.toIntArray +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable + +/** + * @author qmqz + */ + +@Initializable +class randomChildrenDialogue(player: Player? = null) : DialoguePlugin(player){ + var a = FacialExpression.OLD_NORMAL + var b = FacialExpression.FRIENDLY + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + when ((1..5).random()) { + 1 -> npc(FacialExpression.OLD_NORMAL, "Are you a surface-dweller?").also { stage = 0 } + 2 -> npcl(a, "Are you " + player.username + "? Did you help Zanik save the city?").also { stage = 10 } + 3 -> npc(a, "Sorry, I'm not meant to talk to strangers.").also { stage = 99 } + 4 -> npc(a, "Shh! Don't tell anyone!").also { stage = 20 } + 5 -> npc(a, "Help! Help! The surface people are attacking!").also { stage = 30 } + } + + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> player(b, "Yes...").also { stage++ } + 1 -> npcl(a, "Haha! You look funny! All tall and skinny with tiny eyes!").also { stage = 99 } + + 10 -> player(b, "Yes, that was me!").also { stage++ } + 11 -> npcl(a, "When I'm older I'm going to be an adventurer, just like Zanik!").also { stage = 99 } + + 20 -> player(b, "Don't tell anyone what?").also { stage++ } + 21 -> npc(a, "SHHH!").also { stage = 99 } + + 30 -> player(b, "It's alright, I'm friendly!").also { stage = 99 } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return randomChildrenDialogue(player) + } + + val ids = 5807..5822 + + override fun getIds(): IntArray { + return ids.toIntArray() + } +} diff --git a/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/CaveGoblinMinerNPC.kt b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/CaveGoblinMinerNPC.kt new file mode 100644 index 0000000..6813ad0 --- /dev/null +++ b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/CaveGoblinMinerNPC.kt @@ -0,0 +1,50 @@ +package content.region.misthalin.dorgeshuun.quest.thelosttribe + +import core.game.node.entity.Entity +import core.game.node.entity.npc.AbstractNPC +import core.game.world.map.Location +import core.plugin.Initializable + +@Initializable +/** + * Handles the cave goblin miner npc + * @author Ceikry + */ +class CaveGoblinMinerNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id,location) { + var mining = false + var originallyMiner = false + init { + originallyMiner = id > 2073 + } + + override fun construct(id: Int, location: Location?, vararg objects: Any?): AbstractNPC { + return CaveGoblinMinerNPC(id,location) + } + + override fun getIds(): IntArray { + return intArrayOf(2078,2077,2076,2075,2072,2071,2070,2069) + } + + override fun tick() { + mining = (id > 2074) + + if(properties.combatPulse.isAttacking && mining){ + transform(id - 6) + this.isWalks = true + this.walkRadius = 4 + this.isNeverWalks = false + } + super.tick() + } + + override fun finalizeDeath(killer: Entity?) { + if(!mining && originallyMiner){ + transform(id + 6) + this.isWalks = false + this.walkRadius = 0 + this.isNeverWalks = true + } + super.finalizeDeath(killer) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/CaveRockHandler.kt b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/CaveRockHandler.kt new file mode 100644 index 0000000..bad59c4 --- /dev/null +++ b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/CaveRockHandler.kt @@ -0,0 +1,62 @@ +package content.region.misthalin.dorgeshuun.quest.thelosttribe + +import core.cache.def.impl.SceneryDefinition +import core.game.component.Component +import core.game.interaction.OptionHandler +import core.game.node.Node +import core.game.node.entity.player.Player +import core.game.world.map.Direction +import core.game.world.map.Location +import core.plugin.Initializable +import core.plugin.Plugin +import org.rs09.consts.Components + +@Initializable +/** + * Handles looking at the rocks in the tunnels leading up to the dorg mines + * @author Ceikry + */ +class CaveRockHandler : OptionHandler() { + override fun newInstance(arg: Any?): Plugin { + for(i in 6921..6924){ + SceneryDefinition.forId(i).handlers["option:look-at"] = this + } + return this + } + + override fun handle(player: Player?, node: Node?, option: String?): Boolean { + player ?: return false + when(node?.id){ + 6921 -> showRock(player,6923) + 6922 -> showRock(player,6924) + 6923 -> showRock(player,6922) + 6924 -> showRock(player,6927) + } + return true + } + + + fun showRock(player: Player, model: Int){ + player.interfaceManager.open(Component(Components.CAVE_GOBLIN_MARKERS_62)) + player.packetDispatch.sendModelOnInterface(model,62,1,1) + } + + override fun getDestination(n: Node?, node: Node?): Location { + n ?: return super.getDestination(n, node) + node ?: return super.getDestination(n, node) + + var diffX = 0 + var diffY = 0 + + if(node.direction == Direction.SOUTH) + diffX = -1 + if(node.direction == Direction.NORTH) + diffX = 1 + if(node.direction == Direction.WEST) + diffY = 1 + if(node.direction == Direction.EAST) + diffY = -1 + + return node.location.transform(diffX,diffY,0) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/CaveZone.kt b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/CaveZone.kt new file mode 100644 index 0000000..68744f6 --- /dev/null +++ b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/CaveZone.kt @@ -0,0 +1,76 @@ +package content.region.misthalin.dorgeshuun.quest.thelosttribe + +import core.game.node.entity.Entity +import core.game.node.entity.combat.ImpactHandler +import core.game.node.entity.player.Player +import core.game.system.task.Pulse +import core.game.world.GameWorld +import core.game.world.map.Location +import core.game.world.map.zone.MapZone +import core.game.world.map.zone.ZoneBorders +import core.game.world.map.zone.ZoneBuilder +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import core.plugin.Initializable +import core.plugin.Plugin +import core.tools.RandomFunction + +@Initializable +/** + * Handles the movement traps and such for the caves in front of the dorg mines + * @author Ceikry + */ +class CaveZone : MapZone("TLT Cave Zone", true), Plugin { + val triggers = ArrayList() + + override fun configure() { + register(ZoneBorders(3306, 9661, 3222, 9600)) + triggers.add(Location.create(3241, 9614, 0)) + triggers.add(Location.create(3257, 9616, 0)) + triggers.add(Location.create(3258, 9633, 0)) + triggers.add(Location.create(3244, 9635, 0)) + triggers.add(Location.create(3233, 9626, 0)) + triggers.add(Location.create(3249, 9646, 0)) + triggers.add(Location.create(3260, 9638, 0)) + triggers.add(Location.create(3273, 9641, 0)) + triggers.add(Location.create(3275, 9631, 0)) + triggers.add(Location.create(3287, 9631, 0)) + triggers.add(Location.create(3302, 9618, 0)) + } + + override fun move(e: Entity?, from: Location?, to: Location?): Boolean { + if(triggers.contains(from) && e is Player){ + e.asPlayer().walkingQueue.reset() + e.asPlayer().lock() + trigger(e.asPlayer()) + } + return super.move(e, from, to) + } + + fun trigger(player: Player){ + if(RandomFunction.random(1,6) <= 2) { + player.animator.animate(Animation(1950), Graphics(572,1,3)) + GameWorld.Pulser.submit(object : Pulse(5) { + override fun pulse(): Boolean { + player.unlock() + player.properties.teleportLocation = Location.create(3159, 9546, 0) + player.animator.reset() + return true + } + }) + } else { + player.unlock() + player.animator.animate(Animation.RESET,Graphics(302)) + player.impactHandler.manualHit(player,RandomFunction.random(1,7),ImpactHandler.HitsplatType.NORMAL) + } + } + + override fun newInstance(arg: Unit?): Plugin { + ZoneBuilder.configure(this) + return this + } + + override fun fireEvent(identifier: String?, vararg args: Any?): Any { + return Unit + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/DukeHoracioTLTDialogue.kt b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/DukeHoracioTLTDialogue.kt new file mode 100644 index 0000000..c71192c --- /dev/null +++ b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/DukeHoracioTLTDialogue.kt @@ -0,0 +1,231 @@ +package content.region.misthalin.dorgeshuun.quest.thelosttribe + +import content.data.Quests +import core.api.* +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.item.Item +import org.rs09.consts.Items +import core.game.dialogue.DialogueFile +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE + +class DukeHoracioTLTDialogue(val questStage: Int) : DialogueFile() { + private val Sigmund = NPC(2082) + + + override fun handle(componentID: Int, buttonID: Int) { + + if(questStage == 20){ + when(stage){ + START_DIALOGUE -> player("I know what happened in the cellar.").also { stage++ } + 1 -> npc("Oh?").also { stage++ } + 2 -> player("The cook says he saw something in the cellar.","Like a goblin with big eyes.").also { stage++ } + 3 -> npc( + "Yes, he mentioned that to me. But I think he was", + "imagining things. Goblins live in natural caves but", + "everyone knows they don't have the wit to make their", + "own tunnels." + ).also { stage++ } + + 4 -> sendNormalDialogue( + Sigmund, + FacialExpression.ANGRY, + "Yes your grace, but if there is any possibility that this", + "is a goblin incursion then we should take that possibility", + "very seriously!" + ).also { stage++ } + + 5 -> player("I think we should at least investigate.").also { stage++ } + 6 -> sendNormalDialogue( + Sigmund, + FacialExpression.WORRIED, + "Your grace, I think you should listen to " + (if (player!!.isMale) "him" else "her") + "." + ).also { stage++ } + + 7 -> { + npc( + "Hmm, very well. I give you permission to investigate", + "this mystery. If there is a blocked tunnel then perhaps", + "you should try to un-block it." + ) + player!!.questRepository.getQuest(Quests.THE_LOST_TRIBE).setStage(player, 30) + stage = END_DIALOGUE + } + } + } + + else if(questStage == 30 && player!!.inventory.containsItem(Item(Items.BROOCH_5008))){ + when(stage){ + START_DIALOGUE -> player("On the ground I found this brooch.").also { stage++ } + 1 -> npc( + "I've never seen anything like that before. It doesn't", + "come from Lumbridge. What do you think, Sigmund?" + ).also { stage++ } + + 2 -> sendNormalDialogue( + Sigmund, + FacialExpression.WORRIED, + "It is unknown to me, your grace. But the fact it is", + "there is enough to prove the Cook's story. It must have", + "been dropped by a goblin as it fled." + ).also { stage++ } + + 3 -> npc("I've never heard of a goblin wearing something so well-", "crafted.").also { stage++ } + 4 -> sendNormalDialogue( + Sigmund, + FacialExpression.ANGRY, + "Then it must have been stolen!" + ).also { stage++ } + + 5 -> npc("But it wasn't stolen from us. Where could it be from?").also { stage++ } + 6 -> sendNormalDialogue( + Sigmund, + FacialExpression.ANGRY, + "That doesn't matter! You said yourself that goblins", + "couldn't have made that, so they must have stolen it", + "from somewhere." + ).also { stage++ } + + 7 -> sendNormalDialogue( + Sigmund, + FacialExpression.ANGRY, + "Horrible, thieving goblins have broken into our cellar!", + "We must retaliate immediately!" + ).also { stage++ } + + 8 -> sendNormalDialogue( + Sigmund, + FacialExpression.ANGRY, + "First we should wipe out the goblins east of the river,", + "then we can march on the goblin village to the north-", + "west..." + ).also { stage++ } + + 9 -> npc("I will not commit troops until I have proof that goblins", "are behind this.").also { stage++ } + 10 -> { + npc( + player!!.name + ", please find out what you can about this", + "brooch. The librarian in Varrock might be able to help", + "identify the symbol." + ) + player!!.questRepository.getQuest(Quests.THE_LOST_TRIBE).setStage(player, 40) + stage = END_DIALOGUE + } + } + } + + else if(questStage == 44){ + when(stage){ + START_DIALOGUE -> player( + "I spoke to the goblin generals in the goblin village. They", + "told me about an ancient goblin tribe that went to live", + "underground." + ).also { stage++ } + + 1 -> sendNormalDialogue( + Sigmund, + FacialExpression.ANGRY, + "What more proof do we need? Nasty, smelly goblins", + "have been living under our feet all this time! We must", + "crush them at once!" + ).also { stage++ } + + 2 -> npc( + "Hmm, perhaps you are right. I will send word to the", + "army to prepare for an underground assault." + ).also { stage++ } + + 3 -> { + npc( + player!!.name.capitalize() + ", I would still like you to find out more", + "about this tribe. It cannot hurt to know one's enemy." + ) + player!!.questRepository.getQuest(Quests.THE_LOST_TRIBE).setStage(player, 45) + stage = END_DIALOGUE + } + } + } + + else if(questStage == 46){ + when(stage){ + START_DIALOGUE -> player( + "I've made contact with the cave goblins. They say they", + "were following a seam and broke into the cellar by", + "mistake." + ).also { stage++ } + + 1 -> sendNormalDialogue( + Sigmund, + FacialExpression.ANGRY, + "And I suppose you believe them, goblin lover?" + ).also { stage++ } + + 2 -> player("Well, they seemed friendlier than most goblins, and", "nothing was taken from the cellar.").also { stage++ } + 3 -> npc( + "Actually, something was taken. Sigmund has informed", + "me that some of the castle silverware is missing from", + "the cellar." + ).also { stage++ } + + 4 -> { + npc("Unless it is returned, I am afraid I will have no option", "but war.") + player!!.questRepository.getQuest(Quests.THE_LOST_TRIBE).setStage(player, 47) + stage = END_DIALOGUE + } + } + } + + else if(questStage == 49 && player!!.inventory.contains(Items.SILVERWARE_5011,1)){ + when(stage){ + START_DIALOGUE -> player("I found the missing silverware in the HAM cave!").also { stage++ } + 1 -> npc("Sigmund! Is this your doing?").also { stage++ } + 2 -> sendNormalDialogue( + Sigmund, + FacialExpression.WORRIED, + "Of...of course not! The goblins must have, um, dropped", + "the silverware as they ran away." + ).also { stage++ } + + 3 -> npc( + "Don't lie to me! I knew you were a HAM member but", + "I didn't think you would stoop to this. You are", + "dismissed from my service." + ).also { stage++ } + + 4 -> sendNormalDialogue( + Sigmund, + FacialExpression.THINKING, + "But don't you see it was for the best? For goblins to be", + "living under our feet like this... ugh. It doesn't matter", + "how civilised they are: all sub-human species must be", + "wiped out!" + ).also { stage++ } + + 5 -> npc("That's enough! Get out of my castle now!").also { stage++ } + 6 -> npc( + "I see I was ill-advised. Unless there is an act of", + "aggression by the cave goblins there is no need for war." + ).also { stage++ } + + 7 -> interpreter!!.sendItemMessage(Items.PEACE_TREATY_5012, "The Duke writes a document and signs it.").also { stage++ } + 8 -> { + npc( + "This peace treaty specifies the border between", + "Lumbridge and the Cave Goblin realm. Please take it to", + "the cave goblins and tell them I would like to meet with", + "their leader to sign it." + ) + addItemOrDrop(player!!, Items.PEACE_TREATY_5012) + player!!.questRepository.getQuest(Quests.THE_LOST_TRIBE).setStage(player, 50) + setVarbit(player!!, 532, 9, true) + stage = END_DIALOGUE + } + } + } + + else { + abandonFile() + } + } +} diff --git a/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/GoblinFollower.kt b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/GoblinFollower.kt new file mode 100644 index 0000000..987f730 --- /dev/null +++ b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/GoblinFollower.kt @@ -0,0 +1,39 @@ +package content.region.misthalin.dorgeshuun.quest.thelosttribe + +import core.game.component.Component +import core.game.node.entity.player.Player +import core.game.system.task.Pulse +import core.game.world.map.Location +import org.rs09.consts.Components +import core.game.world.GameWorld + +/** + * Small object for the goblin follow options + * @author Ceikry + */ +object GoblinFollower { + fun sendToMines(player: Player){ + travel(player,Location.create(3319, 9616, 0)) + } + fun sendToLumbridge(player: Player){ + travel(player,Location.create(3232, 9610, 0)) + } + + private fun travel(player: Player,location: Location){ + GameWorld.Pulser.submit(object: Pulse(){ + var counter = 0 + override fun pulse(): Boolean { + when(counter++){ + 0 -> player.lock().also { player.interfaceManager.open(Component(Components.FADE_TO_BLACK_120)) } + 3 -> player.properties.teleportLocation = location + 4 -> { + player.interfaceManager.close(Component(Components.FADE_TO_BLACK_120)) + player.interfaceManager.open(Component(Components.FADE_FROM_BLACK_170)) + } + 6 -> player.unlock().also { player.interfaceManager.close(Component(170)); return true } + } + return false + } + }) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/HistoryOfTheGoblinRace.kt b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/HistoryOfTheGoblinRace.kt new file mode 100644 index 0000000..d6d5ed9 --- /dev/null +++ b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/HistoryOfTheGoblinRace.kt @@ -0,0 +1,64 @@ +package content.region.misthalin.dorgeshuun.quest.thelosttribe + +import content.data.Quests +import core.game.component.Component +import core.game.component.ComponentDefinition +import core.game.component.ComponentPlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.plugin.Plugin + +@Initializable +/** + * Handles the HOTGR interface + * @author Ceikry + */ +class HistoryOfTheGoblinRace : ComponentPlugin() { + override fun newInstance(arg: Any?): Plugin { + ComponentDefinition.put(183,this) + return this + } + + override fun open(player: Player?, component: Component?) { + player ?: return + super.open(player, component) + player.packetDispatch.sendInterfaceConfig(183,17,true) + val qstage = player.questRepository.getQuest(Quests.THE_LOST_TRIBE).getStage(player) + component?.setCloseEvent { player, c -> + if(qstage == 42 || qstage == 41 ) { + player.dialogueInterpreter.sendDialogues(player, FacialExpression.THINKING, "Hey... The symbol of the 'Dorgeshuun' tribe looks just", "like the symbol on the brooch I found.") + player.questRepository.getQuest(Quests.THE_LOST_TRIBE).setStage(player, 43) + } + player.removeAttribute("hgr-index") + true + } + } + + override fun handle(player: Player?, component: Component?, opcode: Int, button: Int, slot: Int, itemId: Int): Boolean { + player ?: return false + when(button){ + 16 -> setIndex(player,getIndex(player) + 1) + 17 -> setIndex(player,getIndex(player) - 1) + } + update(player) + return true + } + + fun update(player: Player){ + val index = getIndex(player) + player.packetDispatch.sendInterfaceConfig(183,32,index != 0) + player.packetDispatch.sendInterfaceConfig(183,14,index != 1) + player.packetDispatch.sendInterfaceConfig(183,15,index != 2) + player.packetDispatch.sendInterfaceConfig(183,16,index == 2) + player.packetDispatch.sendInterfaceConfig(183,17,index == 0) + } + + fun setIndex(player: Player, index: Int){ + player.setAttribute("hgr-index",index) + } + + fun getIndex(player: Player): Int{ + return player.getAttribute("hgr-index",0) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/KazgarDialogue.kt b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/KazgarDialogue.kt new file mode 100644 index 0000000..86d056d --- /dev/null +++ b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/KazgarDialogue.kt @@ -0,0 +1,46 @@ +package content.region.misthalin.dorgeshuun.quest.thelosttribe + +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable + +@Initializable +/** + * Dialogue for Kazgar + * @author Ceikry + */ +class KazgarDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player?): DialoguePlugin { + return KazgarDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = (args[0] as NPC).getShownNPC(player) + options("Who are you?","Can you show me to the mine?") + stage = 0 + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage) { + 0 -> when (buttonId) { + 1 -> player("Who are you?").also { stage = 10 } + 2 -> player("Can you show me the way to the other side?").also { stage = 20 } + } + 10 -> npc("I'm Kazgar, I guide people through the mines.").also { stage = 1000 } + 20 -> npc("Certainly!").also { stage++ } + 21 -> end().also { + GoblinFollower.sendToMines(player) + } + + 1000 -> end() + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(2085) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/LostTribe.kt b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/LostTribe.kt new file mode 100644 index 0000000..2bbcda8 --- /dev/null +++ b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/LostTribe.kt @@ -0,0 +1,128 @@ +package content.region.misthalin.dorgeshuun.quest.thelosttribe + +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import core.plugin.Initializable +import org.rs09.consts.Items +import core.api.* +import content.data.Quests + +@Initializable +/** + * Represents the lost tribe quest and quest journal + * @author Ceikry + */ +class LostTribe : Quest(Quests.THE_LOST_TRIBE,84,83,1) { + override fun newInstance(`object`: Any?): Quest { + return this + } + + override fun drawJournal(player: Player?, stage: Int) { + super.drawJournal(player, stage) + player ?: return + var line = 11 + if(stage == 0){ + line(player,"I can start this quest by speaking to !!Sigmund?? in !!Lumbridge??",line++) + line(player,"!!Castle.??",line++) + line(player,"I must have completed:",line++) + line(player,"Rune Mysteries" ,line++,player?.questRepository?.isComplete(Quests.RUNE_MYSTERIES) == true) + line(player,"Goblin Diplomacy" ,line++,player?.questRepository?.isComplete(Quests.GOBLIN_DIPLOMACY) == true) + line(player,"and have:",line++) + line(player,"Level 17 mining",line++,player.skills.getLevel(Skills.MINING) >= 17) + line(player,"Level 13 agility",line++,player.skills.getLevel(Skills.AGILITY) >= 13) + line(player,"Level 13 thieving",line++,player.skills.getLevel(Skills.THIEVING) >= 13) + } else { + if(stage >= 10) { + line(player, "!!Sigmund?? said I should ask around town and see", line++, stage >= 20) + line(player, "if anyone had seen what happened in the !!cellar??.", line++, stage >= 20) + } + if(stage >= 20){ + line(player, "I found out that someone had seen a !!goblin-like?? creature in the cellar.",line++,stage >= 30) + line(player,"I should go speak to !!The Duke?? about this.",line++,stage >= 30) + } + if(stage >= 30){ + line(player,"The Duke gave me permission to investigate !!the tunnel??.",line++,stage >= 40) + line(player,"I should get down into the !!cellar?? and try to unblock the !!tunnel??.",line++,stage >= 40) + } + if(stage >= 40){ + line(player,"The Duke asked me to speak with the !!librarian?? in !!Varrock??",line++,stage >= 43) + line(player,"and see if he can identify the brooch.",line++,stage >= 43) + } + if(stage >= 43){ + line(player,"I should go speak with some !!goblins?? who might be able",line++,stage >= 44) + line(player,"to teach me more about the !!Dorgeshuun??. Perhaps the",line++,stage >= 44) + line(player,"!!generals in Goblin Village?? can help.",line++,stage >= 44) + } + if(stage >= 44){ + line(player,"I should return to !!Duke Horacio?? with my findings.",line++,stage >= 45) + } + if(stage >= 45){ + line(player,"I should try to make contact with the !!Dorgeshuun??.",line++,stage >= 46) + } + if(stage >= 46){ + line(player,"I need to return to !!Duke Horacio?? and ask him to stop",line++,stage >= 47) + line(player,"the war!",line++,stage >= 47) + } + if(stage >= 47){ + line(player,"Duke Horacio said the goblins stole some !!silverware??.",line++,stage >= 49) + line(player,"I need to find it if I want to stop the war.",line++,stage >= 49) + } + if(stage >= 48){ + line(player,"I found !!H.A.M. robes?? in !!Sigmund??'s chest. Perhaps",line++,stage >= 49) + line(player,"I should check the !!H.A.M. hideout?? behind the castle",line++,stage >= 49) + line(player,"for the missing !!silverware??.",line++,stage >= 49) + } + if(stage >= 49){ + line(player,"I found the !!silverware?? in the !!H.A.M. hideout??.",line++,stage >= 50) + line(player,"I should go inform !!Duke Horacio?? immediately!",line++,stage >= 50) + } + if(stage >= 50){ + line(player,"!!The Duke?? gave me a !!peace treaty?? to take to",line++,stage >= 51) + line(player,"the cave goblins. I should do so at once!",line++,stage >= 51) + } + if(stage >= 100){ + line(player,"%%QUEST COMPLETE!&&",line++) + } + } + + } + + override fun finish(player: Player?) { + super.finish(player) + player ?: return + var ln = 10 + player.packetDispatch.sendItemZoomOnInterface(Items.BROOCH_5008,230,277,5) + drawReward(player,"1 Quest Point",ln++) + drawReward(player,"3000 Mining XP",ln++) + drawReward(player,"A Ring of Life",ln++) + drawReward(player,"Freedom of the",ln++) + drawReward(player,"Dorgeshuun mines.",ln++) + player.skills.addExperience(Skills.MINING,3000.0) + if(!player.inventory.add(Item(Items.RING_OF_LIFE_2570))){ + GroundItemManager.create(Item(Items.RING_OF_LIFE_2570),player) + } + setVarp(player, 465, 11) + } + + override fun getConfig(player: Player?, stage: Int): IntArray { + player ?: return intArrayOf(465,0) + if(stage in 50..99){ + return intArrayOf(465,9) + } + if(stage in 46..49){ + return intArrayOf(465,8) + } + if(stage in 44..45){ + return intArrayOf(465,7) + } + if(stage in 30..43 && player.getAttribute("tlt-hole-cleared",false)){ + return intArrayOf(465,4) + } + if(stage >= 100) return intArrayOf(465,11) + if(stage > 0) return intArrayOf(465,1) + return intArrayOf(465,0) + } +} diff --git a/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/LostTribeCutscene.kt b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/LostTribeCutscene.kt new file mode 100644 index 0000000..f155df3 --- /dev/null +++ b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/LostTribeCutscene.kt @@ -0,0 +1,122 @@ +package content.region.misthalin.dorgeshuun.quest.thelosttribe + +import content.data.Quests +import core.api.animate +import core.api.face +import core.game.activity.Cutscene +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.emote.Emotes +import core.game.world.map.Direction +import core.game.world.map.Location +import core.game.global.action.DoorActionHandler +import core.game.dialogue.FacialExpression + +class LostTribeCutscene(player: Player) : Cutscene(player) { + override fun setup() { + setExit(Location.create(3207, 3221, 0)) + if(player.settings.isRunToggled){ + player.settings.toggleRun() + } + loadRegion(12850) + addNPC(DUKE, 6, 23, Direction.SOUTH) + addNPC(MISTAG, 8, 17, Direction.NORTH) + addNPC(URTAG, 8, 15, Direction.NORTH) + addNPC(SIGMUND, 13, 22, Direction.NORTH_WEST) + } + + override fun runStage(stage: Int) { + when(stage) + { + 0 -> { + fadeToBlack() + timedUpdate(6) + } + 1 -> { + teleport(player, 7, 17) + timedUpdate(2) + } + 2 -> { + fadeFromBlack() + moveCamera(8, 26) + rotateCamera(5, 18) + timedUpdate(6) + } + 3 -> { + DoorActionHandler.handleDoor(player, getObject(7, 17)) + timedUpdate(3) + } + 4 -> { + move(player, 7, 22) + move(getNPC(MISTAG)!!, 7, 19) + move(getNPC(URTAG)!!, 7, 18) + timedUpdate(5) + } + 5 -> { + move(getNPC(MISTAG)!!, 7, 20) + move(getNPC(URTAG)!!, 6, 21) + timedUpdate(3) + } + 6 -> { + player.faceLocation(getNPC(DUKE)!!.location) + playerDialogueUpdate(FacialExpression.FRIENDLY, "Your grace, I present Ur-tag, headman of the Dorgeshuun.") + Emotes.BOW.play(player) + } + 7 -> { + move(player, 7, 24) + timedUpdate(5) + } + 8 -> { + animate(getNPC(DUKE)!!, Emotes.BOW.animation) + animate(getNPC(URTAG)!!, URTAG_BOW_ANIM) + dialogueUpdate(DUKE, FacialExpression.FRIENDLY, "Welcome, Ur-tag. I am sorry that your race came under suspicion.") + } + 9 -> { + dialogueUpdate(DUKE, FacialExpression.ANGRY, "I assure you that the warmongering element has been dealt with.") + moveCamera(9, 22) + rotateCamera(6, 22) + } + 10 -> dialogueUpdate(URTAG, FacialExpression.OLD_NORMAL, "I apologize for the damage to your cellar. I will send workers to repair the hole.") + 11 -> dialogueUpdate(DUKE, FacialExpression.FRIENDLY, "No, let it stay. It can be a route of commerce between our lands.") + 12 -> { + val duke = getNPC(DUKE)!! + face(duke, player.location) + face(player, duke.location) + rotateCamera(6, 22, 300, 3) + moveCamera(11, 22, 325, 3) + dialogueUpdate(DUKE, FacialExpression.FRIENDLY, "${player.username}, Lumbridge is in your debt. Please accept this ring as a token of my thanks.") + } + 13 -> dialogueUpdate(DUKE, FacialExpression.FRIENDLY, "It is enchanted to save you in your hour of need.") + 14 -> { + move(getNPC(URTAG)!!, 7, 23) + dialogueUpdate(URTAG, FacialExpression.OLD_NORMAL,"I too thank you. Accept the freedom of the Dorgeshuun mines." ) + } + 15 -> { + dialogueUpdate(URTAG, FacialExpression.OLD_NORMAL, "These are strange times. I never dreamed that I would see the surface, still less that I would be on friendly terms with its people." ) + moveCamera(16, 21, 300, 3) + rotateCamera(6, 22, 300, 2) + } + 16 -> dialogueUpdate(SIGMUND, FacialExpression.ANGRY, "Prattle on, goblin.") + 17 -> { + animate(getNPC(SIGMUND)!!, Emotes.LAUGH.animation) + dialogueUpdate(SIGMUND, FacialExpression.EVIL_LAUGH, "Soon you will be destroyed!") + } + 18 -> { + move(getNPC(SIGMUND)!!, 16, 17) + timedUpdate(4) + } + 19 -> { + end { + player.questRepository.getQuest(Quests.THE_LOST_TRIBE).finish(player) + } + } + } + } + + companion object { + private const val DUKE = 2088 + private const val MISTAG = 2089 + private const val SIGMUND = 2090 + private const val URTAG = 5858 + private const val URTAG_BOW_ANIM = 6000 + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/LostTribeOptionHandler.kt b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/LostTribeOptionHandler.kt new file mode 100644 index 0000000..a361dcf --- /dev/null +++ b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/LostTribeOptionHandler.kt @@ -0,0 +1,74 @@ +package content.region.misthalin.dorgeshuun.quest.thelosttribe + +import content.data.Quests +import core.api.addItemOrDrop +import core.cache.def.impl.ItemDefinition +import core.cache.def.impl.NPCDefinition +import core.cache.def.impl.SceneryDefinition +import core.game.component.Component +import core.game.interaction.OptionHandler +import core.game.node.Node +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import core.plugin.Plugin +import org.rs09.consts.Items + +private val BOOK = Item(Items.GOBLIN_SYMBOL_BOOK_5009) +@Initializable +/** + * Handles misc. lost tribe interactions + * @author Ceikry + */ +class LostTribeOptionHandler : OptionHandler(){ + override fun newInstance(arg: Any?): Plugin { + ItemDefinition.forId(5008).handlers["option:look-at"] = this + ItemDefinition.forId(5009).handlers["option:read"] = this + SceneryDefinition.forId(6916).handlers["option:search"] = this + SceneryDefinition.forId(6911).handlers["option:search"] = this + NPCDefinition.forId(2084).handlers["option:follow"] = this + NPCDefinition.forId(2086).handlers["option:follow"] = this + SceneryDefinition.forId(32952).handlers["option:open"] = this + SceneryDefinition.forId(32953).handlers["option:open"] = this + return this + } + + override fun handle(player: Player?, node: Node?, option: String?): Boolean { + player ?: return false + node ?: return false + when(node.id){ + 5008 -> player.interfaceManager.open(Component(50)) + 5009 -> player.interfaceManager.open(Component(183)) + 6916 -> { + if(!player.inventory.containsItem(BOOK) && !player.bank.containsItem(BOOK) && player.questRepository.getQuest( + Quests.THE_LOST_TRIBE).getStage(player) >= 41){ + player.dialogueInterpreter.sendDialogue("'A History of the Goblin Race.' This must be it.") + player.inventory.add(BOOK) + } else { + return false + } + } + 6911 -> { + if(!player.inventory.containsItem(Item(Items.SILVERWARE_5011)) && player.questRepository.getQuest(Quests.THE_LOST_TRIBE).getStage(player) == 48){ + player.dialogueInterpreter.sendItemMessage(Items.SILVERWARE_5011,"You find the missing silverware!") + addItemOrDrop(player, Items.SILVERWARE_5011) + player.questRepository.getQuest(Quests.THE_LOST_TRIBE).setStage(player,49) + } else { + player.sendMessage("You find nothing.") + } + } + 32952,32953 -> { + player.dialogueInterpreter.sendDialogues(player, core.game.dialogue.FacialExpression.THINKING,"I don't think I have permission to go in there.") + } + } + + if(option.equals("follow")){ + when(node.id){ + 2084 -> GoblinFollower.sendToLumbridge(player) + 2085 -> GoblinFollower.sendToMines(player) + } + } + return true + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/MistagLTDialogue.kt b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/MistagLTDialogue.kt new file mode 100644 index 0000000..8c637a8 --- /dev/null +++ b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/MistagLTDialogue.kt @@ -0,0 +1,60 @@ +package content.region.misthalin.dorgeshuun.quest.thelosttribe + +import content.data.Quests +import core.game.component.Component +import core.game.dialogue.FacialExpression +import core.game.dialogue.DialogueFile +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE + + +class MistagLTDialogue(val isGreeting: Boolean, val questStage: Int) : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + + if(isGreeting){ + when(stage){ + //Greeting dialogue + START_DIALOGUE -> npc("Perhaps you are a friend after all!").also { stage++ } + 1 -> npc("Greetings, friend. I am sorry I panicked when I saw you.").also { stage++ } + 2 -> npc("Our legends tell of the surface as a place of horror and","violence, where the gods forced us to fight in terrible","battles.").also { stage++ } + 3 -> npc("When I saw a surface-dweller appear I was afraid it","was a return to the old days!").also { stage++ } + 4 -> player("Did you break in to the castle cellar?").also { stage++ } + 5 -> npc("It was an accident. We were following a seam of iron","and suddenly we found ourselves in a room!").also { stage++ } + 6 -> npc("We blocked up our tunnel behind us and ran back","here. Then we did what cave goblins always do when","there is a problem: we hid and hoped it would go away.").also { stage++ } + 7 -> npc("We meant no harm! Please tell the ruler of the above","people that we want to make peace.").also { stage = END_DIALOGUE; player!!.questRepository.getQuest( + Quests.THE_LOST_TRIBE).setStage(player,46) } + } + } + + else{ + if(questStage == 45){ + when(stage){ + START_DIALOGUE -> npc("Our legends tell of the surface as a place of horror and","violence, where the gods forced us to fight in terrible","battles.").also { stage++ } + 1 -> npc("When I saw a surface-dweller appear I was afraid it","was a return to the old days!").also { stage++ } + 2 -> player("Did you break in to the castle cellar?").also { stage++ } + 3 -> npc("It was an accident. We were following a seam of iron","and suddenly we found ourselves in a room!").also { stage++ } + 4 -> npc("We blocked up our tunnel behind us and ran back","here. Then we did what cave goblins always do when","there is a problem: we hid and hoped it would go away.").also { stage++ } + 5 -> npc("We meant no harm! Please tell the ruler of the above","people that we want to make peace.").also { stage = END_DIALOGUE; player!!.questRepository.getQuest(Quests.THE_LOST_TRIBE).setStage(player,46) } + } + } + + if(questStage == 50){ + when(stage){ + START_DIALOGUE -> player("I have a peace treaty from the Duke of Lumbridge.").also { stage++ } + 1 -> npc("A peace treaty? Then you will not invade?").also { stage++ } + 2 -> player("No. As long as you stick to the terms of this treaty","there will be no conflict. The Duke of Lumbridge wants","to meet your ruler to sign it.").also { stage++ } + 3 -> npc("I will summon Ur-tag, our headman, at once.").also { stage++ } + 4 -> { + end() + LostTribeCutscene(player!!).start() + //ActivityManager.start(player,"Lost Tribe Cutscene",false) + } + } + } + } + } + + override fun npc(vararg messages: String?): Component? { + return npc(FacialExpression.OLD_NORMAL,*messages) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/PickaxeOnRubble.kt b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/PickaxeOnRubble.kt new file mode 100644 index 0000000..a1a8711 --- /dev/null +++ b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/PickaxeOnRubble.kt @@ -0,0 +1,73 @@ +package content.region.misthalin.dorgeshuun.quest.thelosttribe + +import content.data.Quests +import core.game.interaction.NodeUsageEvent +import core.game.interaction.UseWithHandler +import core.game.node.entity.skill.Skills +import content.data.skill.SkillingTool +import core.game.system.task.Pulse +import core.game.world.GameWorld +import core.plugin.Initializable +import core.plugin.Plugin +import core.api.* + +@Initializable +/** + * Handles the usage of a pickaxe on the rubble for lost tribe + * @author Ceikry + */ +class PickaxeOnRubble : UseWithHandler(1265,1267,1269,1271,1273,1275){ + override fun newInstance(arg: Any?): Plugin { + for(id in arrayOf(6898, 6903, 6904, 6905)) { + addHandler(id, OBJECT_TYPE,this) + } + return this + } + + override fun handle(event: NodeUsageEvent?): Boolean { + val player = event?.player ?: return false + val stage = player.questRepository.getQuest(Quests.THE_LOST_TRIBE).getStage(player) + if(stage < 30){ + player.dialogueInterpreter.sendItemMessage(event.usedItem.id,"I should probably figure out what happened","before vandalizing the castle more.") + return true + } + + val tool = SkillingTool.getPickaxe(player) + if(tool == null){ + player.dialogueInterpreter.sendDialogue("You don't have a pick which you have the level to use.") + return true + } + + if(player.skills.getLevel(Skills.MINING) < 13){ + player.dialogueInterpreter.sendDialogue("You need 13 mining to break through.") + return true + } + + player.lock() + GameWorld.Pulser.submit(object : Pulse(){ + var counter = 0 + override fun pulse(): Boolean { + when(counter++){ + 0 -> { + player.walkingQueue.reset() + player.walkingQueue.addPath(3219,9618,true) + } + 1 -> { + player.animator.animate(tool.animation) + delay = tool.animation.duration + } + 2 -> { + player.dialogueInterpreter.sendItemMessage(tool.id,"You dig a narrow tunnel through the rocks.") + player.setAttribute("/save:tlt-hole-cleared",true) + setVarbit(player, 532, 4, true) + player.unlock() + return true + } + } + return false + } + }) + return true + } + +} diff --git a/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/PickpocketSigmund.kt b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/PickpocketSigmund.kt new file mode 100644 index 0000000..a4e519e --- /dev/null +++ b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/PickpocketSigmund.kt @@ -0,0 +1,45 @@ +package content.region.misthalin.dorgeshuun.quest.thelosttribe + +import content.data.Quests +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.game.world.GameWorld + +/** + * handles pickpocketing sigmund during the lost tribe quest + * @author Ceikry + */ +class PickpocketSigmund : InteractionListener { + val SIGMUND = NPCs.SIGMUND_2082 + + override fun defineListeners() { + on(SIGMUND, IntType.NPC, "pickpocket"){ player, node -> + player.lock() + GameWorld.Pulser.submit(object : Pulse(){ + var counter = 0 + override fun pulse(): Boolean { + when(counter++){ + 0 -> player.animator.animate(Animation(881)) + 3 -> { + if(player.questRepository.getQuest(Quests.THE_LOST_TRIBE).getStage(player) == 47 && !player.inventory.containsItem(Item(Items.KEY_423))){ + player.inventory.add(Item(Items.KEY_423)) + player.dialogueInterpreter.sendItemMessage(Items.KEY_423,"You find a small key on Sigmund.") + } else { + player.dialogueInterpreter.sendDialogues(2082, core.game.dialogue.FacialExpression.ANGRY,"What do you think you're doing?!") + } + player.unlock() + return true + } + } + return false + } + }) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/SigmundChestHandler.kt b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/SigmundChestHandler.kt new file mode 100644 index 0000000..ef26dc5 --- /dev/null +++ b/Server/src/main/content/region/misthalin/dorgeshuun/quest/thelosttribe/SigmundChestHandler.kt @@ -0,0 +1,40 @@ +package content.region.misthalin.dorgeshuun.quest.thelosttribe + +import content.data.Quests +import core.cache.def.impl.SceneryDefinition +import core.game.interaction.OptionHandler +import core.game.node.Node +import core.game.node.entity.player.Player +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import core.plugin.Initializable +import core.plugin.Plugin +import org.rs09.consts.Items + +@Initializable +/** + * Handles sigmund's chest + * @author Ceikry + */ +class SigmundChestHandler : OptionHandler() { + override fun newInstance(arg: Any?): Plugin { + SceneryDefinition.forId(6910).handlers["option:open"] = this + return this + } + + override fun handle(player: Player?, node: Node?, option: String?): Boolean { + player ?: return false + if(player.questRepository.getQuest(Quests.THE_LOST_TRIBE).getStage(player) == 47 && player.inventory.contains(Items.KEY_423,1)){ + player.inventory.remove(Item(Items.KEY_423)) + for(item in arrayOf(Items.HAM_ROBE_4300,Items.HAM_SHIRT_4298,Items.HAM_HOOD_4302).map { Item(it) }){ + if(!player.inventory.add(item)){ + GroundItemManager.create(item,player) + } + } + player.questRepository.getQuest(Quests.THE_LOST_TRIBE).setStage(player,48) + } else { + player.sendMessage("This chest requires a key.") + } + return true + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/draynor/dialogue/AggieDialogue.java b/Server/src/main/content/region/misthalin/draynor/dialogue/AggieDialogue.java new file mode 100644 index 0000000..fe7fb48 --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/dialogue/AggieDialogue.java @@ -0,0 +1,420 @@ +package content.region.misthalin.draynor.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.game.world.update.flag.context.Animation; +import content.data.Quests; + +/** + * Represents the dialogue plugin used for the aggie npc. + * @author 'Vexia + * @version 1.5 + */ +@Initializable +public final class AggieDialogue extends DialoguePlugin { + + /** + * Represents the animaton used to make the dye with aggie. + */ + private static final Animation ANIMATION = new Animation(4352); + + /** + * Represents the ingredients needed to make paste. + */ + + private static final Item ASHES = new Item(592); + private static final Item POT_OF_FLOUR = new Item(1933); + private static final Item REDBERRIES_SINGLE= new Item(1951); // specifying single because 3 redberries are needed for the red dye + private static final Item[] PASTE_SOLID_INGREDIENTS = new Item[] { ASHES, REDBERRIES_SINGLE, POT_OF_FLOUR }; + + private static final Item BUCKET_OF_WATER = new Item(1929); + private static final Item JUG_OF_WATER = new Item(1937); // Jug of Water is meant to be substitutable with the Bucket of Water + + /** + * Represents the cauldron location + */ + private final static Location CAULDRON_LOCATION = Location.create(3085, 3258, 0); + + /** + * Represents the coins item. + */ + private static final Item COINS = new Item(995, 5); + + /** + * Represents the woad leaves item. + */ + private static final Item WOAD_LEAVES = new Item(1793, 2); + + /** + * Represents the onions item. + */ + private static final Item ONIONS = new Item(1957, 2); + + /** + * Represents the redberries item. + */ + private static final Item REDBERRIES = new Item(1951, 3); + + /** + * Represents the skin paste item. + */ + private static final Item PASTE = new Item(2424); + + /** + * Represents the blue dye. + */ + private static final Item BLUE_DYE = new Item(1767); + + /** + * Represents the yellow dye item. + */ + private static final Item YELLOW_DYE = new Item(1765); + + /** + * Represents the red dye item. + */ + private static final Item RED_DYE = new Item(1763); + + /** + * Represents the quest instance. + */ + private Quest quest; + + /** + * Constructs a new {@code AggieDialogue} {@code Object}. + */ + public AggieDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code AggieDialogue} {@code Object}. + * @param player the player. + */ + public AggieDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new AggieDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + if (args.length >= 2) { + interpreter.sendOptions("Select an Option", "What do you need to make a red dye?", "What do you need to make yellow dye?", "What do you need to make blue dye?"); + stage = 42; + return true; + } + quest = player.getQuestRepository().getQuest(Quests.PRINCE_ALI_RESCUE); + npc("What can I help you with?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + if (quest.getStage(player) == 20 || quest.getStage(player) == 30 || quest.getStage(player) == 40 || quest.getStage(player) == 50 || quest.getStage(player) == 60) { + interpreter.sendOptions("Select an Option", "Could you think of a way to make skin paste?", "What could you make for me?", "Cool, do you turn people into frogs?", "You mad old witch, you can't help me.", "Can you make dyes for me please?"); + stage = 720; + return true; + } + interpreter.sendOptions("Select an Option", "What could you make for me?", "Cool, do you turn people into frogs?", "You mad old witch, you can't help me.", "Can you make dyes for me please?"); + stage = 1; + break; + case 720: + switch (buttonId) { + case 1: + player("Could you think of a way to make skin paste?"); + stage = 721; + break; + case 2: + player("What could you make for me?"); + stage = 10; + break; + case 3: + player("Cool, do you turn people into frogs?"); + stage = 20; + break; + case 4: + interpreter.sendDialogues(player, FacialExpression.FURIOUS, "You mad old witch, you can't help me."); + stage = 30; + break; + case 5: + interpreter.sendDialogues(player, FacialExpression.ASKING, "Can you make dyes for me please?"); + stage = 40; + break; + } + break; + case 721: + if (!hasIngredients(player)) { + interpreter.sendDialogues(npc, null, "Why it's one of my most popular potions. The women", "here, they like to have smooth looking skin. And I must", "admit, some of the men buy it as well."); + stage = 722; + } else { + interpreter.sendDialogues(npc, null, "Yes I can, I see you already have the ingredients.", "Would you like me to mix some for you now?"); + stage = 726; + } + break; + case 722: + interpreter.sendDialogues(npc, null, "I can make it for you, just get me what's needed."); + stage = 723; + break; + case 723: + player("What do you need to make it?"); + stage = 724; + break; + case 724: + interpreter.sendDialogues(npc, null, "Well dearie, you need a base for the paste. That's a", "mix of ash, flour and water. Then you need redberries", "to colour it as you want. Bring me those four items", "and I will make you some."); + stage = 725; + break; + case 725: + end(); + break; + case 726: + interpreter.sendOptions("Select an Option", "Yes please. Mix me some skin paste.", "No thank you, I don't need any skin paste right now."); + stage = 727; + break; + case 727: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Yes please. Mix me some skin paste."); + stage = 731; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No thank you, I don't need any skin paste right now."); + stage = 729; + break; + } + break; + case 729: + npc("Okay dearie, that's always your choice."); + stage = 730; + break; + case 730: + end(); + break; + case 731: + npc("That should be simple. Hand the things to Aggie then."); + stage = 732; + break; + case 732: + // remove the solid ingredients and one of the water ingredients + if (player.getInventory().remove(PASTE_SOLID_INGREDIENTS) && (player.getInventory().remove(BUCKET_OF_WATER) || player.getInventory().remove(JUG_OF_WATER))) { + interpreter.sendDialogue("You hand the ash, flour, water and redberries to Aggie.", "Aggie tips the ingredients into a cauldron", "and mutters some words."); + stage = 733; + } + break; + case 733: + npc("Tourniquet, Fenderbaum, Tottenham, marshmaallow,", "MarbleArch."); + stage = 734; + break; + case 734: + if (player.getInventory().add(PASTE)) { + interpreter.sendDialogue("Aggie hands you the skin paste."); + stage = 735; + } + break; + case 735: + npc("There you go dearie, your skin potion. That will make", "you look good at the Varrock dances."); + stage = 736; + break; + case 736: + end(); + break; + case 1: + switch (buttonId) { + case 1: + player("What could you make for me?"); + stage = 10; + break; + case 2: + player("Cool, do you turn people into frogs?"); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.FURIOUS, "You mad old witch, you can't help me."); + stage = 30; + break; + case 4: + interpreter.sendDialogues(player, FacialExpression.ASKING, "Can you make dyes for me please?"); + stage = 40; + break; + } + break; + case 40: + interpreter.sendDialogues(npc, FacialExpression.ASKING, "What sort of dye would you like? Red, yellow or blue?"); + stage = 41; + break; + case 41: + interpreter.sendOptions("Select an Option", "What do you need to make a red dye?", "What do you need to make yellow dye?", "What do you need to make blue dye?"); + stage = 42; + break; + case 42: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.ASKING, "What do you need to make red dye?"); + stage = 410; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.ASKING, "What do you need to make yellow dye?"); + stage = 420; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.ASKING, "What do you need to make blue dye?"); + stage = 430; + break; + } + break; + case 430: + interpreter.sendDialogues(npc, null, "2 woad leaves and 5 coins to you."); + stage = 431; + break; + case 431: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Okay, make me some blue dye please."); + stage = 432; + break; + case 432: + if (player.getInventory().containsItem(COINS) && player.getInventory().containsItem(WOAD_LEAVES)) { + player.getInventory().remove(COINS); + player.getInventory().remove(WOAD_LEAVES); + player.getInventory().add(BLUE_DYE); + make(1767); + interpreter.sendItemMessage(1767, "You hand the woad leaves and payment to Aggie. Aggie produces a blue bottle and hands it to you."); + } else { + interpreter.sendDialogue("You need 2 woad leaves and 5 coins."); + } + stage = 413; + break; + case 433: + end(); + break; + case 420: + interpreter.sendDialogues(npc, null, "Yellow is a strange colour to get, comes from onion", "skins. I need 2 onions and 5 coins to make yellow dye."); + stage = 421; + break; + case 421: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Okay, make me some yellow dye please."); + stage = 422; + break; + case 422: + if (player.getInventory().containsItem(COINS) && player.getInventory().containsItem(ONIONS)) { + player.getInventory().remove(COINS); + player.getInventory().remove(ONIONS); + player.getInventory().add(YELLOW_DYE); + make(1765); + interpreter.sendItemMessage(1765, "You hand the onions and payment to Aggie. Aggie produces a yellow bottle and hands it to you."); + } else { + interpreter.sendDialogue("You need 2 onions and 5 coins."); + } + stage = 423; + break; + case 423: + end(); + break; + case 410: + interpreter.sendDialogues(npc, null, "3 lots of redberries and 5 coins to you."); + stage = 411; + break; + case 411: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Okay, make me some red dye please."); + stage = 412; + break; + case 412: + if (player.getInventory().containsItem(COINS) && player.getInventory().containsItem(REDBERRIES)) { + player.getInventory().remove(COINS); + player.getInventory().remove(REDBERRIES); + player.getInventory().add(RED_DYE); + make(1763); + interpreter.sendItemMessage(1763, "You hand the berries and payment to Aggie. Aggie produces a red bottle and hands it to you."); + } else { + interpreter.sendDialogue("You need 3 redberrie leaves and 5 coins."); + } + stage = 413; + break; + case 413: + end(); + break; + case 30: + interpreter.sendDialogues(npc, null, "Oh, you like to call a witch names do you?"); + stage = 31; + break; + case 31: + Item item = new Item(995, 20); + if (player.getInventory().remove(item)) { + interpreter.sendItemMessage(item, "Aggie waves her hands about, and you seem to be 20", "coins poorer."); + stage = 32; + } else { + interpreter.sendDialogues(npc, null, "You should be careful about insulting a witch. You", "never know what shape you could wake up in."); + stage = 34; + } + break; + case 32: + interpreter.sendDialogues(npc, null, "That's a fine for insulting a witch. You should learn", "some respect."); + stage = 33; + break; + case 34: + end(); + break; + case 33: + end(); + break; + case 20: + interpreter.sendDialogues(npc, null, "Oh, not for years, but if you meet a talking chicken,", "you have probably met the professor in the manor north", "of here. A few years ago it was flying fish. That", "machine is a menace."); + stage = 11; + break; + case 10: + interpreter.sendDialogues(npc, null, "I mostly make what I find pretty. I sometimes", "make dye for the women's clothes to brighten the place", "up. I can make red, yellow and blue dyes. If you'd like", "some, just bring me the appropriate ingredients."); + stage = 11; + break; + case 11: + end(); + break; + } + return true; + } + + /** + * Method used to make a dye. + * @param dye the dye. + */ + public final void make(int dye) { + npc.animate(ANIMATION); + npc.faceLocation(CAULDRON_LOCATION); + } + + /** + * Method used to check if the player has the ingredients for the paste. + * @param player the player. + * @return {@code True} if so. + */ + private final boolean hasIngredients(final Player player) { + // check if the player has all the solid ingredients + for (Item i : PASTE_SOLID_INGREDIENTS) { + if (!player.getInventory().containsItem(i)) { + return false; + } + } + // check if the player has a bucket or jug of water + if (!(player.getInventory().containsItem(BUCKET_OF_WATER) || player.getInventory().containsItem(JUG_OF_WATER))) { + return false; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 922 }; + } +} diff --git a/Server/src/main/content/region/misthalin/draynor/dialogue/ChickenBook.kt b/Server/src/main/content/region/misthalin/draynor/dialogue/ChickenBook.kt new file mode 100644 index 0000000..f8e06d5 --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/dialogue/ChickenBook.kt @@ -0,0 +1,111 @@ +package content.region.misthalin.draynor.dialogue + +import content.global.handlers.iface.BookInterface +import content.global.handlers.iface.BookLine +import content.global.handlers.iface.Page +import content.global.handlers.iface.PageSet +import core.api.setAttribute +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import org.rs09.consts.Items + +class ChickenBook : InteractionListener { + + // Book about the Evil Chicken found on the bookshelves in the Wise Old Man's house in Draynor Village. + + companion object { + private val TITLE = "The Origins of the Bird of Evil" + private val CONTENTS = arrayOf( + PageSet( + Page( + BookLine("Many are the rumours", 55), + BookLine("and tales surrounding", 56), + BookLine("this foul beast.", 57), + BookLine("", 58), + BookLine("The earliest of these tales", 59), + BookLine("seems to date back to", 60), + BookLine("the time of the Mahjarrat.", 61), + BookLine("It is a story about a mad", 62), + BookLine("mage, who attempts to summon", 63), + BookLine("a demon and bind it to his", 64), + BookLine("will. Unfortunately his", 65), + ), + Page( + BookLine("spell failed and all that", 66), + BookLine("appeared was one confused", 67), + BookLine("chicken. In a fit of anger", 68), + BookLine("at his failure the mage", 69), + BookLine("banished the chicken to the", 70), + BookLine("Abyss. The chicken however", 71), + BookLine("appears to have survived", 72), + BookLine("and grown in power. Years", 73), + BookLine("later, when the mage cast", 74), + BookLine("another spell of summoning,", 75), + BookLine("the chicken appeared!", 76), + ) + ), + PageSet( + Page( + BookLine("The story does not tell", 55), + BookLine("of what became of the mage.", 56), + BookLine("", 57), + BookLine("Another popular tale", 58), + BookLine("tells of a chicken of", 59), + BookLine("higher than average", 60), + BookLine("mental ability. Realising", 61), + BookLine("that it and its kind were", 62), + BookLine("prisoners in their coops", 63), + BookLine("he organised a rebellion", 64), + BookLine("against the human farmers.", 65), + ), + Page( + BookLine("The farmers, of course,", 66), + BookLine("simply slaughtered the", 67), + BookLine("rebellious chickens.", 68), + BookLine("However, ", 70), + BookLine("the Evil Chicken escaped.", 71), + BookLine("Blaming its brethren for", 72), + BookLine("the coup's failure it", 73), + BookLine("swore revenge on", 74), + BookLine("all chickens and all humans.", 75), + ) + ), + PageSet( + Page( + BookLine("The Chicken can strike", 55), + BookLine("anybody, anywhere. It", 56), + BookLine("is said that a coven ", 57), + BookLine("worships this fell fowl and", 58), + BookLine("have even built a shrine to it.", 59), + BookLine("The exact location of this", 60), + BookLine("shrine is unknown, but is", 61), + BookLine("rumoured to be in the", 62), + BookLine("fairyworlds. Further", 63), + BookLine("rumour suggests that", 64), + BookLine("his lair is guarded by", 65), + ), + Page( + BookLine("some fearsome beasts, but", 66), + BookLine("it may be reached by", 67), + BookLine("making a tasty offering...", 68), + BookLine("whatever that may be.", 69), + ), + ) + ) + } + + private fun display(player: Player, pageNum: Int, buttonID: Int): Boolean { + BookInterface.pageSetup( + player, BookInterface.FANCY_BOOK_3_49, TITLE, CONTENTS + ) + return true + } + + override fun defineListeners() { + on(Items.BOOK_ON_CHICKENS_7464, IntType.ITEM, "read") { player, _ -> + BookInterface.openBook(player, BookInterface.FANCY_BOOK_3_49, ::display) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/draynor/dialogue/DiangoDialogue.java b/Server/src/main/content/region/misthalin/draynor/dialogue/DiangoDialogue.java new file mode 100644 index 0000000..754d79d --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/dialogue/DiangoDialogue.java @@ -0,0 +1,109 @@ +package content.region.misthalin.draynor.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the dialogue plugin used by diango. + * @author 'Vexia + * @version 1.1 + */ +@Initializable +public final class DiangoDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code DiangoDialogue {@code Object}. + */ + public DiangoDialogue() { + /* + * empty. + */ + } + + /** + * Constructs a new {@code DiangoDialogue} {@code Object}. + * @param player the player. + */ + public DiangoDialogue(Player player) { + super(player); + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + options("Spinning plates?", "I'd like to check holiday items please!", "I'd like to claim purchased cosmetics."); + stage++; + break; + case 1: + switch (buttonId) { + case 1: + player("Spinning plates?"); + stage = 10; + break; + case 2: + player("I'd like to check holiday items please?"); + stage = 20; + break; + case 3: + player("I'd like to claim purchased cosmetics."); + stage = 30; + break; + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.LAUGH, "That's right. There's a funny story behind them, their", "shipment was held up by thieves"); + stage = 11; + break; + case 11: + interpreter.sendDialogues(npc, FacialExpression.LAUGH, "The crate was marked 'Dragon Plates'.", "Apparently they thought it was some kind of armour,", "when really it's just a plate!"); + stage = 12; + break; + case 12: + end(); + npc.openShop(player); + break; + case 20: + npc("Sure thing, let me just see what you're missing."); + stage++; + break; + case 21: + openItemReturn(player); + end(); + break; + case 30: + end(); + break; + } + return true; + } + + /** + * Opens the item return. + * @param player the player. + */ + private void openItemReturn(Player player) { + + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new DiangoDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Howdy there, partner! Want to see my spinning plates?", "Or did ya want a holiday item back?"); + stage = 0; + return true; + } + + @Override + public int[] getIds() { + return new int[] { 970 }; + } +} diff --git a/Server/src/main/content/region/misthalin/draynor/dialogue/DraynorBankGuard.java b/Server/src/main/content/region/misthalin/draynor/dialogue/DraynorBankGuard.java new file mode 100644 index 0000000..13275ac --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/dialogue/DraynorBankGuard.java @@ -0,0 +1,335 @@ +package content.region.misthalin.draynor.dialogue; + +import core.game.activity.ActivityManager; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.game.node.item.Item; + +/** + * Represents the dialogue plugin used for the draynor bank guard npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class DraynorBankGuard extends DialoguePlugin { + + /** + * Represents the coins item needed to re-watch the recording. + */ + private static final Item COINS = new Item(995, 50); + + /** + * Constructs a new {@code DraynorBankGuard} {@code Object}. + */ + public DraynorBankGuard() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code DraynorBankGuard} {@code Object}. + * @param player the player. + */ + public DraynorBankGuard(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new DraynorBankGuard(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Yes?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + if (!player.getSavedData().getGlobalData().isDraynorRecording()) { + interpreter.sendOptions("Select an option", "Can I deposit my stuff here?", "That wall doesn't look very good.", "Sorry, I don't want anything."); + stage = 1; + } else { + interpreter.sendOptions("Select an Option", "Can I see that recording again, please?", "Sorry, I don't want anything."); + stage = 70; + } + break; + case 70: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, null, "Can I see that recording again, please?"); + stage = 71; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Sorry, I don't want anything."); + stage = 30; + break; + } + break; + case 71: + npc("I'd like you to pay me 50 gp first."); + stage = 72; + break; + case 72: + if (!player.getInventory().containsItem(COINS)) { + player("I'm not carrying that much."); + stage = 73; + return true; + } else { + options("Ok, here's 50 gp.", "Thanks, maybe another day."); + stage = 80; + } + break; + case 73: + if (player.getBank().containsItem(COINS)) { + npc("As a bank employee, I suppose I could take the money", "directly from your bank account."); + stage = 74; + } else { + npc("Come back when you do."); + stage = 75; + } + break; + case 74: + options("Ok, you can take 50 gp from my bank account.", "Thanks, maybe another day."); + stage = 76; + break; + case 75: + end(); + break; + case 76: + switch (buttonId) { + case 1: + player("Ok, you can take 50 gp from my bank account."); + stage = 79; + break; + case 2: + player("Thanks, maybe another day."); + stage = 77; + break; + } + break; + case 77: + npc("Ok."); + stage = 78; + break; + case 78: + end(); + break; + case 79: + end(); + if (player.getBank().containsItem(COINS) && player.getBank().remove(COINS)) { + startRecording(player); + } + break; + case 80: + switch (buttonId) { + case 1: + player("Ok, here's 50 gp."); + stage = 81; + break; + case 2: + player("Thanks, maybe another day."); + stage = 77; + break; + } + break; + case 81: + end(); + if (!player.getInventory().containsItem(COINS)) { + end(); + return true; + } + if (player.getInventory().remove(COINS)) { + startRecording(player); + } + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello. Can I deposit my stuff here?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "That wall doesn't look very good."); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Sorry, I don't want anything."); + stage = 30; + break; + } + break; + case 30: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ok."); + stage = 31; + break; + case 31: + end(); + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "No, it doesn't."); + stage = 21; + break; + case 21: + options("Are you going to tell me what happened?", "Alright, I'll stop bothering you now."); + stage = 22; + break; + case 22: + switch (buttonId) { + case 1: + player("Are you going to tell me what happended?"); + stage = 25; + break; + case 2: + player("Alright, I'll stop bothering you now."); + stage = 23; + break; + } + break; + case 23: + npc("Good day, sir."); + stage = 24; + break; + case 24: + end(); + break; + case 25: + npc("I could do."); + stage = 26; + break; + case 26: + player("Ok, go on!"); + stage = 27; + break; + case 27: + npc("Someone smashed the wall when", "they were robbing the bank."); + stage = 28; + break; + case 28: + player("Someone's robbed the bank?"); + stage = 29; + break; + case 29: + npc("Yes."); + stage = 50; + break; + case 50: + player("But... was anyone hurt?", "Did they get anything valuable?"); + stage = 51; + break; + case 51: + npc("Yes, but we were able to get more staff and mend the", "wall easily enough."); + stage = 52; + break; + case 52: + npc("The Bank has already replaced all the stolen items that", "belonged to customers."); + stage = 53; + break; + case 53: + player("Oh, good... but the bank staff got hurt?"); + stage = 54; + break; + case 54: + npc("Yes but the new ones are just as good."); + stage = 55; + break; + case 55: + player("You're not very nice, are you?"); + stage = 56; + break; + case 56: + npc("No-one's expecting me to be nice."); + stage = 57; + break; + case 57: + player("Anyway... So, someone's robbed the bank?"); + stage = 58; + break; + case 58: + npc("Yes."); + stage = 59; + break; + case 59: + player("Do you know who did it?"); + stage = 60; + break; + case 60: + npc("We are fairly sure we know who the robber was. The", "security recording was damaged in the attack, but it still", "shows his face clearly enough."); + stage = 61; + break; + case 61: + player("You've got a security recording?"); + stage = 62; + break; + case 62: + npc("Yes. Our insurers insisted that we", "install a magical scrying orb."); + stage = 63; + break; + case 63: + player("Can I see the recording?"); + stage = 64; + break; + case 64: + npc("I suppose so. But it's quite long."); + stage = 65; + break; + case 65: + options("That's ok, show me the recording.", "Thanks, maybe another day."); + stage = 66; + break; + case 66: + switch (buttonId) { + case 1: + player("That's ok, show me the recording."); + stage = 68; + break; + case 2: + player("Thanks, maybe another day."); + stage = 67; + break; + } + break; + case 67: + end(); + break; + case 68: + npc("Alright... The bank's magical playback device will feed the", "recorded images into your mind. Just shut your eyes."); + stage = 69; + break; + case 69: + startRecording(player); + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "No. I'm a security guard, not a bank clerk."); + stage = 11; + break; + case 11: + end(); + break; + } + return true; + } + + /** + * Method used to start the recording. + * @param player the player. + */ + private void startRecording(Player player) { + end(); + ActivityManager.start(player, "dbr cutscene", false); + } + + @Override + public int[] getIds() { + return new int[] { 2574 }; + } +} diff --git a/Server/src/main/content/region/misthalin/draynor/dialogue/FolkloreBook.kt b/Server/src/main/content/region/misthalin/draynor/dialogue/FolkloreBook.kt new file mode 100644 index 0000000..1ad19ee --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/dialogue/FolkloreBook.kt @@ -0,0 +1,60 @@ +package content.region.misthalin.draynor.dialogue + +import content.global.handlers.iface.BookInterface +import content.global.handlers.iface.BookLine +import content.global.handlers.iface.Page +import content.global.handlers.iface.PageSet +import core.api.setAttribute +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import org.rs09.consts.Items + +class FolkloreBook : InteractionListener { + + // Book found on the bookshelves in the Wise Old Man's house in Draynor Village. + + companion object { + private val TITLE = "The Myth of the Elder-dragons" + private val CONTENTS = arrayOf( + PageSet( + Page( + BookLine("Although the Elder-dragons", 55), + BookLine("are generally considered", 56), + BookLine("to be a myth, stories tell", 57), + BookLine("of an ancient race that dwelt", 58), + BookLine("on Gielinor before any other.", 59), + BookLine("In some arcane way their", 60), + BookLine("lifeforce was linked to the", 61), + BookLine("life of the world itself;", 62), + BookLine("it is written that, as long", 63), + BookLine("as the Elder-dragons", 64), + BookLine("continue to live,", 65), + ), + Page( + BookLine("the world shall not end.", 66), + BookLine("However, sceptics claim", 67), + BookLine("that the myth of the", 68), + BookLine("Elder-dragons was invented", 69), + BookLine("to cast doubt on claims", 70), + BookLine("that this realm was lifeless", 71), + BookLine("until the gods first arrived.", 72), + ), + ) + ) + } + + private fun display(player: Player, pageNum: Int, buttonID: Int): Boolean { + BookInterface.pageSetup( + player, BookInterface.FANCY_BOOK_3_49, TITLE, CONTENTS + ) + return true + } + + override fun defineListeners() { + on(Items.BOOK_OF_FOLKLORE_5508, IntType.ITEM, "read") { player, _ -> + BookInterface.openBook(player, BookInterface.FANCY_BOOK_3_49, ::display) + return@on true + } + } +} diff --git a/Server/src/main/content/region/misthalin/draynor/dialogue/FortunatoDialogue.kt b/Server/src/main/content/region/misthalin/draynor/dialogue/FortunatoDialogue.kt new file mode 100644 index 0000000..a26beb3 --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/dialogue/FortunatoDialogue.kt @@ -0,0 +1,41 @@ +package content.region.misthalin.draynor.dialogue + +// import content.region.misthalin.silvarea.quest.ragandboneman.FortunatoDialogueFile +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class FortunatoDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + // openDialogue(player!!, FortunatoDialogueFile(), npc) + when (stage) { + START_DIALOGUE -> npcl(FacialExpression.ASKING, "Can I help you at all?").also { stage++ } + 1 -> showTopics( + Topic(FacialExpression.FRIENDLY, "Yes, what are you selling?", 2), + Topic(FacialExpression.FRIENDLY, "Not at the moment", 3), + ) + 2 -> openNpcShop(player, NPCs.FORTUNATO_3671).also { + end() + } + 3 -> npcl(FacialExpression.ANGRY, "Then move along, you filthy ragamuffin, I have customers to serve!").also { + stage = END_DIALOGUE + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return FortunatoDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.FORTUNATO_3671) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/draynor/dialogue/JoeGuardDialogue.java b/Server/src/main/content/region/misthalin/draynor/dialogue/JoeGuardDialogue.java new file mode 100644 index 0000000..b7b91c6 --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/dialogue/JoeGuardDialogue.java @@ -0,0 +1,189 @@ +package content.region.misthalin.draynor.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.plugin.Initializable; +import core.game.node.item.Item; +import content.data.Quests; + +/** + * Represents the dialogue of the Joe guard NPC. + * @author 'Vexia + * @date 1/14/1 + */ +@Initializable +public final class JoeGuardDialogue extends DialoguePlugin { + + /** + * Represents the beer item. + */ + private static final Item BEER = new Item(1917); + + /** + * Represents the quest instance. + */ + private Quest quest; + + /** + * Constructs a new {@code JoeGuardDialogue} {@code Object}. + */ + public JoeGuardDialogue() { + + } + + /** + * Constructs a new {@code JoeGuardDialogue} {@code Object}. + * @param player the player. + */ + public JoeGuardDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new JoeGuardDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + quest = player.getQuestRepository().getQuest(Quests.PRINCE_ALI_RESCUE); + switch (quest.getStage(player)) { + case 40: + if (player.getAttribute("guard-drunk", false)) { + interpreter.sendDialogues(npc, null, "Halt! Who goes there?"); + stage = 23; + return true; + } + if (player.getInventory().contains(1917, 3)) { + interpreter.sendDialogues(player, null, "I have some beer here, fancy one?"); + stage = 10; + break; + } + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hi, I'm Joe, door guard for Lady Keli."); + stage = 0; + break; + case 60: + case 100: + interpreter.sendDialogues(npc, null, "Halt! Who goes there? Friend or foe?"); + stage = 0; + break; + default: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hi, I'm Joe, door guard for Lady Keli."); + stage = 0; + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + if (quest.getStage(player) > 50) { + switch (stage) { + case 0: + interpreter.sendDialogues(player, null, "Hi friend, I am just checking out things here."); + stage = 1; + break; + case 1: + interpreter.sendDialogues(npc, null, "The Prince got away, I am in trouble. I better not talk", "to you, they are not sure I was drunk."); + stage = 2; + break; + case 2: + end(); + break; + } + return true; + } + if (stage >= 10 && quest.getStage(player) == 40) { + switch (stage) { + case 10: + interpreter.sendDialogues(npc, null, "Ah, that would be lovely, just one now,", "just to wet my throat."); + stage = 11; + break; + case 11: + interpreter.sendDialogues(player, null, "Of course, it must be tough being here without a drink."); + stage = 12; + break; + case 12: + interpreter.sendDialogue("You hand a beer to the guard, he drinks it in seconds."); + stage = 13; + break; + case 13: + if (!player.getInventory().containsItem(BEER)) { + end(); + return true; + } + if (player.getInventory().remove(BEER)) { + interpreter.sendDialogues(npc, null, "That was perfect, I can't thank you enough."); + stage = 14; + } + break; + case 14: + interpreter.sendDialogues(player, null, "How are you? Still ok? Not too drunk?"); + stage = 15; + break; + case 15: + interpreter.sendDialogues(player, null, "Would you care for another, my friend?"); + stage = 16; + break; + case 16: + interpreter.sendDialogues(npc, null, "I better not, I don't want to be drunk on duty."); + stage = 17; + break; + case 17: + interpreter.sendDialogues(player, null, "Here, just keep these for later,", "I hate to see a thirsty guard."); + stage = 18; + break; + case 18: + if (player.getInventory().remove(BEER) && player.getInventory().remove(BEER)) { + interpreter.sendDialogue("You hand two more beers to the guard.", "He takes a sip of one, and then he drinks the both."); + stage = 19; + player.setAttribute("/save:guard-drunk", true); + } + break; + case 19: + interpreter.sendDialogues(npc, null, "Franksh, that wash just what I need to shtay on guard.", "No more beersh, I don't want to get drunk."); + stage = 20; + break; + case 20: + interpreter.sendDialogue("The guard is drunk, and no longer a problem."); + stage = 21; + break; + case 21: + end(); + break; + case 23: + interpreter.sendDialogues(player, null, "Hello friend, I am just rescuing the prince, is that ok?"); + stage = 24; + break; + case 24: + interpreter.sendDialogues(npc, null, "Thatsh a funny joke. You are lucky I am shober. Go", "in peace, friend."); + stage = 21; + break; + } + return true; + } + switch (stage) { + case 0: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hi, who are you guarding here?"); + stage = 1; + break; + case 1: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Can't say, all very secret. You should get out of here.", "I am not suposed to talk while I guard."); + stage = 2; + break; + case 2: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 916 }; + } +} diff --git a/Server/src/main/content/region/misthalin/draynor/dialogue/LeelaDialogue.java b/Server/src/main/content/region/misthalin/draynor/dialogue/LeelaDialogue.java new file mode 100644 index 0000000..133cebf --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/dialogue/LeelaDialogue.java @@ -0,0 +1,350 @@ +package content.region.misthalin.draynor.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.GroundItemManager; +import core.plugin.Initializable; +import core.game.node.item.Item; +import content.data.Quests; + +/** + * Represnets the dialogue used to handle the Leela npc. + * @author 'Vexia + * @date 1/14/1 + */ +@Initializable +public final class LeelaDialogue extends DialoguePlugin { + + /** + * Represents the rope item. + */ + private static final Item ROPE = new Item(954); + + /** + * Represents the pink skirt item. + */ + private static final Item SKIRT = new Item(1013); + + /** + * Represents the yellow wig item. + */ + private static final Item YELLOW_WIG = new Item(2419); + + /** + * Represents the skin paste item. + */ + private static final Item PASTE = new Item(2424); + + /** + * Represents the bronze key item. + */ + private static final Item BRONZE_KEY = new Item(2418); + + /** + * Represents the quest instance. + */ + private Quest quest; + + /** + * Represents the count of materials you have gathered. + */ + private int itemCount; + + /** + * Constructs a new {@code LeelaDialogue} {@code Object}. + */ + public LeelaDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code LeelaDialogue} {@code Object}. + * @param player the player. + */ + public LeelaDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new LeelaDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + quest = player.getQuestRepository().getQuest(Quests.PRINCE_ALI_RESCUE); + switch (quest.getStage(player)) { + case 60: + case 100: + interpreter.sendDialogues(npc, null, "Thank you, Al-Kharid will forever owe you for your", "help. I think that if there is every anything that needs to", "be done, you will be someone they can rely on."); + stage = 0; + break; + case 50: + case 40: + if (!player.getInventory().containsItem(BRONZE_KEY) && !player.getBank().containsItem(BRONZE_KEY)) { + interpreter.sendDialogues(player, null, "I'm afraid I lost that key you gave me."); + stage = 0; + } else { + interpreter.sendDialogues(npc, null, "Ok now, you have all the basic equipment. What are", "your plans to stop the guard interfering?"); + stage = 10; + } + break; + case 30: + interpreter.sendDialogues(npc, null, "My father sent this key for you.", "Be careful not to lose it."); + stage = 0; + break; + case 20: + interpreter.sendDialogues(player, null, "I am here to help you free the prince."); + stage = 0; + break; + default: + interpreter.sendDialogues(player, null, "Hi!"); + stage = 0; + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (quest.getStage(player)) { + case 60: + case 100: + end(); + break; + case 50: + case 40: + switch (stage) { + case 0: + interpreter.sendDialogues(npc, null, "Foolish man!", "A new key will cost 15 coins."); + stage = 1; + break; + case 1: + if (player.getInventory().contains(995, 15)) { + interpreter.sendDialogues(player, null, "Here, I have 15 coins."); + stage = 2; + } else { + end(); + player.getPacketDispatch().sendMessage("You don't have enough coins."); + } + break; + case 2: + Item remove = new Item(995, 15); + if (!player.getInventory().containsItem(remove)) { + end(); + return true; + } + if (!player.getInventory().containsItem(BRONZE_KEY) && player.getInventory().remove(remove)) { + if (!player.getInventory().add(BRONZE_KEY)) { + GroundItemManager.create(BRONZE_KEY, player); + } + player.getPacketDispatch().sendMessage("Leela gives you another key."); + } + end(); + stage = 99; + break; + case 99: + end(); + break; + case 10: + interpreter.sendOptions("Select an Option", "I haven't spoken to him yet.", "I was going to attack him.", "I hoped to get him drunk.", "Maybe I could bribe him to leave."); + stage = 11; + break; + case 11: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, null, "I haven't spoken to him yet."); + stage = 110; + break; + case 2: + interpreter.sendDialogues(player, null, "I was going to attack him."); + stage = 120; + break; + case 3: + interpreter.sendDialogues(player, null, "I hoped to get him drunk."); + stage = 130; + break; + case 4: + interpreter.sendDialogues(player, null, "Maybe I could bribe him to leave."); + stage = 140; + break; + } + break; + case 110: + interpreter.sendDialogues(npc, null, "Well, speaking to him may find a weakness he has. See", "if there's something that could stop him bothering us."); + stage = 111; + break; + case 111: + end(); + break; + case 120: + interpreter.sendDialogues(npc, null, "I don't think you should. If you do the rest of the", "gang and Keli would attack you. The door guard", "should be removed first, to make it easy."); + stage = 121; + break; + case 121: + end(); + break; + case 130: + interpreter.sendDialogues(npc, null, "Well, that's possible. These guards do like a drink. I", "would think it will take at least 3 beers to do it well.", "You would probably have to do it all at the same time", "too. The effects of the local bear off quickly."); + stage = 131; + break; + case 131: + end(); + break; + case 140: + interpreter.sendDialogues(npc, null, "You could try. I don't think the emir will pay anything", "towards it. And we did bribe on of their guards once."); + stage = 141; + break; + case 141: + end(); + break; + } + break; + case 30: + switch (stage) { + case 0: + interpreter.sendDialogue("Leela gives you a copy of the key to the prince's door."); + stage = 1; + break; + case 1: + if (!player.getInventory().add(BRONZE_KEY)) { + GroundItemManager.create(BRONZE_KEY, player); + } + quest.setStage(player, 40); + interpreter.sendDialogues(npc, null, "Good, you have all the basic equipment. Next to deal", "with the guard on the door. He is talkative, try to find", "a weakness in him."); + stage = 2; + break; + case 2: + end(); + break; + } + break; + case 20: + switch (stage) { + case 0: + interpreter.sendDialogues(npc, null, "Your employment is known to me. Now, do you know", "all that we need to make the break?"); + stage = 1; + break; + case 1: + interpreter.sendOptions("Select an Option", "I must make a disguise. What do you suggest?", "I need to get the key made.", "What can I do with the guards?", "I will go and get the rest of the escape equipment."); + stage = 2; + break; + case 2: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, null, "I must a make a disguise. What do you suggest?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, null, "I need to get the key made."); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, null, "What can I do with the guards?"); + stage = 30; + break; + case 4: + interpreter.sendDialogues(player, null, "I will go and get the rest of the escape equipment."); + stage = 40; + break; + } + break; + case 10: + interpreter.sendDialogues(npc, null, "Only the lady Keli, can wander about outside the jail.", "The guards will shoot to kill if they see the prince out", "so we need a disguise good enough to fool them at a", "distance."); + stage = 11; + break; + case 11: + if (player.getInventory().containsItem(YELLOW_WIG)) { + interpreter.sendDialogues(npc, null, "The wig you have got, well done."); + itemCount++; + } else { + interpreter.sendDialogues(npc, null, "You need a wig, maybe made from wool. If you find", "someone who can work with wool ask them about it.", "There's a witch nearby may be able to help you dye it."); + } + stage = 12; + break; + case 12: + if (player.getInventory().containsItem(SKIRT)) { + interpreter.sendDialogues(npc, null, "You have got the skirt, good."); + itemCount++; + } else { + interpreter.sendDialogues(npc, null, "You will need to get a pink skirt, same as Keli's."); + } + stage = 13; + break; + case 13: + if (player.getInventory().containsItem(PASTE)) { + interpreter.sendDialogues(npc, null, "You have the skin paint, well done. I thought you would", "struggle to make that."); + itemCount++; + } else { + interpreter.sendDialogues(npc, null, "We still need something to colour the Prince's skin", "lighter. There's a witch close to here. She knows about", "many things. She may know some way to make the", "skin lighter."); + } + stage = itemCount == 3 ? 14 : 15; + break; + case 14: + interpreter.sendDialogues(npc, null, "You do have everything for the disguise."); + stage = 15; + break; + case 15: + if (player.getInventory().containsItem(ROPE)) { + interpreter.sendDialogues(npc, null, "You have the rope I see, to tie up Keli. That will be the", "most dangerous part of the plan."); + stage = 16; + } else { + interpreter.sendDialogues(npc, null, "You will still need some rope to tie up Keli, of course. I", "heard that there's a good rope maker around here."); + stage = 16; + } + break; + case 16: + end(); + break; + case 20: + interpreter.sendDialogues(npc, null, "Yes, that is most important. There is no way you can", "get the real key. It is on a chain around Keli's neck.", "Almost impossible to steal."); + stage = 21; + break; + case 21: + interpreter.sendDialogues(npc, null, "Get some soft clay and get her to show you the key", "somehow. Then take the print, with bronze, to my", "father."); + stage = 22; + break; + case 22: + end(); + break; + case 30: + interpreter.sendDialogues(npc, null, "most of the guards will be easy. The disguise will get", "past them. The only guards who will be a problem will be", "the one at the door."); + stage = 31; + break; + case 31: + end(); + break; + case 40: + interpreter.sendDialogues(npc, null, "Good, I shall await your return with everything."); + stage = 41; + break; + case 41: + end(); + break; + } + break; + default: + switch (stage) { + case 0: + interpreter.sendDialogues(npc, null, "Please leave me alone adventurer, I am", "a very busy woman."); + stage = 1; + break; + case 1: + end(); + break; + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 915 }; + } +} diff --git a/Server/src/main/content/region/misthalin/draynor/dialogue/MartinTheMasterGardener.java b/Server/src/main/content/region/misthalin/draynor/dialogue/MartinTheMasterGardener.java new file mode 100644 index 0000000..b3646c2 --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/dialogue/MartinTheMasterGardener.java @@ -0,0 +1,112 @@ +package content.region.misthalin.draynor.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.global.Skillcape; +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; + +/** + * Represents the dialogue plugin used for marti the master gardener. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class MartinTheMasterGardener extends DialoguePlugin { + + /** + * Constructs a new {@code MartinTheMasterGardener} {@code Object}. + */ + public MartinTheMasterGardener() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code MartinTheMasterGardener} {@code Object}. + * @param player the player. + */ + public MartinTheMasterGardener(Player player) { + super(player); + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What is that cape that you're wearing?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I can't chat now, I have too many things to worry", "about."); + stage = 20; + break; + } + break; + case 20: + end(); + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "This is a Skillcape of Farming, isn't it incredbile? It's a", "symbol of my ability as the finest farmer in the land!"); + stage = 11; + break; + case 11: + if (player.getSkills().getStaticLevel(Skills.FARMING) == 99) { + npc("Ah! I see you have mastered the skill of Farming,", "would you like to purchase a Farming cape for", "a fee of 99000 coins?"); + stage = 12; + } else { + end(); + } + break; + case 12: + options("Yes, please.", "No, thanks."); + stage = 13; + break; + case 13: + switch (buttonId) { + case 1: + player("Yes, please."); + stage = 14; + break; + case 2: + end(); + break; + } + break; + case 14: + if (Skillcape.purchase(player, Skills.FARMING)) { + npc("Have fun with it."); + stage = 15; + } + stage = 15; + break; + case 15: + end(); + break; + } + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new MartinTheMasterGardener(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendOptions("Select an Option", "Skillcape of Farming", "Quest."); + stage = 0; + return true; + } + + @Override + public int[] getIds() { + return new int[] { 3299 }; + } +} diff --git a/Server/src/main/content/region/misthalin/draynor/dialogue/MissSchismDialogue.java b/Server/src/main/content/region/misthalin/draynor/dialogue/MissSchismDialogue.java new file mode 100644 index 0000000..afa313c --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/dialogue/MissSchismDialogue.java @@ -0,0 +1,193 @@ +package content.region.misthalin.draynor.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; +import content.data.Quests; + +/** + * Represents the miss schism dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class MissSchismDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code MissSchismDialogue} {@code Object}. + */ + public MissSchismDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code MissSchismDialogue} {@code Object}. + * @param player the player. + */ + public MissSchismDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new MissSchismDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Oooh, my dear, have you heard the news?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("What would you like to say?", "Ok, tell me about the news.", "Who are you?", "I'm not talking to you, you horrible woman."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Ok, tell me about the news."); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Who are you?"); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'm not talking to you, you horrible woman."); + stage = 30; + break; + } + + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Well, there's just to much to tell at once! What would", "you like to hear first: the vampire or the bank?"); + stage = 11; + break; + case 11: + interpreter.sendOptions("Select an Option", "Tell me about the vampire.", "Tell me about the bank."); + stage = 12; + break; + case 12: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Tell me about the vampire."); + stage = 110; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What about the bank?"); + stage = 210; + break; + } + + break; + case 110: + if (player.getQuestRepository().isComplete(Quests.VAMPIRE_SLAYER)) { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Well, there's nothing to tell NOW. You killed it."); + stage = 111; + } else { + npc("There is an evil Vampire terrorizing the city!"); + stage = 119; + } + break; + case 111: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "You could sound a little grateful."); + stage = 112; + break; + case 112: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I'm sure I could, but I don't see why. The vampire wasn't", "bothering me."); + stage = 113; + break; + case 113: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "..."); + stage = 114; + break; + case 114: + end(); + break; + case 119: + player("Oh, that's not good."); + stage = 120; + break; + case 120: + end(); + break; + case 210: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "It's terrible, absolutely terrible! Those poor people!"); + stage = 211; + break; + case 211: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Ok, yeah."); + stage = 212; + break; + case 212: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "And who'd have ever thought such a sweet old gentleman", "would do such a thing?"); + stage = 213; + break; + case 213: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Are we talking about the bank robbery?"); + stage = 214; + break; + case 214: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Oh yes, my dear. It was terrible! TERRIBLE!"); + stage = 215; + break; + case 215: + end(); + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I, my dear, am a concerned citizen of Draynor Village.", "Ever since the Council allowed those farmers to set up", "their stalls here, we've had a constant flow of thieves and", "murderers through our fair village, and I decided that"); + stage = 21; + break; + case 21: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "someone HAD to stand up and", "keep an eye on the situation."); + stage = 22; + break; + case 22: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I also do voluntary work for the Draynor Manor", "Restoration Fund. We're campaigning to have", "Draynor manor turned into a museum before the wet-rot", "destroys it completely."); + stage = 23; + break; + case 23: + if(player.getQuestRepository().isComplete(Quests.VAMPIRE_SLAYER)) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Well, now that I've cleared the vampire out of the manor,", "I guess you won't have too much trouble turning it into a", "museum."); + stage = 24; + } else { + end(); + } + break; + case 24: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "That's all very well dear, but no vampire was ever going to", "stop me making it a museum."); + stage = 25; + break; + case 25: + end(); + break; + case 30: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Oooh."); + stage = 31; + break; + case 31: + end(); + break; + } + + return true; + } + + @Override + public int[] getIds() { + return new int[] { 2634 }; + } +} +/** + * Fixed Vexia's crappy English in some sentences + */ \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/draynor/dialogue/MorganDialogue.java b/Server/src/main/content/region/misthalin/draynor/dialogue/MorganDialogue.java new file mode 100644 index 0000000..e7d150c --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/dialogue/MorganDialogue.java @@ -0,0 +1,147 @@ +package content.region.misthalin.draynor.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.game.node.entity.player.link.quest.Quest; +import content.data.Quests; + +/** + * Represents the dialogue plugin used for the morgan npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class MorganDialogue extends DialoguePlugin { + + /** + * Represents the quest instance. + */ + private Quest quest; + + /** + * Constructs a new {@code MorganDialogue} {@code Object}. + */ + public MorganDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code MorganDialogue} {@code Object}. + * @param player the player. + */ + public MorganDialogue(Player player) { + super(player); + } + + @Override + public boolean open(Object... args) { + quest = player.getQuestRepository().getQuest(Quests.VAMPIRE_SLAYER); + npc = (NPC) args[0]; + quest = player.getQuestRepository().getQuest(Quests.VAMPIRE_SLAYER); + if (quest.getStage(player) == 0) { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Please please help us, bold adventurer!"); + stage = 0; + } + switch (quest.getStage(player)) { + case 10: + case 20: + case 30: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "How are you doing with the quest?"); + stage = 10; + break; + case 100: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I have slain the foul creature!"); + stage = 101; + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What's the problem?"); + stage = 1; + break; + case 1: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Our little village has been dreadfully ravaged by an evil", "vampire! He lives in the basement of the manor to the", "north, we need someone to get rid of him once and for", "all!"); + stage = 2; + break; + case 2: + interpreter.sendOptions("Select an Option", "No, vampires are scary!", "Ok, I'm up for an adventure.", "Have you got any tips on killing the vampire?"); + stage = 7; + break; + case 7: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No, vampires are scary!"); + stage = 8; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Ok, I'm up for an adventure."); + stage = 3; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Have you got any tips on killing the vampire?"); + stage = 3; + break; + } + break; + case 3: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I think first you should seek help. I have a friend who", "is a retired vampire hunter, his name is Dr. Harlow. He", "may be able to give you some tips. He can normally be", "found in the Blue Moon Inn in Varrock, he's a bit of"); + stage = 4; + break; + case 4: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "an old soak these days. Mention his old friend Morgan,", "I'm sure he wouldn't want me killed by a vampire."); + stage = 5; + break; + case 5: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'll look him up then."); + stage = 6; + break; + case 6: + quest.start(player); + player.getQuestRepository().syncronizeTab(player); + end(); + break; + case 8: + end(); + break; + case 10: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'm still working on it."); + stage = 11; + break; + case 11: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Please hurry! Every day we live in fear that we", "the vampire's next victim!"); + stage = 12; + break; + case 12: + end(); + break; + case 101: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Thank you, thank you! You will always be a hero in", "our village!"); + stage = 102; + break; + case 102: + end(); + break; + } + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new MorganDialogue(player); + } + + @Override + public int[] getIds() { + return new int[] { 755 }; + } +} diff --git a/Server/src/main/content/region/misthalin/draynor/dialogue/OliviaDialogue.java b/Server/src/main/content/region/misthalin/draynor/dialogue/OliviaDialogue.java new file mode 100644 index 0000000..4f53b99 --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/dialogue/OliviaDialogue.java @@ -0,0 +1,80 @@ +package content.region.misthalin.draynor.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Handles the OliviaDialogue dialogue. + * @author 'Vexia + */ +@Initializable +public class OliviaDialogue extends DialoguePlugin { + + public OliviaDialogue() { + + } + + public OliviaDialogue(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[] { 2233, 2572 }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "Yes", "No", "Where do I get rarer seeds from?"); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + end(); + npc.openShop(player); + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "No, thanks."); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.ASKING, "Where do I get rarer seeds from?"); + stage = 40; + break; + + } + break; + case 20: + end(); + break; + case 40: + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "The Master Farmers usually carry a few rare seeds", "around with them, although I don't know if they'd want", "to part with them for any price to be honest."); + stage = 41; + break; + case 41: + end(); + break; + } + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new OliviaDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Would you like to trade in seeds?"); + stage = 0; + return true; + } +} diff --git a/Server/src/main/content/region/misthalin/draynor/dialogue/PrinceAliDialogue.java b/Server/src/main/content/region/misthalin/draynor/dialogue/PrinceAliDialogue.java new file mode 100644 index 0000000..cb13ff9 --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/dialogue/PrinceAliDialogue.java @@ -0,0 +1,149 @@ +package content.region.misthalin.draynor.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.plugin.Initializable; +import core.game.world.GameWorld; +import content.data.Quests; + +/** + * Represents the dialogue used to handle the Pricne Ali NPC. + * @author 'Vexia + * @date 1/14/1/ + */ +@Initializable +public class PrinceAliDialogue extends DialoguePlugin { + + /** + * Represents the array of disguised items. + */ + private static final Item[] DISGUISE = new Item[] { new Item(2424), new Item(2419), new Item(2418), new Item(1013) }; + + /** + * Represents the quest instance. + */ + private Quest quest; + + /** + * Constructs a new {@code PrinceAliDialogue} {@code Object}. + */ + public PrinceAliDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code PrinceAliDialogue} {@code Object}. + * @param player the player. + */ + public PrinceAliDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new PrinceAliDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + quest = player.getQuestRepository().getQuest(Quests.PRINCE_ALI_RESCUE); + switch (quest.getStage(player)) { + case 50: + interpreter.sendDialogues(player, null, "Prince, I come to rescue you."); + stage = 0; + break; + case 60: + case 100: + interpreter.sendDialogues(npc, null, "I owe you my life for that escape. You cannot help me", "this time, they know who you are. Go in peace, friend", "of Al-Kharid"); + stage = 100; + break; + default: + end(); + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 100: + end(); + break; + case 0: + interpreter.sendDialogues(npc, null, "That is very kind of you, how do I get out?"); + stage = 1; + break; + case 1: + interpreter.sendDialogues(player, null, "With a disguise. I have removed the Lady Keli. She is", "tied up, but will not stay tied up for long."); + stage = 2; + break; + case 2: + interpreter.sendDialogues(player, null, "Take this disguise, and this key."); + stage = 3; + break; + case 3: + for (Item i : DISGUISE) { + if (!player.getInventory().containsItem(i)) { + player.getPacketDispatch().sendMessage("You don't have all the parts of the disguise."); + end(); + return true; + } + } + if (player.getInventory().remove(DISGUISE)) { + interpreter.sendDialogue("You hand the disguise and the key to the prince."); + stage = 4; + quest.setStage(player, 60); + player.removeAttribute("guard-drunk"); + player.getGameAttributes().removeAttribute("guard-drunk"); + } + break; + case 4: + // NPC 921 start dialogue.921 + npc.transform(921); + GameWorld.getPulser().submit(new Pulse(50) { + @Override + public boolean pulse() { + npc.transform(920); + return true; + } + }); + interpreter.sendDialogues(npc, null, "Thank you my friend, I must leave you now. My", "father will pay you well for this."); + stage = 5; + break; + case 5: + interpreter.sendDialogues(player, null, "Go to Leela, she is close to here."); + stage = 6; + break; + case 6: + npc.setInvisible(true); + GameWorld.getPulser().submit(new Pulse(20) { + @Override + public boolean pulse() { + npc.transform(920); + npc.setInvisible(false); + return true; + } + }); + interpreter.sendDialogue("The prince has escaped, well done! You are now a friend of Al-", "Kharid and may pass through the Al-Kharid toll gate for free."); + stage = 7; + break; + case 7: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 920 }; + } +} diff --git a/Server/src/main/content/region/misthalin/draynor/dialogue/ProfessorOddensteinPlugin.java b/Server/src/main/content/region/misthalin/draynor/dialogue/ProfessorOddensteinPlugin.java new file mode 100644 index 0000000..b90bdc3 --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/dialogue/ProfessorOddensteinPlugin.java @@ -0,0 +1,310 @@ +package content.region.misthalin.draynor.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.repository.Repository; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.game.world.update.flag.context.Graphics; +import content.data.Quests; + +/** + * Represents the plugin dialogue to handle the interaction with professor + * oddenstein. + * @author 'Vexia + */ +@Initializable +public class ProfessorOddensteinPlugin extends DialoguePlugin { + + /** + * Represents the oil can item. + */ + private static final Item OIL_CAN = new Item(277); + + /** + * Represents the pressure guage item. + */ + private static final Item PRESSURE_GAUGE = new Item(271); + + /** + * Represents the rubber tube item. + */ + private static final Item RUBBER_TUBE = new Item(276); + + /** + * Represents the animation for professor to use. + */ + private static final Animation ANIMATION = new Animation(832); + + /** + * Represents the face location. + */ + private static final Location FACE_LOCATION = Location.create(3112, 3367, 2); + + /** + * The start graphic for spell. + */ + private static final Graphics WEAKEN_START = new Graphics(105, 96); + + /** + * The end graphic for the spell. + */ + private static final Graphics WEAKEN_END = new Graphics(107, 96); + + /** + * Constructs a new {@code ProfessorOddensteinPlugin} {@code Object}. + */ + public ProfessorOddensteinPlugin() { + + } + + /** + * Constructs a new {@code ProfessorOddensteinPlugin} {@code Object}. + * @param player the player. + */ + public ProfessorOddensteinPlugin(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new ProfessorOddensteinPlugin(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + final Quest quest = player.getQuestRepository().getQuest(Quests.ERNEST_THE_CHICKEN); + switch (quest.getStage(player)) { + case 0: + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Be careful in here, there's lots of dangerous equipment."); + stage = 0; + break; + case 20: + interpreter.sendDialogues(npc, null, "Have you found everything yet?"); + stage = 0; + break; + case 100: + interpreter.sendOptions("Select an Option", "What does this machine do?", "Is this your house?"); + stage = 1; + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + final Quest quest = player.getQuestRepository().getQuest(Quests.ERNEST_THE_CHICKEN); + switch (quest.getStage(player)) { + case 0: + case 100: + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "What does this machine do?", "Is this your house?"); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What does this machine do?"); + stage = 11; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Is this your house?"); + stage = 20; + break; + } + break; + case 11: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Nothing at the moment... It's broken. It's meant to be", "a transmutation machine."); + stage = 12; + break; + case 12: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "It as also spent time as a time travel machine, and a", "dramatic light generator, and a thing for generating", "monsters."); + stage = 13; + break; + case 13: + end(); + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "No, I'm just one of the tenants. It belongs to the count", "who lives in the basement."); + stage = 21; + break; + case 21: + end(); + break; + } + break; + case 10: + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "I'm looking for a guy called Ernest.", "What does this machine do?", "Is this your house?"); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, null, "I'm looking for a guy called Ernest."); + stage = 2; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What does this machine do?"); + stage = 11; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Is this your house?"); + stage = 20; + break; + } + break; + case 2: + interpreter.sendDialogues(npc, null, "Ah Ernest, top notch bloke. He's helping me with my", "experiments."); + stage = 3; + break; + case 3: + interpreter.sendDialogues(player, null, "So you know where he is then?"); + stage = 4; + break; + case 4: + interpreter.sendDialogues(npc, null, "He's that chicken over there."); + stage = 5; + break; + case 5: + interpreter.sendDialogues(player, null, "Ernest is a chicken..? Are you sure..?"); + stage = 6; + break; + case 6: + interpreter.sendDialogues(npc, null, "Oh, he isn't normally a chicken, or at least he wasn't", "until he helped me test my pouletmorph machine."); + stage = 7; + break; + case 7: + interpreter.sendDialogues(npc, null, "It was originally going to be called a transmutation", "machine. But after testing pouletmorph seems more", "appropriate."); + stage = 8; + break; + case 8: + interpreter.sendDialogues(player, null, "I'm glad Veronica didn't actually get engaged to a", "chicken."); + stage = 9; + break; + case 9: + interpreter.sendDialogues(npc, null, "Who's Veronica?"); + stage = 10; + break; + case 10: + interpreter.sendDialogues(player, null, "Ernest's fiancee. She probably doesn't want to marry a", "chicken."); + stage = 11; + break; + case 11: + interpreter.sendDialogues(npc, null, "Ooh I dunno. She could have free eggs for breakfast."); + stage = 12; + break; + case 12: + interpreter.sendDialogues(player, null, "I think you'd better change him back."); + stage = 13; + break; + case 13: + interpreter.sendDialogues(npc, null, "Umm... It's not so easy..."); + stage = 14; + break; + case 14: + interpreter.sendDialogues(npc, null, "My machine is broken, and the house gremlins have", "run off with some vital bits."); + stage = 15; + break; + case 15: + interpreter.sendDialogues(player, null, "Well I can look for them."); + stage = 16; + break; + case 16: + interpreter.sendDialogues(npc, null, "That would be a help. They'll be somewhere in the", "manor house or its grounds, the gremlins never get", "further than the entrance gate."); + stage = 17; + break; + case 17: + interpreter.sendDialogues(npc, null, "I'm missing the pressure guage and a rubber tube.", "They've also taken my oil can, which I'm going to need", "to get this thing started again."); + stage = 18; + break; + case 18: + quest.setStage(player, 20); + end(); + break; + } + break; + case 20: + switch (stage) { + case 0: + if (player.getInventory().containsItem(OIL_CAN) && player.getInventory().containsItem(PRESSURE_GAUGE) && player.getInventory().containsItem(RUBBER_TUBE)) { + interpreter.sendDialogues(player, null, "I have everything!"); + stage = 3; + } else { + interpreter.sendDialogues(player, null, "I'm afraid I'm still looking for them!"); + stage = 1; + } + break; + case 1: + interpreter.sendDialogues(npc, null, "I need a rubber tube, a pressure gauge and a can of", "oil. Then your friend can stop being a chicken."); + stage = 2; + break; + case 2: + end(); + break; + case 3: + interpreter.sendDialogues(npc, null, "Give 'em here then."); + stage = 4; + break; + case 4: + end(); + player.lock(); + player.getPacketDispatch().sendMessage("You give a rubber tube, a pressure gauge,"); + player.getPacketDispatch().sendMessage("and a can of oil to the professor."); + player.getPacketDispatch().sendMessage("Oddenstein starts up the machine."); + final NPC chicken = Repository.findNPC(288); + GameWorld.getPulser().submit(new Pulse(1, player) { + int counter = 0; + + @Override + public boolean pulse() { + switch (counter++) { + case 1: + npc.animate(ANIMATION); + npc.faceLocation(FACE_LOCATION); + break; + case 2: + player.getPacketDispatch().sendMessage("The machine hums and shakes."); + npc.graphics(WEAKEN_START); + Projectile.create(npc, chicken, 106, 40, 36, 52, 75, 15, 11); + break; + case 4: + NPC ernest = NPC.create(287, chicken.getLocation()); + ernest.setAttribute("target", player); + ernest.init(); + player.setAttribute("ernest-hide", true); + if (player.getInventory().remove(OIL_CAN, PRESSURE_GAUGE, RUBBER_TUBE)) { + player.getDialogueInterpreter().open(287, ernest); + } + break; + case 5: + npc.graphics(WEAKEN_END); + return true; + } + return false; + } + }); + break; + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 286 }; + } +} diff --git a/Server/src/main/content/region/misthalin/draynor/dialogue/StrangeBook.kt b/Server/src/main/content/region/misthalin/draynor/dialogue/StrangeBook.kt new file mode 100644 index 0000000..3def67c --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/dialogue/StrangeBook.kt @@ -0,0 +1,247 @@ +package content.region.misthalin.draynor.dialogue + +import content.global.handlers.iface.BookInterface +import content.global.handlers.iface.BookLine +import content.global.handlers.iface.Page +import content.global.handlers.iface.PageSet +import core.api.setAttribute +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import org.rs09.consts.Items + +class StrangeBook : InteractionListener { + + // The strange book is a book found on the bookshelves in the Wise Old Man's. + companion object { + private val TITLE = "Stange book" + private val CONTENTS = arrayOf( + PageSet( + Page( + BookLine("Perception and Reality", 55), + BookLine("... which leads us to the", 56), + BookLine("new definition of knowledge", 57), + BookLine("as a belief that is both", 58), + BookLine("reliably generated and true.", 59), + BookLine("Our senses tell us about", 61), + BookLine("the world, but to what", 62), + BookLine("extent are they reliable?", 63), + BookLine("One witness may perceive", 64), + BookLine("the weather to be hot,", 65), + ), + Page( + BookLine("but another witness may", 66), + BookLine("consider it to be quite", 67), + BookLine("cold.", 68), + BookLine("Perception of colour may", 70), + BookLine("be similarly affected, as", 71), + BookLine("the reader may demonstrate", 72), + BookLine("by staring at a piece of", 73), + BookLine("brightly-coloured paper.", 74), + BookLine("When the paper is removed,", 75), + BookLine("the reader may find that", 76), + ) + ), + PageSet( + Page( + BookLine("everything else appears", 55), + BookLine("to be a slightly different", 56), + BookLine("colour from normal.", 57), + BookLine("We may conclude from this", 59), + BookLine("that, although we are", 60), + BookLine("sensing some intrinsic", 61), + BookLine("property of the object", 62), + BookLine("under examination,", 63), + BookLine("qualities such as colour", 64), + BookLine("and temperature are NOT", 65), + ), + Page( + BookLine("intrinsic.", 66), + BookLine("Henceforth we recommend", 68), + BookLine("that the reader consider", 69), + BookLine("them to be Secondary", 70), + BookLine("qualities. The quantity", 71), + BookLine("of caloric within the", 72), + BookLine("object that gives it this", 73), + BookLine("perceived temperature", 74), + BookLine("truly is intrinsic to", 75), + BookLine("the object, so this may", 76), + ) + ), + PageSet( + Page( + BookLine("be considered a Primary", 55), + BookLine("quality.", 56), + BookLine("In the following chapter", 58), + BookLine("we will examine the", 59), + BookLine("implications of this", 60), + BookLine("distinction for the study", 61), + BookLine("of natural philosophy.", 62), + BookLine("Certainty and Assumption", 65), + ), + Page( + BookLine("In this chapter we aim", 66), + BookLine("to examine the extent to", 67), + BookLine("which our senses give", 68), + BookLine("us a reliable impression", 69), + BookLine("of the world in which", 70), + BookLine("we live.", 71), + BookLine("Although we may believe", 73), + BookLine("that we are seeing and", 74), + BookLine("hearing things that exist,", 75), + BookLine("we may be deceived by", 76), + ) + ), + PageSet( + Page( + BookLine("our senses, as every", 55), + BookLine("keen drinker will have", 56), + BookLine("experienced! But if our", 57), + BookLine("senses may be deceived,", 58), + BookLine("what can we trust?", 59), + BookLine("We may perhaps try to", 61), + BookLine("rely only on logical", 62), + BookLine("deductions and mathematical", 63), + BookLine("principles. Yet it is", 64), + BookLine("even possible that some", 65), + ), + Page( + BookLine("fiend may have confused", 66), + BookLine("our minds to the extent", 67), + BookLine("that we are making false", 68), + BookLine("deductions without being", 69), + BookLine("aware of this.", 70), + BookLine("We therefore present the", 72), + BookLine("following statement as", 73), + BookLine("the only piece of knowledge", 74), + BookLine("about which we cannot", 75), + BookLine("possibly be deceived:", 76), + ) + ), + PageSet( + Page( + BookLine("'I EXIST'", 55), + BookLine("Although all information", 57), + BookLine("gained through use of our", 58), + BookLine("senses and minds may be", 59), + BookLine("distorted, no self-aware", 60), + BookLine("being can be led to", 61), + BookLine("believe that it does not", 62), + BookLine("exist. It may not be the", 63), + BookLine("man or woman it believes", 64), + BookLine("itself to be, but it can", 65), + ), + Page( + BookLine("never question its own", 66), + BookLine("existence in some form.", 67), + BookLine("In the following chapter", 69), + BookLine("we will discuss ways in", 70), + BookLine("which one may attempt to", 71), + BookLine("demonstrate the existence", 72), + BookLine("of a world outside of one's", 73), + BookLine("own consciousness.", 74), + BookLine("Graphical solution of", 76), + ) + ), + PageSet( + Page( + BookLine("mathematical problems", 55), + BookLine("A simple graph containing", 57), + BookLine("an x-axis and a y-axis may", 58), + BookLine("be used to represent", 59), + BookLine("equations similar to the", 60), + BookLine("following: x + 3y = 5", 61), + BookLine("For every 'x' and 'y' that", 63), + BookLine("satisfy the equation", 64), + BookLine("(such as x = 2, y = 1 or", 65), + ), + Page( + BookLine("x = 5, y = 0 for the", 66), + BookLine("above example), the points", 67), + BookLine("'x,y' may be plotted on", 68), + BookLine("the graph, and it will be", 69), + BookLine("found that they form a line.", 70), + BookLine("If a second equation of", 72), + BookLine("this form is plotted on", 73), + BookLine("the same graph, the two", 74), + BookLine("lines may cross at some", 75), + BookLine("point.", 76), + ) + ), + PageSet( + Page( + BookLine("Any point where the two", 55), + BookLine("lines cross will be given", 56), + BookLine("by some 'x' and 'y'", 57), + BookLine("that fits both equations.", 58), + BookLine("Readers are invited to", 60), + BookLine("create two such equations", 61), + BookLine("and try it for themselves!", 62), + BookLine("Readers' Comments", 64), + ), + Page( + BookLine("This page left blank for", 67), + BookLine("readers' comments", 68), + BookLine("... better now, walls look", 70), + BookLine("decent, nice and elegant.", 71), + BookLine("Those new lanterns were a", 72), + BookLine("rip-off, blasted dwarf", 73), + BookLine("craftsmen. Still, not a", 74), + BookLine("problem for me!", 75), + ) + ), + PageSet( + Page( + BookLine("Even got my old Saradomin", 55), + BookLine("armour gilded, beautiful", 56), + BookLine("gold edges on it now. No-one", 57), + BookLine("else's going to have armour", 58), + BookLine("like that, that'll make", 59), + BookLine("them think, heh heh heh...", 60), + BookLine("Lick of gold-leaf here and", 62), + BookLine("there, even my globe looks", 63), + BookLine("smarter now, maybe that", 64), + BookLine("bath screen was a bit much?", 65), + ), + Page( + BookLine("No, I saw it, I wanted it,", 66), + BookLine("it's mine.", 67), + BookLine("Vidi, volui, mihi est!", 68), + BookLine("Still don't know what that", 70), + BookLine("'thing' is, but it looks nice", 71), + BookLine("on my desk. Probably some", 72), + BookLine("kind of transport? Must run", 73), + BookLine("off hot air or dragon", 74), + BookLine("flatulence? Running a", 76), + ) + ), + PageSet( + Page( + BookLine("bit short of runes now.", 55), + BookLine("Those wizards over to", 56), + BookLine("the south always seem to", 57), + BookLine("have plenty, but will they", 58), + BookLine("spare me some? Bah! Not", 59), + BookLine("a chance, poxy mage scum!", 61), + BookLine("Perhaps another little expedition", 62), + BookLine("is needed - they all", 63), + BookLine("look pretty weedy over there...", 64), + ) + ), + ) + } + + private fun display(player: Player, pageNum: Int, buttonID: Int): Boolean { + BookInterface.pageSetup( + player, BookInterface.FANCY_BOOK_3_49, TITLE, CONTENTS + ) + return true + } + + override fun defineListeners() { + on(Items.STRANGE_BOOK_5507, IntType.ITEM, "read") { player, _ -> + BookInterface.openBook(player, BookInterface.FANCY_BOOK_3_49, ::display) + return@on true + } + } +} diff --git a/Server/src/main/content/region/misthalin/draynor/dialogue/VeronicaDialogue.java b/Server/src/main/content/region/misthalin/draynor/dialogue/VeronicaDialogue.java new file mode 100644 index 0000000..3480ca1 --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/dialogue/VeronicaDialogue.java @@ -0,0 +1,194 @@ +package content.region.misthalin.draynor.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.game.node.entity.player.link.quest.Quest; +import content.data.Quests; + +/** + * Represents the dialogue used to handle the interaction between veronica. + * @author 'Vexia + * @date 24/12/2013 + */ +@Initializable +public class VeronicaDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code VeronicaDialogue} {@code Object}. + */ + public VeronicaDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code VeronicaDialogue} {@code Object}. + * @param player the player. + */ + public VeronicaDialogue(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[] { 285 }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + final Quest quest = player.getQuestRepository().getQuest(Quests.ERNEST_THE_CHICKEN); + switch (quest.getStage(player)) { + case 0: + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "Aha, sounds like a quest. I'll help.", "No, I'm looking for something to kill."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, null, "Aha, sounds like a quest. I'll help."); + stage = 4; + break; + case 2: + interpreter.sendDialogues(player, null, "No, I'm looking for something to kill."); + stage = 2; + break; + } + break; + case 2: + interpreter.sendDialogues(npc, null, "Oooh, you violent person you."); + stage = 3; + break; + case 3: + end(); + break; + case 4: + interpreter.sendDialogues(npc, null, "Yes yes, I suppose it is a quest. My fiance Ernest and", "I came upon this house."); + stage = 5; + break; + case 5: + interpreter.sendDialogues(npc, null, "Seeing as we were a little lost Ernest decided to go in", "and ask for direction."); + stage = 6; + break; + case 6: + interpreter.sendDialogues(npc, null, "That was an hour ago. That house looks spooky, can", "you go and see if you can find him for me?"); + stage = 7; + break; + case 7: + interpreter.sendDialogues(player, null, "Ok, I'll see what I can do."); + stage = 8; + break; + case 8: + quest.start(player); + player.getQuestRepository().syncronizeTab(player); + interpreter.sendDialogues(npc, null, "Thank you, thank you. I'm very grateful."); + stage = 9; + break; + case 9: + end(); + break; + } + break; + case 10: + switch (stage) { + case 9: + end(); + break; + case 0: + interpreter.sendDialogues(player, null, "No, not yet."); + stage = 1; + break; + case 1: + end(); + break; + } + break; + case 20: + switch (stage) { + case 0: + interpreter.sendDialogues(player, null, "Yes, he's a chicken."); + stage = 1; + break; + case 1: + interpreter.sendDialogues(npc, null, "I know he's not exactly brave but I think you're being", "a bit harsh."); + stage = 2; + break; + case 2: + interpreter.sendDialogues(player, null, "No no, he's been turned into an actual chicken by a", "mad scientist."); + stage = 3; + break; + case 3: + interpreter.sendDialogues(npc, null, "Eeeeeek!"); + stage = 4; + break; + case 4: + interpreter.sendDialogues(npc, null, "My poor darling, why must these things happen to us."); + stage = 5; + break; + case 5: + interpreter.sendDialogues(player, null, "Well I'm doing my best to turn him back."); + stage = 6; + break; + case 6: + interpreter.sendDialogues(npc, null, "Well be quick, I'm sure being a chicken can't be good", "for him."); + stage = 7; + break; + case 7: + end(); + break; + } + break; + case 100: + switch (stage) { + case 0: + interpreter.sendDialogues(player, null, "Where is he now?"); + stage = 1; + break; + case 1: + interpreter.sendDialogues(npc, null, "Oh he went off to talk to some green warty guy. I'm", "sure he'll be back soon."); + stage = 2; + break; + case 2: + end(); + break; + } + break; + } + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new VeronicaDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + final Quest quest = player.getQuestRepository().getQuest(Quests.ERNEST_THE_CHICKEN); + switch (quest.getStage(player)) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Can you please help me? I'm in a terrible spot of", "trouble."); + stage = 0; + break; + case 10: + interpreter.sendDialogues(npc, null, "Have you foudn my sweetheart yet?"); + stage = 0; + break; + case 20: + interpreter.sendDialogues(npc, null, "Have you foudn my sweetheart yet?"); + stage = 0; + break; + case 100: + interpreter.sendDialogues(npc, null, "Thank you for resucing Ernest."); + stage = 0; + break; + } + return true; + } +} diff --git a/Server/src/main/content/region/misthalin/draynor/dialogue/WiseOldManDialogue.java b/Server/src/main/content/region/misthalin/draynor/dialogue/WiseOldManDialogue.java new file mode 100644 index 0000000..d6c82d5 --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/dialogue/WiseOldManDialogue.java @@ -0,0 +1,241 @@ +package content.region.misthalin.draynor.dialogue; + +import core.api.Container; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.plugin.Initializable; +import core.game.node.item.Item; +import org.rs09.consts.Items; + +import static core.api.ContentAPIKt.*; + +/** + * Represents the dialogue plugin used for the wise old man. + * + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class WiseOldManDialogue extends DialoguePlugin { + + /** + * Represents the items to use. + */ + private static final Item[] ITEMS = new Item[]{new Item(9813), new Item(9814)}; + + /** + * Represents the coins item. + */ + private static final Item COINS = new Item(995, 99000); + + /** + * Represents the unique books item. + */ + + private static final Item[] UNIQUE_BOOKS = new Item[]{ new Item(5507), new Item(5508), new Item(7464)}; + + + /** + * Constructs a new {@code WiseOldManDialogue} {@code Object}. + */ + public WiseOldManDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code WiseOldManDialogue} {@code Object}. + * + * @param player the player. + */ + public WiseOldManDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new WiseOldManDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + npc("Greetings, " + player.getUsername() + ","); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + if (getAttribute(player, "reclaim-qp-cape", false) || getAttribute(player, "reclaim-qp-hood", false)) { + if (getAttribute(player, "reclaim-qp-cape", false) && getAttribute(player, "reclaim-qp-hood", false)) { + npcl(FacialExpression.NEUTRAL, "I assume you're looking for your items? I've placed them " + (freeSlots(player) < 2 ? "at your feet." : "in your inventory.")); + removeAttribute(player, "reclaim-qp-cape"); + removeAttribute(player, "reclaim-qp-hood"); + addItemOrDrop(player, Items.QUEST_POINT_CAPE_9813, 1); + addItemOrDrop(player, Items.QUEST_POINT_HOOD_9814, 1); + stage = 505; + return true; + } else if (getAttribute(player, "reclaim-qp-cape", false)) { + npcl(FacialExpression.NEUTRAL, "I assume you're looking for your Quest Point Cape? I've placed it " + (freeSlots(player) < 1 ? "at your feet." : "in your inventory.")); + removeAttribute(player, "reclaim-qp-cape"); + addItemOrDrop(player, Items.QUEST_POINT_CAPE_9813, 1); + stage = 505; + return true; + } else { + npcl(FacialExpression.NEUTRAL, "I assume you're looking for your Quest Point Hood? I've placed it " + (freeSlots(player) < 1 ? "at your feet." : "in your inventory.")); + removeAttribute(player, "reclaim-qp-hood"); + addItemOrDrop(player, Items.QUEST_POINT_HOOD_9814, 1); + stage = 505; + return true; + } + } + if (player.getQuestRepository().hasCompletedAll()) { + options("Quest Point Cape.", "Something else."); + stage = 500; + return true; + } + options("Is there anything I can do for you?", "Could you check my things for junk, please?", "I've got something I'd like you to look at."); + stage = 1; + break; + case 500: + switch (buttonId) { + case 1: + player("I believe you are the person to talk to if I want to buy", "a Quest Point Cape?"); + stage = 501; + break; + case 2: + options("Is there anything I can do for you?", "Could you check my things for junk, please?", "I've got something I'd like you to look at."); + stage = 1; + break; + } + break; + case 501: + npc("Indeed you believe rightly, " + player.getUsername() + ", and if you know that", "then you'll also know that they cost 99000 coins."); + stage = 502; + break; + case 502: + options("No, I hadn't heard that!", "Yes, so I was lead to believe."); + stage = 503; + break; + case 503: + switch (buttonId) { + case 1: + player("No, I hadn't heard that!"); + stage = 504; + break; + case 2: + player("Yes, so I was lead to believe."); + stage = 506; + break; + } + break; + case 504: + npc("Well that's the cost, and it's not changing."); + stage = 505; + break; + case 505: + end(); + break; + case 506: + if (player.getInventory().freeSlots() < 2) { + player("I don't seem to have enough inventory space."); + stage = 507; + return true; + } + if (!player.getInventory().containsItem(COINS)) { + player("I don't seem to have enough coins with", "me at this time."); + stage = 507; + return true; + } + if (player.getInventory().remove(COINS) && player.getInventory().add(ITEMS)) { + npc("Have fun with it."); + stage = 507; + } else { + player("I don't seem to have enough coins with", "me at this time."); + stage = 507; + } + break; + case 507: + end(); + break; + case 1: + switch (buttonId) { + case 1: + player("Is there anything I can do for you?"); + stage = 10; + break; + case 2: + options("Could you check my bank for junk, please?", "Could you check my inventory for junk, please?"); + stage = 20; + break; + case 3: + player("I've got something I'd like you to look at."); + stage = 30; + break; + } + + break; + case 10: + npc("Thanks, but I don't have anything I need."); + stage = 11; + break; + case 11: + end(); + break; + case 20: + npc("Certainly, but I should warn you that I don't know about", "all items."); + switch (buttonId) { + case 1: + stage = 100; + break; + case 2: + stage = 102; + break; + } + break; + case 100: + if (player.getBank().containsAtLeastOneItem(UNIQUE_BOOKS) && player.getBank().remove(UNIQUE_BOOKS)){ + npc(FacialExpression.DISGUSTED, "That's my book! What's it doing in your bank?"); + stage = 101; + } else { + npc("You seem to have no junk in your bank, sorry."); + stage = 101; + } + break; + case 101: + player.getAchievementDiaryManager().finishTask(player, DiaryType.LUMBRIDGE, 1, 16); + end(); + break; + case 102: + if (player.getInventory().containsAtLeastOneItem(UNIQUE_BOOKS) && player.getInventory().remove(UNIQUE_BOOKS)){ + npc(FacialExpression.DISGUSTED, "That's my book! What's it doing in your inventory?"); + stage = 101; + } else { + npc("You seem to have no junk in your inventory, sorry."); + stage = 101; + } + break; + case 30: + npc("Jolly good. Give it to me, and I'll tell you anything I know", "about it."); + stage = 31; + break; + case 31: + end(); + break; + } + + return true; + } + + @Override + public int[] getIds() { + return new int[]{2253, 3820}; + } +} diff --git a/Server/src/main/content/region/misthalin/draynor/handlers/DBRCutscenePlugin.java b/Server/src/main/content/region/misthalin/draynor/handlers/DBRCutscenePlugin.java new file mode 100644 index 0000000..78c30fa --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/handlers/DBRCutscenePlugin.java @@ -0,0 +1,896 @@ +package content.region.misthalin.draynor.handlers; + +import core.game.component.Component; +import core.game.activity.ActivityPlugin; +import core.game.activity.CutscenePlugin; +import core.game.global.action.DoorActionHandler; +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.ImpactHandler.HitsplatType; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.SpellBookManager; +import core.game.node.item.GroundItem; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.node.item.ItemPlugin; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.map.build.DynamicRegion; +import core.game.world.map.path.Pathfinder; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.net.packet.PacketRepository; +import core.net.packet.context.CameraContext; +import core.net.packet.context.CameraContext.CameraType; +import core.net.packet.out.CameraViewPacket; +import core.plugin.Plugin; +import core.plugin.ClassScanner; + +/** + * Represents the draynor bank robbery cutscene plugin. + * + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class DBRCutscenePlugin extends CutscenePlugin { + + /** + * Represents the cracked component. + */ + private static final Component CRACKED = new Component(385); + + /** + * Represents the stealing animation used for cool mom. + */ + private static final Animation STEAL_ANIMATION = new Animation(832); + + /** + * Represents the casting animation. + */ + private static final Animation CAST_ANIMATION = new Animation(1167); + + /** + * Represents the telekentic animation to use. + */ + private static final Animation TELEKENTIC_ANIMATION = new Animation(723); + + /** + * Represents the telekentic graphics. + */ + private static final Graphics TELEKENTIC_GRAPHIC = new Graphics(142, 96); + + /** + * Represents the casting animation. + */ + private static final Animation SECOND_CAST_ANIMATION = new Animation(1167); + + /** + * Represents the death animation to use. + */ + private static final Animation DEATH_ANIMATION = new Animation(2553); + + /** + * Represents the graphics to use. + */ + private static final Graphics SHOCK_GRAPHIC = new Graphics(432, 0, 0); + + /** + * Represents the teleport animation to use. + */ + private static final Animation TELEPORT_ANIMATION = new Animation(1816); + + /** + * Represents the graphics to use for teleother. + */ + private static final Graphics[] TELE_OTHERS = new Graphics[] { new Graphics(343), new Graphics(342) }; + + /** + * Represents the pick up animation to use. + */ + private static final Animation PICK_UP_ANIMATION = new Animation(827); + + /** + * Represents the hitting animation. + */ + private static final Animation HIT_ANIMATION = new Animation(401); + + /** + * Represents the blocking animation. + */ + private static final Animation BLOCK_ANIMATION = new Animation(425); + + /** + * Represents the thunder animation. + */ + private static final Animation THUNDER_ANIMATION = new Animation(811); + + /** + * Represents the purple graphics. + */ + private static final Graphics PURPLE_GRAPHIC = new Graphics(301, 100); + + /** + * Represents the thunder graphic. + */ + private static final Graphics THUNDER_GRAPHIC = new Graphics(76); + + /** + * Represents the animation to use for the wise old man. + */ + private static final Animation WISE_JUMP = new Animation(2555); + + /** + * Represents the market guard jump animation. + */ + private static final Animation GUARD_JUMP = new Animation(2556); + + /** + * Represents the stomp animation. + */ + private static final Animation STOMP_ANIM = new Animation(1820); + + /** + * Represents the ashes item. + */ + private static final Item ASHES = new Item(592); + + /** + * Represents the coins item. + */ + private static final Item COINS = new Item(995, 60); + + /** + * Represents the party hat item. + */ + private static final Item PARTY_HAT = new Item(2422); + + /** + * Represents the recording pulse. + */ + private final RecordingPulse recordingPulse = new RecordingPulse(); + + /** + * Represents the npcs to use in the cutscene. + */ + private static final NPC[] NPCS = new NPC[] { + /** cool mom */ + NPC.create(2579, Location.create(2120, 4916, 0), Direction.NORTH), + /** olivia */ + NPC.create(2572, Location.create(2117, 4913, 0), Direction.WEST), + /** market guard */ + NPC.create(2571, Location.create(13, 48, 0), Direction.WEST), + /** purepker */ + NPC.create(2575, new Location(2136, 4914, 0), Direction.WEST), + /** first banker */ + NPC.create(2568, new Location(2130, 4909, 0), Direction.EAST), + /** second last banker. */ + NPC.create(2569, new Location(2130, 4907, 0)), + /** last banker */ + NPC.create(2570, new Location(2130, 4906, 0)), + /** efinlocks */ + NPC.create(2578, new Location(2133, 4908, 0)), + /** 1337sp34kr */ + NPC.create(2577, new Location(2134, 4906, 0), Direction.WEST), + /** quitedoll */ + NPC.create(2576, new Location(2133, 4906, 0), Direction.EAST), + /** oldman */ + NPC.create(2566, new Location(2128, 4915, 0), Direction.SOUTH) }; + + /** + * Constructs a new {@code DBRCutscenePlugin} {@code Object}. + */ + public DBRCutscenePlugin() { + super("dbr cutscene"); + } + + /** + * Constructs a new {@code DBRCutscenePlugin} {@code Object}. + * + * @param player + * the player. + */ + public DBRCutscenePlugin(final Player player) { + super("dbr cutscene"); + this.player = player; + } + + @Override + public void open() { + setNpcs(); + GameWorld.getPulser().submit(recordingPulse); + player.lock(); + player.getLocks().lockMovement(10000000); + camera(27, 45, -14, 2, 700, 100); + } + + @Override + public ActivityPlugin newInstance(Player p) throws Throwable { + return new DBRCutscenePlugin(p); + } + + @Override + public void register() { + super.register(); + try { + new DBRecordingNPC().newInstance(null); + } catch (Throwable e) { + e.printStackTrace(); + } + ClassScanner.definePlugin(new BluePhatItem()); + } + + @Override + public Location getSpawnLocation() { + return null; + } + + @Override + public Location getStartLocation() { + return base.transform(17, 51, 0); + } + + @Override + public void configure() { + region = DynamicRegion.create(8524); + setRegionBase(); + registerRegion(region.getId()); + player.getDialogueInterpreter().sendPlainMessage(true, "You close your eyes and watch the recording..."); + } + + @Override + public void end() { + super.end(); + clearNpcs(); + player.getSavedData().getGlobalData().setDraynorRecording(true); + player.getDialogueInterpreter().sendDialogue("End of recording."); + } + + /** + * Gets the cool mom npc. + * + * @return the cool mom npc. + */ + public NPC getCoolMom() { + return getNpc(2579); + } + + /** + * Gets the olivia npc. + * + * @return the olivia npc. + */ + public NPC getOlivia() { + return getNpc(2572); + } + + /** + * Gets the market guard npc. + * + * @return the market guard. + */ + public NPC getMarketGuard() { + return getNpc(2571); + } + + /** + * Gets the pure pker npc. + * + * @return the pure pker npc. + */ + public NPC getPurePker() { + return getNpc(2575); + } + + /** + * Gets the elfinlocks npc. + * + * @return the elfinocks npc. + */ + public NPC getElfinocks() { + return getNpc(2578); + } + + /** + * Gets the 1337sp34kr npc. + * + * @return the 1337sp34kr npc. + */ + public NPC get1337() { + return getNpc(2577); + } + + /** + * Gets the quitedoll npc. + * + * @return the quitedoll npc. + */ + public NPC getQuiteDoll() { + return getNpc(2576); + } + + /** + * Gets the wise old man npc. + * + * @return the wise old man npc. + */ + public NPC getWiseOldMan() { + int size = region.getPlanes()[0].getNpcs().size(); + return region.getPlanes()[0].getNpcs().get(size - 1); + } + + /** + * Gets the first banker. + * + * @return the first banker. + */ + public NPC getFirstBanker() { + return getNpc(2568); + } + + /** + * Gets the second banker. + * + * @return the second banker. + */ + public NPC getSecondBanker() { + return getNpc(2569); + } + + /** + * Gets the last banker. + * + * @return the last banker. + */ + public NPC getLastBanker() { + return getNpc(2570); + } + + /** + * Method used to walk an npc. + * + * @param npc + * the npc. + * @param location + * the location. + */ + private void walk(NPC npc, final Location location) { + Pathfinder.find(npc, location, true, Pathfinder.DUMB).walk(npc); + } + + /** + * Method used to kill an npc. + * + * @param npc + * the npc. + */ + private void die(NPC npc) { + npc.getAnimator().reset(); + npc.animate(DEATH_ANIMATION); + npc.graphics(SHOCK_GRAPHIC); + npc.getImpactHandler().manualHit(npc, npc.getSkills().getLifepoints(), HitsplatType.NORMAL); + } + + /** + * Method used to cast a shock. + * + * @param target + * the target. + */ + private void castShock(Node target) { + getWiseOldMan().animate(CAST_ANIMATION); + getWiseOldMan().graphics(new Graphics(433)); + if (target instanceof Entity) { + Projectile.create(getWiseOldMan(), (Entity) target, 434).send(); + } else { + Projectile projectile = Projectile.create(getWiseOldMan(), null, 434, 30, 30, 41, 140, 0, 0); + projectile.setEndLocation((Location) target); + projectile.send(); + } + } + + /** + * Method used to cast the telekinetic grab spell. + */ + private void castTelekinetic() { + getWiseOldMan().animate(TELEKENTIC_ANIMATION); + getWiseOldMan().graphics(TELEKENTIC_GRAPHIC); + getWiseOldMan().getSkills().setStaticLevel(Skills.MAGIC, 99); + getWiseOldMan().getSkills().setLevel(Skills.MAGIC, 99); + SpellBookManager.SpellBook.MODERN.getSpell(19).cast(getWiseOldMan(), GroundItemManager.get(PARTY_HAT.getId(), base.transform(20, 44, 0), player)); + } + + /** + * Method used to cast the thunder shock. + */ + private void castThunderShock() { + getWiseOldMan().animate(THUNDER_ANIMATION); + getWiseOldMan().graphics(PURPLE_GRAPHIC); + } + + /** + * Method used to handle the camera. + * + * @param x + * the x offset. + * @param y + * the y offset. + * @param xRot + * the xRotation. + * @param yRot + * the yRotation. + * @Param height the height. + */ + private void camera(int x, int y, int xRot, int yRot, int height, int speed) { + Location loc = base.transform(x, y, 0); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.POSITION, loc.getX(), loc.getY(), height, 1, speed)); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.ROTATION, loc.getX() + xRot, loc.getY() + yRot, height, 1, speed)); + } + + /** + * Method used to set npcs and their locations. + */ + private void setNpcs() { + for (NPC n : NPCS) { + n = NPC.create(n.getId(), n.getLocation(), n.getDirection()); + n.setLocation(base.transform(n.getLocation().getLocalX(), n.getLocation().getLocalY(), 0)); + n.setRespawn(false); + n.init(); + if (n.getName().equals("Banker")) { + n.getSkills().setStaticLevel(Skills.HITPOINTS, 15); + n.getSkills().setLevel(Skills.HITPOINTS, 15); + } + n.setWalks(false); + } + } + + /** + * Method used to clear all the npcs. + */ + private void clearNpcs() { + GameWorld.getPulser().submit(new Pulse(5) { + @Override + public boolean pulse() { + for (NPC n : region.getPlanes()[0].getNpcs()) { + n.clear(); + } + return true; + } + + }); + } + + /** + * Gets the npc. + * + * @param id + * the id. + * @return the npc. + */ + private NPC getNpc(int id) { + for (NPC n : region.getPlanes()[0].getNpcs()) { + if (n.getId() == id) { + return n; + } + } + return null; + } + + /** + * Represents the pulse used during recording. + * + * @author 'Vexia + * @version 1.0 + */ + public final class RecordingPulse extends Pulse { + + /** + * Represents the counter. + */ + private int counter; + + /** + * Constructs a new {@code FightPulse} {@code Object}. + */ + public RecordingPulse() { + super(1, player); + } + + @Override + public boolean pulse() { + switch (counter++) { + case 1: + getCoolMom().animate(STEAL_ANIMATION); + getMarketGuard().getSkills().setStaticLevel(Skills.HITPOINTS, 99); + getMarketGuard().getSkills().setLifepoints(99); + getMarketGuard().sendChat("Hey! Get your hands off there!"); + getCoolMom().getLocks().lockMovement(1000); + getMarketGuard().getProperties().getCombatPulse().attack(getCoolMom()); + break; + case 8: + walk(getPurePker(), base.transform(20, 45, 0)); + break; + case 10: + camera(27, 43, -37, -3, 600, 5); + break; + case 12: + getQuiteDoll().sendChat("Thx"); + break; + case 14: + walk(getQuiteDoll(), base.transform(20, 42, 0)); + get1337().sendChat("Yw"); + getPurePker().faceLocation(base.getLocation().transform(19, 45, 0)); + break; + case 16: + getElfinocks().sendChat("Buying 2k nats - no noob offers"); + break; + case 20: + get1337().sendChat("I h4ve n4ts"); + break; + case 22: + getElfinocks().sendChat("You sell?"); + break; + case 25: + get1337().sendChat("Tr4de"); + get1337().faceTemporary(getElfinocks(), 5); + walk(get1337(), base.transform(21, 43, 0)); + break; + case 26: + camera(23, 49, -37, 0, 500, 3); + break; + case 28: + walk(getQuiteDoll(), base.transform(20, 49, 0)); + walk(getPurePker(), base.transform(16, 49, 0)); + break; + case 29: + walk(getOlivia(), base.transform(12, 48, 0)); + break; + case 36: + DoorActionHandler.handleAutowalkDoor(getWiseOldMan(), RegionManager.getObject(base.transform(16, 51, 0))); + break; + case 37: + getQuiteDoll().sendChat("Huh?"); + getQuiteDoll().faceTemporary(getWiseOldMan(), 2); + getWiseOldMan().sendChat("Please don't block my line of fire!"); + castShock(getPurePker()); + break; + case 38: + die(getPurePker()); + break; + case 39: + getOlivia().sendChat("Hey, what are you doing?"); + getWiseOldMan().faceTemporary(getOlivia(), 2); + GroundItemManager.create(ASHES, base.transform(16, 49, 0), player); + GroundItemManager.create(COINS, base.transform(16, 49, 0), player); + break; + case 42: + getWiseOldMan().sendChat("Olivia - Please go away!"); + getWiseOldMan().animate(SECOND_CAST_ANIMATION); + getWiseOldMan().graphics(TELE_OTHERS[0]); + break; + case 43: + getOlivia().animate(TELEPORT_ANIMATION); + getOlivia().graphics(TELE_OTHERS[1]); + getOlivia().sendChat("Eeeek!"); + GroundItemManager.destroy(GroundItemManager.get(ASHES.getId(), base.transform(16, 49, 0), player)); + break; + case 45: + getOlivia().setInvisible(true); + break; + case 48: + getWiseOldMan().sendChat("Ah, now I can get on with it..."); + getWiseOldMan().faceLocation(base.transform(16, 49, 0)); + break; + case 49: + getWiseOldMan().animate(PICK_UP_ANIMATION); + break; + case 50: + GroundItemManager.destroy(GroundItemManager.get(COINS.getId(), base.transform(16, 49, 0), player)); + break; + case 53: + castShock(base.transform(16, 46, 0)); + break; + case 55: + Scenery wall = RegionManager.getObject(base.transform(16, 46, 0)); + if(wall != null) + SceneryBuilder.replace(wall, wall.transform(9151, 0, 10)); + if(getWiseOldMan() != null) { + getWiseOldMan().getWalkingQueue().reset(); + getWiseOldMan().getWalkingQueue().addPath(base.getX() + 16, base.getY() + 46); + getWiseOldMan().getWalkingQueue().addPath(base.getX() + 17, base.getY() + 46); + } + break; + case 58: + camera(21, 38, -36, 43, 495, 99); + break; + case 59: + getWiseOldMan().sendChat("Could everyone please not move?"); + break; + case 62: + getFirstBanker().sendChat("Hey - you can't come in here!"); + walk(getFirstBanker(), base.transform(18, 46, 0)); + getFirstBanker().faceTemporary(getWiseOldMan(), 2); + getWiseOldMan().faceTemporary(getFirstBanker(), 2); + break; + case 64: + getWiseOldMan().animate(HIT_ANIMATION); + getFirstBanker().animate(BLOCK_ANIMATION); + getFirstBanker().getImpactHandler().manualHit(getWiseOldMan(), getFirstBanker().getSkills().getLifepoints(), HitsplatType.NORMAL); + getSecondBanker().sendChat("Oi!"); + getLastBanker().sendChat("Uh-oh!"); + getSecondBanker().getWalkingQueue().reset(); + getSecondBanker().getWalkingQueue().addPath(base.getX() + 17, base.getY() + 43); + getSecondBanker().getWalkingQueue().addPath(base.getX() + 16, base.getY() + 43); + getSecondBanker().getWalkingQueue().addPath(base.getX() + 16, base.getY() + 46); + break; + case 70: + walk(getLastBanker(), base.transform(18, 40, 0)); + getSecondBanker().faceTemporary(getWiseOldMan(), 2); + getSecondBanker().animate(new Animation(422)); + getWiseOldMan().animate(new Animation(403)); + getWiseOldMan().faceTemporary(getSecondBanker(), 2); + break; + case 73: + getWiseOldMan().animate(new Animation(401)); + getSecondBanker().animate(new Animation(435)); + getSecondBanker().getImpactHandler().manualHit(getWiseOldMan(), 11, HitsplatType.NORMAL); + break; + case 75: + getSecondBanker().animate(new Animation(422)); + NPC npc = getWiseOldMan(); + if (npc != null) { + getWiseOldMan().sendChat("I do wish you'd just stop it!"); + getWiseOldMan().animate(new Animation(403)); + } + break; + case 78: + getWiseOldMan().animate(new Animation(401)); + walk(getLastBanker(), base.transform(16, 40, 0)); + walk(getElfinocks(), base.transform(20, 44, 0)); + break; + case 80: + getWiseOldMan().faceLocation(base.transform(17, 43, 0)); + getLastBanker().faceTemporary(getWiseOldMan(), 1); + getSecondBanker().getImpactHandler().manualHit(getWiseOldMan(), getSecondBanker().getSkills().getLifepoints(), HitsplatType.NORMAL); + break; + case 85: + getWiseOldMan().faceLocation(base.transform(17, 43, 0)); + getElfinocks().sendChat("Hey - how'd he get in there?"); + break; + case 86: + camera(26, 40, -35, 13, 545, 32); + getLastBanker().sendChat("Help! Help!"); + get1337().sendChat("Hax!"); + get1337().faceLocation(base.transform(20, 43, 0)); + break; + case 90: + getWiseOldMan().sendChat("My sincerest regrets, dear lady..."); + break; + case 92: + getWiseOldMan().faceTemporary(getElfinocks(), 1); + castShock(getElfinocks()); + break; + case 94: + die(getElfinocks()); + break; + case 96: + GroundItemManager.create(ASHES, base.transform(20, 44, 0), player); + GroundItemManager.create(PARTY_HAT, base.transform(20, 44, 0), player); + break; + case 99: + getWiseOldMan().sendChat("And also you, sir..."); + GroundItemManager.destroy(GroundItemManager.get(ASHES.getId(), base.transform(20, 44, 0), player)); + break; + case 101: + castShock(get1337()); + walk(getQuiteDoll(), base.transform(21, 44, 0)); + break; + case 103: + getQuiteDoll().faceTemporary(getWiseOldMan(), 1); + break; + case 104: + getQuiteDoll().sendChat("How you do that?"); + die(get1337()); + break; + case 107: + GroundItemManager.create(ASHES, base.transform(21, 43, 0), player); + break; + case 109: + getWiseOldMan().sendChat("Oh dear - another one..."); + walk(getWiseOldMan(), base.transform(18, 46, 0)); + getWiseOldMan().faceTemporary(getQuiteDoll(), 1); + GroundItemManager.destroy(GroundItemManager.get(ASHES.getId(), base.transform(21, 43, 0), player)); + break; + case 110: + GroundItemManager.destroy(GroundItemManager.get(ASHES.getId(), base.transform(21, 43, 0), player)); + break; + case 111: + castShock(getQuiteDoll()); + break; + case 114: + die(getQuiteDoll()); + break; + case 115: + GroundItemManager.create(ASHES, base.transform(21, 44, 0), player); + getWiseOldMan().sendChat("Ooh - a party hat?"); + getWiseOldMan().faceLocation(base.transform(20, 44, 0)); + break; + case 116: + GroundItemManager.destroy(GroundItemManager.get(ASHES.getId(), base.transform(21, 44, 0), player)); + castTelekinetic(); + break; + case 118: + getWiseOldMan().transform(2567); + if (getOlivia().isActive()) { + getOlivia().getImpactHandler().manualHit(getMarketGuard(), getOlivia().getSkills().getLifepoints(), HitsplatType.NORMAL); + } + getMarketGuard().setInvisible(true); + break; + case 120: + getWiseOldMan().sendChat("Now, my dear..."); + walk(getWiseOldMan(), base.transform(18, 42, 0)); + break; + case 121: + getLastBanker().sendChat("Eeek!"); + break; + case 124: + getWiseOldMan().sendChat("Just give me the money, please."); + break; + case 126: + getMarketGuard().setInvisible(false); + getMarketGuard().getProperties().setTeleportLocation(base.transform(18, 46, 0)); + break; + case 127: + camera(25, 42, -20, 0, 400, 4); + getMarketGuard().sendChat("Old man, you're for da cage!"); + walk(getMarketGuard(), base.transform(18, 43, 0)); + break; + case 128: + getWiseOldMan().faceTemporary(getMarketGuard(), 1); + break; + case 129: + getWiseOldMan().sendChat("Oh, am I?"); + break; + case 131: + getWiseOldMan().sendChat("Ahh!"); + break; + case 133: + castThunderShock(); + break; + case 136: + getMarketGuard().graphics(THUNDER_GRAPHIC); + getMarketGuard().getImpactHandler().manualHit(getWiseOldMan(), 40, HitsplatType.NORMAL); + getMarketGuard().sendChat("Aaargh!"); + break; + case 138: + getWiseOldMan().sendChat("Yah!"); + getWiseOldMan().animate(WISE_JUMP); + break; + case 139: + getMarketGuard().animate(GUARD_JUMP); + break; + case 142: + getMarketGuard().clear(); + camera(24, 42, -20, 0, 400, 4); + break; + case 143: + getWiseOldMan().sendChat("And YOU can stop spying on me!"); + getWiseOldMan().faceLocation(base.transform(24, 42, 0)); + break; + case 145: + getWiseOldMan().animate(STOMP_ANIM); + Projectile projectile = Projectile.create(getWiseOldMan(), null, 434, 50, 130, 41, 140, 0, 0); + projectile.setEndLocation((Location) base.transform(24, 42, 0)); + projectile.send(); + break; + case 148: + player.getInterfaceManager().open(CRACKED); + break; + case 150: + DBRCutscenePlugin.this.stop(true); + return true; + } + return !player.isActive(); + } + + @Override + public void stop() { + super.stop(); + clearNpcs(); + } + + /** + * Gets the counter. + * + * @return the counter. + */ + public int getCounter() { + return counter; + } + } + + /** + * Represents an npc during the draynor bank recording cutscene. + * + * @author 'Vexia + * @version 1.0 + */ + public static final class DBRecordingNPC extends AbstractNPC { + + /** + * Represents the ids to use. + */ + private static final int[] IDS = new int[] { 2579 }; + + /** + * Constructs a new {@code DBRecordingNPC} {@code Object}. + */ + public DBRecordingNPC() { + super(0, null, false); + } + + /** + * Constructs a new {@code DBRecordingNPC} {@code Object}. + * + * @param id + * the id. + * @param location + * the locastion. + */ + private DBRecordingNPC(int id, Location location) { + super(id, location); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new DBRecordingNPC(id, location); + } + + @Override + public void init() { + super.init(); + getSkills().setLevel(Skills.ATTACK, 1); + getSkills().setStaticLevel(Skills.ATTACK, 1); + getSkills().setLevel(Skills.DEFENCE, 2); + getSkills().setStaticLevel(Skills.DEFENCE, 2); + } + + @Override + public boolean isAttackable(Entity entity, CombatStyle style, boolean message) { + return true; + } + + @Override + public int[] getIds() { + return IDS; + } + } + + public static final class BluePhatItem extends ItemPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + register(PARTY_HAT.getId()); + return this; + } + + @Override + public boolean canPickUp(Player player, GroundItem item, int type) { + if (type == 1) { + player.sendMessage("Nice try ;)"); + } + return false; + } + } +} diff --git a/Server/src/main/content/region/misthalin/draynor/handlers/DraynorManorPlugin.java b/Server/src/main/content/region/misthalin/draynor/handlers/DraynorManorPlugin.java new file mode 100644 index 0000000..27ba1d9 --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/handlers/DraynorManorPlugin.java @@ -0,0 +1,250 @@ +package content.region.misthalin.draynor.handlers; + +import core.cache.def.impl.SceneryDefinition; +import core.game.dialogue.FacialExpression; +import core.game.global.action.ClimbActionHandler; +import core.game.global.action.DoorActionHandler; +import content.global.skill.agility.AgilityHandler; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.map.path.Pathfinder; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the plugin used to handle node interactions at draynor manor. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class DraynorManorPlugin extends OptionHandler { + + /** + * Represents the lever animation. + */ + private static final Animation LEVER_ANIMATION = new Animation(834); + + /** + * Represents the basement location. + */ + private static final Location BASEMENT = new Location(3117, 9753, 0); + + /** + * Represents the digging animation. + */ + private static final Animation DIG_ANIM = new Animation(830); + + /** + * Represents the searching animation. + */ + private static final Animation SEARCH_ANIM = new Animation(881); + + /** + * Represents the spade item. + */ + private static final Item SPADE = new Item(952); + + /** + * Represents the key item. + */ + private static final Item KEY = new Item(275); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(156).getHandlers().put("option:search", this); + SceneryDefinition.forId(155).getHandlers().put("option:search", this); + SceneryDefinition.forId(160).getHandlers().put("option:pull", this); + SceneryDefinition.forId(131).getHandlers().put("option:open", this); + SceneryDefinition.forId(133).getHandlers().put("option:climb-down", this); + SceneryDefinition.forId(134).getHandlers().put("option:open", this); + SceneryDefinition.forId(135).getHandlers().put("option:open", this); + SceneryDefinition.forId(152).getHandlers().put("option:search", this); + SceneryDefinition.forId(153).getHandlers().put("option:search", this); + SceneryDefinition.forId(11498).getHandlers().put("option:climb-up", this); + SceneryDefinition.forId(37703).getHandlers().put("option:squeeze-through", this); + return this; + } + + @Override + public boolean handle(final Player player, Node node, String option) { + int id = ((Scenery) node).getId(); + switch (id) { + case 11498: + ClimbActionHandler.climb(player, new Animation(828), Location.create(3108, 3366, 1)); + break; + case 160: + case 156: + case 155: + handleBookCase(player, ((Scenery) node)); + break; + case 133: + ClimbActionHandler.climb(player, new Animation(827), BASEMENT); + break; + case 134:// big doors + case 135: + if (player.getLocation().getY() >= 3354) { + player.getPacketDispatch().sendMessage("The doors won't open."); + return true; + } + player.getPacketDispatch().sendMessage("The doors slam shut behind you."); + DoorActionHandler.handleDoor(player, (Scenery) node); + return true; + case 131: + if (!player.getInventory().containsItem(KEY)) { + player.getPacketDispatch().sendMessage("The door is locked."); + } else { + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + } + break; + case 152: + if (!player.getInventory().containsItem(SPADE)) { + player.getDialogueInterpreter().sendDialogues(player, FacialExpression.FURIOUS, "I'm not looking through that with my hands!"); + return true; + } + player.lock(3); + player.animate(DIG_ANIM); + player.getPacketDispatch().sendMessage("You dig throug the compost..."); + if (!player.getInventory().containsItem(KEY)) { + player.getPacketDispatch().sendMessage("... and find a small key."); + if (!player.getInventory().add(KEY)) { + GroundItemManager.create(KEY, player); + } + } else { + player.getPacketDispatch().sendMessage("... but you find nothing of interest."); + } + break; + case 153: + player.lock(3); + player.animate(SEARCH_ANIM); + player.getDialogueInterpreter().open(3954922); + break; + case 37703: + AgilityHandler.walk(player, 0, player.getLocation(), node.getLocation().transform(player.getLocation().getX() <= 3085 ? 1 : 0, 0, 0), new Animation(1426), 0, null); + break; + } + return true; + } + + /** + * Method used to handle the secret book case opening. + * @param player the player. + */ + private final void handleBookCase(final Player player, final Scenery object) { + Location dest = null; + if (RegionManager.getObject(Location.create(3097, 3359, 0)) == null || RegionManager.getObject(Location.create(3097, 3358, 0)) == null) { + return; + } + if (player.getLocation().getX() > 3096) { + if (player.getLocation().getY() >= 3359) { + dest = Location.create(3096, 3359, 0); + } else { + dest = Location.create(3096, 3358, 0); + } + } else { + if (object.getId() != 160) { + return; + } + if (player.getLocation().getY() >= 3359) { + dest = Location.create(3098, 3359, 0); + } else { + dest = Location.create(3098, 3358, 0); + } + } + final Location destination = dest; + if (object.getId() == 160) { + GameWorld.getPulser().submit(new Pulse(1, player) { + int counter = 0; + + @Override + public boolean pulse() { + switch (counter++) { + case 1: + player.getPacketDispatch().sendMessage("The lever opens the secret door!"); + player.animate(LEVER_ANIMATION); + break; + case 2: + SceneryBuilder.replace(object, object.transform(161), 6); + break; + case 3: + Pathfinder.find(player, Location.create(3096, 3358, 0)).walk(player); + break; + case 4: + player.faceLocation(destination); + break; + case 5: + SceneryBuilder.remove(RegionManager.getObject(Location.create(3097, 3359, 0))); + SceneryBuilder.remove(RegionManager.getObject(Location.create(3097, 3358, 0))); + SceneryBuilder.add(new Scenery(156, new Location(3097, 3357, 0))); + SceneryBuilder.add(new Scenery(157, new Location(3097, 3360, 0))); + break; + case 6: + AgilityHandler.walk(player, -1, player.getLocation(), destination, null, 0.0, null); + break; + case 8: + SceneryBuilder.remove(RegionManager.getObject(new Location(3097, 3360, 0))); + SceneryBuilder.remove(RegionManager.getObject(new Location(3097, 3357, 0))); + SceneryBuilder.add(new Scenery(155, new Location(3097, 3359, 0))); + SceneryBuilder.add(new Scenery(156, new Location(3097, 3358, 0))); + break; + } + return false; + } + }); + return; + } + GameWorld.getPulser().submit(new Pulse(1, player) { + int count = 0; + + @Override + public boolean pulse() { + switch (count) { + case 0: + player.getPacketDispatch().sendMessage("You've found a secret door!"); + SceneryBuilder.remove(RegionManager.getObject(Location.create(3097, 3359, 0))); + SceneryBuilder.remove(RegionManager.getObject(Location.create(3097, 3358, 0))); + SceneryBuilder.add(new Scenery(156, new Location(3097, 3357, 0))); + SceneryBuilder.add(new Scenery(157, new Location(3097, 3360, 0))); + break; + case 1: + AgilityHandler.walk(player, -1, player.getLocation(), destination, null, 0.0, null); + break; + case 3: + SceneryBuilder.remove(RegionManager.getObject(new Location(3097, 3360, 0))); + SceneryBuilder.remove(RegionManager.getObject(new Location(3097, 3357, 0))); + SceneryBuilder.add(new Scenery(155, new Location(3097, 3359, 0))); + SceneryBuilder.add(new Scenery(156, new Location(3097, 3358, 0))); + break; + } + count++; + return count == 4; + } + + }); + } + + @Override + public Location getDestination(Node node, Node n) { + if (n instanceof Scenery) { + final int id = ((Scenery) n).getId(); + switch (id) { + case 155: + return Location.create(3098, 3359, 0); + case 156: + return Location.create(3098, 3358, 0); + case 160: + return Location.create(3096, 3357, 0); + } + } + return null; + } +} diff --git a/Server/src/main/content/region/misthalin/draynor/handlers/DraynorManorShortcutListener.kt b/Server/src/main/content/region/misthalin/draynor/handlers/DraynorManorShortcutListener.kt new file mode 100644 index 0000000..457a64d --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/handlers/DraynorManorShortcutListener.kt @@ -0,0 +1,42 @@ +package content.region.misthalin.draynor.handlers + +import content.global.skill.agility.AgilityHandler +import core.api.hasLevelDyn +import core.api.sendDialogue +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.skill.Skills +import core.game.world.map.Direction +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Scenery + +class DraynorManorShortcutListener : InteractionListener { + override fun defineListeners() { + + val BROKEN_RAILING = Scenery.BROKEN_RAILING_37703 + val SQUEEZE_ANIMATION = 3844 + + on(BROKEN_RAILING, IntType.SCENERY, "squeeze-through") { player, _ -> + if (!hasLevelDyn(player, Skills.AGILITY, 28)) { + sendDialogue(player, "You need an Agility level of at least 28 to do this.") + return@on true + } + + val squeezeAnim = Animation.create(SQUEEZE_ANIMATION) + if (player.location.x >= 3086) { + AgilityHandler.forceWalk( + player, -1, player.location, + player.location.transform(Direction.WEST, 1), + squeezeAnim, 5, 0.0, null + ) + } else { + AgilityHandler.forceWalk( + player, -1, player.location, + player.location.transform(Direction.EAST, 1), + squeezeAnim, 5, 0.0, null + ) + } + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/draynor/handlers/DraynorMansionCourtyardZone.java b/Server/src/main/content/region/misthalin/draynor/handlers/DraynorMansionCourtyardZone.java new file mode 100644 index 0000000..3a286e2 --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/handlers/DraynorMansionCourtyardZone.java @@ -0,0 +1,44 @@ +package content.region.misthalin.draynor.handlers; + +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneBuilder; +import core.plugin.Initializable; +import core.plugin.Plugin; + +@Initializable +public class DraynorMansionCourtyardZone extends MapZone implements Plugin { + + public DraynorMansionCourtyardZone() { + super("draynor-mansion-courtyard", true); + } + + @Override + public void configure() { + register(new ZoneBorders(3100, 3333, 3114, 3346)); + } + + @Override + public boolean enter(Entity entity) { + // Enter the courtyard of the spooky mansion in Draynor Village + if (entity.isPlayer()) { + Player player = entity.asPlayer(); + player.getAchievementDiaryManager().finishTask(player, DiaryType.LUMBRIDGE, 0, 8); + } + return super.enter(entity); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ZoneBuilder.configure(this); + return this; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } +} diff --git a/Server/src/main/content/region/misthalin/draynor/handlers/DraynorMarketZone.java b/Server/src/main/content/region/misthalin/draynor/handlers/DraynorMarketZone.java new file mode 100644 index 0000000..6e64da1 --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/handlers/DraynorMarketZone.java @@ -0,0 +1,44 @@ +package content.region.misthalin.draynor.handlers; + +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneBuilder; +import core.plugin.Initializable; +import core.plugin.Plugin; + +@Initializable +public class DraynorMarketZone extends MapZone implements Plugin { + + public DraynorMarketZone() { + super("draynor-market", true); + } + + @Override + public void configure() { + register(new ZoneBorders(3074, 3245, 3086, 3255)); + } + + @Override + public boolean enter(Entity entity) { + // Visit the Draynor Village market + if (entity.isPlayer()) { + Player player = entity.asPlayer(); + player.getAchievementDiaryManager().finishTask(player, DiaryType.LUMBRIDGE, 0, 9); + } + return super.enter(entity); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ZoneBuilder.configure(this); + return this; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } +} diff --git a/Server/src/main/content/region/misthalin/draynor/handlers/DraynorNodePlugin.java b/Server/src/main/content/region/misthalin/draynor/handlers/DraynorNodePlugin.java new file mode 100644 index 0000000..474822f --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/handlers/DraynorNodePlugin.java @@ -0,0 +1,245 @@ +package content.region.misthalin.draynor.handlers; + +import core.cache.def.impl.NPCDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.game.component.Component; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.scenery.SceneryBuilder; +import core.game.activity.ActivityManager; +import core.game.activity.ActivityPlugin; +import core.game.activity.CutscenePlugin; +import core.plugin.Initializable; +import core.game.dialogue.DialoguePlugin; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.net.packet.PacketRepository; +import core.net.packet.context.CameraContext; +import core.net.packet.context.CameraContext.CameraType; +import core.net.packet.out.CameraViewPacket; +import core.plugin.Plugin; + +/** + * Represents the node plugin used to handle draynor interactions. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class DraynorNodePlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + NPCDefinition.forId(922).getHandlers().put("option:make-dyes", this); + SceneryDefinition.forId(7092).getHandlers().put("option:observe", this); + SceneryDefinition.forId(6434).getHandlers().put("option:open", this); + ActivityManager.register(new TelescopeCutscene()); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + final int id = node instanceof NPC ? ((NPC) node).getId() : ((Scenery) node).getId(); + switch (id) { + case 922: + player.getDialogueInterpreter().open(((NPC) node).getId(), ((NPC) node), true); + break; + case 7092: + ActivityManager.start(player, "draynor telescope", false); + break; + case 6434: // Trapdoors above NW and SE corners of Draynor sewer + if (option.equalsIgnoreCase("open")) { + SceneryBuilder.replace(node.asScenery(), node.asScenery().transform(6435), 500); + } + break; + } + return true; + } + + @Override + public Location getDestination(Node node, Node n) { + if (n instanceof Scenery) { + final Scenery object = (Scenery) n; + if (object.getId() == 7092) { + return n.getLocation().transform(0, 1, 0); + } + } + return null; + } + + /** + * Represents the telescope cutscene. + * @author 'Vexia + * @version 1.0 + */ + public static final class TelescopeCutscene extends CutscenePlugin { + + /** + * Represents the telescope interface. + */ + private static final Component INTERFACE = new Component(386); + + /** + * Represents the animation used to look into a telescope. + */ + private static final Animation TELESCOPE_ANIM = new Animation(2171); + + /** + * Constructs a new {@code TelescopeCutscene} {@code Object}. + */ + public TelescopeCutscene() { + super("draynor telescope"); + } + + /** + * Constructs a new {@code TelescopeCutscene} {@code Object}. + * @param player the player. + */ + public TelescopeCutscene(Player player) { + super("draynor telescope"); + this.player = player; + } + + @Override + public ActivityPlugin newInstance(Player p) throws Throwable { + return new TelescopeCutscene(p); + } + + @Override + public boolean start(final Player player, boolean login, Object... args) { + player.animate(TELESCOPE_ANIM); + player.getDialogueInterpreter().sendPlainMessage(true, "You look through the telescope..."); + return super.start(player, login, args); + } + + @Override + public void open() { + player.setAttribute("cutscene:original-loc", Location.create(3088, 3254, 0)); + player.setDirection(Direction.NORTH); + player.faceLocation(player.getLocation().transform(0, 1, 0)); + int x = 3104; + int y = 3175; + int height = 900; + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.POSITION, x, y, height, 1, 100)); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.ROTATION, x + 1, y - 30, height, 1, 100)); + x = 3111; + y = 3172; + height = 700; + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.POSITION, x, y, height, 1, 2)); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.ROTATION, x - 1, y + 230, height, 1, 1)); + player.getInterfaceManager().open(INTERFACE); + GameWorld.getPulser().submit(new Pulse(22, player) { + @Override + public boolean pulse() { + TelescopeCutscene.this.stop(true); + return true; + } + }); + } + + @Override + public void register() { + super.register(); + new EndDialogue().init(); + } + + @Override + public void end() { + player.getInterfaceManager().close(); + player.getDialogueInterpreter().open(32389023); + player.getAchievementDiaryManager().finishTask(player, DiaryType.LUMBRIDGE, 1, 17); + super.end(); + } + + @Override + public Location getSpawnLocation() { + return null; + } + + @Override + public Location getStartLocation() { + return new Location(3104, 3175, 0); + } + + @Override + public void configure() { + + } + + /** + * Represents the ending dialogue. + * @author 'Vexia + * @version 1.0 + */ + public static final class EndDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code EndDialogue} {@code Object}. + * @param player the player. + */ + public EndDialogue(final Player player) { + super(player); + } + + /** + * Constructs a new {@code EndDialogue} {@code Object}. + */ + public EndDialogue() { + /** + * empty. + */ + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new EndDialogue(player); + } + + @Override + public boolean open(Object... args) { + player("I see you've got your telescope", "pointing at the Wizard's Tower."); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(3820, null, "Oh, do I? Well, why does that interest you?"); + stage = 1; + break; + case 1: + player("Well, you robbed a bank, and I bet you're now", "planning something to do with that Tower!"); + stage = 2; + break; + case 2: + interpreter.sendDialogues(3820, null, "No, no, I'm not planning anything like that again."); + stage = 3; + break; + case 3: + player("Well I'll be watching you..."); + stage = 4; + break; + case 4: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 32389023 }; + } + + } + + } + +} diff --git a/Server/src/main/content/region/misthalin/draynor/handlers/DraynorTreeNPC.java b/Server/src/main/content/region/misthalin/draynor/handlers/DraynorTreeNPC.java new file mode 100644 index 0000000..2bc5f68 --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/handlers/DraynorTreeNPC.java @@ -0,0 +1,90 @@ +package content.region.misthalin.draynor.handlers; + +import java.util.List; + +import core.game.node.entity.combat.ImpactHandler.HitsplatType; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.tools.RandomFunction; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playAudio; +import static core.api.ContentAPIKt.playHurtAudio; + +/** + * Represents the abstract draynor tree npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class DraynorTreeNPC extends AbstractNPC { + + /** + * Represents the NPC ids of NPCs using this plugin. + */ + private static final int[] ID = { 5208, 152, 5207 }; + + /** + * Represents the animation of the tree. + */ + private static final Animation ANIMATION = new Animation(73, Priority.HIGH); + + /** + * Represents the attack delay. + */ + private int attackDelay; + + /** + * Constructs a new {@code DraynorTreeNPC} {@code Object}. + */ + public DraynorTreeNPC() { + super(0, null, false); + } + + /** + * Constructs a new {@code DraynorTreeNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + private DraynorTreeNPC(int id, Location location) { + super(id, location, false); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new DraynorTreeNPC(id, location); + } + + @Override + public void tick() { + final List players = RegionManager.getLocalPlayers(this, 1); + if (players.size() != 0) { + if (attackDelay < GameWorld.getTicks()) { + for (Player p : players) { + faceTemporary(p, 2); + getAnimator().forceAnimation(ANIMATION); + playAudio(p, Sounds.NASTY_TREE_ATTACK_651); + int hit = RandomFunction.random(2); + if (hit > 0) playHurtAudio(p, 20); + p.getImpactHandler().manualHit(this, hit, hit > 0 ? HitsplatType.NORMAL : HitsplatType.MISS); + attackDelay = GameWorld.getTicks() + 3; + p.animate(p.getProperties().getDefenceAnimation()); + return; + } + } + } + super.tick(); + } + + @Override + public int[] getIds() { + return ID; + } + +} diff --git a/Server/src/main/content/region/misthalin/draynor/handlers/ManorFountainDialogue.java b/Server/src/main/content/region/misthalin/draynor/handlers/ManorFountainDialogue.java new file mode 100644 index 0000000..2ef3894 --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/handlers/ManorFountainDialogue.java @@ -0,0 +1,97 @@ +package content.region.misthalin.draynor.handlers; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.combat.ImpactHandler.HitsplatType; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItemManager; +import core.plugin.Initializable; +import core.game.node.item.Item; + +/** + * Represents the dialogue that handles the draynor manor fountain. + * @author 'Vexia + * @date 24/12/2013 + */ +@Initializable +public class ManorFountainDialogue extends DialoguePlugin { + + /** + * Represents the dialogue id of the fountain dialogue. + */ + public static final int DIALOGUE_ID = 3954922; + + /** + * Represents the pressure gauge item. + */ + private static final Item PRESSURE_GAUGE = new Item(271); + + /** + * Constructs a new {@code ManorFountainDialogue} {@code Object}. + */ + public ManorFountainDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code ManorFountainDialogue} {@code Object}. + * @param player the player. + */ + public ManorFountainDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new ManorFountainDialogue(player); + } + + @Override + public boolean open(Object... args) { + if (player.getAttribute("pressure-gauge", false) && player.getInventory().containsItem(PRESSURE_GAUGE)) { + interpreter.sendDialogues(player, null, "It's full of dead fish!"); + stage = 5; + return true; + } + interpreter.sendDialogues(player, null, "There seems to be a pressure gauge in here..."); + stage = player.getAttribute("piranhas-killed", false) ? 3 : 1; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 1: + player.getImpactHandler().manualHit(player, 1, HitsplatType.NORMAL); + player.sendChat("Ow!"); + interpreter.sendDialogues(player, null, "... and a lot of piranhas!", "I can't get the guage out."); + stage = 2; + break; + case 2: + end(); + break; + case 3: + interpreter.sendDialogues(player, null, "... and a lot of dead fish."); + stage = 4; + break; + case 4: + if (!player.getInventory().add(PRESSURE_GAUGE)) { + GroundItemManager.create(PRESSURE_GAUGE, player); + } + player.getPacketDispatch().sendMessage("You get the pressure gauge from the fountain."); + player.setAttribute("/save:pressure-gauge", true); + end(); + break; + case 5: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 3954922 }; + } +} diff --git a/Server/src/main/content/region/misthalin/draynor/handlers/WiseOldManHouseListener.kt b/Server/src/main/content/region/misthalin/draynor/handlers/WiseOldManHouseListener.kt new file mode 100644 index 0000000..3e46f8f --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/handlers/WiseOldManHouseListener.kt @@ -0,0 +1,71 @@ +package content.region.misthalin.draynor.handlers + +import core.api.addItem +import core.api.inInventory +import core.api.sendMessage +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import org.rs09.consts.Items +import org.rs09.consts.Scenery + +class WiseOldManHouseListener : InteractionListener { + + // Searching the bookshelves in the Wise Old Man's house + + override fun defineListeners() { + + // All shelves in the room + val bookshelves = intArrayOf( + Scenery.OLD_BOOKSHELF_7058, Scenery.OLD_BOOKSHELF_7071, + Scenery.OLD_BOOKSHELF_7072, Scenery.OLD_BOOKSHELF_7073, + Scenery.OLD_BOOKSHELF_7074, Scenery.OLD_BOOKSHELF_7076, + Scenery.OLD_BOOKSHELF_7077, Scenery.OLD_BOOKSHELF_7078, + Scenery.OLD_BOOKSHELF_7079, Scenery.OLD_BOOKSHELF_7081, + Scenery.OLD_BOOKSHELF_7082, Scenery.OLD_BOOKSHELF_7089, + Scenery.OLD_BOOKSHELF_9146, Scenery.OLD_BOOKSHELF_9147, + ) + + // Shelves contains unique books + val containBookshelf = intArrayOf( + Scenery.OLD_BOOKSHELF_7065, // STRANGE BOOK + Scenery.OLD_BOOKSHELF_7066, // FOLKLORE BOOK + Scenery.OLD_BOOKSHELF_7068, // CHICKEN BOOK + ) + + val strangeBook = Items.STRANGE_BOOK_5507 + val folkloreBook = Items.BOOK_OF_FOLKLORE_5508 + val chickenBook = Items.BOOK_ON_CHICKENS_7464 + + + on(Scenery.OLD_BOOKSHELF_7065, IntType.SCENERY, "search") { player, _ -> + if (!inInventory(player, strangeBook)) { + sendMessage(player, "You search the bookcase and find a book named 'Strange Book'.") + addItem(player, strangeBook) + } else { + sendMessage(player, "You search the bookcase and find nothing of interest.") + } + return@on true + } + + on(Scenery.OLD_BOOKSHELF_7066, IntType.SCENERY, "search") { player, _ -> + if (!inInventory(player, folkloreBook)) { + sendMessage(player, "You search the bookcase and find a book named 'Book of folklore'.") + addItem(player, folkloreBook) + } else { + sendMessage(player, "You search the bookcase and find nothing of interest.") + } + return@on true + } + + on(Scenery.OLD_BOOKSHELF_7068, IntType.SCENERY, "search") { player, _ -> + if (!inInventory(player, chickenBook)) { + sendMessage(player, "You search the bookcase and find a book named 'Book on chickens'.") + addItem(player, chickenBook) + } else { + sendMessage(player, "You search the bookcase and find nothing of interest.") + } + return@on true + } + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/draynor/quest/anma/AliceDialogue.java b/Server/src/main/content/region/misthalin/draynor/quest/anma/AliceDialogue.java new file mode 100644 index 0000000..0d81ec4 --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/quest/anma/AliceDialogue.java @@ -0,0 +1,311 @@ +package content.region.misthalin.draynor.quest.anma; + +import content.data.Quests; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; + +/** + * Handles the alice npc dialogue. + * @author Vexia + */ +public final class AliceDialogue extends DialoguePlugin { + + /** + * The quest. + */ + private Quest quest; + + /** + * Constructs a new {@code AliceDialogue} {@code Object}. + */ + public AliceDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code AliceDialogue} {@code Object}. + * @param player the player. + */ + public AliceDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new AliceDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + quest = player.getQuestRepository().getQuest(Quests.ANIMAL_MAGNETISM); + switch (quest.getStage(player)) { + default: + options("What are you selling?", "I'm okay, thank you."); + break; + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + options("What are you selling?", "I'm okay, thank you.", "I'm here about a quest."); + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (quest.getStage(player)) { + default: + switch (stage) { + case 0: + switch (buttonId) { + case 1: + end(); + npc.openShop(player); + break; + case 2: + player("I'm okay, thank you."); + stage++; + break; + } + break; + case 1: + end(); + break; + } + break; + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + switch (stage) { + case 0: + switch (buttonId) { + case 1: + end(); + npc.openShop(player); + break; + case 2: + player("I'm okay, thank you."); + stage++; + break; + case 3: + player("I'm here about a quest."); + stage = 2; + break; + } + break; + case 1: + end(); + break; + default: + handleQuest(buttonId); + break; + } + break; + } + return true; + } + + /** + * Handles a quest stage. + * @param buttonId the buttonId. + */ + private void handleQuest(int buttonId) { + switch (quest.getStage(player)) { + case 10: + switch (stage) { + case 2: + player("I am after one of your, er, unhealthier poultry. Could", "you help me?"); + stage++; + break; + case 3: + npc("You need those useless, undead chickens? How odd you", "adventurers are."); + stage++; + break; + case 4: + npc("You need to talk to my husband though - not that I", "can these days."); + stage++; + break; + case 5: + player("Whyever would this be?"); + stage++; + break; + case 6: + npc("Can't you see, he is dead. I can't talk to the dead."); + stage++; + break; + case 7: + end(); + break; + } + break; + case 11: + switch (stage) { + case 2: + player("I have a message from your husband. He wants you to", "know that he still loves you, despite his ghostly state."); + stage++; + break; + case 3: + npc("The curse of undeath was so cruel; all the men out", "here succumbed, but Lyra and I were left alive."); + stage++; + break; + case 4: + npc("Ever since that day, I've not been able to speak to him."); + stage++; + break; + case 5: + npc("Tell him I love him but I can't find our savings. I", "know he had our collection of gold and 'prize cow'", "rosettes just before the curse struck."); + stage++; + break; + case 6: + player("I'll have a word with him then; magic has its uses I", "suppose."); + stage++; + break; + case 7: + quest.setStage(player, 12); + end(); + break; + } + break; + case 12: + switch (stage) { + case 2: + npc("Have you spoken to my husband yet?"); + stage++; + break; + case 3: + player("I'm working on it."); + stage++; + break; + case 4: + end(); + break; + } + break; + case 13: + switch (stage) { + case 2: + player("Your husband say he put the cash in the bank."); + stage++; + break; + case 3: + npc("I'll need his bank pass, in that case."); + stage++; + break; + case 4: + player("Can't you just take a ghostspeak amulet? Then you", "could talk to him directly?"); + stage++; + break; + case 5: + npc("I tried that once, but all those other ghosts - and even", "the undead chickens and cows - scared me so much. I", "wouldn't try it again for all the cash in Varrock bank."); + stage++; + break; + case 6: + quest.setStage(player, 14); + end(); + break; + } + break; + case 14: + switch (stage) { + case 2: + npc("Have you asked him about the bank pass?"); + stage++; + break; + case 3: + player("Not yet."); + stage++; + break; + case 4: + end(); + break; + } + break; + case 15: + switch (stage) { + case 2: + player("He says he won't trust me with the bank pass."); + stage++; + break; + case 3: + player("What if I gave some sort of altered ghostspeak amulet", "to him - surely that would work?"); + stage++; + break; + case 4: + npc("You're so clever; I've overheard passing adventurers", "say that there's some witch near here who changes", "ghostspeak amulets."); + stage++; + break; + case 5: + npc("I think she lives a bit west of that mad Professor", "Frenksomething, past the Farming patch."); + stage++; + break; + case 6: + player("I'll see if I can find her. Big nose and a monstrous hat", "I assume? I wonder where the beautiful young witches", "hide..."); + stage++; + break; + case 7: + npc("Mysterious indeed, but in this case she actually looks", "preety normal."); + stage++; + break; + case 8: + quest.setStage(player, 16); + end(); + break; + } + break; + case 16: + case 17: + switch (stage) { + case 2: + npc("Have you found a way for me to talk to my husband", "yet?"); + stage++; + break; + case 3: + player("I've not progressed at all, I'm afraid."); + stage++; + break; + case 4: + end(); + break; + } + break; + case 18: + switch (stage) { + case 2: + npc("Have you handed him an enhanced amulet?"); + stage++; + break; + case 3: + player("I Have obtained the amulet; I just haven't handed it", "over yet. So, it's looking good!"); + stage++; + break; + case 4: + end(); + break; + } + break; + } + } + + @Override + public int[] getIds() { + return new int[] { 2307 }; + } + +} diff --git a/Server/src/main/content/region/misthalin/draynor/quest/anma/AliceHusbandDialogue.java b/Server/src/main/content/region/misthalin/draynor/quest/anma/AliceHusbandDialogue.java new file mode 100644 index 0000000..b584565 --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/quest/anma/AliceHusbandDialogue.java @@ -0,0 +1,427 @@ +package content.region.misthalin.draynor.quest.anma; + +import content.data.Quests; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import content.region.misthalin.draynor.quest.anma.AnmaCutscene; +import org.rs09.consts.Items; + +/** + * Handles the husband of alice's npc dialogue. + * @author Vexia + */ +public final class AliceHusbandDialogue extends DialoguePlugin { + + /** + * The quest. + */ + private Quest quest; + + /** + * Constructs a new {@code AliceHusbandDialogue} {@code Object}. + */ + public AliceHusbandDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code AliceHusbandDialogue} {@code Object}. + * @param player the player. + */ + public AliceHusbandDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new AliceHusbandDialogue(player); + } + + @Override + public void init() { + super.init(); + } + + @Override + public boolean open(Object... args) { + if (!player.getEquipment().containsAtLeastOneItem(Items.GHOSTSPEAK_AMULET_552)) { + npc("Wooo wooo wooooo!"); + return true; + } + quest = player.getQuestRepository().getQuest(Quests.ANIMAL_MAGNETISM); + switch (quest.getStage(player)) { + case 0: + npc("Hi, I don't feel like talking."); + break; + case 10: + player("Your animals don't look too healthy."); + break; + case 11: + npc("'Ave you talked to the wife for me?"); + break; + case 12: + player("Your wife says she needs the family cash and wants to", "know what you did with it."); + stage++; + break; + case 13: + npc("Any luck wiv me wife?"); + break; + case 14: + case 15: + npc("'Ave you talked to 'er?"); + break; + case 16: + case 17: + case 18: + player("I talked to your wife and thought that if you had a", "special amulet, you could speak to her and sort out the", "bank situation without me being involved."); + break; + case 19: + npc("Ahh, many thanks. Now what was it you were wanting", "again?"); + break; + default: + npc("Hello, how can I help you? I'm sellin' if you have ecto-", "tokens."); + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + if (!player.getEquipment().containsAtLeastOneItem(Items.GHOSTSPEAK_AMULET_552)) { + end(); + return true; + } + switch (quest.getStage(player)) { + default: + switch (stage) { + case 0: + options("Could I buy those chickens now, then?", "Your animals don't look too healthy.", "I'm okay, thank you.", "Where can I get these ecto-tokens?"); + stage++; + break; + case 1: + switch (buttonId) { + case 1: + player("Could I buy those chickens now, then?"); + stage = 10; + break; + case 2: + player("Your animals don't look too healthy."); + stage = 20; + break; + case 3: + player("I'm okay, thank you."); + stage = 30; + break; + case 4: + player("Where can I get these ecto-tokens?"); + stage = 40; + break; + } + break; + case 10: + npc("I can hand over a chicken if you give me 10 of them", "ecto-token thingies per bird."); + stage++; + break; + case 11: + options("Could I buy 1 chicken now?", "Could I buy 2 chickens now?", "Your animals don't look too healthy; I'll buy elsewhere."); + stage++; + break; + case 12: + switch (buttonId) { + case 1: + player("Could I buy 1 chicken now?"); + stage = 14; + break; + case 2: + player("Could I buy 2 chickens now?"); + stage = 15; + break; + case 3: + player("Your animals don't look too healthy; I'll buy elsewhere."); + stage++; + break; + } + break; + case 13: + end(); + break; + case 14: + case 15: + buy(stage == 14 ? 1 : 2); + stage = 16; + break; + case 16: + end(); + break; + case 20: + npc("It's that fountain thingy in the temple to the east. It's", "turned them all into zombies."); + stage++; + break; + case 21: + player("What use are zombie animals?"); + stage++; + break; + case 22: + npc("None at all, mate, except that those worshippers at that", "temple keep comin' and killin' em all for their bones.", "Don't ask me why."); + stage++; + break; + case 23: + player("But you're a ghost - surely you know", "something about it."); + stage++; + break; + case 24: + npc("I don't know nuthin' about nuthin'. Oim a simple ghost", "with simple needs. All I know is, years ago, that temple", "started glowing green and, a few months later, I woke", "up dead. That's all there is to it."); + stage++; + break; + case 25: + end(); + break; + case 30: + end(); + break; + case 40: + npc("The ghosts I talk to say that the tokens have something", "to do with the tower just east of here. If you need to", "collect some I'd try there."); + stage++; + break; + case 41: + end(); + break; + } + break; + case 0: + switch (stage) { + default: + end(); + break; + } + break; + case 10: + switch (stage) { + case 0: + npc("It's that fountain thingy in the temple to the east. It's", "turned them all into zombies."); + stage++; + break; + case 1: + player("What use are zombie animals?"); + stage++; + break; + case 2: + npc("None at all, mate, except that those worshippers at that", "temple keep comin' and killin' em all for their bones.", "Don't ask me why."); + stage++; + break; + case 3: + player("But you're a ghost - surely you know", "something about it."); + stage++; + break; + case 4: + npc("I don't know nuthin' about nuthin'. Oim a simple ghost", "with simple needs. All I know is, years ago, that temple", "started glowing green and, a few months later, I woke", "up dead. That's all there is to it."); + stage++; + break; + case 5: + npc("I do miss the wife though; tell 'er I still loves her."); + stage++; + break; + case 6: + player("Would I be able to buy some of your chickens?"); + stage++; + break; + case 7: + npc("Talk to my wife and I'll think about it."); + stage++; + break; + case 8: + if (quest.getStage(player) == 10) { + quest.setStage(player, 11); + } + end(); + break; + } + break; + case 11: + switch (stage) { + case 0: + player("Not yet; I've been distracted by the thought of undead", "cow milk."); + stage++; + break; + case 1: + end(); + break; + } + break; + case 12: + switch (stage) { + case 1: + npc("Tell 'er I spent it on cheap spirits, har har."); + stage++; + break; + case 2: + player("Your sense of humour died too, it seems..."); + stage++; + break; + case 3: + npc("Hah, just trying to lift your spirits."); + stage++; + break; + case 4: + player("I rest my case."); + stage++; + break; + case 5: + npc("Suit yerself, stick-in-the-mud. Anyway, Oim not one o'", "them yokels. Tell 'er I putted the cash in the bank like", "she always told me to."); + stage++; + break; + case 6: + npc("A warning to ya, too; annoy her and I'll haunt ya till", "yer hair turns white."); + stage++; + break; + case 7: + quest.setStage(player, 13); + end(); + break; + } + break; + case 13: + switch (stage) { + case 0: + player("Nothing new, no."); + stage++; + break; + case 1: + end(); + break; + } + break; + case 14: + switch (stage) { + case 0: + player("You may not believe me, but she wants me to find", "your bank pass now."); + stage++; + break; + case 1: + npc("Maybe she said that, maybe she didn't. I think you're", "just after me savings. Tell 'er that no one but a fool", "gives away their pass numbers."); + stage++; + break; + case 2: + npc("Go tell 'er now, if you're not a double-dealing' scammer,", "that is."); + stage++; + break; + case 3: + quest.setStage(player, 15); + end(); + break; + } + break; + case 15: + switch (stage) { + case 0: + player("Not since we last spoke."); + stage++; + break; + case 1: + end(); + break; + } + break; + case 16: + case 17: + case 18: + switch (stage) { + case 0: + npc("Arr, that makes far more sense than I was expecting", "from a muscle-head like you. My wife's a clever one."); + stage++; + break; + case 1: + if (player.getInventory().containsItem(AnimalMagnetism.CRONE_AMULET)) { + player("Well... oh, never mind. I'm desperate enough for those", "chickens to let that pass."); + stage += 2; + break; + } + player("Well...oh, never mind. I'm working on getting the", "amulet anyway."); + stage++; + break; + case 2: + end(); + break; + case 3: + npc("Give me that amulet, then, and we'll be seeing about", "your unnatural desire for chickens."); + stage++; + break; + case 4: + player("Okay, you need it more than I do, I suppose."); + stage++; + break; + case 5: + npc("Ta, mate."); + stage++; + break; + case 6: + player("Lucky we had such a brilliant idea."); + stage++; + break; + case 7: + if (player.getInventory().remove(AnimalMagnetism.CRONE_AMULET)) { + quest.setStage(player, 19); + end(); + } + break; + } + break; + case 19: + switch (stage) { + case 0: + player("I need a couple of your chickens."); + stage++; + break; + case 1: + npc("Chickens is tricksy, 'specially dead 'uns. I'll have to catch", "'em for ye."); + stage++; + break; + case 2: + player("They look preety pathetic, how hard can it be?"); + stage++; + break; + case 3: + npc("Stand back while I catches 'em, ya city slicker."); + stage++; + break; + case 4: + end(); + new AnmaCutscene(player).start(); + break; + } + break; + } + return true; + } + + /** + * Buys an undead chicken(s). + * @param amount the amount. + */ + private void buy(int amount) { + final Item tokens = new Item(4278, amount * 10); + if (!player.getInventory().containsItem(tokens)) { + npc("I'm not a charity here, ya know. Bad enough all you", "cow-killing folks are a'slaughterin' me beasts. Come back", "when ya have enough tokens."); + return; + } + if (player.getInventory().freeSlots() < amount) { + player("Sorry, I don't have enough inventory space."); + return; + } + if (player.getInventory().remove(tokens)) { + player.getInventory().add(new Item(10487, amount), player); + npc("Great! I'm laying away me tokens for some killer cows.", "That'll learn them bones rustlers."); + } + } + + @Override + public int[] getIds() { + return new int[] { 5202 }; + } + +} diff --git a/Server/src/main/content/region/misthalin/draynor/quest/anma/AnimalMagnetism.java b/Server/src/main/content/region/misthalin/draynor/quest/anma/AnimalMagnetism.java new file mode 100644 index 0000000..a04a6c9 --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/quest/anma/AnimalMagnetism.java @@ -0,0 +1,265 @@ +package content.region.misthalin.draynor.quest.anma; + +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import core.plugin.ClassScanner; + +import content.region.misthalin.draynor.quest.anma.AnimalMagnetismPlugin.ContainerHandler; +import content.region.misthalin.draynor.quest.anma.AnimalMagnetismPlugin.HammerMagnetPlugin; +import content.region.misthalin.draynor.quest.anma.AnimalMagnetismPlugin.ResearchNoteHandler; +import core.plugin.Initializable; +import content.region.misthalin.draynor.quest.anma.AnimalMagnetismPlugin.UndeadTreePlugin; +import content.data.Quests; + +/** + * Handles the animal magnetism quest. + * @author Vexia + */ +@Initializable +public final class AnimalMagnetism extends Quest { + /** + * The crone made amulet item. + */ + public static final Item CRONE_AMULET = new Item(10500); + + /** + * The selected iron item. + */ + public static final Item SELECTED_IRON = new Item(10488); + + /** + * The bar magnet item. + */ + public static final Item BAR_MAGNET = new Item(10489); + + /** + * The undead twigs item. + */ + public static final Item UNDEAD_TWIGS = new Item(10490); + + /** + * The blessed axe item. + */ + public static final Item BLESSED_AXE = new Item(10491); + + /** + * The research notes. + */ + public static final Item RESEARCH_NOTES = new Item(10492); + + /** + * The translated notes. + */ + public static final Item TRANSLATED_NOTES = new Item(10493); + + /** + * The pattern item. + */ + public static final Item PATTERN = new Item(10494); + + /** + * The container item. + */ + public static final Item CONTAINER = new Item(10495); + + /** + * The polished items. + */ + public static final Item POLISHED_BUTTONS = new Item(10496); + + /** + * The hard leather item. + */ + public static final Item HARD_LEATHER = new Item(1743); + + /** + * The avas attractor item. + */ + public static final Item AVAS_ATTRACTOR = new Item(10498); + + /** + * The avas accumulator item. + */ + public static final Item AVAS_ACCUMULATOR = new Item(10499); + + /** + * The requirements messages. + */ + private static final String[] REQS = new String[] { "I must have completed Restless Ghost.", "I must have completed Ernest the Chicken", "I must have completed Priest in Peril.", "Level 30 Ranged", "Level 18 Slayer", "Level 19 Crafting", "Level 35 Woodcutting" }; + + /** + * The requirements. + */ + private boolean[] requirements = new boolean[7]; + + /** + * Constructs a new {@code AnimalMagnetism} {@code Object}. + */ + public AnimalMagnetism() { + super(Quests.ANIMAL_MAGNETISM, 33, 32, 1); + } + + @Override + public Quest newInstance(Object object) { + ClassScanner.definePlugin(new AvaDialogue()); + ClassScanner.definePlugin(new AliceDialogue()); + ClassScanner.definePlugin(new WitchDialogue()); + ClassScanner.definePlugin(new ContainerHandler()); + ClassScanner.definePlugin(new UndeadTreePlugin()); + ClassScanner.definePlugin(new HammerMagnetPlugin()); + ClassScanner.definePlugin(new ResearchNoteHandler()); + ClassScanner.definePlugin(new AliceHusbandDialogue()); + ClassScanner.definePlugin(new AnimalMagnetismPlugin()); + return this; + } + + @Override + public void drawJournal(Player player, int stage) { + super.drawJournal(player, stage); + switch (stage) { + case 0: + line(player, "I can start this quest by talking to", 4+ 7); + line(player, "Ava who lives in Draynor Manor.", 5+ 7); + line(player, "Minimum requirements:", 7+ 7); + drawRequirements(player); + break; + case 10: + line(player, "Ava has asked me for undead chickens. One will go toward

making her bed more comfortable, the other will be used in

some unexplained reward for me.

I need to find someone who will supply undead chickens to

me. Perhaps the farm near Port Phasmatys sells them...", 4+ 7); + break; + case 11: + line(player, "Ava has asked me for undead chickens. One will go toward

making her bed more comfortable, the other will be used in

some unexplained reward for me.

I need to find someone who will supply undead chickens to

me. Perhaps the farm near Port Phasmatys sells them...

The ghost farmer wants me to talk to his wife for him. I

need to do this before he will sell chickens.", 11); + break; + case 12: + line(player, "Ava has asked me for undead chickens. One will go toward

making her bed more comfortable, the other will be used in

some unexplained reward for me.

I need to find someone who will supply undead chickens to

me. Perhaps the farm near Port Phasmatys sells them...

The ghost farmer wants me to talk to his wife for him. I

need to do this before he will sell chickens.

The ghost farmer's wife needs to know bank information

that only the farmer can supply.", 11); + break; + case 13: + line(player, "Ava has asked me for undead chickens. One will go toward

making her bed more comfortable, the other will be used in

some unexplained reward for me.

I need to find someone who will supply undead chickens to

me. Perhaps the farm near Port Phasmatys sells them...

The ghost farmer wants me to talk to his wife for him. I

need to do this before he will sell chickens.

The ghost farmer won't tell me the information his wife is

after. Perhaps I should talk to her again.", 11); + break; + case 14: + line(player, "Ava has asked me for undead chickens. One will go toward

making her bed more comfortable, the other will be used in

some unexplained reward for me.

I need to find someone who will supply undead chickens to

me. Perhaps the farm near Port Phasmatys sells them...

The ghost farmer wants me to talk to his wife for him. I

need to do this before he will sell chickens.

The ghost farmer's wife still needs to know bank

information that only the farmer can supply.", 11); + break; + case 15: + line(player, "Ava has asked me for undead chickens. One will go toward

making her bed more comfortable, the other will be used in

some unexplained reward for me.

I need to find someone who will supply undead chickens to

me. Perhaps the farm near Port Phasmatys sells them...

The ghost farmer wants me to talk to his wife for him. I

need to do this before he will sell chickens.

I still need to find a way to allow the undead farmer and his

wife to communicate with each other.", 11); + break; + case 16: + line(player, "Ava has asked me for undead chickens. One will go toward

making her bed more comfortable, the other will be used in

some unexplained reward for me.

I need to find someone who will supply undead chickens to

me. Perhaps the farm near Port Phasmatys sells them...

The ghost farmer wants me to talk to his wife for him. I

need to do this before he will sell chickens.

I should talk to the crone west of the undead farm and ask

about ghostspeak amulets. Perhaps she can enable the

ghost farmer to talk to his wife directly.", 11); + break; + case 17: + line(player, "Ava has asked me for undead chickens. One will go toward

making her bed more comfortable, the other will be used in

some unexplained reward for me.

I need to find someone who will supply undead chickens to

me. Perhaps the farm near Port Phasmatys sells them...

The ghost farmer wants me to talk to his wife for him. I

need to do this before he will sell chickens.

I should talk to the crone west of the undead farm and ask

about ghostspeak amulets. Perhaps she can enable the

ghost farmer to talk to his wife directly.

I need to talk the crone while I have a ghostspeak

amulet so that she can create a new amulet specifically

for the ghost farmer.", 11); + break; + case 18: + line(player, "Ava has asked me for undead chickens. One will go toward

making her bed more comfortable, the other will be used in

some unexplained reward for me.

I need to find someone who will supply undead chickens to

me. Perhaps the farm near Port Phasmatys sells them...

The ghost farmer wants me to talk to his wife for him. I

need to do this before he will sell chickens.

I should talk to the crone west of the undead farm and ask

about ghostspeak amulets. Perhaps she can enable the

ghost farmer to talk to his wife directly.

I need to talk the crone while I have a ghostspeak

amulet so that she can create a new amulet specifically

for the ghost farmer.

I should give the ghost farmer a crone-made amulet so

that he can talk directly to his wife.", 11); + break; + case 19: + line(player, "Ava has asked me for undead chickens. One will go toward

making her bed more comfortable, the other will be used in

some unexplained reward for me.

I need to find someone who will supply undead chickens to

me. Perhaps the farm near Port Phasmatys sells them...

The ghost farmer wants me to talk to his wife for him. I

need to do this before he will sell chickens.

I should talk to the crone west of the undead farm and ask

about ghostspeak amulets. Perhaps she can enable the

ghost farmer to talk to his wife directly.

I need to talk the crone while I have a ghostspeak

amulet so that she can create a new amulet specifically

for the ghost farmer.

I should give the ghost farmer a crone-made amulet so

that he can talk directly to his wife.

The farmer seems friendlier now; I need to talk to him

about the undead chickens.", 11); + break; + case 20: + line(player, "Ava has asked me for undead chickens. One will go toward

making her bed more comfortable, the other will be used in

some unexplained reward for me.

I need to find someone who will supply undead chickens to

me. Perhaps the farm near Port Phasmatys sells them...

The ghost farmer wants me to talk to his wife for him. I

need to do this before he will sell chickens.

I should talk to the crone west of the undead farm and ask

about ghostspeak amulets. Perhaps she can enable the

ghost farmer to talk to his wife directly.

I need to talk the crone while I have a ghostspeak

amulet so that she can create a new amulet specifically

for the ghost farmer.

I should give the ghost farmer a crone-made amulet so

that he can talk directly to his wife.

The farmer seems friendlier now; I need to talk to him

about the undead chickens.

The farmer has agreed to sell chickens; now he needs to

catch one for me.

The ghost farmer caught some chickens; now I need to buy

2 from him and deliver them to Ava.", 11); + break; + case 25: + line(player, "Ava has asked me for undead chickens. One will go toward

making her bed more comfortable, the other will be used in

some unexplained reward for me.

I need to find someone who will supply undead chickens to

me. Perhaps the farm near Port Phasmatys sells them...

The ghost farmer wants me to talk to his wife for him. I

need to do this before he will sell chickens.

I should talk to the crone west of the undead farm and ask

about ghostspeak amulets. Perhaps she can enable the

ghost farmer to talk to his wife directly.

I need to talk the crone while I have a ghostspeak

amulet so that she can create a new amulet specifically

for the ghost farmer.

I should give the ghost farmer a crone-made amulet so

that he can talk directly to his wife.

The farmer seems friendlier now; I need to talk to him

about the undead chickens.

The farmer has agreed to sell chickens; now he needs to

catch one for me.

The ghost farmer caught some chickens; now I need to buy

2 from him and deliver them to Ava.

I need to talk to the Witch in Draynor Manor about

magically attuned magnets. Apparently, the undead

chicken will be using magnets in my reward.", 11); + break; + case 26: + line(player, "Ava has asked me for undead chickens. One will go toward

making her bed more comfortable, the other will be used in

some unexplained reward for me.

I need to find someone who will supply undead chickens to

me. Perhaps the farm near Port Phasmatys sells them...

The ghost farmer wants me to talk to his wife for him. I

need to do this before he will sell chickens.

I should talk to the crone west of the undead farm and ask

about ghostspeak amulets. Perhaps she can enable the

ghost farmer to talk to his wife directly.

I need to talk the crone while I have a ghostspeak

amulet so that she can create a new amulet specifically

for the ghost farmer.

I should give the ghost farmer a crone-made amulet so

that he can talk directly to his wife.

The farmer seems friendlier now; I need to talk to him

about the undead chickens.

The farmer has agreed to sell chickens; now he needs to

catch one for me.

The ghost farmer caught some chickens; now I need to buy

2 from him and deliver them to Ava.

I need to talk to the Witch in Draynor Manor about

magically attuned magnets. Apparently, the undead

chicken will be using magnets in my reward

I need to deliver 5 iron bars to the Witch in Draynor Manor.

She will select one most suitable for both magnetising and

mystical use.", 11); + break; + case 27: + line(player, "Ava has asked me for undead chickens. One will go toward

making her bed more comfortable, the other will be used in

some unexplained reward for me.

I need to find someone who will supply undead chickens to

me. Perhaps the farm near Port Phasmatys sells them...

The ghost farmer wants me to talk to his wife for him. I

need to do this before he will sell chickens.

I should talk to the crone west of the undead farm and ask

about ghostspeak amulets. Perhaps she can enable the

ghost farmer to talk to his wife directly.

I need to talk the crone while I have a ghostspeak

amulet so that she can create a new amulet specifically

for the ghost farmer.

I should give the ghost farmer a crone-made amulet so

that he can talk directly to his wife.

The farmer seems friendlier now; I need to talk to him

about the undead chickens.

The farmer has agreed to sell chickens; now he needs to

catch one for me.

The ghost farmer caught some chickens; now I need to buy

2 from him and deliver them to Ava.

I need to talk to the Witch in Draynor Manor about

magically attuned magnets. Apparently, the undead

chicken will be using magnets in my reward

I need to deliver 5 iron bars to the Witch in Draynor Manor.

She will select one most suitable for both magnetising and

mystical use.

I need to make a magnet by hammering the selected iron

bar while facing north in Rimmington mines. I then need

to pass this magnet to Ava.", 11); + break; + case 28: + line(player, "Ava has asked me for undead chickens. One will go toward

making her bed more comfortable, the other will be used in

some unexplained reward for me.

I need to find someone who will supply undead chickens to

me. Perhaps the farm near Port Phasmatys sells them...

The ghost farmer wants me to talk to his wife for him. I

need to do this before he will sell chickens.

I should talk to the crone west of the undead farm and ask

about ghostspeak amulets. Perhaps she can enable the

ghost farmer to talk to his wife directly.

I need to talk the crone while I have a ghostspeak

amulet so that she can create a new amulet specifically

for the ghost farmer.

I should give the ghost farmer a crone-made amulet so

that he can talk directly to his wife.

The farmer seems friendlier now; I need to talk to him

about the undead chickens.

The farmer has agreed to sell chickens; now he needs to

catch one for me.

The ghost farmer caught some chickens; now I need to buy

2 from him and deliver them to Ava.

I need to talk to the Witch in Draynor Manor about

magically attuned magnets. Apparently, the undead

chicken will be using magnets in my reward

I need to deliver 5 iron bars to the Witch in Draynor Manor.

She will select one most suitable for both magnetising and

mystical use.

I need to make a magnet by hammering the selected iron

bar while facing north in Rimmington mines. I then need

to pass this magnet to Ava.

I need to chop some wood from the undead trees near

Draynor Manor. Ava can use this wood as a source of

unending arrow shafts in my reward. She suggested that I

use a Woodcutting axe made of nothing less powerful than

mithril.", 11); + break; + case 29: + line(player, "Ava has asked me for undead chickens. One will go toward

making her bed more comfortable, the other will be used in

some unexplained reward for me.

I need to find someone who will supply undead chickens to

me. Perhaps the farm near Port Phasmatys sells them...

The ghost farmer wants me to talk to his wife for him. I

need to do this before he will sell chickens.

I should talk to the crone west of the undead farm and ask

about ghostspeak amulets. Perhaps she can enable the

ghost farmer to talk to his wife directly.

I need to talk the crone while I have a ghostspeak

amulet so that she can create a new amulet specifically

for the ghost farmer.

I should give the ghost farmer a crone-made amulet so

that he can talk directly to his wife.

The farmer seems friendlier now; I need to talk to him

about the undead chickens.

The farmer has agreed to sell chickens; now he needs to

catch one for me.

The ghost farmer caught some chickens; now I need to buy

2 from him and deliver them to Ava.

I need to talk to the Witch in Draynor Manor about

magically attuned magnets. Apparently, the undead

chicken will be using magnets in my reward

I need to deliver 5 iron bars to the Witch in Draynor Manor.

She will select one most suitable for both magnetising and

mystical use.

I need to make a magnet by hammering the selected iron

bar while facing north in Rimmington mines. I then need

to pass this magnet to Ava.

I need to find some way of chopping the undead trees

near Draynor Manor so that Ava can use this wood as a

source of unending arrow shafts.

Perhaps Ava could give me some advice...", 11); + break; + case 30: + case 31: + line(player, "Ava has asked me for undead chickens. One will go toward

making her bed more comfortable, the other will be used in

some unexplained reward for me.

I need to find someone who will supply undead chickens to

me. Perhaps the farm near Port Phasmatys sells them...

The ghost farmer wants me to talk to his wife for him. I

need to do this before he will sell chickens.

I should talk to the crone west of the undead farm and ask

about ghostspeak amulets. Perhaps she can enable the

ghost farmer to talk to his wife directly.

I need to talk the crone while I have a ghostspeak

amulet so that she can create a new amulet specifically

for the ghost farmer.

I should give the ghost farmer a crone-made amulet so

that he can talk directly to his wife.

The farmer seems friendlier now; I need to talk to him

about the undead chickens.

The farmer has agreed to sell chickens; now he needs to

catch one for me.

The ghost farmer caught some chickens; now I need to buy

2 from him and deliver them to Ava.

I need to talk to the Witch in Draynor Manor about

magically attuned magnets. Apparently, the undead

chicken will be using magnets in my reward

I need to deliver 5 iron bars to the Witch in Draynor Manor.

She will select one most suitable for both magnetising and

mystical use.

I need to make a magnet by hammering the selected iron

bar while facing north in Rimmington mines. I then need

to pass this magnet to Ava.

I need to find some way of chopping the undead trees

near Draynor Manor so that Ava can use this wood as a

source of unending arrow shafts.

Ava suspects that Turael, the Slayer Master in Burthorpe,

might be able to help.

I need to collect a holy symbol of Saradomin and a mithril

axe. Turael, the Burthorpe Slayer, can use these to

construct a new axe for my undead tree cutting.", 11); + break; + case 32: + line(player, "Ava has asked me for undead chickens. One will go toward

making her bed more comfortable, the other will be used in

some unexplained reward for me.

I need to find someone who will supply undead chickens to

me. Perhaps the farm near Port Phasmatys sells them...

The ghost farmer wants me to talk to his wife for him. I

need to do this before he will sell chickens.

I should talk to the crone west of the undead farm and ask

about ghostspeak amulets. Perhaps she can enable the

ghost farmer to talk to his wife directly.

I need to talk the crone while I have a ghostspeak

amulet so that she can create a new amulet specifically

for the ghost farmer.

I should give the ghost farmer a crone-made amulet so

that he can talk directly to his wife.

The farmer seems friendlier now; I need to talk to him

about the undead chickens.

The farmer has agreed to sell chickens; now he needs to

catch one for me.

The ghost farmer caught some chickens; now I need to buy

2 from him and deliver them to Ava.

I need to talk to the Witch in Draynor Manor about

magically attuned magnets. Apparently, the undead

chicken will be using magnets in my reward

I need to deliver 5 iron bars to the Witch in Draynor Manor.

She will select one most suitable for both magnetising and

mystical use.

I need to make a magnet by hammering the selected iron

bar while facing north in Rimmington mines. I then need

to pass this magnet to Ava.

I need to find some way of chopping the undead trees

near Draynor Manor so that Ava can use this wood as a

source of unending arrow shafts.

Ava suspects that Turael, the Slayer Master in Burthorpe,

might be able to help.

I need to collect a holy symbol of Saradomin and a mithril

axe. Turael, the Burthorpe Slayer, can use these to

construct a new axe for my undead tree cutting.

I need to chop some undead wood with the silver-edged

mithril axe. Then Ava will want the wood for constructing

my reward.

I should ask Ava for the garbled research notes that she

cannot translate. When translated, these notes will tell

her how to combine the undead wood, undead chicken and

magnet into some bizarre device.", 11); + break; + case 33: + if (!player.hasItem(TRANSLATED_NOTES)) { + line(player, "Ava has asked me for undead chickens. One will go toward

making her bed more comfortable, the other will be used in

some unexplained reward for me.

I need to find someone who will supply undead chickens to

me. Perhaps the farm near Port Phasmatys sells them...

The ghost farmer wants me to talk to his wife for him. I

need to do this before he will sell chickens.

I should talk to the crone west of the undead farm and ask

about ghostspeak amulets. Perhaps she can enable the

ghost farmer to talk to his wife directly.

I need to talk the crone while I have a ghostspeak

amulet so that she can create a new amulet specifically

for the ghost farmer.

I should give the ghost farmer a crone-made amulet so

that he can talk directly to his wife.

The farmer seems friendlier now; I need to talk to him

about the undead chickens.

The farmer has agreed to sell chickens; now he needs to

catch one for me.

The ghost farmer caught some chickens; now I need to buy

2 from him and deliver them to Ava.

I need to talk to the Witch in Draynor Manor about

magically attuned magnets. Apparently, the undead

chicken will be using magnets in my reward

I need to deliver 5 iron bars to the Witch in Draynor Manor.

She will select one most suitable for both magnetising and

mystical use.

I need to make a magnet by hammering the selected iron

bar while facing north in Rimmington mines. I then need

to pass this magnet to Ava.

I need to find some way of chopping the undead trees

near Draynor Manor so that Ava can use this wood as a

source of unending arrow shafts.

Ava suspects that Turael, the Slayer Master in Burthorpe,

might be able to help.

I need to collect a holy symbol of Saradomin and a mithril

axe. Turael, the Burthorpe Slayer, can use these to

construct a new axe for my undead tree cutting.

I need to chop some undead wood with the silver-edged

mithril axe. Then Ava will want the wood for constructing

my reward.

I should ask Ava for the garbled research notes that she

cannot translate. When translated, these notes will tell

her how to combine the undead wood, undead chicken and

magnet into some bizarre device.

The research notes must be translated. I should try to

decipher them even though they look like total gibberish.

to me.", 11); + } else { + line(player, "Ava has asked me for undead chickens. One will go toward

making her bed more comfortable, the other will be used in

some unexplained reward for me.

I need to find someone who will supply undead chickens to

me. Perhaps the farm near Port Phasmatys sells them...

The ghost farmer wants me to talk to his wife for him. I

need to do this before he will sell chickens.

I should talk to the crone west of the undead farm and ask

about ghostspeak amulets. Perhaps she can enable the

ghost farmer to talk to his wife directly.

I need to talk the crone while I have a ghostspeak

amulet so that she can create a new amulet specifically

for the ghost farmer.

I should give the ghost farmer a crone-made amulet so

that he can talk directly to his wife.

The farmer seems friendlier now; I need to talk to him

about the undead chickens.

The farmer has agreed to sell chickens; now he needs to

catch one for me.

The ghost farmer caught some chickens; now I need to buy

2 from him and deliver them to Ava.

I need to talk to the Witch in Draynor Manor about

magically attuned magnets. Apparently, the undead

chicken will be using magnets in my reward

I need to deliver 5 iron bars to the Witch in Draynor Manor.

She will select one most suitable for both magnetising and

mystical use.

I need to make a magnet by hammering the selected iron

bar while facing north in Rimmington mines. I then need

to pass this magnet to Ava.

I need to find some way of chopping the undead trees

near Draynor Manor so that Ava can use this wood as a

source of unending arrow shafts.

Ava suspects that Turael, the Slayer Master in Burthorpe,

might be able to help.

I need to collect a holy symbol of Saradomin and a mithril

axe. Turael, the Burthorpe Slayer, can use these to

construct a new axe for my undead tree cutting.

I need to chop some undead wood with the silver-edged

mithril axe. Then Ava will want the wood for constructing

my reward.

I should ask Ava for the garbled research notes that she

cannot translate. When translated, these notes will tell

her how to combine the undead wood, undead chicken and

magnet into some bizarre device.

The research notes must be translated. I should try to

decipher them even though they look like total gibberish.

to me.

The notes look less confusing now. Ava will want to see

these translated research notes.", 11); + } + break; + case 34: + line(player, "Ava has asked me for undead chickens. One will go toward

making her bed more comfortable, the other will be used in

some unexplained reward for me.

I need to find someone who will supply undead chickens to

me. Perhaps the farm near Port Phasmatys sells them...

The ghost farmer wants me to talk to his wife for him. I

need to do this before he will sell chickens.

I should talk to the crone west of the undead farm and ask

about ghostspeak amulets. Perhaps she can enable the

ghost farmer to talk to his wife directly.

I need to talk the crone while I have a ghostspeak

amulet so that she can create a new amulet specifically

for the ghost farmer.

I should give the ghost farmer a crone-made amulet so

that he can talk directly to his wife.

The farmer seems friendlier now; I need to talk to him

about the undead chickens.

The farmer has agreed to sell chickens; now he needs to

catch one for me.

The ghost farmer caught some chickens; now I need to buy

2 from him and deliver them to Ava.

I need to talk to the Witch in Draynor Manor about

magically attuned magnets. Apparently, the undead

chicken will be using magnets in my reward

I need to deliver 5 iron bars to the Witch in Draynor Manor.

She will select one most suitable for both magnetising and

mystical use.

I need to make a magnet by hammering the selected iron

bar while facing north in Rimmington mines. I then need

to pass this magnet to Ava.

I need to find some way of chopping the undead trees

near Draynor Manor so that Ava can use this wood as a

source of unending arrow shafts.

Ava suspects that Turael, the Slayer Master in Burthorpe,

might be able to help.

I need to collect a holy symbol of Saradomin and a mithril

axe. Turael, the Burthorpe Slayer, can use these to

construct a new axe for my undead tree cutting.

I need to chop some undead wood with the silver-edged

mithril axe. Then Ava will want the wood for constructing

my reward.

I should ask Ava for the garbled research notes that she

cannot translate. When translated, these notes will tell

her how to combine the undead wood, undead chicken and

magnet into some bizarre device.

The research notes must be translated. I should try to

decipher them even though they look like total gibberish.

to me.

The notes look less confusing now. Ava will want to see

these translated research notes.

Almost finished! I must combine the pattern which Ava

gave to me with some polished buttons and a bit of hard

leather. Ava tells me that the H.A.M hideout is a good

place to obtain buttons.", 11); + // Almost finished! I must combine the pattern which + // Ava

gave to me with some polished buttons and a bit of + // hard

leather. Ava tells me that the H.A.M hideout is a + // good

place to obtain buttons. + break; + case 100: + line(player, "Ava has asked me for undead chickens. One will gotowards making her bed more comfortable, the other willbe used in some unexplained reward for me.I need to find someone who will supply undead chickens tome. Perhaps the farm near Port Phasmatys sells them...The ghost farmer wants me to talk to his wife for him. Ineed to do this before he will sell the chickens.I should talk to the crone west of the undead farm and askabout ghostspeak amulets. Perhaps she can enable theghost farmer to talk to his wife directly.I need to talk to the crone while I have a ghostspeakamulet so that she can create a new amulet specificallyfor the ghost farmer.I should give the ghost farmer a crone-made amulet sothat he can talk directly to his wife.The farmer seems friendlier now; I need to talk to himabout the undead chickens.The farmer has agreed to sell chickens; now he needs tocatch one for me.The ghost farmer caught some chickens;now I need to buy2 and deliver them to Ava.I need to talk to the Witch in Draynor Manor aboutmagically attuned magnets. Apparently, the undeadchicken will be using magnets in my reward.I need to deliver 5 iron bars to the Witch in Draynor Manor.She will select one most suitable for both magnetising andmystical use.I need to make a magnet by hammering the selected ironbar while facing north in Rimmington mines. I then needto pass this magnet to Ava.I need to find some way of chopping the undead treesnear Draynor manor so that Ava can use this wood as asource of unending arrow shafts.Ava suspects that Turael, the Slayer Master in Burthorpe,might be able to help.I need to collect a holy symbol of Saradomin and a mithrilaxe. Turael, the Burthorpe Slayer, can use these toconstruct a new axe for my undead tree cutting.I need to chop some undead wood with the silver edgedmithril axe. Then Ava will want the wood for constructingmy reward.I should ask Ava for the garbled research notes that shecannot translate. When translated, these notes will tellher how to combine the undead wood, undead chicken andmagnet into some bizarre device.The research notes must be translated. I should try todecipher them even though they look like total gibberishto me.The notes look less confusing now. Ava will want to see", 11); + line(player, "these translated research notes.Almost finished!I must combine the pattern which Avagave to me with some polished buttons and a bit of hardleather.Ava wants the completed container. She can then combineit with the undead chicken, undead wood and magnet.QUEST COMPLETE!Ava's reward for me is an arrow attracting and creatingbackpack.The method is this: the undead chicken can attract lost,stray arrowheads with a magnet, add wood from theundead twigs and then finish the arrows using its ownfeathers. This will give me an unending source of arrows.The cunning bird will also attract some of the arrows which Ihave fired, preventing these arrows from falling upon theground.If I lost my device, I can talk to Ava for a new one,although it will cost me around 1000 gold.Once I achieve a Ranger level of 50 or more, I can upgradethe attractor if I give Ava 75 steel arrows.", 63); + break; + } + } + + /** + * Draws the requirements. + */ + private void drawRequirements(Player player) { + hasRequirements(player); + int line = 8 + 7; + for (int i = 0; i < requirements.length; i++) { + line(player, (requirements[i] ? "" : "") + REQS[i], line++); + } + } + + @Override + public boolean hasRequirements(Player player) { + requirements[0] = player.getQuestRepository().isComplete(Quests.THE_RESTLESS_GHOST); + requirements[1] = player.getQuestRepository().isComplete(Quests.ERNEST_THE_CHICKEN); + requirements[2] = player.getQuestRepository().isComplete(Quests.PRIEST_IN_PERIL); + requirements[3] = player.getSkills().getStaticLevel(Skills.RANGE) >= 30; + requirements[4] = player.getSkills().getStaticLevel(Skills.SLAYER) >= 18; + requirements[5] = player.getSkills().getStaticLevel(Skills.CRAFTING) >= 19; + requirements[6] = player.getSkills().getStaticLevel(Skills.WOODCUTTING) >= 35; + for (boolean bool : requirements) { + if (!bool) { + return false; + } + } + return true; + } + + @Override + public void finish(Player player) { + super.finish(player); + Item item = player.getSkills().getStaticLevel(Skills.RANGE) >= 50 ? AVAS_ACCUMULATOR : AVAS_ATTRACTOR; + player.getPacketDispatch().sendString("1000 XP in each of Crafting,", 277, 8 + 2); + player.getPacketDispatch().sendString("Fletching and Slayer", 277, 9 +2); + player.getPacketDispatch().sendString("2500 Woodcutting XP", 277, 10 + 2); + player.getPacketDispatch().sendString("1 Quest Point", 277, 11 + 2); + player.getPacketDispatch().sendString("Ava's device", 277, 12 + 2); + player.getPacketDispatch().sendItemZoomOnInterface(item.getId(), 235, 277, 3 + 2); + player.getSkills().addExperience(Skills.CRAFTING, 1000); + player.getSkills().addExperience(Skills.SLAYER, 1000); + player.getSkills().addExperience(Skills.FLETCHING, 1000); + player.getSkills().addExperience(Skills.WOODCUTTING, 2500); + player.getInventory().add(item); + player.getQuestRepository().syncronizeTab(player); + } + + @Override + public int[] getConfig(Player player, int stage) { + if (getStage(player) >= 28 && getStage(player) != 100) { + return new int[] { 939, 150 }; + } + int val = stage < 100 && stage > 0 ? 10 : stage >= 100 ? 240 : 0; + return new int[] { 939, val }; + // This config affects object bed in ava's room + // multiples of 10 + // 0 - broken + // 170 - still broken + // 180 - bed is made + // 240 - quest complete + } + +} diff --git a/Server/src/main/content/region/misthalin/draynor/quest/anma/AnimalMagnetismPlugin.java b/Server/src/main/content/region/misthalin/draynor/quest/anma/AnimalMagnetismPlugin.java new file mode 100644 index 0000000..6156fe9 --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/quest/anma/AnimalMagnetismPlugin.java @@ -0,0 +1,435 @@ +package content.region.misthalin.draynor.quest.anma; + +import java.util.HashMap; +import java.util.Map; + +import core.cache.def.impl.ItemDefinition; +import core.cache.def.impl.NPCDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import content.data.skill.SkillingTool; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.OptionHandler; +import core.game.interaction.UseWithHandler; +import core.game.node.Node; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneBuilder; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; +import core.plugin.ClassScanner; +import core.tools.RandomFunction; + +import static core.api.ContentAPIKt.*; +import content.data.Quests; + +/** + * Handles the animal magnetism plugin. + * @author Vexia + */ +@Initializable +public final class AnimalMagnetismPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ItemDefinition.forId(688).getHandlers().put("option:polish", this); + ItemDefinition.forId(4251).getHandlers().put("option:empty", this); + ItemDefinition.forId(4251).getHandlers().put("option:drop", this); + ItemDefinition.forId(4252).getHandlers().put("option:drop", this); + NPCDefinition.forId(5198).getHandlers().put("option:trade", this); + SceneryDefinition.forId(5167).getHandlers().put("option:push", this); + AnimalMagnetism.RESEARCH_NOTES.getDefinition().getHandlers().put("option:translate", this); + ItemDefinition.forId(AnimalMagnetism.CRONE_AMULET.getId()).getHandlers().put("option:wear", this); + ItemDefinition.forId(AnimalMagnetism.CRONE_AMULET.getId()).getHandlers().put("option:equip", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + switch (node.getId()) { + case 5167: + if (!hasRequirement(player, Quests.CREATURE_OF_FENKENSTRAIN)) { + break; + } + player.teleport(new Location(3577, 9927)); + break; + case 5198: + case 5199: + if (player.getQuestRepository().getQuest(Quests.ANIMAL_MAGNETISM).getStage(player) == 0) { + player.getDialogueInterpreter().sendDialogues((NPC) node, null, "Hello there, I'm busy with my research. Come back in a", "bit, could you?"); + break; + } + node.asNpc().openShop(player); + break; + case 10500: + player.getPacketDispatch().sendMessage("Perhaps you should wait a few hundred years or so?"); + break; + case 10492: + open(player); + break; + case 688: + player.lock(1); + if (player.getSkills().getLevel(Skills.CRAFTING) < 3) { + player.getPacketDispatch().sendMessage("You need a Crafting level of at least 3 in order to do that."); + return true; + } + player.getSkills().addExperience(Skills.CRAFTING, 5, true); + player.getInventory().replace(AnimalMagnetism.POLISHED_BUTTONS, ((Item) node).getSlot()); + break; + } + return true; + } + + /** + * Clears the note cache. + * @param player the player. + */ + private void clearCache(Player player) { + player.removeAttribute("note-cache"); + player.removeAttribute("note-disabled"); + } + + /** + * Opens the interface. + * @param player the player. + */ + public void open(Player player) { + clearCache(player); + player.getInterfaceManager().open(new Component(480)); + player.getPacketDispatch().sendMessage("You fiddle with the notes."); + } + + /** + * Handles the hammering of a magnet. + * @author Vexia + */ + public static final class HammerMagnetPlugin extends UseWithHandler { + + /** + * The animation used when hammering a magnet. + */ + private static final Animation ANIMATION = new Animation(5365); + + /** + * Constructs a new {@code HammerMagnetPlugin} {@code Object}. + */ + public HammerMagnetPlugin() { + super(2347); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ZoneBuilder.configure(new MapZone("rimmington mine", true) { + @Override + public void configure() { + register(new ZoneBorders(2970, 3230, 2984, 3249)); + } + }); + addHandler(AnimalMagnetism.SELECTED_IRON.getId(), ITEM_TYPE, this); + return this; + } + + @Override + public boolean handle(final NodeUsageEvent event) { + final Player player = event.getPlayer(); + player.animate(ANIMATION); + player.lock(ANIMATION.getDefinition().getDurationTicks()); + GameWorld.getPulser().submit(new Pulse(ANIMATION.getDefinition().getDurationTicks(), player) { + @Override + public boolean pulse() { + if (!player.getZoneMonitor().isInZone("rimmington mine")) { + player.getPacketDispatch().sendMessage("You aren't in the right area for this to work."); + } else { + if (player.getDirection() != Direction.NORTH) { + player.getPacketDispatch().sendMessage("You think that facing North might work better."); + } else { + player.getInventory().replace(AnimalMagnetism.BAR_MAGNET, event.getUsedItem().getSlot()); + player.getPacketDispatch().sendMessage("You hammer the iron bar and create a magnet."); + } + } + return true; + } + }); + return true; + } + + } + + /** + * Handles the axe on a undead tree. + * @author Vexia + */ + public static final class UndeadTreePlugin extends UseWithHandler { + + /** + * The axe ids. + */ + private final int[] IDS = new int[] { 1355, 1357, 1359, 6739 }; + + /** + * Constructs a new {@code UndeadTreePlugin} {@code Object}. + */ + public UndeadTreePlugin() { + super(1355, 1357, 1359, 6739); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ClassScanner.definePlugin(new OptionHandler() { + @Override + public Plugin newInstance(Object arg) throws Throwable { + NPCDefinition.forId(5208).getHandlers().put("option:chop", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + final Quest quest = player.getQuestRepository().getQuest(Quests.ANIMAL_MAGNETISM); + if (quest.getStage(player) <= 28) { + SkillingTool tool = SkillingTool.getHatchet(player); + if (tool == null || tool.ordinal() < 4) { + player.getPacketDispatch().sendMessage("You don't have the required axe in order to do that."); + return true; + } + final Animation animation = getAnimation(tool.getId()); + player.animate(animation, 2); + if (quest.getStage(player) == 28) { + quest.setStage(player, 29); + } + player.sendMessage("The axe bounces off the undead wood." + (quest.getStage(player) == 28 || quest.getStage(player) == 29 ? " I should report this to Ava." : "")); + return true; + } + if (player.getInventory().freeSlots() < 1) { + player.sendMessage("Your inventory is full right now."); + return true; + } + if (!player.getInventory().containsItem(AnimalMagnetism.BLESSED_AXE) && !player.getEquipment().containsItem(AnimalMagnetism.BLESSED_AXE)) { + player.getPacketDispatch().sendMessage("You need a blessed axe in order to do that."); + return true; + } + Animation animation = getAnimation(1355); + player.lock(animation.getDefinition().getDurationTicks()); + if (RandomFunction.random(10) < 3) { + player.sendMessage("You almost remove a suitable twig, but you don't quite manage it."); + } else { + player.getInventory().add(AnimalMagnetism.UNDEAD_TWIGS); + player.sendMessage("You cut some undead twigs."); + } + player.animate(animation, 2); + return true; + } + + }); + addHandler(5208, NPC_TYPE, this); + addHandler(152, NPC_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + final Animation animation = getAnimation(event.getUsedItem().getId()); + final Quest quest = player.getQuestRepository().getQuest(Quests.ANIMAL_MAGNETISM); + player.animate(animation, 2); + if (quest.getStage(player) == 28) { + quest.setStage(player, 29); + } + player.sendMessage("The axe bounces off the undead wood." + (quest.getStage(player) == 28 || quest.getStage(player) == 29 ? " I should report this to Ava." : "")); + return true; + } + + /** + * Gets the animation id. + * @param itemId the item id. + * @return {@code Animation} the animation. + */ + public Animation getAnimation(int itemId) { + for (int i = 0; i < IDS.length; i++) { + if (IDS[i] == itemId) { + return new Animation(5366 + i, Priority.HIGH); + } + } + return null; + } + } + + /** + * Handles the research note handler. + * @author Vexia + * @version 1.0 + */ + public static final class ResearchNoteHandler extends ComponentPlugin { + + /** + * The button ids. + */ + private final int[][] BUTTONS = new int[][] { { 40, 39, 6 }, { 42, 41, 3 }, { 44, 43, 7 }, { 46, 45, 8}, { 48, 47, 4 }, { 50, 49, 9 }, { 52, 51, 10 }, { 54, 53, 11 }, { 56, 55, 5 } }; + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.forId(480).setPlugin(this); + return this; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + if (player.getAttribute("note-disabled", false)) { + return true; + } + final Object[] data = getIndex(button); + final boolean toggled = (boolean) data[1]; + final int[] configs = getConfigs((int) data[0]); + final Quest quest = player.getQuestRepository().getQuest(Quests.ANIMAL_MAGNETISM); + player.getPacketDispatch().sendInterfaceConfig(480, configs[0], !toggled); + player.getPacketDispatch().sendInterfaceConfig(480, (int) data[2], toggled); + if (quest.getStage(player) == 33) { + setNoteCache(player, (int) data[0], !toggled); + if (isTranslated(player)) { + if (player.getInventory().remove(AnimalMagnetism.RESEARCH_NOTES)) { + player.setAttribute("note-disabled", true); + player.getInventory().add(AnimalMagnetism.TRANSLATED_NOTES); + player.getPacketDispatch().sendMessage("It suddenly all makes sense."); + } + } + } + return true; + } + + /** + * Sets the note in the cache. + * @param player the player. + * @param index the index. + * @param toggled if toggled. + */ + private void setNoteCache(Player player, int index, boolean toggled) { + Map cache = getNoteCache(player); + cache.put(index, toggled); + player.setAttribute("note-cache", cache); + } + + /** + * Checks if the notes are translated. + * @param player the player. + * @return {@code True} if so. + */ + private boolean isTranslated(Player player) { + Map cache = getNoteCache(player); + int[] correct = new int[] { 0, 2, 3, 5, 6, 7 }; + int[] wrong = new int[] { 1, 4, 8 }; + for (int i : correct) { + if (cache.get(i).booleanValue()) { + return false; + } + } + for (int i : wrong) { + if (!cache.get(i).booleanValue()) { + return false; + } + } + return true; + } + + /** + * Gets the note cache. + * @param player the player. + * @return the cache of toggled buttons. + */ + private Map getNoteCache(Player player) { + Map cache = player.getAttribute("note-cache", null); + if (cache == null) { + cache = new HashMap(); + for (int i = 0; i < BUTTONS.length; i++) { + cache.put(i, true); + } + } + return cache; + } + + + /** + * Gets the hidden config ids. + * @param index the index. + * @return the configs. + */ + private int[] getConfigs(int index) { + return new int[] { 21 + index, 0 }; + } + + /** + * Gets the index by the button id. + * @param buttonId the buttonId. + * @return the object data. + */ + private Object[] getIndex(int buttonId) { + for (int i = 0; i < BUTTONS.length; i++) { + for (int k = 0; k < BUTTONS[i].length - 1; k++) { + if (buttonId == BUTTONS[i][k]) { + return new Object[] { i, k == 0, BUTTONS[i][2] }; + } + } + } + return new Object[] { 0, true }; + } + } + + /** + * Handles the creating of a container. + * @author Vexia + */ + public static final class ContainerHandler extends UseWithHandler { + + /** + * Constructs a new {@code ContainerHandler} {@code Object}. + */ + public ContainerHandler() { + super(10496, 1743); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(AnimalMagnetism.PATTERN.getId(), ITEM_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + if (!player.getInventory().containsItem(AnimalMagnetism.HARD_LEATHER)) { + player.sendMessage("You need hard leather as well as these 2 items."); + return true; + } + if (!player.getInventory().containsItem(AnimalMagnetism.POLISHED_BUTTONS)) { + player.sendMessage("You need polished buttons as well as these 2 items."); + return true; + } + if (player.getInventory().remove(AnimalMagnetism.HARD_LEATHER, AnimalMagnetism.POLISHED_BUTTONS, AnimalMagnetism.PATTERN)) { + player.getInventory().add(AnimalMagnetism.CONTAINER); + } + return true; + } + + } + + @Override + public boolean isWalk(Player player, Node node) { + return !(node instanceof Item); + } + + @Override + public boolean isWalk() { + return false; + } +} diff --git a/Server/src/main/content/region/misthalin/draynor/quest/anma/AnmaCutscene.kt b/Server/src/main/content/region/misthalin/draynor/quest/anma/AnmaCutscene.kt new file mode 100644 index 0000000..da0a404 --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/quest/anma/AnmaCutscene.kt @@ -0,0 +1,204 @@ +package content.region.misthalin.draynor.quest.anma + +import core.api.* +import core.game.activity.Cutscene +import core.game.dialogue.FacialExpression +import core.game.node.entity.combat.ImpactHandler +import core.game.node.entity.player.Player +import core.game.world.map.Direction +import org.rs09.consts.Animations +import org.rs09.consts.NPCs +import content.data.Quests + +class AnmaCutscene(player: Player) : Cutscene(player) { + override fun setup() { + setExit(player.location.transform(0,0,0)) //create copy of player's location + loadRegion(14391) + addNPC(FARMER, 36, 9, Direction.EAST, 0) + addNPC(CHICKEN, 44, 10, Direction.WEST, 0) + addNPC(ALICE, 43, 5, Direction.WEST) + addNPC(COWKILLER, 52, 8, Direction.WEST) + addNPC(COW, 37, 8, Direction.WEST) + } + + override fun runStage(stage: Int) { + when (stage) { + 0 -> { + fadeToBlack() + timedUpdate(5) + } + 1 -> { + teleport(player, 46, 13) + face(player, getNPC(CHICKEN)!!.location) + face(getNPC(FARMER)!!, getNPC(CHICKEN)!!) + move(getNPC(FARMER)!!, 43, 10) + timedUpdate(5) + } + 2 -> { + fadeFromBlack() + moveCamera(48,16, 500) + rotateCamera(44, 0) + dialogueUpdate(FARMER, FacialExpression.NEUTRAL, "Here, chicky chicky!") + } + 3 -> { + move(getNPC(FARMER)!!, 44, 10) + animate(getNPC(FARMER)!!, ATTEMPT_CATCH) + move(getNPC(CHICKEN)!!, 45, 9) + timedUpdate(2) + } + 4 -> { + move(getNPC(FARMER)!!, 53, 8) + move(getNPC(CHICKEN)!!, 53, 8) + timedUpdate(10) + } + 5 -> { + move(getNPC(CHICKEN)!!, 47, 8) + timedUpdate(1) + } + 6 -> { + move(getNPC(FARMER)!!, 48, 8) + timedUpdate(8) + } + 7 -> { + move(getNPC(CHICKEN)!!, 45, 10) + animate(getNPC(FARMER)!!, ATTEMPT_CATCH) + timedUpdate(1) + } + 8 -> { + move(getNPC(FARMER)!!, 45, 10) + move(getNPC(CHICKEN)!!, 38, 10) + animate(getNPC(CHICKEN)!!, CHICKEN_JUMP) + timedUpdate(1) + } + 9 -> { + move(getNPC(FARMER)!!, 38, 10) + timedUpdate(9) + } + 10 -> { + face(player, getNPC(FARMER)!!.location) + dialogueUpdate(FARMER, FacialExpression.NEUTRAL, "Git 'ere yer pesky bird!") + } + 11 -> { + move(getNPC(FARMER)!!, 44, 10) + move(getNPC(CHICKEN)!!, 45, 10) + timedUpdate(8) + } + 12 -> { + animate(getNPC(FARMER)!!, ATTEMPT_CATCH) + animate(getNPC(CHICKEN)!!, CHICKEN_JUMP) + face(player, getNPC(CHICKEN)!!.location) + move(getNPC(CHICKEN)!!, 47, 7) + timedUpdate(3) + } + 13 -> { + move(getNPC(FARMER)!!, 52, 8) + timedUpdate(6) + } + 14 -> { + face(getNPC(CHICKEN)!!, getNPC(CHICKEN)!!.location.transform(0, 1, 0)) + timedUpdate(6) + } + 15 -> { + move(getNPC(CHICKEN)!!, 47, 11) + face(getNPC(COW)!!, getNPC(COW)!!.location.transform(Direction.EAST)) + timedUpdate(8) + } + 16 -> { + face(getNPC(CHICKEN)!!, getNPC(FARMER)!!.location) + teleport(getNPC(COW)!!, 41, 10) + dialogueUpdate(FARMER, FacialExpression.NEUTRAL, "Where'd she go?") + } + 17 -> { + setAttribute(getNPC(COWKILLER)!!, "1hko", true) + move(getNPC(COWKILLER)!!, 46, 9) + move(getNPC(COW)!!, 46, 10) + move(getNPC(FARMER)!!, 44, 10) + move(getNPC(ALICE)!!, 48, 8) + timedUpdate(11) + } + 18 -> { + face(getNPC(FARMER)!!, player.location) + face(player, getNPC(FARMER)!!.location) + move(getNPC(CHICKEN)!!, 45, 9) + dialogueUpdate(FARMER, FacialExpression.ANNOYED, "Git oof my laaaaaand!") + } + 19 -> { + face(getNPC(FARMER)!!, getNPC(ALICE)!!.location) + face(getNPC(ALICE)!!, getNPC(COWKILLER)!!.location) + dialogueUpdate(ALICE, FacialExpression.ANNOYED, "You heard my husband: leave now!") + } + 20 -> { + face(getNPC(ALICE)!!, getNPC(COWKILLER)!!.location) + face(getNPC(COWKILLER)!!, getNPC(ALICE)!!.location) + dialogueUpdate(COWKILLER, FacialExpression.HALF_THINKING, "Always the same, I can never get these animals to myself.") + } + 21 -> { + face(getNPC(COWKILLER)!!, getNPC(COW)!!.location) + animate(getNPC(COWKILLER)!!, ATTACK_ANIM) + impact(getNPC(COW)!!, 8, ImpactHandler.HitsplatType.NORMAL) + timedUpdate(3) + } + 22 -> { + dialogueUpdate(ALICE, FacialExpression.SAD, "You killed Bessie!") + } + 23 -> { + dialogueUpdate(COWKILLER, FacialExpression.FRIENDLY, "Buying cowhides and feathers - ahh, that chicken is next, feathers for me!") + } + 24 -> { + move(getNPC(COWKILLER)!!, 46, 10) + timedUpdate(3) + } + 25 -> { + animate(getNPC(COWKILLER)!!, Animations.HUMAN_BURYING_BONES_827) + timedUpdate(1) + } + 26 -> { + face(getNPC(COWKILLER)!!, getNPC(COWKILLER)!!.location.transform(-1,0,0)) + timedUpdate(2) + } + 27 -> { + face(getNPC(CHICKEN)!!, getNPC(CHICKEN)!!.location.transform(0,1,0)) + sendChat(getNPC(CHICKEN)!!, "Woo woo!") + timedUpdate(2) + } + 28 -> { + move(getNPC(CHICKEN)!!, 45, 10) + timedUpdate(2) + } + 29 -> { + animate(getNPC(COWKILLER)!!, ATTACK_ANIM) + animate(getNPC(CHICKEN)!!, CHICKEN_JUMP) + impact(getNPC(CHICKEN)!!, 0, ImpactHandler.HitsplatType.MISS) + timedUpdate(2) + } + 30 -> { + face(getNPC(CHICKEN)!!, getNPC(FARMER)!!) + face(getNPC(FARMER)!!, getNPC(CHICKEN)!!) + visualize(getNPC(FARMER)!!, GRAB_CHICKEN_ANIM, GRAB_CHICKEN_GFX) + timedUpdate(6) + } + 31 -> { + getNPC(CHICKEN)!!.clear() + playerDialogueUpdate(FacialExpression.FRIENDLY, "Well, that's one way to catch a chicken, I suppose.") + } + 32 -> { + end { + setQuestStage(player, Quests.ANIMAL_MAGNETISM, 20) + } + } + } + } + + companion object { + val FARMER = NPCs.ALICES_HUSBAND_5205 + val ALICE = NPCs.ALICE_5212 + val CHICKEN = NPCs.UNDEAD_CHICKEN_1692 + val COWKILLER = NPCs.COW1337KILLR_5210 + val COW = NPCs.UNDEAD_COW_5211 + val ATTEMPT_CATCH = 5377 + val ATTACK_ANIM = 2066 + val GRAB_CHICKEN_ANIM = 5376 + val GRAB_CHICKEN_GFX = 973 + val CHICKEN_JUMP = 5380 + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/draynor/quest/anma/AvaDialogue.java b/Server/src/main/content/region/misthalin/draynor/quest/anma/AvaDialogue.java new file mode 100644 index 0000000..bae10eb --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/quest/anma/AvaDialogue.java @@ -0,0 +1,769 @@ +package content.region.misthalin.draynor.quest.anma; + +import java.util.ArrayList; +import java.util.List; + +import content.data.Quests; +import core.game.container.Container; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import core.game.world.GameWorld; + +import static core.api.ContentAPIKt.*; + +/** + * Handles the ava npc dialogue. + * @author Vexia + */ +public final class AvaDialogue extends DialoguePlugin { + + /** + * The undead chicken items. + */ + private static final Item UNDEAD_CHICKENS = new Item(10487, 2); + + /** + * The quest. + */ + private Quest quest; + + /** + * Constructs a new {@code AvaDialogue} {@code Object}. + */ + public AvaDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code AvaDialogue} {@code Object}. + * @param player the player. + */ + public AvaDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new AvaDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + quest = player.getQuestRepository().getQuest(Quests.ANIMAL_MAGNETISM); + if (!quest.hasRequirements(player)) { + player.getPacketDispatch().sendMessage("She doesn't seem interested in talking to you."); + return false; + } + switch (quest.getStage(player)) { + case 0: + npc("Hello there and welcome to my humble abode. It's sadly", "rather more humble than I'd like, to be honest, although", "perhaps you can help with that?"); + break; + case 10: + npc("Do you need a reminder what you are supposed to do?", "I know you must have shiny beads distracting you, but", "it is an important job you are doing for me."); + break; + case 20: + npc("My spiritometric devices show that you have been in", "close contact with ghostly animals. Are we closer to", "success?"); + break; + case 25: + npc("Go and talk to the Witch next door. She'd talk the hind", "legs off a donkey but she can select the iron with which", "it is suitable for the chicken to interact."); + break; + case 27: + if (player.getInventory().containsItem(AnimalMagnetism.BAR_MAGNET)) { + player("I've manufactured the magnet; here it is."); + stage = 4; + } else { + player("I've talked to the Witch and now I've given her some", "iron bars."); + } + break; + case 28: + npc("So, what terrible hitch have you encountered now?"); + break; + case 29: + case 30: + player("Well, I tried to hack the trees with my axe, but it just", "bounced off the trunk! It did all seem all-too-convenient", "to work on the first try."); + break; + case 31: + if (player.getInventory().containsItem(AnimalMagnetism.UNDEAD_TWIGS)) { + player("I have that undead wood at last. Well, twigs anyway."); + stage++; + } else { + npc("Come back when you have undead wood..."); + } + break; + case 32: + player("I'd like to look at those research notes now, unless you", "have translated them without me?"); + break; + case 33: + if (player.getInventory().containsItem(AnimalMagnetism.TRANSLATED_NOTES)) { + player("I've translated the notes. See? I'm not just a thuggish", "moron like you seem to think."); + stage = 10; + break; + } + if (player.hasItem(AnimalMagnetism.RESEARCH_NOTES)) { + player("I have the notes but haven't translated them yet. Any", "hints?"); + } else { + player("I seem to have lost the research notes."); + stage = 4; + } + break; + case 34: + if (player.getInventory().containsItem(AnimalMagnetism.CONTAINER)) { + npc("Wow, great, now the arrow manufacturer is ready for", "use...there you are! Talk to me if you need more", "information later."); + stage = 20; + break; + } + if (player.hasItem(AnimalMagnetism.PATTERN)) { + player("So what do I do with this pattern again?"); + } else { + player("My pattern seems to have vanished from my pack...not", "my fault, of course."); + stage = 10; + } + break; + case 100: + npc("I'm busy with my newest research, so can't gossip too", "much. Are you after an upgrade to your device, or a", "new device, or some information, of would you like to", "see my goods for sale?"); + break; + default: + npc("How's the quest going?"); + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (quest.getStage(player)) { + case 0: + switch (stage) { + case 0: + player("I would be happy to make your home a better place."); + stage++; + break; + case 1: + npc("Yay, I didn't even have to talk about a reward; you're", "more gullible than most adventurers, that's for sure."); + stage++; + break; + case 2: + npc("Don't worry, though; I just need you to help fix this", "vile old bed for me. Then I'll find a suitable reward for", "you."); + stage++; + break; + case 3: + player("Great, will I be able to take a nap in it?"); + stage++; + break; + case 4: + npc("Don't be silly; everyone knows that true warriors don't", "ever sleep...or perform many other bodily functions, for", "that matter. I'll come up with something, though."); + stage++; + break; + case 5: + player("I'm not convinced by just a vague something; can you", "be a slight bit more inspiring in your offer?"); + stage++; + break; + case 6: + npc("I'll use one for my bed, then see what I can make", "from the other in the way of a reward. I have some", "ideas involving infinite feathers."); + stage++; + break; + case 7: + player("Very well then, I shall await my mystery prize with", "bated breath."); + stage++; + break; + case 8: + quest.start(player); + end(); + break; + } + break; + case 10: + switch (stage) { + case 0: + player("Yes, please."); + stage++; + break; + case 1: + npc("...And people say we scientists are absent minded..."); + stage++; + break; + case 2: + npc("You need to fetch 2 undead chickens for me to use in", "my redecoration. It's not rocket science."); + stage++; + break; + case 3: + player("Rocket?"); + stage++; + break; + case 4: + npc("If they existed, they would be like arrows but much,", "much bigger. Considering the mess you rangers make", "with small bits of sticks, we scientists have decided they", "don't exist. Now get chicken hunting."); + stage++; + break; + case 5: + end(); + break; + } + break; + case 20: + switch (stage) { + case 0: + if (player.getInventory().containsItem(UNDEAD_CHICKENS)) { + player("Here they are."); + stage = 2; + } else { + player("I'm still looking for undead chickens..."); + stage = 1; + } + break; + case 1: + end(); + break; + case 2: + npc("Amazing! Success! I can look forward to some good", "nights' sleep after all."); + stage++; + break; + case 3: + player("Can I ask exactly how an undead chicken will help you", "sleep?"); + stage++; + break; + case 4: + npc("Well, I need the feathers to make my bed more", "comfortable. A comfortable bed will help me sleep.", "Obvious, really."); + stage++; + break; + case 5: + player("Obvious, yes, but why on " + GameWorld.getSettings().getName() + " would you need", "an undead chicken when there are perfectly good live", "chickens just down the road?"); + stage++; + break; + case 6: + npc("Well, for a start, undead feathers are much cleaner", "than living ones; no dust mites or anything. Secondly, I", "always think of Ernest when I see a chicken, so my", "nerves can't take killing them."); + stage++; + break; + case 7: + player("Then why do I need a chicken for my reward; we", "already established that I don't use a bed?"); + stage++; + break; + case 8: + npc("Seeing as how you ranger types use so many feathers", "in your arrows, I was thinking I could harness an", "undead chicken to make an unending supply of arrow", "flights for you."); + stage++; + break; + case 9: + player("Beats chicken slaying or hanging around in fishing", "shops, I suppose. So, what next?"); + stage++; + break; + case 10: + npc("We'll need a magnet next, one with purely natural", "fields and made from a carefully selected iron bar. A", "firm impact when the iron is parallel to " + GameWorld.getSettings().getName() + "'s", "field will stabilise this field in the rod."); + stage++; + break; + case 11: + npc("Go and talk to the Witch next door."); + stage++; + break; + case 12: + if (player.getInventory().remove(UNDEAD_CHICKENS)) { + quest.setStage(player, 25); + end(); + } + break; + } + break; + case 25: + switch (stage) { + case 0: + npc("Despite my extensive studies, her years of experience", "make her better at instinctive magico-mystical", "interaction. Oh well, at least I'm cleverer, prettier and", "will have a better bed."); + stage++; + break; + case 1: + player("Okay, okay, you're great. Yes, I'll go and talk to her", "when you've finished praising yourself."); + stage++; + break; + case 2: + end(); + break; + } + break; + case 27: + switch (stage) { + case 0: + npc("I'm thrilled for you. What about my magnet?"); + stage++; + break; + case 1: + player("The process is subject to some unexpected delays."); + stage++; + break; + case 2: + npc("I can see now why Frenekstrain prefers to work with", "dead folk. It can't be more frustrating than working", "with you."); + stage++; + break; + case 3: + end(); + break; + case 4: + npc("Great stuff! with the Witch's influence within the", "magnet, the undead chicken can use this, I'm sure."); + stage++; + break; + case 5: + npc("The plan is that the chicken will operate the magnet to", "attract bits of iron and steel, maybe even your own", "recently fired arrows. There are plenty of totally lost", "arrowheads lying about in the Fields of " + GameWorld.getSettings().getName() + ", I"); + stage++; + break; + case 6: + npc("bet."); + stage++; + break; + case 7: + npc("In addition, arrows which you fire should be able to be", "attracted back to your quiver by cunning avian."); + stage++; + break; + case 8: + player("I begin to understand your plan. We've covered", "feathers and arrowheads now; what next?"); + stage++; + break; + case 9: + npc("We need a source of wood, but one which is spiritually", "active and can regenerate itself. That will save you", "some axework in the future."); + stage++; + break; + case 10: + npc("Try using a woodcutting axe on the pesky trees in the", "garden here, that ones that attack rather than the really", "dead ones. They are probably just the sort of thing we", "could use."); + stage++; + break; + case 11: + player("They will try to kill me, though, and I can't fight back!"); + stage++; + break; + case 12: + npc("Now you know how those poor guards feel when you", "hide behind mushrooms and fences and attack them", "from afar! Anyway, I reckon you'll need to try a", "mithril or better axe on the trees. At least the trees axe"); + stage++; + break; + case 13: + npc("pretty close."); + stage++; + break; + case 14: + if (player.getInventory().remove(AnimalMagnetism.BAR_MAGNET)) { + setVarp(player, 939, 150, true); + quest.setStage(player, 28); + end(); + } + break; + } + break; + case 28: + switch (stage) { + case 0: + player("Nothing really; I just decided to talk to you in case", "you have any great advice for me."); + stage++; + break; + case 1: + npc("Nope, sorry."); + stage++; + break; + case 2: + end(); + break; + } + break; + case 29: + case 30: + switch (stage) { + case 0: + npc("Fortunately for you, I've done some research and it", "seems to suggest that there are two choices open to", "you."); + stage++; + break; + case 1: + player("Tell me the worst."); + stage++; + break; + case 2: + npc("The first is more interesting. We cut off your arms,", "have them reanimated as undead, reattach them and", "then you should be able to cut the trees normally."); + stage++; + break; + case 3: + npc("Of course, you won't be able to pick your nose any", "more, so I suppose you'll want to try the second option."); + stage++; + break; + case 4: + player("I'm not exactly addicted to picking my nose, but I do", "think I'll pass on that method."); + stage++; + break; + case 5: + npc("Well, in that case, I think it may have something to do", "with Slayer abilities. After all, I did see Turael poking", "around the trees while I was moving in."); + stage++; + break; + case 6: + npc("As he's not known for his random touristic activities,", "you should try chatting with this Turael. He's the", "Slayer Master near Burthorpe."); + stage++; + break; + case 7: + player("Oh dear, I hope he doesn't want me to buy one of his", "ridiculous fashion accessories. Those earmuffs he sells", "make heroic adventurers into a laughing stock."); + stage++; + break; + case 8: + if (quest.getStage(player) == 29) { + quest.setStage(player, 30); + } + end(); + break; + } + break; + case 31: + switch (stage) { + case 0: + end(); + break; + case 1: + npc("You certainly took your time."); + stage++; + break; + case 2: + player("I'd say they didn't grow on trees, but I guess you'd", "just be sarcastic about my sense of humour."); + stage++; + break; + case 3: + npc("Quite. Now that we have all the ingredients for infinite", "arrows, we just need a container in which we can keep", "the components in the correct mutual alignment."); + stage++; + break; + case 4: + npc("I've gathered together some research notes from various", "sources but I can't quite make out what they mean. If", "you want to have a go at making them out, just ask me", "for a copy."); + stage++; + break; + case 5: + if (player.getInventory().remove(AnimalMagnetism.UNDEAD_TWIGS)) { + quest.setStage(player, 32); + } + end(); + break; + } + break; + case 32: + switch (stage) { + case 0: + npc("They are still stumping me. Here are the notes; I", "really hope your head doesn't explode from reading", "them."); + stage++; + break; + case 1: + player("I'd find it slightly inconvenient, I'm sure."); + stage++; + break; + case 2: + npc("It wouldn't be all bad as your body would be useful for", "research after death. What I'd be upset about was if", "bits of you landed in my nice new bed."); + stage++; + break; + case 3: + player("Your concern is touching."); + stage++; + break; + case 4: + quest.setStage(player, 33); + player.getInventory().add(AnimalMagnetism.RESEARCH_NOTES); + end(); + break; + } + break; + case 33: + switch (stage) { + case 0: + npc("I know you have the notes; I gave them to you, in case", "you forgot! Furthermore, if I had hints, I'd have", "translated those notes myself."); + stage++; + break; + case 1: + npc("So, take the hint and go off and translate them. If it's", "too hard, you can always go and shoot demons in", "cages."); + stage++; + break; + case 2: + end(); + break; + case 4: + if (!player.getInventory().hasSpaceFor(AnimalMagnetism.RESEARCH_NOTES)) { + player("Sorry, I don't have enough inventory space."); + stage++; + return true; + } + player.getInventory().add(AnimalMagnetism.RESEARCH_NOTES); + npc("Don't tell me, your cat ate them? You won't get out of", "the job that easily; here are some copies I made."); + stage++; + break; + case 5: + end(); + break; + case 10: + npc("For all I know, it was pure luck, so don't jump to any", "conclusions about your mighty intellect."); + stage++; + break; + case 11: + player("I can see why you don't have any assistants, you're", "not exactly easy to work with."); + stage++; + break; + case 12: + npc("Let's get back to the work we're doing, then.", "Remember, this is all a favour to you. I could have just", "decided to fob you off with a feather duster."); + stage++; + break; + case 13: + npc("I've given you a pattern for the container; you'll need", "to combine them with some polished buttons and hard", "leather. Then we're almost done. Good news, eh?"); + stage++; + break; + case 14: + npc("If you are having trouble finding buttons, I've heard", "rumours that the H.A.M society carry this sort of stuff", "more than most."); + stage++; + break; + case 15: + player("Really? How would you know this strange detail?"); + stage++; + break; + case 16: + npc("I hear they lose their clothes a lot to thieves so they", "have to make do with shoddy goods. Whatever the", "reason, they seem to carry buttons about in their pockets."); + stage++; + break; + case 17: + if (player.getInventory().remove(AnimalMagnetism.TRANSLATED_NOTES)) { + player.getInventory().add(AnimalMagnetism.PATTERN); + quest.setStage(player, 34); + end(); + } + break; + } + break; + case 34: + switch (stage) { + case 0: + npc("Your short-term memory loss worries me. Combine the", "pattern with hard leather and some polished buttons,", "then hand the resulting container to me."); + stage++; + break; + case 1: + end(); + break; + case 10: + npc("You're pretty careless, aren't you. I assume you're the", "type who leaves a trail of arrows and knives behind", "behind them when they train?"); + stage++; + break; + case 11: + if (!player.getInventory().hasSpaceFor(AnimalMagnetism.PATTERN)) { + player("Sorry, I don't have enough room in my backpack."); + stage++; + break; + } + player.getInventory().add(AnimalMagnetism.PATTERN); + npc("Here's a replacement; perhaps if I charged for them,", "you'd be more careful."); + stage++; + break; + case 12: + end(); + break; + case 20: + if (player.getInventory().remove(AnimalMagnetism.CONTAINER)) { + quest.finish(player); + end(); + } + break; + } + break; + case 100: + switch (stage) { + case 0: + options("Devices, please.", "I'd like information, please.", "I'd like to see your stuff for sale, please.", "I'll just head off, I think."); + stage++; + break; + case 1: + switch (buttonId) { + case 1: + player("Devices, please."); + stage = 10; + break; + case 2: + player("I'd like information, please."); + stage = 20; + break; + case 3: + player("I'd like to see your stuff for sale, please."); + stage = 30; + break; + case 4: + player("I'll just head off, I think."); + stage = 40; + break; + } + break; + case 10: + String first = "Basic: 999 coins"; + String second = "Upgraded: 999 coins
+ 75 steel arrows"; + if (!canBuyUpgrade(player)) { + second = " Upgraded: Level 50 Ranged"; + } + player.getPacketDispatch().sendItemZoomOnInterface(10498, 170, 140, 5); + player.getPacketDispatch().sendItemZoomOnInterface(10499, 170, 140, 6); + player.getPacketDispatch().sendString("Which device would you like?", 140, 4); + player.getPacketDispatch().sendString(first, 140, 2); + player.getPacketDispatch().sendString(second, 140, 3); + player.getInterfaceManager().openChatbox(140); + stage++; + break; + case 11: + switch (buttonId) { + case 1: + end(); + buy(buttonId == 2); + break; + case 2: + if (!canBuyUpgrade(player)) { + if (player.getSkills().getStaticLevel(Skills.RANGE) < 50) { + npc("I'm afraid you aren't yet skilled enough for the", "upgraded version. You need a Range level of 50 or", "greater."); + } else { + npc("You need to have an avas attractor in order", "to upgrade it."); + } + stage++; + } else { + buy(true); + } + break; + } + break; + case 12: + end(); + break; + case 20: + npc("Just a few bits of information before you run away to", "persecute rock crabs or cows."); + stage++; + break; + case 21: + npc("First, your new device won't work if you are wearing", "certain metallic chest armours."); + stage++; + break; + case 22: + npc("The magnetic attraction required for operation would", "cause feedback, so the device does not allow such", "incompatible item equippage."); + stage++; + break; + case 23: + npc("Secondly, although the device is calibrated to attract", "only arrow heads, there is a chance that other", "magnetically active items will be attracted."); + stage++; + break; + case 24: + npc("The arrow recovery function of the devices is slightly", "different and relies upon a harmonic bond between", "your arrows and the chicken's magnet. You'll thus only", "recover arrows which you have fired rather than those"); + stage++; + break; + case 25: + npc("fired by nearby folks."); + stage++; + break; + case 26: + npc("Thirdly, there is an upgraded version available when", "your Ranged level is 50 or greater."); + stage++; + break; + case 27: + npc("You'll also need to move about if you want to collect", "arrows since the gathering of long-lost arrowheads can't", "work otherwise."); + stage++; + break; + case 28: + npc("Finally, the device will only work when worn. It", "automatically deactivates in other circumstances."); + stage++; + break; + case 29: + npc("I was worried about what would happen if you were to", "place it in a bank in its active state, so I've made sure", "it only works when it's on your back."); + stage = 41; + break; + case 30: + npc("Here's my shop."); + stage++; + break; + case 31: + end(); + npc.openShop(player); + break; + case 40: + npc("Thanks for the help with my bed; see you again."); + stage++; + break; + case 41: + end(); + break; + } + break; + default: + switch (stage) { + case 0: + player("It's going..."); + stage++; + break; + case 1: + end(); + break; + } + break; + } + return true; + } + + /** + * Checks if the player can buy an upgrade. + * @param player the player. + * @return {@code True} if so. + */ + public boolean canBuyUpgrade(Player player) { + if (player.hasItem(AnimalMagnetism.AVAS_ACCUMULATOR)){ + return true; + } + return player.getSkills().getStaticLevel(Skills.RANGE) >= 50; + } + + /** + * Buys a device. + * @param upgrade if upgraded. + */ + private void buy(boolean upgrade) { + Item item = upgrade ? AnimalMagnetism.AVAS_ACCUMULATOR : AnimalMagnetism.AVAS_ATTRACTOR; + if (!player.getInventory().hasSpaceFor(item)) { + player("Sorry, I don't have enough inventory space."); + stage++; + return; + } + Item coins = new Item(995, 999); + if (upgrade) { + if (!player.getInventory().contains(886, 75)) { + player("Sorry, I don't have enough arrows."); + stage++; + return; + } + } + if (!player.getInventory().containsItem(coins)) { + player("Sorry, I don't have enough coins."); + return; + } + if (upgrade) { + player.getInventory().remove(new Item(886, 75)); + } + removeAll(player, item, upgrade ? AnimalMagnetism.AVAS_ATTRACTOR : AnimalMagnetism.AVAS_ACCUMULATOR); + player.getInventory().remove(coins); + npc("Here's your device; take good care of your chicken."); + stage++; + } + + /** + * Removes all the items. + * @param player the player. + * @param add the add item. + * @param remove the remove item. + */ + private void removeAll(Player player, Item add, Item remove) { + List containers = new ArrayList<>(20); + containers.add(player.getInventory()); + containers.add(player.getEquipment()); + containers.add(player.getBank()); + boolean replace = false; + for (Container c : containers) { + if (c.containsItem(remove)) { + c.replace(add, c.getSlot(remove)); + replace = true; + break; + } + } + if (!replace) { + player.getInventory().add(add); + } + } + + @Override + public int[] getIds() { + return new int[] { 5198, 5199 }; + } + +} diff --git a/Server/src/main/content/region/misthalin/draynor/quest/anma/AvasDevice.kt b/Server/src/main/content/region/misthalin/draynor/quest/anma/AvasDevice.kt new file mode 100644 index 0000000..9607a29 --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/quest/anma/AvasDevice.kt @@ -0,0 +1,119 @@ +package content.region.misthalin.draynor.quest.anma + +import core.api.* +import core.game.event.EventHook +import core.game.event.TickEvent +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import org.rs09.consts.Items +import core.api.Event +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.tools.secondsToTicks +import core.tools.colorize +import content.data.Quests + +/** + * Handles Ava's device + * @source https://runescape.wiki/w/Ava%27s_accumulator?oldid=2097350 + */ +class AvasDevice : InteractionListener, EventHook { + override fun defineListeners() { + onEquip(devices) { player, _ -> + if (!isQuestComplete(player, Quests.ANIMAL_MAGNETISM)) { + sendMessage(player, "You need to complete Animal Magnetism to equip this.") + return@onEquip false + } + + if (attractEnabled(player)) + player.hook(Event.Tick, this) + + setAttribute(player, LAST_TICK, getWorldTicks()) //set this on equip so can't be spam-re-equipped to spawn infinite items. + return@onEquip true + } + onUnequip(devices) { player, _ -> + if (attractEnabled(player)) + player.unhook(this) + return@onUnequip true + } + on(devices, IntType.ITEM, "operate") { player, _ -> + val attract = !attractEnabled(player) + setAttribute(player, ATTRACT_ENABLED, attract) + sendMessage( + player, + colorize( + "Ava's device will ${if (attract) "now" else "no longer"} randomly collect loot for you.", + "990000" + ) + ) + if (attract) { + player.hook(Event.Tick, this) + } else { + player.unhook(this) + } + return@on true + } + } + + override fun process(entity: Entity, event: TickEvent) { + if (entity !is Player) { + entity.unhook(this) + return + } + + if (getWorldTicks() - getLastTick(entity) < attractDelay) + return + else + setAttribute(entity, LAST_TICK, getWorldTicks()) + + if (isInterfered(entity)) { + sendMessage(entity, "Your armour interferes with Ava's device.") + return + } + + val wornId = getItemFromEquipment(entity, EquipmentSlot.CAPE)?.id ?: -1 + + val reward = when (wornId) { + Items.AVAS_ACCUMULATOR_10499 -> ACCUMULATOR_REWARDS + Items.AVAS_ATTRACTOR_10498 -> ATTRACTOR_REWARDS + else -> { + entity.unhook(this) + return + } + }.random() + + if (equipSlot(reward) == EquipmentSlot.AMMO) { + val equippedId = getItemFromEquipment(entity, EquipmentSlot.AMMO)?.id ?: -1 + if (reward == equippedId || equippedId == -1) { + entity.equipment.add(reward.asItem(), true, false) + return + } + } + + addItemOrDrop(entity, reward) + } + + private fun attractEnabled(entity: Entity) : Boolean { + return getAttribute(entity, ATTRACT_ENABLED, true) //defaults to enabled + } + + private fun getLastTick(entity: Entity) : Int { + return getAttribute(entity, LAST_TICK, 0) + } + + private fun isInterfered(player: Player) : Boolean { + val chestPiece = getItemFromEquipment(player, EquipmentSlot.CHEST) + val modelId = chestPiece?.definition?.maleWornModelId1 ?: -1 + return modelId != -1 && modelId in metalBodies + } + + companion object { + const val ATTRACT_ENABLED = "/save:avadevice:attract" + const val LAST_TICK = "avadevice:tick" + val devices = intArrayOf(Items.AVAS_ACCUMULATOR_10499, Items.AVAS_ATTRACTOR_10498) + val metalBodies = intArrayOf(301, 306, 3379) + val attractDelay = secondsToTicks(180) + val ATTRACTOR_REWARDS = arrayOf(Items.IRON_BAR_2351, Items.IRON_KNIFE_863,Items.IRON_DART_807,Items.IRON_DAGGER_1203,Items.IRON_BOLTS_9140,Items.IRON_ARROW_884,Items.IRON_ORE_440,Items.COPPER_ORE_436,Items.IRON_FULL_HELM_1153,Items.IRON_2H_SWORD_1309,Items.STEEL_BAR_2353) + val ACCUMULATOR_REWARDS = arrayOf(Items.STEEL_BAR_2353,Items.STEEL_2H_SWORD_1311,Items.STEEL_KNIFE_865,Items.STEEL_DAGGER_1207,Items.STEEL_MED_HELM_1141,Items.STEEL_DART_808,Items.STEEL_BOLTS_9141,Items.STEEL_ARROW_886,Items.IRON_BAR_2351) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/draynor/quest/anma/OldCronDialogue.java b/Server/src/main/content/region/misthalin/draynor/quest/anma/OldCronDialogue.java new file mode 100644 index 0000000..eb76716 --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/quest/anma/OldCronDialogue.java @@ -0,0 +1,214 @@ +package content.region.misthalin.draynor.quest.anma; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import content.region.misthalin.lumbridge.quest.therestlessghost.RestlessGhost; +import content.data.Quests; + +/** + * Handles the dialogue used for the old crone. + * @author Vexia + */ +public final class OldCronDialogue extends DialoguePlugin { + + /** + * The crone made amulet item. + */ + public static final Item CRONE_AMULET = new Item(10500); + + /** + * The quest used. + */ + private Quest quest; + + /** + * Constructs a new {@code OldCronDialogue} {@code Object}. + */ + public OldCronDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code OldCronDialogue} {@code Object}. + * @param player the player. + */ + public OldCronDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new OldCronDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + quest = player.getQuestRepository().getQuest(Quests.ANIMAL_MAGNETISM); + switch (quest.getStage(player)) { + case 16: + case 17: + case 18: + player("I'm here about the farmers east of here."); + break; + default: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello, old woman."); + stage = 1; + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (quest.getStage(player)) { + case 18: + switch (stage) { + case 0: + if (!player.hasItem(CRONE_AMULET)) { + player("Would you be able to replace the amulet you made? I", "seem to have lost it."); + stage = 4; + break; + } + npc("Yes?"); + stage++; + break; + case 1: + player("Well, to tell the truth, I just came back to chat with", "you. Any news?"); + stage++; + break; + case 2: + npc("Disgraceful! Deliver that amulet; a young lady's", "happiness depends upon it."); + stage++; + break; + case 3: + end(); + break; + case 4: + npc("Here you are; luckily, I saved some of Alice's hair in", "case you were careless. Which you were."); + stage++; + break; + case 5: + if (!player.getInventory().hasSpaceFor(RestlessGhost.AMULET)) { + npc("You don't have enough space in your inventory."); + stage = 3; + break; + } + if (!player.getInventory().containsItem(RestlessGhost.AMULET) && !player.getEquipment().containsItem(RestlessGhost.AMULET)) { + npc("You need to bring me a ghostspeak amulet."); + stage = 3; + break; + } + player.getInventory().add(CRONE_AMULET); + end(); + break; + } + break; + case 17: + switch (stage) { + case 0: + player("I'm here to see if you are ready to do your mystical", "stuff with my ghostspeak amulet."); + stage++; + break; + case 1: + if (!player.getInventory().hasSpaceFor(RestlessGhost.AMULET)) { + npc("I most certainly am, but you don't have enough", "space in your backpack."); + stage++; + break; + } + if (!player.getInventory().containsItem(RestlessGhost.AMULET) && !player.getEquipment().containsItem(RestlessGhost.AMULET)) { + npc("I most certainly am, but you don't have an ghostspeak", "amulet."); + stage++; + } else { + npc("I most certainly am; there you go."); + stage += 2; + } + break; + case 2: + end(); + break; + case 3: + player("Wow, that was quick and painless."); + stage++; + break; + case 4: + npc("Just being a good neighbour."); + stage++; + break; + case 5: + player.getInventory().add(CRONE_AMULET); + quest.setStage(player, 18); + end(); + break; + } + break; + case 16: + switch (stage) { + case 0: + player("Alice and her husband are having trouble talking to one", "another and said you might be able to help."); + stage++; + break; + case 1: + npc("Ah, I know them; shame about those cows. Why would", "they think that I could help?"); + stage++; + break; + case 2: + player("Alice seems to think you could alter a ghostspeak amulet", "in order to allow them to communicate."); + stage++; + break; + case 3: + npc("Well, the poor young lady has such family problems; I", "quite feel her pain. I'd be happy to help."); + stage++; + break; + case 4: + npc("You seem to have one of her golden hairs on your", "shoulder, so I can use that..."); + stage++; + break; + case 5: + interpreter.sendDialogue("In a flash, the crone whisks away an unseen hair from your", "shoulder."); + stage++; + break; + case 6: + npc("Talk to me again with a ghostspeak amulet and some", "space in your backpack and I'll be ready to work on", "the little good deed. The way I plan is quite simple,", "really."); + stage++; + break; + case 7: + npc("I can mirror part of the unused mystical essence of the", "ghostspeak amulet, bind it with Alice's hair and thus", "create a second amulet."); + stage++; + break; + case 8: + npc("The second amulet will be useful for the purpose you", "desire, thought it won't work for any other ghost or", "human other than the farmer and his wife."); + stage++; + break; + case 9: + quest.setStage(player, 17); + end(); + break; + } + break; + default: + switch (stage) { + case 1: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I lived here when this was all just fields, you know."); + stage = 2; + break; + case 2: + end(); + break; + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 1695 }; + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/draynor/quest/anma/WitchDialogue.java b/Server/src/main/content/region/misthalin/draynor/quest/anma/WitchDialogue.java new file mode 100644 index 0000000..7c23e06 --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/quest/anma/WitchDialogue.java @@ -0,0 +1,211 @@ +package content.region.misthalin.draynor.quest.anma; + +import content.data.Quests; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; + +/** + * Handles the witch dialogue. + * @author Vexia + */ +public final class WitchDialogue extends DialoguePlugin { + + /** + * The iron bar items. + */ + private static final Item IRON_BARS = new Item(2351, 5); + + /** + * The quest. + */ + private Quest quest; + + /** + * Constructs a new {@code WitchDialogue} {@code Object}. + */ + public WitchDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code WitchDialogue} {@code Object}. + * @param player the player. + */ + public WitchDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new WitchDialogue(player); + } + + @Override + public boolean open(Object... args) { + quest = player.getQuestRepository().getQuest(Quests.ANIMAL_MAGNETISM); + switch (quest.getStage(player)) { + case 25: + npc("Hello, hello, my poppet. What brings you to my little", "room?"); + break; + case 26: + if (!player.getInventory().containsItem(IRON_BARS)) { + player("I am back."); + } else { + npc("Great, you'll go far! I made some nice painted metal", "toys for you, smookums."); + } + break; + case 27: + if (player.hasItem(AnimalMagnetism.SELECTED_IRON)) { + npc("You were sent to try my patience, weren't you? Go", "away and make that magnet, then hand it to Ava."); + } else { + player("I have lost the selected iron..."); + stage++; + } + break; + default: + npc("Hello there, deary. Don't worry; I'm friendly."); + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (quest.getStage(player)) { + case 25: + switch (stage) { + case 0: + player("Ava told me to ask you about making magnets.", "Something about natural fields and other stuff. Sounded", "like she needed a farmer, to be honest."); + stage++; + break; + case 1: + npc("Don't worry, deary, I can tell you just what to do and", "you won't have to worry your pretty head about the", "complicated bits."); + stage++; + break; + case 2: + player("No need to patronise me quite so much, you know."); + stage++; + break; + case 3: + npc("I went to anger management classes, my lambkin; that's", "why I was treating you so kindly. It's either this way", "or talking or I'll go back to shoving children into ovens."); + stage++; + break; + case 4: + npc("Just bring me 5 iron bars, though, and you've well on", "the way to never having to talk to me again."); + stage++; + break; + case 5: + player("I'll be back."); + stage++; + break; + case 6: + quest.setStage(player, 26); + end(); + break; + } + break; + case 26: + switch (stage) { + case 0: + if (!player.getInventory().containsItem(IRON_BARS)) { + npc("Oh, but sugarpie, I need 5 iron bars, you don't have", "enough. Come back to me quickly with all 5 of them."); + stage++; + } else { + player("Toys? Snookums? What are you on about, you", "deranged old bar?"); + stage += 2; + } + break; + case 2: + npc("Oh, forget it, then. If you won't react to kindness, I'm", "back to luring infants into my oven. You'll have it on", "your conscience."); + stage++; + break; + case 3: + npc("Go to the iron mine just north-east of Rimmington and", "hit the bar with a plain old smithing hammer while facing", "north. Then take your new magnet to Ava. Poor girl,", "having to deal with whippersnappers like you."); + stage++; + break; + case 4: + if (player.getInventory().remove(IRON_BARS)) { + player.getInventory().add(AnimalMagnetism.SELECTED_IRON); + quest.setStage(player, 27); + end(); + } + break; + case 1: + end(); + break; + } + break; + case 27: + switch (stage) { + case 0: + end(); + break; + case 1: + npc("Oh, deary, deary... I had a feeling. I can", "make you another for five more iron bars."); + stage++; + break; + case 2: + if (!player.getInventory().containsItem(IRON_BARS)) { + player("Okay, I'll go get some."); + stage++; + break; + } + if (player.getInventory().remove(IRON_BARS)) { + player.getInventory().add(AnimalMagnetism.SELECTED_IRON); + end(); + } + break; + case 3: + end(); + break; + } + break; + default: + switch (stage) { + case 0: + player("You look very familiar but I can't remember chatting to", "you before."); + stage++; + break; + case 1: + npc("Well, my sisters used to live here but folk kept on", "killing them. A terrible affair, it was. I knew that no one", "would want to kill a chatty old dear like me, though."); + stage++; + break; + case 2: + player("Oh, well..."); + stage++; + break; + case 3: + npc("We still have a terrible problem with local louts, though.", "Poisoning my fish, spilling my compost all over the place", "and causing a nuisance for the dear count."); + stage++; + break; + case 4: + player("I think..."); + stage++; + break; + case 5: + npc("I'm sure a nice young sort like you won't be any", "trouble though. In any case, the Professor will soon", "share the secret of chickenisation with me... Not that I'd", "use it these days of course."); + stage++; + break; + case 6: + player("I have to go now."); + stage++; + break; + case 7: + end(); + break; + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 5200 }; + } + +} diff --git a/Server/src/main/content/region/misthalin/draynor/quest/ernest/ErnestDialogue.java b/Server/src/main/content/region/misthalin/draynor/quest/ernest/ErnestDialogue.java new file mode 100644 index 0000000..8fbf7d1 --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/quest/ernest/ErnestDialogue.java @@ -0,0 +1,89 @@ +package content.region.misthalin.draynor.quest.ernest; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; +import content.data.Quests; + +/** + * Represents the dialogue which handles the interaction with ernest. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class ErnestDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code ErnestDialogue} {@code Object}. + */ + public ErnestDialogue() { + /** + * empty + */ + } + + /** + * Constructs a new {@code ErnestDialogue} {@code Object}. + * @param player the player. + */ + public ErnestDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new ErnestDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Thank you sir. It was dreadfully irritating being a", "chicken. How can I ever thank you?"); + stage = 1; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Well a cash reward is always nice..."); + stage = 2; + break; + case 2: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Of course, of course."); + stage = 3; + break; + case 3: + npc.clear(); + end();// this will trigger close event. + break; + } + return true; + } + + @Override + public boolean close() { + finish(); + return super.close(); + } + + /** + * Method used to finish the quest. + */ + public void finish() { + if (player.getQuestRepository().isComplete(Quests.ERNEST_THE_CHICKEN)) { + npc.clear(); + return; + } + npc.clear(); + player.getQuestRepository().getQuest(Quests.ERNEST_THE_CHICKEN).finish(player); + } + + @Override + public int[] getIds() { + return new int[] { 287 }; + } +} diff --git a/Server/src/main/content/region/misthalin/draynor/quest/ernest/ErnestTheChicken.java b/Server/src/main/content/region/misthalin/draynor/quest/ernest/ErnestTheChicken.java new file mode 100644 index 0000000..58a9fec --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/quest/ernest/ErnestTheChicken.java @@ -0,0 +1,190 @@ +package content.region.misthalin.draynor.quest.ernest; + +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.plugin.ClassScanner; +import content.data.Quests; + +/** + * Represents the ernest the chicken quest. + * @author 'Vexia + */ +@Initializable +public final class ErnestTheChicken extends Quest { + + /** + * Represents the oil can item. + */ + private static final Item OIL_CAN = new Item(277); + + /** + * Represents the pressure gauge item. + */ + private static final Item PRESSURE_GAUGE = new Item(271); + + /** + * Represents the rubber tube item. + */ + private static final Item RUBBER_TUBE = new Item(276); + + /** + * Represents the coins item. + */ + private static final Item COINS = new Item(995, 300); + + /** + * Constructs a new {@code ErnestTheChicken} {@code Object}. + */ + public ErnestTheChicken() { + super(Quests.ERNEST_THE_CHICKEN, 19, 18, 4, 32, 0, 1, 3); + } + + @Override + public Quest newInstance(Object object) { + ClassScanner.definePlugins(new ErnestNPC(), new ErnestChickenNPC()); + return this; + } + + @Override + public void drawJournal(Player player, int stage) { + super.drawJournal(player, stage); + if (getStage(player) == 0) { + player.getPacketDispatch().sendString(BLUE + "I can start this quest by speaking to " + RED+ "Veronica " + BLUE + "who is", 275, 4+ 7); + player.getPacketDispatch().sendString(BLUE + "outside " + RED+ "Draynor Manor", 275, 5+ 7); + player.getPacketDispatch().sendString(BLUE + "There aren't any requirements for this quest.", 275, 7+ 7); + } else if (stage == 10) { + line(player, "I have spoken to Veronica", 4+ 7); + line(player, BLUE + "I need to find " + RED + "Ernest", 6+ 7); + line(player, BLUE + "He went into " + RED+ "Draynor Manor " + BLUE + "and hasn't returned", 7+ 7); + } else if (stage == 20) { + line(player, "I have spoken to Veronica", 4+ 7); + line(player, "I've spoken to Dr Oddenstein, and discovered Ernest is a", 6+ 7); + line(player, "chicken", 7+ 7); + line(player, BLUE + "I need to bring " + RED+ "Dr Oddenstein " + BLUE + "parts for his machine", 9+ 7); + line(player, player.getInventory().containsItem(OIL_CAN) ? "1 Oil Can" : RED+ "1 Oil Can", 10); + line(player, player.getInventory().containsItem(PRESSURE_GAUGE) ? "1 Pressure Gauge" : RED+ "1 Pressure Gauge", 11); + line(player, player.getInventory().containsItem(RUBBER_TUBE) ? "1 Rubber Tube" : RED+ "1 Rubber Tube", 12); + } else if (stage == 100) { + line(player, "I have spoken to Veronica", 4+ 7); + line(player, "I have collected all the parts for the machine", 6+ 7); + line(player, "Dr Oddenstein thanked me for helping fix his machine", 8+ 7); + line(player, "We turned Ernest back to normal and he rewarded me", 9+ 7); + line(player, "QUEST COMPLETE!", 10+ 7); + } + } + + @Override + public void finish(Player player) { + player.unlock(); + player.getPacketDispatch().sendMessage("Ernest hands you 300 coins."); + super.finish(player); + player.getPacketDispatch().sendString("4 Quest Points", 277, 8 + 2); + player.getPacketDispatch().sendString("300 coins", 277, 9 + 2); + player.getPacketDispatch().sendString("You have completed the Ernest The Chicken Quest!", 277, 2 + 2); + player.getGameAttributes().removeAttribute("piranhas-killed"); + player.getGameAttributes().removeAttribute("pressure-gauge"); + player.getPacketDispatch().sendItemZoomOnInterface(314, 230, 277, 3 + 2); + if (!player.getInventory().add(COINS)) { + GroundItemManager.create(COINS, player.getLocation(), player); + } + } + + /** + * Represents the abstract npc class to handle ernest the chicken. + * @author 'Vexia + * @version 1.0 + */ + public final static class ErnestChickenNPC extends AbstractNPC { + + /** + * The NPC ids of NPCs using this plugin. + */ + private static final int[] ID = { 288 }; + + /** + * Constructs a new {@code ErnestChickenNPC} {@code Object}. + */ + public ErnestChickenNPC() { + super(0, null, false); + } + + /** + * Constructs a new {@code ErnestChickenNPC} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + private ErnestChickenNPC(int id, Location location) { + super(id, location, false); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new ErnestChickenNPC(id, location); + } + + @Override + public boolean isHidden(final Player player) { + return player.getQuestRepository().getQuest(Quests.ERNEST_THE_CHICKEN).getStage(player) == 100 || player.getAttribute("ernest-hide", false); + } + + @Override + public int[] getIds() { + return ID; + } + + } + + /** + * Represents the abstract npc class to handle ernest the chicken. + * @author 'Vexia + * @version 1.0 + */ + public final static class ErnestNPC extends AbstractNPC { + + /** + * The NPC ids of NPCs using this plugin. + */ + private static final int[] ID = { 287 }; + + /** + * Constructs a new {@code ErnestChickenNPC} {@code Object}. + */ + public ErnestNPC() { + super(0, null, false); + } + + /** + * Constructs a new {@code ErnestChickenNPC} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + private ErnestNPC(int id, Location location) { + super(id, location, false); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new ErnestNPC(id, location); + } + + @Override + public boolean isHidden(final Player player) { + Player target = getAttribute("target", null); + if (target != null && target.getQuestRepository().getQuest(Quests.ERNEST_THE_CHICKEN).getStage(player) == 100) { + clear(); + return super.isHidden(player); + } + return target == null || player != target; + } + + @Override + public int[] getIds() { + return ID; + } + } +} diff --git a/Server/src/main/content/region/misthalin/draynor/quest/ernest/ErnestTheChickenPlugin.java b/Server/src/main/content/region/misthalin/draynor/quest/ernest/ErnestTheChickenPlugin.java new file mode 100644 index 0000000..fb009f9 --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/quest/ernest/ErnestTheChickenPlugin.java @@ -0,0 +1,588 @@ +package content.region.misthalin.draynor.quest.ernest; + +import java.awt.Point; +import java.util.Arrays; + +import core.cache.def.impl.SceneryDefinition; +import core.game.global.action.DoorActionHandler; +import content.global.skill.agility.AgilityHandler; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBuilder; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; + +import static core.api.ContentAPIKt.*; + +/** + * Represents the ernest the chicken plugin to handle node interactions. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class ErnestTheChickenPlugin extends OptionHandler { + + /** + * Represents the pulling down animation. + */ + private static final Animation DOWN_ANIMATION = new Animation(2140); + + /** + * Represents the pulling up animation. + */ + private static final Animation UP_ANIMATION = new Animation(2139); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(11450).getHandlers().put("option:open", this); + for (Lever lever : Lever.values()) { + for (int i : lever.getObjectIds()) { + SceneryDefinition.forId(i).getHandlers().put("option:pull", this); + SceneryDefinition.forId(i).getHandlers().put("option:inspect", this); + } + } + /** doors */ + ZoneBuilder.configure(new LeverZone()); + return this; + } + + @Override + public boolean handle(final Player player, Node node, String option) { + final Scenery object = ((Scenery) node); + final LeverCacheExtension extension = LeverCacheExtension.extend(player); + Lever lever = Lever.forObject(object.getId()); + switch (option) { + case "pull": + lever = Lever.forObject(object.getId()); + extension.pull(lever, object); + break; + case "inspect": + extension.inspect(lever); + break; + case "open": + extension.walk(object); + return true; + } + return true; + } + + /** + * Represents an extension class of cached levers for the player. + * @author 'Vexia + * @date 24/12/2013 + */ + public static class LeverCacheExtension { + + /** + * Represents the config id for the lever. + */ + private static final int LEVER_CONFIG = 33; + + /** + * Represents the config id for the doors. + */ + private static final int DOOR_CONFIG = 668; + + /** + * Represents the player. + */ + private final Player player; + + /** + * Represents the cached levers. + */ + private boolean[] levers = new boolean[Lever.values().length]; + + /** + * Constructs a new {@code ErnestTheChickenPlugin} {@code Object}. + * @param player the player. + */ + public LeverCacheExtension(final Player player) { + this.player = player; + } + + /** + * Method used to extend a lever cache extension. + * @param player the player. + * @return the lever cache extension. + */ + public static LeverCacheExtension extend(final Player player) { + LeverCacheExtension extension = player.getExtension(LeverCacheExtension.class); + if (extension == null) { + extension = new LeverCacheExtension(player); + player.addExtension(LeverCacheExtension.class, extension); + } + return extension; + } + + /** + * Method used to pull a lever. + * @param lever the lever. + * @param object the object. + */ + public final void pull(final Lever lever, final Scenery object) { + final boolean up = isUp(lever); + levers[lever.ordinal()] = !up; + player.animate(!up ? UP_ANIMATION : DOWN_ANIMATION); + GameWorld.getPulser().submit(new Pulse(1) { + @Override + public boolean pulse() { + updateConfigs(); + player.getPacketDispatch().sendMessage("You pull lever " + lever.name().replace("LEVER_", "").trim() + " " + (up ? "down" : "up") + "."); + player.getPacketDispatch().sendMessage("You hear a clunk."); + return true; + } + }); + } + + /** + * Method used to inspect a cached lever. + * @param lever the lever. + */ + public final void inspect(final Lever lever) { + player.getPacketDispatch().sendMessage("The lever is " + (isUp(lever) ? "up" : "down") + "."); + } + + /** + * Method used to walk through a door. + * @param object the object. + */ + public final void walk(final Scenery object) { + player.lock(4); + GameWorld.getPulser().submit(new Pulse(1, player, object) { + @Override + public boolean pulse() { + Point p = (Point) getWalkData()[0]; + int[] rotation = (int[]) getWalkData()[1]; + Location destination = (Location) getWalkData()[2]; + final Scenery opened = object.transform(object.getId(), rotation[0]); + opened.setCharge(88); + opened.setLocation(object.getLocation().transform((int) p.getX(), (int) p.getY(), 0)); + final Scenery second = DoorActionHandler.getSecondDoor(object, player); + SceneryBuilder.replace(object, opened, 2); + if (second != null) { + final Scenery secondOpened = second.transform(second.getId(), rotation[1]); + secondOpened.setCharge(88); + secondOpened.setLocation(second.getLocation().transform((int) p.getX(), (int) p.getY(), 0)); + SceneryBuilder.replace(second, secondOpened, 2); + } + AgilityHandler.walk(player, 0, player.getLocation(), destination, null, 0, null); + return true; + } + }); + } + + /** + * Method used to update the players config states. + */ + public final void updateConfigs() { + setVarp(player, LEVER_CONFIG, calculateLeverConfig()); + setVarp(player, DOOR_CONFIG, calculateDoorConfig()); + save(); + } + + /** + * Method used to save the lever states. + */ + public final void save() { + boolean value = false; + for (int index = 0; index < levers.length; index++) { + value = levers[index]; + if (!value) {// down. + player.getSavedData().getQuestData().getDraynorLevers()[index] = false; + } + } + } + + /** + * Method used to read the lever states. + */ + public final void read() { + boolean value = false; + for (int i = 0; i < Lever.values().length; i++) { + value = player.getSavedData().getQuestData().getDraynorLevers()[i]; + levers[i] = value; + } + updateConfigs(); + } + + /** + * Method used to calculate the lever config value. + * @return the value. + */ + public final int calculateLeverConfig() { + int value = 0; + for (int i = 0; i < levers.length; i++) { + if (!levers[i]) { + value += Math.pow(2, (i + 1)); + } + } + return value; + } + + /** + * Method used to calculate the door config value. + * @return the value. + */ + public final int calculateDoorConfig() { + final int downCount = getDownCount(); + int value = 0; + boolean up = false; + Lever lever = null; + for (int i = 0; i < levers.length; i++) { + up = levers[i];// if its up. + lever = Lever.values()[i]; + if (downCount == 0 || downCount == 1 && !isUp(Lever.LEVER_B) && lever == Lever.LEVER_B && levers[0]) {// translation: + // no + // down + // lever + // and + // lever + // b + // is + // on/off + // just + // send + // 0. + value = 0; + break; + } + if (downCount == 1 && !isUp(Lever.LEVER_A)) { + return 4; + } + if (downCount == 1 && !isUp(Lever.LEVER_D)) { + return 328; + } + if (downCount == 2 && !isUp(Lever.LEVER_D) && !isUp(Lever.LEVER_E)) { + return 290; + } + if (downCount == 2 && !isUp(Lever.LEVER_D) && !isUp(Lever.LEVER_F)) { + return 64; + } + if (downCount == 3 && !isUp(Lever.LEVER_F) && !isUp(Lever.LEVER_D) && !isUp(Lever.LEVER_C) && isUp(Lever.LEVER_A)) { + return 306; + } + if (downCount == 3 && !isUp(Lever.LEVER_E) && !isUp(Lever.LEVER_D) && !isUp(Lever.LEVER_C) && isUp(Lever.LEVER_F)) { + return 64; + } + if (downCount == 5 && !isUp(Lever.LEVER_F) && !isUp(Lever.LEVER_D) && !isUp(Lever.LEVER_C) && !isUp(Lever.LEVER_A) && !isUp(Lever.LEVER_B)) { + return 304; + } + if (!isUp(Lever.LEVER_F) && !isUp(Lever.LEVER_D) && !isUp(Lever.LEVER_C) && isUp(Lever.LEVER_E) && lever == Lever.LEVER_A) { + return 306; + } + if (!isUp(Lever.LEVER_F) && !isUp(Lever.LEVER_D) && !isUp(Lever.LEVER_C) && isUp(Lever.LEVER_E) && isUp(Lever.LEVER_A) && !isUp(Lever.LEVER_B)) { + return 304; + } + if (!isUp(Lever.LEVER_F) && !isUp(Lever.LEVER_D) && !isUp(Lever.LEVER_C) && isUp(Lever.LEVER_E) && !isUp(Lever.LEVER_A) && !isUp(Lever.LEVER_B)) { + return 304; + } + if (downCount == 4 && !isUp(Lever.LEVER_D) && !isUp(Lever.LEVER_C) && !isUp(Lever.LEVER_A) && !isUp(Lever.LEVER_B)) { + return 264; + } + if (downCount == 3 && !isUp(Lever.LEVER_D) && !isUp(Lever.LEVER_F) && !isUp(Lever.LEVER_E)) { + return 3; + } + if (downCount == 2 && !isUp(Lever.LEVER_E) && !isUp(Lever.LEVER_F) && isUp(Lever.LEVER_D)) { + return 1; + } + if (downCount == 4 && !isUp(Lever.LEVER_D) && !isUp(Lever.LEVER_F) && !isUp(Lever.LEVER_E) && !isUp(Lever.LEVER_C)) { + return 19; + } + if (downCount == 3 && !isUp(Lever.LEVER_E) && !isUp(Lever.LEVER_D) && !isUp(Lever.LEVER_C)) { + return 306; + } + if (downCount == 3 && isUp(Lever.LEVER_E) && !isUp(Lever.LEVER_D) && !isUp(Lever.LEVER_C) && !isUp(Lever.LEVER_F)) { + return 306; + } + if (downCount == 2 && !isUp(Lever.LEVER_B) && !isUp(Lever.LEVER_D)) { + return 64; + } + if (downCount == 2 && !isUp(Lever.LEVER_A) && !isUp(Lever.LEVER_D)) { + return 328; + } + if (lever == Lever.LEVER_A && up && !isUp(Lever.LEVER_B)) { + value -= 132; + continue; + } else if (lever == Lever.LEVER_B && up && !isUp(Lever.LEVER_A)) { + value -= 64; + continue; + } + if (!up) {// if toggled. + if (lever == Lever.LEVER_A) { + value += 4; + } else if (lever == Lever.LEVER_B) { + value += 128; + } else if (lever == Lever.LEVER_D) { + value += 264; + } else if (lever == Lever.LEVER_C) { + value -= 132; + } else if (lever == Lever.LEVER_F) { + value -= 38; + } else if (lever == Lever.LEVER_E) { + value -= 287; + } + } + } + return value; + } + + /** + * Method used to get the walking data. + * @return the data. + */ + public final Object[] getWalkData() { + Object[] data = null; + final int x = player.getLocation().getX(); + final int y = player.getLocation().getY(); + if (x == 3108 && y == 9757) { + data = new Object[] { new Point(-1, 0), new int[] { 2, 0 }, Location.create(3108, 9759, 0) }; + } else if (x == 3108 && y == 9759) { + data = new Object[] { new Point(-1, 0), new int[] { 2, 0 }, Location.create(3108, 9757, 0) }; + } else if (x == 3106 && y == 9760) { + data = new Object[] { new Point(0, 1), new int[] { 3, 0 }, Location.create(3104, 9760, 0) }; + } else if (x == 3104 && y == 9760) { + data = new Object[] { new Point(0, 1), new int[] { 3, 0 }, Location.create(3106, 9760, 0) }; + } else if (x == 3104 && y == 9765) { + data = new Object[] { new Point(0, 1), new int[] { 3, 0 }, Location.create(3106, 9765, 0) }; + } else if (x == 3106 && y == 9765) { + data = new Object[] { new Point(0, 1), new int[] { 3, 0 }, Location.create(3104, 9765, 0) }; + } else if (x == 3102 && y == 9764) { + data = new Object[] { new Point(-1, 0), new int[] { 2, 0 }, Location.create(3102, 9762, 0), }; + } else if (x == 3102 && y == 9762) { + data = new Object[] { new Point(-1, 0), new int[] { 2, 0 }, Location.create(3102, 9764, 0) }; + } else if (x == 3102 && y == 9759) { + data = new Object[] { new Point(-1, 0), new int[] { 2, 0 }, Location.create(3102, 9757, 0) }; + } else if (x == 3102 && y == 9757) { + data = new Object[] { new Point(-1, 0), new int[] { 2, 0 }, Location.create(3102, 9759, 0) }; + } else if (x == 3101 && y == 9760) { + data = new Object[] { new Point(0, 1), new int[] { 3, 0 }, Location.create(3099, 9760, 0) }; + } else if (x == 3099 && y == 9760) { + data = new Object[] { new Point(0, 1), new int[] { 3, 0 }, Location.create(3101, 9760, 0) }; + } else if (x == 3101 && y == 9765) { + data = new Object[] { new Point(0, 1), new int[] { 3, 0 }, Location.create(3099, 9765, 0) }; + } else if (x == 3099 && y == 9765) { + data = new Object[] { new Point(0, 1), new int[] { 3, 0 }, Location.create(3101, 9765, 0) }; + } else if (x == 3097 && y == 9762) { + data = new Object[] { new Point(-1, 0), new int[] { 2, 0 }, Location.create(3097, 9764, 0) }; + } else if (x == 3097 && y == 9764) { + data = new Object[] { new Point(-1, 0), new int[] { 2, 0 }, Location.create(3097, 9762, 0) }; + } else if (x == 3101 && y == 9755) { + data = new Object[] { new Point(0, 1), new int[] { 3, 0 }, Location.create(3099, 9755, 0) }; + } else if (x == 3099 && y == 9755) { + data = new Object[] { new Point(0, 1), new int[] { 3, 0 }, Location.create(3101, 9755, 0) }; + } + return data == null ? new Object[] { new Point(0, 0), new int[] { 0, 0 }, player.getLocation() } : data; + } + + /** + * Method ued to reset the levers. + */ + public void reset() { + Arrays.fill(levers, true); + Arrays.fill(player.getSavedData().getQuestData().getDraynorLevers(), true); + updateConfigs(); + } + + /** + * Gets the count of down levers. + * @return the count. + */ + public final int getDownCount() { + int count = 0; + for (int i = 0; i < levers.length; i++) { + count += !levers[i] ? 1 : 0; + } + return count; + } + + /** + * Method used to check if a lever is up. + * @param lever the lever. + * @return True if so. + */ + public final boolean isUp(final Lever lever) { + return levers[lever.ordinal()]; + } + + /** + * Gets the player. + * @return the player. + */ + public Player getPlayer() { + return player; + } + + } + + /** + * Represents the lever zone map area. + * @author 'Vexia + * @date 26/12/2013 + */ + public class LeverZone extends MapZone { + + /** + * Constructs a new {@code LeverZone} {@code Object}. + */ + public LeverZone() { + super("Draynor lever zone", true); + } + + @Override + public void configure() { + registerRegion(12440); + } + + @Override + public boolean enter(final Entity entity) { + if (!(entity instanceof Player)) { + return super.enter(entity); + } + final Player player = ((Player) entity); + final LeverCacheExtension extension = LeverCacheExtension.extend(player); + extension.read(); + return super.enter(entity); + } + + @Override + public boolean leave(final Entity entity, boolean logout) { + if (entity instanceof Player) { + final Player player = ((Player) entity); + final LeverCacheExtension extension = LeverCacheExtension.extend(player); + extension.save(); + } + return super.leave(entity, logout); + } + } + + /** + * Represents a lever. + * @author 'Vexia + * @date 24/12/2013 + */ + public enum Lever { + LEVER_A(11451, 11452), LEVER_B(11453, 11454), LEVER_C(11455, 11456), LEVER_D(11457, 11458), LEVER_E(11459, 11460), LEVER_F(11461, 11462); + + /** + * Represents the object id. + */ + private final int[] objectIds; + + /** + * Constructs a new {@code ErnestTheChickenPlugin.java} {@code Object}. + * @param objectId + */ + Lever(final int... objectId) { + this.objectIds = objectId; + } + + /** + * Gets the objectId. + * @return The objectId. + */ + public int[] getObjectIds() { + return objectIds; + } + + /** + * Gets the lever from the object id. + * @param objectId the objectId. + * @return the lever. + */ + public static Lever forObject(final int objectId) { + for (Lever lever : Lever.values()) { + for (int i : lever.getObjectIds()) { + if (i == objectId) { + return lever; + } + } + } + return null; + } + } + + @Override + public Location getDestination(final Node node, final Node n) { + if (n instanceof Scenery) { + final Player player = ((Player) node); + final int x = player.getLocation().getX(); + final int y = player.getLocation().getY(); + Location loc = ((Scenery) n).getLocation(); + if (loc.equals(new Location(3108, 9758, 0))) { + if (y <= 9757) { + return Location.create(3108, 9757, 0); + } else { + return Location.create(3108, 9759, 0); + } + } + if (loc.equals(new Location(3105, 9760, 0))) { + if (x >= 3105) { + return Location.create(3106, 9760, 0); + } else { + return Location.create(3104, 9760, 0); + } + } + if (loc.equals(new Location(3105, 9765, 0))) { + if (x >= 3106) { + return Location.create(3106, 9765, 0); + } else { + return Location.create(3104, 9765, 0); + } + } + if (loc.equals(new Location(3102, 9763, 0))) { + if (y >= 9764) { + return Location.create(3102, 9764, 0); + } else { + return Location.create(3102, 9762, 0); + } + } + if (loc.equals(new Location(3102, 9758, 0))) { + if (y >= 9759) { + return Location.create(3102, 9759, 0); + } else { + return Location.create(3102, 9757, 0); + } + } + if (loc.equals(new Location(3100, 9760, 0))) { + if (x >= 3100) { + return Location.create(3101, 9760, 0); + } else { + return Location.create(3099, 9760, 0); + } + } + if (loc.equals(new Location(3100, 9765, 0))) { + if (x >= 3100) { + return Location.create(3101, 9765, 0); + } else { + return Location.create(3099, 9765, 0); + } + } + if (loc.equals(new Location(3097, 9763, 0))) { + if (y <= 9763) { + return Location.create(3097, 9762, 0); + } else { + return Location.create(3097, 9764, 0); + } + } + if (loc.equals(new Location(3100, 9755, 0))) { + if (x >= 3100) { + return Location.create(3101, 9755, 0); + } else { + return Location.create(3099, 9755, 0); + } + } + } + return null; + } + +} diff --git a/Server/src/main/content/region/misthalin/draynor/quest/vampire/VampireSlayer.java b/Server/src/main/content/region/misthalin/draynor/quest/vampire/VampireSlayer.java new file mode 100644 index 0000000..94e7f13 --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/quest/vampire/VampireSlayer.java @@ -0,0 +1,85 @@ +package content.region.misthalin.draynor.quest.vampire; + +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import content.data.Quests; + +/** + * Represents the vampire quest. + * @author 'Vexia + */ +@Initializable +public class VampireSlayer extends Quest { + + /** + * Constructs a new {@code VampireSlayer} {@code Object}. + */ + public VampireSlayer() { + super(Quests.VAMPIRE_SLAYER, 30, 29, 3, 178, 0, 1, 3); + } + + @Override + public void drawJournal(Player player, int stage) { + super.drawJournal(player, stage); + if (getStage(player) == 0) { + line(player, BLUE + "I can start this quest by speaking to " + RED + "Morgan who is in", 4+ 7); + line(player, RED + "Draynor Village.", 5+ 7); + line(player, BLUE + "Requirements:", 7+ 7); + line(player, BLUE + "Must be able to kill a level 34 " + RED + "Vampire.", 8+ 7); + } + if (getStage(player) == 10) { + line(player, "I spoke to Morgan in Draynor Village. He told me that the", 4+ 7); + line(player, "locals are being attacked by a terrifying Vampire!", 5+ 7); + line(player, BLUE + "I need to speak to " + RED + "Dr Harlow " + BLUE + "who can normally be found in", 7+ 7); + line(player, BLUE + "the " + RED + " Blue Moon Inn" + BLUE + " in " + RED + "Varrock.", 8+ 7); + } + if (getStage(player) == 20) { + line(player, "I spoke to Morgan in Draynor Village. He told me that the", 4+ 7); + line(player, "locals are being attacked by a terrifying Vampire!", 5+ 7); + line(player, "I have spoken to Dr Harlow. He seemed terribly drunk, and", 7+ 7); + line(player, "he kept asking me to buy him drinks.", 8+ 7); + line(player, BLUE + "I should see what advice " + RED + "Dr Harlow" + BLUE + " can give me about killing", 10+ 7); + line(player, RED + "Vampires.", 11+ 7); + line(player, BLUE + "When I'm ready, I should go to " + RED + "Draynor Manor" + BLUE + ", north of", 12+ 7); + line(player, BLUE + "Draynor to kill the " + RED + "Vampire" + BLUE + " that's living in the basement.", 13+ 7); + } + if (getStage(player) == 30) { + line(player, "I spoke to Morgan in Draynor Village. He told me that the", 4+ 7); + line(player, "locals are being attacked by a terrifying Vampire!", 5+ 7); + line(player, "I have spoken to Dr Harlow. He seemed terribly drunk, and", 7+ 7); + line(player, "he kept asking me to buy him drinks.", 8+ 7); + line(player, "Dr Harlow gave me a stake to finish off the Vampire then", 10+ 7); + line(player, "I'm fighting it. I've got a hammer to drive the stake deep", 11+ 7); + line(player, "into the Vampire's chest, and I have some garlic which", 12+ 7); + line(player, "should weaken the Vampire.", 13+ 7); + line(player, BLUE + "When i'm ready, I should go to " + RED + "Draynor Manor" + BLUE + ", north of", 14+ 7); + line(player, BLUE + "Draynor to kill the " + RED + "Vampire" + BLUE + " that's living in the basement.", 15+ 7); + } + if (getStage(player) == 100) { + line(player, "I spoke to Morgan in Draynor Village. He told me that the", 4+ 7); + line(player, "locals are being attacked by a terrifying Vampire!", 5+ 7); + line(player, "I have spoken to Dr Harlow. He seemed terribly drunk, and", 7+ 7); + line(player, "he kept asking me to buy him drinks.", 8+ 7); + line(player, "I have killed the Vampire, Count Draynor. Draynor Village is", 10+ 7); + line(player, "now safe!", 11+ 7); + line(player, "QUEST COMPLETE!", 12+ 7); + } + } + + @Override + public void finish(Player player) { + super.finish(player); + player.getSkills().addExperience(Skills.ATTACK, 4825); + player.getPacketDispatch().sendString("3 Quest Point", 277, 8 + 2); + player.getPacketDispatch().sendString("4825 Attack XP", 277, 9 + 2); + player.getPacketDispatch().sendItemZoomOnInterface(1549, 260, 277, 3 + 2); + } + + @Override + public Quest newInstance(Object object) { + // TODO Auto-generated method stub + return this; + } +} diff --git a/Server/src/main/content/region/misthalin/draynor/quest/vampire/VampireSlayerNPC.java b/Server/src/main/content/region/misthalin/draynor/quest/vampire/VampireSlayerNPC.java new file mode 100644 index 0000000..17c72b2 --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/quest/vampire/VampireSlayerNPC.java @@ -0,0 +1,170 @@ +package content.region.misthalin.draynor.quest.vampire; + +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import core.game.world.map.Location; +import core.tools.RandomFunction; +import content.data.Quests; + +/** + * Handles the Vampie Slayer npc. + * @author 'Vexia + */ +@Initializable +public class VampireSlayerNPC extends AbstractNPC { + + /** + * Represents the stake item + */ + private static final Item STAKE = new Item(1549); + + /** + * Represents the hammer item. + */ + private static final Item HAMMER = new Item(2347); + + /** + * Represents the garlic item. + */ + private static final Item GARLIC = new Item(1550); + + /** + * Represents the locations that a candle is at. + */ + private static final Location[] CANDLE_LOCATION = new Location[] { Location.create(3076, 9772, 0), Location.create(3079, 9772, 0), Location.create(3075, 9778, 0), Location.create(3080, 9778, 0) }; + + /** + * Represents the force chat that the player will say if on fire. + */ + private static final String[] FORCE_CHAT = new String[] { "Eeek!", "Oooch!", "Gah!", "Ow!" }; + + /** + * The NPC ids of NPCs using this plugin. + */ + private static final int[] ID = { 757 }; + + /** + * Constructs a new {@code AlKharidWarriorPlugin} {@code Object}. + */ + public VampireSlayerNPC() { + super(0, null); + } + + /** + * Constructs a new {@code AlKharidWarriorPlugin} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + private VampireSlayerNPC(int id, Location location) { + super(id, location); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new VampireSlayerNPC(id, location); + } + + @Override + public void init() { + super.init(); + getSkills().setLifepoints(40); + getSkills().setStaticLevel(Skills.HITPOINTS, 40); + getSkills().setLevel(Skills.HITPOINTS, 40); + } + + @Override + public void tick() { + final Player p = getAttribute("player", null); + if (p != null) { + if (p.getLocation().getDistance(getLocation()) >= 16) { + clear(); + return; + } + if (!getProperties().getCombatPulse().isAttacking()) { + getProperties().getCombatPulse().attack(p); + } + if (p.getProperties().getCombatPulse().isAttacking() && p.getProperties().getCombatPulse().getVictim() == this) { + for (Location l : CANDLE_LOCATION) { + if (p.getLocation().equals(l)) { + p.sendChat(FORCE_CHAT[RandomFunction.random(FORCE_CHAT.length)]); + p.getPacketDispatch().sendMessage("The candles burn your feet!"); + break; + } + } + if (!p.getInventory().containsItem(HAMMER) || !p.getInventory().containsItem(STAKE)) { + getSkills().heal(10); + } + if (RandomFunction.random(7) == 2) { + getSkills().heal(RandomFunction.random(1, !p.getInventory().containsItem(GARLIC) ? 12 : 2)); + } + } + } + super.tick(); + } + + @Override + public void onImpact(Entity entity, BattleState state) { + if (entity instanceof Player) { + final Player p = ((Player) entity); + if (!p.getInventory().containsItem(HAMMER) || !p.getInventory().containsItem(STAKE)) { + getSkills().heal(10); + } + } + super.onImpact(entity, state); + } + + @Override + public void finalizeDeath(final Entity killer) { + setRespawn(false); + super.finalizeDeath(killer); + if (!(killer instanceof Player)) { + return; + } + final Player p = ((Player) killer); + final Quest quest = p.getQuestRepository().getQuest(Quests.VAMPIRE_SLAYER); + if (p.getInventory().containsItem(HAMMER) && p.getInventory().remove(STAKE)) { + if (quest.getStage(p) == 30) { + quest.finish(p); + p.getPacketDispatch().sendMessage("You hammer the stake into the vampire's chest!"); + } + } else { + p.getPacketDispatch().sendMessage("The vampire returns to his coffin. Next time use a stake and hammer."); + } + setRespawn(false); + } + + @Override + public void checkImpact(BattleState state) { + if (state.getAttacker() instanceof Player) { + Player p = (Player) state.getAttacker(); + if (!p.getInventory().containsItem(HAMMER) || !p.getInventory().containsItem(STAKE)) { + if (state.getEstimatedHit() > -1) { + state.setEstimatedHit(0); + } + if (state.getSecondaryHit() > -1) { + state.setSecondaryHit(0); + } + } + } + } + + @Override + public boolean isAttackable(final Entity entity, final CombatStyle style, boolean message) { + final Player player = ((Player) entity); + final Player pl = getAttribute("player", null); + return pl == null ? false : pl == player ? true : false; + } + + @Override + public int[] getIds() { + return ID; + } + +} diff --git a/Server/src/main/content/region/misthalin/draynor/quest/vampire/VampireSlayerPlugin.java b/Server/src/main/content/region/misthalin/draynor/quest/vampire/VampireSlayerPlugin.java new file mode 100644 index 0000000..f8f5825 --- /dev/null +++ b/Server/src/main/content/region/misthalin/draynor/quest/vampire/VampireSlayerPlugin.java @@ -0,0 +1,97 @@ +package content.region.misthalin.draynor.quest.vampire; + +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.plugin.Plugin; +import content.data.Quests; + +/** + * Represents the plugin to handle vampire slayer node handling. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class VampireSlayerPlugin extends OptionHandler { + + /** + * Represents the basement location. + */ + private static final Location BASEMENT = Location.create(3077, 9770, 0); + + /** + * Represents the ground floor location. + */ + private static final Location GROUND_FLOOR = Location.create(3115, 3356, 0); + + /** + * Represents the stake item + */ + private static final Item STAKE = new Item(1549); + + /** + * Represents the hammer item. + */ + private static final Item HAMMER = new Item(2347); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(33502).getHandlers().put("option:open", this); + SceneryDefinition.forId(2614).getHandlers().put("option:open", this); + SceneryDefinition.forId(32835).getHandlers().put("option:walk-down", this); + SceneryDefinition.forId(32836).getHandlers().put("option:walk-up", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + final Quest quest = player.getQuestRepository().getQuest(Quests.VAMPIRE_SLAYER); + switch (option) { + case "open": + int id = ((Scenery) node).getId(); + switch (id) { + case 2614: + if (quest.getStage(player) == 100) { + player.getDialogueInterpreter().sendDialogue("There's only a pillow in here.."); + } else if (quest.getStage(player) == 30) { + if (!player.getInventory().containsItem(STAKE) && !player.getInventory().containsItem(HAMMER)) { + player.getPacketDispatch().sendMessage("You must have a stake and hammer with you to kill the vampire."); + return true; + } + final NPC o = player.getAttribute("count", null); + if (o == null || !o.isActive()) { + final NPC vampire = NPC.create(757, player.getLocation()); + vampire.setRespawn(false); + vampire.setAttribute("player", player); + vampire.init(); + vampire.getProperties().getCombatPulse().attack(player); + player.setAttribute("count", vampire); + } + } + break; + case 33502: + player.getPacketDispatch().sendMessage("The cupboard contains garlic. You take a clove."); + if (!player.getInventory().add(new Item(1550))) { + player.getPacketDispatch().sendMessage("Not enough inventory space."); + } + break; + } + break; + case "walk-down": + player.getProperties().setTeleportLocation(BASEMENT); + player.getPacketDispatch().sendMessage("You walk down the stairs..."); + break; + case "walk-up": + player.getProperties().setTeleportLocation(GROUND_FLOOR); + break; + } + return true; + } +} diff --git a/Server/src/main/content/region/misthalin/edgeville/dialogue/BrotherBordissDialogue.kt b/Server/src/main/content/region/misthalin/edgeville/dialogue/BrotherBordissDialogue.kt new file mode 100644 index 0000000..1a14231 --- /dev/null +++ b/Server/src/main/content/region/misthalin/edgeville/dialogue/BrotherBordissDialogue.kt @@ -0,0 +1,95 @@ +package content.region.misthalin.edgeville.dialogue + +import core.game.component.Component +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import org.rs09.consts.Items + +@Initializable +/** + * Handles Boriss' dialogue + * @author Ceikry + */ +class BrotherBordissDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player?): DialoguePlugin { + return BrotherBordissDialogue(player) + } + + override fun npc(vararg messages: String?): Component { + return npc(FacialExpression.OLD_NORMAL,*messages) + } + + override fun open(vararg args: Any?): Boolean { + player ?: return false + if(getSigil(player) != null && player.inventory.contains(Items.BLESSED_SPIRIT_SHIELD_13736,1)){ + player("Can you combine my shield and sigil for me?") + stage = 10 + return true + } + + npc("Lovely day, adventurer.") + stage = 1000 + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 10 -> npc("I certainly can, for the price of","1,500,000 coins.").also { stage++ } + 11 -> options("Okay, sounds great!","No, thanks.").also { stage++ } + 12 -> when(buttonId){ + 1 -> if(player.inventory.contains(995,1500000)){ + player("Okay, sounds great!") + stage = 15 + } else { + player("I'd like to, but I don't have the coin.") + stage++ + } + 2 -> player("No, thanks").also { stage = 1000 } + } + 13 -> npc("That's a shame, then.").also { stage = 1000 } + 15 -> { + npc("Lovely, here you are.") + val sigil = getSigil(player) + if(sigil == null){ + end() + return true + } + if(player.inventory.remove(sigil,Item(995,1500000),Item(Items.BLESSED_SPIRIT_SHIELD_13736))){ + player.inventory.add(getShield(player,sigil)) + } + stage++ + } + 16 -> player("Thank you!").also { stage = 1000 } + + + + 1000 -> end() + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(7724) + } + + + fun getSigil(player: Player): Item?{ + for(sigil in arrayOf(Items.ARCANE_SIGIL_13746,Items.DIVINE_SIGIL_13748,Items.SPECTRAL_SIGIL_13752,Items.ELYSIAN_SIGIL_13750)){ + if(player.inventory.contains(sigil,1)) return Item(sigil) + } + return null + } + + fun getShield(player: Player, sigil: Item): Item?{ + return when(sigil.id){ + Items.ARCANE_SIGIL_13746 -> Item(Items.ARCANE_SPIRIT_SHIELD_13738) + Items.ELYSIAN_SIGIL_13750 -> Item(Items.ELYSIAN_SPIRIT_SHIELD_13742) + Items.DIVINE_SIGIL_13748 -> Item(Items.DIVINE_SPIRIT_SHIELD_13740) + Items.SPECTRAL_SIGIL_13752 -> Item(Items.SPECTRAL_SPIRIT_SHIELD_13744) + else -> null + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/edgeville/dialogue/EdgevilleMonkDialogue.java b/Server/src/main/content/region/misthalin/edgeville/dialogue/EdgevilleMonkDialogue.java new file mode 100644 index 0000000..665ab07 --- /dev/null +++ b/Server/src/main/content/region/misthalin/edgeville/dialogue/EdgevilleMonkDialogue.java @@ -0,0 +1,122 @@ +package content.region.misthalin.edgeville.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.game.world.update.flag.context.Graphics; + +/** + * Reprents the dialogue plugin used for the edgevill monk. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class EdgevilleMonkDialogue extends DialoguePlugin { + + /** + * Represents the animation to use. + */ + private static final Animation ANIMATION = new Animation(710); + + /** + * Represents the graphics to use. + */ + private static final Graphics GRAPHIC = new Graphics(84); + + /** + * Constructs a new {@code EdgevilleMonkDialogue} {@code Object}. + */ + public EdgevilleMonkDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code EdgevilleMonkDialogue} {@code Object}. + * @param player the player. + */ + public EdgevilleMonkDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new EdgevilleMonkDialogue(player); + } + + @Override + public boolean open(Object... args) { + if (args.length >= 1) { + if (args[0] instanceof NPC) { + npc = (NPC) args[0]; + } else { + interpreter.sendDialogues(7727, null, "Only members of our order can go up there. You'll", "need to talk to Abbot Langley if you want to explore", "the monastery further."); + stage = 21; + return true; + } + } + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Greetings traveller."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "Can you heal me? I'm injured.", "Isn't this place built a bit out of the way?", "How do I get further into the monastery?"); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Can you heal me? I'm injured."); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Isn't this place built a bit out of the way?"); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "How do i get farther into the monastery?"); + stage = 30; + break; + + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ok."); + stage = 11; + break; + case 11: + end(); + npc.animate(ANIMATION); + npc.graphics(GRAPHIC); + player.getPacketDispatch().sendMessage("You feel a little better."); + player.getSkills().heal(((int) (player.getSkills().getStaticLevel(Skills.HITPOINTS) * 0.20))); + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "We like it that way actually! We get disturbed less. We still", "get rather a large amount of travellers looking for", "sanctuary and healing here as it is!"); + stage = 21; + break; + case 21: + end(); + break; + case 30: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "You'll need to talk to Abbot Langley about that. He's", "usually to be found walking the halls of the monastery."); + stage = 21; + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 7727 }; + } +} diff --git a/Server/src/main/content/region/misthalin/edgeville/dialogue/EdgevilleShopKeeperDialogue.java b/Server/src/main/content/region/misthalin/edgeville/dialogue/EdgevilleShopKeeperDialogue.java new file mode 100644 index 0000000..94927f4 --- /dev/null +++ b/Server/src/main/content/region/misthalin/edgeville/dialogue/EdgevilleShopKeeperDialogue.java @@ -0,0 +1,80 @@ +package content.region.misthalin.edgeville.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the edgeville shop keeper dialogue. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class EdgevilleShopKeeperDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code EdgevilleShopKeeperDialogue} {@code Object}. + */ + public EdgevilleShopKeeperDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code EdgevilleShopKeeperDialogue} {@code Object}. + * @param player the player. + */ + public EdgevilleShopKeeperDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new EdgevilleShopKeeperDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Can I help you at all?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "Yes, please. What are you selling?", "How should I use your shop?", "No, thanks."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + end(); + npc.openShop(player); + break; + case 2: + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "I'm glad you ask! You can buy as many of the items", "stocked as you wish. You can also sell most items to the", "shop."); + stage = 20; + break; + case 3: + end(); + break; + } + break; + case 20: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 528, 529 }; + } +} diff --git a/Server/src/main/content/region/misthalin/edgeville/dialogue/HariDialogue.java b/Server/src/main/content/region/misthalin/edgeville/dialogue/HariDialogue.java new file mode 100644 index 0000000..be92297 --- /dev/null +++ b/Server/src/main/content/region/misthalin/edgeville/dialogue/HariDialogue.java @@ -0,0 +1,122 @@ +package content.region.misthalin.edgeville.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the hari dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class HariDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code HariDialogue} {@code Object}. + */ + public HariDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code HariDialogue} {@code Object}. + * @param player the player. + */ + public HariDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new HariDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hello."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "Who are you?", "Can you teach me about canoeing?"); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "My name is Hari."); + stage = 10; + break; + case 2: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "It's really quite simple to make. Just walk down to that", "tree on the bank and chop it down."); + stage = 18; + break; + + } + break; + case 10: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "And what are you going here Hari?"); + stage = 11; + break; + case 11: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Like most people who come to Edgeville, I am here to seek", "adventure in the Wilderness."); + stage = 12; + break; + case 12: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I found a secret underground riber that will take me quite", "a long way north."); + stage = 13; + break; + case 13: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Underground river? Where does it come out?"); + stage = 14; + break; + case 14: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "It comes out in a pond located deep in Wilderness."); + stage = 15; + break; + case 15: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I had to find a very special type of canoe to get me up", "the river though, would you like to know more?"); + stage = 16; + break; + case 16: + interpreter.sendOptions("Select an Option", "Yes", "No"); + stage = 17; + break; + case 17: + switch (buttonId) { + case 1: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "It's really quite simple to make. Just walk down to that", "tree on the bank and chop it down."); + stage = 18; + break; + case 2: + end(); + break; + } + break; + case 18: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "When you have done that you can shape the log further", "with your axe to make a canoe."); + stage = 19; + break; + case 19: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 3330 }; + } + +} diff --git a/Server/src/main/content/region/misthalin/edgeville/handlers/EdgevilleNodePlugin.java b/Server/src/main/content/region/misthalin/edgeville/handlers/EdgevilleNodePlugin.java new file mode 100644 index 0000000..34264e2 --- /dev/null +++ b/Server/src/main/content/region/misthalin/edgeville/handlers/EdgevilleNodePlugin.java @@ -0,0 +1,94 @@ +package content.region.misthalin.edgeville.handlers; + +import static core.api.ContentAPIKt.*; +import core.cache.def.impl.SceneryDefinition; +import core.game.component.Component; +import core.game.global.action.ClimbActionHandler; +import core.game.global.action.DoorActionHandler; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the plugin used to handle Edgeville related interactions. + * + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class EdgevilleNodePlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(9262).getHandlers().put("option:take-seed", this); + SceneryDefinition.forId(9261).getHandlers().put("option:take-seed", this); + SceneryDefinition.forId(30806).getHandlers().put("option:take-seed", this); + SceneryDefinition.forId(12265).getHandlers().put("option:climb", this); + + //Dungeon Wilderness gates + SceneryDefinition.forId(29319).getHandlers().put("option:open", this); + SceneryDefinition.forId(29320).getHandlers().put("option:open", this); + + + SceneryDefinition.forId(12266).getHandlers().put("option:open", this); + SceneryDefinition.forId(26933).getHandlers().put("option:open", this); + SceneryDefinition.forId(26934).getHandlers().put("option:close", this); + SceneryDefinition.forId(26934).getHandlers().put("option:climb-down", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + switch (node.getId()) { + case 9262: + case 9261: + case 30806: + sendMessage(player, "There doesn't seem to be any seeds on this rosebush."); + break; + case 12265: + ClimbActionHandler.climb(player, null, Location.create(3078, 3493, 0)); + break; + case 12266: + if (option.equalsIgnoreCase("open")) { + setVarp(player, 680, 1 << 22); + } else if (option.equalsIgnoreCase("close")) { + setVarp(player, 680, 0); + } + break; + case 26933: // Edgeville Dungeon trapdoor (when closed) + if (option.equalsIgnoreCase("open")) { + player.animate(Animation.create(536)); + sendMessage(player, "The trapdoor opens..."); + SceneryBuilder.replace(node.asScenery(), node.asScenery().transform(26934), 500); + } + break; + case 26934: // Edgeville Dungeon trapdoor (when open) + if (option.equalsIgnoreCase("close")) { + player.animate(Animation.create(535)); + sendMessage(player, "You close the trapdoor."); + SceneryBuilder.replace(node.asScenery(), node.asScenery().transform(26933)); + } else if (option.equalsIgnoreCase("climb-down")) { + sendMessage(player, "You climb down through the trapdoor..."); + ClimbActionHandler.climbLadder(player, (Scenery) node, option); + } + break; + case 29319: + case 29320: // Edgeville Dungeon wilderness entrance + if (option.equalsIgnoreCase("open") && player.getLocation().getY() < 9918) { + player.getInterfaceManager().openComponent(382); + player.setAttribute("wildy_gate", node); + } + else{ // Leaving the wilderness + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + } + } + return true; + } + +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/dialogue/BarfyBill.java b/Server/src/main/content/region/misthalin/lumbridge/dialogue/BarfyBill.java new file mode 100644 index 0000000..1207ee0 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/dialogue/BarfyBill.java @@ -0,0 +1,152 @@ +package content.region.misthalin.lumbridge.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the dialogue plugin used for barfy bill. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class BarfyBill extends DialoguePlugin { + + /** + * Constructs a new {@code BarfyBill} {@code Object}. + */ + public BarfyBill() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code BarfyBill} {@code Object}. + * @param player the player. + */ + public BarfyBill(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new BarfyBill(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + player("Hello there."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + npc("Oh! Hello there."); + stage = 1; + break; + case 1: + interpreter.sendOptions("Select an Option", "Who are you?", "Can you teach me about Canoeing?"); + stage = 2; + break; + case 2: + switch (buttonId) { + case 1: + player("Who are you?"); + stage = 1000; + break; + case 2: + npc("It's really quite simple. Just walk down to that tree on", "the water bank and chop it down."); + stage = 24; + break; + } + break; + case 24: + npc("Then take your axe to it and shape it how you like!"); + stage = 26; + break; + case 26: + npc("You look like you know your way around a tree,", "you can make a canoe."); + stage = 27; + break; + case 27: + end(); + break; + case 1000: + npc("My name is Ex Sea Captain Barfy Bill."); + stage = 1001; + break; + case 1001: + player("Ex sea captain?"); + stage = 1002; + break; + case 1002: + npc("Yeah, I bought a lovely ship and was planning to make", "a fortune running her as a merchant vessel."); + stage = 1003; + break; + case 1003: + player("Why are you not still sailing?"); + stage = 1004; + break; + case 1004: + npc("Chronic sea sickness. My first, and only, voyage was", "spent dry heaving over the rails."); + stage = 1005; + break; + case 1005: + npc("If I had known about the sea sickness I could have", "saved myself a lot of money."); + stage = 1006; + break; + case 1006: + player("What are you up to now then?"); + stage = 1007; + break; + case 1007: + npc("Well my ship had a little fire related problem.", "Fortunately it was well insured."); + stage = 1008; + break; + case 1008: + npc("Anyways, I don't have to work anymore so I've taken to", "canoeing on the river."); + stage = 1009; + break; + case 1009: + npc("I don't get river sick!"); + stage = 69; + break; + case 69: + npc("Would you like to know how to make a canoe?"); + stage = 6000; + break; + case 6000: + interpreter.sendOptions("Select an Option", "Yes", "No"); + stage = 504; + break; + case 504: + switch (buttonId) { + case 1: + player("Could you teach me about canoes?"); + stage = 560; + break; + case 2: + end(); + break; + } + break; + case 560: + npc("It's really quite simple. Just walk down to that tree on", "the water bank and chop it down."); + stage = 24; + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 3331 }; + } + +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/dialogue/BobDialogue.java b/Server/src/main/content/region/misthalin/lumbridge/dialogue/BobDialogue.java new file mode 100644 index 0000000..e98e136 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/dialogue/BobDialogue.java @@ -0,0 +1,569 @@ +package content.region.misthalin.lumbridge.dialogue; + +import core.cache.def.impl.ItemDefinition; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import content.data.RepairItem; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.AchievementDiary; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.item.Item; +import content.global.handlers.item.equipment.BarrowsEquipmentRegister; + +/** + * Represents the dialogue plugin used for the bob npc who repairs items. + * @author 'Vexia + * @version 1.0 + */ +public final class BobDialogue extends DialoguePlugin { + + /** + * Represents the item id being repaired. + */ + private int itemId = 0; + + /** + * Represents the item being repaired. + */ + private Item item; + + /** + * Represents the item repairing. + */ + private static RepairItem repairitem = null; + + /** + * The achievement diary. + */ + private final int level = 1; + + /** + * Constructs a new {@code BobDialogue} {@code Object}. + */ + public BobDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code BobDialogue} {@code Object}. + * @param player the player. + */ + public BobDialogue(Player player) { + super(player); + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 754: + options("Yes, please.", "No, thank you."); + stage = 755; + break; + case 755: + switch (buttonId) { + case 1: + player("Yes, please."); + stage = 757; + break; + case 2: + player("No, thank you."); + stage = 756; + break; + } + break; + case 756: + end(); + break; + case 757: + end(); + if (repairitem != null) { + if (!player.getInventory().contains(995, repairitem.getCost())) { + end(); + player.getPacketDispatch().sendMessage("You don't have enough to pay him."); + break; + } + if (!player.getInventory().contains(itemId, 1)) { + end(); + return true; + } + player.getInventory().remove(new Item(995, repairitem.getCost())); + if (player.getInventory().remove(new Item(itemId, 1))) { + player.getInventory().add(repairitem.getProduct()); + } + String cost = "free"; + if (repairitem.getCost() != 0) { + cost = repairitem.getCost() + "gp"; + } + player.getPacketDispatch().sendMessage("Bob fixes your " + ItemDefinition.forId(itemId).getName().toLowerCase().replace("broken", "").trim() + " for " + cost + "."); + } + if (repairitem == null) { + String cost = "free"; + String type = BarrowsEquipment.formatedName(itemId); + String single = BarrowsEquipment.getSingleName(type); + String equipment = BarrowsEquipment.getEquipmentType(type); + String newString = type.toLowerCase().replace(single, "").trim().replace("'s", ""); + StringBuilder newewString = new StringBuilder(); + newewString.append(newString).append(" " + equipment); + final BarrowsEquipment.BarrowsFullEquipment fullequip = BarrowsEquipment.BarrowsFullEquipment.forName(newewString.toString()); + if (BarrowsEquipment.getFormatedCost(equipment, item) != 0) { + cost = String.valueOf(BarrowsEquipment.getFormatedCost(equipment, item) + "gp"); + } + if (!player.getInventory().contains(995, BarrowsEquipment.getFormatedCost(equipment, item))) { + end(); + player.getPacketDispatch().sendMessage("You don't have enough to pay him."); + break; + } + if (fullequip == null || fullequip.getFull() == null) { + player.getPacketDispatch().sendMessage("Report this to an administrator!"); + return true; + } + if (!player.getInventory().contains(itemId, 1)) { + end(); + return true; + } + player.getInventory().remove(new Item(995, BarrowsEquipment.getFormatedCost(equipment, item))); + if (player.getInventory().remove(new Item(itemId, 1))) { + player.getInventory().add(fullequip.getFull()); + } + player.getPacketDispatch().sendMessage("Bob fixes your " + equipment + " for " + cost + "."); + } + break; + case 678: + end(); + break; + case 0: + switch (buttonId) { + case 1: + player("Give me a quest!"); + stage = -5; + break; + case 2: + player("Have you anything to sell?"); + stage = 10; + break; + case 3: + player("Can you repair my items for me?"); + stage = 20; + break; + case 4: + player("I'd like to talk about Achievement Diaries."); + stage = 30; + break; + } + break; + case -5: + interpreter.sendDialogues(npc, FacialExpression.FURIOUS, "Get yer own!"); + stage = -4; + break; + case -4: + end(); + break; + case 10: + npc("Yes! I buy and sell axes! Take your pick (or axe)!"); + stage = 11; + break; + case 11: + end(); + npc.openShop(player); + break; + case 20: + npc("Of course I'll repair it, though the materials may cost", "you. Just hand me the item and I'll have a look."); + stage = 21; + break; + case 21: + end(); + break; + case 30: + if (AchievementDiary.canClaimLevelRewards(player, DiaryType.LUMBRIDGE, level)) { + player("I've done all the medium tasks in my Lumbridge", "Achievement Diary."); + stage = 150; + break; + } + if (AchievementDiary.canReplaceReward(player, DiaryType.LUMBRIDGE, level)) { + player("I've seemed to have lost my explorer's ring..."); + stage = 160; + break; + } + options("What is the Achievement Diary?", "What are the rewards?", "How do I claim the rewards?", "See you later."); + stage = 31; + break; + case 31: + switch (buttonId) { + case 1: + player("What is the Achievement Diary?"); + stage = 110; + break; + case 2: + player("What are the rewards?"); + stage = 120; + break; + case 3: + player("How do I claim the rewards?"); + stage = 130; + break; + case 4: + player("See you later!"); + stage = 140; + break; + } + break; + case 110: + npc("Ah, well, it's a diary that helps you keep track of", "particular achievements you've made in the world of", "Gielinor. In Lumbridge and Draynor I can help you", "discover some very useful things indeed."); + stage++; + break; + case 111: + npc("Eventually with enough exploration you will be", "rewarded for your explorative efforts."); + stage++; + break; + case 112: + npc("You can access your Achievement Diary by going to", "the Quest Journal. When you've opened the Quest", "Journal click on the green star icon on the top right", "hand corner. This will open the diary."); + stage = 30; + break; + case 120: + npc("Ah, well there are different rewards for each", "Achievement Diary. For completing the Lumbridge and", "Draynor diary you are presented with an explorer's", "ring."); + stage++; + break; + case 121: + npc("This ring will become increasingly useful with each", "section of the diary that you complete."); + stage = 30; + break; + case 130: + npc("You need to complete the tasks so that they're all ticked", "off, then you can claim your reward. Most of them are", "straightforward although you might find some required", "quests to be started, if not finished."); + stage++; + break; + case 131: + npc("To claim the explorer's ring speak to Explorer Jack", " in Lumbridge, Ned in Draynor Village or myself."); + stage = 30; + break; + case 140: + end(); + break; + case 150: + npc("Yes I see that, you'll be wanting your", "reward then I assume?"); + stage++; + break; + case 151: + player("Yes please."); + stage++; + break; + case 152: + AchievementDiary.flagRewarded(player, DiaryType.LUMBRIDGE, level); + npc("This ring is a representation of the adventures you", "went on to complete your tasks."); + stage ++; + break; + case 153: + player("Wow, thanks!"); + stage = 30; + break; + case 160: + AchievementDiary.grantReplacement(player, DiaryType.LUMBRIDGE, level); + npc("You better be more careful this time."); + stage = -1; + break; + } + + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new BobDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + boolean repair = false; + boolean wrong = false; + if (npc.getId() == 3797 && args.length == 1) { + player("Can you repair my items for me?"); + stage = 20; + return true; + } + if (args.length == 1) { + options("Give me a quest!", "Have you anything to sell?", "Can you repair my items for me?", "Talk about Achievement Diaries"); + stage = 0; + return true; + } + if (args[1] != null) { + repair = (boolean) args[1]; + } + if (args[2] != null) { + wrong = (boolean) args[2]; + } + if (args[3] != null) { + repairitem = RepairItem.forId((int) args[3]); + itemId = (int) args[3]; + } + if (args[4] != null) { + item = (Item) args[4]; + } + if (repair && !wrong) { + String cost = "free"; + if (repairitem != null) { + if (repairitem.getCost() != 0) { + cost = String.valueOf(repairitem.getCost() + "gp"); + } + } else { + String type = BarrowsEquipment.formatedName(itemId); + String single = BarrowsEquipment.getSingleName(type); + String equipment = BarrowsEquipment.getEquipmentType(type); + String newString = type.toLowerCase().replace(single, "").trim().replace("'s", ""); + StringBuilder newewString = new StringBuilder(); + newewString.append(newString).append(" " + equipment); + if (BarrowsEquipment.getFormatedCost(equipment, item) != 0) { + cost = String.valueOf(BarrowsEquipment.getFormatedCost(equipment, item) + "gp"); + } + } + npc("Quite badly damaged, but easy to repair. Would you", "like me to repair it for " + cost + "?"); + stage = 754; + return true; + } + if (repair == true && wrong == true) { + npc("Sorry friend, but I can't do anything with that."); + stage = 678; + return true; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 519, 3797 }; + } + + /** + * Barrows equipment information. + * @author 'Vexia + */ + public static class BarrowsEquipment { + + /** + * Represents the base names. + */ + private String[] base = new String[] { "dharok", "verac", "ahrim", "torag", "guthan" }; + + /** + * The weapon names. + */ + private static final String[] weapon_names = new String[] { "flail", "greataxe", "spear", "x-bow", "hammer", "hammers", "staff" }; + + /** + * The weapon body names. + */ + private static final String[] body_names = new String[] { "top", "platebody", "body" }; + + /** + * The helm names. + */ + private static final String[] helm_names = new String[] { "hood", "helm", "coif" }; + + /** + * The leg names. + */ + private static final String[] leg_names = new String[] { "skirt", "legs", "plateskirt", "platelegs" }; + + /** + * The prices. + */ + private static final Object[][] prices = new Object[][] { { "weapon", 100 }, { "body", 90 }, { "legs", 80 }, { "helm", 60 } }; + + /** + * Represents the items. + */ + private static final Object[][] ITEMS = { { 4856, "Ahrim's hood" }, { 4857, "Ahrim's hood" }, { 4858, "Ahrim's hood" }, { 4859, "Ahrim's hood" }, { 4860, "Ahrim's hood" }, { 4862, "Ahrim's staff" }, { 4863, "Ahrim's staff" }, { 4864, "Ahrim's staff" }, { 4865, "Ahrim's staff" }, { 4866, "Ahrim's staff" }, { 4868, "Ahrim's top" }, { 4869, "Ahrim's top" }, { 4870, "Ahrim's top" }, { 4871, "Ahrim's top" }, { 4872, "Ahrim's top" }, { 4874, "Ahrim's skirt" }, { 4875, "Ahrim's skirt" }, { 4876, "Ahrim's skirt" }, { 4877, "Ahrim's skirt" }, { 4878, "Ahrim's skirt" }, { 4880, "Dharok's helm" }, { 4881, "Dharok's helm" }, { 4882, "Dharok's helm" }, { 4883, "Dharok's helm" }, { 4884, "Dharok's helm" }, { 4886, "Dharok's greataxe" }, { 4887, "Dharok's greataxe" }, { 4888, "Dharok's greataxe" }, { 4889, "Dharok's greataxe" }, { 4890, "Dharok's greataxe" }, { 4892, "Dharok's platebody" }, { 4893, "Dharok's platebody" }, { 4894, "Dharok's platebody" }, { 4895, "Dharok's platebody" }, { 4896, "Dharok's platebody" }, { 4898, "Dharok's platelegs" }, { 4899, "Dharok's platelegs" }, { 4900, "Dharok's platelegs" }, { 4901, "Dharok's platelegs" }, { 4902, "Dharok's platelegs" }, { 4904, "Guthan's helm" }, { 4905, "Guthan's helm" }, { 4906, "Guthan's helm" }, { 4907, "Guthan's helm" }, { 4908, "Guthan's helm" }, { 4910, "Guthan's spear" }, { 4911, "Guthan's spear" }, { 4912, "Guthan's spear" }, { 4913, "Guthan's spear" }, { 4914, "Guthan's spear" }, { 4916, "Guthan's body" }, { 4917, "Guthan's body" }, { 4918, "Guthan's body" }, { 4919, "Guthan's body" }, { 4920, "Guthan's body" }, { 4922, "Guthan's skirt" }, { 4923, "Guthan's skirt" }, { 4924, "Guthan's skirt" }, { 4925, "Guthan's skirt" }, { 4926, "Guthan's skirt" }, { 4928, "Karil's coif" }, { 4929, "Karil's coif" }, { 4930, "Karil's coif" }, { 4931, "Karil's coif" }, { 4932, "Karil's coif" }, { 4934, "Karil's x-bow" }, { 4935, "Karil's x-bow" }, { 4936, "Karil's x-bow" }, { 4937, "Karil's x-bow" }, { 4938, "Karil's x-bow" }, { 4940, "Karil's top" }, { 4941, "Karil's top" }, { 4942, "Karil's top" }, { 4943, "Karil's top" }, { 4944, "Karil's top" }, { 4946, "Karil's skirt" }, { 4947, "Karil's skirt" }, { 4948, "Karil's skirt" }, { 4949, "Karil's skirt" }, { 4950, "Karil's skirt" }, { 4952, "Torag's helm" }, { 4953, "Torag's helm" }, { 4954, "Torag's helm" }, { 4955, "Torag's helm" }, { 4956, "Torag's helm" }, { 4958, "Torag's hammers" }, { 4959, "Torag's hammers" }, { 4960, "Torag's hammers" }, { 4961, "Torag's hammers" }, { 4962, "Torag's hammers" }, { 4964, "Torag's body" }, { 4965, "Torag's body" }, { 4966, "Torag's body" }, { 4967, "Torag's body" }, { 4968, "Torag's body" }, { 4970, "Torag's legs" }, { 4971, "Torag's legs" }, { 4972, "Torag's legs" }, { 4973, "Torag's legs" }, { 4974, "Torag's legs" }, { 4976, "Verac's helm" }, { 4977, "Verac's helm" }, { 4978, "Verac's helm" }, { 4979, "Verac's helm" }, { 4980, "Verac's helm" }, { 4982, "Verac's flail" }, { 4983, "Verac's flail" }, { 4984, "Verac's flail" }, { 4985, "Verac's flail" }, { 4986, "Verac's flail" }, { 4988, "Verac's top" }, { 4989, "Verac's top" }, { 4990, "Verac's top" }, { 4991, "Verac's top" }, { 4992, "Verac's top" }, { 4994, "Verac's skirt" }, { 4995, "Verac's skirt" }, { 4996, "Verac's skirt" }, { 4997, "Verac's skirt" }, { 4998, "Verac's skirt" } }; + + /** + * Gets the cost. + * @param name the name. + * @return the price. + */ + public static int getFormatedCost(String name, Item item) { + int ticks = BarrowsEquipmentRegister.TICKS; + int[] degrades = new int[] { 100, 75, 50, 25, 0 }; + for (int i = 0; i < prices.length; i++) { + String check = (String) prices[i][0]; + if (check.equals(name)) { + int degrade = 0; + for (int d : degrades) { + if (item.getName().contains(String.valueOf(d))) { + degrade = d; + break; + } + } + degrade -= 25 - (25 * ((double)item.getCharge() / (double)ticks)); + int max = (int) prices[i][1] * 1000; + return (int) (max - (max * (degrade * 0.01))); + } + } + return 0; + } + + /** + * Gets the cost of the item type. + * @param name the name. + * @return the return type. + */ + public static int getCost(String name) { + for (int i = 0; i < prices.length; i++) { + String check = (String) prices[i][0]; + if (check.equals(name)) { + return (int) prices[i][1]; + } + } + return 0; + } + + /** + * Represents if an item is a barrows item. + * @param id the id. + * @return {@code True} if so. + */ + public static boolean isBarrowsItem(int id) { + for (int i = 0; i < ITEMS.length; i++) { + if ((int) ITEMS[i][0] == id) { + return true; + } + } + return false; + } + + /** + * Gets the formatted name. + * @param id the id. + * @return the name. + */ + public static String formatedName(int id) { + for (int i = 0; i < ITEMS.length; i++) { + if ((int) ITEMS[i][0] == id) { + return (String) ITEMS[i][1]; + } + } + return null; + } + + /** + * Gets the equipment type. + * @param name the name. + * @return the type. + */ + public static String getEquipmentType(String name) { + name = name.toLowerCase().replace("verac's", "").replace("karil's", "").replace("dharok's", "").replace("torag's", "").replace("guthan's", "").replace("ahrim's", "").trim(); + for (int i = 0; i < weapon_names.length; i++) { + if (weapon_names[i].contains(name)) { + return "weapon"; + } + } + for (int k = 0; k < body_names.length; k++) { + if (body_names[k].contains(name)) { + return "body"; + } + } + for (int z = 0; z < leg_names.length; z++) { + if (leg_names[z].contains(name)) { + return "legs"; + } + } + for (int q = 0; q < helm_names.length; q++) { + if (helm_names[q].contains(name)) { + return "helm"; + } + } + return null; + } + + /** + * Method used t get its single name. + * @param name the name. + * @return the name. + */ + public static String getSingleName(String name) { + name = name.toLowerCase().replace("verac's", "").replace("karil's", "").replace("dharok's", "").replace("torag's", "").replace("guthan's", "").replace("ahrim's", "").trim(); + for (int i = 0; i < weapon_names.length; i++) { + if (weapon_names[i].contains(name)) { + return weapon_names[i]; + } + } + for (int k = 0; k < body_names.length; k++) { + if (body_names[k].contains(name)) { + return body_names[k]; + } + } + for (int z = 0; z < leg_names.length; z++) { + if (leg_names[z].contains(name)) { + return leg_names[z]; + } + } + for (int q = 0; q < helm_names.length; q++) { + if (helm_names[q].contains(name)) { + return helm_names[q]; + } + } + return null; + } + + /** + * Gets the bases. + * @return the base. + */ + public String[] getBase() { + return base; + } + + /** + * Represents the multiple full barrows equipment items. + * @author 'Vexia + * @version 1.0 + */ + public enum BarrowsFullEquipment { + VERAC_LEGS(new Item(4759, 1)), VERAC_TOP(new Item(4757, 1)), VERAC_WEAPON(new Item(4755, 1)), VERAC_HELM(new Item(4753, 1)), TORAG_LEGS(new Item(4751, 1)), TORAG_BODY(new Item(4749, 1)), TORAG_HELM(new Item(4745, 1)), TORAG_WEAPON(new Item(4747, 1)), KARIL_HELM(new Item(4732, 1)), KARIL_WEAPON(new Item(4734, 1)), KARIL_BODY(new Item(4736, 1)), KARIL_LEGS(new Item(4738, 1)), GUTHAN_HELM(new Item(4724, 1)), GUTHAN_BODY(new Item(4728, 1)), GUTHAN_LEGS(new Item(4730, 1)), GUTHAN_WEAPON(new Item(4726, 1)), DHAROK_HELM(new Item(4716, 1)), DHAROK_BODY(new Item(4720, 1)), DHAROK_LEGS(new Item(4722, 1)), DHAROK_WEAPON(new Item(4718, 1)), AHRIM_HELM(new Item(4708, 1)), AHRIM_BODY(new Item(4712, 1)), AHRIM_LEGS(new Item(4714, 1)), AHRIM_WEAPON(new Item(4710, 1)); + + /** + * Constructs a new {@code BarrowsEquipment} {@code Object}. + * @param full the full item. + */ + BarrowsFullEquipment(Item full) { + this.full = full; + } + + /** + * Represents the full item. + */ + private final Item full; + + /** + * for name + * @param name thename. + * @return the equipment. + */ + public static BarrowsFullEquipment forName(String name) { + if (name.equals("guthan body body")) { + name = "guthan body"; + } else if (name.equals("torag body body")) { + name = "torag body"; + } else if (name.equals("verac body")) { + name = "verac top"; + } + for (BarrowsFullEquipment barrow : BarrowsFullEquipment.values()) { + if (barrow.name().toLowerCase().replace("_", " ").trim().equalsIgnoreCase(name)) { + return barrow; + } + } + return null; + } + + /** + * Gets the full. + * @return The full. + */ + public Item getFull() { + return full; + } + } + + } + +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/dialogue/CandleSellerDialogue.java b/Server/src/main/content/region/misthalin/lumbridge/dialogue/CandleSellerDialogue.java new file mode 100644 index 0000000..f249775 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/dialogue/CandleSellerDialogue.java @@ -0,0 +1,231 @@ +package content.region.misthalin.lumbridge.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.game.node.item.Item; + +/** + * Represents the dialogue plugin used for the candle seller. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class CandleSellerDialogue extends DialoguePlugin { + + /** + * Represents the coins item. + */ + private static final Item COINS = new Item(995, 1000); + + /** + * Represents the candle item. + */ + private static final Item CANDLE = new Item(33, 1); + + /** + * Constructs a new {@code CandleSellerPlugin} {@code Object}. + */ + public CandleSellerDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code CandleSellerPlugin} {@code Object}. + * @param player the player. + */ + public CandleSellerDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new CandleSellerDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Do you want a lit candle for 1000 gold?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "Yes please.", "One thousand gold?!", "No thanks, I'd rather curse the darkness."); + stage = 1; + break; + case 800: + if (player.getInventory().freeSlots() == 0) { + end(); + player.getPacketDispatch().sendMessage("You don't have enough inventory space to buy a candle."); + break; + } + if (!player.getInventory().contains(995, 1000)) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Sorry, I don't seem to have enough coins."); + stage = 30; + break; + } + if (player.getInventory().contains(995, 1000)) { + player.getInventory().remove(COINS); + player.getInventory().add(new Item(33, 1)); + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Here you go then."); + stage = 400; + } + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HAPPY, "Yes please."); + stage = 800; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.EXTREMELY_SHOCKED, "One thousand gold?!"); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.EXTREMELY_SHOCKED, "No thanks, I'd rather curse the darkness."); + stage = 30; + break; + } + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "Look, you're not going to be able to survive down that", "hole without a light source."); + stage = 21; + break; + case 21: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "So you could go off to the candle shop to buy one", "more cheaply. You could even make your own lantern,", "which is a lot better."); + stage = 22; + break; + case 22: + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "But I bet you want to find out what's down there right", "now, don't you? And you can pay me 1000 gold for", "the privilege!"); + stage = 23; + break; + case 23: + interpreter.sendOptions("Select an Option", "All right, you win, I'll buy a candle.", "No way.", "How do you make lanterns?"); + stage = 240; + break; + case 30: + end(); + break; + case 240: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "All right, you win, I'll buy a candle."); + stage = 350; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.ANNOYED, "No way."); + stage = 30; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_ASKING, "How do you make lanterns?"); + stage = 230; + break; + } + break; + case 230: + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "Out of glass. The more advanced lanterns have a", "metal component as well."); + stage = 231; + break; + case 231: + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "Firstly you can make a simple candle lantern out of", "glass. It's just like a candle, but the flame isn't exposed,", "so it's safer."); + stage = 232; + break; + case 232: + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "Then you can make an oil lamp, which is brighter but", "has an exposed flame. But if you make an iron frame", "for it you can turn it into an oil lantern."); + stage = 233; + break; + case 233: + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "Finally there's a Bullseye lantern. You'll need to", "make a frame out of steel and add a glass lens."); + stage = 234; + break; + case 234: + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "Oce you've made your lamp or lantern, you'll need to", "make lamp oil for it. The chemist near Reimmington has", "a machine for that."); + stage = 235; + break; + case 235: + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "For any light source, you'll need a tinderbox to light it.", "Keep your tinderbox handy in case it goes out!"); + stage = 236; + break; + case 236: + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "But if all that's to complicated, you can buy a candle", "right here for 1000 gold!"); + stage = 237; + break; + case 237: + interpreter.sendOptions("Select an Option", "All right, you win, I'll buy a candle.", "No thanks, I'd rather curse the darkness."); + stage = 290; + break; + case 350: + if (player.getInventory().freeSlots() == 0) { + end(); + player.getPacketDispatch().sendMessage("You don't have enough inventory space to buy a candle."); + break; + } + if (!player.getInventory().contains(995, 1000)) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Sorry, I don't seem to have enough coins."); + stage = 30; + break; + } + + if (player.getInventory().remove(COINS)) { + player.getInventory().add(CANDLE); + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Here you go then."); + stage = 400; + } + break; + case 400: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "I should warn you, though, it can be dangerous to take", "a naked flame down there. You'd better off making", "a lantern."); + stage = 401; + break; + case 401: + interpreter.sendDialogues(player, FacialExpression.FRIENDLY, "Okay, thanks."); + stage = 402; + break; + case 402: + end(); + break; + case 290: + switch (buttonId) { + case 1: + if (player.getInventory().freeSlots() == 0) { + end(); + player.getPacketDispatch().sendMessage("You don't have enough inventory space to buy a candle."); + break; + } + if (!player.getInventory().contains(995, 1000)) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Sorry, I don't seem to have enough coins."); + stage = 30; + break; + } + if (player.getInventory().remove(COINS)) { + player.getInventory().add(CANDLE); + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "Here you go then."); + stage = 400; + } + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.EXTREMELY_SHOCKED, "No thanks, I'd rather curse the darkness."); + stage = 291; + break; + } + break; + case 291: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 1834 }; + } +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/dialogue/CookingTutorDialogue.java b/Server/src/main/content/region/misthalin/lumbridge/dialogue/CookingTutorDialogue.java new file mode 100644 index 0000000..c7c2f71 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/dialogue/CookingTutorDialogue.java @@ -0,0 +1,149 @@ +package content.region.misthalin.lumbridge.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Rerpresents the dialogue plugin used for the cooking tutor. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class CookingTutorDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code CookingTutorDialogue} {@code Object}. + */ + public CookingTutorDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code CookingTutorDialogue} {@code Object}. + * @param player the player. + */ + public CookingTutorDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new CookingTutorDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendOptions("Select an Option", "Can you teach me the basics of cooking please?", "Tell me about different food I can make.", "Goodbye."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Can you teach me the basics of cooking please?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Tell me about different food I can make."); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Goodbye."); + stage = 30; + break; + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "The simplest thing to cook is raw meat or fish."); + stage = 11; + break; + case 11: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Fish can be caught, speak to the fishing tutor south of", "here in the swamp. Killing cows or chickens will yield", "raw meat to cook too."); + stage = 12; + break; + case 12: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "You can use your own fire... but it's not as effective", "and you'll burn more. To build a fire use a tinderbox", "on logs."); + stage = 13; + break; + case 13: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Once you've found your range, click on your raw", "meat or fish in your inventory, then click on the", "cooking range. This will bring up an interface which", "you can right-click on to select the number to cook."); + stage = 14; + break; + case 14: + interpreter.sendOptions("Select an Option", "Can you teach me the basics of cooking please?", "Tell me about different food I can make.", "Goodbye."); + stage = 0; + break; + case 20: + interpreter.sendOptions("Select an Option", "Fish and Meat", "Brewing", "Vegetables", "Pie", "Go back to teaching"); + stage = 21; + break; + case 21: + switch (buttonId) { + case 1: + interpreter.sendDoubleItemMessage(2132, 2142, "Fish and meat of most varieties can be cooked very simply on either a fire or range, experiment which one works for you."); + stage = 20; + break; + case 2: + interpreter.sendDoubleItemMessage(1911, 1905, "You can brew your own beers using the fermenting vats in either Keldagrim or Port Phasmatys. Use two buckets of water, two handfuls of barley malt, 4 hops of your choice and a pot of ale yeast, then leave to"); + stage = 220; + break; + case 3: + interpreter.sendDoubleItemMessage(1942, 7058, "Baked potatoes are excellent foods and they are healthy too! You'll need to churn some butter and cheese. Look for the churn icon on the mini map. There is a churn in the farm building northwest of Lumbridge."); + stage = 230; + break; + case 4: + interpreter.sendDoubleItemMessage(1929, 1933, "Use a pot of flour with a bucket of water. You will then get an option to make bread dough, pitta bread dough, pastry dough, or pizza dough. Select pizza or pastry dough."); + stage = 240; + break; + case 5: + interpreter.sendOptions("Select an Option", "Can you teach me the basics of cooking please?", "Tell me about different food I can make.", "Goodbye."); + stage = 0; + break; + } + break; + case 220: + interpreter.sendDoubleItemMessage(1911, 1905, "ferment for a few days!"); + stage = 221; + break; + case 221: + interpreter.sendDoubleItemMessage(1911, 1905, "Simply turn the tap and let the ale flow into the barrel next to the vat, then use empty beer glasses on the barrel."); + stage = 20; + break; + case 230: + interpreter.sendDoubleItemMessage(6697, 1985, "The nearest dairy cow is noth of the nearby water mill. Take buckets of milk with you to the churn and use the milk on the churn to make butter or cheese."); + stage = 20; + break; + case 240: + interpreter.sendDoubleItemMessage(2313, 1953, "Use the pastry dough with a pie dish then add your filling such as apple or red berries."); + stage = 241; + break; + case 241: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Finally cook your pie by using the unbaked pie on a", "cooking range. Mmmm...pie."); + stage = 242; + break; + case 242: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "There's pizza too! Find yourself some tomato and", "cheese, use on the Pizza dough. Cook the pizza on a", "range then add any other topping you want, such as", "anchovies."); + stage = 20; + break; + case 30: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 4899 }; + } +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/dialogue/CraftingTutorDialogue.java b/Server/src/main/content/region/misthalin/lumbridge/dialogue/CraftingTutorDialogue.java new file mode 100644 index 0000000..d514579 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/dialogue/CraftingTutorDialogue.java @@ -0,0 +1,73 @@ +package content.region.misthalin.lumbridge.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the dialogue plugin used for the crafting tutor. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class CraftingTutorDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code CraftingTutorDialogue} {@code Object}. + */ + public CraftingTutorDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code CraftingTutorDialogue} {@code Object}. + * @param player the player. + */ + public CraftingTutorDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new CraftingTutorDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Can you teach me the basics of crafting please?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Firstly, you should know that not all places associated", "with crafting will be marked on your mini map. Some", "take quite a bit of hunting down to find, don't lose", "heart!"); + stage = 1; + break; + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I see... so where should I start?"); + stage = 2; + break; + case 2: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "When you have a full inventory, take it to the bank,", "you can find it on the roof of this very castle."); + stage = 3; + break; + case 3: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 4900 }; + } +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/dialogue/DonieDialogue.kt b/Server/src/main/content/region/misthalin/lumbridge/dialogue/DonieDialogue.kt new file mode 100644 index 0000000..d699af8 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/dialogue/DonieDialogue.kt @@ -0,0 +1,59 @@ +package content.region.misthalin.lumbridge.dialogue + +import core.api.* +import core.game.dialogue.* +import core.game.node.entity.player.Player +import core.game.world.GameWorld +import core.game.world.GameWorld.settings +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class DonieDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return DonieDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, DonieDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.DONIE_2238) + } +} + +class DonieDialogueFile : DialogueLabeller() { + override fun addConversation() { + assignToIds(NPCs.DONIE_2238) + + npc(ChatAnim.FRIENDLY, "Hello there, can I help you?") + options( + DialogueOption("whereami", "Where am I?", expression = ChatAnim.THINKING), + DialogueOption("howareyou", "How are you today?"), + DialogueOption("shoelace", "Your shoe lace is untied.", skipPlayer=true), + ) + + label("whereami") + npc("This is the town of Lumbridge my friend.") + + label("howareyou") + npc("Aye, not too bad thank you. Lovely weather in", ""+ (GameWorld.settings?.name ?: "2009Scape") +" this fine day.") + player("Weather?") + npc("Yes weather, you know.") + npc("The state or condition of the atmosphere at a time and", "place, with respect to variables such as temperature,", "moisture, wind velocity, and barometric pressure.") + player("...") + npc("Not just a pretty face eh? Ha ha ha.") + + label("shoelace") + open(player!!, DonieDialogueShoelaceFile(), npc!!) + + } +} +class DonieDialogueShoelaceFile : DialogueLabeller() { + override fun addConversation() { + player("Your shoe lace is untied.") + npc(ChatAnim.ANGRY, "No it's not!") + player("No you're right. I have nothing to back that up.") + npc(ChatAnim.ANGRY, "Fool! Leave me alone!") + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/dialogue/DoomsayerDialogue.java b/Server/src/main/content/region/misthalin/lumbridge/dialogue/DoomsayerDialogue.java new file mode 100644 index 0000000..76f0161 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/dialogue/DoomsayerDialogue.java @@ -0,0 +1,131 @@ +package content.region.misthalin.lumbridge.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.link.diary.DiaryType; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the dialogue plugin used for the doomsayer. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class DoomsayerDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code DoomsayerDialogue} {@code Object}. + */ + public DoomsayerDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code DoomsayerDialogue} {@code Object}. + * @param player the player. + */ + public DoomsayerDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new DoomsayerDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Dooooom!"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Where?"); + stage = 1; + break; + case 1: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "All around us! I can feel it in the air, hear it on the", "wind smell it....also in the air!"); + stage = 2; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Is there anything we can do about this doom?"); + stage = 3; + break; + case 3: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "There is nothing you need to do my friend! I am the", "Doomsayer, although my real title could be something like", "the Danger Tutor."); + stage = 4; + break; + case 4: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Danger Tutor?"); + stage = 5; + break; + case 5: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Yes! I roam the world sensing danger."); + stage = 6; + break; + case 6: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "If I find a dangerous area, then I put up warning signs", "that will tell you what is so dangerous about that area."); + stage = 7; + break; + case 7: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "If you see the signs often enough, then you can", "turn them off; by that time you likely know what the", "area has in store for you."); + stage = 8; + break; + case 8: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "But what if I want to see the warning again?"); + stage = 9; + break; + case 9: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "That's why I'm waiting here!"); + stage = 10; + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "If you want to see the warning messages again, I", "can turn them back on for you."); + stage = 11; + break; + case 11: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Do you need to turn on any warning right now?"); + stage = 12; + break; + case 12: + interpreter.sendOptions("Select an Option", "Yes, I do.", "Not right now."); + stage = 13; + break; + case 13: + switch (buttonId) { + case 1: + end(); + player.getWarningMessages().open(player); + break; + case 2: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ok, keep an eye out for the messages though!"); + stage = 30; + break; + } + player.getAchievementDiaryManager().finishTask(player, DiaryType.LUMBRIDGE, 0, 3); + break; + case 30: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, " I will."); + stage = 31; + break; + case 31: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 3777 }; + } +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/dialogue/DukeHoracioDialogue.kt b/Server/src/main/content/region/misthalin/lumbridge/dialogue/DukeHoracioDialogue.kt new file mode 100644 index 0000000..da9ead1 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/dialogue/DukeHoracioDialogue.kt @@ -0,0 +1,87 @@ +package content.region.misthalin.lumbridge.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import content.region.misthalin.varrock.quest.dragonslayer.DragonSlayer +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import content.region.misthalin.varrock.quest.dragonslayer.DukeHoracioDSDialogue +import content.region.misthalin.lumbridge.quest.runemysteries.DukeHoracioRMDialogue +import content.region.misthalin.dorgeshuun.quest.thelosttribe.DukeHoracioTLTDialogue +import core.tools.DIALOGUE_INITIAL_OPTIONS_HANDLE +import core.tools.END_DIALOGUE +import content.data.Quests + +/** + * Core dialogue plugin for Duke Horacio, redirects to more specific DialogueFiles. + * @author Ceikry + */ +class DukeHoracioDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun getIds(): IntArray { + return intArrayOf(741) + } + + override fun open(vararg args: Any): Boolean { + npc = args[0] as NPC + if ((player.questRepository.getQuest(Quests.DRAGON_SLAYER).getStage(player) == 100 && !player.inventory.containsItem(DragonSlayer.SHIELD) && !player.bank.containsItem(DragonSlayer.SHIELD) )|| (player.questRepository.getQuest(Quests.DRAGON_SLAYER).isStarted(player) && !player.questRepository.getQuest(Quests.DRAGON_SLAYER).isCompleted(player))) { + addOption("Dragon Slayer", DukeHoracioDSDialogue(player.questRepository.getStage(Quests.DRAGON_SLAYER))) + } + if (!player.questRepository.isComplete(Quests.THE_LOST_TRIBE) && player.questRepository.getQuest(Quests.THE_LOST_TRIBE).isStarted(player)) { + addOption("Lost Tribe", DukeHoracioTLTDialogue(player.questRepository.getStage(Quests.THE_LOST_TRIBE))) + } + if (!sendChoices()) { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Greetings. Welcome to my castle.") + } + + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + + DIALOGUE_INITIAL_OPTIONS_HANDLE -> { + npc("Greetings. Welcome to my castle.") + loadFile(optionFiles[buttonId - 1]) + } + + 0 -> { + interpreter.sendOptions("Select an Option", "Have you any quests for me?", "Where can I find money?") + stage = 1 + } + 1 -> when (buttonId) { + 1 -> { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Have any quests for me?") + stage = 20 + } + 2 -> { + interpreter.sendDialogues( + npc, + FacialExpression.HALF_GUILTY, + "I hear many of the local people earn money by learning a", + "skill. Many people get by in life by becoming accomplished", + "smiths, cooks, miners and woodcutters." + ) + stage = END_DIALOGUE + } + } + 20 -> { + npc("Let me see...") + if (!player.questRepository.isComplete(Quests.RUNE_MYSTERIES)) { + loadFile(DukeHoracioRMDialogue(player.questRepository.getStage(Quests.RUNE_MYSTERIES))) + } else { + stage++ + } + } + 21 -> { + npc("Nope, I've got everything under control", "in the castle at the moment.") + stage = END_DIALOGUE + } + } + return true + } + + override fun newInstance(player: Player): DialoguePlugin { + return DukeHoracioDialogue(player) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/dialogue/ExplorerJackDialogue.java b/Server/src/main/content/region/misthalin/lumbridge/dialogue/ExplorerJackDialogue.java new file mode 100644 index 0000000..52339c8 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/dialogue/ExplorerJackDialogue.java @@ -0,0 +1,168 @@ +package content.region.misthalin.lumbridge.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.AchievementDiary; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.entity.player.link.emote.Emotes; +import core.plugin.Initializable; + +/** + * Handles the explorer jack dialogue. + * @author Vexia + * + */ +@Initializable +public class ExplorerJackDialogue extends DialoguePlugin { + + /** + * The achievement diary. + */ + private final int level = 0; + + /** + * Constructs the new {@code ExplorerJackDialogue} + */ + public ExplorerJackDialogue() { + /* + * empty. + */ + } + + /** + * Constructs the new {@code ExplorerJackDialogue} + * @param player The player. + */ + public ExplorerJackDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new ExplorerJackDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc("What ho! Where did you come from?"); + stage = 1; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case -1: + if (AchievementDiary.canClaimLevelRewards(player, DiaryType.LUMBRIDGE, level)) { + player("I've done all the beginner tasks in my Lumbridge", "Achievement Diary."); + stage = 50; + break; + } + if (AchievementDiary.canReplaceReward(player, DiaryType.LUMBRIDGE, level)) { + player("I've seemed to have lost my explorer's ring..."); + stage = 60; + break; + } + options("What is the Achievement Diary?", "What are the rewards?", "How do I claim the rewards?", "See you later."); + stage = 0; + break; + case 0: + switch (buttonId) { + case 1: + player("What is the Achievement Diary?"); + stage = 10; + break; + case 2: + player("What are the rewards?"); + stage = 20; + break; + case 3: + player("How do I claim the rewards?"); + stage = 30; + break; + case 4: + player("See you later!"); + stage = 40; + break; + } + break; + case 1: + player("Oh sorry. I was just looking around."); + stage++; + break; + case 2: + npc("Oh thats perfectly alright. Mi Casa and all that what!"); + stage++; + break; + case 3: + player("Uh... and all what?"); + stage++; + break; + case 4: + npc("Splendid! I love a person with a sense of humour. I bet", "you're from Ardougne, eh? Ha!"); + stage = -1; + break; + case 10: + npc("Ah, well, it's a diary that helps you keep track of", "particular achievements you've made in the world of Gielinor. In Lumbridge and Draynor I can help you", "discover some very useful things indeed."); + stage++; + break; + case 11: + npc("Eventually with enough exploration you will be", "rewarded for your explorative efforts."); + stage++; + break; + case 12: + npc("You can access your Achievement Diary by going to", "the Quest Journal. When you've opened the Quest", "Journal click on the green star icon on the top right", "hand corner. This will open the diary."); + stage = -1; + break; + case 20: + npc("Ah, well there are different rewards for each", "Achievement Diary. For completing the Lumbridge and", "Draynor diary you are presented with an explorer's", "ring."); + stage++; + break; + case 21: + npc("This ring will become increasingly useful with each", "section of the diary that you complete."); + stage = -1; + break; + case 30: + npc("You need to complete the tasks so that they're all ticked", "off then you can claim your reward. Most of them are", "straightforward although you might find some required", "quests to be started, if not finished."); + stage++; + break; + case 31: + npc("To claim the explorer's ring speak to Bob in Bob's", "Axes in Lumbridge, Ned in Draynor Village or myself."); + stage = -1; + break; + case 40: + end(); + break; + case 50: + npc("Yes I see that, you'll be wanting your", "reward then I assume?"); + stage++; + break; + case 51: + player("Yes please."); + stage++; + break; + case 52: + AchievementDiary.flagRewarded(player, DiaryType.LUMBRIDGE, level); + player.getEmoteManager().unlock(Emotes.EXPLORE); + npc("This ring is a representation of the adventures you", "went on to complete your tasks."); + stage ++; + break; + case 53: + player("Wow, thanks!"); + stage = -1; + break; + case 60: + AchievementDiary.grantReplacement(player, DiaryType.LUMBRIDGE, level); + npc("You better be more careful this time."); + stage = -1; + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] {7969}; + } + +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/dialogue/FishingTutorDialogue.java b/Server/src/main/content/region/misthalin/lumbridge/dialogue/FishingTutorDialogue.java new file mode 100644 index 0000000..5f0cb3a --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/dialogue/FishingTutorDialogue.java @@ -0,0 +1,161 @@ +package content.region.misthalin.lumbridge.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the fishing tutor dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class FishingTutorDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code FishingTutorDialogue} {@code Object}. + */ + public FishingTutorDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code FishingTutorDialogue} {@code Object}. + * @param player the player. + */ + public FishingTutorDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new FishingTutorDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendOptions("Select an Option", "Can you teach me the basics of fishing please?", "Tell me about different fish.", "Where and what should I fish?", "Goodbye."); + stage = 1; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.ASKING, "Can you teach me the basics of fishing please?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_ASKING, "Tell me about different fish."); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.ASKING, "Where and what should I fish?"); + stage = 30; + break; + case 4: + interpreter.sendDialogues(player, FacialExpression.FRIENDLY, "Goodbye."); + stage = 40; + break; + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Ahoy, to fish, you click on your net in your inventory,", "then on the fishin' spot to put it in. Then you pull the", "net out and see if you got any shrimp."); + stage = 11; + break; + case 11: + interpreter.sendDialogues(player, FacialExpression.THINKING, "I see.. is that it?"); + stage = 12; + break; + case 12: + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "There's far more as you progress, not just shrimps,", "you get more equipment, bigger fish and other things", "too..."); + stage = 13; + break; + case 13: + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "When you have a full inventory, you can cook it or", "take it to the bank. You can find a bank on the roof of", "the castle in Lumbridge and a cookin' range in the", "castles kitchen."); + stage = 14; + break; + case 14: + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "Arrr.. if yer lookin' fer quests you should head to", "the Mountain Dwarf who lies north-west of Taverley", "and have a chat with him, I'm sure he can point you in", "the right direction."); + stage = 15; + break; + case 15: + interpreter.sendOptions("Select an Option", "Can you teach me the basics of fishing please?", "Tell me about different fish.", "Where and what should I fish?", "Goodbye."); + stage = 1; + break; + case 20: + interpreter.sendOptions("Select an Option", "Small Net Fish", "Big Net Fish", "Rod and Fly Fishing", "Tell me about..."); + stage = 21; + break; + case 21: + switch (buttonId) { + case 1: + interpreter.sendItemMessage(303, "Ahoy, small net fishin' you can do just south of Draynor Village and in these very spots here. Aye."); + stage = 210; + break; + case 2: + interpreter.sendItemMessage(305, "Aye, you can net yourself some big fish in Catherby, which is a good place to fish for most things, Gar!"); + stage = 220; + break; + case 3: + interpreter.sendItemMessage(307, "Aye, rod fishin' can be practiced here at these spots, as well as south of Draynor Village and in the Lumbridge river, depending upon your experience. You can get bait at any fishin' shop, there be one in Port Sarim."); + stage = 230; + break; + case 4: + interpreter.sendOptions("Select an Option", "Can you teach me the basics of fishing please?", "Tell me about different fish.", "Where and what should I fish?", "Goodbye."); + stage = 1; + break; + } + break; + case 210: + interpreter.sendItemMessage(315, "Shrimps and anchovies can be caught with your small fishin' net"); + stage = 20; + break; + case 220: + interpreter.sendItemMessage(355, "Mackerel and Cod will form the backbone of your catch when big net fishin'.. except for the added extras..."); + stage = 221; + break; + case 221: + interpreter.sendDialogues(npc, null, "Some rich rewards for big net fishin', make sure you be", "using a big net fishing spot though..."); + stage = 20; + break; + case 230: + interpreter.sendItemMessage(351, "With a rod you can catch pike, sardines and herring. Good eating on them."); + stage = 231; + break; + case 231: + interpreter.sendItemMessage(309, "The art of fly fishin' can be done in rivers, so the Lumbridge river here would suffice."); + stage = 232; + break; + case 232: + interpreter.sendItemMessage(329, "Aye, you can catch yourself a delicious trout or salmon."); + stage = 20; + break; + case 30: + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "Herrin' can be fished from Catherby and some other", "places when you reach level 10."); + stage = 31; + break; + case 31: + interpreter.sendOptions("Select an Option", "Can you teach me the basics of fishing please?", "Tell me about different fish.", "Where and what should I fish?", "Goodbye."); + stage = 1; + break; + case 40: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 4901 }; + } +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/dialogue/FredTheFarmerDialogue.kt b/Server/src/main/content/region/misthalin/lumbridge/dialogue/FredTheFarmerDialogue.kt new file mode 100644 index 0000000..357c76e --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/dialogue/FredTheFarmerDialogue.kt @@ -0,0 +1,48 @@ +package content.region.misthalin.lumbridge.dialogue + +import content.region.misthalin.lumbridge.quest.sheepshearer.SSFredTheFarmerDialogue +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.IfTopic +import core.game.dialogue.Topic +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import content.data.Quests + +@Initializable +class FredTheFarmerDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun getIds(): IntArray { + return intArrayOf(758) + } + + override fun open(vararg args: Any): Boolean { + npc = args[0] as NPC + if (getQuestStage(player, Quests.SHEEP_SHEARER) in 1..99) { + openDialogue(player, SSFredTheFarmerDialogue(getQuestStage(player, Quests.SHEEP_SHEARER)), npc) + } else { + npc(FacialExpression.ANGRY, "What are you doing on my land? You're not the one", "who keeps leaving all my gates open and letting out all", "my sheep are you?").also { stage = START_DIALOGUE } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + START_DIALOGUE -> showTopics( + IfTopic(FacialExpression.NEUTRAL, "I'm looking for a quest.", 1000, getQuestStage(player!!, Quests.SHEEP_SHEARER) == 0), + Topic(FacialExpression.HALF_GUILTY, "I'm looking for something to kill.", 100), + Topic(FacialExpression.HALF_GUILTY, "I'm lost.", 200) + ) + + 100 -> npc(FacialExpression.HALF_GUILTY, "What, on my land? Leave my livestock alone you", "scoundrel!").also { stage = END_DIALOGUE } + + 200 -> npc(FacialExpression.HALF_GUILTY, "How can you be lost? Just follow the road east and", "south. You'll end up in Lumbridge fairly quickly.").also { stage = END_DIALOGUE } + + 1000 -> openDialogue(player, SSFredTheFarmerDialogue(getQuestStage(player, Quests.SHEEP_SHEARER)), npc) + } + return true + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/dialogue/GeeDialogue.java b/Server/src/main/content/region/misthalin/lumbridge/dialogue/GeeDialogue.java new file mode 100644 index 0000000..5fdc5bc --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/dialogue/GeeDialogue.java @@ -0,0 +1,128 @@ +package content.region.misthalin.lumbridge.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the dialogue plugin used for the gee npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class GeeDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code GeeDialogue} {@code Object}. + */ + public GeeDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code GeeDialogue} {@code Object}. + * @param player the player. + */ + public GeeDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new GeeDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hello there, can I help you?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "What's up?", "Are there any quests I can do here?", "Can I buy your stick?"); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What's up?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Do you know of any quests I can do?"); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Can I buy your stick?"); + stage = 30; + break; + + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I assume the sky is up.."); + stage = 11; + break; + case 11: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "You assume?"); + stage = 12; + break; + case 12: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Yeah, unfortunately I don't seem to be able to look up."); + stage = 13; + break; + case 13: + end(); + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Nope, sorry."); + stage = 21; + break; + case 21: + end(); + break; + case 30: + interpreter.sendDialogues(npc, FacialExpression.FURIOUS, "It's not a stick! I'll have you know it's a very powerful", "staff!"); + stage = 31; + break; + case 31: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Really? Show me what it can do!"); + stage = 32; + break; + case 32: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Um..It's a bit low on power at the moment.."); + stage = 33; + break; + case 33: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "It's a stick isn't it?"); + stage = 34; + break; + case 34: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "...Ok it's a stick.. But only while I save up for a staff.", "Zaff in Varrock square sells them in his shop."); + stage = 35; + break; + case 35: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Well good luck with that."); + stage = 36; + break; + case 36: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 2237 }; + } +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/dialogue/HansDialoguePlugin.java b/Server/src/main/content/region/misthalin/lumbridge/dialogue/HansDialoguePlugin.java new file mode 100644 index 0000000..97610d3 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/dialogue/HansDialoguePlugin.java @@ -0,0 +1,410 @@ +package content.region.misthalin.lumbridge.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.link.IronmanMode; +import core.game.world.map.zone.ZoneBorders; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +import static core.tools.DialogueConstKt.END_DIALOGUE; + + +/** + * Represents the dialogue plugin used for the hans npc. + */ +@Initializable +public final class HansDialoguePlugin extends DialoguePlugin { + + private int[] timePlayed = new int[3]; + private int joinDateDays; + private boolean inStartDungeon; + + /** + * Constructs a new {@code HansDialoguePlugin} {@code Object}. + */ + public HansDialoguePlugin() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code HansDialoguePlugin} {@code Object}. + * @param player the player. + */ + public HansDialoguePlugin(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new HansDialoguePlugin(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "Hello. What are you doing here?"); + stage = 0; + if (new ZoneBorders(2528, 5004, 2520, 4997).insideBorder(player.getLocation())) { + inStartDungeon = true; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + + if (inStartDungeon && stage == 0) { + stage = 1; + buttonId = 4; + } + + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "I'm looking for whoever is in charge of this place.", "I have come to kill everyone in this castle!", "I don't know. I'm lost. Where am I?", "Have you been here as long as me?"); + stage++; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "Who, the Duke? He's in his study, on the first floor."); + stage = 50; + break; + case 2: + end(); + //TODO: + // Face the player and walk away from them (like moon walking?). + // After a moment, return to normal pathing associated with HansNPC.java + npc.sendChat("Help! Help!"); + break; + case 3: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "You are in Lumbridge Castle."); + stage = 50; + break; + case 4: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "I've been patrolling this castle for years!"); + stage = 41; + break; + } + break; + case 10: + switch (buttonId) { + case 1: + //Have you been here as long as me? + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "I've been patrolling this castle for years!"); + stage = 41; + break; + case 2: + npc("Your current XP rate is: " + player.getSkills().experienceMultiplier); + stage = 11; + break; + case 3: + //About Iron Man Mode... + if (player.getIronmanManager().isIronman()) { + npc("Your ironman mode is: " + player.getIronmanManager().getMode().name().toLowerCase()); + stage = 50; + } else { + interpreter.sendOptions("Select an Option", "I would like to be an Iron Man.", "What is an Iron Man?", "Go Back..."); + stage = 110; + } + break; + case 4: + interpreter.sendDialogue("Randoms are now permanently enabled. This option to be removed","at a later date."); + stage = END_DIALOGUE; + break; + case 5: // Go back + interpreter.sendOptions("Select an Option", "I'm looking for whoever is in charge of this place.", "I have come to kill everyone in this castle!", "I don't know. I'm lost. Where am I?", "More Options..."); + stage = 1; + break; + } + break; + + case 11: + if (player.getSkills().experienceMultiplier == 5.0) { + player.newPlayer = player.getSkills().getTotalLevel() < 50; + options("Change xp rate", "Nevermind."); + stage++; + } else { + npc("Have a great day!"); + stage = 131; + } + break; + case 12: + switch(buttonId){ + case 1: + if(player.getAttributes().containsKey("permadeath")){ + options("1.0x", "2.5x", "Stay 5.0x", "(HCIM Only) 10x"); + } else { + options("1.0x", "2.5x", "Stay 5.0x"); + } + stage++; + break; + case 2: + npc(FacialExpression.LAUGH, "Haha, alright then!"); + stage = 50; + break; + } + break; + case 13: + switch(buttonId){ + case 1: + if(player.newPlayer) { + player.getSkills().experienceMultiplier = 1.0; + stage = 14; + } else { + stage = 15; + break; + } + break; + case 2: + if(player.newPlayer){ + player.getSkills().experienceMultiplier = 2.5; + stage = 14; + } else { + stage = 15; + } + break; + case 3: + playerl(FacialExpression.FRIENDLY, "I'd rather stay 5x, thank you."); + stage = END_DIALOGUE; + return true; + case 4: + if (player.newPlayer) { + player.getSkills().experienceMultiplier = 10.0; + stage = 14; + } else { + stage = 15; + } + break; + } + npc("One moment, please..."); + break; + case 14: + npc("Tada, your xp rate is now " + player.getSkills().experienceMultiplier); + stage = 131; + break; + case 15: + npc("Sorry, only new accounts can select 2.5x."); + stage = 131; + break; + //Have you been here as long as me? + case 41: + interpreter.sendDialogues(player, FacialExpression.THINKING, "You must be old then?"); + stage++; + break; + case 42: + interpreter.sendDialogues(npc, FacialExpression.LAUGH, "Haha, you could say I'm quite the veteran of these lands.", "Yes, I've been here a fair while..."); + stage++; + break; + case 43: //mixing OSRS here + interpreter.sendDialogues(player, FacialExpression.ASKING, "Can you tell me how long I've been here?"); + stage++; + break; + case 44: + if (!inStartDungeon) { + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "Ahh, I see all the newcomers arriving in Lumbridge, ","fresh-faced and eager for adventure. I remember you..."); + player.sendMessage("Feature not currently available."); + } else { + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "Ahh, I see all the newcomers arriving in Lumbridge, ","fresh-faced and eager for adventure.", "But this is the first time meeting you..."); + } + stage = 50; + break; + //TODO: + /*case 45: + getTimePlayed(); + + //The text: + //NOTE: it splits the text in different spots if the hours/minutes/days are 0 (because 0 days sounds weird, so it doesn't show it). + + //You've spent [amount] days, [amount] hours, [amount] minutes in the world (NEXT LINE) since you arrived [amount] days ago. + //You've spent [amount] (days/hours), [amount] (hours/minutes) in the world since (NEXT LINE) you arrived [amount] days ago. + //You've spent [amount] (days/hours/minutes) in the world since you arrived (NEXT LINE) [amount] days ago. + */ + + //Closing Chat + case 50: + end(); + break; + + //About Iron Man Mode... + case 100: + switch (buttonId) { + case 1: //no longer want to be iron + if (player.getSavedData().getActivityData().getHardcoreDeath() == true) { + interpreter.sendDialogues(npc, FacialExpression.GUILTY, "Sorry, but you've fallen as a Hardcore Iron Man", "already. It would be unfair for those with other", " restrictions if your status were to be removed!"); + stage = 50; + break; + } + if (player.getSkills().getTotalLevel() > 500 || player.getQuestRepository().getPoints() > 10){ + interpreter.sendDialogues(npc, FacialExpression.GUILTY, "Sorry, but you are too far along your journey.", "It would be unfair for those with other", " restrictions if your status were to be removed!"); + stage = 50; + break; + } else { + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "I have removed your Iron Man status."); + player.getIronmanManager().setMode(IronmanMode.NONE); + player.sendMessage("Your Iron Man status has been removed."); + stage = 50; + break; + } + case 2: //change ironman mode + if (player.getSavedData().getActivityData().getHardcoreDeath() == true) { + interpreter.sendDialogues(npc, FacialExpression.GUILTY, "Sorry, but you've fallen as a Hardcore Iron Man", "already. It would be unfair for those with other", " restrictions if your status were to be changed!"); + stage = 50; + break; + } + if (player.getSkills().getTotalLevel() > 500 || player.getQuestRepository().getPoints() > 10){ + interpreter.sendDialogues(npc, FacialExpression.GUILTY, "Sorry, but you are too far along your journey.", "It would be unfair for those with other", " restrictions if your status were to be changed!"); + stage = 50; + break; + } else { + interpreter.sendOptions("Select a Mode", "Standard", "Hardcore", "Ultimate", "Nevermind."); + stage = 150; + break; + } + case 3: // What is Iron Man Mode? + interpreter.sendDialogues(player, FacialExpression.ASKING,"What is an Iron Man?"); + stage = 120; + break; + case 4: //Go back. + interpreter.sendOptions("Select an Option", "Have you been here as long as me?", "I'd like to learn faster!", "About Iron Man mode...", "Go Back..."); + stage = 10; + break; + } + break; + case 110: + switch (buttonId) { + case 1: //I would like to be an Iron Man + if (player.getSkills().getTotalLevel() > 50 || player.getQuestRepository().getPoints() > 10){ + interpreter.sendDialogues(npc, FacialExpression.GUILTY, "Sorry, but you are too far along your journey.", "It would be unfair for those with other", " restrictions if your status were to be changed!"); + stage = 50; + break; + } else { + interpreter.sendOptions("Select a Mode", "Standard", "Hardcore", "Ultimate", "Nevermind."); + stage = 150; + break; + } + case 2: // What is Iron Man Mode? + player("What is an Iron Man?"); + stage = 120; + break; + case 3: //Go back. + interpreter.sendOptions("Select an Option", "Have you been here as long as me?", "I'd like to learn faster!", "About Iron Man mode...", "Go Back..."); + stage = 10; + break; + } + break; + + //What is an Iron Man? + case 120: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL,"An Iron Man account is a style of playing where players", "are completely self-sufficient."); + stage++; + break; + case 121: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL,"A Standard Ironman does not receive items or", "assistance from other players. They cannot trade, stake,", "receive PK loot, scavenge dropped items, nor play", "certain minigames."); + stage++; + break; + case 122: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL,"In addition to Standard Ironman restrictions,", "Hardcore Ironmen only have one life. In the event of","a dangerous death, a player will be downgraded to a", "Standard Ironman, and their stats frozen on the hiscores."); + stage++; + break; + case 123: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL,"For the ultimate challenge, players who choose the", "Ultimate Ironman mode cannot use banks, nor", "retain any items on death in dangerous areas."); + stage++; + break; + case 124: + if (player.getIronmanManager().isIronman()) { + interpreter.sendOptions("Select an Option", "I no longer want to be an Iron Man", "I'd like to change my Iron Man mode", "What is an Iron Man?", "Go Back."); + stage = 100; + } else { + interpreter.sendOptions("Select an Option", "I would like to be an Iron Man.", "What is an Iron Man?", "Go Back..."); + stage = 110; + } + break; + + case 131: + end(); + break; + //Change Iron man mode dialogue/code + case 150: + switch(buttonId){ + case 1: + case 2: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL,"I have changed your Iron Man mode to: ","" + (buttonId == 1 ? "Standard" : "Hardcore" + " Ironman mode.")); + player.getSettings().toggleAcceptAid(); + player.getIronmanManager().setMode(IronmanMode.values()[buttonId]); + if(buttonId == 2) { + player.setAttribute("/save:permadeath",true); + } + player.sendMessage("Your Iron Man status has been changed."); + stage = 50; + break; + case 3: //ultimate ironman + if (!player.getBank().isEmpty()) + { + interpreter.sendDialogues(npc, FacialExpression.GUILTY, "Sorry, but your bank is has items in it.", "Please empty your bank and speak to me again."); + stage = 50; + break; + } else { + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL,"I have changed your Iron Man mode to:","Ultimate Ironman mode."); + player.getIronmanManager().setMode(IronmanMode.ULTIMATE); + player.sendMessage("Your Iron Man status has been changed."); + stage = 50; + break; + } + case 4: + if (player.getIronmanManager().isIronman()) { + interpreter.sendOptions("Select an Option", "I no longer want to be an Iron Man", "I'd like to change my Iron Man mode", "What is an Iron Man?", "Go Back..."); + stage = 100; + } else { + interpreter.sendOptions("Select an Option", "I would like to be an Iron Man.", "What is an Iron Man?", "Go Back..."); + stage = 110; + } + break; + } + break; + + + //About XP Multiplier + case 200: + interpreter.sendOptions("Select an Option", "Set my experience rate to 10x", "Nevermind."); + stage++; + break; + case 201: + switch (buttonId) { + case 1: + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "Tada! Your experience rate is now 10x.", "Happy Scaping!"); + player.getSkills().experienceMultiplier = 10.0; + stage = 50; + break; + case 2: + end(); + break; + } + break; + } + + return true; + } + + /** + * Obtains the player's join date and time played. + */ + private void getPlayerTime() { + + //TODO: + // Find the Date Joined and Time Played variables for the player WITHOUT directly connecting to the SQL database here + // Split the Time Played variable into Days, Hours and Minutes + // Insert each calculation into the timePlayed array ( 0 for Days, 1 for Hours and 2 for Minutes) + // Calculate the Days Since registering by subtracting the Date Joined from the Current Server Date (ServerDate - Join_Date) + // Insert the date difference into joinDateDays variable + // return;??? + } + + @Override + public int[] getIds() { + return new int[] { 0 }; + } +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/dialogue/HarlanDialogue.java b/Server/src/main/content/region/misthalin/lumbridge/dialogue/HarlanDialogue.java new file mode 100644 index 0000000..d1dd299 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/dialogue/HarlanDialogue.java @@ -0,0 +1,240 @@ +package content.region.misthalin.lumbridge.dialogue; + +import core.game.container.Container; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.global.Skillcape; +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +/** + * Represents the dialogue plugin used for the harlan npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class HarlanDialogue extends DialoguePlugin { + + /** + * Represents the training sword. + */ + private static final Item SWORD = new Item(9703); + + /** + * Represents the training shield. + */ + private static final Item SHIELD = new Item(9704); + + /** + * Constructs a new {@code HarlanDialogue} {@code Object}. + */ + public HarlanDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code HarlanDialogue} {@code Object}. + * @param player the player. + */ + public HarlanDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new HarlanDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendOptions("Select an Option", "Can you tell me about different weapon types I can use?", "Please tell me about skillcapes.", "Bye."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Can you tell me about different weapon types I can", "use?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Please tell me about skillcapes."); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Bye."); + stage = 30; + break; + + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Well let me see now...There are stabbing type weapons", "such as daggers, then you have swords which are", "slashing, maces that have great crushing abilities, battle", "axes which are powerful and spears which can be good"); + stage = 11; + break; + case 11: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "for Defence and many forms of Attack."); + stage = 12; + break; + case 12: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "It depends a lot on how you want to fight. Experiment", "and find out what is best for you. Never be scared to", "try out a new weapon; you never know, you might like", "it! Why, I tried all of them for a while and settled on"); + stage = 13; + break; + case 13: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "this rather good sword!"); + stage = 14; + break; + case 14: + interpreter.sendOptions("Select an Option", "I'd like a training sword and shield.", "Bye"); + stage = 15; + break; + case 15: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'd like a training sword and shield."); + stage = 16; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Bye."); + stage = 30; + break; + } + break; + case 16: + if (hasBoth()) { + interpreter.sendDialogues(npc, null, "You already have them! If they're not in your", "inventory, perhaps you should check your bank."); + stage = 99; + return true; + } + if (hasItem(SHIELD)) { + interpreter.sendDialogues(npc, null, "You already have a shield but I can give you a sword."); + stage = 16; + return true; + } + if (hasItem(SWORD)) { + interpreter.sendDialogues(npc, null, "You already have a sword but I can give you a shield."); + stage = 17; + return true; + } + if (player.getInventory().add(SWORD)) { + interpreter.sendItemMessage(SWORD, "Harlan gives you a training sword."); + } else { + end(); + } + stage = 17; + break; + case 17: + if (player.getInventory().add(SHIELD)) { + interpreter.sendItemMessage(SHIELD, "Harlan gives you a training shield."); + } else { + end(); + } + stage = 18; + break; + case 18: + end(); + break; + case 20: + interpreter.sendDialogues(npc, null, "Of course. Skillcapes are a symbol of achievement. Only", "people who have mastered a skill and reached level 99", "can get their hands on them and gain the benefits they", "carry. Is there something else I can help you with,"); + stage = 21; + break; + case 21: + interpreter.sendDialogues(npc, null, "perhaps?"); + stage = 22; + break; + case 22: + if (player.getSkills().getStaticLevel(Skills.DEFENCE) >= 99) { + interpreter.sendOptions("Select an Option", "Can you tell me about different weapon types I can use?", "Can I purchase a defence cape?", "Bye."); + stage = 23; + return true; + } + interpreter.sendOptions("Select an Option", "Can you tell me about different weapon types I can use?", "Please tell me about skillcapes.", "Bye."); + stage = 0; + break; + case 23: + interpreter.sendDialogues(npc, null, "You will have to pay a fee of 99,000 gp."); + stage = 24; + break; + case 24: + interpreter.sendOptions("Select an Option", "Okay.", "No, thanks."); + stage = 25; + break; + case 25: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, null, "Okay."); + stage = 27; + break; + case 2: + interpreter.sendDialogues(player, null, "No, thanks."); + stage = 26; + break; + } + break; + case 27: + if (Skillcape.purchase(player, Skills.DEFENCE)) { + npc("There you go! Enjoy."); + } + stage = 26; + break; + case 26: + end(); + break; + case 30: + end(); + break; + case 99: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 705 }; + } + + /** + * Method usd to check if the player has both. + * @return True if so. + */ + public boolean hasBoth() { + final Container[] containers = new Container[] { player.getInventory(), player.getBank(), player.getEquipment() }; + int count = 0; + for (Container c : containers) { + if (c.containsItem(SWORD)) { + count++; + } + if (c.containsItem(SHIELD)) { + count++; + } + } + return count >= 2; + } + + /** + * Method used to get the item if its in. + * @param item the item. + * @return True + */ + public boolean hasItem(final Item item) { + final Container[] containers = new Container[] { player.getInventory(), player.getBank(), player.getEquipment() }; + for (Container c : containers) { + if (c.containsItem(item)) { + return true; + } + } + return false; + } +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/dialogue/JimmyTheChiselDialogue.kt b/Server/src/main/content/region/misthalin/lumbridge/dialogue/JimmyTheChiselDialogue.kt new file mode 100644 index 0000000..be00885 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/dialogue/JimmyTheChiselDialogue.kt @@ -0,0 +1,38 @@ +package content.region.misthalin.lumbridge.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + * todo char quest description osrs and rs3 doesn't match, but there isn't any for rs3 yet + */ + +@Initializable +class JimmyTheChiselDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npc(FacialExpression.FRIENDLY,"Hello mate!").also { stage = 99 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return JimmyTheChiselDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.JIMMY_THE_CHISEL_1718) + } +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/dialogue/LumbridgeGuideDialogue.kt b/Server/src/main/content/region/misthalin/lumbridge/dialogue/LumbridgeGuideDialogue.kt new file mode 100644 index 0000000..d01bdf6 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/dialogue/LumbridgeGuideDialogue.kt @@ -0,0 +1,128 @@ +package content.region.misthalin.lumbridge.dialogue + +import core.api.isQuestComplete +import core.api.sendGraphics +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.IronmanMode +import core.game.node.entity.player.link.diary.DiaryType +import core.game.world.map.zone.impl.ModeratorZone +import core.plugin.Initializable +import org.rs09.consts.NPCs +import core.game.dialogue.IfTopic +import core.game.dialogue.Topic +import core.tools.END_DIALOGUE +import content.data.Quests + +@Initializable +class LumbridgeGuideDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player?): DialoguePlugin { + return LumbridgeGuideDialogue(player) + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + val staff = player.isStaff + val ironman = player.ironmanManager.isIronman + val sheepShearerComplete = isQuestComplete(player, Quests.SHEEP_SHEARER) + val cooksAssistantComplete = isQuestComplete(player, Quests.COOKS_ASSISTANT) + + when (stage) { + 0 -> npcl(FacialExpression.FRIENDLY, "Greetings, adventurer. I am Phileas, the Lumbridge Guide. I am here to give information and directions to new players. Do you require any help?").also { stage++ } + 1 -> showTopics( + Topic("Where can I find a quest to go on?", 10), + Topic("What monsters should I fight?", 20), + Topic("Where can I make money?", 30), + Topic("I'd like to know more about security.", 40), + IfTopic("Where can I find a bank?", 50, !staff && !ironman), + IfTopic("More Options...", 100, staff || ironman, skipPlayer = true), + ) + + //More Options... + 100 -> showTopics( + Topic("Where can I find a bank?", 50), + IfTopic("I would like to access the P-Mod room.", 200, staff), + IfTopic("I would like to de-iron.", 300, ironman), + Topic("Go back...", 1, skipPlayer = true) + ) + + //Where can I find a quest? + 10 -> { + if (!cooksAssistantComplete) + npcl(FacialExpression.HALF_THINKING, "You can try talking to the Cook in the Lumbridge Castle. I hear he is always looking for some help.") + else if (!sheepShearerComplete) + npcl(FacialExpression.HALF_THINKING, "You can try talking to Fred the Farmer north-west of here. I hear he is always looking for some help.") + else + npcl(FacialExpression.FRIENDLY, "You are such an accomplished adventurer already; you should be telling me some good quests to go on.") + stage = END_DIALOGUE + } + + //What monsters should I fight? + 20 -> if (player.properties.currentCombatLevel >= 30) { + npcl(FacialExpression.FRIENDLY, "You're strong enough to work out what monsters to fight for yourself now, but the tutors might help you with any questions you have about the skills; they're just south of the general store.") + stage = END_DIALOGUE + } else { + npcl(FacialExpression.FRIENDLY, "There are things to kill all over the place! At your level, you might like to try wandering westwards to the Wizards' Tower or north-west to the Barbarian Village.") + stage++ + } + 21 -> npcl(FacialExpression.FRIENDLY, "Non-player characters usually appear as yellow dots on your mini-map, although there are some that you won't be able to fight, such as myself. Watch out for monsters which are tougher").also { stage++ } + 22 -> npcl(FacialExpression.FRIENDLY, "than you. A monster's combat level is shown next to their 'Attack' option. If that level is coloured green it means the monster is weaker than you. If it is red, it means the monster is tougher than you.").also { stage++ } + 23 -> npcl(FacialExpression.FRIENDLY, "Remember, you will do better if you have better armour and weapons and it's always worth carrying a bit of food to heal yourself.").also { stage = 1 } + + //Where can I make money? + 30 -> npcl(FacialExpression.FRIENDLY, "There are many ways to make money in the game. I would suggest either killing monsters or doing a trade skill such as Smithing or Fishing.").also { stage++ } + 31 -> npcl(FacialExpression.FRIENDLY, "Please don't try to get money by begging off other players. It will make you unpopular. Nobody likes a beggar. It is very irritating to have other players asking for your hard-earned cash.").also { stage = 1 } + + //I'd like to know more about security + 40 -> npcl(FacialExpression.FRIENDLY, "I can tell you about password security, avoiding item scamming and in-game moderation. I can also tell you about a place called the Stronghold of Security, where you can learn more about account security and have a").also { stage++ } + 41 -> { + player.achievementDiaryManager.finishTask(player, DiaryType.LUMBRIDGE, 0, 17) + npcl(FacialExpression.FRIENDLY, "bit of an adventure at the same time. In fact, why don't you just head there instead? It's a lot more fun, I promise. You can find it down the hole in the middle of Barbarian Village to the north-west.") + stage = 1 + } + + //Where can I find a bank? + 50 -> npcl(FacialExpression.FRIENDLY, "You'll find a bank upstairs in Lumbridge Castle - go right to the top!").also { stage = 1 } + + //visit pmod room + 200 -> npcl(FacialExpression.FRIENDLY, "Yes, of course.").also { stage++ } + 201 -> { + end() + if (player.isStaff) + ModeratorZone.teleport(player) + } + + //deiron + 300 -> npcl(FacialExpression.FRIENDLY, "Of course, but first let me give you a word of warning.").also { stage++ } + 301 -> npcl(FacialExpression.FRIENDLY, "Should you choose to step away from the path of the ironman now, you will not have the option to return.").also { stage++ } + 302 -> npcl(FacialExpression.FRIENDLY, "Now I ask you to make sure, are you sure you want to permanently remove ironman mode?").also { stage++ } + 303 -> showTopics( + Topic(FacialExpression.FRIENDLY, "Yes, I'm sure.", 310), + Topic(FacialExpression.FRIENDLY, "No, I've changed my mind.", END_DIALOGUE) + ) + + //yes - deiron + 310 -> npcl(FacialExpression.FRIENDLY, "Very well, let me just check one thing...").also { stage++ } + 311 -> if (player.ironmanManager.mode == IronmanMode.HARDCORE) { + npcl(FacialExpression.WORRIED, "Oh, dear, it's just as I feared. You're a hardcore ironman! My apologies, but there's nothing I can do to help.").also { stage = END_DIALOGUE } + } else { + npcl(FacialExpression.FRIENDLY, "Oh, wonderful. It appears everything is in order. Sit still for a moment...").also { stage++ } + } + 312 -> { + sendGraphics(342, player.location) + sendDialogue("------------------", "The wise old wizard casts a strange spell.", "------------------") + stage++ + } + 313 -> { + player.ironmanManager.mode = IronmanMode.NONE + npcl(FacialExpression.HALF_ASKING, "There, I believe it is done. You should no longer be restricted from the wider world.") + stage = END_DIALOGUE + } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.LUMBRIDGE_GUIDE_2244) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/dialogue/LumbridgeJailGuard.java b/Server/src/main/content/region/misthalin/lumbridge/dialogue/LumbridgeJailGuard.java new file mode 100644 index 0000000..4e6ae25 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/dialogue/LumbridgeJailGuard.java @@ -0,0 +1,69 @@ +package content.region.misthalin.lumbridge.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the lumbridge jail guard. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class LumbridgeJailGuard extends DialoguePlugin { + + /** + * Constructs a new {@code LumbridgeJailGuard} {@code Object}. + */ + public LumbridgeJailGuard() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code LumbridgeJailGuard} {@code Object}. + * @param player the player. + */ + public LumbridgeJailGuard(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new LumbridgeJailGuard(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Why are you here ? You must leave at once."); + stage = 1; + break; + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Err.. Okay."); + stage = 2; + break; + case 2: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 917, 447, 448, 449 }; + } +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/dialogue/LumbridgeShopKeeperDialogue.java b/Server/src/main/content/region/misthalin/lumbridge/dialogue/LumbridgeShopKeeperDialogue.java new file mode 100644 index 0000000..6bdc628 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/dialogue/LumbridgeShopKeeperDialogue.java @@ -0,0 +1,78 @@ +package content.region.misthalin.lumbridge.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the lumbridge shop keeper dialogue. + */ +@Initializable +public final class LumbridgeShopKeeperDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code LumbridgeShopKeeperDialogue} {@code Object}. + */ + public LumbridgeShopKeeperDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code LumbridgeShopKeeperDialogue} {@code Object}. + * @param player the player. + */ + public LumbridgeShopKeeperDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new LumbridgeShopKeeperDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Can I help you at all?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "Yes, please. What are you selling?", "How should I use your shop?", "No, thanks."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + end(); + npc.openShop(player); + break; + case 2: + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "I'm glad you ask! You can buy as many of the items", "stocked as you wish. You can also sell most items to the", "shop."); + stage = 20; + break; + case 3: + end(); + break; + } + break; + case 20: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 520, 521 }; + } +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/dialogue/LumbridgeSwampArcher.java b/Server/src/main/content/region/misthalin/lumbridge/dialogue/LumbridgeSwampArcher.java new file mode 100644 index 0000000..cdc54f6 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/dialogue/LumbridgeSwampArcher.java @@ -0,0 +1,73 @@ +package content.region.misthalin.lumbridge.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the lumbridge swamp archer dialogue. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class LumbridgeSwampArcher extends DialoguePlugin { + + /** + * Constructs a new {@code LumbridgeSwampArcher} {@code Object}. + */ + public LumbridgeSwampArcher() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code LumbridgeSwampArcher} {@code Object}. + * @param player the player. + */ + public LumbridgeSwampArcher(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new LumbridgeSwampArcher(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Why are you guys hanging around here?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "(ahem)...'Guys'?"); + stage = 1; + break; + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Uh... yeah, sorry about that. Why are you all standing", "around out here?"); + stage = 2; + break; + case 2: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Well, that's really none of your business."); + stage = 3; + break; + case 3: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 649 }; + } +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/dialogue/LumbridgeSwampMonk.java b/Server/src/main/content/region/misthalin/lumbridge/dialogue/LumbridgeSwampMonk.java new file mode 100644 index 0000000..5ad40d9 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/dialogue/LumbridgeSwampMonk.java @@ -0,0 +1,66 @@ +package content.region.misthalin.lumbridge.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the lumbridge swamp monk. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class LumbridgeSwampMonk extends DialoguePlugin { + + /** + * Constructs a new {@code LumbridgeSwampMonk} {@code Object}. + */ + public LumbridgeSwampMonk() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code LumbridgeSwampMonk} {@code Object}. + * @param player the player. + */ + public LumbridgeSwampMonk(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new LumbridgeSwampMonk(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Why are all of you standing around here?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "None of your business. Get lost."); + stage = 1; + break; + case 1: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 651 }; + } + +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/dialogue/LumbridgeSwampWizard.java b/Server/src/main/content/region/misthalin/lumbridge/dialogue/LumbridgeSwampWizard.java new file mode 100644 index 0000000..aea5dc0 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/dialogue/LumbridgeSwampWizard.java @@ -0,0 +1,70 @@ +package content.region.misthalin.lumbridge.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the lumbridge swamp lizard dialogue. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class LumbridgeSwampWizard extends DialoguePlugin { + + /** + * Constructs a new {@code LumbridgeSwampWizard} {@code Object}. + */ + public LumbridgeSwampWizard() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code LumbridgeSwampWizard} {@code Object}. + * @param player the player. + */ + public LumbridgeSwampWizard(Player player) { + super(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Why are all of you standing around here?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hahaha you dare talk to a mighty wizard such as", "myself? I bet you can't even cast windstrike yet", "amateur!"); + stage = 1; + break; + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "...You're an idiot."); + stage = 2; + break; + case 2: + end(); + break; + } + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new LumbridgeSwampWizard(player); + } + + @Override + public int[] getIds() { + return new int[] { 652 }; + } + +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/dialogue/MagicTutorDialogue.java b/Server/src/main/content/region/misthalin/lumbridge/dialogue/MagicTutorDialogue.java new file mode 100644 index 0000000..db1e454 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/dialogue/MagicTutorDialogue.java @@ -0,0 +1,215 @@ +package content.region.misthalin.lumbridge.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItem; +import core.game.node.item.GroundItemManager; +import core.plugin.Initializable; +import core.game.node.item.Item; + +/** + * Represents the magic tutor dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class MagicTutorDialogue extends DialoguePlugin { + + /** + * Represents the mind runes item. + */ + private static final Item MIND_RUNE = new Item(558); + + /** + * Represents the air rune item. + */ + private static final Item AIR_RUNE = new Item(556); + + /** + * Constructs a new {@code MagicTutorDialogue} {@code Object}. + */ + public MagicTutorDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code MagicTutorDialogue} {@code Object}. + * @param player the player. + */ + public MagicTutorDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new MagicTutorDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + if (args.length == 2) { + if (player.getSavedData().getGlobalData().getTutorClaim() > System.currentTimeMillis()) { + interpreter.sendDialogues(npc, null, "I work with the Ranged Combat tutor to give out", "consumable items that you may need for combat such", "as arrows and runes. However we have had some", "cheeky people try to take both!"); + stage = 200; + return true; + } + stage = 99; + for (int x = 0; x < 16; x++) { + for (int y = 0; y < 16; y++) { + final GroundItem ground = GroundItemManager.get(MIND_RUNE.getId(), player.getLocation().transform(x, y, 0), player); + final GroundItem second = GroundItemManager.get(AIR_RUNE.getId(), player.getLocation().transform(x, y, 0), player); + if (ground != null && ground.droppedBy(player) || second != null && second.getDropper() != null && second.getDropper() == player) { + interpreter.sendDialogues(npc, null, "Someone seems to have dropped some " + (ground == null ? "air" : "mind") + " runes on", "the floor, perhaps you should pick them up to use them."); + return true; + } + } + } + if (player.getInventory().freeSlots() < 2) { + end(); + player.getPacketDispatch().sendMessage("Not enough inventory space."); + return true; + } + if (player.getInventory().containsItem(MIND_RUNE) || player.getBank().containsItem(MIND_RUNE)) { + interpreter.sendDialogues(npc, null, "You have some mind runes already!"); + stage = 69; + return true; + } + if (player.getInventory().containsItem(AIR_RUNE) || player.getBank().containsItem(AIR_RUNE)) { + interpreter.sendDialogues(npc, null, "You have some air runes already!"); + stage = 70; + return true; + } + add(true); + add(false); + stage = 99; + return true; + } + interpreter.sendOptions("Select an Option", "Can you teach me the basics please?", "Teach me about making runes.", "Goodbye."); + stage = 1; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 69: + if (player.getInventory().containsItem(AIR_RUNE) || player.getBank().containsItem(AIR_RUNE)) { + interpreter.sendDialogues(npc, null, "You have some air runes already!"); + stage = 99; + return true; + } + add(false); + stage = 99; + end(); + break; + case 70: + if (player.getInventory().containsItem(MIND_RUNE) || player.getBank().containsItem(MIND_RUNE)) { + interpreter.sendDialogues(npc, null, "You have some mind runes already!"); + stage = 99; + return true; + } + add(true); + stage = 99; + end(); + break; + case 99: + end(); + break; + case 300: + add(false); + break; + case 301: + end(); + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Can you teach me the basics please?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Teach me about making runes."); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Goodbye."); + stage = 30; + break; + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "You can cast different spells according to what runes", "you have in your inventory. To start off with you'll", "need mind runes and air runes. These will allow you to", "cast Wind Strike like you did in the tutorial."); + stage = 11; + break; + case 11: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Use the spell book icon in the top right of the control", "panel to see what spells you can cast. If you have the", "correct runes, the spell will light up."); + stage = 12; + break; + case 12: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Nemarti, the Ranged Combat tutor and I both give out", "items every 30 minutes, however you must choose", "whether you want runes or ranged equipment. To", "claim runes, right-click on me and choose Claim, to claim"); + stage = 13; + break; + case 13: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "ranged equipment right-click on the Ranged Combat", "tutor and select Claim."); + stage = 14; + break; + case 14: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "When you have the spell available, click on it once, then", "click on your target. A good target would be a monster", "that is below your combat level."); + stage = 15; + break; + case 15: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Try rats in the castle or if you're feeling brave, the", "goblins to the west of here have been causing a", "nuisance of themselves."); + stage = 16; + break; + case 16: + interpreter.sendOptions("Select an Option", "Can you teach me the basics please?", "Teach me about making runes.", "Goodbye."); + stage = 1; + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I'd talk to the Duke of Lumbridge if I were you. I", "hear he has an interesting artifact that might just have", "something to do with Runecrafting. I expect there wil", "be a quest involved too!"); + stage = 21; + break; + case 21: + interpreter.sendOptions("Select an Option", "Can you teach me the basics please?", "Teach me about making runes.", "Goodbye."); + stage = 1; + break; + case 30: + end(); + break; + case 200: + interpreter.sendDialogues(npc, null, "So, every half an hour, you may come back and claim", "either arrows OR runes, but not both. Come back in a", "while for runes, or simply make your own."); + stage = 201; + break; + case 201: + end(); + break; + } + return true; + } + + public void add(boolean mind) { + if (mind) { + if (player.getInventory().add(new Item(558, 30))) { + player.getPacketDispatch().sendMessage("Mikasi gives you 30 mind runes."); + stage = 300; + player.getSavedData().getGlobalData().setTutorClaim(System.currentTimeMillis() + 1800000); + } + } else { + if (player.getInventory().add(new Item(556, 30))) { + player.getPacketDispatch().sendMessage("Mikasi gives you 30 air runes."); + stage = 301; + player.getSavedData().getGlobalData().setTutorClaim(System.currentTimeMillis() + 1800000); + } + } + } + + @Override + public int[] getIds() { + return new int[] { 4707 }; + } +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/dialogue/MiningtutorDialogue.java b/Server/src/main/content/region/misthalin/lumbridge/dialogue/MiningtutorDialogue.java new file mode 100644 index 0000000..73f4834 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/dialogue/MiningtutorDialogue.java @@ -0,0 +1,105 @@ +package content.region.misthalin.lumbridge.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the mining tutor dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class MiningtutorDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code MiningtutorDialogue} {@code Object}. + */ + public MiningtutorDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code MiningtutorDialogue} {@code Object}. + * @param player the player. + */ + public MiningtutorDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new MiningtutorDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendOptions("Select an Option", "Can you teach me the basics of mining please?", "Are there any mining related quests?", "Goodbye."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Can you teach me the basics of mining please?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Are there are mining related quests?"); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Goodbye."); + stage = 30; + break; + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "If you want to know what ore's in a rock before you", "mine it, right-click the rock and select prospect from the", "menu, it will take a little time, but you'll find out what's", "in the rock before you mine."); + stage = 11; + break; + case 11: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "You can also tell the ore you'll get from the colour of", "the rock."); + stage = 12; + break; + case 12: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "To mine, simply click on the rock to mine it, but make", "sue you have your pick with you."); + stage = 13; + break; + case 13: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "When you have a full inventory, take it to the bank,", "you can find it on the roof of the castle in Lumbridge."); + stage = 14; + break; + case 14: + interpreter.sendOptions("Select an Option", "Can you teach me the basics of mining please?", "Are there any mining related quests?", "Goodbye."); + stage = 0; + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Oh yes, if you haven't already, speak to Doric who can", "be found around the anvils north of Falador. I'm sure", "he can help you out."); + stage = 21; + break; + case 21: + interpreter.sendOptions("Select an Option", "Can you teach me the basics of mining please?", "Are there any mining related quests?", "Goodbye."); + stage = 0; + break; + case 30: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 4902 }; + } +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/dialogue/PrayerTutorDialogue.java b/Server/src/main/content/region/misthalin/lumbridge/dialogue/PrayerTutorDialogue.java new file mode 100644 index 0000000..687a6b8 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/dialogue/PrayerTutorDialogue.java @@ -0,0 +1,119 @@ +package content.region.misthalin.lumbridge.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Handles the PrayerTutorDialogue dialogue. + * @author 'Vexia + */ +@Initializable +public class PrayerTutorDialogue extends DialoguePlugin { + + public PrayerTutorDialogue() { + + } + + public PrayerTutorDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new PrayerTutorDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendOptions("Select an Option", "I already know about the basic prayers, got any tips?", "Tell me about different bones.", "Goodbye."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.ASKING, "I already know about the basic prayers, got any tips?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_ASKING, "Tell me about different bones."); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.FRIENDLY, "Goodbye."); + stage = 30; + break; + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "For you " + player.getUsername() + "? Always. There are many", "advantages to using the protection prayers when", "fighting the more dangerous foes. You can protect", "yourself from magic, melee or ranged attacks with these"); + stage = 11; + break; + case 11: + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "useful prayers."); + stage = 12; + break; + case 12: + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "A good prayer to have when venturing into the", "wilderness is protect item. This will protect one of your", "items if you should die there."); + stage = 13; + break; + case 13: + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "Remember though that venturing into the wilderness is", "a risky business, store your items in a bank before you", "go there so that you don't lose them."); + stage = 14; + break; + case 14: + interpreter.sendOptions("Select an Option", "I already know about the basic prayers, got any tips?", "Tell me about different bones.", "Goodbye."); + stage = 0; + break; + case 20: + interpreter.sendOptions("Select an Option", "Basic Bones", "Big Bones", "Babydragon Bones", "Goodbye."); + stage = 21; + break; + case 21: + switch (buttonId) { + case 1: + interpreter.sendItemMessage(526, "Basic bones are left by many creatures such as goblins, monkeys and that sort of thing. They won't get you much when you burry them, but if you do it every time you come across them, it all adds up!"); + stage = 20; + break; + case 2: + interpreter.sendItemMessage(532, "Big bones you can get by killing things like ogres and giants, them being big things and all. They're quite a good boost for your prayer if you are up to fighting the big boys."); + stage = 220; + break; + case 3: + interpreter.sendItemMessage(536, "If you're feeling adventurous and up to tackling baby dragons, you can get these Baby Dragon bones which are even better than big bones."); + stage = 20; + break; + case 4: + interpreter.sendDialogues(player, FacialExpression.FRIENDLY, "Goodbye."); + stage = 40; + break; + } + break; + case 220: + interpreter.sendItemMessage(532, "You can probably find them in caves and such dark dank places."); + stage = 20; + break; + case 40: + end(); + break; + case 30: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 4903 }; + } +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/dialogue/RangedTutorDialogue.java b/Server/src/main/content/region/misthalin/lumbridge/dialogue/RangedTutorDialogue.java new file mode 100644 index 0000000..8e322cc --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/dialogue/RangedTutorDialogue.java @@ -0,0 +1,209 @@ +package content.region.misthalin.lumbridge.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.game.node.item.Item; + +/** + * Handles the RangedTutorDialogue dialogue. + * @author 'Vexia + */ +@Initializable +public class RangedTutorDialogue extends DialoguePlugin { + + /** + * Represnets the bow item. + */ + private final Item BOW = new Item(9705); + + /** + * Represents the arrow item. + */ + private final Item ARROW = new Item(9706); + + public RangedTutorDialogue() { + + } + + public RangedTutorDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new RangedTutorDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + if (args.length == 2) { + if (player.getSavedData().getGlobalData().getTutorClaim() > System.currentTimeMillis()) { + interpreter.sendDialogues(npc, null, "I work with the Ranged Combat tutor to give out", "consumable items that you may need for combat such", "as arrows and runes. However we have had some", "cheeky people try to take both!"); + stage = 200; + return true; + } + stage = 99; + if (player.getInventory().containsItem(BOW)) { + interpreter.sendDialogues(npc, null, "You have a training bow in your inventory."); + return true; + } + if (player.getBank().containsItem(BOW)) { + interpreter.sendDialogues(npc, null, "You have a training bow in your bank."); + return true; + } + if (player.getEquipment().containsItem(BOW)) { + interpreter.sendDialogues(npc, null, "You're wielding your training bow."); + return true; + } + if (player.getInventory().containsItem(ARROW)) { + interpreter.sendDialogues(npc, null, "You have a training arrows in your inventory."); + return true; + } + if (player.getBank().containsItem(ARROW)) { + interpreter.sendDialogues(npc, null, "You have a training arrows in your bank."); + return true; + } + if (player.getEquipment().containsItem(ARROW)) { + interpreter.sendDialogues(npc, null, "You're wielding training arrows."); + return true; + } + if (player.getInventory().freeSlots() < 2) { + end(); + player.getPacketDispatch().sendMessage("Not enough inventory space."); + return true; + } + if (player.getInventory().add(BOW)) { + interpreter.sendItemMessage(BOW, "Nemarti gives you a Training Shortbow. It can only be used with Training Arrows."); + stage = 230; + player.getSavedData().getGlobalData().setTutorClaim(System.currentTimeMillis() + 1800000); + return true; + } + return true; + } + interpreter.sendOptions("Select an Option", "Can you teach me the basics please?", "What about fletching?", "Goodbye."); + stage = 1; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 230: + final Item arrows = new Item(ARROW.getId(), 25); + if (player.getInventory().add(arrows)) { + interpreter.sendItemMessage(arrows, "Nemarti gives you 25 training arrows. They can only be used with the Training Shortbow."); + stage = 231; + player.getSavedData().getGlobalData().setTutorClaim(System.currentTimeMillis() + 1800000); + return true; + } + break; + case 231: + end(); + break; + case 99: + end(); + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Can you teach me the basics please?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What about fletching?"); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Goodbye."); + stage = 30; + break; + + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "To start with you'll need a bow and arrows."); + stage = 11; + break; + case 11: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Mikasi, the Magic Combat tutor and I both give you", "items every 30 minutes, however you must choose", "wether you want runes or ranged equipment. To", "claim ranged equipment, right-click on me and choose"); + stage = 12; + break; + case 12: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Claim, to claim runes right-click on the Magic Combat", "tutor and select Claim."); + stage = 13; + break; + case 13: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "When you have both bow and arrows, wield them by", "right-clicking on them in your inventory and selecting", "wield."); + stage = 14; + break; + case 14: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "To set the way you shoot, click on the crossed swords", "above your inventory. This will open the combat", "interface where you can pick how you shoot your bow.", "Accurate means that you will shoot less often but be"); + stage = 15; + break; + case 15: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "more likely to hit, rapid means you shoot more often", "but might not hit so often and long range means just", "that, it increases your range. I prefer rapid personally,", "experiment and try it out!"); + stage = 16; + break; + case 16: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "The Training Shortbow and Training Arrows can only", "be used together. Remember to pick up your arrows,", "re-use them and come back when you need more."); + stage = 17; + break; + case 17: + end(); + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ahh the art of making your own bow and arrows. It's", "quite simple really. You'll need an axe to cut some logs", "from trees and a knife. Knives can be found in and", "arround the Lumbridge castle and in the Varrock"); + stage = 21; + break; + case 21: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "General store upstairs."); + stage = 22; + break; + case 22: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Use your knife on the logs, this will bring up a list of", "items you can make. Right-click on the item of your", "choice and choose the amount to fletch."); + stage = 23; + break; + case 23: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "For arrows you will need to smith some arrow heads", "and kill some chickens for feathers. Add the feathers", "and heads to the shafts to make arrows you can use."); + stage = 24; + break; + case 24: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "You'll need to find a flax field, there's one south of", "Seer's Village. Gather flax, then spin it on a spinning", "wheel, there's one in Seers' Village too. This makes bow", "strings which you can then use on the unstrung bows"); + stage = 25; + break; + case 25: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "to make a working bow!"); + stage = 26; + break; + case 26: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Brilliant. If I forget anything I'll come talk to you", "again."); + stage = 27; + break; + case 27: + interpreter.sendOptions("Select an Option", "Can you teach me the basics please?", "What about fletching?", "Goodbye."); + stage = 1; + break; + case 30: + end(); + break; + case 200: + interpreter.sendDialogues(npc, null, "So, every half an hour, you may come back and claim", "either arrows OR runes, but not both. Come back in a", "while for runes, or simply make your own."); + stage = 201; + break; + case 201: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 1861 }; + } +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/dialogue/SethGroatsDialogue.java b/Server/src/main/content/region/misthalin/lumbridge/dialogue/SethGroatsDialogue.java new file mode 100644 index 0000000..3bbb3be --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/dialogue/SethGroatsDialogue.java @@ -0,0 +1,48 @@ +package content.region.misthalin.lumbridge.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Handles the SethGroatsDialogue dialogue. + * @author Vexia + */ +@Initializable +public class SethGroatsDialogue extends DialoguePlugin { + + public SethGroatsDialogue() { + + } + + public SethGroatsDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new SethGroatsDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "M'arnin'... going to milk me cowsies!"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + end(); + return true; + } + + @Override + public int[] getIds() { + return new int[] { 452 }; + } +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/dialogue/SigmundDialogue.java b/Server/src/main/content/region/misthalin/lumbridge/dialogue/SigmundDialogue.java new file mode 100644 index 0000000..e4e5216 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/dialogue/SigmundDialogue.java @@ -0,0 +1,127 @@ +package content.region.misthalin.lumbridge.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +import static core.tools.DialogueConstKt.END_DIALOGUE; +import content.data.Quests; + + +/** + * Handles the SigmundDialogue dialogue. + * @author 'Vexia + */ +@Initializable +public class SigmundDialogue extends DialoguePlugin { + + int[] TLTNPCS = {278,0,519,2244,3777}; + + public SigmundDialogue() { + + } + + public SigmundDialogue(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[] { 2082, 2083, 2090, 3713, 3716, 3717, 3718, 3719, 3720, 4328, 4331, 4332, 4333, 4334, 4335 }; + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Can I help you?"); + if(player.getQuestRepository().getQuest(Quests.THE_LOST_TRIBE).getStage(player) > 0 && player.getQuestRepository().getQuest(Quests.THE_LOST_TRIBE).getStage(player) < 100){ + npc("Have you found out what it was?"); + stage = 34; + return true; + } + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "Do you have any quests for me?", "Who are you?"); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Do you have any quests for me?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Who are you?"); + stage = 20; + break; + + } + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I'm the Duke's advisor."); + stage = 21; + break; + case 21: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Can you give me any advice then?"); + stage = 22; + break; + case 22: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I only advise the Duke. But if you want to make", "yourself useful, there are evil goblins to slay on the", "other side of the river."); + stage = 23; + break; + case 23: + end(); + break; + case 10: + if(player.getQuestRepository().hasStarted(Quests.THE_LOST_TRIBE) && !player.getQuestRepository().isComplete(Quests.THE_LOST_TRIBE)){ + npc("No, not right now."); + stage = 12; + break; + } + if(player.getQuestRepository().isComplete(Quests.GOBLIN_DIPLOMACY) && player.getQuestRepository().isComplete(Quests.RUNE_MYSTERIES) && !player.getQuestRepository().hasStarted(Quests.THE_LOST_TRIBE)){ + npc("There was recently some damage to the castle cellar.","Part of the wall has collapsed."); + stage = 30; + break; + } + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I hear the Duke has a task for an adventurer.", "Otherwise, if you want to make yourself useful, there", "are always evil monsters to slay."); + stage = 11; + break; + case 11: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Okay, I might just do that."); + stage = 12; + break; + case 12: + end(); + break; + case 30: + npc("The Duke insists that it was an earthquake, but I think","some kind of monsters are to blame."); + stage++; + break; + case 31: + npc("You should ask other people around the town if they","saw anything."); + stage = END_DIALOGUE; + player.getQuestRepository().getQuest(Quests.THE_LOST_TRIBE).start(player); + player.setAttribute("/save:tlt-witness", TLTNPCS[0]); + break; + case 34: + player("No..."); + stage = END_DIALOGUE; + break; + } + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new SigmundDialogue(player); + } +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/dialogue/SirVantDialogue.kt b/Server/src/main/content/region/misthalin/lumbridge/dialogue/SirVantDialogue.kt new file mode 100644 index 0000000..8b61bea --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/dialogue/SirVantDialogue.kt @@ -0,0 +1,53 @@ +package content.region.misthalin.lumbridge.dialogue + +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +/** + * Sir Vant Dialogue + * + * @comments + * I'll be honest, this is a waste of time. + * Sir Vant is part of the new tutorial between 14 July 2008 and 17 Sept 2009, a.k.a. Tutorial 2(Learing the Ropes). + * Learning the Ropes was no longer in use by the time 530 came around. They were already working on Tutorial 3(Unstable Foundations) with a different dialogue that was fully voiced. Learning the Ropes was removed eventually. + * I'm doing this to preserve the dialogue during this period, as there are sceneries left around for this. + * So much effort was put into Tutorial 1(Tutorial Island), that this shouldn't replace it. In fact, modern RS3 has tried to multiple times between 2016 and 2022, but they always end up going back to Tutorial Island. For example, Tutorial Island was removed on 28 November 2012, returned as a special underwater version on 14 December 2015, and was fully reinstated on 14 May 2018. + */ +@Initializable +class SirVantDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, SirVantDialogueFile(), npc) + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return SirVantDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.SIR_VANT_7942) + } +} + +class SirVantDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onPredicate { true } + .npcl(FacialExpression.HAPPY,"Hello there. I'm Sir Vant.") + .playerl(FacialExpression.THINKING, "Why are you down in this cave?") + .npcl("I'm guarding the entrance to the dragon's lair.") + .playerl(FacialExpression.WORRIED, "Dragon?") + .npcl("Yes, but not just any dragon - this one has three heads.") + .playerl("So why don't you kill it?") + .npc(FacialExpression.SAD,"I'm too exhausted, but I can hold it off. I've sent for", "more help from Falador, but it might be a while before", "the message gets there.") + .playerl("I could kill the dragon for you.") // Technically you have a list of options, but they are all a repeat of tutorial with an action cutscene. + .npc("Thank you very much for the offer; however, I would", "be remiss in my duties as a White Knight of Falador if", "I were to let you do that.") + //.npc("Thank you very much for the offer; however, I would", " be remiss in my duties as a White Knight of Falador if", "I were to let you do that. Here, for your kind thoughts", "you may have these old lamps.") + // He gives you 2 exp lamps of 250XP each, but I didn't want to implement it. + .end() + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/dialogue/WoodsmanTutorDialogue.java b/Server/src/main/content/region/misthalin/lumbridge/dialogue/WoodsmanTutorDialogue.java new file mode 100644 index 0000000..03ad3d4 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/dialogue/WoodsmanTutorDialogue.java @@ -0,0 +1,237 @@ +package content.region.misthalin.lumbridge.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +/** + * Represents the woodsman tutor dialogue. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class WoodsmanTutorDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code WoodsmanTutorDialogue} {@code Object}. + */ + public WoodsmanTutorDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code WoodsmanTutorDialogue} {@code Object}. + * @param player the player. + */ + public WoodsmanTutorDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new WoodsmanTutorDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + if (player.getSkills().getLevel(Skills.WOODCUTTING) >= 99) { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Wow! It's not often I meet somebody as accomplished", "as me in Woodcutting! Seeing as youre so skilled,", "maybe you are interested in buying a Skillcape of", "Woodcutting?"); + stage = 100; + } else { + interpreter.sendOptions("Select an Option", "Tell me about different trees and axes.", "What is that cape you're wearing?", "Goodbye."); + stage = 500; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Who are you?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What is that cape you're wearing?"); + stage = 20; + break; + + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "My name is Wilfred and I'm the best woodsman in", "Asgarnia! I've spent my life studying the best methods for", "woodcutting. That's why I have this cape, the Skillcape of", "Woodcutting."); + stage = 11; + break; + case 11: + end(); + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "This is a Skillcape of Woodcutting. Only a person who has", "achieved the highest possible level in a skill can wear one."); + stage = 21; + break; + case 21: + end(); + break; + case 100: + interpreter.sendOptions("Select an Option", "Yes, please.", "No, thank you."); + stage = 101; + break; + case 101: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Yes, please."); + stage = 1000; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No, thank you."); + stage = 2000; + break; + } + break; + case 2000: + interpreter.sendOptions("Select an Option", "Tell me about different trees and axes.", "What is that cape you're wearing?", "Goodbye."); + stage = 500; + break; + case 2002: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Bye!"); + stage = 2003; + break; + case 2003: + end(); + break; + case 1000: + if (player.getInventory().freeSlots() == 1) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Sorry, I don't have enough inventory space."); + stage = 99; + } + if (player.getInventory().contains(995, 99000)) { + player.getInventory().remove(new Item(995, 99000)); + player.getInventory().add(new Item(9807 + (player.getSkills().getMasteredSkills() > 1 ? 1 : 0))); + player.getInventory().add(new Item(9809, 1)); + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Excellent! Wear that cape with pride my friend."); + stage = 107; + } else { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Sorry, I don't seem to have enough coins."); + stage = 160; + } + break; + case 99: + end(); + break; + case 160: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Very well, farewell adventurer."); + stage = 2001; + break; + case 107: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Will do, Wilfred."); + stage = 108; + break; + case 108: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Very well, farewell adventurer."); + stage = 2001; + break; + case 2001: + end(); + break; + case 500: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, null, "Tell me about different trees and axes."); + stage = 510; + break; + case 2: + interpreter.sendDialogues(player, null, "What is that cape you're wearing?"); + stage = 520; + break; + case 3: + interpreter.sendDialogues(player, null, "Goodbye."); + stage = 530; + break; + } + break; + case 510: + interpreter.sendOptions("Trees", "Oak and Willow", "Maple and Yew", "Magic and other trees", "Axes", "Go back to teaching"); + stage = 511; + break; + case 511: + switch (buttonId) { + case 1: + interpreter.sendDoubleItemMessage(1511, 1521, "Almost every tree can be chopped down. Normal logs will be produced by chopping 'Trees' and Oak logs will come from chopping 'Oak Trees'. You can find Oak trees in amongst normal trees scatterd about the"); + stage = 5100; + break; + case 2: + interpreter.sendItemMessage(1517, "Maple logs can be gleaned from Maple trees. You'll usually find Maple trees standing alone amongst other trees."); + stage = 5200; + break; + case 3: + interpreter.sendItemMessage(1513, "Magic trees are... magic. A difficult wood to work with, but worth it for the rewards. Find them in the areas south of Seers village or on the East side of the Mage arena."); + stage = 5300; + break; + case 4: + interpreter.sendItemMessage(1351, "Bronze axes are easy to get, simply go visit Bob in his shop in Lumbridge, or talk to me if you have mislaid yours."); + stage = 5400; + break; + case 5: + interpreter.sendOptions("Select an Option", "Tell me about different trees and axes.", "What is that cape you're wearing?", "Goodbye."); + stage = 500; + + break; + } + break; + case 5400: + interpreter.sendDialogues(npc, null, "As you progress in your combat skill you will find you", "can wield your woodcutting axe as a weapon, it's not", "very effective, but it frees up a slot for another log."); + stage = 5401; + break; + case 5401: + interpreter.sendDoubleItemMessage(1349, 1353, "As your woodcutting skill increases you will find yourself able to use better axes to chop trees faster.... anything up to steel you can buy from Bob's axe shop."); + stage = 5402; + break; + case 5402: + interpreter.sendItemMessage(1359, "Rune axes can be player made with very high level smithing and mining. They can also be obtained through killing one of the fearsome tree spirits, though this is very rare."); + stage = 510; + break; + case 5300: + interpreter.sendDialogues(npc, null, "Hollow trees can be found in the Haunted Woods east", "of Canifis, but be careful of the leeches."); + stage = 510; + break; + case 5200: + interpreter.sendItemMessage(1515, "Yew trees are few and far between. We do our best to cultivate them. Look for the tree icon on your mini map to find rare trees. Try North of Port Sarim."); + stage = 510; + break; + case 5100: + interpreter.sendDoubleItemMessage(1511, 1521, "lands."); + stage = 5101; + break; + case 5101: + interpreter.sendItemMessage(1519, "Willow trees will yield willow logs. You'll find willows like to grow near water, you can find some south of Draynor."); + stage = 5102; + break; + case 5102: + interpreter.sendOptions("Trees", "Oak and Willow", "Maple and Yew", "Magic and other trees", "Axes", "Go back to teaching"); + stage = 511; + break; + case 520: + interpreter.sendDialogues(npc, null, "This is a Skillcape of Woodcutting. Only a person who", "has achieved the highest possible level in a skill can wear", "one."); + stage = 530; + break; + case 530: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 4906 }; + } +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/diary/LumbridgeAchivementDiary.kt b/Server/src/main/content/region/misthalin/lumbridge/diary/LumbridgeAchivementDiary.kt new file mode 100644 index 0000000..5a8ca76 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/diary/LumbridgeAchivementDiary.kt @@ -0,0 +1,438 @@ +package content.region.misthalin.lumbridge.diary + +import content.global.skill.magic.TeleportMethod +import content.global.skill.magic.spellconsts.Modern +import core.api.inBorders +import core.api.getQuestStage +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.diary.DiaryType +import core.game.world.map.zone.ZoneBorders +import org.rs09.consts.Components +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery +import content.region.misthalin.lumbridge.dialogue.DukeHoracioDialogue +import content.region.misthalin.varrock.quest.dragonslayer.DukeHoracioDSDialogue +import core.api.inInventory +import core.game.diary.AreaDiaryTask +import core.game.diary.DiaryEventHookBase +import core.game.diary.DiaryLevel +import core.game.event.* +import content.data.Quests + +class LumbridgeAchivementDiary : DiaryEventHookBase(DiaryType.LUMBRIDGE) { + + companion object { + private val DEAD_TREES = arrayOf( + Scenery.DEAD_TREE_1282, + Scenery.DEAD_TREE_1286, + Scenery.DEAD_TREE_1365 + ) + + private val ZOMBIES = arrayOf( + NPCs.ZOMBIE_73, + NPCs.ZOMBIE_74 + ) + + private val CASTLE_ROOF_AREA = ZoneBorders(3207, 3215, 3210, 3222, 3) + private val CASTLE_COURTYARD_AREA = ZoneBorders(3226, 3229, 3217, 3208) + private val COW_PEN_AREA_1 = ZoneBorders(3253, 3255, 3265, 3297) + private val COW_PEN_AREA_2 = ZoneBorders(3245, 3278, 3253, 3298) + private val WIZARDS_TOWER_TOP_FLOOR_AREA = ZoneBorders(3103, 3155, 3115, 3165, 2) + + object BeginnerTasks { + const val CASTLE_CLIMB_TO_HIGHEST_POINT = 0 + const val CASTLE_RAISE_FLAG_ON_ROOF = 1 + const val CASTLE_SPEAK_TO_DUKE_HORACIO = 2 + const val SPEAK_TO_DOOMSAYER = 3 + const val AL_KHARID_PASS_THROUGH_GATE = 4 + const val CHAMPIONS_GUILD_MINE_CLAY = 5 + const val BARBARIAN_VILLAGE_MAKE_SOFT_CLAY = 6 + const val BARBARIAN_VILLAGE_FIRE_A_POT = 7 + const val DRAYNOR_ENTER_SPOOKY_MANSION_COURTYARD = 8 + const val DRAYNOR_VISIT_MARKET = 9 + const val DRAYNOR_TALK_TO_TOWNCRIER_ABOUT_RULES = 10 + const val WIZARDS_TOWER_CLIMB_TO_TOP = 11 + const val SWAMP_MINE_COPPER_ORE = 12 + const val SWAMP_CATCH_SHRIMPS = 13 + const val SWAMP_FISHING_TUTOR_GET_A_JOB = 14 + const val BROWSE_FATHER_AERECK_GRAVES = 15 + const val CHURCH_PLAY_ORGAN = 16 + const val LUMBRIDGE_GUIDE_TALK_ABOUT_SOS = 17 + const val BROWSE_GENERAL_STORE = 18 + const val VISIT_FRED_THE_FARMER = 19 + const val WINDMILL_MAKE_FLOUR = 20 + } + + object EasyTasks { + const val AL_KHARID_MINE_IRON = 0 + const val COWFIELD_OBTAIN_COW_HIDE = 1 + const val AL_KHARID_TAN_COW_HIDE = 2 + const val CRAFT_LEATHER_GLOVES = 3 + const val RIVER_CATCH_PIKE = 4 + const val SMELT_STEEL_BAR = 5 + const val SWAMP_SEARCH_SHED = 6 + const val SWAMP_KILL_GIANT_RAT = 7 + const val SWAMP_CUT_DEAD_TREE = 8 + const val SWAMP_LIGHT_NORMAL_LOGS = 9 + const val SWAMP_COOK_RAT_MEAT_ON_CAMPFIRE = 10 + const val SWAMP_WATER_ALTAR_CRAFT_RUNE = 11 + const val SWAMP_REPLACE_GHOSTSPEAK_AMULET = 12 + const val WIZARDS_TOWER_TAUNT_DEMON = 13 + const val WIZARDS_TOWER_TELEPORT_ESSENCE_MINE = 14 + const val DRAYNOR_ACCESS_BANK = 15 + const val DRAYNOR_WISEOLDMAN_CHECK_JUNK = 16 + const val DRAYNOR_WISEOLDMAN_PEEK_TELESCOPE = 17 + const val DRAYNOR_JAIL_SEWER_KILL_ZOMBIE = 18 + } + + object MediumTasks { + const val DRAYNOR_JAIL_SEWER_SMITH_STEEL_LONGSWORD = 0 + const val RIDE_GNOMECOPTER = 1 + const val CAST_LUMBRIDGE_TELEPORT = 2 + const val CASTLE_LIGHT_WILLOW_LOGS = 3 + const val CASTLE_COOK_LOBSTER_ON_RANGE = 4 + const val CASTLE_OBTAIN_ANTIDRAGON_SHIELD = 5 + const val RIVER_GATHER_WILLOW_LOGS = 6 + const val SMELT_SILVER_BAR = 7 + const val CRAFT_HOLY_SYMBOL = 8 + const val RIVER_CATCH_SALMON = 9 + const val AL_KHARID_MINE_SILVER = 10 + const val SWAMP_MINE_COAL = 11 + } + } + + override val areaTasks + get() = arrayOf( + AreaDiaryTask( + CASTLE_ROOF_AREA, + DiaryLevel.BEGINNER, + BeginnerTasks.CASTLE_CLIMB_TO_HIGHEST_POINT + ), + + AreaDiaryTask( + WIZARDS_TOWER_TOP_FLOOR_AREA, + DiaryLevel.BEGINNER, + BeginnerTasks.WIZARDS_TOWER_CLIMB_TO_TOP + ) + ) + + override fun onResourceProduced(player: Player, event: ResourceProducedEvent) { + when (player.viewport.region.id) { + 12596 -> if (event.itemId == Items.CLAY_434) { + finishTask( + player, + DiaryLevel.BEGINNER, + BeginnerTasks.CHAMPIONS_GUILD_MINE_CLAY + ) + } + + 12593, 12849 -> { + when (event.itemId) { + Items.RAW_SHRIMPS_317 -> { + finishTask( + player, + DiaryLevel.BEGINNER, + BeginnerTasks.SWAMP_CATCH_SHRIMPS + ) + } + + Items.COPPER_ORE_436 -> { + finishTask( + player, + DiaryLevel.BEGINNER, + BeginnerTasks.SWAMP_MINE_COPPER_ORE + ) + } + + Items.COAL_453 -> { + finishTask( + player, + DiaryLevel.MEDIUM, + MediumTasks.SWAMP_MINE_COAL + ) + } + + Items.LOGS_1511 -> { + if (event.source.id in DEAD_TREES) { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.SWAMP_CUT_DEAD_TREE + ) + } + } + + Items.COOKED_MEAT_2142 -> { + if (event.original == Items.RAW_RAT_MEAT_2134) { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.SWAMP_COOK_RAT_MEAT_ON_CAMPFIRE + ) + } + } + } + } + + 12850 -> when (event.itemId) { + Items.WILLOW_LOGS_1519 -> { + finishTask( + player, + DiaryLevel.MEDIUM, + MediumTasks.RIVER_GATHER_WILLOW_LOGS + ) + } + + Items.RAW_PIKE_349 -> { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.RIVER_CATCH_PIKE + ) + } + + Items.RAW_SALMON_331 -> { + finishTask( + player, + DiaryLevel.MEDIUM, + MediumTasks.RIVER_CATCH_SALMON + ) + } + + Items.LOBSTER_379 -> { + if (event.original == Items.RAW_LOBSTER_377 + && event.source.id == Scenery.COOKING_RANGE_114 + ) { + finishTask( + player, + DiaryLevel.MEDIUM, + MediumTasks.CASTLE_COOK_LOBSTER_ON_RANGE + ) + } + } + + Items.UNSTRUNG_SYMBOL_1714 -> { + if (event.original == Items.SILVER_BAR_2355 + && event.source.id == Scenery.FURNACE_36956 + ) { + finishTask( + player, + DiaryLevel.MEDIUM, + MediumTasks.CRAFT_HOLY_SYMBOL + ) + } + } + } + + 13107 -> when (event.itemId) { + Items.IRON_ORE_440 -> { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.AL_KHARID_MINE_IRON + ) + } + + Items.SILVER_ORE_442 -> { + finishTask( + player, + DiaryLevel.MEDIUM, + MediumTasks.AL_KHARID_MINE_SILVER + ) + } + } + } + } + + override fun onNpcKilled(player: Player, event: NPCKillEvent) { + when (player.viewport.region.id) { + 12593, 12849 -> if (event.npc.id == NPCs.GIANT_RAT_86) { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.SWAMP_KILL_GIANT_RAT + ) + } + + 12438, 12439 -> if (event.npc.id in ZOMBIES) { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.DRAYNOR_JAIL_SEWER_KILL_ZOMBIE + ) + } + } + } + + override fun onTeleported(player: Player, event: TeleportEvent) { + when (event.source) { + is NPC -> if (event.method == TeleportMethod.NPC && event.source.id == NPCs.SEDRIDOR_300) { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.WIZARDS_TOWER_TELEPORT_ESSENCE_MINE + ) + } + } + } + + override fun onFireLit(player: Player, event: LitFireEvent) { + when (player.viewport.region.id) { + 12593, 12849 -> if (event.logId == Items.LOGS_1511) { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.SWAMP_LIGHT_NORMAL_LOGS + ) + } + + 12850 -> if (event.logId == Items.WILLOW_LOGS_1519) { + if (inBorders(player, CASTLE_COURTYARD_AREA)) { + finishTask( + player, + DiaryLevel.MEDIUM, + MediumTasks.CASTLE_LIGHT_WILLOW_LOGS + ) + } + } + } + } + + override fun onInteracted(player: Player, event: InteractionEvent) { + when (player.viewport.region.id) { + 12337 -> if (event.target.id == Scenery.RAILING_37668 + && event.option == "taunt-through" + ) { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.WIZARDS_TOWER_TAUNT_DEMON + ) + } + + 12595 -> if (event.target.id == Scenery.FLOUR_BIN_36878 && event.option == "empty" && inInventory(player, Items.EMPTY_POT_1931)) { + finishTask( + player, + DiaryLevel.BEGINNER, + BeginnerTasks.WINDMILL_MAKE_FLOUR + ) + } + } + } + + override fun onAttributeRemoved(player: Player, event: AttributeRemoveEvent) { + when (event.attribute) { + "gc:flying" -> { + finishTask( + player, + DiaryLevel.MEDIUM, + MediumTasks.RIDE_GNOMECOPTER + ) + } + } + } + + override fun onDialogueOpened(player: Player, event: DialogueOpenEvent) { + if (event.dialogue is DukeHoracioDialogue) { + finishTask( + player, + DiaryLevel.BEGINNER, + BeginnerTasks.CASTLE_SPEAK_TO_DUKE_HORACIO + ) + } + } + + override fun onDialogueOptionSelected(player: Player, event: DialogueOptionSelectionEvent) { + when (event.dialogue) { + is DukeHoracioDSDialogue -> { + val dragonSlayerStage = getQuestStage(player, Quests.DRAGON_SLAYER) + + if ((dragonSlayerStage == 100 && event.currentStage == 4) + || event.currentStage == 12) { + finishTask( + player, + DiaryLevel.MEDIUM, + MediumTasks.CASTLE_OBTAIN_ANTIDRAGON_SHIELD + ) + } + } + } + } + + + override fun onPickedUp(player: Player, event: PickUpEvent) { + when (player.viewport.region.id) { + 12850, 12851 -> { + if (event.itemId == Items.COWHIDE_1739) { + if (inBorders(player, COW_PEN_AREA_1) + || inBorders(player, COW_PEN_AREA_2) + ) { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.COWFIELD_OBTAIN_COW_HIDE + ) + } + } + } + } + } + + override fun onInterfaceOpened(player: Player, event: InterfaceOpenEvent) { + when (player.viewport.region.id) { + 12338 -> if (event.component.id == Components.BANK_V2_MAIN_762) { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.DRAYNOR_ACCESS_BANK + ) + } + + 12850 -> if (event.component.id == Components.SHOP_TEMPLATE_620) { + finishTask( + player, + DiaryLevel.BEGINNER, + BeginnerTasks.BROWSE_GENERAL_STORE + ) + } + } + } + + override fun onSpellCast(player: Player, event: SpellCastEvent) { + when (event.spellId) { + Modern.LUMBRIDGE_TELEPORT -> { + finishTask( + player, + DiaryLevel.MEDIUM, + MediumTasks.CAST_LUMBRIDGE_TELEPORT + ) + } + } + } + + override fun onJobAssigned(player: Player, event: JobAssignmentEvent) { + when (player.viewport.region.id) { + 12849 -> if (event.employerNpc.id == NPCs.FISHING_TUTOR_4901) { + finishTask( + player, + DiaryLevel.BEGINNER, + BeginnerTasks.SWAMP_FISHING_TUTOR_GET_A_JOB + ) + } + } + } + + override fun onUsedWith(player: Player, event: UseWithEvent) { + when (player.viewport.region.id) { + 12595 -> if (event.used == Items.EMPTY_POT_1931 && event.with == Scenery.FLOUR_BIN_36878) { + finishTask( + player, + DiaryLevel.BEGINNER, + BeginnerTasks.WINDMILL_MAKE_FLOUR + ) + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/diary/NedDiaryDialogue.kt b/Server/src/main/content/region/misthalin/lumbridge/diary/NedDiaryDialogue.kt new file mode 100644 index 0000000..5e52e23 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/diary/NedDiaryDialogue.kt @@ -0,0 +1,124 @@ +package content.region.misthalin.lumbridge.diary + +import core.game.node.entity.player.link.diary.AchievementDiary +import core.game.node.entity.player.link.diary.DiaryType +import core.game.dialogue.DialogueFile + +class NedDiaryDialogue : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + val level = 2 + when(stage) { + 0 -> { + if (AchievementDiary.canClaimLevelRewards(player, DiaryType.LUMBRIDGE, level)) { + player("I've done all the medium tasks in my Lumbridge", "Achievement Diary.") + stage = 50 + } + else if (AchievementDiary.canReplaceReward(player, DiaryType.LUMBRIDGE, level)) { + player("I've seemed to have lost my explorer's ring...") + stage = 60 + } + else { + options( + "What is the Achievement Diary?", + "What are the rewards?", + "How do I claim the rewards?", + "See you later." + ) + stage = 1 + } + } + 1 -> when (buttonID) { + 1 -> { + player("What is the Achievement Diary?") + stage = 10 + } + 2 -> { + player("What are the rewards?") + stage = 20 + } + 3 -> { + player("How do I claim the rewards?") + stage = 30 + } + 4 -> { + player("See you later!") + stage = 40 + } + } + 10 -> { + npc( + "Ah, well, it's a diary that helps you keep track of", + "particular achievements you've made in the world of", + "Gielinor. In Lumbridge and Draynor I can help you", + "discover some very useful things indeed." + ) + stage++ + } + 11 -> { + npc("Eventually with enough exploration you will be", "rewarded for your explorative efforts.") + stage++ + } + 12 -> { + npc( + "You can access your Achievement Diary by going to", + "the Quest Journal. When you've opened the Quest", + "Journal click on the green star icon on the top right", + "hand corner. This will open the diary." + ) + stage = 0 + } + 20 -> { + npc( + "Ah, well there are different rewards for each", + "Achievement Diary. For completing the Lumbridge and", + "Draynor diary you are presented with an explorer's", + "ring." + ) + stage++ + } + 21 -> { + npc("This ring will become increasingly useful with each", "section of the diary that you complete.") + stage = 0 + } + 30 -> { + npc( + "You need to complete the task so that they're all ticked", + "off then you can claim your reward. Most of them are", + "straightforward although you might find some required", + "quests to be started, if not finished." + ) + stage++ + } + 31 -> { + npc( + "To claim the explorer's ring speak to Explorer Jack in ", + "Lumbridge, Bob in Bob's Axes in Lumbridge, or myself." + ) + stage = 0 + } + 40 -> end() + 50 -> { + npc("Yes I see that, you'll be wanting your", "reward then I assume?") + stage++ + } + 51 -> { + player("Yes please.") + stage++ + } + 52 -> { + AchievementDiary.flagRewarded(player, DiaryType.LUMBRIDGE, level) + npc("This ring is a representation of the adventures you", "went on to complete your tasks.") + stage++ + } + 53 -> { + player("Wow, thanks!") + stage = 0 + } + 60 -> { + AchievementDiary.grantReplacement(player, DiaryType.LUMBRIDGE, level) + npc("You better be more careful this time.") + stage = 0 + } + } + } +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/handlers/BobRepairItem.java b/Server/src/main/content/region/misthalin/lumbridge/handlers/BobRepairItem.java new file mode 100644 index 0000000..12025ef --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/handlers/BobRepairItem.java @@ -0,0 +1,48 @@ +package content.region.misthalin.lumbridge.handlers; + +import content.region.misthalin.lumbridge.dialogue.BobDialogue; +import content.data.RepairItem; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Plugin; +import core.plugin.Initializable; +import core.plugin.ClassScanner; + +/** + * Represents the plugin used to handle an item being used on bob. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class BobRepairItem extends UseWithHandler { + + /** + * Constructs a new {@code BobRepairItem} {@code Object}. + */ + public BobRepairItem() { + super(494, 468, 496, 470, 498, 472, 500, 502, 474, 504, 476, 506, 478, 6741, 4856, 4857, 4858, 4859, 4860, 4862, 4863, 4864, 4865, 4866, 4868, 4869, 4870, 4871, 4872, 4874, 4875, 4876, 4877, 4878, 4880, 4881, 4882, 4883, 4884, 4886, 4887, 4888, 4889, 4890, 4892, 4893, 4894, 4895, 4896, 4898, 4899, 4900, 4901, 4902, 4904, 4905, 4906, 4907, 4908, 4910, 4911, 4912, 4913, 4914, 4916, 4917, 4918, 4919, 4920, 4922, 4923, 4924, 4925, 4926, 4928, 4929, 4930, 4931, 4932, 4934, 4935, 4936, 4937, 4938, 4940, 4941, 4942, 4943, 4944, 4946, 4947, 4948, 4949, 4950, 4952, 4953, 4954, 4955, 4956, 4958, 4959, 4960, 4961, 4962, 4964, 4965, 4966, 4967, 4968, 4970, 4971, 4972, 4973, 4974, 4976, 4977, 4978, 4979, 4980, 4982, 4983, 4984, 4985, 4986, 4988, 4989, 4990, 4991, 4992, 4994, 4995, 4996, 4997, 4998); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(519, NPC_TYPE, this); + addHandler(3797, NPC_TYPE, this); + ClassScanner.definePlugin(new BobDialogue()); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + final RepairItem repair = RepairItem.forId(event.getUsedItem().getId()); + if (repair == null && !BobDialogue.BarrowsEquipment.isBarrowsItem(event.getUsedItem().getId())) { + player.getDialogueInterpreter().open(519, ((NPC) event.getUsedWith()), true, true, null); + return true; + } + player.getDialogueInterpreter().open(519, ((NPC) event.getUsedWith()), true, false, event.getUsedItem().getId(), event.getUsedItem()); + return true; + } + +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/handlers/ChurchSignListener.kt b/Server/src/main/content/region/misthalin/lumbridge/handlers/ChurchSignListener.kt new file mode 100644 index 0000000..ed6d216 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/handlers/ChurchSignListener.kt @@ -0,0 +1,26 @@ +package content.region.misthalin.lumbridge.handlers + +import core.api.* +import org.rs09.consts.Scenery +import core.GlobalStats +import core.ServerConstants +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +class ChurchSignListener : InteractionListener { + + val CHURCH_SIGN = Scenery.SIGNPOST_31299 + + override fun defineListeners() { + on(CHURCH_SIGN, IntType.SCENERY, "read"){ player, _ -> + val deaths = GlobalStats.getDailyDeaths() + val servername = ServerConstants.SERVER_NAME + if(deaths > 0) { + sendDialogue(player, "So far today $deaths unlucky adventurers have died on $servername and been sent to their respawn location. Be careful out there.") + } else { + sendDialogue(player, "So far today not a single adventurer on $servername has met their end grisly or otherwise. Either the streets are getting safer or adventurers are getting warier.") + } + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/handlers/CowFieldSignListener.kt b/Server/src/main/content/region/misthalin/lumbridge/handlers/CowFieldSignListener.kt new file mode 100644 index 0000000..fbad9dc --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/handlers/CowFieldSignListener.kt @@ -0,0 +1,28 @@ +package content.region.misthalin.lumbridge.handlers + +import core.api.* +import org.rs09.consts.Scenery +import core.GlobalStats +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +/** + * @author bushtail + */ + +class CowFieldSignListener : InteractionListener { + + val SIGN = Scenery.SIGNPOST_31297 + + override fun defineListeners() { + on(SIGN, IntType.SCENERY, "read") { player, _ -> + val COW_DEATHS = GlobalStats.getDailyCowDeaths() + if(COW_DEATHS > 0) { + sendDialogue(player, "Local cowherders have reported that $COW_DEATHS cows have been slain in this field today by passing adventurers. Farmers throughout the land fear this may be an epidemic.") + } else { + sendDialogue(player,"The Lumbridge cow population has been thriving today, without a single cow death to worry about!") + } + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/handlers/CowPenZone.java b/Server/src/main/content/region/misthalin/lumbridge/handlers/CowPenZone.java new file mode 100644 index 0000000..ffccf94 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/handlers/CowPenZone.java @@ -0,0 +1,49 @@ +package content.region.misthalin.lumbridge.handlers; + +import core.game.node.entity.Entity; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneBuilder; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.GlobalStats; + +/** + * Zone for the lumbridge cow pen + * @author ceik + */ + + +@Initializable +public class CowPenZone extends MapZone implements Plugin { + public static int CowDeaths; + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + public CowPenZone() { + super("lumbridge cows", true); + } + @Override + public void configure() { + super.register(new ZoneBorders(3242, 3255, 3265, 3297)); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ZoneBuilder.configure(this); + return this; + } + + @Override + public boolean death(Entity e, Entity killer) { + if (killer instanceof Player && e instanceof NPC) { + GlobalStats.incrementDailyCowDeaths(); + } + return false; + } + +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/handlers/CulinoChestListener.kt b/Server/src/main/content/region/misthalin/lumbridge/handlers/CulinoChestListener.kt new file mode 100644 index 0000000..9b5aefc --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/handlers/CulinoChestListener.kt @@ -0,0 +1,29 @@ +package content.region.misthalin.lumbridge.handlers + +import core.api.getUsedOption +import core.api.openBankAccount +import org.rs09.consts.Scenery +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +/** + * Handles the culino chest options. + * @author Ceikry + */ +class CulinoChestListener : InteractionListener { + companion object { + private const val CULINO_CHEST = Scenery.CHEST_12309 + } + + override fun defineListeners() { + on(CULINO_CHEST, IntType.SCENERY, "buy-items", "buy-food"){ player, _ -> + CulinomancerShop.openShop(player, food = getUsedOption(player).lowercase() == "buy-food") + return@on true + } + + on(CULINO_CHEST, IntType.SCENERY, "bank"){ player, _ -> + openBankAccount(player) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/handlers/CulinomancerShop.kt b/Server/src/main/content/region/misthalin/lumbridge/handlers/CulinomancerShop.kt new file mode 100644 index 0000000..e82bcce --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/handlers/CulinomancerShop.kt @@ -0,0 +1,144 @@ +package content.region.misthalin.lumbridge.handlers + +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.system.task.Pulse +import org.rs09.consts.Items +import core.game.shops.Shop +import core.game.shops.ShopItem +import core.game.world.GameWorld +import java.lang.Integer.min +import kotlin.collections.HashMap + +class CulinomancerShop : LoginListener { + //Enable the chest if the player has 18 quest points or more + override fun login(player: Player) { + if(player.questRepository.points >= 18){ + setVarbit(player, 1850, 5) + setAttribute(player, "culino-tier", player.questRepository.points / 18) //Set this, so we can check if the player has gained a tier during server runtime + + //Restock pulse for this player (yes, this means the chest will only restock if the player has logged in. Shop system needs work in order to do otherwise.) + val restockPulse = object : Pulse(100){ //Run once a minute + override fun pulse(): Boolean { + getShop(player, false).restock() + getShop(player, true).restock() + return false + } + } + GameWorld.Pulser.submit(restockPulse) + //Stop the pulse if the player logs out (easy way to avoid a player having multiple restock pulses by relogging a bunch) + //Stopped pulses are cleared from the list on the next tick cycle + player.logoutListeners["culino-restock"] = {restockPulse.stop()} + } + } + + companion object { + // Our shop mappings - shops are individualized due to the differing items based on player's QP. + // Maps player UID -> shop + private val foodShops = HashMap() + private val gearShops = HashMap() + + //Open methods for the shops - should check player's QP and whether they already have a container generated + @JvmStatic + fun openShop(player: Player, food: Boolean) { + getShop(player, food).openFor(player) + } + + //Retrieve a player's shop - should generate the shop if it does not exist. + fun getShop(player: Player, food: Boolean): Shop { + val uid = player.details.uid + val points = player.questRepository.points + val tier = (points / 18) + if (tier != getAttribute(player, "culino-tier", 0)) //If player tier has changed + { + foodShops.remove(uid) //Clear the previous shops, so they can regenerate with the new tier + gearShops.remove(uid) + } + return if (food) { + val shop = foodShops[uid] ?: Shop("Culinomancer's Chest Tier $tier", generateFoodStock(points), false) + foodShops[uid] = shop + shop + } else { + val shop = gearShops[uid] ?: Shop("Culinomancer's Chest Tier $tier", generateGearStock(points), false) + gearShops[uid] = shop + shop + } + } + + //Generate default food stock based on an amount of total QP. + private fun generateFoodStock(points: Int): Array { + val stock = Array(foodStock.size) { ShopItem(0, 0) } + val maxQty = when (val qpTier = (points / 18) - 1) { + 0, 1, 2, 3, 4 -> 1 + qpTier + else -> qpTier + (qpTier + (qpTier - 5)) //5 = 10, 6 = 13, 7 = 15, etc + } + for ((index, item) in foodStock.withIndex()) { + stock[index].itemId = item.id + stock[index].amount = if (item.id == Items.PIZZA_BASE_2283) 1 else maxQty + } + return stock + } + + //Generate default gear stock based on an amount of total QP. + private fun generateGearStock(points: Int): Array { + val stock = Array(gearStock.size) { ShopItem(0, 0) } + val qpTier = (points / 18) + for ((index, item) in stock.withIndex()) item.itemId = gearStock[index] + + for (i in 0 until min(qpTier, 10)) { + stock[i].amount = 30 + stock[i + 10].amount = 5 + } + stock[9].amount = 1 + return stock + } + + //Default gear shop stock + private val gearStock = arrayOf( + Items.GLOVES_7453, + Items.GLOVES_7454, + Items.GLOVES_7455, + Items.GLOVES_7456, + Items.GLOVES_7457, + Items.GLOVES_7458, + Items.GLOVES_7459, + Items.GLOVES_7460, + Items.GLOVES_7461, + Items.GLOVES_7462, + Items.WOODEN_SPOON_7433, + Items.EGG_WHISK_7435, + Items.SPORK_7437, + Items.SPATULA_7439, + Items.FRYING_PAN_7441, + Items.SKEWER_7443, + Items.ROLLING_PIN_7445, + Items.KITCHEN_KNIFE_7447, + Items.MEAT_TENDERISER_7449, + Items.CLEAVER_7451 + ) + + //Default food shop stock + private val foodStock = arrayOf( + Item(Items.CHOCOLATE_BAR_1973, 1), + Item(Items.CHEESE_1985, 1), + Item(Items.TOMATO_1982, 1), + Item(Items.COOKING_APPLE_1955, 1), + Item(Items.GRAPES_1987, 1), + Item(Items.POT_OF_FLOUR_1933, 1), + Item(Items.PIZZA_BASE_2283, 1), + Item(Items.EGG_1944, 1), + Item(Items.BUCKET_OF_MILK_1927, 1), + Item(Items.POT_OF_CREAM_2130, 1), + Item(Items.PAT_OF_BUTTER_6697, 1), + Item(Items.SPICE_2007, 1), + Item(Items.PIE_DISH_2313, 1), + Item(Items.CAKE_TIN_1887, 1), + Item(Items.BOWL_1923, 1), + Item(Items.JUG_1935, 1), + Item(Items.EMPTY_POT_1931, 1), + Item(Items.EMPTY_CUP_1980, 1), + Item(Items.BUCKET_1925, 1) + ) + } +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/handlers/DoomsayerTogglePlugin.java b/Server/src/main/content/region/misthalin/lumbridge/handlers/DoomsayerTogglePlugin.java new file mode 100644 index 0000000..5d7c272 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/handlers/DoomsayerTogglePlugin.java @@ -0,0 +1,55 @@ +package content.region.misthalin.lumbridge.handlers; + +import core.cache.def.impl.NPCDefinition; +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the option plugin used to toggle the doomsayer interface. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public class DoomsayerTogglePlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + NPCDefinition.forId(3777).getHandlers().put("option:toggle-warnings", this); + new WarningMessagePlugin().newInstance(arg); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + player.getWarningMessages().open(player); + return true; + } + + /** + * Represents the plugin used to handle the warning message plugin. + * @author 'Vexia + */ + public final class WarningMessagePlugin extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.put(583, this); + return this; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + if (button > 45 && button < 74) { + player.getWarningMessages().getMessage(button).toggle(player); + } + return true; + } + + } +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/handlers/FredChestListener.kt b/Server/src/main/content/region/misthalin/lumbridge/handlers/FredChestListener.kt new file mode 100644 index 0000000..0157925 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/handlers/FredChestListener.kt @@ -0,0 +1,30 @@ +package content.region.misthalin.lumbridge.handlers + +import core.api.* +import org.rs09.consts.Scenery +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +/** + * @author bushtail + */ + +class FredChestListener : InteractionListener { + val SHUT = Scenery.CLOSED_CHEST_37009 + val OPEN = Scenery.OPEN_CHEST_37010 + + override fun defineListeners() { + on(SHUT, IntType.SCENERY, "open") { _, node -> + replaceScenery(node.asScenery(), OPEN, -1, node.location) + return@on true + } + on(OPEN, IntType.SCENERY, "shut") { _, node -> + replaceScenery(node.asScenery(), SHUT, -1, node.location) + return@on true + } + on(OPEN, IntType.SCENERY, "search") { player, _ -> + sendMessage(player, "You search the chest but find nothing.") + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/handlers/FredsFarmHouseZone.java b/Server/src/main/content/region/misthalin/lumbridge/handlers/FredsFarmHouseZone.java new file mode 100644 index 0000000..d5b0592 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/handlers/FredsFarmHouseZone.java @@ -0,0 +1,44 @@ +package content.region.misthalin.lumbridge.handlers; + +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneBuilder; +import core.plugin.Initializable; +import core.plugin.Plugin; + +@Initializable +public class FredsFarmHouseZone extends MapZone implements Plugin { + + public FredsFarmHouseZone() { + super("freds-farm-house", true); + } + + @Override + public void configure() { + register(new ZoneBorders(3188, 3275, 3192, 3270)); + } + + @Override + public boolean enter(Entity entity) { + // Visit Fred the Farmer's chicken and sheep farm + if (entity.isPlayer()) { + Player player = entity.asPlayer(); + player.getAchievementDiaryManager().finishTask(player, DiaryType.LUMBRIDGE, 0, 19); + } + return super.enter(entity); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ZoneBuilder.configure(this); + return this; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/handlers/GameInstructorPlugin.java b/Server/src/main/content/region/misthalin/lumbridge/handlers/GameInstructorPlugin.java new file mode 100644 index 0000000..2bd8a13 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/handlers/GameInstructorPlugin.java @@ -0,0 +1,36 @@ +package content.region.misthalin.lumbridge.handlers; + +import core.cache.def.impl.NPCDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the 2009Scape instructor plugin. + * @author 'Vexia + * @date 20.11.2013 + */ +@Initializable +public class GameInstructorPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + NPCDefinition.forId(4707).getHandlers().put("option:claim", this); + NPCDefinition.forId(1861).getHandlers().put("option:claim", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + switch (option) { + case "claim": + player.getDialogueInterpreter().open(((NPC) node).getId(), ((NPC) node), true); + break; + } + return true; + } + +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/handlers/GnomeCopterSignListener.kt b/Server/src/main/content/region/misthalin/lumbridge/handlers/GnomeCopterSignListener.kt new file mode 100644 index 0000000..668e131 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/handlers/GnomeCopterSignListener.kt @@ -0,0 +1,20 @@ +package content.region.misthalin.lumbridge.handlers + +import core.api.sendDialogue +import org.rs09.consts.Scenery +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +/** + * @author bushtail + */ + +class GnomeCopterSignListener : InteractionListener { + val SIGN = Scenery.ADVERTISEMENT_30037 + override fun defineListeners() { + on(SIGN, IntType.SCENERY, "read") { player, _ -> + sendDialogue(player, "Come check our gnome copters up north! Disclaimer: EXTREMELY WIP") + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/handlers/HamHideoutPlugin.java b/Server/src/main/content/region/misthalin/lumbridge/handlers/HamHideoutPlugin.java new file mode 100644 index 0000000..f0b482a --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/handlers/HamHideoutPlugin.java @@ -0,0 +1,114 @@ +package content.region.misthalin.lumbridge.handlers; + +import core.cache.def.impl.SceneryDefinition; +import core.game.global.action.ClimbActionHandler; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; +import core.plugin.Initializable; +import core.tools.RandomFunction; + +import static core.api.ContentAPIKt.*; + + +/** + * Represents the ham hide out node interaction plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class HamHideoutPlugin extends OptionHandler { + + /** + * Represents the animation to use. + */ + private static final Animation ANIMATION = new Animation(827); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(5490).getHandlers().put("option:open", this); + SceneryDefinition.forId(5490).getHandlers().put("option:pick-lock", this); + SceneryDefinition.forId(5491).getHandlers().put("option:close", this); + SceneryDefinition.forId(5491).getHandlers().put("option:climb-down", this); + SceneryDefinition.forId(5493).getHandlers().put("option:climb-up", this); + return this; + } + + @Override + public boolean handle(final Player player, Node node, String option) { + final int id = ((Scenery) node).getId(); + switch (id) { + case 5493: + if (player.getLocation().withinDistance(Location.create(3149, 9652, 0))) { + ClimbActionHandler.climb(player, new Animation(828), new Location(3165, 3251, 0)); + return true; + } + ClimbActionHandler.climbLadder(player, (Scenery) node, option); + return true; + case 5490: + case 5491: + switch (option) { + case "open": + if (getVarp(player, 174) == 0) { + player.getPacketDispatch().sendMessage("This trapdoor seems totally locked."); + } else { + setVarp(player, 346, 272731282); + ClimbActionHandler.climb(player, new Animation(827), new Location(3149, 9652, 0)); + GameWorld.getPulser().submit(new Pulse(2, player) { + @Override + public boolean pulse() { + setVarp(player, 174, 0); + return true; + } + }); + } + break; + case "close": + setVarp(player, 174, 0); + break; + case "climb-down": + switch (id) { + case 5491: + player.getProperties().setTeleportLocation(Location.create(3149, 9652, 0)); + break; + } + break; + case "pick-lock": + player.lock(3); + player.animate(ANIMATION); + player.getPacketDispatch().sendMessage("You attempt to pick the lock on the trap door."); + GameWorld.getPulser().submit(new Pulse(2, player) { + @Override + public boolean pulse() { + player.animate(ANIMATION); + player.getPacketDispatch().sendMessage("You attempt to pick the lock on the trap door."); + boolean success = RandomFunction.random(3) == 1; + player.getPacketDispatch().sendMessage(success ? ("You pick the lock on the trap door.") : "You fail to pick the lock - your fingers get numb from fumbling with the lock."); + player.unlock(); + if (success) { + setVarp(player, 174, 1 << 14); + GameWorld.getPulser().submit(new Pulse(40, player) { + @Override + public boolean pulse() { + setVarp(player, 174, 0); + return true; + } + }); + } + return true; + } + }); + break; + } + break; + } + return true; + } + +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/handlers/HansNPC.java b/Server/src/main/content/region/misthalin/lumbridge/handlers/HansNPC.java new file mode 100644 index 0000000..7cae516 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/handlers/HansNPC.java @@ -0,0 +1,64 @@ +package content.region.misthalin.lumbridge.handlers; + +import core.game.node.entity.npc.AbstractNPC; +import core.game.world.map.Location; +import core.plugin.Plugin; + +/** + * Handles the Hans NPC. + * @author Emperor + */ +//@InitializablePlugin +public final class HansNPC extends AbstractNPC { + + /** + * The default spawn location. + */ + private static final Location DEFAULT_SPAWN = Location.create(3221, 3218, 0); + + /** + * The movement path. + */ + private static final Location[] MOVEMENT_PATH = { Location.create(3221, 3214, 0), Location.create(3218, 3211, 0), Location.create(3218, 3208, 0), Location.create(3214, 3205, 0), Location.create(3202, 3205, 0), Location.create(3202, 3232, 0), Location.create(3203, 3233, 0), Location.create(3207, 3233, 0), Location.create(3210, 3230, 0), Location.create(3219, 3230, 0), Location.create(3219, 3222, 0), Location.create(3221, 3222, 0) }; + + /** + * Constructs a new {@code HansNPC} {@Code Object}. + */ + public HansNPC() { + super(0, DEFAULT_SPAWN); + } + + /** + * Constructs a new {@code HansNPC} {@Code Object}. + * @param id The NPC id. + * @param location The location. + */ + public HansNPC(int id, Location location) { + super(id, location, false); + } + + @Override + public void configure() { + super.configure(); + if (isWalks()) { + configureMovementPath(MOVEMENT_PATH); + } + setWalks(true); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new HansNPC(id, location); + } + + @Override + public int[] getIds() { + return new int[] { 0 }; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + init(); + return super.newInstance(arg); + } +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/handlers/LumbridgeBasementPlugin.java b/Server/src/main/content/region/misthalin/lumbridge/handlers/LumbridgeBasementPlugin.java new file mode 100644 index 0000000..7a810e6 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/handlers/LumbridgeBasementPlugin.java @@ -0,0 +1,173 @@ +package content.region.misthalin.lumbridge.handlers; + +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.OptionHandler; +import core.game.interaction.UseWithHandler; +import core.game.node.Node; +import core.game.node.entity.impl.ForceMovement; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.path.Pathfinder; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; +import core.plugin.ClassScanner; +import core.plugin.Initializable; +import core.tools.RandomFunction; + +import static core.api.ContentAPIKt.hasRequirement; +import content.data.Quests; + +/** + * Handles the lumbridge basement. + * @author Vexia + * + */ +@Initializable +public class LumbridgeBasementPlugin extends OptionHandler { + + /** + * The animation to use for the shortcut. + */ + private static final Animation ANIMATION = new Animation(2240); + + /** + * The jumping animation for stepping stones. + */ + private static final Animation JUMP_ANIMATION = new Animation(741); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(6899).getHandlers().put("option:squeeze-through", this); + SceneryDefinition.forId(6898).getHandlers().put("option:squeeze-through", this); + SceneryDefinition.forId(6905).getHandlers().put("option:squeeze-through", this); + SceneryDefinition.forId(6912).getHandlers().put("option:squeeze-through", this); + SceneryDefinition.forId(5949).getHandlers().put("option:jump-across", this); + SceneryDefinition.forId(6658).getHandlers().put("option:enter", this); + SceneryDefinition.forId(32944).getHandlers().put("option:enter", this); + SceneryDefinition.forId(40261).getHandlers().put("option:climb-up", this); + SceneryDefinition.forId(40262).getHandlers().put("option:climb-up", this); + SceneryDefinition.forId(40849).getHandlers().put("option:jump-down", this); + SceneryDefinition.forId(40260).getHandlers().put("option:climb-through", this); + SceneryDefinition.forId(41077).getHandlers().put("option:crawl-through", this); + SceneryBuilder.add(new Scenery(40260, Location.create(2526, 5828, 2), 2)); + return this; + } + + @Override + public boolean handle(final Player player, Node node, String option) { + switch (option) { + case "squeeze-through": + Direction dir = null; + Location to = null; + switch (node.getId()) { + case 6912: + to = node.getLocation().getY() == 9603 ? Location.create(3224, 9601, 0) : Location.create(3224, 9603, 0); + dir = node.getLocation().getY() == 9603 ? Direction.SOUTH : Direction.NORTH; + break; + default: + to = player.getLocation().getX() >= 3221 ? Location.create(3219, 9618, 0) : Location.create(3222, 9618, 0); + dir = player.getLocation().getX() >= 3221 ? Direction.WEST : Direction.EAST; + break; + } + player.sendMessage("You squeeze through the hole."); + ForceMovement.run(player, player.getLocation(), to, ANIMATION, ANIMATION, dir, 20).setEndAnimation(Animation.RESET); + return true; + case "jump-across": + Location f = null; + Location s = null; + switch (node.getId()) { + case 5949: + f = Location.create(3221, 9554, 0); + s = player.getLocation().getY() >= 9556 ? Location.create(3221, 9552, 0) : Location.create(3221, 9556, 0); + break; + } + final Location first = f; + final Location second = s; + player.lock(); + GameWorld.getPulser().submit(new Pulse(2, player) { + int counter = 1; + + @Override + public boolean pulse() { + if (counter == 3) { + player.unlock(); + ForceMovement.run(player, player.getLocation(), second, JUMP_ANIMATION, 20); + player.sendMessage("You leap across with a mighty leap!"); + return true; + } else if (counter == 1){ + ForceMovement.run(player, player.getLocation(), first, JUMP_ANIMATION, 20); + } + counter++; + return false; + } + }); + break; + case "enter": + switch (node.getId()) { + case 32944: + //Location.create(3353,3951,0) + player.teleport(Location.create(3219, 9532, 2)); + break; + case 6658: + //Location.create(3226, 9542, 0) + player.teleport(Location.create(3226, 9542, 0)); + break; + } + break; + case "climb-up": + switch (node.getId()) { + case 40261: + player.teleport(player.getLocation().transform(0, -1, 1)); + break; + case 40262: + player.teleport(player.getLocation().transform(0, -1, 1)); + break; + } + break; + case "jump-down": + switch (node.getId()) { + case 40849: + player.teleport(player.getLocation().transform(0, 1, -1)); + break; + } + break; + case "climb-through": + switch (node.getId()) { + case 40260: + player.teleport(Location.create(2525, 5810, 0)); + break; + } + break; + case "crawl-through": + switch (node.getId()) { + case 41077: + player.teleport(Location.create(2527, 5830, 2)); + break; + } + break; + } + return true; + } + + @Override + public Location getDestination(Node node, Node n) { + if (n instanceof Scenery) { + if (n.getId() == 5949) { + return node.getLocation().getY() >= 9555 ? Location.create(3221, 9556, 0) : Location.create(3221, 9552, 0); + } else if (n.getId() == 40262) { + return n.getLocation().transform(0, 1, 0); + } else if (n.getId() == 40261) { + return n.getLocation().transform(0, 1, 0); + } + } + return null; + } + +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/handlers/LumbridgeInstructorNPC.java b/Server/src/main/content/region/misthalin/lumbridge/handlers/LumbridgeInstructorNPC.java new file mode 100644 index 0000000..53f19c6 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/handlers/LumbridgeInstructorNPC.java @@ -0,0 +1,62 @@ +package content.region.misthalin.lumbridge.handlers; + +import core.game.node.entity.npc.AbstractNPC; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.tools.RandomFunction; + +/** + * Represents the lumbridge instructor npcs. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class LumbridgeInstructorNPC extends AbstractNPC { + + /** + * The NPC ids of NPCs using this plugin. + */ + private static final int[] ID = { 4707, 4906, 705, 1861, 4903, 4899, 4900, 4904 }; + + /** + * Constructs a new {@code LumbridgeInstructorNPC} {@code Object}. + */ + public LumbridgeInstructorNPC() { + super(0, null); + } + + /** + * Constructs a new {@code LumbridgeInstructorNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + private LumbridgeInstructorNPC(int id, Location location) { + super(id, location); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new LumbridgeInstructorNPC(id, location); + } + + @Override + public void tick() { + super.tick(); + } + + @Override + public int getWalkRadius() { + return 4; + } + + @Override + public Location getMovementDestination() { + return getProperties().getSpawnLocation().transform(-2 + RandomFunction.random(getWalkRadius()), -2 + RandomFunction.random(getWalkRadius()), 0); + } + + @Override + public int[] getIds() { + return ID; + } + +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/handlers/LumbridgeNodePlugin.java b/Server/src/main/content/region/misthalin/lumbridge/handlers/LumbridgeNodePlugin.java new file mode 100644 index 0000000..0a0d611 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/handlers/LumbridgeNodePlugin.java @@ -0,0 +1,210 @@ +package content.region.misthalin.lumbridge.handlers; + +import core.api.Container; +import core.cache.def.impl.SceneryDefinition; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.component.Component; +import core.game.activity.ActivityManager; +import core.game.global.action.ClimbActionHandler; +import core.game.node.entity.skill.Skills; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.equipment.Ammunition; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; +import org.rs09.consts.Items; + +import static core.api.ContentAPIKt.*; + +/** + * Represents the node option handler for lumbridge. + * + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class LumbridgeNodePlugin extends OptionHandler { + + /** + * If the flag is in use. + */ + private static boolean FLAG_IN_USE; + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(36978).getHandlers().put("option:play", this); + SceneryDefinition.forId(37335).getHandlers().put("option:raise", this); + SceneryDefinition.forId(37095).getHandlers().put("option:shoot-at", this); + SceneryDefinition.forId(36976).getHandlers().put("option:ring", this); + SceneryDefinition.forId(22114).getHandlers().put("option:open", this); + SceneryDefinition.forId(29355).getHandlers().put("option:climb-up", this); + SceneryDefinition.forId(37655).getHandlers().put("option:view", this); + SceneryDefinition.forId(org.rs09.consts.Scenery.LOGS_36974).getHandlers().put("option:take-axe", this); + return this; + } + + @Override + public boolean handle(final Player player, Node node, String option) { + int id = ((Scenery) node).getId(); + switch (id) { + case 29355: + if (node.getLocation().getX() == 3209) { + ClimbActionHandler.climb(player, ClimbActionHandler.CLIMB_UP, new Location(3210, 3216, 0)); + break; + } + ClimbActionHandler.climbLadder(player, node.asScenery(), "climb-up"); + return true; + case 37095: + if (!player.getEquipment().contains(9706, 1) || !player.getEquipment().contains(9705, 1)) { + player.getPacketDispatch().sendMessage("You need a training bow and arrow to practice here."); + return true; + } + player.getPulseManager().run(new ArcheryTargetPulse(player, (Scenery) node)); + return true; + case 36978: + player.lock(); + ActivityManager.start(player, "organ cutscene", false); + return true; + case 37335: + if (!FLAG_IN_USE) { + FLAG_IN_USE = true; + GameWorld.getPulser().submit(new Pulse(1, player) { + int counter = 0; + + @Override + public boolean pulse() { + switch (counter++) { + case 0: + player.lock(); + player.sendMessage("You start cranking the lever."); + player.getPacketDispatch().sendSceneryAnimation(((Scenery) node), new Animation(9979)); + player.animate(new Animation(9977)); + break; + case 8: + player.sendMessage("The flag reaches the top..."); + player.animate(new Animation(9978)); + break; + case 9: + player.sendChat("All Hail the Duke!"); + case 12: + player.sendMessage("...and slowly descends."); + player.unlock(); + player.getAchievementDiaryManager().finishTask(player, DiaryType.LUMBRIDGE, 0, 1); + break; + } + return counter >= 20; + } + + @Override + public void stop() { + super.stop(); + FLAG_IN_USE = false; + } + }); + } + break; + case 36976: + player.getPacketDispatch().sendMessage("The townspeople wouldn't appreciate you ringing their bell."); + break; + case 37655: + player.getInterfaceManager().open(new Component(270)); + break; + case org.rs09.consts.Scenery.LOGS_36974: + if (!addItem(player, Items.BRONZE_AXE_1351, 1, Container.INVENTORY)) { + sendMessage(player, "You don't have enough inventory space to hold that item."); + } else { + replaceScenery(node.asScenery(), org.rs09.consts.Scenery.LOGS_36975, 300, null); + } + return true; + } + return true; + } + + @Override + public Location getDestination(Node node, Node n) { + if (n instanceof Scenery) { + final Scenery object = (Scenery) n; + if (object.getId() == 36976) { + return Location.create(3243, 3205, 2); + } else if (object.getId() == 37095) { + return n.getLocation().transform(5, 0, 0); + } + } + return null; + } + + /** + * Represents the archery target pulse. + * + * @author 'Vexia + * @version 1.0 + */ + public static final class ArcheryTargetPulse extends Pulse { + + /** + * Represents the player instance. + */ + private final Player player; + + /** + * Represents the scenery. + */ + private final Scenery object; + + /** + * Constructs a new {@code ArcheryCompetitionPulse} {@code Object}. + * + * @param player the player. + * @param object the object. + */ + public ArcheryTargetPulse(final Player player, final Scenery object) { + super(1, player, object); + this.player = player; + this.object = object; + } + + @Override + public boolean pulse() { + if (getDelay() == 1) { + setDelay(player.getProperties().getAttackSpeed()); + } + if (player.getEquipment().remove(new Item(9706, 1))) { + Projectile p = Ammunition.get(9706).getProjectile().transform(player, object.getLocation()); + p.setEndLocation(object.getLocation()); + p.setEndHeight(25); + p.send(); + player.animate(new Animation(426)); + Entity entity = player; + int level = entity.getSkills().getLevel(Skills.RANGE); + int bonus = entity.getProperties().getBonuses()[14]; + double prayer = 1.0; + if (entity instanceof Player) { + prayer += ((Player) entity).getPrayer().getSkillBonus(Skills.RANGE); + } + double cumulativeStr = Math.floor(level * prayer); + if (entity.getProperties().getAttackStyle().getStyle() == WeaponInterface.STYLE_RANGE_ACCURATE) { + cumulativeStr += 3; + } else if (entity.getProperties().getAttackStyle().getStyle() == WeaponInterface.STYLE_LONG_RANGE) { + cumulativeStr += 1; + } + cumulativeStr *= 1.0; + int hit = (int) ((14.0 + cumulativeStr + ((double) bonus / 8) + ((cumulativeStr * bonus) * 0.016865))) / 10 + 1; + player.getSkills().addExperience(Skills.RANGE, ((hit * 1.33) / 10)); + return !player.getEquipment().contains(9706, 1) || !player.getEquipment().contains(9705, 1); + } else { + return true; + } + } + + } +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/handlers/LumbridgeSwampHoleListener.kt b/Server/src/main/content/region/misthalin/lumbridge/handlers/LumbridgeSwampHoleListener.kt new file mode 100644 index 0000000..e5602d5 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/handlers/LumbridgeSwampHoleListener.kt @@ -0,0 +1,63 @@ +package content.region.misthalin.lumbridge.handlers + +import core.api.* +import org.rs09.consts.Animations +import org.rs09.consts.Items +import org.rs09.consts.Scenery as Sceneries +import core.game.component.Component +import core.game.global.action.ClimbActionHandler +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.game.node.Node +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.node.scenery.Scenery +import core.game.node.scenery.SceneryBuilder +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation + +class LumbridgeSwampHoleListener : InteractionListener { + + val CAVE_ENTRANCE = Sceneries.DARK_HOLE_5947 + val CAVE_EXIT_ROPE = Sceneries.CLIMBING_ROPE_5946 + val WARNING_SIGN = Sceneries.WARNING_SIGN_15566 + val TOOL_STORE_FULL = Sceneries.TOOLS_10375 + val TOOL_STORE_EMPTY = 10373 + + override fun defineListeners() { + on(CAVE_ENTRANCE, IntType.SCENERY, "climb-down") { player, _ -> + if (!player.getSavedData().getGlobalData().hasTiedLumbridgeRope()) { + sendDialogue(player, "There is a sheer drop below the hole. You will need a rope.") + } else { + val insideCave = Location.create(3168, 9572, 0) + ClimbActionHandler.climb(player, Animation(Animations.HUMAN_BURYING_BONES_827), insideCave) + } + + return@on true + } + on(CAVE_EXIT_ROPE, IntType.SCENERY, "climb") { player, _ -> + val outsideCave = Location.create(3169, 3173, 0) + player.getProperties().setTeleportLocation(outsideCave); + return@on true + } + on(WARNING_SIGN, IntType.SCENERY, "read") { player, _ -> + player.getPacketDispatch().sendString("~-~-~ WARNING ~-~-~", 220, 5); + player.getPacketDispatch().sendString("Noxious gases vent into this cave.", 220, 7); + player.getPacketDispatch().sendString("Naked flames may cause an explosion!", 220, 8); + player.getPacketDispatch().sendString("Beware of vicious head-grabbing beasts!", 220, 10); + player.getPacketDispatch().sendString("Contact a Slayer master for protective headgear.", 220, 11); + player.getInterfaceManager().open(Component(220)); + return@on true + } + on(TOOL_STORE_FULL, IntType.SCENERY, "take") { player: Player, node: Node -> + if(freeSlots(player) < 2) { + sendDialogue(player, "You do not have enough inventory space.") + } + else if (player.getInventory().add(Item(Items.RAKE_5341), Item(Items.SPADE_952))) { + SceneryBuilder.replace((node as Scenery), (node as Scenery).transform(TOOL_STORE_EMPTY), 300); + } + + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/handlers/OrganCutScene.java b/Server/src/main/content/region/misthalin/lumbridge/handlers/OrganCutScene.java new file mode 100644 index 0000000..26ab44f --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/handlers/OrganCutScene.java @@ -0,0 +1,96 @@ +package content.region.misthalin.lumbridge.handlers; + +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.activity.ActivityPlugin; +import core.game.activity.CutscenePlugin; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.map.build.DynamicRegion; +import core.game.world.update.flag.context.Animation; +import core.net.packet.PacketRepository; +import core.net.packet.context.CameraContext; +import core.net.packet.context.CameraContext.CameraType; +import core.plugin.Initializable; +import core.net.packet.out.CameraViewPacket; + +import static core.api.ContentAPIKt.animateScenery; + +/** + * Represents the organ cutscene. + * @author 'Vexia + */ +@Initializable +public final class OrganCutScene extends CutscenePlugin { + + /** + * Constructs a new {@code OrganCutScene} {@code Object}. + */ + public OrganCutScene() { + super("organ cutscene"); + } + + /** + * Constructs a new {@code OrganCutScene} {@code Object}. + * @param player the player. + */ + public OrganCutScene(final Player player) { + super("organ cutscene"); + this.player = player; + } + + @Override + public void open() { + final Scenery orgin = RegionManager.getObject(base.transform(43, 14, 0)); + final Scenery newOrgin = new Scenery(36979, base.transform(42, 14, 0)); + SceneryBuilder.remove(orgin); + SceneryBuilder.add(newOrgin); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.POSITION, player.getLocation().getX() + 2, player.getLocation().getY() - 7, 405, 1, 100)); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.ROTATION, player.getLocation().getX() + 1, player.getLocation().getY(), 405, 1, 100)); + player.lock(); + GameWorld.getPulser().submit(new Pulse(3) { + @Override + public boolean pulse() { + animateScenery(player, newOrgin, 9982, false); // Not animation 9841 + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.POSITION, player.getLocation().getX() + 2, player.getLocation().getY() - 3, 400, 1, 1)); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.ROTATION, player.getLocation().getX() + 1, player.getLocation().getY(), 400, 1, 1)); + return true; + } + }); + GameWorld.getPulser().submit(new Pulse(30) { + @Override + public boolean pulse() { + unpause(); + player.getAchievementDiaryManager().finishTask(player, DiaryType.LUMBRIDGE, 0, 16); + return true; + } + }); + } + + @Override + public ActivityPlugin newInstance(Player p) throws Throwable { + return new OrganCutScene(p); + } + + @Override + public Location getSpawnLocation() { + return null; + } + + @Override + public Location getStartLocation() { + return base.transform(42, 14, 0); + } + + @Override + public void configure() { + region = DynamicRegion.create(12850); + setRegionBase(); + registerRegion(region.getId()); + } + +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/handlers/TormentedDemonArea.kt b/Server/src/main/content/region/misthalin/lumbridge/handlers/TormentedDemonArea.kt new file mode 100644 index 0000000..2b5a900 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/handlers/TormentedDemonArea.kt @@ -0,0 +1,10 @@ +package content.region.misthalin.lumbridge + +import core.api.* +import core.game.world.map.zone.ZoneBorders +import core.game.world.map.zone.ZoneRestriction + +class TormentedDemonArea : MapArea { + override fun defineAreaBorders() : Array { return arrayOf (ZoneBorders.forRegion(10329)) } + override fun getRestrictions() : Array { return arrayOf (ZoneRestriction.CANNON, ZoneRestriction.RANDOM_EVENTS) } +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/handlers/TormentedDemonNPC.java b/Server/src/main/content/region/misthalin/lumbridge/handlers/TormentedDemonNPC.java new file mode 100644 index 0000000..87f5de1 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/handlers/TormentedDemonNPC.java @@ -0,0 +1,367 @@ +package content.region.misthalin.lumbridge.handlers; + +import java.util.concurrent.TimeUnit; + +import content.data.BossKillCounter; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.InteractionType; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.tools.RandomFunction; +import core.game.node.entity.combat.CombatSwingHandler; + +/** + * Handles the Tormented Demon NPC. + * @author Vexia + * + */ +@Initializable +public class TormentedDemonNPC extends AbstractNPC { + + /** + * The meele protect npc ids. + */ + private static final int[][] MELEE = new int[][] {{8349, 8352, 8355}, {8358, 8361, 8364}}; + + /** + * The mage protect npc ids. + */ + private static final int[][] MAGE = new int[][] {{8350, 8353, 8356}, {8359, 8362, 8365}}; + + /** + * The range protect npc ids. + */ + private static final int[][] RANGE = new int[][] {{8351, 8354, 8357}, {8360, 8363, 8366}}; + + /** + * The tormented demon swing handler. + */ + private final TormentedDemonSwingHandler TD_SWING_HANDLER = new TormentedDemonSwingHandler(); + + /** + * The last combat style switch. + */ + private long lastSwitch = System.currentTimeMillis() + 15000; + + /** + * If the fire shield is enabled. + */ + private boolean fireShield = true; + + /** + * The delay of the shield being non-active. + */ + private long shieldDelay; + + /** + * The damage log of what style is dealing the most damage. + */ + private final int[] damageLog = new int[3]; + + @Override + public void init() { + super.init(); + getAggressiveHandler().setChanceRatio(10); + getAggressiveHandler().setRadius(64); + getAggressiveHandler().setAllowTolerance(false); + } + + /** + * Constructs a new {@Code TormentedDemonNPC} {@Code Object} + */ + public TormentedDemonNPC() { + this(-1, null); + } + + /** + * Constructs a new {@Code TormentedDemonNPC} {@Code Object} + * @param id The npc id. + * @param location The start location. + */ + public TormentedDemonNPC(int id, Location location) { + super(id, location); + setWalks(true); + setAggressive(true); + this.setDefaultBehavior(); + } + + @Override + public boolean shouldPreventStacking(Entity other) { + return other instanceof TormentedDemonNPC; + } + + @Override + public void handleTickActions() { + super.handleTickActions(); + if (!fireShield && shieldDelay < System.currentTimeMillis() && shieldDelay > 0) { + Player p = getAttribute("shield-player", null); + fireShield = true; + shieldDelay = 0; + if (p != null && p.isActive() && p.getLocation().withinDistance(getLocation()) && isActive() && !isHidden(p)) { + p.sendMessage("The Tormented demon regains its strength against your weapon."); + } + } + } + + @Override + public void sendImpact(BattleState state) { + int max = 0; + switch (state.getStyle()) { + case MAGIC: + case RANGE: + max = 26; + break; + case MELEE: + max = 18; + break; + } + + if (state.getEstimatedHit() > max) { + state.setEstimatedHit(RandomFunction.random(max - 5)); + } + } + + @Override + public void checkImpact(BattleState state) { + // Use the formatted hit to ensure protection prayers are applied (i.e. can't darklight while the demon is praying melee). + int formattedHit = (int) state.getAttacker().getFormattedHit(state, state.getEstimatedHit()); + if (state.getAttacker().isPlayer() && formattedHit > 0 && state.getWeapon() != null && (state.getWeapon().getId() == 6746 || state.getWeapon().getId() == 732)) { + // The message doesn't get sent twice, but additional darklight strikes while the shield is down do delay the shield's return. + if(fireShield) { + state.getAttacker().asPlayer().sendMessage("The demon is temporarily weakened by your weapon."); + } + shieldDelay = System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(60); + fireShield = false; + setAttribute("shield-player", state.getAttacker()); + } + if (fireShield) { + state.setEstimatedHit((int) (state.getEstimatedHit() * 0.25)); + graphics(Graphics.create(1885)); + } + if (state.getStyle() == null) { + return; + } + // Use formattedHit for the prayer swap calculation since it's before the fire + // shield reduction was applied (a ranged hit of 8 through the shield corresponds to a + // pre-shield hit of 32, which should cause the demon to switch to praying range). + int hit = formattedHit > 0 ? formattedHit : 1; + damageLog[state.getStyle().ordinal()] = damageLog[state.getStyle().ordinal()] + hit; + } + + @Override + public void onImpact(final Entity entity, BattleState state) { + // Call the parent class's onImpact handler to ensure that retaliation happens if the TD is non-aggressive. + super.onImpact(entity, state); + // "The demon will switch prayers after it receives 31 damage from one attack style." + // This is done in onImpact so that it happens after the damage that caused the switch is dealt. + CombatStyle damaged = getMostDamagedStyle(); + if (damaged != null && damageLog[damaged.ordinal()] >= 31 && damaged != getProperties().getProtectStyle()) { + for (int i = 0; i < 3; i++) { + damageLog[i] = 0; + } + transformDemon(null, damaged); + return; + } else if (lastSwitch < System.currentTimeMillis()) { + transformDemon(RandomFunction.getRandomElement(getAlternateStyle(TD_SWING_HANDLER.style)), null); + lastSwitch = System.currentTimeMillis() + 15000; + // The roar animation that TDs do when they change attack styles + // shouldn't be interrupted by attack/defence animations. + // https://youtu.be/VcWncVTev1s?t=220 + animate(new Animation(10917, Priority.HIGH)); + } + } + + @Override + public void finalizeDeath(Entity killer) { + super.finalizeDeath(killer); + reTransform(); + fireShield = true; + BossKillCounter.addtoKillcount((Player) killer, this.getId()); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new TormentedDemonNPC(id, location); + } + + @Override + public CombatSwingHandler getSwingHandler(boolean hit) { + return TD_SWING_HANDLER; + } + + /** + * Switches the Tormented Demons style (protection & combat) + * @param attackStyle The combat style to switch to. + * @param protectionStyle The protection style to switch to. + */ + public void transformDemon(CombatStyle attackStyle, CombatStyle protectionStyle) { + + + // If either attackStyle or protectionStyle are null, use the current form's values + if(attackStyle == null) { + attackStyle = getProperties().getCombatPulse().getStyle(); + } + if(protectionStyle == null) { + protectionStyle = getProperties().getProtectStyle(); + } + int id = getCombatStyleDemon(protectionStyle, attackStyle); + int oldHp = getSkills().getLifepoints(); + transform(id); + getSkills().setLifepoints(oldHp); + + TD_SWING_HANDLER.style = getProperties().getCombatPulse().getStyle(); + } + + /** + * Gets the most damaged style. + * @return The combat style. + */ + public CombatStyle getMostDamagedStyle() { + int highestDamage = 0; + CombatStyle style = null; + for (int i = 0; i < damageLog.length; i++) { + if (damageLog[i] > highestDamage) { + highestDamage = damageLog[i]; + style = CombatStyle.values()[i]; + } + } + return style; + } + + /** + * Gets a demon id for a combat style. + * @param protection The protections tyle. + * @param style The style. + * @return The id of a demon in a combat style. + */ + public int getCombatStyleDemon(CombatStyle protection, CombatStyle style) { + return getDemonIds(protection)[2 - style.ordinal()]; + } + + /** + * Gets a list of demon ids to chose from for a protection style. + * @param style The style of protection. + * @return The demon ids. + */ + public int[] getDemonIds(CombatStyle style) { + int[][] ids = style == CombatStyle.MELEE ? MELEE : style == CombatStyle.RANGE ? RANGE : MAGE; + return ids[getStartId() == getIds()[0] ? 0 : 1]; + } + + /** + * Gets the alternate styles. + * @param style The style to compare to. + * @return The combat styles to chose from. + */ + public CombatStyle[] getAlternateStyle(CombatStyle style) { + CombatStyle[] styles = new CombatStyle[2]; + int index = 0; + for (int i = 0; i < CombatStyle.values().length; i++) { + if (CombatStyle.values()[i] != style) { + styles[index] = CombatStyle.values()[i]; + index++; + } + } + return styles; + } + + /** + * Gets the start if of the demon. + * @return The start id. + */ + public int getStartId() { + return getId() <= 8357 ? getIds()[0] : getIds()[10]; + } + + @Override + public int[] getIds() { + return new int[] { 8349, 8350, 8351, 8352, 8353, 8354, 8355, 8356, 8357, 8358, 8359, 8360, 8361, 8362, 8363, 8364, 8365, 8366 }; + } + + /** + * Handles the Tormented Demon's combat. + * @author Vexia + * + */ + public class TormentedDemonSwingHandler extends CombatSwingHandler { + + /** + * The current style. + */ + private CombatStyle style = CombatStyle.MELEE; + + /** + * Constructs a new {@Code TormentedDemonSwingHandler} {@Code Object} + */ + public TormentedDemonSwingHandler() { + super(CombatStyle.MELEE); + } + + @Override + public InteractionType canSwing(Entity entity, Entity victim) { + return style.getSwingHandler().canSwing(entity, victim); + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + return style.getSwingHandler().swing(entity, victim, state); + } + + @Override + public void impact(Entity entity, Entity victim, BattleState state) { + style.getSwingHandler().impact(entity, victim, state); + } + + @Override + public void visualizeImpact(Entity entity, Entity victim, BattleState state) { + style.getSwingHandler().visualizeImpact(entity, victim, state); + } + + @Override + public void visualize(Entity entity, Entity victim, BattleState state) { + switch (style) { + case MELEE: + entity.animate(entity.getProperties().getAttackAnimation()); + entity.graphics(Graphics.create(1886)); + break; + case RANGE: + Projectile.ranged(entity, victim, 1887, 88, 36, 50, 15).send(); + entity.animate(entity.getProperties().getRangeAnimation()); + break; + case MAGIC: + Projectile.magic(entity, victim, 1884, 88, 36, 50, 15).send(); + entity.animate(entity.getProperties().getMagicAnimation()); + break; + } + } + + @Override + public int calculateAccuracy(Entity entity) { + return style.getSwingHandler().calculateAccuracy(entity); + } + + @Override + public int calculateHit(Entity entity, Entity victim, double modifier) { + return style.getSwingHandler().calculateHit(entity, victim, modifier); + } + + @Override + public int calculateDefence(Entity victim, Entity attacker) { + return style.getSwingHandler().calculateDefence(victim, attacker); + } + + @Override + public double getSetMultiplier(Entity e, int skillId) { + return style.getSwingHandler().getSetMultiplier(e, skillId); + } + + } +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/handlers/gnomecopter/GCInformationSign.java b/Server/src/main/content/region/misthalin/lumbridge/handlers/gnomecopter/GCInformationSign.java new file mode 100644 index 0000000..1d1284e --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/handlers/gnomecopter/GCInformationSign.java @@ -0,0 +1,50 @@ +package content.region.misthalin.lumbridge.handlers.gnomecopter; + +import core.game.component.Component; +import core.game.node.entity.player.Player; + +/** + * The information signs for the Gnomecopter tours. + * @author Emperor + */ +public enum GCInformationSign { + + /** + * The gnomecopters entrance sign. + */ + ENTRANCE("~ Gnomecopter Tours ~", "Welcome to Gnomecopter", "Tours: the unique flying", "experience!", "", "If you're a new flier, talk to", "Hieronymous and prepare to be", "amazed by this triumph of", "gnomic engineering.", "", "", "Warning: all riders must be at", "least 2ft, 6ins tall."); + + /** + * The button text. + */ + private final String button; + + /** + * The info. + */ + private final String[] info; + + /** + * Constructs a new {@code GCInformationSign} {@code Object}. + * @param button The button text. + * @param info The information. + */ + private GCInformationSign(String button, String... info) { + this.button = button; + this.info = info; + } + + /** + * Reads the information sign. + * @param player The player. + */ + public void read(Player player) { + player.getInterfaceManager().openSingleTab(new Component(723)); + player.getPacketDispatch().sendString(button, 723, 9); + String information = info[0]; + for (int i = 1; i < info.length; i++) { + information += "
" + info[i]; + } + player.getPacketDispatch().sendString(information, 723, 10); + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/handlers/gnomecopter/GnomeCopterActivity.java b/Server/src/main/content/region/misthalin/lumbridge/handlers/gnomecopter/GnomeCopterActivity.java new file mode 100644 index 0000000..021e8ef --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/handlers/gnomecopter/GnomeCopterActivity.java @@ -0,0 +1,203 @@ +package content.region.misthalin.lumbridge.handlers.gnomecopter; + +import core.game.container.impl.EquipmentContainer; +import core.game.activity.ActivityPlugin; +import core.game.interaction.Option; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.impl.ForceMovement; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.game.world.update.flag.context.Graphics; + +/** + * Handles the gnome copter activity. + * @author Emperor + */ +@Initializable +public final class GnomeCopterActivity extends ActivityPlugin { + + /** + * The gnome copter item. + */ + private static final Item COPTER_ITEM = new Item(12842); + + /** + * The landing pads currently in use. + */ + private final boolean[] usedLandingPads = new boolean[4]; + + /** + * Constructs a new {@code GnomeCopterActivity} {@code Object}. + */ + public GnomeCopterActivity() { + super("Gnome copters", false, false, true); + } + + @Override + public ActivityPlugin newInstance(Player p) throws Throwable { + return this; + } + + @Override + public boolean interact(Entity e, Node target, Option option) { + if (target instanceof Scenery) { + Scenery object = (Scenery) target; + if (object.getId() == 30032) { + flyGnomeCopter((Player) e, object); + return true; + } + if (object.getId() == 30036) { + GCInformationSign.ENTRANCE.read((Player) e); + return true; + } + } else if (target instanceof Item && e.getAttribute("gc:flying", false)) { + ((Player) e).getPacketDispatch().sendMessage("You can't do this right now."); + return true; + } + return false; + } + + @Override + public boolean leave(Entity e, boolean logout) { + if (logout && e.getAttribute("gc:flying", false)) { + e.setLocation(getSpawnLocation()); + ((Player) e).getEquipment().remove(COPTER_ITEM); + } + return super.leave(e, logout); + } + + /** + * Starts flying the gnome copter. + * @param player The player. + * @param object The object. + */ + private void flyGnomeCopter(final Player player, final Scenery object) { + if (!player.getLocation().equals(object.getLocation().transform(0, 1, 0))) { + return; + } + if (object.getCharge() == 88) { + player.getPacketDispatch().sendMessage("Someone else is already using this gnomecopter."); + return; + } + if (player.getEquipment().get(EquipmentContainer.SLOT_HAT) != null) { + player.getPacketDispatch().sendMessage("You can't wear a hat on a Gnomecopter."); + return; + } + if (player.getEquipment().get(EquipmentContainer.SLOT_CAPE) != null) { + player.getPacketDispatch().sendMessage("You can't wear a cape on a Gnomecopter."); + return; + } + if (player.getEquipment().get(3) != null || player.getEquipment().get(5) != null) { + player.getPacketDispatch().sendMessage("You need to have your hands free to use this."); + return; + } + player.setAttribute("gc:flying", true); + player.lock(); + player.faceLocation(player.getLocation().transform(0, 3, 0)); + object.setCharge(88); + GameWorld.getPulser().submit(new Pulse(1, player) { + int stage = 0; + + @Override + public boolean pulse() { + if (++stage == 1) { + player.getInterfaceManager().removeTabs(0, 1, 2, 3, 4, 5, 6, 7, 11); + ForceMovement.run(player, player.getLocation(), object.getLocation(), ForceMovement.WALK_ANIMATION, new Animation(8955), Direction.NORTH, 8); + player.lock(); + } else if (stage == 3) { + player.getEquipment().replace(COPTER_ITEM, 3); + player.visualize(Animation.create(8956), Graphics.create(1578)); + player.getAppearance().setStandAnimation(8964); + player.getAppearance().setWalkAnimation(8961); + player.getAppearance().setRunAnimation(8963); + player.getAppearance().setTurn180(8963); + player.getAppearance().setTurn90ccw(8963); + player.getAppearance().setTurn90cw(8963); + player.getAppearance().setStandTurnAnimation(8963); + } else if (stage == 4) { + object.setCharge(88); + player.getPacketDispatch().sendSceneryAnimation(object, new Animation(5)); + } else if (stage == 16) { + player.getWalkingQueue().reset(); + player.getWalkingQueue().addPath(object.getLocation().getX(), object.getLocation().getY() + 16, true); + Graphics.send(Graphics.create(1579), object.getLocation()); + } else if (stage == 20) { + object.setCharge(1000); + player.getPacketDispatch().sendSceneryAnimation(object, new Animation(8941)); + } else if (stage == 33) { + player.unlock(); + landGnomeCopter(player); + return true; + } + return false; + } + }); + } + + /** + * Lands the gnomecopter. + * @param player The player. + */ + private void landGnomeCopter(final Player player) { + int index = 0; + for (index = 0; index < usedLandingPads.length; index++) { + if (!usedLandingPads[index]) { + break; + } + } + usedLandingPads[index] = true; + player.lock(); + final int pad = index; + player.setDirection(Direction.SOUTH); + player.getProperties().setTeleportLocation(Location.create(3162, 3352, 0)); + GameWorld.getPulser().submit(new Pulse(1, player) { + int stage = 0; + int tick = 0; + + @Override + public boolean pulse() { + if (++stage == 1) { + player.getWalkingQueue().reset(); + player.getWalkingQueue().addPath(3162, 3348, true); + player.getWalkingQueue().addPath(3161 - (pad << 1), 3336, true); + tick = stage + player.getWalkingQueue().getQueue().size(); + } else if (stage == tick) { + player.animate(Animation.create(8957)); + } else if (stage == tick + 14) { + SceneryBuilder.add(new Scenery(30034, player.getLocation()), 6); + player.getEquipment().replace(null, 3); + ForceMovement.run(player, player.getLocation(), player.getLocation().transform(0, -1, 0), new Animation(8959), 8); + player.lock(2); + } else if (stage == tick + 15) { + player.unlock(); + player.getInterfaceManager().restoreTabs(); + usedLandingPads[pad] = false; + player.removeAttribute("gc:flying"); + return true; + } + return false; + } + }); + } + + @Override + public Location getSpawnLocation() { + return Location.create(3161, 3337, 0); + } + + @Override + public void configure() { + register(new ZoneBorders(3154, 3330, 3171, 3353)); + } + +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/cooksassistant/CooksAssistant.kt b/Server/src/main/content/region/misthalin/lumbridge/quest/cooksassistant/CooksAssistant.kt new file mode 100644 index 0000000..54d38f4 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/cooksassistant/CooksAssistant.kt @@ -0,0 +1,113 @@ +package content.region.misthalin.lumbridge.quest.cooksassistant + +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import content.data.Quests + +/** + * The Quest Journal and Configuration for the Cook's Assistant Quest. + * @author Qweqker + */ + +@Initializable +class CooksAssistant : Quest(Quests.COOKS_ASSISTANT,15, 14, 1, 29, 0, 1, 2){ + val MILK = 1927 + val FLOUR = 1933 + val EGG = 1944 + + override fun drawJournal(player: Player?, stage: Int) { + + super.drawJournal(player, stage) + + var line = 12 + var stage = player?.questRepository?.getStage(Quests.COOKS_ASSISTANT)!! + + + if(stage < 10){ //If the quest has not been started + + line(player,"I can start this quest by speaking to the !!Cook?? in the", line++) + line(player,"!!Kitchen?? on the ground floor of !!Lumbridge Castle.??", line) + + } else if (stage in 10..99) { //Player has started Cook's Assistant + + //Situation + line(player,"It's the !!Duke of Lumbridge's?? birthday and I have to help", line++) + line(player,"his !!Cook?? make him a !!birthday cake.?? To do this I need to", line++) + line(player,"bring him the following ingredients:", line++) + + //MILK + if (player.getAttribute("cooks_assistant:milk_submitted", false) || player.getAttribute("cooks_assistant:all_submitted", false)) { //If the player has handed in the bucket of milk + line(player,"---I have given the cook a bucket of milk./--", line++) + } else if (player.inventory.contains(MILK, 1)){ // If the player has a bucket of milk in their inventory + line(player, "I have found a !!bucket of milk?? to give to the cook.", line++) + } else { //If the player satisfies none of the above + line(player,"I need to find a !!bucket of milk.?? There's a cattle field east", line++) + line(player,"of Lumbridge, I should make sure I take an empty bucket", line++) + line(player, "with me.", line++) + } + + //FLOUR + if (player.getAttribute("cooks_assistant:flour_submitted", false) || player.getAttribute("cooks_assistant:all_submitted", false)) { //If the player has handed in the pot of flour + line(player,"---I have given the cook a pot of flour./--", line++) + } else if (player.inventory.contains(FLOUR, 1)){ // If the player has a pot of flour in their inventory + line(player, "I have found a !!pot of flour?? to give to the cook.", line++) + } else { //If the player satisfies none of the above + line(player,"I need to find a !!pot of flour.?? There's a mill found north-", line++) + line(player,"west of Lumbridge, I should take an empty pot with me.", line++) + } + + //EGG + if (player.getAttribute("cooks_assistant:egg_submitted", false) || player.getAttribute("cooks_assistant:all_submitted", false)) { //If the player has handed in the egg + line(player,"---I have given the cook an egg./--", line++) + } else if (player.inventory.contains(EGG, 1)){ // If the player has an egg in their inventory + line(player, "I have found an !!egg?? to give to the cook.", line++) + } else { //If the player satisfies none of the above + line(player,"I need to find an !!egg.?? The cook normally gets his eggs from", line++) + line(player,"the Groats' farm, found just to the west of the cattle", line++) + line(player,"field.", line) + } + + //If the player has handed everything in but was interrupted the final dialogue + if (player.getAttribute("cooks_assistant:all_submitted", false) || (player.getAttribute("cooks_assistant:milk_submitted", false) && player.getAttribute("cooks_assistant:flour_submitted", false) && player.getAttribute("cooks_assistant:egg_submitted", false))) { + line(player,"I should return to the !!Cook.??", line) + } + + } else if (stage >= 100) { //If the player has completed the quest + line(player,"---It was the Duke of Lumbridge's birthday, but his cook had/--", line++) + line(player,"---forgotten to buy the ingredients he needed to make him a/--", line++) + line(player,"---cake. I brought the cook an egg, some flour and some milk/--", line++) + line(player,"---and then cook made a delicious looking cake with them./--", line++) + line += 1 + line(player,"---As a reward he now lets me use his high quality range/--", line++) + line(player,"---which lets me burn things less whenever I wish to cook/--",line++) + line(player,"---there./--", line++) + line += 1 + line(player,"QUEST COMPLETE!",line) + } + } + + //The Quest Finish Certificate + override fun finish(player: Player) { + var ln = 10 + super.finish(player) + player.packetDispatch.sendString("You have completed the Cook's Assistant Quest!", 277, 4) + player.packetDispatch.sendItemZoomOnInterface(1891, 240, 277, 5) + + drawReward(player,"1 Quest Point", ln++) + drawReward(player,"300 Cooking XP", ln) + player.skills.addExperience(Skills.COOKING, 300.0) + + //Removing these attributes in the event that they weren't already cleared in the Cook's Dialogue + player.removeAttribute("cooks_assistant:milk_submitted") + player.removeAttribute("cooks_assistant:flour_submitted") + player.removeAttribute("cooks_assistant:egg_submitted") + player.removeAttribute("cooks_assistant:all_submitted") + player.removeAttribute("cooks_assistant:submitted_some_items") + } + + override fun newInstance(`object`: Any?): Quest { + return this + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/cooksassistant/GillieGroatsDialogue.kt b/Server/src/main/content/region/misthalin/lumbridge/quest/cooksassistant/GillieGroatsDialogue.kt new file mode 100644 index 0000000..a951bca --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/cooksassistant/GillieGroatsDialogue.kt @@ -0,0 +1,73 @@ +package content.region.misthalin.lumbridge.quest.cooksassistant + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable + +/** + * Dialogue for Gillie Groats. + * @author Qweqker + */ + +@Initializable +class GillieGroatsDialogue (player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + var milk = false + if (args.size == 2) milk = true + if (milk) { //If the player attempts to milk a dairy cow without a bucket + npc(FacialExpression.LAUGH, "Tee hee! You've never milked a cow before, have you?") + stage = 100 + return true + } + npc(FacialExpression.HAPPY, "Hello, I'm Gillie the Milkmaid. What can I do for you?") + stage = 0 + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + + //If the player talks to Gillie directly + 0 -> options("Who are you?", "Can you tell me how to milk a cow?", "I'm fine, thanks.").also { stage++ } + 1 -> when(buttonId) { + 1 -> npc(FacialExpression.HAPPY, "My name's Gillie Groats. My father is a farmer and I", "milk the cows for him.").also { stage = 10 } + 2 -> player(FacialExpression.ASKING, "So how do you get milk from a cow then?").also { stage = 20 } + 3 -> player(FacialExpression.NEUTRAL, "I'm fine, thanks.").also { stage = 1000 } + } + + //Who are you? + 10 -> player(FacialExpression.ASKING, "Do you have any buckets of milk spare?").also { stage++ } + 11 -> npc(FacialExpression.SUSPICIOUS, "I'm afraid not. We need all of our milk to sell to", "market, but you can milk the cow yourself if you need", "milk.").also { stage++ } + 12 -> player(FacialExpression.HAPPY,"Thanks.").also { stage = 1000 } + + //Can you tell me how to milk a cow? + 20 -> npc(FacialExpression.FRIENDLY, "It's very easy. First you need an empty bucket to hold", "the milk.").also { stage++ } + 21 -> npc(FacialExpression.FRIENDLY, "Then find a dairy cow to milk - you can't milk just", "any cow.").also { stage++ } + 22 -> player(FacialExpression.ASKING, "How do I find a dairy cow?").also { stage++ } + 23 -> npc(FacialExpression.FRIENDLY, "They are easy to spot - they are dark brown and", "white, unlike beef cows, which are light brown and white.", "We also tether them to a post to stop them wandering", "around all over the place.").also {stage++ } + 24 -> npc(FacialExpression.FRIENDLY, "There are a couple very near, in this field.").also { stage++ } + 25 -> npc(FacialExpression.HAPPY, "Then just milk the cow and your bucket will fill with", "tasty, nutritious milk.").also { stage = 1000 } + + //Continuation of attempting to milk a dairy cow without a bucket + 100 -> player(FacialExpression.ASKING, "Erm... No. How could you tell?").also { stage++ } + 101 -> npc(FacialExpression.LAUGH, "Because you're spilling milk all over the floor. What a","waste ! You need something to hold the milk.").also { stage++ } + 102 -> player(FacialExpression.NEUTRAL, "Ah yes, I really should have guessed that one, shouldn't", "I?").also { stage++ } + 103 -> npc(FacialExpression.LAUGH, "You're from the city, aren't you... Try it again with an","empty bucket.").also{ stage++ } + 104 -> player(FacialExpression.NEUTRAL,"Right, I'll do that.").also { stage = 1000 } + + //Dialogue Endpoint + 1000 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return GillieGroatsDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(3807) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/cooksassistant/LumbridgeCookDialogue.kt b/Server/src/main/content/region/misthalin/lumbridge/quest/cooksassistant/LumbridgeCookDialogue.kt new file mode 100644 index 0000000..ae7b643 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/cooksassistant/LumbridgeCookDialogue.kt @@ -0,0 +1,284 @@ +package content.region.misthalin.lumbridge.quest.cooksassistant + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import content.data.Quests + +/** + * Dialogue for the Lumbridge Cook. + * @author Qweqker + */ + +@Initializable +class LumbridgeCookDialogue (player: Player? = null) : DialoguePlugin(player){ + + //Item declaration + val EMPTY_BUCKET = 1925 + val MILK = 1927 + val EMPTY_POT = 1931 + val FLOUR = 1933 + val EGG = 1944 + + //Default settings for the Cook checking for ingredients in the player's inventory + var gave = false + var leftoverItems = "" + + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + if (player?.questRepository?.getQuest(Quests.THE_LOST_TRIBE)?.getStage(player) == 10) { + player("Did you see what happened in the cellar?") + stage = 0 + return true + } + if (player?.questRepository?.getQuest(Quests.COOKS_ASSISTANT)!!.getStage(player) <= 0) { //If the player has ot started cook's assistant + npc(FacialExpression.SAD, "What am I to do?") + stage = 0 + return true + } else if (player?.questRepository?.getQuest(Quests.COOKS_ASSISTANT)!!.getStage(player) in 10..99) { //During the Cook's Assistant Quest + if (player.getAttribute("cooks_assistant:all_submitted", false) || (player.getAttribute("cooks_assistant:milk_submitted", false) && player.getAttribute("cooks_assistant:flour_submitted", false) && player.getAttribute("cooks_assistant:egg_submitted", false))){ //If the player has handed all the ingredients to the chef but did not continue the dialogue + npc(FacialExpression.HAPPY, "You've brought me everything I need! I am saved!", "Thank you!") + stage = 200 + return true + } else { //If the player has not handed all the items to the chef + npc(FacialExpression.SAD, "How are you getting on with finding the ingredients?") + gave = false //Resetting to false here to prevent dialogue skipping later + stage = 100 + return true + } + } + //After completing Cook's Assistant + npc(FacialExpression.HAPPY, "Hello friend, how is the adventuring going?") + stage = 300 + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + if (player.questRepository.getQuest(Quests.THE_LOST_TRIBE).getStage(player) == 10) { + when(stage){ + //Lost Tribe + 0 -> npc("Last night I was in the kitchen and I heard a noise","from the cellar. I opened the trapdoor and saw a","creature dart into a hole in the wall.").also { stage++ } + 1 -> npc("It looked a bit like a goblin, but it had big bulging eyes.","It wasn't wearing armour, but it had this odd helmet","with a light on it.").also { stage++ } + 2 -> npc("The tunnel was too dark for me to follow it, so I went","to tell the Duke. But when we went down to the cellar","the hole had been blocked up, and no one believes me.").also { stage++ } + 3 -> player("I believe you.").also { stage++ } + 4 -> npc("Thank you, ${player.username}! If you can convince the Duke","I'm telling the truth then we can get to the bottom of","this mystery.").also { stage = 1000; player.questRepository.getQuest(Quests.THE_LOST_TRIBE).setStage(player,20) } + 5 -> end() + } + return true + } + when (stage) { + 0 -> options("What's wrong?", "Can you make me a cake?", "You don't look very happy.", "Nice hat!").also { stage++ } + 1 -> when(buttonId) { + 1 -> player(FacialExpression.NEUTRAL, "What's wrong?").also { stage = 10 } + 2 -> player(FacialExpression.ASKING, "You're a cook, why don't you bake me a cake?").also { stage = 20 } + 3 -> player(FacialExpression.NEUTRAL,"You don't look very happy.").also { stage = 30; } + 4 -> player(FacialExpression.HAPPY, "Nice hat!").also { stage = 40 } + } + + //What's wrong? + 10 -> npc(FacialExpression.SCARED, "Oh dear, oh dear, oh dear, I'm in a terrible terrible", "mess! It's the Duke's birthday today, and I should be", "making him a lovely big birthday cake.").also { stage++ } + 11 -> npc(FacialExpression.SAD, "I've forgotten to buy the ingredients. I'll never get", "them in time now. He'll sack me! What will I do? I have", "four children and a goat to look after. Would you help", "me? Please?").also { stage++ } + 12 -> options("I'm always happy to help a cook in distress.", "I can't right now, Maybe later.").also { stage++ } + 13 -> when(buttonId) { + 1 -> player(FacialExpression.HAPPY, "Yes, I'll help you.").also { stage = 50 } + 2 -> player(FacialExpression.ANNOYED, "No, I don't feel like it. Maybe later.").also { stage++ } + } + + //I can't right now + 14 -> npc(FacialExpression.SAD, "Fine. I always knew you Adventurer types were callous", "beasts. Go on your merry way!").also { stage = 1000 } + + //Can you make me a cake? + 20 -> npc(FacialExpression.SAD, "*sniff* Don't talk to me about cakes...").also { stage++ } + 21 -> player(FacialExpression.NEUTRAL, "What's wrong?").also { stage = 10} + + //You don't look very happy + 30 -> npc(FacialExpression.SAD, "No, I'm not. The world is caving in around me - I am", "overcome by dark feelings of impending doom.").also { stage++ } + 31 -> options("What's wrong?","I'd take the rest of the day off if I were you.").also { stage++ } + 32 -> when(buttonId) { + 1 -> player(FacialExpression.NEUTRAL, "What's wrong?").also { stage = 10} + 2 -> player(FacialExpression.NEUTRAL,"I'd take the rest of the day off if I were you.").also { stage++ } + } + 33 -> npc(FacialExpression.SAD,"No, that's the worst thing I could do. I'd get in terrible","trouble.").also { stage++ } + 34 -> player(FacialExpression.ASKING,"Well maybe you need to take a holiday...").also { stage++ } + 35 -> npc(FacialExpression.SAD,"That would be nice, but the Duke doesn't allow holidays","for core staff").also { stage++ } + 36 -> player(FacialExpression.SUSPICIOUS,"Hmm, why not run away to the sea and start a new","life as a Pirate?").also { stage++ } + 37 -> npc(FacialExpression.SAD,"My wife gets sea sick, and I have an irrational fear of","eyepatches. I don't see it working myself.").also { stage++ } + 38 -> player(FacialExpression.NEUTRAL,"I'm afraid I've run out of ideas.").also { stage++ } + 39 -> npc(FacialExpression.SAD,"I know I'm doomed.").also { stage = 21 } + + //Nice hat! + 40 -> npc(FacialExpression.SAD, "Er, thank you. It's a pretty ordinary cook's hat, really.").also { stage++ } + 41 -> player(FacialExpression.HAPPY, "Still, it suits you. The trousers are pretty special too.").also { stage++ } + 42 -> npc(FacialExpression.SAD, "It's all standard-issue cook's uniform.").also { stage++ } + 43 -> player(FacialExpression.HAPPY, "The whole hat, apron, stripy trousers ensemble. It", "works. It makes you looks like a real cook.").also { stage++ } + 44 -> npc(FacialExpression.ANGRY, "I AM a real cook! I haven't got time to be chatting", "about culinary fashion. I'm in desperate need of help!").also { stage = 21 } + + //Yes, I'll help you + 50 -> npc(FacialExpression.HAPPY, "Oh thank you, thank you. I need milk, an egg and", "flour. I'd be very grateful if you can get them for me.").also{ player?.questRepository?.getQuest(Quests.COOKS_ASSISTANT)?.start(player!!); stage++ } + 51 -> player(FacialExpression.NEUTRAL, "So where do I find these ingredients then?").also { stage = 60 } + + //Where do I find these ingredients? + 60 -> options("Where do I find some flour?","How about milk?","And eggs? Where are they found?","Actually, I know where to find this stuff.").also { stage++ } + 61 -> when(buttonId) { + 1 -> npc(FacialExpression.NEUTRAL,"There is a Mill fairly close, go North and then West.","Mill Lane Mill is just off the road to Draynor. I","usually get my flour from there.").also {stage = 70 } + 2 -> npc(FacialExpression.NEUTRAL,"There is a cattle field on the other side of the river,","just across the road from the Groats' Farm.").also { stage = 71 } + 3 -> npc(FacialExpression.NEUTRAL,"I normally get my eggs from the Groats' farm, on the","other side of the river.").also { stage = 73 } + 4 -> player(FacialExpression.NEUTRAL,"Actually, I know where to find this stuff.").also { stage = 1000 } + } + + //Where do I find some flour? + 70 -> npc(FacialExpression.SUSPICIOUS,"Talk to Millie, she'll help, she's a lovely girl and a fine","Miler. Make sure you take a pot with you for the flour","though, " + if (player.inventory.contains(EMPTY_POT, 1)) "you've got one on you already." else "there should be one on the table in here.").also { stage = 80 } + + //How about milk? + 71 -> npc(FacialExpression.SUSPICIOUS,"Talk to Gillie Groats, she looks after the Dairy cows -","she'll tell you everything you need to know about","milking cows!").also { stage++ } + 72 -> + if (player.inventory.contains(EMPTY_BUCKET , 1)) { + npc(FacialExpression.NEUTRAL,"You'll need an empty bucket for the milk itself. I do see", "you've got a bucket with you already luckily!").also { stage = 80 } + } else { + npc(FacialExpression.NEUTRAL,"You'll need an empty bucket for the milk itself. The", "general store just north of the castle will sell you one", "for a couple of coins.").also { stage = 80 } + } + + //And Eggs? + 73 -> npc(FacialExpression.NEUTRAL,"But any chicken should lay eggs.").also { stage = 80 } + + //Alternative menu for "Where do I find these ingredients?" + 80 -> options("Where do I find some flour?","How about milk?","And eggs? Where are they found?","I've got all the information I need. Thanks.").also { stage++ } + 81 -> when(buttonId) { + 1 -> npc(FacialExpression.NEUTRAL,"There is a Mill fairly close, go North and then West.","Mill Lane Mill is just off the road to Draynor. I","usually get my flour from there.").also {stage = 70 } + 2 -> npc(FacialExpression.NEUTRAL,"There is a cattle field on the other side of the river,","just across the road from the Groats' Farm.").also { stage = 71 } + 3 -> npc(FacialExpression.NEUTRAL,"I normally get my eggs from the Groats' farm, on the","other side of the river.").also { stage = 73 } + 4 -> player(FacialExpression.NEUTRAL,"I've got all the information I need. Thanks.").also { stage = 1000 } + } + + 100 -> + if (!player.getAttribute("cooks_assistant:milk_submitted", false) && player.inventory.contains(MILK, 1)) { + player.setAttribute("/save:cooks_assistant:milk_submitted", true).also { + player(FacialExpression.HAPPY, "Here's a bucket of milk.") + player.inventory.remove(Item(MILK)) + gave = true + stage = 100 + } + } else if (!player.getAttribute("cooks_assistant:flour_submitted", false) && player.inventory.contains(FLOUR, 1)) { + player.setAttribute("/save:cooks_assistant:flour_submitted", true).also { + player(FacialExpression.HAPPY, "Here's a pot of flour.") + player.inventory.remove(Item(FLOUR)) + gave = true + stage = 100 + } + } else if (!player.getAttribute("cooks_assistant:egg_submitted", false) && player.inventory.contains(EGG, 1)) { + player.setAttribute("/save:cooks_assistant:egg_submitted", true).also { + player(FacialExpression.HAPPY, "Here's a fresh egg.") + player.inventory.remove(Item(EGG)) + gave = true + stage = 100 + } + } else { + if (gave) { + + //If this is the first time the player gave an item (or items) to the Lumbridge cook + if (!player.getAttribute("cooks_assistant:submitted_some_items", false)) { + player.setAttribute("/save:cooks_assistant:submitted_some_items", true) + } + + //If the player has now handed in all the ingredients + if (player.getAttribute("cooks_assistant:milk_submitted", false) && player.getAttribute("cooks_assistant:flour_submitted", false) && player.getAttribute("cooks_assistant:egg_submitted", false)) { + npc(FacialExpression.HAPPY, "You've brought me everything I need! I am saved!", "Thank you!").also { player.setAttribute("/save:cooks_assistant:all_submitted",true); stage = 200 } + } else { + npc(FacialExpression.WORRIED,"Thanks for the ingredients you have got so far, please get","the rest quickly. I'm running out of time! The Duke","will throw me into the streets!").also { stage = 151 } + } + + } else { //If the player did not give an item to the Lumbridge cook + + //If the player also has never submitted anything before + if (!player.getAttribute("cooks_assistant:submitted_some_items", false)) { + player(FacialExpression.NEUTRAL, "I haven't gotten any of them yet, I'm still looking.").also { stage = 155 } + } else { + options("I'll get right on it.", "Can you remind me how to find these things again?").also { stage = 161 } + } + } + } + + //If the player has submitted some ingredients but not all of them + 150 -> npc(FacialExpression.WORRIED,"Thanks for the ingredients you have got so far, please get","the rest quickly. I'm running out of time! The Duke","will throw me into the streets!").also { stage++ } + + //Checking what the player has left over + 151 -> leftoverItems = "".also{ + if (!player.getAttribute("cooks_assistant:milk_submitted", false)){ + leftoverItems += "A bucket of milk. " + } + if (!player.getAttribute("cooks_assistant:flour_submitted", false)){ + leftoverItems += "A pot of flour. " + } + if (!player.getAttribute("cooks_assistant:egg_submitted", false)){ + leftoverItems += "An egg." + } + if (leftoverItems != ""){ + sendDialogue("You still need to get:",leftoverItems).also {stage = 160} + } else { + npc(FacialExpression.HAPPY, "You've brought me everything I need! I am saved!", "Thank you!").also { player.setAttribute("/save:cooks_assistant:all_submitted",true); stage = 200 } + } + } + + //If the player has yet to collect or hand in any of the ingredients + 155 -> npc(FacialExpression.WORRIED,"Please get the ingredients quickly. I'm running out of","time! The Duke will throw me into the streets!").also { stage++ } + 156 -> sendDialogue("You still need to get:", "A bucket of milk. A pot of flour. An egg.").also { stage = 160 } + + + // Menu after checking the items handed in + 160 -> options("I'll get right on it.","Can you remind me how to find these things again?").also { stage++ } + 161 -> when(buttonId) { + 1 -> player(FacialExpression.NEUTRAL,"I'll get right on it.").also { stage = 1000 } + 2 -> player(FacialExpression.ASKING,"Can you remind me how to find these things again?").also { stage = 60 } + } + + //Final Cooks Assistant Dialogue + 200 -> player(FacialExpression.HAPPY, "So do I get to go to the Duke's Party?").also { stage++ } + 201 -> npc(FacialExpression.SAD, "I'm afraid not, only the big cheeses get to dine with the", "Duke.").also { stage++ } + 202 -> player(FacialExpression.NEUTRAL, "Well, maybe one day I'll be important enough to sit on", "the Duke's table.").also { stage ++ } + 203 -> npc(FacialExpression.NEUTRAL, "Maybe, but I won't be holding my breath.").also { stage++ } + + //Activate the Cook's Assistant Quest Complete Certificate + 204 -> end().also { player?.questRepository?.getQuest(Quests.COOKS_ASSISTANT)?.finish(player!!) } + + //Dialogue after Cook's Assistant Completion + 300 -> if(player.questRepository.getQuest(Quests.THE_LOST_TRIBE).getStage(player) == 10) { + player("Do you know what happened in the castle cellar?").also { stage = 600 } + } else { + options("I am getting strong and mighty.", "I keep on dying.", "Can I use your range?").also { stage++ } + } + 301 -> when (buttonId) { + 1 -> player(FacialExpression.HAPPY, "I am getting strong and mighty. Grrr").also { stage = 310 } + 2 -> player(FacialExpression.SAD, "I keep on dying.").also { stage = 320 } + 3 -> player(FacialExpression.ASKING, "Can I use your range?").also { stage = 330 } + } + + //I am getting strong and mighty + 310 -> npc(FacialExpression.HAPPY,"Glad to hear it!").also { stage = 1000 } + + //I keep on dying + 320 -> npc(FacialExpression.HAPPY, "Ah, well, at least you keep coming back to life too!").also { stage = 1000 } + + //Can I use your range? + 330 -> npc(FacialExpression.HAPPY, "Go ahead! It's a very good range; it's better than most" ,"other ranges.").also { stage++ } + 331 -> npc(FacialExpression.NEUTRAL, "It's called the Cook-o-Matic 100 and it uses a combination","of state-of-the-art temperature regulation and magic.").also { stage++ } + 332 -> player(FacialExpression.ASKING,"Will it mean my food will burn less often?").also { stage++ } + 333 -> npc(FacialExpression.NEUTRAL,"Well, that's what the salesman told us anyway...").also { stage++ } + 334 -> player(FacialExpression.THINKING, "Thanks?").also { stage = 1000 } + //Conversation Endpoint + 1000 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return LumbridgeCookDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(278) + } +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/cooksassistant/MillieMillerDialogue.kt b/Server/src/main/content/region/misthalin/lumbridge/quest/cooksassistant/MillieMillerDialogue.kt new file mode 100644 index 0000000..ea7b4f5 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/cooksassistant/MillieMillerDialogue.kt @@ -0,0 +1,68 @@ + package content.region.misthalin.lumbridge.quest.cooksassistant + + import core.ServerConstants + import core.game.node.entity.player.Player + import core.plugin.Initializable + + /** + * Dialogue for Millie Miller. + * @author Qweqker + */ + + @Initializable + class MillieMillerDialogue (player: Player? = null) : core.game.dialogue.DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + + npc(core.game.dialogue.FacialExpression.HAPPY, "Hello Adventurer. Welcome to Mill Lane Mill. Can I", "help you?") + stage = 0 + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + + //Continuation of Millie's greeting + 0 -> options("Who are you?", "What is this place?", "How do I mill flour?", "I'm fine, thanks.").also { stage++ } + 1 -> when (buttonId) { + 1 -> player(core.game.dialogue.FacialExpression.ASKING, "Who are you?").also { stage = 10 } + 2 -> player(core.game.dialogue.FacialExpression.ASKING, "What is this place?").also { stage = 20 } + 3 -> player(core.game.dialogue.FacialExpression.ASKING, "How do I mill flour?").also { stage = 30 } + 4 -> player(core.game.dialogue.FacialExpression.NEUTRAL, "I'm fine, thanks.").also { stage = 1000 } + } + + //Who are you? + 10 -> npc(core.game.dialogue.FacialExpression.FRIENDLY, "I'm Miss Millicent Miller the Miller of Mill Lane Mill.", "Our family have been milling flour for generations.").also { stage++ } + 11 -> player(core.game.dialogue.FacialExpression.FRIENDLY, "It's a good business to be in. People will always need", "flour.").also { stage++ } + 12 -> player(core.game.dialogue.FacialExpression.ASKING, "How do I mill flour?").also { stage = 30 } + + //What is this place? + 20 -> npc(core.game.dialogue.FacialExpression.SUSPICIOUS, "This is Mill Lane Mill. Millers of the finest flour in", ServerConstants.SERVER_NAME + ", and home to the Miller family for many", "generations").also { stage++ } + 21 -> npc(core.game.dialogue.FacialExpression.HAPPY, "We take grain from the field nearby and mill into flour.").also { stage++ } + 22 -> player(core.game.dialogue.FacialExpression.ASKING, "How do I mill flour?").also { stage = 30 } + + //How do I mill flour? + 30 -> npc(core.game.dialogue.FacialExpression.FRIENDLY, "Making flour is pretty easy. First of all you need to", "get some grain. You can pick some from wheat fields.", "There is one just outside the Mill, but there are many", "others scattered across " + ServerConstants.SERVER_NAME + ". Feel free to pick wheat").also { stage++ } + 31 -> npc(core.game.dialogue.FacialExpression.FRIENDLY, "from our field! There always seems to be plenty of", "wheat there.").also { stage++ } + 32 -> player(core.game.dialogue.FacialExpression.ASKING, "Then I bring my wheat here?").also { stage++ } + 33 -> npc(core.game.dialogue.FacialExpression.FRIENDLY, "Yes, or one of the other mills in " + ServerConstants.SERVER_NAME + ". They all work", "the same way. Just take your grain to the top floor of", "the mill (up two ladders, there are three floors including", "this one) and then place some grain in to the hopper.").also { stage++ } + 34 -> npc(core.game.dialogue.FacialExpression.HAPPY, "Then you need to start the grinding process by pulling", "the hopper lever. You can add more grain, but each", "time you add grain you have to pul the hopper lever", "again.").also { stage++ } + 35 -> player(core.game.dialogue.FacialExpression.ASKING, "So where does the flour go then?").also { stage++ } + 36 -> npc(core.game.dialogue.FacialExpression.SUSPICIOUS, "The flour appears in this room here, you'll need a pot", "to put the flour into. One pot will hold the flour made", "by one load of grain").also { stage++ } + 37 -> npc(core.game.dialogue.FacialExpression.HAPPY, "And that's it! You now have some pots of finely ground", "flour of the highest quality. Ideal for making tasty cakes", "or delicous bread. I'm not a cook so you'll have to ask a", "cook to ind out how to bake things.").also { stage++ } + 38 -> player(core.game.dialogue.FacialExpression.HAPPY, "Great! Thanks for your help.").also { stage = 1000 } + + //Conversation Endpoint + 1000 -> end() + } + return true + } + + override fun newInstance(player: Player?): core.game.dialogue.DialoguePlugin { + return MillieMillerDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(3806) + } + } \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/DramenTreeListener.kt b/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/DramenTreeListener.kt new file mode 100644 index 0000000..679e28b --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/DramenTreeListener.kt @@ -0,0 +1,47 @@ +package content.region.misthalin.lumbridge.quest.lostcity + +import core.game.node.scenery.Scenery +import content.data.skill.SkillingTool +import content.global.skill.gather.woodcutting.WoodcuttingSkillPulse +import core.game.world.map.Location +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery as Sceneries +import core.game.interaction.InteractionListener +import core.api.getQuestStage +import core.api.sendMessage +import core.game.interaction.IntType +import content.data.Quests + +class DramenTreeListener : InteractionListener { + + override fun defineListeners() { + + on(Sceneries.DRAMEN_TREE_1292, IntType.SCENERY, "chop down"){ player, node -> + val questStage = getQuestStage(player,Quests.LOST_CITY) + if (SkillingTool.getHatchet(player) == null) { + sendMessage(player,"You do not have an axe which you have the level to use.") + return@on true + } + if (questStage < 20) { + return@on true + } + if (questStage == 20) { + if (player.getAttribute("treeSpawned", false)) { + return@on true + } + val spirit = TreeSpiritNPC(NPCs.TREE_SPIRIT_655, Location(2862, 9734, 0)) + spirit.target = player + spirit.init() + spirit.attack(player) + player.setAttribute("treeSpawned", true) + spirit.sendChat("You must defeat me before touching the tree!") + return@on true + } + + player.pulseManager.run(WoodcuttingSkillPulse(player, node as Scenery)) + return@on true + } + + } + +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/LostCity.kt b/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/LostCity.kt new file mode 100644 index 0000000..744ef3c --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/LostCity.kt @@ -0,0 +1,75 @@ +package content.region.misthalin.lumbridge.quest.lostcity + +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.plugin.Initializable +import org.rs09.consts.Items +import content.data.Quests + +/** + * LostCity class for the Lost City quest + * @author lila + * @author Vexia + * @author Aero + */ +@Initializable +class LostCity : Quest(Quests.LOST_CITY, 83, 82, 3, 147, 0, 1, 6) { + + class SkillRequirement(val skill: Int?, val level: Int?) + + val requirements = arrayListOf() + + override fun finish(player: Player?) { + player ?: return + super.finish(player) + var line = 10 + player.packetDispatch.sendItemZoomOnInterface(Items.DRAMEN_STAFF_772, 235, 277, 3 + 2) + drawReward(player,"3 Quest points",line++) + drawReward(player,"Access to Zanaris",line++) + player.questRepository.syncronizeTab(player) + } + + override fun drawJournal(player: Player, stage: Int) { + super.drawJournal(player, stage) + when (stage) { + 0 -> { + line(player, BLUE + "I can start this quest by speaking to the Adventurers in", 4 + 7) + line(player, BLUE + "the Swamp just south of Lumbridge.", 5 + 7) + drawQuestRequirements(player) + } + 10 -> line(player, "According to one of the adventurers in Lumbridge Swamp

the entrance to Zanaris is somewhere around there.

Apparently there is a leprechaun hiding in a tree nearby

who can tell me how to enter the Lost City of Zanaris", 4 + 7) + 20 -> line(player, "According to one of the adventurers in Lumbridge Swamp

the entrance to Zanaris is somewhere around there.

I found the Leprechaun hiding in a nearby tree.

He told me that the entrance to Zanaris is in the shed in

Lumbridge swamp but only if I am carrying a Dramen Staff

I can find a Dramen Tree in a cave on Entrana somewhere", 4 + 7) + 21 -> if (player.hasItem(Item(Items.DRAMEN_STAFF_772,1))) { + line(player, "According to one of the adventurers in Lumbridge Swamp

the entrance to Zanaris is somewhere around there.

I found the Leprechaun hiding in a nearby tree.

He told me that the entrance to Zanaris is in the shed in

Lumbridge swamp but only if I am carrying a Dramen Staff.

The Dramen Tree was guarded by a powerful Tree Spirit.

I cut a branch from the tree and crafted a Dramen Staff.

I should enter Zanaris by going to the shed in Lumbridge

Swamp while keeping the Dramen staff with me", 4 + 7) + } else { + line(player, "According to one of the adventurers in Lumbridge Swamp

the entrance to Zanaris is somewhere around there.

I found the Leprechaun hiding in a nearby tree.

He told me that the entrance to Zanaris is in the shed in

Lumbridge swamp but only if I am carrying a Dramen Staff.

The Dramen Tree was guarded by a powerful Tree Spirit.

With the Spirit defeated I can cut a branch from the tree", 4 + 7) + } + 100 -> line(player, "According to one of the adventurers in Lumbridge Swamp

the entrance to Zanaris is somewhere around there.

I found the Leprechaun hiding in a nearby tree.

He told me that the entrance to Zanaris is in the shed in

Lumbridge swamp but only if I am carrying a Dramen Staff.

The Dramen Tree was guarded by a powerful Tree Spirit.

I cut a branch from the tree and crafted a Dramen Staff.

With the mystical Dramen Staff in my possession I was

able to enter Zanaris through the shed in Lumbridge

swamp.


QUEST COMPLETE!", 4 + 7) + } + } + + private fun drawQuestRequirements(player: Player) { + var line = 7 + 7 + val questRequirements = arrayOf( + "Level 31 Crafting", + "Level 36 Woodcutting" + ) + val hasRequirements = booleanArrayOf( + player.getSkills().hasLevel(Skills.CRAFTING, 31), + player.getSkills().hasLevel(Skills.WOODCUTTING,35) + ) + line(player, BLUE + "To complete this quest I will need:", 6) + for (i in 0..1) { + line(player, questRequirements[i], line++, hasRequirements[i]) + } + line(player, BLUE + "and be able to defeat a " + RED + "Level 101 Spirit without weapons", line++) + } + + override fun newInstance(`object`: Any?): Quest { + requirements.add(SkillRequirement(Skills.WOODCUTTING, 36)) + requirements.add(SkillRequirement(Skills.CRAFTING, 31)) + return this + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/LostCityListeners.kt b/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/LostCityListeners.kt new file mode 100644 index 0000000..32bef20 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/LostCityListeners.kt @@ -0,0 +1,74 @@ +package content.region.misthalin.lumbridge.quest.lostcity + +import core.api.* +import core.game.node.entity.player.link.TeleportManager.TeleportType +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.node.scenery.Scenery +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.Items +import core.game.interaction.IntType +import org.rs09.consts.Scenery as Sceneries +import core.game.interaction.InteractionListener +import core.game.world.GameWorld +import content.data.Quests + +/** + * This class covers some listeners for the Lost City quest + * @author lila + * @author Player Name + */ +@Initializable +class LostCityListeners : InteractionListener { + + override fun defineListeners() { + + // the shed teleport, to allow players to access zanaris if they enter the shed while wielding the dramen staff + on(Sceneries.DOOR_2406, IntType.SCENERY,"open"){ player, node -> + core.game.global.action.DoorActionHandler.handleAutowalkDoor(player,node as Scenery) + val isOutsideShed = player.location.x < node.location.x + val canDramenTeleport = inEquipment(player,Items.DRAMEN_STAFF_772) && getQuestStage(player, Quests.LOST_CITY) > 20 && isOutsideShed + if (canDramenTeleport) { + var count = 0 + // pulser to handle the teleport. after 2 ticks it checks if the player hasn't completed Lost City; if so, then it finishes the quest after the teleport + GameWorld.Pulser.submit(object : Pulse(2) { + override fun pulse(): Boolean { + when (count++) { + 0 -> { + if (player.isTeleBlocked()) { + sendMessage(player,"A magical force has stopped you from teleporting.") + } else { + sendMessage(player,"The world starts to shimmer...") + teleport(player, Location(2452, 4473, 0), TeleportType.FAIRY_RING) + } + } + 1 -> return isQuestComplete(player, Quests.LOST_CITY) + 2 -> { + finishQuest(player, Quests.LOST_CITY) + return true + } + } + return false + } + }) + } + return@on true + } + // creating the dramen staff via using knife on dramen branch + onUseWith(IntType.ITEM,Items.KNIFE_946,Items.DRAMEN_BRANCH_771){ player, _, _ -> + if(!player.skills.hasLevel(Skills.CRAFTING,31)) { + sendDialogue(player,"You need a crafting level of 31 to do this.") + return@onUseWith false + } + runTask(player, 2) { + if (removeItem(player, Item(Items.DRAMEN_BRANCH_771, 1), Container.INVENTORY)) { + sendDialogue(player,"You carve the branch into a staff.") + addItem(player, Items.DRAMEN_STAFF_772, 1, Container.INVENTORY) + } + } + return@onUseWith true + } + } +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/ShamusDialogue.kt b/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/ShamusDialogue.kt new file mode 100644 index 0000000..15800e2 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/ShamusDialogue.kt @@ -0,0 +1,66 @@ +package content.region.misthalin.lumbridge.quest.lostcity + +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs +import core.api.getQuestStage +import core.api.setQuestStage +import content.data.Quests + +/** + * ShamusDialogue, to handle the dialogue of Shamus the Leprechaun from the Lost City quest + * @author lila + * @author Vexia + */ +@Initializable +class ShamusDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin(player) { + override fun open(vararg args: Any?): Boolean { + npcl(core.game.dialogue.FacialExpression.ANNOYED,"Ay yer big elephant! Yer've caught me, to be sure! What would an elephant like yer be wanting wid ol' Shamus then?") + stage = 0 + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(getQuestStage(player, Quests.LOST_CITY)) { + 0 -> when(stage++) { + 0 -> playerl(core.game.dialogue.FacialExpression.THINKING, "I'm not sure.") + 1 -> npcl(core.game.dialogue.FacialExpression.ANNOYED,"Well you'll have to be catchin' me again when yer are, elephant!") + 2 -> end().also { ShamusTreeListener.disappearShamus() } + } + 10 -> when(stage++) { + 0 -> playerl(core.game.dialogue.FacialExpression.NEUTRAL,"I want to find Zanaris.") + 1 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL,"Zanaris is it now? Well well well... Yer'll be needing to be going to that funny little shed out there in the swamp, so you will.") + 2 -> playerl(core.game.dialogue.FacialExpression.THINKING,"...but... I thought... Zanaris was a city?") + 3 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Aye that it is!") + 4 -> playerl(core.game.dialogue.FacialExpression.THINKING,"...How does it fit in a shed then?") + 5 -> npcl(core.game.dialogue.FacialExpression.LAUGH,"Ah yer stupid elephant! The city isn't IN the shed! The doorway to the shed is being a portal to Zanaris, so it is.") + 6 -> playerl(core.game.dialogue.FacialExpression.HALF_THINKING,"So I just walk into the shed and end up in Zanaris then?") + 7 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "Oh, was I fergetting to say? Yer need to be carrying a Dramenwood staff to be getting there! Otherwise Yer'll just be ending up in the shed.") + 8 -> playerl(core.game.dialogue.FacialExpression.ASKING,"So where would I get a staff?") + 9 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL,"Dramenwood staffs are crafted from branches of the Dramen tree, so they are. I hear there's a Dramen tree over on the island of Entrana in a cave.") + 10 -> npcl(core.game.dialogue.FacialExpression.HALF_THINKING,"or some such. There would be probably be a good place for an elephant like yer to be starting looking I reckon.") + 11 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL,"The monks are running a ship from Port Sarim to Entrana, I hear too. Now leave me alone yer elephant!") + 12 -> end().also { + ShamusTreeListener.disappearShamus() + sendDialogue("The leprechaun magically disappears.") + setQuestStage(player, Quests.LOST_CITY, 20) + } + } + else -> when(stage++) { + 0 -> playerl(core.game.dialogue.FacialExpression.THINKING, "I'm not sure.") + 1 -> { + val pronoun = if(player.isMale) "he" else "she" + npcl(core.game.dialogue.FacialExpression.ANNOYED,"HA! Look at yer! Look at the stupid elephant who tries to go catching a leprechaun when $pronoun don't even be knowing what $pronoun wants!") + } + 2 -> end().also { ShamusTreeListener.disappearShamus() } + } + + } + return true + } + + override fun newInstance(player: Player): core.game.dialogue.DialoguePlugin { + return ShamusDialogue(player) + } + override fun getIds(): IntArray = intArrayOf(NPCs.SHAMUS_654) +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/ShamusTreeListener.kt b/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/ShamusTreeListener.kt new file mode 100644 index 0000000..a35fc5b --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/ShamusTreeListener.kt @@ -0,0 +1,72 @@ +package content.region.misthalin.lumbridge.quest.lostcity + +import core.api.sendMessage +import core.api.sendNPCDialogue +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import content.data.skill.SkillingTool +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.game.world.GameWorld + + +/** + * Shamus tree listener, to handle when a player chops Shamus's home tree, + * and to handle some details about the Shamus NPC + * @author lila + * @author Vexia + */ +@Initializable +class ShamusTreeListener : InteractionListener { + + init { + SHAMUS.init() + SHAMUS.isWalks = true + SHAMUS.isInvisible = true + } + + companion object { + val SHAMUS = NPC(NPCs.SHAMUS_654, Location(3138, 3211, 0)) + fun disappearShamus() { + SHAMUS.isInvisible = true + } + } + + private fun handleShamusTree(player: Player): Boolean { + if (SkillingTool.getHatchet(player) == null) { + sendMessage(player,"You do not have an axe which you have the level to use.") + return true + } + showShamus(player) + return true + } + + private fun showShamus(player: Player) { + if(SHAMUS.isInvisible) { + SHAMUS.isInvisible = false + SHAMUS.properties.teleportLocation = SHAMUS.properties.spawnLocation + } + sendNPCDialogue(player,NPCs.SHAMUS_654,"Hey! Yer big elephant! Don't go choppin' down me house, now!", core.game.dialogue.FacialExpression.FURIOUS) + GameWorld.Pulser.submit(object : Pulse(100) { + override fun pulse(): Boolean { + if (SHAMUS.dialoguePlayer == null) { + SHAMUS.isInvisible = true + return true + } + return false + } + }) + } + + override fun defineListeners() { + on(Scenery.TREE_2409, IntType.SCENERY, "chop") { player, _ -> + handleShamusTree(player) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/TreeSpiritNPC.kt b/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/TreeSpiritNPC.kt new file mode 100644 index 0000000..754a82d --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/TreeSpiritNPC.kt @@ -0,0 +1,56 @@ +package content.region.misthalin.lumbridge.quest.lostcity + +import core.game.node.entity.Entity +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.NPCs +import core.api.getQuestStage +import core.api.sendDialogue +import core.api.setQuestStage +import content.data.Quests + +/** + * TreeSpiritNPC class to handle the tree spirit that spawns out of the dramen tree + */ +@Initializable +class TreeSpiritNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id, location) { + var target: Player? = null + + override fun construct(id: Int, location: Location, vararg objects: Any): AbstractNPC { + return TreeSpiritNPC(id, location) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.TREE_SPIRIT_655) + } + init { + isWalks = true + isRespawn = false + } + + override fun handleTickActions() { + if(target==null) { + clear() + return + } + super.handleTickActions() + if (!inCombat()) { + attack(target) + } + if (!target!!.isActive() || target!!.getLocation().getDistance(getLocation()) > 15) { + clear() + target!!.removeAttribute("treeSpawned") + } + } + + override fun finalizeDeath(killer: Entity) { + super.finalizeDeath(killer) + if (killer is Player) { + if (getQuestStage(killer, Quests.LOST_CITY) == 20) { + setQuestStage(killer, Quests.LOST_CITY,21) + sendDialogue(killer, "With the Tree Spirit defeated you can now chop the tree.") + } + } + } +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/WarriorDialogue.kt b/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/WarriorDialogue.kt new file mode 100644 index 0000000..9281c91 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/lostcity/WarriorDialogue.kt @@ -0,0 +1,99 @@ +package content.region.misthalin.lumbridge.quest.lostcity + +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs +import core.game.dialogue.Topic +import core.tools.END_DIALOGUE +import core.api.getQuestStage +import core.api.startQuest +import content.data.Quests + +/** + * WarriorDialogue, to handle the dialogue for the Warrior in the Lost City quest + * @author lila + * @author Vexia + */ +@Initializable +class WarriorDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + when(getQuestStage(player,Quests.LOST_CITY)) { + 10 -> playerl(core.game.dialogue.FacialExpression.THINKING,"So let me get this straight: I need to search the trees around here for a leprechaun; and then when I find him, he will tell me where this 'Zanaris' is?").also { stage = 1000 } + 20, 21 -> playerl(core.game.dialogue.FacialExpression.HAPPY,"Have you found anything yet?").also { stage = 2000 } + 100 -> playerl(core.game.dialogue.FacialExpression.HAPPY,"Hey, thanks for all the information. It REALLY helped me out in finding the lost city of Zanaris and all.").also { stage = 3000 } + else -> npcl(core.game.dialogue.FacialExpression.NEUTRAL,"Hello there traveller.").also { stage = 1 } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage) { + 1 -> showTopics( + Topic(core.game.dialogue.FacialExpression.THINKING,"What are you camped out here for?",100), + Topic(core.game.dialogue.FacialExpression.HALF_THINKING,"Do you know any good adventures I can go on?",101) + ) + 2 -> showTopics( + Topic(core.game.dialogue.FacialExpression.ASKING,"Please tell me.",200), + Topic(core.game.dialogue.FacialExpression.ANGRY,"I don't think you've found a good adventure at all!",250) + ) + 3 -> showTopics( + Topic(core.game.dialogue.FacialExpression.ASKING,"Who's Zanaris?",301), + Topic(core.game.dialogue.FacialExpression.ASKING,"What's Zanaris?",302), + Topic(core.game.dialogue.FacialExpression.ASKING,"What makes you think it's out here?",300) + ) + 4 -> showTopics( + Topic(core.game.dialogue.FacialExpression.ASKING,"If it's hidden how are you planning to find it?",400), + Topic(core.game.dialogue.FacialExpression.LAUGH,"There's no such thing!",450) + ) + 5 -> options("Please tell me.", "Looks like you don't know either.").also { stage = 500 } + 6 -> playerl(core.game.dialogue.FacialExpression.HAPPY,"So a leprechaun knows where Zanaris is eh?").also { stage = 600 } + 7 -> playerl(core.game.dialogue.FacialExpression.HAPPY,"Thanks for the help!").also { stage = 700 } + 8 -> end().also { + startQuest(player,Quests.LOST_CITY) + } + 100 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"We're looking for Zanaris...GAH! I mean we're not here for any particular reason at all.").also { stage = 3 } + 101 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL,"Well we're on an adventure right now. Mind you, this is OUR adventure and we don't want to share it - find your own!").also { stage = 2 } + 200 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL,"No.").also { stage++ } + 201 -> playerl(core.game.dialogue.FacialExpression.SAD,"Please?").also { stage++ } + 202 -> npcl(core.game.dialogue.FacialExpression.ANNOYED,"No!").also { stage++ } + 203 -> playerl(core.game.dialogue.FacialExpression.SAD,"PLEEEEEEEEEEEEEEEEEEEEEEEEASE???").also { stage++ } + 204 -> npcl(core.game.dialogue.FacialExpression.ANGRY,"NO!").also { stage = END_DIALOGUE } + 250 -> npcl(core.game.dialogue.FacialExpression.ANGRY,"Hah! Adventurers of our calibre don't just hang around in forests for fun, whelp!").also { stage++ } + 251 -> playerl(core.game.dialogue.FacialExpression.THINKING,"Oh Really?").also { stage++ } + 252 -> playerl(core.game.dialogue.FacialExpression.THINKING,"What are you camped out here for?").also{ stage = 100 } + 300 -> npcl(core.game.dialogue.FacialExpression.HAPPY,"Don't you know of the legends that tell of the magical city, hidden in the swamp... Uh, no, you're right, we're wasting our time here.").also { stage = 4 } + 301 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL,"Ahahahaha! Zanaris isn't a person! It's a magical hidden city filled with treasure and rich... uh, nothing. It's nothing.").also { stage = 4 } + 302 -> npcl(core.game.dialogue.FacialExpression.HALF_THINKING,"I don't think we want other people competing with us to find it. Forget I said anything.").also { stage = 5 } + 400 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL,"Well, we don't want to tell anyone else about that, because we don't want anyone else sharing in all that glory and treasure.").also { stage = 5 } + 450 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL,"When we've found Zanaris you'll... GAH! I mean, we're not here for any particular reason at all.").also { stage = 3 } + 500 -> when(buttonId) { + 1 -> playerl(core.game.dialogue.FacialExpression.ASKING,"Please tell me.").also{ stage = 200 } + 2 -> playerl(core.game.dialogue.FacialExpression.THINKING,"Well, it looks to ME like YOU don't know EITHER, seeing as you're all just sat around here.").also { stage++ } + } + 501 -> npcl(core.game.dialogue.FacialExpression.ANGRY,"Of course we know! We just haven't found which tree the stupid leprechaun's hiding in yet!").also { stage++ } + 502 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL,"GAH! I didn't mean to tell you that! Look, just forget I said anything okay?").also { stage = 6 } + 600 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL,"Ye.. uh, no. No, not at all. And even if he did - which he doesn't - he DEFINITELY ISN'T hiding in some tree around here. Nope, definitely not. Honestly.").also { stage = 7 } + 700 -> npcl(core.game.dialogue.FacialExpression.WORRIED,"Help? What help? I didn't help! Please don't say I did, I'll get in trouble!").also { stage = 8 } + 1000 -> npcl(core.game.dialogue.FacialExpression.WORRIED,"What? How did you know that? Uh... I mean, no, no you're very wrong. Very wrong, and not right at all, and I definitely didn't tell you about that at all.").also { stage = END_DIALOGUE } + 2000 -> npcl(core.game.dialogue.FacialExpression.SAD,"We're still searching for Zanaris...GAH! I mean we're not doing anything here at all.").also { stage++ } + 2001 -> playerl(core.game.dialogue.FacialExpression.SAD,"I haven't found it yet either.").also { stage = END_DIALOGUE } + 3000 -> npcl(core.game.dialogue.FacialExpression.SAD,"Oh please don't say that anymore! If the rest of my party knew I'd helped you they'd probably throw me out and make me walk home by myself!").also { stage++ } + 3001 -> npcl(core.game.dialogue.FacialExpression.ASKING,"So anyway, what have you found out? Where is the fabled Zanaris? Is it all the legends say it is?").also { stage++ } + 3002 -> playerl(core.game.dialogue.FacialExpression.HAPPY,"You know.... I think I'll keep that to myself.").also { stage = END_DIALOGUE } + } + return true + } + + override fun newInstance(player: Player): core.game.dialogue.DialoguePlugin { + return WarriorDialogue(player) + } + override fun getIds(): IntArray = intArrayOf(NPCs.WARRIOR_650) +} + +/* +Some evidence from early/mid 2009 to help determine facial expressions, and contains some lines not previously included in this warrior's dialogue +this also functions as evidence for most of the warrior's dialogue +https://www.youtube.com/watch?v=nFDifUB8dxQ +https://www.youtube.com/watch?v=4BKRG4yw16o + */ diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/runemysteries/DukeHoracioRMDialogue.kt b/Server/src/main/content/region/misthalin/lumbridge/quest/runemysteries/DukeHoracioRMDialogue.kt new file mode 100644 index 0000000..42ad4fa --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/runemysteries/DukeHoracioRMDialogue.kt @@ -0,0 +1,68 @@ +package content.region.misthalin.lumbridge.quest.runemysteries + +import core.game.node.entity.player.link.quest.Quest +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import core.game.dialogue.DialogueFile +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import content.data.Quests + +class DukeHoracioRMDialogue(val questStage: Int) : DialogueFile() { + + private val TALISMAN = Item(1438) + + override fun handle(componentID: Int, buttonID: Int) { + + if(questStage == 0){ + + when(stage){ + START_DIALOGUE -> npc("Well, it's not really a quest but I recently discovered", "this strange talisman.").also{ stage++ } + 1 -> npc("It seems to be mystical and I have never seen anything", "like it before. Would you take it to the head wizard at").also { stage++ } + 2 -> npc("the Wizards' Tower for me? It's just south-west of here", "and should not take you very long at all. I would be", "awfully grateful.").also { stage++ } + 3 -> options("Sure, no problem.", "Not right now.").also { stage++ } + 4 -> when(buttonID){ + 1 -> player("Sure, no problem.").also { stage = 10 } + 2 -> player("Not right now.").also { stage = 20 } + } + + //Sure + 10 -> npc("Thank you very much, stranger. I am sure the head", "wizard will reward you for such an interesting find.").also { stage++ } + 11 -> { + interpreter!!.sendDialogue("The Duke hands you an " + Quest.BLUE + "air talisman.").also { stage++ } + player!!.questRepository.getQuest(Quests.RUNE_MYSTERIES).start(player) + if (!player!!.inventory.add(TALISMAN)) { + GroundItemManager.create(TALISMAN, player!!.location, player) + } + stage = END_DIALOGUE + } + + //No thanks + 20 -> npc("As you wish, stranger, although I have this strange", "feeling that it is important. Unfortunately, I cannot", "leave my castle unattended.").also { stage = END_DIALOGUE } + } + + } + + else if(questStage == 10){ + + when(stage){ + START_DIALOGUE -> npc("The only task remotely approaching a quest is the", "delivery of the talisman I gave you to the head wizard", "of the Wizards' Tower,").also { stage++ } + 1 -> npc("south-west of here. I suggest you deliver it to him as", "soon as possible. I have the oddest feeling that is", "important...").also { stage = END_DIALOGUE } + } + + } + + else if(questStage > 10){ + + when(stage){ + START_DIALOGUE -> npc("Nope, I've got everything under control", "in the castle at the moment.").also { stage = END_DIALOGUE } + } + + } + + else { + abandonFile() + } + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/runemysteries/RuneMysteries.java b/Server/src/main/content/region/misthalin/lumbridge/quest/runemysteries/RuneMysteries.java new file mode 100644 index 0000000..85e3299 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/runemysteries/RuneMysteries.java @@ -0,0 +1,112 @@ +package content.region.misthalin.lumbridge.quest.runemysteries; + +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.game.node.entity.player.link.quest.Quest; +import content.data.Quests; + +/** + * Represents the rune mysteries fortress quest. + * @author 'Vexia + */ +@Initializable +public class RuneMysteries extends Quest { + + /** + * Constructs a new {@code RuneMysteries} {@code Object}. + */ + public RuneMysteries() { + super(Quests.RUNE_MYSTERIES, 27, 26, 1, 63, 0, 1, 6); + } + + @Override + public void drawJournal(Player player, int stage) { + super.drawJournal(player, stage); + if (getStage(player) == 0) { + line(player, BLUE + "I can start this quest by speaking to " + RED + "Duke Horacio " + BLUE + "of", 4+ 7); + line(player, RED + "Lumbridge, " + BLUE + "upstairs in " + RED + "Lumbridge Castle.", 5+ 7); + } + if (getStage(player) == 10) { + line(player, "I spoke to Duke Horacio and he showed me a strange", 4+ 7); + line(player, "talisman that had been found by one of his subjects.", 5+ 7); + line(player, "I agreed to take it to the Wizards' Tower, South West of", 6+ 7); + line(player, "Lumbridge for further examination by the wizards.", 7+ 7); + line(player, BLUE + "I need to find the " + RED + "Head Wizard " + BLUE + "and give him the " + RED + "Talisman", 8+ 7); + } + if (getStage(player) == 20) { + line(player, "I spoke to Duke Horacio and he showed me a strange", 4+ 7); + line(player, "talisman that had been found by one of his subjects.", 5+ 7); + line(player, "I agreed to take it to the Wizards' Tower, South West of", 6+ 7); + line(player, "Lumbridge for further examination by the wizards.", 7+ 7); + line(player, "I gave the Talisman to the Wizard but I didn't want to help", 8+ 7); + line(player, "him in his research right now.", 9+ 7); + line(player, BLUE + "I should talk to " + RED + "Sedridor " + BLUE + "again to continue this quest.", 10+ 7); + } + if (getStage(player) == 30) { + line(player, "I spoke to Duke Horacio and he showed me a strange", 4+ 7); + line(player, "talisman that had been found by one of his subjects.", 5+ 7); + line(player, "I agreed to take it to the Wizards' Tower, South West of", 6+ 7); + line(player, "Lumbridge for further examination by the wizards.", 7+ 7); + line(player, "I gave the Talisman to the Head of the Tower and", 8+ 7); + line(player, "agreed to help him with his research into rune stones.", 9+ 7); + line(player, BLUE + "I should take this " + RED + "Research Package " + BLUE + "to " + RED + "Aubury " + BLUE + "in " + RED + "Varrock", 10+ 7); + } + if (getStage(player) == 40) { + line(player, "I spoke to Duke Horacio and he showed me a strange", 4+ 7); + line(player, "talisman that had been found by one of his subjects.", 5+ 7); + line(player, "I agreed to take it to the Wizards' Tower, South West of", 6+ 7); + line(player, "Lumbridge for further examination by the wizards.", 7+ 7); + line(player, "I gave the Talisman to the Head of the Tower and", 8+ 7); + line(player, "agreed to help him with his research into rune stones.", 9+ 7); + line(player, "I took the research package to Varrock and delivered it.", 10+ 7); + line(player, BLUE + "I should speak to " + RED + "Aubury " + BLUE + "again when he has finished", 11+ 7); + line(player, BLUE + "examining the " + RED + "research package " + BLUE + " I have delivered to him.", 12+ 7); + } + if (getStage(player) == 50) { + line(player, "I spoke to Duke Horacio and he showed me a strange", 4+ 7); + line(player, "talisman that had been found by one of his subjects.", 5+ 7); + line(player, "I agreed to take it to the Wizards' Tower, South West of", 6+ 7); + line(player, "Lumbridge for further examination by the wizards.", 7+ 7); + line(player, "I gave the Talisman to the Head of the Tower and", 8+ 7); + line(player, "agreed to help him with his research into rune stones.", 9+ 7); + line(player, "I took the research package to Varrock and delivered it.", 10+ 7); + line(player, "Aubury was interested in the research package and gave", 11+ 7); + line(player, "me his own research notes to deliver to Sedridor.", 12+ 7); + line(player, BLUE + "I should take the " + RED + "notes " + BLUE + "to " + RED + "Sedridor " + BLUE + "and see what he says", 13+ 7); + } + if (stage == 100) { + line(player, "I spoke to Duke Horacio and he showed me a strange", 4+ 7); + line(player, "talisman that had been found by one of his subjects.", 5+ 7); + line(player, "I agreed to take it to the Wizards' Tower, South West of", 6+ 7); + line(player, "Lumbridge for further examination by the wizards.", 7+ 7); + line(player, "I gave the Talisman to the Head of the Tower and", 8+ 7); + line(player, "agreed to help him with his research into rune stones.", 9+ 7); + line(player, "I took the research package to Varrock and delivered it.", 10+ 7); + line(player, "Aubury was interested in the research package and gave", 11+ 7); + line(player, "me his own research notes to deliver to Sedridor.", 12+ 7); + line(player, "I brought Sedridor the research notes that Aubury had", 13+ 7); + line(player, "compiled so that he could compare their research. They", 14+ 7); + line(player, "They discovered that it was now possible to create new rune", 15+ 7); + line(player, "stones, a skill that had been thought lost forever.", 16+ 7); + line(player, "In return for all of my help they taught me how to do this,", 17+ 7); + line(player, "and will teleport me to mine blank runes anytime.", 18+ 7); + line(player, "QUEST COMPLETE!", 20 + 7); + } + } + + @Override + public void finish(Player player) { + super.finish(player); + player.getPacketDispatch().sendString("1 Quest Point", 277, 8 + 2); + player.getPacketDispatch().sendString("Runecrafting skill", 277, 9 + 2); + player.getPacketDispatch().sendString("Air talisman", 277, 10 + 2); + player.getPacketDispatch().sendString("You have completed the Rune Mysteries Quest!", 277, 2 + 2); + player.getPacketDispatch().sendItemZoomOnInterface(1438, 240, 277, 3 + 2); + } + + @Override + public Quest newInstance(Object object) { + // TODO Auto-generated method stub + return this; + } +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/sheepshearer/SSFredTheFarmerDialogue.kt b/Server/src/main/content/region/misthalin/lumbridge/quest/sheepshearer/SSFredTheFarmerDialogue.kt new file mode 100644 index 0000000..12a1af3 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/sheepshearer/SSFredTheFarmerDialogue.kt @@ -0,0 +1,183 @@ +package content.region.misthalin.lumbridge.quest.sheepshearer + +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.Items +import content.data.Quests + +class SSFredTheFarmerDialogue(val questStage: Int) : DialogueFile() { + companion object { + const val STAGE_BEGIN_QUEST = 1000 + const val STAGE_PENGUIN_SHEEP_SHEARED = 3000 + const val STAGE_CANT_SPIN_WOOL = 20000 + const val STAGE_CAN_SPIN_WOOL = 20100 + const val STAGE_DELIVER_BALLS_OF_WOOL = 30000 + const val STAGE_FINISH_QUEST = 30301 + } + + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + START_DIALOGUE -> if (questStage == 10) { + if (getAttribute(player!!, SheepShearer.ATTR_IS_PENGUIN_SHEEP_SHEARED, false)) { + npc(FacialExpression.ANGRY, "What are you doing on my land?").also { stage = STAGE_PENGUIN_SHEEP_SHEARED } + } else { + npc(FacialExpression.NEUTRAL, "How are you doing getting those balls of wool?").also { stage = STAGE_DELIVER_BALLS_OF_WOOL } + } + } else if (questStage == 90) { + // Player delivered all balls of wool but exited the dialogue before the quest was recorded as complete + npc(FacialExpression.SAD, "I guess I'd better pay you then.").also { stage = STAGE_FINISH_QUEST } + } else { + npc(FacialExpression.NEUTRAL, "You're after a quest, you say? Actually I could do with", "a bit of help.").also { stage = STAGE_BEGIN_QUEST } + } + + STAGE_BEGIN_QUEST -> npc(FacialExpression.NEUTRAL, "My sheep are getting mighty woolly. I'd be much", "obliged if you could shear them. And while you're at it", "spin the wool for me too.").also { stage++ } + 1001 -> npc(FacialExpression.HAPPY, "Yes, that's it. Bring me 20 balls of wool. And I'm sure", "I could sort out some sort of payment. Of course,", "there's the small matter of The Thing.").also { stage++ } + 1002 -> options("Yes okay. I can do that.", "That doesn't sound a very exciting quest.", "What do you mean, The Thing?").also { stage++ } + 1003 -> when (buttonID) { + 1 -> player(FacialExpression.HAPPY, "Yes okay. I can do that.").also { stage = 2000 } + 2 -> player(FacialExpression.HALF_GUILTY, "That doesn't sound a very exciting quest.").also { stage = 1100 } + 3 -> player(FacialExpression.ASKING, "What do you mean, The Thing?").also { stage = 1200 } + } + + // TODO: There might be more dialogue here + 1100 -> npc(FacialExpression.HALF_GUILTY, "Well what do you expect if you ask a farmer for a", "quest?").also { stage = END_DIALOGUE } + + 1200 -> npc(FacialExpression.SUSPICIOUS, "Well now, no one has ever seen The Thing. That's", "why we call it The Thing, 'cos we don't know what it is.").also { stage++ } + 1201 -> npc(FacialExpression.SCARED, "Some say it's a black hearted shapeshifter, hungering for", "the souls of hard working decent folk like me. Others", "say it's just a sheep.").also { stage++ } + 1202 -> npc(FacialExpression.ANGRY, "Well I don't have all day to stand around and gossip.", "Are you going to shear my sheep or what!").also { stage++ } + 1203 -> options("Yes okay. I can do that.", "Erm I'm a bit worried about this Thing.").also { stage++ } + 1204 -> when (buttonID) { + 1 -> player(FacialExpression.HAPPY, "Yes okay. I can do that.").also { stage = 2000 } + 2 -> player(FacialExpression.HALF_GUILTY, "Erm I'm a bit worried about this Thing.").also { stage = 1300 } + } + + 1300 -> npc(FacialExpression.HALF_GUILTY, "I'm sure it's nothing to worry about. Just because", "my last shearer was seen bolting out of the field", "screaming for his life doesn't mean anything.").also { stage++ } + 1301 -> player(FacialExpression.HALF_GUILTY, "I'm not convinced.").also { stage = END_DIALOGUE } + + 2000 -> { + // NOTE: In a July 2009 video, this only happens when the dialogue ends + startQuest(player!!, Quests.SHEEP_SHEARER) + npc(FacialExpression.NEUTRAL, "Good! Now one more thing, do you actually know how", "to shear a sheep?").also { stage++ } + } + 2001 -> options("Of course!", "Err. No, I don't know actually.").also { stage++ } + 2002 -> when (buttonID) { + 1 -> player(FacialExpression.HAPPY, "Of course!").also { stage = 2100 } + 2 -> player(FacialExpression.NEUTRAL, "Err. No, I don't know actually.").also { stage = 2200 } + } + + 2100 -> npc(FacialExpression.NEUTRAL, "And you know how to spin wool into balls?").also { stage++ } + 2101 -> options("I'm something of an expert actually!", "I don't know how to spin wool, sorry.").also { stage++ } + 2102 -> when (buttonID) { + 1 -> player(FacialExpression.HAPPY, "I'm something of an expert actually!").also { stage = STAGE_CAN_SPIN_WOOL } + 2 -> player(FacialExpression.NEUTRAL, "I don't know how to spin wool, sorry.").also { stage = STAGE_CANT_SPIN_WOOL } + } + + 2200 -> { + if (inInventory(player!!, Items.SHEARS_1735)) { + npc(FacialExpression.HAPPY, "Well, you're halfway there already! You have a set of", "shears in your inventory. Just use those on a Sheep to", "shear it.").also { stage = 2300 } + } else { + npc(FacialExpression.NEUTRAL, "Well, first things first, you need a pair of shears, there's", "a pair in the house on the table.").also { stage = 2400 } + } + } + + 2300 -> player(FacialExpression.NEUTRAL, "That's all I have to do?").also { stage++ } + 2301 -> npc(FacialExpression.NEUTRAL, "Well once you've collected some wool you'll need to spin", "it into balls.").also { stage++ } + 2302 -> npc(FacialExpression.ASKING, "Do you know how to spin wool?").also { stage++ } + 2303 -> options("I don't know how to spin wool, sorry.", "I'm something of an expert actually!").also { stage++ } + 2304 -> when (buttonID) { + 1 -> player(FacialExpression.NEUTRAL, "I don't know how to spin wool, sorry.").also { stage = STAGE_CANT_SPIN_WOOL } + 2 -> player(FacialExpression.HAPPY, "I'm something of an expert actually!").also { stage = STAGE_CAN_SPIN_WOOL } + } + + 2400 -> npc(FacialExpression.NEUTRAL, "Or you could buy your own pair from the General", "Store in Lumbridge.").also { stage++ } + 2401 -> npc(FacialExpression.NEUTRAL, "To get to Lumbridge travel east on the road outside.").also { stage++ } + // TODO: Add "General Stores are marked on the map by this symbol." message with the general store map icon here + 2402 -> npc(FacialExpression.NEUTRAL, "Once you get some shears use them on the sheep in", "my field.").also { stage++ } + 2403 -> player(FacialExpression.HAPPY, "Sounds easy!").also { stage++ } + 2404 -> npc(FacialExpression.LAUGH, "That's what they all say!").also { stage++ } + 2405 -> npc(FacialExpression.NEUTRAL, "Some of the sheep don't like it and will run away from", "you. Persistence is the key.").also { stage++ } + 2406 -> npc(FacialExpression.NEUTRAL, "Once you've collected some wool you can spin it into", "balls.").also { stage++ } + 2407 -> npc(FacialExpression.NEUTRAL, "Do you know how to spin wool?").also { stage++ } + 2408 -> options("I don't know how to spin wool, sorry.", "I'm something of an expert actually!").also { stage++ } + 2409 -> when (buttonID) { + 1 -> player(FacialExpression.NEUTRAL, "I don't know how to spin wool, sorry.").also { stage = STAGE_CANT_SPIN_WOOL } + 2 -> player(FacialExpression.HAPPY, "I'm something of an expert actually!").also { stage = STAGE_CAN_SPIN_WOOL } + } + + STAGE_PENGUIN_SHEEP_SHEARED -> options("I'm back!", "Fred! Fred! I've seen The Thing!").also { stage++ } + 3001 -> when (buttonID) { + 1 -> player(FacialExpression.HAPPY, "I'm back!").also { stage = 3100 } + 2 -> player(FacialExpression.AMAZED, "Fred! Fred! I've seen The Thing!").also { stage = 3200 } + } + + 3100 -> npc(FacialExpression.NEUTRAL, "How are you doing getting those balls of wool?").also { stage = STAGE_DELIVER_BALLS_OF_WOOL } + + 3200 -> npc(FacialExpression.SCARED, "You ... you actually saw it?").also { stage++ } + 3201 -> npc(FacialExpression.SCARED, "Run for the hills! ${player!!.username} grab as many chickens as", "you can! We have to ...").also { stage++ } + 3202 -> player(FacialExpression.AMAZED, "Fred!").also { stage++ } + 3203 -> npc(FacialExpression.SCARED, "... flee! Oh, woe is me! The shapeshifter is coming!", "We're all ...").also { stage++ } + 3204 -> player(FacialExpression.ANGRY, "FRED!").also { stage++ } + 3205 -> npc(FacialExpression.HALF_CRYING, "... doomed. What!").also { stage++ } + 3206 -> player(FacialExpression.NEUTRAL, "It's not a shapeshifter or any other kind of monster!").also { stage++ } + 3207 -> npc(FacialExpression.ASKING, "Well then what is it boy?").also { stage++ } + 3208 -> player(FacialExpression.THINKING, "Well ... it's just two Penguins; Penguins disguised as a", "sheep.").also { stage++ } + 3209 -> npc(FacialExpression.THINKING, "...").also { stage++ } + 3210 -> npc(FacialExpression.AMAZED, "Have you been out in the sun too long?").also { stage = END_DIALOGUE } + + // Common dialogue - doesn't know how to spin wool + STAGE_CANT_SPIN_WOOL -> npc(FacialExpression.NEUTRAL, "Don't worry, it's quite simple!").also { stage++ } + 20001 -> npc(FacialExpression.NEUTRAL, "The nearest Spinning Wheel can be found on the first", "floor of Lumbridge Castle.").also { stage++ } + 20002 -> npc(FacialExpression.NEUTRAL, "To get to Lumbridge Castle just follow the road east.").also { stage++ } + // TODO: Add "This icon denotes a Spinning Wheel on the world map." message with the spinning wheel map icon here + 20003 -> player(FacialExpression.HAPPY, "Thank you!").also { stage = END_DIALOGUE } + + // Common dialogue - knows how to spin wool + STAGE_CAN_SPIN_WOOL -> npc(FacialExpression.NEUTRAL, "Well you can stop grinning and get to work then.").also { stage++ } + 20101 -> npc(FacialExpression.ANGRY, "I'm not paying you by the hour!").also { stage = END_DIALOGUE } + + // Common dialogue - deliver balls of wool + STAGE_DELIVER_BALLS_OF_WOOL -> { + if (inInventory(player!!, Items.BALL_OF_WOOL_1759)) { + player(FacialExpression.HAPPY, "I have some.").also { stage = 30100 } + } else { + player(FacialExpression.ASKING, "How many more do I need to give you?").also { stage = 31000 } + } + } + + 30100 -> npc(FacialExpression.NEUTRAL, "Give 'em here then.").also { stage++ } + 30101 -> { + val ballsOfWoolDelivered = SheepShearer.deliverBallsOfWool(player!!) + if (SheepShearer.getBallsOfWoolRequired(player!!) == 0) { + setQuestStage(player!!, Quests.SHEEP_SHEARER, 90) + player(FacialExpression.HAPPY, "That's the last of them.").also { stage = 30300 } + } else { + sendDialogue(player!!, "You give Fred $ballsOfWoolDelivered balls of wool").also { stage = 30200 } + } + } + + 30200 -> player(FacialExpression.NEUTRAL, "That's all I've got so far.").also { stage++ } + 30201 -> npc(FacialExpression.NEUTRAL, "I need ${SheepShearer.getBallsOfWoolRequired(player!!)} more before I can pay you.").also { stage++ } + 30202 -> player(FacialExpression.NEUTRAL, "Ok I'll work on it.").also { stage = END_DIALOGUE } + + 30300 -> npc(FacialExpression.SAD, "I guess I'd better pay you then.").also { stage++ } + STAGE_FINISH_QUEST -> finishQuest(player!!, Quests.SHEEP_SHEARER).also { stage = END_DIALOGUE } + + 31000 -> npc(FacialExpression.NEUTRAL, "You need to collect ${SheepShearer.getBallsOfWoolRequired(player!!)} more balls of wool.").also { stage++ } + 31001 -> { + if (inInventory(player!!, Items.WOOL_1737)) { + player(FacialExpression.NEUTRAL, "Well I've got some wool. I've not managed to make it", "into a ball though.").also { stage = 31100 } + } else { + player(FacialExpression.HALF_GUILTY, "I haven't got any at the moment.").also { stage = 31200 } + } + } + + 31100 -> npc(FacialExpression.NEUTRAL, "Well go find a spinning wheel then. You can find one", "on the first floor of Lumbridge Castle, just walk east on", "the road outside my house and you'll find Lumbridge.").also { stage = END_DIALOGUE } + + // TODO: There might be more dialogue here + 31200 -> npc(FacialExpression.HALF_GUILTY, "Ah well at least you haven't been eaten.").also { stage = END_DIALOGUE } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/sheepshearer/SheepShearer.kt b/Server/src/main/content/region/misthalin/lumbridge/quest/sheepshearer/SheepShearer.kt new file mode 100644 index 0000000..6340413 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/sheepshearer/SheepShearer.kt @@ -0,0 +1,122 @@ +package content.region.misthalin.lumbridge.quest.sheepshearer + +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.plugin.Initializable +import org.rs09.consts.Items +import kotlin.math.min +import content.data.Quests + +@Initializable +class SheepShearer : Quest(Quests.SHEEP_SHEARER, 28, 27, 1, 179, 0, 20, 21) { + companion object { + val ATTR_NUM_BALLS_OF_WOOL_DELIVERED = "/save:sheep-shearer:num-balls-of-wool-delivered" + val ATTR_IS_PENGUIN_SHEEP_SHEARED = "/save:sheep-shearer:is-penguin-sheep-sheared" + + /** + * Gets the number of balls of wool that have been delivered to Fred the Farmer. + * @param player the player to check + * @return the number of balls of wool that have been delivered + */ + fun getBallsOfWoolDelivered(player: Player): Int { + return getAttribute(player, ATTR_NUM_BALLS_OF_WOOL_DELIVERED, 0) + } + + /** + * Gets the number of balls of wool remaining to be delivered to Fred the Farmer. + * @param player the player to check + * @return the number of balls of wool remaining to be delivered + */ + fun getBallsOfWoolRequired(player: Player): Int { + return 20 - getBallsOfWoolDelivered(player) + } + + /** + * Gets the number of balls of wool that can be removed from the player's inventory, + * up to the amount still required by Fred the Farmer. + * @param player the player whose inventory should be checked + * @return the number of balls of wool that can be removed from the player's inventory + * and delivered to Fred the Farmer + */ + fun getBallsOfWoolToRemove(player: Player): Int { + return min(getBallsOfWoolRequired(player), amountInInventory(player, Items.BALL_OF_WOOL_1759)) + } + + /** + * Gets the number of balls of wool that still need to be collected by the player. + * + * This takes into account the number of balls of wool already delivered to Fred the + * Farmer, and the number of balls of wool in the player's inventory. + * @param player the player to check + * @return the number of balls of wool that still needs to be collected by the player + */ + fun getBallsOfWoolToCollect(player: Player): Int { + return getBallsOfWoolRequired(player) - getBallsOfWoolToRemove(player) + } + + /** + * Delivers all balls of wool in the player's inventory, up to the amount still required + * by Fred the Farmer. + * @param player the player delivering balls of wool to Fred the Farmer + * @return the number of balls of wool removed from the player's inventory and delivered to Fred the Farmer + */ + fun deliverBallsOfWool(player: Player): Int { + val removeAmount = getBallsOfWoolToRemove(player) + if (removeItem(player, Item(Items.BALL_OF_WOOL_1759, removeAmount))) { + setAttribute(player, ATTR_NUM_BALLS_OF_WOOL_DELIVERED, getBallsOfWoolDelivered(player) + removeAmount) + return removeAmount + } + return 0 + } + } + + override fun newInstance(`object`: Any?): Quest { + return this + } + + override fun drawJournal(player: Player, stage: Int) { + super.drawJournal(player, stage) + + var ln = 11 + + if (stage == 0) { + line(player, "I can start this quest by speaking to !!Farmer Fred?? at his", ln++) + line(player, "!!farm?? just a little way !!North West of Lumbridge??", ln++) + } else if (stage == 10 || stage == 90) { + line(player, "I asked Farmer Fred, near Lumbridge, for a quest. Fred", ln++, true) + line(player, "said he'd pay me for shearing his sheep for him!", ln++, true) + ln++ + + val ballsOfWoolToCollect = getBallsOfWoolToCollect(player) + if (ballsOfWoolToCollect == 0) { + line(player, "I have enough !!balls of wool?? to give !!Fred?? and get my !!reward??", ln++) + line(player, "!!money!??", ln++) + } else { + line(player, "I need to collect $ballsOfWoolToCollect more !!balls of wool.??", ln++) + } + } else if (stage == 100) { + line(player, "I brought Farmer Fred 20 balls of wool, and he paid me for", ln++, true) + line(player, "it!", ln++, true) + ln++ + line(player, "QUEST COMPLETE!", ln++) + } + } + + override fun finish(player: Player?) { + super.finish(player) + player ?: return + + var ln = 10 + player.packetDispatch.sendItemZoomOnInterface(Items.SHEARS_1735, 240, 277, 5) + drawReward(player, "1 Quest Point", ln++) + drawReward(player, "150 Crafting XP", ln++) + drawReward(player, "60 coins", ln++) + rewardXP(player, Skills.CRAFTING, 150.0) + addItemOrDrop(player, Items.COINS_995, 60) + removeAttribute(player, ATTR_NUM_BALLS_OF_WOOL_DELIVERED) + removeAttribute(player, ATTR_IS_PENGUIN_SHEEP_SHEARED) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/tearsofguthix/JunaDialogue.kt b/Server/src/main/content/region/misthalin/lumbridge/quest/tearsofguthix/JunaDialogue.kt new file mode 100644 index 0000000..b5a2a16 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/tearsofguthix/JunaDialogue.kt @@ -0,0 +1,204 @@ +package content.region.misthalin.lumbridge.quest.tearsofguthix + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.FacialExpression +import core.game.interaction.InteractionListener +import core.game.node.entity.npc.NPC +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +/** + * Anim 2056 - Juna puts head into itself + * Anim 2055 - Juna lifts tail + */ +class JunaDialogue : InteractionListener { + override fun defineListeners() { + // Juna is a scenery. + on(Scenery.JUNA_31302, SCENERY, "talk-to") { player, _ -> + openDialogue(player, JunaDialogueFile(), NPC(NPCs.JUNA_2023)) + return@on true + } + // This is quest varbit 451 controlled. When it is set to 2, JUNA changes in ID + on(Scenery.JUNA_31303, SCENERY, "talk-to") { player, node -> + openDialogue(player, JunaDialogueFile(), NPC(NPCs.JUNA_2023)) + return@on true + } + } +} + +class JunaDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + + b.onQuestStages(Quests.TEARS_OF_GUTHIX, 0) + .branch { player -> if(TearsOfGuthix.hasRequirements(player)) { 1 } else { 0 } } + .let { branch -> + branch.onValue(0) + // Inauthentic, but absolutely no source on this... + .npcl(FacialExpression.OLD_NORMAL, "You are not strong enough of an adventurer to partake this quest. Come back when you are stronger.") + .linel("You do not meet the quest requirements for Tears of Guthix.") + .end() + return@let branch // Return DialogueBranchBuilder instead of DialogueBuilder to forward the success branch. + }.onValue(1) + .npcl(FacialExpression.OLD_NORMAL, "Tell me... a story...") + .playerl(FacialExpression.THINKING, "A story?") + .npcl(FacialExpression.OLD_NORMAL, "I have been waiting here three thousand years, guarding the Tears of Guthix. I serve my master faithfully, but I am bored.") + .npcl(FacialExpression.OLD_NORMAL, "An adventurer such as yourself must have many tales to tell. If you can entertain me, I will let you into the cave for a time.") + .npcl(FacialExpression.OLD_NORMAL, "The more I enjoy your story, the more time I will give you in the cave.") + .npcl(FacialExpression.OLD_NORMAL, "Then you can drink of the power of balance, which will make you stronger in whatever area you are weakest.") + + .let { builder -> + val returnJoin = b.placeholder() + returnJoin.builder() + .options() + .let { optionBuilder -> + + optionBuilder.option_playerl("Okay...") + .linel("You tell Juna some stories of your adventures.") + // Yes I know. + .playerl("Blah blah blah something about recent quest I did that I'm forced to talk about, but looks like you want me to shut up.") + .npcl(FacialExpression.OLD_NORMAL,"Blah blah blah that's so cool, I'm totally interested in what you are saying and am totally not falling asleep at this point.") + // ^ I'm not going to type out 120 fucking quest dialogue for shit you wouldn't care reading. + .npcl(FacialExpression.OLD_NORMAL,"Your stories have entertained me. I will let you into the cave for a short time.") + .npcl(FacialExpression.OLD_NORMAL,"But first you will need to make a bowl in which to collect the tears.") + // The camera pans south to the part of the cave containing guthix-infused rocks. + .npcl(FacialExpression.OLD_NORMAL,"There is a cave on the south side of the chasm that is similarly infused with the power of Guthix. The stone in that cave is the only substance that can catch the Tears of Guthix.") + .npcl(FacialExpression.OLD_NORMAL,"Mine some stone from that cave, make it into a bowl, and bring it to me, and then I will let you catch the Tears.") + .endWith { _, player -> + if(getQuestStage(player, Quests.TEARS_OF_GUTHIX) == 0) { + setQuestStage(player, Quests.TEARS_OF_GUTHIX, 1) + } + } + + optionBuilder.option_playerl("Not now.") + .end() + + optionBuilder.option_playerl("What are the Tears of Guthix?") + .npcl(FacialExpression.OLD_NORMAL, "The Third Age of the world was a time of great conflict, of destruction never seen before or since, when all the gods save Guthix warred for control.") + .npcl(FacialExpression.OLD_NORMAL, "The colossal Wyrms, of whom today's dragons are a pale reflection, turned all the sky to fire, while on the ground armies of foot soldiers, goblins and trolls and humans, filled the valleys and plains with blood.") + .npcl(FacialExpression.OLD_NORMAL, "In time the noise of the conflict woke Guthix from His deep slumber, and He rose and stood in the centre of the battlefield so that the splendour of His wrath filled the world, and He called for the conflict to cease!") + .npcl(FacialExpression.OLD_NORMAL, "Silence fell, for the gods knew that none could challenge the power of the mighty Guthix -- for His power is that of nature itself, to which all other things are subject, in the end.") + .npcl(FacialExpression.OLD_NORMAL, "Guthix reclaimed that which had been stolen from Him, and went back underground to return to His sleep and continue to draw the world's power into Himself.") + .npcl(FacialExpression.OLD_NORMAL, "But on His way into the depths of the earth He sat and rested in this cave; and, thinking of the battle-scarred desert that now stretched from one side of His world to the other, He wept.") + .npcl(FacialExpression.OLD_NORMAL, "And so great was His sorrow, and so great was His life- giving power, that the rocks themselves began to weep with Him.") + .npcl(FacialExpression.OLD_NORMAL, "Later, Guthix noticed that the rocks continued to weep, and that their tears were infused with a small part of His power.") + .npcl(FacialExpression.OLD_NORMAL, "So He set me, His servant, to guard the cave, and He entrusted to me the task of judging who was and was not worthy to access the tears.") + .npcl(FacialExpression.OLD_NORMAL, "Tell me... a story...") + .goto(returnJoin) + } + return@let builder.goto(returnJoin) + } + + + b.onQuestStages(Quests.TEARS_OF_GUTHIX, 1) + .npc(FacialExpression.OLD_NORMAL, "Before you can collect the Tears of Guthix you must", "make a bowl out of the stone in the cave on the south", "of the chasm.") + .branch { player -> if(inInventory(player, Items.STONE_BOWL_4704)) { 1 } else { 0 } } + .let{ branch -> + branch.onValue(0) + .options() + .let { optionBuilder -> + optionBuilder.option_playerl("But I don't know how to reach the cave!") + .npcl(FacialExpression.OLD_NORMAL, "I will tell you the story of the light-creatures.") + .npcl(FacialExpression.OLD_NORMAL, "Myriad and beautiful were the creatures and civilizations of the early ages of the world. Gielinor was a work of art, shaped lovingly over the millennia by the creative mind of Guthix.") + .npcl(FacialExpression.OLD_NORMAL, "Only the sturdiest races survived the Godwars, and even then only by abandoning their high culture and gearing their societies towards war. Of the more delicate races there is now no trace, and almost no memory.") + .npcl(FacialExpression.OLD_NORMAL, "One such race had bodies as fragile as snowflakes, yet they built crystal cities that stood for a thousand years.") + .npcl(FacialExpression.OLD_NORMAL, "The wind would whisper through the spires and fill them with sweet harmonies, and the rising sun would shine through the precious gems that studded the towers and create inter plays of light as if rainbows were dancing.") + .npcl(FacialExpression.OLD_NORMAL, "Indeed, so marvellous was this light-show at its height that the patterns of light themselves became alive, and great flocks of luminous creatures rode along the gem- cast beams, each drawn to its own colour.") + .npcl(FacialExpression.OLD_NORMAL, "The creatures you see floating in this chasm are the last sorry remnants of that age. I do not know how they made their way here and survived to this time, but I am grateful for their company.") + .end() + + optionBuilder.option_playerl("What are the Tears of Guthix?") + .npcl(FacialExpression.OLD_NORMAL, "The Third Age of the world was a time of great conflict, of destruction never seen before or since, when all the gods save Guthix warred for control.") + .npcl(FacialExpression.OLD_NORMAL, "The colossal Wyrms, of whom today's dragons are a pale reflection, turned all the sky to fire, while on the ground armies of foot soldiers, goblins and trolls and humans, filled the valleys and plains with blood.") + .npcl(FacialExpression.OLD_NORMAL, "In time the noise of the conflict woke Guthix from His deep slumber, and He rose and stood in the centre of the battlefield so that the splendour of His wrath filled the world, and He called for the conflict to cease!") + .npcl(FacialExpression.OLD_NORMAL, "Silence fell, for the gods knew that none could challenge the power of the mighty Guthix -- for His power is that of nature itself, to which all other things are subject, in the end.") + .npcl(FacialExpression.OLD_NORMAL, "Guthix reclaimed that which had been stolen from Him, and went back underground to return to His sleep and continue to draw the world's power into Himself.") + .npcl(FacialExpression.OLD_NORMAL, "But on His way into the depths of the earth He sat and rested in this cave; and, thinking of the battle-scarred desert that now stretched from one side of His world to the other, He wept.") + .npcl(FacialExpression.OLD_NORMAL, "And so great was His sorrow, and so great was His life- giving power, that the rocks themselves began to weep with Him.") + .npcl(FacialExpression.OLD_NORMAL, "Later, Guthix noticed that the rocks continued to weep, and that their tears were infused with a small part of His power.") + .npcl(FacialExpression.OLD_NORMAL, "So He set me, His servant, to guard the cave, and He entrusted to me the task of judging who was and was not worthy to access the tears.") + .end() + + optionBuilder.option_playerl("Not now.") + .end() + } + return@let branch // Return DialogueBranchBuilder instead of DialogueBuilder to forward the success branch. + }.onValue(1) + .playerl("I have a bowl.") + .npcl(FacialExpression.OLD_NORMAL, "I will keep your bowl for you, so that you may collect the tears many times in the future.") + .npcl(FacialExpression.OLD_NORMAL, "Now... tell me another story, and I will let you collect the tears for the first time.") + .endWith { _, player -> + if (removeItem(player, Items.STONE_BOWL_4704)) { + finishQuest(player, Quests.TEARS_OF_GUTHIX) + } + } + + b.onQuestStages(Quests.TEARS_OF_GUTHIX, 100) + .npcl(FacialExpression.OLD_NORMAL, "Tell me... a story...") + .let { builder -> + val returnJoin = b.placeholder() + returnJoin.builder() + .options() + .let { optionBuilder -> + optionBuilder.option_playerl("Okay...") + .linel("You tell Juna some stories of your adventures.") + // Yes I know. + .playerl("Blah blah blah something about recent quest I did that I'm forced to talk about, but looks like you want me to shut up.") + .npcl(FacialExpression.OLD_NORMAL,"Blah blah blah that's so cool, I'm totally interested in what you are saying and am totally not falling asleep at this point.") + // ^ I'm not going to type out 120 fucking quest dialogue for shit you wouldn't care reading. + .branch { player -> + if(TearsOfGuthix.daysLeft(player) > 0 && TearsOfGuthix.xpLeft(player) > 0 && TearsOfGuthix.questPointsLeft(player) > 0) { + 3 + } else if(TearsOfGuthix.xpLeft(player) > 0 && TearsOfGuthix.questPointsLeft(player) > 0) { + 2 + } else if(TearsOfGuthix.daysLeft(player) > 0) { + 1 + } else { + 0 // Success branch + } + } + .let{ branch -> + // https://www.youtube.com/watch?v=X3M9CiS_BeU if not enough time has passed. + branch.onValue(3) + .manualStage { df, player, _, _ -> npcl(FacialExpression.OLD_NORMAL,"Your stories have entertained me. But I will not permit any adventurer to access the tears more than once a week. Come back in " + TearsOfGuthix.daysLeft(player).toString() + " days.") } + .npcl(FacialExpression.OLD_NORMAL,"You should use that time to have more adventures! You may not re-enter the cave until you have more stories to tell.") + .manualStage { df, player, _, _ -> sendDialogue(player, "You cannot enter the cave again until you have gained either one quest point or " + TearsOfGuthix.xpLeft(player) + " total XP.") } + .end() + + branch.onValue(2) + .npc(FacialExpression.OLD_NORMAL,"Your story has entertained me. But it is a poor sort", "of adventurer who only tells stories of the past and", "does not find new stories to tell. I will not let you", "into the cave again until you have had more adventures.") + .manualStage { df, player, _, _ -> sendDialogue(player, "You cannot enter the cave again until you have gained either one quest point or " + TearsOfGuthix.xpLeft(player) + " total XP.") } + .end() + + branch.onValue(1) + .manualStage { df, player, _, _ -> npcl(FacialExpression.OLD_NORMAL,"Your stories have entertained me. But I will not permit any adventurer to access the tears more than once a week. Come back in " + TearsOfGuthix.daysLeft(player).toString() + " days.") } + .end() + + return@let branch + }.onValue(0) + .npcl(FacialExpression.OLD_NORMAL,"Your stories have entertained me. I will let you into the cave for a short time.") + .branch { player -> if(TearsOfGuthix.isHandsFree(player)) { 1 } else { 0 } } + .let{ branch -> + // https://www.youtube.com/watch?v=J76OGo-hHlA your hands must be free. + branch.onValue(0) + .npc(FacialExpression.OLD_NORMAL,"But you must have both hands free to carry the bowl.", "Speak to me again when your hands are free.") + .end() + return@let branch + }.onValue(1) + // https://www.youtube.com/watch?v=Mj3pW-Brv9c + .npc(FacialExpression.OLD_NORMAL,"Collect as much as you can from the blue streams. If", "you let in water from the green streams, it will take", "away from the blue. For Guthix is god of balance, and", "balance lies in the juxtaposition of opposites.") + .endWith { _, player -> + TearsOfGuthixMinigame.startGame(player) + } + + optionBuilder.option_playerl("Not now.") + .end() + } + return@let builder.goto(returnJoin) + } + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/tearsofguthix/LightCreatureBehavior.kt b/Server/src/main/content/region/misthalin/lumbridge/quest/tearsofguthix/LightCreatureBehavior.kt new file mode 100644 index 0000000..daa8c68 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/tearsofguthix/LightCreatureBehavior.kt @@ -0,0 +1,129 @@ +package content.region.misthalin.lumbridge.quest.tearsofguthix + +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.world.GameWorld.ticks +import core.game.world.map.Location +import core.game.world.map.path.Pathfinder +import core.tools.RandomFunction +import org.rs09.consts.NPCs + +class LightCreatureBehavior : NPCBehavior(NPCs.LIGHT_CREATURE_2021) { + + companion object { + fun moveLightCreature(self: NPC, location: Location) { + self.setNextWalk() + Pathfinder.find(self, location, true, Pathfinder.PROJECTILE).walk(self) + } + + } + + override fun tick(self: NPC): Boolean { + if (!self.locks.isMovementLocked) { + self.isWalks = true + self.walkRadius = 20 + if (self.isWalks && !self.pulseManager.hasPulseRunning() && self.nextWalk < ticks) { + self.setNextWalk() + val l: Location = self.location.transform(-5 + RandomFunction.random(self.walkRadius), -5 + RandomFunction.random(self.walkRadius), 0) + if (self.canMove(l)) { + Pathfinder.find(self, l, true, Pathfinder.PROJECTILE).walk(self) + } + } + } + return true + } + +} + +/* + + /** + * Handles the sapphire lantern on a light creature. + * @author Vexia + * + */ + public class LightCreatureHandler extends UseWithHandler { + + /** + * Constructs the {@code LightCreatureHandler} + */ + public LightCreatureHandler() { + super( 4700, 4701, 4702); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(2021, NPC_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + if (!hasRequirement(player, "While Guthix Sleeps")) + return true; + player.lock(2); + player.teleport(Location.create(2538, 5881, 0)); + return true; + } + + @Override + public Location getDestination(Player player, Node with) { + if (player.getLocation().withinDistance(with.getLocation())) { + return player.getLocation(); + } + return null; + } + + } + + + /** + * Handles the light creature npc. + * @author Vexia + * + */ + public class LightCreatureNPC extends AbstractNPC { + + /** + * Constructs the {@code LightCreatureNPC} + */ + public LightCreatureNPC() { + super(0, null); + this.setWalks(true); + this.setWalkRadius(10); + } + + /** + * Constructs the {@code LightCreatureNPC} + */ + public LightCreatureNPC(int id, Location location) { + super(id, location); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new LightCreatureNPC(id, location); + } + + @Override + public void handleTickActions() { + if (!getLocks().isMovementLocked()) { + if (isWalks() && !getPulseManager().hasPulseRunning() && nextWalk < GameWorld.getTicks()) { + setNextWalk(); + Location l = getLocation().transform(-5 + RandomFunction.random(getWalkRadius()), -5 + RandomFunction.random(getWalkRadius()), 0); + if (canMove(l)) { + Pathfinder.find(this, l, true, Pathfinder.PROJECTILE).walk(this); + } + } + } + } + + @Override + public int[] getIds() { + return new int[] {2021}; + } + + } +} + */ \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/tearsofguthix/TearsOfGuthix.kt b/Server/src/main/content/region/misthalin/lumbridge/quest/tearsofguthix/TearsOfGuthix.kt new file mode 100644 index 0000000..52a859b --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/tearsofguthix/TearsOfGuthix.kt @@ -0,0 +1,132 @@ +package content.region.misthalin.lumbridge.quest.tearsofguthix + +import content.data.Quests +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import org.rs09.consts.Items + +/** + * Tears of Guthix Quest + * + * Most of the attributes are for the minigame. + * In order to reset, setQuestStage + * + * if (VARPBIT[451] > 1) return 2; if (VARPBIT[451] == 0) return 0; return 1; }; if (arg0 == 88) + */ +@Initializable +class TearsOfGuthix : Quest(Quests.TEARS_OF_GUTHIX, 120, 119, 1, 449, 451, 0, 1, 2) { + + companion object { + const val attributePreviousDate = "/save:quest:tearsofguthix-previousdateofaccess" // The date in milliseconds in which TOG was played. + const val attributePreviousXPAmount = "/save:quest:tearsofguthix-previousxpamount" // The last snapshot of XP user had. + const val attributePreviousQuestPoints = "/save:quest:tearsofguthix-previousquestpoints" // The last snapshot of quest points user had. + + fun isHandsFree(player: Player): Boolean { + return getItemFromEquipment(player, EquipmentSlot.WEAPON) == null + && getItemFromEquipment(player, EquipmentSlot.SHIELD) == null + } + + fun daysLeft(player: Player): Int { + val currentTime = System.currentTimeMillis() + val previousTime = getAttribute(player, attributePreviousDate, 0) + + val numberOfDaysLeft = (currentTime - previousTime) / 86400000L + return 6 - numberOfDaysLeft.toInt() + } + + fun xpLeft(player: Player): Int { + val currentXP = player.skills.totalXp + val previousXP = getAttribute(player, attributePreviousXPAmount, 0) + return 100000 - (currentXP - previousXP) + } + + fun questPointsLeft(player: Player): Int { + val currentQuestPoints = getQuestPoints(player) + val previousQuestPoints = getAttribute(player, attributePreviousQuestPoints, 0) + return 1 - (currentQuestPoints - previousQuestPoints) + } + + fun hasRequirements(player: Player): Boolean { + return arrayOf( + hasLevelStat(player, Skills.FIREMAKING, 49), + hasLevelStat(player, Skills.CRAFTING, 20), + hasLevelStat(player, Skills.MINING, 20), + ).all { it } + } + } + override fun drawJournal(player: Player, stage: Int) { + super.drawJournal(player, stage) + var line = 12 + var stage = getStage(player) + + var started = getQuestStage(player, Quests.TEARS_OF_GUTHIX) > 0 + + if (!started) { + line(player, "I can start this quest by speaking to !!Juna the serpent?? who", line++, false) + line(player, "lives deep in the !!Lumbridge Swamp Caves??.", line++, false) + line(player, "I will need to have:", line++, false) + line(player, "Level 49 firemaking", line++, hasLevelStat(player, Skills.FIREMAKING, 49)) + line(player, "!!Level 20 crafting??", line++, hasLevelStat(player, Skills.CRAFTING, 20)) + line(player, "!!Level 20 mining??", line++, hasLevelStat(player, Skills.MINING, 20)) + line(player, "!!43 quest points??", line++, getQuestPoints(player) >= 55) + line(player, "!!Level 49 crafting would be an advantage??", line++, hasLevelStat(player, Skills.CRAFTING, 49)) + line(player, "!!Level 49 smithing would be an advantage??", line++, hasLevelStat(player, Skills.SMITHING, 49)) + } else if (stage < 100) { + line(player, "I met Juna the serpent in a deep chasm beneath the", line++, true) + line(player, "Lumbridge Swamp Caves.", line++, true) + line(player, "I told her a story and she said she would let me into the", line++, false) + line(player, "Tears of Guthix cave if I brought her a !!bowl?? made from the", line++, false) + line(player, "stone in !!the cave on the South side of the chasm??.", line++, false) + } else { + line(player, "I met Juna the serpent in a deep chasm beneath the", line++, true) + line(player, "Lumbridge Swamp Caves. I made a bowl out of magical", line++, true) + line(player, "stone in order to catch the Tears of Guthix.", line++, true) + line++ + line(player,"QUEST COMPLETE!", line++) + line++ + line(player, "Now Juna will let me into the cave to collect the Tears if I", line++, false) + line(player, "!!tell her stories?? of my adventures.", line++, false) + // TOG Minigame + if (daysLeft(player) > 0 && xpLeft(player) > 0 && questPointsLeft(player) > 0) { + line(player, "I will be able to collect the Tears of Guthix !!in " + daysLeft(player) + " days??, as", line++, false) + line(player, "long as I gain either !!1 Quest Point?? or !!" + xpLeft(player) + " total XP??", line++, false) + } else if (xpLeft(player) > 0 && questPointsLeft(player) > 0) { + line(player, "I will be able to collect the Tears of Guthix, as long as I", line++, false) + line(player, "gain either !!1 Quest Point?? or !!" + xpLeft(player) + " total XP??", line++, false) + } else if (daysLeft(player) > 0) { + line(player, "I will be able to collect the Tears of Guthix !!in " + daysLeft(player) + " days??.", line++, false) + } else { + line(player, "I have had enough adventures to tell Juna more stories,", line++, false) + line(player, "and a week has passed since I last collected the Tears. I", line++, false) + line(player, "can visit Juna again now.", line++, false) + } + } + } + + override fun finish(player: Player) { + var ln = 10 + super.finish(player) + player.packetDispatch.sendString("You have completed the Tears of Guthix quest!", 277, 4) + player.packetDispatch.sendItemZoomOnInterface(Items.STONE_BOWL_4704,230,277,5) + + drawReward(player, "1 quest point", ln++) + drawReward(player, "1,000 Crafting XP", ln++) + drawReward(player, "Access to the Tears of Guthix", ln++) + drawReward(player, "cave", ln++) + + rewardXP(player, Skills.CRAFTING, 1000.0) + } + + override fun reset(player: Player) { + removeAttribute(player, attributePreviousDate) + removeAttribute(player, attributePreviousXPAmount) + removeAttribute(player, attributePreviousQuestPoints) + } + + override fun newInstance(`object`: Any?): Quest { + return this + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/tearsofguthix/TearsOfGuthixListeners.kt b/Server/src/main/content/region/misthalin/lumbridge/quest/tearsofguthix/TearsOfGuthixListeners.kt new file mode 100644 index 0000000..bd7c488 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/tearsofguthix/TearsOfGuthixListeners.kt @@ -0,0 +1,143 @@ +package content.region.misthalin.lumbridge.quest.tearsofguthix + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.impl.ForceMovement +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.world.map.Direction +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.tools.END_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +class TearsOfGuthixListeners : InteractionListener { + + companion object { + fun crossTheChasm(player: Player, with: NPC) { + // Unless you have time to animate this, this fucking thing is waaay too complicated. + // THIS IS JUST AESTHETICS + // You have to do the following: + // 1 - Get the light creature to your location. + // 2 - Animate both you and the light creature to float up. + // 3 - Walk both YOU AND THE LIGHT CREATURE to the other side. + // 4 - Float both you and the light creature to the ground. + // + // 2046 - Magically float into the air + // 2047 - Magically float back to the ground + // 2048 - Keep floating in the air + + // Instead you will just get fucking thrown to that other side. + val lightCreature = with as NPC + sendMessage(player, "The light-creature is attracted to your beam and comes towards you...") + LightCreatureBehavior.moveLightCreature(lightCreature, player.location) + // Could also do player.appearance.setAnimations(Animation(913)) which is the group animation for floating. + if (player.location.y > 9516) { + forceMove(player, player.location, Location.create(3229, 9504, 2), 0, 400, null, 2048) + } else { + forceMove(player, player.location, Location.create(3228, 9527, 2), 0, 400, null, 2048) + } + } + } + + override fun defineListeners() { + // Similar to RockClimbShortcut.kt + on(Scenery.ROCKS_6673, SCENERY, "climb") { player, _ -> + if (player.location.x > 3240) { + ForceMovement.run(player, player.location, Location.create(player.location).transform(-2, 0, 0), Animation(1148), Animation(1148), Direction.WEST, 13).endAnimation = Animation.RESET + } else { + ForceMovement.run(player, player.location, Location.create(player.location).transform(2, 0, 0), Animation(1148), Animation(1148), Direction.WEST, 13).endAnimation = Animation.RESET + } + return@on true + } + // Similar to RockClimbShortcut.kt + on(Scenery.ROCKS_6672, SCENERY, "climb") { player, _ -> + if (player.location.x > 3239) { + sendMessage(player, "You could climb down here, but it is too uneven to climb up.") + } else { + ForceMovement.run(player, player.location, Location.create(player.location).transform(2, 0, 0), Animation(1148), Animation(1148), Direction.WEST, 13).endAnimation = Animation.RESET + } + return@on true + } + + // Please note: part of this is already done in craftBullseyeLantern() except for the swapping out which is here. + onUseWith(ITEM, Items.BULLSEYE_LANTERN_4548, Items.SAPPHIRE_1607) { player, used, with -> + sendMessage(player, "You swap the lantern's lens for a sapphire.") + if(removeItem(player, with) && removeItem(player, used)) { + addItemOrDrop(player, Items.SAPPHIRE_LANTERN_4701) + addItemOrDrop(player, Items.LANTERN_LENS_4542) + } + return@onUseWith true + } + onUseWith(ITEM, Items.SAPPHIRE_LANTERN_4701, Items.LANTERN_LENS_4542) { player, used, with -> + sendMessage(player, "You swap the lantern's sapphire for a lens.") + if(removeItem(player, with) && removeItem(player, used)) { + addItemOrDrop(player, Items.BULLSEYE_LANTERN_4548) + addItemOrDrop(player, Items.SAPPHIRE_1607) + } + return@onUseWith true + } + onUseWith(ITEM, Items.BULLSEYE_LANTERN_4549, Items.SAPPHIRE_1607) { player, used, with -> + sendMessage(player, "The lantern is too hot to do that while it is lit.") + return@onUseWith true + } + onUseWith(ITEM, Items.SAPPHIRE_LANTERN_4702, Items.LANTERN_LENS_4542) { player, used, with -> + sendMessage(player, "The lantern is too hot to do that while it is lit.") + return@onUseWith true + } + + // MAGIC_STONE are set in MiningNode, but I can't change the messages without screwing up + // When examining ore: sendMessage(player, "This rock contains a magical kind of stone.") + // When mining: sendMessage(player, "You manage to mine some stone.") + // If you have stone in your inventory: sendMessage(player, "You have already mined some stone. You don't need any more.") + + // Note: The construction MAGIC_STONE is MAGIC_STONE_8788 NOT MAGIC_STONE_4703 WHICH IS FOR TEARS OF GUTHIX + onUseWith(ITEM, Items.MAGIC_STONE_4703, Items.CHISEL_1755) { player, used, with -> + sendMessage(player, "You make a stone bowl.") + if(removeItem(player, used)) { + addItemOrDrop(player, Items.STONE_BOWL_4704) + } + return@onUseWith true + } + + onUseWith(NPC, Items.SAPPHIRE_LANTERN_4702, NPCs.LIGHT_CREATURE_2021) { player, used, with -> + if (hasRequirement(player, Quests.WHILE_GUTHIX_SLEEPS)) { + // Options when you have WGS - B6KHH7AQc2Q + openDialogue(player, object : DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + when(stage){ + 0 -> interpreter!!.sendOptions("Select an Option", "Across the Chasm.", "Into the Chasm.").also { stage++ } + 1 -> when(buttonID){ + 1 -> { + crossTheChasm(player, with as NPC) + end() + } + 2 -> { + // This was old. + player.lock(2) + player.teleport(Location.create(2538, 5881, 0)) + end() + } + } + } + } + }) + } else { + crossTheChasm(player, with as NPC) + } + return@onUseWith true + } + + } + + override fun defineDestinationOverrides() { + setDest(IntType.NPC, intArrayOf(NPCs.LIGHT_CREATURE_2021),"use"){ player, node -> + return@setDest player.location + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/tearsofguthix/TearsOfGuthixMinigame.kt b/Server/src/main/content/region/misthalin/lumbridge/quest/tearsofguthix/TearsOfGuthixMinigame.kt new file mode 100644 index 0000000..ab27cbd --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/tearsofguthix/TearsOfGuthixMinigame.kt @@ -0,0 +1,402 @@ +package content.region.misthalin.lumbridge.quest.tearsofguthix + +import content.data.Quests +import core.api.* +import core.game.component.Component +import core.game.event.EventHook +import core.game.event.TickEvent +import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import core.game.world.map.zone.ZoneRestriction +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Components +import org.rs09.consts.Items +import org.rs09.consts.Scenery + +/** + * // ::setvarbit 454 (varp 449 7-11) 0-10 where its just time bar length + * // ::setvarbit 455 (varp 449 12-20) X where x is number of points he gets + * + * anim 2040 - Hold bowl + * anim 2041 - Walk with ToG Bowl + * anim 2042 - Run with ToG Bowl + * anim 2043 - Fill ToG bowl + * anim 2044 - Finish filling from ToG + * anim 2045 - Drink from bowl + * + */ +class TearsOfGuthixMinigame : InteractionListener, EventHook, MapArea { + companion object { + + const val varbitTimeBar = 454 + const val varbitPoints = 455 + const val attributeTicksRemaining = "minigame:tearsofguthix-ticksremaining" + const val attributeTearsCollected = "minigame:tearsofguthix-tearscollected" + const val attributeIsCollecting = "minigame:tearsofguthix-iscollecting" + + // In order specified by RS + private val rewardArray = arrayOf( + Skills.COOKING, + Skills.CRAFTING, + Skills.FIREMAKING, + Skills.FISHING, + Skills.MAGIC, + Skills.MINING, + Skills.PRAYER, + Skills.RANGE, + Skills.RUNECRAFTING, + Skills.SMITHING, + Skills.WOODCUTTING, + Skills.AGILITY, + Skills.HERBLORE, + Skills.FLETCHING, + Skills.THIEVING, + Skills.SLAYER, + Skills.ATTACK, + Skills.DEFENCE, + Skills.STRENGTH, + Skills.HITPOINTS, + Skills.FARMING, + Skills.CONSTRUCTION, + Skills.HUNTER, + Skills.SUMMONING, // This isn't but lmao. + ) + // In order specified by RS + val rewardText = arrayOf( + "You have a brief urge to cook some food.", + "Your fingers feel nimble and suited to delicate work.", + "You have a brief urge to set light to something.", + "You gain a deep understanding of the creatures of the sea.", + "You feel the power of the runes surging through you. ", + "You gain a deep understanding of the stones of the earth.", + "You suddenly feel very close to the gods.", + "Your aim improves.", + "You gain a deep understanding of runes.", + "You gain a deep understanding of all types of metal.", + "You gain a deep understanding of the trees in the wood.", + "You feel very nimble.", + "You gain a deep understanding of all kinds of strange plants.", + "You gain a deep understanding of wooden sticks.", + "You feel your respect for others' property slipping away.", + "You gain a deep understanding of many strange creatures.", + "You feel a brief surge of aggression.", + "You feel more able to defend yourself.", + "Your muscles bulge.", + "You feel very healthy.", + "You gain a deep understanding of the cycles of nature.", + "You feel homesick.", + "You briefly experience the joy of the hunt.", + "You feel at one with nature.", + ) + + /** Calculates the XP to reward. */ + fun rewardTears(player: Player) { + val lowestSkill = rewardArray.reduce{ acc, curr -> + // If you don't have construction, you cannot earn xp on it. + if (curr == Skills.CONSTRUCTION && !hasHouse(player)) { + acc + } + // If you don't have Druidic Ritual completed, you cannot earn xp on it. + else if (curr == Skills.HERBLORE && !isQuestComplete(player, Quests.DRUIDIC_RITUAL)) { + acc + } + // If you don't have Rune Mysteries, you cannot earn xp on it. + else if (curr == Skills.RUNECRAFTING && !isQuestComplete(player, Quests.RUNE_MYSTERIES)) { + acc + } + // If you don't have Wolf Whistle, you cannot earn xp on it. + else if (curr == Skills.SUMMONING && !isQuestComplete(player, Quests.WOLF_WHISTLE)) { + acc + } + else if (player.skills.getExperience(acc) <= player.skills.getExperience(curr)) { + acc + } else { + curr + } + } + + var perTearXP = 60.0 // Caps at level 30, giving 60 per XP. + if (getStatLevel(player, lowestSkill) < 30) { + perTearXP = (getStatLevel(player, lowestSkill) - 1) * 1.724137 // From 50/29 + perTearXP += 10 + } + + sendMessage(player, rewardText[rewardArray.indexOf(lowestSkill)]) + + val tearsCollected = getAttribute(player, attributeTearsCollected, 0) + rewardXP(player, lowestSkill, perTearXP * tearsCollected) + } + + /** Opens interface, walks the player to the center and start game. */ + fun startGame(player: Player) { + lock(player, 15) + // Opens the Tears of Guthix Interface in the tab. + player.interfaceManager.openSingleTab(Component(Components.TOG_WATER_BOWL_4)) + // Sets up the interface varbits. + setAttribute(player, attributeTicksRemaining, getQuestPoints(player) + 15) // 15 to offset the stupid walking. + setAttribute(player, attributeTearsCollected, 0) + setVarbit(player, varbitTimeBar, 10) + setVarbit(player,varbitPoints, 0) + + // Forces the player to hold a bowl and animate accordingly. + replaceSlot(player, EquipmentSlot.WEAPON.ordinal, Item(Items.STONE_BOWL_4704), null, Container.EQUIPMENT) + // Change the player's SET ANIMATIONS to the bowl holding set. Found using ::ranim + player.appearance.setAnimations(Animation(357)) // THIS WAS TRIAL AND ERROR AND WAS FUCKING HARD TO FIND + player.appearance.sync() + + queueScript(player, 0, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + val distance = player.location.getDistance(Location(3251, 9516, 2)).toInt() + 1// Per tick? + forceMove(player, player.location, Location(3251, 9516, 2), 0, distance * 15, null, 2041) + return@queueScript delayScript(player, distance) + } + 1 -> { + face(player, Location(3252, 9516, 2)) + val junaScenery = getScenery(Location(3252, 9516, 2)) + if (junaScenery != null) { + animateScenery(junaScenery, 2055) + } + return@queueScript delayScript(player, 2) + } + 2 -> { + val distance = player.location.getDistance(Location(3253, 9516, 2)).toInt() + 1 // Per tick? + forceMove(player, player.location, Location(3253, 9516, 2), 0, distance * 15, null, 2041) + return@queueScript delayScript(player, distance) + } + 3 -> { + face(player, Location(3253, 9517, 2)) + return@queueScript delayScript(player, 2) + } + 4 -> { + val distance = player.location.getDistance(Location(3253, 9517, 2)).toInt() + 1 // Per tick? + forceMove(player, player.location, Location(3253, 9517, 2), 0, distance * 15, null, 2041) + return@queueScript delayScript(player, distance) + } + 5 -> { + face(player, Location(3257, 9517, 2)) + return@queueScript delayScript(player, 2) + } + 6 -> { + val distance = player.location.getDistance(Location(3257, 9517, 2)).toInt() + 1 // Per tick? + forceMove(player, player.location, Location(3257, 9517, 2), 0, distance * 15, null, 2041) + return@queueScript delayScript(player, distance) + } + 7 -> { + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + } + + fun endGame(player: Player) { + lock(player, 22) + queueScript(player, 0, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + sendMessage(player, "Your time in the cave is up.") + val distance = player.location.getDistance(Location(3253, 9517, 2)).toInt() + 1 // Per tick? + forceMove(player, player.location, Location(3253, 9517, 2), 0, distance * 15, null, 2041) + return@queueScript delayScript(player, distance) + } + 1 -> { + face(player, Location(3253, 9516, 2)) + return@queueScript delayScript(player, 2) + } + 2 -> { + val distance = player.location.getDistance(Location(3253, 9516, 2)).toInt() + 1 // Per tick? + forceMove(player, player.location, Location(3253, 9516, 2), 0, distance * 15, null, 2041) + return@queueScript delayScript(player, distance) + } + 3 -> { + face(player, Location(3251, 9516, 2)) + val junaScenery = getScenery(Location(3252, 9516, 2)) + if (junaScenery != null) { + animateScenery(junaScenery, 2055) + } + return@queueScript delayScript(player, 2) + } + 4 -> { + val distance = player.location.getDistance(Location(3251, 9516, 2)).toInt() + 1 // Per tick? + forceMove(player, player.location, Location(3251, 9516, 2), 0, distance * 15, null, 2041) + return@queueScript delayScript(player, distance) + } + 5 -> { + sendMessage(player, "You drink the liquid...") + animate(player, 2045) + return@queueScript delayScript(player, 3) + } + 6 -> { + rewardTears(player) + setAttribute(player, TearsOfGuthix.attributePreviousDate, System.currentTimeMillis()) + setAttribute(player, TearsOfGuthix.attributePreviousXPAmount, player.skills.totalXp) + setAttribute(player, TearsOfGuthix.attributePreviousQuestPoints, getQuestPoints(player)) + removeAttribute(player, attributeTearsCollected) + if (player.interfaceManager.singleTab?.id == 4) { + player.interfaceManager.closeSingleTab() + } + player.interfaceManager.restoreTabs() + removeItem(player, Items.STONE_BOWL_4704, Container.EQUIPMENT) + return@queueScript stopExecuting(player) + } + else -> return@queueScript stopExecuting(player) + } + } + } + + } + + override fun defineListeners() { + + on(Scenery.WEEPING_WALL_6660, SCENERY, "collect-from") { player, node -> + animate(player, 2043) + val index = TearsOfGuthixGlobalTick.allWalls.indexOf(node.location) + setAttribute(player, attributeIsCollecting, index) + return@on true + } + + } + + // Timer step per tick while you are in the minigame. + override fun process(entity: Entity, event: TickEvent) { + if (entity is Player) { + if (getAttribute(entity, attributeTicksRemaining, -1) > 0) { + setAttribute(entity, attributeTicksRemaining, getAttribute(entity, attributeTicksRemaining, 0) - 1) + setVarbit(entity, varbitTimeBar, (getAttribute(entity, attributeTicksRemaining, 0) * 10 / getQuestPoints(entity)), false) + if (getAttribute(entity, attributeIsCollecting, 0) != 0) { + val currentArrayIndex = getAttribute(entity, attributeIsCollecting, 0) + val currentTearState = TearsOfGuthixGlobalTick.globalWallState[currentArrayIndex] + if (currentTearState == 1) { + setAttribute(entity, attributeTearsCollected, getAttribute(entity, attributeTearsCollected, 0) + 1) + } else if (currentTearState == 2 && getAttribute(entity, attributeTearsCollected, 0) > 0){ + setAttribute(entity, attributeTearsCollected, getAttribute(entity, attributeTearsCollected, 0) - 1) + } + setVarbit(entity, varbitPoints, getAttribute(entity, attributeTearsCollected, 0)) + } + } else if (getAttribute(entity, attributeTicksRemaining, -1) == 0) { + removeAttribute(entity, attributeTicksRemaining) + endGame(entity) + } + } + } + + + override fun defineAreaBorders(): Array { + return arrayOf(ZoneBorders(3253, 9513, 3262, 9522, 2)) + } + + override fun getRestrictions(): Array { + return arrayOf(ZoneRestriction.RANDOM_EVENTS, ZoneRestriction.CANNON, ZoneRestriction.FOLLOWERS, ZoneRestriction.TELEPORT) + } + + override fun areaEnter(entity: Entity) { + if (entity is Player) { + if (getAttribute(entity, attributeTicksRemaining, 0) <= 0) { + removeItem(entity, Items.STONE_BOWL_4704, Container.EQUIPMENT) + teleport(entity, Location(3251, 9516, 2)) + } else { + entity.hook(Event.Tick, this) + } + } + } + + override fun areaLeave(entity: Entity, logout: Boolean) { + if (entity is Player) { + entity.unhook(this) + if (logout) { + removeItem(entity, Items.STONE_BOWL_4704, Container.EQUIPMENT) + removeAttribute(entity, attributeTearsCollected) + removeAttribute(entity, attributeTicksRemaining) + teleport(entity, Location(3251, 9516, 2)) + } + } + } + override fun entityStep(entity: Entity, location: Location, lastLocation: Location) { + if (entity is Player) { + entity.hook(Event.Tick, this) + setAttribute(entity, attributeIsCollecting, 0) // If you move, you ain't collecting + } + } +} + +/** + * Global Tick class to randomize the walls consistently for everyone. + */ +class TearsOfGuthixGlobalTick : TickListener { + + companion object { + var ticks = 0 + var globalWallState = intArrayOf(0, 0, 2, 1, 2, 1, 0, 0, 2, 1) + val allWalls = arrayOf( + // Blank + Location(0, 0, 0), + // Left Walls + Location(3258, 9520, 2), + Location(3261, 9516, 2), + Location(3261, 9518, 2), + Location(3257, 9514, 2), + Location(3259, 9514, 2), + // Right Walls + Location(3257, 9520, 2), + Location(3259, 9520, 2), + Location(3261, 9517, 2), + Location(3258, 9514, 2), + ) + } + + override fun tick() { + // Do this every 10 ticks. + if (ticks++ > 10) { ticks = 0 } else { return } + // Shuffle the walls + val wallStates = intArrayOf(0, 0, 0, 1, 1, 1, 2, 2, 2) // 0 is absent, 1 is blue, 2 is green + wallStates.shuffle() + globalWallState = intArrayOf(0) + wallStates + + /* + * Explanation: The walls are layered sceneries, which makes it rabidly fucked to change them. + * What I did was to add the tears scenery first (essentially overriding the tears scenery), + * then add the WEEPING_WALL_6660 right after it so that the interactions are still there. + * this is how a layer is like: + * 1 - WEEPING_WALL_6660 - No model, but holds the option "collect-from" + * 2 - BLUE/GREEN/ABSENT - Model of the blue/green/absent waterfall. + * 3 - WEEPING_WALL_6664 - The actual model, but not interactive. + * 6661 - 6664 is left side, 6665 to 6668 is right side + */ + wallStates.forEachIndexed { index, state -> + val scenery = getScenery(allWalls[index + 1])!! + val newSceneryId = if (state == 2) { + if (index + 1 <= 5) { + Scenery.GREEN_TEARS_6662 + } else { + Scenery.GREEN_TEARS_6666 + } + } else if (state == 1) { + if (index + 1 <= 5) { + Scenery.BLUE_TEARS_6661 + } else { + Scenery.BLUE_TEARS_6665 + } + } else { + if (index + 1 <= 5) { + Scenery.ABSENCE_OF_TEARS_6663 + } else { + Scenery.ABSENCE_OF_TEARS_6667 + } + } + addScenery(core.game.node.scenery.Scenery( + newSceneryId, + scenery.location, + 4, + scenery.rotation + )) + addScenery(core.game.node.scenery.Scenery(Scenery.WEEPING_WALL_6660, scenery.location, 0, scenery.rotation)) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/FatherAereckDialogue.java b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/FatherAereckDialogue.java new file mode 100644 index 0000000..acf0ca8 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/FatherAereckDialogue.java @@ -0,0 +1,345 @@ +package content.region.misthalin.lumbridge.quest.therestlessghost; + +import core.game.component.Component; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.link.diary.DiaryType; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; +import core.game.dialogue.DialoguePlugin; +import content.data.Quests; + + +/** + * Represents the father aereck dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class FatherAereckDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code FatherAereckDialogue} {@code Object}. + */ + public FatherAereckDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code FatherAereckDialogue} {@code Object}. + * + * @param player the player. + */ + public FatherAereckDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new FatherAereckDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + int questStage = player.getQuestRepository().getQuest(Quests.THE_RESTLESS_GHOST).getStage(player); + if (questStage == 10) { + npc("Have you got rid of the ghost yet?"); + stage = 520; + return true; + } + if (questStage == 20) { + player("I had a talk with Father Urhney. He has given me this", "funny amulet to talk to the ghost with."); + stage = 530; + return true; + } + if (questStage == 30) { + player("I've found out that the ghost's corpse has lost its skull.", "If I can find the skull, the ghost should leave."); + stage = 540; + return true; + } + if (questStage == 40) { + player("I've finally found the ghost's skull!"); + stage = 550; + return true; + } + npc("Welcome to the church of holy Saradomin, my", "friend! What can I do for you today?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + if (player.getQuestRepository().isComplete(Quests.THE_RESTLESS_GHOST)) { + interpreter.sendOptions("What would you like to say?", "Can you change my gravestone now?", "Who's Saradomin?", "Nice place you've got here."); + stage = 1; + } else { + interpreter.sendOptions("What would you like to say?", "Can you change my gravestone now?", "Who's Saradomin?", "Nice place you've got here.", "I'm looking for a quest."); + stage = 500; + } + break; + case 500: + switch (buttonId) { + case 1: + npc("Certainly. All proceeds are donated to the", "Varrockian Guards' Widows & Orphans Fund."); + stage = 10; + break; + case 2: + npc("Surely you have heard of our god, Saradomin?"); + stage = 20; + break; + case 3: + npc("It is, isn't it? It was built over two centuries ago."); + stage = 300; + break; + case 4: + player("I'm looking for a quest."); + stage = 505; + break; + } + break; + case 505: + npc("That's lucky, I need someone to do a quest for me."); + stage = 506; + break; + case 506: + options("Ok, let me help then.", "Sorry, I don't have time right now."); + stage = 507; + break; + case 507: + switch (buttonId) { + case 1: + player("Ok, let me help then."); + stage = 510; + break; + case 2: + player("Sorry, I don't have time right now."); + stage = 508; + break; + } + break; + case 508: + npc("Oh well. If you do have some spare time on your", "hands, come back and talk to me."); + stage = 509; + break; + case 509: + end(); + break; + case 510: + player.getQuestRepository().getQuest(Quests.THE_RESTLESS_GHOST).start(player); + player.getQuestRepository().syncronizeTab(player); + npc("Thank you. The problem is, there is a ghost in the", "church graveyard. I would like you to get rid of it."); + stage = 511; + break; + case 511: + npc("If you need any help, my friend Father Urhney is an", "expert on ghosts."); + stage = 512; + break; + case 512: + npc("I believe he is currently living as a hermit in Lumbridge", "swamp. He has a little shack in the south-west of the", "swamps."); + stage = 513; + break; + case 513: + npc("Exit the graveyard through the south gate to reach the", "swamp. I'm sure if you told him that I sent you he'd", "be willing to help."); + stage = 514; + break; + case 514: + npc("My name is Father Aereck by the way. Pleased to", "meet you."); + stage = 515; + break; + case 515: + player("Likewise."); + stage = 516; + break; + case 516: + npc("Take care travelling through the swamps, I have heard", "they can be quite dangerous."); + stage = 517; + break; + case 517: + player("I will, thanks."); + stage = 518; + break; + case 518: + end(); + break; + case 520: + if (!player.getGameAttributes().getAttributes().containsKey("restless-ghost:urhney")) { + player("I can't find Father Urhney at the moment."); + stage = 521; + break; + } + break; + case 521: + npc("Well, you can get to the swamp he lives in by going", "south through the cemetery."); + stage = 522; + break; + case 522: + npc("You'll have to go right into the western depths of the", "swamp, near the coastline. That is where his house is."); + stage = 523; + break; + case 523: + end(); + break; + case 530: + npc("I always wondered what that amulet was... Well, I hope", "it's useful. Tell me when you get rid of the ghost!"); + stage = 531; + break; + case 531: + end(); + break; + case 540: + npc("That WOULD explain it."); + stage = 541; + break; + case 541: + npc("Hmmmmm. Well, I haven't seen any skulls."); + stage = 542; + break; + case 542: + player("Yes, I think a warlock has stolen it."); + stage = 543; + break; + case 543: + npc("I hate warlocks."); + stage = 544; + break; + case 544: + npc("Ah well, good luck!"); + stage = 545; + break; + case 545: + end(); + break; + case 550: + npc("Great! Put it in the ghost's coffin and see what", "happens!"); + stage = 545; + break; + case 1: + switch (buttonId) { + case 1: + npc("Certainly. All proceeds are donated to the", "Varrockian Guards' Widows & Orphans Fund."); + stage = 10; + break; + case 2: + npc("Surely you have heard of our god, Saradomin?"); + stage = 20; + break; + case 3: + npc("It is, isn't it? It was built over two centuries ago."); + stage = 300; + break; + } + + break; + case 10: + end(); + player.getInterfaceManager().open(new Component(652)); + player.getAchievementDiaryManager().finishTask(player, DiaryType.LUMBRIDGE, 0, 15); + break; + case 20: + npc("He who created the forces of goodness and purity in this", "world? I cannot believe your ignorance!"); + stage = 21; + break; + case 21: + npc("This is the god with more followers than any other ...at", "least in this part of the world."); + stage = 22; + break; + case 22: + npc("He who forged the world as we know it, along with his", "brothers Guthix and Zamorak?"); + stage = 23; + break; + case 23: + options("Oh, THAT Saradomin.", "Oh, sorry, I'm not from this world."); + stage = 24; + break; + case 24: + switch (buttonId) { + case 1: + npc("There is only one Saradomin."); + stage = 200; + break; + case 2: + npc("..."); + stage = 250; + break; + } + + break; + case 200: + player("Yeah. I, uh, thought you said something else."); + stage = 201; + break; + case 201: + end(); + break; + case 250: + npc("That's...strange."); + stage = 251; + break; + case 251: + npc("I thought things not from this world were all, you know,", "slime and tentacles."); + stage = 270; + break; + case 270: + options("Not me.", "I am! Do you like my disguise?"); + stage = 271; + break; + case 271: + + switch (buttonId) { + case 1: + npc("Well, I can see that. Still, there's something special about", "you."); + stage = 253; + break; + case 2: + npc("Argh! Avaunt, foul creature from another dimension!", "Avaunt! Begone in the name of Saradomin!"); + stage = 291; + break; + } + break; + case 291: + player("Okay, okay, I was only joking!"); + stage = 292; + break; + case 292: + end(); + break; + case 253: + player("Thanks, I think."); + stage = 254; + break; + case 254: + end(); + break; + case 300: + end(); + break; + case 570: + interpreter.sendDialogues(player, null, "Yes, I have!"); + stage = 571; + break; + case 571: + interpreter.sendDialogues(npc, null, "Thank you for getting rid of that awful ghost for me!", "May Saradomin always smile upon you!"); + stage = 572; + break; + case 572: + interpreter.sendDialogues(player, null, "I'm looking for a new quest."); + stage = 573; + break; + case 573: + interpreter.sendDialogues(npc, null, "Sorry, I only had the one quest."); + stage = 300; + break; + } + + return true; + } + + @Override + public int[] getIds() { + return new int[]{456}; + } +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/FatherUhrneyDialogue.java b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/FatherUhrneyDialogue.java new file mode 100644 index 0000000..1097d1d --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/FatherUhrneyDialogue.java @@ -0,0 +1,284 @@ +package content.region.misthalin.lumbridge.quest.therestlessghost; + +import content.data.Quests; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.plugin.Initializable; +import core.game.node.item.Item; +import core.game.dialogue.DialoguePlugin; + +/** + * Represents the father urgney dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class FatherUhrneyDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code FatherUhrneyDialogue} {@code Object}. + */ + public FatherUhrneyDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code FatherUhrneyDialogue} {@code Object}. + * @param player the player. + */ + public FatherUhrneyDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new FatherUhrneyDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + npc("Go away! I'm meditating!"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + if (player.getQuestRepository().getQuest(Quests.THE_RESTLESS_GHOST).getStage(player) == 0) { + options("Well, that's friendly.", "I've come to respossess your house."); + stage = 1; + } else if (player.getQuestRepository().getQuest(Quests.THE_RESTLESS_GHOST).getStage(player) == 10) { + options("Well, that's friendly.", "I've come to respossess your house.", "Father Aereck sent me to talk to you."); + stage = 500; + } else if (player.getGameAttributes().getAttributes().containsKey("restless-ghost:urhney") || player.getQuestRepository().isComplete(Quests.THE_RESTLESS_GHOST)) { + options("Well, that's friendly.", "I've come to respossess your house.", "I've lost the Amulet of Ghostspeak."); + stage = 514; + } + break; + case 500: + switch (buttonId) { + case 1: + player("Well, that's friendly."); + stage = 10; + break; + case 2: + player("I've come to repossess your house."); + stage = 20; + break; + case 3: + player("Father Aereck sent me to talk to you."); + stage = 501; + break; + } + break; + case 501: + npc("I suppose I'd better talk to you then. What problems", "has he got himself into this time?"); + stage = 502; + break; + case 502: + player("He's got a ghost haunting his graveyard."); + stage = 503; + break; + case 503: + npc("Oh, the silly fool."); + stage = 504; + break; + case 504: + npc("I leave town for just five months, and ALREADY he", "can't manage."); + stage = 505; + break; + case 505: + npc("(sigh)"); + stage = 506; + break; + case 506: + npc("Well, I can't go back and exorcise it. I vowed not to", "leave this place. Until I had done a full two years of", "prayer and meditation."); + stage = 507; + break; + case 507: + npc("Tell you what I can do though; take this amulet."); + stage = 508; + break; + case 508: + if (player.getInventory().freeSlots() == 0) { + end(); + player.getPacketDispatch().sendMessage("You don't have enough inventory space to accept this amulet."); + break; + } + interpreter.sendItemMessage(552, "Father Urhney hands you an amulet."); + player.getInventory().add(new Item(552, 1)); + player.getQuestRepository().getQuest(Quests.THE_RESTLESS_GHOST).setStage(player, 20); + player.getGameAttributes().setAttribute("/save:restless-ghost:urhney", true); + stage = 509; + break; + case 509: + npc("It is an Amulet of Ghostspeak."); + stage = 510; + break; + case 510: + npc("So called, because when you wear it you can speak to", "ghosts. A lot of ghosts are doomed to be ghosts because", "they have left some important task uncompleted."); + stage = 511; + break; + case 511: + npc("Maybe if you know what this task is, you can get rid of", "the ghost. I'm not making any gurantees mind you,", "but it is the best I can do right now."); + stage = 512; + break; + case 512: + player("Thank you. I'll give it a try!"); + stage = 513; + break; + case 513: + end(); + break; + case 514: + switch (buttonId) { + case 1: + player("Well, that's friendly."); + stage = 10; + break; + case 2: + player("I've come to repossess your house."); + stage = 20; + break; + case 3: + player("I've lost the Amulet of Ghostpeak."); + stage = 515; + break; + } + break; + case 515: + if (player.getInventory().contains(552, 1) || player.getEquipment().contains(552, 1)) { + interpreter.sendDialogue("Father Urhney sighs."); + stage = 516; + break; + } + if (player.getBank().contains(552, 1)) { + interpreter.sendDialogue("Father Urhney sighs."); + stage = 517; + break; + } + interpreter.sendDialogue("Father Urhney sighs."); + stage = 519; + break; + case 516: + npc("What are you talking about? I can see you've got it", "with you!"); + stage = 518; + break; + case 517: + npc("What are you talking about? I can see you've got it", "in your bank!"); + stage = 518; + break; + case 518: + end(); + break; + case 519: + npc("How careless can you get? Those things aren't easy to", "come by you know! It's a good job I've got a spare."); + stage = 520; + break; + case 520: + player.getInventory().add(new Item(552)); + interpreter.sendItemMessage(552, "Father Urhney hands you an amulet."); + player.getAchievementDiaryManager().finishTask(player, DiaryType.LUMBRIDGE, 1, 12); + stage = 521; + break; + case 521: + npc("Be more careful this time."); + stage = 522; + break; + case 522: + player("Ok, I'll try to be."); + stage = 523; + break; + case 523: + end(); + break; + case 1: + switch (buttonId) { + case 1: + player("Well, that's friendly."); + stage = 10; + break; + case 2: + player("I've come to repossess your house."); + stage = 20; + break; + + } + break; + case 10: + npc("I SAID go AWAY."); + stage = 11; + break; + case 11: + player("Ok, ok... sheesh, what a grouch."); + stage = 12; + break; + case 12: + end(); + break; + case 20: + npc("Under what grounds???"); + stage = 21; + break; + case 21: + options("Repeated failure on mortgage repayments.", "I don't know, I just wanted this house."); + stage = 22; + break; + case 22: + switch (buttonId) { + case 1: + player("Repeated failure on mortgage repayments."); + stage = 100; + break; + case 2: + player("I don't know. I just wanted this house..."); + stage = 200; + break; + + } + break; + case 100: + npc("What?"); + stage = 101; + break; + case 101: + npc("I don't have a mortgage! I built this house."); + stage = 102; + break; + case 102: + player("Sorry. I mus thave got the wrong address. All the", "houses look the same around here."); + stage = 103; + break; + case 103: + npc("What? What houses? What ARE you talking about???"); + stage = 104; + break; + case 104: + player("Never mind."); + stage = 105; + break; + case 105: + end(); + break; + case 200: + npc("Oh... go away and stop wasting my time!"); + stage = 201; + break; + case 201: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 458 }; + } +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhost.java b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhost.java new file mode 100644 index 0000000..11fd553 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhost.java @@ -0,0 +1,112 @@ +package content.region.misthalin.lumbridge.quest.therestlessghost; + +import content.region.misthalin.draynor.quest.anma.OldCronDialogue; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.ClassScanner; + +import static core.api.ContentAPIKt.*; +import content.data.Quests; + + +/** + * Represents the restless ghost quest. + * @author Vexia + * + */ +@Initializable +public class RestlessGhost extends Quest { + /** + * The ghost speak amulet. + */ + public static final Item AMULET = new Item(552); + + /** + * Constructs a new {@Code RestlessGhost} {@Code Object} + */ + public RestlessGhost() { + super(Quests.THE_RESTLESS_GHOST, 25, 24, 1, 107, 0, 4, 5); + } + + @Override + public Quest newInstance(Object object) { + ClassScanner.definePlugin(new OldCronDialogue()); + return this; + } + + @Override + public void drawJournal(Player player, int stage) { + super.drawJournal(player, stage); + if (stage == 0) { + player.getPacketDispatch().sendString("I can start this quest by speaking to Father Aereck in the", 275, 4+ 7); + player.getPacketDispatch().sendString("church next to Lumbridge Castle.", 275, 5+ 7); + player.getPacketDispatch().sendString("I must be unafraid of a Level 13 Skeleton ", 275, 6+ 7); + } + if (stage == 10) { + player.getPacketDispatch().sendString("Father Aereck asked me to help him deal with the Ghost in", 275, 4+ 7); + player.getPacketDispatch().sendString("the graveyard next to the church.", 275, 5+ 7); + player.getPacketDispatch().sendString("I should find Father Urhney who is an expert on ghosts. ", 275, 6+ 7); + player.getPacketDispatch().sendString("He lives in a shack in Lumbridge Swamp.", 275, 7+ 7); + + } + if (stage == 20) { + player.getPacketDispatch().sendString("Father Aereck asked me to help him deal with the Ghost in", 275, 4+ 7); + player.getPacketDispatch().sendString("the graveyard next to the church.", 275, 5+ 7); + player.getPacketDispatch().sendString("I should find Father Urhney who is an expert on ghosts. ", 275, 6+ 7); + player.getPacketDispatch().sendString("He lives in a shack in Lumbridge Swamp.", 275, 7+ 7); + player.getPacketDispatch().sendString("I should talk to the Ghost to find out why it is haunting the", 275, 8+ 7); + player.getPacketDispatch().sendString("graveyard crypt", 275, 9+ 7); + } + if (stage == 30) { + player.getPacketDispatch().sendString("Father Aereck asked me to help him deal with the Ghost in", 275, 4+ 7); + player.getPacketDispatch().sendString("the graveyard next to the church.", 275, 5+ 7); + player.getPacketDispatch().sendString("I found Father Urhney in the swamp south of Lumbridge.He ", 275, 6+ 7); + player.getPacketDispatch().sendString("gave me an Amulet of Ghostspeak to talk to the ghost.", 275, 7+ 7); + player.getPacketDispatch().sendString("I spoke to the Ghost and he told me he could not rest in", 275, 8+ 7); + player.getPacketDispatch().sendString("peace because an evil wizard had stolen his skull.", 275, 9+ 7); + player.getPacketDispatch().sendString("I should go and search the Wizard's Tower South West of", 275, 10+ 7); + player.getPacketDispatch().sendString("Lumbridge for the Ghost's Skull.", 275, 11+ 7); + } + if (stage == 40) { + player.getPacketDispatch().sendString("Father Aereck asked me to help him deal with the Ghost in", 275, 4+ 7); + player.getPacketDispatch().sendString("the graveyard next to the church.", 275, 5+ 7); + player.getPacketDispatch().sendString("I found Father Urhney in the swamp south of Lumbridge.He ", 275, 6+ 7); + player.getPacketDispatch().sendString("gave me an Amulet of Ghostspeak to talk to the ghost.", 275, 7+ 7); + player.getPacketDispatch().sendString("I spoke to the Ghost and he told me he could not rest in", 275, 8+ 7); + player.getPacketDispatch().sendString("peace because an evil wizard had stolen his skull.", 275, 9+ 7); + player.getPacketDispatch().sendString("I found the Ghost's Skull in the basement of the Wizards'", 275, 10+ 7); + player.getPacketDispatch().sendString("Tower. It was guarded by a skeleton, but I took it anyways.", 275, 11+ 7); + player.getPacketDispatch().sendString("I should take the Skull back to the Ghost so it can rest.", 275, 12+ 7); + } + if (stage == 100) { + player.getPacketDispatch().sendString("Father Aereck asked me to help him deal with the Ghost in", 275, 4+ 7); + player.getPacketDispatch().sendString("the graveyard next to the church.", 275, 5+ 7); + player.getPacketDispatch().sendString("I found Father Urhney in the swamp south of Lumbridge.He ", 275, 6+ 7); + player.getPacketDispatch().sendString("gave me an Amulet of Ghostspeak to talk to the ghost.", 275, 7+ 7); + player.getPacketDispatch().sendString("I spoke to the Ghost and he told me he could not rest in", 275, 8+ 7); + player.getPacketDispatch().sendString("peace because an evil wizard had stolen his skull.", 275, 9+ 7); + player.getPacketDispatch().sendString("I found the Ghost's Skull in the basement of the Wizards'", 275, 10+ 7); + player.getPacketDispatch().sendString("Tower. It was guarded by a skeleton, but I took it anyways.", 275, 11+ 7); + player.getPacketDispatch().sendString("I placed the Skull in the Ghost's coffin, and allowed it to", 275, 12+ 7); + player.getPacketDispatch().sendString("rest in peace once more, with gratitude for my help.", 275, 13+ 7); + player.getPacketDispatch().sendString("QUEST COMPLETE!", 275, 16+ 7); + } + } + + @Override + public void finish(Player player) { + super.finish(player); + player.getPacketDispatch().sendString("1 Quest Point", 277, 8 + 2); + player.getPacketDispatch().sendString("1125 Prayer XP", 277, 9 + 2); + player.getPacketDispatch().sendItemZoomOnInterface(964, 240, 277, 3 + 2); + player.getSkills().addExperience(Skills.PRAYER, 1125); + player.getInterfaceManager().closeChatbox(); + player.getPacketDispatch().sendString("You have completed The Restless Ghost Quest!", 277, 2 + 2); + setVarp(player, 728, 31, true); + player.getGameAttributes().removeAttribute("restless-ghost:urhney"); + } + +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhostDialogue.java b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhostDialogue.java new file mode 100644 index 0000000..41b9f04 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhostDialogue.java @@ -0,0 +1,252 @@ +package content.region.misthalin.lumbridge.quest.therestlessghost; + +import content.data.Quests; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; + +/** + * Handles the RestlessGhostDialogue dialogue. + * @author 'Vexia + */ +@Initializable +public class RestlessGhostDialogue extends DialoguePlugin { + + public RestlessGhostDialogue() { + + } + + public RestlessGhostDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new RestlessGhostDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello ghost, how are you?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + if (!player.getEquipment().contains(552, 1)) { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Wooo wooo wooooo!"); + stage = 1; + } else { + if (player.getQuestRepository().getQuest(Quests.THE_RESTLESS_GHOST).getStage(player) == 20) { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Not very good actually."); + stage = 500; + break; + } + if (player.getQuestRepository().getQuest(Quests.THE_RESTLESS_GHOST).getStage(player) == 30) { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "How are you doing finding my skull?"); + stage = 520; + break; + } + if (player.getQuestRepository().getQuest(Quests.THE_RESTLESS_GHOST).getStage(player) == 40) { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "How are you doing finding my skull?"); + stage = 550; + break; + } + interpreter.sendDialogues(npc, null, "Fine, thanks."); + stage = 990; + } + break; + case 990: + end(); + break; + case 500: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What's the problem then?"); + stage = 501; + break; + case 501: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Did you just understand what I said???"); + stage = 502; + break; + case 502: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Yep, now tell me what the problem is."); + stage = 503; + break; + case 503: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "WOW! This is INCREDIBLE! I didn't expect anyone", "to ever understand me again!"); + stage = 504; + break; + case 504: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Ok, Ok, I can understand you!"); + stage = 505; + break; + case 505: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "But have you any idea WHY you're doomed to be a", "ghost?"); + stage = 506; + break; + case 506: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Well, to be honest... I'm not sure."); + stage = 507; + break; + case 507: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I've been told a certain task may need to be completed", "so you can rest in peace."); + stage = 508; + break; + case 508: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I should think it is probably because a warlock has come", "along and stolen my skull. If you look inside my coffin", "there, you'll find my corpse without a head on it."); + stage = 509; + break; + case 509: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Do you know where this warlock might be now?"); + stage = 510; + break; + case 510: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I think it was one of the warlocks who lives in the big", "tower by the sea south-west from here."); + stage = 511; + break; + case 511: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Ok. I will try and get the skull back for you, then you", "can rest in peace."); + player.getQuestRepository().getQuest(Quests.THE_RESTLESS_GHOST).setStage(player, 30); + stage = 512; + break; + case 512: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ooh, thank you. That would be such a great relief!"); + stage = 513; + break; + case 513: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "It is so dull being a ghost..."); + stage = 514; + break; + case 514: + end(); + break; + case 520: + if (player.getInventory().contains(964, 1)) { + + break; + } else { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Sorry, I can't find it at the moment."); + stage = 521; + } + break; + case 521: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ah well. Keep on looking."); + stage = 522; + break; + case 522: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I'm pretty sure it's somewhere in the tower south-west", "from here. There's a lot of levels to the tower, though. I", "suppose it might take a little while to find."); + stage = 523; + break; + case 523: + end(); + break; + case 550: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I have found it!"); + stage = 551; + break; + case 551: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hurrah! Now I can stop being a ghost! You just need", "to put it on my coffin there, and I will be free!"); + stage = 523; + break; + case 1: + interpreter.sendOptions("Select an Option", "Sorry, I don't speak ghost.", "Ooh... THAT'S interesting.", "Any hints where I can find some treasure?"); + stage = 2; + break; + case 2: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Sorry, I don't speak ghost."); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Ooh... THAT'S interesting."); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Any hints where I can find some treasure?"); + stage = 30; + break; + + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Woo woo?"); + stage = 11; + break; + case 11: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Nope, still don't understand you."); + stage = 12; + break; + case 12: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "WOOOOOOOOO!"); + stage = 13; + break; + case 13: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Never mind."); + stage = 14; + break; + case 14: + end(); + break; + case 30: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Wooooooo woo! Wooooo woo wooooo woowoowoo wooo", "Woo woooo. Wooooo woo woo? Wooooooooooooooooooo!"); + stage = 31; + break; + case 31: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Sorry, I don't speak ghost."); + stage = 32; + break; + case 32: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Woo woo?"); + stage = 11; + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Woo woooo. Woooooooooooooooooo!"); + stage = 21; + break; + case 21: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Did he really?"); + stage = 22; + break; + case 22: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Woo."); + stage = 23; + break; + case 23: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "My brother had EXACTLY the same problem."); + stage = 24; + break; + case 24: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Woo Wooooo!"); + stage = 25; + break; + case 25: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Wooooo Woo woo woo!"); + stage = 26; + break; + case 26: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Goodbye. Thanks for the chat."); + stage = 27; + break; + case 27: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Wooo wooo?"); + stage = 28; + break; + case 28: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 457 }; + } +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhostPlugin.java b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhostPlugin.java new file mode 100644 index 0000000..d19f260 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhostPlugin.java @@ -0,0 +1,273 @@ +package content.region.misthalin.lumbridge.quest.therestlessghost; + +import content.data.Quests; +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; + +import static core.api.ContentAPIKt.*; + +/** + * Represents the restless ghost plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class RestlessGhostPlugin extends OptionHandler { + + /** + * Represents the close animation of a content. + */ + private static final Animation OPEN_ANIM = new Animation(536); + + /** + * Represents the close animation of a content. + */ + private static final Animation CLOSE_ANIM = new Animation(535); + + /** + * Represents the skull item. + */ + private static final Item SKULL = new Item(964); + + /** + * Represents the ghost npc spawned. + */ + private static RestlessGhostNPC GHOST; + + /** + * Represents the coffin inds. + */ + private static final int[] COFFIN_IDS = new int[] { 2145, 15061, 15052, 15053, 15050, 15051 }; + + /** + * Represents the options. + */ + private static final String[] OPTIONS = new String[] { "open", "close", "search" }; + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (int coffin : COFFIN_IDS) { + for (String option : OPTIONS) { + SceneryDefinition.forId(coffin).getHandlers().put("option:" + option, this); + } + } + new RestlessGhostNPC().newInstance(arg); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + if (GHOST == null) { + GHOST = new RestlessGhostNPC(457, Location.create(3250, 3195, 0)); + GHOST.init(); + GHOST.setInvisible(true); + } + final int id = ((Scenery) node).getId(); + final Scenery object = (Scenery) node; + switch (option) { + case "open": + switch (id) { + default: + toggleCoffin(player, object); + break; + } + case "close": + switch (id) { + case 15052: + case 15053: + toggleCoffin(player, object); + break; + } + break; + case "search": + switch (id) { + case 15052: + player.getPacketDispatch().sendMessage("You search the coffin and find some human remains."); + break; + case 15053: + player.getDialogueInterpreter().sendDialogue("There's a nice and complete skeleton in here!"); + break; + case 15050: + searchAltar(player, object); + break; + case 15051: + if (!player.getQuestRepository().isComplete(Quests.THE_RESTLESS_GHOST) && !player.getBank().containsItem(SKULL) && !player.getInventory().containsItem(SKULL)) { + player.getInventory().add(SKULL); + player.getPacketDispatch().sendMessage("You find another skull."); + } + player.getQuestRepository().getQuest(Quests.THE_RESTLESS_GHOST).setStage(player, 40); + break; + case 2145: + toggleCoffin(player, object); + break; + } + break; + } + return true; + } + + /** + * Method used to toggle the coffin. + * @param player the player. + * @param object the object. + */ + private void toggleCoffin(final Player player, final Scenery object) { + final boolean open = object.getId() == 2145; + player.lock(2); + player.animate(open ? OPEN_ANIM : CLOSE_ANIM); + SceneryBuilder.replace(object, object.transform(open ? 15061 : 2145)); + player.getPacketDispatch().sendMessage("You " + (open ? "open" : "close") + " the coffin."); + if (open && !player.getQuestRepository().isComplete(Quests.THE_RESTLESS_GHOST)) { + sendGhost(); + } + } + + /** + * Method used to send the restless ghost npc. + */ + private void sendGhost() { + if (!GHOST.isInvisible()) { + return; + } + GHOST.setInvisible(false); + GameWorld.getPulser().submit(new Pulse(100, GHOST) { + @Override + public boolean pulse() { + GHOST.setInvisible(true); + return true; + } + }); + } + + /** + * Method used to search the altar. + * @param player the player. + * @param object the object. + */ + private void searchAltar(final Player player, final Scenery object) { + final boolean hasSkull = object.getId() == 15051; + if (player.getQuestRepository().getQuest(Quests.THE_RESTLESS_GHOST).getStage(player) != 30) { + player.getPacketDispatch().sendMessage("You search the altar and find nothing."); + return; + } + if (!hasSkull) { + if (!player.getInventory().add(SKULL)) { + GroundItemManager.create(SKULL, player); + } + setVarp(player, 728, 5, true); + player.getQuestRepository().getQuest(Quests.THE_RESTLESS_GHOST).setStage(player, 40); + player.getPacketDispatch().sendMessage("The skeleton in the corner suddenly comes to life!"); + sendSkeleton(player); + } + } + + /** + * Method used to send the skeleton. + * @param player the player. + */ + private void sendSkeleton(final Player player) { + final NPC skeleton = NPC.create(459, Location.create(3120, 9568, 0)); + skeleton.setWalks(false); + skeleton.setRespawn(false); + skeleton.setAttribute("player", player); + skeleton.init(); + skeleton.getProperties().getCombatPulse().setStyle(CombatStyle.MELEE); + skeleton.getProperties().getCombatPulse().attack(player); + } + + /** + * Handles the temple guardian npc. + * @author 'Vexia + */ + public static final class RestlessGhostNPC extends AbstractNPC { + + /** + * The NPC ids of NPCs using this plugin. + */ + private static final int[] ID = { 459, 457 }; + + /** + * Constructs a new {@code AlKharidWarriorPlugin} {@code Object}. + */ + public RestlessGhostNPC() { + super(0, null); + } + + /** + * Constructs a new {@code AlKharidWarriorPlugin} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + private RestlessGhostNPC(int id, Location location) { + super(id, location, false); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new RestlessGhostNPC(id, location); + } + + @Override + public void init() { + super.init(); + this.getProperties().getCombatPulse().setStyle(CombatStyle.MELEE); + } + + @Override + public void tick() { + super.tick(); + final Player pl = getAttribute("player", null); + if (pl != null) { + if (getAttribute("dead", false) || !getLocation().withinDistance(pl.getLocation(), 16)) { + clear(); + return; + } + } + } + + @Override + public boolean isAttackable(Entity entity, CombatStyle style, boolean message) { + final Player player = ((Player) entity); + final Player pl = getAttribute("player", null); + return pl == null ? false : pl == player ? true : false; + } + + @Override + public void finalizeDeath(Entity killer) { + super.finalizeDeath(killer); + removeAttribute("player"); + } + + @Override + public boolean isHidden(final Player player) { + final Player pl = getAttribute("player", null); + if (this.getRespawnTick() > GameWorld.getTicks()) { + return true; + } + return player.getQuestRepository().isComplete(Quests.THE_RESTLESS_GHOST) || (pl != null && player != pl); + } + + @Override + public int[] getIds() { + return ID; + } + + } + +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhostSkull.java b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhostSkull.java new file mode 100644 index 0000000..4a899c6 --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/RestlessGhostSkull.java @@ -0,0 +1,51 @@ +package content.region.misthalin.lumbridge.quest.therestlessghost; + +import content.data.Quests; +import core.api.Container; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.scenery.Scenery; +import core.plugin.Initializable; +import core.plugin.Plugin; +import org.rs09.consts.Items; + +import static core.api.ContentAPIKt.removeItem; + +/** + * Represents the plugin used to add the skull to the cofin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class RestlessGhostSkull extends UseWithHandler { + + /** + * Constructs a new {@code RestlessGhostSkull} {@code Object}. + */ + public RestlessGhostSkull() { + super(964); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(2145, OBJECT_TYPE, this); + addHandler(15052, OBJECT_TYPE, this); + addHandler(15061, OBJECT_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Scenery object = (Scenery) event.getUsedWith(); + if (object.getId() == 2145) { + event.getPlayer().getDialogueInterpreter().sendDialogue("Maybe I should open it first."); + return true; + } + if (removeItem(event.getPlayer(), Items.SKULL_964, Container.INVENTORY)) { + event.getPlayer().getPacketDispatch().sendMessage("You put the skull in the coffin."); + event.getPlayer().getQuestRepository().getQuest(Quests.THE_RESTLESS_GHOST).finish(event.getPlayer()); + } + return true; + } + +} diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/SkullDropPlugin.java b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/SkullDropPlugin.java new file mode 100644 index 0000000..0fdaf0b --- /dev/null +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/therestlessghost/SkullDropPlugin.java @@ -0,0 +1,32 @@ +package content.region.misthalin.lumbridge.quest.therestlessghost; + +import core.cache.def.impl.ItemDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/* + * 8 + */ +@Initializable +public class SkullDropPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ItemDefinition.forId(964).getHandlers().put("option:drop", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + player.getPacketDispatch().sendMessage("You can't drop this! Return it to the ghost."); + return true; + } + + @Override + public boolean isWalk() { + return false; + } +} diff --git a/Server/src/main/content/region/misthalin/monastery/dialogue/AbbotLangleyDialogue.java b/Server/src/main/content/region/misthalin/monastery/dialogue/AbbotLangleyDialogue.java new file mode 100644 index 0000000..5c80acf --- /dev/null +++ b/Server/src/main/content/region/misthalin/monastery/dialogue/AbbotLangleyDialogue.java @@ -0,0 +1,167 @@ +package content.region.misthalin.monastery.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; + +/** + * Represents the abbot langley dialogue. + * @author Vexia + * @version 1.0 + */ +@Initializable +public final class AbbotLangleyDialogue extends DialoguePlugin { + + /** + * Represents the healing animation to use for the npc. + */ + private static final Animation ANIMATION = new Animation(717); + + /** + * Represents the healing craphics to use for the npc. + */ + private static final Graphics GRAPHICS = new Graphics(84); + + /** + * Constructs a new {@code AbbotLangleyDialogue} {@code Object}. + */ + public AbbotLangleyDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code AbbotLangleyDialogue} {@code Object}. + * @param player the player. + */ + public AbbotLangleyDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new AbbotLangleyDialogue(player); + } + + @Override + public boolean open(Object... args) { + if (args.length >= 1) { + if (args[0] instanceof NPC) { + npc = (NPC) args[0]; + } else { + npc("Only members of our order can go up there."); + stage = 23; + return true; + } + } + npc("Greetings traveller."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + if (player.getSavedData().getGlobalData().isJoinedMonastery()) { + interpreter.sendOptions("Select an Option", "Can you heal me? I'm injured.", "Isn't this place built a bit out the way?"); + } else { + interpreter.sendOptions("Select an Option", "Can you heal me? I'm injured.", "Isn't this place built a bit out the way?", "How do I get further into the monastery?"); + } + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + player("Can you heal me? I'm injured."); + stage = 10; + break; + case 2: + player("Isn't this place built a bit out of the way?"); + stage = 20; + break; + case 3: + player("How do I get further into the monastery?"); + stage = 30; + break; + } + break; + case 10: + npc("Ok."); + stage = 11; + break; + case 11: + player.getSkills().heal(((int) (player.getSkills().getStaticLevel(Skills.HITPOINTS) * 0.20))); + npc.animate(ANIMATION); + npc.graphics(GRAPHICS); + interpreter.sendDialogue("Abbot Langley places his hands on your head. You feel a little better."); + stage = 12; + break; + case 12: + end(); + break; + case 20: + npc("We like it that way actually! We get disturbed less. We still", "get rather a large amount of travellers looking for", "sanctuary and healing here as it is!"); + stage = 21; + break; + case 21: + end(); + break; + case 22: + npc("Only members of our order can go up there."); + stage++; + break; + case 23: + options("Well can I join your order?", "Oh, sorry."); + stage++; + break; + case 24: + switch (buttonId) { + case 1: + player("Well can I join your order?"); + stage = 26; + break; + case 2: + player("Oh, sorry."); + stage = 25; + break; + } + break; + case 25: + end(); + break; + case 26: + if (player.getSkills().getStaticLevel(Skills.PRAYER) < 31) { + npc("No. I am sorry, but I feel you are not devout enough."); + stage++; + } else { + npc("Ok, I see you are someone suitable for our order. You", "may join."); + stage = 31; + } + break; + case 27: + player.getPacketDispatch().sendMessage("You need a prayer level of 31 to join the order."); + end(); + break; + case 30: + npc("I'm sorry but only members of our order are allowed", "in the second level of the monastery."); + stage = 23; + break; + case 31: + player.getSavedData().getGlobalData().setJoinedMonastery(true); + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 801 }; + } +} diff --git a/Server/src/main/content/region/misthalin/monastery/dialogue/BrotherJeredDialogue.java b/Server/src/main/content/region/misthalin/monastery/dialogue/BrotherJeredDialogue.java new file mode 100644 index 0000000..e6103d2 --- /dev/null +++ b/Server/src/main/content/region/misthalin/monastery/dialogue/BrotherJeredDialogue.java @@ -0,0 +1,166 @@ +package content.region.misthalin.monastery.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.global.Skillcape; +import core.game.node.item.Item; +import org.rs09.consts.Items; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Handles the BrotherJeredDialogue dialogue. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class BrotherJeredDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code BrotherJeredDialogue} {@code Object}. + */ + public BrotherJeredDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code BrotherJeredDialogue} {@code Object}. + * @param player the player. + */ + public BrotherJeredDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new BrotherJeredDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + if(player.getInventory().contains(Items.UNBLESSED_SYMBOL_1716,1)){ + player("Can you bless this symbol for me?"); + stage = 10; + return true; + } + if(player.getInventory().contains(Items.HOLY_ELIXIR_13754,1) && player.getInventory().contains(Items.SPIRIT_SHIELD_13734,1)){ + player("Can you bless this spirit shield for me?"); + stage = 100; + return true; + } + if (Skillcape.isMaster(player, Skills.PRAYER)) { + player("Can I buy a Skillcape of Prayer?"); + stage = 2; + } else { + player("Praise to Saradomin!"); + stage = 0; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + npc("Yes! Praise he who brings life to this world."); + stage = 1; + break; + case 1: + case 12: + end(); + break; + case 2: + npc("Certainly! Right when you give me 99000 coins."); + stage = 3; + break; + case 3: + options("Okay, here you go.", "No"); + stage = 4; + break; + case 4: + switch (buttonId) { + case 1: + player("Okay, here you go."); + stage = 5; + break; + case 2: + end(); + break; + } + break; + case 5: + if (Skillcape.purchase(player, Skills.PRAYER)) { + npc("There you go! Enjoy."); + } + stage = 6; + break; + case 6: + end(); + break; + case 10: + npc("Sure thing! Just give me a moment, here..."); + stage++; + break; + case 11: + npc("There we go! I have laid the blessing of", "Saradomin upon it."); + player.getInventory().remove(new Item(Items.UNBLESSED_SYMBOL_1716)); + player.getInventory().add(new Item(Items.HOLY_SYMBOL_1718)); + stage++; + break; + case 100: + npc("Yes I certainly can, but for", "1,000,000 coins."); + stage++; + break; + case 101: + options("Okay, sounds good.","Oh, no thanks.."); + stage++; + break; + case 102: + switch(buttonId){ + case 1: + if(player.getInventory().contains(995,1000000)){ + player("Okay, sounds good!"); + stage = 110; + } else { + player("I'd like to but I don't have","the coin."); + stage = 120; + } + break; + case 2: + player("Oh. No, thank you, then."); + stage = 1000; + break; + } + break; + case 110: + npc("Here you are."); + if(player.getInventory().remove(new Item(Items.HOLY_ELIXIR_13754), new Item(Items.SPIRIT_SHIELD_13734),new Item(995,1000000))){ + player.getInventory().add(new Item(Items.BLESSED_SPIRIT_SHIELD_13736)); + } + stage++; + break; + case 111: + player("Thank you!"); + stage = 1000; + break; + case 120: + npc("That's too bad then."); + stage = 1000; + break; + case 1000: + end(); + break; + + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 802 }; + } +} diff --git a/Server/src/main/content/region/misthalin/monastery/handlers/MonasteryPlugin.java b/Server/src/main/content/region/misthalin/monastery/handlers/MonasteryPlugin.java new file mode 100644 index 0000000..f430630 --- /dev/null +++ b/Server/src/main/content/region/misthalin/monastery/handlers/MonasteryPlugin.java @@ -0,0 +1,41 @@ +package content.region.misthalin.monastery.handlers; + +import core.cache.def.impl.SceneryDefinition; +import core.game.global.action.ClimbActionHandler; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Handles the edgeville monastery. + * @author Vexia + */ +@Initializable +public final class MonasteryPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(2641).getHandlers().put("option:climb-up", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + switch (node.getId()) { + case 2641: + final boolean abbot = node.getLocation().equals(new Location(3057, 3483, 0)); + if (!player.getSavedData().getGlobalData().isJoinedMonastery()) { + player.getDialogueInterpreter().open(abbot ? 801 : 7727, true); + } else { + ClimbActionHandler.climbLadder(player, (Scenery) node, option); + } + break; + } + return true; + } + +} diff --git a/Server/src/main/content/region/misthalin/quest/asoulsbane/ASoulsBane.java b/Server/src/main/content/region/misthalin/quest/asoulsbane/ASoulsBane.java new file mode 100644 index 0000000..91f1f33 --- /dev/null +++ b/Server/src/main/content/region/misthalin/quest/asoulsbane/ASoulsBane.java @@ -0,0 +1,104 @@ +/* +package core.game.content.quest.members.asoulsbane; + +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.plugin.Initializable; +import core.game.content.quest.members.asoulsbane.SoulsBaneLaunaDialogue; +import core.plugin.PluginManager; +import content.data.Quests; + +*/ +/** + * Author: afaroutdude + *//* + +@Initializable +public class ASoulsBane extends Quest { + public ASoulsBane() { + super(Quests.A_SOULS_BANE, 115, 114, 1, 709, 0, 1, 1261); + } + + // config 710 does a lot of shit + // launa 3638 quest start? can disappear w/ config 710 + // launa 3639 ?? + // launa 3640 standing upright w/out staff + // sconfigrange 710 711 + // 2^0 Launa disappears + // 2^13 warning signs appear around rift entrance + // 2^11 rope appears at rift entrance + + // rage iface 315 + // rage config ??? + // fear black iface 317 + // fear ghost iface 318 + // https://www.youtube.com/watch?v=Ad5KUHV7duQ + // https://www.youtube.com/watch?v=bKaaEqmS9KU + + // animGFX 3804 630 - Get Angry In Tolna’s Rift + // anim 3807 - Tolna Awakens From Nightmare + // anim 3838 - Crawl Into Tolna’s Rift + + @Override + public Quest newInstance(Object object) { + PluginManager.definePlugins(new SoulsBaneLaunaDialogue(), new ASoulsBanePlugin()); + return this; + } + + protected enum JournalEntries { + a(0, 5,"I can start this quest by talking to !!Launa?? at the !!Rift

!!entrance north west of the dig site."), + b(5, 15, "I spoke with !!Launa?? next to the rift and she told me

about her lost !!Son.??"), + d(15, 20, "I heard Tolna's voice say, 'Why should I, Tolna, be

trapped in such a wretched place? Feel my ANGER!'"), + e(20, 25, "I beat the anger beasts in the rift."), + f(25, 30, "I heard Tolna's voice say, 'I'm trapped and it's so dark. I FEAR I may never escape this place. Mum, help me!'"), + g(30, 35, "I defeated the fear beasts in the rift."), + h(35, 40, "I heard Tolna's voice say, 'Where am I? How long have I been here? Am I still the person I once was? I hate my CONFUSION'"), + i(40, 45, "I conquered the beasts of confusion."), + j(45, 50, "I heard Tolna's voice say, 'What's the point? Why do I defy such HOPELESSNESS? No-one will ever help me.'"), + k(50, 55, "I overcame the emotion of hopelessness."), + l(55, 60, "I've discovered the physical form of Tolna, and his father."), + m(60, 70, "I fought Tolna and he appears to have returned to his human form."), + n(70, 100, "Tolna has repented and returned to the entrance of the rift."), + o(100, 110, "Tolna has set up a dungeon to help others avoid his mistakes."); + + int stageIntroduce; + int stageStrikeout; + String msg; + + JournalEntries(int stageIn, int stageOut, String msg) { + this.stageIntroduce = stageIn; + this.stageStrikeout = stageOut; + this.msg = msg; + } + } + + private int drawJournalSub(Player player, int questStage, int line) { + // todo this doesn't work right + for (JournalEntries stageLine : JournalEntries.values()) { + if (stageLine.stageIntroduce > questStage) + break; + + line(player, stageLine.msg, line++, stageLine.stageStrikeout <= questStage); + } + return line; + } + + + @Override + public void drawJournal(Player player, int stage) { + int line = 11; + super.drawJournal(player, stage); + + line = drawJournalSub(player, stage, line); + switch (stage) { + case 0: + line(player, "There are no minimum requirements.", line + 2); + break; + case 100: + line(player, "--- QUEST COMPLETE ---", line + 2); + default: + break; + } + } +} +*/ diff --git a/Server/src/main/content/region/misthalin/quest/asoulsbane/ASoulsBaneListeners.kt b/Server/src/main/content/region/misthalin/quest/asoulsbane/ASoulsBaneListeners.kt new file mode 100644 index 0000000..256c7e1 --- /dev/null +++ b/Server/src/main/content/region/misthalin/quest/asoulsbane/ASoulsBaneListeners.kt @@ -0,0 +1,27 @@ +package content.region.misthalin.quest.asoulsbane + +import core.api.* +import core.game.interaction.InteractionListener +import core.game.world.map.Location +import org.rs09.consts.Scenery +import content.data.Quests + +// Temporary access since the monsters in there drop nothing. +class ASoulsBaneListener : InteractionListener { + + companion object { + private val RIFT_IDS = intArrayOf(13967, 13968, 13969, 13970, 13971, 13972, 13973, 13974, 13975, 13976, 13977, 13978, 13979, 13980, 13981, 13982, 13983, 13984, 13985, 13986, 13987, 13988, 13989, 13990, 13991, 13992, 13993) + } + override fun defineListeners() { + on(RIFT_IDS, SCENERY, "enter") { player, _ -> + if (hasRequirement(player, Quests.A_SOULS_BANE)) { + teleport(player, Location(3297, 9824, 0)) + } + return@on true + } + on(Scenery.ROPE_13999, SCENERY, "climb-up") { player, _ -> + teleport(player, Location(3309, 3452, 0)) + return@on true + } + } +} diff --git a/Server/src/main/content/region/misthalin/quest/asoulsbane/ASoulsBanePlugin.java b/Server/src/main/content/region/misthalin/quest/asoulsbane/ASoulsBanePlugin.java new file mode 100644 index 0000000..98391ae --- /dev/null +++ b/Server/src/main/content/region/misthalin/quest/asoulsbane/ASoulsBanePlugin.java @@ -0,0 +1,163 @@ +/* +package core.game.content.quest.members.asoulsbane; + +import core.cache.def.impl.ObjectDefinition; +import org.rs09.consts.Items; +import core.game.interaction.MovementPulse; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.OptionHandler; +import core.game.interaction.UseWithHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import core.game.node.object.GameObject; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; +import core.plugin.PluginManager; + +*/ +/** + * Author: afaroutdude + *//* + + +public class ASoulsBanePlugin extends OptionHandler { + private static final int[] RIFT_IDS = {13967,13968,13969,13970,13971,13972,13973,13974,13975,13976,13977,13978,13979,13980,13981,13982,13983,13984,13985,13986,13987,13988,13989,13990,13991,13992,13993}; + private static final int[] OBJ_EXIT = {13878, 13901, 13904, 13932}; + private static final int WEAPONS_RACK = 13993; + private static final int FINAL_EXIT = 13933; + private static final int OBJ_CONFIG = 710; + //private static final Animation CLIMB_DOWN = new Animation(); + private static final Location ROPE_STAND_LOC = Location.create(3309, 3452, 0); + private static final Location RIFT_RAGE = Location.create(3015, 5244, 0); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + PluginManager.definePlugins(new SoulsBaneRiftRopeHandler()); + for (int obj : RIFT_IDS) { + ObjectDefinition.forId(obj).getHandlers().put("option:enter", this); + } + + for (int obj : OBJ_EXIT) { + ObjectDefinition.forId(obj).getHandlers().put("option:use", this); + } + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + final int id = node instanceof Item ? ((Item) node).getId() : ((GameObject) node).getId(); + GameObject object = node instanceof GameObject ? ((GameObject) node) : null; + Location dest = null; + Quest quest = player.getQuestRepository().getQuest(ASoulsBane.NAME); + + boolean isRift = false; + for (int obj : RIFT_IDS) { + if (id == obj) { + isRift = true; + break; + } + } + + if (isRift) { + switch (quest.getStage(player)) { + case 0: + case 5: + player.getPacketDispatch().sendMessage("You can't just jump down there."); + break; + case 10: + player.getPulseManager().run(new MovementPulse(player, ROPE_STAND_LOC) { + @Override + public boolean pulse() { + return false; + } + + // todo this is janky, what's the better way to do this? Make sure you run to rope before descending + @Override + public void stop() { + player.lock(); + GameWorld.getPulser().submit(new Pulse(1, player) { + int counter = 1; + + @Override + public boolean pulse() { + switch (counter++) { + case 1: + player.animate(new Animation(3838)); + break; + case 3: + // todo there should be a fade to black here + break; + case 6: + player.teleport(RIFT_RAGE); + player.getAnimator().reset(); + player.getAchievementDiaryManager().finishTask(player, DiaryType.VARROCK, 1, 9); + player.unlock(); + return true; + } + return false; + } + }); + } + }, "movement"); + } + return true; + } + + boolean isEarlyExit = false; + for (int obj : OBJ_EXIT) { + if (id == obj) { + isEarlyExit = true; + break; + } + } + + if (isEarlyExit) { + player.teleport(ROPE_STAND_LOC); + } + + return false; + } + + public class SoulsBaneRiftRopeHandler extends UseWithHandler { + public SoulsBaneRiftRopeHandler() { + super(Items.ROPE_954); + } + + @Override + public Location getDestination(Player player, Node node) { + return ROPE_STAND_LOC; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + Item usedItem = event.getUsedItem(); + final Quest quest = player.getQuestRepository().getQuest(ASoulsBane.NAME); + final GameObject object = event.getUsedWith().asObject(); + + if (quest.getStage(player) == 5 && usedItem.getId() == Items.ROPE_954) { + player.getConfigManager().set(OBJ_CONFIG, player.getConfigManager().get(OBJ_CONFIG) | 1<<11, true); + player.getInventory().remove(usedItem); + quest.setStage(player, 10); + return true; + } + + return false; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (int id : RIFT_IDS) { + addHandler(id, OBJECT_TYPE, this); + } + return this; + } + } +} +*/ diff --git a/Server/src/main/content/region/misthalin/quest/asoulsbane/SoulsBaneLaunaDialogue.kt b/Server/src/main/content/region/misthalin/quest/asoulsbane/SoulsBaneLaunaDialogue.kt new file mode 100644 index 0000000..94525db --- /dev/null +++ b/Server/src/main/content/region/misthalin/quest/asoulsbane/SoulsBaneLaunaDialogue.kt @@ -0,0 +1,85 @@ +/* +package rs09.game.content.quest.members.asoulsbane + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.content.quest.members.asoulsbane.ASoulsBane +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest + +*/ +/** + * Launa + * @author afaroutdude + *//* + +class SoulsBaneLaunaDialogue(player: Player? = null) : DialoguePlugin(player) { + lateinit var quest: Quest + + override fun open(vararg args: Any?): Boolean { + player?.let { + player("Hi there.") + quest = it.questRepository.getQuest(ASoulsBane.NAME) + //quest = it.questRepository.getQuest(ASoulsBane.NAME) + when (quest.getStage(player)) { + 0 -> { + stage = 0 + } + 5, 10 -> stage = 999 + } + return true + } + return false + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 999 -> end() + + 0 -> npc(FacialExpression.SAD, "Hello.").also { stage++ } + 1 -> player("What's this big hole in the ground all about?").also { stage++ } + 2 -> npc(FacialExpression.SAD, "Oh I wish I knew for sure... All I do know is that it", "opened seemingly by itself a few months ago. It was", "first discovered by the students over at the digsite, a", "few of which have gone down there but never returned.").also { stage++ } + 3 -> npc(FacialExpression.SAD, "They told me about it straight away.").also { stage++ } + 4 -> player("So why is it important to you?").also { stage++ } + 5 -> npc(FacialExpression.SAD, "A few reasons, but I think the situation is beyond help", "now.").also { stage++ } + 6 -> player("What situation? Maybe I can help.").also { stage++ } + 7 -> npc(FacialExpression.SAD, "I suppose it wouldn't hurt to tell you. I'm waiting to", "see my son Tolna. Don't suppose you've seen him?").also { stage++ } + 8 -> player("Your son, Tolna? I don't know, what does he look like?").also { stage++ } + 9 -> npc(FacialExpression.SAD, "I don't really know.").also { stage++ } + 10 -> player("You don't know what your own son looks like?").also { stage++ } + 11 -> npc(FacialExpression.SAD, "No. You see, I haven't seen him for... for... 25 years", "now. He just ran away one day and never returned.", "I'm hoping he's down this rift as I know he headed in", "this direction. My husband went to look, but he hasn't").also { stage++ } + 12 -> npc(FacialExpression.SAD, "returned for days.").also { stage++ } + 13 -> options("Would you like me to go down to look for your husband and son?", "Surely by now they'd both be dead?").also { stage++ } + 14 -> + when (buttonId) { + 1 -> player("Would you like me to go down to look for your", "husband and son?").also { stage = 20 } + 2 -> player("Surely by now they'd both be dead?").also { stage++ } + } + 15 -> npc(FacialExpression.ANGRY, "What?!?!").also { stage++ } + 16 -> player("Oops.").also { stage++ } + 17 -> npc(FacialExpression.ANGRY, "How could you say such a thing? Get away from me!").also { stage = 999 } + + 20 -> npc("You would do that? Oh thank you so much!").also { stage++ } + 21 -> player("Don't worry. I'll investigate.").also { stage++ } + 22 -> npc("Thank you. You can use a rope to get into the rift,", "just attach it at the edge.").also { stage++ } + 23 -> player("No problem.").also { stage++ } + 24 -> { + npc("Be careful.") + stage = 999 + quest.setStage(player, 5) + player.questRepository.syncronizeTab(player) + println(quest.getStage(player)) + } + } + return true; + } + + + override fun newInstance(player: Player?): DialoguePlugin { + return SoulsBaneLaunaDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(3638, 3639, 3640) + } +}*/ diff --git a/Server/src/main/content/region/misthalin/quest/priestinperil/DoorPerilDialogue.java b/Server/src/main/content/region/misthalin/quest/priestinperil/DoorPerilDialogue.java new file mode 100644 index 0000000..c21b288 --- /dev/null +++ b/Server/src/main/content/region/misthalin/quest/priestinperil/DoorPerilDialogue.java @@ -0,0 +1,145 @@ +package content.region.misthalin.quest.priestinperil; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.global.action.DoorActionHandler; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.plugin.Initializable; +import core.game.node.scenery.Scenery; +import content.data.Quests; + +/** + * Represents the door peril dialogue. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class DoorPerilDialogue extends DialoguePlugin { + + /** + * Represents the scenery door. + */ + private Scenery door; + + /** + * Constructs a new {@code DoorPerilDialogue} {@code Object}. + */ + public DoorPerilDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code DoorPerilDialogue} {@code Object}. + * @param player the player. + */ + public DoorPerilDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new DoorPerilDialogue(player); + } + + @Override + public boolean open(Object... args) { + door = (Scenery) args[0]; + Quest quest = player.getQuestRepository().getQuest(Quests.PRIEST_IN_PERIL); + if (quest.getStage(player) == 10) { + interpreter.sendDialogue("You knock at the door...You hear a voice from inside.", "Who are you, and what do you want?"); + stage = 0; + } + if (quest.getStage(player) == 12) {// just killed dog. + interpreter.sendDialogue("You knock at the door...You hear a voice from inside.", "You again?", "What do you want now?"); + stage = 11; + } + if (quest.getStage(player) >= 13) { + interpreter.sendDialogue("You knock at the door...The door swings open as you knock."); + stage = 20; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Ummmm....."); + stage = 1; + break; + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Roald sent me to check on Drezel."); + stage = 2; + break; + case 2: + interpreter.sendDialogue("(Psst... Hey... Who's Roald? Who's Drezel?)(Uh... isn't Drezel that", "dude upstairs? Oh, wait, Roald's the King of Varrock right?)(He is???", "Aw man... Hey, you deal with this okay?) He's just coming! Wait a", "second!Hello, my name is Drevil. (Drezel!) I mean Drezel."); + stage = 3; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Well, as I say, the King sent me to make sure", "everything's okay with you."); + stage = 4; + break; + case 4: + interpreter.sendDialogue("And, uh, what would you do if everything wasn't okay with me?"); + stage = 5; + break; + case 5: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'm not sure. Ask you what help you need I suppose."); + stage = 6; + break; + case 6: + interpreter.sendDialogue("Ah, good, well, I don't think... (Psst... hey... the dog!) OH! Yes, of", "course! Will you do me a favour adventurer?"); + stage = 7; + break; + case 7: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Sure. I'm a helpful person!"); + stage = 8; + break; + case 8: + interpreter.sendDialogue("HAHAHAHA! Really? Thanks buddy! You see that mausoleum out", "there? There's a horrible big dog underneath it that I'd like you to", "kill for me! It's been really bugging me! Barking all the time and", "stuff! Please kill it for me buddy!"); + stage = 9; + break; + case 9: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Okey-dokey, one dead dog coming up."); + stage = 10; + break; + case 10: + Quest quest = player.getQuestRepository().getQuest(Quests.PRIEST_IN_PERIL); + quest.setStage(player, 11); + end(); + break; + case 11: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I killed that dog for you."); + stage = 12; + break; + case 12: + interpreter.sendDialogue("HAHAHAHAHA! Really? Hey, that's great! Yeah thanks a lot buddy!", "HAHAHAHAHAHA"); + stage = 13; + break; + case 13: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What's so funny?"); + stage = 14; + break; + case 14: + interpreter.sendDialogue("HAHAHAHA nothing buddy! We're just so grateful to you!", "HAHAHA Yeah, maybe you should go tell the King what a great job", "you did buddy! HAHAHA"); + stage = 15; + break; + case 15: + end(); + break; + case 20: + end(); + DoorActionHandler.handleDoor(player, door); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 54584 }; + } +} diff --git a/Server/src/main/content/region/misthalin/quest/priestinperil/DrezelDialogue.java b/Server/src/main/content/region/misthalin/quest/priestinperil/DrezelDialogue.java new file mode 100644 index 0000000..4d06a70 --- /dev/null +++ b/Server/src/main/content/region/misthalin/quest/priestinperil/DrezelDialogue.java @@ -0,0 +1,385 @@ +package content.region.misthalin.quest.priestinperil; + +import core.cache.def.impl.NPCDefinition; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.plugin.Initializable; +import core.game.node.item.Item; +import content.data.Quests; + +/** + * Represents the dialogue plugin used for the drezel npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class DrezelDialogue extends DialoguePlugin { + + /** + * Represents the array of items related to drezel. + */ + private static final Item[] ITEMS = new Item[] { new Item(2953), new Item(2954) }; + + /** + * Constructs a new {@code DrezelDialogue} {@code Object}. + */ + public DrezelDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code DrezelDialogue} {@code Object}. + * @param player the player. + */ + public DrezelDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new DrezelDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + npc.setName("Drezel"); + NPCDefinition.forId(getIds()[0]).setName("Drezel"); + Quest quest = player.getQuestRepository().getQuest(Quests.PRIEST_IN_PERIL); + if (quest.getStage(player) == 13) { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hello."); + stage = 0; + } else if (quest.getStage(player) == 14) { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "How does it adventurer? Any luck in finding the key to", "the cell or a way of stopping the vampire yet?"); + stage = 600; + } else if (quest.getStage(player) == 15) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "The key fitted the lock! You're free to leave now!"); + stage = 701; + } else if (quest.getStage(player) == 16) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I poured the blessed water over the vampires coffin. I", "think that should trap him in there long enough for you", "to escape."); + stage = 800; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + final Quest quest = player.getQuestRepository().getQuest(Quests.PRIEST_IN_PERIL); + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Oh! You do not appear to be on of those Zamorakians", "who imprisoned me here! Who are you and why are", "you here?"); + stage = 1; + break; + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "My name's " + player.getUsername() + ". King Roald sent me to find", "out what was going on at the temple. I take it you are", "Drezel?"); + stage = 2; + break; + case 2: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "That is right! Oh, praise be to Saradomin! All is not yet", "lost! I feared that when those Zamorakians attacked this", "place and imprisoned"); + stage = 3; + break; + case 3: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "me up here, Misthalin would be doomed! If they should", "manage to desecrate the holy river Salve we would be", "defenceless against Morytania!"); + stage = 4; + break; + case 4: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "How is a river a good defence then?"); + stage = 5; + break; + case 5: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Well, it is a long tale, and I am not sure we have time!"); + stage = 6; + break; + case 6: + interpreter.sendOptions("Select an Option", "Tell me anyway.", "You're right, we don't."); + stage = 7; + break; + case 7: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Tell me anyway. I'd like to know the full facts before","acting any further."); + stage = 8; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "You're right, we don't."); + stage = 500; + break; + } + break; + case 8: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ah, Saradomin has granted you wisdom I see. Well, the", "story of the river Salve and of how it protects Misthalin", "is the story of this temple,"); + stage = 9; + break; + case 9: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "and of the seven warrior priests who died here long ago,", "from whom I am descended. Once long ago Misthalin", "did not have the borders that"); + stage = 10; + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "it currently does. This entire area, as far West as", "Varrock itself was under the control of an evil god.", "There was frequent skirmishing"); + stage = 11; + break; + case 11: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "along the borders, as the brave heroes of Varrock", "fought to keep the evil creatures that now are trapped", "on the eastern side of the River Salve from over", "running"); + stage = 12; + break; + case 12: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "the human encampments, who worshipped Saradomin.", "Then one day, Saradomin himself appeared to one of", "our mighty heroes, whose name has been forgotten by", "history,"); + stage = 13; + break; + case 13: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "and told him that should we be able to take the pass that", "this temple now stands in, Saradomin would use his", "power to bless this river, and make it"); + stage = 14; + break; + case 14: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "impassable to all creatures with evil in their hearts. This", "unknown hero grouped together all of the mightiest", "fighters whose hearts were pure"); + stage = 15; + break; + case 15: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "that he could find, and the seven of them rode here to", "make a final stand. The enemies swarmed across the", "Salve but they did not yield."); + stage = 16; + break; + case 16: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "For ten days and nights they fought, never sleeping,", "never eating, fuelled by their desire to make the world a", "better place for humans to live."); + stage = 17; + break; + case 17: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "On the eleventh day they were to be joined by", "reinforcements from a neighbouring encampment, but", "then those reinforcements arrived all they found"); + stage = 18; + break; + case 18: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "were the bodies of these seven brave but unknown", "heroes, surrounded by the piles of the dead creatures of", "evil that had tried to defeat them."); + stage = 19; + break; + case 19: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "The men were saddened at the loss of such pure and", "mighty warriors, yet their sacrifice had not been in", "vain; for the water of the Salve"); + stage = 20; + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "had indeed been filled with the power of Saradomin, and", "the evil creatures of Morytania were trapped beyond", "the river banks forever, by their own evil."); + stage = 21; + break; + case 21: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "In memory of this brave sacrifice my ancestors built", "this temple so that the land would always be free of the", "evil creatures"); + stage = 22; + break; + case 22: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "who wish to destroy it, and laid the bodies of those brave", "warriors in tombs of honour below this temple with", "golden gifts on the tombs as marks of respect."); + stage = 23; + break; + case 23: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "They also built a statue on the river mouth so that all", "who mighty try and cross into Misthalin from Morytania", "would know that these lands are protected"); + stage = 24; + break; + case 24: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "by the glory of Saradomin and that good will always", "defeat evil, no matter how the odds are stacked against", "them."); + stage = 25; + break; + case 25: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Ok, I can see how the river protects the border, but I", "can't see how anything could affect that from this", "temple."); + stage = 26; + break; + case 26: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Well, as much as it saddens me to say so adventurer,", "Lord Saradomin's presence has not been felt on the", "land for many years now, and even"); + stage = 27; + break; + case 27: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "though all true Saradominists know that he watches over", "us, his power upon the land is not as strong as it once", "was."); + stage = 28; + break; + case 28: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I fear that should those Zamorakians somehow pollute", "the Salve and desecrate his blessing, his power might not", "be able to stop"); + stage = 29; + break; + case 29: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "the army of evil that lurks to the east, longing for the", "opportunity to invade and destroy us all!"); + stage = 30; + break; + case 30: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "So what do you say adventurer? Will you aid me and", "all of Misthalin in foiling this Zamorakian plot?"); + stage = 31; + break; + case 31: + interpreter.sendOptions("Select an Option", "Yes.", "No."); + stage = 503; + break; + case 500: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Well, let's just say if we cannot undo whatever damage", "has been done here the entire land is in grave peril!"); + stage = 501; + break; + case 501: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "So what do you say adventurer? Will you aid me and", "all of Misthalin in foiling this Zamorakian plot?"); + stage = 31; + break; + case 503: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Yes, of course. Any threat to Misthalin must be", "neutralised immediately. So what can I do to help?"); + stage = 506; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "HA! NO! You can rot in there for all I care you", "stupid priest! All hail mighty Zamorak! Death to puny", "Misthalin!"); + stage = 504; + break; + } + break; + case 504: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Oooooh... I knew it was too good to be true... then", "leave me to my fate villain, there's no need to taunt me", "as well as keeping me imprisoned."); + stage = 505; + break; + case 505: + end(); + break; + case 506: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Well, the immediate problem is that I am trapped in this", "cell. I know that the key to free me is nearby, for none", "of the Zamorakians"); + stage = 507; + break; + case 507: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "who imprisoned me here were ever gone for long", "periods of time. Should you find the key however, as", "you may have noticed,"); + stage = 508; + break; + case 508: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "there is a vampire in that coffin over there. I do not", "know how they managed to find it, but it is one of the", "ones that somehow"); + stage = 509; + break; + case 509: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "survived the battle here all those years ago, and is by", "now quite, quite, mad. It has been trapped on this side", "of the river for centuries,"); + stage = 510; + break; + case 510: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "and as those fiendish Zamorakians pointed out to me", "with delight, as a descendant of one of those who", "trapped it here, it will recognise"); + stage = 511; + break; + case 511: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "the smell of my blood should I come anywhere near it.", "It will of course then wake up and kill me, very", "probably slowly and painfully."); + stage = 512; + break; + case 512: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Maybe I could kill it somehow then while it is asleep?"); + stage = 513; + break; + case 513: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "No adventurer, I do not think it would be wise for you", "to wake it at all. As I say, it is little more than a wild", "animal, and must"); + stage = 514; + break; + case 514: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "be extremely powerful to have survived until today. I", "suspect your best chance would be to incapacitate it", "somehow."); + stage = 515; + break; + case 515: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Okay, find the key to your cell, and do something about", "the vampire."); + stage = 516; + break; + case 516: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "When you have done both of those I will be able to", "inspect the damage which those Zamorakians have done", "to the purity of the Salve."); + stage = 517; + break; + case 517: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Depending on the severity of the damage, I may", "require further assistance from you in restoring its", "purity."); + stage = 518; + break; + case 518: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Okay, well first thing's first; let's get you out of here."); + stage = 519; + break; + case 519: + quest.setStage(player, 14); + end(); + break; + case 600: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No, not yet..."); + stage = 601; + break; + case 601: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Well don't give up adventurer! That key MUST be", "around here somewhere! I know none of those", "Zamorakians ever got very far from this building!"); + stage = 602; + break; + case 602: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "How do you know that?"); + stage = 603; + break; + case 603: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I could hear them laughing about some gullible fool that", "they tricked into killing the guard dog at the", "monument."); + stage = 604; + break; + case 604: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Oh."); + stage = 605; + break; + case 605: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Honestly, what kind of idiot would go around killing", "things just because a stranger told them to? What kind", "of oafish, numb-skulled, dim-witted,"); + stage = 606; + break; + case 606: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Okay, OKAY, I get the picture!"); + stage = 607; + break; + case 607: + end(); + break; + case 701: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Well excellent work adventurer! Unfortunately, as you", "know, I cannot risk waking that vampire in the coffin."); + stage = 702; + break; + case 702: + if (player.getInventory().contains(2953, 1)) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I have some water from the Salve. It seems to have", "been desecrated though. Do you think you could bless", "it for me?"); + stage = 703; + } else { + + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Do you have any idea about dealing with vampire?"); + stage = 730; + } + break; + case 703: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Yes, good thinking adventurer! Give it to me, I will bless", "it!"); + stage = 704; + break; + case 704: + if (!player.getInventory().containsItem(ITEMS[0])) { + end(); + return true; + } + if (player.getInventory().remove(ITEMS[0])) { + player.getInventory().add(ITEMS[1]); + } + end(); + player.getPacketDispatch().sendMessage("The priest blesses the water for you."); + break; + case 730: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "well, the water of the salve should still have enough", "power to work against the vampire despite what those", "Zamorakians might have done to it..."); + stage = 731; + break; + case 731: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Maybe you should try and get hold of some from", "somewhere?"); + stage = 732; + break; + case 732: + end(); + break; + case 800: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Excellent work adventurer! I am free at last! Let me", "ensure that evil vampire is trapped for good. I will", "meet you down by the monument."); + stage = 801; + break; + case 801: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Look for me down there, I need to assess what damage", "has been done to our holy barrier by those evil", "Zamorakians!"); + stage = 802; + break; + case 802: + Quest quests = player.getQuestRepository().getQuest(Quests.PRIEST_IN_PERIL); + quests.setStage(player, 17); + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 7690 }; + } +} diff --git a/Server/src/main/content/region/misthalin/quest/priestinperil/DrezelMonumentDialogue.java b/Server/src/main/content/region/misthalin/quest/priestinperil/DrezelMonumentDialogue.java new file mode 100644 index 0000000..06c77b5 --- /dev/null +++ b/Server/src/main/content/region/misthalin/quest/priestinperil/DrezelMonumentDialogue.java @@ -0,0 +1,288 @@ +package content.region.misthalin.quest.priestinperil; + +import static core.api.ContentAPIKt.*; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.plugin.Initializable; +import core.game.node.item.Item; +import org.rs09.consts.NPCs; +import content.region.morytania.quest.naturespirit.NSDrezelDialogue; + +import static core.tools.DialogueConstKt.END_DIALOGUE; +import content.data.Quests; + +/** + * Represents the dialogue plugin used for the drezel monument. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class DrezelMonumentDialogue extends DialoguePlugin { + + /** + * Represents the items related to the drezel monument. + */ + private static final Item[] ITEMS = new Item[] { new Item(1436), new Item(7936) }; + + /** + * Constructs a new {@code DrezelMonumentDialogue} {@code Object}. + */ + public DrezelMonumentDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code DrezelMonumentDialogue} {@code Object}. + * @param player the player. + */ + public DrezelMonumentDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new DrezelMonumentDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + Quest quest = player.getQuestRepository().getQuest(Quests.PRIEST_IN_PERIL); + if (quest.getStage(player) == 17) { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ah, " + player.getUsername() + ". I see you finally made it down here.", "Things are worse than I feared. I'm not sure if I will", "be able to repair the damage."); + stage = 900; + return true; + } + if (quest.getStage(player) == 18) { + if (player.getInventory().contains(1436, 1) || player.getInventory().contains(7936, 1)) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I brought you some Rune Essence."); + stage = 100; + } else { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "How many more essence do I need to bring you?"); + stage = 120; + } + return true; + } + if (quest.getStage(player) == 100 && !player.getSavedData().getQuestData().isTalkedDrezel()) { // guy. + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "So can I pass through that barrier now?"); + stage = 400; + return true; + } + + /*else { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Greetings again adventurer, How go your travels in", "Morytania? Is it as evil as I have heard?"); + stage = 420; + }*/ + + quest = player.getQuestRepository().getQuest(Quests.NATURE_SPIRIT); + + if(quest.getStage(player) <= 5){ + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Greetings again adventurer, How go your travels in", "Morytania? Is it as evil as I have heard?"); + stage = 420; + } else if (quest.getStage(player) < 100){ + openDialogue(player, new NSDrezelDialogue(), npc); + } else { + npcl(FacialExpression.NEUTRAL, "I heard you finished your quest with Filliman! Great work!"); + stage = END_DIALOGUE; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + final Quest quest = player.getQuestRepository().getQuest(Quests.PRIEST_IN_PERIL); + switch (stage) { + case 400: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ah, " + player.getUsername() + ". For all the assistance you have given", "both myself and Misthalin in your actions, I cannot let", "you pass without warning you."); + stage = 401; + break; + case 401: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Morytania is an evil land, filled with creatures and", "monsters more terrifying than any you have yet", "encountered. Although I will pray for you"); + stage = 402; + break; + case 402: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "you should take some basic precautions before heading", "over the Salve into it. The first place you will come", "across is the Werewolf trading post."); + stage = 403; + break; + case 403: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "In many ways Werewolves are like you and me, except", "never forget that they are evil vicious beasts at heart.", "The dagger I have given you is named 'Wolfbane'"); + stage = 404; + break; + case 404: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "and it is a holy relic that prevents the werewolf people from", "changing form, I suggest if you battle with them", "that you keep it always equipped, for their"); + stage = 405; + break; + case 405: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "wolf form is incredibly powerful, and would savage you", "very quickly. Please adventurer, promise me this: I", "should hate for you to die foolishly."); + stage = 406; + break; + case 406: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Okay, I will keep it equipped whenever I fight", "werwolves."); + stage = 407; + break; + case 407: + player.getSavedData().getQuestData().setTalkedDrezel(true); + end(); + break; + case 420: + options("Well, I'm going to look around a bit more.", "Is there anything else interesting to do around here?"); + stage = 421; + break; + case 421: + switch(buttonId){ + case 1: + playerl(FacialExpression.FRIENDLY, "Well, I'm going to look around a bit more."); + stage++; + break; + case 2: + playerl(FacialExpression.HALF_THINKING, "Is there anything else interesting to do around here?"); + stage = 425; + break; + } + break; + case 422: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Well, that sounds like a good idea. Don't get into any", "trouble though!"); + stage = 423; + break; + case 423: + end(); + break; + case 425: + npcl(FacialExpression.HALF_THINKING, "Well, not a great deal... but there is something you can do for me if you're interested. Though it is quite dangerous."); + stage++; + break; + case 426: + end(); + player.getDialogueInterpreter().open(new NSDrezelDialogue(), npc); + player.getDialogueInterpreter().handle(0,0); + break; + case 120: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I need " + player.getGameAttributes().getAttribute("priest-in-peril:rune", 50) + " more."); + stage = 121; + break; + case 121: + end(); + break; + case 100: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Quickly, give it to me!"); + stage = 101; + break; + case 101: + int amt = player.getInventory().contains(1436, 1) ? player.getInventory().getAmount(ITEMS[0]) : player.getInventory().getAmount(ITEMS[1]); + player.getInventory().remove(player.getInventory().contains(1436, 1) ? new Item(1436, amt) : new Item(7936, amt)); + int runes = player.getGameAttributes().getAttribute("priest-in-peril:rune", 50); + if (runes > amt) { + amt = runes - amt; + } + if (amt > runes) { + amt = 0; + } + if (amt == runes) { + amt = amt - runes; + } + if (amt < 0) { + amt = 0; + } + player.getGameAttributes().setAttribute("/save:priest-in-peril:rune", amt); + if (player.getGameAttributes().getAttribute("priest-in-peril:rune", 50) <= 0) { + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Excellent! That should do it! I will bless these stones", "and place them within the well, and Misthalin should be", "protected once more!"); + stage = 152; + } else { + end(); + } + break; + case 152: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Please take this dagger; it has been handed down within", "my family for generations and is filled with the power of", "Saradomin. You will find that"); + stage = 153; + break; + case 153: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "it has the power to prevent werewolves from adopting", "their wolf form in combat as long as you have it", "equipped."); + stage = 154; + break; + case 154: + quest.finish(player); + end(); + break; + case 900: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Why, what happened?"); + stage = 901; + break; + case 901: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "From what I can tell, after you killed the guard dog", "who protected the entrance to the monuments, those", "Zamorakians forced the door into the main chamber"); + stage = 902; + break; + case 902: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "and have used some kind of evil potion upon the well", "which leads to the source of the river Salve. As they", "have done this at the very mouth of the river"); + stage = 903; + break; + case 903: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "it will spread along the entire river, disrupting the", "blessing placed upon it and allowing the evil creatures of", "Morytania to invade at their leisure."); + stage = 904; + break; + case 904: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What can we do to prevent that?"); + stage = 905; + break; + case 905: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Well, as you can see, I have placed a holy barrier on", "the entrance to this room from the South, but it is not", "very powerful and required me to remain"); + stage = 906; + break; + case 906: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "here focussing upon it to keep it intact. Should an", "attack come, they would be able to breach this defence", "very quickly indeed. What we need to do is"); + stage = 907; + break; + case 907: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "find some kind of way of removing or counteracting the", "evil magic that has been put into the river source at the", "well, so that the river will flow pure once again."); + stage = 908; + break; + case 908: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Couldn't you bless the river to purify it? Like you did", "with the water I took from the well?"); + stage = 909; + break; + case 909: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "No, that would not work, the power I have from", "Saradomin is not great enough to cleanse an entire", "river of this foul Zamorakian pollutant."); + stage = 910; + break; + case 910: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I have only one idea how we could possibly cleanse the", "river."); + stage = 911; + break; + case 911: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What's that?"); + stage = 912; + break; + case 912: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I have heard rumours recently that Mages have found", "some secret ore that absorbs magic into it and allows", "them to create runes."); + stage = 913; + break; + case 913: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Should you be able to collect enough of this ore, it is", "possible it will soak up the evil potion that has been", "poured into the river, and purify it."); + stage = 914; + break; + case 914: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Kind of like a filter? Okay, I guess it's worth a try.", "How many should I get?"); + stage = 915; + break; + case 915: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Well, I have no knowledge of these ores other than", "speculation and gossip, but if the things I hear are true", "around fifty should be sufficient for the task."); + stage = 916; + break; + case 916: + quest.setStage(player, 18); + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { NPCs.DREZEL_7707 }; + } +} diff --git a/Server/src/main/content/region/misthalin/quest/priestinperil/KingRoaldPIPDialogue.kt b/Server/src/main/content/region/misthalin/quest/priestinperil/KingRoaldPIPDialogue.kt new file mode 100644 index 0000000..d8f8f35 --- /dev/null +++ b/Server/src/main/content/region/misthalin/quest/priestinperil/KingRoaldPIPDialogue.kt @@ -0,0 +1,96 @@ +package content.region.misthalin.quest.priestinperil + +import core.game.dialogue.DialogueFile +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import content.data.Quests + + +class KingRoaldPIPDialogue(val questStage: Int) : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + + if(stage == START_DIALOGUE){ + npc("Well, hello there. What do you want?").also { stage++ } + return + } + + if(questStage == 0){ + when(stage){ + 1 -> player("I am looking for a quest!").also { stage++ } + 2 -> npc("A quest you say? Hmm, what an odd request to make", "of the king. It's funny you should mention it though, as", "there is something you can do for me.").also { stage++ } + 3 -> npc("Are you aware of the temple east of here? It stands on", "the river Salve and guards the entrance to the lands of", "Morytania?").also { stage++ } + 4 -> player("No, I don't think I know it...").also { stage++ } + 5 -> npc("Hmm, how strange that you don't. Well anyway, it has", "been some days since last I heard from Drezel, the", "priest who lives there.").also { stage++ } + 6 -> npc("Be a sport and go make sure that nothing untoward", "has happened to the silly old codger for me, would you?").also { stage++ } + 7 -> options("Sure.", "No, that sounds boring.").also { stage++ } + 8 -> when(buttonID){ + 1 -> { + player("Sure. I don't have anything better to do right now.") + player!!.questRepository.getQuest(Quests.PRIEST_IN_PERIL).start(player) + stage++ + } + 2 -> { + npc("Yes, I dare say it does. I wouldn't even have", "mentioned it had you not seemed to be looking for", "something to do anyway.") + stage = END_DIALOGUE + } + } + 9 -> npc("Many thanks adventurer! I would have sent one of my", "squires but they wanted payment for it!").also { stage = END_DIALOGUE } + } + } + + else if(questStage <= 11){ + when(stage){ + 1 -> npc("You have news of Drezel for me?").also { stage++ } + 2 -> player("No, not yet.").also { stage++ } + 3 -> npc("I would wish you would go check on my dear friend.").also { stage = END_DIALOGUE } + } + } + + else if(questStage == 12){ + when(stage){ + 1 -> npc("You have news of Drezel for me?").also { stage++ } + 2 -> player("Yeah, I spoke to the guys at the temple and they said", "they were being bothered by that dog in the crypt, so I", "went and killed it for them. No problem.").also { stage++ } + 3 -> npc("YOU DID WHAT???").also { stage++ } + 4 -> npc("Are you mentally deficient??? That guard dog was", "protecting the route to Morytania! Without it we could", "be in severe peril of attack!").also { stage++ } + 5 -> player("Did I make a mistake?").also { stage++ } + 6 -> npc("YES YOU DID!!!!! You need to get there right now", "and find out what is happening! Before it is too late for", "us all!").also { stage++ } + 7 -> player("B-but Drezel TOLD me to...!").also { stage++ } + 8 -> npc("No, you absolute cretin! Obviously some fiend has done", "something to Drezel and tricked your feeble intellect", "into helping them kill that guard dog!").also { stage++ } + 9 -> npc("You get back there and do whatever is necessary to", "safeguard my kingdom from attack, or I will see you", "beheaded for high treason!").also { stage++ } + 10 -> { + player("Y-yes your Highness.") + player!!.questRepository.getQuest(Quests.PRIEST_IN_PERIL).setStage(player,13) + stage = END_DIALOGUE + } + } + } + + else if(questStage == 13){ + when(stage){ + 1 -> npc("AND MORE IMPORTANTLY, WHY HAVEN'T", "YOU ENSURED THE BORDER TO", "MORYTANIA IS SECURE YET?").also { stage++ } + 2 -> player("Okay, okay, I'm going, I'm going.... There's no need to", "shout...").also { stage++ } + 3 -> npc("NO NEED TO SHOUT?!").also { stage++ } + 4 -> npc("Listen, and listen well, and see if your puny mind can", "comprehend this; if the border is not protected, then we", "are at the mercy of the evil beings").also { stage++ } + 5 -> npc("that live in Morytania. Given the most of the", "inhabitants consider humans to be nothing more than", "over talkative snack foods, I would").also { stage++ } + 6 -> npc("say that me shouting at you for your incompetence is", "the LEAST of your worries right now, NOW GO!").also { stage = END_DIALOGUE } + } + } + + else if(questStage == 14){ + when(stage){ + 1 -> player("I'm looking for a key to unlock Drezel!").also { stage = END_DIALOGUE } + } + } + + else if(questStage == 15 || questStage == 16 || questStage == 17){ + when(stage){ + 1 -> player("I'm helping Drezel!").also { stage = END_DIALOGUE } + } + } + + else { + abandonFile() + } + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/quest/priestinperil/MonkOfZamorakNPC.java b/Server/src/main/content/region/misthalin/quest/priestinperil/MonkOfZamorakNPC.java new file mode 100644 index 0000000..9ca6c99 --- /dev/null +++ b/Server/src/main/content/region/misthalin/quest/priestinperil/MonkOfZamorakNPC.java @@ -0,0 +1,72 @@ +package content.region.misthalin.quest.priestinperil; + +import core.game.node.entity.Entity; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.game.world.map.Location; +import content.data.Quests; + +/** + * Represents the monk of zamorak npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class MonkOfZamorakNPC extends AbstractNPC { + + /** + * The NPC ids of NPCs using this plugin. + */ + private static final int[] ID = { 1046 }; + + /** + * Represents the golden key. + */ + private static final Item GOLDEN_KEY = new Item(2944, 1); + + /** + * Constructs a new {@code MonkOfZamorakNPC} {@code Object}. + */ + public MonkOfZamorakNPC() { + super(0, null); + } + + /** + * Constructs a new {@code AlKharidWarriorPlugin} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + private MonkOfZamorakNPC(int id, Location location) { + super(id, location); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new MonkOfZamorakNPC(id, location); + } + + @Override + public void tick() { + super.tick(); + } + + @Override + public void finalizeDeath(final Entity killer) { + super.finalizeDeath(killer); + final Player p = ((Player) killer); + final Quest quest = p.getQuestRepository().getQuest(Quests.PRIEST_IN_PERIL); + if (quest.isStarted(p)) { + GroundItemManager.create(GOLDEN_KEY, getLocation(), p); + } + } + + @Override + public int[] getIds() { + return ID; + } + +} diff --git a/Server/src/main/content/region/misthalin/quest/priestinperil/PriestInPeril.java b/Server/src/main/content/region/misthalin/quest/priestinperil/PriestInPeril.java new file mode 100644 index 0000000..c14d08d --- /dev/null +++ b/Server/src/main/content/region/misthalin/quest/priestinperil/PriestInPeril.java @@ -0,0 +1,192 @@ +package content.region.misthalin.quest.priestinperil; + +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import content.data.Quests; + +/** + * Represents the Quest priest in peril. + * @author 'Vexia + */ +@Initializable +public class PriestInPeril extends Quest { + + /** + * Constructs a new {@code PriestInPeril} {@code Object}. + */ + public PriestInPeril() { + super(Quests.PRIEST_IN_PERIL, 99, 98, 1, 302, 0, 1, 100); + } + + @Override + public void drawJournal(Player player, int stage) { + super.drawJournal(player, stage); + switch (stage) { + case 0: + player.getPacketDispatch().sendString("I can start this quest by speaking to King Roald in Varrock", 275, 4+ 7); + player.getPacketDispatch().sendString("Palace", 275, 5+ 7); + player.getPacketDispatch().sendString("I must be able to defeat a level 30 enemy", 275, 7+ 7); + break; + case 10: + player.getPacketDispatch().sendString("I spoke to King Roald who asked me to investigate why his", 275, 4+ 7); + player.getPacketDispatch().sendString("friend Priest Drezel has stopped communicating with him.", 275, 5+ 7); + player.getPacketDispatch().sendString("Drezel lives in a temple to the east of Varrock Palace. I", 275, 7+ 7); + player.getPacketDispatch().sendString("should head there and investigate what's happened to him", 275, 8+ 7); + break; + case 11: + player.getPacketDispatch().sendString("I spoke to King Roald who asked me to investigate why his", 275, 4+ 7); + player.getPacketDispatch().sendString("friend Priest Drezel has stopped communicating with him.", 275, 5+ 7); + player.getPacketDispatch().sendString("I headed to the temple where Drezel lives, but it was all", 275, 6+ 7); + player.getPacketDispatch().sendString("locked shut. I spoke through the locked door to Drezel.", 275, 7+ 7); + player.getPacketDispatch().sendString("He told me that there was an annoying dog below the", 275, 8+ 7); + player.getPacketDispatch().sendString("temple, and has asked me to kill it for him.", 275, 9+ 7); + break; + case 12: + player.getPacketDispatch().sendString("I spoke to King Roald who asked me to investigate why his", 275, 4+ 7); + player.getPacketDispatch().sendString("friend Priest Drezel has stopped communicating with him.", 275, 5+ 7); + player.getPacketDispatch().sendString("I headed to the temple where Drezel lives, but it was all", 275, 6+ 7); + player.getPacketDispatch().sendString("locked shut. I spoke through the locked door to Drezel.", 275, 7+ 7); + player.getPacketDispatch().sendString("He told me that there was an annoying dog below the", 275, 8+ 7); + player.getPacketDispatch().sendString("temple, and asked me to kill it, which I did easily.", 275, 9+ 7); + player.getPacketDispatch().sendString("I should tell King Roald everything's fine with Drezel now I", 275, 11+ 7); + player.getPacketDispatch().sendString("have killed that dog for him, and claim my reward.", 275, 12+ 7); + break; + case 13: + player.getPacketDispatch().sendString("I spoke to King Roald who asked me to investigate why his", 275, 4+ 7); + player.getPacketDispatch().sendString("friend Priest Drezel has stopped communicating with him.", 275, 5+ 7); + player.getPacketDispatch().sendString("I headed to the temple where Drezel lives, but it was all", 275, 6+ 7); + player.getPacketDispatch().sendString("locked shut. I spoke through the locked door to Drezel.", 275, 7+ 7); + player.getPacketDispatch().sendString("He told me that there was an annoying dog below the", 275, 8+ 7); + player.getPacketDispatch().sendString("temple, and asked me to kill it, which I did easily.", 275, 9+ 7); + player.getPacketDispatch().sendString("When I told Roald what I had done, he was furious. The", 275, 10+ 7); + player.getPacketDispatch().sendString("person who told me to kill the dog wasn't Drezel at all!", 275, 11+ 7); + player.getPacketDispatch().sendString("I must return to the temple and find out what happened to", 275, 13+ 7); + player.getPacketDispatch().sendString("the real Drezel, or the King will have me executed!", 275, 14+ 7); + break; + case 14: + player.getPacketDispatch().sendString("I spoke to King Roald who asked me to investigate why his", 275, 4+ 7); + player.getPacketDispatch().sendString("friend Priest Drezel has stopped communicating with him.", 275, 5+ 7); + player.getPacketDispatch().sendString("I headed to the temple where Drezel lives, but it was all", 275, 6+ 7); + player.getPacketDispatch().sendString("locked shut. I spoke through the locked door to Drezel.", 275, 7+ 7); + player.getPacketDispatch().sendString("He told me that there was an annoying dog below the", 275, 8+ 7); + player.getPacketDispatch().sendString("temple, and asked me to kill it, which I did easily.", 275, 9+ 7); + player.getPacketDispatch().sendString("When I told Roald what I had done, he was furious. The", 275, 10+ 7); + player.getPacketDispatch().sendString("person who told me to kill the dog wasn't Drezel at all!", 275, 11+ 7); + player.getPacketDispatch().sendString("I returned to the temple and found the real Drezel locked", 275, 12+ 7); + player.getPacketDispatch().sendString("in a makeshift cell upstairs, guarded by a vampire.", 275, 13+ 7); + player.getPacketDispatch().sendString("I need to find the key to his cell and free him!", 275, 15+ 7); + break; + case 15: + player.getPacketDispatch().sendString("I spoke to King Roald who asked me to investigate why his", 275, 4+ 7); + player.getPacketDispatch().sendString("friend Priest Drezel has stopped communicating with him.", 275, 5+ 7); + player.getPacketDispatch().sendString("I headed to the temple where Drezel lives, but it was all", 275, 6+ 7); + player.getPacketDispatch().sendString("locked shut. I spoke through the locked door to Drezel.", 275, 7+ 7); + player.getPacketDispatch().sendString("He told me that there was an annoying dog below the", 275, 8+ 7); + player.getPacketDispatch().sendString("temple, and asked me to kill it, which I did easily.", 275, 9+ 7); + player.getPacketDispatch().sendString("When I told Roald what I had done, he was furious. The", 275, 10+ 7); + player.getPacketDispatch().sendString("person who told me to kill the dog wasn't Drezel at all!", 275, 11+ 7); + player.getPacketDispatch().sendString("I returned to the temple and found the real Drezel locked", 275, 12+ 7); + player.getPacketDispatch().sendString("in a makeshift cell upstairs, guarded by a vampire.", 275, 13+ 7); + player.getPacketDispatch().sendString("I used a key from the monument to open the cell door", 275, 14+ 7); + player.getPacketDispatch().sendString("but I still have to do something about that vampire", 275, 15+ 7); + break; + case 16: + player.getPacketDispatch().sendString("I spoke to King Roald who asked me to investigate why his", 275, 4+ 7); + player.getPacketDispatch().sendString("friend Priest Drezel has stopped communicating with him.", 275, 5+ 7); + player.getPacketDispatch().sendString("I headed to the temple where Drezel lives, but it was all", 275, 6+ 7); + player.getPacketDispatch().sendString("locked shut. I spoke through the locked door to Drezel.", 275, 7+ 7); + player.getPacketDispatch().sendString("He told me that there was an annoying dog below the", 275, 8+ 7); + player.getPacketDispatch().sendString("temple, and asked me to kill it, which I did easily.", 275, 9+ 7); + player.getPacketDispatch().sendString("When I told Roald what I had done, he was furious. The", 275, 10+ 7); + player.getPacketDispatch().sendString("person who told me to kill the dog wasn't Drezel at all!", 275, 11+ 7); + player.getPacketDispatch().sendString("I returned to the temple and found the real Drezel locked", 275, 12+ 7); + player.getPacketDispatch().sendString("in a makeshift cell upstairs, guarded by a vampire.", 275, 13+ 7); + player.getPacketDispatch().sendString("I used a key from the monument to open the cell door and", 275, 14+ 7); + player.getPacketDispatch().sendString("used Holy Water to trap the vampire in his coffin.", 275, 15+ 7); + player.getPacketDispatch().sendString("I should speak to Drezel again.", 275, 16+ 7); + break; + case 17: + player.getPacketDispatch().sendString("I spoke to King Roald who asked me to investigate why his", 275, 4+ 7); + player.getPacketDispatch().sendString("friend Priest Drezel has stopped communicating with him.", 275, 5+ 7); + player.getPacketDispatch().sendString("I headed to the temple where Drezel lives, but it was all", 275, 6+ 7); + player.getPacketDispatch().sendString("locked shut. I spoke through the locked door to Drezel.", 275, 7+ 7); + player.getPacketDispatch().sendString("He told me that there was an annoying dog below the", 275, 8+ 7); + player.getPacketDispatch().sendString("temple, and asked me to kill it, which I did easily.", 275, 9+ 7); + player.getPacketDispatch().sendString("When I told Roald what I had done, he was furious. The", 275, 10+ 7); + player.getPacketDispatch().sendString("person who told me to kill the dog wasn't Drezel at all!", 275, 11+ 7); + player.getPacketDispatch().sendString("I returned to the temple and found the real Drezel locked", 275, 12+ 7); + player.getPacketDispatch().sendString("in a makeshift cell upstairs, guarded by a vampire.", 275, 13+ 7); + player.getPacketDispatch().sendString("I used a key from the monument to open the cell door and", 275, 14+ 7); + player.getPacketDispatch().sendString("used Holy Water to trap the vampire in his coffin.", 275, 15+ 7); + player.getPacketDispatch().sendString("I should head downstairs to the monument like Drezel", 275, 16+ 7); + player.getPacketDispatch().sendString("asked me to, and asses what damage has been done.", 275, 17+ 7); + break; + case 18: + player.getPacketDispatch().sendString("I spoke to King Roald who asked me to investigate why his", 275, 4+ 7); + player.getPacketDispatch().sendString("friend Priest Drezel has stopped communicating with him.", 275, 5+ 7); + player.getPacketDispatch().sendString("I headed to the temple where Drezel lives, but it was all", 275, 6+ 7); + player.getPacketDispatch().sendString("locked shut. I spoke through the locked door to Drezel.", 275, 7+ 7); + player.getPacketDispatch().sendString("He told me that there was an annoying dog below the", 275, 8+ 7); + player.getPacketDispatch().sendString("temple, and asked me to kill it, which I did easily.", 275, 9+ 7); + player.getPacketDispatch().sendString("When I told Roald what I had done, he was furious. The", 275, 10+ 7); + player.getPacketDispatch().sendString("person who told me to kill the dog wasn't Drezel at all!", 275, 11+ 7); + player.getPacketDispatch().sendString("I returned to the temple and found the real Drezel locked", 275, 12+ 7); + player.getPacketDispatch().sendString("in a makeshift cell upstairs, guarded by a vampire.", 275, 13+ 7); + player.getPacketDispatch().sendString("I used a key from the monument to open the cell door and", 275, 14+ 7); + player.getPacketDispatch().sendString("used Holy Water to trap the vampire in his coffin.", 275, 15+ 7); + player.getPacketDispatch().sendString("I followed Drezel downstairs only to find that the Salve", 275, 16+ 7); + player.getPacketDispatch().sendString("had been contaminated and now needed purifying", 275, 17+ 7); + int amt = player.getGameAttributes().getAttribute("priest-in-peril:rune", 50); + player.getPacketDispatch().sendString("I need to bring " + amt + " rune essence to undo the damage", 275, 19+ 7); + player.getPacketDispatch().sendString("done by the Zamorakians and purify the salve", 275, 20+ 7); + break; + case 100: + player.getPacketDispatch().sendString("I spoke to King Roald who asked me to investigate why his", 275, 4+ 7); + player.getPacketDispatch().sendString("friend Priest Drezel has stopped communicating with him.", 275, 5+ 7); + player.getPacketDispatch().sendString("I headed to the temple where Drezel lives, but it was all", 275, 6+ 7); + player.getPacketDispatch().sendString("locked shut. I spoke through the locked door to Drezel.", 275, 7+ 7); + player.getPacketDispatch().sendString("He told me that there was an annoying dog below the", 275, 8+ 7); + player.getPacketDispatch().sendString("temple, and asked me to kill it, which I did easily.", 275, 9+ 7); + player.getPacketDispatch().sendString("When I told Roald what I had done, he was furious. The", 275, 10+ 7); + player.getPacketDispatch().sendString("person who told me to kill the dog wasn't Drezel at all!", 275, 11+ 7); + player.getPacketDispatch().sendString("I returned to the temple and found the real Drezel locked", 275, 12+ 7); + player.getPacketDispatch().sendString("in a makeshift cell upstairs, guarded by a vampire.", 275, 13+ 7); + player.getPacketDispatch().sendString("I used a key from the monument to open the cell door and", 275, 14+ 7); + player.getPacketDispatch().sendString("used Holy Water to trap the vampire in his coffin.", 275, 15+ 7); + player.getPacketDispatch().sendString("I followed Drezel downstairs only to find that the Salve", 275, 16+ 7); + player.getPacketDispatch().sendString("had been contaminated and now needed purifying", 275, 17+ 7); + player.getPacketDispatch().sendString("I brought Drezel fifty rune essences and the", 275, 18+ 7); + player.getPacketDispatch().sendString("contaminants were dissolved from the Salve, and Drezel", 275, 19+ 7); + player.getPacketDispatch().sendString("Rewarded me for all of my help with an ancient holy weapon", 275, 20+ 7); + player.getPacketDispatch().sendString("to fight with.", 275, 21+ 7); + player.getPacketDispatch().sendString("QUEST COMPLETE!", 275, 23+ 7); + break; + } + } + + @Override + public void finish(Player player) { + super.finish(player); + player.getGameAttributes().removeAttribute("priest-in-peril:rune"); + player.getPacketDispatch().sendString("1 Quest Point", 277, 8+ 2); + player.getPacketDispatch().sendString("1406 Prayer XP", 277, 9+ 2); + player.getPacketDispatch().sendString("Wolfbane dagger", 277, 10+ 2); + player.getPacketDispatch().sendString("Route to Canifis", 277, 11+ 2); + if (!player.getInventory().add(new Item(2952, 1))) { + GroundItemManager.create(new Item(2952, 1), player.getLocation(), player); + } + player.removeAttribute("priest_in_peril:key"); + player.removeAttribute("priest-in-peril:rune"); + player.getSkills().addExperience(Skills.PRAYER, 1406); + player.getPacketDispatch().sendItemZoomOnInterface(2952, 240, 277, 3+ 2); + } + + @Override + public Quest newInstance(Object object) { + return this; + } +} diff --git a/Server/src/main/content/region/misthalin/quest/priestinperil/PriestInPerilOptionPlugin.java b/Server/src/main/content/region/misthalin/quest/priestinperil/PriestInPerilOptionPlugin.java new file mode 100644 index 0000000..538afab --- /dev/null +++ b/Server/src/main/content/region/misthalin/quest/priestinperil/PriestInPerilOptionPlugin.java @@ -0,0 +1,283 @@ +package content.region.misthalin.quest.priestinperil; + +import core.cache.def.impl.NPCDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.game.component.Component; +import core.game.global.action.DoorActionHandler; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.scenery.Scenery; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.plugin.Plugin; +import org.rs09.consts.NPCs; +import content.data.Quests; + +/** + * Represents the quest node plugin handler. + * @author 'Vexia + */ +@Initializable +public class PriestInPerilOptionPlugin extends OptionHandler { + + /** + * (non-Javadoc) + * @see Plugin#newInstance(Object) + */ + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(3444).getHandlers().put("option:open", this); + /** the gate in the chamber near the dog. */ + SceneryDefinition.forId(3445).getHandlers().put("option:open", this); + /** the gate in the temple to get to the other side. */ + SceneryDefinition.forId(30707).getHandlers().put("option:open", this); + /** the "knock-at" door. */ + SceneryDefinition.forId(30707).getHandlers().put("option:knock-at", this); + /** the "knock-at" door. */ + SceneryDefinition.forId(30708).getHandlers().put("option:open", this); + /** the "knock-at" door. */ + SceneryDefinition.forId(30708).getHandlers().put("option:knock-at", this); + /** the "knock-at" door. */ + SceneryDefinition.forId(30575).getHandlers().put("option:climb-up", this); + /** represents the ladder to climb back up. */ + SceneryDefinition.forId(30575).getHandlers().put("option:climb-up", this); + /** represents the ladder to climb back up. */ + SceneryDefinition.forId(30728).getHandlers().put("option:open", this); + /** the coffin. */ + SceneryDefinition.forId(3463).getHandlers().put("option:open", this); + /** the drezel door. */ + SceneryDefinition.forId(3463).getHandlers().put("option:talk-through", this); + /** talk-through. */ + SceneryDefinition.forId(3485).getHandlers().put("option:search", this); + /** teh well. */ + SceneryDefinition.forId(3496).getHandlers().put("option:study", this); + /** teh golden hammer */ + SceneryDefinition.forId(3496).getHandlers().put("option:take-from", this); + /** the golden hammer. */ + SceneryDefinition.forId(3498).getHandlers().put("option:study", this); + /** teh golden needle. */ + SceneryDefinition.forId(3498).getHandlers().put("option:take-from", this); + /** the golden needle. */ + SceneryDefinition.forId(3495).getHandlers().put("option:study", this); + /** teh golden pot. */ + SceneryDefinition.forId(3495).getHandlers().put("option:take-from", this); + /** the golden pot. */ + SceneryDefinition.forId(3497).getHandlers().put("option:study", this); + /** teh golden feather. */ + SceneryDefinition.forId(3497).getHandlers().put("option:take-from", this); + /** the golden feather. */ + SceneryDefinition.forId(3494).getHandlers().put("option:study", this); + /** teh golden candle. */ + SceneryDefinition.forId(3494).getHandlers().put("option:take-from", this); + /** the golden candle. */ + SceneryDefinition.forId(3499).getHandlers().put("option:study", this); + /** teh golden key/iron. */ + SceneryDefinition.forId(3499).getHandlers().put("option:take-from", this); + /** the golden key/iron */ + SceneryDefinition.forId(3493).getHandlers().put("option:study", this); + /** teh tinder box. */ + SceneryDefinition.forId(3493).getHandlers().put("option:take-from", this); + /** the golden tinder box. */ + SceneryDefinition.forId(3443).getHandlers().put("option:pass-through", this); + /** the barrier. */ + SceneryDefinition.forId(30573).getHandlers().put("option:open", this); + /** the door to get back. */ + NPCDefinition.forId(7711).getHandlers().put("option:attack", this); + /** represents the dog attack option. */ + SceneryDefinition.forId(30571).getHandlers().put("option:open", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + final Quest quest = player.getQuestRepository().getQuest(Quests.PRIEST_IN_PERIL); + int id = node instanceof Scenery ? ((Scenery) node).getId() : ((NPC) node).getId(); + switch (option) { + case "study": + player.getInterfaceManager().open(new Component(272)); + int item = 0; + String message = ""; + if (id == 3496) { + if (!player.getGameAttributes().getAttribute("priest_in_peril:hammer", false)) { + item = 2949; + } else { + item = 2347; + } + player.getPacketDispatch().sendItemZoomOnInterface(item, 512, 272, 4); + player.getPacketDispatch().sendAngleOnInterface(272, 4, 512, 128, 0); + message = "Saradomin is the hammer that crushes evil everywhere."; + } + if (id == 3498) { + if (!player.getGameAttributes().getAttribute("priest_in_peril:needle", false)) { + item = 2951; + } else { + item = 1733; + } + player.getPacketDispatch().sendItemZoomOnInterface(item, 512, 272, 4); + player.getPacketDispatch().sendAngleOnInterface(272, 4, 512, 128, 0); + message = "Saradomin is the needle that binds our lives together."; + } + if (id == 3495) { + if (!player.getGameAttributes().getAttribute("priest_in_peril:pot", false)) { + item = 2948; + } else { + item = 1931; + } + player.getPacketDispatch().sendItemZoomOnInterface(item, 512, 272, 4); + player.getPacketDispatch().sendAngleOnInterface(272, 4, 512, 128, 0); + message = "Saradomin is the vessel that keeps our lives from harm."; + } + if (id == 3497) { + if (!player.getGameAttributes().getAttribute("priest_in_peril:feather", false)) { + item = 2950; + } else { + item = 314; + } + player.getPacketDispatch().sendItemZoomOnInterface(item, 512, 272, 4); + player.getPacketDispatch().sendAngleOnInterface(272, 4, 512, 128, 0); + message = "Saradomin is the delicate touch that brushes us with love."; + } + if (id == 3494) { + if (!player.getGameAttributes().getAttribute("priest_in_peril:candle", false)) { + item = 2947; + } else { + item = 36; + } + player.getPacketDispatch().sendItemZoomOnInterface(item, 512, 272, 4); + player.getPacketDispatch().sendAngleOnInterface(272, 4, 512, 256, 0); + message = "Saradomin is the light that shines throughout our lives."; + } + if (id == 3499) { + if (!player.getGameAttributes().getAttribute("priest_in_peril:key", false)) { + item = 2945; + } else { + item = 2944; + } + player.getPacketDispatch().sendItemZoomOnInterface(item, 512, 272, 4); + player.getPacketDispatch().sendAngleOnInterface(272, 4, 512, 256, 0); + message = "Saradomin is the key that unlocks the mysteries of life."; + } + if (id == 3493) { + if (!player.getGameAttributes().getAttribute("priest_in_peril:tinderbox", false)) { + item = 2946; + } else { + item = 590; + } + player.getPacketDispatch().sendItemZoomOnInterface(item, 320, 272, 4); + player.getPacketDispatch().sendAngleOnInterface(272, 4, 320, 256, 0); + message = "Saradomin is the spark that lights the fire in our hearts."; + } + player.getPacketDispatch().sendString(message, 272, 17); + // In SD, this is fine. in HD, this gets clipped when you zoom out too much or zoom in too much. + //player.getPacketDispatch().sendItemZoomOnInterface(item, 175, 272, 4); + break; + case "take-from": + player.getImpactHandler().handleImpact(player, 2, CombatStyle.MELEE); + player.getPacketDispatch().sendMessage("A holy power prevents you stealing from the monument!"); + break; + } + switch (id) { + case 3444: + /** the first gate we encounter. */ + if (quest.getStage(player) <= 13) { + player.getDialogueInterpreter().sendDialogues(player, null, "Hmmm... from the looks of things, it seems as though", "somebody has been trying to force this door open. It's", "still securely locked however."); + return true; + } + DoorActionHandler.handleDoor(player, (Scenery) node); + break; + case 30573: + player.getProperties().setTeleportLocation(Location.create(3440, 9887, 0)); + player.getPacketDispatch().sendMessage("You cilmb down through the trap door..."); + break; + case 3443: + /** the barrier. */ + if (!player.getQuestRepository().isComplete(Quests.PRIEST_IN_PERIL)) { + player.getPacketDispatch().sendMessage("A magic force prevents you from passing through."); + } else { + player.getProperties().setTeleportLocation(Location.create(3425, 3485, 0)); + player.getPacketDispatch().sendMessage("You pass through the holy barrier."); + } + break; + case 3485: + /** the well. */ + player.getDialogueInterpreter().sendDialogue("You look down the well and see the filthy polluted water of the river", "Salve moving slowly along."); + break; + case 3463: + /** the drezel door. */ + switch (option) { + case "open": + + if (quest.getStage(player) < 15) { + player.getPacketDispatch().sendMessage("The door is securely locked shut."); + } else { + DoorActionHandler.handleDoor(player, (Scenery) node); + } + break; + case "talk-through": + player.getDialogueInterpreter().open(NPCs.DREZEL_7690, NPC.create(NPCs.DREZEL_7690, player.getLocation())); + break; + } + break; + case 30728: + /** the coffin. */ + player.getDialogueInterpreter().sendDialogues(player, null, "It sounds like there's something alive inside it. I don't", "think it would be a very good idea to open it..."); + break; + case 3445:/* the other gate. */ + if (quest.getStage(player) < 17) { + player.getPacketDispatch().sendMessage("The door is locked shut."); + } else { + DoorActionHandler.handleDoor(player, (Scenery) node); + } + break; + case 30707:/** the door to the church. */ + case 30708: + switch (option) { + case "open": + if (quest.getStage(player) > 12) { + DoorActionHandler.handleDoor(player, (Scenery) node); + } else { + player.getPacketDispatch().sendMessage("This door is securely locked from inside."); + } + break; + case "knock-at": + if (quest.getStage(player) == 10 || quest.getStage(player) == 12 || quest.getStage(player) == 13) { + player.getDialogueInterpreter().open(54584, node); + } + break; + } + break; + case 30575: + /** represents the ladder to get back up. */ + player.getProperties().setTeleportLocation(Location.create(3405, 3506, 0)); + break; + case 7711: + /** the dog. */ + if (quest.getStage(player) == 10) { + player.getPacketDispatch().sendMessage("You have no reason to attack a helpless dog!"); + return true; + } + if (quest.getStage(player) > 10) { + player.getProperties().getCombatPulse().attack(node); + } + if (quest.getStage(player) == 12) { + player.getPacketDispatch().sendMessage("You've already killed that dog!"); + return true; + } + if (quest.getStage(player) >= 13) { + player.getProperties().getCombatPulse().stop(); + player.getPacketDispatch().sendMessage("I'd better not make the King mad at me again!"); + return true; + } + break; + case 30571: + player.getProperties().setTeleportLocation(Location.create(3405, 9906, 0)); + break; + } + return true; + } + +} diff --git a/Server/src/main/content/region/misthalin/quest/priestinperil/PriestInPerilUseListener.kt b/Server/src/main/content/region/misthalin/quest/priestinperil/PriestInPerilUseListener.kt new file mode 100644 index 0000000..61a36a6 --- /dev/null +++ b/Server/src/main/content/region/misthalin/quest/priestinperil/PriestInPerilUseListener.kt @@ -0,0 +1,132 @@ +package content.region.misthalin.quest.priestinperil + +import core.api.* +import core.game.node.item.Item +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import content.data.Quests + +/** + * Listener for Priest in Peril usage interactions + * @author Byte + */ +class PriestInPerilUseListener : InteractionListener { + + override fun defineListeners() { + onUseWith(IntType.SCENERY, Items.TINDERBOX_590, Scenery.MONUMENT_3493) { player, used, _ -> + if (!getAttribute(player, "priest_in_peril:tinderbox", false) && removeItem(player, used)) { + addItem(player, Items.GOLDEN_TINDERBOX_2946) + sendMessage(player, "You swap the tinderbox for the golden tinderbox.") + setAttribute(player, "/save:priest_in_peril:tinderbox", true) + } + + return@onUseWith true + } + + onUseWith(IntType.SCENERY, Items.CANDLE_36, Scenery.MONUMENT_3494) { player, used, _ -> + if (!getAttribute(player, "priest_in_peril:candle", false) && removeItem(player, used)) { + addItem(player, Items.GOLDEN_CANDLE_2947) + sendMessage(player, "You swap the candle for the golden candle.") + setAttribute(player, "/save:priest_in_peril:candle", true) + } + + return@onUseWith true + } + + onUseWith(IntType.SCENERY, Items.EMPTY_POT_1931, Scenery.MONUMENT_3495) { player, used, _ -> + if (!getAttribute(player, "priest_in_peril:pot", false) && removeItem(player, used)) { + addItem(player, Items.GOLDEN_POT_2948) + sendMessage(player, "You swap the pot for the golden pot.") + setAttribute(player, "/save:priest_in_peril:pot", true) + } + + return@onUseWith true + } + + onUseWith(IntType.SCENERY, Items.HAMMER_2347, Scenery.MONUMENT_3496) { player, used, _ -> + if (!getAttribute(player, "priest_in_peril:hammer", false) && removeItem(player, used)) { + addItem(player, Items.GOLDEN_HAMMER_2949) + sendMessage(player, "You swap the hammer for the golden hammer.") + setAttribute(player, "/save:priest_in_peril:hammer", true) + } + + return@onUseWith true + } + + onUseWith(IntType.SCENERY, Items.FEATHER_314, Scenery.MONUMENT_3497) { player, used, _ -> + if (!getAttribute(player, "priest_in_peril:feather", false) && removeItem(player, Item(used.id, 1))) { + addItem(player, Items.GOLDEN_FEATHER_2950) + sendMessage(player, "You swap the feather for the golden feather.") + setAttribute(player, "/save:priest_in_peril:feather", true) + } + + return@onUseWith true + } + + onUseWith(IntType.SCENERY, Items.NEEDLE_1733, Scenery.MONUMENT_3498) { player, used, _ -> + if (!getAttribute(player, "priest_in_peril:needle", false) && removeItem(player, Item(used.id, 1))) { + addItem(player, Items.GOLDEN_NEEDLE_2951) + sendMessage(player, "You swap the needle for the golden needle.") + setAttribute(player, "/save:priest_in_peril:needle", true) + } + + return@onUseWith true + } + + onUseWith(IntType.SCENERY, Items.GOLDEN_KEY_2944, Scenery.MONUMENT_3499) { player, used, _ -> + // See GL #2112 and sources therein for why we do it this way + val hasNeverGrabbedKey = !getAttribute(player, "priest_in_peril:key", false) + val needsKeyForQuestStage = getQuestStage(player, Quests.PRIEST_IN_PERIL) <= 15 + val hasTotallyLostKey = !hasAnItem(player, Items.IRON_KEY_2945, true).exists() + val giveNewKey = hasNeverGrabbedKey || (needsKeyForQuestStage && hasTotallyLostKey) + if (giveNewKey && removeItem(player, used)) { + addItem(player, Items.IRON_KEY_2945) + sendMessage(player, "You swap the golden key for the iron key.") + setAttribute(player, "/save:priest_in_peril:key", true) + } + + return@onUseWith true + } + + onUseWith(IntType.SCENERY, Items.BUCKET_1925, Scenery.WELL_3485) { player, used, _ -> + if (!removeItem(player, used)) { + return@onUseWith false + } + + addItem(player, Items.BUCKET_OF_WATER_2953) + sendMessage(player, "You fill the bucket from the well.") + + return@onUseWith true + } + + onUseWith(IntType.SCENERY, Items.IRON_KEY_2945, Scenery.CELL_DOOR_3463) { player, used, _ -> + if (!removeItem(player, used)) { + return@onUseWith false + } + + setQuestStage(player, Quests.PRIEST_IN_PERIL, 15) + sendMessage(player, "You have unlocked the cell door.") + + val npc = core.game.node.entity.npc.NPC.create(NPCs.DREZEL_7690, player.location) + npc.name = "Drezel" + sendNPCDialogue(player, npc.id, "Oh! Thank you! You have found the key!", core.game.dialogue.FacialExpression.HALF_GUILTY) + + return@onUseWith true + } + + onUseWith(IntType.SCENERY, Items.BUCKET_OF_WATER_2954, Scenery.MORYTANIA_COFFIN_30728) { player, used, _ -> + if (!removeItem(player, used)) { + return@onUseWith false + } + + addItem(player, Items.BUCKET_1925) + setQuestStage(player, Quests.PRIEST_IN_PERIL, 16) + sendMessage(player, "You pour the blessed water over the coffin...") + + return@onUseWith true + } + } +} diff --git a/Server/src/main/content/region/misthalin/quest/priestinperil/TempleGuardianNPC.java b/Server/src/main/content/region/misthalin/quest/priestinperil/TempleGuardianNPC.java new file mode 100644 index 0000000..23dcd52 --- /dev/null +++ b/Server/src/main/content/region/misthalin/quest/priestinperil/TempleGuardianNPC.java @@ -0,0 +1,64 @@ +package content.region.misthalin.quest.priestinperil; + +import core.game.node.entity.Entity; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.plugin.Initializable; +import core.game.world.map.Location; +import content.data.Quests; + +/** + * Handles the temple guardian npc. + * @author 'Vexia + */ +@Initializable +public class TempleGuardianNPC extends AbstractNPC { + + /** + * The NPC ids of NPCs using this plugin. + */ + private static final int[] ID = { 7711 }; + + /** + * Constructs a new {@code AlKharidWarriorPlugin} {@code Object}. + */ + public TempleGuardianNPC() { + super(0, null); + } + + /** + * Constructs a new {@code AlKharidWarriorPlugin} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + private TempleGuardianNPC(int id, Location location) { + super(id, location); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new TempleGuardianNPC(id, location); + } + + @Override + public void tick() { + super.tick(); + } + + @Override + public void finalizeDeath(final Entity killer) { + super.finalizeDeath(killer); + final Player p = ((Player) killer); + final Quest quest = p.getQuestRepository().getQuest(Quests.PRIEST_IN_PERIL); + if (quest.getStage(p) == 11) { + quest.setStage(p, 12); + } + } + + @Override + public int[] getIds() { + return ID; + } + +} diff --git a/Server/src/main/content/region/misthalin/silvarea/dialogue/OddOldManDialogue.kt b/Server/src/main/content/region/misthalin/silvarea/dialogue/OddOldManDialogue.kt new file mode 100644 index 0000000..6497914 --- /dev/null +++ b/Server/src/main/content/region/misthalin/silvarea/dialogue/OddOldManDialogue.kt @@ -0,0 +1,25 @@ +package content.region.misthalin.silvarea.dialogue + +import content.region.misthalin.silvarea.quest.ragandboneman.OddOldManDialogueFile +import core.api.openDialogue +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class OddOldManDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + // Fallback to default. Always the start of Rag and Bone Man + openDialogue(player!!, OddOldManDialogueFile(), npc) + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return OddOldManDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.ODD_OLD_MAN_3670) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/BatBehavior.kt b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/BatBehavior.kt new file mode 100644 index 0000000..932997b --- /dev/null +++ b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/BatBehavior.kt @@ -0,0 +1,30 @@ +package content.region.misthalin.silvarea.quest.ragandboneman + +import content.data.Quests +import core.api.isQuestInProgress +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.tools.RandomFunction +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class BatBehavior : NPCBehavior(*batIds) { + companion object { + private val batIds = intArrayOf( + NPCs.BAT_412 + ) + } + + override fun onDropTableRolled(self: NPC, killer: Entity, drops: ArrayList) { + super.onDropTableRolled(self, killer, drops) + // Drops the Bat Wing during Rag and Bone Man quest + if (killer is Player && isQuestInProgress(killer, Quests.RAG_AND_BONE_MAN, 1, 99)) { + if(RandomFunction.roll(4)) { + drops.add(Item(Items.BAT_WING_7833)); + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/BearBehavior.kt b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/BearBehavior.kt new file mode 100644 index 0000000..c489832 --- /dev/null +++ b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/BearBehavior.kt @@ -0,0 +1,36 @@ +package content.region.misthalin.silvarea.quest.ragandboneman + +import content.data.Quests +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.tools.RandomFunction +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class BearBehavior : NPCBehavior(*bearIds) { + companion object { + private val bearIds = intArrayOf( + NPCs.GRIZZLY_BEAR_105, + NPCs.BLACK_BEAR_106, + NPCs.GRIZZLY_BEAR_1195, + NPCs.GRIZZLY_BEAR_CUB_1196, + NPCs.GRIZZLY_BEAR_CUB_1197, + NPCs.BEAR_CUB_1326, + NPCs.BEAR_CUB_1327, + ) + } + + override fun onDropTableRolled(self: NPC, killer: Entity, drops: ArrayList) { + super.onDropTableRolled(self, killer, drops) + // Drops the Bear Ribs during Rag and Bone Man quest + if (killer is Player && isQuestInProgress(killer, Quests.RAG_AND_BONE_MAN, 1, 99)) { + if(RandomFunction.roll(4)) { + drops.add(Item(Items.BEAR_RIBS_7815)); + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/BigFrogBehavior.kt b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/BigFrogBehavior.kt new file mode 100644 index 0000000..cd4cd6c --- /dev/null +++ b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/BigFrogBehavior.kt @@ -0,0 +1,30 @@ +package content.region.misthalin.silvarea.quest.ragandboneman + +import content.data.Quests +import core.api.isQuestInProgress +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.tools.RandomFunction +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class BigFrogBehavior : NPCBehavior(*bigFrogIds) { + companion object { + private val bigFrogIds = intArrayOf( + NPCs.BIG_FROG_1829, + ) + } + + override fun onDropTableRolled(self: NPC, killer: Entity, drops: ArrayList) { + super.onDropTableRolled(self, killer, drops) + // Drops the Big Frog Leg during Rag and Bone Man quest + if (killer is Player && isQuestInProgress(killer, Quests.RAG_AND_BONE_MAN, 1, 99)) { + if(RandomFunction.roll(4)) { + drops.add(Item(Items.BIG_FROG_LEG_7908)); + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/BoneBoilerEnum.kt b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/BoneBoilerEnum.kt new file mode 100644 index 0000000..337a6c0 --- /dev/null +++ b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/BoneBoilerEnum.kt @@ -0,0 +1,65 @@ +package content.region.misthalin.silvarea.quest.ragandboneman + +import org.rs09.consts.Items + +enum class BoneBoilerEnum(val bone: Int, val boneInVinegar: Int, val polishedBone: Int, val boneDescription: String) { + GOBLIN_SKULL(Items.GOBLIN_SKULL_7812, Items.BONE_IN_VINEGAR_7813, Items.GOBLIN_SKULL_7814, "goblin bone"), + BEAR_RIBS(Items.BEAR_RIBS_7815, Items.BONE_IN_VINEGAR_7816, Items.BEAR_RIBS_7817, "bear bone"), + RAM_SKULL(Items.RAM_SKULL_7818, Items.BONE_IN_VINEGAR_7819, Items.RAM_SKULL_7820, "ram bone"), + UNICORN_BONE(Items.UNICORN_BONE_7821, Items.BONE_IN_VINEGAR_7822, Items.UNICORN_BONE_7823, "unicorn bone"), + GIANT_RAT_BONE(Items.GIANT_RAT_BONE_7824, Items.BONE_IN_VINEGAR_7825, Items.GIANT_RAT_BONE_7826, "giant rat bone"), + GIANT_BAT_WING(Items.GIANT_BAT_WING_7827, Items.BONE_IN_VINEGAR_7828, Items.GIANT_BAT_WING_7829, "giant bat bone"), + WOLF_BONE(Items.WOLF_BONE_7830, Items.BONE_IN_VINEGAR_7831, Items.WOLF_BONE_7832, "wolf bone"), + BAT_WING(Items.BAT_WING_7833, Items.BONE_IN_VINEGAR_7834, Items.BAT_WING_7835, "bat bone"), + RAT_BONE(Items.RAT_BONE_7836, Items.BONE_IN_VINEGAR_7837, Items.RAT_BONE_7838, "rat bone"), + BABY_DRAGON_BONE(Items.BABY_DRAGON_BONE_7839, Items.BONE_IN_VINEGAR_7840, Items.BABY_DRAGON_BONE_7841, "baby blue dragon bone"), + OGRE_RIBS(Items.OGRE_RIBS_7842, Items.BONE_IN_VINEGAR_7843, Items.OGRE_RIBS_7844, "ogre bone"), + JOGRE_BONE(Items.JOGRE_BONE_7845, Items.BONE_IN_VINEGAR_7846, Items.JOGRE_BONE_7847, "jogre bone"), + ZOGRE_BONE(Items.ZOGRE_BONE_7848, Items.BONE_IN_VINEGAR_7849, Items.ZOGRE_BONE_7850, "zogre bone"), + MOGRE_BONE(Items.MOGRE_BONE_7851, Items.BONE_IN_VINEGAR_7852, Items.MOGRE_BONE_7853, "mogre bone"), + MONKEY_PAW(Items.MONKEY_PAW_7854, Items.BONE_IN_VINEGAR_7855, Items.MONKEY_PAW_7856, "monkey bone"), + DAGANNOTH_RIBS(Items.DAGANNOTH_RIBS_7857, Items.BONE_IN_VINEGAR_7858, Items.DAGANNOTH_RIBS_7859, "Dagannoth bone"), + SNAKE_SPINE(Items.SNAKE_SPINE_7860, Items.BONE_IN_VINEGAR_7861, Items.SNAKE_SPINE_7862, "snake bone"), + ZOMBIE_BONE(Items.ZOMBIE_BONE_7863, Items.BONE_IN_VINEGAR_7864, Items.ZOMBIE_BONE_7865, "zombie bone"), + WEREWOLF_BONE(Items.WEREWOLF_BONE_7866, Items.BONE_IN_VINEGAR_7867, Items.WEREWOLF_BONE_7868, "werewolf bone"), + MOSS_GIANT_BONE(Items.MOSS_GIANT_BONE_7869, Items.BONE_IN_VINEGAR_7870, Items.MOSS_GIANT_BONE_7871, "moss giant bone"), + FIRE_GIANT_BONE(Items.FIRE_GIANT_BONE_7872, Items.BONE_IN_VINEGAR_7873, Items.FIRE_GIANT_BONE_7874, "fire giant bone"), + ICE_GIANT_RIBS(Items.ICE_GIANT_RIBS_7875, Items.BONE_IN_VINEGAR_7876, Items.ICE_GIANT_RIBS_7877, "ice giant bone"), + TERRORBIRD_WING(Items.TERRORBIRD_WING_7878, Items.BONE_IN_VINEGAR_7879, Items.TERRORBIRD_WING_7880, "terrorbird bone"), + GHOUL_BONE(Items.GHOUL_BONE_7881, Items.BONE_IN_VINEGAR_7882, Items.GHOUL_BONE_7883, "ghoul bone"), + TROLL_BONE(Items.TROLL_BONE_7884, Items.BONE_IN_VINEGAR_7885, Items.TROLL_BONE_7886, "troll bone"), + SEAGULL_WING(Items.SEAGULL_WING_7887, Items.BONE_IN_VINEGAR_7888, Items.SEAGULL_WING_7889, "seagull bone"), + UNDEAD_COW_RIBS(Items.UNDEAD_COW_RIBS_7890, Items.BONE_IN_VINEGAR_7891, Items.UNDEAD_COW_RIBS_7892, "undead cow bone"), + EXPERIMENT_BONE(Items.EXPERIMENT_BONE_7893, Items.BONE_IN_VINEGAR_7894, Items.EXPERIMENT_BONE_7895, "experiment bone"), + RABBIT_BONE(Items.RABBIT_BONE_7896, Items.BONE_IN_VINEGAR_7897, Items.RABBIT_BONE_7898, "rabbit bone"), + BASILISK_BONE(Items.BASILISK_BONE_7899, Items.BONE_IN_VINEGAR_7900, Items.BASILISK_BONE_7901, "basilisk bone"), + DESERT_LIZARD_BONE(Items.DESERT_LIZARD_BONE_7902, Items.BONE_IN_VINEGAR_7903, Items.DESERT_LIZARD_BONE_7904, "desert lizard bone"), + CAVE_GOBLIN_SKULL(Items.CAVE_GOBLIN_SKULL_7905, Items.BONE_IN_VINEGAR_7906, Items.CAVE_GOBLIN_SKULL_7907, "cave goblin bone"), + BIG_FROG_LEG(Items.BIG_FROG_LEG_7908, Items.BONE_IN_VINEGAR_7909, Items.BIG_FROG_LEG_7910, "big frog bone"), + VULTURE_WING(Items.VULTURE_WING_7911, Items.BONE_IN_VINEGAR_7912, Items.VULTURE_WING_7913, "vulture bone"), + JACKAL_BONE(Items.JACKAL_BONE_7914, Items.BONE_IN_VINEGAR_7915, Items.JACKAL_BONE_7916, "jackal bone"); + + companion object { + @JvmField + val boneList = BoneBoilerEnum.values().map { it.bone }.toIntArray() + + @JvmField + val boneInVinegarList = BoneBoilerEnum.values().map { it.boneInVinegar }.toIntArray() + + @JvmField + val boneMap = values().associateBy { it.bone } + + @JvmField + val boneInVinegarMap = values().associateBy { it.boneInVinegar } + + @JvmStatic + fun forBone(id: Int): BoneBoilerEnum? { + return boneMap[id] + } + + @JvmStatic + fun forBoneInVinegar(id: Int): BoneBoilerEnum? { + return boneInVinegarMap[id] + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/GiantBatBehavior.kt b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/GiantBatBehavior.kt new file mode 100644 index 0000000..0ffe434 --- /dev/null +++ b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/GiantBatBehavior.kt @@ -0,0 +1,39 @@ +package content.region.misthalin.silvarea.quest.ragandboneman + +import content.data.Quests +import core.api.isQuestInProgress +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.tools.RandomFunction +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class GiantBatBehavior : NPCBehavior(*giantBatIds) { + companion object { + private val giantBatIds = intArrayOf( + NPCs.GIANT_BAT_78, + NPCs.GIANT_BAT_1005, + NPCs.GIANT_BAT_2482, + NPCs.GIANT_BAT_2483, + NPCs.GIANT_BAT_2484, + NPCs.GIANT_BAT_2485, + NPCs.GIANT_BAT_2486, + NPCs.GIANT_BAT_2487, + NPCs.GIANT_BAT_2488, + NPCs.GIANT_BAT_3711, + ) + } + + override fun onDropTableRolled(self: NPC, killer: Entity, drops: ArrayList) { + super.onDropTableRolled(self, killer, drops) + // Drops the Giant Bat Wing during Rag and Bone Man quest + if (killer is Player && isQuestInProgress(killer, Quests.RAG_AND_BONE_MAN, 1, 99)) { + if(RandomFunction.roll(4)) { + drops.add(Item(Items.GIANT_BAT_WING_7827)); + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/GiantRatBehavior.kt b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/GiantRatBehavior.kt new file mode 100644 index 0000000..b670f24 --- /dev/null +++ b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/GiantRatBehavior.kt @@ -0,0 +1,44 @@ +package content.region.misthalin.silvarea.quest.ragandboneman + +import content.data.Quests +import core.api.isQuestInProgress +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.tools.RandomFunction +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class GiantRatBehavior : NPCBehavior(*giantRatIds) { + companion object { + private val giantRatIds = intArrayOf( + NPCs.GIANT_RAT_4395, + NPCs.GIANT_RAT_446, + NPCs.GIANT_RAT_4922, + NPCs.GIANT_RAT_4923, + NPCs.GIANT_RAT_4924, + NPCs.GIANT_RAT_4925, + NPCs.GIANT_RAT_4926, + NPCs.GIANT_RAT_4927, + NPCs.GIANT_RAT_4942, + NPCs.GIANT_RAT_4943, + NPCs.GIANT_RAT_4944, + NPCs.GIANT_RAT_4945, + NPCs.GIANT_RAT_86, + NPCs.GIANT_RAT_87, + NPCs.GIANT_RAT_950, + ) + } + + override fun onDropTableRolled(self: NPC, killer: Entity, drops: ArrayList) { + super.onDropTableRolled(self, killer, drops) + // Drops the Giant Rat Bone during Rag and Bone Man quest + if (killer is Player && isQuestInProgress(killer, Quests.RAG_AND_BONE_MAN, 1, 99)) { + if(RandomFunction.roll(4)) { + drops.add(Item(Items.GIANT_RAT_BONE_7824)); + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/GoblinBehavior.kt b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/GoblinBehavior.kt new file mode 100644 index 0000000..923b9a5 --- /dev/null +++ b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/GoblinBehavior.kt @@ -0,0 +1,187 @@ +package content.region.misthalin.silvarea.quest.ragandboneman + +import content.data.Quests +import core.api.isQuestInProgress +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.tools.RandomFunction +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class GoblinBehavior : NPCBehavior(*goblinIds) { + companion object { + private val goblinIds = intArrayOf( + NPCs.GOBLIN_100, + NPCs.GOBLIN_101, + NPCs.GOBLIN_102, + NPCs.GOBLIN_1769, + NPCs.GOBLIN_1770, + NPCs.GOBLIN_1771, + NPCs.GOBLIN_1772, + NPCs.GOBLIN_1773, + NPCs.GOBLIN_1774, + NPCs.GOBLIN_1775, + NPCs.GOBLIN_1776, + NPCs.GOBLIN_2274, + NPCs.GOBLIN_2275, + NPCs.GOBLIN_2276, + NPCs.GOBLIN_2277, + NPCs.GOBLIN_2278, + NPCs.GOBLIN_2279, + NPCs.GOBLIN_2280, + NPCs.GOBLIN_2281, + NPCs.GOBLIN_2678, + NPCs.GOBLIN_2679, + NPCs.GOBLIN_2680, + NPCs.GOBLIN_2681, + NPCs.GOBLIN_3264, + NPCs.GOBLIN_3265, + NPCs.GOBLIN_3266, + NPCs.GOBLIN_3267, + NPCs.GOBLIN_3726, + NPCs.GOBLIN_4261, + NPCs.GOBLIN_4262, + NPCs.GOBLIN_4263, + NPCs.GOBLIN_4264, + NPCs.GOBLIN_4265, + NPCs.GOBLIN_4266, + NPCs.GOBLIN_4267, + NPCs.GOBLIN_4268, + NPCs.GOBLIN_4269, + NPCs.GOBLIN_4270, + NPCs.GOBLIN_4271, + NPCs.GOBLIN_4272, + NPCs.GOBLIN_4273, + NPCs.GOBLIN_4274, + NPCs.GOBLIN_4275, + NPCs.GOBLIN_4276, + NPCs.GOBLIN_4407, + NPCs.GOBLIN_4408, + NPCs.GOBLIN_4409, + NPCs.GOBLIN_4410, + NPCs.GOBLIN_4411, + NPCs.GOBLIN_4412, + NPCs.GOBLIN_444, + NPCs.GOBLIN_445, + NPCs.GOBLIN_4479, + NPCs.GOBLIN_4480, + NPCs.GOBLIN_4481, + NPCs.GOBLIN_4482, + NPCs.GOBLIN_4483, + NPCs.GOBLIN_4484, + NPCs.GOBLIN_4485, + NPCs.GOBLIN_4486, + NPCs.GOBLIN_4487, + NPCs.GOBLIN_4488, + NPCs.GOBLIN_4489, + NPCs.GOBLIN_4490, + NPCs.GOBLIN_4491, + NPCs.GOBLIN_4492, + NPCs.GOBLIN_4499, + NPCs.GOBLIN_4633, + NPCs.GOBLIN_4634, + NPCs.GOBLIN_4635, + NPCs.GOBLIN_4636, + NPCs.GOBLIN_4637, + NPCs.GOBLIN_5855, + NPCs.GOBLIN_5856, + NPCs.GOBLIN_6125, + NPCs.GOBLIN_6126, + NPCs.GOBLIN_6132, + NPCs.GOBLIN_6133, + NPCs.GOBLIN_6279, + NPCs.GOBLIN_6280, + NPCs.GOBLIN_6281, + NPCs.GOBLIN_6282, + NPCs.GOBLIN_6283, + NPCs.GOBLIN_6284, + NPCs.GOBLIN_6402, + NPCs.GOBLIN_6403, + NPCs.GOBLIN_6404, + NPCs.GOBLIN_6405, + NPCs.GOBLIN_6406, + NPCs.GOBLIN_6407, + NPCs.GOBLIN_6408, + NPCs.GOBLIN_6409, + NPCs.GOBLIN_6410, + NPCs.GOBLIN_6411, + NPCs.GOBLIN_6412, + NPCs.GOBLIN_6413, + NPCs.GOBLIN_6414, + NPCs.GOBLIN_6415, + NPCs.GOBLIN_6416, + NPCs.GOBLIN_6417, + NPCs.GOBLIN_6418, + NPCs.GOBLIN_6419, + NPCs.GOBLIN_6420, + NPCs.GOBLIN_6421, + NPCs.GOBLIN_6422, + NPCs.GOBLIN_6423, + NPCs.GOBLIN_6424, + NPCs.GOBLIN_6425, + NPCs.GOBLIN_6426, + NPCs.GOBLIN_6427, + NPCs.GOBLIN_6428, + NPCs.GOBLIN_6429, + NPCs.GOBLIN_6430, + NPCs.GOBLIN_6431, + NPCs.GOBLIN_6432, + NPCs.GOBLIN_6433, + NPCs.GOBLIN_6434, + NPCs.GOBLIN_6435, + NPCs.GOBLIN_6436, + NPCs.GOBLIN_6437, + NPCs.GOBLIN_6438, + NPCs.GOBLIN_6439, + NPCs.GOBLIN_6440, + NPCs.GOBLIN_6441, + NPCs.GOBLIN_6442, + NPCs.GOBLIN_6443, + NPCs.GOBLIN_6444, + NPCs.GOBLIN_6445, + NPCs.GOBLIN_6446, + NPCs.GOBLIN_6447, + NPCs.GOBLIN_6448, + NPCs.GOBLIN_6449, + NPCs.GOBLIN_6450, + NPCs.GOBLIN_6451, + NPCs.GOBLIN_6452, + NPCs.GOBLIN_6453, + NPCs.GOBLIN_6454, + NPCs.GOBLIN_6455, + NPCs.GOBLIN_6456, + NPCs.GOBLIN_6457, + NPCs.GOBLIN_6458, + NPCs.GOBLIN_6459, + NPCs.GOBLIN_6460, + NPCs.GOBLIN_6461, + NPCs.GOBLIN_6462, + NPCs.GOBLIN_6463, + NPCs.GOBLIN_6464, + NPCs.GOBLIN_6465, + NPCs.GOBLIN_6466, + NPCs.GOBLIN_6467, + NPCs.GOBLIN_6490, + NPCs.GOBLIN_6491, + NPCs.GOBLIN_6492, + NPCs.GOBLIN_6493, + NPCs.GOBLIN_6494, + NPCs.GOBLIN_6495, + NPCs.GOBLIN_7964, + NPCs.GOBLIN_7965, + ) + } + + override fun onDropTableRolled(self: NPC, killer: Entity, drops: ArrayList) { + super.onDropTableRolled(self, killer, drops) + // Drops the Goblin Skull during Rag and Bone Man quest + if (killer is Player && isQuestInProgress(killer, Quests.RAG_AND_BONE_MAN, 1, 99)) { + if(RandomFunction.roll(4)) { + drops.add(Item(Items.GOBLIN_SKULL_7812)) + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/MonkeyBehavior.kt b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/MonkeyBehavior.kt new file mode 100644 index 0000000..2646a86 --- /dev/null +++ b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/MonkeyBehavior.kt @@ -0,0 +1,54 @@ +package content.region.misthalin.silvarea.quest.ragandboneman + +import content.data.Quests +import core.api.isQuestInProgress +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.tools.RandomFunction +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class MonkeyBehavior : NPCBehavior(*monkeyIds) { + companion object { + private val monkeyIds = intArrayOf( + NPCs.MONKEY_132, + NPCs.MONKEY_1463, + NPCs.MONKEY_1464, + NPCs.MONKEY_1487, + NPCs.MONKEY_2301, + NPCs.MONKEY_2302, + NPCs.MONKEY_2303, + NPCs.MONKEY_4344, + NPCs.MONKEY_4363, + NPCs.MONKEY_5852, + NPCs.MONKEY_5853, + NPCs.MONKEY_6943, + NPCs.MONKEY_7211, + NPCs.MONKEY_7213, + NPCs.MONKEY_7215, + NPCs.MONKEY_7217, + NPCs.MONKEY_7219, + NPCs.MONKEY_7221, + NPCs.MONKEY_7223, + NPCs.MONKEY_7225, + NPCs.MONKEY_7227, + NPCs.MONKEY_ZOMBIE_1465, + NPCs.MONKEY_ZOMBIE_1466, + NPCs.MONKEY_ZOMBIE_1467, + ) + } + + + override fun onDropTableRolled(self: NPC, killer: Entity, drops: ArrayList) { + super.onDropTableRolled(self, killer, drops) + // Drops the Monkey Paw during Rag and Bone Man quest + if (killer is Player && isQuestInProgress(killer, Quests.RAG_AND_BONE_MAN, 1, 99)) { + if(RandomFunction.roll(4)) { + drops.add(Item(Items.MONKEY_PAW_7854)); + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/OddOldManDialogueFile.kt b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/OddOldManDialogueFile.kt new file mode 100644 index 0000000..9351b6c --- /dev/null +++ b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/OddOldManDialogueFile.kt @@ -0,0 +1,233 @@ +package content.region.misthalin.silvarea.quest.ragandboneman + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.player.Player +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +class OddOldManDialogueFile : DialogueFile() { + // BONES_3674 is the Sack on ODD_OLD_MAN_3670 + // There are probably FacialExpressions for the bone sack, but that's too much work. + override fun handle(componentID: Int, buttonID: Int) { + when (getQuestStage(player!!, Quests.RAG_AND_BONE_MAN)) { + 0 -> { + when (stage) { + START_DIALOGUE -> npcl(FacialExpression.FRIENDLY, "Can I help you with something?").also { stage++ } + 1 -> playerl(FacialExpression.FRIENDLY, "Well, err...who are you, and what are all these bones doing here?").also { stage++ } + 2 -> npcl(FacialExpression.FRIENDLY, "Errr...").also { stage++ } + 3 -> npcl(NPCs.BONES_3674, "Sack", FacialExpression.OLD_HAPPY, "Mumblemumble").also { stage++ } + 4 -> npcl(FacialExpression.FRIENDLY, "I'm an archaeologist. I work with the museum.").also { stage++ } + 5 -> playerl(FacialExpression.FRIENDLY, "An archaeologist?").also { stage++ } + 6 -> npcl(FacialExpression.FRIENDLY, "Yes.").also { stage++ } + 7 -> playerl(FacialExpression.FRIENDLY, "Well that explains the bones...sort of...but what are you doing all the way out here?").also { stage++ } + 8 -> npcl(FacialExpression.FRIENDLY, "Errr...").also { stage++ } + 9 -> npcl(NPCs.BONES_3674, "Sack", FacialExpression.OLD_HAPPY, "Mumblemumble. Mumblemumblemumble.").also { stage++ } + 10 -> npcl(FacialExpression.FRIENDLY, "I'm collecting bones for the museum.").also { stage++ } + 11 -> npcl(FacialExpression.FRIENDLY, "They have asked me to rig up some displays of second and third age creatures using their bones, so that people can come and...well, look at them.").also { stage++ } + 12 -> npcl(FacialExpression.FRIENDLY, "I need to get them into some sort of order before I begin, but I've run into a bit of a snag.").also { stage++ } + 13 -> playerl(FacialExpression.FRIENDLY, "What sort of a snag?").also { stage++ } + 14 -> npcl(FacialExpression.FRIENDLY, "Well, I need to have all the bones I'm going to use here, and placed into some sort of order.").also { stage++ } + 15 -> npcl(FacialExpression.FRIENDLY, "However, I seem to have discovered I am a few short.").also { stage++ } + 16 -> showTopics( + Topic("Anything I can do to help?", 20, true), + Topic("Well, good luck with that.", 70), + Topic("Where is that mumbling coming from?", 80) + ) + 20 -> playerl(FacialExpression.FRIENDLY, "Anything I can do to help?").also { stage++ } + 21 -> npcl(FacialExpression.FRIENDLY, "Errr...").also { stage++ } + 22 -> npcl(NPCs.BONES_3674, "Sack", FacialExpression.OLD_HAPPY, "Mumblemumble").also { stage++ } + 23 -> npcl(FacialExpression.FRIENDLY, "There is something you could do for me. I'm going to be busy...err...").also { stage++ } + 24 -> npcl(NPCs.BONES_3674, "Sack", FacialExpression.OLD_HAPPY, "Mumble").also { stage++ } + 25 -> npcl(FacialExpression.FRIENDLY, "Sorting, yes, sorting these bones out ready for the museum, but I need a few more.").also { stage++ } + 26 -> npcl(FacialExpression.FRIENDLY, "Will you help me out by grabbing some?").also { stage++ } + 27 -> showTopics( + Topic(FacialExpression.FRIENDLY, "Yes", 28, true), + Topic(FacialExpression.FRIENDLY, "No", 60), + Topic("Where is that mumbling coming from?", 80) + ) + 28 -> playerl(FacialExpression.FRIENDLY, "Yes. I'll give you a hand.").also { stage++ } + 29 -> npcl(FacialExpression.FRIENDLY, "You will? Excellent!").also { stage++ } + 30 -> npcl(NPCs.BONES_3674, "Sack", FacialExpression.OLD_HAPPY, "Sniggersnigger").also { stage++ } + 31 -> playerl(FacialExpression.FRIENDLY, "Where do you need me to dig?").also { stage++ } + 32 -> npcl(FacialExpression.FRIENDLY, "Dig?").also { stage++ } + 33 -> npcl(NPCs.BONES_3674, "Sack", FacialExpression.OLD_HAPPY, "Mumblemumble").also { stage++ } + 34 -> npcl(FacialExpression.FRIENDLY, "Oh, you must have got the wrong end of the stick.").also { stage++ } + 35 -> npcl(FacialExpression.FRIENDLY, "I need some fresh, whole bones to replace ones that have become damaged.").also { stage++ } + 36 -> playerl(FacialExpression.FRIENDLY, "What?").also { stage++ } + 37 -> npcl(FacialExpression.FRIENDLY, "Err...").also { stage++ } + 38 -> npcl(NPCs.BONES_3674, "Sack", FacialExpression.OLD_HAPPY, "Mumblemumblemumblemumblemumble. Mumblemumblemumblemumble. Mumble.").also { stage++ } + 39 -> playerl(FacialExpression.FRIENDLY, "Excuse me...").also { stage++ } + 40 -> npcl(FacialExpression.FRIENDLY, "Shhh!").also { stage++ } + 41 -> playerl(FacialExpression.FRIENDLY, "Sorry...").also { stage++ } + 42 -> npcl(NPCs.BONES_3674, "Sack", FacialExpression.OLD_HAPPY, "Mumblemumble. Mumblemumblemumble.").also { stage++ } + 43 -> npcl(FacialExpression.FRIENDLY, "Ok, got it.").also { stage++ } + 44 -> npcl(FacialExpression.FRIENDLY, "Ok, here is the thing. While sorting out what bones I do have I managed to lose or damage a few. If you can get me some fresh, unbroken bones to use as replacements then I can get on with things.").also { stage++ } + 45 -> npcl(FacialExpression.FRIENDLY, "That make things clearer?").also { stage++ } + 46 -> playerl(FacialExpression.FRIENDLY, "Well, it makes some sense I suppose...").also { stage++ } + 47 -> npcl(FacialExpression.FRIENDLY, "Great. If you can get me a bone from a Goblin, a Bear, a Big Frog, a Ram, a Unicorn, a Monkey, a Giant rat and a Giant Bat then I'll be able to move on with the...").also { stage++ } + 48 -> npcl(FacialExpression.FRIENDLY, "Displays...").also { stage++ } + 49 -> playerl(FacialExpression.FRIENDLY, "So you just want me to bring you these bones and that will be that?").also { stage++ } + 50 -> npcl(FacialExpression.FRIENDLY, "Well, I wouldn't mind you sticking them in a pot and boiling them in vinegar first, if you don't mind.").also { stage++ } + 51 -> npcl(FacialExpression.FRIENDLY, "There is a Wine Merchant in Draynor called Fortunato that sells the stuff you'll need.").also { stage++ } + 52 -> npcl(FacialExpression.FRIENDLY, "You can even use my pot-boiler if you want.").also { stage++ } + 53 -> playerl(FacialExpression.FRIENDLY, "Why do I need to boil them in vinegar?").also { stage++ } + 54 -> npcl(FacialExpression.FRIENDLY, "It gets them bright and sparking white.").also { stage++ } + 55 -> npcl(FacialExpression.FRIENDLY, "It's an archaeologist thing.").also { stage++ } + 56 -> npcl(FacialExpression.FRIENDLY, "Just put the bone in a pot of vinegar, throw some logs on the fire, put the pot in the holder and light the logs.").also { stage++ } + 57 -> npcl(FacialExpression.FRIENDLY, "It takes a while for the vinegar to evaporate, but the bone will be nice and clean in the end.").also { stage++ } + 58 -> playerl(FacialExpression.FRIENDLY, "All right, I'll be back later.").also { stage++ } + 59 -> npcl(FacialExpression.FRIENDLY, "Bye!").also { + setQuestStage(player!!, Quests.RAG_AND_BONE_MAN, 1) + stage = END_DIALOGUE + } + + 60 -> npcl(FacialExpression.FRIENDLY, "Oh...I see.").also { stage++ } + 61 -> npcl(FacialExpression.FRIENDLY, "Well, never mind me young man, I'll just stagger over here under my massive burden, and continue my thankless task.").also { stage++ } + 62 -> npcl(FacialExpression.FRIENDLY, "Unaided and alone...").also { stage++ } + 63 -> playerl(FacialExpression.FRIENDLY, "Wow, trying a guilt trip much?").also { + stage = END_DIALOGUE + } + + 70 -> npcl(FacialExpression.FRIENDLY, "Thanks stranger!").also { stage++ } + 71 -> npcl(FacialExpression.FRIENDLY, "What a polite young man...").also { stage++ } + 72 -> npcl(FacialExpression.FRIENDLY, "Well, back to work!").also { + stage = END_DIALOGUE + } + + 80 -> npcl(FacialExpression.FRIENDLY, "Errr...").also { stage++ } + 81 -> npcl(NPCs.BONES_3674, "Sack", FacialExpression.OLD_HAPPY, "Mumblemumble").also { stage++ } + 82 -> npcl(FacialExpression.FRIENDLY, "What mumbling?").also { stage++ } + 83 -> npcl(FacialExpression.FRIENDLY, "Anyway, I have enough problems of my own without dealing with a delusional adventurer.").also { + stage = 16 + } + } + } + in 1 .. 3 -> { + when(stage) { + START_DIALOGUE -> { + if (checkBonesInInventory(player!!)) { + playerl(FacialExpression.FRIENDLY, "I have some bones for you...").also { stage = 1 } + } else { + npcl(FacialExpression.FRIENDLY, "Have you brought me any bones?").also { stage = 20 } + } + } + 1 -> npcl(FacialExpression.FRIENDLY, "Great! Let me take a look at them.").also { + stage++ + } + 2 -> { + submitBonesInInventory(player!!) + if (hasAllBones(player!!)) { + npcl(FacialExpression.FRIENDLY, "That's the last of them!").also { stage = 4 } + } else { + npcl(FacialExpression.FRIENDLY, "Thanks the museum will be so pleased.").also { stage = 3 } + } + } + 3 -> npcl(FacialExpression.FRIENDLY, "Come and see me when you have the rest.").also { + stage = END_DIALOGUE + } + 4 -> npcl(FacialExpression.FRIENDLY, "The museum will be thrilled to know I've completed the collection.").also { stage++ } + 5 -> playerl(FacialExpression.FRIENDLY, "Well I'm just glad I could help.").also { stage++ } + 6 -> npcl(NPCs.BONES_3674, "Sack", FacialExpression.OLD_HAPPY, "Mumblemumble").also { stage++ } + 7 -> npcl(FacialExpression.FRIENDLY, "Well you've been a big help and no mistake.").also { stage++ } + 8 -> npcl(FacialExpression.FRIENDLY, "I'm always on the lookout for fresh bones, so if you see some bring them right over.").also { stage++ } + 9 -> playerl(FacialExpression.FRIENDLY, "No problem, I'll be sure to bring anything you might like over if I find something.").also { stage++ } + 10 -> playerl(FacialExpression.FRIENDLY, "I can't wait to see the displays once they are finished.").also { stage++ } + 11 -> finishQuest(player!!, Quests.RAG_AND_BONE_MAN).also { + end() + } + 20 -> playerl(FacialExpression.FRIENDLY, "Not at the moment. Can you just give me a run down on which bones I have left to get?").also { stage++ } + 21 -> npcl(FacialExpression.FRIENDLY, "Sure.").also {stage = 30 } + 30, 40, 50, 60, 70, 80, 90, 100, 110 -> { + if (!getAttribute(player!!, RagAndBoneMan.attributeGoblinBone, false) && stage <= 30) { npcl(NPCs.BONES_3674, "Sack", FacialExpression.OLD_HAPPY, "Mumblemumble"); stage = 31 } + else if (!getAttribute(player!!, RagAndBoneMan.attributeBearBone, false) && stage <= 40) { npcl(NPCs.BONES_3674, "Sack", FacialExpression.OLD_HAPPY, "Mumblemumble"); stage = 41 } + else if (!getAttribute(player!!, RagAndBoneMan.attributeBigFrogBone, false) && stage <= 50) { npcl(NPCs.BONES_3674, "Sack", FacialExpression.OLD_HAPPY, "Mumblemumble"); stage = 51 } + else if (!getAttribute(player!!, RagAndBoneMan.attributeRamBone, false) && stage <= 60) { npcl(NPCs.BONES_3674, "Sack", FacialExpression.OLD_HAPPY, "Mumblemumble"); stage = 61 } + else if (!getAttribute(player!!, RagAndBoneMan.attributeUnicornBone, false) && stage <= 70) { npcl(NPCs.BONES_3674, "Sack", FacialExpression.OLD_HAPPY, "Mumblemumble"); stage = 71 } + else if (!getAttribute(player!!, RagAndBoneMan.attributeMonkeyBone, false) && stage <= 80) { npcl(NPCs.BONES_3674, "Sack", FacialExpression.OLD_HAPPY, "Mumblemumble"); stage = 81 } + else if (!getAttribute(player!!, RagAndBoneMan.attributeGiantRatBone, false) && stage <= 90) { npcl(NPCs.BONES_3674, "Sack", FacialExpression.OLD_HAPPY, "Mumblemumble"); stage = 91 } + else if (!getAttribute(player!!, RagAndBoneMan.attributeGiantBatBone, false) && stage <= 100) { npcl(NPCs.BONES_3674, "Sack", FacialExpression.OLD_HAPPY, "Mumblemumble"); stage = 101 } + else { + npcl(FacialExpression.FRIENDLY, "Did you get all that?") + stage = 111 + } + } + 31 -> npcl(FacialExpression.FRIENDLY, "You still need to bring me a Goblin bone.").also { stage++ } + 32 -> npcl(FacialExpression.FRIENDLY, "Goblins are relatively common. I hear there is a house full of them around Lumbridge in fact.").also { stage = 40 } + + 41 -> npcl(FacialExpression.FRIENDLY, "You still need to bring me a Bear bone.").also { stage++ } + 42 -> npcl(FacialExpression.FRIENDLY, "I heard that there are some Bears over by the Legends' Guild, near Ardougne.").also { stage = 50 } + + 51 -> npcl(FacialExpression.FRIENDLY, "You still need to bring me a Big Frog bone.").also { stage++ } + 52 -> npcl(FacialExpression.FRIENDLY, "This might be a little tricky as you will need to go into the Lumbridge Swamp caves. You will need a light source! Never forget your light source down there!").also { stage = 60 } + + 61 -> npcl(FacialExpression.FRIENDLY, "You still need to bring me a Ram bone.").also { stage++ } + 62 -> npcl(FacialExpression.FRIENDLY, "I'm sure you will be able to find a ram wherever there are sheep.").also { stage = 70 } + + 71 -> npcl(FacialExpression.FRIENDLY, "You still need to bring me a Unicorn bone.").also { stage++ } + 72 -> npcl(FacialExpression.FRIENDLY, "I seem to remember that there were Unicorns south of Varrock, I think they might be there still.").also { stage = 80 } + + 81 -> npcl(FacialExpression.FRIENDLY, "You still need to bring me a Monkey bone.").also { stage++ } + 82 -> npcl(FacialExpression.FRIENDLY, "Monkeys tend to live in Jungle areas, like Karamja. I think they are pretty plentiful there if I remember correctly.").also { stage = 90 } + + 91 -> npcl(FacialExpression.FRIENDLY, "You still need to bring me a Giant Rat bone.").also { stage++ } + 92 -> npcl(FacialExpression.FRIENDLY, "If you can't find one in a sewer, then you might want to try looking in some caves.").also { stage = 100 } + + 101 -> npcl(FacialExpression.FRIENDLY, "You still need to bring me a Giant Bat bone.").also { stage++ } + 102 -> npcl(FacialExpression.FRIENDLY, "Giant bats tend to live underground, but I have heard there are a few near the Coal Pits.").also { stage = 110 } + + 111 -> playerl(FacialExpression.FRIENDLY, "Yes. I'll get right on it.").also { stage++ } + 112 -> npcl(NPCs.BONES_3674, "Sack", FacialExpression.OLD_HAPPY, "Mumblemumble").also { stage++ } + 113 -> npcl(FacialExpression.FRIENDLY, "Don't forget to boil them in vinegar first.").also { stage++ } + 114 -> npcl(FacialExpression.FRIENDLY, "Just chuck some logs into the pit, put the bone in the pot of vinegar and drop it onto the pot-boiler. Then light the logs and wait for the the vinegar to boil away.").also { stage++ } + 115 -> playerl(FacialExpression.FRIENDLY, "Ok, I'll remember.").also { + stage = END_DIALOGUE + } + } + } + } + /* + Unfortunately from OSRS 2016: https://www.youtube.com/watch?v=31QNg1E0qf0 + Wonderful! I'll put this with the rest. + No problem. I'll be back if I find some more. + + This one is closest RS 2012: https://www.youtube.com/watch?v=0I8fNTeAwA8 + I have some bones for you... + Great! Let me take a look at them. + Thanks the museum will be so pleased. + Come and see me when you have the rest. + */ + } + + private fun checkBonesInInventory(player: Player) : Boolean { + var hasBone = false + RagAndBoneMan.requiredBonesMap.forEach { + if (inInventory(player, it.key)) { + hasBone = true + } + } + return hasBone + } + + private fun submitBonesInInventory(player: Player) { + RagAndBoneMan.requiredBonesMap.forEach { + if (!getAttribute(player, it.value, false) && removeItem(player, it.key)) { + setAttribute(player, it.value, true) + } + } + } + + private fun hasAllBones(player: Player) : Boolean { + var hasBoneAllBones = true + RagAndBoneMan.requiredBonesMap.values.forEach { + if (!getAttribute(player, it, false)) { + hasBoneAllBones = false + } + } + return hasBoneAllBones + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/RagAndBoneMan.kt b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/RagAndBoneMan.kt new file mode 100644 index 0000000..97e5e9a --- /dev/null +++ b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/RagAndBoneMan.kt @@ -0,0 +1,145 @@ +package content.region.misthalin.silvarea.quest.ragandboneman + +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import org.rs09.consts.Items +import content.data.Quests + +/** + * Rag and Bone Man Quest + * @author ovenbread + * + * Do note: + * Before, the Rag and Bone Man WISHLIST(a.k.a part 2) used to reward 1 quest point, + * thus required to wear the quest cape. + * This was changed on 11 August 2009. + * Rag and Bone Man Quest now rewards 2 quest points. + * The follow-up hidden quest called Rag and Bone Man WISHLIST is not a quest cape req. + * + * https://www.youtube.com/watch?v=6tdNqNa4zGw + * https://www.youtube.com/watch?v=aVyBzqyuPYs + * + * Quest Journal 2012 https://www.youtube.com/watch?v=0I8fNTeAwA8&t=764 + */ +@Initializable +class RagAndBoneMan : Quest(Quests.RAG_AND_BONE_MAN,100, 99, 2, 714, 0, 1, 4) { + companion object { + const val attributeGoblinBone = "/save:quest:ragandboneman-goblinbonesubmit" + const val attributeBearBone = "/save:quest:ragandboneman-bearbonesubmit" + const val attributeBigFrogBone = "/save:quest:ragandboneman-bigfrogbonesubmit" + const val attributeRamBone = "/save:quest:ragandboneman-rambonesubmit" + const val attributeUnicornBone = "/save:quest:ragandboneman-unicornbonesubmit" + const val attributeMonkeyBone = "/save:quest:ragandboneman-monkeybonesubmit" + const val attributeGiantRatBone = "/save:quest:ragandboneman-giantratbonesubmit" + const val attributeGiantBatBone = "/save:quest:ragandboneman-giantbatbonesubmit" + + val requiredBonesMap = mapOf( + Items.GOBLIN_SKULL_7814 to attributeGoblinBone, + Items.BEAR_RIBS_7817 to attributeBearBone, + Items.BIG_FROG_LEG_7910 to attributeBigFrogBone, + Items.RAM_SKULL_7820 to attributeRamBone, + Items.UNICORN_BONE_7823 to attributeUnicornBone, + Items.MONKEY_PAW_7856 to attributeMonkeyBone, + Items.GIANT_RAT_BONE_7826 to attributeGiantRatBone, + Items.GIANT_BAT_WING_7829 to attributeGiantBatBone + ) + } + + override fun drawJournal(player: Player?, stage: Int) { + super.drawJournal(player, stage) + var line = 12 + var stage = getStage(player) + + when (stage) { + 0 -> { + line(player, "I can start this quest by talking to the !!Odd Old Man?? to the", line++) + line(player, "West of the !!Limestone Mine??", line++) + } + in 1 .. 3 -> { + line(player, "I have spoken to the Odd Old Man and have agreed to help him ", line++, true) + line(player, "complete his collection of bones. I should check which ones", line++, true) + line(player, "he needs.", line++, true) + line++ + line(player,"The !!Odd Old Man?? has instructed me on which bones to collect", line++, false) + line(player,"and how to prepare them. I must find !!whole, unbroken bones??", line++, false) + line(player,"and put them into a !!pot of vinegar??. I must then put some", line++, false) + line(player,"!!logs?? under the !!pot boiler??, !!put the bone in vinegar on it??,", line++, false) + line(player,"!!and light the logs??. This will clean the bone.", line++, false) + line++ + line(player,"I need to buy the !!vinegar?? from the !!wine merchant?? in !!Draynor??.", line++, false) + line++ + line(player,"I need to give the !!Odd Old Man?? the following polished bones:", line++, false) + boneChecklist(player, line, "Goblin", BoneBoilerEnum.GOBLIN_SKULL, attributeGoblinBone) + line++ + boneChecklist(player, line, "Bear", BoneBoilerEnum.BEAR_RIBS, attributeBearBone) + line++ + boneChecklist(player, line, "Big frog", BoneBoilerEnum.BIG_FROG_LEG, attributeBigFrogBone) + line++ + boneChecklist(player, line, "Ram", BoneBoilerEnum.RAM_SKULL, attributeRamBone) + line++ + boneChecklist(player, line, "Unicorn", BoneBoilerEnum.UNICORN_BONE, attributeUnicornBone) + line++ + boneChecklist(player, line, "Monkey", BoneBoilerEnum.MONKEY_PAW, attributeMonkeyBone) + line++ + boneChecklist(player, line, "Giant rat", BoneBoilerEnum.GIANT_RAT_BONE, attributeGiantRatBone) + line++ + boneChecklist(player, line, "Giant bat", BoneBoilerEnum.GIANT_BAT_WING, attributeGiantBatBone) + line++ + } + 100 -> { + line(player, "I have spoken to the Odd Old Man and have agreed to help him ", line++, true) + line(player, "complete his collection of bones. I should check which ones", line++, true) + line(player, "he needs.", line++, true) + line++ + line(player,"The !!Odd Old Man?? has instructed me on which bones to collect", line++, true) + line(player,"and how to prepare them. I must find !!whole, unbroken bones??", line++, true) + line(player,"and put them into a !!pot of vinegar??. I must then put some", line++, true) + line(player,"!!logs?? under the !!pot boiler??, !!put the bone in vinegar on it??,", line++, true) + line(player,"!!and light the logs??. This will clean the bone.", line++, true) + line++ + line(player,"I have given the last of the bones to the Odd Old Man.", line++, true) + line(player,"I am sure he will reward me.", line++, true) + line++ + line(player,"The Odd Old Man has given me a reward. I will see if I can", line++, false) + line(player,"find any more bones from his wish list, and will bring them", line++, false) + line(player,"them to him if I do.", line++, false) + line++ + line(player,"%%QUEST COMPLETE!&&",line++) + } + } + } + + private fun boneChecklist(player: Player?, line: Int, mob: String, boneEnum: BoneBoilerEnum, questAttribute: String) { + line(player, + if (getAttribute(player!!, questAttribute, false)) + "!!$mob.??" + else if (inInventory(player, boneEnum.polishedBone)) + "!!$mob.?? (I have a prepared one !!with me.??)" + else if (inInventory(player, boneEnum.bone) || inInventory(player, boneEnum.boneInVinegar)) + "!!$mob.?? (I have an unprepared one !!with me.??)" + else + "!!$mob.??", + line, getAttribute(player, questAttribute, false)) + } + + override fun finish(player: Player) { + var ln = 10 + super.finish(player) + player.packetDispatch.sendString("You have completed Rag and Bone Man!", 277, 4) + player.packetDispatch.sendItemZoomOnInterface(Items.BONE_IN_VINEGAR_7813, 240, 277, 5) + + drawReward(player,"2 Quest Points", ln++) + drawReward(player,"500 Cooking XP and 500", ln++) + drawReward(player,"Prayer XP", ln++) + + player.skills.addExperience(Skills.COOKING, 500.0) + player.skills.addExperience(Skills.PRAYER, 500.0) + } + + override fun newInstance(`object`: Any?): Quest { + return this + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/RagAndBoneManListeners.kt b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/RagAndBoneManListeners.kt new file mode 100644 index 0000000..72119a2 --- /dev/null +++ b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/RagAndBoneManListeners.kt @@ -0,0 +1,102 @@ +package content.region.misthalin.silvarea.quest.ragandboneman + +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.impl.PulseType +import core.game.system.task.Pulse +import org.rs09.consts.Animations +import org.rs09.consts.Items +import org.rs09.consts.Scenery + +class RagAndBoneManListeners : InteractionListener { + + companion object { + const val ATTRIBUTE_ACTIVE_POT_OF_VINEGAR = "ragandboneman:potofvinegar" + } + + override fun defineListeners() { + // Pouring vinegar from jug to pot. + onUseWith(IntType.ITEM, Items.JUG_OF_VINEGAR_7810, Items.EMPTY_POT_1931) { player, _, _ -> + if (removeItem(player, Items.JUG_OF_VINEGAR_7810) && (removeItem(player, Items.EMPTY_POT_1931))) { + addItem(player, Items.POT_OF_VINEGAR_7811) + addItem(player, Items.JUG_1935) + sendMessage(player, "You pour the vinegar into the pot.") + } + return@onUseWith true + } + + // Adding a bone to the pot. + onUseWith(IntType.ITEM, BoneBoilerEnum.boneList, Items.POT_OF_VINEGAR_7811) { player, used, with -> + if (removeItem(player, used) && (removeItem(player, with))) { + addItem(player, BoneBoilerEnum.forBone(used.id)!!.boneInVinegar) + sendMessage(player, "You add the bone to the pot of vinegar.") + } + return@onUseWith true + } + + // Scenery: Placing logs on grate. + onUseWith(IntType.SCENERY, intArrayOf(Items.LOGS_1511, Items.OAK_LOGS_1521, Items.WILLOW_LOGS_1519, Items.MAPLE_LOGS_1517, Items.YEW_LOGS_1515, Items.MAGIC_LOGS_1513), Scenery.POT_BOILER_14006) { player, used, _ -> + if (removeItem(player, used)) { + sendMessage(player, "You place the logs into the grate.") + setVarbit(player, 2046, 1) + } + return@onUseWith true + } + + // Scenery: Placing bone in vinegar pot on pot boiler. + onUseWith(IntType.SCENERY, BoneBoilerEnum.boneInVinegarList, Scenery.POT_BOILER_14005) { player, used, _ -> + val potOfVinegar = used.id + if ((removeItem(player, potOfVinegar))) { + setAttribute(player, ATTRIBUTE_ACTIVE_POT_OF_VINEGAR, potOfVinegar) + sendMessage(player, "You place the pot on the pot boiler.") + setVarbit(player, 2046, 2) + } + return@onUseWith true + } + + // Scenery: Remove bone in vinegar pot from pot boiler. + on(Scenery.POT_BOILER_14007, SCENERY, "remove-pot") { player, _ -> + val potOfVinegar = getAttribute(player, ATTRIBUTE_ACTIVE_POT_OF_VINEGAR, 0) + if (BoneBoilerEnum.forBoneInVinegar(potOfVinegar) != null) { + setAttribute(player, ATTRIBUTE_ACTIVE_POT_OF_VINEGAR, 0) + addItemOrDrop(player, potOfVinegar) + sendMessage(player, "You remove the pot from the pot boiler.") + } + setVarbit(player, 2046, 1) + return@on true + } + + // Scenery: Lighting pot boiler and cooking the bone in vinegar to yield bone. + onUseWith(IntType.SCENERY, Items.TINDERBOX_590, Scenery.POT_BOILER_14007) { player, _, _ -> + sendMessage(player, "You light the logs under the pot.") + animate(player, Animations.HUMAN_LIGHT_FIRE_WITH_TINDERBOX_733) + runTask(player, 3) { + animate(player, -1, true) + setVarbit(player, 2046, 3) + // Player can do something else while the pot is lit, so a side pulse should be used. + player.pulseManager.run(object : Pulse(20) { // 20 * 600ms(1 tick) = 12000ms = 12s + override fun pulse(): Boolean { + setVarbit(player, 2046, 4) + return true + } + }, PulseType.CUSTOM_1) + } + return@onUseWith true + } + + // Taking bone and pot from boiled pot boiler. + on(Scenery.POT_BOILER_14009, SCENERY, "remove-bone") { player, _ -> + val potOfVinegar = getAttribute(player, ATTRIBUTE_ACTIVE_POT_OF_VINEGAR, 0) + if (BoneBoilerEnum.forBoneInVinegar(potOfVinegar) != null) { + val boneBoiler = BoneBoilerEnum.forBoneInVinegar(potOfVinegar)!! + setAttribute(player, ATTRIBUTE_ACTIVE_POT_OF_VINEGAR, 0) + addItemOrDrop(player, boneBoiler.polishedBone) + addItemOrDrop(player, Items.EMPTY_POT_1931) + sendMessage(player, "You retrieve a polished " + boneBoiler.boneDescription + " from the pot.") + } + setVarbit(player, 2046, 0) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/RamBehavior.kt b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/RamBehavior.kt new file mode 100644 index 0000000..b98630e --- /dev/null +++ b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/RamBehavior.kt @@ -0,0 +1,34 @@ +package content.region.misthalin.silvarea.quest.ragandboneman + +import content.data.Quests +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.tools.RandomFunction +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class RamBehavior : NPCBehavior(*ramIds) { + companion object { + private val ramIds = intArrayOf( + NPCs.RAM_3672, + NPCs.RAM_3673, + NPCs.RAM_5168, + NPCs.RAM_5169, + NPCs.RAM_5170, + ) + } + + override fun onDropTableRolled(self: NPC, killer: Entity, drops: ArrayList) { + super.onDropTableRolled(self, killer, drops) + // Drops the Ram Skull during Rag and Bone Man quest + if (killer is Player && isQuestInProgress(killer, Quests.RAG_AND_BONE_MAN, 1, 99)) { + if(RandomFunction.roll(4)) { + drops.add(Item(Items.RAM_SKULL_7818)); + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/UnicornBehavior.kt b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/UnicornBehavior.kt new file mode 100644 index 0000000..894f026 --- /dev/null +++ b/Server/src/main/content/region/misthalin/silvarea/quest/ragandboneman/UnicornBehavior.kt @@ -0,0 +1,32 @@ +package content.region.misthalin.silvarea.quest.ragandboneman + +import content.data.Quests +import core.api.isQuestInProgress +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.tools.RandomFunction +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class UnicornBehavior : NPCBehavior(*unicornIds) { + companion object { + private val unicornIds = intArrayOf( + NPCs.UNICORN_89, + NPCs.UNICORN_987, + NPCs.BLACK_UNICORN_133, + ) + } + + override fun onDropTableRolled(self: NPC, killer: Entity, drops: ArrayList) { + super.onDropTableRolled(self, killer, drops) + // Drops the Unicorn Bone during Rag and Bone Man quest + if (killer is Player && isQuestInProgress(killer, Quests.RAG_AND_BONE_MAN, 1, 99)) { + if(RandomFunction.roll(4)) { + drops.add(Item(Items.UNICORN_BONE_7821)); + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/AeonisigRaispher.java b/Server/src/main/content/region/misthalin/varrock/dialogue/AeonisigRaispher.java new file mode 100644 index 0000000..b461bbb --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/AeonisigRaispher.java @@ -0,0 +1,155 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the npc Aeonisig Raispher dialogue plugin. + * @author 'Vexia + * @version 1.5 + * @note Found transcript on + * (http://2009scape.wikia.com/wiki/Aeonisig_Raispher/dialogue) + */ +@Initializable +public final class AeonisigRaispher extends DialoguePlugin { + + /** + * Represents the public id of this dialogue. + */ + public static final int ID = 4710; + + /** + * Constructs a new {@code AeonisigRaispher} {@code Object}. + */ + public AeonisigRaispher() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code AeonisigRaispher} {@code Object}. + * @param player the player. + */ + public AeonisigRaispher(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new AeonisigRaispher(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + npc("Please only talk to the King if it's important. He has a", "heavy burden to bear with the running of his Kingdom."); + stage = -1; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case -1: + options("Who are you?", "What do you do here?", "Where did you come from?", "How did you come to be an advisor to King Roald?", "What is happening in the kingdom?"); + stage = -2; + break; + case -2: + switch (buttonId) { + case 1: + player("Who are you?"); + stage = 1; + break; + case 2: + player("What do you do here?"); + stage = 20; + break; + case 3: + player("Where did you come from?"); + stage = 30; + break; + case 4: + player("How did you come to be an advisor to King Roald?"); + stage = 40; + break; + case 5: + player("What is happening in the kingdom?"); + stage = 50; + break; + } + break; + case 20: + npc("My main function is to ensure that King Roald is apprised", "of all options, especially those that favour the", "righteous followers of Saradomin."); + stage = 21; + break; + case 21: + player("But surely the King should be able to make", "his own decisions on what's best for Misthalin?"); + stage = 22; + break; + case 22: + npc("What an interesting perspective you have! Totally", "unworkable of course, but interesting nonetheless."); + stage = 23; + break; + case 23: + end(); + break; + case 30: + npc("I took my religious and combat training in several parts", "of the known world. I've also fought despicable beasts", "in the wilderness in Saradomin's name. Needless to say I", "have great experienc in the ways of the world and am an"); + stage = 29; + break; + case 29: + npc("invaluable aid to his ordship's decision making process."); + stage = 31; + break; + case 31: + end(); + break; + case 40: + npc("The King of Misthalin, like any great leader, always", "requires the best advice and the best advisors. He very", "often summons occasional advisors to help him in", "certain situations, but it was felt by the Church"); + stage = 39; + break; + case 39: + npc("of Saradomin that a full time advisor on religious matters", "was needed to ensure fair treatement", "of Saradomin's followers."); + stage = 41; + break; + case 41: + player("How come he doesn't have an advisor for", "any other religious denominations?"); + stage = 42; + break; + case 42: + npc("Because I simply won't stand for it, that's why!", "Now, enough of your impertinent questions.", "I have work to do!"); + stage = 43; + break; + case 43: + end(); + break; + case 50: + npc("Nothing out of the usual."); + stage = 51; + break; + case 51: + end(); + break; + case 1: + npc("Apologies! Allow me to introduce myself. My", "name is Aeonisig Raispher, special advisor", "to King Roald on spiritual matters."); + stage = 2; + break; + case 2: + npc("It means that some decisions the King has to make might", "have unforeseen repercussions on the nation's spiritual", "sensibilities. My duty is to ensure that Saradomin", "ideals are not stomped underfoot."); + stage = 3; + break; + case 3: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { ID }; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/AmbassadorFernook.java b/Server/src/main/content/region/misthalin/varrock/dialogue/AmbassadorFernook.java new file mode 100644 index 0000000..4748e93 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/AmbassadorFernook.java @@ -0,0 +1,77 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the dialogue plugin used for ambassador fernook. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class AmbassadorFernook extends DialoguePlugin { + + /** + * Constructs a new {@code AmbassadorFernook} {@code Object}. + */ + public AmbassadorFernook() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code AmbassadorFernook} {@code Object}. + * @param player the player. + */ + public AmbassadorFernook(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new AmbassadorFernook(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello Ambassador. Are you here visiting King Roald?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Well, in theory, but he always seems to be busy."); + stage = 1; + break; + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "You don't seem that upset by that, though..."); + stage = 2; + break; + case 2: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Oh no, I like travelling, and if you become a diplomat", "patience is a vital skill."); + stage = 3; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'll try to remember that."); + stage = 4; + break; + case 4: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 4582 }; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/ApothecaryDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/ApothecaryDialogue.java new file mode 100644 index 0000000..d9ca490 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/ApothecaryDialogue.java @@ -0,0 +1,278 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.item.GroundItem; +import core.game.node.item.GroundItemManager; +import core.plugin.Initializable; +import core.game.node.item.Item; +import content.data.Quests; + +/** + * Represents the dialogue plugin used for the apothecary npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class ApothecaryDialogue extends DialoguePlugin { + + /** + * Represents the potion requirements. + */ + private static final Item[] POTION_ITEMS = new Item[] { new Item(223), new Item(225), new Item(995, 5) }; + + /** + * Represents the potion item. + */ + private static final Item POTION = new Item(115); + + /** + * Represents the unkown potion. + */ + private static final Item UNKNOWN_POTION = new Item(195, 1); + + /** + * Represents the cadava berries item. + */ + private static final Item CADAVA_BERRIES = new Item(753); + + /** + * Represents the cadava potion item. + */ + private static final Item CADAVA_POTION = new Item(756); + + /** + * Constructs a new {@code ApothecaryDialogue} {@code Object}. + */ + public ApothecaryDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code ApothecaryDialogue} {@code Object}. + * @param player the player. + */ + public ApothecaryDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new ApothecaryDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + if (player.getQuestRepository().getQuest(Quests.ROMEO_JULIET).getStage(player) == 40) { + interpreter.sendDialogues(player, null, "Apothecary. Father Lawrence sent me."); + stage = 500; + return true; + } + if (player.getQuestRepository().getQuest(Quests.ROMEO_JULIET).getStage(player) == 50) { + if (!player.getInventory().contains(753, 1)) { + npc("Keep searching for those Cadava berries. They're needed", "for the potion."); + stage = 507; + return true; + } else { + npc("Well done. You have the berries."); + stage = 637; + return true; + } + } + if (player.getQuestRepository().getQuest(Quests.ROMEO_JULIET).getStage(player) == 60) { + if (!player.getInventory().contains(756, 1) && !player.getBank().contains(756, 1)) { + if (player.getInventory().contains(753, 1)) { + npc("Well done. You have the berries."); + stage = 637; + return true; + } else { + npc("Keep searching for those Cadava berries. They're needed", "for the potion."); + stage = 507; + return true; + } + } else { + npc("I am the Apothecary. I brew potions.", "Do you need anything specific?"); + } + } + npc("I am the Apothecary. I brew potions.", "Do you need anything specific?"); + stage = 1; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 1: + options("Can you make a strength potion?", "Do you know a potion to make hair fall out?", "Have you got any good potions to give away?", "Can you make a potion that makes it seem like I'm dead?"); + stage = 2; + break; + case 2: + switch (buttonId) { + case 1: + player("Can you make a strength potion?"); + stage = 10; + break; + case 2: + player("Do you know a potion to make hair fall out?"); + stage = 20; + break; + case 3: + player("Have you got any good potions to give away?"); + stage = 140; + break; + case 4: + player("Can you make a potion that makes it seems like I'm dead?"); + stage = 40; + break; + } + + break; + case 10: + if (player.getInventory().containItems(223, 225)) { + npc("Certainly, just hand over the ingredients and 5 coins."); + stage = 50; + return true; + } + npc("Yes, but the ingredients are a little hard to find. If you", "ever get them I will make it for you, for a fee."); + stage = 11; + break; + case 50: + if (!player.getInventory().contains(995, 5)) { + end(); + player.getPacketDispatch().sendMessage("You need 5 gold coins to do that."); + return true; + } + interpreter.sendDialogue("You hand over the ingredients and money."); + stage = 51; + break; + case 51: + if (player.getInventory().remove(POTION_ITEMS)) { + player.getInventory().add(POTION); + end(); + player.getAchievementDiaryManager().finishTask(player, DiaryType.VARROCK, 1, 0); + } + break; + case 11: + player("So what are the ingredients?"); + stage = 12; + break; + case 12: + npc("You'll need to find the eggs of the deadly red spider and a", "limpwurt root."); + stage = 13; + break; + case 13: + npc("Oh and you'll have to pay me 5 coins."); + stage = 14; + break; + case 14: + player("Ok, I'll look out for them."); + stage = 15; + break; + case 15: + end(); + break; + case 20: + npc("I do indeed. I gave it to my mother. That's why I now live", "alone."); + stage = 21; + break; + case 21: + end(); + break; + case 30: + npc("Ok then. Try this potion."); + player.getInventory().add(UNKNOWN_POTION); + stage = 31; + break; + case 31: + end(); + break; + case 40: + npc("What a strange and morbid request! I can as it happens.", "The berry of the cadava bush, prepared properly, will", "induce a coma so deep that you will seem to be dead. It's", "very dangerous."); + stage = 41; + break; + case 41: + npc("I have the other ingredients, but I'll need you to bring me", "one bunch of cadava berries."); + stage = 42; + break; + case 42: + player("I'll bear that in mind."); + stage = 43; + break; + case 43: + end(); + break; + case 140: + npc("Sorry, charity is not my strong point."); + stage = 141; + break; + case 141: + end(); + break; + case 500: + interpreter.sendDialogues(player, null, "I need a Cadava potion to help Romeo and Juliet."); + stage = 501; + break; + case 501: + interpreter.sendDialogues(npc, null, "Cadava potion. It's pretty nasty. And hard to make."); + stage = 502; + break; + case 502: + interpreter.sendDialogues(npc, null, "Wing of rat, tail of frog.", "Ear of snake and horn of dog."); + stage = 503; + break; + case 503: + interpreter.sendDialogues(npc, null, "I have all that, but I need some Cadava berries."); + stage = 504; + break; + case 504: + interpreter.sendDialogues(npc, null, "You will have to find them while I get the rest ready."); + stage = 505; + break; + case 505: + interpreter.sendDialogues(npc, null, "Bring them here when you have them. But be careful.", "They are nasty."); + stage = 506; + break; + case 506: + player.getQuestRepository().getQuest(Quests.ROMEO_JULIET).setStage(player, 50); + interpreter.sendDialogues(player, null, "Ok, thanks."); + stage = 507; + break; + case 507: + end(); + break; + case 637: + interpreter.sendItemMessage(753, "You hand over the berries."); + stage = 638; + break; + case 638: + if (player.getInventory().remove(CADAVA_BERRIES)) { + npc("Phew! Here is what you need."); + } + stage = 639; + break; + case 639: + if (!player.getInventory().add(CADAVA_POTION)) { + GroundItemManager.create(new GroundItem(CADAVA_POTION, player.getLocation(), player)); + } + interpreter.sendItemMessage(756, "The Apothecary gives you a Cadava potion."); + stage = 640; + break; + case 640: + player.getQuestRepository().getQuest(Quests.ROMEO_JULIET).setStage(player, 60); + end(); + break; + } + + return true; + } + + @Override + public int[] getIds() { + return new int[] { 638 }; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/AsyffDialogue.kt b/Server/src/main/content/region/misthalin/varrock/dialogue/AsyffDialogue.kt new file mode 100644 index 0000000..0ab285b --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/AsyffDialogue.kt @@ -0,0 +1,60 @@ +package content.region.misthalin.varrock.dialogue + +import core.game.component.Component +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable + +/** + * Dialogue for Asyff, the fancy dress shop owner + * @author Ceikry + */ +@Initializable +class AsyffDialogue(player: Player? = null) : DialoguePlugin(player){ + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> player(FacialExpression.ASKING,"Err...what are you saying exactly?").also { stage++ } + 1 -> npc(FacialExpression.LAUGH,"I'm just saying that perhaps you would","like to peruse my selection of garments.").also { stage++ } + 2 -> npc(FacialExpression.LAUGH,"Or, if that doesn't interest you, then maybe you have","something else to offer? I'm always on the look out","for interesting or unusual new materials.").also { stage++ } + 3 -> options("Okay, let's see what you've got then.","Can you make clothing suitable for hunting in?","I think I might just leave the perusing for now thanks.","What sort of unusual materials did you have in mind?").also { stage++ } + 4 -> when(buttonId){ + 1 -> player("Okay, let's see what you've got then.").also { stage = 10 } + 2 -> player("Can you make clothing suitable for hunting?").also { stage = 20 } + 3 -> player("I think I might just leave the perusing for now, thanks.").also { stage = 30 } + 4 -> player("What sort of unusual materials did you have in mind?").also { stage = 40 } + } + + //Okay, let's see what you've got then + 10 -> end().also { npc.openShop(player) } + + //Can you make clothing suitable for hunting + 20 -> end().also { player.interfaceManager.open(Component(477)) }//Open custom fur clothing interface + + //I think I might just leave the perusing for now, thanks. + 30 -> end() + + //What sort of unusual materials do you have in mind? + 40 -> npc("Well, some more colourful feathers might be useful.","For some surreal reason, all I normally seem to get offered","are large quantities of rather beaten up chicken feathers.").also { stage++ } + 41 -> npc("People must have some very strange pastimes around","these parts, that's all I can say.").also { stage++ } + 42 -> player("Ok, let's see what you've got then.").also { stage = 10 } + } + return true + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npc(FacialExpression.HAPPY,"Now you look like someone who goes to","a lot of fancy dress parties.") + stage = 0 + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return AsyffDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(554) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/BaraekDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/BaraekDialogue.java new file mode 100644 index 0000000..ab062f4 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/BaraekDialogue.java @@ -0,0 +1,385 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.GroundItemManager; +import core.plugin.Initializable; +import core.game.node.item.Item; +import content.data.Quests; + +/** + * Represents the dialogue plugin used for the baraek npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class BaraekDialogue extends DialoguePlugin { + + /** + * Represents the fur item. + */ + private static final Item FUR = new Item(6814); + + /** + * Represents the buy coins item. + */ + private static final Item BUY_COINS = new Item(995, 12); + + /** + * Represents the coins item. + */ + private static final Item COINS = new Item(995, 20); + + /** + * Represents the quest instance. + */ + private Quest quest; + + /** + * Constructs a new {@code BaraekDialogue} {@code Object}. + */ + public BaraekDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code BaraekDialogue} {@code Object}. + * @param player the player. + */ + public BaraekDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new BaraekDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + quest = player.getQuestRepository().getQuest(Quests.SHIELD_OF_ARRAV); + switch (quest.getStage(player)) { + case 30: + if (!player.getInventory().containsItem(FUR)) { + interpreter.sendOptions("Select an Option", "Can you tell me where I can find the Phoenix Gang?", "Can you sell me some furs?", "Hello. I am in search of a quest."); + stage = 0; + } else { + interpreter.sendOptions("Select an Option", "Can you tell me where I can find the Phoenix Gang?", "Can you sell me some furs?", "Hello. I am in search of a quest.", "Would you like to buy my fur?"); + stage = 40; + } + break; + default: + if (player.getInventory().containsItem(FUR)) { + options("Can you sell me some furs?", "Hello. I am in search of a quest.", "Would you like to buy my fur?"); + stage = 40; + } else { + options("Can you sell me some furs?", "Hello. I am in search of a quest."); + stage = 0; + } + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (quest.getStage(player)) { + case 40: + switch (stage) { + case 111: + npc("Gang. they're operating there under the name of", "VTAM Corporation. Be careful. The Phoenixes ain't", "the type to be messed about."); + stage = 112; + break; + case 112: + player("Thanks!"); + stage = 113; + break; + case 113: + end(); + break; + case 120: + npc("Heh. If you wanna deal with the Phoenix Gand they're", "involved in much worse than a bit of briber."); + stage = 121; + break; + case 121: + end(); + break; + case 130: + end(); + break; + } + case 30: + switch (stage) { + case 0: + switch (buttonId) { + case 1: + player("Can you tell me where I can find the Phoenix Gang?"); + stage = 10; + break; + case 2: + player("Can you sell me some furs?"); + stage = 20; + break; + case 3: + player("Hello! I am in search of a quest."); + stage = 30; + break; + } + break; + case 10: + npc("Sh sh sh, not so loud! You don't want to get me in", "trouble!"); + stage = 11; + break; + case 11: + player("So DO you know where they are?"); + stage = 12; + break; + case 12: + npc("I may do."); + stage = 13; + break; + case 13: + npc("But I don't to get in trouble for revealing their", "hideout."); + stage = 14; + break; + case 14: + npc("Of course, if I was, say 20 gold coins richer I may", "happen to be more inclined to take that sort of risk..."); + stage = 15; + break; + case 15: + options("Okay. Have 20 gold coins.", "No, I don't like things like bribery.", "Yes. I'd like to be 20 gold coins richer too."); + stage = 16; + break; + case 16: + switch (buttonId) { + case 1: + player("Okay. Have 20 gold coins."); + stage = 110; + break; + case 2: + player("No, I don't like things like bribery."); + stage = 120; + break; + case 3: + player("Yes. I'd like to be 20 gold coins richer too."); + stage = 130; + break; + } + break; + case 110: + if (!player.getInventory().containsItem(COINS)) { + break; + } + if (player.getInventory().remove(COINS)) { + quest.setStage(player, 40); + npc("Ok, to get to the gang hideout, enter Varrock through", "the south gate. Then, if you take the first turning east", "somewhere along there is an alleway to the south. The", "door at the end of there is an entrance to the Phoenix"); + stage = 111; + } else { + player("I don't have enough coins."); + stage = 121; + } + break; + case 121: + end(); + break; + case 30: + npc("Sorry kiddo, I'm a fur trader not a damsel in distress."); + stage = 31; + break; + case 31: + end(); + break; + case 40: + switch (buttonId) { + case 1: + player("Can you tell me where I can find the Phoenix Gang?"); + stage = 10; + break; + case 2: + stage = 80; + handleFurBuy(buttonId); + break; + case 3: + player("Hello! I am in search of a quest."); + stage = 30; + break; + case 4: + player("Can you sell me some furs?"); + stage = 20; + break; + } + break; + default: + handleFurBuy(buttonId); + handleFurSelling(buttonId); + break; + } + break; + default: + switch (stage) { + case 0: + switch (buttonId) { + case 1: + player("Can you sell me some furs?"); + stage = 20; + break; + case 2: + player("Hello! I am in search of a quest."); + stage = 30; + break; + } + break; + case 30: + npc("Sorry kiddo, I'm a fur trader not a damsel in distress."); + stage = 31; + break; + case 31: + end(); + break; + case 40: + switch (buttonId) { + case 1: + player("Can you sell me some furs?"); + stage = 20; + break; + case 2: + player("Hello! I am in search of a quest."); + stage = 30; + break; + case 3: + stage = 80; + handleFurBuy(buttonId); + break; + } + break; + default: + handleFurBuy(buttonId); + handleFurSelling(buttonId); + break; + } + break; + } + return true; + } + + /** + * Method used to handle the fur selling. + * @param buttonId the button id. + */ + public void handleFurSelling(int buttonId) { + switch (stage) { + case 20: + npc("Yeah, sure. They're 20 gold coins each."); + stage = 21; + break; + case 21: + options("Yeah, okay, here you go.", "20 gold coins? That's an outrade!"); + stage = 22; + break; + case 22: + switch (buttonId) { + case 1: + player("Yeah, OK, here you go."); + stage = 25; + break; + case 2: + player("20 gold coins? That's an outrage!"); + stage = 23; + break; + } + break; + case 23: + npc("Well, I can't go any cheaper than that mate. I have a", "family to feed."); + stage = 24; + break; + case 24: + end(); + break; + case 25: + if (player.getInventory().remove(COINS)) { + if (!player.getInventory().add(FUR)) { + GroundItemManager.create(FUR, player); + } + interpreter.sendItemMessage(FUR.getId(), "Baraeck sells you a fur."); + stage = 26; + } else { + player("Oops, I dont' seem to have enough coins."); + stage = 24; + } + break; + case 26: + end(); + break; + } + } + + /** + * Method used to handle the buying of fur. + * @param buttonId the buttonId. + */ + public void handleFurBuy(int buttonId) { + switch (stage) { + case 80: + player("Would you like to buy my fur?"); + stage = 81; + break; + case 81: + npc("Let's have a look at it."); + stage = 82; + break; + case 82: + interpreter.sendItemMessage(FUR.getId(), "You hand Baraeck your fur to look at."); + stage = 83; + break; + case 83: + npc("It's not in the best condition. I guess I could give you", "12 coins for it."); + stage = 84; + break; + case 84: + options("Yeah, that'll do.", "I think I'll keep hold of it actually."); + stage = 85; + break; + case 85: + switch (buttonId) { + case 1: + player("Yeah, that'll do."); + stage = 89; + break; + case 2: + player("I think I'll keep hold of it actually!"); + stage = 87; + break; + } + break; + case 87: + npc("Oh ok. Didn't want it anyway!"); + stage = 88; + break; + case 88: + end(); + break; + case 89: + if (player.getInventory().remove(FUR)) { + if (!player.getInventory().add(BUY_COINS)) { + GroundItemManager.create(BUY_COINS, player); + } + player("Thanks!"); + stage = 90; + } + break; + case 90: + end(); + break; + } + } + + @Override + public int[] getIds() { + return new int[] { 547 }; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/BennyDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/BennyDialogue.java new file mode 100644 index 0000000..9b03942 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/BennyDialogue.java @@ -0,0 +1,163 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.plugin.Initializable; +import core.game.node.item.Item; + +/** + * Represents the dialogue plugin used for the benny npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class BennyDialogue extends DialoguePlugin { + + /** + * Represents the item coins related to benny. + */ + private static final Item COINS = new Item(995, 50); + + /** + * Represents the newspaper item related to benny. + */ + private static final Item NEWSPAPER = new Item(11169, 1); + + /** + * Constructs a new {@code BennyDialogue} {@code Object}. + */ + public BennyDialogue() { + /* + * ( empty. + */ + } + + /** + * Constructs a new {@code BennyDialogue} {@code Object}. + * @param player the player. + */ + public BennyDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new BennyDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + options("Can I have a newspaper, please?", "How much does a paper cost?", "Varrock Herald? Never heard of it.", "Anything interesting in there?"); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + switch (buttonId) { + case 1: + player("Can I have a newspaper, please?"); + stage = 10; + break; + case 2: + player("How much does a paper cost?"); + stage = 20; + break; + case 3: + player("Varrock Herald? Never heard of it."); + stage = 30; + break; + case 4: + player("Anything interesting in there?"); + stage = 40; + break; + } + break; + case 10: + npc("Certainly, Guv. That'll be 50 gold pieces, please."); + stage = 11; + break; + case 11: + options("Sure, here you go.", "Uh, no thanks, I've changed my mind"); + stage = 12; + break; + case 12: + switch (buttonId) { + case 1: + player("Sure, here you go."); + stage = 13; + break; + case 2: + player("No, thanks."); + stage = 14; + break; + } + break; + case 13: + if (!player.getInventory().contains(995, 50)) { + end(); + player.getPacketDispatch().sendMessage("You need 50 gold coins to buy a newspaper."); + + } else if (player.getInventory().freeSlot() == 0) { + end(); + player.getPacketDispatch().sendMessage("You don't have enough inventory space."); + } else { + if (!player.getInventory().containsItem(COINS)) { + end(); + return true; + } + player.getInventory().remove(COINS); + player.getInventory().add(NEWSPAPER); + player.getAchievementDiaryManager().finishTask(player, DiaryType.VARROCK, 0, 7); + end(); + } + break; + case 14: + npc("Ok, suit yourself. Plenty more fish in the sea."); + stage = 100; + break; + case 20: + npc("Just 50 gold pieces! An absolute bargain! Want one?"); + stage = 21; + break; + case 21: + options("Yes, please.", "No, thanks."); + stage = 22; + break; + case 22: + if (buttonId == 1) { + player("Yes, please."); + stage = 13; + } else if (buttonId == 2) { + player("No, thanks."); + stage = 14; + } + break; + case 30: + npc("For the illiterate amongst us, I shall elucidate. The", "Varrock Herald is a new newspaper. It is edited, printed", "and published by myself, Benny Gutenberg, and each", "edition promises to enthrall the reader with captivating "); + stage = 31; + break; + case 31: + npc("material! Now, can I interest you in buying one for a mere", "50 gold?"); + stage = 21; + break; + case 40: + npc("Of course there is, mate. Packed full of thought provoking", "insights, contentious interviews and celebrity", "scandalmongering! An excellent read and all for just 50", "coins! Want one?"); + stage = 21; + break; + case 100: + end(); + break; + } + return false; + } + + @Override + public int[] getIds() { + return new int[] { 5925 }; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/BobBarterDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/BobBarterDialogue.java new file mode 100644 index 0000000..140f402 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/BobBarterDialogue.java @@ -0,0 +1,121 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.ge.GEGuidePrice; +import core.game.ge.GEGuidePrice.GuideType; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the bob barter npc dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class BobBarterDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code BobBarterDialogue} {@code Object}. + */ + public BobBarterDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code BobBarterDialogue} {@code Object}. + * @param player the player. + */ + public BobBarterDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new BobBarterDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + player("Hi."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + npc("Hello, chum, fancy buyin' some designer", "jewellery? They've come all the way from", "Ardougne! most pukka!"); + stage = 1; + break; + case 1: + player("Erm, no. I'm all set, thanks."); + stage = 2; + break; + case 2: + npc("Okay, chum. So what can I do for you? I can", "tell you the very latest herb prices."); + stage = 3; + break; + case 3: + interpreter.sendOptions("Select an Option", "Who are you?", "Can you help me out with the prices for herbs?", "Sorry, I've got to split."); + stage = 4; + break; + case 4: + switch (buttonId) { + case 1: + player("Who are you?"); + stage = 10; + break; + case 2: + player("Can you help me out with the prices for herbs?"); + stage = 20; + break; + case 3: + player("Sorry, I've got to split."); + stage = 30; + break; + } + break; + case 30: + end(); + break; + case 10: + npc("Why, I'm Bob! Your friendly seller of goods!"); + stage = 11; + break; + case 11: + player("So what do you have to sell?"); + stage = 12; + break; + case 12: + npc("Oh, not much at the moment. Cuz, ya know", "Business being so well and cushie."); + stage = 13; + break; + case 13: + player("You don't really look like you're being so", "successfull."); + stage = 14; + break; + case 14: + npc("You plonka! It's all a show, innit! If I let people", "knows I'm in good business they'll want a", "share of the moolah!"); + stage = 15; + break; + case 15: + end(); + break; + case 20: + end(); + GEGuidePrice.open(player, GuideType.HERBS); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 6524 }; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/DrHarlowDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/DrHarlowDialogue.java new file mode 100644 index 0000000..0e14e00 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/DrHarlowDialogue.java @@ -0,0 +1,190 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItem; +import core.game.node.item.GroundItemManager; +import core.plugin.Initializable; +import core.game.node.item.Item; +import content.data.Quests; + +/** + * Represents the dialogue used for dr harlow. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class DrHarlowDialogue extends DialoguePlugin { + + /** + * Represents the array of items related to dr harlow. + */ + private static final Item[] ITEMS = new Item[] { new Item(1549), new Item(1917, 1) }; + + /** + * Constructs a new {@code DrHarlowDialogue} {@code Object}. + */ + public DrHarlowDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code DrHarlowDialogue} {@code Object}. + * @param player the player. + */ + public DrHarlowDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new DrHarlowDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Buy me a drrink pleassh."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + if (player.getQuestRepository().getQuest(Quests.VAMPIRE_SLAYER).getStage(player) == 10) { + interpreter.sendOptions("Select an Option", "No, you've had enough.", "Morgan needs your help!"); + stage = 1; + } else if (player.getQuestRepository().getQuest(Quests.VAMPIRE_SLAYER).getStage(player) == 20) { + if (player.getInventory().contains(1917, 1)) { + interpreter.sendDialogues(player, null, "Here you go."); + stage = 20; + } else { + interpreter.sendDialogues(player, null, "I'll just go and buy one."); + stage = 2; + } + } else if (player.getQuestRepository().getQuest(Quests.VAMPIRE_SLAYER).getStage(player) == 30) { + if (!player.getBank().contains(1549, 1) && !player.getInventory().contains(1549, 1)) { + if (!player.getInventory().add(ITEMS[0])) { + GroundItem item = new GroundItem(ITEMS[0], npc.getLocation(), player); + GroundItemManager.create(item); + } + interpreter.sendItemMessage(1549, "Dr Harlow hands you a stake."); + stage = 27; + return true; + } + if (player.getInventory().contains(1917, 1)) { + interpreter.sendDialogues(player, null, "Here you go."); + stage = 20; + } else { + interpreter.sendDialogues(player, null, "I'll just go and buy one."); + stage = 2; + } + } else { + interpreter.sendDialogues(player, null, "No, you've had enough."); + stage = 2; + } + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, null, "No, you've had enough."); + stage = 2; + break; + case 2: + interpreter.sendDialogues(player, null, "Morgan needs your help!"); + stage = 5; + break; + } + break; + case 5: + interpreter.sendDialogues(npc, null, "Morgan you shhay..?"); + stage = 6; + break; + case 6: + interpreter.sendDialogues(player, null, "His village is being terrorised by a vampire! He told me", "to ask you about how I can stop it."); + stage = 7; + break; + case 7: + interpreter.sendDialogues(npc, null, "Buy me a beer... then I'll teash you what you need to", "know..."); + stage = 8; + break; + case 8: + interpreter.sendDialogues(player, null, "But this is your friend Morgan we're talking about!"); + stage = 9; + break; + case 9: + interpreter.sendDialogues(npc, null, "Buy ush a drink anyway..."); + stage = 10; + break; + case 10: + player.getQuestRepository().getQuest(Quests.VAMPIRE_SLAYER).setStage(player, 20); + end(); + break; + case 2: + end(); + break; + case 20: + if (player.getInventory().remove(ITEMS[1])) { + interpreter.sendItemMessage(1917, "You give a beer to Dr Harlow."); + player.getQuestRepository().getQuest(Quests.VAMPIRE_SLAYER).setStage(player, 30); + stage = 21; + } + break; + case 21: + interpreter.sendDialogues(npc, null, "Cheersh matey..."); + stage = 22; + break; + case 22: + interpreter.sendDialogues(player, null, "So tell me how to kill vampires then."); + stage = 23; + break; + case 23: + interpreter.sendDialogues(npc, null, "Yesh Yesh vampires, I was very good at", "killing em once..."); + stage = 24; + break; + case 24: + interpreter.sendDialogue("Dr Harlow appears to sober up slightly."); + stage = 25; + break; + case 25: + interpreter.sendDialogues(npc, null, "Well you're gonna to need a stake, otherwise he'll just", "regenerate. Yes, you must have a stake to finish it off..", "I just happen to have one with me."); + stage = 26; + break; + case 26: + if (!player.getInventory().add(ITEMS[0])) { + GroundItem item = new GroundItem(ITEMS[0], npc.getLocation(), player); + GroundItemManager.create(item); + } + interpreter.sendItemMessage(1549, "Dr Harlow hands you a stake."); + stage = 27; + break; + case 27: + interpreter.sendDialogues(npc, null, "You'll need a hammer as well, to drive it in properly,", "your everyday general store hammer will do. One last", "thing... It's wise to carry garlic with you, vampires are", "somewhat weakend if they can smell garlic. Morgan"); + stage = 28; + break; + case 28: + interpreter.sendDialogues(npc, null, "alwys liked garlic, you should try his house. But", "remember, a vampire is still a dangerous foe!"); + stage = 29; + break; + case 29: + interpreter.sendDialogues(player, null, "Thank you very much!"); + stage = 30; + break; + case 30: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 756 }; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/DraulLeptoc.java b/Server/src/main/content/region/misthalin/varrock/dialogue/DraulLeptoc.java new file mode 100644 index 0000000..2b9875c --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/DraulLeptoc.java @@ -0,0 +1,73 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the dialogue plugin for the draul leptoc npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class DraulLeptoc extends DialoguePlugin { + + /** + * Constructs a new {@code DraulLeptoc} {@code Object}. + */ + public DraulLeptoc() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code DraulLeptoc} {@code Object}. + * @param player the player. + */ + public DraulLeptoc(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new DraulLeptoc(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "What are you doing in my house..why the", "impertinence...the sheer cheek...how dare you violate my", "personal lodgings...."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I...I was just looking around..."); + stage = 1; + break; + case 1: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Well get out! Get out....this is my house....and don't go", "near my daughter Juliet...she's grounded in her room", "to keep her away from that good for nothing Romeo."); + stage = 2; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Yes....sir...."); + stage = 3; + break; + case 3: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 3324 }; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/EllamariaDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/EllamariaDialogue.java new file mode 100644 index 0000000..eda264a --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/EllamariaDialogue.java @@ -0,0 +1,85 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the ellamaria dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class EllamariaDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code EllamariaDialogue} {@code Object}. + */ + public EllamariaDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code EllamariaDialogue} {@code Object}. + * @param player the player. + */ + public EllamariaDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new EllamariaDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What's going on here? I see a lot of farming patches", "with nothing growing in them."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "No, one has just had them installed. One has had the", "most marvellous idea to bring renewed happiness to", "one's own deatest husband."); + stage = 1; + break; + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "One? I'm not sure I understand you-"); + stage = 2; + break; + case 2: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Oh dear - the common classes, oh how they fill one with", "intolerable levels of exasperation, I swear to the most", "true."); + stage = 3; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Ri-ight ... if you say so, my lady. I'll be off then, if you", "don't mind."); + stage = 4; + break; + case 4: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Yes, be off with you, before I call the guards."); + stage = 5; + break; + case 5: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No problem, sorry to have bothered you."); + stage = 6; + break; + case 6:// TODO: ques.t + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 2581 }; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/ElsieDialogue.kt b/Server/src/main/content/region/misthalin/varrock/dialogue/ElsieDialogue.kt new file mode 100644 index 0000000..cef36f0 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/ElsieDialogue.kt @@ -0,0 +1,212 @@ +package content.region.misthalin.varrock.dialogue + +import core.api.inInventory +import core.api.removeItem +import core.api.sendItemDialogue +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import core.game.dialogue.Topic +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE + +@Initializable +class ElsieDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun newInstance(player: Player?): DialoguePlugin { + return ElsieDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + + if (hasTea()) { + npcl( + FacialExpression.FRIENDLY, + "Ooh - that looks like a lovely cup of tea, dearie. Is it for me?" + ).also { stage = 10 } + } else { + npcl( + FacialExpression.FRIENDLY, + "Hello dearie! What can old Elsie do for you?" + ) + } + + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + START_DIALOGUE -> showTopics( + Topic(FacialExpression.ASKING, "What are you making?", 1), + Topic(FacialExpression.ASKING, "Can you tell me a story?", 3), + Topic(FacialExpression.ASKING, "Can you tell me how to get rich?", 5), + Topic(FacialExpression.NEUTRAL, "I've got to go.", END_DIALOGUE) + ) + + 1 -> npcl( + FacialExpression.FRIENDLY, + "I'm knitting a new stole for Father Lawrence downstairs." + ).also { stage++ } + + 2 -> npcl( + FacialExpression.FRIENDLY, + "He could do with something to keep his neck warm, standing in " + + "that draughty old church all day." + ).also { stage = START_DIALOGUE } + + 3 -> { + if (hasTea()) { + npcl( + FacialExpression.HALF_THINKING, + "Perhaps... Can I have that lovely cup of tea you have over there?" + ).also { stage = 10 } + } else { + npcl( + FacialExpression.NEUTRAL, + "Maybe I could tell you a story if you'd fetch me a nice cup of tea." + ).also { stage++ } + } + } + + 4 -> playerl( + FacialExpression.ROLLING_EYES, + "I'll think about it." + ).also { stage = START_DIALOGUE } + + 5 -> npcl( + FacialExpression.NEUTRAL, + "Well, dearie, I am probably not the best person to ask about money, but I think the best thing " + + "would be for you to get a good trade." + ).also { stage++ } + + 6 -> npcl( + FacialExpression.HALF_WORRIED, + "If you've got a good trade you can earn your way. That's what my old father would tell me." + ).also { stage++ } + + 7 -> npcl( + FacialExpression.HALF_WORRIED, + "Saradomin rest his soul. I hear people try to get rich by fighting in the Wilderness north of here " + + "or the Duel Arena in the south... But that's no way for honest folk to earn a living!" + ).also { stage++ } + + 8 -> npcl( + FacialExpression.HALF_WORRIED, + "So get yourself a good trade, and keep working at it. There's always folks wanting to buy ore and food around here." + ).also { stage++ } + + 9 -> playerl( + FacialExpression.ROLLING_EYES, + "Thanks, old woman." + ).also { stage = START_DIALOGUE } + + 10 -> showTopics( + Topic(FacialExpression.HAPPY, "Yes, you can have it.", 12), + Topic(FacialExpression.ANNOYED, "No, keep your hands off my tea.", 11) + ) + + 11 -> npcl( + FacialExpression.SAD, + "Aww. Maybe another time, then... Anyway, what can old Elsie do for you?" + ).also { stage = START_DIALOGUE } + + 12 -> sendItemDialogue(player, Items.CUP_OF_TEA_712, "Elsie takes a sip from the cup of tea.") + .also { stage++; removeItem(player, Items.CUP_OF_TEA_712) } + + 13 -> npcl( + FacialExpression.HAPPY, + "Ahh, there's nothing like a nice cuppa tea. You know what, I'll tell you a story as a thank-you for that lovely tea..." + ).also { stage++ } + + 14 -> npcl( + FacialExpression.NEUTRAL, + "A long time ago, when I was a little girl, there was a handsome young man living in Varrock..." + ).also { stage++ } + + 15 -> npcl( + FacialExpression.HALF_GUILTY, + "I saw him here in the church quite often. Everyone said he was going to become a priest and " + + "we girls were so sad about that..." + ).also { stage++ } + + 16 -> npcl( + FacialExpression.NEUTRAL, + "But young Dissy - that was the young man's nickname - he was a wild young thing." + ).also { stage++ } + + 17 -> npcl( + FacialExpression.NEUTRAL, + "One night he gathered some lads together, and after the evening prayer-meeting " + + "they all put their masks on..." + ).also { stage++ } + + 18 -> npcl( + FacialExpression.NEUTRAL, + "Then, they snuck down to the temple in the south of the city - the evil one. " + + "The next day, there was quite a hubbub..." + ).also { stage++ } + + 19 -> npcl( + FacialExpression.LAUGH, + "The guards told us that someone had painted 'Saradomin pwns' on the wall of Zamorakian temple!" + ).also { stage++ } + + 20 -> npcl( + FacialExpression.HALF_THINKING, + "Now, we'd always been taught to keep well away from that dreadful place..." + ).also { stage++ } + + 21 -> npcl( + FacialExpression.FRIENDLY, + "But it really did us all good to see someone wasn't afraid of the scum who live at that end of town." + ).also { stage++ } + + 22 -> npcl( + FacialExpression.NEUTRAL, + "Old Father Packett was furious, but Dissy just laughed it off. " + + "Dissy left town after that, saying he wanted to see the world." + ).also { stage++ } + + 23 -> npcl( + FacialExpression.HALF_GUILTY, + "It was such a shame, he had the most handsome... Shoulders..." + ).also { stage++ } + + 24 -> npcl( + FacialExpression.HAPPY, + "One day, a young man came here looking for stories about Dissy - of course, " + + "that's not his proper name, but his friends called him Dissy - and I told " + + "him that one. " + ).also { stage++ } + + 25 -> npcl( + FacialExpression.HALF_WORRIED, + "He said Dissy had become a really famous man and there was going to be a book about him. " + + "That's good and all, but I do wish Dissy had just come back to Varrock. I did miss him so much... " + ).also { stage++ } + + 26 -> npcl( + FacialExpression.HAPPY, + "Well, until I met my Freddie and we got married. But that's another story." + ).also { stage++ } + + 27 -> playerl( + FacialExpression.FRIENDLY, + "Thank you. I'll leave you to your knitting now." + ).also { stage = END_DIALOGUE } + } + + return true + } + + override fun getIds(): IntArray = intArrayOf(NPCs.ELSIE_5915) + + private fun hasTea(): Boolean { + return inInventory(player, Items.CUP_OF_TEA_712) + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/FaridMorrisaneDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/FaridMorrisaneDialogue.java new file mode 100644 index 0000000..d7774b7 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/FaridMorrisaneDialogue.java @@ -0,0 +1,122 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.plugin.Initializable; +import core.game.ge.GEGuidePrice; +import core.game.ge.GEGuidePrice.GuideType; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; + +/** + * Represents the farid morrisane dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class FaridMorrisaneDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code FaridMorrisaneDialogue} {@code Object}. + */ + public FaridMorrisaneDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code FaridMorrisaneDialogue} {@code Object}. + * @param player the player. + */ + public FaridMorrisaneDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new FaridMorrisaneDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello, little boy."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I would prefer it if you didn't speak to me in such a", "manner. I'll have you know I'm an accomplished", "merchant."); + stage = 1; + break; + case 1: + interpreter.sendOptions("Select an Option", "Calm down, junior.", "Can you help me out with the prices for ores?", "I best go and speak with someone my height."); + stage = 2; + break; + case 2: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Calm down, junior."); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Can you help me out with the prices for ores?"); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I best go and speak with someone more my height."); + stage = 30; + break; + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Don't tell me to calm down! And don't call me 'junior'."); + stage = 11; + break; + case 11: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I'll have you know I am Farid Morrisane, son of Ali", "Morrisane, the worlds greatest merchant!"); + stage = 12; + break; + case 12: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Then why are you here and not him?"); + stage = 13; + break; + case 13: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "My dad has given me the responsibility of", "expanding our business here."); + stage = 14; + break; + case 14: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "And you're up to the task?"); + stage = 15; + break; + case 15: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What a grown up boy you are! Mummy and", "daddy must be very pleased!"); + stage = 16; + break; + case 16: + end(); + break; + case 20: + end(); + GEGuidePrice.open(player, GuideType.ORES); + break; + case 30: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Then I shall not stop you, mister. I've too", "much work to do."); + stage = 31; + break; + case 31: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 6523 }; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/FatherLawrenceDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/FatherLawrenceDialogue.java new file mode 100644 index 0000000..db0f198 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/FatherLawrenceDialogue.java @@ -0,0 +1,184 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.game.node.entity.player.link.quest.Quest; +import content.data.Quests; + +/** + * Represents the father lawrence dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class FatherLawrenceDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code FatherLawrenceDialogue} {@code Object}. + */ + public FatherLawrenceDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code FatherLawrenceDialogu} {@code Object}. + * @param player the player. + */ + public FatherLawrenceDialogue(Player player) { + super(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + final Quest quest = player.getQuestRepository().getQuest(Quests.ROMEO_JULIET); + if (quest.getStage(player) < 30) { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Oh to be a father in the times of whiskey."); + stage = 0; + } + switch (quest.getStage(player)) { + case 30: + interpreter.sendDialogues(npc, null, "\"...and let Saradomin light the way for you... \"", "Urgh!"); + stage = 41; + break; + case 40: + interpreter.sendDialogues(npc, null, "Ah, have you found the Apothecary yet? Remember,", "Cadava potion, for Juliet."); + stage = 30; + break; + case 50: + interpreter.sendDialogues(npc, null, "Did you find the Apothecary?"); + stage = 820; + break; + case 60: + case 70: + interpreter.sendDialogues(npc, null, "Did you find the Apothecary?"); + stage = 820; + break; + case 100: + player("Hi again!"); + stage = 0; + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + final Quest quest = player.getQuestRepository().getQuest(Quests.ROMEO_JULIET); + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I sing and I drink and I wake up in gutters."); + stage = 1; + break; + case 1: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Top of the morning to you."); + stage = 2; + break; + case 2: + end(); + break; + case 41: + interpreter.sendDialogues(npc, null, "Can't you see that I'm in the middle of a Sermon?!"); + stage = 42; + break; + case 42: + interpreter.sendDialogues(player, null, "But Romeo sent me!"); + stage = 43; + break; + case 43: + interpreter.sendDialogues(npc, null, "But I'm busy delivering a sermon to my congregation!"); + stage = 44; + break; + case 44: + interpreter.sendDialogues(player, null, "Yes, well, it certainly seems like you have a captive", "audience!"); + stage = 45; + break; + case 45: + interpreter.sendDialogues(npc, null, "Ok, ok...what do you want so I can get rid of you and", "continue with my sermon?"); + stage = 46; + break; + case 46: + interpreter.sendDialogues(player, null, "Romeo sent me. He says you may be able to help."); + stage = 47; + break; + case 47: + interpreter.sendDialogues(npc, null, "Ah Romeo, yes. A fine lad, but a little bit confused."); + stage = 48; + break; + case 48: + interpreter.sendDialogues(player, null, "Yes, very confused....Anyway, Romeo wishes to be", "married to Juliet! She must be rescued from her", "father's control!"); + stage = 49; + break; + case 49: + interpreter.sendDialogues(npc, null, "I agree, and I think I have an idea! A potion to make", "her appear dead..."); + stage = 50; + break; + case 50: + interpreter.sendDialogues(player, null, "Dead! Sounds a bit creepy to me...but please, continue."); + stage = 51; + break; + case 51: + interpreter.sendDialogues(npc, null, "The potion will only make Juliet 'appear' dead...then", "she'll be taken to the crypt..."); + stage = 52; + break; + case 52: + interpreter.sendDialogues(player, null, "Crypt! Again...very creepy! You must have some", "strange hobbies."); + stage = 53; + break; + case 53: + interpreter.sendDialogues(npc, null, "Then Romeo can collect her from the crypt! Go to the", "Apothecary, tell him I sent you and that you'll need a", "'Cadava' potion."); + stage = 54; + break; + case 54: + interpreter.sendDialogues(player, null, "Apart from the strong overtones of death, this is", "turning out to be a real love story."); + stage = 55; + break; + case 55: + quest.setStage(player, 40); + end(); + break; + case 30: + end(); + break; + case 820: + interpreter.sendDialogues(player, null, "Yes I did. He's told me I must find some Cadava", "berries."); + stage = 821; + break; + case 821: + interpreter.sendDialogues(npc, null, "Well, good luck with that...they're quite tricky to find."); + stage = 822; + break; + case 822: + interpreter.sendDialogues(player, null, "Any clues where I can start to look?"); + stage = 823; + break; + case 823: + interpreter.sendDialogues(npc, null, "I heard some kids saying they saw some the other day.", "They were visiting the mining place to the south east", "Varrock."); + stage = 824; + break; + case 824: + interpreter.sendDialogues(player, null, "Ok, that's as good a place to start looking as any."); + stage = 825; + break; + case 825: + end(); + break; + } + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new FatherLawrenceDialogue(player); + } + + @Override + public int[] getIds() { + return new int[] { 640 }; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/GertrudeDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/GertrudeDialogue.java new file mode 100644 index 0000000..9fcbd6b --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/GertrudeDialogue.java @@ -0,0 +1,430 @@ +package content.region.misthalin.varrock.dialogue; + +import content.global.skill.summoning.pet.Pet; +import core.game.container.Container; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.tools.RandomFunction; +import org.rs09.consts.Items; + +import content.data.Quests; + +import static core.api.ContentAPIKt.*; + +/** + * Represents the gertrude dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class GertrudeDialogue extends DialoguePlugin { + + /** + * Represents the coins item. + */ + private static final Item COINS = new Item(995, 100); + + /** + * Constructs a new {@code GertrudeDialogue} {@code Object}. + */ + public GertrudeDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code GertrudeDialogue} {@code Object}. + * @param player the player. + */ + public GertrudeDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new GertrudeDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + switch (getQuestStage(player, Quests.GERTRUDES_CAT)) { + case 0: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello, are you OK?"); + break; + case 10: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello, Gertrude."); + stage = 210; + break; + case 20: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello, Gertrude."); + stage = 230; + break; + case 30: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello again."); + stage = 236; + break; + case 50: + interpreter.sendDialogues(npc, FacialExpression.HALF_WORRIED, "Please bring me my cat back!"); + stage = 235; + break; + case 40: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello Gertrude."); + stage = 300; + break; + case 60: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello Gertrude. Fluffs ran off with her kitten."); + stage = 320; + break; + case 100: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Hello again."); + stage = 500; + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + final Quest quest = player.getQuestRepository().getQuest(Quests.GERTRUDES_CAT); + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Do I look OK? Those kids drive me crazy."); + stage = 1; + break; + case 1: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I'm sorry. It's just that I've lost her."); + stage = 2; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Lost who?"); + stage = 3; + break; + case 3: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Fluffs, poor Fluffs. She never hurt anyone."); + stage = 4; + break; + case 4: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Who's Fluffs?"); + stage = 5; + break; + case 5: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "My beloved feline friends Fluffs. She's been purring by", "my side for almost a decade. Please, could you go", "search for her while I look over the kids?"); + stage = 6; + break; + case 6: + interpreter.sendOptions("Select an Option", "Well, I suppose I could.", "Sorry, I'm too busy to play pet rescue."); + stage = 7; + break; + case 7: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Well, I suppose I could."); + stage = 100; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Sorry, I'm to busy too play pet rescue."); + stage = 200; + break; + } + break; + case 100: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Really? Thank you so much! I really have no idea", "where she could be!"); + stage = 101; + break; + case 101: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I think my sons, Shilop and Wilough, saw the cat last.", "They'll be out in the market place."); + stage = 102; + break; + case 102: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Alright then, I'll see what I can do."); + stage = 103; + break; + case 103: + quest.start(player); + player.getQuestRepository().syncronizeTab(player); + end(); + break; + case 200: + end(); + break; + case 210:// start of stage 10 + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Have you seen my poor Fluffs?"); + stage = 211; + break; + case 211: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'm afraid not."); + stage = 212; + break; + case 212: + interpreter.sendDialogues(npc, FacialExpression.HALF_ASKING, "What about Shilop?"); + stage = 213; + break; + case 213: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No sign of him either."); + stage = 214; + break; + case 214: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hmmm...strange, he should be at the market."); + stage = 215; + break; + case 215: + end(); + break; + case 230: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hello again, did you manage to find Shilop? I can't keep", "an eye on him for the life of me."); + stage = 231; + break; + case 231: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "He does seem quite a handful."); + stage = 232; + break; + case 232: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "You have no idea! Did he help at all?"); + stage = 233; + break; + case 233: + interpreter.sendDialogues(player, FacialExpression.OLD_NORMAL, "I think so, I'm just going to look now."); + stage = 234; + break; + case 234: + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Thanks again adventurer!"); + stage = 235; + break; + case 235: + end(); + break; + case 236: + interpreter.sendDialogues(npc, FacialExpression.HALF_ASKING, "Hello. How's it going? Any luck?"); + stage = 237; + break; + case 237: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Yes, I've found Fluffs!"); + stage = 238; + break; + case 238: + interpreter.sendDialogues(npc, FacialExpression.HALF_ASKING, "Well well, you are clever!", "Did you bring her back?"); + stage = 239; + break; + case 239: + interpreter.sendDialogues(player, FacialExpression.HALF_WORRIED, "Well, that's the thing, she refuses to leave."); + stage = 240; + break; + case 240: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Oh dear, oh dear! Maybe she's just hungry.", "She loves doogle sardines but I'm all out."); + stage = 241; + break; + case 241: + interpreter.sendDialogues(player, FacialExpression.HALF_ASKING, "Doogle sardines?"); + stage = 242; + break; + case 242: + interpreter.sendDialogues(npc, FacialExpression.HALF_ASKING, "Yes, raw sardines seasoned with doogle leaves.", "Unfortunately I've used all my doogle leaves,", "but you may find some in the woods out back."); + stage = 304; + break; + case 300: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hi! Did you find fluffs?"); + stage = 301; + break; + case 301: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Yes! But she won't follow me."); + stage = 302; + break; + case 302: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "You should try tempting her with a", "seasoned sardine! Those are her favourite snacks."); + stage = 303; + break; + case 303: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Thanks for the advice!"); + stage = 304; + break; + case 304: + end(); + break; + case 320: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "You're back! Thank you! Thank you! Fluffs just came", "back! I think she was just upset as she couldn't find her", "kitten."); + stage = 321; + break; + case 321: + interpreter.sendDialogue("Gertrude gives you a hug."); + npc.face(player); + stage = 322; + break; + case 322: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "If you hadn't found her kitten it would have died out", "there!"); + stage = 323; + break; + case 323: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "That's OK, I like to do my bit."); + stage = 324; + break; + case 324: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I don't know how to thank you. I have no real material", "possesions. I do have kittens! I can only really look", "after one."); + stage = 325; + break; + case 325: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Well, if it needs a home."); + stage = 326; + break; + case 326: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I would sell it to my cousin in West Ardougne. I hear", "there's a rat epidemic there. But it's too far."); + stage = 327; + break; + case 327: + if (player.getInventory().freeSlots() == 0) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I don't seem to have enough inventory space."); + stage = 1000; + break; + } else { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Here you go, look after her and thank you again!"); + stage = 328; + } + break; + case 328: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Oh by the way, the kitten can live in your backpack,", "but to make it grow you must take it out and feed and", "stroke it often."); + stage = 329; + break; + case 329: + interpreter.sendDialogue("Gertrude gives you a kitten."); + stage = 330; + break; + case 330: + player.getPacketDispatch().sendMessage("...and some food!"); + end(); + quest.finish(player); + player.getQuestRepository().syncronizeTab(player); + break; + case 331: + break; + case 1000: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Good good, See you again."); + stage = 1001; + break; + case 1001: + end(); + break; + case 500: + interpreter.sendDialogues(npc, FacialExpression.HALF_ASKING, "Hello my dear. How's things?"); + stage = 501; + break; + case 501: + interpreter.sendOptions("Select an Option", "I'm fine, thanks.", "Do you have any more kittens?"); + stage = 502; + break; + case 502: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'm fine, thanks."); + stage = 1000; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_ASKING, "Do you have any more kittens?"); + stage = 503; + break; + } + break; + case 503: + boolean has = false; + int[] kittens = new int[] { 1555, 1556, 1557, 1558, 1559, 1560, 7583 }; + if (player.getFamiliarManager().hasFamiliar() && player.getFamiliarManager().hasPet()) { + Pet pet = (Pet) player.getFamiliarManager().getFamiliar(); + for (int i : kittens) { + if (pet.getItemId() == i) { + has = true; + break; + } + } + } + Container[] searchSpace = {player.getInventory(), player.getBank()}; + for (Container container : searchSpace) { + if (container.containsAtLeastOneItem(kittens)) { + has = true; + break; + } + } + if (has) { + interpreter.sendDialogues(npc, null, "Aren't you still raising that other kitten? Only once it's", "fully grown and it no longer needs your attention will", "I let you have another kitten."); + stage = 505; + } else { + interpreter.sendDialogues(npc, null, "Indeed I have. They are 100 coins each, do you want", "one?"); + stage = 900; + } + break; + case 900: + interpreter.sendOptions("Select an Option", "Yes please.", "No thanks."); + stage = 901; + break; + case 901: + switch (buttonId) { + case 1:// yes + boolean hasMoney = inInventory(player, Items.COINS_995, 100); + if (!hasMoney) { + player.getPacketDispatch().sendMessage("You need 100 coins to buy a kitten."); + end(); + break; + } else { + boolean hasExtraMoney = inInventory(player, Items.COINS_995, 101); + boolean hasSpace = freeSlots(player) > 0 || !hasExtraMoney; + if (player.getFamiliarManager().hasFamiliar() && !hasSpace) { + player.getPacketDispatch().sendMessage("You don't have enough inventory space."); + end(); + break; + } + interpreter.sendDialogues(player, null, "Yes please."); + stage = 903; + } + break; + case 2:// no + end(); + break; + } + break; + case 903: + interpreter.sendDialogues(npc, null, "OK then, here you go."); + stage = 904; + break; + case 904: + interpreter.sendDialogues(player, null, "Thanks."); + stage = 905; + break; + case 905: + if (player.getInventory().remove(COINS)) { + interpreter.sendDialogue("Gertrude gives you another kitten."); + stage = 906; + final Item kitten = getKitten(); + if (player.getFamiliarManager().hasFamiliar()) { + player.getInventory().add(kitten); + } else { + player.getFamiliarManager().summon(kitten, true, false); + } + } + break; + case 906: + end(); + break; + case 505: + end(); + break; + } + return true; + } + + /** + * Method used to get a random kitten. + * @return the item. + */ + public Item getKitten() { + return new Item(RandomFunction.random(1555, 1560)); + } + + @Override + public int[] getIds() { + return new int[] { 780 }; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/GertrudesCatDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/GertrudesCatDialogue.java new file mode 100644 index 0000000..93d5a00 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/GertrudesCatDialogue.java @@ -0,0 +1,171 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.plugin.Initializable; +import core.game.world.update.flag.context.Animation; +import content.data.Quests; + +/** + * Represents the gertrude cat dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class GertrudesCatDialogue extends DialoguePlugin { + + /** + * Represents the animation of bending down. + */ + private final Animation BEND_DOWN = Animation.create(827); + + /** + * Constructs a new {@code GertrudesCatDialogue} {@code Object}. + */ + public GertrudesCatDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code GertrudesCatDialogue} {@code Object}. + * @param player the player. + */ + public GertrudesCatDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new GertrudesCatDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendOptions("Select an Option", "Talk-with", "Pick-up", "Stroke"); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + final Quest quest = player.getQuestRepository().getQuest(Quests.GERTRUDES_CAT); + switch (stage) { + case 545: + end(); + break; + case 0: + switch (buttonId) { + case 1: + if (quest.getStage(player) < 60) { + end(); + npc.sendChat("Miaoww"); + } else { + interpreter.sendDialogues(player, null, "Oh, it looks like Fluffs has returned.", "I'd better leave her alone."); + stage = 99; + } + break; + case 2: + close(); + player.getPulseManager().run(new Pulse(1, player) { + int count = 0; + + @Override + public boolean pulse() { + switch (count++) { + case 0: + player.animate(BEND_DOWN); + break; + case 2: + npc.sendChat("Hisss!"); + break; + case 3: + player.sendChat("Ouch!"); + break; + case 4: + if (quest.getStage(player) == 40) { + interpreter.sendDialogue("The cat seems afraid to leave.", "In the distance you can hear kittens mewing..."); + stage = 545; + return true; + } + if (quest.getStage(player) == 30) { + interpreter.sendDialogue("Maybe the cat is hungry?"); + stage = 545; + return true; + } + if (quest.getStage(player) == 50) { + end(); + return true; + } + end(); + interpreter.sendDialogue("Maybe the cat is thirsty?"); + stage = 545; + break; + } + return count == 5; + } + }); + break; + case 545: + end(); + break; + case 3: + close(); + player.getPulseManager().run(new Pulse(1, player) { + int count = 0; + + @Override + public boolean pulse() { + switch (count++) { + case 0: + player.animate(BEND_DOWN); + break; + case 2: + npc.sendChat("Hisss!"); + break; + case 3: + player.sendChat("Ouch!"); + break; + case 4: + if (quest.getStage(player) == 40) { + return true; + } + interpreter.sendDialogue("Perhaps the cat want's something?"); + stage = 545; + break; + } + return count == 5; + } + + }); + if (quest.getStage(player) == 40) { + return true; + } + GameWorld.getPulser().submit(new Pulse(7, player) { + @Override + public boolean pulse() { + end(); + return true; + } + + }); + break; + } + break; + case 99: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 2997 }; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/GrandExchangeClerk.java b/Server/src/main/content/region/misthalin/varrock/dialogue/GrandExchangeClerk.java new file mode 100644 index 0000000..b4e7127 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/GrandExchangeClerk.java @@ -0,0 +1,135 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; +import core.game.ge.GrandExchangeRecords; +import content.global.handlers.iface.ge.ExchangeItemSets; +import content.global.handlers.iface.ge.StockMarket; + +/** + * Handles the GrandExchangeClerk dialogue. + * @author 'Vexia + * @author Emperor + * @version 1.0 + */ +@Initializable +public final class GrandExchangeClerk extends DialoguePlugin { + + /** + * Constructs a new {@code GrandExchangeClerk} {@code Object}. + */ + public GrandExchangeClerk() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code GrandExchangeClerk} {@code Object}. + * @param player The player. + */ + public GrandExchangeClerk(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new GrandExchangeClerk(player); + } + + @Override + public boolean open(Object... args) { + if (args.length > 0 && args[0] instanceof NPC) { + npc = (NPC) args[0]; + } + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hi there."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + npc("Good day to you, sir, How can I help?"); + stage = 1; + break; + case 1: + interpreter.sendOptions("Select an Option", "I want to access the Grand Exchange, please.", "I want to collect my items.", "Can I see a history of my offers?", "Can you help me with item sets?", "I'm fine, actually."); + stage = 2; + break; + case 2: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I want to access the Grand Exchange, please."); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I want to collect my items."); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Can I see history of my offers?"); + stage = 30; + break; + case 4: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Can you help me with item sets?"); + stage = 40; + break; + case 5: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'm fine actually."); + stage = 50; + break; + } + break; + case 10: + npc("Only too happy to help you, sir."); + stage = 11; + break; + case 11: + end(); + StockMarket.openFor(player); + break; + case 20: + npc("As you wish, sir."); + stage = 21; + break; + case 21: + end(); + GrandExchangeRecords.getInstance(player).openCollectionBox(); + break; + case 30: + npc("If that is your wish."); + stage = 31; + break; + case 31: + end(); + GrandExchangeRecords.getInstance(player).openHistoryLog(player); + break; + case 40: + npc("It would be my pleasure, sir."); + stage = 41; + break; + case 41: + end(); + ExchangeItemSets.openFor(player); + break; + case 50: + npc("If you say so, sir."); + stage = 51; + break; + case 51: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 6528, 6529, 6530, 6531 }; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/GrandExchangeTutor.java b/Server/src/main/content/region/misthalin/varrock/dialogue/GrandExchangeTutor.java new file mode 100644 index 0000000..0c53691 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/GrandExchangeTutor.java @@ -0,0 +1,141 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.game.world.GameWorld; + +/** + * Represents the dialogue plugin used for the grand exchange tutor. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class GrandExchangeTutor extends DialoguePlugin { + + /** + * Constructs a new {@code GrandExchangeTutor} {@code Object}. + */ + public GrandExchangeTutor() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code GrandExchangeTutor} {@code Object}. + * @param player the player. + */ + public GrandExchangeTutor(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new GrandExchangeTutor(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "How can I help?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "Can you teach me about the Grand Exchange?", "Where can I found out more info?", "I'm okay thanks."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Can you teach me about the Grand Exchange?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Where can I find more info?"); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'm okay thanks."); + stage = 30; + break; + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Of course."); + stage = 11; + break; + case 11: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "This is the Grand Exchange. You can tell us", "what you want to buy or sell, and for how much", "and we'll search for another player willing to do the trade!"); + stage = 12; + break; + case 12: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Let me describe the process in four steps:"); + stage = 13; + break; + case 13: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, getRed() + "Step 1: You come here with items to sell or money to", "spend."); + stage = 14; + break; + case 14: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, getRed() + "Step 2: Speak with one of the clerks at the desk.", "They will help you set up your bid."); + stage = 15; + break; + case 15: + interpreter.sendDialogues(npc, null, "When you're setting up a bid we'll show you a", "guide price for each item. This is just a suggestion", "though: you can offer any amount you like."); + stage = 16; + break; + case 16: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, getRed() + "Step 3: The clerks will take the items or money off you", "and look for someone to complete the trade. This may be", "very fast, or it could take several days."); + stage = 17; + break; + case 17: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, getRed() + "Step 4: When the trade is complete, we will send you a", "message. You can collect your stuff by talking to the", "clerks or by visiting any banker in " + GameWorld.getSettings().getName() + "."); + stage = 18; + break; + case 18: + interpreter.sendDialogues(npc, null, "There's plenty more information about the Grand", "Exchange, all of which can be found out from Brugsen", "Bursen, the guy with the megaphone. I would suggest", "you speak with him to fully get to grips with the Grand"); + stage = 19; + break; + case 19: + interpreter.sendDialogues(npc, null, "Exchange. Good luck!"); + stage = 99; + break; + case 99: + end(); + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Go and speak to Brugsen who's standing over", "there, closer to the building. He'll help you out."); + stage = 31; + break; + case 30: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Fair enough."); + stage = 31; + break; + case 31: + end(); + break; + } + return true; + } + + /** + * Gets the red color id. + * @return the color. + */ + public String getRed() { + return ""; + } + + @Override + public int[] getIds() { + return new int[] { 6521 }; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/GuidorsWifeDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/GuidorsWifeDialogue.java new file mode 100644 index 0000000..5c66666 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/GuidorsWifeDialogue.java @@ -0,0 +1,77 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the guidors wife dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class GuidorsWifeDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code GuidorsWifeDialogue} {@code Object}. + */ + public GuidorsWifeDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code GuidorsWifeDialogue} {@code Object}. + * @param player the player. + */ + public GuidorsWifeDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new GuidorsWifeDialogue(player); + } + + @Override + public boolean open(Object... args) { + if (args.length == 2) { + interpreter.sendDialogues(342, FacialExpression.HALF_GUILTY, "Please leave my husband alone. He's very sick, and I don't", "want anyone bothering him."); + stage = 100; + return true; + } + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + + switch (stage) { + case 0: + interpreter.sendDialogues(342, FacialExpression.HALF_GUILTY, "Oh hello, I can't chat now. I have to keep an eye on my", "husband. He's very ill!"); + stage = 1; + break; + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'm sorry to hear that!"); + stage = 2; + break; + case 2: + end(); + break; + case 100: + end(); + break; + } + + return true; + } + + @Override + public int[] getIds() { + return new int[] { 342 }; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/HeadChefDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/HeadChefDialogue.java new file mode 100644 index 0000000..2e0527b --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/HeadChefDialogue.java @@ -0,0 +1,169 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.global.Skillcape; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the dialogue plugin used for the head chef. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class HeadChefDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code HeadChefDialogue} {@code Object}. + */ + public HeadChefDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code HeadChefDialogue} {@code Object}. + * @param player the player. + */ + public HeadChefDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new HeadChefDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + boolean door = false; + if (args.length == 2) + door = (boolean) args[1]; + if (door) { + interpreter.sendDialogues(847, FacialExpression.NEUTRAL, "You can't come in here unless you're wearing a chef's", "hat or something like that."); + stage = 0; + return true; + } + if (player.getSkills().getStaticLevel(Skills.COOKING) >= 99) { + interpreter.sendDialogues(847, FacialExpression.HAPPY, "Hello, welcome to the Cooking Guild. It's always great to", "have such an accomplished chef visit. Say would you be", "interested in a Skillcape of Cooking? They're only available", "to master chefs."); + stage = 100; + return true; + } + interpreter.sendDialogues(847, FacialExpression.HAPPY, "Hello, welcome to the Cooking Guild. Only accomplished", "chefs and cooks are allowed in here. Feel free to use any", "of our facilities."); + stage = 1; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + + switch (stage) { + case 0: + end(); + break; + case 1: + interpreter.sendOptions("Select an Option", "Nice cape you're wearing!", "Thanks, bye."); + stage = 2; + break; + case 2: + + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HAPPY, "Nice cape, you're wearing!"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.FRIENDLY, "Thanks, bye."); + stage = 3; + break; + } + + break; + case 3: + end(); + break; + case 10: + interpreter.sendDialogues(847, FacialExpression.HAPPY, "Thank you! It's my most prized possession, it's a Skillcape", "of Cooking; it shows that I've achieved level 99 Cooking", "and am one of the best chefs in the land!"); + stage = 11; + break; + case 11: + end(); + break; + case 100: + interpreter.sendOptions("Select an Option", "No thanks.", "Yes please."); + stage = 101; + break; + case 101: + + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.FRIENDLY, "No thanks."); + stage = 110; + break; + case 2: + player("Yes, please."); + stage = 150; + break; + } + break; + + case 110: + interpreter.sendDialogues(847, FacialExpression.HAPPY, "Okay, come back to me if you change your mind."); + stage = 111; + break; + case 111: + end(); + break; + case 150: + interpreter.sendDialogues(847, FacialExpression.HALF_GUILTY, "Most certainly, just as soon as you give me 99000 gold", "coins."); + stage = 151; + break; + case 151: + interpreter.sendOptions("Select an Option", "That's much too expensive.", "Sure."); + stage = 152; + break; + case 152: + + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.EXTREMELY_SHOCKED, "That's much too expensive."); + stage = 160; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HAPPY, "Sure."); + stage = 200; + break; + } + + break; + case 160: + interpreter.sendDialogues(847, FacialExpression.HALF_GUILTY, "I'm sorry you feel that way."); + stage = 161; + break; + case 161: + end(); + break; + case 200: + if (Skillcape.purchase(player, Skills.COOKING)) { + interpreter.sendDialogues(847, FacialExpression.HAPPY, "Now you can use the title Master Chef."); + } + stage = 202; + break; + case 202: + end(); + break; + } + + return true; + } + + @Override + public int[] getIds() { + return new int[] { 847 }; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/HofutThandDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/HofutThandDialogue.java new file mode 100644 index 0000000..2edc88e --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/HofutThandDialogue.java @@ -0,0 +1,95 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.plugin.Initializable; +import core.game.ge.GEGuidePrice; +import core.game.ge.GEGuidePrice.GuideType; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; + +/** + * Represents the hofut thand dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class HofutThandDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code HofutThandDialogue} {@code Object}. + */ + public HofutThandDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code HofutThandDialogue} {@code Object}. + * @param player the player. + */ + public HofutThandDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new HofutThandDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello!"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "What? Oh, hello. I was deep in thought. Did", "you say something?"); + stage = 1; + break; + case 1: + interpreter.sendOptions("Select an Option", "Do you know about the prices for armour and weapons?", "I didn't say anything at all."); + stage = 2; + break; + case 2: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Do you know about the prices for armour and weapons?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I didn't say anything at all."); + stage = 20; + break; + } + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I thought you at least said. 'Hello' I must be", "going mad. Do you think I'm going mad?"); + stage = 21; + break; + case 21: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Oh, most definitely. You should see a doctor before it's", "too late."); + stage = 22; + break; + case 22: + end(); + break; + case 10: + end(); + GEGuidePrice.open(player, GuideType.WEAPONS_AND_ARMOUR); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 6527 }; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/HooknosedJackDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/HooknosedJackDialogue.java new file mode 100644 index 0000000..48504a7 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/HooknosedJackDialogue.java @@ -0,0 +1,71 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the hooknodes jack dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class HooknosedJackDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code HooknosedJackDialogue} {@code Object} + */ + public HooknosedJackDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code HooknosedJackDialogue} {@code Object}. + * @param player the player. + */ + public HooknosedJackDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new HooknosedJackDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "What?"); + stage = 1; + break; + case 1: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Actually I've got no time for this. I don't want to talk to", "you."); + stage = 2; + break; + case 2: + end(); + break; + } + + return true; + } + + @Override + public int[] getIds() { + return new int[] { 2948 }; + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/HorvikDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/HorvikDialogue.java new file mode 100644 index 0000000..d912502 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/HorvikDialogue.java @@ -0,0 +1,84 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the horvik dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class HorvikDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code HorvikDialogue} {@code Object}. + */ + public HorvikDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code HorvikDialogue} {@code Object}. + * @param player the player. + */ + public HorvikDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new HorvikDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Hello, do you need any help?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "No, thanks. I'm just looking around.", "Do you want to trade?"); + stage = 1; + break; + case 1: + + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.FRIENDLY, "No, thanks. I'm just looking around."); + stage = 10; + break; + case 2: + end(); + npc.openShop(player); + break; + } + + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Well, come and see me if you're ever in need of armour!"); + stage = 11; + break; + case 11: + end(); + break; + } + + return true; + } + + @Override + public int[] getIds() { + return new int[] { 549 }; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/IffieDialogue.kt b/Server/src/main/content/region/misthalin/varrock/dialogue/IffieDialogue.kt new file mode 100644 index 0000000..2ebebdf --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/IffieDialogue.kt @@ -0,0 +1,33 @@ +package content.region.misthalin.varrock.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.player.Player +import core.plugin.Initializable + +/** + * Iffie + * @author afaroutdude + */ +@Initializable +class IffieDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun open(vararg args: Any?): Boolean { + npc("Sorry, dearie, if I stop to chat I'll lose count.", "Talk to my sister instead; she likes to chat.", "You'll find her upstairs in the church.") + stage = 999 + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 999 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return IffieDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(5914) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/InformationclerkMuseumDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/InformationclerkMuseumDialogue.java new file mode 100644 index 0000000..f0ca68e --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/InformationclerkMuseumDialogue.java @@ -0,0 +1,221 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.game.world.GameWorld; +import org.rs09.consts.Items; + +/** + * Represents the information clerk museum dialogue plugin + * + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class InformationclerkMuseumDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code InformationclerkMuseumDialogue} {@code Object}. + */ + public InformationclerkMuseumDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code InformationclerkMuseumDialogue} {@code Object}. + * + * @param player the player. + */ + public InformationclerkMuseumDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new InformationclerkMuseumDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + npc("Welcome to Varrock Museum. How can I help you today?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 150: + npc("Of course. The Dig Site exhibit has several display cases", "of finds discovered on the Dig Site to the east of Varrock."); + stage = 151; + break; + case 151: + npc("As you've passed your Earth Science exams at the Dig", "Site, you can go through into the cleaning area and clean", "off some finds. This will help our Dig Site display floor to", "give a more accurate view of life back in the 3rd and fth"); + stage = 152; + break; + case 152: + npc("Ages, as well as earning you Kudos. If you'd like to know", "more about cleaning finds, just ask the archaeologists."); + stage = 153; + break; + case 153: + options("Ask about something else.", "Bye"); + stage = 154; + break; + case 154: + switch (buttonId) { + case 1: + player("What else can you inform me on?"); + stage = 0; + break; + case 2: + player("Bye!"); + stage = 200; + break; + } + break; + case 200: + end(); + break; + case 170: + npc("Why, yes. The Timeline exhibit has lots of display cases", "showing things from the beginning of time right up to the", "present day."); + stage = 171; + break; + case 171: + npc("I know you've helped out a bit in the Timeline exhibit", "upstairs, but I'm sure you can help more. When you're out", "on your travels being a brave adventurer, remember that", "you can come back to the Museum after some quests to"); + stage = 172; + break; + case 172: + npc("let us know important historical facts. This will help us to", "update the displays and make the Museum a more", "informative place! You'll earn yourself Kudos too."); + stage = 173; + break; + case 173: + player("Okay, thanks. One more question: why are the display", "numbers all out of sequence?"); + stage = 174; + break; + case 174: + npc("Ahh, that's due to the numbering being done as we were", "constructing the cases and putting the displays in them,", "then suffling them into the right places. We thought", "rather than renumbering them all - such a boring job,"); + stage = 175; + break; + case 175: + npc("writing labels - we'd leave it. They all have unique numbers", "and future displays would mess up the consecutive", "numbering anyway."); + stage = 176; + break; + case 176: + player("Ahhh, I see."); + stage = 153; + break; + case 180: + npc("Why, yes. The Natural History exhibit has displays of", "various creatures you can find around " + GameWorld.getSettings().getName() + "."); + stage = 181; + break; + case 181: + npc("I see you have already demonstrated some of your", "knowledge of the natural world in the Natural History", "exhibit, so why not pop down and so some more quizzes", "with Orlando! You can earn Kudos at the same time."); + stage = 182; + break; + case 182: + options("But what's Natural History got to do with existing animals?", "Ask about something else.", "Bye"); + stage = 183; + break; + case 183: + switch (buttonId) { + case 1: + player("But what's natural history got to do with existing animals?"); + stage = 184; + break; + case 2: + player("What else can you inform me on?"); + stage = 0; + break; + case 3: + player("Bye!"); + stage = 200; + break; + } + break; + case 184: + npc("The study of nautral history is simply the study of the", "history of the species. The species doesn't neccasrily", "need to be an extinct one."); + stage = 153; + break; + case 230: + npc("Kudos is a measure of how much you've assisted the", "Museum. The more information you give us, Dig Site", "finds that you clean and quizzes you solve, the", "higher your Kudos."); + stage = 231; + break; + case 231: + player("But what's it for?"); + stage = 232; + break; + case 232: + npc("Well, recently we found a rather interesting island to the", "north of Morytania. We believe that it may be of", "archaeological significance. I suspect we'll be looking for", "qualified archaeologists once we have constructed out"); + stage = 233; + break; + case 233: + npc("canal and barge. So, we're using Kudos as a measure of", "who is willing and able to help us here at the Museum, so", "they can then be invited on our digs on the new island."); + stage = 234; + break; + case 234: + player("Would I qualify, then?"); + stage = 235; + break; + case 235: + npc("Unfortunately, you haven't earned enough Kudos yet, so", "you aren't qualified to help us on the dig. If you're", "interested in helping us out and getting that Kudos, simply", "help out around the museum."); + stage = 236; + break; + case 236: + player("Okay, thanks."); + stage = 237; + break; + case 237: + end(); + break; + case 0: + interpreter.sendOptions("What would you like to do?", + "Take a map of the Museum.", + "Find out about the Dig Site exhibit.", + "Find out about the Timeline exhibit.", + "Find out about the Natural History exhibit.", + "Find out about Kudos."); + stage = 1; + break; + case 1: + + switch (buttonId) { + case 1: + sendDialogue("You reach and take a map of the Museum."); + player.getInventory().add(new Item(Items.MUSEUM_MAP_11184, 1)); + stage = 999; + break; + case 2: + player("Could you tell me about the Dig Site exhibit please?"); + stage = 150; + break; + case 3: + player("Could you tell me about the Timeline exhibit please?"); + stage = 170; + break; + case 4: + player("Could you tell me about the Natural History exhibit", "please?"); + stage = 180; + break; + case 5: + npc("What is Kudos?"); + stage = 230; + break; + + } + + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[]{5938}; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/KanelDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/KanelDialogue.java new file mode 100644 index 0000000..4cf81e3 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/KanelDialogue.java @@ -0,0 +1,72 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Kanel - Child in Gertrude's House + */ +@Initializable +public final class KanelDialogue extends DialoguePlugin { + // https://www.youtube.com/watch?v=ANI7DaRVEbg + /** + * Constructs a new {@code KanelDialogue} {@code Object}. + */ + public KanelDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code KanelDialogue} {@code Object}. + * @param player the player. + */ + public KanelDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new KanelDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.FRIENDLY, "Hello there."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.CHILD_THINKING, "Hel-lo?"); + stage = 1; + break; + case 1: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Right. Goodbye."); + stage = 2; + break; + case 2: + interpreter.sendDialogues(npc, FacialExpression.CHILD_THINKING, "Bye?"); + stage = 3; + break; + case 3: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 784 }; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/KingRoaldDialogue.kt b/Server/src/main/content/region/misthalin/varrock/dialogue/KingRoaldDialogue.kt new file mode 100644 index 0000000..1f775ac --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/KingRoaldDialogue.kt @@ -0,0 +1,89 @@ +package content.region.misthalin.varrock.dialogue + +import content.minigame.allfiredup.KingRoaldAFUMiniDialogue +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import content.region.misthalin.varrock.quest.shieldofarrav.KingRoaldArravDialogue +import content.region.misthalin.varrock.quest.allfiredup.KingRoaldAFUDialogue +import content.region.misthalin.quest.priestinperil.KingRoaldPIPDialogue +import core.tools.DIALOGUE_INITIAL_OPTIONS_HANDLE +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import content.data.Quests + +/** + * Central dialogue plugin for King Roald. Reroutes to the more specific DialogueFiles + * @author Ceikry + * @version 1.0 + */ +class KingRoaldDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun newInstance(player: Player): DialoguePlugin { + return KingRoaldDialogue(player) + } + + override fun open(vararg args: Any): Boolean { + npc = args[0] as NPC + + if (player.getAttribute("afu-mini:ring", false) || player.getAttribute("afu-mini:gloves", false) || player.getAttribute("afu-mini:adze", false)) { + player("Your Majesty! I did it!") + loadFile(KingRoaldAFUMiniDialogue()) + return true + } + + if(player.questRepository.isComplete(Quests.PRIEST_IN_PERIL)) { + if (!player.questRepository.hasStarted(Quests.ALL_FIRED_UP) || player.questRepository.getQuest(Quests.ALL_FIRED_UP).getStage(player) == 90) { + addOption("All Fired Up", KingRoaldAFUDialogue(player.questRepository.getStage(Quests.ALL_FIRED_UP))) + } + } else { + addOption("Priest in Peril", KingRoaldPIPDialogue(player.questRepository.getStage(Quests.PRIEST_IN_PERIL))) + } + + if (player.questRepository.getQuest(Quests.SHIELD_OF_ARRAV).isStarted(player) && !player.questRepository.getQuest(Quests.SHIELD_OF_ARRAV).isCompleted(player)) { + addOption("Shield of Arrav", KingRoaldArravDialogue()) + } + + if(!sendChoices()){ + player("Greetings, your Majesty.") + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + //Default (non-specific) dialogue + when (stage) { + + DIALOGUE_INITIAL_OPTIONS_HANDLE -> { + player("Greetings, your Majesty.") + loadFile(optionFiles[buttonId - 1]) + } + + START_DIALOGUE -> { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Do you have anything of importance to say?") + stage = 1 + } + 1 -> { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "...Not really.") + stage = 2 + } + 2 -> { + interpreter.sendDialogues( + npc, + FacialExpression.HALF_GUILTY, + "You will have to excuse me, then. I am very busy as I", + "have a kingdom to run!" + ) + stage = END_DIALOGUE + } + + END_DIALOGUE -> end() + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(648, 2590, 5838) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/KnockAtBankDoor.kt b/Server/src/main/content/region/misthalin/varrock/dialogue/KnockAtBankDoor.kt new file mode 100644 index 0000000..d62ded7 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/KnockAtBankDoor.kt @@ -0,0 +1,59 @@ +package content.region.misthalin.varrock.dialogue + +import core.api.lock +import core.api.queueScript +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.npc.NPC +import core.game.world.map.Location +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +class KnockAtBankDoor : DialogueFile() { + private val femaleBankerNPC = NPC(NPCs.BANKER_45) + private val maleBankerNPC = NPC(NPCs.BANKER_44) + private val femaleBankerDoorLoc = Location(3182, 3434, 0) + + override fun handle(componentID: Int, buttonID: Int) { + npc = if (player!!.location == femaleBankerDoorLoc) femaleBankerNPC else maleBankerNPC + + when (stage) { + START_DIALOGUE -> { + player!!.dialogueInterpreter.sendPlainMessage( + true, "Knock knock..." + ).also { + lock(player!!, 3) + queueScript(player!!, 3) { + npcl(FacialExpression.NEUTRAL, "Who's there?") + stage++ + return@queueScript true + } + } + } + + 1 -> showTopics( + Topic("I'm ${player!!.username}. Please let me in.", 10), + Topic("Boo.", 20), + Topic("Kanga.", 30), + Topic("Thank.", 40), + Topic("Doctor.", 50) + ) + 10 -> npcl("No. Staff only beyond this point. You can't come in here.").also { stage = END_DIALOGUE } + 20 -> npcl("Boo who?").also { stage++ } + 21 -> playerl("There's no need to cry!").also { stage++ } + 22 -> npcl(FacialExpression.FURIOUS, "What? I'm not... oh, just go away!").also { stage = END_DIALOGUE } + 30 -> npcl("Kanga who?").also { stage++ } + 31 -> playerl("No, 'kangaroo'.").also { stage++ } + 32 -> npcl(FacialExpression.FURIOUS, "Stop messing about and go away!").also { stage = END_DIALOGUE } + 40 -> npcl("Thank who?").also { stage++ } + 41 -> playerl("You're welcome!").also { stage++ } + 42 -> npcl(FacialExpression.FURIOUS, "Stop it!").also { stage = END_DIALOGUE } + 50 -> npcl( + FacialExpression.FURIOUS, + "Doctor. wh.. hang on, I'm not falling for that one again! Go away." + ).also { stage = END_DIALOGUE } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/LoweDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/LoweDialogue.java new file mode 100644 index 0000000..97c0da4 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/LoweDialogue.java @@ -0,0 +1,82 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the dialogue plugin used for lowe. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class LoweDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code LoweDialogue} {@code Object}. + */ + public LoweDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code LoweDialogue} {@code Object}. + * @param player the player. + */ + public LoweDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new LoweDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Welcome to Lowe's Archery Emporium. Do you want", "to see my wares?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "Yes, please.", "No, I prefer to bash things close up."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + npc.openShop(player); + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.EVIL_LAUGH, "No, I prefer to bash things close up."); + stage = 3; + break; + } + + break; + case 3: + interpreter.sendDialogues(npc, FacialExpression.ANNOYED, "Humph, philistine."); + stage = 4; + break; + case 4: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 550 }; + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/MurkyMattDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/MurkyMattDialogue.java new file mode 100644 index 0000000..9354bb5 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/MurkyMattDialogue.java @@ -0,0 +1,138 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.ge.GEGuidePrice; +import core.game.ge.GEGuidePrice.GuideType; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the murly matt dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class MurkyMattDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code MurkyMattDialogue} {@code Object}. + */ + public MurkyMattDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code MurkyMattDialogue} {@code Object}. + * @param player the player. + */ + public MurkyMattDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new MurkyMattDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "A pirate!"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Arrrr, How'd ye be guessing that, me-lad?"); + stage = 1; + break; + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "You're kidding, right?"); + stage = 2; + break; + case 2: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Nay! Now, what is it that ye be wantin?", "I can tell ye all about the prices of runes, I can."); + stage = 3; + break; + case 3: + interpreter.sendOptions("Select an Option", "What's a pirate doing here?", "Tell me about the prices of runes.", "I got to go, erm, swab some decks! Yar!"); + stage = 4; + break; + case 4: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What's a pirate doing here?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Tell me about the prices of runes."); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I got to go, erm, swab some decks! Yarr!"); + stage = 30; + break; + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "By my sea-blistered skin, I could ask the same of you!"); + stage = 11; + break; + case 11: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "But... I'm not a pirate?"); + stage = 12; + break; + case 12: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "No? Then what's that smell? The smell o'", "someone spent too long at sea without a bath!"); + stage = 13; + break; + case 13: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I think that's probably you."); + stage = 14; + break; + case 14: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Har har har!"); + stage = 15; + break; + case 15: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "We've got a stern landlubber 'ere'! Well, let", "me tell ye, I'm here for the Grand Exchange!"); + stage = 16; + break; + case 16: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Don't you just want to sell it in a shop or trade", "it to someone specific?"); + stage = 17; + break; + case 17: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "By my wave-battered bones! Not when I can sell to", "the whole world from this very spot!"); + stage = 18; + break; + case 18: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "You pirates are nothing but trouble!"); + stage = 19; + break; + case 19: + end(); + break; + case 20: + end(); + GEGuidePrice.open(player, GuideType.RUNES); + break; + case 30: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 6525 }; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/MuseumGuardsDialoguePlugin.kt b/Server/src/main/content/region/misthalin/varrock/dialogue/MuseumGuardsDialoguePlugin.kt new file mode 100644 index 0000000..6880892 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/MuseumGuardsDialoguePlugin.kt @@ -0,0 +1,90 @@ +package content.region.misthalin.varrock.dialogue + +import content.data.Quests +import content.region.misthalin.varrock.handlers.MuseumInteractionListener.Companion.handleMuseumDoor +import core.api.forceWalk +import core.api.getScenery +import core.api.isQuestComplete +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +class DoorGuardDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun open(vararg args: Any?): Boolean { + npcl(FacialExpression.NEUTRAL, "Hello there. Come to see the new museum?").also { stage = START_DIALOGUE } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + START_DIALOGUE -> playerl(FacialExpression.NEUTRAL, "Yes, how do I get in?").also { stage++ } + 1 -> npcl(FacialExpression.NEUTRAL, "Well, the main entrance is 'round the front. Just head west then north slightly, you can't miss it!").also { stage++ } + 2 -> playerl(FacialExpression.NEUTRAL, "What about these doors?").also { stage++ } + 3 -> { + if (isQuestComplete(player, Quests.THE_DIG_SITE)) { + npcl(FacialExpression.NEUTRAL, "They're primarily for the workmen bringing finds from the Dig Site, but you can go through if you want.").also { stage++ } + } else { + npcl(FacialExpression.NEUTRAL, "They're for the workmen bringing finds from the Dig Site; sorry, but you can't go through.").also { stage = END_DIALOGUE } + } + } + 4 -> playerl(FacialExpression.NEUTRAL, "Okay, thanks.").also { stage++ } + 5 -> { + end() + handleMuseumDoor(player, getScenery(3264, 3441, 0)) + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return DoorGuardDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.MUSEUM_GUARD_5943) + } +} + +@Initializable +class GateGuardDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun open(vararg args: Any?): Boolean { + // Shows the player walking to this spot first https://www.youtube.com/watch?v=t-oeY3a-ZSA&t=53s + if (player.location != Location(3261, 3447)) forceWalk(player, Location(3261, 3447), "smart") + + if (isQuestComplete(player, Quests.THE_DIG_SITE)) { + npcl(FacialExpression.NEUTRAL, "Welcome! Would you like to go into the Dig Site archaeology cleaning area?").also { stage = START_DIALOGUE } + } else { + npcl(FacialExpression.NEUTRAL, "You're not permitted in this area.").also { stage = END_DIALOGUE } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + START_DIALOGUE -> showTopics( + Topic("Yes, I'll go in!", 1, true), + Topic("No thanks, I'll take a look around out here.", END_DIALOGUE, true) + ) + 1 -> { + end() + handleMuseumDoor(player, getScenery(3261, 3446, 0)) + } + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return GateGuardDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.MUSEUM_GUARD_5941) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/MuseumHistorianDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/MuseumHistorianDialogue.java new file mode 100644 index 0000000..91fe629 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/MuseumHistorianDialogue.java @@ -0,0 +1,129 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the Museum Natural Historian dialogue plugin. + * @author 'qmqz + * @version 1.0 + */ +@Initializable +public final class MuseumHistorianDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code MuseumHistorianDialogue {@code Object}. + */ + public MuseumHistorianDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code MuseumHistorianDialogue} {@code Object}. + * @param player the player. + */ + public MuseumHistorianDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new MuseumHistorianDialogue(player); + } + + @Override + public boolean open(Object... args) { + genderCheck(); + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.ASKING, "Hello again, " + gender + ", how can I help you on this fine day?"); + stage = 0; + return true; + } + + public String gender; + public void genderCheck() { + if (player.isMale()) { + gender = "sir"; + } else { + gender = "madam"; + } + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(player, FacialExpression.ASKING, "I was hoping you could tell me about something."); + stage = 1; + break; + + case 1: + interpreter.sendOptions("Select an Option", "Tell me about snails.", "Tell me about monkeys.", "Tell me about sea slugs.", "Tell me about snakes.", "That's enough education for one day."); + stage = 2; + break; + + case 2: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_ASKING, "Tell me about snails."); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_ASKING, "Tell me about monkeys."); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_ASKING, "Tell me about sea slugs."); + stage = 30; + break; + case 4: + interpreter.sendDialogues(player, FacialExpression.HALF_ASKING, "Tell me about snakes."); + stage = 40; + break; + case 5: + interpreter.sendDialogues(player, FacialExpression.HALF_ASKING, "That's enough education for one day."); + stage = 99; + break; + + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ahh snails, the gelatinous gastropods.", "If you just follow me to the display case,"," I shall explain all about them."); + //transitions into a cutscene + stage = 99; + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ahh monkeys, the simian collective.", "If you just follow me to the display case,", " I shall explain all about them."); + //transitions into a cutscene + stage = 99; + break; + + case 30: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ahh sea slugs, the cute crustaceans.", "If you just follow me to the display case,", "I shall explain all about them."); + //transitions into a cutscene + stage = 99; + break; + + case 40: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ahh snakes, the slithering squamata.", "If you just follow me to the display case,", "I shall explain all about them."); + //transitions into a cutscene + stage = 99; + break; + + case 99: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 5966, 5967 }; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/PhillipaDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/PhillipaDialogue.java new file mode 100644 index 0000000..2b6881d --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/PhillipaDialogue.java @@ -0,0 +1,81 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Handles the PhillipaDialogue dialogue. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class PhillipaDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code PhillipaDialogue} {@code Object}. + */ + public PhillipaDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code PhillipaDialogue} {@code Object}. + * @param player the player. + */ + public PhillipaDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new PhillipaDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello, who are you?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hi, I'm Phillipa! Juliet's cousin? I like to keep an eye on", "her, make sure that dashing young Romeo doesn't just", "steal away from here under our plain old noses!"); + stage = 1; + break; + case 1: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "He'd do it to you know... he's ever so dashing, and", "cavalier, in a wet blanket sort of way."); + stage = 2; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Romeo? Where would I find him then?"); + stage = 3; + break; + case 3: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Well, that's a good question! Who knows where his", "head's at most of the time... in the clouds most likely!"); + stage = 4; + break; + case 4: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "But he's probably chasing the ladies who frequent", "Varrockk market. He does like a bit of kiss chase so I've", "heard!"); + stage = 5; + break; + case 5: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 3325 }; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/PhilopDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/PhilopDialogue.java new file mode 100644 index 0000000..9cf02f4 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/PhilopDialogue.java @@ -0,0 +1,73 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Philop - Child in Gertrude's House + */ +@Initializable +public class PhilopDialogue extends DialoguePlugin { + // https://www.youtube.com/watch?v=ANI7DaRVEbg + public PhilopDialogue() { + + } + + public PhilopDialogue(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[] { 782 }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.CHILD_ANGRY, "Gwwrr!"); + stage = 1; + break; + case 1: + interpreter.sendDialogues(player, FacialExpression.THINKING, "Err, hello there. What's that you have there?"); + stage = 2; + break; + case 2: + interpreter.sendDialogues(npc, FacialExpression.CHILD_ANGRY, "Gwwwrrr! Dwa-gon Gwwwwrrrr!"); + stage = 3; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Enjoy playing with your dragon, then."); + stage = 4; + break; + case 4: + interpreter.sendDialogues(npc, FacialExpression.CHILD_ANGRY, "Gwwwrrr!"); + stage = 5; + break; + case 5: + end(); + break; + } + + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new PhilopDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello, what's your name?"); + stage = 0; + return true; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/PoxDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/PoxDialogue.java new file mode 100644 index 0000000..c5f3417 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/PoxDialogue.java @@ -0,0 +1,58 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Handles the PoxDialogue dialogue. + * @author 'Vexia + */ +@Initializable +public class PoxDialogue extends DialoguePlugin { + + public PoxDialogue() { + + } + + public PoxDialogue(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[] { 2943 }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Miaooow!"); + stage = 1; + break; + case 1: + end(); + break; + } + + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new PoxDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hi cat!"); + stage = 0; + return true; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/ReloboBlinyoDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/ReloboBlinyoDialogue.java new file mode 100644 index 0000000..e71d8c3 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/ReloboBlinyoDialogue.java @@ -0,0 +1,122 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.plugin.Initializable; +import core.game.ge.GEGuidePrice; +import core.game.ge.GEGuidePrice.GuideType; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; + +/** + * Handles the ReloboBlinyoDialogue dialogue. + * @author 'Vexia + */ +@Initializable +public class ReloboBlinyoDialogue extends DialoguePlugin { + + public ReloboBlinyoDialogue() { + + } + + public ReloboBlinyoDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new ReloboBlinyoDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hey there."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Why hello to you too, my friend."); + stage = 1; + break; + case 1: + interpreter.sendOptions("Select an Option", "You look like you've travelled a fair distance.", "I'm trying to find the prices for logs.", "Sorry, I need to be macking tracks."); + stage = 2; + break; + case 2: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "You look like you've travelled a fair distance."); + stage = 20; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'm trying to find the prices for logs."); + stage = 10; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Sorry, I need to be making tracks."); + stage = 30; + break; + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Then you've come to the right person."); + stage = 11; + break; + case 11: + end(); + GEGuidePrice.open(player, GuideType.LOGS); + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "What gave me away?"); + stage = 21; + break; + case 21: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I don't mean to be rude, but the face paint and", "hair, for startes."); + stage = 22; + break; + case 22: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ah, yes I'm from Shilo Village on Karamja. It's a style", "I've had since I was little."); + stage = 23; + break; + case 23: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Then tell me, why are you so far from home?"); + stage = 24; + break; + case 24: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "This Grand Exchange! Isn't it marvellous I've never seen", "anything like it in my life. My people were not pleased to", "see me break traditions to visit such a place. But i hope", "to make some serious profit. then they'll see I was right!"); + stage = 25; + break; + case 25: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "So, what are you selling?"); + stage = 26; + break; + case 26: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Logs! of all kinds! That's my plan, at least. Nature", "is one thing my people understand very well."); + stage = 27; + break; + case 27: + end(); + break; + case 30: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Okay. Nice talking to you!"); + stage = 31; + break; + case 31: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 6526 }; + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/RomilyWeaklaxDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/RomilyWeaklaxDialogue.java new file mode 100644 index 0000000..ed93e45 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/RomilyWeaklaxDialogue.java @@ -0,0 +1,256 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import org.rs09.consts.Items; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; +import core.plugin.Plugin; +import core.plugin.ClassScanner; +import core.tools.RandomFunction; + +/** + * Handles the RomilyWeaklaxDialogue dialogue. + * + * @author 'Vexia + */ +@Initializable +public class RomilyWeaklaxDialogue extends DialoguePlugin { + private enum PieReward { + APPLE(Items.APPLE_PIE_2323, 84), + REDBERRY(Items.REDBERRY_PIE_2325, 90), + MEAT(Items.MEAT_PIE_2327, 96), + GARDEN(Items.GARDEN_PIE_7178, 112), + FISH(Items.FISH_PIE_7188, 125), + ADMIRAL(Items.ADMIRAL_PIE_7198, 387); + + int id, reward; + + PieReward(int id, int reward) { + this.id = id; + this.reward = reward; + } + + protected static PieReward forId(int id) { + for (PieReward pie : PieReward.values()) { + if (pie.id == id) { + return pie; + } + } + return null; + } + } + + private final static String keyAmt = "romily-weaklax:pie-amt"; + private final static String keyId = "romily-weaklax:pie-assigned"; + + private int pieId = 0; + private int pieAmt = 0; + private PieReward pieReward; + + public RomilyWeaklaxDialogue() { + + } + + public RomilyWeaklaxDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new RomilyWeaklaxDialogue(player); + } + + @Override + public void init() { + super.init(); + ClassScanner.definePlugin(new RomilyWildPieHandler()); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + pieId = player.getAttribute(keyId, 0); + pieAmt = player.getAttribute(keyAmt, 0); + pieReward = PieReward.forId(pieId); + + if (args.length > 1) { + Item usedWith = (Item) args[1]; + if (usedWith.getId() == Items.WILD_PIE_7208) { + npc("Is that a wild pie for me?"); // TODO not accurate dialogue, unfortunately offscreen in this video https://www.youtube.com/watch?v=FjlLZnDxofY + stage = 100; + return true; + } + } + + npc("Hello and welcome to my pie shop, how can I help you?"); + if (pieId != 0 && pieAmt != 0) { + stage = 2; + } else { + stage = 0; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 999: + end(); + break; + case 0: + options("I'd like to buy some pies.", "Do you need any help?", "I'm good thanks."); + stage = 1; + break; + case 1: + + switch (buttonId) { + case 1: + player("I'd like to buy some pies."); + stage = 10; + break; + case 2: + player("Do you need any help?"); + stage = 20; + break; + case 3: + player("I'm good thanks."); + stage = 999; + break; + } + break; + case 2: + options("I'd like to buy some pies.", "I've got those pies you wanted.", "I'm good thanks."); + stage = 1; + break; + case 3: + + switch (buttonId) { + case 1: + player("I'd like to buy some pies."); + stage = 10; + break; + case 2: + player("I've got those pies you wanted."); + stage = 50; + break; + case 3: + player("I'm good thanks."); + stage = 999; + break; + } + break; + case 10: + npc("Take a look."); + stage++; + break; + case 11: + end(); + npc.openShop(player); + break; + case 20: + npc("Actually I could, you see I'm running out of stock and I", "don't have tme to bake any more pies. would you be", "willing to bake me some pies? I'll pay you well for them."); + stage = 21; + break; + case 21: + options("Sure, what do you need?", "Sorry, I can't help you."); + stage = 22; + break; + case 22: + switch (buttonId) { + case 1: + player("Sure, what do you need?"); + stage = 60; + break; + case 2: + player("Sorry, I can't help you."); + stage++; + break; + } + break; + case 23: + npc("Come back if you ever want to bake pies."); + stage = 999; + break; + case 50: + final int piesInInventory = player.getInventory().getAmount(pieId); + final int deficit = pieAmt - piesInInventory; + if (piesInInventory == 0) { + npc("Doesn't look like you have any of the", pieAmt + " " + new Item(pieId).getName() + "s I requested."); + stage = 999; + break; + } else if (deficit == 0) { + npc("Thank you very much!"); + player.removeAttribute(keyAmt); + player.removeAttribute(keyId); + } else { + npc("Thank you, if you could bring me the other " + deficit + " that'd", "be great!"); + player.setAttribute("/save:" + keyAmt, deficit); + } + player.getInventory().remove(new Item(pieId, piesInInventory)); + player.getInventory().add(new Item(995, pieReward.reward * piesInInventory)); + stage = 999; + break; + case 60: + pieAmt = RandomFunction.random(1, 28); + pieId = PieReward.values()[RandomFunction.nextInt(PieReward.values().length)].id; + player.setAttribute("/save:" + keyAmt, pieAmt); + player.setAttribute("/save:" + keyId, pieId); + npc("Great, can you bake me " + pieAmt + " " + new Item(pieId).getName() + "s please."); + stage = 999; + break; + + case 100: + player("Yes, it is."); + stage++; + break; + case 101: + npc("Oh, how splendid! Let me take that from you then."); + player.getInventory().remove(new Item(Items.WILD_PIE_7208)); + player.getAchievementDiaryManager().finishTask(player, DiaryType.VARROCK, 2, 5); + stage++; + break; + case 102: + npc("Now, was there anything else you needed?"); + if (pieId != 0 && pieAmt != 0) { + stage = 2; + } else { + stage = 0; + } + break; + } + + return true; + } + + + @Override + public int[] getIds() { + return new int[]{3205}; + } + + public static final class RomilyWildPieHandler extends UseWithHandler { + public RomilyWildPieHandler() { + super(Items.WILD_PIE_7208); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(3205, NPC_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + if (!event.getPlayer().getAchievementDiaryManager().getDiary(DiaryType.VARROCK).isComplete(2,5)) { + event.getPlayer().getDialogueInterpreter().open(3205, event.getUsedItem()); + } + return true; + } + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/SaniDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/SaniDialogue.java new file mode 100644 index 0000000..040f59e --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/SaniDialogue.java @@ -0,0 +1,151 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.skill.Skills; +import core.plugin.Initializable; +import core.game.shops.Shops; + +/** + * Handles the SaniDialogue dialogue. + * @author Vexia + * + */ +@Initializable +public class SaniDialogue extends DialoguePlugin { + + /** + * Constructs the {@code SaniDialgoue} + */ + public SaniDialogue() { + /* + * empty. + */ + } + + /** + * Constructs the {@code SaniDialogue} + * @param player The player instance. + */ + public SaniDialogue(Player player) { + super(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + npc("Greetings, " + player.getUsername(), "I sell weapons and armour."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + options("Let me see your stock.", "Where do I get other items, like gloves?", "How do I open these box sets?"); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + player("Let me see your stock."); + stage = 10; + break; + case 2: + player("Where do I get other items, like gloves and capes?"); + stage = 20; + break; + case 3: + player("How do I open these box sets?"); + stage = 30; + break; + } + break; + case 10: + options("Weapons", "Armour"); + stage++; + break; + case 11: + switch (buttonId) { + case 1: + if (player.getSkills().getLevel(Skills.ATTACK) < 30) { + openWeaponShop(player, 204); + end(); + break; + } + options("Weapons (Bronze - Mithril)", "Weapons (Adamant - Dragon)"); + stage = 12; + break; + case 2: + end(); + break; + } + break; + case 12: + switch (buttonId) { + case 1: + openWeaponShop(player, 204); + end(); + break; + case 2: + openWeaponShop(player, 205); + end(); + break; + } + break; + case 13: + end(); + break; + case 20: + npc("Gloves of all kinds may be feely purchased from the", "Culinaromancer's chest below the Lumbridge Castle.", "On the other hand, high-tier armours can be obtained", "by defeating high-levelled bosses, like the Corporeal Beast."); + stage++; + break; + case 21: + npc("Bossing is not the only source of high-tier armour.", "Try Slayer or Barrows, catching Dragon Implings or", "perhaps even defeating monsters inside the TzHaar", "cave for fabled onyx equipment is more your style."); + stage++; + break; + case 22: + player("I see...", "So this means that you only sell common armours", "to help adventurers like myself get started in the world", "of Gielinor."); + stage++; + break; + case 23: + npc("Indeed, that is true. If you have any more questions", "The Gielinor guide near the green portal should be able", "to assist you further."); + stage = 0; + break; + case 30: + player("How exactly do I open these box sets that you", "are selling?"); + stage++; + break; + case 31: + npc("Take the box set to the Grand Exchange clerk. Right", "click her and select 'sets'. Next, right-click the box", "item that is in your inventory to exchange the set for", "the items that are inside the box."); + stage++; + break; + case 32: + npc("You may always convert the individual items back into", "a box set at any time in order to save banking", "space."); + stage = 0; + break; + } + return true; + } + + /** + * Opens the weapon shop. + * @param player The player. + * @param uid The uid. + */ + private void openWeaponShop(Player player, int uid) { + Shops.openId(player, uid); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new SaniDialogue(player); + } + + @Override + public int[] getIds() { + return new int[] { 4905 }; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/SawmillOperator.java b/Server/src/main/content/region/misthalin/varrock/dialogue/SawmillOperator.java new file mode 100644 index 0000000..505fbb3 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/SawmillOperator.java @@ -0,0 +1,97 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.component.Component; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Handles the SawmillOperator dialogue. + * @author Vexia + */ +@Initializable +public class SawmillOperator extends DialoguePlugin { + + public SawmillOperator() { + + } + + public SawmillOperator(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new SawmillOperator(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL,"Do you want me to make some planks for you? Or", "would you be interested in some other housing supplies?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + options("Planks please!", "What kind of planks can you make?", "Can I buy some housing supplies?", "Nothing, thanks."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HAPPY,"Planks please!"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.ASKING,"What kind of planks can you make?"); + stage = 20; + break; + case 3: + end(); + npc.openShop(player); + break; + case 4: + interpreter.sendDialogues(player, FacialExpression.FRIENDLY,"Nothing, thanks."); + stage = 40; + break; + } + break; + case 40: + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY,"Well come back when you want some. You can't get", "good quality planks anywhere but here!"); + stage = 999; + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_ASKING,"What kind of planks do you want?"); + stage = 11; + break; + case 11: + end(); + player.getInterfaceManager().open(new Component(403)); + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL,"I can make planks from wood, oak, teak and mahogany.", "I don't make planks from other woods as they're no", "good for making furniture."); + stage = 21; + break; + case 21: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL,"Wood and oak are all over the place, but teak and", "mahogany can only be found in a few places like", "Karamja and Etceteria."); + stage = 999; + break; + case 999: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 4250 }; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/ScavvoDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/ScavvoDialogue.java new file mode 100644 index 0000000..c097b28 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/ScavvoDialogue.java @@ -0,0 +1,57 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Handles the ScavvoDialogue dialogue. + * @author 'Vexia + */ +@Initializable +public class ScavvoDialogue extends DialoguePlugin { + + public ScavvoDialogue() { + + } + + public ScavvoDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new ScavvoDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "'Ello matey! D'ya wanna buy some exiting new toys?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Let's have a look then."); + stage = 1; + break; + case 1: + end(); + npc.openShop(player); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 537 }; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/SchoolchildMuseumDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/SchoolchildMuseumDialogue.java new file mode 100644 index 0000000..ff51da7 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/SchoolchildMuseumDialogue.java @@ -0,0 +1,60 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; +import core.tools.RandomFunction; + +/** + * Handles the SchoolchildMuseumDialogue dialogue. + * + * @author afaroutdude + */ +@Initializable +public class SchoolchildMuseumDialogue extends DialoguePlugin { + + private static final String[][] chats = { + {"Can you find my teacher? I need the toilet!"}, + {"I wonder what they're doing behind that", "rope."}, + {"Teacher! Can we go to the Natural History Exhibit", "now?"}, + {"*sniff* They won't let me take an arrowhead as a", "souvenir."}, + {"Yaaay! A day off school."}, + {"I wanna be an archaeologist when I grow up!"}, + {"Sada... Sram... Sa-ra-do-min is bestest!"}, + {"*cough* It's so dusty in here."}, + {"Maz... Zar... Za-mor-ak is bestest!"} + }; + + public SchoolchildMuseumDialogue() { + + } + + public SchoolchildMuseumDialogue(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[]{5984, 5945, 5946, 10}; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + end(); + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new SchoolchildMuseumDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.CHILD_FRIENDLY, chats[RandomFunction.random(0, chats.length)]); + return true; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/ShilopDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/ShilopDialogue.java new file mode 100644 index 0000000..d17b6b3 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/ShilopDialogue.java @@ -0,0 +1,243 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.plugin.Initializable; +import core.game.node.item.Item; +import content.data.Quests; + +/** + * Represents the dialogue plugin used for the shilop npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class ShilopDialogue extends DialoguePlugin { + + /** + * Represents the coins item. + */ + private static final Item COINS = new Item(995, 100); + + /** + * Represents the id. + */ + private int id; + + /** + * Constructs a new {@code ShilopDialogue} {@code Object} + */ + public ShilopDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code ShilopDialogue} {@code Object}. + * @param player the player. + */ + public ShilopDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new ShilopDialogue(player); + } + + @Override + public boolean open(Object... args) { + if (args[0] instanceof NPC) { + id = ((NPC) args[0]).getId(); + } else if (args[0] instanceof Integer) { + id = (Integer) args[0]; + } + final Quest quest = player.getQuestRepository().getQuest(Quests.GERTRUDES_CAT); + switch (quest.getStage(player)) { + case 0: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Hello again."); + stage = 0; + break; + case 10: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Hello there, I've been looking for you."); + stage = 100; + break; + case 20: + case 30: + case 40: + case 50: + interpreter.sendDialogues(player, FacialExpression.THINKING, "Where did you say you saw Fluffs?"); + stage = 130; + break; + default: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Hello again."); + stage = 0; + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + final Quest quest = player.getQuestRepository().getQuest(Quests.GERTRUDES_CAT); + switch (stage) { + case 0: + interpreter.sendDialogues(id, FacialExpression.CHILD_ANGRY, "You think you're tough do you?"); + stage = 1; + break; + case 1: + interpreter.sendDialogues(player, FacialExpression.THINKING, "Pardon?"); + stage = 2; + break; + case 2: + interpreter.sendDialogues(id, FacialExpression.CHILD_ANGRY, "I can beat anyone up!"); + stage = 3; + break; + case 3: + interpreter.sendDialogues(783, FacialExpression.CHILD_ANGRY, "He can you know!"); + stage = 4; + break; + case 4: + interpreter.sendDialogues(player, FacialExpression.THINKING, "Really?"); + stage = 5; + break; + case 5: + interpreter.sendDialogue("The boy begins to jump around with his fists up.", "You wonder what sort of desperado he'll grow up to be."); + stage = 6; + break; + case 6: + end(); + break; + case 100:// stage 10 + interpreter.sendDialogues(id, FacialExpression.CHILD_SURPRISED, "I didn't mean to take it! I just forgot to pay."); + stage = 101; + break; + case 101: + interpreter.sendDialogues(player, FacialExpression.THINKING, "What? I'm trying to help your mum find Fluffs."); + stage = 102; + break; + case 102: + interpreter.sendDialogues(id == 781 ? 783 : 781, FacialExpression.CHILD_SIDE_EYE, "I might be able to help. Fluffs followed me to our secret", "play area and I haven't seen her since."); + stage = 103; + break; + case 103: + interpreter.sendDialogues(player, FacialExpression.THINKING, "Where is this play area?"); + stage = 104; + break; + case 104: + interpreter.sendDialogues(id == 781 ? 783 : 781, FacialExpression.CHILD_SIDE_EYE, "If I told you that, it wouldn't be a secret."); + stage = 105; + break; + case 105: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "What will make you tell me?"); + stage = 106; + break; + case 106: + interpreter.sendDialogues(id == 781 ? 783 : 781, FacialExpression.CHILD_SUSPICIOUS, "Well...now you ask, I am a bit short on cash."); + stage = 107; + break; + case 107: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "How much?"); + stage = 108; + break; + case 108: + interpreter.sendDialogues(id == 781 ? 783 : 781, FacialExpression.CHILD_SIDE_EYE, "10 coins."); + stage = 109; + break; + case 109: + interpreter.sendDialogues(id == 781 ? 783 : 781, FacialExpression.CHILD_SURPRISED, "10 coins?!"); + stage = 110; + break; + case 110: + interpreter.sendDialogues(id == 781 ? 783 : 781, FacialExpression.CHILD_NORMAL, "I'll handle this."); + stage = 111; + break; + case 111: + interpreter.sendDialogues(id == 781 ? 783 : 781, FacialExpression.CHILD_FRIENDLY, "100 coins should cover it."); + stage = 112; + break; + case 112: + interpreter.sendDialogues(player, FacialExpression.ANGRY, "100 coins! Why should I pay you?"); + stage = 113; + break; + case 113: + interpreter.sendDialogues(id == 781 ? 783 : 781, FacialExpression.CHILD_NORMAL, "You shouldn't, but we won't help otherwise. We never", "liked that cat anyway, so what do you say?"); + stage = 114; + break; + case 114: + interpreter.sendOptions("Select an Option", "I'm not paying you a penny.", "Okay then, I'll pay."); + stage = 115; + break; + case 115: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.ANGRY, "I'm not paying you a penny."); + stage = 116; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Okay then, I'll pay."); + stage = 118; + break; + } + break; + case 116: + interpreter.sendDialogues(id == 781 ? 783 : 781, FacialExpression.CHILD_SIDE_EYE, "Okay then, I'll find another way to make money."); + stage = 117; + break; + case 117: + end(); + break; + case 118: + if (!player.getInventory().containsItem(COINS)) { + interpreter.sendDialogues(player, null, "Sorry, I don't seem to have enough coins."); + stage = 117; + return true; + } + if (player.getInventory().remove(COINS)) { + interpreter.sendItemMessage(COINS, "You give the lad 100 coins."); + stage = 119; + } else { + interpreter.sendDialogues(player, null, "Sorry, I don't seem to have enough coins."); + stage = 117; + } + quest.setStage(player, 20); + break; + case 119: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "There you go, now where did you see Fluffs?"); + stage = 120; + break; + case 120: + interpreter.sendDialogues(id == 781 ? 783 : 781, FacialExpression.CHILD_NORMAL, "We play at an abandoned lumber mill to the north east.", "Just beyond the Jolly Boar Inn. I saw Fluffs running", "around in there."); + stage = 121; + break; + case 121: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Anything else?"); + stage = 122; + break; + case 122: + interpreter.sendDialogues(id == 781 ? 783 : 781, FacialExpression.CHILD_SIDE_EYE, "Well, you'll have to find the broken fence to get in. I'm", "sure you can manage that."); + stage = 123; + break; + case 123: + end(); + break; + case 130: + interpreter.sendDialogues(id, FacialExpression.CHILD_SIDE_EYE, "Weren't you listening? I saw the flea bag in the old", "lumber mill just north east of here. Just walk past the", "Jolly Boar Inn and you should find it."); + stage = 131; + break; + case 131: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 781 }; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/SinkethsDiary.kt b/Server/src/main/content/region/misthalin/varrock/dialogue/SinkethsDiary.kt new file mode 100644 index 0000000..79a1f59 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/SinkethsDiary.kt @@ -0,0 +1,202 @@ +package content.region.misthalin.varrock.dialogue + +import content.global.handlers.iface.BookInterface +import content.global.handlers.iface.BookLine +import content.global.handlers.iface.Page +import content.global.handlers.iface.PageSet +import core.api.setAttribute +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import org.rs09.consts.Items + +// This is not formatted well. See _-88E9n9jWA +class SinkethsDiary : InteractionListener { + // Obtainable during the What Lies Below quest. + companion object { + private val TITLE = "Sin'keth's diary" + private val CONTENTS = arrayOf( + PageSet( + Page( + BookLine("'...2nd Pentember,", 55), + BookLine("Fifth Age,70", 56), + BookLine("We have worked", 57), + BookLine("for days. It is a weary", 58), + BookLine("and tiring journey that", 59), + BookLine("my brothers and I must", 60), + BookLine("take,but we are close", 61), + BookLine("to success! Elder Dag'eth", 62), + BookLine("has led us well and he", 63), + BookLine("has told us that Zamorak", 64), + BookLine("will reward us greatly", 65), + BookLine("for our service to Him.", 66), + ), + Page( + BookLine("The priests of Saradomin", 67), + BookLine("haunt our very steps and", 68), + BookLine("I fear our discovery. Yet,", 69), + BookLine("soon will be the hour of", 70), + BookLine("our glory. The Dagon'hai", 71), + BookLine("will prevail and the city", 72), + BookLine("will be ours! We will throw", 73), + BookLine("down the vile yoke of", 74), + BookLine("Saradominand the", 75), + BookLine("Dagon'hai will", 76), + ) + ), + PageSet( + Page( + BookLine("be victorious! ", 55), + BookLine("", 56), + BookLine("9th Pentember,Fifth Age, 70", 57), + BookLine("Today we donned the", 58), + BookLine("filthy robes of", 59), + BookLine("the Saradomin priests.", 60), + BookLine("It was a foul deed and", 61), + BookLine("distasteful to my very", 62), + BookLine("soul,yet it had to be", 63), + BookLine("done. Without the disguise,", 64), + BookLine("we would surely have been", 65), + ), + Page( + BookLine("found out and ruined. ", 66), + BookLine("We erected a statue", 67), + BookLine("of Saradomin himself", 68), + BookLine("just outside the city", 69), + BookLine("to the east. Our Lord", 70), + BookLine("Zamorak must be laughing", 71), + BookLine("in the faces of our enemies", 72), + BookLine("at such a deception,for", 73), + BookLine("this statue holds the key", 74), + BookLine("to our success. Beneath", 75), + BookLine("the arrogant caricature", 76), + ) + ), + PageSet( + Page( + BookLine("of this worthless deity", 55), + BookLine("lies the entrance to our", 56), + BookLine("most sacred work yet: the", 57), + BookLine("Tunnel of Chaos. With this", 58), + BookLine("tunnel,we are able to", 59), + BookLine("traverse to the very", 60), + BookLine("source of our power,", 61), + BookLine("the Chaos Temple itself.", 62), + BookLine("Those foolish followers", 63), + BookLine("of Saradomin do not", 64), + BookLine("even sense what", 65), + BookLine("we have achieved. They", 66), + ), + Page( + BookLine("have filled the statue", 67), + BookLine("with their accursed holy", 68), + BookLine("magic,covering even the", 69), + BookLine("merest traces of our work", 70), + BookLine("beneath. They have granted", 71), + BookLine("us the most perfect of", 72), + BookLine("disguises.", 73), + BookLine("Zamorak be praised!", 74), + BookLine("", 75), + BookLine("11th Pentember,Fifth Age, 70", 76), + ) + ), + PageSet( + Page( + BookLine("Excellent news! I", 55), + BookLine("have been chosen", 56), + BookLine("by Elder Dag'eth to be", 57), + BookLine("the next Hyeraph. I,", 58), + BookLine("Sin'keth Magis,", 59), + BookLine("will lead our people", 60), + BookLine("in the incantation of", 61), + BookLine("Zamorak's Will. ", 62), + BookLine("Surely this means", 63), + BookLine("I will become High Elder!", 64), + BookLine("I must prove worthy to", 65), + BookLine("Lord Zamorak. He will not", 66), + ), + Page( + BookLine("find me wanting. There", 67), + BookLine("is much to do in ", 68), + BookLine("preparation for the", 69), + BookLine("ceremony and I do", 70), + BookLine("not have long.", 71), + BookLine("", 72), + BookLine("24th Septober,Fifth Age, 70", 73), + BookLine("Disaster!", 74), + BookLine("The incantation of Zamorak's", 75), + BookLine("Will was discovered by", 76), + ) + ), + PageSet( + Page( + BookLine("a loathsome watchman,of", 55), + BookLine("all people. ", 56), + BookLine("Zamorak's Blood!", 57), + BookLine("The fates are cruel! We", 58), + BookLine("could not finish the final", 59), + BookLine("rites of the spell. Our", 60), + BookLine("work has been undone and", 61), + BookLine("we have no time to gather", 62), + BookLine("our forces together and", 63), + BookLine("hide. We are being followed", 64), + BookLine("by the guards and the ", 65), + BookLine("Priests of Filth are", 66), + ), + Page( + BookLine("at our heels.", 67), + BookLine("We must flee the city!", 68), + BookLine("Elder La'nou and Elder", 69), + BookLine("Kree'nag were slain whilst", 70), + BookLine("protecting the sanctum.", 71), + BookLine("Elder Dag'eth will not", 72), + BookLine("leave with us. Zamorak", 73), + BookLine("take him,he will stand", 74), + BookLine("against the hordes that", 75), + BookLine("follow us! I am the last", 76), + ) + ), + PageSet( + Page( + BookLine("of the Elders. The order", 55), + BookLine("looks to me now.", 56), + BookLine("", 57), + BookLine("27th Septober,Fifth Age, 70", 58), + BookLine("Today,the last of", 59), + BookLine("our order entered the", 60), + BookLine("Tunnel of Chaos. We", 61), + BookLine("will journey to the Chaos", 62), + BookLine("Temple and let Zamorak", 63), + BookLine("Himself decide our fate.", 64), + BookLine("What happened to Elder", 65), + BookLine("Dag'eth, I know not. As", 66), + ), + Page( + BookLine("the city guards closed", 67), + BookLine("upon us,I cast an Earth", 68), + BookLine("Bolt spell to collapse", 69), + BookLine("the entrance of the tunnel", 70), + BookLine("in an avalanche of earth", 71), + BookLine("and stone,saving us and", 72), + BookLine("dooming us in one breath.", 73), + BookLine("There is only one place", 74), + BookLine("for us to go now...", 75), + ), + ) + ) + } + + private fun display(player: Player, pageNum: Int, buttonID: Int): Boolean { + BookInterface.pageSetup(player, BookInterface.FANCY_BOOK_3_49, TITLE, CONTENTS) + return true + } + + override fun defineListeners() { + on(Items.SINKETHS_DIARY_11002, IntType.ITEM, "read") { player, _ -> + setAttribute(player, "bookInterfaceCallback", ::display) + setAttribute(player, "bookInterfaceCurrentPage", 0) + display(player, 0, 0) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/SmithingApparenticeDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/SmithingApparenticeDialogue.java new file mode 100644 index 0000000..2e50d20 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/SmithingApparenticeDialogue.java @@ -0,0 +1,56 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Handles the SmithingApparenticeDialogue dialogue. + * @author 'Vexia + */ +@Initializable +public class SmithingApparenticeDialogue extends DialoguePlugin { + + public SmithingApparenticeDialogue() { + + } + + public SmithingApparenticeDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new SmithingApparenticeDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Can you teach me the basics of smelting please?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "You'll need to have mined some ore to smelt first. Go", "see the mining tutor to the south if you're not sure", "how to do this."); + stage = 1; + break; + case 1: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 7959,4904 }; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/SurokMagis.java b/Server/src/main/content/region/misthalin/varrock/dialogue/SurokMagis.java new file mode 100644 index 0000000..588f8b1 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/SurokMagis.java @@ -0,0 +1,78 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; + +/** + * Handles the SurokMagis dialogue. + * @author 'Vexia + */ +public class SurokMagis extends DialoguePlugin { + + public SurokMagis() { + + } + + public SurokMagis(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[] { 5834, 5835, 7002, 7136 }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "What do you want? ...Oh, wait. I know! You're", "porbably just like all the others, aren't you? After some", "fancy spell or potion from me, I bet!"); + stage = 1; + break; + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No! atleast, I don't think so. What sort of spells", "do you have?"); + stage = 2; + break; + case 2: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hah! I knew it! I expect you want my Aphro-Dizzy-", "Yak spell! Want someone to fall madly in love with you,", "eh?"); + stage = 3; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "That spell sounds very interesting, but I didn't mean to", "disturb you!"); + stage = 4; + break; + case 4: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Well, I see that you do have some manners. I'm glad", "to see that you use them."); + stage = 5; + break; + case 5: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Now, if it's all the same, I am very bust at the", "moment. Come back another time", "please and thank you."); + stage = 6; + break; + case 6: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Yes, ofcourse!"); + stage = 7; + break; + case 7: + end(); + break; + } + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new SurokMagis(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Excuse me?"); + stage = 0; + return true; + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/TarquinDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/TarquinDialogue.java new file mode 100644 index 0000000..0139ce2 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/TarquinDialogue.java @@ -0,0 +1,142 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Handles the TarquinDialogue dialogue. + * @author 'Vexia + */ +@Initializable +public class TarquinDialogue extends DialoguePlugin { + + public TarquinDialogue() { + + } + + public TarquinDialogue(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[] { 3328 }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hello old bean. Is there something I can help you", "with?"); + stage = 1; + break; + case 1: + interpreter.sendOptions("Select an Option", "Who are you?", "Can you teach me about Canoeing?"); + stage = 2; + break; + case 2: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Who are you?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "It's really quite simple. Just walk down to that tree on", "the water bank and chop it down."); + stage = 24; + break; + + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "My name is Tarquin Marjoribanks."); + stage = 11; + break; + case 11: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I'd be surprised if you haven't already heard of me?"); + stage = 12; + break; + case 12: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Why would I have heard of you Mr. Marjoribanks?"); + stage = 13; + break; + case 13: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "It's pronounced 'Marchbanks'!"); + stage = 14; + break; + case 14: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "You should know of me because I am a member of the", "royal family of Misthalin!"); + stage = 15; + break; + case 15: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Are you related to King Roald?"); + stage = 16; + break; + case 16: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Oh yes! Quite closely actually."); + stage = 17; + break; + case 17: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I'm his 4th cousin, once removed on his mothers side."); + stage = 18; + break; + case 18: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Er... Okay. What are you doing here then?"); + stage = 19; + break; + case 19: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I'm canoeing on the river! It's enormous fun! Would", "you like to know how?"); + stage = 20; + break; + case 20: + interpreter.sendOptions("Select an Option", "Yes", "No"); + stage = 21; + break; + case 21: + switch (buttonId) { + case 1: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "It's really quite simple. Just walk down to that tree on", "the water bank and chop it down."); + stage = 24; + break; + case 2: + end(); + break; + + } + break; + case 24: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Then take your axe to it and shape it how you like!"); + stage = 26; + break; + case 26: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "You look like you know your way around a tree,", "you can make many canoes."); + stage = 27; + break; + case 27: + end(); + break; + case 25: + end(); + break; + case 100: + break; + } + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new TarquinDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello there."); + stage = 0; + return true; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/TeaSellerDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/TeaSellerDialogue.java new file mode 100644 index 0000000..48693f2 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/TeaSellerDialogue.java @@ -0,0 +1,91 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Handles the TeaSellerDialogue dialogue. + * @author 'Vexia + */ +@Initializable +public class TeaSellerDialogue extends DialoguePlugin { + + public TeaSellerDialogue() { + + } + + public TeaSellerDialogue(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[] { 595 }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "Yes, please.", "No, thanks.", "What are you selling?"); + stage = 1; + break; + case 1: + + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Yes, please."); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No, thanks."); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What are you selling?"); + stage = 30; + break; + } + + break; + case 30: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Only the most delicious infusion of the leaves of the tea", "plant. Grown in the exotic regions of this world. Buy", "yourself a cup."); + stage = 31; + break; + case 31: + end(); + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Well, if you're sure. You know where to come if you do."); + stage = 21; + break; + case 21: + end(); + break; + case 10: + npc.openShop(player); + end(); + break; + } + + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new TeaSellerDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Greetings! Are you in need of refreshment?"); + stage = 0; + return true; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/TeacherandPupilMuseumDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/TeacherandPupilMuseumDialogue.java new file mode 100644 index 0000000..66dc0c1 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/TeacherandPupilMuseumDialogue.java @@ -0,0 +1,67 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Handles the TeacherandPupilMuseumDialogue dialogue. + * + * @author 'Vexia + */ +@Initializable +public class TeacherandPupilMuseumDialogue extends DialoguePlugin { + + public TeacherandPupilMuseumDialogue() { + + } + + public TeacherandPupilMuseumDialogue(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[]{5947}; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(5951, FacialExpression.CHILD_FRIENDLY, "Aww, but miss, it's sooo exciting."); + stage = 999; + break; + case 1: + interpreter.sendDialogues(5950, FacialExpression.HALF_GUILTY, "That's because he's an art critic, dear. They have", "some very funny ideas."); + stage = 999; + break; + case 999: + end(); + break; + } + + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new TeacherandPupilMuseumDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + if (npc.getLocation().getZ() == 0) { + interpreter.sendDialogues(5950, FacialExpression.ANGRY, "Stop pulling, we've plenty of time to see everything."); + stage = 0; + } else { + interpreter.sendDialogues(5951, FacialExpression.HALF_GUILTY, "That man over there talks funny, miss."); + stage = 1; + } + return true; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/TeacherandPupilMuseumMaleDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/TeacherandPupilMuseumMaleDialogue.java new file mode 100644 index 0000000..f663c28 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/TeacherandPupilMuseumMaleDialogue.java @@ -0,0 +1,66 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Handles the TeacherandPupilMuseumMaleDialogue dialogue. + * + * @author 'qmqz + */ +@Initializable +public class TeacherandPupilMuseumMaleDialogue extends DialoguePlugin { + + public TeacherandPupilMuseumMaleDialogue() { + + } + + public TeacherandPupilMuseumMaleDialogue(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[]{5944}; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(5948, FacialExpression.HALF_GUILTY, "I told you to go before we got here."); + stage = 1; + break; + + case 1: + interpreter.sendDialogues(5949, FacialExpression.CHILD_GUILTY, "But sir, I didn't need to go then!"); + stage = 2; + break; + + case 2: + interpreter.sendDialogues(5948, FacialExpression.HALF_GUILTY, "Alright, come on then."); + stage = 99; + break; + + case 99: + end(); + break; + } + + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new TeacherandPupilMuseumMaleDialogue(player); + } + + @Override + public boolean open(Object... args) { + interpreter.sendDialogues(5949, FacialExpression.CHILD_GUILTY, "Teacher! Sir! I need the toilet!"); + stage = 0; + return true; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/ThessaliaDialogue.kt b/Server/src/main/content/region/misthalin/varrock/dialogue/ThessaliaDialogue.kt new file mode 100644 index 0000000..21772e6 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/ThessaliaDialogue.kt @@ -0,0 +1,146 @@ +package content.region.misthalin.varrock.dialogue + +import core.api.playJingle +import core.game.component.Component +import core.plugin.Initializable +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import org.rs09.consts.Components + +@Initializable +class ThessaliaDialogue(player: Player? = null): DialoguePlugin(player) { + override fun open(vararg args: Any): Boolean { + + //The trade argument is handled elsewhere + if (args.size == 3) { //Right-Click 'Change-Clothes' Option + if (player.equipment.isEmpty) { + if (player.isMale) { + end() + player.interfaceManager.open(Component(Components.THESSALIA_CLOTHES_MALE_591)) + } else { + end() + player.interfaceManager.open(Component(Components.THESSALIA_CLOTHES_FEMALE_594)) + } + playJingle(player, 273) + } else { //Has some armour equipped + interpreter.sendDialogues(548, FacialExpression.WORRIED, "You can't try them on while wearing armour. Take", "it off and speak to me again.") + stage = 52 + } + return true + } + + npc = args[0] as NPC + + //Default Talk + interpreter.sendDialogues(npc, FacialExpression.ASKING, "Would you like to buy any fine clothes?") + stage = 0 + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> { + interpreter.sendOptions("Choose an option:", "What do you have?", "No, thank you.") + stage++ + } + 1 -> when (buttonId) { + 1 -> { + interpreter.sendDialogues(player, FacialExpression.ASKING, "What do you have?") + stage = 10 + } + 2 -> { + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "No, thank you.") + stage = 51 + } + } + 10 -> { + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "I have a number of fine pieces of clothing on sale or,", "if you prefer, I can offer you an exclusive", "total clothing makeover?") + stage++ + } + 11 -> { + interpreter.sendOptions("Select an Option", "Tell me more about this makeover.", "I'd just like to buy some clothes.") + stage++ + } + 12 -> when (buttonId) { + 1 -> { + interpreter.sendDialogues(player, FacialExpression.THINKING, "Tell me more about this makeover.") + stage = 20 + } + 2 -> { + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "I'd just like to buy some clothes.") + stage = 50 + } + } + 20 -> { + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Certainly!") + stage++ + } + 21 -> { + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Here at Thessalia's fine clothing boutique, we offer a", "unique service where we will totally revamp your outfit", "to your choosing, for... wait for it...") + stage++ + } + 22 -> { + interpreter.sendDialogues(npc, FacialExpression.AMAZED, "A fee of only 500 gold coins! Tired of always wearing", "the same old outfit, day in, day out? This is the service", "for you!") + stage++ + } + 23 -> { + interpreter.sendDialogues(npc, FacialExpression.ASKING, "So what do you say? Interested? We can change either", "your top, or your legwear for only 500 gold an item!") + stage++ + } + 24 -> { + interpreter.sendOptions("Select an Option", "I'd like to change my outfit, please.", "I'd just like to buy some clothes.") + stage++ + } + 25 -> when (buttonId) { + 1 -> { + interpreter.sendDialogues(player, FacialExpression.HAPPY, "I'd like to change my outfit, please.") + stage = 30 + } + 2 -> { + interpreter.sendDialogues(player, FacialExpression.HAPPY, "I'd just like to buy some clothes.") + stage = 50 + } + } + 30 -> if (player.equipment.isEmpty) { + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Just select what style and colour you would like from", "this catalogue, and then give me the 1000 gold when", "you've picked.") + stage++ + } else { //Has some armour equipped + interpreter.sendDialogues(npc, FacialExpression.WORRIED, "You can't try them on while wearing armour. Take", "it off and speak to me again.") + stage = 52 + } + 31 -> if (player.equipment.isEmpty) { + if (player.isMale) { + end() + player.interfaceManager.open(Component(Components.THESSALIA_CLOTHES_MALE_591)) + } else { + end() + player.interfaceManager.open(Component(Components.THESSALIA_CLOTHES_FEMALE_594)) + } + } + 49 -> { + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "That's ok! Just come back when you do have it!") + stage = 52 + } + 50 -> { + end() + npc.openShop(player) + } + 51 -> { + npc("Well, please return if you change your mind.") + stage++ + } + 52 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return ThessaliaDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(548) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/TrampDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/TrampDialogue.java new file mode 100644 index 0000000..703d867 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/TrampDialogue.java @@ -0,0 +1,87 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Handles the TrampDialogue dialogue. + * @author 'Vexia + */ +@Initializable +public class TrampDialogue extends DialoguePlugin { + + public TrampDialogue() { + + } + + public TrampDialogue(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[] { 11 }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + + switch (stage) { + case 0: + interpreter.sendOptions("What would you like to say?", "Yes, I can spare a little money.", "Sorry, you'll have to earn it yourself."); + stage = 10; + break; + case 10: + + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Yes, I can spare a little money."); + stage = 100; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.FURIOUS, "Sorry, you'll have to earn it yourself, just like I did."); + stage = 50; + break; + } + break; + case 100: + if (player.getInventory().contains(995, 1)) { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Thank's mate!"); + stage = 101; + } else { + end(); + player.getPacketDispatch().sendMessage("You only need one coin to give to this tramp."); + } + break; + case 101: + end(); + break; + case 50: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Please yourself."); + stage = 51; + break; + case 51: + end(); + break; + } + + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new TrampDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Got any spare change, mate?"); + stage = 0; + return true; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/ValaineDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/ValaineDialogue.java new file mode 100644 index 0000000..970913e --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/ValaineDialogue.java @@ -0,0 +1,72 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Handles the ValaineDialogue dialogue. + * @author 'Vexia + */ +@Initializable +public class ValaineDialogue extends DialoguePlugin { + + public ValaineDialogue() { + + } + + public ValaineDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new ValaineDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hello there. Want to have a look at what we're selling", "today?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "Yes please.", "No thank you."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Yes please."); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No thank you."); + stage = 3; + break; + } + break; + case 3: + end(); + break; + case 10: + end(); + npc.openShop(player); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 536 }; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/VarrockBartenderDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/VarrockBartenderDialogue.java new file mode 100644 index 0000000..67c0f28 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/VarrockBartenderDialogue.java @@ -0,0 +1,138 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.game.node.item.Item; + +/** + * The plugin used to handle the dialogue for the varrock bartender. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class VarrockBartenderDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code VarrockBartenderDialogue} {@code Object}. + */ + public VarrockBartenderDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code VarrockBartenderDialogue} {@code Object}. + * @param player the player. + */ + public VarrockBartenderDialogue(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[] { 732, 731 }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_ASKING, "Good day to you, brave adventurer. Can I get you a", "refreshing beer?"); + stage = 1; + break; + case 1: + interpreter.sendOptions("Select an Option", "Yes please!", "No thanks.", "How much?"); + stage = 2; + break; + case 2: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HAPPY, "Yes please!"); + stage = 10; + break; + + case 2: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "No thanks."); + stage = 20; + break; + + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_ASKING, "How much?"); + stage = 30; + break; + } + + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "Ok then, that's two gold coins please."); + stage = 11; + break; + case 11: + if (player.getInventory().contains(995, 2)) { + player.getInventory().remove(new Item(995, 2)); + player.getInventory().add(new Item(1917, 1)); + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Cheers!"); + stage = 12; + } else { + end(); + player.getPacketDispatch().sendMessage("You need two gold coins to buy a beer."); + } + break; + case 12: + interpreter.sendDialogues(player, FacialExpression.HAPPY, "Cheers!"); + stage = 13; + break; + case 13: + end(); + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "Let me know if you change your mind."); + stage = 21; + break; + case 21: + end(); + break; + case 30: + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "Two gold pieces a pint. So, what do you say?"); + stage = 31; + break; + case 31: + interpreter.sendOptions("Select an Option", "Yes please!", "No thanks."); + stage = 32; + break; + case 32: + + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HAPPY, "Yes please!"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.FRIENDLY, "No thanks."); + stage = 20; + break; + } + + break; + } + + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new VarrockBartenderDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello."); + stage = 0; + return true; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/VarrockCookDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/VarrockCookDialogue.java new file mode 100644 index 0000000..e174548 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/VarrockCookDialogue.java @@ -0,0 +1,152 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.game.node.item.Item; + +/** + * Handles the VarrockCookDialogue dialogue. + * @author 'Vexia + */ +@Initializable +public class VarrockCookDialogue extends DialoguePlugin { + + public VarrockCookDialogue() { + + } + + public VarrockCookDialogue(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[] { 5910 }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + + switch (stage) { + case 0: + interpreter.sendOptions("What would you like to say?", "Can you sell me any food?", "Can you give me any free food?", "I don't want anything from this horrible kitchen."); + stage = 1; + break; + case 1: + + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Can you sell me any food?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Can you give me any free food?"); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I don't want anything from this horrible kitchen."); + stage = 30; + break; + } + + break; + + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I suppose I could sell you some cabbage, if you're willing to", "pay for it. Cabbage is good for you."); + stage = 11; + break; + case 11: + interpreter.sendOptions("What would you like to say?", "Alright, I'll buy a cabbage.", "No thanks, I don't like cabbage."); + stage = 12; + break; + case 12: + + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Alright, I'll buy a cabbage."); + stage = 150; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No thanks, I don't like cabbage."); + stage = 160; + break; + } + + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Can you give me any free money?"); + stage = 21; + break; + case 21: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Why should I give you free money?"); + stage = 22; + break; + case 22: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Why should I give you free food?"); + stage = 23; + break; + case 23: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Oh, forget it."); + stage = 24; + break; + case 24: + end(); + break; + case 30: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "How dare you? I put a lot of effort into cleaning this", "kitchen. My daily sweat and elbow-grease keep this kitchen", "clean!"); + stage = 31; + break; + case 31: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Ewww!"); + stage = 32; + break; + case 32: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Oh, just leave me alone."); + stage = 33; + break; + case 33: + end(); + break; + case 150: + if (player.getInventory().contains(995, 1)) { + player.getInventory().remove(new Item(995, 1)); + player.getInventory().add(new Item(1965, 1)); + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "It's a deal. Now, make sure you eat it all up. Cabbage is", "good for you."); + stage = 151; + } else { + end(); + player.getPacketDispatch().sendMessage("You need one coin to buy a cabbage."); + } + break; + case 151: + end(); + break; + case 160: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Bah! People these days only appreciate junk food."); + stage = 161; + break; + case 161: + end(); + break; + } + + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new VarrockCookDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "What do you want? I'm busy!"); + stage = 0; + return true; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/VarrockEastBartenderDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/VarrockEastBartenderDialogue.java new file mode 100644 index 0000000..6c57f43 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/VarrockEastBartenderDialogue.java @@ -0,0 +1,154 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.game.world.GameWorld; + +/** + * Handles the VarrockEastBartenderDialogue dialogue. + * @author 'Vexia + */ +@Initializable +public class VarrockEastBartenderDialogue extends DialoguePlugin { + + public VarrockEastBartenderDialogue() { + + } + + public VarrockEastBartenderDialogue(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[] { 733 }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "A glass of your finest ale please.", "Can you recommend where an adventurer might make his fortune?", "Do you know where I can get some good equipment?"); + stage = 1; + break; + case 1: + + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HAPPY, "A glass of your finest ale please."); + stage = 10; + break; + + case 2: + interpreter.sendDialogues(player, FacialExpression.ASKING, "Can you recommend where an adventurer might make", "his fortune?"); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.ASKING, "Do you know where I can get some good equipment?"); + stage = 30; + break; + } + + break; + + case 10: + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "No problemo. That'll be 2 coins."); + stage = 11; + break; + case 11: + if (player.getInventory().contains(995, 2)) { + player.getInventory().remove(new Item(995, 2)); + player.getInventory().add(new Item(1917, 1)); + end(); + player.getPacketDispatch().sendMessage("You buy a pint of beer."); + } else { + end(); + player.getPacketDispatch().sendMessage("You need 2 coins to buy ale."); + } + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "Ooh I don't know if I should be giving away information,", "makes the computer game too easy."); + stage = 21; + break; + case 21: + interpreter.sendOptions("Select an Option", "Oh ah well...", "Computer game? What are you talking about?", "Just a small clue?"); + stage = 22; + break; + case 22: + + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Oh ah well..."); + stage = 150; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.ASKING, "Computer game? What are you talking about?"); + stage = 160; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.THINKING, "Just a small clue?"); + stage = 170; + break; + } + + break; + case 160: + interpreter.sendDialogues(npc, FacialExpression.THINKING, "This world around us... is a computer game.... called", "" + GameWorld.getSettings().getName() + "."); + stage = 161; + break; + case 161: + interpreter.sendDialogues(player, FacialExpression.HALF_THINKING, "Nope, still don't understand what you are talking about.", "What's a computer?"); + stage = 162; + break; + case 162: + interpreter.sendDialogues(npc, FacialExpression.THINKING, "It's a sort of magic box thing, which can do all sorts of", "stuff."); + stage = 163; + break; + case 163: + interpreter.sendDialogues(player, FacialExpression.WORRIED, "I give up. You're obviously completely mad."); + stage = 164; + break; + case 164: + end(); + break; + case 150: + end(); + break; + case 30: + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "Well, there's the sword shop across the road, or there's", "also all sorts of shops up around the market."); + stage = 31; + break; + case 31: + end(); + break; + case 170: + interpreter.sendDialogues(npc, FacialExpression.NEUTRAL, "Go and talk to the bartender at the Holly Boar Inn, he", "doesn't seem to mind giving away clues."); + stage = 171; + break; + case 171: + end(); + break; + } + + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new VarrockEastBartenderDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "What can I do yer for?"); + stage = 0; + return true; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/VarrockGateGuardDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/VarrockGateGuardDialogue.java new file mode 100644 index 0000000..4fba68d --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/VarrockGateGuardDialogue.java @@ -0,0 +1,54 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Handles the VarrockGateGuardDialogue dialogue. + * @author 'Vexia + */ +@Initializable +public class VarrockGateGuardDialogue extends DialoguePlugin { + + public VarrockGateGuardDialogue() { + + } + + public VarrockGateGuardDialogue(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[] { 368 }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + + switch (stage) { + case 0: + end(); + break; + } + + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new VarrockGateGuardDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Please don't disturb me, I've got to keep an eye out for", "suspicious indiduals."); + stage = 0; + return true; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/VarrockShopKeeperDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/VarrockShopKeeperDialogue.java new file mode 100644 index 0000000..3597cce --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/VarrockShopKeeperDialogue.java @@ -0,0 +1,78 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the Varrock shop keeper dialogue. + */ +@Initializable +public final class VarrockShopKeeperDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code VarrockShopKeeperDialogue} {@code Object}. + */ + public VarrockShopKeeperDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code VarrockShopKeeperDialogue} {@code Object}. + * @param player the player. + */ + public VarrockShopKeeperDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new VarrockShopKeeperDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Can I help you at all?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "Yes, please. What are you selling?", "How should I use your shop?", "No, thanks."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + end(); + npc.openShop(player); + break; + case 2: + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "I'm glad you ask! You can buy as many of the items", "stocked as you wish. You can also sell most items to the", "shop."); + stage = 20; + break; + case 3: + end(); + break; + } + break; + case 20: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 522, 523 }; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/VarrockSwordShopDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/VarrockSwordShopDialogue.java new file mode 100644 index 0000000..d0deef1 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/VarrockSwordShopDialogue.java @@ -0,0 +1,81 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; + +/** + * Handles the VarrockSwordShopDialogue dialogue. + * @author 'Vexia + */ + +@Initializable +public class VarrockSwordShopDialogue extends DialoguePlugin { + + public VarrockSwordShopDialogue() { + + } + + public VarrockSwordShopDialogue(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[] { 551, 552 }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "Yes, please.", "No, I'm okay for swords right now."); + stage = 1; + break; + case 1: + + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HAPPY, "Yes, please."); + stage = 2; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.FRIENDLY, "No, I'm okay for swords right now."); + stage = 10; + break; + } + + break; + case 2: + end(); + npc.openShop(player); + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "Come back if you need any."); + stage = 11; + break; + case 11: + end(); + break; + } + + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new VarrockSwordShopDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Hello, adventurer. Can I interest you in some swords?"); + stage = 0; + return true; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/WiloughDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/WiloughDialogue.java new file mode 100644 index 0000000..02deb33 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/WiloughDialogue.java @@ -0,0 +1,242 @@ +package content.region.misthalin.varrock.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.plugin.Initializable; +import core.game.node.item.Item; +import content.data.Quests; + +/** + * Represents the dialogue used for wilough. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class WiloughDialogue extends DialoguePlugin { + + /** + * Represents the coins item. + */ + private static final Item COINS = new Item(995, 100); + + /** + * Represents the id. + */ + private int id; + + /** + * Constructs a new {@code WiloughDialogue} {@code Object}. + */ + public WiloughDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code WiloughDialogue} {@code Object}. + * @param player the player. + */ + public WiloughDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new WiloughDialogue(player); + } + + @Override + public boolean open(Object... args) { + if (args[0] instanceof NPC) { + id = ((NPC) args[0]).getId(); + } else if (args[0] instanceof Integer) { + id = (int) args[0]; + } + final Quest quest = player.getQuestRepository().getQuest(Quests.GERTRUDES_CAT); + switch (quest.getStage(player)) { + case 0: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Hello again."); + stage = 0; + break; + case 10: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Hello there, I've been looking for you."); + stage = 100; + break; + case 20: + case 30: + case 40: + case 50: + interpreter.sendDialogues(player, FacialExpression.THINKING, "Where did you say you saw Fluffs?"); + stage = 130; + break; + default: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Hello again."); + stage = 0; + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + final Quest quest = player.getQuestRepository().getQuest(Quests.GERTRUDES_CAT); + switch (stage) { + case 0: + interpreter.sendDialogues(id, FacialExpression.CHILD_ANGRY, "You think you're tough do you?"); + stage = 1; + break; + case 1: + interpreter.sendDialogues(player, FacialExpression.THINKING, "Pardon?"); + stage = 2; + break; + case 2: + interpreter.sendDialogues(id, FacialExpression.CHILD_ANGRY, "I can beat anyone up!"); + stage = 3; + break; + case 3: + interpreter.sendDialogues(781, FacialExpression.CHILD_ANGRY, "He can you know!"); + stage = 4; + break; + case 4: + interpreter.sendDialogues(player, FacialExpression.THINKING, "Really?"); + stage = 5; + break; + case 5: + interpreter.sendDialogue("The boy begins to jump around with his fists up.", "You wonder what sort of desperado he'll grow up to be."); + stage = 6; + break; + case 6: + end(); + break; + case 100:// stage 10 + interpreter.sendDialogues(id, FacialExpression.CHILD_SURPRISED, "I didn't mean to take it! I just forgot to pay."); + stage = 101; + break; + case 101: + interpreter.sendDialogues(player, FacialExpression.THINKING, "What? I'm trying to help your mum find Fluffs."); + stage = 102; + break; + case 102: + interpreter.sendDialogues(id == 783 ? 781 : 783, FacialExpression.CHILD_SIDE_EYE, "Ohh...well, in that case I might be able to help. Fluffs", "followed me to my super secret hideout, I haven't seen", "her since. She's probably off eating small creatures", "somewhere."); + stage = 103; + break; + case 103: + interpreter.sendDialogues(player, FacialExpression.THINKING, "Where is this secret hideout? I really need to find that", "cat for your mum."); + stage = 104; + break; + case 104: + interpreter.sendDialogues(id == 783 ? 781 : 783, FacialExpression.CHILD_SIDE_EYE, "If I told you that, it wouldn't be a secret."); + stage = 105; + break; + case 105: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "What will make you tell me?"); + stage = 106; + break; + case 106: + interpreter.sendDialogues(id == 783 ? 781 : 783, FacialExpression.CHILD_SUSPICIOUS, "Well...now you ask, I am a bit short on cash."); + stage = 107; + break; + case 107: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "How much?"); + stage = 108; + break; + case 108: + interpreter.sendDialogues(id == 783 ? 781 : 783, FacialExpression.CHILD_SIDE_EYE, "10 coins."); + stage = 109; + break; + case 109: + interpreter.sendDialogues(id == 783 ? 783 : id, FacialExpression.CHILD_SURPRISED, "10 coins?!"); + stage = 110; + break; + case 110: + interpreter.sendDialogues(id == 783 ? 783 : id, FacialExpression.CHILD_NORMAL, "I'll handle this."); + stage = 111; + break; + case 111: + interpreter.sendDialogues(id == 783 ? 783 : id, FacialExpression.CHILD_FRIENDLY, "100 coins should cover it."); + stage = 112; + break; + case 112: + interpreter.sendDialogues(player, FacialExpression.ANGRY, "100 coins! Why should I pay you?"); + stage = 113; + break; + case 113: + interpreter.sendDialogues(id == 783 ? 783 : id, FacialExpression.CHILD_NORMAL, "You shouldn't, but we won't help otherwise. We never", "liked that cat anyway, so what do you say?"); + stage = 114; + break; + case 114: + interpreter.sendOptions("Select an Option", "I'm not paying you a penny.", "Okay then, I'll pay."); + stage = 115; + break; + case 115: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.ANGRY, "I'm not paying you a penny."); + stage = 116; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Okay then, I'll pay."); + stage = 118; + break; + } + break; + case 116: + interpreter.sendDialogues(id == 783 ? 783 : id, FacialExpression.CHILD_SIDE_EYE, "Okay then, I'll find another way to make money."); + stage = 117; + break; + case 117: + end(); + break; + case 118: + if (!player.getInventory().containsItem(COINS)) { + end(); + return true; + } + if (player.getInventory().remove(COINS)) { + interpreter.sendItemMessage(COINS, "You give the lad 100 coins."); + quest.setStage(player, 20); + stage = 119; + } else { + interpreter.sendDialogues(player, null, "Sorry, I don't seem to have enough coins."); + stage = 117; + } + break; + case 119: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "There you go, now where did you see Fluffs?"); + stage = 120; + break; + case 120: + interpreter.sendDialogues(id == 783 ? 783 : id, FacialExpression.CHILD_NORMAL, "We play at an abandoned lumber mill to the north east.", "Just beyond the Jolly Boar Inn. I saw Fluffs running", "around in there."); + stage = 121; + break; + case 121: + interpreter.sendDialogues(player, FacialExpression.NEUTRAL, "Anything else?"); + stage = 122; + break; + case 122: + interpreter.sendDialogues(id == 783 ? 783 : id, FacialExpression.CHILD_SIDE_EYE, "Well, you'll have to find the broken fence to get in. I'm", "sure you can manage that."); + stage = 123; + break; + case 123: + end(); + break; + case 130: + interpreter.sendDialogues(id, FacialExpression.CHILD_SIDE_EYE, "Weren't you listening? I saw the flea bag in the old", "lumber mill just north east of here. Just walk past the", "Jolly Boar Inn and you should find it."); + stage = 131; + break; + case 131: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 783 }; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/surok/AbyssalBook.kt b/Server/src/main/content/region/misthalin/varrock/dialogue/surok/AbyssalBook.kt new file mode 100644 index 0000000..677934f --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/surok/AbyssalBook.kt @@ -0,0 +1,379 @@ +package content.region.misthalin.varrock.dialogue.surok + +import content.global.handlers.iface.BookInterface +import content.global.handlers.iface.BookLine +import content.global.handlers.iface.Page +import content.global.handlers.iface.PageSet +import core.api.setAttribute +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items + +@Initializable +class AbyssalBook : InteractionListener { + companion object { + private val TITLE = "Abyssal book" + private val CONTENTS = arrayOf( + PageSet( + Page( + BookLine("A Compendium of Research", 55), + BookLine("Into Chaotic Space.", 56), + BookLine("Author Unknown", 57), + BookLine("", 58), + BookLine("The strange dimension that", 59), + BookLine("we have name 'Abyssal Space'", 60), + BookLine("is something of an enigma.", 61), + BookLine("It was first discovered during", 62), + BookLine("a routine teleportation", 63), + BookLine("experiment that seemingly", 64), + BookLine("went wrong. We are still", 65), + ), + Page( + BookLine("not sure as to what caused", 66), + BookLine("this teleportation failure,", 67), + BookLine("but the discovery of a", 68), + BookLine("previously unknown dimension", 69), + BookLine("led to a flurry of", 70), + BookLine("research from the", 71), + BookLine("Zamorakian Magical Institute", 72), + BookLine("(henceforth known within", 73), + BookLine("(this document as the Z.M.I.).", 74), + ) + ), + PageSet( + Page( + BookLine("Under direct orders to examine", 55), + BookLine("this dimension, I feel I can", 56), + BookLine("accurately state the", 57), + BookLine("following conclusions.", 58), + BookLine("", 59), + BookLine("Conclusion One", 60), + BookLine("", 61), + BookLine("Abyssal Space is not", 62), + BookLine("a dimension in the way", 63), + BookLine("that we understand the term", 64), + BookLine("from examples such as", 65), + ), + Page( + BookLine("Zanaris or Feneskrae.", 66), + BookLine("", 67), + BookLine("Rather, it is the name", 68), + BookLine("we have given the dimension", 69), + BookLine("that exists between other", 70), + BookLine("more developed dimensions", 71), + ) + ), + PageSet( + Page( + BookLine("- the 'glue' that keeps", 55), + BookLine("each dimension together yet", 56), + BookLine("separate, if you will.", 57), + BookLine("", 58), + BookLine("The Abyssal space's existence", 59), + BookLine("at the 'fringe' of reality,", 60), + BookLine("means that it does not", 61), + BookLine("confirm to the same guidelines", 62), + BookLine("of space and time as Gielinor", 63), + BookLine("does; you may enter it and", 64), + BookLine("then leave it from an", 65), + ), + Page( + BookLine("identical spot, yet", 66), + BookLine("", 67), + BookLine("reappear many hundreds of", 68), + BookLine("miles at your target", 69), + BookLine("destination", 70), + BookLine("(the 'teleportation'", 71), + BookLine("phenomenon that we use daily).", 72), + ) + ), + PageSet( + Page( + BookLine("From this basic concept,", 55), + BookLine("I have extrapolated that", 56), + BookLine("all teleport magics in", 57), + BookLine("fact use Abyssal Space", 58), + BookLine("to make the passing of great", 59), + BookLine("distances occur in", 60), + BookLine("a very short space", 61), + BookLine("of time, from our perception.", 62), + BookLine("", 63), + BookLine("What is actually happening,", 64), + BookLine("is that the spellcaster is", 65), + ), + Page( + BookLine("entering abyssal space,", 66), + BookLine("and then immediately", 67), + BookLine("leaving again,", 68), + BookLine("with certain values as to speed", 69), + BookLine("and direction being taken care", 70), + BookLine("of in our spellingcasting to", 71), + BookLine("allow some degree of precision", 72), + BookLine("in these teleports.", 73), + ) + ), + PageSet( + Page( + BookLine("More worryingly,", 55), + BookLine("it seems apparent that", 56), + BookLine("the barriers between", 57), + BookLine("our dimensional space", 58), + BookLine("and abyssal space have", 59), + BookLine("become somewhat weakened", 60), + BookLine("through excessive use", 61), + BookLine("There have been isolated", 62), + BookLine("reports within the Z.M.I.", 63), + BookLine("that creatures not native", 64), + BookLine("to our dimension have entered", 65), + ), + Page( + BookLine("Gielinor through", 66), + BookLine("abyssal space,", 67), + BookLine("as well as the teleportation", 68), + BookLine("malfunction that first", 69), + BookLine("resulted in our discovery", 70), + BookLine("of this dimension.", 71), + ) + ), + PageSet( + Page( + BookLine("I strongly recommend that", 55), + BookLine("further research is taken", 56), + BookLine("- if the barriers between", 57), + BookLine("these dimensions are", 58), + BookLine("sufficiently weakened,", 59), + BookLine("there may exist the", 60), + BookLine("possibility of an alternative", 61), + BookLine("method to proceed", 62), + BookLine("with Operation:", 63), + BookLine("Transient without altering", 64), + BookLine("the other deities to our plans.", 65), + ), + Page( + BookLine("Conclusion Two", 66), + BookLine("", 67), + BookLine("When we have accepted", 68), + BookLine("that Abyssal Space is", 69), + BookLine("somewhat of a tesseract", 70), + BookLine("or hypercube with a direct", 71), + BookLine("relation to our dimension,", 72), + BookLine("then the benefits of", 73), + BookLine("exploiting this resource", 74), + BookLine("become more obvious.", 75), + ) + ), + PageSet( + Page( + BookLine("I ran some experiments", 55), + BookLine("with Sample XJ13", 56), + BookLine("(also known as 'rune essence')", 57), + BookLine("and managed to place six", 58), + BookLine("parts in a space that would", 59), + BookLine("seemingly only hold one.", 60), + BookLine("Continued", 61), + BookLine("experimentation with these", 62), + BookLine("stolen samples showed that", 63), + BookLine("moving items between our", 64), + BookLine("dimension and abyssal space", 65), + ), + Page( + BookLine("degraded the use of these", 66), + BookLine("pouches, but a simple", 67), + BookLine("transfiguration spell", 68), + BookLine("when cast within the abyss", 69), + BookLine("upon these pouches restored", 70), + BookLine("their usage back to", 71), + BookLine("the original results.", 72), + ) + ), + PageSet( + Page( + BookLine("Should we ever locate the", 55), + BookLine("source of these 'essence'", 56), + BookLine("that the Wizard Tower", 57), + BookLine("seem to have an endless", 58), + BookLine("supply of, I would strongly", 59), + BookLine("recommend the harvesting of", 60), + BookLine("these creatures for their", 61), + BookLine("organs so as to maximize", 62), + BookLine("the efficiency of our", 63), + BookLine("rune manufacturing process.", 64), + ), + Page( + BookLine("Some degree of caution will", 66), + BookLine("be necessary, as the creatures", 67), + BookLine("the creatures of the abyss", 68), + BookLine("are seemingly very aggressive.", 69), + ), + ), + PageSet( + Page( + BookLine("Conclusion Three", 55), + BookLine("", 56), + BookLine("Our first discovery of", 57), + BookLine("Abyssal Space was somewhat", 58), + BookLine("of a fluke - and a not easily", 59), + BookLine("repeatable fluke at that.", 60), + BookLine("It proved exceedingly", 61), + BookLine("difficult to find the", 62), + BookLine("correct mystical resonance", 63), + BookLine("for this dimension, due to", 64), + BookLine("my original belief that", 65), + ), + Page( + BookLine("Abyssal space is not a fully", 66), + BookLine("fledged dimension of its own,", 67), + BookLine("so we have had to resort", 68), + BookLine("to unusual measures to", 69), + BookLine("gain permanent access", 70), + BookLine("to this realm.", 71), + ), + ), + PageSet( + Page( + BookLine("We took a large number of", 55), + BookLine("initiates, and gave them", 56), + BookLine("each supplies to cast", 57), + BookLine("a portal spell. We then", 58), + BookLine("had them repeatedly teleport", 59), + BookLine("to various locations,", 60), + BookLine("seeking to replicate the", 61), + BookLine("original error that", 62), + BookLine("caused the first entry", 63), + BookLine("into Abyssal Space.", 64), + BookLine("Once one of our initiates", 65), + ), + Page( + BookLine("had managed to 'fail' his", 66), + BookLine("teleport and appear in", 67), + BookLine("Abyssal Space. he was", 68), + BookLine("then charged with remaining", 69), + BookLine("there and holding a portal", 70), + BookLine("spell open, so that more", 71), + BookLine("senior members of the Z.M.I.", 72), + ), + ), + PageSet( + Page( + BookLine("could gain entry via his portal.", 55), + BookLine("This initiate is still there,", 56), + BookLine("and due to the intense", 57), + BookLine("concentration required", 58), + BookLine("to keep he portal open,", 59), + BookLine("it is my recommendation", 60), + BookLine("that we leave him there", 61), + BookLine("holding the bridge open for us.", 62), + BookLine("As an initiate, he is", 63), + BookLine("always expendable should", 64), + BookLine("something go wrong, and", 65), + ), + Page( + BookLine("the slow passage of", 66), + BookLine("time within Abyssal Space", 67), + BookLine("means we don't need to", 68), + BookLine("worry about feeding", 69), + BookLine("him or anything.", 70), + BookLine("At the time of writing,", 71), + BookLine("this portal is still active,", 72), + BookLine("and will allow us to teleport", 73), + BookLine("people at will into Abyssal Space.", 74), + BookLine("The only downside to this", 75), + BookLine("method of teleportation", 76), + ), + ), + PageSet( + Page( + BookLine("is that we are using", 55), + BookLine("magic provided to us", 56), + BookLine("by our Lord Zamorak himself,", 57), + BookLine("so anybody who uses this", 58), + BookLine("teleport will inevitably be", 59), + BookLine("marked by him - or become", 60), + BookLine("'skulled' as the common", 61), + BookLine("folk put it.", 62), + BookLine("An interesting side-effect", 63), + BookLine("of this portal, is that", 64), + BookLine("various teleports within Abyssal", 65), + ), + Page( + BookLine("Space were opened up by", 66), + BookLine("it's casting. These teleports", 67), + BookLine("seem to lead to mysterious", 68), + BookLine("temples dedicated to various", 69), + BookLine("magical elements, which I", 70), + BookLine("believe are directly related", 71), + BookLine("to the rumours we have", 72), + ), + ), + PageSet( + Page( + BookLine("intercepted of the rediscovery", 55), + BookLine("of Runecrafting by the", 56), + BookLine("Wizards Tower. Sadly, we", 57), + BookLine("must conclude from these", 58), + BookLine("temples that the rumours are", 59), + BookLine("indeed true, and that the", 60), + BookLine("destruction of the Wizards", 61), + BookLine("Tower had been in vain,", 62), + BookLine("as was the sacrifice of", 63), + BookLine("those who died to try", 64), + BookLine("and prevent the meddling", 65), + ), + Page( + BookLine("Saradominists from gaining", 66), + BookLine("access to the creation of", 67), + BookLine("magical runes.", 68), + BookLine("I have detailed my findings", 69), + BookLine("relating to RuneCrafting", 70), + BookLine("in a separate document, and", 71), + BookLine("passed it on to my superiors,", 72), + BookLine("along with me recommendations", 73), + BookLine("on how best to thwart their", 74), + BookLine("research further.", 75), + ) + ), + PageSet( + Page( + BookLine("Until a final decision is taken,", 55), + BookLine("I suggest we make the best", 56), + BookLine("of a bad situation,", 57), + BookLine("and increase our own rune", 58), + BookLine("production to full", 59), + BookLine("manufacturing capabilities.", 60), + BookLine("", 61), + BookLine("I have already ordered buyers", 62), + BookLine("to purchase as much", 63), + BookLine("Sample XJ13", 64), + BookLine("as can be bought, and to", 65), + ), + Page( + BookLine("hire some mercenaries to", 66), + BookLine("sabotage the research efforts", 67), + BookLine("of the Wizards Tower, or", 68), + BookLine("failing that to provide us", 69), + BookLine("some insight into supplies", 70), + BookLine("where their study of these", 71), + BookLine("essence are coming from.", 72), + BookLine("", 73), + BookLine("Until my next report, I", 74), + BookLine("remain as ever a loyal servant.", 75), + BookLine("Strength Through Chaos!", 76), + ) + ), + ) + } + + private fun display(player: Player, pageNum: Int, buttonID: Int): Boolean { + BookInterface.pageSetup(player, BookInterface.FANCY_BOOK_3_49, TITLE, CONTENTS) + return true + } + + override fun defineListeners() { + on(Items.ABYSSAL_BOOK_5520, IntType.ITEM, "read") { player, _ -> + BookInterface.openBook(player, BookInterface.FANCY_BOOK_3_49, ::display) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/surok/DakhThoulanAegisDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/surok/DakhThoulanAegisDialogue.java new file mode 100644 index 0000000..fdb6a57 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/surok/DakhThoulanAegisDialogue.java @@ -0,0 +1,73 @@ +package content.region.misthalin.varrock.dialogue.surok; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; + +/** + * Handles the mishkaun dorn dialogue. + * @author Vexia + */ +public class DakhThoulanAegisDialogue extends DialoguePlugin { + + /** + * Constructs a new {@Code MishkalunDornDialogue} {@Code + * Object} + * @param player the player. + */ + public DakhThoulanAegisDialogue(Player player) { + super(player); + } + + /** + * Constructs a new {@Code MishkalunDornDialogue} {@Code + * Object} + */ + public DakhThoulanAegisDialogue() { + /** + * empty. + */ + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new DakhThoulanAegisDialogue(player); + } + + @Override + public boolean open(Object... args) { + player("Hi there."); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + npc("Hello, you one. What brings you to our humble", "dwelling?"); + stage++; + break; + case 1: + player("I was wondering what this place was?"); + stage++; + break; + case 2: + npc("These are the Tunnels of Chaos. They radiate", "with the energy of chaos magic. At the far end of the", "tunnel, you will find a portal to the Chaos Altar itself", "where chaos runes are crafted!"); + stage++; + break; + case 3: + player("Thanks for your time."); + stage++; + break; + case 4: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 5840 }; + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/surok/HuntForSurokPlugin.java b/Server/src/main/content/region/misthalin/varrock/dialogue/surok/HuntForSurokPlugin.java new file mode 100644 index 0000000..b9b424f --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/surok/HuntForSurokPlugin.java @@ -0,0 +1,42 @@ +package content.region.misthalin.varrock.dialogue.surok; + +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.plugin.Plugin; +import core.plugin.ClassScanner; + +/** + * Handles the hunt for surok mini quest. + * @author Vexia + */ + +public class HuntForSurokPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ClassScanner.definePlugin(new DakhThoulanAegisDialogue()); + ClassScanner.definePlugin(new MishkalunDornDialogue()); + ClassScanner.definePlugin(new SilasDahcsnuDialogue()); + ClassScanner.definePlugin(new SurokMagisDialogue()); + SceneryDefinition.forId(28780).getHandlers().put("option:use", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + switch (option) { + case "use": + switch (node.getId()) { + case 28780: + player.teleport(new Location(3326, 5469, 0)); + break; + } + break; + } + return true; + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/surok/MishkalunDornDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/surok/MishkalunDornDialogue.java new file mode 100644 index 0000000..f122776 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/surok/MishkalunDornDialogue.java @@ -0,0 +1,97 @@ +package content.region.misthalin.varrock.dialogue.surok; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; + +/** + * Handles the mishkaun dorn dialogue. + * @author Vexia + */ +public class MishkalunDornDialogue extends DialoguePlugin { + + /** + * Constructs a new {@Code MishkalunDornDialogue} {@Code + * Object} + * @param player the player. + */ + public MishkalunDornDialogue(Player player) { + super(player); + } + + /** + * Constructs a new {@Code MishkalunDornDialogue} {@Code + * Object} + */ + public MishkalunDornDialogue() { + /** + * empty. + */ + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new MishkalunDornDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc("You are excused. And you are welcome."); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + player("Excuse me...er..thanks."); + stage++; + break; + case 1: + npc("We are the Order of the Dagon'hai."); + stage++; + break; + case 2: + player("Who are you?"); + stage++; + break; + case 3: + npc("Through my magic, I can see a short way into", "the future."); + stage++; + break; + case 4: + player("How do you seem to know what i'm going to", "say? ...Er...oh."); + stage++; + break; + case 5: + npc("These are the Tunnels of Chaos."); + stage++; + break; + case 6: + player("What is...uh..aha! I'm not going to ask that. So you got it", "wrong!"); + stage++; + break; + case 7: + npc("Indeed. You are very clever."); + stage++; + break; + case 8: + player("So I won!"); + stage++; + break; + case 9: + npc("Yes."); + stage++; + break; + case 10: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 5839 }; + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/surok/SilasDahcsnuDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/surok/SilasDahcsnuDialogue.java new file mode 100644 index 0000000..b4e3023 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/surok/SilasDahcsnuDialogue.java @@ -0,0 +1,81 @@ +package content.region.misthalin.varrock.dialogue.surok; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; + +/** + * Handles the mishkaun dorn dialogue. + * @author Vexia + */ +public class SilasDahcsnuDialogue extends DialoguePlugin { + + /** + * Constructs a new {@Code SilasDahcsnuDialogue} {@Code + * Object} + * @param player the player. + */ + public SilasDahcsnuDialogue(Player player) { + super(player); + } + + /** + * Constructs a new {@Code SilasDahcsnuDialogue} {@Code + * Object} + */ + public SilasDahcsnuDialogue() { + /** + * empty. + */ + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new SilasDahcsnuDialogue(player); + } + + @Override + public boolean open(Object... args) { + player("Hello there."); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + npc("Can't you see that I'm busy here?"); + stage++; + break; + case 1: + player("Oh, Sorry, you don't look very busy."); + stage++; + break; + case 2: + npc("Don't look busy? I've got a lot of important work to do", "here."); + stage++; + break; + case 3: + player("Really? What do you do?"); + stage++; + break; + case 4: + npc("That doesn't concern you. What are you doing", "here anyway?"); + stage++; + break; + case 5: + player("None of your business!"); + stage++; + break; + case 6: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 5841 }; + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/dialogue/surok/SurokMagisDialogue.java b/Server/src/main/content/region/misthalin/varrock/dialogue/surok/SurokMagisDialogue.java new file mode 100644 index 0000000..85b9fa6 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/dialogue/surok/SurokMagisDialogue.java @@ -0,0 +1,201 @@ +package content.region.misthalin.varrock.dialogue.surok; + +import core.game.activity.ActivityPlugin; +import core.game.activity.CutscenePlugin; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.game.world.map.build.DynamicRegion; + +/** + * Handles the surok magis dialogue. + * @author Vexia + */ +public class SurokMagisDialogue extends DialoguePlugin { + + /** + * Constructs a new {@Code SurokMagisDialogue} {@Code Object} + * @param player the player. + */ + public SurokMagisDialogue(Player player) { + super(player); + } + + /** + * Constructs a new {@Code SurokMagisDialogue} {@Code Object} + */ + public SurokMagisDialogue() { + /** + * empty. + */ + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new SurokMagisDialogue(player); + } + + @Override + public boolean open(Object... args) { + player(player.getUsername() + "! The meddling adventurer."); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + player("Surok! What are you doing here?", "How did you-"); + stage++; + break; + case 1: + npc("Escape from Varrock Palace Library? That cruel", "imprisonment you left me in?"); + stage++; + break; + case 2: + player("Well...er..yes."); + stage++; + break; + case 3: + npc("Bah! A mere trifle for a powerful mage such as myself.", "There were plenty of other foolish people to help with", "my plans, you would do well to stay out of my way."); + stage++; + break; + case 4: + player("Stop, Surok! As a member of the Varrock Palace Secret", "Guard, I arrest you! Again!"); + stage++; + break; + case 5: + npc("Ha! I tire of this meaningless drivel. Catch me if you can."); + stage++; + break; + case 6: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 7002, 7136 }; + } + + /** + * Handles a surok cutscene. + * @author Vexia + */ + public static class SurokCutscene extends CutscenePlugin { + + /** + * The surok scene. + */ + private SurokScene scene; + + /** + * Constructs a new {@Code SurokCutscene} {@Code Object} + */ + public SurokCutscene() { + super("Surok Cutscene"); + } + + /** + * Constructs a new {@Code SurokCutscene} {@Code Object} + * @param player the player. + */ + public SurokCutscene(Player player) { + this(); + this.player = player; + } + + @Override + public boolean start(Player player, boolean login, Object... args) { + scene = (SurokScene) args[0]; + region = DynamicRegion.create(scene.getRegionId()); + setRegionBase(); + registerRegion(region.getId()); + return super.start(player, login, args); + } + + @Override + public ActivityPlugin newInstance(Player p) throws Throwable { + return new SurokCutscene(p); + } + + @Override + public Location getStartLocation() { + return base.transform(scene.getStartData()[0], scene.getStartData()[1], 0); + } + + @Override + public Location getSpawnLocation() { + return null; + } + + @Override + public void configure() { + + } + + /** + * Gets the scene. + * @return the scene + */ + public SurokScene getScene() { + return scene; + } + + /** + * Sets the bascene. + * @param scene the scene to set. + */ + public void setScene(SurokScene scene) { + this.scene = scene; + } + + /** + * The surok scene. + * @author Vexia + */ + public static enum SurokScene { + ESCAPE(-1, new int[] {}); + + /** + * The region id. + */ + private final int regionId; + + /** + * The start data. + */ + private final int[] startData; + + /** + * Constructs a new {@Code SurokScene} {@Code Object} + * @param regionId the region id. + * @param startData the start data. + */ + private SurokScene(int regionId, int[] startData) { + this.regionId = regionId; + this.startData = startData; + } + + /** + * Gets the regionId. + * @return the regionId + */ + public int getRegionId() { + return regionId; + } + + /** + * Gets the startData. + * @return the startData + */ + public int[] getStartData() { + return startData; + } + + } + + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/diary/RatBurgissDiaryDialogue.kt b/Server/src/main/content/region/misthalin/varrock/diary/RatBurgissDiaryDialogue.kt new file mode 100644 index 0000000..010a3fb --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/diary/RatBurgissDiaryDialogue.kt @@ -0,0 +1,86 @@ +package content.region.misthalin.varrock.diary + +import core.api.getAttribute +import core.api.setAttribute +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.dialogue.IfTopic +import core.game.dialogue.Topic +import core.game.node.entity.player.link.diary.AchievementDiary +import core.game.node.entity.player.link.diary.DiaryType +import core.tools.END_DIALOGUE + +class RatBurgissDiaryDialogue : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + val easyDiaryComplete = AchievementDiary.hasCompletedLevel(player, DiaryType.VARROCK, 0) + val alternateTeleport = getAttribute(player!!, "diaries:varrock:alttele", false) + when(stage) { + 0 -> { + if (AchievementDiary.canClaimLevelRewards(player, DiaryType.VARROCK, 0)) { + playerl(FacialExpression.FRIENDLY, "I think I've finished all of the tasks in my Varrock Achievement Diary.") + stage = 40 + return + } + else if (AchievementDiary.canReplaceReward(player, DiaryType.VARROCK, 0)) { + playerl(FacialExpression.ANNOYED, "I seem to have lost my armor.") + stage = 50 + return + } + + showTopics( + Topic("What is the Achievement Diary?", 10), + IfTopic("Can I change my Varrock Teleport point?", 100, easyDiaryComplete), + Topic("What are the rewards?", 20), + Topic("How do I claim the rewards?", 30), + Topic(FacialExpression.NEUTRAL, "See you later.", END_DIALOGUE) + ) + } + + 10 -> npcl(FacialExpression.FRIENDLY, "It's a diary that helps you keep track of particular achievements. Here in Varrock it can help you discover some quite useful things. Eventually, with enough exploration, the people of Varrock will reward").also { stage++ } + 11 -> npcl(FacialExpression.FRIENDLY, "you. You can see what tasks you have listed by clicking on the green button in the Quest List.").also { stage = 0 } + + 20 -> npcl(FacialExpression.FRIENDLY, "Well, there's three different levels of Varrock Armour, which match up with the three levels of difficulty. Each has the same rewards as the previous level, and an additional one too... but I").also { stage++ } + 21 -> npcl(FacialExpression.FRIENDLY, "won't spoil your surprise. Rest assured, the people of Varrock are happy to see you visiting the land.").also { stage = 0 } + + 30 -> npcl(FacialExpression.FRIENDLY, "Just complete the tasks so they're all ticked off, then you can claim your reward. Most of them are straightforward; you might find some require quests to be started, if not finished.").also { stage++ } + 31 -> npcl(FacialExpression.FRIENDLY, "To claim the different Varrock Armour, speak to Vannaka, Reldo, and myself.").also { stage = 0 } + + 40 -> npcl(FacialExpression.FRIENDLY, "You have? Excellent! Well done.").also { stage++ } + 41 -> playerl(FacialExpression.FRIENDLY, "Thank you. Uh... can I have the reward?").also { stage++ } + 42 -> npcl(FacialExpression.FRIENDLY, "Reward? Ah yes! Of course. Your reward, it's right here.").also { stage++ } + 43 -> { + AchievementDiary.flagRewarded(player, DiaryType.VARROCK, 0) + npcl(FacialExpression.FRIENDLY, "Now, this body armour is magically enhanced to help you with your Smithing and Mining. There is a furnace, not far from here, in Edgeville. Use this armour there and, when smelting ores up to and") + stage++ + } + 44 -> npcl(FacialExpression.FRIENDLY, "including steel, you will have a chance of making an extra bar every time. Also, when you mine with this armour on, you will have a chance of Mining extra ores from rocks up to and including coal.").also { stage++ } + 45 -> npcl(FacialExpression.FRIENDLY, "Bear in mind that you will need to be wearing the armour for either of these to work. I will speak to the shopkeepers around Varrock who sell armour and weapons to get you better prices when you are").also { stage++ } + 46 -> npcl(FacialExpression.FRIENDLY, "wearing it. I can also change your Varrock Teleport spell so that it takes you to the Grand Exchange, if you'd find that more convenient.").also { stage++ } + 47 -> npcl(FacialExpression.FRIENDLY, "As an extra reward, you can also have this old magical lamp to help you with your skills. I was going to use it myself, but I don't really need it.").also { stage++ } + 48 -> playerl(FacialExpression.FRIENDLY, "Wow, thanks!").also { stage++ } + 49 -> npcl(FacialExpression.FRIENDLY, "If you should lose this armour, come back and see me for another set.").also { stage = 0 } + + 50 -> { + AchievementDiary.grantReplacement(player, DiaryType.VARROCK, 0) + npcl(FacialExpression.ANNOYED, "You better be more careful this time.").also { stage = END_DIALOGUE } + } + + 100 -> showTopics( + IfTopic("I'd like to teleport to the Grand Exchange.", 101, easyDiaryComplete && !alternateTeleport), + IfTopic("I'd like to teleport to the city square.", 102, easyDiaryComplete && alternateTeleport), + Topic("Nevermind.", END_DIALOGUE) + ) + + 101 -> { + npcl(FacialExpression.FRIENDLY, "There you are, your Varrock teleport will now take you to the Grand Exchange.") + setAttribute(player!!, "/save:diaries:varrock:alttele", true) + stage = 0 + } + 102 -> { + npcl(FacialExpression.FRIENDLY, "There you are, your Varrock teleport will now take you to the city square.") + setAttribute(player!!, "/save:diaries:varrock:alttele", false) + stage = 0 + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/diary/VarrockAchivementDiary.kt b/Server/src/main/content/region/misthalin/varrock/diary/VarrockAchivementDiary.kt new file mode 100644 index 0000000..f498992 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/diary/VarrockAchivementDiary.kt @@ -0,0 +1,292 @@ +package content.region.misthalin.varrock.diary + +import content.global.skill.prayer.Bones +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.diary.DiaryType +import core.game.world.map.zone.ZoneBorders +import org.rs09.consts.Components +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery +import content.region.misthalin.varrock.dialogue.ElsieDialogue +import content.global.handlers.iface.FairyRing +import content.global.skill.magic.TeleportMethod +import content.global.travel.canoe.CanoeListener +import core.api.getStatLevel +import core.api.inBorders +import core.game.diary.AreaDiaryTask +import core.game.diary.DiaryEventHookBase +import core.game.diary.DiaryLevel +import core.game.event.* +import core.game.node.entity.player.link.SpellBookManager +import core.game.node.entity.skill.Skills +import content.data.Quests + +class VarrockAchivementDiary : DiaryEventHookBase(DiaryType.VARROCK) { + companion object { + private val VARROCK_ROOF_AREA = ZoneBorders(3201, 3467, 3225, 3497, 3) + private val SOS_LEVEL_2_AREA = ZoneBorders(2040, 5241, 2046, 5246) + private val VARROCK_PALACE = ZoneBorders(3201, 3456, 3227, 3468) + private val CHAMPIONS_GUILD = ZoneBorders(3188, 3361, 3194, 3362) + private val OZIACH_SHOP = ZoneBorders(3066, 3514,3070, 3518) + + private val STRAY_DOGS = arrayOf( + NPCs.STRAY_DOG_4766, NPCs.STRAY_DOG_4767, + NPCs.STRAY_DOG_5917, NPCs.STRAY_DOG_5918 + ) + + object EasyTasks { + const val THESSALIA_BROWSE_CLOTHES = 0 + const val AUBURY_TELEPORT_ESSENCE_MINE = 1 + const val MINE_IRON_SOUTHEAST = 2 + const val MAKE_PLANK_SAWMILL = 3 + const val VISIT_SOS_LEVEL2 = 4 + const val JUMP_OVER_FENCE_SOUTH = 5 + const val LUMBERYARD_CHOP_DYING_TREE = 6 + const val BUY_VARROCK_HERALD = 7 + const val GIVE_STRAY_DOG_A_BONE = 8 + const val BARBARIAN_VILLAGE_SPIN_A_BOWL = 9 + const val EDGEVILLE_ENTER_DUNGEON_SOUTH = 10 + const val MOVE_POH_TO_VARROCK = 11 + const val SPEAK_TO_HAIG_HALEN_50QP = 12 + const val ENTER_EARTH_ALTAR = 13 + const val ELSIE_TELL_A_STORY = 14 + const val PATERDOMUS_MINE_LIMESTONE = 15 + const val BARBARIAN_VILLAGE_CATCH_TROUT = 16 + const val SEWERS_CUT_COBWEB = 17 + const val FIND_HIGHEST_POINT = 18 + } + + object MediumTasks { + const val APOTHECARY_MAKE_STRENGTH_POTION = 0 + const val CHAMPIONS_GUILD_VISIT = 1 + const val TAKE_DAGONHAI_CHAOS_PORTAL_SHORTCUT = 2 + const val RAT_POLE_FULL_RAT_COMPLEMENT = 3 + const val SEWER_GATHER_RED_SPIDERS_EGGS = 4 + const val USE_SPIRIT_TREE_NORTH = 5 + const val PERFORM_ALL_SOS_EMOTES = 6 + const val SELECT_KITTEN_COLOR = 7 + const val USE_GE_UNDER_WALL_SHORTCUT = 8 + const val ENTER_SOULBANE_RIFT = 9 + const val DIGSITE_PENDANT_TELEPORT = 10 + const val CRAFT_EARTH_TIARA = 11 + const val PALACE_PICKPOCKET_GUARD = 12 + const val CAST_VARROCK_TELEPORT_SPELL = 13 + const val VANNAKA_GET_SLAYER_TASK = 14 + const val SAWMILL_BUY_20_MAHOGANY_PLANKS = 15 + const val PICK_FROM_WHITE_TREE = 16 + const val HOTAIR_BALLOON_TRAVEL_SOMEWHERE = 17 + const val GERTRUDE_GET_CAT_TRAINING_MEDAL = 18 + const val DIAL_FAIRY_RING_WEST = 19 + const val OZIACH_BROWSE_STORE = 20 + } + + object HardTasks { + const val PICK_POISON_IVY_FARMING_PATCH = 0 + const val USE_MOSS_GIANT_PIPE_SHORTCUT = 1 + const val FANCY_DRESS_SELLER_TRADE_FURS = 2 + const val SMITH_ADAMANT_MED_HELM_SOUTHEAST = 3 + const val SPEAK_TO_ORLANDO_SMITH_153_KUDOS = 4 + const val GIVE_WEAKLAX_A_PIE = 5 + const val CRAFT_AIR_BATTLESTAFF = 6 + const val GIVE_POH_TROPICAL_WOOD_OR_FANCY_STONE_FINISH = 7 + const val MAKE_VARROCK_TELEPORT_TABLET_OR_MAHOGANY_LECTERN = 8 + const val OBTAIN_NEW_SET_OF_FAMILY_CREST_GAUNTLETS = 9 + const val EDGEVILLE_MAKE_WAKA_CANOE = 10 + const val EDGEVILLE_TELEPORT_USING_ANCIENT_MAGICKS = 11 + const val BARBARIAN_VILLAGE_TELEPORT_USING_SKULL_SCEPTRE = 12 + } + } + + override val areaTasks get() = arrayOf( + AreaDiaryTask( + VARROCK_ROOF_AREA, + DiaryLevel.EASY, + EasyTasks.FIND_HIGHEST_POINT + ), + + AreaDiaryTask( + SOS_LEVEL_2_AREA, + DiaryLevel.EASY, + EasyTasks.VISIT_SOS_LEVEL2 + ), + + AreaDiaryTask( + CHAMPIONS_GUILD, + DiaryLevel.MEDIUM, + MediumTasks.CHAMPIONS_GUILD_VISIT + ) + ) + + override fun onResourceProduced(player: Player, event: ResourceProducedEvent) { + when (player.viewport.region.id) { + 12341 -> if (event.itemId == Items.RAW_TROUT_335) { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.BARBARIAN_VILLAGE_CATCH_TROUT + ) + } + + 13108 -> if (event.itemId == Items.IRON_ORE_440) { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.MINE_IRON_SOUTHEAST + ) + } + + 13110 -> { + if (event.itemId == Items.LOGS_1511 + && event.source.id == Scenery.DYING_TREE_24168 + ) { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.LUMBERYARD_CHOP_DYING_TREE + ) + } + } + + 13366 -> if (event.itemId == Items.LIMESTONE_3211) { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.PATERDOMUS_MINE_LIMESTONE + ) + } + } + } + + override fun onTeleported(player: Player, event: TeleportEvent) { + when (event.source) { + is NPC -> if (event.method == TeleportMethod.NPC && event.source.id == NPCs.AUBURY_553) { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.AUBURY_TELEPORT_ESSENCE_MINE + ) + } + } + } + + override fun onInteracted(player: Player, event: InteractionEvent) { + when (player.viewport.region.id) { + 12342 -> if (event.target.id == 26934) { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.EDGEVILLE_ENTER_DUNGEON_SOUTH + ) + } + 12598 -> if (event.target.id == 9312 && player.skills.getLevel(Skills.AGILITY, true) >= 21) { + finishTask( + player, + DiaryLevel.MEDIUM, + MediumTasks.USE_GE_UNDER_WALL_SHORTCUT + ) + } + 12698 -> if (event.target.id == 29370 && player.skills.getLevel(Skills.AGILITY, true) >= 51) { + finishTask( + player, + DiaryLevel.HARD, + HardTasks.USE_MOSS_GIANT_PIPE_SHORTCUT + ) + } + } + + if (event.option == "pickpocket" && (event.target.id == NPCs.GUARD_5920 && inBorders(player, VARROCK_PALACE) && getStatLevel(player, Skills.THIEVING) >= 40)) { + finishTask( + player, + DiaryLevel.MEDIUM, + MediumTasks.PALACE_PICKPOCKET_GUARD + ) + } + + if (player.questRepository.isComplete(Quests.DRAGON_SLAYER)) { + if (event.target.id == NPCs.OZIACH_747 && event.option == "trade" && inBorders(player, OZIACH_SHOP)) { + finishTask( + player, + DiaryLevel.MEDIUM, + MediumTasks.OZIACH_BROWSE_STORE + ) + } + } + } + + override fun onButtonClicked(player: Player, event: ButtonClickEvent) { + /* This gets fired even on the login screen, and we don't have a region there, so... */ + player.viewport.region?.let { + when (it.id) { + 12342 -> { + if (event.iface == CanoeListener.CANOE_SHAPING_INTERFACE + && event.buttonId == CanoeListener.CANOE_SHAPING_BUTTONS[CanoeListener.Companion.Canoes.WAKA.ordinal]) { + finishTask( + player, + DiaryLevel.HARD, + HardTasks.EDGEVILLE_MAKE_WAKA_CANOE + ) + } + } + } + } + } + + override fun onDialogueOptionSelected(player: Player, event: DialogueOptionSelectionEvent) { + when (event.dialogue) { + is ElsieDialogue -> if (event.currentStage == 12) { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.ELSIE_TELL_A_STORY + ) + } + } + } + + override fun onUsedWith(player: Player, event: UseWithEvent) { + when (event.used) { + in Bones.array -> if (event.with in STRAY_DOGS) { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.GIVE_STRAY_DOG_A_BONE + ) + } + } + } + + override fun onInterfaceOpened(player: Player, event: InterfaceOpenEvent) { + when (event.component.id) { + Components.THESSALIA_CLOTHES_MALE_591, + Components.THESSALIA_CLOTHES_FEMALE_594 -> { + finishTask( + player, + DiaryLevel.EASY, + EasyTasks.THESSALIA_BROWSE_CLOTHES + ) + } + } + } + + override fun onSpellCast(player: Player, event: SpellCastEvent) { + if (event.spellBook == SpellBookManager.SpellBook.MODERN && event.spellId == 15) { + finishTask( + player, + DiaryLevel.MEDIUM, + MediumTasks.CAST_VARROCK_TELEPORT_SPELL + ) + } + } + + override fun onFairyRingDialed(player: Player, event: FairyRingDialEvent) { + if (event.fairyRing == FairyRing.DKR) { + finishTask( + player, + DiaryLevel.MEDIUM, + MediumTasks.DIAL_FAIRY_RING_WEST + ) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/handlers/BennyNPC.kt b/Server/src/main/content/region/misthalin/varrock/handlers/BennyNPC.kt new file mode 100644 index 0000000..1e047b4 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/handlers/BennyNPC.kt @@ -0,0 +1,39 @@ +package content.region.misthalin.varrock.handlers + +import core.game.node.entity.npc.AbstractNPC +import core.game.world.map.Location +import core.plugin.Initializable +import core.tools.RandomFunction +import org.rs09.consts.NPCs + +@Initializable +class BennyNPC(id: Int = 0, location: Location? = null) : AbstractNPC(id, location) { + override fun construct(id: Int, location: Location?, vararg objects: Any?): AbstractNPC { + return BennyNPC(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.BENNY_5925) + } + + override fun handleTickActions() { + super.handleTickActions() + if (RandomFunction.roll(12)) { + core.api.sendChat(this, messages.random()) + } + } + + override fun getWalkRadius(): Int { + return 6 + } + + companion object { + private val messages = arrayOf( + "Read all about it!", + "Varrock Herald, on sale here!", + "Buy your Varrock Herald now!", + "Extra! Extra! Read all about it!", + "Varrock Herald, now only 50 gold!" + ) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/handlers/ChampionsGuildDoor.kt b/Server/src/main/content/region/misthalin/varrock/handlers/ChampionsGuildDoor.kt new file mode 100644 index 0000000..4d6187d --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/handlers/ChampionsGuildDoor.kt @@ -0,0 +1,32 @@ +package content.region.misthalin.varrock.handlers + +import core.plugin.Initializable +import org.rs09.consts.Scenery +import core.game.interaction.IntType +import core.game.interaction.InteractionListener + +/** + * Represents the plugin used to handle the interaction with the champions guild + * door. + * @author 'Vexia + * @author dginovker + * @version 2.0 + */ +@Initializable +class ChampionsGuildDoor : InteractionListener { + override fun defineListeners() { + on(Scenery.DOOR_1805, IntType.SCENERY, "open") { player, node -> + if (player.location.y > 3362 && player.questRepository.points < 32) { + player.dialogueInterpreter.open(70099, "You have not proved yourself worthy to enter here yet.") + player.packetDispatch.sendMessage("The door won't open - you need at least 32 Quest Points.") + } else { + if (player.location.x == 3191 && player.location.y == 3363) { + player.dialogueInterpreter.sendDialogues(198, null, "Greetings bold adventurer. Welcome to the guild of", "Champions.") + } + core.game.global.action.DoorActionHandler.handleAutowalkDoor(player, node as core.game.node.scenery.Scenery) + } + return@on true + } + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/handlers/ChefGuildDoorPlugin.java b/Server/src/main/content/region/misthalin/varrock/handlers/ChefGuildDoorPlugin.java new file mode 100644 index 0000000..4058a26 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/handlers/ChefGuildDoorPlugin.java @@ -0,0 +1,77 @@ +package content.region.misthalin.varrock.handlers; + +import core.cache.def.impl.SceneryDefinition; +import org.rs09.consts.Items; +import core.game.global.action.DoorActionHandler; +import core.game.node.item.Item; +import core.game.node.entity.skill.Skills; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the chef guild door plugin. + * + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class ChefGuildDoorPlugin extends OptionHandler { + private static final Item CHEFS_HAT = new Item(Items.CHEFS_HAT_1949); + private static final Item COOKING_CAPE = new Item(Items.COOKING_CAPE_9801); + private static final Item COOKING_CAPE_T = new Item(Items.COOKING_CAPET_9802); + private static final Item VARROCK_ARMOUR_3 = new Item(11758); + private static final Item[] ENTRANCE_ITEMS = {CHEFS_HAT, COOKING_CAPE, COOKING_CAPE_T, VARROCK_ARMOUR_3}; + private static final int CHEF_NPC = 847; + + @Override + public boolean handle(Player player, Node node, String option) { + final Scenery object = (Scenery) node; + switch (object.getId()) { + case 2712: // cooking guild front door + if (player.getSkills().getLevel(Skills.COOKING) < 32) { + if (!player.getEquipment().containsAtLeastOneItem(ENTRANCE_ITEMS)) { + player.getDialogueInterpreter().sendDialogues(CHEF_NPC, null, "Sorry. Only the finest chefs are allowed in here.", "Get your cooking level up to 32 and come back", "wearing a chef's hat."); + } else { + player.getDialogueInterpreter().sendDialogues(CHEF_NPC, null, "Sorry. Only the finest chefs are allowed in here.", "Get your cooking level up to 32."); + } + return true; + } else if (!player.getEquipment().containsAtLeastOneItem(ENTRANCE_ITEMS) && player.getLocation().getY() <= 3443) { + player.getDialogueInterpreter().sendDialogues(CHEF_NPC, null, "You can't come in here unless you're wearing a chef's", "hat or something like that."); + return true; + } else { + if (player.getEquipment().containsAtLeastOneItem(VARROCK_ARMOUR_3)) { + player.getDialogueInterpreter().sendDialogues(847, null, "My word! A master explorer of Varrock! Come in, come in! You are more than welcome in here, my friend!"); + } + DoorActionHandler.handleAutowalkDoor(player, object); + } + break; + case 26810: // cooking guild bank door + if (!player.getEquipment().containsAtLeastOneItem(VARROCK_ARMOUR_3) // player not wearing Varrock Armour 3 + && player.getLocation().getX() <= 3143) { // outside bank area + player.getDialogueInterpreter().sendDialogues(CHEF_NPC, null, "The bank's closed. You just can't get the staff these days."); + } else { + DoorActionHandler.handleAutowalkDoor(player, object); + } + break; + } + return true; + } + + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(2712).getHandlers().put("option:open", this); + SceneryDefinition.forId(26810).getHandlers().put("option:open", this); + return this; + } + + @Override + public Location getDestination(Node node, Node n) { + return DoorActionHandler.getDestination(((Player) node), ((Scenery) n)); + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/handlers/GECutscenePlugin.java b/Server/src/main/content/region/misthalin/varrock/handlers/GECutscenePlugin.java new file mode 100644 index 0000000..4630d1f --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/handlers/GECutscenePlugin.java @@ -0,0 +1,556 @@ +package content.region.misthalin.varrock.handlers; + +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.activity.ActivityManager; +import core.game.activity.ActivityPlugin; +import core.game.activity.CutscenePlugin; +import core.game.dialogue.DialoguePlugin; +import core.game.ge.GEGuidePrice; +import core.game.ge.GEGuidePrice.GuideType; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.net.packet.PacketRepository; +import core.net.packet.context.CameraContext; +import core.net.packet.context.CameraContext.CameraType; +import core.net.packet.out.CameraViewPacket; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the cutscene used for the grand exchange tutorial. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class GECutscenePlugin extends CutscenePlugin { + + /** + * Represents the main g.e interface. + */ + private static final Component MAIN_INTERFACE = new Component(106); + + /** + * Represents the config offer interface. + */ + private static final Component CONFIRM_INTERFACE = new Component(108); + + /** + * Represents the choose item interface. + */ + private static final Component CHOOSE_ITEM = new Component(110); + + /** + * Represents the hour glass interface. + */ + private static final Component HOUR_GLASS = new Component(646); + + /** + * Constructs a new {@code GECutscenePlugin} {@code Object}. + */ + public GECutscenePlugin() { + this(null); + } + + /** + * Constructs a new {@code GECutscenePlugin} {@code Object}. + * @param player the player. + */ + public GECutscenePlugin(final Player player) { + super("ge tutorial"); + this.player = player; + } + + @Override + public void open() { + player.setAttribute("ge-stage", 0); + player.setAttribute("ge-cutscene", this); + camera(3164, 3455, 0, 0, 800, 100); + player.lock(); + player.getDialogueInterpreter().sendDialogue(" - The Grand Exchange - "); + } + + @Override + public ActivityPlugin newInstance(Player p) throws Throwable { + return new GECutscenePlugin(p); + } + + @Override + public void register() { + new BrugsenBursenDialogue().init(); + try { + new TutorialInterfacePlugin().newInstance(null); + } catch (Throwable e) { + e.printStackTrace(); + } + } + + @Override + public Location getSpawnLocation() { + return null; + } + + @Override + public void configure() { + + } + + /** + * Method used to handle the camera. + * @param x the x offset. + * @param y the y offset. + * @param xRot the xRotation. + * @param yRot the yRotation. + * @Param height the height. + */ + private static void camera(final Player player, int x, int y, int xRot, int yRot, int height, int speed) { + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.POSITION, x, y, height, 1, speed)); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.ROTATION, x + xRot, y + yRot, height, 1, speed)); + } + + /** + * Method used to handle the camera. + * @param x the x pos. + * @param y the y pos. + * @param xRot the xRot. + * @param yRot the yRot. + * @param height the height. + * @param speed the speed. + */ + private final void camera(int x, int y, int xRot, int yRot, int height, int speed) { + camera(player, x, y, xRot, yRot, height, speed); + } + + /** + * Represents the brugsen bursen dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ + public static final class BrugsenBursenDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code BrugsenBursenDialogue} {@code Object}. + */ + public BrugsenBursenDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code BrugsenBursenDialogue} {@code Object}. + * @param player the player. + */ + public BrugsenBursenDialogue(final Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new BrugsenBursenDialogue(player); + } + + @Override + public boolean open(Object... args) { + if (!player.getSavedData().getGlobalData().isGeTutorial()) { + player("What is this place?"); + stage = 0; + } else { + npc("It's the young entrepreneur! How can I help you?"); + stage = 112; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + npc("Well, this is the fantastic Grand Exchange!"); + stage = 1; + break; + case 1: + npc("I am only too happy to help teach you everything you", "could possibly want to know. The Tutor nearby can", "give a brief introduction, too, but he's not as fun as me!"); + stage = 2; + break; + case 2: + options("I want to know everything from you!", "I'd rather speak to the Tutor and get a plain idea.", "I'm not interested in either!"); + stage = 3; + break; + case 3: + switch (buttonId) { + case 1: + player("I want to know everything from you!"); + stage = 10; + break; + case 2: + player("I'd rather speak to the Tutor and get a plain idea."); + stage = 20; + break; + case 3: + player("I'm not interested in either!"); + stage = 30; + break; + } + break; + case 10: + npc("Hahaha! Well, let's begin, my friend!"); + stage = 11; + break; + case 11: + close(); + ActivityManager.start(player, "ge tutorial", false); + stage = 100;// room for g.e cutscene + break; + case 20: + npc("Fine, have it your way."); + stage = 21; + break; + case 21: + end(); + break; + case 30: + npc("Okay, if you ever need help don't", "hesitated to ask me."); + stage = 31; + break; + case 31: + end(); + break; + case 100: + close(); + camera(player, 3149, 3470, 1, 1, 870, 10); + GameWorld.getPulser().submit(new Pulse(16, player) { + @Override + public boolean pulse() { + npc("Welcome, my friend to the Grand Exchange! From", "here you can simply tell us what you want to buy or", "sell and for how much, and we'll pair you up with", "another player and make the trade!"); + stage = 101; + return true; + } + }); + break; + case 101: + camera(player, 3172, 3465, -20, 210, 870, 20); + npc("Let me start by telling you how to buy and sell items.", "They are both quite similar, and can be explained in", "five simple steps."); + stage = 102; + break; + case 102: + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.RESET, 0, 0, 580, 1, 100)); + final CutscenePlugin cutscene = player.getAttribute("ge-cutscene", null); + cutscene.stop(false); + player.getSavedData().getGlobalData().setGeTutorial(true); + npc("Step 1: You decide what to buy or sell and come here", "with the items to sell or the money to buy with."); + stage = 103; + break; + case 103: + npc("Step 2: Speak with one of the clerks, behind the desk in", "the middle of the building and you'll place an offer as", "follows..."); + stage = 104; + break; + case 104: + close(); + player.getPacketDispatch().sendString("First! you all see a selection of boxes, each of which represent a possible offer you can place.", 106, 124); + player.getInterfaceManager().open(MAIN_INTERFACE); + for (int i = 0; i < 130; i++) { + player.getPacketDispatch().sendInterfaceConfig(106, i, false); + } + int[] childs = new int[] { 33, 56, 57, 64, 98, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29 }; + for (int i : childs) { + player.getPacketDispatch().sendInterfaceConfig(106, i, true); + } + stage = 105; + break; + case 105: + npc("Step 3: The clerks will have taken the items or money", "off you and will look for someone to complete the trade."); + stage = 106; + break; + case 106: + npc("Step 4: You then need to wait perhaps a matter of", "moments or maybe days until someone is looking for", "what you have offered."); + stage = 107; + break; + case 107: + close(); + player.getInterfaceManager().open(HOUR_GLASS); + stage = 108; + break; + case 108: + npc("To see costs of commonly traded items, you can talk to", "one of the characters around the outside of the building."); + stage = 109; + break; + case 109: + npc("Taking note of past successes and failures is important, ", "so the clerks will show you your previous buy and sell", "attempts on the Grand Exchange."); + stage = 110; + break; + case 110: + npc("There's a lot to learn, but you're now free to use the", "Grand Exchange. If you speak with me further I'm", "more than happy to repeat this tutorial and give more", "information."); + stage = 111; + break; + case 111: + npc("This extra information will be crucial if you wish to", "make the best deals!"); + stage = 112; + break; + case 112: + options("Can you teach me about the Grand Exchange again?", "Can you tell me more about how the system works?", "Can you tell me prices for common items, like....", "Where did the Grand Exchange come from?"); + stage = 113; + break; + case 113: + switch (buttonId) { + case 1: + player("Can you teach me about the Grand Exchange again?"); + stage = 210; + break; + case 2: + player("Can you tell me more about how the system works?"); + stage = 220; + break; + case 3: + player("Can you tell me prices for common items, like...."); + stage = 230; + break; + case 4: + player("Where did the Grand Exchange come from?"); + stage = 240; + break; + } + break; + case 210: + npc("Hahaha. It would be my absolute pleasure!"); + stage = 11; + break; + case 220: + npc("Oh, I simply love passing on knowledge. Okay, let me hit", "you with some facts..."); + stage = 221; + break; + case 221: + npc("The Grand Exchange calculated a guide price for each", "item that can be traded through it, based on the price", "people paid for that item over the previous days."); + stage = 222; + break; + case 222: + npc("An item just a suggestion value, you can", "offer any price you like when setting up your bids."); + stage = 223; + break; + case 223: + end(); + break; + case 230: + options("The price of ores.", "The price of runes.", "The price of logs.", "The price of herbs.", "The price of weapons and armour."); + stage = 231; + break; + case 231: + switch (buttonId) { + case 1: + player("The price of ores."); + stage = 310; + break; + case 2: + player("The price of runes."); + stage = 320; + break; + case 3: + player("The price of logs."); + stage = 330; + break; + case 4: + player("The price of herbs."); + stage = 340; + break; + case 5: + player("The price of weapons and armour."); + stage = 350; + break; + } + break; + case 310: + npc("By all means, but you can probably get at this", "information quicker by visiting Farid M."); + stage = 311; + break; + case 311: + end(); + GEGuidePrice.open(player, GuideType.ORES); + break; + case 320: + npc("My pleasure, but you can probably get this", "information quicker by visitng Murky Matt."); + stage = 321; + break; + case 321: + end(); + GEGuidePrice.open(player, GuideType.RUNES); + break; + case 330: + npc("Sure thing, but you can probably get this", "information quicker by visiting Relobo."); + stage = 331; + break; + case 331: + end(); + GEGuidePrice.open(player, GuideType.LOGS); + break; + case 340: + npc("Of course, but you can probably get at this", "information quicker by visiting Bob Barter."); + stage = 341; + break; + case 341: + end(); + GEGuidePrice.open(player, GuideType.HERBS); + break; + case 350: + npc("That's easy, but you can probably get at this", "information quicker by visiting Hofuthand."); + stage = 351; + break; + case 351: + end(); + GEGuidePrice.open(player, GuideType.WEAPONS_AND_ARMOUR); + break; + case 240: + npc("I'm glad you ask! I like telling this story. Are you sitting", "comfortably?"); + stage = 241; + break; + case 241: + player("Erm, I'll stand if that's okay."); + stage = 242; + break; + case 242: + npc("Fine. *Ahem* I shall tell you a story of hard work,", "dedication and success. I grew up here in Varrock", "at my parent's general store. I got a good feel for how", "the price of items would rise and fall depending on supply"); + stage = 243; + break; + case 243: + npc("and demand; I always found it interesting how", "items would go from one person to another, in this long", " chain of transactions."); + stage = 244; + break; + case 244: + player("So you lived here?"); + stage = 245; + break; + case 245: + npc("Oh, yes. I'd never consider leaving. Anyway, as I became", "an adult, I got to know other shop owners around Varrock", "along with the rich traders that would exchange vast", "quantities of items in one go."); + stage = 246; + break; + case 246: + player("How do you class a big quantity?"); + stage = 247; + break; + case 247: + npc("Well, the quantities are always increasing, I", "remember the day when you could buy some cooked shark", "for five coins!"); + stage = 248; + break; + case 248: + player("Impossible!"); + stage = 249; + break; + case 249: + npc("Nope. Straight up. Anyway. I organised a group of us to", "meet each week to see what deals could be made. It", "seemed to work so well and we developed a system that", "become so popular, that each meeting would a see a variety"); + stage = 250; + break; + case 250: + npc("of new people joining. I kept improving the system that", "I had created, but soon it became too big a thing to", "manage."); + stage = 251; + break; + case 251: + player("I can imagine!"); + stage = 252; + break; + case 252: + npc("So, in the end, I decided why not make this a " + GameWorld.getSettings().getName() + "-", "wide phenomenon? Make it public and allow anyone to join", "in. Up to this point, it catered for people buying and selling", "large quantities, but I knew it would work on a smaller"); + stage = 253; + break; + case 253: + npc("scale."); + stage = 254; + break; + case 254: + npc("And I was also in for a bit of luck. You see, one of the", "initial patrons had deep connections to the banks of", "" + GameWorld.getSettings().getName() + ". Together, I think you'll agree we have a most", "friendly system."); + stage = 255; + break; + case 255: + player("I feel quite exited now! I have a strange urge to shout", "'Buy, buy, sell, sell!'"); + stage = 256; + break; + case 256: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 6522 }; + } + + } + + /** + * Represents the interface plugin for the tutorial. + * @author 'Vexia + * @version 1.0 + */ + public final class TutorialInterfacePlugin extends ComponentPlugin { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + int[] ids = new int[] { 106, 108, 110, 646 }; + for (int id : ids) { + ComponentDefinition.forId(id).setPlugin(this); + } + return this; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + switch (component.getId()) { + case 106: + switch (button) { + case 145:// next + if (player.getAttribute("ge-stage", 0) == 0) { + player.getPacketDispatch().sendInterfaceConfig(106, 131, false); + player.getPacketDispatch().sendString("Upon clicking on one of the boxes you will see two buttons appear - one to make a buy offer and one to make a sell offer", 106, 124); + player.setAttribute("ge-stage", 1); + } else if (player.getAttribute("ge-stage", 0) == 4) { + player.setAttribute("ge-stage", 5); + player.getInterfaceManager().close(); + player.getDialogueInterpreter().sendDialogues(6522, null, "Sellig items is a very much similar process, just that", "you are picking an item you already have."); + } else { + player.getPacketDispatch().sendString("If you selected the buy option you would the see this screen. Here you define what you buy by clicking on the box with the magnifying glass and choosing an item.", 110, 89); + player.setAttribute("ge-stage", 2); + player.getInterfaceManager().open(CHOOSE_ITEM); + } + break; + } + break; + case 108: + player.setAttribute("ge-stage", 4); + player.getInterfaceManager().open(MAIN_INTERFACE); + for (int i = 0; i < 130; i++) { + player.getPacketDispatch().sendInterfaceConfig(106, i, false); + } + int[] childs = new int[] { 33, 56, 57, 64, 98, 131 }; + for (int i : childs) { + player.getPacketDispatch().sendInterfaceConfig(106, i, true); + } + player.getPacketDispatch().sendString("Now the offer is placed! You can click on this anytime you want to see the details of your offer. The progress is shown with a progress bar underndeath", 106, 124); + break; + case 110: + switch (button) { + case 92: + player.setAttribute("ge-stage", 3); + player.getInterfaceManager().open(CONFIRM_INTERFACE); + player.getPacketDispatch().sendString("In this example we have selected a staff of air. You can then define the quantity and cost before selecting the Confirm Offer button", 108, 94); + break; + } + break; + case 646: + switch (button) { + case 13: + player.getInterfaceManager().close(); + player.setAttribute("ge-stage", 5); + player.getDialogueInterpreter().sendDialogues(6522, null, "Step 5: When the trade is complete, we will let you", "know with a message and you can pick up your", "winnings by talking to the clerks or by visiting any", "banker in " + GameWorld.getSettings().getName() + "."); + break; + } + break; + } + return true; + } + + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/handlers/GrandExchangePlugin.java b/Server/src/main/content/region/misthalin/varrock/handlers/GrandExchangePlugin.java new file mode 100644 index 0000000..a4be167 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/handlers/GrandExchangePlugin.java @@ -0,0 +1,164 @@ +package content.region.misthalin.varrock.handlers; + +import core.cache.def.impl.NPCDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.plugin.Initializable; +import core.game.ge.GEGuidePrice; +import core.game.ge.GEGuidePrice.GuideType; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.plugin.Plugin; +import core.game.ge.GrandExchangeRecords; +import content.global.handlers.iface.ge.ExchangeItemSets; +import content.global.handlers.iface.ge.StockMarket; + +/** + * Represents the plugin used for grand exchange npc and object options. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class GrandExchangePlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(28089).getHandlers().put("option:use", this); + SceneryDefinition.forId(28089).getHandlers().put("option:exchange", this); + SceneryDefinition.forId(28089).getHandlers().put("option:collect", this); + SceneryDefinition.forId(28089).getHandlers().put("option:history", this); + SceneryDefinition.forId(28089).getHandlers().put("option:sets", this); + for (int i : new int[] { 6528, 6529, 6530, 6531 }) { + NPCDefinition.forId(i).getHandlers().put("option:exchange", this); + NPCDefinition.forId(i).getHandlers().put("option:history", this); + NPCDefinition.forId(i).getHandlers().put("option:sets", this); + } + NPCDefinition.forId(6527).getHandlers().put("option:info-combat", this); + NPCDefinition.forId(6526).getHandlers().put("option:info-logs", this); + NPCDefinition.forId(6525).getHandlers().put("option:info-runes", this); + NPCDefinition.forId(6524).getHandlers().put("option:info-herbs", this); + NPCDefinition.forId(6523).getHandlers().put("option:info-ores", this); + new GENPCPlugin().newInstance(arg); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + GrandExchangeRecords records = GrandExchangeRecords.getInstance(player); + if (player.getIronmanManager().checkRestriction() && !option.equals("sets")) { + return true; + } + switch (option) { + case "use": + player.getDialogueInterpreter().open(6528, NPC.create(6528, player.getLocation())); + break; + case "exchange": + StockMarket.openFor(player); + break; + case "history": + records.openHistoryLog(player); + break; + case "collect": + records.openCollectionBox(); + break; + case "info-logs": + GEGuidePrice.open(player, GuideType.LOGS); + break; + case "info-ores": + GEGuidePrice.open(player, GuideType.ORES); + break; + case "info-herbs": + GEGuidePrice.open(player, GuideType.HERBS); + break; + case "info-runes": + GEGuidePrice.open(player, GuideType.RUNES); + break; + case "info-combat": + GEGuidePrice.open(player, GuideType.WEAPONS_AND_ARMOUR); + break; + case "sets": + ExchangeItemSets.openFor(player); + break; + } + return true; + } + + @Override + public Location getDestination(Node node, Node n) { + if (n instanceof NPC) { + switch (n.getDirection()) { + case EAST: + return n.getLocation().transform(-1, 0, 0); + case NORTH: + return n.getLocation().transform(0, 1, 0); + case SOUTH: + return n.getLocation().transform(0, -1, 0); + case WEST: + return n.getLocation().transform(1, 0, 0); + default: + break; + } + } + return node.getLocation().getDistance(n.getLocation()) < 2 ? node.getLocation() : null; + } + + /** + * Represents a g.e npc option handler. + * @author 'Vexia + * @version 1.0 + */ + public final class GENPCPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + NPCDefinition.forId(6528).getHandlers().put("option:talk-to", this); + NPCDefinition.forId(6529).getHandlers().put("option:talk-to", this); + NPCDefinition.forId(6535).getHandlers().put("option:talk-to", this); + NPCDefinition.forId(6533).getHandlers().put("option:talk-to", this); + NPCDefinition.forId(6535).getHandlers().put("option:bank", this); + NPCDefinition.forId(6533).getHandlers().put("option:collect", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + switch (option) { + case "talk-to": + final NPC npc = (NPC) node; + return player.getDialogueInterpreter().open(npc.getId(), npc); + case "bank": + player.getBank().open(); + break; + case "collect": + GrandExchangeRecords.getInstance(player).openCollectionBox(); + break; + } + return true; + } + + @Override + public Location getDestination(Node node, Node n) { + if (node instanceof Player) { + Player player = (Player) node; + if (player.getZoneMonitor().isInZone("Donator Zone")) { + return null; + } + } + switch (n.getDirection()) { + case EAST: + return n.getLocation().transform(1, 0, 0); + case NORTH: + return n.getLocation().transform(0, 1, 0); + case SOUTH: + return n.getLocation().transform(0, -1, 0); + case WEST: + return n.getLocation().transform(-1, 0, 0); + default: + break; + } + return null; + } + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/handlers/GrandExchangeShortcut.kt b/Server/src/main/content/region/misthalin/varrock/handlers/GrandExchangeShortcut.kt new file mode 100644 index 0000000..4599453 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/handlers/GrandExchangeShortcut.kt @@ -0,0 +1,104 @@ +package content.region.misthalin.varrock.handlers + +import core.api.* +import core.game.node.entity.impl.ForceMovement +import core.game.node.entity.impl.ForceMovement.direction +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.scenery.Scenery +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.plugin.Initializable +import core.game.interaction.IntType +import core.game.interaction.InteractionListener + +/** + * Handles the grand exchange shortcut. + * @author Emperor + * @author dginovker + * @version 2.0 + */ +@Initializable +class GrandExchangeShortcut : InteractionListener { + companion object { + /** + * The shortcut configs + */ + val SHORTCUTS = mapOf( + 9311 to listOf( + Location.create(3138, 3516, 0), // Run to loc + Location.create(3143, 3514, 0), // Crawl through tele loc + Location.create(3144, 3514, 0), // End loc + ), + 9312 to listOf( + Location.create(3144, 3514, 0), // Run to loc + Location.create(3139, 3516, 0), // Crawl through tele loc + Location.create(3138, 3516, 0), // End loc + ) + ) + /** + * The climbing down animation. + */ + private val CLIMB_DOWN = Animation.create(2589) + + /** + * The crawling through animation. + */ + private val CRAWL_THROUGH = Animation.create(2590) + + /** + * The climbing up animation. + */ + private val CLIMB_UP = Animation.create(2591) + } + + override fun defineListeners() { + on(SHORTCUTS.keys.toIntArray(), IntType.SCENERY, "climb-into") { player, node -> + if (!hasLevelDyn(player, Skills.AGILITY, 21)) { + sendDialogue(player, "You need an Agility level of at least 21 to do this.") + return@on true + } + lock(player, 4) + val o = node as Scenery + val path = SHORTCUTS[o.id]!! + ForceMovement.run(player, path[0], o.location, ForceMovement.WALK_ANIMATION, CLIMB_DOWN, direction(path[0], o.location), ForceMovement.WALKING_SPEED, ForceMovement.WALKING_SPEED, false) + runCrawlPulse(player, path) + return@on true + } + } + + private fun runCrawlPulse(player: Player, path: List) { + submitIndividualPulse(player, object : Pulse(1, player) { + var count = 0 + var reachedStart = false + override fun pulse(): Boolean { + // If the player hasn't reached path[0], don't do anything + if (!reachedStart && player.location != path[0]) { + return false + } + reachedStart = true + + when (++count) { + 2 -> { + teleport(player, path[1]) + visualize(player, CRAWL_THROUGH, -1) + } + + 3 -> { + ForceMovement.run( + player, + path[1], + path[2], + CLIMB_UP + ) + unlock(player) + return true + } + } + return false + } + }) + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/handlers/LumberYardCratePlugin.java b/Server/src/main/content/region/misthalin/varrock/handlers/LumberYardCratePlugin.java new file mode 100644 index 0000000..277d7d6 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/handlers/LumberYardCratePlugin.java @@ -0,0 +1,85 @@ +package content.region.misthalin.varrock.handlers; + +import core.cache.def.impl.NPCDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.impl.ForceMovement; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.tools.RandomFunction; +import content.data.Quests; + +/** + * Represents the plugin used for handling a lumber yard crate. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class LumberYardCratePlugin extends OptionHandler { + + /** + * Represents the kittem item. + */ + private static final Item KITTEN = new Item(13236); + + @Override + public boolean handle(Player player, Node node, String option) { + final Quest quest = player.getQuestRepository().getQuest(Quests.GERTRUDES_CAT); + switch (option) { + case "squeeze-under": + Location dest = null; + Location start = node.getLocation(); + if (player.getLocation().getX() > node.getLocation().getX()) { + start = Location.create(3296, 3498, 0); + dest = Location.create(3295, 3498, 0); + } else { + dest = Location.create(3296, 3498, 0); + } + ForceMovement.run(player, start, dest, Animation.create(9221)); + break; + case "search": + if (quest.getStage(player) == 50 && !player.getInventory().containsItem(KITTEN) && !player.getBank().containsItem(KITTEN)) { + quest.setStage(player, 40); + } + if (node instanceof NPC) { + player.getPacketDispatch().sendMessage("You search the crate."); + player.getPacketDispatch().sendMessage("You find nothing."); + } + if (quest.getStage(player) == 40) { + if (player.getAttribute("findkitten", false) && player.getInventory().freeSlots() > 0) { + quest.setStage(player, 50); + player.getDialogueInterpreter().sendDialogue("You find a kitten! You carefully place it in your backpack."); + player.getInventory().add(KITTEN); + return true; + } + player.getPacketDispatch().sendMessage("You search the crate."); + player.getPacketDispatch().sendMessage("You find nothing."); + if (RandomFunction.random(0, 3) == 1) { + player.getPacketDispatch().sendMessage("You can hear kittens mewing close by..."); + player.setAttribute("findkitten", true); + } + } else { + player.getPacketDispatch().sendMessage("You search the crate."); + player.getPacketDispatch().sendMessage("You find nothing."); + } + break; + } + return true; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + NPCDefinition.forId(767).getHandlers().put("option:search", this); + SceneryDefinition.forId(2620).getHandlers().put("option:search", this); + SceneryDefinition.forId(31149).getHandlers().put("option:squeeze-under", this); + return null; + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/handlers/MuseumInteractionListener.kt b/Server/src/main/content/region/misthalin/varrock/handlers/MuseumInteractionListener.kt new file mode 100644 index 0000000..f72eed5 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/handlers/MuseumInteractionListener.kt @@ -0,0 +1,125 @@ +package content.region.misthalin.varrock.handlers + +import core.api.* +import core.game.global.action.DoorActionHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Components +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +class MuseumInteractionListener : InteractionListener { + override fun defineListeners() { + // Basement Stairs + addClimbDest(Location(3255, 3451, 0), Location(1759, 4958, 0)) + addClimbDest(Location(1758, 4959, 0), Location(3258, 3452, 0)) + + on(mapObject, IntType.SCENERY, "look-at", "take") { player, node -> + if (getUsedOption(player) == "take") { + if (!addItem(player, Items.MUSEUM_MAP_11184)) { + sendMessage(player, "You don't have enough space in your inventory.") + } + } else { + when (node.id) { + Scenery.MAP_24390 -> setAttribute(player, "iface:527:floor", "main") + Scenery.MAP_24391 -> setAttribute(player, "iface:527:floor", "second") + Scenery.MAP_24392 -> setAttribute(player, "iface:527:floor", "top") + } + openInterface(player, Components.VM_MUSEUM_MAP_527) + } + return@on true + } + + on(Items.MUSEUM_MAP_11184, IntType.ITEM, "look-at") { player, node -> + openInterface(player, Components.VM_MUSEUM_MAP_527) + return@on true + } + + on(Scenery.INFORMATION_BOOTH_24452, IntType.SCENERY, "look-at") { player, node -> + // TODO: I cannot find anything that shows what this does in 2009. + sendMessage(player, "Nothing interesting happens.") + return@on true + } + + on(doorsToDigsite, IntType.SCENERY, "open") { player, node -> + if (node.id == Scenery.GATE_24536) { + if (player.location.y <= 3446) { + handleMuseumDoor(player, node.asScenery()) + } else { + openDialogue(player, NPCs.MUSEUM_GUARD_5941) + } + return@on true + } else { + if (player.location.y >= 3442) { + handleMuseumDoor(player, node.asScenery()) + } else { + openDialogue(player, NPCs.MUSEUM_GUARD_5943) + } + } + return@on true + } + + on(Scenery.TOOLS_24535, IntType.SCENERY, "take") { player, node -> + sendDialogueOptions( + player, + "Which tool would you like?", + "Trowel", + "Rock pick", + "Specimen brush", + "Leather gloves", + "Leather boots" + ) + addDialogueAction(player) { _, button -> + val item = when (button) { + 2 -> Items.TROWEL_676 + 3 -> Items.ROCK_PICK_675 + 4 -> Items.SPECIMEN_BRUSH_670 + 5 -> Items.LEATHER_GLOVES_1059 + 6 -> Items.LEATHER_BOOTS_1061 + else -> return@addDialogueAction + } + val name = item.asItem().name.lowercase() + val word = if (name.startsWith("leather")) "pair of " else "" + + if (!addItem(player, item)) { + sendMessage(player, "You don't have enough space in your inventory.") + } else { + sendItemDialogue(player, item, "You take a $word$name from the rack.") + } + } + return@on true + } + + on(naturalHistoryPlaques, IntType.SCENERY, "study") { player, node -> + openInterface(player, 533) + return@on true + } + } + + companion object { + private val doorsToDigsite = intArrayOf(Scenery.GATE_24536, Scenery.DOOR_24565, Scenery.DOOR_24567) + private val mapObject = intArrayOf(Scenery.MAP_24390, Scenery.MAP_24391, Scenery.MAP_24392) + private val naturalHistoryPlaques = intArrayOf( + Scenery.PLAQUE_24605, Scenery.PLAQUE_24606, Scenery.PLAQUE_24607, Scenery.PLAQUE_24608, + Scenery.PLAQUE_24609, Scenery.PLAQUE_24610, Scenery.PLAQUE_24611, Scenery.PLAQUE_24612, + Scenery.PLAQUE_24613, Scenery.PLAQUE_24614, Scenery.PLAQUE_24615, Scenery.PLAQUE_24616, + Scenery.PLAQUE_24617, Scenery.PLAQUE_24618 + ) + + fun handleMuseumDoor(player: Player, door: core.game.node.scenery.Scenery?) { + val npc = if (door?.id == Scenery.GATE_24536) findLocalNPC(player, NPCs.MUSEUM_GUARD_5941) else findLocalNPC(player, NPCs.MUSEUM_GUARD_5943) + val animation = if (DoorActionHandler.getEndLocation(player, door).y > player.location.y) Animation(6391) else Animation(6392) + + if (npc != null) { + animate(npc, animation) + queueScript(player, animationDuration(animation)) { DoorActionHandler.handleAutowalkDoor(player, door) } + } else { + DoorActionHandler.handleAutowalkDoor(player, door) + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/handlers/MuseumInterfaceListener.kt b/Server/src/main/content/region/misthalin/varrock/handlers/MuseumInterfaceListener.kt new file mode 100644 index 0000000..e31f4ce --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/handlers/MuseumInterfaceListener.kt @@ -0,0 +1,91 @@ +package content.region.misthalin.varrock.handlers + +import core.api.* +import core.game.interaction.InterfaceListener +import core.game.node.entity.player.Player +import org.rs09.consts.Components +import org.rs09.consts.NPCs +import org.rs09.consts.Sounds + +class MuseumInterfaceListener : InterfaceListener { + override fun defineInterfaceListeners() { + onOpen(Components.VM_MUSEUM_MAP_527) { player, _ -> + showMapFloor(player, getAttribute(player, "iface:527:floor", "main")) + removeAttribute(player, "iface:527:floor") + return@onOpen true + } + + on(Components.VM_MUSEUM_MAP_527) { player, _, _, buttonID, _, _ -> + showMapFloor(player, when (buttonID) { + in mapButtonsToBasement -> "basement" + in mapButtonsToMainFloor -> "main" + in mapButtonsToSecondFloor -> "second" + in mapButtonsToTopFloor -> "top" + else -> return@on true + }) + return@on true + } + + onOpen(NATURAL_HISTORY_EXAM_533) { player, component -> + // The model for each display is confusing as hell. Some are objects and some are NPCs. + val model = getScenery(1763, 4937, 0)?.definition?.modelIds?.first() + player.packetDispatch.sendModelOnInterface(model!!, component.id, 3, 0) + + // Showing this child makes child 28 - 31 visible. + setComponentVisibility(player, component.id, 27, false) + + // The case number to display. + setInterfaceText(player, "1", component.id, 25) + + // The question text. + setInterfaceText(player, "When will the Natural History Quiz be implemented?", component.id, 28) + + // The choices. + setInterfaceText(player, "Never.", component.id, 29) + setInterfaceText(player, "In 2 days.", component.id, 30) + setInterfaceText(player, "After Barbarian Assault.", component.id, 31) + return@onOpen true + } + + on(NATURAL_HISTORY_EXAM_533) { player, component, opcode, buttonID, slot, itemID -> + if (buttonID in 29..31) { + closeInterface(player) + setVarbit(player, 3637, 1, false) + playAudio(player, Sounds.VM_GAIN_KUDOS_3653) + sendNPCDialogue(player, NPCs.ORLANDO_SMITH_5965, "Nice job, mate. That looks about right.") + } + return@on true + } + } + companion object { + private const val NATURAL_HISTORY_EXAM_533 = 533 + + private val mapButtonsToBasement = intArrayOf(41, 186) + private val mapButtonsToMainFloor = intArrayOf(117, 120, 187, 188) + private val mapButtonsToSecondFloor = intArrayOf(42, 44, 152, 153) + private val mapButtonsToTopFloor = intArrayOf(42, 44, 118, 119) + + private fun showMapFloor(player: Player, floor: String) { + when (floor) { + "basement" -> { + setComponentVisibility(player, Components.VM_MUSEUM_MAP_527, 2, true) + setComponentVisibility(player, Components.VM_MUSEUM_MAP_527, 7, false) + } + "main" -> { + setComponentVisibility(player, Components.VM_MUSEUM_MAP_527, 3, true) + setComponentVisibility(player, Components.VM_MUSEUM_MAP_527, 7, true) + setComponentVisibility(player, Components.VM_MUSEUM_MAP_527, 2, false) + } + "second" -> { + setComponentVisibility(player, Components.VM_MUSEUM_MAP_527, 2, true) + setComponentVisibility(player, Components.VM_MUSEUM_MAP_527, 5, true) + setComponentVisibility(player, Components.VM_MUSEUM_MAP_527, 3, false) + } + "top" -> { + setComponentVisibility(player, Components.VM_MUSEUM_MAP_527, 3, true) + setComponentVisibility(player, Components.VM_MUSEUM_MAP_527, 5, false) + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/handlers/MuseumMapArea.kt b/Server/src/main/content/region/misthalin/varrock/handlers/MuseumMapArea.kt new file mode 100644 index 0000000..cdb5dcb --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/handlers/MuseumMapArea.kt @@ -0,0 +1,29 @@ +package content.region.misthalin.varrock.handlers + +import core.api.MapArea +import core.api.closeOverlay +import core.api.openOverlay +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.world.map.zone.ZoneBorders +import org.rs09.consts.Components + +class MuseumMapArea : MapArea { + override fun defineAreaBorders(): Array { + val vmArea = ZoneBorders(3253, 3442, 3267, 3455) + val vmBasementArea = ZoneBorders(1730, 4932, 1788, 4988) + return arrayOf(vmArea, vmBasementArea) + } + + override fun areaEnter(entity: Entity) { + if (entity is Player) { + openOverlay(entity.asPlayer(), Components.VM_KUDOS_532) + } + } + + override fun areaLeave(entity: Entity, logout: Boolean) { + if (entity is Player) { + closeOverlay(entity.asPlayer()) + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/handlers/RedberryBushPlugin.java b/Server/src/main/content/region/misthalin/varrock/handlers/RedberryBushPlugin.java new file mode 100644 index 0000000..af25650 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/handlers/RedberryBushPlugin.java @@ -0,0 +1,66 @@ +package content.region.misthalin.varrock.handlers; + +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the plugin used to handle picking from a red berry bush. + * @author 'Vexia + */ +@Initializable +public class RedberryBushPlugin extends OptionHandler { + + /** + * Represents the red berries item. + */ + private final Item RED_BERRIES = new Item(1951); + + /** + * Represents the picking berries animation. + */ + private final Animation ANIMATION = new Animation(2282); + + /** + * Represents the counter. + */ + private int counter = 0; + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(23628).getHandlers().put("option:pick-from", this); + SceneryDefinition.forId(23629).getHandlers().put("option:pick-from", this); + SceneryDefinition.forId(23630).getHandlers().put("option:pick-from", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + if (((Scenery) node).getId() == 23630) { + player.getPacketDispatch().sendMessage("There are no berries left on this bush."); + player.getPacketDispatch().sendMessage("More berries will grow soon."); + return true; + } + if (!player.getInventory().add(RED_BERRIES)) { + player.getPacketDispatch().sendMessage("Your inventory is too full to pick the berries from the bush."); + return true; + } + player.lock(4); + player.animate(ANIMATION); + if (counter == 2) { + SceneryBuilder.replace(((Scenery) node), new Scenery(23630, node.getLocation()), 30); + counter = 0; + return true; + } + counter++; + return true; + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/handlers/SawmillListener.kt b/Server/src/main/content/region/misthalin/varrock/handlers/SawmillListener.kt new file mode 100644 index 0000000..7d7f2ee --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/handlers/SawmillListener.kt @@ -0,0 +1,31 @@ +package content.region.misthalin.varrock.handlers + +import core.game.component.Component +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.world.map.Location +import org.rs09.consts.NPCs + +class SawmillListener : InteractionListener { + override fun defineListeners() { + on(NPCs.SAWMILL_OPERATOR_4250, IntType.NPC, "talk-to") { player, node -> + player.dialogueInterpreter.open(4250, node) + return@on true + } + + on(NPCs.SAWMILL_OPERATOR_4250, IntType.NPC, "buy-plank") { player, _ -> + player.interfaceManager.open( Component(403)) + return@on true + } + + on(NPCs.SAWMILL_OPERATOR_4250, IntType.NPC, "trade") { player, node -> + node.asNpc().openShop(player) + return@on true + } + + setDest(IntType.NPC, intArrayOf(NPCs.SAWMILL_OPERATOR_4250), "talk-to", "buy-plank", "trade") { _, _ -> + return@setDest Location.create(3302, 3491 , 0) + } + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/handlers/ShooAwayStrayDogPlugin.java b/Server/src/main/content/region/misthalin/varrock/handlers/ShooAwayStrayDogPlugin.java new file mode 100644 index 0000000..d21dee8 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/handlers/ShooAwayStrayDogPlugin.java @@ -0,0 +1,43 @@ +package content.region.misthalin.varrock.handlers; + +import core.cache.def.impl.NPCDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the option plugin used to shoo away a dog. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class ShooAwayStrayDogPlugin extends OptionHandler { + + /** + * Represents the animatio to use. + */ + private static final Animation ANIMATION = new Animation(2110); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + NPCDefinition.forId(5917).getHandlers().put("option:shoo-away", this); + NPCDefinition.setOptionHandler("shoo-away", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + player.sendChat("Thbbbbt!"); + player.animate(ANIMATION); + NPC dog = (NPC) node; + dog.sendChat("Whine!"); + dog.moveStep(); + dog.getPulseManager().clear(); + return true; + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/handlers/StrayDogNPC.java b/Server/src/main/content/region/misthalin/varrock/handlers/StrayDogNPC.java new file mode 100644 index 0000000..e2ce086 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/handlers/StrayDogNPC.java @@ -0,0 +1,123 @@ +package content.region.misthalin.varrock.handlers; + +import java.util.ArrayList; +import java.util.List; + +import core.game.interaction.DestinationFlag; +import core.game.interaction.MovementPulse; +import core.game.node.entity.impl.PulseType; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.map.path.Pathfinder; +import core.game.world.map.zone.impl.BankZone; +import core.plugin.Initializable; +import core.tools.RandomFunction; + +/** + * Handles the temple guardian npc. + * @author 'Vexia + */ +@Initializable +public class StrayDogNPC extends AbstractNPC { + + /** + * The NPC ids of NPCs using this plugin. + */ + private static final int[] ID = { 5918, 5917 }; + + /** + * Represents the target player. + */ + private Player target; + + /** + * Represents the delay. + */ + private long delay; + + /** + * Represents the array list of players. + */ + private List players = new ArrayList<>(20); + + /** + * Constructs a new {@code AlKharidWarriorPlugin} {@code Object}. + */ + public StrayDogNPC() { + super(0, null, true); + } + + /** + * Constructs a new {@code AlKharidWarriorPlugin} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + private StrayDogNPC(int id, Location location) { + super(id, location, true); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new StrayDogNPC(id, location); + } + + @Override + public void tick() { + super.tick(); + if (delay < System.currentTimeMillis() && RandomFunction.random(1, 16) == 2) { + getPulseManager().clear(); + target = null; + players = RegionManager.getLocalPlayers(this, 7); + if (players.size() != 0) { + target = players.get(RandomFunction.random(players.size())); + getPulseManager().run(getFollowPulse(target), PulseType.STANDARD); + delay = System.currentTimeMillis() + 150000; + } + } + if (target != null && target.getZoneMonitor().isInZone("bank")) { + Pathfinder.find(this, getProperties().getSpawnLocation()).walk(this); + getPulseManager().clear(); + target = null; + delay = System.currentTimeMillis() + 150000; + } + } + + @Override + public Location getMovementDestination() { + return super.getMovementDestination(); + } + + @Override + public boolean canMove(Location l) { + if (BankZone.VARROCK_EAST.insideBorder(l) || BankZone.VARROCK_WEST.insideBorder(l)) { + return false; + } + return true; + } + + @Override + public int[] getIds() { + return ID; + } + + /** + * Gets the following pulse. + * @param target the target. + * @return the movement pulse. + */ + public MovementPulse getFollowPulse(final Player target) { + return new MovementPulse(this, target, DestinationFlag.FOLLOW_ENTITY) { + @Override + public boolean pulse() { + return false; + } + }; + } + + @Override + public int getWalkRadius() { + return 17; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/handlers/ThessaliaPlugin.java b/Server/src/main/content/region/misthalin/varrock/handlers/ThessaliaPlugin.java new file mode 100644 index 0000000..3ef52ee --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/handlers/ThessaliaPlugin.java @@ -0,0 +1,28 @@ +package content.region.misthalin.varrock.handlers; + +import core.cache.def.impl.NPCDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * @author 'Vexia. + */ +@Initializable +public class ThessaliaPlugin extends OptionHandler { + + @Override + public boolean handle(Player player, Node node, String option) { + player.getDialogueInterpreter().open(548, true, true, true); + return true; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + NPCDefinition.forId(548).getHandlers().put("option:change-clothes", this); + return this; + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/handlers/VarrockCensusInterface.kt b/Server/src/main/content/region/misthalin/varrock/handlers/VarrockCensusInterface.kt new file mode 100644 index 0000000..6cb95f0 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/handlers/VarrockCensusInterface.kt @@ -0,0 +1,27 @@ +package content.region.misthalin.varrock.handlers + +import core.api.getVarbit +import core.api.setVarbit +import core.game.interaction.InterfaceListener + +class VarrockCensusInterface : InterfaceListener { + override fun defineInterfaceListeners() { + on(INTERFACE_ID) { player, _, _, buttonID, _, _ -> + when (buttonID) { + 2 -> setVarbit(player, VARBIT_ID, getVarbit(player, VARBIT_ID).plus(1)) + 3 -> setVarbit(player, VARBIT_ID, getVarbit(player, VARBIT_ID).minus(1)) + else -> return@on true + } + return@on true + } + + onClose(INTERFACE_ID) { player, _ -> + setVarbit(player, VARBIT_ID, 0) + return@onClose true + } + } + companion object { + const val INTERFACE_ID = 794 + const val VARBIT_ID = 5390 + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/handlers/VarrockGuardSignpost.kt b/Server/src/main/content/region/misthalin/varrock/handlers/VarrockGuardSignpost.kt new file mode 100644 index 0000000..29a4526 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/handlers/VarrockGuardSignpost.kt @@ -0,0 +1,43 @@ +package content.region.misthalin.varrock.handlers + +import core.GlobalStats +import core.api.log +import core.api.registerMapZone +import core.api.sendDialogue +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.interaction.Option +import core.game.node.Node +import core.game.node.entity.Entity +import core.game.world.map.zone.MapZone +import core.game.world.map.zone.ZoneBorders +import core.tools.Log + +class VarrockGuardSignpost : InteractionListener { + override fun defineListeners() { + val zone = object : MapZone("Varrock Guards", true){ + override fun interact(e: Entity?, target: Node?, option: Option?): Boolean { + if(option != null && option.name.toLowerCase().contains("pickpocket") && target != null && target.name.toLowerCase().contains("guard")){ + GlobalStats.incrementGuardPickpockets() + } + return false + } + } + + registerMapZone(zone, ZoneBorders(3225,3445,3198,3471)) + registerMapZone(zone, ZoneBorders(3222,3375,3199,3387)) + registerMapZone(zone, ZoneBorders(3180,3420,3165,3435)) + registerMapZone(zone, ZoneBorders(3280,3422,3266,3435)) + + on(31298, IntType.SCENERY, "read"){ player, _ -> + val pickpocketCount = GlobalStats.getDailyGuardPickpockets() + log(this::class.java, Log.FINE, "Is equal? ${pickpocketCount == 0}") + when(pickpocketCount){ + 0 -> sendDialogue(player, "The Varrock Palace guards are pleased to announce that crime is at an all-time low, without a single guard in the palace or at the city gates being pickpocketed today.") + 1 -> sendDialogue(player, "One of the Varrock Palace guards was pickpocketed today. He was close to tears at having lost his last few gold pieces." ) + else -> sendDialogue(player, "Guards in the Varrock Palace are on full alert due to increasing levels of pickpocketing. So far today, $pickpocketCount guards have had their money pickpocketed in the palace or at the city gates.") + } + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/handlers/VarrockInteractionListener.kt b/Server/src/main/content/region/misthalin/varrock/handlers/VarrockInteractionListener.kt new file mode 100644 index 0000000..1610daf --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/handlers/VarrockInteractionListener.kt @@ -0,0 +1,91 @@ +package content.region.misthalin.varrock.handlers + +import content.region.misthalin.varrock.dialogue.KnockAtBankDoor +import core.api.* +import core.game.global.action.DoorActionHandler +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.world.map.Location +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery +import org.rs09.consts.Sounds + +class VarrockInteractionListener : InteractionListener { + override fun defineListeners() { + // Varrock Sewer Manhole + on(VARROCK_MANHOLE, IntType.SCENERY, "open", "close") { player, node -> + if (getUsedOption(player) == "open") { + playAudio(player, Sounds.MANHOLE_OPEN_75) + replaceScenery(node.asScenery(), Scenery.VARROCK_MANHOLE_OPEN_882, 100) + } else { + playAudio(player, Sounds.MANHOLE_CLOSE_74) + replaceScenery(node.asScenery(), Scenery.VARROCK_MANHOLE_CLOSED_881, -1) + } + return@on true + } + + // Phoenix Gang Hideout Plaque + on(Scenery.PLAQUE_23636, IntType.SCENERY, "read") { player, _ -> + openInterface(player, VTAM_IFACE) + return@on true + } + + // Varrock Census in the palace Library + on(Scenery.VARROCK_CENSUS_37209, IntType.SCENERY, "read") { player, _ -> + sendPlayerDialogue(player, "Hmm. The Varrock Census - year 160. That means it's nine years out of date.") + addDialogueAction(player) { _, buttonID -> + if (buttonID == 6) { + openInterface(player, VARROCK_CENSUS_IFACE) + } + } + return@on true + } + + // Broken Cart next to Rat Burgiss + on(Scenery.BROKEN_CART_23055, IntType.SCENERY, "search") { player, node -> + sendDialogue(player, "You search the cart but are surprised to find very little there. " + + "It's a little odd for a travelling trader not to have anything to trade.") + return@on true + } + + on(openOptionNodes, IntType.SCENERY, "open") { player, node -> + when (node.id) { + // Guidor's Bedroom Door + Scenery.BEDROOM_DOOR_2032 -> { + openDialogue(player, NPCs.GUIDORS_WIFE_342, true, true) + } + + // Guidor's Drawers + Scenery.DRAWERS_17466 -> { + sendMessage(player, "The drawers are locked shut.") + } + + // Brass Key Door to Edgeville Dungeon + Scenery.DOOR_1804 -> { + if (inInventory(player, Items.BRASS_KEY_983)) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else { + sendMessage(player, "This door is locked.") + } + } + } + return@on true + } + + // Varrock West Bank Door + on(Scenery.DOOR_24389, IntType.SCENERY, "knock-at") { player, node -> + openDialogue(player, KnockAtBankDoor()) + return@on true + } + + // TODO: Cooking Guild + // TODO: Fix Achievements + } + companion object { + private val VARROCK_MANHOLE = intArrayOf(Scenery.VARROCK_MANHOLE_CLOSED_881, Scenery.VARROCK_MANHOLE_OPEN_882) + private val openOptionNodes = intArrayOf(Scenery.BEDROOM_DOOR_2032, Scenery.DRAWERS_17466, Scenery.DOOR_1804) + private const val VTAM_IFACE = 531 + private const val VARROCK_CENSUS_IFACE = 794 + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/handlers/ZaffPlugin.kt b/Server/src/main/content/region/misthalin/varrock/handlers/ZaffPlugin.kt new file mode 100644 index 0000000..1af2980 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/handlers/ZaffPlugin.kt @@ -0,0 +1,453 @@ +package content.region.misthalin.varrock.handlers + +import core.api.Container +import core.api.* +import core.api.InputType +import core.cache.def.impl.NPCDefinition +import core.plugin.Initializable +import core.game.interaction.OptionHandler +import core.plugin.Plugin +import core.game.node.entity.player.link.quest.Quest +import core.game.node.Node +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.diary.DiaryType +import core.game.node.item.Item +import org.json.simple.JSONObject +import org.rs09.consts.Items +import core.ServerStore +import core.ServerStore.Companion.getInt +import content.data.Quests + +/** + * Represents the plugin used for buying a battle staff from zeke. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +class ZaffPlugin : OptionHandler() { + @Throws(Throwable::class) + override fun newInstance(arg: Any?): Plugin { + NPCDefinition.setOptionHandler("buy-battlestaves", this) + ZaffDialogue().init() + ZaffStaveDialogue().init() + return this + } + + override fun handle(player: Player, node: Node, option: String): Boolean { + player.dialogueInterpreter.open(9679) + return true + } + + /** + * Represents the dialogue plugin used for the zaff npc. + * @author 'Vexia + * @version 1.0 + */ + class ZaffDialogue : core.game.dialogue.DialoguePlugin { + /** + * The quest. + */ + private var quest: Quest? = null + + /** + * Constructs a new `ZaffDialogue` `Object`. + */ + constructor() { + /** + * empty. + */ + } + + /** + * Constructs a new `ZaffDialogue` `Object`. + * @param player the player. + */ + constructor(player: Player?) : super(player) {} + + override fun newInstance(player: Player?): core.game.dialogue.DialoguePlugin { + return ZaffDialogue(player) + } + + override fun open(vararg args: Any): Boolean { + npc = args[0] as NPC + quest = player.questRepository.getQuest(Quests.WHAT_LIES_BELOW) + interpreter.sendDialogues( + npc, + core.game.dialogue.FacialExpression.HALF_GUILTY, + "Would you like to buy or sell some staves or is there", + "something else you need?" + ) + stage = 0 + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> { + if (quest!!.getStage(player) == 60) { + interpreter.sendOptions( + "Select an Option", + "Yes, please.", + "No, thank you.", + "Rat Burgiss sent me." + ) + stage = 1 + } else if (quest!!.getStage(player) == 80) { + interpreter.sendOptions( + "Select an Option", + "Yes, please.", + "No, thank you.", + "We did it! We beat Surok!" + ) + stage = 1 + } else if (quest!!.getStage(player) >= 70) { + interpreter.sendOptions( + "Select an Option", + "Yes, please.", + "No, thank you.", + "Can I have another ring?" + ) + stage = 1 + } else { + interpreter.sendOptions("Select an Option", "Yes, please.", "No, thank you.") + stage = 1 + } + } + 1 -> when (buttonId) { + 1 -> { + interpreter.sendDialogues(player, core.game.dialogue.FacialExpression.HALF_GUILTY, "Yes, please.") + stage = 10 + } + 2 -> { + interpreter.sendDialogues(player, core.game.dialogue.FacialExpression.HALF_GUILTY, "No, thank you.") + stage = 20 + } + 3 -> { + if (quest!!.getStage(player) == 60) { + player("Rat Burgiss sent me!") + stage = 70 + } else if (quest!!.getStage(player) == 80) { + player("We did it! We beat Surok!") + stage = 200 + } else { + interpreter.sendDialogues(player, core.game.dialogue.FacialExpression.HALF_GUILTY, "Can I have another ring?") + stage = 50 + } + } + } + 10 -> { + if(player.achievementDiaryManager.getDiary(DiaryType.VARROCK).levelRewarded.contains(true)){ + npcl(core.game.dialogue.FacialExpression.FRIENDLY, "Would you like to hear about my battlestaves?") + stage = 1000 + } else { + end() + npc.openShop(player) + } + } + 20 -> { + interpreter.sendDialogues( + npc, + core.game.dialogue.FacialExpression.HALF_GUILTY, + "Well, 'stick' your head in again if you change your mind." + ) + stage = 21 + } + 21 -> { + interpreter.sendDialogues( + player, + core.game.dialogue.FacialExpression.HALF_GUILTY, + "Huh, terrible pun. You just can't get the 'staff' these", + "days!" + ) + stage = 22 + } + 22 -> end() + 50 -> { + if (player.inventory.contains(11014, 1)) interpreter.sendDialogues( + npc, + core.game.dialogue.FacialExpression.HALF_GUILTY, + "Go and get the one that's in your inventory " + player.username + "!" + ) else if (player.bank.contains(11014, 1)) interpreter.sendDialogues( + npc, + core.game.dialogue.FacialExpression.HALF_GUILTY, + "Go and get the one that's in your bank" + player.username + "!" + ) else if (player.equipment.contains(11014, 1)) interpreter.sendDialogues( + npc, + core.game.dialogue.FacialExpression.HALF_GUILTY, + "Go and get the one that's on your finger " + player.username + "!" + ) else { + interpreter.sendDialogues( + npc, + core.game.dialogue.FacialExpression.HALF_GUILTY, + "Of course you can! Here you go " + player.username + "!" + ) + player.inventory.add(BEACON_RING) + } + stage = 51 + } + 51 -> end() + 70 -> { + npc( + "Ah, yes; You must be " + player.username + "! Rat sent word that you", + "would be coming. Everything is prepared. I have created", + "a spell that will remove the mind control spell." + ) + stage++ + } + 71 -> { + player("Okay, what's the plan?") + stage++ + } + 72 -> { + npc( + "Listen carefully. For the spell to succeed, the king must", + "be made very weak, if his mind is controlled, you will", + "need to fight him until he is all but dead." + ) + stage++ + } + 73 -> { + npc( + "Then and ONLY then, use your ring to summon me.", + "I will teleport to you and cast the spell that will", + "cure the king." + ) + stage++ + } + 74 -> { + player("Why must I summon you? Can't you come with me?") + stage++ + } + 75 -> { + npc( + "I cannot. I must look after my shop here and", + "I have lots to do. Rest assured, I will come when you", + "summon me." + ) + stage++ + } + 76 -> { + player("Okay, so what do I do now?") + stage++ + } + 77 -> { + npc("Take this beacon ring and some instructions.") + stage++ + } + 78 -> { + npc("Once you have read the instructions. It will be time for", "you to arrest Surok.") + stage++ + } + 79 -> { + player("Won't he be disinclined to acquiesce to that request?") + stage++ + } + 80 -> { + npc("Won't he what?") + stage++ + } + 81 -> { + player("Won't he refuse?") + stage++ + } + 82 -> { + npc( + "I very much expect so. It may turn nasty, so be on your", + "guard. I hope we can stop him before he can cast his", + "spell!", + "Make sure you have that ring I gave you." + ) + stage++ + } + 83 -> { + player("Okay, thanks, Zaff!") + stage++ + } + 84 -> { + player.inventory.add(BEACON_RING) + quest!!.setStage(player, 70) + end() + } + 200 -> { + npc("Yes. You have done well, " + player.username + ". You are to be", "commended for you actions!") + stage++ + } + 201 -> { + player("It was all in the call of duty!") + stage++ + } + 202 -> { + player("What will happen with Surok now?") + stage++ + } + 203 -> { + npc( + "Well, when I disrupted Surok's spell, he will have been", + "sealed in the library, but we still need to keep an", + "eye on him, just in case." + ) + stage++ + } + 204 -> { + npc("When you are ready, report back to Rat and he will", "reward you.") + stage++ + } + 205 -> { + player("Okay, I will.") + stage++ + } + 206 -> { + quest!!.setStage(player, 90) + end() + } + + 1000 -> options("Yes, please.", "No, thanks.").also { stage++ } + 1001 -> when(buttonId){ + 1 -> { + end() + openDialogue(player, 9679, npc) + } + 2 -> { + end() + npc.openShop(player) + } + } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(546) + } + + companion object { + /** + * Represents the staff item. + */ + private val STAFF = Item(11014, 1) + } + } + + /** + * Represents the dialogue used to buy staves from zaff. + * @author 'Vexia + * @version 1.0 + */ + inner class ZaffStaveDialogue : core.game.dialogue.DialoguePlugin { + /** + * The ammount of battlestaves. + */ + private var ammount = 0 + + /** + * Constructs a new `ZaffBuyStavesDialogue` `Object`. + */ + constructor() { + /** + * empty. + */ + } + + /** + * Constructs a new `ZaffBuyStavesDialogue` `Object`. + * @param player the player. + */ + constructor(player: Player?) : super(player) {} + + override fun newInstance(player: Player?): core.game.dialogue.DialoguePlugin { + return ZaffStaveDialogue(player) + } + + override fun open(vararg args: Any): Boolean { + ammount = getStoreFile().getInt(player.username.toLowerCase()) + interpreter.sendDialogues(player, core.game.dialogue.FacialExpression.HALF_GUILTY, "Do you have any battlestaves?") + stage = 0 + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> { + if (ammount >= maxStaffs) { + interpreter.sendDialogues( + 546, + core.game.dialogue.FacialExpression.HALF_GUILTY, + "I'm very sorry! I seem to be out of battlestaves at the", + "moment! I expect I'll get some more in by tomorrow,", + "though." + ) + stage = 2 + return true + } + interpreter.sendDialogues( + 546, + core.game.dialogue.FacialExpression.HALF_GUILTY, + "Battlestaves cost 7,000 gold pieces each. I have ${maxStaffs - ammount} left.", + "How many would you like to buy?" + ) + stage = 1 + } + 1 -> end().also { sendInputDialogue(player, InputType.AMOUNT, "Enter an amount:"){ value -> + ammount = getStoreFile().getInt(player.username.toLowerCase()) + var amt = value as Int + if(amt > maxStaffs - ammount) amt = maxStaffs - ammount + val coinage = amt * 7000 + if(!inInventory(player, Items.COINS_995, coinage)){ + sendDialogue(player, "You can't afford that many.") + return@sendInputDialogue + } + + if(amt == 0){ + return@sendInputDialogue + } + + if(removeItem(player, Item(Items.COINS_995, coinage), Container.INVENTORY)){ + addItem(player, Items.BATTLESTAFF_1392, amt) + getStoreFile()[player.username.toLowerCase()] = amt + ammount + } + } } + 2 -> { + interpreter.sendDialogues( + player, + core.game.dialogue.FacialExpression.HALF_GUILTY, + "Oh, okay then. I'll try again another time." + ) + stage = 3 + } + 3 -> end() + } + return true + } + + /** + * Gets the max staffs to buy. + * @return the max staffs to buy. + */ + val maxStaffs: Int + get() { + val level = player.achievementDiaryManager.getDiary(DiaryType.VARROCK).level + return when (level) { + 2 -> 64 + 1 -> 32 + 0 -> 16 + else -> 8 + } + } + + override fun getIds(): IntArray { + return intArrayOf(9679) + } + } + + companion object { + /** + * The bacon ring. + */ + val BEACON_RING = Item(11014) + + fun getStoreFile(): JSONObject { + return ServerStore.getArchive("daily-zaff") + } + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/allfiredup/AllFiredUp.kt b/Server/src/main/content/region/misthalin/varrock/quest/allfiredup/AllFiredUp.kt new file mode 100644 index 0000000..29f8580 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/allfiredup/AllFiredUp.kt @@ -0,0 +1,162 @@ +package content.region.misthalin.varrock.quest.allfiredup + +import content.data.Quests +import content.minigame.allfiredup.AFUBeacon +import core.api.setVarbit +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.plugin.Initializable +import org.rs09.consts.Items + +/** + * Represents the "All Fired Up" quest. + * @author Ceikry + */ +@Initializable +class AllFiredUp : Quest(Quests.ALL_FIRED_UP, 157, 156, 1){ + override fun newInstance(`object`: Any?): Quest { + return this + } + + override fun drawJournal(player: Player?, stage: Int) { + super.drawJournal(player, stage) + var line = 11 + player ?: return + if (stage == 0) { + line(player, "I can start this quest by speaking to !!King Roald?? in !!Varrock??", line++) + line(player, "!!Palace??.", line++) + line++ + line(player, "To start this quest, I require:", line++) + line(player, "!!43 Firemaking??", line++, player.skills.getLevel(Skills.FIREMAKING) >= 43) + line(player, "!!Completion of Priest in Peril??", line++, player.questRepository.isComplete(Quests.PRIEST_IN_PERIL)) + limitScrolling(player, line, true) + } else { + line(player, "I have agreed to help King Roald test the beacon network", line++, true) + line(player, "that he hopes will serve as an early warning system,", line++, true) + line(player, "should Misthalin and Asgarnia come under attack from", line++, true) + line(player, "Morytania or the Wilderness.", line++, true) + + if (stage > 10) { + line(player, "I've spoken with the head fire-tender, Blaze Sharpeye", line++, true) + line(player, "who is stationed near the Temple of Paterdomus, at the", line++, true) + line(player, "source of the River Salve.", line++, true) + } else if (stage == 10) { + line(player, "!!King Roald?? asked me to talk to the head fire-tender !!Blaze??", line++, false) + line(player, "!!Sharpeye?? who is stationed near the !!Temple of??", line++, false) + line(player, "!!Paterdomus??, at the source of the !!River Salve??.", line++, false) + } + + if (stage > 20) { + // Replaced with stage 30 text. + } else if (stage == 20) { + line(player, "!!Blaze?? has asked me to light the nearby !!beacon??.", line++, false) + line(player, "To light the !!beacon??, I need to add !!twenty logs?? of the same", line++, false) + line(player, "type and then light the fire with a !!tinderbox??.", line++, false) + } + + if (stage > 30) { + line(player, "I've lit the beacon near Blaze by loading it with twenty logs", line++, true) + line(player, "and lighting them with a tinderbox.", line++, true) + } else if (stage == 30) { + line(player, "!!Blaze?? has asked me to light the nearby !!beacon??.", line++, false) + line(player, "I've placed !!twenty logs?? on the !!beacon?? and lit the fire with", line++, false) + line(player, "my !!tinderbox??. Now that it's blazing brightly, perhaps I", line++, false) + line(player, "should speak with !!Blaze??.", line++, false) + } + + if (stage > 40) { + // Replaced with stage 50 text. + } else if (stage == 40) { + line(player, "!!Blaze?? has now asked me to light the !!beacon?? tended by", line++, false) + line(player, "!!Squire Fyre??, which is located just west of the !!Rag and??", line++, false) + line(player, "!!Bone Man??'s hovel.", line++, false) + line(player, "I need permission from !!Squire Fyre?? to light the !!beacon??", line++, false) + } + + if (stage > 50) { + // Replaced with stage 60 text. + } else if (stage == 50) { + line(player, "!!Blaze?? has now asked me to light the !!beacon?? tended by", line++, false) + line(player, "!!Squire Fyre??, which is located just west of the !!Rag and??", line++, false) + line(player, "!!Bone Man??'s hovel.", line++, false) + line(player, "To light the !!beacon??, I need to add !!twenty logs?? of the same", line++, false) + line(player, "type and then light the fire with a !!tinderbox??.", line++, false) + } + + if (stage > 60) { + line(player, "Blaze has now asked me to light the beacon tended by", line++, true) + line(player, "Squire Fyre, near the Rag and Bone Man's hovel. I've", line++, true) + line(player, "loaded it with logs and set it alight; it's now blazing", line++, true) + line(player, "brightly.", line++, true) + } else if (stage == 60) { + line(player, "!!Blaze?? has now asked me to light the !!beacon?? tended by", line++, false) + line(player, "!!Squire Fyre??, which is located just west of the !!Rag and??", line++, false) + line(player, "!!Bone Man??'s hovel.", line++, false) + line(player, "I've placed twenty logs on the !!beacon?? and lit the fire with", line++, false) + line(player, "my tinderbox. Now that it's blazing brightly, perhaps I", line++, false) + line(player, "should speak with Blaze.", line++, false) + } + + if (stage > 70) { + // Replaced with stage 80 text. + } else if (stage == 70) { + line(player, "!!Blaze?? has now asked me to maintain the nearby !!beacon??.", line++, false) + line(player, "To maintain the !!beacon??, I need to add !!five logs?? of the same", line++, false) + line(player, "type.", line++, false) + } + + if (stage > 80) { + line(player, "Blaze has explained how to maintain a beacon. When the", line++, true) + line(player, "fire begins to die out, five more logs can be added to", line++, true) + line(player, "restore a beacon to its blazing state. I've tended the", line++, true) + line(player, "beacon near Blaze and have reported back to him.", line++, true) + } else if (stage == 80) { + line(player, "!!Blaze?? has explained how to maintain a beacon. When the", line++, false) + line(player, "fire begins to die out, !!five more logs?? can be added to", line++, false) + line(player, "restore a beacon to its blazing state.", line++, false) + line(player, "!!Blaze?? has asked me to maintain the !!beacon?? nearest him.", line++, false) + } + + if (stage > 90) { + // Replaced with stage 100 complete text. + } else if (stage == 90){ + line(player, "I need to talk to !!King Roald?? in !!Varrock Palace?? to claim my", line++, false) + line(player, "reward.", line++, false) + } + + if (stage == 100) { + line(player, "I spoke to King Roald who thanked me for helping and", line++, true) + line(player, "rewarded me with 20,000gp and 5,500 Firemaking XP. He", line++, true) + line(player, "told me that if I'm able to light six, ten and all fourteen", line++, true) + line(player, "fires simultaneously, he'll have further rewards for me.", line++, true) + line++ + line++ + line(player,"QUEST COMPLETE!", line) + } + limitScrolling(player, line, false) + } + } + + override fun finish(player: Player?) { + super.finish(player) + player ?: return + player.packetDispatch.sendString("20,000gp,", 277, 8 + 2) + player.packetDispatch.sendString("5,500 Firemaking XP", 277, 9 + 2) + player.packetDispatch.sendString("Full access to the beacon network", 277, 10 + 2) + player.packetDispatch.sendString("1 Quest Point", 277, 11 + 2) + player.packetDispatch.sendItemZoomOnInterface(Items.TINDERBOX_590, 235, 277, 3 + 2) + player.skills.addExperience(Skills.FIREMAKING, 5500.0) + player.inventory.add(Item(995,20000)) + AFUBeacon.resetAllBeacons(player) + setVarbit(player, 1283, 0) + player.questRepository.syncronizeTab(player) + } + + override fun getConfig(player: Player?, stage: Int): IntArray { + if(stage == 100) return intArrayOf(1282, 90) + if(stage > 0) return intArrayOf(1282, 1) + else return intArrayOf(1282, 0) + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/allfiredup/BlazeSharpeyeDialogue.kt b/Server/src/main/content/region/misthalin/varrock/quest/allfiredup/BlazeSharpeyeDialogue.kt new file mode 100644 index 0000000..9f85e66 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/allfiredup/BlazeSharpeyeDialogue.kt @@ -0,0 +1,110 @@ +package content.region.misthalin.varrock.quest.allfiredup + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import content.data.Quests + +@Initializable +class BlazeSharpeyeDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player?): DialoguePlugin { + return BlazeSharpeyeDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = (args[0] as NPC).getShownNPC(player) + val qstage = player?.questRepository?.getStage(Quests.ALL_FIRED_UP) ?: -1 + when(qstage){ + 0 -> player.dialogueInterpreter.sendDialogue("He seems uninterested in talking.").also { stage = 1000 } + 10 -> player("So, what's going on?").also { stage = 100 } + 20 -> npc("Well, go on, light the fire, then.").also { stage = 1000 } + 30 -> npc("Ah, I see you've managed to successfully light the","beacon and have mastered our super-secret beacon","lighting technique. Well done!").also { stage = 200 } + 40,50 -> npc("Please go and light the other beacon.").also { stage = 116 } + 60 -> npc("Ah, ${player.username}, you're back! Great news - I can see","you've managed to light the beacon over yonder. Many","thanks!").also { stage = 300 } + 70 -> npc("Well, GO ON, BURN IT!!!").also { stage = 1000 } + 80 -> player("I've added some logs to the beacon; it's now blazing","away.").also { stage = 400 } + 90 -> npc("Go talk to King Roald!").also { stage = 1000 } + else -> npc("Ah yes, hello adventurer!").also { stage = 600 } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + //Stage = 10 + 100 -> npc("Well, King Roald has commissioned these lovely beacons","to serve as an early warning system. We'll be able to","see their huge, majestic flames from great distances.").also { stage++ } + 101 -> npc("There are 14 beacons in total, spanning the south","and west borders of the Wilderness.").also { stage++ } + 102 -> player("It sounds like you've already got everything figured","out. How do I fit into this?").also { stage++ } + 103 -> npc("Well, to test these beacons, we need someone to light a","couple of them for us, so that we can determine","whether or not they'll actually be visible.").also { stage++ } + 104 -> player("You mean, you went out and built these huge things","without knowing that they'd work?").also { stage++ } + 105 -> npc("Don't interrupt. Now, yours truly has recruited some","of the sharpest eyes this side of the River Salve to look","after these beacons and to watch the horizon for signs","of danger.").also { stage++ } + 106 -> npc("In case of emergency, we've all got a supply of logs","and can start a fire faster than a cat can sneeze.").also { stage++ } + 107 -> npc("As soon as we spot a threat from the Wilderness or the","glow from another beacon, we can light our own","beacons and send a warning right across Misthalin,","faster than any courier could ever run.").also { stage++ } + 108 -> npc("We've agreed to use gnomish firelighters to colour the","flames of our beacons' fires in an actual emergency, so","it's safe to test the network with normal fires.").also { stage++ } + 109 -> player("So, what do you want me to actually do?").also { stage++ } + 110 -> npc("I need you to light a couple of beacons for me to make","sure we can see the glow from the flames over the","horizon.").also { stage++ } + 111 -> npc("So! First of all, you'll need to know how to light a beacon.").also { stage++ } + 112 -> npc("Our technique is super-secret, but quite effective. All","you do is put twenty logs of the same type on a","beacon and...").also { stage++ } + 113 -> npc(FacialExpression.AMAZED,"SET IT ON FIRE WITH A TINDERBOX!").also { stage++ } + 114 -> player("You really enjoy your job, don't you?").also { stage++ } + 115 -> npc("Yes. Yes I do. Now, why don't you go over there and","try lighting that beacon. Show us what you've got.").also { stage++; player.questRepository.getQuest(Quests.ALL_FIRED_UP).setStage(player,20) } + 116 -> options("Does it matter what type of log I use?","Okay.").also { stage++ } + 117 -> when(buttonId){ + 1 -> player("Does it matter what type of log I use?").also { stage = 150 } + 2 -> player("Okay.").also { stage = 1000 } + } + 150 -> npc("Normal, Oak, Willow, Maple, Yew and Magic.").also { stage = 1000 } + + //Stage = 30 + 200 -> player("Well, it's not like it was all that complicated.").also { stage++ } + 201 -> npc("Well, apparently, not for someone of your Firemaking","calibre and expertise. Now that you've got the hang of","things, we can get this show on the road.").also { stage++ } + 202 -> npc("If you'd be so kind as to light the beacon to the west","and report back to me, I can make sure I can clearly","see its glow on the horizon.").also { stage++ } + 203 -> npc("It's near the limestone quarry, north-east of Varrock,","west of the Rag and Bone Man's hovel.").also { stage++ } + 204 -> npc("My colleague, Squire Fyre, is tending that beacon.","She'll help you out if you run into any trouble.").also { stage = 116; player.questRepository.getQuest(Quests.ALL_FIRED_UP).setStage(player,40) } + + //Stage = 60 + 300 -> player("Can you really see it from this far away?").also { stage++ } + 301 -> npc("Absolutely! I can see a warm, delicious glow on the","horizon. If you have sharp eyes and know what to look","for it's trivial.").also { stage++ } + 302 -> npc("This beacon, however, is struggling at the moment.","Do you see how the fire has died down?").also { stage++ } + 303 -> player("Hmm, yes. The fire is a bit smaller and the logs look","rather charred.").also { stage++ } + 304 -> npc("If a beacon's fire starts to die down, you can restore it","to its blazing glory by adding five logs.").also { stage++ } + 305 -> npc("You wouldn't mind topping this one up for me, would","you? Oh, how I love to see things burn!").also { stage++; player.questRepository.getQuest(Quests.ALL_FIRED_UP).setStage(player, 70) } + 306 -> options("Oh, alright, then.","Don't you have logs of your own you can use?").also { stage++ } + 307 -> when(buttonId){ + 1 -> player("Oh, alright, then.").also { stage++ } + 2 -> player("Don't you have logs of your own that you","can use?").also { stage = 310 } + } + 308 -> npc("MORE FIRE for ME!!!").also { stage++ } + 309 -> player("Backing away now...").also { stage = 1000 } + 310 -> npc("Nope.").also { stage = 1000 } + + + //Stage = 80 + 400 -> npc("Beautiful...mesmerising...").also { stage++ } + 401 -> player("Uh...Blaze?").also { stage++ } + 402 -> npc("Ah, yes, it's you again. Brilliant work; an incandescent","effort.").also { stage++ } + 403 -> player("So, what now?").also { stage++ } + 404 -> npc("We're all pretty pleased with the results of the trial run","and are gearing up for more serious testing. There's a","lot at stake, so we'll need to test out the entire network","as soon as possible.").also { stage++ } + 405 -> options("When's all this to take place?","More serious testing?").also { stage++ } + 406 -> when(buttonId){ + 1 -> player("When's all this taking place?").also { stage = 410 } + 2 -> player("More serious testing?").also { stage = 420 } + } + 410 -> npc("Imminently, I'm sure - we're just waiting for the word","from King Roald. Speaking of which, have you reported","back to him about the progress we've made?").also { stage++ } + 411 -> player("Not yet, I'm afraid.").also { stage++ } + 412 -> npc("Well, what are you waiting for? This is a serious","matter! I'm sure King Roald is on the edge of his","throne, waiting for the news.").also { stage++ } + 413 -> player("I'll get right on that.").also { stage = 1000; player.questRepository.getQuest(Quests.ALL_FIRED_UP).setStage(player,90) } + 420 -> npc("Yes... YES HAHAHAHA FIRE").also { stage = 412 } + + 1000 -> end() + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(8065) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/quest/allfiredup/KingRoaldAFUDialogue.kt b/Server/src/main/content/region/misthalin/varrock/quest/allfiredup/KingRoaldAFUDialogue.kt new file mode 100644 index 0000000..4c5d448 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/allfiredup/KingRoaldAFUDialogue.kt @@ -0,0 +1,117 @@ +package content.region.misthalin.varrock.quest.allfiredup + +import core.game.node.entity.skill.Skills +import core.game.dialogue.DialogueFile +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import content.data.Quests + + +class KingRoaldAFUDialogue(val questStage: Int) : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + + if(questStage == 0){ + when(stage){ + 0 -> npc("Ah, it's you again. Hello there.").also { stage++ } + + 1 -> player( + "Hello, Your Majesty. I am happy to report that the", + "situation at the Temple of Paterdomus has been sorted.", + "Misthalin's borders should once again be fully protected", + "against the threats of Morytania." + ).also { stage++ } + + 2 -> npc("Ah, thank you! The kingdom is forever in your", "debt.").also{stage++} + 3 -> player("In your debt? Does that mean you're going to give me", "fabulous rewards for my efforts?").also { stage++ } + 4 -> npc( + "Of course not; however, if it's rewards you're after, it", + "occurs to me that you could be of even more service to", + "the kingdom...and this time, there's payment in it for", + "you." + ).also { stage++ } + + 5 -> options("Oh, tell me more!", "Sorry, not interested.").also { stage++ } + 6 -> when(buttonID){ + 1 -> player("Oh, tell me more!").also { stage++ } + 2 -> player("Sorry, not interested.").also { stage = END_DIALOGUE } + } + + 7 -> npc( + "Well, you see, because of the mounting threats from", + "Morytania and the Wilderness, the southern kingdoms", + "have banded together to take action." + ).also { stage++ } + + 8 -> npc( + "We have constructed a network of beacons that stretch", + "all the way from the source of the River Salve to the", + "northwestern-most edge of the Wilderness." + ).also { stage++ } + + 9 -> npc( + "Should there be any threat from these uncivilized lands,", + "we'll be able to spread the word as fast as the light of", + "the flames can travel." + ).also { stage++ } + + 10 -> player("So how could I be of help?").also { stage++ } + 11 -> npc( + "The task itself should be rather straightforward: I need", + "you to help us test the network of beacons to make", + "sure everything is in order, in case the worst", + "should occur." + ).also { stage++ } + + 12 -> options("I'd be happy to help.", "I'm a bit busy right now.").also { stage++ } + 13 -> when(buttonID){ + 1 -> player("I'd be happy to help.").also { stage++ } + 2 -> player("I'm a bit busy right now.").also { stage = END_DIALOGUE } + } + + 14 -> if (player!!.skills.getLevel(Skills.FIREMAKING) < 43) { + npc("I'd love for you to help, but you need", "to get better at lighting fires first.") + stage = END_DIALOGUE + } else { + npc("Excellent! The kingdom of Misthalin is eternally", "grateful.") + stage++ + } + + 15 -> player("So what do I need to do?").also { stage++ } + 16 -> npc( + "Talk to the head fire tender, Blaze Sharpeye - he'll", + "explain everything. He is stationed just south of the", + "Temple of Paterdomus, on the cliffs by the River Salve." + ).also { stage++ } + + 17 -> { + player("Thank you, Your Majesty. I'll seek out Blaze", "right away.") + stage = END_DIALOGUE + player!!.questRepository.getQuest(Quests.ALL_FIRED_UP).start(player) + } + + END_DIALOGUE -> end() + } + } + + else if(questStage == 90){ + when(stage){ + START_DIALOGUE -> player("I'm happy to report that the beacon network seems to", "be working as expected.").also { stage++ } + 1 -> npc("Excellent! I'm delighted to hear it.").also { stage++ } + 2 -> player("So, about that reward you promised?").also { stage++ } + 3 -> npc("What happened to the days when adventurers felt", "rewarded in full by the knowledge of a job well done?").also { stage++ } + 4 -> player("Well before my time, I'm afraid.").also { stage++ } + 5 -> npc("Hmph. Well, I suppose a king must stick to his word.", "Mind you, let me stress how grateful we are - and how", "grateful we'd be if you could continue helping us test", "the beacons.").also { stage++ } + 6 -> npc("There is much more to be done and this is but a", "pittance compared to what I'm willing to offer for", "further assistance!").also { stage++ } + 7 -> { + end() + player!!.questRepository.getQuest(Quests.ALL_FIRED_UP).finish(player) + } + } + } + + else { + abandonFile() + } + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/quest/allfiredup/SquireFyreDialogue.kt b/Server/src/main/content/region/misthalin/varrock/quest/allfiredup/SquireFyreDialogue.kt new file mode 100644 index 0000000..606e784 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/allfiredup/SquireFyreDialogue.kt @@ -0,0 +1,54 @@ +package content.region.misthalin.varrock.quest.allfiredup + +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import content.minigame.allfiredup.BeaconState +import core.api.* +import content.data.Quests + +@Initializable +class SquireFyreDialogue(player: Player? = null) : DialoguePlugin(player){ + override fun newInstance(player: Player?): DialoguePlugin { + return SquireFyreDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = (args[0] as NPC).getShownNPC(player) + val qstage = player.questRepository.getQuest(Quests.ALL_FIRED_UP).getStage(player) + when(qstage){ + 40 -> player("Hi there. I'm helping Blaze and King Roald test the","beacon network. Can you see it from here? Blaze said","you have pretty sharp eyes.").also { stage = 100 } + else -> npc("Carry on, friend.").also { stage = 1000 } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 100 -> npc("Of course I can see it. I haven't spent my entire life","practising my seeing skills for nothing! I'm happy to","report that the fire near Blaze is burning brightly.").also { stage++ } + 101 -> player("Terrific! Blaze has asked me to light this fire as well, so","he can see how things look from his vantage point.").also { stage++ } + 102 -> npc("Be my guest!").also { stage++; player.questRepository.getQuest(Quests.ALL_FIRED_UP).setStage(player,50); setVarbit(player, 5146, BeaconState.DYING.ordinal) } + 103 -> options("How do I light the beacon?","I suppose you don't have any logs I could have?","Okay, thanks.").also { stage++ } + 104 -> when(buttonId){ + 1 -> player("How do I light the beacon?").also { stage = 110 } + 2 -> player("I suppose you don't have any logs I could have?").also { stage = 120 } + 3 -> player("Okay, thanks").also { stage = 1000 } + } + 110 -> npc("Put in 20 logs of the same kind, and then light it.").also { stage = 1000 } + 120 -> npc("No, I do not.").also { stage = 1000 } + + + + + 1000 -> end() + } + + return true + } + + override fun getIds(): IntArray { + return intArrayOf(8066) + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/DSCutsceneTrigger.kt b/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/DSCutsceneTrigger.kt new file mode 100644 index 0000000..d498fd0 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/DSCutsceneTrigger.kt @@ -0,0 +1,29 @@ +package content.region.misthalin.varrock.quest.demonslayer + +import core.api.* +import core.game.world.map.zone.ZoneBorders +import core.game.activity.ActivityManager +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import org.rs09.consts.Items +import content.data.Quests + +class DSCutsceneTrigger : MapArea { + + override fun defineAreaBorders() : Array { + return arrayOf(ZoneBorders(3222, 3364, 3234, 3375)) + } + + override fun areaEnter(entity: Entity) { + if (entity !is Player) return + + val quest = entity.questRepository.getQuest(Quests.DEMON_SLAYER) + val alreadyInCutscene = getAttribute(entity, "demon-slayer:cutscene", false) + val hasSilverlight = inInventory(entity, Items.SILVERLIGHT_2402) || inEquipment(entity, Items.SILVERLIGHT_2402) + + if (quest.getStage(entity) == 30 && !alreadyInCutscene && hasSilverlight) { + ActivityManager.start(entity, "Demon Slayer Cutscene", false) + setAttribute(entity, "demon-slayer:cutscene", true) + } + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/DSlayerDrainPlugin.java b/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/DSlayerDrainPlugin.java new file mode 100644 index 0000000..2534847 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/DSlayerDrainPlugin.java @@ -0,0 +1,90 @@ +package content.region.misthalin.varrock.quest.demonslayer; + +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; + +import static core.api.ContentAPIKt.*; +import content.data.Quests; + + +/** + * Represents the demon slayer plugin used to handle washing the key down the drain. + * @author 'Vexia + * @version 1.0 + */ +public final class DSlayerDrainPlugin extends UseWithHandler { + + /** + * Represents the animation to use. + */ + private static final Animation ANIMATION = new Animation(827); + + /** + * Represents the bucket of water item. + */ + private static final Item BUCKET_OF_WATER = new Item(1929); + + /** + * Represents the bucket item. + */ + private static final Item BUCKET = new Item(1925); + + /** + * Constructs a new {@code DSlayerDrainPlugin} {@code Object}. + */ + public DSlayerDrainPlugin() { + super(1929); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(17424, OBJECT_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + final Quest quest = player.getQuestRepository().getQuest(Quests.DEMON_SLAYER); + if (player.getInventory().remove(BUCKET_OF_WATER)) { + player.getInventory().add(BUCKET); + player.animate(ANIMATION); + player.getPacketDispatch().sendMessage("You pour the liquid down the drain."); + if (quest.getStage(player) != 20) { + + return true; + } + if (player.getAttribute("demon-slayer:just-poured", false)) { + + return true; + } + if (!player.hasItem(DemonSlayer.FIRST_KEY)) { + + player.getSavedData().getQuestData().getDemonSlayer()[0] = false; + } + if (quest.getStage(player) == 20 && !player.hasItem(DemonSlayer.FIRST_KEY) && !player.getSavedData().getQuestData().getDemonSlayer()[0]) { + + player.getDialogueInterpreter().sendDialogues(player, null, "OK, I think I've washed the key down into the sewer.", "I'd better go down and get it!"); + player.getSavedData().getQuestData().getDemonSlayer()[0] = true;// poured + setVarp(player, 222, 2660610, true); + player.setAttribute("demon-slayer:just-poured", true); + return true; + } + } + return true; + } + + @Override + public Location getDestination(Player player, Node with) { + return new Location(3225, 3495); + + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/DemonSlayer.java b/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/DemonSlayer.java new file mode 100644 index 0000000..0492bb2 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/DemonSlayer.java @@ -0,0 +1,383 @@ +package content.region.misthalin.varrock.quest.demonslayer; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import core.plugin.Initializable; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import core.plugin.ClassScanner; +import content.data.Quests; + +/** + * Represents the demon slayer quest. + * @author Vexia + * + */ +@Initializable +public class DemonSlayer extends Quest { + + /** + * Represents the silverlight item. + */ + public static final Item SILVERLIGHT = new Item(2402); + + /** + * Represents the incantations we can use to generate a total incantation. + */ + private static final String[] INCANTATIONS = new String[] { "Carlem", "Aber", "Purchai", "Camerinthum", "Gabindo" }; + + /** + * Represents the first key item. + */ + public static final Item FIRST_KEY = new Item(2401); + + /** + * Represents the second key item. + */ + public static final Item SECOND_KEY = new Item(2400); + + /** + * Represents the third key item. + */ + public static final Item THIRD_KEY = new Item(2399); + + /** + * Constructs a new {@Code DemonSlayer} {@Code Object} + */ + public DemonSlayer() { + super(Quests.DEMON_SLAYER, 16, 15, 3, 222, 0, 1, 3); + } + + @Override + public Quest newInstance(Object object) { + ClassScanner.definePlugins(new DemonSlayerPlugin(), new DSlayerDrainPlugin(), new DemonSlayerCutscene(), new WallyCutscenePlugin(), new GypsyArisDialogue(), new SirPyrsinDialogue(), new TraibornDialogue(), new CaptainRovinDialogue()); + return this; + } + + @Override + public void drawJournal(Player player, int stage) { + super.drawJournal(player, stage); + switch (getStage(player)) { + case 0: + player.getPacketDispatch().sendString(BLUE + "I can start this quest by speaking to the " + RED + "Gypsy " + BLUE + "in the " + RED + "tent", 275, 4 + 8); + player.getPacketDispatch().sendString(BLUE + "in " + RED + "Varrock's main square", 275, 5+ 8); + player.getPacketDispatch().sendString(BLUE + "I must be able to defeat a level 27 " + RED + "apocalyptic demon" + BLUE + "!", 275, 7+ 8); + break; + case 10: + line(player, "I spoke to the Gypsy in Varrock Square who saw my future.", 4+ 8); + line(player, "Unfortunately it involved killing a demon who nearly", 5+ 8); + line(player, "destroyed Varrock over 150 years ago.", 6+ 7); + line(player, BLUE + "To defeat the " + RED + "demon " + BLUE + "I need the magical sword " + RED + "Silverlight.", 8+ 8); + line(player, BLUE + "I should ask " + RED + "Sir Prysin " + BLUE + "in " + RED + "Varrock Palace " + BLUE + "where it is.", 9+ 8); + break; + case 20: + line(player, "I spoke to the Gypsy in Varrock Square who saw my future.", 4+ 8); + line(player, "Unfortunately it involved killing a demon who nearly", 5+ 8); + line(player, "destroyed Varrock over 150 years ago.", 6+ 8); + line(player, BLUE + "To defeat the " + RED + "demon " + BLUE + "I need the magical sword " + RED + "Silverlight.", 8+ 8); + line(player, RED + "Sir Prysin " + BLUE + "needs " + RED + "3 keys " + BLUE + "before he can give me " + RED + "Silverlight.", 9+ 8); + if (player.getInventory().containsItem(FIRST_KEY) && player.getInventory().containsItem(SECOND_KEY) && player.getInventory().containsItem(THIRD_KEY)) { + line(player, BLUE + "Now I have " + RED + "all 3 keys " + BLUE + "I should go and speak to " + RED + "Sir Prysin", 9+ 8); + line(player, BLUE + "and collect the magical sword " + RED + "Silverlight " + BLUE + "from him.", 10+ 8); + } else { + line(player, player.hasItem(FIRST_KEY) ? "I have the 1st Key with me." : BLUE + "The " + RED + "1st Key " + BLUE + "was dropped down the palace kitchen drains.", 11+ 8); + line(player, player.hasItem(SECOND_KEY) ? "I have the 2nd Key with me." : BLUE + "The " + RED + "2nd Key " + BLUE + "is with Captain Rovin in Varrock Palace.", 12+ 8); + line(player, player.hasItem(THIRD_KEY) ? "I Have the 3rd key with me." : BLUE + "The " + RED + "3rd Key " + BLUE + "is with the Wizard Traiborn at the Wizards' Tower.", 13+ 8); + if (player.getAttribute("demon-slayer:traiborn", false)) { + line(player, BLUE + "The " + RED + "3rd Key " + BLUE + "is with Wizard Traiborn at the Wizards' Tower.", 13); + line(player, RED + "Traiborn " + BLUE + "needs " + RED + "25 " + BLUE + "more " + RED + "bones.", 14); + } + } + break; + case 30: + line(player, "I spoke to the Gypsy in Varrock Square who saw my future.", 4+ 8); + line(player, "Unfortunately it involved killing a demon who nearly", 5+ 8); + line(player, "destroyed Varrock over 150 years ago.", 6+ 8); + line(player, "I reclaimed the magical sword Silverlight from Sir Prysin.", 8+ 8); + line(player, BLUE + "Now I should go to the stone circle south of the city and", 9+ 8); + line(player, BLUE + "destroy " + RED + "Delrith " + BLUE + "using " + RED + "Silverlight" + BLUE + "!", 10+ 8); + break; + case 100: + line(player, "I spoke to the Gypsy in Varrock Square who saw my future.", 4+ 8); + line(player, "Unfortunately it involved killing a demon who nearly", 5+ 8); + line(player, "destroyed Varrock over 150 years ago.", 6+ 7); + line(player, "I reclaimed the magical sword Silverlight from Sir Prysin.", 8+ 8); + line(player, "Using its power I managed to destroy the demon Delrith", 9+ 8); + line(player, "like the great hero Wally did many years before.", 10+ 8); + line(player, "QUEST COMPLETE!", 12+ 7); + break; + } + } + + @Override + public void finish(Player player) { + super.finish(player); + player.getPacketDispatch().sendString("3 Quests Points", 277, 8+ 2); + player.getPacketDispatch().sendString("Silverlight", 277, 9+ 2); + player.getPacketDispatch().sendItemZoomOnInterface(SILVERLIGHT.getId(), 230, 277, 5); + player.removeAttribute("demon-slayer:traiborn"); + player.removeAttribute("demon-slayer:incantation"); + player.removeAttribute("demon-slayer:poured"); + player.removeAttribute("demon-slayer:received"); + player.getQuestRepository().syncronizeTab(player); + } + + /** + * Gets the incantation the player was given. + * @param player the player. + * @return the incantation given. + */ + public static String getIncantation(final Player player) { + return player.getAttribute("demon-slayer:incantation", generateIncantation(player)); + } + + /** + * Generates an incantation. + * @param player the player. + * @return the incantation. + */ + public static String generateIncantation(final Player player) { + final String incantation = player.getAttribute("demon-slayer:incantation", generateIncantation()); + player.setAttribute("/save:demon-slayer:incantation", incantation); + return incantation; + } + + /** + * Gets the generated incantation. + * @return the incantation. + */ + private final static String generateIncantation() { + List incantations = new ArrayList<>(20); + for (String s : INCANTATIONS) { + incantations.add(s); + } + Collections.shuffle(incantations); + return incantations.get(0) + "... " + incantations.get(1) + "... " + incantations.get(2) + "... " + incantations.get(3) + "... " + incantations.get(4); + } + /** + * Represents the dialogue plugin used for the captain rovin npc. + * @author 'Vexia + * @version 1.0 + */ + public final class CaptainRovinDialogue extends DialoguePlugin { + + /** + * Represents the quest instance. + */ + private Quest quest; + + /** + * Constructs a new {@code CaptainRovin} {@code Object}. + */ + public CaptainRovinDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code CaptainRovin} {@code Object}. + * @param player the player. + */ + public CaptainRovinDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new CaptainRovinDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + quest = player.getQuestRepository().getQuest(Quests.DEMON_SLAYER); + switch (quest.getStage(player)) { + default: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "What are you doing up here? Only the palace guards", "are allowed up here."); + stage = 0; + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (quest.getStage(player)) { + default: + defaultDialogue(buttonId); + break; + } + return true; + } + + /** + * Method used to handle the default dialogue. + * @param buttonId the button id. + */ + private final void defaultDialogue(int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "I am one of the palace guards.", "What about the King?", "Yes I know, but this is important."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I am one of the palace guards."); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What about the King? Surely you'd let him up here."); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Yes, I know but this is important."); + stage = 30; + break; + } + break; + case 30: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ok, I'm listening. Tell me what's so important."); + stage = 31; + break; + case 31: + if (quest.getStage(player) == 20) { + player("There's a demon who wants to invade the city."); + stage = 600; + return; + } + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Erm... I forgot."); + stage = 32; + break; + case 32: + end(); + break; + case 21: + end(); + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Well, yes I suppose we'd let him up, He doesn't", "generally want to come up here, but if he did want to,", "he could."); + stage = 21; + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "No, you're not! I know all the palace guards."); + stage = 11; + break; + case 11: + end(); + break; + case 600: + if (player.getInventory().containsItem(DemonSlayer.SECOND_KEY) || player.getBank().containsItem(DemonSlayer.SECOND_KEY)) { + npc("Yes, you said before, haven't you killed it yet?"); + stage = 620; + return; + } + npc("Is it a powerful demon?"); + stage = 601; + break; + case 601: + player("Yes, very."); + stage = 602; + break; + case 602: + npc("As good as the palace guards are, I don't know if", "they're up to taking on a very powerful demon."); + stage = 603; + break; + case 603: + player("It's not them who are going to fight the demon, it's me."); + ; + stage = 604; + break; + case 604: + npc("What, all by yourself? How are you going to do that?"); + stage = 605; + break; + case 605: + player("I'm going to use the powerful sword Silverlight, which I", "believe you have one of the keys for?"); + stage = 606; + break; + case 606: + npc("Yes, I do. But why should I give it to you?"); + stage = 607; + break; + case 607: + player("Sir Prysin said you would give me the key."); + stage = 608; + break; + case 608: + npc("Oh, he did, did he? Well I don't report to Sir Prysin, I", "report directly to the king!"); + stage = 609; + break; + case 609: + npc("I didn't work my way up through the ranks of the", "palace guards so I could take orders from an ill-bred", "moron who only has his job because his great-", "grandfather was a hero with a silly name!"); + stage = 610; + break; + case 610: + player("Why did he give you one of the keys then?"); + stage = 611; + break; + case 611: + npc("Only because the king ordered him to! The king", "couldn't get Sir Prysin to part with his precious", "ancestral sword, but he made him lock it up so he", "couldn't lose it."); + stage = 612; + break; + case 612: + npc("I got one key and I think some wizard got another.", "Now what happened to the third one?"); + stage = 613; + break; + case 613: + player("Sir Prysin dropped it down a drain!"); + stage = 614; + break; + case 614: + npc("Ha ha ha! The idiot!"); + stage = 615; + break; + case 615: + npc("Okay, I'll give you the key, just so that it's you that", "kills the demon and not Sir Prysin!"); + stage = 616; + break; + case 616: + if (player.getInventory().freeSlots() == 0) { + npc("Talk to me again when you have free inventory space."); + stage = 617; + return; + } + if (player.getInventory().add(DemonSlayer.SECOND_KEY)) { + interpreter.sendItemMessage(DemonSlayer.SECOND_KEY.getId(), "Captain Rovin hands you a key."); + stage = 618; + } + break; + case 617: + end(); + break; + case 618: + end(); + break; + case 620: + player("Well I'm going to use the powerful sword Silverlight", "which I believe you have one of the keys for?"); + stage = 621; + break; + case 621: + npc("I already gave you my key. Check your pockets."); + stage = 622; + break; + case 622: + end(); + break; + } + } + + @Override + public int[] getIds() { + return new int[] { 884 }; + } + + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/DemonSlayerCutscene.java b/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/DemonSlayerCutscene.java new file mode 100644 index 0000000..7c46309 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/DemonSlayerCutscene.java @@ -0,0 +1,592 @@ +package content.region.misthalin.varrock.quest.demonslayer; + +import core.game.activity.ActivityManager; +import core.game.activity.ActivityPlugin; +import core.game.activity.CutscenePlugin; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.spell.CombatSpell; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.build.DynamicRegion; +import core.game.world.map.path.Path; +import core.game.world.map.path.Pathfinder; +import core.game.world.update.flag.context.Animation; +import core.net.packet.PacketRepository; +import core.net.packet.context.CameraContext; +import core.net.packet.context.MinimapStateContext; +import core.net.packet.context.CameraContext.CameraType; +import core.net.packet.out.CameraViewPacket; +import core.net.packet.out.MinimapState; + +import static core.api.ContentAPIKt.*; +import content.data.Quests; + +/** + * Represents the cutscene during the combat of fighting delrith the demon. + * @author Vexia + * + */ +public final class DemonSlayerCutscene extends CutscenePlugin { + + /** + * Represents the id of delrith. + */ + public static final int DELRITH = 879; + + /** + * Represents the id of weakened delrith. + */ + public static final int WEAKENED_DELRITH = 880; + + /** + * Represents the wizard animation. + */ + private static final Animation WIZARD_ANIM = new Animation(4617); + + /** + * Represents the stone table. + */ + public Scenery stoneTable; + + /** + * Represents the delrith npc. + */ + public NPC delrith; + + /** + * Constructs a new {@code DemonSlayerCutscene} {@code Object}. + */ + public DemonSlayerCutscene() { + super("Demon Slayer Cutscene"); + } + + /** + * Constructs a new {@code DemonSlayerCutscene} {@code Object}. + * @param player the player. + */ + public DemonSlayerCutscene(final Player player) { + super("Demon Slayer Cutscene"); + this.player = player; + } + + @Override + public ActivityPlugin newInstance(Player p) throws Throwable { + return new DemonSlayerCutscene(p); + } + + @Override + public boolean start(final Player player, final boolean login, Object... args) { + final NPC npcs[] = new NPC[] { NPC.create(4658, base.transform(29, 43, 0)), NPC.create(4659, base.transform(29, 40, 0)), NPC.create(4662, base.transform(26, 40, 0)), NPC.create(4660, base.transform(26, 43, 0)) }; + for (NPC n : npcs) { + n.init(); + n.faceLocation(base.transform(27, 42, 0)); + this.npcs.add(n); + } + player.lock(); + return super.start(player, login, args); + } + + @Override + public void open() { + player.setAttribute("cutscene:original-loc", Location.create(3221, 3373, 0)); + player.setAttribute("real-end", Location.create(3221, 3373, 0)); + for (NPC n : npcs) { + n.animate(WIZARD_ANIM); + } + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.POSITION, player.getLocation().getX(), player.getLocation().getY(), 450, 1, 100)); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.ROTATION, player.getLocation().getX() - 15, player.getLocation().getY() + -55, 450, 1, 100)); + player.lock(); + player.getDialogueInterpreter().open(4662, npcs.get(3), this); + } + + @Override + public void end() { + super.end(); + player.unlock(); + } + + @Override + public boolean enter(final Entity entity) { + if (!(entity instanceof Player)) { + return true; + } + final Player player = ((Player) entity); + final Quest quest = player.getQuestRepository().getQuest(Quests.DEMON_SLAYER); + boolean in = player.getAttribute("demon-slayer:cutscene", false); + if (quest.getStage(player) == 30 && !in && (player.getEquipment().containsItem(DemonSlayer.SILVERLIGHT) || player.getInventory().containsItem(DemonSlayer.SILVERLIGHT))) { + ActivityManager.start(player, "Demon Slayer Cutscene", false); + player.setAttribute("demon-slayer:cutscene", true); + return super.enter(entity); + } + return super.enter(entity); + } + + @Override + public void locationUpdate(Entity entity, Location last) { + if (!(entity instanceof Player)) { + super.locationUpdate(entity, last); + return; + } + Player player = ((Player) entity); + if (base != null && player.getAttribute("demon-slayer:cutscene", false) && player.getLocation().getDistance(base.transform(27, 42, 0)) > 8) { + stop(true); + } + super.locationUpdate(entity, last); + } + + @Override + public boolean leave(final Entity e, final boolean logout) { + if (!(e instanceof Player)) { + return true; + } + final Player player = ((Player) e); + if (player.getAttribute("demon-slayer:cutscene", false)) { + if (base != null && player.getLocation().getDistance(base.transform(27, 42, 0)) > 13) { + player.removeAttribute("demon-slayer:cutscene"); + } + return super.leave(player, logout); + } + return super.leave(player, logout); + } + + @Override + public Location getStartLocation() { + return base.transform(29, 47, 0); + } + + @Override + public Location getSpawnLocation() { + return null; + } + + @Override + public void configure() { + region = DynamicRegion.create(12852); + setRegionBase(); + registerRegion(region.getId()); + } + + @Override + public void register() { + //register(new ZoneBorders(3222, 3364, 3234, 3375)); + try { + new DarkWizardNPC().newInstance(null); + new DelrithNPC().newInstance(null); + new DelrithDialoguePlugin().init(); + new DenathDialogue().init(); + } catch (Throwable e) { + e.printStackTrace(); + } + } + + /** + * Handles the dark wizard npc. + * @author 'Vexia + */ + public static class DarkWizardNPC extends AbstractNPC { + + /** + * The NPC ids of NPCs using this plugin. + */ + private static final int[] IDS = { 4658 }; + + /** + * Constructs a new {@code DarkWizardNPC} {@code Object}. + */ + public DarkWizardNPC() { + super(0, null); + } + + /** + * Constructs a new {@code DarkWizardNPC} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + private DarkWizardNPC(int id, Location location) { + super(id, location, false); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new DarkWizardNPC(id, location); + } + + @Override + public void init() { + super.init(); + this.getSkills().setLevel(Skills.MAGIC, 11); + this.setRespawn(false); + } + + @Override + public void tick() { + super.tick(); + getProperties().setAutocastSpell((CombatSpell) SpellBook.MODERN.getSpell(4)); + getProperties().getCombatPulse().setStyle(CombatStyle.MAGIC); + } + + @Override + public int[] getIds() { + return IDS; + } + + } + + /** + * Handles the delrith NPC. + * @author 'Vexia + */ + public class DelrithNPC extends AbstractNPC {// 65, 64 + + /** + * The NPC ids of NPCs using this plugin. + */ + private final int[] IDS = { WEAKENED_DELRITH, DELRITH }; + + /** + * Constructs a new {@code DarkWizardNPC} {@code Object}. + */ + public DelrithNPC() { + super(0, null); + } + + /** + * Constructs a new {@code DarkWizardNPC} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + private DelrithNPC(int id, Location location) { + super(id, location, false); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new DelrithNPC(id, location); + } + + @Override + public void init() { + super.init(); + } + + @Override + public void finalizeDeath(final Entity killer) { + if (getId() == DELRITH) { + setAttribute("disable:drop", true); + super.finalizeDeath(killer); + super.setRespawnTick(-1); + super.getWalkingQueue().reset(); + super.getLocks().lockMovement(10); + transform(WEAKENED_DELRITH); + getProperties().setTeleportLocation(null); + lock(); + } else { + super.finalizeDeath(killer); + } + } + + @Override + public void tick() { + super.tick(); + } + + @Override + public int[] getIds() { + return IDS; + } + + @Override + public int getWalkRadius() { + return 3; + } + } + + /** + * Represents the dialogue for delrith. + * @author 'Vexia + * @version 1.0 + */ + public static final class DelrithDialoguePlugin extends DialoguePlugin { + + /** + * Represents the word array. + */ + private static final String[] WORDS = new String[] { "Carlem", "Aber", "Camerinthum", "Purchai", "Gabindo" }; + + /** + * Represents the incantationc ounter. + */ + private int counter = 0; + + /** + * Represents the cutscene. + */ + private DemonSlayerCutscene cutscene; + + /** + * Represents the string builder. + */ + private StringBuilder incantation = new StringBuilder(); + + /** + * Constructs a new {@code DelrithDialoguePlugin} {@code Object}. + */ + public DelrithDialoguePlugin() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code DelrithDialoguePlugin} {@code Object}. + * @param player the player. + */ + public DelrithDialoguePlugin(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new DelrithDialoguePlugin(player); + } + + @Override + public boolean open(Object... args) { + cutscene = player.getAttribute("cutscene", null); + player("Now what was that incantation again?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select a word", WORDS); + stage = 1; + break; + case 1: + switch (buttonId) { + default: + String text = ((String) WORDS[buttonId - 1]) + (counter != 4 ? "..." : "!"); + if (text.contains("!")) { + incantation.append(text.replace("!", "")); + } else { + incantation.append(text + " "); + } + player.sendChat(text); + player(text); + if (counter == 4) { + if (incantation.toString().equals(DemonSlayer.getIncantation(player).trim())) { + stage = 4; + } else { + stage = 2; + } + } else { + stage = 0; + } + break; + } + counter++; + break; + case 2: + cutscene.delrith.reTransform(); + cutscene.delrith.animate(new Animation(4620)); + cutscene.delrith.unlock(); + interpreter.sendDialogue("The vortex collapses. That was the wrong incantation."); + stage = 3; + break; + case 3: + end(); + break; + case 4: + interpreter.sendPlainMessage(true, "Delrith is sucked into the vortex..."); + cutscene.delrith.animate(new Animation(4624)); + player.lock(); + GameWorld.getPulser().submit(new Pulse(10) { + @Override + public boolean pulse() { + cutscene.delrith.clear(); + interpreter.sendDialogue("...back into the dark dimension from which he came."); + player.unlock(); + cutscene.end(); + cutscene.delrith.clear(); + setVarp(player, 222, 5653570, true); + player.getQuestRepository().getQuest(Quests.DEMON_SLAYER).finish(player); + end(); + return true; + } + + }); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 8427322 }; + } + } + + /** + * Represents the dialogue which handles the denath NPC. + * @author 'Vexia + * @version 1.0 + */ + public static final class DenathDialogue extends DialoguePlugin { + + /** + * Represents the animation to use. + */ + private static final Animation ANIMATION = new Animation(4623); + + /** + * Represents the cutscene plugin. + */ + public DemonSlayerCutscene cutscene; + + /** + * Constructs a new {@code DenathDialogue} {@code Object}. + */ + public DenathDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code DenathDialogue} {@code Object}. + * @param player the player. + */ + public DenathDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new DenathDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = ((NPC) args[0]); + cutscene = ((DemonSlayerCutscene) args[1]); + npc("Arise, O mighty Delrith! Bring destruction to this soft,", "weak city!"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(cutscene.getNPCS().get(0), null, "Arise, Delrith!"); + for (NPC n : cutscene.getNPCS()) { + n.sendChat("Arise, Delrith!"); + } + stage = 1; + break; + case 1: + player.getProperties().setTeleportLocation(cutscene.getBase().transform(28, 35, 0)); + cutscene.stoneTable = new Scenery(17437, cutscene.getBase().transform(27, 41, 0)); + SceneryBuilder.add(cutscene.stoneTable); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.POSITION, player.getLocation().getX() - 1, player.getLocation().getY() + 2, 380, 1, 98)); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.ROTATION, player.getLocation().getX() + 19, player.getLocation().getY() - 55, 380, 1, 98)); + interpreter.sendPlainMessage(true, "The wizards cast an evil spell..."); + GameWorld.getPulser().submit(new Pulse(1, player) { + int counter = 0; + + @SuppressWarnings("deprecation") + @Override + public boolean pulse() { + switch (counter++) { + case 5: + cutscene.delrith = NPC.create(DemonSlayerCutscene.DELRITH, cutscene.getBase().transform(27, 40, 0)); + cutscene.delrith.init(); + cutscene.delrith.animate(ANIMATION); + player.getProperties().setTeleportLocation(cutscene.getBase().transform(26, 48, 0)); + player.setLocation(cutscene.getBase().transform(26, 48, 0)); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.POSITION, player.getLocation().getX() - 1, player.getLocation().getY() - 3, 390, 1, 100)); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.ROTATION, player.getLocation().getX() + 30, player.getLocation().getY() - 55, 390, 1, 100)); + setVarp(player, 222, 14194946, true); + SceneryBuilder.replace(cutscene.stoneTable, cutscene.stoneTable.transform(17438)); + npc("Ha ha ha! At last you are free, my demonic brother!", "Rest now, and then have your revenge on this pitiful", "city!"); + stage = 2; + return true; + } + return false; + } + }); + break; + case 2: + interpreter.sendDialogues(cutscene.getNPCS().get(0), null, "Who's that?"); + for (NPC n : cutscene.getNPCS()) { + n.animate(new Animation(-1)); + n.face(player); + } + stage = 3; + break; + case 3: + npc = cutscene.getNPCS().get(2); + npc("Noo! Not Silverlight! Delrith is not ready yet!"); + stage = 4; + break; + case 4: + npc("I've got to get out of here..."); + npc.faceLocation(null); + npc.face(null); + Path path = Pathfinder.find(npc, cutscene.getBase().transform(18, 40, 0)); + path.walk(npc); + stage = 5; + break; + case 5: + player.getProperties().setTeleportLocation(cutscene.getBase().transform(24, 42, 0)); + npc.clear(); + cutscene.getNPCS().remove(npc); + end(); + cutscene.delrith.moveStep(); + cutscene.delrith.setWalks(true); + player.unlock(); + player.getInterfaceManager().restoreTabs(); + player.getInterfaceManager().close(); + PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 0)); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.RESET, player.getLocation().getX(), player.getLocation().getY(), 390, 1, 100)); + for (NPC n : cutscene.getNPCS()) { + n.clear(); + } + cutscene.getNPCS().clear(); + final Location base = cutscene.getBase(); + cutscene.getNPCS().add(NPC.create(4658, base.transform(29, 40, 0))); + cutscene.getNPCS().add(NPC.create(4658, base.transform(26, 40, 0))); + cutscene.getNPCS().add(NPC.create(4658, base.transform(26, 43, 0))); + for (NPC n : cutscene.getNPCS()) { + n.init(); + n.setWalks(true); + n.unlock(); + } + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.RESET, 0, 0, 0, 0, 0)); + cutscene.getNPCS().get(0).getProperties().getCombatPulse().attack(player); + player.setAttribute("cutscene", cutscene); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 4662 }; + } + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/DemonSlayerPlugin.java b/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/DemonSlayerPlugin.java new file mode 100644 index 0000000..87740d6 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/DemonSlayerPlugin.java @@ -0,0 +1,97 @@ +package content.region.misthalin.varrock.quest.demonslayer; + +import core.cache.def.impl.NPCDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.world.map.Location; +import core.plugin.Plugin; + +import static core.api.ContentAPIKt.*; +import content.data.Quests; + + +/** + * Represents the demon slayer plugin used to handle relative node interactions. + * @author 'Vexia + * @date 3/1/14 + */ +public final class DemonSlayerPlugin extends OptionHandler { + + /** + * Represents the object id of the drain. + */ + public static final int DRAIN_ID = 17424; + + /** + * Represents the location of the lumbridge sewers. + */ + private static final Location SEWER_LOCATION = new Location(3237, 9858, 0); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(DRAIN_ID).getHandlers().put("option:search", this); + SceneryDefinition.forId(17429).getHandlers().put("option:take", this); + NPCDefinition.forId(DemonSlayerCutscene.DELRITH).getHandlers().put("option:attack", this); + NPCDefinition.forId(DemonSlayerCutscene.WEAKENED_DELRITH).getHandlers().put("option:banish", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + final Quest quest = player.getQuestRepository().getQuest(Quests.DEMON_SLAYER); + final int id = node instanceof Scenery ? ((Scenery) node).getId() : node instanceof Item ? ((Item) node).getId() : ((NPC) node).getId(); + switch (id) { + case 880: + player.getDialogueInterpreter().open(8427322); + break; + case 879: + if (!player.getEquipment().containsItem(DemonSlayer.SILVERLIGHT)) { + player.getPacketDispatch().sendMessage("I'd better wield Silverlight first."); + return true; + } + player.face(((NPC) node)); + player.getProperties().getCombatPulse().attack(node); + return true; + case DRAIN_ID: + if (quest.getStage(player) == 20) { + player.getDialogueInterpreter().open(883, 883, "key"); + return true; + } else { + player.sendMessage("You search the castle drain and find nothing of value."); + } + return true; + case 17429: + if (quest.getStage(player) == 20 && player.getInventory().add(DemonSlayer.FIRST_KEY)) { + setVarp(player, 222, 4757762, true); + player.removeAttribute("demon-slayer:poured"); + player.removeAttribute("demon-slayer:just-poured"); + player.getDialogueInterpreter().sendItemMessage(DemonSlayer.FIRST_KEY.getId(), "You pick up an old rusty key."); + } else { + if (player.getInventory().freeSlots() == 0) { + player.getPacketDispatch().sendMessage("Not enough inventory space."); + return true; + } + } + break; + } + return true; + } + + @Override + public Location getDestination(final Node node, final Node n) { + if (n instanceof NPC) { + return n.getLocation().transform(2, 0, 0); + } + if (n.getId() == DRAIN_ID) { + return Location.create(3226, 3496, 0); + } + return null; + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/GypsyArisDialogue.java b/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/GypsyArisDialogue.java new file mode 100644 index 0000000..7d0c852 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/GypsyArisDialogue.java @@ -0,0 +1,673 @@ +package content.region.misthalin.varrock.quest.demonslayer; + +import core.game.component.Component; +import core.game.activity.ActivityManager; +import core.game.activity.CutscenePlugin; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Direction; +import core.game.world.update.flag.context.Animation; +import core.net.packet.PacketRepository; +import core.net.packet.context.CameraContext; +import core.net.packet.context.CameraContext.CameraType; +import core.net.packet.out.CameraViewPacket; +import content.data.Quests; + +/** + * Represents the dialogue which handles the transcript for the gypsy aris. + * @author 'Vexia + * @version 1.0 + */ +public final class GypsyArisDialogue extends DialoguePlugin { + + /** + * Represents the coins to remove. + */ + private static final Item COINS = new Item(995, 1); + + /** + * Represents the animation used to look into a crystal ball. + */ + private static final Animation ANIMATION = new Animation(4615); + + /** + * Represents the quest instance. + */ + private Quest quest; + + /** + * Represents the wally npc. + */ + private NPC wally; + + /** + * Represents the cutscene plugin instance. + */ + private CutscenePlugin cutscene; + + /** + * Constructs a new {@code GypsyArisDialogue} {@code Object}. + */ + public GypsyArisDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code GypsyArisDialogue} {@code Object}. + * @param player the player. + */ + public GypsyArisDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new GypsyArisDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + quest = player.getQuestRepository().getQuest(Quests.DEMON_SLAYER); + switch (quest.getStage(player)) { + case 100: + npc("Greetings young one."); + stage = 0; + break; + case 30: + case 10: + case 20: + if (args.length > 1) { + npc("Delrith will come forth from the stone circle again."); + stage = 200; + return true; + } + npc("Greetings. How goes the quest?"); + if (quest.getStage(player) != 30) { + stage = 1; + } else { + stage = 0; + } + break; + case 0: + if (args.length > 1) { + cutscene = ((CutscenePlugin) args[1]); + npc("Wally managed to arrive at the stone circle just as", "Delrith was summoned by a cult of chaos druids..."); + stage = 200; + return true; + } + npc("Hello young one."); + stage = 1; + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (quest.getStage(player)) { + case 100: + switch (stage) { + case 0: + npc("You're a hero now. That was a good bit of", "demonslaying."); + stage = 1; + break; + case 1: + player("Thanks."); + stage = 2; + break; + case 2: + end(); + break; + } + break; + case 30: + switch (stage) { + case 0: + player("I have the sword now. I just need to kill the demon, I", "think."); + stage = 1; + break; + case 1: + npc("Yep, that's right."); + stage = 2; + break; + case 2: + options("What is the magical incantation?", "Well I'd better press on with it", "Where can I find the demon?"); + stage = 3; + break; + case 3: + switch (buttonId) { + case 1: + player("What is the magical incantation?"); + stage = 10; + break; + case 2: + player("Well I'd better press on with it."); + stage = 20; + break; + case 3: + player("Where can I find the demon?"); + stage = 30; + break; + } + break; + case 10: + npc(DemonSlayer.getIncantation(player) + "."); + stage = 11; + break; + case 11: + player("Well I'd better press on with it."); + stage = 20; + break; + case 20: + npc("See you anon."); + stage = 21; + break; + case 21: + end(); + break; + case 30: + npc("Just head south and you should find the stone circle", "just outside the city gate."); + stage = 31; + break; + case 31: + end(); + break; + } + break; + case 20: + switch (stage) { + case 0: + player("I found Sir Prysin. Unfortunately I haven't got the", "sword yet. He's made it complicated for me."); + stage = 1; + break; + case 1: + npc("Ok, hurry, we haven't much time."); + stage = 2; + break; + case 2: + options("What is the magical incantation?", "Well I'd better press on with it."); + stage = 3; + break; + case 3: + switch (buttonId) { + case 1: + player("What is the magical incantation?"); + stage = 10; + break; + case 2: + player("Well I'd better press on with it."); + stage = 20; + break; + } + break; + case 10: + npc(DemonSlayer.getIncantation(player) + "."); + stage = 11; + break; + case 11: + player("Well I'd better press on with it."); + stage = 20; + break; + case 20: + player("See you anon."); + stage = 21; + break; + case 21: + end(); + break; + } + break; + case 10: + switch (stage) { + case 1: + player("I'm still working on it."); + stage = 2; + break; + case 2: + npc("Well if you need any advice I'm always here, young", "one."); + stage = 3; + break; + case 3: + options("What is the magical incantation?", "Where can I find Silverlight?", "Stop calling me that!", "Well I'd better press on with it."); + stage = 4; + break; + case 4: + switch (buttonId) { + case 1: + player("What is the magical incantation?"); + stage = 10; + break; + case 2: + player("Where can I find Silverlight?"); + stage = 20; + break; + case 3: + player("Stop calling me that!"); + stage = 30; + break; + case 4: + player("Well I'd better press on with it."); + stage = 40; + break; + } + break; + case 10: + npc("Oh yes, let me think a second..."); + stage = 11; + break; + case 11: + npc("Alright, I think I've got it now, it goes..."); + stage = 12; + break; + case 12: + npc(DemonSlayer.getIncantation(player) + ".", "Have you got that?"); + stage = 13; + break; + case 13: + player("I think so, yes."); + stage = 14; + break; + case 14: + end(); + break; + case 20: + npc("Silverlight has been passed down through Wally's", "descendants. I believe it is currently in the care of one", "of the King's knights called Sir Prysin."); + stage = 21; + break; + case 21: + npc("He shouldn't be too hard to find. He lives in the royal", "palace in this city. Tell him Gypsy Aris sent you."); + stage = 22; + break; + case 22: + end(); + break; + case 30: + npc("In the scheme of things you are very young."); + stage = 31; + break; + case 31: + end(); + break; + case 40: + npc("See you anon."); + stage = 41; + break; + case 41: + end(); + break; + case 200: + npc("I would imagine an evil sorcerer is already starting on", "the rituals to summon Delrith as we speak."); + stage = 201; + break; + case 201: + options("How am I meant to fight a demon who can destroy cities?", "Okay, where is he? I'll kill him for you!", "What is the magical incantation?", "Where can I find Silverlight?"); + stage = 202; + break; + case 202: + switch (buttonId) { + case 1: + player("How am I meant to fight a demon who can destroy ", "cities?!"); + stage = 110; + break; + case 2: + player("Okay, where is he? I'll kill him for you!"); + stage = 120; + break; + case 3: + player("What is the magical incantation?"); + stage = 10; + break; + case 4: + player("Where can I find Silverlight?"); + stage = 20; + break; + } + break; + case 120: + npc("Ah, the overconfidence of the young!"); + stage = 121; + break; + case 121: + npc("Delrith can't be harmed by ordinary weapons. You", "must face him using the same weapon that Wally used."); + stage = 201; + break; + case 110: + npc("If you face Delrith while he is still weak from being", "summoned, and use the correct weapon, you will not", "find the task to arduous."); + stage = 111; + break; + case 111: + npc("Do not fear. If you follow the path of the great hero", "Wally, then you are sure to defeat the demon."); + stage = 201; + break; + } + break; + case 0: + switch (stage) { + case 1: + npc("Cross my palm with silver and the future will be", "revealed to you."); + stage = 2; + break; + case 2: + options("Ok, here you go.", "Who are you calling young one?!", "No, I don't believe in that stuff.", "With silver?"); + stage = 3; + break; + case 3: + switch (buttonId) { + case 1: + player("Ok, here you go."); + stage = 10; + break; + case 2: + player("Who are you calling young one?!"); + stage = 20; + break; + case 3: + player("No, I don't believe in that stuff."); + stage = 30; + break; + case 4: + player("With silver?"); + stage = 40; + break; + } + break; + case 10: + if (!player.getInventory().containsItem(COINS)) { + end(); + return true; + } + if (player.getInventory().remove(COINS)) { + npc("Come closer, and listen carefully to what the future", "holds for you, as I peer int the swirling mists of the", "crystal ball."); + npc.animate(ANIMATION); + stage = 12; + } else { + player("Sorry, I don't seem to have enough coins."); + stage = 11; + } + break; + case 11: + end(); + break; + case 12: + npc("I can see images forming. I can see you."); + stage = 13; + break; + case 13: + npc("You are holding a very impressive looking sword. I'm", "sure I recognize that sword..."); + stage = 14; + break; + case 14: + npc("There is a big dark shadow appearing now."); + stage = 15; + break; + case 15: + npc("Aargh!"); + stage = 16; + break; + case 16: + player("Are you all right?"); + stage = 17; + break; + case 17: + npc("It's Delrith! Delrith is coming!"); + stage = 18; + break; + case 18: + player("Who's Delrith?"); + stage = 50; + break; + case 50: + npc("Delrith..."); + stage = 51; + break; + case 51: + npc("Delrith is a powerful demon."); + stage = 52; + break; + case 52: + npc("Oh! I really hope he didn't see me looking at him", "through my crystal ball!"); + stage = 53; + break; + case 53: + npc("He tried to destroy this city 150 years ago. He was", "stopped just in time by the great hero Wally."); + stage = 54; + break; + case 54: + npc("Using his magic sword Silverlight, Wally managed to", "trap the demon in the stone circle just south", "of this city."); + stage = 55; + break; + case 55: + npc("Ye gods! Silverlight was the sword you were holding in", "my vision! You are the one destined to stop the demon", "this time."); + stage = 56; + break; + case 56: + options("How am I meant to fight a demon who can destroy cities?", "Okay, where is he? I'll kill him for you!", "Wally doesn't sound like a very heroic name."); + stage = 57; + break; + case 57: + switch (buttonId) { + case 1: + player("How am I meant to fight a demon who can destroy ", "cities?!"); + stage = 110; + break; + case 2: + player("Okay, where is he? I'll kill him for you!"); + stage = 120; + break; + case 3: + player("Wally doesn't sound like a very heroic name."); + stage = 130; + break; + } + break; + case 110: + npc("If you face Delrith while he is still weak from being", "summoned, and use the correct weapon, you will not", "find the task to arduous."); + stage = 111; + break; + case 111: + npc("Do not fear. If you follow the path of the great hero", "Wally, then you are sure to defeat the demon."); + stage = 112; + break; + case 112: + options("Okay, where is he? I'll kill him for you!", "Wally doesn't sound like a very heroic name.", "So how did Wally kill Delrith?"); + stage = 113; + break; + case 113: + switch (buttonId) { + case 1: + player("Okay, where is he? I'll kill him for you!"); + stage = 120; + break; + case 2: + player("Wally doesn't sound like a very heroic name."); + stage = 130; + break; + case 3: + player("So how did Wally kill Delrith?"); + stage = 180; + break; + } + break; + case 120: + npc("Ah, the overconfidence of the young!"); + stage = 121; + break; + case 121: + npc("Delrith can't be harmed by ordinary weapons. You", "must face him using the same weapon that Wally used."); + stage = 122; + break; + case 122: + options("How am I meant to fight a demon who can destroy cities?", "Wally doesn't sound like a very heroic name.", "So how did wally kill Delrith?"); + stage = 123; + break; + case 123: + switch (buttonId) { + case 1: + player("How am I meant to fight a demon who can destroy ", "cities?!"); + stage = 110; + break; + case 2: + player("Wally doesn't sound like a very heroic name."); + stage = 130; + break; + case 3: + player("So how did Wally kill Delrith?"); + stage = 180; + break; + } + break; + case 130: + npc("Yes I know. Maybe this is why history doesn't", "remember him. However he was a very great hero."); + stage = 131; + break; + case 131: + npc("Who knows how much pain and suffering Delrith would", "have brought forth without Wally to stop him!"); + stage = 132; + break; + case 132: + npc("It looks like you are going to need to perform similar", "heroics."); + stage = 133; + break; + case 133: + options("How am I meant to fight a demon who can destroy cities?", "Okay, where is he? I'll kill him for you!", "So how did Wally kill Delrith?"); + stage = 134; + break; + case 134: + switch (buttonId) { + case 1: + player("How am I meant to fight a demon who can destroy ", "cities?!"); + stage = 110; + break; + case 2: + player("Okay, where is he? I'll kill him for you!"); + stage = 120; + break; + case 3: + player("So how did Wally kill Delrith?"); + stage = 180; + break; + } + break; + case 180: + ActivityManager.start(player, "Wally cutscene", false); + end(); + break; + case 20: + npc("You have been on this world a relatively short time. At", "least compared to me."); + stage = 21; + break; + case 21: + end(); + break; + case 30: + npc("Ok suit yourself."); + stage = 31; + break; + case 31: + end(); + break; + case 40: + npc("Oh, sorry, I forgot. With gold, I mean. They haven't", "used silver coins since before you were born! So, do", "you want your fortune told?"); + stage = 41; + break; + case 41: + options("Ok, here you go.", "No, I don't believe in that stuff."); + stage = 42; + break; + case 42: + switch (buttonId) { + case 1: + player("Ok, here you go."); + stage = 10; + break; + case 2: + player("No, I don't believe in that stuff."); + stage = 30; + break; + } + break; + case 200:// Wally cutscene dialogue. + wally = NPC.create(4664, cutscene.getBase().transform(31, 40, 0)); + wally.setDirection(Direction.WEST); + cutscene.getNPCS().add(wally); + wally.init(); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.POSITION, player.getLocation().getX() + 2, player.getLocation().getY() + 2, 260, 1, 10)); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.ROTATION, player.getLocation().getX() + 190, player.getLocation().getY() + 14, 260, 1, 10)); + interpreter.sendDialogues(wally, FacialExpression.FURIOUS, "Die, foul demon!"); + GameWorld.getPulser().submit(new Pulse(5) { + @Override + public boolean pulse() { + wally.animate(new Animation(4603)); + return true; + } + }); + stage = 201; + break; + case 201: + interpreter.sendDialogues(wally, null, "Now, what was that incantation again?"); + stage = 202; + break; + case 202: + interpreter.sendDialogues(wally, null, DemonSlayer.generateIncantation(player) + "!"); + stage = 203; + break; + case 203: + close(); + player.getInterfaceManager().openOverlay(new Component(115)); + GameWorld.getPulser().submit(new Pulse(1) { + int counter = 0; + + @Override + public boolean pulse() { + switch (counter++) { + case 1: + player.getProperties().setTeleportLocation(cutscene.getBase().transform(25, 36, 0)); + break; + case 3: + wally.setDirection(Direction.SOUTH_WEST); + wally.getProperties().setTeleportLocation(cutscene.getBase().transform(28, 40, 0)); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.POSITION, player.getLocation().getX(), player.getLocation().getY(), 440, 1, 100)); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.ROTATION, player.getLocation().getX() + 1, player.getLocation().getY() + 1, 440, 1, 100)); + case 4: + player.getInterfaceManager().closeOverlay(); + player.getInterfaceManager().close(); + wally.animate(new Animation(4604)); + interpreter.sendDialogues(wally, null, "I am the greatest demon slayer EVER!"); + stage = 204; + break; + case 5: + wally.animate(new Animation(4604)); + return true; + } + return false; + } + }); + break; + case 204: + npc("By reciting the correct magical incantation, and", "thrusting Silverlight into Delrith while he was newly", "summoned, Wally was able to imprison Delrith in the", "stone block in the centre of the circle."); + stage = 205; + break; + case 205: + cutscene.stop(true); + close(); + break; + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 882 }; + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/SirPyrsinDialogue.java b/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/SirPyrsinDialogue.java new file mode 100644 index 0000000..8be176a --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/SirPyrsinDialogue.java @@ -0,0 +1,543 @@ +package content.region.misthalin.varrock.quest.demonslayer; + +import core.api.Container; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import org.rs09.consts.Items; + +import static core.api.ContentAPIKt.*; +import static core.tools.DialogueConstKt.END_DIALOGUE; +import static core.tools.GlobalsKt.colorize; +import content.data.Quests; + +/** + * Represents the dialogue which handles the Sir Prysin NPC. + * @author Vexia + * @date 3/1/13 + */ +public class SirPyrsinDialogue extends DialoguePlugin { + + /** + * Represents the quest instance. + */ + private Quest quest; + + /** + * Represents the current npc id. + */ + private int id; + + /** + * Constructs a new {@code SirPyrsinDialogue} {@code Object}. + */ + public SirPyrsinDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code SirPyrsinDialogue} {@code Object}. + * @param player the player. + */ + public SirPyrsinDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new SirPyrsinDialogue(player); + } + + @Override + public boolean open(Object... args) { + if (args[0] instanceof NPC) { + npc = (NPC) args[0]; + id = npc.getId(); + } else if (args[0] instanceof Integer) { + id = ((int) args[0]); + } + quest = player.getQuestRepository().getQuest(Quests.DEMON_SLAYER); + switch (quest.getStage(player)) { + case 30: + npc(id, "Have you sorted that demon out yet?"); + stage = 0; + break; + case 20: + if (args.length > 1) { + player("That must be the key Sir Prysin dropped."); + stage = 800; + return true; + } + npc(id, "So how are you doing with getting the keys?"); + stage = 0; + break; + default: + npc(id, "Hello, who are you?"); + stage = 0; + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (quest.getStage(player)) { + case 30: + switch (stage) { + case 0: + if (!player.getInventory().containsItem(DemonSlayer.SILVERLIGHT) && !player.getBank().containsItem(DemonSlayer.SILVERLIGHT) && !player.getEquipment().containsItem(DemonSlayer.SILVERLIGHT)) { + player("Not yet. And I, um, lost Silverlight."); + stage = 1; + } else { + player("No, not yet."); + stage = 3; + } + break; + case 1: + if (player.getInventory().add(DemonSlayer.SILVERLIGHT)) { + npc(id, "Yes, I know, someone returned it to me. Take better", "care of it this time."); + stage = 2; + } + break; + case 2: + end(); + break; + case 3: + npc(id, "Well get on with it. He'll be pretty powerful when he", "gets to full strength."); + stage = 4; + break; + case 4: + end(); + break; + case 302: + end(); + break; + } + break; + case 20: + switch (stage) { + case 0: + if (player.getInventory().containsItem(DemonSlayer.FIRST_KEY) && player.getInventory().containsItem(DemonSlayer.SECOND_KEY) && player.getInventory().containsItem(DemonSlayer.THIRD_KEY)) { + player("I've got all three keys!"); + stage = 300; + } else { + player("I haven't found them all yet."); + stage = 1; + } + break; + case 1: + options("Can you remind me where all the keys were again?", "I'm still looking."); + stage = 2; + break; + case 2: + switch (buttonId) { + case 1: + player("Can you remind me where all the keys were again?"); + stage = 62; + break; + case 2: + player("I'm still looking."); + stage = 20; + break; + } + break; + case 20: + npc(id, "Ok, tell me when you've got them all."); + stage = 21; + break; + case 21: + end(); + break; + case 62: + npc(id, "I kept one of the keys. I gave the other two to other", "people for safe keeping."); + stage = 63; + break; + case 63: + npc(id, "One I gave to Rovin, the captain of the palace guard."); + stage = 64; + break; + case 64: + npc(id, "I gave the other to the wizard Traiborn."); + stage = 65; + break; + case 65: + end(); + break; + case 300: + npc(id, "Excellent! Now I can give you Silverlight."); + stage = 301; + break; + case 301: + if (player.getInventory().freeSlots() == 0) { + npc(id, "You don't have any inventory space for Silverlight."); + stage = 302; + return true; + } + close(); + player.lock(); + GameWorld.getPulser().submit(new Pulse(1, player) { + int counter = 0; + + @Override + public boolean pulse() { + switch (counter++) { + case 1: + player.getProperties().setTeleportLocation(Location.create(3204, 3470, 0)); + if (!npc.getLocation().equals(Location.create(3204, 3469, 0))) { + npc.getProperties().setTeleportLocation(Location.create(3204, 3469, 0)); + } + npc.lock(); + npc.getWalkingQueue().reset(); + npc.getPulseManager().clear(); + npc.faceLocation(Location.create(3204, 3468, 0)); + player.face(npc); + break; + case 2: + npc.animate(new Animation(4597)); + break; + case 9: + setVarp(player, 222, 5653570, true); + player.setAttribute("/save:demon-slayer:received", true); + npc.animate(new Animation(4607)); + break; + case 10: + npc.transform(4657); + break; + case 11: + npc.faceLocation(player.getLocation()); + break; + case 12: + npc.transform(883); + if (player.getInventory().remove(DemonSlayer.FIRST_KEY, DemonSlayer.SECOND_KEY, DemonSlayer.THIRD_KEY)) { + if (player.getInventory().add(DemonSlayer.SILVERLIGHT)) { + npc.animate(new Animation(4608)); + player.animate(new Animation(4604)); + quest.setStage(player, 30); + } + } + break; + case 13: + npc.getWalkingQueue().reset(); + npc.unlock(); + interpreter.sendItemMessage(DemonSlayer.SILVERLIGHT.getId(), "Sir Prysin hands you a very shiny sword."); + stage = 302; + player.unlock(); + return true; + } + return false; + } + }); + break; + case 302: + end(); + break; + case 800: + player("I don't seem to be able to reach it. I wonder if I can", "dislodge it somehow. That way it may go down into the", "sewers."); + stage = 801; + break; + case 801: + end(); + break; + } + break; + case 10: + switch (stage) { + case 0: + options("I am a mighty adventurer. Who are you?", "I'm not sure, I was hoping you could tell me.", "Gypsy Aris said I should come and talk to you."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + case 2: + handleDefault(buttonId); + break; + case 3: + player("Gypsy Aris said I should come and talk to you."); + stage = 2; + break; + } + break; + case 2: + npc(id, "Gypsy Aris? Is she still alive? I remember her from", "when I was pretty young. Well what do you need to", "talk to me about?"); + stage = 3; + break; + case 3: + options("I need to find the Silverlight.", "Yes, she is still alive."); + stage = 4; + break; + case 4: + switch (buttonId) { + case 1: + player("I need to find the Silverlight."); + stage = 40; + break; + case 2: + player("Yes, she is still alive. She lives right outside the castle!"); + stage = 50; + break; + } + break; + case 40: + npc(id, "What do you need to find that for?"); + stage = 41; + break; + case 41: + player("I need it to fight Delrith."); + stage = 42; + break; + case 42: + npc(id, "Delrith? I thought the world was rid of him, thanks to", "my great-grandfather."); + stage = 43; + break; + case 43: + options("Well, the gypsy's crystal ball seems to think otherwise.", "He's back and unfortunately I've got to deal with him."); + stage = 44; + break; + case 44: + switch (buttonId) { + case 1: + player("Well the gypsy's crystal ball seems to think otherwise."); + stage = 45; + break; + case 2: + player("He's back and unfortunately I've got to deal with him."); + stage = 48; + break; + } + break; + case 45: + npc(id, "Well if the ball says so, I'd better help you."); + stage = 46; + break; + case 46: + npc(id, "The problem is getting Silverlight."); + stage = 47; + break; + case 47: + player("You mean you don't have it?"); + stage = 60; + break; + case 48: + npc(id, "You don't look up to much. I suppose Silverlight may be", "good enough to carry you though though."); + stage = 46; + break; + case 60: + npc(id, "Oh I do have it, but it is so powerful that the king", "made me put it in a special box which needs three", "different keys to open it. That way it won't fall into the", "wrong hands."); + stage = 61; + break; + case 61: + player("And why is this a problem?"); + stage = 62; + break; + case 62: + npc(id, "I kept one of the keys. I gave the other two to other", "people for safe keeping."); + stage = 63; + break; + case 63: + npc(id, "One I gave to Rovin, the captain of the palace guard."); + stage = 64; + break; + case 64: + npc(id, "I gave the other to the wizard Traiborn."); + stage = 65; + break; + case 65: + player("Can you give me your key?"); + stage = 66; + break; + case 66: + npc(id, "Um.... ah...."); + stage = 67; + break; + case 67: + npc(id, "Well there's a problem there as well."); + stage = 68; + break; + case 68: + npc(id, "I managed to drop the key in the drain just outside the", "palace kitchen. It is just inside and I can't reach it."); + stage = 69; + break; + case 69: + player("So what does the drain lead to?"); + stage = 70; + break; + case 70: + npc(id, "It is the drain for the drainpipe running from the sink", "in the kitchen down to the palace sewers."); + stage = 71; + break; + case 71: + options("Where can I find Captain Rovin?", "Where does the wizard live?", "Well I'd better go key hunting."); + stage = 72; + break; + case 72: + switch (buttonId) { + case 1: + player("Where can I find Captain Rovin?"); + stage = 110; + break; + case 2: + player("Where does the wizard live?"); + stage = 120; + break; + case 3: + player("Well I'd better go key hunting."); + stage = 130; + break; + } + break; + case 130: + npc(id, "Ok, goodbye."); + stage = 131; + break; + case 131: + quest.setStage(player, 20); + end(); + break; + case 120: + npc(id, "Wizard Traiborn?"); + stage = 121; + break; + case 121: + npc(id, "He is one of the wizards who lives in the tower on the", "little island just south coast. I believe his", "quarters are on the first floor of the tower."); + stage = 122; + break; + case 122: + options("Where can I find Captain Rovin?", "Well I'd better go key hunting."); + stage = 123; + break; + case 123: + switch (buttonId) { + case 1: + player("Where can I find Captain Rovin?"); + stage = 110; + break; + case 2: + player("Well I'd better go key hunting."); + stage = 130; + break; + } + break; + case 110: + npc(id, "Captain Rovin lives at the top of the guards' quarters in", "the north-west wing of this palace."); + stage = 111; + break; + case 111: + options("Can you give me your key?", "Where does the wizard live?", "Well I'd better go key hunting."); + stage = 112; + break; + case 112: + switch (buttonId) { + case 1: + player("Can you give me your key?"); + stage = 66; + break; + case 2: + player("Where does the wizard live?"); + stage = 120; + break; + case 3: + player("Well I'd better go key hunting."); + stage = 130; + break; + } + break; + case 50: + npc(id, "Oh , is that the same gypsy? I would have thought she", "would have died by now. She was pretty old when I", "was a lad."); + stage = 51; + break; + case 51: + npc(id, "Anyway, what can I do for you?"); + stage = 52; + break; + case 52: + player("I need to find the Silverlight."); + stage = 40; + break; + default: + handleDefault(buttonId); + break; + } + break; + default: + handleDefault(buttonId); + break; + } + return true; + } + + /** + * Method used to handle default chat. + * @param buttonId the button id. + */ + private final void handleDefault(int buttonId) { + switch (stage) { + case 0: + if(getQuestStage(player, Quests.DEMON_SLAYER) == 100) + options("I am a mighty adventurer. Who are you?", "I'm not sure, I was hoping you could tell me.", "Hey can you give me another Silverlight"); + else + options("I am a mighty adventurer. Who are you?", "I'm not sure, I was hoping you could tell me."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + player("I am a mighty adventurer, Who are you?"); + stage = 10; + break; + case 2: + player("I'm not sure, I was hoping you could tell me."); + stage = 20; + break; + case 3: + if(hasAnItem(player, Items.SILVERLIGHT_2402).getContainer() != null) { + npc(id, "You already have Silverlight"); + stage = END_DIALOGUE; + } else { + npc("I can sell you another one for 500GP"); + stage = 30; + } break; + } + break; + case 10: + npc(id, "I am Sir Prysin. A bold and famous knight of the", "realm."); + stage = 11; + break; + case 11: + end(); + break; + case 20: + npc(id, "Well I've never met you before."); + stage = 21; + break; + case 21: + end(); + break; + case 30: + if(inInventory(player, Items.COINS_995, 500)) { + if(removeItem(player, new Item(Items.COINS_995, 500), Container.INVENTORY)) { + addItem(player, Items.SILVERLIGHT_2402, 1, Container.INVENTORY); + sendItemDialogue(player, Items.SILVERLIGHT_2402, "Sir Prysin gives you another Silverlight"); + stage = END_DIALOGUE; + } + } else { + npc(id, "Come back when you have 500GP to buy another one."); + stage = END_DIALOGUE; + } + break; + } + } + + @Override + public int[] getIds() { + return new int[] { 883, 4657 }; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/TraibornDialogue.java b/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/TraibornDialogue.java new file mode 100644 index 0000000..5ea8e36 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/TraibornDialogue.java @@ -0,0 +1,393 @@ +package content.region.misthalin.varrock.quest.demonslayer; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import content.data.Quests; + +/** + * Represents the dialogue used to handle the Traiborn NPC. + * @author 'Vexia + * @date 3/1/14 + */ +public class TraibornDialogue extends DialoguePlugin { + + /** + * Represents the bones item. + */ + private static final Item[] BONES = {new Item(526, 25), new Item(2530, 25)}; + + /** + * Represents the animation of giving the key. + */ + private static final Animation ANIMATION = new Animation(536); + + /** + * Represents the quest instance. + */ + private Quest quest; + + /** + * Constructs a new {@code TraibornDialogue} {@code Object}. + */ + public TraibornDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code TraibornDialogue} {@code Object}. + * @param player the player. + */ + public TraibornDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new TraibornDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + quest = player.getQuestRepository().getQuest(Quests.DEMON_SLAYER); + switch (quest.getStage(player)) { + case 20: + if (player.getAttribute("demon-slayer:traiborn", false)) { + npc("How are you doing finding bones?"); + stage = 380; + } else { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ello young thingummywut."); + stage = 0; + } + break; + default: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ello young thingummywut."); + stage = 0; + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (quest.getStage(player)) { + case 20: + switch (stage) { + case 0: + if (player.getInventory().containsItem(DemonSlayer.THIRD_KEY) && player.getBank().containsItem(DemonSlayer.THIRD_KEY)) { + options("What's a thingummywut?", "Teach me to be a mighty powerful wizard."); + stage = 1; + } else { + options("What's a thingummywut?", "Teach me to be a mighty powerful wizard.", "I need to get a key given to you by Sir Prysin."); + stage = 1; + } + break; + case 1: + switch (buttonId) { + case 1: + case 2: + handleDefault(buttonId); + break; + case 3: + player("I need to get a key given to you by Sir Prysin."); + stage = 300; + break; + } + break; + case 300: + npc("Sir Prysin? Who's that? What would I want his key", "for?"); + stage = 301; + break; + case 301: + player("Well, have you got any keys knocking around?"); + stage = 302; + break; + case 302: + npc("Now you come to mention it, yes I do have a key. It's", "in my special closet of valuable stuff. Now how do I get", "into that?"); + stage = 303; + break; + case 303: + npc("I sealed it using one of my magic rituals. So it would", "makes sense that another ritual would open it again."); + stage = 304; + break; + case 304: + player("So do you know what ritual to use?"); + stage = 305; + break; + case 305: + npc("Let me think a second."); + stage = 306; + break; + case 306: + npc("Yes a simple drazier style ritual should suffice. Hmm,", "main problem with that is I'll need 25 sets of bones.", "Now where am I going to get hold of something like", "that?"); + stage = 307; + break; + case 307: + options("Hmm, that's too bad. I really need that key.", "I'll get the bones for you."); + stage = 308; + break; + case 308: + switch (buttonId) { + case 1: + player("Hmm, that's too bad. I really need that key."); + stage = 330; + break; + case 2: + player("I'll get the bones for you."); + stage = 340; + break; + } + break; + case 330: + npc("Ah well, sorry I couldn't be any more help."); + stage = 331; + break; + case 331: + end(); + break; + case 340: + npc("Ooh that would be very good of you."); + stage = 341; + break; + case 341: + player("Ok I'll speak to you when I've got some bones."); + stage = 342; + break; + case 342: + player.setAttribute("/save:demon-slayer:traiborn", true); + end(); + break; + case 380: + if (player.getInventory().containsItem(BONES[0]) || player.getInventory().containsItem(BONES[1])) { + player("I have some bones."); + stage = 382; + } else { + player("I don't have all the bones yet."); + stage = 381; + } + break; + case 382: + npc("Give 'em here then."); + stage = 383; + break; + case 383: + interpreter.sendDialogue("You give Traiborn 25 sets of bones."); + stage = 384; + break; + case 384: + npc("Hurrah! That's all 25 sets of bones."); + stage = 385; + break; + case 385: + npc.animate(new Animation(4602)); + npc("Wings of dark and colour too,", "Spreading in the morning dew;", "Locked away I have a key;", "Return it now, please, unto me."); + stage = 386; + break; + case 386: + final Scenery object = new Scenery(17434, Location.create(3113, 3161, 1), 11, 1); + SceneryBuilder.add(object); + npc.faceLocation(object.getLocation()); + npc.animate(ANIMATION); + if (!player.getInventory().containsItem(BONES[0]) && !player.getInventory().containsItem(BONES[1])) { + end(); + return true; + } + if (player.getInventory().remove(BONES[0]) || player.getInventory().remove(BONES[1])) { + player.removeAttribute("demon-slayer:traiborn"); + player.getInventory().add(DemonSlayer.THIRD_KEY); + interpreter.sendItemMessage(DemonSlayer.THIRD_KEY.getId(), "Traiborn hands you a key."); + stage = 387; + } + GameWorld.getPulser().submit(new Pulse(1) { + int counter = 0; + + @Override + public boolean pulse() { + switch (counter++) { + case 5: + npc.face(player); + break; + case 7: + SceneryBuilder.remove(object); + return true; + } + return false; + } + }); + break; + case 387: + player("Thank you very much."); + stage = 388; + break; + case 388: + npc("Not a problem for a friend of Sir What's-his-face."); + stage = 389; + break; + case 389: + end(); + break; + case 381: + end(); + break; + } + break; + case 0: + switch (stage) { + default: + handleDefault(buttonId); + break; + } + break; + } + return true; + } + + /** + * Method used to handle the default button id. + * @param buttonId the button id. + */ + private final void handleDefault(int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "What's a thingummywut?", "Teach me to be a mighty and powerful wizard."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What's a thingummywut?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Teach me to be a mighty and powerful wizard."); + stage = 20; + break; + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "A thingummywut? Where? Where?"); + stage = 11; + break; + case 11: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Those pesky thingummywuts. They get everywhere.", "They leave a terrible mess too."); + stage = 12; + break; + case 12: + interpreter.sendOptions("Select an Option", "Err you just called me a thingummywut.", "Tell me what they look like and I'll mask 'em."); + stage = 13; + break; + case 13: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Err you just called me thingummywut."); + stage = 100; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Tell me what they look like and I'll mash 'em."); + stage = 120; + break; + } + break; + case 120: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Don't be ridiculous. No-one has ever seen one."); + stage = 121; + break; + case 121: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "They're invisible, or a myth, or a figment of my", "imagination. Can't remember which right now."); + stage = 122; + break; + case 122: + end(); + break; + case 100: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "You're a thingummywut? I've never seen one up close", "before. They said I was mad!"); + stage = 101; + break; + case 101: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Now you are my proof! There ARE thingummywuts in", "this tower. Now where can I find a cage big enough to", "keep you?"); + stage = 102; + break; + case 102: + interpreter.sendOptions("Select an Option", "Err I'd better be off really.", "They're right, you are mad."); + stage = 103; + break; + case 103: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Err I'd better be off really."); + stage = 110; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "They're right, you are mad."); + stage = 130; + break; + } + break; + case 130: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "That's a pity. I thought maybe they were winding me", "up."); + stage = 131; + break; + case 131: + end(); + break; + case 110: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Oh ok, have a good time, and watch out for sheep!", "They're more cunning than they look."); + stage = 111; + break; + case 111: + end(); + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Wizard eh? You don't want any truck with that sort.", "They're not to be trusted. That's what I've heard", "anyways."); + stage = 21; + break; + case 21: + interpreter.sendOptions("Select an Option", "So aren't you a wizard?", "Oh I'd better stop talking to you then."); + stage = 22; + break; + case 22: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "So aren't you a wizard?"); + stage = 40; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Oh I'd better stop talking to you then."); + stage = 60; + break; + } + break; + case 60: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Cheerio then. It was nice chatting to you."); + stage = 61; + break; + case 61: + end(); + break; + case 40: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "How dare you? Of course I'm a wizard. Now don't be", "so cheeky or I'll turn you into a frog."); + stage = 41; + break; + case 41: + end(); + break; + } + } + + @Override + public int[] getIds() { + return new int[] { 881 }; + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/WallyCutscenePlugin.java b/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/WallyCutscenePlugin.java new file mode 100644 index 0000000..190989d --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/demonslayer/WallyCutscenePlugin.java @@ -0,0 +1,79 @@ +package content.region.misthalin.varrock.quest.demonslayer; + +import core.game.activity.ActivityPlugin; +import core.game.activity.CutscenePlugin; +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.game.world.map.build.DynamicRegion; +import core.game.world.repository.Repository; +import core.net.packet.PacketRepository; +import core.net.packet.context.CameraContext; +import core.net.packet.context.CameraContext.CameraType; +import core.net.packet.out.CameraViewPacket; +import content.data.Quests; + +/** + * Represents the wally cutscene plugin. + * @author 'Vexia + * @date 3/1/14 + */ +public class WallyCutscenePlugin extends CutscenePlugin { + + /** + * Constructs a new {@code WallyCutscenePlugin} {@code Object}. + */ + public WallyCutscenePlugin() { + this(null); + } + + /** + * Constructs a new {@code WallyCutscenePlugin} {@code Object}. + * @param player the player. + */ + public WallyCutscenePlugin(final Player player) { + super("Wally cutscene"); + this.player = player; + } + + @Override + public ActivityPlugin newInstance(Player p) throws Throwable { + return new WallyCutscenePlugin(p); + } + + @Override + public void open() { + player.lock(); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.POSITION, player.getLocation().getX() + 2, player.getLocation().getY() + 3, 305, 1, 35)); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.ROTATION, player.getLocation().getX() + 10, player.getLocation().getY() + 12, 305, 1, 35)); + player.getDialogueInterpreter().open(882, Repository.findNPC(882), this); + } + + @Override + public void end() { + player.unlock(); + } + + @Override + public void fade() { + player.getQuestRepository().getQuest(Quests.DEMON_SLAYER).start(player); + player.getDialogueInterpreter().open(882, Repository.findNPC(882), this); + } + + @Override + public Location getSpawnLocation() { + return Location.create(3203, 3423, 0); + } + + @Override + public Location getStartLocation() { + return base.transform(26, 38, 0); + } + + @Override + public void configure() { + region = DynamicRegion.create(12852); + setRegionBase(); + registerRegion(region.getId()); + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/CabinBoyJenkins.java b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/CabinBoyJenkins.java new file mode 100644 index 0000000..096bbba --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/CabinBoyJenkins.java @@ -0,0 +1,112 @@ +package content.region.misthalin.varrock.quest.dragonslayer; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.game.node.entity.player.link.quest.Quest; +import content.data.Quests; + +import static core.api.ContentAPIKt.getQuestStage; + +/** + * Represents the cabin boy jenkins dialogue. + * @author 'Vexia + */ +@Initializable +public class CabinBoyJenkins extends DialoguePlugin { + /** + * Constructs a new {@code CabinBoyJenkins} {@code Object}. + */ + public CabinBoyJenkins() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code CabinBoyJenkins} {@code Object}. + * @param player the player. + */ + public CabinBoyJenkins(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new CabinBoyJenkins(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + switch (getQuestStage(player, Quests.DRAGON_SLAYER)) { + case 20: + npc("Ahoy! Whay d'ye think of yer ship then?"); + stage = 0; + break; + case 40: + case 30: + interpreter.sendDialogues(918, null, "Splice the mainsail!"); + stage = 0; + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (getQuestStage(player, Quests.DRAGON_SLAYER)) { + case 40: + case 30: + switch (stage) { + case 0: + npc("Aye aye, cap'n!"); + stage = 1; + break; + case 1: + end(); + break; + } + break; + case 20: + switch (stage) { + case 0: + player("Can you sail this ship to Crandor?"); + stage = 1; + break; + case 1: + npc("Not me, sir! I'm just an 'umble cabin boy. You'll need", "a proper cap'n."); + stage = 2; + break; + case 2: + player("Where can I find a captain?"); + stage = 3; + break; + case 3: + npc("The cap'ns round 'ere seem to be a mite scared of", "Crandor. I ask 'em why and they just say it was afore", "my time,"); + stage = 4; + break; + case 4: + end(); + npc("but there is one cap'n I reckon might 'elp. I 'eard", "there's a retired 'un who lives in Draynor Village who's", "so desperate to sail again 'ed' take any job."); + stage = 5; + break; + case 5: + npc("I can't remember 'is name, but 'e lives in Draynor", "Village an' makes rope."); + stage = 6; + break; + case 6: + end(); + break; + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 6085 }; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/CrandorMapPlugin.java b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/CrandorMapPlugin.java new file mode 100644 index 0000000..a01c968 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/CrandorMapPlugin.java @@ -0,0 +1,42 @@ +package content.region.misthalin.varrock.quest.dragonslayer; + +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.plugin.Plugin; + +/** + * Represents the crandor map creating plugin. + * @author 'Vexia + * @version 1.0 + */ +public final class CrandorMapPlugin extends UseWithHandler { + + /** + * Constructs a new {@code CrandorMapPlugin} {@code Object}. + */ + public CrandorMapPlugin() { + super(DragonSlayer.MAGIC_PIECE.getId(), DragonSlayer.MAZE_PIECE.getId(), DragonSlayer.WORMBRAIN_PIECE.getId()); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(DragonSlayer.MAGIC_PIECE.getId(), ITEM_TYPE, this); + addHandler(DragonSlayer.MAZE_PIECE.getId(), ITEM_TYPE, this); + addHandler(DragonSlayer.WORMBRAIN_PIECE.getId(), ITEM_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + if (!event.getPlayer().getInventory().containsItem(DragonSlayer.MAGIC_PIECE) || !event.getPlayer().getInventory().containsItem(DragonSlayer.MAZE_PIECE) || !event.getPlayer().getInventory().containsItem(DragonSlayer.WORMBRAIN_PIECE)) { + event.getPlayer().getPacketDispatch().sendMessage("You don't have all the map pieces yet."); + return true; + } + if (event.getPlayer().getInventory().remove(DragonSlayer.MAGIC_PIECE) && event.getPlayer().getInventory().remove(DragonSlayer.MAZE_PIECE) && event.getPlayer().getInventory().remove(DragonSlayer.WORMBRAIN_PIECE)) { + event.getPlayer().getInventory().add(DragonSlayer.CRANDOR_MAP); + event.getPlayer().getDialogueInterpreter().sendItemMessage(DragonSlayer.CRANDOR_MAP.getId(), "You put the three pieces together and assemble a map that shows the route through the reefs to Crandor."); + } + return true; + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DSChestDialogue.java b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DSChestDialogue.java new file mode 100644 index 0000000..604bfb0 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DSChestDialogue.java @@ -0,0 +1,76 @@ +package content.region.misthalin.varrock.quest.dragonslayer; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItemManager; + +/** + * Represents the dialogue plugin used for the dragon slayer chest. + * @author 'Vexia + * @version 1.0 + */ +public final class DSChestDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code DSChestDialogue} {@code Object}. + */ + public DSChestDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code DSChestDialogue} {@code Object}. + * @param player the player. + */ + public DSChestDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new DSChestDialogue(player); + } + + @Override + public boolean open(Object... args) { + interpreter.sendDialogue("As you open the chest, you notice an inscription on the lid:"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogue("Here I rest the map to my beloved home. To whoever finds it, I beg", "of you, let it be. I was honour-bound not to destroy the map piece,", "but I have used all my magical skill to keep it from being recovered."); + stage = 1; + break; + case 1: + interpreter.sendDialogue("This map leads to the lair of the beast that destroyed my home,", "devoured my family, and burned to a cinder all that I love. But", "revenge would not benefit me now, and to disturb this beast is to risk", "bringing its wrath down upon another land."); + stage = 2; + break; + case 2: + interpreter.sendDialogue("I cannot stop you from taking this map piece now, but think on this:", "if you can slay the Dragon of Crandor, you are a greater hero than", "my land ever produced. There is no shame in backing out now."); + stage = 3; + break; + case 3: + interpreter.sendItemMessage(DragonSlayer.MAGIC_PIECE.getId(), "You find a map piece in the chest."); + stage = 4; + break; + case 4: + if (!player.getInventory().add(DragonSlayer.MAGIC_PIECE)) { + GroundItemManager.create(DragonSlayer.MAGIC_PIECE, player); + } + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 3802875 }; + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DSListeners.kt b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DSListeners.kt new file mode 100644 index 0000000..20efdab --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DSListeners.kt @@ -0,0 +1,29 @@ +package content.region.misthalin.varrock.quest.dragonslayer + +import core.api.sendMessage +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.world.map.Location +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery + +class DSListeners : InteractionListener { + override fun defineListeners() { + on(Scenery.CELL_DOOR_40184, IntType.SCENERY, "open") { player, _ -> + sendMessage(player, "It's locked tight.") + return@on true + } + // Talk to Wormbrain + setDest(IntType.NPC, intArrayOf(NPCs.WORMBRAIN_745), "talk-to") { player, node -> + val npc = node.asNpc() + val p = player.asPlayer() + val dis = player.location.withinMaxnormDistance(npc.location, 1) + if (dis){ + return@setDest Location.create( p.location.x, p.location.y, 0) + } + else return@setDest Location.create( npc.location.x, npc.location.y, 0) + } + + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DSMagicDoorPlugin.java b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DSMagicDoorPlugin.java new file mode 100644 index 0000000..0501b06 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DSMagicDoorPlugin.java @@ -0,0 +1,66 @@ +package content.region.misthalin.varrock.quest.dragonslayer; + +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.plugin.Plugin; +import content.data.Quests; + +/** + * Represents the dragon slayer magic door plugin. + * @author Vexia + * + */ +public final class DSMagicDoorPlugin extends UseWithHandler { + + /** + * Represents the location to go to. + */ + private static final Location LOC = Location.create(3049, 9840, 0); + + /** + * Represents the ids of the items. + */ + private static final int[] IDS = new int[] { 301, 1791, 950, 1907 }; + + /** + * Constructs a new {@code DSMagicDoorPlugin} {@code Object}. + */ + public DSMagicDoorPlugin() { + super(301, 1791, 950, 1907); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(25115, OBJECT_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + if (player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER).getStage(player) < 20) { + return true; + } + if (player.getInventory().remove(event.getUsedItem())) { + player.getPacketDispatch().sendMessage("You put " + event.getUsedItem().getName().toLowerCase() + " into the opening in the door."); + int index = 0; + for (int i = 0; i < IDS.length; i++) { + if (IDS[i] == event.getUsedItem().getId()) { + index = i; + break; + } + } + player.getSavedData().getQuestData().getDragonSlayerItems()[index] = true; + DragonSlayer.handleMagicDoor(player, false); + } + return true; + } + + @Override + public Location getDestination(final Player player, Node node) { + return LOC; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DSNedNPC.java b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DSNedNPC.java new file mode 100644 index 0000000..4040b31 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DSNedNPC.java @@ -0,0 +1,51 @@ +package content.region.misthalin.varrock.quest.dragonslayer; + +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import content.data.Quests; + +/** + * Represents the dragon slayer npc. + * @author 'Vexia + * @version 1.0 + */ +public final class DSNedNPC extends AbstractNPC { + + /** + * Represents the NPC ids of NPCs using this plugin. + */ + private static final int[] ID = { 918 }; + + /** + * Constructs a new {@code DSNedNPC} {@code Object}. + */ + public DSNedNPC() { + super(0, null); + } + + /** + * Constructs a new {@code DSNedNPC} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + private DSNedNPC(int id, Location location) { + super(id, location); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new DSNedNPC(id, location); + } + + @Override + public boolean isHidden(final Player player) { + return player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER).getStage(player) != 30 && player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER).getStage(player) != 40; + } + + @Override + public int[] getIds() { + return ID; + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DragonSlayer.kt b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DragonSlayer.kt new file mode 100644 index 0000000..3bb325b --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DragonSlayer.kt @@ -0,0 +1,506 @@ +package content.region.misthalin.varrock.quest.dragonslayer + +import content.global.skill.agility.AgilityHandler +import content.region.misthalin.lumbridge.dialogue.DukeHoracioDialogue +import core.api.Event +import core.api.LoginListener +import core.api.getQuestStage +import core.game.component.Component +import core.game.event.EventHook +import core.game.event.PickUpEvent +import core.game.event.SpellCastEvent +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.game.world.GameWorld.Pulser +import core.game.world.map.Location +import core.game.world.map.RegionManager.getObject +import core.game.world.update.flag.context.Animation +import core.integrations.discord.Discord +import core.plugin.ClassScanner.definePlugins +import core.plugin.Initializable +import org.rs09.consts.Items +import content.data.Quests + +/** + * Represents the dragon slayer quest. + * @author Vexia - Converted to Kotlin with use of event hooks by not-Vexia + */ +@Initializable +class DragonSlayer : Quest(Quests.DRAGON_SLAYER, 18, 17, 2, 176, 0, 1, 10), LoginListener { + override fun newInstance(`object`: Any?): Quest { + definePlugins( + CrandorMapPlugin(), + DragonSlayerPlugin(), + DSMagicDoorPlugin(), + DragonSlayerCutscene(), + MazeDemonNPC(), + MazeGhostNPC(), + MazeSkeletonNPC(), + MazeZombieNPC(), + MeldarMadNPC(), + WormbrainNPC(), + ZombieRatNPC(), + DSChestDialogue(), + GuildmasterDialogue(), + ElvargNPC(), + WormbrainDialogue(), + OziachDialogue(), + NedDialogue(), + DukeHoracioDialogue() + ) + return this + } + + override fun drawJournal(player: Player, stage: Int) { + super.drawJournal(player, stage) + when (getStage(player)) { + 0 -> { + player.packetDispatch.sendString( + BLUE + "I can start this quest by speaking to the " + RED + "Guildmaster " + BLUE + "in", + 275, + 4 + 7 + ) + player.packetDispatch.sendString( + BLUE + "the " + RED + "Champions' Guild" + BLUE + " , south-west of Varrock.", + 275, + 5 + 7 + ) + player.packetDispatch.sendString( + BLUE + "I will need to be able to defeat a " + RED + "level 83 dragon.", + 275, + 6 + 7 + ) + if (player.questRepository.points < 32) { + player.packetDispatch.sendString( + BLUE + "To enter the Champions' Guild I need" + RED + " 32 Quest Points.", + 275, + 7 + 7 + ) + } else { + player.packetDispatch.sendString( + "To enter the Champions' Guild I need 32 Quest Points.", + 275, + 7 + 7 + ) + } + } + + 10 -> { + line(player, "The Guildmaster of the Champions' Guild said I could earn", 4 + 7) + line(player, "the right to wear rune armour if I went on a quest for", 5 + 7) + line(player, "Oziach, who makes the armour.", 6 + 7) + line( + player, + BLUE + "I should speak to " + RED + "Oziach" + BLUE + ", who lives by the cliffs to the", + 7 + 7 + ) + line(player, BLUE + "west of " + RED + "Edgeville.", 8 + 7) + } + + 15 -> { + line(player, "The Guildmaster of the Champions' Guild said I could earn", 4 + 7) + line(player, "the right to wear rune armour if I went on a quest for", 5 + 7) + line(player, "Oziach, who makes the armour.", 6 + 7) + line(player, "I spoke to Oziach in Edgeville. He told me to slay the", 7 + 7) + line(player, "dragon of Crandor island.", 8 + 7) + line( + player, + BLUE + "I should return to the " + RED + "Champions' Guild Guildmaster " + BLUE + "for", + 9 + 7 + ) + line(player, BLUE + "more detailed instructions.", 10 + 7) + } + + 20 -> { + line(player, "The Guildmaster of the Champions' Guild said I could earn", 4 + 7) + line(player, "the right to wear rune armour if I went on a quest for", 5 + 7) + line(player, "Oziach, who makes the armour.", 6 + 7) + line(player, "I spoke to Oziach in Edgeville. He told me to slay the", 7 + 7) + line(player, "dragon of Crandor island.", 8 + 7) + line(player, "The Champions' Guild Guildmaster gave me more detailed", 9 + 7) + line(player, "instructions.", 10 + 7) + line( + player, + BLUE + "To defeat the dragon I will need to find a " + RED + "map " + BLUE + "to Crandor, a", + 11 + 7 + ) + line( + player, + RED + "ship" + BLUE + ", a " + RED + "captain " + BLUE + "to take me there and some kind of", + 12 + 7 + ) + line(player, RED + "protection " + BLUE + "against the dragon's breath.", 13 + 7) + if (!player.inventory.containsItem(MAZE_PIECE) && !player.bank.containsItem(MAZE_PIECE)) { + line(player, BLUE + "One-third of the map is in " + RED + "Melzar's Maze" + BLUE + ", near", 14 + 7) + line(player, RED + "Rimmington" + ".", 15 + 7) + } else { + line(player, "I found the piece of the map that was hidden in Melzar's", 14 + 7) + line(player, "Maze.", 15 + 7) + } + if (!player.inventory.containsItem(MAGIC_PIECE) && !player.bank.containsItem(MAGIC_PIECE)) { + line( + player, + BLUE + "One-third of the map is hidden and only the " + RED + "Oracle " + BLUE + "on " + RED + "Ice", + 16 + 7 + ) + line(player, RED + "Mountain" + BLUE + " will know where it is.", 17 + 7) + } else { + line(player, "I found the piece of the map that was hidden beneath Ice", 16 + 7) + line(player, "Mountain.", 18 + 7) + } + if (!player.inventory.containsItem(WORMBRAIN_PIECE) && !player.bank.containsItem(WORMBRAIN_PIECE)) { + line( + player, + BLUE + "One-third of the map was stolen by a " + RED + "goblin " + BLUE + "from the", + 18 + 7 + ) + line(player, RED + "Goblin Village.", 19 + 7) + } else { + line(player, "I found the piece of the map that the goblin, Wormbrain,", 18 + 7) + line(player, "stole.", 19 + 7) + } + if (!player.inventory.containsItem(SHIELD) && !player.bank.containsItem(SHIELD)) { + line( + player, + BLUE + "I should ask the " + RED + "Duke of Lumbridge " + BLUE + "for an " + RED + "anti-", + 20 + 7 + ) + line(player, RED + "dragonbreath shield.", 21 + 7) + } else { + line(player, "The Duke of Lumbridge gave me an anti-dragonbreath", 20 + 7) + line(player, "shield.", 21 + 7) + } + if (!player.savedData.questData.getDragonSlayerAttribute("ship")) { + line( + player, + BLUE + "I should see if there is a " + RED + "ship " + BLUE + "for sale in " + RED + "Port Sarim", + 22 + 7 + ) + } else { + line(player, "I bought a ship in Port Sarim called the Lady Lumbridge.", 22 + 7) + if (!player.savedData.questData.getDragonSlayerAttribute("repaired")) { + line(player, "I need to repair the hole in bottom of the ship.", 23 + 7) + } else { + line(player, "I have repaired my ship using wooden planks and steel", 23 + 7) + line(player, "nails.", 24 + 7) + } + } + } + + 30 -> { + line(player, "The Guildmaster of the Champions' Guild said I could earn", 4 + 7) + line(player, "the right to wear rune armour if I went on a quest for", 5 + 7) + line(player, "Oziach, who makes the armour.", 6 + 7) + line(player, "I spoke to Oziach in Edgeville. He told me to slay the", 7 + 7) + line(player, "dragon of Crandor island.", 8 + 7) + line(player, "The Champions' Guild Guildmaster told me I had to find", 9 + 7) + line(player, "three pieces of a map to Crandor, a ship, a captain to take", 10 + 7) + line(player, "me there and a shield to protect me from the dragon's", 11 + 7) + line(player, "breath.", 12 + 7) + line(player, "I found the piece of the map that was hidden in Melzar's", 13 + 7) + line(player, "Maze.", 14 + 7) + line(player, "I found the piece of the map that was hidden beneath Ice", 15 + 7) + line(player, "Mountain.", 16 + 7) + line(player, "I found the piece of the map that the goblin, Wormbrain,", 17 + 7) + line(player, "stole.", 18 + 7) + line(player, "The Duke of Lumbridge gave me an anti-dragonbreath", 19 + 7) + line(player, "shield.", 20 + 7) + line(player, "I bought a ship in Port Sarim called the Lady Lumbridge", 21 + 7) + line(player, "I have repaired my ship using wooden planks and steel", 22 + 7) + line(player, "nails.", 23 + 7) + line(player, "Captain Ned from Draynor Village has agreed to sail the", 24 + 7) + line(player, "ship to Crandor for me.", 25 + 7) + line( + player, + BLUE + "Now I should go to my ship in " + RED + "Port Sarim " + BLUE + "and set sail for", + 26 + 7 + ) + line(player, RED + "Crandor" + BLUE + "!", 27 + 7) + } + + 40 -> { + line(player, "The Guildmaster of the Champions' Guild said I could earn", 4 + 7) + line(player, "the right to wear rune armour if I went on a quest for", 5 + 7) + line(player, "Oziach, who makes the armour.", 6 + 7) + line(player, "I spoke to Oziach in Edgeville. He told me to slay the", 7 + 7) + line(player, "dragon of Crandor island.", 8 + 7) + line(player, "The Champions' Guild Guildmaster told me I had to find", 9 + 7) + line(player, "three pieces of a map to Crandor, a ship, a captain to take", 10 + 7) + line(player, "me there and a shield to protect me from the dragon's", 11 + 7) + line(player, "breath.", 12 + 7) + line(player, "I found the piece of the map that was hidden in Melzar's", 13 + 7) + line(player, "Maze.", 14 + 7) + line(player, "I found the piece of the map that was hidden beneath Ice", 15 + 7) + line(player, "Mountain.", 16 + 7) + line(player, "I found the piece of the map that the goblin, Wormbrain,", 17 + 7) + line(player, "stole.", 18 + 7) + line(player, "The Duke of Lumbridge gave me an anti-dragonbreath", 19 + 7) + line(player, "shield.", 20 + 7) + if (!player.getAttribute("demon-slayer:memorize", false)) { + if (!player.inventory.containsItem(ELVARG_HEAD)) { + line(player, BLUE + "Now all I need to do is kill the " + RED + "dragon" + BLUE + "!", 21 + 7) + } else { + line( + player, + BLUE + "I have slain the dragon! Now I just need to tell " + RED + "Oziach.", + 21 + 7 + ) + } + } else { + line(player, "I have found a secret passage leading from Karamja to", 21 + 7) + line(player, "Crandor, so I no longer need to worry about finding a", 22 + 7) + line(player, "seaworthy ship and captain to take me there.", 23 + 7) + if (!player.inventory.containsItem(ELVARG_HEAD)) { + line(player, BLUE + "Now all I need to do is kill the " + RED + "dragon" + BLUE + "!", 24 + 7) + } else { + line( + player, + BLUE + "I have slain the dragon! Now I just need to tell " + RED + "Oziach.", + 24 + 7 + ) + } + } + } + + 100 -> { + line(player, "The Guildmaster of the Champions' Guild said I could earn", 4 + 7) + line(player, "the right to wear rune armour if I went on a quest for", 5 + 7) + line(player, "Oziach, who makes the armour.", 6 + 7) + line(player, "I spoke to Oziach in Edgeville. He told me to slay the", 7 + 7) + line(player, "dragon of Crandor island.", 8 + 7) + line(player, "The Champions' Guild Guildmaster told me I had to find", 9 + 7) + line(player, "three pieces of a map to Crandor, a ship, a captain to take", 10 + 7) + line(player, "me there and a shield to protect me from the dragon's", 11 + 7) + line(player, "breath.", 12 + 7) + line(player, "I found the piece of the map that was hidden in Melzar's", 13 + 7) + line(player, "Maze.", 14 + 7) + line(player, "I found the piece of the map that was hidden beneath Ice", 15 + 7) + line(player, "Mountain.", 16 + 7) + line(player, "I found the piece of the map that the goblin, Wormbrain,", 17 + 7) + line(player, "stole.", 18 + 7) + line(player, "The Duke of Lumbridge gave me an anti-dragonbreath", 19 + 7) + line(player, "shield.", 20 + 7) + line(player, "I have found a secret passage leading from Karamja to", 21 + 7) + line(player, "Crandor, so I no longer need to worry about finding a", 22 + 7) + line(player, "seaworthy ship and captain to take me there.", 23 + 7) + line(player, "I sailed to Crandor and killed the dragon. I am not a true", 24 + 7) + line(player, "champion and have proved myself worthy to wear rune", 25 + 7) + line(player, "platemail!", 26 + 7) + line(player, "QUEST COMPLETE!", 27 + 7) + line( + player, + BLUE + "I gained " + RED + "2 Quest Points" + BLUE + ", " + RED + "18,650 Strength XP" + BLUE + ", " + RED + "18,650", + 28 + 7 + ) + line(player, RED + "Defence XP " + BLUE + "and the right to wear " + RED + "rune platebodies.", 29 + 7) + } + } + } + + override fun finish(player: Player) { + super.finish(player) + player.packetDispatch.sendString("2 Quests Points", 277, 8 + 2) + player.packetDispatch.sendString("Ability to wear rune platebody", 277, 9 + 2) + player.packetDispatch.sendString("18,650 Strength XP", 277, 10 + 2) + player.packetDispatch.sendString("18,650 Defence XP", 277, 11 + 2) + player.packetDispatch.sendString("You have completed the Dragon Slayer Quest!", 277, 2 + 2) + player.packetDispatch.sendItemZoomOnInterface(ELVARG_HEAD.id, 230, 277, 3 + 2) + player.getSkills().addExperience(Skills.STRENGTH, 18650.0) + player.getSkills().addExperience(Skills.DEFENCE, 18650.0) + player.unhook(SpellCastHook) + player.unhook(PickedUpHook) + } + + override fun setStage(player: Player, stage: Int) { + super.setStage(player, stage) + if (stage == 20) { + player.hook(Event.SpellCast, SpellCastHook) + player.hook(Event.PickedUp, PickedUpHook) + } + } + + override fun login(player: Player) { + if (getQuestStage(player, this.quest) == 20) { + player.hook(Event.SpellCast, SpellCastHook) + player.hook(Event.PickedUp, PickedUpHook) + } + } + + private val SpellCastHook = object : EventHook { + override fun process(entity: Entity, event: SpellCastEvent) { + if (event.spellId == 19 && event.target != null && event.target.id == Items.MAP_PART_1536) {//telegrab + Discord.sendToOpenRSC(entity.name, "Player obtained Wormbrain piece! (Murder-Then-Telegrab)") + entity.unhook(this) + } + } + } + + private val PickedUpHook = object : EventHook { + override fun process(entity: Entity, event: PickUpEvent) { + if (event.itemId == Items.MAP_PART_1536) { + Discord.sendToOpenRSC(entity.name, "Player obtained Wormbrain piece! (Yoinked-Off-Floor)") + entity.unhook(this) + } + } + } + + companion object { + /** + * Represents the maze key given by the guildmaster. + */ + @JvmField + val MAZE_KEY = Item(1542) + + /** + * Represents the red key item. + */ + @JvmField + val RED_KEY = Item(1543) + + /** + * Represents the orange key item. + */ + @JvmField + val ORANGE_KEY = Item(1544) + + /** + * Represents the yellow key item. + */ + @JvmField + val YELLOW_KEY = Item(1545) + + /** + * Represents the blue key item. + */ + @JvmField + val BLUE_KEY = Item(1546) + + /** + * Represents the purple key item. + */ + @JvmField + val PURPLE_KEY = Item(1547) + + /** + * Represents the green key item. + */ + @JvmField + val GREEN_KEY = Item(1548) + + /** + * Represents the maze map piece. + */ + @JvmField + val MAZE_PIECE = Item(1535) + + /** + * Represents the magic door map piece. + */ + @JvmField + val MAGIC_PIECE = Item(1537) + + /** + * Represents the wormbrain piece. + */ + @JvmField + val WORMBRAIN_PIECE = Item(1536) + + /** + * Represents the anti dragon fire shield. + */ + val SHIELD = Item(1540) + + /** + * Represents the crandor map item. + */ + @JvmField + val CRANDOR_MAP = Item(1538) + + /** + * Represents the map component interface. + */ + @JvmField + val MAP_COMPONENT = Component(547) + + /** + * Represents the nails item. + */ + @JvmField + val NAILS = Item(1539, 30) + + /** + * Represents the plank item. + */ + @JvmField + val PLANK = Item(960) + + /** + * Represents the hammer item. + */ + @JvmField + val HAMMER = Item(2347) + + /** + * Represents the elvarg head item. + */ + @JvmField + val ELVARG_HEAD = Item(11279) + + /** + * Method used to handle going through the magic door. + * @param player the player. + * @param interaction the interaction. + * @return `True` if so. + */ + @JvmStatic + fun handleMagicDoor(player: Player, interaction: Boolean): Boolean { + if (!player.savedData.questData.getDragonSlayerItem("lobster") || !player.savedData.questData.getDragonSlayerItem( + "bowl" + ) || !player.savedData.questData.getDragonSlayerItem("silk") || !player.savedData.questData.getDragonSlayerItem( + "wizard" + ) + ) { + if (interaction) { + player.packetDispatch.sendMessage("You can't see any way to open the door.") + } + return true + } + player.packetDispatch.sendMessage("The door opens...") + val `object` = getObject(Location(3050, 9839, 0)) + player.faceLocation(`object`!!.location) + player.packetDispatch.sendSceneryAnimation(`object`, Animation(6636)) + Pulser.submit(object : Pulse(1, player) { + var counter = 0 + override fun pulse(): Boolean { + when (counter++) { + 4 -> AgilityHandler.walk( + player, + 0, + player.location, + if (player.location.x == 3051) Location.create(3049, 9840, 0) else Location.create( + 3051, + 9840, + 0 + ), + null, + 0.0, + null + ) + + 5 -> player.packetDispatch.sendSceneryAnimation(`object`, Animation(6637)) + 6 -> { + player.packetDispatch.sendSceneryAnimation(`object`, Animation(6635)) + return true + } + } + return false + } + }) + return true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DragonSlayerCutscene.java b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DragonSlayerCutscene.java new file mode 100644 index 0000000..b1a4fbc --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DragonSlayerCutscene.java @@ -0,0 +1,563 @@ + package content.region.misthalin.varrock.quest.dragonslayer; + +import java.util.ArrayList; +import java.util.List; + +import core.game.component.Component; +import core.game.activity.ActivityManager; +import core.game.activity.ActivityPlugin; +import core.game.activity.CutscenePlugin; +import core.game.dialogue.DialoguePlugin; +import content.global.travel.ship.Ships; +import core.game.node.entity.combat.ImpactHandler.HitsplatType; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.build.DynamicRegion; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.net.packet.PacketRepository; +import core.net.packet.context.CameraContext; +import core.net.packet.context.MinimapStateContext; +import core.net.packet.context.CameraContext.CameraType; +import core.net.packet.out.CameraViewPacket; +import core.net.packet.out.MinimapState; + + +import static core.api.ContentAPIKt.*; +import content.data.Quests; + +/** + * Represents the dragon slayer cutscene. + * @author Vexia + * + */ +public final class DragonSlayerCutscene extends CutscenePlugin { + + /** + * Represents the animation for the player to use. + */ + private static final Animation ANIMATION = new Animation(4191); + + /** + * Represents the bobbin pulse. + */ + private final BobingPulse bobinPulse = new BobingPulse(); + + /** + * Constructs a new {@code DragonSlayerCutscene} {@code Object}. + */ + public DragonSlayerCutscene() { + this(null); + } + + /** + * Constructs a new {@code DragonSlayerCutscene} {@code Object}. + * @param p the player. + */ + public DragonSlayerCutscene(final Player p) { + super("Dragon Slayer", true); + this.player = p; + } + + @Override + public ActivityPlugin newInstance(Player p) throws Throwable { + return new DragonSlayerCutscene(p); + } + + @Override + public boolean start(final Player player, final boolean login, Object... args) { + npcs.add(NPC.create(918, base.transform(39, 6, 1))); + npcs.add(NPC.create(6085, base.transform(39, 7, 1))); + for (NPC n : npcs) { + n.setWalks(false); + n.init(); + } + player.lock(); + return super.start(player, login, args); + } + + @Override + public void register() { + new DSNedDialogue().init(); + } + + @Override + public void open() { + player.lock(); + player.getDialogueInterpreter().open(918, npcs.get(0), this); + player.getLocks().unlockMovement(); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.POSITION, player.getLocation().getX() + 11, player.getLocation().getY() + 1, 190, 1, 100)); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.ROTATION, player.getLocation().getX() + 3, player.getLocation().getY(), 190, 1, 100)); + bob(new CameraContext(player, CameraType.POSITION, player.getLocation().getX() + 7, player.getLocation().getY() - 3, 250, 1, 1), new CameraContext(player, CameraType.ROTATION, player.getLocation().getX() + 4, player.getLocation().getY(), 210, 1, 1)); + } + + @Override + public void end() { + super.end(); + this.getBobinPulse().stop(); + player.getProperties().setTeleportLocation(Ships.PORT_SARIM_TO_CRANDOR.getLocation()); + player.getInterfaceManager().close(); + player.animate(ANIMATION); + player.getDialogueInterpreter().close(); + player.getDialogueInterpreter().sendDialogue("You are knocked unconscious and later awake on an ash-strewn", "beach."); + player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER).setStage(player, 40); + player.getSavedData().getQuestData().setDragonSlayerAttribute("repaired", false); + setVarp(player, 177, 8257540); + setVarp(player, 176, 8); + player.getSavedData().getQuestData().setDragonSlayerPlanks(0); + PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 0)); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.RESET, player.getLocation().getX() + 13, player.getLocation().getY() - 3, 250, 1, 100)); + player.lock(3); + } + + @Override + public Location getStartLocation() { + return base.transform(38, 5, 1); + } + + /** + * Method used to bob the camera. + * @param position the position. + * @param rotation the rotation. + */ + public void bob(final CameraContext position, final CameraContext rotation) { + PacketRepository.send(CameraViewPacket.class, position); + PacketRepository.send(CameraViewPacket.class, rotation); + if (bobinPulse.position == null || bobinPulse.rotation == null) { + GameWorld.getPulser().submit(bobinPulse); + } + bobinPulse.position = position; + bobinPulse.rotation = rotation; + } + + /** + * Represents a pulse used to bob a camera. + * @author 'Vexia + */ + public class BobingPulse extends Pulse { + + /** + * Represents if it's the alternate position. + */ + boolean alternate = false; + + /** + * Represents the position. + */ + private CameraContext position = null; + + /** + * Represents the rotation. + */ + private CameraContext rotation = null; + + /** + * Represents the counter. + */ + private int counter = 0; + + /** + * Constructs a new {@code DragonSlayerCutscene} {@code Object}. + */ + public BobingPulse() { + super(1); + } + + @Override + public boolean pulse() { + if (counter == 3) { + if (alternate) { + PacketRepository.send(CameraViewPacket.class, position); + PacketRepository.send(CameraViewPacket.class, rotation); + alternate = false; + } else { + PacketRepository.send(CameraViewPacket.class, position.transform(840)); + alternate = true; + } + counter = 0; + } + counter++; + return false; + } + } + + @Override + public Location getSpawnLocation() { + return Location.create(3047, 3203, 0); + } + + @Override + public void configure() { + region = DynamicRegion.create(7500); + setRegionBase(); + registerRegion(region.getId()); + } + + @Override + public Pulse getStartPulse() { + PacketRepository.send(MinimapState.class, new MinimapStateContext(player, getMapState())); + player.getInterfaceManager().removeTabs(getRemovedTabs()); + return new Pulse(1) { + int counter = 0; + + @Override + public boolean pulse() { + switch (counter++) { + case 1: + player.getProperties().setTeleportLocation(getStartLocation()); + break; + case 2: + player.getInterfaceManager().close(); + player.unlock(); + player.getWalkingQueue().reset(); + player.getLocks().lockMovement(1000000); + open(); + return true; + } + return false; + } + }; + } + + /** + * Gets the bobinPulse. + * @return The bobinPulse. + */ + public BobingPulse getBobinPulse() { + return bobinPulse; + } + + /** + * Represents the dialogue plugin used for the dragon slayer ned. + * @author 'Vexia + * @version 1.0 + */ + public static final class DSNedDialogue extends DialoguePlugin { + + /** + * Represents the animations used during the cutscene. + */ + private static final Animation[] ANIMATIONS = new Animation[] { new Animation(2105), new Animation(4280), new Animation(6649) }; + + /** + * Represents the fire graphics. + */ + private static final Graphics FIRE = new Graphics(453); + + /** + * Represents the quest instance. + */ + private Quest quest; + + /** + * Represents the cutscene. + */ + private CutscenePlugin cutscene; + + /** + * Represents the active fires. + */ + private List fires = new ArrayList<>(20); + + /** + * Represents if the fires are done burning. + */ + private boolean finished = false; + + /** + * Constructs a new {@code DSNedDialogue} {@code Object}. + */ + public DSNedDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code DSNedDialogue} {@code Object}. + * @param player the player. + */ + public DSNedDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new DSNedDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + quest = player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER); + if (args.length > 1) { + cutscene = ((DragonSlayerCutscene) args[1]); + npc("Ah it's good to feel that salt spray on my face once", "again!"); + stage = 500; + return true; + } + switch (quest.getStage(player)) { + case 40: + if (!player.getSavedData().getQuestData().getDragonSlayerAttribute("repaired")) { + npc("The ship's in a sorry state. You'd better fix up the hole", "in the hull before we can go anywhere."); + stage = 100; + } else { + npc("Ah, it's good to be on board a ship again! No matter", "how long I live on land, a ship will always seem better.", "Are you ready to depart?"); + stage = 0; + } + break; + case 30: + npc("Ah, it's good to be on board a ship again! No matter", "how long I live on land, a ship will always seem better.", "Are you ready to depart?"); + stage = 0; + break; + default: + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (quest.getStage(player)) { + case 40: + case 30: + switch (stage) { + case 500:/*------cutscene--------*/ + ((DragonSlayerCutscene) cutscene).bob(new CameraContext(player, CameraType.POSITION, player.getLocation().getX() + 6, player.getLocation().getY() - 3, 350, 1, 1), new CameraContext(player, CameraType.ROTATION, player.getLocation().getX() + 2, player.getLocation().getY(), 190, 1, 1)); + npc("And this is a mighty fine ship. She don't look much, but", "she handles like a dream."); + stage = 501; + break; + case 501: + ((DragonSlayerCutscene) cutscene).bob(new CameraContext(player, CameraType.POSITION, player.getLocation().getX() + 5, player.getLocation().getY() - 3, 350, 1, 1), new CameraContext(player, CameraType.ROTATION, player.getLocation().getX() + 1, player.getLocation().getY(), 350, 1, 1)); + player.face(npc); + npc.face(player); + player("How much longer until we reach Crandor?"); + stage = 502; + break; + case 502: + npc("Not long now! According to the chart, we'd be able to", "see Crandor if it wasn't for those clouds on the horizon."); + stage = 503; + break; + case 503: + player.getInterfaceManager().open(new Component(543)); + interpreter.sendPlainMessage(true, "Clouds surround the ship."); + GameWorld.getPulser().submit(new Pulse(6, player) { + @Override + public boolean pulse() { + player.getInterfaceManager().close(); + interpreter.sendDialogues(6085, null, "Looks like theres a storm coming up, cap'n. Soon we", "won't be able to see anything!"); + stage = 504; + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.POSITION, player.getLocation().getX() + 8, player.getLocation().getY() + 15, 1200, 1, 100)); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.ROTATION, player.getLocation().getX(), player.getLocation().getY(), 1200, 1, 100)); + ((DragonSlayerCutscene) cutscene).bob(new CameraContext(player, CameraType.POSITION, player.getLocation().getX() + 5, player.getLocation().getY() + 18, 1200, 1, 1), new CameraContext(player, CameraType.ROTATION, player.getLocation().getX() - 2, player.getLocation().getY(), 1200, 1, 1)); + return true; + } + }); + break; + case 504: + ((DragonSlayerCutscene) cutscene).bob(new CameraContext(player, CameraType.POSITION, player.getLocation().getX() - 2, player.getLocation().getY() + 14, 1000, 1, 1), new CameraContext(player, CameraType.ROTATION, player.getLocation().getX() - 2, player.getLocation().getY() - 50, 1000, 1, 1)); + npc("Oh, well. The weather has been so good up until now."); + stage = 505; + break; + case 505: + player.getInterfaceManager().open(new Component(545)); + GameWorld.getPulser().submit(new Pulse(2, player) { + @Override + public boolean pulse() { + player("Did you see that?"); + stage = 506; + player.getInterfaceManager().close(); + return true; + } + }); + break; + case 506: + npc("See what?"); + stage = 507; + break; + case 507: + player("I thought I saw something up above us."); + stage = 508; + break; + case 508: + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.POSITION, player.getLocation().getX() + 7, player.getLocation().getY() + 2, 400, 1, 100)); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.ROTATION, player.getLocation().getX() - 3, player.getLocation().getY(), 400, 1, 100)); + ((DragonSlayerCutscene) cutscene).bob(new CameraContext(player, CameraType.POSITION, player.getLocation().getX() + 8, player.getLocation().getY() + 5, 400, 1, 1), new CameraContext(player, CameraType.ROTATION, player.getLocation().getX() - 3, player.getLocation().getY(), 400, 1, 1)); + close(); + player.getPacketDispatch().sendPositionedGraphic(446, 70, 1, cutscene.getBase().transform(37, 5, 1)); + player.getPacketDispatch().sendPositionedGraphic(446, 70, 2, cutscene.getBase().transform(36, 5, 1)); + player.getPacketDispatch().sendPositionedGraphic(446, 70, 3, cutscene.getBase().transform(35, 5, 1)); + GameWorld.getPulser().submit(new Pulse(1, player) { + + @Override + public boolean pulse() { + // Projectile.create(, loc, id, startHeight, + // endHeight, delay, speed, angle, + // distance).send(); + fires.add(Location.create(37, 5, 1)); + fires.add(Location.create(36, 5, 1)); + fires.add(Location.create(35, 5, 1)); + return true; + } + + }); + startFires(); + npc.animate(ANIMATIONS[0]); + cutscene.getNPCS().get(1).animate(ANIMATIONS[1]); + npc("It's the dragon!"); + npc.face(player); + player.face(npc); + stage = 509; + break; + case 509: + close(); + player.getInterfaceManager().open(new Component(546)); + GameWorld.getPulser().submit(new Pulse(1, player) { + int counter = 0; + + @Override + public boolean pulse() { + switch (counter++) { + case 2: + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.POSITION, player.getLocation().getX() + 5, player.getLocation().getY() + 2, 400, 1, 100)); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.ROTATION, player.getLocation().getX() - 3, player.getLocation().getY(), 400, 1, 100)); + ((DragonSlayerCutscene) cutscene).bob(new CameraContext(player, CameraType.POSITION, player.getLocation().getX() + 7, player.getLocation().getY() + 2, 400, 1, 1), new CameraContext(player, CameraType.ROTATION, player.getLocation().getX() - 3, player.getLocation().getY(), 400, 1, 1)); + // player.getPacketDispatch().sendPositionedGraphic(446, + // 20, 1, + // cutscene.getBase().transform(39, + // 7, 1)); + player.getPacketDispatch().sendPositionedGraphic(446, 20, 2, cutscene.getBase().transform(38, 7, 1)); + player.getPacketDispatch().sendPositionedGraphic(446, 20, 1, cutscene.getBase().transform(37, 7, 1)); + player.getPacketDispatch().sendPositionedGraphic(446, 20, 2, cutscene.getBase().transform(38, 6, 1)); + player.getPacketDispatch().sendPositionedGraphic(446, 20, 1, cutscene.getBase().transform(36, 6, 1)); + fires.add(cutscene.getBase().transform(39, 7, 1)); + fires.add(cutscene.getBase().transform(38, 7, 1)); + fires.add(cutscene.getBase().transform(37, 7, 1)); + fires.add(cutscene.getBase().transform(38, 6, 1)); + fires.add(cutscene.getBase().transform(36, 6, 1)); + player.getInterfaceManager().close(); + npc.animate(ANIMATIONS[1]); + cutscene.getNPCS().get(1).animate(ANIMATIONS[0]); + break; + case 4: + cutscene.getNPCS().get(1).animate(ANIMATIONS[2]); + break; + case 5: + player.getPacketDispatch().sendPositionedGraphic(446, 20, 1, npc.getLocation()); + break; + case 6: + player.getPacketDispatch().sendPositionedGraphics(FIRE, cutscene.getNPCS().get(1).getLocation()); + cutscene.getNPCS().get(1).animate(new Animation(836)); + cutscene.getNPCS().get(1).getImpactHandler().manualHit(player, 10, HitsplatType.NORMAL); + break; + case 10: + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.POSITION, player.getLocation().getX() + 13, player.getLocation().getY() + 2, 400, 1, 40)); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.ROTATION, player.getLocation().getX() - 3, player.getLocation().getY(), 400, 1, 40)); + ((DragonSlayerCutscene) cutscene).bob(new CameraContext(player, CameraType.POSITION, player.getLocation().getX() + 2, player.getLocation().getY() + 2, 400, 1, 1), new CameraContext(player, CameraType.ROTATION, player.getLocation().getX() - 4, player.getLocation().getY(), 400, 1, 1)); + npc("We're going to sink!"); + stage = 510; + return true; + } + return false; + } + }); + break; + case 510: + player("Look! Land ahead!"); + ((DragonSlayerCutscene) cutscene).bob(new CameraContext(player, CameraType.POSITION, player.getLocation().getX() + 2, player.getLocation().getY() + 3, 350, 1, 1), new CameraContext(player, CameraType.ROTATION, player.getLocation().getX() + 70, player.getLocation().getY() - 30, 350, 1, 1)); + player.face(npc); + stage = 511; + break; + case 511: + npc.faceLocation(npc.getLocation().transform(-1, 0, 0)); + player.faceLocation(player.getLocation().transform(-1, 0, 0)); + npc("We're going to crash!"); + stage = 512; + break; + case 512: + player.setAttribute("real-end", Ships.PORT_SARIM_TO_CRANDOR.getLocation()); + player.setAttribute("cutscene:original-loc", Ships.PORT_SARIM_TO_CRANDOR.getLocation()); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.SHAKE, 4, 4, 1200, 4, 4)); + player.getDialogueInterpreter().sendPlainMessage(true, "CRASH!"); + cutscene.stop(true); + finished = true; + break; + case 0: + options("Yes, let's go!", "No, I'm not quite ready yet."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + player("Yes, let's go!"); + stage = 10; + break; + case 2: + player("No, I'm not quite ready yet."); + stage = 30; + break; + } + break; + case 30: + end(); + break; + case 10: + end(); + Ships.PORT_SARIM_TO_CRANDOR.sail(player); + GameWorld.getPulser().submit(new Pulse(17) { + @Override + public boolean pulse() { + player.getInterfaceManager().open(new Component(317)); + ActivityManager.start(player, "Dragon Slayer", false); + player.getInterfaceManager().closeOverlay(); + player.getInterfaceManager().open(new Component(317)); + return true; + } + }); + break; + case 100: + end(); + break; + case 20: + end(); + break; + } + break; + default: + break; + } + return true; + } + + /** + * Method used to start the fires. + */ + public void startFires() { + for (Location fire : fires) { + player.getPacketDispatch().sendPositionedGraphic(453, 0, 1, fire); + } + GameWorld.getPulser().submit(new Pulse(2, player) { + @Override + public boolean pulse() { + for (Location fire : fires) { + player.getPacketDispatch().sendPositionedGraphic(453, 0, 1, fire); + } + if (finished) { + return true; + } + return false; + } + + }); + } + + @Override + public int[] getIds() { + return new int[] { 918 }; + } + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DragonSlayerPlugin.java b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DragonSlayerPlugin.java new file mode 100644 index 0000000..f16658d --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DragonSlayerPlugin.java @@ -0,0 +1,461 @@ +package content.region.misthalin.varrock.quest.dragonslayer; + +import core.cache.def.impl.ItemDefinition; +import core.cache.def.impl.NPCDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.game.global.action.ClimbActionHandler; +import core.game.global.action.DoorActionHandler; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.impl.ForceMovement; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; + +import java.util.List; + +import static core.api.ContentAPIKt.*; +import content.data.Quests; + + +/** + * Represents the plugin used to handle node interactions related to dragon slayer. + * + * @author Vexia + * + */ +public final class DragonSlayerPlugin extends OptionHandler { + + /** + * Represents the hammer animation. + */ + private static final Animation HAMMER_ANIM = new Animation(3676); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(25115).getHandlers().put("option:open", this);// magic + // door. + NPCDefinition.forId(747).getHandlers().put("option:trade", this);// oziach. + SceneryDefinition.forId(2595).getHandlers().put("option:open", this);// maze + // main + // door. + // maze first floor. + SceneryDefinition.forId(32968).getHandlers().put("option:open", this); + SceneryDefinition.forId(2602).getHandlers().put("option:open", this); + SceneryDefinition.forId(2596).getHandlers().put("option:open", this);// red + // door. + SceneryDefinition.forId(1752).getHandlers().put("option:climb-up", this); + SceneryDefinition.forId(25038).getHandlers().put("option:climb-up", this);// trapdoor + // ladder + SceneryDefinition.forId(25214).getHandlers().put("option:open", this);// trapdoor + SceneryDefinition.forId(1746).getHandlers().put("option:climb-down", this);// ladder + SceneryDefinition.forId(2605).getHandlers().put("option:climb-down", this);// ladder + + // maze second floor. + SceneryDefinition.forId(2597).getHandlers().put("option:open", this);// orange + // door. + SceneryDefinition.forId(1747).getHandlers().put("option:climb-up", this); + SceneryDefinition.forId(25045).getHandlers().put("option:climb-down", this); + // maze third floor + SceneryDefinition.forId(2598).getHandlers().put("option:open", this);// yellow + // door. + // basement floor + SceneryDefinition.forId(2599).getHandlers().put("option:open", this);// blue + // door. + SceneryDefinition.forId(2600).getHandlers().put("option:open", this);// purple + // door. + SceneryDefinition.forId(2601).getHandlers().put("option:open", this);// green + // door. + SceneryDefinition.forId(2603).getHandlers().put("option:open", this);// closed + // chest. + SceneryDefinition.forId(2604).getHandlers().put("option:search", this);// search + // chest. + SceneryDefinition.forId(2604).getHandlers().put("option:close", this);// search + // chest. + SceneryDefinition.forId(1755).getHandlers().put("option:climb-up", this); + // map parts + ItemDefinition.forId(DragonSlayer.MAZE_PIECE.getId()).getHandlers().put("option:study", this); + ItemDefinition.forId(DragonSlayer.MAGIC_PIECE.getId()).getHandlers().put("option:study", this); + ItemDefinition.forId(DragonSlayer.WORMBRAIN_PIECE.getId()).getHandlers().put("option:study", this); + ItemDefinition.forId(DragonSlayer.CRANDOR_MAP.getId()).getHandlers().put("option:study", this); + // dwarv mine + SceneryDefinition.forId(2587).getHandlers().put("option:open", this); + NPCDefinition.forId(745).getHandlers().put("option:talk-to", this); + // lady lumby + SceneryDefinition.forId(25036).getHandlers().put("option:repair", this); + SceneryDefinition.forId(2589).getHandlers().put("option:repair", this); + + // crandor + SceneryDefinition.forId(25154).getHandlers().put("option:enter", this); + SceneryDefinition.forId(2606).getHandlers().put("option:open", this); + SceneryDefinition.forId(25213).getHandlers().put("option:climb", this); + SceneryDefinition.forId(25161).getHandlers().put("option:climb-over", this); + NPCDefinition.forId(742).getHandlers().put("option:attack", this); + NPCDefinition.forId(745).getHandlers().put("option:attack", this); + return this; + } + + @Override + public boolean handle(final Player player, Node node, String option) { + final Quest quest = player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER); + final int id = node instanceof Item ? ((Item) node).getId() : node instanceof Scenery ? ((Scenery) node).getId() : ((NPC) node).getId(); + switch (id) { + case 1755: + if (player.getLocation().withinDistance(Location.create(2939, 9656, 0))) { + ClimbActionHandler.climb(player, new Animation(828), Location.create(2939, 3256, 0)); + } else { + ClimbActionHandler.climbLadder(player, (Scenery) node, option); + return true; + } + break; + case 742: + if (player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER).getStage(player) == 40 && (player.getInventory().containsItem(DragonSlayer.ELVARG_HEAD))) { + player.getPacketDispatch().sendMessage("You have already slain the dragon. Now you just need to return to Oziach for"); + player.getPacketDispatch().sendMessage("your reward!"); + return true; + } + if (player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER).getStage(player) > 40) { + player.getPacketDispatch().sendMessage("You have already slain Elvarg the dragon."); + return true; + } + player.getProperties().getCombatPulse().attack(node); + player.face((Entity) node); + break; + case 25161: + if (player.getLocation().getX() >= 2847) { + ForceMovement movement = new ForceMovement(player, player.getLocation(), player.getLocation().transform(player.getLocation().getX() == 2845 ? 2 : -2, 0, 0), new Animation(839)); + movement.run(player, 10); + return true; + } + if (player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER).getStage(player) == 40 && (player.getInventory().containsItem(DragonSlayer.ELVARG_HEAD))) { + player.getPacketDispatch().sendMessage("You have already slain the dragon. Now you just need to return to Oziach for"); + player.getPacketDispatch().sendMessage("your reward!"); + return true; + } + if (player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER).getStage(player) > 40) { + player.getPacketDispatch().sendMessage("You have already slain the dragon."); + return true; + } + if (player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER).getStage(player) == 40 && !player.getInventory().containsItem(DragonSlayer.ELVARG_HEAD)) { + ForceMovement movement = new ForceMovement(player, player.getLocation(), player.getLocation().transform(player.getLocation().getX() == 2845 ? 2 : -2, 0, 0), new Animation(839)); + movement.run(player, 10); + if (player.getLocation().getX() <= 2845) { + List npcs = RegionManager.getLocalNpcs(player); + for (NPC n : npcs) { + if (n.getId() == 742) { + n.getProperties().getCombatPulse().attack(player); + return true; + } + } + } + } + break; + case 25213: + ClimbActionHandler.climb(player, new Animation(828), new Location(2834, 3258, 0)); + player.getAchievementDiaryManager().finishTask(player, DiaryType.KARAMJA, 1, 2); + break; + case 2606: + if (player.getLocation().getY() < 9600 && !player.getSavedData().getQuestData().getDragonSlayerAttribute("memorized") && player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER).getStage(player) != 100) { + player.getPacketDispatch().sendMessage("The door is securely locked."); + } else { + if (!player.getSavedData().getQuestData().getDragonSlayerAttribute("memorized")) { + player.getPacketDispatch().sendMessage("You found a secret door."); + player.getPacketDispatch().sendMessage("You remember where the secret door is for future reference."); + } + player.getAchievementDiaryManager().finishTask(player, DiaryType.KARAMJA, 1, 1); + player.getSavedData().getQuestData().setDragonSlayerAttribute("memorized", true); + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + } + break; + case 25154: + ClimbActionHandler.climb(player, new Animation(828), new Location(2833, 9658, 0)); + break; + case 25036: + case 2589: + if (player.getSavedData().getQuestData().getDragonSlayerAttribute("memorized")) { + player.getDialogueInterpreter().sendDialogue("You don't need to mess about with broken ships now that you have", "found the secret passage from Karamja."); + return true; + } + if (!player.getInventory().containsItem(DragonSlayer.NAILS)) { + player.getDialogueInterpreter().sendDialogue("You need 30 steel nails to attach the plank with."); + return true; + } + if (!player.getInventory().containsItem(DragonSlayer.PLANK)) { + player.getDialogueInterpreter().sendDialogue("You'll need to use wooden planks on this hole to patch it up."); + return true; + } + if (!player.getInventory().containsItem(DragonSlayer.HAMMER)) { + player.getDialogueInterpreter().sendDialogue("You need a hammer to force the nails in with."); + return true; + } + if (player.getInventory().remove(DragonSlayer.NAILS) && player.getInventory().remove(DragonSlayer.PLANK)) { + player.lock(2); + player.animate(HAMMER_ANIM); + player.getSavedData().getQuestData().setDragonSlayerPlanks(player.getSavedData().getQuestData().getDragonSlayerPlanks() + 1); + if (player.getSavedData().getQuestData().getDragonSlayerPlanks() < 3) { + player.getDialogueInterpreter().sendDialogue("You nail a plank over the hole, but you still need more planks to", "close the hole completely."); + } else { + player.getSavedData().getQuestData().setDragonSlayerAttribute("repaired", true); + setVarp(player, 177, 1967876); + player.getDialogueInterpreter().sendDialogue("You nail a final plank over the hole. You have successfully patched", "the hole in the ship."); + } + } + break; + case 1538: + player.getInterfaceManager().open(DragonSlayer.MAP_COMPONENT); + break; + case 745: + if (option.equals("attack")) { + player.getProperties().getCombatPulse().attack(node); + return true; + } + player.getDialogueInterpreter().open(745, ((NPC) node)); + break; + case 1535:// maze map piece. + player.getDialogueInterpreter().sendItemMessage(1535, "This is a piece of map that you found in Melzar's Maze. You will need to join it to the other two map pieces before you can see the route to Crandor."); + break; + case 1536: + player.getDialogueInterpreter().sendItemMessage(1536, "This is a piece of map that you got from Wormbrain, the goblin thief. You will need to join it to the other two map pieces before you can see the route to Crandor."); + break; + case 1537:// magic map piece. + player.getDialogueInterpreter().sendItemMessage(1537, "This is a piece of map that you found in a secret chest in the Dwarven Mine. You will need to join it to the other two map pieces before you can see the route to Crandor."); + break; + case 2587: + if (!player.getInventory().containsItem(DragonSlayer.MAGIC_PIECE) && !player.getBank().containsItem(DragonSlayer.MAGIC_PIECE)) { + player.getDialogueInterpreter().open(3802875); + } else { + player.getPacketDispatch().sendMessage("You already have the map piece."); + } + break; + case 25115:// magic door. + DragonSlayer.handleMagicDoor(player, true); + return true; + case 747:// oziach. + switch (quest.getStage(player)) { + case 100: + node.asNpc().openShop(player); + break; + case 20: + case 30: + case 40: + case 15: + case 10: + player.getDialogueInterpreter().open(((NPC) node).getId(), ((NPC) node), true); + break; + default: + player.getDialogueInterpreter().sendDialogues(((NPC) node), null, "I ain't got nothing to sell ye, adventurer. Leave me be!"); + break; + } + break; + default: + handleMelzarMaze(player, node, option, id, quest); + break; + } + return true; + } + + /** + * Method used to handle the melzar maze nodes. + * @param player the player. + * @param node the node. + * @param option the option. + * @param id the id. + * @param quest the quest. + * @return True if so. + */ + private final boolean handleMelzarMaze(final Player player, final Node node, final String option, final int id, final Quest quest) { + switch (id) { + case 2603: + player.getPacketDispatch().sendMessage("You open the chest."); + SceneryBuilder.replace(((Scenery) node), ((Scenery) node).transform(2604)); + break; + case 2605: + ClimbActionHandler.climb(player, new Animation(827), Location.create(2933, 9640, 0)); + break; + case 2604: + switch (option) { + case "search": + if (!player.getInventory().containsItem(DragonSlayer.MAZE_PIECE)) { + if (!player.getInventory().add(DragonSlayer.MAZE_PIECE)) { + GroundItemManager.create(DragonSlayer.MAZE_PIECE, player); + } + player.getDialogueInterpreter().sendItemMessage(DragonSlayer.MAZE_PIECE.getId(), "You find a map piece in the chest."); + } else { + player.getPacketDispatch().sendMessage("You find nothing in the chest."); + } + break; + case "close": + player.getPacketDispatch().sendMessage("You shut the chest."); + SceneryBuilder.replace(((Scenery) node), ((Scenery) node).transform(2603)); + break; + } + break; + case 2601:// green door. + if (!player.getInventory().containsItem(DragonSlayer.GREEN_KEY)) { + player.getPacketDispatch().sendMessage("This door is securely locked."); + } else { + player.getInventory().remove(DragonSlayer.GREEN_KEY); + player.getPacketDispatch().sendMessage("The key disintegrates as it unlocks the door."); + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + return true; + } + break; + case 2600:// purple door. + if (!player.getInventory().containsItem(DragonSlayer.PURPLE_KEY)) { + player.getPacketDispatch().sendMessage("This door is securely locked."); + } else { + player.getInventory().remove(DragonSlayer.PURPLE_KEY); + player.getPacketDispatch().sendMessage("The key disintegrates as it unlocks the door."); + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + return true; + } + break; + case 2599:// blue door. + if (!player.getInventory().containsItem(DragonSlayer.BLUE_KEY)) { + player.getPacketDispatch().sendMessage("This door is securely locked."); + } else { + player.getInventory().remove(DragonSlayer.BLUE_KEY); + player.getPacketDispatch().sendMessage("The key disintegrates as it unlocks the door."); + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + return true; + } + break; + case 2598:// yellow door. + if (!player.getInventory().containsItem(DragonSlayer.YELLOW_KEY)) { + player.getPacketDispatch().sendMessage("This door is securely locked."); + } else { + player.getInventory().remove(DragonSlayer.YELLOW_KEY); + player.getPacketDispatch().sendMessage("The key disintegrates as it unlocks the door."); + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + return true; + } + break; + case 25045: + if (player.getLocation().getDistance(new Location(2925, 3259, 1)) < 3) { + ClimbActionHandler.climb(player, new Animation(828), Location.create(2924, 3258, 0)); + return true; + } + ClimbActionHandler.climbLadder(player, (Scenery) node, option); + return true; + case 1747:// ladder with wrong spawn. + if (player.getLocation().getDistance(new Location(2940, 3256, 1)) < 3) { + ClimbActionHandler.climb(player, new Animation(828), Location.create(2940, 3256, 2)); + return true; + } + ClimbActionHandler.climbLadder(player, (Scenery) node, option); + return true; + case 25214:// trapdoor. + player.getPacketDispatch().sendMessage("The trapdoor can only be opened from below."); + break; + case 25038:// melzar's maze trapdoor ladder + ClimbActionHandler.climbLadder(player, (Scenery) node, option); + return true; + case 1752: + player.getPacketDispatch().sendMessage("The ladder is broken, I can't climb it."); + break; + case 1746: + if (player.getLocation().getDistance(Location.create(2923, 3241, 1)) < 3) { + ClimbActionHandler.climb(player, new Animation(828), Location.create(2923, 3241, 0)); + return true; + } + if (player.getLocation().getDistance(Location.create(2932, 3245, 2)) < 3) { + ClimbActionHandler.climb(player, new Animation(828), Location.create(2932, 3245, 1)); + return true; + } + ClimbActionHandler.climbLadder(player, (Scenery) node, option); + return true; + case 2596:// red door. + if (!player.getInventory().containsItem(DragonSlayer.RED_KEY)) { + player.getPacketDispatch().sendMessage("This door is securely locked."); + } else { + player.getInventory().remove(DragonSlayer.RED_KEY); + player.getPacketDispatch().sendMessage("The key disintegrates as it unlocks the door."); + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + return true; + } + break; + case 2597:// orange door. + if (!player.getInventory().containsItem(DragonSlayer.ORANGE_KEY)) { + player.getPacketDispatch().sendMessage("This door is securely locked."); + } else { + player.getInventory().remove(DragonSlayer.ORANGE_KEY); + player.getPacketDispatch().sendMessage("The key disintegrates as it unlocks the door."); + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + return true; + } + case 32968: + case 2602: + if (player.getLocation().equals(new Location(2931, 9640, 0))) { + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + return true; + } + if (player.getLocation().equals(new Location(2927, 9649, 0))) { + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + return true; + } + if (player.getLocation().equals(Location.create(2924, 9654, 0)) || player.getLocation().equals(Location.create(2938, 3252, 0))) { + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + return true; + } + player.getPacketDispatch().sendMessage("The door is locked."); + break; + case 2595: + if (player.getLocation().equals(Location.create(2940, 3248, 0))) { + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + return true; + } + if (player.getInventory().containsItem(DragonSlayer.MAZE_KEY)) { + player.getPacketDispatch().sendMessage("You use the key and the door opens."); + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + return true; + } else { + player.getPacketDispatch().sendMessage("This door is securely locked."); + } + break; + } + return true; + } + + @Override + public Location getDestination(Node node, Node n) { + if (n instanceof Scenery) { + Scenery obj = (Scenery) n; + if (obj.getId() == 25115) { + if (node.getLocation().getX() <= 3049) { + return Location.create(3049, 9840, 0); + } else { + return Location.create(3051, 9840, 0); + } + } else if (obj.getId() == 2587) { + return Location.create(3056, 9841, 0); + } + } else if (n instanceof NPC) { + NPC npc = ((NPC) n); + if (npc.getId() == 745) { + return Location.create(3012, 3188, 0); + } + } + return null; + } + + @Override + public boolean isWalk() { + return false; + } + + @Override + public boolean isWalk(final Player player, Node node) { + return !(node instanceof Item); + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DukeHoracioDSDialogue.kt b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DukeHoracioDSDialogue.kt new file mode 100644 index 0000000..e61630a --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/DukeHoracioDSDialogue.kt @@ -0,0 +1,95 @@ +package content.region.misthalin.varrock.quest.dragonslayer + +import content.region.misthalin.varrock.quest.dragonslayer.DragonSlayer +import core.game.node.entity.player.Player +import core.game.node.item.GroundItemManager +import core.game.dialogue.DialogueFile +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE + +class DukeHoracioDSDialogue(val questStage: Int) : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + + if(questStage in 20..99 && !hasShield(player!!)){ + + when(stage){ + START_DIALOGUE -> player("I seek a shield that will protect me from dragonbreath.").also { stage++ } + 1 -> npc("A knight going on a dragon quest, hmm? What", "dragon do you intend to slay?").also{ stage++ } + 2 -> player("Elvarg, the dragon of Crandor island!").also { stage++ } + 3 -> npc("Elvarg? Are you sure?").also { stage++ } + 4 -> player("Yes!").also { stage++ } + 5 -> npc("Well, you're a braver man than I!").also { stage++ } + 6 -> player("Why is everyone scared of this dragon?").also { stage++ } + 7 -> npc( + "Back in my father's day, Crandor was an important", + "city-state. Politically, it was important as Falador or", + "Varrock and its ships traded with every port." + ).also { stage++ } + + 8 -> npc( + "But, one day when I was little, all contact was lost. The", + "trading ships and diplomatic envoys just stopped", + "coming." + ).also { stage++ } + + 9 -> npc( + "I remember my father being very scared. He posted", + "lookouts on the roof to warn if the dragon was", + "approaching. All the city rulers worried that", + "Elvarg would devastate the whole continent." + ).also { stage++ } + + 10 -> player("So, are you going to give me the shield or not?").also { stage++ } + 11 -> npc( + "If you really think you're up to it then perhaps you", + "are the one who can kill this dragon." + ).also { stage++ } + + 12 -> { + if (!player!!.inventory.add(DragonSlayer.SHIELD)) { + GroundItemManager.create(DragonSlayer.SHIELD, player) + } + interpreter!!.sendItemMessage(DragonSlayer.SHIELD, "The Duke hands you a heavy orange shield.") + stage = END_DIALOGUE + } + } + + } + + else if(questStage == 20) { + + when(stage){ + START_DIALOGUE -> npc("Take care out there. If you kill it...").also { stage++ } + 1 -> npc("If you kill it, for Saradomin's sake make sure it's really","dead!").also { stage = END_DIALOGUE } + } + + } + + else if(questStage == 100 && !hasShield(player!!)){ + + when(stage){ + START_DIALOGUE -> player("I seek a shield that will protect me from dragonbreath.").also { stage++ } + 1 -> npc("A knight going on a dragon quest, hmm? What", "dragon do you intend to slay?").also { stage++ } + 2 -> player("Oh, no dragon in particular. I just feel like killing a", "dragon.").also { stage++ } + 3 -> npc("Of course. Now you've slain Elvarg, you've earned", "the right to call the shield your own!").also { stage++ } + 4 -> { + if (!player!!.inventory.add(DragonSlayer.SHIELD)) { + GroundItemManager.create(DragonSlayer.SHIELD, player) + } + interpreter!!.sendItemMessage(DragonSlayer.SHIELD, "The Duke hands you the shield.") + stage = END_DIALOGUE + } + } + + } + + else { + abandonFile() + } + } + + fun hasShield(player: Player): Boolean{ + return player.inventory.containsItem(DragonSlayer.SHIELD) || player.bank.containsItem(DragonSlayer.SHIELD) || player.equipment.containsItem( + DragonSlayer.SHIELD) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/ElvargNPC.java b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/ElvargNPC.java new file mode 100644 index 0000000..fa25a9f --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/ElvargNPC.java @@ -0,0 +1,330 @@ +package content.region.misthalin.varrock.quest.dragonslayer; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.node.entity.combat.InteractionType; +import core.game.node.entity.combat.equipment.ArmourSet; +import core.game.node.entity.combat.equipment.FireType; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItemManager; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.tools.RandomFunction; +import content.global.handlers.item.equipment.special.DragonfireSwingHandler; + +import static core.api.ContentAPIKt.calculateDragonfireMaxHit; +import content.data.Quests; + + +/** + * Represents the Elvarg npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class ElvargNPC extends AbstractNPC { + + /** + * The NPC ids of NPCs using this plugin. + */ + private static final int[] ID = { 742 }; + + /** + * Represents the animations to use. + */ + private static final Animation[] ANIMATIONS = new Animation[] { new Animation(6654), new Animation(6655) }; + + /** + * Represents the combat swing handler. + */ + private final CombatSwingHandler combatHandler = new ElvargCombatSwingHandler(); + + /** + * Constructs a new {@code ElvargNPC} {@code Object}. + */ + public ElvargNPC() { + super(0, null); + } + + /** + * Constructs a new {@code ElvargNPC} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + private ElvargNPC(int id, Location location) { + super(id, location); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new ElvargNPC(id, location); + } + + @Override + public void commenceDeath(Entity killer) { + final Direction direction = Direction.getLogicalDirection(getLocation(), killer.getLocation()); + GameWorld.getPulser().submit(new Pulse(1, this) { + @Override + public boolean pulse() { + faceLocation(getCenterLocation().transform(direction.getStepX() * 3, direction.getStepY() * 3, 0)); + return true; + } + }); + setDirection(direction); + } + + @Override + public void finalizeDeath(final Entity killer) { + super.finalizeDeath(killer); + final Scenery object = new Scenery(25202, getLocation(), getRotation()); + SceneryBuilder.add(object); + killer.faceLocation(object.getCenterLocation()); + killer.lock(); + GameWorld.getPulser().submit(new Pulse(1) { + int counter = 0; + + @Override + public boolean pulse() { + counter++; + if (counter == 1) { + killer.animate(ANIMATIONS[0]); + } else if (counter == 4) { + final Player player = ((Player) killer); + SceneryBuilder.replace(object, object.transform(25203)); + if (!player.getInventory().add(DragonSlayer.ELVARG_HEAD)) { + GroundItemManager.create(DragonSlayer.ELVARG_HEAD, player); + } + killer.animate(ANIMATIONS[1]); + killer.unlock(); + } else if (counter == 12) { + SceneryBuilder.remove(RegionManager.getObject(object.getLocation())); + return true; + } + return false; + } + + }); + } + + @Override + public CombatSwingHandler getSwingHandler(boolean swing) { + return combatHandler; + } + + @Override + public int[] getIds() { + return ID; + } + + /** + * Method used to get the rotation. + * @return the rotation. + */ + public int getRotation() { + switch (getDirection()) { + case EAST: + return 3; + case NORTH: + return 2; + case WEST: + return 1; + case SOUTH: + return 0; + default: + break; + } + return 0; + } + + @Override + public boolean isAttackable(Entity entity, CombatStyle style, boolean message) { + if (!(entity instanceof Player)) { + return super.isAttackable(entity, style, message); + } + final Player player = (Player) entity; + if (player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER).getStage(player) == 40 && (player.getInventory().containsItem(DragonSlayer.ELVARG_HEAD))) { + if(message) { + player.getPacketDispatch().sendMessage("You have already slain the dragon. Now you just need to return to Oziach for"); + player.getPacketDispatch().sendMessage("your reward!"); + } + return false; + } + if (player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER).getStage(player) > 40) { + if(message) { + player.getPacketDispatch().sendMessage("You have already slain Elvarg."); + } + return false; + } + return super.isAttackable(entity, style, message); + } + + @Override + public int getDragonfireProtection(boolean fire) { + return 0x2 | 0x4 | 0x8; + } + + /** + * Handles the Elvarg combat swing handler. + * @author Emperor + */ + static class ElvargCombatSwingHandler extends CombatSwingHandler { + + /** + * The style. + */ + private CombatStyle style = CombatStyle.RANGE; + + /** + * The melee attack animation. + */ + private static final Animation MELEE_ATTACK = new Animation(80, Priority.HIGH); + + /** + * The fire type. + */ + private final FireType fireType = FireType.FIERY_BREATH; + + /** + * The DragonFire Attack */ + private static final DragonfireSwingHandler DRAGONFIRE = new DragonfireSwingHandler(false, 60, null, true); + + /** + * Constructs a new {@Code ElvargCombatSwingHandler} {@Code CombatStyle}. + * The Combat style. + */ + public ElvargCombatSwingHandler() { + super(CombatStyle.RANGE); + } + + @Override + public void adjustBattleState(Entity entity, Entity victim, BattleState state) { + if (style == CombatStyle.RANGE) { + fireType.getTask().exec(victim, entity); + state.setStyle(null); + DRAGONFIRE.adjustBattleState(entity, victim, state); + state.setStyle(CombatStyle.RANGE); + return; + } + style.getSwingHandler().adjustBattleState(entity, victim, state); + } + + @Override + public int calculateAccuracy(Entity entity) { + // If in melee combat, calculate attackers accuracy level. + if (style == CombatStyle.MELEE) { + return style.getSwingHandler().calculateAccuracy(entity); + } + // Else calculate attackers accuracy based on their magic level. + return CombatStyle.MAGIC.getSwingHandler().calculateAccuracy(entity); + } + + @Override + public int calculateDefence(Entity victim, Entity attacker) { + // If in melee combat, calculate players defense level. + if (style == CombatStyle.MELEE) { + return style.getSwingHandler().calculateDefence(victim, attacker); + } + // Else calculate players defense against attack based on their magic level. + return CombatStyle.MAGIC.getSwingHandler().calculateDefence(victim, attacker); + } + + @Override + public int calculateHit(Entity entity, Entity victim, double modifier) { + if (style == CombatStyle.MELEE) { + return style.getSwingHandler().calculateHit(entity, victim, modifier); + } + + return calculateDragonfireMaxHit(victim, 60, false, 3, true); + } + + @Override + public InteractionType canSwing(Entity entity, Entity victim) { + if (!isProjectileClipped(entity, victim, false)) { + return InteractionType.NO_INTERACT; + } + if (victim.getCenterLocation().withinDistance(entity.getCenterLocation(), getCombatDistance(entity, victim, 9)) && super.canSwing(entity, victim) != InteractionType.NO_INTERACT) { + entity.getWalkingQueue().reset(); + return InteractionType.STILL_INTERACT; + } + return InteractionType.NO_INTERACT; + } + + @Override + public ArmourSet getArmourSet(Entity e) { + return style.getSwingHandler().getArmourSet(e); + } + + @Override + public double getSetMultiplier(Entity e, int skillId) { + return style.getSwingHandler().getSetMultiplier(e, skillId); + } + + @Override + public void impact(Entity entity, Entity victim, BattleState state) { + style.getSwingHandler().impact(entity, victim, state); + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + style = CombatStyle.RANGE; + int hit = 0; + int ticks = 1; + + if (victim.getCenterLocation().withinDistance(entity.getCenterLocation(), getCombatDistance(entity, victim, 1)) ) { + if ( RandomFunction.random(10) < 7 ){ + style = CombatStyle.MELEE; + } + } else { + ticks += (int) Math.ceil(entity.getLocation().getDistance(victim.getLocation()) * 0.3); + } + + state.setStyle(style); + + if (isAccurateImpact(entity, victim)) { + int max = calculateHit(entity, victim, 1.0); + state.setMaximumHit(max); + hit = RandomFunction.random(max + 1); + } + state.setEstimatedHit(hit); + return ticks; + } + + @Override + public void visualize(Entity entity, Entity victim, BattleState state) { + switch (style) { + case MELEE: + entity.animate(MELEE_ATTACK); + break; + case RANGE: + Projectile.ranged(entity, victim, 450, 20, 36, 50, 15).send(); + entity.animate(fireType.getAnimation()); + break; + default: + break; + } + } + + @Override + public void visualizeImpact(Entity entity, Entity victim, BattleState state) { + if (style != CombatStyle.MELEE) { + DRAGONFIRE.visualizeImpact(entity, victim, state); + } else { + style.getSwingHandler().visualizeImpact(entity, victim, state); + } + } + + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/GuildmasterDialogue.java b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/GuildmasterDialogue.java new file mode 100644 index 0000000..a94d7ba --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/GuildmasterDialogue.java @@ -0,0 +1,492 @@ +package content.region.misthalin.varrock.quest.dragonslayer; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.GroundItemManager; +import content.data.Quests; + +/** + * Represents the guild master dialogue at the champions guild related to dragon slayer. + * @author Vexia + * + */ +public final class GuildmasterDialogue extends DialoguePlugin { + + /** + * Represents the quest instance. + */ + private Quest quest; + + /** + * Constructs a new {@code GuildmasterDialogue} {@code Object}. + */ + public GuildmasterDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code GuildmasterDialogue} {@code Object}. + * @param player the player. + */ + public GuildmasterDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new GuildmasterDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + if (player.getQuestRepository().getPoints() < 32) { + return true; + } + quest = player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER); + npc("Greetings!"); + if (quest.getStage(player) == 10) { + stage = 0; + } else { + stage = 1; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (quest.getStage(player)) { + case 30: + end(); + break; + case 40: + end(); + break; + case 100: + switch (stage) { + case 1: + options("What is this place?", "Can I have another key to Melzar's Maze?"); + stage = 2; + break; + case 2: + switch (buttonId) { + case 1: + handleDescription(buttonId); + break; + case 2: + player("Can I have another key to Melzar's Maze?"); + stage = 20; + break; + } + break; + case 99: + end(); + break; + case 20: + if (!player.getInventory().containsItem(DragonSlayer.MAZE_KEY) && !player.getBank().containsItem(DragonSlayer.MAZE_KEY)) { + if (!player.getInventory().add(DragonSlayer.MAZE_KEY)) { + GroundItemManager.create(DragonSlayer.MAZE_KEY, player); + } + interpreter.sendItemMessage(DragonSlayer.MAZE_KEY.getId(), "The Guildmaster hands you a key."); + stage = 21; + break; + } + npc("I think you've already got a key."); + stage = 21; + break; + case 21: + end(); + break; + } + break; + case 20: + switch (stage) { + case 1: + player("About my quest to kill the dragon..."); + stage = 2; + break; + case 2: + npc("If you're serious about taking on Elvarg, first you'll", "need to get to Crandor. The island is surrounded by", "dangerous reefs, so you'll need a ship capable of getting", "through them and a map to show you the way."); + stage = 3; + break; + case 3: + npc("When you reach Crandor, you'll also need some kind of", "protection against the dragon's breath."); + stage = 18; + break; + case 18: + options("How can I find the route to Crandor?", "Where can I find the right ship?", "How can I protect myself from the dragon's breath?", "What's so special about this dragon?", "Okay, I'll get going."); + stage = 19; + break; + case 19: + switch (buttonId) { + case 1: + player("How can I find the route to Crandor?"); + stage = 100; + break; + case 2: + player("Where can I find the right ship?"); + stage = 110; + break; + case 3: + player("How can I protect myself from the dragon's breath?"); + stage = 120; + break; + case 4: + player("What's so special about this dragon?"); + stage = 130; + break; + case 5: + player("Okay, I'll get going."); + stage = 140; + break; + } + break; + case 100: + npc("Only one map exists that shows the route through the", "reefs of Crandor. That map was split into three pieces", "by Melzar, Thalzar and Lozar, the wizards who escaped", "from the dragon. Each of them took one piece."); + stage = 101; + break; + case 101: + options("Where is Melzar's map piece?", "Where is Thalzar's map piece?", "Where is Lozar's map piece?"); + stage = 102; + break; + case 102: + switch (buttonId) { + case 1: + player("Where is Melzar's map piece?"); + stage = 1000; + break; + case 2: + player("Where is Thalzar's map piece?"); + stage = 1020; + break; + case 3: + player("Where is Lozar's map piece?"); + stage = 1030; + break; + } + break; + case 1000: + npc("Melzar built a castle on the site of the Crandorian", "refugee camp, north of Rimmington. He's locked himself", "in there and no one's seen him for years."); + stage = 1001; + break; + case 1001: + npc("The inside of his castle is like a maze, and is populated", "by undead monsters. Maybe, if you could get all the", "way through the maze, you could find his piece of the", "map."); + if (player.getInventory().containsItem(DragonSlayer.MAZE_KEY) || player.getBank().containsItem(DragonSlayer.MAZE_KEY)) { + stage = 1004; + return true; + } + stage = 1002; + break; + case 1002: + npc("Adventurers sometimes go in there to prove themselves,", "so I can give you this key to Melzar's Maze."); + stage = 1003; + break; + case 1003: + if (!player.getInventory().add(DragonSlayer.MAZE_KEY)) { + GroundItemManager.create(DragonSlayer.MAZE_KEY, player); + } + interpreter.sendItemMessage(DragonSlayer.MAZE_KEY.getId(), "The Guildmaster hands you a key."); + stage = 1004; + break; + case 1004: + end(); + break; + case 1020: + npc("Thalzar was the most paranoid of the three wizards. He", "hid his map piece and took the secret of its location to", "his grave."); + stage = 1021; + break; + case 1021: + npc("I don't think you'll be able to find out where it is by", "ordinary means. You'll need to talk to the Oracle on", "Ice Mountain."); + stage = 1022; + break; + case 1022: + end(); + break; + case 1030: + npc("A few weeks ago, I'd have told you to speak to Lozar", "herself, in her house across the river from Lumbridge."); + stage = 1031; + break; + case 1031: + npc("Unfortunately, goblin raiders killed her and stole", "everything. One of the goblins from the Goblin Village", "probably has the map piece now."); + stage = 1032; + break; + case 1032: + end(); + break; + case 110: + npc("Even if you find the right route, only a ship made to", "the old crandorian design would be able to navigate", "through the reefs to the island."); + stage = 111; + break; + case 111: + npc("If there's still one in existence, it's probably in Port", "Sarim."); + stage = 112; + break; + case 112: + npc("Then, of course, you'll need to find a captain willing to", "sail to Crandor, and I'm not sure where you'd find one", "of them!"); + stage = 113; + break; + case 113: + end(); + break; + case 120: + npc("That part shouldn't be too different, actually. I believe", "the Duke of Lumbridge has a special shield in his", "armoury that is enchanted against dragon's breath."); + stage = 121; + break; + case 121: + end(); + break; + case 130: + npc("Thirty years ago, Candor was a thriving community", "with a great tradition of mages and adventurers. Many", "Crandorians even earned the right to be part of the", "Champions' Guild!"); + stage = 131; + break; + case 131: + npc("One of their adventurers went too far, however. He", "descended into the volcano in the centre of Crandor", "and woke the dragon Elvarg."); + stage = 132; + break; + case 132: + npc("He must have fought valiantly against the dragon", "because they say that, to this day, she has a scar down", "her side,"); + stage = 133; + break; + case 133: + npc("but the dragon still won the fight. She emerged and laid", "waste to the whole of Crandor with her fire breath!"); + stage = 134; + break; + case 134: + npc("Some refugees managed to escape in fishing boats.", "They landed on the coast, north of Rimmington, and", "set up camp but the dragon followed them and burned", "the camp to the ground."); + stage = 135; + break; + case 135: + npc("Out of all the people of Crandor there were only three", "survivors: a trio of wizards who used magic to escape.", "Their names were Thalzar, Lozar and Melzar."); + stage = 140; + break; + case 136: + npc("If you're serious about taking on Elvarg, first you'll", "need to get to Crandor. The island is surrounded by", "dangerous reefs, so you'll need a ship capable of getting", "through them and a map to show you the way."); + stage = 17; + break; + case 140: + end(); + break; + case 99: + end(); + break; + } + break; + case 15: + switch (stage) { + case 1: + options("What is this place?", "I talked to Oziach..."); + stage = 2; + break; + case 2: + switch (buttonId) { + case 1: + handleDescription(buttonId); + break; + case 2: + player("I talked to Oziach and he gave me a quest."); + stage = 3; + break; + } + break; + case 3: + npc("Oh? What did he tell you to do?"); + stage = 4; + break; + case 4: + player("Defeat the dragon of Crandor."); + stage = 5; + break; + case 5: + npc("The dragon of Crandor?"); + stage = 7; + break; + case 7: + player("Um, yes..."); + stage = 8; + break; + case 8: + npc("Goodness, he hasn't given you an easy job, has he?"); + stage = 9; + break; + case 9: + player("What's so special about this dragon?"); + stage = 10; + break; + case 10: + npc("Thirty years ago, Crandor was a thriving community", "with a great tradition of mages and adventurers. Many", "Crandorians even earned the right to be part of the", "Champion's Guild!"); + stage = 11; + break; + case 11: + npc("One of their adventurers went too far, however. He", "descended into the volcano in the centre of Crandor", "and woke the dragon Elvarg."); + stage = 12; + break; + case 12: + npc("He must have fought valiantly against the dragon", "because they say that, to this day, she has a scar down", "her side,"); + stage = 13; + break; + case 13: + npc("but the dragon still won the fight. She emerged and laid", "waste to the whole of Crandor with her fire breath!"); + stage = 14; + break; + case 14: + npc("Some refugees managed to escape in fishing boats.", "They landed on the coast, north of Rimmington, and", "set up camp but the dragon followed them and burned", "the camp to the ground."); + stage = 15; + break; + case 15: + npc("Out of all the people of Crandor there were only three", "surviors: a trio of wizards who used the magic to escape.", "Their names were Thalzar, Lozar and Melzar."); + stage = 16; + break; + case 16: + npc("If you're serious about taking on Elvarg, first you'll", "need to get to Crandor. The island is surrounded by", "dangerous reefs, so you'll need a ship capable of getting", "through them and a map to show you the way."); + stage = 17; + break; + case 17: + npc("When you reach Crandor, you'll also need some kind of", "protection against the dragon's breath."); + stage = 19; + break; + case 19: + player("Okay, I'll get going."); + stage = 20; + break; + case 20: + quest.setStage(player, 20); + end(); + break; + case 99: + end(); + break; + } + break; + case 10: + switch (stage) { + case 18: + end(); + break; + case 0: + npc("Have you gone to talk to Oziach yet?"); + stage = 1; + break; + case 1: + player("No, not yet."); + stage = 2; + break; + case 2: + npc("You can only begin your journey once you've", "spoken to Oziach who is located near Edgeville."); + stage = 3; + break; + case 3: + player("Okay, thanks."); + stage = 4; + break; + case 4: + end(); + break; + } + break; + case 0: + switch (stage) { + case 1: + options("What is this place?", "Can I have a quest?"); + stage = 10; + break; + case 10: + switch (buttonId) { + case 1: + handleDescription(buttonId); + break; + case 2: + player("Can I have a quest?"); + stage = 13; + break; + } + break; + case 11: + if (quest.getStage(player) == 10) { + npc("You're already on a quest for me, if I recall correctly.", "Have you talked to Oziach yet?"); + stage = 20; + return true; + } + npc("This is the Champions' Guild. Only adventurers who", "have proved themselves worthy by gaining influence", "from quests are allowed in here."); + stage = 12; + break; + case 12: + end(); + break; + case 13: + npc("Aha!"); + stage = 14; + break; + case 14: + npc("Yes! A mighty and perilous quest fit only for the most", "powerful champion! And, at the end of it, you will earn", "the right to wear the legendary rune platebody!"); + stage = 15; + break; + case 15: + player("So, what is this quest?"); + stage = 16; + break; + case 16: + npc("You'll have to speak to Oziach, the maker of rune", "armour. He sets the quests that champions must", "complete in order to wear it."); + stage = 17; + break; + case 17: + npc("Oziach lives in a hut, by the cliffs to the west of", "Edgeville. he can be a little...odd...sometimes, though."); + stage = 18; + quest.start(player); + break; + case 18: + end(); + break; + case 20: + player("No, not yet."); + stage = 21; + break; + case 21: + npc("Well, he's the only one who can grant you the right to", "wear rune platemail. He lives in a hut, by the cliffs west", "of Edgeville."); + stage = 22; + break; + case 22: + player("Okay, I'll go and talk to him."); + stage = 23; + break; + case 23: + end(); + break; + case 99: + end(); + break; + } + break; + } + return true; + } + + /** + * Method used to handle the description. + * @param buttonId the id. + */ + public void handleDescription(int buttonId) { + switch (buttonId) { + case 1: + if (quest.getStage(player) == 10) { + npc("You're already on a quest for me, if I recall correctly.", "Have you talked to Oziach yet?"); + stage = 20; + return; + } + npc("This is the Champions' Guild. Only adventurers who", "have proved themselves worthy by gaining influence", "from quests are allowed in here."); + stage = 99; + break; + case 2: + end(); + break; + } + } + + @Override + public int[] getIds() { + return new int[] { 198 }; + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/MazeDemonNPC.java b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/MazeDemonNPC.java new file mode 100644 index 0000000..3e4a92a --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/MazeDemonNPC.java @@ -0,0 +1,62 @@ +package content.region.misthalin.varrock.quest.dragonslayer; + +import core.game.node.entity.Entity; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItemManager; +import core.game.world.map.Location; + +/** + * Represents the lesser demon maze npc. + * @author 'Vexia + * @version 1.0 + */ +public final class MazeDemonNPC extends AbstractNPC { + + /** + * The NPC ids of NPCs using this plugin. + */ + private static final int[] ID = { 82 }; + + /** + * Represents the location to be near to count as a maze npc. + */ + private final static Location LOCATION = Location.create(2936, 9652, 0); + + /** + * Constructs a new {@code AlKharidWarriorPlugin} {@code Object}. + */ + public MazeDemonNPC() { + super(0, null); + } + + /** + * Constructs a new {@code MazeDemonNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + private MazeDemonNPC(int id, Location location) { + super(id, location); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new MazeDemonNPC(id, location); + } + + @Override + public void finalizeDeath(final Entity killer) { + super.finalizeDeath(killer); + if (killer.getLocation().withinDistance(LOCATION)) { + if (killer instanceof Player) { + GroundItemManager.create(DragonSlayer.GREEN_KEY, getLocation(), ((Player) killer)); + } + } + } + + @Override + public int[] getIds() { + return ID; + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/MazeGhostNPC.java b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/MazeGhostNPC.java new file mode 100644 index 0000000..497cad9 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/MazeGhostNPC.java @@ -0,0 +1,65 @@ +package content.region.misthalin.varrock.quest.dragonslayer; + +import core.game.node.entity.Entity; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItemManager; +import core.game.world.map.Location; +import core.tools.RandomFunction; + +/** + * Represents a ghosts in melzar's maze. + * @author 'Vexia + * @version 1.0 + */ +public final class MazeGhostNPC extends AbstractNPC { + + /** + * The NPC ids of NPCs using this plugin. + */ + private static final int[] ID = { 103 }; + + /** + * Represents the location to be near. + */ + private static final Location LOCATION = Location.create(2926, 3253, 1); + + /** + * Constructs a new {@code MazeGhostNPC} {@code Object}. + */ + public MazeGhostNPC() { + super(0, null); + } + + /** + * Constructs a new {@code MazeGhostNPC} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + private MazeGhostNPC(int id, Location location) { + super(id, location); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new MazeGhostNPC(id, location); + } + + @Override + public void finalizeDeath(final Entity killer) { + super.finalizeDeath(killer); + if (killer.getLocation().withinDistance(LOCATION)) { + if (killer instanceof Player) { + if (RandomFunction.random(0, 4) == 2) { + GroundItemManager.create(DragonSlayer.ORANGE_KEY, getLocation(), ((Player) killer)); + } + } + } + } + + @Override + public int[] getIds() { + return ID; + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/MazeSkeletonNPC.java b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/MazeSkeletonNPC.java new file mode 100644 index 0000000..55afb35 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/MazeSkeletonNPC.java @@ -0,0 +1,65 @@ +package content.region.misthalin.varrock.quest.dragonslayer; + +import core.game.node.entity.Entity; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItemManager; +import core.game.world.map.Location; +import core.tools.RandomFunction; + +/** + * Represents a skeleton in melzars maze. + * @author 'Vexia + * @version 1.0 + */ +public final class MazeSkeletonNPC extends AbstractNPC { + + /** + * The NPC ids of NPCs using this plugin. + */ + private static final int[] ID = { 90 }; + + /** + * Represents the location to be near to count as a maze npc. + */ + private static Location LOCATION = Location.create(2927, 3253, 2); + + /** + * Constructs a new {@code MazeSkeletonNPC} {@code Object}. + */ + public MazeSkeletonNPC() { + super(0, null); + } + + /** + * Constructs a new {@code MazeSkeletonNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + private MazeSkeletonNPC(int id, Location location) { + super(id, location); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new MazeSkeletonNPC(id, location); + } + + @Override + public void finalizeDeath(final Entity killer) { + super.finalizeDeath(killer); + if (killer.getLocation().withinDistance(LOCATION)) { + if (killer instanceof Player) { + if (RandomFunction.random(0, 5) == 2) { + GroundItemManager.create(DragonSlayer.YELLOW_KEY, getLocation(), ((Player) killer)); + } + } + } + } + + @Override + public int[] getIds() { + return ID; + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/MazeZombieNPC.java b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/MazeZombieNPC.java new file mode 100644 index 0000000..950927e --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/MazeZombieNPC.java @@ -0,0 +1,65 @@ +package content.region.misthalin.varrock.quest.dragonslayer; + +import core.game.node.entity.Entity; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItemManager; +import core.game.world.map.Location; +import core.tools.RandomFunction; + +/** + * Represents a skeleton in melzars maze. + * @author 'Vexia + * @version 1.0 + */ +public final class MazeZombieNPC extends AbstractNPC { + + /** + * The NPC ids of NPCs using this plugin. + */ + private static final int[] ID = { 75 }; + + /** + * Represents the location to be near. + */ + private final static Location LOCATION = Location.create(2933, 9641, 0); + + /** + * Constructs a new {@code MazeZombieNPC.java} {@code Object}. + */ + public MazeZombieNPC() { + super(0, null); + } + + /** + * Constructs a new {@code MazeZombieNPC} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + private MazeZombieNPC(int id, Location location) { + super(id, location); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new MazeZombieNPC(id, location); + } + + @Override + public void finalizeDeath(final Entity killer) { + super.finalizeDeath(killer); + if (killer.getLocation().withinDistance(LOCATION)) { + if (killer instanceof Player) { + if (RandomFunction.random(0, 3) == 2) { + GroundItemManager.create(DragonSlayer.BLUE_KEY, getLocation(), ((Player) killer)); + } + } + } + } + + @Override + public int[] getIds() { + return ID; + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/MeldarMadNPC.java b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/MeldarMadNPC.java new file mode 100644 index 0000000..2b731c0 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/MeldarMadNPC.java @@ -0,0 +1,204 @@ +package content.region.misthalin.varrock.quest.dragonslayer; + +import core.game.node.entity.skill.Skills; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.spell.CombatSpell; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.node.entity.combat.DeathTask; +import core.game.node.entity.combat.InteractionType; +import core.game.node.entity.combat.equipment.ArmourSet; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.SpellBookManager; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.tools.RandomFunction; + +/** + * Represents the medlar the mad npc. + * @author 'Vexia + * @version 1.0 + */ +public final class MeldarMadNPC extends AbstractNPC { + + /** + * The NPC ids of NPCs using this plugin. + */ + private static final int[] ID = { 753 }; + + /** + * Represents the cabbage npc. + */ + public static final Item CABBAGE = new Item(1965); + + /** + * Represents the messages to say when fighting. + */ + public static final String[] MESSAGES = new String[] { "Feel the wrath of my feet!", "By the power of custard!", "Let me drink my tea in peace.", "Leave me alone, I need to feed my pet rock." }; + + /** + * Represents the swing handler. + */ + private final MeldarSwingHandler combatHandler = new MeldarSwingHandler(); + + /** + * Constructs a new {@code MeldarMadNPC} {@code Object}. + */ + public MeldarMadNPC() { + super(0, null); + } + + /** + * Constructs a new {@code MeldarMadNPC} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + private MeldarMadNPC(int id, Location location) { + super(id, location); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new MeldarMadNPC(id, location); + } + + @Override + public void init() { + super.init(); + getSkills().setLevel(Skills.MAGIC, 40); + getSkills().setLevel(Skills.ATTACK, 30); + getSkills().setLevel(Skills.STRENGTH, 35); + getSkills().setLevel(Skills.DEFENCE, 10); + } + + @Override + public void handleTickActions() { + super.handleTickActions(); + if (!DeathTask.isDead(this) && getProperties().getCombatPulse().isAttacking() && RandomFunction.random(0, 4) == 1) { + sendChat(MESSAGES[RandomFunction.random(MESSAGES.length)]); + } + } + + @Override + public void finalizeDeath(final Entity killer) { + super.finalizeDeath(killer); + GroundItemManager.create(DragonSlayer.PURPLE_KEY, getLocation(), ((Player) killer)); + } + + @Override + public CombatSwingHandler getSwingHandler(boolean swing) { + return combatHandler; + } + + @Override + public int[] getIds() { + return ID; + } + + /** + * Represents the combat swing handler for meldar the mad npc. + * @author 'Vexia + */ + public class MeldarSwingHandler extends CombatSwingHandler { + + /** + * Represents the style to use. + */ + private CombatStyle style = CombatStyle.MAGIC; + + /** + * Represents the spell ids. + */ + private final int SPELL_IDS[] = new int[] { 8, 2, 7, 11 }; + + /** + * Constructs a new {@code MeldarMapNPC} {@code Object}. + */ + public MeldarSwingHandler() { + super(CombatStyle.MAGIC); + } + + @Override + public InteractionType canSwing(Entity entity, Entity victim) { + return getType().getSwingHandler().canSwing(entity, victim); + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + if (RandomFunction.random(5) == 3) { + style = CombatStyle.MELEE; + } else { + style = CombatStyle.MAGIC; + } + return 2; + } + + @Override + public void visualize(Entity entity, Entity victim, BattleState state) { + if (style == CombatStyle.MAGIC) { + state.setSpell(getCombatSpell()); + for (int i = 0; i < 2; i++) { + Location l = getLocation().transform(RandomFunction.random(1, 5), RandomFunction.random(1, 5), 0); + if (RegionManager.isTeleportPermitted(l) && GroundItemManager.get(CABBAGE.getId(), l, null) == null && l.getY() <= 9651 && l.getY() >= 9644) { + if (victim instanceof Player) + ((Player) victim).getPacketDispatch().sendPositionedGraphic(86, 1, 0, l); + GroundItemManager.create(CABBAGE, l, ((Player) victim)); + } + } + } + style.getSwingHandler().visualize(entity, victim, state); + } + + @Override + public void visualizeImpact(Entity entity, Entity victim, BattleState state) { + style.getSwingHandler().visualizeImpact(entity, victim, state); + } + + @Override + public void adjustBattleState(Entity entity, Entity victim, BattleState state) { + style.getSwingHandler().adjustBattleState(entity, victim, state); + } + + @Override + public int calculateAccuracy(Entity entity) { + return style.getSwingHandler().calculateAccuracy(entity); + } + + @Override + public int calculateDefence(Entity victim, Entity attacker) { + return style.getSwingHandler().calculateDefence(victim, attacker); + } + + @Override + public int calculateHit(Entity entity, Entity victim, double modifier) { + return style.getSwingHandler().calculateHit(entity, victim, modifier); + } + + @Override + public void impact(Entity entity, Entity victim, BattleState state) { + style.getSwingHandler().impact(entity, victim, state); + } + + @Override + public ArmourSet getArmourSet(Entity e) { + return style.getSwingHandler().getArmourSet(e); + } + + @Override + public double getSetMultiplier(Entity e, int skillId) { + return style.getSwingHandler().getSetMultiplier(e, skillId); + } + + /** + * Method used to get a combat spell. + * @return the spell. + */ + public CombatSpell getCombatSpell() { + return ((CombatSpell) SpellBookManager.SpellBook.MODERN.getSpell(SPELL_IDS[RandomFunction.random(SPELL_IDS.length)])); + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/NedDSDialogue.kt b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/NedDSDialogue.kt new file mode 100644 index 0000000..7b59f9c --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/NedDSDialogue.kt @@ -0,0 +1,107 @@ +package content.region.misthalin.varrock.quest.dragonslayer + +import core.game.dialogue.DialogueFile +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import content.data.Quests + +private const val SHIP_DIALOGUE = 2000 +class NedDSDialogue(val questStage: Int) : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + + if(stage >= SHIP_DIALOGUE){ + when(stage){ + SHIP_DIALOGUE -> { + if (player!!.getSavedData().questData.getDragonSlayerAttribute("ship")) { + player("It's the Lady Lumbridge, in Port Sarim.") + stage++ + } else { + player("I'm still looking...") + stage = END_DIALOGUE + } + } + + //It's the lady lumbridge + 2001 -> npc("That old pile of junk? Last I heard, she wasn't", "seaworthy.").also { stage++ } + 2002 -> { + stage = if (player!!.savedData.questData.getDragonSlayerAttribute("repaired")) { + player("I fixed her up!") + stage + 1 + } else { + player("Oh, I better go inspect her.") + END_DIALOGUE + } + } + + //I fixed her up + 2003 -> npc("You did? Excellent!").also { stage++ } + 2004 -> npc("Just show me the map and we can get ready to go!").also { stage++ } + 2005 -> { + if (player!!.inventory.containsItem(DragonSlayer.CRANDOR_MAP)) { + player("Here you go.") + stage++ + } else { + player!!.packetDispatch.sendMessage("You don't have the map to Crandor.") + stage = END_DIALOGUE + } + } + + 2006 -> { + if (player!!.inventory.remove(DragonSlayer.CRANDOR_MAP)) { + interpreter!!.sendItemMessage(DragonSlayer.CRANDOR_MAP.id, "You hand the map to Ned.") + player!!.questRepository.getQuest(Quests.DRAGON_SLAYER).setStage(player, 30) + stage++ + } else stage = END_DIALOGUE + } + + 2007 -> npc("Excellent! I'll meet you at the ship, then.").also { stage = END_DIALOGUE } + } + } + + else if(questStage == 20 && player!!.savedData.questData.getDragonSlayerAttribute("ned")){ + when(stage){ + START_DIALOGUE -> player("Will you take me to Crandor now, then?").also{ stage++ } + 1 -> npc("I Said I would and old Ned is a man of his word!").also { stage++ } + 2 -> npc("So, where's your ship?").also { stage = SHIP_DIALOGUE } + } + } + + else if(questStage == 20){ + when(stage){ + START_DIALOGUE -> player("You're a sailor? Could you take me to Crandor?").also { stage++ } + 1 -> npc( + "Well, I was a sailor. I've not been able to get work at", + "sea these days, though. They say I'm too old." + ).also { stage++ } + + 2 -> npc("Sorry, where was it you said you wanted to go?").also { stage++ } + 3 -> player("To the island of Crandor.").also { stage++ } + 4 -> npc("Crandor? You've got to be out of your mind!").also { stage++ } + 5 -> npc( + "But... It would be a chance to sail a ship once more.", + "I'd sail anywhere if it was a chance to sail again." + ).also { stage++ } + + 6 -> npc("Then again, no captain in his right mind would sail to", "that island...").also { stage++ } + 7 -> { + npc("Ah, you only live once! I'll do it!") + player!!.savedData.questData.setDragonSlayerAttribute("ned", true) + stage++ + } + + 8 -> npc("So, where's your ship?").also { stage = SHIP_DIALOGUE } + } + } + + else if(questStage == 30){ + when(stage){ + START_DIALOGUE -> player("So will you take me to Crandor now then?").also { stage++ } + 1 -> npc( + "I Said I would and old Ned is a man of his word! I'll", + "meet you on board the Lady Lumbridge in Port Sarim." + ).also { stage = END_DIALOGUE } + } + } + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/NedDialogue.kt b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/NedDialogue.kt new file mode 100644 index 0000000..dcc331b --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/NedDialogue.kt @@ -0,0 +1,214 @@ +package content.region.misthalin.varrock.quest.dragonslayer + +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.diary.AchievementDiary +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import core.game.dialogue.IfTopic +import core.game.dialogue.Topic +import content.region.desert.alkharid.quest.princealirescue.NedPARDialogue +import content.region.misthalin.lumbridge.diary.NedDiaryDialogue +import core.game.world.GameWorld.settings +import core.tools.END_DIALOGUE +import content.data.Quests + + +/** + * Core dialogue plugin for Ned. + * @author Ceikry + */ +class NedDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin(player) { + /** + * The achievement diary. + */ + private var diary: AchievementDiary? = null + private val level = 2 + + override fun newInstance(player: Player): core.game.dialogue.DialoguePlugin { + return NedDialogue(player) + } + + override fun open(vararg args: Any): Boolean { + npc = args[0] as NPC + npc( + "Why, hello there, lad. Me friends call me Ned. I was a", + "man of the sea, but it's past me now. Could I be", + "making or selling you some rope?" + ) + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> { + val dSlayerStage = player.questRepository.getStage(Quests.DRAGON_SLAYER) + val parStage = player.questRepository.getStage(Quests.PRINCE_ALI_RESCUE) + showTopics( + IfTopic("I'd like to talk about Dragon Slayer.", NedDSDialogue(dSlayerStage), dSlayerStage == 20 || dSlayerStage == 30), + IfTopic("I'd like to talk about Prince Ali Rescue.", NedPARDialogue(parStage), parStage == 20 || parStage == 30 || parStage == 40 || parStage == 50), + Topic("Yes, I would like some rope.", 10), + Topic("No thanks Ned, I don't need any.", END_DIALOGUE), + Topic("I'd like to ask about my Achievement Diary.", NedDiaryDialogue()) + ) + } + + 10 -> { + npc( + "Well, I can sell you some rope for 15 coins. Or I can", + "be making you some if you gets me 4 balls of wool. I", + "strands them together I does, makes em strong." + ) + stage = 11 + } + 11 -> { + player("You make rope from wool?") + stage = 12 + } + 12 -> { + npc("Of course you can!") + stage = 13 + } + 13 -> { + player("I thought you needed hemp or jute.") + stage = 14 + } + 14 -> { + npc("Do you want some rope or not?") + stage = 15 + } + 15 -> stage = if (!player.inventory.containsItem(WOOL)) { + options( + "Okay, please sell me some rope.", + "That's a little more than I want to pay.", + "I will go and get some wool." + ) + 16 + } else { + options( + "Okay, please sell me some rope.", + "I have some balls of wool. Could you make me some rope?", + "That's a little more than I want to pay." + ) + 17 + } + 17 -> when (buttonId) { + 1 -> { + player("Okay, please sell me some rope.") + stage = 100 + } + 2 -> { + player("I have some balls of wool.", "Could you make me some rope?") + stage = 120 + } + 3 -> { + player("That's a little more than I want to pay.") + stage = 200 + } + } + 16 -> when (buttonId) { + 1 -> { + player("Okay, please sell me some rope.") + stage = 100 + } + 2 -> { + player("That's a little more than I want to pay.") + stage = 200 + } + 3 -> { + player("I will go and get some wool.") + stage = 300 + } + } + 40 -> when (buttonId) { + 1 -> { + player("Ned could you make other things from wool?") + stage = 41 + } + 2 -> { + player("Yes, I would like some rope.") + stage = 10 + } + 3 -> { + player("No thanks Ned, I don't need any.") + stage = 20 + } + } + 100 -> { + npc("There you go, finest rope in " + settings!!.name + ".") + stage = 101 + } + 101 -> { + interpreter.sendDialogue("You hand Ned 15 coins. Ned gives you a coil of rope.") + stage = 102 + } + 102 -> { + if (player.inventory.remove(COINS)) { + if (!player.inventory.add(ROPE)) { + GroundItemManager.create(ROPE, player) + } + } else { + player.packetDispatch.sendMessage("You don't have enough coins to pay for rope.") + } + end() + } + 120 -> { + interpreter.sendDialogues(npc, null, "Sure I can.") + stage = 121 + } + 121 -> { + interpreter.sendDialogue("You hand over 4 balls of wool. Ned gives you a coil of rope.") + stage = 122 + } + 122 -> { + if (player.inventory.remove(WOOL)) { + player.inventory.add(ROPE) + } + end() + } + 200 -> { + npc( + "Well, if you ever need rope that's the price. Sorry.", + "An old sailor needs money for a little drop o' rum." + ) + stage = 201 + } + 201 -> end() + 300 -> { + npc("Aye, you do that. Remember, it takes 4 balls of wool to", "make strong rope.") + stage = 301 + } + 301 -> end() + 20 -> { + npc( + "Well, old Neddy is always here if you do. Tell your", + "friends. I can always be using the business." + ) + stage = 21 + } + 21 -> end() + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(743) + } + + companion object { + /** + * Represents the coins item to remove. + */ + private val COINS = Item(995, 15) + + /** + * Represents the rope item to add. + */ + private val ROPE = Item(954) + + /** + * Represents the ball of wool item. + */ + private val WOOL = Item(1759, 4) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/OziachDialogue.java b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/OziachDialogue.java new file mode 100644 index 0000000..faebde0 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/OziachDialogue.java @@ -0,0 +1,414 @@ +package content.region.misthalin.varrock.quest.dragonslayer; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import content.data.Quests; + +/** + * Represents the dialogue used to handle the oziach dialogue. + * @author Aero + * @author 'Vexia + */ +public final class OziachDialogue extends DialoguePlugin { + + /** + * Represents the demon slayer quest. + */ + private Quest quest; + + /** + * Constructs a new {@code OziachDialogue} {@code Object}. + */ + public OziachDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code OziachDialogue} {@code Object}. + * @param player the player. + */ + public OziachDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new OziachDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + quest = player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER); + player.debug("" + quest.getStage(player)); + switch (quest.getStage(player)) { + case 100: + npc("Aye, 'tis a fair day, my mighty dragon-slaying friend."); + if (player.getInventory().containsItem(new Item(11286))) {// player.getEquipment().containsItem(new + // Item(1540))//TODO: + // Anti-drag + // shield + // dialogue. + stage = 42; + } else { + stage = 0; + } + break; + case 40: + case 30: + case 20: + case 15: + if (args.length > 1) { + npc("I'm not selling' ye anything till you've slayed that", "dragon! Now be off wi' ye."); + stage = -1; + return true; + } else { + npc("Have ye slayed that dragon yet?"); + stage = 0; + } + break; + case 10: + if (args.length > 1) { + player("Can you sell me a rune platebody?"); + stage = 0; + } else { + npc("Aye, 'tis a fair day my friend."); + stage = -1; + } + break; + default: + npc("Aye, 'tis a fair day my friend."); + stage = 0; + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (quest.getStage(player)) { + case 30: + case 20: + if (stage == -1) { + end(); + } else { + end(); + break; + } + break; + case 100: + switch (stage) { + case 0: + options("Can I buy a rune platebody now, please?", "I'm not your friend.", "Yes, it's a very nice day.", "Can I have another key to Melzar's Maze?"); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + player("Can I buy a rune platebody now, please?"); + stage = 10; + break; + case 2: + player("I'm not your friend."); + stage = 20; + break; + case 3: + player("Yes, it's a very nice day."); + stage = 30; + break; + case 4: + player("Can I have another key to Melzar's Maze?"); + stage = 40; + break; + case 5: + player("Here you go."); + stage = 44; + break; + } + break; + case 10: + end(); + npc.openShop(player); + break; + case 20: + end(); + break; + case 30: + end(); + break; + case 40: + npc("It's the Guildmaster in the Champions' Guild who hands", "those keys out now. Go talk to him. No need to bother", "me if you don't need armour."); + stage = 41; + break; + case 41: + end(); + break; + case 42: + npc("Ye've got... Ye've found a draconic visage! Could I look at", "it?"); + stage++; + break; + case 43: + options("Can I buy a rune platebody now, please?", "I'm not your friend.", "Yes, it's a very nice day.", "Can I have another key to Melzar's Maze?", "Here you go"); + stage = 1; + break; + case 44: + npc("Amazin'! Ye can almost feel it pulsin with draconic power!"); + stage++; + break; + case 45: + npc("Now, if ye want me to, I could attach this to yer anti-", "dragonbreath shield and make something pretty special."); + stage++; + break; + case 46: + npc("The shield won't be easy to weild though; ye'll need level", "75 Defence."); + stage++; + break; + case 47: + npc("I'll charge 1,250,000 coins to construct it. What d'ye say?"); + stage++; + break; + case 48: + options("Yes, please!", "No, thanks.", "That's a bit expensive!"); + stage++; + break; + case 49: + switch (buttonId) { + case 1: + player("Yes please!"); + stage = 50; + break; + case 2: + player("No thanks."); + stage = 52; + break; + case 3: + player("That's a bit expensive!"); + stage = 53; + break; + } + break; + case 50: + if (player.getInventory().contains(11286, 1)) { + if (player.getInventory().contains(995, 1250000)) { + if (player.getInventory().contains(1540, 1)) { + player.getInventory().remove(new Item(1540, 1)); + player.getInventory().remove(new Item(11286, 1)); + player.getInventory().remove(new Item(995, 1250000)); + player.getInventory().add(new Item(11283, 1)); + player.getDialogueInterpreter().sendItemMessage(11283, "Oziach skillfully forges the shield and visage into a new shield."); + stage = 51; + } else { + npc("Ye need an anti-dragonbreath shield for me to", "attach this onto, talk to me again once you do."); + stage = 41; + } + } else { + player("I don't seem to have enough coins tho,", "I will return once I do."); + stage = 41; + } + } else { + npc("Ye need the draconic visage for me to attach.", "Talk to me again once you have it."); + stage = 41; + } + break; + case 51: + npc("There ye go. Now, the more dragonfire your shield", "absorbs, the more powerful it'll become."); + stage = 41; + break; + case 52: + npc("Talk to me again if ye change your mind", "mighty dragon slayer."); + stage = 41; + break; + case 53: + npc("It's the price ye pay to make such a magnificent shield."); + stage = 41; + break; + } + break; + case 40: + switch (stage) { + case -1: + end(); + break; + case 0: + if (!player.getInventory().containsItem(DragonSlayer.ELVARG_HEAD)) { + player("Nope, not yet."); + stage = -1; + return true; + } + player("Yes, I have!"); + stage = 2; + break; + case 2: + player("I have its head here."); + stage = 3; + break; + case 3: + npc("You actually did it?"); + stage = 4; + break; + case 4: + npc("I underestimated ye, adventurer. I apologize."); + stage = 5; + break; + case 5: + npc("Yer a true hero, and I'd be happy to sell ye rune", "platebodies."); + stage = 6; + break; + case 6: + end(); + int heads = player.getInventory().getAmount(DragonSlayer.ELVARG_HEAD); + if (player.getInventory().remove(new Item(DragonSlayer.ELVARG_HEAD.getId(),heads)) && !player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER).isCompleted(player)) { + quest.finish(player); + } + break; + } + break; + case 15: + switch (stage) { + case -1: + end(); + break; + case 0: + player("Um... no."); + stage = 2; + break; + case 1: + player("Um... no."); + stage = 2; + break; + case 2: + npc("Be off with ye then."); + stage = 3; + break; + case 3: + end(); + break; + } + break; + case 10: + switch (stage) { + case -1: + player("Can you sell me a rune platebody?"); + stage = 0; + break; + case 0: + npc("So, how does thee know I 'ave some?"); + stage = 2; + break; + case 2: + player("The Guildmaster of the Champions' Guild told me."); + stage = 3; + break; + case 3: + npc("Yes, I suppose he would, wouldn't he? He's always", "sending you fancy-pants 'heroes' up to bother me.", "Telling me I'll give them a quest or sommat like that."); + stage = 4; + break; + case 4: + npc("Well, I'm not going to let just anyone wear my rune", "platemail. It's only for heroes. So, leave me alone."); + stage = 5; + break; + case 5: + player("I thought you were going to give me a quest."); + stage = 6; + break; + case 6: + npc("*Sigh*"); + stage = 7; + break; + case 7: + npc("All right, I'll give ye a quest. I'll let ye wear my rune", "platemail if ye..."); + stage = 8; + break; + case 8: + npc("Slay the dragon of Crandor!"); + stage = 9; + break; + case 9: + options("A dragon, that sounds like fun.", "I may be a champion, but I don't think I'm up to dragon-killing yet."); + stage = 10; + break; + case 10: + switch (buttonId) { + case 1: + player("A dragon, that sounds like fun!"); + stage = 100; + break; + case 2: + player("I may be a champion, but I don't think I'm up to", "dragon-killing yet."); + stage = 200; + break; + } + break; + case 100: + npc("Hah, yes, you are a typical reckless adventurer, aren't", "you? Now go kill the dragon and get out of my face."); + stage = 101; + break; + case 101: + player("But how can I defeat the dragon?"); + stage = 102; + break; + case 102: + npc("Go talk to the Guildmaster in the Champions' Guild. He'll", "help ye out if yer so keen on doing a quest. I'm not", "going to be handholding any adventurers."); + stage = 103; + break; + case 103: + quest.setStage(player, 15); + end(); + break; + case 200: + npc("Yes, I can understand that. Yer a coward."); + stage = 201; + break; + case 201: + end(); + break; + } + break; + default: + switch (stage) { + case 0: + options("I'm not your friend.", "Yes, it's a very nice day."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + player("I'm not your friend."); + stage = 10; + break; + case 2: + player("Yes, it's a very nice day."); + stage = 20; + break; + } + break; + case 10: + npc("I'm surprised if you're anyone's friend with those kind", "of manners."); + stage = 11; + break; + case 11: + end(); + break; + case 20: + npc("Aye, may the gods walk by yer side. Now leave me", "alone."); + stage = 21; + break; + case 21: + end(); + break; + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 747 }; + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/WormbrainDialogue.java b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/WormbrainDialogue.java new file mode 100644 index 0000000..84feb6b --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/WormbrainDialogue.java @@ -0,0 +1,189 @@ +package content.region.misthalin.varrock.quest.dragonslayer; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.integrations.discord.Discord; +import content.data.Quests; + +/** + * Represents the dialogue used to handle the wormbrain npc related to the + * dragon slayer. + * @author 'Vexia + * @version 1.0 + */ +public final class WormbrainDialogue extends DialoguePlugin { + + /** + * Represents the coins item. + */ + private static final Item COINS = new Item(995, 10000); + + /** + * Represents the quest instance. + */ + private Quest quest; + + /** + * Constructs a new {@code WormbrainDialogue} {@code Object}. + */ + public WormbrainDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code WormbrainDialogue} {@code Object}. + * @param player the player. + */ + public WormbrainDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new WormbrainDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + quest = player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER); + switch (quest.getStage(player)) { + default: + npc("Whut you want?"); + stage = -1; + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (quest.getStage(player)) { + case 20: + switch (stage) { + case -1: + if (!player.getInventory().containsItem(DragonSlayer.WORMBRAIN_PIECE) && !player.getBank().containsItem(DragonSlayer.WORMBRAIN_PIECE)) { + player("I believe you've got a piece of a map that I need."); + stage = 500; + } else { + defaultDial(buttonId); + } + break; + case 500: + npc("So? Why should I be giving it to you? What you do", "for Wormbrain?"); + stage = 501; + break; + case 501: + player("I suppose I could pay you for the map piece. Say, 500", "coins?"); + stage = 502; + break; + case 502: + npc("Me not stoopid, it worth at least 10,000 coins!"); + stage = 503; + break; + case 503: + options("You must be joking! Forget it.", "Alright then, 10,000 it is."); + stage = 504; + break; + case 504: + switch (buttonId) { + case 1: + player("You must be joking! Forget it."); + stage = 505; + break; + case 2: + player("Alright, then, 10,000 it is."); + stage = 506; + break; + } + break; + case 505: + end(); + break; + case 506: + if (player.getInventory().containsItem(COINS) && player.getInventory().remove(COINS)) { + if (!player.getInventory().add(DragonSlayer.WORMBRAIN_PIECE)) { + GroundItemManager.create(DragonSlayer.WORMBRAIN_PIECE, player); + } + interpreter.sendItemMessage(DragonSlayer.WORMBRAIN_PIECE.getId(), "You buy the map piece from Wormbrain."); + Discord.sendToOpenRSC(player.getName(), "Player obtained Wormbrain piece! (Dialogue)"); + stage = 507; + } else { + end(); + player.getPacketDispatch().sendMessage("You don't have enough coins in order to do that."); + } + break; + case 507: + npc("Fank you very much! Now me can bribe da guards,", "hehehe."); + stage = 508; + break; + case 508: + end(); + break; + } + default: + defaultDial(buttonId); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 745 }; + } + + /** + * Method used to handle the default dial. + * @param buttonId the button id. + */ + public void defaultDial(int buttonId) { + switch (stage) { + case -1: + options("What are you in for?", "Sorry, thought this was a zoo."); + stage = 0; + break; + case 0: + switch (buttonId) { + case 1: + player("What are you in for?"); + stage = 10; + break; + case 2: + player("Sorry, thought this was a zoo."); + stage = 15; + break; + } + break; + case 10: + npc("Me not sure. Me pick some stuff up and take it away."); + stage = 11; + break; + case 11: + player("Well, did the stuff belong to you?"); + stage = 12; + break; + case 12: + npc("Umm...no."); + stage = 13; + break; + case 13: + player("Well, that would be why then."); + stage = 14; + break; + case 14: + npc("Oh, right."); + stage = 15; + break; + case 15: + end(); + break; + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/WormbrainNPC.java b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/WormbrainNPC.java new file mode 100644 index 0000000..f755bd8 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/WormbrainNPC.java @@ -0,0 +1,74 @@ +package content.region.misthalin.varrock.quest.dragonslayer; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItemManager; +import core.game.world.map.Location; +import content.data.Quests; + +/** + * Represents the worm brain npc. + * @author 'Vexia + * @versin 1.0 + */ +public final class WormbrainNPC extends AbstractNPC { + + /** + * The NPC ids of NPCs using this plugin. + */ + private static final int[] ID = { 745 }; + + /** + * Constructs a new {@code WormBrainPlugin} {@code Object}. + */ + public WormbrainNPC() { + super(0, null); + } + + /** + * Constructs a new {@code AlKharidWarriorPlugin} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + private WormbrainNPC(int id, Location location) { + super(id, location); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new WormbrainNPC(id, location); + } + + @Override + public void finalizeDeath(final Entity killer) { + super.finalizeDeath(killer); + if (killer instanceof Player) { + if (((Player) killer).getQuestRepository().getQuest(Quests.DRAGON_SLAYER).getStage(killer.asPlayer()) == 20 && !((Player) killer).getInventory().containsItem(DragonSlayer.WORMBRAIN_PIECE) && !((Player) killer).getBank().containsItem(DragonSlayer.WORMBRAIN_PIECE)) { + GroundItemManager.create(DragonSlayer.WORMBRAIN_PIECE, getLocation(), ((Player) killer)); + ((Player) killer).getPacketDispatch().sendMessage("Wormbrain drops a map piece on the floor."); + } + } + } + + @Override + public boolean isAttackable(Entity entity, CombatStyle style, boolean message) { + if (entity instanceof Player) { + final Player player = (Player) entity; + if (player.getQuestRepository().getQuest(Quests.DRAGON_SLAYER).getStage(player) != 20) { + if(message) { + player.getPacketDispatch().sendMessage("The goblin is already in prison. You have no reason to attack him."); + } + return false; + } + } + return super.isAttackable(entity, style, message); + } + + @Override + public int[] getIds() { + return ID; + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/ZombieRatNPC.java b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/ZombieRatNPC.java new file mode 100644 index 0000000..65a6026 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/dragonslayer/ZombieRatNPC.java @@ -0,0 +1,73 @@ +package content.region.misthalin.varrock.quest.dragonslayer; + +import core.game.node.entity.Entity; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.world.map.Location; +import core.tools.RandomFunction; +import content.data.Quests; + +import static core.api.ContentAPIKt.getQuestStage; + +/** + * Represents a zombie rat npc related to dragon slayer and witch's potion. + * @author 'Vexia + * @version 1.0 + */ +public final class ZombieRatNPC extends AbstractNPC { + + /** + * The NPC ids of NPCs using this plugin. + */ + private static final int[] ID = { 6088, 6089, 6090 }; + + /** + * Represents the rat tail item. + */ + private static final Item RAT_TAIL = new Item(300, 1); + + /** + * Constructs a new {@code AlKharidWarriorPlugin} {@code Object}. + */ + public ZombieRatNPC() { + super(0, null); + } + + /** + * Constructs a new {@code AlKharidWarriorPlugin} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + private ZombieRatNPC(int id, Location location) { + super(id, location); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new ZombieRatNPC(id, location); + } + + @Override + public void finalizeDeath(final Entity killer) { + super.finalizeDeath(killer); + if (killer instanceof Player) { + final Player p = ((Player) killer); + if (RandomFunction.random(0, 4) == 2) { + GroundItemManager.create(DragonSlayer.RED_KEY, getLocation(), p); + } + if (getQuestStage(p, Quests.WITCHS_POTION) > 0 && getQuestStage(p, Quests.WITCHS_POTION) < 100) { + GroundItemManager.create(RAT_TAIL, getLocation(), p); + } + GroundItemManager.create(new Item(526), getLocation(), p); + } + } + + @Override + public int[] getIds() { + return ID; + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/familycrest/AvanDialogue.kt b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/AvanDialogue.kt new file mode 100644 index 0000000..1961c45 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/AvanDialogue.kt @@ -0,0 +1,212 @@ +package content.region.misthalin.varrock.quest.familycrest + +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import org.rs09.consts.Items +import content.data.Quests + +@Initializable +class AvanDialogue (player: Player? = null): DialoguePlugin(player) { + + val CREST_PIECE_AVAN: Item = Item(779) + + override fun newInstance(player: Player?): DialoguePlugin { + return AvanDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = (args[0] as NPC).getShownNPC(player) + val qstage = player?.questRepository?.getStage(Quests.FAMILY_CREST) ?: -1 + + if (qstage == 100) { + options("Can you change my gauntlets for me?", "Nevermind") + stage = 6000 + return true + } + + if(qstage < 13){ + npc("What? Can't you see I'm busy?").also { stage = 1000 } + }else{ + when(qstage){ + 13 -> options("Why are you lurking around a scorpion pit?", "I'm looking for a man... his name is Avan Fitzharmon.").also{stage = 2} + 14 -> npc("So how are you doing getting me my perfect gold jewelry?").also{stage = 100} + 15 -> npc("So how are you doing getting me my perfect gold jewelry?").also{stage = 200} + 16 -> player("Where did you say I could find your brother Johnathon again?").also{stage = 304} + 17 -> npc("Greetings again, adventurer. How are you doing on retrieving the crest pieces?").also{stage = 400} + 18 -> npc("Greetings again, adventurer. How are you doing on retrieving the crest pieces?").also{stage = 400} + 19 -> npc("Greetings again, adventurer. How are you doing on retrieving the crest pieces?").also{stage = 400} + } + } + + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + + when(stage){ + 1 -> player("Well, sooooorry...").also{stage = 1000} + + 2->when(buttonId){ + 1 -> npc("It's a good place to find gold...").also{stage = 1000} + 2 -> npc("Then you have found him. My name is Avan Fitzharmon.").also{stage++} + } + + 3 -> player("You have a part of your family crest. I am on a quest ", + "to retrieve all of the fragmented pieces ", + "and restore the crest.").also{stage++} + + 4 -> npc("Ha! I suppose one of my worthless brothers ", + "has sent you on this quest then?").also{stage++} + + 5 -> player("No, it was your father who has asked me to do this for him.").also{stage++} + + 6 -> npc("My... my father wishes this? Then that is a different matter. ", + "I will let you have my crest shard, adventurer, ", + "but you must first do something for me.").also{stage++} + + 7 -> npc("There is a certain lady I am trying to impress. ", + "As a man of noble birth, I can not give her just ", + "any gold trinket to show my devotion. ").also{stage++} + + 8 -> npc("What I intend to give her, is a golden ring, " , + "embedded with the finest precious red stone available, " , + "and a necklace to match this ring. ").also { stage++ } + + 9 -> npc("The problem however for me, is that ", + "not just any old gold will be suitable. ", + "I seek only the purest, the most high quality of gold ", + "what I seek, if you will, is perfect gold.").also{stage++} + 10 -> npc("None of the gold around here is even " , + "remotely suitable in terms of quality. ", + "I have searched far and wide for the perfect gold I desire, ", + "but have had no success so in finding it I am afraid. ").also { stage++ } + + 11 -> npc("If you can find me my perfect gold, " , + "make a ring and necklace from it, and add rubies to them, ", + "I will gladly hand over my fragment of " , + "the family crest to you.").also{stage++} + + 12 -> player("Can you give me any help on finding this 'perfect gold'?").also{stage++} + + 13 -> npc("I thought I had found a solid lead on its whereabouts ", + "when I heard of a dwarf who is an expert " , + "on gold who goes by the name of 'Boot'. ").also { stage++ } + + 14 -> npc("Unfortunately he has apparently returned to this home,", + "somewhere in the mountains, " , + "and I have no idea how to find him.").also { stage++} + + 15 -> player("Well, I'll see what I can do.").also{ + stage = 1000 + player.questRepository.getQuest(Quests.FAMILY_CREST).setStage(player, 14) + } + + 100 -> player("I'm still after that 'perfect gold'.").also { stage++ } + + 101 -> npc("I know how you feel... for such a long time " , + "I have searched and searched for the elusive perfect gold... " , + "I thought I had gotten a good lead on finding it ").also{stage++} + + 102 -> npc("when I heard talk of a dwarven expert on gold named Boot " , + "some time back, but unfortunately for me," , + " he has returned to his mountain home, which I cannot find.").also { stage = 1000} + + 200 -> if(!player.inventory.containItems(774,773)){ + npc("I have spoken to Boot the dwarf about the location " , + "of 'perfect gold', " , + "but haven't managed to make you your jewelry yet.").also { stage++ } + } + else{ + player("I have the ring and necklace right here.") + stage = 300 + } + 201 -> npc("Well, I won't entrust you with my piece of the crest " , + "until you have brought me a necklace of perfect gold " , + "with a red precious stone, and a perfect gold ring to match.").also { stage = 1000 } + + 300 -> sendDialogue("You hand Avan the perfect gold ring and necklace.").also{ + player.questRepository.getQuest(Quests.FAMILY_CREST).setStage(player, 16) + player.inventory.remove(Item(774), Item(773)) + player.inventory.add(CREST_PIECE_AVAN) + stage++ + } + 301 -> npc("These... these are exquisite! E" , + "XACTLY what I was searching for all of this time! " , + "Please, take my crest fragment!").also { stage++ } + + 302 -> npc("Now, I suppose you will be wanting to find my brother " , + "Johnathon who is in possession of the " , + "final piece of the family's crest?").also { stage++ } + + 303 -> player("That's correct.").also{stage++} + + 304 -> npc("Well, the last I heard of my brother Johnathon," , + " he was studying the magical arts, " , + "and trying to hunt some demon or other out in The Wilderness.").also{stage++} + 305 -> npc("Unsurprisingly, I do not believe he is doing a particularly good job of things, ", + "and spends most of his time recovering from his injuries " , + "in some tavern or other near the eastern edge of The Wilderness. " , + "You'll probably find him still there.").also{stage++} + + 306 -> player("Thanks Avan.").also { stage = 1000 } + + 400 -> player("I am still working on it.").also{stage++} + + 401 -> npc("I hope you succeed for my father's sake.").also{ + if(player.inventory.containItems(CREST_PIECE_AVAN.id, 782) || player.bank.containItems(CREST_PIECE_AVAN.id, 782)){ + stage = 1000 + } + else{ + stage++ + } + } + + 402 -> player("I have lost the fragment you gave me...").also{stage++} + 403 -> npc("I have a confession myself adventurer... " , + "I did not fully trust you with the actual part ", + "of my family's crest before, and gave you a " , + "worthless replica before... ").also{stage++} + 404-> npc("In hindsight, it seems I was right. " , + "I will give you the real piece now, ", + "but please try not to lose it; " , + "it is a priceless family heirloom.").also{stage = 1000 + player.inventory.add(CREST_PIECE_AVAN)} + + 6000 -> when (buttonId) { + 1 -> { + var freeThisTime = getAttribute(player, "family-crest:gauntlets", Items.FAMILY_GAUNTLETS_778) == Items.FAMILY_GAUNTLETS_778 + npc("Yes certainly, though it will cost you 25,000 coins" + if (freeThisTime) " next time." else ".").also { stage = 6001 } + } + 2 -> player("Never mind").also{ stage = 1000 } + } + 6001 -> options("Great thanks!", "No that's okay thanks.").also{ stage++ } + 6002 -> when (buttonId) { + 1 -> { + stage = 1000 + val givingGauntletsId = Items.GOLDSMITH_GAUNTLETS_776 + val npcString = SwapGauntletsHelper.swapGauntlets(player, givingGauntletsId) + if (npcString == "") + { + end() + } + else { + npc(npcString) + } + } + 2 -> end() + } + + 1000 -> end() + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(663) + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/familycrest/BootDialogue.kt b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/BootDialogue.kt new file mode 100644 index 0000000..89dd53a --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/BootDialogue.kt @@ -0,0 +1,76 @@ +package content.region.misthalin.varrock.quest.familycrest + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import content.data.Quests + + +@Initializable +class BootDialogue (player: Player? = null): DialoguePlugin(player){ + override fun newInstance(player: Player?): DialoguePlugin { + return BootDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = (args[0] as NPC).getShownNPC(player) + val qstage = player?.questRepository?.getStage(Quests.FAMILY_CREST) ?: -1 + + if(qstage < 14 || qstage > 14){ + npc(FacialExpression.OLD_NORMAL,"Hello tall person.") + stage = 1 + } + else{ + npc(FacialExpression.OLD_NORMAL,"Hello tall person.") + stage = 2 + } + + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + + 1-> options("Hello short person.", "Why are you called Boot?").also { stage = 10 } + + 2 -> options("Hello. I'm in search of very high quality gold.", "Hello short person.", "Why are you called Boot?").also { stage= 20} + + 10 ->when(buttonId){ + 1-> player("Hello short person.").also { stage = 1000 } + 2 -> npc( + FacialExpression.OLD_ANGRY1,"I'm called Boot, because when I was very young, ", + "I used to sleep, in a large boot.").also{stage++} + + } + + 11 -> player("Yeah, great, I didn't want your life story.").also { stage = 1000} + + 20 -> when (buttonId){ + 1 -> npc( + FacialExpression.OLD_DEFAULT,"High quality gold eh? Hmmm... " , + "Well, the very best quality gold that I know of " , + "can be found in an underground ruin near Witchaven.").also{stage++} + + 2-> player("Hello short person.").also { stage = 1000 } + + 3 -> npc( + FacialExpression.OLD_ANGRY1,"I'm called Boot, because when I was very young, ", + "I used to sleep, in a large boot.").also{stage = 11} + } + + 21 -> npc("I don't believe it's exactly easy to get to though...").also { + stage = 1000 + player.questRepository.getQuest(Quests.FAMILY_CREST).setStage(player, 15) + } + 1000 -> end() + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(665) + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/familycrest/CalebDialogue.kt b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/CalebDialogue.kt new file mode 100644 index 0000000..618bf40 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/CalebDialogue.kt @@ -0,0 +1,242 @@ +package content.region.misthalin.varrock.quest.familycrest + +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import org.rs09.consts.Items +import content.data.Quests + + +@Initializable +class CalebDialogue (player: Player? = null): DialoguePlugin(player) { + + val CREST_PIECE: Item = Item(780) + + override fun newInstance(player: Player?): DialoguePlugin { + return CalebDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = (args[0] as NPC).getShownNPC(player) + val qstage = player?.questRepository?.getStage(Quests.FAMILY_CREST) ?: -1 + + if (qstage == 100) { + options("Can you change my gauntlets for me?", "Nevermind") + stage = 6000 + return true + } + + when(qstage){ + 0-> npc("Who are you? What are you after?").also{stage = 2} + + 10 -> npc("Who are you? What are you after?").also{stage = 1} + + 11 -> npc("How is the fish collecting going?").also{stage = 300} + + 12 -> player("Where did you say I could find Avan again?").also{stage = 400} + + 13 -> player("Where did you say I could find Avan again?").also{stage = 400} + + 14 -> player("Where did you say I could find Avan again?").also{stage = 400} + + 15 -> player("Where did you say I could find Avan again?").also{stage = 400} + 16 -> player("How are you doing getting the crest pieces?").also{stage = 402} + 17 -> player("How are you doing getting the crest pieces?").also{stage = 402} + 18 -> player("How are you doing getting the crest pieces?").also{stage = 402} + 19 -> player("How are you doing getting the crest pieces?").also{stage = 402} + + + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 1 -> options("Are you Caleb Fitzharmon", "Nothing I will be on my way.", "I see you are a chef... could you cook me anything?").also{stage = 3} + 2-> options( "Nothing I will be on my way.", "I see you are a chef... could you cook me anything?").also{stage = 4} + + 3 -> when(buttonId){ + 1 -> npc("Why... yes I am, but I don't believe I know you... " , + "how did you know my name?").also{stage = 5} + 2 -> player("Nothing I will be on my way.").also{stage = 1000} + + 3 -> npc("I would, but I am very busy. I am trying to increase ", + "my renown as one of the world's leading chefs " , + "by preparing a special and unique fish salad.").also{stage = 1000} + } + + 4 -> when(buttonId){ + 1 -> player("Nothing I will be on my way.").also{stage = 1000} + + 2 -> npc("I would, but I am very busy. I am trying to increase ", + "my renown as one of the world's leading chefs " , + "by preparing a special and unique fish salad.").also{stage = 1000} + } + + 5 -> player("I have been sent by your father. ", + "He wishes the Fitzharmon Crest to be restored.").also{stage++} + + 6 -> npc("Ah... well... hmmm... yes... ", + "I do have a piece of it anyway...").also{stage++} + + 7 -> options("Uh... what happened to the rest of it?", "So can I have your bit?").also{stage++} + + 8 -> when(buttonId){ + 1 -> npc("Well... my brothers and I ", + "had a slight disagreement about it...", + " we all wanted to be heir to my fathers' lands, ", + "and we each ended up with a piece of the crest.").also{stage = 100} + 2 -> npc("Well, I am the oldest son, so by the rules of chivalry, ", + "I am most entitled to be the rightful bearer of the crest.").also{stage = 200} + } + + 100 -> npc("None of us wanted to give up our rights to our brothers, ", + "so we didn't want to give up our pieces of the crest, " , + "but none of us wanted to face our father by returning to " , + "him with an incomplete crest... ").also{stage ++} + + 101 -> npc("We each went our separate ways many years past, " , + "none of us seeing our father or willing " , + "to give up our fragments.").also{stage = 7} + + 200 -> player("It's not really much use without " , + "the other fragments is it though?").also{stage++} + + 201 -> npc("Well that is true... " + + "perhaps it is time to put my pride aside... ").also{stage++} + + 202 -> npc( "I'll tell you what: ", + "I'm struggling to complete this fish salad of mine, ").also{stage++} + + 203 -> npc( "so if you will assist me in my search for the ingredients, " , + "then I will let you take my", + "piece as reward for your assistance.").also{stage++} + + 204 -> player("So what ingredients are you missing?").also{stage++} + + 205 -> npc("I require the following cooked fish: " , + "Swordfish, Bass, Tuna, Salmon and Shrimp.").also{stage++} + 206 -> options("Ok, I will get those.", "Why don't you just give me the crest?").also{stage++} + + 207 -> when(buttonId){ + 1 -> npc("You will? It would help me a lot!").also{stage = 1000}.also{ + player.questRepository.getQuest(Quests.FAMILY_CREST).setStage(player, 11) + } + + 2 -> npc("It's a valuable family heirloom. " , + "I think the least you can do is prove you're worthy " , + "of it before I hand it over.").also{stage = 206} + + } + + 300 -> if(player.inventory.containItems(315, 329, 361, 365, 373)){ + player("Got them all with me.").also{stage++} + + }else{ + player("I didn't manage to get them all yet...").also{stage = 320} + } + + 301 -> sendDialogue("You exchange the fish for Caleb's piece of the crest.").also{stage++}.also{ + player.inventory.remove(Item(315),Item(329), Item(361), Item(365), Item(373)) + player.inventory.add(CREST_PIECE) + player.questRepository.getQuest(Quests.FAMILY_CREST).setStage(player, 12) + } + + 302 -> options("Uh... what happened to the rest of it?" , "Thank you very much!").also{stage++} + 303 -> when(buttonId){ + 1 -> npc("Well... my brothers and I had a slight disagreement about it... ", + "we all wanted to be the heir of my father's lands ", + "and we each ended up with a piece of the crest.").also{stage++} + 2 -> npc("You're welcome.").also{stage = 1000} + } + + 304 -> npc("None of us wanted to give up our rights to our brothers," , + "so we didn't want to give up our pieces of the crest, " , + "but none of us wanted to face our father " , + "by returning to him with an incomplete crest.").also{stage ++} + + 305 -> npc("We each went our separate ways many years past,", + "none of us seeing our father or willing to", + "give up our fragments.").also{stage++} + + 306 -> player("So do you know where I could find any of your brothers?").also{stage++} + + 307 -> npc("Well, we haven't really kept in touch... ", + "what with the dispute over the crest and all...", + "I did hear from my brother Avan a while ago though..").also{stage++} + + 308 -> npc("He said he was on some kind of search for treasure,", + "or gold, or something out near Al Kharid somewhere. ", + "Avan always had expensive tastes, so you might try", + "asking the gem trader for his wherebouts.").also{stage ++} + + 309 -> npc("Be warned though. Avan is quite greedy, ", + "and you may find he is not prepared to hand over " , + "his crest piece to you as easily as I have.").also{stage = 1000} + + 320 -> npc("Remember, I want the following cooked fish: ", + "Swordfish, Bass, Tuna, Salmon and Shrimp.").also{stage = 1000} + + 400 -> npc("Last I heard he was on some " , + "stupid treasure hunt out in the desert somewhere. " , + "Your best bet is asking around there.").also{stage++} + 401 -> npc("How are you doing getting the crest pieces?").also{stage++} + + 402 -> player("I am still working on it.").also{stage++} + + 403 -> + if(player.inventory.containItems(CREST_PIECE.id, 782) || player.bank.containItems(CREST_PIECE.id, 782)) { + npc("Then why are you wasting your time here?") + stage = 1000 + } + else{ + player("I have lost the fragment that you gave me...") + stage++ + } + 404 -> npc("I have some good news for you then. " , + "One of my customers found this on their travels " , + "and recognised it as mine and returned it to me here.").also{stage++} + 405 -> sendDialogue("Caleb hands over his crest piece to you again.").also{ + stage++ + player.inventory.add(CREST_PIECE) + } + 406 -> npc("I suggest you be less careless in the future. ", + "The crest is extremely valuable, and utterly irreplaceable.").also{stage = 1000} + + 6000 -> when (buttonId) { + 1 -> { + var freeThisTime = getAttribute(player, "family-crest:gauntlets", Items.FAMILY_GAUNTLETS_778) == Items.FAMILY_GAUNTLETS_778 + npc("Yes certainly, though it will cost you 25,000 coins" + if (freeThisTime) " next time." else ".").also { stage = 6001 } + } + 2 -> player("Never mind").also{ stage = 1000 } + } + 6001 -> options("Great thanks!", "No that's okay thanks.").also{ stage++ } + 6002 -> when (buttonId) { + 1 -> { + stage = 1000 + val givingGauntletsId = Items.COOKING_GAUNTLETS_775 + val npcString = SwapGauntletsHelper.swapGauntlets(player, givingGauntletsId) + if (npcString == "") + { + end() + } + else { + npc(npcString) + } + } + 2 -> end() + } + + 1000 -> end() + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(666) + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/familycrest/ChronozonCaveZone.kt b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/ChronozonCaveZone.kt new file mode 100644 index 0000000..1ca3002 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/ChronozonCaveZone.kt @@ -0,0 +1,77 @@ +package content.region.misthalin.varrock.quest.familycrest + + +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.game.world.map.RegionManager +import core.game.world.map.zone.MapZone +import core.game.world.map.zone.ZoneBorders +import core.game.world.map.zone.ZoneBuilder +import core.plugin.Initializable +import core.plugin.Plugin +import core.api.getQuestStage +import core.api.hasAnItem +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import content.data.Quests + + +@Initializable +class ChronozonCaveZone: MapZone("FC ChronozoneZone", true), Plugin { + + val spawnLoc = Location(3086, 9936, 0) + var chronozon = ChronozonNPC(NPCs.CHRONOZON_667, spawnLoc) + + override fun configure() { + register(ZoneBorders(3079, 9927, 3095, 9944)) + } + + override fun move(e: Entity?, from: Location?, to: Location?): Boolean { + return super.move(e, from, to) + } + + override fun enter(e: Entity?): Boolean { + if (e != null) { + if (e.isPlayer) { + val player = e as Player + if (getQuestStage(player,Quests.FAMILY_CREST) in (19..99) && + !hasAnItem(player, Items.CREST_PART_781).exists() + ){ + // Chronozon is allowed to spawn (quest stage right and the player doesn't have the crest part) + // Now check there is not one already + if(!RegionManager.getLocalNpcs(spawnLoc, 5).contains(chronozon)){ + chronozon.setPlayer(e) + chronozon.isRespawn = false + chronozon.location = spawnLoc + chronozon.init() + } + } + } + return true + } + return false + } + + + override fun leave(e: Entity?, logout: Boolean): Boolean { + if (e!!.isPlayer){ + if (RegionManager.getLocalPlayers(spawnLoc, 5).size <= 0){ + // There are no other players close by + chronozon.clear() + } + } + return super.leave(e, logout) + } + + override fun newInstance(arg: Unit?): Plugin { + ZoneBuilder.configure(this) + return this + } + + override fun fireEvent(identifier: String?, vararg args: Any?): Any { + return UInt + } + + +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/familycrest/ChronozonNPC.kt b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/ChronozonNPC.kt new file mode 100644 index 0000000..954e5b0 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/ChronozonNPC.kt @@ -0,0 +1,102 @@ +package content.region.misthalin.varrock.quest.familycrest + +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.player.Player +import core.game.world.map.Location +import org.rs09.consts.NPCs +import content.data.Quests + + +class ChronozonNPC(id: Int, location: Location?) : AbstractNPC(NPCs.CHRONOZON_667, Location(3086, 9936, 0)){ + + private lateinit var targetplayer: Player + + private var amountOfFireDamageTaken: Int = 0 + + private var amountOfAirDamageTaken: Int = 0 + + private var amountOfWaterDamageTaken: Int = 0 + + private var amountOfEarthDamageTaken: Int = 0 + + override fun construct(id: Int, location: Location?, vararg objects: Any?): AbstractNPC { + return ChronozonNPC(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.CHRONOZON_667) + } + + override fun checkImpact(state: BattleState?) { + if (state != null) { + if(amountOfAirDamageTaken == 0 || amountOfWaterDamageTaken == 0 || + amountOfEarthDamageTaken == 0 || amountOfFireDamageTaken == 0) { + if(state.style != CombatStyle.MAGIC || state.totalDamage >= skills.lifepoints) { + state.neutralizeHits() + } + } + + if(state.spell != null) { + if(state.spell.spellId == 24) { + if(state.totalDamage > 0 && amountOfAirDamageTaken == 0) { + targetplayer.sendMessage("Chronozon weakens...") + } + amountOfAirDamageTaken += state.totalDamage + } + + if(state.spell.spellId == 27) { + if(state.totalDamage > 0 && amountOfWaterDamageTaken == 0) { + targetplayer.sendMessage("Chronozon weakens...") + } + amountOfWaterDamageTaken += state.totalDamage + } + + if(state.spell.spellId == 33) { + if(state.totalDamage > 0 && amountOfEarthDamageTaken == 0) { + targetplayer.sendMessage("Chronozon weakens...") + } + amountOfEarthDamageTaken += state.totalDamage + } + + if(state.spell.spellId == 38) { + if(state.totalDamage > 0 && amountOfFireDamageTaken == 0) { + targetplayer.sendMessage("Chronozon weakens...") + } + amountOfFireDamageTaken += state.totalDamage + } + } + } + } + + override fun finalizeDeath(killer: Entity?) { + if(killer == targetplayer) { + if (targetplayer.questRepository.getStage(Quests.FAMILY_CREST) != 20){ + targetplayer.questRepository.getQuest(Quests.FAMILY_CREST).setStage(targetplayer, 20) + // Make sure to despawn Chronozon + this.clear() + } + } + clear() + super.finalizeDeath(killer) + } + + + fun setPlayer(player: Player){ + targetplayer = player + } + + override fun init() { + // Make sure to reset damage taken when spawning in + amountOfFireDamageTaken = 0 + amountOfAirDamageTaken= 0 + amountOfWaterDamageTaken= 0 + amountOfEarthDamageTaken= 0 + super.init() + + } + +} + diff --git a/Server/src/main/content/region/misthalin/varrock/quest/familycrest/CrestCombiningInteration.kt b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/CrestCombiningInteration.kt new file mode 100644 index 0000000..8a6e40c --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/CrestCombiningInteration.kt @@ -0,0 +1,53 @@ +package content.region.misthalin.varrock.quest.familycrest + +import core.game.interaction.NodeUsageEvent +import core.game.interaction.UseWithHandler +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import core.plugin.Plugin + +@Initializable +class CrestCombiningInteraction: UseWithHandler(779, 780,781) { + + val CREST_AVAN: Item = Item(779) + val CREST_CALEB: Item = Item(780) + val CREST_JOHNATHON: Item = Item(781) + val CREST_FULL: Item = Item(782) + + + + override fun newInstance(arg: Any?): Plugin { + addHandler(779, ITEM_TYPE, this) + addHandler(780, ITEM_TYPE, this) + addHandler(781, ITEM_TYPE, this) + return this + } + + override fun handle(event: NodeUsageEvent?): Boolean { + event ?: return false + val used = event.used + return when(used.id){ + 779 -> CraftCrest(event.player, event) + 780 -> CraftCrest(event.player, event) + 781 -> CraftCrest(event.player, event) + else -> false + } + } + + private fun CraftCrest(player: Player, event: NodeUsageEvent): Boolean{ + return when(event.usedWith.id){ + 779,780,781 ->{ + if(player.inventory.containItems(779, 780, 781)) { + player.inventory.remove(CREST_AVAN) + player.inventory.remove(CREST_CALEB) + player.inventory.remove(CREST_JOHNATHON) + player.inventory.add(CREST_FULL) + true + } + false + } + else -> false + } + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/familycrest/DimintheisDialogue.kt b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/DimintheisDialogue.kt new file mode 100644 index 0000000..e5e2f9b --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/DimintheisDialogue.kt @@ -0,0 +1,187 @@ +package content.region.misthalin.varrock.quest.familycrest + + +import core.api.* +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import content.data.Quests + + +@Initializable +/** +* Handles DimintheisDialogue Dialogue +* @author Plex +*/ +class DimintheisDialogue(player: Player? = null): core.game.dialogue.DialoguePlugin(player) { + override fun newInstance(player: Player?): core.game.dialogue.DialoguePlugin { + return DimintheisDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = (args[0] as NPC).getShownNPC(player) + val questStage = getQuestStage(player, Quests.FAMILY_CREST) + val questComplete = isQuestComplete(player, Quests.FAMILY_CREST) + + if (questStage == 20 && inInventory(player, Items.FAMILY_CREST_782)) { + player("I have retrieved your crest.").also{ stage = 5000 } + return true + } + + val hasGauntlets = hasAnItem(player, arrayOf(Items.COOKING_GAUNTLETS_775, Items.GOLDSMITH_GAUNTLETS_776, Items.CHAOS_GAUNTLETS_777, Items.FAMILY_GAUNTLETS_778), true).container != null + + if (questComplete && hasGauntlets) { + npc("Thank you for saving our family honour, ", + "We will never forget you") + stage = 1000 + return true + } + + if (questComplete && !hasGauntlets) { + player("I've lost the gauntlets you gave me") + stage = 6000 + return true + } + + when(questStage) { + 0 -> npc("Hello. My name is Dimintheis, ", + "of the noble family Fitzharmon.").also { stage = 1 } + 10 -> player("Where did you say I could find your son Caleb again?").also { stage = 3000 } + 11 -> player("Where did you say I could find your son Caleb again?").also { stage = 3000 } + 12 -> npc("Have you found my crest yet?").also{ stage = 4000 } + 13 -> npc("Have you found my crest yet?").also{ stage = 4000 } + 14 -> npc("Have you found my crest yet?").also{ stage = 4000 } + 15 -> npc("Have you found my crest yet?").also{ stage = 4000 } + 16 -> npc("Have you found my crest yet?").also{ stage = 4000 } + 17 -> npc("Have you found my crest yet?").also{ stage = 4000 } + 18 -> npc("Have you found my crest yet?").also{ stage = 4000 } + 19 -> npc("Have you found my crest yet?").also{ stage = 4000 } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 1 -> options( + "Why would a nobleman live in a dump like this?", + "You're rich then? Can i have some money?", + "Hi, i am a bold adventurer.").also { stage++ } + 2 -> when(buttonId){ + 1 -> npc("The King has taken my estate from me ", + "until such time as I can show my family crest to him.").also { stage = 3 } + 2 -> npc("Gah! Lousy beggar! " , + "Your sort is what's ruining this great land! ", + "Why don't you just go and get a " , + "job if you need money so badly?").also { stage = 1000} + 3 -> npc("An adventurer hmmm? How lucky. I may have an adventure for you. " , + "I desperately need my family crest returning to me. " , + "It is of utmost importance.").also { stage = 4 } + } + 3 -> options("Why would he do that?", + "So where is this crest?").also { stage = 5 } + + 4 -> options("Why are you so desperate for it?", + "So where is this crest?", + "I'm not interested in that adventure right now").also { stage = 6 } + 5 -> when(buttonId){ + 1-> npc("Well, there is a long standing rule of chivalry " , + "amongst the Varrockian aristocracy,").also{ stage = 2000 } + 2-> npc("Well, my three sons took it with them " , + "many years ago when they rode ").also { stage = 2007 } + } + 6 -> when(buttonId){ + 1 -> npc("Well, there is a long standing rule of chivalry " , + "amongst the Varrockian aristocracy,").also{ stage = 2000 } + 2 -> npc("Well, my three sons took it with them " , + "many years ago when they rode ").also { stage = 2007 } + 3 -> npc("I realise it was a lot to ask of a stranger.").also { stage = 1000} + + } + 2000 -> npc( + "where each noble family is in possession of a unique crest, ", + "which signifies the honour and lineage of the family. ").also { stage++} + 2001 -> npc("More than this however, it also represents the ", + "lawful rights of each family to prove their ownership of ", + "their wealth and lands. If the family crest is lost,").also { stage++ } + + 2002 -> npc( "then the family's estate is handed over to the ", + "current monarch until the crest is restored.").also{ stage++ } + 2003 -> npc("This dates back to the times when there was much in-fighting " , + "amongst the noble families and their clans, and ", + "was introduced as a way of reducing the bloodshed that was ", + "devastating the ranks of the ruling classes at that time.").also { stage++ } + 2004 -> npc("When you captured a rival family's clan, " , + "you also captured their lands and wealth.").also{ stage++} + + 2005 -> options("So where is this crest?", "I'm not interested in an adventure right now").also{stage++} + + 2006 -> when(buttonId){ + 1-> npc("Well, my three sons took it ", + "with them many years ago when they rode out ").also { stage++ } + 2 -> npc("I realise it was a lot to ask of a stranger.").also { stage = 1000 } + + } + 2007 -> npc("to fight in the war against the undead necromancer " , + "and his army in the battle to save Varrock.").also { stage++ } + 2008 -> npc("For many years I had assumed them all dead, " , + "as I had heard no word from them.").also { stage++ } + 2009 -> npc("Recently I heard that my son Caleb is alive and well, " , + "trying to earn his fortune as a great fish chef in Catherby.").also { stage++ } + 2010 -> options("Ok, I will help you", "I'm not interested in an adventure right now").also { stage++ } + 2011 -> when(buttonId){ + 1 -> npc("I thank you greatly adventurer!").also { stage++ } + 2 -> npc("I realise it was a lot to ask of a stranger.").also { stage = 1000 } + } + 2012 -> if(startQuest(player, Quests.FAMILY_CREST)) { + npc("If you find Caleb, or my other sons... please... ", + "let them know their father still loves them...").also { stage = 1000 } + } else { + npc("But im sorry, but you cannot help me right now").also{ stage = 1000 } + } + + 3000 ->npc("The only thing I have heard of my son Caleb ", + "is that he is trying to earn his fortune as a great fish chef.").also{ stage++ } + 3001 ->npc("I believe he is staying with a friend ", + "who lives just outside the west gates of Varrock.").also{ stage = 1000 } + + 4000 -> player("I'm still looking for it").also{ stage = 1000 } + + 5000 -> npc("Adventurer... I can only thank you for your kindness, " , + "although the words are insufficient " , + "to express the gratitude I feel!").also{ stage++ } + 5001 -> npc("You are truly a hero in every sense, " , + "and perhaps your efforts can begin to " , + "patch the wounds that have torn this family apart...").also{ stage++ } + 5002 -> npc("I know not how I can adequately reward you for your efforts... " , + "although I do have these mystical gauntlets, " , + "a family heirloom that through some power unknown to me, " , + "have always returned to the head of the family whenever lost,").also{ stage++ } + 5003 -> npc(" or if the owner has died. " , + "I will pledge these to you, " , + "and if you should lose them return to me, " , + "and they will be here.").also{ stage++ } + 5004 -> npc("They can also be granted extra powers. " , + "Take them to one of my sons, " , + "they should be able to imbue them with a skill for you.").also { + stage = 1000 + if (removeItem(player, Items.FAMILY_CREST_782)) { + finishQuest(player, Quests.FAMILY_CREST) + } + } + + 6000 -> npc("Not to worry, here they are").also { + stage = 1000 + addItem(player, getAttribute(player, "family-crest:gauntlets", Items.FAMILY_GAUNTLETS_778)) + } + + 1000 -> end() + } + + return true + } + + override fun getIds(): IntArray { + return intArrayOf(8171) + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/familycrest/FamilyCrest.kt b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/FamilyCrest.kt new file mode 100644 index 0000000..2cedd61 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/FamilyCrest.kt @@ -0,0 +1,133 @@ +package content.region.misthalin.varrock.quest.familycrest + + +import core.api.addItem +import core.api.log +import core.api.setAttribute +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import core.tools.Log +import org.rs09.consts.Items +import content.data.Quests + +/** +* Represents the "Family Crest" quest. +* @author Plex +*/ + +@Initializable +class FamilyCrest: Quest(Quests.FAMILY_CREST, 59, 58, 1, 148, 0, 1, 11) { + + override fun newInstance(`object`: Any?): Quest { + return this + } + + override fun drawJournal(player: Player?, stage: Int) { + super.drawJournal(player, stage) + var line = 11 + player?: return + if(stage == 0){ + line(player, "I can start this quest by speaking to !!Dimintheis??", line++) + line(player, "in east Varrock", line++) + line++ + line(player, "To start this quest I require:", line++) + line(player, "!!40 Crafting??", line++, player.skills.getLevel(Skills.CRAFTING) >= 40) + line(player, "!!40 Smithing??", line++, player.skills.getLevel(Skills.SMITHING) >= 40) + line(player, "!!40 Mining??", line++, player.skills.getLevel(Skills.MINING) >= 40) + line(player, "!!59 Magic??", line++, player.skills.getLevel(Skills.MAGIC) >= 59) + } + if(stage >= 10){ + line(player, "I have agreed to restore !!Dimintheis'?? family crest to him.", line++, stage >10) + line(player, "He has asked me to find his son Caleb for him", line++, stage >10) + } + + if(stage >= 11){ + line(player, "I found !!Caleb?? at his house?? in !!Catherby??", line++, stage >11) + line(player, "and told him of my Quest for his father to restore his Family Crest.", line++, stage >11) + line(player, "I gave !!Caleb?? the Swordfish, Bass, Tuna, Salmon and Shrimp he needed for his salad in return for his crest piece", line++, stage >11) + + } + if(stage >=12){ + line(player, "!!Caleb?? has told me to speak to the !!Gem trader??", line++, stage >12) + line(player, " in !!Al-Kharid?? to find his brother.", line++, stage >12) + } + if(stage >=13){ + line(player, "I found !!Avan?? by some gold rocks North of !!Al Kharid??.", line++, stage >13) + } + if(stage >= 14){ + line(player, "!!Avan?? has asked me to find the perfect gold, he has heard of a !!dwarf??", line++, stage >14) + line(player, "who might know where to get some", line++, stage >14) + } + if(stage >=15){ + line(player, "I have spoken to !!Boot?? and he told me that ", line++, stage >15) + line(player, "i can find perfect gold in the !!Witchaven dungeons??", line++, stage >15) + } + if(stage >=16){ + line(player, "!!Avan?? gave me his crest piece in return for a ruby ring ", line++, stage >16) + line(player, "and ruby necklace made of high quality 'perfect gold'.", line++, stage >16) + } + if(stage >= 17){ + line(player, "I found !!Johnathon?? looking very ill at the !!Jolly Boar Inn??.", line++, stage >17) + } + if(stage >= 18){ + line(player, "He soon recovered when I used an antipoison potion on him.", line++, stage >18) + } + if(stage >= 19){ + line(player, "He has told me about the Demon !!Chronozon?? located in the !!Edgeville dungeon??", line++, stage > 19) + } + if(stage >= 20){ + line(player, "I defeated the Demon !!Chronozon?? and obtained !!Johnathon??'s crest piece", line++, stage > 20) + } + if(stage == 100){ + line(player, "I took all three pieces of the crest back to !!Dimintheis?? in !!Varrock??", line++) + line(player, "As a reward !!Dimintheis?? gave me some !!magical gauntlets?? ", line++) + line(player, "that could be enchanted by his sons", line++) + line(player, "to give them bonuses in specific skillss", line++) + line(player, "and would always return to !!Dimintheis??", line++) + line(player, "for me to reclaim if I ever lost them.", line++) + line++ + line(player, "%%QUEST COMPLETE!&&.", line++) + } + + + } + + override fun hasRequirements(player: Player?): Boolean { + if (player != null) { + if (player.skills.getLevel(Skills.CRAFTING) < 40) + return false + if (player.skills.getLevel(Skills.SMITHING) < 40) + return false + if(player.skills.getLevel(Skills.MINING) < 40) + return false + if( player.skills.getLevel(Skills.MAGIC) < 59) + return false + return true + } + return false + } + + override fun finish(player: Player?) { + super.finish(player) + player ?: return + var ln = 10 + player.packetDispatch.sendItemZoomOnInterface(Items.COOKING_GAUNTLETS_775,230,277,5) + drawReward(player,"1 Quest Point",ln++) + drawReward(player,"Family Gauntlets",ln++) + drawReward(player,"A choice of special abilities for the gauntlets",ln++) + drawReward(player,"for the gauntlets",ln++) + + if (!addItem(player, Items.FAMILY_GAUNTLETS_778)) { + log(this::class.java, Log.ERR, "Failed to give gauntlets to ${player.username} at end of quest, this should not occur due to crest item removal needed to finish quest.") + } + setAttribute(player, "/save:family-crest:gauntlets", Items.FAMILY_GAUNTLETS_778) + } + + /*override fun getConfig(player: Player?, stage: Int): IntArray { + if(stage == 100) return intArrayOf(1282, 90) + if(stage > 0) return intArrayOf(1282, 1) + else return intArrayOf(1282, 0) + }*/ +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/familycrest/JohnathonAntiPoisonInteraction.kt b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/JohnathonAntiPoisonInteraction.kt new file mode 100644 index 0000000..9c12e51 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/JohnathonAntiPoisonInteraction.kt @@ -0,0 +1,34 @@ +package content.region.misthalin.varrock.quest.familycrest + + +import core.api.* +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import content.data.Quests + +class JohnathonAntiPosionInteraction: InteractionListener { + override fun defineListeners() { + val poisons = intArrayOf(Items.ANTIPOISON4_2446, Items.ANTIPOISON3_175, Items.ANTIPOISON2_177, Items.ANTIPOISON1_179) + + onUseWith(IntType.NPC, poisons, NPCs.JOHNATHON_668){ player, used, with -> + val npc = with.asNpc() + val antip = used.asItem() + val stage = getQuestStage(player, Quests.FAMILY_CREST) + + val index = poisons.indexOf(used.id) + val returnItem = if(index + 1 == poisons.size) Items.VIAL_229 else poisons[index + 1] + + if(stage == 17 && removeItem(player, antip)){ + addItem(player, returnItem) + setQuestStage(player, Quests.FAMILY_CREST, 18) + openDialogue(player, NPCs.JOHNATHON_668, npc) + } else { + sendMessage(player, "Nothing interesting happens.") + } + + return@onUseWith true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/quest/familycrest/JohnathonDialogue.kt b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/JohnathonDialogue.kt new file mode 100644 index 0000000..c0e6d6f --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/JohnathonDialogue.kt @@ -0,0 +1,128 @@ +package content.region.misthalin.varrock.quest.familycrest + + +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import org.rs09.consts.Items +import content.data.Quests + +@Initializable +class JohnathonDialogue(player: Player? = null): DialoguePlugin(player) { + val CREST_PIECE: Item = Item(781) + override fun newInstance(player: Player?): DialoguePlugin { + return JohnathonDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = (args[0] as NPC).getShownNPC(player) + val qstage = player?.questRepository?.getStage(Quests.FAMILY_CREST) ?: -1 + + if (qstage == 100) { + options("Can you change my gauntlets for me?", "Nevermind") + stage = 6000 + return true + } + + if(qstage < 16){ + npc("I don't feel so well... maybe we can talk later") + stage = 1000 + } + else{ + when(qstage){ + 16 -> player("Greetings. Would you happen to be Johnathon Fitzharmon?").also { stage = 1} + 17 -> npc("What... what did that spider... DO to me? " , + "I... I feel so weak... " , + "I can hardly... think at all...").also { stage = 1000 } + 18 -> sendDialogue("You use the potion on Johnathon").also { stage = 100 } + 19 -> player("I'm trying to kill this demon Chronozon that you mentioned...").also { stage = 200 } + } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage) { + + 1 -> npc("That... I am...").also { stage++ } + 2 -> player("I am here to retrieve your fragment " , + "of the Fitzharmon family crest.").also { stage++ } + 3 -> npc("The... poison... it is all... " , + "too much... My head... " , + "will not... stop spinning...").also { stage++ } + 4 -> sendDialogue("Sweat is pouring down Jonathons' face.").also { stage = 1000 + player.questRepository.getQuest(Quests.FAMILY_CREST).setStage(player, 17) + } + + 100 -> npc("Ooooh... thank you... Wow! " , + "I'm feeling a lot better now! " , + "That potion really seems to have done the trick!").also{stage++} + 101 -> npc("How can I reward you?").also { stage++ } + + 102 -> player("I've come here for your piece of the Fitzharmon family crest.").also { stage++} + + 103 -> npc("You have? Unfortunately I don't have it any more... " , + "in my attempts to slay the fiendish Chronozon, the blood demon, " , + "I lost a lot of equipment in our last battle when he " , + "bested me and forced me away from his den. He probably still has it now.").also{ + stage = 200 + player.questRepository.getQuest(Quests.FAMILY_CREST).setStage(player, 19) + } + + 200 -> options("So is this Chronozon hard to defeat?", "Where can I find Chronozon?", "So how did you end up getting poisoned?", "I will be on my way now.").also{stage++} + 201 -> when(buttonId){ + 1-> npc("Well... you will have to be a skilled Mage to defeat him, " , + "and my powers are not good enough yet. " , + "You will need to hit him once with each of the four " , + "elemental spells of death before he will be defeated.").also{stage = 1000} + + 2->npc("The fiend has made his lair in Edgeville Dungeon. " , + "When you come in down the ladder in Edgeville, follow" , + "the corridor north until you reach a room with skeletons. " , + "That passageway to the left will lead you to him.").also{stage = 1000} + + 3 -> npc("Those accursed poison spiders that surround " , + "the entrance to Chronozon's lair... " , + "I must have taken a nip from one of them " , + "as I attempted to make my escape.").also{stage = 1000} + + 4 -> npc("My thanks for the assistance adventure").also{stage = 1000} + + } + 6000 -> when (buttonId) { + 1 -> { + var freeThisTime = getAttribute(player, "family-crest:gauntlets", Items.FAMILY_GAUNTLETS_778) == Items.FAMILY_GAUNTLETS_778 + npc("Yes certainly, though it will cost you 25,000 coins" + if (freeThisTime) " next time." else ".").also { stage = 6001 } + } + 2 -> player("Never mind").also{ stage = 1000 } + } + 6001 -> options("Great thanks!", "No that's okay thanks.").also{ stage++ } + 6002 -> when (buttonId) { + 1 -> { + stage = 1000 + val givingGauntletsId = Items.CHAOS_GAUNTLETS_777 + val npcString = SwapGauntletsHelper.swapGauntlets(player, givingGauntletsId) + if (npcString == "") + { + end() + } + else { + npc(npcString) + } + } + 2 -> end() + } + + 1000 -> end() + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(668) + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/familycrest/PerfectGoldSmeltingHandler.kt b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/PerfectGoldSmeltingHandler.kt new file mode 100644 index 0000000..cec2f65 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/PerfectGoldSmeltingHandler.kt @@ -0,0 +1,48 @@ +package content.region.misthalin.varrock.quest.familycrest + + +import core.api.addItem +import core.api.animate +import core.api.removeItem +import core.game.interaction.NodeUsageEvent +import core.game.interaction.UseWithHandler +import core.game.node.entity.skill.Skills +import content.global.skill.smithing.FurnaceOptionPlugin +import core.game.system.task.Pulse +import core.plugin.Initializable +import core.plugin.Plugin +import org.rs09.consts.Items +import core.game.world.GameWorld.Pulser + + +@Initializable +class PerfectGoldSmeltingHandler : UseWithHandler(Items.PERFECT_GOLD_ORE_446){ + + + private val furnaceIDs: IntArray = FurnaceOptionPlugin.SmeltUseWithHandler.furnaceIDS + + override fun newInstance(arg: Any?): Plugin { + for(furnace in furnaceIDs){ + addHandler(furnace, OBJECT_TYPE, this) + } + return this + } + + override fun handle(event: NodeUsageEvent?): Boolean { + + event ?: return false + val player = event.player + + Pulser.submit(object : Pulse(2, player) { + override fun pulse(): Boolean { + if(removeItem(player,Items.PERFECT_GOLD_ORE_446)){ + animate(player,3243) + addItem(player,Items.PERFECT_GOLD_BAR_2365) + player.skills.addExperience(Skills.SMITHING,22.5) + } + return true + } + }) + return true + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/familycrest/PerfectJewelryHandler.kt b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/PerfectJewelryHandler.kt new file mode 100644 index 0000000..ff615e0 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/PerfectJewelryHandler.kt @@ -0,0 +1,63 @@ +package content.region.misthalin.varrock.quest.familycrest + +import core.game.dialogue.DialogueInterpreter +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable + + +@Initializable +class PerfectJewelryHandler (player: Player? = null): DialoguePlugin(player){ + + override fun newInstance(player: Player?): DialoguePlugin { + return PerfectJewelryHandler(player) + } + + override fun open(vararg args: Any?): Boolean { + if(player.inventory.containItems(2365, 1603)){ + options("Craft perfect ruby ring", "Craft perfect ruby necklace") + stage = 1 + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + + when(stage){ + 1-> when(buttonId){ + + 1-> if(player.inventory.containItems(2365, 1603,1592)) { + player.inventory.remove(Item(2365), Item(1603)) + player.inventory.add(Item(773)) + sendDialogue("You made a perfect gold ring.") + stage = 1000 + } + else{ + sendDialogue("You do not have everything to make this item.") + stage = 1000 + } + + 2-> if(player.inventory.containItems(2365, 1603) && player.inventory.containItems(1597)){ + player.inventory.remove(Item(2365), Item(1603)) + player.inventory.add(Item(774)) + sendDialogue("You made a perfect gold necklace.") + stage = 1000 + } + else{ + sendDialogue("You do not have everything to make this item.") + stage = 1000 + } + } + + 1000 -> end() + } + + return true + } + + override fun getIds(): IntArray { + return intArrayOf(DialogueInterpreter.getDialogueKey("perfect-jewelry")) + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/familycrest/PerfectJewelryOnUseHandler.kt b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/PerfectJewelryOnUseHandler.kt new file mode 100644 index 0000000..4d258b5 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/PerfectJewelryOnUseHandler.kt @@ -0,0 +1,28 @@ +package content.region.misthalin.varrock.quest.familycrest + +import org.rs09.consts.Items + +import core.game.interaction.NodeUsageEvent +import core.game.interaction.UseWithHandler +import core.plugin.Initializable +import core.plugin.Plugin + +@Initializable +class PerfectJewelryOnUseHandler : UseWithHandler(Items.PERFECT_GOLD_BAR_2365){ + val furnaceIDs = listOf(2349, 2351, 2353, 2359, 2361, 2363, 2366, 2368, 9467, 11286, 1540, 11710, 11712, 11714, 11666, 11686, 11688, 11692) + override fun newInstance(arg: Any?): Plugin { + for(furnaces in furnaceIDs){ + addHandler(furnaces, OBJECT_TYPE, this) + } + return this + } + + override fun handle(event: NodeUsageEvent?): Boolean { + event ?: return false + event.player.dialogueInterpreter.open("perfect-jewelry") + return true + } + +} + +//event.getPlayer().getDialogueInterpreter().open("perfect-jewelry"); diff --git a/Server/src/main/content/region/misthalin/varrock/quest/familycrest/SwapGauntletsHelper.kt b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/SwapGauntletsHelper.kt new file mode 100644 index 0000000..ebe4a88 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/SwapGauntletsHelper.kt @@ -0,0 +1,45 @@ +package content.region.misthalin.varrock.quest.familycrest + +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.item.Item +import org.rs09.consts.Items + +class SwapGauntletsHelper { + companion object { + private val legalGauntlets = setOf(Items.COOKING_GAUNTLETS_775, Items.GOLDSMITH_GAUNTLETS_776, Items.CHAOS_GAUNTLETS_777, Items.FAMILY_GAUNTLETS_778) + + @JvmStatic + fun swapGauntlets(player: Player, givingGauntletsId: Int): String { + if (givingGauntletsId !in legalGauntlets) { + throw IllegalArgumentException("givingGauntletsId not in list of legal gauntlets.") + } + if (inInventory(player, givingGauntletsId)) { + val gauntletString = Item(givingGauntletsId).name + return "You already have the $gauntletString." + } + var otherGauntlets = -1 + val otherPossibleGauntlets = legalGauntlets.toMutableSet() + otherPossibleGauntlets.remove(givingGauntletsId) + for (gauntletId in otherPossibleGauntlets) { + if (inInventory(player, gauntletId)) + { + otherGauntlets = gauntletId + } + } + if (otherGauntlets == -1) { + return "You do not have the gauntlets with you in your inventory." + } + val fee = 25000 + val shouldBeFree = getAttribute(player, "family-crest:gauntlets", Items.FAMILY_GAUNTLETS_778) == Items.FAMILY_GAUNTLETS_778 + if (!shouldBeFree && !inInventory(player, Items.COINS_995, fee)) { + return "You do not have enough coins." + } + if ((shouldBeFree || removeItem(player, Item(Items.COINS_995, fee))) && removeItem(player, otherGauntlets)) { + addItem(player, givingGauntletsId) + setAttribute(player, "/save:family-crest:gauntlets", givingGauntletsId) + } + return "" + } + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/familycrest/WitchavenLeverInteraction.kt b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/WitchavenLeverInteraction.kt new file mode 100644 index 0000000..af534f4 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/familycrest/WitchavenLeverInteraction.kt @@ -0,0 +1,102 @@ +package content.region.misthalin.varrock.quest.familycrest + +import core.game.node.entity.impl.ForceMovement +import core.game.node.entity.player.Player +import core.game.node.scenery.Scenery +import core.game.world.map.Direction +import core.game.world.map.RegionManager +import core.game.world.update.flag.context.Animation +import core.net.packet.out.ClearScenery +import core.net.packet.out.ConstructScenery +import core.net.packet.out.UpdateAreaPosition +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import content.data.Quests + +fun doDoor(player: Player, scenery: Scenery) { + val d = if(scenery.rotation == 0 || scenery.rotation == 3) { -1 } else { 0 } + var direction = Direction.NORTH + if(scenery.rotation % 2 == 0) { + direction = if(player.location.x <= scenery.location.x + d) { Direction.EAST } else { Direction.WEST } + } else { + direction = if(player.location.y <= scenery.location.y + d) { Direction.NORTH } else { Direction.SOUTH } + } + ForceMovement.run(player, + player.location, + player.location.transform(direction.stepX, direction.stepY, 0), + ForceMovement.WALK_ANIMATION, + ForceMovement.WALK_ANIMATION, + direction, + 8) + +} + +class WitchavenLeverInteraction : InteractionListener { + val DOWN_ANIMATION = Animation(2140) + val UP_ANIMATION = Animation(2139) + + // TODO: It seems like the even numbers are used for the "up" positions, but there's no parent object with varps for them. + // Currently, we just send a `ConstructScenery` packet to the specific player. Is there a cleaner way to do this? + val NORTH_LEVER_A = 2421 + val NORTH_LEVER_B = 2425 + val SOUTH_LEVER = 2423 + val LEVERS = intArrayOf(NORTH_LEVER_A, NORTH_LEVER_A+1, NORTH_LEVER_B, NORTH_LEVER_B+1, SOUTH_LEVER, SOUTH_LEVER+1) + + val NORTH_DOOR = 2431 // 92 in RSC + val HELLHOUND_DOOR = 2430 // 91 in RSC + val SOUTHWEST_DOOR = 2427 // 90 in RSC + val SOUTHEAST_DOOR = 2429 // 88 in RSC + val DOORS = intArrayOf(NORTH_DOOR, HELLHOUND_DOOR, SOUTHWEST_DOOR, SOUTHEAST_DOOR) + + override fun defineListeners() { + on(LEVERS, IntType.SCENERY, "pull") { player, node -> + val baseId = if(node.id % 2 == 0) { node.id - 1 } else { node.id } + if(player.questRepository.getQuest(Quests.FAMILY_CREST).getStage(player) == 0) { + player.sendMessage("Nothing interesting happens.") + } + val old = player.getAttribute("family-crest:witchaven-lever:${baseId}", false) + player.setAttribute("family-crest:witchaven-lever:${baseId}", !old) + val direction = if(old) { "down" } else { "up" } + player.sendMessage("You pull the lever ${direction}.") + player.sendMessage("You hear a clunk.") + player.animate(if(old) { DOWN_ANIMATION } else { UP_ANIMATION }) + val downLever = (node as Scenery).transform(baseId) + val upLever = (node as Scenery).transform(baseId + 1) + player.debug("lever: ${downLever.id} ${upLever.id}") + val buffer = UpdateAreaPosition.getChunkUpdateBuffer(player, RegionManager.getRegionChunk(player.location).currentBase) + if(old) { + // TODO: This doesn't seem to properly make the lever return to the "down" position visually. + ClearScenery.write(buffer, upLever) + ConstructScenery.write(buffer, downLever) + //PacketRepository.send(ClearScenery::class.java, BuildSceneryContext(player, downLever)) + } else { + ClearScenery.write(buffer, downLever) + ConstructScenery.write(buffer, upLever) + //PacketRepository.send(ConstructScenery::class.java, BuildSceneryContext(player, upLever)) + } + player.session.write(buffer) + return@on true + } + on(DOORS, IntType.SCENERY, "open") { player, node -> + val northA = player.getAttribute("family-crest:witchaven-lever:${NORTH_LEVER_A}", false) + val northB = player.getAttribute("family-crest:witchaven-lever:${NORTH_LEVER_B}", false) + val south = player.getAttribute("family-crest:witchaven-lever:${SOUTH_LEVER}", false) + val questComplete = player.questRepository.getQuest(Quests.FAMILY_CREST).getStage(player) >= 100 + // Authentic door formulae from https://gitlab.com/open-runescape-classic/core/-/blob/develop/server/plugins/com/openrsc/server/plugins/authentic/quests/members/FamilyCrest.java#L575-657 + val canPass = when(node.id) { + NORTH_DOOR -> !northA && (south || northB) + HELLHOUND_DOOR -> questComplete || (northA && northB && !south) + SOUTHWEST_DOOR -> (northA && !south) || (northA && northB && !south) + SOUTHEAST_DOOR -> (northA && south) || (northA && northB && south) + else -> false + } + if(canPass) { + player.sendMessage("The door swings open. You go through the door.") + doDoor(player, node as Scenery) + } else { + player.sendMessage("The door is locked.") + } + return@on true + } + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/gertrude/FluffNPC.java b/Server/src/main/content/region/misthalin/varrock/quest/gertrude/FluffNPC.java new file mode 100644 index 0000000..fd90e43 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/gertrude/FluffNPC.java @@ -0,0 +1,56 @@ +package content.region.misthalin.varrock.quest.gertrude; + +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.game.world.map.Location; +import content.data.Quests; + +/** + * Represents the plugin used for the fluff npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class FluffNPC extends AbstractNPC { + + /** + * The NPC ids of NPCs using this plugin. + */ + private static final int[] ID = { 2997 }; + + /** + * Constructs a new {@code FluffNPC} {@code Object}. + */ + public FluffNPC() { + super(0, null); + } + + /** + * Constructs a new {@code FluffNPC} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + private FluffNPC(int id, Location location) { + super(id, location); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new FluffNPC(id, location); + } + + @Override + public boolean isHidden(final Player player) { + if (player.getQuestRepository().getQuest(Quests.GERTRUDES_CAT).getStage(player) < 20) { + return true; + } + return player.getAttribute("hidefluff", 0L) > System.currentTimeMillis(); + } + + @Override + public int[] getIds() { + return ID; + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/gertrude/GertrudesCat.java b/Server/src/main/content/region/misthalin/varrock/quest/gertrude/GertrudesCat.java new file mode 100644 index 0000000..c4eb025 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/gertrude/GertrudesCat.java @@ -0,0 +1,117 @@ +package content.region.misthalin.varrock.quest.gertrude; + +import core.plugin.Initializable; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.tools.RandomFunction; + +import static core.api.ContentAPIKt.addItemOrBank; +import content.data.Quests; + +/** + * Represents the gertrudes fortress quest. + * @author 'Vexia + */ +@Initializable +public class GertrudesCat extends Quest { + + /** + * Constructs a new {@code GertrudesCat} {@code Object}. + */ + public GertrudesCat() { + super(Quests.GERTRUDES_CAT, 67, 66, 1, 180, 0, 1, 100); + } + + @Override + public void drawJournal(Player player, int stage) { + super.drawJournal(player, stage); + switch (stage) { + case 0: + player.getPacketDispatch().sendString(BLUE+ "I can start this quest by speaking to " + RED + "Gertrude.", 275, 4+ 7); + player.getPacketDispatch().sendString(BLUE+ "She can be found to the " + RED + "west of Varrock.", 275, 5+ 7); + break; + case 10: + player.getPacketDispatch().sendString("I accepted the challenge of finding Gertrude's lost cat.", 275, 4+ 7); + player.getPacketDispatch().sendString(BLUE+ "I need " + RED + "to speak to Shilop and Wilough" + BLUE+ " at the " + RED + "marketplace.", 275, 6+ 7); + break; + case 20: + player.getPacketDispatch().sendString("I accepted the challenge of finding Gertrude's lost cat.", 275, 4+ 7); + player.getPacketDispatch().sendString("I spoke to Shilop, Gertrude's Son.", 275, 5+ 7); + player.getPacketDispatch().sendString(BLUE+ "I need to " + RED + "go to their play area " + BLUE+ "and " + RED + "find the lost cat and", 275, 7+ 7); + player.getPacketDispatch().sendString(RED + "return it to Gertrude.", 275, 8+ 7); + break; + case 30: + player.getPacketDispatch().sendString("I accepted the challenge of finding Gertrude's lost cat.", 275, 4+ 7); + player.getPacketDispatch().sendString("I spoke to Shilop, Gertrude's Son.", 275, 5+ 7); + player.getPacketDispatch().sendString("I found the lost cat but it won't come back.", 275, 6+ 7); + player.getPacketDispatch().sendString(RED + "I still need to " + RED + "get her to follow me home.", 275, 8+ 7); + break; + case 40: + case 50: + player.getPacketDispatch().sendString("I accepted the challenge of finding Gertrude's lost cat.", 275, 4+ 7); + player.getPacketDispatch().sendString("I spoke to Shilop, Gertrude's Son.", 275, 5+ 7); + player.getPacketDispatch().sendString("I found the lost cat but it won't come back.", 275, 6+ 7); + player.getPacketDispatch().sendString("I gave the cat milk and sardines.", 275, 7+ 7); + player.getPacketDispatch().sendString(BLUE+ "I still need to " + RED + "get her to follow me home.", 275, 9+ 7); + break; + case 60: + player.getPacketDispatch().sendString("I accepted the challenge of finding Gertrude's lost cat.", 275, 4+ 7); + player.getPacketDispatch().sendString("I spoke to Shilop, Gertrude's Son.", 275, 5+ 7); + player.getPacketDispatch().sendString("I found the lost cat but it won't come back.", 275, 6+ 7); + player.getPacketDispatch().sendString("I gave the cat milk and sardines.", 275, 7+ 7); + player.getPacketDispatch().sendString(BLUE+ "She ran off home.", 275, 9+ 7); + break; + case 100: + player.getPacketDispatch().sendString("I helped Gertrude to find her lost cat,", 275, 4+ 7); + player.getPacketDispatch().sendString("I fed it and returned her missing kitten,", 275, 5+ 7); + player.getPacketDispatch().sendString("Gertrude gave me my very own pet for a reward.", 275, 6+ 7); + player.getPacketDispatch().sendString("QUEST COMPLETE!", 275, 8+ 7); + break; + } + } + + @Override + public void finish(Player player) { + super.finish(player); + final Item kitten = getKitten(); + player.getPacketDispatch().sendString("1 Quest Point", 277, 8 + 2); + player.getPacketDispatch().sendString("A kitten!", 277, 9 + 2); + player.getPacketDispatch().sendString("1525 Cooking XP", 277, 10 + 2); + player.getPacketDispatch().sendString("A chocolate cake", 277, 11 + 2); + player.getPacketDispatch().sendString("A bowl of stew", 277, 12 + 2); + player.getPacketDispatch().sendString("The ability to raise cats", 277, 13 + 2); + player.getSkills().addExperience(Skills.COOKING, 1525); + player.getPacketDispatch().sendItemZoomOnInterface(kitten.getId(), 240, 277, 3 + 2); + setStage(player, 100); + if (player.getFamiliarManager().hasFamiliar()) { + addItemOrBank(player, kitten.getId(), 1); + } else { + player.getFamiliarManager().summon(kitten, true, false); + } + final Item cake = new Item(1897); + final Item stew = new Item(2003); + if (!player.getInventory().add(cake)) { + GroundItemManager.create(cake, player.getLocation(), player); + } + if (!player.getInventory().add(stew)) { + GroundItemManager.create(stew, player.getLocation(), player); + } + } + + /** + * Method used to get a random kitten. + * @return the item. + */ + public Item getKitten() { + return new Item(RandomFunction.random(1555, 1560)); + } + + @Override + public Quest newInstance(Object object) { + // TODO Auto-generated method stub + return this; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/gertrude/LumberKittenNPC.java b/Server/src/main/content/region/misthalin/varrock/quest/gertrude/LumberKittenNPC.java new file mode 100644 index 0000000..51ab6f1 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/gertrude/LumberKittenNPC.java @@ -0,0 +1,96 @@ +package content.region.misthalin.varrock.quest.gertrude; + +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.tools.RandomFunction; +import content.data.Quests; + +/** + * Represents the lumber kittens at the lumber yard. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class LumberKittenNPC extends AbstractNPC { + + /** + * Represents if the kitten is hidden. + */ + private boolean hidden = true; + + /** + * Represents the next time you can do a speak. + */ + private int nextSpeak; + + /** + * Represents the delay of hiding again. + */ + private int hideDelay; + + /** + * Constructs a new {@code LumberKittenNPC} {@code Object}. + */ + public LumberKittenNPC() { + super(0, null); + } + + /** + * Constructs a new {@code LumberKittenNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + private LumberKittenNPC(int id, Location location) { + super(id, location, false); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new LumberKittenNPC(id, location); + } + + @Override + public void init() { + setWalks(false); + super.init(); + } + + @Override + public void tick() { + if (nextSpeak < GameWorld.getTicks()) { + hidden = false; + nextSpeak = GameWorld.getTicks() + RandomFunction.random(10, 40); + hideDelay = GameWorld.getTicks() + 4; + sendChat("Mew!"); + } + if (hideDelay < GameWorld.getTicks()) { + hidden = true; + int rand = RandomFunction.random(20, 40); + hideDelay = GameWorld.getTicks() + rand; + nextSpeak = GameWorld.getTicks() + rand; + } + super.tick(); + } + + @Override + public boolean isHidden(final Player player) { + Quest quest = player.getQuestRepository().getQuest(Quests.GERTRUDES_CAT); + if (hidden) { + return true; + } + if (quest.getStage(player) < 20 || quest.getStage(player) > 50) { + return true; + } + return false; + } + + @Override + public int[] getIds() { + return new int[] { 767 }; + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/romeo/JulietCutscenePlugin.java b/Server/src/main/content/region/misthalin/varrock/quest/romeo/JulietCutscenePlugin.java new file mode 100644 index 0000000..da943fa --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/romeo/JulietCutscenePlugin.java @@ -0,0 +1,118 @@ +package content.region.misthalin.varrock.quest.romeo; + +import core.game.activity.ActivityPlugin; +import core.game.activity.CutscenePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.map.build.DynamicRegion; +import core.net.packet.PacketRepository; +import core.net.packet.context.CameraContext; +import core.net.packet.context.CameraContext.CameraType; +import core.net.packet.out.CameraViewPacket; +import core.plugin.Initializable; +import core.plugin.ClassScanner; + +/** + * Represents the romeo and juliet cutscene plugin. + * + * @author 'Vexia + * @date 31/12/2013 + */ +@Initializable +public final class JulietCutscenePlugin extends CutscenePlugin { + + /** + * Represents the location the player will return to. + */ + private static final Location SPAWN_LOCATION = Location.create(3166, 3431, 1); + + /** + * Constructs a new {@code JulietCutscenePlugin} {@code Object}. + */ + public JulietCutscenePlugin() { + this(null); + ClassScanner.definePlugin(new JulietDialogue()); + } + + /** + * Constructs a new {@code JulietCutscenePlugin} {@code Object}. + */ + public JulietCutscenePlugin(final Player player) { + super("Juliet Cutscene"); + this.player = player; + } + + @Override + public boolean start(final Player player, final boolean login, Object... args) { + NPC juliet = NPC.create(637, base.transform(29, 39, 1)); + juliet.setWalks(false); + npcs.add(juliet); + npcs.add(NPC.create(3325, base.transform(29, 38, 1))); + npcs.add(NPC.create(3324, base.transform(26, 41, 1))); + final Scenery door = RegionManager.getObject(getBase().transform(29, 41, 1)); + SceneryBuilder.remove(door); + for (NPC npc : npcs) { + npc.init(); + } + return super.start(player, login, args); + } + + @Override + public void open() { + int x = player.getLocation().getX(); + int y = player.getLocation().getY(); + CameraContext rot = null; + CameraContext pos = null; + int height = 390; + int speed = 100; + int other = 1; + pos = new CameraContext(player, CameraType.POSITION, x, y - 4, height, other, speed); + rot = new CameraContext(player, CameraType.ROTATION, x, y - 4, height, other, speed); + PacketRepository.send(CameraViewPacket.class, pos); + PacketRepository.send(CameraViewPacket.class, rot); + for (NPC npc : npcs) { + npc.face(player); + } + npcs.get(1).face(npcs.get(0)); + player.face(npcs.get(0)); + player.getDialogueInterpreter().open(npcs.get(0).getId(), npcs.get(0), this); + player.lock(); + player.getLocks().lockMovement(1000000); + } + + @Override + public void configure() { + region = DynamicRegion.create(12597); + setRegionBase(); + registerRegion(region.getId()); + } + + @Override + public Location getStartLocation() { + return getBase().transform(30, 39, 1); + } + + @Override + public ActivityPlugin newInstance(Player p) throws Throwable { + return new JulietCutscenePlugin(p); + } + + @Override + public Location getSpawnLocation() { + return SPAWN_LOCATION; + } + + /** + * Gets the phillipia npc. + * + * @return the npc. + */ + public NPC getPhillipia() { + return npcs.get(1); + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/romeo/JulietDialogue.java b/Server/src/main/content/region/misthalin/varrock/quest/romeo/JulietDialogue.java new file mode 100644 index 0000000..7d6b190 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/romeo/JulietDialogue.java @@ -0,0 +1,570 @@ +package content.region.misthalin.varrock.quest.romeo; + +import core.game.activity.ActivityManager; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.GroundItem; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.path.Path; +import core.game.world.map.path.Pathfinder; +import core.game.world.repository.Repository; +import core.game.world.update.flag.context.Animation; +import content.data.Quests; + +/** + * Represents the dialogue of the juliet NPC. + * @author 'Vexia + * @date 31/12/2013 + */ +public final class JulietDialogue extends DialoguePlugin { + + /** + * Represents the quest instance. + */ + private Quest quest; + + /** + * Represents the juliet cutscene plugin. + */ + private JulietCutscenePlugin cutscene; + + /** + * Represents the cadava potion(next stage = 70) + */ + private static final Item POTION = new Item(756); + + /** + * Represents the drinking animation. + */ + private static final Animation DRINK_ANIM = new Animation(1327); + + /** + * Constructs a new {@code JulietDialogue} {@code Object}. + */ + public JulietDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code JulietDialogue} {@code Object}. + * @param player the player. + */ + public JulietDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new JulietDialogue(player); + } + + @Override + public boolean open(Object... args) { + quest = player.getQuestRepository().getQuest(Quests.ROMEO_JULIET); + npc = (NPC) args[0]; + if (args.length > 1) { + cutscene = (JulietCutscenePlugin) args[1]; + interpreter.sendDialogues(npc, null, "Oh, here's Phillipa, my cousin...she's in on the plot too!"); + stage = 2000; + return true; + } + switch (quest.getStage(player)) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Romeo, Romeo, wherefore art thou Romeo? Bold", "adventurer, have you seen Romeo on your travels?", "Skinny guy, a bit wishy washy, head full of poetry."); + stage = 0; + break; + case 10: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Juliet, I come from Romeo.", "He begs me to tell you that he cares still."); + stage = 700; + break; + case 20: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello Juliet!"); + stage = 100; + break; + case 30: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hi Juliet, I have passed your message on to", "Romeo...he's scared half out of his wits at the news that", "your father wants to kill him."); + stage = 900; + break; + case 40: + interpreter.sendDialogues(player, null, "Hi Juliet, I've found Father Lawrence and he has a", "cunning plan. But for it to work, I need to seek the", "Apothecary!"); + stage = 236; + break; + case 50: + interpreter.sendDialogues(player, null, "Hi Juliet!"); + stage = 656; + break; + case 60: + if (!player.getInventory().contains(756, 1)) { + interpreter.sendDialogues(player, null, "Hi Juliet! I have an interesting proposition for", "you...suggested by Father Lawrence. It may be the", "only way you'll be able to escape from this house and", "be with Romeo."); + stage = 950; + } else { + interpreter.sendDialogues(player, null, "Hi Juliet! I have an interesting proposition for", "you...suggested by Father Lawrence. It may be the", "only way you'll be able to escape from this house and", "be with Romeo."); + stage = 950; + } + break; + case 70: + interpreter.sendDialogues(npc, null, "Quickly! Go and tell Romeo the plan!"); + stage = 1002; + break; + default: + npc(FacialExpression.ANGRY,"Oh, Romeo, that no good scoundrel!"); + stage = 22; + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + final Quest quest = player.getQuestRepository().getQuest(Quests.ROMEO_JULIET); + final NPC phil = cutscene != null ? cutscene.getPhillipia() : (NPC) Repository.findNPC(3325); + final NPC dad = cutscene != null ? cutscene.getNPCS().get(2) : (NPC) Repository.findNPC(3324); + switch (stage) { + case 2000: + interpreter.sendDialogues(npc, null, "She's going to make it seem even more convincing!"); + stage = 2001; + break; + case 2001: + interpreter.sendDialogues(phil, null, "Yes, I'm quite the actress! Good luck dear cousin!"); + stage = 2002; + break; + case 2002: + interpreter.sendDialogues(npc, null, "Right...bottoms up!"); + stage = 2003; + break; + case 2003: + close(); + GameWorld.getPulser().submit(new Pulse(1) { + int counter = 0; + + @Override + public boolean pulse() { + switch (counter++) { + case 0: + npc.animate(DRINK_ANIM); + break; + case 2: + interpreter.sendDialogues(npc, FacialExpression.THINKING, "Urk!"); + stage = 2004; + return true; + } + return false; + } + + }); + break; + case 2004: + close(); + npc.animate(new Animation(836)); + GameWorld.getPulser().submit(new Pulse(1) { + int counter = 0; + + @Override + public boolean pulse() { + switch (counter++) { + case 2: + interpreter.sendDialogues(phil, FacialExpression.THINKING, "Oh no...Juliet has...died!"); + stage = 2005; + return true; + } + return false; + } + + }); + break; + case 2005: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "You might be more believable if you're not smiling when", "you say it..."); + stage = 2006; + break; + case 2006: + interpreter.sendDialogues(phil, FacialExpression.HALF_GUILTY, "Oh yeah...you might be right...ok, let's try again."); + stage = 2007; + break; + case 2007: + interpreter.sendDialogues(phil, FacialExpression.HALF_GUILTY, "Oh no...Juliet has...died?"); + stage = 2008; + break; + case 2008: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Perhaps a bit louder, like you're upset...that your cousin", "has died!"); + stage = 2009; + break; + case 2009: + interpreter.sendDialogues(phil, FacialExpression.HALF_GUILTY, "Right...yes...Ok, ok, I think I'm getting my motivation", "now. Ok, let's try this again!"); + stage = 2010; + break; + case 2010: + interpreter.sendDialogues(phil, FacialExpression.FURIOUS, "OH NO...JULIET HAS...DIED?....", "Oooooohhhhhh....(sob), (sob).Juliet...my poor dead cousin!"); + stage = 2011; + break; + case 2011: + interpreter.sendDialogues(dad, null, "What's all that screaming?"); + stage = 2012; + break; + case 2012: + final Path path = Pathfinder.find(dad, player.getLocation().transform(0, 1, 0)); + path.walk(dad); + interpreter.sendDialogues(dad, null, "Oh no! My poor daughter...what has become of you?"); + stage = 2013; + break; + case 2013: + interpreter.sendDialogues(phil, FacialExpression.FURIOUS, "Poor Juliet...make preparations for her body to be", "placed in the Crypt..."); + stage = 2014; + break; + case 2014: + if (player.getInventory().remove(POTION)) { + quest.setStage(player, 70); + cutscene.stop(true); + end(); + } + break; + case 0: + interpreter.sendOptions("Select an Option", "Yes I've met him.", "No, I think I'd have remembered if I'd met him.", "I guess I could look for him for you."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Yes I've met him."); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No, I think I'd have remembered if I'd met him."); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I guess I could look for him for you."); + stage = 30; + break; + } + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Oh, well that's a shame, I was hopping that you might", "deliver a message to him for me."); + stage = 21; + break; + case 21: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Sorry, but I don't even know what he looks like."); + stage = 22; + break; + case 22: + end(); + break; + case 30: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Oh, that would be so wonderful of you!", "I'd be most grateful if you could please deliver a", "message to him?"); + stage = 31; + break; + case 31: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Certainly, I'll do it straight away."); + stage = 32; + break; + case 32: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Many thanks! Oh, i'm so very grateful. You may be", "our only hope."); + stage = 33; + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I'd be most grateful if you could please deliver a", "message to him?"); + stage = 31; + break; + case 33: + if (!player.getInventory().add(new Item(755))) { + GroundItemManager.create(new GroundItem(new Item(755), npc.getLocation(), player)); + } + quest.setStage(player, 20); + player.getQuestRepository().syncronizeTab(player); + interpreter.sendItemMessage(755, "Juliet gives you a message."); + stage = 34; + break; + case 34: + end(); + break; + case 100: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hello there...have you delivered the message to Romeo", "yet? What news do you have from my loved one?"); + stage = 101; + break; + case 101: + if (!player.getInventory().contains(755, 1) && !player.getBank().contains(755, 1)) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hmmm, that's the thing about messages....they're so easy", "to misplace..."); + stage = 105; + } else { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Oh, sorry, I've not had a chance to deliver it yet!"); + stage = 102; + } + break; + case 102: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Oh, that's a shame. I've been waiting so patiently to", "hear some word from him."); + stage = 103; + break; + case 103: + end(); + break; + case 105: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "How could you lose that message?", "It was incredibly important...and it took me an age to", "write! I used joined up writing and everything!"); + stage = 106; + break; + case 106: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Please, take this new message to him,", "and please don't loose it."); + stage = 107; + break; + case 107: + if (!player.getInventory().add(new Item(755))) { + GroundItemManager.create(new GroundItem(new Item(755), npc.getLocation(), player)); + } + quest.setStage(player, 20); + player.getQuestRepository().syncronizeTab(player); + interpreter.sendItemMessage(755, "Juliet gives you another message."); + stage = 108; + break; + case 108: + end(); + break; + case 900: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "yes, unfortunately my father is quite the hunter, you", "may have seen some the animal head trophies on the", "wall. And it would be so awful to see Romeo's head up", "there with them!"); + stage = 901; + break; + case 901: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I know what you mean..."); + stage = 902; + break; + case 902: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "...this hair colour will clash terribly with the rest of the", "decoration."); + stage = 903; + break; + case 903: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "That's not what I was suggesting at all..."); + stage = 904; + break; + case 904: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I know, I know...I was just kidding."); + stage = 905; + break; + case 905: + interpreter.sendDialogues(player, null, "Anyway, don't worry because I'm on the case. I'm", "going to get some help from Father Lawrence."); + stage = 906; + break; + case 906: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Oh yes, I'm sure that Father Lawrence will come up", "with a solution. I hope you find him soon."); + stage = 907; + break; + case 907: + end(); + break; + case 700: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Oh how my heart soars to hear this news! Please take", "this message to him with great haste."); + stage = 701; + break; + case 701: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Well, I hope it's good news...he was quite upset when I", "left him."); + stage = 702; + break; + case 702: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "He's quite often upset...the poor sensitive soul. But I", "don't think he's going to take this news very well,", "however, all is not lost."); + stage = 703; + break; + case 703: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Everything is explained in the letter, would you be so", "kind and deliver it to him please?"); + stage = 704; + break; + case 704: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Certainly, I'll do so straight away."); + stage = 705; + break; + case 705: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Many thanks! Oh, I'm so very grateful. You may be", "our only hope."); + stage = 706; + break; + case 706: + if (!player.getInventory().add(new Item(755))) { + GroundItemManager.create(new GroundItem(new Item(755), npc.getLocation(), player)); + } + quest.setStage(player, 20); + player.getQuestRepository().syncronizeTab(player); + interpreter.sendItemMessage(755, "Juliet gives you a message."); + stage = 707; + break; + case 707: + end(); + break; + case 236: + interpreter.sendDialogues(npc, null, "Oh good! I knew Father Lawrence would come up with", "something. However, I don't know where the apothecary", "is...I hope you find him soon. My father's temper gets", "no better."); + stage = 237; + break; + case 237: + end(); + break; + case 656: + interpreter.sendDialogues(npc, null, "Hi " + player.getUsername() + ", how close am I to being with my true", "love Romeo?"); + stage = 657; + break; + case 657: + interpreter.sendDialogues(player, null, "Sorry, I still have to get a speical potion for you."); + stage = 658; + break; + case 658: + interpreter.sendDialogues(npc, null, "Oh, I hope it isn't a love potion because you would be", "wasting your time. My love for Romeo grows stronger", "every minute..."); + stage = 659; + break; + case 659: + interpreter.sendDialogues(player, null, "That must be because you're not with him..."); + stage = 660; + break; + case 660: + interpreter.sendDialogues(npc, null, "Oh no! I long to be close to my true love Romeo!"); + stage = 661; + break; + case 661: + interpreter.sendDialogues(player, null, "Well, ok then...I'll set about getting this potion as quickly", "as I can!"); + stage = 662; + break; + case 662: + interpreter.sendDialogues(npc, null, "Fair luck to you, the end is close."); + stage = 663; + break; + case 663: + end(); + break; + case 950: + interpreter.sendDialogues(npc, null, "Go on...."); + stage = 951; + break; + case 951: + if (!player.getInventory().containsItem(POTION)) { + interpreter.sendDialogues(player, null, "Let me go get the potion.."); + stage = 663; + } else { + interpreter.sendDialogues(player, null, "I have a Cadava potion here, suggested by Father", "Lawrence. If you drink it, it will make you appear dead!"); + stage = 952; + } + break; + case 952: + interpreter.sendDialogues(npc, null, "Yes..."); + stage = 953; + break; + case 953: + interpreter.sendDialogues(player, null, "And when you appear dead...your still and lifeless", "corpse will be removed to the crypt!"); + stage = 954; + break; + case 954: + interpreter.sendDialogues(npc, null, "Oooooh, a cold dark creepy crypt..."); + stage = 955; + break; + case 955: + interpreter.sendDialogues(npc, null, "...sounds just peachy!"); + stage = 956; + break; + case 956: + interpreter.sendDialogues(player, null, "Then...Romeo can steal into the crypt and rescure you", "just as you wake up!"); + stage = 957; + break; + case 957: + interpreter.sendDialogues(npc, null, "...and this is the great idea for getting me out of here?"); + stage = 958; + break; + case 958: + interpreter.sendDialogues(player, null, "To be fair, I can't take all the credit...in fact...it was all", "Father Lawrence's suggestion..."); + stage = 959; + break; + case 959: + interpreter.sendDialogues(npc, null, "Ok...if this is the best we can do...hand over the potion!"); + stage = 960; + break; + case 960: + interpreter.sendItemMessage(756, "You pass the suspicious potion to Juliet."); + stage = 961; + break; + case 961: + interpreter.sendDialogues(npc, null, "Wonderful! I just hope Romeo can remember to get", "me from the crypt."); + stage = 962; + break; + case 962: + interpreter.sendDialogues(npc, null, "Please go to Romeo and make sure he understands.", "Although I love his gormless, lovelorn soppy ways, he", "can be a bit dense sometimes and I don't want to wake", "up in that crypt on my own."); + stage = 963; + break; + case 963: + interpreter.sendDialogues(npc, null, "Before I swig this potion down, let me stand on the", "balcony so that I might see the sun one last time before", "I am commited to the crypt."); + stage = 964; + break; + case 964: + end(); + ActivityManager.start(player, "Juliet Cutscene", false); + break; + case 965: + interpreter.sendDialogues(npc, null, "She's going to make it seem even more convincing!"); + stage = 966; + break; + case 966: + interpreter.sendDialogues(phil, null, "Yes, I'm quite the actress! Good luck dear cousin!"); + stage = 967; + break; + case 967: + interpreter.sendDialogues(npc, null, "Right...buttoms up!"); + stage = 968; + break; + case 968: + npc.animate(npc.getProperties().getDeathAnimation()); + interpreter.sendDialogues(npc, null, "Urk!"); + stage = 969; + break; + case 969: + interpreter.sendDialogues(phil, null, "Oh no...Juliet has...died!"); + stage = 970; + break; + case 970: + interpreter.sendDialogues(player, null, "You might be more believable if you're not smiling when", "you say it..."); + stage = 971; + break; + case 971: + interpreter.sendDialogues(phil, null, "Oh yeah...you might be right...ok, let's try again."); + stage = 972; + break; + case 972: + interpreter.sendDialogues(phil, null, "Oh no...Juliet has...died?"); + stage = 973; + break; + case 973: + interpreter.sendDialogues(player, null, "Perhaps a bit louder, like you're upset...that your cousin", "has died!"); + stage = 974; + break; + case 974: + interpreter.sendDialogues(phil, null, "Right...yes...Ok, ok, I think I'm getting my motivation", "now. Ok, let's try this again!"); + stage = 975; + break; + case 975: + interpreter.sendDialogues(phil, null, "OH NO...JULIET HAS...DIED?...", "Ooooooohhhhhh...(sob), (sob).Juliet...my poor dead cousin!"); + stage = 976; + break; + case 976: + interpreter.sendDialogues(dad, null, "What's all that screaming?"); + stage = 977; + break; + case 977: + interpreter.sendDialogues(dad, null, "Oh no! My poor daughter...what has become of you?"); + stage = 978; + break; + case 978: + interpreter.sendDialogues(phil, null, "Poor Juliet...make preparations for her body to be", "placed in the Crypt..."); + stage = 979; + break; + case 979: + end(); + break; + case 1002: + interpreter.sendDialogues(player, null, "I'm on my way!"); + stage = 979; + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 637 }; + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/romeo/JulietNPC.java b/Server/src/main/content/region/misthalin/varrock/quest/romeo/JulietNPC.java new file mode 100644 index 0000000..d87164e --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/romeo/JulietNPC.java @@ -0,0 +1,53 @@ +package content.region.misthalin.varrock.quest.romeo; + +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.game.world.map.Location; +import content.data.Quests; + +/** + * Represents the juliet npc. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class JulietNPC extends AbstractNPC { + + /** + * The NPC ids of NPCs using this plugin. + */ + private static final int[] ID = { 637 }; + + /** + * Constructs a new {@code AlKharidWarriorPlugin} {@code Object}. + */ + public JulietNPC() { + super(0, null); + } + + /** + * Constructs a new {@code AlKharidWarriorPlugin} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + private JulietNPC(int id, Location location) { + super(id, location); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new JulietNPC(id, location); + } + + @Override + public boolean isHidden(final Player player) { + return player.getQuestRepository().getQuest(Quests.ROMEO_JULIET).getStage(player) > 60 && player.getQuestRepository().getQuest(Quests.ROMEO_JULIET).getStage(player) < 100; + } + + @Override + public int[] getIds() { + return ID; + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/romeo/RJCutscenePlugin.java b/Server/src/main/content/region/misthalin/varrock/quest/romeo/RJCutscenePlugin.java new file mode 100644 index 0000000..17a33f2 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/romeo/RJCutscenePlugin.java @@ -0,0 +1,834 @@ +package content.region.misthalin.varrock.quest.romeo; + +import core.game.activity.ActivityManager; +import core.game.activity.ActivityPlugin; +import core.game.activity.CutscenePlugin; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.build.DynamicRegion; +import core.game.world.map.path.Path; +import core.game.world.map.path.Pathfinder; +import core.net.packet.PacketRepository; +import core.net.packet.context.CameraContext; +import core.net.packet.context.CameraContext.CameraType; +import core.plugin.Initializable; +import core.net.packet.out.CameraViewPacket; +import content.data.Quests; + +/** + * Represents the romeo and juliet cutscene plugin. + * + * @author 'Vexia + * @date 31/12/2013 + */ +@Initializable +public final class RJCutscenePlugin extends CutscenePlugin { + + /** + * Represents the location the player will return to. + */ + private static final Location SPAWN_LOCATION = Location.create(3211, 3424, 0); + + /** + * Constructs a new {@code RJCutscenePlugin} {@code Object}. + */ + public RJCutscenePlugin() { + this(null); + } + + /** + * Constructs a new {@code RJCutscenePlugin} {@code Object}. + */ + public RJCutscenePlugin(final Player player) { + super("Romeo & Juliet Cutscene"); + this.player = player; + } + + @Override + public boolean start(final Player player, final boolean login, Object... args) { + final NPC romeo = NPC.create(639, base.transform(30, 37, 0)); + romeo.setDirection(Direction.EAST); + romeo.faceLocation(getBase().transform(30, 38, 0)); + romeo.getLocks().lockMovement(10000); + romeo.setWalks(false); + npcs.add(NPC.create(639, base.transform(30, 37, 0))); + for (NPC npc : npcs) { + npc.init(); + } + return super.start(player, login, args); + } + + @Override + public void open() { + npcs.get(0).lock(); + player.getDialogueInterpreter().open(npcs.get(0).getId(), npcs.get(0), this); + int x = player.getLocation().getX(); + int y = player.getLocation().getY(); + CameraContext rot = null; + CameraContext pos = null; + int height = 450; + int speed = 100; + int other = 1; + pos = new CameraContext(player, CameraType.POSITION, x - 5, y - 4, height, other, speed); + rot = new CameraContext(player, CameraType.ROTATION, x + 2, y, height, other, speed); + PacketRepository.send(CameraViewPacket.class, pos); + PacketRepository.send(CameraViewPacket.class, rot); + player.lock(); + player.getLocks().lockMovement(1000000); + } + + @Override + public void configure() { + region = DynamicRegion.create(9288); + setRegionBase(); + registerRegion(region.getId()); + } + + @Override + public void fade() { + player.getQuestRepository().getQuest(Quests.ROMEO_JULIET).finish(player); + } + + @Override + public void register() { + new RomeoDialogue().init(); + } + + @Override + public Location getStartLocation() { + return getBase().transform(30, 38, 0); + } + + @Override + public ActivityPlugin newInstance(Player p) throws Throwable { + return new RJCutscenePlugin(p); + } + + @Override + public Location getSpawnLocation() { + return SPAWN_LOCATION; + } + + /** + * Gets the phillipia npc. + * + * @return the npc. + */ + public NPC getPhillipia() { + return npcs.get(1); + } + + /** + * Represents the plugin used to handle the romeo dialogue. + * + * @author 'Vexia + * @date 31/12/2013 + */ + public class RomeoDialogue extends DialoguePlugin { + + /** + * Represents the cutscene instance. + */ + private RJCutscenePlugin cutscene; + + /** + * Represents the phil npc. + */ + private NPC phill; + + /** + * Constructs a new {@code RomeoDialogue} {@code Object}. + */ + public RomeoDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code RomeoDialogue} {@code Object}. + * + * @param player + * the player. + */ + public RomeoDialogue(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[] { 639 }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + Quest quest = player.getQuestRepository().getQuest(Quests.ROMEO_JULIET); + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "No sorry. I haven't seen her.", "Perhaps I could help to find her for you?"); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No sorry. I haven't seen her."); + stage = 200; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Perhaps I can help find her for you? What does she", "look like?"); + stage = 10; + break; + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Oh would you? That would be great! She has this sort", "of hair..."); + stage = 11; + break; + case 11: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hair...check.."); + stage = 12; + break; + case 12: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "...and she these...great lips..."); + stage = 13; + break; + case 13: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Lips...right."); + stage = 14; + break; + case 14: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Oh and she has these lovley shoulders as well.."); + stage = 15; + break; + case 15: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Shoulders...right so she has hair, lips and shoulders...that", "should cut it down a bit."); + stage = 16; + break; + case 16: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Oh yes, Juliet Is very different...please tell her that she", "is the love of my long and that I life to be with her?"); + stage = 17; + break; + case 17: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What?", "Surely you mean that 'she is the love of your life and", "that you long to be with her?"); + stage = 18; + break; + case 18: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Oh yeah...what you said...tell her that, it sounds much", "bettter!", "Oh you're so good at this!"); + stage = 19; + break; + case 19: + interpreter.sendOptions("Select an Option", "Yes okay, I'll let her know.", "Sorry Romeo, I've got better things to do right now but", "maybe later?"); + stage = 20; + break; + case 20: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Yes, ok, I'll let her know."); + stage = 100; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Sorry Romeo, I've got better things to do right now but maybe latter?"); + stage = 50; + break; + case 3: + end(); + break; + } + break; + case 100: + quest.setStage(player, 10); + player.getQuestRepository().syncronizeTab(player); + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Oh great! And tell her that I want to kiss her a give."); + stage = 101; + break; + case 101: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "You mean you want to give her a kiss!"); + stage = 102; + break; + case 102: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Oh you're good...you are good!"); + stage = 103; + break; + case 103: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I see I've picked a true professional...!"); + stage = 104; + break; + case 104: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ok, thanks."); + stage = 106; + break; + case 105: + switch (buttonId) { + case 1: + break; + case 2: + break; + case 3: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ok, thanks."); + stage = 106; + break; + } + break; + case 106: + end(); + break; + case 200: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "If you do see her please tell me!"); + stage = 201; + break; + case 201: + end(); + break; + case 230: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Please, oh please! Tell me where you have seen my juliet."); + stage = 231; + break; + case 231: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I found her alone on a balcony!"); + stage = 255; + break; + case 255: + end(); + break; + case 300: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Oh great! That is great news! Well done...well done...", "what a total success!"); + stage = 301; + break; + case 301: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Yes, and she gave me a message to give you..."); + stage = 302; + break; + case 302: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ohh great! A message...wow!"); + stage = 303; + break; + case 303: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Yes!"); + stage = 304; + break; + case 304: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "A message...oh, I can't wait to read what my dear Juliet", "has to say...."); + stage = 305; + break; + case 305: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I know...it's exiting isn't it...?"); + stage = 306; + break; + case 306: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Yes...yes..."); + stage = 307; + break; + case 307: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "..."); + stage = 308; + break; + case 308: + interpreter.sendDialogues(npc, FacialExpression.OLD_SNEAKY, "You've lost the message haven't you?"); + stage = 309; + break; + case 309: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Yep, haven't got a clue where it is."); + stage = 310; + break; + case 310: + end(); + break; + case 400: + interpreter.sendItemMessage(755, "You hand over Juliet's message to Romeo."); + stage = 401; + break; + case 401: + interpreter.sendDialogues(npc, null, "Oh, a message! A message! I've never had a message", "before..."); + stage = 402; + break; + case 402: + interpreter.sendDialogues(player, null, "Really?"); + stage = 403; + break; + case 403: + interpreter.sendDialogues(npc, null, "No, no, not one!"); + stage = 404; + break; + case 404: + interpreter.sendDialogues(npc, null, "Oh, well, except for the occasional court summons."); + stage = 405; + break; + case 405: + interpreter.sendDialogues(npc, null, "But they're not really 'nice' messages. Not like this one!", "I'm sure that this message will be lovely."); + stage = 406; + break; + case 406: + interpreter.sendDialogues(player, null, "Well are you going to open it or not?"); + stage = 407; + break; + case 407: + interpreter.sendDialogues(npc, null, "Oh yes, yes, of course!", "'Dearest Romeo, I am very pleased that you sent", player.getUsername() + " to look for me and to tell me that you still", "hold affliction...', Affliction! She thinks I'm diseased?"); + stage = 408; + break; + case 408: + interpreter.sendDialogues(player, null, "'Affection?'"); + stage = 409; + break; + case 409: + interpreter.sendDialogues(npc, null, "Ahh yes...'still hold affection for me. I still feel great", "affection for you, but unfortunately my Father opposes", "our marriage.'"); + stage = 410; + break; + case 410: + interpreter.sendDialogues(player, null, "Oh dear...that doesn't sound too good."); + stage = 411; + break; + case 411: + interpreter.sendDialogues(npc, null, "What? '...great affection for you. Father opposes our.."); + stage = 412; + break; + case 412: + interpreter.sendDialogues(npc, null, "'...marriage and will..."); + stage = 413; + break; + case 413: + interpreter.sendDialogues(npc, null, "...will kill you if he sees you again!'"); + stage = 414; + break; + case 414: + interpreter.sendDialogues(player, null, "I have to be honest, it's not getting any better..."); + stage = 415; + break; + case 415: + interpreter.sendDialogues(npc, null, "'Our only hope is that Father Lawrence, our long time", "confidant, can help us in some way.'"); + stage = 416; + break; + case 416: + interpreter.sendItemMessage(755, "Romeo folds the message away."); + stage = 417; + break; + case 417: + interpreter.sendDialogues(npc, null, "Well, that's it then...we haven't got a chance."); + stage = 418; + break; + case 418: + interpreter.sendDialogues(player, null, "What about Father Lawrence?"); + stage = 419; + break; + case 419: + interpreter.sendDialogues(npc, null, "...our love is over...the great romance, the life of my", "love..."); + stage = 420; + break; + case 420: + interpreter.sendDialogues(player, null, "...or you could speak to Father Lawrence!"); + stage = 421; + break; + case 421: + interpreter.sendDialogues(npc, null, "Oh, my aching, breaking, heart...how useless the situation", "is now...we have no one to turn to..."); + stage = 422; + break; + case 422: + quest.setStage(player, 30); + player.getQuestRepository().syncronizeTab(player); + player.getInventory().remove(new Item(755)); + interpreter.sendDialogues(player, null, "FATHER LAWRENCE!"); + stage = 423; + break; + case 423: + interpreter.sendDialogues(npc, null, "Father Lawrence?"); + stage = 424; + break; + case 424: + interpreter.sendDialogues(npc, null, "Oh yes, Father Lawrence...he's our long time confidant,", "he might have a solution! yes, yes, you have to go and", "talk to Lather Fawrence for us and ask him if he's got", "any suggestions for our predicament?"); + stage = 425; + break; + case 425: + interpreter.sendDialogues(player, null, "Where can I find Father Lawrence?"); + stage = 426; + break; + case 426: + interpreter.sendDialogues(npc, null, "Lather Fawrence! Oh he's..."); + stage = 427; + break; + case 427: + interpreter.sendDialogues(npc, null, "You know he's not my 'real' Father don't you?"); + stage = 428; + break; + case 428: + interpreter.sendDialogues(player, null, "I think I suspected that he wasn't."); + stage = 429; + break; + case 429: + interpreter.sendDialogues(npc, null, "Well anyway...he tells these song, loring bermons...and", "keep these here Carrockian vitizens snoring in his", "church to the East North."); + stage = 430; + break; + case 430: + interpreter.sendOptions("Select an Option", "How are you?", "Where can I find Father Lawrence?", "Have you heard anything from Juliet?", "Ok, thanks."); + stage = 431; + break; + case 431: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, null, "How are you?"); + stage = 500; + break; + case 2: + interpreter.sendDialogues(player, null, "Where can I find Father Lawrence?"); + stage = 530; + break; + case 3: + interpreter.sendDialogues(player, null, "Have you heard anything from Juliet?"); + stage = 560; + break; + case 4: + interpreter.sendDialogues(player, null, "Ok, thanks."); + stage = 580; + break; + } + break; + case 580: + end(); + break; + case 560: + interpreter.sendDialogues(npc, null, "Sadly not my friend! And what's worse, her Father has", "threatend to kill me if he sees me. I mean, that seems", "a bit harsh!"); + stage = 561; + break; + case 561: + interpreter.sendDialogues(player, null, "Well, I shouldn't worry too much...you can always run", "away if you see him..."); + stage = 562; + break; + case 562: + interpreter.sendDialogues(npc, null, "I just wish I could remember what he looks like! I live", "in fear of every man I see!"); + stage = 563; + break; + case 563: + interpreter.sendOptions("Select an Option", "How are you?", "Where can I find Father Lawrence?", "Have you heard anything from Juliet?", "Ok, thanks."); + stage = 431; + break; + case 530: + interpreter.sendDialogues(npc, null, "Lather Fawrence! Oh he's..."); + stage = 531; + break; + case 531: + interpreter.sendDialogues(npc, null, "You know he's not my 'real' Father don't you?"); + stage = 532; + break; + case 532: + interpreter.sendDialogues(player, null, "I think I suspected that he wasn't."); + stage = 533; + break; + case 533: + interpreter.sendDialogues(npc, null, "Well anyway...he tells these song, loring bermons...and", "keep these here Carrockian vitizens snoring in his", "church to the East North."); + stage = 534; + break; + case 534: + interpreter.sendOptions("Select an Option", "How are you?", "Where can I find Father Lawrence?", "Have you heard anything from Juliet?", "Ok, thanks."); + stage = 431; + break; + case 500: + interpreter.sendDialogues(npc, null, "Not so good my friend...I miss Judi..., Junie..., Jooopie..."); + stage = 501; + break; + case 501: + interpreter.sendDialogues(player, null, "Juliet?"); + stage = 502; + break; + case 502: + interpreter.sendDialogues(npc, null, "Juliet! I miss Juliet, terribly?"); + stage = 503; + break; + case 503: + interpreter.sendDialogues(player, null, "Hmmm, so I see!"); + stage = 504; + break; + case 504: + interpreter.sendOptions("Select an Option", "How are you?", "Where can I find Father Lawrence?", "Have you heard anything from Juliet?", "Ok, thanks."); + stage = 431; + break; + case 800: + interpreter.sendOptions("Select an Option", "How are you?", "Where can I find Father Lawrence?", "Have you heard anything from Juliet?", "Ok, thanks."); + stage = 431; + break; + case 236: + interpreter.sendDialogues(player, null, "Did not!"); + stage = 237; + break; + case 237: + interpreter.sendDialogues(npc, null, "Oh, come on, come on, what did he say?"); + stage = 238; + break; + case 238: + interpreter.sendDialogues(player, null, "He wants me to go to the Apothercary!"); + stage = 239; + break; + case 239: + interpreter.sendDialogues(npc, null, "The Apothecary?"); + stage = 240; + break; + case 240: + interpreter.sendDialogues(npc, null, "Oh...is he the one who mixes up all them magical potion-", "ey things?"); + stage = 241; + break; + case 241: + interpreter.sendDialogues(player, null, "Yeah, I think so...but the word potion-ey doesn't exist."); + stage = 242; + break; + case 242: + interpreter.sendDialogues(npc, null, "Well, you just used it...so I guess it does exist!"); + stage = 243; + break; + case 243: + interpreter.sendDialogues(player, null, "It doesn't matter...do you know where the Apothecary", "is?"); + stage = 244; + break; + case 244: + interpreter.sendDialogues(npc, null, "It is Wouth Sest of here and near a sword shop."); + stage = 245; + break; + case 245: + end(); + break; + case 326: + interpreter.sendDialogues(npc, null, "Oh hello, have you seen Lather Fawrence?"); + stage = 327; + break; + case 327: + interpreter.sendDialogues(player, null, "Yes, he's given me details of a potion which should help", "resolve this siution. The Apothecary is helping me", "prepare it."); + stage = 328; + break; + case 328: + interpreter.sendDialogues(npc, null, "Oooh, it all sounds horribly complicated?"); + stage = 329; + break; + case 329: + interpreter.sendDialogues(npc, null, "All I can say is I'll be glad when Juliet's finally in that", "crypt!"); + stage = 330; + break; + case 330: + interpreter.sendDialogues(player, null, "Spoken like a true lover!"); + stage = 331; + break; + case 331: + end(); + break; + case 350: + interpreter.sendDialogues(npc, null, "Ooohh, that's the potion is it?", "Rather you than me!"); + stage = 351; + break; + case 351: + interpreter.sendDialogues(player, null, "I'm not drinking it! It's for Juliet!"); + stage = 352; + break; + case 352: + end(); + break; + case 71: + interpreter.sendDialogues(npc, null, "Ah right, the potion! Great..."); + stage = 72; + break; + case 72: + interpreter.sendDialogues(npc, null, "What potion would that be then?"); + stage = 73; + break; + case 73: + interpreter.sendDialogues(player, null, "The Cadava potion...you know, the one which will make", "her appear dead! She's in the crypt, pop along and claim", "your true love."); + stage = 74; + break; + case 74: + interpreter.sendDialogues(npc, null, "But I'm scared...will you come with me?"); + stage = 75; + break; + case 75: + interpreter.sendDialogues(player, null, "Oh, ok...come on! I think I saw the entrance when I", "visited there last..."); + stage = 76; + break; + case 76: + end(); + ActivityManager.start(player, "Romeo & Juliet Cutscene", false); + player.lock(); + break; + case 456: + interpreter.sendDialogues(npc, null, "Her cousin and I are getting on well though. Thanks", "for your help."); + stage = 457; + break; + case 457: + end(); + break; + case 740: + interpreter.sendDialogues(player, null, "Oh, be quiet..."); + stage = 741; + break; + case 741: + interpreter.sendDialogues(player, null, "We're here. Look, Juliet is over there!"); + stage = 742; + break; + case 742: + close(); + Location ll = cutscene.getBase().transform(21, 36, 0); + int x = ll.getX(); + int y = ll.getY(); + CameraContext rot = null; + CameraContext pos = null; + int height = 450; + int speed = 55; + int other = 1; + pos = new CameraContext(player, CameraType.POSITION, x + 3, y + 4, height, other, speed); + rot = new CameraContext(player, CameraType.ROTATION, x - 1, y - 2, height, other, speed); + PacketRepository.send(CameraViewPacket.class, pos); + PacketRepository.send(CameraViewPacket.class, rot); + GameWorld.getPulser().submit(new Pulse(5) { + @Override + public boolean pulse() { + int x = player.getLocation().getX(); + int y = player.getLocation().getY(); + CameraContext rot = null; + CameraContext pos = null; + int height = 450; + int speed = 100; + int other = 1; + pos = new CameraContext(player, CameraType.POSITION, x - 5, y - 4, height, other, speed); + rot = new CameraContext(player, CameraType.ROTATION, x + 2, y, height, other, speed); + PacketRepository.send(CameraViewPacket.class, pos); + PacketRepository.send(CameraViewPacket.class, rot); + interpreter.sendDialogues(player, null, "You go over to her...and I'll go and wait over here..."); + stage = 743; + return true; + } + }); + break; + case 743: + interpreter.sendDialogues(npc, null, "Ohhh, ok then..."); + stage = 744; + break; + case 744: + Location l = cutscene.base.transform(18, 32, 0); + x = l.getX(); + y = l.getY(); + height = 330; + speed = 100; + other = 1; + pos = new CameraContext(player, CameraType.POSITION, x, y - 1, height, other, speed); + rot = new CameraContext(player, CameraType.ROTATION, x + 20, y + 50, height, other, speed); + PacketRepository.send(CameraViewPacket.class, pos); + PacketRepository.send(CameraViewPacket.class, rot); + close(); + npc.getWalkingQueue().reset(); + npc.getWalkingQueue().addPath(cutscene.getBase().transform(19, 35, 0).getX(), cutscene.getBase().transform(19, 35, 0).getY()); + GameWorld.getPulser().submit(new Pulse(12) { + @Override + public boolean pulse() { + interpreter.sendDialogues(npc, null, "Hey...Juliet..."); + stage = 745; + phill = NPC.create(3325, cutscene.getBase().transform(30, 37, 0)); + phill.init(); + cutscene.getNPCS().add(phill); + Path path = Pathfinder.find(phill, cutscene.getBase().transform(20, 35, 0)); + path.walk(phill); + return true; + } + }); + break; + case 745: + interpreter.sendDialogues(npc, null, "Juliet....?"); + stage = 746; + break; + case 746: + interpreter.sendDialogues(npc, null, "Oh dear...you seem to be dead."); + stage = 747; + break; + case 747: + interpreter.sendDialogues(phill, null, "Hi Romeo...I'm Phillipa!"); + stage = 748; + break; + case 748: + npc.face(phill); + interpreter.sendDialogues(npc, null, "Wow! You're a fox!"); + stage = 749; + break; + case 749: + interpreter.sendDialogues(phill, null, "It's a shame about Juliet...but perhaps we can meet up", "later?"); + stage = 750; + break; + case 750: + interpreter.sendDialogues(npc, null, "Who's Juliet?"); + stage = 751; + break; + case 751: + end(); + cutscene.stop(true); + quest.finish(player); + break; + } + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new RomeoDialogue(player); + } + + @Override + public boolean open(Object... args) { + Quest quest = player.getQuestRepository().getQuest(Quests.ROMEO_JULIET); + npc = (NPC) args[0]; + if (args.length > 1) { + cutscene = (RJCutscenePlugin) args[1]; + interpreter.sendDialogues(npc, null, "This is pretty scary..."); + stage = 740; + return true; + } + switch (quest.getStage(player)) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Juliet. Juliet, where art thou Juliet?", "Have you seen my Juliet?"); + stage = 0; + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Go and speak with Juliet!"); + stage = 457; + break; + case 20: + if (!player.getInventory().contains(755, 1)) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Romeo...great news...I've been in touch with Juliet!"); + stage = 300; + } else { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Romeo...great news...I've been in touch with Juliet!", "She's written a message for you..."); + stage = 400; + } + break; + case 30: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hey again Romeo!"); + stage = 800; + break; + case 40: + interpreter.sendDialogues(npc, null, "Ooh did you manage to survive one of Lather", "Fawrences sermons? I bet not, you were ages! I bet", "you snoozed on the welcome mat just as soon as you", "heard his voice!"); + stage = 236; + break; + case 50: + interpreter.sendDialogues(player, null, "Hi Romeo!"); + stage = 326; + break; + case 60: + if (!player.getInventory().contains(756, 1)) { + interpreter.sendDialogues(player, null, "Hi Romeo!"); + stage = 326; + } else { + interpreter.sendItemMessage(756, "Romeo spots the Cadava potion."); + stage = 350; + } + break; + case 70: + interpreter.sendDialogues(player, null, "Romeo, it's all set. Juliet has drunk the potion and has", "been taken down into the Crypt...now you just need to", "pop along and collect her."); + stage = 71; + break; + case 100: + interpreter.sendDialogues(npc, null, "I heard Juliet had died. Terrible business."); + stage = 456; + break; + } + return true; + } + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/romeo/RomeoJuliet.java b/Server/src/main/content/region/misthalin/varrock/quest/romeo/RomeoJuliet.java new file mode 100644 index 0000000..2e59453 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/romeo/RomeoJuliet.java @@ -0,0 +1,147 @@ +package content.region.misthalin.varrock.quest.romeo; + +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.game.node.entity.player.link.quest.Quest; +import content.data.Quests; + +/** + * Represents the romeo and juliet quest. + * @author 'Vexia + */ +@Initializable +public class RomeoJuliet extends Quest { + + /** + * Constructs a new {@code RomeoJuliet} {@code Object}. + */ + public RomeoJuliet() { + super(Quests.ROMEO_JULIET, 26, 25, 5, 144, 0, 1, 100); + } + + @Override + public void drawJournal(Player player, int stage) { + super.drawJournal(player, stage); + switch (getStage(player)) { + case 0: + line(player, BLUE + "I can start this quest by speaking to " + RED + "Romeo " + BLUE + "in " + RED + "Varrock", 4 + 7); + line(player, BLUE + "central square by the " + RED + "fountain.", 5+ 7); + break; + case 10: + line(player, "I have agreed to find Juliet for Romeo and tell her how he", 4+ 7); + line(player, "feels. For some reason he can't just do this himself.", 5+ 7); + // https://www.youtube.com/watch?v=ush_RVY4tvw + line(player, BLUE + "I should go and speak to " + RED + "Juliet" + BLUE + ", wherever she is?", 7+ 7); + break; + case 20: + line(player, "I have agreed to find Juliet for Romeo and tell her how he", 4+ 7); + line(player, "feels. For some reason he can't just do this himself.", 5+ 7); + line(player, "I found Juliet on the Western edge of Varrock, and told", 6+ 7); + line(player, "her about Romeo. She gave me a message + 7+ 7); take back", 7+ 7); + line(player, BLUE + "I should take the " + RED + "message " + BLUE + "from" + RED + " Juliet " + BLUE + "to" + RED + " Romeo.", 8+ 7); + break; + case 30: + line(player, "I have agreed to find Juliet for Romeo and tell her how he", 4+ 7); + line(player, "feels. For some reason he can't just do this himself.", 5+ 7); + line(player, "I found Juliet on the Western edge of Varrock, and told", 6+ 7); + line(player, "her about Romeo. She gave me a message to take back", 7+ 7); + line(player, "I delivered the message to Romeo, and he was sad to hear", 8+ 7); + line(player, "that Juliet's father opposed their marriage. However, he", 9+ 7); + line(player, "said that Father Lawrence might be able to overcome this.", 10+ 7); + line(player, BLUE + "I should find" + RED + " Father Lawrence " + BLUE + "and see how we can help.", 11+ 7); + break; + case 40: + line(player, "I have agreed to find Juliet for Romeo and tell her how he", 4+ 7); + line(player, "feels. For some reason he can't just do this himself.", 5+ 7); + line(player, "I found Juliet on the Western edge of Varrock, and told", 6+ 7); + line(player, "her about Romeo. She gave me a message to take back", 7+ 7); + line(player, "I delivered the message to Romeo, and he was sad to hear", 8+ 7); + line(player, "that Juliet's father opposed their marriage. However, he", 9+ 7); + line(player, "said that Father Lawrence might be able to overcome this.", 10+ 7); + line(player, "I found Father Lawrence and he suggested the use of a", 11+ 7); + line(player, "potion to fool Juliet's father that she is dead so that", 12+ 7); + line(player, "Romeo and Juliet can be together in peace.", 13+ 7); + line(player, BLUE + "I need to find the " + RED + "Apothecary" + " " + BLUE + "to make a " + RED + "cadava potion.", 14+ 7); + break; + case 50: + line(player, "I have agreed to find Juliet for Romeo and tell her how he", 4+ 7); + line(player, "feels. For some reason he can't just do this himself.", 5+ 7); + line(player, "I found Juliet on the Western edge of Varrock, and told", 6+ 7); + line(player, "her about Romeo. She gave me a message to take back", 7+ 7); + line(player, "I delivered the message to Romeo, and he was sad to hear", 8+ 7); + line(player, "that Juliet's father opposed their marriage. However, he", 9+ 7); + line(player, "said that Father Lawrence might be able to overcome this.", 10+ 7); + line(player, "I found Father Lawrence and he suggested the use of a", 11+ 7); + line(player, "potion to fool Juliet's father that she is dead so that", 12+ 7); + line(player, "Romeo and Juliet can be together in peace.", 13+ 7); + line(player, "I went to the Apothecary regarding making this cadava", 14+ 7); + line(player, "potion, and he told me to bring him some cadava berries", 15+ 7); + if (!player.getInventory().contains(753, 1)) { + line(player, BLUE + "I will have to find some " + RED + "Cadava berries" + BLUE + " somewhere!", 16+ 7); + } else { + line(player, BLUE + "I should take these " + RED + "cadava berries" + BLUE + " to the " + RED + "Apothecary.", 16+ 7); + } + break; + case 60: + line(player, "I have agreed to find Juliet for Romeo and tell her how he", 4+ 7); + line(player, "feels. For some reason he can't just do this himself.", 5+ 7); + line(player, "I found Juliet on the Western edge of Varrock, and told", 6+ 7); + line(player, "her about Romeo. She gave me a message to take back", 7+ 7); + line(player, "I delivered the message to Romeo, and he was sad to hear", 8+ 7); + line(player, "that Juliet's father opposed their marriage. However, he", 9+ 7); + line(player, "said that Father Lawrence might be able to overcome this.", 10+ 7); + line(player, "I found Father Lawrence and he suggested the use of a", 11+ 7); + line(player, "potion to fool Juliet's father that she is dead so that", 12+ 7); + line(player, "Romeo and Juliet can be together in peace.", 13+ 7); + line(player, "I went to the Apothecary regarding making this cadava", 14+ 7); + line(player, "potion, and he told me to bring him some cadava berries", 15+ 7); + line(player, BLUE + "I should take this " + RED + "cadava potion " + BLUE + "to " + RED + "Juliet.", 16+ 7); + break; + case 70: + line(player, "I have agreed to find Juliet for Romeo and tell her how he", 4+ 7); + line(player, "feels. For some reason he can't just do this himself.", 5+ 7); + line(player, "I found Juliet on the Western edge of Varrock, and told", 6+ 7); + line(player, "her about Romeo. She gave me a message to take back", 7+ 7); + line(player, "I delivered the message to Romeo, and he was sad to hear", 8+ 7); + line(player, "that Juliet's father opposed their marriage. However, he", 9+ 7); + line(player, "said that Father Lawrence might be able to overcome this.", 10+ 7); + line(player, "I found Father Lawrence and he suggested the use of a", 11+ 7); + line(player, "potion to fool Juliet's father that she is dead so that", 12+ 7); + line(player, "Romeo and Juliet can be together in peace.", 13+ 7); + line(player, "I went to the Apothecary regarding making this cadava", 14+ 7); + line(player, "potion, and he told me to bring him some cadava berries", 15+ 7); + line(player, "After the Apothecary made me the potion, I delivered it to", 16+ 7); + line(player, "Juliet. She asked me to tell Romeo the plan.", 17+ 7); + line(player, BLUE + "I have to find " + RED + "Romeo" + BLUE + " and tell him what's happened.", 18+ 7); + break; + case 100: + // https://www.youtube.com/watch?v=m4bZ4GmHxRs + line(player, "Romeo and Juliet can be together in peace.", 4+ 7); + line(player, "I went to the Apothecary regarding making this cadava", 5+ 7); + line(player, "potion, and he told me to bring him some cadava berries.", 6+ 7); + line(player, "After the Apothecary made me the potion, I delivered it to", 7+ 7); + line(player, "Juliet. She asked me to tell Romeo the plan.", 8+ 7); + line(player, "I told Romeo what was going to happen, but I'm not exactly", 9+ 7); + line(player, "sure he understood what was happening. Ah well, I was", 10+ 7); + line(player, "rewarded for all of my help regardless.", 11+ 7); + line(player, "QUEST COMPLETE!", 13+ 7); + break; + } + } + + @Override + public void finish(Player player) { + if(player.getQuestRepository().getQuest(Quests.ROMEO_JULIET).isCompleted(player)){ + return; + } + super.finish(player); + player.getPacketDispatch().sendString("5 Quest Points", 277, 8 + 2); + player.getPacketDispatch().sendItemZoomOnInterface(756, 240, 277, 3 + 2); + player.getQuestRepository().syncronizeTab(player); + } + + @Override + public Quest newInstance(Object object) { + return this; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/romeo/RomeoNPC.java b/Server/src/main/content/region/misthalin/varrock/quest/romeo/RomeoNPC.java new file mode 100644 index 0000000..0034cdd --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/romeo/RomeoNPC.java @@ -0,0 +1,74 @@ +package content.region.misthalin.varrock.quest.romeo; + +import core.game.node.entity.npc.AbstractNPC; +import core.game.world.map.Location; +import core.plugin.Initializable; + +/** + * Represents the abstract romeo npc. + * @author 'Vexia + */ +@Initializable +public class RomeoNPC extends AbstractNPC { + + /** + * The NPC ids of NPCs using this plugin. + */ + private static final int[] ID = { 639 }; + + /** + * Represents the delay of speaking to a random player. + */ + private static int speakDelay; + + /** + * Constructs a new {@code RomeoNPC} {@code Object}. + */ + public RomeoNPC() { + super(0, null, true); + } + + /** + * Constructs a new {@code RomeoNPC} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + private RomeoNPC(int id, Location location) { + super(id, location, true); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new RomeoNPC(id, location); + } + + @Override + public void init() { + setWalks(true); + super.init(); + setWalks(true); + } + + @Override + public void tick() { + super.tick(); + /*if (speakDelay < GameWorld.getTicks()) { + speakDelay = GameWorld.getTicks() + 30; + for (Player p : RegionManager.getLocalPlayers(this, 2)) { + if (!p.getInterfaceManager().isOpened() && RandomFunction.random(0, 8) == 2 && p.getQuestRepository().getQuest(Quests.ROMEO_JULIET).getStage(p) == 0) { + if (p.getDialogueInterpreter().getDialogue() != null || p.getDialogueInterpreter().getDialogueStage() != null) { + continue; + } + p.getDialogueInterpreter().open(this.getId(), this); + return; + } + } + }*/ + } + + @Override + public int[] getIds() { + return ID; + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/romeo/RomeoQuestPlugin.java b/Server/src/main/content/region/misthalin/varrock/quest/romeo/RomeoQuestPlugin.java new file mode 100644 index 0000000..a95cc82 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/romeo/RomeoQuestPlugin.java @@ -0,0 +1,65 @@ +package content.region.misthalin.varrock.quest.romeo; + +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the plguin used to handle cadava berries. + * @author 'Vexia + */ +@Initializable +public class RomeoQuestPlugin extends OptionHandler { + + /** + * Represents the cadava berries. + */ + private final Item CADAVA_BERRIES = new Item(753); + + /** + * Represents the picking berries animation. + */ + private final Animation ANIMATION = new Animation(2282); + + /** + * Represents the counter. + */ + private int counter = 0; + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(23625).getHandlers().put("option:pick-from", this); + SceneryDefinition.forId(23626).getHandlers().put("option:pick-from", this); + SceneryDefinition.forId(23627).getHandlers().put("option:pick-from", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + if (((Scenery) node).getId() == 23627) { + player.getPacketDispatch().sendMessage("There are no berries left on this bush."); + player.getPacketDispatch().sendMessage("More berries will grow soon."); + return true; + } + if (!player.getInventory().add(CADAVA_BERRIES)) { + player.getPacketDispatch().sendMessage("Your inventory is too full to pick the berries from the bush."); + return true; + } + player.animate(ANIMATION); + if (counter == 2) { + SceneryBuilder.replace(((Scenery) node), new Scenery(23627, node.getLocation()), 30); + counter = 0; + return true; + } + counter++; + return true; + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/CertificatePlugin.java b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/CertificatePlugin.java new file mode 100644 index 0000000..98c11bf --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/CertificatePlugin.java @@ -0,0 +1,46 @@ +package content.region.misthalin.varrock.quest.shieldofarrav; + +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the plugin handler used for the certificates related to shield of + * arrav. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class CertificatePlugin extends UseWithHandler { + + /** + * Represents the certificate item. + */ + private static final Item CERTIFICATE = new Item(769); + + /** + * Constructs a new {@code CertificatePlugin} {@code Object}. + */ + public CertificatePlugin() { + super(11173); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(11174, ITEM_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + if (player.getInventory().remove(new Item(event.getUsedItem().getId(), 1), new Item(event.getBaseItem().getId(), 1))) { + player.getInventory().add(CERTIFICATE); + } + return true; + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/CharlieTheTrampDialogue.kt b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/CharlieTheTrampDialogue.kt new file mode 100644 index 0000000..3ba076b --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/CharlieTheTrampDialogue.kt @@ -0,0 +1,114 @@ +package content.region.misthalin.varrock.quest.shieldofarrav + +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import content.data.Quests + +/** + * @author qmqz + */ + +@Initializable +class CharlieTheTrampDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin(player){ + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npc(core.game.dialogue.FacialExpression.FRIENDLY,"Spare some change guv?").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> options("Who are you?", "Sorry, I haven't got any.", "Go get a job!", "Ok. Here you go.", "Is there anything down this alleyway?").also { stage++ } + + 1 -> when (buttonId) { + 1 -> player(core.game.dialogue.FacialExpression.HALF_THINKING, "Who are you?").also { stage = 50 } + 2 -> player(core.game.dialogue.FacialExpression.NEUTRAL, "Sorry, I haven't got any.").also { stage = 100 } + 3 -> player(core.game.dialogue.FacialExpression.ANNOYED, "Go get a job!").also { stage = 150 } + 4 -> player(core.game.dialogue.FacialExpression.ANNOYED, "Ok. Here you go.").also { stage = 200 } + 5 -> player(core.game.dialogue.FacialExpression.ANNOYED, "Is there anything down this alleyway?").also { stage = 250 } + } + + 50 -> npcl(core.game.dialogue.FacialExpression.FRIENDLY, "Charles. Charles E. Trampin' at your service. Now, about that change you were going to give me...").also { stage = 0 } + 100 -> npc(core.game.dialogue.FacialExpression.SAD, "Thanks anyways!").also { stage = 99 } + 150 -> npc(core.game.dialogue.FacialExpression.ANNOYED, "You startin? I hope your nose falls off!").also { stage = 99 } + 200 -> { + if (player.inventory.contains(Items.COINS_995, 1)) { + player.inventory.remove(Item(Items.COINS_995, 1)).also { end() } + } else { + sendDialogue("You need one coin to give away.").also { stage = 99 } + } + } + 201 -> npc(core.game.dialogue.FacialExpression.HAPPY, "Hey, thanks a lot!").also { stage++ } + 202 -> options("No problem.", "Don't I get some sort of quest hint or something now?").also { stage++ } + 203 -> when(buttonId) { + 1 -> player(core.game.dialogue.FacialExpression.FRIENDLY, "No problem.").also { stage = 99 } + 2 -> player(core.game.dialogue.FacialExpression.HALF_THINKING, "So... don't I get some sort of quest hint or something now?").also { stage = 220 } + } + 220 -> npcl(core.game.dialogue.FacialExpression.ANNOYED, "Huh? What do you mean? That wasn't why I asked you for money.").also { stage++ } + 221 -> npcl(core.game.dialogue.FacialExpression.SAD, "I just need to eat...").also { stage = 99 } + 250 -> npcl(core.game.dialogue.FacialExpression.AFRAID,"The ruthless and notorious criminal gang known as the Black Arm Gang have their headquarters down there.").also { stage++ } + 251 -> options("Thank you for the warning!", "Do you think they would let me join?").also { stage++ } + 252 -> when (buttonId) { + 1 -> player(core.game.dialogue.FacialExpression.FRIENDLY,"Thanks for the warning!").also { stage = 270 } + 2 -> player(core.game.dialogue.FacialExpression.ASKING, "Do you think they would let me join?").also { stage = 280 } + } + 270 -> npc(core.game.dialogue.FacialExpression.HAPPY, "Don't worry about it.").also { stage = 99 } + + 280 -> if (!ShieldofArrav.isBlackArm(player) && !ShieldofArrav.isPhoenix(player)) { + npcl(core.game.dialogue.FacialExpression.SUSPICIOUS, "You never know. You'll find a lady down there called Katrine. Speak to her.").also { stage = 282 } + } else if (ShieldofArrav.isBlackArm(player)) { + npcl(core.game.dialogue.FacialExpression.SUSPICIOUS, "I was under the impression you were already a member...").also { stage = 99 } + } else { + npcl(core.game.dialogue.FacialExpression.ANNOYED, "No. You're a collaborator with the Phoenix Gang. There's no way they'll let you join now.").also { stage++ } + } + + 282 -> npc(core.game.dialogue.FacialExpression.AFRAID, "But don't upset her, she's pretty dangerous.").also { stage++ } + 283 -> npcl(core.game.dialogue.FacialExpression.FRIENDLY, "I also heard that Reldo the librarian knows more about them, go talk to him.").also { stage++ } + 284 -> { + if (!player.questRepository.hasStarted(Quests.SHIELD_OF_ARRAV)) { + player.questRepository.getQuest(Quests.SHIELD_OF_ARRAV).start(player) + player.questRepository.getQuest(Quests.SHIELD_OF_ARRAV).setStage(player,50) + } else if (!ShieldofArrav.isBlackArm(player) && !ShieldofArrav.isPhoenix(player)) { + player.questRepository.getQuest(Quests.SHIELD_OF_ARRAV).setStage(player, 50) + } + end() + } + + 291 -> options("How did you know I was in the Phoenix Gang?", "Any ideas how I could get in there then?").also { stage++ } + 292 -> when(buttonId) { + 1 -> player(core.game.dialogue.FacialExpression.SUSPICIOUS, "How did you know I was in the Phoenix Gang?").also { stage = 300 } + 2 -> stage = 290 + } + + 300 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "In my current profession I spend a lot of time on the streets and you hear these sorta things sometimes.").also { stage++ } + 301 -> player(core.game.dialogue.FacialExpression.ASKING, "Any ideas how I could get in there then?").also { stage++ } + 302 -> npc(core.game.dialogue.FacialExpression.THINKING, "Hmmm. I dunno.").also { stage++ } + 303 -> npcl(core.game.dialogue.FacialExpression.THINKING, "Your best bet would probably be to find someone else... Someone who ISN'T a member of the Phoenix Gang, and get them to infiltrate the ranks of the Black Arm Gang for you.").also { stage++ } + 304 -> npc(core.game.dialogue.FacialExpression.THINKING, "If you find someone like that, tell 'em to come to me first.").also { stage++ } + + 305 -> options("Ok. Good plan!", "Like who?").also { stage++ } + 306 -> when (buttonId) { + 1 -> player(core.game.dialogue.FacialExpression.FRIENDLY, "Ok. Good plan!").also { stage = 310 } + 2 -> player(core.game.dialogue.FacialExpression.ASKING, "Like who?").also { stage = 320 } + } + + 310 -> npc(core.game.dialogue.FacialExpression.LAUGH, "I'm not just a pretty face!").also { stage = 99 } + 320 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "There's plenty of other adventurers about besides yourself. I'm sure if you asked one of them nicely they would help you.").also { stage = 99 } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): core.game.dialogue.DialoguePlugin { + return CharlieTheTrampDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.CHARLIE_THE_TRAMP_641) + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/CuratorHaigHalenDialogue.kt b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/CuratorHaigHalenDialogue.kt new file mode 100644 index 0000000..67422ee --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/CuratorHaigHalenDialogue.kt @@ -0,0 +1,85 @@ +package content.region.misthalin.varrock.quest.shieldofarrav + +import content.region.desert.quest.thegolem.CuratorHaigHalenGolemDialogue +import core.api.* +import core.game.dialogue.* +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.diary.DiaryType +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import content.data.Quests + +class CuratorHaigHalenDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + START_DIALOGUE -> npcl(FacialExpression.NEUTRAL, "Welcome to Varrock Museum!").also { + if (player.getQuestRepository().points >= 50 && !player.achievementDiaryManager.hasCompletedTask(DiaryType.VARROCK, 0, 12)) { + player.achievementDiaryManager.finishTask(player, DiaryType.VARROCK, 0, 12) + } + if (getQuestStage(player, Quests.THE_DIG_SITE) == 1 && inInventory(player, Items.UNSTAMPED_LETTER_682) ) { + stage = 11 // Couldn't do a dialogueFile for digsite as it needs to resume the topic after. + } + stage++ + } + 1 -> showTopics( + Topic(FacialExpression.FRIENDLY, "Have you any interesting news?", 2), + Topic(FacialExpression.FRIENDLY, "Do you know where I could find any treasure?", 8), + IfTopic(FacialExpression.FRIENDLY, "I've lost the letter of recommendation.", 18, + getQuestStage(player, Quests.THE_DIG_SITE) == 2 && !inInventory(player, Items.SEALED_LETTER_683)), + IfTopic("I have the Shield of Arrav", CuratorHaigHalenSOADialogue(), + getQuestStage(player, Quests.SHIELD_OF_ARRAV) == 70, false), + IfTopic("I'm looking for a statuette recovered from the city of Uzer.", CuratorHaigHalenGolemDialogue(), + getQuestStage(player, Quests.THE_GOLEM) == 3, false) + ) + 2 -> npcl(FacialExpression.FRIENDLY, "Yes, we found a rather interesting island to the north of Morytania. We believe that it may be of archaeological significance.").also { stage++ } + 3 -> playerl(FacialExpression.FRIENDLY, "Oh? That sounds interesting.").also { stage++ } + 4 -> npcl(FacialExpression.FRIENDLY, "Indeed. I suspect we'll be looking for qualified archaeologists once we have constructed our canal and barge.").also { stage++ } + 5 -> playerl(FacialExpression.FRIENDLY, "Would I qualify then?").also { stage++ } + // These three dialogues are based on what he would say depending on what stage of the quest/kudos you have. I'm too lazy to implement this part as the kudos system isn't implemented yet and this is all cosmetic. + // "Unfortunately, you haven't passed your Earth Science", "exams so you aren't qualified to help us on the dig. If" "you're interested, visit the Exam Centre on the Dig Site", "to the east and talk to the examiners there." + // "Unfortunately, you haven't earned enough kudos yet to", "help us on the dig. If you're interested in helping us", "out and getting that Kudos, simply help out around the", "Museum. You can find out more at the information" ANOTHER DIALOGUE "booth." PLAYER "Ok, thanks. + // After 150 kudos I think "Yes indeed. You've helped us a great deal around the", "Museum and you have the necessary qualifications from", "the Earth Sciences exams. When the canal is ready,", "we'll let you know." + 6 -> npcl(FacialExpression.FRIENDLY, "You've certainly done a lot to help out Varrock Museum, so we'd be silly not to ask for your expertise.").also { stage++ } + 7 -> playerl(FacialExpression.FRIENDLY, "Thank you. I'll look forward to it!").also { + stage = END_DIALOGUE + } + 8 -> npcl(FacialExpression.FRIENDLY, "Look around you! This museum is full of treasures!").also { stage++ } + 9 -> playerl(FacialExpression.FRIENDLY, "No, I meant treasures for ME.").also { stage++ } + 10 -> npcl(FacialExpression.FRIENDLY, "Any treasures this museum knows about it goes to great lengths to acquire.").also { + stage = END_DIALOGUE + } + 11 -> player(FacialExpression.FRIENDLY, "I've been given this letter by an examiner at the Dig", "Site. Can you stamp this for me?").also { stage++ } + 12 -> npc(FacialExpression.FRIENDLY, "What have we here? A letter of recommendation", "indeed...").also { stage++ } + // The next two dialogues are supposed to expand based on the player.username length, but I have no time for this shit. + 13 -> npcl(FacialExpression.FRIENDLY, "The letter here says you name is ${player.username}. Well ${player.username}, I wouldn't normally do this for just anyone, but as you did us such a great service with the Shield of Arrav I don't see why not.").also { stage++ } + 14 -> npcl(FacialExpression.FRIENDLY, "Run this letter back to the Examiner to begin your adventure into the world of Earth Sciences. Enjoy your studies, Student!").also { stage++ } + 15 -> npc(FacialExpression.FRIENDLY, "There you go, good luck student... Be sure to come", "back and show me your certificates. I would like to see", "how you get on.").also { + if (removeItem(player, Items.UNSTAMPED_LETTER_682)) { + addItemOrDrop(player, Items.SEALED_LETTER_683) + } + stage++ + } + 16 -> playerl(FacialExpression.FRIENDLY, "Ok, I will. Thanks, see you later.").also { + if(getQuestStage(player, Quests.THE_DIG_SITE) == 1) { + setQuestStage(player, Quests.THE_DIG_SITE, 2) + } + stage = 1 + } + 18 -> npc(FacialExpression.FRIENDLY, "Yes, I saw you drop it as you walked off last time. Here it is.").also { + addItemOrDrop(player, Items.SEALED_LETTER_683) + stage = 1 + } + } + return true + } + + override fun newInstance(player: Player): DialoguePlugin { + return CuratorHaigHalenDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.CURATOR_HAIG_HALEN_646) + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/CuratorHaigHalenSOADialogue.java b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/CuratorHaigHalenSOADialogue.java new file mode 100644 index 0000000..a13fb96 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/CuratorHaigHalenSOADialogue.java @@ -0,0 +1,93 @@ +package content.region.misthalin.varrock.quest.shieldofarrav; + +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.dialogue.DialogueFile; + +public final class CuratorHaigHalenSOADialogue extends DialogueFile { + @Override + public void handle(int componentID, int buttonID) { + Player player = getPlayer(); + if (player.getInventory().containsItem(ShieldofArrav.PHOENIX_SHIELD) || player.getInventory().containsItem(ShieldofArrav.BLACKARM_SHIELD)) { + switch (getStage()) { + case 0: + player("I have half the shield of Arrav here. Can I get a", "reward?"); + setStage(1); + break; + case 1: + npc("The Shield of Arrav! Goodness, the Museum has been", "searching for that for years! The late King Roald II", "offered a reward for it years ago!"); + setStage(2); + break; + case 2: + player("Well, I'm here to claim it."); + setStage(3); + break; + case 3: + npc("Let me have a look at it first."); + setStage(4); + break; + case 4: + getInterpreter().sendItemMessage(ShieldofArrav.getShield(player), "The curator peers at the shield."); + setStage(5); + break; + case 5: + npc("This is incredible!"); + setStage(6); + break; + case 6: + npc("That shield has been missing for over twenty-five years!"); + setStage(7); + break; + case 7: + npc("Leave the shield here with me and I'll write you out a", "certificate saying that you have returned the shield, so", "that you can claim your reward from the King."); + setStage(8); + break; + case 8: + player("Can I have two certificates please?"); + setStage(9); + break; + case 9: + npc("Yes, certainly. Please hand over the shield."); + setStage(10); + break; + case 10: + getInterpreter().sendItemMessage(ShieldofArrav.getShield(player), "You hand over the shield half."); + setStage(11); + break; + case 11: + final Item shield = ShieldofArrav.getShield(player); + final Item certificate = shield == ShieldofArrav.BLACKARM_SHIELD ? ShieldofArrav.BLACKARM_CERTIFICATE : ShieldofArrav.PHOENIX_CERTIFICATE; + if (player.getInventory().remove(shield)) { + player.getInventory().add(certificate); + getInterpreter().sendItemMessage(certificate, "The curator writes out two half-certificates."); + setStage(12); + } + break; + } + return; + } + switch (getStage()) { + case 0: + case 12: + npc("Of course you won't actually be able to claim the", "reward with only half the reward certificate..."); + setStage(13); + break; + case 13: + player("What? I went through a lot of trouble to get that shield", "piece and now you tell me it was for nothing? That's", "not very fair!"); + setStage(14); + break; + case 14: + npc("Well, if you were to get me the other half of the shield,", "I could give you the other half of the reward certificate.", "It's rumoured to be in the possession of the infamous", "Blackarm Gang, beyond that I can't help you."); + setStage(15); + break; + case 15: + player("Okay, I'll see what I can do."); + setStage(16); + break; + case 16: + end(); + break; + } + } +} + diff --git a/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/JohnnyBeardNPC.java b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/JohnnyBeardNPC.java new file mode 100644 index 0000000..f5be4a4 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/JohnnyBeardNPC.java @@ -0,0 +1,61 @@ +package content.region.misthalin.varrock.quest.shieldofarrav; + +import core.game.node.entity.Entity; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.GroundItemManager; +import core.game.world.map.Location; +import content.data.Quests; + +/** + * Represents the npc to handle Johnny the beard npc. + * @author 'Vexia + * @version 1.0 + */ +public final class JohnnyBeardNPC extends AbstractNPC { + + /** + * The NPC ids of NPCs using this plugin. + */ + private static final int[] ID = { 645 }; + + /** + * Constructs a new {@code JohnnyBeardNPC} {@code Object}. + */ + public JohnnyBeardNPC() { + super(0, null); + } + + /** + * Constructs a new {@code JohnnyBeardNPC} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + private JohnnyBeardNPC(int id, Location location) { + super(id, location); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new JohnnyBeardNPC(id, location); + } + + @Override + public void finalizeDeath(final Entity killer) { + super.finalizeDeath(killer); + if (killer instanceof Player) { + final Player p = ((Player) killer); + final Quest quest = p.getQuestRepository().getQuest(Quests.SHIELD_OF_ARRAV); + if (quest.getStage(p) == 60 && ShieldofArrav.isPhoenixMission(p) && !p.getInventory().containsItem(ShieldofArrav.INTEL_REPORT) && !p.getBank().containsItem(ShieldofArrav.INTEL_REPORT)) { + GroundItemManager.create(ShieldofArrav.INTEL_REPORT, getLocation(), p); + } + } + } + + @Override + public int[] getIds() { + return ID; + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/JonnytheBeardPlugin.java b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/JonnytheBeardPlugin.java new file mode 100644 index 0000000..41f2382 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/JonnytheBeardPlugin.java @@ -0,0 +1,68 @@ +package content.region.misthalin.varrock.quest.shieldofarrav; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; + +/** + * Represents the plugin used for jonny the beard. + * @author 'Vexia + * @version 1.0 + */ +public final class JonnytheBeardPlugin extends DialoguePlugin { + + /** + * Constructs a new {@code JonnytheBearPlugin} {@code Object}. + */ + public JonnytheBeardPlugin() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code JonnytheBearPlugin} {@code Object}. + * @param player the player. + */ + public JonnytheBeardPlugin(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new JonnytheBeardPlugin(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + if (ShieldofArrav.isPhoenixMission(player)) { + player.getPacketDispatch().sendMessage("Johnny the beard is not interested in talking."); + end(); + return true; + } + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Will you buy me a beer?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No, I don't think I will."); + stage = 1; + break; + case 1: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 645 }; + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/KatrineDialogue.java b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/KatrineDialogue.java new file mode 100644 index 0000000..53f90ed --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/KatrineDialogue.java @@ -0,0 +1,466 @@ +package content.region.misthalin.varrock.quest.shieldofarrav; + +import content.region.asgarnia.burthorpe.quest.heroesquest.KatrineDialogueFile; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import content.data.Quests; + +import static core.api.ContentAPIKt.openDialogue; + +/** + * Represents the katrine NPC dialogue. + * @author 'Vexia + * @version 1.0 + */ +public final class KatrineDialogue extends DialoguePlugin { + + /** + * Represents the corssbow items. + */ + private static final Item CROSSBOWS = new Item(767, 2); + + /** + * Represents the quest instance. + */ + private Quest quest; + + /** + * Constructs a new {@code KatrineDialogue} {@code Object}. + */ + public KatrineDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code KatrineDialogue} {@code Object}. + * @param player the player. + */ + public KatrineDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new KatrineDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + quest = player.getQuestRepository().getQuest(Quests.SHIELD_OF_ARRAV); + switch (quest.getStage(player)) { + case 100: + if (ShieldofArrav.isBlackArm(player)) { + Quest heroesQuest = player.getQuestRepository().getQuest(Quests.HEROES_QUEST); + if (0 < heroesQuest.getStage(player) && heroesQuest.getStage(player) < 100) { + openDialogue(player, new KatrineDialogueFile(), npc); + break; + } + } + // Continues below if not during the Heroes' Quest + case 90: + case 80: + case 70: + if (ShieldofArrav.isPhoenix(player)) { + npc("You've got some guts coming here, Phoenix guy!"); + stage = 200; + } else { + player("Hey."); + stage = 0; + } + break; + case 60: + if (ShieldofArrav.isBlackArmMission(player)) { + npc("Have you got those crossbows for me yet?"); + stage = 200; + } else { + player("What is this place?"); + stage = 0; + } + break; + default: + player("What is this place?"); + stage = 0; + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + if (quest.getStage(player) == 60 && stage >= 200) { + switch (stage) { + case 200: + if (!player.getInventory().containsItem(CROSSBOWS)) { + player("No, I haven't found them yet."); + stage = 201; + } else { + player("Yes, I have."); + stage = 204; + } + break; + case 201: + npc("I need two crossbows stolen from the Phoenix Gang", "weapons stash, which if you head east for a bit, is a", "building on the south side of the road."); + stage = 202; + break; + case 202: + npc("Come back when you got 'em."); + stage = 203; + break; + case 203: + end(); + break; + case 204: + interpreter.sendDialogue("You give the crossbows to Katrine."); + stage = 205; + break; + case 205: + if (!player.getInventory().containsItem(CROSSBOWS)) { + end(); + return true; + } + if (player.getInventory().remove(CROSSBOWS)) { + npc("Ok. You can join our gang now. Feel free to enter", "any of the rooms of the ganghouse."); + stage = 206; + quest.setStage(player, 70); + ShieldofArrav.setBlackArm(player); + } + break; + case 206: + end(); + break; + } + return true; + } + switch (quest.getStage(player)) { + case 80: + case 90: + case 100: + case 70: + switch (stage) { + case 0: + npc("Hey."); + stage = 1; + break; + case 1: + end(); + break; + case 200: + interpreter.sendDialogue("Katrine spits."); + stage = 201; + break; + case 201: + npc("Now get lost!"); + stage = 202; + break; + case 202: + end(); + break; + case 206: + end(); + break; + } + break; + case 60: + case 50: + switch (stage) { + case 0: + npc("It's a private business. Can I help you at all?"); + stage = 1; + break; + case 1: + options("I've heard you're the Black Arm Gang.", "What sort of business?", "I'm looking for fame and riches."); + stage = 2; + break; + case 2: + switch (buttonId) { + case 1: + player("I've heard you're the Black Arm Gang."); + stage = 100; + break; + case 2: + player("What sort of business?"); + stage = 10; + break; + case 3: + player("I'm looking for fame and riches."); + stage = 20; + break; + } + break; + case 100: + npc("Who told you that?"); + stage = 101; + break; + case 101: + options("I'd rather not reveal my sources.", "It was Charlie, the tramp outside.", "Everyone knows - it's no great secret."); + stage = 102; + break; + case 102: + switch (buttonId) { + case 1: + player("I'd rather not reveal my sources."); + stage = 110; + break; + case 2: + player("It was Charlie, the tramp outside."); + stage = 120; + break; + case 3: + player("Everyone knows - it's not great secret."); + stage = 130; + break; + } + break; + case 110: + npc("Yes, I can understand that. So what do you want with", "us?"); + stage = 111; + break; + case 111: + options("I want to become a member of your gang.", "I want some hints for becoming a thief.", "I'm looking for the door out of here."); + stage = 112; + break; + case 112: + switch (buttonId) { + case 1: + player("I want to become a member of your gang."); + stage = 160; + break; + case 2: + player("I want some hints for becoming a thief."); + stage = 113; + break; + case 3: + player("I'm looking for the door out of here."); + stage = 115; + break; + } + break; + case 160: + npc("How unusual."); + stage = 161; + break; + case 161: + npc("Normally we recruit for our gang by watching local", "thugs and thieves in reward. People don't normally waltz", "in here saying 'hello, can I play'."); + stage = 162; + break; + case 162: + npc("How can I be sure you can be trusted?"); + stage = 163; + break; + case 163: + options("Well, you can give me a try can't you?", "Well, people tell me I have an honest face."); + stage = 164; + break; + case 164: + switch (buttonId) { + case 1: + player("Well, you can give me a try can't you?"); + stage = 167; + break; + case 2: + player("Well, people tell me I have an honest face."); + stage = 165; + break; + } + break; + case 165: + npc("... How unusual. Someone honest wanting to join a", "gang of thieves. Excuse me if I remain unconvinced."); + stage = 166; + break; + case 166: + npc("Thinking about it... I may have a solution actually."); + stage = 169; + break; + case 167: + npc("I'm not so sure."); + stage = 166; + break; + case 169: + npc("Our rival gang - the Phoenix Gang - has a weapons", "stash a little east of here."); + stage = 170; + break; + case 170: + npc("We're fresh out of crossbows, so if you could steal a", "couple of crossbows for us it would be very much", "appreciated."); + stage = 171; + break; + case 171: + npc("Then I'll be happy to call you a Black Arm."); + stage = 172; + break; + case 172: + player("Sounds simple enough. Any particular reason you need", "two of them?"); + stage = 173; + break; + case 173: + npc("I have an idea for framing a local merchant who is", "refusing to pay our, very reasonable, 'keep-your-life-", "pleasant' insurance rates. I need two phoenix crossbows;", "one to kill somebody important with and the other to"); + stage = 174; + break; + case 174: + npc("hide in the merchant's house where the local law can", "find it! When they find it, they'll suspect him of", "murdering the target for the Phoenix gang and", "hopefully, arrest the whole gang! Leaving us as the only"); + stage = 175; + break; + case 175: + npc("thieves gang in Varrock! Brilliant, eh?"); + stage = 176; + break; + case 176: + player("Yeah, brilliant. So who are you planning to murder?"); + stage = 177; + break; + case 177: + npc("I haven't decided yet, but it'll need to be somebody", "important. Say, why you being so nosey? You aren't", "with the law are you?"); + stage = 178; + break; + case 178: + player("No, no! Just curious."); + stage = 179; + break; + case 179: + npc("You'd better just keep your mouth shut about this plan,", "or I'll make sure it stays shut for you. Now, are you", "going to get those crossbows or not?"); + stage = 180; + break; + case 180: + options("Ok, no problem.", "Sounds a little tricky. Got anything easier?"); + stage = 181; + break; + case 181: + switch (buttonId) { + case 1: + player("Ok, no problem."); + stage = 184; + break; + case 2: + player("Sounds a little tricky. Got anything easier?"); + stage = 182; + break; + } + break; + case 182: + npc("If you're not up to a little bit of dager I don't think", "you've got anything to offer our gang."); + stage = 183; + break; + case 183: + end(); + break; + case 184: + quest.setStage(player, 60); + ShieldofArrav.setBlackArmMission(player); + npc("Great! You'll find the Phoenix gang's weapon stash just", "next to a temple, due east of here."); + stage = 185; + break; + case 185: + end(); + break; + case 113: + npc("Well, I'm sorry luv, I'm not giving away any of my", "secrets."); + stage = 114; + break; + case 114: + end(); + break; + case 115: + interpreter.sendDialogue("Katrine groans."); + stage = 116; + break; + case 116: + npc("Try... the one you just came in?"); + stage = 117; + break; + case 117: + end(); + break; + case 120: + npc("Is that guy still out there? He's getting to be a", "nuisance. Remind me to send someone to kill him."); + stage = 121; + break; + case 121: + end(); + break; + case 130: + npc("I thought we were safe back here!"); + stage = 131; + break; + case 131: + player("Oh no, not at all... It's so obvious! Even the town", "guard have caught on..."); + stage = 132; + break; + case 132: + npc("Wow! We MUSE be obvious! I guess they'll be", "expecting bribes again soon in that case."); + stage = 133; + break; + case 133: + npc("Thanks for the information."); + stage = 134; + break; + case 134: + end(); + break; + case 10: + npc("A small, family business. We give financial advice to", "other companies."); + stage = 11; + break; + case 11: + end(); + break; + case 20: + npc("And you expect to find it up the back streets of", "Varrock?"); + stage = 21; + break; + case 21: + end(); + break; + } + break; + default: + switch (stage) { + case 0: + npc("It's a private business. Can I help you at all?"); + stage = 1; + break; + case 1: + options("What sort of business?", "I'm looking for fame and riches."); + stage = 2; + break; + case 2: + switch (buttonId) { + case 1: + player("What sort of business?"); + stage = 10; + break; + case 2: + player("I'm looking for fame and riches."); + stage = 20; + break; + } + break; + case 10: + npc("A small, family business. We give financial advice to", "other companies."); + stage = 11; + break; + case 11: + end(); + break; + case 20: + npc("And you expect to find it up the back streets of", "Varrock?"); + stage = 21; + break; + case 21: + end(); + break; + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 642 }; + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/KingRoaldArravDialogue.kt b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/KingRoaldArravDialogue.kt new file mode 100644 index 0000000..26238d7 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/KingRoaldArravDialogue.kt @@ -0,0 +1,60 @@ +package content.region.misthalin.varrock.quest.shieldofarrav + +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import core.game.dialogue.DialogueFile +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import content.data.Quests + + +private val CERTIFICATE = Item(769) + + +class KingRoaldArravDialogue() : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + + if (player!!.inventory.containsItem(ShieldofArrav.PHOENIX_SHIELD) || player!!.inventory.containsItem(ShieldofArrav.BLACKARM_SHIELD)) { + when (stage) { + START_DIALOGUE -> player("Your majesty, I have recovered the Shield of Arrav; I", "would like to claim the reward.").also { stage++ } + 1 -> npc("The Shield of Arrav, eh? Yes, I do recall my father,", "King Roald, put a reward out for that.").also { stage++ } + 2 -> npc("Very well.").also { stage++ } + 3 -> npc("If you get the authenticity of the shield verified by the", "curator at the museum and then return here with", "authentication, I will grant your reward.").also { stage = END_DIALOGUE } + END_DIALOGUE -> end() + } + } + + else if(player!!.getInventory().containsItem(ShieldofArrav.BLACKARM_CERTIFICATE) || player!!.getInventory().containsItem(ShieldofArrav.PHOENIX_CERTIFICATE)){ + when(stage) { + START_DIALOGUE -> player("Your majesty, I have come to claim the reward for the", "return of the Shield of Arrav.").also { stage++ } + 1 -> interpreter!!.sendItemMessage(if (player!!.inventory.containsItem(ShieldofArrav.BLACKARM_CERTIFICATE)) ShieldofArrav.BLACKARM_CERTIFICATE.id else ShieldofArrav.PHOENIX_CERTIFICATE.id, "You show the certificate to the king.").also { stage++ } + 2 -> npc("I'm afraid that's only half the reward certificate. You'll", "have to get the other half and join them together if you", "want to cliam the reward.").also { stage = END_DIALOGUE } + END_DIALOGUE -> end() + } + } + + else if(player!!.inventory.containsItem(CERTIFICATE)){ + when(stage){ + START_DIALOGUE -> player("Your majesty, I have come to claim the reward for the", "return of the Shield of Arrav.").also { stage++ } + 1 -> interpreter!!.sendItemMessage(CERTIFICATE.id, "You show the certificate to the king.").also { stage++ } + 2 -> npc("My goodness! This claim is for the reward offered by", "my father many years ago!").also { stage++ } + 3 -> npc("I never thought I would live to see the day when", "someone came forward to claim this reward!").also { stage++ } + 4 -> npc("I heard that you found half the shield, so I will give", "you half of the bounty. That comes to exactly 600 gp!").also { stage++ } + 5 -> { + interpreter!!.sendItemMessage(CERTIFICATE.id, "You hand over a certificate. The king gives you 600 gp.") + if (player!!.inventory.remove(CERTIFICATE)) { + if (!player!!.inventory.add(Item(995, 600))) { + GroundItemManager.create(Item(995, 600), player) + } + player!!.questRepository.getQuest(Quests.SHIELD_OF_ARRAV).finish(player) + stage = END_DIALOGUE + } + } + } + } + + else { + abandonFile() + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/ReldoDialogue.java b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/ReldoDialogue.java new file mode 100644 index 0000000..91bee28 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/ReldoDialogue.java @@ -0,0 +1,605 @@ +package content.region.misthalin.varrock.quest.shieldofarrav; + +import org.rs09.consts.Items; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.AchievementDiary; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.GroundItemManager; +import content.data.Quests; + +/** + * Represents the dialogue to handle reldo. + * + * @author 'Vexia + * @dtae 27/12/2013 + */ +public class ReldoDialogue extends DialoguePlugin { + + /** + * Represents the knight sword quest instance. + */ + private Quest knightSword; + + /** + * Represents the shield of arrav quest instance. + */ + private Quest shieldArrav; + + /** + * If w'ere chatting about our diary. + */ + private boolean isDiary; + + private final int level = 1; + + /** + * Constructs a new {@code ReldoDialogue} {@code Object}. + */ + public ReldoDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code ReldoDialogue} {@code Object}. + * + * @param player the player. + */ + public ReldoDialogue(Player player) { + super(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + knightSword = player.getQuestRepository().getQuest(Quests.THE_KNIGHTS_SWORD); + shieldArrav = player.getQuestRepository().getQuest(Quests.SHIELD_OF_ARRAV); + if (args.length == 2 && ((String) args[1]).equals("book")) { + player("Aha! 'The Shield of Arrav'! Exactly what I was looking", "for."); + stage = 3; + return true; + } + if(player.getQuestRepository().getQuest(Quests.THE_LOST_TRIBE).getStage(player) == 40 && player.getInventory().contains(Items.BROOCH_5008,1)){ + options("Hello stranger.","I have a question about my Achievement Diary.","Ask about the brooch."); + } else { + options("Hello stranger.", "I have a question about my Achievement Diary."); + } + stage = -1; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + if (isDiary) { + // https://www.youtube.com/watch?v=2q-29WxUl1U + switch (stage) { + case 999: + end(); + break; + case -1: + // when available, "Can I change my Varrock teleport point?" is option 2 + options("What is the Achievement Diary?", "What are the rewards?", "How do I claim the rewards?", "See you later."); + stage++; + break; + case 0: + switch (buttonId) { + case 1: + player("What is the Achievement Diary?"); + stage = 410; + break; + case 2: + player("What are the rewards?"); + stage = 420; + break; + case 3: + player("How do I claim the rewards?"); + stage = 430; + break; + case 4: + player("See you later."); + stage = 999; + break; + } + break; + case 440: + npc("Really? How extraordinary! Well, that certainly is a ", "worthy achievement indeed."); + stage++; + break; + case 441: + player("Thanks. Was there a reward?"); + stage++; + break; + case 442: + npc("A reward? Well, yes, I suppose I can help you there."); + stage = 444; + break; + case 444: + AchievementDiary.flagRewarded(player, DiaryType.VARROCK, level); + sendDialogue("Reldo takes the Varrock armour and attaches some more plate metal", "to it, filling it out to look like a proper suit of armour. He etches", "some words into the armour, which glows slightly before fading."); + stage++; + break; + case 445: + npc("I have enhanced your body armour with a spell so that,", "when using the Edgeville furnace, you'll have the chance", "of smelting an extra bar up to mithril. It will also give", "you the chance of an extra ore when Mining up to"); + stage++; + break; + case 446: + npc("mithril as well."); + stage++; + break; + case 447: + npc("Smithing can take time, so I have placed a small speed", "enhancement on the armour. When you smith with this armour on, there is a chance that you will be able to", "smith faster each time and thus decrease the time it"); + stage++; + break; + case 448: + npc("takes to produce forged items."); + stage++; + break; + case 449: + npc("I can also change your Varrock Teleport spell so that it", "takes you to the Grand Exchange, if you'd find that more convenient."); + stage++; + break; + case 450: + npc("As an extra reward I have also given you a magical lamp to help with your skills."); + stage++; + break; + case 451: + player("Wow, thanks! What if I lose the armour?"); + stage++; + break; + case 452: + npc("Oh, that's not a problem. You can come back to see me", "and I'll get you another set."); + stage = -1; + break; + + case 460: + AchievementDiary.grantReplacement(player, DiaryType.VARROCK, level); + npc("You better be more careful this time."); + stage = 999; + break; + + case 410: + npc("It's a diary that helps you keep track of particular", "achievements. Here in Varrock it can help you", "discover some quite useful things. Eventually, with", "enough exploration, the people of Varrock will reward"); + stage++; + break; + case 411: + npc("you."); + stage++; + break; + case 412: + npc("You can see what tasks you have listed by clicking on", "the green button in the Quest List."); + stage = 999; + break; + case 420: + npc("Well, there's three different levels of Varrock Armour,", "which match up with the three levels of difficulty. Each", "has the same rewards as the previous level, and an", "additional one too... but I won't spoil your surprise."); + stage++; + break; + case 421: + npc("Rest assured, the people of Varrock are happy to see", "you visiting the land."); + stage = 999; + break; + case 430: + npc("Just complete the tasks so they're all ticked off, then", "you can claim your reward. Most of them are", "straightforward; you might find some require quests to", "be started, if not finished."); + stage++; + break; + case 431: + npc("To claim the different Varrock Armour, speak to Vannaka", "Rat Burgis, and myself."); + stage = 999; + break; + } + return true; + } + if (stage == -1) { + switch (buttonId) { + case 1: + npc("Hello stranger."); + stage = 0; + break; + case 2: + player("I have a question about my Achievement Diary."); + stage = 900; + break; + case 3: + player("What can you tell me about this brooch?"); + stage = 2000; + break; + } + return true; + } + if (stage == 900) { + sendDiaryDialogue(); + return true; + } + //Lost Tribe + if(stage >= 2000){ + switch(stage){ + case 2000: + npc("I've never seen that symbol before. Where did you find","it?"); + stage++; + break; + case 2001: + player("In a cave beneath Lumbridge."); + stage++; + break; + case 2002: + npc("Very odd. Have you any idea how it got there?"); + stage++; + break; + case 2003: + player("A goblin might have dropped it."); + stage++; + break; + case 2004: + npc("I've never heard of a goblin carrying a brooch like this.","But just a minute..."); + stage++; + break; + case 2005: + npc("The other day I filed a book about ancient goblin tribes.","It's somewhere on the west end of the library, I think.","Maybe that will be of some use."); + player.getQuestRepository().getQuest(Quests.THE_LOST_TRIBE).setStage(player,42); + stage++; + break; + case 2006: + end(); + break; + + } + return true; + } + if (knightSword.getStage(player) == 10) { + switch (stage) { + default: + handleKnightSword(buttonId); + handleQuest(buttonId); + break; + } + return true; + } + switch (shieldArrav.getStage(player)) { + case 20: + switch (stage) { + case 0: + player("Ok. I've read the book. Do you know where I can find", "the Phoenix Gang?"); + stage = 1; + break; + case 1: + npc("No, I don't. I think I know someone who might", "however."); + stage = 2; + break; + case 2: + npc("If I were you I would talk to Baraeck, the fur trader in", "the market place. I've heard he has connections with the", "Phoenix Gang."); + stage = 3; + break; + case 3: + player("Thanks, I'll try that!"); + stage = 4; + break; + case 4: + shieldArrav.setStage(player, 30); + end(); + break; + } + break; + case 10: + switch (stage) { + case 0: + player("About that book... where is it again?"); + stage = 1; + break; + case 1: + npc("I'm not sure where it is exactly... but I'm sure it's", "around here somewhere."); + stage = 2; + break; + case 2: + end(); + break; + case 14: + end(); + break; + case 3: + interpreter.sendDialogue("You take the book from the bookcase."); + stage = 4; + break; + case 4: + if (!player.getInventory().add(ShieldofArrav.BOOK)) { + GroundItemManager.create(ShieldofArrav.BOOK, player); + } + end(); + break; + } + break; + case 0: + switch (stage) { + case 0: + options("I'm in search of a quest.", "Do you have anything to trade?", "What do you do?"); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + player("I'm in search of a quest."); + stage = 10; + break; + case 2: + player("Do you have anything to trade?"); + stage = 20; + break; + case 3: + player("What do you do?"); + stage = 30; + break; + } + break; + case 30: + npc("I am the palace librarian."); + stage = 31; + break; + case 31: + player("Ah. That's why you're in the library then."); + stage = 32; + break; + case 32: + npc("Yes."); + stage = 33; + break; + case 33: + end(); + break; + case 20: + npc("Only knowledge."); + stage = 21; + break; + case 21: + player("How much do you want for that then?"); + stage = 22; + break; + case 22: + npc("No, sorry, that was just my little joke. I'm not the", "trading type."); + stage = 23; + break; + case 23: + player("Ah well."); + stage = 24; + break; + case 24: + end(); + break; + default: + handleQuest(buttonId); + break; + } + break; + default: + switch (stage) { + case 0: + options("Do you have anything to trade?", "What do you do?"); + stage = 1; + break; + default: + regular(buttonId); + break; + } + break; + } + return true; + } + + /** + * Method used to handle the quest. + */ + public final void handleQuest(int buttonId) { + switch (stage) { + case 10: + npc("Hmmm. I don't... believe there are any here..."); + stage = 11; + break; + case 11: + npc("Let me think actually..."); + stage = 12; + break; + case 12: + npc("Ah yes. I know. If you look in a book called 'The Shield", "of Arrav', you'll find a quest in there."); + stage = 13; + break; + case 13: + shieldArrav.start(player); + npc("I'm not not sure where the book is mind you... but I'm", "sure it's around here somewhere."); + stage = 14; + break; + case 14: + player("Thank you."); + stage = 15; + break; + case 15: + end(); + break; + } + } + + /** + * Method used to handle his regular chat. + * + * @param buttonId the buttonId. + */ + public void regular(int buttonId) { + switch (stage) { + case 1: + switch (buttonId) { + case 1: + player("Do you have anything to trade?"); + stage = 20; + break; + case 2: + player("What do you do?"); + stage = 30; + break; + } + break; + case 30: + npc("I am the palace librarian."); + stage = 31; + break; + case 31: + player("Ah. That's why you're in the library then."); + stage = 32; + break; + case 32: + npc("Yes."); + stage = 33; + break; + case 33: + end(); + break; + case 20: + npc("Only knowledge."); + stage = 21; + break; + case 21: + player("How much do you want for that then?"); + stage = 22; + break; + case 22: + npc("No, sorry, that was just my little joke. I'm not the", "trading type."); + stage = 23; + break; + case 23: + player("Ah well."); + stage = 24; + break; + case 24: + end(); + break; + } + } + + /** + * Handles the knight sword dial. + * + * @param buttonId the button Id. + */ + public void handleKnightSword(int buttonId) { + switch (stage) { + case 0: + options("Do you have anything to trade?", "What do you do?", "What do you know about Imcando dwarves?"); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + player("Do you have anything to trade?"); + stage = 20; + break; + case 2: + player("What do you do?"); + stage = 30; + break; + case 3: + player("What do you know about Imcando dwarves?"); + stage = 40; + break; + } + break; + case 30: + npc("I am the palace librarian."); + stage = 31; + break; + case 31: + player("Ah. That's why you're in the library then."); + stage = 32; + break; + case 32: + npc("Yes."); + stage = 33; + break; + case 33: + end(); + break; + case 20: + npc("Only knowledge."); + stage = 21; + break; + case 21: + player("How much do you want for that then?"); + stage = 22; + break; + case 22: + npc("No, sorry, that was just my little joke. I'm not the", "trading type."); + stage = 23; + break; + case 23: + player("Ah well."); + stage = 24; + break; + case 24: + end(); + break; + case 40: + npc("The Imcando dwarves, you say?"); + stage = 41; + break; + case 41: + npc("Ah yes... for many hundreds of years they were the", "world's most skilled smiths. They used secret smithing", "knowledge passed down from generation to generation."); + stage = 42; + break; + case 42: + npc("Unfortunately, about a century ago, the once thriving", "race was wiped out during the barbarian invasions of", "that time."); + stage = 43; + break; + case 43: + player("So are there any Imcando left at all?"); + stage = 44; + break; + case 44: + npc("I believe a few of them survived, but with the bulk of", "their population destroyed their numbers have dwindled", "even further."); + stage = 45; + break; + case 45: + npc("I believe I remember a couple living in Asgarnia near", "the cliffs on the Asgarnian southern peninusla, but they", "DO tend to keep to themselves."); + stage = 46; + break; + case 46: + npc("They tend not to tell people that they're the", "descendants of the Imcando, which is why people think", "that the tribe has died out totally, but you may well", "have more luck talking to them if you bring them some"); + stage = 47; + break; + case 47: + npc("redberry pie. They REALLY like redberry pie."); + stage = 48; + break; + case 48: + knightSword.setStage(player, 20); + end(); + break; + } + } + + /** + * Sends the diary dialogue. + */ + private void sendDiaryDialogue() { + isDiary = true; + if (AchievementDiary.canClaimLevelRewards(player, DiaryType.VARROCK, level)) { + player("I've finished all the medium tasks in my Varrock", "Achievement Diary."); + stage = 440; + return; + } + if (AchievementDiary.canReplaceReward(player, DiaryType.VARROCK, level)) { + player("I've seemed to have lost my armour..."); + stage = 460; + return; + } + options("What is the Achievement Diary?", "What are the rewards?", "How do I claim the rewards?", "See you later."); + stage = 0; + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new ReldoDialogue(player); + } + + @Override + public int[] getIds() { + return new int[]{2660, 2661}; + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/ShieldArravPlugin.java b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/ShieldArravPlugin.java new file mode 100644 index 0000000..80a581a --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/ShieldArravPlugin.java @@ -0,0 +1,231 @@ +package content.region.misthalin.varrock.quest.shieldofarrav; + +import core.cache.def.impl.ItemDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.game.component.Component; +import core.game.global.action.ClimbActionHandler; +import core.game.global.action.DoorActionHandler; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.GroundItem; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; +import core.game.global.action.PickupHandler; +import core.game.world.repository.Repository; + +import java.util.List; +import content.data.Quests; + +/** + * Represents the shield of arrav plugin. + * @author 'Vexia + * @version 1.0 + */ +public final class ShieldArravPlugin extends OptionHandler { + + /** + * Represents the message component for intel report. + */ + private static final Component MESSAGE_COMPONENT = new Component(222); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(2402).getHandlers().put("option:search", this); + SceneryDefinition.forId(2397).getHandlers().put("option:open", this); + SceneryDefinition.forId(2399).getHandlers().put("option:open", this); + SceneryDefinition.forId(2398).getHandlers().put("option:open", this); + ItemDefinition.forId(761).getHandlers().put("option:read", this); + SceneryDefinition.forId(2403).getHandlers().put("option:open", this); + SceneryDefinition.forId(2404).getHandlers().put("option:close", this); + SceneryDefinition.forId(2404).getHandlers().put("option:search", this); + ItemDefinition.forId(767).getHandlers().put("option:take", this); + SceneryDefinition.forId(24356).getHandlers().put("option:climb-up", this); + SceneryDefinition.forId(2400).getHandlers().put("option:open", this); + SceneryDefinition.forId(2401).getHandlers().put("option:search", this); + SceneryDefinition.forId(2401).getHandlers().put("option:shut", this); + ItemDefinition.forId(ShieldofArrav.PHOENIX_CERTIFICATE.getId()).getHandlers().put("option:read", this); + ItemDefinition.forId(ShieldofArrav.BLACKARM_CERTIFICATE.getId()).getHandlers().put("option:read", this); + ItemDefinition.forId(769).getHandlers().put("option:read", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + final Quest quest = player.getQuestRepository().getQuest(Quests.SHIELD_OF_ARRAV); + final int id = node instanceof Scenery ? ((Scenery) node).getId() : node instanceof Item ? ((Item) node).getId() : ((NPC) node).getId(); + switch (id) { + case 769: + player.getInterfaceManager().open(new Component(526)); + player.getPacketDispatch().sendString("The bearer of this certificate has brought both halves of the legendary Shield of Arrav to me, Halg Halen, Curator of the Varrock Museum. I have examined the shield and am satisfied as to its authenticity. I recommend to His Majesty, King Roald III, that the bearer is rewarded as per Proclamation 262 of the year 143 of the 5th Age, by King Roald II.", 526, 2); + break; + case 11173: + player.getInterfaceManager().open(new Component(525)); + player.getPacketDispatch().sendString("The bearer of this certificate has brought both halves of the legendary Shield of Arrav to me, Halg Halen, Curator of the Varrock Museum. I have examined the shield and am satisfied as to its authenticity. I recommend to His Majesty, King Roald III, that the bearer is rewarded as per Proclamation 262 of the year 143 of the 5th Age, by King Roald II.", 525, 2); + break; + case 11174: + player.getInterfaceManager().open(new Component(529)); + player.getPacketDispatch().sendString("The bearer of this certificate has brought both halves of the legendary Shield of Arrav to me, Halg Halen, Curator of the Varrock Museum. I have examined the shield and am satisfied as to its authenticity. I recommend to His Majesty, King Roald III, that the bearer is rewarded as per Proclamation 262 of the year 143 of the 5th Age, by King Roald II.", 529, 2); + break; + case 2400: + SceneryBuilder.replace(((Scenery) node), ((Scenery) node).transform(2401)); + break; + case 2401: + switch (option) { + case "search": + if (quest.getStage(player) == 70 && ShieldofArrav.isBlackArm(player)) { + if (!player.getInventory().containsItem(ShieldofArrav.BLACKARM_SHIELD) && !player.getBank().containsItem(ShieldofArrav.BLACKARM_SHIELD)) { + if (!player.getInventory().add(ShieldofArrav.BLACKARM_SHIELD)) { + GroundItemManager.create(ShieldofArrav.BLACKARM_SHIELD, player); + } + player.getDialogueInterpreter().sendItemMessage(ShieldofArrav.BLACKARM_SHIELD.getId(), "You find half of a shield, which you take."); + } else { + player.getDialogueInterpreter().sendDialogue("The cupboard is bare."); + } + } + break; + case "shut": + SceneryBuilder.replace(((Scenery) node), ((Scenery) node).transform(2400)); + break; + } + break; + case 24356: + if (node.getLocation().getX() == 3188) { + ClimbActionHandler.climb(player, new Animation(828), Location.create(3188, 3392, 1)); + } else { + ClimbActionHandler.climbLadder(player, (Scenery) node, option); + return true; + } + break; + case 767: + List npcs = RegionManager.getLocalNpcs(player); + NPC master = null; + for (NPC n : npcs) { + if (n.getId() == 643) { + master = n; + break; + } + } + if (master == null) { + return true; + } + if (!ShieldofArrav.isPhoenix(player) && !master.isInvisible()) { + player.getDialogueInterpreter().open(643, master, true); + } else { + return PickupHandler.take(player, (GroundItem) node); + } + break; + case 2403: + SceneryBuilder.replace(((Scenery) node), ((Scenery) node).transform(2404)); + break; + case 2404: + switch (option) { + case "close": + SceneryBuilder.replace(((Scenery) node), ((Scenery) node).transform(2403)); + break; + case "search": + if (quest.getStage(player) == 70 && ShieldofArrav.isPhoenix(player)) { + if (!player.getInventory().containsItem(ShieldofArrav.PHOENIX_SHIELD) && !player.getBank().containsItem(ShieldofArrav.PHOENIX_SHIELD)) { + if (!player.getInventory().add(ShieldofArrav.PHOENIX_SHIELD)) { + GroundItemManager.create(ShieldofArrav.PHOENIX_SHIELD, player); + } + player.getDialogueInterpreter().sendItemMessage(ShieldofArrav.PHOENIX_SHIELD.getId(), "You find half of a shield, which you take."); + } else { + player.getDialogueInterpreter().sendDialogue("The chest is empty."); + } + } + break; + } + break; + case 761: + player.getPacketDispatch().sendString("Intelligence Report", 222, 1); + player.getPacketDispatch().sendString("There is an archeologist hanging around the", 222, 1); + player.getPacketDispatch().sendString("statue outside of the city, with mining equipment", 222, 2); + player.getPacketDispatch().sendString("Could she be onto a hidden treasure buried near", 222, 3); + player.getPacketDispatch().sendString("the statue?", 222, 4); + player.getPacketDispatch().sendString("There is a new channel being dug and a barge", 222, 5); + player.getPacketDispatch().sendString("being assembled near the digsite. The Varrock", 222, 6); + player.getPacketDispatch().sendString("museum seems to be paying for it. Could they", 222, 7); + player.getPacketDispatch().sendString("have information about new treasures?", 222, 8); + player.getInterfaceManager().open(MESSAGE_COMPONENT); + break; + case 2398: + if (quest.getStage(player) == 60 && ShieldofArrav.isBlackArmMission(player) && !player.getInventory().containsItem(ShieldofArrav.KEY)) { + player.getDialogueInterpreter().sendDialogue("This is the door to the weapon stash you were looking for. Maybe if", "you can find another adventurer who happens to be a member of the", "Phoenix Gang, they could help you."); + return true; + } else if (quest.getStage(player) == 60 && player.getInventory().containsItem(ShieldofArrav.KEY)) { + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + return true; + } + if (quest.getStage(player) == 70 && player.getInventory().containsItem(ShieldofArrav.KEY)) { + if (!player.getInventory().containsItem(ShieldofArrav.KEY) && player.getLocation().getY() > 3385) { + player.getPacketDispatch().sendMessage("You should get a replacement key from Straven to enter here."); + return true; + } else { + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + return true; + } + } + player.getPacketDispatch().sendMessage("The door is securely locked."); + break; + case 2399: + if (!ShieldofArrav.isBlackArm(player)) { + player.getPacketDispatch().sendMessage("This door seems to be locked from the inside."); + } else { + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + } + break; + case 2397: + if (ShieldofArrav.isPhoenix(player)) { + player.getPacketDispatch().sendMessage("The door automatically opens for you."); + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node); + return true; + } + player.getPacketDispatch().sendMessage("The door is securely locked."); + break; + case 2402: + if (quest.getStage(player) != 10) { + player.getPacketDispatch().sendMessage("A large collection of books."); + } else { + if (!player.getInventory().containsItem(ShieldofArrav.BOOK) && !player.getBank().containsItem(ShieldofArrav.BOOK)) { + player.getDialogueInterpreter().open(2660, Repository.findNPC(2660), "book"); + } else { + player.getPacketDispatch().sendMessage("You already own 'The Shield of Arrav', the book that was kept here."); + } + } + break; + } + return true; + } + + @Override + public boolean isWalk() { + return false; + } + + @Override + public boolean isWalk(final Player player, final Node node) { + if (node instanceof GroundItem) { + return true; + } + return !(node instanceof Item); + } + + @Override + public Location getDestination(Node n, Node node) { + if (node instanceof Scenery) { + if (node.getName().toLowerCase().contains("door")) { + return DoorActionHandler.getDestination((Player) n, (Scenery) node); + } + } + return null; + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/ShieldofArrav.java b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/ShieldofArrav.java new file mode 100644 index 0000000..4b42703 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/ShieldofArrav.java @@ -0,0 +1,307 @@ +package content.region.misthalin.varrock.quest.shieldofarrav; + +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import core.plugin.Initializable; +import content.region.misthalin.varrock.dialogue.KingRoaldDialogue; +import core.plugin.ClassScanner; +import content.data.Quests; + +/** + * Represents the shield of arrav quest. + * @author Vexia + * + */ +@Initializable +public class ShieldofArrav extends Quest { + + /** + * Represents the shield of arrav book item. + */ + public static final Item BOOK = new Item(757); + + /** + * Represents the intel report item. + */ + public static final Item INTEL_REPORT = new Item(761); + + /** + * Represents the weapon store item key. + */ + public static final Item KEY = new Item(759); + + /** + * Represents the phoenix shield item. + */ + public static final Item PHOENIX_SHIELD = new Item(763); + + /** + * Represents the black arm shield item. + */ + public static final Item BLACKARM_SHIELD = new Item(765); + + /** + * Represents the blackarm certificate item. + */ + public static final Item BLACKARM_CERTIFICATE = new Item(11174, 2); + + /** + * Represents the phoenix certificate item. + */ + public static final Item PHOENIX_CERTIFICATE = new Item(11173, 2); + + /** + * Constructs a new {@Code ShieldofArrav} {@Code Object} + */ + public ShieldofArrav() { + super(Quests.SHIELD_OF_ARRAV, 29, 28, 1, 145, 0, 1, 7); + } + + @Override + public Quest newInstance(Object object) { + ClassScanner.definePlugins(new CertificatePlugin(), new CuratorHaigHalenDialogue(), new JohnnyBeardNPC(), new JonnytheBeardPlugin(), new KatrineDialogue(), new KingRoaldDialogue(), new ReldoDialogue(), new ShieldArravPlugin(), new StravenDialogue(), new WeaponsMasterDialogue()); + return this; + } + + @Override + public void drawJournal(Player player, int stage) { + super.drawJournal(player, stage); + switch (stage) { + case 0: + player.getPacketDispatch().sendString(BLUE + "I can start this quest by speaking to " + RED + "Reldo " + BLUE + "in " + RED + "Varrock's", 275, 4+ 7); + player.getPacketDispatch().sendString(RED + "Palace Library" + BLUE + ", or by speaking to " + RED + "Charlie the Tramp" + BLUE + " near", 275, 5+ 7); + player.getPacketDispatch().sendString(BLUE + "the " + RED + "Blue Moon Inn " + BLUE + "in " + RED + "Varrock.", 275, 6+ 7); + player.getPacketDispatch().sendString(BLUE + "I will need a friend to help me and some combat experience", 275, 7+ 7); + player.getPacketDispatch().sendString(BLUE + "may be an advantage.", 275, 8+ 7); + break; + case 10: + line(player, RED + "Reldo " + BLUE + "says there is a " + RED + "quest " + BLUE + "hidden in one of the books in", 4+ 7); + line(player, BLUE + "his " + RED + "library" + BLUE + " somewhere. I should look for it and see.", 5+ 7); + break; + case 20: + line(player, "I read about a valuable shield stolen long ago by a gang of", 4+ 7); + line(player, "thieves with an outstanding reward upon it.", 5+ 7); + line(player, BLUE + "I should ask " + RED + "Reldo " + BLUE + "if he knows anything more about this.", 6+ 7); + break; + case 30: + line(player, "I read about a valuable shield stolen long ago by a gang of", 4+ 7); + line(player, "thieves with an outstanding reward upon it.", 5+ 7); + line(player, BLUE + "Reldo told me that the fur trader in " + RED + "Varrock" + BLUE + ", named", 6+ 7); + line(player, RED + "Baraek" + BLUE + ", knows about the " + RED + "Phoenix Gang." + BLUE + " I should speak to", 7+ 7); + line(player, BLUE + "him next.", 8+ 7); + break; + case 40: + line(player, "I read about a valuable shield stolen long ago by a gang of", 4+ 7); + line(player, "thieves with an outstanding reward upon it.", 5+ 7); + line(player, BLUE + "Baraek told me that the " + RED + "'Phoenix Gang' " + BLUE + "have a hideout in", 6+ 7); + line(player, BLUE + "the " + RED + "south-eastern part of Varrock" + BLUE + ", disguising themselves", 7+ 7); + line(player, BLUE + "as the " + RED + "VTAM Corporation" + BLUE + ". I should find them and join.", 8+ 7); + break; + case 50: + line(player, "I read about a valuable shield stolen long ago by a gang of", 4+ 7); + line(player, "thieves with an outstanding reward upon it.", 5+ 7); + line(player, BLUE + "Baraek told me that the " + RED + "'Phoenix Gang' " + BLUE + "have a hideout in", 6+ 7); + line(player, BLUE + "the " + RED + "south-eastern part of Varrock" + BLUE + ", disguising themselves", 7+ 7); + line(player, BLUE + "as the " + RED + "VTAM Corporation" + BLUE + ". I should find them and join.", 8+ 7); + line(player, "I also spoke to Charlie the tramp in Varrock.", 9+ 7); + line(player, BLUE + "According to him there is a criminal organisation known as", 10+ 7); + line(player, BLUE + "the " + RED + "'Black Arm Gang' " + BLUE + "down an alley near to him. I should", 11+ 7); + line(player, BLUE + "speak to their " + RED + "leader, Katrine" + BLUE + ", about joining.", 12+ 7); + break; + case 60: + line(player, "I read about a valuable shield stolen long ago by a gang of", 4+ 7); + line(player, "thieves with an outstanding reward upon it. Baraek told me", 5+ 7); + line(player, "the location of the Phoenix Gang hideout.", 6+ 7); + line(player, "I also spoke to Charlie the tramp in Varrock.", 7+ 7); + line(player, "According to him there is a criminal organisation known as", 8+ 7); + line(player, "the " + RED + "'Black Arm Gang'" + BLUE + "down the alley near to him.", 9+ 7); + if (isPhoenixMission(player) && isBlackArmMission(player)) { + line(player, "I read about a valuable shield stolen long ago by a gang of", 4+ 7); + line(player, "thieves with an outstanding reward upon it. Baraek told me", 5+ 7); + line(player, "the location of the Phoenix Gang hideout.", 6+ 7); + line(player, "To start this quest, I spoke to Charlie the tramp in Varrock.", 7+ 7); + line(player, "He gave me the location of the Black Arm gang HQ.", 8+ 7); + line(player, "According to him there is a criminal organisation known as", 9+ 7); + line(player, "the " + RED + "'Black Arm Gang'" + BLUE + "down the alley near to him.", 10+ 7); + line(player, BLUE + "If I want to join the " + RED + "Phoenix Gang " + BLUE + "I need to kill" + RED + " Jonny The", 11+ 7); + line(player, RED + "Beard " + BLUE + "in the " + RED + "Blue Moon Inn " + BLUE + "and retrieve his " + RED + "report.", 12+ 7); + line(player, RED + "Katrine " + BLUE + "said if I wanted to join the " + RED + "Black Arm Gang," + BLUE + " I'd", 13+ 7); + line(player, BLUE + "have to steal " + RED + "two Phoenix crossbows " + BLUE + "from the rival gang.", 14+ 7); + line(player, BLUE + "Maybe " + RED + "Charlie the tramp " + BLUE + "can give me some ideas about", 15+ 7); + line(player, BLUE + "how to do this.", 16+ 7); + } else if (isPhoenixMission(player)) { + line(player, BLUE + "If I want to join the " + RED + "Phoenix Gang " + BLUE + "I need to kill" + RED + " Jonny The", 10+ 7); + line(player, RED + "Beard " + BLUE + "in the " + RED + "Blue Moon Inn " + BLUE + "and retrieve his " + RED + "report.", 11+ 7); + line(player, BLUE + "Alternatively, if I want to join the " + RED + "Blackarm gang " + BLUE + "I should", 12+ 7); + line(player, BLUE + "speak to their " + RED + "leader, Katrine, " + BLUE + "about joining.", 13+ 7); + } else if (isBlackArmMission(player)) { + line(player, RED + "Katrine " + BLUE + "said if I wanted to join the " + RED + "Black Arm Gang" + BLUE + ", I'd", 10+ 7); + line(player, BLUE + "have to steal " + RED + "two Phoenix crossbows " + BLUE + "from the rival gang.", 11+ 7); + line(player, BLUE + "Maybe " + RED + "Charlie the tramp " + BLUE + "can give me some ideas about", 12+ 7); + line(player, BLUE + "how to do this.", 13+ 7); + } + break; + case 70: + if (isPhoenix(player)) { + line(player, "I read about a valuable shield stolen long ago by a gang of", 4+ 7); + line(player, "thieves with an outstanding reward upon it. Baraek told me", 5+ 7); + line(player, "the location of the Phoenix Gang hideout.", 6+ 7); + line(player, "I killed Jonny the Beard and was welcomed into the Phoenix", 7+ 7); + line(player, "Gang. Straven gave me a key to the weapons room.", 8+ 7); + if (!player.getInventory().containsItem(PHOENIX_SHIELD) && !player.getBank().containsItem(PHOENIX_SHIELD)) { + line(player, BLUE + "I need to search the " + RED + "Phoenix Gang's hideout " + BLUE + "to find half", 10+ 7); + line(player, BLUE + "of the " + RED + "Shield of Arrav.", 11+ 7); + } else { + line(player, BLUE + "I found half of the " + RED + "Shield of Arrav " + BLUE + "in the " + RED + "Phoenix Gang's", 10+ 7); + line(player, RED + "hideout.", 11+ 7); + } + line(player, BLUE + "The second half of the " + RED + "shield" + BLUE + " belongs to a rival gang", 12+ 7); + line(player, BLUE + "known as the " + RED + "Black Arm Gang. " + BLUE + "I will need " + RED + "a friend's help " + BLUE + "to", 13+ 7); + line(player, BLUE + "retreive it before claiming the " + RED + "reward " + BLUE + "for it.", 14+ 7); + } else { + line(player, "I read about a valuable shield stolen long ago by a gang of", 4+ 7); + line(player, "thieves with an outstanding reward upon it. Baraek told me", 5+ 7); + line(player, "the location of the Phoenix Gang hideout.", 6+ 7); + line(player, "With the help of a friend, I managed to obtain two Phoenix", 8+ 7); + line(player, "Crossbows from the Phoenix Gang's weapons store, and", 9+ 7); + line(player, "Katrine welcomes me as a Black Arm Gang member.", 10+ 7); + line(player, BLUE + "With " + RED + "my friend's help" + BLUE + ", I can get both pieces of the shield", 12+ 7); + line(player, BLUE + "and return it to " + RED + "King Roald " + BLUE + "for my " + RED + "reward.", 13+ 7); + } + break; + case 100: + line(player, "I read about a valuable shield stolen long ago by a gang of", 4+ 7); + line(player, "thieves with an outstanding reward upon it. Baraek told me", 5+ 7); + line(player, "the location of the Phoenix Gang hideout.", 6+ 7); + if (!isPhoenix(player)) { + line(player, "With the help of a friend, I managed to obtain two Phoenix", 8+ 7); + line(player, "Crossbows from the Phoenix Gang's weapons store, and", 9+ 7); + line(player, "Katrine welcomes me as a Black Arm Gang member.", 10+ 7); + line(player, "With the help of my friend in the rival gang, I was able to", 12+ 7); + line(player, "retrieve both parts of the fabled Shield of Arrav and", 13+ 7); + line(player, "return it to the Museum of Varrock. In Recognition of my", 14+ 7); + line(player, "efforts, King Roald paid me the reward set by his", 15+ 7); + line(player, "ancestor.", 16+ 7); + line(player, "QUEST COMPLETE!", 18+ 7); + line(player, RED + "I received a reward of 600 coins and got 1 quest point.", 19+ 7); + } else { + line(player, "I killed Jonny the Beard and was welcomed into the Phoenix", 7+ 7); + line(player, "Gang. Straven gave me a key to the weapons room.", 8+ 7); + line(player, "With the help of my friend in the rival gang, I was able to", 10+ 7); + line(player, "retrieve both parts of the fabled Shield of Arrav and", 11+ 7); + line(player, "return it to the Museum of Varrock. In Recognition of my", 12+ 7); + line(player, "efforts, King Roald paid me the reward set by his", 13+ 7); + line(player, "ancestor.", 14+ 7); + line(player, "QUEST COMPLETE!", 16+ 7); + line(player, RED + "I received a reward of 600 coins and got 1 quest point.", 17+ 7); + } + break; + } + } + + @Override + public void finish(Player player) { + super.finish(player); + player.removeAttribute("blackarm-mission"); + player.removeAttribute("phoenix-mission"); + player.getPacketDispatch().sendString("1 Quests Points", 277, 8 + 2); + player.getPacketDispatch().sendString("600 Coins", 277, 9 + 2); + player.getPacketDispatch().sendItemZoomOnInterface(767, 1, 230, 277, 3 + 2); + } + + /** + * Sets the phoenix gang. + * @param player the player. + */ + public static void setPhoenix(final Player player) { + player.setAttribute("/save:phoenix-gang", true); + } + + /** + * Sets the black arm gang. + * @param player the player. + */ + public static void setBlackArm(final Player player) { + player.setAttribute("/save:black-arm-gang", true); + } + + /** + * Swaps the gang. + * @param player the player. + */ + public static void swapGang(final Player player) { + if(isPhoenix(player)) { + player.setAttribute("/save:black-arm-gang", true); + player.setAttribute("/save:phoenix-gang", false); + } else if(isBlackArm(player)) { + player.setAttribute("/save:black-arm-gang", false); + player.setAttribute("/save:phoenix-gang", true); + } else { + player.setAttribute("/save:phoenix-gang", true); + } + } + + /** + * Method used to check if the player is part of the phoenix gang. + * @param player the player. + * @return True if so. + */ + public static boolean isPhoenix(final Player player) { + return player.getAttribute("phoenix-gang", false); + } + + /** + * Method used to check if the player is part of the black arm gang. + * @param player the player. + * @return True if so. + */ + public static boolean isBlackArm(final Player player) { + return player.getAttribute("black-arm-gang", false); + } + + /** + * Method used to set that the player is trying to do the phoennix mission. + * @param player the player. + */ + public static void setPhoenixMission(final Player player) { + player.setAttribute("/save:phoenix-mission", true); + } + + /** + * Method used to set that the player is trying to do the black arm gang + * mission. + * @param player the player. + */ + public static void setBlackArmMission(final Player player) { + player.setAttribute("/save:blackarm-mission", true); + } + + /** + * Method used to check if they're doing the black arm gang mission. + * @param player the player. + * @return True if so. + */ + public static boolean isBlackArmMission(final Player player) { + return player.getAttribute("blackarm-mission", false); + } + + /** + * Method used to check if they're doing the phoenix gang mission. + * @param player the player. + * @return True if so. + */ + public static boolean isPhoenixMission(final Player player) { + return player.getAttribute("phoenix-mission", false); + } + + /** + * Gets the shield item. + * @param player the player. + * @return + */ + public static final Item getShield(final Player player) { + return isBlackArm(player) ? BLACKARM_SHIELD : PHOENIX_SHIELD; + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/ShieldofArravBook.kt b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/ShieldofArravBook.kt new file mode 100644 index 0000000..10ec52e --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/ShieldofArravBook.kt @@ -0,0 +1,105 @@ +package content.region.misthalin.varrock.quest.shieldofarrav + +import content.global.handlers.iface.BookInterface +import content.global.handlers.iface.BookLine +import content.global.handlers.iface.Page +import content.global.handlers.iface.PageSet +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.player.Player +import org.rs09.consts.Items +import content.data.Quests +import core.api.getQuestStage +import core.api.setQuestStage + +/** + * Shield of Arrav Book + * @author ovenbreado + * @author 'Vexia + * @author Empathy + */ +class ShieldofArravBook : InteractionListener { + companion object { + private val TITLE = "The Shield of Arrav" + private val CONTENTS = arrayOf( + PageSet( + Page( + BookLine("The Shield of Arrav", 55), + BookLine("by A.R Wright", 57), + BookLine("Arrav is probably the best", 61), + BookLine("known hero of the 4th", 62), + BookLine("age. Many legends are", 63), + BookLine("told of his heroics. One", 64), + BookLine("surviving artefact from", 65) + ), + Page( + BookLine("the 4th age is a fabulous", 66), + BookLine("shield.", 67), + BookLine("This shield is believed to", 69), + BookLine("have once belonged to", 70), + BookLine("Arrav and is now indeed", 71), + BookLine("known as the Shield of", 72), + BookLine("Arrav. For over 150", 73), + BookLine("years it was the prize", 74), + BookLine("piece in the royal", 75), + BookLine("museum of Varrock.", 76) + ) + ), + PageSet( + Page( + BookLine("However, in the year 143", 55), + BookLine("of the fith age a gang of", 56), + BookLine("thieves called the Phoenix", 57), + BookLine("Gang broke into the", 58), + BookLine("museum and stole the", 59), + BookLine("shield in a daring raid. As", 60), + BookLine("a result, the current", 61), + BookLine("ruler, King Roald, put a", 62), + BookLine("1200 gold bounty (a", 63), + BookLine("massive sum of money in", 64), + BookLine("those days) on the return", 65) + ), + Page( + BookLine("of the shield, hoping that", 66), + BookLine("one of the culprits would", 67), + BookLine("betray his fellows out of", 68), + BookLine("greed.", 69) + ) + ), + PageSet( + Page( + BookLine("This tactic did not work", 55), + BookLine("however, and the thieves", 56), + BookLine("who stole the shield have", 57), + BookLine("since gone on to become", 58), + BookLine("the most powerful crime", 59), + BookLine("gang in Varrock, despite", 60), + BookLine("making an enemy of the", 61), + BookLine("Royal Family many", 62), + BookLine("years ago.", 63) + ), + Page( + BookLine("The reward for the", 66), + BookLine("return of the shield still", 67), + BookLine("stands.", 68) + ) + ) + ) + private fun display(player: Player, pageNum: Int, buttonID: Int) : Boolean { + BookInterface.pageSetup(player, BookInterface.FANCY_BOOK_3_49, TITLE, CONTENTS) + if (BookInterface.isLastPage(pageNum, CONTENTS.size)) { + if (getQuestStage(player, Quests.SHIELD_OF_ARRAV) == 10) { + setQuestStage(player, Quests.SHIELD_OF_ARRAV, 20) + } + } + return true + } + } + + override fun defineListeners() { + on(Items.BOOK_757, IntType.ITEM, "read") { player, _ -> + BookInterface.openBook(player, BookInterface.FANCY_BOOK_3_49, ::display) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/StravenDialogue.java b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/StravenDialogue.java new file mode 100644 index 0000000..f12d9ce --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/StravenDialogue.java @@ -0,0 +1,418 @@ +package content.region.misthalin.varrock.quest.shieldofarrav; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.GroundItemManager; +import content.data.Quests; +import content.region.asgarnia.burthorpe.quest.heroesquest.StravenDialogueFile; + +import static core.api.ContentAPIKt.openDialogue; + +/** + * Represents the dialogue which handles the straven NPC. + * @author 'Vexia + * @date 3/1/14 + */ +public class StravenDialogue extends DialoguePlugin { + + /** + * Represents the quest instance. + */ + private Quest quest; + + /** + * Constructs a new {@code StravenDialogue} {@code Object}. + */ + public StravenDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code StravenDialogue} {@code Object}. + * @param player the player. + */ + public StravenDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new StravenDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + quest = player.getQuestRepository().getQuest(Quests.SHIELD_OF_ARRAV); + switch (quest.getStage(player)) { + case 100: + if (ShieldofArrav.isPhoenix(player)) { + Quest heroesQuest = player.getQuestRepository().getQuest(Quests.HEROES_QUEST); + if (0 < heroesQuest.getStage(player) && heroesQuest.getStage(player) < 100) { + openDialogue(player, new StravenDialogueFile(), npc); + break; + } + } + // Continues below if not during the Heroes' Quest + case 70: + if (ShieldofArrav.isPhoenix(player)) { + npc("Greetings fellow gang member."); + stage = 10; + } else { + player.getPacketDispatch().sendMessage("I wouldn't talk to him if I was you."); + end(); + } + break; + case 60: + if (ShieldofArrav.isPhoenixMission(player)) { + npc("How's your little mission going?"); + stage = 200; + } else { + player("What's through the door?"); + stage = 100; + } + break; + default: + player("What's through the door?"); + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + if (quest.getStage(player) == 60 && stage >= 200) { + switch (stage) { + case 200: + if (!player.getInventory().containsItem(ShieldofArrav.INTEL_REPORT)) { + player("I haven't managed to find the report yet..."); + stage = 201; + } else { + player("I have the intelligence report!"); + stage = 204; + } + break; + case 201: + npc("You need to kill Johnny the Beard, who should be in the", "Blue Moon Inn."); + stage = 202; + break; + case 202: + npc("...I would guess. Not being a member of the Phoenix", "Gang and all."); + stage = 203; + break; + case 203: + end(); + break; + case 204: + npc("Let's see it then."); + stage = 205; + break; + case 205: + interpreter.sendDialogue("You hand over the report. The man reads the report."); + stage = 206; + break; + case 206: + npc("Yes. Yes, this is very good."); + stage = 207; + break; + case 207: + npc("Ok! You can join the Phoenix Gang! I am Straven, one", "of the gang leaders."); + stage = 208; + break; + case 208: + player("Nice to meet you."); + stage = 209; + break; + case 209: + npc("Take this key."); + stage = 210; + break; + case 210: + if (player.getInventory().remove(ShieldofArrav.INTEL_REPORT)) { + if (!player.getInventory().add(ShieldofArrav.KEY)) { + GroundItemManager.create(ShieldofArrav.KEY, player); + } + interpreter.sendItemMessage(ShieldofArrav.KEY.getId(), "Straven hands you a key."); + quest.setStage(player, 70); + ShieldofArrav.setPhoenix(player); + stage = 211; + } + break; + } + return true; + } + switch (quest.getStage(player)) { + case 100: + case 70: + switch (stage) { + case 10: + if (!player.getInventory().containsItem(ShieldofArrav.KEY) && !player.getBank().containsItem(ShieldofArrav.KEY)) { + player("I'm afraid I've lost the key you gave me..."); + stage = 80; + } else { + options("I've heard you've got some cool treasure in this place.", "Any suggestions for where I can go thieving?", "Where's the Black Arm Gang hideout?"); + stage = 11; + } + break; + case 80: + npc("You really need to be more careful. We don't want", "that key falling into the wrong hands. Ah well... Have", "this spare. Don't lose THIS one."); + stage = 81; + break; + case 81: + if (!player.getInventory().add(ShieldofArrav.KEY)) { + GroundItemManager.create(ShieldofArrav.KEY, player); + } + interpreter.sendItemMessage(ShieldofArrav.KEY.getId(), "Straven hands you a key."); + stage = 82; + break; + case 82: + end(); + break; + case 11: + switch (buttonId) { + case 1: + player("I've heard you've got some cool treasures in this place..."); + stage = 110; + break; + case 2: + player("Any suggestions on where I can go thieving?"); + stage = 120; + break; + case 3: + player("Where's the Black Arm Gang hideout? I wanna go", "sabotage 'em!"); + stage = 130; + break; + } + break; + case 130: + npc("That would be a little tricky; their security is pretty", "good."); + stage = 131; + break; + case 131: + end(); + break; + case 120: + npc("You can always try the marketplace in Ardougne.", "LOTS of opportunity there!"); + stage = 121; + break; + case 121: + end(); + break; + case 110: + npc("Oh yeah, we've all stolen some stuff in our time. Those", "candelsticks down here, for example, were quite a", "challenge to get out of the palace."); + stage = 111; + break; + case 111: + player("And the shield of Arrav? I heard you got that!"); + stage = 112; + break; + case 112: + npc("Woah... thats a blast from the past! We stole that years", "and years ago! We don't even have all the shield", "anymore."); + stage = 113; + break; + case 113: + end(); + break; + case 211: + npc("This key will give you access to our weapons supply", "depot round the front of this building."); + stage = 212; + break; + case 212: + end(); + break; + default: + handleDefault(buttonId); + break; + } + break; + case 60: + case 50: + case 40: + switch (stage) { + case 0: + npc("Hey! You can't go in there. Only authories personnel", "of the VTAM Corporation are allowed beyond this point."); + stage = 1; + break; + case 1: + options("I know who you are!", "How do I get a job with the VTAM corporation?", "Why not?"); + stage = 2; + break; + case 2: + switch (buttonId) { + case 1: + player("I know who you are!"); + stage = 10; + break; + case 2: + player("How do I get a job with the VTAM corporation?"); + stage = 20; + break; + case 3: + player("Why not?"); + stage = 30; + break; + } + break; + case 10: + npc("Really?"); + stage = 11; + break; + case 11: + npc("Well?"); + stage = 12; + break; + case 12: + npc("Who are we then?"); + stage = 13; + break; + case 13: + player("This is the headquarters of the Phoenix Gang, the most", "powerful crime syndicate this city has ever seen!"); + stage = 14; + break; + case 14: + npc("No, this is a legitimate business run by legitimate", "businessmen."); + stage = 15; + break; + case 15: + npc("Supposing we were this crime gang however, what would", "you want with us?"); + stage = 16; + break; + case 16: + options("I'd like to offer you my services.", "I want nothing. I was just making sure you were them."); + stage = 17; + break; + case 17: + switch (buttonId) { + case 1: + player("I'd like to offer you my services."); + stage = 41; + break; + case 2: + player("I want nothing. I was just making sure you were them."); + stage = 18; + break; + } + break; + case 18: + npc("Well then get lost and stop wasting my time."); + stage = 19; + break; + case 19: + npc("...if you know what's good for you."); + stage = 40; + break; + case 40: + end(); + break; + case 41: + npc("You mean you'd like to join the Phoenix Gang?"); + stage = 42; + break; + case 42: + npc("well obviously I can't speak for them, but the Phoenix", "Gang doesn't let people join just like that."); + stage = 43; + break; + case 43: + npc("You can't be too careful, you understand."); + stage = 44; + break; + case 44: + npc("Generally someone has to prove their loyalty before", "they can join."); + stage = 45; + break; + case 45: + player("How would I go about doing that?"); + stage = 46; + break; + case 46: + npc("Obviously, I would have no idea about that."); + stage = 47; + break; + case 47: + npc("Although having said that, a rival gang of ours, er,", "theirs, called the Black Arm Gang is supposedly meeting", "a contact from Port Sarim today in the Blue Moon", "Inn."); + stage = 48; + break; + case 48: + npc("The Blue Moon Inn is just by the south entrance to", "this city, and supposedly the name of the contact is", "Jonny the Beard."); + stage = 49; + break; + case 49: + npc("OBVIOUSLY I know NOTHING about the dealing", "of the Phoenix Gang, but I bet if SOMEBODY were", "to kill him and bring back his intelligence report, they", "would be considered loyal enough to join."); + stage = 50; + break; + case 50: + player("Ok, I'll get right on it."); + stage = 51; + break; + case 51: + quest.setStage(player, 60); + ShieldofArrav.setPhoenixMission(player); + end(); + break; + case 20: + npc("Get a copy of the Varrock Herald. If we have any", "positions right now, they'll be advertised in there."); + stage = 21; + break; + case 21: + end(); + break; + case 30: + npc("Sorry. That's classified information."); + stage = 31; + break; + case 31: + end(); + break; + default: + handleDefault(buttonId); + break; + } + break; + default: + switch (stage) { + case 0: + npc("Hey! You can't go in there. Only authories personnel", "of the VTAM Corporation are allowed beyond this point."); + stage = 1; + break; + case 1: + player("Ok, sorry."); + stage = 2; + break; + case 2: + end(); + break; + } + break; + } + return true; + } + + /** + * Method used to handle the default dial. + * @param buttonId the button id. + */ + public void handleDefault(int buttonId) { + switch (stage) { + case 0: + npc("Hey! You can't go in there. Only authories personnel", "of the VTAM Corporation are allowed beyond this point."); + stage = 1; + break; + case 1: + player("Ok, sorry."); + stage = 2; + break; + case 2: + end(); + break; + } + } + + @Override + public int[] getIds() { + return new int[] { 644 }; + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/WeaponsMasterDialogue.java b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/WeaponsMasterDialogue.java new file mode 100644 index 0000000..e0f0f5f --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/shieldofarrav/WeaponsMasterDialogue.java @@ -0,0 +1,123 @@ +package content.region.misthalin.varrock.quest.shieldofarrav; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import content.data.Quests; + +/** + * Represents the dialogue which handles the weapons master. + * @author 'Vexia + * @version 1.0 + */ +public final class WeaponsMasterDialogue extends DialoguePlugin { + + /** + * Represents the quest. + */ + private Quest quest; + + /** + * Constructs a new {@code WeaponsMasterDialogue} {@code Object}. + */ + public WeaponsMasterDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code WeaponsMasterDialogue} {@code Object}. + * @param player the player. + */ + public WeaponsMasterDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new WeaponsMasterDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + quest = player.getQuestRepository().getQuest(Quests.SHIELD_OF_ARRAV); + switch (quest.getStage(player)) { + default: + if (args.length > 1) { + npc("Stop! Thief!"); + stage = 600; + return true; + } + player("Hello."); + stage = 0; + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (quest.getStage(player)) { + default: + switch (stage) { + case 600: + end(); + npc.getProperties().getCombatPulse().attack(player); + break; + case 0: + if (ShieldofArrav.isPhoenix(player)) { + npc("Hello fellow Phoenix! What are you after?"); + stage = 1; + } else { + npc("Hey! Who are you? I'm gonna teach you not to stick", "your nose where it don't belong!"); + stage = 50; + } + break; + case 50: + end(); + npc.getProperties().getCombatPulse().attack(player); + break; + case 1: + options("I'm after a weapon or two.", "I'm looking for treasure."); + stage = 2; + break; + case 2: + switch (buttonId) { + case 1: + player("I'm after a weapon or two."); + stage = 10; + break; + case 2: + player("I'm looking for treasure."); + stage = 20; + break; + } + break; + case 10: + npc("No problem. Feel free to look around."); + stage = 11; + break; + case 11: + end(); + break; + case 20: + npc("Aren't we all? We've not got any up here. Go mug", "someone somewhere if you want some treasure."); + stage = 21; + break; + case 21: + end(); + break; + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 643 }; + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/AnnaJonesDialogue.java b/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/AnnaJonesDialogue.java new file mode 100644 index 0000000..645995c --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/AnnaJonesDialogue.java @@ -0,0 +1,271 @@ +package content.region.misthalin.varrock.quest.whatliesbelow; + +import content.data.Quests; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; + +/** + * Handles the anna jones dialogue. + * @author Vexia + */ +public class AnnaJonesDialogue extends DialoguePlugin { + + /** + * The quest. + */ + private Quest quest; + + /** + * Constructs a new {@Code AnnaJonesDialogue} {@Code Object} + */ + public AnnaJonesDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@Code AnnaJonesDialogue} {@Code Object} + * @param player the player. + */ + public AnnaJonesDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new AnnaJonesDialogue(player); + } + + @Override + public boolean open(Object... args) { + quest = player.getQuestRepository().getQuest(Quests.WHAT_LIES_BELOW); + switch (quest.getStage(player)) { + default: + if (args.length >= 2) { + npc("Excuse me. I am working on that statue at the moment", "Please don't touch it."); + stage = 50; + break; + } + npc("Yes? Can I help you?"); + break; + case 30: + npc("Ah. You must be " + player.getUsername() + ", right? I have a bronze", "pickaxe here for you."); + break; + case 40: + if (args.length >= 2) { + npc("You did it! oh, well done! How exciting!"); + stage = 10; + break; + } + npc("You opened the tunnel; well done!"); + stage++; + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (quest.getStage(player)) { + default: + switch (stage) { + case 0: + options("Who are you?", "What are you doing here?", "Who does this statue represent?", "Okay, I'd better go."); + stage++; + break; + case 1: + switch (buttonId) { + case 1: + player("Who are you?"); + stage = 10; + break; + case 2: + player("What are you doing here?"); + stage = 30; + break; + case 3: + player("Who does this statue represent?"); + stage = 20; + break; + case 4: + player("Okay, I'd better go."); + stage = 40; + break; + } + break; + case 10: + npc("Well, now. Do you always go around asking about people", "like that? It's very rude, you know."); + stage++; + break; + case 11: + player("Sorry! I didn't mean to pry!"); + stage++; + break; + case 12: + npc("That's alright. My name is Louisiana Jones, although", "most people call me Anna. I'm an archaeologist."); + stage++; + break; + case 13: + player("Oh. Do you work for the Varrock Museum?"); + stage++; + break; + case 14: + npc("Hah! No. I used to, but now I prefer to work", "freelance for independent employers."); + stage++; + break; + case 15: + player("I see."); + stage++; + break; + case 16: + end(); + break; + case 20: + npc("That, my dear, is the statue of the great god Saradomin", "himself. Stand and admire in awe, for you are in the", "presence of greatness!"); + stage++; + break; + case 21: + end(); + break; + case 30: + npc("I'm investigating something for someone."); + stage++; + break; + case 31: + player("That doesn't really explain anything!"); + stage++; + break; + case 32: + npc("I never said it would."); + stage++; + break; + case 33: + end(); + break; + case 40: + end(); + break; + case 50: + player("You are? But you're just sitting there."); + stage++; + break; + case 51: + npc("Yes. I'm on a break."); + stage++; + break; + case 52: + player("Oh, I see. When does your break finish?"); + stage++; + break; + case 53: + npc("When I decide to start working again. Right now, I'm", "enjoying sitting on this bench."); + stage++; + break; + case 54: + end(); + break; + } + break; + case 30: + switch (stage) { + case 0: + if (!player.getInventory().contains(1265, 1)) { + player.getInventory().add(new Item(1265), player); + player("Thank you very much!"); + stage++; + } else { + player("Thanks, but I already have one."); + stage = 1; + } + break; + case 1: + npc("My employer, Surok Magis, sent word to me that you", "may come to use the tunnel. You will need something to", "help you get in there. The pickaxe will help."); + stage++; + break; + case 2: + player("Uh, thanks."); + stage++; + break; + case 3: + npc("Okay, then. The tunnel awaits..."); + stage++; + break; + case 4: + options("What tunnel?", "Sorry, who are you?", "Who does this statue represent?", "What are you doing here?", "Okay, I'd better go."); + stage++; + break; + case 5: + switch (buttonId) { + case 1: + player("What tunnel?"); + stage = 10; + break; + case 2: + player("Sorry, who are you?"); + stage = 20; + break; + case 3: + player("Who does this statue represent?"); + stage = 30; + break; + case 4: + player("What are you doing here?"); + stage = 40; + break; + case 5: + player("Okay, I'd better go."); + stage = 50; + break; + } + break; + case 10: + npc("Why, the Chaos Tunnel of course! I imagine Surok will", "have told you of it."); + stage = 41; + break; + case 20: + npc("My name is Louisiana Jones, although most people", "call me Anna. I'm an archaeologist."); + stage = 41; + break; + case 30: + npc("That, my dear, is the statue of the great god Saradomin", "himself. Stand and admire in awe for you are in the", "presence of greatness!"); + stage = 41; + break; + case 40: + npc("Well story and rumour has it that Dagon'hai built a", "tunnel under this statue of Saradomin that would allow", "them to visit the Chaos Altar without having to go", "through the Wilderness."); + stage++; + break; + case 41: + end(); + break; + case 50: + end(); + break; + } + break; + case 40: + switch (stage) { + case 1: + end(); + break; + case 10: + player("Right, well, I better see what's down there, then."); + stage++; + break; + case 11: + end(); + break; + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 5837 }; + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/KingRoaldNPC.java b/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/KingRoaldNPC.java new file mode 100644 index 0000000..437ec83 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/KingRoaldNPC.java @@ -0,0 +1,83 @@ +package content.region.misthalin.varrock.quest.whatliesbelow; + +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.npc.AbstractNPC; +import core.game.world.map.Location; + +/** + * Handles the king roald npc. + * @author Vexia + */ +public class KingRoaldNPC extends AbstractNPC { + + /** + * The cutscene. + */ + private WLBelowCutscene cutscene; + + /** + * Constructs a new {@Code KingRoaldNPC} {@Code Object} + * @param id the id. + * @param location the location. + */ + public KingRoaldNPC(int id, Location location) { + super(id, location); + } + + /** + * Constructs a new {@Code KingRoaldNPC} {@Code Object} + */ + public KingRoaldNPC() { + super(-1, null); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new KingRoaldNPC(id, location); + } + + @Override + public void checkImpact(BattleState state) { + int lp = getSkills().getLifepoints(); + if (state.getEstimatedHit() > -1) { + if (lp - state.getEstimatedHit() < 1) { + state.setEstimatedHit(0); + if (lp > 1) { + state.setEstimatedHit(lp - 1); + } + } + } + if (state.getSecondaryHit() > -1) { + if (lp - state.getSecondaryHit() < 1) { + state.setSecondaryHit(0); + if (lp > 1) { + state.setSecondaryHit(lp - 1); + } + } + } + int totalHit = state.getEstimatedHit() + state.getSecondaryHit(); + if (lp - totalHit < 1) { + state.setEstimatedHit(0); + state.setSecondaryHit(0); + } + if (lp <= 1 && !getAttribute("message", false)) { + setAttribute("message", true); + cutscene.getPlayer().sendMessage("Now would be a good time to summon Zaff!"); + ; + } + } + + /** + * Sets the cutscene. + * @param cutscene the cutscene. + */ + public void setCutscene(WLBelowCutscene cutscene) { + this.cutscene = cutscene; + } + + @Override + public int[] getIds() { + return new int[] { 5838 }; + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/OutlawNPC.java b/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/OutlawNPC.java new file mode 100644 index 0000000..9649f5f --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/OutlawNPC.java @@ -0,0 +1,63 @@ +package content.region.misthalin.varrock.quest.whatliesbelow; + +import content.data.Quests; +import core.game.node.entity.Entity; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.GroundItemManager; +import core.game.world.map.Location; + +/** + * Handles the outlaw npc. + * @author adam + */ +public class OutlawNPC extends AbstractNPC { + + /** + * Constructs a new {@Code OutlawNPC} {@Code Object} + */ + public OutlawNPC() { + super(-1, null); + } + + /** + * Constructs a new {@Code OutlawNPC} {@Code Object} + * @param id the id. + * @param location the location. + */ + public OutlawNPC(int id, Location location) { + super(id, location); + } + + @Override + public void onAttack(Entity e) { + sendChat("Stand and deliver!"); + } + + @Override + public void finalizeDeath(Entity killer) { + super.finalizeDeath(killer); + if (killer instanceof Player) { + Player p = killer.asPlayer(); + Quest quest = p.getQuestRepository().getQuest(Quests.WHAT_LIES_BELOW); + if (quest.getStage(p) == 10) { + int amount = p.getInventory().getAmount(WhatLiesBelow.RATS_PAPER) + p.getBank().getAmount(WhatLiesBelow.RATS_PAPER); + if (amount < 5) { + GroundItemManager.create(WhatLiesBelow.RATS_PAPER, getLocation()); + } + } + } + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new OutlawNPC(id, location); + } + + @Override + public int[] getIds() { + return new int[] { 5842, 5843, 5844, 5845, 5846, 5847, 5848, 5849, 5850, 5852 }; + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/RatBurgissDialogue.java b/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/RatBurgissDialogue.java new file mode 100644 index 0000000..0a8e97b --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/RatBurgissDialogue.java @@ -0,0 +1,486 @@ +package content.region.misthalin.varrock.quest.whatliesbelow; + +import content.data.Quests; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.AchievementDiary; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.entity.player.link.quest.Quest; +import content.region.misthalin.varrock.diary.RatBurgissDiaryDialogue; + +/** + * The rat burgiss dialogue. + * + * @author Vexia + */ +public class RatBurgissDialogue extends DialoguePlugin { + /** + * The quest. + */ + private Quest quest; + + /** + * If we're chatting about our diary. + */ + private boolean isDiary; + + private final int level = 0; + + /** + * Constructs a new {@Code RatBurgissDialogue} {@Code Object} + * + * @param player the player. + */ + public RatBurgissDialogue(Player player) { + super(player); + } + + /** + * + */ + public RatBurgissDialogue() { + /** + * empty. + */ + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new RatBurgissDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + quest = player.getQuestRepository().getQuest(Quests.WHAT_LIES_BELOW); + options("Hello there!", "I have a question about my Achievement Diary."); + stage = -1; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + if (stage == -1) { + switch (buttonId) { + case 1: + player("Hello there!"); + stage = 5; + break; + case 2: + player("I have a question about my Achievement Diary."); + loadFile(new RatBurgissDiaryDialogue()); + break; + } + return true; + } + if (stage == 900) { + sendDiaryDialogue(); + return true; + } + switch (quest.getStage(player)) { + case 0: + switch (stage) { + /* + * case 0: interpreter.sendDialogues(npc, FacialExpression.NORMAL, + * "Oh, hello. I'd love to chat right now, but I'm a bit busy.", + * "Perhaps you could come back and chat another time?"); stage = 1; + * break; case 1: interpreter.sendDialogues(player, + * FacialExpression.NORMAL, "Of course. Sorry to bother you!"); + * stage = 2; break; case 2: interpreter.sendDialogues(npc, + * FacialExpression.NORMAL, + * "No problem! Say, have you been to see the wizard's", + * "tower in the south yet? It's an amazing sight! you", + * "should go and see it!"); stage = 3; break; case 3: + * interpreter.sendDialogues(player, FacialExpression.NORMAL, + * "Thanks! I will!"); stage = 4; break; case 4: end(); break; + */ + case 5: + npc("Oh, hello. I'm Rat."); + stage++; + break; + case 6: + player("You're a what?"); + stage++; + break; + case 7: + npc("No, no. My name is Rat. Rat Burgiss."); + stage++; + break; + case 8: + player("Ohhhhh, well, what's up, Ratty?"); + stage++; + break; + case 9: + npc("It's Rat, thank you. And I, uh..heh...I seem to", "be in a bit of trouble here, as", "you can probably see."); + stage++; + break; + case 10: + player("Why, what seems to be the matter?"); + stage++; + break; + case 11: + npc("Well, I'm a trader by nature and I was on the way to", "Varrock with my cart here when I was set upon by", "outlaws! They ransacked my cart and stole", "some very important papers that I must get back."); + stage++; + break; + case 12: + player("Shall I get them back for you?"); + stage++; + break; + case 13: + npc("You mean you want to help?"); + stage++; + break; + case 14: + player("Of course! Tell me what you need me to do."); + stage++; + break; + case 15: + npc("Right, now I heard those outlaws say something about", "having a small campsite somewhere to the west of the", "Grand Exchange. They headed off to the north-west of", "here, taking five pages with them."); + stage++; + break; + case 16: + npc("Kill the outlaws and get those papers back from them for", "me. Here's a folder in which you can put the", "pages. Be careful, though; those outlaws are tough."); + stage++; + break; + case 17: + npc("When you find all 5 pages, put them back in the folder", "and bring them back to me!"); + stage++; + break; + case 18: + player("Don't worry, Ratty! I won't let you down!"); + stage++; + break; + case 19: + npc("..."); + stage++; + break; + case 20: + quest.start(player); + end(); + break; + } + break; + case 10: + switch (stage) { + case 0: + npc("Hello again! How are things going?"); + stage++; + break; + case 1: + if (player.getInventory().containsItem(WhatLiesBelow.FULL_FOLDER)) { + player("I got your pages back!"); + stage = 5; + break; + } + if (!player.hasItem(WhatLiesBelow.EMPTY_FOLDER) && !player.hasItem(WhatLiesBelow.USED_FOLDER) && !player.hasItem(WhatLiesBelow.FULL_FOLDER)) { + player("I lost the folder you gave me. Do you have another", "one?"); + stage = 3; + break; + } else { + player("Good!"); + } + stage++; + break; + case 2: + end(); + break; + case 3: + player.getInventory().add(WhatLiesBelow.EMPTY_FOLDER); + npc("Sure. Here you go. I'll add it to your account."); + stage++; + break; + case 4: + end(); + break; + case 5: + npc("Excellent! I knew you could help! Let me take", "those from you, there."); + stage++; + break; + case 6: + npc("Now, I liked the way you handled yourself on that last", "little 'mission' I gave you there, so I'm going to let", "you in on a little secret!"); + stage++; + break; + case 7: + player("Wait! Wait! Let me guess! You're a actually a rich prince", "in disguise who wants to help poor people", "like me!?"); + stage++; + break; + case 8: + npc("Uhhh...no. No, that's not it. You know, on second thought. I", "think I'll keep my secret for now. Look, instead", "you can do another job for me."); + stage++; + break; + case 9: + player("All work and no play makes " + player.getUsername() + " a dull adventurer!"); + stage++; + break; + case 10: + npc("Yes, well, I'm sure that may be the case. However, what", "I want you to do is take this letter to someone", "for me. It's in a different language so, trust me you", "won't be able to read it."); + stage++; + break; + case 11: + npc("Take it to a wizard named Surok Magis who resides in", "the Varrock Palace Library. I'll see about some sort of", "reward for your work when I get myself sorted out here."); + stage++; + break; + case 12: + player("Letter. Wizard. Varrock. Library. Got it!"); + stage++; + break; + case 13: + npc("Yes, good luck then."); + stage++; + break; + case 14: + player.getInventory().remove(WhatLiesBelow.FULL_FOLDER); + player.getInventory().add(WhatLiesBelow.RATS_LETTER); + quest.setStage(player, 20); + end(); + break; + } + break; + case 20: + switch (stage) { + case 0: + npc("Ah, hello. How is your task going?"); + stage++; + break; + case 1: + if (!player.hasItem(WhatLiesBelow.RATS_LETTER)) { + player("I think I lost that letter you gave me!"); + stage = 3; + break; + } + player("Good!"); + stage++; + break; + case 2: + end(); + break; + case 3: + npc("Goodness me! Not much of a messenger, are you? Here's", "another one; try not to lose it this time! I've charged the", "parchment to your account."); + stage++; + break; + case 4: + player("Will you take cheque?"); + stage++; + break; + case 5: + npc("No thanks. I prefer tartan."); + stage++; + break; + case 6: + if (!player.getInventory().contains(WhatLiesBelow.RATS_LETTER.getId(), 1)) { + player.getInventory().add(WhatLiesBelow.RATS_LETTER, player); + } + end(); + break; + } + break; + default: + end(); + break; + case 50: + switch (stage) { + case 0: + npc("Ah, " + player.getUsername() + "! You've returned!"); + stage++; + break; + case 1: + if (!player.getInventory().containsItem(WhatLiesBelow.SUROKS_LETTER)) { + player("I'm still searching!"); + stage = 2; + break; + } + player("Yes! I have a letter for you."); + stage = 3; + break; + case 2: + end(); + break; + case 3: + npc("A letter for me? Let me see."); + stage++; + break; + case 4: + if (player.getInventory().containsItem(WhatLiesBelow.SUROKS_LETTER)) { + npc("This letter is treasonous! This does indeed confirm my", "worst fears. It is time I let you into my", "secret and hopefully this will answer any questions", "you may have."); + stage++; + } + break; + case 5: + player("Okay, go on."); + stage++; + break; + case 6: + npc("I am not really a trader. I am the Commander of", "the Varrock Palace Secret Guard, VPSG for short."); + stage++; + break; + case 7: + player("Okay, I had a feeling you weren't a real trader due to", "the fact that you had nothing to sell! So why", "the secrecy?"); + stage++; + break; + case 8: + npc("I'm just getting to that. A short while ago, we received", "word that Surok had discovered a powerful mind-control", "spell and intended to use it on King Roald himself!"); + stage++; + break; + case 9: + npc("He could control the whole kingdom that way!"); + stage++; + break; + case 10: + player("I think I can believe that. Surok's not the nicest", "person in Misthalin!"); + stage++; + break; + case 11: + npc("Yes, but until now, the spell has been useless to him", "as he is currently under guard at the palace and not", "allowed to leave. He could not get the tools for the spell", "because if he left the palace he would be arrested!"); + stage++; + break; + case 12: + player("Uh oh! I think I may have helped him by mistake, here.", "He promised me a big reward if I collected some items for", "him..but he said it was for a spell to make gold!"); + stage++; + break; + case 13: + npc("I assume you did not know of his plans; that is", "why you weren't arrested!"); + stage++; + break; + case 14: + player("Thank you! How can I help fix this mistake?"); + stage++; + break; + case 15: + npc("Okay, here's what I need you to do. One of my contacts", "has devised a spell that he is sure will be able to", "counteract the effects of the mind-control spell. I need", "you to visit him."); + stage++; + break; + case 16: + player("Okay, who is it?"); + stage++; + break; + case 17: + npc("His name is Zaff. He runs a staff shop in Varrock. Go", "and speak to him and he will tell you what you should", "do. I will send word to him to let him know that", "you are coming."); + stage++; + break; + case 18: + player("Yes, sir! I'm on my way!"); + stage++; + break; + case 19: + player.getInventory().remove(WhatLiesBelow.SUROKS_LETTER); + quest.setStage(player, 60); + end(); + break; + } + break; + case 60: + case 70: + switch (stage) { + case 0: + npc("Yes, " + player.getUsername() + "?"); + stage++; + break; + case 1: + player("Nevermind."); + stage++; + break; + case 2: + end(); + break; + } + break; + case 80: + case 90: + switch (stage) { + case 0: + npc("Well, " + player.getUsername() + ", how did it go?"); + stage++; + break; + case 1: + player("You should have been there! There was this...and Surok", "was like...and I was...and then King...and", "and...uh...ahem! The mission was accomplished and the", "king has been saved."); + stage++; + break; + case 2: + npc("I take it that it went alright, then? That's great news!"); + stage++; + break; + case 3: + npc("Zaff has already briefed me on the events. We will", "arrange for Surok to be fed and watched. I think he", "will not to be a problem any more."); + stage++; + break; + case 4: + player("You know, one thing bother's me. He's now stuck in the", "library, but wasn't that the reason we were in this mess", "in the first place?"); + stage++; + break; + case 5: + npc("Yes, you are right. But rest assured, we will be", "watching him much more closely from now on."); + stage++; + break; + case 6: + npc("You've done very well and have been a credit to the", "VPSG; perhaps one day there may be a place for you", "here!"); + stage++; + break; + case 7: + npc("In the meantime, let me reward you for what you've", "done. I will be sure to call on you if we ever need help", "in the future."); + stage++; + break; + case 8: + quest.finish(player); + end(); + break; + } + break; + case 100: + switch (stage) { + case 0: + npc("Ah, " + player.getUsername() + "! You did a fine service for us. You might", "make a good member of the VPSG one day. With a little", "training and a bit more muscle!"); + stage++; + break; + case 1: + end(); + break; + } + break; + } + return true; + } + + /** + * Sends the diary dialogue. + */ + private void sendDiaryDialogue() { + isDiary = true; + if (AchievementDiary.canClaimLevelRewards(player, DiaryType.VARROCK, level)) { + player("I think I've finished all of the tasks in my Varrock", "Achievement Diary."); + stage = 440; + return; + } + if (AchievementDiary.canReplaceReward(player, DiaryType.VARROCK, level)) { + player("I've seemed to have lost my armour..."); + stage = 460; + return; + } + options("What is the Achievement Diary?", "What are the rewards?", "How do I claim the rewards?", "See you later."); + stage = 0; + } + + @Override + public int[] getIds() { + return new int[]{5833}; + } + + /** + * Gets the isDiary. + * + * @return the isDiary + */ + public boolean isDiary() { + return isDiary; + } + + /** + * Sets the isDiary. + * + * @param isDiary the isDiary to set. + */ + public void setDiary(boolean isDiary) { + this.isDiary = isDiary; + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/SurokMagisDialogue.java b/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/SurokMagisDialogue.java new file mode 100644 index 0000000..838900d --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/SurokMagisDialogue.java @@ -0,0 +1,531 @@ +package content.region.misthalin.varrock.quest.whatliesbelow; + +import content.data.Quests; +import core.game.activity.ActivityManager; +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.world.update.flag.context.Animation; + +/** + * Handles the surok magis dialogue. + * @author Vexia + * @editor Nuggles + * fixed the default dialogue, the NPC and Player tags were swapped. + */ +public class SurokMagisDialogue extends DialoguePlugin { + + /** + * The quest instance. + */ + private Quest quest; + + /** + * The cutscene. + */ + private WLBelowCutscene cutscene; + + /** + * Constructs a new {@Code SurokMagisDialogue} {@Code Object} + */ + public SurokMagisDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@Code SurokMagisDialogue} {@Code Object} + * @param player the player. + */ + public SurokMagisDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new SurokMagisDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + quest = player.getQuestRepository().getQuest(Quests.WHAT_LIES_BELOW); + switch (quest.getStage(player)) { + default: + npc("Excuse me?"); + break; + case 20: + player("Hello."); + break; + case 30: + case 40: + npc("Ah! You're back. Have you found the things I need yet?"); + break; + case 50: + if (!player.hasItem(WhatLiesBelow.SUROKS_LETTER)) { + player("That letter was treasonous so I destroyed it!"); + stage = 10; + break; + } + player("This letter is treasonous! I'm going to report you to the", "king!"); + break; + case 60: + npc("Hi, " + player.getUsername() + "!"); + break; + case 70: + if (!player.getInventory().containsItem(WhatLiesBelow.BEACON_RING) && !player.getEquipment().containsItem(WhatLiesBelow.BEACON_RING)) { + player("I should probably get my beacon ring first..."); + stage = -1; + break; + } + if (args.length >= 2) { + cutscene = player.getAttribute("cutscene", null); + if (args.length == 3) { + player.getDialogueInterpreter().sendDialogues(cutscene.getZaff(), null, "Your teleport spell has been corrupted, Surok! I have", "placed a magic block on this room. You will remain here,", "under guard, in the library from now on."); + stage = 12; + return true; + } + interpreter.sendPlainMessage(true, "The room grows dark and you sense objects moving..."); + stage = 10; + break; + } + player("Surok!! Your plans have been uncovered! You are hereby", "under arrest on the authority of the Varrock Palace", "Secret Guard!"); + break; + case 80: + case 90: + case 100: + npc("You have foiled my plans, " + player.getUsername() + "... I obviously", "underestimated you."); + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (quest.getStage(player)) { + default: + switch (stage) { + case 0: + npc("What do you want? ...Oh, wait. I know! You're", "probably just like all the others, aren't you? After some", "fancy spell or potion from me, I bet!"); + stage = 1; + break; + case 1: + player("No! at least, I don't think so. What sort of spells", "do you have?"); + stage = 2; + break; + case 2: + npc("Hah! I knew it! I expect you want my Aphro-Dizzy-", "Yak spell! Want someone to fall madly in love with you,", "eh?"); + stage = 3; + break; + case 3: + player("That spell sounds very interesting, but I didn't mean to", "disturb you!"); + stage = 4; + break; + case 4: + npc("Well, I see that you do have some manners. I'm glad", "to see that you use them."); + stage = 5; + break; + case 5: + npc("Now, if it's all the same, I am very busy at the", "moment. Come back another time", "please and thank you."); + stage = 6; + break; + case 6: + player("Yes, of course!"); + stage = 7; + break; + case 7: + end(); + break; + } + break; + case 20: + switch (stage) { + case 0: + npc("Hah! Come for my Aphro-Dizzy-Yak spell! Want", "someone to fall madly in love with you eh? Not", "surprised with a face like that, to be honest!"); + stage++; + break; + case 1: + player("I didn't come here to be insulted!"); + stage++; + break; + case 2: + npc("Really? Well, with ears like that, you do surprise me!"); + stage++; + break; + case 3: + if (!player.getInventory().containsItem(WhatLiesBelow.RATS_LETTER)) { + player("Nevermind!"); + stage = 99; + break; + } + player("No, look. I have a letter for you."); + stage++; + break; + case 4: + npc("Really? Well then, let me see it!"); + stage++; + break; + case 5: + player("Here it is!"); + stage++; + break; + case 6: + npc.animate(Animation.create(6096)); + npc("Of all the luck!"); + stage++; + break; + case 7: + player("Why did you destroy the letter?"); + stage++; + break; + case 8: + npc("None of your business! It's a secret!"); + stage++; + break; + case 9: + player("Yes, there seems to be a lot of them going around at", "the moment."); + stage++; + break; + case 10: + npc("Of course. Hmmm. However, I could let you in on", "another secret, if you like?"); + stage++; + break; + case 11: + player("Go on, then!"); + stage++; + break; + case 12: + npc("My secret is this. I have been spending time here in", "the palace library trying to discover some ancient spells", "and magics."); + stage++; + break; + case 13: + npc("In my research, I have uncovered the most astounding", "spell that will allow me to transform simple clay into solid", "gold bars!"); + stage++; + break; + case 14: + npc("Now I am ready to use the spell to create all the gold", "I...uh...the city wants. I would gladly share this gold", "with you; I simply need a few more things."); + stage++; + break; + case 15: + player("Okay, what do you need?"); + stage++; + break; + case 16: + npc("I will only need a couple of items. The first is very", "simple: an ordinary bowl to use as a casting vessel."); + stage++; + break; + case 17: + npc("You should be able to find one of these at any local", "store here in Varrock. I would go myself but I", "am...uh...busy with my research."); + stage++; + break; + case 18: + npc("The other item is much harder. I need a metal wand", "infused with chaos magic."); + stage++; + break; + case 19: + player("How would I get something like that?"); + stage++; + break; + case 20: + npc("Take this metal wand. You will also need 15 chaos", "runes. When you get to the Chaos Altar, use the wand", "on the altar itself. This would infuse the runes into the", "wand."); + stage++; + break; + case 21: + player("How on earth do you know about Runecrafting? I", "thought only a few people knew of it."); + stage++; + break; + case 22: + npc("Hah! Don't presume to think that those wizards in their", "fancy towers are the only people to have heard of", "Runecrafting! Now pay attention!"); + stage++; + break; + case 23: + npc("You will need to have the 15 chaos runes in your", "inventory. Make sure you also have either a chaos", "talisman or chaos tiara to complete the infusion."); + stage++; + break; + case 24: + player("Where can I get a talisman or a tiara?"); + stage++; + break; + case 25: + npc("I'm afraid I don't know. You will need to research for", "one."); + stage++; + break; + case 26: + npc("Bring the infused wand and a bowl back to me and I", "will make us both rich!"); + stage++; + break; + case 27: + npc("One more thing. I have uncovered information here in", "the library which may be of use to you. It tells of a", "safe route to the Chaos Altar that avoids the Wilderness."); + stage++; + break; + case 28: + player("Great! What is it?"); + stage++; + break; + case 29: + npc("It is an old tome...a history book of sorts. It's", "somewhere here in the library. I forget where I left it,", "but it should be easy enough for you to find."); + stage++; + break; + case 30: + npc("I have also given you a copy of a diary", "I...uh...acquired. It may also help you to find that which", "you seek."); + stage++; + break; + case 31: + player.getInventory().remove(WhatLiesBelow.RATS_LETTER); + player.getInventory().add(WhatLiesBelow.WAND, player); + player.getInventory().add(WhatLiesBelow.SIN_KETH_DIARY, player); + quest.setStage(player, 30); + end(); + break; + case 99: + end(); + break; + } + break; + case 30: + case 40: + switch (stage) { + case 0: + if (player.getInventory().containsItem(WhatLiesBelow.INFUSED_WAND)) { + if (!player.getInventory().containsItem(WhatLiesBelow.BOWL)) { + player("No, I still need to get you a bowl."); + stage = 1; + break; + } + player("I have the things you wanted."); + stage = 6; + break; + } + if (!player.hasItem(WhatLiesBelow.WAND)) { + player("I lost the wand!"); + stage = 2; + break; + } + if (!player.hasItem(WhatLiesBelow.SIN_KETH_DIARY)) { + player("I lost the diary!"); + stage = 4; + break; + } + player("No not yet."); + stage++; + break; + case 1: + end(); + break; + case 2: + npc("Somehow, I knew that would happen so I have made a", "few spares for just such an occasion!"); + stage++; + break; + case 3: + npc("Here you are. Try not to lose this one!"); + player.getInventory().add(WhatLiesBelow.WAND, player); + stage = 1; + break; + case 4: + player.getInventory().add(WhatLiesBelow.SIN_KETH_DIARY, player); + npc("Here you are, Try not to lose this one!"); + stage = 5; + break; + case 5: + end(); + break; + case 6: + npc("Excellent! Well done! I knew that you would not let", "me down."); + stage++; + break; + case 7: + player("So...about this gold that you're going to", "give me?"); + stage++; + break; + case 8: + npc("All in good time. I must prepare the spell first", ", and that will take a little time. While I am", "doing that, please take this letter to Rat, the trader", "outside the city who sent you here."); + stage++; + break; + case 9: + player("Okay, but I'll be back for my gold."); + stage++; + break; + case 10: + npc("Yes, yes, yes. Now off you go!"); + stage++; + break; + case 11: + quest.setStage(player, 50); + player.getInventory().add(WhatLiesBelow.SUROKS_LETTER, player); + end(); + break; + } + break; + case 50: + switch (stage) { + case 0: + npc("Hah! Have fun with that!"); + stage++; + break; + case 1: + end(); + break; + case 10: + npc("Really? You destroyed it?"); + stage++; + break; + case 11: + player("Yes!"); + stage++; + break; + case 12: + npc("You want another one, don't you?"); + stage++; + break; + case 13: + player("Ah..uh..yes..yes, I do."); + stage++; + break; + case 14: + player.getInventory().add(WhatLiesBelow.SUROKS_LETTER, player); + npc("Fine. Here you are. And stop all this complaining; it's", "getting me down!"); + stage++; + break; + case 15: + end(); + break; + } + break; + case 60: + switch (stage) { + case 0: + player("You are a bad man!"); + stage++; + break; + case 1: + end(); + break; + } + break; + case 70: + switch (stage) { + case -1: + end(); + break; + case 0: + npc("So! You're with the Secret Guard, eh? I should have", "known! I knew you had ugly ears from the start...", "and your nose is too short!"); + stage++; + break; + case 1: + player("Give yourself up, Surok!"); + stage++; + break; + case 2: + npc("Never! I am Surok Magis, descendant of the High Elder", "Sin'keth Magis, rightful heir of the Dagon'hai Order! I will", "have my revenge on those who destroyed my people!"); + stage++; + break; + case 3: + player("The place is surrounded. There is nowhere to run!"); + stage++; + break; + case 4: + npc("Do you really wish to die so readily? Are you prepared", "to face your death?"); + stage++; + break; + case 5: + player("Bring it on!"); + stage++; + break; + case 6: + npc("I am Dagon'hai! I run from nothing. My spell has", "been completed and it is time for you to meet your", "end, " + player.getUsername() + "! The king is now under my control!"); + stage++; + break; + case 7: + end(); + ActivityManager.start(player, "What Lies below", false); + break; + case 10: + close(); + player.unlock(); + cutscene.getKing().unlock(); + cutscene.reset(); + player.getInterfaceManager().restoreTabs(); + cutscene.getKing().getProperties().getCombatPulse().attack(player); + stage = 11; + break; + case 11: + close(); + stage = 12; + break; + case 12: + player.lock(); + npc("No! All is lost! I must escape!"); + stage++; + break; + case 13: + interpreter.sendDialogues(cutscene.getZaff(), null, "You will not escape justice this time, Surok!"); + stage = 14; + break; + case 14: + npc("No! My plans have been ruined! I was so close to", "success!"); + stage = 16; + break; + case 16: + interpreter.sendDialogues(cutscene.getZaff(), null, "Thank you for your help, " + player.getUsername() + ". I will put the", "room back in order and then I must leave. Surok is", "defeated and will be no more trouble for us. We will", "guard him more closely from now on!"); + stage++; + break; + case 17: + quest.setStage(player, 80); + interpreter.sendPlainMessage(true, "The room grows dark and you sense objects moving..."); + cutscene.stop(true); + break; + } + break; + case 80: + case 90: + case 100: + switch (stage) { + case 0: + player("Yes. Let this be a lesson to you."); + stage++; + break; + case 1: + npc("..."); + stage++; + break; + case 2: + end(); + break; + } + break; + } + return true; + } + + @Override + public void end() { + if (cutscene != null) { + return; + } + super.end(); + } + + @Override + public int[] getIds() { + return new int[] { 5834, 5835 }; + } + + /** + * Gets the cutscene. + * @return the cutscene + */ + public WLBelowCutscene getCutscene() { + return cutscene; + } + + /** + * Sets the cutscene. + * @param cutscene the cutscene to set. + */ + public void setCutscene(WLBelowCutscene cutscene) { + this.cutscene = cutscene; + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/WLBelowCutscene.java b/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/WLBelowCutscene.java new file mode 100644 index 0000000..d1c154c --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/WLBelowCutscene.java @@ -0,0 +1,353 @@ +package content.region.misthalin.varrock.quest.whatliesbelow; + +import core.game.activity.ActivityPlugin; +import core.game.activity.CutscenePlugin; +import core.game.dialogue.FacialExpression; +import core.game.interaction.Option; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.map.build.DynamicRegion; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.net.packet.PacketRepository; +import core.net.packet.context.CameraContext; +import core.net.packet.context.CameraContext.CameraType; +import core.net.packet.out.CameraViewPacket; + +/** + * Handles the what lies below cutscene. + * @author Vexia + */ +public class WLBelowCutscene extends CutscenePlugin { + + /** + * The surok npc. + */ + private NPC surok; + + /** + * The king. + */ + private NPC king; + + /** + * The zaff npc. + */ + private NPC zaff; + + /** + * Constructs a new {@Code WLBelowCutscene} {@Code Object} + */ + public WLBelowCutscene() { + super("What Lies below"); + } + + /** + * Constructs a new {@Code WLBelowCutscene} {@Code Object} + * @param player the player. + */ + public WLBelowCutscene(Player player) { + this(); + this.player = player; + this.setUid(getName().hashCode()); + } + + @Override + public boolean start(final Player player, boolean login, Object... args) { + player.lock(); + player.setAttribute("cutscene", this); + Scenery table = RegionManager.getObject(base.transform(9, 37, 0)); + if (table != null) { + SceneryBuilder.remove(table); + } + surok = NPC.create(5835, base.transform(8, 39, 0)); + surok.init(); + king = KingRoaldNPC.create(5838, base.transform(10, 34, 0)); + king.lock(); + ((KingRoaldNPC) king).setCutscene(this); + king.init(); + king.face(player); + surok.face(king); + player.face(surok); + player.getDialogueInterpreter().open(5834, surok, this); + return super.start(player, login, args); + } + + @Override + public void open() { + player.lock(); + sendCamera(0, -6, 0, 0, 500, 100); + surok.animate(Animation.create(1084)); + surok.graphics(Graphics.create(108)); + surok.sendChat("Annach Narh Hin Dei!"); + sendCamera(0, 3, 0, 0, 450, 95, 5); + king.animate(Animation.create(860), 7); + king.sendChat("What's going on?", 6); + king.sendChat("I...must...kill..." + player.getUsername() + "!!", 9); + player.sendChat("Uh oh! King Roald looks evil!", 13); + GameWorld.getPulser().submit(new Pulse(13) { + @Override + public boolean pulse() { + reset(); + player.face(king); + player.getDialogueInterpreter().sendDialogues(player, FacialExpression.ANNOYED, "Uh oh! King Roald looks evil!"); + return true; + } + }); + super.open(); + } + + @Override + public void end() { + super.end(); + player.removeAttribute("cutscene"); + player.getDialogueInterpreter().close(); + if (player.getDialogueInterpreter().getDialogue() != null) { + player.getDialogueInterpreter().getDialogue().end(); + } + } + + @Override + public boolean interact(Entity entity, Node target, Option option) { + if (entity instanceof Player) { + switch (target.getId()) { + case 5835: + if (player.getAttribute("can-arrest", false)) { + Location loc = base.transform(9, 34, 0); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.POSITION, loc.getX(), loc.getY(), 450, 1, 100)); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.ROTATION, loc.getX(), loc.getY(), 450, 1, 100)); + zaff.face(surok); + surok.face(zaff); + player.lock(); + surok.animate(Animation.create(1084)); + surok.sendChat("Mirra din namus!!", 1); + player.sendMessage("Surok looks like he's trying to teleport away!"); + zaff.sendChat("Stop!!", 3); + surok.sendChat("Nooooooooooooo!", 6); + GameWorld.getPulser().submit(new Pulse(3, player) { + + @Override + public boolean pulse() { + surok.animate(Animation.create(6098)); + zaff.animate(Animation.create(1819)); + Projectile.magic(zaff, surok, 109, 60, 36, 36, 10).send(); + return true; + } + + }); + GameWorld.getPulser().submit(new Pulse(9, player) { + + @Override + public boolean pulse() { + player.getDialogueInterpreter().open(5834, surok, this, true); + return true; + } + + }); + return true; + } + return true; + case 11014: + if (option.getName().toLowerCase().equals("operate") || option.getName().toLowerCase().equals("summon")) { + if (king.getAttribute("message", false)) { + summonZaff(); + return true; + } + } + break; + case 15536: + return true; + } + } + return super.interact(entity, target, option); + } + + @Override + public boolean teleport(Entity e, int type, Node node) { + if (type != -1) { + return false; + } + return super.teleport(e, type, node); + } + + /** + * Summons zaff. + */ + public void summonZaff() { + if (!king.getAttribute("message", false)) { + player.sendMessage("Zaff isn't ready to be summoned."); + return; + } + player.lock(); + king.lock(); + king.getProperties().getCombatPulse().stop(); + player.getProperties().getCombatPulse().stop(); + player.getInterfaceManager().removeTabs(getRemovedTabs()); + zaff = NPC.create(5836, player.getLocation()); + Location loc = RegionManager.getSpawnLocation(player, zaff); + if (loc != null) { + zaff.setLocation(loc); + } + zaff.init(); + zaff.graphics(Graphics.create(110)); + if (zaff.getLocation().equals(king.getLocation()) || zaff.getLocation().equals(surok.getLocation())) { + zaff.moveStep(); + } + zaff.face(king); + king.face(zaff); + zaff.animate(Animation.create(5633)); + zaff.sendChat("Sin danna nim borha!!", 2); + king.animate(Animation.create(6099), 5); + zaff.graphics(Graphics.create(108), 3); + king.graphics(Graphics.create(110), 8); + king.sendChat("Wh...!", 7); + GameWorld.getPulser().submit(new Pulse(9, player) { + + @Override + public boolean pulse() { + king.clear(); + player.unlock(); + player.setAttribute("can-arrest", true); + player.getDialogueInterpreter().sendDialogues(zaff, null, "The king's mind has been restored to him and he has", "been teleported away to safety. Now, to deal with", "Surok!"); + return true; + } + + }); + } + + /** + * Sends the camera on a tick. + * @param x1 the x. + * @param y1 the y1. + * @param x2 the x2. + * @param y2 the y2. + * @param height the height. + * @param speed the speed. + * @param ticks the ticks. + */ + public void sendCamera(final int x1, final int y1, final int x2, final int y2, final int height, final int speed, int ticks) { + GameWorld.getPulser().submit(new Pulse(ticks, player) { + + @Override + public boolean pulse() { + sendCamera(x1, y1, x2, y2, height, speed); + return true; + } + + }); + } + + /** + * Sends a camera. + * @param height the height. + * @param speed the speed. + */ + public void sendCamera(int x1, int y1, int x2, int y2, int height, int speed) { + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.POSITION, player.getLocation().getX() + x1, player.getLocation().getY() + y1, height, 1, speed)); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.ROTATION, player.getLocation().getX() + x2, player.getLocation().getY() + y2, height, 1, speed)); + } + + /** + * Resets the camera on a tick. + * @param ticks the ticks. + */ + public void reset(int ticks) { + GameWorld.getPulser().submit(new Pulse(1, player) { + + @Override + public boolean pulse() { + reset(); + return true; + } + + }); + } + + /** + * Resets the camera. + */ + public void reset() { + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.RESET, 0, 0, 0, 0, 0)); + } + + @Override + public ActivityPlugin newInstance(Player p) throws Throwable { + return new WLBelowCutscene(p); + } + + @Override + public Location getStartLocation() { + return base.transform(10, 38, 0); + } + + @Override + public Location getSpawnLocation() { + return null; + } + + @Override + public void configure() { + region = DynamicRegion.create(12854); + region.setMusicId(250); + setRegionBase(); + registerRegion(region.getId()); + } + + /** + * Gets the surok. + * @return the surok + */ + public NPC getSurok() { + return surok; + } + + /** + * Sets the surok. + * @param surok the surok to set. + */ + public void setSurok(NPC surok) { + this.surok = surok; + } + + /** + * Gets the king. + * @return the king + */ + public NPC getKing() { + return king; + } + + /** + * Sets the baking. + * @param king the king to set. + */ + public void setKing(NPC king) { + this.king = king; + } + + /** + * Gets the zaff. + * @return the zaff + */ + public NPC getZaff() { + return zaff; + } + + /** + * Sets the zaff. + * @param zaff the zaff to set. + */ + public void setZaff(NPC zaff) { + this.zaff = zaff; + } + +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/WLBelowPlugin.java b/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/WLBelowPlugin.java new file mode 100644 index 0000000..09c27bc --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/WLBelowPlugin.java @@ -0,0 +1,262 @@ +package content.region.misthalin.varrock.quest.whatliesbelow; + +import content.data.Quests; +import core.cache.def.impl.SceneryDefinition; +import core.game.component.Component; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.activity.ActivityManager; +import core.game.node.entity.skill.Skills; +import content.data.skill.SkillingTool; +import content.global.skill.runecrafting.Altar; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.OptionHandler; +import core.game.interaction.UseWithHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; +import core.plugin.ClassScanner; +import static core.api.ContentAPIKt.*; + + +/** + * Handles the what lies below options. + * @author Vexia + * + */ +public class WLBelowPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ClassScanner.definePlugin(new OutlawNPC()); + ClassScanner.definePlugin(new KingRoaldNPC()); + ActivityManager.register(new WLBelowCutscene()); + ClassScanner.definePlugin(new FolderHandler()); + ClassScanner.definePlugin(new MetalWandHandler()); + ClassScanner.definePlugin(new AnnaJonesDialogue()); + ClassScanner.definePlugin(new SurokMagisDialogue()); + ClassScanner.definePlugin(new RatBurgissDialogue()); + SceneryDefinition.forId(23095).getHandlers().put("option:use", this); + SceneryDefinition.forId(23058).getHandlers().put("option:enter", this); + SceneryDefinition.forId(23057).getHandlers().put("option:excavate", this); + WhatLiesBelow.RATS_PAPER.getDefinition().getHandlers().put("option:read", this); + WhatLiesBelow.EMPTY_FOLDER.getDefinition().getHandlers().put("option:read", this); + WhatLiesBelow.USED_FOLDER.getDefinition().getHandlers().put("option:read", this); + WhatLiesBelow.FULL_FOLDER.getDefinition().getHandlers().put("option:read", this); + WhatLiesBelow.RATS_LETTER.getDefinition().getHandlers().put("option:read", this); + WhatLiesBelow.SUROKS_LETTER.getDefinition().getHandlers().put("option:read", this); + WhatLiesBelow.BEACON_RING.getDefinition().getHandlers().put("option:summon", this); + WhatLiesBelow.BEACON_RING.getDefinition().getHandlers().put("option:operate", this); + return this; + } + + @Override + public boolean handle(final Player player, Node node, String option) { + final Quest quest = player.getQuestRepository().getQuest(Quests.WHAT_LIES_BELOW); + switch (option) { + case "summon": + case "operate": + if (quest.getStage(player) > 70) { + player.sendMessage("Zaff has removed the summon charges from the ring. It will not summon him again."); + } else { + if (quest.getStage(player) == 70 && player.getZoneMonitor().isInZone("What Lies below")) { + WLBelowCutscene cutscene = player.getAttribute("cutscene", null); + cutscene.summonZaff(); + return true; + } + player.sendMessage("You need to use this at the proper time."); + } + break; + case "enter": + switch (node.getId()) { + case 23058: + player.animate(Animation.create(6103)); + player.teleport(new Location(3179, 5191, 0), 2); + + break; + } + break; + case "use": + switch (node.getId()) { + case 23095: + player.teleport(new Location(2270, 4836, 1)); + // Take the Dagon'Hai shortcut to the chaos portal + player.getAchievementDiaryManager().finishTask(player, DiaryType.VARROCK, 1, 2); + break; + } + break; + case "excavate": + switch (quest.getStage(player)) { + case 30: + final SkillingTool tool = SkillingTool.getPickaxe(player); + if (tool == null) { + player.sendMessage("You need a pickaxe in order to do that."); + break; + } + player.lock(); + player.animate(tool.getAnimation()); + GameWorld.getPulser().submit(new Pulse(1, player) { + int count; + + @Override + public boolean pulse() { + count++; + int duration = 7; + if (count == duration) { + player.sendChat("Hmmm..."); + } else if (count == duration + 2) { + player.animate(tool.getAnimation()); + } else if (count == duration * 2) { + quest.setStage(player, 40); + player.getAnimator().reset(); + setVarp(player, 992, 1 << 8, true); + player.getDialogueInterpreter().open(5837, true, true, true); + player.unlock(); + return true; + } + return false; + } + + }); + break; + default: + player.sendMessage("Nothing interesting happened."); + break; + } + break; + case "read": + switch (node.getId()) { + case 11003: + String message = "The folder is empty at the moment so there is nothing inside to read!"; + player.sendMessage(message); + break; + case 11009: + case 11010: + player.sendMessage("You read the letter."); + player.getInterfaceManager().open(new Component(node.getId() == 11009 ? 249 : 250)); + break; + case 11008: + case 11007: + case 11006: + player.getDialogueInterpreter().sendDialogue("The piece of papers appears to contain lots of facts and figures.", "They look like accounts and lists of items. You're", "not sure what they all mean."); + break; + } + break; + } + return true; + } + + /** + * Handles the infusion of the metal wand. + * @author Vexia + */ + public static class MetalWandHandler extends UseWithHandler { + + /** + * The chaos runes. + */ + private static final Item CHAOS_RUNES = new Item(562, 15); + + /** + * The chaos talisman. + */ + private static final Item CHAOS_TALISMAN = new Item(1452); + + /** + * The chaos tiara. + */ + private static final Item CHAOS_TIARA = new Item(5543); + + /** + * Constructs a new {@Code MetalWandHandler} {@Code + * Object} + */ + public MetalWandHandler() { + super(WhatLiesBelow.WAND.getId()); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(Altar.CHAOS.getObject(), OBJECT_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + Player player = event.getPlayer(); + if (!player.getInventory().containsItem(CHAOS_RUNES)) { + player.sendMessage("You need 15 chaos runes."); + return true; + } + /*if (!player.getInventory().containsItem(CHAOS_TALISMAN) && !player.getInventory().containsItem(CHAOS_TIARA)) { + player.sendMessage("You need a chaos talisman or chaos tiara."); + return true; + }*/ + Item chaosItem = player.getInventory().containsItem(CHAOS_TALISMAN) ? CHAOS_TALISMAN : CHAOS_TIARA; + if (player.getSkills().hasLevel(Skills.RUNECRAFTING,35)){ + if (chaosItem != null && player.getInventory().remove(CHAOS_RUNES)) { + player.lock(5); + player.getInventory().remove(WhatLiesBelow.WAND); + player.getInventory().add(WhatLiesBelow.INFUSED_WAND); + player.animate(Animation.create(6104)); + player.getDialogueInterpreter().sendDialogue("The metal wand bursts into life and crackles with arcane", "power. This is a powerful instrument indeed!"); + } + return true; + }else { + player.getDialogueInterpreter().sendDialogue("You need a Runecrafting level of 35 to make the infused wand."); + return false; + } + } + + } + + /** + * Handles the empty folder. + * @author Vexia + */ + public class FolderHandler extends UseWithHandler { + + /** + * Constructs a new {@Code FolderHandler} {@Code Object} + */ + public FolderHandler() { + super(WhatLiesBelow.EMPTY_FOLDER.getId(), WhatLiesBelow.USED_FOLDER.getId()); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(WhatLiesBelow.RATS_PAPER.getId(), ITEM_TYPE, this); + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + Player player = event.getPlayer(); + Item paper = event.getUsedItem(); + Item folder = event.getUsedWith().asItem(); + if (player.getInventory().remove(paper)) { + if (folder.getId() == 11003) { + player.getInventory().replace(WhatLiesBelow.USED_FOLDER, folder.getSlot()); + folder = player.getInventory().get(folder.getSlot()); + } + folder.setCharge(folder.getCharge() + 1); + int amount = 1005 - folder.getCharge(); + player.sendMessage("You add the page to the folder that Rat gave to you."); + if (amount <= 0) { + player.getInventory().replace(WhatLiesBelow.FULL_FOLDER, folder.getSlot()); + player.sendMessage("You add the last page to Rat's folder. You should take this back to Rat as soon as"); + player.sendMessage("possible."); + player.getDialogueInterpreter().sendDialogue("You have added all the pages to the folder that Rat gave to you.", "You should take this folder back to Rat."); + return true; + } + player.sendMessage("You need to find " + amount + " more page" + (amount <= 1 ? "." : "s.")); + } + return true; + } + } +} diff --git a/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/WhatLiesBelow.java b/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/WhatLiesBelow.java new file mode 100644 index 0000000..0b02381 --- /dev/null +++ b/Server/src/main/content/region/misthalin/varrock/quest/whatliesbelow/WhatLiesBelow.java @@ -0,0 +1,219 @@ +package content.region.misthalin.varrock.quest.whatliesbelow; + +import core.plugin.Initializable; +import org.rs09.consts.Items; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import core.plugin.ClassScanner; + +import static core.api.ContentAPIKt.*; +import content.data.Quests; + +/** + * The what lies below quest. + * @author Vexa + * + */ +@Initializable +public class WhatLiesBelow extends Quest { + /** + * The bowl item. + */ + public static final Item BOWL = new Item(Items.BOWL_1923); + + /** + * The sin keth diary. + */ + public static final Item SIN_KETH_DIARY = new Item(Items.SINKETHS_DIARY_11002); + + /** + * The empty folder item. + */ + public static final Item EMPTY_FOLDER = new Item(Items.AN_EMPTY_FOLDER_11003); + + /** + * The used folder. + */ + public static final Item USED_FOLDER = new Item(Items.USED_FOLDER_11006); + + /** + * The full folder. + */ + public static final Item FULL_FOLDER = new Item(Items.FULL_FOLDER_11007); + + /** + * The rats paper item. + */ + public static final Item RATS_PAPER = new Item(Items.RATS_PAPER_11008); + + /** + * The rats letter. + */ + public static final Item RATS_LETTER = new Item(Items.RATS_LETTER_11009); + + /** + * The suroks letter. + */ + public static final Item SUROKS_LETTER = new Item(Items.SUROKS_LETTER_11010); + + /** + * The wand item. + */ + public static final Item WAND = new Item(Items.WAND_11012); + + /** + * The infused item. + */ + public static final Item INFUSED_WAND = new Item(Items.INFUSED_WAND_11013); + + /** + * The bacon ring. + */ + public static final Item BEACON_RING = new Item(Items.BEACON_RING_11014); + + /** + * The requirements. + */ + private final boolean[] requirements = new boolean[4]; + + /** + * Constructs a new {@Code WhatLiesBelow} {@Code Object} + */ + public WhatLiesBelow() { + super(Quests.WHAT_LIES_BELOW, 136, 135, 1); + } + + @Override + public Quest newInstance(Object object) { + ClassScanner.definePlugin(new WLBelowPlugin()); + return this; + } + + @Override + public void drawJournal(Player player, int stage) { + super.drawJournal(player, stage); + var line = 12; + + if(stage == 0){ + line(player, "I can start this quest by speaking to !!Rat Burgiss?? on the", line++); + line(player, "road south of !!Varrock??.", line++); + line(player, "Before I begin I will need to:", line++); + line(player, "Have level 35 !!Runecrafting??.", line++, getStatLevel(player, Skills.RUNECRAFTING) >= 35); + line(player, "Be able to defeat a !!level 47 enemy??.", line++); + line(player, "I need to have completed the !!Rune Mysteries?? quest.", line++, isQuestComplete(player, Quests.RUNE_MYSTERIES)); + line(player, "Have a !!Mining?? level of 42 to use the !!Chaos Tunnel??.", line++, getStatLevel(player, Skills.MINING) >= 42); + } else { + // These are somehow at the top with different stage when crossed out. + if (stage >= 10) { + line(player, "!!Rat??, a trader in Varrock, has asked me to help him with a", line++, stage >= 30); + line(player, "task.", line++, stage >= 30); + } + if (stage >= 30) { + line(player, "!!Surok??, a Wizard in Varrock, has asked me to complete a", line++, stage >= 50); + line(player, "task for him.", line++, stage >= 50); + } + // End + + if (stage >= 10) { + line(player, "I need to kill !!outlaws?? west of Varrock so that I can collect 5", line++, stage >= 20); + line(player, "of Rat's !!papers??.", line++, stage >= 20); + if (inInventory(player, Items.FULL_FOLDER_11007, 1)) { + line(player, "I should take the !!full folder?? back to Rat.", line++); + } + } + if (stage >= 20) { + line(player, "I have delivered Rat's folder to him. Perhaps I should", line++, stage >= 30); + line(player, "should speak to him again.", line++, stage >= 30); + // Should be separated stages + line(player, "I need to deliver !!Rat's?? letter to !!Surok Magis?? in !!Varrock??.", line++, stage >= 30); + // Should be separated stages + line(player, "I need to talk to !!Surok?? about the secret he has for me.", line++, stage >= 30); + } + if (stage >= 30) { + line(player, "I need to infuse the !!metal wand?? with !!chaos runes?? at the", line++, stage >= 50); + line(player, "!!Chaos Altar??. I also need to find or buy an empty !!bowl??.", line++, stage >= 50); + } + if (stage >= 50) { + line(player, "I need to take the !!glowing wand?? I have created back to", line++, true); + line(player, "!!Surok?? in Varrock along with an empty !!bowl??.", line++, true); + // Should be separated stages + line(player, "I need to deliver !!Surok's letter?? to !!Rat?? who is waiting for me", line++, true); + line(player, "south of Varrock.", line++, true); + // Should be separated stages + line(player, "I should speak to !!Rat?? again; he is waiting for me south of", line++, stage >= 60); + line(player, "Varrock.", line++, stage >= 60); + } + if (stage >= 60) { + line(player, "I need to speak to !!Zaff?? of !!Zaff's Staffs?? in Varrock.", line++, stage >= 70); + } + if (stage >= 70) { + line(player, "I need to tell !!Surok?? in Varrock that he is under arrest.", line++, stage >= 80); + } + if (stage >= 80) { + line(player, "I need to defeat !!King Roald?? in Varrock so that !!Zaff?? can", line++, true); + line(player, "remove the mind-control spell.", line++, true); + // Should be separated stages + line(player, "I need to tell !!Rat?? what has happened; he is waiting for me", line++, stage >= 100); + line(player, "south of Varrock.", line++, stage >= 100); + } + if (stage >= 100) { + line++; + line++; + line(player,"QUEST COMPLETE!", line++); + line++; + line(player, "I have been given information about the !!Chaos Tunnel??.", line++); + line(player, "Zaff has given me the !!Beacon Ring??.", line++); + line++; + line(player, "I have also been given !!8,000 Runecrafting XP, 2000??.", line++); + line(player, "!!Defence XP?? and !!1 Quest Point??.", line++); + } + } + } + + @Override + public void start(Player player) { + super.start(player); + player.getInventory().add(EMPTY_FOLDER, player); + } + + @Override + public void finish(Player player) { + super.finish(player); + player.getPacketDispatch().sendString("8,000 Runecrafting XP", 277, 8+ 2); + player.getPacketDispatch().sendString("2,000 Defence XP", 277, 9+ 2); + player.getPacketDispatch().sendString("Beacon Ring", 277, 10+ 2); + player.getPacketDispatch().sendString("Knowledge of Chaos Tunnel", 277, 11+ 2); + player.getPacketDispatch().sendItemZoomOnInterface(BEACON_RING.getId(), 235, 277, 3+ 2); + player.getSkills().addExperience(Skills.RUNECRAFTING, 8000); + player.getSkills().addExperience(Skills.DEFENCE, 2000); + player.getQuestRepository().syncronizeTab(player); + } + + + @Override + public boolean hasRequirements(Player player) { + requirements[0] = player.getSkills().getStaticLevel(Skills.RUNECRAFTING) >= 35; + requirements[1] = false; + requirements[3] = player.getSkills().getStaticLevel(Skills.MINING) >= 42; + requirements[2] = player.getQuestRepository().isComplete(Quests.RUNE_MYSTERIES); + return requirements[0] && requirements[2] && requirements[3]; + } + + @Override + public int[] getConfig(Player player, int stage) { + int id = 992; + if (stage >= 40 && stage != 100) { + return new int[] { id, (1 << 8) + 1 }; + } + if (stage == 0) { + return new int[] { id, 0 }; + } else if (stage > 0 && stage < 100) { + return new int[] { id, 1 }; + } + setVarp(player, 1181, (1 << 8) + (1 << 9), true); + return new int[] { id, 502 }; + } + +} diff --git a/Server/src/main/content/region/misthalin/wiztower/dialogue/DrOnglewipDialogue.java b/Server/src/main/content/region/misthalin/wiztower/dialogue/DrOnglewipDialogue.java new file mode 100644 index 0000000..75b08b0 --- /dev/null +++ b/Server/src/main/content/region/misthalin/wiztower/dialogue/DrOnglewipDialogue.java @@ -0,0 +1,81 @@ +package content.region.misthalin.wiztower.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the dr onglewip dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class DrOnglewipDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code DrOnglewipDialogue} {@code Object}. + */ + public DrOnglewipDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code DrOnglewipDialogue} {@code Object}. + * @param player the player. + */ + public DrOnglewipDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new DrOnglewipDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.ASKING, "Do you live here too?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "Oh no, I come from Gnome Stronghold. I've been", "sent here by King Narnode to learn about human", "magics."); + stage = 1; + break; + case 1: + interpreter.sendDialogues(player, FacialExpression.ASKING, "So where's this Gnome Stronghold?"); + stage = 2; + break; + case 2: + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "It's in the North West of the continent - a long way", "away. You should visit us there some time. The food's", "great, and the company's delightful."); + stage = 3; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.FRIENDLY, "I'll try and make time for it. Sounds like a nice place."); + stage = 4; + break; + case 4: + interpreter.sendDialogues(npc, FacialExpression.OLD_NORMAL, "Well, it's full of gnomes. How much nicer could it be?"); + stage = 5; + break; + case 5: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 4585 }; + } +} diff --git a/Server/src/main/content/region/misthalin/wiztower/dialogue/TraibornDialogue.java b/Server/src/main/content/region/misthalin/wiztower/dialogue/TraibornDialogue.java new file mode 100644 index 0000000..4f4200c --- /dev/null +++ b/Server/src/main/content/region/misthalin/wiztower/dialogue/TraibornDialogue.java @@ -0,0 +1,401 @@ +package content.region.misthalin.wiztower.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; + +import content.region.misthalin.varrock.quest.demonslayer.DemonSlayer; +import content.data.Quests; + +/** + * Represents the dialogue used to handle the Traiborn NPC. + * @author 'Vexia + * @date 3/1/14 + */ +public class TraibornDialogue extends DialoguePlugin { + + /** + * Represents the bones item. + */ + private static final Item BONES = new Item(526, 25); + + /** + * Represents the object animation. + */ + @SuppressWarnings("unused") + private static final Animation OBJECT_ANIM = new Animation(4599); + + /** + * Represents the animation of giving the key. + */ + private static final Animation ANIMATION = new Animation(536); + + /** + * Represents the quest instance. + */ + private Quest quest; + + /** + * Constructs a new {@code TraibornDialogue} {@code Object}. + */ + public TraibornDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code TraibornDialogue} {@code Object}. + * @param player the player. + */ + public TraibornDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new TraibornDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + quest = player.getQuestRepository().getQuest(Quests.DEMON_SLAYER); + switch (quest.getStage(player)) { + case 20: + if (player.getAttribute("demon-slayer:traiborn", false)) { + npc("How are you doing finding bones?"); + stage = 380; + } else { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ello young thingummywut."); + stage = 0; + } + break; + default: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Ello young thingummywut."); + stage = 0; + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (quest.getStage(player)) { + case 20: + switch (stage) { + case 0: + if (player.getInventory().containsItem(DemonSlayer.THIRD_KEY) && player.getBank().containsItem(DemonSlayer.THIRD_KEY)) { + options("What's a thingummywut?", "Teach me to be a mighty powerful wizard."); + stage = 1; + } else { + options("What's a thingummywut?", "Teach me to be a mighty powerful wizard.", "I need to get a key given to you by Sir Prysin."); + stage = 1; + } + break; + case 1: + switch (buttonId) { + case 1: + case 2: + handleDefault(buttonId); + break; + case 3: + player("I need to get a key given to you by Sir Prysin."); + stage = 300; + break; + } + break; + case 300: + npc("Sir Prysin? Who's that? What would I want his key", "for?"); + stage = 301; + break; + case 301: + player("Well, have you got any keys knocking around?"); + stage = 302; + break; + case 302: + npc("Now you come to mention it, yes I do have a key. It's", "in my special closet of valuable stuff. Now how do I get", "into that?"); + stage = 303; + break; + case 303: + npc("I sealed it using one of my magic rituals. So it would", "makes sense that another ritual would open it again."); + stage = 304; + break; + case 304: + player("So do you know what ritual to use?"); + stage = 305; + break; + case 305: + npc("Let me think a second."); + stage = 306; + break; + case 306: + npc("Yes a simple drazier style ritual should suffice. Hmm,", "main problem with that is I'll need 25 sets of bones.", "Now where am I going to get hold of something like", "that?"); + stage = 307; + break; + case 307: + options("Hmm, that's too bad. I really need that key.", "I'll get the bones for you."); + stage = 308; + break; + case 308: + switch (buttonId) { + case 1: + player("Hmm, that's too bad. I really need that key."); + stage = 330; + break; + case 2: + player("I'll get the bones for you."); + stage = 340; + break; + } + break; + case 330: + npc("Ah well, sorry I couldn't be any more help."); + stage = 331; + break; + case 331: + end(); + break; + case 340: + npc("Ooh that would be very good of you."); + stage = 341; + break; + case 341: + player("Ok I'll speak to you when I've got some bones."); + stage = 342; + break; + case 342: + player.setAttribute("/save:demon-slayer:traiborn", true); + end(); + break; + case 380: + if (player.getInventory().containsItem(BONES)) { + player("I have some bones."); + stage = 382; + } else { + player("I don't have all the bones yet."); + stage = 381; + } + break; + case 382: + npc("Give 'em here then."); + stage = 383; + break; + case 383: + interpreter.sendDialogue("You give Traiborn 25 sets of bones."); + stage = 384; + break; + case 384: + npc("Hurrah! That's all 25 sets of bones."); + stage = 385; + break; + case 385: + npc.animate(new Animation(4602)); + npc("Wings of dark and colour too,", "Spreading in the morning dew;", "Locked away I have a key;", "Return it now, please, unto me."); + stage = 386; + break; + case 386: + final Scenery object = new Scenery(17434, Location.create(3113, 3161, 1), 11, 1); + SceneryBuilder.add(object); + npc.faceLocation(object.getLocation()); + npc.animate(ANIMATION); + if (!player.getInventory().containsItem(BONES)) { + end(); + return true; + } + if (player.getInventory().remove(BONES)) { + player.removeAttribute("demon-slayer:traiborn"); + player.getInventory().add(DemonSlayer.THIRD_KEY); + interpreter.sendItemMessage(DemonSlayer.THIRD_KEY.getId(), "Traiborn hands you a key."); + stage = 387; + } + GameWorld.getPulser().submit(new Pulse(1) { + int counter = 0; + + @Override + public boolean pulse() { + switch (counter++) { + case 5: + npc.face(player); + break; + case 7: + SceneryBuilder.remove(object); + return true; + } + return false; + } + }); + break; + case 387: + player("Thank you very much."); + stage = 388; + break; + case 388: + npc("Not a problem for a friend of Sir What's-his-face."); + stage = 389; + break; + case 389: + end(); + break; + case 381: + end(); + break; + } + break; + case 0: + switch (stage) { + default: + handleDefault(buttonId); + break; + } + break; + } + return true; + } + + /** + * Method used to handle the default button id. + * @param buttonId the buttton id. + */ + private final void handleDefault(int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "What's a thingummywut?", "Teach me to be a mighty and powerful wizard."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What's a thingumywut?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Teach me to be a mighty and powerful wizard."); + stage = 20; + break; + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "A thingummywut? Where? Where?"); + stage = 11; + break; + case 11: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Those pesky thingummywuts. They get everywhere.", "They leave a terrible mess too."); + stage = 12; + break; + case 12: + interpreter.sendOptions("Select an Option", "Err you just called me a thingymummywut.", "Tell me what they look like and I'll mask 'em."); + stage = 13; + break; + case 13: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Err you just called me thingummywut."); + stage = 100; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Tell me what they look like and I'll mash 'em."); + stage = 120; + break; + } + break; + case 120: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Don't be ridiculous. No-one has ever seen one."); + stage = 121; + break; + case 121: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "They're invisible, or a myth, or a figment of my", "imagination. Can't remember which right now."); + stage = 122; + break; + case 122: + end(); + break; + case 100: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "You're a thingummywut? I've never seen one up close", "before. They said I was mad!"); + stage = 101; + break; + case 101: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Now you are my proof! There ARE thingummywuts in", "this tower. Now where can I find a cage big enough to", "keep you?"); + stage = 102; + break; + case 102: + interpreter.sendOptions("Select an Option", "Err I'd better be off really.", "They're right, you are mad."); + stage = 103; + break; + case 103: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Err I'd better be off really."); + stage = 110; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "They're right, you are mad."); + stage = 130; + break; + } + break; + case 130: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "That's a pity. I thought maybe they were winding me", "up."); + stage = 131; + break; + case 131: + end(); + break; + case 110: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Oh ok, have a good time, and watch out for sheep!", "They're more cunning than they look."); + stage = 111; + break; + case 111: + end(); + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Wizard eh? You don't want any truck with that sort.", "They're not to be trusted. That's what I've heard", "anyways."); + stage = 21; + break; + case 21: + interpreter.sendOptions("Select an Option", "So aren't you a wizard?", "Oh I'd better stop talking to you then."); + stage = 22; + break; + case 22: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "So aren't you a wizard?"); + stage = 40; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Oh I'd better stop talking to you then."); + stage = 60; + break; + } + break; + case 60: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Cheerio then. It was nice chatting to you."); + stage = 61; + break; + case 61: + end(); + break; + case 40: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "How dare you? Of course I'm a wizard. Now don't be", "so cheeky or I'll turn you into a frog."); + stage = 41; + break; + case 41: + end(); + break; + } + } + + @Override + public int[] getIds() { + return new int[] { 881 }; + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/wiztower/handlers/DemonTauntHandler.kt b/Server/src/main/content/region/misthalin/wiztower/handlers/DemonTauntHandler.kt new file mode 100644 index 0000000..6b74064 --- /dev/null +++ b/Server/src/main/content/region/misthalin/wiztower/handlers/DemonTauntHandler.kt @@ -0,0 +1,29 @@ +package content.region.misthalin.wiztower.handlers + +import core.api.* +import core.game.node.entity.player.link.emote.Emotes +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +/** + * Handles taunting of the demon in the wizard's tower + * @author Ceikry + * @author vddCore + */ +class DemonTauntHandler : InteractionListener { + + override fun defineListeners() { + on(Scenery.RAILING_37668, IntType.SCENERY, "taunt-through") { player, _ -> + val demon = findLocalNPC(player, NPCs.LESSER_DEMON_82) ?: return@on true + forceWalk(demon, player.location, "smart") + face(player, demon, 3) + sendMessage(player, "You taunt the demon, making it growl.") + sendChat(demon, "Graaaagh!") + face(demon, player, 3) + emote(player, Emotes.RASPBERRY) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/wiztower/handlers/TalismanMapInterface.kt b/Server/src/main/content/region/misthalin/wiztower/handlers/TalismanMapInterface.kt new file mode 100644 index 0000000..b97893d --- /dev/null +++ b/Server/src/main/content/region/misthalin/wiztower/handlers/TalismanMapInterface.kt @@ -0,0 +1,21 @@ +package content.region.misthalin.wiztower.handlers + +import core.api.* +import core.game.interaction.InteractionListener +import org.rs09.consts.Scenery +import org.rs09.consts.Components + +// http://youtu.be/T62dugdfzSQ +/** Map for talismans in Wizard Tower basement. I display everything, because let's be real, you can find this online... */ +class TalismanMapInterface : InteractionListener { + override fun defineListeners() { + on(intArrayOf(Scenery.MAP_38421, Scenery.MAP_38422), SCENERY, "study") { player, node -> + openInterface(player, Components.RCGUILD_MAP_780) + // Air talisman to Death talisman + for(i in 35..48) { + setComponentVisibility(player, Components.RCGUILD_MAP_780, i, false) + } + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/wiztower/handlers/WizardGuildPortals.kt b/Server/src/main/content/region/misthalin/wiztower/handlers/WizardGuildPortals.kt new file mode 100644 index 0000000..e6c5a0b --- /dev/null +++ b/Server/src/main/content/region/misthalin/wiztower/handlers/WizardGuildPortals.kt @@ -0,0 +1,36 @@ +package content.region.misthalin.wiztower.handlers + +import core.api.* +import core.game.world.map.Location +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +class WizardGuildPortals : InteractionListener { + + val WTOWER_PORTAL = 2156 + val DWTOWER_PORTAL = 2157 + val SORC_TOWER_PORTAL = 2158 + + override fun defineListeners() { + on(WTOWER_PORTAL, IntType.SCENERY, "enter"){ player, _ -> + teleport(player, Location.create(3109, 3159, 0)) + sendMessage(player, "You enter the magic portal...") + sendMessage(player, "You teleport to the Wizards' tower.") + return@on true + } + + on(DWTOWER_PORTAL, IntType.SCENERY, "enter"){ player, _ -> + teleport(player, Location.create(2907, 3333, 0)) + sendMessage(player, "You enter the magic portal...") + sendMessage(player, "You teleport to the Dark Wizards' tower.") + return@on true + } + + on(SORC_TOWER_PORTAL, IntType.SCENERY, "enter"){ player, _ -> + teleport(player, Location.create(2703, 3406, 0)) + sendMessage(player, "You enter the magic portal...") + sendMessage(player, "You teleport to Thormac the Sorceror's house.") + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/misthalin/wiztower/handlers/WizardTowerPlugin.java b/Server/src/main/content/region/misthalin/wiztower/handlers/WizardTowerPlugin.java new file mode 100644 index 0000000..01b970f --- /dev/null +++ b/Server/src/main/content/region/misthalin/wiztower/handlers/WizardTowerPlugin.java @@ -0,0 +1,1786 @@ +package content.region.misthalin.wiztower.handlers; + +import static core.api.ContentAPIKt.*; +import core.cache.def.impl.NPCDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.game.component.Component; +import core.game.dialogue.DialoguePlugin; +import core.game.global.Skillcape; +import core.game.global.action.ClimbActionHandler; +import core.game.global.action.DoorActionHandler; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.combat.spell.CombatSpell; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.entity.skill.Skills; +import core.game.node.item.GroundItem; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.system.task.Pulse; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.net.packet.PacketRepository; +import core.net.packet.context.ChildPositionContext; +import core.net.packet.out.RepositionChild; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.tools.RandomFunction; +import core.tools.StringUtils; +import kotlin.Unit; +import content.global.travel.EssenceTeleport; +import core.game.world.GameWorld; +import core.plugin.ClassScanner; +import content.data.Quests; + +/** + * Represents the plugins used related to the wizard tower. + * + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class WizardTowerPlugin extends OptionHandler { + + /** + * Represents the location of the wizard tower. + */ + private static final Location BASEMENT = new Location(3104, 9576, 0); + + /** + * Represents the location of the ground floor. + */ + private static final Location GROUND_FLOOR = new Location(3105, 3162, 0); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(12540).getHandlers().put("option:search", this); + SceneryDefinition.forId(12539).getHandlers().put("option:search", this); + SceneryDefinition.forId(2147).getHandlers().put("option:climb-down", this); + SceneryDefinition.forId(32015).getHandlers().put("option:climb-up", this); + NPCDefinition.forId(300).getHandlers().put("option:teleport", this); + SceneryDefinition.forId(11993).getHandlers().put("option:open", this); + ClassScanner.definePlugin(new WizardtowerWizardNPC()); + ClassScanner.definePlugin(new WizardTowerDialogue()); + ClassScanner.definePlugin(new WizardMizgogDialogue()); + ClassScanner.definePlugin(new WizardGrayzagDialogue()); + ClassScanner.definePlugin(new WizardDialogue()); + ClassScanner.definePlugin(new SedridorDialogue()); + ClassScanner.definePlugin(new AuburyDialoguePlugin()); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + switch (option) { + case "teleport": + if (!player.getQuestRepository().isComplete(Quests.RUNE_MYSTERIES)) { + player.getPacketDispatch().sendMessage("You need to have completed the Rune Mysteries Quest to use this feature."); + return true; + } + EssenceTeleport.teleport(((NPC) node), player); + break; + case "climb-down": + player.getProperties().setTeleportLocation(BASEMENT); + break; + case "climb-up": + if (node.getLocation().equals(new Location(3017, 10249))) { + ClimbActionHandler.climb(player, new Animation(828), new Location(3069, 3857, 0)); + return true; + } + if (node.getLocation().equals(new Location(3069, 10256))) { + ClimbActionHandler.climb(player, new Animation(828), new Location(3017, 3850, 0)); + return true; + } + if (player.getLocation().withinDistance(Location.create(3117, 9753, 0))) { + ClimbActionHandler.climb(player, new Animation(828), new Location(3092, 3361, 0)); + return true; + } + if (!Location.create(3103, 9576, 0).equals(((Scenery) node).getLocation())) { + return SceneryDefinition.getOptionHandler(2147, "climb-up").handle(player, node, option); + } + player.getProperties().setTeleportLocation(GROUND_FLOOR); + break; + case "search": + player.getDialogueInterpreter().open(458543948); + break; + case "open": + if (node.getLocation().equals(new Location(3107, 3162, 0))) { + DoorActionHandler.handleAutowalkDoor(player, (Scenery) node, player.getLocation().getX() >= 3107 ? Location.create(3106, 3161, 0) : Location.create(3108, 3163, 0)); + } else { + DoorActionHandler.handleDoor(player, (Scenery) node); + } + break; + } + return true; + } + + @Override + public Location getDestination(Node node, Node n) { + if (n instanceof Scenery) { + final Scenery object = (Scenery) n; + if (object.getId() == 11993 && object.getLocation().equals(new Location(3107, 3162, 0))) { + return node.getLocation().getX() >= 3107 ? Location.create(3108, 3163, 0) : Location.create(3106, 3161, 0); + } + } + return null; + } + + /** + * Represents a wizard at the wizard tower. + * + * @author 'Vexia + * @version 1.0 + */ + public static final class WizardtowerWizardNPC extends AbstractNPC { + + /** + * The NPC ids of NPCs using this plugin. + */ + private static final int[] ID = {13}; + + /** + * Constructs a new {@code WizardtowerWizardNPC} {@code Object}. + */ + public WizardtowerWizardNPC() { + super(0, null); + } + + /** + * Constructs a new {@code AlKharidWarriorPlugin} {@code Object}. + * + * @param id The NPC id. + * @param location The location. + */ + private WizardtowerWizardNPC(int id, Location location) { + super(id, location); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new WizardtowerWizardNPC(id, location); + } + + @Override + public void init() { + super.init(); + getProperties().getCombatPulse().setStyle(CombatStyle.MAGIC); + getProperties().setAutocastSpell((CombatSpell) SpellBook.MODERN.getSpell(8)); + } + + @Override + public int[] getIds() { + return ID; + } + + } + + /** + * Represents the dialogue used in the wizard tower. + * + * @author 'Vexia + * @version 1.0 + */ + public final class WizardTowerDialogue extends DialoguePlugin { + + /** + * Represents the book name to use. + */ + private String bookName = ""; + + /** + * Represents the book names. + */ + private final String[] books = new String[]{"Living with a Wizard Husband - a Housewife's Story", "Wind Strike for Beginners", "So you think you're a Mage? Volume 28", "101 Ways to Impress your Mates with Magic", "The Life & Times of a Thingummywut by Traiborn the Wizard", "How to become the Ulitmate Wizard of the Universe", "The Dark Arts of Magical Wands"}; + + /** + * Constructs a new {@code WizardTowerDialogue.java} {@code Object}. + */ + public WizardTowerDialogue() { + } + + /** + * Constructs a new {@code WizardTowerDialogue.java} {@code Object}. + * + * @param player the player. + */ + public WizardTowerDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new WizardTowerDialogue(player); + } + + @Override + public boolean open(Object... args) { + sendDialogue("There's a large selection of books, the majority of which look fairly", "old. Some very strange names... You pick one at random :"); + bookName = books[RandomFunction.random(books.length)]; + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + sendDialogue("'" + bookName + "'"); + stage = 1; + break; + case 1: + sendDialogue("Interesting..."); + stage = 2; + break; + case 2: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[]{458543948}; + } + } + + /** + * Handles the WizardMizgogDialogue dialogue. + * + * @author 'Vexia + * @version 1.0 + */ + public static final class WizardMizgogDialogue extends DialoguePlugin { + + /** + * Represents the black bead item. + */ + private static final Item BLACK_BEAD = new Item(1474); + + /** + * Represents the red bead item. + */ + private static final Item RED_BEAD = new Item(1470); + + /** + * Represents the white bead item. + */ + private static final Item WHITE_BEAD = new Item(1476); + + /** + * Represents the yellow bead item. + */ + private static final Item YELLOW_BEAD = new Item(1472); + + /** + * Represents the animation. + */ + private static final Animation ANIMATION = new Animation(4285); + + /** + * Constructs a new {@code WizardMizgogDialogue} {@code Object}. + */ + public WizardMizgogDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code WizardMizgogDialogue} {@code Object}. + * + * @param player the player. + */ + public WizardMizgogDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new WizardMizgogDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + Quest quest = player.getQuestRepository().getQuest(Quests.IMP_CATCHER); + switch (quest.getStage(player)) { + case 0: + player("Give me a quest!"); + stage = 0; + break; + case 10: + npc("So how are you doing finding my beads?"); + stage = 0; + break; + case 100: + options("Got any more quests?", "Do you know any interesting spells you could teach me?"); + stage = 0; + break; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + final Quest quest = player.getQuestRepository().getQuest(Quests.IMP_CATCHER); + switch (quest.getStage(player)) { + case 0: + switch (stage) { + case 0: + npc("Give me a quest what?"); + stage = 1; + break; + case 1: + options("Give me a quest please.", "Give me a quest or else!", "Just stop messing around and give me a quest!"); + stage = 2; + break; + case 2: + switch (buttonId) { + case 1: + player("Give me a quest please."); + stage = 10; + break; + case 2: + player("Give me a quest or else!"); + stage = 20; + break; + case 3: + player("Just stop messing around and give me a quest!"); + stage = 30; + break; + } + break; + case 10: + npc("Well seeing as you asked nicely... I could do with some", "help."); + stage = 11; + break; + case 11: + npc("The wizard Grayzag next door decided he didn't like", "me so he enlisted an army of hundreds of imps."); + stage = 12; + break; + case 12: + npc("The imps stole all sorts of my things. Most of these", "things I don't really care about, just eggs and balls of", "string and things."); + stage = 13; + break; + case 13: + npc("But they stole my four magical beads. There was a red", "one, a yellow one, a black one, and a white one."); + stage = 14; + break; + case 14: + npc("These imps have now spread out all over the kingdom.", "Could you get my beads back for me?"); + stage = 15; + break; + case 15: + options("I'll try", "I've better things to do than chase imps."); + stage = 16; + break; + case 16: + switch (buttonId) { + case 1: + player("I'll try."); + stage = 17; + break; + case 2: + player("I've better things to do than chase imps."); + stage = 18; + break; + } + break; + case 17: + npc("That's great, thank you."); + stage = 19; + break; + case 19: + quest.start(player); + player.getQuestRepository().syncronizeTab(player); + end(); + break; + case 18: + end(); + break; + case 20: + npc("Or else what? You'll attack me?"); + stage = 21; + break; + case 21: + npc("Hahaha!"); + stage = 22; + break; + case 22: + end(); + break; + case 30: + npc("Ah now you're assuming I have one to give."); + stage = 31; + break; + case 31: + end(); + break; + } + break; + case 10: + switch (stage) { + case 0: + if (player.getInventory().containItems(BLACK_BEAD.getId(), RED_BEAD.getId(), YELLOW_BEAD.getId(), WHITE_BEAD.getId())) { + player("I've got all four beads. It was hard work I can tell you."); + stage = 5; + break; + } + if (!player.getInventory().containsItem(WHITE_BEAD) && !player.getInventory().containsItem(RED_BEAD) && !player.getInventory().containsItem(YELLOW_BEAD) && !player.getInventory().containsItem(BLACK_BEAD)) { + player("I've not found any yet."); + stage = 1; + } else { + player("I have found some of your beads."); + stage = 3; + } + break; + case 1: + npc("Well get on with it. I've lost a white bead, a read bead, a", "black bead, and a yellow bead. Go kill some imps!"); + stage = 2; + break; + case 2: + end(); + break; + case 3: + npc("Come back when you have them all. The colour of the", "four beads that I need are red, yellow, black, and white.", "Go chase some imps!"); + stage = 4; + break; + case 4: + end(); + break; + case 5: + npc("Give them here and I'll check that they really are MY", "beads, before I give you your reward. You'll like it, it's", "an amulet of accuracy."); + stage = 6; + break; + case 6: + sendDialogue("You give four coloured beads to Wizard Mizgog."); + stage = 7; + break; + case 7: + end(); + if (player.getInventory().remove(BLACK_BEAD, WHITE_BEAD, RED_BEAD, YELLOW_BEAD)) { + player.lock(7); + npc.faceLocation(Location.create(3102, 3163, 2)); + npc.animate(ANIMATION); + GameWorld.getPulser().submit(new Pulse(3, player) { + @Override + public boolean pulse() { + quest.finish(player); + player.getQuestRepository().syncronizeTab(player); + return true; + } + + }); + } + break; + } + break; + case 100: + switch (stage) { + case 0: + switch (buttonId) { + case 1: + player("Got any more quests?"); + stage = 10; + break; + case 2: + player("Do you know any interesting spells you could teach me?"); + stage = 20; + break; + } + break; + case 10: + npc("No, everything is good with the world today."); + stage = 11; + break; + case 11: + end(); + break; + case 20: + npc("I don't think so, the type of magic I study involves", "years of meditation and research."); + stage = 11; + break; + } + } + return true; + } + + @Override + public int[] getIds() { + return new int[]{706}; + } + } + + /** + * Handles the WizardGrayzagDialogue dialogue. + * + * @author 'Vexia + * @version 1.0 + */ + public final class WizardGrayzagDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code WizardGrayzagDialogue} {@code Object}. + */ + public WizardGrayzagDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code WizardGrayzagDialogue} {@code Object}. + * + * @param player the player. + */ + public WizardGrayzagDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new WizardGrayzagDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + npc("Not now, I'm trying to concentrate on a", "very difficult spell!"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[]{707}; + } + } + + /** + * Handles the WizardDialogue dialogue. + * + * @author 'Vexia + * @version 1.0 + */ + public static final class WizardDialogue extends DialoguePlugin { + + /** + * Represents the bark item used to make split bark equipment. + */ + private static final Item BARK = new Item(3239); + + /** + * Constructs a new {@code WizardDialogue} {@code Object}. + */ + public WizardDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code WizardDialogue.java} {@code Object}. + * + * @param player the player. + */ + public WizardDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new WizardDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + npc("Hello there, can I help you?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + options("What do you do here?", "What's that you're wearing?", "Can you make me some armour please?", "No thanks."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + player("What do you do here?"); + stage = 10; + break; + case 2: + player("What's that you're wearing?"); + stage = 20; + break; + case 3: + player("Can you make me some armour please?"); + stage = 30; + break; + case 4: + player("No thanks."); + stage = 40; + break; + } + break; + case 30: + npc("Certainly, what would like to me to make?"); + stage = 31; + break; + case 31: + player.getInterfaceManager().openChatbox(new Component(306)); + int count = 2; + int shift = 75; + PacketRepository.send(RepositionChild.class, new ChildPositionContext(player, 306, 26, 10, shift)); + PacketRepository.send(RepositionChild.class, new ChildPositionContext(player, 306, 22, 88, shift)); + PacketRepository.send(RepositionChild.class, new ChildPositionContext(player, 306, 18, 288, shift)); + PacketRepository.send(RepositionChild.class, new ChildPositionContext(player, 306, 14, 188, shift + 5)); + PacketRepository.send(RepositionChild.class, new ChildPositionContext(player, 306, 10, 380, shift)); + int indexes[] = new int[]{26, 22, 14, 18, 10}; + for (SplitBark bark : SplitBark.values()) { + player.getPacketDispatch().sendItemZoomOnInterface(bark.itemId, 170, 306, count); + player.getPacketDispatch().sendString(StringUtils.formatDisplayName(bark.name()), 306, indexes[bark.ordinal()]); + count++; + } + stage = 32; + break; + case 32: + final SplitBark bark = SplitBark.forButton(buttonId); + if (bark == null) { + end(); + return true; + } + + if (!player.getInventory().contains(BARK.getId(), bark.getAmt())) { + String name = bark == SplitBark.HELM ? "a splitbark helm" : bark == SplitBark.BODY ? "a splitbark body" : bark == SplitBark.BOOTS ? "splitbark boots" : bark == SplitBark.GAUNTLETS ? "splitbark gauntlets" : "splitbark legs"; + npc("You need " + bark.getAmt() + " pieces of bark for " + name + "."); + return true; + } + final int amount = getAmt(buttonId); + if (amount == -1) {// rscript. + sendInputDialogue(player, true, "Enter the amount:", (value) -> { + make(bark, (int) value); + return Unit.INSTANCE; + }); + return true; + } + make(bark, amount); + break; + case 33: + end(); + break; + case 20: + npc("Split-bark armour is special armour for mages, it's much", "more resistant to physical attacks than normal robes.", "It's actually very easy for me to make, but I've been", "having trouble getting hold of the pieces."); + stage = 14; + break; + case 10: + npc("I've been studying the practice of making split-bark", "armour."); + stage = 11; + break; + case 11: + options("Split-bark armour, what's that?", "Can you make me some?"); + stage = 12; + break; + case 12: + switch (buttonId) { + case 1: + player("Split-bark armour, what's that?"); + stage = 13; + break; + case 2: + player("Can you make me some?"); + stage = 9000; + break; + } + break; + case 13: + npc("Split-bark armour is special armour for mages, it's much", "more resistant to physical attacks than normal robes.", "It's actually very easy for me to make, but I've been", "having trouble getting hold of the pieces."); + stage = 14; + break; + case 14: + options("Well good luck with that.", "Can you make me some?"); + stage = 15; + break; + case 15: + switch (buttonId) { + case 1: + player("Well good luck with that."); + stage = 16; + break; + case 2: + player("Can you make me some?"); + stage = 9000; + break; + } + break; + case 16: + end(); + break; + case 9000: + npc("I need bark from a hollow tree, and some fine cloth.", "Unfortunately both these items can be found in", "Morytania, especially the cloth which is found in the", "tombs of shades."); + stage = 9001; + break; + case 9001: + npc("Of course I'd happily sell you some at a discounted", "price if you bring me those items."); + stage = 9002; + break; + case 9002: + options("Ok, guess I'll go looking then!", "Ok, how much do I need?"); + stage = 9003; + break; + case 9003: + switch (buttonId) { + case 1: + player("Ok, guess I'll go looking then!"); + stage = 9004; + break; + case 2: + player("Ok, how much do I need?"); + stage = 9005; + break; + } + break; + case 9004: + end(); + break; + case 9005: + npc("1 need 1 piece of each for either gloves or boots,", "2 pieces of each for a hat,", "3 pieces of each for leggings,", "and 4 pieces of each for a top."); + stage = 9006; + break; + case 9006: + npc("I'll charge you 1,000 coins for either gloves or boots,", "6,000 coins for a hat", "32,000 coins for leggings,", "and 37,000 for a top."); + stage = 9007; + break; + case 9007: + player("Ok, guess I'll go looking then!"); + stage = 9008; + break; + case 9008: + end(); + break; + case 40: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[]{1263}; + } + + /** + * Method used to make split bark. + * + * @param bark the bark. + * @param amount the amount. + */ + public final void make(final SplitBark bark, int amount) { + final int barkAmt = player.getInventory().getAmount(BARK); + if (barkAmt < amount * bark.getAmt()) { + npc("You don't have enough bark to make that many."); + stage = 33; + return; + } + if (amount < 1) { + end(); + return; + } + if (player.getInventory().freeSlots() < amount) { + player("Sorry, I don't seem to have enough inventory space."); + stage = 33; + return; + } + if (!player.getInventory().contains(995, bark.getCost() * amount)) { + player("Sorry, I don't seem to have enough coins."); + stage = 33; + return; + } + final Item money = new Item(995, bark.getCost() * amount); + final Item barkRemove = new Item(BARK.getId(), amount * bark.getAmt()); + if (player.getInventory().remove(money) && player.getInventory().remove(barkRemove)) { + player.getInventory().add(new Item(bark.getItemId(), amount)); + npc("There you go, enjoy your new armour!"); + return; + } + end(); + } + + /** + * Method used to get the amount to make. + * + * @param buttonId the button id. + * @return the amt. + */ + public final int getAmt(final int buttonId) { + int amount = -1; + switch (buttonId) { + case 10: + case 14: + case 18: + case 22: + case 26: + amount = 1; + break; + case 9: + case 13: + case 17: + case 21: + case 25: + amount = 5; + break; + case 8: + case 12: + case 16: + case 20: + case 24: + amount = 10; + break; + case 7: + case 11: + case 15: + case 19: + case 23: + amount = -1; + break; + } + return amount; + } + + /** + * Represents the split bark item info. + * + * @author 'Vexia + * @date 21/11/2013 + */ + public enum SplitBark { + HELM(3385, 6000, 2, 9), BODY(3387, 37000, 4, 13), LEGS(3389, 32000, 3, 17), GAUNTLETS(3391, 1000, 1, 21), BOOTS(3393, 1000, 1, 25); + + /** + * Constructs a new {@code WizardDialogue.java} {@code Object}. + * + * @param itemId the item id. + * @param cost the cost. + * @param buttonId the button id. + */ + SplitBark(final int itemId, final int cost, final int amt, final int buttonId) { + this.itemId = itemId; + this.cost = cost; + this.amt = amt; + this.buttonId = buttonId; + } + + /** + * Represents the item to give. + */ + private final int itemId; + + /** + * Represents the cost of the item. + */ + private final int cost; + + /** + * Represents the needed amt. + */ + private final int amt; + + /** + * Represents the button id. + */ + private final int buttonId; + + /** + * Gets the itemId. + * + * @return The itemId. + */ + public int getItemId() { + return itemId; + } + + /** + * Gets the cost. + * + * @return The cost. + */ + public int getCost() { + return cost; + } + + /** + * Gets the buttonId. + * + * @return The buttonId. + */ + public int getButtonId() { + return buttonId; + } + + /** + * Method used to get the splitbark armour. + * + * @return the split bark. + */ + public static SplitBark forButton(final int buttonId) { + SplitBark bark = null; + if (buttonId >= 7 && buttonId <= 10) { + bark = HELM; + } + if (buttonId >= 11 && buttonId <= 14) { + bark = BODY; + } + if (buttonId >= 15 && buttonId <= 18) { + bark = LEGS; + } + if (buttonId >= 19 && buttonId <= 22) { + bark = GAUNTLETS; + } + if (buttonId >= 23 && buttonId <= 26) { + bark = BOOTS; + } + if (buttonId == 26) { + bark = HELM; + } + return bark; + } + + /** + * Gets the amt. + * + * @return The amt. + */ + public int getAmt() { + return amt; + } + } + } + + /** + * Handles the SedridorDialogue dialogue. + * + * @author 'Vexia + * @version 1.0 + */ + public final static class SedridorDialogue extends DialoguePlugin { + + /** + * Represents the talisman item. + */ + private static final Item TALISMAN = new Item(1438); + + /** + * Represents the package item. + */ + private static final Item PACKAGE = new Item(290); + + /** + * Represents the notes item. + */ + private static final Item NOTES = new Item(291); + + /** + * Represents the graphic to use. + */ + private static final Graphics GRAPHIC = new Graphics(6); + + /** + * Constructs a new {@code SedridorDialogue} {@code Object}. + */ + public SedridorDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code SedridorDialogue} {@code Object}. + * + * @param player the player. + */ + public SedridorDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new SedridorDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + npc("Welcome adventurer, to the world renowned", "Wizards' Tower. How may I help you?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + final Quest quest = player.getQuestRepository().getQuest(Quests.RUNE_MYSTERIES); + switch (stage) { + case 0: + if (quest.getStage(player) == 100) { + player("Hello there."); + stage = 400; + return true; + } + if (quest.getStage(player) == 10) { + options("Nothing thanks, I'm just looking around.", "What are you doing down here?", "I'm looking for the head wizard."); + stage = 1000; + return true; + } + if (quest.getStage(player) == 20) { + npc("Wow! This is... incredible!"); + stage = 52; + return true; + } + if (quest.getStage(player) == 30) { + npc("Ah, " + player.getUsername() + ". How goes your quest? Have you", "delivered the research notes to my friend Aubury yet?"); + stage = 800; + return true; + } + if (quest.getStage(player) == 50) { + npc("Ah, " + player.getUsername() + ". How goes your quest? Have you", "delivered the research notes to my friend Aubury yet?"); + stage = 900; + return true; + } + options("Nothing thanks, I'm just looking around.", "What are you doing down here?"); + stage = 1; + break; + case 400: + npc("Hello again " + player.getUsername() + ". What can I do for you?"); + stage = 401; + break; + case 401: + options("Nothing thanks, I'm just looking around.", "Can you teleport me to the Rune Essence?"); + stage = 402; + break; + case 402: + switch (buttonId) { + case 1: + player("Nothing thanks, I'm just looking around."); + stage = 403; + break; + case 2: + player("Can you teleport me to the Rune Essence?"); + stage = 405; + break; + } + break; + case 403: + npc("Well, take care adventurer. You stand on the", "ruins of the old destroyed Wizards' Tower.", "Strange and powerful magicks lurk here,"); + stage = 404; + break; + case 404: + end(); + break; + case 405: + end(); + EssenceTeleport.teleport(npc, player); + player.getAchievementDiaryManager().finishTask(player, DiaryType.LUMBRIDGE, 1, 14); + break; + case 900: + player("Yes, I have. He gave me some research notes", "to pass on to you."); + stage = 901; + break; + case 901: + npc("May I have his notes then?"); + stage = 902; + break; + case 902: + if (!player.getInventory().containsItem(NOTES)) { + player("Uh... I kind of... lost them..."); + stage = 903; + break; + } + player("Sure. I have them here."); + stage = 905; + break; + case 905: + npc("Well, before you hand them over to me, as you", "have been nothing but truthful with me to this point,", "and I admire that in an adventurer, I will let you", "into the secret of our research."); + stage = 906; + break; + case 906: + npc("Now as you may or may not know, many", "centuries ago, the wizards at this Tower", "learnt the secret of creating Rune Stones, which", "allowed us to cast Magic very easily."); + stage = 907; + break; + case 907: + npc("When this Tower was burnt down the secret of", "creating runes was lost to us for all time... except it", "wasn't. Some months ago, while searching these ruins", "for information from the old days,"); + stage = 908; + break; + case 908: + npc("I came upon a scroll, almost destroyed, that detailed a", "magical rock deep in the icefields of the North, closed", "off from access by anything other than magical means."); + stage = 909; + break; + case 909: + npc("This rock was called the 'Rune Essence' by the", "magicians who studied its power. Apparently, by simply", "breaking a chunk from it, a Rune Stone could be", "fashioned very quickly and easily at certain"); + stage = 910; + break; + case 910: + npc("elemental altars that were scattered across the land", "back then. Now, this is an interesting little piece of", "history, but not much use to us as modern wizards", "without access to the Rune Essence,"); + stage = 911; + break; + case 911: + npc("or these elemental altars. This is where you and", "Aubury come into this story. A few weeks back,", "Aubury discovered in a standard delivery of runes", "to his store, a parchment detailing a"); + stage = 912; + break; + case 912: + npc("teleportation spell that he had never come across", "before. To his shock, when cast it took him to a", "strange rock he had never encountered before...", "yet that he felt strangely famliar..."); + stage = 913; + break; + case 913: + npc("As I'm sure you have now guessed, he had discovered a", "portal leading to the mythical Rune Essence. As soon as", "he told me of this spell, I saw the importance of his find,"); + stage = 914; + break; + case 914: + npc("for it we could but find the elemental altars spoken", "of in the ancient texts, we would once more be able", "to create runes as our ancestors had done! It would", "be the saviour of the wizards' art!"); + stage = 915; + break; + case 915: + player("I'm still not sure how I fit into", "this little story of yours..."); + stage = 916; + break; + case 916: + npc("You haven't guessed? This talisman you brought me...", "it is the key to the elemental altar of air! When", "you hold it next, it will direct you towards"); + stage = 917; + break; + case 917: + npc("the entrance to the long forgotten Air Altar! By", "bringing pieces of the Rune Essence to the Air Temple,", "you will be able to fashion your own Air Runes!"); + stage = 918; + break; + case 918: + npc("And this is not all! By finding other talismans similar", "to this one, you will eventually be able to craft every", "rune that is available on this world! Just"); + stage = 919; + break; + case 919: + npc("as our ancestors did! I cannot stress enough what a", "find this is! Now, due to the risks involved of letting", "this mighty power fall into the wrong hands"); + stage = 920; + break; + case 920: + npc("I will keep the teleport skill to the Rune Essence", "a closely guarded secret, shared only by myself", "and those Magic users around the world", "whom I trust enough to keep it."); + stage = 921; + break; + case 921: + npc("This means that if any evil power should discover", "the talismans required to enter the elemental", "temples, we will be able to prevent their access", "to the Rune Essence and prevent"); + stage = 922; + break; + case 922: + npc("tragedy befalling this world. I know not where the", "temples are located, nor do I know where the talismans", "have been scattered to in this land, but I now"); + stage = 923; + break; + case 923: + npc("return your Air Talisman to you. Find the Air", "Temple, and you will be able to charge your Rune", "Essences to become Air Runes at will. Any time"); + stage = 924; + break; + case 924: + npc("you wish to visit the Rune Essence, speak to me", "or Aubury and we will open a portal to that", "mystical place for you to visit."); + stage = 925; + break; + case 925: + player("So only you and Aubury know the teleport", "spell to the Rune Essence?"); + stage = 926; + break; + case 926: + npc("No... there are others... whom I will tell of your", "authorisation to visit that place. When you speak", "to them, they will know you, and grant you", "access to that place when asked."); + stage = 927; + break; + case 927: + npc("Use the Air Talisman to locate the air temple,", "and use any further talismans you find to locate", "the other missing elemental temples.", "Now... my research notes please?"); + stage = 928; + break; + case 928: + sendDialogue("You hand the head wizard the research notes.", "He hands you back the Air Talisman."); + stage = 929; + break; + case 929: + if (player.getInventory().remove(NOTES)) { + if (!player.getInventory().add(TALISMAN)) { + GroundItemManager.create(new GroundItem(TALISMAN, player.getLocation(), player)); + } + quest.finish(player); + player.getQuestRepository().syncronizeTab(player); + } + end(); + break; + case 903: + npc("You did? You are extremely careless aren't you? I", "suggest you go and speak to Aubury once more, with", "luck he will have made copies of his research."); + stage = 904; + break; + case 904: + end(); + break; + case 800: + player("Not yet..."); + stage = 801; + break; + case 801: + if (!player.getInventory().containsItem(PACKAGE) && !player.getBank().containsItem(PACKAGE)) { + player("...I lost the package you gave me."); + stage = 804; + return true; + } + npc("Well, please do so as soon as possible. Remember: to get", "to Varrock, head due North, through Draynor Village,", "around Draynor Manor, and then head East when"); + stage = 802; + break; + case 802: + npc("you get to the Barbarian village. The man you seek", "is named Aubury, and he owns the rune shop there.", "It is vital he receives this package."); + stage = 803; + break; + case 803: + end(); + break; + case 804: + npc("You WHAT?"); + stage = 805; + break; + case 805: + npc("Tch, that was really very careless of you. Luckily as", "head wizard I have great powers, and will be able to", "teleport it back here without too much effort."); + stage = 806; + break; + case 806: + close(); + npc.graphics(GRAPHIC); + player.lock(3); + GameWorld.getPulser().submit(new Pulse(2) { + @Override + public boolean pulse() { + npc("Ok, I have retrieved it. Luckily it doesn't appear to", "have been damaged. Now please take it to Aubury, ", "and try not to lose it again."); + stage = 807; + return true; + } + }); + break; + case 807: + if (!player.getInventory().add(PACKAGE)) { + GroundItemManager.create(new GroundItem(PACKAGE, player.getLocation(), player)); + } + end(); + break; + case 1000: + switch (buttonId) { + case 1: + player("Nothing thanks, I'm just looking around."); + stage = 10; + break; + case 2: + player("What are you doing down here?"); + stage = 20; + break; + case 3: + player("I'm looking for the head wizard."); + stage = 30; + break; + } + break; + case 30: + npc("Oh, you are, are you?", "And just why would you be doing that?"); + stage = 31; + break; + case 31: + player("The Duke of Lumbridge sent me to find him. I have", "this weird talisman he found. He said the head wizard", "would be very interested in it."); + stage = 32; + break; + case 32:// ...except I don't have it with me..." + npc("Did he now? HmmmMMMMMmmmmm.", "Well that IS interesting. Hand it over then adventurer,", "let me see what all the hubbub about it is.", "Just come amulet I'll wager."); + stage = 33; + break; + case 33: + options("Ok, here you are.", "No, I'll only give it to the head wizard."); + stage = 34; + break; + case 34: + switch (buttonId) { + case 1: + player("Ok, here you are."); + stage = 50; + break; + case 2: + player("No, I'll only give it to the head wizard."); + stage = 40; + break; + } + break; + case 50: + if (!player.getInventory().containsItem(TALISMAN)) { + player("...except I don't have it with me..."); + stage = 99; + break; + } + sendDialogue("You hand the Talisman to the wizard."); + stage = 51; + break; + case 51: + if (player.getInventory().remove(TALISMAN)) { + quest.setStage(player, 20); + npc("Wow! This is... incredible!"); + stage = 52; + } + break; + case 52: + npc("Th-this talisman you brought me...! It is the last piece", "of the puzzle, I think! Finally! The legacy of our", "ancestors... it will return to us once more!"); + stage = 53; + break; + case 53: + npc("I need time to study this, " + player.getUsername() + ". Can you please", "do me this task while I study this talisman you have", "brought me? In the mighty town of Varrock, which"); + stage = 54; + break; + case 54: + npc("is located North East of here, there is a certain shop", "that sells magical runes. I have in this package all of the", "research I have done relating to the Rune Stones, and"); + stage = 55; + break; + case 55: + npc("require somebody to take them to the shopkeeper so that", "he may share my research and offer me his insights.", "Do this thing for me, and bring back what he gives you,"); + stage = 56; + break; + case 56: + npc("and if my suspicions are correct, I will let you into the", "knowledge of one of the greatest secrets this world has", "ever known! A secret so powerful that it destroyed the"); + stage = 57; + break; + case 57: + npc("original Wizards' Tower all of those centuries", "ago! My research, combined with this mysterious", "talisman... I cannot believe the answer", "the mysteries is so close now!"); + stage = 58; + break; + case 58: + npc("Do this thing for me " + player.getUsername() + ". Be rewarded in a", "way you can never imagine."); + stage = 59; + break; + case 59: + options("Yes, certainly.", "No, I'm busy."); + stage = 60; + break; + case 60: + switch (buttonId) { + case 1: + player("Yes, certainly."); + stage = 70; + break; + case 2: + player("No, I'm busy."); + stage = 61; + break; + } + break; + case 70: + npc("Take this package, and head directly North", "from here, through Draynor village, until you reach", "the Barbarian Village. Then head East from there", "until you reach Varrock."); + stage = 71; + break; + case 71: + npc("Once in Varrock, take this package to the owner of the", "rune shop. His name is Aubury. You may find it", "helpful to ask one of Varrock's citizens for directions,"); + stage = 72; + break; + case 72: + npc("as Varrock can be a confusing place for the first time", "visitor. He will give you a special item - bring it back to", "me, and I shall show you the mystery of the runes..."); + stage = 73; + break; + case 73: + sendDialogue("The head wizard gives you a package."); + stage = 74; + break; + case 74: + quest.setStage(player, 30); + npc("Best of luck with your quest, " + player.getUsername() + "."); + if (!player.getInventory().add(PACKAGE)) { + GroundItemManager.create(new GroundItem(PACKAGE, player.getLocation(), player)); + } + stage = 75; + break; + case 75: + end(); + break; + case 61: + npc("As you wish adventurer. I will continue to study this", "talisman you have brought me. Return here if you find", "yourself with some spare time to help me."); + stage = 62; + break; + case 62: + end(); + break; + case 99: + end(); + break; + case 40: + npc("HA HA HA HA HA! I can tell you are new to this", "land, for I AM the head wizard! Hand it over and", "let me have a proper look at it, hmmm?"); + stage = 41; + break; + case 41: + options("Ok, here you are.", "No, I'll only give it to the head wizard."); + stage = 34; + break; + case 1: + switch (buttonId) { + case 1: + player("Nothing thanks, I'm just looking around."); + stage = 10; + break; + case 2: + player("What are you doing down here?"); + stage = 20; + break; + } + break; + case 10: + npc("Well, take care adventurer. You stand on the", "ruins of the destroyed Wizards' Tower.", "Strange and powerful magicks lurk here."); + stage = 11; + break; + case 11: + end(); + break; + case 20: + npc("That is indeed a good question. Here in the cellar", "of the Wizards' Tower you find the remains of", "the old Wizards' Tower, destroyed by fire"); + stage = 21; + break; + case 21: + npc("many years past by the treachery of the Zamorakians.", "Many mytseries were lost, which we try to find once", "more. By building this tower on the remains of the old,"); + stage = 22; + break; + case 22: + npc("we sought to show the world of our dedication to", "learning the mysteries of Magic. I am here searching", "through these fragments for knowledge from", "the artefacts from our past."); + stage = 23; + break; + case 23: + player("And have you found anything useful?"); + stage = 24; + break; + case 24: + npc("Aaah... that would be telling adventurer. Anything I", "have found I cannot speak freely of, for fear the", "treachery of the past might be repeated."); + stage = 25; + break; + case 25: + player("Ok, well I'll leave you to it."); + stage = 26; + break; + case 26: + npc("Perhaphs I will see you later " + player.getUsername() + "."); + stage = 27; + break; + case 27: + player("How did you know my name???"); + stage = 28; + break; + case 28: + npc("Well, I AM the head wizard here..."); + stage = 29; + break; + case 29: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[]{300}; + } + } + + /** + * Represents the dialogue plugin used for aubury. + * + * @author 'Vexia + * @version 1.0 + */ + public static final class AuburyDialoguePlugin extends DialoguePlugin { + + /** + * Represents the package item. + */ + private static final Item PACKAGE = new Item(290); + + /** + * Represents the package item. + */ + private static final Item NOTES = new Item(291); + + /** + * The NPC ids that use this dialogue plugin. + */ + private static final int[] NPC_IDS = {553}; + + /** + * Constructs a new {@code AuburyDialoguePlugin} {@code Object}. + */ + public AuburyDialoguePlugin() { + /* + * empty. + */ + } + + public AuburyDialoguePlugin(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new AuburyDialoguePlugin(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + final Quest quest = player.getQuestRepository().getQuest(Quests.RUNE_MYSTERIES); + if (quest.getStage(player) == 40) { + npc("My gratitude to you adventurer for bringing me these", "research notes. I notice that you brought the head", "wizard a special talisman that was the key to our finally", "unlocking the puzzle."); + stage = 900; + return true; + } + if (Skillcape.isMaster(player, Skills.RUNECRAFTING)) { + options("Can I buy a Skillcape of Runecrafting?", "Something else"); + stage = 450; + } else { + npc("Do you want to buy some runes?"); + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + final Quest quest = player.getQuestRepository().getQuest(Quests.RUNE_MYSTERIES); + switch (stage) { + case 0: + if (quest.getStage(player) == 30) { + options("Yes please!", "Oh, it's a rune shop. No thank you, then.", "I have been sent here with a package for you."); + stage = 800; + return true; + } + if (quest.getStage(player) == 40) { + npc("My gratitude to you adventurer for bringing me these", "research notes. I notice that you brought the head", "wizard a speical talisman that was the key to our finally", "unlocking the puzzle."); + stage = 900; + return true; + } + if (quest.getStage(player) == 50) { + npc("I suggest you take those research notes of mine back", "to the head wizard at the Wizards' Tower."); + stage = 950; + return true; + } + if (!player.getQuestRepository().isComplete(Quests.RUNE_MYSTERIES)) { + options("Yes please!", "Oh, it's a rune shop. No thank you, then."); + stage = 100; + } else { + options("Yes, please.", "No thanks.", "Can you teleport me to the rune essence?"); + stage = 1; + } + break; + case 900:// quest + npc("Combined with the information I had already collated", "regarding the Rune Essence, I think we have finally", "unlocked the power to"); + stage = 901; + break; + case 901: + npc("...no. I am getting ahead of myself. Please take this", "summary of my research back to the head wizard at", "the Wizards' Tower. I trust his judgement on whether", "to let you in on our little secret or not."); + stage = 902; + break; + case 902: + quest.setStage(player, 50); + if (!player.getInventory().add(NOTES)) { + GroundItemManager.create(new GroundItem(NOTES, player.getLocation(), player)); + } + sendDialogue("Aubury gives you his research notes."); + stage = 903; + break; + case 903: + end(); + break; + case 950: + if (!player.getBank().containsItem(NOTES) && !player.getInventory().containsItem(NOTES)) { + player("I can't... I lost them..."); + stage = 955; + return true; + } + player("Ok then, I will do that."); + stage = 951; + break; + case 951: + npc("Unless you were talking to me because you wished to", "buy some runes?"); + stage = 952; + break; + case 952: + options("Yes please!", "Oh, it's a rune shop. No thank you, then."); + stage = 100; + break; + case 955: + npc("Well, luckily I have duplicates. It's a good thing they", "are written in code, I would not want the wrong kind", "of person to get access to the information contained", "within."); + stage = 956; + break; + case 956: + if (!player.getInventory().add(NOTES)) { + GroundItemManager.create(new GroundItem(NOTES, player.getLocation(), player)); + } + sendDialogue("Aubury gives you his research notes."); + stage = 957; + break; + case 957: + end(); + break; + case 800:// quest + switch (buttonId) { + case 1: + npc.openShop(player); + end(); + break; + case 2: + player("Oh, it's a rune shop. No thank you, then."); + stage = 105; + break; + case 3: + player("I have been sent here with a package for you. It's from ", "the head wizard at the Wizards' Tower."); + stage = 801; + break; + } + break; + case 801: + player("I have been sent here with a package for you. It's from ", "the head wizard at the Wizards' Tower."); + stage = 802; + break; + case 802: + npc("Really? But... surely he can't have..? Please, let me", "have it, it must be extremely important for him to have", "sent a stranger."); + stage = 803; + break; + case 803: + if (!player.getInventory().containsItem(PACKAGE)) { + player("Uh... yeah... about that... I kind of don't have it with", "me..."); + stage = 804; + return true; + } + sendDialogue("You hand Aubury the research package."); + stage = 807; + break; + case 804: + npc("What kind of person tells me theyhave a delivery for", "me, but not with them? Honestly."); + stage = 805; + break; + case 805: + npc("Come back when you do."); + stage = 806; + break; + case 806: + end(); + break; + case 807: + if (player.getInventory().remove(PACKAGE)) { + quest.setStage(player, 40); + npc("This... this is incredible. Please, give me a few moments", "to quickly look over this, and then talk to me again."); + stage = 808; + } + break; + case 808: + end(); + break; + case 1: + switch (interfaceId) { + case 230: + switch (buttonId) { + case 1: + npc.openShop(player); + end(); + break; + case 2: + player("No thanks."); + stage = 10; + break; + case 3: + player("Can you teleport me to the rune essence?"); + stage = 11; + break; + } + } + break; + case 100: + switch (buttonId) { + case 1: + npc.openShop(player); + end(); + break; + case 2: + player("Oh, it's a rune shop. No thank you, then."); + stage = 105; + break; + } + break; + case 105: + end(); + break; + case 106: + end(); + break; + case 10: + end(); + break; + case 11: + EssenceTeleport.teleport(npc, player); + end(); + break; + case 450: + switch (buttonId) { + case 1: + player("Can I buy a Skillcape of Runecrafting?"); + stage = 2; + break; + case 2: + npc("Do you want to buy some runes?"); + stage = 0; + break; + } + break; + case 2: + npc("Certainly! Right when you give me 99000 coins."); + stage = 3; + break; + case 3: + options("Okay, here you go.", "No"); + stage = 4; + break; + case 4: + switch (buttonId) { + case 1: + player("Okay, here you go."); + stage = 5; + break; + case 2: + end(); + break; + } + break; + case 5: + if (Skillcape.purchase(player, Skills.RUNECRAFTING)) { + npc("There you go! Enjoy."); + } + stage = 6; + break; + case 6: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return NPC_IDS; + } + } + +} diff --git a/Server/src/main/content/region/misthalin/wiztower/handlers/rcguild/RCGuildMap.java b/Server/src/main/content/region/misthalin/wiztower/handlers/rcguild/RCGuildMap.java new file mode 100644 index 0000000..1044a72 --- /dev/null +++ b/Server/src/main/content/region/misthalin/wiztower/handlers/rcguild/RCGuildMap.java @@ -0,0 +1,30 @@ +package content.region.misthalin.wiztower.handlers.rcguild; + +import core.ServerConstants; +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.plugin.Plugin; + + +/** + * Map in RC guild/wiz tower + * @author ceik + */ +public class RCGuildMap extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(38422).getHandlers().put("option:study",this); + return null; + } + + @Override + public boolean handle(Player player, Node node, String option) { + if(option.equals("study")){ + player.getPacketDispatch().sendMessage("A map of " + ServerConstants.SERVER_NAME + "."); + } + return false; + } +} diff --git a/Server/src/main/content/region/misthalin/wiztower/handlers/rcguild/RCGuildPortal.java b/Server/src/main/content/region/misthalin/wiztower/handlers/rcguild/RCGuildPortal.java new file mode 100644 index 0000000..7529632 --- /dev/null +++ b/Server/src/main/content/region/misthalin/wiztower/handlers/rcguild/RCGuildPortal.java @@ -0,0 +1,33 @@ +package content.region.misthalin.wiztower.handlers.rcguild; + +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Portal in wiz tower + * @author ceik + */ + +@Initializable +public class RCGuildPortal extends OptionHandler { + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(38279).getHandlers().put("option:examine",this); + SceneryDefinition.forId(38279).getHandlers().put("option:enter",this); + return null; + } + + @Override + public boolean handle(Player player, Node node, String string){ + if(string.equals("examine")){ + player.getPacketDispatch().sendMessage("The portal to the runecrafting guild."); + }else { + player.getPacketDispatch().sendMessage("Currently under construction."); + } + return true; + } +} diff --git a/Server/src/main/content/region/misthalin/wiztower/handlers/rcguild/RuneCraftingGuildObjects.java b/Server/src/main/content/region/misthalin/wiztower/handlers/rcguild/RuneCraftingGuildObjects.java new file mode 100644 index 0000000..600525b --- /dev/null +++ b/Server/src/main/content/region/misthalin/wiztower/handlers/rcguild/RuneCraftingGuildObjects.java @@ -0,0 +1,44 @@ +package content.region.misthalin.wiztower.handlers.rcguild; + +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Created for 2009Scape + * User: Ethan Kyle Millard + * Date: March 25, 2020 + * Time: 7:19 PM + */ +@Initializable +public class RuneCraftingGuildObjects extends OptionHandler { + + + @Override + public boolean handle(Player player, Node node, String option) { + Scenery object = ((Scenery) node); + + switch(object.getId()) { + case 38279: + if (player.getViewport().getRegion().getRegionId() == 12337) { + player.teleport(Location.create(1696, 5460, 2)); + } else { + player.teleport(Location.create(3106, 3160, 1)); + } + break; + } + + return true; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(38279).getHandlers().put("option:enter", this); + return this; + } +} diff --git a/Server/src/main/content/region/misthalin/wiztower/quest/ImpCatcher.java b/Server/src/main/content/region/misthalin/wiztower/quest/ImpCatcher.java new file mode 100644 index 0000000..d077a59 --- /dev/null +++ b/Server/src/main/content/region/misthalin/wiztower/quest/ImpCatcher.java @@ -0,0 +1,125 @@ +package content.region.misthalin.wiztower.quest; + +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.game.world.map.RegionManager; +import content.data.Quests; + +/** + * Represents the imp catcher quest. + * @author Vexia + * + */ +@Initializable +public class ImpCatcher extends Quest { + + /** + * Represents the black bead item. + */ + private static final Item BLACK_BEAD = new Item(1474); + + /** + * Represents the red bead item. + */ + private static final Item RED_BEAD = new Item(1470); + + /** + * Represents the white bead item. + */ + private static final Item WHITE_BEAD = new Item(1476); + + /** + * Represents the yellow bead item. + */ + private static final Item YELLOW_BEAD = new Item(1472); + + /** + * Represents the amulet item. + */ + private static final Item AMULET = new Item(1478); + + /** + * Constructs a new {@Code ImpCatcher} {@Code Object} + */ + public ImpCatcher() { + super(Quests.IMP_CATCHER, 21, 20, 1, 160, 0, 1, 2); + } + + @Override + public Quest newInstance(Object object) { + return this; + } + + @Override + public void drawJournal(Player player, int stage) { + super.drawJournal(player, stage); + if (getStage(player) == 0) { + player.getPacketDispatch().sendString(BLUE + "I can start this quest by speaking to " + RED + "Wizard Mizgog " + BLUE + "who is", 275, 4+ 7); + player.getPacketDispatch().sendString(BLUE + "in the " + RED + "Wizard's Tower", 275, 5+ 7); + player.getPacketDispatch().sendString(BLUE + "There are no requirements for this quest.", 275, 7+ 7); + } else if (getStage(player) == 10) { + line(player, "I have spoken to Wizard Mizgog.", 4+ 7); + line(player, BLUE + "I need to collect some items by killing " + RED + " Imps.", 6+ 7); + if (player.getInventory().containItems(BLACK_BEAD.getId(), RED_BEAD.getId(), YELLOW_BEAD.getId(), WHITE_BEAD.getId())) { + line(player, BLUE + "I have collected all the missing beads and need to return", 6+ 7); + line(player, BLUE + "them to " + RED + "Wizard Mizgog.", 7+ 7); + return; + } + if (player.getInventory().containsItem(BLACK_BEAD)) { + line(player, "1 Black Bead", 7+ 7); + } else { + line(player, RED + "1 Black Bead", 7+ 7); + } + if (player.getInventory().containsItem(RED_BEAD)) { + line(player, "1 Red Bead", 8+ 7); + } else { + line(player, RED + "1 Red Bead", 8+ 7); + } + if (player.getInventory().containsItem(WHITE_BEAD)) { + line(player, "1 White Bead", 9+ 7); + } else { + line(player, RED + "1 White Bead", 9+ 7); + } + if (player.getInventory().containsItem(YELLOW_BEAD)) { + line(player, "1 Yellow Bead", 10+ 7); + } else { + line(player, RED + "1 Yellow Bead", 10+ 7); + } + } else { + line(player, "I have spoken to Wizard Mizgog.", 4+ 7); + line(player, "I have collected all the beads.", 6+ 7); + line(player, "Wizard Mizgog thanked me for finding his beads and gave", 8+ 7); + line(player, "me and Amulet of Accuracy.", 9+ 7); + line(player, "QUEST COMPLETE!", 10+ 7); + } + } + + @Override + public void finish(Player player) { + super.finish(player); + player.unlock(); + player.getPacketDispatch().sendMessage("The Wizard hands you an amulet."); + player.getPacketDispatch().sendString("1 Quest Point", 277, 8 + 2); + player.getPacketDispatch().sendString("875 Magic XP", 277, 9 + 2); + player.getPacketDispatch().sendString("Amulet of Accuracy", 277, 10 + 2); + player.getPacketDispatch().sendString("You have completed the Imp Catcher Quest!", 277, 2 + 2); + player.getPacketDispatch().sendItemZoomOnInterface(AMULET.getId(), 230, 277, 3 + 2); + player.getSkills().addExperience(Skills.MAGIC, 875); + // 16170 + Scenery table = RegionManager.getObject(Location.create(3102, 3163, 2)); + if (table.getId() != 16170) { + SceneryBuilder.replace(table, table.transform(16170), 80); + } + if (!player.getInventory().add(AMULET)) { + GroundItemManager.create(AMULET, player.getLocation(), player); + } + } + +} diff --git a/Server/src/main/content/region/morytania/burghderott/dialogue/DustyScroll.kt b/Server/src/main/content/region/morytania/burghderott/dialogue/DustyScroll.kt new file mode 100644 index 0000000..6d566a8 --- /dev/null +++ b/Server/src/main/content/region/morytania/burghderott/dialogue/DustyScroll.kt @@ -0,0 +1,36 @@ +package content.region.morytania.burghderott.dialogue + +import core.api.openDialogue +import core.game.dialogue.DialogueFile +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.tools.END_DIALOGUE +import org.rs09.consts.Items + + +class DustyScroll : InteractionListener { + // Receive during the In Aid of the Myreque quest. + companion object { + const val DUSTY_SCROLL = Items.DUSTY_SCROLL_7629 + class DustyScrollContent : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + 0 -> player!!.dialogueInterpreter.sendItemMessage(DUSTY_SCROLL, "", "You take the scroll and gingerly unravel it. It seems", "very old and the language is not easy to make out.", "You begin to see that it looks like a letter of some kind.").also { stage++ } + 1 -> player!!.dialogueInterpreter.sendItemMessage(DUSTY_SCROLL, "My dearest Lantania,", "I know not what these dark hours bring. I will come for", "thee as soon as I am able, I care no longer for the", "possessions which tie me to this wasted land and the").also { stage++ } + 2 -> player!!.dialogueInterpreter.sendItemMessage(DUSTY_SCROLL, "living which I earned from it.", "Prepare for leaving soon, I shall be there with haste,", "and with Saradomin's blessings we shall make our way out of Hallowvale westwards over the Salve towards").also { stage++ } + 3 -> player!!.dialogueInterpreter.sendItemMessage(DUSTY_SCROLL, "Misthalin and hopefully into the arms of our brethren.", "I also offer up a prayer to Saradomin that he may help", "Queen Efaritay in her hour of need and somehow fight", "these beasts back to the dead place from where they").also { stage++ } + 4 -> player!!.dialogueInterpreter.sendItemMessage(DUSTY_SCROLL, "came.", "I cry at the plight of poor Ascertes and offer up a", "prayer for their children in this darkest of hours.", "So make ready your plans and so soon as you see me,").also { stage++ } + 5 -> player!!.dialogueInterpreter.sendItemMessage(DUSTY_SCROLL, "so we shall set for Misthalin, bring only what you need.", "We shall need all good fortune and speed in this, our", "last chance at a life together.", "Yours, most faithfully,").also { stage++ } + 6 -> player!!.dialogueInterpreter.sendItemMessage(DUSTY_SCROLL, "", "Sialathin").also { stage = END_DIALOGUE } + } + } + } + } + + override fun defineListeners() { + on(DUSTY_SCROLL, IntType.ITEM, "read"){ player, _ -> + openDialogue(player, DustyScrollContent()) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/morytania/burghderott/dialogue/HiylikMynaDialogue.java b/Server/src/main/content/region/morytania/burghderott/dialogue/HiylikMynaDialogue.java new file mode 100644 index 0000000..40ae074 --- /dev/null +++ b/Server/src/main/content/region/morytania/burghderott/dialogue/HiylikMynaDialogue.java @@ -0,0 +1,132 @@ +package content.region.morytania.burghderott.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the hiylikmyna dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class HiylikMynaDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code HiylikMynaDialogue} {@code Object}. + */ + public HiylikMynaDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code HiylikMynaDialogue} {@code Object}. + * @param player the player. + */ + public HiylikMynaDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new HiylikMynaDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendOptions("Select an Option", "Can you tell me why you're here?", "Why is there a mini-game sign here?", "Ok, thanks."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Can you tell me why you're here?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Why is there a mini-game sign here?"); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Ok, thanks."); + stage = 30; + break; + + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Of course. I plan to assist the forces of Saradomin who", "will come out to aid, and fight against the legion of", "vamypyres that infest this foul place. These brave", "mercenaries shall need a guide."); + stage = 11; + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Mini-game sign? Surely sir it is confused and not at all", "in their right mind."); + stage = 21; + break; + case 30: + end(); + break; + case 21: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "This is the collection area for the forces of Saradomin.", "If you know of the plight of the Myreque, you should", "understand what is at stake! Aid the Myreque if you", "can and attempt to draw back the darkness of"); + stage = 22; + break; + case 22: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hallowvale."); + stage = 23; + break; + case 23: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Then perhaps you can then be a guiding light for the", "forces of Saradomin, as they enter the lair of the beast."); + stage = 24; + break; + case 24: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Ok, thanks."); + stage = 25; + break; + case 25: + end(); + break; + case 11: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "When a guide arrives, I will aid the mercenary by", "holding their wealth for their eventual return. The", "mercenary will repay the guide by giving him a token", "for items which I am holding."); + stage = 12; + break; + case 12: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "I shall give such items to the guide as a payment for their", "services once I'm handed the token."); + stage = 13; + break; + case 13: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "What items will you hold?"); + stage = 14; + break; + case 14: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Oh, the range of items is very varied. Mercenaries tend", "to hold raw materials in high esteem and so will deposit", "those with me. They also seem to be good battering", "items."); + stage = 15; + break; + case 15: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Generally, things like uncooked lobsters, coal, silver bars,", "bow strings. Things which are useful! Plus the odd", "tome of experience, which are considered incredibly", "useful."); + stage = 16; + break; + case 16: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Okay, thanks."); + stage = 17; + break; + case 17: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 1514 }; + } +} diff --git a/Server/src/main/content/region/morytania/canifis/dialogue/AgilityBossDialogue.kt b/Server/src/main/content/region/morytania/canifis/dialogue/AgilityBossDialogue.kt new file mode 100644 index 0000000..5b476b6 --- /dev/null +++ b/Server/src/main/content/region/morytania/canifis/dialogue/AgilityBossDialogue.kt @@ -0,0 +1,56 @@ +package content.region.morytania.canifis.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable + +/** + * @author qmqz + */ + +@Initializable +class AgilityBossDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + + if(player.equipment.contains(4202,1)) { + player(FacialExpression.ASKING,"How do I use the agility course?").also { stage = 0 } + } else { + npc(FacialExpression.CHILD_SUSPICIOUS,"Grrr - you don't belong in here, human!").also { stage = 99 } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> npc(FacialExpression.CHILD_NORMAL,"I'll throw you a stick, which you need to", + "fetch as quickly as possible, ", + "from the area beyond the pipes.").also { stage++ } + + 1 -> npc(FacialExpression.CHILD_NORMAL,"Be wary of the deathslide - you must hang by your teeth,", + "and if your strength is not up to the job you will", + "fall into a pit of spikes. Also, I would advise not", + "carrying too much extra weight.").also { stage++ } + + 2 -> npc(FacialExpression.CHILD_NORMAL,"Bring the stick back to the werewolf waiting at", + "the end of the death slide to get your agility bonus.").also { stage++ } + + 3 ->npc(FacialExpression.CHILD_NORMAL,"I will throw your stick as soon as you jump onto the", + "first stone.").also { stage = 99 } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return AgilityBossDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(1661) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/morytania/canifis/dialogue/BarkerDialogue.java b/Server/src/main/content/region/morytania/canifis/dialogue/BarkerDialogue.java new file mode 100644 index 0000000..810c0d3 --- /dev/null +++ b/Server/src/main/content/region/morytania/canifis/dialogue/BarkerDialogue.java @@ -0,0 +1,90 @@ +package content.region.morytania.canifis.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the barker npc dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class BarkerDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code BarkerDialogue} {@code Object}. + */ + public BarkerDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code BarkerDialogue} {@code Object}. + * @param player the player. + */ + public BarkerDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new BarkerDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.HAPPY, "Hello."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "You are looking for clothes, yes? You look at my", "products! I have very many nice clothes, yes?"); + stage = 1; + break; + case 1: + interpreter.sendOptions("Select an Option", "Yes, please.", "No, thanks."); + stage = 2; + break; + case 2: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.FRIENDLY, "Yes, please."); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.FRIENDLY, "No thanks."); + stage = 15; + break; + } + break; + + case 15: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Unfortunate for you, yes?", "Many bargains, won't find elsewhere!"); + stage = 20; + break; + case 20: + end(); + break; + case 10: + end(); + npc.openShop(player); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 1039 }; + } +} diff --git a/Server/src/main/content/region/morytania/canifis/dialogue/FilelioDialogue.java b/Server/src/main/content/region/morytania/canifis/dialogue/FilelioDialogue.java new file mode 100644 index 0000000..07c2187 --- /dev/null +++ b/Server/src/main/content/region/morytania/canifis/dialogue/FilelioDialogue.java @@ -0,0 +1,86 @@ +package content.region.morytania.canifis.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the filelio dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class FilelioDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code FilelioDialogue} {@code Object}. + */ + public FilelioDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code FilelioDialogue} {@code Object}. + * @param player the player. + */ + public FilelioDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new FilelioDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello there."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "H-hello. You l-look like a s-stranger to these p-parts.", "Would you l-ike to buy something? I h-have some s-", "special offers at the m-minute...some s-sample bottles for", "s-storing s-snail slime."); + stage = 1; + break; + case 1: + interpreter.sendOptions("Select an Option", "Yes, please.", "No, thanks."); + stage = 2; + break; + case 2: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Yes, please."); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "No thanks."); + stage = 20; + break; + + } + break; + case 20: + end(); + break; + case 10: + end(); + npc.openShop(player); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 1040 }; + } +} diff --git a/Server/src/main/content/region/morytania/canifis/dialogue/HumanWerewolfDialogue.kt b/Server/src/main/content/region/morytania/canifis/dialogue/HumanWerewolfDialogue.kt new file mode 100644 index 0000000..9763d0a --- /dev/null +++ b/Server/src/main/content/region/morytania/canifis/dialogue/HumanWerewolfDialogue.kt @@ -0,0 +1,66 @@ +package content.region.morytania.canifis.dialogue + +import core.api.anyInEquipment +import core.api.toIntArray +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.Items + +@Initializable +class HumanWerewolfDialogue(player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage){ + START_DIALOGUE -> { + // There are 10 random different messages for all of the werewolves in human form + // If you have the Ring of Charos they think you're a werewolf and talk differently + if (anyInEquipment(player, Items.RING_OF_CHAROS_4202, Items.RING_OF_CHAROSA_6465)){ + // Nice talks + when ((1..10).random()){ + 1 -> npcl(FacialExpression.HAPPY, "I bet you have wonderful paws.").also { stage = END_DIALOGUE } + 2 -> npcl(FacialExpression.NEUTRAL, "A very miserable day, altogether... enjoy it while it lasts.").also { stage = END_DIALOGUE } + 3 -> npcl(FacialExpression.ASKING, "If you catch anyone promise me you'll share.").also { stage = END_DIALOGUE } + 4 -> npcl(FacialExpression.ASKING, "I haven't smelt you around here before...").also { stage = END_DIALOGUE } + 5 -> npcl(FacialExpression.FRIENDLY, "You smell familiar...").also { stage = END_DIALOGUE } + 6 -> npcl(FacialExpression.ASKING, "Seen any humans around here? I'm v-e-r-y hungry.").also { stage = END_DIALOGUE } + 7 -> npcl(FacialExpression.FRIENDLY, "You look to me like someone with a healthy taste for blood.").also { stage = END_DIALOGUE } + 8 -> npcl(FacialExpression.FRIENDLY, "Good day to you, my friend.").also { stage = END_DIALOGUE } + 9 -> npcl(FacialExpression.ASKING, "Fancy going up to the castle for a bit of a snack?").also { stage = END_DIALOGUE } + 10 -> npcl(FacialExpression.NEUTRAL, "Give me a moment, I have a bit of someone stuck in my teeth...").also { stage = END_DIALOGUE } + } + } + else { + // Mean talks + when ((1..10).random()){ + 1 -> npcl(FacialExpression.ANNOYED, "If I were as ugly as you I would not dare to show my face in public!").also { stage = END_DIALOGUE } + 2 -> npcl(FacialExpression.ANGRY, "Out of my way, punk.").also { stage = END_DIALOGUE } + // The only one that has a path + 3 -> npcl(FacialExpression.ASKING, "Hmm... you smell strange...").also { stage++ } + 4 -> npcl(FacialExpression.ANGRY, "Leave me alone.").also { stage = END_DIALOGUE } + 5 -> npcl(FacialExpression.ANNOYED, "Don't talk to me again if you value your life!").also { stage = END_DIALOGUE } + 6 -> npcl(FacialExpression.ANNOYED, "Get lost!").also { stage = END_DIALOGUE } + 7 -> npcl(FacialExpression.ANNOYED, "I don't have anything to give you so leave me alone, mendicant.").also { stage = END_DIALOGUE } + 8 -> npcl(FacialExpression.ANGRY, "Have you no manners?").also { stage = END_DIALOGUE } + 9 -> npcl(FacialExpression.ANNOYED, "I don't have time for this right now.").also { stage = END_DIALOGUE } + 10 -> npcl(FacialExpression.ANGRY, "I have no interest in talking to a pathetic meat bag like yourself.").also{ stage = END_DIALOGUE} + } + } + } + // There's one path that the player can respond to (3 without the ring) + 1 -> playerl(FacialExpression.ASKING, "Strange how?").also { stage++ } + 2 -> npcl(FacialExpression.EVIL_LAUGH, "Like a human!").also { stage++ } + 3 -> playerl(FacialExpression.PANICKED, "Oh! Er... I just ate one is why!").also { stage = END_DIALOGUE } + else -> { + end() + } + } + return true + } + + override fun getIds(): IntArray { + return (6026..6046).toIntArray() + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/morytania/canifis/dialogue/RoavarDialogue.kt b/Server/src/main/content/region/morytania/canifis/dialogue/RoavarDialogue.kt new file mode 100644 index 0000000..edb3fbd --- /dev/null +++ b/Server/src/main/content/region/morytania/canifis/dialogue/RoavarDialogue.kt @@ -0,0 +1,118 @@ +package content.region.morytania.canifis.dialogue + +import content.region.morytania.quest.creatureoffenkenstrain.RoavarDialogueFile +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.IfTopic +import core.game.dialogue.Topic +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import content.data.Quests + +/** + * Roavar dialogue. + */ +@Initializable +class RoavarDialogue (player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any): Boolean { + npc = args[0] as NPC + player(FacialExpression.HALF_GUILTY, "Hello there!") + stage = 0 + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + 0 -> { + npc(FacialExpression.HALF_GUILTY, "Greeting traveller. Welcome to 'The Hair Of The Dog'", "Tavern. What can I do you for?") + stage = 1 + } + + 1 -> showTopics( + Topic(FacialExpression.HALF_GUILTY, "Can I buy a beer?", 10, false), + Topic(FacialExpression.HALF_GUILTY, "Can I hear some gossip", 20, false), + IfTopic(FacialExpression.HALF_GUILTY, "Can I buy something to eat?", RoavarDialogueFile(1), player.getQuestRepository().getQuest(Quests.CREATURE_OF_FENKENSTRAIN).getStage(player) == 2, false), + Topic(FacialExpression.HALF_GUILTY, "Nothing thanks.", 40, false) + ) + + 10 -> { + npc(FacialExpression.HALF_GUILTY, "Well that's my speciality! The local brew's named", "'Moonlight Mead' and will set you back 5 gold.", "Waddya say? Fancy a pint?") + stage = 11 + } + + 11 -> { + interpreter.sendOptions("Select an Option", "Yes please.", "Actually, no thanks.") + stage = 12 + } + + 12 -> when (buttonId) { + 1 -> { + player(FacialExpression.HALF_GUILTY, "Yes please.") + stage = 15 + } + + 2 -> { + player(FacialExpression.HALF_GUILTY, "Actually, no thanks.") + stage = 14 + } + } + 14 -> end() + 15 -> if (inInventory(player, Items.COINS_995, 5)) { + if (removeItem(player, Item(Items.COINS_995, 5))) { + addItemOrDrop(player, Items.MOONLIGHT_MEAD_2955) + npc(FacialExpression.HALF_GUILTY, "Here ya go pal. Enjoy!") + stage = 16 + } + } else { + end() + sendMessage(player, "You need 5 gold coins to buy a pint of beer.") + } + + 16 -> end() + 20 -> { + npc(FacialExpression.HALF_GUILTY, "I am not one to gossip!") + stage = 21 + } + + 21 -> end() + 30 -> stage = if (inInventory(player, 2963, 1)) { + npc(FacialExpression.HALF_GUILTY, "I don't have a spare lying around, sorry friend.", "Hopefully you'll find something else that can protect you", "against ghasts!") + 31 + } else { + npc(FacialExpression.HALF_GUILTY, "Ah, well I do have one lying around.", "I suppose you could have it.") + 42 + } + + 31 -> end() + 40 -> { + npc(FacialExpression.HALF_GUILTY, "...I don't know why you talked to me if you don't want", "anything then...") + stage = 41 + } + + 41 -> end() + 42 -> { + if (freeSlots(player) < 1) { + npc(FacialExpression.HALF_GUILTY, "Oh, nevermind. It seems your backpack is full.") + } else { + sendDialogue(player, "The bartender hands you a silver sickle.") + addItem(player, 2963) + } + stage = 31 + } + } + return true + } + + override fun newInstance(player: Player): DialoguePlugin { + return RoavarDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.ROAVAR_1042) + } +} diff --git a/Server/src/main/content/region/morytania/canifis/dialogue/RufusDialogue.java b/Server/src/main/content/region/morytania/canifis/dialogue/RufusDialogue.java new file mode 100644 index 0000000..abe17c0 --- /dev/null +++ b/Server/src/main/content/region/morytania/canifis/dialogue/RufusDialogue.java @@ -0,0 +1,107 @@ +package content.region.morytania.canifis.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Handles the RufusDialogue dialogue. + * @author 'Vexia + */ +@Initializable +public class RufusDialogue extends DialoguePlugin { + + public RufusDialogue() { + + } + + public RufusDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new RufusDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.HAPPY, "Hi!"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Grreeting frrriend! Welcome to my worrrld famous", "food emporrium! All my meats are so frrresh you'd", "swear you killed them yourrrself!"); + stage = 1; + break; + case 1: + interpreter.sendOptions("Select an Option", "Why do you only sell meats?", "Do you sell cooked food?", "Can I buy some food?"); + stage = 2; + break; + case 2: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.ASKING, "Why do you only sell meats?"); + stage = 10; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.ASKING, "Do you sell cooked food?"); + stage = 20; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.FRIENDLY, "Can I buy some food?"); + stage = 30; + break; + } + break; + case 10: + interpreter.sendDialogues(npc, FacialExpression.DISGUSTED, "What? Why, what else would you want to eat? What", "kind of lycanthrrope are you anyway?"); + stage = 11; + break; + case 11: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "...A vegetarian one?"); + stage = 12; + break; + case 12: + interpreter.sendDialogues(npc, FacialExpression.EXTREMELY_SHOCKED, "Vegetarrrian...?"); + stage = 13; + break; + case 13: + interpreter.sendDialogues(player, FacialExpression.SUSPICIOUS, "Never mind."); + stage = 14; + break; + case 14: + end(); + break; + case 20: + interpreter.sendDialogues(npc, FacialExpression.EVIL_LAUGH, "Cooked food? Who would want that? You lose all the", "flavourrr of the meat when you can't taste the blood!"); + stage = 21; + break; + case 21: + end(); + break; + case 30: + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "Cerrrtainly!"); + stage = 31; + break; + case 31: + end(); + npc.openShop(player); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 1038 }; + } +} diff --git a/Server/src/main/content/region/morytania/canifis/dialogue/SbottDialogue.kt b/Server/src/main/content/region/morytania/canifis/dialogue/SbottDialogue.kt new file mode 100644 index 0000000..b315f4b --- /dev/null +++ b/Server/src/main/content/region/morytania/canifis/dialogue/SbottDialogue.kt @@ -0,0 +1,67 @@ +package content.region.morytania.canifis.dialogue + +import content.global.skill.crafting.TanningProduct +import core.api.inInventory +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.game.node.entity.npc.NPC +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import org.rs09.consts.NPCs + +/** + * Handles Sbott's dialogue. + */ +@Initializable +class SbottDialogue(player: Player? = null) : DialoguePlugin(player) { + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npcl(FacialExpression.HAPPY, "Hello stranger. Would you like to me to tan any hides for you?").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when (stage) { + //0 -> npc(FacialExpression.HAPPY, "Soft leather - 2 gp per hide", "Hard leather - 5 gp per hide", "Snakeskins - 25 gp per hide", "Dragon leather - 45 gp per hide.").also { stage++ } + 0 -> npc(FacialExpression.HAPPY, "Soft leather - 1 gp per hide", "Hard leather - 3 gp per hide", "Snakeskins - 20 gp per hide", "Dragon leather - 20 gp per hide.").also { stage++ } + 1 -> { + var hasHides = false + + for (tanningProduct in TanningProduct.values()) { + if (inInventory(player, tanningProduct.item)) { + hasHides = true + break + } + } + + if(hasHides) { + npcl(FacialExpression.FRIENDLY, "I see you have brought me some hides. Would you like me to tan them for you?").also { stage = 10 } + } else { + playerl(FacialExpression.HALF_GUILTY, "No thanks, I haven't any hides.").also { stage = END_DIALOGUE } + } + } + + 10 -> options("Yes please.", "No thanks.").also { stage++ } + + 11 -> when (buttonId) { + 1 -> playerl(FacialExpression.HAPPY, "Yes please.").also { stage = 12 } + 2 -> playerl(FacialExpression.NEUTRAL, "No thanks.").also { stage = 13 } + } + + 12 -> end().also { TanningProduct.open(player, NPCs.SBOTT_1041) } + 13 -> npcl(FacialExpression.FRIENDLY, "Very well, @g[sir,madam], as you wish.").also { stage = END_DIALOGUE } + } + + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return SbottDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.SBOTT_1041) + } +} diff --git a/Server/src/main/content/region/morytania/canifis/dialogue/TaxidermistDialogue.kt b/Server/src/main/content/region/morytania/canifis/dialogue/TaxidermistDialogue.kt new file mode 100644 index 0000000..abaefb1 --- /dev/null +++ b/Server/src/main/content/region/morytania/canifis/dialogue/TaxidermistDialogue.kt @@ -0,0 +1,43 @@ +package content.region.morytania.canifis.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.NPCs + +@Initializable +open class TaxidermistDialogue(player: Player? = null) : DialoguePlugin(player) { + companion object{ + const val YES = 10 + const val NO = 20 + const val WHAT = 30 + } + + override fun open(vararg args: Any?): Boolean { + npcl(FacialExpression.HAPPY, "Oh, hello. Have you got something you want preserving?").also { stage++ } + return true + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + START_DIALOGUE + 1 -> showTopics( + Topic("Yes please.", YES), + Topic("Not right now.", NO), + Topic("What?", WHAT) + ) + + YES -> npcl(FacialExpression.HAPPY, "Give it to me to look at then.").also { stage = END_DIALOGUE } + NO -> npcl(FacialExpression.ANNOYED, "Well, you go kill things so I can stuff them, eh?").also { stage = END_DIALOGUE } + WHAT -> npcl(FacialExpression.NEUTRAL, " If you bring me a monster head or a very big fish, I can preserve it for you so you can mount it in your house.").also { stage++ } + WHAT + 1 -> npcl(FacialExpression.HAPPY, "I hear there are all sorts of exotic creatures in the Slayer Tower -- I'd like a chance to stuff one of them!").also { stage = END_DIALOGUE } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.TAXIDERMIST_4246) + } +} diff --git a/Server/src/main/content/region/morytania/canifis/handlers/CanafisWerewolfNPC.kt b/Server/src/main/content/region/morytania/canifis/handlers/CanafisWerewolfNPC.kt new file mode 100644 index 0000000..51a82b8 --- /dev/null +++ b/Server/src/main/content/region/morytania/canifis/handlers/CanafisWerewolfNPC.kt @@ -0,0 +1,61 @@ +package content.region.morytania.canifis.handlers + +import core.api.* +import core.game.interaction.QueueStrength +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.combat.DeathTask +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items + +class WerewolfBehavior : NPCBehavior(*HUMAN_NPCS) { + companion object { + // There are 20 humans that can turn into werewolves. They are all in series, so a range toIntArray() is easier. + private val HUMAN_NPCS = (6026 .. 6045).toIntArray() + private val WEREWOLF_NPCS = (6006 .. 6025).toIntArray() + private val HUMAN_OUT_ANIMATION = Animation(6554) + private val WEREWOLF_IN_ANIMATION = Animation(6543) // This is not used as there is a corresponding gfx. + private val WEREWOLF_IN_GFXS = (1079 .. 1098).toIntArray() // Play each werewolf's gfx with the animation. + } + + override fun afterDamageReceived(self: NPC, attacker: Entity, state: BattleState) { + if(DeathTask.isDead(self)){ + // Don't transform if you are killed + return + } + if (attacker is Player) { + if (!inEquipment(attacker, Items.WOLFBANE_2952, 1) && self.id in HUMAN_NPCS) { + delayAttack(self, 3) + delayAttack(attacker, 3) + lock(self, 3) + queueScript(self, 0, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + visualize(self, HUMAN_OUT_ANIMATION, WEREWOLF_IN_GFXS[self.id - 6026]) + return@queueScript delayScript(self, WEREWOLF_IN_ANIMATION.duration) + } + 1 -> { + transformNpc(self, WEREWOLF_NPCS[self.id - 6026], 200) + return@queueScript delayScript(self, 1) + } + 2 -> { + self.properties.combatPulse.attack(attacker) + return@queueScript stopExecuting(self) + } + else -> return@queueScript stopExecuting(self) + } + } + } + } + } + + override fun onRespawn(self: NPC) { + if (self.id in WEREWOLF_NPCS){ + self.reTransform() + } + super.onRespawn(self) + } +} diff --git a/Server/src/main/content/region/morytania/canifis/handlers/RoavarOptionPlugin.java b/Server/src/main/content/region/morytania/canifis/handlers/RoavarOptionPlugin.java new file mode 100644 index 0000000..1a71527 --- /dev/null +++ b/Server/src/main/content/region/morytania/canifis/handlers/RoavarOptionPlugin.java @@ -0,0 +1,26 @@ +package content.region.morytania.canifis.handlers; + +import core.cache.def.impl.NPCDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; + +@Initializable +public class RoavarOptionPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + NPCDefinition.forId(1042).getHandlers().put("option:trade", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + player.getDialogueInterpreter().open(((NPC) node).getId(), ((NPC) node)); + return true; + } + +} diff --git a/Server/src/main/content/region/morytania/canifis/handlers/TaxidermistInteraction.kt b/Server/src/main/content/region/morytania/canifis/handlers/TaxidermistInteraction.kt new file mode 100644 index 0000000..d7ead3a --- /dev/null +++ b/Server/src/main/content/region/morytania/canifis/handlers/TaxidermistInteraction.kt @@ -0,0 +1,100 @@ +package content.region.morytania.canifis.handlers + +import content.region.morytania.canifis.dialogue.TaxidermistDialogue +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class TaxidermistInteraction : InteractionListener { + + enum class StuffableItem(val toStuff : Int, val product : Int, val message : String, val cost : Int){ + BASS(Items.BIG_BASS_7989, Items.BIG_BASS_7990, "That's a mighty fine sea bass you've caught there.", 1000), + SWORDFISH(Items.BIG_SWORDFISH_7991, Items.BIG_SWORDFISH_7992, "Don't point that thing at me!", 2500), + SHARK(Items.BIG_SHARK_7993,Items.BIG_SHARK_7994, "That's quite a fearsome shark! You've done everyone a service by removing it from the sea!", 5000), + CRAWLING_HAND(Items.CRAWLING_HAND_7975,Items.CRAWLING_HAND_7982, "That's a very fine crawling hand.", 1000), + COCKATRICE(Items.COCKATRICE_HEAD_7976, Items.COCKATRICE_HEAD_7983, "A cockatrice! Beautiful, isn't it? Look at the plumage!", 2000), + BASILISK( Items.BASILISK_HEAD_7977, Items.BASILISK_HEAD_7984, "My, he's a scary-looking fellow, isn't he? He'll look good on your wall!",4000), + KURASK(Items.KURASK_HEAD_7978, Items.KURASK_HEAD_7985, "A kurask? Splendid! Look at those horns!", 6000), + ABYSSAL(Items.ABYSSAL_HEAD_7979, Items.ABYSSAL_HEAD_7986, "Goodness, an abyssal demon!", 12000), + KBD(Items.KBD_HEADS_7980, Items.KBD_HEADS_7987, " This must be a King Black Dragon!", 50000), + KQ(Items.KQ_HEAD_7981, Items.KQ_HEAD_7988, " That must be the biggest kalphite I've ever seen!", 50000) + } + class TaxidermistTradeDialogue : DialogueFile() { + companion object{ + const val TRADE = 10 + const val YES = 20 + const val NO = 30 + const val POOR = 40 + } + + lateinit var stuffableItem : StuffableItem + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + START_DIALOGUE -> npcl(FacialExpression.HAPPY, stuffableItem.message).also { + stage = when(stuffableItem){ + StuffableItem.ABYSSAL -> stage + 1 + StuffableItem.KBD -> stage + 2 + StuffableItem.KQ -> stage + 3 + else -> TRADE + } + } + START_DIALOGUE + 1 -> npcl(FacialExpression.HAPPY, "See how it's still glowing? I'll have to use some magic to preserve that.").also { stage = TRADE } + START_DIALOGUE + 2 -> npcl(FacialExpression.HAPPY, "I'll have to get out my heavy duty tools -- this skin's as tough as iron!").also { stage = TRADE } + START_DIALOGUE + 3 -> npcl(FacialExpression.HAPPY, "Preserving insects is always tricky. I'll have to be careful...").also { stage = TRADE } + + TRADE -> npcl(FacialExpression.HAPPY, "I can preserve that for you for ${stuffableItem.cost} coins.").also { stage++ } + TRADE + 1 -> showTopics( + Topic("Yes please.", YES), + Topic("No thanks.", NO) + ) + YES -> { + if (inInventory(player!!, Items.COINS_995, stuffableItem.cost)){ + if (removeItem(player!!, stuffableItem.toStuff) && removeItem(player!!, Item(Items.COINS_995, stuffableItem.cost))){ + addItem(player!!, stuffableItem.product) + npcl(FacialExpression.HAPPY, "There you go!").also { stage = END_DIALOGUE } + } + } + else { + playerl(FacialExpression.SAD, "But I don't have enough money on me.").also { stage = POOR } + } + } + + POOR -> npcl(FacialExpression.ANNOYED, "Don't waste my time, then!").also { stage = END_DIALOGUE } + + NO -> npcl(FacialExpression.NEUTRAL, "All right, come back if you change your mind, eh?").also { stage = END_DIALOGUE } + } + } + + } + + override fun defineListeners() { + + onUseAnyWith(IntType.NPC, NPCs.TAXIDERMIST_4246) { player, used, with -> + val item = used.id + StuffableItem.values().map { if(it.toStuff == item){ + val dialogueFile = TaxidermistTradeDialogue() + dialogueFile.stuffableItem = it + openDialogue(player, dialogueFile, with as NPC) + return@onUseAnyWith true + } + } + + when (item) { + // all fish + Items.RAW_CHICKEN_2138 -> sendNPCDialogue(player, with.id, "Killing a chicken is hardly worth boasting about!") + else -> sendNPCDialogue(player, with.id, "Don't be silly, I can't preserve that!") + } + return@onUseAnyWith true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/morytania/dialogue/AfflictedDialogue.kt b/Server/src/main/content/region/morytania/dialogue/AfflictedDialogue.kt new file mode 100644 index 0000000..0f3cfd0 --- /dev/null +++ b/Server/src/main/content/region/morytania/dialogue/AfflictedDialogue.kt @@ -0,0 +1,42 @@ +package content.region.morytania.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.RandomFunction + + +/** + * @author qmqz + */ + +@Initializable +class AfflictedDialogue : DialoguePlugin { + private val chats = arrayOf("ughugh", "knows'is", "knows'is", "nots", "pirsl", "wot's", "zurgle", "gurghl", "mee's", "seysyi", "sfriess", "says") + + override fun open(vararg args: Any): Boolean { + npc = args[0] as NPC + chats.shuffle() + interpreter.sendDialogues( npc, FacialExpression.ASKING, chats.copyOfRange(0, RandomFunction.random(1, 6)).contentToString() + .replace("[", "").replace("]", "").replace(",", "")) + return true + } + + constructor() + constructor(player: Player?) : super(player) + + override fun getIds(): IntArray { + return intArrayOf(1257, 1258, 1261, 1262) + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + end() + return true + } + + override fun newInstance(player: Player): DialoguePlugin { + return AfflictedDialogue(player) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/morytania/dialogue/UliziusDialogue.java b/Server/src/main/content/region/morytania/dialogue/UliziusDialogue.java new file mode 100644 index 0000000..6b83303 --- /dev/null +++ b/Server/src/main/content/region/morytania/dialogue/UliziusDialogue.java @@ -0,0 +1,72 @@ +package content.region.morytania.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Handles the UliziusDialogue dialogue. + * @author 'Vexia + */ +@Initializable +public class UliziusDialogue extends DialoguePlugin { + + public UliziusDialogue() { + + } + + public UliziusDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new UliziusDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello there."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "What... Oh, don't creep up on me like that... I thought", "you were a Ghast!"); + stage = 1; + break; + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Can I go through the gate please?"); + stage = 2; + break; + case 2: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Absolutely not. I've been given strict instructions not to", "let anyone through. It's just too dangerous. No one", "gets in without Drezels say so!"); + stage = 3; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Where is Drezel?"); + stage = 4; + break; + case 4: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Oh, he's in the temple, just go back over the bridge,", "down the ladder and along the hallway, you can't miss", "him."); + stage = 5; + break; + case 5: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 1054 }; + } +} diff --git a/Server/src/main/content/region/morytania/dialogue/VanstromKlause.java b/Server/src/main/content/region/morytania/dialogue/VanstromKlause.java new file mode 100644 index 0000000..f9e8e82 --- /dev/null +++ b/Server/src/main/content/region/morytania/dialogue/VanstromKlause.java @@ -0,0 +1,60 @@ +package content.region.morytania.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Handles the VanstromKlause dialogue. + * @author 'Vexia + */ +@Initializable +public class VanstromKlause extends DialoguePlugin { + + public VanstromKlause() { + + } + + public VanstromKlause(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + + return new VanstromKlause(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Hello there, how goes it stranger?"); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Quite well thanks for asking, how about you?"); + stage = 1; + break; + case 1: + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Quite well my self."); + stage = 2; + break; + case 2: + end();// todo real dial at this part. + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 2020 }; + } +} diff --git a/Server/src/main/content/region/morytania/handlers/BarrowsBoatPlugin.java b/Server/src/main/content/region/morytania/handlers/BarrowsBoatPlugin.java new file mode 100644 index 0000000..befd516 --- /dev/null +++ b/Server/src/main/content/region/morytania/handlers/BarrowsBoatPlugin.java @@ -0,0 +1,53 @@ +package content.region.morytania.handlers; + +import core.cache.def.impl.SceneryDefinition; +import core.game.component.Component; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Handles the barrows boat plugin. + * @author Vexia + */ +@Initializable +public class BarrowsBoatPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(6970).getHandlers().put("option:board", this); + SceneryDefinition.forId(6969).getHandlers().put("option:board", this); + return this; + } + + @Override + public boolean handle(final Player player, Node node, String option) { + switch (option) { + case "board": + final Location dest = node.getId() == 6970 ? new Location(3522, 3285, 0) : new Location(3500, 3380, 0); + final String name = node.getId() == 6970 ? "Mort'ton." : "the swamp"; + player.lock(); + player.getInterfaceManager().open(new Component(321)); + GameWorld.getPulser().submit(new Pulse(7, player) { + + @Override + public boolean pulse() { + player.unlock(); + player.teleport(dest); + player.getInterfaceManager().close(); + player.getDialogueInterpreter().sendDialogue("You arrive at " + name + "."); + return true; + } + + }); + break; + } + return true; + } + +} diff --git a/Server/src/main/content/region/morytania/handlers/BarrowsTunnelShortcut.java b/Server/src/main/content/region/morytania/handlers/BarrowsTunnelShortcut.java new file mode 100644 index 0000000..65f72d7 --- /dev/null +++ b/Server/src/main/content/region/morytania/handlers/BarrowsTunnelShortcut.java @@ -0,0 +1,83 @@ +package content.region.morytania.handlers; + +import core.cache.def.impl.SceneryDefinition; +import core.game.global.action.ClimbActionHandler; +import core.game.global.action.DoorActionHandler; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Handles the underground shortcut from the Canifis trapdoor to the swamp. + * @author Splinter - March 1st + */ +@Initializable +public class BarrowsTunnelShortcut extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(5055).getHandlers().put("option:open", this); + SceneryDefinition.forId(5054).getHandlers().put("option:climb-up", this); + SceneryDefinition.forId(5052).getHandlers().put("option:search", this); + SceneryDefinition.forId(30261).getHandlers().put("option:open", this); + SceneryDefinition.forId(30262).getHandlers().put("option:open", this); + SceneryDefinition.forId(30265).getHandlers().put("option:open", this); + SceneryDefinition.forId(5005).getHandlers().put("option:climb up", this); + SceneryDefinition.forId(5005).getHandlers().put("option:climb down", this); + SceneryDefinition.forId(5002).getHandlers().put("option:walk-here", this); + return this; + } + + @Override + public boolean handle(final Player player, Node node, String option) { + switch (node.getId()) { + case 5055: + player.teleport(new Location(3477, 9845)); + break; + case 5054: + ClimbActionHandler.climb(player, ClimbActionHandler.CLIMB_UP, new Location(3496, 3465, 0)); + break; + case 5052: + player.getPacketDispatch().sendMessage("You search the wall and find a lever."); + DoorActionHandler.handleAutowalkDoor(player, ((Scenery) node)); + break; + case 30261: + case 30262: + player.teleport(new Location(3509, 3448), 1); + break; + case 30265: + player.teleport(new Location(3500, 9812), 1); + break; + case 5002: + + break; + case 5005:// First tree + if (node.getLocation().equals(new Location(3502, 3431))) { + switch (option) { + case "climb up": + ClimbActionHandler.climb(player, ClimbActionHandler.CLIMB_UP, new Location(3502, 3425, 0)); + break; + case "climb down": + ClimbActionHandler.climb(player, ClimbActionHandler.CLIMB_DOWN, new Location(3503, 3431, 0)); + break; + } + break; + } else {// second tree + switch (option) { + case "climb up": + ClimbActionHandler.climb(player, ClimbActionHandler.CLIMB_UP, new Location(3503, 3431, 0)); + break; + case "climb down": + ClimbActionHandler.climb(player, ClimbActionHandler.CLIMB_DOWN, new Location(3502, 3425, 0)); + break; + } + } + } + return true; + } + +} diff --git a/Server/src/main/content/region/morytania/handlers/MortMyreGhastNPC.kt b/Server/src/main/content/region/morytania/handlers/MortMyreGhastNPC.kt new file mode 100644 index 0000000..6748596 --- /dev/null +++ b/Server/src/main/content/region/morytania/handlers/MortMyreGhastNPC.kt @@ -0,0 +1,105 @@ +package content.region.morytania.handlers + +import core.api.Container +import core.api.* +import content.data.consumables.Consumables +import core.game.consumable.Food +import core.game.interaction.MovementPulse +import core.game.node.entity.Entity +import core.game.node.entity.combat.ImpactHandler +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.world.map.Location +import core.game.world.map.RegionManager +import core.game.world.update.flag.context.Animation +import core.plugin.Initializable +import core.tools.RandomFunction +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import content.region.morytania.quest.naturespirit.NSUtils +import org.rs09.consts.Sounds + +@Initializable +class MortMyreGhastNPC : AbstractNPC { + //Constructor spaghetti because Arios I guess + constructor() : super(NPCs.GHAST_1052, null, true) {} + private constructor(id: Int, location: Location) : super(id, location) {} + + override fun construct(id: Int, location: Location, vararg objects: Any?): AbstractNPC { + isAggressive = id != ids[0] + return MortMyreGhastNPC(id, location) + } + + override fun handleTickActions() { + super.handleTickActions() + if(id == ids[0] && RandomFunction.roll(35)){ + val players = RegionManager.getLocalPlayers(this, 5).filter { !it.inCombat() } + if(players.isNotEmpty()){ + val player = players.random() + submitIndividualPulse(this, object : MovementPulse(this, player){ + override fun pulse(): Boolean { + animate(Animation(1093)) + attemptLifeSiphon(player) + return true + } + }) + } + } else { + val ticksTransformed = getWorldTicks() - getAttribute(this, "woke", 0) + if(!inCombat() && ticksTransformed > 10){ + reTransform() + } + } + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.GHAST_1052, NPCs.GHAST_1053) + } + + fun attemptLifeSiphon(player: Player){ + var hasFood = false + + if(NSUtils.activatePouch(player, this)) return + + GlobalScope.launch { + for(i in player.inventory.toArray()){ + if(i == null) continue + val consumable = Consumables.getConsumableById(i.id) + if(consumable != null && consumable.consumable is Food) { + hasFood = true + removeItem(player, i, Container.INVENTORY) + addItem(player, Items.ROTTEN_FOOD_2959) + sendMessage(player, "You feel something attacking your backpack, and smell a terrible stench.") + break + } + } + playAudio(player, Sounds.GHAST_ATTACK_433) + + if(!hasFood && RandomFunction.roll(3)) { + sendMessage(player, "An attacking Ghast just misses you.") + } else if(!hasFood){ + impact(player, RandomFunction.random(3,6), ImpactHandler.HitsplatType.NORMAL) + sendMessage(player, "A supernatural force draws energy from you.") + } + } + } + + override fun commenceDeath(killer: Entity?) { + super.commenceDeath(killer) + } + + override fun finalizeDeath(killer: Entity?) { + super.finalizeDeath(killer) + if(id == ids[1]) { + reTransform() + if(killer is Player){ + NSUtils.incrementGhastKC(killer) + rewardXP(killer, Skills.PRAYER, 30.0) + removeAttribute("woke") + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/morytania/handlers/MorytaniaArea.kt b/Server/src/main/content/region/morytania/handlers/MorytaniaArea.kt new file mode 100644 index 0000000..5edfa55 --- /dev/null +++ b/Server/src/main/content/region/morytania/handlers/MorytaniaArea.kt @@ -0,0 +1,81 @@ +package content.region.morytania.handlers + +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import org.rs09.consts.NPCs +import core.game.bots.AIPlayer +import core.game.dialogue.DialogueFile +import core.game.world.GameWorld +import content.data.Quests + +class MorytaniaArea : MapArea { + override fun defineAreaBorders(): Array { + return arrayOf( + ZoneBorders(3426, 3191, 3715, 3588), //Morytania overworld + ZoneBorders(3520, 9856, 3583, 9919) //Werewolf agility course + ) + } + + override fun areaEnter(entity: Entity) { + if (entity is Player && entity !is AIPlayer && ( + !isQuestComplete(entity, Quests.PRIEST_IN_PERIL) || //not allowed to be anywhere in Morytania + defineAreaBorders()[1].insideBorder(entity) //Werewolf agility course is not implemented + )) { + kickThemOut(entity) + } + } + + private fun kickThemOut(entity: Player) { + val watchdog = NPC(NPCs.ABIDOR_CRANK_3635) + watchdog.isNeverWalks = true + watchdog.isWalks = false + watchdog.location = entity.location + watchdog.init() + entity.lock() + + runTask(watchdog, 1) { + watchdog.moveStep() + watchdog.face(entity) + openDialogue(entity, FuckOffDialogue(), watchdog) + GameWorld.Pulser.submit(object : Pulse() { + override fun pulse(): Boolean { + if (getAttribute(entity, "teleporting-away", false)) + return true + if (!entity.isActive) + poofClear(watchdog) + if (entity.dialogueInterpreter.dialogue == null || entity.dialogueInterpreter.dialogue.file == null) + openDialogue(entity, FuckOffDialogue(), watchdog) + return !watchdog.isActive || !entity.isActive + } + }) + } + } + + class FuckOffDialogue : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when(stage) { + 0 -> npcl(core.game.dialogue.FacialExpression.WORRIED, "Oh this is no good, you surely will not survive here. Let me take you back.").also { stage++ } + 1 -> { + end() + visualize(npc!!, 1818, 343) + sendGraphics(342, player!!.location) + setAttribute(player!!, "teleporting-away", true) + runTask(player!!, 3) { + poofClear(npc!!) + teleport(player!!, Location.create(3402, 3485, 0)) + unlock(player!!) + removeAttribute(player!!, "teleporting-away") + } + } + + } + } + } +} + + diff --git a/Server/src/main/content/region/morytania/handlers/MorytaniaListeners.kt b/Server/src/main/content/region/morytania/handlers/MorytaniaListeners.kt new file mode 100644 index 0000000..0cd82fe --- /dev/null +++ b/Server/src/main/content/region/morytania/handlers/MorytaniaListeners.kt @@ -0,0 +1,100 @@ +package content.region.morytania.handlers + +import core.api.* +import content.global.skill.agility.AgilityHandler +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch +import org.rs09.consts.NPCs +import org.rs09.consts.Scenery +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import kotlin.random.Random +import content.data.Quests + +/** + * File to be used for anything Morytania related. + * Handles the summoning/altar cave enter and exit in Morytania. + * @author Sir Kermit + */ + +class MorytaniaListeners : InteractionListener { + + val SWAMP_GATES = intArrayOf(Scenery.GATE_3506, Scenery.GATE_3507) + val GROTTO_EXIT = intArrayOf(3525, 3526) + val GROTTO_BRIDGE = 3522 + val outside = Location.create(3439, 3337, 0) + val inside = Location.create(3442, 9734, 1) + + private val swimAnim = Animation(6988) + private val jumpAnim = Animation(1603) + private val failWater = Location(3439,3330) + private val failMessage = "You nearly drown in the disgusting swamp." + private val splashGFX = Graphics(68) + + override fun defineListeners() { + + on(SWAMP_GATES, IntType.SCENERY, "open"){ player, node -> + if(player.location.y == 3457){ + core.game.global.action.DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + GlobalScope.launch { + findLocalNPC(player, NPCs.ULIZIUS_1054)?.sendChat("Oh my! You're still alive!", 2) + } + } else { + if (player.questRepository.hasStarted(Quests.NATURE_SPIRIT)) { + core.game.global.action.DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else { + sendNPCDialogue( + player, + NPCs.ULIZIUS_1054, + "I'm sorry, but I'm afraid it's too dangerous to let you through this gate right now." + ) + } + } + return@on true + } + + on(GROTTO_EXIT, IntType.SCENERY, "exit"){ player, node -> + player.teleport(outside) + return@on true + } + + on(GROTTO_BRIDGE, IntType.SCENERY, "jump"){ player, node -> + val start = node.location + var failLand = Location(3438,3331) + var failAnim = Animation(770) + var fromGrotto = false + + lock(player,10) + + // Switch to south facing animations if jumping from Grotto + if (start.y == 3331) { + fromGrotto = true + failAnim = Animation(771) + failLand = Location(3438,3328) + } + if (AgilityHandler.hasFailed(player, 1, 0.1)) { + val end = if (fromGrotto) failWater else start + AgilityHandler.forceWalk(player, -1, start, end, failAnim, 15, 0.0, null,0).endAnimation = swimAnim + AgilityHandler.forceWalk(player, -1, failWater, failLand, swimAnim, 15, 2.0, null,3) + submitIndividualPulse(player, object : Pulse(2){ + override fun pulse(): Boolean { + visualize(player,failAnim,splashGFX) + teleport(player,failWater) + // Deal 1-6 damage but wait until the player is back on land + AgilityHandler.fail(player,0,failLand,swimAnim,Random.nextInt(1,7),failMessage) + return true + } + }) + } + else{ + val end = if (fromGrotto) start.transform(0,-3,0) else start.transform(0,3,0) + AgilityHandler.forceWalk(player, -1, start, end, jumpAnim, 15, 15.0, null,0) + } + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/morytania/handlers/MoyrtniaSwampPlugin.java b/Server/src/main/content/region/morytania/handlers/MoyrtniaSwampPlugin.java new file mode 100644 index 0000000..69e663f --- /dev/null +++ b/Server/src/main/content/region/morytania/handlers/MoyrtniaSwampPlugin.java @@ -0,0 +1,30 @@ +package content.region.morytania.handlers; + +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the mortynia swamp plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class MoyrtniaSwampPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(3506).getHandlers().put("option:open", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + player.getDialogueInterpreter().sendDialogue("There's a message attached to this gate, it reads:~", "~ Mort Myre is a dangerous Ghast infested swamp. ~", "~ Do not enter if you value your life. ~", "~ All persons wishing to enter must see Drezel. ~"); + return true; + } + +} diff --git a/Server/src/main/content/region/morytania/handlers/PyreSitePlugin.java b/Server/src/main/content/region/morytania/handlers/PyreSitePlugin.java new file mode 100644 index 0000000..d21b400 --- /dev/null +++ b/Server/src/main/content/region/morytania/handlers/PyreSitePlugin.java @@ -0,0 +1,423 @@ +package content.region.morytania.handlers; + +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.npc.drop.DropFrequency; +import core.game.node.entity.player.Player; +import core.game.node.entity.skill.Skills; +import content.global.skill.firemaking.Log; +import content.data.skill.SkillingTool; +import core.game.node.item.ChanceItem; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.tools.RandomFunction; +import org.rs09.consts.Items; +import core.game.world.GameWorld; +import core.game.world.repository.Repository; +import core.plugin.ClassScanner; + +import java.util.ArrayList; +import java.util.List; + +/** + * Handles the pyre site plugin. + * @author Vexia + */ +@Initializable +public final class PyreSitePlugin extends OptionHandler { + + /** + * The chance reward items. + */ + private static final ChanceItem[] REWARDS = new ChanceItem[] { new ChanceItem(560, 8, 15, DropFrequency.COMMON), new ChanceItem(565, 4, 7, DropFrequency.COMMON), new ChanceItem(1601, 2, 2, DropFrequency.UNCOMMON), new ChanceItem(532, 10, 10, DropFrequency.RARE), new ChanceItem(100, 2, 2, DropFrequency.COMMON), new ChanceItem(9145, 5, 5, DropFrequency.COMMON), new ChanceItem(9144, 10, 10, DropFrequency.UNCOMMON), new ChanceItem(892, 10, 10, DropFrequency.COMMON), new ChanceItem(867, 20, 20, DropFrequency.UNCOMMON), new ChanceItem(816, 20, 20, DropFrequency.COMMON), new ChanceItem(9419, 1, 1, DropFrequency.COMMON) }; + + /** + * The chewed bones item. + */ + private static final Item CHEWED_BONES = new Item(Items.CHEWED_BONES_11338); + + /** + * The mangled bones item. + */ + private static final Item MANGLED_BONES = new Item(Items.MANGLED_BONES_11337); + + /** + * The dragon full helm item (1/250) chance. + */ + private static final Item DFH = new Item(Items.DRAGON_FULL_HELM_11335); + + /** + * The list of used pyre ship locations. + */ + private static final List USED_LOCATIONS = new ArrayList<>(20); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(25286).getHandlers().put("option:construct", this); + ClassScanner.definePlugin(new FerociousBarbarianNPC()); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + for (Location l : USED_LOCATIONS) { + if (l.withinDistance(node.getLocation(), 3)) { + player.sendMessage("This pyre site is in use currently."); + return true; + } + } + if (!player.getInventory().containsItem(CHEWED_BONES) && !player.getInventory().containsItem(MANGLED_BONES)) { + player.sendMessage("You need chewed bones or mangled bones in order to do this."); + return true; + } + if (!player.getInventory().contains(590, 1)) { + player.sendMessage("You need a tinderbox in order to do this."); + return true; + } + final SkillingTool tool = SkillingTool.getHatchet(player); + if (tool == null) { + player.sendMessage("You need an axe in order to do this."); + return true; + } + final LogType type = LogType.getType(player); + if (type == null) { + player.sendMessage("You don't have any logs."); + return true; + } + if (player.getAttribute("barb", null) != null && ((NPC) player.getAttribute("barb")).isActive()) { + player.sendMessage("You must defeat the barbarian spirit first."); + return true; + } + player.setAttribute("logType", type); + ritual(player, node.asScenery()); + return true; + } + + /** + * Handles the pyre ritual. + * @param player the player. + * @param object the ship object. + */ + private void ritual(Player player, Scenery object) { + player.lock(); + USED_LOCATIONS.add(object.getLocation()); + player.faceLocation(object.getLocation()); + GameWorld.getPulser().submit(getPulse(player, object)); + } + + /** + * Gets the ritual pulse. + * @param player the player. + * @param object the object. + * @return the pulse. + */ + private Pulse getPulse(final Player player, final Scenery object) { + final LogType logType = player.getAttribute("logType", LogType.NORMAL); + final SkillingTool tool = SkillingTool.getHatchet(player); + final Item bones = player.getInventory().containsItem(CHEWED_BONES) ? player.getInventory().getItem(CHEWED_BONES) : player.getInventory().getItem(MANGLED_BONES); + return new Pulse(1, player) { + int count; + int objectId = 25288; + + @Override + public boolean pulse() { + if ((count % 6 == 0 || count == 0) && count <= 10 && objectId <= 25291) { + player.animate(getAnimation(tool)); + player.faceLocation(object.getLocation()); + } + if (count % 4 == 0) { + if (objectId == 25291) { + if (player.getInventory().remove(new Item(logType.getLog().getLogId()), bones)) { + player.getAnimator().reset(); + player.getSkills().addExperience(Skills.CRAFTING, logType.getExperiences()[0]); + player.getSkills().addExperience(Skills.FIREMAKING, logType.getExperiences()[1]); + if (bones.getId() == CHEWED_BONES.getId()) { + player.getInventory().add(getRandomItem(player), player); + player.sendMessages("The ancient barbarian is laid to rest. Your future prayer training is blessed,", "as his spirit ascends to a glorious afterlife. Spirits drop an object into your", "pack."); + } else { + final NPC barb = NPC.create(752, object.getLocation().transform(object.getDirection(), 1)); + ((FerociousBarbarianNPC) barb).target = player; + barb.init(); + barb.moveStep(); + player.setAttribute("barb", barb); + player.unlock(); + } + } + } + if (objectId == 25295) { + return true; + } + replace(objectId++, object, player); + } + count++; + return false; + } + + @Override + public void stop() { + super.stop(); + player.unlock(); + replace(25286, object, player); + USED_LOCATIONS.remove(object.getLocation()); + } + }; + } + + /** + * Replaces the pyre site with a new object. + * @param newId the new id. + * @param ship the ship. + */ + private void replace(int newId, Scenery ship, Player player) { + Scenery newShip = new Scenery(newId, getLocation(newId, ship), 10, ship.getLocation().getX() == 2503 ? 4 : 1); + SceneryBuilder.add(newShip); + } + + /** + * Gets the location of where the object should be. + * @param newId the new Id. + * @param ship the ship. + * @return the location. + */ + private Location getLocation(int newId, Scenery ship) { + Location location = ship.getLocation().transform(ship.getDirection(), -2); + if (ship.getLocation().getX() == 2507 || ship.getLocation().getX() == 2519) { + return location.transform(-1, 0, 0); + } else if (ship.getLocation().getX() == 2503) { + return location.transform(-2, -1, 0); + } + return location; + } + + /** + * Gets a random item. + * @param player the player. + * @return the random item. + */ + private Item getRandomItem(Player player) { + if (RandomFunction.random(250) == 10) { + Repository.sendNews(player.getUsername() + " has just received a Dragon Full Helm from the Pyre Ship."); + return DFH; + } + return RandomFunction.getChanceItem(REWARDS); + } + + @Override + public Location getDestination(Node node, Node n) { + if (n instanceof Scenery) { + return n.getLocation().transform(n.getDirection(), 1); + } + return null; + } + + /** + * Gets the animation for the skilling tool. + * @param tool the tool. + * @return the animation. + */ + public Animation getAnimation(final SkillingTool tool) { + Animation animation = null; + switch (tool) { + case BRONZE_AXE: + animation = Animation.create(3291); + break; + case IRON_AXE: + animation = Animation.create(3290); + break; + case STEEL_AXE: + animation = Animation.create(3289); + break; + case BLACK_AXE: + animation = Animation.create(3288); + break; + case MITHRIL_AXE: + animation = Animation.create(3287); + break; + case ADAMANT_AXE: + animation = Animation.create(3286); + break; + case RUNE_AXE: + animation = Animation.create(3285); + break; + case DRAGON_AXE: + animation = Animation.create(3292); + break; + default: + break; + } + return animation; + } + + /** + * A log type for a pyre ship. + * @author Vexia + */ + public enum LogType { + NORMAL(Log.NORMAL, 11, new double[] { 10, 40 }, 1), ACHEY(Log.ACHEY, 11, new double[] { 10, 40 }, 1), OAK(Log.OAK, 25, new double[] { 15, 60 }, 2), WILLOW(Log.WILLOW, 40, new double[] { 22.5, 90 }, 2), TEAK(Log.TEAK, 45, new double[] { 26.2, 105 }, 3), ARCTIC_PINE(Log.ARCTIC_PINE, 52, new double[] { 31.2, 125 }, 3), MAPLE(Log.MAPLE, 55, new double[] { 33.7, 135 }, 3), MAHOGANY(Log.MAHOGANY, 60, new double[] { 39.3, 157.5 }, 3), YEW(Log.YEW, 70, new double[] { 50.6, 202.5 }, 4), MAGIC(Log.MAGIC, 85, new double[] { 75.9, 303.8 }, 5); + + /** + * The log. + */ + private final Log log; + + /** + * The level. + */ + private final int level; + + /** + * The experiences required. + */ + private final double[] experiences; + + /** + * The enhanced xp reward of bones. + */ + private final int enhancedExp; + + /** + * Constructs a new {@Code LogType} {@Code Object} + * @param log the log. + * @param level the level. + * @param experiences the experiences. + * @param enhancedExp the enhanced exp. + */ + private LogType(Log log, int level, double[] experiences, int enhancedExp) { + this.log = log; + this.level = level; + this.experiences = experiences; + this.enhancedExp = enhancedExp; + } + + /** + * Gets a log type. + * @param player the player. + * @return the type. + */ + public static LogType getType(Player player) { + for (LogType type : values()) { + if (player.getInventory().contains(type.getLog().getLogId(), 1)) { + return type; + } + } + return null; + } + + /** + * Gets the blog. + * @return the log + */ + public Log getLog() { + return log; + } + + /** + * Gets the blevel. + * @return the level + */ + public int getLevel() { + return level; + } + + /** + * Gets the bexperiences. + * @return the experiences + */ + public double[] getExperiences() { + return experiences; + } + + /** + * Gets the benhancedExp. + * @return the enhancedExp + */ + public int getEnhancedExp() { + return enhancedExp; + } + + } + + /** + * Handles the ferocious barbarian npc. + * @author Vexia + * + */ + public class FerociousBarbarianNPC extends AbstractNPC { + + /** + * The target npc. + */ + private Player target; + + /** + * Constructs a new {@Code FerociousBarbarianNPC} {@Code Object} + * @param id the npc id. + * @param location the location. + */ + public FerociousBarbarianNPC(int id, Location location) { + super(id, location); + this.setRespawn(false); + this.setAggressive(true); + } + + /** + * Constructs a new {@Code FerociousBarbarianNPC} {@Code Object} + */ + public FerociousBarbarianNPC() { + this(-1, null); + } + + @Override + public void handleTickActions() { + if (target == null) { + return; + } + if (!target.isActive() || !target.getLocation().withinDistance(getLocation())) { + clear(); + } + if (!getProperties().getCombatPulse().isAttacking()) { + getProperties().getCombatPulse().attack(target); + } + } + + @Override + public boolean isAttackable(Entity entity, CombatStyle style, boolean message) { + if (entity instanceof Player && entity != target) { + if(message) { + ((Player) entity).getPacketDispatch().sendMessage("It's not after you."); + } + return false; + } + return super.isAttackable(entity, style, message); + } + + @Override + public void finalizeDeath(Entity killer) { + super.finalizeDeath(killer); + if (killer instanceof Player && killer == target) { + target.removeAttribute("barb"); + } + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new FerociousBarbarianNPC(id, location); + } + + @Override + public int[] getIds() { + return new int[] { 752 }; + } + } +} diff --git a/Server/src/main/content/region/morytania/phas/dialogue/GhostDiscipleDialogue.java b/Server/src/main/content/region/morytania/phas/dialogue/GhostDiscipleDialogue.java new file mode 100644 index 0000000..23d8093 --- /dev/null +++ b/Server/src/main/content/region/morytania/phas/dialogue/GhostDiscipleDialogue.java @@ -0,0 +1,191 @@ +package content.region.morytania.phas.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Initializable; + +/** + * Handles the dialogue used for a ghost disciple. + * @author Vexia + */ +@Initializable +public final class GhostDiscipleDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code GhostDiscipleDialogue} {@code Object}. + */ + public GhostDiscipleDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code GhostDiscipleDialogue} {@code Object}. + * @param player the player. + */ + public GhostDiscipleDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new GhostDiscipleDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + if(args.length > 1){ + final int amount = player.getSavedData().getGlobalData().getEctoCharges() * 5; + final Item tokens = new Item(4278, amount); + if (!player.getInventory().hasSpaceFor(tokens)) { + player("Sorry, I don't have enough inventory space."); + return true; + } + if(amount > 0) { + player.getInventory().add(tokens); + player.getSavedData().getGlobalData().setEctoCharges(0); + npc("Certainly, mortal. Here's " + (amount) + " ectotokens."); + } else { + npc("I'm sorry, but you haven't earned any."); + } + stage = 81; + return true; + } + if (player.getSavedData().getGlobalData().getEctoCharges() > 0) { + player("Can I have the tokens I have earned?"); + stage = 80; + return true; + } + if (player.getLocation().getZ() > 0) { + if (args.length > 1) { + npc("What are you doing going in there?"); + stage = 70; + return true; + } + player("How do I use the bone grinder?"); + stage = 60; + return true; + } + player("What is this strange fountain?"); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + npc("This is the Ectofuntus, the most marvellous creation of", "Necrovarus, our glorious leader."); + stage++; + break; + case 1: + options("What is the Ectofunuts?", "Where do I get ectoplasm from?", "How do I grind bones?", "How do I receive Ectotokens?", "Thanks for your time."); + stage++; + break; + case 2: + switch (buttonId) { + case 1: + player("What is the Ectofunuts?"); + stage = 10; + break; + case 2: + player("Where do I get ectoplasm from?"); + stage = 20; + break; + case 3: + player("How do I grind bones?"); + stage = 30; + break; + case 4: + player("How do I receive Ectotokens?"); + stage = 40; + break; + case 5: + player("Thanks for your time."); + stage = 50; + break; + } + break; + case 10: + npc("It provides the power to keep us ghosts from passing", "over into the next plane of existence."); + stage++; + break; + case 11: + player("And how does it work?"); + stage++; + break; + case 12: + npc("You have to pour a bucket of ectoplasm into the", "fountain, a pot of ground bones, and then worship at", "the Ectofuntus. A unit of unholy power will then be", "created."); + stage = 1; + break; + case 20: + npc("Necrovarus sensed the power bubbling beneath our feet,", "and we delved long and deep beneath Port Phasmatys,", "until we found a pool of natural ectoplasm. You may", "find it by using the trapdoor over there."); + stage = 1; + break; + case 30: + npc("There is a bone grinding machine upstairs. Put bones", "of any type into the machine's hopper, and then turn", "the handle to grind them. You will need a pot to empty", "the machine of ground up bones."); + stage = 1; + break; + case 40: + npc("We disciples keep track of how many units of power", "have been produced. Just talk to us once you have", "generated some and we will reimburse you with the", "correct amount of Ectotokens."); + stage++; + break; + case 41: + player("How do I generate units of power?"); + stage++; + break; + case 42: + npc("You have to pour a bucket of ectoplasm into the", "fountain and then worship at the Ectofuntus with a pot", "of ground bones. This will create a unit of unholy", "power."); + stage = 1; + break; + case 50: + end(); + break; + case 60: + npc("Put bones of any type into the machine's hopper, and", "then turn the handle to grind them. You will need a pot", "to empty the machine of ground up bones."); + stage++; + break; + case 61: + end(); + break; + case 70: + player("Err, I was just curious..."); + stage++; + break; + case 71: + npc("Inside that room is a coffin, inside which lie the mortal", "remains of our most glorious master. Necrovarus.", "None may enter."); + stage++; + break; + case 72: + end(); + break; + case 80: { + final int amount = player.getSavedData().getGlobalData().getEctoCharges() * 5; + final Item tokens = new Item(4278, amount); + if (!player.getInventory().hasSpaceFor(tokens)) { + player("Sorry, I don't have enough inventory space."); + stage++; + break; + } + stage++; + player.getInventory().add(tokens); + player.getSavedData().getGlobalData().setEctoCharges(0); + npc("Certainly, mortal. Here's " + (amount) + " ectotokens."); + break; + } + case 81: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 1686 }; + } + +} diff --git a/Server/src/main/content/region/morytania/phas/dialogue/GhostInkeeperDialogue.java b/Server/src/main/content/region/morytania/phas/dialogue/GhostInkeeperDialogue.java new file mode 100644 index 0000000..107cc98 --- /dev/null +++ b/Server/src/main/content/region/morytania/phas/dialogue/GhostInkeeperDialogue.java @@ -0,0 +1,146 @@ +package content.region.morytania.phas.dialogue; + +import core.game.dialogue.DialoguePlugin; +import content.region.morytania.phas.handlers.PhasmatysZone; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; + +/** + * Handles the ghost inkeeper dialogue. + * @author Vexia + */ +@Initializable +public class GhostInkeeperDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code GhostInkeeperDialogue} {@code Object}. + * @param player the player. + */ + public GhostInkeeperDialogue(final Player player) { + super(player); + } + + /** + * Constructs a new {@code GhostInkeeperDialogue} {@code Object}. + */ + public GhostInkeeperDialogue() { + /** + * empty. + */ + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new GhostInkeeperDialogue(player); + } + + @Override + public boolean open(Object... args) { + if (PhasmatysZone.hasAmulet(player)) { + player("Hello there!"); + } else { + npc("Woooo wooo wooooo woooo"); + stage = 10; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + npc("Greetings, traveller. Welcome to 'The Green Ghost'", "Tavern. What can I do you for?"); + stage++; + break; + case 1: + options("Can I buy a beer?", "Can I hear some gossip?", "What happened to the folk of this town?", "Do you have any jobs I can do?", "Nothing, thanks."); + stage++; + break; + case 2: + switch (buttonId) { + case 1: + player("Can I buy a beer?"); + stage = 3; + break; + case 2: + player("Can I hear some gossip?"); + stage = 20; + break; + case 3: + player("What happened to the folk of this town?"); + stage = 30; + break; + case 4: + player("Do you have any jobs I can do?"); + stage = 40; + break; + case 5: + player("Nothing, thanks."); + stage = 50; + break; + } + break; + case 3: + npc("Sorry, but our pumps dried up over half a century", "ago. We of this village do not have much of a thirst", "these days."); + stage++; + break; + case 4: + end(); + break; + case 20: + npc("I suppose, as long as you keep it to yourself..."); + stage++; + break; + case 21: + npc("You see Gravingas out there in the marketplace? He", "speaks for the silent majoirty of Port Phasmatys, for", "those of us who would prefer to pass over into the next", "world."); + stage++; + break; + case 22: + npc("But old Gravingas is far too obvious in his methods.", "Now Velorina, she's a ghost of a different colour", "altogether. If you feel like helping our cause at all, go", "speak to Velorina."); + stage++; + break; + case 23: + end(); + break; + case 30: + npc("That's a long story, my friend, but you look like you", "have the time..."); + stage++; + break; + case 31: + player("Nope, you are right. I am very busy!");// .. Might need future revision + stage++; + break; + case 32: + end(); + break; + case 40: + npc("Yes, actually, I do. We have a very famous Master", "Bowman named Robin staying with us at the moment.", "Could you take him some clean bed linen for me?"); + stage++; + break; + case 41: + npc("No, I didn't mean a job like that."); + stage++; + break; + case 42: + end(); + break; + case 50: + end(); + break; + case 10: + interpreter.sendDialogue("You cannot understand the ghost."); + stage++; + break; + case 11: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 1700 }; + } + +} diff --git a/Server/src/main/content/region/morytania/phas/dialogue/GhostSailorDialogue.java b/Server/src/main/content/region/morytania/phas/dialogue/GhostSailorDialogue.java new file mode 100644 index 0000000..55a1f6e --- /dev/null +++ b/Server/src/main/content/region/morytania/phas/dialogue/GhostSailorDialogue.java @@ -0,0 +1,86 @@ +package content.region.morytania.phas.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import content.region.morytania.phas.handlers.PhasmatysZone; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; + +/** + * Represents the ghost sailor dialogue plugin. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class GhostSailorDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code GhostSailorDialogue} {@code Object}. + */ + public GhostSailorDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code GhostSailorDialogue} {@code Object}. + * @param player the player. + */ + public GhostSailorDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new GhostSailorDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + if (PhasmatysZone.hasAmulet(player)) { + player("Hi there. Why do you still bother having ships here? I", "mean - you're dead, what use are they to you?"); + stage = 1; + } else { + interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Woooo wooo wooooo woooo"); + stage = 10; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 1: + npc("We keep ships because we still need trade in", "Phasmatys. Every trader that comes to Phastmatys is", "made to worship the Ectofuntus, so that the Ectopower", "doesn't run out."); + stage++; + break; + case 2: + player("So, without traders to worship in the Temple you're", "history right?"); + stage++; + break; + case 3: + npc("Aye, matey."); + stage++; + break; + case 4: + end(); + break; + case 10: + interpreter.sendDialogue("You cannot understand the ghost."); + stage = 11; + break; + case 11: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 1703, 1704 }; + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/morytania/phas/dialogue/GhostShopKeeperDialogue.java b/Server/src/main/content/region/morytania/phas/dialogue/GhostShopKeeperDialogue.java new file mode 100644 index 0000000..da88f66 --- /dev/null +++ b/Server/src/main/content/region/morytania/phas/dialogue/GhostShopKeeperDialogue.java @@ -0,0 +1,88 @@ +package content.region.morytania.phas.dialogue; + +import content.region.morytania.phas.handlers.PhasmatysZone; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents the Ghost shop keeper dialogue in Port Phasmatys in Mortaniya. + */ +@Initializable +public final class GhostShopKeeperDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code GhostShopKeeperDialogue} {@code Object}. + */ + public GhostShopKeeperDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code GhostShopKeeperDialogue} {@code Object}. + * @param player the player. + */ + public GhostShopKeeperDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new GhostShopKeeperDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + if (PhasmatysZone.hasAmulet(player)) { + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "Can I help you at all?"); + stage = 0; + } else { + interpreter.sendDialogues(npc, FacialExpression.FRIENDLY, "Woooo wooo wooooo woooo"); + stage = 10; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + interpreter.sendOptions("Select an Option", "Yes, please. What are you selling?", "How should I use your shop?", "No, thanks."); + stage = 1; + break; + case 1: + switch (buttonId) { + case 1: + end(); + npc.openShop(player); + break; + case 2: + interpreter.sendDialogues(npc, FacialExpression.HAPPY, "I'm glad you ask! You can buy as many of the items", "stocked as you wish. You can also sell most items to the", "shop."); + stage = 3; + break; + case 3: + end(); + break; + } + break; + case 10: + interpreter.sendDialogue( "You cannot understand the ghost."); + stage = 11; + break; + case 11: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 1699 }; + } +} diff --git a/Server/src/main/content/region/morytania/phas/dialogue/GhostVillagerDialogue.java b/Server/src/main/content/region/morytania/phas/dialogue/GhostVillagerDialogue.java new file mode 100644 index 0000000..759c66f --- /dev/null +++ b/Server/src/main/content/region/morytania/phas/dialogue/GhostVillagerDialogue.java @@ -0,0 +1,78 @@ +package content.region.morytania.phas.dialogue; + +import core.game.dialogue.DialoguePlugin; +import content.region.morytania.phas.handlers.PhasmatysZone; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.tools.RandomFunction; + +/** + * Handles the ghost villager dialogue. + * @author Vexia + */ + +@Initializable +public final class GhostVillagerDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code GhostVillagerDialogue} {@code Object}. + */ + public GhostVillagerDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code GhostVillagerDialogue} {@code Object}. + * @param player the player. + */ + public GhostVillagerDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new GhostVillagerDialogue(player); + } + + @Override + public boolean open(Object... args) { + if (PhasmatysZone.hasAmulet(player)) { + final int random = RandomFunction.random(10); + switch (random) { + default: + npc("What do you want, mortal?"); + break; + } + } else { + npc("Woooo wooo wooooo woooo"); + stage = 10; + } + + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + end(); + break; + case 10: + interpreter.sendDialogue("You cannot understand the ghost."); + stage++; + break; + case 11: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 1697 }; + } + +} diff --git a/Server/src/main/content/region/morytania/phas/dialogue/NecrovarusDialogue.java b/Server/src/main/content/region/morytania/phas/dialogue/NecrovarusDialogue.java new file mode 100644 index 0000000..3283cd8 --- /dev/null +++ b/Server/src/main/content/region/morytania/phas/dialogue/NecrovarusDialogue.java @@ -0,0 +1,89 @@ +package content.region.morytania.phas.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; + +/** + * Handles the dialogue used for necrovarus. + * @author Vexia + */ +public final class NecrovarusDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code NecrovarusDialogue} {@code Object}. + */ + public NecrovarusDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code NecrovarusDialogue} {@code Object}. + * @param player the player. + */ + public NecrovarusDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new NecrovarusDialogue(player); + } + + @Override + public boolean open(Object... args) { + options("What is this place?", "What happened to everyone here?", "How do I get into the town?"); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + switch (buttonId) { + case 1: + player("What is this place?"); + stage = 10; + break; + case 2: + player("What happened to everyone here?"); + stage = 20; + break; + case 3: + player("How do I get into the town?"); + stage = 30; + break; + } + break; + case 10: + npc("Speak to me again and I will rend the soul from your", "flesh."); + stage++; + break; + case 11: + end(); + break; + case 20: + npc("You dare to speak to me??? Have you lost your", "wits????"); + stage++; + break; + case 21: + end(); + break; + case 30: + npc("I do not answer questions, mortal fool!"); + stage++; + break; + case 31: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 1684 }; + } + +} diff --git a/Server/src/main/content/region/morytania/phas/dialogue/VelorinaDialogue.java b/Server/src/main/content/region/morytania/phas/dialogue/VelorinaDialogue.java new file mode 100644 index 0000000..2407c17 --- /dev/null +++ b/Server/src/main/content/region/morytania/phas/dialogue/VelorinaDialogue.java @@ -0,0 +1,75 @@ +package content.region.morytania.phas.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.game.node.item.Item; + +/** + * Handles the velorina dialogue. + * @author Vexia + */ +@Initializable +public class VelorinaDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code VelorinaDialogue} {@code Object} + */ + public VelorinaDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code VelorinaDialogue} {@code Object} + * @param player the player. + */ + public VelorinaDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new VelorinaDialogue(player); + } + + @Override + public boolean open(Object... args) { + player("Can I have another ectophial?"); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + if (player.hasItem(new Item(4251)) || player.hasItem(new Item(4252))) { + npc("You already have an ectophial."); + stage = 1; + return true; + } + npc("Of course you can, you have helped us more than we", "could ever have hoped."); + stage = 2; + break; + case 1: + end(); + break; + case 2: + interpreter.sendItemMessage(4251, "Velorina gives you a vial of bright green ectoplasm."); + stage++; + break; + case 3: + player.getInventory().add(new Item(4251), player); + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 1683 }; + } + +} diff --git a/Server/src/main/content/region/morytania/phas/handlers/BoneGrinderListener.kt b/Server/src/main/content/region/morytania/phas/handlers/BoneGrinderListener.kt new file mode 100644 index 0000000..9f333e5 --- /dev/null +++ b/Server/src/main/content/region/morytania/phas/handlers/BoneGrinderListener.kt @@ -0,0 +1,264 @@ +package content.region.morytania.phas.handlers + +import content.global.skill.prayer.Bones +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.node.entity.impl.PulseType +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.game.world.GameWorld.Pulser +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items +import org.rs09.consts.Scenery +import org.rs09.consts.Sounds + +private const val LOADER = Scenery.LOADER_11162 +private const val BONE_GRINDER = Scenery.BONE_GRINDER_11163 +private const val BIN = Scenery.BIN_11164 + +private const val LOADED_BONE_KEY = "/save:bonegrinder-bones" +private const val BONE_HOPPER_KEY = "/save:bonegrinder-hopper" +private const val BONE_BIN_KEY = "/save:bonegrinder-bin" + +private val FILL_ANIM = Animation(1649) +private val WIND_ANIM = Animation(1648) +private val SCOOP_ANIM = Animation(1650) + +class BoneGrinderListener : InteractionListener { + + private val boneIDs = Bones.values().map { it.itemId }.toIntArray() + + override fun defineListeners() { + + /** + * Handle the bone loader/hopper fill option + */ + on(LOADER, IntType.SCENERY, "fill"){ player, _ -> + handleFill(player) + } + + /** + * Handle the wheel's wind option + */ + on(BONE_GRINDER, IntType.SCENERY, "wind"){ player, _ -> + handleWind(player) + } + + /** + * Handle the wheel's status option + */ + on(BONE_GRINDER, IntType.SCENERY, "status"){ player, _ -> + handleStatus(player) + } + + /** + * Handle the bin's empty option + */ + on(BIN, IntType.SCENERY, "empty"){ player, _ -> + handleEmpty(player) + } + + /** + * Handle Bone -> Hopper + */ + onUseWith(IntType.SCENERY, LOADER,*boneIDs){ player, _, _ -> + handleFill(player) + return@onUseWith true + } + + } + + fun handleFill(player: Player): Boolean{ + val bone = getBone(player) + if((bone == null) || (bone.bonemealId == null)) { + if (inInventory(player, Items.MARINATED_J_BONES_3130) || inInventory(player, Items.MARINATED_J_BONES_3133)) { + sendDialogue(player, "These bones could break the bone grinder. Perhaps I should find some different bones.") + } else { + sendMessage(player, "You have no bones to grind.") + } + return true + } + if(getAttribute(player, BONE_HOPPER_KEY,false)){ + sendMessage(player,"You already have some bones in the hopper.") + return true + } + if(getAttribute(player, BONE_BIN_KEY,false)){ + sendMessage(player,"You already have some bonemeal that needs to be collected.") + return true + } + + val fillPulse = object: Pulse(){ + var stage = 0 + override fun pulse(): Boolean { + when(stage++){ + 0 -> { + lock(player, FILL_ANIM.duration) + animate(player, FILL_ANIM) + playAudio(player, Sounds.FILL_GRINDER_1133) + } + FILL_ANIM.duration -> { + sendMessage(player,"You fill the hopper with bones.") + removeItem(player,Item(bone.itemId),Container.INVENTORY) + setAttribute(player, LOADED_BONE_KEY,bone.ordinal) + setAttribute(player, BONE_HOPPER_KEY,true) + return true + } + } + return false + } + } + + if(inInventory(player,bone.itemId)){ + player.pulseManager.run(object : Pulse(){ + var stage = 0 + override fun pulse(): Boolean { + when(stage++){ + 0 -> Pulser.submit(fillPulse).also { delay = FILL_ANIM.duration + 1} + 1 -> { + stopWalk(player) + forceWalk(player,Location(3659,3524),"smart") + delay = 2 + } + 2 -> { + handleWind(player) + delay = WIND_ANIM.duration + 1 + } + 3 -> { + stopWalk(player) + forceWalk(player,Location(3658,3524),"smart") + delay = 2 + } + 4 -> { + if(!inInventory(player,Items.EMPTY_POT_1931,1)){ + return handleEmpty(player) + } else { + handleEmpty(player) + delay = SCOOP_ANIM.duration + 1 + } + } + 5 -> { + stopWalk(player) + forceWalk(player,Location(3660,3524),"smart") + delay = 4 + } + 6 -> { + face(player,Location(3660,3526)) + handleFill(player) + return true + } + } + return false + } + }) + } else { + player.pulseManager.run(fillPulse, PulseType.CUSTOM_1) + } + return true + } + + fun handleWind(player: Player): Boolean{ + if(!getAttribute(player, BONE_HOPPER_KEY,false)){ + sendMessage(player,"You have no bones loaded to grind.") + return true + } + + if(getAttribute(player, BONE_BIN_KEY,false)){ + sendMessage(player,"You already have some bonemeal which you need to collect.") + return true + } + + player.pulseManager.run(object : Pulse(){ + var stage = 0 + override fun pulse(): Boolean { + when(stage++){ + 0 -> { + face(player,Location(3659, 3526, 1)) + lock(player, WIND_ANIM.duration) + animate(player, WIND_ANIM) + sendMessage(player,"You wind the handle.") + playAudio(player, Sounds.GRINDER_GRINDING_1131) + } + WIND_ANIM.duration -> { + sendMessage(player,"The bonemeal falls into the bin.") + setAttribute(player, BONE_HOPPER_KEY,false) + setAttribute(player, BONE_BIN_KEY,true) + return true + } + } + return false + } + }, PulseType.CUSTOM_1) + return true + } + + private fun handleStatus(player: Player): Boolean{ + val bonesLoaded = getAttribute(player, BONE_HOPPER_KEY,false) + val boneMealReady = getAttribute(player, BONE_BIN_KEY,false) + + if(bonesLoaded) sendMessage(player,"There are bones waiting in the hopper.") + if(boneMealReady) sendMessage(player,"There is bonemeal waiting in the bin to be collected.") + + if(!bonesLoaded && !boneMealReady){ + sendMessage(player,"There is nothing loaded into the machine.") + } + + return true + } + + fun handleEmpty(player: Player): Boolean { + val inHopper = getAttribute(player, BONE_HOPPER_KEY, false) + val boneType = getAttribute(player, LOADED_BONE_KEY, -1) + val hasMeal = getAttribute(player, BONE_BIN_KEY, false) && boneType != -1 + + if(!hasMeal){ + if (inHopper) + sendMessage(player,"You need to wind the wheel to grind the bones.") + else if (boneType == -1) + sendMessage(player, "You need to load some bones in the hopper first.") + else + sendMessage(player,"You have no bonemeal to collect.") + return true + } + + if(!inInventory(player,Items.EMPTY_POT_1931,1)){ + sendMessage(player,"You don't have any pots to take the bonemeal with.") + return true + } + + val bone = Bones.values()[boneType] + + removeAttributes(player, BONE_HOPPER_KEY, BONE_BIN_KEY, LOADED_BONE_KEY) + lock(player, SCOOP_ANIM.duration + 1) + + player.pulseManager.run(object : Pulse(){ + var stage = 0 + override fun pulse(): Boolean { + when(stage++){ + 0 -> { + face(player,Location(3658, 3525, 1)) + animate(player, SCOOP_ANIM) + playAudio(player, Sounds.GRINDER_EMPTY_1136) + } + SCOOP_ANIM.duration -> { + if(removeItem(player,Item(Items.EMPTY_POT_1931),Container.INVENTORY)){ + addItem(player, bone.bonemealId!!) + } + return true + } + } + return false + } + }, PulseType.CUSTOM_1) + return true + } + + fun getBone(player: Player): Bones? { + for(bone in Bones.values()){ + if(inInventory(player,bone.itemId)) return bone + } + return null + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/morytania/phas/handlers/EctoplasmFillPlugin.java b/Server/src/main/content/region/morytania/phas/handlers/EctoplasmFillPlugin.java new file mode 100644 index 0000000..46000fc --- /dev/null +++ b/Server/src/main/content/region/morytania/phas/handlers/EctoplasmFillPlugin.java @@ -0,0 +1,63 @@ +package content.region.morytania.phas.handlers; + +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.UseWithHandler; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playAudio; + +/** + * Handles the ectoplasm filling. + * @author Vexia + */ +public class EctoplasmFillPlugin extends UseWithHandler { + + /** + * The object ids of the slime. + */ + private static final int[] OBJECTS = new int[] { 5461, 17116, 17117, 17118, 17119 }; + + /** + * Constructs a new {@code EctoplasmFillPlugin} {@code Object}. + */ + public EctoplasmFillPlugin() { + super(1925); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (int id : OBJECTS) { + addHandler(id, OBJECT_TYPE, this); + } + return this; + } + + @Override + public boolean handle(NodeUsageEvent event) { + final Player player = event.getPlayer(); + player.animate(Animation.create(4471)); + playAudio(player, Sounds.FILL_ECTOPLASM_1132); + player.getPacketDispatch().sendMessage("You fill the bucket with ectoplasm."); + player.getPulseManager().run(new Pulse(3, player) { + @Override + public boolean pulse() { + if (player.getInventory().remove(new Item(1925, 1))) { + player.getInventory().add(new Item(4286)); + if (player.getInventory().contains(1925, 1)) { + player.animate(Animation.create(4471), 1); + playAudio(player, Sounds.FILL_ECTOPLASM_1132); + return false; + } + } + return !player.getInventory().contains(1925, 1); + } + }); + return true; + } + +} diff --git a/Server/src/main/content/region/morytania/phas/handlers/GravingasNPC.java b/Server/src/main/content/region/morytania/phas/handlers/GravingasNPC.java new file mode 100644 index 0000000..171ce93 --- /dev/null +++ b/Server/src/main/content/region/morytania/phas/handlers/GravingasNPC.java @@ -0,0 +1,134 @@ +package content.region.morytania.phas.handlers; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.plugin.Plugin; +import core.plugin.ClassScanner; +import core.tools.RandomFunction; + +/** + * Handles the gravingas npc. + * @author Vexia + */ +public final class GravingasNPC extends AbstractNPC { + + /** + * The force chats. + */ + private static final String[] CHATS = new String[] { "Down with Necrovaus!!", "Rise up my fellow ghosts, and we shall be victorious!", "Power to the Ghosts!!", "Rise together, Ghosts without a cause!!", "United we conquer - divided we fall!!", "We shall overcome!!", "Let Necrovarus know we want out!!", "Don't stay silent - victory in numbers!!" }; + + /** + * Constructs a new {@code GravingasNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + public GravingasNPC(int id, Location location) { + super(id, location); + } + + /** + * Constructs a new {@code GravingasNPC} {@code Object}. + */ + public GravingasNPC() { + super(0, null); + } + + @Override + public void handleTickActions() { + super.handleTickActions(); + if (RandomFunction.random(45) == 5) { + sendChat(CHATS[RandomFunction.random(CHATS.length)]); + } + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new GravingasNPC(id, location); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ClassScanner.definePlugin(new GravingasDialogue()); + return super.newInstance(arg); + } + + @Override + public int[] getIds() { + return new int[] { 1685 }; + } + + /** + * Handles the gravingas dialogue. + * @author Vexia + */ + public final class GravingasDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code GravingasDialogue} {@code Object}. + * @param player the player. + */ + public GravingasDialogue(final Player player) { + super(player); + } + + /** + * Constructs a new {@code GravingasDialogue} {@code Object}. + */ + public GravingasDialogue() { + /** + * empty. + */ + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new GravingasDialogue(player); + } + + @Override + public boolean open(Object... args) { + if (PhasmatysZone.hasAmulet(player)) { + npc("Will you join with me and protect against the evil ban", "of Nercrovarus and his disciples?"); + stage = 0; + } else { + npc("Woooo wooo wooooo woooo"); + stage = 10; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + player("I'm sorry, I don't really think I should get involved."); + stage++; + break; + case 1: + npc("Ah, the youth of today - so apathetic to politics."); + stage++; + break; + case 2: + end(); + break; + case 10: + interpreter.sendDialogue("You cannot understand the ghost."); + stage = 11; + break; + case 11: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return GravingasNPC.this.getIds(); + } + + } + +} diff --git a/Server/src/main/content/region/morytania/phas/handlers/PhasmatysZone.java b/Server/src/main/content/region/morytania/phas/handlers/PhasmatysZone.java new file mode 100644 index 0000000..70131a4 --- /dev/null +++ b/Server/src/main/content/region/morytania/phas/handlers/PhasmatysZone.java @@ -0,0 +1,218 @@ +package content.region.morytania.phas.handlers; + +import content.global.skill.agility.AgilityHandler; +import content.global.skill.prayer.Bones; +import content.region.morytania.phas.dialogue.NecrovarusDialogue; +import core.game.global.action.ClimbActionHandler; +import core.game.interaction.Option; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.skill.Skills; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneBuilder; +import core.game.world.update.flag.context.Animation; +import core.plugin.ClassScanner; +import core.plugin.Initializable; +import core.plugin.Plugin; +import org.rs09.consts.NPCs; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playAudio; +import static core.api.ContentAPIKt.sendMessage; + +/** + * Handles the phasmatys zone area. + * + * @author Vexia + */ +@Initializable +public final class PhasmatysZone extends MapZone implements Plugin { + int b; + Bones[] bones; + Player player; + Bones bone; + + /** + * Constructs a new {@code PhasmatysZone} {@code Object}. + */ + public PhasmatysZone() { + super("Port phasmatys", true); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ZoneBuilder.configure(this); + ClassScanner.definePlugin(new GravingasNPC()); + ClassScanner.definePlugin(new NecrovarusDialogue()); + ClassScanner.definePlugin(new EctoplasmFillPlugin()); + return this; + } + + @Override + public boolean interact(Entity e, Node target, Option option) { + if (e.isPlayer()) { + player = e.asPlayer(); + if (target instanceof NPC) { + NPC npc = (NPC) target; + + if (npc.getId() == NPCs.GHOST_BANKER_1702) { + // Kludge to prevent this module from overriding NPC + // handling until I rip this piece of Vexia shit out. + return false; + } + + if ((npc.getName().toLowerCase().contains("ghost") || npc.getName().equalsIgnoreCase("velorina") || npc.getName().contains("husband")) && !hasAmulet(player)) { + //player.getDialogueInterpreter().open("ghosty dialogue", target); // Commented for ghost npcs to work from their individual plugin files + player.getDialogueInterpreter().open(target.getId() , target); + return true; + } + } + switch (target.getId()) { + case 5259: + handleEnergyBarrier(player, (Scenery) target); + return true; + case 5267: + player.animate(Animation.create(536)); + sendMessage(player, "The trapdoor opens..."); + SceneryBuilder.replace((Scenery) target, ((Scenery) target).transform(5268)); + return true; + case 5268: + if (option.getName().equals("Close")) { + player.animate(Animation.create(535)); + sendMessage(player, "You close the trapdoor."); + SceneryBuilder.replace((Scenery) target, ((Scenery) target).transform(5267)); + } else { + sendMessage(player, "You climb down through the trapdoor..."); + player.getProperties().setTeleportLocation(Location.create(3669, 9888, 3)); + } + return true; + case 7434: // Trapdoors in bar + if (option.getName().equalsIgnoreCase("open")) { + SceneryBuilder.replace(target.asScenery(), target.asScenery().transform(7435)); + } + break; + case 7435: // open trapdoor in bar + if (option.getName().equalsIgnoreCase("close")) { + SceneryBuilder.replace(target.asScenery(), target.asScenery().transform(7434)); + } + break; + case 9308: + if (player.getSkills().getStaticLevel(Skills.AGILITY) < 58) { + player.sendMessage("You need an agility level of at least 58 to climb down this wall."); + return true; + } + player.getProperties().setTeleportLocation(Location.create(3671, 9888, 2)); + return true; + case 9307: + if (player.getSkills().getStaticLevel(Skills.AGILITY) < 58) { + player.sendMessage("You need an agility level of at least 58 to climb up this wall."); + return true; + } + player.getProperties().setTeleportLocation(Location.create(3670, 9888, 3)); + return true; + case 5264: + ClimbActionHandler.climb(player, Animation.create(828), Location.create(3654, 3519, 0)); + return true; + case 5282: + worship(player); + return true; + } + } + return super.interact(e, target, option); + } + + /** + * Checks if the player has the amulet equipped. + * + * @param player the player. + * @return {@code True} if so. + */ + public static boolean hasAmulet(Player player) { + return player.getEquipment().contains(552, 1); + } + + /** + * Worships the ectofuntus. + * + * @param player the player. + */ + private void worship(Player player) { + Bones bone = null; + for (Item i : player.getInventory().toArray()) { + if (i == null) { + continue; + } + Bones b = Bones.forBoneMeal(i.getId()); + if (b != null) { + bone = b; + break; + } + } + if (!player.getInventory().contains(4286, 1) && bone == null) { + player.getDialogueInterpreter().sendDialogue("You don't have any ectoplasm or crushed bones to put into the", "Ectofuntus."); + return; + } + if (bone == null) { + player.getDialogueInterpreter().sendDialogue("You need a pot of crushed bones to put into the Ectofuntus."); + return; + } + if (!player.getInventory().contains(4286, 1)) { + player.getDialogueInterpreter().sendDialogue("You need ectoplasm to put into the Ectofuntus."); + return; + } + if (player.getInventory().remove(new Item(bone.getBonemealId()), new Item(4286, 1))) { + player.lock(1); + player.animate(Animation.create(1651)); + playAudio(player, Sounds.PRAYER_BOOST_2671); + player.getInventory().add(new Item(1925), new Item(1931)); + player.getSkills().addExperience(Skills.PRAYER, bone.getExperience() * 4, true); + player.sendMessage("You put some ectoplasm and bonemeal into the Ectofuntus, and worship it."); + player.getSavedData().getGlobalData().setEctoCharges(player.getSavedData().getGlobalData().getEctoCharges() + 1); + } + } + + /** + * Handles the passing of the energy barrier. + * + * @param player the player. + * @param object the object. + */ + private void handleEnergyBarrier(Player player, Scenery object) { + boolean force = object.getLocation().equals(3659, 3508, 0) && player.getLocation().getY() < 3508 || object.getLocation().equals(3652, 3485, 0) && player.getLocation().getX() > 3652; + if (!force && !player.getInventory().contains(4278, 2)) { + player.getDialogueInterpreter().open(1706); + return; + } + if (force || player.getInventory().remove(new Item(4278, 2))) { + final Direction direction = Direction.getLogicalDirection(player.getLocation(), object.getLocation()); + Location end = player.getLocation().transform(direction, 2); + if (player.getLocation().getY() >= 3508) { + end = object.getLocation().transform(0, -2, 0); + } + if (object.getLocation().equals(new Location(3652, 3485, 0))) { + end = object.getLocation().transform(player.getLocation().getX() >= 3653 ? -1 : 2, 0, 0); + } + AgilityHandler.walk(player, -1, player.getLocation(), end, null, 0.0, null); + } + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public void configure() { + register(new ZoneBorders(3583, 3456, 3701, 3552)); + register(new ZoneBorders(3667, 9873, 3699, 9914)); + } + +} diff --git a/Server/src/main/content/region/morytania/phas/handlers/TokenCollectOption.java b/Server/src/main/content/region/morytania/phas/handlers/TokenCollectOption.java new file mode 100644 index 0000000..608cc5b --- /dev/null +++ b/Server/src/main/content/region/morytania/phas/handlers/TokenCollectOption.java @@ -0,0 +1,27 @@ +package content.region.morytania.phas.handlers; + +import core.cache.def.impl.NPCDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; + +@Initializable +public class TokenCollectOption extends OptionHandler { + + @Override + public boolean handle(Player player, Node node, String option) { + if(option.equals("collect")){ + player.getDialogueInterpreter().open(1686,node.asNpc() ,true); + } + return true; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + NPCDefinition.forId(1686).getHandlers().put("option:collect",this); + return this; + } +} diff --git a/Server/src/main/content/region/morytania/phas/handlers/akharanu.java b/Server/src/main/content/region/morytania/phas/handlers/akharanu.java new file mode 100644 index 0000000..798ff09 --- /dev/null +++ b/Server/src/main/content/region/morytania/phas/handlers/akharanu.java @@ -0,0 +1,70 @@ +package content.region.morytania.phas.handlers; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; + +@Initializable +public class akharanu extends DialoguePlugin { + public akharanu() {}; + public akharanu(Player player){super(player);} + @Override + public DialoguePlugin newInstance(Player player){return new akharanu(player);} + public boolean open(Object... args){ + npc("Hello, there, friend!"); + stage = 0; + return true; + } + @Override + public boolean handle(int componentId, int buttonId){ + switch(stage){ + case 0: + player.getDialogueInterpreter().sendOptions("Select one","Why are you, errr, so stiff?","Do you sell anything?"); + stage++; + break; + case 1: + switch(buttonId){ + case 1: + player("Why are you, errr, so stiff?"); + stage++; + break; + case 2: + player("Do you sell anything?"); + stage = 8; + break; + } + break; + case 2: + npc(FacialExpression.HALF_GUILTY,"I have extremely severe arthritis. It really sucks."); + stage++; + break; + case 3: + player("Oh. Well I'm sorry to hear that."); + stage++; + break; + case 4: + npc("Yes, thank you for your concern."); + stage++; + break; + case 5: + end(); + break; + case 8: + player("Do you sell anything?"); + stage++; + break; + case 9: + npc("Why, yes I do!"); + stage++; + break; + case 10: + end(); + new NPC(1688).openShop(player); + break; + } + return true; + } + public int[] getIds() {return new int[] {1688};} +} diff --git a/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/BookcaseDialogueFile.kt b/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/BookcaseDialogueFile.kt new file mode 100644 index 0000000..f188633 --- /dev/null +++ b/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/BookcaseDialogueFile.kt @@ -0,0 +1,106 @@ +package content.region.morytania.quest.creatureoffenkenstrain + +import content.data.Quests +import content.global.handlers.iface.BookInterface +import content.global.handlers.iface.BookLine +import content.global.handlers.iface.Page +import content.global.handlers.iface.PageSet +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.node.entity.player.Player +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.Items + +class BookcaseWestDialogueFile : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + START_DIALOGUE -> sendDialogueOptions(player!!, "Which book would you like to read?", "1001 Ways To Eat Fried Gizzards", "Practical Gardening For The Headless", "Human Taxidermy for Nincompoops", "The Joy of Gravedigging").also { + setComponentVisibility(player!!, 232, 9, false) + setComponentVisibility(player!!, 232, 8, true) + stage++ + } + 1 -> when (buttonID) { + 1 -> sendDialogue(player!!, "This book leaves you contemplating vegetarianism.").also { stage = END_DIALOGUE } + 2 -> sendDialogue(player!!, "This book has some very enlightening points to make, but you are at a loss to know how anyone without a head could possibly read it.").also { stage = END_DIALOGUE } + 3 -> sendDialogue(player!!, "This book seems to have been read hundreds of times, and has scribbles and formulae on every page. One such scribble says None good enough - have to lock them in the caverns...").also { stage = END_DIALOGUE } + 4 -> sendDialogue(player!!, "As you pull the book a hidden latch springs into place, and the bookcase swings open, revealing a secret compartment.").also { stage++ } + } + 2 -> sendItemDialogue(player!!, Items.MARBLE_AMULET_4187, "You find a marble amulet in the secret compartment.").also { + addItemOrDrop(player!!, Items.MARBLE_AMULET_4187, 1) + stage = END_DIALOGUE + } + } + } +} + +class BookcaseEastDialogueFile : DialogueFile() { + + override fun handle(componentID: Int, buttonID: Int) { + val opposingGender = if (player!!.isMale) "female" else "male" + when (stage) { + START_DIALOGUE -> sendDialogueOptions(player!!, "Which book would you like to read?", "Men are from Morytania, Women are from Lumbridge", "Chimney Sweeping on a Budget", "Handy Maggot Avoidance Techniques", "My Family and Other Zombies").also { stage++ } + 1 -> when (buttonID) { + 1 -> sendDialogue(player!!, "You discover some fascinating insights into the mind of the $opposingGender kind.").also { stage = END_DIALOGUE } + 2 -> ChimneySweepingOnABudgetBook.display(player!!, 0, 0).also { end() } + 3 -> sendDialogue(player!!, "As you pull the book a hidden latch springs into place, and the bookcase swings open, revealing a secret compartment.").also { stage++ } + 4 -> sendDialogue(player!!, "The book is appallingly dull.").also { stage = END_DIALOGUE } + } + 2 -> { + if (getQuestStage(player!!, Quests.CREATURE_OF_FENKENSTRAIN) == 2) { + sendItemDialogue(player!!, Items.OBSIDIAN_AMULET_4188, "You find an obsidian amulet in the secret compartment.").also { + addItemOrDrop(player!!, Items.OBSIDIAN_AMULET_4188, 1) + stage = END_DIALOGUE + } + } else { + sendDialogue(player!!, "The secret compartment is empty.") + } + } + } + } +} + + +/** + * Chimney Sweeping on a Budget Book + * @author ovenbreado + */ +class ChimneySweepingOnABudgetBook { + companion object { + + private val TITLE = "Chimney Sweeping on a Budget " + val CONTENTS = arrayOf( + PageSet( + Page( + BookLine("Page 26", 55), + BookLine("that sometimes a sweep", 56), + BookLine("may find themselves", 57), + BookLine("brushless and without the", 58), + BookLine("funds to purchase the", 59), + BookLine("one tool that is most", 60), + BookLine("essential to their trade.", 61), + BookLine("What is a chimney sweep", 62), + BookLine("without his or her brush?", 63), + BookLine("In this kind of situation", 64), + BookLine("any normal long-handled", 65), + ), + Page( + BookLine("brush might be a suitable", 66), + BookLine("replacement, although", 67), + BookLine("when attaching extensions", 68), + BookLine("to the handle make sure", 69), + BookLine("to use something sturdy", 70), + BookLine("like wire, otherwise a", 71), + BookLine("sweep may find", 72), + BookLine("themselves losing their", 73), + BookLine("brush and livelyhood to", 74), + BookLine("the forces of gravity", 75), + ) + ), + ) + fun display(player: Player, pageNum: Int, buttonID: Int) : Boolean { + BookInterface.pageSetup(player, BookInterface.FANCY_BOOK_3_49, TITLE, CONTENTS) + return true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/CreatureOfFenkenstrain.kt b/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/CreatureOfFenkenstrain.kt new file mode 100644 index 0000000..dd7dccc --- /dev/null +++ b/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/CreatureOfFenkenstrain.kt @@ -0,0 +1,183 @@ +package content.region.morytania.quest.creatureoffenkenstrain + +import core.api.* +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import org.rs09.consts.Items +import content.data.Quests + +/** + * Creature of Fenkenstrain Quest + * + * https://www.youtube.com/watch?v=zmvgzuA31S0 + * https://www.youtube.com/watch?v=RoR6zLGrRoY + * https://www.youtube.com/watch?v=I6X0kER1wDA - You can telekinetic grab the pickled brain jar lol + * https://www.youtube.com/watch?v=53_2dKEu0xo - has the letter and the bottom part of the quest dialogue + * https://www.youtube.com/watch?v=s57ElnRNhmU - in 2014 but the most thorough + + * 1 - Read Signpost to start the quest + * 2 - Talked to Fenkenstrain + * 3 - Collected body parts + * 4 - Gave needle and thread + * 5 - Repaired the lightning conductor and bring the creature to life + * 6 - Talked to the creature + * 100 - Stoped Fenkenstrain by stealing ring of charos + */ +@Initializable +class CreatureOfFenkenstrain : Quest(Quests.CREATURE_OF_FENKENSTRAIN, 41, 40, 2, 399, 0, 1, 9) { + + companion object { + const val attributeArms = "/save:quest:creatureoffenkenstrain-arms" + const val attributeLegs = "/save:quest:creatureoffenkenstrain-legs" + const val attributeTorso = "/save:quest:creatureoffenkenstrain-torso" + const val attributeHead = "/save:quest:creatureoffenkenstrain-decaphead" + const val attributeUnlockedMemorial = "/save:quest:creatureoffenkenstrain-amuletonmemorial" + const val attributeUnlockedShed = "/save:quest:creatureoffenkenstrain-keyonsheddoor" + const val attributeNeedle = "/save:quest:creatureoffenkenstrain-needle" + const val attributeThread = "/save:quest:creatureoffenkenstrain-thread" + const val fenkenstrainVarp = 399 + } + override fun drawJournal(player: Player, stage: Int) { + super.drawJournal(player, stage) + var line = 12 + var stage = getStage(player) + + var started = getQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN) > 0 + + if(!started){ + line(player, "I can start this quest by reading the signpost in the", line++, false) + line(player, "centre of !!Canifis??.", line++, false) + line(player, "I must be able to defeat a !!level 51 monster??, and need the", line++, false) + line(player, "following skill levels:", line++, false) + line(player, "Level 20 Crafting", line++, hasLevelStat(player, Skills.CRAFTING, 20)) + line(player, "Level 25 Theiving", line++, hasLevelStat(player, Skills.THIEVING, 25)) + line(player, "I also need to have completed the following quests:", line++, false) + line(player, "Priest in Peril", line++, isQuestComplete(player, Quests.PRIEST_IN_PERIL)) + line(player, "Restless Ghost", line++, isQuestComplete(player, Quests.THE_RESTLESS_GHOST)) + limitScrolling(player, line, true) + } else { + line(player, "I read the signpost in Canifis, which tells of a butler", line++, true) + line(player, "position that is available at the castle to the northeast.", line++, true) + if (stage >= 2) { + line(player, "I spoke to Fenkenstrain, who wanted me to find him some", line++, true) + line(player, "body parts so that he could build a creature.", line++, true) + } else if (stage >= 1) { + line(player, "I should go up to the castle and speak to !!Dr Fenkenstrain??", line++, false) + } + if (stage >= 3) { + line(player, "I gave a torso, some arms and legs, and a head to", line++, true) + line(player, "Fenkenstrain, who then wanted a needle and 5 lots of", line++, true) + line(player, "thread, so that he could sew the bodyparts together and", line++, true) + line(player, "create his creature.", line++, true) + } else if (stage >= 2) { + line++ + line(player, "I need to find these body parts for !!Fenkenstrain??:", line++, false) + line(player, "a pair of !!arms??", line++, false) + line(player, "a pair legs !!legs??", line++, false) + line(player, "a !!torso??", line++, false) + line(player, "a !!head??", line++, false) + line++ + line(player, "Apparently the soil of !!Morytania?? has a unique quality", line++, false) + line(player, "which preserves the bodies of the dead better than", line++, false) + line(player, "elsewhere, so perhaps I should look at the graves in the", line++, false) + line(player, "local area", line++, false) + } + if (stage >= 4) { + line(player, "I brought Fenkenstrain a needle and 5 quantities of", line++, true) + line(player, "thread.", line++, true) + } else if (stage >= 3) { + line(player, "I need to bring !!Fenkenstrain?? a !!needle?? and !!5 quantities??", line++, false) + line(player, "!!of thread??.", line++, false) + } + if (stage >= 5) { + line(player, "I repaired the lightning conductor, and Fenkenstrain", line++, true) + line(player, "brought the Creature to life.", line++, true) + } else if (stage >= 4) { + line(player, "!!Fenkenstrain?? has ordered me to repair the lightning", line++, false) + line(player, "conductor.", line++, false) + } + if (stage == 5) { + line(player, "!!Fenkenstrain?? wants to talk to me.", line++, false) + line++ + } + if (stage >= 7) { + line(player, "The Creature went on a rampage, and Fenkenstrain sent", line++, true) + line(player, "me up to the Tower to destroy it.", line++, true) + line(player, "The Creature convinced me to stop Fenkenstrain's", line++, true) + line(player, "experiments once and for all, and has told me the true", line++, true) + line(player, "history of Fenkenstrain's treachery.", line++, true) + } else if (stage >= 6) { + line(player, "The !!Creature?? went on a rampage, and !!Fenkenstrain?? wants", line++, false) + line(player, "me to go up the !!Tower?? to destroy it.", line++, false) + } + if (stage >= 8) { + line(player, "I stole Fenkenstrain's Ring of Charos, and he released", line++, true) + line(player, "me from his service.", line++, true) + } else if (stage >= 7) { + line(player, "I must find a way to stop Fenkenstrain's experiments.", line++, false) + } + if (stage >= 100) { + line++ + line(player,"QUEST COMPLETE!", line) + } + limitScrolling(player, line, false) + } + } + + override fun hasRequirements(player: Player): Boolean { + return arrayOf( + hasLevelStat(player, Skills.CRAFTING, 20), + hasLevelStat(player, Skills.THIEVING, 25), + isQuestComplete(player, Quests.PRIEST_IN_PERIL), + isQuestComplete(player, Quests.THE_RESTLESS_GHOST), + ).all { it } + } + + override fun reset(player: Player) { + setVarp(player, fenkenstrainVarp, 0, true) + removeAttribute(player, attributeArms) + removeAttribute(player, attributeLegs) + removeAttribute(player, attributeTorso) + removeAttribute(player, attributeHead) + removeAttribute(player, attributeUnlockedMemorial) + removeAttribute(player, attributeUnlockedShed) + removeAttribute(player, attributeNeedle) + removeAttribute(player, attributeThread) + } + + override fun finish(player: Player) { + var ln = 10 + super.finish(player) + player.packetDispatch.sendString("You have completed Creature of Fenkenstrain!", 277, 4) + player.packetDispatch.sendItemZoomOnInterface(Items.RING_OF_CHAROS_4202,230,277,5) + + drawReward(player, "2 quest points", ln++) + drawReward(player, "Ring of Charos", ln++) + drawReward(player, "1,000 Theiving XP", ln++) + + addItemOrDrop(player, Items.RING_OF_CHAROS_4202, 1) + rewardXP(player, Skills.THIEVING, 1000.0) + } + + override fun setStage(player: Player, stage: Int) { + super.setStage(player, stage) + this.updateVarps(player) + } + + override fun updateVarps(player: Player) { + // This is a bit of a hack. I didn't manage to align the quest with the varp, + // so I had to include both stage 3 and 4 to varp value 3 to show the creature. + if(getQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN) == 4) { + setVarp(player, fenkenstrainVarp, 3, true) + } + if(getQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN) >= 8) { + setVarp(player, fenkenstrainVarp, 8, true) + } + } + + override fun newInstance(`object`: Any?): Quest { + return this + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/CreatureOfFenkenstrainListeners.kt b/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/CreatureOfFenkenstrainListeners.kt new file mode 100644 index 0000000..7a0aea3 --- /dev/null +++ b/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/CreatureOfFenkenstrainListeners.kt @@ -0,0 +1,396 @@ +package content.region.morytania.quest.creatureoffenkenstrain + +import content.data.Quests +import core.api.* +import core.game.dialogue.FacialExpression +import core.game.global.action.DoorActionHandler +import core.game.global.action.PickupHandler +import core.game.interaction.InteractionListener +import core.game.node.item.GroundItem +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Scenery +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class CreatureOfFenkenstrainListeners : InteractionListener { + companion object { + private val itemToAttribute = hashMapOf( + Items.ARMS_4195 to CreatureOfFenkenstrain.attributeArms, + Items.LEGS_4196 to CreatureOfFenkenstrain.attributeLegs, + Items.TORSO_4194 to CreatureOfFenkenstrain.attributeTorso, + Items.DECAPITATED_HEAD_4197 to CreatureOfFenkenstrain.attributeHead + ) + + enum class Graves(val location: Location, val graveName: String, val unearthText: String, val unearthItem: Int?) { + GRAVE1(Location(3541, 3541), "Anton Hayes", "...but the grave is empty.", null), + GRAVE2(Location(3542, 3486), "Callum Elding", "...but the grave is empty.", null), + GRAVE3(Location(3585, 3497), "Domin O'Raleigh", "...but the grave is empty.", null), + GRAVE4(Location(3608, 3491), "Ed Lestwit", "...and you unearth a decapitated head.", Items.DECAPITATED_HEAD_4197), + GRAVE5(Location(3588, 3472), "Elena Frey", "...but the grave is empty.", null), + GRAVE6(Location(3593, 3509), "Eryn Treforest", "...but the grave is empty.", null), + GRAVE7(Location(3594, 3491), "Isla Skye", "...but the grave is empty.", null), + GRAVE8(Location(3596, 3479), "Jayna Harrow", "...but the grave is empty.", null), + GRAVE9(Location(3604, 3466), "Jayne Corbo", "...but the grave is empty.", null), + GRAVE10(Location(3608, 3466), "Kandik Kludge", "...but the grave is empty.", null), + GRAVE11(Location(3616, 3478), "Korvic Frey", "...but the grave is empty.", null), + GRAVE12(Location(3619, 3469), "Marabella Kludge", "...but the grave is empty.", null), + GRAVE13(Location(3626, 3495), "Marcus Harrow", "...but the grave is empty.", null), + GRAVE14(Location(3629, 3483), "Petrik Corbo", "...but the grave is empty.", null), + GRAVE15(Location(3631, 3476), "Serra Alcanthric", "...but the grave is empty.", null), + GRAVE16(Location(3631, 3500), "Toran Alcanthric", "...but the grave is empty.", null), + GRAVE17(Location(3572, 3527), "Unknown", "...but the grave is empty.", null), + GRAVE18(Location(3576, 3526), "Unknown", "...but the grave is empty.", null), + GRAVE19(Location(3639, 3470), "Lord Rologray", "...but the grave is empty.", null), + GRAVE20(Location(3634, 3503), "Lord Rologarth", "...but the grave is empty.", null), + GRAVE21(Location(3502, 3576), "Lady Rolobrae", "...and you unearth a torso.", Items.TORSO_4194), + GRAVE22(Location(3504, 3577), "Lord Rolomere", "...and you unearth a pair of arms.", Items.ARMS_4195), + GRAVE23(Location(3506, 3576), "Lord Rolovanne", "...and you unearth a pair of legs.", Items.LEGS_4196); + + companion object { + @JvmField + val locationMap = Graves.values().associateBy { it.location } + } + } + } + override fun defineListeners() { + + // Climbing ladders + addClimbDest(Location.create(3504, 9970, 0), Location.create(3504, 3571, 0)) + + // 1: Reading Signpost to start the quest + on(Items.NULL_5164, SCENERY, "read") { player, _ -> + if (getQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN) < 7 ) { + sendDialogueLines( + player, + "The signpost has a note pinned onto it. The note says:", + "'---- Braindead Butler Wanted ----", + " Gravedigging skills essential - Hunchback advantageous", + "See Dr Fenkenstrain at the castle NE of Canifis'", + ) + } else { + sendDialogueLines( + player, + "The signpost has a note pinned onto it. The note says:", + "'AAARRGGGHHHHH!!!!!'", + ) + } + if(getQuest(player, Quests.CREATURE_OF_FENKENSTRAIN).hasRequirements(player) && getQuestStage( + player, + Quests.CREATURE_OF_FENKENSTRAIN + ) == 0) { + setQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN, 1) + } + return@on true + } + + // 2 Reading a grave + on(intArrayOf(Scenery.GRAVE_5168, Scenery.GRAVE_5169), SCENERY, "read") { player, node -> + val grave = Graves.locationMap[node.location] + sendMessage(player, "The grave says:") + sendMessage(player, " 'Here lies ${grave?.graveName ?: "Unknown"} - REST IN PEACE'") + return@on true + } + + // 2: Digging a grave + on(intArrayOf(Scenery.GRAVE_5168, Scenery.GRAVE_5169), SCENERY, "dig") { player, node -> + if(!inInventory(player, Items.SPADE_952)) { + sendMessage(player, "You need a spade to do that.") + return@on true + } + val grave = Graves.locationMap[node.location] + sendMessage(player, "You start digging...") + animate(player, Animation(831)) + player.pulseManager.run(object : Pulse(5) { + override fun pulse(): Boolean { + player.animate(Animation(-1)) + if(grave?.unearthItem != null && + !hasAnItem(player, grave.unearthItem).exists() + /* && !getAttribute(player, itemToAttribute[grave.unearthItem] ?: "", false) */) { + sendItemDialogue(player, grave.unearthItem, grave.unearthText) + addItemOrDrop(player, grave.unearthItem) + } else { + sendMessage(player, "...but the grave is empty.") + } + return true + } + }) + return@on true + } + + // 2: Find amulets in bookcases. Note: even after the quest, these can still be accessed, but nothing falls out. + on(Scenery.BOOKCASE_5166, SCENERY, "search") { player, node -> + if (node.location.equals(Location(3555, 3558, 1))) { + openDialogue(player, BookcaseEastDialogueFile()) + return@on true + } else if(node.location.equals(Location(3542, 3558, 1))) { + openDialogue(player, BookcaseWestDialogueFile()) + return@on true + } else { + sendMessage(player, "It is a bookcase full of books") + return@on true + } + } + + // 2: Snap together Amulets + onUseWith(ITEM, Items.MARBLE_AMULET_4187, Items.OBSIDIAN_AMULET_4188) { player, used, with -> + if(removeItem(player, Items.MARBLE_AMULET_4187) && removeItem(player, Items.OBSIDIAN_AMULET_4188)) { + sendItemDialogue(player, Items.STAR_AMULET_4183, "The marble and obsidian amulets snap together tightly to form a six-pointed amulet.") + addItemOrDrop(player, Items.STAR_AMULET_4183) + } + return@onUseWith true + } + + // 2: Fit Star Amulet on Memorial + onUseWith(SCENERY, Items.STAR_AMULET_4183, Items.NULL_5167) { player, used, with -> + if (removeItem(player, Items.STAR_AMULET_4183)) { + sendItemDialogue(player, Items.STAR_AMULET_4183, "The star amulet fits exactly into the depression on the coffin lid.") + setAttribute(player, CreatureOfFenkenstrain.attributeUnlockedMemorial, true) + } + return@onUseWith true + } + + // 2: Opening Cavern Entrance + on(Scenery.ENTRANCE_5170, SCENERY, "open") { player, node -> + if (inInventory(player, Items.CAVERN_KEY_4184) && removeItem(player, Items.CAVERN_KEY_4184)) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else { + sendMessage(player, "The door is locked.") + } + return@on true + } + // 2: Using Cavern Key on the Cavern Entrance + onUseWith(SCENERY, Items.CAVERN_KEY_4184, Scenery.ENTRANCE_5170) { player, used, with -> + if (removeItem(player, used)) { + DoorActionHandler.handleAutowalkDoor(player, with.asScenery()) + } + return@onUseWith true + } + + + // 2: Searching for Cavern Key out of the Chest + on(Scenery.CHEST_5163, SCENERY, "search") { player, node -> + sendItemDialogue(player, Items.CAVERN_KEY_4184, "You take a key out of the chest.") + addItemOrDrop(player, Items.CAVERN_KEY_4184) + return@on true + } + + // 2: Taking the brain from the table (telekinetic grab is allowed) + on(Items.PICKLED_BRAIN_4199, GROUNDITEM, "take") { player, node -> + if(node.location.equals(3492, 3474, 0)) { + openDialogue(player, RoavarDialogueFile(2), findLocalNPC(player, NPCs.ROAVAR_1042)!!) + } else { + PickupHandler.take(player, node as GroundItem) + } + return@on true + } + + // 2: Fit Brain into Decapitated Head + onUseWith(ITEM, Items.PICKLED_BRAIN_4199, Items.DECAPITATED_HEAD_4197) { player, used, with -> + if(removeItem(player, used) && removeItem(player, with)) { + sendItemDialogue(player, Items.DECAPITATED_HEAD_4198, "You squeeze the pickled brain into the decapitated head.") + addItemOrDrop(player, Items.DECAPITATED_HEAD_4198) + } + return@onUseWith true + } + + // 2: Searching the Memorial (Scenery.MEMORIAL_5167) + on(Items.NULL_5167, SCENERY, "search") { player, node -> + val scenery = node.asScenery() + if(getAttribute(player, CreatureOfFenkenstrain.attributeUnlockedMemorial, false) || + getQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN) > 2) { + animateScenery(player, scenery, 1620) + var dest: Location? = null + if(scenery.location.equals(Location(3505, 3571))) { + dest = Location(3504, 9969) + } else if(scenery.location.equals(Location(3578, 3527))) { + dest = Location(3577, 9927) + } + if(dest != null) { + player.pulseManager.run(object : Pulse(3) { + override fun pulse(): Boolean { + resetAnimator(player) + teleport(player, dest!!) + return true + } + }) + } + } else { + if (scenery.location.equals(Location(3505, 3571))) { + sendMessage(player, "You find a depression in the memorial stone in the shape of a six-pointed star.") + } else { + sendMessage(player, "You find nothing remarkable about the memorial stone.") + } + } + return@on true + } + + // 2: Pushing open the Memorial (Scenery.MEMORIAL_5167) + on(Items.NULL_5167, SCENERY, "push") { player, node -> + val scenery = node.asScenery() + if (getAttribute(player, CreatureOfFenkenstrain.attributeUnlockedMemorial, false) || + getQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN) > 2) { + animateScenery(player, scenery, 1620) + var dest: Location? = null + if(scenery.location.equals(Location(3505, 3571))) { + dest = Location(3504, 9969) + } else if(scenery.location.equals(Location(3578, 3527))) { + dest = Location(3577, 9927) + } + if(dest != null) { + player.pulseManager.run(object : Pulse(3) { + override fun pulse(): Boolean { + resetAnimator(player) + teleport(player, dest!!) + return true + } + }) + } + } else { + player.sendMessage("The coffin is incredibly heavy, and does not budge.") + } + return@on true + } + + // 5: Garden Shed Door + on(Scenery.DOOR_5174, SCENERY, "open") { player, node -> + if (getAttribute(player, CreatureOfFenkenstrain.attributeUnlockedShed, false) || + getQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN) >= 5) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else if (inInventory(player, Items.SHED_KEY_4186)) { + if (removeItem(player, Items.SHED_KEY_4186)) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + setAttribute(player, CreatureOfFenkenstrain.attributeUnlockedShed, true) + } + } else { + sendMessage(player, "The door is locked.") + } + return@on true + } + + // 5: Garden Shed Door + onUseWith(SCENERY, Items.SHED_KEY_4186, Scenery.DOOR_5174) { player, used, with -> + if (getAttribute(player, CreatureOfFenkenstrain.attributeUnlockedShed, false) || + getQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN) >= 5) { + DoorActionHandler.handleAutowalkDoor(player, with.asScenery()) + } else if (removeItem(player, used)) { + DoorActionHandler.handleAutowalkDoor(player, with.asScenery()) + setAttribute(player, CreatureOfFenkenstrain.attributeUnlockedShed, true) + } + return@onUseWith true + } + + // 5: Pile of Canes + on(Items.NULL_5158, SCENERY, "take-from") { player, node -> + sendMessage(player, "You take a garden cane from the pile.") + addItemOrDrop(player, Items.GARDEN_CANE_4189) + return@on true + } + + // 5: Cupboard Garden Brush + on(Items.NULL_5157, SCENERY, "search") { player, node -> + sendItemDialogue(player, Items.GARDEN_BRUSH_4190, "You find a garden brush in the cupboard.") + // player.packetDispatch.sendAngleOnInterface(241, 1, 1000, 510, 0) + addItemOrDrop(player, Items.GARDEN_BRUSH_4190) + return@on true + } + + // 5: Extended Brush up to 3 Fused + onUseWith(ITEM, intArrayOf(Items.GARDEN_BRUSH_4190, Items.EXTENDED_BRUSH_4191, Items.EXTENDED_BRUSH_4192), Items.GARDEN_CANE_4189) { player, used, with -> + if (!inInventory(player, Items.BRONZE_WIRE_1794)) { + sendMessage(player, "You need some bronze wire to tie them together.") + return@onUseWith true + } + if (removeItem(player, Items.BRONZE_WIRE_1794) && removeItem(player, used) && removeItem(player, with)){ + sendMessage(player, "You attach the cane to the brush.") + when (used.id) { + Items.GARDEN_BRUSH_4190 -> { + addItemOrDrop(player, Items.EXTENDED_BRUSH_4191) + } + Items.EXTENDED_BRUSH_4191 -> { + addItemOrDrop(player, Items.EXTENDED_BRUSH_4192) + } + Items.EXTENDED_BRUSH_4192 -> { + addItemOrDrop(player, Items.EXTENDED_BRUSH_4193) + } + } + } + return@onUseWith true + } + + // 5: Cupboard Garden Brush + on(Scenery.FIREPLACE_5165, SCENERY, "examine") { player, node -> + if (!inInventory(player, Items.CONDUCTOR_4201)) { + sendMessage(player, "You give the chimney a jolly good clean out.") + sendItemDialogue(player, Items.CONDUCTOR_MOULD_4200, "A lightning conductor mould falls down out of the chimney.") + addItemOrDrop(player, Items.CONDUCTOR_MOULD_4200) + return@on true + } + sendMessage(player, "It looks like it needs a good sweep out.") + return@on true + } + + // 5: Brush Fireplace + onUseWith(SCENERY, Items.EXTENDED_BRUSH_4193, Scenery.FIREPLACE_5165) { player, used, with -> + sendMessage(player, "You give the chimney a jolly good clean out.") + sendItemDialogue(player, Items.CONDUCTOR_MOULD_4200, "A lightning conductor mould falls down out of the chimney.") + addItemOrDrop(player, Items.CONDUCTOR_MOULD_4200) + return@onUseWith true + } + + // 5: Repair the lightning rod + on(Scenery.LIGHTNING_CONDUCTOR_5176, SCENERY, "repair") { player, node -> + if (!inInventory(player, Items.CONDUCTOR_4201)) { + sendMessage(player, "You need to repair it with a conductor.") + return@on true + } + if (removeItem(player, Items.CONDUCTOR_4201)) { + if(getQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN) == 4) { + setQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN, 5) + } + sendDialogue(player, "You repair the lightning conductor not one moment too soon - a tremendous bold of lightning melts the new lightning conductor, and power blazes throughout the castle, if only briefly.") + val scenery = node.asScenery() + replaceScenery(scenery, Items.NULL_5177, 3, node.location) + animateScenery(player, scenery, 1632) + } + return@on true + } + + // 6: Enter jail above + on(Scenery.DOOR_5172, SCENERY, "open") { player, node -> + if (inInventory(player, Items.TOWER_KEY_4185) || getQuestStage( + player, + Quests.CREATURE_OF_FENKENSTRAIN + ) > 7) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + } else { + sendMessage(player, "The door is locked.") + } + return@on true + } + // 2: Using Cavern Key on the Cavern Entrance + onUseWith(SCENERY, Items.TOWER_KEY_4185, Scenery.DOOR_5172) { player, used, with -> + if (inInventory(player, Items.TOWER_KEY_4185)) { + DoorActionHandler.handleAutowalkDoor(player, with.asScenery()) + } + return@onUseWith true + } + + + // 7: Pickpocket Ring of Charos from Fenkenstrain + on(NPCs.DR_FENKENSTRAIN_1670, NPC, "pickpocket") { player, node -> + if (getQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN) == 7) { + sendMessage(player, "You steal the Ring of Charos from Fenkenstrain.") + finishQuest(player, Quests.CREATURE_OF_FENKENSTRAIN) + } else if (getQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN) > 7 && hasAnItem(player, Items.RING_OF_CHAROS_4202).container == null) { + // Allow Fenkenstrain to be pickpocketed beyond the quest if the ring is lost. + addItemOrDrop(player, Items.RING_OF_CHAROS_4202, 1) + sendMessage(player, "You steal the Ring of Charos from Fenkenstrain.") + } else { + player.dialogueInterpreter.sendDialogues(NPCs.DR_FENKENSTRAIN_1670, FacialExpression.NEUTRAL ,"What do you think you're doing???") + } + return@on true + } + } +} diff --git a/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/DrFenkenstrainDialogue.kt b/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/DrFenkenstrainDialogue.kt new file mode 100644 index 0000000..c6e848f --- /dev/null +++ b/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/DrFenkenstrainDialogue.kt @@ -0,0 +1,275 @@ +package content.region.morytania.quest.creatureoffenkenstrain + +import content.data.Quests +import core.api.* +import core.game.dialogue.* +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +@Initializable +class DrFenkenstrainDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, DrFenkenstrainDialogueFile(), npc) + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return DrFenkenstrainDialogue(player) + } + override fun getIds(): IntArray { + // THE IDs ARE WRONG. 1668 and 1669 are varp controlled Dr Fenkenstrain + return intArrayOf(NPCs.WEREWOLF_1668, NPCs.WEREWOLF_1669, NPCs.DR_FENKENSTRAIN_1670) + } +} + +class DrFenkenstrainDialogueFile : DialogueBuilderFile() { + + companion object { + private fun allPartsSubmitted(player: Player): Boolean { + return getAttribute(player, CreatureOfFenkenstrain.attributeArms, false) && + getAttribute(player, CreatureOfFenkenstrain.attributeLegs, false) && + getAttribute(player, CreatureOfFenkenstrain.attributeTorso, false) && + getAttribute(player, CreatureOfFenkenstrain.attributeHead, false) + } + private fun reqArms(player: Player): Boolean { + return !getAttribute(player, CreatureOfFenkenstrain.attributeArms, false) && inInventory(player, Items.ARMS_4195) + } + private fun reqLegs(player: Player): Boolean { + return !getAttribute(player, CreatureOfFenkenstrain.attributeLegs, false) && inInventory(player, Items.LEGS_4196) + } + private fun reqTorso(player: Player): Boolean { + return !getAttribute(player, CreatureOfFenkenstrain.attributeTorso, false) && inInventory(player, Items.TORSO_4194) + } + private fun reqHead(player: Player): Boolean { + return !getAttribute(player, CreatureOfFenkenstrain.attributeHead, false) && inInventory(player, Items.DECAPITATED_HEAD_4198) + } + private fun hasPart(b: DialogueBuilder, item: Item, attributeToSet: String, successMsg: String): DialogueBuilder { + return b.branch { player -> + return@branch if (!getAttribute(player, attributeToSet, false) && inInventory(player, item.id, item.amount)) { 1 } else { 0 } + }.let{ branch -> + val returnJoin = b.placeholder() + branch.onValue(0) + .goto(returnJoin) + branch.onValue(1) + .betweenStage { _, player, _, _ -> + setAttribute(player, attributeToSet, true) + removeItem(player, item) + } + .npcl(successMsg) + .goto(returnJoin) + return@let returnJoin.builder() + } + } + } + + override fun create(b: DialogueBuilder) { + + b.onQuestStages(Quests.CREATURE_OF_FENKENSTRAIN, 0) + .npcl("Have you come to apply for the job?") + .playerl(FacialExpression.THINKING, "What job?") + .npcl("I've posted a note on the signpost in Canifis about it. Go take a look at it first.") + .end() + + b.onQuestStages(Quests.CREATURE_OF_FENKENSTRAIN, 1) + .npcl("Have you come to apply for the job?") + .options().let { optionBuilder -> + val continuePath = b.placeholder() + optionBuilder.option ("Yes") + .playerl("Yes, if it pays well.") + .goto(continuePath) // Continue down below. + optionBuilder.option_playerl("No.") + .end() + return@let continuePath.builder() + } + .npcl("I'll have to ask you some questions first.") + .playerl("Okay...") + .npcl("How would you describe yourself in one word?") + .options().let { optionBuilder -> + val continuePath = b.placeholder() + optionBuilder.recordAttribute("creature-of-fenkenstrain:first-question") + optionBuilder.option_playerl("Stunning.").goto(continuePath) + optionBuilder.option_playerl("Awe-inspiring.").goto(continuePath) + optionBuilder.option_playerl("Breathtaking.").goto(continuePath) + optionBuilder.option_playerl("Braindead.").goto(continuePath) + return@let continuePath.builder() + } + .npcl("Mmmm, I see.") + .npcl("Just one more question. What would you say is your greatest skill?") + .options().let { optionBuilder -> + val continuePath = b.placeholder() + optionBuilder.recordAttribute("creature-of-fenkenstrain:second-question") + optionBuilder.option_playerl("Combat.").goto(continuePath) + optionBuilder.option_playerl("Magic.").goto(continuePath) + optionBuilder.option_playerl("Cooking.").goto(continuePath) + optionBuilder.option_playerl("Grave-digging.").goto(continuePath) + return@let continuePath.builder() + } + .npcl("Mmmm, I see.") + .branch { player -> if(player.getAttribute("creature-of-fenkenstrain:first-question", -1) == 3 && player.getAttribute("creature-of-fenkenstrain:second-question", -1) == 3) { 1 } else { 0 } } + .let{ branch -> + // Failure branch + branch.onValue(0) + .npcl("Looks like you're not the @g[man,woman] for the job.") + .end() + return@let branch // Return DialogueBranchBuilder instead of DialogueBuilder to forward the success branch. + }.onValue(1) // Success branch + .npcl("Looks like you're just the @g[man,woman] for the job! Welcome aboard!") + .playerl("Is there anything you'd like me to do for you, sir?") + .npcl("Yes, there is. You're highly skilled at grave-digging, yes?") + .playerl("Err...yes, that's what I said.") + .npcl("Excellent. Now listen carefully. I need you to find some...stuff...for me.") + .playerl("Stuff?") + .npcl("That's what I said...stuff.") + .playerl("What kind of stuff?") + .npcl("Well...dead stuff.") + .playerl("Go on...") + .npcl("I need you to get me enough dead body parts for me to stitch together a complete body, which I plan to bring to life.") + .playerl("Right...okay...if you insist.") + .endWith { _, player -> + if(getQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN) == 1) { + setQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN, 2) + } + } + + b.onQuestStages(Quests.CREATURE_OF_FENKENSTRAIN, 2) + .options().let { optionBuilder -> + val continuePath = b.placeholder() + + optionBuilder.optionIf("I have some body parts for you.") { player -> return@optionIf allPartsSubmitted(player) || reqArms(player) || reqLegs(player) || reqTorso(player) || reqHead(player) } + .playerl("I have some body parts for you.") + .goto(continuePath) // Continue down below. + optionBuilder.optionIf("Do you know where I could find body parts?") { player -> return@optionIf !(allPartsSubmitted(player) || reqArms(player) || reqLegs(player) || reqTorso(player) || reqHead(player)) } + .playerl("Do you know where I could find body parts?") + .npcl("The soil of Morytania is unique in its ability to preserve the bodies of the dead, which is one reason why I have chosen to carry out my experiments here.") + .npcl("I recommend digging up some graves in the local area. To the south-east you will find the Haunted Woods; I believe there are many graves there.") + .npcl( "There is also a mausoleum on an island west of this castle. I expect the bodies that are buried there to be extremely well preserved, as they were wealthy in life.") + .end() + optionBuilder.option_playerl("Remind me what you want me to do.") + .npcl("I need you to get me enough dead body parts for me to stitch together a complete body, which I plan to bring to life.") + .playerl("Right...okay...if you insist.") + .end() + optionBuilder.option_playerl("Why are you trying to make this creature?") + .npcl("I came to the land of Morytania many years ago, to find a safe sanctuary for my experiments. This abandoned castle suited my purposes exactly.") + .playerl("What were you experimenting in?") + .npcl("Oh, perfectly innocent experiments - for the good of mankind.") + .playerl("Then why did you need to come to Morytania?") + .npcl("Enough questions, now. Get back to your work.") + .end() + optionBuilder.option_playerl("Will this creature put me out of a job?") + .npcl("No, my friend. I have a very special purpose in mind for this creature.") + .end() + optionBuilder.option_playerl("I must get back to work, sir.") + .end() + + return@let continuePath.builder() + } + // Dialogue path to look for arms. + .let{ builder -> return@let hasPart(builder, Item(Items.ARMS_4195, 1), CreatureOfFenkenstrain.attributeArms, "Great, you've brought me some arms.") } + // Dialogue path to look for legs. + .let{ builder -> return@let hasPart(builder, Item(Items.LEGS_4196, 1), CreatureOfFenkenstrain.attributeLegs, "Excellent, you've brought me some legs.") } + // Dialogue path to look for torso. + .let{ builder -> return@let hasPart(builder, Item(Items.TORSO_4194, 1), CreatureOfFenkenstrain.attributeTorso, "Splendid, you've brought me a torso.") } + // Dialogue path to look for head. + .let{ builder -> return@let hasPart(builder, Item(Items.DECAPITATED_HEAD_4198, 1), CreatureOfFenkenstrain.attributeHead, "Fantastic, you've brought me a head.") } + .branch { player -> + return@branch if (allPartsSubmitted(player)) { 1 } else { 0 } + }.let{ branch -> + // Failure branch + branch.onValue(0) + .end() + return@let branch // Return DialogueBranchBuilder instead of DialogueBuilder to forward the success branch. + }.onValue(1) // Success branch + .npcl("Superb! Those are all the parts I need. Now to sew them together...") + .npcl("Oh bother! I haven't got a needle or thread!") + .npcl("Go and get me a needle, and I'll need 5 lots of thread.") + .endWith { _, player -> + if(getQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN) == 2) { + setQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN, 3) + } + } + + b.onQuestStages(Quests.CREATURE_OF_FENKENSTRAIN, 3) + .npcl("Where are my needle and thread, @name?") + // Dialogue path to look for 1 needle. + .let{ builder -> return@let hasPart(builder, Item(Items.NEEDLE_1733, 1), CreatureOfFenkenstrain.attributeNeedle, "Ah, a needle. Wonderful.") } + // Dialogue path to look for 5 threads. + .let{ builder -> return@let hasPart(builder, Item(Items.THREAD_1734, 5), CreatureOfFenkenstrain.attributeThread, "Some thread. Excellent.") } + // Final branch to only continue conversation when both needle and threads are submitted. + .branch { player -> + return@branch if (getAttribute(player, CreatureOfFenkenstrain.attributeNeedle, false) && + getAttribute(player, CreatureOfFenkenstrain.attributeThread, false)) { 1 } else { 0 } + }.let{ branch -> + // Failure branch + branch.onValue(0) + .end() + return@let branch // Return DialogueBranchBuilder instead of DialogueBuilder to forward the success branch. + }.onValue(1) // Success branch + .betweenStage { df, player, _, _ -> + setVarp(player, CreatureOfFenkenstrain.fenkenstrainVarp, 3, true) + } + .line("Fenkenstrain uses the needle and thread to sew the body parts", "together. Soon, a hideous creature lies inanimate on the ritual table.") + .npcl("Perfect. But I need one more thing from you - flesh and bones by themselves do not make life.") + .playerl("Really?") + .npcl("I have honed to perfection an ancient ritual that will give life to this creature, but for this I must harness the very power of Nature.") + .playerl("And what power is this?") + .npcl("The power of lightning.") + .playerl("Sorry, can't make lightning, you've got the wrong @g[man,woman]-") + .npcl("Silence your insolent tongue! The storm that brews overhead will create the lightning. What I need you to do is to repair the lightning conductor on the balcony above.") + .playerl("Repair the lightning conductor, right. Can I have a break, soon? By law I'm entitled to 15 minutes every-") + .npcl("Repair the conductor and BEGONE!!") + .endWith { _, player -> + if(getQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN) == 3) { + setQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN, 4) + } + } + + + b.onQuestStages(Quests.CREATURE_OF_FENKENSTRAIN, 4) + .playerl(FacialExpression.THINKING, "How do I repair the lighting conductor?") + .npcl("Oh, it would be easier to do it myself! If you find a conductor mould you should be able to cast a new one.") + .npcl("Remember this, @name, my experiment will only work with a conductor made from silver.") + .end() + + b.onQuestStages(Quests.CREATURE_OF_FENKENSTRAIN, 5) + .playerl("So did it work, then?") + .npcl("Yes, I'm afraid it did, @name - all too well.") + .playerl(FacialExpression.SUSPICIOUS, "I can't see it anywhere.") + .npcl("I tricked it into going up to the Tower, and there it remains, imprisoned.") + .playerl(FacialExpression.SUSPICIOUS, "So the creature wasn't all you'd hoped then?") + .npcl("...oh, what have I done...") + .playerl(FacialExpression.SUSPICIOUS, "Oh, I see, we're developing a sense of right and wrong now are we?") + .playerl(FacialExpression.SUSPICIOUS, "Bit late for that, I'd say.") + .npcl("I have no control over it! It's coming to get me!") + .playerl(FacialExpression.SUSPICIOUS, "What do you want me to do about it?") + .npcl("Destroy it!!! Take the key to the Tower and take back the life I never should have granted!!!") + .endWith() { df, player -> + if(getQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN) == 5) { + setQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN, 6) + } + addItemOrDrop(player, Items.TOWER_KEY_4185) + } + + b.onQuestStages(Quests.CREATURE_OF_FENKENSTRAIN, 6) + .npcl("So have you destroyed it?!!?") + .playerl("Not yet.") + .npcl("Please, hurry - save me!!!!") + .end() + + b.onQuestStages(Quests.CREATURE_OF_FENKENSTRAIN, 7) + .npcl("So have you destroyed it?!!?") + .playerl("Never, now that he has told me the truth!") + .npcl("Oh my, oh my, this is exactly what I feared!") + .npcl("Why did you have to pick Rologarth's brain of all brains?!?") + .playerl("I'm through working for you.") + .npcl("No! I refuse to release you! You must help me build another creature to destroy this dreadful mistake!!") + .end() + + b.onQuestStages(Quests.CREATURE_OF_FENKENSTRAIN, 8, 100) + .npcl("theyrecomingtogetme theyrecomingtogetme...") + .playerl("It is all you deserve. Lord Rologarth is master of this castle once more. Let him protect you - if he wants to.") + .npcl("theyrecomingtogetme theyrecomingtogetme...") + .end() + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/GardenerGhostDialogue.kt b/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/GardenerGhostDialogue.kt new file mode 100644 index 0000000..70387d2 --- /dev/null +++ b/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/GardenerGhostDialogue.kt @@ -0,0 +1,102 @@ +package content.region.morytania.quest.creatureoffenkenstrain + +import content.data.Quests +import core.api.* +import core.game.dialogue.* +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import java.util.* + +@Initializable +class GardenerGhostDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + val gardenerGhost = npc as GardenerGhostNPC + if (gardenerGhost.target == player) { + // This is the special case where the gardener follows you. + if (gardenerGhost.location.withinDistance(gardenerGhost.graveLocation, 5)) { + sendChat(gardenerGhost, "Here is the place where I met me' maker.") + } else { + sendChat(gardenerGhost, "Go " + gardenerGhost.location.deriveDirection(gardenerGhost.graveLocation).name.lowercase(Locale.getDefault()).replace('_', '-') + ", mate") + gardenerGhost.continueFollowing(player) + } + } else { + openDialogue(player, GardenerGhostDialogueFile(), npc) + } + return true + } + override fun newInstance(player: Player): DialoguePlugin { + return GardenerGhostDialogue(player) + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.GARDENER_GHOST_1675) + } +} + +class GardenerGhostDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onPredicate { player -> !player.equipment.containsAtLeastOneItem(Items.GHOSTSPEAK_AMULET_552) } + .npcl("Wooo wooo wooooo.") + .end() + b.onQuestStages(Quests.CREATURE_OF_FENKENSTRAIN, *(0..8).toIntArray(), 100) + .options().let { optionBuilder -> + optionBuilder.option("Tell me about Fenkenstrain.") + .playerl("Can you tell me anything about Fenkenstrain?") + .item(Items.GHOSTSPEAK_AMULET_552, "You feel power emanate from the Amulet of Ghostspeak", "and the air around you vibrates with the ghostly voice", "of the headless gardener.") + .npcl("Oi could tell you a few things about old Fenky, yeah.") + .playerl("Go on.") + .npcl("Once, this castle were full o' good folk - my friends. Fenky was just the castle doctor, you know, to the lord and the castle folk. I don't know what happened to them all, but one by one they all disappeared.") + .npcl("When they were gone a while, I went an dug graves for 'em in the forest. After a while there weren't no one left, but the lord, Fenkenstrain and meself.") + .npcl("Old Fenky sent me into the forest to dig 'im a pit - never said what for - then would you believe it, someone chops me 'ead off.") + .playerl("Did you see who did it...before...?") + .npcl("Before oi kicked the bucket, you mean?") + .playerl("Umm...") + .npcl("Don't worry yerself. I'm not worried about bein' dead. Worse things could happen, I suppose.") + .npcl("One thing I do know is, there ain't no lord of the castle anymore, 'cept for old Fenky. Makes ya think a bit, don't it?") + .end() + optionBuilder.optionIf("Do you know where the key to the shed is?") { player -> return@optionIf getQuestStage( + player, + Quests.CREATURE_OF_FENKENSTRAIN + ) == 4 } + .item(Items.GHOSTSPEAK_AMULET_552, "You feel power emanate from the Amulet of Ghostspeak", "and the air around you vibrates with the ghostly voice", "of the headless gardener.") + .npcl("Got it right 'ere in my pocket. Here you go.") + .iteml(4186, "The headless gardener hands you a rusty key.") + .endWith { _, player -> + addItemOrDrop(player, Items.SHED_KEY_4186) + } + optionBuilder.optionIf("Do you know where I can find a lightning conductor mould is?") { player -> return@optionIf getQuestStage( + player, + Quests.CREATURE_OF_FENKENSTRAIN + ) == 4 } + .item(Items.GHOSTSPEAK_AMULET_552, "You feel power emanate from the Amulet of Ghostspeak", "and the air around you vibrates with the ghostly voice", "of the headless gardener.") + .npcl("A conductor mould, you say? Let me see...") + .npcl("There used to be a bloke 'ere, sort of an 'andyman 'e was. Did everything 'round the place - fixed what was broke, swept the chimneys and the like. He would 'ave had a mould, I imagine.") + .playerl("Where is he now?") + .npcl("E's dead, just like everyone else round 'ere... 'cept for me.") + .end() + optionBuilder.option("What happened to your head?") + .playerl("What happened to your head?") + .item(Items.GHOSTSPEAK_AMULET_552, "You feel power emanate from the Amulet of Ghostspeak", "and the air around you vibrates with the ghostly voice", "of the headless gardener.") + .npcl("Oi was in the old 'aunted Forest to the south, diggin' a pit for moi old master, old Fenkenstrain, when would you believe it, someone chops me head off. Awful bad luck weren't it?") + .playerl("Oh yes, dreadful bad luck.") + .npcl("So oi thinks to meself, I don't needs any 'ead to be getting on with me gardenin', long as I got me hands and me spade.") + .playerl("Would you show me where the place was?") + .npcl("Well, oi s'pose oi've got ten minutes to spare.") + .endWith { df, player -> (df.npc!! as GardenerGhostNPC).startFollowing(player) } + optionBuilder.optionIf("What's your name?") { player -> return@optionIf getQuestStage( + player, + Quests.CREATURE_OF_FENKENSTRAIN + ) < 4 } + .playerl("What's your name?") + .item(Items.GHOSTSPEAK_AMULET_552, "You feel power emanate from the Amulet of Ghostspeak", "and the air around you vibrates with the ghostly voice", "of the headless gardener.") + .npcl("Me name? It's been a moivellous long while, mate, since I had any use for such a thing as a name.") + .playerl("Don't worry, I was just trying to make conversation.") + .npcl("No, no, I can't be havin' that. I'll remember in a minute...") + .playerl("Please, don't worry.") + .npcl("Lestwit, that's it! Ed Lestwit.") + .end() + } + + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/GardenerGhostNPC.kt b/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/GardenerGhostNPC.kt new file mode 100644 index 0000000..750343b --- /dev/null +++ b/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/GardenerGhostNPC.kt @@ -0,0 +1,88 @@ +package content.region.morytania.quest.creatureoffenkenstrain + +import core.api.teleport +import core.game.interaction.MovementPulse +import core.game.node.entity.impl.PulseType +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.game.world.map.path.Pathfinder +import core.plugin.Initializable +import core.tools.secondsToTicks +import org.rs09.consts.NPCs + +@Initializable +class GardenerGhostNPC : AbstractNPC { + var target: Player? = null + var ticksLeft = secondsToTicks(0) + val graveLocation = Location(3608, 3490) + + constructor() : super(NPCs.GARDENER_GHOST_1675, null, true) {} + private constructor(id: Int, location: Location) : super(id, location) {} + + override fun construct(id: Int, location: Location, vararg objects: Any?): AbstractNPC { + return GardenerGhostNPC(id, location) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.GARDENER_GHOST_1675) + } + + override fun handleTickActions() { + if (target == null) { + super.handleTickActions() + } else { + val distance = location.getDistance(target!!.location) + if (distance > 10) { + teleport(this, target!!.location) + } + if (ticksLeft > 0) { + ticksLeft-- + } + + if (this.location.withinDistance(graveLocation, 5) && ticksLeft > secondsToTicks(5)) { + // If gardener is about to reach his grave. + ticksLeft = secondsToTicks(4) + sendChat("Here is the place where I met me' maker.") + } + if (!properties.spawnLocation.withinDistance(target!!.location, 160) && ticksLeft > secondsToTicks(5)) { + // If person is about to walk outside of the range + ticksLeft = secondsToTicks(4) + sendChat("Fare thee well - oi must return to me' garden.") + } + if (ticksLeft == secondsToTicks(5)) { + // https://www.youtube.com/watch?v=RoR6zLGrRoY 2:07 + sendChat("Fare thee well - oi must return to me' garden.") + } + if (ticksLeft == 0) { + // No time left, reset him back. + target = null + pulseManager.clear(PulseType.STANDARD) + walkRadius = 11 + teleport(properties.spawnLocation) + } + } + } + + fun startFollowing(player: Player) { + ticksLeft = secondsToTicks(120) // You have two minutes to let him show you where his grave is. + target = player + walkRadius = 200 + + pulseManager.run((object : MovementPulse(this, player, Pathfinder.DUMB) { + override fun pulse(): Boolean { + face(player) + return false + } + }), PulseType.STANDARD) + } + + fun continueFollowing(player: Player) { + pulseManager.run((object : MovementPulse(this, player, Pathfinder.DUMB) { + override fun pulse(): Boolean { + face(player) + return false + } + }), PulseType.STANDARD) + } +} diff --git a/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/LordRologarthDialogue.kt b/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/LordRologarthDialogue.kt new file mode 100644 index 0000000..6fd066d --- /dev/null +++ b/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/LordRologarthDialogue.kt @@ -0,0 +1,72 @@ +package content.region.morytania.quest.creatureoffenkenstrain + +import content.data.Quests +import core.api.* +import core.game.dialogue.DialogueBuilder +import core.game.dialogue.DialogueBuilderFile +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class LordRologarthDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return LordRologarthDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, LordRologarthDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + // THE IDs ARE WRONG. 1671 and 1672 are varp controlled Lord Rologarth + return intArrayOf(NPCs.DR_FENKENSTRAIN_1671, NPCs.DR_FENKENSTRAIN_1672, NPCs.FENKENSTRAINS_MONSTER_1673) + } +} + +class LordRologarthDialogueFile : DialogueBuilderFile() { + override fun create(b: DialogueBuilder) { + b.onQuestStages(Quests.CREATURE_OF_FENKENSTRAIN, 6) + .playerl("I am commanded to destroy you, creature!") + .npcl("Oh that's *hic* not very *hic* nice ...") + .playerl("Are you feeling ok?") + .npcl("Abso *hic* lutely. Never *buuurrp* better.") + .playerl("You don't look very dangerous.") + .npcl("How *hic* do I look?") + .playerl("You really don't know, do you? Have a look for yourself.") + .line("The creature stumbles over towards the mirror, focuses upon his", "reflection and...") + .npcl("AAAAARRGGGGHHHH!") + .line("The creature becomes instantly sober, horror all too evident in his", "undead eyes.") + .playerl("I'm sorry. I suppose I'm partly to blame for this.") + .npcl("No - it was him I wager - Fenkenstrain - wasn't it? He's brought me back to life!") + .playerl("Who are - were - you?") + .npcl("I was Rologarth, Lord of the North Coast - this castle was once mine. Fenkenstrain was the castle doctor.") + .playerl("So the castle wasn't really abandoned when he found it?") + .npcl("Is that what he told you? No, no, this castle was once full of people and life. Fenkenstrain advised me to sell them to the vampyres, which - I am sad to say - I did.") + .playerl("I found your brain in a jar in Canifis, so he must have sold you too.") + .npcl("Of that I will not speak. There lie memories that should rest with the dead, the living unable to bear them.") + .playerl("That's it - I'm leaving this dreadful place, whether I get paid or not. Is there anything I can do for you before I leave?") + .npcl("Only one - please stop Fenkenstrain from carrying on his experiments, once and for all, so that no other poor soul has to endure suffering such as that of my people and I.") + .endWith() { df, player -> + if(getQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN) == 6) { + setQuestStage(player, Quests.CREATURE_OF_FENKENSTRAIN, 7) + } + } + b.onQuestStages(Quests.CREATURE_OF_FENKENSTRAIN, 7) + .playerl(FacialExpression.THINKING, "Do you know how I can stop Fenkenstrain's experiments?") + .npcl("Take the Ring of Charos from him.") + .playerl(FacialExpression.THINKING, "What is this ring?") + .npcl("It was my birthright, passed down to me through the ages, its origin forgotten.") + .npcl("The Ring of Charos has many powers, but Fenkenstrain has bent them to his down evil purposes. Without the power of the ring, he will not be able to raise the dead from their sleep.") + .npcl("It has one other, extremely important use - it confuses the werewolves' senses, making them believe that they smell one of their own kind. Without the ring, Fenkenstrain will be at their mercy.") + .end() + b.onQuestStages(Quests.CREATURE_OF_FENKENSTRAIN, 8, 100) + .npcl("How goes it, friend?") + .playerl("I stole the Ring of Charos from Fenkenstrain.") + .npcl("I saw him climb up into the Tower to hide. It doesn't matter - soon the werewolves will come for him, and his experiments will be forever ceased.") + .playerl(FacialExpression.THINKING, "Do you want the ring back? It is yours after all.") + .npcl("No, you keep it, my friend. Werewolves hunger for the scent of live flesh - I have no need for the ring. I have my castle back, if not my soul.") + .end() + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/RoavarDialogueFile.kt b/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/RoavarDialogueFile.kt new file mode 100644 index 0000000..330fa64 --- /dev/null +++ b/Server/src/main/content/region/morytania/quest/creatureoffenkenstrain/RoavarDialogueFile.kt @@ -0,0 +1,54 @@ +package content.region.morytania.quest.creatureoffenkenstrain + +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.dialogue.Topic +import core.game.node.item.Item +import core.tools.END_DIALOGUE +import core.tools.START_DIALOGUE +import org.rs09.consts.Items + +class RoavarDialogueFile(private val dialogueNum: Int = 0) : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when (stage) { + START_DIALOGUE -> { + if (dialogueNum == 1) { + npcl("If you've got the money, I've got a real treat for you.") + stage = 1 + } else if (dialogueNum == 2) { + npcl("You're interested in our speciality, I see. Would you like to buy some?") + stage = 2 + } else if (dialogueNum == 3) { + npcl("You can leave that alone, my friend. I've already sold you one of your own - eat that. I can't afford to give away freebies in this business!") + stage = END_DIALOGUE + } else { + npcl("Hey! Don't touch that.") + stage = END_DIALOGUE + } + } + 1 -> playerl("What have you got?").also { stage = 3 } + 2 -> playerl("What exactly is in the jar?").also { stage = 3 } + 3 -> npcl("Pickled brain, my friend. Only 50 gold to you.").also { stage++ } + 4 -> playerl("Err... pickled brain from what animal?").also { stage++ } + 5 -> npcl("Animal? Don't be disgusting, man! No, this a human brain - only the best for my customers.").also { stage++ } + 6 -> showTopics( + Topic(FacialExpression.HALF_GUILTY, "I'll buy one.", 10, true), + Topic(FacialExpression.HALF_GUILTY, "I'm not hungry.", 20, true), + ) + 10 -> playerl("I'll buy one, please.").also { stage++ } + 11 -> { + if (amountInInventory(player!!, Items.COINS_995) >= 50) { + if(removeItem(player!!, Item(Items.COINS_995, 50))) { + addItemOrDrop(player!!, Items.PICKLED_BRAIN_4199, 1) + npcl("A very wise choice. Don't eat it all at once, savour every morsel - that's my advice to you.") + } + } else { + sendDialogue(player!!, "You do not have enough coins.") + } + stage = END_DIALOGUE + } + 20 -> playerl("I'm afraid I'm not really hungry at the moment.").also { stage = END_DIALOGUE } + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/morytania/quest/naturespirit/FillimanTarlockNPC.kt b/Server/src/main/content/region/morytania/quest/naturespirit/FillimanTarlockNPC.kt new file mode 100644 index 0000000..3fc36b2 --- /dev/null +++ b/Server/src/main/content/region/morytania/quest/naturespirit/FillimanTarlockNPC.kt @@ -0,0 +1,32 @@ +package content.region.morytania.quest.naturespirit + +import core.api.* +import core.game.node.entity.npc.AbstractNPC +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.NPCs + +@Initializable +class FillimanTarlockNPC : AbstractNPC { + var spawnedTicks = 0 + constructor() : super(NPCs.FILLIMAN_TARLOCK_1050, null, true) {} + private constructor(id: Int, location: Location) : super(id, location) {} + + override fun construct(id: Int, location: Location, vararg objects: Any?): AbstractNPC { + return FillimanTarlockNPC(id, location) + } + + init { + isNeverWalks = true + isWalks = false + } + + override fun handleTickActions() { + super.handleTickActions() + if(spawnedTicks++ > 100) poofClear(this) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.FILLIMAN_TARLOCK_1050) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/morytania/quest/naturespirit/NSDrezelDialogue.kt b/Server/src/main/content/region/morytania/quest/naturespirit/NSDrezelDialogue.kt new file mode 100644 index 0000000..8bfa233 --- /dev/null +++ b/Server/src/main/content/region/morytania/quest/naturespirit/NSDrezelDialogue.kt @@ -0,0 +1,120 @@ +package content.region.morytania.quest.naturespirit + +import core.api.* +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.system.task.Pulse +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import org.rs09.consts.Items +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.tools.END_DIALOGUE +import org.rs09.consts.Sounds +import content.data.Quests + +class NSDrezelDialogue : DialogueFile() { + var questStage = 0 + override fun handle(componentID: Int, buttonID: Int) { + questStage = player!!.questRepository.getStage(Quests.NATURE_SPIRIT) + + if(questStage <= 5){ + when(stage){ + 0 -> options("Sorry, not interested...", "Well, what is it, I may be able to help?").also { stage++ } + 1 -> when(buttonID){ + 1 -> playerl(FacialExpression.NEUTRAL, "Sorry, not interested.").also { stage = END_DIALOGUE } + 2 -> playerl(FacialExpression.FRIENDLY, "Well, what is it, I may be able to help?").also { stage++ } + } + + 2 -> npcl(FacialExpression.HALF_THINKING, "There's a man called Filliman who lives in Mort Myre, I wonder if you could look for him? The swamps of Mort Myre are dangerous though, they're infested with Ghasts!").also { stage++ } + 3 -> options("Who is this Filliman?", "Where's Mort Myre?", "What's a Ghast?", "Yes, I'll go and look for him.", "Sorry, I don't think I can help.").also { stage++ } + 4 -> when(buttonID){ + 1 -> npcl(FacialExpression.NEUTRAL, "Filliman Tarlock is his full name and he's a Druid. He lives in Mort Myre much like a hermit, but there's many a traveller who he's helped.").also { stage-- } + 2 -> npcl(FacialExpression.NEUTRAL, "Mort Myre is a decayed and dangerous swamp to the south. It was once a beautiful forest but has since become filled with vile emanations from within Morytania.").also { stage = 6 } + 3 -> npcl(FacialExpression.NEUTRAL, "A Ghast is a poor soul who died in Mort Myre. They're undead of a special class, they're untouchable as far as I'm aware!").also { stage = 5 } + 4 -> playerl(FacialExpression.FRIENDLY, "Yes, I'll go and look for him.").also { stage = 10 } + 5 -> playerl(FacialExpression.NEUTRAL, "Sorry, I don't think I can help.").also { stage = END_DIALOGUE } + } + 5 -> npcl(FacialExpression.NEUTRAL, "Filliman knew how to tackle them, but I've not heard from him in a long time. Ghasts, when they attack, will devour any food you have. If you have no food, they'll draw their nourishment from you!").also { stage = 3 } + 6 -> npcl(FacialExpression.NEUTRAL, " We put a fence around it to stop unwary travellers going in. Anyone who dies in the swamp is forever cursed to haunt it as a Ghast. Ghasts attack travellers, turning food to rotten filth.").also { stage = 3 } + + 10 -> npcl(FacialExpression.NEUTRAL, "That's great, but it is very dangerous. Are you sure you want to do this?").also { stage++ } + 11 -> options("Yes, I'm sure.", "Sorry, I don't think I can help.").also { stage++ } + 12 -> when(buttonID){ + 1 -> playerl(FacialExpression.FRIENDLY, "Yes, I'm sure.").also { stage = 20 } + 2 -> playerl(FacialExpression.NEUTRAL, "Sorry, I don't think I can help.").also { stage = END_DIALOGUE } + } + + 20 -> npcl(FacialExpression.NEUTRAL, "That's great! Many thanks! Now then, please be aware of the Ghasts, you cannot attack them, only Filliman knew how to take them on.").also { stage++ } + 21 -> npcl(FacialExpression.NEUTRAL, "Just run from them if you can. If you start to get lost, try to make your way back to the temple.").also { stage++ } + 22 -> { + sendDoubleItemDialogue(player!!, Items.MEAT_PIE_2327, Items.APPLE_PIE_2323, "The cleric hands you some food.") + if(questStage == 0){ + repeat(3) { addItemOrDrop(player!!, Items.MEAT_PIE_2327, 1) } + repeat(3) { addItemOrDrop(player!!, Items.APPLE_PIE_2323, 1) } + player!!.questRepository.getQuest(Quests.NATURE_SPIRIT).setStage(player!!, 5) + } + stage++ + } + 23 -> npcl(FacialExpression.NEUTRAL, "Please take this food to Filliman, he'll probably appreciate a bit of cooked food. Now, he's never revealed where he lives in the swamps but I guess he'd be to the south, search for him won't you?").also { stage++ } + 24 -> playerl(FacialExpression.FRIENDLY, "I'll do my very best, don't worry, if he's in there and he's still alive I'll definitely find him.").also { stage = END_DIALOGUE; player!!.questRepository.getQuest(Quests.NATURE_SPIRIT).start(player!!) } + } + } + + else if(questStage == 15) { + when(stage){ + 0 -> playerl(FacialExpression.HALF_GUILTY, "I've found Filliman and you should prepare for some sad news.").also { stage++ } + 1 -> npcl(FacialExpression.HALF_GUILTY, "You mean... he's dead?").also { stage++ } + 2 -> playerl(FacialExpression.NEUTRAL, "Well, er sort of. I got to his camp and I encountered a spirit of some kind. I don't think it was a Ghast, it tried to communicate with me, but made no sense, it was all 'ooooh' this and 'oooh' that.").also { stage++ } + 3 -> npcl(FacialExpression.NEUTRAL, "Hmmm, that's very interesting, I seem to remember Father Aereck in Lumbridge and his predecessor Father Urhney having a similar issue. Though this is probably not related to your problem.").also { stage++ } + 4 -> npcl(FacialExpression.NEUTRAL, " I will pray that it wasn't the spirit of my friend Filliman, but some lost soul who needs some help. Please do let me know how you get on with it.").also { stage = END_DIALOGUE } + } + } + + else if(questStage == 35){ + when(stage){ + 0 -> playerl(FacialExpression.FRIENDLY, "Hello again! I'm helping Filliman, he plans to become a nature spirit. I have a spell to cast but first I need to be blessed. Can you bless me?").also { stage++ } + 1 -> npcl(FacialExpression.NEUTRAL, "But you haven't sneezed!").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "You're so funny! But can you bless me?").also { stage++ } + 3 -> npcl(FacialExpression.NEUTRAL, "Very well my friend, prepare yourself for the blessings of Saradomin. Here we go!").also { stage++ } + 4 -> { + end() + player!!.lock() + submitIndividualPulse(player!!, BlessingPulse(npc!!, player!!)) + } + } + } + + else if(questStage == 40){ + npcl(FacialExpression.NEUTRAL, "There you go my friend, you're now blessed. It's funny, now I look at you, there seems to be something of the faith about you. Anyway, good luck with your quest!").also { stage = END_DIALOGUE; player!!.questRepository.getQuest(Quests.NATURE_SPIRIT).setStage(player!!, 45) } + } + + else { + when(stage){ + 0 -> npcl(FacialExpression.NEUTRAL, "Hello, friend, how goes your quest with Filliman?").also { stage++ } + 1 -> playerl(FacialExpression.NEUTRAL, "Still working at it.").also { stage++ } + 2 -> npcl(FacialExpression.NEUTRAL, "Well enough! Do let me know when something develops!").also { stage = END_DIALOGUE } + } + } + } + +} + +private class BlessingPulse(val drezel: NPC, val player: Player) : Pulse(){ + var ticks = 0 + + override fun pulse(): Boolean { + when(ticks){ + 0 -> animate(drezel, 1162).also { spawnProjectile(drezel, player, 268); playAudio(player, Sounds.PRAYER_RECHARGE_2674) } + 2 -> visualize(player, Animation(645), Graphics(267, 100)) + 4 -> unlock(player).also { player.questRepository.getQuest(Quests.NATURE_SPIRIT).setStage(player, 40); return true } + } + ticks++ + return false + } + + override fun stop() { + super.stop() + openDialogue(player, NSDrezelDialogue(), drezel) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/morytania/quest/naturespirit/NSListeners.kt b/Server/src/main/content/region/morytania/quest/naturespirit/NSListeners.kt new file mode 100644 index 0000000..0be9056 --- /dev/null +++ b/Server/src/main/content/region/morytania/quest/naturespirit/NSListeners.kt @@ -0,0 +1,262 @@ +package content.region.morytania.quest.naturespirit + +import core.api.Container +import core.api.* +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.GroundItem +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.game.world.map.Location +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import core.game.dialogue.DialogueFile +import core.game.global.action.PickupHandler +import core.game.shops.Shops +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import content.region.morytania.handlers.MortMyreGhastNPC +import core.tools.END_DIALOGUE +import core.tools.Log +import content.data.Quests + +class NSListeners : InteractionListener { + + val GROTTO_TREE = 3517 + val GROTTO_ENTRANCE = 3516 + val GROTTO_ALTAR = 3520 + val NATURE_ALTAR = 3521 + val JOURNAL = Items.JOURNAL_2967 + val NATURE_STONE = 3527 + val FAITH_STONE = 3528 + val FREELY_GIVEN_STONE = 3529 + val WASHING_BOWL = Items.WASHING_BOWL_2964 + val MIRROR = Items.MIRROR_2966 + val SPELLCARD = Items.DRUIDIC_SPELL_2968 + val USED_SPELLCARD = Items.A_USED_SPELL_2969 + val FUNGUS = Items.MORT_MYRE_FUNGUS_2970 + val STEM = Items.MORT_MYRE_STEM_2972 + val PEAR = Items.MORT_MYRE_PEAR_2974 + val MIRROR_TAKEN = "/save:ns:mirror_taken" + val GROTTO_SEARCHED = "/save:ns:grotto_searched" + val WISHING_WELL = 28715 + val DRUID_POUCH = Items.DRUID_POUCH_2958 + val DRUID_POUCH_EMPTY = Items.DRUID_POUCH_2957 + val stones = intArrayOf(NATURE_STONE, FAITH_STONE, FREELY_GIVEN_STONE) + val items = intArrayOf(USED_SPELLCARD, FUNGUS) + + override fun defineListeners() { + on(GROTTO_TREE, IntType.SCENERY, "look-at"){ player, _ -> + sendMessage(player, "It looks like a tree on a large rock with roots trailing down to the ground.") + return@on true + } + + on(GROTTO_TREE, IntType.SCENERY, "search"){ player, _ -> + if(!getAttribute(player, GROTTO_SEARCHED, false) || !(inInventory(player, JOURNAL) || inBank(player, JOURNAL))){ + sendItemDialogue(player, JOURNAL, "You search the strange rock. You find a knot and inside of it you discover a small tome. The words on the front are a bit vague, but you can make out the words 'Tarlock' and 'journal'.") + addItemOrDrop(player, JOURNAL, 1) + setAttribute(player, GROTTO_SEARCHED, true) + return@on true + } + return@on false + } + + on(GROTTO_ENTRANCE, IntType.SCENERY, "enter"){ player, node -> + val questStage = player.questRepository.getQuest(Quests.NATURE_SPIRIT).getStage(player) + if(questStage < 55) { + val npc = core.game.node.entity.npc.NPC.create(NPCs.FILLIMAN_TARLOCK_1050, Location.create(3440, 3336, 0)) + npc.init() + } else if(questStage < 60) { + player.teleport(Location.create(3442, 9734, 0)) + } else if (questStage >= 60){ + player.teleport(Location.create(3442, 9734, 1)) + } + return@on true + } + + on(GROTTO_ALTAR, IntType.SCENERY, "search"){ player, node -> + val stage = player.questRepository.getStage(Quests.NATURE_SPIRIT) + if(stage == 55){ + openDialogue(player, FillimanCompletionDialogue(), NPC(NPCs.FILLIMAN_TARLOCK_1050)) + return@on true + } + + return@on false + } + + on(NATURE_STONE, IntType.SCENERY, "search"){ player, _ -> + sendDialogue(player, "You search the stone and find that it has some sort of nature symbol scratched into it.") + return@on true + } + + on(FAITH_STONE, IntType.SCENERY, "search"){ player, _ -> + sendDialogue(player, "You search the stone and find that it has some sort of faith symbol scratched into it.") + return@on true + } + + on(FREELY_GIVEN_STONE, IntType.SCENERY, "search"){ player, _ -> + sendDialogue(player, "You search the stone and find it has some sort of spirit symbol scratched into it.") + return@on true + } + + on(WISHING_WELL, IntType.SCENERY, "make-wish"){ player, node -> + if(player.questRepository.isComplete(Quests.NATURE_SPIRIT) && player.questRepository.isComplete(Quests.WOLF_WHISTLE)) + Shops.openId(player, 241) + else + sendDialogue(player, "You can't do that yet.") + + return@on true + } + + on(JOURNAL, IntType.ITEM, "read"){ player, _ -> + player.dialogueInterpreter.open(NSJournalDialogue()) + return@on true + } + + on(WASHING_BOWL, IntType.GROUNDITEM, "take"){ player, node -> + log(this::class.java, Log.FINE, "Running listener") + GroundItemManager.create(Item(MIRROR), node.location, player) + PickupHandler.take(player, node as GroundItem) + return@on true + } + + on(MIRROR, IntType.GROUNDITEM, "take"){ player, node -> + if(getAttribute(player, MIRROR_TAKEN, false) && (inInventory(player, MIRROR) || inBank(player, MIRROR))){ + sendDialogue(player, "I don't need another one of these.") + return@on true + } + setAttribute(player, MIRROR_TAKEN, true) + PickupHandler.take(player, node as GroundItem) + return@on true + } + + on(SPELLCARD, IntType.ITEM, "cast"){ player, node -> + if(NSUtils.castBloom(player)){ + removeItem(player, node.asItem(), Container.INVENTORY) + addItem(player, Items.A_USED_SPELL_2969) + } + return@on true + } + + on(intArrayOf(DRUID_POUCH, DRUID_POUCH_EMPTY), IntType.ITEM, "fill"){ player, node -> + + if(player.questRepository.getStage(Quests.NATURE_SPIRIT) >= 75) { + if (amountInInventory(player, PEAR) >= 3) { + if (node.id != Items.DRUID_POUCH_2958) { + removeItem(player, node, Container.INVENTORY) + } + removeItem(player, Item(PEAR, 3), Container.INVENTORY) + addItem(player, Items.DRUID_POUCH_2958, 9 ) + } else if (amountInInventory(player, STEM) >= 3) { + if (node.id != Items.DRUID_POUCH_2958) { + removeItem(player, node, Container.INVENTORY) + } + removeItem(player, Item(STEM, 3), Container.INVENTORY) + addItem(player, Items.DRUID_POUCH_2958, 6) + } else if (amountInInventory(player, FUNGUS) >= 3) { + if (node.id != Items.DRUID_POUCH_2958) { + removeItem(player, node, Container.INVENTORY) + } + removeItem(player, Item(FUNGUS, 3), Container.INVENTORY) + addItem(player, Items.DRUID_POUCH_2958, 3) + } else { + sendDialogue(player, "You need 3 fungus before you can do that.") + } + } else { + sendDialogue(player, "I don't know how to use that yet.") + } + + return@on true + } + + onUseWith(IntType.SCENERY, Items.SILVER_SICKLE_2961, NATURE_ALTAR){ player, used, with -> + sendItemDialogue(player, Items.SILVER_SICKLEB_2963, "You dump the sickle into the waters.") + if(removeItem(player, Items.SILVER_SICKLE_2961, Container.INVENTORY)){ + addItem(player, Items.SILVER_SICKLEB_2963, 1) + } + return@onUseWith true + } + + onUseWith(IntType.NPC, DRUID_POUCH, NPCs.GHAST_1052){ player, used, with -> + NSUtils.activatePouch(player, with as MortMyreGhastNPC) + } + + onUseWith(IntType.NPC, Items.SECATEURS_5329, NPCs.NATURE_SPIRIT_1051) {player, used, with -> + if (!hasRequirement(player, Quests.FAIRYTALE_I_GROWING_PAINS)) + return@onUseWith true + if (amountInInventory(player, Items.COINS_995) < 40000) { + sendDialogue(player, "You need 40,000 coins to do this.") + return@onUseWith true + } + if (removeItem(player, used) && removeItem(player, Item(Items.COINS_995, 40000))) { + sendItemDialogue(player, Items.MAGIC_SECATEURS_7409, "Your secateurs are enchanted into magic secateurs") + addItem(player, Items.MAGIC_SECATEURS_7409) + } + return@onUseWith true + } + + onUseWith(IntType.SCENERY, items, *stones) { player, used, with -> + when (used.id) { + USED_SPELLCARD -> { + if (with.id == FREELY_GIVEN_STONE) { + if(removeItem(player, used, Container.INVENTORY)){ + sendNPCDialogue(player, NPCs.FILLIMAN_TARLOCK_1050, "Aha, yes, that seems right well done!") + sendMessage(player, "The stone seems to absorb the used spell scroll.") + NSUtils.flagCardPlaced(player) + } + } else sendMessage(player, "You try to put the item on the stone, but it just moves off.") + } + + FUNGUS -> { + if (with.id == NATURE_STONE) { + if(removeItem(player, used, Container.INVENTORY)){ + sendNPCDialogue(player, NPCs.FILLIMAN_TARLOCK_1050, "Aha, yes, that seems right well done!") + sendMessage(player, "The stone seems to absorb the used fungus.") + NSUtils.flagFungusPlaced(player) + } + } else sendMessage(player, "You try to put the item on the stone, but it just moves off.") + } + } + return@onUseWith true + } + } +} + +class NSJournalDialogue : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when(stage){ + 0 -> dialogue(*splitLines("Most of the writing is pretty uninteresting, but something inside refers to a nature spirit. The requirements for which are,")).also { stage++ } + 1 -> dialogue(*splitLines("'Something from nature', 'something with faith' and 'something of the spirit-to-become freely given'. It's all pretty vague.")).also { stage = END_DIALOGUE } + } + } +} + +class FillimanCompletionDialogue : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + when(stage){ + 0 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "Well, hello there again. I was just enjoying the grotto. Many thanks for your help, I couldn't have become a Spirit of nature without you.").also { stage++ } + 1 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "I must complete the transformation now. Just stand there and watch the show, apparently it's quite good!").also { stage++ } + 2 -> { + end() + lock(player!!, 10) + submitWorldPulse(CompleteSpellPulse(player!!)) + } + } + } +} + +class CompleteSpellPulse(val player: Player) : Pulse(2){ + var counter = 0 + val locations = arrayOf(Location.create(3444, 9740, 0), Location.create(3439, 9740, 0), Location.create(3439, 9737, 0), Location.create(3444, 9737, 0), Location.create(3444, 9735, 0), Location.create(3438, 9735, 0)) + val dest = Location.create(3441, 9738, 0) + override fun pulse(): Boolean { + when(counter++){ + 0 -> repeat(6) { spawnProjectile(locations[it], dest, 268, 0, 1000, 0, 40, 20) } + 1 -> player.questRepository.getQuest(Quests.NATURE_SPIRIT).setStage(player, 60) + 2 -> player.teleport(player.location.transform(0,0,1)) + 3 -> openDialogue(player, NPCs.NATURE_SPIRIT_1051, findLocalNPC(player, NPCs.NATURE_SPIRIT_1051) as NPC).also { unlock(player); return true } + } + return false + } +} diff --git a/Server/src/main/content/region/morytania/quest/naturespirit/NSTarlockDialogue.kt b/Server/src/main/content/region/morytania/quest/naturespirit/NSTarlockDialogue.kt new file mode 100644 index 0000000..d7bdaba --- /dev/null +++ b/Server/src/main/content/region/morytania/quest/naturespirit/NSTarlockDialogue.kt @@ -0,0 +1,240 @@ +package content.region.morytania.quest.naturespirit + +import core.api.Container +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.update.flag.context.Graphics +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import core.tools.END_DIALOGUE +import content.data.Quests + +@Initializable +class NSTarlockDialogue(player: Player? = null) : DialoguePlugin(player) { + var questStage = 0 + + override fun newInstance(player: Player?): DialoguePlugin { + return NSTarlockDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + val quest = player.questRepository.getQuest(Quests.NATURE_SPIRIT) + questStage = quest.getStage(player) + + if(questStage > 10 && !inEquipment(player, Items.GHOSTSPEAK_AMULET_552)){ + npcl(FacialExpression.HALF_GUILTY, "OooOOOOOOoooOoOOoOOOo") + setQuest(15) + return false + } + + when(questStage){ + 10, 15 -> sendDialogue("A shifting apparition appears in front of you.").also { stage = 1000 } + 20 -> npcl(FacialExpression.HALF_GUILTY, "Oh, hello there, do you still think I'm dead? It's hard to see how I could be dead when I'm still in the world. I can see everything quite clearly. And nothing of what you say reflects the truth.") + 25 -> npcl(FacialExpression.HALF_GUILTY, "Oh, hello... Sorry, you've caught me at a bad time, it's just that I've had a sign you see and I need to find my journal.").also { stage = 7 } + 30 -> npcl(FacialExpression.HALF_GUILTY, "Thanks for the journal, I've been reading it. It looks like I came to a violent and bitter end but that's not really important. I just have to figure out what I am going to do now?").also { stage = 14 } + 35 -> npcl(FacialExpression.NEUTRAL, "Hello there, have you been blessed yet?").also { stage = 60 } + 45 -> { + if(inInventory(player, Items.MORT_MYRE_FUNGUS_2970)){ + npcl(FacialExpression.NEUTRAL, "Did you manage to get something from nature?").also { stage = 80 } + } else { + playerl( + FacialExpression.NEUTRAL, + "Hello, I've been blessed but I don't know what to do now." + ).also { stage = 70 } + } + } + 50 -> npcl(FacialExpression.NEUTRAL, " Hello again! I don't suppose you've found out what the other components of the Nature spell are have you?").also { stage = 90 } + else -> npcl(FacialExpression.NEUTRAL, ".......").also { stage = END_DIALOGUE } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> if(inInventory(player, Items.MIRROR_2966)){ + sendDialogue("You use the mirror on the spirit","of the dead Filliman Tarlock.").also { stage++ } + } else { + playerl(FacialExpression.NEUTRAL, "Yes, I do think you're dead and I'll prove it somehow.").also { stage = 1002 } + } + + 1 -> playerl(FacialExpression.NEUTRAL, "Here take a look at this, perhaps you can see that you're utterly transparent now!").also { stage++ } + 2 -> sendDialogue("The spirit of Filliman reaches forwards and takes the mirror.").also { stage++ } + 3 -> npcl(FacialExpression.HALF_GUILTY, "Well, that is the most peculiar thing I've ever experienced. Strange how well it reflects the stagnant swamp behind me, but there is nothing of my own visage apparent.").also { stage++ } + 4 -> playerl(FacialExpression.NEUTRAL, "That's because you're dead! Dead as a door nail... Deader in fact... You bear a remarkable resemblance to wormbait! Err... No offence...").also { stage++ } + 5 -> npcl(FacialExpression.HALF_GUILTY, "I think you might be right my friend, though I still feel very much alive. It is strange how I still come to be here and yet I've not turned into a Ghast.").also { stage++ } + 6 -> npcl(FacialExpression.HALF_GUILTY, " It must be a sign... Yes a sign... I must try to find out what it means. Now, where did I put my journal?").also { stage++ } + 7 -> if(!inInventory(player, Items.JOURNAL_2967)){ + playerl(FacialExpression.NEUTRAL, "Where did you put it?").also { stage++; setQuest(25) } + } else sendDialogue("You give the journal to Filliman Tarlock").also { removeItem(player, Items.JOURNAL_2967, Container.INVENTORY); stage = 10; setQuest(30) } + + //no journal + 8 -> npcl(FacialExpression.HALF_GUILTY, "Well, if I knew that, I wouldn't still be looking for it. However, I do remember something about a knot? Perhaps I was meant to tie a knot or something?").also { stage = END_DIALOGUE } + + //has journal + 10 -> playerl(FacialExpression.NEUTRAL, "Here, I found this, maybe you can use it?").also { stage++ } + 11 -> npcl(FacialExpression.FRIENDLY, "My journal! That should help to collect my thoughts.").also { stage++ } + 12 -> sendDialogue("~ The spirit starts leafing through the journal. ~", "~ He seems quite distant as he regards the pages. ~", "~ After some time the druid faces you again. ~").also {stage++} + 13 -> npcl(FacialExpression.HALF_GUILTY, "It's all coming back to me now. It looks like I came to a violent and bitter end but that's not important now. I just have to figure out what I am going to do now?").also { stage++ } + 14 -> options("Being dead, what options do you think you have?", "So, what's your plan?", "Well, good luck with that.", "How can I help?", "Ok thanks.").also { stage++ } + 15 -> when(buttonId){ + 1 -> playerl(FacialExpression.NEUTRAL, "Being dead, what options do you think you have? I'm not trying to be rude or anything, but it's not like you have many options is it? I mean, it's either up or down for you isn't it?").also { stage = 20 } + 2 -> playerl(FacialExpression.NEUTRAL, "So, what's your plan?").also { stage = 30 } + 3 -> playerl(FacialExpression.NEUTRAL, "Well, good luck with that.").also { stage = 40 } + 4 -> playerl(FacialExpression.NEUTRAL, "How can I help?").also { stage = 50 } + 5 -> playerl(FacialExpression.NEUTRAL, "Ok thanks.").also { stage = END_DIALOGUE } + } + + //Being dead, what options + 20 -> npcl(FacialExpression.HALF_GUILTY, "Hmm, well you're a poetic one aren't you. Your material world logic stands you in good stead... If you're standing in the material world...").also { stage = 14 } + + //what's your plan? + 30 -> npcl(FacialExpression.HALF_GUILTY, "In my former incarnation I was Filliman Tarlock, a great druid of some power. I spent many years in this place, which was once a forest and I would wish to protect it as a nature spirit.").also { stage = 14 } + + //good luck with that + 40 -> npcl(FacialExpression.HALF_GUILTY, "Won't you help me to become a nature spirit? I could really use your help!").also { stage = 14 } + + //How can I help? + 50 -> npcl(FacialExpression.HALF_GUILTY, "Will you help me to become a nature spirit? The directions for becoming one are a bit vague, I need three things but I know how to get one of them. Perhaps you can help collect the rest?").also { stage++ } + 51 -> playerl(FacialExpression.NEUTRAL, "I might be interested, what's involved?").also { stage++ } + 52 -> npcl(FacialExpression.HALF_GUILTY, "Well, the book says, that I need, and I quote:- 'Something with faith', 'something from nature' and the 'spirit-to-become' freely given'. Hmm, I know how to get something from nature.").also { stage++ } + 53 -> playerl(FacialExpression.NEUTRAL, "Well, that does seem a bit vague.").also { stage++ } + 54 -> npcl(FacialExpression.HALF_GUILTY, "Hmm, it does and I could understand if you didn't want to help. However, if you could perhaps at least get the item from nature, that would be a start. Perhaps we can figure out the rest as we go along.").also { stage++ } + 55 -> sendDialogue(*splitLines("The druid produces a small sheet of papyrus with some writing on it.")).also { addItemOrDrop(player, Items.DRUIDIC_SPELL_2968); setQuest(35); stage++ } + 56 -> npcl(FacialExpression.NEUTRAL, "This spell needs to be cast in the swamp after you have been blessed. I'm afraid you'll need to go to the temple to the North and ask a member of the clergy to bless you.").also { stage++ } + 57 -> playerl(FacialExpression.NEUTRAL, "Blessed, what does that do?").also { stage++ } + 58 -> npcl(FacialExpression.NEUTRAL, "It is required if you're to cast this druid spell. Once you've cast the spell, you should find something from nature. Bring it back to me and then we'll try to figure out the other things we need.").also { stage = END_DIALOGUE } + + //have you been blessed yet + 60 -> playerl(FacialExpression.NEUTRAL, "No, not yet.").also { stage++ } + 61 -> npcl(FacialExpression.NEUTRAL, "Well, hurry up!").also { stage++ } + 62 -> if(inInventory(player, Items.DRUIDIC_SPELL_2968) || inBank(player, Items.DRUIDIC_SPELL_2968)) end() + else playerl(FacialExpression.NEUTRAL, "Could I have another bloom scroll please?").also { stage++ } + 63 -> npcl(FacialExpression.NEUTRAL, "Sure, but please look after this one.").also { stage++ } + 64 -> sendDialogue("The spirit of Filliman Tarlock gives you another bloom spell.").also { addItemOrDrop(player, Items.DRUIDIC_SPELL_2968); stage = END_DIALOGUE } + + //I've been blessed + 70 -> npcl(FacialExpression.NEUTRAL, "Well, you need to bring 'something from nature', 'something with faith' and 'something of the spirit-to- become freely given.'").also { stage++ } + 71 -> playerl(FacialExpression.NEUTRAL, "Yeah, but what does that mean?").also { stage++ } + 72 -> npcl(FacialExpression.NEUTRAL, "Hmm, it is a conundrum, however, if you use that spell I gave you, you should be able to get from nature. Once you have that, we may be puzzle the rest out.").also { stage++ } + 73 -> if(!inInventory(player, Items.DRUIDIC_SPELL_2968) && !inBank(player, Items.DRUIDIC_SPELL_2968)){ + playerl(FacialExpression.NEUTRAL, "Could I have another bloom scroll please?").also { stage++ } + } else end() + 74 -> npcl(FacialExpression.NEUTRAL, "Sure, but please look after this one.").also { stage++ } + 75 -> sendDialogue("The spirit of Filliman Tarlock gives you","another bloom spell.").also { addItem(player, Items.DRUIDIC_SPELL_2968); stage = END_DIALOGUE } + + //has fungus + 80 -> sendDialogue("You show the fungus to Filliman.").also { stage++ } + 81 -> playerl(FacialExpression.NEUTRAL, "Yes, I have a fungus here that I picked.").also { stage++ } + 82 -> npcl(FacialExpression.NEUTRAL, "Wonderful, the mushroom represents 'something from nature'. Now we need to work out what the other components of the spell are!").also { stage = 90; setQuest(50) } + + //pre-spell options + 90 -> options("What are the things that are needed?", "What should I do when I have those things?", "I think I've solved the puzzle!", "Could I have another bloom scroll please?", "Ok, thanks.").also { stage++ } + 91 -> when(buttonId){ + 1 -> playerl(FacialExpression.NEUTRAL, "What are the things that are needed?").also { stage = 100 } + 2 -> playerl(FacialExpression.NEUTRAL, "What should I do when I have those things?").also { stage = 110 } + 3 -> playerl(FacialExpression.FRIENDLY, "I think I've solved the puzzle!").also { stage = 120 } + 4 -> playerl(FacialExpression.FRIENDLY, "Can I have another bloom scroll please?").also { stage = 130 } + 5 -> playerl(FacialExpression.NEUTRAL, "Ok, thanks.").also { stage = END_DIALOGUE } + } + + //What things are needed? + 100 -> npcl(FacialExpression.NEUTRAL, "The three things are: 'Something with faith', 'something from nature' and 'something of the spirit-to-become freely given'.").also { stage++ } + 101 -> playerl(FacialExpression.FRIENDLY, " Ok, and 'something from nature' is the mushroom from the bloom spell you gave me?").also { stage++ } + 102 -> npcl(FacialExpression.FRIENDLY, "Yes, that's correct, that seems right to me. The other things we need are 'something with faith' and 'something of the spirit-to-become freely given.").also { stage++ } + 103 -> playerl(FacialExpression.NEUTRAL, "Do you have any ideas what those things are?").also { stage++ } + 104 -> npcl(FacialExpression.HALF_GUILTY, "I'm sorry my friend, but I do not.").also { stage = 90 } + + //What should I do when I have them? + 110 -> npcl(FacialExpression.NEUTRAL, "It says,.. 'to arrange upon three rocks around the spirit-to-become...'. Then I must cast a spell. As you can see, I've already placed the rocks.").also { stage++ } + 111 -> playerl(FacialExpression.NEUTRAL, "Can we just place the components on any rock?").also { stage++ } + 112 -> npcl(FacialExpression.NEUTRAL, "Well, the only thing the journal says is that 'something with faith stands south of the spirit-to-become', but I'm so confused now I don't really know what that means.").also { stage = 90 } + + //I think I've solved the puzzle! + 120 -> npcl(FacialExpression.NEUTRAL, "Oh really.. Have you placed all the items on the stones? Ok, well, let's try!").also { stage++ } + 121 -> sendDialogue("~ The druid attempts to cast a spell. ~").also { stage++ } + 122 -> { + animate(npc, 812) + if(NSUtils.hasPlacedCard(player) && NSUtils.hasPlacedFungus(player) && NSUtils.onStone(player)){ + end() + player.lock() + val locations = arrayOf(Location.create(3439, 3336, 0), Location.create(3441, 3336, 0), Location.create(3440, 3335, 0)) + repeat(3) {i -> spawnProjectile(locations[i], Location.create(3440, 3336, 0), 268, 0, 35, 0, 100, 20) } + submitIndividualPulse(player, object : Pulse(4){ + override fun pulse(): Boolean { + sendNPCDialogue(player, npc.originalId, "Aha, everything seems to be in place! You can come through now into the grotto for the final section of my transformation.") + setQuest(55) + unlock(player) + return true + } + + override fun stop() { + visualize(npc, -1, Graphics(266, 80)) + super.stop() + } + }) + } else { + npcl(FacialExpression.NEUTRAL, "Hmm, something still doesn't seem right. I think we need something more before we can continue.") + } + + stage = END_DIALOGUE + } + + 130 -> if(inInventory(player, Items.DRUIDIC_SPELL_2968) || inBank(player, Items.DRUIDIC_SPELL_2968)){ + npcl(FacialExpression.NEUTRAL, "No, you've already got one!").also { stage = END_DIALOGUE } + } else { + npcl(FacialExpression.NEUTRAL, "Sure, but look after this one.") + addItem(player, Items.DRUIDIC_SPELL_2968) + stage = END_DIALOGUE + } + + //Initial dialogue + 1000 -> playerl(FacialExpression.HALF_ASKING, "Hello?").also { stage++ } + 1001 -> if(inEquipment(player, Items.GHOSTSPEAK_AMULET_552)){ + npcl(FacialExpression.EXTREMELY_SHOCKED, "Oh, I understand you! At last, someone who doesn't just mumble. I understand what you're saying!").also { stage++ } + } else npcl(FacialExpression.HALF_GUILTY, "OooOOoOOoOOOOo.") + + 1002 -> options("I'm wearing an amulet of ghost speak!","How long have you been a ghost?", "What's it like being a ghost?", "Ok, thanks.").also { stage++ } + 1003 -> when(buttonId){ + 1 -> playerl(FacialExpression.NEUTRAL, "I'm wearing an amulet of ghost speak!").also { stage = 1010; setQuest(20) } + 2 -> playerl(FacialExpression.NEUTRAL, "How long have you been a ghost?").also { stage = 1020; setQuest(20) } + 3 -> playerl(FacialExpression.NEUTRAL, "What's it like being a ghost?").also { stage = 1030; setQuest(20) } + 4 -> playerl(FacialExpression.NEUTRAL, "Ok, thanks.").also { stage = END_DIALOGUE } + } + + 1010 -> npcl(FacialExpression.HALF_GUILTY, "Why you poor fellow, have you passed away and you want to send a message back to a loved one?").also { stage++ } + 1011 -> playerl(FacialExpression.HALF_THINKING, "Err.. Not exactly...").also { stage++ } + 1012 -> npcl(FacialExpression.HALF_GUILTY, "You have come to haunt my dreams until I pass on your message to a dearly loved one. I understand. Pray, tell me who would you like me to pass a message on to?").also { stage++ } + 1013 -> playerl(FacialExpression.NEUTRAL, "Ermm, you don't understand... It's just that...").also { stage++ } + 1014 -> npcl(FacialExpression.HALF_GUILTY, "Yes!").also { stage++ } + 1015 -> playerl(FacialExpression.NEUTRAL, "Well please don't be upset or anything... But you're the ghost!").also { stage++ } + 1016 -> npcl(FacialExpression.HALF_GUILTY, "Don't be silly now! That in no way reflects the truth!").also { stage = 1002 } + + 1020 -> npcl(FacialExpression.HALF_GUILTY, "What?! Don't be preposterous! I'm not a ghost! How could you say something like that?").also { stage++ } + 1021 -> playerl(FacialExpression.NEUTRAL, "But it's true, you're a ghost... well, at least that is to say, you're sort of not alive anymore.").also { stage++ } + 1022 -> npcl(FacialExpression.HALF_GUILTY, "Don't be silly, I can see you. I can see that tree. If I were dead, I wouldn't be able to see anything. What you say just doesn't reflect the truth. You'll have to try harder to put one over on me!").also { stage = 1002 } + + 1030 -> npcl(FacialExpression.HALF_GUILTY, "Oh, it's quite.... Oh... Trying to catch me out were you! Anyone can clearly see that I am not a ghost!").also { stage++ } + 1031 -> playerl(FacialExpression.NEUTRAL, "But you are a ghost, look at yourself! I can see straight through you! You're as dead as this swamp! Err... No offence or anything...").also { stage++ } + 1032 -> npcl(FacialExpression.HALF_GUILTY, "No I won't take offence because I'm not dead and I'm afraid you'll have to come up with some pretty conclusive proof before I believe it. What a strange dream this is.").also { stage = 1002 } + + + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.FILLIMAN_TARLOCK_1050) + } + + fun setQuest(stage: Int){ + player.questRepository.getQuest(Quests.NATURE_SPIRIT).setStage(player, stage) + } + +} \ No newline at end of file diff --git a/Server/src/main/content/region/morytania/quest/naturespirit/NSUtils.kt b/Server/src/main/content/region/morytania/quest/naturespirit/NSUtils.kt new file mode 100644 index 0000000..03263c6 --- /dev/null +++ b/Server/src/main/content/region/morytania/quest/naturespirit/NSUtils.kt @@ -0,0 +1,134 @@ +package content.region.morytania.quest.naturespirit + +import core.api.Container +import core.api.* +import core.game.node.scenery.SceneryBuilder +import core.game.node.entity.player.Player +import core.game.system.task.Pulse +import core.game.world.map.RegionManager +import core.game.world.map.RegionManager.forId +import core.game.world.update.flag.context.Graphics +import core.tools.RandomFunction +import org.rs09.consts.Items +import content.region.morytania.handlers.MortMyreGhastNPC +import org.rs09.consts.Sounds + +object NSUtils { + fun flagFungusPlaced(player: Player) { + setAttribute(player, "/save:ns:fungus_placed", true) + } + + fun flagCardPlaced(player: Player){ + setAttribute(player, "/save:ns:card_placed", true) + } + + fun hasPlacedFungus(player: Player): Boolean { + return getAttribute(player, "ns:fungus_placed", false) + } + + fun hasPlacedCard(player: Player): Boolean { + return getAttribute(player, "ns:card_placed", false) + } + + fun onStone(player: Player): Boolean { + return player.location.equals(3440, 3335, 0) + } + + fun getGhastKC(player: Player): Int { + return getAttribute(player,"ns:ghasts_killed", 0) as Int + } + + fun incrementGhastKC(player: Player){ + setAttribute(player, "/save:ns:ghasts_killed", getGhastKC(player) + 1) + val msg = when(getGhastKC(player)) { + 1 -> "That's one down, two more to go." + 2 -> "Two down, only one more to go." + 3 -> "That's it! I've killed all 3 Ghasts!" + else -> "" + } + + if(!msg.isEmpty()){ + sendMessage(player, msg) + } + } + + fun activatePouch(player: Player, attacker: MortMyreGhastNPC): Boolean { + var shouldAddEmptyPouch = false + val pouchAmt = amountInInventory(player, Items.DRUID_POUCH_2958) + if(pouchAmt == 1) shouldAddEmptyPouch = true + if(pouchAmt > 0 && removeItem(player, Items.DRUID_POUCH_2958, Container.INVENTORY)){ + if(shouldAddEmptyPouch){ + addItem(player, Items.DRUID_POUCH_2957) + } + spawnProjectile(player, attacker, 268) + submitWorldPulse(object : Pulse(){ + var ticks = 0 + override fun pulse(): Boolean { + when(ticks++){ + 2 -> visualize(attacker, -1, Graphics(269, 125)) + 3 -> attacker.transform(attacker.id + 1).also { attacker.attack(player); attacker.setAttribute("woke", getWorldTicks()); return true } + } + return false + } + }) + return true + } + return false + } + + fun cleanupAttributes(player: Player){ + player.removeAttribute("ns:fungus_placed") + player.removeAttribute("ns:card_placed") + } + + @JvmStatic + fun castBloom(player: Player): Boolean{ + var success = false + val region = forId(player.location.regionId) + if (player.skills.prayerPoints < 1) { + player.packetDispatch.sendMessage("You don't have enough prayer points to do this.") + return false + } + handleVisuals(player) + val locs = player.location.surroundingTiles + for (o in locs) { + val obj = RegionManager.getObject(o) + if (obj != null) { + if (obj.name.equals("Rotting log", ignoreCase = true) && player.skills.prayerPoints >= 1) { + if (player.location.withinDistance(obj.location, 2)) { + SceneryBuilder.replace(obj, obj.transform(3509)) + success = true + } + } + if (obj.name.equals("Rotting branch", ignoreCase = true) && player.skills.prayerPoints >= 1) { + if (player.location.withinDistance(obj.location, 2)) { + SceneryBuilder.replace(obj, obj.transform(3511)) + success = true + } + } + if (obj.name.equals("A small bush", ignoreCase = true) && player.skills.prayerPoints >= 1) { + if (player.location.withinDistance(obj.location, 2)) { + SceneryBuilder.replace(obj, obj.transform(3513)) + success = true + } + } + } + } + return success + } + + /** + * Handles the draining of prayer points and physical graphics and + * animation. + */ + private fun handleVisuals(player: Player) { + player.skills.decrementPrayerPoints(RandomFunction.random(1, 3).toDouble()) + playAudio(player, Sounds.CAST_BLOOM_1493) + val AROUND_YOU = player.location.surroundingTiles + for (location in AROUND_YOU) { + // The graphic is meant to play on a 3x3 radius around you, but not + // including the tile you are on. + player.packetDispatch.sendGlobalPositionGraphic(263, location) + } + } +} diff --git a/Server/src/main/content/region/morytania/quest/naturespirit/NatureSpiritDialogue.kt b/Server/src/main/content/region/morytania/quest/naturespirit/NatureSpiritDialogue.kt new file mode 100644 index 0000000..bdf92ad --- /dev/null +++ b/Server/src/main/content/region/morytania/quest/naturespirit/NatureSpiritDialogue.kt @@ -0,0 +1,164 @@ +package content.region.morytania.quest.naturespirit + +import core.api.Container +import core.api.* +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import core.tools.END_DIALOGUE +import content.data.Quests + +@Initializable +class NatureSpiritDialogue(player: Player? = null) : DialoguePlugin(player){ + + val questStage = player?.questRepository?.getStage(Quests.NATURE_SPIRIT) ?: 0 + override fun newInstance(player: Player?): DialoguePlugin { + return NatureSpiritDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + + when(questStage){ + 60 -> npcl(FacialExpression.NEUTRAL, "Hmm, good, the transformation is complete. Now, my friend, in return for your assistance, I will help you to kill the Ghasts. First bring to me a silver sickle so that I can bless it for you.").also { return true } + 65 -> npcl(FacialExpression.NEUTRAL, "Have you brought me a silver sickle?").also { stage = 100; return true } + 70 -> npcl(FacialExpression.NEUTRAL, "Now you can go forth and make the swamp bloom. Collect nature's bounty to fill a druids pouch. So armed will the Ghasts be bound to you until, you flee or they are defeated.").also { stage = 200 } + 75 -> npcl(FacialExpression.NEUTRAL, "Hello again, my friend. Have you defeated three ghasts as I asked you?").also { stage = 300 } + else -> npcl(FacialExpression.FRIENDLY, "Welcome to my grotto, friend. Enjoy your visit.").also { stage = END_DIALOGUE } + } + return true + } + + override fun handle(componentID: Int, buttonID: Int): Boolean { + when(stage){ + 0 -> playerl(FacialExpression.NEUTRAL,"A silver sickle? What's that?").also { stage++ } + 1 -> npcl(FacialExpression.NEUTRAL, "The sickle is the symbol and weapon of the Druid, you need to construct one of silver so that I can bless it, with its powers you will be able to defeat the Ghasts of Mort Myre.").also { stage++; setQuest(65) } + 2 -> options("Where would I get a silver sickle?", "What will you do to the silver sickle?", "How can a blessed sickle help me to defeat the Ghasts?", "Ok, thanks.").also { stage++ } + 3 -> when(buttonID){ + 1 -> playerl(FacialExpression.NEUTRAL, "Where would I get a silver sickle?").also { stage = 10 } + 2 -> playerl(FacialExpression.NEUTRAL, "What will you do to the silver sickle?").also { stage = 20 } + 3 -> playerl(FacialExpression.NEUTRAL, "How can a blessed sickle help me to defeat the Ghasts?").also { stage = 30 } + 4 -> playerl(FacialExpression.NEUTRAL, "Ok, thanks.").also { stage = END_DIALOGUE } + } + + //where sickle + 10 -> npcl(FacialExpression.NEUTRAL, "You could make one yourself if you're artisan enough. I've heard of a distant sandy place where you can buy the mould that you require, it's similar in many respects to the creating of a holy symbol.").also { stage = 2 } + + //What you gonna do to my sickle bro + 20 -> npcl(FacialExpression.NEUTRAL, "Why, I will give it my blessings so that the very swamp in which you stand will blossom and bloom!").also { stage = 2 } //pompous git + + //bruh how does a silver sickle help me tho + 30 -> npcl(FacialExpression.NEUTRAL, "My blessings will entice nature to bloom in Mort Myre! And then with nature's harvest you can fill a druids pouch and release the Ghasts from their torment.").also { stage = 2 } //this dude kinda weird + + //have you brought me a sickle yet bro + 100 -> if(inInventory(player, Items.SILVER_SICKLE_2961)){ + playerl(FacialExpression.FRIENDLY, "Yes, here it is. What are you going to do with it?").also { stage = 110 } + } else { + playerl(FacialExpression.NEUTRAL, "No sorry, not yet!").also { stage++ } + } + 101 -> npcl(FacialExpression.NEUTRAL, "Well, come to me when you have it.").also { stage = 2 } + + /** + * This dialogue drags on so much man this quest has been like 95% dialogue. + * Nature Spirit dude also talks like an uppity self-righteous deity looking dude + */ + + //yeah bro I got it + 110 -> npcl(FacialExpression.NEUTRAL, "My friend, I will bless it for you and you will then be able to accomplish great things. Now then, I must cast the enchantment. You can bless a new sickle by dipping it in the holy water of the grotto.").also { stage++ } + 111 -> sendDialogue("- The Nature Spirit casts a spell on the player. -").also { stage++ } + + /** + * Here we go uoooh + */ + 112 -> end().also { lock(player, 10); submitWorldPulse(SickleBlessPulse(player, npc)) } + + //go kill some ghasts bro + 200 -> npcl(FacialExpression.NEUTRAL, "Go forth into Mort Myre and slay three Ghasts. You'll be releasing their souls from Mort Myre.").also { stage++ } + 201 -> sendItemDialogue(player, Items.DRUID_POUCH_2957, "The nature spirit gives you an empty pouch.").also { stage++; setQuest(75) } + 202 -> npcl(FacialExpression.NEUTRAL, "You'll need this in order to collect together nature's bounty. It will bind the Ghast to you until you flee or it is defeated.").also { stage = END_DIALOGUE } + + //Have you killed the ghasts yet bro + 300 -> if(NSUtils.getGhastKC(player) >= 3){ + playerl(FacialExpression.NEUTRAL, "Yes, I've killed all three and their spirits have been released!").also { stage = 350 } + } else { + playerl(FacialExpression.NEUTRAL, "Not yet.").also { stage++ } + } + + //nah bro + 301 -> npcl(FacialExpression.NEUTRAL, "Well, when you do, please come to me and I'll reward you!").also { stage++ } + 302 -> options("How do I get to attack the Ghasts?", "What's this pouch for?", "What can I do with this sickle?", "I've lost my sickle.", "Ok, thanks.").also { stage++ } + 303 -> when(buttonID){ + 1 -> playerl(FacialExpression.NEUTRAL, "How do I get to attack the Ghasts?").also { stage = 310 } + 2 -> playerl(FacialExpression.NEUTRAL, "What's this pouch for?").also { stage = 320 } + 3 -> playerl(FacialExpression.NEUTRAL, "What can I do with this sickle?").also { stage = 330 } + 4 -> playerl(FacialExpression.NEUTRAL, "I've lost my sickle.").also { stage = 340 } + 5 -> playerl(FacialExpression.NEUTRAL, "Ok, thanks.").also { stage = END_DIALOGUE } + } + + //How do I attack duh ghosty bois + 310 -> npcl(FacialExpression.NEUTRAL, "Go forth and with the sickle make the swamp bloom. Collect natures bounty to fill a druids pouch. So armed will the Ghasts be bound to you until, you flee or they are defeated.").also { stage = 302 } + + //What's dis funny pouch for? + 320 -> npcl(FacialExpression.NEUTRAL, "It is for collecting natures bounty, once it contains the blossomed items of the swamp, it will make the Ghasts appear and you can then attack them.").also { stage = 302 } + + //What can I do wif da sickle m8 + 330 -> npcl(FacialExpression.NEUTRAL, "You may use it wisely within the area of Mort Myre to affect natures balance and bring forth a bounty of natures harvest. Once collected into the druid pouch will the Ghast be apparent.").also { stage = 302 } + + //oi I lost it bruv + 340 -> npcl(FacialExpression.NEUTRAL, "If you should lose the blessed sickle, simply bring another to my altar of nature and refresh it in the grotto waters.").also { stage = 302 } + + //killed all dem buggers bruv + 350 -> npcl(FacialExpression.NEUTRAL, "Many thanks my friend, you have completed your quest!").also { stage++ } + 351 -> end().also { player.questRepository.getQuest(Quests.NATURE_SPIRIT).finish(player) } + } + + return true + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.NATURE_SPIRIT_1051) + } + + /** + * Needs to spawn 4ish of those green projectiles and the player needs to lift up the sickle + * then needs to open the dialogue back up with the quest stage at 70 + */ + internal class SickleBlessPulse(val player: Player, val spirit: NPC) : Pulse() { + var ticks = 0 + val locs: MutableList = player.location.surroundingTiles + + override fun pulse(): Boolean { + when(ticks++){ + 0 -> animate(spirit, 812) + 1 -> repeat(4) { + val loc = locs.random() + locs.remove(loc) + + spawnProjectile(loc, player.location, 268, 0, 400, 0, 125, 180) + animate(player, 9021) + } + 4 -> { + if(removeItem(player, Items.SILVER_SICKLE_2961, Container.INVENTORY)){ + addItem(player, Items.SILVER_SICKLEB_2963) + unlock(player) + player.questRepository.getQuest(Quests.NATURE_SPIRIT).setStage(player, 70) + openDialogue(player, NPCs.NATURE_SPIRIT_1051, findLocalNPC(player, NPCs.NATURE_SPIRIT_1051) as NPC) + sendMessage(player, "Your sickle has been blessed! You can bless a new sickle by dipping it into the grotto waters.") + } + } + 6 -> return true + } + return false + } + } + + fun setQuest(stage: Int){ + player!!.questRepository.getQuest(Quests.NATURE_SPIRIT).setStage(player!!, stage) + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/morytania/quest/naturespirit/NatureSpiritQuest.kt b/Server/src/main/content/region/morytania/quest/naturespirit/NatureSpiritQuest.kt new file mode 100644 index 0000000..87d7107 --- /dev/null +++ b/Server/src/main/content/region/morytania/quest/naturespirit/NatureSpiritQuest.kt @@ -0,0 +1,210 @@ +package content.region.morytania.quest.naturespirit + +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.skill.Skills +import core.plugin.Initializable +import org.rs09.consts.Items +import content.data.Quests + +@Initializable +class NatureSpiritQuest : Quest(Quests.NATURE_SPIRIT, 95, 94, 2, 307, 0, 1, 110 ) { + override fun newInstance(`object`: Any?): Quest { + return this + } + + override fun drawJournal(player: Player?, stage: Int) { + super.drawJournal(player, stage) + player ?: return + var line = 12 + if(stage == 0){ + line(player, "I can start this quest by speaking to !!Drezel?? in the temple.", line++) + line(player, /* The "to" is [sic] */"to !!Saradomin?? at the mouth of the river !!Salve??.", line++) + line(player, "I first need to complete :", line++) + line(player, "!!The Restless Ghost.??", line++, isQuestComplete(player, Quests.THE_RESTLESS_GHOST)) + line(player, "!!Priest in Peril.??", line++, isQuestComplete(player, Quests.PRIEST_IN_PERIL)) + if (isQuestComplete(player, Quests.THE_RESTLESS_GHOST) && isQuestComplete(player, Quests.PRIEST_IN_PERIL)) { + line(player, "I've completed all the quest requirements.", line++) + } + line(player, "In order to complete this quest !!level 18 crafting?? would be", line++, getStatLevel(player, Skills.CRAFTING) >= 18) + line(player, "an advantage.", line++, getStatLevel(player, Skills.CRAFTING) >= 18) + if (getStatLevel(player, Skills.CRAFTING) >= 18) { + line(player, "I have a suitable crafting level for this quest.", line++) + } + if (isQuestComplete(player, Quests.THE_RESTLESS_GHOST) && isQuestComplete(player, Quests.PRIEST_IN_PERIL) && getStatLevel(player, Skills.CRAFTING) >= 18) { + line(player, "I have all the requirements for this quest.", line++) + } + } else if (stage < 100) { + line(player, "After talking to Drezel in the temple of Saradomin I've", line++, true) + line(player, "agreed to look for a Druid called Filliman Tarlock.", line++, true) + + if (stage >= 15) { + line(player, "I've found a spirit in the swamp which I think might be", line++, true) + line(player, "Filliman Tarlock.", line++, true) + } else if (stage >= 10) { + line(player, "I need to look for !!Filliman Tarlock?? in the !!Swamps?? of Mort", line++) + line(player, "Myre. I should be wary of !!Ghasts??.", line++) + } + + if (stage >= 20) { + line(player, "I've communicated with Fillman using the amulet of", line++, true) + line(player, "ghostspeak.", line++, true) + } else if (stage >= 15) { + // Questionable + line(player, "I located a !!spirit?? in the swamp. I believe he's", line++) + line(player, "!!Filliman Tarlock?? but I can't understand him.", line++) + } + + if (stage >= 25) { + line(player, "I managed to convince Fillman that he's a ghost.", line++, true) + } else if (stage >= 20) { + line(player, "I think I need to convince this poor fellow !!Tarlock?? that he's", line++) + line(player, "actually !!dead??!", line++) + } + + if (stage >= 30) { + line(player, "Fillman is looking for his journal to help him plan what his", line++, true) + line(player, "next step is.", line++, true) + line(player, "I've given Filliman his journal. I wonder what he plans to do", line++, true) + line(player, "now?", line++, true) + } else if (stage >= 25){ + line(player, "Fillman is looking for his !!journal?? to help him plan what his", line++, true) + line(player, "next step is.", line++, true) + // Questionable +// line(player, "Filliman needs his !!journal?? to figure out what to do",line++) +// line(player, "next. He mentioned something about a !!knot??.", line++) + } + + if (stage >= 35) { + line(player, "I've agreed to help Fillman become a nature spirit.", line++, true) + line(player, "I need to find 'something from nature', 'something of", line++, true) + line(player, "faith' and 'something of the spirit-to-become freely", line++, true) + line(player, "given'.", line++, true) + } else if (stage >= 30) { + // Derived by squinting hard + line(player, "!!Filliman?? might need !!my help?? with his !!plan??.", line++) + // Questionable +// line(player, "I should speak to !!Filliman Tarlock?? to see what I can", line++) +// line(player, "do to help.", line++) + } + + if (stage >= 40) { + line(player, "Filliman gave me a 'bloom' spell to cast in the swamp.", line++, true) + line(player, "With the bloom spell I can collect 'Something of nature.'", line++, true) + line(player, "I've been blessed at the temple by Drezel.", line++, true) + } else if (stage >= 35) { + line(player, "!!Filliman?? gave me a '!!bloom??' spell but I need to be !!blessed?? at", line++) + line(player, "the !!temple?? before I can cast it. I am supposed to collect", line++) + line(player, "'!!something from nature??'.", line++) + } + + if (stage >= 45) { + // Disappears. + } else if (stage >= 40) { + line(player, "I should return to !!Filliman?? to see what I need to do.", line++) + } + + if (stage in 45 until 55){ + if (NSUtils.hasPlacedFungus(player)) { + line(player, "I've cast the bloom spell in the swamp.", line++, true) + line(player, "I collected a Mort Myre Fungi.", line++, true) + line(player, "I think I have collected 'something of nature'.", line++, true) + } else if (inInventory(player, Items.MORT_MYRE_FUNGUS_2970)) { + line(player, "I've cast the bloom spell in the swamp.", line++, true) + line(player, "I collected a Mort Myre Fungi.", line++, true) + line(player, "I have a !!Mort Myre Fungi??, I hope this is what !!Fillman??",line++) + line(player, "wanted.",line++) + } else { + // Questionable +// if(stage == 50){ +// line(player, "I know for a fact the fungus is !!something of Nature??.", line++, false) +// } + line(player, "I need to collect '!!something of nature??'.", line++) + } + + // Just stand on the damn thing. + line(player, "I need to find '!!something with faith??'.",line++, false) + + if (NSUtils.hasPlacedCard(player)) { + line(player, "The spell scroll was absorbed into the spirit stone I think I", line++, true) + line(player, "have collected 'something of spirit-to-become freely", line++, true) + line(player, "given.'", line++, true) + } else { + line(player, "I need to find :",line++) + line(player, "'!!something of the spirit-to-be freely given??.'", line++) + } + } + + if (stage >= 55) { + line(player, "I managed to get all the required items that Fillman asked.", line++, true) + line(player, "for. He says that he can cast the spell now which will", line++, true) + line(player, "transform him into a Nature Spirit.", line++, true) + } + + if (stage >= 60) { + line(player, "I entered Fillimans grotto as he asked me to.", line++, true) // no apostrophe is sic + line(player, "Filliman has turned into a nature spirit, it was an", line++, true) + line(player, "impressive transformation!", line++, true) + line(player, "Filliman says he can help me to defeat the ghasts.", line++, true) + } else if (stage >= 55) { + // Questionable + line(player, "!!Filliman?? has asked me to enter his !!grotto??.", line++) + } + + if (stage >= 70) { + line(player, "Filliman has blessed the silver sickle for me.", line++, true) + // --- Should be separate stage, but we don't have it. + // line(player, "I need to use the !!sickle?? to make the swamp bloom.", line++) + line(player, "I cast the bloom spell in the swamp.", line++, true) + // --- Should be separate stage, but we don't have it. + // line(player, "I need to collect some !!bloomed items?? from the swamp", line++) + // line(player, "and put them into a druid pouch.", line++) + line(player, "I collected some bloomed items from the swamp an put", line++, true) + line(player, "them into a druid pouch.", line++, true) + } else if (stage >= 60) { + // Questionable + line(player, "I need to bring a silver sickle for !!Filliman?? to bless.", line++) + } + // We don't have this stage. +// if (stage >= 80) { +// line(player, "The druid pouch made a ghast appear which I attacked and", line++, true) +// line(player, "killed.", line++, true) +// line(player, "I've killed two ghasts now.", line++, true) +// line(player, "I've killed three ghasts now.", line++, true) +// line(player, "I should tell !!Filliman?? that I've killed the !!three ghasts??.", line++, true) +// } else + if (stage >= 75){ + line(player, "!!Filliman?? asked me to kill !!three Ghasts??.", line++, false) + } + } else { + // The final text is a summary of the quest. + line(player, "Drezel, a priest of Saradomin, asked me to look for the", line++, true) + line(player, "druid Filliman Tarlock in the swamps of Mort Myre. However", line++, true) + line(player, "Filliman had been slain and appeared as a ghost. After", line++, true) + line(player, "persuading Filliman that he was in fact dead I helped him to", line++, true) + line(player, "make a transformation into a Nature Spirit.", line++, true) + line++ + line(player, "In return for this help Filliman blessed a silver sickle and", line++, true) + line(player, "showed me how to defeat the ghasts of Mort Myre.", line++, true) + line(player, "He also gave me some kill experience in crafting,", line++, true) + line(player, "hitpoints and defence.", line++, true) + line(player, "%%QUEST COMPLETE!&&",line++) + } + } + + override fun finish(player: Player?) { + super.finish(player) + player ?: return + var ln = 10 + player.packetDispatch.sendItemZoomOnInterface(Items.SILVER_SICKLEB_2963,230,277,5) + drawReward(player, "2 Quest Points", ln++) + drawReward(player, "3,000 Crafting XP",ln++) + drawReward(player, "2,000 Hitpoints XP", ln++) + drawReward(player, "2,000 Defence XP", ln++) + rewardXP(player, Skills.CRAFTING, 3000.0) + rewardXP(player, Skills.HITPOINTS, 2000.0) + rewardXP(player, Skills.DEFENCE, 2000.0) + NSUtils.cleanupAttributes(player) + } +} diff --git a/Server/src/main/content/region/tirranwn/dialogue/ArvelDialogue.kt b/Server/src/main/content/region/tirranwn/dialogue/ArvelDialogue.kt new file mode 100644 index 0000000..221c75a --- /dev/null +++ b/Server/src/main/content/region/tirranwn/dialogue/ArvelDialogue.kt @@ -0,0 +1,47 @@ +package content.region.tirranwn.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + * Not including quest-related dialogue + */ + +@Initializable +class ArvelDialogue(player: Player? = null) : DialoguePlugin(player){ + + fun gender (male : String = "hero", female : String = "heroine") = if (player.isMale) male else female + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npcl(FacialExpression.FRIENDLY,"Good day traveller. You are far from home, what brings you here?").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> playerl(FacialExpression.FRIENDLY, "I am a wandering " + gender() + ". I come here in search of adventure.").also { stage++ } + 1 -> npc(FacialExpression.FRIENDLY, "Sounds ghastly, I just want to live in peace.").also { stage++ } + 2 -> playerl(FacialExpression.FRIENDLY, "Unfortunately without people like me, peace doesn't last for long.").also { stage++ } + 3 -> npcl(FacialExpression.FRIENDLY, "True, but then again most adventurers cause as much trouble as they put right.").also { stage++ } + 4 -> player(FacialExpression.FRIENDLY, "You've got a point there... Hmm...").also { stage++ } + 5 -> npc(FacialExpression.FRIENDLY, "Well, good day traveller. And always do the right thing.").also { stage = 99 } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return ArvelDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.ARVEL_2365) + } +} diff --git a/Server/src/main/content/region/tirranwn/dialogue/DalldavDialogue.kt b/Server/src/main/content/region/tirranwn/dialogue/DalldavDialogue.kt new file mode 100644 index 0000000..1b89b65 --- /dev/null +++ b/Server/src/main/content/region/tirranwn/dialogue/DalldavDialogue.kt @@ -0,0 +1,48 @@ +package content.region.tirranwn.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class DalldavDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npc(FacialExpression.FRIENDLY,"Can I help you at all?").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> options("Yes please. What are you selling?", "Why do you sell this stuff?", "No thanks.").also { stage++ } + 1 -> when (buttonId) { + 1 -> player(FacialExpression.FRIENDLY, "Yes please. What are you selling?").also { stage = 10 } + 2 -> playerl(FacialExpression.FRIENDLY, "Why do you sell this stuff? The Crystal Bow is so much better.").also { stage = 20 } + 3 -> player(FacialExpression.FRIENDLY, "No thanks.").also { stage = 99 } + } + + 10 -> end().also { npc.openShop(player) } + + 20 -> npcl(FacialExpression.FRIENDLY, "We keep all these old toys to train our children with, but if people will part with coins for them, then they are theirs!").also { stage = 99 } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return DalldavDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.DALLDAV_2356) + } +} diff --git a/Server/src/main/content/region/tirranwn/dialogue/ElfTrackerDialogue.kt b/Server/src/main/content/region/tirranwn/dialogue/ElfTrackerDialogue.kt new file mode 100644 index 0000000..d11634c --- /dev/null +++ b/Server/src/main/content/region/tirranwn/dialogue/ElfTrackerDialogue.kt @@ -0,0 +1,89 @@ +package content.region.tirranwn.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class ElfTrackerDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + + //todo check if found tracks or not + //temporary booly boi + var tracksFound = false + if (!tracksFound) { + player(FacialExpression.FRIENDLY, "Hello.").also { stage = 0 } + } else { + playerl(FacialExpression.NEUTRAL, "I've found tracks leading off to the west. But they trail off into the trees. Beyond that I am unable to follow.").also { stage = 30} + } + + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> npc(FacialExpression.SUSPICIOUS, "Human! You must be one of Tyras's men...").also { stage++ } + 1 -> playerl(FacialExpression.HALF_GUILTY, "No, I'm " + player.username + "! Lord Iorwerth said you might be able to help me.").also { stage++ } + 2 -> npc(FacialExpression.SUSPICIOUS, "And you have something to prove this?").also { stage++ } + 3 -> { + //todo check quest stages whenever it's added + if (player.inventory.contains(Items.CRYSTAL_PENDANT_3208, 1) || player.equipment.contains(Items.CRYSTAL_PENDANT_3208, 1)) { + sendDialogue("You show the tracker the crystal pendant.").also { stage = 20 } + } else { + player(FacialExpression.HALF_GUILTY, "Well... Err... No.").also { stage = 10 } + } + } + 10 -> npcl(FacialExpression.ANNOYED, "As I was saying... I have no time for brigands or outlaws.").also { stage = 99 } + + 20 -> npcl(FacialExpression.FRIENDLY, "That is Lord Iorwerth's pendant. He must have a lot of faith in you. Now, what is it I can help you with?").also { stage ++ } + 21 -> playerl(FacialExpression.ASKING, "I need to find Tyras and kill him. Do you know where his camp is?").also { stage++ } + 22 -> npcl(FacialExpression.FRIENDLY, "Well this was his old camp. After the battle a few days ago they moved. We're yet to find them again.").also { stage++ } + 23 -> player(FacialExpression.ASKING, "Can I help at all?").also { stage++ } + 24 -> npcl(FacialExpression.FRIENDLY, "As it goes I'm not actually tracking them at the moment. I'm currently trying to trace our renegade brethen instead. This here is the best lead we've found so far.").also { stage++ } + 25 -> player(FacialExpression.HALF_ASKING, "What is?").also { stage++ } + 26 -> npc(FacialExpression.THINKING, "Ahh I guess you can't see it with those human eyes.").also { stage++ } + 27 -> npcl(FacialExpression.THINKING, "I tell you what. Now that you're here I may as well give you a hand. I'll search here on the east side. You check out the west end of the camp.").also { stage++ } + 28 -> npc(FacialExpression.THINKING, "Come and tell me if you find anything.").also { stage = 99 } + + //todo after finding the tracks + 30 -> npcl(FacialExpression.THINKING, "These forests aren't always as dense as you'd think. If you look closer, you might see ways that you can get through. With that in mind, why don't you give it another go?").also { stage++ } + 31 -> player(FacialExpression.ANNOYED, "Thanks... I'll see what I can find.").also { stage = 99 } + + //todo after searching past the dense forest + 40 -> player(FacialExpression.FRIENDLY, "Hello.").also { stage++ } + 41 -> npc(FacialExpression.FRIENDLY, "How goes the hunt for that bandit camp?").also { stage++ } + 42 -> { + //todo (If the camp has not been found) + //temporary booly bois + var campFound = false + if (!campFound) { + player(FacialExpression.FRIENDLY, "Getting there.").also { stage = 99 } + } else { + player(FacialExpression.NEUTRAL, "I found it a short distance west of here.").also { stage++ } + } + } + 43 -> npcl(FacialExpression.FRIENDLY, "I'm sure Lord Iorwerth will be pleased to hear that. You should let him know.").also { stage = 99 } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return ElfTrackerDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.ELF_TRACKER_1199) + } +} diff --git a/Server/src/main/content/region/tirranwn/dialogue/EoinDialogue.kt b/Server/src/main/content/region/tirranwn/dialogue/EoinDialogue.kt new file mode 100644 index 0000000..a8bfbe9 --- /dev/null +++ b/Server/src/main/content/region/tirranwn/dialogue/EoinDialogue.kt @@ -0,0 +1,39 @@ +package content.region.tirranwn.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class EoinDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + player(FacialExpression.FRIENDLY,"Hello.").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> npcl(FacialExpression.FRIENDLY, "Sorry, I cannot stop or Iona will catch me, we are playing tag!").also { stage = 99 } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return EoinDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.EOIN_2368) + } +} diff --git a/Server/src/main/content/region/tirranwn/dialogue/EudavGethinDialogue.kt b/Server/src/main/content/region/tirranwn/dialogue/EudavGethinDialogue.kt new file mode 100644 index 0000000..1d2c93a --- /dev/null +++ b/Server/src/main/content/region/tirranwn/dialogue/EudavGethinDialogue.kt @@ -0,0 +1,44 @@ +package content.region.tirranwn.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class EudavGethinDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npc(FacialExpression.FRIENDLY,"Can I help you at all?").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> options("Yes please. What are you selling?", "No thanks.").also { stage++ } + + 1 -> when(buttonId) { + 1 -> end().also { npc.openShop(player) } + 2 -> player(FacialExpression.FRIENDLY, "No thanks.").also { stage = 99 } + } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return EudavGethinDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.EUDAV_2352, NPCs.GETHIN_2357) + } +} diff --git a/Server/src/main/content/region/tirranwn/dialogue/GoreuDialogue.kt b/Server/src/main/content/region/tirranwn/dialogue/GoreuDialogue.kt new file mode 100644 index 0000000..3152265 --- /dev/null +++ b/Server/src/main/content/region/tirranwn/dialogue/GoreuDialogue.kt @@ -0,0 +1,42 @@ +package content.region.tirranwn.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class GoreuDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + player(FacialExpression.FRIENDLY,"Hello.").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> npcl(FacialExpression.FRIENDLY, "Good day, can I help you?").also { stage++ } + 1 -> playerl(FacialExpression.FRIENDLY, "No thanks I'm just watching the world go by.").also { stage++ } + 2 -> npcl(FacialExpression.FRIENDLY, "Well I can think of no better place to do it, it is beautiful here is it not?").also { stage++ } + 3 -> playerl(FacialExpression.FRIENDLY, "Indeed it is.").also { stage = 99 } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return GoreuDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.GOREU_2363) + } +} diff --git a/Server/src/main/content/region/tirranwn/dialogue/IlfeenDialogue.kt b/Server/src/main/content/region/tirranwn/dialogue/IlfeenDialogue.kt new file mode 100644 index 0000000..7f5f121 --- /dev/null +++ b/Server/src/main/content/region/tirranwn/dialogue/IlfeenDialogue.kt @@ -0,0 +1,78 @@ +package content.region.tirranwn.dialogue + +import core.api.addItemOrDrop +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class IlfeenDialogue(player: Player? = null) : DialoguePlugin(player){ + + //temp var + var queststage = 0 + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + //todo choose dialogue tree based off of quest stage + when(queststage) { + 0 -> npcl(FacialExpression.FRIENDLY,"Good day, what are you doing all the way out here?").also { stage = 0 } + 1 -> playerl(FacialExpression.ASKING, "There is something I meant to ask you about. Do you remember Oaknock? He was a gnome inventor.").also { stage = 10 } + 2 -> player(FacialExpression.FRIENDLY, "Hello again. Are you still offering to chant seeds?").also { stage = 20 } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> playerl(FacialExpression.FRIENDLY, "I'm just wandering, it's a lovely day for a walk in the woods.").also { stage++ } + 1 -> npc(FacialExpression.FRIENDLY, "It is that.").also { stage++ } + 2 -> player(FacialExpression.FRIENDLY, "Well I shouldn't keep you, see you later.").also { stage++ } + 3 -> npc(FacialExpression.FRIENDLY, "Bye.").also { stage = 99 } + + 10 -> npcl(FacialExpression.HAPPY, "Of course! I remember him from when I was living in the eastern lands. He was just a budding engineer then. I rather liked the young gnome: he was rather loud, but he had a good soul.").also { stage++ } + 11 -> npcl(FacialExpression.HAPPY, "He was very interested in elven magic. Last time we spoke, not too long ago, he was very interested in illusion magic and how to dispel it. I gave him some advice and a few pieces of equipment to help him.").also { stage++ } + 12 -> playerl(FacialExpression.THINKING, "I think Oaknock died of old age a few hundred years ago now.").also { stage++ } + 13 -> npcl(FacialExpression.HALF_GUILTY, "I keep forgetting, a hundred years is a long time for you.").also { stage++ } + 14 -> player(FacialExpression.ASKING, "Did you ever give him a seed?").also { stage++ } + 15 -> npcl(FacialExpression.FRIENDLY, "Of course. It grew into a saw. I hope he found it useful.").also { stage++ } + 16 -> player(FacialExpression.FRIENDLY, "I think he did! Thanks.").also { stage++ } + 17 -> sendDialogue("Ilfeen smiles serenely.").also { stage = 99 } + + 20 -> npcl(FacialExpression.ASKING, "I am, but you’ll need your own seed. I can also chant your shield or bow back to full charges if you have it with you. Would you like me to enchant anything?").also { stage++ } + 21 -> npcl(FacialExpression.ASKING, "Or I could give you a book about crystal singing?").also { stage++ } + 22 -> options ("Enchant something.", "Crystal singing book.", "Nothing, thanks.").also { stage++ } + 23 -> when (buttonId) { + //1 -> todo opens interface for enchanting + 2 -> player(FacialExpression.ASKING, "Could I have the book, please?").also { stage = 40 } + 3 -> npc(FacialExpression.FRIENDLY, "Well, good luck.").also { stage = 43 } + } + + 40 -> { + addItemOrDrop(player, Items.CRYSTAL_OF_SEREN_4313, 1) + sendDialogue("Ilfeen hands you a book.").also { stage++ } + } + 41 -> player(FacialExpression.FRIENDLY, "Thanks, I'll read all about it.").also { stage++ } + 42 -> npc(FacialExpression.FRIENDLY, "Well, good luck.").also { stage++ } + 43 -> player(FacialExpression.FRIENDLY, "Goodbye, Ilfeen.").also { stage = 99 } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return IlfeenDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.ILFEEN_1777) + } +} diff --git a/Server/src/main/content/region/tirranwn/dialogue/IonaDialouge.kt b/Server/src/main/content/region/tirranwn/dialogue/IonaDialouge.kt new file mode 100644 index 0000000..9ab6bdc --- /dev/null +++ b/Server/src/main/content/region/tirranwn/dialogue/IonaDialouge.kt @@ -0,0 +1,39 @@ +package content.region.tirranwn.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class IonaDialouge(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + player(FacialExpression.FRIENDLY,"Hello.").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> npcl(FacialExpression.FRIENDLY, "I can never catch Eoin, he is just too fast, I am always 'It'.").also { stage = 99 } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return IonaDialouge(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.IONA_2369) + } +} diff --git a/Server/src/main/content/region/tirranwn/dialogue/KelynDialogue.kt b/Server/src/main/content/region/tirranwn/dialogue/KelynDialogue.kt new file mode 100644 index 0000000..5b19b0b --- /dev/null +++ b/Server/src/main/content/region/tirranwn/dialogue/KelynDialogue.kt @@ -0,0 +1,43 @@ +package content.region.tirranwn.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class KelynDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + player(FacialExpression.FRIENDLY,"Hello.").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> npcl(FacialExpression.FRIENDLY, "Huh... Oh sorry, you made me jump. I was miles away, day dreaming.").also { stage++ } + 1 -> player(FacialExpression.FRIENDLY, "About what may I ask?").also { stage++ } + 2 -> npcl(FacialExpression.FRIENDLY, "I was thinking about the crystal spires of Prifddinas.").also { stage++ } + 3 -> player(FacialExpression.FRIENDLY, "It must be beautiful, I've only seen the city walls.").also { stage++ } + 4 -> npcl(FacialExpression.FRIENDLY, "I have never seen it, all I know are the stories. I hope that changes one day.").also { stage = 99 } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return KelynDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.KELYN_2367) + } +} diff --git a/Server/src/main/content/region/tirranwn/dialogue/MawrthDialogue.kt b/Server/src/main/content/region/tirranwn/dialogue/MawrthDialogue.kt new file mode 100644 index 0000000..db5e0f9 --- /dev/null +++ b/Server/src/main/content/region/tirranwn/dialogue/MawrthDialogue.kt @@ -0,0 +1,44 @@ +package content.region.tirranwn.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class MawrthDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npcl(FacialExpression.FRIENDLY,"Those children are nothing but trouble - if I did not watch them all the time, Seren knows what trouble they would get in to!").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> player(FacialExpression.FRIENDLY, "They look old enough to look after themselves.").also { stage++ } + 1 -> npcl(FacialExpression.FRIENDLY, "They are only 34 and 38, far too young to be left unsupervised.").also { stage++ } + 2 -> player(FacialExpression.FRIENDLY, "Only!?! How old does that make you?").also { stage++ } + 3 -> npcl(FacialExpression.FRIENDLY, "Has no one told you it is rude to ask a lady her age?").also { stage++ } + 4 -> playerl(FacialExpression.FRIENDLY, "Sorry, I wasn't thinking. Anyway... I'd better stop distracting you.").also { stage++ } + 5 -> npc(FacialExpression.FRIENDLY, "Okay, See you some other time.").also { stage = 99 } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return MawrthDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.MAWRTH_2366) + } +} diff --git a/Server/src/main/content/region/tirranwn/dialogue/OronwenDialogue.kt b/Server/src/main/content/region/tirranwn/dialogue/OronwenDialogue.kt new file mode 100644 index 0000000..1172948 --- /dev/null +++ b/Server/src/main/content/region/tirranwn/dialogue/OronwenDialogue.kt @@ -0,0 +1,46 @@ +package content.region.tirranwn.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class OronwenDialogue(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npc(FacialExpression.FRIENDLY,"Hello, can I help?").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> options("Yes please. What are you selling?", "No thanks.").also { stage++ } + + 1 -> when(buttonId) { + 1 -> player(FacialExpression.FRIENDLY, "Yes please. What are you selling?").also { stage = 10 } + 2 -> player(FacialExpression.FRIENDLY, "No thanks.").also { stage = 99 } + } + + 10 -> end().also { npc.openShop(player) } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return OronwenDialogue(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.ORONWEN_2353) + } +} diff --git a/Server/src/main/content/region/tirranwn/dialogue/QuarterMasterDialogue.java b/Server/src/main/content/region/tirranwn/dialogue/QuarterMasterDialogue.java new file mode 100644 index 0000000..b8d7628 --- /dev/null +++ b/Server/src/main/content/region/tirranwn/dialogue/QuarterMasterDialogue.java @@ -0,0 +1,73 @@ +package content.region.tirranwn.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +import static core.api.ContentAPIKt.hasRequirement; +import content.data.Quests; + +/** + * Handles the quarter master dialogue. + * @author Vexia + */ +@Initializable +public final class QuarterMasterDialogue extends DialoguePlugin { + + /** + * Constructs a new {@Code QuarterMasterDialogue} {@Code + * Object} + * @param player the player. + */ + public QuarterMasterDialogue(Player player) { + super(player); + } + + /** + * Constructs a new {@Code QuarterMasterDialogue} {@Code + * Object} + */ + public QuarterMasterDialogue() { + /** + * empty. + */ + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new QuarterMasterDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + npc("Hi, would you like to see my wares?"); + if (!hasRequirement(player, Quests.REGICIDE)) { + end(); + return true; + } + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + player("Yes, please."); + stage++; + break; + case 1: + end(); + npc.openShop(player); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 1208 }; + } + +} diff --git a/Server/src/main/content/region/tirranwn/dialogue/TyrasGuard.kt b/Server/src/main/content/region/tirranwn/dialogue/TyrasGuard.kt new file mode 100644 index 0000000..076a7eb --- /dev/null +++ b/Server/src/main/content/region/tirranwn/dialogue/TyrasGuard.kt @@ -0,0 +1,57 @@ +package content.region.tirranwn.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class TyrasGuard(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + npc(FacialExpression.FRIENDLY,"What is it?").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> options("What's going on around here?", "Do you know what's south of here?", "I'll leave you alone.").also { stage++ } + 1 -> when (buttonId) { + 1 -> player(FacialExpression.ASKING, "What's going on around here?").also { stage = 10 } + 2 -> player(FacialExpression.ASKING, "Do you know what's south of here?").also { stage = 20 } + 3 -> player(FacialExpression.NEUTRAL, "I'll leave you alone.").also { stage = 99 } + } + + 10 -> npcl(FacialExpression.NEUTRAL, "Sorry, I shouldn't give out sensitive information to civilians. You should go to General Hining, in the camp along the road.").also { stage++ } + 11 -> options("Do you know what's south of here?", "Okay, thanks.").also { stage++ } + 12 -> when (buttonId) { + 1 -> player(FacialExpression.ASKING, "Do you know what's south of here?").also { stage = 20 } + 2 -> player(FacialExpression.NEUTRAL, "Ok, thanks.").also { stage = 99 } + } + + 20 -> npcl(FacialExpression.NEUTRAL, "No. We sent a scouting party in that direction, when we first established our camp. Some of the men got lost in the swamps. Eventually we listed them as dead.").also { stage++ } + 21 -> npcl(FacialExpression.NEUTRAL, "Then suddenly they returned, with a wild gleam in their eyes, raving about gods and snakes and all kinds of madness.").also { stage++ } + 22 -> npcl(FacialExpression.NEUTRAL, "We had to drive them out, in case their condition infected the rest of the troops. Their wives will be given a full widow pension when we return home.").also { stage++ } + 23 -> npcl(FacialExpression.NEUTRAL, "General Hining concluded that, whatever is down there, it's not affiliated with any of the elf factions, and it should be left alone.").also { stage++ } + 24 -> player(FacialExpression.FRIENDLY, "Thank you.").also { stage = 0 } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return TyrasGuard(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.TYRAS_GUARD_1203) + } +} diff --git a/Server/src/main/content/region/tirranwn/dialogue/TyrasGuardTent.kt b/Server/src/main/content/region/tirranwn/dialogue/TyrasGuardTent.kt new file mode 100644 index 0000000..35f8ab5 --- /dev/null +++ b/Server/src/main/content/region/tirranwn/dialogue/TyrasGuardTent.kt @@ -0,0 +1,39 @@ +package content.region.tirranwn.dialogue + +import core.game.dialogue.DialoguePlugin +import core.game.dialogue.FacialExpression +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.NPCs + +/** + * @author qmqz + */ + +@Initializable +class TyrasGuardTent(player: Player? = null) : DialoguePlugin(player){ + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + player(FacialExpression.FRIENDLY,"Hello").also { stage = 0 } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> npcl(FacialExpression.NEUTRAL,"Sorry, can't stop to talk. You should go to General Hining if you need something.").also { stage = 99 } + + 99 -> end() + } + return true + } + + override fun newInstance(player: Player?): DialoguePlugin { + return TyrasGuardTent(player) + } + + override fun getIds(): IntArray { + return intArrayOf(NPCs.TYRAS_GUARD_1206) + } +} diff --git a/Server/src/main/content/region/tirranwn/handlers/IsafdarListeners.kt b/Server/src/main/content/region/tirranwn/handlers/IsafdarListeners.kt new file mode 100644 index 0000000..15d837e --- /dev/null +++ b/Server/src/main/content/region/tirranwn/handlers/IsafdarListeners.kt @@ -0,0 +1,31 @@ +package content.region.tirranwn.handlers + +import core.game.world.map.Location +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +/** + * File to be used for anything Isafdar related. + * Handles the summoning/altar cave enter and exit in Isafdar. + * @author Sir Kermit + */ + +class IsafdarListeners : InteractionListener { + + val CAVE_ENTRANCE = 4006 + val CAVE_EXIT = 4007 + val outside = Location.create(2312, 3217, 0) + val inside = Location.create(2314, 9624, 0) + + override fun defineListeners() { + on(CAVE_ENTRANCE, IntType.SCENERY, "enter"){ player, node -> + player.teleport(inside) + return@on true + } + + on(CAVE_EXIT, IntType.SCENERY, "exit"){ player, node -> + player.teleport(outside) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/content/region/tirranwn/quest/rovingelves/ElunedDialogue.java b/Server/src/main/content/region/tirranwn/quest/rovingelves/ElunedDialogue.java new file mode 100644 index 0000000..67b9dda --- /dev/null +++ b/Server/src/main/content/region/tirranwn/quest/rovingelves/ElunedDialogue.java @@ -0,0 +1,199 @@ +package content.region.tirranwn.quest.rovingelves; + +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import org.rs09.consts.Items; +import content.data.Quests; + +/** + * Handles Eluned's Dialogue for Roving Elves. + * @author Splinter + */ +public class ElunedDialogue extends DialoguePlugin { + + public ElunedDialogue() { + + } + + public ElunedDialogue(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[] { 1679 }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + final Quest quest = player.getQuestRepository().getQuest(Quests.ROVING_ELVES); + switch (stage) { + case 500: + end(); + break; + case 1000: + if (quest.getStage(player) == 15 && !player.getInventory().contains(RovingElves.CONSECRATION_SEED_CHARGED.getId(), 1)) { + interpreter.sendDialogues(1679, FacialExpression.HALF_GUILTY, "Hello, any luck finding the consecration seed?"); + stage = 1002; + } + if (quest.getStage(player) == 15 && player.getInventory().contains(RovingElves.CONSECRATION_SEED_CHARGED.getId(), 1)) { + interpreter.sendDialogues(1679, FacialExpression.HALF_GUILTY, "You still have the charged seed with you, I can feel it.", "Hurry adventurer, go plant the seed and free", "my grandmother's spirit."); + stage = 500; + } + if (quest.getStage(player) == 15 && player.getInventory().contains(RovingElves.CONSECRATION_SEED.getId(), 1)) { + interpreter.sendDialogues(1679, FacialExpression.HALF_GUILTY, "Hello, any luck finding the consecration seed?"); + stage = 1002; + } + if (quest.getStage(player) == 20) { + interpreter.sendDialogues(1679, FacialExpression.HALF_GUILTY, "Hey... how's it going? Have you managed to", "reconsecrate Glarial's resting place?"); + stage = 12; + } else if (quest.getStage(player) != 15) { + interpreter.sendDialogues(1679, FacialExpression.HALF_GUILTY, "Hello there, it's a lovely day for a walk in the woods.", "So what can I help you with?"); + stage = 1001; + } + break; + case 1001: + if (quest.getStage(player) >= 100 && player.getInventory().contains(Items.TINY_ELF_CRYSTAL_6103, 1)) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I am looking to recharge teleportation crystals."); + stage = 1200; + } else { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'm just looking around."); + stage = 500; + } + break; + case 1002: + if (player.getInventory().contains(RovingElves.CONSECRATION_SEED.getId(), 1)) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Yes, I have it here."); + stage = 6; + } else { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I forgot what you told me to do."); + stage = 1003; + } + break; + case 1003: + interpreter.sendDialogues(1679, FacialExpression.HALF_GUILTY, "Re-enter Glarial's tomb and defeat the tomb's guardian.", "Take the consecration seed it is guarding and", "bring it back to me."); + stage = 500; + break; + case 1200: + int timesRecharged = player.getAttribute("rovingelves:crystal-teleport-recharges", 0); + int price = crystalTeleportPrice(timesRecharged); + interpreter.sendDialogues(1679, FacialExpression.HALF_GUILTY, "Very well. I'll recharge your teleportation", String.format("crystal for %d gold. What do you say?", price)); + stage = 1202; + break; + case 1202: + interpreter.sendOptions("Select an Option", "Recharge a crystal", "Nevermind"); + stage = 1203; + break; + case 1203: + switch (buttonId) { + case 1: + stage = 1204; + timesRecharged = player.getAttribute("rovingelves:crystal-teleport-recharges", 0); + price = crystalTeleportPrice(timesRecharged); + if (!player.getInventory().contains(995, price)) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Actually, I don't have enough coins."); + } else { + interpreter.sendDialogue(String.format("Eluned recharges your elven teleportation crystal for %d gold.", price)); + if (player.getInventory().remove(new Item(Items.TINY_ELF_CRYSTAL_6103)) && player.getInventory().remove(new Item(995, price))) { + player.getInventory().add(new Item(Items.TELEPORT_CRYSTAL_4_6099, 1)); + player.incrementAttribute("/save:rovingelves:crystal-teleport-recharges", 1); + } + } + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Nevermind, I really must be going."); + stage = 1204; + break; + } + break; + case 1204: + end(); + break; + + /* Main dialogue */ + + case 1: + interpreter.sendDialogues(1679, FacialExpression.HALF_GUILTY, "That I do... It is elvish tradition to plant a specially", "enchanted crystal seed at the graves of our ancestors.", "The seed will create guardians to protect the area."); + stage = 2; + break; + case 2: + interpreter.sendDialogues(1679, FacialExpression.HALF_GUILTY, "Unfortunately the crystal seed must be tuned to the", "person it's protecting... a new seed won't do. But you", "should be able to recover the seed from her old tomb."); + stage = 3; + break; + case 3: + interpreter.sendDialogues(1679, FacialExpression.HALF_GUILTY, "The tomb's guardian will be protecting the seed, you'll", "need to defeat him to get it. Once you have it, return", "here and I will re-enchant it."); + stage = 4; + break; + case 4: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "OK... I'll be back as soon as I have it."); + stage = 5; + break; + case 5: + quest.setStage(player, 15); + end(); + break; + case 6: + interpreter.sendItemMessage(RovingElves.CONSECRATION_SEED.getId(), "You hand the crystal seed to Eluned."); + stage = 7; + break; + case 7: + interpreter.sendDialogues(1679, FacialExpression.HALF_GUILTY, ""); + stage = 8; + break; + case 8: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "How odd. I can see her lips moving... But there's no", "sound."); + stage = 9; + break; + case 9: + if (player.getInventory().remove(RovingElves.CONSECRATION_SEED)) { + player.getInventory().add(RovingElves.CONSECRATION_SEED_CHARGED); + } + interpreter.sendItemMessage(RovingElves.CONSECRATION_SEED_CHARGED.getId(), "Eluned hands you an enchanted crystal seed."); + stage = 10; + break; + case 10: + interpreter.sendDialogues(1679, FacialExpression.HALF_GUILTY, "Plant this seed in Glarial's new tomb, close to her", "remains and she will rest in peace."); + stage = 11; + break; + case 11: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "OK."); + stage = 500; + break; + case 12: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Yes, it's done."); + stage = 13; + break; + case 13: + interpreter.sendDialogues(1679, FacialExpression.HALF_GUILTY, "Well done... You should go see Islwyn, but I'd guess he", "already knows."); + stage = 500; + break; + } + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new ElunedDialogue(player); + } + + @Override + public boolean open(Object... args) { + final Quest quest = player.getQuestRepository().getQuest(Quests.ROVING_ELVES); + if (quest.getStage(player) == 10) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hey there... Islwyn said you may be able to help me.", "He told me you know how to consecrate ground for an", "elven burial. I need to reconsecrate Glarial's resting", "place."); + stage = 1; + } else { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Good day."); + stage = 1000; + } + return true; + } + + // 750 for the 0th recharge, decreasing by 150 per recharge down to 150 + public int crystalTeleportPrice(int timesRecharged) { + return Math.max(750 - 150 * timesRecharged, 150); + } +} diff --git a/Server/src/main/content/region/tirranwn/quest/rovingelves/IsafdarZone.java b/Server/src/main/content/region/tirranwn/quest/rovingelves/IsafdarZone.java new file mode 100644 index 0000000..11c0d13 --- /dev/null +++ b/Server/src/main/content/region/tirranwn/quest/rovingelves/IsafdarZone.java @@ -0,0 +1,82 @@ +package content.region.tirranwn.quest.rovingelves; + +import static core.api.ContentAPIKt.*; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.ImpactHandler; +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneBuilder; +import core.plugin.Initializable; +import core.plugin.Plugin; + +import java.util.Arrays; +import java.util.List; + +/** + * locationUpdate hook for Isafdar traps + * @authors downthecrop + */ + +@Initializable +public final class IsafdarZone extends MapZone implements Plugin { + + public IsafdarZone() { super("Isafdar", true); } + + Location LEAF_TRAP_PIT = new Location(2336,9656,0); + + private String STICK_FAIL_MSG = "You set off the trap as you pass."; + private String WIRE_FAIL_MSG = "You snag the trip wire as you step over it."; + private String LEAF_FAIL_MSG = "You fall through and onto some spikes."; + + List WIRE_TRAPS = Arrays.asList( + new Location(2215,3154,0), + new Location(2220,3153,0), + new Location(2285,3188,0) + ); + + List LEAF_TRAPS = Arrays.asList( + new Location(2274,3174,0) + ); + + List STICK_TRAPS = Arrays.asList( + new Location(2236,3181,0), + new Location(2201,3169,0), + new Location(2276,3163,0) + ); + + @Override + public void configure() { + register(new ZoneBorders(2178, 3150, 2304, 3196)); + } + + @Override + public void locationUpdate(Entity e, Location last) { + if (e instanceof Player) { + Player player = (Player) e; + if(LEAF_TRAPS.contains(player.getLocation())){ + sendMessage(player,LEAF_FAIL_MSG); + impact(player,1, ImpactHandler.HitsplatType.NORMAL); + player.teleport(LEAF_TRAP_PIT); + } else if(STICK_TRAPS.contains(player.getLocation())) { + sendMessage(player,STICK_FAIL_MSG); + impact(player,1, ImpactHandler.HitsplatType.NORMAL); + } else if (WIRE_TRAPS.contains(player.getLocation())){ + sendMessage(player,WIRE_FAIL_MSG); + impact(player,1, ImpactHandler.HitsplatType.NORMAL); + } + } + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ZoneBuilder.configure(this); + return this; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } +} diff --git a/Server/src/main/content/region/tirranwn/quest/rovingelves/IslwynDialogue.java b/Server/src/main/content/region/tirranwn/quest/rovingelves/IslwynDialogue.java new file mode 100644 index 0000000..9dbb4a6 --- /dev/null +++ b/Server/src/main/content/region/tirranwn/quest/rovingelves/IslwynDialogue.java @@ -0,0 +1,384 @@ +package content.region.tirranwn.quest.rovingelves; + +import core.game.dialogue.DialogueInterpreter; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import content.data.Quests; + +/** + * Handles Islwyn's dialogue for Roving Elves. + * @author Splinter + */ +public class IslwynDialogue extends DialoguePlugin { + + public IslwynDialogue() { + + } + + public IslwynDialogue(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[] { DialogueInterpreter.getDialogueKey("islwyn_dialogue"), 1680 }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + final Quest quest = player.getQuestRepository().getQuest(Quests.ROVING_ELVES); + switch (stage) { + case 500: + end(); + break; + case 1000: + interpreter.sendDialogues(1680, FacialExpression.HALF_GUILTY, "Hello there, it's a lovely day for a walk in the woods.", "So what can I help you with?"); + stage = 1001; + break; + case 1001: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'm just looking around."); + stage = 500; + break; + case 2000: + if (quest.getStage(player) == 15) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Yes I have! She explained that I have to visit", "Glarial's old tomb and obtain a consecration seed", "from the temple guardian in there."); + stage = 2001; + } + if (quest.getStage(player) != 15) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Not yet, I'll be back when I have."); + stage = 500; + } + break; + case 2001: + interpreter.sendDialogues(1680, FacialExpression.HALF_GUILTY, "Good luck against the guardian, adventurer.", "Do it in the name of my grandmother Glarial."); + stage = 500; + break; + /* main dialogue sequence */ + case 0: + if (quest.getStage(player) == 10 || quest.getStage(player) == 15) { + interpreter.sendDialogues(1680, FacialExpression.HALF_GUILTY, "Have you spoken to Eluned yet?"); + stage = 2000; + } + if (quest.getStage(player) == 20) { + interpreter.sendDialogues(1680, FacialExpression.HALF_GUILTY, "You have returned! Thank you for all you have done.", "Now both me and my grandmother can rest in peace."); + stage = 19; + } else if (quest.getStage(player) != 10 && quest.getStage(player) != 15) { + interpreter.sendDialogues(1680, FacialExpression.HALF_GUILTY, "Leave me be, I have no time for easterners. Between", "your lot and them gnomes, all you do is take and", "destroy. No thought for others."); + stage = 1; + } + break; + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "...but..."); + stage = 2; + break; + case 2: + interpreter.sendDialogues(1680, FacialExpression.HALF_GUILTY, "Save your excuses young one! It was one of your", "species that disturbed my grandmother's remains. Will", "she never get the peace she deserves?"); + stage = 3; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Grandmother?"); + stage = 4; + break; + case 4: + interpreter.sendDialogues(1680, FacialExpression.HALF_GUILTY, "Yes! Someone took her ashes from her tomb. If it", "wasn't for them gnomes she'd have been left in peace.", "But now I can sense her restlessness."); + stage = 5; + break; + case 5: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Gnomes?"); + stage = 6; + break; + case 6: + interpreter.sendDialogues(1680, FacialExpression.HALF_GUILTY, "Yes gnomes! One of those little pests took the key to", "my grandmother's tomb. He must've given it to the", "human that desecrated the tomb."); + stage = 7; + break; + case 7: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Was your grandmother's name Glarial?"); + stage = 8; + break; + case 8: + interpreter.sendDialogues(1680, FacialExpression.HALF_GUILTY, "Yes... How did you know that?"); + stage = 9; + break; + case 9: + interpreter.sendOptions("Do you want to;", "Tell the truth?", "Lie?", "Leave the old elf be?"); + stage = 10; + break; + case 10: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "It's a bit of a long tale, but to cut the story short, her", "remains reside in Baxtorian's home. I thought it's where", "she'd want to be. It was I that removed your", "grandmother's ashes."); + stage = 11; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I just guessed.", "Well, now that that's over, I really need to be", "going."); + stage = 500; + break; + case 3: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "On second thought, I really should be going."); + stage = 500; + break; + } + break; + case 11: + interpreter.sendDialogues(1680, FacialExpression.HALF_GUILTY, "You've been in grandfather's home? That's where we", "originally wanted to leave Glarial's ashes to rest, but we", "could not understand how to enter."); + stage = 12; + break; + case 12: + interpreter.sendDialogues(1680, FacialExpression.HALF_GUILTY, "This is gravely concerning... Her resting place must be", "consecrated."); + stage = 13; + break; + case 13: + interpreter.sendOptions("Select an Option", "Maybe I could help.", "Sounds like you've got a lot to do."); + stage = 14; + break; + case 14: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Maybe I could help. What needs doing to consecrate", "her new tomb?"); + stage = 15; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Sounds like you've got a lot to do."); + stage = 500; + break; + } + break; + case 15: + interpreter.sendDialogues(1680, FacialExpression.HALF_GUILTY, "Are you offering to help?!? Maybe not all humans are", "as bad as I thought."); + stage = 16; + break; + case 16: + interpreter.sendDialogues(1680, FacialExpression.HALF_GUILTY, "I don't know the consecration process. You should speak", "with Eluned... she is wise in the ways of the ritual."); + stage = 17; + break; + case 17: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'll see what I can do."); + stage = 18; + break; + case 18: + end(); + quest.start(player); + break; + case 19: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "How did you know that I have consecrated the tomb?"); + stage = 20; + break; + case 20: + interpreter.sendDialogues(1680, FacialExpression.HALF_GUILTY, "Her restlessness has finally left me. Here - I should", "give you something for your effort."); + stage = 21; + break; + case 21: + interpreter.sendDoubleItemMessage(RovingElves.CRYSTAL_BOW_FULL, RovingElves.CRYSTAL_SHIELD_FULL, "Islwyn shows you a crystal bow and a crystal shield."); + stage = 22; + break; + case 22: + interpreter.sendDialogues(1680, FacialExpression.HALF_GUILTY, "Crystal equipment is at its best when new and", "previously unused. The bow does not require", "ammunition and reduces in strength the more it's fired.", "The shield decreases in defensive capabilities the more"); + stage = 23; + break; + case 23: + interpreter.sendDialogues(1680, FacialExpression.HALF_GUILTY, "it's hit. Both the shield and the bow I am carrying only", "have 500 uses before they revert to seed."); + stage = 24; + break; + case 24: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Revert to seed? What do you mean?"); + stage = 25; + break; + case 25: + interpreter.sendDialogues(1680, FacialExpression.HALF_GUILTY, "Ahhh, young one. It was thousands of years before we", "fully understood that ourselves. All will be explained if", "we feel you are ready. Now which one of these crystal", "creations would you like?"); + stage = 26; + break; + case 26: + interpreter.sendOptions("Select an Option", "Shields are for wimps! Give me the bow!", "I don't like running and hiding behind mushrooms. Shield please!"); + stage = 27; + break; + case 27: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Shields are for wimps! Give me the bow!"); + stage = 30; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I don't like running and hiding behind mushrooms.", "Shield please!"); + stage = 301; + break; + } + break; + case 30: + if (!quest.isCompleted(player)) { + if (!player.getInventory().add(new Item(4222, 1))) { + GroundItemManager.create(new Item(4222, 1), player); + } + quest.finish(player); + } + end(); + break; + case 301: + if (!quest.isCompleted(player)) { + if (!player.getInventory().add(new Item(4233, 1))) { + GroundItemManager.create(new Item(4233, 1), player); + } + quest.finish(player); + } + end(); + break; + case 31: + interpreter.sendDialogues(1680, FacialExpression.HALF_GUILTY, "Welcome back to the land of the elves, friend!", "Do you need your seeds charged into equipment?"); + stage = 32; + break; + case 32: + interpreter.sendOptions("Select an Option", "I need to buy a new piece of equipment.", "I need to recharge my seeds into equipment."); + stage = 33; + break; + case 33: + switch (buttonId) { + case 1: + interpreter.sendDialogues(1680, FacialExpression.HALF_GUILTY, "Ah, very well.", "I will sell you a new bow or shield for 900,000 coins."); + stage = 37; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I need to recharge my current seeds into equipment."); + stage = 34; + break; + } + break; + case 34: + interpreter.sendOptions("Select an Option", "Recharge seed into bow", "Recharge seed into shield"); + stage = 35; + break; + case 35: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Recharge my seed into a bow, please."); + stage = 36; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Recharge my seed into a shield, please."); + stage = 3601; + break; + } + break; + case 36: + if (!player.getInventory().contains(RovingElves.CRYSTAL_SEED.getId(), 1)) { + interpreter.sendDialogue("You don't have any seeds to recharge."); + stage = 500; + } + int timesRecharged = player.getAttribute("rovingelves:crystal-equip-recharges", 0); + int price = crystalWeaponPrice(timesRecharged); + if (!player.getInventory().contains(995, price)) { + interpreter.sendDialogue(String.format("You don't have enough coins, you need %d.", price)); + stage = 500; + } + if (player.getInventory().contains(995, price) && player.getInventory().contains(RovingElves.CRYSTAL_SEED.getId(), 1)) { + if (player.getInventory().remove(RovingElves.CRYSTAL_SEED) && player.getInventory().remove(new Item(995, price))) { + player.getInventory().add(new Item(4214, 1)); + player.incrementAttribute("/save:rovingelves:crystal-equip-recharges", 1); + end(); + } + } + break; + case 3601: + if (!player.getInventory().contains(RovingElves.CRYSTAL_SEED.getId(), 1)) { + interpreter.sendDialogue("You don't have any seeds to recharge."); + stage = 500; + } + timesRecharged = player.getAttribute("rovingelves:crystal-equip-recharges", 0); + price = crystalWeaponPrice(timesRecharged); + if (!player.getInventory().contains(995, price)) { + interpreter.sendDialogue("You don't have enough coins."); + stage = 500; + } + if (player.getInventory().contains(995, price) && player.getInventory().contains(RovingElves.CRYSTAL_SEED.getId(), 1)) { + if (player.getInventory().remove(RovingElves.CRYSTAL_SEED) && player.getInventory().remove(new Item(995, price))) { + player.getInventory().add(new Item(4225, 1)); + player.incrementAttribute("/save:rovingelves:crystal-equip-recharges", 1); + end(); + } + } + break; + case 37: + interpreter.sendOptions("Select an Option", "Purchase bow", "Purchase shield"); + stage = 38; + break; + case 38: + switch (buttonId) { + case 1: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'd like to buy a new bow."); + stage = 39; + break; + case 2: + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "I'd like to buy a new shield."); + stage = 40; + break; + } + break; + case 39: + price = crystalWeaponPrice(0); + if (!player.getInventory().contains(995, price)) { + interpreter.sendDialogue("You don't have enough coins."); + stage = 500; + } + if (player.getInventory().contains(995, price)) { + if (player.getInventory().remove(new Item(995, price))) { + if (!player.getInventory().add(new Item(4212, 1))) { + GroundItemManager.create(new Item(4212, 1), player); + } + end(); + } + } + break; + case 40: + price = crystalWeaponPrice(0); + if (!player.getInventory().contains(995, price)) { + interpreter.sendDialogue("You don't have enough coins."); + stage = 500; + } + if (player.getInventory().contains(995, price)) { + if (player.getInventory().remove(new Item(995, price))) { + if (!player.getInventory().add(new Item(4224, 1))) { + GroundItemManager.create(new Item(4224, 1), player); + } + end(); + } + } + break; + } + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new IslwynDialogue(player); + } + + @Override + public boolean open(Object... args) { + final Quest quest = player.getQuestRepository().getQuest(Quests.ROVING_ELVES); + final Quest waterfall = player.getQuestRepository().getQuest(Quests.WATERFALL_QUEST); + if (quest.getStage(player) == 0 && waterfall.isCompleted(player)) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello there."); + stage = 0; + } + if (!waterfall.isCompleted(player)) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello there."); + stage = 1000; + } + if (quest.isStarted(player) && quest.getStage(player) >= 10) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello Islwyn."); + stage = 0; + } + if (quest.isCompleted(player) || quest.getStage(player) >= 100) { + interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Hello Islwyn, I'm back."); + stage = 31; + } + return true; + } + + // 900k for the 0th recharge (or for new bows), decreasing by 180k per recharge down to 180k + public int crystalWeaponPrice(int timesRecharged) { + return Math.max(900000 - 180000 * timesRecharged, 180000); + } +} diff --git a/Server/src/main/content/region/tirranwn/quest/rovingelves/MossGiantGuardianNPC.java b/Server/src/main/content/region/tirranwn/quest/rovingelves/MossGiantGuardianNPC.java new file mode 100644 index 0000000..8268517 --- /dev/null +++ b/Server/src/main/content/region/tirranwn/quest/rovingelves/MossGiantGuardianNPC.java @@ -0,0 +1,84 @@ +package content.region.tirranwn.quest.rovingelves; + +import core.cache.def.impl.NPCDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.world.map.Location; +import core.plugin.Plugin; +import core.plugin.ClassScanner; +import content.data.Quests; + +/** + * The level 84 Moss Giant in Glarial's tomb. + * @author Splinter + */ +public final class MossGiantGuardianNPC extends AbstractNPC { + + /** + * Constructs a new {@code MossGiantGuardianNPC} {@code Object}. + */ + public MossGiantGuardianNPC() { + super(0, null); + } + + /** + * Constructs a new {@code MossGiantGuardianNPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + public MossGiantGuardianNPC(int id, Location location) { + super(id, location); + this.setAggressive(true); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new MossGiantGuardianNPC(id, location); + } + + @Override + public void finalizeDeath(Entity killer) { + super.finalizeDeath(killer); + if (killer instanceof Player) { + final Player player = (Player) killer; + final Quest quest = player.getQuestRepository().getQuest(Quests.ROVING_ELVES); + if (quest.getStage(player) == 15 && !player.getInventory().contains(RovingElves.CONSECRATION_SEED.getId(), 1)) { + player.getPacketDispatch().sendMessages("A small grey seed drops on the ground."); + GroundItemManager.create(new Item(RovingElves.CONSECRATION_SEED.getId()), getLocation(), player); + } + } + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ClassScanner.definePlugin(new OptionHandler() { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + NPCDefinition.forId(getIds()[0]).getHandlers().put("option:attack", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + ((NPC) node).attack(player); + return true; + } + + }); + return super.newInstance(arg); + } + + @Override + public int[] getIds() { + return new int[] { 1681 }; + } + +} diff --git a/Server/src/main/content/region/tirranwn/quest/rovingelves/RovingElves.java b/Server/src/main/content/region/tirranwn/quest/rovingelves/RovingElves.java new file mode 100644 index 0000000..91d6813 --- /dev/null +++ b/Server/src/main/content/region/tirranwn/quest/rovingelves/RovingElves.java @@ -0,0 +1,106 @@ +package content.region.tirranwn.quest.rovingelves; + +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import core.plugin.Initializable; +import core.plugin.ClassScanner; +import content.data.Quests; + +/** + * The Roving Elves quest. + * @author Splinter + */ +@Initializable +public class RovingElves extends Quest { + + /** + * Crystal Bow (full) + */ + public static final Item CRYSTAL_BOW_FULL = new Item(4214); + + /** + * Crystal Shield (full) + */ + public static final Item CRYSTAL_SHIELD_FULL = new Item(4225); + + /** + * The little seed. + */ + public static final Item CONSECRATION_SEED = new Item(4205); + + /** + * The little seed. (charged) + */ + public static final Item CONSECRATION_SEED_CHARGED = new Item(4206); + + /** + * Crystal seed, ready to be made into equipment + */ + public static final Item CRYSTAL_SEED = new Item(4207); + + /** + * Constructs a new {@Code RovingElves} {@Code Object} + */ + public RovingElves() { + super(Quests.ROVING_ELVES, 105, 104, 1, 402, 0, 1, 6); + } + + @Override + public void drawJournal(Player player, int stage) { + super.drawJournal(player, stage); + switch (stage) { + case 0: + line(player, "I can start this quest by talking to Islwyn found in Isafdar.Minimum requirements:I must have completed the Waterfall questI must be able to kill a level 84 moss giant unarmed", 11); + break; + case 10: + line(player, "It appears that when I recovered Glarial's ashes fromher tomb near the waterfall, I disturbed her peace.I talked to Islwyn, an elf that I found in the woods.When I offered to help he said I should talk with Eluned,she will tell me how elven consecration is done.", 11); + break; + case 15: + if (player.getInventory().contains(CONSECRATION_SEED.getId(), 1)) { + line(player, "It appears that when I recovered Glarial's ashes fromher tomb near the waterfall, I disturbed her peace.I talked to Islwyn, an elf that I found in the woods.When I offered to help he said I should talk with Eluned,she will tell me how elven consecration is done.Eluned told me that I must acquire the old consecration seed from the guardian spirit in Glarial's old tomb.Once I have the old seed I will need to return to Eluned, whowill re-enchant it for me.I have the consecration seed. I should return to Elunedand have her enchant it for me.", 11); + } else { + line(player, "It appears that when I recovered Glarial's ashes fromher tomb near the waterfall, I disturbed her peace.I talked to Islwyn, an elf that I found in the woods.When I offered to help he said I should talk with Eluned,she will tell me how elven consecration is done.Eluned told me that I must acquire the old consecration seed from the guardian spirit in Glarial's old tomb.Once I have the old seed I will need to return to Eluned, whowill re-enchant it for me.", 11); + } + if (player.getInventory().contains(CONSECRATION_SEED_CHARGED.getId(), 1)) { + line(player, "It appears that when I recovered Glarial's ashes fromher tomb near the waterfall, I disturbed her peace.I talked to Islwyn, an elf that I found in the woods.When I offered to help he said I should talk with Eluned,she will tell me how elven consecration is done.Eluned told me that I must acquire the old consecration seed from the guardian spirit in Glarial's old tomb.Once I have the old seed I will need to return to Eluned, whowill re-enchant it for me.I have the charged consecration seed.I need to head to the treasure room under the waterfall and plant the consecration seed near the chalice in order to free Glarial's spirit.", 11); + } + break; + case 20: + line(player, "It appears that when I recovered Glarial's ashes fromher tomb near the waterfall, I disturbed her peace.I talked to Islwyn, an elf that I found in the woods.When I offered to help he said I should talk with Eluned,she will tell me how elven consecration is done.Eluned told me that I must acquire the old consecration seed from the guardian spirit in Glarial's old tomb.Once I have the old seed I will need to return to Eluned, whowill re-enchant it for me.I have the charged consecration seed.I need to head to the treasure room under the waterfall and plant the consecration seed near the chalice in order to free Glarial's spirit.I have freed Glarial's spirit by planting the consecration seed nearthe chalice under the waterfall. The seed I planted vanished. I should go speak to Eluned again.", 11); + break; + case 100: + line(player, "It appears that when I recovered Glarial's ashes fromher tomb near the waterfall, I disturbed her peace.I talked to Islwyn, an elf that I found in the woods.When I offered to help he said I should talk with Eluned,she will tell me how elven consecration is done.Eluned told me that I must acquire the old consecration seed from the guardian spirit in Glarial's old tomb.Once I have the old seed I will need to return to Eluned, whowill re-enchant it for me.I have the charged consecration seed.I need to head to the treasure room under the waterfall and plant the consecration seed near the chalice in order to free Glarial's spirit.I have freed Glarial's spirit by planting the consecration seed nearthe chalice under the waterfall. The seed I planted vanished. I should go speak to Eluned again.QUEST COMPLETE!", 11); + break; + } + } + + @Override + public void start(Player player) { + super.start(player); + } + + @Override + public void finish(Player player) { + super.finish(player); + player.getPacketDispatch().sendString("1 Quest Point", 277, 8+ 2); + player.getPacketDispatch().sendString("Used elf equipment.", 277, 9+ 2); + player.getPacketDispatch().sendString("10000 Strength XP", 277, 10+ 2); + player.getPacketDispatch().sendString("You have completed Roving Elves!", 277, 2+ 2); + player.getPacketDispatch().sendItemZoomOnInterface(CRYSTAL_BOW_FULL.getId(), 235, 277, 3+ 2); + player.getSkills().addExperience(Skills.STRENGTH, 10000); + player.getQuestRepository().syncronizeTab(player); + } + + @Override + public Quest newInstance(Object object) { + ClassScanner.definePlugin(new RovingElvesPlugin()); + ClassScanner.definePlugin(new RovingElvesObstacles()); + ClassScanner.definePlugin(new ElunedDialogue()); + ClassScanner.definePlugin(new IslwynDialogue()); + ClassScanner.definePlugin(new MossGiantGuardianNPC()); + return this; + } + +} diff --git a/Server/src/main/content/region/tirranwn/quest/rovingelves/RovingElvesObstacles.java b/Server/src/main/content/region/tirranwn/quest/rovingelves/RovingElvesObstacles.java new file mode 100644 index 0000000..144b624 --- /dev/null +++ b/Server/src/main/content/region/tirranwn/quest/rovingelves/RovingElvesObstacles.java @@ -0,0 +1,236 @@ +package content.region.tirranwn.quest.rovingelves; + +import static core.api.ContentAPIKt.*; +import core.cache.def.impl.SceneryDefinition; +import content.global.skill.agility.AgilityHandler; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; +import java.util.Arrays; +import java.util.List; + +import static core.api.ContentAPIKt.hasRequirement; +import content.data.Quests; + +/** + * Handles all the agility obstacles for Roving Elves. + * @authors Splinter & downthecrop + */ +public final class RovingElvesObstacles extends OptionHandler { + + //Messages + private String LEAF_SUCCESS_MSG = "You safely jump across."; + private String LEAF_LADDER_MSG = "You climb out of the pit."; + private String STICK_SUCCESS_MSG = "You manage to skillfully pass the trap."; + private String WIRE_SUCCESS_MSG = "You successfully step over the tripwire."; + + private final Animation OVER = new Animation(839); + private final Animation THROUGH = new Animation(1237); + private final Animation STICK_TRAP = new Animation(819); + private final Animation LEAF_TRAP = new Animation(1115); + private final Animation WIRE_TRAP = new Animation(1236); + + private final Location STICK_TRAP_NORTH = new Location(0,2,0); + private final Location STICK_TRAP_SOUTH = new Location(0,-1,0); + private final Location STICK_TRAP_EAST = new Location(2,0,0); + private final Location STICK_TRAP_WEST = new Location(-1,0,0); + + private final Location WIRE_TRAP_NORTH = new Location(0,2,0); + private final Location WIRE_TRAP_SOUTH = new Location(0,-1,0); + private final Location WIRE_TRAP_EAST = new Location(2,0,0); + private final Location WIRE_TRAP_WEST = new Location(-1,0,0); + + private final Location FOREST_NORTH = new Location(0,2,0); + private final Location FOREST_SOUTH = new Location(0,-1,0); + private final Location FOREST_EAST = new Location(2,0,0); + private final Location FOREST_WEST = new Location(-1,0,0); + + private final Location LEAF_TRAP_CLIMB = new Location(2274, 3172, 0); + + private final List illegalJumpsY = Arrays.asList(3174); + + private Location nodeCenter(Node node){ + if(node.asScenery().getRotation() % 2 == 0) + return node.getLocation().transform(1,0,0); + return node.getLocation().transform(0,1,0); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(3922).getHandlers().put("option:pass", this); + SceneryDefinition.forId(3999).getHandlers().put("option:enter", this); + SceneryDefinition.forId(3939).getHandlers().put("option:enter", this); + SceneryDefinition.forId(3921).getHandlers().put("option:step-over", this); + SceneryDefinition.forId(3998).getHandlers().put("option:enter", this); + SceneryDefinition.forId(3938).getHandlers().put("option:enter", this); + SceneryDefinition.forId(3937).getHandlers().put("option:enter", this); + SceneryDefinition.forId(3924).getHandlers().put("option:jump", this); + SceneryDefinition.forId(3925).getHandlers().put("option:jump", this); + SceneryDefinition.forId(8742).getHandlers().put("option:pass", this); + SceneryDefinition.forId(3927).getHandlers().put("option:climb",this); + return this; + } + + + @Override + public boolean handle(final Player player, Node node, String option) { + + player.lock(5); + player.faceLocation(node.asScenery().getLocation()); + Boolean isNorthOrSouth = true; + + if (node.getId() == 3922 && node.asScenery().getRotation() % 2 == 0){ + //Facing East or West Stick Trap + isNorthOrSouth = false; + } else if (node.asScenery().getRotation() % 2 != 0) { + isNorthOrSouth = false; + } + + // Direction of the NODE in relation to the player + Direction NORTH_SOUTH = player.getLocation().getY() <= node.getLocation().getY() ? Direction.NORTH : Direction.SOUTH; + Direction EAST_WEST = player.getLocation().getX() <= node.getLocation().getX() ? Direction.EAST : Direction.WEST; + + switch (node.getId()) { + case 8742: + if (!hasRequirement(player, Quests.MOURNINGS_END_PART_I)) + return true; + player.teleport(player.getLocation().transform(EAST_WEST, 2)); + break; + case 3999: + AgilityHandler.forceWalk(player, -1, player.getLocation(), + player.getLocation().transform(NORTH_SOUTH, 3), OVER, 25, 0, null); + break; + //Wire Trap + case 3921: + if (isNorthOrSouth) { + if (NORTH_SOUTH == Direction.NORTH) + AgilityHandler.forceWalk(player, -1, node.getLocation().transform(WIRE_TRAP_SOUTH), + node.getLocation().transform(WIRE_TRAP_NORTH), WIRE_TRAP, 100, 0, WIRE_SUCCESS_MSG); + else + AgilityHandler.forceWalk(player, -1, node.getLocation().transform(WIRE_TRAP_NORTH), + node.getLocation().transform(WIRE_TRAP_SOUTH), WIRE_TRAP, 100, 0, WIRE_SUCCESS_MSG); + } else { + if (EAST_WEST == Direction.EAST) + AgilityHandler.forceWalk(player, -1, node.getLocation().transform(WIRE_TRAP_WEST), + node.getLocation().transform(WIRE_TRAP_EAST), WIRE_TRAP, 100, 0, WIRE_SUCCESS_MSG); + else + AgilityHandler.forceWalk(player, -1, node.getLocation().transform(WIRE_TRAP_EAST), + node.getLocation().transform(WIRE_TRAP_WEST), WIRE_TRAP, 100, 0, WIRE_SUCCESS_MSG); + } + break; + //Stick Trap + case 3922: + if (isNorthOrSouth) { + if (NORTH_SOUTH == Direction.NORTH) + AgilityHandler.forceWalk(player, -1, node.getLocation(), + node.getLocation().transform(STICK_TRAP_NORTH), STICK_TRAP, 25, 0, STICK_SUCCESS_MSG); + else + AgilityHandler.forceWalk(player, -1, node.getLocation(), + node.getLocation().transform(STICK_TRAP_SOUTH), STICK_TRAP, 25, 0, STICK_SUCCESS_MSG); + } else { + if (EAST_WEST == Direction.EAST) + AgilityHandler.forceWalk(player, -1, node.getLocation().transform(STICK_TRAP_WEST), + node.getLocation().transform(STICK_TRAP_EAST), STICK_TRAP, 25, 0, STICK_SUCCESS_MSG); + else + AgilityHandler.forceWalk(player, -1, node.getLocation().transform(STICK_TRAP_EAST), + node.getLocation().transform(STICK_TRAP_WEST), STICK_TRAP, 25, 0, STICK_SUCCESS_MSG); + } + break; + // Dense Forest + case 3998: + case 3939: + case 3938: + if (isNorthOrSouth) { + if (NORTH_SOUTH == Direction.NORTH) + AgilityHandler.forceWalk(player, -1, nodeCenter(node).transform(FOREST_SOUTH), + nodeCenter(node).transform(FOREST_NORTH), THROUGH, 25, 0, null); + else + AgilityHandler.forceWalk(player, -1, nodeCenter(node).transform(FOREST_NORTH), + nodeCenter(node).transform(FOREST_SOUTH), THROUGH, 25, 0, null); + } else { + if (EAST_WEST == Direction.EAST) + AgilityHandler.forceWalk(player, -1, nodeCenter(node).transform(FOREST_WEST), + nodeCenter(node).transform(FOREST_EAST), THROUGH, 25, 0, null); + else + AgilityHandler.forceWalk(player, -1, nodeCenter(node).transform(FOREST_EAST), + nodeCenter(node).transform(FOREST_WEST), THROUGH, 25, 0, null); + } + break; + // Climb Over Dense Forest + case 3937: + if (isNorthOrSouth) { + if (NORTH_SOUTH == Direction.NORTH) + AgilityHandler.forceWalk(player, -1, nodeCenter(node).transform(FOREST_SOUTH), + nodeCenter(node).transform(FOREST_NORTH), OVER, 25, 0, null); + else + AgilityHandler.forceWalk(player, -1, nodeCenter(node).transform(FOREST_NORTH), + nodeCenter(node).transform(FOREST_SOUTH), OVER, 25, 0, null); + } else { + if (EAST_WEST == Direction.EAST) + AgilityHandler.forceWalk(player, -1, nodeCenter(node).transform(FOREST_WEST), + nodeCenter(node).transform(FOREST_EAST), OVER, 25, 0, null); + else + AgilityHandler.forceWalk(player, -1, nodeCenter(node).transform(FOREST_EAST), + nodeCenter(node).transform(FOREST_WEST), OVER, 25, 0, null); + } + break; + // Leaf Trap Center + case 3924: + if(!illegalJumpsY.contains(player.getLocation().getY())){ + if (isNorthOrSouth) { + AgilityHandler.forceWalk(player, -1, node.getLocation().transform(NORTH_SOUTH,-1), + node.getLocation().transform(NORTH_SOUTH, 2), LEAF_TRAP, 25, 0, LEAF_SUCCESS_MSG); + } else { + AgilityHandler.forceWalk(player, -1, node.getLocation().transform(EAST_WEST,-2), + node.getLocation().transform(EAST_WEST, 2), LEAF_TRAP, 25, 0, LEAF_SUCCESS_MSG); + } + } + break; + // Leaf Trap Edges + case 3925: + if(!illegalJumpsY.contains(node.getLocation().getY())){ + if (!isNorthOrSouth) { + AgilityHandler.forceWalk(player, -1, node.getLocation().transform(NORTH_SOUTH,-1), + node.getLocation().transform(NORTH_SOUTH, 3), LEAF_TRAP, 25, 0, LEAF_SUCCESS_MSG); + } else { + AgilityHandler.forceWalk(player, -1, nodeCenter(node).transform(EAST_WEST,-1), + node.getLocation().transform(EAST_WEST, 3), LEAF_TRAP, 25, 0, LEAF_SUCCESS_MSG); + } + } + break; + case 3927: + player.teleport(LEAF_TRAP_CLIMB); + sendMessage(player,LEAF_LADDER_MSG); + break; + } + + return true; + } + + @Override + public Location getDestination(Node node, Node n) { + switch (node.getId()) { + case 3999: + return new Location(2188, 3162); + case 3998: + return new Location(2188, 3171); + } + return null; + } + + @Override + public boolean isWalk(Player player, Node node) { + return !(node instanceof Item); + } + + @Override + public boolean isWalk() { + return false; + } + +} diff --git a/Server/src/main/content/region/tirranwn/quest/rovingelves/RovingElvesPlugin.java b/Server/src/main/content/region/tirranwn/quest/rovingelves/RovingElvesPlugin.java new file mode 100644 index 0000000..38616e8 --- /dev/null +++ b/Server/src/main/content/region/tirranwn/quest/rovingelves/RovingElvesPlugin.java @@ -0,0 +1,103 @@ +package content.region.tirranwn.quest.rovingelves; + +import core.cache.def.impl.ItemDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.quest.Quest; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; +import content.data.Quests; + +/** + * Master plugin file for Roving Elves. + * @author Splinter + */ +public final class RovingElvesPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(5252).getHandlers().put("option:search", this); + ItemDefinition.forId(RovingElves.CONSECRATION_SEED_CHARGED.getId()).getHandlers().put("option:plant", this); + return this; + } + + /** + * The digging animation. + */ + public static final Animation ANIMATION_DIG = Animation.create(830); + + /** + * The drop animation. + */ + public static final Animation ANIMATION_DROP = Animation.create(827); + + @SuppressWarnings("static-access") + @Override + public boolean handle(final Player player, Node node, String option) { + final Quest quest = player.getQuestRepository().getQuest(Quests.ROVING_ELVES); + if (quest == null) { + player.sendMessage("Error! RovingElves quest cannot be found, please contact an admin!"); + return true; + } + switch (node.getId()) { + case 5252: + player.getDialogueInterpreter().sendDialogue("The firepit is still warm, there must be travellers about. Maybe I", "should look for them."); + break; + case 4206: + if (player.getLocation().getDistance(new Location(2603, 9911), player.getLocation()) <= 3 && quest.getStage(player) == 15) { + if (!player.getInventory().containsItem(new Item(952, 1))) { + player.getPacketDispatch().sendMessage("You need a spade to plant the seed."); + } else { + player.animate(ANIMATION_DIG); + player.getPacketDispatch().sendMessage("You dig a small hole with your spade."); + GameWorld.getPulser().submit(new Pulse(1, player) { + int counter; + + @Override + public boolean pulse() { + switch (counter++) { + case 3: + player.getPacketDispatch().sendMessage("You drop the crystal seed in the hole."); + player.animate(ANIMATION_DROP); + player.faceLocation(new Location(2604, 9907, 0)); + break; + case 6: + player.getInventory().remove(new Item(RovingElves.CONSECRATION_SEED_CHARGED.getId())); + quest.setStage(player, 20); + player.getPacketDispatch().sendGlobalPositionGraphic(719, new Location(2604, 9907, 0)); + player.getPacketDispatch().sendMessage("The seed vanishes in a puff of smoke."); + break; + } + return false; + } + }); + } + } + break; + } + + return true; + } + + @Override + public Location getDestination(Node node, Node n) { + return null; + } + + @Override + public boolean isWalk(Player player, Node node) { + return !(node instanceof Item); + } + + @Override + public boolean isWalk() { + return false; + } + +} diff --git a/Server/src/main/content/region/wilderness/dialogue/CapeMerchantDialogue.java b/Server/src/main/content/region/wilderness/dialogue/CapeMerchantDialogue.java new file mode 100644 index 0000000..ebf5d95 --- /dev/null +++ b/Server/src/main/content/region/wilderness/dialogue/CapeMerchantDialogue.java @@ -0,0 +1,94 @@ +package content.region.wilderness.dialogue; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.npc.NPC; +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Handles the cape merchant dialogue. + * @author Vexia + */ +@Initializable +public class CapeMerchantDialogue extends DialoguePlugin { + + /** + * Constructs a new {@code CapeMerchantDialogue} {@code Object} + * @param player the player. + */ + public CapeMerchantDialogue(Player player) { + super(player); + } + + /** + * Constructs a new {@code CapeMerchantDialogue} {@code Object} + */ + public CapeMerchantDialogue() { + /** + * empty. + */ + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new CapeMerchantDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + npc("Hello there, are you interested in buying one of my", "special capes?"); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + options("What's so special about your capes?", "Yes please!", "No thanks."); + stage++; + break; + case 1: + switch (buttonId) { + case 1: + player("What's so special about your capes?"); + stage = 10; + break; + case 2: + player("Yes please!"); + stage = 20; + break; + case 3: + player("No thanks."); + stage = 30; + break; + } + break; + case 10: + npc("Ahh well they make it less likely that you'll accidently", "attack anyone wearing the same cape as you and easier", "to attack everyone else. They also make it easier to", "distinguish people who're wearing the same cape as you"); + stage++; + break; + case 11: + npc("from everyone else. They're very useful when out in", "the wilderness with friends or anyone else you don't", "want to harm."); + stage++; + break; + case 12: + end(); + break; + case 20: + end(); + npc.openShop(player); + break; + case 30: + end(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { 1778, 1779, 1780, 1781, 1782, 1783, 1784, 1785, 1786, 1787 }; + } + +} diff --git a/Server/src/main/content/region/wilderness/handlers/BorkNPC.java b/Server/src/main/content/region/wilderness/handlers/BorkNPC.java new file mode 100644 index 0000000..c0a28f0 --- /dev/null +++ b/Server/src/main/content/region/wilderness/handlers/BorkNPC.java @@ -0,0 +1,604 @@ +package content.region.wilderness.handlers; + +import core.game.component.Component; +import content.data.BossKillCounter; +import core.game.interaction.Option; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.ChanceItem; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.build.DynamicRegion; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.net.packet.PacketRepository; +import core.net.packet.context.CameraContext; +import core.net.packet.context.CameraContext.CameraType; +import core.net.packet.context.MinimapStateContext; +import core.net.packet.out.CameraViewPacket; +import core.net.packet.out.MinimapState; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.plugin.ClassScanner; +import core.tools.RandomFunction; +import core.game.activity.ActivityPlugin; +import core.game.activity.CutscenePlugin; +import core.game.dialogue.DialogueInterpreter; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.skill.Skills; + +import java.util.ArrayList; +import java.util.List; + +/** + * Handles the bork npc. + * @author Vexia + */ +@Initializable +public class BorkNPC extends AbstractNPC { + + /** + * The chats the legion can say. + */ + private static final String[] LEGION_CHATS = new String[] { "For Bork!", "Die, human!", "Resistance is futile!", "We are the collective!", "Form a triangle!!", "To the attack!", "Hup! 2... 3... 4!!" }; + + /** + * The chance items. + */ + private static final ChanceItem[] DROPS = new ChanceItem[] { new ChanceItem(532, 1, 1, 0.0), new ChanceItem(12163, 5, 5, 0.0), new ChanceItem(12160, 7, 7, 0.0), new ChanceItem(12159, 2, 2, 0.0), new ChanceItem(995, 2000, 10000, 0.0), new ChanceItem(1619, 1, 0.0), new ChanceItem(1621, 1, 1, 0.0), new ChanceItem(1623, 1, 1, 0.0) }; + + /** + * The ring drops. + */ + private static final ChanceItem[] RING_DROPS = new ChanceItem[] { new ChanceItem(532, 1, 1, 0.0), new ChanceItem(12163, 5, 5, 0.0), new ChanceItem(12160, 10, 10, 0.0), new ChanceItem(12159, 3, 3, 0.0), new ChanceItem(1601, 1, 1, 0.0), new ChanceItem(995, 2000, 10000, 0.0), new ChanceItem(1619, 2, 2, 0.0), new ChanceItem(1621, 3, 3, 0.0) }; + + /** + * The list of the legion npc. + */ + private final List legions = new ArrayList<>(20); + + /** + * If the legion is spawned. + */ + private boolean spawnedLegion; + + /** + * The player. + */ + private Player player; + + /** + * The bork cutscene. + */ + private BorkCutscene cutscene; + + /** + * Constructs a new {@Code BorkNPC} {@Code Object} + */ + public BorkNPC() { + super(-1, null); + } + + /** + * Constructs a new {@Code BorkNPC} {@Code Object} + * @param id the id. + * @param location the location. + */ + public BorkNPC(int id, Location location) { + super(id, location); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new BorkNPC(id, location); + } + + @Override + public void handleTickActions() { + if (player == null) { + return; + } + super.handleTickActions(); + if (!getLocks().isMovementLocked() && player != null) { + if (!getProperties().getCombatPulse().isAttacking()) { + getProperties().getCombatPulse().attack(player); + } + } + } + + @Override + public void finalizeDeath(Entity killer){ + super.finalizeDeath(killer); + BossKillCounter.addtoKillcount((Player) killer, this.getId()); + } + + @Override + public void commenceDeath(Entity killer) { + super.commenceDeath(killer); + for (NPC l : legions) { + l.clear(); + } + player.lock(); + cutscene.wizard.clear(); + cutscene.wizard.lock(); + player.getInterfaceManager().removeTabs(0, 1, 2, 3, 4, 5, 6, 11, 12); + PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 2)); + player.getInterfaceManager().open(new Component(693)); + if (player.getDialogueInterpreter().getDialogue() != null) { + player.getDialogueInterpreter().getDialogue().end(); + } + GameWorld.getPulser().submit(new Pulse(10, player) { + + @Override + public boolean pulse() { + player.unlock(); + player.getDialogueInterpreter().sendDialogues(player, FacialExpression.FURIOUS, "That monk - he called to Zamorak for revenge!"); + player.sendMessage("Something is shaking the whole cavern! You should get out of here quick!"); + PacketRepository.send(CameraViewPacket.class, new CameraContext(player, CameraType.SHAKE, 3, 2, 2, 2, 2)); + player.getInterfaceManager().restoreTabs(); + PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 0)); + player.getInterfaceManager().close(); + return true; + } + + }); + } + + @Override + public void handleDrops(Player p, Entity killer) { + if (player.getAttribute("first-bork", false)) { + player.removeAttribute("first-bork"); + player.getSkills().addExperience(Skills.SLAYER, 5000, true); + } else { + player.getSkills().addExperience(Skills.SLAYER, 1500, true); + } + ChanceItem[] drops = new Item(player.getEquipment().getId(12)).getName().toLowerCase().contains("ring of wealth") ? RING_DROPS : DROPS; + for (int i = 0; i < drops.length; i++) { + Item item = new Item(drops[i].getId(), RandomFunction.random(drops[i].getMinimumAmount(), drops[i].getMaximumAmount())); + GroundItemManager.create(item, getLocation(), player); + } + if (RandomFunction.random(5) == 1) { + super.handleDrops(p, killer); + } + } + + @Override + public void checkImpact(BattleState state) { + super.checkImpact(state); + if (!spawnedLegion && getSkills().getLifepoints() < (getSkills().getStaticLevel(Skills.HITPOINTS) / 2)) { + spawnLegion(); + } + } + + /** + * Spawns the legion. + */ + private void spawnLegion() { + player.getInterfaceManager().removeTabs(0, 1, 2, 3, 4, 5, 6, 11, 12); + PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 2)); + spawnedLegion = true; + player.lock(); + player.getImpactHandler().setDisabledTicks(14); + lock(); + cutscene.wizard.lock(); + getProperties().getCombatPulse().stop(); + player.getProperties().getCombatPulse().stop(); + getAnimator().forceAnimation(Animation.create(8757)); + GameWorld.getPulser().submit(new Pulse(1, player, this) { + + @Override + public boolean pulse() { + getAnimator().forceAnimation(Animation.create(8757)); + sendChat("Come to my aid, brothers!"); + player.sendMessage("Bork strikes the ground with his axe."); + GameWorld.getPulser().submit(new Pulse(4, player) { + + @Override + public boolean pulse() { + player.getInterfaceManager().open(new Component(691)); + return true; + } + + }); + GameWorld.getPulser().submit(new Pulse(13, player) { + + @Override + public boolean pulse() { + player.getInterfaceManager().close(); + for (int i = 0; i < 3; i++) { + NPC legion = NPC.create(7135, getLocation().transform(RandomFunction.random(1, 3), RandomFunction.random(1, 3), 0), player); + legion.init(); + legion.graphics(Graphics.create(1314)); + legion.setAggressive(true); + legion.setRespawn(false); + legion.attack(player); + legions.add(legion); + legion.sendChat(RandomFunction.getRandomElement(LEGION_CHATS)); + } + player.unlock(); + cutscene.wizard.unlock(); + unlock(); + if (player != null) { + attack(player); + player.getInterfaceManager().restoreTabs(); + PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 0)); + } + for (NPC n : legions) { + n.getProperties().getCombatPulse().attack(player); + } + return true; + } + + }); + return true; + } + + }); + } + + /** + * Sets the player. + * @param player the player. + */ + public void setPlayer(Player player) { + this.player = player; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ClassScanner.definePlugin(new BorkCutscene()); + ClassScanner.definePlugin(new DagonDialogue()); + ClassScanner.definePlugin(new OrkLegion()); + ClassScanner.definePlugin(new DagonElite()); + return super.newInstance(arg); + } + + @Override + public int[] getIds() { + return new int[] { 7133 }; + } + + /** + * Handles the ork legion. + * @author Vexia + */ + public class OrkLegion extends AbstractNPC { + + private Player player; + + /** + * The last talk. + */ + private int lastTalk = GameWorld.getTicks() + 30; + + /** + * Constructs a new {@Code OrkLegion} {@Code Object} + * @param id the id. + * @param location the location. + */ + public OrkLegion(int id, Location location) { + super(id, location); + super.setAggressive(true); + } + + /** + * Constructs a new {@Code OrkLegion} {@Code Object} + */ + public OrkLegion() { + super(-1, null); + } + + @Override + public void handleTickActions() { + if (player == null) { + return; + } + + if (lastTalk < GameWorld.getTicks()) { + sendChat(LEGION_CHATS[RandomFunction.random(LEGION_CHATS.length)]); + lastTalk = GameWorld.getTicks() + 30; + } + } + + @Override + public boolean isIgnoreMultiBoundaries(Entity victim) { + return true; + } + + @Override + public boolean canAttack(Entity e) { + return true; + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + OrkLegion legion = new OrkLegion(id, location); + legion.player = (Player) objects[0]; + return legion; + } + + @Override + public int[] getIds() { + return new int[] { 7135 }; + } + + } + + /** + * Handles the dagone lite npc. + * @author Vexia + */ + public class DagonElite extends AbstractNPC { + + private Player player; + + /** + * Constructs a new {@Code DagonElite} {@Code Object} + * @param id the id. + * @param location the location. + */ + public DagonElite(int id, Location location) { + super(id, location); + } + + /** + * Constructs a new {@Code DagonElite} {@Code Object} + */ + public DagonElite() { + super(-1, null); + } + + @Override + public void checkImpact(BattleState state) { + state.neutralizeHits(); + } + + @Override + public boolean isIgnoreMultiBoundaries(Entity victim) { + return true; + } + + @Override + public boolean canAttack(Entity e) { + return true; + } + + @Override + public boolean isAttackable(Entity e, CombatStyle style, boolean message) { + return false; + } + + @Override + public void handleTickActions() { + if (player == null) { + return; + } + super.handleTickActions(); + if (!getProperties().getCombatPulse().isAttacking()) { + getProperties().getCombatPulse().attack(player); + } + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + DagonElite elite = new DagonElite(id, location); + elite.player = (Player) objects[0]; + return elite; + } + + @Override + public int[] getIds() { + return new int[] { 7137 }; + } + + } + + /** + * Handles the bork cutscene. + * @author Vexia + */ + public class BorkCutscene extends CutscenePlugin { + + /** + * The bork npc. + */ + private BorkNPC bork; + + /** + * The wizard npc. + */ + private NPC wizard; + + /** + * Constructs a new {@Code BorkCutscene} {@Code Object} + */ + public BorkCutscene() { + super("Bork cutscene"); + this.setMulticombat(true); + } + + /** + * Constructs a new {@Code BorkCutscene} {@Code Object} + * @param player the player. + */ + public BorkCutscene(Player player) { + this(); + this.player = player; + } + + @Override + public boolean interact(Entity e, Node target, Option option) { + if (e instanceof Player) { + switch (target.getId()) { + case 29537: + e.asPlayer().graphics(Graphics.create(110)); + e.asPlayer().teleport(Location.create(3143, 5545, 0)); + return true; + } + } + return super.interact(e, target, option); + } + + @Override + public boolean leave(Entity entity, boolean logout) { + if (entity instanceof Player) { + PacketRepository.send(CameraViewPacket.class, new CameraContext(entity.asPlayer(), CameraType.RESET, 3, 2, 2, 2, 2)); + } + return super.leave(entity, logout); + } + + @Override + public boolean start(Player player, boolean login, Object... args) { + player.lock(); + bork = new BorkNPC(7133, base.transform(26, 33, 0)); + bork.init(); + bork.setPlayer(player); + bork.setRespawn(false); + bork.lock(); + bork.cutscene = this; + wizard = NPC.create(7137, base.transform(38, 29, 0), player); + wizard.init(); + wizard.lock(); + wizard.faceTemporary(player, 2); + player.getImpactHandler().setDisabledTicks(5); + player.faceTemporary(wizard, 2); + return super.start(player, login, args); + } + + @Override + public void stop(boolean fade) { + end(); + } + + /** + * Commences the fight. + */ + public void commenceFight() { + bork.unlock(); + wizard.unlock(); + player.unlock(); + wizard.attack(player); + bork.attack(player); + wizard.setRespawn(false); + player.getInterfaceManager().restoreTabs(); + PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 0)); + } + + @Override + public void open() { + super.open(); + bork.cutscene.player = player; + player.lock(); + player.getInterfaceManager().open(new Component(692)); + GameWorld.getPulser().submit(new Pulse(13, player) { + + @Override + public boolean pulse() { + commenceFight(); + player.getInterfaceManager().close(); + + player.getDialogueInterpreter().open("dagon-dialogue", wizard, BorkCutscene.this); + return true; + } + + }); + } + + @Override + public ActivityPlugin newInstance(Player p) throws Throwable { + return new BorkCutscene(player); + } + + @Override + public Location getStartLocation() { + return base.transform(36, 33, 0); + } + + @Override + public Location getSpawnLocation() { + return null; + } + + @Override + public void configure() { + region = DynamicRegion.create(12374); + region.setMulticombat(true); + region.setMusicId(488); + setRegionBase(); + registerRegion(region.getId()); + } + } + + /** + * Handles the dagon dialogue. + * @author Vexia + */ + public class DagonDialogue extends DialoguePlugin { + + /** + * The bork cutscene. + */ + private BorkCutscene cutscene; + + /** + * Constructs a new {@Code DagonDialogue} {@Code Object} + */ + public DagonDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@Code DagonDialogue} {@Code Object} + * @param player the player. + */ + public DagonDialogue(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new DagonDialogue(player); + } + + @Override + public boolean open(Object... args) { + npc = (NPC) args[0]; + cutscene = (BorkCutscene) args[1]; + npc("Our Lord Zamorak has power over life and death,", player.getUsername() + "! He has seen fit to resurrect Bork to", "continue his great work...and now you will fall before him"); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + boolean played = player.getSavedData().getActivityData().hasKilledBork(); + player(played ? "Uh -oh! Here we go again." : "Oh boy..."); + stage++; + break; + case 1: + end(); + cutscene.commenceFight(); + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { DialogueInterpreter.getDialogueKey("dagon-dialogue") }; + } + + } +} diff --git a/Server/src/main/content/region/wilderness/handlers/ChaosElementalNPC.java b/Server/src/main/content/region/wilderness/handlers/ChaosElementalNPC.java new file mode 100644 index 0000000..4da67fe --- /dev/null +++ b/Server/src/main/content/region/wilderness/handlers/ChaosElementalNPC.java @@ -0,0 +1,188 @@ +package content.region.wilderness.handlers; + +import content.data.BossKillCounter; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.equipment.SwitchAttack; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.tools.RandomFunction; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.node.entity.combat.MultiSwingHandler; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.*; + +/** + * Handles the chaos elemental npc. + * @author Vexia + */ +@Initializable +public class ChaosElementalNPC extends AbstractNPC { + + /** + * The multi swing handler. + */ + private final MultiSwingHandler COMBAT_HANDLER = new ChaosCombatHandler(); + + /** + * Constructs a new {@Code ChaosElementalNPC} {@Code Object} + * @param id the id. + * @param location the location. + */ + public ChaosElementalNPC(int id, Location location) { + super(id, location); + } + + @Override + public void tick() { + super.tick(); + if(!isActive()){ + getProperties().getCombatPulse().stop(); + } + } + + /** + * Constructs a new {@Code ChaosElementalNPC} {@Code Object} + */ + public ChaosElementalNPC() { + this(-1, null); + } + + @Override + public CombatSwingHandler getSwingHandler(boolean swing) { + return COMBAT_HANDLER; + } + + @Override + public void sendImpact(BattleState state) { + if (state.getEstimatedHit() > 28) { + state.setEstimatedHit(RandomFunction.random(20, 28)); //possibly absolutely mental "haha random" damage adjustment. not sure. - crash + } + super.sendImpact(state); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new ChaosElementalNPC(id, location); + } + + @Override + public int[] getIds() { + return new int[] { 3200 }; + } + + @Override + public void finalizeDeath(Entity killer) { + super.finalizeDeath(killer); + BossKillCounter.addtoKillcount((Player) killer, this.getId()); + } + + /** + * Handles the chaos combat handler. + * @author Vexia + */ + public static class ChaosCombatHandler extends MultiSwingHandler { + + /** + * The projectile animation. + */ + private static final Animation PROJECTILE_ANIM = new Animation(3148); + + /** + * The primary projectile. + */ + private static final Projectile PRIMARY_PROJECTILE = Projectile.create((Entity) null, null, 557, 60, 55, 41, 46, 20, 255); + + /** + * The switch attacks. + */ + private static final SwitchAttack[] ATTACKS = new SwitchAttack[] { new SwitchAttack(CombatStyle.MELEE.getSwingHandler(), PROJECTILE_ANIM, new Graphics(556), null, PRIMARY_PROJECTILE), // primary + new SwitchAttack(CombatStyle.RANGE.getSwingHandler(), PROJECTILE_ANIM, new Graphics(556), null, PRIMARY_PROJECTILE),// primary + new SwitchAttack(CombatStyle.MAGIC.getSwingHandler(), PROJECTILE_ANIM, new Graphics(556), null, PRIMARY_PROJECTILE),// primary + new SwitchAttack(CombatStyle.MAGIC.getSwingHandler(), PROJECTILE_ANIM, new Graphics(553), null, Projectile.create((Entity) null, null, 554, 60, 55, 41, 46, 20, 255)) { + @Override + public boolean canSelect(Entity entity, Entity victim, BattleState state) { + return true; + } + },// tele + new SwitchAttack(CombatStyle.MAGIC.getSwingHandler(), PROJECTILE_ANIM, new Graphics(550), null, Projectile.create((Entity) null, null, 551, 60, 55, 41, 46, 20, 255)) { + @Override + public boolean canSelect(Entity entity, Entity victim, BattleState state) { + return true; + } + } }; + + /** + * Constructs a new {@Code ChaosCombatHandler} {@Code + * Object} + */ + public ChaosCombatHandler() { + super(ATTACKS); + } + + @Override + public void impact(Entity entity, Entity victim, BattleState state) { + super.impact(entity, victim, state); + SwitchAttack attack = super.getCurrent(); + if (victim instanceof Player) { + Player player = victim.asPlayer(); + if (player == null) { + return; + } + if (attack.getProjectile().getProjectileId() == 557) { + playGlobalAudio(player.getLocation(), Sounds.CHAOS_ELEMENTAL_HIT_351); // C. Elemental Discord Impact SFX + } + else if (attack.getProjectile().getProjectileId() == 554) { + playAudio(player, Sounds.CHAOS_ELEMENTAL_CONFUSION_IMPACT_346); // C. Elemental Confusion Impact SFX + Location loc = getPathableRandomLocalCoordinate(player, 10, entity.getLocation(), 3); + player.teleport(loc); + } else if (attack.getProjectile().getProjectileId() == 551) { + playGlobalAudio(player.getLocation(), Sounds.CHAOS_ELEMENTAL_MADNESS_IMPACT_353); // C. Elemental Madness Impact SFX + if (player.getInventory().freeSlots() < 1 || player.getEquipment().itemCount() < 1) { + return; + } + Item e = null; + int tries = 0; + while (e == null && tries < 30) { + e = player.getEquipment().toArray()[RandomFunction.random(player.getEquipment().itemCount())]; + tries++; + if (e != null && player.getInventory().hasSpaceFor(e)) { + break; + } + e = null; + } + if (e == null) { + return; + } + player.lock(1); + if (!player.getEquipment().containsItem(e)) { + return; + } + if (player.getEquipment().remove(e)) { + player.getInventory().add(e); + } + } + } + } + + /** + * Gets the random loc. + * @param entity the entity. + * @return the loc. + */ + public Location getRandomLoc(Entity entity) { + Location l = entity.getLocation(); + boolean negative = RandomFunction.random(2) == 1; + return l.getLocation().transform((negative ? RandomFunction.random(-10, 10) : RandomFunction.random(0, 10)), (negative ? RandomFunction.random(-10, 10) : RandomFunction.random(0, 10)), 0); + } + } + +} diff --git a/Server/src/main/content/region/wilderness/handlers/ChaosTunnelZone.java b/Server/src/main/content/region/wilderness/handlers/ChaosTunnelZone.java new file mode 100644 index 0000000..6d1f06c --- /dev/null +++ b/Server/src/main/content/region/wilderness/handlers/ChaosTunnelZone.java @@ -0,0 +1,369 @@ +package content.region.wilderness.handlers; + +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import core.cache.def.impl.SceneryDefinition; +import core.game.activity.ActivityManager; +import core.game.interaction.Option; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import org.json.simple.JSONObject; +import core.ServerStore; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneBuilder; +import core.game.world.map.zone.ZoneRestriction; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.plugin.ClassScanner; +import core.tools.RandomFunction; + +import static core.api.ContentAPIKt.hasRequirement; +import content.data.Quests; + +/** + * Handles the chaos tunnels. + * @author Vexia + */ +@Initializable +public final class ChaosTunnelZone extends MapZone implements Plugin { + + /** + * The entrance data. + */ + private static final Object[][] ENTRANCE_DATA = new Object[][] { { 28891, new Location(3182, 5471, 0), 28782, new Location(3059, 3549, 0) },// 1 + { 28893, new Location(3248, 5489, 0), 28782, new Location(3120, 3571, 0) },// 2 + { 28892, new Location(3292, 5479, 0), 28782, new Location(3166, 3561, 0) },// 3 + { 28893, new Location(3234, 5558, 0), 28782, new Location(3107, 3640, 0) },// 4 + { 28892, new Location(3290, 5538, 0), 28782, new Location(3165, 3617, 0) },// 5 + }; + + /** + * The mapping of portals. + */ + private static final Map PORTALS = new HashMap<>(); + + /** + * Constructs a new {@Code ChaosTunnelZone} {@Code Object} + */ + public ChaosTunnelZone() { + super("Chaos tunnel", true, ZoneRestriction.CANNON); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ZoneBuilder.configure(this); + ClassScanner.definePlugin(new OptionHandler() { + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (int i = 0; i < ENTRANCE_DATA.length; i++) { + SceneryDefinition.forId((int) ENTRANCE_DATA[i][0]).getHandlers().put("option:enter", this); + SceneryDefinition.forId((int) ENTRANCE_DATA[i][2]).getHandlers().put("option:climb-up", this); + } + SceneryDefinition.forId(23074).getHandlers().put("option:climb", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + Object[] data = null; + switch (option) { + case "enter": + case "climb-up": + switch (node.getId()) { + case 28891: + case 28893: + case 28892: + case 28782: + if (option.equals("enter") && player.inCombat()) { + player.sendMessage("You can't enter the rift when you've recently been in combat."); + return true; + } + for (int i = 0; i < ENTRANCE_DATA.length; i++) { + if ((int) ENTRANCE_DATA[i][option.equals("enter") ? 0 : 2] == node.getId() && player.getLocation().withinDistance((Location) ENTRANCE_DATA[i][option.equals("enter") ? 3 : 1])) { + data = ENTRANCE_DATA[i]; + break; + } + } + if (data == null) { + player.sendMessage("Error! Data null."); + break; + } + player.teleport((Location) data[option.equals("enter") ? 1 : 3]); + break; + } + break; + case "climb": + switch (node.getId()) { + case 23074: + player.teleport(new Location(3283, 3467, 0)); + break; + } + break; + } + return true; + } + }); + return this; + } + + @Override + public boolean interact(Entity entity, Node target, Option option) { + if (entity instanceof Player) { + switch (target.getId()) { + case 29537: + break; + case 28779:// portal + if (target.getLocation().equals(new Location(3326, 5469, 0))) { + entity.asPlayer().sendMessage("You can't go back through this portal."); + return true; + } + teleport(entity.asPlayer(), target.asScenery()); + break; + } + } + return super.interact(entity, target, option); + } + + @Override + public boolean enter(Entity entity) { + if (entity instanceof NPC) { + NPC n = entity.asNpc(); + if (!n.isAggressive()) { + n.setAggressive(true); + } + } + return super.enter(entity); + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public void configure() { + register(new ZoneBorders(3116, 5412, 3362, 5584)); + /* top left */ + addLink(3158, 5561, 3162, 5557); + addLink(3162, 5545, 3166, 5553); + addLink(3147, 5541, 3143, 5535); + addLink(3148, 5533, 3153, 5537); + addLink(3152, 5520, 3156, 5523); + addLink(3165, 5515, 3173, 5530); + addLink(3169, 5510, 3159, 5501); + addLink(3181, 5517, 3185, 5518); + addLink(3182, 5530, 3187, 5531); + addLink(3190, 5519, 3190, 5515); + addLink(3196, 5512, 3202, 5515); + addLink(3197, 5529, 3201, 5531); + addLink(3190, 5549, 3190, 5554); + addLink(3180, 5557, 3174, 5558); + addLink(3171, 5542, 3168, 5541); + /* top middle */ + addLink(3206, 5553, 3204, 5546); + addLink(3226, 5553, 3230, 5547); + addLink(3214, 5533, 3211, 5533); + addLink(3208, 5527, 3211, 5523); + addLink(3238, 5507, 3232, 5501); + addLink(3241, 5529, 3243, 5526); + addLink(3261, 5536, 3268, 5534); + addLink(3252, 5543, 3249, 5546); + addLink(3262, 5552, 3266, 5552); + addLink(3256, 5561, 3253, 5561); + addLink(3297, 5536, 3299, 5533); + /* top right */ + addLink(3285, 5556, 3291, 5555); + addLink(3288, 5536, 3289, 5533); + addLink(3285, 5527, 3282, 5531); + addLink(3285, 5508, 3280, 5501); + addLink(3300, 5514, 3297, 5510); + addLink(3325, 5518, 3323, 5531); + addLink(3321, 5554, 3315, 5552); + /* bottom left */ + addLink(3142, 5489, 3141, 5480); + addLink(3142, 5462, 3154, 5462); + addLink(3143, 5443, 3155, 5449); + addLink(3167, 5478, 3171, 5478); + addLink(3171, 5473, 3167, 5471); + addLink(3168, 5456, 3178, 5460); + addLink(3187, 5460, 3189, 5444); + addLink(3192, 5472, 3186, 5472); + addLink(3185, 5478, 3191, 5482); + addLink(3197, 5448, 3204, 5445); + addLink(3191, 5482, 3185, 5478); + addLink(3191, 5495, 3194, 5490); + /* bottom middle */ + addLink(3214, 5456, 3212, 5452); + addLink(3229, 5454, 3235, 5457); + addLink(3233, 5445, 3241, 5445); + addLink(3239, 5498, 3244, 5495); + addLink(3233, 5470, 3241, 5469); + addLink(3241, 5445, 3233, 5445); + addLink(3259, 5446, 3265, 5491); + addLink(3260, 5491, 3266, 5446); + addLink(3218, 5478, 3215, 5475); + addLink(3208, 5471, 3210, 5477); + /* bottom right */ + addLink(3283, 5448, 3287, 5448); + addLink(3296, 5455, 3299, 5450); + addLink(3302, 5469, 3290, 5463); + addLink(3286, 5470, 3285, 5474); + addLink(3322, 5480, 3318, 5481); + addLink(3317, 5496, 3307, 5496); + addLink(3299, 5484, 3303, 5477); + addLink(3280, 5460, 3273, 5460); + addLink(3285, 5474, 3286, 5470); + addLink(3222, 5474, 3224, 5479); + addLink(3222, 5488, 3218, 5497); + } + + /** + * Teleports a player through a portal. + * @param object the object. + * @param player the player. + */ + private void teleport(Player player, Scenery object) { + if (object.getLocation().getX() == 3142 && object.getLocation().getY() == 5545) { + if (hasRequirement(player, Quests.WHAT_LIES_BELOW)) + commenceBorkBattle(player); + return; + } + Location loc = getLocation(object.getLocation()); + if (loc == null) { + player.sendMessage("Error! Unhandled portal for - " + object + "!"); + return; + } + if (!isFixed(player)) { + boolean stained = isStained(object); + if (!stained && RandomFunction.random(100) <= 3) { + stained = true; + setStainedTime(object); + } + if (stained) { + player.sendMessage("The portal is stained with dark magic."); + return; + } + if (RandomFunction.random(100) <= 3) { + loc = getRandomLocation(); + player.sendMessage("The dark magic teleports you into a random location."); + } + } + player.teleport(loc); + player.graphics(Graphics.create(110)); + } + + /** + * Starts the instanced battle against Bork. + * @param player The player. + */ + private void commenceBorkBattle(Player player) { + if (ServerStore.getBoolean(getStoreFile(), player.getUsername().toLowerCase(), false) && GameWorld.getSettings().isHosted()) { + player.getPacketDispatch().sendMessage("The portal's magic is too weak to teleport you right now."); + return; + } + player.lock(10); + player.graphics(Graphics.create(110)); + getStoreFile().put(player.getUsername().toLowerCase(), true); + ActivityManager.start(player, "Bork cutscene", false); + } + + /** + * Gets a random location. + * @return the location. + */ + private Location getRandomLocation() { + return (Location) RandomFunction.getRandomElement(PORTALS.values().toArray()); + } + + /** + * Checks if the object is stained. + * @param object the object. + * @return {@code True} if so. + */ + private boolean isStained(Scenery object) { + return getStainedTime(object) > GameWorld.getTicks(); + } + + /** + * Sets stained time. + * @param object the object. + */ + private void setStainedTime(Scenery object) { + object.getAttributes().setAttribute("stained", (int) GameWorld.getTicks() + RandomFunction.random(50, 150)); + } + + /** + * Gets the stained tiem. + * @param object the object. + * @return the time. + */ + private int getStainedTime(Scenery object) { + return object.getAttributes().getAttribute("stained", 0); + } + + /** + * Checks if the portals are fixed. + * @param player the player. + * @return {@code True} if so. + */ + private boolean isFixed(Player player) { + return false; + } + + /** + * Gets a location from the portal. + * @param location the location. + * @return the location. + */ + public Location getLocation(Location location) { + Location l = PORTALS.get(location); + if (l != null) { + return l; + } + for (Entry entry : PORTALS.entrySet()) { + if (entry.getValue().equals(location)) { + return entry.getKey(); + } + } + return null; + } + + /** + * Adds a portal link. + * @param x the x. + * @param y the x. + * @param x2 the second x. + * @param y2 the second y. + */ + private void addLink(int x, int y, int x2, int y2) { + addLink(new Location(x, y, 0), new Location(x2, y2, 0)); + } + + /** + * Adds a portal link. + * @param location the location. + * @param loc the second location. + */ + private void addLink(Location location, Location loc) { + PORTALS.put(location, loc); + } + + /** + * Returns the Server Store file for Bork being killed for the day + * @return The JSONObject containing the boolean of whether Bork has been killed + */ + private JSONObject getStoreFile() { + return ServerStore.getArchive("daily-bork-killed"); + } + +} diff --git a/Server/src/main/content/region/wilderness/handlers/CorpAreaController.kt b/Server/src/main/content/region/wilderness/handlers/CorpAreaController.kt new file mode 100644 index 0000000..265a60c --- /dev/null +++ b/Server/src/main/content/region/wilderness/handlers/CorpAreaController.kt @@ -0,0 +1,74 @@ +package content.region.wilderness.handlers + +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import content.global.skill.summoning.familiar.Familiar +import core.game.world.map.zone.ZoneBorders +import core.game.world.map.zone.ZoneRestriction +import core.tools.secondsToTicks + +class CorpAreaController : MapArea, TickListener { + companion object { + var activePlayers = ArrayList() + var corpBeast: NPC? = null + var borders = ZoneBorders(2974, 4369, 3007, 4400) + } + + override fun defineAreaBorders(): Array { + return arrayOf(borders) + } + + override fun getRestrictions(): Array { + return arrayOf(ZoneRestriction.GRAVES, ZoneRestriction.RANDOM_EVENTS) + } + + override fun areaEnter(entity: Entity) { + if (entity is Player) { + activePlayers.add(entity) + if(entity.familiarManager.hasFamiliar()) { + entity.familiarManager.familiar.call() + } + } + else if (entity is Familiar) { + entity.setAttribute("corp-time-remaining", secondsToTicks(10)) //Familiars last about 10 seconds, based on https://www.youtube.com/watch?v=kOd6q5Q5ZKI + } + else if (entity is NPC && entity.behavior is CorporealBeastNPC) { + corpBeast = entity + } + } + + override fun areaLeave(entity: Entity, logout: Boolean) { + if (entity is Player) { + activePlayers.remove(entity) + } + } + + override fun tick() { + if (activePlayers.size == 0) { + corpBeast?.let { + it.skills.lifepoints = it.skills.maximumLifepoints + val behavior = it.behavior as CorporealBeastNPC + if (behavior.darkEnergyCore != null) { + behavior.darkEnergyCore.clear() + behavior.darkEnergyCore = null + } + } + } + + if (corpBeast?.isActive == true && activePlayers.isNotEmpty()) { + for (player in activePlayers.toTypedArray()) { + val familiar = player.familiarManager.familiar ?: continue + val timeRemaining = getAttribute(familiar, "corp-time-remaining", -1) + if (timeRemaining == 0 && borders.insideBorder(familiar)) { + val healBy = familiar.skills.lifepoints / 4 + player.familiarManager.dismiss() + corpBeast?.skills?.heal(healBy) + sendMessage(familiar.owner, "The Beast devoured your familiar!") + } + setAttribute(familiar, "corp-time-remaining", timeRemaining - 1) + } + } + } +} diff --git a/Server/src/main/content/region/wilderness/handlers/CorporealBeastNPC.java b/Server/src/main/content/region/wilderness/handlers/CorporealBeastNPC.java new file mode 100644 index 0000000..67ad9c8 --- /dev/null +++ b/Server/src/main/content/region/wilderness/handlers/CorporealBeastNPC.java @@ -0,0 +1,302 @@ +package content.region.wilderness.handlers; + +import content.data.BossKillCounter; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.*; +import core.game.node.entity.combat.ImpactHandler.HitsplatType; +import core.game.node.entity.combat.equipment.SwitchAttack; +import core.game.node.entity.combat.equipment.Weapon; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.npc.NPCBehavior; +import core.game.node.entity.player.Player; +import core.game.node.entity.skill.Skills; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.tools.RandomFunction; +import org.rs09.consts.NPCs; + +import java.util.ArrayList; +import java.util.List; + +/** + * Handles the Corporeal beast NPC. + * @author Emperor + */ +@Initializable +public final class CorporealBeastNPC extends NPCBehavior { + + /** + * The combat handler. + */ + private final MultiSwingHandler combatHandler = new CombatHandler(); + + /** + * The dark energy core NPC. + */ + public NPC darkEnergyCore; + + /** + * Whether to force a dark core spawn roll on our next swing (only done if we just got hit >= 32 damage). + */ + public boolean forceCoreRoll = false; + + /** + * Constructs a new {@code CorporealBeastNPC} {@code Object}. + */ + public CorporealBeastNPC() { + super(new int[] { NPCs.CORPOREAL_BEAST_8133 }); + } + + @Override + public void onCreation(NPC self) { + self.configureBossData(); + } + + @Override + public CombatSwingHandler getSwingHandlerOverride(NPC self, CombatSwingHandler original) { + return combatHandler; + } + + @Override + public void beforeDamageReceived(NPC self, Entity attacker, BattleState state) { + if (state.getStyle() == CombatStyle.MELEE || state.getStyle() == CombatStyle.RANGE) { + Weapon w = state.getWeapon(); + String name = w != null ? w.getName() : ""; + if (w == null || name.toLowerCase().indexOf("spear") == -1) { + if (state.getEstimatedHit() > 0) { + state.setEstimatedHit(state.getEstimatedHit() / 2); + } + if (state.getSecondaryHit() > 0) { + state.setSecondaryHit(state.getSecondaryHit() / 2); + } + } + } + if (state.getEstimatedHit() >= 32) { + CorporealBeastNPC corp = (CorporealBeastNPC) self.behavior; + corp.forceCoreRoll = true; + } + if (state.getEstimatedHit() > 100) { + state.setEstimatedHit(100); + } + if (state.getSecondaryHit() > 100) { + state.setSecondaryHit(100); + } + } + + @Override + public void onDeathFinished(NPC self, Entity killer) { + BossKillCounter.addtoKillcount((Player) killer, NPCs.CORPOREAL_BEAST_8133); + if (darkEnergyCore != null) { + darkEnergyCore.clear(); + darkEnergyCore = null; + } + } + + /** + * Handles the Corporeal beast's combat. + * @author Emperor + */ + static class CombatHandler extends MultiSwingHandler { + + /** + * Constructs a new {@code CombatHandler} {@code Object}. + */ + public CombatHandler() { + super( + //Melee (crush) + new SwitchAttack(CombatStyle.MELEE.getSwingHandler(), Animation.create(10057)).setMaximumHit(51), + //Melee (slash) + new SwitchAttack(CombatStyle.MELEE.getSwingHandler(), Animation.create(10058)).setMaximumHit(51), + //Magic (drain skill, blocked by prayer) + new SwitchAttack(CombatStyle.MAGIC.getSwingHandler(), Animation.create(10410), null, null, Projectile.create(null, null, 1823, 60, 36, 41, 46)).setMaximumHit(55), + //Magic (location-based, hits through prayer) + new SwitchAttack(CombatStyle.MAGIC.getSwingHandler(), Animation.create(10410), null, null, Projectile.create(null, null, 1824, 60, 36, 41, 46)).setMaximumHit(42), + //Magic (hits through prayer) + new SwitchAttack(CombatStyle.MAGIC.getSwingHandler(), Animation.create(10410), null, null, Projectile.create(null, null, 1825, 60, 36, 41, 46)).setMaximumHit(65) + ); + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + // If we're below the right HP threshold, roll a chance to spawn the dark core + CorporealBeastNPC corp = (CorporealBeastNPC) ((NPC) entity).behavior; + double thresh = entity.getSkills().getMaximumLifepoints() * (0.3 + (entity.getViewport().getCurrentPlane().getPlayers().size() * 0.05)); + if (corp.forceCoreRoll || entity.getSkills().getLifepoints() < thresh) { + rollDarkCore(entity, corp, victim); + corp.forceCoreRoll = false; + } + // If we can stomp, do that for our turn + if (doStompAttack(entity)) { + entity.getProperties().getCombatPulse().setNextAttack(entity.getProperties().getAttackSpeed()); + return -1; + } + // Location-based attack. + if (super.getNext().getProjectile() != null && super.getNext().getProjectile().getProjectileId() == 1824) { + setCurrent(getNext()); + CombatStyle style = getCurrent().getStyle(); + setType(style); + int index = RandomFunction.randomize(super.getAttacks().length); + SwitchAttack pick = getNext(entity, victim, state, index); + setNext(pick); + fireLocationBasedAttack(entity, victim.getLocation()); + entity.getProperties().getCombatPulse().setNextAttack(entity.getProperties().getAttackSpeed()); + return -1; + } + return super.swing(entity, victim, state); + } + + /** + * Rolls a 1/8 chance to spawn a dark core. + * @param npc The corporeal beast NPC. + * @param victim The victim. + */ + private void rollDarkCore(Entity corp, final CorporealBeastNPC npc, Entity victim) { + if (npc.darkEnergyCore != null && npc.darkEnergyCore.isActive() && !DeathTask.isDead(npc.darkEnergyCore)) { + return; + } + if (!RandomFunction.roll(8)) { + return; + } + Location l = RegionManager.getTeleportLocation(victim.getLocation(), 3); + npc.darkEnergyCore = NPC.create(8127, l, corp); + npc.darkEnergyCore.setActive(true); + Projectile.create(corp.getLocation().transform(2, 2, 0), l, 1828, 60, 0, 0, 60, 20, 0).send(); + GameWorld.getPulser().submit(new Pulse(2, corp) { + @Override + public boolean pulse() { + if (npc.darkEnergyCore == null) + return true; + npc.darkEnergyCore.init(); + return true; + } + }); + } + + /** + * Fires the location based magic attack. + * @param entity The corporeal beast. + * @param location The location. + */ + private void fireLocationBasedAttack(final Entity entity, final Location location) { + entity.animate(getCurrent().getAnimation()); + Projectile.create(entity, null, 1824, 60, 0, 41, 0).transform(entity, location, true, 46, 10).send(); + int ticks = 1 + (int) Math.ceil(entity.getLocation().getDistance(location) * 0.5); + GameWorld.getPulser().submit(new Pulse(ticks) { + boolean secondStage = false; + List players = RegionManager.getLocalPlayers(entity); + Location[] locations = null; + + @Override + public boolean pulse() { + if (!secondStage) { + for (Player p : players) { + if (p.getLocation().equals(location)) { + hit(p); + } + } + locations = new Location[4 + RandomFunction.random(3)]; + for (int i = 0; i < locations.length; i++) { + locations[i] = location.transform(-2 + RandomFunction.random(5), -2 + RandomFunction.random(5), 0); + Projectile.create(location, locations[i], 1824, 60, 0, 25, 56, 0, 0).send(); + } + setDelay(2); + secondStage = true; + return false; + } + for (int i = 0; i < locations.length; i++) { + Location l = locations[i]; + Graphics.send(Graphics.create(1806), l.transform(-1, -1, 0)); + for (Player p : players) { + if (p.getLocation().equals(l)) { + hit(p); + } + } + } + players.clear(); + players = null; + locations = null; + return true; + } + + private void hit(Player p) { + int hit = 0; + if (isAccurateImpact(entity, p)) { + hit = RandomFunction.random(42); + if (p.hasProtectionPrayer(CombatStyle.MAGIC)) { + hit = (int) (hit * 0.6); + } + } + p.getImpactHandler().handleImpact(entity, hit, CombatStyle.MAGIC); + } + }); + } + + /** + * Attempts to do a stomp attack if needed. + * @param entity The corporeal beast. + * @return {@code True} if a stomp attack is being done. + */ + public boolean doStompAttack(Entity entity) { + Location l = entity.getLocation(); + List stompTargets = null; + for (Player player : RegionManager.getLocalPlayers(entity, 5)) { + Location p = player.getLocation(); + if (p.getX() >= l.getX() && p.getY() >= l.getY() && p.getX() < l.getX() + entity.size() && p.getY() < l.getY() + entity.size()) { + if (stompTargets == null) { + stompTargets = new ArrayList<>(20); + } + stompTargets.add(player); + } + } + if (stompTargets != null) { + entity.visualize(Animation.create(10496), Graphics.create(1834)); + for (Player p : stompTargets) { + p.getImpactHandler().manualHit(entity, RandomFunction.random(52), HitsplatType.NORMAL, 1); + } + return true; + } + return false; + } + + @Override + public void adjustBattleState(Entity entity, Entity victim, BattleState state) { + super.adjustBattleState(entity, victim, state); + if (getCurrent().getProjectile() != null && getCurrent().getProjectile().getProjectileId() == 1823) { + if (state.getEstimatedHit() > 0) { + int random = RandomFunction.random(3); + int skill = random == 0 ? Skills.PRAYER : random == 1 ? Skills.MAGIC : Skills.SUMMONING; + int drain = 1 + RandomFunction.random(6); + if ((skill == Skills.PRAYER ? victim.getSkills().getPrayerPoints() : victim.getSkills().getLevel(skill)) < 1) { + victim.getImpactHandler().manualHit(entity, drain, HitsplatType.NORMAL, 2); + ((Player) victim).getPacketDispatch().sendMessage("Your Hitpoints have been slightly drained!"); + } else { + if (skill == Skills.PRAYER) { + victim.getSkills().decrementPrayerPoints(drain); + } else { + victim.getSkills().updateLevel(skill, -drain, 0); + } + if (victim instanceof Player) { + ((Player) victim).getPacketDispatch().sendMessage("Your " + Skills.SKILL_NAME[skill] + " has been slightly drained!"); + } + } + } + } + } + + @Override + protected int getFormattedHit(Entity entity, Entity victim, BattleState state, int hit) { + if (getCurrent().getProjectile() == null || getCurrent().getProjectile().getProjectileId() != 1825) { + hit = (int) entity.getFormattedHit(state, hit); + } else if (victim.hasProtectionPrayer(CombatStyle.MAGIC)) { + hit = (int) (hit * 0.6); + } + return formatHit(victim, hit); + } + } +} diff --git a/Server/src/main/content/region/wilderness/handlers/CorporealBeastWarningInterface.kt b/Server/src/main/content/region/wilderness/handlers/CorporealBeastWarningInterface.kt new file mode 100644 index 0000000..5568d54 --- /dev/null +++ b/Server/src/main/content/region/wilderness/handlers/CorporealBeastWarningInterface.kt @@ -0,0 +1,40 @@ +package content.region.wilderness.handlers + +import core.game.component.Component +import core.game.node.entity.player.Player +import core.game.interaction.InterfaceListener +import core.game.world.GameWorld +import core.api.* +import content.data.Quests + +/** + * Handles the corporeal beast warning interface + * @author Ceikry + */ +class CorporealBeastWarningInterface : InterfaceListener { + + val COMPONENT_ID = 650 + + override fun defineInterfaceListeners() { + on(COMPONENT_ID,17){player,component,_,_,_,_ -> + if (!hasRequirement(player, Quests.SUMMERS_END)) + return@on true + if(player.getAttribute("corp-beast-cave-delay",0) <= GameWorld.ticks) { + player.properties.teleportLocation = player.location.transform(4, 0, 0).also { close(player,component) } + player.setAttribute("corp-beast-cave-delay", GameWorld.ticks + 5) + } else { + close(player,component) + } + return@on true + } + + on(COMPONENT_ID){player, component, _, _, _, _ -> + close(player,component) + return@on true + } + } + + fun close(player: Player,component: Component){ + player.interfaceManager.close(component) + } +} diff --git a/Server/src/main/content/region/wilderness/handlers/DarkEnergyCoreNPC.java b/Server/src/main/content/region/wilderness/handlers/DarkEnergyCoreNPC.java new file mode 100644 index 0000000..0695955 --- /dev/null +++ b/Server/src/main/content/region/wilderness/handlers/DarkEnergyCoreNPC.java @@ -0,0 +1,130 @@ +package content.region.wilderness.handlers; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.ImpactHandler.HitsplatType; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.path.Path; +import core.game.world.map.path.Pathfinder; +import core.plugin.Initializable; +import core.tools.RandomFunction; + +import static core.api.ContentAPIKt.*; + +/** + * Handles the Dark Energy Core NPC. + * @author Emperor, Player Name + */ +@Initializable +public final class DarkEnergyCoreNPC extends AbstractNPC { + + /** + * The corporeal beast. + */ + private NPC master; + + /** + * The amount of ticks. + */ + private int ticks = 0; + + /** + * The amount of failed attacks. + */ + private int fails = 0; + + /** + * Constructs a new {@code DarkEnergyCoreNPC} {@code Object}. + */ + public DarkEnergyCoreNPC() { + this(8127, null); + } + + /** + * Constructs a new {@code DarkEnergyCoreNPC} {@code Object}. + * + * @param id The NPC id. + * @param location The location. + */ + public DarkEnergyCoreNPC(int id, Location location) { + super(id, location, false); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + DarkEnergyCoreNPC core = new DarkEnergyCoreNPC(id, location); + if (objects.length > 0) { + core.master = (NPC) objects[0]; + } + core.setRespawn(false); + return core; + } + + @Override + public boolean canStartCombat(Entity victim) { + return false; //No combat needed. + } + + @Override + public void handleTickActions() { + ticks++; + boolean poisoned = isPoisoned(this); + if (isStunned(this) || isInvisible()) { + return; + } + if (fails == 0 && poisoned && (ticks % 100) != 0) { + return; + } + if (ticks % 2 == 0) { + boolean jump = true; + for (Player p : getViewport().getCurrentPlane().getPlayers()) { + if (p.getLocation().withinDistance(getLocation(), 1)) { + jump = false; + int hit = 5 + RandomFunction.random(6); + p.getImpactHandler().manualHit(master, hit, HitsplatType.NORMAL); + master.getSkills().heal(hit); + p.getPacketDispatch().sendMessage("The dark core creature steals some life from you for its master."); + } + } + if (jump) { + Entity victim = master.getProperties().getCombatPulse().getVictim(); + if (++fails >= 3 && victim != null && victim.getViewport().getCurrentPlane() == getViewport().getCurrentPlane()) { + Path path = Pathfinder.find(getLocation(), victim.getLocation(), 1); + if (path.isSuccessful() || !path.isMoveNear()) { + jump(victim.getLocation()); + fails = 0; + } + } + } else { + fails = 0; + } + } + } + + /** + * Handles jumping towards a new location. + * @param location The location. + */ + private void jump(final Location location) { + setInvisible(true); + Projectile.create(getLocation(), location, 1828, 0, 0, 0, 60, 20, 0).send(); + GameWorld.getPulser().submit(new Pulse(2, this) { + @Override + public boolean pulse() { + getProperties().setTeleportLocation(location); + setInvisible(false); + return true; + } + }); + } + + @Override + public int[] getIds() { + return new int[]{8127}; + } +} diff --git a/Server/src/main/content/region/wilderness/handlers/KingBlackDragonNPC.java b/Server/src/main/content/region/wilderness/handlers/KingBlackDragonNPC.java new file mode 100644 index 0000000..ab55596 --- /dev/null +++ b/Server/src/main/content/region/wilderness/handlers/KingBlackDragonNPC.java @@ -0,0 +1,245 @@ +package content.region.wilderness.handlers; + +import content.data.BossKillCounter; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.node.entity.combat.InteractionType; +import core.game.node.entity.combat.equipment.ArmourSet; +import core.game.node.entity.combat.equipment.FireType; +import content.global.handlers.item.equipment.special.DragonfireSwingHandler; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.tools.RandomFunction; + +import static core.api.ContentAPIKt.calculateDragonfireMaxHit; + +/** + * Represents the King Black Dragon NPC. + * @author Emperor + * @version 1.0 + */ +@Initializable +public final class KingBlackDragonNPC extends AbstractNPC { + + /** + * The default spawn location. + */ + private static final Location DEFAULT_SPAWN = Location.create(2273, 4698, 0); + + /** + * The combat swing handler. + */ + private CombatSwingHandler combatHandler = new KBDCombatSwingHandler(); + + + public KingBlackDragonNPC() { + super(-1,null); + } + + @Override + public void finalizeDeath(Entity killer) { + super.finalizeDeath(killer); + BossKillCounter.addtoKillcount((Player) killer, this.getId()); + } + + /** + * Constructs a new {@code KingBlackDragonNPC} {@code Object}. + * @param id the id. + * @param l the l. + */ + public KingBlackDragonNPC(int id, Location l) { + super(id, l); + } + + @Override + public void init() { + super.init(); + configureBossData(); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new KingBlackDragonNPC(id, location); + } + + @Override + public int getDragonfireProtection(boolean fire) { + return 0x2 | 0x4 | 0x8; + } + + @Override + public int[] getIds() { + return new int[] { 50 }; + } + + @Override + public CombatSwingHandler getSwingHandler(boolean swing) { + return combatHandler; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + return super.newInstance(arg); + } + + /** + * Handles the King Black Dragon's combat swings. + * @author Emperor + */ + static class KBDCombatSwingHandler extends CombatSwingHandler { + + /** + * The style. + */ + private CombatStyle style = CombatStyle.RANGE; + + /** + * Dragonfire. + */ + private static final DragonfireSwingHandler DRAGONFIRE = new DragonfireSwingHandler(false, 56, null, true); + + /** + * The melee attack animation. + */ + private static final Animation MELEE_ATTACK = new Animation(80, Priority.HIGH); + + /** + * The fire type. + */ + private FireType fireType = FireType.FIERY_BREATH; + + /** + * Constructs a new {@code KBDCombatSwingHandler} {@Code Object}. + */ + public KBDCombatSwingHandler() { + super(CombatStyle.RANGE); + } + + @Override + public void adjustBattleState(Entity entity, Entity victim, BattleState state) { + if (style == CombatStyle.RANGE) { + fireType.getTask().exec(victim, entity); + state.setStyle(null); + DRAGONFIRE.adjustBattleState(entity, victim, state); + state.setStyle(CombatStyle.RANGE); + return; + } + style.getSwingHandler().adjustBattleState(entity, victim, state); + } + + @Override + public int calculateAccuracy(Entity entity) { + if (style == CombatStyle.MELEE) { + return style.getSwingHandler().calculateAccuracy(entity); + } + return CombatStyle.MAGIC.getSwingHandler().calculateAccuracy(entity); + } + + @Override + public int calculateDefence(Entity victim, Entity attacker) { + if (style == CombatStyle.MELEE) { + return style.getSwingHandler().calculateDefence(victim, attacker); + } + return CombatStyle.MAGIC.getSwingHandler().calculateDefence(victim, attacker); + } + + @Override + public int calculateHit(Entity entity, Entity victim, double modifier) { + if (style == CombatStyle.MELEE) { + return style.getSwingHandler().calculateHit(entity, victim, modifier); + } + return calculateDragonfireMaxHit(victim, 56, false, fireType != FireType.FIERY_BREATH ? 10 : 0, true); + } + + @Override + public InteractionType canSwing(Entity entity, Entity victim) { + if (!isProjectileClipped(entity, victim, false)) { + return InteractionType.NO_INTERACT; + } + if (victim.getCenterLocation().withinMaxnormDistance(entity.getCenterLocation(), getCombatDistance(entity, victim, 9)) && super.canSwing(entity, victim) == InteractionType.STILL_INTERACT) { + entity.getWalkingQueue().reset(); + return InteractionType.STILL_INTERACT; + } + return InteractionType.NO_INTERACT; + } + + @Override + public ArmourSet getArmourSet(Entity e) { + return style.getSwingHandler().getArmourSet(e); + } + + @Override + public double getSetMultiplier(Entity e, int skillId) { + return style.getSwingHandler().getSetMultiplier(e, skillId); + } + + @Override + public void impact(Entity entity, Entity victim, BattleState state) { + style.getSwingHandler().impact(entity, victim, state); + } + + @Override + public int swing(Entity entity, Entity victim, BattleState state) { + style = CombatStyle.RANGE; + int hit = 0; + int ticks = 1; + if (victim.getCenterLocation().withinMaxnormDistance(entity.getCenterLocation(), getCombatDistance(entity, victim, 1)) && RandomFunction.random(10) < 7) { + style = CombatStyle.MELEE; + } else { + ticks += (int) Math.ceil(entity.getLocation().getDistance(victim.getLocation()) * 0.3); + } + fireType = FireType.values()[RandomFunction.random(FireType.values().length)]; + state.setStyle(style); + if (isAccurateImpact(entity, victim)) { + int max = calculateHit(entity, victim, 1.0); + state.setMaximumHit(max); + hit = RandomFunction.random(max + 1); + } + state.setEstimatedHit(hit); + ((NPC) entity).getAggressiveHandler().setPauseTicks(2); + return ticks; + } + + @Override + public void visualize(Entity entity, Entity victim, BattleState state) { + switch (style) { + case MELEE: + entity.animate(MELEE_ATTACK); + break; + case RANGE: + Projectile.ranged(entity, victim, fireType.getProjectileId(), 20, 36, 50, 15).send(); + entity.animate(fireType.getAnimation()); + break; + default: + break; + } + } + + @Override + public void visualizeImpact(Entity entity, Entity victim, BattleState state) { + if (style != CombatStyle.MELEE) { + DRAGONFIRE.visualizeImpact(entity, victim, state); + } else { + style.getSwingHandler().visualizeImpact(entity, victim, state); + } + } + + /** + * Gets the fire type. + * @return the type. + */ + public FireType getFireType() { + return fireType; + } + + } +} diff --git a/Server/src/main/content/region/wilderness/handlers/LavaMazePlugin.java b/Server/src/main/content/region/wilderness/handlers/LavaMazePlugin.java new file mode 100644 index 0000000..4af2240 --- /dev/null +++ b/Server/src/main/content/region/wilderness/handlers/LavaMazePlugin.java @@ -0,0 +1,48 @@ +package content.region.wilderness.handlers; + +import core.cache.def.impl.SceneryDefinition; +import core.game.global.action.ClimbActionHandler; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.world.map.Location; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Handles the lava maze. + * @author Vexia + */ +@Initializable +public final class LavaMazePlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(1767).getHandlers().put("option:climb-down", this); + SceneryDefinition.forId(1768).getHandlers().put("option:climb-up", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + switch (node.getId()) { + case 1767: + if (node.getLocation().getX() == 3069) { + ClimbActionHandler.climb(player, null, Location.create(3017, 10248, 0)); + return true; + } + ClimbActionHandler.climbLadder(player, (Scenery) node, option); + return true; + case 1768: + if (node.getLocation().getX() == 3017) { + ClimbActionHandler.climb(player, null, Location.create(3069, 3857, 0)); + return true; + } + ClimbActionHandler.climbLadder(player, (Scenery) node, option); + return true; + } + return true; + } + +} diff --git a/Server/src/main/content/region/wilderness/handlers/MuddyChestHandler.kt b/Server/src/main/content/region/wilderness/handlers/MuddyChestHandler.kt new file mode 100644 index 0000000..48000d5 --- /dev/null +++ b/Server/src/main/content/region/wilderness/handlers/MuddyChestHandler.kt @@ -0,0 +1,49 @@ +package content.region.wilderness.handlers + +import core.game.node.scenery.Scenery +import core.game.node.scenery.SceneryBuilder +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import core.game.world.update.flag.context.Animation +import org.rs09.consts.Items +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +/** + * Handles the muddy chest + * @author Ceikry + */ +class MuddyChestHandler : InteractionListener { + + private val CHEST = 170 + + override fun defineListeners() { + + on(CHEST, IntType.SCENERY, "open"){ player, node -> + val key = Item(Items.MUDDY_KEY_991) + if(player.inventory.containsItem(key)){ + player.inventory.remove(key) + player.animator.animate(Animation(536)) + SceneryBuilder.replace(node.asScenery(), Scenery(171, node.location, node.asScenery().rotation),3) + for(item in chestLoot){ + if(!player.inventory.add(item)) GroundItemManager.create(item,player) + } + } else { + player.sendMessage("This chest is locked and needs some sort of key.") + } + return@on true + } + + } + + val chestLoot = arrayOf( + Item(Items.UNCUT_RUBY_1619), + Item(Items.MITHRIL_BAR_2359), + Item(Items.MITHRIL_DAGGER_1209), + Item(Items.ANCHOVY_PIZZA_2297), + Item(Items.LAW_RUNE_563,2), + Item(Items.DEATH_RUNE_560,2), + Item(Items.CHAOS_RUNE_562,10), + Item(995,50) + ) +} \ No newline at end of file diff --git a/Server/src/main/content/region/wilderness/handlers/RoguesCastleListeners.kt b/Server/src/main/content/region/wilderness/handlers/RoguesCastleListeners.kt new file mode 100644 index 0000000..f2e1a50 --- /dev/null +++ b/Server/src/main/content/region/wilderness/handlers/RoguesCastleListeners.kt @@ -0,0 +1,144 @@ +package content.region.wilderness.handlers + +import core.api.* +import core.game.node.scenery.Scenery +import core.game.node.entity.combat.ImpactHandler +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.tools.RandomFunction +import org.rs09.consts.Items +import core.api.utils.WeightBasedTable +import core.api.utils.WeightedItem +import core.game.interaction.InteractionListener +import core.game.interaction.IntType + +class RoguesCastleListeners : InteractionListener { + + val CHEST_ANIM = getAnimation(536) + val FLOOR_1_CHESTS = intArrayOf(14773, 14774) + val FLOOR_2_CHESTS = intArrayOf(38834, 38835) + + override fun defineListeners() { + on(FLOOR_1_CHESTS, IntType.SCENERY, "open"){ player, node -> + val scenery = node.asScenery() + openChest(player, scenery) + return@on true + } + + on(FLOOR_1_CHESTS, IntType.SCENERY, "search"){ player, node -> + val scenery = node.asScenery() + if(getCharge(scenery) == 0){ + sendMessage(player, "This chest has already been looted.") + return@on true + } + + if(freeSlots(player) == 0){ + sendMessage(player, "You don't have enough space to do that.") + return@on true + } + + val item = FLOOR_1_LOOT.roll()[0] + addLoot(player, item) + setCharge(scenery, 0) + return@on true + } + + on(FLOOR_2_CHESTS, IntType.SCENERY, "open"){ player, node -> + sendMessage(player, "This chest appears to be locked.") + return@on true + } + + on(FLOOR_2_CHESTS, IntType.SCENERY, "pick-lock"){ player, node -> + val scenery = node.asScenery() + if(!inInventory(player, Items.LOCKPICK_1523)){ + sendMessage(player, "You need a lockpick in order to attempt this.") + return@on true + } + + if(!hasLevelDyn(player, Skills.THIEVING, 13)){ + sendMessage(player, "You need a Thieving level of 13 to attempt this.") + return@on true + } + + sendMessage(player, "You attempt to pick the lock on the chest...") + submitIndividualPulse(player, object : Pulse(2){ + override fun pulse(): Boolean { + val success = RandomFunction.roll(10) // 1/10 chance to succeed + if(success){ + replaceScenery(scenery, scenery.id + 1, 20) + rewardXP(player, Skills.THIEVING, 300.0) + } else { + val dealsDamage = RandomFunction.roll(10) // 1/10 chance to deal damage on a fail + if(dealsDamage) { + impact(player, RandomFunction.random(1, 3), ImpactHandler.HitsplatType.NORMAL) + sendMessage(player, "You activated a trap on the chest!") + } + } + + sendMessage(player, "You ${if(success) "manage" else "fail"} to pick the lock on the chest.") + return true + } + }) + + return@on true + } + + on(FLOOR_2_CHESTS, IntType.SCENERY, "search"){ player, node -> + val scenery = node.asScenery() + + if(getCharge(scenery) == 0){ + sendMessage(player, "This chest has already been looted.") + return@on true + } + + val loot = FLOOR_2_LOOT.roll()[0] + if(freeSlots(player) > 0){ + addItemOrDrop(player, loot.id, loot.amount) + sendMessage(player, "In the chest you find some ${loot.name.toLowerCase() + if(!loot.name.endsWith("s")) "s" else ""}!") + setCharge(scenery, 0) + rewardXP(player, Skills.THIEVING, 60.0) + } + + return@on true + } + } + + fun openChest(player: Player, scenery: Scenery){ + animate(player, CHEST_ANIM) + submitIndividualPulse(player, object : Pulse(animationDuration(CHEST_ANIM)){ + override fun pulse(): Boolean { + return true.also { replaceScenery(scenery, scenery.id + 1, 20) } + } + }) + } + + fun addLoot(player: Player, item: Item){ + sendMessage(player, "You search the chest...") + submitIndividualPulse(player, object : Pulse(){ + override fun pulse(): Boolean { + sendMessage(player, "... and find some ${item.name.toLowerCase() + if(!item.name.endsWith("s")) "s" else ""}!") + addItemOrDrop(player, item.id, item.amount) + return true + } + }) + } + + val FLOOR_1_LOOT = WeightBasedTable.create( + WeightedItem(Items.COINS_995, 8, 25, 70.0), + WeightedItem(Items.NATURE_RUNE_561, 2, 3, 10.0), + WeightedItem(Items.BLOOD_RUNE_565, 2, 3, 10.0), + WeightedItem(Items.DEATH_RUNE_560, 3, 5, 10.0) + ) + + val FLOOR_2_LOOT = WeightBasedTable.create( + WeightedItem(Items.COINS_995, 4, 57, 75.0), + WeightedItem(Items.COINS_995, 107, 243, 5.0), + WeightedItem(Items.BLOOD_RUNE_565, 2, 5, 5.0), + WeightedItem(Items.GOLD_ORE_445, 1, 1, 5.0), + WeightedItem(Items.STEEL_MED_HELM_1141, 1, 1, 5.0), + WeightedItem(Items.STEEL_PLATELEGS_1069, 1, 1, 5.0) + ) + +} \ No newline at end of file diff --git a/Server/src/main/content/region/wilderness/handlers/WildernessAreaZone.java b/Server/src/main/content/region/wilderness/handlers/WildernessAreaZone.java new file mode 100644 index 0000000..acf3727 --- /dev/null +++ b/Server/src/main/content/region/wilderness/handlers/WildernessAreaZone.java @@ -0,0 +1,575 @@ +package content.region.wilderness.handlers; + +import core.game.dialogue.DialogueAction; +import core.game.dialogue.DialoguePlugin; +import core.game.dialogue.FacialExpression; +import core.game.global.action.DoorActionHandler; +import core.game.node.entity.skill.SkillPulse; +import core.game.node.entity.skill.Skills; +import content.global.skill.gather.SkillingResource; +import content.data.skill.SkillingTool; +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.Option; +import core.game.interaction.UseWithHandler; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneBuilder; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.plugin.ClassScanner; + +import java.util.ArrayList; +import java.util.List; + +/** + * Handles the Wilderness Area Zone. + * @author Empathy + * @author Vexia + * + */ +@Initializable +public class WildernessAreaZone extends MapZone implements Plugin { + + /** + * The list of players in the arena. + */ + private final List players = new ArrayList<>(20); + + /** + * Constructs a new {@code WildernessAreaZone} {@code Object} + */ + public WildernessAreaZone() { + super("Wilderness Area Zone", true); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ZoneBuilder.configure(this); + ClassScanner.definePlugins(new MandrithDialoguePlugin(), new PilesDialoguePlugin(), new PilesItemHandler(), new RuniteGolemNPC()); + return this; + } + + @Override + public boolean interact(Entity e, final Node node, Option option) { + if (e instanceof Player) { + Player player = e.asPlayer(); + switch (node.getId()) { + case 42044: + switch (option.getName()) { + case "Open": + if (player.getLocation().equals(Location.create(3184, 3945, 0))) { + if (player.getInventory().contains(995, 7500)) { + player.getDialogueInterpreter().sendOptions("Pay 7500 coins?", "Yes", "No"); + player.getDialogueInterpreter().addAction(new DialogueAction() { + + @Override + public void handle(Player player, int buttonId) { + switch (buttonId) { + case 2: + if (player.getInventory().remove(new Item(995, 7500))) { + DoorActionHandler.handleDoor(player, node.asScenery()); + player.sendMessage("You pay 7500 coins and enter the resource arena."); + } + break; + } + } + + }); + return true; + } + player.sendMessage("You do not have enough coins to enter the Arena."); + return true; + } + DoorActionHandler.handleDoor(player, node.asScenery()); + return true; + case "Players-inside": + if (player.getLocation().getY() < 3495) { + player.sendMessage("All you see is the barren wasteland of the Wilderness."); + return true; + } + String message = "You peek inside the gate and see no adventurers inside the arena."; + if (players.size() > 0) { + message = players.size() == 1 ? "You peek inside the gate and see 1 adventurer inside the arena." : "You peek inside the gate and see " + players.size() + " inside the arena."; + } + player.getDialogueInterpreter().sendDialogue(message); + break; + } + break; + case 8666: + switch (option.getName()) { + case "Mine": + player.getPulseManager().run(new RuniteGolemMinePulse(player, node.asNpc())); + return true; + case "Prospect": + player.sendMessages("You examine the rock for ores...", "This rock contains runite ore."); + return true; + } + break; + } + } + return super.interact(e, node, option); + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public void configure() { + register(new ZoneBorders(3174, 3924, 3196, 3945)); + } + + @Override + public boolean enter(Entity e) { + if (e instanceof Player) { + Player p = e.asPlayer(); + players.add(p); + } + return super.enter(e); + } + + @SuppressWarnings("deprecation") + @Override + public boolean leave(Entity e, boolean logout) { + if (e instanceof Player) { + Player p = e.asPlayer(); + players.remove(p); + if (logout && p.getLocation().getY() <= 3944) { + p.setLocation(Location.create(3184, 3945, 0)); + return true; + } + } + return super.leave(e, logout); + } + + /** + * The mining of a runite golem. + * @author Vexia + * + */ + public class RuniteGolemMinePulse extends SkillPulse { + + /** + * The skilling tool used. + */ + private SkillingTool tool; + + /** + * The ticks. + */ + private int ticks; + + /** + * Constructs a new @{Code RuniteGolemMinePulse} object. + * @param player The player. + * @param node The node. + */ + public RuniteGolemMinePulse(Player player, NPC node) { + super(player, node); + } + + @Override + public void start() { + resource = SkillingResource.RUNITE_ORE_0; + if (node.getId() != 8666) { + player.getPacketDispatch().sendMessage("This rock contains no ore."); + return; + } + if (resource == null) { + return; + } + super.start(); + } + + + @Override + public boolean checkRequirements() { + if (node.getId() != 8666) { + return false; + } + if (player.getSkills().getLevel(resource.getSkillId()) < resource.getLevel()) { + player.getPacketDispatch().sendMessage("You need a " + Skills.SKILL_NAME[resource.getSkillId()] + " level of " + resource.getLevel() + " to mine this rock."); + return false; + } + if ((tool = SkillingTool.getPickaxe(player)) == null) { + player.getPacketDispatch().sendMessage("You do not have a pickaxe to use."); + return false; + } + if (player.getInventory().freeSlots() < 1) { + player.getDialogueInterpreter().sendDialogue("Your inventory is too full to hold any more runite ore."); + return false; + } + return true; + } + + @Override + public void animate() { + if (tool != null) { + player.animate(tool.getAnimation()); + } + } + + @Override + public boolean reward() { + if (++ticks % 4 != 0) { + return false; + } + if (!checkReward()) { + return false; + } + node.transform(8667); + node.setAttribute("reward-tick", GameWorld.getTicks() + resource.getRespawnDuration()); + final Item item = new Item(resource.getReward()); + player.getInventory().add(item); + player.getSkills().addExperience(resource.getSkillId(), resource.getExperience(), true); + return true; + } + + /** + * Checks if the player gets rewarded. + * @return {@code True} if so. + */ + private boolean checkReward() { + int skill = Skills.MINING; + int level = 1 + player.getSkills().getLevel(skill) + player.getFamiliarManager().getBoost(skill); + double hostRatio = Math.random() * (100.0 * resource.getRate()); + double clientRatio = Math.random() * ((level - resource.getLevel()) * (1.0 + tool.getRatio())); + return hostRatio < clientRatio; + } + } + + /** + * Handles the runite golem npc. + * @author Vexia + * + */ + public class RuniteGolemNPC extends AbstractNPC { + + /** + * The respawn time. + */ + private int respawn = -1; + + /** + * Constructs a new @{Code RuniteGolemNPC} object. + * @param id The npc id. + * @param location The location. + */ + public RuniteGolemNPC(int id, Location location) { + super(id, location); + } + + /** + * Constructs a new @{Code RuniteGolemNPC} object. + */ + public RuniteGolemNPC() { + super(-1, null); + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new RuniteGolemNPC(id, location); + } + + @Override + public void init() { + super.init(); + setAggressive(false); + } + + @Override + public void sendImpact(BattleState state) { + super.sendImpact(state); + if (state.getEstimatedHit() > 16) { + state.setEstimatedHit(16); + } + } + + @Override + public void handleTickActions() { + super.handleTickActions(); + if (isAggressive()) { + setAggressive(false); + } + if (respawn != -1 && respawn < GameWorld.getTicks() && getId() > 8664) { + transform(8664); + unlock(); + } + if (getId() == 8667) { + int rewardTick = getAttribute("reward-tick", -1); + if (rewardTick != -1 && rewardTick < GameWorld.getTicks()) { + transform(8666); + } + } + } + + @Override + public void finalizeDeath(Entity killer) { + respawn = GameWorld.getTicks() + 500; + fullRestore(); + getProperties().setTeleportLocation(getLocation()); + setRespawnTick(0); + setInvisible(false); + transform(8666); + lock(); + faceLocation(null); + face(null); + } + + @Override + public int[] getIds() { + return new int[] {8664}; + } + + + } + + /** + * Handles the item on piles interaction. + * @author Vexia + * + */ + public static class PilesItemHandler extends UseWithHandler { + + /** + * The allowed items for piles. + */ + private static final int[] ALLOWED = new int[] {14937, 14939, 449, 447, 440, 444, 453, 451, 1515, 1513, 2349, 9467,2351,2355,2353,2357,2359,2361,2363}; + + /** + * Constructs a new @{Code PilesItemHandler} object. + */ + public PilesItemHandler() { + super(); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + addHandler(8663, NPC_TYPE, this); + return this; + } + + @Override + public boolean handle(final NodeUsageEvent event) { + final Player player = event.getPlayer(); + for (int itemId : ALLOWED) { + if (event.getUsedItem().getId() == itemId) { + final int amount = player.getInventory().getAmount(itemId); + final int price = 50 * amount; + if (!player.getInventory().contains(995, price)) { + player.getDialogueInterpreter().sendDialogues(8663, FacialExpression.OLD_NORMAL, "I'll need 50 coins per item."); + return true; + } + player.getDialogueInterpreter().sendOptions("Banknote " + amount + " x " + event.getUsedItem().getName() + "?", "Yes - " + price + " gp", "Cancel"); + player.getDialogueInterpreter().addAction((player1, buttonId) -> { + if (player1.getInventory().remove(new Item(995, price)) && player1.getInventory().remove(new Item(event.getUsedItem().getId(), amount))) { + player1.getInventory().add(new Item(event.getUsedItem().getNoteChange(), amount)); + player1.getDialogueInterpreter().sendItemMessage(event.getUsedItem().getId(), "Piles converts your items to banknotes."); + } + }); + return true; + } + } + player.getDialogueInterpreter().sendDialogues(8663, FacialExpression.OLD_NORMAL, "Sorry, I wasn't expecting anyone to want to convert", "that sort of item, so I haven't any banknotes for it."); + return true; + } + + @Override + public boolean isDynamic() { + return true; + } + } + + /** + * Handles the Piles dialogue. + * @author Vexia + * + */ + public class PilesDialoguePlugin extends DialoguePlugin { + + /** + * Constructs a new @{Code PilesDialoguePlugin} object. + */ + public PilesDialoguePlugin() { + /* + * empty. + */ + } + + /** + * Constructs a new @{Code PilesDialoguePlugin} object. + * @param player The player. + */ + public PilesDialoguePlugin(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new PilesDialoguePlugin(player); + } + + @Override + public boolean open(Object... args) { + npc("Hello. I can convert items to banknotes, for 50 coins", "per item. Just hand me the items you'd like me to", "convert."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + options("Who are you?", "Thanks."); + stage++; + break; + case 1: + switch (buttonId) { + case 1: + player("Who are you?"); + stage = 10; + break; + case 2: + player("Thanks."); + stage = 2; + break; + } + break; + case 2: + end(); + break; + case 10: + npc("I'm Piles. I lived in Draynor Village when I was", "young, where I saw three men working in the market,", "converting items to banknotes."); + stage++; + break; + case 11: + npc("Their names were Niles, Miles and Giles. I'm trying to", "be like them, so I've changed my name and started this", "business here."); + stage++; + break; + case 12: + player("Thanks."); + stage = 2; + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] {8663}; + } + + } + + /** + * Handles the Mandrith dialogue. + * @author Empathy + * + */ + public class MandrithDialoguePlugin extends DialoguePlugin { + + /** + * + * Constructs a new @{Code MandrithDialoguePlugin} object. + */ + public MandrithDialoguePlugin() { + /* + * empty + */ + } + + /** + * + * Constructs a new @{Code MandrithDialoguePlugin} object. + * @param player + */ + public MandrithDialoguePlugin(Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new MandrithDialoguePlugin(player); + } + + @Override + public boolean open(Object... args) { + player("Who are you and what is this place?" ); + stage = 1; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 1: + npc("My name is Mandrith." ); + stage = 2; + break; + case 2: + npc("I collect valuable resources and pawn off access to them", "to foolish adventurers, like yourself" ); + stage = 3; + break; + case 3: + npc("You should take a look inside my arena. There's an", "abundance of valuable resources inside." ); + stage = 4; + break; + case 4: + player("And I can take whatever I want?" ); + stage = 5; + break; + case 5: + npc("It's all yours. All I ask is that you pay the upfront fee." ); + stage = 6; + break; + case 6: + player("Will others be able to kill me inside?" ); + stage = 7; + break; + case 7: + npc("Yes. These walls will only hold them back for so long." ); + stage = 8; + break; + case 8: + player("You'll stop them though, right?" ); + stage = 9; + break; + case 9: + npc("Haha! For the right price, I won't deny anyone access", "to my arena. Even if their intention is to kill you." ); + stage = 10; + break; + case 10: + player("Right..." ); + stage = 11; + break; + case 11: + npc("My arena holds many treasure that I've acquired at", "great expense, adventurer. Their bounty can come at a", "price." ); + stage = 12; + break; + case 12: + npc("One day, adventurer, I will boast ownership of a much", "larger, much more dangerous arena than this. Take", "advantage of this offer while it lasts." ); + stage = 13; + break; + case 13: + end(); + break; + } + return false; + } + + @Override + public int[] getIds() { + return new int[] { 8662 }; + } + } +} diff --git a/Server/src/main/content/region/wilderness/handlers/WildernessDitchPlugin.java b/Server/src/main/content/region/wilderness/handlers/WildernessDitchPlugin.java new file mode 100644 index 0000000..20b1c87 --- /dev/null +++ b/Server/src/main/content/region/wilderness/handlers/WildernessDitchPlugin.java @@ -0,0 +1,80 @@ +package content.region.wilderness.handlers; + +import core.cache.def.impl.SceneryDefinition; +import core.game.component.Component; +import core.game.interaction.MovementPulse; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.impl.PulseType; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.plugin.ClassScanner; + +/** + * Represents the plugin to handle the crossing. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class WildernessDitchPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(23271).getHandlers().put("option:cross", this); + ClassScanner.definePlugin(new WildernessInterfacePlugin()); + return this; + } + + @Override + public boolean handle(final Player player, final Node node, String option) { + if (player.getLocation().getDistance(node.getLocation()) < 3) { + handleDitch(player, node); + } else { + player.getPulseManager().run(new MovementPulse(player, node) { + @Override + public boolean pulse() { + handleDitch(player, node); + return true; + } + }, PulseType.STANDARD); + } + return true; + } + + /** + * Handles the wilderness ditch jumping. + * @param player The player. + * @param node The ditch object. + */ + public void handleDitch(final Player player, Node node) { + player.faceLocation(node.getLocation()); + Scenery ditch = (Scenery) node; + player.setAttribute("wildy_ditch", ditch); + /* + + Comment out the annoying ditch warning until the doomsayer has been implemented so that players can disable it properly. + + if(!player.isArtificial()) { + if (ditch.getRotation() % 2 == 0) { + if (player.getLocation().getY() <= node.getLocation().getY()) { + player.getInterfaceManager().open(new Component(382)); + return; + } + } else { + if (player.getLocation().getX() > node.getLocation().getX()) { + player.getInterfaceManager().open(new Component(382)); + return; + } + } + } + */ + WildernessInterfacePlugin.handleDitch(player); + } + + @Override + public boolean isWalk() { + return true; + } +} diff --git a/Server/src/main/content/region/wilderness/handlers/WildernessGateHandler.kt b/Server/src/main/content/region/wilderness/handlers/WildernessGateHandler.kt new file mode 100644 index 0000000..2f0ed6a --- /dev/null +++ b/Server/src/main/content/region/wilderness/handlers/WildernessGateHandler.kt @@ -0,0 +1,73 @@ +package content.region.wilderness.handlers + +import content.region.wilderness.handlers.WildernessGateHandler.GateDialogue +import core.ServerConstants +import core.api.* +import core.game.interaction.* +import core.game.node.entity.player.Player +import core.game.node.Node +import core.game.global.action.DoorActionHandler +import core.game.dialogue.* +import core.tools.* + +class WildernessGateHandler : InteractionListener { + val gates = intArrayOf(1597, 1596) + + override fun defineListeners() { + on (gates, IntType.SCENERY, "open", handler = ::handleGate) + } + + private fun handleGate(player: Player, node: Node) : Boolean { + if (player.location.y > 3890 && ServerConstants.ENHANCED_DEEP_WILDERNESS) { + val isEntering = !player.skullManager.isDeepWilderness + if (isEntering) { + fun enter(player: Player) { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + player.skullManager.isDeepWilderness = true + } + enterDeepWilderness(player, ::enter, "Beyond this gate you enter the deep wilderness!") + } else { + if (player.properties.combatPulse.isInCombat) { + sendMessage(player, "You cannot leave while you are under attack.") + } else { + DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + player.skullManager.isDeepWilderness = false + } + } + } else DoorActionHandler.handleAutowalkDoor(player, node.asScenery()) + + return true + } + + class GateDialogue(val callback: (Player) -> Unit, val firstLine: String) : DialogueFile() { + override fun handle (interfaceId: Int, buttonId: Int) { + when (stage) { + 0 -> sendDialogueLines(player!!, "WARNING!", firstLine, "Anyone will be able to attack you without consequence!", "You WILL NOT be able to leave during combat!").also { stage++ } + 1 -> sendDialogueLines(player!!, "While you are there, you will be skulled:","you will lose all your items if you die!","The skull will go away when you leave the deep wilderness.").also { stage++ } + 2 -> sendDialogueLines(player!!, "If you are risking sufficient value, the skull will become red.","This increases your chances of receiving special loot from killing","revenants and the Chaos Elemental!").also { stage++ } + 3 -> showTopics( + Topic(FacialExpression.NEUTRAL, "I wish to proceed.", 10, true), + Topic(FacialExpression.NEUTRAL, "I wish to proceed, and don't show this warning again.", 11, true), + Topic(FacialExpression.NEUTRAL, "Never mind.", END_DIALOGUE, true) + ) + 10 -> { + end() + callback(player!!) + } + 11 -> { + player!!.setAttribute("/save:skip-deep-wilderness-warning", true) + end() + callback(player!!) + } + } + } + } +} + +fun enterDeepWilderness(player: Player, callback: (Player) -> Unit, firstLine: String) { + if (player.getAttribute("/save:skip-deep-wilderness-warning",false)) { + callback(player) + } else { + openDialogue(player, GateDialogue(callback, firstLine)) + } +} diff --git a/Server/src/main/content/region/wilderness/handlers/WildernessInterfacePlugin.java b/Server/src/main/content/region/wilderness/handlers/WildernessInterfacePlugin.java new file mode 100644 index 0000000..6500ccf --- /dev/null +++ b/Server/src/main/content/region/wilderness/handlers/WildernessInterfacePlugin.java @@ -0,0 +1,111 @@ +package content.region.wilderness.handlers; + +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.ComponentPlugin; +import core.game.global.action.DoorActionHandler; +import core.game.node.Node; +import core.game.node.entity.impl.ForceMovement; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.audio.Audio; +import core.game.node.scenery.Scenery; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playAudio; + +/** + * Represents the wilderness interface plugin. + * @author Emperor + * @version 1.0 + */ +public final class WildernessInterfacePlugin extends ComponentPlugin { + + /** + * The animation. + */ + private static final Animation ANIMATION = Animation.create(6132); + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ComponentDefinition.put(382, this); + return this; + } + + @Override + public boolean handle(Player player, Component component, int opcode, int button, int slot, int itemId) { + player.getInterfaceManager().close(); + if (button != 18) { + return true; + } + if (player.getAttribute("wildy_ditch") != null) + handleDitch(player); + else if(player.getAttribute("wildy_gate") != null) + handleGate(player); + return true; + } + + /** + * Method used to handle the ditch interface. + * @param player the player. + */ + public static void handleDitch(final Player player) { + Scenery ditch = player.getAttribute("wildy_ditch"); + player.removeAttribute("wildy_ditch"); + Location l = ditch.getLocation(); + int x = player.getLocation().getX(); + int y = player.getLocation().getY(); + if (ditch.getRotation() % 2 == 0) { + if (y <= l.getY()) { + ForceMovement.run(player, Location.create(x, l.getY() - 1, 0), Location.create(x, l.getY() + 2, 0), ANIMATION, 20).setEndAnimation(null); + } else { + ForceMovement.run(player, Location.create(x, l.getY() + 2, 0), Location.create(x, l.getY() - 1, 0), ANIMATION, 20).setEndAnimation(null); + } + } else { + if (x > l.getX()) { + ForceMovement.run(player, Location.create(l.getX() + 2, y, 0), Location.create(l.getX() - 1, y, 0), ANIMATION, 20).setEndAnimation(null); + } else { + ForceMovement.run(player, Location.create(l.getX() - 1, y, 0), Location.create(l.getX() + 2, y, 0), ANIMATION, 20).setEndAnimation(null); + } + } + playAudio(player, Sounds.JUMP2_2462, 30); + /*if (GameWorld.getSettings().isPvp()) { + ActivityManager.register(new BountyHunterActivity(CraterType.MID_LEVEL)); + ActivityManager.register(new BountyHunterActivity(CraterType.HIGH_LEVEL)); + }*/ + } + public static void handleBotDitch(final Player player, Node node) { + Scenery ditch = node.asScenery(); + player.removeAttribute("wildy_ditch"); + Location l = ditch.getLocation(); + int x = player.getLocation().getX(); + int y = player.getLocation().getY(); + if (ditch.getRotation() % 2 == 0) { + if (y <= l.getY()) { + ForceMovement.run(player, Location.create(x, l.getY() - 1, 0), Location.create(x, l.getY() + 2, 0), ANIMATION, 20).setEndAnimation(null); + } else { + ForceMovement.run(player, Location.create(x, l.getY() + 2, 0), Location.create(x, l.getY() - 1, 0), ANIMATION, 20).setEndAnimation(null); + } + } else { + if (x > l.getX()) { + ForceMovement.run(player, Location.create(l.getX() + 2, y, 0), Location.create(l.getX() - 1, y, 0), ANIMATION, 20).setEndAnimation(null); + } else { + ForceMovement.run(player, Location.create(l.getX() - 1, y, 0), Location.create(l.getX() + 2, y, 0), ANIMATION, 20).setEndAnimation(null); + } + } + playAudio(player, Sounds.JUMP2_2462, 30); + /*if (GameWorld.getSettings().isPvp()) { + ActivityManager.register(new BountyHunterActivity(CraterType.MID_LEVEL)); + ActivityManager.register(new BountyHunterActivity(CraterType.HIGH_LEVEL)); + }*/ + } + public static void handleGate(final Player player){ + Scenery gate = player.getAttribute("wildy_gate"); + // Cleanup + player.removeAttribute("wildy_gate"); + // Move player through gate/door + DoorActionHandler.handleAutowalkDoor(player,gate); + } +} diff --git a/Server/src/main/content/region/wilderness/handlers/WildernessObeliskPlugin.java b/Server/src/main/content/region/wilderness/handlers/WildernessObeliskPlugin.java new file mode 100644 index 0000000..267a5b8 --- /dev/null +++ b/Server/src/main/content/region/wilderness/handlers/WildernessObeliskPlugin.java @@ -0,0 +1,168 @@ +package content.region.wilderness.handlers; + +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.TeleportManager.TeleportType; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.chunk.GraphicUpdateFlag; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Initializable; +import core.plugin.Plugin; +import core.tools.RandomFunction; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playAudio; + +/** + * Represents the wilderness obelisk plugin. + * @author 'Vexia + * @author Player Name + * @version 1.2 + */ +@Initializable +public final class WildernessObeliskPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(14829).getHandlers().put("option:activate", this); + SceneryDefinition.forId(14826).getHandlers().put("option:activate", this); + SceneryDefinition.forId(14827).getHandlers().put("option:activate", this); + SceneryDefinition.forId(14828).getHandlers().put("option:activate", this); + SceneryDefinition.forId(14830).getHandlers().put("option:activate", this); + SceneryDefinition.forId(14831).getHandlers().put("option:activate", this); + return this; + } + + @Override + public boolean handle(final Player player, final Node node, String option) { + final Scenery nodeObject = (Scenery) node; + final Obelisk stationObelisk = Obelisk.forLocation(player.getLocation()); + if (stationObelisk == null) { + return false; + } + if (player.getSkullManager().isDeepWilderness()) { + if (player.getProperties().getCombatPulse().isInCombat()) { + player.sendMessage("You can't use this while in combat."); + return false; + } + } + for (int i = 0; i < 4; i++) { + int x = stationObelisk.getLocation().getX(); + int y = stationObelisk.getLocation().getY(); + int z = stationObelisk.getLocation().getZ(); + switch (i) { + case 0: + x = x + 2; + y = y + 2; + SceneryBuilder.replace(new Scenery(nodeObject.getId(), Location.create(x, y, z)), new Scenery(14825, Location.create(x, y, 0)), 6); + break; + case 1: + x = x - 2; + y = y + 2; + SceneryBuilder.replace(new Scenery(nodeObject.getId(), Location.create(x, y, z)), new Scenery(14825, Location.create(x, y, 0)), 6); + break; + case 2: + x = x - 2; + y = y - 2; + SceneryBuilder.replace(new Scenery(nodeObject.getId(), Location.create(x, y, z)), new Scenery(14825, Location.create(x, y, 0)), 6); + break; + case 3: + x = x + 2; + y = y - 2; + SceneryBuilder.replace(new Scenery(nodeObject.getId(), Location.create(x, y, z)), new Scenery(14825, Location.create(x, y, 0)), 6); + break; + } + } + playAudio(player, Sounds.WILDERNESS_TELEPORT_204); + GameWorld.getPulser().submit(new Pulse(6, player) { + @Override + public boolean pulse() { + final Location center = stationObelisk.getLocation(); + if (getDelay() == 1) { + for (int x = center.getX() - 1; x <= center.getX() + 1; x++) { + for (int y = center.getY() - 1; y <= center.getY() + 1; y++) { + Location l = Location.create(x, y, 0); + RegionManager.getRegionChunk(l).flag(new GraphicUpdateFlag(Graphics.create(342), l)); + } + } + return true; + } + // Determine new obelisk + Obelisk[] newObelisks = Obelisk.values(); + for (int i = 0; i < newObelisks.length; i++) { + // Find our current obelisk and remove it from the candidate set by replacing it with the last obelisk + if (newObelisks[i] == stationObelisk) { + newObelisks[i] = newObelisks[newObelisks.length - 1]; + break; + } + } + int index = RandomFunction.random(0, newObelisks.length - 1); //cutting out the last one that is now duplicated + Obelisk newObelisk = newObelisks[index]; + // Teleport players standing within a 3-by-3 bounding box + for (Player player : RegionManager.getLocalPlayersBoundingBox(center, 1, 1)) { + if (player.timers.getTimer("teleblock") == null) { + player.getPacketDispatch().sendMessage("Ancient magic teleports you somewhere in the wilderness."); + int xOffset = player.getLocation().getX() - center.getX(); + int yOffset = player.getLocation().getY() - center.getY(); + player.getTeleporter().send(Location.create(newObelisk.getLocation().getX() + xOffset, newObelisk.getLocation().getY() + yOffset, 0), TeleportType.OBELISK, 2); + } else { + player.getPacketDispatch().sendMessage("A magical force has stopped you from teleporting."); + } + } + super.setDelay(1); + return false; + } + + }); + return true; + } + + /** + * Represents an obelisk type. + * @author 'Vexia + * @version 1.0 + */ + public enum Obelisk { + LEVEL_13(new Location(3156, 3620, 0)), LEVEL_19(new Location(3219, 3656, 0)), LEVEL_27(new Location(3035, 3732, 0)), LEVEL_35(new Location(3106, 3794, 0)), LEVEL_44(new Location(2980, 3866, 0)), LEVEL_50(new Location(3307, 3916, 0)); + + /** + * Represents the location to teleport to. + */ + private Location location; + + /** + * Constructs a new {@code Obelisk} {@code Object}. + * @param location the location. + */ + Obelisk(Location location) { + this.location = location; + } + + /** + * Gets the location. + * @return the location + */ + public Location getLocation() { + return location; + } + + /** + * Gets the obelisk by location. + * @param location the location. + * @return the obelisk. + */ + public static Obelisk forLocation(Location location) { + for (Obelisk obelisk : Obelisk.values()) + if (obelisk.getLocation().getDistance(location) <= 20) + return obelisk; + return null; + } + } +} diff --git a/Server/src/main/content/region/wilderness/handlers/WildernessPlugin.java b/Server/src/main/content/region/wilderness/handlers/WildernessPlugin.java new file mode 100644 index 0000000..26bb09c --- /dev/null +++ b/Server/src/main/content/region/wilderness/handlers/WildernessPlugin.java @@ -0,0 +1,162 @@ +package content.region.wilderness.handlers; + +import core.cache.def.impl.SceneryDefinition; +import core.game.component.Component; +import core.game.global.action.ClimbActionHandler; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.TeleportManager; +import core.game.node.entity.player.link.TeleportManager.TeleportType; +import core.game.node.scenery.Scenery; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.plugin.Plugin; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.*; +import content.data.Quests; + +/** + * Represents a plugin used to handle wilderness nodes. + * + * @author 'Vexia + * @author Splinter + * @version 1.0 + */ +@Initializable +public final class WildernessPlugin extends OptionHandler { + + @Override + public Plugin newInstance(Object arg) throws Throwable { + new KBDPlugin().newInstance(arg); + SceneryDefinition.forId(37749).getHandlers().put("option:go-through", this); + SceneryDefinition.forId(37928).getHandlers().put("option:go-through", this); + SceneryDefinition.forId(37929).getHandlers().put("option:go-through", this); + SceneryDefinition.forId(38811).getHandlers().put("option:go-through", this); + SceneryDefinition.forId(39191).getHandlers().put("option:climb-up", this); + SceneryDefinition.forId(39188).getHandlers().put("option:open", this); + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + switch (node.getId()) { + case 37749: + player.teleport(Location.create(2885, 4372, 2)); + break; + case 39191: + ClimbActionHandler.climb(player, ClimbActionHandler.CLIMB_UP, Location.create(3239, 3606, 0), "You climb up the ladder to the surface."); + break; + case 39188: + if (!hasRequirement(player, Quests.DEFENDER_OF_VARROCK)) + break; + ClimbActionHandler.climb(player, ClimbActionHandler.CLIMB_DOWN, Location.create(3241, 9991, 0), "You descend into the cavern below."); + break; + case 37928: + player.teleport(Location.create(3214, 3782, 0)); + break; + case 38811: + case 37929: + if(player.getLocation().getX() < node.getLocation().getX()){ + player.getInterfaceManager().open(new Component(650)); + } else { + player.teleport(player.getLocation().transform(player.getLocation().getX() < node.getLocation().getX() ? 4 : -4, 0, 0)); + } + break; + } + return true; + } + + /** + * Represents the plugin used to handle kbd nodes. + * + * @author 'Vexia + * @author Player Name + * @version 1.1 + */ + public static final class KBDPlugin extends OptionHandler { + + /** + * Represents the locations used for kbd interactions. + */ + private static final Location[] LOCATIONS = new Location[] { new Location(3017, 3849, 0), Location.create(3069, 10257, 0), new Location(3069, 3856, 0), new Location(3017, 3850, 0), Location.create(2272, 4680, 0), Location.create(3067, 10253, 0), new Location(3069, 10256, 0) }; + + @Override + public Plugin newInstance(Object arg) throws Throwable { + SceneryDefinition.forId(1765).getHandlers().put("option:climb-down", this);// ladder + SceneryDefinition.forId(1766).getHandlers().put("option:climb-up", this);// ladder + SceneryDefinition.forId(1816).getHandlers().put("option:pull", this);// kbd + SceneryDefinition.forId(1817).getHandlers().put("option:pull", this);// kbd + return this; + } + + @Override + public boolean handle(Player player, Node node, String option) { + int id = ((Scenery) node).getId(); + switch (option) { + case "climb-down": + switch (id) { + case 1765:// kbd ladder. + if (node.getLocation().equals(LOCATIONS[0])) { + ClimbActionHandler.climb(player, new Animation(827), LOCATIONS[1]); + } else { + ClimbActionHandler.climbLadder(player, (Scenery) node, option); + return true; + } + break; + } + break; + case "climb-up": + switch (id) { + case 1766:// kbd leave ladder. + if (node.getLocation().equals(LOCATIONS[6])) { + ClimbActionHandler.climb(player, new Animation(828), LOCATIONS[3]); + } else { + ClimbActionHandler.climbLadder(player, (Scenery) node, option); + return true; + } + break; + } + break; + case "pull": + switch (id) { + case 1816:// kbd lever. + if (player.getLocation().withinDistance(LOCATIONS[5])) { + animate(player, 2140, false); + playAudio(player, Sounds.LEVER_2400); + player.getPacketDispatch().sendMessage("You pull the lever..."); + player.getTeleporter().send(LOCATIONS[4], TeleportType.NORMAL, TeleportManager.WILDY_TELEPORT); + player.getPacketDispatch().sendMessage("... and teleport into the lair of the King Black Dragon!", 5); + } + break; + case 1817: + if (player.getLocation().withinDistance(LOCATIONS[4])) { + animate(player, 2140, false); + playAudio(player, Sounds.LEVER_2400); + player.getPacketDispatch().sendMessage("You pull the lever..."); + player.getTeleporter().send(LOCATIONS[5], TeleportType.NORMAL); + player.getPacketDispatch().sendMessage("... and teleport out of the lair of the King Black Dragon!", 5); + } + break; + } + break; + } + return true; + } + + @Override + public Location getDestination(Node node, Node n) { + // if (n instanceof GameObject) { + // int id = ((GameObject) n).getId(); + // if (id == 1817) { + // return Location.create(2273, 4680, 0); + // } else if (id == 1816) { + // return Location.create(3067, 10253, 0); + // } + // } + return null; + } + } +} diff --git a/Server/src/main/content/region/wilderness/handlers/revenants/RevenantCombatHandler.java b/Server/src/main/content/region/wilderness/handlers/revenants/RevenantCombatHandler.java new file mode 100644 index 0000000..0104004 --- /dev/null +++ b/Server/src/main/content/region/wilderness/handlers/revenants/RevenantCombatHandler.java @@ -0,0 +1,106 @@ +package content.region.wilderness.handlers.revenants; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.equipment.SwitchAttack; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.prayer.PrayerType; +import core.game.world.map.zone.impl.WildernessZone; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.game.node.entity.combat.MultiSwingHandler; +import core.game.world.GameWorld; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.*; + +/** + * Handles the multi swing combat handler for revenants. + * @author Vexia + */ +public class RevenantCombatHandler extends MultiSwingHandler { + + /** + * The magic graphics. + */ + private static final Graphics MAGIC_GRAPHIC = Graphics.create(1276); + + /** + * The range graphics. + */ + private static final Graphics RANGE_GRAPHIC = Graphics.create(1278); + + /** + * Constructs a new {@code RevenantCombatHandler} {@code Object} + */ + public RevenantCombatHandler(Animation meleeAnimation, Animation magicAnimation, Animation rangeAnimation) { + super(true, new SwitchAttack(CombatStyle.MELEE.getSwingHandler(), meleeAnimation), new SwitchAttack(CombatStyle.RANGE.getSwingHandler(), rangeAnimation, createProjectile(RANGE_GRAPHIC)), new SwitchAttack(CombatStyle.MAGIC.getSwingHandler(), magicAnimation, createProjectile(MAGIC_GRAPHIC))); + } + + @Override + public void visualizeImpact(Entity entity, Entity victim, BattleState state) { + if (victim instanceof Player) { + SwitchAttack attack = getCurrent(); + if (attack != null) { + if (attack.getStyle() == CombatStyle.RANGE) { + playGlobalAudio(victim.getLocation(), 4061, 0, 1, 10); + } + } + } + super.visualizeImpact(entity, victim, state); + } + + @Override + public void impact(Entity entity, Entity victim, BattleState state) { + if (victim instanceof Player) { + SwitchAttack attack = getCurrent(); + if (attack != null) { + if (attack.getStyle() == CombatStyle.RANGE && !hasTimerActive(victim, "frozen") && !hasTimerActive(victim, "frozen:immunity")) { + registerTimer(victim, spawnTimer("frozen", 16, true)); + sendMessage((Player) victim, "The icy darts freeze your muscles!"); + playGlobalAudio(victim.getLocation(), 4059, 0, 1, 10); + } else if (attack.getStyle() == CombatStyle.MAGIC) { + int ticks = 500; + if (victim.asPlayer().getPrayer().get(PrayerType.PROTECT_FROM_MAGIC)) { + ticks /= 2; + } + if (hasTimerActive(victim, "teleblock")) { + playGlobalAudio(victim.getLocation(), 4064, 0, 1, 10); + } else { + registerTimer (victim, spawnTimer("teleblock", ticks)); + } + } + } + } + if (!isPoisoned(victim) && (WildernessZone.getWilderness(entity) >= 50 || entity.getId() == 6998)) { + applyPoison(victim, entity, 6); + } + super.impact(entity, victim, state); + } + + @Override + public void visualize(Entity entity, Entity victim, BattleState state) { + super.visualize(entity, victim, state); + if (victim.isPlayer()) { + SwitchAttack attack = getCurrent(); + if (attack != null) { + if (attack.getStyle() == CombatStyle.MAGIC) { + playGlobalAudio(entity.getLocation(), Sounds.TELEPORTBLOCK_CAST_202, 0, 1, 10); + } else if (attack.getStyle() == CombatStyle.RANGE) { + playGlobalAudio(entity.getLocation(), 4062, 0, 1, 10); + } + } + } + } + + /** + * Creates a projectile with a graphic id. + * @param graphic the graphic. + * @return the projectile. + */ + public static Projectile createProjectile(Graphics graphic) { + return Projectile.create(null, null, graphic.getId(), 48, 36, 34, 20); + } +} diff --git a/Server/src/main/content/region/wilderness/handlers/revenants/RevenantController.kt b/Server/src/main/content/region/wilderness/handlers/revenants/RevenantController.kt new file mode 100644 index 0000000..1a1bdc0 --- /dev/null +++ b/Server/src/main/content/region/wilderness/handlers/revenants/RevenantController.kt @@ -0,0 +1,231 @@ +package content.region.wilderness.handlers.revenants + +import core.game.interaction.MovementPulse +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.link.TeleportManager +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.update.flag.context.Graphics +import core.tools.RandomFunction +import core.ServerConstants +import core.api.* +import core.tools.SystemLogger +import core.game.system.command.Privilege +import core.game.world.GameWorld +import core.game.world.map.path.Pathfinder +import core.game.world.repository.Repository +import core.tools.Log +import java.lang.Integer.min +import kotlin.collections.ArrayList +import kotlin.collections.HashMap + +class RevenantController : TickListener, Commands { + + companion object { + private val trackedRevenants = ArrayList() + private val taskTimeRemaining = HashMap() + private val currentTask = HashMap() + private var expectedRevAmount: Int = ServerConstants.REVENANT_POPULATION + private var groupPatrolQueue = ArrayList() + + @JvmStatic fun registerRevenant(revenantNPC: RevenantNPC) { + trackedRevenants.add(revenantNPC) + taskTimeRemaining[revenantNPC] = 0 + currentTask[revenantNPC] = RevenantTask.NONE + Repository.RENDERABLE_NPCS.add(revenantNPC) + } + + @JvmStatic fun unregisterRevenant(revenantNPC: RevenantNPC, removeRender: Boolean = true) { + trackedRevenants.remove(revenantNPC) + taskTimeRemaining.remove(revenantNPC) + currentTask.remove(revenantNPC) + if (removeRender) + Repository.RENDERABLE_NPCS.remove(revenantNPC) + } + + val routes = listOf( + arrayOf(Location.create(3070, 3651), Location.create(3083, 3640), Location.create(3106, 3645), Location.create(3133, 3647), Location.create(3149, 3642), Location.create(3160, 3654), Location.create(3171, 3665, 0), Location.create(3189, 3663, 0), Location.create(3202, 3675, 0), Location.create(3217, 3660, 0), Location.create(3235, 3661, 0), Location.create(3235, 3661, 0), Location.create(3279, 3650, 0), Location.create(3269, 3636, 0), Location.create(3253, 3632, 0), Location.create(3236, 3638, 0), Location.create(3220, 3637, 0), Location.create(3203, 3634, 0), Location.create(3187, 3631, 0), Location.create(3166, 3633, 0), Location.create(3160, 3616, 0), Location.create(3148, 3604, 0), Location.create(3134, 3596, 0), Location.create(3118, 3590, 0), Location.create(3104, 3597, 0)), + arrayOf(Location.create(3077, 3565, 0), Location.create(3093, 3559, 0), Location.create(3110, 3566, 0), Location.create(3127, 3574, 0), Location.create(3146, 3571, 0), Location.create(3164, 3575, 0), Location.create(3183, 3573, 0), Location.create(3197, 3587, 0), Location.create(3215, 3584, 0), Location.create(3233, 3576, 0), Location.create(3251, 3573, 0), Location.create(3269, 3577, 0), Location.create(3287, 3569, 0), Location.create(3305, 3568, 0), Location.create(3321, 3576, 0), Location.create(3338, 3584, 0), Location.create(3352, 3573, 0), Location.create(3354, 3554, 0), Location.create(3342, 3541, 0), Location.create(3324, 3536, 0), Location.create(3306, 3543, 0), Location.create(3290, 3544, 0), Location.create(3272, 3545, 0), Location.create(3255, 3546, 0), Location.create(3239, 3539, 0), Location.create(3222, 3543, 0), Location.create(3206, 3548, 0), Location.create(3189, 3549, 0), Location.create(3173, 3552, 0), Location.create(3157, 3549, 0), Location.create(3140, 3548, 0), Location.create(3122, 3548, 0), Location.create(3110, 3555, 0)), + arrayOf(Location.create(3318, 3691, 0), Location.create(3307, 3700, 0), Location.create(3290, 3696, 0), Location.create(3277, 3706, 0), Location.create(3260, 3706, 0), Location.create(3250, 3707, 0), Location.create(3245, 3723, 0), Location.create(3254, 3735, 0), Location.create(3251, 3754, 0), Location.create(3243, 3768, 0), Location.create(3253, 3780, 0), Location.create(3238, 3783, 0), Location.create(3224, 3793, 0), Location.create(3206, 3786, 0), Location.create(3192, 3780, 0), Location.create(3170, 3787, 0), Location.create(3156, 3800, 0), Location.create(3148, 3814, 0), Location.create(3148, 3814, 0), Location.create(3127, 3840, 0), Location.create(3124, 3856, 0), Location.create(3124, 3872, 0), Location.create(3116, 3892, 0)), + arrayOf(Location.create(2949, 3890, 0), Location.create(2965, 3899, 0), Location.create(2984, 3900, 0), Location.create(2998, 3895, 0), Location.create(3016, 3898, 0), Location.create(3032, 3893, 0), Location.create(3048, 3897, 0), Location.create(3068, 3894, 0), Location.create(3084, 3898, 0), Location.create(3101, 3895, 0), Location.create(3118, 3897, 0), Location.create(3136, 3893, 0), Location.create(3154, 3900, 0), Location.create(3172, 3895, 0), Location.create(3189, 3892, 0), Location.create(3206, 3897, 0), Location.create(3222, 3890, 0), Location.create(3240, 3897, 0), Location.create(3259, 3892, 0), Location.create(3278, 3895, 0), Location.create(3296, 3892, 0), Location.create(3313, 3899, 0), Location.create(3331, 3888, 0), Location.create(3345, 3880, 0)), + arrayOf(Location.create(3308, 3941, 0), Location.create(3301, 3925, 0), Location.create(3287, 3915, 0), Location.create(3276, 3922, 0), Location.create(3266, 3938, 0), Location.create(3267, 3952, 0), Location.create(3250, 3949, 0), Location.create(3235, 3944, 0), Location.create(3219, 3944, 0), Location.create(3206, 3938, 0), Location.create(3194, 3929, 0), Location.create(3182, 3921, 0), Location.create(3174, 3936, 0), Location.create(3180, 3952, 0), Location.create(3167, 3960, 0), Location.create(3155, 3959, 0), Location.create(3141, 3953, 0), Location.create(3126, 3954, 0), Location.create(3110, 3961, 0), Location.create(3093, 3962, 0), Location.create(3078, 3953, 0), Location.create(3066, 3942, 0), Location.create(3059, 3929, 0), Location.create(3049, 3916, 0), Location.create(3033, 3924, 0), Location.create(3020, 3921, 0), Location.create(3010, 3913, 0), Location.create(2993, 3906, 0), Location.create(2977, 3911, 0), Location.create(2970, 3928, 0)) + ) + + val spawnLocations = listOf(Location.create(3075, 3553, 0), Location.create(3077, 3563, 0), Location.create(3077, 3578, 0), Location.create(3093, 3581, 0), Location.create(3103, 3570, 0), Location.create(3101, 3564, 0), Location.create(3030, 3596, 0), Location.create(3015, 3598, 0), Location.create(3000, 3593, 0), Location.create(2986, 3588, 0), Location.create(2969, 3701, 0), Location.create(2982, 3689, 0), Location.create(2967, 3689, 0), Location.create(2953, 3711, 0), Location.create(2966, 3759, 0), Location.create(2989, 3759, 0), Location.create(2986, 3741, 0), Location.create(2961, 3763, 0), Location.create(2969, 3808, 0), Location.create(3004, 3816, 0)) + } + + override fun tick() { + taskTimeRemaining.replaceAll { _, t -> t - 1 } + currentTask.entries.forEach { entry -> + if (entry.value == RevenantTask.NONE) { + entry.setValue(assignRandomTask(entry.key)) + } else { + entry.value.execute(entry.key) + } + } + spawnMissingRevenants() + } + + private fun spawnMissingRevenants() { + val amountToSpawn = min(5, expectedRevAmount - trackedRevenants.size) //only spawn 5 at a time + + if (amountToSpawn <= 0) return + + for (i in 0 until amountToSpawn) { + val type = RevenantType.values().random() + val npc = NPC.create(type.ids[0], getRandomSpawnLocation()) + npc.init() + } + } + + private fun getRandomSpawnLocation(): Location { + return spawnLocations.random() + } + + private fun assignRandomTask(npc: RevenantNPC): RevenantTask { + return RevenantTask.values().random().also { it.assign(npc) } + } + + override fun defineCommands() { + define("setrevcap", Privilege.ADMIN) {player, strings -> + val amt = strings[1].toInt() + expectedRevAmount = amt + } + + define("listrevs", Privilege.ADMIN) {player, strings -> + for (rev in trackedRevenants) { + log(this::class.java, Log.FINE, "REV ${rev.id}-${rev.name} @ ${rev.location.toString()}") + } + + log(this::class.java, Log.FINE, "Total of ${trackedRevenants.size} revenants spawned.") + } + + define("clearrevs", Privilege.ADMIN) {_, _ -> + for (rev in trackedRevenants.toTypedArray()) rev.clear() + } + } + + //The current task for any given revenant - execute is called every tick. + enum class RevenantTask { + NONE { + override fun execute(revenantNPC: RevenantNPC) {} + }, + RANDOM_ROAM { + private val MAX_ROAM_TICKS: Int = 250 + + override fun execute(revenantNPC: RevenantNPC) { + if (!canMove(revenantNPC)) return + + val nextLoc = getNextLocation(revenantNPC) + revenantNPC.pulseManager.run(object : MovementPulse(revenantNPC, nextLoc, Pathfinder.SMART) { + override fun pulse(): Boolean { + if (taskTimeRemaining[revenantNPC]!! <= 0) currentTask[revenantNPC] = NONE + return true + } + }) + } + + override fun assign(revenantNPC: RevenantNPC) { + taskTimeRemaining[revenantNPC] = RandomFunction.random(MAX_ROAM_TICKS) + } + + fun canMove(revenantNPC: RevenantNPC) : Boolean { + return !revenantNPC.walkingQueue.isMoving + && !revenantNPC.pulseManager.hasPulseRunning() + && !revenantNPC.properties.combatPulse.isAttacking + && !revenantNPC.properties.combatPulse.isInCombat + } + + fun getNextLocation(revenantNPC: RevenantNPC) : Location { + val nextX = RandomFunction.random(-revenantNPC.walkRadius, revenantNPC.walkRadius) + val nextY = RandomFunction.random(-revenantNPC.walkRadius, revenantNPC.walkRadius) + return revenantNPC.location.transform(nextX, nextY, 0) + } + }, + PATROLLING_ROUTE { + private val MAXIMUM_GROUP_PATROL_LEVEL = 105 + + override fun assign(revenantNPC: RevenantNPC) { + if (canGroup(revenantNPC)) { + addToPatrolGroup(revenantNPC) + } else { + revenantNPC.setAttribute("route", routes.random()) + revenantNPC.setAttribute("routeidx", -1) + } + } + + private fun addToPatrolGroup(revenantNPC: RevenantNPC) { + revenantNPC.setAttribute("group", true) + groupPatrolQueue.add(revenantNPC) + + if (groupPatrolQueue.size == 3) { + val groupRoute = routes.random() + for (rev in groupPatrolQueue) { + rev.setAttribute("route", groupRoute) + rev.setAttribute("routeidx", -1) + } + groupPatrolQueue.clear() + } + } + + private fun canGroup(revenantNPC: RevenantNPC) = + revenantNPC.properties.currentCombatLevel <= MAXIMUM_GROUP_PATROL_LEVEL && RandomFunction.nextBool() + + override fun execute(revenantNPC: RevenantNPC) { + val isGroup = revenantNPC.getAttribute("group", false) + val route = revenantNPC.getAttribute>("route", null) + val routeIdx = revenantNPC.getAttribute("routeidx", -1) + + if (!canMove(revenantNPC)) return + + if (isGroup && route == null) { //if this is a grouped rev and we are waiting on more revs still + taskTimeRemaining[revenantNPC] = 50 //just to make sure it doesn't time out roaming... + RANDOM_ROAM.execute(revenantNPC) + return + } + + if (routeIdx == -1) { + GameWorld.Pulser.submit(object : Pulse() { + override fun pulse(): Boolean { + Graphics.send(Graphics(86), revenantNPC.location) + return true + } + }) + teleport(revenantNPC, route[0], TeleportManager.TeleportType.INSTANT) + revenantNPC.setAttribute("routeidx", 1) + } else { + if (routeIdx == route.size) { + poofClear(revenantNPC) + revenantNPC.setAttribute("done", true) + return + } + val pathVariance = if (isGroup) 4 else 10 + val nextLoc = route[routeIdx].transform( + RandomFunction.random(-pathVariance, pathVariance), + RandomFunction.random(-pathVariance, pathVariance), + 0 + ) + revenantNPC.pulseManager.run(object : MovementPulse(revenantNPC, nextLoc, Pathfinder.SMART) { + override fun pulse(): Boolean { + return true + } + }) + revenantNPC.setAttribute("routeidx", routeIdx + 1) + } + } + + fun canMove(revenantNPC: RevenantNPC) : Boolean { + return !revenantNPC.walkingQueue.isMoving + && !revenantNPC.pulseManager.hasPulseRunning() + && !revenantNPC.properties.combatPulse.isAttacking + && !revenantNPC.properties.combatPulse.isInCombat + && revenantNPC.properties.teleportLocation == null + && !revenantNPC.getAttribute("done", false) + } + } + ; + + abstract fun execute(revenantNPC: RevenantNPC) + open fun assign(revenantNPC: RevenantNPC) {} + } +} diff --git a/Server/src/main/content/region/wilderness/handlers/revenants/RevenantNPC.java b/Server/src/main/content/region/wilderness/handlers/revenants/RevenantNPC.java new file mode 100644 index 0000000..6e0d0e6 --- /dev/null +++ b/Server/src/main/content/region/wilderness/handlers/revenants/RevenantNPC.java @@ -0,0 +1,290 @@ +package content.region.wilderness.handlers.revenants; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.DeathTask; +import core.game.node.entity.npc.AbstractNPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.audio.Audio; +import core.game.node.entity.skill.Skills; +import content.global.skill.summoning.familiar.Familiar; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.impl.WildernessZone; +import core.game.world.update.flag.context.Animation; +import core.plugin.Initializable; +import core.tools.RandomFunction; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.system.config.NPCConfigParser; +import core.game.world.GameWorld; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playAudio; +import static core.api.ContentAPIKt.playGlobalAudio; + +/** + * Handles a revenant NPC. + * @author Ceikry-ish (mostly Vexia code still), Player Name + */ +@Initializable +public class RevenantNPC extends AbstractNPC { + + /** + * The safe zone borders. + */ + private static final ZoneBorders[] SAFE_ZONES = new ZoneBorders[] { new ZoneBorders(3074, 3651, 3193, 3774), new ZoneBorders(3264, 3672, 3279, 3695), new ZoneBorders(3081, 3909, 3129, 3954), new ZoneBorders(3350, 3869, 3391, 3900) }; + + /** + * The possible PVP item drops. + */ + private static final int[] PVP_DROPS = new int[] { 13896, 13884, 13890, 13902, 13887, 13899, 13893, 13905, 13864, 13858, 13861, 13867, 13876, 13879, 13870, 13873, 13883, 13908, 13911, 13914, 13917, 13920, 13923, 13926, 13929, 13932, 13935, 13938, 13941, 13944, 13947, 13950, 13953, 13958, 13961, 13964, 13967, 13970, 13973, 13976, 13979, 13982, 13985, 13988 }; + + /** + * The swing handler. + */ + private CombatSwingHandler swingHandler; + + /** + * The revenant type. + */ + private final RevenantType type; + + /** + * The routes this revenant can travel. + */ + private final Location[][] routes; + + /** + * Constructs a new {@code RevenantNPC} {@code Object} + * @param id the id. + * @param location the location. + */ + public RevenantNPC(int id, Location location, Location[][] routes) { + super(id, location); + this.routes = routes; + this.type = RevenantType.forId(id); + } + + /** + * Constructs a new {@code RevenantNPC} {@code Object} + */ + public RevenantNPC() { + this(-1, null, null); + } + + @Override + public void configure() { + setWalks(true); + setRespawn(false); + setAggressive(true); + setRenderable(true); + setDefaultBehavior(); + getAggressiveHandler().setRadius(64 * 2); + getAggressiveHandler().setChanceRatio(9); + getAggressiveHandler().setAllowTolerance(false); + getProperties().setCombatTimeOut(120); + configureBonuses(); + super.configure(); + this.swingHandler = new RevenantCombatHandler(getProperties().getAttackAnimation(), getProperties().getMagicAnimation(), getProperties().getRangeAnimation()); + setAttribute("food-items", 20); + } + + @Override + public void init() { + super.init(); + RevenantController.registerRevenant(this); + int spawnAnim = getDefinition().getConfiguration(NPCConfigParser.SPAWN_ANIMATION, -1); + if (spawnAnim != -1) { + animate(new Animation(spawnAnim)); + } + } + + @Override + public void clear() { + super.clear(); + RevenantController.unregisterRevenant(this, true); + } + + @Override + public void finalizeDeath(Entity killer) { + super.finalizeDeath(killer); + playGlobalAudio(killer.getLocation(),4063); + } + + @Override + public void tick() { + skills.pulse(); + getWalkingQueue().update(); + if (this.getViewport().getRegion().isActive()) { + getUpdateMasks().prepare(this); + } + if (!DeathTask.isDead(this)) { + int curhp = getSkills().getLifepoints(); + int maxhp = getSkills().getStaticLevel(Skills.HITPOINTS); + int fooditems = getAttribute("food-items", 0); + if (curhp < maxhp / 2 && fooditems > 0 && getAttribute("eat-delay", 0) < GameWorld.getTicks()) { + lock(3); + getProperties().getCombatPulse().delayNextAttack(3); + getSkills().heal(maxhp / 6); + for (Player p : RegionManager.getLocalPlayers(this)) { + playAudio(p, Sounds.EAT_2393); + } + setAttribute("eat-delay", GameWorld.getTicks() + 6); + setAttribute("food-items", fooditems - 1); + } + } + behavior.tick(this); + if (aggressiveHandler != null && aggressiveHandler.selectTarget()) { + return; + } + } + + @Override + public void sendImpact(BattleState state) { + if (state.getEstimatedHit() > type.getMaxHit()) { + state.setEstimatedHit(RandomFunction.random(type.getMaxHit() - 5, type.getMaxHit())); + } + } + + @Override + public Audio getAudio(int index) { + return null; + } + + @Override + public AbstractNPC construct(int id, Location location, Object... objects) { + return new RevenantNPC(id, location, null); + } + + @Override + public void setNextWalk() { + nextWalk = GameWorld.getTicks() + RandomFunction.random(7, 15); + } + + @Override + public CombatSwingHandler getSwingHandler(boolean swing) { + return swingHandler; + } + + @Override + public boolean canMove(Location location) { + for (ZoneBorders zone : SAFE_ZONES) { + if (zone.insideBorder(location)) { + return false; + } + } + return true; + } + + @Override + protected Location getMovementDestination() { + if (!pathBoundMovement || movementPath == null || movementPath.length < 1) { + return getLocation().transform(-5 + RandomFunction.random(getWalkRadius()), -5 + RandomFunction.random(getWalkRadius()), 0); + } + Location l = movementPath[movementIndex++]; + if (movementIndex == movementPath.length) { + movementIndex = 0; + } + return l; + } + + @Override + public int getWalkRadius() { + return 20; + } + + @Override + public boolean continueAttack(Entity target, CombatStyle style, boolean message) { + return target instanceof Player ? hasAcceptableCombatLevel(target.asPlayer()) : true; + } + + @Override + public boolean isAttackable(Entity entity, CombatStyle style, boolean message) { + if (entity instanceof Player) { + if (!hasAcceptableCombatLevel(entity.asPlayer()) && !entity.asPlayer().isAdmin()) { + if (message) { + entity.asPlayer().sendMessage("The level difference between you and your opponent is too great."); + } + return false; + } + } + if (entity instanceof Familiar) { + Player owner = ((Familiar) entity).getOwner(); + if (owner == null) { + return false; + } + if (!hasAcceptableCombatLevel(owner)) { + return false; + } + } + return super.isAttackable(entity, style, message); + } + + @Override + public boolean canSelectTarget(Entity target) { + if (!(target instanceof Player)) { + return false; + } + return hasAcceptableCombatLevel(target.asPlayer()); + } + + @Override + public int[] getIds() { + return new int[] { 6604, 6635, 6655, 6666, 6677, 6697, 6703, 6715, 6605, 6612, 6616, 6620, 6636, 6637, 6638, 6639, 6651, 6656, 6657, 6658, 6667, 6678, 6679, 6680, 6681, 6693, 6698, 6699, 6704, 6705, 6706, 6707, 6716, 6717, 6718, 6719, 6606, 6621, 6628, 6640, 6659, 6682, 6694, 6708, 6720, 6622, 6631, 6641, 6660, 6668, 6683, 6709, 6721, 6608, 6642, 6661, 6684, 6710, 6722, 6727, 6613, 6623, 6643, 6652, 6662, 6669, 6671, 6674, 6685, 6695, 6700, 6711, 6723, 6607, 6609, 6614, 6617, 6625, 6632, 6644, 6663, 6675, 6686, 6701, 6712, 6724, 6728, 6645, 6687, 6646, 6688, 6647, 6689, 6610, 6615, 6618, 6624, 6626, 6629, 6633, 6648, 6653, 6664, 6670, 6672, 6690, 6696, 6702, 6713, 6725, 6729, 6649, 6691, 6611, 6619, 6627, 6630, 6634, 6650, 6654, 6665, 6673, 6676, 6692, 6714, 6726, 6730, 6998, 6999 }; + } + + /** + * Configures the bonuses, + */ + @SuppressWarnings("deprecation") + private void configureBonuses() { + for (int i = 0; i < getProperties().getBonuses().length; i++) { + getProperties().getBonuses()[i] = 40 + (4 * (getProperties().getCombatLevel() / 2)); + } + } + + /** + * Configures a route for the revenant. + */ + private void configureRoute() { + if (routes == null || routes.length == 0) { + return; + } + configureMovementPath(RandomFunction.getRandomElement(routes)); + } + + /** + * Checks if the combat level of a revenant is acceptable to attack the + * player. + * @param player the player. + * @return {@code True} if so. + */ + private boolean hasAcceptableCombatLevel(Player player) { + int level = WildernessZone.getWilderness(this); + if (player.getSkullManager().getLevel() < level) { + level = player.getSkullManager().getLevel(); + } + int combat = getProperties().getCurrentCombatLevel(); + int targetCombat = player.getProperties().getCurrentCombatLevel(); + return Math.abs(combat - targetCombat) <= level; + } + + /** + * Gets the routes. + * @return the routes + */ + public Location[][] getRoutes() { + return routes; + } + + /** + * Gets the type. + * @return the type + */ + public RevenantType getType() { + return type; + } + +} diff --git a/Server/src/main/content/region/wilderness/handlers/revenants/RevenantType.java b/Server/src/main/content/region/wilderness/handlers/revenants/RevenantType.java new file mode 100644 index 0000000..0e7bfb0 --- /dev/null +++ b/Server/src/main/content/region/wilderness/handlers/revenants/RevenantType.java @@ -0,0 +1,82 @@ +package content.region.wilderness.handlers.revenants; + +import core.cache.def.impl.NPCDefinition; + +import java.util.ArrayList; +import java.util.List; + +/** + * A revenant type. + * @author Vexia + */ +public enum RevenantType { + IMP(8, 6604, 6635, 6655, 6666, 6677, 6697, 6703, 6715), GOBLIN(12, 6605, 6612, 6616, 6620, 6636, 6637, 6638, 6639, 6651, 6656, 6657, 6658, 6667, 6678, 6679, 6680, 6681, 6693, 6698, 6699, 6704, 6705, 6706, 6707, 6716, 6717, 6718, 6719), ICEFIEND(20, 6606, 6621, 6628, 6640, 6659, 6682, 6694, 6708, 6720), PYREFIEND(20, 6622, 6631, 6641, 6660, 6668, 6683, 6709, 6721), HOGOBLIN(20, 6608, 6642, 6661, 6684, 6710, 6722, 6727), VAMPYRE(22, 6613, 6623, 6643, 6652, 6662, 6669, 6671, 6674, 6685, 6695, 6700, 6711, 6723), WEREWOLF(23, 6607, 6609, 6614, 6617, 6625, 6632, 6644, 6663, 6675, 6686, 6701, 6712, 6724, 6728), CYCLOPS(24, 6645, 6687), HELLHOUND(25, 6646, 6688), DEMON(25, 6647, 6689), ORK(31, 6610, 6615, 6618, 6624, 6626, 6629, 6633, 6648, 6653, 6664, 6670, 6672, 6690, 6696, 6702, 6713, 6725, 6729), DARK_BEAST(36, 6649, 6691), KNIGHT(42, 6611, 6619, 6627, 6630, 6634, 6650, 6654, 6665, 6673, 6676, 6692, 6714, 6726, 6730), DRAGON(60, 6998, 6999); + + /** + * The max hit. + */ + private final int maxHit; + + /** + * The ids of the revenant. + */ + private final int[] ids; + + /** + * Constructs a new {@code RevenantType} {@code Object} + * @param maxHit the max hit. + * @param ids the ids. + */ + private RevenantType(int maxHit, int... ids) { + this.maxHit = maxHit; + this.ids = ids; + } + + /** + * Gets the revenant type by the id. + * @param id the id. + * @return the type. + */ + public static RevenantType forId(int id) { + for (RevenantType type : values()) { + for (int i : type.getIds()) { + if (i == id) { + return type; + } + } + } + return null; + } + + /** + * Gets the ids. + * @return the ids. + */ + public int[] getIds() { + return ids; + } + + /** + * Gets the maxHit. + * @return the maxHit + */ + public int getMaxHit() { + return maxHit; + } + + public static RevenantType getClosestHigherOrEqual (int combatLevel) { + for (RevenantType t : values()) { + NPCDefinition def = NPCDefinition.forId(t.ids[0]); + if (def.getCombatLevel() >= combatLevel) return t; + } + return RevenantType.DRAGON; + } + + public static List getAllIds() { + ArrayList ids = new ArrayList<>(); + for (RevenantType t : values()) { + for (int id : t.ids) ids.add(id); + } + return ids; + } +} diff --git a/Server/src/main/core/GlobalStats.kt b/Server/src/main/core/GlobalStats.kt new file mode 100644 index 0000000..f055e32 --- /dev/null +++ b/Server/src/main/core/GlobalStats.kt @@ -0,0 +1,45 @@ +package core + +import org.json.simple.JSONObject +import core.ServerStore.Companion.getInt + +object GlobalStats { + + @JvmStatic + fun incrementDeathCount(){ + getDailyDeathArchive()["players"] = getDailyDeathArchive().getInt("players") + 1 + } + + @JvmStatic + fun incrementDailyCowDeaths(){ + getDailyDeathArchive()["lumbridge-cows"] = getDailyDeathArchive().getInt("lumbridge-cows") + 1 + } + + @JvmStatic + fun incrementGuardPickpockets(){ + getGuardPickpocketArchive()["count"] = getGuardPickpocketArchive().getInt("count") + 1 + } + + @JvmStatic + fun getDailyGuardPickpockets(): Int { + return getGuardPickpocketArchive().getInt("count") + } + + fun getDailyDeaths(): Int { + return getDailyDeathArchive().getInt("players") + } + + @JvmStatic + fun getDailyCowDeaths(): Int { + return getDailyDeathArchive().getInt("lumbridge-cows") + } + + private fun getDailyDeathArchive(): JSONObject { + return ServerStore.getArchive("daily-deaths-global") + } + + private fun getGuardPickpocketArchive(): JSONObject { + return ServerStore.getArchive("daily-guard-pickpockets") + } + +} \ No newline at end of file diff --git a/Server/src/main/core/JSONUtils.kt b/Server/src/main/core/JSONUtils.kt new file mode 100644 index 0000000..bafec26 --- /dev/null +++ b/Server/src/main/core/JSONUtils.kt @@ -0,0 +1,47 @@ +package core + +import core.game.world.map.Location +import java.io.File + +class JSONUtils { + companion object { + + + /** + * Parses a location from the format "x,y,z" + * @author Ceikry + * @param locString The string to parse + * @return Location + */ + @JvmStatic + fun parseLocation(locString: String): Location { + val locTokens = locString.split(",").map { it.toInt() } + return Location(locTokens[0], locTokens[1], locTokens[2]) + } + + /** + * Parses a path string + * @author Ceikry + * @param pathString The string to parse + * @return a String with the proper file separators for the current OS. + */ + @JvmStatic + fun parsePath(pathString: String): String { + var pathTokens: List? = null + if(pathString.contains("/")) + pathTokens = pathString.split("/") + else if(pathString.contains("\\")) + pathTokens = pathString.split("\\") + + pathTokens ?: return pathString //return the initial pathString if path does not contain file separators. + var pathProduct = "" + for(token in pathTokens){ + if(token != "") + pathProduct += "$token${File.separator}" + } + + return pathProduct + } + + } +} \ No newline at end of file diff --git a/Server/src/main/core/Server.kt b/Server/src/main/core/Server.kt new file mode 100644 index 0000000..80f29a8 --- /dev/null +++ b/Server/src/main/core/Server.kt @@ -0,0 +1,197 @@ +package core + +import core.api.log +import core.game.system.SystemManager +import core.game.system.SystemState +import core.game.system.config.ServerConfigParser +import core.game.world.GameWorld +import core.net.NioReactor +import core.tools.Log +import core.tools.NetworkReachability +import core.tools.TimeStamp +import kotlinx.coroutines.* +import java.io.File +import java.io.FileWriter +import java.lang.management.ManagementFactory +import java.lang.management.ThreadMXBean +import java.net.BindException +import java.net.URL +import java.util.* +import kotlin.math.max +import kotlin.system.exitProcess + + +/** + * The main class, for those that are unable to read the class' name. + * @author Emperor + * @author Ceikry + */ +object Server { + /** + * The time stamp of when the server started running. + */ + @JvmField + var startTime: Long = 0 + + var lastHeartbeat = System.currentTimeMillis() + + @JvmStatic + var running = false + + /** + * The NIO reactor. + */ + @JvmStatic + var reactor: NioReactor? = null + + var networkReachability = NetworkReachability.Reachable + + /** + * The main method, in this method we load background utilities such as + * cache and our world, then end with starting networking. + * @param args The arguments cast on runtime. + * @throws Throwable When an exception occurs. + */ + @Throws(Throwable::class) + @JvmStatic + fun main(args: Array) { + if (args.isNotEmpty()) { + log(this::class.java, Log.INFO, "Using config file: ${args[0]}") + ServerConfigParser.parse(args[0]) + } else { + log(this::class.java, Log.INFO, "Using config file: ${"worldprops" + File.separator + "default.conf"}") + ServerConfigParser.parse("worldprops" + File.separator + "default.conf") + } + startTime = System.currentTimeMillis() + val t = TimeStamp() + GameWorld.prompt(true) + Runtime.getRuntime().addShutdownHook(ServerConstants.SHUTDOWN_HOOK) + log(this::class.java, Log.INFO, "Starting networking...") + try { + reactor = NioReactor.configure(43594 + GameWorld.settings?.worldId!!) + reactor!!.start() + } catch (e: BindException) { + log(this::class.java, Log.ERR, "Port " + (43594 + GameWorld.settings?.worldId!!) + " is already in use!") + throw e + } + //WorldCommunicator.connect() + log(this::class.java, Log.INFO, GameWorld.settings?.name + " flags " + GameWorld.settings?.toString()) + log(this::class.java, Log.INFO, GameWorld.settings?.name + " started in " + t.duration(false, "") + " milliseconds.") + val scanner = Scanner(System.`in`) + + running = true + GlobalScope.launch { + while(scanner.hasNextLine()){ + val command = scanner.nextLine() + when(command){ + "stop" -> exitProcess(0) + + "update" -> SystemManager.flag(SystemState.UPDATING) + "help","commands" -> printCommands() + "restartworker" -> SystemManager.flag(SystemState.ACTIVE) + + } + } + } + + if (ServerConstants.WATCHDOG_ENABLED) { + GlobalScope.launch { + delay(20000) + while (running) { + val timeStart = System.currentTimeMillis() + if (!checkConnectivity()) + networkReachability = NetworkReachability.Unreachable + else + networkReachability = NetworkReachability.Reachable + if (System.currentTimeMillis() - lastHeartbeat > 7200 && running) { + log(this::class.java, Log.ERR, "Triggering reboot due to heartbeat timeout") + log(this::class.java, Log.ERR, "Creating thread dump...") + val dump = threadDump(true, true) + + withContext(Dispatchers.IO) { + FileWriter("latestdump.txt").use { + + if (dump != null) { + it.write(dump) + } + + it.flush() + it.close() + } + } + + if (!SystemManager.isTerminated()) + exitProcess(0) + } + val timeNow = System.currentTimeMillis() + delay(max(0L, 625 - (timeNow - timeStart))) + } + } + } + } + + private fun checkConnectivity(): Boolean + { + //Has to be done this way because you can't actually ping in Java unless you run the whole thing as root + val urls = ServerConstants.CONNECTIVITY_CHECK_URL.split(",") + var timeout = ServerConstants.CONNECTIVITY_TIMEOUT + if (timeout * urls.size > 5000) //Limit timeout down to 5000ms so other watchdog functions continue as expected. + timeout = 5000 / urls.size + for (targetUrl in urls) { + try { + val url = URL(targetUrl) + val conn = url.openConnection() + conn.connectTimeout = timeout + conn.connect() + conn.getInputStream().close() + return true + } catch (e: Exception) { + log(this::class.java, Log.WARN, "${targetUrl} failed to respond. Are we offline?") + continue + } + } + return false + } + + @JvmStatic + fun heartbeat() { + lastHeartbeat = System.currentTimeMillis() + } + + fun printCommands(){ + println("stop - stop the server (saves all accounts and such)") + println("players - show online player count") + println("update - initiate an update with a countdown visible to players") + println("help, commands - show this") + println("restartworker - Reboots the major update worker in case of a travesty.") + } + + fun autoReconnect() { + /*SystemLogger.log("Attempting autoreconnect of server") + WorldCommunicator.connect()*/ + } + /** + * Gets the startTime. + * @return the startTime + */ + fun getStartTime(): Long { + return startTime + } + + private fun threadDump(lockedMonitors: Boolean, lockedSynchronizers: Boolean): String? { + val threadDump = StringBuffer(System.lineSeparator()) + val threadMXBean: ThreadMXBean = ManagementFactory.getThreadMXBean() + for (threadInfo in threadMXBean.dumpAllThreads(lockedMonitors, lockedSynchronizers)) { + threadDump.append(threadInfo.toString()) + } + return threadDump.toString() + } + + /** + * Sets the bastartTime.ZZ + * @param startTime the startTime to set. + */ + fun setStartTime(startTime: Long) { + Server.startTime = startTime + } +} diff --git a/Server/src/main/core/ServerConstants.kt b/Server/src/main/core/ServerConstants.kt new file mode 100644 index 0000000..26923a2 --- /dev/null +++ b/Server/src/main/core/ServerConstants.kt @@ -0,0 +1,348 @@ +package core + +import core.game.system.SystemShutdownHook +import core.game.world.map.Location +import core.tools.LogLevel +import core.tools.mysql.Database +import core.tools.secondsToTicks +import rs09.game.content.activity.castlewars.CastleWars +import java.math.BigInteger +import java.util.* + +/** + * A class holding various variables for the server. + * @author Ceikry + */ +class ServerConstants { + companion object { + var NOAUTH_DEFAULT_ADMIN: Boolean = true + + @JvmField + var CURRENT_SAVEFILE_VERSION = 3 + + @JvmField + var DAILY_ACCOUNT_LIMIT = 3 + + @JvmField + var REVENANT_POPULATION: Int = 30 + + @JvmField + var BOTS_INFLUENCE_PRICE_INDEX = true + + @JvmField + var SHUTDOWN_HOOK: Thread = Thread(SystemShutdownHook()) + + @JvmField + var ALLOW_GUI: Boolean = false + + @JvmField + var DATA_PATH: String? = null + + //path to the cache + @JvmField + var CACHE_PATH: String? = null + + //path for the server store + @JvmField + var STORE_PATH: String? = null + + //path for player saves + @JvmField + var PLAYER_SAVE_PATH: String? = null + + @JvmField + var PLAYER_ATTRIBUTE_PATH = "ish" + + //path to the various config files, such as npc_spawns.json + var CONFIG_PATH: String? = null + + @JvmField + var GRAND_EXCHANGE_DATA_PATH: String? = null + + @JvmField + var RDT_DATA_PATH: String? = null + + @JvmField + var OBJECT_PARSER_PATH: String? = null + + @JvmField + var SCRIPTS_PATH: String? = null + + @JvmField + var DIALOGUE_SCRIPTS_PATH: String? = null + + @JvmField + var LOGS_PATH: String? = null + + @JvmField + var BOT_DATA_PATH: String? = null + + @JvmField + var CELEDT_DATA_PATH: String? = null + + @JvmField + var USDT_DATA_PATH: String? = null + + @JvmField + var HDT_DATA_PATH: String? = null + + @JvmField + var GDT_DATA_PATH: String? = null + + @JvmField + var RSDT_DATA_PATH: String? = null + + @JvmField + var ASDT_DATA_PATH: String? = null + + @JvmField + var GRAFANA_PATH: String? = null + + //the max number of players. + @JvmField + var MAX_PLAYERS = 2000 + + //the max number of NPCs + @JvmField + var MAX_NPCS = 32000 + + //the location where new players are placed on login. + @JvmField + var START_LOCATION: Location? = null + + //Location for all home teleports/respawn location + @JvmField + var HOME_LOCATION: Location? = null + + //the name for the database + @JvmField + var DATABASE_NAME: String? = null + + //username for the database + @JvmField + var DATABASE_USER: String? = null + + //password for the database + @JvmField + var DATABASE_PASS: String? = null + + //address for the database + @JvmField + var DATABASE_ADDRESS: String? = null + + @JvmField + var DATABASE_PORT: String? = null + + @JvmField + var WRITE_LOGS: Boolean = false + + @JvmField + var BANK_SIZE: Int = 496 + + @JvmField + var BANK_BOOTH_QUICK_OPEN: Boolean = false + + @JvmField + var BANK_BOOTH_NOTE_ENABLED: Boolean = true + + @JvmField + var BANK_BOOTH_NOTE_UIM: Boolean = true + + @JvmField + var GE_AUTOSAVE_FREQUENCY = secondsToTicks(3600) //1 hour + + @JvmField + var GE_AUTOSTOCK_ENABLED = false + + @JvmField + var MS_SECRET_KEY = "" + + @JvmField + var LOG_CUTSCENE = true + + @JvmField + var RULES_AND_INFO_ENABLED = true + + @JvmField + var WATCHDOG_ENABLED = true + + @JvmField + var I_AM_A_CHEATER = false + + @JvmField + var LOG_LEVEL = LogLevel.VERBOSE + + @JvmField + var JAVA_VERSION = 8 + + @JvmField + var GRAFANA_LOGGING = true + + @JvmField + var GRAFANA_TTL_DAYS = 7 + + //location names for the ::to command. + val TELEPORT_DESTINATIONS = arrayOf( + arrayOf(Location.create(2974, 4383, 2), "corp", "corporal", "corporeal"), + arrayOf(Location.create(2659, 2649, 0), "pc", "pest control", "pest"), + arrayOf(Location.create(3293, 3184, 0), "al kharid", "alkharid", "kharid"), + arrayOf(Location.create(3222, 3217, 0), "lumbridge", "lumby"), + arrayOf(Location.create(3110, 3168, 0), "wizard tower", "wizards tower", "tower", "wizards"), + arrayOf(Location.create(3083, 3249, 0), "draynor", "draynor village"), + arrayOf(Location.create(3019, 3244, 0), "port sarim", "sarim"), + arrayOf(Location.create(2956, 3209, 0), "rimmington"), + arrayOf(Location.create(2965, 3380, 0), "fally", "falador"), + arrayOf(Location.create(2895, 3436, 0), "taverley"), + arrayOf(Location.create(3080, 3423, 0), "barbarian village", "barb"), + arrayOf(Location.create(3213, 3428, 0), "varrock"), + arrayOf(Location.create(3164, 3485, 0), "grand exchange", "ge"), + arrayOf(Location.create(2917, 3175, 0), "karamja"), + arrayOf(Location.create(2450, 5165, 0), "tzhaar"), + arrayOf(Location.create(2795, 3177, 0), "brimhaven"), + arrayOf(Location.create(2849, 2961, 0), "shilo village", "shilo"), + arrayOf(Location.create(2605, 3093, 0), "yanille"), + arrayOf(Location.create(2663, 3305, 0), "ardougne", "ardy"), + arrayOf(Location.create(2450, 3422, 0), "gnome stronghold", "gnome"), + arrayOf(Location.create(2730, 3485, 0), "camelot", "cammy", "seers"), + arrayOf(Location.create(2805, 3435, 0), "catherby"), + arrayOf(Location.create(2659, 3657, 0), "rellekka"), + arrayOf(Location.create(2890, 3676, 0), "trollheim"), + arrayOf(Location.create(2914, 3746, 0), "godwars", "gwd", "god wars"), + arrayOf(Location.create(3180, 3684, 0), "bounty hunter", "bh"), + arrayOf(Location.create(3272, 3687, 0), "clan wars", "clw"), + arrayOf(Location.create(3090, 3957, 0), "mage arena", "mage", "magearena", "arena"), + arrayOf(Location.create(3069, 10257, 0), "king black dragon", "kbd"), + arrayOf(Location.create(3359, 3416, 0), "digsite"), + arrayOf(Location.create(3488, 3489, 0), "canifis"), + arrayOf(Location.create(3428, 3526, 0), "slayer tower", "slayer"), + arrayOf(Location.create(3502, 9483, 2), "kalphite queen", "kq", "kalphite hive", "kalphite"), + arrayOf(Location.create(3233, 2913, 0), "pyramid"), + arrayOf(Location.create(3419, 2917, 0), "nardah"), + arrayOf(Location.create(3482, 3090, 0), "uzer"), + arrayOf(Location.create(3358, 2970, 0), "pollnivneach", "poln"), + arrayOf(Location.create(3305, 2788, 0), "sophanem"), + arrayOf(Location.create(2898, 3544, 0), "burthorpe", "burthorp"), + arrayOf(Location.create(3088, 3491, 0), "edge", "edgeville"), + arrayOf(Location.create(3169, 3034, 0), "bedabin"), + arrayOf(Location.create(3565, 3289, 0), "barrows"), + arrayOf(Location.create(3016, 3513, 0), "bkf", "black knights fortress"), + arrayOf(Location.create(3052, 3481, 0), "monastery"), + arrayOf(Location.create(1945, 4959, 0), "blast furnace", "blast"), + arrayOf(Location.create(2408, 4449, 0), "zanaris"), + arrayOf(Location.create(3656, 3517, 0), "ectofuntus", "ecto"), + arrayOf(Location.create(2408, 4449, 0), "tower of life lower"), + arrayOf(Location.create(2894, 4756, 0), "test area"), + arrayOf(Location.create(2722, 4886, 0), "quest the golem 1"), + arrayOf(Location.create(2704, 5349, 0), "dorgeshuun", "dorg"), + arrayOf(Location.create(2711, 10132, 0), "brine rats"), + arrayOf(Location.create(2328, 3677, 0), "piscatoris"), + arrayOf(Location.create(2660, 3158, 0), "fishing trawler", "trawler"), + arrayOf(Location.create(2800, 3667, 0), "mountain camp"), + arrayOf(Location.create(2575, 3250, 0), "clocktower"), + arrayOf(Location.create(2544, 3759, 0), "waterbirth"), + arrayOf(Location.create(2899, 4450, 0), "dks"), + arrayOf(CastleWars.lobbyBankArea.randomLoc, "cwars", "castle wars", "castle war", "castlewars", "castlewar", "castle") + ) + + @JvmField + var DATABASE: Database? = null + + //if SQL is enabled + @JvmField + var MYSQL = true + + //the server name + @JvmField + var SERVER_NAME: String = "" + + //the server's grand exchange name + @JvmField + var SERVER_GE_NAME: String = "" + + //The RSA_KEY for the server. + @JvmField + var EXPONENT = BigInteger("52317200263721308660411803146360972546561037484450290559823448967617618536819222494429186211525706853703641369936136465589036631055945454547936148730495933263344792588795811788941129493188907621550836988152620502378278134421731002382361670176785306598134280732756356458964850508114958769985438054979422820241") + + //The MODULUS for the server. + @JvmField + var MODULUS = BigInteger("96982303379631821170939875058071478695026608406924780574168393250855797534862289546229721580153879336741968220328805101128831071152160922518190059946555203865621183480223212969502122536662721687753974815205744569357388338433981424032996046420057284324856368815997832596174397728134370577184183004453899764051") + + @JvmField + var DAILY_RESTART = false + + @JvmField + var DISCORD_GE_WEBHOOK = "" + + @JvmField + var DISCORD_MOD_WEBHOOK = "" + + @JvmField + var DISCORD_OPENRSC_HOOK = "" + + @JvmField + var PRELOAD_MAP = false + + @JvmField + var USE_AUTH = false + + @JvmField + var PERSIST_ACCOUNTS = false + + @JvmField + var DRAGON_AXE_USE_OSRS_SPEC = false + + @JvmField + var ENABLE_GLOBALCHAT = false + + @JvmField + var MAX_PATHFIND_DISTANCE = 25 + + @JvmField + var IRONMAN_ICONS = false + + @JvmField + var PLAYER_STOCK_CLEAR_INTERVAL = 1 + + @JvmField + var PLAYER_STOCK_RECIRCULATE = true + + @JvmField + var BOTSTOCK_LIMIT = 5000 + + @JvmField + var BETTER_AGILITY_PYRAMID_GP = true + + @JvmField + var BETTER_DFS = true + + @JvmField + var NEW_PLAYER_ANNOUNCEMENT = true + + @JvmField + var HOLIDAY_EVENT_RANDOMS = true + + @JvmField + var FORCE_HALLOWEEN_EVENTS = false + + @JvmField + var FORCE_CHRISTMAS_EVENTS = false + + @JvmField + var FORCE_EASTER_EVENTS = false + + @JvmField + var RUNECRAFTING_FORMULA_REVISION = 581 + + @JvmField + var ENHANCED_DEEP_WILDERNESS = false + + @JvmField + var STARTUP_MOMENT = Calendar.getInstance() + + @JvmField + var CONNECTIVITY_CHECK_URL = "https://google.com,https://2009scape.org" + + @JvmField + var CONNECTIVITY_TIMEOUT = 500 + } +} diff --git a/Server/src/main/core/ServerStore.kt b/Server/src/main/core/ServerStore.kt new file mode 100644 index 0000000..52df7fb --- /dev/null +++ b/Server/src/main/core/ServerStore.kt @@ -0,0 +1,216 @@ +package core + +import core.api.PersistWorld +import core.api.getItemName +import core.api.log +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.tools.Log +import org.json.simple.JSONArray +import org.json.simple.JSONObject +import org.json.simple.parser.JSONParser +import core.tools.SystemLogger +import core.tools.SystemLogger.logShutdown +import core.tools.SystemLogger.logStartup +import java.io.File +import java.io.FileReader +import java.io.FileWriter +import javax.script.ScriptEngineManager + +class ServerStore : PersistWorld { + override fun parse() { + logStartup("Parsing server store...") + val dir = File(ServerConstants.STORE_PATH!!) + if(!dir.exists()){ + dir.mkdirs() + return + } + + var parser: JSONParser + var reader: FileReader + + dir.listFiles()?.forEach { storeFile -> + val key = storeFile.nameWithoutExtension + + reader = FileReader(storeFile) + parser = JSONParser() + + try { + val data = parser.parse(reader) as JSONObject + fileMap[key] = data + counter++ + } catch (e: Exception){ + log(this::class.java, Log.ERR, "Failed parsing ${storeFile.name} - stack trace below.") + e.printStackTrace() + return@forEach + } + } + + logStartup("Initialized $counter store files.") + } + + override fun save() { + logShutdown("Saving server store...") + val dir = File(ServerConstants.DATA_PATH + File.separator + "serverstore") + if(!dir.exists()){ + dir.mkdirs() + return + } + + val manager = ScriptEngineManager() + val scriptEngine = manager.getEngineByName("JavaScript") + + fileMap.forEach { (name, data) -> + val path = dir.absolutePath + File.separator + name + ".json" + + scriptEngine.put("jsonString", data.toJSONString()) + scriptEngine.eval("result = JSON.stringify(JSON.parse(jsonString), null, 2)") + val prettyPrintedJson = scriptEngine["result"] as String + + FileWriter(path).use { it.write(prettyPrintedJson); it.flush(); it.close() } + } + } + + companion object { + val fileMap = HashMap() + var counter = 0 + + @JvmStatic + fun getArchive(name: String): JSONObject { + if(fileMap[name] == null){ + fileMap[name] = JSONObject() + } + + return fileMap[name]!! + } + + fun setArchive(name: String, data: JSONObject){ + fileMap[name] = data + } + + fun clearDailyEntries() { + fileMap.keys.toTypedArray().forEach { + if(it.toLowerCase().contains("daily")) fileMap[it]?.clear() + } + } + + fun clearWeeklyEntries() { + fileMap.keys.toTypedArray().forEach { + if(it.toLowerCase().contains("weekly")) fileMap[it]?.clear() + } + } + + @JvmStatic + fun JSONObject.getInt(key: String, default: Int = 0): Int { + return when(val value = this[key]){ + is Long -> value.toInt() + is Double -> value.toInt() + is Float -> value.toInt() + is Int -> value + is Nothing -> default + else -> default + } + } + + @JvmStatic + fun JSONObject.getString(key: String, default: String = "nothing"): String { + return this[key] as? String ?: default + } + + @JvmStatic + fun JSONObject.getLong(key: String, default: Long = 0L): Long { + return this[key] as? Long ?: default + } + + @JvmStatic + fun JSONObject.getBoolean(key: String, default: Boolean = false): Boolean { + return this[key] as? Boolean ?: default + } + + fun List.toJSONArray(): JSONArray{ + val jArray = JSONArray() + for(i in this){ + jArray.add(i) + } + return jArray + } + + inline fun JSONObject.getList(key: String) : List { + val array = this[key] as? JSONArray ?: JSONArray() + val list = ArrayList() + for(element in array) list.add(element as T) + return list + } + + fun JSONObject.addToList(key: String, value: Any) { + val array = this.getOrPut(key) {JSONArray()} as JSONArray + array.add(value) + } + + /** NPCItemMemory + * These next methods handle the NPCItemMemory database. these are server-stored JSON objects, + * which are based on an npc and an item. + * each NPC can have a JSON object for itself for any item. + * the NPC Item object can store integer values for individual players, using their names as keys. + * the first methods handle the serverstore filename and accessing the JSON object. + * these methods are wrapped by more convenient ones that allow access for a particular player, see below. + */ + fun NPCItemFilename(npc: Int, item: Int, period: String = "daily"): String { + val itemName = getItemName(item).lowercase().replace(" ","-") + val npcName = NPC(npc).name.lowercase() + return "$period-$npcName-$itemName" + } + fun NPCItemMemory(npc: Int, item: Int, period: String = "daily"): JSONObject { + return getArchive(NPCItemFilename(npc,item,period)) + } + + /** NPCItemMemory Player Access + * These next functions handle individual player access to the NPC Item Memory database. + * each of the functions has at least 3 mandatory arguments: npc, item, player. + * These functions can be used to allow players to access a daily- or weekly-reset stock of a particular item overseen by a particular NPC. + * + * note that none of these functions perform tangible actions on the player. + * whoever calls these functions is responsible for handling tangible actions like putting items in an inventory. + * these functions simply return and update the NPCItemMemory database numbers in useful ways. + */ + + /** getNPCItemStock: + * gets the available stock of a particular item at a particular NPC for a particular player. + */ + fun getNPCItemStock(npc: Int, item: Int, limit: Int, player: Player, period: String = "daily"): Int { + val itemMemory = NPCItemMemory(npc,item) + val key = player.name + var stock = limit-itemMemory.getInt(key) + stock = maxOf(stock,0) + return stock + } + /** getNPCItemAmount: + * gets the usable amount of a particular item from a particular npc for a particular player. + * this is essentially just a requested amount cut to conform to stock and nonnegative requirements. + * what this function does is it takes a requested amount, cuts it down to be equal to available stock if + * available stock is less than the requested amount, and then additionally sets a minimum of 0. + */ + fun getNPCItemAmount(npc: Int, item: Int, limit: Int, player: Player, amount: Int, period: String = "daily"): Int { + val stock = getNPCItemStock(npc,item,limit,player,period) + var realamount = minOf(amount,stock) + realamount = maxOf(realamount,0) + return realamount + } + /** addNPCItemAmount: + * this function updates the NPC Item Memory database entry for a particular player. + * it is intended to be called after all the actions that use the number have been successfully completed. + * this function will *add* the amount argument to the current npc item memory entry for that player. this means that + * the amount argument is the amount to add, not the absolute final amount. + * this function will handle correctly setting the limit and any other required semantics. + */ + fun addNPCItemAmount(npc: Int, item: Int, limit: Int, player: Player, amount: Int, period: String = "daily") { + val itemMemory = NPCItemMemory(npc,item,period) + val key = player.name + var realamount = itemMemory.getInt(key) + amount + realamount = minOf(realamount,limit) + realamount = maxOf(realamount,0) + itemMemory[key] = realamount + } + } +} + diff --git a/Server/src/main/core/Util.java b/Server/src/main/core/Util.java new file mode 100644 index 0000000..5bb17aa --- /dev/null +++ b/Server/src/main/core/Util.java @@ -0,0 +1,55 @@ +package core; + +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; + +public class Util { + + /** + * Capitalize the first letter of the string + * @return Capitalized string + */ + public static String capitalize(String name) { + if (name != null && name.length() != 0) { + char[] chars = name.toCharArray(); + chars[0] = Character.toUpperCase(chars[0]); + return new String(chars); + } else { + return name; + } + } + + public static String strToEnum(String name) { + name = name.toUpperCase(); + return name.replaceAll(" ", "_"); + } + + public static String enumToString(String name) { + name = name.toLowerCase(); + name = name.replaceAll("_", " "); + return capitalize(name); + } + + public static double clamp(double input, double min, double max) { + return Math.max(Math.min(input, max), min); + } + public static int clamp(int input, int min, int max) { + return Math.max(Math.min(input, max), min); + } + + public static long nextMidnight(long currentTime) { + Date date = new Date(); + Calendar cal = Calendar.getInstance(); + + date.setTime(currentTime); + cal.setTime(date); + cal.set(Calendar.HOUR_OF_DAY, 0); + cal.set(Calendar.MINUTE, 0); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + cal.add(Calendar.HOUR_OF_DAY, 24); + + return cal.getTime().getTime(); + } +} diff --git a/Server/src/main/core/api/ApiExtensions.kt b/Server/src/main/core/api/ApiExtensions.kt new file mode 100644 index 0000000..fc8efda --- /dev/null +++ b/Server/src/main/core/api/ApiExtensions.kt @@ -0,0 +1,66 @@ +package core.api + +import core.game.node.item.Item +import java.util.* +import kotlin.collections.ArrayList + +fun IntProgression.toIntArray(): IntArray { + val result = IntArray((last - first) / step + 1) + forEachIndexed { index, i -> result[index] = i } + return result +} + +fun Int.asItem() : Item { + return Item(this) +} + +fun Collection.toIntArray() : IntArray { + val list = ArrayList() + this.forEach { arr -> arr.forEach { list.add(it) } } + return list.toIntArray() +} + +inline fun Collection.isLast(element: T) : Boolean { + return this.indexOf(element) == this.size - 1 +} + +inline fun Collection.getNext(element: T) : T { + val idx = this.indexOf(element) + return if (idx < this.size - 1) + this.elementAt(idx + 1) + else + element +} + +inline fun Collection.isNextLast(element: T) : Boolean { + return this.isLast(this.getNext(element)) +} + +fun IntArray.isLast(element: Int) : Boolean { + return this.indexOf(element) == this.size - 1 +} + +fun IntArray.getNext(element: Int) : Int { + val idx = this.indexOf(element) + return if (idx < this.size - 1) + this.elementAt(idx + 1) + else + element +} + +fun IntArray.isNextLast(element: Int) : Boolean { + return this.isLast(this.getNext(element)) +} + +fun LinkedList.tryPop(default: T?) : T? { + this.peek() ?: return default + return this.pop() +} + +inline fun > parseEnumEntry(name: String) : E? { + return try { + enumValueOf(name) + } catch (e: Exception) { + null + } +} \ No newline at end of file diff --git a/Server/src/main/core/api/Commands.kt b/Server/src/main/core/api/Commands.kt new file mode 100644 index 0000000..231adc1 --- /dev/null +++ b/Server/src/main/core/api/Commands.kt @@ -0,0 +1,52 @@ +package core.api + +import core.game.node.entity.player.Player +import core.game.system.command.Command +import core.game.system.command.CommandMapping +import core.game.system.command.Privilege +import core.tools.Log +import core.tools.colorize + +/** + * An interface for writing content that allows the class to define commands. + * + * Includes methods [reject] and [notify] for notifying the player of a command rejection or some output text respectively. + * + * Includes the method [define] to define individual commands + * + * Commands should ideally be defined in the required [defineCommands] method. + */ +interface Commands : ContentInterface { + /** + * Glorified player.sendMessage with red text coloring. Please use this + * rather than just player.sendMessage for anything that involves informing the player + * of proper usage or invalid syntax. Throws an IllegalStateException and ends command execution immediately. + */ + fun reject(player: Player, vararg message: String){ + for(msg in message) { + player.sendMessage(colorize("-->%R$msg")) + } + throw IllegalStateException() + } + + /** + * Glorified player.sendMessage with black text coloring and an arrow. Use this when you need to + * notify/inform a player of some information from within the command without ending execution. + */ + fun notify(player: Player, message: String, logToConsole: Boolean = false){ + if (logToConsole) + log (this::class.java, Log.DEBUG, message) + player.sendMessage(colorize("-->$message")) + } + + /** + * Used to define commands. define("name",(optional) privilege override){ handle } + * @param name the name of the command. Example: ::example would be just "example" + * @param privilege the rights level needed to execute the command. Options are [Privilege.STANDARD], [Privilege.MODERATOR], [Privilege.ADMIN]. Defaults to [Privilege.STANDARD] + */ + fun define(name: String, privilege: Privilege = Privilege.ADMIN, usage: String = "", description: String = "", handle: (Player, Array) -> Unit){ + CommandMapping.register(Command(name, privilege, usage, description, handle)) + } + + fun defineCommands() +} diff --git a/Server/src/main/core/api/Container.kt b/Server/src/main/core/api/Container.kt new file mode 100644 index 0000000..590d94a --- /dev/null +++ b/Server/src/main/core/api/Container.kt @@ -0,0 +1,7 @@ +package core.api + +enum class Container { + INVENTORY, + BANK, + EQUIPMENT +} \ No newline at end of file diff --git a/Server/src/main/core/api/ContentAPI.kt b/Server/src/main/core/api/ContentAPI.kt new file mode 100644 index 0000000..f11ca49 --- /dev/null +++ b/Server/src/main/core/api/ContentAPI.kt @@ -0,0 +1,3195 @@ +package core.api + +import com.moandjiezana.toml.Toml +import content.data.Quests +import content.data.consumables.* +import content.data.skill.SkillingTool +import content.global.handlers.iface.ge.StockMarket +import content.global.skill.slayer.SlayerEquipmentFlags +import content.global.skill.slayer.SlayerManager +import content.global.skill.slayer.Tasks +import content.global.skill.summoning.familiar.BurdenBeast +import core.ServerConstants +import core.api.utils.PlayerStatsCounter +import core.api.utils.Vector +import core.cache.def.impl.AnimationDefinition +import core.cache.def.impl.ItemDefinition +import core.cache.def.impl.SceneryDefinition +import core.cache.def.impl.VarbitDefinition +import core.game.activity.Cutscene +import core.game.component.Component +import core.game.consumable.* +import core.game.container.impl.EquipmentContainer +import core.game.dialogue.DialogueFile +import core.game.dialogue.SkillDialogueHandler +import core.game.ge.GrandExchangeRecords +import core.game.interaction.* +import core.game.node.Node +import core.game.node.entity.Entity +import core.game.node.entity.combat.CombatSwingHandler +import core.game.node.entity.combat.ImpactHandler +import core.game.node.entity.impl.Animator +import core.game.node.entity.impl.ForceMovement +import core.game.node.entity.impl.Projectile +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.player.info.LogType +import core.game.node.entity.player.info.PlayerMonitor +import core.game.node.entity.player.link.HintIconManager +import core.game.node.entity.player.link.IronmanMode +import core.game.node.entity.player.link.TeleportManager +import core.game.node.entity.player.link.audio.Audio +import core.game.node.entity.player.link.emote.Emotes +import core.game.node.entity.player.link.prayer.PrayerType +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.player.link.quest.QuestRepository +import core.game.node.entity.skill.Skills +import core.game.node.item.GroundItem +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import core.game.node.scenery.Scenery +import core.game.node.scenery.SceneryBuilder +import core.game.requirement.* +import core.game.shops.Shops +import core.game.system.config.ItemConfigParser +import core.game.system.config.ServerConfigParser +import core.game.system.task.Pulse +import core.game.system.timer.* +import core.game.system.timer.impl.* +import core.game.world.GameWorld +import core.game.world.GameWorld.Pulser +import core.game.world.map.Direction +import core.game.world.map.Location +import core.game.world.map.RegionManager +import core.game.world.map.RegionManager.getRegionChunk +import core.game.world.map.path.Pathfinder +import core.game.world.map.zone.MapZone +import core.game.world.map.zone.ZoneBorders +import core.game.world.map.zone.ZoneBuilder +import core.game.world.repository.Repository +import core.game.world.update.flag.* +import core.game.world.update.flag.chunk.AnimateObjectUpdateFlag +import core.game.world.update.flag.context.* +import core.net.packet.PacketRepository +import core.net.packet.context.DefaultContext +import core.net.packet.context.MusicContext +import core.net.packet.out.AudioPacket +import core.net.packet.out.MusicPacket +import core.tools.* +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import org.rs09.consts.Sounds +import java.io.* +import java.util.regex.* +import kotlin.math.* + +/** + * Gets a skilling tool which the player has the level to use and is in their inventory. + * @param player the player to get the tool for + * @param pickaxe whether or not we are trying to get a pickaxe. + * @return the tool which meets the requirements or null if none. + */ +fun getTool(player: Player, pickaxe: Boolean): SkillingTool? { + return if (pickaxe) SkillingTool.getPickaxe(player) else SkillingTool.getHatchet(player) +} + +/** + * Check if a player has a given level (buffable/debuffable) + * @param player the player to check the stat for + * @param skill the Skill to check. There is an enum for this called Skills. Example: Skills.STRENGTH + * @param level the level to check against + * @return true if the check succeeds, false otherwise + */ +fun hasLevelDyn(player: Player, skill: Int, level: Int): Boolean { + return player.skills.getLevel(skill) >= level +} + +/** + * Check if a player's static skill level meets a certain value + * @param player the player to check the stat for + * @param skill the Skill to check. There is an enum for this called Skills. Example: Skills.STRENGTH + * @param level the level to check against + * @return true if the check succeeds, false otherwise + */ +fun hasLevelStat(player: Player, skill: Int, level: Int): Boolean { + return player.skills.getStaticLevel(skill) >= level +} + +/** + * Check the amount of a given item in the player's inventory + * @param player the player whose inventory to check + * @param id the ID of the item to check for the amount of + * @return the amount of the given ID in the player's inventory + */ +fun amountInInventory(player: Player, id: Int): Int { + return player.inventory.getAmount(id) +} + +/** + * Check the amount of a given item in the player's bank + * @param player the player to check + * @param id the ID of the item to check for + * @param includeSecondary if the secondary bank should be included in the search + * @return the amount of the ID in the player's bank. + */ +fun amountInBank(player: Player, id: Int, includeSecondary: Boolean = true): Int { + return getAmountInBank(player, id) + if (includeSecondary) getAmountInBank(player, id, true) else 0 +} + +/** + * More performant way to check the amount of a given item in the player's bank + * Uses the alwaysStack property of banks to short circuit the search. + * @param player the player to check + * @param id the ID of the item to check for + * @param secondary if the secondary bank should be searched instead + * @return the amount of the ID in the player's bank. + */ +private fun getAmountInBank(player: Player, id: Int, secondary: Boolean = false): Int { + val bank = if (secondary) player.bankSecondary.toArray() else player.bankPrimary.toArray() + bank.forEach { if (it?.id == id) return it.amount } + return 0 +} + +/** + * Check the amount of a given item in the player's equipment slots + * @param player the player to check + * @param id the ID of the item to check for + * @return the amount of the ID in the player's equipment. + */ +fun amountInEquipment(player: Player, id: Int): Int { + val slot = itemDefinition(id).getConfiguration(ItemConfigParser.EQUIP_SLOT, -1) + val equipped = player.equipment[slot] ?: return 0 + return if (equipped.id == id) equipped.amount else 0 +} + +/** + * Check if an item exists in a player's inventory + * @param player the player whose inventory to check + * @param id the ID of the item to check for + * @param amount the amount to check for + * @return true if the player has >= the given item in the given amount, false otherwise. + */ +fun inInventory(player: Player, id: Int, amount: Int = 1): Boolean { + return player.inventory.contains(id, amount) +} + +/** + * Check if an item exists in a player's bank + * @param player the player whose bank to check + * @param id the ID of the item to check for + * @param amount the amount to check for, defaults to 1 + * @return true if the item exists in the given amount in the player's bank + */ +fun inBank(player: Player, id: Int, amount: Int = 1): Boolean { + return amountInBank(player, id) >= amount +} + +/** + * Check if an item exists in a player's equipment + * @param player the player whose equipment to check + * @param id the ID of the item to check for + * @param amount the amount to check for, defaults to 1 + * @return true if the item exists in the given amount in the player's equipment + */ +fun inEquipment(player: Player, id: Int, amount: Int = 1): Boolean { + return amountInEquipment(player, id) >= amount +} + +/** + * Check if any item is in a player's inventory + * @param player the player + * @param ids the set of item ids to check + * @return true if the player has at least one of the items in their inventory, false if none are present + */ +fun anyInInventory(player: Player, vararg ids: Int): Boolean { + return ids.any{ id -> + inInventory(player, id) + } +} + +/** + * Check if an item exists in a player's equipment or inventory + * @param player the player whose equipment to check + * @param id the ID of the item to check for + * @param amount the amount to check for, defaults to 1 + * @return true if the item exists in the given amount in the player's equipment or inventory + */ +fun inEquipmentOrInventory(player: Player, id: Int, amount: Int = 1): Boolean { + // Proper, but slower implementation. Use faster unless need to check amounts split between equip/inv + //return amountInEquipment(player, id) + amountInInventory(player, id) >= amount + return inEquipment(player, id, amount) || inInventory(player, id, amount) +} + +/** + * Check that a set of items is equipped by the given player + */ +fun allInEquipment(player: Player, vararg ids: Int): Boolean { + return ids.all { id -> + inEquipment(player, id) + } +} + +/** + * Check that at least one item from a set of items is equipped by the given player + * @param player the player + * @param ids the set of item ids to check + * @return true if the player has at least one of the items equipped, false if none are equipped + */ +fun anyInEquipment(player: Player, vararg ids: Int): Boolean { + return ids.any { id -> + inEquipment(player, id) + } +} + +/** + * Gets the item in the given equipment slot for the given player + * @param player the player whose equipment to pull from + * @param slot the Equipment slot to use, EquipmentSlot enum contains the options. + * @return the Item in the given slot, or null if none. + */ +fun getItemFromEquipment(player: Player, slot: EquipmentSlot): Item? { + return player.equipment.get(slot.ordinal) +} + +class ContainerisedItem(val container: core.game.container.Container?, val itemId: Int) { + fun remove() : Boolean { + return this.container?.remove(this.itemId.asItem()) ?: false + } + fun exists() : Boolean { + return this.container != null && this.itemId > -1 + } +} + +/** + * Check if player has the specified item ID equipped, in inventory, or in their bank + * @param id The item ID to check + * @return A ContainerisedItem containing the container and the item ID if found, otherwise ContainerisedItem(null, -1) if not found + */ +fun hasAnItem(player: Player, id: Int): ContainerisedItem { + return hasAnItem(player, arrayOf(id), false) +} + +/** + * Check if player has the specified item ID equipped, in inventory, or in their bank + * @param id The item ID to check + * @param checkSecondBank Whether to check the player's second bank. + * @return A ContainerisedItem containing the container and the item ID if found, otherwise ContainerisedItem(null, -1) if not found + */ +fun hasAnItem(player: Player, id: Int, checkSecondBank: Boolean): ContainerisedItem { + return hasAnItem(player, arrayOf(id), checkSecondBank) +} + +/** + * Check if player has any of the specified item IDs equipped, in inventory, or in their bank + * @param ids An array of item IDs to check + * @param checkSecondBank Whether to check the player's second bank. + * @return A ContainerisedItem containing the container and the item ID if found, otherwise ContainerisedItem(null, -1) if not found + */ +fun hasAnItem(player: Player, ids: Array, checkSecondBank: Boolean): ContainerisedItem { + val searchSpace = if (checkSecondBank) { + arrayOf(player.inventory, player.equipment, player.bankPrimary, player.bankSecondary) + } else { + arrayOf(player.inventory, player.equipment, player.bankPrimary) + } + for (container in searchSpace) { + for (id in ids) { + if (container.containItems(id)) { + return ContainerisedItem(container, id) + } + } + } + return ContainerisedItem(null, -1) +} + +/** + * Check if a player has an item equipped which corresponds to the given God + * @param player the player to check + * @param god the God whose equipment we are checking for + * @return true if the player has an item corresponding to the given god, false otherwise + */ +fun hasGodItem(player: Player, god: God): Boolean { + god.validItems.forEach { if (inEquipment(player, it)) return true } + return false +} + +/** + * Check if the given player should have the "remove nothing" RoW effect active. + * @param player the player we are checking + * @return whether we should ignore nothings + */ +fun shouldRemoveNothings(player: Player) : Boolean { + val ring = getItemFromEquipment(player, EquipmentSlot.RING) + return ring != null && ring.id in Items.RING_OF_WEALTH_14638..Items.RING_OF_WEALTH4_14646 +} + +/** + * Remove an item from a player's inventory + * @param player the player whose inventory to remove the item from + * @param item the ID or Item object to remove from the player's inventory + * @param container the Container to remove the items from. An enum exists for this in the api package called Container. Ex: api.Container.BANK + */ +fun removeItem(player: Player, item: T, container: Container = Container.INVENTORY): Boolean { + item ?: return false + val it = when (item) { + is Item -> item + is Int -> Item(item) + else -> throw IllegalStateException("Invalid value passed for item") + } + + return when (container) { + Container.INVENTORY -> player.inventory.remove(it) + Container.BANK -> player.bank.remove(it) || player.bankSecondary.remove(it) + Container.EQUIPMENT -> player.equipment.remove(it) + } +} + +/** + * Add an item to the given player's given container + * @param player the player whose container to modify + * @param id the ID of the item to add + * @param amount the amount of the item to add + * @param container the Container to modify + * @return true if the item was successfully added + */ +fun addItem(player: Player, id: Int, amount: Int = 1, container: Container = Container.INVENTORY): Boolean { + val cont = when (container) { + Container.INVENTORY -> player.inventory + Container.BANK -> player.bank + Container.EQUIPMENT -> player.equipment + } + + return cont.add(Item(id, amount)) +} + +/** + * Replaces the item in the given slot in the given container with the given item. + * @param player the player whose container to modify + * @param slot the slot to use + * @param item the item to replace the slot with + * @param currentItem the current item that is being replaced + * @param container the Container to modify + * @return the item that was previously in the slot, or null if none. + */ +fun replaceSlot(player: Player, slot: Int, item: Item, currentItem: Item? = null, container: Container = Container.INVENTORY): Item? { + val cont = when (container) { + Container.INVENTORY -> player.inventory + Container.EQUIPMENT -> player.equipment + Container.BANK -> player.bank + } + + if (item.id == 65535 || item.amount <= 0) { + return cont.replace(null, slot) + } + + if (currentItem == null) { + return cont.replace(item, slot) + } + + if (cont.remove(currentItem, slot, true)) { + return cont.replace(item, slot) + } + + PlayerMonitor.log(player, LogType.DUPE_ALERT, "Potential slot-replacement-based dupe attempt, slot: $slot, item: $item") + val other = when (container) { + Container.INVENTORY -> Container.EQUIPMENT + else -> Container.INVENTORY + } + if (removeItem(player, currentItem, other)) + return cont.replace(item, slot) + return null +} + +/** + * Replaces all items a player owns anywhere (equipment, inventory, bank, second bank) + * @param player the player whose inventory to remove the item from + * @param itemId the item ID to replace + * @param replaceId the replacement item ID + * @author Player Name + */ +fun replaceAllItems(player: Player, itemId: Int, replaceId: Int) { + val item = Item(itemId) + val containers = if (player.familiarManager.hasFamiliar() && player.familiarManager.familiar.isBurdenBeast()) { + arrayOf(player.inventory, player.equipment, player.bankPrimary, player.bankSecondary, (player.familiarManager.familiar as BurdenBeast).container) + } else { + arrayOf(player.inventory, player.equipment, player.bankPrimary, player.bankSecondary) + } + for (container in containers) { + val hasItems = container.getAll(item) + if (!item.definition.isStackable && container != player.bankPrimary && container != player.bankSecondary) { + // just replace + for (target in hasItems) { + val newItem = Item(replaceId, target.amount) + container.replace(newItem, target.slot, true) + } + } else { + // add to existing stack if possible + if (hasItems.size > 0) { + val target = hasItems[0] + var count = 0 + for (x in hasItems) { + count += x.amount + } + val newItem = Item(replaceId, count) + container.replace(newItem, target.slot, true) + } + if (hasItems.size > 1) { + for (i in 1 until hasItems.size) { + container.remove(hasItems[i], hasItems[i].slot, true) + } + } + } + } +} + +/** + * Add an item with a variable quantity or drop it if a player does not have enough space + * @param player the player whose inventory to add to + * @param id the ID of the item to add to the player's inventory + * @param amount the amount of the ID to add to the player's inventory, defaults to 1 + */ +fun addItemOrDrop(player: Player, id: Int, amount: Int = 1) { + val item = Item(id, amount) + if(amount == 1 || item.definition.isStackable) { + if (!player.inventory.add(item)) GroundItemManager.create(item, player) + } else { + val singleItem = Item(id, 1) + for(i in 0 until amount) { + if(!player.inventory.add(singleItem)) GroundItemManager.create(singleItem, player) + } + } +} + +/** + * Add an item with a variable quantity or bank it if a player does not have enough space, or drop it if that still doesn't work + * @param player the player whose inventory to add to + * @param id the ID of the item to add to the player's inventory + * @param amount the amount of the ID to add to the player's inventory, defaults to 1 + */ +fun addItemOrBank(player: Player, id: Int, amount: Int = 1) { + val item = Item(id, amount) + if (!player.inventory.add(item)) { + if (player.ironmanManager.mode != IronmanMode.ULTIMATE && player.bankPrimary.add(item)) { + sendMessage(player, colorize("%RThe ${item.name} has been sent to your bank.")) + } else if (player.ironmanManager.mode != IronmanMode.ULTIMATE && player.bankSecondary.add(item)) { + sendMessage(player, colorize("%RThe ${item.name} has been sent to your secondary bank.")) + } else { + GroundItemManager.create(item, player) + sendMessage(player, colorize("%RAs your inventory and bank account(s) are all full, the ${item.name} has been placed on the ground under your feet. Don't forget to grab it. (Also consider cleaning out some stuff, maybe? I mean, Jesus!)")) + } + } +} + +/** + * Clears an NPC with the "poof" smoke graphics commonly seen with random event NPCs. + * @param npc the NPC object to initialize + */ +fun poofClear(npc: NPC) { + submitWorldPulse(object : Pulse() { + var counter = 0 + override fun pulse(): Boolean { + when (counter++) { + 2 -> { + npc.isInvisible = true; Graphics.send(Graphics(86), npc.location) + } + 3 -> npc.clear().also { return true } + } + return false + } + }) +} + +/** + * Get number of free slots in a player's inventory + * @param player the player to check + * @return the number of free slots in the player's inventory + */ +fun freeSlots(player: Player): Int { + return player.inventory.freeSlots() +} + +/** + * Get an animation by ID. + * @param id the ID of the animation to use + * @return an Animation object with the given ID. + */ +fun getAnimation(id: Int): Animation { + return Animation(id) +} + +/** + * Get an animation by ID with priority + * @param id the ID of the animation to get + * @param priority the Animator.Priority enum instance to represent the desired priority + * @return an Animation object with the given ID and priority + */ +fun getAnimationWithPriority(id: Int, priority: Animator.Priority): Animation { + return Animation(id, Animator.Priority.values()[priority.ordinal]) +} + +/** + * Reset a player's animator + * @param player the player whose animator to reset + */ +fun resetAnimator(player: Player) { + player.animator.animate(Animation(-1, Animator.Priority.VERY_HIGH)) +} + +/** + * Get the number of ticks an animation lasts + * @param animation the Animation object to check the duration of + * @return the number of ticks the given animation lasts for + */ +fun animationDuration(animation: Animation): Int { + return animation.definition.durationTicks +} + +fun animationCycles (animation: Int) : Int { + val def = AnimationDefinition.forId(animation) + return def.cycles +} + +/** + * Give a player some amount of experience in a specific skill + * @param player the player to award XP to + * @param skill the Skill ID to reward XP for. There is a Skills enum you can use for this. Example: Skills.STRENGTH + * @param amount the amount, including decimal place, of experience to award + */ +fun rewardXP(player: Player, skill: Int, amount: Double) { + player.skills.addExperience(skill, amount) +} + +/** + * Replace an object with the given revert timer + * @param toReplace the Scenery instance we are replacing + * @param with the ID of the Scenery we wish to replace toReplace with + * @param forTicks the number of ticks the object should be replaced for. Use -1 for permanent. + * @param loc the location to move the new object to if necessary. Defaults to null. + */ +fun replaceScenery(toReplace: Scenery, with: Int, forTicks: Int, loc: Location? = null) { + val newLoc = when (loc) { + null -> toReplace.location + else -> loc + } + if (forTicks == -1) { + SceneryBuilder.replace(toReplace, toReplace.transform(with, toReplace.rotation, newLoc)) + } else { + SceneryBuilder.replace(toReplace, toReplace.transform(with, toReplace.rotation, newLoc), forTicks) + } + toReplace.isActive = false +} + +/** + * Add a scenery to the world + * @param sceneryId the ID of the scenery to add + * @param location the location to place it at + * @param rotation the rotation of the scenery (default 0) + * @param type the type of the scenery (default 22) + * @return the created scenery +*/ +fun addScenery (sceneryId: Int, location: Location, rotation: Int = 0, type: Int = 22) : Scenery { + val scenery = Scenery(sceneryId, location, type, rotation) + SceneryBuilder.add(scenery) + return scenery +} + +fun addScenery (scenery: Scenery) { + SceneryBuilder.add(scenery) +} + +/** + * Remove a scenery from the world + * @param scenery the Scenery object to remove. +*/ +fun removeScenery (scenery: Scenery) { + SceneryBuilder.remove(scenery) +} + +/** + * Replace an object with the given revert timer with the given rotation + * @param toReplace the Scenery instance we are replacing + * @param with the ID of the Scenery we wish to replace toReplace with + * @param forTicks the number of ticks the object should be replaced for. Use -1 for permanent. + * @Param rotation the Direction of the rotation it should use. Direction.NORTH, Direction.SOUTH, etc + * @param loc the location to move the new object to if necessary. Defaults to null. + */ +fun replaceScenery(toReplace: Scenery, with: Int, forTicks: Int, rotation: Direction, loc: Location? = null) { + val newLoc = when (loc) { + null -> toReplace.location + else -> loc + } + val rot = when (rotation) { + Direction.NORTH_WEST -> 0 + Direction.NORTH -> 1 + Direction.NORTH_EAST -> 2 + Direction.EAST -> 4 + Direction.SOUTH_EAST -> 7 + Direction.SOUTH -> 6 + Direction.SOUTH_WEST -> 5 + Direction.WEST -> 3 + } + if (forTicks == -1) { + SceneryBuilder.replace(toReplace, toReplace.transform(with, rot, newLoc)) + } else { + SceneryBuilder.replace(toReplace, toReplace.transform(with, rot, newLoc), forTicks) + } + toReplace.isActive = false +} + +/** + * Gets the name of an item. + * @param id the ID of the item to get the name of + * @return the name of the item + */ +fun getItemName(id: Int): String { + return ItemDefinition.forId(id).name +} + +/** + * Removes a ground item + * @param node the GroundItem object to remove + */ +fun removeGroundItem(node: GroundItem) { + GroundItemManager.destroy(node) +} + +/** + * Checks if a ground item is valid/still exists/should exist + * @param node the GroundItem object to check the validity of + * @return true if the node is valid, false otherwise + */ +fun isValidGroundItem(node: GroundItem): Boolean { + return GroundItemManager.getItems().contains(node) +} + +/** + * Checks if a player has space for an item + * @param player the player whose inventory to check + * @param item the Item to check against + * @return true if the player's inventory has space for the item + */ +fun hasSpaceFor(player: Player, item: Item): Boolean { + return player.inventory.hasSpaceFor(item) +} + +/** + * Get the number of ticks passed since server startup + */ +fun getWorldTicks(): Int { + return GameWorld.ticks +} + +/** + * Plays a jingle by id + * @param player the player to play the jingle for + * @param jingleId the jingle to play + */ +fun playJingle(player: Player, jingleId: Int) { + PacketRepository.send(MusicPacket::class.java, MusicContext(player, jingleId, true)) +} + +/** + * Impact an enemy with the given amount of damage and the given hitsplat type + * @param entity the entity to damage + * @param amount the amount of damage to deal + * @param type the type of hit splat to use, ImpactHandler.HitsplatType is an enum containing these options. + */ +fun impact(entity: Entity, amount: Int, type: ImpactHandler.HitsplatType = ImpactHandler.HitsplatType.NORMAL) { + entity.impactHandler.manualHit(entity, amount, type) + if (entity is Player) playHurtAudio(entity) +} + +/** + * Get an item's definition + * @param id the ID of the item to get the definition of + * @return the ItemDefinition for the given ID. + */ +fun itemDefinition(id: Int): ItemDefinition { + return ItemDefinition.forId(id) +} + +/** + * Check whether a node contains an interaction option. + * + * @param node: An NPC, a scenery object or an item to inspect. + * @param option: The name of the interaction option to check for existence of. + * + * @return A Boolean value indicating the presence of the specified option in the given node. + * + * @author vddCore + */ +fun hasOption(node: Node, option: String): Boolean { + return when (node) { + is NPC -> node.definition.hasAction(option) + is Scenery -> node.definition.hasAction(option) + is Item -> node.definition.hasAction(option) + else -> throw IllegalArgumentException("Expected an NPC, Scenery or an Item, got ${node.javaClass.simpleName}.") + } +} + +/** + * Send an object animation + */ +fun animateScenery(player: Player, obj: Scenery, animationId: Int, global: Boolean = false) { + player.packetDispatch.sendSceneryAnimation(obj, getAnimation(animationId), global) +} + +/** + * Send an object animation independent of a player + */ +fun animateScenery(obj: Scenery, animationId: Int) { + val animation = Animation(animationId) + animation.setObject(obj) + getRegionChunk(obj.location).flag(AnimateObjectUpdateFlag(animation)) +} + +/** + * Produce a ground item owned by the player + */ +fun produceGroundItem(player: Player, item: Int) { + GroundItemManager.create(Item(item), player) +} + +/** + * Produces a ground item with the given ID and amount at the given location + * @param owner the owner of the ground item, use null for none. + * @param id the id of the item. + * @param amount the amount of the item. + * @param location the location of the item. + * @return the created ground item. + */ +fun produceGroundItem(owner: Player?, id: Int, amount: Int, location: Location) : GroundItem { + return GroundItemManager.create(Item(id, amount), location, owner) +} + +/** + * Spawns a projectile + */ +fun spawnProjectile(source: Entity, dest: Entity, projectileId: Int) { + Projectile.create(source, dest, projectileId).send() +} + +/** + * Spawns a projectile with more advanced parameters + * @param source the initial Location of the projectile + * @param dest the final Location of the projectile + * @param projectile the ID of the gfx used for the projectile + * @param startHeight the height the projectile spawns at + * @param endHeight the height the projectile ends at + * @param delay the delay before the projectile spawns + * @param speed the speed the projectile travels at + * @param angle the angle the projectile travels at + */ +fun spawnProjectile( + source: Location, + dest: Location, + projectile: Int, + startHeight: Int, + endHeight: Int, + delay: Int, + speed: Int, + angle: Int +) { + Projectile.create( + source, + dest, + projectile, + startHeight, + endHeight, + delay, + speed, + angle, + source.getDistance(dest).toInt() + ).send() +} + +/** + * Causes the given entity to face the given toFace + * @param entity the entity you wish to face something + * @param toFace the thing to face + * @param duration how long you wish to face the thing for + */ +fun face(entity: Entity, toFace: Node, duration: Int = -1) { + if (duration == -1) { + when (toFace) { + is Location -> entity.faceLocation(toFace) + is Entity -> entity.face(toFace) + } + } else { + when (toFace) { + is Location -> entity.faceTemporary(toFace.asNpc(), duration) + else -> entity.faceTemporary(toFace as Entity, duration) + } + } +} + +/** + * Causes the given entity to reset its face direction. + * @param entity the entity to reset. +*/ +fun resetFace (entity: Entity) { + entity.face(null) + entity.faceLocation(entity.location) +} + +/** + * Opens the given interface for the given player + * @param player the player to open the interface for + * @param id the ID of the interface to open + */ +fun openInterface(player: Player, id: Int) { + player.interfaceManager.open(Component(id)) +} + +/** + * Opens the given interface as an overlay for the given player + * @param player the player to open the interface for + * @param id the ID of the interface to open + */ +fun openOverlay(player: Player, id: Int) { + player.interfaceManager.openOverlay(Component(id)) +} + +/** + * Closes any open overlays for the given player + * @param player the player to close for + */ +fun closeOverlay(player: Player) { + player.interfaceManager.closeOverlay() +} + +/** + * Runs the given Emote for the given Entity + * @param entity the entity to run the emote on + * @param emote the Emotes enum entry to run + */ +fun emote(entity: Entity, emote: Emotes) { + entity.animate(emote.animation) +} + +/** + * Sends a message to the given player. + * + * The message will be split on word boundaries into multiple lines so + * that none of the lines will overflow the player's message box. + * + * @param player the player to send the message to. + * @param message the message to send. + */ +fun sendMessage(player: Player, message: String) { + player.sendMessages(*splitLines(message, 86)) +} + +/** + * Forces an above-head chat message for the given entity + * @param entity the entity to send the chat for + * @param message the message to display + */ +fun sendChat(entity: Entity, message: String, delay: Int = -1) { + if (delay > -1) { + queueScript(entity, delay, QueueStrength.SOFT) { + entity.sendChat(message) + return@queueScript stopExecuting(entity) + } + } else entity.sendChat(message) +} + +/** + * Sends a message to a player's dialogue box + * @param player the player to send the dialogue to + * @param message the message to send, lines are split automatically. + */ +fun sendDialogue(player: Player, message: String) { + player.dialogueInterpreter.sendDialogue(*splitLines(message)) +} + +/** + * Sends a message to the player's dialogue box + * @param player the player to send the dialogue to + * @param lines the lines of dialogue to send. No automatic splitting. + */ +fun sendDialogueLines(player: Player, vararg message: String) { + player.dialogueInterpreter.sendDialogue(*message) +} + +/** + * Sends options dialogue to the given player. + * @param player the player to send the options to. + * @param title the title of the dialogue options + * @param options the options to present to the player + */ +fun sendDialogueOptions(player: Player, title: String, vararg options: String) { + player.dialogueInterpreter.sendOptions(title, *options) +} + +/** + * Plays an animation on the entity + * @param entity the entity to animate + * @param anim the animation to play, can be an ID or an Animation object. + * @param forced whether or not to force the animation (usually not necessary) + */ +fun animate(entity: Entity, anim: T, forced: Boolean = false) { + val animation = when (anim) { + is Int -> Animation(anim) + is Animation -> anim + else -> throw IllegalStateException("Invalid value passed for anim") + } + + if (forced) { + entity.animator.forceAnimation(animation) + } else { + entity.animator.animate(animation) + } +} + +/** + * Plays audio for the player + * @param player the player to play the defined audio for + * @param id the audio id to play + * @param delay the delay in client cycles (50 cycles = 1 second) + * @param loops the number of times to loop audio (for some audio ids it is used to define how many times to loop the audio) + * @param location the location where the audio will play from (The sound will fade with distance) + * @param radius the distance the audio can be heard from the defined location (default = 8 tiles if undefined) + */ +@JvmOverloads +fun playAudio(player: Player, id: Int, delay: Int = 0, loops: Int = 1, location: Location? = null, radius: Int = Audio.defaultAudioRadius) { + PacketRepository.send(AudioPacket::class.java, DefaultContext(player, Audio(id, delay, loops, radius), location)) +} + +/** + * Plays audio for players near a defined location + * @param location the location where the audio will play from (The sound will fade with distance) + * @param id the audio id to play + * @param delay the delay in client cycles (50 cycles = 1 second) + * @param loops the number of times to loop audio (for some audio ids it is used to define how many times to loop the audio) + * @param radius the distance the audio can be heard from the defined location (default = 8 tiles if undefined) + */ +@JvmOverloads +fun playGlobalAudio(location: Location, id: Int, delay: Int = 0, loops: Int = 1, radius: Int = Audio.defaultAudioRadius) { + val nearbyPlayers = RegionManager.getLocalPlayers(location, radius) + for (player in nearbyPlayers) { + PacketRepository.send(AudioPacket::class.java, DefaultContext(player, Audio(id, delay, loops, radius), location)) + } +} + +/** + * Plays a random hurt audio for the player based on gender + * @param player the player to play hurt audio for + * @param delay the delay in client cycles (50 cycles = 1 second) + */ +fun playHurtAudio(player: Player, delay: Int = 0) { + val maleHurtAudio = intArrayOf(Sounds.HUMAN_HIT4_516, Sounds.HUMAN_HIT5_517, Sounds.HUMAN_HIT_518, Sounds.HUMAN_HIT_6_522) + val femaleHurtAudio = intArrayOf(Sounds.FEMALE_HIT_506, Sounds.FEMALE_HIT_507, Sounds.FEMALE_HIT2_508, Sounds.FEMALE_HIT_2_510) + if (player.isMale) { + playAudio(player, maleHurtAudio.random(), delay) + } else { + playAudio(player, femaleHurtAudio.random(), delay) + } +} + +/** + * Opens a dialogue with the given dialogue key or dialogue file, depending which is passed. + * @param player the player to open the dialogue for + * @param dialogue either the dialogue key or an instance of a DialogueFile + * @param args various args to pass to the opened dialogue + */ +fun openDialogue(player: Player, dialogue: Any, vararg args: Any) { + player.dialogueInterpreter.close() + when (dialogue) { + is Int -> player.dialogueInterpreter.open(dialogue, *args) + is DialogueFile -> player.dialogueInterpreter.open(dialogue, *args) + is SkillDialogueHandler -> dialogue.open() + else -> log(ContentAPI::class.java, Log.ERR, "Invalid object type passed to openDialogue() -> ${dialogue.javaClass.simpleName}") + } +} + +/** + * Closes any opened dialogue. + */ +fun closeDialogue(player: Player) { + player.dialogueInterpreter.close() + player.interfaceManager.closeChatbox() +} + +/** + * Gets an NPC with the given ID from the repository. + * @param id the ID of the NPC to locate + * @returns an NPC instance matching the ID if it finds one, null otherwise + */ +fun findNPC(id: Int): NPC? { + return Repository.findNPC(id) +} + +/** + * Gets the spawned scenery from the world map using the given coordinates + * @param x the X coordinate to use + * @param y the Y coordinate to use + * @param z the Z coordinate to use + */ +fun getScenery(x: Int, y: Int, z: Int): Scenery? { + return RegionManager.getObject(z, x, y) +} + +/** + * Gets the spawned scenery from the world map using the given Location object. + * @param loc the Location object to use. + */ +fun getScenery(loc: Location): Scenery? { + return RegionManager.getObject(loc) +} + +/** + * Gets an NPC within render distance of the refLoc that matches the given ID + * @param refLoc the Location to find the closes NPC to + * @param id the ID of the NPC to locate + * @returns an NPC instance matching the ID if it finds one, null otherwise + */ +fun findNPC(refLoc: Location, id: Int): NPC? { + return Repository.npcs.firstOrNull { it.id == id && it.location.withinDistance(refLoc) } +} + +/** + * Gets an NPC with the given ID in the same general area as the given Entity + * @param entity the entity to search around + * @param id the ID of the NPC to locate + * @returns an NPC matching the given ID or null if none is found + */ +fun findLocalNPC(entity: Entity, id: Int): NPC? { + return RegionManager.getLocalNpcs(entity).firstOrNull { it.id == id } +} + +/** + * Gets an NPC with the given ID in the same general area as the given Entity + * @param location The location to search around. + * @param distance The maximum distance to the entity. + * @returns an NPC matching the given ID or null if none is found + */ +fun findLocalNPCs(location: Location, distance: Int): MutableList { + return RegionManager.getLocalNpcs(location, distance) +} + + +/** + * Gets a list of nearby NPCs that match the given IDs. + * @param entity the entity to check around + * @param ids the IDs of the NPCs to look for + */ +fun findLocalNPCs(entity: Entity, ids: IntArray): List { + return RegionManager.getLocalNpcs(entity).filter { it.id in ids }.toList() +} + +/** + * Gets a list of nearby NPCs that match the given IDs. + * @param entity the entity to check around + * @param ids the IDs of the NPCs to look for + * @param distance The maximum distance to the entity. + */ +fun findLocalNPCs(entity: Entity, ids: IntArray, distance: Int): List { + return RegionManager.getLocalNpcs(entity, distance).filter { it.id in ids }.toList() +} + +/** + * @param regionId the ID of the region + * @return a [ZoneBorders] encapsulating the entire region indicated by the provided regionId + */ +fun getRegionBorders(regionId: Int): ZoneBorders { + return ZoneBorders.forRegion(regionId) +} + +/** + * Gets the value of an attribute key from the Entity's attributes store + * @param entity the entity to get the attribute from + * @param attribute the attribute key to use + * @param default the default value to return if the attribute does not exist + */ +fun getAttribute(entity: Entity, attribute: String, default: T): T { + return entity.getAttribute(attribute, default) +} + +/** + * Sets an attribute key to the given value in an Entity's attribute store + * @param entity the entity to set the attribute for + * @param attribute the attribute key to use + * @param value the value to set the attribute to + */ +fun setAttribute(entity: Entity, attribute: String, value: T) { + entity.setAttribute(attribute, value) +} + +fun removeAttribute(entity: Entity, attribute: String) { + entity.removeAttribute(attribute.replace("/save:","")) +} + +fun removeAttributes(entity: Entity, vararg attributes: String) { + for (attribute in attributes) removeAttribute(entity, attribute) +} + +/** + * Adds the given timer to the entity's active timers. + * @param entity the entity whose timers are being added to + * @param timer the timer being added +**/ +fun registerTimer (entity: Entity, timer: RSTimer?) { + if (timer == null) return + entity.timers.registerTimer (timer) +} + +/** + * Used to fetch the existing, active, non-abstract and non-anonymous timer with the given identifier, or start a new timer if none exists and return that. + * @param entity the entity whose timers we're retrieving + * @param identifier the identifier of the timer, refer to the individual timer class for this token. + * @param args various args to pass to the initialization of the timer, if applicable. + * @return Either the existing active timer, or a new timer initialized with the passed args if none exists yet. +**/ +fun getOrStartTimer (entity: Entity, identifier: String, vararg args: Any) : RSTimer? { + val existing = getTimer (entity, identifier) + if (existing != null) + return existing + return spawnTimer (identifier, *args).also { registerTimer (entity, it) } +} + +/** + * Used to fetch the existing, active, non-abstract and non-anonymous timer with the given type, or start a new timer if none exists and return that. + * @param entity the entity whose timer we're retrieving + * @param T the type of timer we are fetching + * @param args the various args to pass to the initialization of the timer, if applicable. + * @return Either the existing, active timer or a new timer initialized with the passed args if none exists yet. +**/ +inline fun getOrStartTimer (entity: Entity, vararg args: Any) : T { + val existing = getTimer (entity) + if (existing != null) + return existing + return spawnTimer (*args).also { registerTimer (entity, it) } +} + +/** + * Used to fetch a new instance of a registered (see: non-anonymous, non-abstract) timer with the given configuration args + * @param identifier the string identifier for the timer. e.g. poison's is "poison" + * @param args various arbitrary arguments to be passed to the timer's constructor. Refer to the timer in question for what the args are expected to be. + * @return a timer instance configured with your given args, or null if no timer with the given key exists in the registry. +**/ +fun spawnTimer (identifier: String, vararg args: Any) : RSTimer? { + return TimerRegistry.getTimerInstance (identifier, *args) +} + +/** + * Used to fetch a new instance of a registered (see: non-anonymous, non-abstract) timer with the given configuration args + * @param T the type of the timer you're trying to retrieve. The timer registry will be searched for a timer of this type. + * @param args various arbitrary arguments to be passed to the timer's constructor. Refer to the timer in question for what the args are expected to be. + * @return a timer instance configured with your given args, or null if the timer is not listed in the registry (if this happens, your timer is either abstract or anonymous.) +**/ +inline fun spawnTimer (vararg args: Any) : T { + return TimerRegistry.getTimerInstance (*args)!! +} + +/** + * Used to check if a timer of the given type is registered and active in the entity's timers. + * @param T the type of timer + * @param entity the entity whose timers are being checked + * @return true if there is a timer registered and active with the given type. +**/ +inline fun hasTimerActive (entity: Entity) : Boolean { + return getTimer(entity) != null +} + +/** + * Used to get the active instance of a timer with the given type from the entity's timers. + * @param T the type of timer + * @param entity the entity whose timers we are checking + * @return the active instance of the given type in the entity's timers, or null. +*/ +inline fun getTimer (entity: Entity) : T? { + return entity.timers.getTimer() +} + +/** + * Removes any active timers of the given type from the entity's active timers. This will remove ALL matching instances. + * @param T the type of timer + * @param entity the entity whose timers are being checked +**/ +inline fun removeTimer (entity: Entity) { + entity.timers.removeTimer() +} + +/** + * Used to check if a timer with the given identifier string is registered and active in the entity's timers. + * @param identifier the identifier token assigned to the timer. You'll have to refer to the actual timer class for this string. + * @param entity the entity whose timers are being checked + * @return true if there's a timer with the given identifier active in the entity's timers +**/ +fun hasTimerActive (entity: Entity, identifier: String) : Boolean { + return getTimer (entity, identifier) != null +} + +/** + * Used to get the active instance of a timer with the given identifier from the entity's timers. + * @param identifier the string identifier of the timer we are looking for. You'll have to refer to the actual timer class for this string. + * @param entity the entity whose timers are being checked + * @return the instance of the active timer if found, null otherwise. +**/ +fun getTimer (entity: Entity, identifier: String) : RSTimer? { + return entity.timers.getTimer(identifier) +} + +/** + * Removes any active timers with the given identifier from the entity's active timers. This will remove ALL matching instances. + * @param identifier the identifier token assigned to the timer. You'll have to refer to the actual timer class for this string. + * @param entity the entity whose timers are being checked +**/ +fun removeTimer (entity: Entity, identifier: String) { + entity.timers.removeTimer(identifier) +} + +/** + * Removes the given timer from the entity's active timers. Note this variant will only work with a reference to the same exact timer you want to remove. + * @param entity the entity whose timers we are modifying + * @param timer the timer to remove +**/ +fun removeTimer (entity: Entity, timer: RSTimer) { + entity.timers.removeTimer(timer) +} + +/** + * Locks the given entity for the given number of ticks + * @param entity the entity to lock + * @param duration the number of ticks to lock for + */ +fun lock(entity: Entity, duration: Int) { + entity.lock(duration) +} + +/** + * Locks specifically an entity's interactions, allowing movement still + * @param entity the entity to lock + * @param duration the duration in ticks to lock for + */ +fun lockInteractions(entity: Entity, duration: Int) { + entity.locks.lockInteractions(duration) +} + +/** + * Unlocks the given entity + * @param entity the entity to unlock + */ +fun unlock(entity: Entity) { + entity.unlock() +} + +/** + * Transforms an NPC for the given number of ticks + * @param npc the NPC object to transform + * @param transformTo the ID of the NPC to turn into + * @param restoreTicks the number of ticks until the NPC returns to normal + */ +fun transformNpc(npc: NPC, transformTo: Int, restoreTicks: Int) { + npc.transform(transformTo) + Pulser.submit(object : Pulse(restoreTicks) { + override fun pulse(): Boolean { + npc.reTransform() + return true + } + }) +} + +/** + * Produces a Location object using the given x,y,z values + */ +fun location(x: Int, y: Int, z: Int): Location { + return Location.create(x, y, z) +} + +/** + * Checks if the given entity is within the given ZoneBorders + */ +fun inBorders(entity: Entity, borders: ZoneBorders): Boolean { + return borders.insideBorder(entity) +} + +/** + * Checks if the given entity is within the given borders + */ +fun inBorders(entity: Entity, swX: Int, swY: Int, neX: Int, neY: Int): Boolean { + return ZoneBorders(swX, swY, neX, neY).insideBorder(entity) +} + +/** + * AHeals the given entity for the given number of hitpoints + */ +fun heal(entity: Entity, amount: Int) { + entity.skills.heal(amount) +} + +fun getVarp (player: Player, varpIndex: Int) : Int { + return player.varpMap[varpIndex] ?: 0 +} + +fun getVarbit (player: Player, def: VarbitDefinition) : Int { + val mask = def.mask + val current = getVarp (player, def.varpId) + return (current shr def.startBit) and mask +} + +fun getVarbit (player: Player, varbitId: Int) : Int { + val def = VarbitDefinition.forId(varbitId) + return getVarbit (player, def) +} + +@JvmOverloads +fun setVarp (player: Player, varpIndex: Int, value: Int, save: Boolean = false) { + player.varpMap[varpIndex] = value + if (player.saveVarp[varpIndex] != true && save) + player.saveVarp[varpIndex] = true //only set if we're choosing to save. Prevents accidental unsaving. if you REALLY want to unsave a varp, use unsaveVarp. + player.packetDispatch.sendVarp(varpIndex, value) +} + +fun saveVarp (player: Player, varpIndex: Int) { + player.saveVarp[varpIndex] = true +} + +fun unsaveVarp (player: Player, varpIndex: Int) { + player.saveVarp.remove(varpIndex) +} + +@JvmOverloads +fun setVarbit (player: Player, def: VarbitDefinition, value: Int, save: Boolean = false) { + val mask = def.mask + val current = getVarp (player, def.varpId) and (mask shl def.startBit).inv() + val newValue = (value and mask) shl def.startBit + setVarp (player, def.varpId, current or newValue, save) +} + +@JvmOverloads +fun setVarbit (player: Player, varbitId: Int, value: Int, save: Boolean = false) { + val def = VarbitDefinition.forId(varbitId) + + if (def == null) { + logWithStack (ContentAPI::class.java, Log.ERR, "Trying to setVarbit $varbitId, which doesn't seem to exist.") + return + } + + setVarbit (player, def, value, save) +} + +fun setVarc (player: Player, varc: Int, value: Int) +{ + player.packetDispatch.sendVarcUpdate(varc.toShort(), value) +} + +fun reinitVarps (player: Player) { + for ((index, value) in player.varpMap) { + setVarp(player, index, value, player.saveVarp[index] ?: false) + } +} + +/** + * Force an entity to walk to a given destination. + * @param entity the entity to forcewalk + * @param dest the Location object to walk to + * @param type the type of pathfinder to use. "smart" for the SMART pathfinder, "clip" for the noclip pathfinder, anything else for DUMB. + */ +fun forceWalk(entity: Entity, dest: Location, type: String) { + if (type == "clip") { + ForceMovement(entity, dest, 10, 10).run() + return + } + val pathfinder = when (type) { + "smart" -> Pathfinder.SMART + else -> Pathfinder.DUMB + } + val path = Pathfinder.find(entity, dest, true, pathfinder) + path.walk(entity) +} + +/** + * Returns a location truncated to the appropriate pathfinding limit +**/ +fun truncateLoc (mover: Entity, destination: Location) : Pair { + val vector = Vector.betweenLocs(mover.location, destination) + val normVec = vector.normalized() + val mag = vector.magnitude() + + var multiplier = if (mover is NPC) 14.0 else ServerConstants.MAX_PATHFIND_DISTANCE.toDouble() + var clampedMultiplier = min(multiplier, mag) + + var truncated = multiplier == clampedMultiplier + + return Pair(truncated, mover.location.transform(normVec * clampedMultiplier)) +} + +/** + * Force a player to move from the start location to the dest location + * @param player the player we are moving + * @param start the start location + * @param dest the end location + * @param startArrive the number of client cycles to take moving the player to the start location + * @param destArrive the number of client cycles to take moving the player to the end location from the start location + * @param direction (optional) the direction to face the player during the movement + * @param anim (optional) the animation to use throughout the movement + * @param callback (optional) a callback called when the forced movement completes + * @see NOTE: There are 30 client cycles per second. +*/ +fun forceMove (player: Player, start: Location, dest: Location, startArrive: Int, destArrive: Int, dir: Direction? = null, anim: Int = 819, callback: (()->Unit)? = null) { + var direction: Direction + + if (dir == null) { + var delta = Location.getDelta(start, dest) + var x = abs(delta.x) + var y = abs(delta.y) + + if (x > y) + direction = Direction.getDirection(delta.x, 0) + else + direction = Direction.getDirection(0, delta.y) + } else direction = dir + + val startLoc = Location.create(start) + val destLoc = Location.create(dest) + var startArriveTick = getWorldTicks() + cyclesToTicks (startArrive) + 1 + var destArriveTick = startArriveTick + cyclesToTicks (destArrive) + var maskSet = false + + delayEntity(player, (destArriveTick - getWorldTicks()) + 1) + queueScript (player, 0, QueueStrength.SOFT) { stage: Int -> + if (!finishedMoving(player)) + return@queueScript keepRunning(player) + if (!maskSet) { + var ctx = ForceMoveCtx (startLoc, destLoc, startArrive, destArrive, direction) + player.updateMasks.register(EntityFlag.ForceMove, ctx) + maskSet = true + } + + var tick = getWorldTicks() + if (tick < startArriveTick) { + return@queueScript keepRunning(player) + } else if (tick < destArriveTick) { + if (animationFinished(player)) + animate (player, anim) + return@queueScript keepRunning(player) + } else if (tick >= destArriveTick) { + try { + callback?.invoke() + } catch (e: Exception) { + e.printStackTrace() + } + player.properties.teleportLocation = dest + return@queueScript stopExecuting(player) + } + return@queueScript stopExecuting(player) + } +} + +/** + * Interrupts a given entity's walking queue + * @param entity the entity to interrupt + */ +fun stopWalk(entity: Entity) { + entity.walkingQueue.reset() +} + +/** + * Returns a list of all valid children IDs for a given scenery ID + */ +fun getChildren(scenery: Int): IntArray { + return SceneryDefinition.forId(scenery).getChildrenIds().filter { it != -1 }.toIntArray() +} + +/** + * Adjusts the charge for the given node. + * @param node the node to adjust the charge of + * @param amount the amount to adjust by + */ +fun adjustCharge(node: Node, amount: Int) { + when (node) { + is Item -> node.charge += amount + is Scenery -> node.charge += amount + else -> log(ContentAPI::class.java, Log.ERR, "Attempt to adjust the charge of invalid type: ${node.javaClass.simpleName}") + } +} + +/** + * Get the current charge of the given node + * @param node the node whose charge to check + * @return amount of charges the node has, or -1 if the node does not accept charges. + */ +fun getCharge(node: Node): Int { + when (node) { + is Item -> return node.charge + is Scenery -> return node.charge + else -> log(ContentAPI::class.java, Log.ERR, "Attempt to get charge of invalid type: ${node.javaClass.simpleName}") + .also { return -1 } + } +} + +/** + * Set the charge of the given node to the given amount. + * @param node the node to set the charge for + * @param charge the amount to set the node's charge to (default is 1000) + */ +fun setCharge(node: Node, charge: Int) { + when (node) { + is Item -> node.charge = charge + is Scenery -> node.charge = charge + else -> log(ContentAPI::class.java, Log.ERR, "Attempt to set the charge of invalid type: ${node.javaClass.simpleName}") + } +} + +/** + * Gets the used option in the context of an interaction. + * @param player the player to get the used option for. + * @return the option the player used + */ +fun getUsedOption(player: Player): String { + return player.getAttribute("interact:option", "INVALID") +} + +/** + * Used to play both an Animation and Graphics object simultaneously. + * Use -1 in place of anim or graphics if not needed. + * @param entity the entity to perform this on + * @param anim the Animation object to use, can also be an ID. + * @param gfx the Graphics object to use, can also be an ID. + */ +fun visualize(entity: Entity, anim: A, gfx: G) { + val animation = when (anim) { + is Int -> Animation(anim) + is Animation -> anim + else -> throw IllegalStateException("Invalid parameter passed for animation.") + } + + val graphics = when (gfx) { + is Int -> Graphics(gfx) + is Graphics -> gfx + else -> throw IllegalStateException("Invalid parameter passed for graphics.") + } + + entity.visualize(animation, graphics) +} + +/** + * Used to submit a pulse to the GameWorld's Pulser. + * @param pulse the Pulse object to submit + */ +fun submitWorldPulse(pulse: Pulse) { + Pulser.submit(pulse) +} + +/** + * Used to submit a pulse to the GameWorld's Pulser, albeit with a cleaner syntax. + * @param task an anonymous function that will be run in the Pulse + * @return the newly submitted Pulse + */ +fun runWorldTask(task: () -> Unit): Pulse { + val pulse = object : Pulse() { + override fun pulse(): Boolean { + task.invoke() + return true + } + } + + submitWorldPulse(pulse) + return pulse +} + +/** + * Teleports or "instantly moves" an entity to a given Location object. + * @param entity the entity to move + * @param loc the Location object to move them to + * @param type the teleport type to use (defaults to instant). An enum exists as TeleportManager.TeleportType. + */ +fun teleport(entity: Entity, loc: Location, type: TeleportManager.TeleportType = TeleportManager.TeleportType.INSTANT) : Boolean { + if (type == TeleportManager.TeleportType.INSTANT) { + entity.properties.teleportLocation = loc + return true + } + else return entity.teleporter.send(loc, type) +} + +/** + * Sets the dynamic or "temporary" (restores) level of a skill. + * @param entity the entity to set the level for + * @param skill the Skill to set. A Skills enum exists that can be used. Ex: Skills.STRENGTH + * @param level the level to set the skill to + */ +fun setTempLevel(entity: Entity, skill: Int, level: Int) { + entity.skills.setLevel(skill, level) +} + +/** + * Gets the static (unchanging/max) level of an entity's skill + * @param entity the entity to get the level for + * @param skill the Skill to get the level of. A Skills enum exists that can be used. Ex: Skills.STRENGTH + * @return the static level of the skill + */ +fun getStatLevel(entity: Entity, skill: Int): Int { + return entity.skills.getStaticLevel(skill) +} + +/** + * Gets the dynamic (boostable/debuffable/restoring) level of an entity's skill + * @param entity the entity to get the level for + * @param skill the Skill to get the level of. A Skills enum exists that can be used. Ex: Skills.STRENGTH + * @return the dynamic level of the skill + */ +fun getDynLevel(entity: Entity, skill: Int): Int { + return entity.skills.getLevel(skill) +} + +/** + * Adjusts (buffs/debuffs) the given Skill by the amount given. + * @param entity the entity to adjust the skill for + * @param skill the Skill to adjust. A Skills enum exists that can be used. Ex: Skills.STRENGTH + * @param amount the amount to adjust the skill by. Ex-Buff: 5, Ex-Debuff: -5 + */ +fun adjustLevel(entity: Entity, skill: Int, amount: Int) { + entity.skills.setLevel(skill, entity.skills.getStaticLevel(skill) + amount) +} + +/** + * Remove all of a given item from the given container + * @param player the player to remove the item from + * @param item the item to remove. Can be an Item object or an ID. + * @param container the Container to remove the item from. An enum exists for this called Container. Ex: Container.BANK + */ +fun removeAll(player: Player, item: T, container: Container = Container.INVENTORY): Boolean { + item ?: return false + val it = when (item) { + is Item -> item.id + is Int -> item + else -> throw IllegalStateException("Invalid value passed as item") + } + + return when (container) { + Container.EQUIPMENT -> player.equipment.remove(Item(it, amountInEquipment(player, it))) + Container.BANK -> { + val amountInPrimary = amountInBank(player, it, false) + val amountInSecondary = amountInBank(player, it, true) - amountInPrimary + player.bank.remove(Item(it, amountInPrimary)) && player.bankSecondary.remove(Item(it, amountInSecondary)) + } + Container.INVENTORY -> player.inventory.remove(Item(it, amountInInventory(player, it))) + } +} + +/** + * Sends a string to a specific interface child + * @param player the player to send the packet to + * @param string the string to send to the child + * @param iface the ID of the interface to use + * @param child the index of the child to send the string to + */ +fun setInterfaceText(player: Player, string: String, iface: Int, child: Int) { + player.packetDispatch.sendString(string, iface, child) +} + +/** + * Allows you to hide or show specific children in an interface + * @param player the player to send the packet to + * @param iface the ID of the interface to use + * @param child the index of the child to hide or show + * @param hide if the child should be hidden or not + */ +fun setComponentVisibility(player: Player, iface: Int, child: Int, hide: Boolean) { + player.packetDispatch.sendInterfaceConfig(iface, child, hide) +} + +/** + * Closes any open (non-chat) interfaces for the player + * @param player the player to close the interface for + */ +fun closeInterface(player: Player) { + player.interfaceManager.close() +} + +/** + * Closes any opened tab interfaces for the player + * @param player the player to close the tab for + */ +fun closeTabInterface(player: Player) { + player.interfaceManager.closeSingleTab() +} + +/** + * Closes any open (both chat and non-chat) interfaces for the player + * @param player the player to close the interfaces for + */ +fun closeAllInterfaces(player: Player) { + player.interfaceManager.close() + player.interfaceManager.closeChatbox() + player.dialogueInterpreter.close() +} + +/** + * Sends a dialogue that uses the player's chathead. + * @param player the player to send the dialogue to + * @param msg the message to send. + * @param expr the FacialExpression to use. An enum exists for these called FacialExpression. Defaults to FacialExpression.FRIENDLY + * @param hide should the continue button be hidden? + */ +fun sendPlayerDialogue(player: Player, msg: String, expr: core.game.dialogue.FacialExpression = core.game.dialogue.FacialExpression.FRIENDLY, hide: Boolean = false) { + player.dialogueInterpreter.sendDialogues(player, expr, hide, *splitLines(msg)) +} + +/** + * Sends a player model to a specific interface child + * @param player the player to send the packet to and whose model to use + * @param iface the ID of the interface to send it to + * @param child the index of the child on the interface to send the model to + */ +fun sendPlayerOnInterface(player: Player, iface: Int, child: Int) { + player.packetDispatch.sendPlayerOnInterface(iface, child) +} + +/** + * Sends a dialogue that uses the npc's chathead. + * @param player the player to send the dialogue to + * @param npc the ID of the NPC to use for the chathead + * @param msg the message to send. + * @param expr the FacialExpression to use. An enum exists for these called FacialExpression. Defaults to FacialExpression.FRIENDLY + * @param hide should the continue button be hidden? + */ +fun sendNPCDialogue(player: Player, npc: Int, msg: String, expr: core.game.dialogue.FacialExpression = core.game.dialogue.FacialExpression.FRIENDLY, + hide: Boolean = false) { + player.dialogueInterpreter.sendDialogues(npc, expr, hide, *splitLines(msg)) +} + +/** + * Sends a dialogue that uses the npc's chathead. + * @param player the player to send the dialogue to + * @param npc the ID of the NPC to use for the chathead + * @param expr the FacialExpression to use. An enum exists for these called FacialExpression. + * @param msg the message to send. + */ +fun sendNPCDialogueLines(player: Player, npc: Int, expr: core.game.dialogue.FacialExpression, hideContinue: Boolean, vararg msgs: String) { + val dialogueComponent = player.dialogueInterpreter.sendDialogues(npc, expr, *msgs) + player.packetDispatch.sendInterfaceConfig(dialogueComponent.id, msgs.size + 4, hideContinue) +} + +/** + * Sends an animation to a specific interface child + * @param player the player to send the packet to + * @param anim the ID of the animation to send to the interface + * @param iface the ID of the interface to send the animation to + * @param child the index of the child on the interface to send the model to + */ +fun sendAnimationOnInterface(player: Player, anim: Int, iface: Int, child: Int) { + player.packetDispatch.sendAnimationInterface(anim, iface, child) +} + +/** + * Register a logout listener to a player. Logout listeners are methods that run when a player logs out. + * @param player the player to register the listener for + * @param handler the method to run when the listener is invoked (when the player logs out) + */ +fun registerLogoutListener(player: Player, key: String, handler: (p: Player) -> Unit) { + player.logoutListeners[key] = handler +} + +/** + * Removes a logout listener based on the key from a player + * @param player the player to remove the logout listner from + * @param key the key of the logout listener to remove. + */ +fun clearLogoutListener(player: Player, key: String) { + player.logoutListeners.remove(key) +} + +/** + * Sends an item to a specific child on an interface + * @param player the player to send the packet to + * @param iface the ID of the interface to send the item onto + * @Param child the index of the child on the interface to send the item onto + * @param item the ID of the item to send + * @param amount the amount of the item to send - defaults to 1 + */ +fun sendItemOnInterface(player: Player, iface: Int, child: Int, item: Int, amount: Int = 1) { + player.packetDispatch.sendItemOnInterface(item, amount, iface, child) +} + +/** + * Sends a zoomed item to a specific child on an interface + * @param player the player to send the packet to + * @param iface the ID of the interface to send the item onto + * @Param child the index of the child on the interface to send the item onto + * @param item the ID of the item to send + * @param zoom the amount of zoom to apply to the item - defaults to 230 + */ +fun sendItemZoomOnInterface(player: Player, iface: Int, child: Int, item: Int, zoom: Int = 230) { + player.packetDispatch.sendItemZoomOnInterface(item, zoom, iface, child) +} + +/** + * Sends a dialogue box with a single item and some text + * @param player the player to send it to + * @param item the ID of the item to show + * @param message the text to display + */ +fun sendItemDialogue(player: Player, item: Any, message: String) { + val dialogueItem = when (item) { + is Item -> item + is Int -> Item(item) + else -> { + throw java.lang.IllegalArgumentException("Expected an Item or an Int, got ${item::class.java.simpleName}.") + } + } + + player.dialogueInterpreter.sendItemMessage(dialogueItem, *splitLines(message)) +} + +/** + * Sends a dialogue box with two items and some text + * @param player the player to send it to + * @param item1 the ID of the first item to show + * @param item2 the ID of the second item to show + * @param message the text to display + */ +fun sendDoubleItemDialogue(player: Player, item1: Any, item2: Any, message: String) { + when (item1) { + is Item -> player.dialogueInterpreter.sendDoubleItemMessage(item1, item2 as Item, message) + is Int -> player.dialogueInterpreter.sendDoubleItemMessage(item1, item2 as Int, message) + } +} + +/** + * Send an input dialogue to retrieve a specified value from the player + * @param player the player to send the input dialogue to + * @param numeric whether or not the input is numeric + * @param prompt what to prompt the player + * @param handler the method that handles the value gained from the input dialogue + */ +fun sendInputDialogue(player: Player, numeric: Boolean, prompt: String, handler: (value: Any) -> Unit) { + if (numeric) sendInputDialogue(player, InputType.NUMERIC, prompt, handler) + else sendInputDialogue(player, InputType.STRING_SHORT, prompt, handler) +} + +/** + * Send input dialogues based on type. Some dialogues are special and can't be covered by the other sendInputDialogue method + * @param player the player to send the input dialogue to + * @param type the input type to send - an enum is available for this called InputType + * @param prompt what to prompt the player + * @param handler the method that handles the value from the input dialogue + */ +fun sendInputDialogue(player: Player, type: InputType, prompt: String, handler: (value: Any) -> Unit) { + when (type) { + InputType.AMOUNT -> { + player.setAttribute("parseamount", true) + player.dialogueInterpreter.sendInput(true, prompt) + } + + InputType.NUMERIC, InputType.STRING_SHORT -> player.dialogueInterpreter.sendInput( + type != InputType.NUMERIC, + prompt + ) + + InputType.STRING_LONG -> player.dialogueInterpreter.sendLongInput(prompt) + InputType.MESSAGE -> player.dialogueInterpreter.sendMessageInput(prompt) + } + + player.setAttribute("runscript", handler) + player.setAttribute("input-type", type) +} + +/** + * Forces an NPC to "flee" from a player or other entity + * @param entity the entity to make flee + * @param from the entity to flee from + */ +fun flee(entity: Entity, from: Entity) { + lock(entity, 5) + face(entity, from, 5) + + val diffX = entity.location.x - from.location.x + val diffY = entity.location.y - from.location.y + + forceWalk(entity, entity.location.transform(diffX, diffY, 0), "DUMB") +} + +/** + * Submits an individual or "weak" pulse to a specific entity's pulse manager. Pulses submitted this way can be overridden by other pulses. + * @param entity the entity to submit the pulse to + * @param pulse the pulse to submit + */ +fun submitIndividualPulse(entity: Entity, pulse: Pulse) { + entity.pulseManager.run(pulse) +} + +/** + * Similar to submitIndividualPulse, but for non-repeating tasks, with a cleaner syntax. + */ +fun runTask(entity: Entity, delay: Int = 0, repeatTimes: Int = 1, task: () -> Unit) { + var cycles = repeatTimes + entity.pulseManager.run(object : Pulse(delay) { + override fun pulse(): Boolean { + task.invoke() + return --cycles == 0 + } + }) +} + +/** + * Gets the number of QP a player has + * @param player the player to get the QP for + * @return the number of QP the player has + */ +fun getQuestPoints(player: Player): Int { + return player.questRepository.points +} + +/** + * Gets the stage for the given quest for the given player + */ +fun getQuestStage(player: Player, quest: Quests): Int { + return player.questRepository.getStage(quest) +} + +/** + * Sets the stage for the given quest for the given player + */ +fun setQuestStage(player: Player, quest: Quests, stage: Int) { + player.questRepository.setStage(QuestRepository.getQuests()[quest]!!, stage) + player.questRepository.syncronizeTab(player) +} + +/** + * Check if a quest is in progress + */ +fun isQuestInProgress(player: Player, quest: Quests, startStage: Int, endStage: Int): Boolean { + return player.questRepository.getStage(quest) in startStage..endStage +} + +/** + * Check if a quest is complete + */ +fun isQuestComplete(player: Player, quest: Quests): Boolean { + return player.questRepository.getStage(quest) == 100 +} + +/** + * Get the quest for a player. + * @param player The player to get the quest for. + * @param quest The quest name string + * @return the quest object + */ +fun getQuest(player: Player, quest: Quests): Quest { + return player.questRepository.getQuest(quest) +} + + +/** + * Check if a player meets the requirements to start a quest, and then starts it if they do. Returns success bool + */ +fun startQuest(player: Player, quest: Quests): Boolean { + val quest = player.questRepository.getQuest(quest) + val canStart = quest.hasRequirements(player) + if (!canStart) return false + quest.start(player) + return true +} + +/** + * Finishes a quest, gives rewards, marks as completed, etc + */ +fun finishQuest(player: Player, quest: Quests) { + player.questRepository.getQuest(quest).finish(player) +} + +/** + * Gets a scenery definition from the given ID + * @param id the ID of the scenery to get the definition for. + * @return the scenery definition + */ +fun sceneryDefinition(id: Int): SceneryDefinition { + return SceneryDefinition.forId(id) +} + +/** + * Register a map zone + * @param zone the zone to register + * @param borders the ZoneBorders that compose the zone + */ +fun registerMapZone(zone: MapZone, borders: ZoneBorders) { + ZoneBuilder.configure(zone) + zone.register(borders) +} + +/** + * Animates a component of an interface. + * @param player the player to animate the interface for. + * @param iface the ID of the interface to animate. + * @param child the child on the interface to animate. + * @param anim the ID of the animation to use. + */ +fun animateInterface(player: Player, iface: Int, child: Int, anim: Int) { + player.packetDispatch.sendAnimationInterface(anim, iface, child) +} + +/** + * Adds a climb destination to the ladder handler. + * @param ladderLoc the location of the ladder/stairs object you want to climb. + * @param dest the destination for the climb. + */ +fun addClimbDest(ladderLoc: Location, dest: Location) { + core.game.global.action.SpecialLadders.add(ladderLoc, dest) +} + +/** + * Sends a news announcement in game chat. + * @param message the message to announce + */ +fun sendNews(message: String) { + Repository.sendNews(message, 12, "CC6600") +} + +/** + * Sends a given Graphics object, or graphics ID, to the given location. + * @param gfx the Graphics object, or the Integer ID of the graphics, to send. Either works. + * @param location the location to send it to + */ +fun sendGraphics(gfx: G, location: Location) { + when (gfx) { + is Int -> Graphics.send(Graphics(gfx), location) + is Graphics -> Graphics.send(gfx, location) + } +} + +/** + * Instructs the given player's client to execute a given CS2 script with the given arguments + * @param player the Player + * @param scriptId the ID of the CS2 script to execute + * @param arguments the various arguments passed to the script. +**/ +fun runcs2 (player: Player, scriptId: Int, vararg arguments: Any) { + var typeString = StringBuilder() + var finalArgs = Array (arguments.size) { null } + try { + for (i in 0 until arguments.size) { + val arg = arguments[i] + if (arg is Int) + typeString.append("i") + else if (arg is String) + typeString.append("s") + else + throw IllegalArgumentException("Argument at index $i ($arg) is not an acceptable type! Only string and int are accepted.") + finalArgs[arguments.size - i - 1] = arg + } + player.packetDispatch.sendRunScript(scriptId, typeString.toString(), *finalArgs) + } catch (e: Exception) { + e.printStackTrace() + } +} + +/** + * Opens a generic item selection prompt with a glowing background, with your own callback to handle the selection. + * @param player the player we are openinig the prompt for + * @param options the right-click options the items should have + * @param keepAlive whether or not the selection prompt should remain open for multiple interactions + * @param callback a callback to handle the selection. The parameters passed to the callback are the slot in the inventory of the selected item, and the 0-9 index of the option clicked. +**/ +@JvmOverloads +fun sendItemSelect (player: Player, vararg options: String, keepAlive: Boolean = false, callback: (slot: Int, optionIndex: Int) -> Unit) { + player.interfaceManager.openSingleTab(Component(12)) + val scriptArgs = arrayOf ((12 shl 16) + 18, 93, 4, 7, 0, -1, "", "", "", "", "", "", "", "", "") + for (i in 0 until min(9, options.size)) + scriptArgs[6 + i] = options[i] + runcs2(player, 150, *scriptArgs) + val settings = IfaceSettingsBuilder() + .enableOptions(0 until 9) + .build() + player.packetDispatch.sendIfaceSettings(settings, 18, 12, 0, 28) + setAttribute(player, "itemselect-callback", callback) + setAttribute(player, "itemselect-keepalive", keepAlive) +} + +fun announceIfRare(player: Player, item: Item) { + if (item.definition.getConfiguration(ItemConfigParser.RARE_ITEM, false)) { + sendNews("${player.username} has just received: ${item.amount} x ${item.name}.") + PlayerStatsCounter.incrementRareDrop(player, item) + } +} + +fun hasRequirement(player: Player, req: QuestReq, message: Boolean = true) : Boolean { + var (isMet, unmetReqs) = req.evaluate(player) + val messageList = ArrayList() + + var totalSoftQp = 0 + var totalHardQp = 0 + + for (req in unmetReqs) { + when (req) { + is QPCumulative -> totalSoftQp += req.amount + is QPReq -> if (req.amount > totalHardQp) totalHardQp = req.amount + } + } + + var neededQp = min(max(totalSoftQp, totalHardQp), player.questRepository.getAvailablePoints()) + + isMet = isMet && neededQp <= player.questRepository.getPoints() + + if (isMet) return true + + if (unmetReqs.size == 2 && unmetReqs[0] is QuestReq) { + messageList.add ("This requires completion of ${(unmetReqs[0] as QuestReq).questReq.quest} to access.") + } else { + messageList.add ("You need the pre-reqs for ${req.questReq.quest} to access this.") + messageList.add ("Please check the page in your quest journal for more info.") + } + + if (message) + for (message in messageList) + sendMessage(player, message) + + return false +} + +@JvmOverloads +fun hasRequirement(player: Player, quest: Quests, message: Boolean = true) : Boolean { + val questReq = QuestRequirements.values().firstOrNull { it.quest == quest } ?: return false + return hasRequirement(player, QuestReq(questReq), message) +} + +/** + * Generates a list of skill names which the player has mastered + * @param player the player + * @return a List of skill names + */ +fun getMasteredSkillNames(player: Player): List { + val hasMastered = player.getSkills().masteredSkills > 0 + val masteredSkills = ArrayList() + + if (hasMastered) { + for ((skillId, skillName) in Skills.SKILL_NAME.withIndex()) { + //phil you were looping every skill and performing a string comparison (another loop) for every one here. + //that's some real shit code bro. + //you were also performing a dynamic level check rather than a static. + if (hasLevelStat(player, skillId, 99)) { + masteredSkills.add(skillName) + } + } + } + return masteredSkills +} + +/** + * Empties the provided container into the player's bank. + * @param player the player + * @param container the container to be emptied. + * @return The amount of items which were successfully transferred to the bank. + * + * @author ceik + * @author James Triantafylos + * @author vddCore + */ +fun dumpContainer(player: Player, container: core.game.container.Container): Int { + val bank = player.bank + var dumpedCount = 0 + + run beginDepositing@{ + container.toArray().filterNotNull().forEach { item -> + if (!bank.hasSpaceFor(item)) { + sendMessage(player, "You have no more space in your bank.") + return@beginDepositing + } + + if (!bank.canAdd(item)) { + sendMessage(player, "A magical force prevents you from banking the ${item.name}.") + return@forEach + } else { + if (container is EquipmentContainer) { + if (!InteractionListeners.run(item.id, player, item, false)) { + sendMessage(player, "A magical force prevents you from removing your ${item.name}.") + return@forEach + } + if (SlayerEquipmentFlags.isSlayerEq(item.id)) { + SlayerEquipmentFlags.updateFlags(player) + } + } + + container.remove(item) + bank.add(unnote(item), false) + dumpedCount++ + } + } + } + + container.update() + bank.update() + + return dumpedCount +} + +/** + * Attempts to empty the player's Beast of Burden's inventory + * into the player's bank. + * + * @param player The player whose Beast of Burden's inventory to empty. + * + * @author vddCore + */ +fun dumpBeastOfBurden(player: Player) { + val famMan = player.familiarManager + + if (!famMan.hasFamiliar()) { + sendMessage(player, "You don't have a familiar.") + return + } + + if (famMan.familiar !is BurdenBeast) { + sendMessage(player, "Your familiar is not a Beast of Burden.") + return + } + + val beast: BurdenBeast = (famMan.familiar as BurdenBeast) + + if (beast.container.isEmpty) { + sendMessage(player, "Your familiar's inventory is empty.") + return + } + + val itemCount = beast.container.itemCount() + val dumpedCount = dumpContainer(player, beast.container) + + + when { + dumpedCount == itemCount -> sendMessage(player, "Your familiar's inventory was deposited into your bank.") + dumpedCount > 0 -> { + val remainPhrase = when { + (itemCount - dumpedCount == 1) -> "item remains" + else -> "items remain" + } + + sendMessage(player, "${itemCount - dumpedCount} $remainPhrase in your familiar's inventory.") + } + } +} + +/** + * Gets the player's familiar boost in the given skill + * + * @param player The player who owns the familiar. + * @param skill The skill to check boost of. + * @return The amount of skill boost gained from the player's familiar. + * + * @author bushtail + */ +fun getFamiliarBoost(player: Player, skill: Int): Int { + return player.familiarManager.getBoost(skill) +} + +/** + * Converts an item into its noted representation. + * + * @param item The item to convert. + * @return Noted form of the item or the item itself if it's already, or cannot be, noted. + * + * @author vddCore + */ +fun note(item: Item): Item { + if (!item.definition.isUnnoted) + return item + + if (item.definition.noteId < 0) + return item + + return Item(item.definition.noteId, item.amount, item.charge) +} + +/** + * Converts a noted item into its unnoted representation. + * + * @param item The item to convert. + * @return Unnoted form of the item, or the item itself if it's already unnoted. + * + * @author vddCore + */ +fun unnote(item: Item): Item { + if (item.definition.isUnnoted) + return item + + return Item(item.noteChange, item.amount, item.charge) +} + +/** + * Checks if the player has the Seal of Passage equipped or if it's present in the inventory. + * + * @param player The player to inspect for item's presence. + * @return True if Seal of Passage present, false otherwise. + */ +fun hasSealOfPassage(player: Player): Boolean { + return inEquipmentOrInventory(player, Items.SEAL_OF_PASSAGE_9083) +} + +/** + * Returns a boolean indicating if the player has a house. + * @param player the player. + * @return boolean indicating presence of house. + */ +fun hasHouse(player: Player): Boolean { + return player.houseManager.hasHouse() +} + +fun Player.getCutscene(): Cutscene? { + return getAttribute(this, Cutscene.ATTRIBUTE_CUTSCENE, null) +} + +fun Player.getCutsceneStage(): Int { + return getAttribute(this, Cutscene.ATTRIBUTE_CUTSCENE_STAGE, 0) +} + +fun getServerConfig(): Toml { + return ServerConfigParser.tomlData ?: Toml() +} + +fun getPathableRandomLocalCoordinate(target: Entity, radius: Int, center: Location, maxAttempts: Int = 3): Location { + var maxRadius = Vector.deriveWithEqualComponents(ServerConstants.MAX_PATHFIND_DISTANCE.toDouble()).x - 1 + var effectiveRadius = min(radius, maxRadius.toInt()) + val swCorner = center.transform(-effectiveRadius, -effectiveRadius, center.z) + val neCorner = center.transform(effectiveRadius, effectiveRadius, center.z) + val borders = ZoneBorders(swCorner.x, swCorner.y, neCorner.x, neCorner.y, center.z) + + var attempts = maxAttempts + var success: Boolean + while (attempts-- > 0) { + val dest = borders.randomLoc + val path = Pathfinder.find(center, dest, target.size()) + success = path.isSuccessful && !path.isMoveNear + if (success) return dest + } + + return target.location +} + +/** + * Returns a pathable cardinal location in a 1 tile radius in order of west, south, east, north. + * @param entity the entity used to check if the loc is pathable + * @param center the center location + */ +fun getPathableCardinal(target: Entity, center: Location) : Location { + var tiles = center.cardinalTiles + + for (tile in tiles) { + val path = Pathfinder.find(center, tile, target.size()) + if (path.isSuccessful && !path.isMoveNear) + return tile + } + + return center +} + +/** + * Returns the player's active slayer task. + * @author bushtail + * @param player the player whose task we are checking. + * @return the slayer task. + */ +fun getSlayerTask(player: Player): Tasks? { + return SlayerManager.getInstance(player).activeTask +} + +/** + * Returns the name of the player's active slayer task. + * @author bushtail + * @param player the player whose task we are checking. + * @return the name of the slayer task. + */ +fun getSlayerTaskName(player: Player): String { + return SlayerManager.getInstance(player).taskName +} + +/** + * Returns the player's remaining kills for their active slayer task. + * @author bushtail + * @param player the player whose task we are checking. + * @return the remaining kills of the slayer task. + */ +fun getSlayerTaskKillsRemaining(player: Player): Int { + return SlayerManager.getInstance(player).amount +} + +/** + * Returns the player's slayer master as npc. + * @author bushtail + * @param player the player whose master we are checking. + * @return the slayer master as NPC. + */ +fun getSlayerMaster(player: Player): NPC { + return findNPC(SlayerManager.getInstance(player).master?.npc as Int) as NPC +} + +/** + * Returns the player's slayer master location as string. + * @author bushtail + * @param player the player whose master we are checking. + * @return the slayer master location as String. + */ +fun getSlayerMasterLocation(player: Player): String { + return when (getSlayerMaster(player).id) { + NPCs.CHAELDAR_1598 -> "Zanaris" + NPCs.DURADEL_8275 -> "Shilo Village" + NPCs.MAZCHNA_8274 -> "Canifis" + NPCs.TURAEL_8273 -> "Taverley" + NPCs.VANNAKA_1597 -> "Edgeville Dungeon" + else -> "The Backrooms" + } +} + +/** + * Returns the player's slayer task tip as String. + * @author bushtail + * @param player the player whose task tip we are checking. + * @return the task tip as String. + */ +fun getSlayerTip(player: Player): Array { + return if (hasSlayerTask(player)) { + getSlayerTask(player)?.tip!! + } else { + arrayOf("You need something new to hunt.") + } +} + +/** + * Returns the player's slayer task flags as Int. + * @author bushtail + * @param player the player whose task flags we are checking. + * @return the task flags as Int. + */ +fun getSlayerTaskFlags(player: Player): Int { + return SlayerManager.getInstance(player).flags.taskFlags +} + +/** + * Returns whether or not the player has a task. + * @author bushtail + * @param player the player whose task we are checking. + * @return has task as Boolean. + */ +fun hasSlayerTask(player: Player): Boolean { + return SlayerManager.getInstance(player).hasTask() +} + +/** + * Checks whether a player plays in a specific Ironman mode. + * + * @param player Player whose Ironman status to check. + * @param restriction The Ironman restriction level to check the player against. + * @return Whether the player is restricted to the provided Ironman mode. + */ +fun hasIronmanRestriction(player: Player, restriction: IronmanMode): Boolean { + return player.ironmanManager.isIronman + && player.ironmanManager.mode.ordinal >= restriction.ordinal +} + +/** + * Conditionally executes an action based on the player's Ironman status. + * + * @param player Player whose action to restrict. + * @param restriction Ironman mode that will be used as the restriction criterion. + * @param action The action to be restricted. + */ +fun restrictForIronman(player: Player, restriction: IronmanMode, action: () -> Unit) { + if (!player.ironmanManager.checkRestriction(restriction)) { + action() + } +} + +/** + * Opens the given player's Grand Exchange interface. + * + * @author vddCore + * @param player The player whose Grand Exchange interface to open. + */ +fun openGrandExchange(player: Player) { + restrictForIronman(player, IronmanMode.ULTIMATE) { + StockMarket.openFor(player) + } +} + +/** + * Checks if the player has any items to collect from the Grand Exchange + * + * @author vddCore + * @param player The player whose Grand Exchange collection box to inspect. + */ +fun hasAwaitingGrandExchangeCollections(player: Player): Boolean { + val records = GrandExchangeRecords.getInstance(player) + + for (record in records.offerRecords) { + val offer = records.getOffer(record) + + return offer != null + && offer.withdraw[0] != null + } + + return false +} + +/** + * Opens the given player's Grand Exchange collection box. + * + * It will send a prohibition message to Ultimate Ironmen. + * + * @author vddCore + * @param player The player whose collection box to open. + */ +fun openGrandExchangeCollectionBox(player: Player) { + restrictForIronman(player, IronmanMode.ULTIMATE) { + GrandExchangeRecords.getInstance(player).openCollectionBox() + } +} + +/** + * Opens the given player's bank account. If the player has a PIN set, + * the PIN interface will be shown first. + * + * It will send a prohibition message to Ultimate Ironmen. + * + * @author vddCore + * @param player The player whose bank account to open. + */ +fun openBankAccount(player: Player) { + restrictForIronman(player, IronmanMode.ULTIMATE) { + player.bank.open() + } +} + +/** + * Opens the given player's bank deposit box interface. + * + * It will send a prohibition message to Ultimate Ironmen. + * + * @author vddCore + * @param player The player whose bank account to open. + */ +fun openDepositBox(player: Player) { + restrictForIronman(player, IronmanMode.ULTIMATE) { + player.bank.openDepositBox() + } +} + +/** + * Opens the given player's bank PIN settings interface. + * + * It will send a prohibition message to Ultimate Ironmen. + * + * @author vddCore + * @param player The player whose PIN settings to open. + */ +fun openBankPinSettings(player: Player) { + restrictForIronman(player, IronmanMode.ULTIMATE) { + player.bankPinManager.openSettings() + } +} + +enum class SecondaryBankAccountActivationResult { + SUCCESS, + ALREADY_ACTIVE, + NOT_ENOUGH_MONEY, + INTERNAL_FAILURE +} +/** + * Activates the secondary bank account and handles all the fees required. + * + * @author vddCore + * @param player The player whose secondary bank account to activate. + * @returns Whether the operation was successful or not. + */ +fun activateSecondaryBankAccount(player: Player): SecondaryBankAccountActivationResult { + if (hasIronmanRestriction(player, IronmanMode.ULTIMATE)) { + return SecondaryBankAccountActivationResult.INTERNAL_FAILURE + } + + if (hasActivatedSecondaryBankAccount(player)) { + return SecondaryBankAccountActivationResult.ALREADY_ACTIVE + } + + val cost = 5000000 + val coinsInInventory = amountInInventory(player, Items.COINS_995) + val coinsInBank = amountInBank(player, Items.COINS_995) + val coinsTotal = coinsInInventory + coinsInBank + + if (cost > coinsTotal) { + return SecondaryBankAccountActivationResult.NOT_ENOUGH_MONEY + } + + val operationResult = if (cost > coinsInInventory) { + val amountToTakeFromBank = cost - coinsInInventory + + removeItem(player, Item(Items.COINS_995, coinsInInventory), Container.INVENTORY) + && removeItem(player, Item(Items.COINS_995, amountToTakeFromBank), Container.BANK) + } else { + removeItem(player, Item(Items.COINS_995, cost)) + } + + return if (operationResult) { + setAttribute(player, "/save:UnlockedSecondaryBank", true) + SecondaryBankAccountActivationResult.SUCCESS + } else { + sendMessage(player, "$cost;$coinsInInventory;$coinsInBank;$coinsTotal") + SecondaryBankAccountActivationResult.INTERNAL_FAILURE + } +} + +/** + * Checks if the player has unlocked their secondary bank account. + * + * @author vddCore + * @param player The player whose secondary bank activation status to inspect. + * @return Secondary bank activation status. + */ +fun hasActivatedSecondaryBankAccount(player: Player): Boolean { + return getAttribute(player, "UnlockedSecondaryBank", false) +} + +/** + * Toggles between the player's primary and/or secondary bank account. + * Has no effect if the secondary bank account hasn't been activated. + * + * It will send a prohibition message to Ultimate Ironmen. + * + * @author vddCore + * @param player The player whose bank accounts to toggle. + */ +fun toggleBankAccount(player: Player) { + restrictForIronman(player, IronmanMode.ULTIMATE) { + if (!hasActivatedSecondaryBankAccount(player)) { + return@restrictForIronman + } + + player.useSecondaryBank = !player.useSecondaryBank + } +} + +/** + * Checks if a player is currentl using their secondary bank account. + * + * @author vddCore + * @param player The player whose bank account toggle state to inspect. + */ +fun isUsingSecondaryBankAccount(player: Player): Boolean { + return player.useSecondaryBank +} + +/** + * Returns 'primary' or 'secondary' strings based on which + * bank account is activated for the given user. + * + * @author vddCore + * @param player The player whose bank account name to retrieve. + * @param invert Whether to invert the return value. + * @return Bank account name according to the given criteria. + */ +fun getBankAccountName(player: Player, invert: Boolean = false): String { + return if (isUsingSecondaryBankAccount(player)) { + if (invert) "primary" else "secondary" + } else { + if (invert) "secondary" else "primary" + } +} + +/** + * Opens a shop for the given NPC in the provided player's context. + * + * @author vddCore + * @param player The player serving as the shop context. + * @param npc The NPC ID whose shop to open. + */ +fun openNpcShop(player: Player, npc: Int): Boolean { + val shop = Shops.shopsByNpc[npc] + + if (shop != null) { + shop.openFor(player) + return true + } + + return false +} + +/** + * Skill Dialogue builder. + * @param player the player to send the dialogue for. + * Use like: + * sendSkillDialogue(player) { + * withItems(Items.EXAMPLE_0, Items.EXAMPLE_1) + * create { id, amount -> + * doSomethingWith(id, amount) + * } + * calculateMaxAmount { id -> + * return someAmount + * } + * } + */ +fun sendSkillDialogue(player: Player, init: SkillDialogueBuilder.() -> Unit) { + val builder = SkillDialogueBuilder() + builder.player = player + builder.init() + + if (builder.items.size !in 1..5) { + throw IllegalStateException("Invalid number of items passed to skill dialogue (min 1, max 5): ${builder.items.size}") + } + + val type = when (builder.items.size) { + 1 -> SkillDialogueHandler.SkillDialogue.ONE_OPTION + 2 -> SkillDialogueHandler.SkillDialogue.TWO_OPTION + 3 -> SkillDialogueHandler.SkillDialogue.THREE_OPTION + 4 -> SkillDialogueHandler.SkillDialogue.FOUR_OPTION + 5 -> SkillDialogueHandler.SkillDialogue.FIVE_OPTION + else -> null + } + + object : SkillDialogueHandler(player, type, *builder.items) { + override fun create(amount: Int, index: Int) { + builder.creationCallback(builder.items[index].id, amount) + } + + override fun getAll(index: Int): Int { + return builder.totalAmountCallback(builder.items[index].id) + } + }.open() +} + +class SkillDialogueBuilder { + internal lateinit var player: Player + internal var items: Array = arrayOf() + internal var creationCallback: (itemId: Int, amount: Int) -> Unit = {_,_ -> } + internal var totalAmountCallback: (itemId: Int) -> Int = {id -> amountInInventory(player, id)} + + fun withItems(vararg item: Item) { + items = arrayOf(*item) + } + + fun withItems(vararg item: Int) { + items = item.map { Item(it) }.toTypedArray() + } + + fun create(method: (itemId: Int, amount: Int) -> Unit) { + creationCallback = method + } + + fun calculateMaxAmount(method: (itemId: Int) -> Int) { + totalAmountCallback = method + } +} + +/** + * Registers a hint icon with the given height at the given location + * @param player the player to register the hint icon for + * @param height the height of the hint icon + * @param location the location of the hint icon + */ +fun registerHintIcon(player: Player, location: Location, height: Int) { + setAttribute(player, "hinticon", HintIconManager.registerHintIcon(player, location, 1, -1, player.hintIconManager.freeSlot(), height, 3)) +} + +/** + * Registers a hint icon for the given Node. + * @param player the player to show a hint icon to. + * @param node the Node to register a hint icon for. + */ +fun registerHintIcon(player: Player, node: Node) { + if (getAttribute(player, "hinticon", null) != null) + return + setAttribute(player, "hinticon", HintIconManager.registerHintIcon(player, node)) +} + +/** + * Clears the active ContentAPI-originated hint icon + * @param player the player to clear the active hint icon for + */ +fun clearHintIcon(player: Player) { + val slot = getAttribute(player, "hinticon", -1) + player.removeAttribute("hinticon") + HintIconManager.removeHintIcon(player, slot) +} + +/** + * Gets the equipment slot the item belongs to + * @param item the Id of the item to check + * @return the EquipmentSlot, or null if the item cannot be equipped, or has no slot defined. + */ +fun equipSlot(item: Int) : EquipmentSlot? { + return EquipmentSlot + .values() + .getOrNull(itemDefinition(item).getConfiguration(ItemConfigParser.EQUIP_SLOT, -1)) +} + +/** + * Adjusts the user's credits by the given amount + * @param player the player whose credits to adjust + * @param amt the amount to adjust by - add with positive, remove with negative. + * @return true if successful. Success is defined as always true when adding, but can be false if we are trying to remove, and it would put the amount below 0. + */ +fun updateCredits(player: Player, amount: Int) : Boolean { + val creds = getCredits(player) + amount + + if (creds < 0) + return false + else + player.details.accountInfo.credits = creds + + return true +} + +/** + * Gets the number of credits a user has. + * @param player the player to check + * @return the number of credits they have + */ +fun getCredits(player: Player) : Int { + return player.details.accountInfo.credits +} + +/** + * Asserts that a quest is required, and sends the player "You must have completed the $quest quest $message" + * @param player the player we are checking + * @param quest the quest we are checking for + * @param message the text appended to "You must have completed the $quest quest ..." if the quest is not complete. + * @return whether or not the quest has been completed + */ +fun requireQuest(player: Player, quest: Quests, message: String) : Boolean { + if (!isQuestComplete(player, quest)) { + sendMessage(player, "You must have completed the $quest quest $message") + return false + } + return true +} + + +/** + * Determines whether or not specified node is a player + * @param entity the node whom we are checking + * @return whether or not the entity is a player + */ +fun isPlayer(node: Node) : Boolean { + return (node is Player) +} + +/** + * Adds a dialogue action to the player's dialogue interpreter + * @param player the player to add the dialogue action to + * @param action the dialogue action to add + */ +fun addDialogueAction(player: Player, action: core.game.dialogue.DialogueAction) { + player.dialogueInterpreter.addAction(action) +} + +/** + * Logs a message to the server console + * @param origin simply put (Kotlin) this::class.java or (Java) this.getClass() + * @param type the type of log: Log.FINE (default, visible on VERBOSE), Log.INFO (visible on DETAILED), Log.WARN (visible on CAUTIOUS), Log.ERR (always visible) + * @param message the actual message to log. + */ +fun log(origin: Class<*>, type: Log, message: String) { + SystemLogger.processLogEntry(origin, type, message) +} + +/** + * Logs a message to the server console along with a stack trace leading up to it. + * @param origin simply put (Kotlin) this::class.java or (Java) this.getClass() + * @param type the type of log: Log.FINE (default, visible on VERBOSE), Log.INFO (visible on DETAILED), Log.WARN (visible on CAUTIOUS), Log.ERR (always visible) + * @param message the actual message to log. +*/ +fun logWithStack(origin: Class<*>, type: Log, message: String) { + try { + throw Exception(message) + } catch (e: Exception) { + log(origin, type, "${exceptionToString(e)}") + } +} + +/** + * Takes an exception as an argument, and sends back the complete exception with stack trace as a standard string. Useful for various things. + * @param e The exception you wish to convert. + * @return a string with the full stack trace of the exception +**/ +fun exceptionToString (e: Exception) : String { + val sw = StringWriter() + val pw = PrintWriter(sw) + e.printStackTrace(pw) + return sw.toString() +} + +/** + * Used by content handlers to check if the entity is done moving yet + */ +fun finishedMoving(entity: Entity) : Boolean { + return entity.clocks[Clocks.MOVEMENT] < GameWorld.ticks +} + + +/** + * Delay the execution of the currently running script + */ +fun delayScript(entity: Entity, ticks: Int): Boolean { + entity.scripts.getActiveScript()?.let { it.nextExecution = GameWorld.ticks + ticks } + return false +} + +/** + * Set the global delay for the entity, pausing execution of all queues/scripts until passed. + */ +fun delayEntity(entity: Entity, ticks: Int) { + entity.scripts.delay = GameWorld.ticks + ticks + lock(entity, ticks) //TODO: REMOVE WHEN EVERYTHING IMPORTANT USES PROPER QUEUES - THIS IS INCORRECT BEHAVIOR +} + +fun apRange(entity: Entity, apRange: Int) { + entity.scripts.apRange = apRange + entity.scripts.apRangeCalled = true +} + +fun hasLineOfSight(entity: Entity, target: Node) : Boolean { + return CombatSwingHandler.isProjectileClipped (entity, target, false) +} + +fun animationFinished(entity: Entity) : Boolean { + return entity.clocks[Clocks.ANIMATION_END] < GameWorld.ticks +} + +fun clearScripts(entity: Entity) : Boolean { + entity.scripts.reset() + return true +} + +fun restartScript(entity: Entity) : Boolean { + if (entity.scripts.getActiveScript()?.persist != true) { + log(entity.scripts.getActiveScript()!!::class.java, Log.ERR, "Tried to call restartScript on a non-persistent script! Either use stopExecuting() or make the script persistent.") + return clearScripts(entity) + } + return true +} + +fun keepRunning(entity: Entity) : Boolean { + entity.scripts.getActiveScript()?.nextExecution = getWorldTicks() + 1 + return false +} + +fun stopExecuting(entity: Entity) : Boolean { + if (entity.scripts.getActiveScript()?.persist == true) { + log(entity.scripts.getActiveScript()!!::class.java, Log.ERR, "Tried to call stopExecuting() on a persistent script! To halt execution of a persistent script, you MUST call clearScripts()!") + return clearScripts(entity) + } + return true +} + +fun queueScript(entity: Entity, delay: Int = 1, strength: QueueStrength = QueueStrength.WEAK, persist: Boolean = false, script: (stage: Int) -> Boolean) { + val s = QueuedScript(script, strength, persist) + s.nextExecution = getWorldTicks() + delay + entity.scripts.addToQueue(s, strength) +} + +/** + * Sets the clock to the value of WORLD_TICSK + ticks. + * @param entity the entity whose clock we are updating + * @param clock the clock we are updating. Please use [core.game.interaction.Clocks] for this argument. + * @param ticks the number of ticks to delay by + * @return always returns false so this can be used as a script return value. +**/ +fun delayClock(entity: Entity, clock: Int, ticks: Int) : Boolean { + entity.clocks[clock] = getWorldTicks() + ticks + return false +} + +/** + * Checks if a clock is ready (have we elapsed any delay put into it) + * @param entity the entity whose clock we are checking + * @param clock the clock we are checking. Please use [core.game.interaction.Clocks] for this argument. + * @return true if we have elapsed the clock's wait +**/ +fun clockReady(entity: Entity, clock: Int) : Boolean { + return entity.clocks[clock] <= getWorldTicks() +} + +fun delayAttack(entity: Entity, ticks: Int) { + entity.properties.combatPulse.delayNextAttack(3) + entity.clocks[Clocks.NEXT_ATTACK] = getWorldTicks() + ticks +} + +fun stun(entity: Entity, ticks: Int) { + stun(entity, ticks, true) +} + +fun stun(entity: Entity, ticks: Int, sendMessage: Boolean) { + entity.walkingQueue.reset() + entity.pulseManager.clear() + entity.locks.lockMovement(ticks) + entity.clocks[Clocks.STUN] = getWorldTicks() + ticks + entity.graphics(Graphics(80, 96)) + if (entity is Player) { + playAudio(entity.asPlayer(), Sounds.STUNNED_2727) + entity.animate(Animation(424, Animator.Priority.VERY_HIGH)) + if (sendMessage) { + sendMessage(entity, "You have been stunned!") + } + } +} + +fun isStunned(entity: Entity) : Boolean { + return entity.clocks[Clocks.STUN] >= getWorldTicks() +} + +/** + * Applies poison to the target. (In other words, creates and starts a poison timer.) + * @param entity the entity who will be receiving the poison damage. + * @param source the entity to whom credit for the damage should be awarded (the attacker.) You should award credit to the victim if the poison is sourceless (e.g. from a trap or plant or something) + * @param severity the severity of the poison damage. Severity is not a 1:1 representation of damage, rather the formula `floor((severity + 4) / 5)` is used. Severity is decreased by 1 with each application of the poison, and ends when it reaches 0. + * @see To those whe ask "why severity instead of plain damage?" to which the answer is: severity is how it works authentically, and allows for scenarios where, e.g. a poison should hit 6 once, and then drop to 5 immediately. +**/ +fun applyPoison (entity: Entity, source: Entity, severity: Int) { + if(hasTimerActive(entity)) { + return + } + val existingTimer = getTimer(entity) + + if (existingTimer != null) { + existingTimer.severity = severity + existingTimer.damageSource = source + } else { + registerTimer(entity, spawnTimer(source, severity)) + } +} + +fun isPoisoned (entity: Entity) : Boolean { + return getTimer(entity) != null +} + +fun curePoison (entity: Entity) { + if (!hasTimerActive(entity)) + return + removeTimer(entity) + if (entity is Player) + sendMessage(entity, "Your poison has been cured.") +} + +fun setCurrentScriptState(entity: Entity, state: Int) { + val script = entity.scripts.getActiveScript() + if (script == null) { + log(ContentAPI::class.java, Log.WARN, "Tried to set a script state when no script was being ran!") + if (GameWorld.settings?.isDevMode != true) return + throw IllegalStateException("Script execution mistake - check stack trace and above warning log!") + } + script.state = state - 1 //set it to 1 below the state so that on next execution the state is at the expected value. +} + +/** + * Modifies prayer points by value + * @param player the player to modify prayer points + * @param amount the amount of points to modify by (positive for increment, negative for decrement) + */ +fun modPrayerPoints(player: Player, amount: Double) { + if(amount > 0) player.skills.incrementPrayerPoints(amount) + else if(amount < 0) player.skills.decrementPrayerPoints(amount.absoluteValue) + else return +} + +/** + * Iterates a container and "decants" every potion type in the container. (Decanting is the process of condensing multiple variable-dose potions into the minimum number of max-dose potions) + * @param container the container to iterate + * @return a pair where the first element is the list of items to be removed, and the second element is the list of items to add. +*/ +fun decantContainer (container: core.game.container.Container) : Pair, List> { + val doseCount = HashMap() + val toRemove = ArrayList() + val toAdd = ArrayList() + val doseRegex = Pattern.compile("(\\([0-9]\\))") //Matches "(2)" in "Defense potion (2)" + + for (item in container.toArray()) { + if (item == null) continue + val potionType = Consumables.getConsumableById(item.id)?.consumable as? Potion ?: continue + val matcher = doseRegex.matcher(item.name) + if (!matcher.find()) continue + val dosage = matcher.group(1).replace("(","").replace(")","").toIntOrNull() ?: continue + doseCount[potionType] = (doseCount[potionType] ?: 0) + dosage + toRemove.add(item) + } + + for ((consumable, count) in doseCount) { + val maxDose = consumable.ids.size + val totalMaxDosePotions = count / maxDose + val remainderDose = count % maxDose + if (totalMaxDosePotions > 0) + toAdd.add(Item(consumable.ids[0], totalMaxDosePotions)) + if (remainderDose > 0) + toAdd.add(Item(consumable.ids[consumable.ids.size - remainderDose])) + } + + val emptyVials = toRemove.size - toAdd.sumBy { it.amount } + if (emptyVials > 0) + toAdd.add(Item(229, emptyVials)) + return Pair,List>(toRemove, toAdd) +} + +/** + * Checks whether the user has a valid anti-dragonfire shield equipped. + * @param player the player whose shield we are checking. + * @param wyvern an optional parameter (default false) whether or not we are checking against wyvern fire, which ignores normal anti-dragon-shields, but accepts elemental/mind shields, etc. + * @return whether or not the player is protected by their shield. + * @see Source +**/ +fun hasDragonfireShieldProtection(player: Player, wyvern: Boolean = false): Boolean { + val shield = getItemFromEquipment(player, EquipmentSlot.SHIELD) ?: return false + return when (shield.id) { + Items.ELEMENTAL_SHIELD_2890, Items.MIND_SHIELD_9731 -> wyvern + Items.ANTI_DRAGON_SHIELD_1540 -> !wyvern + Items.DRAGONFIRE_SHIELD_11283, Items.DRAGONFIRE_SHIELD_11284 -> true + else -> false + } +} + +/** + * Calculates the expected max hit of dragonfire after checking/applying valid protections. + * @param entity the entity whose protection we are checking. + * @param maxDamage the max damage the dragonfire can do without protection. + * @param wyvern an optional parameter (default false) that defines whether or not this is wyvern fire. Wyvern fire ignores anti-fire potions and regular anti-dragon shield. + * @param unprotectableDamage an optional parameter (default 0) that defines how much damage cannot be protected against. Think of it as a minimum-max-hit. + * @param sendMessage an optional parameter (default false) whether or not to send a message notifying the player of the damage being blocked. + * @return the maximum amount of damage that can be done to the player. + * @see Source +**/ +fun calculateDragonfireMaxHit(entity: Entity, maxDamage: Int, wyvern: Boolean = false, unprotectableDamage: Int = 0, sendMessage: Boolean = false): Int { + val hasShield: Boolean + val hasPotion: Boolean + val hasPrayer: Boolean + + if (entity is Player) { + hasShield = hasDragonfireShieldProtection(entity, wyvern) + hasPotion = !wyvern && hasTimerActive(entity) + hasPrayer = entity.prayer.get(PrayerType.PROTECT_FROM_MAGIC) + + if (sendMessage) { + var message = "You are horribly burnt by the ${if (wyvern) "icy" else "fiery"} breath." + if (hasShield && hasPotion) + message = "Your potion and shield fully absorb the ${if (wyvern) "icy" else "fiery"} breath." + else if (hasShield) + message = "Your shield absorbs most of the ${if (wyvern) "icy" else "fiery"} breath." + else if (hasPotion) + message = "Your potion absorbs some of the fiery breath." + else if (hasPrayer) + message = "Your prayer absorbs some of the ${if (wyvern) "icy" else "fiery"} breath." + sendMessage(entity, message) + } + } else { + val dragonfireTokens = entity.getDragonfireProtection(!wyvern) + hasShield = dragonfireTokens and 0x2 != 0 + hasPotion = dragonfireTokens and 0x4 != 0 + hasPrayer = dragonfireTokens and 0x8 != 0 + } + + var effectiveDamage = maxDamage.toDouble() + if (hasPrayer && !hasShield && !hasPotion) + effectiveDamage -= 0.6 * maxDamage + else { + if (hasShield) + effectiveDamage -= 0.9 * maxDamage + if (hasPotion) + effectiveDamage -= 0.1 * maxDamage + } + + return Math.max(unprotectableDamage, effectiveDamage.toInt()) +} + +/** + * Opens a single interface tab from given ID. + * @param player the player to open interface for + * @param component the component ID to open + */ +fun openSingleTab(player: Player, component: Int) { + player.interfaceManager.openSingleTab(Component(component)) +} + +private class ContentAPI diff --git a/Server/src/main/core/api/ContentInterface.kt b/Server/src/main/core/api/ContentInterface.kt new file mode 100644 index 0000000..1c48fe9 --- /dev/null +++ b/Server/src/main/core/api/ContentInterface.kt @@ -0,0 +1,7 @@ +package core.api + +interface ContentInterface { + /** + * A dummy/shell interface that allows us to more easily load content via class scanning + */ +} \ No newline at end of file diff --git a/Server/src/main/core/api/DialUtils.kt b/Server/src/main/core/api/DialUtils.kt new file mode 100644 index 0000000..1149906 --- /dev/null +++ b/Server/src/main/core/api/DialUtils.kt @@ -0,0 +1,90 @@ +package core.api +import java.util.* +import kotlin.math.ceil + +object DialUtils { + val tagRegex = "<([A-Za-z0-9=/]+)>".toRegex() + + fun removeMatches(message: String, regex: Regex): String { + return regex.replace(message, "") + } +} + +/** + * Automatically split a single continuous string into multiple comma-separated lines. + * Should this not work out for any reason, you should fallback to standard npc and player methods for dialogue. + */ +fun splitLines(message: String, perLineLimit: Int = 54): Array { + var lines = Array(ceil(DialUtils.removeMatches(message, DialUtils.tagRegex).length / perLineLimit.toFloat()).toInt()) { "" } + + //short circuit when possible because it's cheaper. + if (lines.size == 1) { + lines[0] = message + return lines + } + + val tokenQueue = LinkedList(message.split(" ")) + var index = 0 + val line = StringBuilder() + var accumulator = 0 + + val openTags = LinkedList() + + fun pushLine() { + if (line.isEmpty()) return + + // find all tags that were opened or closed in the line + for (lineTag in DialUtils.tagRegex.findAll(line)) { + if (lineTag.value.get(1) == '/') { + // closing tag encountered; remove it from the list of open tags + for (openTag in openTags.descendingIterator()) { + val lineTagName = lineTag.value.substring(2, lineTag.value.length - 1) + val openTagName = openTag.substring(1, lineTag.value.length - 2) + if (lineTagName == openTagName) { + openTags.remove(openTag) + break + } + } + } else { + openTags.add(lineTag.value) + } + } + + //allow array to be resized - there are specific edgecases where it becomes necessary. (Check the unit test for example) + if (lines.size == index) + lines = lines.plus(line.toString()) + else + lines[index] = line.toString() + index++ + line.clear() + accumulator = 0 + + // if any unclosed tags remain, add them to the beginning of the new line + for (tag in openTags) line.append(tag) + openTags.clear() + } + + while (!tokenQueue.isEmpty()) { + val shouldSpace = DialUtils.removeMatches(line.toString(), DialUtils.tagRegex).isNotEmpty() + accumulator += DialUtils.removeMatches(tokenQueue.peek(), DialUtils.tagRegex).length + + if (shouldSpace) accumulator += 1 + if (accumulator > perLineLimit) { + pushLine() + continue + } + + if (shouldSpace) line.append(" ") + line.append(tokenQueue.pop()) + } + + pushLine() + + // If there's 5 lines, merge lines 4 and 5 into line 4. + if (lines.size > 4) { + lines[3] = lines[3] + "
" + lines[4] + lines = lines.sliceArray(0..3) + } + + return lines +} diff --git a/Server/src/main/core/api/EquipmentSlot.kt b/Server/src/main/core/api/EquipmentSlot.kt new file mode 100644 index 0000000..0b09e37 --- /dev/null +++ b/Server/src/main/core/api/EquipmentSlot.kt @@ -0,0 +1,43 @@ +package core.api + +enum class EquipmentSlot { + HEAD, + CAPE, + NECK, + WEAPON, + CHEST, + SHIELD, + HIDDEN_1, + LEGS, + HIDDEN_2, + HANDS, + FEET, + HIDDEN_3, + RING, + AMMO; + + companion object { + private val slotMap = HashMap() + + init { + slotMap["head"] = HEAD; slotMap["helm"] = HEAD; slotMap ["helmet"] = HEAD + slotMap["cape"] = CAPE; slotMap["back"] = CAPE + slotMap["neck"] = NECK; slotMap["amulet"] = NECK + slotMap["weapon"] = WEAPON; slotMap["main"] = WEAPON + slotMap["chest"] = CHEST; slotMap["body"] = CHEST; slotMap["torso"] = CHEST + slotMap["shield"] = SHIELD; slotMap["off"] = SHIELD + slotMap["legs"] = LEGS; slotMap["leg"] = LEGS + slotMap["hands"] = HANDS; slotMap["hand"] = HANDS; slotMap["brace"] = HANDS; slotMap["bracelet"] = HANDS + slotMap["feet"] = FEET + slotMap["ring"] = RING + slotMap["ammo"] = AMMO; slotMap["ammunition"] = AMMO + } + + /** + * Return the equipment slot by name. Return null if matching no slot. + */ + fun slotByName(input: String): EquipmentSlot? { + return slotMap[input.lowercase()] + } + } +} \ No newline at end of file diff --git a/Server/src/main/core/api/Event.kt b/Server/src/main/core/api/Event.kt new file mode 100644 index 0000000..1c1bc1e --- /dev/null +++ b/Server/src/main/core/api/Event.kt @@ -0,0 +1,40 @@ +package core.api + +import core.game.event.* + +object Event { + @JvmStatic val ResourceProduced = ResourceProducedEvent::class.java + @JvmStatic val NPCKilled = NPCKillEvent::class.java + @JvmStatic val BoneBuried = BoneBuryEvent::class.java + @JvmStatic val Teleported = TeleportEvent::class.java + @JvmStatic val FireLit = LitFireEvent::class.java + @JvmStatic val LightSourceLit = LitLightSourceEvent::class.java + @JvmStatic val Interacted = InteractionEvent::class.java + @JvmStatic val ButtonClicked = ButtonClickEvent::class.java + @JvmStatic val DialogueOpened = DialogueOpenEvent::class.java + @JvmStatic val DialogueOptionSelected = DialogueOptionSelectionEvent::class.java + @JvmStatic val DialogueClosed = DialogueCloseEvent::class.java + @JvmStatic val UsedWith = UseWithEvent::class.java + @JvmStatic val SelfDeath = SelfDeathEvent::class.java + @JvmStatic val Tick = TickEvent::class.java + @JvmStatic val PickedUp = PickUpEvent::class.java + @JvmStatic val InterfaceOpened = InterfaceOpenEvent::class.java + @JvmStatic val InterfaceClosed = InterfaceCloseEvent::class.java + @JvmStatic val AttributeSet = AttributeSetEvent::class.java + @JvmStatic val AttributeRemoved = AttributeRemoveEvent::class.java + @JvmStatic val SpellCast = SpellCastEvent::class.java + @JvmStatic val ItemAlchemized = ItemAlchemizationEvent::class.java + @JvmStatic val ItemEquipped = ItemEquipEvent::class.java + @JvmStatic val ItemUnequipped = ItemUnequipEvent::class.java + @JvmStatic val ItemPurchased = ItemShopPurchaseEvent::class.java + @JvmStatic val ItemSold = ItemShopSellEvent::class.java + @JvmStatic val JobAssigned = JobAssignmentEvent::class.java + @JvmStatic val FairyRingDialed = FairyRingDialEvent::class.java + @JvmStatic val VarbitUpdated = VarbitUpdateEvent::class.java + @JvmStatic val DynamicSkillLevelChanged = DynamicSkillLevelChangeEvent::class.java + @JvmStatic val SummoningPointsRecharged = SummoningPointsRechargeEvent::class.java + @JvmStatic val PrayerPointsRecharged = PrayerPointsRechargeEvent::class.java + @JvmStatic val XpGained = XPGainEvent::class.java + @JvmStatic val PrayerActivated = PrayerActivatedEvent::class.java + @JvmStatic val PrayerDeactivated = PrayerDeactivatedEvent::class.java +} diff --git a/Server/src/main/core/api/God.kt b/Server/src/main/core/api/God.kt new file mode 100644 index 0000000..c2e16c3 --- /dev/null +++ b/Server/src/main/core/api/God.kt @@ -0,0 +1,125 @@ +package core.api + +import org.rs09.consts.Items + +enum class God(vararg val validItems: Int) { + ARMADYL( + Items.ARMADYL_CHESTPLATE_11720, + Items.ARMADYL_GODSWORD_11694, + Items.ARMADYL_HELMET_11718, + Items.ARMADYL_HELMET_CHARGED_12671, + Items.ARMADYL_HELMET_E_12670, + Items.ARMADYL_PENDANT_87, + Items.ARMADYL_PLATESKIRT_11722, + ), + BANDOS( + Items.ANCIENT_MACE_11061, + Items.BANDOS_BOOTS_11728, + Items.BANDOS_CHESTPLATE_11724, + Items.BANDOS_GODSWORD_11696, + Items.BANDOS_TASSETS_11726, + ), + SARADOMIN( + Items.ANCIENT_SYMBOL_11181, + Items.GILDED_KITESHIELD_3489, + Items.HOLY_BOOK_3840, + Items.HOLY_SYMBOL_1718, + Items.HOLY_SYMBOL_4682, + Items.MONKS_ROBE_542, + Items.MONKS_ROBE_544, + Items.RUNE_HERALDIC_HELM_8488, + Items.SARADOMIN_BRACERS_10384, + Items.SARADOMIN_CAPE_2412, + Items.SARADOMIN_CHAPS_10388, + Items.SARADOMIN_CLOAK_10446, + Items.SARADOMIN_COIF_10390, + Items.SARADOMIN_CROZIER_10440, + Items.SARADOMIN_DHIDE_10386, + Items.SARADOMIN_FULL_HELM_2665, + Items.SARADOMIN_GODSWORD_11698, + Items.SARADOMIN_KITESHIELD_2667, + Items.SARADOMIN_MITRE_10452, + Items.SARADOMIN_MJOLNIR_6762, + Items.SARADOMIN_PLATEBODY_2661, + Items.SARADOMIN_PLATELEGS_2663, + Items.SARADOMIN_PLATESKIRT_3479, + Items.SARADOMIN_PLATESKIRT_3675, + Items.SARADOMIN_ROBE_LEGS_10464, + Items.SARADOMIN_ROBE_TOP_10458, + Items.SARADOMIN_STAFF_2415, + Items.SARADOMIN_STOLE_10470, + Items.SARADOMIN_SWORD_11730, + Items.SARADOMIN_SYMBOL_8055, + Items.STEEL_HERALDIC_HELM_8706, + ), + ZAMORAK( + Items.DAGONHAI_HAT_14499, + Items.DAGONHAI_ROBE_TOP_14497, + Items.DAGONHAI_ROBE_BOTTOM_14501, + Items.DAMAGED_BOOK_3841, + Items.RUNE_HERALDIC_HELM_8494, + Items.STEEL_HERALDIC_HELM_8712, + Items.UNHOLY_BOOK_3842, + Items.UNHOLY_SYMBOL_1724, + Items.UNHOLY_SYMBOL_3852, + Items.UNHOLY_SYMBOL_4683, + Items.ZAMORAK_BRACERS_10368, + Items.ZAMORAK_CAPE_2414, + Items.ZAMORAK_CHAPS_10372, + Items.ZAMORAK_CLOAK_10450, + Items.ZAMORAK_COIF_10374, + Items.ZAMORAK_CROZIER_10444, + Items.ZAMORAK_DHIDE_10370, + Items.ZAMORAK_DHIDE_10790, + Items.ZAMORAK_FULL_HELM_2657, + Items.ZAMORAK_GODSWORD_11700, + Items.ZAMORAKIAN_SPEAR_11716, + Items.ZAMORAK_KITESHIELD_2659, + Items.ZAMORAK_MITRE_10456, + Items.ZAMORAK_MJOLNIR_6764, + Items.ZAMORAK_PLATEBODY_10776, + Items.ZAMORAK_PLATEBODY_2653, + Items.ZAMORAK_PLATELEGS_2655, + Items.ZAMORAK_PLATESKIRT_3478, + Items.ZAMORAK_PLATESKIRT_3674, + Items.ZAMORAK_ROBE_LEGS_10468, + Items.ZAMORAK_ROBE_TOP_10460, + Items.ZAMORAK_ROBE_TOP_10786, + Items.ZAMORAK_STAFF_2417, + Items.ZAMORAK_STOLE_10474, + Items.ZAMORAK_SYMBOL_8056, + Items.ZAMORAK_ROBE_1033, + Items.ZAMORAK_ROBE_1035, + ), + GUTHIX( + Items.STEEL_HERALDIC_HELM_8692, + Items.RUNE_HERALDIC_HELM_8474, + Items.GUTHIX_BRACERS_10376, + Items.GUTHIX_CAPE_10720, + Items.GUTHIX_CHAPS_10380, + Items.GUTHIX_CLOAK_10448, + Items.GUTHIX_COIF_10382, + Items.GUTHIX_CROZIER_10442, + Items.GUTHIX_DRAGONHIDE_10378, + Items.GUTHIX_DRAGONHIDE_10794, + Items.GUTHIX_FULL_HELM_13833, + Items.GUTHIX_FULL_HELM_2673, + Items.GUTHIX_KITESHIELD_13834, + Items.GUTHIX_KITESHIELD_2675, + Items.GUTHIX_MITRE_10454, + Items.GUTHIX_MJOLNIR_6760, + Items.GUTHIX_PLATEBODY_10780, + Items.GUTHIX_PLATEBODY_2669, + Items.GUTHIX_PLATEBODY_13830, + Items.GUTHIX_PLATELEGS_2671, + Items.GUTHIX_PLATELEGS_13831, + Items.GUTHIX_PLATESKIRT_13832, + Items.GUTHIX_PLATESKIRT_3676, + Items.GUTHIX_ROBE_LEGS_10466, + Items.GUTHIX_ROBE_TOP_10462, + Items.GUTHIX_ROBE_TOP_10788, + Items.GUTHIX_STAFF_2416, + Items.GUTHIX_STOLE_10472, + Items.GUTHIX_SYMBOL_8057, + ) +} diff --git a/Server/src/main/core/api/IfaceSettingsBuilder.kt b/Server/src/main/core/api/IfaceSettingsBuilder.kt new file mode 100644 index 0000000..d3e5774 --- /dev/null +++ b/Server/src/main/core/api/IfaceSettingsBuilder.kt @@ -0,0 +1,151 @@ +package core.api + +/** + * Used to generate interface settings hashes. + * Deprecates [core.game.container.access.BitregisterAssembler] + * @author Ceikry + */ +class IfaceSettingsBuilder { + /** + * Contains the value which should be sent in access mask packet. + */ + private var value = 0 + + /** + * Sets right click option settings. If specified option is not allowed, it + * might not appear in the context menu, and if it does, it will throw an error when clicked. + * @param optionId The option index. + */ + fun enableOption(optionId: Int): IfaceSettingsBuilder { + require(!(optionId < 0 || optionId > 9)) { "Option index must be 0-9." } + value = value or (0x1 shl optionId + 1) + return this + } + + fun enableOptions(vararg ids: Int): IfaceSettingsBuilder { + for (i in ids.indices) { + enableOption(ids[i]) + } + return this + } + + fun enableOptions(ids: IntRange): IfaceSettingsBuilder { + for (i in ids.start..ids.endInclusive) { + enableOption(i) + } + return this + } + + fun enableAllOptions(): IfaceSettingsBuilder { + for (i in 0..9) { + enableOption(i) + } + return this + } + + fun enableOptions(vararg options: String?): IfaceSettingsBuilder { + for (i in options.indices) { + enableOption(i) + } + return this + } + + /** + * Sets use on option settings. If nothing is allowed then 'use' option will + * not appear in right click menu. + */ + fun setUseOnSettings( + groundItems: Boolean, + npcs: Boolean, + objects: Boolean, + otherPlayer: Boolean, + selfPlayer: Boolean, + component: Boolean + ): IfaceSettingsBuilder { + var useFlag = 0 + if (groundItems) { + useFlag = useFlag or 0x1 + } + if (npcs) { + useFlag = useFlag or 0x2 + } + if (objects) { + useFlag = useFlag or 0x4 + } + if (otherPlayer) { + useFlag = useFlag or 0x8 + } + if (selfPlayer) { + useFlag = useFlag or 0x10 + } + if (component) { + useFlag = useFlag or 0x20 + } + value = value or (useFlag shl 11) + return this + } + + /** + * Sets interface events depth. For example, we have inventory interface + * which is opened on gameframe interface (548) If depth is 1, then the + * clicks in inventory will also invoke click event handler scripts on + * gameframe interface. Setting depth to 2 also allows dragged items to + * leave the bounds of their container, useful for things such as bank tabs. + * @param depth The depth value. + */ + fun setInterfaceEventsDepth(depth: Int): IfaceSettingsBuilder { + require(!(depth < 0 || depth > 7)) { "depth must be 0-7." } + value = value and (0x7 shl 18).inv() + value = value or (depth shl 18) + return this + } + + /** + * Allows items in this interface container to be switched around + * @return this builder + */ + fun enableSlotSwitch(): IfaceSettingsBuilder { + value = value or (1 shl 21) + return this + } + + /** + * Allows items in this interface container to have a "Use" option + * @return this builder + */ + fun enableUseOption(): IfaceSettingsBuilder { + value = value or (1 shl 17) + return this + } + + fun enableExamine(): IfaceSettingsBuilder { + value = value or (1 shl 9) + return this + } + + /** + * Allows this component to have items used on it + * @return this builder + */ + fun enableUseOnSelf(): IfaceSettingsBuilder { + value = value or (1 shl 22) + return this + } + + /** + * Allows this component to switch item slots with a slot that contains a null (empty slot) + * @return this builder + */ + fun enableNullSlotSwitch(): IfaceSettingsBuilder { + value = value or (1 shl 23) + return this + } + + /** + * Gets the current value. + * @return The value. + */ + fun build(): Int { + return value + } +} \ No newline at end of file diff --git a/Server/src/main/core/api/InputType.kt b/Server/src/main/core/api/InputType.kt new file mode 100644 index 0000000..bdbf2b2 --- /dev/null +++ b/Server/src/main/core/api/InputType.kt @@ -0,0 +1,9 @@ +package core.api + +enum class InputType { + AMOUNT, + NUMERIC, + STRING_SHORT, + STRING_LONG, + MESSAGE +} \ No newline at end of file diff --git a/Server/src/main/core/api/LoginListener.kt b/Server/src/main/core/api/LoginListener.kt new file mode 100644 index 0000000..e761640 --- /dev/null +++ b/Server/src/main/core/api/LoginListener.kt @@ -0,0 +1,17 @@ +package core.api + +import core.game.node.entity.player.Player + +/** + * An interface for writing content that allows the class to execute some code when a player logs in. + * + * Login listeners are called *before* [PersistPlayer] data is parsed. + */ +interface LoginListener : ContentInterface { + /** + * NOTE: This should NOT reference any non-static class-local variables. + * If you need to access a player's specific instance, use an attribute. + * Alternatively, consider using an [api.events.EventHook] if applicable. + */ + fun login(player: Player) +} \ No newline at end of file diff --git a/Server/src/main/core/api/LogoutListener.kt b/Server/src/main/core/api/LogoutListener.kt new file mode 100644 index 0000000..bd84591 --- /dev/null +++ b/Server/src/main/core/api/LogoutListener.kt @@ -0,0 +1,16 @@ +package core.api + +import core.game.node.entity.player.Player + +/** + * An interface for writing content that allows code to be executed by the class when a player logs out. + * + * Logout listeners are called *before* [PersistPlayer] data is saved. + */ +interface LogoutListener : ContentInterface { + /** + * NOTE: This should NOT reference any non-static class-local variables. + * If you need to access a player's specific instance, use an attribute. + */ + fun logout(player: Player) +} \ No newline at end of file diff --git a/Server/src/main/core/api/MapArea.kt b/Server/src/main/core/api/MapArea.kt new file mode 100644 index 0000000..28631f5 --- /dev/null +++ b/Server/src/main/core/api/MapArea.kt @@ -0,0 +1,32 @@ +package core.api + +import core.game.node.entity.Entity +import core.game.world.map.Location +import core.game.world.map.zone.MapZone +import core.game.world.map.zone.RegionZone +import core.game.world.map.zone.ZoneBorders +import core.game.world.map.zone.ZoneRestriction + +/** + * Interface that allows a class to define a map area. + * Optionally-overridable methods include [getRestrictions], [areaEnter], [areaLeave] and [entityStep] + */ +interface MapArea : ContentInterface { + var zone: MapZone + get(){ + return zoneMaps[this::class.java.simpleName + "MapArea"]!! + } + set(value) { + zoneMaps[this::class.java.simpleName + "MapArea"] = value + } + + fun defineAreaBorders() : Array + fun getRestrictions() : Array {return arrayOf()} + fun areaEnter(entity: Entity) {} + fun areaLeave(entity: Entity, logout: Boolean) {} + fun entityStep(entity: Entity, location: Location, lastLocation: Location) {} + + companion object { + val zoneMaps = HashMap() + } +} diff --git a/Server/src/main/core/api/PersistPlayer.kt b/Server/src/main/core/api/PersistPlayer.kt new file mode 100644 index 0000000..76c6db1 --- /dev/null +++ b/Server/src/main/core/api/PersistPlayer.kt @@ -0,0 +1,26 @@ +package core.api + +import core.game.node.entity.player.Player +import org.json.simple.JSONObject + +/** + * An interface for writing content that allows data to be saved and loaded from player saves. + * + * Parsing is called *after* any [LoginListener] is executed. + * + * Saving is called *after* any [LogoutListener] is executed. + */ +interface PersistPlayer : ContentInterface { + /** + * NOTE: This should NOT reference nonstatic class-local variables. + * You need to fetch a player's specific instance of the data and save from that. + * For reference, see [rs09.game.node.entity.skill.slayer.SlayerManager] + */ + fun savePlayer(player: Player, save: JSONObject) + /** + * NOTE: This should NOT reference nonstatic class-local variables. + * You need to fetch a player's specific instance of the data and parse to that. + * For reference, see [rs09.game.node.entity.skill.slayer.SlayerManager] + */ + fun parsePlayer(player: Player, data: JSONObject) +} \ No newline at end of file diff --git a/Server/src/main/core/api/PersistWorld.kt b/Server/src/main/core/api/PersistWorld.kt new file mode 100644 index 0000000..06571fe --- /dev/null +++ b/Server/src/main/core/api/PersistWorld.kt @@ -0,0 +1,6 @@ +package core.api + +interface PersistWorld : ContentInterface { + fun save() + fun parse() +} diff --git a/Server/src/main/core/api/ShutdownListener.kt b/Server/src/main/core/api/ShutdownListener.kt new file mode 100644 index 0000000..21e20e2 --- /dev/null +++ b/Server/src/main/core/api/ShutdownListener.kt @@ -0,0 +1,11 @@ +package core.api + +/** + * An interface for writing content that allows the class to execute code as the server is shutting down + */ +interface ShutdownListener : ContentInterface { + /** + * NOTE: This should NOT reference nonstatic class-local variables. + */ + fun shutdown() +} \ No newline at end of file diff --git a/Server/src/main/core/api/StartupListener.kt b/Server/src/main/core/api/StartupListener.kt new file mode 100644 index 0000000..d3735f5 --- /dev/null +++ b/Server/src/main/core/api/StartupListener.kt @@ -0,0 +1,11 @@ +package core.api + +/** + * An interface for writing content that allows the class to execute code when the server is started. + */ +interface StartupListener : ContentInterface { + /** + * NOTE: This should NOT reference nonstatic class-local variables. + */ + fun startup() +} \ No newline at end of file diff --git a/Server/src/main/core/api/TickListener.kt b/Server/src/main/core/api/TickListener.kt new file mode 100644 index 0000000..f006d59 --- /dev/null +++ b/Server/src/main/core/api/TickListener.kt @@ -0,0 +1,14 @@ +package core.api + +/** + * An interface for writing content that allows the class to be updated each tick. + */ +interface TickListener : ContentInterface { + /** + * NOTE: This should NOT reference nonstatic class-local variables. + * TickListeners are generally for NON-player, WORLD tick events. + * Examples: Fishing spot rotation, grand exchange updates, puro puro randomization, etc. + * If you need something (player/entity)-specific, use an [api.events.EventHook] with the [api.events.TickEvent] + */ + fun tick() +} \ No newline at end of file diff --git a/Server/src/main/core/api/regionspec/RegionSpecification.kt b/Server/src/main/core/api/regionspec/RegionSpecification.kt new file mode 100644 index 0000000..863c980 --- /dev/null +++ b/Server/src/main/core/api/regionspec/RegionSpecification.kt @@ -0,0 +1,33 @@ +package core.api.regionspec + +import core.api.regionspec.contracts.* +import core.game.world.map.Region +import core.game.world.map.RegionChunk +import core.game.world.map.build.DynamicRegion + +class RegionSpecification(val regionContract: RegionSpecContract = EmptyRegionContract(), vararg val chunkContracts: ChunkSpecContract = arrayOf(EmptyChunkContract())) { + constructor(vararg chunkContracts: ChunkSpecContract) : this(EmptyRegionContract(), *chunkContracts) + + fun build(): DynamicRegion { + val dyn = regionContract.instantiateRegion() + Region.load(dyn) + chunkContracts.forEach { it.populateChunks(dyn) } + return dyn + } +} + +fun fillWith(chunk: RegionChunk?): FillChunkContract { + return FillChunkContract(chunk) +} + +fun fillWith(delegate: (Int, Int, Int, Region) -> RegionChunk?) : FillChunkContract { + return FillChunkContract(delegate) +} + +fun copyOf(regionId: Int): RegionSpecContract { + return CloneRegionContract(regionId) +} + +fun using(region: DynamicRegion) : UseExistingRegionContract { + return UseExistingRegionContract(region) +} diff --git a/Server/src/main/core/api/regionspec/contracts/ChunkSpecContract.kt b/Server/src/main/core/api/regionspec/contracts/ChunkSpecContract.kt new file mode 100644 index 0000000..ea4bd93 --- /dev/null +++ b/Server/src/main/core/api/regionspec/contracts/ChunkSpecContract.kt @@ -0,0 +1,7 @@ +package core.api.regionspec.contracts + +import core.game.world.map.build.DynamicRegion + +interface ChunkSpecContract { + fun populateChunks(dyn: DynamicRegion) +} diff --git a/Server/src/main/core/api/regionspec/contracts/CloneRegionContract.kt b/Server/src/main/core/api/regionspec/contracts/CloneRegionContract.kt new file mode 100644 index 0000000..63b3279 --- /dev/null +++ b/Server/src/main/core/api/regionspec/contracts/CloneRegionContract.kt @@ -0,0 +1,9 @@ +package core.api.regionspec.contracts + +import core.game.world.map.build.DynamicRegion + +class CloneRegionContract(val regionId: Int) : RegionSpecContract { + override fun instantiateRegion(): DynamicRegion { + return DynamicRegion.create(regionId) + } +} diff --git a/Server/src/main/core/api/regionspec/contracts/EmptyChunkContract.kt b/Server/src/main/core/api/regionspec/contracts/EmptyChunkContract.kt new file mode 100644 index 0000000..3abd07f --- /dev/null +++ b/Server/src/main/core/api/regionspec/contracts/EmptyChunkContract.kt @@ -0,0 +1,7 @@ +package core.api.regionspec.contracts + +import core.game.world.map.build.DynamicRegion + +class EmptyChunkContract : ChunkSpecContract { + override fun populateChunks(dyn: DynamicRegion) {} +} diff --git a/Server/src/main/core/api/regionspec/contracts/EmptyRegionContract.kt b/Server/src/main/core/api/regionspec/contracts/EmptyRegionContract.kt new file mode 100644 index 0000000..a8f8725 --- /dev/null +++ b/Server/src/main/core/api/regionspec/contracts/EmptyRegionContract.kt @@ -0,0 +1,11 @@ +package core.api.regionspec.contracts + +import core.game.world.map.build.DynamicRegion + +class EmptyRegionContract : RegionSpecContract { + override fun instantiateRegion(): DynamicRegion { + val borders = DynamicRegion.reserveArea(8,8) + val dyn = DynamicRegion(borders) + return dyn + } +} diff --git a/Server/src/main/core/api/regionspec/contracts/FillChunkContract.kt b/Server/src/main/core/api/regionspec/contracts/FillChunkContract.kt new file mode 100644 index 0000000..a26d33b --- /dev/null +++ b/Server/src/main/core/api/regionspec/contracts/FillChunkContract.kt @@ -0,0 +1,54 @@ +package core.api.regionspec.contracts + +import core.game.world.map.BuildRegionChunk +import core.game.world.map.Region +import core.game.world.map.RegionChunk +import core.game.world.map.build.DynamicRegion + +open class FillChunkContract(var chunk: RegionChunk? = null) : ChunkSpecContract { + constructor(chunk: (Int, Int, Int, Region) -> RegionChunk?) : this(null) {this.chunkDelegate = chunk} + + lateinit var sourceRegion: Region + var planes: IntArray = intArrayOf(0) + var replaceCondition: (Int,Int,Int) -> Boolean = {_,_,_ -> true} + var chunkDelegate: (Int, Int, Int, Region) -> RegionChunk? = {_,_,_,_ -> chunk} + + override fun populateChunks(dyn: DynamicRegion) { + for(plane in planes) { + for(x in 0 until 8) + for(y in 0 until 8) + if(replaceCondition.invoke(x,y,plane)) { + val chunk = getChunk(x,y,plane,dyn) + dyn.replaceChunk( + plane, + x, + y, + chunk, + sourceRegion + ) + afterSetting(chunk, x, y, plane, dyn) + } + } + } + + open fun getChunk(x: Int, y: Int, plane: Int, dyn: DynamicRegion) : BuildRegionChunk? { + return chunkDelegate.invoke(x, y, plane, sourceRegion)?.copy(dyn.planes[plane]) + } + + open fun afterSetting(chunk: BuildRegionChunk?, x: Int, y: Int, plane: Int, dyn: DynamicRegion) {} + + fun from(region: Region): FillChunkContract { + this.sourceRegion = region + return this + } + + fun onPlanes(vararg planes: Int) : FillChunkContract { + this.planes = planes + return this + } + + fun onCondition(cond: (Int,Int,Int) -> Boolean): FillChunkContract { + this.replaceCondition = cond + return this + } +} diff --git a/Server/src/main/core/api/regionspec/contracts/RegionSpecContract.kt b/Server/src/main/core/api/regionspec/contracts/RegionSpecContract.kt new file mode 100644 index 0000000..3136bd4 --- /dev/null +++ b/Server/src/main/core/api/regionspec/contracts/RegionSpecContract.kt @@ -0,0 +1,7 @@ +package core.api.regionspec.contracts + +import core.game.world.map.build.DynamicRegion + +interface RegionSpecContract { + fun instantiateRegion(): DynamicRegion +} diff --git a/Server/src/main/core/api/regionspec/contracts/UseExistingRegionContract.kt b/Server/src/main/core/api/regionspec/contracts/UseExistingRegionContract.kt new file mode 100644 index 0000000..24e4bde --- /dev/null +++ b/Server/src/main/core/api/regionspec/contracts/UseExistingRegionContract.kt @@ -0,0 +1,9 @@ +package core.api.regionspec.contracts + +import core.game.world.map.build.DynamicRegion + +class UseExistingRegionContract(val region: DynamicRegion) : RegionSpecContract { + override fun instantiateRegion(): DynamicRegion { + return region + } +} \ No newline at end of file diff --git a/Server/src/main/core/api/utils/CameraUtils.kt b/Server/src/main/core/api/utils/CameraUtils.kt new file mode 100644 index 0000000..d2d95f6 --- /dev/null +++ b/Server/src/main/core/api/utils/CameraUtils.kt @@ -0,0 +1,23 @@ +package core.api.utils + +object CameraUtils { + +} + +/* + * All camera shake types were found by facing the camera North using + * these values: + * Type [0-4] Jit: 0 Amp: 0 Freq: 128 Speed: 2 + * + * **See Also:** [This forum post](https://forum.2009scape.org/viewtopic.php?t=173-in-game-camera-movement-documentation-server-sided) + * + * WARNING: Playing around with camera shake values may potentially trigger seizures for people with photosensitive epilepsy. + * Please use care when discovering camera values. + */ +enum class CameraShakeType { + TRUCK, // camera movement from left to right + PEDESTAL, // camera movement vertically up to down, fixated on one location + DOLLY, // camera movement forwards to backwards + PAN, // camera movement horizontally, fixed on a certain point + TILT // camera movement vertically, fixed on a certain point +} \ No newline at end of file diff --git a/Server/src/main/core/api/utils/Exceptions.kt b/Server/src/main/core/api/utils/Exceptions.kt new file mode 100644 index 0000000..4dd71a8 --- /dev/null +++ b/Server/src/main/core/api/utils/Exceptions.kt @@ -0,0 +1,3 @@ +package core.api.utils + +class ConfigParseException (message: String) : Exception (message) diff --git a/Server/src/main/core/api/utils/NPCDropTable.kt b/Server/src/main/core/api/utils/NPCDropTable.kt new file mode 100644 index 0000000..defe06e --- /dev/null +++ b/Server/src/main/core/api/utils/NPCDropTable.kt @@ -0,0 +1,28 @@ +package core.api.utils + +import core.game.node.entity.Entity +import core.game.node.item.Item + +class NPCDropTable : WeightBasedTable() { + private val charmDrops = WeightBasedTable() + private val tertiaryDrops = WeightBasedTable() + + fun addToCharms(element: WeightedItem): Boolean { + return charmDrops.add(element) + } + + fun addToTertiary(element: WeightedItem) : Boolean { + return tertiaryDrops.add(element) + } + + override fun roll(receiver: Entity?, times: Int): ArrayList { + val items = ArrayList() + // Charms table is always rolled, and should contain explicit "Nothing" + // entries at the data level to account for the chance to not drop a charm. + items.addAll(charmDrops.roll(receiver, times)) + items.addAll(tertiaryDrops.roll(receiver, times)) + items.addAll(super.roll(receiver, times)) + return items + } + +} diff --git a/Server/src/main/core/api/utils/Permadeath.kt b/Server/src/main/core/api/utils/Permadeath.kt new file mode 100644 index 0000000..c7e5069 --- /dev/null +++ b/Server/src/main/core/api/utils/Permadeath.kt @@ -0,0 +1,131 @@ +package core.api.utils + +import content.global.skill.construction.HouseLocation +import content.minigame.blastfurnace.BFPlayerState +import content.minigame.blastfurnace.BlastFurnace +import core.api.isUsingSecondaryBankAccount +import core.api.teleport +import core.api.toggleBankAccount +import core.game.node.entity.player.Player +import core.game.node.entity.player.VarpManager +import core.game.node.entity.player.info.login.PlayerSaver +import core.game.node.entity.player.link.IronmanMode +import core.game.node.entity.player.link.SavedData +import core.game.node.entity.player.link.SpellBookManager +import core.game.node.entity.player.link.diary.DiaryType +import core.game.node.entity.player.link.quest.QuestRepository +import core.game.node.entity.skill.Skills +import core.game.node.item.GroundItem +import core.game.node.item.GroundItemManager +import core.game.world.map.Location +import java.util.ArrayList + +fun permadeath(target: Player) { + teleport(target, Location.create(3094, 3107, 0)) + + // Core + target.inventory.clear() + target.bank.clear() + target.bankSecondary.clear() + for (i in target.bankPrimary.tabStartSlot.indices) { + target.bankPrimary.tabStartSlot[i] = 0 + } + for (i in target.bankSecondary.tabStartSlot.indices) { + target.bankSecondary.tabStartSlot[i] = 0 + } + if (isUsingSecondaryBankAccount(target)) { + toggleBankAccount(target) + } + target.equipment.clear() + target.varpManager = VarpManager(target) + target.varpMap.clear() + target.saveVarp.clear() + target.timers.clearTimers() + + // Skills + target.skills = Skills(target) + + // Settings can be kept + + // Quests + target.questRepository = QuestRepository(target) + + // Appearance doesn't matter because you're going to tutorial island anyway + + // Spellbook + target.spellBookManager.setSpellBook(SpellBookManager.SpellBook.MODERN) + + // Saved data + target.savedData = SavedData(target) + + // Autocast + target.properties.autocastSpell = null + + // Player monitor is a no-op + + // Music player + target.musicPlayer.clearUnlocked() + + // Familiar manager + if (target.familiarManager.hasFamiliar()) { + target.familiarManager.dismiss() + } + val petKeys = target.familiarManager.petDetails.keys.toList() + for (key in petKeys) { + target.familiarManager.removeDetails(key) + } + + // Bank pin data + target.bankPinManager.doCancelPin() + + // House data + target.houseManager.createNewHouseAt(HouseLocation.NOWHERE) + + // Achievements + for (type in DiaryType.values()) { + val diary = target.achievementDiaryManager.getDiary(type) + for (level in 0 until diary.levelStarted.size) { + for (task in 0 until diary.taskCompleted[level].size) { + diary.resetTask(target, level, task) + } + } + } + + // Ironman data + target.ironmanManager.mode = IronmanMode.NONE + + // Emote data + target.emoteManager.emotes.clear() + + // Stat manager is a no-op + + // Attributes + target.clearAttributes() + + // Pouches + for (pouch in target.pouchManager.pouches.values) { + pouch.container.clear() + pouch.currentCap = pouch.capacity + pouch.charges = pouch.maxCharges + pouch.remakeContainer() + } + + // Destroy any dropped items to prevent droptrading to yourself after death + val droppedItems = ArrayList(); + for (item in GroundItemManager.getItems()) { + if (item.dropperUid == target.details.uid) { + droppedItems.add(item) + } + } + for (item in droppedItems) { + GroundItemManager.destroy(item) + } + + // grep -R savePlayer: jobs, treasure trails, brawling gloves, slayer manager, barcrawl, ge history will simply not get saved if we don't run the hooks + // Only the Blast Furnace needs to be reset explicitly + BlastFurnace.playerStates[target.details.uid] = BFPlayerState(target) + + // Sayonara + PlayerSaver(target).save() + target.clear() +} diff --git a/Server/src/main/core/api/utils/PlayerCamera.kt b/Server/src/main/core/api/utils/PlayerCamera.kt new file mode 100644 index 0000000..8be7bed --- /dev/null +++ b/Server/src/main/core/api/utils/PlayerCamera.kt @@ -0,0 +1,52 @@ +package core.api.utils + +import core.game.node.entity.player.Player +import core.net.packet.PacketRepository +import core.net.packet.context.CameraContext +import core.net.packet.out.CameraViewPacket + +/** + * Player camera + * + * @property player + * @constructor Create empty Player camera + * **See Also:** [This forum post](https://forum.2009scape.org/viewtopic.php?t=173-in-game-camera-movement-documentation-server-sided) + * + * WARNING: Playing around with camera values may potentially trigger seizures for people with photosensitive epilepsy. + * Please use care when using camera values. + */ +class PlayerCamera(val player: Player?) { + var ctx: CameraContext? = null + + fun setPosition(x: Int, y: Int, height: Int){ + player ?: return + ctx = CameraContext(player,CameraContext.CameraType.SET,x,y,height,0,0) + PacketRepository.send(CameraViewPacket::class.java,ctx) + } + fun rotateTo(x: Int, y: Int, height: Int, speed: Int){ + player ?: return + ctx = CameraContext(player,CameraContext.CameraType.ROTATION,x,y,height,speed,1) + PacketRepository.send(CameraViewPacket::class.java,ctx) + } + fun rotateBy(diffX: Int, diffY: Int, diffHeight: Int, speed: Int){ + player ?: return + ctx ?: return + ctx = CameraContext(player,CameraContext.CameraType.ROTATION, ctx!!.x + diffX, ctx!!.y + diffY, ctx!!.height + diffHeight,speed,1) + PacketRepository.send(CameraViewPacket::class.java,ctx) + } + fun panTo(x: Int, y: Int, height: Int, speed: Int){ + player ?: return + ctx = CameraContext(player,CameraContext.CameraType.POSITION,x,y,height,speed,1) + PacketRepository.send(CameraViewPacket::class.java,ctx) + } + fun shake(cameraType: Int, jitter: Int, amplitude: Int, frequency: Int, speed: Int){ + player ?: return + ctx = CameraContext(player,CameraContext.CameraType.SHAKE,cameraType,jitter,amplitude,frequency,speed) + PacketRepository.send(CameraViewPacket::class.java,ctx) + } + fun reset(){ + player ?: return + ctx = CameraContext(player,CameraContext.CameraType.RESET, -1, -1, -1, -1, -1) + PacketRepository.send(CameraViewPacket::class.java,ctx) + } +} \ No newline at end of file diff --git a/Server/src/main/core/api/utils/PlayerStatsCounter.kt b/Server/src/main/core/api/utils/PlayerStatsCounter.kt new file mode 100644 index 0000000..3337c3d --- /dev/null +++ b/Server/src/main/core/api/utils/PlayerStatsCounter.kt @@ -0,0 +1,253 @@ +package core.api.utils + +import core.api.StartupListener +import core.game.node.entity.player.Player +import java.io.File +import java.io.FileReader +import org.json.simple.JSONObject +import org.json.simple.parser.JSONParser +import core.ServerConstants +import core.api.log +import core.game.node.item.Item +import core.game.world.GameWorld +import core.integrations.sqlite.SQLiteProvider +import core.tools.Log +import core.tools.SystemLogger.logStartup +import kotlin.io.path.Path + +class PlayerStatsCounter( + private val dbPath: String = Path(ServerConstants.DATA_PATH ?: "", "playerstats", "player_stats.db").toString() +) : StartupListener { + + override fun startup() { + logStartup("Loading Player Stats") + + db = SQLiteProvider(dbPath, expectedTables) + db.initTables() + + if (!tableHasData()) { // TODO: Remove check, porter and raw inserts once SQLite tracking is proven and the live server has been updated + portLegacyKillCounterJsonToSQLite() + } + } + + companion object { + lateinit var db: SQLiteProvider + + private fun resolveUIDFromPlayerUsername(playerUsername: String): Int { + return GameWorld.accountStorage.getAccountInfo(playerUsername).uid + } + + private fun portLegacyKillCounterJsonToSQLite() { + val file = File(Path(ServerConstants.DATA_PATH ?: "", "global_kill_stats.json").toString()) + if (!file.exists()) { + return + } + + val reader = FileReader(file) + val parser = JSONParser() + try { + val data = parser.parse(reader) as JSONObject + val json_kills = data.get("kills") + if (json_kills != null && json_kills is JSONObject) { + var progress = 1 + val totalPlayers = json_kills.size + for ((player, killStats) in json_kills.asIterable()) { + log( + PlayerStatsCounter::class.java, + Log.INFO, + "Porting kill counters for player $progress/$totalPlayers" + ) + if (player is String) { + val playerUid = resolveUIDFromPlayerUsername(player.replace(" ", "_")) + log( + PlayerStatsCounter::class.java, + Log.INFO, + "Player $player ($playerUid)" + ) + for ((npc_id, count) in (killStats as JSONObject).asIterable()) { + log( + PlayerStatsCounter::class.java, + Log.INFO, + "Inserting kill for $player ($playerUid, $npc_id, $count)" + ) + incrementKills( + playerUid, + (npc_id as String).toInt(), + count as Long + ) + } + } + progress++ + } + } + val json_rare_drops = data.get("rare_drops") + if (json_rare_drops != null && json_rare_drops is JSONObject) { + var progress = 1 + val totalPlayers = json_rare_drops.size + for ((player, rareDrops) in json_rare_drops.asIterable()) { + log( + PlayerStatsCounter::class.java, + Log.INFO, + "Porting rare drops for player $progress/$totalPlayers" + ) + if (player is String) { + val playerUid = resolveUIDFromPlayerUsername(player.replace(" ", "_")) + log( + PlayerStatsCounter::class.java, + Log.INFO, + "Player $player ($playerUid)" + ) + for ((item_id, count) in (rareDrops as JSONObject).asIterable()) { + log( + PlayerStatsCounter::class.java, + Log.INFO, + "Inserting rare drop for $player ($playerUid, $item_id, $count)" + ) + incrementRareDrop( + playerUid, + (item_id as String).toInt(), + count as Long + ) + } + } + progress++ + } + } + } catch (e: Exception) { + log(this::class.java, Log.ERR, "Failed parsing ${file.name} - stack trace below.") + e.printStackTrace() + } + } + + private val killsTableDefinition = """ + CREATE TABLE kills( + player_uid INTEGER, + entity_id INTEGER, + kills INTEGER, + PRIMARY KEY(player_uid, entity_id)) + """.trimIndent() + + private val rareDropsTableDefinition = """ + CREATE TABLE rare_drops( + player_uid INTEGER, + item_id INTEGER, + amount INTEGER, + PRIMARY KEY (player_uid, item_id)) + """.trimIndent() + + private val getKillsRowCountSql = """ + SELECT COUNT(1) FROM kills; + """.trimIndent() + + private val insertOrIncrementKillSql = """ + INSERT INTO kills (player_uid, entity_id, kills) + VALUES (?, ?, ?) + ON CONFLICT(player_uid, entity_id) DO UPDATE SET kills = kills + ?; + """.trimIndent() + + private val insertOrIncrementRareDropSql = """ + INSERT INTO rare_drops (player_uid, item_id, amount) + VALUES (?, ?, ?) + ON CONFLICT(player_uid, item_id) DO UPDATE SET amount = amount + ?; + """.trimIndent() + + private val getRareDropsSql = """ + SELECT amount FROM rare_drops WHERE player_uid=? AND item_id=? + """.trimIndent() + + private fun createGetKillsSql(countOfEntitiesToSearchFor: Int): String { + if (countOfEntitiesToSearchFor < 1) { + throw Exception("Should be at least 1") + } + val entitySearchParameterMarkers = "?" + ",?".repeat(countOfEntitiesToSearchFor - 1) + return """ + SELECT SUM(kills) FROM kills WHERE player_uid=? AND entity_id IN ($entitySearchParameterMarkers) + """.trimIndent() + } + + private val expectedTables = hashMapOf( + "kills" to killsTableDefinition, + "rare_drops" to rareDropsTableDefinition, + ) + + private fun tableHasData(): Boolean { + var hasData = false + db.run { conn -> + val statement = conn.prepareStatement(getKillsRowCountSql) + val result = statement.executeQuery() + if (result.next()) { + val rowCount = result.getInt(1) + hasData = rowCount > 0 + } + } + return hasData + } + + @JvmStatic + private fun incrementKills(playerUid: Int, npcId: Int, kills: Long) { + db.run { conn -> + val statement = conn.prepareStatement(insertOrIncrementKillSql) + statement.setInt(1, playerUid) + statement.setInt(2, npcId) + statement.setLong(3, kills) + statement.setLong(4, kills) + statement.execute() + } + } + + @JvmStatic + fun incrementKills(player: Player, npcId: Int) { + incrementKills(player.details.uid, npcId, 1) + } + + @JvmStatic + private fun incrementRareDrop(playerUid: Int, itemId: Int, amount: Long) { + db.run { conn -> + val statement = conn.prepareStatement(insertOrIncrementRareDropSql) + statement.setInt(1, playerUid) + statement.setInt(2, itemId) + statement.setLong(3, amount) + statement.setLong(4, amount) + statement.execute() + } + } + + @JvmStatic + fun incrementRareDrop(player: Player, item: Item) { + incrementRareDrop(player.details.uid, item.id, item.amount.toLong()) + } + + @JvmStatic + fun getKills(player: Player, npcIds: IntArray): Long { + var kills: Long = 0 + db.run { conn -> + val statement = conn.prepareStatement(createGetKillsSql(npcIds.size)) + statement.setInt(1, player.details.uid) + for (npcIdParamIndex in npcIds.indices) { + // +2 because the statement parameterIndexes start at 1 and the first param is the player uid + statement.setInt(npcIdParamIndex + 2, npcIds[npcIdParamIndex]) + } + val result = statement.executeQuery() + if (result.next()) { + kills = result.getLong(1) + } + } + return kills + } + + @JvmStatic + fun getRareDrops(player: Player, itemId: Int): Long { + var rareDropsForItem: Long = 0 + db.run { conn -> + val statement = conn.prepareStatement(getRareDropsSql) + statement.setInt(1, player.details.uid) + statement.setInt(2, itemId) + val result = statement.executeQuery() + if (result.next()) { + rareDropsForItem = result.getLong(1) + } + } + return rareDropsForItem + } + } +} diff --git a/Server/src/main/core/api/utils/Vector.kt b/Server/src/main/core/api/utils/Vector.kt new file mode 100644 index 0000000..eb0688f --- /dev/null +++ b/Server/src/main/core/api/utils/Vector.kt @@ -0,0 +1,75 @@ +package core.api.utils + +import core.game.world.map.Direction +import core.game.world.map.Location +import kotlin.math.* + +class Vector (val x: Double, val y: Double) { + fun normalized() : Vector { + val magnitude = magnitude() + val xComponent = x / magnitude + val yComponent = y / magnitude + return Vector(xComponent, yComponent) + } + + fun magnitude() : Double { + return sqrt(x.pow(2.0) + y.pow(2.0)) + } + + operator fun Vector.unaryMinus() = Vector(-x, -y) + + operator fun times (other: Double) : Vector { + return Vector(this.x * other, this.y * other) + } + + operator fun times (other: Int) : Vector { + return Vector(this.x * other, this.y * other) + } + + operator fun plus (other: Vector) : Vector { + return Vector(this.x + other.x, this.y + other.y) + } + + operator fun minus (other: Vector) : Vector { + return Vector(this.x - other.x, this.y - other.y) + } + + override fun toString() : String { + return "{$x,$y}" + } + + fun invert() : Vector { + return -this + } + + fun toLocation (plane: Int = 0) : Location { + return Location.create(floor(x).toInt(), floor(y).toInt(), plane) + } + + fun toDirection() : Direction { + val norm = normalized() + + if (norm.x >= 0.85) return Direction.EAST + else if (norm.x <= -0.85) return Direction.WEST + + if (norm.y > 0) { + if (norm.y >= 0.85) return Direction.NORTH + return if (norm.x > 0) Direction.NORTH_EAST else Direction.NORTH_WEST + } else { + if (norm.y <= -0.85) return Direction.SOUTH + return if (norm.x > 0) Direction.SOUTH_EAST else Direction.SOUTH_WEST + } + } + + companion object { + @JvmStatic fun betweenLocs (from: Location, to: Location) : Vector { + val xDiff = to.x - from.x + val yDiff = to.y - from.y + return Vector (xDiff.toDouble(), yDiff.toDouble()) + } + @JvmStatic fun deriveWithEqualComponents (magnitude: Double) : Vector { + var sideLength = sqrt(magnitude.pow(2.0) / 2) + return Vector(sideLength, sideLength) + } + } +} diff --git a/Server/src/main/core/api/utils/WeightBasedTable.kt b/Server/src/main/core/api/utils/WeightBasedTable.kt new file mode 100644 index 0000000..79466bf --- /dev/null +++ b/Server/src/main/core/api/utils/WeightBasedTable.kt @@ -0,0 +1,195 @@ +package core.api.utils + +import core.cache.def.impl.ItemDefinition +import content.global.activity.ttrail.ClueLevel +import content.global.activity.ttrail.ClueScrollPlugin +import content.data.tables.RareDropTable +import content.data.tables.CELEMinorTable +import content.data.tables.UncommonSeedDropTable +import content.data.tables.HerbDropTable +import content.data.tables.GemDropTable +import content.data.tables.RareSeedDropTable +import content.data.tables.AllotmentSeedDropTable +import content.global.handlers.item.equipment.fistofguthixgloves.FOGGlovesManager +import core.api.inEquipment +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.tools.RandomFunction +import org.rs09.consts.Items + +open class WeightBasedTable : ArrayList() { + var totalWeight = 0.0 + val guaranteedItems = ArrayList() + + override fun add(element: WeightedItem): Boolean { + return if (element.guaranteed) { + guaranteedItems.add(element) + } else { + totalWeight += element.weight + val randIndex = RandomFunction.random(0, size) + val end = this.size + super.add(element) + + val temp = this[randIndex] + this[randIndex] = element + this[end] = temp + true + } + } + + open fun roll(receiver: Entity? = null) : ArrayList { + return roll(receiver, 1) + } + + open fun roll(receiver: Entity? = null, times: Int = 1): ArrayList{ + val items = ArrayList((guaranteedItems.size + 1) * times) + + for (i in 0 until times) { + items.addAll(guaranteedItems) + + if (size == 1) { + items.add(get(0)) + } else if (isNotEmpty()) { + var rngWeight = RandomFunction.randomDouble(totalWeight) + for (item in this) { + rngWeight -= item.weight + if (rngWeight <= 0) { + items.add(item) + break + } + } + } + } + + return convertWeightedItems(items, receiver) + } + + fun convertWeightedItems(weightedItems: ArrayList, receiver: Entity?): ArrayList { + val safeItems = ArrayList() + for (e in weightedItems) { + val safeItem = when (e.id) { + SLOT_CLUE_EASY -> ClueScrollPlugin.getClue(ClueLevel.EASY) + SLOT_CLUE_MEDIUM -> ClueScrollPlugin.getClue(ClueLevel.MEDIUM) + SLOT_CLUE_HARD -> ClueScrollPlugin.getClue(ClueLevel.HARD) + SLOT_RDT -> RareDropTable.retrieve(receiver) + SLOT_CELEDT -> CELEMinorTable.retrieve() + SLOT_USDT -> UncommonSeedDropTable.retrieve() + SLOT_HDT -> { + if (RandomFunction.nextBool() && receiver is Player) { + if (inEquipment(receiver, Items.IRIT_GLOVES_12856)) { + FOGGlovesManager.updateCharges(receiver) + Item(Items.GRIMY_IRIT_209) + } else if (inEquipment(receiver, Items.AVANTOE_GLOVES_12857)) { + FOGGlovesManager.updateCharges(receiver) + Item(Items.GRIMY_AVANTOE_211) + } else if (inEquipment(receiver, Items.KWUARM_GLOVES_12858)) { + FOGGlovesManager.updateCharges(receiver) + Item(Items.GRIMY_KWUARM_213) + } else if (inEquipment(receiver, Items.CADANTINE_GLOVES_12859)) { + FOGGlovesManager.updateCharges(receiver) + Item(Items.GRIMY_CADANTINE_215) + } else + HerbDropTable.retrieve() + } else { + HerbDropTable.retrieve() + } + } + SLOT_GDT -> GemDropTable.retrieve() + SLOT_RSDT -> RareSeedDropTable.retrieve() + SLOT_ASDT -> AllotmentSeedDropTable.retrieve() + Items.DWARF_REMAINS_0 -> continue + else -> e.getItem() + } + safeItems.add(safeItem ?: continue) + } + return safeItems + } + + open fun canRoll(player: Player): Boolean{ + val guaranteed = guaranteedItems.map { it.getItem() }.toTypedArray() + return (guaranteed.isNotEmpty() && player.inventory.hasSpaceFor(*guaranteed)) || !player.inventory.isFull + } + + fun insertEasyClue(weight: Double): WeightBasedTable { + this.add(WeightedItem(SLOT_CLUE_EASY,1,1,weight,false)) + return this + } + + fun insertMediumClue(weight: Double): WeightBasedTable { + this.add(WeightedItem(SLOT_CLUE_MEDIUM,1,1,weight,false)) + return this + } + + fun insertHardClue(weight: Double): WeightBasedTable { + this.add(WeightedItem(SLOT_CLUE_HARD,1,1,weight,false)) + return this + } + + fun insertRDTRoll(weight: Double): WeightBasedTable { + this.add(WeightedItem(SLOT_RDT,1,1,weight,false)) + return this + } + + fun insertCELEDTRoll(weight: Double): WeightBasedTable { + this.add(WeightedItem(SLOT_CELEDT,1,1,weight,false)) + return this + } + + fun insertSEEDDTRoll(weight: Double): WeightBasedTable { + this.add(WeightedItem(SLOT_USDT,1,1,weight,false)) + return this + } + + fun insertHERBDTRoll(weight: Double): WeightBasedTable { + this.add(WeightedItem(SLOT_HDT,1,1,weight,false)) + return this + } + + fun insertGDTRoll(weight: Double): WeightBasedTable { + this.add(WeightedItem(SLOT_GDT,1,1,weight,false)) + return this + } + + fun insertRSDTRoll(weight: Double): WeightBasedTable { + this.add(WeightedItem(SLOT_RSDT,1,1,weight,false)) + return this + } + + fun insertASDTRoll(weight: Double): WeightBasedTable { + this.add(WeightedItem(SLOT_ASDT,1,1,weight,false)) + return this + } + + companion object { + @JvmStatic + fun create(vararg items: WeightedItem): WeightBasedTable { + val table = WeightBasedTable() + items.forEach { + table.add(it) + } + return table + } + + @JvmField + val SLOT_RDT = Items.TINDERBOX_31 + val SLOT_CLUE_EASY = Items.TOOLKIT_1 + val SLOT_CLUE_MEDIUM = Items.ROTTEN_POTATO_5733 + val SLOT_CLUE_HARD = Items.GRANITE_LOBSTER_POUCH_12070 + val SLOT_CELEDT = Items.NULL_799 + val SLOT_USDT = Items.SACRED_CLAY_POUCH_CLASS_1_14422 + val SLOT_HDT = Items.SACRED_CLAY_POUCH_CLASS_2_14424 + val SLOT_GDT = Items.SACRED_CLAY_POUCH_CLASS_3_14426 + val SLOT_RSDT = Items.SACRED_CLAY_POUCH_CLASS_4_14428 + val SLOT_ASDT = Items.SACRED_CLAY_POUCH_CLASS_5_14430 + } + + override fun toString(): String { + val builder = StringBuilder() + for(item in this){ + builder.append("${ItemDefinition.forId(item.id).name} || Weight: ${item.weight} || MinAmt: ${item.minAmt} || maxAmt: ${item.maxAmt}") + builder.appendLine() + } + return builder.toString() + } +} diff --git a/Server/src/main/core/api/utils/WeightedItem.kt b/Server/src/main/core/api/utils/WeightedItem.kt new file mode 100644 index 0000000..adba25e --- /dev/null +++ b/Server/src/main/core/api/utils/WeightedItem.kt @@ -0,0 +1,10 @@ +package core.api.utils + +import core.game.node.item.Item +import core.tools.RandomFunction + +class WeightedItem(var id: Int, var minAmt: Int, var maxAmt: Int, var weight: Double, var guaranteed: Boolean = false) { + fun getItem(): Item { + return Item(id,RandomFunction.random(minAmt,maxAmt)) + } +} \ No newline at end of file diff --git a/Server/src/main/core/api/utils/WeightedTable.kt b/Server/src/main/core/api/utils/WeightedTable.kt new file mode 100644 index 0000000..a399b8e --- /dev/null +++ b/Server/src/main/core/api/utils/WeightedTable.kt @@ -0,0 +1,61 @@ +package core.api.utils + +import core.tools.* + +/** + * Implementation of a weighted table that supports generic (particularly non-Item) types. +**/ +class WeightedTable : ArrayList>() { + var totalWeight: Double = 0.0 + + fun add (element: T?, weight: Double) : Boolean { + totalWeight += weight + return super.add(Pair(element, weight)) + } + + fun remove (element: T?) : Boolean { + var index = -1 + for ((i, pair) in this.withIndex()) { + val (elem, _) = pair + if (element == elem) { + index = i + break + } + } + if (index == -1) return false + + this.removeAt(index) + return true + } + + override fun removeAt (index: Int) : Pair { + val (_, weight) = this[index] + totalWeight -= weight + return super.removeAt(index) + } + + fun roll() : T? { + if (this.size == 1) return this[0].component1() + else if (this.size == 0) return null + + var shuffled = this.shuffled() + var randWeight = RandomFunction.random(0.0, totalWeight) + + for ((element, weight) in shuffled) { + randWeight -= weight + if (randWeight <= 0) + return element + } + + return null + } + + companion object { + fun create (vararg elements: Pair) : WeightedTable { + var table = WeightedTable() + for ((element, weight) in elements) + table.add (element, weight) + return table + } + } +} diff --git a/Server/src/main/core/auth/Auth.kt b/Server/src/main/core/auth/Auth.kt new file mode 100644 index 0000000..8d55aff --- /dev/null +++ b/Server/src/main/core/auth/Auth.kt @@ -0,0 +1,23 @@ +package core.auth + +import core.ServerConstants +import core.storage.AccountStorageProvider +import core.storage.InMemoryStorageProvider +import core.storage.SQLStorageProvider + +object Auth { + lateinit var authenticator: AuthProvider<*> + lateinit var storageProvider: AccountStorageProvider + + fun configure() { + storageProvider = if (ServerConstants.PERSIST_ACCOUNTS) + SQLStorageProvider() + else + InMemoryStorageProvider() + + authenticator = if (ServerConstants.USE_AUTH) + ProductionAuthenticator().also { it.configureFor(storageProvider) } + else + DevelopmentAuthenticator().also { it.configureFor(storageProvider) } + } +} \ No newline at end of file diff --git a/Server/src/main/core/auth/AuthProvider.kt b/Server/src/main/core/auth/AuthProvider.kt new file mode 100644 index 0000000..69db563 --- /dev/null +++ b/Server/src/main/core/auth/AuthProvider.kt @@ -0,0 +1,22 @@ +package core.auth + +import core.game.node.entity.player.Player +import core.storage.AccountStorageProvider + +abstract class AuthProvider { + lateinit var storageProvider: T + + abstract fun configureFor(provider: T) + + fun canCreateAccountWith(info: UserAccountInfo) : Boolean { + return !storageProvider.checkUsernameTaken(info.username) + } + + abstract fun createAccountWith(info: UserAccountInfo) : Boolean + + abstract fun checkLogin(username: String, password: String) : Pair + + abstract fun checkPassword(player: Player, password: String) : Boolean + + abstract fun updatePassword(username: String, newPassword: String) +} diff --git a/Server/src/main/core/auth/AuthResponse.kt b/Server/src/main/core/auth/AuthResponse.kt new file mode 100644 index 0000000..379d927 --- /dev/null +++ b/Server/src/main/core/auth/AuthResponse.kt @@ -0,0 +1,27 @@ +package core.auth + +enum class AuthResponse { + UnexpectedError, + CouldNotAd, + Success, + InvalidCredentials, + AccountDisabled, + AlreadyOnline, + Updated, + FullWorld, + LoginServerOffline, + LoginLimitExceeded, + BadSessionID, + WeakPassword, + MembersWorld, + CouldNotLogin, + Updating, + TooManyIncorrectLogins, + StandingInMembersArea, + AccountLocked, + ClosedBeta, + InvalidLoginServer, + MovingWorld, + ErrorLoadingProfile, + BannedUser +} diff --git a/Server/src/main/core/auth/DevelopmentAuthenticator.kt b/Server/src/main/core/auth/DevelopmentAuthenticator.kt new file mode 100644 index 0000000..eb26aa4 --- /dev/null +++ b/Server/src/main/core/auth/DevelopmentAuthenticator.kt @@ -0,0 +1,41 @@ +package core.auth + +import core.game.node.entity.player.Player +import core.ServerConstants +import core.storage.AccountStorageProvider + +class DevelopmentAuthenticator : AuthProvider() { + override fun configureFor(provider: AccountStorageProvider) { + storageProvider = provider + } + + override fun checkLogin(username: String, password: String): Pair { + val info: UserAccountInfo + if(!storageProvider.checkUsernameTaken(username.toLowerCase())) { + info = UserAccountInfo.createDefault() + info.username = username + createAccountWith(info) + } else { + info = storageProvider.getAccountInfo(username.toLowerCase()) + } + return Pair(AuthResponse.Success, storageProvider.getAccountInfo(username)) + } + + override fun createAccountWith(info: UserAccountInfo): Boolean { + info.username = info.username.toLowerCase() + if (ServerConstants.NOAUTH_DEFAULT_ADMIN) + info.rights = 2 + storageProvider.store(info) + return true + } + + override fun checkPassword(player: Player, password: String): Boolean { + return password == player.details.password + } + + override fun updatePassword(username: String, newPassword: String) { + val info = storageProvider.getAccountInfo(username) + info.password = newPassword + storageProvider.update(info) + } +} diff --git a/Server/src/main/core/auth/ProductionAuthenticator.kt b/Server/src/main/core/auth/ProductionAuthenticator.kt new file mode 100644 index 0000000..b18592b --- /dev/null +++ b/Server/src/main/core/auth/ProductionAuthenticator.kt @@ -0,0 +1,64 @@ +package core.auth + +import core.game.node.entity.player.Player +import core.game.system.SystemManager +import core.ServerConstants +import core.game.world.repository.Repository +import core.storage.AccountStorageProvider +import core.storage.SQLStorageProvider +import java.sql.SQLDataException +import java.sql.Timestamp + +class ProductionAuthenticator : AuthProvider() { + override fun configureFor(provider: AccountStorageProvider) { + storageProvider = provider + if (provider is SQLStorageProvider) { + provider.configure(ServerConstants.DATABASE_ADDRESS!!, ServerConstants.DATABASE_NAME!!, ServerConstants.DATABASE_USER!!, ServerConstants.DATABASE_PASS!!) + } + } + + override fun createAccountWith(info: UserAccountInfo): Boolean { + try { + info.password = SystemManager.getEncryption().hashPassword(info.password) + info.joinDate = Timestamp(System.currentTimeMillis()) + storageProvider.store(info) + } catch (e: SQLDataException) { + return false + } catch (e: Exception) { + e.printStackTrace() + return false + } + return true + } + + override fun checkLogin(username: String, password: String): Pair { + val info: UserAccountInfo + try { + if (!storageProvider.checkUsernameTaken(username.toLowerCase())) { + return Pair(AuthResponse.InvalidCredentials, null) + } + info = storageProvider.getAccountInfo(username.toLowerCase()) + val passCorrect = SystemManager.getEncryption().checkPassword(password, info.password) + if(!passCorrect || info.password.isEmpty()) + return Pair(AuthResponse.InvalidCredentials, null) + if(info.banEndTime > System.currentTimeMillis()) + return Pair(AuthResponse.AccountDisabled, null) + if(info.online) + return Pair(AuthResponse.AlreadyOnline, null) + } catch (e: Exception) { + e.printStackTrace() + return Pair(AuthResponse.CouldNotLogin, null) + } + return Pair(AuthResponse.Success, info) + } + + override fun checkPassword(player: Player, password: String): Boolean { + return SystemManager.getEncryption().checkPassword(password, player.details.password) + } + + override fun updatePassword(username: String, newPassword: String) { + val info = storageProvider.getAccountInfo(username) + info.password = SystemManager.getEncryption().hashPassword(newPassword) + storageProvider.update(info) + } +} \ No newline at end of file diff --git a/Server/src/main/core/auth/UserAccountInfo.kt b/Server/src/main/core/auth/UserAccountInfo.kt new file mode 100644 index 0000000..58f8e37 --- /dev/null +++ b/Server/src/main/core/auth/UserAccountInfo.kt @@ -0,0 +1,108 @@ +package core.auth + +import java.sql.Timestamp + +class UserAccountInfo( + var username: String, + var password: String, + var uid: Int, + var rights: Int, + var credits: Int, + var ip: String, + var lastUsedIp: String, + var muteEndTime: Long, + var banEndTime: Long, + var contacts: String, + var blocked: String, + var clanName: String, + var currentClan: String, + var clanReqs: String, + var timePlayed: Long, + var lastLogin: Long, + var online: Boolean, + var joinDate: Timestamp +) { + companion object { + val default = createDefault() + @JvmStatic fun createDefault() : UserAccountInfo { + return UserAccountInfo("", "", 0, 0, 0, "", "", 0L, 0L, "", "", "", "", "1,0,8,9", 0L, 0L, false, joinDate = Timestamp(System.currentTimeMillis())).also { it.setInitialReferenceValues() } + } + } + + lateinit var initialValues: Array + + fun setInitialReferenceValues() { + initialValues = toArray() + } + + fun getChangedFields(): Pair, Array> { + val current = toArray() + val changed = ArrayList() + + for(i in current.indices) { + if (current[i] != initialValues[i]) changed.add(i) + } + + return Pair(changed, current) + } + + fun toArray(): Array { + return arrayOf(username, password, uid, rights, credits, ip, lastUsedIp, muteEndTime, banEndTime, contacts, blocked, clanName, currentClan, clanReqs, timePlayed, lastLogin, online, joinDate) + } + + override fun toString(): String { + return "USER:$username,PASS:$password,UID:$uid,RIGHTS:$rights,CREDITS:$credits,IP:$ip,LASTIP:$lastUsedIp" + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as UserAccountInfo + + if (username != other.username) return false + if (password != other.password) return false + if (uid != other.uid) return false + if (rights != other.rights) return false + if (credits != other.credits) return false + if (ip != other.ip) return false + if (lastUsedIp != other.lastUsedIp) return false + if (muteEndTime != other.muteEndTime) return false + if (banEndTime != other.banEndTime) return false + if (contacts != other.contacts) return false + if (blocked != other.blocked) return false + if (clanName != other.clanName) return false + if (currentClan != other.currentClan) return false + if (clanReqs != other.clanReqs) return false + if (timePlayed != other.timePlayed) return false + if (lastLogin != other.lastLogin) return false + if (online != other.online) return false + + return true + } + + override fun hashCode(): Int { + var result = username.hashCode() + result = 31 * result + password.hashCode() + result = 31 * result + uid + result = 31 * result + rights + result = 31 * result + credits + result = 31 * result + ip.hashCode() + result = 31 * result + lastUsedIp.hashCode() + result = 31 * result + muteEndTime.hashCode() + result = 31 * result + banEndTime.hashCode() + result = 31 * result + contacts.hashCode() + result = 31 * result + blocked.hashCode() + result = 31 * result + clanName.hashCode() + result = 31 * result + currentClan.hashCode() + result = 31 * result + clanReqs.hashCode() + result = 31 * result + timePlayed.hashCode() + result = 31 * result + lastLogin.hashCode() + result = 31 * result + online.hashCode() + return result + } + + fun isDefault() : Boolean { + return this == default + } +} \ No newline at end of file diff --git a/Server/src/main/core/cache/Cache.java b/Server/src/main/core/cache/Cache.java new file mode 100644 index 0000000..ce4ed3c --- /dev/null +++ b/Server/src/main/core/cache/Cache.java @@ -0,0 +1,241 @@ +package core.cache; + +import java.io.File; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; + +import core.ServerConstants; +import core.cache.def.impl.AnimationDefinition; +import core.cache.def.impl.GraphicDefinition; +import core.cache.def.impl.ItemDefinition; +import core.cache.def.impl.NPCDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.tools.Log; +import core.tools.SystemLogger; + +import static core.api.ContentAPIKt.log; + +/** + * A cache reader. + * + * @author Emperor + * @author Dragonkk + */ +public final class Cache { + + /** + * The cache file manager. + */ + private static CacheFileManager[] cacheFileManagers; + + /** + * The container cache file informer. + */ + private static CacheFile referenceFile; + + /** + * Construct a new instance. + */ + private Cache(String location) { + try { + init(location); + } catch (Throwable e) { + e.printStackTrace(); + } + } + + /** + * Initialize the cache reader. + * + * @param path The cache path.x + * @throws Throwable When an exception occurs. + */ + public static void init(String path) throws Throwable { + log(Cache.class, Log.FINE, "Initializing cache..."); + byte[] cacheFileBuffer = new byte[520]; + RandomAccessFile containersInformFile = new RandomAccessFile(path + File.separator + "main_file_cache.idx255", "r"); + RandomAccessFile dataFile = new RandomAccessFile(path + File.separator + "main_file_cache.dat2", "r"); + referenceFile = new CacheFile(255, containersInformFile, dataFile, 500000, cacheFileBuffer); + int length = (int) (containersInformFile.length() / 6); + cacheFileManagers = new CacheFileManager[length]; + for (int i = 0; i < length; i++) { + File f = new File(path + File.separator + "main_file_cache.idx" + i); + if (f.exists() && f.length() > 0) { + CacheFile cacheFile = new CacheFile(i, new RandomAccessFile(f, "r"), dataFile, 1000000, cacheFileBuffer); + cacheFileManagers[i] = new CacheFileManager(cacheFile, true); + if (cacheFileManagers[i].getInformation() == null) { + log(Cache.class, Log.ERR, "Error loading cache index " + i + ": no information."); + cacheFileManagers[i] = null; + } + } + } + ItemDefinition.parse(); + SceneryDefinition.parse(); + } + + /** + * Initializes the cache. + */ + public static void init() { + try { + init(ServerConstants.CACHE_PATH); + } catch (Throwable e) { + e.printStackTrace(); + } + } + + /** + * Gets the archive buffer for the grab requests. + * + * @param index The index id. + * @param archive The archive id. + * @param priority The priority. + * @param encryptionValue The current encryption value. + * @return The byte buffer. + */ + public static ByteBuffer getArchiveData(int index, int archive, boolean priority, int encryptionValue) { + byte[] data = index == 255 ? referenceFile.getContainerData(archive) : cacheFileManagers[index].getCacheFile().getContainerData(archive); + if (data == null || data.length < 1) { + log(Cache.class, Log.ERR, "Invalid JS-5 request - " + index + ", " + archive + ", " + priority + ", " + encryptionValue + "!"); + return null; + } + int compression = data[0] & 0xff; + int length = ((data[1] & 0xff) << 24) + ((data[2] & 0xff) << 16) + ((data[3] & 0xff) << 8) + (data[4] & 0xff); + int settings = compression; + if (!priority) { + settings |= 0x80; + } + int realLength = compression != 0 ? length + 4 : length; + + // TODO There are two archives that lack two bytes at the end (The version, most likely). This causes the client CRC to be miscalculated. To combat this, we simply send two more bytes if the length seems to be off. + realLength += (index != 255 && compression != 0 && data.length - length == 9) ? 2 : 0; + ByteBuffer buffer = ByteBuffer.allocate((realLength + 5) + (realLength / 512) + 10); + buffer.put((byte) index); + buffer.putShort((short) archive); + buffer.put((byte) settings); + buffer.putInt(length); + for (int i = 5; i < realLength + 5; i++) { + if (buffer.position() % 512 == 0) { + buffer.put((byte) 255); + } + if (data.length > i) + buffer.put(data[i]); + else + buffer.put((byte) 0); + } + if (encryptionValue != 0) { + for (int i = 0; i < buffer.position(); i++) { + buffer.put(i, (byte) (buffer.get(i) ^ encryptionValue)); + } + } + buffer.flip(); + return buffer; + } + + /** + * Generate the reference data for the cache files. + * + * @return The reference data byte array. + */ + public static final byte[] generateReferenceData() { + ByteBuffer buffer = ByteBuffer.allocate(cacheFileManagers.length * 8); + for (int index = 0; index < cacheFileManagers.length; index++) { + if (cacheFileManagers[index] == null) { + buffer.putInt(index == 24 ? 609698396 : 0); + buffer.putInt(0); + continue; + } + buffer.putInt(cacheFileManagers[index].getInformation().getInformationContainer().getCrc()); + buffer.putInt(cacheFileManagers[index].getInformation().getRevision()); + } + return buffer.array(); + } + + /** + * Get the cache file managers. + * + * @return The cache file managers. + */ + public static final CacheFileManager[] getIndexes() { + return cacheFileManagers; + } + + /** + * Get the container cache file informer. + * + * @return The container cache file informer. + */ + public static final CacheFile getReferenceFile() { + return referenceFile; + } + + /** + * Method used to return the component size of the interface. + * + * @param interfaceId the interface. + * @return the value. + */ + public static final int getInterfaceDefinitionsComponentsSize(int interfaceId) { + return getIndexes()[3].getFilesSize(interfaceId); + } + + /** + * Method used to return the max size of the interface definitions. + * + * @return the size. + */ + public static final int getInterfaceDefinitionsSize() { + return getIndexes()[3].getContainersSize(); + } + + /** + * Method used to return the {@link NPCDefinition} size. + * + * @return the size. + */ + public static final int getNPCDefinitionsSize() { + int lastContainerId = getIndexes()[18].getContainersSize() - 1; + return lastContainerId * 128 + getIndexes()[18].getFilesSize(lastContainerId); + } + + /** + * Method used to return the {@link GraphicDefinition} size. + * + * @return the size. + */ + public static final int getGraphicDefinitionsSize() { + int lastContainerId = getIndexes()[21].getContainersSize() - 1; + return lastContainerId * 256 + getIndexes()[21].getFilesSize(lastContainerId); + } + + /** + * Method used to return the {@link AnimationDefinition} size. + * + * @return the size. + */ + public static final int getAnimationDefinitionsSize() { + int lastContainerId = getIndexes()[20].getContainersSize() - 1; + return lastContainerId * 128 + getIndexes()[20].getFilesSize(lastContainerId); + } + + /** + * Method used to return the {@link SceneryDefinition} size. + * + * @return the size. + */ + public static final int getObjectDefinitionsSize() { + int lastContainerId = getIndexes()[16].getContainersSize() - 1; + return lastContainerId * 256 + getIndexes()[16].getFilesSize(lastContainerId); + } + + /** + * Method used to return the item definition size. + * + * @return the size. + */ + public static final int getItemDefinitionsSize() { + int lastContainerId = getIndexes()[19].getContainersSize() - 1; + return lastContainerId * 256 + getIndexes()[19].getFilesSize(lastContainerId); + } + +} \ No newline at end of file diff --git a/Server/src/main/core/cache/CacheFile.java b/Server/src/main/core/cache/CacheFile.java new file mode 100644 index 0000000..a036428 --- /dev/null +++ b/Server/src/main/core/cache/CacheFile.java @@ -0,0 +1,148 @@ +package core.cache; + +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; + +import core.cache.crypto.XTEACryption; +import core.cache.misc.ContainersInformation; + +/** + * A cache file. + * @author Dragonkk + */ +public final class CacheFile { + + /** + * The index file id. + */ + private int indexFileId; + + /** + * The cache file buffer. + */ + private byte[] cacheFileBuffer; + + /** + * The maximum container size. + */ + private int maxContainerSize; + + /** + * The index file. + */ + private RandomAccessFile indexFile; + + /** + * The data file. + */ + private RandomAccessFile dataFile; + + /** + * Construct a new cache file. + * @param indexFileId The index file id. + * @param indexFile The index file. + * @param dataFile The data file. + * @param maxContainerSize The maximum container size. + * @param cacheFileBuffer The cache file buffer. + */ + public CacheFile(int indexFileId, RandomAccessFile indexFile, RandomAccessFile dataFile, int maxContainerSize, byte[] cacheFileBuffer) { + this.cacheFileBuffer = cacheFileBuffer; + this.indexFileId = indexFileId; + this.maxContainerSize = maxContainerSize; + this.indexFile = indexFile; + this.dataFile = dataFile; + } + + /** + * Get the unpacked container data. + * @param containerId The container id. + * @param xteaKeys The container keys. + * @return The unpacked container data. + */ + public final byte[] getContainerUnpackedData(int containerId, int[] xteaKeys) { + byte[] packedData = getContainerData(containerId); + if (packedData == null) { + return null; + } + if (xteaKeys != null && (xteaKeys[0] != 0 || xteaKeys[1] != 0 || xteaKeys[2] != 0 || xteaKeys[3] != 0)) { + packedData = XTEACryption.decrypt(xteaKeys, ByteBuffer.wrap(packedData), 5, packedData.length).array(); + } + return ContainersInformation.unpackCacheContainer(packedData); + } + + /** + * Get the container data for the specified container id. + * @param containerId The container id. + * @return The container data. + */ + public final byte[] getContainerData(int containerId) { + synchronized (dataFile) { + try { + if (indexFile.length() < (6 * containerId + 6)) { + return null; + } + indexFile.seek(6 * containerId); + indexFile.read(cacheFileBuffer, 0, 6); + int containerSize = (cacheFileBuffer[2] & 0xff) + (((0xff & cacheFileBuffer[0]) << 16) + (cacheFileBuffer[1] << 8 & 0xff00)); + int sector = ((cacheFileBuffer[3] & 0xff) << 16) - (-(0xff00 & cacheFileBuffer[4] << 8) - (cacheFileBuffer[5] & 0xff)); + if (containerSize < 0 || containerSize > maxContainerSize) { + return null; + } + if (sector <= 0 || dataFile.length() / 520L < sector) { + return null; + } + byte data[] = new byte[containerSize]; + int dataReadCount = 0; + int part = 0; + while (containerSize > dataReadCount) { + if (sector == 0) { + return null; + } + dataFile.seek(520 * sector); + int dataToReadCount = containerSize - dataReadCount; + if (dataToReadCount > 512) { + dataToReadCount = 512; + } + dataFile.read(cacheFileBuffer, 0, 8 + dataToReadCount); + int currentContainerId = (0xff & cacheFileBuffer[1]) + (0xff00 & cacheFileBuffer[0] << 8); + int currentPart = ((cacheFileBuffer[2] & 0xff) << 8) + (0xff & cacheFileBuffer[3]); + int nextSector = (cacheFileBuffer[6] & 0xff) + (0xff00 & cacheFileBuffer[5] << 8) + ((0xff & cacheFileBuffer[4]) << 16); + int currentIndexFileId = cacheFileBuffer[7] & 0xff; + if (containerId != currentContainerId || currentPart != part || indexFileId != currentIndexFileId) { + return null; + } + if (nextSector < 0 || (dataFile.length() / 520L) < nextSector) { + return null; + } + for (int index = 0; dataToReadCount > index; index++) { + data[dataReadCount++] = cacheFileBuffer[8 + index]; + } + part++; + sector = nextSector; + } + return data; + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + } + + /** + * Get the index file id. + * @return + */ + public int getIndexFileId() { + return indexFileId; + } + + /** + * Get the unpacked container data. + * @param containerId The container id. + * @return The unpacked container data. + */ + public final byte[] getContainerUnpackedData(int containerId) { + return getContainerUnpackedData(containerId, null); + } +} diff --git a/Server/src/main/core/cache/CacheFileManager.java b/Server/src/main/core/cache/CacheFileManager.java new file mode 100644 index 0000000..023803e --- /dev/null +++ b/Server/src/main/core/cache/CacheFileManager.java @@ -0,0 +1,293 @@ +package core.cache; + +import java.nio.ByteBuffer; + +import core.cache.misc.ContainersInformation; +import core.tools.StringUtils; + +/** + * A cache file manager. + * @author Dragonkk + */ +public final class CacheFileManager { + + /** + * The cache file. + */ + private CacheFile cacheFile; + + /** + * The containers information. + */ + private ContainersInformation information; + + /** + * Discard a files data. + */ + private boolean discardFilesData; + + /** + * A array holding file data. + */ + private byte[][][] filesData; + + /** + * Construct a new cache file manager. + * @param cacheFile The cache file. + * @param discardFilesData To discard a files data. + */ + public CacheFileManager(CacheFile cacheFile, boolean discardFilesData) { + this.cacheFile = cacheFile; + this.discardFilesData = discardFilesData; + byte[] informContainerPackedData = Cache.getReferenceFile().getContainerData(cacheFile.getIndexFileId()); + if (informContainerPackedData == null) { + return; + } + information = new ContainersInformation(informContainerPackedData); + resetFilesData(); + } + + /** + * Get the cache file. + * @return The cache file. + */ + public CacheFile getCacheFile() { + return cacheFile; + } + + /** + * Get the containers size. + * @return The containers size. + */ + public int getContainersSize() { + return information.getContainers().length; + } + + /** + * Get the files size. + * @param containerId The container id. + * @return The files size. + */ + public int getFilesSize(int containerId) { + if (!validContainer(containerId)) { + return -1; + } + return information.getContainers()[containerId].getFiles().length; + } + + /** + * Reset the file data. + */ + public void resetFilesData() { + filesData = new byte[information.getContainers().length][][]; + } + + /** + * Check if a file is valid. + * @param containerId The container id. + * @param fileId The file id. + * @return If the file is valid {@code true}. + */ + public boolean validFile(int containerId, int fileId) { + if (!validContainer(containerId)) { + return false; + } + if (fileId < 0 || information.getContainers()[containerId] == null || information.getContainers()[containerId].getFiles().length <= fileId) { + return false; + } + return true; + + } + + /** + * If a container is valid. + * @param containerId The container id. + * @return If the container is valid {@code true}. + */ + public boolean validContainer(int containerId) { + if (containerId < 0 || information.getContainers().length <= containerId) { + return false; + } + return true; + } + + /** + * Get the file ids. + * @param containerId The container id. + * @return The file ids. + */ + public int[] getFileIds(int containerId) { + if (!validContainer(containerId)) { + return null; + } + return information.getContainers()[containerId].getFilesIndexes(); + } + + /** + * Get the archive id. + * @param name The archive name. + * @return The archive id. + */ + public int getArchiveId(String name) { + if (name == null) { + return -1; + } + int hash = StringUtils.getNameHash(name); + for (int containerIndex = 0; containerIndex < information.getContainersIndexes().length; containerIndex++) { + if (information.getContainers()[information.getContainersIndexes()[containerIndex]].getNameHash() == hash) { + return information.getContainersIndexes()[containerIndex]; + } + } + return -1; + } + + /** + * Get the file data. + * @param containerId The container id. + * @param fileId The file id. + * @return The get file data. + */ + public byte[] getFileData(int containerId, int fileId) { + return getFileData(containerId, fileId, null); + } + + /** + * Load the file data. + * @param archiveId The container id. + * @param keys The container keys. + * @return If the file data is loaded {@code true}. + */ + public boolean loadFilesData(int archiveId, int[] keys) { + byte[] data = cacheFile.getContainerUnpackedData(archiveId, keys); + if (data == null) { + return false; + } + if (filesData[archiveId] == null) { + if (information.getContainers()[archiveId] == null) { + return false; // container inform doesnt exist anymore + } + filesData[archiveId] = new byte[information.getContainers()[archiveId].getFiles().length][]; + } + if (information.getContainers()[archiveId].getFilesIndexes().length == 1) { + int fileId = information.getContainers()[archiveId].getFilesIndexes()[0]; + filesData[archiveId][fileId] = data; + } else { + int readPosition = data.length; + int amtOfLoops = data[--readPosition] & 0xff; + readPosition -= amtOfLoops * (information.getContainers()[archiveId].getFilesIndexes().length * 4); + ByteBuffer buffer = ByteBuffer.wrap(data); + int filesSize[] = new int[information.getContainers()[archiveId].getFilesIndexes().length]; + buffer.position(readPosition); + for (int loop = 0; loop < amtOfLoops; loop++) { + int offset = 0; + for (int fileIndex = 0; fileIndex < information.getContainers()[archiveId].getFilesIndexes().length; fileIndex++) { + filesSize[fileIndex] += offset += buffer.getInt(); + } + } + byte[][] filesBufferData = new byte[information.getContainers()[archiveId].getFilesIndexes().length][]; + for (int fileIndex = 0; fileIndex < information.getContainers()[archiveId].getFilesIndexes().length; fileIndex++) { + filesBufferData[fileIndex] = new byte[filesSize[fileIndex]]; + filesSize[fileIndex] = 0; + } + buffer.position(readPosition); + int sourceOffset = 0; + for (int loop = 0; loop < amtOfLoops; loop++) { + int dataRead = 0; + for (int fileIndex = 0; fileIndex < information.getContainers()[archiveId].getFilesIndexes().length; fileIndex++) { + dataRead += buffer.getInt(); + System.arraycopy(data, sourceOffset, filesBufferData[fileIndex], filesSize[fileIndex], dataRead); + sourceOffset += dataRead; + filesSize[fileIndex] += dataRead; + } + } + for (int fileIndex = 0; fileIndex < information.getContainers()[archiveId].getFilesIndexes().length; fileIndex++) { + filesData[archiveId][information.getContainers()[archiveId].getFilesIndexes()[fileIndex]] = filesBufferData[fileIndex]; + } + } + return true; + + } + + /** + * Get the file data. + * @param containerId The container id. + * @param fileId The file id. + * @param xteaKeys The container keys. + * @return The file data. + */ + public byte[] getFileData(int containerId, int fileId, int[] xteaKeys) { + if (!validFile(containerId, fileId)) { + return null; + } + if (filesData[containerId] == null || filesData[containerId][fileId] == null) { + if (!loadFilesData(containerId, xteaKeys)) { + return null; + } + } + byte[] data = filesData[containerId][fileId]; + if (discardFilesData) { + if (filesData[containerId].length == 1) { + filesData[containerId] = null; + } else { + filesData[containerId][fileId] = null; + } + } + return data; + } + + /** + * Get the containers information. + * @return The containers information. + */ + public ContainersInformation getInformation() { + return information; + } + + /** + * Gets the discardFilesData. + * @return the discardFilesData. + */ + public boolean isDiscardFilesData() { + return discardFilesData; + } + + /** + * Sets the discardFilesData. + * @param discardFilesData the discardFilesData to set + */ + public void setDiscardFilesData(boolean discardFilesData) { + this.discardFilesData = discardFilesData; + } + + /** + * Gets the filesData. + * @return the filesData. + */ + public byte[][][] getFilesData() { + return filesData; + } + + /** + * Sets the filesData. + * @param filesData the filesData to set + */ + public void setFilesData(byte[][][] filesData) { + this.filesData = filesData; + } + + /** + * Sets the cacheFile. + * @param cacheFile the cacheFile to set + */ + public void setCacheFile(CacheFile cacheFile) { + this.cacheFile = cacheFile; + } + + /** + * Sets the information. + * @param information the information to set + */ + public void setInformation(ContainersInformation information) { + this.information = information; + } +} diff --git a/Server/src/main/core/cache/StoreFile.java b/Server/src/main/core/cache/StoreFile.java new file mode 100644 index 0000000..50e1728 --- /dev/null +++ b/Server/src/main/core/cache/StoreFile.java @@ -0,0 +1,72 @@ +package core.cache; + +import java.nio.ByteBuffer; + +/** + * Represents a file used in the server store. + * @author Emperor + */ +public final class StoreFile { + + /** + * If the data can change during server runtime. + */ + private boolean dynamic; + + /** + * The file data. + */ + private byte[] data; + + /** + * Constructs a new {@code StoreFile} {@code Object}. + */ + public StoreFile() { + /* + * empty. + */ + } + + /** + * Puts the data on the buffer. + * @param buffer The buffer. + */ + public void put(ByteBuffer buffer) { + byte[] data = new byte[buffer.remaining()]; + buffer.get(data); + this.data = data; + } + + /** + * Creates a byte buffer containing the file data. + * @return The buffer. + */ + public ByteBuffer data() { + return ByteBuffer.wrap(data); + } + + /** + * Sets the data. + * @param data The data. + */ + public void setData(byte[] data) { + this.data = data; + } + + /** + * Gets the dynamic. + * @return The dynamic. + */ + public boolean isDynamic() { + return dynamic; + } + + /** + * Sets the dynamic. + * @param dynamic The dynamic to set. + */ + public void setDynamic(boolean dynamic) { + this.dynamic = dynamic; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/cache/bzip2/BZip2BlockEntry.java b/Server/src/main/core/cache/bzip2/BZip2BlockEntry.java new file mode 100644 index 0000000..c5c304d --- /dev/null +++ b/Server/src/main/core/cache/bzip2/BZip2BlockEntry.java @@ -0,0 +1,56 @@ +package core.cache.bzip2; + +public class BZip2BlockEntry { + + boolean aBooleanArray2205[]; + boolean aBooleanArray2213[]; + byte aByte2201; + byte aByteArray2204[]; + byte aByteArray2211[]; + byte aByteArray2212[]; + byte aByteArray2214[]; + byte aByteArray2219[]; + byte aByteArray2224[]; + byte aByteArrayArray2229[][]; + int anInt2202; + int anInt2203; + int anInt2206; + int anInt2207; + int anInt2208; + int anInt2209; + int anInt2215; + int anInt2216; + int anInt2217; + int anInt2221; + int anInt2222; + int anInt2223; + int anInt2225; + int anInt2227; + int anInt2232; + int anIntArray2200[]; + int anIntArray2220[]; + int anIntArray2226[]; + int anIntArray2228[]; + int anIntArrayArray2210[][]; + int anIntArrayArray2218[][]; + int anIntArrayArray2230[][]; + + public BZip2BlockEntry() { + anIntArray2200 = new int[6]; + anInt2203 = 0; + aByteArray2204 = new byte[4096]; + aByteArray2211 = new byte[256]; + aByteArray2214 = new byte[18002]; + aByteArray2219 = new byte[18002]; + anIntArray2220 = new int[257]; + anIntArrayArray2218 = new int[6][258]; + aBooleanArray2205 = new boolean[16]; + aBooleanArray2213 = new boolean[256]; + anInt2209 = 0; + anIntArray2226 = new int[16]; + anIntArrayArray2210 = new int[6][258]; + aByteArrayArray2229 = new byte[6][258]; + anIntArrayArray2230 = new int[6][258]; + anIntArray2228 = new int[256]; + } +} diff --git a/Server/src/main/core/cache/bzip2/BZip2Decompressor.java b/Server/src/main/core/cache/bzip2/BZip2Decompressor.java new file mode 100644 index 0000000..f62ec11 --- /dev/null +++ b/Server/src/main/core/cache/bzip2/BZip2Decompressor.java @@ -0,0 +1,532 @@ +package core.cache.bzip2; + +public class BZip2Decompressor { + + private static int anIntArray257[]; + private static BZip2BlockEntry entryInstance = new BZip2BlockEntry(); + + public static final void decompress(byte decompressedData[], byte packedData[], int containerSize, int blockSize) { + synchronized (entryInstance) { + entryInstance.aByteArray2224 = packedData; + entryInstance.anInt2209 = blockSize; + entryInstance.aByteArray2212 = decompressedData; + entryInstance.anInt2203 = 0; + entryInstance.anInt2206 = decompressedData.length; + entryInstance.anInt2232 = 0; + entryInstance.anInt2207 = 0; + entryInstance.anInt2217 = 0; + entryInstance.anInt2216 = 0; + method1793(entryInstance); + entryInstance.aByteArray2224 = null; + entryInstance.aByteArray2212 = null; + } + } + + private static final void method1785(BZip2BlockEntry entry) { + entry.anInt2215 = 0; + for (int i = 0; i < 256; i++) { + if (entry.aBooleanArray2213[i]) { + entry.aByteArray2211[entry.anInt2215] = (byte) i; + entry.anInt2215++; + } + } + + } + + private static final void method1786(int ai[], int ai1[], int ai2[], byte abyte0[], int i, int j, int k) { + int l = 0; + for (int i1 = i; i1 <= j; i1++) { + for (int l2 = 0; l2 < k; l2++) { + if (abyte0[l2] == i1) { + ai2[l] = l2; + l++; + } + } + + } + + for (int j1 = 0; j1 < 23; j1++) { + ai1[j1] = 0; + } + + for (int k1 = 0; k1 < k; k1++) { + ai1[abyte0[k1] + 1]++; + } + + for (int l1 = 1; l1 < 23; l1++) { + ai1[l1] += ai1[l1 - 1]; + } + + for (int i2 = 0; i2 < 23; i2++) { + ai[i2] = 0; + } + + int i3 = 0; + for (int j2 = i; j2 <= j; j2++) { + i3 += ai1[j2 + 1] - ai1[j2]; + ai[j2] = i3 - 1; + i3 <<= 1; + } + + for (int k2 = i + 1; k2 <= j; k2++) { + ai1[k2] = (ai[k2 - 1] + 1 << 1) - ai1[k2]; + } + + } + + private static final void method1787(BZip2BlockEntry entry) { + byte byte4 = entry.aByte2201; + int i = entry.anInt2222; + int j = entry.anInt2227; + int k = entry.anInt2221; + int ai[] = anIntArray257; + int l = entry.anInt2208; + byte abyte0[] = entry.aByteArray2212; + int i1 = entry.anInt2203; + int j1 = entry.anInt2206; + int k1 = j1; + int l1 = entry.anInt2225 + 1; + label0: do { + if (i > 0) { + do { + if (j1 == 0) { + break label0; + } + if (i == 1) { + break; + } + abyte0[i1] = byte4; + i--; + i1++; + j1--; + } while (true); + abyte0[i1] = byte4; + i1++; + j1--; + } + boolean flag = true; + while (flag) { + flag = false; + if (j == l1) { + i = 0; + break label0; + } + byte4 = (byte) k; + l = ai[l]; + byte byte0 = (byte) (l & 0xff); + l >>= 8; + j++; + if (byte0 != k) { + k = byte0; + if (j1 == 0) { + i = 1; + } else { + abyte0[i1] = byte4; + i1++; + j1--; + flag = true; + continue; + } + break label0; + } + if (j != l1) { + continue; + } + if (j1 == 0) { + i = 1; + break label0; + } + abyte0[i1] = byte4; + i1++; + j1--; + flag = true; + } + i = 2; + l = ai[l]; + byte byte1 = (byte) (l & 0xff); + l >>= 8; + if (++j != l1) { + if (byte1 != k) { + k = byte1; + } else { + i = 3; + l = ai[l]; + byte byte2 = (byte) (l & 0xff); + l >>= 8; + if (++j != l1) { + if (byte2 != k) { + k = byte2; + } else { + l = ai[l]; + byte byte3 = (byte) (l & 0xff); + l >>= 8; + j++; + i = (byte3 & 0xff) + 4; + l = ai[l]; + k = (byte) (l & 0xff); + l >>= 8; + j++; + } + } + } + } + } while (true); + entry.anInt2216 += k1 - j1; + entry.aByte2201 = byte4; + entry.anInt2222 = i; + entry.anInt2227 = j; + entry.anInt2221 = k; + anIntArray257 = ai; + entry.anInt2208 = l; + entry.aByteArray2212 = abyte0; + entry.anInt2203 = i1; + entry.anInt2206 = j1; + } + + private static final byte method1788(BZip2BlockEntry entry) { + return (byte) method1790(1, entry); + } + + private static final byte method1789(BZip2BlockEntry entryInstance2) { + return (byte) method1790(8, entryInstance2); + } + + private static final int method1790(int i, BZip2BlockEntry entry) { + int j; + do { + if (entry.anInt2232 >= i) { + int k = entry.anInt2207 >> entry.anInt2232 - i & (1 << i) - 1; + entry.anInt2232 -= i; + j = k; + break; + } + entry.anInt2207 = entry.anInt2207 << 8 | entry.aByteArray2224[entry.anInt2209] & 0xff; + entry.anInt2232 += 8; + entry.anInt2209++; + entry.anInt2217++; + } while (true); + return j; + } + + public static void clearBlockEntryInstance() { + entryInstance = null; + } + + private static final void method1793(BZip2BlockEntry entryInstance2) { + // unused + /* + * boolean flag = false; boolean flag1 = false; boolean flag2 = false; + * boolean flag3 = false; boolean flag4 = false; boolean flag5 = false; + * boolean flag6 = false; boolean flag7 = false; boolean flag8 = false; + * boolean flag9 = false; boolean flag10 = false; boolean flag11 = + * false; boolean flag12 = false; boolean flag13 = false; boolean flag14 + * = false; boolean flag15 = false; boolean flag16 = false; boolean + * flag17 = false; + */ + int j8 = 0; + int ai[] = null; + int ai1[] = null; + int ai2[] = null; + entryInstance2.anInt2202 = 1; + if (anIntArray257 == null) { + anIntArray257 = new int[entryInstance2.anInt2202 * 0x186a0]; + } + boolean flag18 = true; + while (flag18) { + byte byte0 = method1789(entryInstance2); + if (byte0 == 23) { + return; + } + byte0 = method1789(entryInstance2); + byte0 = method1789(entryInstance2); + byte0 = method1789(entryInstance2); + byte0 = method1789(entryInstance2); + byte0 = method1789(entryInstance2); + byte0 = method1789(entryInstance2); + byte0 = method1789(entryInstance2); + byte0 = method1789(entryInstance2); + byte0 = method1789(entryInstance2); + byte0 = method1788(entryInstance2); + entryInstance2.anInt2223 = 0; + byte0 = method1789(entryInstance2); + entryInstance2.anInt2223 = entryInstance2.anInt2223 << 8 | byte0 & 0xff; + byte0 = method1789(entryInstance2); + entryInstance2.anInt2223 = entryInstance2.anInt2223 << 8 | byte0 & 0xff; + byte0 = method1789(entryInstance2); + entryInstance2.anInt2223 = entryInstance2.anInt2223 << 8 | byte0 & 0xff; + for (int j = 0; j < 16; j++) { + byte byte1 = method1788(entryInstance2); + if (byte1 == 1) { + entryInstance2.aBooleanArray2205[j] = true; + } else { + entryInstance2.aBooleanArray2205[j] = false; + } + } + + for (int k = 0; k < 256; k++) { + entryInstance2.aBooleanArray2213[k] = false; + } + + for (int l = 0; l < 16; l++) { + if (entryInstance2.aBooleanArray2205[l]) { + for (int i3 = 0; i3 < 16; i3++) { + byte byte2 = method1788(entryInstance2); + if (byte2 == 1) { + entryInstance2.aBooleanArray2213[l * 16 + i3] = true; + } + } + + } + } + + method1785(entryInstance2); + int i4 = entryInstance2.anInt2215 + 2; + int j4 = method1790(3, entryInstance2); + int k4 = method1790(15, entryInstance2); + for (int i1 = 0; i1 < k4; i1++) { + int j3 = 0; + do { + byte byte3 = method1788(entryInstance2); + if (byte3 == 0) { + break; + } + j3++; + } while (true); + entryInstance2.aByteArray2214[i1] = (byte) j3; + } + + byte abyte0[] = new byte[6]; + for (byte byte16 = 0; byte16 < j4; byte16++) { + abyte0[byte16] = byte16; + } + + for (int j1 = 0; j1 < k4; j1++) { + byte byte17 = entryInstance2.aByteArray2214[j1]; + byte byte15 = abyte0[byte17]; + for (; byte17 > 0; byte17--) { + abyte0[byte17] = abyte0[byte17 - 1]; + } + + abyte0[0] = byte15; + entryInstance2.aByteArray2219[j1] = byte15; + } + + for (int k3 = 0; k3 < j4; k3++) { + int k6 = method1790(5, entryInstance2); + for (int k1 = 0; k1 < i4; k1++) { + do { + byte byte4 = method1788(entryInstance2); + if (byte4 == 0) { + break; + } + byte4 = method1788(entryInstance2); + if (byte4 == 0) { + k6++; + } else { + k6--; + } + } while (true); + entryInstance2.aByteArrayArray2229[k3][k1] = (byte) k6; + } + + } + + for (int l3 = 0; l3 < j4; l3++) { + byte byte8 = 32; + int i = 0; + for (int l1 = 0; l1 < i4; l1++) { + if (entryInstance2.aByteArrayArray2229[l3][l1] > i) { + i = entryInstance2.aByteArrayArray2229[l3][l1]; + } + if (entryInstance2.aByteArrayArray2229[l3][l1] < byte8) { + byte8 = entryInstance2.aByteArrayArray2229[l3][l1]; + } + } + + method1786(entryInstance2.anIntArrayArray2230[l3], entryInstance2.anIntArrayArray2218[l3], entryInstance2.anIntArrayArray2210[l3], entryInstance2.aByteArrayArray2229[l3], byte8, i, i4); + entryInstance2.anIntArray2200[l3] = byte8; + } + + int l4 = entryInstance2.anInt2215 + 1; + int i5 = -1; + int j5 = 0; + for (int i2 = 0; i2 <= 255; i2++) { + entryInstance2.anIntArray2228[i2] = 0; + } + + int i9 = 4095; + for (int k8 = 15; k8 >= 0; k8--) { + for (int l8 = 15; l8 >= 0; l8--) { + entryInstance2.aByteArray2204[i9] = (byte) (k8 * 16 + l8); + i9--; + } + + entryInstance2.anIntArray2226[k8] = i9 + 1; + } + + int l5 = 0; + if (j5 == 0) { + i5++; + j5 = 50; + byte byte12 = entryInstance2.aByteArray2219[i5]; + j8 = entryInstance2.anIntArray2200[byte12]; + ai = entryInstance2.anIntArrayArray2230[byte12]; + ai2 = entryInstance2.anIntArrayArray2210[byte12]; + ai1 = entryInstance2.anIntArrayArray2218[byte12]; + } + j5--; + int l6 = j8; + int k7; + byte byte9; + for (k7 = method1790(l6, entryInstance2); k7 > ai[l6]; k7 = k7 << 1 | byte9) { + l6++; + byte9 = method1788(entryInstance2); + } + + for (int k5 = ai2[k7 - ai1[l6]]; k5 != l4;) { + if (k5 == 0 || k5 == 1) { + int i6 = -1; + int j6 = 1; + do { + if (k5 == 0) { + i6 += j6; + } else if (k5 == 1) { + i6 += 2 * j6; + } + j6 *= 2; + if (j5 == 0) { + i5++; + j5 = 50; + byte byte13 = entryInstance2.aByteArray2219[i5]; + j8 = entryInstance2.anIntArray2200[byte13]; + ai = entryInstance2.anIntArrayArray2230[byte13]; + ai2 = entryInstance2.anIntArrayArray2210[byte13]; + ai1 = entryInstance2.anIntArrayArray2218[byte13]; + } + j5--; + int i7 = j8; + int l7; + byte byte10; + for (l7 = method1790(i7, entryInstance2); l7 > ai[i7]; l7 = l7 << 1 | byte10) { + i7++; + byte10 = method1788(entryInstance2); + } + + k5 = ai2[l7 - ai1[i7]]; + } while (k5 == 0 || k5 == 1); + i6++; + byte byte5 = entryInstance2.aByteArray2211[entryInstance2.aByteArray2204[entryInstance2.anIntArray2226[0]] & 0xff]; + entryInstance2.anIntArray2228[byte5 & 0xff] += i6; + for (; i6 > 0; i6--) { + anIntArray257[l5] = byte5 & 0xff; + l5++; + } + + } else { + int i11 = k5 - 1; + byte byte6; + if (i11 < 16) { + int i10 = entryInstance2.anIntArray2226[0]; + byte6 = entryInstance2.aByteArray2204[i10 + i11]; + for (; i11 > 3; i11 -= 4) { + int j11 = i10 + i11; + entryInstance2.aByteArray2204[j11] = entryInstance2.aByteArray2204[j11 - 1]; + entryInstance2.aByteArray2204[j11 - 1] = entryInstance2.aByteArray2204[j11 - 2]; + entryInstance2.aByteArray2204[j11 - 2] = entryInstance2.aByteArray2204[j11 - 3]; + entryInstance2.aByteArray2204[j11 - 3] = entryInstance2.aByteArray2204[j11 - 4]; + } + + for (; i11 > 0; i11--) { + entryInstance2.aByteArray2204[i10 + i11] = entryInstance2.aByteArray2204[(i10 + i11) - 1]; + } + + entryInstance2.aByteArray2204[i10] = byte6; + } else { + int k10 = i11 / 16; + int l10 = i11 % 16; + int j10 = entryInstance2.anIntArray2226[k10] + l10; + byte6 = entryInstance2.aByteArray2204[j10]; + for (; j10 > entryInstance2.anIntArray2226[k10]; j10--) { + entryInstance2.aByteArray2204[j10] = entryInstance2.aByteArray2204[j10 - 1]; + } + + entryInstance2.anIntArray2226[k10]++; + for (; k10 > 0; k10--) { + entryInstance2.anIntArray2226[k10]--; + entryInstance2.aByteArray2204[entryInstance2.anIntArray2226[k10]] = entryInstance2.aByteArray2204[(entryInstance2.anIntArray2226[k10 - 1] + 16) - 1]; + } + + entryInstance2.anIntArray2226[0]--; + entryInstance2.aByteArray2204[entryInstance2.anIntArray2226[0]] = byte6; + if (entryInstance2.anIntArray2226[0] == 0) { + int l9 = 4095; + for (int j9 = 15; j9 >= 0; j9--) { + for (int k9 = 15; k9 >= 0; k9--) { + entryInstance2.aByteArray2204[l9] = entryInstance2.aByteArray2204[entryInstance2.anIntArray2226[j9] + k9]; + l9--; + } + + entryInstance2.anIntArray2226[j9] = l9 + 1; + } + + } + } + entryInstance2.anIntArray2228[entryInstance2.aByteArray2211[byte6 & 0xff] & 0xff]++; + anIntArray257[l5] = entryInstance2.aByteArray2211[byte6 & 0xff] & 0xff; + l5++; + if (j5 == 0) { + i5++; + j5 = 50; + byte byte14 = entryInstance2.aByteArray2219[i5]; + j8 = entryInstance2.anIntArray2200[byte14]; + ai = entryInstance2.anIntArrayArray2230[byte14]; + ai2 = entryInstance2.anIntArrayArray2210[byte14]; + ai1 = entryInstance2.anIntArrayArray2218[byte14]; + } + j5--; + int j7 = j8; + int i8; + byte byte11; + for (i8 = method1790(j7, entryInstance2); i8 > ai[j7]; i8 = i8 << 1 | byte11) { + j7++; + byte11 = method1788(entryInstance2); + } + + k5 = ai2[i8 - ai1[j7]]; + } + } + + entryInstance2.anInt2222 = 0; + entryInstance2.aByte2201 = 0; + entryInstance2.anIntArray2220[0] = 0; + for (int j2 = 1; j2 <= 256; j2++) { + entryInstance2.anIntArray2220[j2] = entryInstance2.anIntArray2228[j2 - 1]; + } + + for (int k2 = 1; k2 <= 256; k2++) { + entryInstance2.anIntArray2220[k2] += entryInstance2.anIntArray2220[k2 - 1]; + } + + for (int l2 = 0; l2 < l5; l2++) { + byte byte7 = (byte) (anIntArray257[l2] & 0xff); + anIntArray257[entryInstance2.anIntArray2220[byte7 & 0xff]] |= l2 << 8; + entryInstance2.anIntArray2220[byte7 & 0xff]++; + } + + entryInstance2.anInt2208 = anIntArray257[entryInstance2.anInt2223] >> 8; + entryInstance2.anInt2227 = 0; + entryInstance2.anInt2208 = anIntArray257[entryInstance2.anInt2208]; + entryInstance2.anInt2221 = (byte) (entryInstance2.anInt2208 & 0xff); + entryInstance2.anInt2208 >>= 8; + entryInstance2.anInt2227++; + entryInstance2.anInt2225 = l5; + method1787(entryInstance2); + if (entryInstance2.anInt2227 == entryInstance2.anInt2225 + 1 && entryInstance2.anInt2222 == 0) { + flag18 = true; + } else { + flag18 = false; + } + } + } + +} diff --git a/Server/src/main/core/cache/crypto/ISAACCipher.java b/Server/src/main/core/cache/crypto/ISAACCipher.java new file mode 100644 index 0000000..16cd85b --- /dev/null +++ b/Server/src/main/core/cache/crypto/ISAACCipher.java @@ -0,0 +1,271 @@ +package core.cache.crypto; + +/** + *

An implementation of an ISAAC cipher. See + * http://en.wikipedia.org/wiki/ISAAC_(cipher) for more information.

+ *

This implementation is based on the one written by Bob Jenkins, which is + * available at + * http://www.burtleburtle.net/bob/java/rand/Rand.java.

+ * @author Graham Edgecombe + */ +public class ISAACCipher { + + /** + * The golden ratio. + */ + public static final int RATIO = 0x9e3779b9; + + /** + * The log of the size of the results and memory arrays. + */ + public static final int SIZE_LOG = 8; + + /** + * The size of the results and memory arrays. + */ + public static final int SIZE = 1 << SIZE_LOG; + + /** + * For pseudorandom lookup. + */ + public static final int MASK = (SIZE - 1) << 2; + + /** + * The count through the results. + */ + private int count = 0; + + /** + * The results. + */ + private int results[] = new int[SIZE]; + + /** + * The internal memory state. + */ + private int memory[] = new int[SIZE]; + + /** + * The accumulator. + */ + private int a; + + /** + * The last result. + */ + private int b; + + /** + * The counter. + */ + private int c; + + /** + * Creates the ISAAC cipher. + * @param seed The seed. + */ + public ISAACCipher(int[] seed) { + for (int i = 0; i < seed.length; i++) { + results[i] = seed[i]; + } + init(true); + } + + /** + * Gets the next value. + * @return The next value. + */ + public int getNextValue() { + if (count-- == 0) { + isaac(); + count = SIZE - 1; + } + return 0;//results[count]; + } + + /** + * Generates 256 results. + */ + public void isaac() { + int i, j, x, y; + b += ++c; + for (i = 0, j = SIZE / 2; i < SIZE / 2;) { + x = memory[i]; + a ^= a << 13; + a += memory[j++]; + memory[i] = y = memory[(x & MASK) >> 2] + a + b; + results[i++] = b = memory[((y >> SIZE_LOG) & MASK) >> 2] + x; + + x = memory[i]; + a ^= a >>> 6; + a += memory[j++]; + memory[i] = y = memory[(x & MASK) >> 2] + a + b; + results[i++] = b = memory[((y >> SIZE_LOG) & MASK) >> 2] + x; + + x = memory[i]; + a ^= a << 2; + a += memory[j++]; + memory[i] = y = memory[(x & MASK) >> 2] + a + b; + results[i++] = b = memory[((y >> SIZE_LOG) & MASK) >> 2] + x; + + x = memory[i]; + a ^= a >>> 16; + a += memory[j++]; + memory[i] = y = memory[(x & MASK) >> 2] + a + b; + results[i++] = b = memory[((y >> SIZE_LOG) & MASK) >> 2] + x; + } + for (j = 0; j < SIZE / 2;) { + x = memory[i]; + a ^= a << 13; + a += memory[j++]; + memory[i] = y = memory[(x & MASK) >> 2] + a + b; + results[i++] = b = memory[((y >> SIZE_LOG) & MASK) >> 2] + x; + + x = memory[i]; + a ^= a >>> 6; + a += memory[j++]; + memory[i] = y = memory[(x & MASK) >> 2] + a + b; + results[i++] = b = memory[((y >> SIZE_LOG) & MASK) >> 2] + x; + + x = memory[i]; + a ^= a << 2; + a += memory[j++]; + memory[i] = y = memory[(x & MASK) >> 2] + a + b; + results[i++] = b = memory[((y >> SIZE_LOG) & MASK) >> 2] + x; + + x = memory[i]; + a ^= a >>> 16; + a += memory[j++]; + memory[i] = y = memory[(x & MASK) >> 2] + a + b; + results[i++] = b = memory[((y >> SIZE_LOG) & MASK) >> 2] + x; + } + } + + /** + * Initialises the ISAAC. + * @param flag Flag indicating if we should perform a second pass. + */ + public void init(boolean flag) { + int i; + int a, b, c, d, e, f, g, h; + a = b = c = d = e = f = g = h = RATIO; + for (i = 0; i < 4; ++i) { + a ^= b << 11; + d += a; + b += c; + b ^= c >>> 2; + e += b; + c += d; + c ^= d << 8; + f += c; + d += e; + d ^= e >>> 16; + g += d; + e += f; + e ^= f << 10; + h += e; + f += g; + f ^= g >>> 4; + a += f; + g += h; + g ^= h << 8; + b += g; + h += a; + h ^= a >>> 9; + c += h; + a += b; + } + for (i = 0; i < SIZE; i += 8) { + if (flag) { + a += results[i]; + b += results[i + 1]; + c += results[i + 2]; + d += results[i + 3]; + e += results[i + 4]; + f += results[i + 5]; + g += results[i + 6]; + h += results[i + 7]; + } + a ^= b << 11; + d += a; + b += c; + b ^= c >>> 2; + e += b; + c += d; + c ^= d << 8; + f += c; + d += e; + d ^= e >>> 16; + g += d; + e += f; + e ^= f << 10; + h += e; + f += g; + f ^= g >>> 4; + a += f; + g += h; + g ^= h << 8; + b += g; + h += a; + h ^= a >>> 9; + c += h; + a += b; + memory[i] = a; + memory[i + 1] = b; + memory[i + 2] = c; + memory[i + 3] = d; + memory[i + 4] = e; + memory[i + 5] = f; + memory[i + 6] = g; + memory[i + 7] = h; + } + if (flag) { + for (i = 0; i < SIZE; i += 8) { + a += memory[i]; + b += memory[i + 1]; + c += memory[i + 2]; + d += memory[i + 3]; + e += memory[i + 4]; + f += memory[i + 5]; + g += memory[i + 6]; + h += memory[i + 7]; + a ^= b << 11; + d += a; + b += c; + b ^= c >>> 2; + e += b; + c += d; + c ^= d << 8; + f += c; + d += e; + d ^= e >>> 16; + g += d; + e += f; + e ^= f << 10; + h += e; + f += g; + f ^= g >>> 4; + a += f; + g += h; + g ^= h << 8; + b += g; + h += a; + h ^= a >>> 9; + c += h; + a += b; + memory[i] = a; + memory[i + 1] = b; + memory[i + 2] = c; + memory[i + 3] = d; + memory[i + 4] = e; + memory[i + 5] = f; + memory[i + 6] = g; + memory[i + 7] = h; + } + } + isaac(); + count = SIZE; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/cache/crypto/ISAACPair.java b/Server/src/main/core/cache/crypto/ISAACPair.java new file mode 100644 index 0000000..83c4654 --- /dev/null +++ b/Server/src/main/core/cache/crypto/ISAACPair.java @@ -0,0 +1,45 @@ +package core.cache.crypto; + +/** + * Represents a ISAAC key pair, for both input and output. + * @author `Discardedx2 + */ +public final class ISAACPair { + + /** + * The input cipher. + */ + private ISAACCipher input; + + /** + * The output cipher. + */ + private ISAACCipher output; + + /** + * Constructs a new {@code ISAACPair} {@code Object}. + * @param input The input cipher. + * @param output The output cipher. + */ + public ISAACPair(ISAACCipher input, ISAACCipher output) { + this.input = input; + this.output = output; + } + + /** + * Gets the input cipher. + * @return The input cipher. + */ + public ISAACCipher getInput() { + return input; + } + + /** + * Gets the output cipher. + * @return The output cipher. + */ + public ISAACCipher getOutput() { + return output; + } + +} diff --git a/Server/src/main/core/cache/crypto/XTEACryption.java b/Server/src/main/core/cache/crypto/XTEACryption.java new file mode 100644 index 0000000..7ed799e --- /dev/null +++ b/Server/src/main/core/cache/crypto/XTEACryption.java @@ -0,0 +1,124 @@ +package core.cache.crypto; + +import java.nio.ByteBuffer; + +/** + * Holds XTEA cryption methods. + * @author ? + * @author Emperor + */ +public final class XTEACryption { + + /** + * The delta value + */ + private static final int DELTA = -1640531527; + + /** + * The sum. + */ + private static final int SUM = -957401312; + + /** + * The amount of "cryption cycles". + */ + private static final int NUM_ROUNDS = 32; + + /** + * Constructs a new {@code XTEACryption}. + */ + private XTEACryption() { + /* + * empty. + */ + } + + /** + * Decrypts the contents of the buffer. + * @param keys The cryption keys. + * @param buffer The buffer. + */ + public static ByteBuffer decrypt(int[] keys, ByteBuffer buffer) { + return decrypt(keys, buffer, buffer.position(), buffer.limit()); + } + + /** + * Decrypts the buffer data. + * @param keys The keys. + * @param buffer The buffer to decrypt. + * @param offset The offset of the data to decrypt. + * @param length The length. + * @return The decrypted data. + */ + public static ByteBuffer decrypt(int[] keys, ByteBuffer buffer, int offset, int length) { + int numBlocks = (length - offset) / 8; + int[] block = new int[2]; + for (int i = 0; i < numBlocks; i++) { + int index = i * 8 + offset; + block[0] = buffer.getInt(index); + block[1] = buffer.getInt(index + 4); + decipher(keys, block); + buffer.putInt(index, block[0]); + buffer.putInt(index + 4, block[1]); + } + return buffer; + } + + /** + * Deciphers the values. + * @param keys The cryption key. + * @param block The values to decipher. + */ + private static void decipher(int[] keys, int[] block) { + long sum = SUM; + for (int i = 0; i < NUM_ROUNDS; i++) { + block[1] -= (keys[(int) ((sum & 0x1933) >>> 11)] + sum ^ block[0] + (block[0] << 4 ^ block[0] >>> 5)); + sum -= DELTA; + block[0] -= ((block[1] << 4 ^ block[1] >>> 5) + block[1] ^ keys[(int) (sum & 0x3)] + sum); + } + } + + /** + * Encrypts the contents of the byte buffer. + * @param keys The cryption keys. + * @param buffer The buffer to encrypt. + */ + public static void encrypt(int[] keys, ByteBuffer buffer) { + encrypt(keys, buffer, buffer.position(), buffer.limit()); + } + + /** + * Encrypts the buffer data. + * @param keys The keys. + * @param buffer The buffer to encrypt. + * @param offset The offset of the data to encrypt. + * @param length The length. + * @return The encrypted data. + */ + public static void encrypt(int[] keys, ByteBuffer buffer, int offset, int length) { + int numBlocks = (length - offset) / 8; + int[] block = new int[2]; + for (int i = 0; i < numBlocks; i++) { + int index = i * 8 + offset; + block[0] = buffer.getInt(index); + block[1] = buffer.getInt(index + 4); + encipher(keys, block); + buffer.putInt(index, block[0]); + buffer.putInt(index + 4, block[1]); + } + } + + /** + * Enciphers the values of the block. + * @param keys The cryption keys. + * @param block The block to encipher. + */ + private static void encipher(int[] keys, int[] block) { + long sum = 0; + for (int i = 0; i < NUM_ROUNDS; i++) { + block[0] += ((block[1] << 4 ^ block[1] >>> 5) + block[1] ^ keys[(int) (sum & 0x3)] + sum); + sum += DELTA; + block[1] += (keys[(int) ((sum & 0x1933) >>> 11)] + sum ^ block[0] + (block[0] << 4 ^ block[0] >>> 5)); + } + } +} \ No newline at end of file diff --git a/Server/src/main/core/cache/def/Definition.java b/Server/src/main/core/cache/def/Definition.java new file mode 100644 index 0000000..c6a4d5f --- /dev/null +++ b/Server/src/main/core/cache/def/Definition.java @@ -0,0 +1,190 @@ +package core.cache.def; + +import java.util.HashMap; +import java.util.Map; + +import core.tools.StringUtils; +import core.game.node.Node; + +/** + * Represent's a node's definitions. + * @author Emperor + * @param The node type. + */ +public class Definition { + + /** + * The node id. + */ + protected int id; + + /** + * The name. + */ + protected String name = "null"; + + /** + * The examine info. + */ + protected String examine; + + /** + * The options. + */ + protected String[] options; + + /** + * The configurations. + */ + protected final Map handlers = new HashMap(); + + /** + * Constructs a new {@code Definition} {@code Object}. + */ + public Definition() { + /* + * empty. + */ + } + + /** + * Checks if this node has options. + * @return {@code True} if so. + */ + public boolean hasOptions() { + return hasOptions(true); + } + + /** + * Checks if this node has options. + * @param examine If examine should be treated as an option. + * @return {@code True} if so. + */ + public boolean hasOptions(boolean examine) { + if (name.equals("null") || options == null) { + return false; + } + for (String option : options) { + if (option != null && !option.equals("null")) { + if (examine || !option.equals("Examine")) { + return true; + } + } + } + return false; + } + + /** + * Gets a configuration of this item's definitions. + * @param key The key. + * @return The configuration value. + */ + @SuppressWarnings("unchecked") + public V getConfiguration(String key) { + return (V) handlers.get(key); + } + + /** + * Gets a configuration from this item's definitions. + * @param key The key. + * @param fail The object to return if there was no value found for this + * key. + * @return The value, or the fail object. + */ + @SuppressWarnings("unchecked") + public V getConfiguration(String key, V fail) { + V object = (V) handlers.get(key); + if (object == null) { + return fail; + } + return object; + } + + /** + * Gets the id. + * @return The id. + */ + public int getId() { + return id; + } + + /** + * Sets the id. + * @param id The id to set. + */ + public void setId(int id) { + this.id = id; + } + + /** + * Gets the name. + * @return The name. + */ + public String getName() { + return name; + } + + /** + * Sets the name. + * @param name The name to set. + */ + public void setName(String name) { + this.name = name; + } + + /** + * Gets the examine. + * @return The examine. + */ + public String getExamine() { + if (examine == null) { + try { + if(handlers.get("examine") != null) + examine = handlers.get("examine").toString(); + } catch (Exception e){ + e.printStackTrace(); + } + if(examine == null) { + if (name.length() > 0) { + examine = "It's a" + (StringUtils.isPlusN(name) ? "n " : " ") + name + "."; + } else { + examine = "null"; + } + } + } + return examine; + } + + /** + * Sets the examine. + * @param examine The examine to set. + */ + public void setExamine(String examine) { + this.examine = examine; + } + + /** + * Gets the options. + * @return The options. + */ + public String[] getOptions() { + return options; + } + + /** + * Sets the options. + * @param options The options to set. + */ + public void setOptions(String[] options) { + this.options = options; + } + + /** + * Gets the configurations. + * @return The configurations. + */ + public Map getHandlers() { + return handlers; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/cache/def/impl/AnimationDefinition.java b/Server/src/main/core/cache/def/impl/AnimationDefinition.java new file mode 100644 index 0000000..1f56d91 --- /dev/null +++ b/Server/src/main/core/cache/def/impl/AnimationDefinition.java @@ -0,0 +1,209 @@ +package core.cache.def.impl; + +import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.Map; + +import core.cache.Cache; +import core.cache.misc.buffer.ByteBufferUtils; + +/** + * Represents an animation's definitions. + * @author Emperor + */ +public final class AnimationDefinition { + + public int anInt2136; + public int anInt2137; + public int[] anIntArray2139; + public int anInt2140; + public boolean aBoolean2141 = false; + public int anInt2142; + public int emoteItem; + public int anInt2144 = -1; + public int[][] handledSounds; + public boolean[] aBooleanArray2149; + public int[] anIntArray2151; + public boolean aBoolean2152; + public int[] durations; + public int anInt2155; + public boolean aBoolean2158; + public boolean aBoolean2159; + public int anInt2162; + public int anInt2163; + boolean newHeader; + + // added + public int[] soundMinDelay; + public int[] soundMaxDelay; + public int[] anIntArray1362; + public boolean effect2Sound; + + private static final Map animDefs = new HashMap<>(); + + public static final AnimationDefinition forId(int emoteId) { + try { + AnimationDefinition defs = animDefs.get(emoteId); + if (defs != null) { + return defs; + } + byte[] data = Cache.getIndexes()[20].getFileData(emoteId >>> 7, emoteId & 0x7f); + defs = new AnimationDefinition(); + if (data != null) { + defs.readValueLoop(ByteBuffer.wrap(data)); + } + defs.method2394(); + animDefs.put(emoteId, defs); + return defs; + } catch (Throwable t) { + return null; + } + } + + private void readValueLoop(ByteBuffer buffer) { + for (;;) { + int opcode = buffer.get() & 0xFF; + if (opcode == 0) { + break; + } + readValues(buffer, opcode); + } + } + + /** + * Gets the duration of this animation in milliseconds. + * @return The duration. + */ + public int getDuration() { + if (durations == null) { + return 0; + } + int duration = 0; + for (int i : durations) { + if (i > 100) { + continue; + } + duration += i * 20; + } + return duration; + } + + public int getCycles() { + if (durations == null) return 0; + int duration = 0; + for (int i : durations) + duration += i; + return duration; + } + + /** + * Gets the duration of this animation in (600ms) ticks. + * @return The duration in ticks. + */ + public int getDurationTicks() { + int ticks = getDuration() / 600; + return Math.max(ticks, 1); + } + + private void readValues(ByteBuffer buffer, int opcode) { + if (opcode == 1) { + int length = buffer.getShort() & 0xFFFF; + durations = new int[length]; + for (int i = 0; i < length; i++) { + durations[i] = buffer.getShort() & 0xFFFF; + } + anIntArray2139 = new int[length]; + for (int i = 0; i < length; i++) { + anIntArray2139[i] = buffer.getShort() & 0xFFFF; + } + for (int i = 0; i < length; i++) { + anIntArray2139[i] = ((buffer.getShort() & 0xFFFF << 16) + anIntArray2139[i]); + } + } else if (opcode != 2) { + if (opcode != 3) { + if (opcode == 4) + aBoolean2152 = true; + else if (opcode == 5) + anInt2142 = buffer.get() & 0xFF; + else if (opcode != 6) { + if (opcode == 7) + emoteItem = buffer.getShort() & 0xFFFF; + else if ((opcode ^ 0xffffffff) != -9) { + if (opcode != 9) { + if (opcode != 10) { + if (opcode == 11) + anInt2155 = buffer.get() & 0xFF; + else if (opcode == 12) { + int i = buffer.get() & 0xFF; + anIntArray2151 = new int[i]; + for (int i_19_ = 0; ((i_19_ ^ 0xffffffff) > (i ^ 0xffffffff)); i_19_++) { + anIntArray2151[i_19_] = buffer.getShort() & 0xFFFF; + } + for (int i_20_ = 0; i > i_20_; i_20_++) + anIntArray2151[i_20_] = ((buffer.getShort() & 0xFFFF << 16) + anIntArray2151[i_20_]); + } else if (opcode == 13) { + // opcode 13 + int i = buffer.getShort() & 0xFFFF; + handledSounds = new int[i][]; + for (int i_21_ = 0; i_21_ < i; i_21_++) { + int i_22_ = buffer.get() & 0xFF; + if ((i_22_ ^ 0xffffffff) < -1) { + handledSounds[i_21_] = new int[i_22_]; + handledSounds[i_21_][0] = ByteBufferUtils.getMedium(buffer); + for (int i_23_ = 1; ((i_22_ ^ 0xffffffff) < (i_23_ ^ 0xffffffff)); i_23_++) { + handledSounds[i_21_][i_23_] = buffer.getShort() & 0xFFFF; + } + } + } + } else if (opcode == 14) { + aBoolean2141 = true; + } else { + + } + } else + anInt2162 = buffer.get() & 0xFF; + } else + anInt2140 = buffer.get() & 0xFF; + } else + anInt2136 = buffer.get() & 0xFF; + } else + anInt2144 = buffer.getShort() & 0xFFFF; + } else { + aBooleanArray2149 = new boolean[256]; + int length = buffer.get() & 0xFF; + for (int i = 0; i < length; i++) { + aBooleanArray2149[buffer.get() & 0xFF] = true; + } + } + } else + anInt2163 = buffer.getShort() & 0xFFFF; + } + + public void method2394() { + if (anInt2140 == -1) { + if (aBooleanArray2149 == null) + anInt2140 = 0; + else + anInt2140 = 2; + } + if (anInt2162 == -1) { + if (aBooleanArray2149 == null) + anInt2162 = 0; + else + anInt2162 = 2; + } + } + + public AnimationDefinition() { + anInt2136 = 99; + emoteItem = -1; + anInt2140 = -1; + aBoolean2152 = false; + anInt2142 = 5; + aBoolean2159 = false; + anInt2163 = -1; + anInt2155 = 2; + aBoolean2158 = false; + anInt2162 = -1; + } +} \ No newline at end of file diff --git a/Server/src/main/core/cache/def/impl/CS2Mapping.java b/Server/src/main/core/cache/def/impl/CS2Mapping.java new file mode 100644 index 0000000..440c06c --- /dev/null +++ b/Server/src/main/core/cache/def/impl/CS2Mapping.java @@ -0,0 +1,256 @@ +package core.cache.def.impl; + +import java.io.BufferedWriter; +import java.nio.ByteBuffer; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.Map; + +import core.cache.Cache; +import core.cache.misc.buffer.ByteBufferUtils; +import core.game.world.GameWorld; + +/** + * The CS2 mapping. + * @author Emperor + */ +public final class CS2Mapping { + + /** + * The CS2 mappings. + */ + private static final Map maps = new HashMap<>(); + + /** + * The script id. + */ + private final int scriptId; + + /** + * Unknown value. + */ + private int unknown; + + /** + * Second unknown value. + */ + private int unknown1; + + /** + * The default string value. + */ + private String defaultString; + + /** + * The default integer value. + */ + private int defaultInt; + + /** + * The mapping. + */ + private HashMap map; + + /** + * The array of the objects. + */ + private Object[] array; + + /** + * Constructs a new {@code CS2Mapping} {@code Object}. + * @param scriptId The script id. + */ + public CS2Mapping(int scriptId) { + this.scriptId = scriptId; + } + + /** + * The main method. + * @param args The arguments cast on runtime. + * @throws Throwable When an exception occurs. + */ + public static void main(String... args) throws Throwable { + GameWorld.prompt(false); + BufferedWriter bw = Files.newBufferedWriter(Paths.get("./cs2.txt")); + for (int i = 0; i < 10000; i++) { + CS2Mapping mapping = forId(i); + if (mapping == null) { + continue; + } + if (mapping.map == null) { + continue; + } + bw.append("ScriptAPI - " + i + " ["); + for (int index : mapping.map.keySet()) { + bw.append(mapping.map.get(index) + ": " + index + " "); + } + bw.append("]"); + bw.newLine(); + } + bw.flush(); + bw.close(); + } + + /** + * Gets the mapping for the given script id. + * @param scriptId The script id. + * @return The mapping. + */ + public static CS2Mapping forId(int scriptId) { + CS2Mapping mapping = maps.get(scriptId); + if (mapping != null) { + return mapping; + } + mapping = new CS2Mapping(scriptId); + byte[] bs = Cache.getIndexes()[17].getFileData(scriptId >>> 8, scriptId & 0xFF); + if (bs != null) { + mapping.load(ByteBuffer.wrap(bs)); + } else { + return null; + } + maps.put(scriptId, mapping); + return mapping; + } + + /** + * Loads the mapping data. + * @param buffer The buffer to read the data from. + */ + private void load(ByteBuffer buffer) { + int opcode; + while ((opcode = buffer.get() & 0xFF) != 0) { + switch (opcode) { + case 1: + unknown = buffer.get() & 0xFF; + break; + case 2: + unknown1 = buffer.get() & 0xFF; + break; + case 3: + defaultString = ByteBufferUtils.getString(buffer); + break; + case 4: + defaultInt = buffer.getInt(); + break; + case 5: + case 6: + int size = buffer.getShort() & 0xFFFF; + String string = null; + int val = 0; + map = new HashMap<>(size); + array = new Object[size]; + + for (int i = 0; i < size; i++) { + int key = buffer.getInt(); + if (opcode == 5) { + string = ByteBufferUtils.getString(buffer); + array[i] = string; + map.put(key, string); + } else { + val = buffer.getInt(); + array[i] = val; + map.put(key, val); + } + } + break; + } + } + } + + /** + * Gets the array of objects. + * @return the objects. + */ + public Object[] getArray() { + return array; + } + + /** + * Gets the scriptId. + * @return The scriptId. + */ + public int getScriptId() { + return scriptId; + } + + /** + * Gets the unknown. + * @return The unknown. + */ + public int getUnknown() { + return unknown; + } + + /** + * Sets the unknown. + * @param unknown The unknown to set. + */ + public void setUnknown(int unknown) { + this.unknown = unknown; + } + + /** + * Gets the unknown1. + * @return The unknown1. + */ + public int getUnknown1() { + return unknown1; + } + + /** + * Sets the unknown1. + * @param unknown1 The unknown1 to set. + */ + public void setUnknown1(int unknown1) { + this.unknown1 = unknown1; + } + + /** + * Gets the defaultString. + * @return The defaultString. + */ + public String getDefaultString() { + return defaultString; + } + + /** + * Sets the defaultString. + * @param defaultString The defaultString to set. + */ + public void setDefaultString(String defaultString) { + this.defaultString = defaultString; + } + + /** + * Gets the defaultInt. + * @return The defaultInt. + */ + public int getDefaultInt() { + return defaultInt; + } + + /** + * Sets the defaultInt. + * @param defaultInt The defaultInt to set. + */ + public void setDefaultInt(int defaultInt) { + this.defaultInt = defaultInt; + } + + /** + * Gets the map. + * @return The map. + */ + public HashMap getMap() { + return map; + } + + /** + * Sets the map. + * @param map The map to set. + */ + public void setMap(HashMap map) { + this.map = map; + } +} \ No newline at end of file diff --git a/Server/src/main/core/cache/def/impl/ClothDefinition.java b/Server/src/main/core/cache/def/impl/ClothDefinition.java new file mode 100644 index 0000000..c100c16 --- /dev/null +++ b/Server/src/main/core/cache/def/impl/ClothDefinition.java @@ -0,0 +1,205 @@ +package core.cache.def.impl; + +import java.nio.ByteBuffer; + +import core.ServerConstants; +import core.cache.Cache; + +/** + * The definitions for player clothing/look. + * @author Emperor + */ +public final class ClothDefinition { + + /** + * The equipment slot. + */ + private int equipmentSlot; + + /** + * The model ids. + */ + private int[] modelIds; + + /** + * Unknown boolean. + */ + private boolean unknownBool; + + /** + * Original colors. + */ + private int[] originalColors; + + /** + * The colors to change to. + */ + private int[] modifiedColors; + + /** + * Original texture colors. + */ + private int[] originalTextureColors; + + /** + * Texture colors to change to. + */ + private int[] modifiedTextureColors; + + /** + * Other model ids(?) + */ + private int[] models = { -1, -1, -1, -1, -1 }; + + /** + * Gets the definitions for the given cloth id. + * @param clothId The clothing id. + * @return The definition. + */ + public static ClothDefinition forId(int clothId) { + ClothDefinition def = new ClothDefinition(); + byte[] bs = Cache.getIndexes()[2].getFileData(3, clothId); + if (bs != null) { + def.load(ByteBuffer.wrap(bs)); + } + return def; + } + + /** + * The main method. + * @param args The arguments cast on runtime. + */ + public static void main(String... args) { + try { + Cache.init(ServerConstants.CACHE_PATH); + } catch (Throwable e) { + e.printStackTrace(); + } + int length = Cache.getIndexes()[2].getFilesSize(3); + + for (int i = 0; i < length; i++) { + ClothDefinition def = forId(i); + } + } + + /** + * Loads the definitions. + * @param buffer The buffer. + */ + public void load(ByteBuffer buffer) { + int opcode; + while ((opcode = buffer.get() & 0xFF) != 0) { + parse(opcode, buffer); + } + } + + /** + * Parses an opcode. + * @param opcode The opcode. + * @param buffer The buffer to read the data from. + */ + private void parse(int opcode, ByteBuffer buffer) { + switch (opcode) { + case 1: + equipmentSlot = buffer.get() & 0xFF; + break; + case 2: + int length = buffer.get() & 0xFF; + modelIds = new int[length]; + for (int i = 0; i < length; i++) { + modelIds[i] = buffer.getShort() & 0xFFFF; + } + break; + case 3: + unknownBool = true; + break; + case 40: + length = buffer.get() & 0xFF; + originalColors = new int[length]; + modifiedColors = new int[length]; + for (int i = 0; i < length; i++) { + originalColors[i] = buffer.getShort(); + modifiedColors[i] = buffer.getShort(); + } + break; + case 41: + length = buffer.get() & 0xFF; + originalTextureColors = new int[length]; + modifiedTextureColors = new int[length]; + for (int i = 0; i < length; i++) { + originalTextureColors[i] = buffer.getShort(); + modifiedTextureColors[i] = buffer.getShort(); + } + break; + default: + if (opcode >= 60 && opcode < 70) { + models[opcode - 60] = buffer.getShort() & 0xFFFF; + } + break; + } + } + + /** + * Gets the unknown. + * @return The unknown. + */ + public int getUnknown() { + return equipmentSlot; + } + + /** + * Gets the modelIds. + * @return The modelIds. + */ + public int[] getModelIds() { + return modelIds; + } + + /** + * Gets the unknownBool. + * @return The unknownBool. + */ + public boolean isUnknownBool() { + return unknownBool; + } + + /** + * Gets the originalColors. + * @return The originalColors. + */ + public int[] getOriginalColors() { + return originalColors; + } + + /** + * Gets the modifiedColors. + * @return The modifiedColors. + */ + public int[] getModifiedColors() { + return modifiedColors; + } + + /** + * Gets the originalTextureColors. + * @return The originalTextureColors. + */ + public int[] getOriginalTextureColors() { + return originalTextureColors; + } + + /** + * Gets the modifiedTextureColors. + * @return The modifiedTextureColors. + */ + public int[] getModifiedTextureColors() { + return modifiedTextureColors; + } + + /** + * Gets the models. + * @return The models. + */ + public int[] getModels() { + return models; + } +} \ No newline at end of file diff --git a/Server/src/main/core/cache/def/impl/ComponentType.java b/Server/src/main/core/cache/def/impl/ComponentType.java new file mode 100644 index 0000000..d92e842 --- /dev/null +++ b/Server/src/main/core/cache/def/impl/ComponentType.java @@ -0,0 +1,14 @@ +package core.cache.def.impl; + +public enum ComponentType { + SCROLLABLE, + UNKNOWN_1, + UNKNOWN_2, + UNKNOWN_3, + TEXT, + SPRITE, + MODEL, + UNKNOWN_7, + UNKNOWN_8, + UNKNOWN_9 +} diff --git a/Server/src/main/core/cache/def/impl/DataMap.java b/Server/src/main/core/cache/def/impl/DataMap.java new file mode 100644 index 0000000..bdf4c82 --- /dev/null +++ b/Server/src/main/core/cache/def/impl/DataMap.java @@ -0,0 +1,117 @@ +package core.cache.def.impl; + +import core.cache.Cache; +import core.cache.misc.buffer.ByteBufferUtils; +import core.tools.CP1252; +import core.tools.Log; +import core.tools.SystemLogger; + +import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.Map; + +import static core.api.ContentAPIKt.log; + +public class DataMap { + + /** + * The config definitions mapping. + */ + private static final Map definitions = new HashMap<>(); + + /** + * The enum id. + */ + private final int id; + + public char keyType = '?'; + + public char valueType = '?'; + + public String defaultString; + + public int defaultInt; + + public HashMap dataStore = new HashMap<>(); + + public DataMap(int id) { + this.id = id; + } + + public int getInt(int key){ + if(!dataStore.containsKey(key)){ + log(this.getClass(), Log.ERR, "Invalid value passed for key: " + key + " map: " + id); + return -1; + } + return (int) dataStore.get(key); + } + + public String getString(int key){ + return (String) dataStore.get(key); + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + return "DataMapDefinition{" + + "id=" + id + + ", keyType=" + keyType + + ", valueType=" + (valueType == 'K' ? "Normal" : valueType == 'J' ? "Struct Pointer" : "Unknown") + + ", defaultString='" + defaultString + '\'' + + ", defaultInt=" + defaultInt + + ", dataStore=" + dataStore + + '}' + "\n"; + } + + public static DataMap get(int id){ + core.cache.def.impl.DataMap def = definitions.get(id); + if (def != null) { + return def; + } + byte[] data = Cache.getIndexes()[17].getFileData(id >>> 8, id & 0xFF); + def = parse(id, data); + definitions.put(id, def); + return def; + } + + public static DataMap parse(int id, byte[] data) + { + DataMap def = new DataMap(id); + if (data != null) { + ByteBuffer buffer = ByteBuffer.wrap(data); + int opcode; + + while ((opcode = buffer.get() & 0xFF) != 0) { + + if (opcode == 1) { + def.keyType = CP1252.getFromByte(buffer.get()); + } else if (opcode == 2) { + def.valueType = CP1252.getFromByte(buffer.get()); + } else if (opcode == 3) { + def.defaultString = ByteBufferUtils.getString(buffer); + } else if (opcode == 4) { + def.defaultInt = buffer.getInt(); + } else if (opcode == 5 || opcode == 6) { + int size = buffer.getShort() & 0xFFFF; + + for (int i = 0; i < size; i++) { + int key = buffer.getInt(); + + Object value; + if (opcode == 5) { + value = ByteBufferUtils.getString(buffer); + } else { + value = buffer.getInt(); + } + def.dataStore.put(key, value); + } + } + } + } + return def; + } + + public int getId() { + return id; + } +} diff --git a/Server/src/main/core/cache/def/impl/GraphicDefinition.java b/Server/src/main/core/cache/def/impl/GraphicDefinition.java new file mode 100644 index 0000000..866aa80 --- /dev/null +++ b/Server/src/main/core/cache/def/impl/GraphicDefinition.java @@ -0,0 +1,189 @@ +package core.cache.def.impl; + +import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.Map; + +import core.ServerConstants; +import core.cache.Cache; + +/** + * Represents a Graphic's definition. + * @author Jagex + */ +public class GraphicDefinition { + + public short[] aShortArray1435; + public short[] aShortArray1438; + public int anInt1440; + public boolean aBoolean1442; + public int defaultModel; + public int anInt1446; + public boolean aBoolean1448 = false; + public int anInt1449; + public int animationId; + public int anInt1451; + public int graphicsId; + public int anInt1454; + public short[] aShortArray1455; + public short[] aShortArray1456; + + // added + public byte byteValue; + // added + public int intValue; + + /** + * The definitions mapping. + */ + private static final Map graphicDefinitions = new HashMap<>(); + + /** + * Gets the graphic definition for the given graphic id. + * @param gfxId The graphic id. + * @return The definition. + */ + public static final GraphicDefinition forId(int gfxId) { + GraphicDefinition def = graphicDefinitions.get(gfxId); + if (def != null) { + return def; + } + byte[] data = Cache.getIndexes()[21].getFileData(gfxId >>> 8, gfxId & 0xff); + def = new GraphicDefinition(); + def.graphicsId = gfxId; + if (data != null) { + def.readValueLoop(ByteBuffer.wrap(data)); + } + graphicDefinitions.put(gfxId, def); + return def; + } + + /** + * The main method, used for running a graphic definition search. + * @param s The arguments cast on runtime. + */ + public static final void main(String... s) { + try { + Cache.init(ServerConstants.CACHE_PATH); + } catch (Throwable e) { + e.printStackTrace(); + } + // 5046 - 5050 are related anims & 2148 + GraphicDefinition d = GraphicDefinition.forId(803); + + for (int i = 0; i < 5000; i++) { + GraphicDefinition def = GraphicDefinition.forId(i); + if (def == null) { + continue; + } + if ((def.animationId > 2000 && def.animationId < 2200) || (def.defaultModel >= 1300 && def.defaultModel < 1500)) { + + } + } + } + + /** + * Reads and handles all data from the input stream. + * @param buffer The input stream. + */ + private void readValueLoop(ByteBuffer buffer) { + for (;;) { + int opcode = buffer.get() & 0xFF; + if (opcode == 0) { + break; + } + readValues(buffer, opcode); + } + } + + /** + * Reads the opcode values from the input stream. + * @param buffer The input stream. + * @param opcode The opcode to handle. + */ + public void readValues(ByteBuffer buffer, int opcode) { + if (opcode != 1) { + if (opcode == 2) + animationId = buffer.getShort(); + else if (opcode == 4) + anInt1446 = buffer.getShort() & 0xFFFF; + else if (opcode != 5) { + if ((opcode ^ 0xffffffff) != -7) { + if (opcode == 7) + anInt1440 = buffer.get() & 0xFF; + else if ((opcode ^ 0xffffffff) == -9) + anInt1451 = buffer.get() & 0xFF; + else if (opcode != 9) { + if (opcode != 10) { + if (opcode == 11) { // added opcode + // aBoolean1442 = true; + byteValue = (byte) 1; + } else if (opcode == 12) { // added opcode + // aBoolean1442 = true; + byteValue = (byte) 4; + } else if (opcode == 13) { // added opcode + // aBoolean1442 = true; + byteValue = (byte) 5; + } else if (opcode == 14) { // added opcode + // aBoolean1442 = true; + // aByte2856 = 2; + byteValue = (byte) 2; + intValue = (buffer.get() & 0xFF) * 256; + } else if (opcode == 15) { + // aByte2856 = 3; + byteValue = (byte) 3; + intValue = buffer.getShort() & 0xFFFF; + } else if (opcode == 16) { + // aByte2856 = 3; + byteValue = (byte) 3; + intValue = buffer.getInt(); + } else if (opcode != 40) { + if ((opcode ^ 0xffffffff) == -42) { + int i = buffer.get() & 0xFF; + aShortArray1455 = new short[i]; + aShortArray1435 = new short[i]; + for (int i_0_ = 0; i > i_0_; i_0_++) { + aShortArray1455[i_0_] = (short) (buffer.getShort() & 0xFFFF); + aShortArray1435[i_0_] = (short) (buffer.getShort() & 0xFFFF); + } + } + } else { + int i = buffer.get() & 0xFF; + aShortArray1438 = new short[i]; + aShortArray1456 = new short[i]; + for (int i_1_ = 0; ((i ^ 0xffffffff) < (i_1_ ^ 0xffffffff)); i_1_++) { + aShortArray1438[i_1_] = (short) (buffer.getShort() & 0xFFFF); + aShortArray1456[i_1_] = (short) (buffer.getShort() & 0xFFFF); + } + } + } else + aBoolean1448 = true; + } else { + // aBoolean1442 = true; + byteValue = (byte) 3; + intValue = 8224; + } + } else + anInt1454 = buffer.getShort() & 0xFFFF; + } else + anInt1449 = buffer.getShort() & 0xFFFF; + } else + defaultModel = buffer.getShort(); + } + + /** + * Constructs a new {@code GraphicDefinition} {@code Object}. + */ + public GraphicDefinition() { + byteValue = 0; + intValue = -1; + anInt1446 = 128; + aBoolean1442 = false; + anInt1449 = 128; + anInt1451 = 0; + animationId = -1; + anInt1454 = 0; + anInt1440 = 0; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/cache/def/impl/IfaceDefinition.java b/Server/src/main/core/cache/def/impl/IfaceDefinition.java new file mode 100644 index 0000000..90b32c4 --- /dev/null +++ b/Server/src/main/core/cache/def/impl/IfaceDefinition.java @@ -0,0 +1,554 @@ +package core.cache.def.impl; + +import core.cache.Cache; +import core.net.packet.IoBuffer; +import core.net.packet.PacketHeader; + +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Optional; + +public class IfaceDefinition { + private static HashMap defCache = new HashMap<>(); + public int id; + public ComponentType type; + public int version; + public int clientCode; + public int baseX, baseY; + public int baseWidth, baseHeight; + public int dynWidth, dynHeight; + public int xMode, yMode; + public int overlayer; + public boolean hidden; + public int scrollMaxH, scrollMaxV; + public boolean noClickThrough; + public int spriteId, activeSpriteId; + public int angle2d; + public boolean hasAlpha; + public boolean spriteTiling; + public int alpha; + public int outlineThickness; + public int shadowColor; + public boolean hFlip, vFlip; + public int modelType, activeModelType; + public int modelId, activeModelId; + public int unknownModelProp_1; + public int unknownModelProp_2; + public int modelXAngle, modelYAngle; + public int modelYOffset; + public int modelZoom; + public int modelAnimId, activeModelAnimId; + public boolean modelOrtho; + public int unknownModelProp_3; + public int unknownModelProp_4; + public boolean unknownModelProp_5; + public int unknownModelProp_6; + public int unknownModelProp_7; + public int font; + public String text, activeText; + public int vPadding; + public int halign, valign; + public boolean shadowed; + public int color, activeColor, overColor, unknownColor; + public boolean filled; + public int lineWidth; + public boolean unknownProp_8; + public int[] unknownIntArray_1; + public int[] unknownIntArray_2; + public byte[] unknownByteArray_1; + public byte[] unknownByteArray_2; + public String optionBase; + public String[] ops; + public int dragDeadzone; + public int dragDeadtime; + public boolean dragRenderBehavior; + public String opCircumfix, opSuffix, option; + public int unknownProp_9, unknownProp_10, unknownProp_11; + public int[] cs1ComparisonOperands, cs1ComparisonOpcodes; + public int[][] cs1Scripts; + public int[] objCounts; + public int[] objTypes; + public int invMarginX, invMarginY; + public int[] invOffsetX, invOffsetY; + public int[] invSprite; + public int buttonType; + public String[] invOptions; + public LinkedScripts scripts; + public ScriptTriggers triggers; + + public IfaceDefinition[] children; + public int parent; + + @Override + public String toString() { + if (parent == id) { + return "[IF " + id + " (P)]"; + } else { + return "[IF " + (id >> 16) + ", CH " + (id & 0xFF) + " (" + type.name() + ")]"; + } + } + + public static IfaceDefinition forId (int id) { + if (defCache.containsKey(id)) { + return defCache.get(id); + } + IfaceDefinition def = loadAndParse(id); + defCache.put(id, def); + return def; + } + + public static IfaceDefinition forId (int id, int child) { + if (defCache.containsKey(child + (id << 16))) + return defCache.get(child + (id << 16)); + IfaceDefinition def = forId(id); + return def.children[child]; + } + + private static IfaceDefinition loadAndParse (int id) { + IfaceDefinition def = new IfaceDefinition(); + int childCount = Cache.getIndexes()[3].getFilesSize(id); + def.children = new IfaceDefinition[childCount]; + def.id = id; + def.parent = id; + for (int i = 0; i < childCount; i++) { + def.children[i] = parseChild(id, i); + } + return def; + } + + private static IfaceDefinition parseChild (int id, int childIndex) { + IfaceDefinition def = new IfaceDefinition(); + def.id = childIndex + (id << 16); + def.parent = id; + defCache.put(def.id, def); + + byte[] dataRaw = Cache.getIndexes()[3].getFileData(id, childIndex); + if (dataRaw == null) return def; + + IoBuffer data = new IoBuffer(-1, PacketHeader.NORMAL, ByteBuffer.wrap(dataRaw)); + + if (dataRaw[0] == -1) + decodeIf3 (def, data); + else + decodeIf1 (def, data); + + return def; + } + + private static void decodeIf1 (IfaceDefinition def, IoBuffer data) { + data.g1(); + def.version = 1; + def.type = ComponentType.values()[data.g1()]; + def.buttonType = data.g1(); + def.clientCode = data.g2(); + def.baseX = data.g2b(); + def.baseY = data.g2b(); + def.baseWidth = data.g2(); + def.baseHeight = data.g2(); + def.dynWidth = def.dynHeight = 0; + def.xMode = def.yMode = 0; + def.alpha = data.g1(); + def.overlayer = data.g2(); + if (def.overlayer == 65535) + def.overlayer = -1; + else def.overlayer += def.id & 0xFFFF0000; + def.unknownProp_11 = data.g2(); + + int unknownLocal_1 = data.g1(); + if (unknownLocal_1 > 0) { + def.cs1ComparisonOpcodes = new int[unknownLocal_1]; + def.cs1ComparisonOperands = new int[unknownLocal_1]; + for (int i = 0; i < unknownLocal_1; i++) { + def.cs1ComparisonOpcodes[i] = data.g1(); + def.cs1ComparisonOperands[i] = data.g2(); + } + } + + int unknownLocal_2 = data.g1(); + int unknownLocal_3; + if (unknownLocal_2 > 0) { + def.cs1Scripts = new int[unknownLocal_2][]; + for (int i = 0; i < unknownLocal_2; i++) { + unknownLocal_3 = data.g2(); + def.cs1Scripts[i] = new int[unknownLocal_3]; + for (int j = 0; j < unknownLocal_3; j++) { + def.cs1Scripts[i][j] = data.g2(); + if (def.cs1Scripts[i][j] == 65535) + def.cs1Scripts[i][j] = -1; + } + } + } + + int flags = 0; + if (def.type == ComponentType.SCROLLABLE) { + def.scrollMaxV = data.g2(); + def.hidden = data.g1() == 1; + } + if (def.type == ComponentType.UNKNOWN_1) { + data.g2(); + data.g1(); + } + if (def.type == ComponentType.UNKNOWN_2) { + def.dynHeight = 3; + def.objCounts = new int[def.baseWidth * def.baseHeight]; + def.objTypes = new int[def.baseWidth * def.baseHeight]; + def.dynWidth = 3; + int unknownLocal_4 = data.g1(); + int unknownLocal_5 = data.g1(); + if (unknownLocal_4 == 1) + flags = 268435456; + int unknownLocal_6 = data.g1(); + if (unknownLocal_5 == 1) + flags |= 0x40000000; + if (unknownLocal_6 == 1) + flags |= Integer.MAX_VALUE; + int unknownLocal_7 = data.g1(); + if (unknownLocal_7 == 1) + flags |= 0x20000000; + def.invMarginX = data.g1(); + def.invMarginY = data.g1(); + def.invOffsetX = new int[20]; + def.invOffsetY = new int[20]; + def.invSprite = new int[20]; + for (int i = 0; i < 20; i++) { + int hasSprite = data.g1(); + if (hasSprite == 1) { + def.invOffsetX[i] = data.g2b(); + def.invOffsetY[i] = data.g2b(); + def.invSprite[i] = data.g4(); + } else { + def.invSprite[i] = -1; + } + } + def.invOptions = new String[5]; + for (int i = 0; i < 5; i++) { + String option = data.getJagString(); + if (option.length() > 0) { + def.invOptions[i] = option; + flags |= 0x1 << i + 23; + } + } + } + if (def.type == ComponentType.UNKNOWN_3) { + def.filled = data.g1() == 1; + } + if (def.type == ComponentType.TEXT || def.type == ComponentType.UNKNOWN_1) { + def.halign = data.g1(); + def.valign = data.g1(); + def.vPadding = data.g1(); + def.font = data.g2(); + if (def.font == 65535) + def.font = -1; + def.shadowed = data.g1() == 1; + } + if (def.type == ComponentType.TEXT) { + def.text = data.getJagString(); + def.activeText = data.getJagString(); + } + if (def.type == ComponentType.UNKNOWN_1 || def.type == ComponentType.UNKNOWN_3 || def.type == ComponentType.TEXT) { + def.color = data.g4(); + } + if (def.type == ComponentType.UNKNOWN_3 || def.type == ComponentType.TEXT) { + def.activeColor = data.g4(); + def.overColor = data.g4(); + def.unknownColor = data.g4(); + } + if (def.type == ComponentType.SPRITE) { + def.spriteId = data.g4(); + def.activeSpriteId = data.g4(); + } + if (def.type == ComponentType.MODEL) { + def.modelType = 1; + def.modelId = data.g2(); + if (def.modelId == 65535) + def.modelId = -1; + def.activeModelType = 1; + def.activeModelId = data.g2(); + if (def.activeModelId == 65535) + def.activeModelId = -1; + def.modelAnimId = data.g2(); + if (def.modelAnimId == 65535) + def.modelAnimId = -1; + def.activeModelAnimId = data.g2(); + if (def.activeModelAnimId == 65535) + def.activeModelAnimId = -1; + def.modelZoom = data.g2(); + def.modelXAngle = data.g2(); + def.modelYAngle = data.g2(); + } + if (def.type == ComponentType.UNKNOWN_7) { + def.dynHeight = def.dynWidth = 3; + def.objCounts = new int [def.baseHeight * def.baseWidth]; + def.objTypes = new int [def.baseHeight * def.baseWidth]; + def.halign = data.g1(); + def.font = data.g2(); + if (def.font == 65535) + def.font = -1; + def.shadowed = data.g1() == 1; + def.color = data.g4(); + def.invMarginX = data.g2b(); + def.invMarginY = data.g2b(); + int invHasOptions = data.g1(); + if (invHasOptions == 1) { + flags |= 0x40000000; + } + def.invOptions = new String[5]; + for (int i = 0; i < 5; i++) { + String option = data.getJagString(); + if (option.length() > 0) { + def.invOptions[i] = option; + flags |= 0x1 << i + 23; + } + } + } + if (def.type == ComponentType.UNKNOWN_8) + def.text = data.getJagString(); + if (def.buttonType == 2 || def.type == ComponentType.UNKNOWN_2) { + def.opCircumfix = data.getJagString(); + def.opSuffix = data.getJagString(); + int unknownLocal_4 = data.g2() & 0x3F; + flags |= unknownLocal_4 << 11; + } + if (def.buttonType == 1 || def.buttonType == 4 || def.buttonType == 5 || def.buttonType == 6) { + def.option = data.getJagString(); + if (def.option.length() == 0) { + switch (def.buttonType) { + case 1: + def.option = "Ok"; + break; + case 4: + case 5: + def.option = "Select"; + break; + case 6: + def.option = "Continue"; + break; + } + } + } + if (def.buttonType == 1 || def.buttonType == 4 || def.buttonType == 5) { + flags |= 0x400000; + } + if (def.buttonType == 6) { + flags |= 0x1; + } + } + + private static void decodeIf3 (IfaceDefinition def, IoBuffer data) { + data.g1(); + def.version = 3; + int type = data.g1(); + if ((type & 0x80) != 0) { + type &= 0x7F; + data.getJagString(); + } + def.type = ComponentType.values()[type]; + def.clientCode = data.g2(); + def.baseX = data.g2b(); + def.baseY = data.g2b(); + def.baseWidth = data.g2(); + def.baseHeight = data.g2(); + def.dynWidth = data.g1b(); + def.dynHeight = data.g1b(); + def.yMode = data.g1b(); + def.xMode = data.g1b(); + def.overlayer = data.g2(); + if (def.overlayer == 65535) { + def.overlayer = -1; + } else { + def.overlayer = (def.id & 0xFFFF0000) + def.overlayer; + } + def.hidden = data.g1() == 1; + parseIf3Type (def, data); + + int unknownLocal_1 = data.g3(); + int unknownLocal_2 = data.g1(); + int unknownLocal_3; + if (unknownLocal_2 != 0) { + def.unknownIntArray_1 = new int[10]; + def.unknownByteArray_1 = new byte[10]; + def.unknownByteArray_2 = new byte[10]; + + while (unknownLocal_2 != 0) { + unknownLocal_3 = (unknownLocal_2 >> 4) - 1; + unknownLocal_2 = data.g1() | unknownLocal_2 << 8; + unknownLocal_2 &= 0xFFF; + if (unknownLocal_2 == 4095) { + def.unknownIntArray_1[unknownLocal_3] = -1; + } else { + def.unknownIntArray_1[unknownLocal_3] = unknownLocal_2; + } + def.unknownByteArray_2[unknownLocal_3] = (byte) data.g1b(); + def.unknownByteArray_1[unknownLocal_3] = (byte) data.g1b(); + unknownLocal_2 = data.g1(); + } + } + + def.optionBase = data.getJagString(); + unknownLocal_2 = data.g1(); + int opCount = unknownLocal_2 & 0xF; + if (opCount > 0) { + def.ops = new String[opCount]; + for (int i = 0; i < opCount; i++) { + def.ops[i] = data.getJagString(); + } + } + + int unknownLocal_5; + int unknownLocal_6 = unknownLocal_2 >> 4; + if (unknownLocal_6 > 0) { + unknownLocal_5 = data.g1(); + def.unknownIntArray_2 = new int[unknownLocal_5 + 1]; + for (int i = 0; i < def.unknownIntArray_2.length; i++) + def.unknownIntArray_2[i] = -1; + def.unknownIntArray_2[unknownLocal_5] = data.g2(); + } + if (unknownLocal_6 > 1) { + unknownLocal_5 = data.g1(); + def.unknownIntArray_2[unknownLocal_5] = data.g2(); + } + def.dragDeadzone = data.g1(); + def.dragDeadtime = data.g1(); + def.dragRenderBehavior = data.g1() == 1; + unknownLocal_5 = -1; + def.opCircumfix = data.getJagString(); + + if ((unknownLocal_1 >> 11 & 0x7F) != 0) { + unknownLocal_5 = data.g2(); + def.unknownProp_9 = data.g2(); + if (unknownLocal_5 == 65535) + unknownLocal_5 = -1; + if (def.unknownProp_9 == 65535) + def.unknownProp_9 = -1; + def.unknownProp_10 = data.g2(); + if (def.unknownProp_10 == 65535) + def.unknownProp_10 = -1; + } + + def.scripts = new LinkedScripts(); + def.scripts.unknown = parseIf3ScriptArgs(data); + def.scripts.onMouseOver = parseIf3ScriptArgs(data); + def.scripts.onMouseLeave = parseIf3ScriptArgs(data); + def.scripts.onUseWith = parseIf3ScriptArgs(data); + def.scripts.onUse = parseIf3ScriptArgs(data); + def.scripts.onVarpTransmit = parseIf3ScriptArgs(data); + def.scripts.onInvTransmit = parseIf3ScriptArgs(data); + def.scripts.onStatTransmit = parseIf3ScriptArgs(data); + def.scripts.onTimer = parseIf3ScriptArgs(data); + def.scripts.onOptionClick = parseIf3ScriptArgs(data); + def.scripts.onMouseRepeat = parseIf3ScriptArgs(data); + def.scripts.onClickRepeat = parseIf3ScriptArgs(data); + def.scripts.onDrag = parseIf3ScriptArgs(data); + def.scripts.onRelease = parseIf3ScriptArgs(data); + def.scripts.onHold = parseIf3ScriptArgs(data); + def.scripts.onDragStart = parseIf3ScriptArgs(data); + def.scripts.onDragRelease = parseIf3ScriptArgs(data); + def.scripts.onScroll = parseIf3ScriptArgs(data); + def.scripts.onVarcTransmit = parseIf3ScriptArgs(data); + def.scripts.onVarcstrTransmit = parseIf3ScriptArgs(data); + + def.triggers = new ScriptTriggers(); + def.triggers.varpTriggers = parseIf3Triggers(data); + def.triggers.inventoryTriggers = parseIf3Triggers(data); + def.triggers.statTriggers = parseIf3Triggers(data); + def.triggers.varcTriggers = parseIf3Triggers(data); + def.triggers.varcstrTriggers = parseIf3Triggers(data); + } + + private static ScriptArgs parseIf3ScriptArgs (IoBuffer data) { + int argCount = data.g1(); + if (argCount == 0) + return null; + Object[] argArray = new Object[argCount]; + for (int i = 0; i < argCount; i++) { + int type = data.g1(); + if (type == 0) { + int datum = Integer.valueOf(data.g4()); + argArray[i] = datum; + } else if (type == 1) { + String datum = data.getJagString(); + argArray[i] = datum; + } + } + return new ScriptArgs((int) argArray[0], Arrays.copyOfRange(argArray, 1, argArray.length)); + } + + private static int[] parseIf3Triggers (IoBuffer data) { + int triggerCount = data.g1(); + if (triggerCount == 0) + return null; + int[] triggers = new int[triggerCount]; + for (int i = 0; i < triggerCount; i++) { + triggers[i] = data.g4(); + } + return triggers; + } + + private static void parseIf3Type (IfaceDefinition def, IoBuffer data) { + switch (def.type) { + case SCROLLABLE: + def.scrollMaxH = data.g2(); + def.scrollMaxV = data.g2(); + def.noClickThrough = data.g1() == 1; + break; + case SPRITE: + def.spriteId = data.g4(); + def.angle2d = data.g2(); + int spriteFlags = data.g1(); + def.hasAlpha = (spriteFlags & 0x2) != 0; + def.spriteTiling = (spriteFlags & 0x1) != 0; + def.alpha = data.g1(); + def.outlineThickness = data.g1(); + def.shadowColor = data.g4(); + def.vFlip = data.g1() == 1; + def.hFlip = data.g1() == 1; + break; + case MODEL: + def.modelType = 1; + def.modelId = data.g2(); + if (def.modelId == 65535) + def.modelId = -1; + def.unknownModelProp_1 = data.g2b(); + def.unknownModelProp_2 = data.g2b(); + def.modelXAngle = data.g2(); + def.modelYAngle = data.g2(); + def.modelYOffset = data.g2(); + def.modelZoom = data.g2(); + def.modelAnimId = data.g2(); + if (def.modelAnimId == 65535) + def.modelAnimId = -1; + def.modelOrtho = data.g1() == 1; + def.unknownModelProp_3 = data.g2(); + def.unknownModelProp_4 = data.g2(); + def.unknownModelProp_5 = data.g1() == 1; + if (def.dynWidth != 0) + def.unknownModelProp_6 = data.g2(); + if (def.dynHeight != 0) + def.unknownModelProp_7 = data.g2(); + break; + case TEXT: + def.font = data.g2(); + if (def.font == 65535) + def.font = -1; + def.text = data.getJagString(); + def.vPadding = data.g1(); + def.halign = data.g1(); + def.valign = data.g1(); + def.shadowed = data.g1() == 1; + def.color = data.g4(); + break; + case UNKNOWN_3: + def.color = data.g4(); + def.filled = data.g1() == 1; + def.alpha = data.g1(); + break; + case UNKNOWN_9: + def.lineWidth = data.g1(); + def.color = data.g4(); + def.unknownProp_8 = data.g1() == 1; + break; + } + } + +} diff --git a/Server/src/main/core/cache/def/impl/ItemDefinition.java b/Server/src/main/core/cache/def/impl/ItemDefinition.java new file mode 100644 index 0000000..0474e11 --- /dev/null +++ b/Server/src/main/core/cache/def/impl/ItemDefinition.java @@ -0,0 +1,1708 @@ +package core.cache.def.impl; + +import content.global.skill.summoning.familiar.BurdenBeast; +import core.api.EquipmentSlot; +import core.cache.Cache; +import core.cache.def.Definition; +import core.cache.misc.buffer.ByteBufferUtils; +import core.game.container.Container; +import core.game.interaction.OptionHandler; +import core.game.node.entity.player.Player; +import core.game.node.entity.skill.Skills; +import core.game.node.item.Item; +import core.game.node.item.ItemPlugin; +import core.game.world.GameWorld; +import core.tools.Log; +import core.tools.StringUtils; +import core.game.system.config.ItemConfigParser; +import org.rs09.consts.Items; + +import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Arrays; + +import static core.api.ContentAPIKt.equipSlot; +import static core.api.ContentAPIKt.log; + +/** + * Represents an item's definitions. + * @author Emperor + */ +public class ItemDefinition extends Definition { + + /** + * The item definitions mapping. + */ + private static final Map DEFINITIONS = new HashMap<>(); + + /** + * The default option handlers. + */ + private static final Map OPTION_HANDLERS = new HashMap<>(); + + /** + * The interface model id. + */ + private int interfaceModelId; + + /** + * The model zoom. + */ + private int modelZoom; + + /** + * The model rotation. + */ + private int modelRotationX; + + /** + * The model rotation. + */ + private int modelRotationY; + + /** + * The model offset. + */ + private int modelOffsetX; + + /** + * The model offset. + */ + private int modelOffsetY; + + /** + * If item is stackable. + */ + private boolean stackable; + + /** + * The item value. + */ + private int value = 1; + + /** + * If item is members only. + */ + private boolean membersOnly; + + /** + * The male model wear id. + */ + private int maleWornModelId1 = -1; + + /** + * The female model wear id. + */ + private int femaleWornModelId1 = -1; + + /** + * The male model wear id. + */ + private int maleWornModelId2 = -1; + + /** + * The female wear model id. + */ + private int femaleWornModelId2 = -1; + + /** + * The male model wear id. + */ + private int maleWornModelId3 = -1; + + /** + * The female model wear id. + */ + private int femaleWornModelId3 = -1; + + /** + * The male model wear id. + */ + private int maleWornModelId4 = -1; + + /** + * The female wear model id. + */ + private int femaleWornModelId4 = -1; + + /** + * The ground actions. + */ + private String[] groundActions; + + /** + * The original model colors. + */ + private short[] originalModelColors; + + /** + * The modified model colors. + */ + private short[] modifiedModelColors; + + /** + * The texture color 1. + */ + private short[] textureColour1; + + /** + * The texture color 2. + */ + private short[] textureColour2; + + /** + * A unknown byte array. + */ + private byte[] unknownArray1; + + /** + * A unknown integer array. + */ + private int[] unknownArray2; + + /** + * A unknown integer array. + */ + private int[][] unknownArray3; + + /** + * If item is noted. + */ + private boolean unnoted = true; + + /** + * The colour equipment. + */ + private int colourEquip1 = -1; + + /** + * The colour equipment. + */ + private int colourEquip2; + + /** + * The note item id if un-noted. The un-noted item id if noted. -1 if no noted counterpart. + */ + private int noteId = -1; + + /** + * The note template id. + */ + private int noteTemplateId = -1; + + /** + * The stackable ids. + */ + private int[] stackIds; + + /** + * The stackable amounts. + */ + private int[] stackAmounts; + + /** + * The team id. + */ + private int teamId; + + /** + * The lend id. + */ + private int lendId = -1; + + /** + * The lend template id. + */ + private int lendTemplateId = -1; + + /** + * The recolour id. + */ + private int recolourId = -1; + + /** + * The recolour template id. + */ + private int recolourTemplateId = -1; + + /** + * The equip id. + */ + private int equipId; + + /** + * The item requirements + */ + private HashMap itemRequirements; + + /** + * The clientscript data. + */ + private HashMap clientScriptData; + + /** + * The item type. + */ + private int itemType; + + /** + * Constructs a new {@code ItemDefinition} {@code Object}. + */ + public ItemDefinition() { + groundActions = new String[] { null, null, "take", null, null }; + options = new String[] { null, null, null, null, "drop" }; + } + + /** + * Parses the item definitions. + */ + public static void parse() { + for (int itemId = 0; itemId < Cache.getItemDefinitionsSize(); itemId++) { + byte[] data = Cache.getIndexes()[19].getFileData(itemId >>> 8, itemId & 0xFF); + if (data == null) { + ItemDefinition.getDefinitions().put(itemId, new ItemDefinition()); + continue; + } + ItemDefinition def = ItemDefinition.parseDefinition(itemId, ByteBuffer.wrap(data)); + if (def == null) { + log(ItemDefinition.class, Log.ERR, "Could not load item definitions for id " + itemId + " - no definitions found!"); + return ; + } + if(itemId == 14958) + def.setStackable(true); + + ItemDefinition.getDefinitions().put(itemId, def); + } + ItemDefinition.defineTemplates(); + } + + /** + * Gets an item definition. + * @param itemId The item's id. + * @return The item definition. + */ + public static ItemDefinition forId(int itemId) { + ItemDefinition def = DEFINITIONS.get(itemId); + if (def != null) { + return def; + } + return new ItemDefinition(); + } + + /** + * Parses an item's definitions. + * @param itemId The item id. + * @param buffer The buffer. + * @return The item definition. + */ + public static ItemDefinition parseDefinition(int itemId, ByteBuffer buffer) { + ItemDefinition def = new ItemDefinition(); + def.id = itemId; + while (true) { + int opcode = buffer.get() & 0xFF; + if (opcode == 0) { + break; + } else if (opcode == 1) { + def.interfaceModelId = buffer.getShort() & 0xFFFF; + } else if (opcode == 2) { + def.name = ByteBufferUtils.getString(buffer); + } else if (opcode == 3) { + def.handlers.put("examine", ByteBufferUtils.getString(buffer)); // Examine + // info. + } else if (opcode == 4) { + def.modelZoom = buffer.getShort() & 0xFFFF; + } else if (opcode == 5) { + def.modelRotationX = buffer.getShort() & 0xFFFF; + } else if (opcode == 6) { + def.modelRotationY = buffer.getShort() & 0xFFFF; + } else if (opcode == 7) { + def.modelOffsetX = buffer.getShort() & 0xFFFF; + if (def.modelOffsetX > 32767) + def.modelOffsetX -= 65536; + } else if (opcode == 8) { + def.modelOffsetY = buffer.getShort() & 0xFFFF; + if (def.modelOffsetY > 32767) { + def.modelOffsetY -= 65536; + } + } else if (opcode == 10) { + // buffer.getShort(); //10 is unused opcode. + } else if (opcode == 11) { + def.stackable = true; + } else if (opcode == 12) { + def.value = ((buffer.get() & 0xFF) << 24) + ((buffer.get() & 0xFF) << 16) + ((buffer.get() & 0xFF) << 8) + (buffer.get() & 0xFF); + } else if (opcode == 16) { + def.membersOnly = true; + } else if (opcode == 23) { + def.maleWornModelId1 = buffer.getShort() & 0xFFFF; + // buffer.get(); + } else if (opcode == 24) { + def.femaleWornModelId1 = buffer.getShort() & 0xFFFF; + } else if (opcode == 25) { + def.maleWornModelId2 = buffer.getShort() & 0xFFFF; + // buffer.get(); + } else if (opcode == 26) { + def.femaleWornModelId2 = buffer.getShort() & 0xFFFF; + } else if (opcode >= 30 && opcode < 35) { + def.groundActions[opcode - 30] = ByteBufferUtils.getString(buffer); + } else if (opcode >= 35 && opcode < 40) { + def.options[opcode - 35] = ByteBufferUtils.getString(buffer); + } else if (opcode == 40) { + int length = buffer.get() & 0xFF; + def.originalModelColors = new short[length]; + def.modifiedModelColors = new short[length]; + for (int index = 0; index < length; index++) { + def.originalModelColors[index] = buffer.getShort(); + def.modifiedModelColors[index] = buffer.getShort(); + } + } else if (opcode == 41) { + int length = buffer.get() & 0xFF; + def.textureColour1 = new short[length]; + def.textureColour2 = new short[length]; + for (int index = 0; index < length; index++) { + def.textureColour1[index] = buffer.getShort(); + def.textureColour2[index] = buffer.getShort(); + } + } else if (opcode == 42) { + int length = buffer.get() & 0xFF; + def.unknownArray1 = new byte[length]; + for (int index = 0; index < length; index++) + def.unknownArray1[index] = buffer.get(); + } else if (opcode == 65) { + def.unnoted = true; + } else if (opcode == 78) { + def.colourEquip1 = buffer.getShort() & 0xFFFF; + } else if (opcode == 79) { + def.colourEquip2 = buffer.getShort() & 0xFFFF; + } else if (opcode == 90) { + def.setMaleWornModelId3(buffer.getShort()); + } else if (opcode == 91) { + def.setFemaleWornModelId3(buffer.getShort()); + } else if (opcode == 92) { + def.setMaleWornModelId4(buffer.getShort()); + } else if (opcode == 93) { + def.setFemaleWornModelId4(buffer.getShort()); + } else if (opcode == 95) { + buffer.getShort(); + } else if (opcode == 96) { + def.itemType = buffer.get(); + } else if (opcode == 97) { + def.noteId = buffer.getShort() & 0xFFFF; + } else if (opcode == 98) { + def.noteTemplateId = buffer.getShort() & 0xFFFF; + } else if (opcode >= 100 && opcode < 110) { + if (def.stackIds == null) { + def.stackIds = new int[10]; + def.stackAmounts = new int[10]; + } + def.stackIds[opcode - 100] = buffer.getShort() & 0xFFFF; + def.stackAmounts[opcode - 100] = buffer.getShort() & 0xFFFF; + } else if (opcode == 110) { + buffer.getShort(); + } else if (opcode == 111) { + buffer.getShort(); + } else if (opcode == 112) { + buffer.getShort(); + } else if (opcode == 113) { + buffer.get(); + } else if (opcode == 114) { + buffer.get(); + } else if (opcode == 115) { + def.teamId = buffer.get(); + } else if (opcode == 121) { + def.lendId = buffer.getShort() & 0xFFFF; + } else if (opcode == 122) { + def.lendTemplateId = buffer.getShort() & 0xFFFF; + } else if (opcode == 125) { + buffer.get(); + buffer.get(); + buffer.get(); + } else if (opcode == 126) { + buffer.get(); + buffer.get(); + buffer.get(); + } else if (opcode == 127) { + buffer.get(); + buffer.getShort(); + } else if (opcode == 128) { + buffer.get(); + buffer.getShort(); + } else if (opcode == 129) { + buffer.get(); + buffer.getShort(); + } else if (opcode == 130) { + buffer.get(); + buffer.getShort(); + } else if (opcode == 249) { + int length = buffer.get() & 0xFF; + if (def.clientScriptData == null) { + def.clientScriptData = new HashMap(); + } + for (int index = 0; index < length; index++) { + boolean string = (buffer.get() & 0xFF) == 1; + int key = ByteBufferUtils.getMedium(buffer); + Object value = string ? ByteBufferUtils.getString(buffer) : buffer.getInt(); + def.clientScriptData.put(key, value); + } + } else { + + break; + } + } + return def; + } + + /** + * Defines the definitions for noted, lending and recolored items. + */ + public static void defineTemplates() { + int equipId = 0; + for (int i = 0; i < Cache.getItemDefinitionsSize(); i++) { + ItemDefinition def = forId(i); + if (def.noteTemplateId != -1) { + def.transferNoteDefinition(forId(def.noteId), forId(def.noteTemplateId)); + } + if (def.lendTemplateId != -1) { + def.transferLendDefinition(forId(def.lendId), forId(def.lendTemplateId)); + } + if (def.recolourTemplateId != -1) { + def.transferRecolourDefinition(forId(def.recolourId), forId(def.recolourTemplateId)); + } + if (def != null && (def.maleWornModelId1 >= 0 || def.maleWornModelId2 >= 0)) { + def.equipId = equipId++; + } + } + forId(2513).equipId = forId(3140).equipId; + } + + /** + * Transfers definitions for noted items. + * @param reference The reference definitions. + * @param templateReference The template definitions. + */ + public void transferNoteDefinition(ItemDefinition reference, ItemDefinition templateReference) { + membersOnly = reference.membersOnly; + interfaceModelId = templateReference.interfaceModelId; + originalModelColors = templateReference.originalModelColors; + name = reference.name; + modelOffsetY = templateReference.modelOffsetY; + textureColour1 = templateReference.textureColour1; + value = reference.value; + modelRotationY = templateReference.modelRotationY; + stackable = true; + unnoted = false; + modifiedModelColors = templateReference.modifiedModelColors; + modelRotationX = templateReference.modelRotationX; + modelZoom = templateReference.modelZoom; + textureColour1 = templateReference.textureColour1; + handlers.put(ItemConfigParser.TRADEABLE, true); + } + + /** + * Transfers definitions for lending items. + * @param reference The reference definitions. + * @param templateReference The template definitions. + */ + public void transferLendDefinition(ItemDefinition reference, ItemDefinition templateReference) { + femaleWornModelId1 = reference.femaleWornModelId1; + maleWornModelId2 = reference.maleWornModelId2; + membersOnly = reference.membersOnly; + interfaceModelId = templateReference.interfaceModelId; + textureColour2 = reference.textureColour2; + groundActions = reference.groundActions; + unknownArray1 = reference.unknownArray1; + modelRotationX = templateReference.modelRotationX; + modelRotationY = templateReference.modelRotationY; + originalModelColors = reference.originalModelColors; + name = reference.name; + maleWornModelId1 = reference.maleWornModelId1; + colourEquip1 = reference.colourEquip1; + teamId = reference.teamId; + modelOffsetY = templateReference.modelOffsetY; + clientScriptData = reference.clientScriptData; + modifiedModelColors = reference.modifiedModelColors; + colourEquip2 = reference.colourEquip2; + modelOffsetX = templateReference.modelOffsetX; + textureColour1 = reference.textureColour1; + value = 0; + modelZoom = templateReference.modelZoom; + options = new String[5]; + femaleWornModelId2 = reference.femaleWornModelId2; + if (reference.options != null) { + options = reference.options.clone(); + } + } + + /** + * Transfers definitions for recolored items. + * @param reference The reference definitions. + * @param templateReference The template definitions. + */ + public void transferRecolourDefinition(ItemDefinition reference, ItemDefinition templateReference) { + femaleWornModelId2 = reference.femaleWornModelId2; + options = new String[5]; + modelRotationY = templateReference.modelRotationY; + name = reference.name; + maleWornModelId1 = reference.maleWornModelId1; + modelOffsetY = templateReference.modelOffsetY; + femaleWornModelId1 = reference.femaleWornModelId1; + maleWornModelId2 = reference.maleWornModelId2; + modelOffsetX = templateReference.modelOffsetX; + unknownArray1 = reference.unknownArray1; + stackable = reference.stackable; + modelRotationX = templateReference.modelRotationX; + textureColour1 = reference.textureColour1; + colourEquip1 = reference.colourEquip1; + textureColour2 = reference.textureColour2; + modifiedModelColors = reference.modifiedModelColors; + modelZoom = templateReference.modelZoom; + colourEquip2 = reference.colourEquip2; + teamId = reference.teamId; + value = 0; + groundActions = reference.groundActions; + originalModelColors = reference.originalModelColors; + membersOnly = reference.membersOnly; + clientScriptData = reference.clientScriptData; + interfaceModelId = templateReference.interfaceModelId; + if (reference.options != null) { + options = reference.options.clone(); + } + } + + /** + * Checks if the player has the needed requirements to use this item. + * @param player The player. + * @param wield If requirements are checked for wearing the item. + * @param message If a message should be sent when the player does not meet + * a requirement. + * @return {@code True} if so. + */ + public boolean hasRequirement(Player player, boolean wield, boolean message) { + Map requirements = getConfiguration(ItemConfigParser.REQUIREMENTS); + if (requirements == null) { + return true; + } + for (int skill : requirements.keySet()) { + if (skill < 0 || skill >= Skills.SKILL_NAME.length) { + continue; + } + int level = requirements.get(skill); + if (player.getSkills().getStaticLevel(skill) < level) { + if (message) { + String name = Skills.SKILL_NAME[skill]; + player.getPacketDispatch().sendMessage("You need a" + (StringUtils.isPlusN(name) ? "n " : " ") + name + " level of " + level + " to " + (wield ? "wear " : "use ") + "this."); + } + return false; + } + } + return true; + } + + /** + * Checks if the player can enter entrana. + * @param player the player. + * @return {@code True} if so. + */ + public static boolean canEnterEntrana(Player player) { + Container[] containers; + if (player.getFamiliarManager().hasFamiliar() && player.getFamiliarManager().getFamiliar().isBurdenBeast()) { + containers = new Container[] { player.getInventory(), player.getEquipment(), ((BurdenBeast) player.getFamiliarManager().getFamiliar()).getContainer() }; + } else { + containers = new Container[] { player.getInventory(), player.getEquipment() }; + } + for (Container c : containers) { + for (Item i : c.toArray()) { + if (i == null) { + continue; + } + if (GameWorld.getSettings().getSkillcape_perks() && i.getId() == Items.RUNECRAFT_CAPE_9765 || i.getId() == Items.RUNECRAFT_CAPET_9766) { + continue; + } + if (!i.getDefinition().isAllowedOnEntrana()) { + return false; + } + } + } + return true; + } + + /** + * The allowed ids. + */ + private static final HashSet entranaAllowedItems = new HashSet(Arrays.asList( + Items.PENANCE_GLOVES_10553, + Items.ICE_GLOVES_1580, + Items.BOOTS_OF_LIGHTNESS_88, + Items.CLIMBING_BOOTS_3105, + Items.SPOTTED_CAPE_10069, + Items.SPOTTIER_CAPE_10071, + Items.SARADOMIN_CAPE_2412, + Items.ZAMORAK_CAPE_2414, + Items.GUTHIX_CAPE_2413, + Items.SARADOMIN_CLOAK_10446, + Items.ZAMORAK_CLOAK_10450, + Items.GUTHIX_CLOAK_10448, + Items.HOLY_BOOK_3840, + Items.DAMAGED_BOOK_3839, + Items.UNHOLY_BOOK_3842, + Items.DAMAGED_BOOK_3841, + Items.BOOK_OF_BALANCE_3844, + Items.DAMAGED_BOOK_3843, + Items.WIZARD_BOOTS_2579, + Items.COMBAT_BRACELET1_11124, + Items.COMBAT_BRACELET2_11122, + Items.COMBAT_BRACELET3_11120, + Items.COMBAT_BRACELET4_11118, + Items.REGEN_BRACELET_11133, + Items.WARLOCK_CLOAK_14081, + Items.WARLOCK_LEGS_14077, + Items.WARLOCK_TOP_14076, + Items.MONKS_ROBE_542, + Items.MONKS_ROBE_544, + Items.HAM_SHIRT_4298, + Items.HAM_ROBE_4300, + Items.HAM_HOOD_4302, + Items.HAM_CLOAK_4304, + Items.HAM_LOGO_4306, + Items.GLOVES_4308, + Items.BOOTS_4310, + Items.ZAMORAK_ROBE_1033, + Items.ZAMORAK_ROBE_1035 + )); + private static final HashSet entranaBannedItems = new HashSet(Arrays.asList( + /**Items.BUTTERFLY_NET_10010, easing the restriction until barehanded implementation**/ + Items.DWARF_CANNON_SET_11967, + Items.CANNON_BARRELS_10, + Items.CANNON_BASE_6, + Items.CANNON_STAND_8, + Items.CANNON_FURNACE_12, + Items.COOKING_GAUNTLETS_775, + Items.CHAOS_GAUNTLETS_777, + Items.GOLDSMITH_GAUNTLETS_776, + Items.KARAMJA_GLOVES_1_11136, + Items.KARAMJA_GLOVES_2_11138, + Items.KARAMJA_GLOVES_3_11140, + Items.VYREWATCH_TOP_9634, + Items.VYREWATCH_LEGS_9636, + Items.VYREWATCH_SHOES_9638 + )); + + + /** + * Checks if the item is allowed on entrana. + * @return {@code True} if so. + */ + public boolean isAllowedOnEntrana() { + if (entranaAllowedItems.contains(getId())) { + return true; + } + if (entranaBannedItems.contains(getId())) { + return false; + } + if (equipSlot(getId()) == EquipmentSlot.AMMO) { + return true; + } + if (getName().toLowerCase().startsWith("ring") || getName().toLowerCase().startsWith("amulet")) { + return true; + } + int[] bonuses = getConfiguration(ItemConfigParser.BONUS); + return bonuses == null || Arrays.stream(bonuses).allMatch(x -> x == 0); + } + + /** + * Gets the level requirement for this item. + * @param skillId The skill id. + * @return The level required. + */ + public int getRequirement(int skillId) { + Map requirements = getConfiguration(ItemConfigParser.REQUIREMENTS); + if (requirements == null) { + return 0; + } + Integer level = requirements.get(skillId); + return level == null ? 0 : level; + } + + /** + * Gets the wielding animation id (render animation id). + * @return The wield animation id. + */ + public int getRenderAnimationId() { + return getConfiguration(ItemConfigParser.RENDER_ANIM_ID, 1426); + } + + @Override + public int getId() { + return id; + } + + @Override + public void setId(int id) { + this.id = id; + } + + /** + * Gets the interfaceModelId. + * @return The interfaceModelId. + */ + public int getInterfaceModelId() { + return interfaceModelId; + } + + /** + * Sets the interfaceModelId. + * @param interfaceModelId The interfaceModelId to set. + */ + public void setInterfaceModelId(int interfaceModelId) { + this.interfaceModelId = interfaceModelId; + } + + /** + * Gets the name. + * @return The name. + */ + @Override + public String getName() { + return name; + } + + /** + * Sets the name. + * @param name The name to set. + */ + @Override + public void setName(String name) { + this.name = name; + } + + /** + * Checks if the item type is for player usage. + * @return {@code True}. + */ + public boolean isPlayerType() { + return itemType == 0; + } + + /** + * Gets the modelZoom. + * @return The modelZoom. + */ + public int getModelZoom() { + return modelZoom; + } + + /** + * Sets the modelZoom. + * @param modelZoom The modelZoom to set. + */ + public void setModelZoom(int modelZoom) { + this.modelZoom = modelZoom; + } + + /** + * Gets the modelRotation1. + * @return The modelRotation1. + */ + public int getModelRotationX() { + return modelRotationX; + } + + /** + * Sets the modelRotation1. + * @param modelRotation1 The modelRotation1 to set. + */ + public void setModelRotationX(int modelRotation1) { + this.modelRotationX = modelRotation1; + } + + /** + * Gets the modelRotation2. + * @return The modelRotation2. + */ + public int getModelRotationY() { + return modelRotationY; + } + + /** + * Sets the modelRotation2. + * @param modelRotation2 The modelRotation2 to set. + */ + public void setModelRotationY(int modelRotation2) { + this.modelRotationY = modelRotation2; + } + + /** + * Gets the modelOffset1. + * @return The modelOffset1. + */ + public int getModelOffset1() { + return modelOffsetX; + } + + /** + * Sets the modelOffset1. + * @param modelOffset1 The modelOffset1 to set. + */ + public void setModelOffset1(int modelOffset1) { + this.modelOffsetX = modelOffset1; + } + + /** + * Gets the modelOffset2. + * @return The modelOffset2. + */ + public int getModelOffset2() { + return modelOffsetY; + } + + /** + * Sets the modelOffset2. + * @param modelOffset2 The modelOffset2 to set. + */ + public void setModelOffset2(int modelOffset2) { + this.modelOffsetY = modelOffset2; + } + + /** + * Gets the stackable. + * @return The stackable. + */ + public boolean isStackable() { + return stackable || !this.unnoted; + } + + /** + * Sets the stackable. + * @param stackable The stackable to set. + */ + public void setStackable(boolean stackable) { + this.stackable = stackable; + } + + /** + * Gets the value. + * @return The value. + */ + public int getValue() { + return value; + } + + /** + * Gets whether the Item has a value in a custom currency + * @param currency the configuration string of the currency in the item definition + * @return {@code True} if so. + */ + public boolean hasShopCurrencyValue(String currency) { + return getHandlers().getOrDefault(currency, "0") != "0"; + } + + /** + * Gets whether shops value the Item (even if the value is 0) in a currency + * @param currency the ID of the currency + * @return {@code True} if so. + */ + public boolean hasShopCurrencyValue(int currency) { + switch (currency) { + case Items.COINS_995: + return isTradeable(); + case Items.TOKKUL_6529: + return hasShopCurrencyValue(ItemConfigParser.TOKKUL_PRICE); + case Items.ARCHERY_TICKET_1464: + return hasShopCurrencyValue(ItemConfigParser.ARCHERY_TICKET_PRICE); + case Items.CASTLE_WARS_TICKET_4067: + return hasShopCurrencyValue(ItemConfigParser.CASTLE_WARS_TICKET_PRICE); + default: + return false; + } + } + + /** + * @return The value. + */ + public int getMaxValue() { + if ((int) (value * 1.05) <= 0) { + return 1; + } + return (int) (value * 1.05); + } + + /** + * @return The value. + */ + public int getMinValue() { + if ((int) (value * .95) <= 0) { + return 1; + } + return (int) (value * .95); + } + + /** + * Sets the value. + * @param value The value to set. + */ + public void setValue(int value) { + this.value = value; + } + + /** + * Gets the membersOnly. + * @return The membersOnly. + */ + public boolean isMembersOnly() { + return membersOnly; + } + + /** + * Sets the membersOnly. + * @param membersOnly The membersOnly to set. + */ + public void setMembersOnly(boolean membersOnly) { + this.membersOnly = membersOnly; + } + + /** + * Gets the maleWornModelId1. + * @return The maleWornModelId1. + */ + public int getMaleWornModelId1() { + return maleWornModelId1; + } + + /** + * Sets the maleWornModelId1. + * @param maleWornModelId1 The maleWornModelId1 to set. + */ + public void setMaleWornModelId1(int maleWornModelId1) { + this.maleWornModelId1 = maleWornModelId1; + } + + /** + * Gets the femaleWornModelId1. + * @return The femaleWornModelId1. + */ + public int getFemaleWornModelId1() { + return femaleWornModelId1; + } + + /** + * Sets the femaleWornModelId1. + * @param femaleWornModelId1 The femaleWornModelId1 to set. + */ + public void setFemaleWornModelId1(int femaleWornModelId1) { + this.femaleWornModelId1 = femaleWornModelId1; + } + + /** + * Gets the maleWornModelId2. + * @return The maleWornModelId2. + */ + public int getMaleWornModelId2() { + return maleWornModelId2; + } + + /** + * Sets the maleWornModelId2. + * @param maleWornModelId2 The maleWornModelId2 to set. + */ + public void setMaleWornModelId2(int maleWornModelId2) { + this.maleWornModelId2 = maleWornModelId2; + } + + /** + * Gets the femaleWornModelId2. + * @return The femaleWornModelId2. + */ + public int getFemaleWornModelId2() { + return femaleWornModelId2; + } + + /** + * Sets the femaleWornModelId2. + * @param femaleWornModelId2 The femaleWornModelId2 to set. + */ + public void setFemaleWornModelId2(int femaleWornModelId2) { + this.femaleWornModelId2 = femaleWornModelId2; + } + + /** + * Gets the groundOptions. + * @return The groundOptions. + */ + public String[] getGroundOptions() { + return groundActions; + } + + /** + * Sets the groundOptions. + * @param groundOptions The groundOptions to set. + */ + public void setGroundOptions(String[] groundOptions) { + this.groundActions = groundOptions; + } + + /** + * Gets the inventoryOptions. + * @return The inventoryOptions. + */ + public String[] getInventoryOptions() { + return options; + } + + /** + * Sets the inventoryOptions. + * @param inventoryOptions The inventoryOptions to set. + */ + public void setInventoryOptions(String[] inventoryOptions) { + this.options = inventoryOptions; + } + + /** + * Gets the originalModelColors. + * @return The originalModelColors. + */ + public short[] getOriginalModelColors() { + return originalModelColors; + } + + /** + * Sets the originalModelColors. + * @param originalModelColors The originalModelColors to set. + */ + public void setOriginalModelColors(short[] originalModelColors) { + this.originalModelColors = originalModelColors; + } + + /** + * Gets the modifiedModelColors. + * @return The modifiedModelColors. + */ + public short[] getModifiedModelColors() { + return modifiedModelColors; + } + + /** + * Sets the modifiedModelColors. + * @param modifiedModelColors The modifiedModelColors to set. + */ + public void setModifiedModelColors(short[] modifiedModelColors) { + this.modifiedModelColors = modifiedModelColors; + } + + /** + * Gets the textureColour1. + * @return The textureColour1. + */ + public short[] getTextureColour1() { + return textureColour1; + } + + /** + * Sets the textureColour1. + * @param textureColour1 The textureColour1 to set. + */ + public void setTextureColour1(short[] textureColour1) { + this.textureColour1 = textureColour1; + } + + /** + * Gets the textureColour2. + * @return The textureColour2. + */ + public short[] getTextureColour2() { + return textureColour2; + } + + /** + * Sets the textureColour2. + * @param textureColour2 The textureColour2 to set. + */ + public void setTextureColour2(short[] textureColour2) { + this.textureColour2 = textureColour2; + } + + /** + * Gets the unknownArray1. + * @return The unknownArray1. + */ + public byte[] getUnknownArray1() { + return unknownArray1; + } + + /** + * Sets the unknownArray1. + * @param unknownArray1 The unknownArray1 to set. + */ + public void setUnknownArray1(byte[] unknownArray1) { + this.unknownArray1 = unknownArray1; + } + + /** + * Gets the unknownArray2. + * @return The unknownArray2. + */ + public int[] getUnknownArray2() { + return unknownArray2; + } + + /** + * Sets the unknownArray2. + * @param unknownArray2 The unknownArray2 to set. + */ + public void setUnknownArray2(int[] unknownArray2) { + this.unknownArray2 = unknownArray2; + } + + /** + * Gets the unnoted. + * @return The unnoted. + */ + public boolean isUnnoted() { + return unnoted; + } + + /** + * Sets the unnoted. + * @param unnoted The unnoted to set. + */ + public void setUnnoted(boolean unnoted) { + this.unnoted = unnoted; + } + + /** + * Gets the colourEquip1. + * @return The colourEquip1. + */ + public int getColourEquip1() { + return colourEquip1; + } + + /** + * Sets the colourEquip1. + * @param colourEquip1 The colourEquip1 to set. + */ + public void setColourEquip1(int colourEquip1) { + this.colourEquip1 = colourEquip1; + } + + /** + * Gets the colourEquip2. + * @return The colourEquip2. + */ + public int getColourEquip2() { + return colourEquip2; + } + + /** + * Sets the colourEquip2. + * @param colourEquip2 The colourEquip2 to set. + */ + public void setColourEquip2(int colourEquip2) { + this.colourEquip2 = colourEquip2; + } + + /** + * Gets the noteId. + * @return The noteId. + */ + public int getNoteId() { + return noteId; + } + + /** + * Sets the noteId. + * @param noteId The noteId to set. + */ + public void setNoteId(int noteId) { + this.noteId = noteId; + } + + /** + * Gets the noteTemplateId. + * @return The noteTemplateId. + */ + public int getNoteTemplateId() { + return noteTemplateId; + } + + /** + * Sets the noteTemplateId. + * @param noteTemplateId The noteTemplateId to set. + */ + public void setNoteTemplateId(int noteTemplateId) { + this.noteTemplateId = noteTemplateId; + } + + /** + * Gets the stackIds. + * @return The stackIds. + */ + public int[] getStackIds() { + return stackIds; + } + + /** + * Sets the stackIds. + * @param stackIds The stackIds to set. + */ + public void setStackIds(int[] stackIds) { + this.stackIds = stackIds; + } + + /** + * Gets the stackAmounts. + * @return The stackAmounts. + */ + public int[] getStackAmounts() { + return stackAmounts; + } + + /** + * Sets the stackAmounts. + * @param stackAmounts The stackAmounts to set. + */ + public void setStackAmounts(int[] stackAmounts) { + this.stackAmounts = stackAmounts; + } + + /** + * Gets the teamId. + * @return The teamId. + */ + public int getTeamId() { + return teamId; + } + + /** + * Sets the teamId. + * @param teamId The teamId to set. + */ + public void setTeamId(int teamId) { + this.teamId = teamId; + } + + /** + * Gets the lendId. + * @return The lendId. + */ + public int getLendId() { + return lendId; + } + + /** + * Sets the lendId. + * @param lendId The lendId to set. + */ + public void setLendId(int lendId) { + this.lendId = lendId; + } + + /** + * Gets the lendTemplateId. + * @return The lendTemplateId. + */ + public int getLendTemplateId() { + return lendTemplateId; + } + + /** + * Sets the lendTemplateId. + * @param lendTemplateId The lendTemplateId to set. + */ + public void setLendTemplateId(int lendTemplateId) { + this.lendTemplateId = lendTemplateId; + } + + /** + * Gets the recolourId. + * @return The recolourId. + */ + public int getRecolourId() { + return recolourId; + } + + /** + * Sets the recolourId. + * @param recolourId The recolourId to set. + */ + public void setRecolourId(int recolourId) { + this.recolourId = recolourId; + } + + /** + * Gets the recolourTemplateId. + * @return The recolourTemplateId. + */ + public int getRecolourTemplateId() { + return recolourTemplateId; + } + + /** + * Sets the recolourTemplateId. + * @param recolourTemplateId The recolourTemplateId to set. + */ + public void setRecolourTemplateId(int recolourTemplateId) { + this.recolourTemplateId = recolourTemplateId; + } + + /** + * Gets the equipId. + * @return The equipId. + */ + public int getEquipId() { + return equipId; + } + + /** + * Sets the equipId. + * @param equipId The equipId to set. + */ + public void setEquipId(int equipId) { + this.equipId = equipId; + } + + /** + * Gets the clientScriptData. + * @return The clientScriptData. + */ + public HashMap getClientScriptData() { + return clientScriptData; + } + + /** + * Sets the clientScriptData. + * @param clientScriptData The clientScriptData to set. + */ + public void setClientScriptData(HashMap clientScriptData) { + this.clientScriptData = clientScriptData; + } + + /** + * Gets the alchemy value. + * @param highAlchemy If the value is for high alchemy (instead of low). + * @return The alchemy value. + */ + public int getAlchemyValue(boolean highAlchemy) { + if (!unnoted && noteId > -1) { + return forId(noteId).getAlchemyValue(highAlchemy); + } + if (highAlchemy) { + return getConfiguration(ItemConfigParser.HIGH_ALCHEMY, (int)Math.rint(value * 0.6)); + } + return getConfiguration(ItemConfigParser.LOW_ALCHEMY, (int)Math.rint(value * 0.4)); + } + + /** + * Checks if the item is alchemizable. + * @return {@code True} if so. + */ + public boolean isAlchemizable() { + if (!getConfiguration(ItemConfigParser.ALCHEMIZABLE, false)) { + return false; + } + return true; + } + + /** + * Checks if the item is tradeable. + * @return {@code True} if so. + */ + public boolean isTradeable() { + if (hasDestroyAction() && !getName().contains("impling jar")) { + return false; + } + if (!getConfiguration(ItemConfigParser.TRADEABLE, false)) { + return false; + } + return true; + } + + /** + * If the item has the specified item. + * @param optionName The reward. + * @return If the item has the specified reward {@code true}. + */ + public boolean hasAction(String optionName) { + if (options == null) { + return false; + } + for (String action : options) { + if (action == null) { + continue; + } + if (action.equalsIgnoreCase(optionName)) { + return true; + } + } + return false; + } + + /** + * If the item has the destroy reward. + * @return If the item has the destroy reward {@code true}. + */ + public boolean hasDestroyAction() { + return hasAction("destroy") || hasAction("dissolve"); + } + + /** + * If the item has the wear reward. + * @return If the item has the wear reward {@code true}. + */ + public boolean hasWearAction() { + if (options == null) { + return false; + } + for (String action : options) { + if (action == null) { + continue; + } + if (action.equalsIgnoreCase("wield") || action.equalsIgnoreCase("wear") || action.equalsIgnoreCase("equip")) { + return true; + } + } + return false; + } + + /** + * If the item has a special bar. + * @return If the item has a special bar {@code true}. + */ + public boolean hasSpecialBar() { + if (clientScriptData == null) { + return false; + } + Object specialBar = clientScriptData.get(686); + if (specialBar != null && specialBar instanceof Integer) { + return (Integer) specialBar == 1; + } + return false; + } + + /** + * Get the quest id for the item. + * @return The quest id. + */ + public int getQuestId() { + if (clientScriptData == null) { + return -1; + } + Object questId = clientScriptData.get(861); + if (questId != null && questId instanceof Integer) { + return (Integer) questId; + } + return -1; + } + + /** + * Get the archive id. + * @return The archive id. + */ + public int getArchiveId() { + return id >>> 8; + } + + /** + * Get the file id. + * @return The file id. + */ + public int getFileId() { + return 0xff & id; + } + + /** + * Gets the definitions. + * @return The definitions. + */ + public static Map getDefinitions() { + return DEFINITIONS; + } + + /** + * Gets the option handler for the given option name. + * @param nodeId + * @param name The name. + * @return The option handler, or {@code null} if there was no default + * option handler. + */ + public static OptionHandler getOptionHandler(int nodeId, String name) { + ItemDefinition def = forId(nodeId); + if (def == null) { + if (nodeId == 22937) + log(ItemDefinition.class, Log.ERR, "[ItemDefinition] No definition for item id " + nodeId + "!"); + return null; + } + OptionHandler handler = def.getConfiguration("option:" + name); + if (handler != null) { + return handler; + } + return OPTION_HANDLERS.get(name); + } + + /** + * The bonus names. + */ + private static final String[] BONUS_NAMES = { "Stab: ", "Slash: ", "Crush: ", "Magic: ", "Ranged: ", "Stab: ", "Slash: ", "Crush: ", "Magic: ", "Ranged: ", "Summoning: ", "Strength: ", "Prayer: " }; + + /** + * Updates the equipment stats interface. + * @param player The player to update for. + */ + public static void statsUpdate(Player player) { + if (!player.getAttribute("equip_stats_open", false)) { + return; + } + int index = 0; + int[] bonuses = player.getProperties().getBonuses(); + for (int i = 36; i < 50; i++) { + if (i == 47) { + continue; + } + int bonus = bonuses[index]; + String bonusValue = bonus > -1 ? ("+" + bonus) : Integer.toString(bonus); + player.getPacketDispatch().sendString(BONUS_NAMES[index++] + bonusValue, 667, i); + } + player.getPacketDispatch().sendString("Attack bonus", 667, 34); + } + + /** + * Checks if it has a plugin. + * @return {@code True} if so. + */ + public boolean hasPlugin() { + return getItemPlugin() != null; + } + + /** + * Gets the item plugin. + * @return the plugin. + */ + public ItemPlugin getItemPlugin() { + return getConfiguration("wrapper", null); + } + + /** + * Sets the item plugin. + * @param plugin the plugin. + */ + public void setItemPlugin(ItemPlugin plugin) { + getHandlers().put("wrapper", plugin); + } + + /** + * Sets the default option handler for an option. + * @param name The option name. + * @param handler The default option handler. + * @return {@code True} if there was a previous default handler mapped. + */ + public static boolean setOptionHandler(String name, OptionHandler handler) { + return OPTION_HANDLERS.put(name, handler) != null; + } + + /** + * @return the optionHandlers + */ + public static Map getOptionHandlers() { + return OPTION_HANDLERS; + } + + /** + * @return the itemRequirements. + */ + public HashMap getItemRequirements() { + return itemRequirements; + } + + /** + * @param itemRequirements the itemRequirements to set. + */ + public void setItemRequirements(HashMap itemRequirements) { + this.itemRequirements = itemRequirements; + } + + /** + * Gets the itemType. + * @return The itemType. + */ + public int getItemType() { + return itemType; + } + + /** + * Sets the itemType. + * @param itemType The itemType to set. + */ + public void setItemType(int itemType) { + this.itemType = itemType; + } + + /** + * Gets the femaleWornModelId3 value. + * @return The femaleWornModelId3. + */ + public int getFemaleWornModelId3() { + return femaleWornModelId3; + } + /** + * Sets the femaleWornModelId3 value. + * @param femaleWornModelId3 The femaleWornModelId3 to set. + */ + public void setFemaleWornModelId3(int femaleWornModelId3) { + this.femaleWornModelId3 = femaleWornModelId3; + } + /** + * Gets the femaleWornModelId4 value. + * @return The femaleWornModelId4. + */ + public int getFemaleWornModelId4() { + return femaleWornModelId4; + } + /** + * Sets the femaleWornModelId4 value. + * @param femaleWornModelId4 The femaleWornModelId4 to set. + */ + public void setFemaleWornModelId4(int femaleWornModelId4) { + this.femaleWornModelId4 = femaleWornModelId4; + } + /** + * Gets the maleWornModelId3 value. + * @return The maleWornModelId3. + */ + public int getMaleWornModelId3() { + return maleWornModelId3; + } + /** + * Sets the maleWornModelId3 value. + * @param maleWornModelId3 The maleWornModelId3 to set. + */ + public void setMaleWornModelId3(int maleWornModelId3) { + this.maleWornModelId3 = maleWornModelId3; + } + /** + * Gets the maleWornModelId4 value. + * @return The maleWornModelId4. + */ + public int getMaleWornModelId4() { + return maleWornModelId4; + } + /** + * Sets the maleWornModelId4 value. + * @param maleWornModelId4 The maleWornModelId4 to set. + */ + public void setMaleWornModelId4(int maleWornModelId4) { + this.maleWornModelId4 = maleWornModelId4; + } + + /** + * Gets the examine. + * @return The examine. + */ + @Override + public String getExamine() { + examine = super.getExamine(); + if (!isUnnoted()) { + examine = "Swap this note at any bank for the equivalent item."; + } + return examine; + } +} diff --git a/Server/src/main/core/cache/def/impl/LinkedScripts.java b/Server/src/main/core/cache/def/impl/LinkedScripts.java new file mode 100644 index 0000000..933d9e9 --- /dev/null +++ b/Server/src/main/core/cache/def/impl/LinkedScripts.java @@ -0,0 +1,24 @@ +package core.cache.def.impl; + +public class LinkedScripts { + public ScriptArgs unknown; + public ScriptArgs onMouseOver; + public ScriptArgs onMouseLeave; + public ScriptArgs onUseWith; + public ScriptArgs onUse; + public ScriptArgs onVarpTransmit; + public ScriptArgs onInvTransmit; + public ScriptArgs onStatTransmit; + public ScriptArgs onTimer; + public ScriptArgs onOptionClick; + public ScriptArgs onMouseRepeat; + public ScriptArgs onClickRepeat; + public ScriptArgs onDrag; + public ScriptArgs onRelease; + public ScriptArgs onHold; + public ScriptArgs onDragStart; + public ScriptArgs onDragRelease; + public ScriptArgs onScroll; + public ScriptArgs onVarcTransmit; + public ScriptArgs onVarcstrTransmit; +} diff --git a/Server/src/main/core/cache/def/impl/NPCDefinition.java b/Server/src/main/core/cache/def/impl/NPCDefinition.java new file mode 100644 index 0000000..dbf3bdf --- /dev/null +++ b/Server/src/main/core/cache/def/impl/NPCDefinition.java @@ -0,0 +1,1119 @@ +package core.cache.def.impl; + +import core.cache.Cache; +import core.cache.def.Definition; +import core.cache.misc.buffer.ByteBufferUtils; +import core.game.interaction.OptionHandler; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.npc.drop.NPCDropTables; +import core.game.node.entity.player.Player; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.tools.StringUtils; +import core.game.system.config.NPCConfigParser; +import core.game.world.GameWorld; + +import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.Map; + +import static core.api.ContentAPIKt.*; + +/** + * Debug NPC Opcodes Line 483, Uncomment + */ + +/** + * Represents an NPC's definitions. + * @author Emperor + */ +public final class NPCDefinition extends Definition { + + /** + * The definitions. + */ + private static final Map DEFINITIONS = new HashMap<>(); + + /** + * The default option handlers. + */ + private static final Map OPTION_HANDLERS = new HashMap<>(); + + /** + * The size. + */ + public int size = 1; + + /** + * The combat level. + */ + private int combatLevel; + + /** + * The head icons. + */ + public int headIcons; + + /** + * If the NPC can be seen on the minimap. + */ + public boolean isVisibleOnMap; + + +/* public String examine;*/ + + /** + * The drop tables. + */ + private NPCDropTables dropTables = new NPCDropTables(this); + + /** + * Unidentified variables. + */ + public int anInt833; + public int anInt836; + public int anInt837; + public boolean aBoolean841; + public int anInt842; + public int configFileId; + public int[] childNPCIds; + public int anInt846; + public int anInt850; + public byte aByte851; + public boolean aBoolean852; + public int anInt853; + public byte aByte854; + public boolean aBoolean856; + public boolean aBoolean857; + public short[] aShortArray859; + public byte[] aByteArray861; + public short aShort862; + public boolean aBoolean863; + public int anInt864; + public short[] aShortArray866; + public int[] anIntArray868; + public int anInt869; + public int anInt870; + public int anInt871; + public int anInt872; + public int anInt874; + public int anInt875; + public int anInt876; + public int anInt879; + public short[] aShortArray880; + public int anInt884; + public int configId; + public int anInt889; + public int[] anIntArray892; + public short aShort894; + public short[] aShortArray896; + public int anInt897; + public int anInt899; + public int anInt901; + public int standAnimation; + public int walkAnimation; + public int renderAnimationId; + + /** + * The minimum combat distance (0 uses default distances). + */ + private int combatDistance; + + /** + * The combat graphics. + */ + private Graphics[] combatGraphics = new Graphics[3]; + + /** + * The turning animation. + */ + private int turnAnimation; + + /** + * The turn 180� animation. + */ + private int turn180Animation; + + /** + * The turn clock-wise animation. + */ + private int turnCWAnimation; + + /** + * The turn counter clock-wise animation. + */ + private int turnCCWAnimation; + + /** + * Constructs a new {@code NPCDefinition} {@code Object}. + * @param id The NPC id. + */ + public NPCDefinition(int id) { + this.id = id; + anInt842 = -1; + configFileId = -1; + anInt837 = -1; + anInt846 = -1; + anInt853 = 32; + standAnimation = -1; + walkAnimation = -1; + combatLevel = 0; + anInt836 = -1; + name = "null"; + anInt869 = 0; + anInt850 = 255; + anInt871 = -1; + aBoolean852 = true; + aShort862 = (short) 0; + anInt876 = -1; + aByte851 = (byte) -96; + anInt875 = 0; + anInt872 = -1; + aBoolean857 = true; + anInt870 = -1; + anInt874 = -1; + anInt833 = -1; + anInt864 = 128; + headIcons = -1; + aBoolean856 = false; + configId = -1; + aByte854 = (byte) -16; + aBoolean863 = false; + isVisibleOnMap = true; + anInt889 = -1; + anInt884 = -1; + aBoolean841 = true; + anInt879 = -1; + anInt899 = 128; + aShort894 = (short) 0; + options = new String[5]; + anInt897 = 0; + anInt901 = -1; + anIntArray868 = new int[0]; + } + + /** + * Gets the NPC definition for this id. + * @param id The NPC id. + * @return The NPC definition object. + */ + public static NPCDefinition forId(int id) { + NPCDefinition def = DEFINITIONS.get(id); + if (def == null) { + def = new NPCDefinition(id); + byte[] data = Cache.getIndexes()[18].getFileData(id >>> 7, id & 0x7f); + if (data == null) { + if (id != -1) { + + } + } else { + def.parse(ByteBuffer.wrap(data)); + } + DEFINITIONS.put(id, def); + } + return def; + } + + public static void main(String... args) throws Throwable { + GameWorld.prompt(false); + + // for (int i = 0; i < 11000; i++) { + // ItemDefinition def = ItemDefinition.forId(i); + // if (def.getMaleWornModelId1() >= 1250 && def.getMaleWornModelId1() <= + // 1550) { + + // def.getMaleWornModelId1()); + // } + // } + } + + /** + * Gets the child object definitions. + * @param player The player to get it for. + * @return The object definition. + */ + public NPCDefinition getChildNPC(Player player) { + if (childNPCIds == null || childNPCIds.length < 1) { + return this; + } + int configValue = -1; + if (player != null) { + if (configFileId != -1) { + configValue = VarbitDefinition.forNPCID(configFileId).getValue(player); + } else if (configId != -1) { + configValue = getVarp(player, configId); + } + } else { + configValue = 0; + } + if (configValue < 0 || configValue >= childNPCIds.length - 1 || childNPCIds[configValue] == -1) { + int objectId = childNPCIds[childNPCIds.length - 1]; + if (objectId != -1) { + return forId(objectId); + } + return this; + } + return forId(childNPCIds[configValue]); + } + + /** + * Parses the data. + * @param buffer The data input stream. + */ + private void parse(ByteBuffer buffer) { + while (true) { + int opcode = buffer.get() & 0xFF; + if (opcode == 0) { + break; + } + parseOpcode(buffer, opcode); + } + } + + /** + * Parses an opcode. + * @param buffer The data input stream. + * @param opcode The opcode to parse. + */ + private void parseOpcode(ByteBuffer buffer, int opcode) { + switch (opcode) { + case 1: + int length = buffer.get() & 0xFF; + anIntArray868 = new int[length]; + for (int i_66_ = 0; i_66_ < length; i_66_++) { + anIntArray868[i_66_] = buffer.getShort() & 0xFFFF; + if ((anIntArray868[i_66_] ^ 0xffffffff) == -65536) + anIntArray868[i_66_] = -1; + } + break; + case 2: + name = ByteBufferUtils.getString(buffer); + break; + case 12: + size = buffer.get() & 0xFF; + break; + case 13: + standAnimation = buffer.getShort(); + break; + case 14: + walkAnimation = buffer.getShort(); + break; + case 15: + turnAnimation = buffer.getShort(); + break; + case 16: + buffer.getShort(); // Another turn animation + break; + case 17: + walkAnimation = buffer.getShort(); + turn180Animation = buffer.getShort(); + turnCWAnimation = buffer.getShort(); + turnCCWAnimation = buffer.getShort(); + break; + case 30: + case 31: + case 32: + case 33: + case 34: + options[opcode - 30] = ByteBufferUtils.getString(buffer); + break; + case 40: + length = buffer.get() & 0xFF; + aShortArray859 = new short[length]; + aShortArray896 = new short[length]; + for (int i_65_ = 0; (length ^ 0xffffffff) < (i_65_ ^ 0xffffffff); i_65_++) { + aShortArray896[i_65_] = (short) (buffer.getShort() & 0xFFFF); + aShortArray859[i_65_] = (short) (buffer.getShort() & 0xFFFF); + } + break; + case 41: + length = buffer.get() & 0xFF; + aShortArray880 = new short[length]; + aShortArray866 = new short[length]; + for (int i_54_ = 0; (i_54_ ^ 0xffffffff) > (length ^ 0xffffffff); i_54_++) { + aShortArray880[i_54_] = (short) (buffer.getShort() & 0xFFFF); + aShortArray866[i_54_] = (short) (buffer.getShort() & 0xFFFF); + } + break; + case 42: + length = buffer.get() & 0xFF; + aByteArray861 = new byte[length]; + for (int i_55_ = 0; length > i_55_; i_55_++) { + aByteArray861[i_55_] = (byte) buffer.get(); + } + break; + case 60: + length = buffer.get() & 0xFF; + anIntArray892 = new int[length]; + for (int i_64_ = 0; (i_64_ ^ 0xffffffff) > (length ^ 0xffffffff); i_64_++) { + anIntArray892[i_64_] = buffer.getShort() & 0xFFFF; + } + break; + case 93: + isVisibleOnMap = false; + break; + case 95: + setCombatLevel(buffer.getShort() & 0xFFFF); + break; + case 97: + anInt864 = buffer.getShort() & 0xFFFF; + break; + case 98: + anInt899 = buffer.getShort() & 0xFFFF; + break; + case 99: + aBoolean863 = true; + break; + case 100: + anInt869 = buffer.get(); + break; + case 101: + anInt897 = buffer.get() * 5; + break; + case 102: + headIcons = buffer.getShort() & 0xFFFF; + break; + case 103: + anInt853 = buffer.getShort() & 0xFFFF; + break; + case 106: + case 118: + configFileId = buffer.getShort() & 0xFFFF; + if (configFileId == 65535) { + configFileId = -1; + } + configId = buffer.getShort() & 0xFFFF; + if (configId == 65535) { + configId = -1; + } + int defaultValue = -1; + if ((opcode ^ 0xffffffff) == -119) { + defaultValue = buffer.getShort() & 0xFFFF; + if (defaultValue == 65535) { + defaultValue = -1; + } + } + length = buffer.get() & 0xFF; + childNPCIds = new int[2 + length]; + for (int i = 0; length >= i; i++) { + childNPCIds[i] = buffer.getShort() & 0xFFFF; + if (childNPCIds[i] == 65535) { + childNPCIds[i] = -1; + } + } + childNPCIds[length + 1] = defaultValue; + break; + case 107: + aBoolean841 = false; + break; + case 109: + aBoolean852 = false; + break; + case 111: + aBoolean857 = false; + break; + case 113: + aShort862 = (short) (buffer.getShort() & 0xFFFF); + aShort894 = (short) (buffer.getShort() & 0xFFFF); + break; + case 114: + aByte851 = (byte) (buffer.get()); + aByte854 = (byte) (buffer.get()); + break; + case 115: + buffer.get();// & 0xFF; + buffer.get();// & 0xFF; + break; + case 119: + buffer.get(); + break; + case 121: + length = buffer.get() & 0xFF; + for (int i = 0; i < length; i++) { + buffer.get(); + buffer.get(); + buffer.get(); + buffer.get(); + } + break; + case 122: + buffer.getShort(); + break; + case 123: + buffer.getShort(); + break; + case 125: + buffer.get(); + break; + case 126: + buffer.getShort(); + case 127: + renderAnimationId = buffer.getShort(); + break; + case 128: + buffer.get(); + break; + case 134: + buffer.getShort(); + buffer.getShort(); + buffer.getShort(); + buffer.getShort(); + buffer.get(); + break; + case 135: + buffer.get(); + buffer.getShort(); + break; + case 136: + buffer.get(); + buffer.getShort(); + break; + case 137: + buffer.getShort(); + break; + case 249: + length = buffer.get() & 0xFF; + for (int i = 0; i < length; i++) { + boolean string = buffer.get() == 1; + ByteBufferUtils.getMedium(buffer); // script id + if (!string) { + buffer.getInt(); // Value + } else { + ByteBufferUtils.getString(buffer); // value + } + } + break; + default: + //SystemLogger.logErr("Unhandled NPC definition opcode: " + opcode); + } + } + + /** + * Checks if this NPC has an attack option. + * @return {@code True} if so. + */ + public boolean hasAttackOption() { + for (String option : options) { + if (option != null && option.equalsIgnoreCase("attack")) { + return true; + } + } + return false; + } + + /** + * Gets the option handler for the given option name. + * @param nodeId The node id. + * @param name The name. + * @return The option handler, or {@code null} if there was no default + * option handler. + */ + public static OptionHandler getOptionHandler(int nodeId, String name) { + NPCDefinition def = forId(nodeId); + OptionHandler handler = def.getConfiguration("option:" + name); + if (handler != null) { + return handler; + } + return OPTION_HANDLERS.get(name); + } + + /** + * Checks if an npc has an reward. + * @param optionName The option name. + * @return {@code True} if so. + */ + public boolean hasAction(String optionName) { + if (options == null) { + return false; + } + for (String action : options) { + if (action == null) { + continue; + } + if (action.equalsIgnoreCase(optionName)) { + return true; + } + } + return false; + } + + /** + * Sets the default option handler for an option. + * @param name The option name. + * @param handler The default option handler. + * @return {@code True} if there was a previous default handler mapped. + */ + public static boolean setOptionHandler(String name, OptionHandler handler) { + return OPTION_HANDLERS.put(name, handler) != null; + } + + /** + * Gets the option handlers. + * @return The option handlers. + */ + public static Map getOptionHandlers() { + return OPTION_HANDLERS; + } + + /** + * Gets the definitions mapping. + * @return The mapping. + */ + public static final Map getDefinitions() { + return DEFINITIONS; + } + + /** + * Method returns the value for 'examine' + * @return the examine. + */ + public final String getExamine() { + String string = getConfiguration(NPCConfigParser.EXAMINE, examine); + if (string != null) { + return string; + } + if (name.length() <= 1) { + return string; + } + return "It's a" + (StringUtils.isPlusN(name) ? "n " : " ") + name + "."; + } + + /** + * Method sets the value for 'examine' + * @param examine the examine to set. + */ + public final void setExamine(String examine) { + this.examine = examine; + } + + /** + * Initializes the combat graphics. + * @param config The configurations. + */ + public void initCombatGraphics(Map config) { + if (config.containsKey(NPCConfigParser.START_GRAPHIC)) { + combatGraphics[0] = new Graphics((Integer) config.get(NPCConfigParser.START_GRAPHIC), getConfiguration(NPCConfigParser.START_HEIGHT, 0)); + } + if (config.containsKey(NPCConfigParser.PROJECTILE)) { + combatGraphics[1] = new Graphics((Integer) config.get(NPCConfigParser.PROJECTILE), getConfiguration(NPCConfigParser.PROJECTILE_HEIGHT, 42)); + } + if (config.containsKey(NPCConfigParser.END_GRAPHIC)) { + combatGraphics[2] = new Graphics((Integer) config.get(NPCConfigParser.END_GRAPHIC), getConfiguration(NPCConfigParser.END_HEIGHT, 96)); + } + } + + /** + * Gets the combat animation. + * @param index The index. + * @return The Animation. + */ + public Animation getCombatAnimation(int index) { + String name = ""; + switch (index) { + case 0: + name = NPCConfigParser.MELEE_ANIMATION; + break; + case 1: + name = NPCConfigParser.MAGIC_ANIMATION; + break; + case 2: + name = NPCConfigParser.RANGE_ANIMATION; + break; + case 3: + name = NPCConfigParser.DEFENCE_ANIMATION; + break; + case 4: + name = NPCConfigParser.DEATH_ANIMATION; + break; + default: + break; + } + return getConfiguration(name, null); + } + + /** + * Gets the size. + * @return The size. + */ + public int getSize() { + return size; + } + + /** + * Gets the headIcons. + * @return The headIcons. + */ + public int getHeadIcons() { + return headIcons; + } + + /** + * Gets the isVisibleOnMap. + * @return The isVisibleOnMap. + */ + public boolean isVisibleOnMap() { + return isVisibleOnMap; + } + + /** + * Gets the anInt833. + * @return The anInt833. + */ + public int getAnInt833() { + return anInt833; + } + + /** + * Gets the anInt836. + * @return The anInt836. + */ + public int getAnInt836() { + return anInt836; + } + + /** + * Gets the anInt837. + * @return The anInt837. + */ + public int getAnInt837() { + return anInt837; + } + + /** + * Gets the aBoolean841. + * @return The aBoolean841. + */ + public boolean isaBoolean841() { + return aBoolean841; + } + + /** + * Gets the anInt842. + * @return The anInt842. + */ + public int getAnInt842() { + return anInt842; + } + + /** + * Gets the configFileId. + * @return The configFileId. + */ + public int getConfigFileId() { + return configFileId; + } + + /** + * Gets the childNPCIds. + * @return The childNPCIds. + */ + public int[] getChildNPCIds() { + return childNPCIds; + } + + /** + * Gets the anInt846. + * @return The anInt846. + */ + public int getAnInt846() { + return anInt846; + } + + /** + * Gets the anInt850. + * @return The anInt850. + */ + public int getAnInt850() { + return anInt850; + } + + /** + * Gets the aByte851. + * @return The aByte851. + */ + public byte getaByte851() { + return aByte851; + } + + /** + * Gets the aBoolean852. + * @return The aBoolean852. + */ + public boolean isaBoolean852() { + return aBoolean852; + } + + /** + * Gets the anInt853. + * @return The anInt853. + */ + public int getAnInt853() { + return anInt853; + } + + /** + * Gets the aByte854. + * @return The aByte854. + */ + public byte getaByte854() { + return aByte854; + } + + /** + * Gets the aBoolean856. + * @return The aBoolean856. + */ + public boolean isaBoolean856() { + return aBoolean856; + } + + /** + * Gets the aBoolean857. + * @return The aBoolean857. + */ + public boolean isaBoolean857() { + return aBoolean857; + } + + /** + * Gets the aShortArray859. + * @return The aShortArray859. + */ + public short[] getaShortArray859() { + return aShortArray859; + } + + /** + * Gets the aByteArray861. + * @return The aByteArray861. + */ + public byte[] getaByteArray861() { + return aByteArray861; + } + + /** + * Gets the aShort862. + * @return The aShort862. + */ + public short getaShort862() { + return aShort862; + } + + /** + * Gets the aBoolean863. + * @return The aBoolean863. + */ + public boolean isaBoolean863() { + return aBoolean863; + } + + /** + * Gets the anInt864. + * @return The anInt864. + */ + public int getAnInt864() { + return anInt864; + } + + /** + * Gets the aShortArray866. + * @return The aShortArray866. + */ + public short[] getaShortArray866() { + return aShortArray866; + } + + /** + * Gets the anIntArray868. + * @return The anIntArray868. + */ + public int[] getAnIntArray868() { + return anIntArray868; + } + + /** + * Gets the anInt869. + * @return The anInt869. + */ + public int getAnInt869() { + return anInt869; + } + + /** + * Gets the anInt870. + * @return The anInt870. + */ + public int getAnInt870() { + return anInt870; + } + + /** + * Gets the anInt871. + * @return The anInt871. + */ + public int getAnInt871() { + return anInt871; + } + + /** + * Gets the anInt872. + * @return The anInt872. + */ + public int getAnInt872() { + return anInt872; + } + + /** + * Gets the anInt874. + * @return The anInt874. + */ + public int getAnInt874() { + return anInt874; + } + + /** + * Gets the anInt875. + * @return The anInt875. + */ + public int getAnInt875() { + return anInt875; + } + + /** + * Gets the anInt876. + * @return The anInt876. + */ + public int getAnInt876() { + return anInt876; + } + + /** + * Gets the anInt879. + * @return The anInt879. + */ + public int getAnInt879() { + return anInt879; + } + + /** + * Gets the aShortArray880. + * @return The aShortArray880. + */ + public short[] getaShortArray880() { + return aShortArray880; + } + + /** + * Gets the anInt884. + * @return The anInt884. + */ + public int getAnInt884() { + return anInt884; + } + + /** + * Gets the configId. + * @return The configId. + */ + public int getConfigId() { + if(configFileId != -1) { + return VarbitDefinition.forNPCID(configFileId).getVarpId(); + } else return configFileId; + } + + public int getVarbitOffset() { + if(configFileId != -1){ + return VarbitDefinition.forNPCID(configFileId).getStartBit(); + } + return -1; + } + + public int getVarbitSize() { + if(configFileId != -1){ + return VarbitDefinition.forNPCID(configFileId).getEndBit() - VarbitDefinition.forNPCID(configFileId).getStartBit(); + } + return -1; + } + + /** + * Gets the anInt889. + * @return The anInt889. + */ + public int getAnInt889() { + return anInt889; + } + + /** + * Gets the anIntArray892. + * @return The anIntArray892. + */ + public int[] getAnIntArray892() { + return anIntArray892; + } + + /** + * Gets the aShort894. + * @return The aShort894. + */ + public short getaShort894() { + return aShort894; + } + + /** + * Gets the aShortArray896. + * @return The aShortArray896. + */ + public short[] getaShortArray896() { + return aShortArray896; + } + + /** + * Gets the anInt897. + * @return The anInt897. + */ + public int getAnInt897() { + return anInt897; + } + + /** + * Gets the anInt899. + * @return The anInt899. + */ + public int getAnInt899() { + return anInt899; + } + + /** + * Gets the anInt901. + * @return The anInt901. + */ + public int getAnInt901() { + return anInt901; + } + + /** + * Gets the standAnimation. + * @return The standAnimation. + */ + public int getStandAnimation() { + return standAnimation; + } + + /** + * Gets the walkAnimation. + * @return The walkAnimation. + */ + public int getWalkAnimation() { + return walkAnimation; + } + + /** + * Gets the turnAnimation. + * @return The turnAnimation. + */ + public int getTurnAnimation() { + return turnAnimation; + } + + /** + * Gets the turn180Animation. + * @return The turn180Animation. + */ + public int getTurn180Animation() { + return turn180Animation; + } + + /** + * Gets the turnCWAnimation. + * @return The turnCWAnimation. + */ + public int getTurnCWAnimation() { + return turnCWAnimation; + } + + /** + * Gets the turnCCWAnimation. + * @return The turnCCWAnimation. + */ + public int getTurnCCWAnimation() { + return turnCCWAnimation; + } + + /** + * @return the dropTables. + */ + public NPCDropTables getDropTables() { + return dropTables; + } + + /** + * @param dropTables the dropTables to set. + */ + public void setDropTables(NPCDropTables dropTables) { + this.dropTables = dropTables; + } + + /** + * Gets the combatLevel. + * @return The combatLevel. + */ + public int getCombatLevel() { + return combatLevel; + } + + /** + * Sets the combatLevel. + * @param combatLevel The combatLevel to set. + */ + public void setCombatLevel(int combatLevel) { + this.combatLevel = combatLevel; + } + + /** + * Gets the combatDistance. + * @return The combatDistance. + */ + public int getCombatDistance() { + return combatDistance; + } + + /** + * Sets the combatDistance. + * @param combatDistance The combatDistance to set. + */ + public void setCombatDistance(int combatDistance) { + this.combatDistance = combatDistance; + } + + /** + * Gets the combatGraphics. + * @return The combatGraphics. + */ + public Graphics[] getCombatGraphics() { + return combatGraphics; + } + + /** + * Sets the combatGraphics. + * @param combatGraphics The combatGraphics to set. + */ + public void setCombatGraphics(Graphics[] combatGraphics) { + this.combatGraphics = combatGraphics; + } + + /** + * Gets the renderAnimationId value. + * @return The renderAnimationId. + */ + public int getRenderAnimationId() { + return renderAnimationId; + } + + /** + * Sets the renderAnimationId value. + * @param renderAnimationId The renderAnimationId to set. + */ + public void setRenderAnimationId(int renderAnimationId) { + this.renderAnimationId = renderAnimationId; + } +} diff --git a/Server/src/main/core/cache/def/impl/RenderAnimationDefinition.java b/Server/src/main/core/cache/def/impl/RenderAnimationDefinition.java new file mode 100644 index 0000000..881e404 --- /dev/null +++ b/Server/src/main/core/cache/def/impl/RenderAnimationDefinition.java @@ -0,0 +1,330 @@ +package core.cache.def.impl; + +import core.cache.Cache; +import core.tools.Log; +import core.game.world.GameWorld; + +import java.lang.reflect.Array; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.nio.ByteBuffer; + +import static core.api.ContentAPIKt.log; + +/** + * Holds definitions for render animations. + * @author Jagex + * @author Emperor + * + */ +public class RenderAnimationDefinition { + + public int turn180Animation; + public int anInt951 = -1; + public int anInt952; + public int turnCWAnimation = -1; + public int anInt954; + public int anInt955; + public int anInt956; + public int anInt957; + public int anInt958; + public int[] anIntArray959 = null; + public int anInt960; + public int anInt961 = 0; + public int anInt962; + public int walkAnimationId; + public int anInt964; + public int anInt965; + public int anInt966; + public int[] standAnimationIds; + public int anInt969; + public int[] anIntArray971; + public int standAnimationId; + public int anInt973; + public int anInt974; + public int anInt975; + public int runAnimationId; + public int anInt977; + public boolean aBoolean978; + public int[][] anIntArrayArray979; + public int anInt980; + public int turnCCWAnimation; + public int anInt983; + public int anInt985; + public int anInt986; + public int anInt987; + public int anInt988; + public int anInt989; + public int anInt990; + public int anInt992; + public int anInt993; + public int anInt994; + + /** + * Gets the render animation definitions for the given id. + * @param animId The render animation id. + * @return The render animation definitions. + */ + public static RenderAnimationDefinition forId(int animId) { + if (animId == -1) { + return null; + } + byte[] data = Cache.getIndexes()[2].getFileData(32, animId); + RenderAnimationDefinition defs = new RenderAnimationDefinition(); + if (data != null) { + defs.parse(ByteBuffer.wrap(data)); + } else { + log(RenderAnimationDefinition.class, Log.ERR, "No definitions found for render animation " + animId + ", size=" + Cache.getIndexes()[2].getFilesSize(32) + "!"); + } + return defs; + } + + private void parse(ByteBuffer buffer) { + for (;;) { + int opcode = buffer.get() & 0xFF; + if (opcode == 0) { + break; + } + parseOpcode(buffer, opcode); + } + } + + private void parseOpcode(ByteBuffer buffer, int opcode) { + if (opcode == 54) { + @SuppressWarnings("unused") + int anInt1260 = (buffer.get() & 0xFF) << 6; + @SuppressWarnings("unused") + int anInt1227 = (buffer.get() & 0xFF) << 6; + } else if (opcode == 55) { + int[] anIntArray1246 = new int[12]; + int i_14_ = buffer.get() & 0xFF; + anIntArray1246[i_14_] = buffer.getShort() & 0xFFFF; + } else if (opcode == 56) { + int[][] anIntArrayArray1217 = new int[12][]; + int i_12_ = buffer.get() & 0xFF; + anIntArrayArray1217[i_12_] = new int[3]; + for (int i_13_ = 0; i_13_ < 3; i_13_++) + anIntArrayArray1217[i_12_][i_13_] = buffer.getShort(); + } else if ((opcode ^ 0xffffffff) != -2) { + if ((opcode ^ 0xffffffff) != -3) { + if (opcode != 3) { + if ((opcode ^ 0xffffffff) != -5) { + if (opcode == 5) + anInt977 = buffer.getShort() & 0xFFFF; + else if ((opcode ^ 0xffffffff) != -7) { + if (opcode == 7) + anInt960 = buffer.getShort() & 0xFFFF; + else if ((opcode ^ 0xffffffff) == -9) + anInt985 = buffer.getShort() & 0xFFFF; + else if (opcode == 9) + anInt957 = buffer.getShort() & 0xFFFF; + else if (opcode == 26) { + anInt973 = (short) (4 * buffer + .get() & 0xFF); + anInt975 = (short) (buffer.get() & 0xFF * 4); + } else if ((opcode ^ 0xffffffff) == -28) { + if (anIntArrayArray979 == null) + anIntArrayArray979 = new int[12][]; + int i = buffer.get() & 0xFF; + anIntArrayArray979[i] = new int[6]; + for (int i_1_ = 0; (i_1_ ^ 0xffffffff) > -7; i_1_++) + anIntArrayArray979[i][i_1_] = buffer + .getShort(); + } else if ((opcode ^ 0xffffffff) == -29) { + anIntArray971 = new int[12]; + for (int i = 0; i < 12; i++) { + anIntArray971[i] = buffer + .get() & 0xFF; + if (anIntArray971[i] == 255) + anIntArray971[i] = -1; + } + } else if (opcode != 29) { + if (opcode != 30) { + if ((opcode ^ 0xffffffff) != -32) { + if (opcode != 32) { + if ((opcode ^ 0xffffffff) != -34) { + if (opcode != 34) { + if (opcode != 35) { + if ((opcode ^ 0xffffffff) != -37) { + if ((opcode ^ 0xffffffff) != -38) { + if (opcode != 38) { + if ((opcode ^ 0xffffffff) != -40) { + if ((opcode ^ 0xffffffff) != -41) { + if ((opcode ^ 0xffffffff) == -42) + turnCWAnimation = buffer + .getShort() & 0xFFFF; + else if (opcode != 42) { + if ((opcode ^ 0xffffffff) == -44) + buffer.getShort(); + else if ((opcode ^ 0xffffffff) != -45) { + if ((opcode ^ 0xffffffff) == -46) + anInt964 = buffer + .getShort() & 0xFFFF; + else if ((opcode ^ 0xffffffff) != -47) { + if (opcode == 47) + anInt966 = buffer + .getShort() & 0xFFFF; + else if (opcode == 48) + anInt989 = buffer + .getShort() & 0xFFFF; + else if (opcode != 49) { + if ((opcode ^ 0xffffffff) != -51) { + if (opcode != 51) { + if (opcode == 52) { + int i = buffer + .get() & 0xFF; + anIntArray959 = new int[i]; + standAnimationIds = new int[i]; + for (int i_2_ = 0; i_2_ < i; i_2_++) { + standAnimationIds[i_2_] = buffer + .getShort() & 0xFFFF; + int i_3_ = buffer + .get() & 0xFF; + anIntArray959[i_2_] = i_3_; + anInt994 += i_3_; + } + } else if (opcode == 53) + aBoolean978 = false; + } else + anInt962 = buffer + .getShort() & 0xFFFF; + } else + anInt990 = buffer + .getShort() & 0xFFFF; + } else + anInt952 = buffer + .getShort() & 0xFFFF; + } else + anInt983 = buffer + .getShort() & 0xFFFF; + } else + anInt955 = buffer + .getShort() & 0xFFFF; + } else + turnCCWAnimation = buffer + .getShort() & 0xFFFF; + } else + turn180Animation = buffer + .getShort() & 0xFFFF; + } else + anInt954 = buffer + .getShort() & 0xFFFF; + } else + anInt958 = (buffer + .getShort() & 0xFFFF); + } else + anInt951 = (buffer + .get() & 0xFF); + } else + anInt965 = (buffer + .getShort()); + } else + anInt969 = (buffer + .getShort() & 0xFFFF); + } else + anInt993 = buffer + .get() & 0xFF; + } else + anInt956 = (buffer.getShort()); + } else + anInt961 = buffer + .getShort() & 0xFFFF; + } else + anInt988 = buffer.get() & 0xFF; + } else + anInt980 = buffer.getShort() & 0xFFFF; + } else + anInt992 = buffer.get() & 0xFF; + } else + runAnimationId = buffer.getShort() & 0xFFFF; + } else + anInt986 = buffer.getShort() & 0xFFFF; + } else + anInt987 = buffer.getShort() & 0xFFFF; + } else + anInt974 = buffer.getShort() & 0xFFFF; + } else { + standAnimationId = buffer.getShort() & 0xFFFF; + walkAnimationId = buffer.getShort() & 0xFFFF; + if ((standAnimationId ^ 0xffffffff) == -65536) + standAnimationId = -1; + if ((walkAnimationId ^ 0xffffffff) == -65536) + walkAnimationId = -1; + } + } + + public RenderAnimationDefinition() { + anInt957 = -1; + anInt954 = -1; + anInt960 = -1; + anInt958 = -1; + anInt965 = 0; + anInt973 = 0; + turn180Animation = -1; + anInt956 = 0; + standAnimationId = -1; + standAnimationIds = null; + anInt952 = -1; + anInt983 = -1; + anInt985 = -1; + anInt962 = -1; + anInt966 = -1; + anInt977 = -1; + anInt975 = 0; + runAnimationId = -1; + anInt988 = 0; + turnCCWAnimation = -1; + anInt987 = -1; + anInt980 = 0; + anInt964 = -1; + walkAnimationId = -1; + anInt986 = -1; + aBoolean978 = true; + anInt992 = 0; + anInt955 = -1; + anInt989 = -1; + anInt974 = -1; + anInt969 = 0; + anInt994 = 0; + anInt990 = -1; + anInt993 = 0; + } + + public static void main(String...args) throws Throwable { + GameWorld.prompt(false); + RenderAnimationDefinition def = RenderAnimationDefinition.forId(1426); + + for (Field f : def.getClass().getDeclaredFields()) { + if (!Modifier.isStatic(f.getModifiers())) { + if (f.getType().isArray()) { + Object object = f.get(def); + if (object != null) { + int length = Array.getLength(object); + System.out.print(f.getName() + ", ["); + for (int i = 0; i < length; i++) { + System.out.print(Array.get(object, i) + (i < (length - 1) ? ", " : "]")); + } + continue; + } + } + + } + } + for (Field f : def.getClass().getSuperclass().getDeclaredFields()) { + if (!Modifier.isStatic(f.getModifiers())) { + if (f.getType().isArray()) { + Object object = f.get(def); + if (object != null) { + int length = Array.getLength(object); + System.out.print(f.getName() + ", ["); + for (int i = 0; i < length; i++) { + System.out.print(Array.get(object, i) + (i < (length - 1) ? ", " : "]")); + } + continue; + } + } + + } + } + } +} diff --git a/Server/src/main/core/cache/def/impl/SceneryDefinition.java b/Server/src/main/core/cache/def/impl/SceneryDefinition.java new file mode 100644 index 0000000..6172d78 --- /dev/null +++ b/Server/src/main/core/cache/def/impl/SceneryDefinition.java @@ -0,0 +1,1695 @@ +package core.cache.def.impl; + +import core.cache.Cache; +import core.cache.def.Definition; +import core.cache.misc.buffer.ByteBufferUtils; +import core.game.interaction.OptionHandler; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.tools.Log; +import core.game.world.GameWorld; + +import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.Map; + +import static core.api.ContentAPIKt.log; +import static core.api.ContentAPIKt.getVarp; + +/** + * Represents an object's definition. + * @author Emperor + */ +public class SceneryDefinition extends Definition { + + /** + * The item definitions mapping. + */ + private static final Map DEFINITIONS = new HashMap(); + + /** + * The default option handlers. + */ + private static final Map OPTION_HANDLERS = new HashMap<>(); + + /** + * The original model colors. + */ + private short[] originalColors; + + /** + * The children ids. + */ + public int[] childrenIds; + + /** + * The model ids. + */ + private int[] modelIds; + + /** + * The model configuration. + */ + private int[] modelConfiguration; + + /** + * A unknown integer. + */ + static int anInt3832; + + /** + * A unkown integer array. + */ + int[] anIntArray3833 = null; + + /** + * A unknown integer. + */ + private int anInt3834; + + /** + * A unknown integer. + */ + int anInt3835; + + /** + * A unknown integer. + */ + static int anInt3836; + + /** + * A unknown byte. + */ + private byte aByte3837; + + /** + * A unknown integer. + */ + int anInt3838 = -1; + + /** + * A unknown boolean. + */ + boolean aBoolean3839; + + /** + * A unknown integer. + */ + private int anInt3840; + + /** + * A unknown integer. + */ + private int anInt3841; + + /** + * A unknown integer. + */ + static int anInt3842; + + /** + * A unknown integer. + */ + static int anInt3843; + + /** + * A unknown integer. + */ + int anInt3844; + + /** + * A unknown boolean. + */ + boolean aBoolean3845; + + /** + * A unknown integer. + */ + static int anInt3846; + + /** + * A unknown byte. + */ + private byte aByte3847; + + /** + * A unknown byte. + */ + private byte aByte3849; + + /** + * A unknown integer. + */ + int anInt3850; + + /** + * A unknown integer. + */ + int anInt3851; + + /** + * The second boolean. + */ + public boolean secondBool; + + /** + * A unknown boolean. + */ + public boolean aBoolean3853; + + /** + * A unknown integer. + */ + int anInt3855; + + /** + * The first boolean. + */ + public boolean notClipped; + + /** + * A unknown integer. + */ + int anInt3857; + + /** + * A unknown byte array. + */ + private byte[] aByteArray3858; + + /** + * A unknown integer array. + */ + int[] anIntArray3859; + + /** + * A unknown integer. + */ + int anInt3860; + + /** + * The config file id. + */ + int configFileId; + + /** + * The modified colors. + */ + private short[] modifiedColors; + + /** + * A unknown integer. + */ + int anInt3865; + + /** + * A unknown boolean. + */ + boolean aBoolean3866; + + /** + * A unknown boolean. + */ + boolean aBoolean3867; + + /** + * The solid. + */ + public boolean projectileClipped; + + /** + * A unknown integer array. + */ + private int[] anIntArray3869; + + /** + * A unknown boolean. + */ + boolean aBoolean3870; + + /** + * The y-size. + */ + public int sizeY; + + /** + * A unknown boolean. + */ + boolean aBoolean3872; + + /** + * A unknown boolean. + */ + boolean membersOnly; + + /** + * The third integer. + */ + public boolean boolean1; + + /** + * A unknown integer. + */ + private int anInt3875; + + /** + * The add object check. + */ + public int animationId; + + /** + * A unknown integer. + */ + private int anInt3877; + + /** + * A unknown integer. + */ + private int anInt3878; + + /** + * The clipping type. + */ + public int clipType; + + /** + * A unknown integer. + */ + private int anInt3881; + + /** + * A unknown integer. + */ + private int anInt3882; + + /** + * A unknown integer. + */ + private int anInt3883; + + /** + * The loader. + */ + Object loader; + + /** + * A unknown integer. + */ + private int anInt3889; + + /** + * The x-size. + */ + public int sizeX; + + /** + * A unknown boolean. + */ + public boolean aBoolean3891; + + /** + * A unknown integer. + */ + int anInt3892; + + /** + * The second integer. + */ + public int interactable; + + /** + * A unknown boolean. + */ + boolean aBoolean3894; + + /** + * A unknown boolean. + */ + boolean aBoolean3895; + + /** + * A unknown integer. + */ + int anInt3896; + + /** + * The configuration id. + */ + int configId; + + /** + * A unknown byte array. + */ + private byte[] aByteArray3899; + + /** + * A unknown integer. + */ + int anInt3900; + + /** + * A unknown integer. + */ + private int anInt3902; + + /** + * A unknown integer. + */ + int anInt3904; + + /** + * A unknown integer. + */ + int anInt3905; + + /** + * A unknown boolean. + */ + boolean aBoolean3906; + + /** + * A unknown integer array. + */ + int[] anIntArray3908; + + /** + * A unknown byte. + */ + private byte aByte3912; + + /** + * A unknown integer. + */ + int anInt3913; + + /** + * A unknown byte. + */ + private byte aByte3914; + + /** + * A unknown integer. + */ + private int anInt3915; + + /** + * A unknown integer array. + */ + private int[][] anIntArrayArray3916; + + /** + * A unknown integer. + */ + private int anInt3917; + + /** + * A unknown short array. + */ + private short[] aShortArray3919; + + /** + * A unknown short array. + */ + private short[] aShortArray3920; + + /** + * A unknown integer. + */ + int anInt3921; + + /** + * A unknown object. + */ + private Object aClass194_3922; + + /** + * A unknown integer. + */ + boolean aBoolean3923; + + /** + * A unknown integer. + */ + boolean aBoolean3924; + + /** + * The walking flag. + */ + int walkingFlag; + + /** + * If the object has hidden options. + */ + private boolean hasHiddenOptions; + + /** + * The map icon. + */ + private short mapIcon; + + /** + * Construct a new {@code ObjectDefinition} {@code Object}. + */ + public SceneryDefinition() { + anInt3835 = -1; + anInt3860 = -1; + configFileId = -1; + aBoolean3866 = false; + anInt3851 = -1; + anInt3865 = 255; + aBoolean3845 = false; + aBoolean3867 = false; + anInt3850 = 0; + anInt3844 = -1; + anInt3881 = 0; + anInt3857 = -1; + aBoolean3872 = true; + anInt3882 = -1; + anInt3834 = 0; + options = new String[5]; + anInt3875 = 0; + aBoolean3839 = false; + anIntArray3869 = null; + sizeY = 1; + boolean1 = false; + projectileClipped = true; + anInt3883 = 0; + aBoolean3895 = true; + anInt3840 = 0; + aBoolean3870 = false; + anInt3889 = 0; + aBoolean3853 = true; + secondBool = false; + clipType = 2; + anInt3855 = -1; + anInt3878 = 0; + anInt3904 = 0; + sizeX = 1; + animationId = -1; + notClipped = false; + aBoolean3891 = false; + anInt3905 = 0; + name = "null"; + anInt3913 = -1; + aBoolean3906 = false; + membersOnly = false; + aByte3914 = (byte) 0; + anInt3915 = 0; + anInt3900 = 0; + interactable = -1; + aBoolean3894 = false; + aByte3912 = (byte) 0; + anInt3921 = 0; + anInt3902 = 128; + configId = -1; + anInt3877 = 0; + walkingFlag = 0; + anInt3892 = 64; + aBoolean3923 = false; + aBoolean3924 = false; + anInt3841 = 128; + anInt3917 = 128; + mapIcon = -1; + } + + /** + * Main method, used for debugging object definitions. + * @param args The arguments cast on runtime. + * @throws Throwable When an exception occurs. + */ + public static void main(String... args) throws Throwable { + GameWorld.prompt(false); + // if (true) { + // for (int id = 0; id <= 27325; id++) { + // ObjectDefinition def = ObjectDefinition.forId(id); + // if (def.mapIcon > 69) { + + // def.mapIcon); + // } + // } + // return; 2105 + // } + /*ObjectDefinition def = ObjectDefinition.forId(2105); + + for (Field f : def.getClass().getDeclaredFields()) { + if (!Modifier.isStatic(f.getModifiers())) { + if (f.getType().isArray()) { + Object object = f.get(def); + if (object != null) { + int length = Array.getLength(object); + System.out.print(f.getName() + ", ["); + for (int i = 0; i < length; i++) { + System.out.print(Array.get(object, i) + (i < (length - 1) ? ", " : "]")); + } + + continue; + } + } + + } + } + for (Field f : def.getClass().getSuperclass().getDeclaredFields()) { + if (!Modifier.isStatic(f.getModifiers())) { + if (f.getType().isArray()) { + Object object = f.get(def); + if (object != null) { + int length = Array.getLength(object); + System.out.print(f.getName() + ", ["); + for (int i = 0; i < length; i++) { + System.out.print(Array.get(object, i) + (i < (length - 1) ? ", " : "]")); + } + + continue; + } + } + + } + }*/ + } + + /** + * Parses the definitions. + * @throws Throwable the throwable. + */ + public static void parse() throws Throwable { + for (int objectId = 0; objectId < Cache.getObjectDefinitionsSize(); objectId++) { + byte[] data = Cache.getIndexes()[16].getFileData(getContainerId(objectId), objectId & 0xff); + if (data == null) { + SceneryDefinition.getDefinitions().put(objectId, new SceneryDefinition()); + //SystemLogger.logErr("Could not load object definitions for id " + objectId + " - no data!"); + continue; + } + SceneryDefinition def = SceneryDefinition.parseDefinition(objectId, ByteBuffer.wrap(data)); + if (def == null) { + // SystemLogger.logErr("Could not load object definitions for id " + objectId + " - no definitions found!"); + return; + } + SceneryDefinition.getDefinitions().put(objectId, def); + data = null; + } + } + + /** + * Gets an object definition. + * @param objectId The object's id. + * @return The object definition. + */ + public static SceneryDefinition forId(int objectId) { + SceneryDefinition def = DEFINITIONS.get(objectId); + if (def != null) { + return def; + } + DEFINITIONS.put(objectId, def = new SceneryDefinition()); + def.id = objectId; + return def; + } + + + + /** + * Parses an object's definitions. + * @param objectId The object id. + * @param buffer The buffer. + * @return The object definition. + */ + public static SceneryDefinition parseDefinition(int objectId, ByteBuffer buffer) { + SceneryDefinition def = new SceneryDefinition(); + def.id = objectId; +// SystemLogger.logErr("----------------------------------------------------\n\n\n"); + while (true) { + if (!buffer.hasRemaining()) { + log(SceneryDefinition.class, Log.ERR, "Buffer empty for " + objectId); + break; + } + int opcode = buffer.get() & 0xFF; + //SystemLogger.logErr("Parsing object " + objectId + " op " + opcode); + if (opcode == 1 || opcode == 5) { + int length = buffer.get() & 0xff; + if (def.modelIds == null) { + def.modelIds = new int[length]; + if (opcode == 1) { + def.modelConfiguration = new int[length]; + } + for (int i = 0; i < length; i++) { + def.modelIds[i] = buffer.getShort() & 0xFFFF; + if (opcode == 1) { + def.modelConfiguration[i] = buffer.get() & 0xFF; + } + } + } else { + buffer.position(buffer.position() + (length * (opcode == 1 ? 3 : 2))); + } + } else if (opcode == 2) { + def.name = ByteBufferUtils.getString(buffer); + } else if (opcode == 14) { + def.sizeX = buffer.get() & 0xFF; + } else if (opcode == 15) { + def.sizeY = buffer.get() & 0xFF; + } else if (opcode == 17) { + def.projectileClipped = false; + def.clipType = 0; + } else if (opcode == 18) { + def.projectileClipped = false; + } else if (opcode == 19) { + def.interactable = buffer.get() & 0xFF; + } else if (opcode == 21) { + def.aByte3912 = (byte) 1; + } else if (opcode == 22) { + def.aBoolean3867 = true; + } else if (opcode == 23) { + def.boolean1 = true; + } else if (opcode == 24) { + def.animationId = buffer.getShort() & 0xFFFF; + if (def.animationId == 65535) { + def.animationId = -1; + } + } else if (opcode == 27) { + def.clipType = 1; + } else if (opcode == 28) { + def.anInt3892 = ((buffer.get() & 0xFF) << 2); + } else if (opcode == 29) { + def.anInt3878 = buffer.get(); + } else if (opcode == 39) { + def.anInt3840 = buffer.get() * 5; + } else if (opcode >= 30 && opcode < 35) { + def.options[opcode - 30] = ByteBufferUtils.getString(buffer); + if (def.options[opcode - 30].equals("Hidden")) { + def.options[opcode - 30] = null; + def.hasHiddenOptions = true; + } + } else if (opcode == 40) { + int length = buffer.get() & 0xFF; + def.originalColors = new short[length]; + def.modifiedColors = new short[length]; + for (int i = 0; i < length; i++) { + def.originalColors[i] = buffer.getShort(); + def.modifiedColors[i] = buffer.getShort(); + } + } else if (opcode == 41) { + int length = buffer.get() & 0xFF; + def.aShortArray3920 = new short[length]; + def.aShortArray3919 = new short[length]; + for (int i = 0; i < length; i++) { + def.aShortArray3920[i] = buffer.getShort(); + def.aShortArray3919[i] = buffer.getShort(); + } + } else if (opcode == 42) { + int length = buffer.get() & 0xFF; + def.aByteArray3858 = new byte[length]; + for (int i = 0; i < length; i++) { + def.aByteArray3858[i] = buffer.get(); + } + } else if (opcode == 60) { + def.mapIcon = buffer.getShort(); + } else if (opcode == 62) { + def.aBoolean3839 = true; + } else if (opcode == 64) { + def.aBoolean3872 = false; + } else if (opcode == 65) { + def.anInt3902 = buffer.getShort() & 0xFFFF; + } else if (opcode == 66) { + def.anInt3841 = buffer.getShort() & 0xFFFF; + } else if (opcode == 67) { + def.anInt3917 = buffer.getShort() & 0xFFFF; + } else if (opcode == 68) { + buffer.getShort(); + } else if (opcode == 69) { + def.walkingFlag = buffer.get() & 0xFF; + } else if (opcode == 70) { + def.anInt3883 = buffer.getShort() << 2; + } else if (opcode == 71) { + def.anInt3889 = buffer.getShort() << 2; + } else if (opcode == 72) { + def.anInt3915 = buffer.getShort() << 2; + } else if (opcode == 73) { + def.secondBool = true; + } else if (opcode == 74) { + def.notClipped = true; + } else if (opcode == 75) { + def.anInt3855 = buffer.get() & 0xFF; + } else if (opcode == 77 || opcode == 92) { + def.configFileId = buffer.getShort() & 0xFFFF; + if (def.configFileId == 65535) { + def.configFileId = -1; + } + def.configId = buffer.getShort() & 0xFFFF; + if (def.configId == 65535) { + def.configId = -1; + } + int defaultId = -1; + if (opcode == 92) { + defaultId = buffer.getShort() & 0xFFFF; + if (defaultId == 65535) { + defaultId = -1; + } + } + int childrenAmount = buffer.get() & 0xFF; + def.childrenIds = new int[childrenAmount + 2]; + for (int index = 0; childrenAmount >= index; index++) { + def.childrenIds[index] = buffer.getShort() & 0xFFFF; + if (def.childrenIds[index] == 65535) { + def.childrenIds[index] = -1; + } + } + def.childrenIds[childrenAmount + 1] = defaultId; + } else if (opcode == 78) { + def.anInt3860 = buffer.getShort() & 0xFFFF; + def.anInt3904 = buffer.get() & 0xFF; + } else if (opcode == 79) { + def.anInt3900 = buffer.getShort() & 0xFFFF; + def.anInt3905 = buffer.getShort() & 0xFFFF; + def.anInt3904 = buffer.get() & 0xFF; + int length = buffer.get() & 0xFF; + def.anIntArray3859 = new int[length]; + for (int i = 0; i < length; i++) { + def.anIntArray3859[i] = buffer.getShort() & 0xFFFF; + } + } else if (opcode == 81) { + def.aByte3912 = (byte) 2; + def.anInt3882 = 256 * buffer.get() & 0xFF; + } else if (opcode == 82 || opcode == 88) { + // Nothing. + } else if (opcode == 89) { + def.aBoolean3895 = false; + } else if (opcode == 90) { + def.aBoolean3870 = true; + } else if (opcode == 91) { + def.membersOnly = true; + } else if (opcode == 93) { + def.aByte3912 = (byte) 3; + def.anInt3882 = buffer.getShort() & 0xFFFF; + } else if (opcode == 94) { + def.aByte3912 = (byte) 4; + } else if (opcode == 95) { + def.aByte3912 = (byte) 5; + } else if (opcode == 96 || opcode == 97) { + // + } else if (opcode == 100) { + buffer.get(); + buffer.getShort(); + } else if (opcode == 101) { + buffer.get(); + } else if (opcode == 102) { + buffer.getShort(); + } else if (opcode == 249) { // cs2 scripts + int length = buffer.get() & 0xFF; + for (int i = 0; i < length; i++) { + boolean string = buffer.get() == 1; + ByteBufferUtils.getMedium(buffer); // script id + if (!string) { + buffer.getInt(); // Value + } else { + ByteBufferUtils.getString(buffer); // value + } + } + } else { + if (opcode != 0) { + log(SceneryDefinition.class, Log.ERR, "Unhandled object definition opcode: " + opcode); + } + break; + } + } + def.configureObject(); + if (def.notClipped) { + def.clipType = 0; + def.projectileClipped = false; + } + return def; + } + + /** + * Configures the object definitions. + */ + final void configureObject() { + if (interactable == -1) { + interactable = 0; + if (modelIds != null && (getModelConfiguration() == null || getModelConfiguration()[0] == 10)) { + interactable = 1; + } + for (int i = 0; i < 5; i++) { + if (options[i] != null) { + interactable = 1; + break; + } + } + } + if(childrenIds != null) { + for (int i = 0; i < childrenIds.length; ++i) { + SceneryDefinition def = forId(childrenIds[i]); + def.configFileId = configFileId; + } + } + if (anInt3855 == -1) { + anInt3855 = clipType == 0 ? 0 : 1; + } + // Manual changes + if (id == 31017) { + sizeX = sizeY = 2; + } + if (id == 29292) { + projectileClipped = false; + } + } + + /** + * Checks if the object is visible. + * @return {@code True} if so. + */ + public boolean hasActions() { + if(interactable > 0) { + return true; + } + if (childrenIds == null) { + return hasOptions(false); + } + for (int i = 0; i < childrenIds.length; i++) { + if (childrenIds[i] != -1) { + SceneryDefinition def = forId(childrenIds[i]); + if (def.hasOptions(false)) { + return true; + } + } + } + return hasOptions(false); + } + + /** + * Gets the child object definitions. + * @param player The player to get it for. + * @return The object definition. + */ + public SceneryDefinition getChildObject(Player player) { + if (childrenIds == null || childrenIds.length < 1) { + return this; + } + int configValue = -1; + if (player != null) { + if (configFileId != -1) { + VarbitDefinition def = VarbitDefinition.forObjectID(configFileId); + if (def != null) { + configValue = def.getValue(player); + } + } else if (configId != -1) { + configValue = getVarp(player, configId); + } + } else { + configValue = 0; + } + SceneryDefinition childDef = getChildObjectAtIndex(configValue); + if (childDef != null) childDef.configFileId = this.configFileId; + return childDef; + } + + public SceneryDefinition getChildObjectAtIndex (int index) { + if (childrenIds == null || childrenIds.length < 1) { + return this; + } + if (index < 0 || index >= childrenIds.length - 1 || childrenIds[index] == -1) { + int objectId = childrenIds[childrenIds.length - 1]; + if (objectId != -1) { + return forId(objectId); + } + return this; + } + return forId(childrenIds[index]); + } + + /** + * Gets the config file definition. + * @return The config file definition. + */ + public VarbitDefinition getConfigFile() { + if (configFileId != -1) { + return VarbitDefinition.forObjectID(configFileId); + } + return null; + } + + /** + * Get the aBoolean3839. + * @return the aBoolean3839 + */ + public boolean isaBoolean3839() { + return aBoolean3839; + } + + /** + * @param aBoolean3839 the aBoolean3839 to set + */ + public void setaBoolean3839(boolean aBoolean3839) { + this.aBoolean3839 = aBoolean3839; + } + + /** + * Get the originalColors. + * @return the originalColors + */ + public short[] getOriginalColors() { + return originalColors; + } + + /** + * Get the childrenIds. + * @return the childrenIds + */ + public int[] getChildrenIds() { + return childrenIds; + } + + /** + * Get the anInt3832. + * @return the anInt3832 + */ + public static int getAnInt3832() { + return anInt3832; + } + + /** + * Get the anIntArray3833. + * @return the anIntArray3833 + */ + public int[] getAnIntArray3833() { + return anIntArray3833; + } + + /** + * Get the anInt3834. + * @return the anInt3834 + */ + public int getAnInt3834() { + return anInt3834; + } + + /** + * Get the anInt3835. + * @return the anInt3835 + */ + public int getAnInt3835() { + return anInt3835; + } + + /** + * Get the anInt3836. + * @return the anInt3836 + */ + public static int getAnInt3836() { + return anInt3836; + } + + /** + * Get the aByte3837. + * @return the aByte3837 + */ + public byte getaByte3837() { + return aByte3837; + } + + /** + * Get the anInt3838. + * @return the anInt3838 + */ + public int getAnInt3838() { + return anInt3838; + } + + /** + * Get the anInt3840. + * @return the anInt3840 + */ + public int getAnInt3840() { + return anInt3840; + } + + /** + * Get the anInt3841. + * @return the anInt3841 + */ + public int getAnInt3841() { + return anInt3841; + } + + /** + * Get the anInt3842. + * @return the anInt3842 + */ + public static int getAnInt3842() { + return anInt3842; + } + + /** + * Get the anInt3843. + * @return the anInt3843 + */ + public static int getAnInt3843() { + return anInt3843; + } + + /** + * Get the anInt3844. + * @return the anInt3844 + */ + public int getAnInt3844() { + return anInt3844; + } + + /** + * Get the aBoolean3845. + * @return the aBoolean3845 + */ + public boolean isaBoolean3845() { + return aBoolean3845; + } + + /** + * Get the anInt3846. + * @return the anInt3846 + */ + public static int getAnInt3846() { + return anInt3846; + } + + /** + * Get the aByte3847. + * @return the aByte3847 + */ + public byte getaByte3847() { + return aByte3847; + } + + /** + * Get the aByte3849. + * @return the aByte3849 + */ + public byte getaByte3849() { + return aByte3849; + } + + /** + * Get the anInt3850. + * @return the anInt3850 + */ + public int getAnInt3850() { + return anInt3850; + } + + /** + * Get the anInt3851. + * @return the anInt3851 + */ + public int getAnInt3851() { + return anInt3851; + } + + /** + * Get the secondBool. + * @return the secondBool + */ + public boolean isSecondBool() { + return secondBool; + } + + /** + * Get the aBoolean3853. + * @return the aBoolean3853 + */ + public boolean isaBoolean3853() { + return aBoolean3853; + } + + /** + * Get the anInt3855. + * @return the anInt3855 + */ + public int getAnInt3855() { + return anInt3855; + } + + /** + * Get the firstBool. + * @return the firstBool + */ + public boolean isFirstBool() { + return notClipped; + } + + /** + * Get the anInt3857. + * @return the anInt3857 + */ + public int getAnInt3857() { + return anInt3857; + } + + /** + * Get the aByteArray3858. + * @return the aByteArray3858 + */ + public byte[] getaByteArray3858() { + return aByteArray3858; + } + + /** + * Get the anIntArray3859. + * @return the anIntArray3859 + */ + public int[] getAnIntArray3859() { + return anIntArray3859; + } + + /** + * Get the anInt3860. + * @return the anInt3860 + */ + public int getAnInt3860() { + return anInt3860; + } + + /** + * Get the options. + * @return the options + */ + @Override + public String[] getOptions() { + return options; + } + + /** + * Get the configFileId. + * @return the configFileId + */ + public int getVarbitID() { + return configFileId; + } + + /** + * Get the modifiedColors. + * @return the modifiedColors + */ + public short[] getModifiedColors() { + return modifiedColors; + } + + /** + * Get the anInt3865. + * @return the anInt3865 + */ + public int getAnInt3865() { + return anInt3865; + } + + /** + * Get the aBoolean3866. + * @return the aBoolean3866 + */ + public boolean isaBoolean3866() { + return aBoolean3866; + } + + /** + * Get the aBoolean3867. + * @return the aBoolean3867 + */ + public boolean isaBoolean3867() { + return aBoolean3867; + } + + /** + * Get the solid. + * @return the solid + */ + public boolean isProjectileClipped() { + return projectileClipped; + } + + /** + * Get the anIntArray3869. + * @return the anIntArray3869 + */ + public int[] getAnIntArray3869() { + return anIntArray3869; + } + + /** + * Get the aBoolean3870. + * @return the aBoolean3870 + */ + public boolean isaBoolean3870() { + return aBoolean3870; + } + + /** + * Get the sizeY. + * @return the sizeY + */ + public int getSizeY() { + return sizeY; + } + + /** + * Get the aBoolean3872. + * @return the aBoolean3872 + */ + public boolean isaBoolean3872() { + return aBoolean3872; + } + + /** + * Get the membersOnly. + * @return the membersOnly + */ + public boolean isaBoolean3873() { + return membersOnly; + } + + /** + * Get the thirdInt. + * @return the thirdInt + */ + public boolean getThirdBoolean() { + return boolean1; + } + + /** + * Get the anInt3875. + * @return the anInt3875 + */ + public int getAnInt3875() { + return anInt3875; + } + + /** + * Get the addObjectCheck. + * @return the addObjectCheck + */ + public int getAddObjectCheck() { + return animationId; + } + + /** + * Get the anInt3877. + * @return the anInt3877 + */ + public int getAnInt3877() { + return anInt3877; + } + + /** + * Get the anInt3878. + * @return the anInt3878 + */ + public int getAnInt3878() { + return anInt3878; + } + + /** + * Get the clipType. + * @return the clipType + */ + public int getClipType() { + return clipType; + } + + /** + * Get the anInt3881. + * @return the anInt3881 + */ + public int getAnInt3881() { + return anInt3881; + } + + /** + * Get the anInt3882. + * @return the anInt3882 + */ + public int getAnInt3882() { + return anInt3882; + } + + /** + * Get the anInt3883. + * @return the anInt3883 + */ + public int getAnInt3883() { + return anInt3883; + } + + /** + * Get the loader. + * @return the loader + */ + public Object getLoader() { + return loader; + } + + /** + * Get the anInt3889. + * @return the anInt3889 + */ + public int getAnInt3889() { + return anInt3889; + } + + /** + * Get the sizeX. + * @return the sizeX + */ + public int getSizeX() { + return sizeX; + } + + /** + * Get the aBoolean3891. + * @return the aBoolean3891 + */ + public boolean isaBoolean3891() { + return aBoolean3891; + } + + /** + * Get the anInt3892. + * @return the anInt3892 + */ + public int getAnInt3892() { + return anInt3892; + } + + /** + * Get the interactable. + * @return the interactable + */ + public int getInteractable() { + return interactable; + } + + /** + * Get the aBoolean3894. + * @return the aBoolean3894 + */ + public boolean isaBoolean3894() { + return aBoolean3894; + } + + /** + * Get the aBoolean3895. + * @return the aBoolean3895 + */ + public boolean isaBoolean3895() { + return aBoolean3895; + } + + /** + * Get the anInt3896. + * @return the anInt3896 + */ + public int getAnInt3896() { + return anInt3896; + } + + /** + * Get the configId. + * @return the configId + */ + public int getConfigId() { + return configId; + } + + /** + * Get the aByteArray3899. + * @return the aByteArray3899 + */ + public byte[] getaByteArray3899() { + return aByteArray3899; + } + + /** + * Get the anInt3900. + * @return the anInt3900 + */ + public int getAnInt3900() { + return anInt3900; + } + + /** + * Get the name. + * @return the name + */ + @Override + public String getName() { + return name; + } + + /** + * Get the anInt3902. + * @return the anInt3902 + */ + public int getAnInt3902() { + return anInt3902; + } + + /** + * Get the anInt3904. + * @return the anInt3904 + */ + public int getAnInt3904() { + return anInt3904; + } + + /** + * Get the anInt3905. + * @return the anInt3905 + */ + public int getAnInt3905() { + return anInt3905; + } + + /** + * Get the aBoolean3906. + * @return the aBoolean3906 + */ + public boolean isaBoolean3906() { + return aBoolean3906; + } + + /** + * Get the anIntArray3908. + * @return the anIntArray3908 + */ + public int[] getAnIntArray3908() { + return anIntArray3908; + } + + /** + * Get the aByte3912. + * @return the aByte3912 + */ + public byte getaByte3912() { + return aByte3912; + } + + /** + * Get the anInt3913. + * @return the anInt3913 + */ + public int getAnInt3913() { + return anInt3913; + } + + /** + * Get the aByte3914. + * @return the aByte3914 + */ + public byte getaByte3914() { + return aByte3914; + } + + /** + * Get the anInt3915. + * @return the anInt3915 + */ + public int getAnInt3915() { + return anInt3915; + } + + /** + * Get the anIntArrayArray3916. + * @return the anIntArrayArray3916 + */ + public int[][] getAnIntArrayArray3916() { + return anIntArrayArray3916; + } + + /** + * Get the anInt3917. + * @return the anInt3917 + */ + public int getAnInt3917() { + return anInt3917; + } + + /** + * Get the aShortArray3919. + * @return the aShortArray3919 + */ + public short[] getaShortArray3919() { + return aShortArray3919; + } + + /** + * Get the aShortArray3920. + * @return the aShortArray3920 + */ + public short[] getaShortArray3920() { + return aShortArray3920; + } + + /** + * Get the anInt3921. + * @return the anInt3921 + */ + public int getAnInt3921() { + return anInt3921; + } + + /** + * Get the aClass194_3922. + * @return the aClass194_3922 + */ + public Object getaClass194_3922() { + return aClass194_3922; + } + + /** + * Get the aBoolean3923. + * @return the aBoolean3923 + */ + public boolean isaBoolean3923() { + return aBoolean3923; + } + + /** + * Get the aBoolean3924. + * @return the aBoolean3924 + */ + public boolean isaBoolean3924() { + return aBoolean3924; + } + + /** + * Gets the object's model ids. + * @return The model ids array. + */ + public int[] getModelIds() { + return modelIds; + } + + /** + * If the object has a reward. + * @param action The specified reward. + * @return If the object has the reward {@code true}. + */ + public boolean hasAction(String action) { + if (options == null) { + return false; + } + for (String option : options) { + if (option == null) { + continue; + } + if (option.equalsIgnoreCase(action)) { + return true; + } + } + return false; + } + + /** + * Get the definitions. + * @return the definitions + */ + public static Map getDefinitions() { + return DEFINITIONS; + } + + /** + * Gets the option handler for the given option name. + * @param nodeId The node id. + * @param name The name. + * @return The option handler, or {@code null} if there was no default + * option handler. + */ + public static OptionHandler getOptionHandler(int nodeId, String name) { + SceneryDefinition def = forId(nodeId); + OptionHandler handler = def.getConfiguration("option:" + name); + if (handler != null) { + return handler; + } + return OPTION_HANDLERS.get(name); + } + + /** + * Sets the default option handler for an option. + * @param name The option name. + * @param handler The default option handler. + * @return {@code True} if there was a previous default handler mapped. + */ + public static boolean setOptionHandler(String name, OptionHandler handler) { + return OPTION_HANDLERS.put(name, handler) != null; + } + + /** + * Gets the hasHiddenOptions. + * @return The hasHiddenOptions. + */ + public boolean isHasHiddenOptions() { + return hasHiddenOptions; + } + + /** + * Sets the hasHiddenOptions. + * @param hasHiddenOptions The hasHiddenOptions to set. + */ + public void setHasHiddenOptions(boolean hasHiddenOptions) { + this.hasHiddenOptions = hasHiddenOptions; + } + + /** + * Gets the walking flag. + * @return The walking flag. + */ + public int getWalkingFlag() { + return walkingFlag; + } + + /** + * Gets the modelConfiguration. + * @return The modelConfiguration. + */ + public int[] getModelConfiguration() { + return modelConfiguration; + } + + /** + * Sets the modelConfiguration. + * @param modelConfiguration The modelConfiguration to set. + */ + public void setModelConfiguration(int[] modelConfiguration) { + this.modelConfiguration = modelConfiguration; + } + + /** + * Gets the mapIcon. + * @return The mapIcon. + */ + public short getMapIcon() { + return mapIcon; + } + + /** + * Get the container id. + * @param id The object id. + * @return The container id. + */ + public static int getContainerId(int id) { + return id >>> 8; + } +} diff --git a/Server/src/main/core/cache/def/impl/ScriptArgs.java b/Server/src/main/core/cache/def/impl/ScriptArgs.java new file mode 100644 index 0000000..27b0373 --- /dev/null +++ b/Server/src/main/core/cache/def/impl/ScriptArgs.java @@ -0,0 +1,11 @@ +package core.cache.def.impl; + +public class ScriptArgs { + public int id; + public Object[] args; + + public ScriptArgs(int id, Object[] args) { + this.id = id; + this.args = args; + } +} diff --git a/Server/src/main/core/cache/def/impl/ScriptTriggers.java b/Server/src/main/core/cache/def/impl/ScriptTriggers.java new file mode 100644 index 0000000..dbc165a --- /dev/null +++ b/Server/src/main/core/cache/def/impl/ScriptTriggers.java @@ -0,0 +1,9 @@ +package core.cache.def.impl; + +public class ScriptTriggers { + public int[] varpTriggers; + public int[] inventoryTriggers; + public int[] statTriggers; + public int[] varcTriggers; + public int[] varcstrTriggers; +} diff --git a/Server/src/main/core/cache/def/impl/Struct.java b/Server/src/main/core/cache/def/impl/Struct.java new file mode 100644 index 0000000..92081ad --- /dev/null +++ b/Server/src/main/core/cache/def/impl/Struct.java @@ -0,0 +1,100 @@ +package core.cache.def.impl; + +import core.cache.Cache; +import core.cache.misc.buffer.ByteBufferUtils; +import core.tools.Log; +import core.tools.SystemLogger; + +import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.Map; + +import static core.api.ContentAPIKt.log; + +public class Struct { + + /** + * The struct definitions mapping. + */ + private static final Map definitions = new HashMap<>(); + + /** + * The enum id. + */ + private final int id; + + public HashMap dataStore = new HashMap<>(); + + public Struct(int id) { + this.id = id; + } + + public int getInt(int key){ + if(!dataStore.containsKey(key)){ + log(this.getClass(), Log.ERR, "Invalid value passed for key: " + key + " struct: " + id); + return -1; + } + return (int) dataStore.get(key); + } + + public String getString(int key){ + return (String) dataStore.get(key); + } + + @Override + public String toString() { + return "Struct{" + + "id=" + id + + ", dataStore=" + dataStore + + '}'; + } + + public static Struct get(int id){ + Struct def = definitions.get(id); + if (def != null) { + return def; + } + byte[] data = Cache.getIndexes()[2].getFileData(26, id); + def = parse(id, data); + + definitions.put(id, def); + return def; + } + + public static Struct parse(int id, byte[] data) + { + Struct def = new Struct(id); + if (data != null) { + ByteBuffer buffer = ByteBuffer.wrap(data); + int opcode; + + while ((opcode = buffer.get() & 0xFF) != 0) { + + if (opcode == 249) { + int size = buffer.get() & 0xFF; + + for (int i = 0; size > i; i++) { + boolean bool = (buffer.get() & 0xFF) == 1; + int key = ByteBufferUtils.getMedium(buffer); + Object value; + if (bool) { + value = ByteBufferUtils.getString(buffer); + } else { + value = buffer.getInt(); + } + def.dataStore.put(key, value); + } + } + } + } + return def; + } + + public static int getCount() { + return Cache.getIndexes()[2].getFilesSize(26); + } + + public int getId() { + return id; + } +} diff --git a/Server/src/main/core/cache/def/impl/VarbitDefinition.java b/Server/src/main/core/cache/def/impl/VarbitDefinition.java new file mode 100644 index 0000000..9fb4f6b --- /dev/null +++ b/Server/src/main/core/cache/def/impl/VarbitDefinition.java @@ -0,0 +1,173 @@ +package core.cache.def.impl; + +import core.cache.Cache; +import core.game.node.entity.player.Player; + +import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.Map; + +import static core.api.ContentAPIKt.*; + +/** + * Handles config definition reading. + * @author Emperor + */ +public final class VarbitDefinition { + + /** + * The config definitions mapping. + */ + private static final Map MAPPING = new HashMap<>(); + + /** + * The bit size flags. + */ + private static final int[] BITS = new int[32]; + + /** + * The file id. + */ + private final int id; + + /** + * The config id. + */ + private int varpId; + + /** + * The bit shift amount. + */ + private int startBit; + + /** + * The bit amount. + */ + private int endBit; + + /** + * Constructs a new {@code ConfigFileDefinition} {@code Object}. + * @param id The file id. + */ + public VarbitDefinition(int id) { + this.id = id; + } + + public VarbitDefinition(int varpId, int id, int startBit, int endBit) + { + this.varpId = varpId; + this.id = id; + this.startBit = startBit; + this.endBit = endBit; + } + + /** + * Initializes the bit flags. + */ + static { + int flag = 2; + for (int i = 0; i < 32; i++) { + BITS[i] = flag - 1; + flag += flag; + } + } + + /** + * Gets the config file definitions for the given file id. + * @param id The file id. + * @return The definition. + */ + public static VarbitDefinition forObjectID(int id) { + return forId(id); + } + + public static VarbitDefinition forNPCID(int id){ + return forId(id); + } + + public static VarbitDefinition forItemID(int id){ + return forId(id); + } + + public static VarbitDefinition forId(int id){ + VarbitDefinition def = MAPPING.get(id); + if (def != null) { + return def; + } + + def = new VarbitDefinition(id); + byte[] bs = Cache.getIndexes()[22].getFileData(id >>> 10, id & 0x3ff); + if (bs != null) { + ByteBuffer buffer = ByteBuffer.wrap(bs); + int opcode = 0; + while ((opcode = buffer.get() & 0xFF) != 0) { + if (opcode == 1) { + def.varpId = buffer.getShort() & 0xFFFF; + def.startBit = buffer.get() & 0xFF; + def.endBit = buffer.get() & 0xFF; + } + } + } + MAPPING.put(id, def); + return def; + } + + public static void create(int varpId, int varbitId, int startBit, int endBit){ + VarbitDefinition def = new VarbitDefinition( + varpId, + varbitId, + startBit, + endBit + ); + MAPPING.put(varbitId, def); + } + + /** + * Gets the current config value for this file. + * @param player The player. + * @return The config value. + */ + public int getValue(Player player) { + return getVarbit(player, id); + } + + /** + * Gets the mapping. + * @return The mapping. + */ + public static Map getMapping() { + return MAPPING; + } + + /** + * Gets the id. + * @return The id. + */ + public int getId() { + return id; + } + + public int getVarpId() { + return varpId; + } + + public int getStartBit() { + return startBit; + } + + public int getEndBit() { + return endBit; + } + + public int getMask() { + int mask = 0; + for (int i = startBit; i <= endBit; i++) + mask |= (1 << (i - startBit)); + return mask; + } + + @Override + public String toString() { + return "ConfigFileDefinition [id=" + id + ", configId=" + varpId + ", bitShift=" + startBit + ", bitSize=" + endBit + "]"; + } +} diff --git a/Server/src/main/core/cache/def/impl/test.txt b/Server/src/main/core/cache/def/impl/test.txt new file mode 100644 index 0000000..2cd6e87 --- /dev/null +++ b/Server/src/main/core/cache/def/impl/test.txt @@ -0,0 +1,365 @@ +private void readValues(int i, InputStream stream, int opcode) { + if (opcode != 1 && opcode != 5) { + if (opcode != 2) { + if (opcode != 14) { + if (opcode != 15) { + if (opcode == 17) { + projectileCliped = false; + clipType = 0; + } else if (opcode != 18) { + if (opcode == 19) + secondInt = stream.readUnsignedByte(); + else if (opcode == 21) + aByte3912 = (byte) 1; + else if (opcode != 22) { + if (opcode != 23) { + if (opcode != 24) { + if (opcode == 27) + clipType = 1; + else if (opcode == 28) + anInt3892 = (stream + .readUnsignedByte() << 2); + else if (opcode != 29) { + if (opcode != 39) { + if (opcode < 30 || opcode >= 35) { + if (opcode == 40) { + int i_53_ = (stream + .readUnsignedByte()); + originalColors = new short[i_53_]; + modifiedColors = new short[i_53_]; + for (int i_54_ = 0; i_53_ > i_54_; i_54_++) { + originalColors[i_54_] = (short) (stream + .readUnsignedShort()); + modifiedColors[i_54_] = (short) (stream + .readUnsignedShort()); + } + } else if (opcode != 41) { + if (opcode != 42) { + if (opcode != 62) { + if (opcode != 64) { + if (opcode == 65) + anInt3902 = stream + .readUnsignedShort(); + else if (opcode != 66) { + if (opcode != 67) { + if (opcode == 69) + anInt3925 = stream + .readUnsignedByte(); + else if (opcode != 70) { + if (opcode == 71) + anInt3889 = stream + .readShort() << 2; + else if (opcode != 72) { + if (opcode == 73) + secondBool = true; + else if (opcode == 74) + notCliped = true; + else if (opcode != 75) { + if (opcode != 77 + && opcode != 92) { + if (opcode == 78) { + anInt3860 = stream + .readUnsignedShort(); + anInt3904 = stream + .readUnsignedByte(); + } else if (opcode != 79) { + if (opcode == 81) { + aByte3912 = (byte) 2; + anInt3882 = 256 * stream + .readUnsignedByte(); + } else if (opcode != 82) { + if (opcode == 88) + aBoolean3853 = false; + else if (opcode != 89) { + if (opcode == 90) + aBoolean3870 = true; + else if (opcode != 91) { + if (opcode != 93) { + if (opcode == 94) + aByte3912 = (byte) 4; + else if (opcode != 95) { + if (opcode != 96) { + if (opcode == 97) + aBoolean3866 = true; + else if (opcode == 98) + aBoolean3923 = true; + else if (opcode == 99) { + anInt3857 = stream + .readUnsignedByte(); + anInt3835 = stream + .readUnsignedShort(); + } else if (opcode == 100) { + anInt3844 = stream + .readUnsignedByte(); + anInt3913 = stream + .readUnsignedShort(); + } else if (opcode != 101) { + if (opcode == 102) + anInt3838 = stream + .readUnsignedShort(); + else if (opcode == 103) + thirdInt = 0; + else if (opcode != 104) { + if (opcode == 105) + aBoolean3906 = true; + else if (opcode == 106) { + int i_55_ = stream + .readUnsignedByte(); + anIntArray3869 = new int[i_55_]; + anIntArray3833 = new int[i_55_]; + for (int i_56_ = 0; i_56_ < i_55_; i_56_++) { + anIntArray3833[i_56_] = stream + .readUnsignedShort(); + int i_57_ = stream + .readUnsignedByte(); + anIntArray3869[i_56_] = i_57_; + anInt3881 += i_57_; + } + } else if (opcode == 107) + anInt3851 = stream + .readUnsignedShort(); + else if (opcode >= 150 + && opcode < 155) { + options[opcode + + -150] = stream + .readString(); + /*if (!loader.showOptions) + options[opcode + -150] = null;*/ + } else if (opcode != 160) { + if (opcode == 162) { + aByte3912 = (byte) 3; + anInt3882 = stream + .readInt(); + } else if (opcode == 163) { + aByte3847 = (byte) stream + .readByte(); + aByte3849 = (byte) stream + .readByte(); + aByte3837 = (byte) stream + .readByte(); + aByte3914 = (byte) stream + .readByte(); + } else if (opcode != 164) { + if (opcode != 165) { + if (opcode != 166) { + if (opcode == 167) + anInt3921 = stream + .readUnsignedShort(); + else if (opcode != 168) { + if (opcode == 169) { + aBoolean3845 = true; + //added opcode + }else if (opcode == 170) { + int anInt3383 = stream.readUnsignedSmart(); + //added opcode + }else if (opcode == 171) { + int anInt3362 = stream.readUnsignedSmart(); + //added opcode + }else if (opcode == 173) { + int anInt3302 = stream.readUnsignedShort(); + int anInt3336 = stream.readUnsignedShort(); + //added opcode + }else if (opcode == 177) { + boolean ub = true; + //added opcode + }else if (opcode == 178) { + int db = stream.readUnsignedByte(); + } else if (opcode == 249) { + int i_58_ = stream + .readUnsignedByte(); + if (aClass194_3922 == null) { + /*int i_59_ = Class307 + .method3331( + (byte) -117, + i_58_); + aClass194_3922 = new HashTable( + i_59_);*/ + } + for (int i_60_ = 0; i_60_ < i_58_; i_60_++) { + boolean bool = stream + .readUnsignedByte() == 1; + int i_61_ = stream.read24BitInt(); + Object class279; + if (!bool) + /*class279 = new IntegerNode(*/ + stream + .readInt();//); + else + /*class279 = new Class279_Sub4(*/ + stream + .readString();//); + /*aClass194_3922 + .method1598( + (long) i_61_, + -125, + class279);*/ + } + } + } else + aBoolean3894 = true; + } else + anInt3877 = stream + .readShort(); + } else + anInt3875 = stream + .readShort(); + } else + anInt3834 = stream + .readShort(); + } else { + int i_62_ = stream + .readUnsignedByte(); + anIntArray3908 = new int[i_62_]; + for (int i_63_ = 0; i_62_ > i_63_; i_63_++) + anIntArray3908[i_63_] = stream + .readUnsignedShort(); + } + } else + anInt3865 = stream + .readUnsignedByte(); + } else + anInt3850 = stream + .readUnsignedByte(); + } else + aBoolean3924 = true; + } else { + aByte3912 = (byte) 5; + anInt3882 = stream + .readShort(); + } + } else { + aByte3912 = (byte) 3; + anInt3882 = stream + .readUnsignedShort(); + } + } else + aBoolean3873 = true; + } else + aBoolean3895 = false; + } else + aBoolean3891 = true; + } else { + anInt3900 = stream + .readUnsignedShort(); + anInt3905 = stream + .readUnsignedShort(); + anInt3904 = stream + .readUnsignedByte(); + int i_64_ = stream + .readUnsignedByte(); + anIntArray3859 = new int[i_64_]; + for (int i_65_ = 0; i_65_ < i_64_; i_65_++) + anIntArray3859[i_65_] = stream + .readUnsignedShort(); + } + } else { + configFileId = stream + .readUnsignedShort(); + if (configFileId == 65535) + configFileId = -1; + configId = stream + .readUnsignedShort(); + if (configId == 65535) + configId = -1; + int i_66_ = -1; + if (opcode == 92) { + i_66_ = stream + .readUnsignedShort(); + if (i_66_ == 65535) + i_66_ = -1; + } + int i_67_ = stream + .readUnsignedByte(); + childrenIds = new int[i_67_ + - -2]; + for (int i_68_ = 0; i_67_ >= i_68_; i_68_++) { + childrenIds[i_68_] = stream + .readUnsignedShort(); + if (childrenIds[i_68_] == 65535) + childrenIds[i_68_] = -1; + } + childrenIds[i_67_ + 1] = i_66_; + } + } else + anInt3855 = stream + .readUnsignedByte(); + } else + anInt3915 = stream + .readShort() << 2; + } else + anInt3883 = stream + .readShort() << 2; + } else + anInt3917 = stream + .readUnsignedShort(); + } else + anInt3841 = stream + .readUnsignedShort(); + } else + aBoolean3872 = false; + } else + aBoolean3839 = true; + } else { + int i_69_ = (stream + .readUnsignedByte()); + aByteArray3858 = (new byte[i_69_]); + for (int i_70_ = 0; i_70_ < i_69_; i_70_++) + aByteArray3858[i_70_] = (byte) (stream + .readByte()); + } + } else { + int i_71_ = (stream + .readUnsignedByte()); + aShortArray3920 = new short[i_71_]; + aShortArray3919 = new short[i_71_]; + for (int i_72_ = 0; i_71_ > i_72_; i_72_++) { + aShortArray3920[i_72_] = (short) (stream + .readUnsignedShort()); + aShortArray3919[i_72_] = (short) (stream + .readUnsignedShort()); + } + } + } else + options[-30 + + opcode] = (stream + .readString()); + } else + anInt3840 = (stream.readByte() * 5); + } else + anInt3878 = stream.readByte(); + } else { + anInt3876 = stream.readUnsignedShort(); + if (anInt3876 == 65535) + anInt3876 = -1; + } + } else + thirdInt = 1; + } else + aBoolean3867 = true; + } else + projectileCliped = false; + } else + sizeY = stream.readUnsignedByte(); + } else + sizeX = stream.readUnsignedByte(); + } else + name = stream.readString(); + } else { + boolean aBoolean1162 = false; + if (opcode == 5 && aBoolean1162) + method3297(stream); + int i_73_ = stream.readUnsignedByte(); + anIntArrayArray3916 = new int[i_73_][]; + aByteArray3899 = new byte[i_73_]; + for (int i_74_ = 0; i_74_ < i_73_; i_74_++) { + aByteArray3899[i_74_] = (byte) stream.readByte(); + int i_75_ = stream.readUnsignedByte(); + anIntArrayArray3916[i_74_] = new int[i_75_]; + for (int i_76_ = 0; i_75_ > i_76_; i_76_++) + anIntArrayArray3916[i_74_][i_76_] = stream + .readUnsignedShort(); + } + if (opcode == 5 && !aBoolean1162) + method3297(stream); + } + } \ No newline at end of file diff --git a/Server/src/main/core/cache/gzip/GZipDecompressor.java b/Server/src/main/core/cache/gzip/GZipDecompressor.java new file mode 100644 index 0000000..0b45064 --- /dev/null +++ b/Server/src/main/core/cache/gzip/GZipDecompressor.java @@ -0,0 +1,47 @@ +package core.cache.gzip; + +import java.nio.ByteBuffer; +import java.util.zip.Inflater; + +public class GZipDecompressor { + + private static final Inflater inflaterInstance = new Inflater(true); + + public static final void decompress(ByteBuffer buffer, byte[] data) { + synchronized (inflaterInstance) { + if (~buffer.get(buffer.position()) != -32 || buffer.get(buffer.position() + 1) != -117) { + data = null; + // throw new RuntimeException("Invalid GZIP header!"); + } + try { + inflaterInstance.setInput(buffer.array(), buffer.position() + 10, -buffer.position() - 18 + buffer.limit()); + inflaterInstance.inflate(data); + } catch (Exception e) { + // inflaterInstance.reset(); + data = null; + // throw new RuntimeException("Invalid GZIP compressed data!"); + } + inflaterInstance.reset(); + } + } + + public static final boolean decompress(byte[] compressed, byte data[], int offset, int length) { + synchronized (inflaterInstance) { + if (data[offset] != 31 || data[offset + 1] != -117) + return false; + // throw new RuntimeException("Invalid GZIP header!"); + try { + inflaterInstance.setInput(data, offset + 10, -offset - 18 + length); + inflaterInstance.inflate(compressed); + } catch (Exception e) { + inflaterInstance.reset(); + e.printStackTrace(); + return false; + // throw new RuntimeException("Invalid GZIP compressed data!"); + } + inflaterInstance.reset(); + return true; + } + } + +} diff --git a/Server/src/main/core/cache/misc/Container.java b/Server/src/main/core/cache/misc/Container.java new file mode 100644 index 0000000..9760845 --- /dev/null +++ b/Server/src/main/core/cache/misc/Container.java @@ -0,0 +1,109 @@ +package core.cache.misc; + +/** + * A container. + * @author Dragonkk + */ +public class Container { + + /** + * The version. + */ + private int version; + + /** + * The CRC. + */ + private int crc; + + /** + * The name hash. + */ + private int nameHash; + + /** + * If updated. + */ + private boolean updated; + + /** + * Construct a new container. + */ + public Container() { + nameHash = -1; + version = -1; + crc = -1; + } + + /** + * Set the version. + * @param version + */ + public void setVersion(int version) { + this.version = version; + } + + /** + * Update the version. + */ + public void updateVersion() { + version++; + updated = true; + } + + /** + * Get the version. + * @return The version. + */ + public int getVersion() { + return version; + } + + /** + * Get the next version. + * @return The next version. + */ + public int getNextVersion() { + return updated ? version : version + 1; + } + + /** + * Set the CRC. + * @param crc The cRC. + */ + public void setCrc(int crc) { + this.crc = crc; + } + + /** + * Get the CRC. + * @return The CRC. + */ + public int getCrc() { + return crc; + } + + /** + * Set the name hash. + * @param nameHash The name hash. + */ + public void setNameHash(int nameHash) { + this.nameHash = nameHash; + } + + /** + * Get the name hash. + * @return The name hash. + */ + public int getNameHash() { + return nameHash; + } + + /** + * If is updated. + * @return If is updated. + */ + public boolean isUpdated() { + return updated; + } +} diff --git a/Server/src/main/core/cache/misc/ContainersInformation.java b/Server/src/main/core/cache/misc/ContainersInformation.java new file mode 100644 index 0000000..f786c1d --- /dev/null +++ b/Server/src/main/core/cache/misc/ContainersInformation.java @@ -0,0 +1,228 @@ +package core.cache.misc; + +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.zip.CRC32; + +import core.cache.bzip2.BZip2Decompressor; +import core.cache.gzip.GZipDecompressor; + +/** + * A class holding the containers information. + * @author Dragonkk + */ +public final class ContainersInformation { + + /** + * The information container. + */ + private Container informationContainer; + + /** + * The protocol. + */ + private int protocol; + + /** + * The revision. + */ + private int revision; + + /** + * The container indexes. + */ + private int[] containersIndexes; + + /** + * The containers. + */ + private FilesContainer[] containers; + + /** + * If files have to be named. + */ + private boolean filesNamed; + + /** + * If it has to be whirpool. + */ + private boolean whirpool; + + /** + * The data. + */ + private final byte[] data; + + /** + * Construct a new containers information. + * @param informationContainerPackedData The information container data + * packed. + */ + public ContainersInformation(byte[] informationContainerPackedData) { + this.data = Arrays.copyOf(informationContainerPackedData, informationContainerPackedData.length); + informationContainer = new Container(); + informationContainer.setVersion((informationContainerPackedData[informationContainerPackedData.length - 2] << 8 & 0xff00) + (informationContainerPackedData[-1 + informationContainerPackedData.length] & 0xff)); + CRC32 crc32 = new CRC32(); + crc32.update(informationContainerPackedData); + informationContainer.setCrc((int) crc32.getValue()); + decodeContainersInformation(unpackCacheContainer(informationContainerPackedData)); + } + + /** + * Unpacks a container. + * @param packedData The packed container data. + * @return The unpacked data. + */ + public static final byte[] unpackCacheContainer(byte[] packedData) { + ByteBuffer buffer = ByteBuffer.wrap(packedData); + int compression = buffer.get() & 0xFF; + int containerSize = buffer.getInt(); + if (containerSize < 0 || containerSize > 5000000) { + return null; + // throw new RuntimeException(); + } + if (compression == 0) { + byte unpacked[] = new byte[containerSize]; + buffer.get(unpacked, 0, containerSize); + return unpacked; + } + int decompressedSize = buffer.getInt(); + if (decompressedSize < 0 || decompressedSize > 20000000) { + return null; + // throw new RuntimeException(); + } + byte decompressedData[] = new byte[decompressedSize]; + if (compression == 1) { + BZip2Decompressor.decompress(decompressedData, packedData, containerSize, 9); + } else { + GZipDecompressor.decompress(buffer, decompressedData); + } + return decompressedData; + } + + /** + * Get the container indexes. + * @return The container indexes. + */ + public int[] getContainersIndexes() { + return containersIndexes; + } + + /** + * Get the containers. + * @return The containers. + */ + public FilesContainer[] getContainers() { + return containers; + } + + /** + * Get the information container. + * @return The information container. + */ + public Container getInformationContainer() { + return informationContainer; + } + + /** + * Get the revision. + * @return The revision. + */ + public int getRevision() { + return revision; + } + + /** + * Decode the containers information. + * @param data The data. + */ + public void decodeContainersInformation(byte[] data) { + ByteBuffer buffer = ByteBuffer.wrap(data); + protocol = buffer.get() & 0xFF; + if (protocol != 5 && protocol != 6) { + throw new RuntimeException(); + } + revision = protocol < 6 ? 0 : buffer.getInt(); + int nameHash = buffer.get() & 0xFF; + filesNamed = (0x1 & nameHash) != 0; + whirpool = (0x2 & nameHash) != 0; + containersIndexes = new int[buffer.getShort() & 0xFFFF]; + int lastIndex = -1; + for (int index = 0; index < containersIndexes.length; index++) { + containersIndexes[index] = (buffer.getShort() & 0xFFFF) + (index == 0 ? 0 : containersIndexes[index - 1]); + if (containersIndexes[index] > lastIndex) { + lastIndex = containersIndexes[index]; + } + } + containers = new FilesContainer[lastIndex + 1]; + for (int index = 0; index < containersIndexes.length; index++) { + containers[containersIndexes[index]] = new FilesContainer(); + } + if (filesNamed) { + for (int index = 0; index < containersIndexes.length; index++) { + containers[containersIndexes[index]].setNameHash(buffer.getInt()); + } + } + byte[][] filesHashes = null; + if (whirpool) { + filesHashes = new byte[containers.length][]; + for (int index = 0; index < containersIndexes.length; index++) { + filesHashes[containersIndexes[index]] = new byte[64]; + buffer.get(filesHashes[containersIndexes[index]], 0, 64); + } + } + for (int index = 0; index < containersIndexes.length; index++) { + containers[containersIndexes[index]].setCrc(buffer.getInt()); + } + for (int index = 0; index < containersIndexes.length; index++) { + containers[containersIndexes[index]].setVersion(buffer.getInt()); + } + for (int index = 0; index < containersIndexes.length; index++) { + containers[containersIndexes[index]].setFilesIndexes(new int[buffer.getShort() & 0xFFFF]); + } + for (int index = 0; index < containersIndexes.length; index++) { + int lastFileIndex = -1; + for (int fileIndex = 0; fileIndex < containers[containersIndexes[index]].getFilesIndexes().length; fileIndex++) { + containers[containersIndexes[index]].getFilesIndexes()[fileIndex] = (buffer.getShort() & 0xFFFF) + (fileIndex == 0 ? 0 : containers[containersIndexes[index]].getFilesIndexes()[fileIndex - 1]); + if (containers[containersIndexes[index]].getFilesIndexes()[fileIndex] > lastFileIndex) { + lastFileIndex = containers[containersIndexes[index]].getFilesIndexes()[fileIndex]; + } + } + containers[containersIndexes[index]].setFiles(new Container[lastFileIndex + 1]); + for (int fileIndex = 0; fileIndex < containers[containersIndexes[index]].getFilesIndexes().length; fileIndex++) { + containers[containersIndexes[index]].getFiles()[containers[containersIndexes[index]].getFilesIndexes()[fileIndex]] = new Container(); + } + } + if (whirpool) { + for (int index = 0; index < containersIndexes.length; index++) { + for (int fileIndex = 0; fileIndex < containers[containersIndexes[index]].getFilesIndexes().length; fileIndex++) { + containers[containersIndexes[index]].getFiles()[containers[containersIndexes[index]].getFilesIndexes()[fileIndex]].setVersion(filesHashes[containersIndexes[index]][containers[containersIndexes[index]].getFilesIndexes()[fileIndex]]); + } + } + } + if (filesNamed) { + for (int index = 0; index < containersIndexes.length; index++) { + for (int fileIndex = 0; fileIndex < containers[containersIndexes[index]].getFilesIndexes().length; fileIndex++) { + containers[containersIndexes[index]].getFiles()[containers[containersIndexes[index]].getFilesIndexes()[fileIndex]].setNameHash(buffer.getInt()); + } + } + } + } + + /** + * If is whirpool. + * @return If is whirpool {@code true}. + */ + public boolean isWhirpool() { + return whirpool; + } + + /** + * Gets the data. + * @return The data. + */ + public byte[] getData() { + return data; + } + +} diff --git a/Server/src/main/core/cache/misc/FilesContainer.java b/Server/src/main/core/cache/misc/FilesContainer.java new file mode 100644 index 0000000..5f14e44 --- /dev/null +++ b/Server/src/main/core/cache/misc/FilesContainer.java @@ -0,0 +1,57 @@ +package core.cache.misc; + +/** + * A class holding the file containers. + * @author Dragonkk + */ +public final class FilesContainer extends Container { + + /** + * The file indexes. + */ + private int[] filesIndexes; + + /** + * The files. + */ + private Container[] files; + + /** + * Construct a new files container. + */ + public FilesContainer() { + + } + + /** + * Set the files. + * @param containers The files. + */ + public void setFiles(Container[] containers) { + this.files = containers; + } + + /** + * Get the files. + * @return The files. + */ + public Container[] getFiles() { + return files; + } + + /** + * Set the file indexes. + * @param containersIndexes The file indexes. + */ + public void setFilesIndexes(int[] containersIndexes) { + this.filesIndexes = containersIndexes; + } + + /** + * Get the file indexes. + * @return The file indexes. + */ + public int[] getFilesIndexes() { + return filesIndexes; + } +} diff --git a/Server/src/main/core/cache/misc/buffer/BufferInputStream.java b/Server/src/main/core/cache/misc/buffer/BufferInputStream.java new file mode 100644 index 0000000..a801c87 --- /dev/null +++ b/Server/src/main/core/cache/misc/buffer/BufferInputStream.java @@ -0,0 +1,39 @@ +package core.cache.misc.buffer; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.ByteBuffer; + +/** + * Handles the reading of data from a byte buffer. + * @author Emperor + */ +public final class BufferInputStream extends InputStream { + + /** + * The buffer to write on. + */ + private final ByteBuffer buffer; + + /** + * The buffer input stream. + * @param buffer The buffer. + */ + public BufferInputStream(ByteBuffer buffer) throws IOException { + this.buffer = buffer; + } + + @Override + public int read() throws IOException { + return buffer.get(); + } + + /** + * Gets the buffer. + * @return The buffer. + */ + public ByteBuffer getBuffer() { + return buffer; + } + +} diff --git a/Server/src/main/core/cache/misc/buffer/BufferOutputStream.java b/Server/src/main/core/cache/misc/buffer/BufferOutputStream.java new file mode 100644 index 0000000..88ea2ac --- /dev/null +++ b/Server/src/main/core/cache/misc/buffer/BufferOutputStream.java @@ -0,0 +1,57 @@ +package core.cache.misc.buffer; + +import java.io.IOException; +import java.io.OutputStream; +import java.nio.ByteBuffer; + +/** + * Handles the writing of data on a byte buffer. + * @author Emperor + */ +public final class BufferOutputStream extends OutputStream { + + /** + * The buffer to write on. + */ + private final ByteBuffer buffer; + + /** + * Constructs a new {@code BufferOutputStream} {@code Object}. + * @param buffer The buffer to write on. + * @throws IOException When an I/O exception occurs. + * @throws SecurityException If a security manager exists and its + * checkPermission method denies enabling subclassing. + */ + public BufferOutputStream(ByteBuffer buffer) throws IOException, SecurityException { + super(); + this.buffer = buffer; + } + + @Override + public void write(int b) throws IOException { + buffer.put((byte) b); + } + + @Override + public void flush() { + /* + * empty. + */ + } + + @Override + public void close() { + /* + * empty. + */ + } + + /** + * Gets the buffer. + * @return The buffer. + */ + public ByteBuffer getBuffer() { + return buffer; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/cache/misc/buffer/ByteBufferUtils.java b/Server/src/main/core/cache/misc/buffer/ByteBufferUtils.java new file mode 100644 index 0000000..fb04ae2 --- /dev/null +++ b/Server/src/main/core/cache/misc/buffer/ByteBufferUtils.java @@ -0,0 +1,182 @@ +package core.cache.misc.buffer; + +import java.io.ObjectInputStream; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; + +/** + * Holds utility methods for reading/writing a byte buffer. + * @author Emperor + */ +public final class ByteBufferUtils { + + /** + * Gets a string from the byte buffer. + * @param buffer The byte buffer. + * @return The string. + */ + public static String getString(ByteBuffer buffer) { + StringBuilder sb = new StringBuilder(); + byte b; + while ((b = buffer.get()) != 0) { + sb.append((char) b); + } + return sb.toString(); + } + + /** + * Puts a string on the byte buffer. + * @param s The string to put. + * @param buffer The byte buffer. + */ + public static void putString(String s, ByteBuffer buffer) { + buffer.put(s.getBytes(StandardCharsets.UTF_8)).put((byte) 0); + } + + /** + * Gets a string from the byte buffer. + * @param s The string. + * @param buffer The byte buffer. + * @return The string. + */ + public static ByteBuffer putGJ2String(String s, ByteBuffer buffer) { + byte[] packed = new byte[256]; + int length = packGJString2(0, packed, s); + return buffer.put((byte) 0).put(packed, 0, length).put((byte) 0); + } + + /** + * Decodes the XTEA encryption. + * @param keys The keys. + * @param start The start index. + * @param end The end index. + * @param buffer The byte buffer. + */ + public static void decodeXTEA(int[] keys, int start, int end, ByteBuffer buffer) { + int l = buffer.position(); + buffer.position(start); + int length = (end - start) / 8; + for (int i = 0; i < length; i++) { + int firstInt = buffer.getInt(); + int secondInt = buffer.getInt(); + int sum = 0xc6ef3720; + int delta = 0x9e3779b9; + for (int j = 32; j-- > 0;) { + secondInt -= keys[(sum & 0x1c84) >>> 11] + sum ^ (firstInt >>> 5 ^ firstInt << 4) + firstInt; + sum -= delta; + firstInt -= (secondInt >>> 5 ^ secondInt << 4) + secondInt ^ keys[sum & 3] + sum; + } + buffer.position(buffer.position() - 8); + buffer.putInt(firstInt); + buffer.putInt(secondInt); + } + buffer.position(l); + } + + /** + * Converts a String to an Integer? + * @param position The position. + * @param buffer The buffer used. + * @param string The String to convert. + * @return The Integer. + */ + public static int packGJString2(int position, byte[] buffer, String string) { + int length = string.length(); + int offset = position; + for (int i = 0; length > i; i++) { + int character = string.charAt(i); + if (character > 127) { + if (character > 2047) { + buffer[offset++] = (byte) ((character | 919275) >> 12); + buffer[offset++] = (byte) (128 | ((character >> 6) & 63)); + buffer[offset++] = (byte) (128 | (character & 63)); + } else { + buffer[offset++] = (byte) ((character | 12309) >> 6); + buffer[offset++] = (byte) (128 | (character & 63)); + } + } else + buffer[offset++] = (byte) character; + } + return offset - position; + } + + /** + * Gets a tri-byte from the buffer. + * @param buffer The buffer. + * @return The value. + */ + public static int getMedium(ByteBuffer buffer) { + return ((buffer.get() & 0xFF) << 16) + ((buffer.get() & 0xFF) << 8) + (buffer.get() & 0xFF); + } + + /** + * Gets a smart from the buffer. + * @param buffer The buffer. + * @return The value. + */ + public static int getSmart(ByteBuffer buffer) { + int peek = buffer.get() & 0xFF; + if (peek <= Byte.MAX_VALUE) { + return peek; + } + return ((peek << 8) | (buffer.get() & 0xFF)) - 32768; + } + + /** + * Gets a smart from the buffer. + * @param buffer The buffer. + * @return The value. + */ + public static int getBigSmart(ByteBuffer buffer) { + int value = 0; + int current = getSmart(buffer); + while (current == 32767) { + current = getSmart(buffer); + value += 32767; + } + value += current; + return value; + } + + /* *//** + * Writes an object on the buffer. + * @param buffer The buffer to write on. + * @param o The object. + */ + /* + * public static void putObject(ByteBuffer buffer, Object o) { ByteBuffer b; + * try (ObjectOutputStream out = new ObjectOutputStream(new + * BufferOutputStream(b = ByteBuffer.allocate(99999)))) { + * out.writeObject(o); b.flip(); } catch (Throwable e) { + * e.printStackTrace(); b = (ByteBuffer) ByteBuffer.allocate(0).flip(); } + * buffer.putInt(b.remaining()); if (b.remaining() > 0) { buffer.put(b); } } + */ + + /** + * Gets an object from the byte buffer. + * @param buffer The buffer. + * @return The object. + */ + public static Object getObject(ByteBuffer buffer) { + int length = buffer.getInt(); + if (length > 0) { + byte[] bytes = new byte[length]; + buffer.get(bytes); + try (ObjectInputStream str = new ObjectInputStream(new BufferInputStream(ByteBuffer.wrap(bytes)))) { + return (Object) str.readObject(); + } catch (Throwable e) { + e.printStackTrace(); + } + } + return null; + } + + /** + * Constructs a new {@code ByteBufferUtils} {@code Object}. + */ + private ByteBufferUtils() { + /* + * empty. + */ + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/activity/ActivityManager.java b/Server/src/main/core/game/activity/ActivityManager.java new file mode 100644 index 0000000..15ab8ff --- /dev/null +++ b/Server/src/main/core/game/activity/ActivityManager.java @@ -0,0 +1,82 @@ +package core.game.activity; + +import core.game.node.entity.player.Player; +import core.tools.Log; +import core.tools.SystemLogger; +import core.game.world.GameWorld; + +import java.util.HashMap; +import java.util.Map; + +import static core.api.ContentAPIKt.log; + +/** + * Manages the activities. + * @author Emperor + */ +public final class ActivityManager { + + /** + * The mapping of instanced activities. + */ + private static final Map ACTIVITIES = new HashMap<>(); + + /** + * Constructs a new {@code ActivityManager} {@code Object}. + */ + private ActivityManager() { + /* + * empty. + */ + } + + /** + * Registers an activity plugin. + * @param plugin The plugin to register. + */ + public static void register(ActivityPlugin plugin) { + plugin.register(); + ACTIVITIES.put(plugin.getName(), plugin); + if (!plugin.isInstanced()) { + plugin.configure(); + } + } + + /** + * Starts an instanced activity. + * @param player The player. + * @param name The name. + * @param login If we are logging in. + * @param args The arguments. + */ + public static boolean start(Player player, String name, boolean login, Object... args) { + ActivityPlugin plugin = ACTIVITIES.get(name); + if (plugin == null) { + if (GameWorld.getSettings().isDevMode()) { + log(ActivityManager.class, Log.ERR, "Unhandled activity - " + name + "!"); + } + return false; + } + try { + if (plugin.isInstanced()) { + (plugin = plugin.newInstance(player)).configure(); + } + return plugin.start(player, login, args); + } catch (Throwable e) { + e.printStackTrace(); + if (GameWorld.getSettings().isDevMode()) { + player.getPacketDispatch().sendMessage("Error starting activity " + (plugin == null ? null : plugin.getName()) + "!"); + } + } + return false; + } + + /** + * Gets the activity by the name. + * @param name the name. + * @return the activity. + */ + public static ActivityPlugin getActivity(String name) { + return ACTIVITIES.get(name); + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/activity/ActivityPlugin.java b/Server/src/main/core/game/activity/ActivityPlugin.java new file mode 100644 index 0000000..50ea847 --- /dev/null +++ b/Server/src/main/core/game/activity/ActivityPlugin.java @@ -0,0 +1,254 @@ +package core.game.activity; + +import core.ServerConstants; +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.game.world.map.Region; +import core.game.world.map.build.DynamicRegion; +import core.game.world.map.zone.*; +import core.game.world.map.zone.impl.MultiwayCombatZone; +import core.plugin.Plugin; +import core.plugin.PluginManifest; +import core.plugin.PluginType; + +/** + * A plugin implementation used for activity plugins. + * @author Emperor + */ +@PluginManifest(type = PluginType.ACTIVITY) +public abstract class ActivityPlugin extends MapZone implements Plugin { + + /** + * If the activity is instanced. + */ + private boolean instanced; + + /** + * If the activity is multicombat. + */ + private boolean multicombat; + + /** + * If the activity is safe. + */ + private boolean safe; + + /** + * The region of the activity. + */ + protected DynamicRegion region; + + /** + * The base location. + */ + protected Location base; + + /** + * A location which the player is teleported to in the case of death, if this activity is safe. + * Defaults to the home location of the server. + */ + protected Location safeRespawn = ServerConstants.HOME_LOCATION; + + /** + * The player. + */ + protected Player player; + + /** + * Constructs a new {@code ActivityPlugin} {@code Object}. + * @param name The name. + * @param instanced If the activity is instanced. + * @param multicombat If the activity is multicombat. + * @param safe If the activity is safe (the player does not lose his/her + * items). + */ + public ActivityPlugin(String name, boolean instanced, boolean multicombat, boolean safe, ZoneRestriction... restrictions) { + super(name, true, ZoneRestriction.RANDOM_EVENTS); + for (ZoneRestriction restriction : restrictions) { + addRestriction(restriction.getFlag()); + } + this.instanced = instanced; + this.multicombat = multicombat; + this.safe = safe; + if (safe) { + setZoneType(ZoneType.SAFE.getId()); + } + } + + @Override + public void register(ZoneBorders borders) { + if (multicombat) { + MultiwayCombatZone.getInstance().register(borders); + } + super.register(borders); + } + + /** + * Sets the region base location. + */ + protected void setRegionBase() { + if (region != null) { + if (multicombat) { + region.toggleMulticombat(); + } + setBase(Location.create(region.getBorders().getSouthWestX(), region.getBorders().getSouthWestY(), 0)); + } + } + + /** + * Sets the region base for multiple regions. + * @param regions The regions. + */ + protected void setRegionBase(DynamicRegion[] regions) { + region = regions[0]; + Location l = region.getBaseLocation(); + for (DynamicRegion r : regions) { + if (r.getX() > l.getX() || r.getY() > l.getY()) { + l = r.getBaseLocation(); + } + } + ZoneBorders borders = new ZoneBorders(region.getX() << 6, region.getY() << 6, l.getX() + Region.SIZE, l.getY() + Region.SIZE); + RegionZone multiZone = multicombat ? new RegionZone(MultiwayCombatZone.getInstance(), borders) : null; + RegionZone zone = new RegionZone(this, borders); + for (DynamicRegion r : regions) { + if (multicombat) { + r.setMulticombat(true); + r.getRegionZones().add(multiZone); + } + r.getRegionZones().add(zone); + } + setBase(Location.create(borders.getSouthWestX(), borders.getSouthWestY(), 0)); + } + + /** + * Starts the activity for the player. + * @param player The player. + * @param login If the player is logging in. + * @param args The arguments. + * @return {@code True} if successfully started the activity. + */ + public boolean start(Player player, boolean login, Object... args) { + this.player = player; + return true; + } + + @Override + public boolean enter(Entity e) { + Location l; + if (e instanceof Player && (l = getSpawnLocation()) != null) { + e.getProperties().setSpawnLocation(l); + } + e.getProperties().setSafeZone(safe); + e.getProperties().safeRespawn = this.safeRespawn; + e.setAttribute("activity", this); + return super.enter(e); + } + + @Override + public boolean leave(Entity e, boolean logout) { + if (e instanceof Player) { + e.getProperties().setSpawnLocation(ServerConstants.HOME_LOCATION); + } + Location l; + if (instanced && logout && (l = getSpawnLocation()) != null) { + e.setLocation(l); + } + e.getProperties().setSafeZone(false); + e.getProperties().safeRespawn = ServerConstants.HOME_LOCATION; + e.removeAttribute("activity"); + return super.leave(e, logout); + } + + /** + * Method used to do anything on registration. + */ + public void register() { + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public abstract ActivityPlugin newInstance(Player p) throws Throwable; + + /** + * Gets the spawn location for this activity. + */ + public abstract Location getSpawnLocation(); + + /** + * Gets the instanced. + * @return The instanced. + */ + public boolean isInstanced() { + return instanced; + } + + /** + * Sets the instanced. + * @param instanced The instanced to set. + */ + public void setInstanced(boolean instanced) { + this.instanced = instanced; + } + + /** + * Gets the multicombat. + * @return The multicombat. + */ + public boolean isMulticombat() { + return multicombat; + } + + /** + * Sets the multicombat. + * @param multicombat The multicombat to set. + */ + public void setMulticombat(boolean multicombat) { + this.multicombat = multicombat; + } + + /** + * Gets the safe. + * @return The safe. + */ + public boolean isSafe() { + return safe; + } + + /** + * Sets the safe. + * @param safe The safe to set. + */ + public void setSafe(boolean safe) { + this.safe = safe; + } + + /** + * Gets the player. + * @return The player. + */ + public Player getPlayer() { + return player; + } + + /** + * Gets the base. + * @return The base. + */ + public Location getBase() { + return base; + } + + /** + * Sets the base. + * @param base The base to set. + */ + public void setBase(Location base) { + this.base = base; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/activity/Cutscene.kt b/Server/src/main/core/game/activity/Cutscene.kt new file mode 100644 index 0000000..5cf9584 --- /dev/null +++ b/Server/src/main/core/game/activity/Cutscene.kt @@ -0,0 +1,497 @@ +package core.game.activity + +import core.api.* +import core.game.event.EventHook +import core.game.event.SelfDeathEvent +import core.game.component.Component +import core.game.interaction.MovementPulse +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.scenery.Scenery +import core.game.system.task.Pulse +import core.game.world.map.Direction +import core.game.world.map.Location +import core.game.world.map.Region +import core.game.world.map.RegionManager +import core.game.world.map.build.DynamicRegion +import core.game.world.map.path.Pathfinder +import core.net.packet.PacketRepository +import core.net.packet.context.MinimapStateContext +import core.net.packet.out.MinimapState +import org.rs09.consts.Components +import core.ServerConstants +import core.api.Event +import core.api.utils.CameraShakeType +import core.api.utils.PlayerCamera +import core.game.system.timer.impl.AntiMacro +import core.game.world.GameWorld +import core.tools.Log + +/** + * A utility class for making cutscenes. + * @author Ceikry + */ +abstract class Cutscene(val player: Player) { + lateinit var region: Region + lateinit var base: Location + var exitLocation: Location = player.location.transform(0,0,0) + var ended = false + + val camera = PlayerCamera(player) + private val addedNPCs = HashMap>() + + abstract fun setup() + abstract fun runStage(stage: Int) + + /** + * Creates a new dynamic copy of the region identified by regionId, sets this cutscene's region as this new copy, and clears any cutscene-spawned NPCs from the previous region. + * @param regionId the region ID to duplicate. + */ + fun loadRegion(regionId: Int) + { + clearNPCs() + logCutscene("Creating new instance of region $regionId for ${player.username}.") + region = DynamicRegion.create(regionId) + logCutscene("Dynamic region instantiated for ${player.username}. Global coordinates: ${region.baseLocation}.") + base = region.baseLocation + } + + /** + * Immediately closes the player's overlay. + */ + fun closeOverlay() + { + logCutscene("Close ${player.username}'s overlay.") + player.interfaceManager.closeOverlay() + } + + /** + * Fade the player's view to black. This process can be safely assumed to take about 8 ticks to complete. + */ + fun fadeToBlack() + { + logCutscene("Fading ${player.username}'s screen to black.") + player.interfaceManager.closeOverlay() + player.interfaceManager.openOverlay(Component(Components.FADE_TO_BLACK_120)) + } + + /** + * Fade the player's view from black back to normal. This process can be safely assumed to take about 6 ticks to complete. + */ + fun fadeFromBlack() + { + logCutscene("Fading ${player.username}'s screen from black to normal.") + player.interfaceManager.closeOverlay() + player.interfaceManager.openOverlay(Component(Components.FADE_FROM_BLACK_170)) + } + + /** + * Teleports an entity to a pair of coordinates within the currently active cutscene region + * @param entity the entity to teleport + * @param regionX the region X coordinate to teleport the entity to (0-63) + * @param regionY the region Y coordinate to teleport the entity to (0-63) + * @param plane (optional) the plane to teleport to (0-3) + */ + fun teleport(entity: Entity, regionX: Int, regionY: Int, plane: Int = 0) + { + val newLoc = base.transform(regionX, regionY, plane) + logCutscene("Teleporting ${entity.username} to coordinates: LOCAL[$regionX,$regionY,$plane] GLOBAL[${newLoc.x},${newLoc.y},$plane].") + entity.properties.teleportLocation = newLoc + } + + /** + * Moves an entity to the given coordinates within the currently active cutscene region + * @param entity the entity to move + * @param regionX the region X coordinate to move the entity to (0-63) + * @param regionY the region Y coordinate to move the entity to (0-63) + */ + fun move(entity: Entity, regionX: Int, regionY: Int) + { + logCutscene("Moving ${entity.username} to LOCAL[$regionX,$regionY].") + entity.pulseManager.run(object : MovementPulse(entity, base.transform(regionX,regionY,0), Pathfinder.SMART) { + override fun pulse(): Boolean { + return true + } + }) + } + + /** + * Sends a dialogue to the player using the given NPC ID, which updates the cutscene stage by default when continued. + * @param npcId the ID of the NPC to send a dialogue for + * @param expression the FacialExpression the NPC should use + * @param message the message to send + * @param onContinue (optional) a method that runs when the dialogue is "continued." Increments the cutscene stage by default. + * @param hide Should the continue button be hidden? + */ + fun dialogueUpdate(npcId: Int, expression: core.game.dialogue.FacialExpression, message: String, onContinue: () -> Unit = {incrementStage()}, hide: Boolean = false) + { + logCutscene("Sending NPC dialogue update.") + sendNPCDialogue(player, npcId, message, expression, hide) + player.dialogueInterpreter.addAction { _,_ -> onContinue.invoke() } + } + + /** + * Sends a dialogue to the player using the given NPC ID, which updates the cutscene stage by default when continued. + * @param npcId the ID of the NPC to send a dialogue for + * @param expression the FacialExpression the NPC should use + * @param message the message to send + * @param onContinue (optional) a method that runs when the dialogue is "continued." Increments the cutscene stage by default. + */ + fun dialogueLinesUpdate(npcId: Int, expression: core.game.dialogue.FacialExpression, vararg message: String, onContinue: () -> Unit = {incrementStage()}) + { + logCutscene("Sending NPC dialogue lines update.") + sendNPCDialogueLines(player, npcId, expression, true, *message) + player.dialogueInterpreter.addAction { _,_ -> onContinue.invoke() } + } + + /** + * Forces the dialogue to close. + */ + fun dialogueClose() + { + logCutscene("Sending dialogue close.") + closeDialogue(player) + } + + /** + * Sends a non-NPC dialogue to the player, which updates the cutscene stage by default when continued + * @param message the message to send + * @param onContinue (optional) a method that runs when the dialogue is "continued." Increments the cutscene stage by default. + */ + fun dialogueUpdate(message: String, onContinue: () -> Unit = {incrementStage()}) + { + logCutscene("Sending standard dialogue update.") + sendDialogue(player, message) + player.dialogueInterpreter.addAction {_,_ -> onContinue.invoke()} + } + + /** + * Sends a player dialogue, which updates the cutscene stage by default when continued + * @param expression the FacialExpression to use + * @param message the message to send + * @param onContinue (optional) a method that runs when the dialogue is "continued." Increments the cutscene stage by default. + */ + fun playerDialogueUpdate(expression: core.game.dialogue.FacialExpression, message: String, onContinue: () -> Unit = {incrementStage()}) + { + logCutscene("Sending player dialogue update") + sendPlayerDialogue(player, message, expression) + player.dialogueInterpreter.addAction{_,_ -> onContinue.invoke()} + } + + /** + * Updates the stage after a set number of ticks. + * @param ticks the number of ticks to wait + * @param newStage (optional) the new stage to update to. If not passed, stage is incremented instead. + */ + fun timedUpdate(ticks: Int, newStage: Int = -1) + { + logCutscene("Executing timed updated for $ticks ticks.") + GameWorld.Pulser.submit(object : Pulse(ticks) + { + override fun pulse(): Boolean { + if(newStage == -1) + incrementStage() + else + updateStage(newStage) + return true + } + }) + } + + /** + * Retrieves the first NPC from the added-to-cutscene NPCs with a matching ID. + * @param id the ID to grab for. + * @return the first NPC, or null if there are no matching NPCs. + */ + fun getNPC(id: Int): NPC? + { + return addedNPCs[id]?.firstOrNull() + } + + /** + * Retrieves all NPCs from the added-to-cutscene NPCs with a matching ID. + * @param id the ID to grab for. + * @return an ArrayList of the matching NPCs, which will be empty if there were no matches. + */ + fun getNPCs(id: Int): ArrayList + { + return addedNPCs[id] ?: ArrayList() + } + + /** + * Retrieves the object in the region at the given regionX and regionY + * @param regionX the region-local X coordinate to grab the object from (0-63) + * @param regionY the region-local Y coordinate to grab the object from (0-63) + * @param plane the plane to grab the object from (0-3) + */ + fun getObject(regionX: Int, regionY: Int, plane: Int = 0): Scenery? + { + val obj = RegionManager.getObject(base.transform(regionX,regionY,plane)) + logCutscene("Retrieving object at LOCAL[$regionX,$regionY], GOT: ${obj?.definition?.name ?: "null"}.") + return obj + } + + /** + * Adds an NPC to the cutscene with the given ID, at the region-local X and Y coordinates. + * @param id the ID of the NPC to add. + * @param regionX the region-local X coordinate to place the NPC at + * @param regionY the region-local Y coordinate to place the NPC at + * @param direction the direction the NPC faces when it is initially placed. + * @param plane the plane to place te NPC on. Default is 0. + */ + fun addNPC(id: Int, regionX: Int, regionY: Int, direction: Direction, plane: Int = 0) + { + val npc = NPC(id) + npc.isRespawn = false + npc.isAggressive = false + npc.isWalks = false + npc.location = base.transform(regionX, regionY, plane) + npc.init() + npc.faceLocation(npc.location.transform(direction)) + + val npcs = addedNPCs[id] ?: ArrayList() + npcs.add(npc) + addedNPCs[id] = npcs + logCutscene("Added NPC $id at location LOCAL[$regionX,$regionY,$plane] GLOBAL[${npc.location.x},${npc.location.y},$plane]") + } + + fun start(){ + start(true) + } + + fun start(hideMiniMap: Boolean) + { + logCutscene("Starting cutscene for ${player.username}.") + region = RegionManager.forId(player.location.regionId) + base = RegionManager.forId(player.location.regionId).baseLocation + setup() + if (hideMiniMap) { + PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 2)) + } + runStage(player.getCutsceneStage()) + setAttribute(player, ATTRIBUTE_CUTSCENE, this) + setAttribute(player, ATTRIBUTE_CUTSCENE_STAGE, 0) + player.interfaceManager.removeTabs(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14) + player.properties.isSafeZone = true + player.properties.safeRespawn = player.location + player.lock() + player.hook(Event.SelfDeath, CUTSCENE_DEATH_HOOK) + player.logoutListeners["cutscene"] = {player -> player.location = exitLocation; player.getCutscene()?.end() } + AntiMacro.pause(player) + } + + + /** + * Ends this cutscene, teleporting the player to the exit location, and then fading it back in and executing the endActions passed to this method. + * @param endActions (optional) a method that executes when the cutscene fully completes + */ + fun endWithoutFade(endActions: (() -> Unit)? = null) + { + ended = true + GameWorld.Pulser.submit(object : Pulse(){ + var tick: Int = 0 + override fun pulse(): Boolean { + when(tick++) + { + 0 -> player.properties.teleportLocation = exitLocation + 1 -> { + return true + } + } + return false + } + + override fun stop() { + super.stop() + player ?: return + player.removeAttribute(ATTRIBUTE_CUTSCENE) + player.removeAttribute(ATTRIBUTE_CUTSCENE_STAGE) + player.properties.isSafeZone = false + player.properties.safeRespawn = ServerConstants.HOME_LOCATION + player.interfaceManager.restoreTabs() + player.unlock() + clearNPCs() + player.unhook(CUTSCENE_DEATH_HOOK) + player.logoutListeners.remove("cutscene") + AntiMacro.unpause(player) + PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 0)) + try { + endActions?.invoke() + } catch (e: Exception) { + log(this::class.java, Log.ERR, "There's some bad nasty code in ${this::class.java.simpleName} end actions!") + e.printStackTrace() + } + } + }) + } + + /** + * Ends this cutscene, fading the screen to black, teleporting the player to the exit location, and then fading it back in and executing the endActions passed to this method. + * @param fade (optional) should the cutscene fade to black? + * @param endActions (optional) a method that executes when the cutscene fully completes + */ + fun end(fade: Boolean = true, endActions: (() -> Unit)? = null) + { + ended = true + if (fade) fadeToBlack() + GameWorld.Pulser.submit(object : Pulse(){ + var tick: Int = 0 + override fun pulse(): Boolean { + if (fade) { + when (tick++) { + 8 -> player.properties.teleportLocation = exitLocation + 9 -> fadeFromBlack() + 16 -> return true + else -> return false + } + } + else player.properties.teleportLocation = exitLocation + return true + } + + override fun stop() { + super.stop() + player ?: return + player.removeAttribute(ATTRIBUTE_CUTSCENE) + player.removeAttribute(ATTRIBUTE_CUTSCENE_STAGE) + player.properties.isSafeZone = false + player.properties.safeRespawn = ServerConstants.HOME_LOCATION + player.interfaceManager.restoreTabs() + player.unlock() + clearNPCs() + player.unhook(CUTSCENE_DEATH_HOOK) + player.logoutListeners.remove("cutscene") + AntiMacro.unpause(player) + PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 0)) + try { + endActions?.invoke() + } catch (e: Exception) { + log(this::class.java, Log.ERR, "There's some bad nasty code in ${this::class.java.simpleName} end actions!") + e.printStackTrace() + } + } + }) + } + + /** + * Moves the camera to the specified regionX and regionY + * @param regionX the region-local X coordinate to move the camera to (0-63) + * @param regionY the region-local Y coordinate to move the camera to (0-63) + * @param height (optional) the height of the camera, defaults to 300. + * @param speed (optional) the speed of the camera transition, defaults to 100. + */ + fun moveCamera(regionX: Int, regionY: Int, height: Int = 300, speed: Int = 100) + { + val globalLoc = base.transform(regionX, regionY, 0) + camera.panTo(globalLoc.x, globalLoc.y, height, speed) + } + + /** + * Rotates the camera to face the given region-local X and Y coordinates + * @param regionX the region-local X coordinate to rotate the camera to (0-63) + * @param regionY the region-local Y coordinate to rotate the camera to (0-63) + * @param height (optional) the height of the camera, defaults to 300. + * @param speed (optional) the speed of the camera transition, defaults to 100. + */ + fun rotateCamera(regionX: Int, regionY: Int, height: Int = 300, speed: Int = 100) + { + val globalLoc = base.transform(regionX, regionY, 0) + camera.rotateTo(globalLoc.x, globalLoc.y, height, speed) + } + + /** + * Rotates the camera to face the given difference of the X and Y coordinates + * @param regionX the difference X value to rotate the camera to (0-63) + * @param regionY the difference Y value to rotate the camera to (0-63) + * @param height (optional) the height of the camera, defaults to 300. + * @param speed (optional) the speed of the camera transition, defaults to 100. + */ + fun rotateCameraBy(diffX: Int, diffY: Int, diffHeight: Int = 300, diffSpeed: Int = 100) + { + camera.rotateBy(diffX, diffY, diffHeight, diffSpeed) + } + + /** + * Manipulates the camera using different camera types. Also known as "shake" + * @param cameraType the "type" of shake: TRUCK, PEDESTAL, DOLLY, PAN, TILT + * @param jitter (optional) the amount to rock the camera while looping + * @param amplitude (optional) the maximum extent of camera vibration + * @param frequency (optional) the rate at which jitter and amplitude are repeated + * @param speed (optional) the rate at which the whole camera "shake" loop is repeated + * + * WARNING: Playing around with camera shake values may potentially trigger seizures for people with photosensitive epilepsy. + * Please use care when using the "shake" camera values. + */ + fun shakeCamera(cameraType: CameraShakeType, jitter: Int = 0, amplitude: Int = 0, frequency: Int = 128, speed: Int = 2) + { + camera.shake(cameraType.ordinal, jitter, amplitude, frequency, speed) + } + + /** + * Resets the camera to the current player position + */ + fun resetCamera() + { + camera.reset() + } + + /** + * Sets the location the player is placed at when the cutscene ends. + */ + fun setExit(location: Location) + { + exitLocation = location + } + + private fun loadCurrentStage() + { + if(ended) return + runStage(player.getCutsceneStage()) + } + + /** + * Increments the player's stage attribute by 1 + */ + fun incrementStage() + { + setAttribute(player, ATTRIBUTE_CUTSCENE_STAGE, player.getCutsceneStage() + 1) + loadCurrentStage() + } + + /** + * Sets the player's stage attribute to a new stage + */ + fun updateStage(newStage: Int) + { + setAttribute(player, ATTRIBUTE_CUTSCENE_STAGE, newStage) + loadCurrentStage() + } + + fun logCutscene(message: String) + { + if(ServerConstants.LOG_CUTSCENE) + log(this::class.java, Log.FINE, "$message") + } + + fun clearNPCs() { + for(entry in addedNPCs.entries) + { + logCutscene("Clearing ${entry.value.size} NPCs with ID ${entry.key} for ${player.username}.") + for(npc in entry.value) npc.clear() + } + addedNPCs.clear() + } + + companion object { + const val ATTRIBUTE_CUTSCENE = "cutscene" + const val ATTRIBUTE_CUTSCENE_STAGE = "cutscene:stage" + object CUTSCENE_DEATH_HOOK : EventHook + { + override fun process(entity: Entity, event: SelfDeathEvent) { + if(entity !is Player) return + entity.getCutscene()?.end() ?: entity.unhook(this) + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/activity/CutscenePlugin.java b/Server/src/main/core/game/activity/CutscenePlugin.java new file mode 100644 index 0000000..043b7c1 --- /dev/null +++ b/Server/src/main/core/game/activity/CutscenePlugin.java @@ -0,0 +1,337 @@ +package core.game.activity; + +import core.game.component.Component; +import core.game.node.entity.Entity; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.build.DynamicRegion; +import core.net.packet.PacketRepository; +import core.net.packet.context.MinimapStateContext; +import core.net.packet.out.MinimapState; +import core.plugin.PluginManifest; +import core.plugin.PluginType; + +import java.util.ArrayList; +import java.util.List; + +/** + * Represents the plugin used to handle a cutscene. + * @author Vexia + * @date 28/12/2013 + */ +@PluginManifest(type = PluginType.ACTIVITY) +public abstract class CutscenePlugin extends ActivityPlugin { + + /** + * The list of tabs to remove. + */ + private static final int[] TABS = new int[] { 0, 1, 2, 3, 4, 5, 6, 11, 12 }; + + /** + * The npcs in our cutscene. + */ + protected final List npcs = new ArrayList<>(100); + + /** + * The start pulse used for effect. + */ + private final StartPulse startPulse = new StartPulse(); + + /** + * The ending pulse used for effect. + */ + private final EndPulse endPulse = new EndPulse(); + + /** + * If we should use a fade in or not. + */ + private final boolean fade; + + /** + * Constructs a new {@code CutscenePlugin} {@code Object}. + * @param name the name of the cutscene/mapzone. + * @param fade fading in or not. + */ + public CutscenePlugin(String name, final boolean fade) { + super(name, true, false, true); + this.fade = fade; + } + + /** + * Constructs a new {@code CutscenePlugin} {@code Object}. + * @param name the name. + */ + public CutscenePlugin(final String name) { + this(name, true); + } + + @Override + public boolean start(final Player player, boolean login, Object... args) { + player.setAttribute("cutscene:original-loc", player.getLocation()); + player.removeAttribute("real-end"); + player.setAttribute("real-end", player.getLocation()); + if (isFade()) { + GameWorld.getPulser().submit(getStartPulse()); + } else { + PacketRepository.send(MinimapState.class, new MinimapStateContext(player, getMapState())); + player.getInterfaceManager().removeTabs(getRemovedTabs()); + player.getProperties().setTeleportLocation(getStartLocation()); + player.unlock(); + player.getWalkingQueue().reset(); + player.getLocks().lockMovement(1000000); + player.getInterfaceManager().close(); + open(); + } + player.lock(); + return super.start(player, login, args); + } + + @SuppressWarnings("deprecation") + @Override + public boolean leave(final Entity e, boolean logout) { + if (player != null) { + if (logout) { + player.setLocation(player.getAttribute("cutscene:original-loc", player.getLocation())); + end(); + } else { + unpause(); + } + player.unlock(); + player.getInterfaceManager().openDefaultTabs(); + player.getWalkingQueue().reset(); + player.getLocks().unlockMovement(); + } + return super.leave(e, logout); + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + /** + * Method used to stop the cutscene. + * @param fade if we should use a fade cutout. + */ + public void stop(boolean fade) { + if (fade) { + GameWorld.getPulser().submit(endPulse); + } else { + end(); + } + } + + /** + * Method used to end the cutscene. + */ + public void end() { + if (region != null) { + for (int i = 0; i < region.getPlanes().length; i++) { + for (NPC n : region.getPlanes()[i].getNpcs()) { + if (n == null) { + continue; + } + n.clear(); + } + } + } + PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 0)); + player.getInterfaceManager().restoreTabs(); + player.unlock();// incase he was locked. + player.getWalkingQueue().reset(); + } + + /** + * Represents the pulse used when starting a cutscene. This is used to give + * dramatic effect for entering a cutscene. In the future allow for this to + * be toggled. + * @author 'Vexia + * @date 30/12/2013 + */ + public class StartPulse extends Pulse { + + /** + * Represents the counter. + */ + private int counter = 0; + + /** + * Constructs a new {@code StartPulse} {@code Object}. + */ + public StartPulse() { + super(1, player); + } + + @Override + public boolean pulse() { + switch (counter++) { + case 1: + player.lock(); + player.getInterfaceManager().openOverlay(new Component(115)); + break; + case 3: + PacketRepository.send(MinimapState.class, new MinimapStateContext(player, getMapState())); + player.getInterfaceManager().removeTabs(getRemovedTabs()); + break; + case 4: + player.getProperties().setTeleportLocation(getStartLocation()); + break; + case 5: + player.getInterfaceManager().closeOverlay(); + player.getInterfaceManager().close(); + player.unlock(); + player.getWalkingQueue().reset(); + player.getLocks().lockMovement(1000000); + open(); + return true; + } + return false; + } + + } + + /** + * Represents the pulse used when ending a cutscene. This is used to give + * dramatic effect for entering a cutscene. + * @author 'Vexia + * @date 30/12/2013 + */ + public class EndPulse extends Pulse { + + /** + * Represents the counter. + */ + private int counter = 0; + + /** + * Constructs a new {@code EndPulse} {@code Object}. + */ + public EndPulse() { + super(1, player); + } + + @Override + public boolean pulse() { + switch (counter++) { + case 1: + player.lock(); + player.getInterfaceManager().openOverlay(new Component(115)); + break; + case 3: + PacketRepository.send(MinimapState.class, new MinimapStateContext(player, getMapState())); + player.getInterfaceManager().removeTabs(getRemovedTabs()); + break; + case 4: + Location loc = (Location) (player.getAttribute("real-end", player.getAttribute("cutscene:original-loc", player.getLocation()))); + player.getProperties().setTeleportLocation(loc); + break; + case 5: + end(); + stop(); + fade();// specfic for fadeout. + if (player.getSession().isActive()) { + PacketRepository.send(MinimapState.class, new MinimapStateContext(player, 0)); + } + player.getInterfaceManager().closeOverlay(); + if (player.getSession().isActive()) { + player.getInterfaceManager().close(); + } + player.getProperties().setSafeZone(false); + return true; + } + return false; + } + + } + + /** + * Method called when the dim interface is closed. And you can see the + * cutscene. + */ + public void open() { + + } + + /** + * Method called on the end of the cutscene. + */ + public void fade() { + + } + + /** + * Gets the mapstate to use. (override if needed). + * @return the state. + */ + public int getMapState() { + return 2; + } + + /** + * Gets the removed tabs. (override if needed). + * @return the tabs. + */ + public int[] getRemovedTabs() { + return TABS; + } + + /** + * Gets the starting location (region based, override if needed). + * @return the location. + */ + public Location getStartLocation() { + return getBase(); + } + + /** + * Method used to unpause this cutscene. + */ + public final void unpause() { + stop(true); + } + + /** + * Gets the player. + * @return The player. + */ + public Player getPlayer() { + return player; + } + + /** + * Gets the region. + * @return The region. + */ + public DynamicRegion getRegion() { + return region; + } + + /** + * Gets the nPCS. + * @return The nPCS. + */ + public List getNPCS() { + return npcs; + } + + /** + * Gets the fade. + * @return The fade. + */ + public boolean isFade() { + return fade; + } + + /** + * Gets the start pulse. + * @return the pulse. + */ + public Pulse getStartPulse() { + return startPulse; + } + + public Pulse getEndPulse(){return new EndPulse();} +} diff --git a/Server/src/main/core/game/bots/AIPBuilder.java b/Server/src/main/core/game/bots/AIPBuilder.java new file mode 100644 index 0000000..e79c954 --- /dev/null +++ b/Server/src/main/core/game/bots/AIPBuilder.java @@ -0,0 +1,1640 @@ +package core.game.bots; + +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.appearance.Gender; +import core.game.node.item.Item; +import core.game.world.map.Location; +import core.tools.RandomFunction; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Used for "building" artificial intelligent players. + * @author Emperor + */ +public final class AIPBuilder { + + /** + * Creates a new artificial intelligent player. + * @return The AIPlayer object. + */ + public static AIPlayer create(Location l) { + return new AIPlayer(l); + } + + /** + * Makes an artificial intelligent copy of the player. + * @param player The player. + * @return The artificial intelligent player with the same name, stats, + * items, etc. + */ + public static AIPlayer copy(Player player) { + return copy(player, player.getLocation()); + } + + /** + * Makes an artificial intelligent copy of the player. + * @param player The player. + * @param l The location the AIP should spawn on. + * @return The artificial intelligent player with the same name, stats, + * items, etc. + */ + public static AIPlayer copy(Player player, Location l) { + AIPlayer p = new AIPlayer(l); + p.getSkills().copy(player.getSkills()); + p.getInventory().copy(player.getInventory()); + p.getEquipment().copy(player.getEquipment()); + p.getBank().copy(player.getBank()); + p.getAppearance().copy(player.getAppearance()); + p.setControler(player); + return p; + } + + public static void RandomAfkPlayer(Location loc) + { + final AIPlayer bot = new AIPlayer(loc); + bot.getAppearance().setGender(RandomFunction.random(3) == 1 ? Gender.FEMALE : Gender.MALE); + + + + bot.getSkills().setStaticLevel(Skills.MAGIC, RandomFunction.getRandom(99)); + bot.getSkills().setStaticLevel(Skills.DEFENCE, RandomFunction.getRandom(99)); + bot.getSkills().setStaticLevel(Skills.ATTACK, RandomFunction.getRandom(99)); + bot.getSkills().setStaticLevel(Skills.STRENGTH, RandomFunction.getRandom(99)); + bot.getSkills().setStaticLevel(Skills.RANGE, RandomFunction.getRandom(99)); + bot.getSkills().setStaticLevel(Skills.HITPOINTS, RandomFunction.getRandom(99)); + + bot.getSkills().updateCombatLevel(); + bot.getAppearance().sync(); + + //set orientation? + } + + public static void immersiveSpawns() + { + //Edge + RandomAfkPlayer(new Location(3094, 3491)); + RandomAfkPlayer(new Location(3094, 3493)); + RandomAfkPlayer(new Location(3092, 3497)); + + //GE + RandomAfkPlayer(new Location(3160, 3492)); + RandomAfkPlayer(new Location(3161, 3491)); + RandomAfkPlayer(new Location(3165, 3483)); + RandomAfkPlayer(new Location(3168, 3485)); + RandomAfkPlayer(new Location(3165, 3485)); + RandomAfkPlayer(new Location(3164, 3493)); + + //Varrock Ge bank + RandomAfkPlayer(new Location(3189, 3439)); + + //Home Bank + RandomAfkPlayer(new Location(2099, 3918)); + } + + private List ITEMS = new ArrayList<>(Arrays.asList(new Item(286), //Orange goblin mail + + new Item(287), //Blue goblin mail + + new Item(288), //Goblin mail + + new Item(426), //Priest gown + + new Item(428), //Priest gown + + new Item(466), //Pickaxe handle + + new Item(492), //Picture + + new Item(542), //Monk's robe + + new Item(544), //Monk's robe + + new Item(546), //Shade robe + + new Item(548), //Shade robe + + new Item(552), //Ghostspeak amulet + + new Item(577), //Wizard robe + + new Item(579), //Wizard hat + + new Item(581), //Black robe + + new Item(599), //Picture + + new Item(667), //Blurite sword + + new Item(713), //Picture + + new Item(762), //Picture + + new Item(764), //Picture + + new Item(766), //Picture + + new Item(767), //Phoenix crossbow + + new Item(770), //Picture + + new Item(837), //Crossbow + + new Item(839), //Longbow + + new Item(841), //Shortbow + + new Item(843), //Oak shortbow + + new Item(845), //Oak longbow + + new Item(847), //Willow longbow + + new Item(849), //Willow shortbow + + new Item(851), //Maple longbow + + new Item(853), //Maple shortbow + + new Item(877), //Bronze bolts + + new Item(882), //Bronze arrow + + new Item(884), //Iron arrow + + new Item(886), //Steel arrow + + new Item(888), //Mithril arrow + + new Item(890), //Adamant arrow + + new Item(1005), //White apron + + new Item(1007), //Cape + + new Item(1009), //Brass necklace + + new Item(1011), //Blue skirt + + new Item(1013), //Pink skirt + + new Item(1015), //Black skirt + + new Item(1017), //Wizard hat + + new Item(1019), //Cape + + new Item(1021), //Cape + + new Item(1023), //Cape + + new Item(1027), //Cape + + new Item(1029), //Cape + + new Item(1031), //Cape + + new Item(1037), //Bunny ears + + new Item(1038), //Red partyhat + + new Item(1040), //Yellow partyhat + + new Item(1042), //Blue partyhat + + new Item(1044), //Green partyhat + + new Item(1046), //Purple partyhat + + new Item(1048), //White partyhat + + new Item(1050), //Santa hat + + new Item(1053), //Green h'ween mask + + new Item(1055), //Blue h'ween mask + + new Item(1057), //Red h'ween mask + + new Item(1059), //Leather gloves + + new Item(1061), //Leather boots + + new Item(1063), //Leather vambraces + + new Item(1065), //Green d'hide vamb + + new Item(1067), //Iron platelegs + + new Item(1069), //Steel platelegs + + new Item(1071), //Mithril platelegs + + new Item(1073), //Adamant platelegs + + new Item(1075), //Bronze platelegs + + new Item(1077), //Black platelegs + + new Item(1079), //Rune platelegs + + new Item(1081), //Iron plateskirt + + new Item(1083), //Steel plateskirt + + new Item(1085), //Mithril plateskirt + + new Item(1087), //Bronze plateskirt + + new Item(1089), //Black plateskirt + + new Item(1091), //Adamant plateskirt + + new Item(1093), //Rune plateskirt + + new Item(1095), //Leather chaps + + new Item(1097), //Studded chaps + + new Item(1099), //Green d'hide chaps + + new Item(1101), //Iron chainbody + + new Item(1103), //Bronze chainbody + + new Item(1105), //Steel chainbody + + new Item(1107), //Black chainbody + + new Item(1109), //Mithril chainbody + + new Item(1111), //Adamant chainbody + + new Item(1113), //Rune chainbody + + new Item(1115), //Iron platebody + + new Item(1117), //Bronze platebody + + new Item(1119), //Steel platebody + + new Item(1121), //Mithril platebody + + new Item(1123), //Adamant platebody + + new Item(1125), //Black platebody + + new Item(1127), //Rune platebody + + new Item(1129), //Leather body + + new Item(1131), //Hardleather body + + new Item(1133), //Studded body + + new Item(1135), //Green d'hide body + + new Item(1137), //Iron med helm + + new Item(1139), //Bronze med helm + + new Item(1141), //Steel med helm + + new Item(1143), //Mithril med helm + + new Item(1145), //Adamant med helm + + new Item(1147), //Rune med helm + + new Item(1151), //Black med helm + + new Item(1153), //Iron full helm + + new Item(1155), //Bronze full helm + + new Item(1157), //Steel full helm + + new Item(1159), //Mithril full helm + + new Item(1161), //Adamant full helm + + new Item(1163), //Rune full helm + + new Item(1165), //Black full helm + + new Item(1167), //Leather cowl + + new Item(1169), //Coif + + new Item(1171), //Wooden shield + + new Item(1173), //Bronze sq shield + + new Item(1175), //Iron sq shield + + new Item(1177), //Steel sq shield + + new Item(1179), //Black sq shield + + new Item(1181), //Mithril sq shield + + new Item(1183), //Adamant sq shield + + new Item(1185), //Rune sq shield + + new Item(1189), //Bronze kiteshield + + new Item(1191), //Iron kiteshield + + new Item(1193), //Steel kiteshield + + new Item(1195), //Black kiteshield + + new Item(1197), //Mithril kiteshield + + new Item(1199), //Adamant kiteshield + + new Item(1201), //Rune kiteshield + + new Item(1203), //Iron dagger + + new Item(1205), //Bronze dagger + + new Item(1207), //Steel dagger + + new Item(1209), //Mithril dagger + + new Item(1211), //Adamant dagger + + new Item(1213), //Rune dagger + + new Item(1217), //Black dagger + + new Item(1265), //Bronze pickaxe + + new Item(1267), //Iron pickaxe + + new Item(1269), //Steel pickaxe + + new Item(1271), //Adamant pickaxe + + new Item(1273), //Mithril pickaxe + + new Item(1275), //Rune pickaxe + + new Item(1277), //Bronze sword + + new Item(1279), //Iron sword + + new Item(1281), //Steel sword + + new Item(1283), //Black sword + + new Item(1285), //Mithril sword + + new Item(1287), //Adamant sword + + new Item(1289), //Rune sword + + new Item(1291), //Bronze longsword + + new Item(1293), //Iron longsword + + new Item(1295), //Steel longsword + + new Item(1297), //Black longsword + + new Item(1299), //Mithril longsword + + new Item(1301), //Adamant longsword + + new Item(1303), //Rune longsword + + new Item(1307), //Bronze 2h sword + + new Item(1309), //Iron 2h sword + + new Item(1311), //Steel 2h sword + + new Item(1313), //Black 2h sword + + new Item(1315), //Mithril 2h sword + + new Item(1317), //Adamant 2h sword + + new Item(1319), //Rune 2h sword + + new Item(1321), //Bronze scimitar + + new Item(1323), //Iron scimitar + + new Item(1325), //Steel scimitar + + new Item(1327), //Black scimitar + + new Item(1329), //Mithril scimitar + + new Item(1331), //Adamant scimitar + + new Item(1333), //Rune scimitar + + new Item(1335), //Iron warhammer + + new Item(1337), //Bronze warhammer + + new Item(1339), //Steel warhammer + + new Item(1341), //Black warhammer + + new Item(1343), //Mithril warhammer + + new Item(1345), //Adamant warhammer + + new Item(1347), //Rune warhammer + + new Item(1349), //Iron axe + + new Item(1351), //Bronze axe + + new Item(1353), //Steel axe + + new Item(1355), //Mithril axe + + new Item(1357), //Adamant axe + + new Item(1359), //Rune axe + + new Item(1361), //Black axe + + new Item(1363), //Iron battleaxe + + new Item(1365), //Steel battleaxe + + new Item(1367), //Black battleaxe + + new Item(1369), //Mithril battleaxe + + new Item(1371), //Adamant battleaxe + + new Item(1373), //Rune battleaxe + + new Item(1375), //Bronze battleaxe + + new Item(1379), //Staff + + new Item(1381), //Staff of air + + new Item(1383), //Staff of water + + new Item(1385), //Staff of earth + + new Item(1387), //Staff of fire + + new Item(1389), //Magic staff + + new Item(1419), //Scythe + + new Item(1420), //Iron mace + + new Item(1422), //Bronze mace + + new Item(1424), //Steel mace + + new Item(1426), //Black mace + + new Item(1428), //Mithril mace + + new Item(1430), //Adamant mace + + new Item(1432), //Rune mace + + new Item(1478), //Amulet of accuracy + + new Item(1540), //Anti-dragon shield + + new Item(1589), //Picture + + new Item(1635), //Gold ring + + new Item(1637), //Sapphire ring + + new Item(1639), //Emerald ring + + new Item(1641), //Ruby ring + + new Item(1643), //Diamond ring + + new Item(1654), //Gold necklace + + new Item(1656), //Sapphire necklace + + new Item(1658), //Emerald necklace + + new Item(1660), //Ruby necklace + + new Item(1662), //Diamond necklace + + new Item(1692), //Gold amulet + + new Item(1694), //Sapphire amulet + + new Item(1696), //Emerald amulet + + new Item(1698), //Ruby amulet + + new Item(1700), //Diamond amulet + + new Item(1716), //Unblessed symbol + + new Item(1718), //Holy symbol + + new Item(1725), //Amulet of strength + + new Item(1727), //Amulet of magic + + new Item(1729), //Amulet of defence + + new Item(1731), //Amulet of power + + new Item(1757), //Brown apron + + new Item(1949), //Chef's hat + + new Item(2402), //Silverlight + + new Item(2420), //Picture + + new Item(2422), //Blue partyhat + + new Item(2425), //Picture + + new Item(2480), //Picture + + new Item(2512), //Picture + + new Item(2513), //Dragon chainbody + + new Item(2583), //Black platebody (t) + + new Item(2585), //Black platelegs (t) + + new Item(2587), //Black full helm(t) + + new Item(2589), //Black kiteshield (t) + + new Item(2591), //Black platebody (g) + + new Item(2593), //Black platelegs (g) + + new Item(2595), //Black full helm(g) + + new Item(2597), //Black kiteshield (g) + + new Item(2599), //Adam platebody (t) + + new Item(2601), //Adam platelegs (t) + + new Item(2603), //Adam kiteshield (t) + + new Item(2605), //Adam full helm(t) + + new Item(2607), //Adam platebody (g) + + new Item(2609), //Adam platelegs (g) + + new Item(2611), //Adam kiteshield (g) + + new Item(2613), //Adam full helm(g) + + new Item(2615), //Rune platebody (g) + + new Item(2617), //Rune platelegs (g) + + new Item(2619), //Rune full helm(g) + + new Item(2621), //Rune kiteshield (g) + + new Item(2623), //Rune platebody (t) + + new Item(2625), //Rune platelegs (t) + + new Item(2627), //Rune full helm (t) + + new Item(2629), //Rune kiteshield (t) + + new Item(2653), //Zamorak platebody + + new Item(2655), //Zamorak platelegs + + new Item(2657), //Zamorak full helm + + new Item(2659), //Zamorak kiteshield + + new Item(2661), //Saradomin platebody + + new Item(2663), //Saradomin platelegs + + new Item(2665), //Saradomin full helm + + new Item(2667), //Saradomin kiteshield + + new Item(2669), //Guthix platebody + + new Item(2671), //Guthix platelegs + + new Item(2673), //Guthix full helm + + new Item(2675), //Guthix kiteshield + + new Item(2902), //Gloves + + new Item(2912), //Gloves + + new Item(2922), //Gloves + + new Item(2932), //Gloves + + new Item(2942), //Gloves + + new Item(3057), //Mime mask + + new Item(3058), //Mime top + + new Item(3059), //Mime legs + + new Item(3060), //Mime gloves + + new Item(3061), //Mime boots + + new Item(3472), //Black plateskirt (t) + + new Item(3473), //Black plateskirt (g) + + new Item(3474), //Adam plateskirt (t) + + new Item(3475), //Adam plateskirt (g) + + new Item(3476), //Rune plateskirt (g) + + new Item(3477), //Rune plateskirt (t) + + new Item(3478), //Zamorak plateskirt + + new Item(3479), //Saradomin plateskirt + + new Item(3480), //Guthix plateskirt + + new Item(3667), //Picture + + new Item(4000), //Picture + + new Item(4076), //Picture + + new Item(4178), //Abyssal whip + + new Item(4180), //Dragon platelegs + + new Item(4315), //Team-1 cape + + new Item(4317), //Team-2 cape + + new Item(4319), //Team-3 cape + + new Item(4321), //Team-4 cape + + new Item(4323), //Team-5 cape + + new Item(4325), //Team-6 cape + + new Item(4327), //Team-7 cape + + new Item(4329), //Team-8 cape + + new Item(4331), //Team-9 cape + + new Item(4333), //Team-10 cape + + new Item(4335), //Team-11 cape + + new Item(4337), //Team-12 cape + + new Item(4339), //Team-13 cape + + new Item(4341), //Team-14 cape + + new Item(4343), //Team-15 cape + + new Item(4345), //Team-16 cape + + new Item(4347), //Team-17 cape + + new Item(4349), //Team-18 cape + + new Item(4351), //Team-19 cape + + new Item(4353), //Team-20 cape + + new Item(4355), //Team-21 cape + + new Item(4357), //Team-22 cape + + new Item(4359), //Team-23 cape + + new Item(4361), //Team-24 cape + + new Item(4363), //Team-25 cape + + new Item(4365), //Team-26 cape + + new Item(4367), //Team-27 cape + + new Item(4369), //Team-28 cape + + new Item(4371), //Team-29 cape + + new Item(4373), //Team-30 cape + + new Item(4375), //Team-31 cape + + new Item(4377), //Team-32 cape + + new Item(4379), //Team-33 cape + + new Item(4381), //Team-34 cape + + new Item(4383), //Team-35 cape + + new Item(4385), //Team-36 cape + + new Item(4387), //Team-37 cape + + new Item(4389), //Team-38 cape + + new Item(4391), //Team-39 cape + + new Item(4393), //Team-40 cape + + new Item(4395), //Team-41 cape + + new Item(4397), //Team-42 cape + + new Item(4399), //Team-43 cape + + new Item(4401), //Team-44 cape + + new Item(4403), //Team-45 cape + + new Item(4405), //Team-46 cape + + new Item(4407), //Team-47 cape + + new Item(4409), //Team-48 cape + + new Item(4411), //Team-49 cape + + new Item(4413), //Team-50 cape + + new Item(4565), //Basket of eggs + + new Item(4566), //Rubber chicken + + new Item(5525), //Tiara + + new Item(5527), //Air tiara + + new Item(5529), //Mind tiara + + new Item(5531), //Water tiara + + new Item(5533), //Body tiara + + new Item(5535), //Earth tiara + + new Item(5537), //Fire tiara + + new Item(6180), //Lederhosen top + + new Item(6181), //Lederhosen shorts + + new Item(6182), //Lederhosen hat + + new Item(6184), //Prince tunic + + new Item(6185), //Prince leggings + + new Item(6186), //Princess blouse + + new Item(6187), //Princess skirt + + new Item(6188), //Frog mask + + new Item(6201), //Picture + + new Item(6203), //Picture + + new Item(6205), //Picture + + new Item(6207), //Picture + + new Item(6208), //Man speak amulet + + new Item(6210), //Picture + + new Item(6381), //Picture + + new Item(6654), //Camo top + + new Item(6655), //Camo bottoms + + new Item(6656), //Camo helmet + + new Item(6659), //Camo helmet + + new Item(6856), //Bobble hat + + new Item(6857), //Bobble scarf + + new Item(6858), //Jester hat + + new Item(6859), //Jester scarf + + new Item(6860), //Tri-jester hat + + new Item(6861), //Tri-jester scarf + + new Item(6862), //Woolly hat + + new Item(6863), //Woolly scarf + + new Item(6864), //Marionette handle + + new Item(6967), //Dragon med helm + + new Item(7332), //Black shield(h1) + + new Item(7334), //Adamant shield(h1) + + new Item(7336), //Rune shield(h1) + + new Item(7338), //Black shield(h2) + + new Item(7340), //Adamant shield(h2) + + new Item(7342), //Rune shield(h2) + + new Item(7344), //Black shield(h3) + + new Item(7346), //Adamant shield(h3) + + new Item(7348), //Rune shield(h3) + + new Item(7350), //Black shield(h4) + + new Item(7352), //Adamant shield(h4) + + new Item(7354), //Rune shield(h4) + + new Item(7356), //Black shield(h5) + + new Item(7358), //Adamant shield(h5) + + new Item(7360), //Rune shield(h5) + + new Item(7362), //Studded body (g) + + new Item(7364), //Studded body (t) + + new Item(7366), //Studded chaps (g) + + new Item(7368), //Studded chaps (t) + + new Item(7370), //D'hide body(g) + + new Item(7372), //D'hide body (t) + + new Item(7378), //D'hide chaps (g) + + new Item(7380), //D'hide chaps (t) + + new Item(7386), //Blue skirt (g) + + new Item(7388), //Blue skirt (t) + + new Item(7390), //Wizard robe (g) + + new Item(7392), //Wizard robe (t) + + new Item(7394), //Wizard hat (g) + + new Item(7396), //Wizard hat (t) + + new Item(7414), //Paddle + + new Item(7592), //Zombie shirt + + new Item(7593), //Zombie trousers + + new Item(7594), //Zombie mask + + new Item(7595), //Zombie gloves + + new Item(7596), //Zombie boots + + new Item(7672), //Picture + + new Item(7674), //Perfect + + new Item(7803), //Yin yang amulet + + new Item(7927), //Easter ring + + new Item(9005), //Fancy boots + + new Item(9006), //Fighting boots + + new Item(9013), //Skull sceptre + + new Item(9054), //Red goblin mail + + new Item(9056), //Yellow goblin mail + + new Item(9057), //Green goblin mail + + new Item(9058), //Purple goblin mail + + new Item(9059), //Pink goblin mail + + new Item(9665), //Torch + + new Item(9702), //Stick + + new Item(9703), //Training sword + + new Item(9704), //Training shield + + new Item(9705), //Training bow + + new Item(9706), //Training arrows + + new Item(9906), //Ghost buster 500 + + new Item(9907), //Ghost buster 500 + + new Item(9908), //Ghost buster 500 + + new Item(9909), //Ghost buster 500 + + new Item(9910), //Ghost buster 500 + + new Item(9911), //Ghost buster 500 + + new Item(9920), //Jack lantern mask + + new Item(9921), //Skeleton boots + + new Item(9922), //Skeleton gloves + + new Item(9923), //Skeleton leggings + + new Item(9924), //Skeleton shirt + + new Item(9925), //Skeleton mask + + new Item(10280), //Willow comp bow + + new Item(10286), //Rune helm (h1) + + new Item(10288), //Rune helm (h2) + + new Item(10290), //Rune helm (h3) + + new Item(10292), //Rune helm (h4) + + new Item(10294), //Rune helm (h5) + + new Item(10296), //Adamant helm (h1) + + new Item(10298), //Adamant helm (h2) + + new Item(10300), //Adamant helm (h3) + + new Item(10302), //Adamant helm (h4) + + new Item(10304), //Adamant helm (h5) + + new Item(10306), //Black helm (h1) + + new Item(10308), //Black helm (h2) + + new Item(10310), //Black helm (h3) + + new Item(10312), //Black helm (h4) + + new Item(10314), //Black helm (h5) + + new Item(10364), //Strength amulet(t) + + new Item(10366), //Amulet of magic(t) + + new Item(10501), //Snowball + + new Item(10507), //Reindeer hat + + new Item(10567), //Picture + + new Item(10569), //Picture + + new Item(10571), //Picture + + new Item(10573), //Picture + + new Item(10575), //Picture + + new Item(10577), //Picture + + new Item(10579), //Picture + + new Item(10629), //Mime mask + + new Item(10630), //Princess blouse + + new Item(10631), //Zombie shirt + + new Item(10632), //Camo top + + new Item(10633), //Lederhosen top + + new Item(10634), //Shade robe + + new Item(10665), //Black shield(h1) + + new Item(10666), //Adamant shield(h1) + + new Item(10667), //Rune shield(h1) + + new Item(10668), //Black shield(h2) + + new Item(10669), //Adamant shield(h2) + + new Item(10670), //Rune shield(h2) + + new Item(10671), //Black shield(h3) + + new Item(10672), //Adamant shield(h3) + + new Item(10673), //Rune shield(h3) + + new Item(10674), //Black shield(h4) + + new Item(10675), //Adamant shield(h4) + + new Item(10676), //Rune shield(h4) + + new Item(10677), //Black shield(h5) + + new Item(10678), //Adamant shield(h5) + + new Item(10679), //Rune shield(h5) + + new Item(10680), //Studded body (g) + + new Item(10681), //Studded body (t) + + new Item(10682), //D'hide body(g) + + new Item(10683), //D'hide body (t) + + new Item(10686), //Wizard robe (g) + + new Item(10687), //Wizard robe (t) + + new Item(10690), //Black platebody (t) + + new Item(10691), //Black platebody (g) + + new Item(10697), //Adam platebody (t) + + new Item(10698), //Adam platebody (g) + + new Item(10699), //Black helm (h1) + + new Item(10700), //Black helm (h2) + + new Item(10701), //Black helm (h3) + + new Item(10702), //Black helm (h4) + + new Item(10703), //Black helm (h5) + + new Item(10704), //Rune helm (h1) + + new Item(10705), //Rune helm (h2) + + new Item(10706), //Rune helm (h3) + + new Item(10707), //Rune helm (h4) + + new Item(10708), //Rune helm (h5) + + new Item(10709), //Adamant helm (h1) + + new Item(10710), //Adamant helm (h2) + + new Item(10711), //Adamant helm (h3) + + new Item(10712), //Adamant helm (h4) + + new Item(10713), //Adamant helm (h5) + + new Item(10736), //Strength amulet(t) + + new Item(10738), //Amulet of magic(t) + + new Item(10776), //Zamorak platebody + + new Item(10778), //Saradomin plate + + new Item(10780), //Guthix platebody + + new Item(10798), //Rune platebody (g) + + new Item(10800), //Rune platebody (t) + + new Item(11019), //Chicken feet + + new Item(11020), //Chicken wings + + new Item(11021), //Chicken head + + new Item(11022), //Chicken legs + + new Item(11165), //Phoenix crossbow + + new Item(11167), //Phoenix crossbow + + new Item(11789), //Grim reaper hood + + new Item(11790), //Grim reaper hood + + new Item(11951), //Snowball + + new Item(12629), //Safety gloves + + new Item(12634), //Chocatrice cape + + new Item(12645), //Chocatrice cape + + new Item(12844), //Toy kite + + new Item(12845), //Stone of power + + new Item(12846), //Stone of power + + new Item(12847), //Stone of power + + new Item(12848), //Stone of power + + new Item(12849), //Stone of power + + new Item(12860), //Swordfish gloves + + new Item(12863), //Air runecrafting gloves + + new Item(12864), //Water runecrafting gloves + + new Item(12865), //Earth runecrafting gloves + + new Item(12887), //Druidic mage hood 100 + + new Item(12888), //Druidic mage hood 80 + + new Item(12889), //Druidic mage hood 60 + + new Item(12890), //Druidic mage hood 40 + + new Item(12891), //Druidic mage hood 20 + + new Item(12892), //Druidic mage hood 0 + + new Item(12894), //Druidic mage top 100 + + new Item(12895), //Druidic mage top 80 + + new Item(12896), //Druidic mage top 60 + + new Item(12897), //Druidic mage top 40 + + new Item(12898), //Druidic mage top 20 + + new Item(12899), //Druidic mage top 0 + + new Item(12901), //Druidic mage bottom 100 + + new Item(12902), //Druidic mage bottom 80 + + new Item(12903), //Druidic mage bottom 60 + + new Item(12904), //Druidic mage bottom 40 + + new Item(12905), //Druidic mage bottom 20 + + new Item(12906), //Druidic mage bottom 0 + + new Item(12908), //Adamant spikeshield 100 + + new Item(12909), //Adamant spikeshield 80 + + new Item(12910), //Adamant spikeshield 60 + + new Item(12911), //Adamant spikeshield 40 + + new Item(12912), //Adamant spikeshield 20 + + new Item(12913), //Adamant spikeshield 0 + + new Item(12915), //Adamant berserker shield 100 + + new Item(12916), //Adamant berserker shield 80 + + new Item(12917), //Adamant berserker shield 60 + + new Item(12918), //Adamant berserker shield 40 + + new Item(12919), //Adamant berserker shield 20 + + new Item(12920), //Adamant berserker shield 0 + + new Item(12922), //Rune spikeshield 100 + + new Item(12923), //Rune spikeshield 80 + + new Item(12924), //Rune spikeshield 60 + + new Item(12925), //Rune spikeshield 40 + + new Item(12926), //Rune spikeshield 20 + + new Item(12927), //Rune spikeshield 0 + + new Item(12929), //Rune berserker shield 100 + + new Item(12930), //Rune berserker shield 80 + + new Item(12931), //Rune berserker shield 60 + + new Item(12932), //Rune berserker shield 40 + + new Item(12933), //Rune berserker shield 20 + + new Item(12934), //Rune berserker shield 0 + + new Item(12936), //Green d'hide coif 100 + + new Item(12937), //Green d'hide coif 80 + + new Item(12938), //Green d'hide coif 60 + + new Item(12939), //Green d'hide coif 40 + + new Item(12940), //Green d'hide coif 20 + + new Item(12941), //Green d'hide coif 0 + + new Item(12964), //Combat hood 100 + + new Item(12965), //Combat hood 80 + + new Item(12966), //Combat hood 60 + + new Item(12967), //Combat hood 40 + + new Item(12968), //Combat hood 20 + + new Item(12969), //Combat hood 0 + + new Item(12971), //Combat robe top 100 + + new Item(12972), //Combat robe top 80 + + new Item(12973), //Combat robe top 60 + + new Item(12974), //Combat robe top 40 + + new Item(12975), //Combat robe top 20 + + new Item(12976), //Combat robe top 0 + + new Item(12978), //Combat robe bottom 100 + + new Item(12979), //Combat robe bottom 80 + + new Item(12980), //Combat robe bottom 60 + + new Item(12981), //Combat robe bottom 40 + + new Item(12982), //Combat robe bottom 20 + + new Item(12983), //Combat robe bottom 0 + + new Item(12985), //Bronze gauntlets + + new Item(12986), //Worn-out bronze gauntlets + + new Item(12988), //Iron gauntlets + + new Item(12989), //Worn-out iron gauntlets + + new Item(12991), //Steel gauntlets + + new Item(12992), //Worn-out steel gauntlets + + new Item(12994), //Black gauntlets + + new Item(12995), //Worn-out black gauntlets + + new Item(12997), //Mithril gauntlets + + new Item(12998), //Worn-out mithril gauntlets + + new Item(13000), //Adamant gauntlets + + new Item(13001), //Worn-out adamant gauntlets + + new Item(13003), //Rune gauntlets + + new Item(13004), //Worn-out rune gauntlets + + new Item(13469), //Rune axe + + new Item(13471), //Rune battleaxe + + new Item(13473), //Rune warhammer + + new Item(13474), //Rune longsword + + new Item(13476), //Rune scimitar + + new Item(13480), //Rune pickaxe + + new Item(13482), //Rune platebody + + new Item(13483), //Green d'hide body + + new Item(13487), //Rune platelegs + + new Item(13489), //Rune plateskirt + + new Item(13491), //Green d'hide chaps + + new Item(13496), //Rune full helm + + new Item(13497), //Green d'hide vamb + + new Item(13507), //Rune kiteshield + + new Item(13523), //Maple longbow + + new Item(13524), //Maple shortbow + + new Item(13531), //Red partyhat + + new Item(13532), //Yellow partyhat + + new Item(13533), //Blue partyhat + + new Item(13534), //Green partyhat + + new Item(13535), //Purple partyhat + + new Item(13536), //White partyhat + + new Item(13537), //Santa hat + + new Item(13538), //Green h'ween mask + + new Item(13539), //Blue h'ween mask + + new Item(13540), //Red h'ween mask + + new Item(13541), //Willow comp bow + + new Item(13560), //Explorer's ring 1 + + new Item(13561), //Explorer's ring 2 + + new Item(13562), //Explorer's ring 3 + + new Item(13613), //Runecrafter hat + + new Item(13614), //Runecrafter robe + + new Item(13615), //Runecrafter hat + + new Item(13616), //Runecrafter hat + + new Item(13617), //Runecrafter skirt + + new Item(13618), //Runecrafter gloves + + new Item(13619), //Runecrafter robe + + new Item(13620), //Runecrafter hat + + new Item(13621), //Runecrafter hat + + new Item(13622), //Runecrafter skirt + + new Item(13623), //Runecrafter gloves + + new Item(13624), //Runecrafter robe + + new Item(13625), //Runecrafter hat + + new Item(13626), //Runecrafter hat + + new Item(13627), //Runecrafter skirt + + new Item(13628), //Runecrafter gloves + + new Item(13630), //Air talisman staff + + new Item(13631), //Mind talisman staff + + new Item(13632), //Water talisman staff + + new Item(13633), //Earth talisman staff + + new Item(13634), //Fire talisman staff + + new Item(13635), //Body talisman staff + + new Item(13643), //Yellow attractor + + new Item(13644), //Yellow repeller + + new Item(13645), //Green attractor + + new Item(13646), //Green repeller + + new Item(13657), //Runecrafter hat + + new Item(13658), //Runecrafter hat + + new Item(13765), //Rune dagger + + new Item(13777), //Rune sword + + new Item(13778), //Rune 2h sword + + new Item(13780), //Rune mace + + new Item(13781), //Rune chainbody + + new Item(13783), //Rune med helm + + new Item(13787), //Rune sq shield + + new Item(13800), //Rune platebody (g) + + new Item(13801), //Rune platelegs (g) + + new Item(13802), //Rune plateskirt (g) + + new Item(13803), //Rune full helm(g) + + new Item(13804), //Rune kiteshield (g) + + new Item(13805), //Rune platebody (t) + + new Item(13806), //Rune platelegs (t) + + new Item(13807), //Rune plateskirt (t) + + new Item(13808), //Rune full helm (t) + + new Item(13809), //Rune kiteshield (t) + + new Item(13820), //Zamorak platebody + + new Item(13821), //Zamorak platelegs + + new Item(13822), //Zamorak plateskirt + + new Item(13823), //Zamorak full helm + + new Item(13824), //Zamorak kiteshield + + new Item(13825), //Saradomin platebody + + new Item(13826), //Saradomin platelegs + + new Item(13827), //Saradomin plateskirt + + new Item(13828), //Saradomin full helm + + new Item(13829), //Saradomin kiteshield + + new Item(13830), //Guthix platebody + + new Item(13831), //Guthix platelegs + + new Item(13832), //Guthix plateskirt + + new Item(13833), //Guthix full helm + + new Item(13834), //Guthix kiteshield + + new Item(13958), //Corrupt dragon chainbody + + new Item(13960), //Corrupt dragon chainbody (deg) + + new Item(13961), //Corrupt dragon med helm + + new Item(13963), //Corrupt dragon med helm (deg) + + new Item(13964), //Corrupt dragon sq shield + + new Item(13966), //Corrupt dragon sq shield (deg) + + new Item(13967), //Corrupt dragon plateskirt + + new Item(13969), //Corrupt dragon plateskirt (deg) + + new Item(13970), //Corrupt dragon platelegs + + new Item(13972), //Corrupt dragon platelegs (deg) + + new Item(13973), //Corrupt dragon battleaxe + + new Item(13975), //C. dragon battleaxe (deg) + + new Item(13976), //Corrupt dragon dagger + + new Item(13978), //C. dragon dagger (deg) + + new Item(13979), //Corrupt dragon scimitar + + new Item(13981), //C. dragon scimitar (deg) + + new Item(13982), //Corrupt dragon longsword + + new Item(13984), //C. dragon longsword (deg) + + new Item(13985), //Corrupt dragon mace + + new Item(13987), //Corrupt dragon mace (deg) + + new Item(13988), //Corrupt dragon spear + + new Item(13990), //Corrupt dragon spear (deg) + + new Item(14057), //Broomstick + + new Item(14076), //Warlock top + + new Item(14077), //Warlock legs + + new Item(14078), //Witch top + + new Item(14079), //Witch skirt + + new Item(14080), //Witch cloak + + new Item(14081), //Warlock cloak + + new Item(14086), //Witch top + + new Item(14087), //Witch skirt + + new Item(14088), //Witch cloak + + new Item(14595), //Santa costume top + + new Item(14596), //Ice amulet + + new Item(14599), //Ice amulet + + new Item(14600), //Santa costume top + + new Item(14601), //Santa costume top + + new Item(14602), //Santa costume gloves + + new Item(14603), //Santa costume legs + + new Item(14604), //Santa costume legs + + new Item(14605), //Santa costume boots + + new Item(14812), //Black partyhat + + new Item(14819), //Rainbow partyhat + + new Item(14873), //Black santa hat + + new Item(14874)//Inverted santa hat + )); +} \ No newline at end of file diff --git a/Server/src/main/core/game/bots/AIPlayer.java b/Server/src/main/core/game/bots/AIPlayer.java new file mode 100644 index 0000000..079875d --- /dev/null +++ b/Server/src/main/core/game/bots/AIPlayer.java @@ -0,0 +1,578 @@ +package core.game.bots; + +import core.game.node.entity.impl.PulseType; +import core.ServerConstants; +import core.game.container.impl.EquipmentContainer; +import core.game.interaction.DestinationFlag; +import core.game.interaction.MovementPulse; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.info.PlayerDetails; +import core.game.node.entity.player.link.appearance.Gender; +import core.game.node.item.Item; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.map.path.Pathfinder; +import core.game.world.map.zone.impl.WildernessZone; +import core.game.world.repository.Repository; +import core.net.packet.context.MessageContext; +import core.tools.RandomFunction; +import core.tools.StringUtils; +import core.game.node.entity.skill.Skills; +import content.region.misc.tutisland.handlers.iface.CharacterDesign; + +import java.io.File; +import java.io.FileNotFoundException; +import java.util.*; + +/** + * Represents an Artificial Intelligent Player. + * + * @author Emperor + */ +public class AIPlayer extends Player { + + /** + * The current UID. + */ + private static int currentUID = 0x1; + + private static final List botNames = new ArrayList(); + + /** + * The active Artificial intelligent players mapping. + */ + private static final Map botMapping = new HashMap<>(); + + /** + * A line of data from namesandarmor.txt that will be used to generate the appearance + * Data in format: + * //name:cblevel:helmet:cape:neck:weapon:chest:shield:unknown:legs:unknown:gloves:boots: + */ + private static String OSRScopyLine; + + /** + * The AIP's UID. + */ + private final int uid; + + /** + * The start location of the AIP. + */ + private final Location startLocation; + + /** + * The username. + */ + private String username; + + /** + * The player controlling this AIP. + */ + private Player controler; + + + /** + * Constructs a new {@code AIPlayer} {@code Object}. + * + * @param l The location. + */ + static { + loadNames("botnames.txt"); + } + + public AIPlayer(Location l) { + this(getRandomName(), l, null); + } + + public AIPlayer(String fileName, Location l) { + this(retrieveRandomName(fileName), l, null); + } + + @SuppressWarnings("deprecation") + private AIPlayer(String name, Location l, String ignored) { + super(new PlayerDetails("/aip" + (currentUID + 1) + ":" + name)); + super.setLocation(startLocation = l); + super.artificial = true; + super.getDetails().setSession(ArtificialSession.getSingleton()); + Repository.getPlayers().add(this); + this.username = StringUtils.formatDisplayName(name + (currentUID + 1)); + this.uid = currentUID++; + this.updateRandomValues(); + this.init(); + } + + /** + * Generates bot stats/equipment/etc based on OSRScopyLine + */ + public void updateRandomValues() { + this.getAppearance().setGender(RandomFunction.random(5) == 1 ? Gender.FEMALE : Gender.MALE); + int setTo = RandomFunction.random(0,10); + CharacterDesign.randomize(this,true); + this.setDirection(Direction.values()[new Random().nextInt(Direction.values().length)]); //Random facing dir + this.getSkills().updateCombatLevel(); + this.getAppearance().sync(); + } + + @Override + public void update() { + return; + } + + private void setLevels() { + //Create realistic player stats + int maxLevel = RandomFunction.random(1, Math.min(parseOSRS(1), 99)); + for (int i = 0; i < Skills.NUM_SKILLS; i++) { + this.getSkills().setStaticLevel(i, RandomFunction.linearDecreaseRand(maxLevel)); + } + int combatLevelsLeft = parseOSRS(1); + int hitpoints = Math.max(RandomFunction.random(10, Math.min(maxLevel, combatLevelsLeft * 4)), 10); + combatLevelsLeft -= 0.25 * hitpoints; + int prayer = combatLevelsLeft > 0 ? RandomFunction.random(Math.min(maxLevel, combatLevelsLeft * 8)) : 1; + combatLevelsLeft -= 0.125 * prayer; + int defence = combatLevelsLeft > 0 ? RandomFunction.random(Math.min(maxLevel, combatLevelsLeft * 4)) : 1; + combatLevelsLeft -= 0.25 * defence; + + combatLevelsLeft = Math.min(combatLevelsLeft, 199); + + int attack = combatLevelsLeft > 0 ? RandomFunction.normalRandDist(Math.min(maxLevel, combatLevelsLeft * 3)) : 1; + int strength = combatLevelsLeft > 0 ? combatLevelsLeft * 3 - attack : 1; + + this.getSkills().setStaticLevel(Skills.HITPOINTS, hitpoints); + this.getSkills().setStaticLevel(Skills.PRAYER, prayer); + this.getSkills().setStaticLevel(Skills.DEFENCE, defence); + this.getSkills().setStaticLevel(Skills.ATTACK, attack); + this.getSkills().setStaticLevel(Skills.STRENGTH, strength); + this.getSkills().setStaticLevel(Skills.RANGE, combatLevelsLeft / 2); + this.getSkills().setStaticLevel(Skills.MAGIC, combatLevelsLeft / 2); + } + + private void giveArmor() { + //name:cblevel:helmet2:cape3:neck4:weapon5:chest6:shield7:unknown8:legs9:unknown10:gloves11:boots12: + //sicriona:103:1163: 1023: 1725 :1333: 1127 :1201 :0: 1079 :0: 2922: 1061:0: + equipIfExists(new Item(parseOSRS(2)), EquipmentContainer.SLOT_HAT); + equipIfExists(new Item(parseOSRS(3)), EquipmentContainer.SLOT_CAPE); + equipIfExists(new Item(parseOSRS(4)), EquipmentContainer.SLOT_AMULET); + equipIfExists(new Item(parseOSRS(5)), EquipmentContainer.SLOT_WEAPON); + equipIfExists(new Item(parseOSRS(6)), EquipmentContainer.SLOT_CHEST); + equipIfExists(new Item(parseOSRS(7)), EquipmentContainer.SLOT_SHIELD); + equipIfExists(new Item(parseOSRS(9)), EquipmentContainer.SLOT_LEGS); + equipIfExists(new Item(parseOSRS(11)), EquipmentContainer.SLOT_HANDS); + equipIfExists(new Item(parseOSRS(12)), EquipmentContainer.SLOT_FEET); + } + + private int parseOSRS(int index) { + return Integer.parseInt(OSRScopyLine.split(":")[index]); + } + + private void equipIfExists(Item e, int slot) { + if (e == null || e.getName().equalsIgnoreCase("null")) { + return; + } + if (e.getId() != 0) + getEquipment().replace(e, slot); + + } + + /** + * Load a list of bot names into memory + */ + public static void loadNames(String fileName){ + try { + Scanner sc = new Scanner(new File(ServerConstants.BOT_DATA_PATH + fileName)); + while (sc.hasNextLine()) { + botNames.add(sc.nextLine()); + } + } catch (Exception e){ + e.printStackTrace(); + } + } + + public static String getRandomName(){ + int index = (RandomFunction.random(botNames.size())); + String name = botNames.get(index); + botNames.remove(index); + return name; + } + + /** + * Get a bot content + */ + public static void updateRandomOSRScopyLine(String fileName) { + Random rand = new Random(); + int n = 0; + try { + for (Scanner sc = new Scanner(new File(ServerConstants.BOT_DATA_PATH + fileName)); sc.hasNext(); ) { + ++n; + String line = sc.nextLine(); + if (rand.nextInt(n) == 0) { //Chance of overwriting line is lower and lower + if (line.length() < 3 || line.startsWith("#")) //probably an empty line + { + continue; + } + OSRScopyLine = line; + } + } + } catch (FileNotFoundException e) { + + e.printStackTrace(); + } + } + + private static String retrieveRandomName(String fileName) { + do { + updateRandomOSRScopyLine(fileName); + } while (OSRScopyLine.startsWith("#") || OSRScopyLine.contains("_") || OSRScopyLine.contains(" ")); //Comment + return OSRScopyLine.split(":")[0]; + } + + private static String retrieveRandomName() { + return retrieveRandomName("namesandarmor.txt"); + } + + @Override + public void init() { + getProperties().setSpawnLocation(startLocation); + getInterfaceManager().openDefaultTabs(); + getSession().setObject(this); + botMapping.put(uid, this); + super.init(); + getSettings().setRunToggled(true); + CharacterDesign.randomize(this, false); + getPlayerFlags().setLastSceneGraph(location); + } + + /** + * Handles the following. + * + * @param e The entity to follow. + */ + public void follow(final Entity e) { + getPulseManager().run(new MovementPulse(this, e, DestinationFlag.FOLLOW_ENTITY) { + @Override + public boolean pulse() { + face(e); + return false; + } + }, PulseType.STANDARD); + } + + public void randomWalkAroundPoint(Location point, int radius) { + Pathfinder.find(this, point.transform(RandomFunction.random(radius, (radius * -1)), RandomFunction.random(radius, (radius * -1)), 0), true, Pathfinder.SMART).walk(this); + } + + public void randomWalk(int radiusX, int radiusY) { + Pathfinder.find(this, this.getLocation().transform(RandomFunction.random(radiusX, (radiusX * -1)), RandomFunction.random(radiusY, (radiusY * -1)), 0), false, Pathfinder.SMART).walk(this); + } + + public void walkToPosSmart(int x, int y) { + walkToPosSmart(new Location(x, y)); + } + + public void walkToPosSmart(Location loc) { + Pathfinder.find(this, loc, true, Pathfinder.SMART).walk(this); + } + + public void walkPos(int x, int y) { + Pathfinder.find(this, new Location(x, y)); + } + + public boolean checkVictimIsPlayer() { + if (this.getProperties().getCombatPulse().getVictim() != null) + if (this.getProperties().getCombatPulse().getVictim().isPlayer()) + return true; + return false; + } + + @Override + public void tick() { + super.tick(); + if(getSkullManager().isWilderness()) { + getSkullManager().setLevel(WildernessZone.getWilderness(this)); + } + if(getSkills().getLifepoints() <= 0){ + //deregister(this.uid); + + } + } + + public Item getItemById(int id) { + for (int i = 0; i < 28; i++) { + Item item = this.getInventory().get(i); + if (item != null) { + if (item.getId() == id) + return item; + } + } + return null; + } + + public void handleIncomingChat(MessageContext ctx){ + } + + + private ArrayList getNodeInRange(int range, int entry) { + int meX = this.getLocation().getX(); + int meY = this.getLocation().getY(); + ArrayList nodes = new ArrayList(); + for (NPC npc : RegionManager.getLocalNpcs(this, range)) { + if (npc.getId() == entry) + nodes.add(npc); + } + for (int x = 0; x < range; x++) { + for (int y = 0; y < range - x; y++) { + Node node = RegionManager.getObject(0, meX + x, meY + y); + if (node != null) + if (node.getId() == entry) + nodes.add(node); + Node node2 = RegionManager.getObject(0, meX + x, meY - y); + if (node2 != null) + if (node2.getId() == entry) + nodes.add(node2); + Node node3 = RegionManager.getObject(0, meX - x, meY + y); + if (node3 != null) + if (node3.getId() == entry) + nodes.add(node3); + Node node4 = RegionManager.getObject(0, meX - x, meY - y); + if (node4 != null) + if (node4.getId() == entry) + nodes.add(node4); + } + } + return nodes; + } + + private ArrayList getNodeInRange(int range, List entrys) { + int meX = this.getLocation().getX(); + int meY = this.getLocation().getY(); + //int meX2 = this.getLocation().getX(); + + ArrayList nodes = new ArrayList(); + for (NPC npc : RegionManager.getLocalNpcs(this, range)) { + if (entrys.contains(npc.getId())) + nodes.add(npc); + } + for (int x = 0; x < range; x++) { + for (int y = 0; y < range - x; y++) { + Node node = RegionManager.getObject(0, meX + x, meY + y); + if (node != null) + if (entrys.contains(node.getId())) + nodes.add(node); + Node node2 = RegionManager.getObject(0, meX + x, meY - y); + if (node2 != null) + if (entrys.contains(node2.getId())) + nodes.add(node2); + Node node3 = RegionManager.getObject(0, meX - x, meY + y); + if (node3 != null) + if (entrys.contains(node3.getId())) + nodes.add(node3); + Node node4 = RegionManager.getObject(0, meX - x, meY - y); + if (node4 != null) + if (entrys.contains(node4.getId())) + nodes.add(node4); + } + } + return nodes; + } + + public Node getClosestNodeWithEntryAndDirection(int range, int entry, Direction direction) { + ArrayList nodeList = getNodeInRange(range, entry); + if (nodeList.isEmpty()) { + + return null; + } + Node node = getClosestNodeinNodeListWithDirection(nodeList, direction); + return node; + } + + public Node getClosestNodeWithEntry(int range, int entry) { + ArrayList nodeList = getNodeInRange(range, entry); + if (nodeList.isEmpty()) { + + return null; + } + Node node = getClosestNodeinNodeList(nodeList); + return node; + } + + public Node getClosestNodeWithEntry(int range, List entrys) { + ArrayList nodeList = getNodeInRange(range, entrys); + if (nodeList.isEmpty()) { + + return null; + } + Node node = getClosestNodeinNodeList(nodeList); + return node; + } + + public Node getClosesCreature(int radius) { + int distance = radius + 1; + Node npcReturn = null; + for (NPC npc : RegionManager.getLocalNpcs(this, radius)) { + double distanceToNpc = npc.getLocation().getDistance(this.getLocation()); + if ((distanceToNpc) < distance) { + distance = (int) distanceToNpc; + npcReturn = npc; + } + } + return npcReturn; + } + + public Node getClosesCreature(int radius, int entry) { + int distance = radius + 1; + Node npcReturn = null; + for (NPC npc : RegionManager.getLocalNpcs(this, radius)) { + double distanceToNpc = npc.getLocation().getDistance(this.getLocation()); + if (npc.getId() == entry) { + if ((distanceToNpc) < distance) { + distance = (int) distanceToNpc; + npcReturn = npc; + } + } + } + return npcReturn; + } + + public Node getClosesCreature(int radius, ArrayList entrys) { + int distance = radius + 1; + Node npcReturn = null; + for (NPC npc : RegionManager.getLocalNpcs(this, radius)) { + double distanceToNpc = npc.getLocation().getDistance(this.getLocation()); + if (entrys.contains(npc.getId())) { + if ((distanceToNpc) < distance) { + distance = (int) distanceToNpc; + npcReturn = npc; + } + } + } + return npcReturn; + } + + private Node getClosestNodeinNodeListWithDirection(ArrayList nodes, Direction direction) { + if (nodes.isEmpty()) { + + return null; + } + + double distance = 0; + Node nodeReturn = null; + for (Node node : nodes) { + double nodeDistance = this.getLocation().getDistance(node.getLocation()); + if ((nodeReturn == null || nodeDistance < distance) && node.getDirection() == direction) { + distance = nodeDistance; + nodeReturn = node; + } + } + return nodeReturn; + } + + private Node getClosestNodeinNodeList(ArrayList nodes) { + if (nodes.isEmpty()) { + + return null; + } + + double distance = 0; + Node nodeReturn = null; + for (Node node : nodes) { + double nodeDistance = this.getLocation().getDistance(node.getLocation()); + if (nodeReturn == null || nodeDistance < distance) { + distance = nodeDistance; + nodeReturn = node; + } + } + return nodeReturn; + } + + @Override + public void clear() { + botMapping.remove(uid); + super.clear(); + } + + @Override + public void reset() { + if (getPlayerFlags().isUpdateSceneGraph()) { + getPlayerFlags().setLastSceneGraph(getLocation()); + } + super.reset(); + } + + @Override + public void finalizeDeath(Entity killer) { + super.finalizeDeath(killer); + fullRestore(); + } + + /** + * Gets the UID. + * + * @return the UID. + */ + public int getUid() { + return uid; + } + + /** + * Deregisters an AIP. + * + * @param uid The player's UID. + */ + public static void deregister(int uid) { + AIPlayer player = botMapping.get(uid); + if (player != null) { + player.clear(); + Repository.getPlayers().remove(player); + return; + } + //log(this.getClass(), Log.ERR, "Could not deregister AIP#" + uid + ": UID not added to the mapping!"); + } + + @Override + public String getUsername() { + return username; + } + + /** + * Gets the AIP for the given UID. + * + * @param uid The UID. + * @return The AIPlayer. + */ + public static AIPlayer get(int uid) { + return botMapping.get(uid); + } + + /** + * @return the startLocation. + */ + public Location getStartLocation() { + return startLocation; + } + + /** + * Gets the controler. + * + * @return The controler. + */ + public Player getControler() { + return controler; + } + + /** + * Sets the controler. + * + * @param controler The controler to set. + */ + public void setControler(Player controler) { + this.controler = controler; + } + + + public void interact(Node n) { + // InteractionPacket.handleObjectInteraction(this, 0, n.getLocation(), n.getId()); + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/bots/AIRepository.kt b/Server/src/main/core/game/bots/AIRepository.kt new file mode 100644 index 0000000..3faef51 --- /dev/null +++ b/Server/src/main/core/game/bots/AIRepository.kt @@ -0,0 +1,69 @@ +package core.game.bots + +import core.game.node.entity.player.Player +import core.game.node.item.GroundItem +import core.game.ge.GrandExchangeOffer +import content.global.bots.* + +/** + * A repository for bots to make use of that can contain any info that might be useful to them. + * @author Ceikry + */ +class AIRepository { + companion object { + val groundItems = HashMap>() + val GEOffers = HashMap() + + @JvmStatic + val PulseRepository = HashMap() // Lowercase username, pulse + + @JvmStatic + fun addItem(item: GroundItem){ + if(groundItems[item.dropper] == null){ + val list = ArrayList() + list.add(item) + groundItems[item.dropper] = list + return + } + groundItems[item.dropper]!!.add(item) + } + + @JvmStatic + fun getItems(player: Player): ArrayList?{ + return groundItems[player] + } + + @JvmStatic + fun addOffer(player: Player, offer: GrandExchangeOffer){ + GEOffers[player] = offer + } + + @JvmStatic + fun getOffer(player: Player): GrandExchangeOffer? { + return GEOffers[player] + } + + @JvmStatic fun clearAllBots() { + PulseRepository.toList().forEach { (_, it) -> + it.stop() + it.botScript.bot.clear() + AIPlayer.deregister((it.botScript.bot as AIPlayer).uid) + } + } + + @JvmStatic fun sendBotInfo (player: Player, bot: AIPlayer) { + val pulse = PulseRepository[bot.username.lowercase()] ?: return + bot.setAttribute("tracked", true) + player.debug("[Bot: ${bot.username}][${pulse.botScript::class.simpleName}]=================") + player.debug("PM Pulse Running? ${if(bot.pulseManager.hasPulseRunning()) bot.pulseManager.getCurrent()::class.java.name else "No"}") + player.debug("Interaction Running? ${bot.scripts.getActiveScript() != null} ${bot.scripts.getActiveScript()?.let { " : " + it.execution!!::class.java.name } ?: ""}") + player.debug("Botscript Running? ${pulse.botScript.running}") + player.debug("Random Delay? ${pulse.randomDelay}") + player.debug("Delayed? ${bot.scripts.delay}") + if (pulse.botScript is Adventurer) { + player.debug("State: ${pulse.botScript.state.name}") + } + player.debug("==========================================") + } + } +} diff --git a/Server/src/main/core/game/bots/ArtificialSession.java b/Server/src/main/core/game/bots/ArtificialSession.java new file mode 100644 index 0000000..81ef7dd --- /dev/null +++ b/Server/src/main/core/game/bots/ArtificialSession.java @@ -0,0 +1,53 @@ +package core.game.bots; + +import java.nio.ByteBuffer; + +import core.net.IoSession; + +/** + * Represents an artificial networking session. + * @author Emperor + */ +public final class ArtificialSession extends IoSession { + + /** + * The artificial session singleton. + */ + private static final ArtificialSession SINGLETON = new ArtificialSession(); + + /** + * Constructs a new {@code ArtificialSession} {@code Object}. + */ + private ArtificialSession() { + super(null, null); + } + + @Override + public String getRemoteAddress() { + return "127.0.0.1"; + } + + @Override + public void write(Object context, boolean instant) { + + } + + @Override + public void queue(ByteBuffer buffer) { + } + + @Override + public void write() { + } + + @Override + public void disconnect() { + } + + /** + * @return the singleton. + */ + public static ArtificialSession getSingleton() { + return SINGLETON; + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/bots/CombatBot.kt b/Server/src/main/core/game/bots/CombatBot.kt new file mode 100644 index 0000000..a5b5c67 --- /dev/null +++ b/Server/src/main/core/game/bots/CombatBot.kt @@ -0,0 +1,55 @@ +package core.game.bots + +import core.game.node.entity.player.link.appearance.Gender +import core.game.node.entity.player.link.prayer.PrayerType +import core.game.node.item.Item +import core.game.world.map.Direction +import core.game.world.map.Location +import core.tools.RandomFunction +import core.game.consumable.Consumable +import content.data.consumables.Consumables +import core.game.consumable.Food +import content.data.consumables.effects.HealingEffect +import core.game.node.entity.skill.Skills +import java.util.* + +class CombatBot(location: Location) : AIPlayer(location) { + var tick = 0 + + override fun updateRandomValues() { + appearance.gender = if (RandomFunction.random(5) == 1) Gender.FEMALE else Gender.MALE + setDirection(Direction.values()[Random().nextInt(Direction.values().size)]) //Random facing dir + skills.updateCombatLevel() + appearance.sync() + } + override fun tick() { + super.tick() + this.tick++ + + //Despawn + if (skills.lifepoints == 0) { + //CombatBotAssembler.produce(CombatBotAssembler.Type.RANGE, CombatBotAssembler.Tier.LOW,this.location) + deregister(uid) + } + } + + fun CheckPrayer(type: Array) { + for (i in type.indices) prayer.toggle(type[i]) + } + + fun eat(foodId: Int) { + val foodItem = Item(foodId) + if (skills.getStaticLevel(Skills.HITPOINTS) >= skills.lifepoints * 3 && inventory.containsItem(foodItem)) { + this.lock(3) + //this.animate(new Animation(829)); + val food = inventory.getItem(foodItem) + var consumable: Consumable? = Consumables.getConsumableById(food.id)?.consumable + if (consumable == null) { + consumable = Food(IntArray(food.id), HealingEffect(1)) + } + consumable.consume(food, this) + properties.combatPulse.delayNextAttack(3) + } + if (!checkVictimIsPlayer()) if (!inventory.contains(foodId, 1)) inventory.add(Item(foodId, 5)) //Add Food to Inventory + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/bots/CombatBotAssembler.kt b/Server/src/main/core/game/bots/CombatBotAssembler.kt new file mode 100644 index 0000000..ebbed14 --- /dev/null +++ b/Server/src/main/core/game/bots/CombatBotAssembler.kt @@ -0,0 +1,533 @@ +package core.game.bots + +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.world.map.Location +import core.tools.RandomFunction +import org.rs09.consts.Items +import java.util.* +import kotlin.collections.ArrayList + +/** + * Assembles combat-style bots, intended to replace PVMBotBuilder. + * @author Ceikry + */ +class CombatBotAssembler { + enum class Type{ + RANGE, + MAGE, + MELEE + } + enum class Tier{ + LOW, + MED, + HIGH, + PURE + } + + /** + * Produces a bot with the specified parameters. + * @param type the type of bot to produce. Melee, Ranged, or Mage. + * @param tier specifies the range of skills the bot can have, and thereby, the gear. LOW, MED, or HIGH. + * @param location the location that the bot spawns and respawns at. + * @return an AIPlayer with the specified values. + * @author Ceikry + */ + fun produce(type: Type, tier: Tier, location: Location): AIPlayer? { + return when (type) { + Type.RANGE -> assembleRangedBot(tier, location) + Type.MELEE -> assembleMeleeBot(tier,location) + Type.MAGE -> assembleMeleeBot(tier,location) + } + } + + /** + * Assembles a ranged bot with the specified values. + * @param tier the tier to use which defines skill ranges and gear. + * @param location the bot's spawn and respawn location + * @param crossbow (optional) whether or not this bot should use a crossbow + * @return a CombatBot with the specified values. + * @author Ceikry + */ + fun assembleRangedBot(tier: Tier, location: Location, crossbow: Boolean? = null): CombatBot { + val bot = CombatBot(location) + + generateStats(bot, tier, Skills.RANGE, Skills.DEFENCE) + gearRangedBot(bot, (crossbow ?: (Random().nextInt() % 2)) == 0) + return bot + } + + /** + * Assembles a melee bot with the specified values. + * @param tier the tier of the bot. Specifies levels and gear. + * @param location the spawn and respawn location of the bot. + * @return a CombatBot with the specified values. + * @author Ceikry + */ + fun assembleMeleeBot(tier: Tier, location: Location): CombatBot { + val bot = CombatBot(location) + + generateStats(bot, tier, Skills.ATTACK, Skills.STRENGTH, Skills.DEFENCE) + gearMeleeBot(bot) + return bot + } + + /** + * Assembles a melee bot with gear appropriate for killing dragons. + * @param tier the tier of the bot, specifying levels and gear. + * @param location the spawn and respawn location of the bot. + * @return a CombatBot suited for killing dragons. + * @author Kermit + */ + fun MeleeAdventurer(tier: Tier, location: Location): CombatBot { + val bot = CombatBot(location) + var max = 0 + val level = RandomFunction.random(25, 69).also {max = 99 } + generateStats(bot,tier,Skills.ATTACK, Skills.STRENGTH, Skills.DEFENCE) + bot.skills.setStaticLevel(Skills.HITPOINTS, level) + bot.skills.setStaticLevel(Skills.ATTACK, level + 5) + bot.skills.setStaticLevel(Skills.STRENGTH, level + 5) + bot.skills.setLevel(Skills.HITPOINTS, level) + bot.skills.setLevel(Skills.ATTACK, level + 5) + bot.skills.setLevel(Skills.STRENGTH, level + 5) + bot.skills.updateCombatLevel() + equipHighest(bot, MELEE_HELMS) + equipHighest(bot, MELEE_TOP) + equipHighest(bot, MELEE_LEG) + equipHighest(bot, MELEE_WEP) + equipHighest(bot, MELEE_SHIELD) + equipHighest(bot, CAPE) + equipHighest(bot, NNECK) + equipHighest(bot, NGLOVES) + equipHighest(bot, NBOOTS) + bot.equipment.refresh() + return bot + } + + /** + * Assembles a melee bot with gear appropriate for killing dragons. + * @param tier the tier of the bot, specifying levels and gear. + * @param location the spawn and respawn location of the bot. + * @return a CombatBot suited for killing dragons. + * @author Kermit + */ + fun RangeAdventurer(tier: Tier, location: Location): CombatBot { + val bot = CombatBot(location) + var max = 0 + val level = RandomFunction.random(35, 69).also {max = 75 } + generateStats(bot,tier,Skills.ATTACK, Skills.STRENGTH) + bot.skills.setStaticLevel(Skills.HITPOINTS, level) + bot.skills.setStaticLevel(Skills.DEFENCE, level) + bot.skills.setStaticLevel(Skills.RANGE, level + 10) + bot.skills.setLevel(Skills.HITPOINTS, level) + bot.skills.setLevel(Skills.DEFENCE, level) + bot.skills.setLevel(Skills.RANGE, level + 10) + bot.skills.updateCombatLevel() + equipHighest(bot,RANGE_HELMS,65) + equipHighest(bot,RANGE_TOPS,65) + equipHighest(bot,RANGE_LEGS,65) + equipHighest(bot,CROSSBOWS,50) + equipHighest(bot, CAPE) + equipHighest(bot, NRANGENECK) + equipHighest(bot, NRANGESHIELD) + equipHighest(bot, PCRANGE_BACK) + equipHighest(bot, NGLOVES) + equipHighest(bot, NRBOOTS) + bot.equipment.add(Item(Items.BRONZE_BOLTS_877,100000),13,false,false) + bot.equipment.refresh() + return bot + } + + /** + * Assembles a melee bot with gear appropriate for killing dragons. + * @param tier the tier of the bot, specifying levels and gear. + * @param location the spawn and respawn location of the bot. + * @return a CombatBot suited for killing dragons. + * @author Ceikry + */ + fun assembleMeleeDragonBot(tier: Tier, location: Location): CombatBot { + val bot = CombatBot(location) + generateStats(bot,tier,Skills.ATTACK, Skills.STRENGTH, Skills.DEFENCE) + equipHighest(bot, MELEE_HELMS, 50) + equipHighest(bot, MELEE_TOP, 40) + equipHighest(bot, MELEE_LEG, 40) + equipHighest(bot, MELEE_WEP, 60) + equipHighest(bot, CAPE) + equipHighest(bot, NGLOVES) + equipHighest(bot, NBOOTS) + bot.equipment.refresh() + return bot + } + + /** + * Assembles a ranged bot with gear appropriate for killing dragons. + * @param tier the tier of the bot, specifying levels and gear. + * @param location the spawn and respawn location of the bot. + * @return a CombatBot suited for killing dragons. + * @author Ceikry + */ + fun assembleRangeDragonBot(tier: Tier, location: Location): CombatBot { + val bot = CombatBot(location) + bot.fullRestore() + generateStats(bot,tier,Skills.RANGE,Skills.DEFENCE) + equipHighest(bot,RANGE_HELMS,50) + equipHighest(bot,RANGE_TOPS,50) + equipHighest(bot,RANGE_LEGS,50) + equipHighest(bot,CROSSBOWS,50) + equipHighest(bot, CAPE) + equipHighest(bot, NGLOVES) + equipHighest(bot, NRBOOTS) + bot.equipment.add(Item(Items.BRONZE_BOLTS_877,100000),13,false,false) + bot.equipment.refresh() + return bot + } + + /** + * Gears a ranged bot with the best gear for its stats. + * @param bot the bot to gear + * @param crossbow (optional) whether or not this bot should use a crossbow. Default is false. + * @author Ceikry + */ + fun gearRangedBot(bot: AIPlayer, crossbow: Boolean? = false) { + equipHighest(bot, RANGE_HELMS) + equipHighest(bot, RANGE_TOPS) + equipHighest(bot, RANGE_LEGS) + equipHighest(bot, CAPE) + equipHighest(bot, NGLOVES) + equipHighest(bot, NRBOOTS) + if(crossbow == true) { equipHighest(bot,CROSSBOWS); equipHighest(bot,MELEE_SHIELD); bot.equipment.add(Item(Items.BRONZE_BOLTS_877,Integer.MAX_VALUE),13,false,false) } + else {equipHighest(bot, BOWS); bot.equipment.add(Item(Items.BRONZE_ARROW_882,Integer.MAX_VALUE),13,false,false) } + bot.equipment.refresh() + } + + /** + * Gears a melee bot with the best gear for its stats. + * @param bot the bot to gear. + * @author Ceikry + */ + fun gearMeleeBot(bot: AIPlayer){ + equipHighest(bot, MELEE_HELMS) + equipHighest(bot, MELEE_LEG) + equipHighest(bot, MELEE_SHIELD) + equipHighest(bot, MELEE_TOP) + equipHighest(bot, CAPE) + equipHighest(bot, NGLOVES) + equipHighest(bot, NBOOTS) + equipHighest(bot, MELEE_WEP) + bot.equipment.refresh() + } + + /** + * Gears a Novice Pest control bot. + * @author Sir Kermit & Ceikry + */ + fun gearPCnRangedBot(bot: AIPlayer, crossbow: Boolean? = false, vararg skills: Int) { + var max = 0 + val level = RandomFunction.random(30, 70).also {max = 75 } + bot.fullRestore() + + bot.skills.setStaticLevel(Skills.RANGE, 50) + bot.skills.setStaticLevel(Skills.DEFENCE, 50) + bot.skills.setStaticLevel(Skills.ATTACK, level) + bot.skills.setStaticLevel(Skills.STRENGTH, level) + bot.skills.setStaticLevel(Skills.HITPOINTS, level) + bot.skills.setLevel(Skills.RANGE, 50) + bot.skills.setLevel(Skills.DEFENCE, 50) + bot.skills.setLevel(Skills.ATTACK, level) + bot.skills.setLevel(Skills.STRENGTH, level) + bot.skills.setLevel(Skills.HITPOINTS, level) + bot.skills.updateCombatLevel() + equipHighest(bot, PCRANGE_HELMS) + equipHighest(bot, PCRANGE_TOPS) + equipHighest(bot, PCRANGE_BACK) + equipHighest(bot, PCRANGE_LEGS) + bot.equipment.refresh() + equipHighest(bot, NECK) + equipHighest(bot, GLOVES) + equipHighest(bot, BOOTS) + equipHighest(bot, RING_ARCH) + bot.equipment.refresh() + if(crossbow == true) { equipHighest(bot,PCCROSSBOWS); equipHighest(bot,MELEE_SHIELD); bot.equipment.add(Item(Items.BRONZE_BOLTS_877,Integer.MAX_VALUE),13,false,false) } + else {equipHighest(bot, PCBOWS); bot.equipment.add(Item(Items.BRONZE_ARROW_882,Integer.MAX_VALUE),13,false,false) } + bot.skills.setStaticLevel(Skills.RANGE, 99) + bot.skills.setLevel(Skills.RANGE, 99) + bot.equipment.refresh() + } + + fun gearPCnMeleeBot(bot: AIPlayer, vararg skills: Int){ + var max = 0 + val initial = RandomFunction.random(30, 75).also {max = 75 } + var level = initial + bot.fullRestore() + + bot.skills.setStaticLevel(Skills.STRENGTH, level) + bot.skills.setStaticLevel(Skills.DEFENCE, level) + bot.skills.setStaticLevel(Skills.ATTACK, level) + bot.skills.setStaticLevel(Skills.HITPOINTS, level) + bot.skills.setStaticLevel(Skills.PRAYER, 70) + bot.skills.setStaticLevel(Skills.RANGE, 10) + bot.skills.setStaticLevel(Skills.MAGIC, 10) + bot.skills.setLevel(Skills.STRENGTH, level) + bot.skills.setLevel(Skills.DEFENCE, level) + bot.skills.setLevel(Skills.ATTACK, level) + bot.skills.setLevel(Skills.HITPOINTS, level) + bot.skills.setLevel(Skills.PRAYER, 70) + bot.skills.setLevel(Skills.RANGE, 10) + bot.skills.setLevel(Skills.MAGIC, 10) + bot.skills.updateCombatLevel() + equipHighest(bot, PCMELEE_HELMS) + equipHighest(bot, PCMELEE_LEG) + equipHighest(bot, PCMELEE_SHIELD) + equipHighest(bot, PCMELEE_TOP) + equipHighest(bot, PCMELEE_WEP) + bot.equipment.refresh() + equipHighest(bot, CAPE) + equipHighest(bot, NECK) + equipHighest(bot, GLOVES) + equipHighest(bot, BOOTS) + equipHighest(bot, RING_BERS) + bot.equipment.refresh() + bot.skills.setStaticLevel(Skills.DEFENCE, 70) + bot.skills.setStaticLevel(Skills.ATTACK, 99) + bot.skills.setStaticLevel(Skills.STRENGTH, 99) + bot.skills.setStaticLevel(Skills.HITPOINTS, 80) + bot.skills.setLevel(Skills.DEFENCE, 70) + bot.skills.setLevel(Skills.ATTACK, 99) + bot.skills.setLevel(Skills.STRENGTH, 99) + bot.skills.setLevel(Skills.HITPOINTS, 80) + bot.fullRestore() + } + /** + * Gears a Intermediate Pest control bot. + * @author Sir Kermit & Ceikry + */ + fun gearPCiRangedBot(bot: AIPlayer, crossbow: Boolean? = false, vararg skills: Int) { + var max = 0 + val level = RandomFunction.random(50, 80).also {max=99 } + bot.fullRestore() + + bot.skills.setStaticLevel(Skills.RANGE, level) + bot.skills.setStaticLevel(Skills.DEFENCE, 80) + bot.skills.setStaticLevel(Skills.ATTACK, level) + bot.skills.setStaticLevel(Skills.STRENGTH, level) + bot.skills.setStaticLevel(Skills.HITPOINTS, 70) + bot.skills.setStaticLevel(Skills.SUMMONING, 99) + bot.skills.setLevel(Skills.RANGE, level) + bot.skills.setLevel(Skills.DEFENCE, 80) + bot.skills.setLevel(Skills.ATTACK, level) + bot.skills.setLevel(Skills.STRENGTH, level) + bot.skills.setLevel(Skills.HITPOINTS, 70) + bot.skills.setLevel(Skills.SUMMONING, 99) + bot.skills.updateCombatLevel() + equipHighest(bot, PCRANGE_HELMS) + equipHighest(bot, PCRANGE_TOPS) + equipHighest(bot, PCRANGE_BACK) + equipHighest(bot, PCRANGE_LEGS) + bot.equipment.refresh() + equipHighest(bot, GLOVES) + equipHighest(bot, NECK) + equipHighest(bot, BOOTS) + equipHighest(bot, RING_ARCH) + bot.equipment.refresh() + if(crossbow == true) { equipHighest(bot,PCCROSSBOWS); equipHighest(bot,MELEE_SHIELD); bot.equipment.add(Item(Items.BRONZE_BOLTS_877,Integer.MAX_VALUE),13,false,false) } + else {equipHighest(bot, PCBOWS); bot.equipment.add(Item(Items.BRONZE_ARROW_882,Integer.MAX_VALUE),13,false,false) } + bot.skills.setStaticLevel(Skills.RANGE, 99) + bot.skills.setLevel(Skills.RANGE, 99) + bot.equipment.refresh() + } + + fun gearPCiMeleeBot(bot: AIPlayer, vararg skills: Int){ + var max = 0 + val initial = RandomFunction.random(55, 95).also {max=95 } + var level = initial + bot.fullRestore() + + bot.skills.setStaticLevel(Skills.STRENGTH, level) + bot.skills.setStaticLevel(Skills.DEFENCE, level) + bot.skills.setStaticLevel(Skills.ATTACK, level) + bot.skills.setStaticLevel(Skills.HITPOINTS, level) + bot.skills.setStaticLevel(Skills.PRAYER, 99) + bot.skills.setStaticLevel(Skills.RANGE, level) + bot.skills.setStaticLevel(Skills.MAGIC, level) + bot.skills.setStaticLevel(Skills.SUMMONING, 99) + bot.skills.setLevel(Skills.STRENGTH, level) + bot.skills.setLevel(Skills.DEFENCE, level) + bot.skills.setLevel(Skills.ATTACK, level) + bot.skills.setLevel(Skills.HITPOINTS, level) + bot.skills.setLevel(Skills.PRAYER, 99) + bot.skills.setLevel(Skills.RANGE, level) + bot.skills.setLevel(Skills.MAGIC, level) + bot.skills.setLevel(Skills.SUMMONING, 99) + bot.skills.updateCombatLevel() + equipHighest(bot, PCMELEE_HELMS) + equipHighest(bot, PCMELEE_LEG) + equipHighest(bot, PCMELEE_SHIELD) + equipHighest(bot, PCMELEE_TOP) + equipHighest(bot, PCMELEE_WEP) + bot.equipment.refresh() + equipHighest(bot, CAPE) + equipHighest(bot, NECK) + equipHighest(bot, GLOVES) + equipHighest(bot, BOOTS) + equipHighest(bot, RING_BERS) + bot.equipment.refresh() + bot.skills.setStaticLevel(Skills.DEFENCE, 99) + bot.skills.setStaticLevel(Skills.ATTACK, 99) + bot.skills.setStaticLevel(Skills.STRENGTH, 99) + bot.skills.setStaticLevel(Skills.HITPOINTS, 99) + bot.skills.setLevel(Skills.DEFENCE, 99) + bot.skills.setLevel(Skills.ATTACK, 99) + bot.skills.setLevel(Skills.STRENGTH, 99) + bot.skills.setLevel(Skills.HITPOINTS, 99) + bot.fullRestore() + } + + + /** + * Generates the stats for a bot with the given tier. + * @param bot the bot to gear + * @param tier the Tier of stats and gear. LOW, MED, HIGH, PURE. + * @param skills the skills that we should generate. + * @author Ceikry and Eli + */ + fun generateStats(bot: AIPlayer, tier: Tier, vararg skills: Int) { + var totalXPAdd = 0.0 + var skillAmt = 0.0 + val variance = 0.5 + var max = 0 + val initial = when (tier) { + Tier.LOW -> RandomFunction.random(33).also { max = 33 } + Tier.MED -> RandomFunction.random(33, 66).also { max = 66 } + Tier.HIGH -> RandomFunction.random(66, 99).also { max = 99 } + Tier.PURE -> RandomFunction.random(90, 99).also {max = 99 } + } + for (skill in skills.indices) { + val perc = RandomFunction.random(-variance,variance) + var level = initial + (perc * 33).toInt() + if(level < 1) + level = 1 + if(level > max) + level = max + bot.skills.setLevel(skills[skill], level) + bot.skills.setStaticLevel(skills[skill], level) + totalXPAdd += bot.skills.getExperience(skills[skill]) + skillAmt++ + } + when (tier){ + Tier.PURE -> { + bot.skills.setStaticLevel(Skills.DEFENCE,10) + bot.skills.setStaticLevel(Skills.STRENGTH,99) + bot.skills.setStaticLevel(Skills.ATTACK,90) + bot.skills.setStaticLevel(Skills.PRAYER,43) + bot.skills.setStaticLevel(Skills.RANGE,1) + bot.skills.setStaticLevel(Skills.MAGIC,1) + } + else -> {} + } + + bot.skills.addExperience(Skills.HITPOINTS, (totalXPAdd / skillAmt) * 0.2) + val new_hp = bot.skills.levelFromXP((totalXPAdd / skillAmt) * 0.2) + bot.skills.setStaticLevel(Skills.HITPOINTS,10 + new_hp) + bot.skills.updateCombatLevel() + bot.fullRestore() + } + + /** + * Equips the highest piece of gear from a set for the stats the bot has. + * @param bot the bot to equip gear to. + * @param set the IntArray set to check + * @param levelcap (optional) the max level of gear to equip. + * @author Ceikry + */ + private fun equipHighest(bot: AIPlayer, set: Array, levelcap: Int? = null) { + val highestItems = ArrayList() + var highest: Item? = null + for (i in set.indices) { + val item = Item(set[i]) + var canEquip = true + (item.definition.handlers.getOrDefault("requirements",null) as HashMap?)?.let { map -> + levelcap?.let {levelcap -> + map.map { + if (bot.skills.getLevel(it.key) < it.value || it.value > levelcap) + canEquip = false + } + } ?: map.map { + if (bot.skills.getLevel(it.key) < it.value) + canEquip = false + } + } + if (canEquip) { + if (highest == null) { + highest = item + highestItems.add(item) + continue + } + if (item.lvlAvg() > highest.lvlAvg()) { + highest = item + highestItems.clear() + highestItems.add(item) + } else if(item.lvlAvg() == highest.lvlAvg()){ + highestItems.add(item) + } + } + } + bot.equipment.add(highestItems.random(), highest!!.definition!!.handlers["equipment_slot"] as Int, false, false) + } + + /** + * Extension function for the Item class that gets the average of its level requirements. + * @author Ceikry + */ + fun Item.lvlAvg(): Int { + var total = 1 + var count = 1 + (definition.handlers.getOrDefault("requirements",null) as HashMap?)?.let { map -> + map.map { + total += it.value + count++ + } + } + return total / count + } + + + val RANGE_HELMS = arrayOf(1167,4732,3749) + val RANGE_TOPS = arrayOf(1129,1131,1135,2499,2501,2503) + val RANGE_LEGS = arrayOf(1095,1097,1099,2493,2495,2497) + val BOWS = arrayOf(841,843,847,853) + val CROSSBOWS = arrayOf(9185,9174,9177,9176,9179,9181,9183) + + val PCRANGE_HELMS = arrayOf(1167,4732,3749,11718) + val PCRANGE_TOPS = arrayOf(1129,1131,1135,2503,11720) + val PCRANGE_LEGS = arrayOf(1095,1097,1099,2497,11722) + val PCRANGE_BACK = arrayOf(1019,10498,10499) + val PCBOWS = arrayOf(841,843,847,853) + val PCCROSSBOWS = arrayOf(9185,9174,9177,9176,9179,9181,9183) + + val MELEE_HELMS = arrayOf(1137,1139, 1141, 6621, 1143,1145,1147,1149,1151,1153, 6623, 1159,1163,1165,3748, 3751, 3753, 4716,4724, 4745, 4753) + val MELEE_TOP = arrayOf(1101,1103,1105,1107,1109,1111,1113,2513,1115,1117,1119,1121,1123,1125,1127,4720,4728,4749,4749) + val MELEE_LEG = arrayOf(1081,1083,1085,1087,1089,1091,1093,4759,1067,1069,1071,1073,1075,1077,1079,4722,4751,4722,4751) + val MELEE_SHIELD = arrayOf(1171,1173,1175,1177,1179,1181,1183,1185,1187,1189,1191,1193,1195,1197,1199,1201) + val MELEE_WEP = arrayOf(1277,1279,1281,1283,1285,1287,1289,1291,1293,1295,1297,1299,1301,1303,1305,1321,1323,1325,1327,1329,1331,1333,4587,4151,1363,1365,1367,1369,1371,1373,1375,1377) + val NGLOVES = arrayOf(1059,2922,2912,2902,2932,2942,3799) + val NBOOTS = arrayOf(4121,4123,4125,4127,4129,4131,1061,1837,2579,9005) + val NRBOOTS = arrayOf(9006,626,628,630,632,634) + val NNECK = arrayOf(1704,1725,1729,1731) + val NRANGENECK = arrayOf(1478,1704) + val NRANGESHIELD = arrayOf(1191,1193,1195,1197,1199,1201) + + val PCMELEE_HELMS = arrayOf(1137,1139, 1141, 6621, 1143,1145,1147,1149,1151,1153, 6623, 1159,1163,1165,3748, 3751, 10828, 11335, 3753, 4716,4724, 4745, 4753, 3751) + val PCMELEE_TOP = arrayOf(1101,1103,1105,1107,1109,1111,1113,2513,1115,1117,1119,1121,1123,1125,1127,4720,4728,4749,4749,11724,14479,2513) + val PCMELEE_LEG = arrayOf(1081,1083,1085,1087,1089,1091,1093,4759,1067,1069,1071,1073,1075,1077,1079,4722,4751,4722,4751,11726,4087) + val PCMELEE_SHIELD = arrayOf(1171,1173,1175,1177,1179,1181,1183,1185,1187,1189,1191,1193,1195,1197,1199,1201,6524,13742,13740,13738,13736,13734) + val PCMELEE_WEP = arrayOf(1277,1279,1281,1283,1285,1287,1289,1291,1293,1295,1297,1299,1301,1303,1305,1321,1323,1325,1327,1329,1331,1333,4587,4151,1363,1365,1367,1369,1371,1373,1375,1377,1434,5698) + + val NECK = arrayOf(1704,6585) + val CAPE = arrayOf(1019,1021,1023,6568,4315,4317,4319,4321,4323,4325,4327,4329,4331,4333,4335,4337,4339,4341,4343,4345,4347,4349,4351) + val GLOVES = arrayOf(1059,7456,7457,7458,7459,7460,7461,7462) + val BOOTS = arrayOf(1061,4131,11732,11728,4131) + val RING_BERS = arrayOf(6737) + val RING_ARCH = arrayOf(6733) + + val RICH_MELEE_HELMS = arrayOf(2587,2595,2605,2613,2619,2627,2657,2665,2673,3486,1149,10828,4716,4724,4753) +} diff --git a/Server/src/main/core/game/bots/GeneralBotCreator.kt b/Server/src/main/core/game/bots/GeneralBotCreator.kt new file mode 100644 index 0000000..7e3cb54 --- /dev/null +++ b/Server/src/main/core/game/bots/GeneralBotCreator.kt @@ -0,0 +1,129 @@ +package core.game.bots + +import core.game.node.entity.player.Player +import core.game.system.task.Pulse +import core.game.world.GameWorld +import core.game.world.map.Location +import core.tools.RandomFunction +import core.Server +import content.global.bots.Idler +import core.api.* +import core.game.interaction.MovementPulse +import core.tools.Log + +class GBCTick : TickListener { + override fun tick() { + GeneralBotCreator.botPulsesTriggeredThisTick = 0 + } +} + +class GeneralBotCreator { + //org/crandor/net/packet/in/InteractionPacket.java <<< This is a very useful class for learning to code bots + constructor(botScript: Script, loc: Location?) { + botScript.bot = AIPBuilder.create(loc) + GameWorld.Pulser.submit(BotScriptPulse(botScript)) + } + + constructor(botScript: Script, bot: AIPlayer?) { + botScript.bot = bot + GameWorld.Pulser.submit(BotScriptPulse(botScript).also { AIRepository.PulseRepository[it.botScript.bot.username.lowercase()] = it }) + } + + constructor(botScript: Script, player: Player, isPlayer: Boolean){ + botScript.bot = player + val pulse = BotScriptPulse(botScript,isPlayer) + GameWorld.Pulser.submit(pulse) + player.setAttribute("/save:not_on_highscores",true) + player.setAttribute("botting:script",pulse) + } + + companion object { + var botPulsesTriggeredThisTick = 0 + } + + inner class BotScriptPulse(public val botScript: Script, val isPlayer: Boolean = false) : Pulse(1) { + var ticks = 0 + init { + botScript.init(isPlayer) + } + var randomDelay = 0 + var lastBotLocation: Location = botScript.bot.location.transform(0,0,0) + var lastBotMoveTicks = getWorldTicks() + override fun pulse(): Boolean { + if(randomDelay > 0){ + randomDelay -= 1 + return false + } + if (botScript.bot.pulseManager.hasPulseRunning()) { + if (botScript.bot.pulseManager.current is MovementPulse) { + if (botScript.bot.location != lastBotLocation) { + lastBotLocation = botScript.bot.location.transform(0,0,0) + lastBotMoveTicks = getWorldTicks() + } + if (lastBotLocation == botScript.bot.location && getWorldTicks() - lastBotMoveTicks > 5) { + botScript.bot.pulseManager.current.stop() + } + } + } + + /* + * Chatboxes and interfaces will cause the authentic interaction subsystem + * to pause any currently running authentically-implemented interactions. + * + * When this happens, if the interfaces are not handled by the script and closed, + * execution will remain paused as the game believes the bot is still doing something + * (because they still have an authentic interaction in the queue, that is not advancing + * because it is paused) and so the script does not execute, but the pulse is waiting on botscript input. + * + * This deadlock can be worked around by just closing these. + * + * Set endDialogue to FALSE if you want + * to avoid automatic dialogue termination (useful for, for example, boat travel) + */ + if (botScript.bot.scripts.getActiveScript() != null && botScript.bot.hasModalOpen() && botScript.endDialogue) { + botScript.bot.interfaceManager.closeChatbox() + botScript.bot.interfaceManager.openChatbox(137) + botScript.bot.interfaceManager.close() + botScript.bot.dialogueInterpreter.close() + } + + if (!botScript.bot.pulseManager.hasPulseRunning() && botScript.bot.scripts.getActiveScript() == null) { + + /*if (ticks++ >= RandomFunction.random(90000,120000)) { + AIPlayer.deregister(botScript.bot.uid) + ticks = 0 + SystemLogger.log("Submitting transition pulse from ticks") + GameWorld.Pulser.submit(TransitionPulse(botScript)) + return true + }*/ + if(!botScript.running) return true //has to be separated this way or it double-submits the respawn pulse. + + if (botPulsesTriggeredThisTick++ >= 75) + return false + + val idleRoll = RandomFunction.random(10) + if(idleRoll == 2 && botScript !is Idler){ + randomDelay += RandomFunction.random(20,50) + return false + } + botScript.tick() + } + return false + } + + override fun stop() { + ticks = Integer.MAX_VALUE - 20 //Sets the ticks as high as they can go (safely) and then runs pulse again + pulse() //to trigger the transition pulse to be submitted. + super.stop() + if (Server.running) AIRepository.PulseRepository.remove(this.botScript.bot.username.lowercase()) + } + } + + inner class TransitionPulse(val script: Script) : Pulse(RandomFunction.random(60,200)){ + override fun pulse(): Boolean { + // This does not get called and should be removed + GameWorld.Pulser.submit(BotScriptPulse(script.newInstance()).also { AIRepository.PulseRepository[it.botScript.bot.username.lowercase()] = it }) + return true + } + } +} diff --git a/Server/src/main/core/game/bots/PlayerCompatible.kt b/Server/src/main/core/game/bots/PlayerCompatible.kt new file mode 100644 index 0000000..870efe5 --- /dev/null +++ b/Server/src/main/core/game/bots/PlayerCompatible.kt @@ -0,0 +1,3 @@ +package core.game.bots + +annotation class PlayerCompatible diff --git a/Server/src/main/core/game/bots/PlayerScripts.kt b/Server/src/main/core/game/bots/PlayerScripts.kt new file mode 100644 index 0000000..f4e0185 --- /dev/null +++ b/Server/src/main/core/game/bots/PlayerScripts.kt @@ -0,0 +1,6 @@ +package core.game.bots + +object PlayerScripts { + class PlayerScript(val identifier: String, val description: Array, val name: String, val clazz: Class<*>) + val identifierMap = HashMap() +} \ No newline at end of file diff --git a/Server/src/main/core/game/bots/PvMBots.java b/Server/src/main/core/game/bots/PvMBots.java new file mode 100644 index 0000000..6aef6e0 --- /dev/null +++ b/Server/src/main/core/game/bots/PvMBots.java @@ -0,0 +1,149 @@ +package core.game.bots; + +import java.util.ArrayList; +import java.util.List; + +import core.game.consumable.Consumable; +import content.data.consumables.Consumables; +import core.game.consumable.Food; +import content.data.consumables.effects.HealingEffect; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.Entity; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.prayer.PrayerType; +import core.game.node.item.Item; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.tools.RandomFunction; + +public class PvMBots extends AIPlayer { + + //Used so the bot doesn't spam actions + private int tick = 0; + + public PvMBots(Location l) { + super(l); + } + + public PvMBots(String copyFromFile, Location l) { + super(copyFromFile, l); + } + + + public List FindTargets(Entity entity, int radius) { + List targets = new ArrayList<>(20); + Object[] localNPCs = RegionManager.getLocalNpcs(entity,radius).toArray(); + int length = localNPCs.length; + if(length > 5){length = 5;} + for (int i = 0; i < length; i++) { + NPC npc = (NPC) localNPCs[i]; + { + if (checkValidTargets(npc)) + targets.add(npc); + } + } + if (targets.size() == 0) + return null; + return targets; + } + + public boolean checkValidTargets(NPC target) { + if (!target.isActive()) { + return false; + } + if (!target.getProperties().isMultiZone() && target.inCombat()) { + return false; + } + if (!target.getDefinition().hasAction("attack")) { + return false; + } + return true; + } + + public boolean AttackNpcsInRadius(int radius) + { + return AttackNpcsInRadius(this, radius); + } + + /** + * Attacks NPCs in radius of bot + * @param bot + * @param radius + * @return true if bot will be fighting + */ + public boolean AttackNpcsInRadius(Player bot, int radius) { + if (bot.inCombat()) + return true; + List creatures = FindTargets(bot, radius); + if (creatures == null) { + return false; + } + bot.attack(creatures.get(RandomFunction.getRandom((creatures.size() - 1)))); + if (!creatures.isEmpty()) { + return true; + } else { + creatures = FindTargets(bot, radius); + if (!creatures.isEmpty()) + { + bot.attack(creatures.get(RandomFunction.getRandom((creatures.size() - 1)))); + return true; + } + return false; + } + } + + @Override + public void tick() { + super.tick(); + + this.tick++; + + //Despawn + if (this.getSkills().getLifepoints() <= 5){ + //TODO: Just respawn a new bot (not sure how you'd do that :L) + // Maybe make all PvMBots know what to do if they aren't in right area? I.e. pest control bots teleport to PC + //this.teleport(new Location(500, 500)); + //Despawning not being delayed causes 3 errors in the console + this.getSkills().setLifepoints(20); + } + + //Npc Combat + /*if (this.tick % 10 == 0) { + if (!this.inCombat()) + AttackNpcsInRadius(this, 5); + }*/ + + if (this.tick == 100) this.tick = 0; + + //this.eat(); + //this.getPrayer().toggle() + } + + public void CheckPrayer(PrayerType type[]) { + for (int i = 0; i < type.length; i++) + this.getPrayer().toggle(type[i]); + } + + public void eat(int foodId) { + Item foodItem = new Item(foodId); + + if ((this.getSkills().getStaticLevel(Skills.HITPOINTS) >= this.getSkills().getLifepoints() * 3) && this.getInventory().containsItem(foodItem)) { + this.lock(3); + //this.animate(new Animation(829)); + Item food = this.getInventory().getItem(foodItem); + + Consumable consumable = Consumables.getConsumableById(food.getId()).getConsumable(); + + if (consumable == null) { + return; + } + + consumable.consume(food, this); + this.getProperties().getCombatPulse().delayNextAttack(3); + } + if (this.checkVictimIsPlayer() == false) + if (!(this.getInventory().contains(foodId, 1))) + this.getInventory().add(new Item(foodId, 5)); //Add Food to Inventory + } +} diff --git a/Server/src/main/core/game/bots/PvMBotsBuilder.kt b/Server/src/main/core/game/bots/PvMBotsBuilder.kt new file mode 100644 index 0000000..bfe79d6 --- /dev/null +++ b/Server/src/main/core/game/bots/PvMBotsBuilder.kt @@ -0,0 +1,30 @@ +package core.game.bots + +import core.game.world.map.Location +import content.minigame.pestcontrol.bots.PestControlTestBot +import content.minigame.pestcontrol.bots.PestControlTestBot2 + +// import sun.util.resources.CalendarData; +class PvMBotsBuilder { + + companion object { + var botsSpawned = 0 + + fun create(l: Location?): PvMBots { + botsSpawned++ + return PvMBots(l) + } + + @JvmStatic + fun createPestControlTestBot2(l: Location?): PestControlTestBot2 { + botsSpawned++ + return PestControlTestBot2(l!!) + } + @JvmStatic + fun createPestControlTestBot(l: Location?): PestControlTestBot { + botsSpawned++ + return PestControlTestBot(l!!) + } + + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/bots/Script.java b/Server/src/main/core/game/bots/Script.java new file mode 100644 index 0000000..9c5da33 --- /dev/null +++ b/Server/src/main/core/game/bots/Script.java @@ -0,0 +1,64 @@ +package core.game.bots; + +import content.data.Quests; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +public abstract class Script { + + public ScriptAPI scriptAPI; + public ArrayList inventory = new ArrayList<>(20); + public ArrayList equipment = new ArrayList<>(20); + public Map skills = new HashMap<>(); + public ArrayList quests = new ArrayList<>(20); + + + public Player bot; + + public boolean running = true; + public boolean endDialogue = true; + + public void init(boolean isPlayer) + { + //bot.init(); + scriptAPI = new ScriptAPI(bot); + + if(!isPlayer) { + // Skills and quests need to be set before equipment in case equipment has level or quest requirements + for (Map.Entry skill : skills.entrySet()) { + setLevel(skill.getKey(), skill.getValue()); + } + for (Quests quest : quests) { + bot.getQuestRepository().setStage(bot.getQuestRepository().getQuest(quest), 100); + } + for (Item i : equipment) { + bot.getEquipment().add(i, true, false); + } + bot.getInventory().clear(); + for (Item i : inventory) { + bot.getInventory().add(i); + } + } + } + + @Override + public String toString() { + return bot.getName() + " is a " + this.getClass().getSimpleName() + " at location " + bot.getLocation().toString() + " Current pulse: " + bot.getPulseManager().getCurrent(); + } + + public abstract void tick(); + + public void setLevel(int skill, int level) { + bot.getSkills().setLevel(skill, level); + bot.getSkills().setStaticLevel(skill, level); + bot.getSkills().updateCombatLevel(); + bot.getAppearance().sync(); + } + + // This does not get called and all implementations should be removed + public abstract Script newInstance(); +} diff --git a/Server/src/main/core/game/bots/ScriptAPI.kt b/Server/src/main/core/game/bots/ScriptAPI.kt new file mode 100644 index 0000000..5a3306e --- /dev/null +++ b/Server/src/main/core/game/bots/ScriptAPI.kt @@ -0,0 +1,873 @@ +package core.game.bots + +import core.api.* +import core.game.interaction.NodeUsageEvent +import core.game.interaction.PluginInteractionManager +import core.game.interaction.UseWithHandler +import core.cache.def.impl.ItemDefinition +import core.game.component.Component +import core.game.consumable.Consumable +import content.data.consumables.Consumables +import core.game.consumable.Food +import content.data.consumables.effects.HealingEffect +import core.game.interaction.DestinationFlag +import core.game.interaction.MovementPulse +import core.game.interaction.Option +import core.game.node.Node +import core.game.node.scenery.Scenery +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.GroundItem +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.map.RegionManager +import core.game.world.map.path.Pathfinder +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.ChatMessage +import core.game.world.update.flag.context.Graphics +import core.game.world.update.flag.* +import core.tools.RandomFunction +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch +import org.json.simple.JSONArray +import org.json.simple.JSONObject +import org.rs09.consts.Items +import core.ServerConstants.Companion.SERVER_GE_NAME +import core.game.ge.GrandExchange +import core.game.ge.GrandExchangeOffer +import core.game.interaction.IntType +import core.game.interaction.InteractionListeners +import core.tools.SystemLogger +import core.game.system.config.ItemConfigParser +import core.game.world.GameWorld +import core.game.world.repository.Repository +import core.tools.Log +import core.tools.colorize +import java.util.* +import java.util.concurrent.CountDownLatch +import kotlin.math.max +import kotlin.math.pow +import kotlin.math.sqrt +import core.ServerConstants +import core.api.utils.Vector +import kotlin.random.Random + +class ScriptAPI(private val bot: Player) { + val GRAPHICSUP = Graphics(1576) + val ANIMATIONUP = Animation(8939) + val GRAPHICSDOWN = Graphics(1577) + val ANIMATIONDOWN = Animation(8941) + + /** + * Gets the distance between two nodes + * @param n1 the first node + * @param n2 the second node + * @author Ceikry + */ + fun distance(n1: Node, n2: Node): Double { + return sqrt((n1.location.x - n2.location.x.toDouble()).pow(2.0) + (n2.location.y - n1.location.y.toDouble()).pow(2.0)) + } + + fun interact(bot: Player, node: Node?, option: String){ + + if(node == null) return + + val type = when(node){ + is Scenery -> IntType.SCENERY + is NPC -> IntType.NPC + is Item -> IntType.ITEM + else -> null + } ?: return + val opt: Option? = node.interaction.options.filter {it != null && it.name.equals(option, true) }.firstOrNull() + + if(opt == null){ + log(this::class.java, Log.WARN, "Invalid option name provided: $option") + return + } + + if(!InteractionListeners.run(node.id, type, option, bot, node)) node.interaction.handle(bot, opt) + } + + fun useWith(bot: Player, itemId: Int, node: Node?) { + if(node == null) return + + val type = when(node){ + is Scenery -> IntType.SCENERY + is NPC -> IntType.NPC + is Item -> IntType.ITEM + else -> null + } ?: return + + val item = bot.inventory.getItem(Item(itemId)) + + val childNode = node.asScenery()?.getChild(bot) + + if (InteractionListeners.run(item, node, type, bot)) + return + if (childNode != null && childNode.id != node.id) { + if (InteractionListeners.run(item, childNode, type, bot)) + return + } + val flipped = type == IntType.ITEM && item.id < node.id + val event = if (flipped) + NodeUsageEvent(bot, 0, node, item) + else + NodeUsageEvent(bot, 0, item, childNode ?: node) + if (PluginInteractionManager.handle(bot, event)) + return + UseWithHandler.run(event) + } + + fun sendChat(message: String) { + bot.sendChat(message) + bot.updateMasks.register(EntityFlag.Chat, ChatMessage(bot, message, 0, 0)) + } + + /** + * Gets the nearest node with a name contained in the list of acceptable names + * @param acceptedNames the list of accepted npc/object names + * @return the nearest node with a matching name or null + * @author Ceikry + */ + fun getNearestNodeFromList(acceptedNames: List, isObject: Boolean): Node? { + if (isObject) + return processEvaluationList(RegionManager.forId(bot.location.regionId).planes[bot.location.z].objectList, acceptedName = acceptedNames) + else + return processEvaluationList(RegionManager.forId(bot.location.regionId).planes[bot.location.z].entities, acceptedName = acceptedNames) + } + + /** + * Gets the nearest node with matching id. + * @param id the id to look for + * @param object whether or not the node we are looking for is an object. + * @return the closest node with matching id or null. + * @author Ceikry + */ + fun getNearestNode(id: Int, isObject: Boolean): Node? { + if (isObject) + return processEvaluationList(RegionManager.forId(bot.location.regionId).planes[bot.location.z].objectList, acceptedId = id) + else + return processEvaluationList(RegionManager.forId(bot.location.regionId).planes[bot.location.z].entities, acceptedId = id) + } + + /** + * Gets the nearest node with name entityName + * @param entityName the name of the node to look for + * @return the nearest node with a matching name or null + * @author Ceikry + */ + fun getNearestNode(entityName: String): Node? { + return processEvaluationList(RegionManager.forId(bot.location.regionId).planes[bot.location.z].entities, acceptedName = listOf(entityName)) + } + + /** + * Gets the nearest node with a matching name. + * @param name the name to look for. + * @param object whether or not the node we are looking for is an object. + * @return the nearest matching node or null. + * @author Ceikry + */ + fun getNearestNode(name: String, isObject: Boolean): Node? { + if (isObject) + return processEvaluationList(RegionManager.forId(bot.location.regionId).planes[bot.location.z].objectList, acceptedName = listOf(name)) + else + return processEvaluationList(RegionManager.forId(bot.location.regionId).planes[bot.location.z].entities, acceptedName = listOf(name)) + } + + fun getNearestObjectByPredicate(predicate: (Node?) -> Boolean): Node? { + return processEvaluationList(RegionManager.forId(bot.location.regionId).planes[bot.location.z].objectList, acceptedPredicate = predicate) + } + + fun evaluateViability (e: Node?, minDistance: Double, maxDistance: Double, acceptedNames: List? = null, acceptedId: Int = -1, acceptedPredicate: ((Node?) -> Boolean)? = null): Boolean { + if (e == null || !e.isActive) + return false + if (acceptedId != -1 && e.id != acceptedId) + return false + + val dist = distance(bot, e) + if (dist > maxDistance || dist > minDistance) + return false + + if (acceptedPredicate != null) { + return acceptedPredicate(e) && !Pathfinder.find(bot, e).isMoveNear + } else { + val name = e?.name + return (acceptedNames?.stream()?.anyMatch({ s -> s.equals(name, true) }) ?: true && !Pathfinder.find(bot, e).isMoveNear) + } + } + + fun processEvaluationList (list: List, acceptedName: List? = null, acceptedId: Int = -1, acceptedPredicate: ((Node?) -> Boolean)? = null): Node? { + var entity: Node? = null + var minDistance = Double.MAX_VALUE + val maxDistance = ServerConstants.MAX_PATHFIND_DISTANCE.toDouble() + for (e in list) { + if (evaluateViability(e, minDistance, maxDistance, acceptedName, acceptedId, acceptedPredicate)) { + entity = e + minDistance = distance(bot, e) + } + } + return entity + } + + /** + * Gets the nearest ground item with matching ID from the list in AIRepository. + * @param id the id of the ground item we are looking for. + * @return the nearest GroundItem with a matching id or null + * @author Ceikry + */ + private fun getNearestGroundItem(id: Int): GroundItem? { + var distance = 11.0 + var closest: GroundItem? = null + if(AIRepository.getItems(bot) != null) { + for (item in AIRepository.getItems(bot)!!.filter { it: GroundItem -> it.distance(bot.location) < 10 }) { + if (item.id == id) { + //distance = item.distance(bot.location) + closest = item + } + } + if (!GroundItemManager.getItems().contains(closest)){ + AIRepository.getItems(bot)?.remove(closest) + return null + } + } else { + val items: ArrayList? = bot.getAttribute("botting:drops",null) + if(items != null){ + for(item in items.filter { it.distance(bot.location) < 10 }){ + if(item.id == id) return item.also { items.remove(item); bot.setAttribute("botting:drops",items) } + } + } + } + return closest + } + + /** + * Takes the nearest ground item with a matching id if it exists. + * @param id the id to look for + * @author Ceikry + */ + fun takeNearestGroundItem(id: Int) : Boolean{ + val item = getNearestGroundItem(id) + if(item != null){ + item.interaction?.handle(bot, item.interaction[2]) + return true + } + else return false + } + + /** + * Gets the nearest GameObject to loc with matching objectId + * @param loc the location we are checking around + * @param objectId the id of the object we are looking for + * @return the nearest matching object or null. + * @author Ceikry + */ + fun getNearestGameObject(loc: Location, objectId: Int): Scenery? { + var nearestObject: Scenery? = null + val minDistance = Double.MAX_VALUE + for (o in RegionManager.forId(loc.regionId).planes[0].objects) { + for (obj in o) { + if (obj != null) { + if (distance(loc, obj) < minDistance && obj.id == objectId) { + nearestObject = obj + } + } + } + } + return nearestObject + } + + /** + * Gets a list of NPCs that are attackable around the entity. + * @param entity the entity to search around. + * @param radius the radius around entity to search in. + * @param name the name of the NPC to look for. + * @return an Array of the nearest NPCs with matching name, or null. + * @author Ceikry + */ + private fun findTargets(entity: Entity, radius: Int, name: String? = null): List? { + val targets: MutableList = ArrayList() + val localNPCs: Array = RegionManager.getLocalNpcs(entity, radius).toTypedArray() + var length = localNPCs.size + if (length > 5) { + length = 5 + } + for (i in 0 until length) { + val npc = localNPCs[i] as NPC + run { if (checkValidTargets(npc, name)) targets.add(npc) } + } + return if (targets.size == 0) null else targets + } + + /** + * Checks if the given target is a valid target for a combat bot. + * @param target the NPC that we are checking + * @param name the expected name of the NPC. + * @return true if the target is valid, false if not. + * @author Ceikry + */ + private fun checkValidTargets(target: NPC, name: String?): Boolean { + if (!target.isActive) { + return false + } + if (!target.properties.isMultiZone && target.inCombat()) { + return false + } + if (name != null){ + if(target.name != name) + return false + } + return target.definition.hasAction("attack") + } + + /** + * Attacks npcs in the given radius of the bot. + * @param bot the bot that is attacking + * @param radius the radius to attack in + * @return true if successfully attacking an NPC within that radius, false if not. + * @author Ceikry + */ + fun attackNpcsInRadius(bot: Player, radius: Int): Boolean { + if (bot.inCombat()) return true + var creatures: List? = findTargets(bot, radius) ?: return false + bot.attack(creatures!![RandomFunction.getRandom(creatures.size - 1)]) + return if (creatures.isNotEmpty()) { + true + } else { + creatures = findTargets(bot, radius) + if (!creatures!!.isEmpty()) { + bot.attack(creatures[RandomFunction.getRandom(creatures.size - 1)]) + return true + } + false + } + } + + /** + * Function to iteratively walk a bot to a faraway location. Limited by doors and large obstacles like mountains. + * @param loc the location to walk to. + * @author Ceikry + */ + fun walkTo(loc: Location){ + if(!bot.walkingQueue.isMoving) { + walkToIterator(loc) + } + } + + /** + * Function to iteratively walk an array of Locations to get over complex obstacles. + * @param steps the array of locations to walk to. + * @author dginovker + */ + fun walkArray(steps: Array){ + bot.pulseManager.run(object : Pulse(){ + var stepIndex = 0 + override fun pulse(): Boolean { + // If the stepIndex is out of bounds, we're done + if(stepIndex >= steps.size) return true + // If we're near the last step, we're done + if (bot.location.withinDistance(steps[steps.size - 1], 2)) { + return true + } + // If we're not near the next step, walk to it + if (!bot.location.withinDistance(steps[stepIndex], 5)) { + walkTo(steps[stepIndex]) + return false + } + // If we're near the next step, increment the step index + stepIndex++ + + return false + } + }) + } + + /** + * @param loc the location to walk to. + * @param radius tiles around the location the bot could walk to. + * @author Kermit + */ + fun randomWalkTo(loc: Location, radius: Int) { + if(!bot.walkingQueue.isMoving) { + var newloc = loc.transform(RandomFunction.random(radius,-radius),RandomFunction.random(radius,-radius), 0) + walkToIterator(newloc) + } + } + + /** + * @param location the location you want the coordinates randomized for. + * @param xMin the minimum range value X coordinates should be randomized by, must be xMin <= xMax ex: -1 min 1 max. + * @param xMax the maximum range value X coordinates should be randomized by, must be xMin <= xMax ex: -1 min 1 max. + * @param yMin the minimum range value Y coordinates should be randomized by, must be yMin <= yMax ex: -1 min 1 max. + * @param yMax the maximum range value Y coordinates should be randomized by, must be yMin <= yMax ex: -1 min 1 max. + * @param staticZ this value is static and does not change from what is given, must be actual Z value of location. + * @author Kermit + */ + fun randomizeLocationInRanges(location: Location, xMin: Int, xMax: Int, yMin: Int, yMax: Int, staticZ: Int): Location { + val newX = location.x + Random.nextInt(xMin, xMax) + val newY = location.y + Random.nextInt(yMin, yMax) + return Location(newX, newY, staticZ) + } + + /** + * The iterator for long-distance walking. Limited by doors and large obstacles like mountains. + * @param loc the location to find a path to. + * @author Ceikry + */ + private fun walkToIterator(loc: Location){ + var diffX = loc.x - bot.location.x + var diffY = loc.y - bot.location.y + + val vec = Vector.betweenLocs(bot.location, loc) + val norm = vec.normalized() + val tiles = kotlin.math.min(kotlin.math.floor(vec.magnitude()).toInt(), ServerConstants.MAX_PATHFIND_DISTANCE - 1) + val loc = bot.location.transform(norm * tiles) + bot.pulseManager.run(object : MovementPulse(bot, loc) { override fun pulse() : Boolean { return true } }) + } + + /** + * Attacks npcs in the given radius of the bot. + * @param bot the bot that is attacking + * @param radius the radius to attack in + * @param name the name of the NPC to target. + * @return true if successfully attacking an NPC within that radius, false if not. + * @author Ceikry + */ + fun attackNpcInRadius(bot: Player, name: String, radius: Int): Boolean { + if (bot.inCombat()) return true + var creatures: List? = findTargets(bot, radius, name) ?: return false + bot.attack(creatures!![RandomFunction.getRandom(creatures.size - 1)]) + return if (creatures.isNotEmpty()) { + true + } else { + creatures = findTargets(bot, radius, name) + if (!creatures!!.isEmpty()) { + bot.attack(creatures.random()) + return true + } + false + } + } + + /** + * Extension function to find the distance between a location and a ground item. + * @param loc the location to check the distance from. + * @return a Double representing the distance. + * @author Ceikry + */ + fun GroundItem.distance(loc: Location): Double{ + return location.getDistance(loc) + } + + /** + * A function for teleporting the bot to the GE + * @author Ceikry + */ + fun teleportToGE() : Boolean{ + if (bot.isTeleBlocked) { + return false + } + bot.lock() + bot.visualize(ANIMATIONUP, GRAPHICSUP) + bot.impactHandler.disabledTicks = 4 + val location = Location.create(3165, 3482, 0) + bot.pulseManager.run(object : Pulse(4, bot) { + override fun pulse(): Boolean { + bot.unlock() + bot.properties.teleportLocation = location + bot.pulseManager.clear() + bot.animator.reset() + return true + } + }) + return true + } + + /** + * A function for selling a given item on the GE. + * @param id the ID of the item to sell on the GE. Pulls from the bot's bank. + * @author Ceikry + * @author Angle + */ + fun sellOnGE(id: Int){ + class toCounterPulse : MovementPulse(bot, Location.create(3165, 3487, 0)){ + override fun pulse(): Boolean { + var actualId = id + val itemAmt = bot.bank.getAmount(id) + if (ItemDefinition.forId(id).noteId == id){ + actualId = Item(id).noteChange + } + val canSell = GrandExchange.addBotOffer(actualId, itemAmt) + if (canSell && saleIsBigNews(actualId, itemAmt)) { + Repository.sendNews(SERVER_GE_NAME + " just offered " + itemAmt + " " + ItemDefinition.forId(actualId).name.toLowerCase() + " on the GE.") + } + bot.bank.remove(Item(id, itemAmt)) + bot.bank.refresh() + return true + } + } + bot.pulseManager.run(toCounterPulse()) + } + + /** + * Function to sell all items in a bot's bank on the Grand Exchange, if they are tradable. + * @author Ceikry + */ + fun sellAllOnGe(){ + class toCounterPulseAll : MovementPulse(bot, Location.create(3165, 3487, 0)){ + override fun pulse(): Boolean { + for(item in bot.bank.toArray()) { + item ?: continue + if (item.id == Items.LOBSTER_379) continue + if (item.id == Items.SWORDFISH_373) continue + if (item.id == Items.SHARK_385) continue + if(!item.definition.isTradeable) {continue} + val itemAmt = item.amount + var actualId = item.id + if (ItemDefinition.forId(actualId).noteId == actualId){ + actualId = Item(actualId).noteChange + } + val canSell = GrandExchange.addBotOffer(actualId, itemAmt) + if (canSell && saleIsBigNews(actualId, itemAmt)) { + Repository.sendNews(SERVER_GE_NAME + " just offered " + itemAmt + " " + ItemDefinition.forId(actualId).name.toLowerCase() + " on the GE.") + } + bot.bank.remove(item) + bot.bank.refresh() + } + return true + } + } + bot.pulseManager.run(toCounterPulseAll()) + } + + /** + * Function to sell all items in a bot's bank on the Grand Exchange, if they are tradable. + * @author Ceikry & Kermit + */ + fun sellAllOnGeAdv(){ + val ge: Scenery? = getNearestNode("Desk", true) as Scenery? + class toCounterPulseAll : MovementPulse(bot, ge, DestinationFlag.OBJECT) { + override fun pulse(): Boolean { + for(item in bot.bank.toArray()) { + item ?: continue + if(!item.definition.isTradeable) {continue} + val itemAmt = item.amount + var actualId = item.id + if (ItemDefinition.forId(actualId).noteId == actualId){ + actualId = Item(actualId).noteChange + } + val canSell = GrandExchange.addBotOffer(actualId, itemAmt) + if (canSell && saleIsBigNews(actualId, itemAmt)) { + when (actualId){ + 1511 -> continue + 1513 -> continue + 1515 -> continue + 1517 -> continue + 1519 -> continue + 1521 -> continue + else -> sendNews(SERVER_GE_NAME + " just offered " + itemAmt + " " + ItemDefinition.forId(actualId).name.lowercase() + " on the GE.") + } + } + bot.bank.remove(item) + bot.bank.refresh() + } + return true + } + } + if (ge != null) { + bot.pulseManager.run(toCounterPulseAll()) + } + } + + /** + * Function to bank all items that are not excluded at a nearby bank. + * @author Kermit & Ceikry + */ + fun depositAtBank(){ + val bank: Scenery? = getNearestNode("Bank booth", true) as Scenery? + class BankingPulse : MovementPulse(bot, bank, DestinationFlag.OBJECT) { + override fun pulse(): Boolean { + bot.faceLocation(bank?.location) + for (item in bot.inventory.toArray()) { + item ?: continue + when (item.id) { + Items.RUNE_AXE_1359, Items.TINDERBOX_590, Items.ADAMANT_PICKAXE_1271, Items.COINS_995 -> continue + } + bot.bank.add(item) + bot.inventory.remove(item) + } +// log(this::class.java, Log.FINE, "${bot.username} Just finished banking at ${bot.location} || Bank contents: ${bot.bank}") + return true + } + } + if (bank != null) { + bot.pulseManager.run(BankingPulse()) + } + } + + /** + * Function to determine whether or not to bother everyone on the server + * with the big news that a bot is selling something to the GE, based on item value + * @param itemID + * @param amount + * @author Gexja + */ + fun saleIsBigNews(itemID: Int, amount: Int): Boolean { + return ItemDefinition.forId(itemID).getAlchemyValue(true) * amount >= (GameWorld.settings?.ge_announcement_limit + ?: 500) + } + + /** + * Function to teleport a bot to the given location. + * @param loc the location to teleport to + * @author Ceikry + */ + fun teleport(loc: Location) : Boolean { + if (bot.isTeleBlocked) { + return false + } + bot.lock() + bot.visualize(ANIMATIONUP, GRAPHICSUP) + bot.impactHandler.disabledTicks = 4 + val location = loc + GameWorld.Pulser.submit(object : Pulse(4, bot) { + override fun pulse(): Boolean { + bot.unlock() + bot.properties.teleportLocation = location + bot.pulseManager.clear() + bot.animator.reset() + return true + } + }) + return true + } + + /** + * Takes the given item out of the bot's inventory and places it into the bank. Banks all items with matching ID. + * @param item the ID of the item to bank + * @author Ceikry + */ + fun bankItem(item: Int){ + class BankingPulse() : Pulse(20){ + override fun pulse(): Boolean { + val logs = bot.inventory.getAmount(item) + bot.inventory.remove(Item(item, logs)) + bot.bank.add(Item(item, logs)) + return true + } + } + bot.pulseManager.run(BankingPulse()) + } + + /** + * Takes every item out of the bots inventory and places it into the bank. + * @param none + * @author cfunnyman joe + */ + fun bankAll(onComplete: (() -> Unit)? = null){ + class BankingPulse() : Pulse(20){ + override fun pulse(): Boolean { + for(item in bot.inventory.toArray()){ + if(item != null) { + var itemAmount = bot.inventory.getAmount(item) + + if(bot.inventory.remove(item)) { + bot.bank.add(item) + } + } + } + if(onComplete != null) { + onComplete?.invoke() + } + return true + } + } + bot.pulseManager.run(BankingPulse()) + } + + /** + * Function that makes the bot eat the food item in their inventory if their HP is below 2/3. + * @author Ceikry + * @param foodId the ID of the food item to eat + */ + fun eat(foodId: Int) { + val foodItem = Item(foodId) + if (bot.skills.getStaticLevel(Skills.HITPOINTS) * RandomFunction.random(0.5, 0.75) >= bot.skills.lifepoints && bot.inventory.containsItem(foodItem)) { + bot.lock(3) + //this.animate(new Animation(829)); + val food = bot.inventory.getItem(foodItem) + var consumable: Consumable? = Consumables.getConsumableById(foodId)?.consumable + if (consumable == null) { + consumable = Food(intArrayOf(food.id), HealingEffect(1)) + } + consumable.consume(food, bot) + bot.properties.combatPulse.delayNextAttack(3) + } + } + + /** + * Same as the eat function, except that it forces the bot to eat regardless of HP. + * @author Ceikry + * @param foodId the ID of the food item to eat. + */ + fun forceEat(foodId: Int) { + val foodItem = Item(foodId) + if (bot.inventory.containsItem(foodItem)) { + bot.lock(3) + //this.animate(new Animation(829)); + val food = bot.inventory.getItem(foodItem) + var consumable: Consumable? = Consumables.getConsumableById(foodId)?.consumable + if (consumable == null) { + consumable = Food(intArrayOf(foodId), HealingEffect(1)) + } + consumable.consume(food, bot) + bot.properties.combatPulse.delayNextAttack(3) + } + } + + /** + * Function for buying items off the GE. + * @param itemID the id of the item to buy off the GE. + * @param amount the amount to buy. + * @return true if item was successfully bought, false if not. + */ + fun buyFromGE(bot: Player, itemID: Int, amount: Int){ + GlobalScope.launch { + val offer = GrandExchangeOffer() + offer.itemID = itemID + offer.sell = false + offer.offeredValue = checkPriceOverrides(itemID) ?: ItemDefinition.forId(itemID).value + offer.amount = amount + offer.player = bot + //GrandExchange.dispatch(bot, offer) + AIRepository.addOffer(bot, offer) + var bought: Boolean = false + val latch = CountDownLatch(1) + bot.pulseManager.run(object : Pulse(5) { + override fun pulse(): Boolean { + bought = offer.completedAmount == offer.amount + latch.countDown() + return true + } + }) + latch.await() + if(bought){ + bot.bank.add(Item(offer.itemID, offer.completedAmount)) + bot.bank.refresh() + } + } + } + + /** + * Method to allow a bot to withdraw items from its bank. + * @param itemID the item to withdraw. + * @param amount the amount to withdraw. + * @author Ceikry + */ + fun withdraw(itemID: Int, amount: Int){ + var item: Item? = null + if(bot.bank.containsItem(Item(itemID, amount))){ + item = Item(itemID, amount) + } else { + item = Item(itemID, bot.bank.getAmount(itemID)) + } + if(item.amount == 0) return + if(!bot.inventory.hasSpaceFor(item)){ + item.amount = bot.inventory.getMaximumAdd(item) + } + bot.bank.remove(item) + bot.inventory.add(item) + } + + /** + * Method to equip list of items and set stats + * Useful for starting a bot up + * @param items the list of items to equip + * @author dginovker + */ + fun equipAndSetStats(items: List?){ + if (items == null) return + for(item in items){ + equipAndSetStats(item) + } + } + + /** + * Method to equip a single item and set stats + * Useful for starting a bot up + * @param item the item to equip + * @author dginovker + */ + fun equipAndSetStats(item: Item){ + val configs = item.definition.handlers + val slot = configs["equipment_slot"] ?: return + bot.equipment.add(item, slot as Int, + false,false) + val reqs = configs["requirements"] + if(reqs != null) + for(req in configs["requirements"] as HashMap) + bot.skills.setStaticLevel(req.key, req.value) + bot.skills.updateCombatLevel() + } + + /** + * Method to load appearance and equipment from JSON + * Useful for starting a bot up + * @param json the JSON object to load from (dumped via ::dumpappearance) + * @author dginovker + */ + fun loadAppearanceAndEquipment(json: JSONObject?) { + if (json == null) return + bot.equipment.clear() + bot.appearance.parse(json["appearance"] as JSONObject) + val equipment = json["equipment"] as JSONArray + bot.equipment.parse(equipment) + bot.appearance.sync() + for (i in 0 until bot.equipment.capacity()) { + val item = bot.equipment.get(i) + if (item != null) { + equipAndSetStats(item) + } + } + // Set all combat stats to a function of the highest combat stat(otherwise you end up with lopsided stats) + val highestCombatSkill = bot.skills.getStaticLevel(bot.skills.highestCombatSkillId) + for (i in 0 until 7) { + bot.skills.setStaticLevel(i, max((highestCombatSkill * 0.75).toInt(), bot.skills.getStaticLevel(i))) + } + bot.skills.updateCombatLevel() + } + + fun getOverlay(): BottingOverlay { + return BottingOverlay(bot) + } + + /** + * Function to check for price overrides. + * @param id the id to check for overrides for. + * @author Ceikry + */ + fun checkPriceOverrides(id: Int): Int?{ + return when(id){ + else -> itemDefinition(id).getConfiguration(ItemConfigParser.GE_PRICE) + } + } + + class BottingOverlay(val player: Player){ + fun init(){ + player.interfaceManager.openOverlay(Component(195)) + player.packetDispatch.sendInterfaceConfig(195,5,true) + } + fun setTitle(title: String){ + player.packetDispatch.sendString(colorize("%B$title"),195,7) + } + fun setTaskLabel(label: String){ + player.packetDispatch.sendString(colorize("%B$label"),195,8) + } + fun setAmount(amount: Int){ + player.packetDispatch.sendString(colorize("%B$amount"),195,9) + } + } +} diff --git a/Server/src/main/core/game/bots/ScriptDescription.kt b/Server/src/main/core/game/bots/ScriptDescription.kt new file mode 100644 index 0000000..95ded9c --- /dev/null +++ b/Server/src/main/core/game/bots/ScriptDescription.kt @@ -0,0 +1,3 @@ +package core.game.bots + +annotation class ScriptDescription(vararg val value: String) diff --git a/Server/src/main/core/game/bots/ScriptIdentifier.kt b/Server/src/main/core/game/bots/ScriptIdentifier.kt new file mode 100644 index 0000000..a2a8cb5 --- /dev/null +++ b/Server/src/main/core/game/bots/ScriptIdentifier.kt @@ -0,0 +1,3 @@ +package core.game.bots + +annotation class ScriptIdentifier(val value: String) diff --git a/Server/src/main/core/game/bots/ScriptName.kt b/Server/src/main/core/game/bots/ScriptName.kt new file mode 100644 index 0000000..cf99dff --- /dev/null +++ b/Server/src/main/core/game/bots/ScriptName.kt @@ -0,0 +1,3 @@ +package core.game.bots + +annotation class ScriptName(val value: String) diff --git a/Server/src/main/core/game/bots/SkillingBotAssembler.kt b/Server/src/main/core/game/bots/SkillingBotAssembler.kt new file mode 100644 index 0000000..4e47773 --- /dev/null +++ b/Server/src/main/core/game/bots/SkillingBotAssembler.kt @@ -0,0 +1,45 @@ +package core.game.bots + +import core.game.node.item.Item +import core.game.world.map.Location + +class SkillingBotAssembler { + fun produce(type: Wealth, loc: Location): AIPlayer { + return assembleBot(AIPlayer(loc),type) + } + + fun assembleBot(bot: AIPlayer, type: Wealth): AIPlayer { + return when(type){ + Wealth.POOR -> equipSet(bot,POORSETS.random()) + Wealth.AVERAGE -> equipSet(bot,AVGSETS.random()) + Wealth.RICH -> equipSet(bot,RICHSETS.random()) + } + } + + fun equipSet(bot: AIPlayer, set: List): AIPlayer { + for(i in set){ + val item = Item(i) + val configs = item.definition.handlers + val slot = configs["equipment_slot"] ?: continue + if(bot.inventory.get(slot as Int) == null) { + bot.equipment.add(item, slot as Int,false,false) + } + val reqs = configs["requirements"] + if(reqs != null) + for(req in configs["requirements"] as HashMap) + bot.skills.setStaticLevel(req.key, req.value) + } + bot.skills.updateCombatLevel() + return bot + } + + enum class Wealth { + POOR, + AVERAGE, + RICH + } + + val POORSETS = arrayOf(listOf(542,544), listOf(581), listOf(6654,6655,6656), listOf(6654,6656), listOf(636,646), listOf(638,648), listOf(), listOf(), listOf()) + val AVGSETS = arrayOf(listOf(2649,342,344), listOf(2651,542,544), listOf(6654,6655,6656), listOf(6139,6141), listOf(9923,9924,9925), listOf(10400,10402,2649), listOf(10404,10406), listOf(12971,12978)) + val RICHSETS = arrayOf(listOf(10330,10332,2649), listOf(12873,12880,1046), listOf(13858,13861,13864), listOf(13887,13893), listOf(3481,3483), listOf(2653,2655), listOf(2661,2663), listOf(2591,2593), listOf(14490,14492)) +} diff --git a/Server/src/main/core/game/component/CloseEvent.java b/Server/src/main/core/game/component/CloseEvent.java new file mode 100644 index 0000000..3e87199 --- /dev/null +++ b/Server/src/main/core/game/component/CloseEvent.java @@ -0,0 +1,20 @@ +package core.game.component; + +import core.game.node.entity.player.Player; + +/** + * An event called when the interface gets closed. + * @author Emperor + */ +public interface CloseEvent { + + /** + * Called when the interface gets closed. + * @param player The player. + * @param c The component. + * @return {@code True} if successful, {@code false} if the component should + * remain open. + */ + boolean close(Player player, Component c); + +} \ No newline at end of file diff --git a/Server/src/main/core/game/component/Component.java b/Server/src/main/core/game/component/Component.java new file mode 100644 index 0000000..412ca8d --- /dev/null +++ b/Server/src/main/core/game/component/Component.java @@ -0,0 +1,174 @@ +package core.game.component; + +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.InterfaceManager; +import core.net.packet.PacketRepository; +import core.net.packet.context.InterfaceContext; +import core.net.packet.out.Interface; +import core.game.interaction.InterfaceListeners; + +/** + * Represents a component. + * @author Emperor + * + */ +public class Component { + + /** + * The component id. + */ + protected int id; + + /** + * The component definitions. + */ + protected final ComponentDefinition definition; + + /** + * The close event. + */ + protected CloseEvent closeEvent; + + /** + * The component plugin. + */ + protected ComponentPlugin plugin; + + /** + * If the component is hidden. + */ + private boolean hidden; + + /** + * Constructs a new {@code Component} {@code Object}. + * @param id The component id. + */ + public Component(int id) { + this.id = id; + this.definition = ComponentDefinition.forId(id); + this.plugin = definition.getPlugin(); + } + + /** + * Opens the component. + */ + public void open(Player player) { + InterfaceManager manager = player.getInterfaceManager(); + InterfaceListeners.runOpen(player,this); + if (definition == null) { + PacketRepository.send(Interface.class, new InterfaceContext(player, manager.getWindowPaneId(), manager.getDefaultChildId(), getId(), false)); + if (plugin != null) { + plugin.open(player, this); + } + return; + } + if (definition.getType() == InterfaceType.WINDOW_PANE) { + return; + } + if (definition.getType() == InterfaceType.TAB) { + PacketRepository.send(Interface.class, new InterfaceContext(player, definition.getWindowPaneId(manager.isResizable()), definition.getChildId(manager.isResizable()) + definition.getTabIndex(), getId(), definition.isWalkable())); + if (plugin != null) { + plugin.open(player, this); + } + return; + } + PacketRepository.send(Interface.class, new InterfaceContext(player, definition.getWindowPaneId(manager.isResizable()), definition.getChildId(manager.isResizable()), getId(), definition.isWalkable())); + if (plugin != null) { + plugin.open(player, this); + } + } + + /** + * Closes the component. + * @param player The player. + * @return {@code True} if the component can be closed. + */ + public boolean close(Player player) { + return (closeEvent == null || closeEvent.close(player, this)) && InterfaceListeners.runClose(player, this); + } + + /** + * Gets the id. + * @return The id. + */ + public int getId() { + return id; + } + + /** + * Gets the definition. + * @return The definition. + */ + public ComponentDefinition getDefinition() { + return definition; + } + + /** + * Gets the closeEvent. + * @return The closeEvent. + */ + public CloseEvent getCloseEvent() { + return closeEvent; + } + + /** + * Sets the closeEvent. + * @param closeEvent The closeEvent to set. + */ + public Component setCloseEvent(CloseEvent closeEvent) { + this.closeEvent = closeEvent; + return this; + } + + /** + * Sets the component unclosable. + * @param c The component. + */ + public static void setUnclosable(Player p, Component c) { + p.setAttribute("close_c_", true); + c.setCloseEvent(new CloseEvent() { + @Override + public boolean close(Player player, Component c) { + return !player.getAttribute("close_c_", false); + } + }); + } + + /** + * Sets the plugin. + * @param plugin the plugin. + */ + public void setPlugin(ComponentPlugin plugin) { + this.plugin = plugin; + } + + /** + * Gets the component plugin. + * @return the plugin. + */ + public ComponentPlugin getPlugin() { + if (plugin == null) { + ComponentPlugin p = ComponentDefinition.forId(getId()).getPlugin(); + if ((plugin = p) != null) { + return p; + } + } + return plugin; + } + + /** + * Gets the hidden value. + * @return The hidden. + */ + public boolean isHidden() { + return hidden; + } + + /** + * Sets the hidden value. + * @param hidden The hidden to set. + */ + public void setHidden(boolean hidden) { + this.hidden = hidden; + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/component/ComponentDefinition.java b/Server/src/main/core/game/component/ComponentDefinition.java new file mode 100644 index 0000000..3f64836 --- /dev/null +++ b/Server/src/main/core/game/component/ComponentDefinition.java @@ -0,0 +1,178 @@ +package core.game.component; + + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.HashMap; +import java.util.Map; + +/** + * Represents the component definitions. + * @author Emperor + * + */ +public final class ComponentDefinition { + + /** + * The component definitions mapping. + */ + private static final Map DEFINITIONS = new HashMap(); + + /** + * The interface type. + */ + private InterfaceType type = InterfaceType.DEFAULT; + + /** + * The interface context. + */ + private boolean walkable; + + /** + * The tab index. + */ + private int tabIndex = -1; + + /** + * Represents the plugin handler. + */ + private ComponentPlugin plugin; + + /** + * Constructs a new {@code ComponentDefinition} {@code Object}. + */ + public ComponentDefinition() { + /* + * empty. + */ + } + + /** + * Parses the definition values from a result set. + * @throws SQLException The exception if thrown. + */ + public ComponentDefinition parse(String type, String walkable, String tabIndex){ + setType(InterfaceType.values()[Integer.parseInt(type)]); + setWalkable(Boolean.parseBoolean(walkable)); + setTabIndex(Integer.parseInt(tabIndex)); + return this; + } + + /** + * Gets the component definitions for the component id. + * @param componentId The component id. + * @return The component definitions. + */ + public static ComponentDefinition forId(int componentId) { + ComponentDefinition def = DEFINITIONS.get(componentId); + if (def == null) { + DEFINITIONS.put(componentId, def = new ComponentDefinition()); + } + return def; + } + + /** + * Add a plugin to a definition. + * @param id the id. + * @param plugin the plugin. + */ + public static void put(int id, ComponentPlugin plugin) { + ComponentDefinition.forId(id).setPlugin(plugin); + } + + /** + * Gets the definitions mapping. + * @return The definitions mapping. + */ + public static Map getDefinitions() { + return DEFINITIONS; + } + + /** + * Gets the plugin. + * @return The plugin. + */ + public ComponentPlugin getPlugin() { + return plugin; + } + + /** + * Sets the plugin. + * @param plugin The plugin to set. + */ + public void setPlugin(ComponentPlugin plugin) { + this.plugin = plugin; + } + + /** + * Gets the window pane id. + * @param resizable If the player is using resizable mode. + * @return The window pane id. + */ + public int getWindowPaneId(boolean resizable) { + return resizable ? type.getResizablePaneId() : type.getFixedPaneId(); + } + + /** + * Gets the child id. + * @param resizable If the player is using resizable mode. + * @return The child id. + */ + public int getChildId(boolean resizable) { + return resizable ? type.getResizableChildId() : type.getFixedChildId(); + } + + /** + * Gets the type. + * @return the type + */ + public InterfaceType getType() { + return type; + } + + /** + * Sets the batype. + * @param type the type to set. + */ + public void setType(InterfaceType type) { + this.type = type; + } + + /** + * Gets the walkable. + * @return the walkable + */ + public boolean isWalkable() { + return walkable; + } + + /** + * Sets the bawalkable. + * @param walkable the walkable to set. + */ + public void setWalkable(boolean walkable) { + this.walkable = walkable; + } + + /** + * Gets the tabIndex. + * @return the tabIndex + */ + public int getTabIndex() { + return tabIndex; + } + + /** + * Sets the batabIndex. + * @param tabIndex the tabIndex to set. + */ + public void setTabIndex(int tabIndex) { + this.tabIndex = tabIndex; + } + + @Override + public String toString() { + return "ComponentDefinition [type=" + type + ", walkable=" + walkable + ", tabIndex=" + tabIndex + ", plugin=" + plugin + "]"; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/component/ComponentPlugin.java b/Server/src/main/core/game/component/ComponentPlugin.java new file mode 100644 index 0000000..7bdbce0 --- /dev/null +++ b/Server/src/main/core/game/component/ComponentPlugin.java @@ -0,0 +1,35 @@ +package core.game.component; + +import core.game.node.entity.player.Player; +import core.plugin.Plugin; + +/** + * Represents the plugin used to handle a component reward. + * @author Vexia + */ +public abstract class ComponentPlugin implements Plugin { + + /** + * Handles the interface interaction. + * @param player The player. + * @param component The component. + * @param opcode The opcode. + * @param slot The slot. + * @param itemId The item id. + * @return {@code True} if succesfully handled. + */ + public abstract boolean handle(final Player player, Component component, final int opcode, final int button, int slot, int itemId); + + /** + * Called when this component opens. + * @param player The player + * @param component The component opening. + */ + public void open(Player player, Component component) {} + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + +} diff --git a/Server/src/main/core/game/component/InterfaceType.java b/Server/src/main/core/game/component/InterfaceType.java new file mode 100644 index 0000000..59dd77e --- /dev/null +++ b/Server/src/main/core/game/component/InterfaceType.java @@ -0,0 +1,123 @@ +package core.game.component; + + +import org.rs09.consts.Components; + +/** + * Represents an interface type. + * @author Emperor + * + */ +public enum InterfaceType { + + /** + * Default interface. + */ + DEFAULT(Components.TOPLEVEL_548, Components.TOPLEVEL_FULLSCREEN_746, 11, 6), + + /** + * Walkable interface. + */ + OVERLAY(Components.TOPLEVEL_548, Components.TOPLEVEL_FULLSCREEN_746, 4, 5), + + /** + * A tab interface. + */ + TAB(Components.TOPLEVEL_548, Components.TOPLEVEL_FULLSCREEN_746, 83, 93), + + /** + * The only tab to be shown (when this type is opened). + */ + SINGLE_TAB(Components.TOPLEVEL_548, Components.TOPLEVEL_FULLSCREEN_746, 80, 76), + + /** + * Chatbox dialogue interface. + */ + DIALOGUE(Components.CHATTOP_752, Components.CHATTOP_752, 12, 12), + + /** + * A window pane. + */ + WINDOW_PANE(Components.TOPLEVEL_548, Components.TOPLEVEL_FULLSCREEN_746, 0, 0), + + /** + * Client script chatbox interface. + */ + CS_CHATBOX(Components.CHATTOP_752, Components.CHATTOP_752, 6, 6), + + /** + * Chatbox interface. + */ + CHATBOX(Components.CHATTOP_752, Components.CHATTOP_752, 8, 8), + + /** + * Wilderness overlay + */ + OVERLAY_B(Components.TOPLEVEL_548, Components.TOPLEVEL_FULLSCREEN_746, 11, 3); + + /** + * The fixed window pane id. + */ + private final int fixedPaneId; + + /** + * The resizable window pane id. + */ + private final int resizablePaneId; + + /** + * The fixed child id. + */ + private final int fixedChildId; + + /** + * The resizable child id. + */ + private final int resizableChildId; + + /** + * Constructs a new {@Code InterfaceType} {@Code Object} + * @param fixedPaneId The fixed window pane id. + * @param resizablePaneId The resizable window pane id. + * @param fixedChildId The fixed child id. + * @param resizableChildId The resizable child id. + */ + private InterfaceType(int fixedPaneId, int resizablePaneId, int fixedChildId, int resizableChildId) { + this.fixedPaneId = fixedPaneId; + this.resizablePaneId = resizablePaneId; + this.fixedChildId = fixedChildId; + this.resizableChildId = resizableChildId; + } + + /** + * Gets the fixedPaneId. + * @return the fixedPaneId + */ + public int getFixedPaneId() { + return fixedPaneId; + } + + /** + * Gets the resizablePaneId. + * @return the resizablePaneId + */ + public int getResizablePaneId() { + return resizablePaneId; + } + + /** + * Gets the fixedChildId. + * @return the fixedChildId + */ + public int getFixedChildId() { + return fixedChildId; + } + + /** + * Gets the resizableChildId. + * @return the resizableChildId + */ + public int getResizableChildId() { + return resizableChildId; + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/consumable/BarbarianMix.java b/Server/src/main/core/game/consumable/BarbarianMix.java new file mode 100644 index 0000000..6cfe96c --- /dev/null +++ b/Server/src/main/core/game/consumable/BarbarianMix.java @@ -0,0 +1,16 @@ +package core.game.consumable; + +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +public class BarbarianMix extends Potion { + + public BarbarianMix(int[] ids, ConsumableEffect effect, String... messages) { + super(ids, effect, messages); + } + + @Override + protected void sendDefaultMessages(Player player, Item item) { + player.getPacketDispatch().sendMessage("You drink the lumpy potion."); + } +} diff --git a/Server/src/main/core/game/consumable/Cake.java b/Server/src/main/core/game/consumable/Cake.java new file mode 100644 index 0000000..bd72862 --- /dev/null +++ b/Server/src/main/core/game/consumable/Cake.java @@ -0,0 +1,47 @@ +package core.game.consumable; + +import content.data.consumables.Consumables; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +/** + * Represents any cake item that is made of three even slices. + */ +public class Cake extends Food { + + public Cake(int[] ids, ConsumableEffect effect, String... messages) { + super(ids, effect, messages); + } + + @Override + public void consume(Item item, Player player) { + executeConsumptionActions(player); + final int nextItemId = getNextItemId(item.getId()); + if (nextItemId != -1) { + player.getInventory().replace(new Item(nextItemId), item.getSlot()); + } else { + player.getInventory().remove(item); + } + final int initialLifePoints = player.getSkills().getLifepoints(); + Consumables.getConsumableById(item.getId()).getConsumable().effect.activate(player); + sendMessages(player, initialLifePoints, item, messages); + } + + @Override + protected void sendMessages(Player player, int initialLifePoints, Item item, String[] messages) { + if (messages.length == 0) { + sendDefaultMessages(player, item); + } else { + sendCustomMessages(player, messages, item.getId()); + } + sendHealingMessage(player, initialLifePoints); + } + + private void sendCustomMessages(final Player player, final String[] messages, int itemId) { + int i = 0; + while (ids[i] != itemId) { + i++; + } + player.getPacketDispatch().sendMessage(messages[i]); + } +} diff --git a/Server/src/main/core/game/consumable/Consumable.java b/Server/src/main/core/game/consumable/Consumable.java new file mode 100644 index 0000000..f300847 --- /dev/null +++ b/Server/src/main/core/game/consumable/Consumable.java @@ -0,0 +1,115 @@ +package core.game.consumable; + +import content.data.consumables.Consumables; +import core.api.Container; +import static core.api.ContentAPIKt.*; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; +import core.plugin.Plugin; + +/** + * Represents any item that has a consumption option such as 'Eat' or 'Drink'. + */ +public abstract class Consumable { + + /** + * Represents the item IDs of all the variants of a consumable where the last one is often the empty container, if it has any. + */ + protected final int[] ids; + + /** + * Represents the effect to apply on the player once the item is consumed. + */ + protected final ConsumableEffect effect; + + /** + * Represents the messages to send to the player when it consumes the item. + */ + protected final String[] messages; + + /** + * Represents the animation that the player will execute when consuming the item. + */ + protected Animation animation = null; + + public Consumable(final int[] ids, final ConsumableEffect effect, final String... messages) { + this.ids = ids; + this.effect = effect; + this.messages = messages; + } + + public Consumable(final int[] ids, final ConsumableEffect effect, final Animation animation, final String... messages) { + this.ids = ids; + this.effect = effect; + this.animation = animation; + this.messages = messages; + } + + public void consume(final Item item, final Player player) { + executeConsumptionActions(player); + final int nextItemId = getNextItemId(item.getId()); + + // STACKABLE + NON-RETURN + if (ids.length == 1) { + replaceSlot(player, item.getSlot(), new Item(item.getId(), (item.getAmount() - 1)), item, Container.INVENTORY); + } else { + // ITEM HAS RETURN + replaceSlot(player, item.getSlot(), new Item(nextItemId, 1), item, Container.INVENTORY); + } + + final int initialLifePoints = player.getSkills().getLifepoints(); + Consumables.getConsumableById(item.getId()).getConsumable().effect.activate(player); + sendMessages(player, initialLifePoints, item, messages); + } + + protected void sendMessages(final Player player, final int initialLifePoints, final Item item, String[] messages) { + if (messages.length == 0) { + sendDefaultMessages(player, item); + sendHealingMessage(player, initialLifePoints); + } else { + sendCustomMessages(player, messages); + } + } + + protected void sendHealingMessage(final Player player, final int initialLifePoints) { + if (player.getSkills().getLifepoints() > initialLifePoints) { + player.getPacketDispatch().sendMessage("It heals some health."); + } + } + + protected void sendCustomMessages(final Player player, final String[] messages) { + for (String message : messages) { + player.getPacketDispatch().sendMessage(message); + } + } + + protected abstract void sendDefaultMessages(final Player player, final Item item); + + protected abstract void executeConsumptionActions(Player player); + + protected int getNextItemId(final int currentConsumableId) { + for (int i = 0; i < ids.length; i++) { + if (ids[i] == currentConsumableId && i != ids.length - 1) { + return ids[i + 1]; + } + } + return -1; + } + + public String getFormattedName(Item item) { + return item.getName().replace("(4)", "").replace("(3)", "").replace("(2)", "").replace("(1)", "").trim().toLowerCase(); + } + + public int getHealthEffectValue(Player player) { + return effect.getHealthEffectValue(player); + } + + public ConsumableEffect getEffect() { + return effect; + } + + public int[] getIds() { + return ids; + } +} diff --git a/Server/src/main/core/game/consumable/ConsumableEffect.java b/Server/src/main/core/game/consumable/ConsumableEffect.java new file mode 100644 index 0000000..6b827ab --- /dev/null +++ b/Server/src/main/core/game/consumable/ConsumableEffect.java @@ -0,0 +1,12 @@ +package core.game.consumable; + + +import core.game.node.entity.player.Player; + +public abstract class ConsumableEffect { + public abstract void activate(Player p); + + public int getHealthEffectValue(Player player) { + return 0; + } +} diff --git a/Server/src/main/core/game/consumable/Drink.java b/Server/src/main/core/game/consumable/Drink.java new file mode 100644 index 0000000..e5b8611 --- /dev/null +++ b/Server/src/main/core/game/consumable/Drink.java @@ -0,0 +1,35 @@ +package core.game.consumable; + +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; + +import static core.api.ContentAPIKt.playAudio; + +public class Drink extends Consumable { + + public Drink(int[] ids, ConsumableEffect effect, String... messages) { + super(ids, effect, messages); + animation = new Animation(1327); + } + + public Drink(int[] ids, ConsumableEffect effect, Animation animation, String... messages) { + super(ids, effect, animation, messages); + } + + @Override + protected void sendDefaultMessages(Player player, Item item) { + player.getPacketDispatch().sendMessage("You drink the " + getFormattedName(item) + "."); + } + + @Override + protected void executeConsumptionActions(Player player) { + player.animate(animation); + playAudio(player, 4580); + } + + @Override + public String getFormattedName(Item item) { + return item.getName().replace("(4)", "").replace("(3)", "").replace("(2)", "").replace("(1)", "").replace("(m4)", "").replace("(m3)", "").replace("(m2)", "").replace("(m1)", "").replace("(m)", "").trim().toLowerCase(); + } +} diff --git a/Server/src/main/core/game/consumable/FakeConsumable.java b/Server/src/main/core/game/consumable/FakeConsumable.java new file mode 100644 index 0000000..94ff20c --- /dev/null +++ b/Server/src/main/core/game/consumable/FakeConsumable.java @@ -0,0 +1,31 @@ +package core.game.consumable; + +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +/** + * Represents a special type of consumable that cannot be consumed unless it is transformed into another item. + * During its 'consumption', only a message is sent to the player. + */ +public class FakeConsumable extends Consumable { + + public FakeConsumable(final int id, final String[] messages) { + super(new int[] {id}, null, messages); + } + + @Override + public void consume(Item item, Player player) { + sendDefaultMessages(player, item); + } + + @Override + protected void sendDefaultMessages(Player player, Item item) { + for (String message : messages) { + player.getPacketDispatch().sendMessage(message); + } + } + + @Override + protected void executeConsumptionActions(Player player) { + } +} diff --git a/Server/src/main/core/game/consumable/Food.java b/Server/src/main/core/game/consumable/Food.java new file mode 100644 index 0000000..d5b55bb --- /dev/null +++ b/Server/src/main/core/game/consumable/Food.java @@ -0,0 +1,35 @@ +package core.game.consumable; + +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playAudio; + +public class Food extends Consumable { + + public Food(final int[] ids, final ConsumableEffect effect, final String... messages) { + super(ids, effect, messages); + animation = new Animation(829); + } + + public Food(int[] ids, ConsumableEffect effect, Animation animation, String... messages) { + super(ids, effect, animation, messages); + } + + @Override + protected void sendDefaultMessages(Player player, Item item) { + player.getPacketDispatch().sendMessage("You eat the " + getFormattedName(item) + "."); + } + + @Override + protected void executeConsumptionActions(Player player) { + player.animate(animation); + playEatingSound(player); + } + + private void playEatingSound(Player player) { + playAudio(player, Sounds.EAT_2393); + } +} diff --git a/Server/src/main/core/game/consumable/HalfableFood.java b/Server/src/main/core/game/consumable/HalfableFood.java new file mode 100644 index 0000000..89e18f2 --- /dev/null +++ b/Server/src/main/core/game/consumable/HalfableFood.java @@ -0,0 +1,30 @@ +package core.game.consumable; + +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +/** + * Represents any food that is consumed in two parts such as pies and pizzas. + */ +public class HalfableFood extends Food { + + public HalfableFood(int[] ids, ConsumableEffect effect, String... messages) { + super(ids, effect, messages); + } + + @Override + protected void sendDefaultMessages(Player player, Item item) { + if (item.getId() == ids[0]) { + player.getPacketDispatch().sendMessage("You eat half the "+ getFormattedName(item) + "."); + } else if (item.getId() == ids[1]) { + player.getPacketDispatch().sendMessage("You eat the remaining " + getFormattedName(item) + "."); + } else { + super.sendDefaultMessages(player, item); + } + } + + @Override + public String getFormattedName(Item item) { + return item.getName().replace("1/2", "").replace("Half an", "").replace("Half a", "").trim().toLowerCase(); + } +} diff --git a/Server/src/main/core/game/consumable/Potion.java b/Server/src/main/core/game/consumable/Potion.java new file mode 100644 index 0000000..60afb00 --- /dev/null +++ b/Server/src/main/core/game/consumable/Potion.java @@ -0,0 +1,80 @@ +package core.game.consumable; + +import content.data.consumables.Consumables; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.audio.Audio; +import core.game.node.item.Item; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.playAudio; + +public class Potion extends Drink { + + private static final int VIAL = 229; + + private static final Audio SOUND = new Audio(2401, 1, 1); + + public Potion(final int[] ids, final ConsumableEffect effect, final String... messages) { + super(ids, effect, messages); + } + + @Override + public void consume(Item item, Player player) { + executeConsumptionActions(player); + final int nextItemId = getNextItemId(item.getId()); + if (nextItemId != -1) { + player.getInventory().replace(new Item(nextItemId), item.getSlot()); + } + else { + player.getInventory().replace(new Item(VIAL), item.getSlot()); + } + + final int initialLifePoints = player.getSkills().getLifepoints(); + Consumables.getConsumableById(item.getId()).getConsumable().effect.activate(player); + if (messages.length == 0) { + sendDefaultMessages(player, item); + } else { + sendCustomMessages(player, messages); + } + sendHealingMessage(player, initialLifePoints); + } + + @Override + protected void executeConsumptionActions(Player player) { + player.animate(animation); + playAudio(player, Sounds.LIQUID_2401); + } + + @Override + protected void sendDefaultMessages(Player player, Item item) { + int consumedDoses = 1; + int i = 0; + while (ids[i] != item.getId()) { + consumedDoses++; + i++; + } + final int dosesLeft = ids.length - consumedDoses; + player.getPacketDispatch().sendMessage("You drink some of your " + getFormattedName(item) + "."); + if (dosesLeft > 1) { + player.getPacketDispatch().sendMessage("You have " + dosesLeft + " doses of potion left."); + } else if (dosesLeft == 1) { + player.getPacketDispatch().sendMessage("You have 1 dose of potion left."); + } else { + player.getPacketDispatch().sendMessage("You have finished your potion."); + } + } + + public int getDose(Item potion){ + for (int i = 0; i < ids.length; i++) + if (ids[i] == potion.getId()) return ids.length - i; + return Integer.parseInt(potion.getName().replaceAll("[^\\d.]","")); + } + + public int[] getIds() { + return ids; + } + + public ConsumableEffect getEffect() { + return effect; + } +} diff --git a/Server/src/main/core/game/container/Container.java b/Server/src/main/core/game/container/Container.java new file mode 100644 index 0000000..5cecb69 --- /dev/null +++ b/Server/src/main/core/game/container/Container.java @@ -0,0 +1,1078 @@ +package core.game.container; + +import core.cache.def.impl.ItemDefinition; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.rs09.consts.Items; + +import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; + +import com.google.errorprone.annotations.CheckReturnValue; + + +/** + * Represents a container which contains items. + * + * @author Emperor + */ +public class Container { + + /** + * The item array. A crystalline + */ + private Item[] items; + + /** + * The capacity. + */ + private final int capacity; + + /** + * The current sort type. + */ + private SortType sortType; + + /** + * The current container type. + */ + private final ContainerType type; + + /** + * The current container event. + */ + private ContainerEvent event; + + /** + * The container listeners. + */ + private final List listeners = new ArrayList<>(20); + + /** + * Constructs a new {@code Container} {@code Object}. + * + * @param capacity The capacity. + */ + public Container(int capacity) { + this(capacity, ContainerType.DEFAULT); + } + + /** + * Constructs a new {@code Container.java} {@code Object}. + * + * @param capacity the capacity. + * @param items the items to add. + */ + public Container(int capacity, Item... items) { + this(capacity); + add(items); + } + + /** + * Constructs a new {@code Container} {@code Object}. + * + * @param capacity The capacity. + * @param type The container type. + */ + public Container(int capacity, ContainerType type) { + this(capacity, type, SortType.ID); + } + + /** + * Constructs a new {@code Container} {@code Object}. + * + * @param capacity The capacity. + * @param type The container type. + * @param sortType The sort type. + */ + public Container(int capacity, ContainerType type, SortType sortType) { + this.capacity = capacity; + this.type = type; + this.items = new Item[capacity]; + this.sortType = sortType; + this.event = new ContainerEvent(capacity); + } + + /** + * Registers a container listener. + * + * @param listener The container listener. + * @return This container instance, for chaining. + */ + public Container register(ContainerListener listener) { + listeners.add(listener); + return this; + } + + /** + * Adds the items. + * + * @param items The items to add. + * @return {@code True} if successfully added all items. + */ + public boolean add(Item... items) { + boolean addedAll = true; + for (Item item : items) { + if (item == null) { + continue; + } + if (!add(item, false)) { + addedAll = false; + break; + } + } + update(); + return addedAll; + } + + public void addList(List items){ + items.stream().filter(Objects::nonNull).forEach(this::add); + update(); + } + + /** + * Inserts an item into a specific slot. + * + * @param fromSlot The original slot of the item. + * @param toSlot The slot to insert into. + */ + public void insert(int fromSlot, int toSlot) { + insert(fromSlot, toSlot, true); + } + + /** + * Inserts an item into a specific slot. + * + * @param fromSlot The original slot of the item. + * @param toSlot The slot to insert into. + * @param update If the container packets should be sent. + */ + public void insert(int fromSlot, int toSlot, boolean update) { + Item temp = items[fromSlot]; + if (toSlot > fromSlot) { + for (int i = fromSlot; i < toSlot; i++) { + replace(get(i + 1), i, false); + } + } else if (fromSlot > toSlot) { + for (int i = fromSlot; i > toSlot; i--) { + replace(get(i - 1), i, false); + } + } + replace(temp, toSlot, update); + } + + /** + * Adds an item to this container if full it goes to ground. + * + * @param item the item. + * @param player the player. + * @return {@code True} if added. + */ + public boolean add(final Item item, final Player player) { + if (!add(item, true, -1)) { + GroundItemManager.create(item, player); + return false; + } + return true; + } + + public boolean addIfDoesntHave(final Item item) { + if (containsItem(item)) { + return false; + } else { + return add(item); + + } + } + + /** + * Adds an item to this container. + * + * @param item The item. + * @return {@code True} if the item got added. + */ + public boolean add(Item item) { + return add(item, true, -1); + } + + /** + * Adds an item to this container. + * + * @param item The item to add. + * @param fireListener If we should update. + * @return {@code True} if the item got added. + */ + public boolean add(Item item, boolean fireListener) { + return add(item, fireListener, -1); + } + + /** + * Adds an item to this container. + * + * @param item The item to add. + * @param fireListener If we should update. + * @param preferredSlot The slot to add the item in, when possible. + * @return {@code True} if the item got added. + */ + public boolean add(Item item, boolean fireListener, int preferredSlot) { + item = item.copy(); + int maximum = getMaximumAdd(item); + if (maximum == 0) { + return false; + } + if (preferredSlot > -1 && items[preferredSlot] != null) { + preferredSlot = -1; + } + if (item.getAmount() > maximum) { + item.setAmount(maximum); + } + if (type != ContainerType.NEVER_STACK && (item.getDefinition().isStackable() || type == ContainerType.ALWAYS_STACK || type == ContainerType.SHOP)) { + boolean hashBased = sortType == SortType.HASH; + for (int i = 0; i < items.length; i++) { + if (items[i] != null) { + if ((hashBased && items[i].getIdHash() == item.getIdHash()) || (!hashBased && items[i].getId() == item.getId())) { + int totalCount = item.getAmount() + items[i].getAmount(); + items[i] = new Item(items[i].getId(), totalCount, item.getCharge()); + items[i].setIndex(i); + event.flag(i, items[i]); + if (fireListener) { + update(); + } + return true; + } + } + } + int slot = preferredSlot > -1 ? preferredSlot : freeSlot(); + if (slot == -1) { + return false; + } + items[slot] = item; + item.setIndex(slot); + event.flag(slot, item); + if (fireListener) { + update(); + } + return true; + } + int slots = freeSlots(); + if (slots >= item.getAmount()) { + for (int i = 0; i < item.getAmount(); i++) { + int slot = i == 0 && preferredSlot > -1 ? preferredSlot : freeSlot(); + items[slot] = new Item(item.getId(), 1, item.getCharge()); + items[slot].setIndex(slot); + event.flag(slot, items[slot]); + } + if (fireListener) { + update(); + } + return true; + } + return false; + } + + /** + * Removes a set of items. + * + * @param items The set of items. + * @return {@code True} if all items got successfully removed. + */ + @CheckReturnValue + public boolean remove(Item... items) { + boolean removedAll = true; + for (Item item : items) { + if (!remove(item, false)) { + removedAll = false; + } + } + update(); + return removedAll; + } + + /** + * Removes an item. + * + * @param item The item. + * @return {@code True} if the item got removed, {@code false} if not. + */ + @CheckReturnValue + public boolean remove(Item item) { + return remove(item, true); + } + + /** + * Removes an item. + * + * @param item The item to remove. + * @param fireListener If the fire listener should be "notified". + * @return {@code True} if the item got removed,
{@code false} if not. + */ + @CheckReturnValue + public boolean remove(Item item, boolean fireListener) { + int slot = getSlot(item); + if (slot != -1) { + return remove(item, slot, fireListener); + } + return false; + } + + /** + * Removes an item from this container. + * + * @param item The item. + * @param slot The item slot. + * @param fireListener If the fire listener should be "notified". + * @return {@code True} if the item got removed,
{@code false} if the + * item on the slot was null or the ids didn't match. + */ + @CheckReturnValue + public boolean remove(Item item, int slot, boolean fireListener) { + if (!contains(item.getId(), item.getAmount())) + return false; + Item oldItem = items[slot]; + if (oldItem == null || oldItem.getId() != item.getId()) { + return false; + } + if (item.getAmount() < 1) { + return true; + } + if (oldItem.getDefinition().isStackable() || type.equals(ContainerType.ALWAYS_STACK) || type == ContainerType.SHOP) { + if (item.getAmount() >= oldItem.getAmount()) { + items[slot] = null; + event.flagNull(slot); + if (fireListener) { + update(); + } + return true; + } + items[slot] = new Item(item.getId(), oldItem.getAmount() - item.getAmount(), item.getCharge()); + items[slot].setIndex(slot); + event.flag(slot, items[slot]); + if (fireListener) { + update(); + } + return true; + } + items[slot] = null; + event.flagNull(slot); + int removed = 1; + for (int i = removed; i < item.getAmount(); i++) { + slot = getSlot(item); + if (slot != -1) { + items[slot] = null; + event.flagNull(slot); + } else { + break; + } + } + if (fireListener) { + update(); + } + return true; + } + + /** + * Removes all items from the container that have the passed in IDs + * + * @param ids Array of IDs to remove + * @return {@code True} if all the items got removed,
{@code false} if some of the + * found items were null + */ + public boolean removeAll(int[] ids) { + boolean removedAll = true; + for (int id : ids) { + if (!removeAll(id)) { + removedAll = false; + } + } + update(); + return removedAll; + } + + /** + * Removes all items from the container that have the passed in ID + * + * @param id Item ID to remove all instances of + * @return {@code True} if all the items got removed,
{@code false} if some of the + * found items were null + */ + public boolean removeAll(int id) { + ArrayList matchingIdItems = new ArrayList<>(); + for (Item item : this.items) { + // If the item is not null and the item ID matches the ID we're looking for + if (item != null && item.getId() == id) { + // Add the item to the list + matchingIdItems.add(item); + } + } + boolean res = true; + // Remove all the items from the container + for (Item item : matchingIdItems) { + if (!remove(item, false)) { + res = false; + } + } + return res; + } + + /** + * Replaces the item on the given slot with the argued item. + * + * @param item The item. + * @param slot The slot. + * @return The old item. + */ + public Item replace(Item item, int slot) { + return replace(item, slot, true); + } + + /** + * Replaces the item on the given slot with the argued item. + * + * @param item The item. + * @param slot The slot. + * @param fireListener If the listener should be "notified". + * @return The old item. + */ + public Item replace(Item item, int slot, boolean fireListener) { + if (item != null) { + if (item.getAmount() < 1 && type != ContainerType.SHOP) { + item = null; + } else { + item = item.copy(); + } + } + Item oldItem = items[slot]; + items[slot] = item; + if (item == null) { + event.flagNull(slot); + } else { + item.setIndex(slot); + event.flag(slot, item); + } + if (fireListener) { + update(); + } + return oldItem; + } + + /** + * Updates the container. + */ + public void update() { + if (event.getChangeCount() < 1 && !event.isClear()) { + return; + } + for (ContainerListener listener : listeners) { + listener.update(this, event); + } + event.setClear(false); + event = new ContainerEvent(capacity); + } + + /** + * Updates the container. + */ + public void update(boolean force) { + if (event.getChangeCount() < 1 && !force) { + return; + } + for (ContainerListener listener : listeners) { + listener.update(this, event); + } + event = new ContainerEvent(capacity); + } + + /** + * Refreshes the entire container. + */ + public void refresh() { + for (ContainerListener listener : listeners) { + listener.refresh(this); + } + event = new ContainerEvent(capacity); + } + + public void refresh(ContainerListener listener) { + listener.refresh(this); + event = new ContainerEvent(capacity); + } + + /** + * Gets the item on the given slot. + * + * @param slot The slot. + * @return The id of the item on the slot, or 0 if the item wasn't there. + */ + public int getAsId(int slot) { + if (slot < 0 || slot >= items.length || items[slot] == null) { + return 0; + } + return items[slot].getId(); + } + + + /** + * Gets the item on the given slot. + * + * @param slot The slot. + * @return The item on the slot, or {@code null} if the item wasn't there. + */ + public Item get(int slot) { + if (slot < 0 || slot >= items.length) { + return null; + } + return items[slot]; + } + + /** + * Gets the item on the given slot. + * + * @param slot The slot. + * @return The item on the slot, or a new constructed item with id 0 if the + * item wasn't there. + */ + public Item getNew(int slot) { + Item item = items[slot]; + if (item != null) { + return item; + } + return new Item(0); + } + + /** + * Gets the item id on the given slot. + * + * @param slot The slot. + * @return The id of the item on the slot. + */ + public int getId(int slot) { + if (slot >= items.length) { + return -1; + } + Item item = items[slot]; + if (item != null) { + return item.getId(); + } + return -1; + } + + public void parse(JSONArray itemArray){ + AtomicInteger total = new AtomicInteger(0); + itemArray.forEach(item -> { + JSONObject i = (JSONObject) item; + int slot = Integer.parseInt(i.get("slot").toString()); + int id = Integer.parseInt(i.get("id").toString()); + int amount = Integer.parseInt(i.get("amount").toString()); + int charge = Integer.parseInt(i.get("charge").toString()); + if (id >= ItemDefinition.getDefinitions().size() || id < 0 || slot >= items.length || id == Items.MAGIC_CARPET_5614) { + } else { + Item it = items[slot] = new Item(id,amount,charge); + it.setIndex(slot); + total.set(total.get() + (int)it.getValue()); + } + }); + } + + /** + * Copies the container to this container. + * + * @param c The container to copy. + */ + public void copy(Container c) { + items = new Item[c.items.length]; + for (int i = 0; i < items.length; i++) { + Item it = c.items[i]; + if (it == null) { + continue; + } + items[i] = new Item(it.getId(), it.getAmount(), it.getCharge()); + items[i].setIndex(i); + } + } + + /** + * Formats a container for the SQL database. + * + * @return the string. + */ + public String format() { + String log = ""; + Map map = new HashMap<>(); + Integer old = null; + for (Item item : items) { + if (item != null) { + old = map.get(item.getId()); + map.put(item.getId(), old == null ? item.getAmount() : old + item.getAmount()); + + } + } + for (int i : map.keySet()) { + log += i + "," + map.get(i) + "|"; + } + if (log.length() > 0 && log.charAt(log.length() - 1) == '|') { + log = log.substring(0, log.length() - 1); + } + return log; + } + + /** + * Checks if the container contains an item. + * + * @param item the Item + * @return {@code True} if so. + */ + public boolean containsItem(Item item) { + return contains(item.getId(), item.getAmount()); + } + + /** + * Checks if the containers contains these items. + * + * @param items the items. + * @return {@code True} if so. + */ + public boolean containsItems(Item... items) { + for (Item i : items) { + if (!containsItem(i)) { + return false; + } + } + return true; + } + + /** + * Checks if the container contains an item. + * + * @param itemId The item id. + * @param amount The amount. + * @return {@code True} if so. + */ + public boolean contains(int itemId, int amount) { + int count = 0; + for (Item item : items) { + if (item != null && item.getId() == itemId) { + if ((count += item.getAmount()) >= amount) { + return true; + } + } + } + return false; + } + + /** + * Checks if the containers contains at least ONE item. + * + * @param itemId + * @return + */ + public boolean containsAtLeastOneItem(int itemId) { + for (Item item : items) { + if (item != null && item.getId() == itemId && item.getAmount() > 0) { + return true; + } + } + return false; + } + + /** + * Checks if the containers contains AT LEAST ONE item from a list of items. + * @param itemIds + * @return true if at least one item from list of IDs is in the container + */ + public boolean containsAtLeastOneItem(int[] itemIds) { + for (int id : itemIds) { + if (getAmount(id) > 0) + return true; + } + return false; + } + + public boolean containsAtLeastOneItem(Item... items) { + for (Item item : items) { + if (containsItem(item)) { + return true; + } + } + return false; + } + + /** + * Checks if the container contains all items. + * + * @param itemIds to check + * @return {@code True} if so. + */ + public boolean containsAll(int... itemIds) { + for (int i : itemIds) { + if (!containsAtLeastOneItem(i)) { + return false; + } + } + return true; + } + + /** + * Adds a container to this container. + * + * @param container The container. + */ + public void addAll(Container container) { + add(container.items); + } + + /** + * Checks the maximum amount of this item we can add. + * + * @param item The item. + * @return The maximum amount we can add. + */ + public int getMaximumAdd(Item item) { + if (type != ContainerType.NEVER_STACK) { + if (item.getDefinition().isStackable() || type == ContainerType.ALWAYS_STACK || type == ContainerType.SHOP) { + if (contains(item.getId(), 1)) { + return Integer.MAX_VALUE - getAmount(item); + } + return freeSlots() > 0 ? Integer.MAX_VALUE : 0; + } + } + return freeSlots(); + } + + /** + * Checks if the container has space for the item. + * + * @param item The item to check. + * @return {@code True} if so. + */ + public boolean hasSpaceFor(Item item) { + return item.getAmount() <= getMaximumAdd(item); + } + + public boolean hasSpaceFor(Item... items) { + Container c = new Container(28, ContainerType.DEFAULT); + c.add(items); + return this.hasSpaceFor(c); + } + + /** + * Checks if this container has space to add the other container. + * + * @param c The other container. + * @return {@code True} if so. + */ + public boolean hasSpaceFor(Container c) { + if (c == null) { + return false; + } + Container check = new Container(capacity, type); + check.addAll(this); + for (Item item : c.items) { + if (item != null) { + if (!check.add(item, false)) { + return false; + } + } + } + return true; + } + + /** + * Gets the item slot. + * + * @param item The item. + * @return The slot of the item in this container. + */ + public int getSlot(Item item) { + if (item == null) { + return -1; + } + int id = item.getId(); + for (int i = 0; i < items.length; i++) { + Item it = items[i]; + if (it != null && it.getId() == id) { + return i; + } + } + return -1; + } + + /** + * Gets the item slot, taking into account the item's whole hash rather than just the ID part. + * + * @param item The item. + * @return The slot of the item in this container. + */ + public int getSlotHash(Item item) { + if (item == null) { + return -1; + } + int idHash = item.getIdHash(); + for (int i = 0; i < items.length; i++) { + Item it = items[i]; + if (it != null && it.getIdHash() == idHash) { + return i; + } + } + return -1; + } + + /** + * Gets the item instance. + * + * @param item the item. + * @return the item. + */ + public Item getItem(Item item) { + return get(getSlot(item)); + } + + public Item get(Item item){ + for(Item i : items){ + if(i == null) continue; + if(item.getId() == i.getId()) return i; + } + return null; + } + + /** + * Gets all instances of an item, and returns them. + * @author Player Name + * @param item the item. + * @return a list of all items that were found (can be length 0). + */ + public ArrayList getAll(Item item){ + ArrayList ret = new ArrayList(); + for(Item i : items){ + if(i == null) continue; + if(item.getId() == i.getId()) ret.add(i); + } + return ret; + } + + /** + * Gets the next free slot. + * + * @return The slot, or -1 if there are no available slots. + */ + public int freeSlot() { + for (int i = 0; i < items.length; i++) { + if (items[i] == null) { + return i; + } + } + return -1; + } + + /** + * Gets the slot of where to add the item. + * + * @param item The item to add. + * @return The slot where the item will go. + */ + public int getAddSlot(Item item) { + if (type != ContainerType.NEVER_STACK && (item.getDefinition().isStackable() || type.equals(ContainerType.ALWAYS_STACK) || type == ContainerType.SHOP)) { + boolean hashBased = sortType == SortType.HASH; + for (int i = 0; i < items.length; i++) { + if (items[i] != null) { + if ((hashBased && items[i].getIdHash() == item.getIdHash()) || (!hashBased && items[i].getId() == item.getId())) { + return i; + } + } + } + } + return freeSlot(); + } + + /** + * Gets the number of free slots. + * + * @return The number of free slots. + */ + public int freeSlots() { + return capacity - itemCount(); + } + + /** + * Gets the size of this container. + * + * @return The size of this container. + */ + public int itemCount() { + int size = 0; + for (int i = 0; i < items.length; i++) { + if (items[i] != null) { + size++; + } + } + return size; + } + + /** + * Checks if the player has all the item ids in the inventory. + * + * @param itemIds The item ids. + * @return {@code True} if so. + */ + public boolean containItems(int... itemIds) { + for (int i = 0; i < itemIds.length; i++) { + if (!contains(itemIds[i], 1)) { + return false; + } + } + return true; + } + + /** + * Gets the amount of an item. + * + * @param item The item. + * @return The amount of this item in this container. + */ + public int getAmount(Item item) { + if (item == null) { + return 0; + } + int count = 0; + for (Item i : items) { + if (i != null && i.getId() == item.getId()) { + count += i.getAmount(); + } + } + return count; + } + + /** + * Gets the amount. + * + * @param id the id. + * @return the amount. + */ + public int getAmount(int id) { + return getAmount(new Item(id)); + } + + /** + * Shifts the elements in the Container to the appropriate position. + */ + public void shift() { + final Item itemss[] = items; + clear(false); + for (Item item : itemss) { + if (item == null) { + continue; + } + add(item, false); + } + refresh(); + } + + /** + * Checks if the container is empty. + * + * @return {@code True} if so. + */ + public boolean isEmpty() { + for (Item item : items) { + if (item != null) { + return false; + } + } + return true; + } + + /** + * Checks if the container is full. + * + * @return {@code True} if so. + */ + public boolean isFull() { + return freeSlots() < 1; + } + + /** + * Clears and updates the container. + */ + public void clear() { + clear(true); + } + + /** + * Clears the container. + * + * @param update If the container should be updated. + */ + public void clear(boolean update) { + items = new Item[capacity]; + event.flagEmpty(); + if (update) { + refresh(); + } + } + + /** + * Gets the wealth. + * + * @return the wealth. + */ + public int getWealth() { + int wealth = 0; + for (Item i : items) { + if (i == null) { + continue; + } + wealth += i.getDefinition().getValue() * i.getAmount(); + } + return wealth; + } + + /** + * Returns an array representing this container. + * + * @return The array. + */ + public Item[] toArray() { + return items; + } + + /** + * Gets the listeners. + * + * @return The listeners. + */ + public List getListeners() { + return listeners; + } + + /** + * Gets the capacity. + * + * @return The capacity of this container. + */ + public int capacity() { + return capacity; + } + + /** + * Gets the event. + * + * @return the event. + */ + public ContainerEvent getEvent() { + return event; + } + + @Override + public String toString() { + return "Container{" + + "items=" + Arrays.toString(items) + + ", capacity=" + capacity + + ", sortType=" + sortType + + ", type=" + type + + ", event=" + event + + ", listeners=" + listeners + + '}'; + } +} diff --git a/Server/src/main/core/game/container/ContainerEvent.java b/Server/src/main/core/game/container/ContainerEvent.java new file mode 100644 index 0000000..6a47b0f --- /dev/null +++ b/Server/src/main/core/game/container/ContainerEvent.java @@ -0,0 +1,117 @@ +package core.game.container; + +import core.game.node.item.Item; + +/** + * Represents a container event. + * @author Emperor + */ +public final class ContainerEvent { + + /** + * Represents a null item. + */ + public static final Item NULL_ITEM = new Item(0, 0); + + /** + * The array of changed items. + */ + private final Item[] items; + + /** + * Clears the container. + */ + private boolean clear; + + /** + * Constructs a new {@code ContainerEvent} {@code Object}. + * @param size The container size. + */ + public ContainerEvent(int size) { + this.items = new Item[size]; + } + + /** + * Flags a null item on the given slot. + * @param slot The slot. + */ + public void flagNull(int slot) { + items[slot] = NULL_ITEM; + } + + /** + * Flags an item on the given slot. + * @param slot The slot. + * @param item The item. + */ + public void flag(int slot, Item item) { + items[slot] = item; + } + + /** + * Gets the amount of item slots changed. + * @return The amount of item slots that have changed. + */ + public int getChangeCount() { + int count = 0; + for (Item item : items) { + if (item != null) { + count++; + } + } + return count; + } + + /** + * Gets the updated slots. + * @return The slots array. + */ + public int[] getSlots() { + int size = 0; + int[] slots = new int[items.length]; + for (int i = 0; i < items.length; i++) { + if (items[i] != null) { + slots[size++] = i; + } + } + int[] slot = new int[size]; + for (int i = 0; i < size; i++) { + slot[i] = slots[i]; + } + return slot; + } + + /** + * Gets the items. + * @return The items. + */ + public Item[] getItems() { + return items; + } + + /** + * Flags an empty container. + */ + public void flagEmpty() { + this.clear = true; + for (int i = 0; i < items.length; i++) { + items[i] = null; + } + } + + /** + * Gets the clear. + * @return The clear. + */ + public boolean isClear() { + return clear; + } + + /** + * Sets the clear flag. + * @param clear The container is cleared. + */ + public void setClear(boolean clear) { + this.clear = clear; + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/container/ContainerListener.java b/Server/src/main/core/game/container/ContainerListener.java new file mode 100644 index 0000000..af3e71f --- /dev/null +++ b/Server/src/main/core/game/container/ContainerListener.java @@ -0,0 +1,21 @@ +package core.game.container; + +/** + * Represents a container listener. + * @author Emperor + */ +public interface ContainerListener { + + /** + * Updates the changed item slots in the container. + * @param c The container we're listening to. + * @param event The container event. + */ + void update(Container c, ContainerEvent event); + + /** + * Updates the entire container. + * @param c The container. + */ + void refresh(Container c); +} \ No newline at end of file diff --git a/Server/src/main/core/game/container/ContainerType.java b/Server/src/main/core/game/container/ContainerType.java new file mode 100644 index 0000000..27a55fa --- /dev/null +++ b/Server/src/main/core/game/container/ContainerType.java @@ -0,0 +1,29 @@ +package core.game.container; + +/** + * Represents the container types. + * @author Emperor + */ +public enum ContainerType { + + /** + * The default container type. + */ + DEFAULT, + + /** + * If the container is used for a shop. + */ + SHOP, + + /** + * The container should always stack items. + */ + ALWAYS_STACK, + + /** + * The container should never stack items. + */ + NEVER_STACK; + +} \ No newline at end of file diff --git a/Server/src/main/core/game/container/SortType.java b/Server/src/main/core/game/container/SortType.java new file mode 100644 index 0000000..9002398 --- /dev/null +++ b/Server/src/main/core/game/container/SortType.java @@ -0,0 +1,19 @@ +package core.game.container; + +/** + * The sort type of the container. + * @author Emperor + */ +public enum SortType { + + /** + * Sort by item id (default). + */ + ID, + + /** + * Sort by item identification hash (bank). + */ + HASH + +} \ No newline at end of file diff --git a/Server/src/main/core/game/container/access/InterfaceContainer.java b/Server/src/main/core/game/container/access/InterfaceContainer.java new file mode 100644 index 0000000..2fde474 --- /dev/null +++ b/Server/src/main/core/game/container/access/InterfaceContainer.java @@ -0,0 +1,167 @@ +package core.game.container.access; + +import core.api.IfaceSettingsBuilder; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.net.packet.PacketRepository; +import core.net.packet.context.ContainerContext; +import core.net.packet.out.ContainerPacket; + +/** + * Generates a set of items and options on an interface. + * @date 5/02/2013 + * @author Stacx + */ +public class InterfaceContainer { + + /** + * The client script index for set_options. + */ + private static final int CLIENT_SCRIPT_INDEX = 150; + + /** + * This index will increase each time a set is generated. + */ + private static int index = 600; // 93 + + /** + * Generates a container/array of items in an interface positioned on the + * child index. + * @param player , the player we generate this set for + * @param itemArray , the container/array of items we want to display + * @param options , the right-click options we want for the items + * @param interfaceIndex , the interface index + * @param childIndex , the child index of the interface where we display the + * items at. + * @return The container key. + */ + private static int generate(Player player, Item[] itemArray, String[] options, int interfaceIndex, int childIndex, int x, int y, int key) { + Object[] clientScript = new Object[options.length + 7]; + player.getPacketDispatch().sendRunScript(CLIENT_SCRIPT_INDEX, generateScriptArguments(options.length), populateScript(clientScript, options, interfaceIndex << 16 | childIndex, x, y, key)); + int settings = new IfaceSettingsBuilder().enableAllOptions().build(); + player.getPacketDispatch().sendIfaceSettings(settings, childIndex, interfaceIndex, 0, itemArray.length); + PacketRepository.send(ContainerPacket.class, new ContainerContext(player, -1, -2, key, itemArray, itemArray.length, false)); + return increment(); + } + + public static int generateOptions(Player player, String[] options, int interfaceIndex, int childIndex, int x, int y, int key){ + player.getPacketDispatch().sendRunScript(CLIENT_SCRIPT_INDEX, generateScriptArguments(options.length), populateScript(new Object[options.length + 7],options,interfaceIndex << 16 | childIndex, x, y, key)); + int settings = new IfaceSettingsBuilder().enableAllOptions().build(); + player.getPacketDispatch().sendIfaceSettings(settings, childIndex, interfaceIndex, 0, 28); + return increment(); + } + + /** + * Generates options for the interface item container. + * @param player The player. + * @param interfaceId The interface id. + * @param childId The child index. + * @param itemLength The amount of items. + * @param options The options. + * @return The container key. + */ + public static int generate(Player player, int interfaceId, int childId, int itemLength, String... options) { + return generate(player, interfaceId, childId, itemLength, 7, 3, options); + } + + /** + * Generates options for the interface item container. + * @param player The player. + * @param interfaceId The interface id. + * @param childId The child index. + * @param itemLength The amount of items. + * @param x The amount of items in a row. + * @param y The amount of item rows. + * @param options The options. + * @return The container key. + */ + public static int generate(Player player, int interfaceId, int childId, int itemLength, int x, int y, String... options) { + int key = increment(); + Object[] clientScript = new Object[options.length + 7]; + player.getPacketDispatch().sendRunScript(CLIENT_SCRIPT_INDEX, generateScriptArguments(options.length), populateScript(clientScript, options, interfaceId << 16 | childId, x, y, key)); + int settings = new IfaceSettingsBuilder().enableAllOptions().build(); + player.getPacketDispatch().sendIfaceSettings(settings, childId, interfaceId, 0, itemLength); + return key; + } + + /** + * Increments the current index. + * @return The previous index. + */ + private static int increment() { + if (index == 6999) { + index = 600; + } + return index++; + } + + /** + * Populates an object array used as a script for the client + * @param script , the array we want to populate + * @param options , the right-click options for our items + * @param hash , interfaceIndex << 16 | childIndex + * @return script, the populated script + */ + private static Object[] populateScript(Object[] script, String[] options, int hash, int x, int y, int key) { + int offset = 0; + for (String option : options) { + script[offset++] = option; + } + System.arraycopy(new Object[] { -1, 0, x, y, key, hash }, 0, script, offset, 6); + return script; + } + + /** + * Generates a script argument type string for the client (note: everything + * but a "s" is integer for the run script packet) + * @param length , the amount of options + * @return the generated string. + */ + private static String generateScriptArguments(int length) { + StringBuilder builder = new StringBuilder("IviiiI"); + while (length > 0) { + builder.append("s"); + length--; + } + return builder.toString(); + } + + /** + * Default method to generate and send an item array for the client. + * @return The container key. + */ + public static int generateItems(Player player, Item[] itemArray, String[] options, int interfaceIndex, int childIndex) { + return generateItems(player, itemArray, options, interfaceIndex, childIndex, 7, 3, increment()); + } + + /** + * Default method to generate and send an item array for the client. + * @return The container key. + */ + public static int generateItems(Player player, Item[] itemArray, String[] options, int interfaceIndex, int childIndex, int key) { + return generateItems(player, itemArray, options, interfaceIndex, childIndex, 7, 3, key); + } + + /** + * Method to generate the send items for the client with a specified + * location for the items. + * @param x , the x coordinate + * @param y , the y coordinate + * @return The container key. + */ + public static int generateItems(Player player, Item[] itemArray, String[] options, int interfaceIndex, int childIndex, int x, int y) { + return generateItems(player, itemArray, options, interfaceIndex, childIndex, x, y, increment()); + } + + /** + * Method to generate the send items for the client with a specified + * location for the items. + * @param x , the x coordinate + * @param y , the y coordinate + * @return The container key. + */ + public static int generateItems(Player player, Item[] itemArray, String[] options, int interfaceIndex, int childIndex, int x, int y, int key) { + return generate(player, itemArray, options, interfaceIndex, childIndex, x, y, key); + } + +} diff --git a/Server/src/main/core/game/container/impl/BankContainer.java b/Server/src/main/core/game/container/impl/BankContainer.java new file mode 100644 index 0000000..5fb9579 --- /dev/null +++ b/Server/src/main/core/game/container/impl/BankContainer.java @@ -0,0 +1,519 @@ +package core.game.container.impl; + +import core.api.IfaceSettingsBuilder; +import core.game.container.access.InterfaceContainer; +import kotlin.Unit; +import kotlin.ranges.IntRange; +import org.rs09.consts.Vars; +import core.ServerConstants; +import core.game.component.Component; +import core.game.container.*; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.IronmanMode; +import core.game.node.item.Item; +import core.game.system.config.ItemConfigParser; +import core.game.world.GameWorld; +import core.net.packet.PacketRepository; +import core.net.packet.context.ContainerContext; +import core.net.packet.out.ContainerPacket; + +import java.nio.ByteBuffer; + +import static core.api.ContentAPIKt.*; + + +/** + * Represents the bank container. + * @author Emperor + */ +public final class BankContainer extends Container { + + /** + * The bank container size. + */ + public static final int SIZE = ServerConstants.BANK_SIZE; + + /** + * The maximum amount of bank tabs + */ + public static final int TAB_SIZE = 11; + + /** + * The player reference. + */ + private Player player; + + /** + * The bank listener. + */ + private final BankListener listener; + + /** + * If the bank is open. + */ + private boolean open; + + /** + * The last x-amount entered. + */ + private int lastAmountX = 50; + + /** + * The current tab index. + */ + private int tabIndex = 10; + + /** + * The tab start indexes. + */ + private final int[] tabStartSlot = new int[TAB_SIZE]; + + /** + * Construct a new {@code BankContainer} {@code Object}. + * @param player The player reference. + */ + public BankContainer(Player player) { + super(SIZE, ContainerType.ALWAYS_STACK, SortType.HASH); + super.register(listener = new BankListener(player)); + this.player = player; + } + + /** + * Method used to open the deposit box. + */ + public void openDepositBox() { + player.getInterfaceManager().open(new Component(11)).setCloseEvent((player, c) -> { + player.getInterfaceManager().openDefaultTabs(); + return true; + }); + player.getInterfaceManager().removeTabs(0, 1, 2, 3, 4, 5, 6); + refreshDepositBoxInterface(); + } + + /** + * Invalidates the visual state of deposit box interface + * forcing the client to re-draw the items + */ + public void refreshDepositBoxInterface() + { + InterfaceContainer.generateItems( + player, + player.getInventory().toArray(), + new String[] { + "Examine", + "Deposit-X", + "Deposit-All", + "Deposit-10", + "Deposit-5", + "Deposit-1" + }, 11, 15, 5, 7 + ); + } + + /** + * Open the bank. + */ + public void open() { + if (open) { + return; + } + if (player.getIronmanManager().checkRestriction(IronmanMode.ULTIMATE)) { + return; + } + if (!player.getBankPinManager().isUnlocked() && !GameWorld.getSettings().isDevMode()) { + player.getBankPinManager().openType(1); + return; + } + player.getInterfaceManager().openComponent(762).setCloseEvent((player, c) -> { + BankContainer.this.close(); + return true; + }); + player.getInterfaceManager().openSingleTab(new Component(763)); + super.refresh(); + player.getInventory().getListeners().add(listener); + player.getInventory().refresh(); + setVarp(player, 1249, lastAmountX); + int settings = new IfaceSettingsBuilder().enableOptions(new IntRange(0, 5)).enableExamine().enableSlotSwitch().build(); + player.getPacketDispatch().sendIfaceSettings(settings, 0, 763, 0, 27); + open = true; + } + + public void open(Player player) { + if (open) { + return; + } + if (player.getIronmanManager().checkRestriction(IronmanMode.ULTIMATE)) { + return; + } + if (!player.getBankPinManager().isUnlocked() && !GameWorld.getSettings().isDevMode()) { + player.getBankPinManager().openType(1); + return; + } + player.getInterfaceManager().openComponent(762).setCloseEvent((player1, c) -> { + BankContainer.this.close(); + return true; + }); + refresh(listener); + player.getInterfaceManager().openSingleTab(new Component(763)); + player.getInventory().getListeners().add(player.getBank().listener); + player.getInventory().refresh(); + setVarp(player, 1249, lastAmountX); + player.getPacketDispatch().sendIfaceSettings(1278, 73, 762, 0, SIZE); + int settings = new IfaceSettingsBuilder().enableOptions(new IntRange(0,5)).enableExamine().enableSlotSwitch().build(); + player.getPacketDispatch().sendIfaceSettings(settings, 0, 763, 0, 27); + player.getPacketDispatch().sendRunScript(1451, ""); + open = true; + + } + + /** + * Closes the bank. + */ + public void close() { + open = false; + player.getInventory().getListeners().remove(listener); + player.getInterfaceManager().closeSingleTab(); + player.removeAttribute("search"); + player.getPacketDispatch().sendRunScript(571, ""); + } + + /** + * Adds an item to the bank container. + * @param slot The item slot. + * @param amount The amount. + */ + public void addItem(int slot, int amount) { + if (slot < 0 || slot > player.getInventory().capacity() || amount < 1) { + return; + } + Item item = player.getInventory().get(slot); + if (item == null) { + return; + } + + if (!item.getDefinition().getConfiguration(ItemConfigParser.BANKABLE, true)) { + player.sendMessage("A magical force prevents you from banking this item"); + return; + } + + int maximum = player.getInventory().getAmount(item); + if (amount > maximum) { + amount = maximum; + } + + item = new Item(item.getId(), amount, item.getCharge()); + boolean unnote = !item.getDefinition().isUnnoted(); + + Item add = unnote ? new Item(item.getDefinition().getNoteId(), amount, item.getCharge()) : item; + if (unnote && !add.getDefinition().isUnnoted()) { + add = item; + } + + int maxCount = super.getMaximumAdd(add); + if (amount > maxCount) { + add.setAmount(maxCount); + item.setAmount(maxCount); + if (maxCount < 1) { + player.getPacketDispatch().sendMessage("There is not enough space left in your bank."); + return; + } + } + + if (player.getInventory().remove(item, slot, false)) { + int preferredSlot = -1; + if (tabIndex != 0 && tabIndex != 10 && !super.contains(add.getId(), 1)) { + preferredSlot = tabStartSlot[tabIndex] + getItemsInTab(tabIndex); + insert(freeSlot(), preferredSlot, false); + increaseTabStartSlots(tabIndex); + } + super.add(add, true, preferredSlot); + player.getInventory().update(); + } + } + + /** + * Takes a item from the bank container and adds one to the inventory + * container. + * @param slot The slot. + * @param amount The amount. + */ + public void takeItem(int slot, int amount) { + if (slot < 0 || slot > super.capacity() || amount <= 0) { + return; + } + Item item = get(slot); + if (item == null) { + return; + } + if (amount > item.getAmount()) { + amount = item.getAmount(); // It always stacks in the bank. + } + item = new Item(item.getId(), amount, item.getCharge()); + int noteId = item.getDefinition().getNoteId(); + Item add = isNoteItems() && noteId > 0 ? new Item(noteId, amount, item.getCharge()) : item; + int maxCount = player.getInventory().getMaximumAdd(add); + if (amount > maxCount) { + item.setAmount(maxCount); + add.setAmount(maxCount); + if (maxCount < 1) { + player.getPacketDispatch().sendMessage("Not enough space in your inventory."); + return; + } + } + if (isNoteItems() && noteId < 0) { + player.getPacketDispatch().sendMessage("This item can't be withdrawn as a note."); + add = item; + } + if (super.remove(item, slot, false)) { + player.getInventory().add(add, false); + } + if (get(slot) == null) { + int tabId = getTabByItemSlot(slot); + decreaseTabStartSlots(tabId); + shift(); + } else update(); + player.getInventory().update(); + } + + /** + * Updates the last x-amount entered. + * @param amount The amount to set. + */ + public void updateLastAmountX(int amount) { + this.lastAmountX = amount; + setVarp(player, 1249, amount); + } + + /** + * Gets the tab the item slot is in. + * @param itemSlot The item slot. + * @return The tab index. + */ + public int getTabByItemSlot(int itemSlot) { + int tabId = 0; + for (int i = 0; i < tabStartSlot.length; i++) { + if (itemSlot >= tabStartSlot[i]) { + tabId = i; + } + } + return tabId; + } + + /** + * Increases a tab's start slot. + * @param startId The start id. + */ + public void increaseTabStartSlots(int startId) { + for (int i = startId + 1; i < tabStartSlot.length; i++) { + tabStartSlot[i]++; + } + } + + /** + * Decreases a tab's start slot. + * @param startId The start id. + */ + public void decreaseTabStartSlots(int startId) { + if (startId == 10) { + return; + } + for (int i = startId + 1; i < tabStartSlot.length; i++) { + tabStartSlot[i]--; + } + if (getItemsInTab(startId) == 0) { + collapseTab(startId); + } + } + + /** + * Gets the array index for a tab. + * @param tabId The tab id. + * @return The array index. + */ + public static int getArrayIndex(int tabId) { + if (tabId == 41 || tabId == 74) { + return 10; + } + int base = 39; + for (int i = 1; i < 10; i++) { + if (tabId == base) { + return i; + } + base -= 2; + } + return -1; + } + + /** + * Sends the bank space values on the interface. + */ + public void sendBankSpace() { + setVarc(player, 192, capacity() - freeSlots()); + } + + /** + * Collapses a tab. + * @param tabId The tab index. + */ + public void collapseTab(int tabId) { + int size = getItemsInTab(tabId); + Item[] tempTabItems = new Item[size]; + for (int i = 0; i < size; i++) { + tempTabItems[i] = get(tabStartSlot[tabId] + i); + replace(null, tabStartSlot[tabId] + i, false); + } + shift(); + for (int i = tabId; i < tabStartSlot.length - 1; i++) { + tabStartSlot[i] = tabStartSlot[i + 1] - size; + } + tabStartSlot[10] = tabStartSlot[10] - size; + for (int i = 0; i < size; i++) { + int slot = freeSlot(); + replace(tempTabItems[i], slot, false); + } + refresh(); //We only refresh once. + } + + /** + * Sets the tab configs. + */ + public void setTabConfigurations() { + for (int i = 0; i < 8; i++) { + setVarbit(player, 4885 + i, getItemsInTab(i + 1)); + } + } + + /** + * Gets the amount of items in one tab. + * @param tabId The tab index. + * @return The amount of items in this tab. + */ + public int getItemsInTab(int tabId) { + return tabStartSlot[tabId + 1] - tabStartSlot[tabId]; + } + + /** + * Checks if the item can be added. + * @param item the item. + * @return {@code True} if so. + */ + public boolean canAdd(Item item) { + return item.getDefinition().getConfiguration(ItemConfigParser.BANKABLE, true); + } + + /** + * Gets the last x-amount. + * @return The last x-amount. + */ + public int getLastAmountX() { + return lastAmountX; + } + + /** + * If items have to be noted. + * @return If items have to be noted {@code true}. + */ + public boolean isNoteItems() { + return getVarbit(player, Vars.VARBIT_IFACE_BANK_NOTE_MODE) == 1; + } + + /** + * Set if items have to be noted. + * @param noteItems If items have to be noted {@code true}. + */ + public void setNoteItems(boolean noteItems) { + setVarbit(player, Vars.VARBIT_IFACE_BANK_NOTE_MODE, noteItems ? 1 : 0, true); + } + + /** + * Gets the tabStartSlot value. + * @return The tabStartSlot. + */ + public int[] getTabStartSlot() { + return tabStartSlot; + } + + /** + * Gets the tabIndex value. + * @return The tabIndex. + */ + public int getTabIndex() { + return tabIndex; + } + + /** + * Sets the tabIndex value. + * @param tabIndex The tabIndex to set. + */ + public void setTabIndex(int tabIndex) { + this.tabIndex = tabIndex == 0 ? 10 : tabIndex; + setVarbit(player, 4893, tabIndex + 1); + setAttribute(player, "bank:lasttab", tabIndex); + } + + /** + * Sets the insert items value. + * @param insertItems The insert items value. + */ + public void setInsertItems(boolean insertItems) { + setVarbit(player, Vars.VARBIT_IFACE_BANK_INSERT_MODE, insertItems ? 1 : 0, true); + } + + /** + * Gets the insert items value. + * @return {@code True} if inserting items mode is enabled. + */ + public boolean isInsertItems() { + return getVarbit(player, Vars.VARBIT_IFACE_BANK_INSERT_MODE) == 1; + } + + /** + * Checks if the bank is opened. + * @return {@code True} if so. + */ + public boolean isOpen() { + return open; + } + + /** + * Listens to the bank container. + * @author Emperor + */ + private static class BankListener implements ContainerListener { + + /** + * The player reference. + */ + private Player player; + + /** + * Construct a new {@code BankListener} {@code Object}. + * @param player The player reference. + */ + public BankListener(Player player) { + this.player = player; + } + + @Override + public void update(Container c, ContainerEvent event) { + if (c instanceof BankContainer) { + PacketRepository.send(ContainerPacket.class, new ContainerContext(player, 762, 64000, 95, event.getItems(), false, event.getSlots())); + } else { + PacketRepository.send(ContainerPacket.class, new ContainerContext(player, 763, 64000, 93, event.getItems(), false, event.getSlots())); + } + player.getBank().setTabConfigurations(); + player.getBank().sendBankSpace(); + } + + @Override + public void refresh(Container c) { + if (c instanceof BankContainer) { + PacketRepository.send(ContainerPacket.class, new ContainerContext(player, 762, 64000, 95, c.toArray(), c.capacity(), false)); + } else { + PacketRepository.send(ContainerPacket.class, new ContainerContext(player, 763, 64000, 93, c.toArray(), 28, false)); + } + player.getBank().setTabConfigurations(); + player.getBank().sendBankSpace(); + } + } +} diff --git a/Server/src/main/core/game/container/impl/EquipmentContainer.java b/Server/src/main/core/game/container/impl/EquipmentContainer.java new file mode 100644 index 0000000..1e5eba3 --- /dev/null +++ b/Server/src/main/core/game/container/impl/EquipmentContainer.java @@ -0,0 +1,375 @@ +package core.game.container.impl; + +import content.global.skill.skillcapeperks.SkillcapePerks; +import core.game.container.Container; +import core.game.container.ContainerEvent; +import core.game.container.ContainerListener; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.player.Player; +import core.game.node.entity.skill.Skills; +import core.game.node.item.Item; +import core.net.packet.PacketRepository; +import core.net.packet.context.ContainerContext; +import core.net.packet.out.ContainerPacket; +import core.net.packet.out.WeightUpdate; +import core.plugin.Plugin; +import org.jetbrains.annotations.Nullable; +import core.game.interaction.InteractionListeners; +import core.game.system.config.ItemConfigParser; + +import java.util.ArrayList; + +import static core.api.ContentAPIKt.*; + +/** + * Represents the equipment container. + * @author Emperor + */ +public final class EquipmentContainer extends Container { + /** + * The equipment slots. + */ + public static final int SLOT_HAT = 0, SLOT_CAPE = 1, SLOT_AMULET = 2, SLOT_WEAPON = 3, SLOT_CHEST = 4, SLOT_SHIELD = 5, SLOT_LEGS = 7, SLOT_HANDS = 9, SLOT_FEET = 10, SLOT_RING = 12, SLOT_ARROWS = 13; + + /** + * The bonus names. + */ + private static final String[] BONUS_NAMES = { "Stab: ", "Slash: ", "Crush: ", "Magic: ", "Ranged: ", "Stab: ", "Slash: ", "Crush: ", "Magic: ", "Ranged: ", "Summoning: ", "Strength: ", "Prayer: " }; + + /** + * The player. + */ + private final Player player; + + /** + * Constructs a new {@code EquipmentContainer} {@code Object}. + * @param player The player. + */ + public EquipmentContainer(Player player) { + super(14); + this.player = player; + register(new EquipmentListener(player)); + } + + @Override + public boolean add(Item item, boolean fire) { + return add(item, fire, true); + } + + /** + * Adds an item to the equipment container. + * @param item The item to add. + * @param fire If we should refresh. + * @param fromInventory If the item is being equipped from the inventory. + * @return {@code True} if succesful, {@code false} if not. + */ + public boolean add(Item item, boolean fire, boolean fromInventory) { + return add(item, player.getInventory().getSlot(item), fire, fromInventory); + } + + /** + * Adds an item to the equipment container. + * @param newItem The item to add. + * @param inventorySlot The inventory slot of the item to add. + * @param fire If we should refresh. + * @param fromInventory If the item is being equipped from the inventory. + * @return {@code True} if succesful, {@code false} if not. + */ + public boolean add(Item newItem, int inventorySlot, boolean fire, boolean fromInventory) { + int equipmentSlot = newItem.getDefinition().getConfiguration(ItemConfigParser.EQUIP_SLOT, -1); + if (!isEquippable(newItem, equipmentSlot)) return false; + + ArrayList itemsToRemove = new ArrayList<>(); + + Item currentItem = super.get(equipmentSlot); + if(currentItem != null) itemsToRemove.add(currentItem); + + Item secondaryEquip = getSecondaryEquipIfApplicable(newItem, equipmentSlot); + if(secondaryEquip != null) itemsToRemove.add(secondaryEquip); + + if(fromInventory && !player.getInventory().remove(newItem, inventorySlot, true)) { + return false; + } + + if (!itemsToRemove.isEmpty()) { + ArrayList invalidatedEntries = new ArrayList<>(); + for(Item current : itemsToRemove) { + if(current.getId() == newItem.getId() && current.getDefinition().isStackable()) { + addStackableItemToExistingStack(newItem, fromInventory, equipmentSlot, current); + invalidatedEntries.add(current); + } + } + itemsToRemove.removeAll(invalidatedEntries); + + if(itemsToRemove.isEmpty()) { + return true; + } + + boolean successfullyRemovedAll = tryUnequipCurrent(itemsToRemove, newItem, inventorySlot); + + if(!successfullyRemovedAll) { + if (fromInventory) player.getInventory().add(newItem); //add the item back in case we weren't able to remove the currently equipped item(s) + return false; + } + } + + super.replace(newItem, equipmentSlot, fire); + setWeaponInterfaceWeaponName(newItem); + return true; + } + + private boolean isEquippable(Item newItem, int slot) { + if (slot < 0) { + return false; + } + return newItem.getDefinition().hasRequirement(player, true, true); + } + + private void setWeaponInterfaceWeaponName(Item newItem) { + if (newItem.getSlot() == SLOT_WEAPON) { + player.getPacketDispatch().sendString(newItem.getName(), 92, 0); + } + } + + private boolean tryUnequipCurrent(ArrayList current, Item newItem, int preferredSlot) { + if(current.isEmpty()) return true; + int freeSlots = player.getInventory().freeSlots(); + int neededSlots = getNeededSlotsToUnequip(current); + + boolean hasSpaceForUnequippedItems = freeSlots >= neededSlots; + + if(!hasSpaceForUnequippedItems) { + player.getPacketDispatch().sendMessage("Not enough space in your inventory!"); + return false; + } + + boolean listenersSayWeCanUnequip = runUnequipHooks(current, newItem); + + boolean allRemoved = true; + for(Item item : current) { + if(!remove(item)) { + allRemoved = false; + break; + } + } + + boolean allAdded = allRemoved; + if(allRemoved) { + for (Item item : current) { + if (!player.getInventory().add(item, true, preferredSlot)) { + allAdded = false; + break; + } + } + } + + if (listenersSayWeCanUnequip && allRemoved && allAdded) return true; + else { + //put things back if we couldn't remove everything + for(Item item : current) { + if(!containsItem(item)) { + add(item); + } + } + } + + return false; + } + + private int getNeededSlotsToUnequip(ArrayList current) { + int neededSlots = 0; + + for(Item item : current) { + if(!item.getDefinition().isStackable()) { + neededSlots++; + } else { + if(player.getInventory().getAmount(item.getId()) == 0) { + neededSlots++; + } + } + } + return neededSlots; + } + + @Nullable + private Item getSecondaryEquipIfApplicable(Item newItem, int equipmentSlot) { + Item secondaryEquipItem = null; + if (newItem.getDefinition().getConfiguration(ItemConfigParser.TWO_HANDED, false)) { + secondaryEquipItem = get(SLOT_SHIELD); + } else if (equipmentSlot == SLOT_SHIELD) { + Item inSlot = player.getEquipment().get(SLOT_WEAPON); + if(inSlot != null && inSlot.getDefinition().getConfiguration(ItemConfigParser.TWO_HANDED, false)) + secondaryEquipItem = get(SLOT_WEAPON); + } + return secondaryEquipItem; + } + + private boolean runUnequipHooks(ArrayList currentItems, Item newItem) { + boolean canContinue = true; + + for(Item currentItem : currentItems) { + Plugin plugin = currentItem.getDefinition().getConfiguration("equipment", null); + if (plugin != null) { + Object object = plugin.fireEvent("unequip", player, currentItem, newItem); + if (object != null && !((Boolean) object)) { + canContinue = false; + break; + } + } + + canContinue = InteractionListeners.run(currentItem.getId(), player, currentItem, false); + + if(!canContinue) break; + } + + return canContinue; + } + + private void addStackableItemToExistingStack(Item item, boolean fromInventory, int slot, Item current) { + int amount = getMaximumAdd(item); + if (item.getAmount() > amount) { + amount += current.getAmount(); + } else { + amount = current.getAmount() + item.getAmount(); + } + Item transferItem = new Item(current.getId(), amount); + if (fromInventory) { + player.getInventory().remove(transferItem); + } + replace(transferItem, slot); + } + + /** + * Listens to the equipment container. + * @author Emperor + */ + private static class EquipmentListener implements ContainerListener { + + /** + * The player. + */ + private final Player player; + + /** + * Constructs a new {@code EquipmentContainer} {@code Object}. + * @param player The player. + */ + public EquipmentListener(Player player) { + this.player = player; + } + + @Override + public void update(Container c, ContainerEvent event) { + int[] slots = event.getSlots(); + PacketRepository.send(ContainerPacket.class, new ContainerContext(player, 387, 28, 94, event.getItems(), false, slots)); + update(c); + boolean updateDefenceAnimation = false; + for (int slot : slots) { + if (slot == EquipmentContainer.SLOT_WEAPON) { + player.getProperties().setAttackSpeed(c.getNew(slot).getDefinition().getConfiguration(ItemConfigParser.ATTACK_SPEED, 4)); + WeaponInterface inter = player.getExtension(WeaponInterface.class); + if (inter == null) { + break; + } + inter.updateInterface(); + updateDefenceAnimation = true; + } else if (slot == EquipmentContainer.SLOT_SHIELD) { + updateDefenceAnimation = true; + } + } + if (updateDefenceAnimation) { + player.getProperties().updateDefenceAnimation(); + } + } + + @Override + public void refresh(Container c) { + player.getProperties().setAttackSpeed(c.getNew(3).getDefinition().getConfiguration(ItemConfigParser.ATTACK_SPEED, 4)); + WeaponInterface inter = player.getExtension(WeaponInterface.class); + if (inter != null) { + inter.updateInterface(); + } + PacketRepository.send(ContainerPacket.class, new ContainerContext(player, 387, 28, 94, c.toArray(), 14, false)); + update(c); + player.getProperties().updateDefenceAnimation(); + } + + /** + * Updates the bonuses, weight, animations, ... + * @param c The container. + */ + public void update(Container c) { + if (c.getNew(SLOT_SHIELD).getId() != 11283 && player.getAttribute("dfs_spec", false)) { + player.removeAttribute("dfs_spec"); + player.getProperties().getCombatPulse().setHandler(null); + if (!player.getSettings().isSpecialToggled()) { + setVarp(player, 301, 0); + } + } + player.getAppearance().setAnimations(); + player.updateAppearance(); + player.getSettings().updateWeight(); + updateBonuses(player); + } + } + + /** + * Updates the bonuses. + * @param player The player. + */ + public static void updateBonuses(Player player) { + int[] bonuses = new int[15]; + for (Item item : player.getEquipment().toArray()) { + if (item != null) { + int[] bonus = item.getDefinition().getConfiguration(ItemConfigParser.BONUS, new int[15]); + for (int i = 0; i < bonus.length; i++) { + bonuses[i] += bonus[i]; + } + } + } + Item weapon = player.getEquipment().get(SLOT_WEAPON); + if(weapon != null && weapon.getDefinition().getRequirement(Skills.STRENGTH) > 0 && SkillcapePerks.isActive(SkillcapePerks.FINE_ATTUNEMENT,player)){ + int[] bonus = weapon.getDefinition().getConfiguration(ItemConfigParser.BONUS, new int[15]); + bonuses[11] += Math.ceil(bonus[11] * 0.20); + } + Item shield = player.getEquipment().get(SLOT_SHIELD); + if(shield != null && SkillcapePerks.isActive(SkillcapePerks.GRAND_BULLWARK,player)){ + bonuses[5] += Math.ceil(bonuses[5] * 0.20); + bonuses[6] += Math.ceil(bonuses[6] * 0.20); + bonuses[7] += Math.ceil(bonuses[7] * 0.20); + bonuses[9] += Math.ceil(bonuses[9] * 0.20); + bonuses[10] += Math.ceil(bonuses[10] * 0.20); + } + if (shield != null && shield.getId() == 11283) { + int increase = shield.getCharge() / 20; + bonuses[5] += increase; + bonuses[6] += increase; + bonuses[7] += increase; + bonuses[9] += increase; + bonuses[10] += increase; + } + player.getProperties().setBonuses(bonuses); + update(player); + } + + /** + * Updates the equipment stats interface. + * @param player The player to update for. + */ + public static void update(Player player) { + if (!player.getInterfaceManager().hasMainComponent(667)) { + return; + } + int index = 0; + int[] bonuses = player.getProperties().getBonuses(); + for (int i = 36; i < 50; i++) { + if (i == 47) { + continue; + } + int bonus = bonuses[index]; + String bonusValue = bonus > -1 ? ("+" + bonus) : Integer.toString(bonus); + player.getPacketDispatch().sendString(BONUS_NAMES[index++] + bonusValue, 667, i); + } + player.getPacketDispatch().sendString("Attack bonus", 667, 34); + } +} diff --git a/Server/src/main/core/game/container/impl/InventoryListener.java b/Server/src/main/core/game/container/impl/InventoryListener.java new file mode 100644 index 0000000..4ef874f --- /dev/null +++ b/Server/src/main/core/game/container/impl/InventoryListener.java @@ -0,0 +1,65 @@ +package core.game.container.impl; + +import core.game.container.Container; +import core.game.container.ContainerEvent; +import core.game.container.ContainerListener; +import content.global.skill.summoning.SummoningPouch; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.net.packet.PacketRepository; +import core.net.packet.context.ContainerContext; +import core.net.packet.out.ContainerPacket; + +/** + * Handles the inventory container listening. + * @author Emperor + */ +public final class InventoryListener implements ContainerListener { + + /** + * The player. + */ + private final Player player; + + /** + * Constructs a new {@code InventoryListener} {@code Object}. + * @param player The player. + */ + public InventoryListener(Player player) { + this.player = player; + } + + /** + * Updates the required settings etc for the player when the container + * updates. + * @param c The container. + */ + public void update(Container c) { + player.getSettings().updateWeight(); + boolean hadPouch = player.getFamiliarManager().isHasPouch(); + boolean pouch = false; + for (Item item : c.toArray()) { + if (item != null && SummoningPouch.get(item.getId()) != null) { + pouch = true; + break; + } + } + player.getFamiliarManager().setHasPouch(pouch); + if (hadPouch != pouch) { + player.getAppearance().sync(); + } + } + + @Override + public void refresh(Container c) { + PacketRepository.send(ContainerPacket.class, new ContainerContext(player, 149, 0, 93, c, false)); + update(c); + } + + @Override + public void update(Container c, ContainerEvent event) { + PacketRepository.send(ContainerPacket.class, new ContainerContext(player, 149, 0, 93, event.getItems(), false, event.getSlots())); + update(c); + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/dialogue/ActivateEnchantedGem.java b/Server/src/main/core/game/dialogue/ActivateEnchantedGem.java new file mode 100644 index 0000000..7865f4d --- /dev/null +++ b/Server/src/main/core/game/dialogue/ActivateEnchantedGem.java @@ -0,0 +1,48 @@ +package core.game.dialogue; + +import content.global.skill.slayer.SlayerManager; +import core.cache.def.impl.ItemDefinition; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import core.plugin.Plugin; + +/** + * Represents the plugin used to handle the enchanted gem related to slayer. + * @author 'Vexia + * @version 1.0 + */ +@Initializable +public final class ActivateEnchantedGem extends OptionHandler { + + /** + * Constructs a new {@code ActivateEnchantedGem} {@Code Object}. + */ + public ActivateEnchantedGem() { + /** + * empty. + */ + } + + @Override + public boolean handle(Player player, Node node, String option) { + if (!SlayerManager.getInstance(player).hasStarted()) { + player.getPacketDispatch().sendMessage("You try to activate the gem..."); + return true; + } + player.getDialogueInterpreter().open(77777); + return true; + } + + @Override + public boolean isWalk() { + return false; + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + ItemDefinition.forId(4155).getHandlers().put("option:activate", this); + return this; + } +} diff --git a/Server/src/main/core/game/dialogue/DialogueAction.java b/Server/src/main/core/game/dialogue/DialogueAction.java new file mode 100644 index 0000000..4ed1a41 --- /dev/null +++ b/Server/src/main/core/game/dialogue/DialogueAction.java @@ -0,0 +1,18 @@ +package core.game.dialogue; + +import core.game.node.entity.player.Player; + +/** + * A dialogue reward. + * @author Vexia + */ +public interface DialogueAction { + + /** + * Handles a dialogue click. + * @param player the player. + * @param buttonId the buttonId. + */ + public void handle(Player player, int buttonId); + +} diff --git a/Server/src/main/core/game/dialogue/DialogueBuilder.kt b/Server/src/main/core/game/dialogue/DialogueBuilder.kt new file mode 100644 index 0000000..5b1f542 --- /dev/null +++ b/Server/src/main/core/game/dialogue/DialogueBuilder.kt @@ -0,0 +1,428 @@ +package core.game.dialogue + +import content.data.Quests +import core.api.splitLines +import core.game.node.entity.player.Player +import core.tools.END_DIALOGUE +import java.util.regex.Pattern + +val DEBUG_DIALOGUE = false +val NUMBER_PATTERN1 = Pattern.compile("^(\\d+) \\[label", Pattern.MULTILINE) +val NUMBER_PATTERN2 = Pattern.compile("(\\d+) -> (\\d+)") + +abstract class DialogueBuilderFile : DialogueFile() { + var data: ArrayList = ArrayList() + //var stages: ArrayList = ArrayList() + abstract fun create(b: DialogueBuilder) + init { + create(DialogueBuilder(this)) + if(DEBUG_DIALOGUE) { + var graphSb = StringBuilder("digraph {\n") + var nodeIndex = 0 + for((i, clause) in data.iterator().withIndex()) { + var clauseSb = StringBuilder() + for(j in 0 until clause.nodes.size) { + if(!(clause.nodes[j] is OptionsDispatchNode)) { + clauseSb.append("${j} ${clause.nodes[j].toString().replace("@indexPlus", "${j+1}").replace("@index", "${j}")}\n") + } + } + graphSb.append("subgraph cluster_${i} {\n") + var tmpSb = StringBuilder() + var m = NUMBER_PATTERN1.matcher(clauseSb) + while(m.find()) { + var x = Integer.valueOf(m.group(1)) + m.appendReplacement(tmpSb, "${x+nodeIndex} [label") + } + m.appendTail(tmpSb) + m = NUMBER_PATTERN2.matcher(tmpSb) + while(m.find()) { + var x = Integer.valueOf(m.group(1)) + var y = Integer.valueOf(m.group(2)) + m.appendReplacement(graphSb, "${x+nodeIndex} -> ${y+nodeIndex}") + } + m.appendTail(graphSb) + graphSb.append("}\n") + nodeIndex += clause.nodes.size + } + graphSb.append("}\n") + System.out.println(graphSb.toString()) + } + } + override fun handle(componentID: Int, buttonID: Int) { + for((i, clause) in data.iterator().withIndex()) { + if(clause.predicate(player!!)) { + stage = clause.handle(this, componentID, buttonID, stage) + if(stage == END_DIALOGUE) { + end() + } + return + } + } + } +} + +interface DialogueNode { + fun handle(df: DialogueFile, componentID: Int, buttonID: Int, stage: Int): Int +} + +class NpcLNode(val expression: FacialExpression, val value: String): DialogueNode { + override fun toString(): String { + return "[label=\"npcl(FacialExpression.${expression.name}, \\\"${value}\\\")\"]; @index -> @indexPlus;" + } + override fun handle(df: DialogueFile, componentID: Int, buttonID: Int, stage: Int): Int { + df.npcl(expression, value) + return stage + 1 + } +} +class NpcNode(val expression: FacialExpression, val values: Array): DialogueNode { + override fun toString(): String { + return "[label=\"npc(FacialExpression.${expression.name}, \\\"${values.contentDeepToString()}\\\")\"]; @index -> @indexPlus;" + } + override fun handle(df: DialogueFile, componentID: Int, buttonID: Int, stage: Int): Int { + df.npc(expression, *values) + return stage + 1 + } +} +class ItemNode(val item: Int, val values: Array): DialogueNode { + override fun toString(): String { + return "[label=\"item(${item}, \\\"${values.contentDeepToString()}\\\")\"]; @index -> @indexPlus;" + } + override fun handle(df: DialogueFile, componentID: Int, buttonID: Int, stage: Int): Int { + df.interpreter!!.sendItemMessage(item, *values) + return stage + 1 + } +} +class PlayerLNode(val expression: FacialExpression, val value: String): DialogueNode { + override fun toString(): String { + return "[label=\"playerl(FacialExpression.${expression.name}, \\\"${value}\\\")\"]; @index -> @indexPlus;" + } + override fun handle(df: DialogueFile, componentID: Int, buttonID: Int, stage: Int): Int { + df.playerl(expression, value) + return stage + 1 + } +} +class PlayerNode(val expression: FacialExpression, val values: Array): DialogueNode { + override fun toString(): String { + return "[label=\"player(FacialExpression.${expression.name}, \\\"${values.contentDeepToString()}\\\")\"]; @index -> @indexPlus;" + } + override fun handle(df: DialogueFile, componentID: Int, buttonID: Int, stage: Int): Int { + df.player(expression, *values) + return stage + 1 + } +} +class BetweenStageNode(val f: (DialogueFile, Player, Int, Int) -> Unit): DialogueNode { + override fun toString(): String { + return "[label=\"betweenstage(${(f as java.lang.Object).getClass().getName()})\"]; @index -> @indexPlus" + } + override fun handle(df: DialogueFile, componentID: Int, buttonID: Int, stage: Int): Int { + df.stage = stage + 1 // Simulates moving to this stage. + f(df, df.player!!, componentID, buttonID) // Calls callback function. + df.handle(componentID, buttonID) // Handles the current stage + return stage + 2 // Skips over the current stage. + } +} +class ManualStageNode(val f: (DialogueFile, Player, Int, Int) -> Unit): DialogueNode { + override fun toString(): String { + return "[label=\"manualstage(${(f as java.lang.Object).getClass().getName()})\"]; @index -> @indexPlus" + } + override fun handle(df: DialogueFile, componentID: Int, buttonID: Int, stage: Int): Int { + f(df, df.player!!, componentID, buttonID) + return stage + 1 + } +} +class ManualStageWithGotoNode(val f: (DialogueFile, Player, Int, Int, Int) -> Int, g: (Int) -> Int): DialogueNode { + override fun toString(): String { + return "[label=\"manualstagewithgoto(${(f as java.lang.Object).getClass().getName()})\"]; @index -> @indexPlus" + } + override fun handle(df: DialogueFile, componentID: Int, buttonID: Int, stage: Int): Int { + return f(df, df.player!!, componentID, buttonID, stage) + } +} + +class PlaceholderNode(val dbf: DialogueBuilderFile, val clauseIndex: Int, var targetStage: Int): DialogueNode { + override fun toString(): String { + return "[label=\"placeholder(${targetStage})\"]; @index -> ${targetStage}" + } + override fun handle(df: DialogueFile, componentID: Int, buttonID: Int, stage: Int): Int { + df.stage = targetStage + df.handle(componentID, buttonID) + return df.stage + } + + fun builder(): DialogueBuilder { + targetStage = dbf.data[clauseIndex].nodes.size + return DialogueBuilder(dbf, clauseIndex) + } +} + +class GotoNode(val node: PlaceholderNode): DialogueNode { + override fun toString(): String { + return "[label=\"goto(${node.targetStage})\"]; @index -> ${node.targetStage}" + } + override fun handle(df: DialogueFile, componentID: Int, buttonID: Int, stage: Int): Int { + df.stage = node.targetStage + df.handle(componentID, buttonID) + return df.stage + } +} + +class OptionEntry(val text: String, val nextStage: Int, val predicate: (Player) -> Boolean = { _ -> true }) {} +class OptionsData(val header: String, val entries: ArrayList, var attr: String? = null) {} + +class OptionsNode(var options: OptionsData): DialogueNode { + override fun toString(): String { + var ret = "[label=\"options(\\\"${options.header}\\\")\"]; " + for(entry in options.entries) { + ret += "@index -> ${entry.nextStage} [label=\"\\\"${entry.text}\\\"\"]; " + } + return ret + } + fun optionNames(player: Player): Array { + return options.entries.asSequence().filter({ it.predicate(player) }).map({ it.text }).toList().toTypedArray() + } + override fun handle(df: DialogueFile, componentID: Int, buttonID: Int, stage: Int): Int { + val tmp: Array = optionNames(df.player!!) + if(DEBUG_DIALOGUE) { + System.out.println("OptionsNode: ${tmp.size}") + for(i in 0 until tmp.size) { + System.out.println("tmp[${i}]: ${tmp[i]}") + } + } + if(tmp.size > 5) { + System.out.printf("Only a maximum of 5 options are supported by the interface") + return END_DIALOGUE + } else if(tmp.size > 1) { + df.interpreter!!.sendOptions(options.header, *tmp) + return stage + 1 + } else if(tmp.size == 1) { + val tmp: List = options.entries.asSequence().filter({ it.predicate(df.player!!) }).toList() + df.stage = tmp[0].nextStage + df.handle(componentID, 0) + return df.stage + } else { + return END_DIALOGUE + } + } +} +class OptionsDispatchNode(var options: OptionsData): DialogueNode { + override fun toString(): String { + return "[label=\"OptionsDispatchNode\"]" + } + override fun handle(df: DialogueFile, componentID: Int, buttonID: Int, stage: Int): Int { + val tmp: List = options.entries.asSequence().filter({ it.predicate(df.player!!) }).toList() + if(DEBUG_DIALOGUE) { + System.out.println("OptionsDispatchNode: ${tmp.size}") + } + if(options.attr != null) { + df.player!!.setAttribute(options.attr, buttonID-1) + } + df.stage = tmp[buttonID-1].nextStage + df.handle(componentID, 0) + return df.stage + } +} + +class DialogueClause(val predicate: (player: Player) -> Boolean, val nodes: ArrayList) { + fun handle(df: DialogueFile, componentID: Int, buttonID: Int, stage: Int): Int { + if(stage < nodes.size) { + return nodes[stage].handle(df, componentID, buttonID, stage) + } else { + return END_DIALOGUE + } + } +} + +class DialogueOptionsBuilder(var target: DialogueBuilderFile, val clauseIndex: Int, var options: OptionsData) { + fun option(value: String): DialogueBuilder { + options.entries.add(OptionEntry(value, target.data[clauseIndex].nodes.size)) + return DialogueBuilder(target, clauseIndex) + } + + fun optionIf(value: String, predicate: (Player) -> Boolean): DialogueBuilder { + options.entries.add(OptionEntry(value, target.data[clauseIndex].nodes.size, predicate)) + return DialogueBuilder(target, clauseIndex) + } + + fun option_playerl(value: String): DialogueBuilder { + return option(value).playerl(value) + } + + fun recordAttribute(name: String): DialogueOptionsBuilder { + options.attr = name + return this + } +} + +class BranchesData(val branches: HashMap, val f: (Player) -> Int) {} +class BranchNode(val branches: BranchesData): DialogueNode { + override fun toString(): String { + var ret = "[label=\"branch(\\\"${(branches.f as Object).getClass().getName()}\\\")\"]; " + for(entry in branches.branches) { + ret += "@index -> ${entry.value} [label=\"\\\"${entry.key}\\\"\"]; " + } + return ret + } + override fun handle(df: DialogueFile, componentID: Int, buttonID: Int, stage: Int): Int { + df.stage = branches.branches[branches.f(df.player!!)] ?: END_DIALOGUE + df.handle(componentID, buttonID) + return df.stage + } +} +class DialogueBranchBuilder(var target: DialogueBuilderFile, val clauseIndex: Int, var branches: BranchesData) { + fun onValue(value: Boolean): DialogueBuilder { + return onValue(if(value) { 1 } else { 0 }) + } + fun onValue(value: Int): DialogueBuilder { + val index = target.data[clauseIndex].nodes.size + branches.branches.put(value, index) + return DialogueBuilder(target, clauseIndex) + } +} + +class EndWithNode(val f: (DialogueFile, Player) -> Unit): DialogueNode { + override fun toString(): String { + return "[label=\"endWith(${(f as java.lang.Object).getClass().getName()})\"]"; + } + override fun handle(df: DialogueFile, componentID: Int, buttonID: Int, stage: Int): Int { + f(df, df.player!!) + return END_DIALOGUE + } +} + +class DialogueBuilder(var target: DialogueBuilderFile, var clauseIndex: Int = -1) { + companion object DialogueBuilderStatic { + @JvmStatic + fun endWithNoop(df: DialogueFile, player: Player) { + } + } + + /** + * The first if-statement to a dialogue. At minimum, you must have "b.onPredicate { _ -> true }" + * PLEASE BE CAREFUL ABOUT HAVING COMPLEX PREDICATE. + * If at any point during a dialogue that the predicate is not satisfied, + * it will block further dialogue progression and any dialogue will suddenly disappear. + * e.g. onPredicate(x==2) but during dialogue you set x=3, dialogue after it will disappear. + * Think of this as a repeated filter at every dialogue step. + */ + fun onPredicate(predicate: (player: Player) -> Boolean): DialogueBuilder { + target.data.add(DialogueClause(predicate, ArrayList())) + clauseIndex = target.data.size - 1 + return this + } + fun defaultDialogue(): DialogueBuilder { + return onPredicate({ _ -> return@onPredicate true}) + } + fun onQuestStages(name: Quests, vararg stages: Int): DialogueBuilder { + return onPredicate() { player -> + val questStage = player.questRepository.getStage(name) + return@onPredicate stages.contains(questStage) + } + } + fun playerl(value: String): DialogueBuilder { + target.data[clauseIndex].nodes.add(PlayerLNode(FacialExpression.NEUTRAL, value)) + return this + } + fun playerl(expression: FacialExpression, value: String): DialogueBuilder { + target.data[clauseIndex].nodes.add(PlayerLNode(expression, value)) + return this + } + fun player(vararg values: String): DialogueBuilder { + target.data[clauseIndex].nodes.add(PlayerNode(FacialExpression.NEUTRAL, values as Array)) + return this + } + fun player(expression: FacialExpression, vararg values: String): DialogueBuilder { + target.data[clauseIndex].nodes.add(PlayerNode(expression, values as Array)) + return this + } + fun npcl(value: String): DialogueBuilder { + target.data[clauseIndex].nodes.add(NpcLNode(FacialExpression.NEUTRAL, value)) + return this + } + fun npcl(expression: FacialExpression, value: String): DialogueBuilder { + target.data[clauseIndex].nodes.add(NpcLNode(expression, value)) + return this + } + fun npc(vararg values: String): DialogueBuilder { + target.data[clauseIndex].nodes.add(NpcNode(FacialExpression.NEUTRAL, values as Array)) + return this + } + fun npc(expression: FacialExpression, vararg values: String): DialogueBuilder { + target.data[clauseIndex].nodes.add(NpcNode(expression, values as Array)) + return this + } + fun item(item: Int, vararg values: String): DialogueBuilder { + target.data[clauseIndex].nodes.add(ItemNode(item, values as Array)) + return this + } + fun iteml(item: Int, value: String): DialogueBuilder { + return item(item, *splitLines(value)) + } + fun line(vararg values: String): DialogueBuilder { + return manualStage() { df, player, _, _ -> + df.interpreter!!.sendDialogue(*(values as Array)) + } + } + fun linel(value: String): DialogueBuilder { + return manualStage() { df, player, _, _ -> + df.interpreter!!.sendDialogue(*splitLines(value)) + } + } + fun endWith(f: (DialogueFile, Player) -> Unit) { + target.data[clauseIndex].nodes.add(EndWithNode(f)) + } + fun end() { + target.data[clauseIndex].nodes.add(EndWithNode(::endWithNoop)) + } + /** Runs block without the need for a DialogueFile df.something call. */ + fun betweenStage(f: (DialogueFile, Player, Int, Int) -> Unit): DialogueBuilder { + target.data[clauseIndex].nodes.add(BetweenStageNode(f)) + return this + } + fun manualStage(f: (DialogueFile, Player, Int, Int) -> Unit): DialogueBuilder { + target.data[clauseIndex].nodes.add(ManualStageNode(f)) + return this + } + fun manualStageWithGoto(f: (DialogueFile, Player, Int, Int, Int) -> Int, g: (Int) -> Int): DialogueBuilder { + target.data[clauseIndex].nodes.add(ManualStageWithGotoNode(f, g)) + return this + } + fun options(): DialogueOptionsBuilder { + return options("Select an Option") + } + fun options(header: String): DialogueOptionsBuilder { + val options: ArrayList = ArrayList() + val optionsData = OptionsData(header, options) + val node = OptionsNode(optionsData) + val dispatchNode = OptionsDispatchNode(optionsData) + target.data[clauseIndex].nodes.add(node) + target.data[clauseIndex].nodes.add(dispatchNode) + return DialogueOptionsBuilder(target, clauseIndex, optionsData) + } + + fun placeholder(): PlaceholderNode { + val node = PlaceholderNode(target, clauseIndex, END_DIALOGUE) + target.data[clauseIndex].nodes.add(node) + return node + } + + fun goto(node: PlaceholderNode): DialogueBuilder { + target.data[clauseIndex].nodes.add(GotoNode(node)) + return this + } + + fun branch(f: (Player) -> Int): DialogueBranchBuilder { + var branches = BranchesData(HashMap(), f) + target.data[clauseIndex].nodes.add(BranchNode(branches)) + return DialogueBranchBuilder(target, clauseIndex, branches) + } + + fun branchStages(f: (Player) -> Int): DialogueBranchBuilder { + var branches = BranchesData(HashMap(), f) + target.data[clauseIndex].nodes.add(BranchNode(branches)) + return DialogueBranchBuilder(target, clauseIndex, branches) + } + + fun branchBoolAttribute(attrName: String, defaultVal: Boolean): DialogueBranchBuilder { + return branch({ player -> return@branch if(player.getAttribute(attrName, defaultVal)) { 1 } else { 0 } }) + } +} diff --git a/Server/src/main/core/game/dialogue/DialogueFile.kt b/Server/src/main/core/game/dialogue/DialogueFile.kt new file mode 100644 index 0000000..226c962 --- /dev/null +++ b/Server/src/main/core/game/dialogue/DialogueFile.kt @@ -0,0 +1,179 @@ +package core.game.dialogue + +import core.api.splitLines +import core.cache.def.impl.NPCDefinition +import core.game.component.Component +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.tools.START_DIALOGUE + +abstract class DialogueFile { + var player: Player? = null + var npc: NPC? = null + var interpreter: DialogueInterpreter? = null + open var stage = START_DIALOGUE + var dialoguePlugin: DialoguePlugin? = null + + abstract fun handle(componentID: Int, buttonID: Int) + + fun load(player: Player, npc: NPC?, interpreter: DialogueInterpreter): DialogueFile { + this.player = player + this.npc = npc + this.interpreter = interpreter + interpreter.activeTopics.clear() + + return this + } + + open fun npc(vararg messages: String?): Component? { + if (npc != null) { + return interpreter!!.sendDialogues( + npc, + if (npc!!.id > 8591) FacialExpression.OLD_NORMAL else FacialExpression.FRIENDLY, + *messages + ) + } + return null + } + + open fun npc(id: Int, vararg messages: String?): Component? { + return interpreter!!.sendDialogues(id, FacialExpression.FRIENDLY, *messages) + } + + open fun npc(expression: FacialExpression?, vararg messages: String?): Component? { + return if (npc == null) { + interpreter!!.sendDialogues(0, expression, *messages) + } else interpreter!!.sendDialogues(npc, expression, *messages) + } + + open fun npc(id: Int, expression: FacialExpression?, vararg messages: String?): Component? { + val chatBoxComponent = interpreter!!.sendDialogues(id, expression, *messages) + return chatBoxComponent + } + + open fun npc(id: Int, title: String, expression: FacialExpression?, vararg messages: String?): Component? { + val chatBoxComponent = interpreter!!.sendDialogues(id, expression, *messages) + player!!.packetDispatch.sendString(title, chatBoxComponent.id, 3) + return chatBoxComponent + } + + open fun player(vararg messages: String?): Component? { + return interpreter!!.sendDialogues(player, null, *messages) + } + + open fun player(expression: FacialExpression?, vararg messages: String?): Component? { + return interpreter!!.sendDialogues(player, expression, *messages) + } + + /** + * Use the automatic linesplitting feature in DialUtils to produce npc dialogues + * @param expr the FacialExpression to use, located in the FacialExpression enum. + * @param msg the message for the NPC to say + */ + open fun npcl(expr: FacialExpression?, msg: String?): Component? { + return npc(expr, *splitLines(msg!!)) + } + + open fun npcl(id: Int, expr: FacialExpression?, msg: String?): Component? { + return npc(id, expr, *splitLines(msg!!)) + } + + open fun npcl(id: Int, title: String, expr: FacialExpression?, msg: String?): Component? { + return npc(id, title, expr, *splitLines(msg!!)) + } + + open fun npcl(msg: String?): Component? { + return npc(*splitLines(msg!!)) + } + + /** + * Use the automatic linesplitting feature in DialUtils to produce player dialogues + * @param expr the FacialExpression to use, located in the FacialExpression enum. + * @param msg the message for the player to say + */ + open fun playerl(expr: FacialExpression?, msg: String?): Component? { + return player(expr, *splitLines(msg!!)) + } + + open fun playerl(msg: String?): Component? { + return player(*splitLines(msg!!)) + } + + open fun end(){ + if(interpreter != null) interpreter!!.close() + } + + open fun sendNormalDialogue(entity: Entity?, expression: FacialExpression?, vararg messages: String?) { + interpreter!!.sendDialogues(entity, expression, *messages) + } + + open fun options(vararg options: String?, title: String = "Select an Option") { + interpreter!!.sendOptions(title, *options) + } + + /** + * Use in place of setting the stage to END_DIALOGUE when you want to return to the default dialogue plugin at START_DIALOGUE + */ + fun endFile(){ + interpreter!!.dialogue.file = null + + } + + /** + * Return to the default dialogue plugin at the given stage. + * Should be used in place of setting a new stage. I.E. instead of "stage = END_DIALOGUE" use "returnAtStage(whatever stage)" + * @param stage The stage to return to. + */ + fun returnAtStage(toStage: Int){ + dialoguePlugin!!.file = null + dialoguePlugin!!.stage = toStage + } + + /** + * Use when you've entered a DialogueFile but current state does not match any possible conditionals. + * Sort-of a fail-safe in a sense. + */ + fun abandonFile(){ + interpreter!!.dialogue.file = null + player("Huh. Nevermind.") + } + + open fun getCurrentStage(): Int{ + return stage + } + + fun Int.substage(stage: Int): Int{ + return this + stage + } + + fun dialogue(vararg messages: String){ + player?.dialogueInterpreter?.sendDialogue(*messages) + } + + fun showTopics(vararg topics: Topic<*>, title: String = "Select an Option"): Boolean { + val validTopics = ArrayList() + topics.filter { if(it is IfTopic) it.showCondition else true }.forEach { + topic -> interpreter!!.activeTopics.add(topic) + validTopics.add(topic.text) + } + if(validTopics.size == 0) { + return true + } + else if (validTopics.size == 1) { + val topic = topics[0] + if(topic.toStage is DialogueFile) { + val topicFile = topic.toStage as DialogueFile + interpreter!!.dialogue.loadFile(topicFile) + } else if(topic.toStage is Int) { + stage = topic.toStage as Int + } + player(topic.text) + interpreter!!.activeTopics.clear() + return false + } + else { options(*validTopics.toTypedArray(), title = title) + return false + } + } +} diff --git a/Server/src/main/core/game/dialogue/DialogueInterpreter.java b/Server/src/main/core/game/dialogue/DialogueInterpreter.java new file mode 100644 index 0000000..b37a610 --- /dev/null +++ b/Server/src/main/core/game/dialogue/DialogueInterpreter.java @@ -0,0 +1,631 @@ +package core.game.dialogue; + +import core.game.event.DialogueCloseEvent; +import core.game.event.DialogueOpenEvent; +import core.game.event.DialogueOptionSelectionEvent; +import core.cache.def.impl.ItemDefinition; +import core.cache.def.impl.NPCDefinition; +import core.game.component.Component; +import core.game.node.entity.Entity; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.GameWorld; +import core.net.packet.PacketRepository; +import core.net.packet.context.ChildPositionContext; +import core.net.packet.context.ContainerContext; +import core.net.packet.out.ContainerPacket; +import core.net.packet.out.RepositionChild; +import core.plugin.PluginManifest; +import core.plugin.PluginType; +import core.game.system.config.ItemConfigParser; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static core.tools.DialogueConstKt.END_DIALOGUE; + + +/** + * Handles the dialogues. + * @author Emperor + */ +@PluginManifest(type = PluginType.DIALOGUE) +public final class DialogueInterpreter { + public ArrayList> activeTopics = new ArrayList<>(); + + /** + * The dialogue plugins. + */ + private static final Map PLUGINS = new HashMap<>(); + + /** + * a List of dialogue actions. + */ + private final List actions = new ArrayList<>(10); + + /** + * The currently opened dialogue. + */ + private DialoguePlugin dialogue; + + /** + * The current dialogue key. + */ + private int key; + + /** + * The player. + */ + private final Player player; + + /** + * Constructs a new {@code DialogueInterpreter} {@code Object}. + * @param player The player. + */ + public DialogueInterpreter(Player player) { + this.player = player; + } + + /** + * @param dialogue the dialogue to set. + */ + public void setDialogue(DialoguePlugin dialogue) { + this.dialogue = dialogue; + } + + /** + * Opens the dialogue for the given dialogue type. + * @param dialogueType The dialogue type. + * @param args the args. + * @return {@code True} if successful. + */ + public boolean open(String dialogueType, Object... args) { + return open(getDialogueKey(dialogueType), args); + } + + /** + * Opens the dialogue for the given NPC id. + * @param dialogueKey The dialogue key (usually NPC id). + * @param args The arguments. + * @return {@code True} if successful. + */ + public boolean open(int dialogueKey, Object... args) { + key = dialogueKey; + if (args.length > 0 && args[0] instanceof NPC) { + NPC npc = (NPC) args[0]; + npc.setDialoguePlayer(player); + try { //this prevents the dialogue interpreter from dying when you try opening an NPC's dialogue without passing the NPC itself as an argument + npc.getWalkingQueue().reset(); + npc.getPulseManager().clear(); + } catch(Exception e){ + e.printStackTrace(); + } + } else if (args.length < 1) { + args = new Object[] { dialogueKey }; + } + DialoguePlugin plugin = PLUGINS.get(dialogueKey); + if (plugin == null) { + return false; + } + if (player.isDebug()) { + player.sendMessage("Dialogue opening - " + plugin.getClass().getSimpleName() + ", key=" + dialogueKey + ""); + } + this.dialogue = plugin.newInstance(player); + if (dialogue == null || !dialogue.open(args)) { + dialogue = null; + return false; + } + + if (dialogue != null) { + player.dispatch(new DialogueOpenEvent(dialogue)); + } + + return true; + } + + public void open(DialogueFile file, Object... args){ + this.dialogue = new EmptyPlugin(player,file); + this.dialogue.open(args); + } + + /** + * Handles an dialogue input. + * @param componentId The id of the chatbox component. + * @param buttonId The button id. + */ + public void handle(int componentId, int buttonId) { + player.setAttribute("chatbox-buttonid",buttonId); + if((player.getDialogueInterpreter().getDialogue().file != null && player.getDialogueInterpreter().getDialogue().file.getCurrentStage() == END_DIALOGUE) || player.getDialogueInterpreter().getDialogue().stage == END_DIALOGUE){ + player.getInterfaceManager().closeChatbox(); + player.getInterfaceManager().openChatbox(137); + player.getDialogueInterpreter().dialogue.finished = true; + close(); + return; + } + + DialogueFile file = dialogue.file; + if (!activeTopics.isEmpty() && buttonId >= 2) { + Topic topic = activeTopics.get(buttonId - 2); + + if (!topic.getSkipPlayer()) + sendDialogues(player, topic.getExpr(), topic.getText()); + + if(topic.getToStage() instanceof DialogueFile) { + DialogueFile topicFile = (DialogueFile) topic.getToStage(); + dialogue.loadFile(topicFile); + } else if(topic.getToStage() instanceof Integer) { + int stage = (Integer) topic.getToStage(); + if (file == null) dialogue.stage = stage; + else file.setStage(stage); + } + activeTopics.clear(); + + if (topic.getSkipPlayer()) + handle(componentId, buttonId); + + return; + } + + if(file != null){ + player.dispatch( + new DialogueOptionSelectionEvent( + file, + file.getStage(), + buttonId - 1 + ) + ); + + file.handle(componentId,buttonId - 1); + } else { + player.dispatch( + new DialogueOptionSelectionEvent( + dialogue, + dialogue.stage, + buttonId - 1 + ) + ); + + dialogue.handle(componentId, buttonId - 1);//here + } + } + + /** + * Closes the current dialogue. + * @return {@code True} if successful. + */ + public boolean close() { + if (dialogue != null) { + actions.clear(); + + if (player.getInterfaceManager().getChatbox() != null && player.getInterfaceManager().getChatbox().getCloseEvent() != null) { + return true; + } + if (dialogue != null) { + DialoguePlugin d = dialogue; + dialogue = null; + d.close(); + player.dispatch(new DialogueCloseEvent(d)); + } + } + activeTopics.clear(); + return dialogue == null; + } + + /** + * Puts a dialogue plugin on the mapping. + * @param id The NPC id (or {@code 1 << 16 | dialogueId} when the dialogue + * isn't for an NPC). + * @param plugin The plugin. + */ + public static void add(int id, DialoguePlugin plugin) { + if (PLUGINS.containsKey(id)) { + throw new IllegalArgumentException("Dialogue " + (id & 0xFFFF) + " is already in use - [old=" + PLUGINS.get(id).getClass().getSimpleName() + ", new=" + plugin.getClass().getSimpleName() + "]!"); + } + PLUGINS.put(id, plugin); + } + + /** + * Send plain messages based on the amount of specified messages. + * @param messages The messages. + * @return The chatbox component. + */ + public Component sendDialogue(String... messages) { + if (messages.length < 1 || messages.length > 4) { + return null; + } + int interfaceId = 209 + messages.length; + for (int i = 0; i < messages.length; i++) { + player.getPacketDispatch().sendString(messages[i], interfaceId, i + 1); + } + player.getInterfaceManager().openChatbox(interfaceId); + player.getPacketDispatch().sendInterfaceConfig(player.getInterfaceManager().getChatbox().getId(), 1, false); + return player.getInterfaceManager().getChatbox(); + } + + /** + * Sends a plane message and hides the continue button. + * @param hideContinue if we should hide it or not. + * @param messages the messages. + * @return the component. + */ + public Component sendPlainMessage(final boolean hideContinue, String... messages) { + sendDialogue(messages); + player.getPacketDispatch().sendInterfaceConfig(player.getInterfaceManager().getChatbox().getId(), (messages.length + 1), hideContinue); + return player.getInterfaceManager().getChatbox(); + } + + /** + * Opens the destroy item chatbox interface. + * @param id The item id. + * @param message The message to display. + * @return The component. + */ + public Component sendDestroyItem(int id, String message) { + String text = ItemDefinition.forId(id).getConfiguration(ItemConfigParser.DESTROY_MESSAGE, "Are you sure you want to destroy this object?"); + if (text.length() > 200) { + String[] words = text.split(" "); + StringBuilder sb = new StringBuilder(words[0]); + for (int i = 1; i < words.length; i++) { + if (i == (words.length / 2)) { + sb.append("
"); + } else { + sb.append(" "); + } + sb.append(words[i]); + } + text = sb.toString(); + } + player.getPacketDispatch().sendString(text, 94, 7); + player.getPacketDispatch().sendString(ItemDefinition.forId(id).getName(), 94, 8); + player.getPacketDispatch().sendItemOnInterface(id, 1, 94, 9); + + player.getInterfaceManager().openChatbox(94); + return player.getInterfaceManager().getChatbox(); + } + + /** + * Send plane messages with a blue title. + * @param title The title. + * @param messages The messages. + * @return The chatbox component. + */ + public Component sendPlaneMessageWithBlueTitle(String title, String... messages) { + player.getPacketDispatch().sendString(title, 372, 0); + for (int i = 0; i < messages.length; i++) { + player.getPacketDispatch().sendString(messages[i], 372, i + 1); + } + player.getInterfaceManager().openChatbox(372); + return player.getInterfaceManager().getChatbox(); + } + + /** + * Send plane messages with scroll and a blue title. + * @param title The title. + * @param messages The messages. + * @return The chatbox component. + */ + public Component sendScrollMessageWithBlueTitle(String title, String... messages) { + for (int i = 0; i < 11; i++) { + player.getPacketDispatch().sendString(" ", 421, i + 2); + } + player.getPacketDispatch().sendString(title, 421, 1); + for (int i = 0; i < messages.length; i++) { + player.getPacketDispatch().sendString(messages[i], 421, i + 2); + } + player.getInterfaceManager().openChatbox(421); + return player.getInterfaceManager().getChatbox(); + } + + /** + * Send a message with an item next to it. + * @param itemId The item id. + */ + public Component sendItemMessage(int itemId, String... messages) { + if(1 <= messages.length && messages.length < 4) { + ArrayList packedMessages = new ArrayList(); + for(int i = 0; i < messages.length/2; i++) { + packedMessages.add(messages[i] + "
" + messages[i+1]); + } + if(messages.length % 2 == 1) { + packedMessages.add(messages[messages.length-1]); + } + + int interfaceId = 241 + (packedMessages.size() - 1); + player.getInterfaceManager().openChatbox(interfaceId); + player.getPacketDispatch().sendItemOnInterface(itemId, 1, interfaceId, 1); + ItemDefinition itemDef = ItemDefinition.forId(itemId); + player.getPacketDispatch().sendAngleOnInterface(interfaceId, 1, itemDef.getModelZoom() / 2, itemDef.getModelRotationX(), itemDef.getModelRotationY()); + player.getPacketDispatch().sendString("", interfaceId, 3); + for(int i = 0; i < packedMessages.size(); i++) { + //System.out.printf("sendItemMessage[%d]: %s\n", i, packedMessages[i]); + player.getPacketDispatch().sendString(packedMessages.get(i), interfaceId, 4+i); + } + } else { + int interfaceId = 131; + //int interfaceId = 173; + //int interfaceId = 519; + //int interfaceId = 757; + //int interfaceId = 760; + player.getInterfaceManager().openChatbox(interfaceId); + String message = messages[0]; + for (int i = 1; i < messages.length; i++) { + message += "
" + messages[i]; + } + switch(interfaceId) { + case 131: + player.getPacketDispatch().sendString(message, 131, 1); + player.getPacketDispatch().sendItemOnInterface(itemId, 1, 131, 2); + break; + case 173: + player.getPacketDispatch().sendString(message, 173, 4); + player.getPacketDispatch().sendString("", 173, 3); + player.getPacketDispatch().sendItemOnInterface(itemId, 1, 173, 1); + break; + case 519: + player.getPacketDispatch().sendString(message, 519, 1); + player.getPacketDispatch().sendItemOnInterface(itemId, 1, 519, 0); + break; + case 757: + player.getPacketDispatch().sendString(message, 757, 2); + player.getPacketDispatch().sendString("", 757, 1); + player.getPacketDispatch().sendItemOnInterface(itemId, 1, 757, 0); + break; + case 760: + player.getPacketDispatch().sendString(message, 760, 0); + player.getPacketDispatch().sendItemOnInterface(itemId, 1, 760, 1); + break; + } + } + return player.getInterfaceManager().getChatbox(); + } + + /** + * Send a message with an item next to it. + */ + public Component sendItemMessage(final Item item, String... messages) { + return sendItemMessage(item.getId(), messages); + } + + /** + * Send a message with an item next to it. + * @param message The message. + */ + public Component sendDoubleItemMessage(int first, int second, String message) { + player.getInterfaceManager().openChatbox(131); + player.getPacketDispatch().sendString(message, 131, 1); + player.getPacketDispatch().sendItemOnInterface(first, 1, 131, 0); + player.getPacketDispatch().sendItemOnInterface(second, 1, 131, 2); + return player.getInterfaceManager().getChatbox(); + } + + /** + * Send a message with an item next to it. + * @param message The message. + */ + public Component sendDoubleItemMessage(Item first, Item second, String message) { + player.getInterfaceManager().openChatbox(131); + player.getPacketDispatch().sendString(message, 131, 1); + player.getPacketDispatch().sendItemOnInterface(first.getId(), first.getAmount(), 131, 0); + player.getPacketDispatch().sendItemOnInterface(second.getId(), second.getAmount(), 131, 2); + return player.getInterfaceManager().getChatbox(); + } + + /** + * Send dialogues based on the amount of specified messages. + * @param entity The entity. + * @param expression The entity's facial expression. + * @param messages The messages. + * @return The chatbox component. + */ + public Component sendDialogues(Entity entity, FacialExpression expression, String... messages) { + return sendDialogues(entity, expression == null ? -1 : expression.getAnimationId(), messages); + } + + /** + * Send dialogues based on the amount of specified messages. + * @param entity The entity. + * @param expression The entity's facial expression. + * @param messages The messages. + * @return The chatbox component. + */ + public Component sendDialogues(Entity entity, int expression, String... messages) { + return sendDialogues(entity instanceof Player ? -1 : ((NPC) entity).getShownNPC(player).getId(), expression, false, messages); + } + + /** + * Send dialogues based on the amount of specified messages. + * @param npcId The npc id. + * @param expression The entity's facial expression. + * @param messages The messages. + * @param hide should the continue button be hidden? + * @return The chatbox component. + */ + public Component sendDialogues(int npcId, FacialExpression expression, boolean hide, String... messages) { + return sendDialogues(npcId, expression == null ? -1 : expression.getAnimationId(), hide, messages); + } + + /** + * Send dialogues based on the amount of specified messages. + * @param expression The entity's facial expression. + * @param messages The messages. + * @param hide the continue. + * @return The chatbox component. + */ + public Component sendDialogues(Entity entity, FacialExpression expression, boolean hide, String... messages) { + return sendDialogues(entity.getId(), expression == null ? -1 : expression.getAnimationId(), hide, messages); + } + + /** + * Send dialogues based on the amount of specified messages. + * @param expression The entity's facial expression. + * @param messages The messages. + * @param hide should the continue button be hidden? + * @return The chatbox component. + */ + public Component sendDialogues(Entity entity, int expression, boolean hide, String... messages) { + return sendDialogues(entity.getId(), expression, hide, messages); + } + + /** + * Send dialogues based on the amount of specified messages. + * @param npcId The npc id. + * @param expression The entity's facial expression. + * @param messages The messages. + * @return The chatbox component. + */ + public Component sendDialogues(int npcId, FacialExpression expression, String... messages) { + return sendDialogues(npcId, expression == null ? -1 : expression.getAnimationId(),false, messages); + } + + static Pattern GENDERED_SUBSTITUTION = Pattern.compile("@g\\[([^,]*),([^\\]]*)\\]"); + public static String doSubstitutions(Player player, String msg) { + msg = msg.replace("@name", player.getUsername()); + msg = msg.replace("@servername", GameWorld.getSettings().getName()); + StringBuilder sb = new StringBuilder(); + Matcher m = GENDERED_SUBSTITUTION.matcher(msg); + int index = player.isMale() ? 1 : 2; + while(m.find()) { + m.appendReplacement(sb, m.group(index)); + } + m.appendTail(sb); + return sb.toString(); + } + /** + * Send dialogues based on the amount of specified messages. + * @param npcId The npc id. + * @param expression The entity's facial expression. + * @param messages The messages. + * @return The chatbox component. + */ + public Component sendDialogues(int npcId, int expression, String... messages) { + return sendDialogues(npcId, expression, false, messages); + } + + /** + * Send dialogues based on the amount of specified messages. + * @param npcId The npc id. + * @param expression The entity's facial expression. + * @param messages The messages. + * @param hide should the continue button be hidden? + * @return The chatbox component. + */ + public Component sendDialogues(int npcId, int expression, boolean hide, String... messages) { + if (messages.length < 1 || messages.length > 4) { + System.err.println("Invalid amount of messages: " + messages.length); + return null; + } + boolean npc = npcId > -1; + int interfaceId = (npc ? 240 : 63) + messages.length; + interfaceId += hide ? 4 : 0; + if (expression == -1) { + expression = FacialExpression.HALF_GUILTY.getAnimationId(); + } + player.getPacketDispatch().sendAnimationInterface(expression, interfaceId, 2); + player.getPacketDispatch().sendItemOnInterface(-1, 1, interfaceId, 1); + if (npc) { + player.getPacketDispatch().sendNpcOnInterface(npcId, interfaceId, 2); + player.getPacketDispatch().sendString(NPCDefinition.forId(npcId).getName(), interfaceId, 3); + } else { + player.getPacketDispatch().sendPlayerOnInterface(interfaceId, 2); + player.getPacketDispatch().sendString(player.getUsername(), interfaceId, 3); + } + for (int i = 0; i < messages.length; i++) { + player.getPacketDispatch().sendString(doSubstitutions(player, messages[i]), interfaceId, (i + 4)); + } + player.getInterfaceManager().openChatbox(interfaceId); + player.getPacketDispatch().sendInterfaceConfig(player.getInterfaceManager().getChatbox().getId(), 3, false); + return player.getInterfaceManager().getChatbox(); + } + + /** + * Send options based on the amount of specified options. + * @param title The title. + * @param options The options. + */ + public Component sendOptions(Object title, String... options) { + int interfaceId = 224 + (2 * options.length); + if (options.length < 2 || options.length > 5) { + return null; + } + if (title != null) { + player.getPacketDispatch().sendString(title.toString(), interfaceId, 1); + } + for (int i = 0; i < options.length; i++) { + player.getPacketDispatch().sendString(options[i].toString(), interfaceId, i + 2); + } + player.getInterfaceManager().openChatbox(interfaceId); + return player.getInterfaceManager().getChatbox(); + } + + /** + * Send a input run script. + * @param string The strings. + * @param objects The arguments. + */ + public void sendInput(boolean string, Object... objects) { + player.getPacketDispatch().sendRunScript(string ? 109 : 108, "s", objects); + } + + /** + * Sends a long input. + * @param objects the objects. + */ + public void sendLongInput(Object... objects) { + player.getPacketDispatch().sendRunScript(110, "s", objects); + } + + /** + * Sends the private message input. + * @param reciever The receiver. + */ + public void sendMessageInput(String reciever) { + player.getPacketDispatch().sendRunScript(107, "s", reciever); + } + + /** + * Checks if the dialogue for the given id is added. + * @param id The NPC id/dialogue id. + * @return {@code True} if so. + */ + public static boolean contains(int id) { + return PLUGINS.containsKey(id); + } + + /** + * Gets the currently opened dialogue. + * @return The dialogue plugin. + */ + public DialoguePlugin getDialogue() { + return dialogue; + } + + /** + * Reserves a key for the name. + * @param name The name. + * @return The key. + */ + public static int getDialogueKey(String name) { + return 1 << 16 | name.hashCode(); + } + + /** + * Adds a dialogue reward. + * @param action the reward. + */ + public void addAction(DialogueAction action) { + actions.add(action); + } + + /** + * Gets the actions. + * @return The actions. + */ + public List getActions() { + return actions; + } +} diff --git a/Server/src/main/core/game/dialogue/DialogueLabeller.kt b/Server/src/main/core/game/dialogue/DialogueLabeller.kt new file mode 100644 index 0000000..6a48b86 --- /dev/null +++ b/Server/src/main/core/game/dialogue/DialogueLabeller.kt @@ -0,0 +1,360 @@ +package core.game.dialogue + +import core.api.InputType +import core.api.face +import core.api.openDialogue +import core.api.splitLines +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.Item + +/** Alias FacialExpression to ChatAnim for compatibility. */ +typealias ChatAnim = FacialExpression +/** Alias InputType to InputType for compatibility. */ +typealias InputType = InputType +/** Create container class DialogueOption for [DialogueLabeller.options] */ +class DialogueOption( + val goto: String, // Required: Label to go to if player selects option. + val option: String, // Required: Printed text on the option list. + val spokenText: String = option, // Optional: Option selected will be spoken text unless provided here. + val expression: ChatAnim = ChatAnim.NEUTRAL, // Optional: Player expression to show. + val skipPlayer: Boolean = false, // Optional: Skips the player spoken text (if wildly different) + val optionIf: ((player: Player, npc: NPC) -> Boolean)? = null // Optional: Function to show/not show option. +) + +/** + * DialogueLabeller is another way to organize a dialogue file. + * It shares the same dialogue layout as another project for portability. + * - Uses [stage] is for the current loop and [super.stage] as the "next" stage + * - Have [dialogueCounter] assign stages and guards for each option/player/npc dialogue + * - Assign [exec] and [goto] the same [dialogueCounter] to execute all in one pass + * - Save [label] to a HashMap to refer to when using [goto] + * - Loops again when a [goto] is encountered, ends when no [stageHit] during a stage + * + * ! WARNING: DO NOT use functions in DialogueFile as it will cause unexpected behavior. + * + * ! HELP: There are snippets below that you can copy and modify to use as part of your code. + */ +abstract class DialogueLabeller : DialogueFile() { + + companion object { + /** + * Makes NPC stop in its tracks and look at player. + * An alternative to setting up DialoguePlugin(player) to be used in InteractionListener. + */ + fun open(player: Player, dialogue: Any, npc: NPC) { + face(npc, player.location) + npc.setDialoguePlayer(player) // This prevents random walking in [NPC.java handleTickActions()] + npc.getWalkingQueue().reset() + npc.getPulseManager().clear() + openDialogue(player, dialogue, npc) + } + } + + /** Maps labels to stage numbers, to make jumps. */ + val labelStageMap = HashMap () + /** Assigns the number to each dialogue line. */ + var dialogueCounter = 0 + /** Set [stage] to start off (1 when there is an initial label). */ + var startingStage: Int? = null + /** Keeps the current stage for the whole cycle. */ + override var stage = -1 + /** Assigns the number to each stage. */ + var stageHit = false + /** Jump to next stage number when hitting a goto. */ + var jumpTo: Int? = null + /** ButtonID on every click */ + var buttonID: Int? = null + /** ButtonID when user clicks on an option */ + var optButton: Int? = null + /** Input value after a user enters a value */ + var optInput: Any? = null + + /** Implement this function instead of overriding handle. */ + abstract fun addConversation() + + /** Helper function to create an individual stage for each of the dialogue stages. */ + private fun assignIndividualStage(callback: () -> Unit) { + if (startingStage == null) { startingStage = 0 } + if (stage == dialogueCounter && jumpTo == null) { // Run this stage when the stage equals to the dialogueCounter of this dialogue + callback() // CALLBACK FUNCTION + super.stage++ // Increment the stage to the next stage (only applies after a pass) + stageHit = true // Flag that the stage was hit, so that it doesn't close the dialogue + } + dialogueCounter++ // Increment the dialogueCounter to assign each line of dialogue + } + + /** Formats a vararg messages or falls back to message to an array for spread function. */ + private fun formatMessages(messages: Array?, message: String = ""): Array { + return if (messages == null || messages.isEmpty()) { + splitLines(message) + } else if (messages.size > 1) { + messages + } else { + splitLines(messages[0]) // A single line message is similar to a splitLine returning 1 line. + } + } + + /** Does absolutely nothing but to make it look like the other API. */ + fun assignToIds(npcid: Int) { /* super.npc = NPC(npcid) */ } + + /** Marks the start of a series of dialogue that can be jumped to using a [goto]. */ + fun label(label: String, nesting: () -> Unit = {}) { + if (startingStage == null) { startingStage = 1 } + dialogueCounter++ + labelStageMap[label] = dialogueCounter + nesting() + } + + /** Jumps to a [label] after a series of dialogue. */ + fun goto(label: String) { + if (stage == dialogueCounter && jumpTo == null) { + jumpTo = labelStageMap[label] + } + } + + /** Jumps to a [label] inside an [exec]. */ + fun loadLabel(player: Player, label: String) { + goto(label) + } + + /** + * Executes the callback between stages and can be used for branching with [loadLabel]. + * You can chain as many exec as you like since they read sequentially. + * You can also read [options] and [input] values here via [optButton] and [optInput]. + */ + fun exec(callback: (player: Player, npc: NPC) -> Unit) { + if (startingStage == null) { startingStage = 0 } + if (stage == dialogueCounter && jumpTo == null) { + callback(player!!, npc!!) + } + } + + /** Manual stage. For custom creation of an individual stage. Must call interpreter in some form. **/ + fun manual(callback: (player: Player, npc: NPC) -> Unit) { + assignIndividualStage { callback(player!!, npc!!) } + } + + /** Dialogue player/playerl. Shows player chathead with text. **/ + fun player(chatAnim: ChatAnim = ChatAnim.NEUTRAL, vararg messages: String) { + assignIndividualStage { interpreter!!.sendDialogues(player, chatAnim, *formatMessages(messages)) } + } + /** Dialogue player/playerl. Shows player chathead with text. **/ + fun player(vararg messages: String) { player(ChatAnim.NEUTRAL, *messages) } + @Deprecated("Use player() instead.", ReplaceWith("player(chatAnim, *messages)")) + fun playerl(chatAnim: ChatAnim = ChatAnim.NEUTRAL, vararg messages: String) { throw Exception("Deprecated DialogueLabel: Use player() instead.") } + @Deprecated("Use player() instead.", ReplaceWith("player(*messages)")) + fun playerl(vararg messages: String) { throw Exception("Deprecated DialogueLabel: Use player() instead.") } + + /** Dialogue npc/npcl. Shows npc chathead with text. **/ + fun npc(chatAnim: ChatAnim = ChatAnim.NEUTRAL, vararg messages: String) { + assignIndividualStage { interpreter!!.sendDialogues(npc, chatAnim, *formatMessages(messages)) } + } + /** Dialogue npc/npcl. Shows npcId chathead with text. **/ + fun npc(chatAnim: ChatAnim = ChatAnim.NEUTRAL, npcId: Int = npc!!.id, vararg messages: String) { + assignIndividualStage { interpreter!!.sendDialogues(NPC(npcId), chatAnim, *formatMessages(messages)) } + } + /** Dialogue npc/npcl. Shows npcId chathead with text. **/ + fun npc(npcId: Int = npc!!.id, vararg messages: String) { + assignIndividualStage { interpreter!!.sendDialogues(NPC(npcId), ChatAnim.NEUTRAL, *formatMessages(messages)) } + } + /** Dialogue npc/npcl. Shows npc chathead with text. **/ + fun npc(vararg messages: String) { npc(ChatAnim.NEUTRAL, *messages) } + @Deprecated("Use npc() instead.", ReplaceWith("npc(chatAnim, *messages)")) + fun npcl(chatAnim: ChatAnim = ChatAnim.NEUTRAL, vararg messages: String) { throw Exception("Deprecated DialogueLabel: Use npc() instead.") } + @Deprecated("Use npc() instead.", ReplaceWith("npc(*messages)")) + fun npcl(vararg messages: String) { throw Exception("Deprecated DialogueLabel: Use npc() instead.") } + + /** Dialogue item/iteml. Shows item with text. **/ + fun item(item: Item, vararg messages: String, message: String = "") { + assignIndividualStage { interpreter!!.sendItemMessage(item, *formatMessages(messages, message)) } + } + @Deprecated("Use item() instead.", ReplaceWith("item(item, *messages)")) + fun iteml(item: Item, vararg messages: String) { throw Exception("Deprecated DialogueLabel: Use item() instead.") } + + /** Dialogue overloaded doubleItem/doubleIteml. Shows two items with text. **/ + fun item(item: Item, item2: Item, vararg messages: String, message: String = "") { + assignIndividualStage { interpreter!!.sendDoubleItemMessage(item, item2, formatMessages(messages, message).joinToString(" ")) } + } + + /** Dialogue line/linel. Simply shows text. **/ + fun line(vararg messages: String) { + assignIndividualStage { interpreter!!.sendDialogue(*messages) } + } + @Deprecated("Use line() instead.", ReplaceWith("line(*messages)")) + fun linel(vararg messages: String) { throw Exception("Deprecated DialogueLabel: Use line() instead.") } + + /** Dialogue option. Shows the option dialogue with choices for the user to select. **/ + fun options(vararg options: DialogueOption, title: String = "Select an Option") { + // Filter out options that aren't shown. + val filteredOptions = options.filter{ if (it.optionIf != null) { it.optionIf.invoke(player!!, npc!!) } else { true } } + // Stage Part 1: Options List Dialogue + assignIndividualStage { interpreter!!.sendOptions(title, *filteredOptions.map{ it.option }.toTypedArray()) } + // Stage Part 2: Show spoken text. + var opt = if (buttonID != null && buttonID in 1..filteredOptions.size) { filteredOptions[buttonID!! - 1] } else { null } + assignIndividualStage { + if (opt?.skipPlayer == true) { + jumpTo = stage + 1 + } else { + interpreter!!.sendDialogues(player, opt?.expression ?: ChatAnim.NEUTRAL, *(splitLines(opt?.spokenText ?: " "))) + } + optButton = buttonID // transfer the buttonID to a temp memory for the next stage + } + // Stage Part 3: Jump To goto + if (stage == dialogueCounter && optButton != null && optButton in 1..filteredOptions.size) { + jumpTo = labelStageMap[filteredOptions[optButton!! - 1].goto] + } + dialogueCounter++ + } + @Deprecated("Use options(DialogueOption()) and not options(string).", ReplaceWith("options(DialogueOption(options))")) + override fun options(vararg options: String?, title: String) { throw Exception("Deprecated DialogueLabel: Use options(DialogueOption()) and not options(string).") } + + /** Dialogue input. Shows the input dialogue with an input box for the user to type in. Read [optInput] for the value. **/ + fun input(type: InputType, prompt: String = "Enter the amount") { + assignIndividualStage { + // These are similar to calling sendInputDialogue + when (type) { + InputType.AMOUNT -> interpreter!!.sendInput(true, prompt) + InputType.NUMERIC -> interpreter!!.sendInput(false, prompt) + InputType.STRING_SHORT -> interpreter!!.sendInput(true, prompt) // Only 12 letters + InputType.STRING_LONG -> interpreter!!.sendLongInput(prompt) // Very long text, can overflow. + InputType.MESSAGE -> interpreter!!.sendMessageInput(prompt) + } + if (type == InputType.AMOUNT) { + player!!.setAttribute("parseamount", true) + } + // This runscript is the same runscript as the one in ContentAPI sendInputDialogue + player!!.setAttribute("runscript") { value: Any -> + optInput = value + // The next line is a hack. Because this prompt overlays the actual chat box, we trigger the next dialogue with a call to handle. + interpreter!!.handle(player!!.interfaceManager.chatbox.id, 2) + } + player!!.setAttribute("input-type", type) + } + } + /** Dialogue input. Shows the input dialogue with an input box for the user to type in. Read [optInput] in an [exec] function for the value. **/ + fun input(numeric: Boolean, prompt: String = "Enter the amount") { input( if (numeric) { InputType.NUMERIC } else { InputType.STRING_SHORT }, prompt) } + + /** Calls another dialogue file. Always use this to open another dialogue file instead of calling openDialogue() in exec{} due to interfaces clashing. **/ + fun open(player: Player, dialogue: Any, vararg args: Any) { + assignIndividualStage { core.api.openDialogue(player, dialogue, *args) } + } + + /** WARNING: DIALOGUE LABELLER WILL BREAK IN CERTAIN FUNCTIONS. USE open() instead. */ + fun openDialogue(player: Player, dialogue: Any, vararg args: Any) { + core.api.openDialogue(player, dialogue, *args) + } + + /** Hook onto the handle function of DialogueFile. This function gets called every loop with a super.stage. */ + override fun handle(componentID: Int, buttonID: Int) { + this.buttonID = buttonID + startingStage = null + /** This -1 stage is to read labels into a hashmap and to find the starting stage. */ + if (stage == -1) { + dialogueCounter = 0 + addConversation() // Force all labels to be recorded into hashmap. + super.stage = startingStage ?: 0 + } + for (i in 0..10) { // Limit to 10 jumpTo PER DIALOGUE LINE to prevent infinite looping/ping-ponging jumps. + if (jumpTo != null) { // If jumpTo is set, set the super.stage stage as the new jumpTo stage. + super.stage = jumpTo as Int + jumpTo = null + } + stageHit = false + stage = super.stage // [stage] is for the current loop. [super.stage] is treated as the "next" stage. + dialogueCounter = 0 + addConversation() // MAIN CALLBACK FUNCTION + // If there is no jumpTo set, or jumpTo is set to the same stage as this(infinite loop), exit. + if (jumpTo == null || jumpTo == stage) { + break + } + } + if (!stageHit) { end() } // If a dialogue stage is not hit, end the dialogues. + } +} + +/* +// COPY PASTA SNIPPETS SECTION FOR QUICK BOILERPLATES + +// STANDARD: Initializing with DialoguePlugin. +@Initializable +class DonieDialogue (player: Player? = null) : DialoguePlugin(player) { + override fun newInstance(player: Player): DialoguePlugin { + return DonieDialogue(player) + } + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + openDialogue(player, DonieDialogueFile(), npc) + return false + } + override fun getIds(): IntArray { + return intArrayOf(NPCs.DONIE_2238) + } +} +class DonieDialogueFile : DialogueLabeller() { + override fun addConversation() { + assignToIds(NPCs.DONIE_2238) + + npc(ChatAnim.FRIENDLY, "Hello there, can I help you?") + goto("nowhere") + } +} + +// NEW! (EXPERIMENTAL): Initializing with InteractionListener. +class SomeDudeDialogue : InteractionListener { + override fun defineListeners() { + on(NPCs.PRIEST_OF_GUTHIX_8555, IntType.NPC, "talk-to") { player, node -> + DialogueLabeller.open(player, SomeDudeDialogueLabellerFile(), node as NPC) + return@on true + } + } +} + +// Exec with quest stage branches. +exec { player, npc -> + when(getQuestStage(player, SomeQuest.questName)) { + 100 -> loadLabel(player, "SomeQuestStage100") + 10, 20 -> loadLabel(player, "SomeQuestStage10") + else -> { + loadLabel(player, "SomeQuestStage0") + } + } +} + +// Exec to move quest stage up. +exec { player, npc -> + if (getQuestStage(player, SomeQuest.questName) == 0) { + setQuestStage(player, SomeQuest.questName, 10) + } +} + +// Exec to add item, set attribute. +exec { player, npc -> + if (removeItem(player, Items.ITEM_1)) { + addItemOrDrop(player, Items.ITEM_2) + } + if (getAttribute(player, attributeSomething, null) == null) { + setAttribute(player, attributeSomething, player.location) + } +} + +// Open to another dialogue file. +npc("I'm going to another file.") +open(player!!, SomeDialogueFile2(), npc!!) +... +class SomeDialogueFile2 : DialogueLabeller() { + override fun addConversation() { + npc("This is another file.") + } +} + +// Options with all the different controls. +options( + DialogueOption("Label1", "Line 1 Say", expression=ChatAnim.THINKING), + DialogueOption("Label2", "Line 2 Huh", skipPlayer=true), + DialogueOption("Label3", "Line 3 Blah", spokenText="I say something else", expression=ChatAnim.FRIENDLY), + DialogueOption("Label4", "Line 4 What") { player, npc -> + return@DialogueOption false // Don't show + } +) + +*/ \ No newline at end of file diff --git a/Server/src/main/core/game/dialogue/DialoguePlugin.java b/Server/src/main/core/game/dialogue/DialoguePlugin.java new file mode 100644 index 0000000..635b41c --- /dev/null +++ b/Server/src/main/core/game/dialogue/DialoguePlugin.java @@ -0,0 +1,397 @@ +package core.game.dialogue; + +import core.game.component.Component; +import core.game.node.entity.Entity; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.plugin.Plugin; +import core.plugin.PluginManifest; +import core.plugin.PluginType; +import core.tools.Log; +import core.tools.SystemLogger; + +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; + +import static core.api.ContentAPIKt.log; +import static core.api.DialUtilsKt.splitLines; +import static core.tools.DialogueConstKt.DIALOGUE_INITIAL_OPTIONS_HANDLE; +import static core.tools.DialogueConstKt.START_DIALOGUE; + +/** + * Represents a dialogue plugin. + * @author Emperor + */ +@PluginManifest(type = PluginType.DIALOGUE) +public abstract class DialoguePlugin implements Plugin { + + /** + * Represents the red string. + */ + protected static final String RED = ""; + + /** + * Represents the blue string. + */ + protected static final String BLUE = ""; + + /** + * The player. + */ + protected Player player; + + /** + * The dialogue interpreter. + */ + protected DialogueInterpreter interpreter; + + public DialogueFile file; + + protected ArrayList optionNames = new ArrayList(10); + protected ArrayList optionFiles = new ArrayList(10); + + /** + * Two options interface. + */ + protected final int TWO_OPTIONS = 228; + + /** + * Three options interface. + */ + protected final int THREE_OPTIONS = 230; + + /** + * Four options interface. + */ + protected final int FOUR_OPTIONS = 232; + + /** + * Five options interface. + */ + protected final int FIVE_OPTIONS = 234; + + /** + * The NPC the player is talking with. + */ + protected NPC npc; + + /** + * The current dialogue stage. + */ + public int stage; + + /** + * If the dialogue is finished. + */ + protected boolean finished; + + /** + * Constructs a new {@code DialoguePlugin} {@code Object}. + */ + public DialoguePlugin() { + /* + * empty. + */ + } + + public String pirateGender() { + return (player.isMale() ? "lad" : "lass"); + + } + + /** + * Constructs a new {@code DialoguePlugin} {@code Object}. + * @param player The player. + */ + public DialoguePlugin(Player player) { + this.player = player; + if (player != null) { + this.interpreter = player.getDialogueInterpreter(); + } + } + + /** + * Initializes this plugin. + */ + public void init() { + for (int id : getIds()) { + DialogueInterpreter.add(id, this); + } + } + + /** + * Closes (but does not end) the dialogue. + * @return {@code True} if the dialogue succesfully closed. + */ + public boolean close() { + player.getInterfaceManager().closeChatbox(); + player.getInterfaceManager().openChatbox(137); + if(file != null) file.end(); + finished = true; + return true; + } + + public void sendNormalDialogue(Entity entity, FacialExpression expression, String... messages) { + interpreter.sendDialogues(entity, expression, messages); + } + + /** + * Increments the stage variable. + */ + public void increment() { + stage++; + } + + + /** + * Increments the stage variable. + * @return The stage variable. + */ + public int getAndIncrement() { + return stage++; + } + + /** + * Ends the dialogue. + */ + public void end() { + if (interpreter != null) { + interpreter.close(); + } + } + + public void finish() { + setStage(-1); + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public DialoguePlugin newInstance(Player player) { + try { + Class classReference = Class.forName(this.getClass().getCanonicalName()); + + return (DialoguePlugin)classReference + .getDeclaredConstructor(Player.class) + .newInstance(player); + } catch (ClassNotFoundException + | IllegalAccessException + | IllegalArgumentException + | NoSuchMethodException + | InvocationTargetException + | InstantiationException e) { + e.printStackTrace(); + return null; + } + } + + /** + * Opens the dialogue. + * @param args The arguments. + * @return {@code True} if the dialogue plugin succesfully opened. + */ + public boolean open(Object... args) { + player.getDialogueInterpreter().activeTopics.clear(); + if (args.length > 0 && args[0] instanceof NPC) { + npc = (NPC)args[0]; + } + + if (npc == null) { + log(this.getClass(), Log.WARN, + args[0].getClass().getSimpleName() + + "Is not assigning an NPC. Whoever did that should fix it." + ); + } + + player.getDialogueInterpreter().handle(0, 0); + return true; + } + + /** + * Handles the progress of this dialogue.. + * @return {@code True} if the dialogue has started. + */ + public abstract boolean handle(int interfaceId, int buttonId); + + /** + * Gets the ids of the NPCs using this dialogue plugin. + * @return The array of NPC ids. + */ + public abstract int[] getIds(); + + /** + * Method wrapper to send an npc dial. + * @return the component. + */ + public Component npc(final String... messages) { + if (npc == null) { + return interpreter.sendDialogues(getIds()[0], getIds()[0] > 8591 ? FacialExpression.OLD_NORMAL : FacialExpression.FRIENDLY, messages); + } + return interpreter.sendDialogues(npc, npc.getId() > 8591 ? FacialExpression.OLD_NORMAL : FacialExpression.FRIENDLY, messages); + } + + /** + * Method wrapper to send an npc dial. + * @param id the id. + * @return the component. + */ + public Component npc(int id, final String... messages) { + return interpreter.sendDialogues(id, FacialExpression.FRIENDLY, messages); + } + + public Component sendDialogue(String... messages) { + return interpreter.sendDialogue(messages); + } + + /** + * Method wrapper to send an npc dial. + * @return the component. + */ + public Component npc(FacialExpression expression, final String... messages) { + if (npc == null) { + return interpreter.sendDialogues(getIds()[0], expression, messages); + } + return interpreter.sendDialogues(npc, expression, messages); + } + + /** + * Method wrapper to send a player dial. + * @return the component. + */ + public Component player(final String... messages) { + return interpreter.sendDialogues(player, null, messages); + } + /** + * Method wrapper to send a player dial. + * @return the component. + */ + public Component player(FacialExpression expression, final String... messages) { + return interpreter.sendDialogues(player, expression, messages); + } + + /** + * Method used to send options. + * @param options the options. + */ + public void options(final String... options) { + interpreter.sendOptions("Select an Option", options); + } + + /** + * Checks if the dialogue plugin is finished. + * @return {@code True} if so. + */ + public boolean isFinished() { + return finished; + } + + /** + * Gets the player. + * @return The player. + */ + public Player getPlayer() { + return player; + } + + /** + * Sets the stage. + * @param i the stage. + */ + public void setStage(int i) { + this.stage = i; + } + + public void next() { + this.stage += 1; + } + + /** + * Loads a DialogueFile and sets its stage to START_DIALOGUE, and diverts all further handling for the conversation to the file. + * @param file the DialogueFile to load. + */ + public void loadFile(DialogueFile file){ + if(file == null) return; + this.file = file.load(player,npc,interpreter); + this.file.setDialoguePlugin(this); + stage = START_DIALOGUE; + } + + /** + * Add an option to the list of possible choices a player can pick from. Helps build the options interface for sendChoices() + * @param name the name of the quest/activity to talk about. Turns into "Talk about $name" on the option interface. + * @param file the DialogueFile that the option loads when selected. + */ + public void addOption(String name, DialogueFile file){ + optionNames.add("Talk about " + name); + optionFiles.add(file); + } + + /** + * Send the player a list of conversation options if there's more than one choice. I.E. multiple quest lines. + * @return true if an options interface was sent, false if not. + */ + public boolean sendChoices(){ + if(optionNames.size() == 1){ + loadFile(optionFiles.get(0)); + return false; + } else if(optionNames.isEmpty()) { + stage = START_DIALOGUE; + return false; + } else { + options(optionNames.toArray(new String[0])); + stage = DIALOGUE_INITIAL_OPTIONS_HANDLE; + return true; + } + } + + /** + * Use the automatic linesplitting feature in DialUtils to produce npc dialogues + * @param expr the FacialExpression to use, located in the FacialExpression enum. + * @param msg the message for the NPC to say + */ + public Component npcl(FacialExpression expr, String msg){ + return npc(expr, splitLines(msg, 54)); + } + + /** + * Use the automatic linesplitting feature in DialUtils to produce player dialogues + * @param expr the FacialExpression to use, located in the FacialExpression enum. + * @param msg the message for the player to say + */ + public Component playerl(FacialExpression expr, String msg){ + return player(expr, splitLines(msg, 54)); + } + + public boolean showTopics(Topic... topics) { + ArrayList validTopics = new ArrayList<>(); + for(Topic topic : topics) + { + if(topic instanceof IfTopic && !((IfTopic) topic).getShowCondition()) continue; + interpreter.activeTopics.add(topic); + validTopics.add(topic.getText()); + } + if(validTopics.size() == 0) { + return true; + } + else if (validTopics.size() == 1) { + Topic topic = interpreter.activeTopics.get(0); + if(topic.getToStage() instanceof DialogueFile) { + DialogueFile topicFile = (DialogueFile) topic.getToStage(); + interpreter.getDialogue().loadFile(topicFile); + } + else if(topic.getToStage() instanceof Integer) { + stage = (Integer) topic.getToStage(); + } + player(topic.getText()); + interpreter.activeTopics.clear(); + return false; + } + else { + options(validTopics.toArray(new String[0])); + return false; + } + } +} diff --git a/Server/src/main/core/game/dialogue/DialogueTopic.kt b/Server/src/main/core/game/dialogue/DialogueTopic.kt new file mode 100644 index 0000000..3ef290a --- /dev/null +++ b/Server/src/main/core/game/dialogue/DialogueTopic.kt @@ -0,0 +1,14 @@ +package core.game.dialogue + +/** + * Topic/IfTopic system backported from my personal project + * @author Ceikry + */ +open class Topic @JvmOverloads constructor(val expr: FacialExpression, val text: String, val toStage: T, val skipPlayer: Boolean = false) { + @JvmOverloads + constructor(text: String, toStage: T, skipPlayer: Boolean = false) : this(FacialExpression.ASKING, text, toStage, skipPlayer) +} +class IfTopic @JvmOverloads constructor(expr: FacialExpression, text: String, toStage: T, val showCondition: Boolean, skipPlayer: Boolean = false) : Topic(expr, text, toStage, skipPlayer) { + @JvmOverloads + constructor(text: String, toStage: T, showCondition: Boolean, skipPlayer: Boolean = false) : this(core.game.dialogue.FacialExpression.ASKING, text, toStage, showCondition, skipPlayer) +} diff --git a/Server/src/main/core/game/dialogue/EmptyPlugin.kt b/Server/src/main/core/game/dialogue/EmptyPlugin.kt new file mode 100644 index 0000000..7985765 --- /dev/null +++ b/Server/src/main/core/game/dialogue/EmptyPlugin.kt @@ -0,0 +1,30 @@ +package core.game.dialogue + +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.tools.START_DIALOGUE + +class EmptyPlugin(player: Player? = null,val file: DialogueFile?) : DialoguePlugin(player) { + override fun newInstance(player: Player?): DialoguePlugin { + return EmptyPlugin(player,null) + } + + override fun open(vararg args: Any?): Boolean { + if(args.isNotEmpty() && args[0] is NPC){ + npc = args[0] as NPC + } + stage = START_DIALOGUE + loadFile(file) + interpreter.handle(0,0) + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + return true + } + + override fun getIds(): IntArray { + return intArrayOf(Integer.MAX_VALUE) + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/dialogue/FacialExpression.java b/Server/src/main/core/game/dialogue/FacialExpression.java new file mode 100644 index 0000000..6d415cf --- /dev/null +++ b/Server/src/main/core/game/dialogue/FacialExpression.java @@ -0,0 +1,152 @@ +package core.game.dialogue; + +/** + * Represents the facial expressions (the animations the entity does when + * talking). + * + * @author Emperor + * @author Empathy + */ +public enum FacialExpression { + + /** + * The normal talking expression. + */ + + //Names based off https://2009scape.wiki/w/Chathead/Animations + + //Chat heads from oldschool 2009scape? + //Maybe for gnomes or dwarves? Chat heads are frozen when used on Human NPCs + OLD_HAPPY(588), + OLD_CALM_TALK1(589), + OLD_CALM_TALK2(590), + OLD_DEFAULT(591), + OLD_EVIL1(592), + OLD_EVIL2(593), + OLD_NORMAL(594), + OLD_SNEAKY(595), + OLD_DISTRESSED(596), + OLD_DISTRESSED2(597), + OLD_ALMOST_CRYING(598), + OLD_BOWS_HEAD_SAD(599), + OLD_DRUNK_LEFT(600), + OLD_DRUNK_RIGHT(601), + OLD_NOT_INTERESTED(602), + OLD_SLEEPY(603), + OLD_PLAIN_EVIL(604), + OLD_LAUGH1(605), + OLD_LAUGH2(606), + OLD_LAUGH3(607), + OLD_LAUGH4(608), + OLD_EVIL_LAUGH(609), + OLD_SAD(610), + OLD_MORE_SAD(611), + OLD_ON_ONE_HAND(612), + OLD_NEARLY_CRYING(613), + OLD_ANGRY1(614), + OLD_ANGRY2(615), + OLD_ANGRY3(616), + OLD_ANGRY4(617), + + //Chatheads from 2009? + NOD_YES(9741), + WORRIED(9743), + HALF_WORRIED(9745), //Not on the wiki, first half of worried + AMAZED(9746), + EXTREMELY_SHOCKED(9750), + GUILTY(9758), + HALF_GUILTY(9760), //Not on the wiki, first half of guilty + SAD(9761), + CRYING(9765), + HALF_CRYING(9768), //Not on the wiki, but plays the first half of the crying animation + AFRAID(9772), + SCARED(9776), + PANICKED(9780), + ANNOYED(9784), + ANGRY(9785), + FURIOUS(9792), + ANGRY_WITH_SMILE(9796), // Not on the wiki + ANGRY_WITH_SMILE_AND_EVIL_EYE(9798), //Not on the Wiki + SLEEPING(9802), + SILENT(9804), + NEUTRAL(9808), + THINKING(9812), + HALF_THINKING(9814), + DISGUSTED(9816), + DISGUSTED_HEAD_SHAKE(9823), //Not on the wiki + ASKING(9827), + HALF_ASKING(9830), //Not on wiki, first half of Asking + ROLLING_EYES(9831), //9832, 9833 are the same + HALF_ROLLING_EYES(9834), //Not on Wiki, first half of Rolling eyes + DRUNK(9835), + SUSPICIOUS(9836), + LAUGH(9840), + LOUDLY_LAUGHING(9841), + EVIL_LAUGH(9842), + FRIENDLY(9844), + HAPPY(9847), + JOLLY(9851), + STRUGGLE(9865), //TODO: More? + //9855-9857 are like disgusted? does it just repeat after this? + + //Child Chathead? + CHILD_ANGRY(7168), + CHILD_SIDE_EYE(7169), + CHILD_RECALLING(7170), + CHILD_EVIL_LAUGH(7171), + CHILD_FRIENDLY(7172), + CHILD_NORMAL(7173), + CHILD_NEUTRAL(7174), + CHILD_LOUDLY_LAUGHING(7175), + CHILD_THINKING(7176), + CHILD_SAD(7177), + CHILD_GUILTY(7178), + CHILD_SUSPICIOUS(7179), + CHILD_SURPRISED(7180), + + ; //TODO: More? + + /* + * From some sources: here's a potential list of chatheads. + * // 667 + * Chat animation group: 1540; linked animations: [7, 8, 9, 6824] + * Chat animation group: 1489; linked animations: [225, 6550, 6551, 6552, 6553, 6555, 8372, 8373, 8374, 8375, 8581, 8582, 9178, 9179, 9180, 9181, 9183, 9187, 9189, 9190, 9192, 9202] + * Chat animation group: 82; linked animations: [554, 555, 556, 557, 562, 563, 564, 565, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 610, 611, 612, 613, 614, 615, 616, 617] + * Chat animation group: 84; linked animations: [558, 559, 560, 561] + * Chat animation group: 80; linked animations: [584, 585, 586, 587] + * Chat animation group: 78; linked animations: [3874] + * Chat animation group: 77; linked animations: [4119, 4120, 4121, 4122] + * Chat animation group: 1124; linked animations: [4843, 4844, 4845, 4846, 8388, 8389, 8390, 8391, 8392, 8393, 8394, 8403, 8404, 8405, 8406, 8898, 8899, 8900] + * Chat animation group: 1309; linked animations: [5661, 5662, 5663, 5665] + * Chat animation group: 1421; linked animations: [6244, 6245, 6246, 7636, 7637, 7638, 7639, 8380, 8381, 8382, 8383, 8475, 8476, 8477, 8478] + * Chat animation group: 1627; linked animations: [7168, 7169, 7170, 7171, 7172, 7173, 7176, 7177, 7178, 7179, 7180, 8824] + * Chat animation group: 1698; linked animations: [7539, 7540, 7541, 7542, 8447, 8448, 8449, 8450] + * Chat animation group: 1885; linked animations: [8395, 8396, 8397, 8398] + * Chat animation group: 1882; linked animations: [8411, 8412, 8413, 8414] + * Chat animation group: 1887; linked animations: [8443, 8444, 8445, 8446, 9315, 9316, 9317, 9318, 9319] + * Chat animation group: 1906; linked animations: [8579, 8580, 8583, 8584, 8585, 8656, 8657, 8659, 8660, 8661, 8662] + */ + + /** + * The animation id. + */ + private final int animationId; + + /** + * Constructs a new {@code FacialExpression} {@code Object}. + * + * @param animationId The animation id. + */ + FacialExpression(int animationId) { + this.animationId = animationId; + } + + /** + * Gets the animation id. + * + * @return The animation id. + */ + public int getAnimationId() { + return animationId; + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/dialogue/SimpleDialoguePlugin.java b/Server/src/main/core/game/dialogue/SimpleDialoguePlugin.java new file mode 100644 index 0000000..d930c3d --- /dev/null +++ b/Server/src/main/core/game/dialogue/SimpleDialoguePlugin.java @@ -0,0 +1,46 @@ +package core.game.dialogue; + +import core.plugin.Initializable; +import core.game.node.entity.player.Player; + +/** + * Represents a simple dialogue. + * @author 'Vexia + */ +@Initializable +public class SimpleDialoguePlugin extends DialoguePlugin { + + public SimpleDialoguePlugin() { + + } + + public SimpleDialoguePlugin(Player player) { + super(player); + } + + @Override + public int[] getIds() { + return new int[] { 70099 }; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + end(); + return true; + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new SimpleDialoguePlugin(player); + } + + @Override + public boolean open(Object... args) { + String[] messages = new String[args.length]; + for (int i = 0; i < messages.length; i++) + messages[i] = (String) args[i]; + interpreter.sendDialogue(messages); + return true; + } + +} diff --git a/Server/src/main/core/game/dialogue/SkillDialogueHandler.kt b/Server/src/main/core/game/dialogue/SkillDialogueHandler.kt new file mode 100644 index 0000000..58e692b --- /dev/null +++ b/Server/src/main/core/game/dialogue/SkillDialogueHandler.kt @@ -0,0 +1,374 @@ +package core.game.dialogue + +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.net.packet.PacketRepository +import core.net.packet.context.ChildPositionContext +import core.net.packet.out.RepositionChild +import core.tools.StringUtils + +/** + * Represents a skill dialogue handler class. + * @author Vexia + */ +open class SkillDialogueHandler( + /** + * Represents the player. + */ + val player: Player, + /** + * Represents the skill dialogue type. + */ + val type: SkillDialogue?, vararg data: Any) { + /** + * Gets the player. + * @return The player. + */ + + /** + * Gets the type. + * @return The type. + */ + + /** + * Gets the passed data. + * @return the data. + */ + /** + * Represents the object data passed through. + */ + val data: Array + + /** + * Method used to open a skill dialogue. + */ + fun open() { + player.dialogueInterpreter.open(SKILL_DIALOGUE, this) + } + + /** + * Method used to display the content on the dialogue. + */ + fun display() { + if (type == null) { + player.debug("Error! Type is null.") + return + } + type.display(player, this) + } + + /** + * Method used to create a product. + * @param amount the amount. + * @param index the index. + */ + open fun create(amount: Int, index: Int) {} + + /** + * Gets the total amount of items to be made. + * @param index the index. + * @return the amount. + */ + open fun getAll(index: Int): Int { + return player.inventory.getAmount(data[0] as Item) + } + + /** + * Gets the name. + * @param item the item. + * @return the name. + */ + protected open fun getName(item: Item): String { + return StringUtils.formatDisplayName(item.name.replace("Unfired", "")) + } + + /** + * Represents a skill dialogue type. + * @author 'Vexia + */ + enum class SkillDialogue + /** + * Constructs a new `SkillDialogue` `Object`. + * @param interfaceId the interface id. + * @param base the base button. + * @param length the length. + */( + /** + * Represents the interface id. + */ + val interfaceId: Int, + /** + * Represents the base button. + */ + private val baseButton: Int, + /** + * Represents the length. + */ + private val length: Int) { + ONE_OPTION(309, 5, 1) { + override fun display(player: Player, handler: SkillDialogueHandler) { + val item = handler.data[0] as Item + player.packetDispatch.sendString("



" + item.name, 309, 6) + player.packetDispatch.sendItemZoomOnInterface(item.id, 160, 309, 2) + PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, 309, 6, 60, 20)) + PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, 309, 2, 210, 30)) + } + + override fun getAmount(handler: SkillDialogueHandler, buttonId: Int): Int { + return when(buttonId){ + 5 -> 1 + 4 -> 5 + 3 -> -1 //-1 is used to prompt an "enter an amount" + else -> handler.getAll(getIndex(handler, buttonId)) + } + } + }, + MAKE_SET_ONE_OPTION(582, 4, 1) { + override fun display(player: Player, handler: SkillDialogueHandler) { + val item = handler.data[0] as Item + + // Send item + item name to interface + player.packetDispatch.sendItemZoomOnInterface(item.id, 160, 582, 2) + player.packetDispatch.sendString("



" + item.name, 582, 5) + + // Re-format this interface because it is not formatted properly for the chat-box + // Swords + PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, 582, 0, 12, 15)) + PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, 582, 1, 431, 15)) + // "How many would you like to make?" + PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, 582, 6, 0, 12)) + // Item displayed + PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, 582, 2, 207, 23)) + // Right click context menu boxes + PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, 582, 3, 58, 27)) + PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, 582, 4, 58, 27)) + PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, 582, 5, 58, 27)) + } + + override fun getAmount(handler: SkillDialogueHandler, buttonId: Int): Int { + return when(buttonId){ + // "Continue" Option + 5 -> 1 + // "Make 1 set" Option + 4 -> 1 + // "Make 5 sets" Option + 3 -> 5 + // "Make 10 sets" Option + 2 -> 10 + else -> 10 + } + } + }, + TWO_OPTION(303, 7, 2) { + override fun display(player: Player, handler: SkillDialogueHandler) { + var item: Item + player.interfaceManager.openChatbox(306) + for (i in handler.data.indices) { + item = handler.data[i] as Item + player.packetDispatch.sendString("



" + handler.getName(item), 303, 7 + i) + player.packetDispatch.sendItemZoomOnInterface(item.id, 160, 303, 2 + i) + } + } + + override fun getIndex(handler: SkillDialogueHandler?, buttonId: Int): Int { + when (buttonId) { + 6, 5, 4, 3 -> return 0 + 10, 9, 8, 7 -> return 1 + } + return 1 + } + + override fun getAmount(handler: SkillDialogueHandler, buttonId: Int): Int { + when (buttonId) { + 6, 10 -> return 1 + 5, 9 -> return 5 + 4, 8 -> return 10 + 3, 7 -> return -1 + } + return 1 + } + }, + THREE_OPTION(304, 8, 3) { + override fun display(player: Player, handler: SkillDialogueHandler) { + var item: Item? = null + for (i in 0..2) { + item = handler.data[i] as Item + player.packetDispatch.sendItemZoomOnInterface(item.id, 135, 304, 2 + i) + player.packetDispatch.sendString("



" + item!!.name, 304, 304 - 296 + i * 4) + } + } + + override fun getIndex(handler: SkillDialogueHandler?, buttonId: Int): Int { + when (buttonId) { + 7, 6, 5, 4 -> return 0 + 11, 10, 9, 8 -> return 1 + 15, 14, 13, 12 -> return 2 + } + return 1 + } + + override fun getAmount(handler: SkillDialogueHandler, buttonId: Int): Int { + when (buttonId) { + 7, 11, 15 -> return 1 + 6, 10, 14 -> return 5 + 5, 9, 13 -> return 10 + 4, 8, 12 -> return -1 + } + return 1 + } + }, + FOUR_OPTION(305, 9, 4) { + override fun display(player: Player, handler: SkillDialogueHandler) { + var item: Item? = null + for (i in 0..3) { + item = handler.data[i] as Item + player.packetDispatch.sendItemZoomOnInterface(item!!.id, 135, 305, 2 + i) + player.packetDispatch.sendString("



" + item.name, 305, 305 - 296 + i * 4) + } + } + + override fun getIndex(handler: SkillDialogueHandler?, buttonId: Int): Int { + when (buttonId) { + 5, 8, 6, 7 -> return 0 + 9, 10, 11, 12 -> return 1 + 13, 14, 15, 16 -> return 2 + 17, 18, 19, 20 -> return 3 + } + return 0 + } + + override fun getAmount(handler: SkillDialogueHandler, buttonId: Int): Int { + when (buttonId) { + 8, 12, 16, 20 -> return 1 + 7, 11, 15, 19 -> return 5 + 6, 10, 14, 18 -> return 10 + 5, 9, 13, 17 -> return -1 + } + return 1 + } + }, + FIVE_OPTION(306, 7, 5) { + /** + * Represents the position data. + */ + private val positions = arrayOf(intArrayOf(10, 30), intArrayOf(117, 10), intArrayOf(217, 20), intArrayOf(317, 15), intArrayOf(408, 15)) + override fun display(player: Player, handler: SkillDialogueHandler) { + var item: Item + player.interfaceManager.openChatbox(306) + for (i in handler.data.indices) { + item = handler.data[i] as Item + player.packetDispatch.sendString("



" + handler.getName(item), 306, 10 + 4 * i) + player.packetDispatch.sendItemZoomOnInterface(item.id, 160, 306, 2 + i) + PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, 306, 2 + i, positions[i][0], positions[i][1])) + } + } + + override fun getIndex(handler: SkillDialogueHandler?, buttonId: Int): Int { + when (buttonId) { + 9, 8, 7, 6 -> return 0 + 13, 12, 11, 10 -> return 1 + 17, 16, 15, 14 -> return 2 + 21, 20, 19, 18 -> return 3 + 25, 24, 23, 22 -> return 4 + } + return 0 + } + + override fun getAmount(handler: SkillDialogueHandler, buttonId: Int): Int { + when (buttonId) { + 9, 13, 17, 21, 25 -> return 1 + 8, 12, 16, 20, 24 -> return 5 + 7, 11, 15, 19, 23 -> return 10 + 6, 10, 14, 18, 22 -> return -1 + } + return 1 + } + }; + + /** + * Gets the interfaceId. + * @return The interfaceId. + */ + + /** + * Method used to display the content for this type. + * @param player the player. + * @param handler the handler. + */ + open fun display(player: Player, handler: SkillDialogueHandler) {} + + /** + * Gets the amount. + * @param handler the handler. + * @param buttonId the buttonId. + * @return the amount. + */ + open fun getAmount(handler: SkillDialogueHandler, buttonId: Int): Int { + for (k in 0..3) { + for (i in 0 until length) { + val `val` = baseButton - k + 4 * i + if (`val` == buttonId) { + return if (k == 13) 1 else if (k == 8) 5 else if (k == 7) 10 else 6 + } + } + } + return -1 + } + + /** + * Gets the index selected. + * @param handler the handler. + * @param buttonId the buttonId. + * @return the index selected. + */ + open fun getIndex(handler: SkillDialogueHandler?, buttonId: Int): Int { + var index = 0 + for (k in 0..3) { + for (i in 1 until length) { + val `val` = baseButton + k + 4 * i + if (`val` == buttonId) { + return index + 1 + } else if (`val` <= buttonId) { + index++ + } + } + index = 0 + } + return index + } + + companion object { + /** + * Gets the type for the length. + * @param length2 the length to compare. + * @return the type. + */ + fun forLength(length2: Int): SkillDialogue? { + for (dial in values()) { + if (dial.length == length2) { + return dial + } + } + return null + } + } + + } + + companion object { + /** + * Represents the skill dialogue id. + */ + const val SKILL_DIALOGUE = 3 shl 16 + } + + /** + * Constructs a new `SkillDialogueHandler` `Object`. + * @param player the player. + * @param type the type. + * @param data the data. + */ + init { + this.data = data as Array + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/dialogue/SkillDialoguePlugin.java b/Server/src/main/core/game/dialogue/SkillDialoguePlugin.java new file mode 100644 index 0000000..f33a3a0 --- /dev/null +++ b/Server/src/main/core/game/dialogue/SkillDialoguePlugin.java @@ -0,0 +1,77 @@ +package core.game.dialogue; + +import static core.api.ContentAPIKt.*; +import core.game.node.entity.player.Player; +import core.plugin.Initializable; +import kotlin.Unit; + +/** + * Represents the dialogue plugin used to automatically handle skill dialogues with creation amounts. + * @author Vexia + * + */ +@Initializable +public class SkillDialoguePlugin extends DialoguePlugin { + + /** + * Represents the skill dialogue handler. + */ + private SkillDialogueHandler handler; + + /** + * Constructs a new {@code SkillDialogue} {@code Object}. + */ + public SkillDialoguePlugin() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code SkillDialogue} {@code Object}. + * @param player the player. + */ + public SkillDialoguePlugin(final Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new SkillDialoguePlugin(player); + } + + @Override + public boolean open(Object... args) { + handler = (SkillDialogueHandler) args[0]; + handler.display(); + player.getInterfaceManager().openChatbox(handler.getType().getInterfaceId()); + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + final int amount = handler.getType().getAmount(handler, buttonId); + final int index = handler.getType().getIndex(handler, buttonId); + end(); + if (amount != -1) { + handler.create(amount, index); + } else { + sendInputDialogue(player, true, "Enter the amount:", (value) -> { + if (value instanceof String) { + handler.create(Integer.parseInt((String) value), index); + } else { + handler.create((int) value, index); + } + return Unit.INSTANCE; + }); + return true; + } + return true; + } + + @Override + public int[] getIds() { + return new int[] { SkillDialogueHandler.SKILL_DIALOGUE }; + } + +} diff --git a/Server/src/main/core/game/diary/AreaDiaryTask.kt b/Server/src/main/core/game/diary/AreaDiaryTask.kt new file mode 100644 index 0000000..7041ad4 --- /dev/null +++ b/Server/src/main/core/game/diary/AreaDiaryTask.kt @@ -0,0 +1,22 @@ +package core.game.diary + +import core.api.inBorders +import core.game.node.entity.player.Player +import core.game.world.map.zone.ZoneBorders + +class AreaDiaryTask( + val zoneBorders: ZoneBorders, + val diaryLevel: DiaryLevel, + val taskId: Int, + private val condition: ((player: Player) -> Boolean)? = null +) { + fun whenSatisfied(player: Player, then: () -> Unit) { + var result = inBorders(player, zoneBorders) + + condition?.let { + result = it(player) + } + + if (result) then() + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/diary/DiaryEventHookBase.kt b/Server/src/main/core/game/diary/DiaryEventHookBase.kt new file mode 100644 index 0000000..4fb85b0 --- /dev/null +++ b/Server/src/main/core/game/diary/DiaryEventHookBase.kt @@ -0,0 +1,232 @@ +package core.game.diary + +import core.api.* +import core.game.event.* +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.diary.DiaryType +import core.game.world.map.zone.ZoneBorders +import core.api.Event + +abstract class DiaryEventHookBase(private val diaryType: DiaryType) : MapArea, LoginListener { + protected companion object { + private fun forEligibleEntityDo(entity: Entity, event: T, handler: (Player, T) -> Unit) { + if (entity !is Player) return + if (entity.isArtificial) return + + handler(entity, event) + } + } + + class EventHandler( + private val owner: DiaryEventHookBase, + private val handler: (Player, T) -> Unit + ) : EventHook { + override fun process(entity: Entity, event: T) { + forEligibleEntityDo(entity, event, handler) + } + } + + open val areaTasks get() = arrayOf() + + final override fun defineAreaBorders(): Array + = areaTasks.map { task -> task.zoneBorders }.toTypedArray() + + final override fun areaEnter(entity: Entity) { + if (entity !is Player) return + if (entity.isArtificial) return + + onAreaVisited(entity) + } + + final override fun areaLeave(entity: Entity, logout: Boolean) { + if (entity !is Player) return + if (entity.isArtificial) return + + onAreaLeft(entity) + } + + final override fun login(player: Player) { + player.hook(Event.ResourceProduced, EventHandler(this, ::onResourceProduced)) + player.hook(Event.NPCKilled, EventHandler(this, ::onNpcKilled)) + player.hook(Event.Teleported, EventHandler(this, ::onTeleported)) + player.hook(Event.FireLit, EventHandler(this, ::onFireLit)) + player.hook(Event.LightSourceLit, EventHandler(this, ::onLightSourceLit)) + player.hook(Event.Interacted, EventHandler(this, ::onInteracted)) + player.hook(Event.ButtonClicked, EventHandler(this, ::onButtonClicked)) + player.hook(Event.DialogueOpened, EventHandler(this, ::onDialogueOpened)) + player.hook(Event.DialogueOptionSelected, EventHandler(this, ::onDialogueOptionSelected)) + player.hook(Event.DialogueClosed, EventHandler(this, ::onDialogueClosed)) + player.hook(Event.UsedWith, EventHandler(this, ::onUsedWith)) + player.hook(Event.PickedUp, EventHandler(this, ::onPickedUp)) + player.hook(Event.InterfaceOpened, EventHandler(this, ::onInterfaceOpened)) + player.hook(Event.AttributeSet, EventHandler(this, ::onAttributeSet)) + player.hook(Event.AttributeRemoved, EventHandler(this, ::onAttributeRemoved)) + player.hook(Event.SpellCast, EventHandler(this, ::onSpellCast)) + player.hook(Event.ItemAlchemized, EventHandler(this, ::onItemAlchemized)) + player.hook(Event.ItemEquipped, EventHandler(this, ::onItemEquipped)) + player.hook(Event.ItemUnequipped, EventHandler(this, ::onItemUnequipped)) + player.hook(Event.ItemPurchased, EventHandler(this, ::onItemPurchasedFromShop)) + player.hook(Event.ItemSold, EventHandler(this, ::onItemSoldToShop)) + player.hook(Event.JobAssigned, EventHandler(this, ::onJobAssigned)) + player.hook(Event.FairyRingDialed, EventHandler(this, ::onFairyRingDialed)) + player.hook(Event.SummoningPointsRecharged, EventHandler(this, ::onSummoningPointsRecharged)) + player.hook(Event.PrayerPointsRecharged, EventHandler(this, ::onPrayerPointsRecharged)) + } + + protected fun fulfillTaskRequirement(player: Player, level: DiaryLevel, task: Int, attribute: String) { + if (getAttribute(player, attribute, false)) return + + player.achievementDiaryManager.updateTask( + player, + diaryType, + findIndexFor(level), + task, + false + ) + + setAttribute(player, "/save:$attribute", true) + } + + protected fun whenTaskRequirementFulfilled(player: Player, attribute: String, then: () -> Unit) { + if (getAttribute(player, attribute, false)) { + then() + removeAttribute(player, attribute) + } + } + + protected fun progressIncrementalTask( + player: Player, + level: DiaryLevel, + task: Int, + attribute: String, + maxProgress: Int + ) { + if (isTaskCompleted(player, level, task)) return + + val newValue = getAttribute(player, attribute, 0) + 1 + + setAttribute( + player, + "/save:${attribute}", + newValue + ) + + if (newValue < maxProgress) { + player.achievementDiaryManager.updateTask( + player, + diaryType, + findIndexFor(level), + task, + false + ) + } else { + finishTask(player, level, task) + removeAttribute(player, attribute) + } + } + + protected fun progressFlaggedTask( + player: Player, + level: DiaryLevel, + task: Int, + attribute: String, + bit: Int, + targetValue: Int + ) { + if (isTaskCompleted(player, level, task)) { + return + } + + val oldValue = getAttribute(player, attribute, 0) + val newValue = oldValue or bit + + if (newValue != targetValue) { + if ((oldValue and bit) != 0) return + + setAttribute( + player, + "/save:${attribute}", + newValue + ) + + player.achievementDiaryManager.updateTask( + player, + diaryType, + findIndexFor(level), + task, + false + ) + } else { + finishTask(player, level, task) + removeAttribute(player, attribute) + } + } + + protected fun finishTask(player: Player, level: DiaryLevel, task: Int) { + player.achievementDiaryManager.finishTask( + player, + diaryType, + findIndexFor(level), + task + ) + } + + private fun isTaskCompleted(player: Player, level: DiaryLevel, task: Int): Boolean { + return player.achievementDiaryManager.hasCompletedTask( + diaryType, + findIndexFor(level), + task + ) + } + + private fun findIndexFor(level: DiaryLevel): Int { + val levelName = level.name.lowercase().replaceFirstChar { c -> c.uppercase() } + val levelIndex = diaryType.levelNames.indexOf(levelName) + + if (levelIndex < 0) { + throw IllegalArgumentException("'$levelName' was not found in diary '$diaryType'.") + } + + return levelIndex + } + + protected open fun onAreaVisited(player: Player) { + areaTasks.forEach { + it.whenSatisfied(player) { + finishTask( + player, + it.diaryLevel, + it.taskId + ) + } + } + } + + protected open fun onAreaLeft(player: Player) {} + protected open fun onResourceProduced(player: Player, event: ResourceProducedEvent) {} + protected open fun onNpcKilled(player: Player, event: NPCKillEvent) {} + protected open fun onTeleported(player: Player, event: TeleportEvent) {} + protected open fun onFireLit(player: Player, event: LitFireEvent) {} + protected open fun onLightSourceLit(player: Player, event: LitLightSourceEvent) {} + protected open fun onInteracted(player: Player, event: InteractionEvent) {} + protected open fun onButtonClicked(player: Player, event: ButtonClickEvent) {} + protected open fun onDialogueOpened(player: Player, event: DialogueOpenEvent) {} + protected open fun onDialogueClosed(player: Player, event: DialogueCloseEvent) {} + protected open fun onDialogueOptionSelected(player: Player, event: DialogueOptionSelectionEvent) {} + protected open fun onUsedWith(player: Player, event: UseWithEvent) {} + protected open fun onPickedUp(player: Player, event: PickUpEvent) {} + protected open fun onInterfaceOpened(player: Player, event: InterfaceOpenEvent) {} + protected open fun onAttributeSet(player: Player, event: AttributeSetEvent) {} + protected open fun onAttributeRemoved(player: Player, event: AttributeRemoveEvent) {} + protected open fun onSpellCast(player: Player, event: SpellCastEvent) {} + protected open fun onItemAlchemized(player: Player, event: ItemAlchemizationEvent) {} + protected open fun onItemEquipped(player: Player, event: ItemEquipEvent) {} + protected open fun onItemUnequipped(player: Player, event: ItemUnequipEvent) {} + protected open fun onItemPurchasedFromShop(player: Player, event: ItemShopPurchaseEvent) {} + protected open fun onItemSoldToShop(player: Player, event: ItemShopSellEvent) {} + protected open fun onJobAssigned(player: Player, event: JobAssignmentEvent) {} + protected open fun onFairyRingDialed(player: Player, event: FairyRingDialEvent) {} + protected open fun onSummoningPointsRecharged(player: Player, event: SummoningPointsRechargeEvent) {} + protected open fun onPrayerPointsRecharged(player: Player, event: PrayerPointsRechargeEvent) {} +} \ No newline at end of file diff --git a/Server/src/main/core/game/diary/DiaryLevel.kt b/Server/src/main/core/game/diary/DiaryLevel.kt new file mode 100644 index 0000000..f983cc0 --- /dev/null +++ b/Server/src/main/core/game/diary/DiaryLevel.kt @@ -0,0 +1,8 @@ +package core.game.diary + +enum class DiaryLevel { + BEGINNER, + EASY, + MEDIUM, + HARD +} \ No newline at end of file diff --git a/Server/src/main/core/game/event/Event.kt b/Server/src/main/core/game/event/Event.kt new file mode 100644 index 0000000..9dfb6c7 --- /dev/null +++ b/Server/src/main/core/game/event/Event.kt @@ -0,0 +1,3 @@ +package core.game.event + +interface Event {} \ No newline at end of file diff --git a/Server/src/main/core/game/event/EventHook.kt b/Server/src/main/core/game/event/EventHook.kt new file mode 100644 index 0000000..728fa46 --- /dev/null +++ b/Server/src/main/core/game/event/EventHook.kt @@ -0,0 +1,7 @@ +package core.game.event + +import core.game.node.entity.Entity + +interface EventHook { + fun process(entity: Entity, event: T) +} diff --git a/Server/src/main/core/game/event/Events.kt b/Server/src/main/core/game/event/Events.kt new file mode 100644 index 0000000..900b416 --- /dev/null +++ b/Server/src/main/core/game/event/Events.kt @@ -0,0 +1,50 @@ +package core.game.event + +import core.game.component.Component +import core.game.dialogue.DialoguePlugin +import core.game.node.Node +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.link.SpellBookManager.SpellBook +import core.game.node.entity.player.link.TeleportManager.TeleportType +import core.game.node.entity.player.link.prayer.PrayerType +import core.game.node.item.Item +import core.game.world.map.Location +import content.global.activity.jobs.JobType +import content.global.handlers.iface.FairyRing +import content.global.skill.magic.TeleportMethod + +data class ResourceProducedEvent(val itemId: Int, val amount: Int, val source: Node, val original: Int = -1) : Event +data class NPCKillEvent(val npc: NPC) : Event +data class BoneBuryEvent(val boneId: Int) : Event +data class TeleportEvent(val type: TeleportType, val method: TeleportMethod, val source: Any, val location: Location) : Event +data class LitFireEvent(val logId: Int) : Event +data class LitLightSourceEvent(val litLightSourceId: Int) : Event +data class InteractionEvent(val target: Node, val option: String) : Event +data class ButtonClickEvent(val iface: Int, val buttonId: Int) : Event +data class DialogueOpenEvent(val dialogue: DialoguePlugin) : Event +data class DialogueOptionSelectionEvent(val dialogue: Any, val currentStage: Int, val optionId: Int) : Event +data class DialogueCloseEvent(val dialogue: DialoguePlugin) : Event +data class UseWithEvent(val used: Int, val with: Int) : Event +data class SelfDeathEvent(val killer: Entity) : Event +data class TickEvent(val worldTicks: Int) : Event +data class PickUpEvent(val itemId: Int) : Event +data class InterfaceOpenEvent(val component: Component) : Event +data class InterfaceCloseEvent(val component: Component) : Event +data class AttributeSetEvent(val entity: Entity, val attribute: String, val value: Any) : Event +data class AttributeRemoveEvent(val entity: Entity, val attribute: String) : Event +data class SpellCastEvent(val spellBook: SpellBook, val spellId: Int, val target: Node? = null) : Event +data class ItemAlchemizationEvent(val itemId: Int, val isHigh: Boolean) : Event +data class ItemEquipEvent(val itemId: Int, val slotId: Int) : Event +data class ItemUnequipEvent(val itemId: Int, val slotId: Int) : Event +data class ItemShopPurchaseEvent(val itemId: Int, val amount: Int, val currency: Item) : Event +data class ItemShopSellEvent(val itemId: Int, val amount: Int, val currency: Item) : Event +data class JobAssignmentEvent(val jobType: JobType, val employerNpc: NPC) : Event +data class FairyRingDialEvent(val fairyRing: FairyRing) : Event +data class VarbitUpdateEvent(val offset: Int, val value: Int) : Event +data class DynamicSkillLevelChangeEvent(val skillId: Int, val oldValue: Int, val newValue: Int): Event +data class SummoningPointsRechargeEvent(val obelisk: Node) : Event +data class PrayerPointsRechargeEvent(val altar: Node) : Event +data class XPGainEvent(val skillId: Int, val amount: Double) : Event +data class PrayerActivatedEvent (val type: PrayerType) : Event +data class PrayerDeactivatedEvent (val type: PrayerType) : Event diff --git a/Server/src/main/core/game/ge/BotPrices.kt b/Server/src/main/core/game/ge/BotPrices.kt new file mode 100644 index 0000000..3d180d8 --- /dev/null +++ b/Server/src/main/core/game/ge/BotPrices.kt @@ -0,0 +1,45 @@ +package core.game.ge + +import core.cache.def.impl.ItemDefinition +import org.rs09.consts.Items + +class BotPrices { + + companion object { + @JvmStatic + fun getPrice(id: Int): Int { + return getPriceOverrides(id) ?: ItemDefinition.forId(id).value + } + + @JvmStatic + private fun getPriceOverrides(id: Int): Int? { + return when (id) { + Items.PURE_ESSENCE_7936 -> 50 + Items.BOW_STRING_1777 -> 250 + Items.MAGIC_LOGS_1513 -> 750 + Items.COWHIDE_1739 -> 250 + Items.DRAGON_BONES_536 -> 1250 + Items.GREEN_DRAGONHIDE_1753 -> 550 + Items.GRIMY_RANARR_207 -> 1214 + Items.GRIMY_AVANTOE_211 -> 453 + Items.GRIMY_CADANTINE_215 -> 232 + Items.GRIMY_DWARF_WEED_217 -> 86 + Items.GRIMY_GUAM_199 -> 50 + Items.GRIMY_HARRALANDER_205 -> 115 + Items.GRIMY_IRIT_209 -> 860 + Items.GRIMY_KWUARM_213 -> 334 + Items.GRIMY_LANTADYME_2485 -> 115 + Items.GRIMY_MARRENTILL_201 -> 250 + Items.LOBSTER_379 -> 268 + Items.RAW_LOBSTER_377 -> 265 + Items.LOOP_HALF_OF_A_KEY_987 -> 5250 + Items.TOOTH_HALF_OF_A_KEY_985 -> 4263 + Items.SWORDFISH_373 -> 400 + Items.RAW_SWORDFISH_371 -> 390 + Items.SHARK_385 -> 720 + Items.RAW_SHARK_383 -> 710 + else -> null + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/ge/GEAutoStock.kt b/Server/src/main/core/game/ge/GEAutoStock.kt new file mode 100644 index 0000000..db0467e --- /dev/null +++ b/Server/src/main/core/game/ge/GEAutoStock.kt @@ -0,0 +1,35 @@ +package core.game.ge + +import core.api.StartupListener +import org.json.simple.JSONArray +import org.json.simple.JSONObject +import org.json.simple.parser.JSONParser +import core.ServerConstants +import java.io.File +import java.io.FileReader + +class GEAutoStock : StartupListener { + override fun startup() { + autostock() + } + + companion object { + // autostock format should be identical to the botoffers json format. + private val DB_PATH = "data" + File.separator + "eco" + File.separator + "autostock.json" + + fun autostock() { + if(ServerConstants.GE_AUTOSTOCK_ENABLED) { + val parser = JSONParser() + val botReader: FileReader? = FileReader(DB_PATH) + val botSave = parser.parse(botReader) as JSONObject + if (botSave.containsKey("offers")) { + val offers = botSave["offers"] as JSONArray + for (offer in offers) { + val o = offer as JSONObject + GrandExchange.addBotOffer(o["item"].toString().toInt(), o["qty"].toString().toInt()) + } + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/ge/GEDB.kt b/Server/src/main/core/game/ge/GEDB.kt new file mode 100644 index 0000000..3fedd1e --- /dev/null +++ b/Server/src/main/core/game/ge/GEDB.kt @@ -0,0 +1,94 @@ +package core.game.ge + +import core.ServerConstants +import core.cache.def.impl.ItemDefinition +import core.integrations.sqlite.SQLiteProvider +import org.json.simple.JSONArray +import org.json.simple.JSONObject +import java.sql.Connection + +/** + * Collection of methods for interacting with the grand exchange databases + * @author Ceikry + */ +object GEDB { + lateinit var db: SQLiteProvider + + fun init() { + init (ServerConstants.GRAND_EXCHANGE_DATA_PATH + "grandexchange.db") + } + + fun init (path: String) { + db = SQLiteProvider(path, expectedTables) + db.initTables { createdTable: String -> + if (createdTable == "price_index") + populateInitialPriceIndex() + } + } + + @JvmStatic fun run(closure: (conn: Connection) -> Unit) { + db.run(closure) + } + + private fun convertJsonArray(arr: JSONArray): String + { + val sb = StringBuilder() + for ((index, data) in arr.withIndex()) + { + val item = data as JSONObject + sb.append("$index") + sb.append(",") + sb.append(item["id"]) + sb.append(",") + sb.append(item["amount"]) + if(index + 1 < arr.size) + sb.append(":") + } + return sb.toString() + } + + var expectedTables = hashMapOf( + "player_offers" to "CREATE TABLE player_offers(" + + "uid INTEGER PRIMARY KEY ASC," + + "player_uid INTEGER," + + "item_id INTEGER," + + "amount_total INTEGER," + + "amount_complete INTEGER," + + "offered_value INTEGER," + + "time_stamp INTEGER," + + "offer_state INTEGER," + + "is_sale INTEGER," + + "withdraw_items STRING ," + + "slot_index INTEGER," + + "total_coin_xc INTEGER)", + "bot_offers" to "CREATE TABLE bot_offers(" + + "item_id INTEGER," + + "amount INTEGER)", + "price_index" to "CREATE TABLE price_index(" + + "item_id INTEGER," + + "value INTEGER," + + "total_value INTEGER," + + "unique_trades INTEGER," + + "last_update INTEGER)" + ) + + private fun populateInitialPriceIndex() + { + //price index isn't worth transferring, so we're just going to make a new one. + run { + with (it.prepareStatement(PriceIndex.INSERT_QUERY)) { + ItemDefinition.getDefinitions().values.forEach { def -> + if(def.isTradeable) { + setInt(1, def.id) + setInt(2, def.getAlchemyValue(true)) + setInt(3, def.getAlchemyValue(true)) + setInt(4, 0) + setInt(5, 0) + execute() + } + } + } + } + + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/ge/GEGuidePrice.java b/Server/src/main/core/game/ge/GEGuidePrice.java new file mode 100644 index 0000000..f5cff84 --- /dev/null +++ b/Server/src/main/core/game/ge/GEGuidePrice.java @@ -0,0 +1,147 @@ +package core.game.ge; + +import core.game.component.Component; +import core.game.node.entity.player.Player; +import core.tools.StringUtils; + +/** + * Represents the glass used to open the guide prices for the different type of + * trade(herbs, logs, runes, etc...) + * @author 'Vexia + * @date 30/11/2013 + */ +public final class GEGuidePrice { + + /** + * Represents the guide price component. + */ + private static final Component COMPONENT = new Component(642); + + /** + * Method used to open a Grand Exchange guide price type. + * @param player the player. + * @param type the type. + */ + public static final void open(final Player player, final GuideType type) { + player.getInterfaceManager().open(COMPONENT); + type.display(player); + } + + /** + * Method used to clear the current items being showed. + * @param player the player. + */ + public static final void clear(final Player player) { + for (int i = 135; i < 165; i++) { + player.getPacketDispatch().sendInterfaceConfig(COMPONENT.getId(), i, true); + } + } + + /** + * Represents a guide item shown on the Guide Price interface. + * @author 'Vexia + * @date 01/12/2013 + */ + public static class GuideItem { + + /** + * Represents the item of this type. + */ + private final int item; + + /** + * Represents the unlock child. + */ + private final int[] childData; + + /** + * Constructs a new {@code GEGuidePrice} {@code Object}. + * @param item the item. + * @param childData the child data. + */ + public GuideItem(final int item, final int... childData) { + this.item = item; + this.childData = childData; + } + + /** + * Gets the item. + * @return The item. + */ + public int getItem() { + return item; + } + + /** + * Gets the childData. + * @return The childData. + */ + public int[] getChildData() { + return childData; + } + } + + /** + * Represents a guide price type of trade(herbs, logs, etc...) + * @author 'Vexia + * @date 30/11/2013 + */ + public enum GuideType { + LOGS(new int[] { 0, 0 }, new GuideItem(1511, 155), new GuideItem(2862, 156), new GuideItem(1521, 157), new GuideItem(1519, 158), new GuideItem(6333, 159), new GuideItem(1517, 160), new GuideItem(6332, 161), new GuideItem(12581, 162), new GuideItem(1515, 163), new GuideItem(1513, 164)), ORES(new int[] { 40, 44 }, new GuideItem(436, 33), new GuideItem(438, 34), new GuideItem(440, 35), new GuideItem(442, 36), new GuideItem(453, 37), new GuideItem(444, 38), new GuideItem(447, 39), new GuideItem(449, 40), new GuideItem(451, 41)), RUNES(new int[] { 215, 216 }, new GuideItem(1436, 183), new GuideItem(7936, 184), new GuideItem(556, 185), new GuideItem(558, 186), new GuideItem(555, 187), new GuideItem(557, 188), new GuideItem(554, 189), new GuideItem(559, 190), new GuideItem(564, 191), new GuideItem(562, 192), new GuideItem(9075, 193), new GuideItem(561, 194), new GuideItem(563, 195), new GuideItem(560, 196), new GuideItem(565, 197), new GuideItem(566, 198)), HERBS(new int[] { 130, 135 }, new GuideItem(249, 119), new GuideItem(251, 120), new GuideItem(253, 121), new GuideItem(255, 122), new GuideItem(257, 123), new GuideItem(2998, 124), new GuideItem(259, 125), new GuideItem(12172, 126), new GuideItem(261, 127), new GuideItem(263, 128), new GuideItem(3000, 129), new GuideItem(265, 130), new GuideItem(2481, 131), new GuideItem(267, 132), new GuideItem(269, 133)), WEAPONS_AND_ARMOUR(new int[] { 88, 89 }, new GuideItem(11834, 73), new GuideItem(11838, 74), new GuideItem(11842, 75), new GuideItem(11864, 76), new GuideItem(11870, 77), new GuideItem(11846, 78), new GuideItem(11848, 79), new GuideItem(11850, 80), new GuideItem(11856, 81), new GuideItem(11732, 82), new GuideItem(4151, 83), new GuideItem(11235, 84), new GuideItem(6739, 85), new GuideItem(4587, 86), new GuideItem(4153, 87)); + + /** + * Constructs a new {@code GEGuidePrice} {@code Object}. + * @param childData the childData. + * @param items the guide items. + */ + GuideType(final int[] childData, final GuideItem... items) { + this.childData = childData; + this.items = items; + } + + /** + * Represents the guide items. + */ + private final GuideItem[] items; + + /** + * Represents the child data for the guide type. + */ + private final int childData[]; + + /** + * Gets the items. + * @return The items. + */ + public GuideItem[] getItems() { + return items; + } + + /** + * Gets the childData. + * @return The childData. + */ + public int[] getChildData() { + return childData; + } + + /** + * Method used to display the guide type. + * @param player the player. + */ + public void display(final Player player) { + player.setAttribute("guide-price", this); + if (this != LOGS) { + clear(player); + } + player.getPacketDispatch().sendString("Guide Prices: " + StringUtils.formatDisplayName(name()), COMPONENT.getId(), 14); + for (int i = getChildData()[0]; i < getChildData()[1]; i++) { + player.getPacketDispatch().sendInterfaceConfig(642, i, false); + } + for (GuideItem item : getItems()) { + player.getPacketDispatch().sendString("" + GrandExchange.getRecommendedPrice(item.item, false) + " gp", COMPONENT.getId(), item.getChildData()[0]); + } + } + } + +} diff --git a/Server/src/main/core/game/ge/GEItemSet.java b/Server/src/main/core/game/ge/GEItemSet.java new file mode 100644 index 0000000..dd7a55d --- /dev/null +++ b/Server/src/main/core/game/ge/GEItemSet.java @@ -0,0 +1,94 @@ +package core.game.ge; + +import core.game.node.item.Item; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +/** + * Holds the Grand Exchange item sets. + * @author Emperor + */ +public enum GEItemSet { + + BRONZE_L(11814, 1155, 1117, 1075, 1189), BRONZE_SK(11816, 1155, 1117, 1087, 1189), IRON_L(11818, 1153, 1115, 1067, 1191), IRON_SK(11820, 1153, 1115, 1081, 1191), STEEL_L(11822, 1157, 1119, 1069, 1193), STEEL_SK(11824, 1157, 1119, 1083, 1193), BLACK_L(11826, 1165, 1125, 1077, 1195), BLACK_SK(11828, 1165, 1125, 1089, 1195), MITHRIL_L(11830, 1159, 1121, 1071, 1197), MITHRIL_SK(11832, 1159, 1121, 1085, 1197), ADAMANT_L(11834, 1161, 1123, 1073, 1199), ADAMANT_SK(11836, 1161, 1123, 1091, 1199), RUNE_L(11838, 1163, 1127, 1079, 1201), RUNE_SK(11840, 1163, 1127, 1093, 1201), DRAGON_L(11842, 1149, 3140, 4087), DRAGON_SK(11844, 1149, 3140, 4585), + // NULL_1(-1), //This would create the spaces between the sets (uncomment + // when needed) + AHRIMS(11846, 4708, 4712, 4714, 4710), DHAROKS(11848, 4716, 4720, 4722, 4718), GUTHANS(11850, 4724, 4728, 4730, 4726), KARILS(11852, 4732, 4736, 4738, 4734), TORAGS(11854, 4745, 4749, 4751, 4747), VERACS(11856, 4753, 4757, 4759, 4755), THIRD_AGE_MELEE(11858, 10350, 10348, 10346, 10352), THIRD_AGE_RANGE(11860, 10334, 10330, 10332, 10336), THIRD_AGE_MAGE(11862, 10342, 10338, 10340, 10344), GREEN_DHIDE(11864, 1135, 1099, 1065), BLUE_DHIDE(11866, 2499, 2493, 2487), RED_DHIDE(11868, 2501, 2495, 2489), BLACK_DHIDE(11870, 2503, 2497, 2491), MYSTIC(11872, 4089, 4091, 4093, 4095, 4097), LIGHT_MYSTIC(11960, 4109, 4111, 4113, 4115, 4117), DARK_MYSTIC(11962, 4099, 4101, 4103, 4105, 4107), INFINITY(11874, 6918, 6916, 6924, 6922, 6920), SPLITBARK(11876, 3385, 3387, 3389, 3391, 3393), BLACK_TRIMMED_L(11878, 2587, 2583, 2585, 2589), BLACK_TRIMMED_SK(11880, 2587, 2583, 3472, 2589), BLACK_GOLD_TRIMMED_L(11882, 2595, 2591, 2593, 2597), BLACK_GOLD_TRIMMED_SK(11884, 2595, 2591, 3473, 2597), ADAMANT_TRIMMED_L(11886, 2605, 2599, 2601, 2603), ADAMANT_TRIMMED_SK(11888, 2605, 2599, 3474), ADAMANT_GOLD_TRIMMED_L(11890, 2613, 2607, 2609, 2611), ADAMANT_GOLD_TRIMMED_SK(11892, 2613, 3475, 2611), RUNE_TRIMMED_L(11894, 2627, 2623, 2625, 2629), RUNE_TRIMMED_SK(11896, 2627, 2623, 3477, 2629), RUNE_GOLD_TRIMMED_L(11898, 2619, 2615, 2617, 2621), RUNE_GOLD_TRIMMED_SK(11900, 2619, 2615, 3476, 2621), ENCHANTED(11902, 7400, 7399, 7398), TRIMMED_BLUE_WIZARD(11904, 7396, 7392, 7388), GOLD_TRIMMED_BLUE_WIZARD(11906, 7394, 7390, 7386), TRIMMED_LEATHER(11908, 7364, 7368), GOLD_TRIMMED_LEATHER(11910, 7362, 7366), GREEN_DHIDE_T(11912, 7372, 7380), GREEN_DHIDE_G(11914, 7370, 7378), BLUE_DHIDE_T(11916, 7376, 7384), BLUE_DHIDE_G(11918, 7374, 7382), GREEN_DHIDE_BLESSED(11920, 10382, 10378, 10380, 10376), BLUE_DHIDE_BLESSED(11922, 10390, 10386, 10388, 10384), RED_DHIDE_BLESSED(11924, 10374, 10370, 10372, 10368), GUTHIX_L(11926, 2673, 2669, 2671, 2675), SARADOMIN_L(11928, 2665, 2661, 2663, 2667), ZAMORAK_L(11930, 2657, 2653, 2655, 2659), GUTHIX_SK(11932, 2673, 2669, 3480, 2675), SARADOMIN_SK(11934, 2665, 2661, 3479, 2667), ZAMORAK_SK(11936, 2657, 2653, 3478, 2659), GILDED_L(11938, 3486, 3481, 3483, 3488), GILDED_SK(11940, 3486, 3481, 3485, 3488), ROCKSHELL(11942, 6128, 6129, 6130, 6151, 6145), SPINED(11944, 6131, 6133, 6135, 6149, 6143), SKELETAL(11946, 6137, 6139, 6141, 6153, 6147), CANNON(11967, 6, 8, 10, 12); + + /** + * The item sets mapping. + */ + private static final Map ITEM_SETS = new HashMap<>(); + + /** + * The items array. + */ + private static Item[] itemArray; + + /** + * Populate the mapping. + */ + static { + itemArray = new Item[values().length]; + for (int i = 0; i < itemArray.length; i++) { + GEItemSet set = values()[i]; + itemArray[i] = set.itemId == -1 ? new Item() : new Item(set.itemId); + ITEM_SETS.put(set.itemId, set); + } + } + + /** + * Gets the item set for the given id. + * @param setId The set item id. + * @return The item set object. + */ + public static GEItemSet forId(int setId) { + return ITEM_SETS.get(setId); + } + + /** + * The item id. + */ + private int itemId; + + /** + * The components. + */ + private int[] components; + + /** + * Constructs a new {@code GEItemSet} {@code Object}. + * @param itemId The item id. + * @param components The components. + */ + private GEItemSet(int itemId, int... components) { + this.itemId = itemId; + this.components = components; + } + + /** + * Gets the itemId. + * @return The itemId. + */ + public int getItemId() { + return itemId; + } + + /** + * Gets the components. + * @return The components. + */ + public int[] getComponents() { + return Arrays.copyOf(components, components.length); + } + + /** + * Gets the item array. + * @return The item array. + */ + public static Item[] getItemArray() { + return Arrays.copyOf(itemArray, itemArray.length); + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/ge/GrandExchange.kt b/Server/src/main/core/game/ge/GrandExchange.kt new file mode 100644 index 0000000..5b763bf --- /dev/null +++ b/Server/src/main/core/game/ge/GrandExchange.kt @@ -0,0 +1,382 @@ +package core.game.ge + +import core.ServerConstants +import core.api.* +import core.cache.def.impl.ItemDefinition +import core.game.node.entity.player.Player +import core.game.node.entity.player.info.PlayerDetails +import core.game.system.command.Privilege +import core.game.system.config.ItemConfigParser +import core.game.system.task.Pulse +import core.game.world.GameWorld +import core.game.world.repository.Repository +import core.tools.Log +import core.tools.SystemLogger +import core.tools.colorize +import org.rs09.consts.Sounds +import java.lang.Integer.max +import java.util.concurrent.LinkedBlockingDeque + +/** + * Handles the exchanging of offers, offer update thread, etc. + * @author Ceikry + */ +class GrandExchange : StartupListener, Commands { + + /** + * Fallback safety check to make sure we don't start the GE twice under any circumstance + */ + var isRunning = false + + /** + * Initializes the offer manager and spawns an update thread. + * @param local whether or not the GE should be the local in-code server rather than some hypothetical remote implementation. + */ + fun boot(){ + if(isRunning) return + + SystemLogger.logGE("Initializing GE Update Worker") + + Thread { + Thread.currentThread().name = "GE Update Worker" + while(true) { + var offer = pendingOffers.takeFirst() + offer.writeNew() + offer = getOfferByUid(offer.uid) ?: continue + selectPotentialMatches(offer).asSequence() + .sortedBy { if (offer.sell) -it.offeredValue else it.offeredValue } + .filter { if (offer.sell) it.offeredValue >= offer.offeredValue else it.offeredValue <= offer.offeredValue } + .forEach { match -> exchange(offer, match) } + if (!offer.isBot && offer.amountLeft > 0 && !offer.sell) + tryExchangeWithBots(offer) + } + }.start() + + isRunning = true + } + + + private fun tryExchangeWithBots(offer: GrandExchangeOffer) { + GEDB.run { conn -> + val query = conn.prepareStatement(GET_MATCH_FROM_BOT_OFFERS) + query.setInt(1, offer.itemID) + val res = query.executeQuery() + + if (res.next()) { + exchange(offer, GrandExchangeOffer.fromBotQuery(res).also { it.timeStamp = offer.timeStamp - 1L }) + } + } + } + + private fun selectPotentialMatches(offer: GrandExchangeOffer): List { + val matches = ArrayList() + GEDB.run { conn -> + val query = conn.prepareStatement(GET_MATCHES_FROM_PLAYER_OFFERS) + query.setInt(1, offer.itemID) + query.setBoolean(2, !offer.sell) + val res = query.executeQuery() + while (res.next()) { + matches.add(GrandExchangeOffer.fromQuery(res)) + } + } + return matches + } + + override fun defineCommands() { + define("addbotoffer", Privilege.ADMIN) {player, strings -> + val id = strings[1].toInt() + val amount = strings[2].toInt() + addBotOffer(id, amount) + notify(player, "Added ${amount}x ${getItemName(id)} to the bot offers.") + } + + define("bange", Privilege.ADMIN) {player, strings -> + val id = strings[1].toInt() + PriceIndex.banItem(id) + notify(player, "Banned ${getItemName(id)} from GE trade.") + } + + define("allowge", Privilege.ADMIN) {player, strings -> + val id = strings[1].toInt() + PriceIndex.allowItem(id) + notify(player, "Allowed ${getItemName(id)} for GE trade.") + } + + define("geprivacy", Privilege.STANDARD) {player, _ -> + val current = getAttribute(player, "ge-exclude", false) + val new = !current + notify(player, "Your name is now ${if (new) colorize("%RHIDDEN") else colorize("%RSHOWN")}.") + setAttribute(player, "/save:ge-exclude", new) + } + } + + companion object { + val pendingOffers = LinkedBlockingDeque() + private val GET_SPECIFIC_OFFER_BY_UID = "SELECT * FROM player_offers WHERE uid = ?;" + private val GET_MATCHES_FROM_PLAYER_OFFERS = "SELECT * FROM player_offers WHERE item_id = ? AND is_sale = ? AND offer_state < 4 AND NOT offer_state = 2;" + private val GET_MATCH_FROM_BOT_OFFERS = "SELECT * FROM bot_offers WHERE item_id = ?;" + + private fun getOfferByUid(uid: Long): GrandExchangeOffer? { + var offer: GrandExchangeOffer? = null + GEDB.run { conn -> + val query = conn.prepareStatement(GET_SPECIFIC_OFFER_BY_UID) + query.setLong(1, uid) + val res = query.executeQuery() + + if (res.next()) + offer = GrandExchangeOffer.fromQuery(res) + } + return offer + } + + @JvmStatic + fun getRecommendedPrice(itemID: Int, from_bot: Boolean = false): Int { + var base = max(PriceIndex.getValue(itemID), getItemDefPrice(itemID)) + if (from_bot) base = (max(BotPrices.getPrice(itemID), base) * 1.10).toInt() + return base + } + + private fun getItemDefPrice(itemID: Int): Int { + return max(itemDefinition(itemID).getConfiguration(ItemConfigParser.GE_PRICE) ?: 0, itemDefinition(itemID).value) + } + + @JvmStatic + fun getOfferStats(itemID: Int, sale: Boolean) : String + { + val sb = StringBuilder() + + GEDB.run { conn -> + var foundOffers = 0 + var totalAmount = 0 + var bestPrice = 0 + var stmt = conn.createStatement() + + if (!sale) { + var botAmt = 0 + var botPrice = 0 + val player_offers = stmt.executeQuery("SELECT * from player_offers where item_id = $itemID AND is_sale = 1 AND offer_state < 4 AND NOT offer_state = 2") + + while (player_offers.next()) { + val o = GrandExchangeOffer.fromQuery(player_offers) + ++foundOffers + totalAmount += o.amountLeft + if (o.offeredValue < bestPrice || bestPrice == 0) + bestPrice = o.offeredValue + } + + stmt.close() + stmt = conn.createStatement() + val bot_offers = stmt.executeQuery("SELECT * from bot_offers where item_id = $itemID") + if (bot_offers.next()) { + val o = GrandExchangeOffer.fromBotQuery(bot_offers) + botAmt = o.amount + botPrice = getRecommendedPrice(itemID, true) + } + + sb.append("Player Stock: $totalAmount ") + sb.append(" Lowest Price: $bestPrice
") + sb.append("-".repeat(50)) + sb.append("
Bot Stock: $botAmt ") + sb.append(" Bot Price: $botPrice") + } else { + val buy_offers = stmt.executeQuery("SELECT * from player_offers where item_id = $itemID AND is_sale = 0 AND offer_state < 4 AND NOT offer_state = 2") + + while (buy_offers.next()) { + val o = GrandExchangeOffer.fromQuery(buy_offers) + ++foundOffers + totalAmount += o.amountLeft + if (o.offeredValue > bestPrice) + bestPrice = o.offeredValue + } + + sb.append("Buy Offers: $totalAmount ") + sb.append("Highest Offer: $bestPrice") + } + + stmt.close() + } + + return sb.toString() + } + + fun addBotOffer(itemID: Int, amount: Int): Boolean + { + if (!PriceIndex.canTrade(itemID)) + return false + + // noted offers can not be bought. + val itemDef = ItemDefinition.forId(itemID) + val offer = GrandExchangeOffer.createBotOffer(if (itemDef.isUnnoted) itemID else itemDef.noteId, amount) + pendingOffers.addLast(offer) + + return true + } + + fun dispatch(player: Player, offer: GrandExchangeOffer) : Boolean + { + if ( offer.amount < 1 ) + sendMessage(player, "You must choose the quantity you wish to buy!").also { return false } + + if ( offer.offeredValue < 1 ) + sendMessage(player, "You must choose the price you wish to buy for!").also { return false } + + if ( offer.offerState != OfferState.PENDING || offer.uid != 0L ) + { + log(this::class.java, Log.WARN, "[GE] DISPATCH FAILURE: ${offer.offerState.name}, UID: ${offer.uid}") + return false + } + + if ( player.isArtificial ) + offer.playerUID = PlayerDetails.getDetails("2009scape").uid.also { offer.isBot = true } + else + offer.playerUID = player.details.uid + + offer.offerState = OfferState.REGISTERED + //GrandExchangeRecords.getInstance(player).update(offer) + + if (offer.sell && !player.isArtificial) { + val username = if (getAttribute(player, "ge-exclude", false)) "?????" else player.username + Repository.sendNews(username + " just offered " + offer.amount + " " + getItemName(offer.itemID) + " on the GE.") + } + + if (ServerConstants.I_AM_A_CHEATER) { + val otherO = GrandExchangeOffer() + otherO.itemID = offer.itemID + otherO.amount = offer.amount + otherO.sell = !offer.sell + otherO.offeredValue = offer.offeredValue + offer.writeNew() + GameWorld.Pulser.submit(object : Pulse(5) { + override fun pulse(): Boolean { + val offer2 = getOfferByUid(offer.uid) ?: return false + exchange(offer2, otherO) + return true + } + }) + return true + } + + pendingOffers.add(offer) + return true + } + + fun exchange(offer: GrandExchangeOffer, other: GrandExchangeOffer) + { + if(offer.sell == other.sell) return //Don't exchange if they are both buy/sell offers + val amount = Integer.min(offer.amount - offer.completedAmount, other.amount - other.completedAmount) + + if (amount == 0) return + + val seller = if(offer.sell) offer else other + val buyer = if(offer == seller) other else offer + + val sellerBias = seller.timeStamp > buyer.timeStamp + + //If the buyer is buying for less than the seller is selling for, don't exchange + if(seller.offeredValue > buyer.offeredValue) return + + seller.completedAmount += amount + buyer.completedAmount += amount + + if(seller.amountLeft < 1 && seller.player != null) + playAudio(seller.player!!, Sounds.GE_COLLECT_COINS_4042) + + seller.addWithdrawItem(995, amount * if(sellerBias) buyer.offeredValue else seller.offeredValue) + buyer.addWithdrawItem(seller.itemID, amount) + + if(!sellerBias) + buyer.addWithdrawItem(995, amount * (buyer.offeredValue - seller.offeredValue)) + + if(seller.amountLeft < 1) + seller.offerState = OfferState.COMPLETED + if(buyer.amountLeft < 1) + buyer.offerState = OfferState.COMPLETED + + val totalCoinXC = (if(sellerBias) buyer.offeredValue else seller.offeredValue) * amount + + seller.totalCoinExchange += totalCoinXC + buyer.totalCoinExchange += totalCoinXC + + if(canUpdatePriceIndex(seller, buyer)) + PriceIndex.addTrade(offer.itemID, amount, (totalCoinXC / amount)) + +/* + if (seller.amountLeft > 0) { + Discord.postOfferUpdate(true, seller.itemID, seller.offeredValue, seller.amountLeft) + } + + if (buyer.amountLeft > 0) { + Discord.postOfferUpdate(false, buyer.itemID, buyer.offeredValue, buyer.amountLeft) + } +*/ + + seller.update() + val sellerPlayer = Repository.uid_map[seller.playerUID] + sellerPlayer?.let { GrandExchangeRecords.getInstance(sellerPlayer).visualizeRecords() } + buyer.update() + val buyerPlayer = Repository.uid_map[buyer.playerUID] + buyerPlayer?.let { GrandExchangeRecords.getInstance(buyerPlayer).visualizeRecords() } + } + + private fun canUpdatePriceIndex(seller: GrandExchangeOffer, buyer: GrandExchangeOffer): Boolean { + if(seller.playerUID == buyer.playerUID) return false + if(!ServerConstants.BOTS_INFLUENCE_PRICE_INDEX && (seller.isBot || buyer.isBot)) return false + return true + } + + fun getValidOffers(): List + { + val offers = ArrayList() + + GEDB.run { conn -> + val stmt = conn.createStatement() + + val results = + stmt.executeQuery("SELECT * FROM player_offers WHERE offer_state < 4 AND NOT offer_state = 2") + while (results.next()) { + val o = GrandExchangeOffer.fromQuery(results) + offers.add(o) + } + stmt.close() + } + return offers + } + + fun getBotOffers(): List + { + val offers = ArrayList() + + GEDB.run { conn -> + val stmt = conn.createStatement() + + val results = stmt.executeQuery("SELECT item_id,amount FROM bot_offers WHERE amount > 0") + while (results.next()) { + val o = GrandExchangeOffer.fromBotQuery(results) + offers.add(o) + } + stmt.close() + } + return offers + } + + fun getBotstockForId(itemId: Int): Int { + var total = 0 + GEDB.run { conn -> + val stmt = conn.prepareStatement("SELECT sum(amount) FROM bot_offers WHERE amount > 0 AND item_id = ?") + stmt.setInt(1, itemId) + + val results = stmt.executeQuery() + while (results.next()) { + total += results.getInt(1) + } + } + return total + } + + } + + override fun startup(){ + GEDB.init() + boot() + } +} diff --git a/Server/src/main/core/game/ge/GrandExchangeOffer.kt b/Server/src/main/core/game/ge/GrandExchangeOffer.kt new file mode 100644 index 0000000..9194275 --- /dev/null +++ b/Server/src/main/core/game/ge/GrandExchangeOffer.kt @@ -0,0 +1,261 @@ +package core.game.ge + +import core.api.getAttribute +import core.cache.def.impl.ItemDefinition +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.net.packet.PacketRepository +import core.net.packet.context.ContainerContext +import core.net.packet.context.GrandExchangeContext +import core.net.packet.out.ContainerPacket +import core.net.packet.out.GrandExchangePacket +import core.integrations.discord.Discord +import core.game.world.repository.Repository +import kotlin.math.min +import java.sql.ResultSet +import core.ServerConstants + + +/** + * A struct holding all the data for grand exchange offers. + * + * @author Ceikry + */ + +class GrandExchangeOffer() { + var itemID = 0 + var completedAmount = 0 + var offeredValue = 0 + var index = 0 + var sell = false + var offerState = OfferState.PENDING + var uid: Long = 0 + var timeStamp: Long = 0 + var withdraw = arrayOfNulls(2) + var totalCoinExchange = 0 + var player: Player? = null + var playerUID = 0 + var isLimitation = false + var isBot = false + + var amount: Int = 0 + get() = if (isBot) min(field, ServerConstants.BOTSTOCK_LIMIT) else field + /** + * Gets the total amount of money entered. + * @return The total value. + */ + val totalValue: Int + get() = offeredValue * amount + + /** + * Gets the amount of this item left to buy. + * @return The amount. + */ + val amountLeft: Int + get() = if (isBot) min(ServerConstants.BOTSTOCK_LIMIT, amount - completedAmount) else amount - completedAmount + + /** + * Checks if this offer is still active for dispatching. + * @return `True` if so. + */ + val isActive: Boolean + get() = offerState != OfferState.ABORTED && offerState != OfferState.PENDING && offerState != OfferState.COMPLETED && offerState != OfferState.REMOVED + + fun addWithdrawItem(id: Int, amount: Int) + { + if(amount == 0) return + //loop checking if the item is already present first + for(item in withdraw) + if(item != null && item.id == id) + { + item.amount += amount + return + } + + //if we make it to this point, the item was not present. Loop to find first null slot and stick item there. + for((index,item) in withdraw.withIndex()) + if(item == null) + { + withdraw[index] = Item(id, amount) + return + } + + //send container update packet to player if they exist (are online) + if ( player != null ) + visualize(player) + } + + fun visualize(player: Player?) + { + player ?: return + PacketRepository.send( + GrandExchangePacket::class.java, + GrandExchangeContext(player, index.toByte(), offerState.ordinal.toByte(), itemID.toShort(), + sell, offeredValue, amount, completedAmount, totalCoinExchange) + ) + PacketRepository.send(ContainerPacket::class.java, ContainerContext(player, -1, -1757, 523 + index, withdraw, false)) + } + + fun update() + { + GEDB.run { conn -> + if (isBot) { + val stmt = conn.prepareStatement("UPDATE bot_offers SET amount = ? WHERE item_id = ?") + stmt.setInt(1, amountLeft) + stmt.setInt(2, itemID) + stmt.executeUpdate() + stmt.close() + } else { + val stmt = conn.prepareStatement("UPDATE player_offers SET amount_complete = ?, offer_state = ?, total_coin_xc = ?, withdraw_items = ?, slot_index = ? WHERE uid = ?") + stmt.setInt(1, completedAmount) + stmt.setInt(2, offerState.ordinal) + stmt.setInt(3, totalCoinExchange) + stmt.setString(4, encodeWithdraw()) + stmt.setInt(5, index) + stmt.setLong(6, uid) + stmt.executeUpdate() + stmt.close() + } + } + } + + /** Called when writing a brand new offer to the database. Should not be used under any other circumstance **/ + fun writeNew() + { + GEDB.run { conn -> + if (isBot) { + val stmt = conn.createStatement() + val result = stmt.executeQuery("SELECT * from bot_offers where item_id = $itemID") + val isExists = result.next() + + if (isExists) { + val oldAmount = result.getInt("amount") + stmt.executeUpdate("UPDATE bot_offers set amount = ${oldAmount + amount} where item_id = $itemID") + } else + stmt.executeUpdate("INSERT INTO bot_offers(item_id,amount) values($itemID,$amount)") + stmt.close() + } else { + val stmt = conn.createStatement() + stmt.executeUpdate( + "INSERT INTO player_offers(player_uid, item_id, amount_total, offered_value, time_stamp, offer_state, is_sale, slot_index) " + + "values($playerUID,$itemID,$amount,$offeredValue,${System.currentTimeMillis()},${offerState.ordinal},${if (sell) 1 else 0}, $index)" + ) + val nowuid = stmt.executeQuery("SELECT last_insert_rowid()") + uid = nowuid.getLong(1) + GrandExchangeRecords.getInstance(player).offerRecords[index] = GrandExchangeRecords.OfferRecord(uid, index) + visualize(player) + stmt.close() + + val username = if (getAttribute(player ?: return@run, "ge-exclude", false)) "?????" + else player?.username ?: "?????" + + Discord.postNewOffer(sell, itemID, offeredValue, amount, username) + } + } + } + + private fun encodeWithdraw() : String + { + val sb = StringBuilder() + for((index, item) in withdraw.withIndex()) + { + sb.append(index) + sb.append(",") + if(item == null) + sb.append("null") + else + sb.append(item.id) + sb.append(",") + if(item == null) + sb.append("null") + else + sb.append(item.amount) + + if(index + 1 < withdraw.size) + sb.append(":") + } + + return sb.toString() + } + + override fun toString(): String { + return "[name=" + ItemDefinition.forId(itemID).name + ", itemId=" + itemID + ", amount=" + amount + ", completedAmount=" + completedAmount + ", offeredValue=" + offeredValue + ", index=" + index + ", sell=" + sell + ", state=" + offerState + ", withdraw=" + withdraw.contentToString() + ", totalCoinExchange=" + totalCoinExchange + ", playerUID=" + playerUID + "]" + } + + companion object { + fun fromQuery(result: ResultSet): GrandExchangeOffer + { + val o = GrandExchangeOffer() + o.itemID = result.getInt("item_id") + o.amount = result.getInt("amount_total") + o.completedAmount = result.getInt("amount_complete") + o.offeredValue = result.getInt("offered_value") + o.sell = result.getInt("is_sale") == 1 + o.offerState = OfferState.values()[result.getInt("offer_state")] + o.uid = result.getLong("uid") + o.timeStamp = result.getLong("time_stamp") + + val itemString = result.getString("withdraw_items") + if(itemString != null && itemString.isNotEmpty()) { + val items = itemString.split(":") + for (item in items) { + if(item.isEmpty()) continue + val tokens = item.split(",") + val index = tokens[0].toInt() + if (tokens[1] == "null") continue //Skip null slots + o.withdraw[index] = Item(tokens[1].toInt(), tokens[2].toInt()) + } + } + + o.totalCoinExchange = result.getInt("total_coin_xc") + o.playerUID = result.getInt("player_uid") + o.index = result.getInt("slot_index") + o.player = Repository.players.firstOrNull { it.details.accountInfo.uid == o.playerUID } + + return o + } + + fun fromBotQuery(result: ResultSet): GrandExchangeOffer + { + val o = GrandExchangeOffer() + o.sell = true + o.amount = result.getInt("amount") + o.offerState = OfferState.REGISTERED + o.itemID = result.getInt("item_id") + o.offeredValue = GrandExchange.getRecommendedPrice(o.itemID, true) + o.isBot = true + o.timeStamp = System.currentTimeMillis() + return o + } + + fun createBotOffer(itemId: Int, amount: Int, sale: Boolean = true) : GrandExchangeOffer + { + val o = GrandExchangeOffer() + o.sell = sale + o.itemID = itemId + o.amount = amount + o.offeredValue = GrandExchange.getRecommendedPrice(itemId, true) + o.offerState = OfferState.REGISTERED + o.isBot = true + return o + } + } + + fun cacheValue(): Int { + var value = 0 + if(sell) { + // count the cache value of the unsold items + value += ItemDefinition.forId(itemID).getValue() * amountLeft + } else { + // count the number of coins that haven't yet been spent + value += offeredValue * amountLeft + } + // for both the buyer and seller, the already completed portion is present in withdraw + for(item in withdraw) { + if(item != null) { + value += item.definition.value * item.amount + } + } + return value + } +} diff --git a/Server/src/main/core/game/ge/GrandExchangeRecords.kt b/Server/src/main/core/game/ge/GrandExchangeRecords.kt new file mode 100644 index 0000000..63aa208 --- /dev/null +++ b/Server/src/main/core/game/ge/GrandExchangeRecords.kt @@ -0,0 +1,255 @@ +package core.game.ge + +import core.api.* +import core.cache.def.impl.ItemDefinition +import core.game.component.Component +import core.game.node.entity.player.Player +import org.json.simple.JSONArray +import org.json.simple.JSONObject +import org.rs09.consts.Components +import core.tools.SystemLogger +import java.text.NumberFormat +import java.util.* + + +/** + * Handles the grand exchange interfaces for the player. + * + * @author Emperor + * @author Angle + */ + +class GrandExchangeRecords(private val player: Player? = null) : PersistPlayer, LoginListener { + var history = arrayOfNulls(5) + val offerRecords = arrayOfNulls(6) + + override fun login(player: Player) { + val instance = GrandExchangeRecords(player) + player.setAttribute("ge-records", instance) + } + + override fun parsePlayer(player: Player, data: JSONObject) { + /** + * Parse history from JSON + */ + val historyRaw = data["ge-history"] + if(historyRaw != null){ + val history = historyRaw as JSONArray + for (i in history.indices) { + val offer = history[i] as JSONObject + val o = GrandExchangeOffer() + o.itemID = offer["itemId"].toString().toInt() + o.sell = offer["isSell"] as Boolean + o.totalCoinExchange = (offer["totalCoinExchange"].toString().toInt()) + o.completedAmount = (offer["completedAmount"].toString().toInt()) + getInstance(player).history[i] = o + } + } + + /** + * Read offers from the database + */ + val needsIndex = ArrayDeque() + val instance = getInstance(player) + + GEDB.run { conn -> + val stmt = conn.createStatement() + val offer_records = stmt.executeQuery("SELECT * from player_offers where player_uid = ${player.details.uid} AND offer_state < 6") + + while (offer_records.next()) { + val offer = GrandExchangeOffer.fromQuery(offer_records) + if (offer.index == -1) //used to index old (converted from JSON) offers + needsIndex.push(offer) + else + instance.offerRecords[offer.index] = OfferRecord(offer.uid, offer.index) + } + stmt.close() + } + + if (needsIndex.isNotEmpty()) { + for ((index, offer) in offerRecords.withIndex()) { + if (offer == null) { + val o = needsIndex.pop() + o.index = index + instance.offerRecords[o.index] = OfferRecord(o.uid, o.index) + o.update() //write the new index to the database + } + } + + while(needsIndex.isNotEmpty()) //If we enter this loop, there were more offers than can fit inside the 6 slots. This should never happen - at least, not anymore. Can't speak for JSON offers. + { + val o = needsIndex.pop() + SystemLogger.logGE("[WARN] PLAYER HAD EXTRA OFFER - RECOMMEND IMMEDIATE REFUND OF CONTENTS -> OFFER UID: ${o.uid}") + SystemLogger.logGE("[WARN] AS PER ABOVE MESSAGE, REFUND CONTENTS OF OFFER AND MANUALLY SET offer_state = 6") + } + } + + instance.init() + } + + override fun savePlayer(player: Player, save: JSONObject) { + /** + * Save history to JSON + */ + val history = JSONArray() + getInstance(player).history.map { + if(it != null){ + val historyEntry = JSONObject() + historyEntry["isSell"] = it.sell + historyEntry["itemId"] = it.itemID.toString() + historyEntry["totalCoinExchange"] = it.totalCoinExchange.toString() + historyEntry["completedAmount"] = it.completedAmount.toString() + history.add(historyEntry) + } + } + save["ge-history"] = history + } + + /** + * Opens the collection box. + */ + fun openCollectionBox() { + if (!player!!.bankPinManager.isUnlocked) { + player.bankPinManager.openType(3) + return + } + player.interfaceManager.openComponent(Components.STOCKCOLLECT_109) + player.packetDispatch.sendIfaceSettings(6, 18, 109, 0, 2) + player.packetDispatch.sendIfaceSettings(6, 23, 109, 0, 2) + player.packetDispatch.sendIfaceSettings(6, 28, 109, 0, 2) + player.packetDispatch.sendIfaceSettings(6, 36, 109, 0, 2) + player.packetDispatch.sendIfaceSettings(6, 44, 109, 0, 2) + player.packetDispatch.sendIfaceSettings(6, 52, 109, 0, 2) + + visualizeRecords() + } + + fun visualizeRecords() + { + GEDB.run { conn -> + val stmt = conn.createStatement() + + for (record in offerRecords) { + if (record != null) { + val offer_raw = stmt.executeQuery("select * from player_offers where uid = ${record.uid}") + if (offer_raw.next()) { + val offer = GrandExchangeOffer.fromQuery(offer_raw) + if (offer.offerState == OfferState.REMOVED) continue + offer.index = record.slot + offer.visualize(player) + } + } + } + stmt.close() + } + } + + fun getOffer(index: Int) : GrandExchangeOffer? + { + if(index == -1) return getOffer(null) + return getOffer(offerRecords[index]) + } + + fun getOffer(record: OfferRecord?) : GrandExchangeOffer? + { + record ?: return null + var offerToReturn: GrandExchangeOffer? = null + GEDB.run { conn -> + val stmt = conn.createStatement() + val offer_raw = stmt.executeQuery("select * from player_offers where uid = ${record.uid}") + if (offer_raw.next()) { + val offer = GrandExchangeOffer.fromQuery(offer_raw) + offer.index = record.slot + stmt.close() + offerToReturn = offer + } + stmt.close() + } + return offerToReturn + } + + /** + * Opens the history log. + * + * @param p The player to open it for. + */ + fun openHistoryLog(p: Player) { + p.interfaceManager.open(Component(643)) + for (i in history.indices) { + val o: GrandExchangeOffer? = history[i] + if (o == null) { + for (j in 0..3) { + p.packetDispatch.sendString("-", 643, 25 + i + j * 5) + } + continue + } + p.packetDispatch.sendString(if (o.sell) "You sold" else "You bought", 643, 25 + i) + p.packetDispatch.sendString( + NumberFormat.getNumberInstance(Locale.US).format(o.completedAmount.toLong()), + 643, + 30 + i + ) + p.packetDispatch.sendString(ItemDefinition.forId(o.itemID).name, 643, 35 + i) + p.packetDispatch.sendString( + NumberFormat.getNumberInstance(Locale.US).format(o.totalCoinExchange.toLong()) + " gp", 643, 40 + i + ) + } + } + + /** + * Initializes the grand exchange. + */ + fun init() { + // Were trades made while gone? + var updated = false + for (record in offerRecords) { + if (record != null) { + val offer = getOffer(record) ?: continue + if (!updated && (offer.withdraw[0] != null || offer.withdraw[1] != null)) { + updated = true + } + offer.visualize(player) + } + } + if (updated) { + sendMessage(player!!, "You have items waiting in your Grand Exchange collection box!") + playJingle(player, 284) + } + } + + fun hasActiveOffer(): Boolean { + for (i in offerRecords) { + if (i != null) + return true + } + return false + } + + /** + * Formats the grand exchange. + * + * @return the formatted offer for the SQL database. + */ + fun format(): String? { + var log = "" + for (record in offerRecords) { + if (record != null) { + val offer = getOffer(record) ?: continue + log += offer.itemID.toString() + "," + offer.amount + "," + offer.sell + "|" + } + } + if (log.isNotEmpty() && log[log.length - 1] == '|') { + log = log.substring(0, log.length - 1) + } + return log + } + + data class OfferRecord(val uid: Long, val slot: Int) + + companion object { + @JvmStatic fun getInstance(player: Player? = null): GrandExchangeRecords + { + return player?.getAttribute("ge-records", GrandExchangeRecords()) ?: GrandExchangeRecords() + } + } +} diff --git a/Server/src/main/core/game/ge/OfferState.java b/Server/src/main/core/game/ge/OfferState.java new file mode 100644 index 0000000..745f870 --- /dev/null +++ b/Server/src/main/core/game/ge/OfferState.java @@ -0,0 +1,43 @@ +package core.game.ge; + +/** + * Represents the state of a Grand Exchange offer. + * @author Emperor + */ +public enum OfferState { + + /** + * The player is still constructing the offer. + */ + PENDING, + + /** + * The player has confirmed the offer (the offer is being dispatched). + */ + REGISTERED, + + /** + * The offer has been aborted. + */ + ABORTED, + + /** + * The offer has been updated. + */ + UPDATED, + + /** + * The offer is completed. + */ + COMPLETED, + + /** + * The offer is outdated. + */ + OUTDATED, + + /** + * The offer has been removed. + */ + REMOVED; +} \ No newline at end of file diff --git a/Server/src/main/core/game/ge/PriceIndex.kt b/Server/src/main/core/game/ge/PriceIndex.kt new file mode 100644 index 0000000..5acf813 --- /dev/null +++ b/Server/src/main/core/game/ge/PriceIndex.kt @@ -0,0 +1,137 @@ +package core.game.ge + +import core.api.itemDefinition +import java.sql.ResultSet + +object PriceIndex { + @JvmStatic fun canTrade(id: Int): Boolean { + var canTrade = false + + GEDB.run { conn -> + val stmt = conn.prepareStatement(EXISTS_QUERY) + stmt.setInt(1, id) + val res = stmt.executeQuery() + if (res.next()) { + canTrade = res.getInt(1) == 1 + } + } + + return canTrade + } + + fun banItem(id: Int) { + GEDB.run { conn -> + val stmt = conn.prepareStatement(REMOVE_QUERY) + stmt.setInt(1, id) + stmt.execute() + } + } + + fun allowItem(id: Int) { + if(canTrade(id)) return + + GEDB.run { conn -> + val stmt = conn.prepareStatement(INSERT_QUERY) + stmt.setInt(1, id) + stmt.setInt(2, itemDefinition(id).getAlchemyValue(true)) + stmt.setInt(3, itemDefinition(id).getAlchemyValue(true)) + stmt.setInt(4, 0) + stmt.setInt(5, 0) + stmt.execute() + } + } + + fun getValue(id: Int): Int { + var value = itemDefinition(id).getAlchemyValue(true) + GEDB.run { conn -> + val stmt = conn.prepareStatement(GET_VALUE_QUERY) + stmt.setInt(1, id) + val res = stmt.executeQuery() + if (res.next()) { + value = res.getInt(1) + } + } + return value + } + + fun addTrade(id: Int, amount: Int, pricePerUnit: Int) { + val oldInfo = getInfo(id) ?: return + val newInfo = oldInfo.copy() + + val volumeResetThreshold = + if (pricePerUnit >= 1000000) 500 + else if (pricePerUnit >= 100000) 1000 + else if (pricePerUnit >= 25000) 2500 + else 10000 + + newInfo.totalValue += (amount * pricePerUnit) + newInfo.uniqueTrades += amount + newInfo.lastUpdate = System.currentTimeMillis() + newInfo.currentValue = (newInfo.totalValue / newInfo.uniqueTrades).toInt() + + if (newInfo.uniqueTrades > volumeResetThreshold) { + val newAmt = (0.1 * volumeResetThreshold).toInt() + newInfo.uniqueTrades = newAmt + newInfo.totalValue = newAmt.toLong() * newInfo.currentValue + } + + updateInfo(newInfo) + } + + private fun updateInfo(newInfo: PriceInfo) { + GEDB.run { conn -> + val stmt = conn.prepareStatement(UPDATE_QUERY) + stmt.setInt(1, newInfo.currentValue) + stmt.setLong(2, newInfo.totalValue) + stmt.setInt(3, newInfo.uniqueTrades) + stmt.setLong(4, newInfo.lastUpdate) + stmt.setInt(5, newInfo.itemId) + stmt.execute() + } + } + + private fun getInfo(id: Int): PriceInfo? { + var priceInfo: PriceInfo? = null + + GEDB.run { conn -> + val stmt = conn.prepareStatement(SELECT_QUERY) + stmt.setInt(1, id) + val res = stmt.executeQuery() + if (res.next()) { + priceInfo = PriceInfo.fromQuery(res) + } + } + + return priceInfo + } + + const val SELECT_QUERY = "SELECT * FROM price_index WHERE item_id = ?;" + const val UPDATE_QUERY = "UPDATE price_index SET value = ?, total_value = ?, unique_trades = ?, last_update = ? WHERE item_id = ?;" + const val EXISTS_QUERY = "SELECT EXISTS(SELECT 1 FROM price_index WHERE item_id = ?);" + const val REMOVE_QUERY = "DELETE FROM price_index WHERE item_id = ?;" + const val INSERT_QUERY = "INSERT INTO price_index (item_id, value, total_value, unique_trades, last_update) VALUES (?,?,?,?,?);" + const val GET_VALUE_QUERY = "SELECT value FROM price_index WHERE item_id = ?;" +} + +data class PriceInfo( + var itemId: Int, + var currentValue: Int, + var totalValue: Long, + var uniqueTrades: Int, + var lastUpdate: Long +) { + fun copy() : PriceInfo { + return PriceInfo(itemId, currentValue, totalValue, uniqueTrades, lastUpdate) + } + companion object { + fun fromQuery(result: ResultSet) : PriceInfo { + return PriceInfo( + result.getInt(1), + result.getInt(2), + result.getLong(3), + result.getInt(4), + result.getLong(5) + ) + } + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/global/Skillcape.java b/Server/src/main/core/game/global/Skillcape.java new file mode 100644 index 0000000..619b87f --- /dev/null +++ b/Server/src/main/core/game/global/Skillcape.java @@ -0,0 +1,113 @@ +package core.game.global; + +import core.game.container.Container; +import core.game.dialogue.FacialExpression; +import core.game.dialogue.FacialExpression; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +/** + * Represents a utility class for purchasing skillcapes. + * @author Vexia + */ +public final class Skillcape { + + /** + * Represents the amount needed to purchase a cape. + */ + private static final Item COINS = new Item(995, 99000); + + /** + * Represents the skillcapes to purchase. + */ + public static final int[] SKILLCAPES = { 9747, 9753, 9750, 9768, 9756, 9759, 9762, 9801, 9807, 9783, 9798, 9804, 9780, 9795, 9792, 9774, 9771, 9777, 9786, 9810, 9765, 9948, 9789, 12169 }; + + /** + * Method used to purchase a cape of accomplisment. + * @param player the player. + * @param skill the skill. + * @return {@code True} if purchased. + */ + public static boolean purchase(final Player player, final int skill) { + if (!isMaster(player, skill)) { + return false; + } + if (player.getInventory().freeSlots() < 2) { + player.getDialogueInterpreter().sendDialogues(player, FacialExpression.HALF_GUILTY, "Sorry, I don't seem to have inventory space."); + return false; + } + if (!player.getInventory().containsItem(COINS)) { + player.getDialogueInterpreter().sendDialogues(player, FacialExpression.HALF_GUILTY, "Sorry, I don't seem to have enough coins with", "me at this time."); + return false; + } + if (player.getInventory().remove(COINS)) { + return player.getInventory().add(getItems(player, skill)); + } else { + return false; + } + } + + /** + * Method used to trim the players skillcapes. + * @param player the player. + */ + public static void trim(final Player player) { + final Container[] containers = new Container[] { player.getInventory(), player.getEquipment(), player.getBank() }; + int skill = -1; + for (Container container : containers) { + for (Item item : container.toArray()) { + if (item == null || item.getId() < 9700) { + continue; + } + skill = getCapeIndex(item); + if (skill != -1) { + container.replace(new Item(getTrimmed(skill).getId(), item.getAmount()), item.getSlot()); + skill = -1; + } + } + } + } + + /** + * Checks if the player has the appropriate level. + * @param player the player. + * @param skill the skill. + * @return {@code True} if so. + */ + public static boolean isMaster(final Player player, final int skill) { + return player.getSkills().getStaticLevel(skill) == 99; + } + + /** + * Gets the items to purchase. + * @param player the player. + * @param skill the skill. + * @return {@code Items} to buy. + */ + public static Item[] getItems(final Player player, final int skill) { + return new Item[] { new Item(SKILLCAPES[skill] + (player.getSkills().getMasteredSkills() > 1 ? 1 : 0)), new Item(SKILLCAPES[skill] + 2) }; + } + + /** + * Gets the trimmed item. + * @param skill the skill. + * @return the trimmed cape. + */ + public static Item getTrimmed(final int skill) { + return new Item(SKILLCAPES[skill] + 1); + } + + /** + * Gets the cape index by the item. + * @param item the item. + * @return the skill index, if not (-1). + */ + public static int getCapeIndex(final Item item) { + for (int i = 0; i < SKILLCAPES.length; i++) { + if (SKILLCAPES[i] == item.getId()) { + return i; + } + } + return -1; + } +} diff --git a/Server/src/main/core/game/global/action/ClimbActionHandler.java b/Server/src/main/core/game/global/action/ClimbActionHandler.java new file mode 100644 index 0000000..1914c24 --- /dev/null +++ b/Server/src/main/core/game/global/action/ClimbActionHandler.java @@ -0,0 +1,355 @@ +package core.game.global.action; + +import core.game.dialogue.DialoguePlugin; +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; + +/** + * Handles a ladder climbing reward. + * @author Emperor + */ +public final class ClimbActionHandler { + + /** + * Represents the climb up animation of ladders. + */ + public static final Animation CLIMB_UP = new Animation(828); + + /** + * Represents the climb down animation of ladders. + */ + public static final Animation CLIMB_DOWN = new Animation(827); + + /** + * The climb dialogue. + */ + public static DialoguePlugin CLIMB_DIALOGUE = new ClimbDialogue(); + + /** + * Handles the climbing of a rope. + * + * @param player The player. + * @param object The rope object. + * @param option The option. + */ + public static void climbRope(Player player, Scenery object, String option) { + + } + + /** + * Handles the climbing of a trap door. + * + * @param player The player. + * @param object The trap door object. + * @param option The option. + */ + public static void climbTrapdoor(Player player, Scenery object, String option) { + + } + + /** + * Handles the climbing of a ladder. + * + * @param player The player. + * @param startLadder The scenery. + * @param option The option. + * @return True if successfully climbed + */ + public static boolean climbLadder(Player player, Scenery startLadder, String option) { + Scenery endLadder = null; + Animation animation = CLIMB_UP; + if (startLadder.getName().startsWith("Stair")) { + animation = null; + } + if (SpecialLadders.getDestination(startLadder.getLocation()) != null) { + Location destination = SpecialLadders.getDestination(startLadder.getLocation()); + climb(player, animation, destination); + if(SpecialLadders.getSpecialLadder(startLadder.getLocation()) != null) { + SpecialLadders.getSpecialLadder(startLadder.getLocation()).checkAchievement(player); + } + return true; + } + switch (option) { + case "climb-up": + case "walk-up": + endLadder = getLadder(startLadder, false); + break; + case "climb-down": + case "walk-down": + if (startLadder.getName().equals("Trapdoor")) { + animation = CLIMB_DOWN; + } + endLadder = getLadder(startLadder, true); + break; + case "climb": + Scenery upperLadder = getLadder(startLadder, false); + Scenery downLadder = getLadder(startLadder, true); + if (upperLadder == null && downLadder != null) { + return climbLadder(player, startLadder, "climb-down"); + } + if (upperLadder != null && downLadder == null) { + return climbLadder(player, startLadder, "climb-up"); + } + DialoguePlugin dialogue = CLIMB_DIALOGUE.newInstance(player); + if (dialogue != null && dialogue.open(startLadder)) { + player.getDialogueInterpreter().setDialogue(dialogue); + } + return false; + } + Location destination = endLadder != null ? getDestination(endLadder) : null; + if (endLadder == null || destination == null) { + player.getPacketDispatch().sendMessage("The ladder doesn't seem to lead anywhere."); + return false; + } + climb(player, animation, destination); + return true; + } + + /** + * Gets the teleport destination. + * + * @param object The object to teleport to. + * @return The teleport destination. + */ + public static Location getDestination(Scenery object) { + int sizeX = object.getDefinition().sizeX; + int sizeY = object.getDefinition().sizeY; + if (object.getRotation() % 2 != 0) { + int switcher = sizeX; + sizeX = sizeY; + sizeY = switcher; + } + Direction dir = Direction.forWalkFlag(object.getDefinition().getWalkingFlag(), object.getRotation()); + if (dir != null) { + return getDestination(object, sizeX, sizeY, dir, 0); + } + switch (object.getRotation()) { + case 0: + return getDestination(object, sizeX, sizeY, Direction.SOUTH, 0); + case 1: + return getDestination(object, sizeX, sizeY, Direction.EAST, 0); + case 2: + return getDestination(object, sizeX, sizeY, Direction.NORTH, 0); + case 3: + return getDestination(object, sizeX, sizeY, Direction.WEST, 0); + } + return null; + } + + /** + * Gets the destination for the given object. + * + * @param object The object. + * @param dir The preferred direction from the object. + * @return The teleporting destination. + */ + private static Location getDestination(Scenery object, int sizeX, int sizeY, Direction dir, int count) { + Location loc = object.getLocation(); + if (dir.toInteger() % 2 != 0) { + int x = dir.getStepX(); + if (x > 0) { + x *= sizeX; + } + for (int y = 0; y < sizeY; y++) { + Location l = loc.transform(x, y, 0); + if (RegionManager.isTeleportPermitted(l) && dir.canMove(l)) { + return l; + } + } + } else { + int y = dir.getStepY(); + if (y > 0) { + y *= sizeY; + } + for (int x = 0; x < sizeX; x++) { + Location l = loc.transform(x, y, 0); + if (RegionManager.isTeleportPermitted(l) && dir.canMove(l)) { + return l; + } + } + } + if (count == 3) { + return null; + } + return getDestination(object, sizeX, sizeY, Direction.get((dir.toInteger() + 1) % 4), count + 1); + } + + /** + * Executes the climbing reward. + * + * @param player The player. + * @param animation The climbing animation. + * @param destination The destination. + */ + public static void climb(final Player player, Animation animation, final Location destination, final String... messages) { + player.lock(2); + player.animate(animation); + GameWorld.getPulser().submit(new Pulse(1) { + @Override + public boolean pulse() { + player.getProperties().setTeleportLocation(destination); + for (String message : messages) { + player.getPacketDispatch().sendMessage(message); + } + return true; + } + }); + } + + /** + * Gets the ladder the object leads to. + * + * @param object The ladder object. + * @param down If the player is going down a floor. + * @return The ladder the current ladder object leads to. + */ + private static Scenery getLadder(Scenery object, boolean down) { + int mod = down ? -1 : 1; + Scenery ladder = RegionManager.getObject(object.getLocation().transform(0, 0, mod)); + if (ladder == null || !isLadder(ladder)) { + if (ladder != null && ladder.getName().equals(object.getName())) { + ladder = RegionManager.getObject(ladder.getLocation().transform(0, 0, mod)); + if (ladder != null) { + return ladder; + } + } + ladder = findLadder(object.getLocation().transform(0, 0, mod)); + if (ladder == null) { + ladder = RegionManager.getObject(object.getLocation().transform(0, mod * -6400, 0)); + if (ladder == null) { + ladder = findLadder(object.getLocation().transform(0, mod * -6400, 0)); + } + } + } + return ladder; + } + + /** + * Finds a ladder (by searching a 10x10 area around the given location). + * + * @param l The location. + * @return The ladder. + */ + private static Scenery findLadder(Location l) { + for (int x = -5; x < 6; x++) { + for (int y = -5; y < 6; y++) { + Scenery object = RegionManager.getObject(l.transform(x, y, 0)); + if (object != null && isLadder(object)) { + return object; + } + } + } + return null; + } + + /** + * Checks if the object is a ladder. + * + * @param object The object. + * @return {@code True} if so. + */ + private static boolean isLadder(Scenery object) { + for (String option : object.getDefinition().getOptions()) { + if (option != null && (option.contains("Climb"))) { + return true; + } + } + return object.getName().equals("Trapdoor"); + } + + /** + * Represents the dialogue plugin used for climbing stairs or a ladder. + * + * @author 'Vexia + * @version 1.0 + */ + static final class ClimbDialogue extends DialoguePlugin { + + /** + * Represents the climbing dialogue id. + */ + public static final int ID = 8 << 16; + + /** + * Constructs a new {@code ClimbDialogue} {@code Object}. + */ + public ClimbDialogue() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code ClimbDialogue} {@code Object}. + * + * @param player the player. + */ + public ClimbDialogue(final Player player) { + super(player); + } + + @Override + public DialoguePlugin newInstance(Player player) { + return new ClimbDialogue(player); + } + + /** + * Represents the object to use. + */ + private Scenery object; + + @Override + public boolean open(Object... args) { + object = (Scenery) args[0]; + interpreter.sendOptions("What would you like to do?", "Climb Up.", "Climb Down."); + stage = 0; + return true; + } + + @Override + public boolean handle(int interfaceId, int buttonId) { + switch (stage) { + case 0: + switch (buttonId) { + case 1: + player.lock(1); + GameWorld.getPulser().submit(new Pulse(1) { + @Override + public boolean pulse() { + climbLadder(player, object, "climb-up"); + return true; + } + }); + end(); + break; + case 2: + player.lock(1); + GameWorld.getPulser().submit(new Pulse(1) { + @Override + public boolean pulse() { + climbLadder(player, object, "climb-down"); + return true; + } + }); + end(); + break; + + } + break; + } + return true; + } + + @Override + public int[] getIds() { + return new int[]{ID}; + } + + } +} diff --git a/Server/src/main/core/game/global/action/DigAction.java b/Server/src/main/core/game/global/action/DigAction.java new file mode 100644 index 0000000..3c47ef6 --- /dev/null +++ b/Server/src/main/core/game/global/action/DigAction.java @@ -0,0 +1,17 @@ +package core.game.global.action; + +import core.game.node.entity.player.Player; + +/** + * Handles a digging reward. + * @author Emperor + */ +public interface DigAction { + + /** + * Runs the digging reward. + * @param player The player. + */ + void run(Player player); + +} \ No newline at end of file diff --git a/Server/src/main/core/game/global/action/DigSpadeHandler.java b/Server/src/main/core/game/global/action/DigSpadeHandler.java new file mode 100644 index 0000000..31735e4 --- /dev/null +++ b/Server/src/main/core/game/global/action/DigSpadeHandler.java @@ -0,0 +1,75 @@ +package core.game.global.action; + +import core.game.node.entity.player.Player; +import core.game.system.communication.CommunicationInfo; +import content.global.handlers.item.SpadeDigListener; +import core.tools.Log; +import core.tools.SystemLogger; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; + +import java.util.HashMap; +import java.util.Map; + +import static core.api.ContentAPIKt.log; + +/** + * Handles digging with a spade. + * @author Emperor + */ +public final class DigSpadeHandler { + + /** + * The digging actions. + */ + private static final Map ACTIONS = new HashMap<>(); + + /** + * The digging animation. + */ + public static final Animation ANIMATION = Animation.create(830); + + /** + * Handles a digging reward. + * @param player The player. + * @return {@code True} if the reward got handled. + */ + public static boolean dig(final Player player) { + final DigAction action = ACTIONS.get(player.getLocation()); + player.animate(ANIMATION); + player.lock(1); + + if(SpadeDigListener.runListener(player.getLocation(), player)){ + return true; + } + + if (action != null) { + GameWorld.getPulser().submit(new Pulse(1, player) { + @Override + public boolean pulse() { + action.run(player); + return true; + } + }); + return true; + } + return false; + } + + /** + * Registers a new digging reward. + * @param location The location to dig on. + * @param action The reward. + * @return {@code True} if the reward got registered. + */ + public static boolean register(Location location, DigAction action) { + if (ACTIONS.containsKey(location)) { + log(CommunicationInfo.class, Log.ERR, "Already contained dig reward for location " + location + "."); + return false; + } + ACTIONS.put(location, action); + return true; + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/global/action/DoorActionHandler.java b/Server/src/main/core/game/global/action/DoorActionHandler.java new file mode 100644 index 0000000..02234e1 --- /dev/null +++ b/Server/src/main/core/game/global/action/DoorActionHandler.java @@ -0,0 +1,549 @@ +package core.game.global.action; + +import content.data.Quests; +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.scenery.Constructed; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.game.system.task.Pulse; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.map.path.Pathfinder; +import kotlin.Unit; +import core.game.system.config.DoorConfigLoader; +import core.game.world.GameWorld; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.hasRequirement; +import static core.api.ContentAPIKt.playAudio; + +import java.awt.*; + +/** + * Handles door actions. + * + * @author Emperor + */ +public final class DoorActionHandler { + + /** + * The charge indicating the door is already in use. + */ + private static final int IN_USE_CHARGE = 88; + + /** + * Handles a door reward. + * + * @param player The player. + * @param object The object. + */ + public static void handleDoor(final Player player, final Scenery object) { + final Scenery second = (object.getId() == 1530 || object.getId() == 1531) ? null : getSecondDoor(object, player); + Scenery o = null; + if (object instanceof Constructed && (o = ((Constructed) object).getReplaced()) != null) { + DoorConfigLoader.Door d = DoorConfigLoader.Companion.forId(object.getId()); + if (d != null && d.isMetal()) { + playAudio(player, Sounds.IRON_DOOR_CLOSE_70); + } else if (d != null && d.isFence()){ + playAudio(player, Sounds.GATE_CLOSE_66); + } else { + playAudio(player, 60); + } + SceneryBuilder.replace(object, o); + if (second instanceof Constructed && (o = ((Constructed) second).getReplaced()) != null) { + SceneryBuilder.replace(second, o); + return; + } + return; + } + if (object.getDefinition().hasAction("close")) { + if (second != null) { + player.getPacketDispatch().sendMessage("The doors appear to be stuck."); + playAudio(player, Sounds.DOOR_CREAK_61); + return; + } + DoorConfigLoader.Door d = DoorConfigLoader.Companion.forId(object.getId()); + if (d != null && d.isMetal()) { + playAudio(player, Sounds.IRON_DOOR_OPEN_71); + } else if (d != null && d.isFence()){ + playAudio(player, Sounds.GATE_OPEN_67); + } else { + playAudio(player, Sounds.DOOR_OPEN_62); + } + if (d == null) { + player.getPacketDispatch().sendMessage("The door appears to be stuck."); + playAudio(player, Sounds.DOOR_CREAK_61); + return; + } + int firstDir = (object.getRotation() + 3) % 4; + Point p = getCloseRotation(object); + Location firstLoc = object.getLocation().transform((int) p.getX(), (int) p.getY(), 0); + SceneryBuilder.replace(object, object.transform(d.getReplaceId(), firstDir, firstLoc)); + return; + } + DoorConfigLoader.Door d = DoorConfigLoader.Companion.forId(object.getId()); + if (d == null || d.isAutoWalk()) { + handleAutowalkDoor(player, object); + return; + } + if (d.isMetal()) { + playAudio(player, Sounds.IRON_DOOR_OPEN_71); + } else if (d.isFence()){ + playAudio(player, Sounds.GATE_OPEN_67); + } else { + playAudio(player, Sounds.DOOR_OPEN_62); + } + if (second != null) { + DoorConfigLoader.Door s = DoorConfigLoader.Companion.forId(second.getId()); + open(object, second, d.getReplaceId(), s == null ? second.getId() : s.getReplaceId(), true, 500, d.isFence()); + return; + } + open(object, null, d.getReplaceId(), -1, true, 500, d.isFence()); + } + + /** + * Handles the opening and walking through a door. + * + * @param entity The entity walking through the door. + * @param object The door object. + * @return + */ + public static boolean handleAutowalkDoor(final Entity entity, final Scenery object, final Location endLocation) { + if (object.getCharge() == IN_USE_CHARGE) { + return false; + } + // TODO: Maybe have this passed in as an optional parameter or overload handleAutowalkDoor? + boolean ignoreSecondDoor = (object.getId() == 3628 || object.getId() == 3629 || object.getId() == 3630 || object.getId() == 3631|| object.getId() == 3632); // Ignore second door for Maze Random + final Scenery second = (object.getId() == 3 || ignoreSecondDoor) ? null : getSecondDoor(object, entity); + entity.lock(4); + final Location loc = entity.getLocation(); + if (entity instanceof Player) { + DoorConfigLoader.Door d = DoorConfigLoader.Companion.forId(object.getId()); + if (d != null && d.isMetal()) { + playAudio(entity.asPlayer(), Sounds.IRON_DOOR_OPEN_71); + playAudio(entity.asPlayer(), Sounds.IRON_DOOR_CLOSE_70, 60); + } else if (d != null && d.isFence()){ + playAudio(entity.asPlayer(), Sounds.GATE_OPEN_67); + playAudio(entity.asPlayer(), Sounds.GATE_CLOSE_66, 60); + } else { + playAudio(entity.asPlayer(), Sounds.DOOR_OPEN_62); + playAudio(entity.asPlayer(), 60, 60); + } + entity.asPlayer().logoutListeners.put("autowalk", player -> { + player.setLocation(loc); + return Unit.INSTANCE; + }); + } + GameWorld.getPulser().submit(new Pulse(1) { + boolean opened = false; + @Override + public boolean pulse() { + if (!opened) { + open(object, second, object.getId(), second == null ? -1 : second.getId(), false, 2, false); + entity.getWalkingQueue().reset(); + entity.getWalkingQueue().addPath(endLocation.getX(), endLocation.getY()); + opened = true; + + // Set the door in_use + object.setCharge(IN_USE_CHARGE); + if (second != null) { + second.setCharge(IN_USE_CHARGE); + } + return false; + } + if (entity instanceof Player) { + Player player = entity.asPlayer(); + if (object.getId() == 2112 && player.getLocation().withinDistance(new Location(3046, 9756, 0), 10)) { + player.getAchievementDiaryManager().finishTask(player, DiaryType.FALADOR, 2, 6); + } + + // pass the al kharid gate + if (object.getId() == 35549 || object.getId() == 35551 && player.getViewport().getRegion().getId() == 13106) { + player.getAchievementDiaryManager().finishTask(player, DiaryType.LUMBRIDGE, 0, 4); + } + + // Search the shed in Lumbridge Swamp + if (object.getId() == 2406 && player.getLocation().withinDistance(Location.create(3202,3169,0))) { + player.getAchievementDiaryManager().finishTask(player, DiaryType.LUMBRIDGE, 1, 6); + } + + entity.asPlayer().logoutListeners.remove("autowalk"); + } + + // Reset door to inactive + object.setCharge(1000); + if (second != null) { + second.setCharge(1000); + } + return true; + } + }); + return true; + } + + /** + * Method wrapper for handling the auto walk door. + * + * @param entity the entity. + * @param object the object. + */ + public static boolean handleAutowalkDoor(final Entity entity, final Scenery object) { + return handleAutowalkDoor(entity, object, getEndLocation(entity, object)); + } + + /** + * Gets the end location to walk to. + * + * @param entity the entity. + * @param object the object. + * @return the end location. + */ + public static Location getEndLocation(Entity entity, Scenery object){ + return getEndLocation(entity,object,false); + } + public static Location getEndLocation(Entity entity, Scenery object, Boolean isAutoWalk) { + Location l = object.getLocation(); + switch (object.getRotation()) { + case 0: + if (entity.getLocation().getX() >= l.getX()) { + l = l.transform(-1, 0, 0); + } + break; + case 1: + if (entity.getLocation().getY() <= l.getY()) { + l = l.transform(0, 1, 0); + } + break; + case 2: + if (entity.getLocation().getX() <= l.getX()) { + l = l.transform(1, 0, 0); + } + break; + default: + if (entity.getLocation().getY() >= l.getY()) { + l = l.transform(0, -1, 0); + } + break; + } + return l; + } + + /** + * Gets the destination for the door. + * + * @param door The door. + * @return The destination location. + */ + public static Location getDestination(Entity entity, Scenery door) { + Location l = door.getLocation(); + int rotation = door.getRotation(); + if (door instanceof Constructed && door.getDefinition().hasAction("close")) { + Scenery o = ((Constructed) door).getReplaced(); + if (o != null) { + l = o.getLocation(); + rotation = o.getRotation(); + } + } + if (door.getType() == 9) { // Diagonal doors + switch (rotation) { + case 0: + case 2: + if (entity.getLocation().getY() < l.getY() || entity.getLocation().getX() < l.getX()) { + return l.transform(0, -1, 0); + } + return l.transform(0, 1, 0); + case 1: + case 3: + if (entity.getLocation().getX() > l.getX() || entity.getLocation().getY() > l.getY()) { + return l.transform(1, 0, 0); + } + return l.transform(-1, 0, 0); + } + } + switch (rotation) { + case 0: + if (entity.getLocation().getX() < l.getX()) { + if(Pathfinder.find(entity,l.transform(-1,0,0)).isMoveNear()){ + return l.transform(0,0,0); + } + return l.transform(-1, 0, 0); + } + break; + case 1: + if (entity.getLocation().getY() > l.getY()) { + if(Pathfinder.find(entity,l.transform(0,1,0)).isMoveNear()){ + return l.transform(0,0,0); + } + return l.transform(0, 1, 0); + } + break; + case 2: + if (entity.getLocation().getX() > l.getX()) { + if(Pathfinder.find(entity,l.transform(1,0,0)).isMoveNear()){ + return l.transform(0,0,0); + } + return l.transform(1, 0, 0); + } + break; + case 3: + if (entity.getLocation().getY() < l.getY()) { + if(Pathfinder.find(entity,l.transform(0,-1,0)).isMoveNear()){ + return l.transform(0,0,0); + } + return l.transform(0, -1, 0); + } + break; + } + return l; + } + + /** + * Opens the doors. + * + * @param object The door object. + * @param second The second door object. + * @param replaceId The replace id. + * @param secondReplaceId The second replace id. + * @param clip If clipping should be changed due to opening the door. + * @param restoreTicks The amount of ticks before the door(s) should be + * closed again. + */ + public static void open(Scenery object, Scenery second, int replaceId, int secondReplaceId, boolean clip, int restoreTicks, boolean fence) { + object = object.getWrapper(); + int mod = object.getType() == 9 ? -1 : 1; + int firstDir = (object.getRotation() + ((mod + 4) % 4)) % 4; + Point p = getRotationPoint(object.getRotation()); + Location firstLoc = object.getLocation().transform((int) p.getX() * mod, (int) p.getY() * mod, 0); + if (second == null) { + if (replaceId == 4577) { + replaceId = 4578; + firstDir = 3; + firstLoc = firstLoc.transform(0, 1, 0); + } + SceneryBuilder.replace(object, object.transform(replaceId, firstDir, firstLoc), restoreTicks, clip); + return; + } + second = second.getWrapper(); + if (fence) { + openFence(object, second, replaceId, secondReplaceId, clip, restoreTicks); + return; + } + Direction offset = Direction.getDirection(second.getLocation().getX() - object.getLocation().getX(), second.getLocation().getY() - object.getLocation().getY()); + int secondDir = (second.getRotation() + mod) % 4; + if (firstDir == 1 && offset == Direction.NORTH) { + firstDir = 3; + } else if (firstDir == 2 && offset == Direction.EAST) { + firstDir = 0; + } else if (firstDir == 3 && offset == Direction.SOUTH) { + firstDir = 1; + } else if (firstDir == 0 && offset == Direction.WEST) { + firstDir = 2; + } + if (firstDir == secondDir) { + secondDir = (secondDir + 2) % 4; + } + Location secondLoc = second.getLocation().transform((int) p.getX(), (int) p.getY(), 0); + SceneryBuilder.replace(object, object.transform(replaceId, firstDir, firstLoc), restoreTicks, clip); + SceneryBuilder.replace(second, second.transform(secondReplaceId, secondDir, secondLoc), restoreTicks, clip); + } + + /** + * Handles the opening of a fence. + * + * @param object The fence object. + * @param second The second fence object. + * @param replaceId The replace id. + * @param secondReplaceId The second replace id. + * @param clip If clipping should be changed due to opening the door. + * @param restoreTicks The amount of ticks before the door(s) should be + * closed again. + */ + private static void openFence(Scenery object, Scenery second, int replaceId, int secondReplaceId, boolean clip, int restoreTicks) { + Direction offset = Direction.getDirection(second.getLocation().getX() - object.getLocation().getX(), second.getLocation().getY() - object.getLocation().getY()); + int firstDir = (object.getRotation() + 3) % 4; + Point p = getRotationPoint(object.getRotation()); + Location firstLoc = null; + int secondDir = (second.getRotation() + 3) % 4; + if (offset == Direction.WEST || offset == Direction.SOUTH) { + firstLoc = second.getLocation().transform((int) p.getX(), (int) p.getY(), 0); + int s = replaceId; + replaceId = secondReplaceId; + secondReplaceId = s; + } else { + firstLoc = object.getLocation().transform((int) p.getX(), (int) p.getY(), 0); + } + if (object.getRotation() == 3 || object.getRotation() == 2) { + firstDir = (firstDir + 2) % 4; + secondDir = (secondDir + 2) % 4; + } + Location secondLoc = firstLoc.transform((int) p.getX(), (int) p.getY(), 0); + if ((object.getId() == 36917 || object.getId() == 36919)) { + switch (object.getDirection()) { + case SOUTH: + SceneryBuilder.replace(object, object.transform(36919, firstDir, firstLoc), restoreTicks, true); + SceneryBuilder.replace(second, second.transform(36917, secondDir, secondLoc), restoreTicks, true); + break; + case EAST: + SceneryBuilder.replace(object, object.transform(36917, firstDir, firstLoc), restoreTicks, true); + SceneryBuilder.replace(second, second.transform(36919, secondDir, secondLoc), restoreTicks, true); + break; + default: + SceneryBuilder.replace(object, object.transform(36919, firstDir, firstLoc), restoreTicks, true); + SceneryBuilder.replace(second, second.transform(36917, secondDir, secondLoc), restoreTicks, true); + break; + } + } else { + SceneryBuilder.replace(object, object.transform(replaceId, firstDir, firstLoc), restoreTicks, clip); + SceneryBuilder.replace(second, second.transform(secondReplaceId, secondDir, secondLoc), restoreTicks, clip); + } + } + + /** + * Handles the opening of a fence. + * + * @param object The fence object. + * @param replaceId The replace id. + * @param secondReplaceId The second replace id. + * closed again. + */ + public static boolean autowalkFence(final Entity entity, final Scenery object, final int replaceId, final int secondReplaceId) { + final Scenery second = getSecondDoor(object, entity); + if (object.getCharge() == IN_USE_CHARGE || second == null) { + return false; + } + entity.lock(4); + final Location loc = entity.getLocation(); + if(entity instanceof Player) + { + entity.asPlayer().logoutListeners.put("autowalk", player -> { + player.setLocation(loc); + return Unit.INSTANCE; + }); + } + object.setCharge(IN_USE_CHARGE); + second.setCharge(IN_USE_CHARGE); + GameWorld.getPulser().submit(new Pulse(1) { + boolean opened = false; + + @Override + public boolean pulse() { + if (!opened) { + openFence(object, second, replaceId, secondReplaceId, false, 2); + Location l = getEndLocation(entity, object); + entity.getWalkingQueue().reset(); + entity.getWalkingQueue().addPath(l.getX(), l.getY()); + opened = true; + return false; + } + if(entity instanceof Player) + { + entity.asPlayer().logoutListeners.remove("autowalk"); + } + object.setCharge(1000); + if (second != null) { + second.setCharge(1000); + } + return true; + } + }); + return true; + } + + /** + * Gets the closing rotation point. + * + * @param object The object. + * @return The point. + */ + private static Point getCloseRotation(Scenery object) { + switch (object.getRotation()) { + case 0: + return new Point(0, 1); + case 1: + return new Point(1, 0); + case 2: + return new Point(0, -1); + case 3: + return new Point(-1, 0); + } + return new Point(0, 0); + } + + /** + * Gets the rotation point for the object. + * + * @return The rotation point. + */ + public static Point getRotationPoint(int rotation) { + switch (rotation) { + case 0: + return new Point(-1, 0); + case 1: + return new Point(0, 1); + case 2: + return new Point(1, 0); + case 3: + return new Point(0, -1); + } + return null; + } + + /** + * Gets the door next to this door. + * + * @param object The door. + * @return The second door, if any, {@code null} if no second door existed. + */ + public static Scenery getSecondDoor(Scenery object, Entity entity) { + Location l = object.getLocation(); + Player player = entity instanceof Player ? (Player) entity : null; + Scenery o = null; + if ((o = RegionManager.getObject(l.transform(-1, 0, 0))) != null && o.getName().equals(object.getName())) { + return o; + } + if ((o = RegionManager.getObject(l.transform(1, 0, 0))) != null && o.getName().equals(object.getName())) { + return o; + } + if ((o = RegionManager.getObject(l.transform(0, -1, 0))) != null && o.getName().equals(object.getName())) { + return o; + } + if ((o = RegionManager.getObject(l.transform(0, 1, 0))) != null && o.getName().equals(object.getName())) { + return o; + } + return null; + } + + /** + * Gets the rotations to set the opened doors to. + * + * @param object The first door. + * @param second The second door. + * @param rp The rotation point. + * @return An int-array, with index 0 being first door rotation and index 1 + * being second door rotation. + */ + public static int[] getRotation(Scenery object, Scenery second, Point rp) { + if (second == null) { + return new int[]{(object.getRotation() + 1) % 4}; + } + int[] rotations = new int[]{3, 1}; + Location fl = object.getLocation(); + Location sl = second.getLocation(); + if (fl.getX() > sl.getX()) { + rotations = new int[]{2, 0}; + } + if (fl.getX() < sl.getX()) { + rotations = new int[]{0, 2}; + } + if (fl.getY() > sl.getY()) { + rotations = new int[]{1, 3}; + } + if (rp.getY() > 0 || rp.getX() > 0) { + rotations = new int[]{rotations[1], rotations[0]}; + } + return rotations; + } +} diff --git a/Server/src/main/core/game/global/action/DropListener.kt b/Server/src/main/core/game/global/action/DropListener.kt new file mode 100644 index 0000000..254b582 --- /dev/null +++ b/Server/src/main/core/game/global/action/DropListener.kt @@ -0,0 +1,83 @@ +package core.game.global.action + +import core.api.* +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength +import core.game.node.Node +import core.game.node.entity.combat.graves.GraveController +import core.game.node.entity.player.Player +import core.game.node.entity.player.info.login.PlayerParser +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import core.game.system.config.ItemConfigParser +import content.global.skill.summoning.pet.Pets +import core.game.node.entity.player.info.LogType +import core.game.node.entity.player.info.PlayerMonitor +import org.rs09.consts.Items +import org.rs09.consts.Sounds + +/** + * Represents the item drop/destroy/dissolve handler. + * @author Ceikry, ovenbreado + */ +class DropListener : InteractionListener { + override fun defineListeners() { + on(IntType.ITEM, "drop", "destroy", "dissolve", handler = ::handleDropAction) + } + + companion object { + private val DROP_COINS_SOUND = Sounds.EYEGLO_COIN_10 + private val DROP_ITEM_SOUND = Sounds.PUT_DOWN_2739 + private val DESTROY_ITEM_SOUND = Sounds.DESTROY_OBJECT_2381 + @JvmStatic fun drop(player: Player, item: Item) : Boolean { + return handleDropAction(player, item) + } + private fun handleDropAction(player: Player, node: Node) : Boolean { + val option = getUsedOption(player) + val item = node as? Item ?: return false + if (option == "drop") { + if (Pets.forId(item.id) != null) { + player.familiarManager.summon(item, true, true) + return true + } + if (GraveController.hasGraveAt(player.location)) { + sendMessage(player, "You cannot drop items on top of graves!") + return false + } + if (player.locks.equipmentLock != null) { + return false + } + + closeAllInterfaces(player) + queueScript(player, strength = QueueStrength.SOFT) { //do this as a script to allow dropping multiple items in the same tick (authentic) + // It's possible for state to change between queueing the script and executing it at the end of the tick (https://forum.2009scape.org/viewtopic.php?f=8&t=1195-lost-bandos-chestplate-whilst-making-iron-titans&p=5292). So, sanity check: + val current = player.inventory.get(item.slot) + if (current == null || current !== item) { + return@queueScript stopExecuting(player) + } + if (player.inventory.replace(null, item.slot) !== item) { + PlayerMonitor.log(player, LogType.DUPE_ALERT, "Potential exploit attempt when player ${player.name} tried to drop ${item.amount}x ${item.id}. The item has been lost and will need to be refunded to the player, but how did they get this to happen?") + return@queueScript stopExecuting(player) + } + val droppedItem = item.dropItem + if (droppedItem.id == Items.COINS_995) playAudio(player, DROP_COINS_SOUND) else playAudio(player, DROP_ITEM_SOUND) + GroundItemManager.create(droppedItem, player.location, player) + setAttribute(player, "droppedItem:${droppedItem.id}", getWorldTicks() + 2) + PlayerParser.save(player) + return@queueScript stopExecuting(player) + } + } else if (option == "destroy" || option == "dissolve" || item.definition.handlers.getOrDefault(ItemConfigParser.DESTROY, false) as Boolean) { + player.dialogueInterpreter.sendDestroyItem(item.id, item.name) + addDialogueAction(player) { player, button -> + if (button == 3) { + if (removeItem(player, item)) { + playAudio(player, DESTROY_ITEM_SOUND) + } + } + } + } + return true + } + } +} diff --git a/Server/src/main/core/game/global/action/EquipHandler.kt b/Server/src/main/core/game/global/action/EquipHandler.kt new file mode 100644 index 0000000..29299e2 --- /dev/null +++ b/Server/src/main/core/game/global/action/EquipHandler.kt @@ -0,0 +1,149 @@ +package core.game.global.action + +import core.game.event.ItemEquipEvent +import core.game.event.ItemUnequipEvent +import core.game.container.impl.EquipmentContainer +import content.global.handlers.item.equipment.brawling_gloves.BrawlingGlovesManager +import content.global.skill.slayer.SlayerEquipmentFlags +import core.api.playAudio +import core.game.node.Node +import core.game.node.entity.combat.equipment.WeaponInterface +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.audio.Audio +import core.plugin.Plugin +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.game.interaction.InteractionListeners +import core.game.system.config.ItemConfigParser +import org.rs09.consts.Sounds + +/** + * Represents the equipment equipping handler plugin. + * @author Ceikry + * @author Woah + */ +class EquipHandler : InteractionListener { + + override fun defineListeners() { + on(IntType.ITEM, "equip", "wield", "wear") { player, node -> + handleEquip(player, node) + return@on true + } + } + + fun handleEquip(player: Player, node: Node) { + val item = node.asItem() + val itemEquipmentSlot = item.definition.getConfiguration(ItemConfigParser.EQUIP_SLOT, -1) + + val currentEquippedItem = player.equipment[itemEquipmentSlot] + if (item == null || currentEquippedItem == item || item.name.toLowerCase().contains("goblin mail")) { + return + } + + if(currentEquippedItem != null){ + if(!InteractionListeners.run(currentEquippedItem.id, player, currentEquippedItem, false)){ + return + } + } + + val equipStateListener = item.definition.getConfiguration>("equipment", null) + if (equipStateListener != null) { + val bool = equipStateListener.fireEvent("equip", player, item) + if (bool != true) { + return + } + } + if (!InteractionListeners.run(node.id, player, item, true)) { + return + } + + val lock = player.locks.equipmentLock + if (lock != null && lock.isLocked) { + if (lock.message != null) { + player.packetDispatch.sendMessage(lock.message) + } + return + } + + if (player.equipment.add(item, item.slot, true, true)) { + //check if a brawling glove is being equipped and register it + if (item.id in 13845..13857) { + player.debug("Registering gloves... ID: " + item.id) + BrawlingGlovesManager.getInstance(player).registerGlove(item.id) + } + + player.dialogueInterpreter.close() + + /* TODO: Send different equip sound based on what is being equip.*/ + playAudio(player, item.definition.getConfiguration(ItemConfigParser.EQUIP_AUDIO, 2244)) + + if (player.properties.autocastSpell != null) { + + if (itemEquipmentSlot == EquipmentContainer.SLOT_WEAPON) { + player.properties.autocastSpell = null + val wif = player.getExtension(WeaponInterface::class.java) + wif.selectAutoSpell(-1, true) + wif.openAutocastSelect() + } + } + + if (SlayerEquipmentFlags.isSlayerEq(item.id)) { + SlayerEquipmentFlags.updateFlags(player) + } + + player.dispatch(ItemEquipEvent(item.id, item.slot)) + } + } + + companion object { + /** + * Unequips an item. + * @param player the player. + * @param slot the slot. + * @param itemId the item id. + */ + @JvmStatic + fun unequip(player: Player, slot: Int, itemId: Int) { + if (slot < 0 || slot > 13) { + return + } + val item = player.equipment[slot] ?: return + val lock = player.locks.equipmentLock + if (lock != null && lock.isLocked) { + if (lock.message != null) { + player.packetDispatch.sendMessage(lock.message) + } + return + } + if (slot == EquipmentContainer.SLOT_WEAPON) { + player.packetDispatch.sendString("", 92, 0) + } + val maximumAdd = player.inventory.getMaximumAdd(item) + if (maximumAdd < item.amount) { + player.packetDispatch.sendMessage("Not enough free space in your inventory.") + return + } + val plugin = item.definition.getConfiguration>("equipment", null) + if (plugin != null) { + if (!(plugin.fireEvent("unequip", player, item) as Boolean)) { + return + } + } + if (!InteractionListeners.run(itemId, player, item, false)) { + return + } + if (player.equipment.remove(item)) { + /* TODO: Send different unequip sound based on what is being unequipped.*/ + playAudio(player, Sounds.EQUIP_FUN_2238) + player.dialogueInterpreter.close() + player.inventory.add(item) + + player.dispatch(ItemUnequipEvent(itemId, slot)) + } + + if (SlayerEquipmentFlags.isSlayerEq(item.id)) { + SlayerEquipmentFlags.updateFlags(player) + } + } + } +} diff --git a/Server/src/main/core/game/global/action/LadderAchievementCheck.java b/Server/src/main/core/game/global/action/LadderAchievementCheck.java new file mode 100644 index 0000000..9f8e6b5 --- /dev/null +++ b/Server/src/main/core/game/global/action/LadderAchievementCheck.java @@ -0,0 +1,9 @@ +package core.game.global.action; + +import core.game.node.entity.player.Player; + +interface LadderAchievementCheck { + default void checkAchievement(Player player) { + return; + } +} diff --git a/Server/src/main/core/game/global/action/PickupHandler.kt b/Server/src/main/core/game/global/action/PickupHandler.kt new file mode 100644 index 0000000..ec42b18 --- /dev/null +++ b/Server/src/main/core/game/global/action/PickupHandler.kt @@ -0,0 +1,107 @@ +package core.game.global.action + +import core.game.event.PickUpEvent +import core.api.getItemName +import content.data.GodType +import core.game.node.entity.player.Player +import content.global.skill.runecrafting.RunePouch +import core.api.playAudio +import core.game.node.entity.player.info.LogType +import core.game.node.item.GroundItem +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import core.game.world.map.RegionManager +import core.game.world.update.flag.context.Animation +import core.game.node.entity.player.info.PlayerMonitor +import core.game.system.config.GroundSpawnLoader +import core.game.world.GameWorld +import org.rs09.consts.Sounds + +/** + * A class used to handle the picking up of ground items. + * @author 'Vexia + */ +object PickupHandler { + /** + * Method used to take a ground item. + * @param player the player. + * @param item the item. + * @return `True` if taken. + */ + @JvmStatic + fun take(player: Player, item: GroundItem): Boolean { + if (item.location == null) { + player.packetDispatch.sendMessage("Invalid ground item!") + return true + } + if (!GroundItemManager.getItems().contains(item)) { + player.packetDispatch.sendMessage("Too late!") + return true + } + if (player.getAttribute("droppedItem:" + item.id, 0) > GameWorld.ticks) { //Splinter + return true + } + if (item !is GroundSpawnLoader.GroundSpawn && item.isRemainPrivate && !item.droppedBy(player)) { + player.sendMessage("You can't take that item!") + return true + } + val add = Item(item.id, item.amount, item.charge) + if (!player.inventory.hasSpaceFor(add)) { + player.packetDispatch.sendMessage("You don't have enough inventory space to hold that item.") + return true + } + if (!canTake(player, item, 0)) { + return true + } + if (item.isActive && player.inventory.add(add)) { + if (item.dropper is Player && item.dropper.details.uid != player.details.uid){ + PlayerMonitor.log(item.dropper, LogType.DROP_TRADE, "${getItemName(item.id)} x${item.amount} picked up by ${player.name}.") + } + if (!RegionManager.isTeleportPermitted(item.location)) { + player.animate(Animation.create(535)) + } + GroundItemManager.destroy(item) +/* if (item.dropper?.isArtificial == true) { + getItems(item.dropper)?.remove(item) + } + */ + + playAudio(player, Sounds.PICK2_2582) + player.dispatch(PickUpEvent(item.id)) + } + return true + } + + /** + * Checks if the player can take an item. + * @param player the player. + * @param item the item. + * @param type the type (1= ground, 2=telegrab) + * @return `True` if so. + */ + @JvmStatic + fun canTake(player: Player, item: GroundItem, type: Int): Boolean { + if (item.dropper != null && !item.droppedBy(player) && player.ironmanManager.checkRestriction()) { + return false + } + if (item.id == 8858 || item.id == 8859) { + player.dialogueInterpreter.sendDialogues(4300, core.game.dialogue.FacialExpression.FURIOUS, "Hey! You can't take that, it's guild property. Take one", "from the pile.") + return false + } + if (GodType.forCape(item) != null) { + if (GodType.hasAny(player)) { + player.sendMessages("You may only possess one sacred cape at a time.", "The conflicting powers of the capes drive them apart.") + return false + } + } + if (RunePouch.forItem(item) != null) { + if (player.hasItem(item)) { + player.sendMessage("A mystical force prevents you from picking up the pouch.") + return false + } + } + return if (item.hasItemPlugin()) { + item.plugin.canPickUp(player, item, type) + } else true + } +} diff --git a/Server/src/main/core/game/global/action/SpecialLadders.java b/Server/src/main/core/game/global/action/SpecialLadders.java new file mode 100644 index 0000000..532bd89 --- /dev/null +++ b/Server/src/main/core/game/global/action/SpecialLadders.java @@ -0,0 +1,130 @@ +package core.game.global.action; + +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.world.map.Location; +import content.region.kandarin.feldip.quest.zogreflesheaters.ZogreFleshEatersListeners; + +import java.util.Arrays; +import java.util.HashMap; + +public enum SpecialLadders implements LadderAchievementCheck { + HAM_STORAGE_UP(new Location(2567,5185,0), new Location(3166,9623,0)), + GEM_MINE(new Location(2821,2996,0), new Location(2838,9387,0)), + GEM_MINE_UP(new Location(2838,9388,0), new Location(2820, 2996, 0)), + BEAR_CAGE_UP(Location.create(3230, 9904, 0),Location.create(3231, 3504, 0)), + BEAR_CAGE_DOWN(Location.create(3230,3508,0),Location.create(3229, 9904, 0)), + GLARIAL_EXIT(Location.create(2556,9844,0),Location.create(2557,3444,0)), + SWENSEN_DOWN(Location.create(2644, 3657, 0), Location.create(2631, 10006, 0)), + SWENSEN_UP(Location.create(2665, 10037, 0),Location.create(2649, 3661, 0)), + FOG_ENTER(Location.create(3240,3575,0),Location.create(1675,5599,0)), + FOG_LEAVE(Location.create(1673,5598,0),Location.create(3242, 3574, 0)), + INTRO_ENTER(Location.create(3230,3241,0),Location.create(3290, 4936, 0)), + INTRO_LEAVE(Location.create(3290, 4935, 0),Location.create(3230, 3240, 0)), + JATIZSO_MINE_UP(Location.create(2406,10188,0),Location.create(2397, 3811, 0)), + JATIZSO_MINE_DOWN(Location.create(2397, 3812, 0), Location.create(2405, 10188, 0)), + JATIZSO_SHOUT_TOWER_UP(Location.create(2373, 3800, 2),Location.create(2374, 3800, 0)), + JATIZSO_SHOUT_TOWER_DOWN(Location.create(2373, 3800, 0),Location.create(2374, 3800, 2)), + + // sendMessage(player, "You descend into the somewhat smoky depths of the well, to the accompaniment of") + // sendMessage(player, "eery wails.") https://youtu.be/x8abdpkJ6ZA + POLLNIVNEACH_SLAYER_DUNGEON_UP(Location.create(3358,2971,0), Location.create(3359,9354,0)), + // sendMessage(player, "You nimbly climb up the bucket rope, emerging into Pollnivneach's bustling square.") https://youtu.be/LVwbmCNjlzQ + POLLNIVNEACH_SLAYER_DUNGEON_DOWN(Location.create(3358,9352,0), Location.create(3358,2970,0)), + ALKHARID_ZEKE_UP(Location.create(3284,3186,0), Location.create(3284,3190,1)), + ALKHARID_ZEKE_DOWN(Location.create(3284,3190,1), Location.create(3284,3186,0)), + ALKHARID_CRAFTING_UP(Location.create(3311,3187,0),Location.create(3314,3187,1)), + ALKHARID_CRAFTING_DOWN(Location.create(3314,3187,1),Location.create(3310,3187,0)), + ALKHARID_SOCRCERESS_UP(Location.create(3325,3142,0),Location.create(3325,3139,1)), + ALKHARID_SOCRCERESS_DOWN(Location.create(3325,3139,1),Location.create(3325,3143,0)), + KHARIDIAN_DESERT_SUMMONING_UP(Location.create(3299,9318,0),Location.create(3303,2897,0)), + KHARIDIAN_DESERT_SUMMONING_DOWN(Location.create(3304,2897,0),Location.create(3299,9317,0)), + SHADOW_DUNGEON_UP(new Location(2629, 5072,0), new Location(2548, 3421,0)), + + CLOCKTOWER_HIDDEN_LADDER(Location.create(2572,9631,0),Location.create(2572,3230,0)), + + DRAYNOR_SEWER_SOUTHEAST_DOWN(new Location(3118, 3244, 0), new Location(3118, 9643, 0)), + DRAYNOR_SEWER_SOUTHEAST_UP(new Location(3118, 9643, 0), new Location(3118, 3243, 0)), + DRAYNOR_SEWER_NORTHWEST_DOWN(new Location(3084, 3272, 0), new Location(3085, 9672, 0)), + DRAYNOR_SEWER_NORTHWEST_UP(new Location(3084, 9672, 0), new Location(3084, 3271, 0)), + + BURTHORPE_HEROES_GUILD_STAIRS_UP(new Location(2895,3513,0), new Location(2897, 3513,1)), + + TREE_GNOME_STRONGHOLD_WEST_BAR_STAIRS_UP( new Location(2417, 3490, 0), new Location(2418, 3492,1)), + TREE_GNOME_STRONGHOLD_WEST_BAR_STAIRS_DOWN(new Location(2418, 3491,1), new Location(2419, 3491, 0)), + + WATERBIRTH_ISLAND_DUNGEON_SUBLEVEL_2_WALLASALKI_3_LADDER_DOWN(new Location(1799,4387,2), new Location(1799,4388,1)), + + FALADOR_WHITE_KNIGHT_CASTLE_WEST_TOWER_STAIRS_UP(new Location(2960, 3338,1), new Location(2959,3339,2)), + FALADOR_WHITE_KNIGHT_CASTLE_WEST_TOWER_STAIRS_DOWN(new Location(2960,3339,2), new Location(2960,3340,1)), + + CASTLEWARS_SARADOMIN_MAIN_FLOOR_STAIRS_DOWN(Location.create(2419, 3080, 1), Location.create(2419, 3077, 0)), + CASTLEWARS_SARADOMIN_MAIN_FLOOR_STAIRS_UP(Location.create(2428, 3081, 1), Location.create(2430, 3080, 2)), + CASTLEWARS_SARADOMIN_OUTER_WALL_STAIRS_UP(Location.create(2417, 3077, 0), Location.create(2416, 3075, 0)), + CASTLEWARS_SARADOMIN_OUTER_WALL_STAIRS_DOWN(Location.create(2417, 3075, 0), Location.create(2417, 3078, 0)), + + CASTLEWARS_ZAMORAK_TOP_FLOOR_DOWN(Location.create(2374, 3133, 3), Location.create(2374, 3130, 2)), + CASTLEWARS_ZAMORAK_MAIN_FLOOR_STAIRS_UP(Location.create(2380, 3129, 0), Location.create(2379, 3127, 1)), + CASTLEWARS_ZAMORAK_OUTERWALL_STAIRS_UP(Location.create(2382, 3130, 0), Location.create(2383, 3132, 0)), + CASTLEWARS_ZAMOUTER_WALL_STAIRS_DOWN(Location.create(2382, 3132, 0), Location.create(2382, 3129, 0)), + + WHITE_WOLF_MOUNTAIN_FAKE_LADDER_1_UP(Location.create(2837, 9927, 0), Location.create(2837, 3527, 0)), + WHITE_WOLF_MOUNTAIN_FAKE_LADDER_2_UP(Location.create(2823, 9930, 0), Location.create(2823, 3529, 0)), + + PORT_SARIM_RAT_PITS_DOWN(new Location(3018,3232,0), new Location(2962,9650,0)) { + @Override + public void checkAchievement(Player player) { + player.getAchievementDiaryManager().finishTask(player,DiaryType.FALADOR,1,11); + } + }, + PORT_SARIM_RAT_PITS_UP(new Location(2962,9651,0), new Location(3018,3231,0)), + ENTRANA_GLASSBLOWING_PIPE_HOUSE_DOWN(new Location(2816, 3352, 1), new Location(2817, 3352, 0)), + PATERDOMUS_TEMPLE_STAIRCASE_NORTH_UP(new Location(3415, 3490, 0), new Location(3415, 3491, 1)), + PATERDOMUS_TEMPLE_STAIRCASE_NORTH_DOWN(new Location(3415, 3491, 1), new Location(3414,3491,0)), + PATERDOMUS_TEMPLE_STAIRCASE_SOUTH_DOWN(new Location(3415, 3486,1), new Location(3414, 3486,0)), + PHASMATYS_BAR_DOWN(new Location(3681,3498,0), new Location(3682,9961,0)), + PHASMATYS_BAR_UP(new Location(3682,9962,0), new Location(3681,3497,0)), + YANNILE_HOUSE_DOWN(new Location(2597, 3107,1), new Location(2597, 3107,0)), + YANNILE_HOUSE_UP(new Location(2597, 3107,0), new Location(2597, 3107,1)) { + @Override + public void checkAchievement(Player player) { + ZogreFleshEatersListeners.ladderMakesSithikTurnIntoOgre(player); + } + }, + SEERS_VILLAGE_SPINNING_HOUSE_ROOFTOP_UP(new Location(2715,3472,1), new Location(2714,3472,3)) { + @Override + public void checkAchievement(Player player) { + player.getAchievementDiaryManager().finishTask(player,DiaryType.SEERS_VILLAGE,1,3); + } + }, + SEERS_VILLAGE_SPINNING_HOUSE_ROOFTOP_DOWN(new Location(2715,3472,3), new Location(2714,3472,1)); + + private static HashMap destinationMap = new HashMap<>(); + private static HashMap ladderMap = new HashMap<>(); + static { + Arrays.stream(SpecialLadders.values()).forEach(entry -> { + destinationMap.putIfAbsent(entry.ladderLoc,entry.destLoc); + }); + Arrays.stream(SpecialLadders.values()).forEach(entry -> { + ladderMap.putIfAbsent(entry.ladderLoc, entry); + }); + } + + private Location ladderLoc,destLoc; + SpecialLadders(Location ladderLoc, Location destLoc){ + this.ladderLoc = ladderLoc; + this.destLoc = destLoc; + } + + public static void add(Location from, Location to){ + destinationMap.put(from,to); + } + + public static Location getDestination(Location loc){ + return destinationMap.get(loc); + } + public static SpecialLadders getSpecialLadder(Location loc) { + return ladderMap.get(loc); + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/global/presets/Preset.java b/Server/src/main/core/game/global/presets/Preset.java new file mode 100644 index 0000000..4be9548 --- /dev/null +++ b/Server/src/main/core/game/global/presets/Preset.java @@ -0,0 +1,33 @@ +package core.game.global.presets; + +import core.game.node.item.Item; + +import java.util.ArrayList; + +public class Preset { + + private ArrayList equipment; + + private ArrayList inventory; + + public Preset(ArrayList equipment, ArrayList inventory) { + setEquipment(equipment); + setInventory(inventory); + } + + public ArrayList getEquipment() { + return equipment; + } + + public void setEquipment(ArrayList equipment) { + this.equipment = equipment; + } + + public ArrayList getInventory() { + return inventory; + } + + public void setInventory(ArrayList inventory) { + this.inventory = inventory; + } +} diff --git a/Server/src/main/core/game/global/presets/PresetManager.java b/Server/src/main/core/game/global/presets/PresetManager.java new file mode 100644 index 0000000..a5fa057 --- /dev/null +++ b/Server/src/main/core/game/global/presets/PresetManager.java @@ -0,0 +1,46 @@ +package core.game.global.presets; + +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +public class PresetManager { + + private Player player; + + private final Map current_presets; + + public PresetManager() { + current_presets = new HashMap<>(); + } + + public PresetManager storeSet(String name_key) { + final Preset set = current_presets.get(name_key); + if (set != null) { + player.sendMessage("You were unable to store the set " + name_key + " as it already exists."); + } + name_key = name_key.toLowerCase(); + ArrayList equipment = new ArrayList(Arrays.asList(player.getEquipment().getEvent().getItems())), inventory = new ArrayList(Arrays.asList(player.getInventory().getEvent().getItems())); + current_presets.put(name_key, new Preset(equipment, inventory)); + return this; + } + + public void printAvailableSetups() { + final int size = current_presets.size(); + player.sendMessage("You have used "+size+"/"+maxSize()+" available setups."); + if (size > 0) { + player.sendMessage("Your available setups are:"); + for (final String key : current_presets.keySet()) { + player.sendMessage(key); + } + } + } + + public int maxSize() { + return 6; + } +} diff --git a/Server/src/main/core/game/global/report/AbuseReport.java b/Server/src/main/core/game/global/report/AbuseReport.java new file mode 100644 index 0000000..dee08a0 --- /dev/null +++ b/Server/src/main/core/game/global/report/AbuseReport.java @@ -0,0 +1,97 @@ +package core.game.global.report; + +import core.game.node.entity.player.Player; +import core.integrations.discord.Discord; +import core.game.system.command.CommandMapping; + +/** + * Represents an abuse report to file. + * @author 'Vexia + */ +public final class AbuseReport { + + /** + * The name of the reporter. + */ + private final String reporter; + + /** + * The victim. + */ + private final String victim; + + /** + * The rule. + */ + private final Rule rule; + + /** + * The messages. + */ + private String messages; + + /** + * Constructs a new {@code AbuseReport {@code Object}. + * @param reporter the reporter. + * @param victim the victim. + * @param rule the rule broken. + */ + public AbuseReport(String reporter, String victim, Rule rule) { + this.reporter = reporter; + this.victim = victim; + this.rule = rule; + } + + /** + * Constructs the report and dispatches it to the database. + * @param player the player. + */ + public void construct(Player player, boolean mute) { + if (mute) { + CommandMapping.INSTANCE.get("mute").attemptHandling(player, new String[] {"mute", victim, "48h"}); + } + player.getPacketDispatch().sendMessage("Thank-you, your abuse report has been received."); + Discord.postPlayerAlert(victim, "Abuse Report - " + rule.name()); + } + + /** + * Gets the reporter. + * @return The reporter. + */ + public String getReporter() { + return reporter; + } + + /** + * Gets the victim. + * @return The victim. + */ + public String getVictim() { + return victim; + } + + /** + * Gets the rule. + * @return The rule. + */ + public Rule getRule() { + return rule; + } + + /** + * Gets the messages. + * @return The messages. + */ + public String getMessages() { + return messages; + } + + /** + * Sets the messages. + * @param messages The messages to set. + */ + public void setMessages(String messages) { + this.messages = messages; + } + +} diff --git a/Server/src/main/core/game/global/report/Rule.java b/Server/src/main/core/game/global/report/Rule.java new file mode 100644 index 0000000..b11c3a5 --- /dev/null +++ b/Server/src/main/core/game/global/report/Rule.java @@ -0,0 +1,60 @@ +package core.game.global.report; + +import core.game.node.entity.player.Player; + +/** + * Represents a rule. + * @author 'Vexia + */ +public enum Rule { + OFFENSIVE_LANGUAGE(0), ITEM_SCAMMING(1), PASSWORD_SCAMMING(2), BUG_ABUSE(3), KELDAGRIM_STAFF_IMPERSONATION(4), ACCCOUNT_SHARING(5), MACROING(6), MULTIPLE_LOGGING(7), ENCOURAGING_TO_BREAK_TULES(8), MISUSE_OF_CUSTOMER_SUPPORT(9), ADVERISTING(10), REAL_WORLD_ITEM_TRADING(11), ASKING_PERSONAL_DETAILS(12); + + /** + * Constructs a new {@code Rule.java} {@code Object}. + * @param rule the rule. + */ + Rule(int rule) { + this.rule = rule; + } + + /** + * The rule id opcode. + */ + private int rule; + + /** + * Represents if the rule is relative to the sequences that has happend. + * @return {@code True} if so. + */ + public boolean canRequest(Player target) { + if (target == null) { + return false; + } + if (target.getSavedData().getGlobalData().getChatPing() < System.currentTimeMillis()) { + return false; + } + return true; + } + + /** + * Gets the rule. + * @return the rule. + */ + public int getRule() { + return rule; + } + + /** + * Gets the rule. + * @param id the id. + * @return the rule. + */ + public static Rule forId(int id) { + for (Rule rule : Rule.values()) { + if (rule.getRule() == id) { + return rule; + } + } + return null; + } +} diff --git a/Server/src/main/core/game/interaction/Clocks.kt b/Server/src/main/core/game/interaction/Clocks.kt new file mode 100644 index 0000000..950ef84 --- /dev/null +++ b/Server/src/main/core/game/interaction/Clocks.kt @@ -0,0 +1,12 @@ +package core.game.interaction + +object Clocks { + @JvmStatic val MOVEMENT = 0 + @JvmStatic val ANIMATION_END = 1 + @JvmStatic val NEXT_EAT = 2 + @JvmStatic val NEXT_CONSUME = 3 + @JvmStatic val NEXT_DRINK = 4 + @JvmStatic val NEXT_ATTACK = 5 + @JvmStatic val STUN = 6 + @JvmStatic val SKILLING = 7 +} diff --git a/Server/src/main/core/game/interaction/DestinationFlag.java b/Server/src/main/core/game/interaction/DestinationFlag.java new file mode 100644 index 0000000..a5d9a01 --- /dev/null +++ b/Server/src/main/core/game/interaction/DestinationFlag.java @@ -0,0 +1,267 @@ +package core.game.interaction; + +import core.game.global.action.DoorActionHandler; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.scenery.Scenery; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; + +/** + * Holds the destination flags for all types of nodes. + * @author Emperor + */ +public class DestinationFlag { + + /** + * The Location destination flag. + */ + public static final DestinationFlag LOCATION = new DestinationFlag(); + + /** + * The entity destination flag. + */ + public static final DestinationFlag ENTITY = new DestinationFlag() { + + @Override + public Location getDestination(Entity mover, Node n) { + Location l = getClosestTo(mover, n, n.getLocation().transform(0, -1, 0)); + if (mover.size() > 1) { + if (l.getX() < n.getLocation().getX()) { + l = l.transform(-(mover.size() - 1), 0, 0); + } + if (l.getY() < n.getLocation().getY()) { + l = l.transform(0, -(mover.size() - 1), 0); + } + } + return l; + } + }; + + /** + * The following an entity destination flag. + */ + public static final DestinationFlag FOLLOW_ENTITY = new DestinationFlag() { + + @Override + public Location getDestination(Entity mover, Node n) { + Direction dir = n.getDirection(); + Location l = n.getLocation().transform(-dir.getStepX(), -dir.getStepY(), 0); + if (!checkTraversal(l, dir)) { + l = getClosestTo(mover, n, l); + } + if (mover.size() > 1) { + if (l.getX() < n.getLocation().getX()) { + l = l.transform(-(mover.size() - 1), 0, 0); + } + if (l.getY() < n.getLocation().getY()) { + l = l.transform(0, -(mover.size() - 1), 0); + } + } + return l; + } + }; + + /** + * The entity destination flag. + */ + public static final DestinationFlag COMBAT = new DestinationFlag() { + + @Override + public Location getDestination(Entity mover, Node n) { + return null;// MovementPulse.getClosest(mover, (Entity) n); + } + }; + + /** + * The item destination flag. + */ + public static final DestinationFlag ITEM = new DestinationFlag() { + + @Override + public Location getDestination(Entity mover, Node n) { + if (!RegionManager.isTeleportPermitted(n.getLocation())) { + return getClosestTo(mover, n, n.getLocation().transform(1, 0, 0)); + } + return n.getLocation(); + } + + }; + + /** + * The object destination flag. + */ + public static final DestinationFlag OBJECT = new DestinationFlag() { + + @Override + public Location getDestination(Entity mover, Node n) { + Scenery object = (Scenery) n; + if (object.getType() < 4 || object.getType() == 9) { + return DoorActionHandler.getDestination(mover, object); + } + if (object.getType() == 4 || object.getType() == 5) { // Wall + // decoration + return object.getLocation(); + } + int sizeX = object.getDefinition().sizeX; + int sizeY = object.getDefinition().sizeY; + if (object.getRotation() % 2 != 0) { + int switcher = sizeX; + sizeX = sizeY; + sizeY = switcher; + } + Direction dir = Direction.forWalkFlag(object.getDefinition().getWalkingFlag(), object.getRotation()); + if (dir != null) { + return getDestination(mover, object, sizeX, sizeY, dir, 3); + } + + return getDestination(mover, object, sizeX, sizeY, Direction.getLogicalDirection(object.getLocation(), mover.getLocation()), 0); + } + + /** + * Gets the destination for the given object. + * @param object The object. + * @param dir The preferred direction from the object. + * @return The teleporting destination. + */ + private Location getDestination(Entity mover, Scenery object, int sizeX, int sizeY, Direction dir, int count) { + Location closest = null; + double distance = 9999.9; + Location loc = object.getLocation(); + for (int i = count; i < 4; i++) { + if (dir.toInteger() % 2 != 0) { + int x = dir.getStepX(); + if (x > 0) { + x *= sizeX; + } + for (int y = 0; y < sizeY; y++) { + Location l = loc.transform(x, y, 0); + if (checkTraversal(l, dir)) { + double dist = mover.getLocation().getDistance(l); + if (dist < distance) { + distance = dist; + closest = l; + } + } + } + } else { + int y = dir.getStepY(); + if (y > 0) { + y *= sizeY; + } + for (int x = 0; x < sizeX; x++) { + Location l = loc.transform(x, y, 0); + if (checkTraversal(l, dir)) { + double dist = mover.getLocation().getDistance(l); + if (dist < distance) { + distance = dist; + closest = l; + } + } + } + } + dir = Direction.get((dir.toInteger() + 1) % 4); + } + return closest; + } + + @Override + public boolean checkTraversal(Location l, Direction dir) { + return RegionManager.isTeleportPermitted(l) && dir.canMove(l); + } + }; + + /** + * Constructs a new {@code DestinationFlag} {@code Object}. + */ + public DestinationFlag() { + /* + * empty. + */ + } + + /** + * Gets the default destination location. + * @param mover The moving entity. + * @param node The node to move to. + * @return The location to walk to. + */ + public Location getDestination(Entity mover, Node node) { + return node.getLocation(); + } + + /** + * Checks if traversal is permitted. + * @param l The location to check. + * @param dir The direction to move. + * @return {@code True}. + */ + public boolean checkTraversal(Location l, Direction dir) { + return Direction.get((dir.toInteger() + 2) % 4).canMove(l); + } + + /** + * Gets the closest destination to the current destination, to reach the + * node. + * @param mover The moving entity. + * @param node The node to move to. + * @param suggestion The suggested destination location. + * @return The destination location. + */ + public Location getClosestTo(Entity mover, Node node, Location suggestion) { + Location nl = node.getLocation(); + int diffX = suggestion.getX() - nl.getX(); + int diffY = suggestion.getY() - nl.getY(); + Direction moveDir = Direction.NORTH; + if (diffX < 0) { + moveDir = Direction.EAST; + } else if (diffX >= node.size()) { + moveDir = Direction.WEST; + } else if (diffY >= node.size()) { + moveDir = Direction.SOUTH; + } + double distance = 9999.9; + Location destination = suggestion; + for (int c = 0; c < 4; c++) { + for (int i = 0; i < node.size() + 1; i++) { + for (int j = 0; j < (i == 0 ? 1 : 2); j++) { + Direction current = Direction.get((moveDir.toInteger() + (j == 1 ? 3 : 1)) % 4); + Location loc = suggestion.transform(current.getStepX() * i, current.getStepY() * i, 0); + if (moveDir.toInteger() % 2 == 0) { + if (loc.getX() < nl.getX() || loc.getX() > nl.getX() + node.size() - 1) { + continue; + } + } else { + if (loc.getY() < nl.getY() || loc.getY() > nl.getY() + node.size() - 1) { + continue; + } + } + if (checkTraversal(loc, moveDir)) { + double dist = mover.getLocation().getDistance(loc); + if (dist < distance) { + distance = dist; + destination = loc; + } + } + } + } + moveDir = Direction.get((moveDir.toInteger() + 1) % 4); + int offsetX = Math.abs(moveDir.getStepY() * (node.size() >> 1)); // Not + // a + // mixup + // between + // x + // & + // y! + int offsetY = Math.abs(moveDir.getStepX() * (node.size() >> 1)); + if (moveDir.toInteger() < 2) { + suggestion = node.getLocation().transform(-moveDir.getStepX() + offsetX, -moveDir.getStepY() + offsetY, 0); + } else { + suggestion = node.getLocation().transform(-moveDir.getStepX() * node.size() + offsetX, -moveDir.getStepY() * node.size() + offsetY, 0); + } + } + return destination; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/interaction/IntType.kt b/Server/src/main/core/game/interaction/IntType.kt new file mode 100644 index 0000000..6fbee00 --- /dev/null +++ b/Server/src/main/core/game/interaction/IntType.kt @@ -0,0 +1,9 @@ +package core.game.interaction + +enum class IntType { + ITEM, + SCENERY, + NPC, + GROUNDITEM, + PLAYER +} \ No newline at end of file diff --git a/Server/src/main/core/game/interaction/InteractPlugin.java b/Server/src/main/core/game/interaction/InteractPlugin.java new file mode 100644 index 0000000..d505798 --- /dev/null +++ b/Server/src/main/core/game/interaction/InteractPlugin.java @@ -0,0 +1,346 @@ +package core.game.interaction; + +import core.game.event.InteractionEvent; +import core.game.container.Container; +import core.game.node.Node; +import core.game.node.entity.impl.PulseType; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.system.task.Pulse; +import core.net.packet.PacketRepository; +import core.net.packet.context.InteractionOptionContext; +import core.net.packet.out.InteractionOption; +import core.tools.Log; +import core.tools.SystemLogger; +import core.game.world.GameWorld; + +import static core.api.ContentAPIKt.log; + +/** + * Handles interaction between nodes. + * @author Emperor + */ +public class InteractPlugin { + + /** + * The current options. + */ + private Option[] options = new Option[8]; + + /** + * The player. + */ + private final Node node; + + /** + * If the interaction option handlers have been initialized. + */ + private boolean initialized; + + /** + * Constructs a new {@code Interaction} {@code Object}. + * @param node The node reference. + */ + public InteractPlugin(Node node) { + this.node = node; + } + + /** + * Sends the current option. + * @param node The node. + * @param index The index. + * @param name The option name. + */ + public static void sendOption(Node node, int index, String name) { + if (!(node instanceof Player)) { + return; + } + PacketRepository.send(InteractionOption.class, new InteractionOptionContext((Player) node, index, name)); + } + + /** + * Handles an interaction option being clicked. + * @param player The player using the option. + * @param option The option used. + */ + public void handle(final Player player, final Option option) { + try { + if (player.getLocks().isInteractionLocked() || option == null) { + return; + } + player.debug("Received interaction request " + option.getName()); + boolean hasHandler = option.getHandler() != null; + boolean walk = hasHandler && option.getHandler().isWalk(); + if (!walk && hasHandler && option.getHandler().isWalk(player, node)) { + walk = true; + } + if (!hasHandler || walk) { + handleWalkOption(player, option, PulseType.STANDARD); + } else if (hasHandler) { + player.debug("Option handler being used=" + option.getHandler().getClass().getSimpleName()); + handleDefaultOption(player, option, PulseType.STANDARD); + } else { + player.getPulseManager().runUnhandledAction(player, PulseType.STANDARD); + } + player.dispatch(new InteractionEvent(node, option.getName().toLowerCase())); + } catch (Exception e){ + e.printStackTrace(); + log(this.getClass(), Log.ERR, this.getClass().getName() + e.getMessage()); + } + } + + /** + * Handles an item option. + * @param player The player. + * @param option The option. + * @param container The container the item is in. + */ + public void handleItemOption(final Player player, final Option option, final Container container) { + if (player.getLocks().isInteractionLocked()) { + return; + } + player.getPulseManager().clear(PulseType.STANDARD); + GameWorld.getPulser().submit(new Pulse(1, player) { + @Override + public boolean pulse() { + try { + if (player.getLocks().isInteractionLocked() || player.getZoneMonitor().interact(node, option)) { + return true; + } + if(InteractionListeners.run(node.getId(), IntType.ITEM, option.getName(),player,node)){ + return true; + } + if (option.getHandler() == null || !option.getHandler().handle(player, node, option.getName().toLowerCase())) { + player.getPacketDispatch().sendMessage("Nothing interesting happens."); + } + if (option.getHandler() != null) { + player.debug("Using item handler " + option.getHandler().getClass().getSimpleName()); + } + } catch (Exception e){ + e.printStackTrace(); + log(this.getClass(), Log.ERR, this.getClass().getName() + e.getMessage()); + } + return true; + } + }); + } + + /** + * Handles an invalid interaction. + * @param player The player. + * @param node The node to interact with. + */ + public static void handleInvalidInteraction(final Player player, final Node node, final Option option) { + if (node == null) { + return; + } + if (node.getLocation() != null) { + if (player.getLocks().isMovementLocked()) { + return; + } + player.getPulseManager().run(new MovementPulse(player, node) { + @Override + public boolean pulse() { + try { + player.faceLocation(node.getFaceLocation(player.getLocation())); + if (player.getLocks().isInteractionLocked() || player.getZoneMonitor().interact(node, option)) { + return true; + } + player.getPacketDispatch().sendMessage("Nothing interesting happens."); + } catch (Exception e){ + e.printStackTrace(); + log(this.getClass(), Log.ERR, this.getClass().getName() + e.getMessage()); + } + return true; + } + }, PulseType.STANDARD); + } else { + player.getPulseManager().runUnhandledAction(player, PulseType.STANDARD); + } + } + + /** + * Handles an option requiring the player to walk to the node. + * @param player The player. + * @param option The option. + * @param pulseType The pulse type. + */ + private void handleWalkOption(final Player player, final Option option, PulseType pulseType) { + if (node.getLocation() == null) { + player.getPulseManager().runUnhandledAction(player, pulseType); + return; + } + if (player.getLocks().isMovementLocked()) { + player.getPulseManager().clear(pulseType); + return; + } + player.getPulseManager().run(new MovementPulse(player, node, option.getHandler()) { + @Override + public boolean pulse() { + try { + player.faceLocation(node.getFaceLocation(player.getLocation())); + if (player.getLocks().isInteractionLocked() || player.getZoneMonitor().interact(node, option)) { + return true; + } + if (option == null || option.getHandler() == null || !option.getHandler().handle(player, node, option.getName().toLowerCase())) { + player.getPacketDispatch().sendMessage("Nothing interesting happens."); + } + } catch (Exception e){ + e.printStackTrace(); + log(this.getClass(), Log.ERR, this.getClass().getName() + e.getMessage()); + } + return true; + } + }, pulseType); + } + + /** + * Handles a default option. + * @param player The player. + * @param option The option. + * @param pulseType The pulse type. + */ + private void handleDefaultOption(final Player player, final Option option, PulseType pulseType) { + if (!option.getHandler().isDelayed(player)) { + if (player.getZoneMonitor().interact(node, option)) { + return; + } + player.getProperties().getCombatPulse().stop(); + if (!option.getHandler().handle(player, node, option.getName().toLowerCase())) { + player.getPulseManager().runUnhandledAction(player, pulseType); + } + return; + } + player.getPulseManager().run(new Pulse(1, player, node) { + @Override + public boolean pulse() { + if (player.getLocks().isInteractionLocked() || player.getZoneMonitor().interact(node, option)) { + return true; + } + if (!option.getHandler().handle(player, node, option.getName().toLowerCase())) { + player.getPacketDispatch().sendMessage("Nothing interesting happens."); + } + return true; + } + }, pulseType); + } + + /** + * Initializes the interaction options. + * @param nodeId The node id. + * @param names The option names. + */ + public void init(int nodeId, String... names) { + options = new Option[names.length]; + for (int i = 0; i < options.length; i++) { + String name = names[i]; + if (name != null && !name.equals("null")) { + set(new Option(name, i).setHandler(Option.defaultHandler(node, nodeId, name))); + } + continue; + } + } + + /** + * Sets the default option handlers (if not yet initialized). + */ + public void setDefault() { + if (initialized) { + return; + } + if (node instanceof Player) { + for (int i = 0; i < options.length; i++) { + remove(i); + } + set(Option._P_FOLLOW); + set(Option._P_TRADE); + set(Option._P_ASSIST); + } else if (node instanceof NPC) { + NPC npc = (NPC) node; + init(npc.getId(), npc.getDefinition().getOptions()); + } else if (node instanceof Scenery) { + Scenery object = (Scenery) node; + init(object.getId(), object.getDefinition().getOptions()); + } else if (node instanceof Item) { + Item item = (Item) node; + if (item.getLocation() != null) { + init(item.getId(), item.getDefinition().getGroundOptions()); + } else { + init(item.getId(), item.getDefinition().getInventoryOptions()); + } + } else { + throw new IllegalStateException("Unsupported node type - " + node); + } + initialized = true; + } + + /** + * Sets a new option. + * @param option The option. + */ + public void set(Option option) { + options[option.getIndex()] = option; + sendOption(node, option.getIndex(), option.getName()); + } + + /** + * Removes an option. + * @return {@code True} if the option got removed, {@code false} if the + * option wasn't set. + */ + public boolean remove(Option option) { + if (options[option.getIndex()] == option) { + remove(option.getIndex()); + return true; + } + return false; + } + + /** + * Removes an option. + * @param index The index. + */ + public void remove(int index) { + if (options[index] == null) { + return; + } + options[index] = null; + sendOption(node, index, "null"); + } + + /** + * Gets the option on the requested slot. + * @param index The slot index. + * @return The option on that slot, or {@code null} if there was no option. + */ + public Option get(int index) { + return options[index]; + } + + /** + * Gets the options. + * @return The options. + */ + public Option[] getOptions() { + return options; + } + + /** + * Gets the initialized value. + * @return The initialized. + */ + public boolean isInitialized() { + return initialized; + } + + /** + * Sets the initialized value. + * @param initialized The initialized to set. + */ + public void setInitialized(boolean initialized) { + this.initialized = initialized; + } + +} diff --git a/Server/src/main/core/game/interaction/InteractionListener.kt b/Server/src/main/core/game/interaction/InteractionListener.kt new file mode 100644 index 0000000..fff3966 --- /dev/null +++ b/Server/src/main/core/game/interaction/InteractionListener.kt @@ -0,0 +1,97 @@ +package core.game.interaction + +import core.api.ContentInterface +import core.game.node.Node +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.world.map.Location +import content.global.handlers.item.SpadeDigListener + +interface InteractionListener : ContentInterface{ + val ITEM + get() = IntType.ITEM + val GROUNDITEM + get() = IntType.GROUNDITEM + val NPC + get() = IntType.NPC + val SCENERY + get() = IntType.SCENERY + + fun on(id: Int, type: IntType, vararg option: String, handler: (player: Player, node: Node) -> Boolean){ + InteractionListeners.add(id, type.ordinal, option, handler) + } + fun on(ids: IntArray, type: IntType, vararg option: String, handler: (player: Player, node: Node) -> Boolean){ + InteractionListeners.add(ids, type.ordinal, option, handler) + } + @Deprecated("Don't use") fun on(option: String, type: IntType, handler: (player: Player, node: Node) -> Boolean){ + InteractionListeners.add(option, type.ordinal, handler) + } + fun on(type: IntType, vararg option: String, handler: (player: Player, node: Node) -> Boolean){ + InteractionListeners.add(option, type.ordinal, handler) + } + fun onUseWith(type: IntType, used: Int, vararg with: Int, handler: (player: Player, used: Node, with: Node) -> Boolean){ + InteractionListeners.add(type.ordinal, used, with, handler) + } + fun onUseWith(type: IntType, used: IntArray, vararg with: Int, handler: (player: Player, used: Node, with: Node) -> Boolean){ + InteractionListeners.add(type.ordinal, used, with, handler) + } + fun onUseAnyWith(type: IntType, vararg with: Int, handler: (player: Player, used: Node, with: Node) -> Boolean) { + InteractionListeners.add(type.ordinal, with, handler) + } + fun onUseWithPlayer(vararg used: Int, handler: (player: Player, used: Node, with: Node) -> Boolean) { + InteractionListeners.add(IntType.PLAYER.ordinal, used, handler) + } + // Note: wildcard listeners incur overhead on every use-with interaction, only use them as a space-time tradeoff when something + // is actually supposed to have a response to every item used with it (e.g. imp boxes, certain quest npcs) + fun onUseWithWildcard(type: IntType, predicate: (used: Int, with: Int) -> Boolean, handler: (player: Player, used: Node, with: Node) -> Boolean) { + InteractionListeners.addWildcard(type.ordinal, predicate, handler) + } + fun onEquip(id: Int, handler: (player: Player, node: Node) -> Boolean){ + InteractionListeners.addEquip(id, handler) + } + fun onUnequip(id:Int, handler: (player: Player, node: Node) -> Boolean){ + InteractionListeners.addUnequip(id, handler) + } + + fun onEquip(ids: IntArray, handler: (player: Player, node: Node) -> Boolean){ + ids.forEach { id -> InteractionListeners.addEquip(id, handler) } + } + fun onUnequip(ids:IntArray, handler: (player: Player, node: Node) -> Boolean){ + ids.forEach{ id -> InteractionListeners.addUnequip(id, handler) } + } + + fun defineDestinationOverrides(){} + + fun setDest(type: IntType, id: Int, handler: (Entity, Node) -> Location){ + InteractionListeners.addDestOverride(type.ordinal, id, handler) + } + fun setDest(type: IntType, vararg options: String, handler: (Entity, Node) -> Location){ + InteractionListeners.addDestOverrides(type.ordinal, options, handler) + } + + fun setDest(type: IntType, ids: IntArray, vararg options: String, handler: (Entity, Node) -> Location){ + InteractionListeners.addDestOverrides(type.ordinal, ids, options, handler) + } + + fun onDig(location: Location,method: (player: Player) -> Unit){ + SpadeDigListener.registerListener(location, method) + } + + fun flagInstant() { + val name = this::class.java.name + InteractionListeners.instantClasses.add(name) + } + + fun defineInteraction(type: IntType, ids: IntArray, vararg options: String, persistent: Boolean = false, allowedDistance: Int = 1, handler: (player: Player, node: Node, state: Int) -> Boolean) { + InteractionListeners.addMetadata(ids, type, options, InteractionMetadata(handler, allowedDistance, persistent)) + } + + fun defineInteraction(type: IntType, vararg options: String, persist: Boolean = false, allowedDistance: Int = 1, handler: (player: Player, node: Node, state: Int) -> Boolean) { + InteractionListeners.addGenericMetadata(options, type, InteractionMetadata(handler, allowedDistance, persist)) + } + + data class InteractionMetadata(val handler: (player: Player, node: Node, state: Int) -> Boolean, val distance: Int, val persist: Boolean) + data class UseWithMetadata(val handler: (player: Player, used: Node, with: Node, state: Int) -> Boolean, val distance: Int, val persist: Boolean) + + fun defineListeners() +} diff --git a/Server/src/main/core/game/interaction/InteractionListeners.kt b/Server/src/main/core/game/interaction/InteractionListeners.kt new file mode 100644 index 0000000..c281135 --- /dev/null +++ b/Server/src/main/core/game/interaction/InteractionListeners.kt @@ -0,0 +1,320 @@ +package core.game.interaction + +import core.game.event.InteractionEvent +import core.game.event.UseWithEvent +import core.game.node.Node +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.world.map.Location + +object InteractionListeners { + private val listeners = HashMap Boolean>(1000) + private val useWithListeners = HashMap Boolean>(1000) + private val useAnyWithListeners = HashMap Boolean>(10) + private val useWithWildcardListeners = HashMap Boolean, (Player, Node, Node) -> Boolean>>>(10) + private val destinationOverrides = HashMap Location>(100) + private val equipListeners = HashMap Boolean>(10) + private val interactions = HashMap() + private val useWithInteractions = HashMap() + val instantClasses = HashSet() + + @JvmStatic + fun add(id: Int, type: Int, option: Array, method: (Player,Node) -> Boolean){ + for(opt in option) { + val key = "$id:$type:${opt.toLowerCase()}" + if (!validate(key)) { + throw IllegalStateException("$opt for $id with type ${IntType.values()[type].name} already defined! Existing use: [${listeners[key]!!::class.toString()}]") + } + listeners[key] = method + } + } + + private fun validate(key: String): Boolean { + return !listeners.containsKey(key) && !useWithListeners.containsKey(key) + } + + @JvmStatic + fun add(ids: IntArray, type: Int, option: Array, method: (Player,Node) -> Boolean){ + for(id in ids){ + add(id,type,option,method) + } + } + + @JvmStatic + fun add(option: String,type: Int, method: (Player,Node) -> Boolean){ + val key = "$type:${option.toLowerCase()}" + if (!validate(key)) { + throw IllegalStateException("Catchall listener for $option on type ${IntType.values()[type].name} already in use: ${listeners[key]!!::class}") + } + listeners[key] = method + } + + @JvmStatic + fun add(options: Array,type: Int,method: (Player, Node) -> Boolean){ + for(opt in options){ + add(opt.toLowerCase(),type,method) + } + } + + @JvmStatic + fun add(used: Int, with: Int, type: Int, method: (Player,Node,Node) -> Boolean){ + val key = "$used:$with:$type" + val altKey = "$with:$used:$type" + if (!validate(key) || !validate(altKey)) { + throw IllegalStateException("Usewith using $used with $with for type ${IntType.values()[type]} already in use: [${(useWithListeners[key] ?: useWithListeners[altKey])!!::class}") + } + useWithListeners[key] = method + } + + @JvmStatic + fun add(type: Int, used: Int, with: IntArray, method: (Player, Node, Node) -> Boolean){ + for(id in with){ + add(used = used, with = id, type = type, method = method) + } + } + + @JvmStatic + fun addWildcard(type: Int, predicate: (used: Int, with: Int) -> Boolean, handler: (player: Player, used: Node, with: Node) -> Boolean) { + if(!useWithWildcardListeners.containsKey(type)) { + useWithWildcardListeners.put(type, ArrayList()) + } + useWithWildcardListeners[type]!!.add(Pair(predicate, handler)) + } + + @JvmStatic + fun addEquip(id: Int,method: (Player, Node) -> Boolean){ + equipListeners["equip:$id"] = method + } + + @JvmStatic + fun addUnequip(id: Int, method: (Player,Node) -> Boolean){ + equipListeners["unequip:$id"] = method + } + + @JvmStatic + fun getEquip(id: Int): ((Player,Node) -> Boolean)? { + return equipListeners["equip:$id"] + } + + @JvmStatic + fun getUnequip(id: Int): ((Player,Node) -> Boolean)? { + return equipListeners["unequip:$id"] + } + + @JvmStatic + fun get(used: Int, with: Int, type: Int): ((Player,Node,Node) -> Boolean)? { + val method = useWithListeners["$used:$with:$type"] ?: useAnyWithListeners["$with:$type"] + if(method != null) { + return method + } + val handlers = useWithWildcardListeners[type] ?: return null + for(pair in handlers) { + if(pair.first(used, with)) { + return pair.second + } + } + return null + } + + @JvmStatic + fun get(id: Int, type: Int, option: String): ((Player,Node) -> Boolean)?{ + return listeners["$id:$type:${option.toLowerCase()}"] + } + + @JvmStatic + fun get(option: String,type: Int): ((Player,Node) -> Boolean)?{ + return listeners["$type:${option.toLowerCase()}"] + } + + @JvmStatic + fun addDestOverride(type: Int, id: Int, method: (Entity,Node) -> Location){ + destinationOverrides["$type:$id"] = method + } + + @JvmStatic + fun addDestOverrides(type: Int,options: Array, method: (Entity,Node) -> Location){ + for(opt in options){ + destinationOverrides["$type:${opt.toLowerCase()}"] = method + } + } + + @JvmStatic + fun addDestOverrides(type: Int, ids: IntArray,options: Array, method: (Entity,Node) -> Location){ + for(id in ids){ + for(opt in options){ + destinationOverrides["$type:$id:${opt.toLowerCase()}"] = method + } + } + } + + @JvmStatic + fun getOverride(type: Int, id:Int, option: String): ((Entity, Node) -> Location)?{ + return destinationOverrides["$type:$id:${option.toLowerCase()}"] + } + + @JvmStatic + fun getOverride(type: Int,id: Int): ((Entity,Node) -> Location)?{ + return destinationOverrides["$type:$id"] + } + + @JvmStatic + fun getOverride(type: Int,option: String): ((Entity,Node) -> Location)?{ + return destinationOverrides["$type:$option"] + } + + @JvmStatic + fun run(id: Int, player: Player, node: Node, isEquip: Boolean): Boolean{ + player.dispatch(InteractionEvent(node, if(isEquip) "equip" else "unequip")) + if(isEquip){ + return equipListeners["equip:$id"]?.invoke(player,node) ?: true + } else { + return equipListeners["unequip:$id"]?.invoke(player,node) ?: true + } + } + + @JvmStatic + fun run(used: Node, with: Node, type: IntType, player: Player): Boolean{ + val flag = when(type){ + IntType.NPC, IntType.PLAYER -> DestinationFlag.ENTITY + IntType.SCENERY -> DestinationFlag.OBJECT + IntType.GROUNDITEM -> DestinationFlag.ITEM + else -> DestinationFlag.OBJECT + } + + if(player.locks.isInteractionLocked) return false + + var flipped = false + + val method = if (with is Player) get(-1, used.id, 4) ?: return false + else get(used.id,with.id,type.ordinal) ?: + if (type == IntType.ITEM) + get(with.id,used.id,type.ordinal).also { flipped = true } ?: return false + else return false + + val destOverride = if(flipped) { + getOverride(type.ordinal, used.id, "use") ?: getOverride(type.ordinal, with.id) ?: getOverride(type.ordinal, "use") + } else { + getOverride(type.ordinal, with.id, "use") ?: getOverride(type.ordinal, used.id) ?: getOverride(type.ordinal, "use") + } + + + if(type != IntType.ITEM && !isUseWithInstant(method)) { + if(player.locks.isMovementLocked) return false + player.pulseManager.run(object : MovementPulse(player, with, flag, destOverride) { + override fun pulse(): Boolean { + if (player.zoneMonitor.useWith(used.asItem(), with)) { + return true + } + player.faceLocation(with.location) + if(flipped) player.dispatch(UseWithEvent(with.id, used.id)) + else player.dispatch(UseWithEvent(used.id, with.id)) + if(flipped) method.invoke(player,with,used) + else method.invoke(player,used,with) + return true + } + }) + } else { + if(flipped) player.dispatch(UseWithEvent(with.id, used.id)) + else player.dispatch(UseWithEvent(used.id, with.id)) + if(flipped) return method.invoke(player,with,used) + else return method.invoke(player,used,with) + } + return true + } + + @JvmStatic + fun run(id: Int, type: IntType, option: String, player: Player, node: Node): Boolean{ + val flag = when(type){ + IntType.PLAYER -> DestinationFlag.ENTITY + IntType.GROUNDITEM -> DestinationFlag.ITEM + IntType.NPC -> DestinationFlag.ENTITY + IntType.SCENERY -> null + else -> DestinationFlag.OBJECT + } + + if(player.locks.isInteractionLocked) return false + + val method = get(id,type.ordinal,option) ?: get(option,type.ordinal) + + player.setAttribute("interact:option", option.lowercase()) + player.dispatch(InteractionEvent(node, option.toLowerCase())) + + if (method == null) { + val inter = interactions["${type.ordinal}:$id:${option.lowercase()}"] ?: interactions["${type.ordinal}:${option.lowercase()}"] ?: return false + val script = Interaction(inter.handler, inter.distance, inter.persist) + player.scripts.setInteractionScript(node, script) + player.pulseManager.run(object : MovementPulse(player, node, flag) { + override fun pulse(): Boolean { + return true + } + }) + return true + } + + val destOverride = getOverride(type.ordinal, id, option) ?: getOverride(type.ordinal,node.id) ?: getOverride(type.ordinal,option.toLowerCase()) + + if(type != IntType.ITEM && !isInstant(method)) { + if(player.locks.isMovementLocked) return false + player.pulseManager.run(object : MovementPulse(player, node, flag, destOverride) { + override fun pulse(): Boolean { + if(player.zoneMonitor.interact(node, Option(option, 0))) return true + player.faceLocation(node.location) + method.invoke(player,node) + return true + } + }) + } else { + method.invoke(player,node) + } + return true + } + + fun add(type: Int, used: IntArray, with: IntArray, handler: (Player, Node, Node) -> Boolean) { + for(u in used){ + for (w in with){ + useWithListeners["$u:$w:$type"] = handler + } + } + } + + fun add(type: Int, with: IntArray, handler: (Player, Node, Node) -> Boolean) { + for (w in with) { + useAnyWithListeners["$w:$type"] = handler + } + } + + fun isInstant(handler: (Player, Node) -> Boolean): Boolean { + val className = handler.javaClass.name.substringBefore("$") + return instantClasses.contains(className) + } + + fun isUseWithInstant(handler: (player: Player, used: Node, with: Node) -> Boolean): Boolean { + val className = handler.javaClass.name.substringBefore("$") + return instantClasses.contains(className) + } + + fun addMetadata (ids: IntArray, type: IntType, options: Array, metadata: InteractionListener.InteractionMetadata) { + for (id in ids) + for (opt in options) + interactions["${type.ordinal}:$id:${opt.lowercase()}"] = metadata + } + + fun addMetadata (id: Int, type: IntType, options: Array, metadata: InteractionListener.InteractionMetadata) { + for (opt in options) + interactions["${type.ordinal}:$id:${opt.lowercase()}"] = metadata + } + + fun addGenericMetadata (options: Array, type: IntType, metadata: InteractionListener.InteractionMetadata) { + for (opt in options) + interactions["${type.ordinal}:$opt"] = metadata + } + + fun addMetadata (used: Int, with: IntArray, type: IntType, metadata: InteractionListener.UseWithMetadata) { + for (id in with) + useWithInteractions["${type.ordinal}:$used:$with"] = metadata + } + + fun addMetadata (used: Int, with: Int, type: IntType, metadata: InteractionListener.UseWithMetadata) { + useWithInteractions["${type.ordinal}:$used:$with"] = metadata + } +} diff --git a/Server/src/main/core/game/interaction/InterfaceListener.kt b/Server/src/main/core/game/interaction/InterfaceListener.kt new file mode 100644 index 0000000..b28c5e9 --- /dev/null +++ b/Server/src/main/core/game/interaction/InterfaceListener.kt @@ -0,0 +1,27 @@ +package core.game.interaction + +import core.api.ContentInterface +import core.game.component.Component +import core.game.node.entity.player.Player + +/** + * An interface for writing content that allows the class to handle game interface interactions + * + * Interactions should be defined in the required [defineInterfaceListeners] method. + */ +interface InterfaceListener : ContentInterface { + fun defineInterfaceListeners() + + fun on(componentID: Int, buttonID: Int, handler: (player: Player, component: Component, opcode: Int, buttonID: Int, slot: Int, itemID: Int) -> Boolean){ + InterfaceListeners.add(componentID, buttonID, handler) + } + fun on(componentID: Int, handler: (player: Player, component: Component, opcode: Int, buttonID: Int, slot: Int, itemID: Int) -> Boolean){ + InterfaceListeners.add(componentID, handler) + } + fun onOpen(componentID: Int,handler: (player: Player, component: Component) -> Boolean){ + InterfaceListeners.addOpenListener(componentID, handler) + } + fun onClose(componentID: Int,handler: (player: Player, component: Component) -> Boolean){ + InterfaceListeners.addCloseListener(componentID, handler) + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/interaction/InterfaceListeners.kt b/Server/src/main/core/game/interaction/InterfaceListeners.kt new file mode 100644 index 0000000..2fded1e --- /dev/null +++ b/Server/src/main/core/game/interaction/InterfaceListeners.kt @@ -0,0 +1,67 @@ +package core.game.interaction + +import core.game.component.Component +import core.game.node.entity.player.Player + +object InterfaceListeners { + val buttonListeners = HashMap Boolean>(1000) + val openListeners = HashMap Boolean>(100) + + @JvmStatic + fun add(componentID: Int, buttonID: Int, handler: (Player,Component,Int,Int,Int,Int) -> Boolean){ + buttonListeners["$componentID:$buttonID"] = handler + } + + @JvmStatic + fun add(componentID: Int, handler: (Player, Component, Int, Int, Int, Int) -> Boolean){ + buttonListeners["$componentID"] = handler + } + + @JvmStatic + fun addOpenListener(componentID: Int, handler: (Player,Component) -> Boolean){ + openListeners["$componentID"] = handler + } + + @JvmStatic + fun addCloseListener(componentID: Int, handler: (Player, Component) -> Boolean){ + openListeners["close:$componentID"] = handler + } + + @JvmStatic + fun get(componentID: Int, buttonID: Int): ((Player,Component,Int,Int,Int,Int) -> Boolean)?{ + return buttonListeners["$componentID:$buttonID"] + } + + @JvmStatic + fun get(componentID: Int): ((Player,Component,Int,Int,Int,Int) -> Boolean)?{ + return buttonListeners["$componentID"] + } + + @JvmStatic + fun getOpenListener(componentID: Int): ((Player,Component) -> Boolean)?{ + return openListeners["$componentID"] + } + + @JvmStatic + fun getCloseListener(componentID: Int): ((Player,Component) -> Boolean)?{ + return openListeners["close:$componentID"] + } + + @JvmStatic + fun runOpen(player: Player,component: Component): Boolean{ + val method = getOpenListener(component.id) ?: return false + return method.invoke(player,component) + } + + @JvmStatic + fun runClose(player: Player,component: Component): Boolean{ + val method = getCloseListener(component.id) ?: return true + return method.invoke(player,component) + } + + @JvmStatic + fun run(player: Player, component: Component, opcode: Int, buttonID: Int, slot: Int, itemID: Int): Boolean{ + val method = get(component.id,buttonID) ?: get(component.id) ?: return false + return method.invoke(player,component,opcode,buttonID,slot,itemID) + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/interaction/Listener.kt b/Server/src/main/core/game/interaction/Listener.kt new file mode 100644 index 0000000..dc4b5c4 --- /dev/null +++ b/Server/src/main/core/game/interaction/Listener.kt @@ -0,0 +1,11 @@ +package core.game.interaction + +import core.api.StartupListener + +interface Listener : StartupListener { + override fun startup() { + defineListeners() + } + + fun defineListeners() +} \ No newline at end of file diff --git a/Server/src/main/core/game/interaction/MovementPulse.java b/Server/src/main/core/game/interaction/MovementPulse.java new file mode 100644 index 0000000..04c9d2a --- /dev/null +++ b/Server/src/main/core/game/interaction/MovementPulse.java @@ -0,0 +1,556 @@ +package core.game.interaction; + +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.impl.WalkingQueue; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.npc.NPCBehavior; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.Point; +import core.game.world.map.path.Path; +import core.game.world.map.path.Pathfinder; +import core.net.packet.PacketRepository; +import core.net.packet.context.PlayerContext; +import core.net.packet.out.ClearMinimapFlag; +import kotlin.jvm.functions.Function2; +import kotlin.Pair; +import core.tools.SystemLogger; +import core.api.utils.Vector; + +import content.region.wilderness.handlers.revenants.RevenantNPC; + +import static core.api.ContentAPIKt.*; + +import java.util.Deque; + +/** + * Handles a movement task. + * + * @author Emperor + */ +public abstract class MovementPulse extends Pulse { + + /** + * The moving entity. + */ + protected Entity mover; + + /** + * The destination node. + */ + protected Node destination; + + /** + * The destination's last location. + */ + private Location last; + + /** + * The pathfinder. + */ + private Pathfinder pathfinder; + + /** + * If running should be forced. + */ + private boolean forceRun; + + /** + * The option handler. + */ + private OptionHandler optionHandler; + + /** + * The use with handler. + */ + private UseWithHandler useHandler; + + /** + * The destination flag. + */ + private DestinationFlag destinationFlag; + + /** + * The location to interact from. + */ + private Location interactLocation; + + /** + * If the path couldn't be fully found. + */ + private boolean near; + + private Function2 overrideMethod; + + private Location previousLoc; + + /** + * Constructs a new {@code MovementPulse} {@code Object}. + * + * @param mover The moving entity. + * @param destination The destination node. + */ + public MovementPulse(Entity mover, Node destination) { + this(mover, destination, null, false); + } + + /** + * Constructs a new {@code MovementPulse} {@code Object}. + * + * @param mover The moving entity. + * @param destination The destination node. + * @param forceRun If the entity is forced to run. + */ + public MovementPulse(Entity mover, Node destination, boolean forceRun) { + this(mover, destination, null, forceRun); + } + + /** + * Constructs a new {@code MovementPulse} {@code Object}. + * + * @param mover The moving entity. + * @param destination The destination node. + * @param pathfinder The pathfinder to use. + */ + public MovementPulse(Entity mover, Node destination, Pathfinder pathfinder) { + this(mover, destination, pathfinder, false); + } + + /** + * Constructs a new {@code MovementPulse} {@code Object}. + * + * @param mover The moving entity. + * @param destination The destination node. + * @param optionHandler The option handler used. + */ + public MovementPulse(Entity mover, Node destination, OptionHandler optionHandler) { + this(mover, destination, null, false); + this.optionHandler = optionHandler; + } + + /** + * Constructs a new {@code MovementPulse} {@code Object}. + * + * @param mover The moving entity. + * @param destination The destination node. + * @param useHandler The use with handler used. + */ + public MovementPulse(Entity mover, Node destination, UseWithHandler useHandler) { + this(mover, destination, null, false); + this.useHandler = useHandler; + } + + /** + * Constructs a new {@code MovementPulse} {@code Object}. + * + * @param mover The moving entity. + * @param destination The destination node. + * @param destinationFlag The destination flag. + */ + public MovementPulse(Entity mover, Node destination, DestinationFlag destinationFlag) { + this(mover, destination, null, false); + this.destinationFlag = destinationFlag; + } + + public MovementPulse(Entity mover, Node destination, DestinationFlag destinationFlag, Function2 method){ + this(mover,destination,null,false); + this.destinationFlag = destinationFlag; + this.overrideMethod = method; + } + + /** + * Constructs a new {@code MovementPulse} {@code Object}. + * + * @param mover The moving entity. + * @param destination The destination node. + * @param pathfinder The pathfinder to use. + * @param forceRun If the entity is forced to run. + */ + public MovementPulse(Entity mover, Node destination, Pathfinder pathfinder, boolean forceRun) { + super(1, mover, destination); + this.mover = mover; + this.destination = destination; + if (pathfinder == null) { + if (mover instanceof Player) { + this.pathfinder = Pathfinder.SMART; + } else if (mover instanceof NPC) { + NPC npc = (NPC)mover; + NPCBehavior behavior = npc.behavior; + Pathfinder pf = behavior != null ? behavior.getPathfinderOverride(npc) : null; + this.pathfinder = pf != null ? pf : Pathfinder.DUMB; + } else { + this.pathfinder = Pathfinder.DUMB; + } + } else { + this.pathfinder = pathfinder; + } + this.forceRun = forceRun; + + if (destination instanceof NPC || destination instanceof Player) + destinationFlag = DestinationFlag.ENTITY; + + if (mover.currentMovement != null) { + mover.currentMovement.stop(); + mover.getWalkingQueue().reset(); + } + mover.currentMovement = this; + } + + private void clearInferiorScripts() { + mover.scripts.removeWeakScripts(); + mover.scripts.removeNormalScripts(); + } + + @Override + public boolean update() { + if (!mover.getViewport().getRegion().isActive()) + return false; + + if (!isRunning()) return true; + + if (!validate()) { + stop(); + return true; + } + + clearInferiorScripts(); + + mover.face(null); + updatePath(); + + if (tryInteract()) { + stop(); + return true; + } + + return false; + } + + private boolean tryInteract() { + Location ml = mover.getLocation(); + // Allow being within 1 square of moving entities to interact with them. + int radius = destination instanceof Entity && ((Entity)destination).getWalkingQueue().hasPath() ? 1 : 0; + if (interactLocation == null) + return false; + if (Math.max(Math.abs(ml.getX() - interactLocation.getX()), Math.abs(ml.getY() - interactLocation.getY())) <= radius) { + try { + if (near || pulse()) { + if (mover instanceof Player) { + if (near) { + ((Player) mover).getPacketDispatch().sendMessage("I can't reach that."); + } + PacketRepository.send(ClearMinimapFlag.class, new PlayerContext((Player) mover)); + } + stop(); + return true; + } + } catch (Exception e){ + e.printStackTrace(); + stop(); + } + } + return false; + } + + private boolean validate() { + if (mover == null || destination == null || mover.getViewport().getRegion() == null || hasInactiveNode()) { + return false; + } + return isRunning(); + } + + @Override + public void stop() { + super.stop(); + if (destination instanceof Entity) { + mover.face(null); + } + last = null; + } + + /** + * Finds a path to the destination, if necessary. + */ + private boolean usingTruncatedPath = false; + private boolean isMoveNearSet = false; + public void updatePath() { + if (mover instanceof NPC && mover.asNpc().isNeverWalks()) { + return; + } + if(destination == null || destination.getLocation() == null){ + return; + } + + Location loc = null; + + if (optionHandler != null) { + loc = optionHandler.getDestination(mover, destination); + } + else if (useHandler != null) { + loc = useHandler.getDestination((Player) mover, destination); + } + else if (isInsideEntity(mover.getLocation())) { + loc = findBorderLocation(); + } + + if (loc == null && destinationFlag != null && overrideMethod == null) { + loc = destinationFlag.getDestination(mover, destination); + } + else if(loc == null && overrideMethod != null){ + loc = overrideMethod.invoke(mover,destination); + if(loc == destination.getLocation() && destinationFlag != null) loc = destinationFlag.getDestination(mover,destination); + else if (loc == destination.getLocation()) loc = null; + } + + if (destination instanceof NPC && mover.getProperties().getCombatPulse().getVictim() != destination) + loc = checkForEntityPathInterrupt(loc != null ? loc : destination.getLocation()); + + if (interactLocation == null) + interactLocation = loc; + + if (destination instanceof Entity || interactLocation == null || (mover.getWalkingQueue().getQueue().size() <= 1 && interactLocation.getDistance(mover.getLocation()) > 0) || (usingTruncatedPath && destination.getLocation().getDistance(mover.getLocation()) < 14)) { + if (!checkAllowMovement()) + return; + if (destination instanceof Entity && previousLoc != null && previousLoc.equals(loc) && mover.getWalkingQueue().hasPath()) + return; + + Path path; + Pair truncation = truncateLoc(mover, loc != null ? loc : destination.getLocation()); + if (truncation.getFirst()) { + path = Pathfinder.find(mover, truncation.getSecond(), true, pathfinder); + usingTruncatedPath = true; + } else { + path = Pathfinder.find(mover, loc != null ? loc : destination, true, pathfinder); + interactLocation = null; //reset interactLocation so the below code can set it to the properly-pathfound last bit of path. + usingTruncatedPath = false; + } + near = !path.isSuccessful() || path.isMoveNear(); + + if (!path.getPoints().isEmpty()) { + Point point = path.getPoints().getLast(); + if (forceRun) { + mover.getWalkingQueue().reset(forceRun); + } else { + mover.getWalkingQueue().reset(); + } + int size = path.getPoints().toArray().length; + Deque points = path.getPoints(); + for (int i = 0; i < size; i++) { + point = path.getPoints().pop(); + mover.getWalkingQueue().addPath(point.getX(), point.getY()); + if (destination instanceof Entity) { + mover.face((Entity) destination); + } else { + mover.face(null); + } + + if (i == size - 1 && interactLocation == null) + interactLocation = Location.create(point.getX(), point.getY(), mover.getLocation().getZ()); + } + } + previousLoc = loc; + } + last = destination.getLocation(); + if (mover instanceof Player && mover.getAttribute("draw-intersect", false)) { + clearHintIcon((Player) mover); + registerHintIcon((Player) mover, interactLocation, 5); + } + } + + private boolean checkAllowMovement() { + boolean canMove = true; + if (destination instanceof Entity) { + Entity e = (Entity) destination; + Location l = e.getLocation(); + Deque npcPath = e.getWalkingQueue().getQueue(); + if (e.getWalkingQueue().hasPath() && e.getProperties().getCombatPulse().isRunning() && e.getProperties().getCombatPulse().getVictim() == mover) + canMove = false; + if (!canMove) { //If we normally shouldn't move, but the NPC's pathfinding is not letting them move, then move. + if (npcPath.size() == 1) { + Point pathElement = npcPath.peek(); + if (pathElement.getX() == l.getX() && pathElement.getY() == l.getY()) + canMove = true; + } + } + } + return canMove; + } + + private Location checkForEntityPathInterrupt(Location loc) { + Location ml = mover.getLocation(); + Location dl = destination.getLocation(); + // Lead the target if they're walking/running, unless they're already within interaction range + if(loc != null && destination instanceof Entity) { + WalkingQueue wq = ((Entity)destination).getWalkingQueue(); + if(wq.hasPath()) { + Point[] points = wq.getQueue().toArray(new Point[0]); + if(points.length > 0) { + Point p = points[0]; + Point predictiveIntersection = null; + for(int i=0; i> 1, size >> 1, 0); + Location center = mover.getLocation().transform(mover.size() >> 1, mover.size() >> 1, 0); + Direction direction = Direction.getLogicalDirection(centerDest, center); + Location delta = Location.getDelta(centerDestLoc, mover.getLocation()); + main: + for (int i = 0; i < 4; i++) { + int amount = 0; + switch (direction) { + case NORTH: + amount = size - delta.getY(); + break; + case EAST: + amount = size - delta.getX(); + break; + case SOUTH: + amount = mover.size() + delta.getY(); + break; + case WEST: + amount = mover.size() + delta.getX(); + break; + default: + return null; + } + for (int j = 0; j < amount; j++) { + for (int s = 0; s < mover.size(); s++) { + switch (direction) { + case NORTH: + if (!direction.canMove(mover.getLocation().transform(s, j + mover.size(), 0))) { + direction = Direction.get((direction.toInteger() + 1) & 3); + continue main; + } + break; + case EAST: + if (!direction.canMove(mover.getLocation().transform(j + mover.size(), s, 0))) { + direction = Direction.get((direction.toInteger() + 1) & 3); + continue main; + } + break; + case SOUTH: + if (!direction.canMove(mover.getLocation().transform(s, -(j + 1), 0))) { + direction = Direction.get((direction.toInteger() + 1) & 3); + continue main; + } + break; + case WEST: + if (!direction.canMove(mover.getLocation().transform(-(j + 1), s, 0))) { + direction = Direction.get((direction.toInteger() + 1) & 3); + continue main; + } + break; + default: + return null; + } + } + } + Location location = mover.getLocation().transform(direction, amount); + return location; + } + return null; + } + + /** + * Checks if the mover is standing on an invalid position. + * + * @param l The location. + * @return {@code True} if so. + */ + private boolean isInsideEntity(Location l) { + if (!(destination instanceof Entity)) { + return false; + } + if (((Entity) destination).getWalkingQueue().isMoving()) { + return false; + } + Location loc = destination.getLocation(); + int size = destination.size(); + return Pathfinder.isStandingIn(l.getX(), l.getY(), mover.size(), mover.size(), loc.getX(), loc.getY(), size, size); + } + + /** + * Gets the forceRun. + * + * @return The forceRun. + */ + public boolean isForceRun() { + return forceRun; + } + + /** + * Sets the forceRun. + * + * @param forceRun The forceRun to set. + */ + public void setForceRun(boolean forceRun) { + this.forceRun = forceRun; + } + + /** + * Sets the current destination. + * + * @param destination The destination. + */ + public void setDestination(Node destination) { + this.destination = destination; + } + + /** + * Sets the last location. + * + * @param last The last location. + */ + public void setLast(Location last) { + this.last = last; + } + +} diff --git a/Server/src/main/core/game/interaction/NodeUsageEvent.java b/Server/src/main/core/game/interaction/NodeUsageEvent.java new file mode 100644 index 0000000..7f81703 --- /dev/null +++ b/Server/src/main/core/game/interaction/NodeUsageEvent.java @@ -0,0 +1,95 @@ +package core.game.interaction; + +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +/** + * Represents a node use-with (other node) option. + * @author Emperor + */ +public final class NodeUsageEvent { + + /** + * The player. + */ + private final Player player; + + /** + * The component id. + */ + private final int componentId; + + /** + * The used node. + */ + private final Node used; + + /** + * The node we used the other node on. + */ + private final Node with; + + /** + * Constructs a new {@code NodeUsageEvent} {@code Object}. + * @param player The player. + * @param componentId The component id. + * @param used The used node. + * @param with The node the other node is used on. + */ + public NodeUsageEvent(Player player, int componentId, Node used, Node with) { + this.player = player; + this.componentId = componentId; + this.used = used; + this.with = with; + } + + /** + * Gets the base item. + * @return The base item. + */ + public Item getBaseItem() { + return with instanceof Item ? (Item) with : null; + } + + /** + * Gets the used item. + * @return The used item. + */ + public Item getUsedItem() { + return used instanceof Item ? (Item) used : null; + } + + /** + * Gets the player. + * @return The player. + */ + public Player getPlayer() { + return player; + } + + /** + * Gets the componentId. + * @return The componentId. + */ + public int getComponentId() { + return componentId; + } + + /** + * Gets the used. + * @return The used. + */ + public Node getUsed() { + return used; + } + + /** + * The node the other node is used on. + * @return The node. + */ + public Node getUsedWith() { + return with; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/interaction/Option.java b/Server/src/main/core/game/interaction/Option.java new file mode 100644 index 0000000..8c99a1b --- /dev/null +++ b/Server/src/main/core/game/interaction/Option.java @@ -0,0 +1,128 @@ +package core.game.interaction; + +import core.cache.def.impl.ItemDefinition; +import core.cache.def.impl.NPCDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; + +/** + * Represents an Interaction option. + * @author Emperor + */ +public final class Option { + + /** + * The player attack option. + */ + public static final Option _P_ATTACK = new Option("Attack", 0); + + /** + * The player follow option. + */ + public static final Option _P_FOLLOW = new Option("Follow", 2); + + /** + * The player trade option. + */ + public static final Option _P_TRADE = new Option("Trade with", 3); + public static final Option _P_GIVETO = new Option("Give-to", 3); + + public static final Option _P_PICKPOCKET = new Option("Pickpocket", 4); + + + public static final Option _P_EXAMINE = new Option("Examine", 7); + + /** + * The player assist option. + */ + public static final Option _P_ASSIST = new Option("Req Assist", 6); + + /** + * A null option. + */ + public static final Option NULL = new Option("null", 0); + + /** + * The option name. + */ + private final String name; + + /** + * The index. + */ + private final int index; + + /** + * The option handler. + */ + private OptionHandler handler; + + /** + * Constructs a new {@code Interaction} {@code Object}. + * @param name The name. + * @param index The index. + */ + public Option(String name, int index) { + this.name = name; + this.index = index; + } + + /** + * Gets the default option handler for the given name. + * @param node The node type that has this option. + * @param nodeId The id of the node. + * @param name The name of the option. + * @return The default option handler for this option. + */ + public static OptionHandler defaultHandler(Node node, int nodeId, String name) { + name = name.toLowerCase(); + if (node instanceof NPC) { + return NPCDefinition.getOptionHandler(nodeId, name); + } + if (node instanceof Scenery) { + return SceneryDefinition.getOptionHandler(nodeId, name); + } + if (node instanceof Item) { + return ItemDefinition.getOptionHandler(nodeId, name); + } + + return null; + } + + /** + * Gets the name. + * @return The name. + */ + public String getName() { + return name; + } + + /** + * Gets the index. + * @return The index. + */ + public int getIndex() { + return index; + } + + /** + * Gets the handler. + * @return The handler. + */ + public OptionHandler getHandler() { + return handler; + } + + /** + * Sets the handler. + * @param handler The handler to set. + * @return This option instance. + */ + public Option setHandler(OptionHandler handler) { + this.handler = handler; + return this; + } +} diff --git a/Server/src/main/core/game/interaction/OptionHandler.java b/Server/src/main/core/game/interaction/OptionHandler.java new file mode 100644 index 0000000..057bdac --- /dev/null +++ b/Server/src/main/core/game/interaction/OptionHandler.java @@ -0,0 +1,96 @@ +package core.game.interaction; + +import core.cache.def.impl.SceneryDefinition; +import core.game.node.Node; +import core.game.node.entity.player.Player; +import core.tools.Log; +import core.tools.SystemLogger; +import core.game.world.map.Location; +import core.plugin.Plugin; + +import java.util.ArrayList; +import java.util.List; + +import static core.api.ContentAPIKt.log; + +/** + * Handles an interaction option. + * @author Emperor + */ +public abstract class OptionHandler implements Plugin { + + /** + * Handles the interaction option. + * @param player The player who used the option. + * @param node The node the player selected an option on. + * @param option The option selected. + * @return {@code True} if successful. + */ + public abstract boolean handle(Player player, Node node, String option); + + /** + * Checks if the option should be handled after 1 game tick. + * @param player The player. + * @return {@code True} if so. + */ + public boolean isDelayed(Player player) { + return true; + } + + /** + * Checks if it needs a walk.. + * @param node the node. + * @return true if so. + */ + public boolean isWalk(final Player player, final Node node) { + return false; + } + + /** + * Gets the walk. + * @return if a walk is required. + */ + public boolean isWalk() { + return true; + } + + /** + * Gets the custom destination for the node. + * @param n The moving node. + * @param node The node to walk to. + * @return The custom destination, or {@code null} if we should use the + * default destination. + */ + public Location getDestination(Node n, Node node) { + return null; + } + + /** + * Gets the valid children for the wrapper id. + * @param wrapper the wrapper id. + * @return the valid children. + */ + public int[] getValidChildren(int wrapper) { + final SceneryDefinition definition = SceneryDefinition.forId(wrapper); + final List list = new ArrayList<>(20); + if (definition.getChildrenIds() == null) { + log(this.getClass(), Log.ERR, "Null child wrapper in option handler wrapperId=" + wrapper); + return new int[] { wrapper }; + } + for (int child : definition.getChildrenIds()) { + if (child != -1 && !list.contains(child)) { + list.add(child); + } + } + int[] array = new int[list.size()]; + for (int i = 0; i < list.size(); i++) { + array[i] = list.get(i); + } + return array; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/interaction/PluginInteraction.java b/Server/src/main/core/game/interaction/PluginInteraction.java new file mode 100644 index 0000000..ecb8708 --- /dev/null +++ b/Server/src/main/core/game/interaction/PluginInteraction.java @@ -0,0 +1,36 @@ +package core.game.interaction; + +import core.game.interaction.NodeUsageEvent; +import core.game.interaction.Option; +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Plugin; + +public abstract class PluginInteraction implements Plugin { + int[] ids; + Item item; + public boolean handle(Player player, Node node){ + return false; + }; + public boolean handle(Player player, NodeUsageEvent event){ + return false; + }; + public boolean handle(Player player, NPC npc, Option option){ + return false; + } + public boolean handle(Player player, Item item, Option option){return false;} + public PluginInteraction(int... ids){ + this.ids = ids; + } + public PluginInteraction(Item item){this.item = item;} + + public void setIds(int[] ids) { + this.ids = ids; + } + + public void setItem(Item item) { + this.item = item; + } +} diff --git a/Server/src/main/core/game/interaction/PluginInteractionManager.java b/Server/src/main/core/game/interaction/PluginInteractionManager.java new file mode 100644 index 0000000..1f2eadb --- /dev/null +++ b/Server/src/main/core/game/interaction/PluginInteractionManager.java @@ -0,0 +1,83 @@ +package core.game.interaction; + +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; + +import java.util.HashMap; + +public class PluginInteractionManager { + private static final HashMap npcInteractions = new HashMap<>(); + private static final HashMap objectInteractions = new HashMap<>(); + private static final HashMap useWithInteractions = new HashMap<>(); + private static final HashMap groundItemInteractions = new HashMap<>(); + + public static void register(PluginInteraction interaction, InteractionType type){ + switch(type){ + case OBJECT: + for(int i = 0; i < interaction.ids.length; i++){ + objectInteractions.putIfAbsent(interaction.ids[i],interaction); + } + break; + case USEWITH: + for(int i = 0; i < interaction.ids.length; i++){ + useWithInteractions.putIfAbsent(interaction.ids[i],interaction); + } + break; + case NPC: + for(int i = 0; i < interaction.ids.length; i++){ + npcInteractions.putIfAbsent(interaction.ids[i],interaction); + } + break; + case ITEM: + for(int i = 0; i < interaction.ids.length; i++){ + groundItemInteractions.putIfAbsent(interaction.ids[i],interaction); + } + break; + } + } + + public static boolean handle(Player player, Scenery object){ + PluginInteraction i = objectInteractions.get(object.getId()); + if(i == null) { + return false; + } else { + return i.handle(player,object); + } + } + + public static boolean handle(Player player, NodeUsageEvent event){ + PluginInteraction i = useWithInteractions.get(event.getUsed().asItem().getId()); + if(i == null) { + return false; + } else { + return i.handle(player,event); + } + } + + public static boolean handle(Player player, NPC npc, Option option){ + PluginInteraction i = npcInteractions.get(npc.getId()); + if(i == null) { + return false; + } else { + return i.handle(player,npc,option); + } + } + + public static boolean handle(Player player, Item item, Option option){ + PluginInteraction i = groundItemInteractions.get(item.getId()); + if(i == null){ + return false; + } else { + return i.handle(player,item,option); + } + } + + public enum InteractionType{ + NPC, + OBJECT, + USEWITH, + ITEM; + } +} diff --git a/Server/src/main/core/game/interaction/Script.kt b/Server/src/main/core/game/interaction/Script.kt new file mode 100644 index 0000000..8950119 --- /dev/null +++ b/Server/src/main/core/game/interaction/Script.kt @@ -0,0 +1,25 @@ +package core.game.interaction + +import core.game.node.Node +import core.game.node.entity.player.Player + +typealias UseWithExecutor = (Player, Node, Node, Int) -> Boolean +typealias InteractExecutor = (Player, Node, Int) -> Boolean +typealias VoidExecutor = (Int) -> Boolean + +enum class QueueStrength { + WEAK, + NORMAL, + STRONG, + SOFT +} + +open class Script (val execution: T, val persist: Boolean) { + var state: Int = 0 + var nextExecution = 0 +} + +class Interaction(execution: InteractExecutor, val distance: Int, persist: Boolean) : Script(execution, persist) +class UseWithInteraction(execution: UseWithExecutor, val distance: Int, persist: Boolean, val used: Node, val with: Node) : Script(execution, persist) +class QueuedScript(executor: VoidExecutor, val strength: QueueStrength, persist: Boolean) : Script(executor, persist) +class QueuedUseWith(executor: UseWithExecutor, val strength: QueueStrength, persist: Boolean, val used: Node, val with: Node) : Script(executor, persist) \ No newline at end of file diff --git a/Server/src/main/core/game/interaction/ScriptProcessor.kt b/Server/src/main/core/game/interaction/ScriptProcessor.kt new file mode 100644 index 0000000..52c86b1 --- /dev/null +++ b/Server/src/main/core/game/interaction/ScriptProcessor.kt @@ -0,0 +1,303 @@ +package core.game.interaction + +import core.api.* +import core.game.node.Node +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.GroundItem +import core.game.node.scenery.Scenery +import core.game.world.GameWorld +import core.game.world.map.Location +import core.game.world.map.path.Pathfinder +import core.game.bots.AIPlayer +import core.tools.Log +import java.lang.Integer.max +import java.io.* + +class ScriptProcessor(val entity: Entity) { + private var apScript: Script<*>? = null + private var opScript: Script<*>? = null + private var interactTarget: Node? = null + private var currentScript: Script<*>? = null + private val queue = ArrayList>() + + var delay = 0 + var interacted = false + var apRangeCalled = false + var apRange = 10 + var persistent = false + var targetDestination: Location? = null + + fun preMovement() { + var allSkipped = false + while (!allSkipped) { + allSkipped = processQueue() + } + + if (isStunned(entity)) return + if (entity.delayed()) return + + var canProcess = !entity.delayed() + if (entity is Player && entity !is AIPlayer) + canProcess = canProcess && !entity.hasModalOpen() + + if (entity !is Player) return + if (!entity.delayed() && canProcess && interactTarget != null) { + if (opScript != null && inOperableDistance()) { + face(entity, interactTarget?.getFaceLocation(entity.location) ?: return reset()) + processInteractScript(opScript ?: return reset()) + } + else if (apScript != null && inApproachDistance(apScript ?: return reset())) { + face(entity, interactTarget?.getFaceLocation(entity.location) ?: return reset()) + processInteractScript(apScript ?: return reset()) + } + else if (apScript == null && opScript == null && inOperableDistance()) { + sendMessage(entity, "Nothing interesting happens.") + } + } + } + + fun postMovement(didMove: Boolean) { + if (didMove) + entity.clocks[Clocks.MOVEMENT] = GameWorld.ticks + if (entity.walkingQueue.isRunning) 0 else 1 + var canProcess = !entity.delayed() + if (entity is Player && entity !is AIPlayer) + canProcess = canProcess && !entity.interfaceManager.isOpened && !entity.interfaceManager.hasChatbox() + + if (entity !is Player) return + if (!entity.delayed() && canProcess && interactTarget != null && !interacted) { + if (opScript != null && inOperableDistance()) { + face(entity, interactTarget?.centerLocation ?: return reset()) + processInteractScript(opScript ?: return reset()) + } + else if (apScript != null && inApproachDistance(apScript ?: return reset())) { + face(entity, interactTarget?.centerLocation ?: return reset()) + processInteractScript(apScript ?: return reset()) + } + else if (apScript == null && opScript == null && inOperableDistance()) { + sendMessage(entity, "Nothing interesting happens.") + } + } + if (canProcess && (apScript != null || opScript != null)) { + if (!interacted && !didMove && finishedMoving(entity)) { + sendMessage(entity, "I can't reach that!") + reset() + } + } + if (interacted && !apRangeCalled && !persistent) reset() + if (interactTarget != null && interactTarget?.isActive != true) reset() + } + + fun processQueue() : Boolean { + var strongInQueue = false + var softInQueue = false + var anyExecuted = false + strongInQueue = hasTypeInQueue(QueueStrength.STRONG) + softInQueue = hasTypeInQueue(QueueStrength.SOFT) + + if (strongInQueue) { + if (entity is Player) { + closeAllInterfaces(entity) + } + } + + if (strongInQueue) { + removeWeakScripts() + } + + val toRemove = ArrayList>() + + for (i in 0 until queue.size) { + when (val script = queue[i]) { + is QueuedScript -> { + if (entity.delayed() && script.strength != QueueStrength.SOFT) + continue + if (script.nextExecution > GameWorld.ticks) + continue + if ((script.strength == QueueStrength.STRONG) && entity is Player) { + closeAllInterfaces(entity) + } + script.nextExecution = GameWorld.ticks + 1 + val finished = executeScript(script) + script.state++ + if (finished && !script.persist) + toRemove.add(script) + else if (finished) + script.state = 0 + anyExecuted = true + } + is QueuedUseWith -> { + if (entity.delayed() && script.strength != QueueStrength.SOFT) + continue + if (entity !is Player) { + toRemove.add(script) + log(this::class.java, Log.ERR, "Tried to queue an item UseWith interaction for a non-player!") + continue + } + if (script.nextExecution > GameWorld.ticks) + continue + if ((script.strength == QueueStrength.STRONG)) { + closeAllInterfaces(entity) + } + script.nextExecution = GameWorld.ticks + 1 + val finished = executeScript(script) + script.state++ + if (finished && !script.persist) + toRemove.add(script) + else if (finished) + script.state = 0 + anyExecuted = true + } + } + } + + queue.removeAll(toRemove.toSet()) + return !anyExecuted + } + + fun isPersist (script: Script<*>) : Boolean { + return script.persist + } + + fun processInteractScript(script: Script<*>) { + if (interactTarget == null || !interactTarget!!.isActive) { + log(this::class.java, Log.FINE, "Interact target $interactTarget no longer active, cancelling interaction.") + reset() + } + if (script.nextExecution < GameWorld.ticks) { + val finished = executeScript(script) + script.state++ + if (finished && isPersist(script)) + script.state = 0 + interacted = true + } + } + + fun executeScript(script: Script<*>) : Boolean { + currentScript = script + try { + when (script) { + is Interaction -> return script.execution.invoke(entity as? Player ?: return true, interactTarget ?: return true, script.state) + is UseWithInteraction -> return script.execution.invoke(entity as? Player ?: return true, script.used, script.with, script.state) + is QueuedScript -> return script.execution.invoke(script.state) + is QueuedUseWith -> return script.execution.invoke(entity as? Player ?: return true, script.used, script.with, script.state) + } + } catch (e: Exception) { + val sw = StringWriter() + val pw = PrintWriter(sw) + e.printStackTrace(pw) + log(this::class.java, Log.ERR, "Error processing ${script::class.java.simpleName} - stopping the script. Exception follows: $sw") + reset() + } + currentScript = null + return true + } + + fun removeWeakScripts() { + queue.removeAll(queue.filter { it is QueuedScript && it.strength == QueueStrength.WEAK || it is QueuedUseWith && it.strength == QueueStrength.WEAK }.toSet()) + } + + fun removeNormalScripts() { + queue.removeAll(queue.filter { it is QueuedScript && it.strength == QueueStrength.NORMAL || it is QueuedUseWith && it.strength == QueueStrength.NORMAL }.toSet()) + } + + fun inApproachDistance(script: Script<*>) : Boolean { + val distance = when (script) { + is Interaction -> script.distance + is UseWithInteraction -> script.distance + else -> 10 + } + targetDestination?.let { + return it.location.getDistance(entity.location) <= distance && hasLineOfSight(entity, it) + } + return false + } + + fun inOperableDistance() : Boolean { + targetDestination?.let { + return it.cardinalTiles.any {loc -> loc == entity.location} && hasLineOfSight(entity, it) + } + return false + } + + fun reset() { + apScript = null + opScript = null + currentScript = null + apRangeCalled = false + interacted = false + apRange = 10 + interactTarget = null + persistent = false + targetDestination = null + resetAnimator(entity as? Player ?: return) + } + + fun setInteractionScript(target: Node, script: Script<*>?) { + if (apScript != null && script != null && script.execution == apScript!!.execution) return + if (opScript != null && script != null && script.execution == opScript!!.execution) return + reset() + interactTarget = target + if (script != null) { + apRange = when(script) { + is Interaction -> script.distance + is UseWithInteraction -> script.distance + else -> 10 + } + persistent = script.persist + if (apRange == -1) + opScript = script + else + apScript = script + targetDestination = when (interactTarget) { + is NPC -> DestinationFlag.ENTITY.getDestination(entity, interactTarget) + is Scenery -> { + val basicPath = Pathfinder.find(entity, interactTarget) + val path = basicPath.points.lastOrNull() + if (basicPath.isMoveNear) { + target.location + return + } + if (path == null) { + clearScripts(entity) + return + } + Location.create(path.x, path.y, entity.location.z) + } + is GroundItem -> DestinationFlag.ITEM.getDestination(entity, interactTarget) + else -> target.location + } + } + } + + fun addToQueue(script: Script<*>, strength: QueueStrength) { + if (script !is QueuedScript && script !is QueuedUseWith) { + log(this::class.java, Log.ERR, "Tried to queue ${script::class.java.simpleName} as a queueable script but it's not!") + return + } + if (strength == QueueStrength.STRONG && entity is Player) { + closeAllInterfaces(entity) + } + script.nextExecution = max(GameWorld.ticks + 1, script.nextExecution) + queue.add(script) + } + + fun getActiveScript() : Script<*>? { + return currentScript ?: getActiveInteraction() + } + + private fun getActiveInteraction() : Script<*>? { + return opScript ?: apScript + } + + fun hasTypeInQueue (type: QueueStrength) : Boolean { + for (script in queue) { + if (script is QueuedScript && script.strength == type) + return true + else if (script is QueuedUseWith && script.strength == type) + return true + } + return false + } +} diff --git a/Server/src/main/core/game/interaction/SpecialGroundInteraction.java b/Server/src/main/core/game/interaction/SpecialGroundInteraction.java new file mode 100644 index 0000000..0fe6180 --- /dev/null +++ b/Server/src/main/core/game/interaction/SpecialGroundInteraction.java @@ -0,0 +1,15 @@ +package core.game.interaction; + +import core.game.node.entity.player.Player; + +/** + * Stub class for special ground item interactions + * @author ceik + */ +public class SpecialGroundInteraction { + public void handle(Player player, Option option){ + } + public void configure(){ + + } +} diff --git a/Server/src/main/core/game/interaction/SpecialGroundItems.java b/Server/src/main/core/game/interaction/SpecialGroundItems.java new file mode 100644 index 0000000..9e73242 --- /dev/null +++ b/Server/src/main/core/game/interaction/SpecialGroundItems.java @@ -0,0 +1,30 @@ +package core.game.interaction; + +import content.region.asgarnia.portsarim.handlers.AhabBeerInteraction; +import core.game.node.item.GroundItem; +import core.game.node.item.GroundItemManager; +import core.game.world.map.Location; + +/** + * Handles interactions for special ground items + * @author ceik + */ +public enum SpecialGroundItems { + //Ahab's beer + AHAB_BEER(1917,new Location(3049,3257,0), new AhabBeerInteraction()); + + private int itemid; + private Location location; + private SpecialGroundInteraction inter; + + SpecialGroundItems(int itemId, Location location, SpecialGroundInteraction inter){ + this.itemid = itemId; + this.location = location; + this.inter = inter; + } + + public SpecialGroundInteraction getInteraction() { return inter;} + public int getItemid() {return itemid;} + public Location getLocation() {return location;} + public GroundItem asGroundItem(){return GroundItemManager.get(itemid,location,null);} +} diff --git a/Server/src/main/core/game/interaction/UseWithHandler.java b/Server/src/main/core/game/interaction/UseWithHandler.java new file mode 100644 index 0000000..4c5a6f4 --- /dev/null +++ b/Server/src/main/core/game/interaction/UseWithHandler.java @@ -0,0 +1,277 @@ +package core.game.interaction; + +import core.game.event.UseWithEvent; +import core.cache.def.impl.SceneryDefinition; +import core.game.node.Node; +import core.game.node.entity.impl.PulseType; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.tools.Log; +import core.tools.SystemLogger; +import core.game.system.task.Pulse; +import core.game.world.map.Location; +import core.plugin.Plugin; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static core.api.ContentAPIKt.log; + +/** + * Handles the "use {@code node a} with {@code node b}" option. + * + * @author Emperor + */ +public abstract class UseWithHandler implements Plugin { + + /** + * The item type. + */ + public static final int ITEM_TYPE = 0; + + /** + * The NPC type. + */ + public static final int NPC_TYPE = 1; + + /** + * The object type. + */ + public static final int OBJECT_TYPE = 2; + + /** + * The player type. + */ + public static final int PLAYER_TYPE = 3; + + /** + * The handlers. + */ + private static final Map> HANDLERS = new HashMap<>(); + + /** + * The allowed node ids. + */ + private int[] allowedNodes; + + /** + * Constructs a new {@code UseWithHandler.java} {@code Object}. + * + * @param allowedNodes + */ + public UseWithHandler(int... allowedNodes) { + this.allowedNodes = allowedNodes; + } + + public UseWithHandler(ArrayList allowedNodes){ + this.allowedNodes = allowedNodes.stream().mapToInt(i -> i).toArray(); + } + + public void setAllowedNodes(ArrayList allowedNodes){ + this.allowedNodes = allowedNodes.stream().mapToInt(i -> i).toArray(); + } + + /** + * Adds a handler. + * + * @param id The node id. + * @param type The node type (0=item, 1=NPC, 2=object, 3=player). + * @param handler The handler. + */ + public static void addHandler(int id, int type, UseWithHandler handler) { + int key = id | type << 16; + List handlers = HANDLERS.get(key); + if (handlers == null) { + HANDLERS.put(key, handlers = new ArrayList<>(20)); + } + if (type == PLAYER_TYPE) { + if (handler.allowedNodes == null) { + handler.allowedNodes = new int[]{id}; + } else { + int[] array = handler.allowedNodes; + handler.allowedNodes = new int[handler.allowedNodes.length + 1]; + System.arraycopy(array, 0, handler.allowedNodes, 0, array.length); + handler.allowedNodes[handler.allowedNodes.length - 1] = id; + } + } + handlers.add(handler); + } + + /** + * Runs the event. + * + * @param event The event. + */ + public static void run(final NodeUsageEvent event) { + try { + if (event.getPlayer() != null) { + event.getPlayer().getInterfaceManager().close(); + } + Node n = event.getUsedWith(); + List handler = null; + if (n instanceof Item) { + handler = HANDLERS.get(((Item) event.getUsed()).getId());// fixed. + if (handler == null) { + handler = HANDLERS.get(((Item) event.getUsedWith()).getId()); + } + } else if (n instanceof NPC) { + handler = HANDLERS.get(((NPC) n).getId() | NPC_TYPE << 16); + } else if (n instanceof Scenery) { + handler = HANDLERS.get(((Scenery) n).getId() | OBJECT_TYPE << 16); + } else if (n instanceof Player) { + handler = HANDLERS.get(((Item) event.getUsed()).getId() | PLAYER_TYPE << 16); + } else { + handler = HANDLERS.get(((NPC) n).getId() | NPC_TYPE << 16); + } + if (handler == null) { + if (n instanceof Item && !(event.getUsed() instanceof Player)) { + event.getPlayer().getPulseManager().runUnhandledAction(event.getPlayer(), PulseType.STANDARD); + } else { + event.getPlayer().getPulseManager().run(new MovementPulse(event.getPlayer(), event.getUsedWith()) { + @Override + public boolean pulse() { + event.getPlayer().debug("Unhandled use with interaction:"); + event.getPlayer().debug("Used: " + event.getUsed()); + event.getPlayer().debug("With: " + event.getUsedWith()); + event.getPlayer().getPacketDispatch().sendMessage("Nothing interesting happens."); + return true; + } + }, PulseType.STANDARD); + } + return; + } + final List handlers = handler; + if (n instanceof Item && !(event.getUsed() instanceof Player)) { + event.getPlayer().getPulseManager().run(new Pulse(1, event.getPlayer(), event.getUsed(), event.getUsedWith()) { + @Override + public boolean pulse() { + event.getPlayer().dispatch(new UseWithEvent(event.getUsed().getId(), event.getUsedWith().getId())); + boolean handled = false; + if (event.getPlayer() != null) { + event.getPlayer().getInterfaceManager().close(); + } + for (UseWithHandler h : handlers) { + if (!h.nodeAllowed(((Item) event.getUsedWith()).getId()) && !h.nodeAllowed(event.getUsedItem().getId()) || !h.handle(event)) {// fixed, + continue; + } + event.getPlayer().debug("Handler=" + h.getClass().getSimpleName() + ", used item=" + event.getUsedItem() + ", used with=" + event.getUsedWith()); + handled = true; + break; + } + if (!handled) { + event.getPlayer().debug("Handler=none, used item=" + event.getUsedItem()); + event.getPlayer().debug("used with=" + event.getUsedWith()); + event.getPlayer().getPacketDispatch().sendMessage("Nothing interesting happens."); + } + return true; + } + }, PulseType.STANDARD); + return; + } + event.getPlayer().getPulseManager().run(new MovementPulse(event.getPlayer(), event.getUsedWith(), handler.get(0)) { + @Override + public boolean pulse() { + event.getPlayer().dispatch(new UseWithEvent(event.getUsed().getId(), event.getUsedWith().getId())); + event.getPlayer().faceLocation(event.getUsedWith().getFaceLocation(event.getPlayer().getLocation())); + boolean handled = false; + Item used = (Item) event.getUsed(); + for (UseWithHandler h : handlers) { + if ((used != null && !h.nodeAllowed(used.getId())) || !h.handle(event)) { + continue; + } + event.getPlayer().debug("Handler=" + h.getClass().getSimpleName() + ", used item=" + event.getUsedItem() + ", used with=" + event.getUsedWith()); + handled = true; + break; + } + if (!handled) { + event.getPlayer().debug("Handler=none, used item=" + event.getUsedItem() + ", used with=" + event.getUsedWith()); + event.getPlayer().getPacketDispatch().sendMessage("Nothing interesting happens."); + } + return true; + } + }, PulseType.STANDARD); + } catch (Exception e){ + e.printStackTrace(); + } + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + /** + * Gets the valid children for the wrapper id. + * + * @param wrapper the wrapper id. + * @return the valid children. + */ + public int[] getValidChildren(int wrapper) { + final SceneryDefinition definition = SceneryDefinition.forId(wrapper); + final List list = new ArrayList<>(20); + if (definition.getChildrenIds() == null) { + log(this.getClass(), Log.ERR, "Null child wrapper in option handler wrapperId=" + wrapper); + return new int[]{wrapper}; + } + for (int child : definition.getChildrenIds()) { + if (child != -1 && !list.contains(child)) { + list.add(child); + } + } + int[] array = new int[list.size()]; + for (int i = 0; i < list.size(); i++) { + array[i] = list.get(i); + } + return array; + } + + /** + * Method used to get the destination to go to, leave null to go to proper + * one. + * + * @param player the player. + * @return the location. + */ + public Location getDestination(Player player, Node with) { + return null; + } + + /** + * Checks if the node is allowed to be used with the base node. + * + * @param nodeId The node id. + * @return {@code True} if so. + */ + public boolean nodeAllowed(int nodeId) { + if (isDynamic()) { + return true; + } + for (int id : allowedNodes) { + if (nodeId == id) { + return true; + } + } + return false; + } + + /** + * Handles the interaction option. + * + * @param event The node usage event. + * @return {@code True} if successful. + */ + public abstract boolean handle(NodeUsageEvent event); + + /** + * Checks if the handler excepts all dynamic items. + * + * @return {@code True} if so. + */ + public boolean isDynamic() { + return false; + } +} diff --git a/Server/src/main/core/game/node/Node.java b/Server/src/main/core/game/node/Node.java new file mode 100644 index 0000000..2e93e60 --- /dev/null +++ b/Server/src/main/core/game/node/Node.java @@ -0,0 +1,295 @@ +package core.game.node; + +import core.game.interaction.DestinationFlag; +import core.game.interaction.InteractPlugin; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.tools.StringUtils; +import core.api.utils.Vector; + +/** + * Represents a node which is anything that is interactable in 2009Scape. + * @author Emperor + */ +public abstract class Node { + + /** + * The name of the node; + */ + protected String name; + + /** + * The location. + */ + protected Location location; + + /** + * The index of the node. + */ + protected int index; + + /** + * The node's direction. + */ + protected Direction direction; + + /** + * The node's size. + */ + protected int size = 1; + + /** + * If the node is active. + */ + protected boolean active = true; + + /** + * The interaction instance. + */ + protected InteractPlugin interactPlugin; + + /** + * The destination flag. + */ + protected DestinationFlag destinationFlag; + + /** + * If the node is renderable. + */ + protected boolean renderable = true; + + /** + * Constructs a new {@code Node} {@code Object}. + * @param name The name. + * @param location The location. + */ + public Node(String name, Location location) { + this.name = name; + this.location = location; + } + + /** + * Casts the npc to a player. + * @return the npc. + */ + public NPC asNpc() { + return (NPC) this; + } + + /** + * Casts the player. + * @return the player. + */ + public Player asPlayer() { + return (Player) this; + } + + /** + * Casts the scenery. + * @return the object. + */ + public Scenery asScenery() { + return (Scenery) this; + } + + /** + * Casts the item. + * @return the item. + */ + public Item asItem() { + return (Item) this; + } + + /** + * Gets the node id. + * @return the id. + */ + public int getId() { + return this instanceof NPC ? ((NPC) this).getId() : this instanceof Scenery ? ((Scenery) this).getId() : this instanceof Item ? ((Item) this).getId() : -1; + } + + /** + * Gets the node id hash (only relevant if the node is an item). + * @return the id hash. + */ + public int getIdHash() { + return this instanceof Item ? ((Item) this).getIdHash() : -1; + } + + /** + * Gets the center location. + * @return The center location. + */ + public Location getCenterLocation() { + int offset = size >> 1; + return location.transform(offset, offset, 0); + } + + public Vector getMathematicalCenter() { + Location topRight = location.transform(size - 1, size - 1, 0); + double x = ((double) location.getX() + (double) topRight.getX()) / 2.0; + double y = ((double) location.getY() + (double) topRight.getY()) / 2.0; + return new Vector(x, y); + } + + public Location getFaceLocation (Location fromLoc) { + Vector center = getMathematicalCenter(); + Vector fromVec = new Vector((double) fromLoc.getX(), (double) fromLoc.getY()); + Vector difference = fromVec.minus(center); + Vector end = center.plus(difference.invert()); + return Location.create((int)end.getX(), (int)end.getY(), fromLoc.getZ()); + } + + /** + * Gets the name of this node. + * @return The name. + */ + public String getName() { + return name; + } + + /** + * Get a formated username. + * @return The username. + */ + public String getUsername() { + return StringUtils.formatDisplayName(name); + } + + /** + * Gets the index. + * @return The index. + */ + public int getIndex() { + return index; + } + + /** + * Sets the index. + * @param index The index to set. + */ + public void setIndex(int index) { + this.index = index; + } + + /** + * Gets the location. + * @return The location. + */ + public Location getLocation() { + return location; + } + + /** + * Sets the location. + * @param location The location to set. + */ + public void setLocation(Location location) { + this.location = location; + } + + /** + * Gets the direction. + * @return The direction. + */ + public Direction getDirection() { + return direction; + } + + /** + * Sets the direction. + * @param direction The direction to set. + */ + public void setDirection(Direction direction) { + if (direction == null) + return; + this.direction = direction; + } + + /** + * Gets the size. + * @return The size. + */ + public int size() { + return size; + } + + /** + * Sets the size. + * @param size The size to set. + */ + public void setSize(int size) { + this.size = size; + } + + /** + * Gets the active. + * @return The active. + */ + public boolean isActive() { + return active; + } + + /** + * Sets the active. + * @param active The active to set. + */ + public void setActive(boolean active) { + this.active = active; + } + + /** + * Gets the interaction. + * @return The interaction. + */ + public InteractPlugin getInteraction() { + if (interactPlugin != null && !interactPlugin.isInitialized()) { + interactPlugin.setDefault(); + } + return interactPlugin; + } + + /** + * Sets the interaction. + * @param interactPlugin The interaction to set. + */ + public void setInteraction(InteractPlugin interactPlugin) { + this.interactPlugin = interactPlugin; + } + + /** + * Gets the destinationFlag. + * @return The destinationFlag. + */ + public DestinationFlag getDestinationFlag() { + return destinationFlag; + } + + /** + * Sets the destinationFlag. + * @param destinationFlag The destinationFlag to set. + */ + public void setDestinationFlag(DestinationFlag destinationFlag) { + this.destinationFlag = destinationFlag; + } + + /** + * Gets the renderable. + * @return The renderable. + */ + public boolean isRenderable() { + return renderable; + } + + /** + * Sets the renderable. + * @param renderable The renderable to set. + */ + public void setRenderable(boolean renderable) { + this.renderable = renderable; + } +} diff --git a/Server/src/main/core/game/node/entity/Entity.java b/Server/src/main/core/game/node/entity/Entity.java new file mode 100644 index 0000000..b566ccc --- /dev/null +++ b/Server/src/main/core/game/node/entity/Entity.java @@ -0,0 +1,989 @@ +package core.game.node.entity; + +import core.game.event.*; +import core.game.interaction.*; +import core.game.node.Node; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.DeathTask; +import core.game.node.entity.combat.ImpactHandler; +import core.game.node.entity.combat.equipment.ArmourSet; +import core.game.node.entity.impl.*; +import core.game.node.entity.impl.Properties; +import core.game.node.entity.lock.ActionLocks; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.TeleportManager; +import core.game.node.entity.skill.Skills; +import core.game.system.task.Pulse; +import core.game.world.map.zone.ZoneRestriction; +import org.jetbrains.annotations.NotNull; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.Viewport; +import core.game.world.map.path.Path; +import core.game.world.map.path.Pathfinder; +import core.game.world.map.zone.ZoneMonitor; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.game.world.update.flag.*; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.world.update.UpdateMasks; +import core.game.system.timer.TimerManager; +import core.game.system.timer.TimerRegistry; + +import java.util.*; + +/** + * An entity is a movable node, such as players and NPCs. + * @author Emperor + */ +public abstract class Entity extends Node { + + /** + * The entity's properties. + */ + private final Properties properties = new Properties(this); + + /** + * The entity's update masks. + */ + private final UpdateMasks updateMasks = new UpdateMasks(this); + + /** + * The walking queue. + */ + private final WalkingQueue walkingQueue = new WalkingQueue(this); + + /** + * The entity's skills. + */ + public Skills skills = new Skills(this); + + /** + * The entity's extension classes. + */ + private final Map, Object> extensions = new HashMap, Object>(); + + /** + * The entity's attributes. + */ + private final GameAttributes attributes = new GameAttributes(); + + /** + * The entity's viewport. + */ + private final Viewport viewport = new Viewport(); + + /** + * The pulse manager. + */ + private final PulseManager pulseManager = new PulseManager(); + + /** + * The impact handler. + */ + private final ImpactHandler impactHandler = new ImpactHandler(this); + + /** + * The animator. + */ + private final Animator animator = new Animator(this); + + /** + * The teleporter. + */ + private final TeleportManager teleporter = new TeleportManager(this); + + /** + * The zone monitor. + */ + private final ZoneMonitor zoneMonitor = new ZoneMonitor(this); + + /** + * The reward locks. + */ + private final ActionLocks locks = new ActionLocks(); + public ScriptProcessor scripts = new ScriptProcessor(this); + public final int[] clocks = new int[10]; + + public MovementPulse currentMovement; + + + /** + * The mapping of event types to event hooks + */ + private HashMap, ArrayList> hooks = new HashMap<>(); + public TimerManager timers = new TimerManager(this); + + /** + * If the entity is invisible. + */ + private boolean invisible; + + + + /** + * Constructs a new {@code Entity} {@code Object}. + * @param name The name of the entity. + * @param location The location. + */ + public Entity(String name, Location location) { + super(name, location); + super.destinationFlag = DestinationFlag.ENTITY; + } + + /** + * Attempts to make the entity move one step (priority order: west, south, + * east, north). + */ + public void moveStep() { + if (locks.isMovementLocked()) { + return; + } + Path path; + if (!(path = Pathfinder.find(this, getLocation().transform(-1, 0, 0), false, Pathfinder.DUMB)).isSuccessful()) { + if (!(path = Pathfinder.find(this, getLocation().transform(0, -1, 0), false, Pathfinder.DUMB)).isSuccessful()) { + if (!(path = Pathfinder.find(this, getLocation().transform(1, 0, 0), false, Pathfinder.DUMB)).isSuccessful()) { + if (!(path = Pathfinder.find(this, getLocation().transform(0, 1, 0), false, Pathfinder.DUMB)).isSuccessful()) { + path = null; + } + } + } + } + if (path != null) { + path.walk(this); + } + } + + /** + * Dispatches an event to this entity's event hooks + */ + public void dispatch(Event event) + { + if(this.hooks.containsKey(event.getClass())) + { + ArrayList processList = new ArrayList(this.hooks.get(event.getClass())); + processList.forEach((hook) -> { hook.process(this, event); }); + } + } + + /** + * Unhooks an eventhook from this entity + */ + public void unhook(EventHook hook) + { + for(ArrayList s : hooks.values()) s.remove(hook); + } + + /** + * Hooks an eventhook to this entity + */ + public void hook(Event event, EventHook hook) + { + hook(event.getClass(), hook); + } + + public void hook(Class event, EventHook hook) + { + ArrayList hookList; + if(hooks.get(event) != null) + { + hookList = hooks.get(event); + } + else + { + hookList = new ArrayList(); + } + if (!hookList.contains(hook)) + hookList.add(hook); + hooks.put(event, hookList); + } + + /** + * Initializes the entity. + */ + public void init() { + active = true; + TimerRegistry.addAutoTimers (this); + } + + /** + * This methods gets called before the {@link #update()} method. + */ + public void tick() { + scripts.preMovement(); + dispatch(new TickEvent(GameWorld.getTicks())); + skills.pulse(); + Location old = location != null ? location.transform(0, 0, 0) : Location.create(0,0,0); + walkingQueue.update(); + scripts.postMovement(!Objects.equals(location, old)); + timers.processTimers(); + updateMasks.prepare(this); + } + + /** + * Updates the entity, this gets called in a thread pool. + */ + public void update() { + } + + /** + * Resets the entity's update flags, ...
Gets called after + * {@link #update()}. + */ + public void reset() { + updateMasks.reset(); + properties.setTeleporting(false); + } + + /** + * Removes the entity from the world. + */ + public void clear() { + active = false; + viewport.remove(this); + pulseManager.clear(); + } + + /** + * Checks if the entity is in combat. + * @return {@code True} if so. + */ + public boolean inCombat() { + return getAttribute("combat-time", 0L) > System.currentTimeMillis(); + } + + /** + * Fully restores the entity. + */ + public void fullRestore() { + skills.restore(); + timers.removeTimer("poison"); + timers.removeTimer("poison:immunity"); + } + + /** + * Called when the death task gets submitted. + * @param killer The killer of this entity. + */ + public void commenceDeath(Entity killer) { + } + + /** + * Finalizes the death task. + * @param killer The killer of this entity. + */ + public void finalizeDeath(Entity killer) { + skills.restore(); + skills.rechargePrayerPoints(); + impactHandler.getImpactQueue().clear(); + impactHandler.setDisabledTicks(10); + timers.onEntityDeath(); + removeAttribute("combat-time"); + face(null); + //Check if it's a Loar shade and transform back into the shadow version. + if(this.getId() == 1240 || this.getId() == 1241){ + this.asNpc().transform(1240); + } + } + + /** + * Updates the location of an entity. + * @param last the last location. + */ + public void updateLocation(Location last) { + + } + + /** + * Checks if multiway combat zone rules should be ignored. + * @param victim The victim. + * @return {@code True} if this entity can attack regardless of multiway + * combat zone. + */ + public boolean isIgnoreMultiBoundaries(Entity victim) { + if (this instanceof NPC) { + return ((NPC) this).behavior.shouldIgnoreMultiRestrictions((NPC) this, victim); + } + return false; + } + + /** + * Should this entity prevent the mover from moving through it? + */ + public boolean shouldPreventStacking(Entity mover) { + return false; + } + + /** + * Checks an impact before receiving it. + */ + public void checkImpact(BattleState state) { + getProperties().getCombatPulse().setLastReceivedAttack(GameWorld.getTicks()); + int ticks = GameWorld.getTicks() - getProperties().getCombatPulse().getLastSentAttack(); + if (ticks > 10 && this instanceof NPC && ((NPC) this).getDefinition().getConfiguration("safespot", false)) { + Pathfinder.find(state.getAttacker(), getLocation()).walk(state.getAttacker()); + Pathfinder.find(state.getVictim(), state.getAttacker().getLocation()).walk(state.getVictim()); + if (ticks > 40) { + state.getAttacker().moveStep(); + state.getAttacker().getProperties().getCombatPulse().stop(); + state.getVictim().moveStep(); + state.getVictim().getProperties().getCombatPulse().stop(); + } + } + } + + /** + * Handles an impact. + * @param entity The entity. + * @param state The battle state. + */ + public void onImpact(final Entity entity, BattleState state) { + if (DeathTask.isDead(this)) + state.neutralizeHits(); + if (this instanceof NPC) { + ((NPC) this).behavior.afterDamageReceived((NPC) this, entity, state); + } + if (properties.isRetaliating() && !properties.getCombatPulse().isAttacking() && !getLocks().isInteractionLocked() && properties.getCombatPulse().getNextAttack() < GameWorld.getTicks()) { + if (!getWalkingQueue().hasPath() && !getPulseManager().isMovingPulse() || (this instanceof NPC)) { + properties.getCombatPulse().attack(entity); + } + } + } + + /** + * Handles the first attack. + * @param target the target. + */ + public void onAttack(final Entity target) { + + } + + /** + * Method used to attack a node. + * @param node the node. + */ + public void attack(final Node node) { + getProperties().getCombatPulse().attack(node); + } + + /** + * Checks if the entity can move to the destination. + * @param destination the destination. + * @return {@code True} if so. + */ + public boolean canMove(Location destination) { + return true; + } + + /** + * Teleports the entity to a location. + * @param location the location. + */ + public void teleport(Location location) { + getProperties().setTeleportLocation(location); + } + + /** + * Teleports the entity. + * @param location the location. + * @param ticks the ticks. + */ + public void teleport(final Location location, int ticks) { + GameWorld.getPulser().submit(new Pulse(ticks, this) { + @Override + public boolean pulse() { + teleport(location); + return true; + } + }); + } + + /** + * Locks the entity. + */ + public void lock() { + locks.lock(); + } + + /** + * Locks the entity from using any actions. + * @param time The time (in game ticks) to lock. + */ + public void lock(int time) { + locks.lock(time); + } + + /** + * Unlocks the default reward locks. + */ + public void unlock() { + locks.unlock(); + } + + /** + * Checks if the entity is using the protection prayer for the given style. + * @param style The combat style. + * @return {@code True} if so. + */ + public abstract boolean hasProtectionPrayer(CombatStyle style); + + /** + * Gets the dragonfire protection value. + * @param fire if a fire attack. + * @return The value. + */ + public abstract int getDragonfireProtection(boolean fire); + + /** + * Checks if this entity is attackable by the attacking entity. + * @param entity The attacking entity. + * @param style The combat style used. + * @param message Whether to send the player a message indicating why the entity isn't attackable. + * @return {@code True} if the attacking entity can attack this entity. + */ + public boolean isAttackable(Entity entity, CombatStyle style, boolean message) { + if (DeathTask.isDead(this)) { + return false; + } + if (!entity.getZoneMonitor().continueAttack(this, style, message)) { + return false; + } + return true; + } + + /** + * Registers a new graphics update flag to the update masks. + * @param graphics The graphics. + * @return {@code True} if succesful. + */ + public boolean graphics(Graphics graphics) { + return animator.graphics(graphics); + } + + /** + * Registers a new animation update flag to the update masks. + * @param animation The animation. + * @return {@code True} if succesful. + */ + public boolean animate(Animation animation) { + return animator.animate(animation); + } + + /** + * Registers a new graphics update flag. + * @param graphics the graphics. + * @param delay the delay. + * @return {@code True} if so. + */ + public boolean graphics(final Graphics graphics, int delay) { + GameWorld.getPulser().submit(new Pulse(delay, this) { + @Override + public boolean pulse() { + graphics(graphics); + return true; + } + }); + return true; + } + + /** + * Checks if an entity can continue its attack. + * @param target the target. + * @param style the style. + * @return {@code True} if so. + */ + public boolean continueAttack(Entity target, CombatStyle style, boolean message) { + return true; + } + + /** + * Registers a new animation update flag to the update masks. + * @param animation The animation. + * @param delay the delay + * @return {@code True} if succesful. + */ + public boolean animate(final Animation animation, int delay) { + GameWorld.getPulser().submit(new Pulse(delay, this) { + @Override + public boolean pulse() { + animate(animation); + return true; + } + }); + return true; + } + + /** + * Sends the impact. + * @param state the state. + */ + public void sendImpact(BattleState state) { + getProperties().getCombatPulse().setLastSentAttack(GameWorld.getTicks()); + } + + /** + * Checks if the target can be selected. + * @param target the target. + * @return {@code True} if so. + */ + public boolean canSelectTarget(Entity target) { + return true; + } + + /** + * Registers a new animation & graphic update flag to the update masks. + * @param animation The animation. + * @param graphics The graphics. + * @return {@code True} if successful. + */ + public boolean visualize(Animation animation, Graphics graphics) { + return animator.animate(animation, graphics); + } + + /** + * Temporarily faces an entity. + * @param entity The entity to face. + * @param ticks The ticks to face the entity. + * @return {@code True} if successful. + */ + public boolean faceTemporary(Entity entity, int ticks) { + return faceTemporary(entity, null, ticks); + } + + /** + * Temporarily faces an entity. + * @param entity The entity to face. + * @param reset The entity to face when the pulse has passed. + * @param ticks The ticks to face the entity. + * @return {@code True} if successful. + */ + public boolean faceTemporary(Entity entity, final Entity reset, int ticks) { + if (face(entity)) { + GameWorld.getPulser().submit(new Pulse(ticks + 1, this) { + @Override + public boolean pulse() { + face(reset); + return true; + } + }); + return true; + } + return false; + } + + /** + * Gets the formatted hit. + * @param state the state. + * @param hit the hit. + * @return {@code True} if so. + */ + public double getFormattedHit(BattleState state, int hit) { + if (state.getAttacker() == null || state.getVictim() == null || state.getStyle() == null) { + return hit; + } + Entity entity = state.getAttacker(); + Entity victim = state.getVictim(); + CombatStyle type = state.getStyle(); + if (state.getArmourEffect() != ArmourSet.VERAC && !entity.isIgnoreProtection(type) && victim.hasProtectionPrayer(type)) { + return hit *= (entity instanceof Player && victim instanceof Player) ? 0.6 : 0; + } + return hit; + } + + /** + * Checks if this entity ignores protection prayers for the given combat style. + * @param style The combat style used. + * @return {@code True} if the entity can hit through protection prayers. + */ + public boolean isIgnoreProtection(CombatStyle style) { + return false; + } + + /** + * Starts the death for an npc. + * @param killer the killer. + */ + public void startDeath(Entity killer) { + if (zoneMonitor.startDeath(this, killer)) { + DeathTask.startDeath(this, killer); + } + } + + /** + * Casts the player type. + * @return the player. + */ + public Player asPlayer() { + return (Player) this; + } + + /** + * Checks if the entity is instance of a player. + * @return {@code True} if so. + */ + public boolean isPlayer() { + return this instanceof Player; + } + + /** + * Registers a new face entity update flag to the update masks. + * @param entity The entity to face. + * @return {@code True} if succesful. + */ + public boolean face(Entity entity) { + if (entity == null) { + int ordinal = EntityFlags.getOrdinal(EFlagType.of(this), EntityFlag.FaceEntity); + if (getUpdateMasks().unregisterSynced(ordinal)) { + return getUpdateMasks().register(EntityFlag.FaceEntity, null); + } + return true; + } + return getUpdateMasks().register(EntityFlag.FaceEntity, entity, true); + } + + /** + * Registers a new face location update flag to the update masks. + * @param location The location to face. + * @return {@code True} if succesful. + */ + public boolean faceLocation(Location location) { + if (location == null) { + int ordinal = EntityFlags.getOrdinal(EFlagType.of(this), EntityFlag.FaceLocation); + getUpdateMasks().unregisterSynced(ordinal); + return true; + } + return getUpdateMasks().register(EntityFlag.FaceLocation, location, true); + } + + /** + * Registers a new force chat update flag to the update masks. + * @param string The string. + * @return {@code True} if successful. + */ + public boolean sendChat(String string) { + return getUpdateMasks().register(EntityFlag.ForceChat, string); + } + + /** + * Gets the current combat swing handler. + * @param swing If this method is called when actually performing a combat + * swing. + * @return The current combat swing handler to use. + */ + public abstract CombatSwingHandler getSwingHandler(boolean swing); + + /** + * Checks if the entity is immune to poison. + * @return {@code True} if the entity is immune to poison. + */ + public abstract boolean isPoisonImmune(); + + /** + * Sends the chat on a tick. + * @param string the string. + * @param ticks the ticks. + */ + public void sendChat(final String string, int ticks) { + GameWorld.getPulser().submit(new Pulse(ticks, this) { + @Override + public boolean pulse() { + sendChat(string); + return true; + } + }); + } + + /** + * Gets the level mod. + * @param entity the entity. + * @param victim the victim. + * @return the levelMod. + */ + public double getLevelMod(Entity entity, Entity victim) { + return 0; + } + + /** + * Gets the reward locks. + * @return The reward locks. + */ + public ActionLocks getLocks() { + return locks; + } + + /** + * Gets the client index of the entity. + * @return The client index. + */ + public int getClientIndex() { + return index; + } + + /** + * Gets the properties. + * @return The properties. + */ + public Properties getProperties() { + return properties; + } + /** + * Gets the updateMasks. + * @return The updateMasks. + */ + public UpdateMasks getUpdateMasks() { + return updateMasks; + } + + /** + * Adds an extension. + * @param clazz The class type. + * @param object The object. + */ + public void addExtension(Class clazz, Object object) { + extensions.put(clazz, object); + } + + /** + * Gets an extension. + * @param clazz The class type. + * @return The object. + */ + @SuppressWarnings("unchecked") + public T getExtension(Class clazz) { + return (T) extensions.get(clazz); + } + + /** + * Gets an extension. + * @param clazz The class type. + * @param fail The object to return if the extension wasn't added. + * @return The object. + */ + @SuppressWarnings("unchecked") + public T getExtension(Class clazz, T fail) { + T extension = (T) extensions.get(clazz); + if (extension == null) { + return fail; + } + return extension; + } + + /** + * Removes the extension. + * @param clazz The class type. + */ + public void removeExtension(Class clazz) { + extensions.remove(clazz); + } + + /** + * Gets the players attributes. + * @return the attributes. + */ + public Map getAttributes() { + return attributes.getAttributes(); + } + + public void clearAttributes() { + this.attributes.getAttributes().clear(); + this.attributes.getSavedAttributes().clear(); + } + + /** + * Sets an attribute value. + * @param key The attribute name. + * @param value The attribute value. + */ + public void setAttribute(String key, Object value) { + attributes.setAttribute(key, value); + dispatch(new AttributeSetEvent(this, key, value)); + } + + /** + * Gets an attribute. + * @param key The attribute name. + * @return The attribute value. + */ + public T getAttribute(String key) { + return attributes.getAttribute(key); + } + + /** + * Increments an attribute + * @param key The attribute name. + */ + public void incrementAttribute(String key) { + incrementAttribute(key, 1); + } + + /** + * Increments an attribute + * @param key The attribute name. + */ + public void incrementAttribute(String key, int amount) { + attributes.setAttribute(key, attributes.getAttribute(key, 0) + amount); + } + + /** + * Gets an attribute. + * @param string The attribute name. + * @param fail The value to return if the attribute is null. + * @return The attribute value, or the fail argument when null. + */ + public T getAttribute(String string, T fail) { + return attributes.getAttribute(string, fail); + } + + /** + * Removes an attribute. + * @param string The attribute name. + */ + public void removeAttribute(String string) { + attributes.removeAttribute(string); + dispatch(new AttributeRemoveEvent(this, string)); + } + + /** + * Gets the game attributes instance. + * @return The game attributes. + */ + public GameAttributes getGameAttributes() { + return attributes; + } + + /** + * Gets the walkingQueue. + * @return The walkingQueue. + */ + public WalkingQueue getWalkingQueue() { + return walkingQueue; + } + + /** + * Gets the viewport. + * @return The viewport. + */ + public Viewport getViewport() { + return viewport; + } + + /** + * Gets the skills. + * @return The skills. + */ + public Skills getSkills() { + return skills; + } + + /** + * Gets the pulseManager. + * @return The pulseManager. + */ + public PulseManager getPulseManager() { + return pulseManager; + } + + /** + * Gets the impactHandler. + * @return The impactHandler. + */ + public ImpactHandler getImpactHandler() { + return impactHandler; + } + + /** + * @return the animator. + */ + public Animator getAnimator() { + return animator; + } + + /** + * Gets the Teleporter + * @return the Teleporter + */ + public TeleportManager getTeleporter() { + return teleporter; + } + + /** + * Gets the zoneMonitor. + * @return The zoneMonitor. + */ + public ZoneMonitor getZoneMonitor() { + return zoneMonitor; + } + + /** + * Checks if we have fire resistance. + * @return {@code True} if so. + */ + public boolean hasFireResistance() { + return getAttribute("fire:immune",0) >= GameWorld.getTicks(); + } + + /** + * Checks if the entity is teleblocked. + * @return {@code True} if so. + */ + public boolean isTeleBlocked() { + return timers.getTimer("teleblock") != null || getLocks().isTeleportLocked() || getZoneMonitor().isRestricted(ZoneRestriction.TELEPORT); + } + + /** + * Gets the invisible value. + * @return The invisible. + */ + public boolean isInvisible() { + return invisible; + } + + /** + * Sets the invisible value. + * @param invisible The invisible to set. + */ + public void setInvisible(boolean invisible) { + this.invisible = invisible; + } + + public Location getClosestOccupiedTile(@NotNull Location other) { + List occupied = getOccupiedTiles(); + + Location closest = location; + if (occupied.size() > 1) { + double lowest = 9999; + for (Location tile : occupied) { + double dist = tile.getDistance(other); + if (dist < lowest) { + lowest = dist; + closest = tile; + } + } + } + + return closest; + } + + public List getOccupiedTiles() { + ArrayList occupied = new ArrayList<>(); + + Location northEast = location.transform(size, size, 0); + + for (int x = location.getX(); x < northEast.getX(); x++) { + for (int y = location.getY(); y < northEast.getY(); y++) { + occupied.add(Location.create(x, y, location.getZ())); + } + } + return occupied; + } + + public boolean delayed() { + return scripts.getDelay() > GameWorld.getTicks(); + } + + public boolean isTeleporting() { + return getAttribute("tele-pulse", null) != null || properties.getTeleportLocation() != null; + } +} diff --git a/Server/src/main/core/game/node/entity/combat/BattleState.java b/Server/src/main/core/game/node/entity/combat/BattleState.java new file mode 100644 index 0000000..e75aac1 --- /dev/null +++ b/Server/src/main/core/game/node/entity/combat/BattleState.java @@ -0,0 +1,354 @@ +package core.game.node.entity.combat; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.equipment.Ammunition; +import core.game.node.entity.combat.equipment.ArmourSet; +import core.game.node.entity.combat.equipment.RangeWeapon; +import core.game.node.entity.combat.equipment.Weapon; +import core.game.node.entity.combat.spell.CombatSpell; + +/** + * Represents an entity's current battle state. + * @author Emperor + */ +public final class BattleState { + + /** + * The entity. + */ + private Entity entity; + + /** + * The victim entity. + */ + private Entity victim; + + /** + * The estimated hit. + */ + private int estimatedHit; + + /** + * The maximum hit. + */ + private int maximumHit; + + /** + * The second estimated hit. + */ + private int secondaryHit = -1; + + /** + * The amount of recoil damage. + */ + private int recoilDamage = -1; + + /** + * The amount of poison damage. + */ + private int poisonDamage = -1; + + /** + * If the victim is frozen. + */ + private boolean frozen; + + /** + * The other targets. + */ + private BattleState[] targets; + + /** + * The weapon used. + */ + private Weapon weapon; + + /** + * The range weapon used. + */ + private RangeWeapon rangeWeapon; + + /** + * The range ammunition used. + */ + private Ammunition ammunition; + + /** + * The magic spell used. + */ + private CombatSpell spell; + + /** + * The combat style used (used for style-switching NPCs). + */ + private CombatStyle style; + + /** + * The active armour set effect. + */ + private ArmourSet armourEffect; + + /** + * Constructs a new {@code BattleState} {@code Object}. + */ + public BattleState() { + /* + * empty. + */ + } + + /** + * Constructs a new {@code BattleState} {@Code Object} + * @param victim The victim entity. + */ + public BattleState(Entity entity, Entity victim) { + this.victim = victim; + this.entity = entity; + } + + /** + * Neutralizes the hits. + */ + public void neutralizeHits() { + if (getEstimatedHit() > 0) { + setEstimatedHit(0); + } + if (getSecondaryHit() > 0) { + setSecondaryHit(0); + } + } + + /** + * @return the victim. + */ + public Entity getVictim() { + return victim; + } + + /** + * @param victim the victim to set. + */ + public void setVictim(Entity victim) { + this.victim = victim; + } + + /** + * Gets the estimatedHit. + * @return The estimatedHit. + */ + public int getEstimatedHit() { + return estimatedHit; + } + + /** + * Sets the estimated hit. + * @param estimatedHit The estimated hit to set. + */ + public void setEstimatedHit(int estimatedHit) { + this.estimatedHit = estimatedHit; + } + + /** + * @return the secondaryHit. + */ + public int getSecondaryHit() { + return secondaryHit; + } + + /** + * @param secondaryHit the secondaryHit to set. + */ + public void setSecondaryHit(int secondaryHit) { + this.secondaryHit = secondaryHit; + } + + /** + * Gets the recoilDamage. + * @return The recoilDamage. + */ + public int getRecoilDamage() { + return recoilDamage; + } + + /** + * Sets the recoilDamage. + * @param recoilDamage The recoilDamage to set. + */ + public void setRecoilDamage(int recoilDamage) { + this.recoilDamage = recoilDamage; + } + + /** + * @return the targets. + */ + public BattleState[] getTargets() { + return targets; + } + + /** + * @param targets the targets to set. + */ + public void setTargets(BattleState[] targets) { + this.targets = targets; + } + + /** + * @return the poisonDamage. + */ + public int getPoisonDamage() { + return poisonDamage; + } + + /** + * @param poisonDamage the poisonDamage to set. + */ + public void setPoisonDamage(int poisonDamage) { + this.poisonDamage = poisonDamage; + } + + /** + * @return the weapon. + */ + public Weapon getWeapon() { + return weapon; + } + + /** + * @param weapon the weapon to set. + */ + public void setWeapon(Weapon weapon) { + this.weapon = weapon; + } + + /** + * @return the spell. + */ + public CombatSpell getSpell() { + return spell; + } + + /** + * @param spell the spell to set. + */ + public void setSpell(CombatSpell spell) { + this.spell = spell; + } + + /** + * Gets the maximumHit. + * @return The maximumHit. + */ + public int getMaximumHit() { + return maximumHit; + } + + /** + * Sets the maximumHit. + * @param maximumHit The maximumHit to set. + */ + public void setMaximumHit(int maximumHit) { + this.maximumHit = maximumHit; + } + + /** + * Gets the rangeWeapon. + * @return The rangeWeapon. + */ + public RangeWeapon getRangeWeapon() { + return rangeWeapon; + } + + /** + * Sets the rangeWeapon. + * @param rangeWeapon The rangeWeapon to set. + */ + public void setRangeWeapon(RangeWeapon rangeWeapon) { + this.rangeWeapon = rangeWeapon; + } + + /** + * Gets the ammunition. + * @return The ammunition. + */ + public Ammunition getAmmunition() { + return ammunition; + } + + /** + * Sets the ammunition. + * @param ammunition The ammunition to set. + */ + public void setAmmunition(Ammunition ammunition) { + this.ammunition = ammunition; + } + + /** + * Gets the frozen. + * @return The frozen. + */ + public boolean isFrozen() { + return frozen; + } + + /** + * Sets the frozen. + * @param frozen The frozen to set. + */ + public void setFrozen(boolean frozen) { + this.frozen = frozen; + } + + /** + * Gets the style. + * @return The style. + */ + public CombatStyle getStyle() { + return style; + } + + /** + * Sets the style. + * @param style The style to set. + */ + public void setStyle(CombatStyle style) { + this.style = style; + } + + /** + * Gets the armourEffect. + * @return The armourEffect. + */ + public ArmourSet getArmourEffect() { + return armourEffect; + } + + /** + * Sets the armourEffect. + * @param armourEffect The armourEffect to set. + */ + public void setArmourEffect(ArmourSet armourEffect) { + this.armourEffect = armourEffect; + } + + /** + * Gets the attacking entity. + * @return The entity. + */ + public Entity getAttacker() { + return entity; + } + + public int getTotalDamage() { + int hit = Math.max(estimatedHit, 0) + Math.max(secondaryHit, 0); + + if (targets != null) { + for (BattleState s : targets) { + if (s != null) { + hit += Math.max(s.getEstimatedHit(), 0) + Math.max(s.getSecondaryHit(), 0); + } + } + } + return hit; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/combat/CombatPulse.kt b/Server/src/main/core/game/node/entity/combat/CombatPulse.kt new file mode 100644 index 0000000..7e0475e --- /dev/null +++ b/Server/src/main/core/game/node/entity/combat/CombatPulse.kt @@ -0,0 +1,478 @@ +package core.game.node.entity.combat + +import content.global.ame.RandomEventNPC +import content.global.handlers.item.equipment.special.SalamanderSwingHandler +import core.game.container.impl.EquipmentContainer +import core.game.interaction.MovementPulse +import core.game.node.Node +import core.game.node.entity.Entity +import core.game.node.entity.combat.equipment.WeaponInterface +import core.game.node.entity.impl.Animator +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.game.world.GameWorld +import core.game.world.update.flag.context.Animation +import core.tools.RandomFunction +import core.api.* +import core.game.interaction.DestinationFlag +import core.game.system.timer.impl.* + +/** + * The combat-handling pulse implementation. + * @author Emperor + */ +class CombatPulse( + /** + * The entity. + */ + val entity: Entity?) : Pulse(1, entity, null) { + + /** + * The victim. + */ + private var victim: Entity? = null + + /** + * Gets the style. + * @return The style. + */ + /** + * Sets the style. + * @param style The style to set. + */ + /** + * The current combat style used. + */ + var style = CombatStyle.MELEE + + /** + * @return the temporaryHandler. + */ + /** + * @param temporaryHandler the temporaryHandler to set. + */ + /** + * The temporary combat swing handler. + */ + var temporaryHandler: CombatSwingHandler? = null + + /** + * Gets the handler. + * @return The handler. + */ + /** + * Sets the handler. + * @param handler The handler to set. + */ + /** + * The current combat swing handler. + */ + var handler = style.swingHandler + + /** + * @return the lastVictim. + */ + /** + * @param lastVictim the lastVictim to set. + */ + /** + * The last victim. + */ + var lastVictim: Entity? = null + + /** + * The tick value of when we can start another hit-cycle. + */ + private var nextAttack = -1 + + /** + * The combat time out counter. + */ + private var combatTimeOut = 0 + + /** + * The movement handling pulse. + */ + private val movement: MovementPulse + + /** + * The last attack sent. + */ + var lastSentAttack = 0 + + /** + * The last attack recieved. + */ + var lastReceivedAttack = 0 + + init { + running = false + } + + override fun pulse(): Boolean { + if (victim == null || DeathTask.isDead(entity) || DeathTask.isDead(victim)) { + return true + } + if (!entity!!.viewport.region.isActive || !victim!!.viewport.region.isActive) { + return true + } + if (!interactable()) { + return if (entity.walkingQueue.isMoving) { + false + } else combatTimeOut++ > entity.properties.combatTimeOut + } + combatTimeOut = 0 + entity.face(victim) + if (nextAttack <= GameWorld.ticks) { + victim ?: return false + val v: Entity = victim!! + var handler = temporaryHandler + if (handler == null) { + handler = entity.getSwingHandler(true) + } + if (!v.isAttackable(entity, handler!!.type, true) && entity != getAttribute(v, AntiMacro.EVENT_NPC, null)) { + return true + } + if (!swing(entity, victim, handler)) { + temporaryHandler = null + updateStyle() + return false + } + var speed = entity.properties.attackSpeed + val magic = handler!!.type == CombatStyle.MAGIC + val salamander = handler!! is SalamanderSwingHandler + if (entity is Player && magic) { + speed = 5 + } else if (entity.properties.attackStyle.style == WeaponInterface.STYLE_RAPID || (salamander && entity.properties.attackStyle.style == WeaponInterface.STYLE_RANGE_ACCURATE)) { + speed-- + } + if (!magic && hasTimerActive(entity)) { + speed = (speed * 1.5).toInt() + } + setNextAttack(speed) + temporaryHandler = null + setCombatFlags(v) + } + return victim != null && victim!!.skills.lifepoints < 1 || entity.skills.lifepoints < 1 + } + + /** + * Sets the "in combat" flag for the victim and handles closing. + * @param victim The victim. + */ + fun setCombatFlags(victim: Entity?) { + if (victim == null || entity == null) { + return + } + if (entity is Player) { + val p = entity + if (!p.attributes.containsKey("keepDialogueAlive")) { + p.interfaceManager.close() + p.interfaceManager.closeChatbox() + } + } + if (victim is Player) { + if (entity is Player && entity.skullManager.isWilderness) { + entity.skullManager.checkSkull(victim) + } + if (!victim.getAttributes().containsKey("keepDialogueAlive")) { + victim.interfaceManager.closeChatbox() + victim.interfaceManager.close() + } + } + if (!victim.pulseManager.isMovingPulse) { + victim.pulseManager.clear() + } + victim.setAttribute("combat-time", System.currentTimeMillis() + 10000) + victim.setAttribute("combat-attacker", entity) + } + + /** + * Checks if the mover can interact with the victim. + * @return `True` if so. + */ + private fun interactable(): Boolean { + if (victim == null) { + return false + } + if (entity is NPC && victim is Player && entity.isHidden(victim as Player?)) { + stop() + return false + } + if (victim is NPC && entity is Player && (victim as NPC).isHidden(entity as Player?)) { + stop() + return false + } + if (entity is NPC && !entity.asNpc().canStartCombat(victim)) { + stop() + return false + } + val type = canInteract() + if (type == InteractionType.STILL_INTERACT) { + return true + } + if (entity == null || victim == null || entity.locks.isMovementLocked) { + return false + } + movement.updatePath() + return type == InteractionType.MOVE_INTERACT + } + + /** + * Sets the combat style. + */ + fun updateStyle() { + if (entity == null) { + return + } + if (entity is Player) { + val p = entity + if (p.properties.spell != null) { + style = CombatStyle.MAGIC + return + } + if (p.properties.autocastSpell != null) { + style = CombatStyle.MAGIC + return + } + style = when (p.properties.attackStyle.bonusType) { + WeaponInterface.BONUS_MAGIC -> CombatStyle.MAGIC + WeaponInterface.BONUS_RANGE -> CombatStyle.RANGE + else -> CombatStyle.MELEE + } + } + } + + /** + * Attacks the node. + * @param victim The victim node. + */ + fun attack(victim: Node?) { + if (victim == null) { + return + } + if (entity!!.locks.isInteractionLocked) { + return + } + if (victim === this.victim && isAttacking) { + return + } + //makes sure lumbridge dummies can't attack back (lol) + if (victim is Player && (entity.id == 4474 || entity.id == 7891)) { + return + } + if(entity is Player) { + if ((victim.id == 4474 || victim.id == 7891) && entity.asPlayer().properties.combatLevel >= 30){ + entity.asPlayer().sendMessage("You are too experienced to gain anything from these.") + return + } + } + if (victim is NPC) { + if (entity is Player && victim !== this.victim && victim !== lastVictim) { + // Loar Shade Transformation Animation + val shade = Animation(1288, 0, Animator.Priority.VERY_HIGH) + val player = entity + val mask = player.equipment[EquipmentContainer.SLOT_HAT] + if (victim.getId() == 1240) { + victim.animate(shade) + victim.transform(1241) + } + if (mask != null && mask.id >= 8901 && mask.id < 8920 && RandomFunction.random(50) == 0) { + player.packetDispatch.sendMessage("Your black mask startles your enemy, you have " + + (if (mask.id == 8919) "no" else ((8920 - mask.id) / 2).toString()) + " charges left.") + player.equipment.replace(Item(mask.id + 2), EquipmentContainer.SLOT_HAT) + var drain = 3 + victim.skills.getLevel(Skills.DEFENCE) / 14 + if (drain > 10) { + drain = 10 + } + victim.skills.updateLevel(Skills.DEFENCE, -drain, victim.skills.getStaticLevel(Skills.DEFENCE) - drain) + } + } + if (!victim.locks.isMovementLocked) + victim.walkingQueue.reset() + } + setVictim(victim) + entity.onAttack(victim as Entity?) + victim.scripts.removeWeakScripts() + + if (!isAttacking) + entity.pulseManager.run(this) + } + + /** + * Sets the victim. + * @param victim The victim. + */ + fun setVictim(victim: Node?) { + super.addNodeCheck(1, victim) + movement.setLast(null) + movement.setDestination(victim) + this.victim = victim as Entity? + combatTimeOut = 0 + } + + /** + * Sets the next attack. + * @param ticks The amount of ticks. + */ + fun setNextAttack(ticks: Int) { + nextAttack = GameWorld.ticks + ticks + } + + /** + * Delays the next attack. + * @param ticks The amount of ticks to delay the next attack with. + */ + fun delayNextAttack(ticks: Int) { + nextAttack += ticks + } + + /** + * Gets the next attack tick. + * @return The next attack tick. + */ + fun getNextAttack(): Int { + return nextAttack + } + + /** + * Checks if we can fight with the victim. + * @return `True` if so. + */ + fun canInteract(): InteractionType? { + if (victim == null) { + return InteractionType.NO_INTERACT + } + return if (temporaryHandler != null) { + temporaryHandler!!.canSwing(entity!!, victim!!) + } else entity!!.getSwingHandler(false).canSwing(entity, victim!!) + } + + override fun start() { + super.start() + entity!!.face(victim) + entity.walkingQueue.reset() + } + + override fun stop() { + super.stop() + entity!!.setAttribute("combat-stop", GameWorld.ticks) + if (victim != null) { + lastVictim = victim + } + super.addNodeCheck(1, null.also { victim = it }) + entity.face(null) + entity.properties.spell = null + } + + override fun removeFor(pulseType: String): Boolean { + var pulse = pulseType + if (isAttacking) { + pulse = pulse.toLowerCase() + if (pulse.startsWith("interaction:attack")) { + if (victim.hashCode() == pulse.replace("interaction:attack:", "").toInt()) { + return false + } + } + } + return true + } + + /** + * Checks if this entity is attacking. + * @return `True` if so. + */ + val isAttacking: Boolean + get() = victim != null && victim!!.isActive && isRunning + + /** + * If the entity has an attacker. + * @return `True` if so. + */ + val isInCombat: Boolean + get() { + val entity = entity!!.getAttribute("combat-attacker") + return entity != null && entity.properties.combatPulse.isAttacking + } + + /** + * Gets the current victim. + * @return The victim. + */ + fun getVictim(): Entity? { + return victim + } + + companion object { + + /** + * Executes a combat swing. + * @param entity The entity. + * @param victim The victim. + * @param handler The combat swing handler. + * @return `True` if successfully started the swing. + */ + fun swing(entity: Entity?, victim: Entity?, handler: CombatSwingHandler?): Boolean { + val state = BattleState(entity, victim) + val set = handler!!.getArmourSet(entity) + entity!!.properties.armourSet = set + val delay = handler.swing(entity, victim, state) + if (delay < 0) { + return false + } + if (victim == null) { + entity.faceTemporary(victim, 1) // face back to entity. + } + handler.adjustBattleState(entity, victim!!, state) + handler.addExperience(entity, victim, state) + handler.visualize(entity, victim, state) + if (delay - 1 < 1) { + handler.visualizeImpact(entity, victim, state) + } + handler.visualizeAudio(entity, victim, state) + if (set != null && set.effect(entity, victim, state)) { + set.visualize(entity, victim) + } + GameWorld.Pulser.submit(object : Pulse(delay - 1, entity, victim) { + var impact = false + override fun pulse(): Boolean { + if (DeathTask.isDead(victim) || DeathTask.isDead(entity)) { + return true + } + if (entity is NPC) + entity.asNpc().behavior.beforeAttackFinalized(entity, victim, state) + if (impact || getDelay() == 0) { + if (state.estimatedHit != 0 && victim is NPC) { + val n = victim.asNpc() + val audio = n.getAudio(1) + if (audio != null) { + playGlobalAudio(victim.location, audio.id) + } + } else if (state.estimatedHit != 0 && victim is Player) { + playHurtAudio(victim.asPlayer()) + } + handler.impact(entity, victim, state) + handler.onImpact(entity, victim, state) + return true + } + setDelay(1) + impact = true + handler.visualizeImpact(entity, victim, state) + return false + } + }) + return true + } + } + + init { + movement = object : MovementPulse(entity, null) { + override fun pulse(): Boolean { + return false + } + } + } +} diff --git a/Server/src/main/core/game/node/entity/combat/CombatStyle.java b/Server/src/main/core/game/node/entity/combat/CombatStyle.java new file mode 100644 index 0000000..eaa4c31 --- /dev/null +++ b/Server/src/main/core/game/node/entity/combat/CombatStyle.java @@ -0,0 +1,62 @@ +package core.game.node.entity.combat; + +import core.game.node.entity.player.link.prayer.PrayerType; + +/** + * Represents the different styles of combat. + * @author Emperor + */ +public enum CombatStyle { + + /** + * The melee combat style. + */ + MELEE(new MeleeSwingHandler(), PrayerType.PROTECT_FROM_MELEE), + + /** + * The range combat style. + */ + RANGE(new RangeSwingHandler(), PrayerType.PROTECT_FROM_MISSILES), + + /** + * The magic combat style. + */ + MAGIC(new MagicSwingHandler(), PrayerType.PROTECT_FROM_MAGIC); + + /** + * The combat swing handler used by the combat style. + */ + private final CombatSwingHandler swingHandler; + + /** + * The protection prayer for this combat type. + */ + private final PrayerType protectionPrayer; + + /** + * Constructs a new {@code CombatStyle} {@code Object}. + * @param swingHandler The combat swing handler. + * @param protectionPrayer The protection prayer. + */ + private CombatStyle(CombatSwingHandler swingHandler, PrayerType protectionPrayer) { + this.swingHandler = swingHandler; + this.protectionPrayer = protectionPrayer; + swingHandler.setType(this); + } + + /** + * Gets the swingHandler. + * @return The swingHandler. + */ + public CombatSwingHandler getSwingHandler() { + return swingHandler; + } + + /** + * Gets the protectionPrayer. + * @return The protectionPrayer. + */ + public PrayerType getProtectionPrayer() { + return protectionPrayer; + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/combat/CombatSwingHandler.kt b/Server/src/main/core/game/node/entity/combat/CombatSwingHandler.kt new file mode 100644 index 0000000..748e258 --- /dev/null +++ b/Server/src/main/core/game/node/entity/combat/CombatSwingHandler.kt @@ -0,0 +1,673 @@ +package core.game.node.entity.combat + +import core.game.component.Component +import core.game.container.impl.EquipmentContainer +import core.game.node.Node +import core.game.node.entity.Entity +import core.game.node.entity.combat.equipment.* +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.audio.Audio +import core.game.node.entity.player.link.prayer.PrayerType +import core.game.node.entity.skill.Skills +import content.global.skill.summoning.familiar.Familiar +import core.api.log +import core.api.playGlobalAudio +import core.game.world.map.Direction +import core.game.world.map.Location +import core.game.world.map.RegionManager +import core.game.world.map.RegionManager.getClippingFlag +import core.game.world.map.path.Pathfinder +import core.game.world.map.path.Pathfinder.* +import core.game.world.update.flag.context.Animation +import core.tools.RandomFunction +import core.game.system.config.ItemConfigParser +import core.tools.Log +import org.rs09.consts.Sounds +import java.util.* +import kotlin.math.floor + +/** + * Handles a combat swing. + * @author Emperor + * @author Ceikry - Kotlin refactoring, general cleanup + * @author Player Name - converted `flags` to ArrayList + */ +abstract class CombatSwingHandler(var type: CombatStyle?) { + var flags: ArrayList = ArrayList(SwingHandlerFlag.values().size) + constructor(type: CombatStyle?, vararg flags: SwingHandlerFlag) : this(type) { + this.flags = arrayListOf(*flags) + } + + /** + * The mapping of the special attack handlers. + */ + private var specialHandlers: MutableMap? = null + + /** + * Starts the combat swing. + * @param entity The attacking entity. + * @param victim The victim. + * @param state The battle state instance. + * @return The amount of ticks before impact of the attack. + */ + abstract fun swing(entity: Entity?, victim: Entity?, state: BattleState?): Int + + /** + * Handles the impact of the combat swing (victim getting hit). + * @param entity The attacking entity. + * @param victim The victim. + * @param state The battle state instance. + */ + abstract fun impact(entity: Entity?, victim: Entity?, state: BattleState?) + + /** + * Visualizes the impact itself (end animation, end GFX, ...) + * @param entity The attacking entity. + * @param victim The victim. + * @param state The battle state instance. + */ + abstract fun visualizeImpact(entity: Entity?, victim: Entity?, state: BattleState?) + + /** + * Calculates the maximum accuracy of the entity. + * @param entity The entity. + * @return The maximum accuracy value. + */ + abstract fun calculateAccuracy(entity: Entity?): Int + + /** + * Calculates the maximum strength of the entity. + * @param entity The entity. + * @param victim The victim. + * @param modifier The modifier. + * @return The maximum strength value. + */ + abstract fun calculateHit(entity: Entity?, victim: Entity?, modifier: Double): Int + + /** + * Calculates the maximum defence of the entity. + * @param victim The entity. + * @param attacker The entity to defend against. + * @return The maximum defence value. + */ + abstract fun calculateDefence(victim: Entity?, attacker: Entity?): Int + + /** + * Gets the void set multiplier. + * @param e The entity. + * @param skillId The skill id. + * @return The multiplier. + */ + abstract fun getSetMultiplier(e: Entity?, skillId: Int): Double + + /** + * Visualizes the combat swing (start animation, GFX, projectile, ...) + * @param entity The attacking entity. + * @param victim The victim. + * @param state The battle state instance. + */ + open fun visualize(entity: Entity, victim: Entity?, state: BattleState?) { + entity.animate(getAttackAnimation(entity, type)) + } + + /** + * Method called when the impact method got called. + * @param entity The attacking entity. + * @param victim The victim. + * @param state The battle state. + */ + fun onImpact(entity: Entity?, victim: Entity?, state: BattleState?) { + if (entity is Player && victim != null) { + DegradableEquipment.degrade(entity as Player?, victim, true) + } + if (state == null) { + return + } + if (state.targets != null && state.targets.isNotEmpty()) { + if (!(state.targets.size == 1 && state.targets[0] == state)) { + for (s in state.targets) { + if (s != null && s != state) { + onImpact(entity, s.victim, s) + } + } + return + } + } + victim!!.onImpact(entity, state) + } + + /** + * Gets the currently worn armour set, if any. + * @param e The entity. + * @return The armour set worn. + */ + open fun getArmourSet(e: Entity?): ArmourSet? { + return null + } + + /** + * Checks if the hit will be accurate. + * @param entity The entity. + * @param victim The victim. + * @return `True` if the hit is accurate. + */ + fun isAccurateImpact(entity: Entity?, victim: Entity?): Boolean { + return isAccurateImpact(entity, victim, type, 1.0, 1.0) + } + + /** + * Checks if the hit will be accurate. + * @param entity The entity. + * @param victim The victim. + * @param style The combat style used. + * @return `True` if the hit is accurate. + */ + fun isAccurateImpact(entity: Entity?, victim: Entity?, style: CombatStyle?): Boolean { + return isAccurateImpact(entity, victim, style, 1.0, 1.0) + } + + /** + * Checks if the hit will be accurate. + * @param entity The entity. + * @param victim The victim. + * @param style The combat style (null to ignore prayers). + * @param accuracyMod The accuracy modifier. + * @param defenceMod The defence modifier. + * @return `True` if the hit is accurate. + */ + fun isAccurateImpact(entity: Entity?, victim: Entity?, style: CombatStyle?, accuracyMod: Double, defenceMod: Double): Boolean { + var mod = 1.0 + if (victim == null || style == null) { + return false + } + if (victim is Player && entity is Familiar && victim.prayer[PrayerType.PROTECT_FROM_SUMMONING]) { + mod = 0.0 + } + val attack = calculateAccuracy(entity) * accuracyMod * mod + val defence = calculateDefence(victim, entity) * defenceMod + val chance: Double = if (attack > defence) { + 1 - ((defence + 2) / (2 * (attack + 1))) + } else { + attack / (2 * (defence + 1)) + } + return Math.random() < chance + } + + /** + * Checks if the entity can execute a combat swing at the victim. + * @param entity The entity. + * @param victim The victim. + * @return `True` if so. + */ + open fun canSwing(entity: Entity, victim: Entity): InteractionType? { + return isAttackable(entity, victim) + } + + /** + * Checks if the victim can be attacked by the entity. + * @param entity The attacking entity. + * @param victim The entity being attacked. + * @return `True` if so. + */ + open fun isAttackable(entity: Entity, victim: Entity): InteractionType? { + if (victim.getAttribute("return-to-spawn", false)) { + return InteractionType.NO_INTERACT + } + + if (type == CombatStyle.MELEE) { + val stepType = canStepTowards(entity, victim) + if (stepType != InteractionType.STILL_INTERACT) return stepType + } + + val comp = entity.getAttribute("autocast_component",null) as Component? + if((comp != null || type == CombatStyle.MAGIC) && (entity.properties.autocastSpell == null || entity.properties.autocastSpell.spellId == 0) && entity is Player){ + val weapEx = entity.getExtension(WeaponInterface::class.java) as WeaponInterface? + if(comp != null){ + entity.interfaceManager.close(comp) + entity.interfaceManager.openTab(weapEx) + entity.properties.combatPulse.stop() + entity.attack(victim) + entity.removeAttribute("autocast_component") + } + weapEx?.updateInterface() + entity.debug("Adjusting attack style") + } + if (entity.location == victim.location) { + return if (entity is Player && victim is Player && entity.clientIndex < victim.clientIndex && victim.properties.combatPulse.getVictim() === entity) { + InteractionType.STILL_INTERACT + } else InteractionType.NO_INTERACT + } + val el = entity.location + val vl = victim.location + val evl = vl.transform(victim.size(), victim.size(), 0) + if (el.x >= vl.x && el.x < evl.x && el.y >= vl.y && el.y < evl.y || el.z != vl.z) { + return InteractionType.NO_INTERACT + } + return InteractionType.STILL_INTERACT + } + + private fun canStepTowards(entity: Entity, victim: Entity): InteractionType { + val closestVictimTile = victim.getClosestOccupiedTile(entity.location) + val closestEntityTile = entity.getClosestOccupiedTile(closestVictimTile) + val dir = closestEntityTile.deriveDirection(closestVictimTile) + ?: return InteractionType.STILL_INTERACT //if we cannot derive a direction, it's because both tiles are the same, so hand off control to the main logic which already handles this case + var next = closestEntityTile + + while (next.getDistance(closestVictimTile) > 3) { //skip the initial gap in distance if it exists, because standard pathfinding would already stop us before this point if something was between us and the NPC or vice versa + next = next.transform(dir) + } + + var result: InteractionType = InteractionType.STILL_INTERACT + val maxIterations = next.getDistance(closestVictimTile).toInt() + for (i in 0 until maxIterations) { //step towards the target tile, checking if anything would obstruct us on the way, and immediately breaking + returning if it does. + next = next.transform(dir) + result = checkStepInterval(dir, next) + if (result == InteractionType.NO_INTERACT) break + } + + + return result + } + + private fun checkStepInterval( + dir: Direction, + next: Location + ): InteractionType { + val components = next.getStepComponents(dir) + + when (dir) { + Direction.NORTH -> if (getClippingFlag(next) and PREVENT_NORTH != 0) return InteractionType.NO_INTERACT + Direction.EAST -> if (getClippingFlag(next) and PREVENT_EAST != 0) return InteractionType.NO_INTERACT + Direction.SOUTH -> if (getClippingFlag(next) and PREVENT_SOUTH != 0) return InteractionType.NO_INTERACT + Direction.WEST -> if (getClippingFlag(next) and PREVENT_WEST != 0) return InteractionType.NO_INTERACT + + Direction.NORTH_EAST -> { + if (getClippingFlag(components[0]) and PREVENT_EAST != 0 + || getClippingFlag(components[1]) and PREVENT_NORTH != 0 + || getClippingFlag(next) and PREVENT_NORTHEAST != 0 + ) return InteractionType.NO_INTERACT + } + + Direction.NORTH_WEST -> { + if (getClippingFlag(components[0]) and PREVENT_WEST != 0 + || getClippingFlag(components[1]) and PREVENT_NORTH != 0 + || getClippingFlag(next) and PREVENT_NORTHWEST != 0 + ) return InteractionType.NO_INTERACT + } + + Direction.SOUTH_EAST -> { + if (getClippingFlag(components[0]) and PREVENT_EAST != 0 + || getClippingFlag(components[1]) and PREVENT_SOUTH != 0 + || getClippingFlag(next) and PREVENT_SOUTHEAST != 0 + ) return InteractionType.NO_INTERACT + } + + Direction.SOUTH_WEST -> { + if (getClippingFlag(components[0]) and PREVENT_WEST != 0 + || getClippingFlag(components[1]) and PREVENT_SOUTH != 0 + || getClippingFlag(next) and PREVENT_SOUTHWEST != 0 + ) return InteractionType.NO_INTERACT + } + + } + + return InteractionType.STILL_INTERACT + } + + /** + * Gets the dragonfire message. + * @param protection The protection value. + * @param fireName The fire breath name. + * @return The message to send. + */ + fun getDragonfireMessage(protection: Int, fireName: String): String { + if (protection and 0x4 != 0) { + if (protection and 0x2 != 0) { + return "Your potion and shield fully protects you from the dragon's $fireName." + } + return "Your shield absorbs most of the dragon's $fireName." + } + if (protection and 0x2 != 0) { + return "Your antifire potion helps you defend the against the dragon's $fireName." + } + if (protection and 0x8 != 0) { + return "Your magic prayer absorbs some of the dragon's $fireName." + } + return "You are horribly burnt by the dragon's $fireName." + } + + /** + * Visualizes the audio. + * @param entity the entity. + * @param victim the victim. + * @param state the state. + */ + fun visualizeAudio(entity: Entity, victim: Entity, state: BattleState) { + if (entity is Player) { + val styleIndex = entity.settings.attackStyleIndex + if (state.weapon != null && state.weapon.item != null) { + val weapon = state.weapon.item + val audios = weapon.definition.getConfiguration>(ItemConfigParser.ATTACK_AUDIO, null) + if (audios != null) { + var audio: Audio? = null + if (styleIndex < audios.size) { + audio = audios[styleIndex] + } + if (audio == null || audio.id == 0) { + audio = audios[0] + } + playGlobalAudio(entity.location, audio.id) + } + } else if (type == CombatStyle.MELEE) { + //plays a punching sound when no weapon is equipped + playGlobalAudio(entity.location, Sounds.HUMAN_ATTACK_2564) + } + } else if (entity is NPC) { + val npc = entity.asNpc() + val audio = npc.getAudio(0) + if (audio != null) playGlobalAudio(entity.location, audio.id) + } + } + + /** + * Gets the combat distance. + * @param e The entity. + * @param v The victim. + * @param rawDistance The distance. + * @return The actual distance used for combat. + */ + open fun getCombatDistance(e: Entity, v: Entity, rawDistance: Int): Int { + var distance = rawDistance + if (e is NPC) { + if (e.definition.combatDistance > 0) { + distance = e.definition.combatDistance + } + } + return (e.size() shr 1) + (v.size() shr 1) + distance + } + + /** + * Formats the hit for the victim. (called as + * victim.getSwingHandler(false).formatHit(victim, hit)) + * @param victim The entity receiving the hit. + * @param rawHit The hit to format. + * @return The formatted hit. + */ + fun formatHit(victim: Entity, rawHit: Int): Int { + var hit = rawHit + if (hit < 1) { + return hit + } + if (hit > victim.skills.lifepoints) { + hit = victim.skills.lifepoints + } + return hit + } + + /** + * Adjusts the battle state object for this combat swing. + * @param entity The attacking entity. + * @param victim The victim. + * @param state The battle state. + */ + open fun adjustBattleState(entity: Entity, victim: Entity, state: BattleState) { + EXPERIENCE_MOD = 4.0 + var totalHit = 0 + if (entity is Player) { + entity.familiarManager.adjustBattleState(state) + } + entity.sendImpact(state) + victim.checkImpact(state) + //Prevents lumbridge dummies from dying (true to how rs3 / 2009scape in 2009 does it) + if (victim.id == 4474 && type == CombatStyle.MAGIC || victim.id == 7891 && type == CombatStyle.MELEE) { + EXPERIENCE_MOD = 0.1 + victim.fullRestore() + if (state.estimatedHit >= 15) { + state.estimatedHit = 14 + } + if (state.secondaryHit >= 15) { + state.secondaryHit = 14 + } + } + if (victim.id == 757) { + EXPERIENCE_MOD = 0.01 + } + // Recursively adjustBattleState targets so that multi-target attacks have protection prayers applied. + if (state.targets != null && state.targets.isNotEmpty()) { + if (!(state.targets.size == 1 && state.targets[0] == state)) { + for (s in state.targets) { + if (s != null && s != state) { + adjustBattleState(entity, victim, s) + } + } + } + } + if (state.estimatedHit > 0) { + state.estimatedHit = getFormattedHit(entity, victim, state, state.estimatedHit) + totalHit += state.estimatedHit + } + if (state.secondaryHit > 0) { + state.secondaryHit = getFormattedHit(entity, victim, state, state.secondaryHit) + totalHit += state.secondaryHit + } + if (entity is Player) { + entity.degrader.checkWeaponDegrades(entity) + if (totalHit > 0 && entity.prayer[PrayerType.SMITE] && victim.skills.prayerPoints > 0) { + victim.skills.decrementPrayerPoints(totalHit * 0.25) + } + if (entity.getAttribute("1hko", false)) { + state.estimatedHit = victim.skills.lifepoints + } + } + if (victim is NPC) { + if (victim.properties.protectStyle != null && state.style == victim.properties.protectStyle) { + state.neutralizeHits() + } + } + } + + /** + * Adds the experience for the current combat swing. + * @param entity The attacking entity. + * @param victim The victim. + * @param state The battle state. + */ + open fun addExperience(entity: Entity?, victim: Entity?, state: BattleState?) { + if (entity == null || (victim is Player && entity is Player && entity.asPlayer().ironmanManager.isIronman)) { + return + } + var player: Player + var attStyle: Int + + when(entity) + { + is Familiar -> {player = entity.owner; attStyle = entity.attackStyle} + is Player -> {player = entity; attStyle = entity.properties.attackStyle.style} + else -> return + } + if (victim is NPC) EXPERIENCE_MOD *= victim.behavior.getXpMultiplier(victim, player) + if (state != null) { + val hit = state.totalDamage + if (entity is Player) { + var experience = hit * 1.33 + if (victim is NPC) experience *= victim.behavior.getXpMultiplier(victim, player) + player.skills.addExperience(Skills.HITPOINTS, experience, true) + } + + var skill = -1 + when (attStyle) { + WeaponInterface.STYLE_DEFENSIVE -> skill = Skills.DEFENCE + WeaponInterface.STYLE_ACCURATE -> skill = Skills.ATTACK + WeaponInterface.STYLE_AGGRESSIVE -> skill = Skills.STRENGTH + WeaponInterface.STYLE_CONTROLLED -> { + var experience = hit * EXPERIENCE_MOD + experience /= 3.0 + player.skills.addExperience(Skills.ATTACK, experience, true) + player.skills.addExperience(Skills.STRENGTH, experience, true) + player.skills.addExperience(Skills.DEFENCE, experience, true) + return + } + + WeaponInterface.STYLE_RANGE_ACCURATE -> skill = Skills.RANGE + WeaponInterface.STYLE_RAPID -> skill = Skills.RANGE + WeaponInterface.STYLE_LONG_RANGE -> { + player.skills.addExperience(Skills.RANGE, hit * (EXPERIENCE_MOD / 2), true) + player.skills.addExperience(Skills.DEFENCE, hit * (EXPERIENCE_MOD / 2), true) + return + } + + WeaponInterface.STYLE_CAST -> skill = Skills.MAGIC + WeaponInterface.STYLE_DEFENSIVE_CAST -> { + var experience = hit.toDouble() + if (victim is NPC) experience *= victim.behavior.getXpMultiplier(victim, player) + player.skills.addExperience(Skills.MAGIC, experience * 1.33, true) + player.skills.addExperience(Skills.DEFENCE, experience, true) + return + } + } + if (skill < 0) return + player.skills.addExperience(skill, hit * EXPERIENCE_MOD, true) + } + } + + /** + * Gets the formated hit. + * @param attacker The attacking entity. + * @param victim The victim. + * @param state The battle state. + * @param rawHit The hit to format. + * @return The formated hit. + */ + protected open fun getFormattedHit(attacker: Entity, victim: Entity, state: BattleState, rawHit: Int): Int { + var hit = rawHit + hit = attacker.getFormattedHit(state, hit).toInt() + if (victim is Player) { + val player = victim.asPlayer() + val shield = player.equipment[EquipmentContainer.SLOT_SHIELD] + if (shield != null && shield.id == 13742) { + if (RandomFunction.random(100) < 71) { + hit -= (hit.toDouble() * 0.25).toInt() + if (hit < 1) { + hit = 0 + } + } + } + if (shield != null && shield.id == 13740) { + val reduce = hit.toDouble() * 0.30 + var drain = hit * 0.15 + if (player.skills.prayerPoints > drain && drain > 0) { + if (drain < 1) { + drain = 1.0 + } + hit -= reduce.toInt() + if (hit < 1) { + hit = 0 + } + player.skills.decrementPrayerPoints(drain) + } + } + } + if (attacker is Player) { + val player = attacker.asPlayer() + if (player.equipment[3] != null && player.equipment[3].id == 14726 && state.style == CombatStyle.MAGIC) { + hit += (hit.toDouble() * 0.15).toInt() + } + } + if (attacker is Familiar && victim is Player) { + if (victim.prayer[PrayerType.PROTECT_FROM_SUMMONING]) { + hit = 0 + } + } + return formatHit(victim, hit) + } + + /** + * Gets the default animation of the entity. + * @param e The entity. + * @param style The combat style. + * @return The attack animation. + */ + fun getAttackAnimation(e: Entity, style: CombatStyle?): Animation { + var anim: Animation? = null + if (type != null && e is NPC) { + anim = e.properties.getCombatAnimation(style!!.ordinal % 3) + } + return anim ?: e.properties.attackAnimation + } + + /** + * Registers a special attack handler. + * @param itemId The item id. + * @param handler The combat swing handler. + * @return `True` if succesful. + */ + fun register(itemId: Int, handler: CombatSwingHandler): Boolean { + if (specialHandlers == null) { + specialHandlers = HashMap() + } + if (specialHandlers!!.containsKey(itemId)) { + log(this::class.java, Log.ERR, "Already contained special attack handler for item " + itemId + " - [old=" + specialHandlers!![itemId]!!::class.java.simpleName + ", new=" + handler.javaClass.simpleName + "].") + return false + } + return specialHandlers!!.put(itemId, handler) == null + } + + /** + * Gets the special attack handler for the given item id. + * @param itemId The item id. + * @return The special attack handler, or `null` if this item has no + * special attack handler. + */ + fun getSpecial(itemId: Int): CombatSwingHandler? { + if (specialHandlers == null) { + specialHandlers = HashMap() + } + return specialHandlers!![itemId] + } + + companion object { + /** + * The amount of experience to get per hit. + */ + @JvmField + var EXPERIENCE_MOD = 4.0 + + /** + * Checks if a projectile can be fired from the node location to the victim + * location. + * @param entity The node. + * @param victim The victim. + * @param checkClose If we are checking for a melee attack rather than a + * projectile. + * @return `True` if so. + */ + @JvmStatic + fun isProjectileClipped(entity: Node, victim: Node?, checkClose: Boolean): Boolean { + for(x1 in 0 until entity.size()) { + for(y1 in 0 until entity.size()) { + val src = entity.location.transform(x1, y1, 0) + for(x2 in 0 until victim!!.size()) { + for(y2 in 0 until victim!!.size()) { + val dst = victim!!.location.transform(x2, y2, 0) + val path = PROJECTILE.find(src, 1, dst, 1, 1, 0, 0, 0, false, RegionManager::getClippingFlag) + if(path.isSuccessful && (!checkClose || path.points.size <= 1)) { + return true + } + } + } + } + } + return false + } + } + +} + +enum class SwingHandlerFlag { + IGNORE_STAT_BOOSTS_DAMAGE, + IGNORE_STAT_BOOSTS_ACCURACY, + IGNORE_PRAYER_BOOSTS_DAMAGE, + IGNORE_PRAYER_BOOSTS_ACCURACY, + IGNORE_STAT_REDUCTION +} diff --git a/Server/src/main/core/game/node/entity/combat/DeathTask.java b/Server/src/main/core/game/node/entity/combat/DeathTask.java new file mode 100644 index 0000000..da30885 --- /dev/null +++ b/Server/src/main/core/game/node/entity/combat/DeathTask.java @@ -0,0 +1,181 @@ +package core.game.node.entity.combat; + +import core.game.event.SelfDeathEvent; +import core.game.container.Container; +import core.game.container.ContainerType; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.impl.Animator; +import core.game.node.entity.impl.PulseType; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.IronmanMode; +import core.game.node.entity.player.link.audio.Audio; +import core.game.node.entity.player.link.prayer.PrayerType; +import core.game.node.item.Item; +import core.game.system.task.NodeTask; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; + +import static core.api.ContentAPIKt.playGlobalAudio; + +/** + * Handles an entity death task. + * @author Emperor + */ +public final class DeathTask extends NodeTask { + + /** + * The death task singleton. + */ + private static final DeathTask SINGLETON = new DeathTask(); + + /** + * Constructs a new {@code DeathTask} {@Code Object}. + */ + private DeathTask() { + super(1); + } + + @Override + public void start(Node node, Node... n) { + Entity e = (Entity) node; + e.getWalkingQueue().reset(); + e.setAttribute("state:death", true); + e.setAttribute("tick:death", GameWorld.getTicks()); + e.lock(50); + e.face(null); + Entity killer = n.length > 0 ? (Entity) n[0] : e; + if (e instanceof NPC) { + killer.removeAttribute("combat-time"); + Audio audio = e.asNpc().getAudio(2); + if (audio != null) { + playGlobalAudio(e.getLocation(), audio.id); + } + } + e.graphics(Animator.RESET_G); + e.visualize(e.getProperties().getDeathAnimation(), e.getProperties().deathGfx); + e.getAnimator().forceAnimation(e.getProperties().getDeathAnimation()); + e.commenceDeath(killer); + e.getImpactHandler().setDisabledTicks(50); + } + + @Override + public boolean exec(Node node, Node... n) { + Entity e = (Entity) node; + int ticks = e.getProperties().getDeathAnimation().getDuration(); + if (ticks < 1 || ticks > 30) { + ticks = 6; + } + return e.getAttribute("tick:death", -1) <= GameWorld.getTicks() - ticks; + } + + @Override + public void stop(Node node, Node... n) { + Entity e = (Entity) node; + Entity killer = n.length > 0 ? (Entity) n[0] : e; + e.removeAttribute("state:death"); + e.removeAttribute("tick:death"); + Location spawn = e.getProperties().isSafeZone() ? e.getProperties().safeRespawn : e.getProperties().getSpawnLocation(); + e.getAnimator().forceAnimation(Animator.RESET_A); + e.getProperties().setTeleportLocation(spawn); + e.unlock(); + e.finalizeDeath(killer); + e.getImpactHandler().getNpcImpactLog().clear();// check if this needs to be before finalize + e.getImpactHandler().getPlayerImpactLog().clear();// check if this needs to be before finalize + e.getImpactHandler().setDisabledTicks(4); + e.dispatch(new SelfDeathEvent(killer)); + } + + @Override + public boolean removeFor(String s, Node node, Node... n) { + return false; + } + + /** + * Gets the player's death containers. + * @param player The player. + * @return The containers, index 0 = kept items, index 1 = lost items. + */ + public static Container[] getContainers(Player player) { + Container[] containers = new Container[2]; + Container wornItems = new Container(42, ContainerType.ALWAYS_STACK); + wornItems.addAll(player.getInventory()); + wornItems.addAll(player.getEquipment()); + int count = 3; + if (player.getSkullManager().isSkulled()) { + count -= 3; + } + if (player.getPrayer().get(PrayerType.PROTECT_ITEMS)) { + count += 1; + } + Container keptItems = new Container(count, ContainerType.NEVER_STACK); + containers[0] = keptItems; + if (player.getIronmanManager().getMode() != IronmanMode.ULTIMATE) { + for (int i = 0; i < count; i++) { + for (int j = 0; j < 42; j++) { + Item item = wornItems.get(j); + if (item != null) { + for (int x = 0; x < count; x++) { + Item kept = keptItems.get(x); + if (kept == null || kept != null && kept.getDefinition().getAlchemyValue(true) <= item.getDefinition().getAlchemyValue(true)) { + keptItems.replace(new Item(item.getId(), 1, item.getCharge()), x); + x++; + while (x < count) { + Item newKept = keptItems.get(x); + keptItems.replace(kept, x++); + kept = newKept; + } + if (kept != null) { + wornItems.add(kept, false); + } + item = wornItems.get(j); + wornItems.replace(new Item(item.getId(), item.getAmount() - 1, item.getCharge()), j); + break; + } + } + } + } + } + } + containers[1] = new Container(42, ContainerType.DEFAULT); + containers[1].addAll(wornItems); + return containers; + } + + /** + * Starts the death task for an entity. + * @param entity The entity. + * @param killer The entity's killer. + */ + @SuppressWarnings("deprecation") + public static void startDeath(Entity entity, Entity killer) { + if (!isDead(entity)) { + if (killer == null) { + killer = entity; + } + Pulse pulse = new DeathTask().schedule(entity, killer); + entity.getPulseManager().run(pulse, PulseType.STRONG); + } + } + + /** + * Checks if the entity is dead. + * @param e The entity. + * @return {@code True} if so. + */ + public static boolean isDead(Entity e) { + if (e instanceof NPC) return ((NPC) e).getRespawnTick() > GameWorld.getTicks() || e.getAttribute("state:death", false); + else return e.getAttribute("state:death", false); + } + + /** + * Gets the singleton. + * @return The singleton. + */ + public static DeathTask getSingleton() { + return SINGLETON; + } + +} diff --git a/Server/src/main/core/game/node/entity/combat/ImpactHandler.java b/Server/src/main/core/game/node/entity/combat/ImpactHandler.java new file mode 100644 index 0000000..4065a0d --- /dev/null +++ b/Server/src/main/core/game/node/entity/combat/ImpactHandler.java @@ -0,0 +1,412 @@ +package core.game.node.entity.combat; + +import content.data.EnchantedJewellery; +import core.game.container.impl.EquipmentContainer; +import core.game.node.entity.skill.Skills; +import content.global.skill.summoning.familiar.Familiar; +import content.global.skill.summoning.pet.Pet; +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.prayer.PrayerType; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.bots.AIPlayer; +import core.game.world.GameWorld; +import core.game.world.map.zone.ZoneType; +import core.game.world.repository.Repository; +import org.rs09.consts.Items; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Map; +import java.util.Queue; + +/** + * Class used for handling combat impacts. + * @author Emperor + */ +public final class ImpactHandler { + + /** + * The entity. + */ + private final Entity entity; + + /** + * The amount of ticks impacts have been disabled for. + */ + private int disabledTicks; + + /** + * The NPC impact log. + */ + private final Map npcImpactLog = new HashMap<>(); + + /** + * The player impact log. This is by player uid to cope with players relogging. + */ + private final Map playerImpactLog = new HashMap<>(); + + /** + * Gets the current hitsplats to show. + */ + private final Queue impactQueue = new LinkedList(); + + /** + * Constructs a new {@code ImpactHandler} {@code Object}. + * @param entity The entity. + */ + public ImpactHandler(Entity entity) { + this.entity = entity; + } + + /** + * Manually hits the entity. + * @param source The entity dealing the hit. + * @param hit The amount to hit. + * @param type The hitsplat type. + * @return The impact object. + */ + public Impact manualHit(Entity source, int hit, HitsplatType type) { + if (hit > entity.getSkills().getLifepoints()) { + hit = entity.getSkills().getLifepoints(); + } + return handleImpact(source, hit, null, null, type); + } + + /** + * Manually hits the entity. + * @param source The entity dealing the hit. + * @param hit The amount to hit. + * @param type The hitsplat type. + * @param ticks The delay before handling the hit. + * @return The impact object (or null if a pulse got submitted). + */ + public Impact manualHit(final Entity source, int hit, final HitsplatType type, int ticks) { + if (ticks > 0) { + final int damage = hit; + GameWorld.getPulser().submit(new Pulse(ticks, entity) { + @Override + public boolean pulse() { + manualHit(source, damage, type); + return true; + } + }); + return null; + } + return manualHit(source, hit, type); + } + + /** + * Handles an impact. + * @param source The impact-dealing entity. + * @param hit The hit amount. + * @param style The combat style used to deal the impact. + * @return The impact object created. + */ + public Impact handleImpact(Entity source, int hit, CombatStyle style) { + return handleImpact(source, hit, style, null, null, false); + } + + /** + * Handles an impact. + * @param source The impact-dealing entity. + * @param hit The hit amount. + * @param style The combat style used to deal the impact. + * @param state The battle state. + * @return The impact object created. + */ + public Impact handleImpact(Entity source, int hit, CombatStyle style, BattleState state) { + return handleImpact(source, hit, style, state, null, false); + } + + /** + * Handles an impact. + * @param source The impact-dealing entity. + * @param hit The hit amount. + * @param style The combat style used to deal the impact. + * @param state The battle state. + * @param type The hitsplat type. + * @return The impact object created. + */ + public Impact handleImpact(Entity source, int hit, CombatStyle style, BattleState state, HitsplatType type) { + return handleImpact(source, hit, style, state, type, false); + } + + /** + * Handles an impact. + * @param source The impact-dealing entity. + * @param hit The hit amount. + * @param style The combat style used to deal the impact. + * @param state The battle state. + * @param type The hitsplat type. + * @return The impact object created. + */ + public Impact handleImpact(Entity source, int hit, final CombatStyle style, final BattleState state, HitsplatType type, boolean secondary) { + if (DeathTask.isDead(this.entity)) { + this.entity.getProperties().getCombatPulse().setVictim(null); + this.entity.getProperties().getCombatPulse().stop(); + return null; + } + boolean fam = source instanceof Familiar; + if (fam) { + source = ((Familiar) source).getOwner(); + } + if (disabledTicks > GameWorld.getTicks()) { + return null; + } + if (entity instanceof Player && !(entity instanceof AIPlayer) && !(entity.getAttribute("tutorial:complete",false))) { + Impact impact = new Impact(source, 0, style, HitsplatType.MISS); + impactQueue.add(impact); + return impact; + } + hit -= entity.getSkills().hit(hit); + if (type == null || type == HitsplatType.NORMAL) { + if (hit == 0) { + type = HitsplatType.MISS; + } else { + type = HitsplatType.NORMAL; + } + } else if (hit == 0 && type == HitsplatType.POISON) { + return null; + } + if (hit > 0) { + if (source instanceof Player) { + int uid = source.asPlayer().getDetails().getUid(); + Integer value = playerImpactLog.get(uid); + playerImpactLog.put(uid, value == null ? hit : hit + value); + } else { + Integer value = npcImpactLog.get(source); + npcImpactLog.put(source, value == null ? hit : hit + value); + } + } + if (style != null && style.getSwingHandler() != null && source instanceof Player) { + Player player = source.asPlayer(); + if (fam && player.getFamiliarManager().hasFamiliar() && !(player.getFamiliarManager().getFamiliar() instanceof Pet)) { + source.setAttribute("fam-exp", true); + } + source.removeAttribute("fam-exp"); + } + boolean dead = false; + if (entity.getSkills().getLifepoints() < 1) { + entity.getProperties().getCombatPulse().stop(); + entity.face(source); + entity.startDeath(getMostDamageEntity(source)); + dead = true; + } else if (entity.getSkills().getLifepoints() < (entity.getSkills().getMaximumLifepoints() * 0.1)) { + if (entity instanceof Player && ((Player) entity).getPrayer().get(PrayerType.REDEMPTION)) { + ((Player) entity).getPrayer().startRedemption(); + } + } + if (entity instanceof Player) { + Player p = entity.asPlayer(); + if (p.getAttribute("godMode", false)) { + p.getSkills().heal(10000); + } + } + Impact impact = new Impact(source, hit, style, type); + impactQueue.add(impact); + if (entity instanceof Player && !dead) { + final Player p = entity.asPlayer(); + if (p.getZoneMonitor().getType() != ZoneType.SAFE.getId() && (p.getEquipment().contains(Items.RING_OF_LIFE_2570, 1))) { + int percentage = (int) (entity.getSkills().getStaticLevel(Skills.HITPOINTS) * 0.10); + if (p.getSkills().getLifepoints() <= percentage) { + Item rolItem = new Item(Items.RING_OF_LIFE_2570); + if (EnchantedJewellery.RING_OF_LIFE.attemptTeleport(p, rolItem, 0, true)) { + p.sendMessage("Your ring of life saves you and in the process is destroyed."); + } + } + } + } + return impact; + } + + /** + * Handles the recoil effect. + * @param attacker The attacker. + * @param hit The hit to handle. + */ + public void handleRecoilEffect(Entity attacker, int hit) { + int damage = (int) Math.ceil(hit * 0.1); + if (entity instanceof Player) { + Player player = (Player) entity; + int current = player.getSavedData().getGlobalData().getRecoilDamage(); + if (damage >= current) { + damage = current; + player.getPacketDispatch().sendMessage("Your Ring of Recoil has shattered."); + player.getEquipment().replace(null, EquipmentContainer.SLOT_RING); + player.getSavedData().getGlobalData().setRecoilDamage(40); + } else { + player.getSavedData().getGlobalData().setRecoilDamage(current - damage); + } + } + if (damage > 0) { + attacker.getImpactHandler().manualHit(entity, damage, HitsplatType.NORMAL); + } + } + + /** + * Gets the player who's dealt the most damage. + * @param killer The killer. + * @return The player. + */ + public Entity getMostDamageEntity(Entity killer) { + Entity entity = this.entity; + if (entity instanceof Player) { + return killer; + } + + int damage = -1; + if (playerImpactLog.isEmpty()) { + for (Entity e : npcImpactLog.keySet()) { + if (e == this.entity) { + continue; + } + int amount = npcImpactLog.get(e); + if (amount > damage) { + damage = amount; + entity = e; + } + } + return entity; + } + + int player = 0; //needs to be fake-initialized because java is dumb + for (int uid : playerImpactLog.keySet()) { + int amount = playerImpactLog.get(uid); + if (amount > damage) { + damage = amount; + player = uid; + } + } + return Repository.getPlayerByUid(player); + } + + /** + * Gets the npc impact log. + * @return The npc impact log. + */ + public Map getNpcImpactLog() { + return npcImpactLog; + } + + /** + * Gets the player impact log. + * @return The player impact log. + */ + public Map getPlayerImpactLog() { + return playerImpactLog; + } + + /** + * Checks if the entity needs a hit update. + * @return {@code True} if so. + */ + public boolean isHitUpdate() { + return impactQueue.peek() != null; + } + + /** + * Gets the hitsplats. + * @return The hitsplats. + */ + public Queue getImpactQueue() { + return impactQueue; + } + + /** + * Gets the disabledTicks. + * @return The disabledTicks. + */ + public int getDisabledTicks() { + return disabledTicks; + } + + /** + * Sets the disabledTicks. + */ + public void setDisabledTicks(int ticks) { + this.disabledTicks = GameWorld.getTicks() + ticks; + } + + /** + * Represents an impact. + * @author Emperor + */ + public static class Impact { + + /** + * The impact-dealing entity. + */ + private final Entity source; + + /** + * The hit amount. + */ + private final int amount; + + /** + * The combat style used to deal the hit. + */ + private final CombatStyle style; + + /** + * The hitsplat type. + */ + private final HitsplatType type; + + /** + * Constructs a new {@code ImpactHandler} {@code Object}. + * @param source The impact-dealing entity. + * @param amount The hit amount. + * @param style The combat style used to deal the hit. + * @param type The hitsplat type. + */ + public Impact(Entity source, int amount, CombatStyle style, HitsplatType type) { + this.source = source; + this.amount = amount; + this.style = style; + this.type = type; + } + + /** + * Gets the source. + * @return The source. + */ + public Entity getSource() { + return source; + } + + /** + * Gets the amount. + * @return The amount. + */ + public int getAmount() { + return amount; + } + + /** + * Gets the style. + * @return The style. + */ + public CombatStyle getStyle() { + return style; + } + + /** + * Gets the type. + * @return The type. + */ + public HitsplatType getType() { + return type; + } + } + + /** + * Represents the hitsplat types. + * @author Emperor + */ + public static enum HitsplatType { + MISS, NORMAL, POISON, DISEASE, NORMAL_1, VENOM; + } +} diff --git a/Server/src/main/core/game/node/entity/combat/InteractionType.java b/Server/src/main/core/game/node/entity/combat/InteractionType.java new file mode 100644 index 0000000..38c6d35 --- /dev/null +++ b/Server/src/main/core/game/node/entity/combat/InteractionType.java @@ -0,0 +1,24 @@ +package core.game.node.entity.combat; + +/** + * The interaction types for combat. + * @author Emperor + */ +public enum InteractionType { + + /** + * The entity can hit while standing still. + */ + STILL_INTERACT, + + /** + * The entity can hit while following the victim. + */ + MOVE_INTERACT, + + /** + * The entity can't hit its target. + */ + NO_INTERACT; + +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/combat/MagicSwingHandler.kt b/Server/src/main/core/game/node/entity/combat/MagicSwingHandler.kt new file mode 100644 index 0000000..82bf1d5 --- /dev/null +++ b/Server/src/main/core/game/node/entity/combat/MagicSwingHandler.kt @@ -0,0 +1,238 @@ +package core.game.node.entity.combat + +import content.global.skill.skillcapeperks.SkillcapePerks +import core.game.node.entity.Entity +import core.game.node.entity.combat.equipment.ArmourSet +import core.game.node.entity.combat.spell.SpellType +import core.game.node.entity.combat.equipment.WeaponInterface +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.tools.RandomFunction +import kotlin.math.floor + +/** + * Handles the magic combat swings. + * @author Emperor + * @author Ceikry, Kotlin conversion + cleanup + */ +open class MagicSwingHandler (vararg flags: SwingHandlerFlag) + : CombatSwingHandler(CombatStyle.MAGIC, *flags) { + + override fun canSwing(entity: Entity, victim: Entity): InteractionType? { + if (!isProjectileClipped(entity, victim, false)) { + return InteractionType.NO_INTERACT + } + var distance = 10 + var type = InteractionType.STILL_INTERACT + var goodRange = victim.centerLocation.withinDistance(entity.centerLocation, getCombatDistance(entity, victim, distance)) + if (victim.walkingQueue.isMoving && !goodRange) { + goodRange = victim.centerLocation.withinDistance(entity.centerLocation, getCombatDistance(entity, victim, ++distance)) + type = InteractionType.MOVE_INTERACT + } + if (goodRange && isAttackable(entity, victim) != InteractionType.NO_INTERACT) { + if (type == InteractionType.STILL_INTERACT) { + entity.walkingQueue.reset() + } + return type + } + return InteractionType.NO_INTERACT + } + + override fun swing(entity: Entity?, victim: Entity?, state: BattleState?): Int { + var spell = entity!!.properties.spell + if (spell == null) { + if (entity.properties.autocastSpell.also { spell = it } == null) { + return -1 + } + } + state!!.style = CombatStyle.MAGIC + if (!spell!!.meetsRequirements(entity, true, true)) { + entity.properties.spell = null + val inter = entity.getExtension(WeaponInterface::class.java) + if (inter != null) { + inter.selectAutoSpell(-1, true) + entity.properties.combatPulse.updateStyle() + } + return -1 + } + val max = calculateHit(entity, victim, spell!!.getMaximumImpact(entity, victim, state).toDouble()) + state.targets = spell!!.getTargets(entity, victim) + state.spell = spell + for (s in state.targets) { + var hit = -1 + s.spell = spell + if (isAccurateImpact(entity, s.victim, CombatStyle.MAGIC)) { + s.maximumHit = max + hit = RandomFunction.random(max) + } + s.style = CombatStyle.MAGIC + s.estimatedHit = hit + } + if (spell === entity.properties.spell) { + entity.properties.spell = null + if (entity.properties.autocastSpell == null) { + entity.properties.combatPulse.stop() + } + } + var ticks = 2 + floor(entity.location.getDistance(victim!!.location) * 0.5).toInt() + if (spell!!.type === SpellType.BLITZ) { + ticks++ + } + if(state.estimatedHit > victim.skills.lifepoints) state.estimatedHit = victim.skills.lifepoints + if(state.estimatedHit + state.secondaryHit > victim.skills.lifepoints) state.secondaryHit -= ((state.estimatedHit + state.secondaryHit) - victim.skills.lifepoints) + return ticks + } + + override fun adjustBattleState(entity: Entity, victim: Entity, state: BattleState) { + if (state.targets == null) { + super.adjustBattleState(entity, victim, state) + if (state.spell != null) { + state.spell.fireEffect(entity, victim, state) + } + return + } + for (s in state.targets) { + if (s != null) { + super.adjustBattleState(entity, s.victim, s) + if (s.spell != null) { + s.spell.fireEffect(entity, s.victim, s) + } + } + } + } + + override fun visualize(entity: Entity, victim: Entity?, state: BattleState?) { + state!!.spell.visualize(entity, victim) + } + + override fun impact(entity: Entity?, victim: Entity?, state: BattleState?) { + if (state!!.targets == null) { + if (state.estimatedHit > -1) { + victim!!.impactHandler.handleImpact(entity, state.estimatedHit, CombatStyle.MAGIC, state) + } + return + } + for (s in state.targets) { + if (s == null || s.estimatedHit < 0) { + continue + } + val hit = s.estimatedHit + s.victim.impactHandler.handleImpact(entity, hit, CombatStyle.MAGIC, s) + } + } + + override fun visualizeImpact(entity: Entity?, victim: Entity?, state: BattleState?) { + if (state!!.targets == null) { + if (state.spell != null) { + state.spell.visualizeImpact(entity, victim, state) + } + return + } + for (s in state.targets) { + if (s != null) { + state.spell.visualizeImpact(entity, s.victim, s) + } + } + } + + override fun calculateAccuracy(entity: Entity?): Int { + entity ?: return 0 + + val styleAttackBonus = entity.properties.bonuses[WeaponInterface.BONUS_MAGIC] + 64 + when (entity) { + is Player -> { + var effectiveMagicLevel = entity.skills.getLevel(Skills.MAGIC, true).toDouble() + if(!flags.contains(SwingHandlerFlag.IGNORE_PRAYER_BOOSTS_ACCURACY)) + effectiveMagicLevel = floor(effectiveMagicLevel + (entity.prayer.getSkillBonus(Skills.MAGIC) * effectiveMagicLevel)) + effectiveMagicLevel += 8 + effectiveMagicLevel *= getSetMultiplier(entity, Skills.MAGIC) + effectiveMagicLevel = floor(effectiveMagicLevel) + + if (!flags.contains(SwingHandlerFlag.IGNORE_STAT_BOOSTS_ACCURACY)) + effectiveMagicLevel *= styleAttackBonus + else effectiveMagicLevel *= 64 + + return effectiveMagicLevel.toInt() + } + is NPC -> { + val magicLevel = entity.skills.getLevel(Skills.MAGIC) + 9 + return magicLevel * styleAttackBonus + } + } + + return 0 + } + + override fun calculateHit(entity: Entity?, victim: Entity?, modifier: Double): Int { + var baseDamage = modifier + if (baseDamage < 2.0 || entity is NPC) { + if (baseDamage > 2.0) { + baseDamage = 1.0 + } + val level = entity!!.skills.getLevel(Skills.MAGIC, true) + val bonus = entity.properties.bonuses[if (entity is Player) 14 else 13] + val cumulativeStr = level.toDouble() + return 1 + ((14 + cumulativeStr + bonus.toDouble() / 8 + cumulativeStr * bonus * 0.016865) * baseDamage).toInt() / 10 + } + var levelMod = 1.0 + val entityMod = entity!!.getLevelMod(entity, victim) + if (entityMod != 0.0) { + levelMod += entityMod + } + return (baseDamage * levelMod).toInt() + 1 + } + + override fun calculateDefence(victim: Entity?, attacker: Entity?): Int { + victim ?: return 0 + attacker ?: return 0 + + val styleDefenceBonus = victim.properties.bonuses[WeaponInterface.BONUS_MAGIC + 5] + 64 + when (victim) { + is Player -> { + var effectiveDefenceLevel = victim.skills.getLevel(Skills.DEFENCE).toDouble() + effectiveDefenceLevel = floor(effectiveDefenceLevel + (victim.prayer.getSkillBonus(Skills.DEFENCE) * effectiveDefenceLevel)) + if (victim.properties.attackStyle.style == WeaponInterface.STYLE_DEFENSIVE || victim.properties.attackStyle.style == WeaponInterface.STYLE_LONG_RANGE) effectiveDefenceLevel += 3 + else if (victim.properties.attackStyle.style == WeaponInterface.STYLE_CONTROLLED) effectiveDefenceLevel += 1 + effectiveDefenceLevel *= getSetMultiplier(victim, Skills.DEFENCE) + + var effectiveMagicLevel = victim.skills.getLevel(Skills.MAGIC).toDouble() + effectiveMagicLevel = floor(effectiveMagicLevel + (victim.prayer.getSkillBonus(Skills.MAGIC) * effectiveMagicLevel)) + + effectiveDefenceLevel = effectiveDefenceLevel * 0.3 + effectiveMagicLevel * 0.7 + 8 + return effectiveDefenceLevel.toInt() * styleDefenceBonus + } + is NPC -> { + val defLevel = victim.skills.getLevel(Skills.MAGIC) + 9 + return defLevel * styleDefenceBonus + } + } + + return 0 + } + + override fun getSetMultiplier(e: Entity?, skillId: Int): Double { + if(skillId == Skills.MAGIC) { + if(e is Player && e.isWearingVoid(CombatStyle.MAGIC)) { + return 1.3 + } + } + return 1.0 + } + + override fun addExperience(entity: Entity?, victim: Entity?, state: BattleState?) { + if (state?.spell != null && entity is Player) { + state.spell.addExperience(entity, state.totalDamage) + return + } + + super.addExperience(entity, victim, state) + } + + + override fun getArmourSet(e: Entity?): ArmourSet? { + return if (ArmourSet.AHRIM.isUsing(e)) { + ArmourSet.AHRIM + } else super.getArmourSet(e) + } +} diff --git a/Server/src/main/core/game/node/entity/combat/MeleeSwingHandler.kt b/Server/src/main/core/game/node/entity/combat/MeleeSwingHandler.kt new file mode 100644 index 0000000..b58fe0c --- /dev/null +++ b/Server/src/main/core/game/node/entity/combat/MeleeSwingHandler.kt @@ -0,0 +1,328 @@ +package core.game.node.entity.combat + +import content.global.skill.skillcapeperks.SkillcapePerks +import content.global.skill.slayer.SlayerEquipmentFlags +import content.global.skill.slayer.SlayerManager +import core.api.* +import core.api.EquipmentSlot +import core.game.container.impl.EquipmentContainer +import core.game.node.entity.Entity +import core.game.node.entity.combat.equipment.ArmourSet +import core.game.node.entity.combat.equipment.Weapon +import core.game.node.entity.combat.equipment.WeaponInterface +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.world.map.path.Pathfinder +import core.tools.RandomFunction +import org.rs09.consts.Items +import kotlin.math.ceil +import kotlin.math.floor + +/** + * Handles a melee combat swing. + * @author Emperor + * @author Ceikry, Kotlin conversion + cleanup + */ +open class MeleeSwingHandler (vararg flags: SwingHandlerFlag) +/** + * Constructs a new `MeleeSwingHandler` {@Code Object}. + */ + : CombatSwingHandler(CombatStyle.MELEE, *flags) { + override fun canSwing(entity: Entity, victim: Entity): InteractionType? { + //Credits wolfenzi, https://www.rune-server.ee/2009scape-development/rs2-server/snippets/608720-arios-hybridding-improve.html + var distance = if (usingHalberd(entity)) 2 else 1 + var type = InteractionType.STILL_INTERACT + var goodRange = canMelee(entity, victim, distance) + if (!goodRange && victim.properties.combatPulse.getVictim() !== entity && victim.walkingQueue.isMoving && entity.size() == 1) { + type = InteractionType.MOVE_INTERACT + distance += if (entity.walkingQueue.isRunningBoth) 2 else 1 + goodRange = canMelee(entity, victim, distance) + } + if (!isProjectileClipped(entity, victim, !usingHalberd(entity))) { + return InteractionType.NO_INTERACT + } + val isRunning = entity.walkingQueue.runDir != -1 + val enemyRunning = victim.walkingQueue.runDir != -1 + // THX 4 fix tom <333. + if (super.canSwing(entity, victim) != InteractionType.NO_INTERACT) { + val maxDistance = if (isRunning) if (enemyRunning) 3 else 4 else 2 + if (entity.walkingQueue.isMoving + && entity.location.getDistance(victim.location) <= maxDistance) { + return type + } else if (goodRange) { + if (type == InteractionType.STILL_INTERACT) entity.walkingQueue.reset() + return type + } + } + return InteractionType.NO_INTERACT + } + + override fun swing(entity: Entity?, victim: Entity?, state: BattleState?): Int { + var hit = 0 + state!!.style = CombatStyle.MELEE + if (entity is Player) { + state.weapon = Weapon(entity.equipment[3]) + } + if (entity!!.properties.armourSet == ArmourSet.VERAC && RandomFunction.roll(4)) { + state.armourEffect = ArmourSet.VERAC + } + if (state.armourEffect == ArmourSet.VERAC || isAccurateImpact(entity, victim, CombatStyle.MELEE)) { + var max = calculateHit(entity, victim, 1.0) + if (victim != null) { + if (entity is NPC && state.armourEffect == ArmourSet.VERAC && victim.hasProtectionPrayer(CombatStyle.MELEE)) max = max * 2 / 3 + } + state.maximumHit = max + hit = RandomFunction.random(max + 1) + } + state.estimatedHit = hit + if(victim != null) { + if (state.estimatedHit > victim.skills.lifepoints) state.estimatedHit = victim.skills.lifepoints + if (state.estimatedHit + state.secondaryHit > victim.skills.lifepoints) state.secondaryHit -= ((state.estimatedHit + state.secondaryHit) - victim.skills.lifepoints) + } + return 1 + } + + override fun visualize(entity: Entity, victim: Entity?, state: BattleState?) { + entity.animate(entity.properties.attackAnimation) + } + + override fun impact(entity: Entity?, victim: Entity?, state: BattleState?) { + var targets = state!!.targets + if (targets == null) { + targets = arrayOf(state) + } + for (s in targets) { + var hit = s!!.estimatedHit + if (hit > -1) { + victim!!.impactHandler.handleImpact(entity, hit, CombatStyle.MELEE, s) + } + hit = s.secondaryHit + if (hit > -1) { + victim!!.impactHandler.handleImpact(entity, hit, CombatStyle.MELEE, s) + } + } + } + + override fun visualizeImpact(entity: Entity?, victim: Entity?, state: BattleState?) { + victim!!.animate(victim.properties.defenceAnimation) + } + + override fun adjustBattleState(entity: Entity, victim: Entity, state: BattleState) { + if (entity is Player) { + if (state.estimatedHit > 0) { + val name = entity.equipment.getNew(3).name + var damage = -1 + if (name.contains("(p++") || name.contains("(s)") || name.contains("(kp)")) { + damage = 68 + } else if (name.contains("(p+)")) { + damage = 58 + } else if (name.contains("(p)")) { + damage = 48 + } + if (damage > -1 && RandomFunction.random(10) < 4) { + applyPoison (victim, entity, damage) + } + } + } + super.adjustBattleState(entity, victim, state) + } + + override fun calculateAccuracy(entity: Entity?): Int { + //formula taken from wiki: https://oldschool.runescape.wiki/w/Damage_per_second/Melee#Step_six:_Calculate_the_hit_chance Yes I know it's old school. It's the best resource we have for potentially authentic formulae. + entity ?: return 0 + + val styleAttackBonus = entity.properties.bonuses[entity.properties.attackStyle.bonusType] + 64 + when (entity) { + is Player -> { + var effectiveAttackLevel = entity.skills.getLevel(Skills.ATTACK).toDouble() + if(!flags.contains(SwingHandlerFlag.IGNORE_PRAYER_BOOSTS_ACCURACY)) + effectiveAttackLevel = floor(effectiveAttackLevel + (entity.prayer.getSkillBonus(Skills.ATTACK) * effectiveAttackLevel)) + if(entity.properties.attackStyle.style == WeaponInterface.STYLE_ACCURATE) effectiveAttackLevel += 3 + else if(entity.properties.attackStyle.style == WeaponInterface.STYLE_CONTROLLED) effectiveAttackLevel += 1 + effectiveAttackLevel += 8 + if(SkillcapePerks.isActive(SkillcapePerks.PRECISION_STRIKES, entity)){ //Attack skillcape perk + effectiveAttackLevel += 6 + } + effectiveAttackLevel *= getSetMultiplier(entity, Skills.ATTACK) + effectiveAttackLevel = floor(effectiveAttackLevel) + if (!flags.contains(SwingHandlerFlag.IGNORE_STAT_BOOSTS_ACCURACY)) + effectiveAttackLevel *= styleAttackBonus + else effectiveAttackLevel *= 64 + + val victimName = entity.properties.combatPulse.getVictim()?.name ?: "none" + + // attack bonus for specialized equipments (salve amulets, slayer equips) + val amuletId = getItemFromEquipment(entity, EquipmentSlot.NECK)?.id ?: 0 + if ((amuletId == Items.SALVE_AMULET_4081 || amuletId == Items.SALVE_AMULETE_10588) && checkUndead(victimName)) { + effectiveAttackLevel *= if (amuletId == Items.SALVE_AMULET_4081) 1.15 else 1.2 + } else if (getSlayerTask(entity)?.ids?.contains((entity.properties.combatPulse?.getVictim()?.id ?: 0)) == true) { + effectiveAttackLevel *= SlayerEquipmentFlags.getDamAccBonus(entity) //Slayer Helm/ Black Mask/ Slayer cape + if (getSlayerTask(entity)?.dragon == true && inEquipment(entity, Items.DRAGON_SLAYER_GLOVES_12862)) + effectiveAttackLevel *= 1.1 + } + + return effectiveAttackLevel.toInt() + } + is NPC -> { + val attackLevel = entity.skills.getLevel(Skills.ATTACK) + 9 + return attackLevel * styleAttackBonus + } + } + + return 0 + + + } + + override fun calculateHit(entity: Entity?, victim: Entity?, modifier: Double): Int { + entity ?: return 0 + + var styleStrengthBonus = entity.properties.bonuses[11] + 64 + when (entity) { + is Player -> { + var effectiveStrengthLevel = entity.skills.getLevel(Skills.STRENGTH).toDouble() + if(!flags.contains(SwingHandlerFlag.IGNORE_PRAYER_BOOSTS_DAMAGE)) + effectiveStrengthLevel = floor(effectiveStrengthLevel + (entity.prayer.getSkillBonus(Skills.STRENGTH) * effectiveStrengthLevel)) + if(entity.properties.attackStyle.style == WeaponInterface.STYLE_AGGRESSIVE) effectiveStrengthLevel += 3 + else if (entity.properties.attackStyle.style == WeaponInterface.STYLE_CONTROLLED) effectiveStrengthLevel += 1 + effectiveStrengthLevel += 8 + effectiveStrengthLevel *= getSetMultiplier(entity, Skills.STRENGTH) + effectiveStrengthLevel = floor(effectiveStrengthLevel) + if (!flags.contains(SwingHandlerFlag.IGNORE_STAT_BOOSTS_DAMAGE)) + effectiveStrengthLevel *= styleStrengthBonus + else effectiveStrengthLevel *= 64 + if (getSlayerTask(entity)?.ids?.contains((entity.properties.combatPulse?.getVictim()?.id ?: 0)) == true) + effectiveStrengthLevel *= SlayerEquipmentFlags.getDamAccBonus(entity) //Slayer Helm/ Black Mask/ Slayer cape + + return (floor((0.5 + (effectiveStrengthLevel / 640.0))) * modifier).toInt() + } + is NPC -> { + val strengthLevel = entity.skills.getLevel(Skills.STRENGTH) + 9 + return (floor((0.5 + (strengthLevel * styleStrengthBonus / 640.0))) * modifier).toInt() + } + } + + return 0 + } + + override fun calculateDefence(victim: Entity?, attacker: Entity?): Int { + //authentic formula, taken from OSRS wiki: https://oldschool.runescape.wiki/w/Damage_per_second/Melee#Step_five:_Calculate_the_Defence_roll + victim ?: return 0 + attacker ?: return 0 + + val styleDefenceBonus = victim.properties.bonuses[attacker.properties.attackStyle.bonusType + 5] + 64 + when (victim) { + is Player -> { + var effectiveDefenceLevel = victim.skills.getLevel(Skills.DEFENCE).toDouble() + effectiveDefenceLevel = floor(effectiveDefenceLevel + (victim.prayer.getSkillBonus(Skills.DEFENCE) * effectiveDefenceLevel)) + if (victim.properties.attackStyle.style == WeaponInterface.STYLE_DEFENSIVE || victim.properties.attackStyle.style == WeaponInterface.STYLE_LONG_RANGE) effectiveDefenceLevel += 3 + else if (victim.properties.attackStyle.style == WeaponInterface.STYLE_CONTROLLED) effectiveDefenceLevel += 1 + effectiveDefenceLevel += 8 + effectiveDefenceLevel *= getSetMultiplier(victim, Skills.DEFENCE) + return effectiveDefenceLevel.toInt() * styleDefenceBonus + } + is NPC -> { + val defLevel = victim.skills.getLevel(Skills.DEFENCE) + 9 + return defLevel * styleDefenceBonus + } + } + + return 0 + } + + override fun getSetMultiplier(e: Entity?, skillId: Int): Double { + if (e!!.properties.armourSet === ArmourSet.DHAROK && skillId == Skills.STRENGTH) { + + return 1.0 + (e!!.skills.maximumLifepoints - e.skills.lifepoints) * 0.01 + } + if(e is Player && e.isWearingVoid(CombatStyle.MELEE) && (skillId == Skills.ATTACK || skillId == Skills.STRENGTH)) { + return 1.1 + } + return 1.0 + } + + override fun getArmourSet(e: Entity?): ArmourSet? { + if (ArmourSet.DHAROK.isUsing(e)) { + return ArmourSet.DHAROK + } + if (ArmourSet.GUTHAN.isUsing(e)) { + return ArmourSet.GUTHAN + } + if (ArmourSet.VERAC.isUsing(e)) { + return ArmourSet.VERAC + } + return if (ArmourSet.TORAG.isUsing(e)) { + ArmourSet.TORAG + } else super.getArmourSet(e) + } + + /** + * Check to see whether an NPC is classified as undead. + * @param name + * @return true if so + */ + private fun checkUndead(name: String): Boolean { + return (name == "Zombie" || name.contains("rmoured") || name == "Ankou" || name == "Crawling Hand" || name == "Banshee" || name == "Ghost" || name == "Ghast" || name == "Mummy" || name.contains("Revenant") + || name == "Skeleton" || name == "Zogre" || name == "Spiritual Mage") + } + + companion object { + /** + * Checks if the entity is using a halberd. + * @param entity The entity. + * @return `True` if so. + */ + private fun usingHalberd(entity: Entity): Boolean { + if (entity is Player) { + val weapon = entity.equipment[EquipmentContainer.SLOT_WEAPON] + if (weapon != null) { + return weapon.id in 3190..3204 || weapon.id == 6599 + } + } else if (entity is NPC) { + return entity.id == 8612 + } + return false + } + + /** + * Checks if the entity can execute a melee swing from its current location. + * @param entity The attacking entity. + * @param victim The victim. + * @return `True` if so. + */ + fun canMelee(entity: Entity, victim: Entity?, distance: Int): Boolean { + val e = entity.location + if (victim == null) { + return false + } + if (entity.id == 7135 && entity.location.withinDistance(victim.location, 2)) { + return true + } + val x = victim.location.x + val y = victim.location.y + val size = entity.size() + if (distance == 1) { + for (i in 0 until size) { + if (Pathfinder.isStandingIn(e.x - 1, e.y + i, 1, 1, x, y, victim.size(), victim.size())) { + return true + } + if (Pathfinder.isStandingIn(e.x + size, e.y + i, 1, 1, x, y, victim.size(), victim.size())) { + return true + } + if (Pathfinder.isStandingIn(e.x + i, e.y - 1, 1, 1, x, y, victim.size(), victim.size())) { + return true + } + if (Pathfinder.isStandingIn(e.x + i, e.y + size, 1, 1, x, y, victim.size(), victim.size())) { + return true + } + } + if (e == victim.location) { + return true + } + return victim.getSwingHandler(false).type == CombatStyle.MELEE && e.withinDistance(victim.location, 1) && victim.properties.combatPulse.getVictim() === entity && entity.index < victim.index + } + return entity.centerLocation.withinDistance(victim.centerLocation, distance + (size shr 1) + (victim.size() shr 1)) + } + } +} diff --git a/Server/src/main/core/game/node/entity/combat/MultiSwingHandler.kt b/Server/src/main/core/game/node/entity/combat/MultiSwingHandler.kt new file mode 100644 index 0000000..d283f3a --- /dev/null +++ b/Server/src/main/core/game/node/entity/combat/MultiSwingHandler.kt @@ -0,0 +1,187 @@ +package core.game.node.entity.combat + +import core.game.node.entity.Entity +import core.game.node.entity.combat.equipment.SwitchAttack +import core.game.node.entity.npc.NPC +import core.tools.RandomFunction + +/** + * Handles combat swings with switching combat styles. + * @author Emperor + * @author Ceikry, Kotlin conversion + */ +open class MultiSwingHandler(meleeDistance: Boolean, vararg attacks: SwitchAttack) : CombatSwingHandler(CombatStyle.RANGE) { + /** + * The attacks available. + */ + val attacks: Array + + /** + * If the entity has to be in melee distance to switch to melee. + */ + val isMeleeDistance: Boolean + + /** + * The current attack. + */ + protected var current: SwitchAttack + + /** + * The current attack. + */ + protected var next: SwitchAttack + + /** + * Constructs a new `MultiSwingHandler` `Object`. + * @param attacks The available attacks. + */ + constructor(vararg attacks: SwitchAttack) : this(true, *attacks) {} + + override fun canSwing(entity: Entity, victim: Entity): InteractionType? { + return if (isMeleeDistance) { + CombatStyle.RANGE.swingHandler.canSwing(entity, victim) + } else next.handler.canSwing(entity, victim) + } + + override fun swing(entity: Entity?, victim: Entity?, state: BattleState?): Int { + current = next + if (isMeleeDistance && current.style == CombatStyle.MELEE && CombatStyle.MELEE.swingHandler.canSwing(entity!!, victim!!) != InteractionType.STILL_INTERACT) { + for (attack in attacks) { + if (attack.style != CombatStyle.MELEE) { + current = attack + break + } + } + } + val style = current.style + type = style + val index = RandomFunction.randomize(attacks.size) + val pick = getNext(entity, victim, state, index) + next = pick + if (current.isUseHandler) { + return current.handler.swing(entity, victim, state) + } + var ticks = 1 + if (style != CombatStyle.MELEE) { + ticks += Math.ceil(entity!!.location.getDistance(victim!!.location) * if (type == CombatStyle.MAGIC) 0.5 else 0.3).toInt() + } + var hit = 0 + if (isAccurateImpact(entity, victim, style)) { + val max = calculateHit(entity, victim, 1.0) + state!!.maximumHit = max + hit = RandomFunction.random(max) + } + state!!.estimatedHit = hit + state.style = style + return ticks + } + + override fun visualize(entity: Entity, victim: Entity?, state: BattleState?) { + if (current.isUseHandler) { + current.handler.visualize(entity, victim, state) + return + } + entity.visualize(current.animation, current.startGraphic) + if (current.projectile != null) { + current.projectile.transform(entity, victim, entity is NPC, 46, if (current.style == CombatStyle.MAGIC) 10 else 5).send() + } + } + + override fun impact(entity: Entity?, victim: Entity?, state: BattleState?) { + if (current.isUseHandler) { + current.handler.impact(entity, victim, state) + return + } + var targets = state!!.targets + if (targets == null) { + targets = arrayOf(state) + } + for (s in targets) { + var hit = s!!.estimatedHit + if (hit > -1) { + victim!!.impactHandler.handleImpact(entity, hit, current.style, s) + } + hit = s.secondaryHit + if (hit > -1) { + victim!!.impactHandler.handleImpact(entity, hit, current.style, s) + } + } + } + + override fun adjustBattleState(entity: Entity, victim: Entity, state: BattleState) { + if (current.isUseHandler) { + current.handler.adjustBattleState(entity, victim, state) + return + } + super.adjustBattleState(entity, victim, state) + } + + override fun addExperience(entity: Entity?, victim: Entity?, state: BattleState?) { + current.handler.addExperience(entity, victim, state) + } + override fun visualizeImpact(entity: Entity?, victim: Entity?, state: BattleState?) { + if (current.isUseHandler) { + current.handler.visualizeImpact(entity, victim, state) + return + } + victim!!.visualize(victim.properties.defenceAnimation, current.endGraphic) + } + + override fun calculateAccuracy(entity: Entity?): Int { + return current.handler.calculateAccuracy(entity) + } + + override fun calculateHit(entity: Entity?, victim: Entity?, modifier: Double): Int { + return if (current.maximumHit > -1) { + current.maximumHit + } else current.handler.calculateHit(entity, victim, modifier) + } + + override fun calculateDefence(victim: Entity?, attacker: Entity?): Int { + return current.handler.calculateDefence(victim, attacker) + } + + override fun getSetMultiplier(e: Entity?, skillId: Int): Double { + return current.handler.getSetMultiplier(e, skillId) + } + + /** + * Checks if an attack switch can be selected. + * @param attack The attack to switch to. + * @return `True` if selectable. + */ + fun canSelect(attack: SwitchAttack?): Boolean { + return true + } + + /** + * Gets the next switch attack. + * @param entity the entity. + * @param victim the victim. + * @param state the state. + * @param index the index. + * @return the next attack. + */ + fun getNext(entity: Entity?, victim: Entity?, state: BattleState?, index: Int): SwitchAttack { + var index = index + var pick = attacks[index] + while (!pick.canSelect(entity, victim, state)) { + index = RandomFunction.randomize(attacks.size) + pick = attacks[index] + } + return pick + } + + /** + * Constructs a new `MultiSwingHandler` `Object`. + * @param meleeDistance If the entity has to be in melee distance to switch + * to melee. + * @param attacks The available attacks. + */ + init { + current = attacks[0] + next = current + isMeleeDistance = meleeDistance && !(attacks.size == 1 && attacks[0].style == CombatStyle.MELEE) + this.attacks = attacks as Array + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/combat/RangeSwingHandler.kt b/Server/src/main/core/game/node/entity/combat/RangeSwingHandler.kt new file mode 100644 index 0000000..a197d8b --- /dev/null +++ b/Server/src/main/core/game/node/entity/combat/RangeSwingHandler.kt @@ -0,0 +1,403 @@ +package core.game.node.entity.combat + +import content.global.skill.skillcapeperks.SkillcapePerks +import core.api.* +import core.game.container.impl.EquipmentContainer +import core.game.node.entity.Entity +import core.game.node.entity.combat.equipment.* +import core.game.node.entity.combat.equipment.Weapon.WeaponType +import core.game.node.entity.impl.Projectile +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.node.item.GroundItem +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import core.game.system.config.ItemConfigParser +import core.game.system.task.Pulse +import core.game.world.GameWorld +import core.game.world.map.Location +import core.game.world.map.RegionManager +import core.game.world.update.flag.context.Graphics +import core.tools.Log +import core.tools.RandomFunction +import java.util.* +import kotlin.math.ceil +import kotlin.math.floor + +/** + * Handles the range combat swings. + * @author Emperor + * @author Ceikry, conversion to Kotlin + cleanup + */ +open class RangeSwingHandler (vararg flags: SwingHandlerFlag) : CombatSwingHandler(CombatStyle.RANGE, *flags) { +/** + * Constructs a new `RangeSwingHandler` {@Code Object}. + */ + override fun canSwing(entity: Entity, victim: Entity): InteractionType? { + if (!isProjectileClipped(entity, victim, false)) { + return InteractionType.NO_INTERACT + } + var distance = 7 + if (entity is Player && (entity.getExtension(WeaponInterface::class.java) as WeaponInterface).weaponInterface.interfaceId == 91) { + distance -= 2 + } + if (entity.properties.attackStyle.style == WeaponInterface.STYLE_LONG_RANGE) { + distance += 2 + } + if (entity is Player) { + val rw = RangeWeapon.get(entity.getEquipment().getNew(EquipmentContainer.SLOT_WEAPON).getId()) + if(rw != null && (rw.weaponType == WeaponType.DOUBLE_SHOT || rw.weaponType == WeaponType.DEGRADING)) { + // Dark bow and crystal bow have a 10-square range, independent of whether longrange stance is used + distance = 10 + } + } + var goodRange = victim.centerLocation.withinDistance(entity.centerLocation, getCombatDistance(entity, victim, distance)) + var type = InteractionType.STILL_INTERACT + if (victim.walkingQueue.isMoving && !goodRange) { + goodRange = victim.centerLocation.withinDistance(entity.centerLocation, getCombatDistance(entity, victim, ++distance)) + type = InteractionType.MOVE_INTERACT + } + if (goodRange && super.canSwing(entity, victim) != InteractionType.NO_INTERACT) { + if (type == InteractionType.STILL_INTERACT) { + entity.walkingQueue.reset() + } + return type + } + return InteractionType.NO_INTERACT + } + + override fun swing(entity: Entity?, victim: Entity?, state: BattleState?): Int { + configureRangeData(entity, state) + if (state!!.weapon == null || !hasAmmo(entity, state)) { + entity!!.properties.combatPulse.stop() + return -1 + } + var hit = 0 + val armourPierce = state.ammunition != null && state.ammunition.effect != null && state.ammunition.effect == BoltEffect.DIAMOND && state.ammunition.effect.canFire(state) + if (armourPierce || isAccurateImpact(entity, victim, CombatStyle.RANGE)) { + val max: Int + if (armourPierce) { + state.ammunition.effect.impact(state) + flags.add(SwingHandlerFlag.IGNORE_STAT_REDUCTION) + max = (calculateHit(entity, victim, 1.0) * 1.15).toInt() + flags.remove(SwingHandlerFlag.IGNORE_STAT_REDUCTION) + } else { + max = calculateHit(entity, victim, 1.0) + } + state.maximumHit = max + hit = RandomFunction.random(max + 1) + } + state.estimatedHit = hit + if (state.weapon.type == WeaponType.DOUBLE_SHOT) { + if (isAccurateImpact(entity, victim, CombatStyle.RANGE)) { + hit = RandomFunction.random(calculateHit(entity, victim, 1.0) + 1) + } + state.secondaryHit = hit + } + if (entity == null || victim!!.location == null) { + return -1 + } + if(state.estimatedHit > victim.skills.lifepoints) state.estimatedHit = victim.skills.lifepoints + if(state.estimatedHit + state.secondaryHit > victim.skills.lifepoints) state.secondaryHit -= ((state.estimatedHit + state.secondaryHit) - victim.skills.lifepoints) + useAmmo(entity, state, victim.location) + return 1 + ceil(entity.location.getDistance(victim.location) * 0.3).toInt() + } + + /** + * Configures the range data. + * @param entity The entity. + * @param state The battle state. + */ + fun configureRangeData(entity: Entity?, state: BattleState?) { + state!!.style = CombatStyle.RANGE + val w: Weapon? + if (entity is Player) { + val rw = RangeWeapon.get(entity.equipment.getNew(3).id) + if (rw == null) { + log(this::class.java, Log.ERR, "Unhandled range weapon used - [item id=" + entity.equipment.getNew(3).id + "].") + return + } + w = Weapon(entity.equipment[3], rw.ammunitionSlot, entity.equipment.getNew(rw.ammunitionSlot)) + w.type = rw.weaponType + state.rangeWeapon = rw + state.ammunition = Ammunition.get(w.ammunition.id) + } else { + w = Weapon(null) + } + state.weapon = w + } + + override fun adjustBattleState(entity: Entity, victim: Entity, state: BattleState) { + if (state.ammunition != null && entity is Player) { + val damage = state.ammunition.poisonDamage + if (state.estimatedHit > 0 && damage > 8 && RandomFunction.random(10) < 4) { + applyPoison(victim, entity, damage) + } + } + super.adjustBattleState(entity, victim, state) + } + + override fun visualize(entity: Entity, victim: Entity?, state: BattleState?) { + var start: Graphics? = null + if (state!!.ammunition != null) { + start = state.ammunition.startGraphics + state.ammunition.projectile.copy(entity, victim, 5.0).send() + if (state.weapon.type == WeaponType.DOUBLE_SHOT && state.ammunition.darkBowGraphics != null) { + start = state.ammunition.darkBowGraphics + val speed = (55 + entity.location.getDistance(victim!!.location) * 10).toInt() + Projectile.create(entity, victim, state.ammunition.projectile.projectileId, 40, 36, 41, speed, 25).send() + } + } else if (entity is NPC) { + if (entity.definition.combatGraphics[0] != null) { + start = entity.definition.combatGraphics[0] + } + val g = entity.definition.combatGraphics[1] + if (g != null) { + Projectile.ranged(entity, victim, g.id, g.height, 36, 41, 5).send() + } + } + val weapon: RangeWeapon? = state.weapon?.let { RangeWeapon.get(it.id) } + val anim = entity.properties.attackAnimation.id + weapon?.let { + if ((anim == 422 || anim == 423)) { + entity.visualize(it.animation, start) + return + } + } + entity.visualize(entity.properties.attackAnimation, start) + } + + override fun impact(entity: Entity?, victim: Entity?, state: BattleState?) { + if (state!!.ammunition != null && state.ammunition.effect != null && state.ammunition.effect != BoltEffect.DIAMOND && state.ammunition.effect.canFire(state)) { + state.ammunition.effect.impact(state) + } + val hit = state.estimatedHit + victim!!.impactHandler.handleImpact(entity, hit, CombatStyle.RANGE, state) + if (state.secondaryHit > -1) { + val hitt = state.secondaryHit + GameWorld.Pulser.submit(object : Pulse(1, victim) { + override fun pulse(): Boolean { + victim.impactHandler.handleImpact(entity, hitt, CombatStyle.RANGE, state) + return true + } + }) + } + } + + override fun visualizeImpact(entity: Entity?, victim: Entity?, state: BattleState?) { + victim!!.animate(victim.properties.defenceAnimation) + } + + override fun calculateAccuracy(entity: Entity?): Int { + entity ?: return 0 + + val styleAttackBonus = entity.properties.bonuses[entity.properties.attackStyle.bonusType] + 64 + when (entity) { + is Player -> { + var effectiveRangedLevel = entity.skills.getLevel(Skills.RANGE).toDouble() + if(!flags.contains(SwingHandlerFlag.IGNORE_PRAYER_BOOSTS_ACCURACY)) + effectiveRangedLevel = floor(effectiveRangedLevel + (entity.prayer.getSkillBonus(Skills.RANGE) * effectiveRangedLevel)) + if(entity.properties.attackStyle.style == WeaponInterface.STYLE_RANGE_ACCURATE) effectiveRangedLevel += 3 + effectiveRangedLevel += 8 + effectiveRangedLevel *= getSetMultiplier(entity, Skills.RANGE) + if(SkillcapePerks.isActive(SkillcapePerks.ACCURATE_MARKSMAN,entity)) effectiveRangedLevel *= 1.1 + + effectiveRangedLevel = floor(effectiveRangedLevel) + if (!flags.contains(SwingHandlerFlag.IGNORE_STAT_BOOSTS_ACCURACY)) + effectiveRangedLevel *= styleAttackBonus + else effectiveRangedLevel *= 64 + + return effectiveRangedLevel.toInt() + } + is NPC -> { + val rangedLevel = entity.skills.getLevel(Skills.RANGE) + 9 + return rangedLevel * styleAttackBonus + } + } + + return 0 + } + + override fun calculateHit(entity: Entity?, victim: Entity?, modifier: Double): Int { + entity ?: return 0 + + var styleStrengthBonus = entity.properties.bonuses[14] + 64 + when (entity) { + is Player -> { + if(entity.equipment[EquipmentContainer.SLOT_WEAPON] != null && RangeWeapon.get(entity.equipment[EquipmentContainer.SLOT_WEAPON].id).ammunitionSlot != EquipmentContainer.SLOT_ARROWS && entity.equipment[EquipmentContainer.SLOT_ARROWS] != null) + styleStrengthBonus -= entity.equipment[EquipmentContainer.SLOT_ARROWS].definition.getConfiguration(ItemConfigParser.BONUS)[14] + var effectiveStrengthLevel = entity.skills.getLevel(Skills.RANGE).toDouble() + if (flags.contains(SwingHandlerFlag.IGNORE_STAT_REDUCTION)) { + val staticLevel = entity.skills.getStaticLevel(Skills.RANGE).toDouble() + if (staticLevel > effectiveStrengthLevel) { + effectiveStrengthLevel = staticLevel + } + } + if (!flags.contains(SwingHandlerFlag.IGNORE_PRAYER_BOOSTS_DAMAGE)) + effectiveStrengthLevel = floor(effectiveStrengthLevel + (entity.prayer.getSkillBonus(Skills.RANGE) * effectiveStrengthLevel)) + if(entity.properties.attackStyle.style == WeaponInterface.STYLE_RANGE_ACCURATE) effectiveStrengthLevel += 3 + effectiveStrengthLevel += 8 + effectiveStrengthLevel *= getSetMultiplier(entity, Skills.RANGE) + effectiveStrengthLevel = floor(effectiveStrengthLevel) + if (!flags.contains(SwingHandlerFlag.IGNORE_STAT_BOOSTS_DAMAGE)) + effectiveStrengthLevel *= styleStrengthBonus + else effectiveStrengthLevel *= 64 + + return (floor((0.5 + (effectiveStrengthLevel / 640.0))) * modifier).toInt() + } + is NPC -> { + val rangedLevel = entity.skills.getLevel(Skills.RANGE) + 9 + return (floor((0.5 + (rangedLevel * styleStrengthBonus / 640.0))) * modifier).toInt() + } + } + + return 0 + } + + override fun calculateDefence(victim: Entity?, attacker: Entity?): Int { + victim ?: return 0 + attacker ?: return 0 + + val styleDefenceBonus = victim.properties.bonuses[attacker.properties.attackStyle.bonusType + 5] + 64 + when (victim) { + is Player -> { + var effectiveDefLevel = victim.skills.getLevel(Skills.DEFENCE).toDouble() + effectiveDefLevel = floor(effectiveDefLevel + (victim.prayer.getSkillBonus(Skills.DEFENCE) * effectiveDefLevel)) + if (victim.properties.attackStyle.style == WeaponInterface.STYLE_DEFENSIVE || victim.properties.attackStyle.style == WeaponInterface.STYLE_LONG_RANGE) effectiveDefLevel += 3 + else if (victim.properties.attackStyle.style == WeaponInterface.STYLE_CONTROLLED) effectiveDefLevel += 1 + effectiveDefLevel += 8 + effectiveDefLevel *= getSetMultiplier(victim, Skills.DEFENCE) + return effectiveDefLevel.toInt() * styleDefenceBonus + } + is NPC -> { + val defLevel = victim.skills.getLevel(Skills.DEFENCE) + 9 + return defLevel * styleDefenceBonus + } + } + + return 0 + } + + override fun getSetMultiplier(e: Entity?, skillId: Int): Double { + if(skillId == Skills.RANGE) { + if(e is Player && e.isWearingVoid(CombatStyle.RANGE)) { + return 1.2 + } + } + return 1.0 + } + + override fun getArmourSet(e: Entity?): ArmourSet? { + return if (ArmourSet.KARIL.isUsing(e)) { + ArmourSet.KARIL + } else super.getArmourSet(e) + } + + companion object { + /** + * Checks if the entity has the ammunition needed to proceed. + * @param e The entity. + * @param state The battle state. + * @return `True` if so. + */ + fun hasAmmo(e: Entity?, state: BattleState?): Boolean { + if (e !is Player) { + return true + } + val type = state!!.weapon.type + val amount = if (type == WeaponType.DOUBLE_SHOT) 2 else 1 + if (type == WeaponType.DEGRADING) { + return true + } + val item = e.equipment[state.weapon.ammunitionSlot] + if (item != null && item.amount >= amount) { + if (!state.rangeWeapon.ammunition.contains(item.id)) { + e.packetDispatch.sendMessage("You can't use this type of ammunition with this bow.") + return false + } + return true + } + if (type == WeaponType.DOUBLE_SHOT) { + state.weapon.type = WeaponType.DEFAULT + return hasAmmo(e, state) + } + e.packetDispatch.sendMessage("You do not have enough ammo left.") + return false + } + + /** + * Uses the ammunition for the range weapon. + * @param e The entity. + * @param state The battle state. + * @param location The drop location. + */ + fun useAmmo(e: Entity, state: BattleState, location: Location?) { + var dropLocation = location + if (e !is Player) { + return + } + val type = state.weapon.type + val amount = if (type == WeaponType.DOUBLE_SHOT) 2 else 1 + if (type == WeaponType.DEGRADING) { + return + } + val ammo = state.weapon.ammunition + if (state.weapon.ammunitionSlot == -1 || ammo == null) { + return + } + val dropRate = getDropRate(e) + if (dropRate == -1.0) { + return + } + e.equipment.replace(Item(ammo.id, ammo.amount - amount, ammo.charge), state.weapon.ammunitionSlot) + if (dropLocation == null) { + return + } + val flag = RegionManager.getClippingFlag(dropLocation) + if (flag and 0x200000 != 0) { //Water + dropLocation = null + } + if (dropLocation != null && state.rangeWeapon.isDropAmmo) { + val rate = 5 * (1.0 + e.skills.getLevel(Skills.RANGE) * 0.01) * dropRate + if (RandomFunction.randomize(rate.toInt()) != 0) { + val drop = GroundItemManager.increase(Item(ammo.id, amount), dropLocation, e) + if (drop != null) { + if (e.getAttribute("duel:ammo", null) != null) { + (e.getAttribute("duel:ammo") as ArrayList).add(drop) + } + } + } + } + if (e.equipment[state.rangeWeapon.ammunitionSlot] == null) { + e.packetDispatch.sendMessage("You have no ammo left in your quiver!") + } + } + + /** + * Checks if ammunition should be saved. + * @param e The entity. + * @return `True` if so. + */ + private fun getDropRate(e: Entity?): Double { + if (e is Player) { + val cape = e.equipment[EquipmentContainer.SLOT_CAPE] + val weapon = e.equipment[EquipmentContainer.SLOT_WEAPON] + if (cape != null && (cape.id == 10498 || cape.id == 10499) && weapon != null && weapon.id != 10034 && weapon.id != 10033) { + val rate = 80 + if (RandomFunction.random(100) < rate) { + val torso = e.equipment[EquipmentContainer.SLOT_CHEST] + val modelId = torso?.definition?.maleWornModelId1 ?: -1 + if (modelId == 301 || modelId == 306 || modelId == 3379) { + e.packetDispatch.sendMessage("Your armour interferes with Ava's device.") + return 1.0 + } + return (-1).toDouble() + } + return 0.33 + } + } + return 1.0 + } + } +} diff --git a/Server/src/main/core/game/node/entity/combat/equipment/Ammunition.java b/Server/src/main/core/game/node/entity/combat/equipment/Ammunition.java new file mode 100644 index 0000000..a7b8951 --- /dev/null +++ b/Server/src/main/core/game/node/entity/combat/equipment/Ammunition.java @@ -0,0 +1,203 @@ +package core.game.node.entity.combat.equipment; + +import core.game.node.entity.Entity; +import core.game.node.entity.impl.Projectile; +import core.game.world.update.flag.context.Graphics; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import java.io.File; +import java.util.HashMap; +import java.util.Map; + +/** + * Represents range ammunition types. + * @author Emperor + */ +public final class Ammunition { + + /** + * The ammunition mapping. + */ + private static final Map AMMUNITION = new HashMap(); + + /** + * The ammunition item id. + */ + private final int itemId; + + /** + * The start graphics. + */ + private final Graphics startGraphics; + + /** + * The start graphics when using Dark bow. + */ + private final Graphics darkBowGraphics; + + /** + * The projectile. + */ + private final Projectile projectile; + + /** + * The poison damage. + */ + private final int poisonDamage; + + /** + * The bolt effect. + */ + private BoltEffect effect; + + /** + * Constructs a new {@code Ammunition} object. + * @param itemId The item id. + * @param startGraphics The start graphics. + * @param darkBowGraphics The dark bow start graphics. + * @param projectile The projectile. + * @param poisonDamage The poison damage the ammunition can do. + */ + public Ammunition(int itemId, Graphics startGraphics, Graphics darkBowGraphics, Projectile projectile, int poisonDamage) { + this.itemId = itemId; + this.startGraphics = startGraphics; + this.darkBowGraphics = darkBowGraphics; + this.poisonDamage = poisonDamage; + this.projectile = projectile; + } + + /** + * Loads all the {@code Ammunition} info to the mapping. + * @return {@code True}. + */ + public static boolean initialize() { + Document doc; + try { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + doc = builder.parse(new File("This file never existed. I have no idea how this code works, but it probably doesn't get called anywhere.")); + } catch (Throwable e) { + e.printStackTrace(); + return false; + } + NodeList nodeList = doc.getDocumentElement().getChildNodes(); + for (short i = 1; i < nodeList.getLength(); i += 2) { + Node n = nodeList.item(i); + if (n != null) { + if (n.getNodeName().equalsIgnoreCase("Ammunition")) { + NodeList list = n.getChildNodes(); + int itemId = 0; + int graphicsId = 0; + Graphics startGraphics = null; + Graphics darkBowGraphics = null; + Projectile projectile = null; + for (int a = 1; a < list.getLength(); a += 2) { + Node node = list.item(a); + if (node.getNodeName().equalsIgnoreCase("itemId")) { + itemId = Integer.parseInt(node.getTextContent()); + } else if (node.getNodeName().equalsIgnoreCase("startGraphicsId")) { + graphicsId = Integer.parseInt(node.getTextContent()); + } else if (node.getNodeName().equalsIgnoreCase("startGraphicsHeight")) { + startGraphics = new Graphics(graphicsId, Integer.parseInt(node.getTextContent()), 0); + } else if (node.getNodeName().equalsIgnoreCase("darkBowGraphicsId")) { + graphicsId = Integer.parseInt(node.getTextContent()); + } else if (node.getNodeName().equalsIgnoreCase("darkBowGraphicsHeight")) { + darkBowGraphics = new Graphics(graphicsId, Integer.parseInt(node.getTextContent()), 0); + } else if (node.getNodeName().equalsIgnoreCase("projectileId")) { + int startHeight = Integer.parseInt(node.getAttributes().getNamedItem("start_height").getTextContent()); + int type = Integer.parseInt(node.getAttributes().getNamedItem("type").getTextContent()); + int angle = Integer.parseInt(node.getAttributes().getNamedItem("angle").getTextContent()); + int baseSpeed = Integer.parseInt(node.getAttributes().getNamedItem("base_speed").getTextContent()); + int projectileId = Integer.parseInt(node.getTextContent()); + projectile = Projectile.create((Entity) null, null, projectileId, startHeight, 36, type, baseSpeed, angle, 0); + } else if (node.getNodeName().equalsIgnoreCase("poisonDamage")) { + AMMUNITION.put(itemId, new Ammunition(itemId, startGraphics, darkBowGraphics, projectile, Integer.parseInt(node.getTextContent()))); + } + } + } + } + } + return true; + } + + public static void main(String... args) { + initialize(); + } + + /** + * Gets the ammunition mapping. + * @return The mapping. + */ + public static Map getAmmunition() { + return AMMUNITION; + } + + /** + * Gets an ammunition object from the mapping. + * @param id The ammo id. + * @return The ammunition object. + */ + public static Ammunition get(int id) { + return AMMUNITION.get(id); + } + + /** + * @return the itemId + */ + public int getItemId() { + return itemId; + } + + /** + * @return the startGraphics + */ + public Graphics getStartGraphics() { + return startGraphics; + } + + /** + * @return the darkBowGraphics + */ + public Graphics getDarkBowGraphics() { + return darkBowGraphics; + } + + /** + * @return the projectile + */ + public Projectile getProjectile() { + return projectile; + } + + /** + * @return the poisonDamage + */ + public int getPoisonDamage() { + return poisonDamage; + } + + /** + * Gets the effect. + * @return the effect + */ + public BoltEffect getEffect() { + return effect; + } + + /** + * Sets the effect. + * @param effect the effect to set. + */ + public void setEffect(BoltEffect effect) { + this.effect = effect; + } + + @Override + public String toString() { + return "Ammunition [itemId=" + itemId + ", startGraphics=" + startGraphics + ", darkBowGraphics=" + darkBowGraphics + ", projectile=" + projectile + ", poisonDamage=" + poisonDamage + ", effect=" + effect + "]"; + } +} diff --git a/Server/src/main/core/game/node/entity/combat/equipment/ArmourSet.java b/Server/src/main/core/game/node/entity/combat/equipment/ArmourSet.java new file mode 100644 index 0000000..f311b95 --- /dev/null +++ b/Server/src/main/core/game/node/entity/combat/equipment/ArmourSet.java @@ -0,0 +1,203 @@ +package core.game.node.entity.combat.equipment; + +import core.game.node.entity.skill.Skills; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Graphics; +import core.tools.RandomFunction; + +/** + * Represents the types of armour sets. + * @author Emperor + */ +public enum ArmourSet { + + /** + * Ahrim the blighted barrows set. + */ + AHRIM(new Graphics(401, 96), new int[][] { { 4708, 4856, 4857, 4858, 4859 }, { 4710, 4862, 4863, 4864, 4865 }, { 4712, 4868, 4869, 4870, 4871 }, { 4714, 4874, 4875, 4876, 4877 } }) { + @Override + public boolean effect(Entity e, Entity victim, BattleState state) { + if (RandomFunction.random(100) < 25 && state.getEstimatedHit() > -1) { + victim.getSkills().updateLevel(Skills.STRENGTH, -5, 0); + return true; + } + return false; + } + + @Override + public boolean isUsing(Entity e) { + if (e instanceof NPC && ((NPC) e).getId() == 2025) { + return true; + } + return super.isUsing(e); + } + }, + + /** + * Dharok the wretched barrows set. + */ + DHAROK(null, new int[][] { { 4716, 4880, 4881, 4882, 4883 }, { 4718, 4886, 4887, 4888, 4889 }, { 4720, 4892, 4893, 4894, 4895 }, { 4722, 4898, 4899, 4900, 4901 } }) { + @Override + public boolean isUsing(Entity e) { + if (e instanceof NPC && ((NPC) e).getId() == 2026) { + return true; + } + return super.isUsing(e); + } + }, + + /** + * Guthan the infested barrows set. + */ + GUTHAN(new Graphics(398, 96), new int[][] { { 4724, 4904, 4905, 4906, 4907 }, { 4726, 4910, 4911, 4912, 4913 }, { 4728, 4916, 4917, 4918, 4919 }, { 4730, 4922, 4923, 4924, 4925 } }) { + @Override + public boolean effect(Entity e, Entity victim, BattleState state) { + if (RandomFunction.random(100) < 25) { + e.getSkills().heal(state.getEstimatedHit()); + return true; + } + return false; + } + + @Override + public boolean isUsing(Entity e) { + if (e instanceof NPC && ((NPC) e).getId() == 2027) { + return true; + } + return super.isUsing(e); + } + }, + + /** + * Karil the tainted barrows set. + */ + KARIL(new Graphics(400, 96), new int[][] { { 4732, 4928, 4929, 4930, 4931 }, { 4734, 4934, 4935, 4936, 4937 }, { 4736, 4940, 4941, 4942, 4943 }, { 4738, 4946, 4947, 4948, 4949 } }) { + @Override + public boolean effect(Entity e, Entity victim, BattleState state) { + if (state.getEstimatedHit() > 0 && RandomFunction.random(100) < 25) { + victim.getSkills().updateLevel(Skills.AGILITY, -(victim.getSkills().getDynamicLevels()[Skills.AGILITY] / 5), 0); + return true; + } + return false; + } + + @Override + public boolean isUsing(Entity e) { + if (e instanceof NPC && ((NPC) e).getId() == 2028) { + return true; + } + return super.isUsing(e); + } + }, + + /** + * Torag the corrupted barrows set. + */ + TORAG(new Graphics(399, 96), new int[][] { { 4745, 4952, 4953, 4954, 4955 }, { 4747, 4958, 4959, 4960, 4961 }, { 4749, 4964, 4965, 4966, 4967 }, { 4751, 4970, 4971, 4972, 4973 } }) { + @Override + public boolean effect(Entity e, Entity victim, BattleState state) { + if (state.getEstimatedHit() > 0 && RandomFunction.random(100) < 25) { + if (victim instanceof Player) { + ((Player) victim).getSettings().updateRunEnergy(20); + } + return true; + } + return false; + } + + @Override + public boolean isUsing(Entity e) { + if (e instanceof NPC && ((NPC) e).getId() == 2029) { + return true; + } + return super.isUsing(e); + } + }, + + /** + * Verac the defiled barrows set. + */ + VERAC(null, new int[][] { { 4753, 4976, 4977, 4978, 4979 }, { 4755, 4982, 4983, 4984, 4985 }, { 4757, 4988, 4989, 4990, 4991 }, { 4759, 4994, 4995, 4996, 4997 } }) { + @Override + public boolean isUsing(Entity e) { + if (e instanceof NPC && ((NPC) e).getId() == 2030) { + return true; + } + return super.isUsing(e); + } + }; + + /** + * The end graphic. + */ + private final Graphics endGraphic; + + /** + * The items. + */ + private final Item[][] sets; + + /** + * Constructs a new {@code ArmourSet} {@code Object}. + * @param endGraphic the end. + * @param set the set. + */ + private ArmourSet(Graphics endGraphic, int[][] set) { + this.endGraphic = endGraphic; + this.sets = new Item[4][5]; + for (int i = 0; i < set.length; i++) { + for (int k = 0; k < sets[i].length; k++) { + sets[i][k] = new Item(set[i][k]); + } + } + } + + /** + * Visualizes the effect. + * @param e The entity using the effect. + * @param victim The victim. + */ + public void visualize(Entity e, Entity victim) { + if (endGraphic != null) { + victim.graphics(endGraphic); + } + } + + /** + * Handles the effect of the armour set. + * @param e The entity using the effect. + * @param victim The victim. + * @param state The battle state. + * @return {@code True} if an effect occured. + */ + public boolean effect(Entity e, Entity victim, BattleState state) { + return false; + } + + /** + * Checks if the entity is wearing this armour set. + * @param e The entity. + * @return {@code True} if so. + */ + public boolean isUsing(Entity e) { + if (!(e instanceof Player)) { + return false; + } + Player p = (Player) e; + int hits = 0; + for (int i = 0; i < sets.length; i++) { + for (Item item : sets[i]) { + if (p.getEquipment().containsAtLeastOneItem(item.getId())) { + hits++; + break; + } + } + } + return hits == 4; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/combat/equipment/BoltEffect.java b/Server/src/main/core/game/node/entity/combat/equipment/BoltEffect.java new file mode 100644 index 0000000..7fb24f1 --- /dev/null +++ b/Server/src/main/core/game/node/entity/combat/equipment/BoltEffect.java @@ -0,0 +1,260 @@ +package core.game.node.entity.combat.equipment; + +import core.game.node.entity.skill.Skills; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.ImpactHandler.HitsplatType; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.audio.Audio; +import core.game.world.GameWorld; +import core.game.world.update.flag.context.Graphics; +import core.tools.RandomFunction; +import org.rs09.consts.NPCs; + +import static core.api.ContentAPIKt.*; + +/** + * Represents a bolt effect. + * @author Vexia + * @author Aero + */ +public enum BoltEffect { + OPAL(9236, Graphics.create(749), new Audio(2918)) { + @Override + public void impact(BattleState state) { + state.setEstimatedHit(state.getEstimatedHit() + RandomFunction.random(3, 20)); + if (state.getEstimatedHit() > 29) { + state.setEstimatedHit(21); + } + super.impact(state); + } + + }, + JADE(9237, new Graphics(755), new Audio(2916)) { + @Override + public void impact(BattleState state) { + if (state.getVictim() instanceof Player) { + Player p = state.getVictim().asPlayer(); + p.lock(2); + } + super.impact(state); + } + + @Override + public boolean canFire(BattleState state) { + boolean success = false; + if (state.getVictim() instanceof Player) { + Player p = state.getVictim().asPlayer(); + double level = p.getSkills().getLevel(Skills.AGILITY); + double req = 80; + double successChance = Math.ceil((level * 50 - req * 15) / req / 3 * 4); + int roll = RandomFunction.random(99); + success = successChance >= roll; + } + return super.canFire(state) && !success; + } + + }, + PEARL(9238, Graphics.create(750), new Audio(2920)) { + @Override + public void impact(BattleState state) { + state.setEstimatedHit(state.getEstimatedHit() + RandomFunction.random(3, 20)); + if (state.getEstimatedHit() > 29) { + state.setEstimatedHit(21); + } + super.impact(state); + } + + @Override + public boolean canFire(BattleState state) { + if (state.getVictim() instanceof Player) { + if (state.getVictim().asPlayer().getEquipment().contains(1383, 1) || state.getVictim().asPlayer().getEquipment().contains(1395, 1)) { + return false; + } + } + return super.canFire(state); + } + }, + TOPAZ(9239, Graphics.create(757), new Audio(2914)) { + @Override + public void impact(BattleState state) { + if (state.getVictim() instanceof Player) { + Player p = state.getVictim().asPlayer(); + int level = (int) ((int) p.getSkills().getLevel(Skills.MAGIC) * 0.03); + p.getSkills().updateLevel(Skills.MAGIC, -level, 0); + } + super.impact(state); + } + }, + SAPPHIRE(9240, new Graphics(759, 100), new Audio(2912)) { + @Override + public void impact(BattleState state) { + if (state.getVictim() instanceof Player && state.getAttacker() instanceof Player) { + Player p = state.getVictim().asPlayer(); + Player player = state.getAttacker().asPlayer(); + int give = (int) (p.getSkills().getPrayerPoints() * 0.05); + if (give > 0) { + p.getSkills().decrementPrayerPoints(give); + player.getSkills().incrementPrayerPoints(give); + } + } + super.impact(state); + } + }, + EMERALD(9241, new Graphics(752), new Audio(2919)) { + @Override + public void impact(BattleState state) { + applyPoison(state.getVictim(), state.getAttacker(), 40); + super.impact(state); + } + }, + RUBY(9242, new Graphics(754), new Audio(2911, 1)) { // in this case, volume is the number of times to play the sound... + @Override + public void impact(BattleState state) { // hit target for 20% of their HP, hit self for 10% of HP + int victimPoints = (int) (state.getVictim().getSkills().getLifepoints() * 0.20); + int playerPoints = (int) (state.getAttacker().getSkills().getLifepoints() * 0.10); + if (victimPoints >= 100 && state.getVictim().getId() == NPCs.CORPOREAL_BEAST_8133) { + victimPoints = 100; + } + state.setEstimatedHit(victimPoints); + state.getAttacker().getImpactHandler().manualHit(state.getVictim(), playerPoints, HitsplatType.NORMAL); + super.impact(state); + } + + @Override + public boolean canFire(BattleState state) { + int playerPoints = (int) (state.getAttacker().getSkills().getLifepoints() * 0.10); + if (playerPoints < 1) { + return false; + } + return super.canFire(state) && state.getAttacker().getSkills().getLifepoints() - playerPoints >= 1; + } + }, + DIAMOND(9243, new Graphics(758), new Audio(2913)) { /* handled in RangeSwingHandler.kt::swing(entity: Entity?, victim: Entity?, state: BattleState?) */ }, + DRAGON(9244, new Graphics(756), new Audio(2915)) { + @Override + public void impact(BattleState state) { + state.setEstimatedHit(state.getEstimatedHit() + RandomFunction.random(17, 29)); + super.impact(state); + } + + @Override + public boolean canFire(BattleState state) { + if (state.getVictim() instanceof NPC) { + NPC n = (NPC) state.getVictim(); + if (n.getName().toLowerCase().contains("fire") || n.getName().toLowerCase().contains("dragon")) { + return false; + } + } + if (state.getVictim() instanceof Player) { + if (state.getVictim().asPlayer().getEquipment().contains(1540, 1) || state.getVictim().asPlayer().getEquipment().contains(11283, 1) || state.getVictim().hasFireResistance()) { + return false; + } + } + return super.canFire(state); + } + }, + ONYX(9245, new Graphics(753), new Audio(2917)) { + @Override + public void impact(BattleState state) { + int newDamage = (int) (state.getEstimatedHit() * 0.25); + state.setEstimatedHit(state.getEstimatedHit() + newDamage); + state.getAttacker().getSkills().heal((int) (state.getEstimatedHit() * 0.25)); + state.getAttacker().setAttribute("onyx-effect", GameWorld.getTicks() + 12); + super.impact(state); + } + + @Override + public boolean canFire(BattleState state) { + if (state.getAttacker().getAttribute("onyx-effect", 0) > GameWorld.getTicks()) { + return false; + } + if (state.getVictim() instanceof NPC) { + NPC n = (NPC) state.getVictim(); + if (n.getTask() != null && n.getTask().undead) { + return false; + } + } + return super.canFire(state); + } + }; + + /** + * The item id of the bolt. + */ + private final int itemId; + + /** + * The graphics to send. + */ + private final Graphics graphics; + + /** + * The sound to send. + */ + private final Audio sound; + + /** + * Constructs a new {@Code BoltEffect} {@Code Object} + * @param itemId the item id. + * @param graphics the graphics. + * @param sound the sound. + */ + BoltEffect(int itemId, Graphics graphics, Audio sound) { + this.itemId = itemId; + this.graphics = graphics; + this.sound = sound; + } + + /** + * Handles the impact. + * @param state the battle state. + */ + public void impact(BattleState state) { + Entity victim = state.getVictim(); + if (sound != null) { + Entity attacker = state.getAttacker(); + if (attacker instanceof Player) { + playGlobalAudio(attacker.getLocation(), sound.id); + } + if (victim instanceof Player) { + playGlobalAudio(victim.getLocation(), sound.id); + } + } + if (graphics != null) { + victim.graphics(graphics); + } + } + + /** + * Checks if the effect can fire. + * @param state the state. + * @return {@code True} if so. + */ + public boolean canFire(BattleState state) { + return RandomFunction.random(13) == 5; + } + + /** + * Gets an effect by the id. + * @param id the id. + * @return the effect. + */ + public static BoltEffect forId(int id) { + for (BoltEffect effect : values()) { + if (effect.getItemId() == id) { + return effect; + } + } + return null; + } + + /** + * Gets the itemId. + * @return the itemId + */ + public int getItemId() { + return itemId; + } +} diff --git a/Server/src/main/core/game/node/entity/combat/equipment/DegradableEquipment.java b/Server/src/main/core/game/node/entity/combat/equipment/DegradableEquipment.java new file mode 100644 index 0000000..35a900e --- /dev/null +++ b/Server/src/main/core/game/node/entity/combat/equipment/DegradableEquipment.java @@ -0,0 +1,152 @@ +package core.game.node.entity.combat.equipment; + +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.plugin.Plugin; + +import java.util.ArrayList; +import java.util.List; + +/** + * Handles equipment degrading. + * @author Emperor + */ +public abstract class DegradableEquipment implements Plugin { + + /** + * The equipment lists. + */ + private static final List[] EQUIPMENT = new ArrayList[14]; + + /** + * The equipment slot. + */ + private final int slot; + + /** + * The item ids. + */ + private final int[] itemIds; + + /** + * Constructs a new {@code DegradableEquipment} {@code Object}. + * @param slot The equipment slot. + * @param itemIds The item ids. + */ + public DegradableEquipment(int slot, int... itemIds) { + this.slot = slot; + this.itemIds = itemIds; + } + + + + /** + * Handles equipment degrading. + * @param player The player. + * @param entity The combat entity. + * @param attack If the player is attacking instead of defending. + */ + public static void degrade(Player player, Entity entity, boolean attack) { + /*if (attack) { + checkDegrade(player, entity, EquipmentContainer.SLOT_WEAPON); + return; + } + for (int i = 0; i < 14; i++) { + if (i != EquipmentContainer.SLOT_WEAPON && i != EquipmentContainer.SLOT_ARROWS) { + checkDegrade(player, entity, i); + } + }*/ + } + + /** + * Checks the degrading equipment on an equipment slot. + * @param player The player. + * @param entity The entity. + * @param slot The slot to check. + */ + public static void checkDegrade(Player player, Entity entity, int slot) { + /*Item item = player.getEquipment().get(slot); + if(item != null) { + roar: + { + for (DegradableEquipment e : EQUIPMENT[slot]) { + for (int itemId : e.itemIds) { + if (itemId == item.getId()) { + e.degrade(player, entity, item); + break roar; + } + } + } + } + }*/ + } + + /** + * Gets the item to drop. + * @param itemId The item id. + * @return The dropped item. + */ + public static int getDropReplacement(int itemId) { + for (int i = 0; i < EQUIPMENT.length; i++) { + if (EQUIPMENT[i] == null) { + continue; + } + for (DegradableEquipment e : EQUIPMENT[i]) { + for (int id : e.itemIds) { + if (id == itemId) { + return e.getDropItem(id); + } + } + } + } + return itemId; + } + + /** + * Called when the player receives a hit. + * @param player The player. + * @param entity The combat entity. + * @param item The degrading equipment item. + */ + public abstract void degrade(Player player, Entity entity, Item item); + + /** + * Gets the item to drop when this equipment is getting dropped. + * @param itemId The drop item. + * @return The item to drop. + */ + public abstract int getDropItem(int itemId); + + @Override + public DegradableEquipment newInstance(Object arg) { + List equipment = EQUIPMENT[slot]; + if (equipment == null) { + equipment = EQUIPMENT[slot] = new ArrayList<>(20); + } + equipment.add(this); + return this; + } + + @Override + public Object fireEvent(String key, Object... args) { + return null; + } + + /** + * Gets the slot. + * @return The slot. + */ + public int getSlot() { + return slot; + } + + /** + * Gets the itemIds. + * @return The itemIds. + */ + public int[] getItemIds() { + return itemIds; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/combat/equipment/FireType.java b/Server/src/main/core/game/node/entity/combat/equipment/FireType.java new file mode 100644 index 0000000..4e006d6 --- /dev/null +++ b/Server/src/main/core/game/node/entity/combat/equipment/FireType.java @@ -0,0 +1,116 @@ +package core.game.node.entity.combat.equipment; + +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.Player; +import core.game.system.task.NodeTask; +import core.game.world.update.flag.context.Animation; +import core.tools.RandomFunction; + +import static core.api.ContentAPIKt.*; + +/** + * The fire types. + * @author Emperor + */ +public enum FireType { + + /** + * The normal dragonfire fire type. + */ + FIERY_BREATH(new Animation(81, Priority.HIGH), 393, new NodeTask(0) { + @Override + public boolean exec(Node node, Node... n) { + return true; + } + }), + + /** + * The shocking breath fire type. + */ + SHOCKING_BREATH(new Animation(84, Priority.HIGH), 396, new NodeTask(0) { + @Override + public boolean exec(Node node, Node... n) { + if (RandomFunction.random(10) < 3) { + ((Entity) node).getSkills().updateLevel(RandomFunction.random(3), -5, 0); + if (node instanceof Player) { + ((Player) node).getPacketDispatch().sendMessage("You have been shocked."); + } + } + return true; + } + }), + + /** + * The toxic breath fire type. + */ + TOXIC_BREATH(new Animation(82, Priority.HIGH), 394, new NodeTask(0) { + @Override + public boolean exec(Node node, Node... n) { + applyPoison ((Entity) node, (Entity) n[0], 40); + return true; + } + }), + + /** + * The freezing breath fire type. + */ + ICY_BREATH(new Animation(83, Priority.HIGH), 395, new NodeTask(0) { + @Override + public boolean exec(Node node, Node... n) { + registerTimer((Entity) node, spawnTimer ("frozen", 7, true)); + return true; + } + }); + + /** + * The attack animation. + */ + private final Animation animation; + + /** + * The projectile id. + */ + private final int projectileId; + + /** + * The breath effect. + */ + private final NodeTask task; + + /** + * Constructs a new {@code FireType} {@code Object}. + * @param animation The animation. + */ + private FireType(Animation animation, int projectileId, NodeTask breathEffect) { + this.animation = animation; + this.projectileId = projectileId; + task = breathEffect; + } + + /** + * Gets the animation. + * @return The animation. + */ + public Animation getAnimation() { + return animation; + } + + /** + * Gets the projectileId. + * @return The projectileId. + */ + public int getProjectileId() { + return projectileId; + } + + /** + * Gets the task. + * @return The task. + */ + public NodeTask getTask() { + return task; + } + +} diff --git a/Server/src/main/core/game/node/entity/combat/equipment/RangeWeapon.java b/Server/src/main/core/game/node/entity/combat/equipment/RangeWeapon.java new file mode 100644 index 0000000..1326530 --- /dev/null +++ b/Server/src/main/core/game/node/entity/combat/equipment/RangeWeapon.java @@ -0,0 +1,211 @@ +package core.game.node.entity.combat.equipment; + +import core.game.node.entity.impl.Animator.Priority; +import core.game.world.update.flag.context.Animation; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * A class holding all the range weapon definitions. + * @author Emperor + */ +public final class RangeWeapon { + + /** + * The range weapons mapping. + */ + private static final Map RANGE_WEAPONS = new HashMap(); + + /** + * The mapping containing all the possible ammunition types. + */ + private final List ammunition; + + /** + * The item id. + */ + private final int itemId; + + /** + * The attack animation id. + */ + private final Animation animation; + + /** + * The attack speed. + */ + private final int attackSpeed; + + /** + * The equipment slot the ammunition uses, if any. + */ + private final int ammunitionSlot; + + /** + * The weapon type. + */ + private final int type; + + /** + * If we should drop ammo. + */ + private final boolean dropAmmo; + + /** + * Constructs a new {@code RangeWeapon} {@code Object}. + * @param itemId The item id. + * @param animation The animation. + * @param attackSpeed The attack speed. + * @param ammunitionSlot The ammunition's equipment slot, or -1 if not worn. + * @param type The weapon type. + * @param dropAmmo If the ammunition should be dropped. + * @param ammunition The possible ammunition vector list. + */ + public RangeWeapon(int itemId, Animation animation, int attackSpeed, int ammunitionSlot, int type, boolean dropAmmo, List ammunition) { + this.itemId = itemId; + this.animation = animation; + this.attackSpeed = attackSpeed; + this.ammunitionSlot = ammunitionSlot; + this.type = type; + this.dropAmmo = dropAmmo; + this.ammunition = ammunition; + } + + /** + * Populates the range weapons mapping. + * @return {@code True}. + */ + public static boolean initialize() { + Document doc; + try { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + doc = builder.parse(new File("This file never existed. I have no idea how this code works, but it probably doesn't get called anywhere")); + } catch (Throwable e) { + e.printStackTrace(); + return false; + } + NodeList nodeList = doc.getDocumentElement().getChildNodes(); + + for (short i = 1; i < nodeList.getLength(); i += 2) { + Node n = nodeList.item(i); + if (n != null) { + if (n.getNodeName().equalsIgnoreCase("Weapon")) { + NodeList list = n.getChildNodes(); + int itemId = 0; + int animationId = 426; + int attackSpeed = 4; + int slot = 13; + int type = 0; + boolean dropAmmo = true; + List ammo = new ArrayList(); + for (int a = 1; a < list.getLength(); a += 2) { + Node node = list.item(a); + if (node.getNodeName().equalsIgnoreCase("itemId")) { + itemId = Integer.parseInt(node.getTextContent()); + } else if (node.getNodeName().equalsIgnoreCase("animationId")) { + animationId = Integer.parseInt(node.getTextContent()); + } else if (node.getNodeName().equalsIgnoreCase("attackSpeed")) { + attackSpeed = Integer.parseInt(node.getTextContent()); + } else if (node.getNodeName().equalsIgnoreCase("ammunitionSlot")) { + slot = Integer.parseInt(node.getTextContent()); + } else if (node.getNodeName().equalsIgnoreCase("type")) { + type = Integer.parseInt(node.getTextContent()); + } else if (node.getNodeName().equalsIgnoreCase("drop_ammo")) { + dropAmmo = Boolean.parseBoolean(node.getTextContent()); + } else if (node.getNodeName().equalsIgnoreCase("ammunition")) { + int ammunitionId = Integer.parseInt(node.getTextContent()); + ammo.add(ammunitionId); + } + } + RANGE_WEAPONS.put(itemId, new RangeWeapon(itemId, new Animation(animationId, 0, Priority.HIGH), attackSpeed, slot, type, dropAmmo, ammo)); + } + } + } + + return true; + } + + /** + * Gets the range weapons mapping. + * @return The range weapons. + */ + public static Map getRangeWeapons() { + return RANGE_WEAPONS; + } + + /** + * Gets a range weapon instance from the mapping. + * @param id The item id. + * @return The instance. + */ + public static RangeWeapon get(int id) { + return RANGE_WEAPONS.get(id); + } + + /** + * @return the itemId + */ + public int getItemId() { + return itemId; + } + + /** + * @return the animation + */ + public Animation getAnimation() { + return animation; + } + + /** + * @return the ammunitionSlot + */ + public int getAmmunitionSlot() { + return ammunitionSlot; + } + + /** + * @return the ammunition + */ + public List getAmmunition() { + return ammunition; + } + + /** + * @return the attackSpeed + */ + public int getAttackSpeed() { + return attackSpeed; + } + + /** + * @return the type + */ + public int getType() { + return type; + } + + /** + * Gets the weapon type. + * @return The weapon type. + */ + public Weapon.WeaponType getWeaponType() { + return Weapon.WeaponType.values()[type]; + } + + /** + * @return the dropAmmo + */ + public boolean isDropAmmo() { + return dropAmmo; + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/combat/equipment/SwitchAttack.java b/Server/src/main/core/game/node/entity/combat/equipment/SwitchAttack.java new file mode 100644 index 0000000..7a11c7e --- /dev/null +++ b/Server/src/main/core/game/node/entity/combat/equipment/SwitchAttack.java @@ -0,0 +1,216 @@ +package core.game.node.entity.combat.equipment; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.node.entity.impl.Projectile; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; + +/** + * Represents a possible attack the entity can switch to. + * @author Emperor + */ +public class SwitchAttack { + + /** + * The combat swing handler. + */ + private CombatSwingHandler handler; + + /** + * The start graphic. + */ + private final Graphics startGraphic; + + /** + * The animation. + */ + private final Animation animation; + + /** + * The end graphic. + */ + private final Graphics endGraphic; + + /** + * The projectile. + */ + private final Projectile projectile; + + /** + * If the handler should be used for visualizing/handling combat. + */ + private boolean useHandler; + + /** + * The maximum hit of this attack. + */ + private int maximumHit = -1; + + /** + * Constructs a new {@code SwitchAttack} {@code Object}. + * @param handler The combat handler. + * @param animation The animation. + */ + public SwitchAttack(CombatSwingHandler handler, Animation animation) { + this(handler, animation, null, null, null); + } + + /** + * Constructs a new {@code SwitchAttack} {@code Object}. + * @param handler The combat handler. + * @param animation The animation. + * @param startGraphic The start graphic. + */ + public SwitchAttack(CombatSwingHandler handler, Animation animation, Graphics startGraphic) { + this(handler, animation, startGraphic, null, null); + } + + /** + * Constructs a new {@code SwitchAttack} {@code Object}. + * @param handler The combat handler. + * @param animation The animation. + * @param startGraphic The start graphic. + * @param endGraphic The end graphic. + */ + public SwitchAttack(CombatSwingHandler handler, Animation animation, Graphics startGraphic, Graphics endGraphic) { + this(handler, animation, startGraphic, endGraphic, null); + } + + /** + * Constructs a new {@code SwitchAttack} {@code Object} + * @param handler the handler. + * @param projectile the projectile. + */ + public SwitchAttack(CombatSwingHandler handler, Animation animation, Projectile projectile) { + this(handler, animation, null, null, projectile); + } + + /** + * Constructs a new {@code SwitchAttack} {@code Object} + * @param style the style. + */ + public SwitchAttack(CombatStyle style) { + this(style.getSwingHandler(), null, null, null); + } + + /** + * Constructs a new {@code SwitchAttack} {@code Object}. + * @param handler The combat handler. + * @param animation The animation. + * @param startGraphic The start graphic. + * @param endGraphic The end graphic. + * @param projectile The projectile. + */ + public SwitchAttack(CombatSwingHandler handler, Animation animation, Graphics startGraphic, Graphics endGraphic, Projectile projectile) { + this.handler = handler; + this.animation = animation; + this.startGraphic = startGraphic; + this.endGraphic = endGraphic; + this.projectile = projectile; + } + + /** + * Checks if this attack can be selected. + * @param entity the entity. + * @param victim the victim. + * @param state the state. + * @return {@code True} if selected. + */ + public boolean canSelect(Entity entity, Entity victim, BattleState state) { + return true; + } + + /** + * Gets the combat swing handler. + * @return The swing handler. + */ + public CombatSwingHandler getHandler() { + return handler; + } + + /** + * Sets the combat swing handler. + * @param handler The swing handler. + */ + public void setHandler(CombatSwingHandler handler) { + this.handler = handler; + } + + /** + * Gets the style. + * @return The style. + */ + public CombatStyle getStyle() { + return handler.getType(); + } + + /** + * Gets the startGraphic. + * @return The startGraphic. + */ + public Graphics getStartGraphic() { + return startGraphic; + } + + /** + * Gets the animation. + * @return The animation. + */ + public Animation getAnimation() { + return animation; + } + + /** + * Gets the endGraphic. + * @return The endGraphic. + */ + public Graphics getEndGraphic() { + return endGraphic; + } + + /** + * Gets the projectile. + * @return The projectile. + */ + public Projectile getProjectile() { + return projectile; + } + + /** + * Gets the useHandler. + * @return The useHandler. + */ + public boolean isUseHandler() { + return useHandler; + } + + /** + * Sets the useHandler. + * @param useHandler The useHandler to set. + * @return This instance, for chaining. + */ + public SwitchAttack setUseHandler(boolean useHandler) { + this.useHandler = useHandler; + return this; + } + + /** + * Gets the maximumHit value. + * @return The maximumHit. + */ + public int getMaximumHit() { + return maximumHit; + } + + /** + * Sets the maximumHit value. + * @param maximumHit The maximumHit to set. + */ + public SwitchAttack setMaximumHit(int maximumHit) { + this.maximumHit = maximumHit; + return this; + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/combat/equipment/Weapon.java b/Server/src/main/core/game/node/entity/combat/equipment/Weapon.java new file mode 100644 index 0000000..c3c83a8 --- /dev/null +++ b/Server/src/main/core/game/node/entity/combat/equipment/Weapon.java @@ -0,0 +1,130 @@ +package core.game.node.entity.combat.equipment; + +import core.game.node.item.Item; + +/** + * Represents the type of weapon used. + * @author Emperor + */ +public class Weapon { + + /** + * The item id. + */ + private final int id; + + /** + * The item. + */ + private final Item item; + + /** + * The weapon's name. + */ + private final String name; + + /** + * The ammunition equipment slot (if any). + */ + private final int ammunitionSlot; + + /** + * The ammunition item (if any). + */ + private final Item ammunition; + + /** + * The weapon type. + */ + private WeaponType type; + + /** + * Represents the weapon types. + * @author Emperor + */ + public static enum WeaponType { + DEFAULT, CROSSBOW, DOUBLE_SHOT, THROWN, DEGRADING, STAFF, CHINCHOMPA; + } + + /** + * Constructs a new {@code Weapon} {@Code Object}. + * @param item The item. + */ + public Weapon(Item item) { + this(item, -1, null, WeaponType.DEFAULT); + } + + /** + * Constructs a new {@code Weapon} {@Code Object} using ammunition. + * @param item The item. + * @param ammunitionSlot The ammunition equipment slot. + * @param ammunition The ammunition item. + */ + public Weapon(Item item, int ammunitionSlot, Item ammunition) { + this(item, ammunitionSlot, ammunition, WeaponType.DEFAULT); + } + + /** + * Constructs a new {@code Weapon} {@Code Object} using ammunition. + * @param item The item. + * @param ammunitionSlot The ammunition equipment slot. + * @param ammunition The ammunition item. + * @param type The weapon type. + */ + public Weapon(Item item, int ammunitionSlot, Item ammunition, WeaponType type) { + this.id = item == null ? -1 : item.getId(); + this.item = item; + this.name = item == null ? "null" : item.getName(); + this.ammunition = ammunition; + this.ammunitionSlot = ammunitionSlot; + } + + /** + * @return the item. + */ + public Item getItem() { + return item; + } + + /** + * @return the ammunitionSlot. + */ + public int getAmmunitionSlot() { + return ammunitionSlot; + } + + /** + * @return the ammunition. + */ + public Item getAmmunition() { + return ammunition; + } + + /** + * @return the id. + */ + public int getId() { + return id; + } + + /** + * @return the type. + */ + public WeaponType getType() { + return type; + } + + /** + * @param type the type to set. + */ + public void setType(WeaponType type) { + this.type = type; + } + + /** + * @return the name. + */ + public String getName() { + return name; + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/combat/equipment/WeaponInterface.java b/Server/src/main/core/game/node/entity/combat/equipment/WeaponInterface.java new file mode 100644 index 0000000..cb74f3f --- /dev/null +++ b/Server/src/main/core/game/node/entity/combat/equipment/WeaponInterface.java @@ -0,0 +1,735 @@ +package core.game.node.entity.combat.equipment; + +import core.game.component.Component; +import core.game.component.ComponentDefinition; +import core.game.component.InterfaceType; +import core.game.container.impl.EquipmentContainer; +import core.game.node.entity.combat.spell.CombatSpell; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.SpellBookManager; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; +import core.net.packet.PacketRepository; +import core.net.packet.context.InterfaceConfigContext; +import core.net.packet.context.InterfaceContext; +import core.net.packet.context.StringContext; +import core.net.packet.out.Interface; +import core.net.packet.out.InterfaceConfig; +import core.net.packet.out.StringPacket; +import org.rs09.consts.Components; +import core.game.system.config.ItemConfigParser; + +import static core.api.ContentAPIKt.*; + + + +/** + * Represents the weapon interface component. + * @author Emperor + */ +public final class WeaponInterface extends Component { + + /** + * The modern spell ids. + */ + private static final int[] MODERN_SPELL_IDS = { 1, 4, 6, 8, 10, 14, 17, 20, 24, 27, 33, 38, 45, 48, 52, 55 }; + + /** + * The ancient spell ids. + */ + private static final int[] ANCIENT_SPELL_IDS = { 8, 12, 4, 0, 10, 14, 6, 2, 9, 13, 5, 1, 11, 15, 7, 3, 16, 17, 18, 19 }; + + /** + * The slayer staff spell ids + */ + private static final int[] SLAYER_STAFF_SPELL_IDS = { 22, 31, 45, 48, 52, 55 }; + + /** + * The void staff spell ids + */ + private static final int[] VOID_STAFF_SPELL_IDS = { 22, 42, 45, 48, 52, 55 }; + + /** + * The default attack animations. + */ + public static final Animation[] DEFAULT_ANIMS = { new Animation(422, Priority.HIGH), new Animation(423, Priority.HIGH), new Animation(422, Priority.HIGH), new Animation(422, Priority.HIGH) }; + + /** + * The stab equipment bonus index. + */ + public static final int BONUS_STAB = 0; + + /** + * The slash equipment bonus index. + */ + public static final int BONUS_SLASH = 1; + + /** + * The crush equipment bonus index. + */ + public static final int BONUS_CRUSH = 2; + + /** + * The magic equipment bonus index. + */ + public static final int BONUS_MAGIC = 3; + + /** + * The range equipment bonus index. + */ + public static final int BONUS_RANGE = 4; + + /** + * The accurate melee attack style + */ + public static final int STYLE_ACCURATE = 0; + + /** + * The aggressive attack style + */ + public static final int STYLE_AGGRESSIVE = 1; + + /** + * The controlled attack style + */ + public static final int STYLE_CONTROLLED = 2; + + /** + * The defensive attack style + */ + public static final int STYLE_DEFENSIVE = 3; + + /** + * The accurate range attack style + */ + public static final int STYLE_RANGE_ACCURATE = 4; + + /** + * The rapid range attack style + */ + public static final int STYLE_RAPID = 5; + + /** + * The long range attack style + */ + public static final int STYLE_LONG_RANGE = 6; + + /** + * The defensive spell cast attack style + */ + public static final int STYLE_DEFENSIVE_CAST = 7; + + /** + * The spell cast attack style + */ + public static final int STYLE_CAST = 8; + + /** + * The player. + */ + private final Player player; + + /** + * The current weapon interface. + */ + private WeaponInterfaces current; + + /** + * If the player has the special attack bar shown. + */ + private boolean specialBar; + + /** + * The player's attack animations. + */ + private Animation[] attackAnimations; + + /** + * Constructs a new {@code WeaponInterface} {@code Object}. + * @param player The player. + */ + public WeaponInterface(Player player) { + super(92); + this.player = player; + player.addExtension(WeaponInterface.class, this); + } + + @Override + public void open(Player player) { + current = null; + updateInterface(); + } + + /** + * Opens the interface. + */ + private void open() { + ComponentDefinition definition = ComponentDefinition.forId(Components.WEAPON_FISTS_SEL_92); + boolean resizable = player.getInterfaceManager().isResizable(); + PacketRepository.send(Interface.class, new InterfaceContext(player, definition.getWindowPaneId(resizable), definition.getChildId(resizable), id, definition.isWalkable())); + int slot = ensureStyleIndex(player, player.getSettings().getAttackStyleIndex()); + if (slot != player.getSettings().getAttackStyleIndex()) { + player.getSettings().toggleAttackStyleIndex(slot); + } + player.getProperties().setAttackStyle(current.getAttackStyles()[slot]); + checkStaffConfigs(slot); + } + + /** + * Ensures the style index. + * @param player The player. + * @param slot The attack style index. + * @return The index, ensured to be smaller than styles.length and larger + * than 0. + */ + private int ensureStyleIndex(Player player, int slot) { + AttackStyle style = player.getProperties().getAttackStyle(); + if (slot >= current.getAttackStyles().length) { + slot = current.getAttackStyles().length - 1; + if (style != null) { + for (int i = slot; i >= 0; i--) { + if (current.getAttackStyles()[i].style == style.style) { + return i; + } + } + } + return slot; + } + if (style != null && current.getAttackStyles()[slot].style != style.style) { + for (int i = current.getAttackStyles().length - 1; i >= 0; i--) { + if (current.getAttackStyles()[i].style == style.style) { + return i; + } + } + } + return slot; + } + + /** + * Get the proper config for the special bar. + * @return the config. + */ + private int getConfig(int buttons, int interfaceId){ + if(interfaceId == Components.WEAPON_STAFF_SEL_90){ + return 87;//Return Config + } + if(interfaceId != Components.WEAPON_WHIP_SEL_93 && + interfaceId != Components.WEAPON_WARHAMMER_SEL_76 && + interfaceId != Components.WEAPON_XBOW_SEL_79 && + interfaceId != Components.WEAPON_HALBERD_SEL_84 && + interfaceId != Components.WEAPON_THROWN_SEL_91) + { + switch(buttons){ + case 3: + return 13; + case 4: + return 12; + } + } else { + return 10; + } + return 10; + } + + /** + * Updates the interface. + */ + public void updateInterface() { + player.getInterfaceManager().getTabs()[0] = this; + Item weapon = player.getEquipment().get(EquipmentContainer.SLOT_WEAPON); + WeaponInterfaces inter = getWeaponInterface(weapon); + String name; + if (weapon != null) { + name = weapon.getDefinition().getName(); + specialBar = weapon.getDefinition().getConfiguration(ItemConfigParser.HAS_SPECIAL, false); + attackAnimations = weapon.getDefinition().getConfiguration(ItemConfigParser.ATTACK_ANIMS, DEFAULT_ANIMS); + } else { + name = "Unarmed"; + specialBar = false; + attackAnimations = DEFAULT_ANIMS; + } + if (inter != current) { + id = inter.interfaceId; + current = inter; + open(); + player.getProperties().getCombatPulse().updateStyle(); + } + if (player.getSettings().getAttackStyleIndex() < attackAnimations.length && !player.getAppearance().isNpc()) { + player.getProperties().setAttackAnimation(attackAnimations[player.getSettings().getAttackStyleIndex()]); + } + if (current != WeaponInterfaces.STAFF) { + selectAutoSpell(-1, false); + PacketRepository.send(InterfaceConfig.class, new InterfaceConfigContext(player, id, getConfig(current.getAttackStyles().length, current.getInterfaceId()), !specialBar)); + } else { //if staff + PacketRepository.send(InterfaceConfig.class, new InterfaceConfigContext(player, id, 87, !specialBar)); + } + if (!canAutocast(false)) { + if (current == WeaponInterfaces.STAFF && player.getAttribute("autocast_select", false)) { + open(); + } + selectAutoSpell(-1, true); + } + PacketRepository.send(StringPacket.class, new StringContext(player, name, id, 0)); + if (player.getSettings().isSpecialToggled()) { + player.getSettings().toggleSpecialBar(); + } + } + + /** + * Sets the current attack style. + * @param button The button the player has pressed. + * @return {@code True} if the attack style got set. + */ + public boolean setAttackStyle(int button) { + int slot = button - 1; + if (current != WeaponInterfaces.STAFF) { + slot--; + } + if (current == WeaponInterfaces.WARHAMMER_MAUL || (current.attackStyles.length > 2 && current.attackStyles[2].bonusType == BONUS_RANGE && current.getInterfaceId() != Components.WEAPON_THROWN_SEL_91)) { + slot = button == 4 ? 1 : button == 3 ? 2 : 0; + } else if (current == WeaponInterfaces.CLAWS) { + slot = button == 5 ? 1 : button == 3 ? 3 : slot; + } + if (current == WeaponInterfaces.AXE) { + if (button == 5) { + slot = 1; + } else if (button == 3) { + slot = 3; + } + } + if (slot < 0 || slot >= current.getAttackStyles().length) { + return false; + } + AttackStyle style = current.getAttackStyles()[slot]; + player.getProperties().setAttackStyle(style); + player.getSettings().toggleAttackStyleIndex(slot); + if (slot < attackAnimations.length && !player.getAppearance().isNpc()) { + player.getProperties().setAttackAnimation(attackAnimations[slot]); + } + checkStaffConfigs(button - 1); + return true; + } + + /** + * Checks the staff configurations. + * @param slot The slot of the current attack style selected. + */ + private void checkStaffConfigs(int slot) { + if (current != WeaponInterfaces.STAFF) { + selectAutoSpell(-1, false); + return; + } + boolean defensive = slot == 3; + setVarp(player, 439, defensive ? -5 : 0); + if (slot > 2) { + setVarp(player, 43, defensive ? -1 : 3); + } + }; + + /** + * Gets the autocast tab component id. + * @param spellId The spell id. + * @return The component id for the autocast select tab. + */ + public int getAutospellId(int spellId) { + boolean modern = player.getSpellBookManager().getSpellBook() == Components.MAGIC_192; + int[] data = modern ? MODERN_SPELL_IDS : ANCIENT_SPELL_IDS; + if (modern && player.getEquipment().getNew(3).getName().equalsIgnoreCase("Slayer's staff")) { + data = SLAYER_STAFF_SPELL_IDS; + } + if (modern && player.getEquipment().getNew(3).getName().equalsIgnoreCase("Void knight mace")) { + data = VOID_STAFF_SPELL_IDS; + } + for (int i = 0; i < data.length; i++) { + if (data[i] == spellId) { + return i; + } + } + return -1; + } + + /** + * Selects the current autocast spell. + * @param buttonId The button id. + * @param adjustAttackStyle If the attack style should be adjusted. + */ + public void selectAutoSpell(int buttonId, boolean adjustAttackStyle) { + boolean modern = player.getSpellBookManager().getSpellBook() == Components.MAGIC_192; + int[] data = modern ? MODERN_SPELL_IDS : ANCIENT_SPELL_IDS; + if (modern && player.getEquipment().getNew(3).getName().equalsIgnoreCase("Slayer's staff")) { + data = SLAYER_STAFF_SPELL_IDS; + } + if (modern && player.getEquipment().getNew(3).getName().equalsIgnoreCase("Void knight mace")) { + data = VOID_STAFF_SPELL_IDS; + } + CombatSpell current = player.getProperties().getAutocastSpell(); + if (buttonId >= data.length) { + return; + } + int configStart = modern ? 45 : 13; + if (current != null) { + for (int index = 0; index < data.length; index++) { + if (data[index] == current.getSpellId()) { + player.getPacketDispatch().sendInterfaceConfig(Components.WEAPON_STAFF_SEL_90, configStart + (2 * index), true); + player.getPacketDispatch().sendInterfaceConfig(Components.WEAPON_STAFF_SEL_90, 100 + configStart + (2 * index), true); + } + } + } + if (buttonId < 0) { + player.getProperties().setAutocastSpell(null); + if (adjustAttackStyle && current != null) { + setAttackStyle(3); + player.getProperties().getCombatPulse().updateStyle(); + } + return; + } + boolean defensive = player.getSettings().getAttackStyleIndex() == 3; + player.getPacketDispatch().sendInterfaceConfig(Components.WEAPON_STAFF_SEL_90, 183, defensive); + player.getPacketDispatch().sendInterfaceConfig(Components.WEAPON_STAFF_SEL_90, 83, !defensive); + current = (CombatSpell) (modern ? SpellBookManager.SpellBook.MODERN.getSpell(data[buttonId]) : SpellBookManager.SpellBook.ANCIENT.getSpell(data[buttonId])); + player.getProperties().setAutocastSpell(current); + int configId = configStart + (2 * buttonId); + if (modern && player.getEquipment().getNew(3).getName().equalsIgnoreCase("Slayer's staff") || modern && player.getEquipment().getNew(3).getName().equalsIgnoreCase("Void knight mace")) { + boolean slayer = player.getEquipment().getNew(3).getName().equalsIgnoreCase("Slayer's staff"); + switch (buttonId) { + case 0: + configId = 77; + break; + case 1: + if (slayer) { + configId = 79; + } else { + configId = 81; + } + break; + case 2: + configId = 69; + break; + case 3: + configId = 71; + break; + case 4: + configId = 73; + break; + case 5: + configId = 75; + break; + + } + if (configId >= 85 || configId <= 65) { + return; + } else { + player.getPacketDispatch().sendInterfaceConfig(Components.WEAPON_STAFF_SEL_90, (defensive ? 100 : 0) + configId, false); + } + } else { + configId += defensive ? 100 : 0; + switch (buttonId) { + case 16: + configId = defensive ? 265 : 253; + break; + case 17: + configId = defensive ? 268 : 256; + break; + case 18: + configId = defensive ? 271 : 259; + break; + case 19: + configId = defensive ? 274 : 262; + break; + } + player.getPacketDispatch().sendInterfaceConfig(Components.WEAPON_STAFF_SEL_90, configId, false); + } + + } + + /** + * Opens the autocast select. + */ + public void openAutocastSelect() { + if (current != WeaponInterfaces.STAFF) { + return; + } + if (!canAutocast(true)) { + setAttackStyle(3); + return; + } + player.setAttribute("autocast_select", true); + int id = player.getSpellBookManager().getSpellBook() == 193 ? 797 : 319; + boolean slayer = player.getEquipment().getNew(3).getName().equalsIgnoreCase("Slayer's staff"); + boolean mace = player.getEquipment().getNew(3).getName().equalsIgnoreCase("Void knight mace"); + if (slayer) { + id = 310; + } + if (mace) { + id = 406; + } + Component component = new Component(id); + component.getDefinition().setTabIndex(0); + component.getDefinition().setType(InterfaceType.TAB); + player.setAttribute("autocast_component",component); + player.getInterfaceManager().openTab(component); + } + + /** + * Checks if the player is currently able to autocast. + * @param message If we should notify the player if he's unable to autocast. + * @return {@code True} if so. + */ + public boolean canAutocast(boolean message) { + if (current != WeaponInterfaces.STAFF) { + return false; + } + if (player.getSpellBookManager().getSpellBook() == SpellBookManager.SpellBook.LUNAR.getInterfaceId()) { + if (message) { + player.getPacketDispatch().sendMessage("You can't autocast Lunar magic."); + } + return false; + } + boolean ancientStaff = player.getEquipment().getNew(3).getName().contains("ncient staff") || player.getEquipment().getNew(3).getName().contains("uriel's staff");; + if ((player.getSpellBookManager().getSpellBook() == Components.MAGIC_192 && ancientStaff) || (player.getSpellBookManager().getSpellBook() == Components.MAGIC_ZAROS_193 && !ancientStaff)) { + if (message) { + player.getPacketDispatch().sendMessage("You can only autocast ancient magicks with an Ancient or Zuriel's staff."); + } + return false; + } + return true; + } + + /** + * Gets the current weapon interface id. + * @return The component id. + */ + public static WeaponInterfaces getWeaponInterface(Item weapon) { + if (weapon == null) { + return WeaponInterfaces.values()[0]; + } + int slot = weapon.getDefinition().getConfiguration(ItemConfigParser.WEAPON_INTERFACE, 0); + return WeaponInterfaces.values()[slot]; + } + + /** + * Represents an attack style. + * @author Emperor + */ + public static class AttackStyle { + + /** + * The style type. + */ + private final int style; + + /** + * The bonus type. + */ + private final int bonusType; + + /** + * Constructs a new {@code AttackStyle} {@code Object}. + * @param style The style type. + * @param bonusType The bonus type. + */ + public AttackStyle(int style, int bonusType) { + this.style = style; + this.bonusType = bonusType; + } + + /** + * Gets the style. + * @return The style. + */ + public int getStyle() { + return style; + } + + /** + * Gets the bonusType. + * @return The bonusType. + */ + public int getBonusType() { + return bonusType; + } + } + + /** + * Represents the weapon interfaces. + * @author Emperor + */ + public static enum WeaponInterfaces { + + /** + * The unarmed weapon interface (ordinal=0) + */ + UNARMED(Components.WEAPON_FISTS_SEL_92, new AttackStyle(STYLE_ACCURATE, BONUS_CRUSH), new AttackStyle(STYLE_AGGRESSIVE, BONUS_CRUSH), new AttackStyle(STYLE_DEFENSIVE, BONUS_CRUSH)), + + /** + * The staff weapon interface (ordinal=1) + */ + STAFF(Components.WEAPON_STAFF_SEL_90, new AttackStyle(STYLE_ACCURATE, BONUS_CRUSH), new AttackStyle(STYLE_AGGRESSIVE, BONUS_CRUSH), new AttackStyle(STYLE_DEFENSIVE, BONUS_CRUSH), new AttackStyle(STYLE_DEFENSIVE_CAST, BONUS_MAGIC), new AttackStyle(STYLE_CAST, BONUS_MAGIC)), + + /** + * The (battle) axe weapon interface (ordinal=2) + */ + AXE(Components.WEAPON_BAXE_SEL_75, new AttackStyle(STYLE_ACCURATE, BONUS_SLASH), new AttackStyle(STYLE_AGGRESSIVE, BONUS_SLASH), new AttackStyle(STYLE_AGGRESSIVE, BONUS_CRUSH), new AttackStyle(STYLE_DEFENSIVE, BONUS_SLASH)), + + /** + * The scepter weapon interface (ordinal=3) + */ + SCEPTER(Components.WEAPON_SCEPTER_SEL_85, new AttackStyle(STYLE_ACCURATE, BONUS_CRUSH), new AttackStyle(STYLE_AGGRESSIVE, BONUS_CRUSH), new AttackStyle(STYLE_DEFENSIVE, BONUS_CRUSH)), + + /** + * The pickaxe weapon interface (ordinal=4) + */ + PICKAXE(Components.WEAPON_PICKAXE_SEL_83, new AttackStyle(STYLE_ACCURATE, BONUS_STAB), new AttackStyle(STYLE_AGGRESSIVE, BONUS_STAB), new AttackStyle(STYLE_AGGRESSIVE, BONUS_CRUSH), new AttackStyle(STYLE_DEFENSIVE, BONUS_STAB)), + + /** + * The sword/dagger weapon interface (ordinal=5) + */ + SWORD_DAGGER(Components.WEAPON_DAGGER_SEL_89, new AttackStyle(STYLE_ACCURATE, BONUS_STAB), new AttackStyle(STYLE_AGGRESSIVE, BONUS_STAB), new AttackStyle(STYLE_AGGRESSIVE, BONUS_SLASH), new AttackStyle(STYLE_DEFENSIVE, BONUS_STAB)), + + /** + * The scimitar/silverlight/silver sickle/... weapon interface + * (ordinal=6) + */ + SCIMITAR(Components.WEAPON_SCIMITAR_SEL_81, new AttackStyle(STYLE_ACCURATE, BONUS_SLASH), new AttackStyle(STYLE_AGGRESSIVE, BONUS_SLASH), new AttackStyle(STYLE_CONTROLLED, BONUS_STAB), new AttackStyle(STYLE_DEFENSIVE, BONUS_SLASH)), + + /** + * The 2-h sword weapon interface (ordinal=7) + */ + TWO_H_SWORD(Components.WEAPON_2H_SWORD_SEL_82, new AttackStyle(STYLE_ACCURATE, BONUS_SLASH), new AttackStyle(STYLE_AGGRESSIVE, BONUS_SLASH), new AttackStyle(STYLE_AGGRESSIVE, BONUS_CRUSH), new AttackStyle(STYLE_DEFENSIVE, BONUS_SLASH)), + + /** + * The mace weapon interface (ordinal=8) + */ + MACE(Components.WEAPON_MACE_SEL_88, new AttackStyle(STYLE_ACCURATE, BONUS_CRUSH), new AttackStyle(STYLE_AGGRESSIVE, BONUS_CRUSH), new AttackStyle(STYLE_CONTROLLED, BONUS_STAB), new AttackStyle(STYLE_DEFENSIVE, BONUS_CRUSH)), + + /** + * The claws weapon interface (ordinal=9) + */ + CLAWS(Components.WEAPON_CLAWS_SEL_78, new AttackStyle(STYLE_ACCURATE, BONUS_SLASH), new AttackStyle(STYLE_AGGRESSIVE, BONUS_SLASH), new AttackStyle(STYLE_CONTROLLED, BONUS_STAB), new AttackStyle(STYLE_DEFENSIVE, BONUS_SLASH)), + + /** + * The warhammer/maul weapon interface (ordinal=10) + */ + WARHAMMER_MAUL(Components.WEAPON_WARHAMMER_SEL_76, new AttackStyle(STYLE_ACCURATE, BONUS_CRUSH), new AttackStyle(STYLE_AGGRESSIVE, BONUS_CRUSH), new AttackStyle(STYLE_DEFENSIVE, BONUS_CRUSH)), + + /** + * The abyssal whip weapon interface (ordinal=11) + */ + WHIP(Components.WEAPON_WHIP_SEL_93, new AttackStyle(STYLE_ACCURATE, BONUS_SLASH), new AttackStyle(STYLE_CONTROLLED, BONUS_SLASH), new AttackStyle(STYLE_DEFENSIVE, BONUS_SLASH)), + + /** + * The flowers weapon interface (ordinal=12) + */ + FLOWERS(Components.WEAPON_WARHAMMER_SEL_76, new AttackStyle(STYLE_ACCURATE, BONUS_CRUSH), new AttackStyle(STYLE_AGGRESSIVE, BONUS_CRUSH), new AttackStyle(STYLE_DEFENSIVE, BONUS_CRUSH)), + + /** + * The mud pie weapon interface (ordinal=13) + */ + MUD_PIE(Components.WEAPON_THROWN_SEL_91, new AttackStyle(STYLE_RANGE_ACCURATE, BONUS_RANGE), new AttackStyle(STYLE_RAPID, BONUS_RANGE), new AttackStyle(STYLE_LONG_RANGE, BONUS_RANGE)), + + /** + * The spear weapon interface (ordinal=14) + */ + SPEAR(Components.WEAPON_SPEAR_SEL_87, new AttackStyle(STYLE_CONTROLLED, BONUS_STAB), new AttackStyle(STYLE_CONTROLLED, BONUS_SLASH), new AttackStyle(STYLE_CONTROLLED, BONUS_CRUSH), new AttackStyle(STYLE_DEFENSIVE, BONUS_STAB)), + + /** + * The halberd weapon interface (ordinal=15) + */ + HALBERD(Components.WEAPON_HALBERD_SEL_84, new AttackStyle(STYLE_CONTROLLED, BONUS_STAB), new AttackStyle(STYLE_AGGRESSIVE, BONUS_SLASH), new AttackStyle(STYLE_DEFENSIVE, BONUS_STAB)), + + /** + * The bow weapon interface (ordinal=16) + */ + BOW(Components.WEAPON_BOW_SEL_77, new AttackStyle(STYLE_RANGE_ACCURATE, BONUS_RANGE), new AttackStyle(STYLE_RAPID, BONUS_RANGE), new AttackStyle(STYLE_LONG_RANGE, BONUS_RANGE)), + + /** + * The crossbow weapon interface (ordinal=17) + */ + CROSSBOW(Components.WEAPON_XBOW_SEL_79, new AttackStyle(STYLE_RANGE_ACCURATE, BONUS_RANGE), new AttackStyle(STYLE_RAPID, BONUS_RANGE), new AttackStyle(STYLE_LONG_RANGE, BONUS_RANGE)), + + /** + * The thrown weapons weapon interface (ordinal=18) + */ + THROWN_WEAPONS(Components.WEAPON_THROWN_SEL_91, new AttackStyle(STYLE_RANGE_ACCURATE, BONUS_RANGE), new AttackStyle(STYLE_RAPID, BONUS_RANGE), new AttackStyle(STYLE_LONG_RANGE, BONUS_RANGE)), + + /** + * The thrown weapons weapon interface (ordinal=19) + */ + CHINCHOMPA(Components.WEAPON_CHINCHOMPA_SEL_473, new AttackStyle(STYLE_RANGE_ACCURATE, BONUS_RANGE), new AttackStyle(STYLE_RAPID, BONUS_RANGE), new AttackStyle(STYLE_LONG_RANGE, BONUS_RANGE)), + + /** + * The fixed device weapon interface (ordinal=20) + */ + FIXED_DEVICE(Components.WEAPON_FIXED_DEVICE_SEL_80, new AttackStyle(STYLE_RANGE_ACCURATE, BONUS_RANGE), new AttackStyle(STYLE_AGGRESSIVE, BONUS_CRUSH)), + + /** + * The salamander weapon interface (ordinal=21) + */ + SALAMANDER(Components.WEAPON_SALAMANDER_SEL_474, new AttackStyle(STYLE_AGGRESSIVE, BONUS_SLASH), new AttackStyle(STYLE_RANGE_ACCURATE, BONUS_RANGE), new AttackStyle(STYLE_DEFENSIVE_CAST, BONUS_MAGIC)), + + /** + * The scythe weapon interface (ordinal=22) + */ + SCYTHE(Components.WEAPON_SCYTHE_SEL_86, new AttackStyle(STYLE_ACCURATE, BONUS_SLASH), new AttackStyle(STYLE_AGGRESSIVE, BONUS_STAB), new AttackStyle(STYLE_AGGRESSIVE, BONUS_CRUSH), new AttackStyle(STYLE_DEFENSIVE, BONUS_SLASH)), + + /** + * The ivandis flail weapon interface (ordinal=23) TODO: Find correct + * interface id! + */ + IVANDIS_FLAIL(Components.WEAPON_SCEPTER_SEL_85, new AttackStyle(STYLE_ACCURATE, BONUS_CRUSH), new AttackStyle(STYLE_AGGRESSIVE, BONUS_CRUSH), new AttackStyle(STYLE_DEFENSIVE, BONUS_CRUSH)); + + /** + * The interface id. + */ + private final int interfaceId; + + /** + * The attack styles. + */ + private final AttackStyle[] attackStyles; + + /** + * Constructs a new {@code WeaponInterface} {@code Object}. + * @param interfaceId The interface id. + * @param attackStyles The attack styles. + */ + private WeaponInterfaces(int interfaceId, AttackStyle... attackStyles) { + this.interfaceId = interfaceId; + this.attackStyles = attackStyles; + } + + /** + * Gets the interfaceId. + * @return The interfaceId. + */ + public int getInterfaceId() { + return interfaceId; + } + + /** + * Gets the attackStyles. + * @return The attackStyles. + */ + public AttackStyle[] getAttackStyles() { + return attackStyles; + } + } + + /** + * Gets the currently opened weapon interface. + * @return The current weapon interface. + */ + public WeaponInterfaces getWeaponInterface() { + return current; + } + + /** + * If the special bar is enabled. + * @return {@code True} if so. + */ + public boolean isSpecialBar() { + return specialBar; + } + +} diff --git a/Server/src/main/core/game/node/entity/combat/graves/Grave.kt b/Server/src/main/core/game/node/entity/combat/graves/Grave.kt new file mode 100644 index 0000000..2118ab7 --- /dev/null +++ b/Server/src/main/core/game/node/entity/combat/graves/Grave.kt @@ -0,0 +1,173 @@ +package core.game.node.entity.combat.graves + +import core.api.clearHintIcon +import core.api.registerHintIcon +import core.api.sendMessage +import core.game.node.entity.npc.AbstractNPC +import core.game.node.entity.player.Player +import core.game.node.item.GroundItem +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import core.game.world.map.Location +import core.plugin.Initializable +import org.rs09.consts.NPCs +import core.game.world.GameWorld +import core.game.world.repository.Repository +import core.tools.secondsToTicks +import core.tools.colorize +import core.tools.ticksToSeconds + +@Initializable +class Grave : AbstractNPC { + lateinit var type: GraveType + private val items = ArrayList() + var ownerUsername: String = "" + var ownerUid: Int = -1 + + var ticksRemaining = -1 + + constructor() : super(NPCs.GRAVESTONE_6571, Location.create(0,0,0), false) + private constructor(id: Int, location: Location) : super(id, location) + + override fun construct(id: Int, location: Location, vararg objects: Any): AbstractNPC { + return Grave(id, location) + } + + override fun getIds(): IntArray { + return GraveType.ids + } + + fun configureType(type: GraveType) { + this.type = type + this.transform(type.npcId) + this.ticksRemaining = secondsToTicks(type.durationMinutes * 60) + } + + fun initialize(player: Player, location: Location, inventory: Array) { + if (!GraveController.allowGenerate(player)) + return + + this.ownerUid = player.details.uid + this.ownerUsername = player.username + this.location = player.getAttribute("/save:original-loc",location) + this.isRespawn = false + this.isWalks = false + this.isNeverWalks = true + + for (item in inventory) { + if (GraveController.shouldRelease(item.id)) { + sendMessage(player, "Your ${item.name.lowercase().replace("jar", "")} has escaped.") + continue + } + + if (GraveController.shouldCrumble(item.id)) { + sendMessage(player, "Your ${item.name.lowercase()} has crumbled to dust.") + continue + } + + val finalItem = GraveController.checkTransform(item) + + val gi = GroundItemManager.create(finalItem, this.location, player) + gi.isRemainPrivate = true + gi.decayTime = secondsToTicks(type.durationMinutes * 60) + this.items.add(gi) + } + + if (items.isEmpty()) { + clear() + return + } + + this.init() + + if (GraveController.activeGraves[ownerUid] != null) { + val oldGrave = GraveController.activeGraves[ownerUid] + oldGrave?.collapse() + } + + GraveController.activeGraves[ownerUid] = this + sendMessage(player, colorize("%RBecause of your current gravestone, you have ${type.durationMinutes} minutes to get your items back.")) + } + + fun setupFromJsonParams(playerUid: Int, ticks: Int, location: Location, items: Array, username: String) { + this.ownerUid = playerUid + this.ticksRemaining = ticks + this.location = location + this.isRespawn = false + this.isWalks = false + this.isNeverWalks = true + this.ownerUsername = username + + for (item in items) { + val gi = GroundItemManager.create(item, location, playerUid, GameWorld.ticks + ticksRemaining) + gi.isRemainPrivate = true + this.items.add(gi) + } + + this.transform(type.npcId) + this.init() + } + + override fun tick() { + //Grave should not do anything else on tick, that is all handled by GraveController. + if (Repository.uid_map[ownerUid] != null) { + val p = Repository.uid_map[ownerUid] ?: return + registerHintIcon(p, this) + } + } + + fun addTime(ticks: Int) { + ticksRemaining += ticks + for (gi in items) { + gi.decayTime = ticksRemaining + } + if (ticksRemaining < 30) + transform(type.npcId + 2) + else if (ticksRemaining < 90) + transform(type.npcId + 1) + else + transform(type.npcId) + } + + fun collapse() { + for (item in items) { + GroundItemManager.destroy(item) + } + clear() + GraveController.activeGraves.remove(ownerUid) + if (Repository.uid_map[ownerUid] != null) { + val p = Repository.uid_map[ownerUid] ?: return + clearHintIcon(p) + } + } + + fun demolish() { + val owner = Repository.uid_map[ownerUid] ?: return + for (item in items) { + if (!item.isRemoved) + item.decayTime = secondsToTicks(45) + } + clear() + sendMessage(owner, "It looks like it'll last another ${getFormattedTimeRemaining()}.") + sendMessage(owner, "You demolish it anyway.") + GraveController.activeGraves.remove(ownerUid) + clearHintIcon(owner) + } + + fun getItems() : Array { + return this.items.toTypedArray() + } + + fun retrieveFormattedText(): String { + return type.text + .replace("@name", ownerUsername) + .replace("@mins", getFormattedTimeRemaining()) + } + + fun getFormattedTimeRemaining() : String { + val seconds = ticksToSeconds(ticksRemaining) + val timeQty = if (seconds / 60 > 0) seconds / 60 else seconds + val timeUnit = (if (seconds / 60 > 0) "minute" else "second") + if (timeQty > 1) "s" else "" + return "$timeQty $timeUnit" + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/combat/graves/GraveController.kt b/Server/src/main/core/game/node/entity/combat/graves/GraveController.kt new file mode 100644 index 0000000..00e0e0b --- /dev/null +++ b/Server/src/main/core/game/node/entity/combat/graves/GraveController.kt @@ -0,0 +1,297 @@ +package core.game.node.entity.combat.graves + +import core.api.* +import core.game.node.Node +import core.game.node.entity.combat.ImpactHandler +import core.game.node.entity.player.Player +import core.game.node.entity.player.info.Rights +import core.game.node.entity.player.link.IronmanMode +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.map.zone.ZoneRestriction +import org.json.simple.JSONArray +import org.json.simple.JSONObject +import org.rs09.consts.Items +import core.ServerStore +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.game.interaction.QueueStrength +import core.game.system.command.Privilege +import core.game.world.GameWorld +import core.game.world.map.zone.impl.WildernessZone +import core.game.world.repository.Repository +import core.tools.secondsToTicks +import core.tools.colorize +import org.rs09.consts.Sounds +import java.util.Map +import kotlin.math.min + +class GraveController : PersistWorld, TickListener, InteractionListener, Commands { + override fun defineListeners() { + on(GraveType.ids, IntType.NPC, "read", handler = this::onGraveReadOption) + on(GraveType.ids, IntType.NPC, "bless", handler = this::onGraveBlessed) + on(GraveType.ids, IntType.NPC, "repair", handler = this::onGraveRepaired) + on(GraveType.ids, IntType.NPC, "demolish", handler = this::onGraveDemolished) + } + + override fun defineCommands() { + define("forcegravedeath", Privilege.ADMIN, "", "Forces a death that should produce a grave.") { player, _ -> + player.details.rights = Rights.REGULAR_PLAYER + setAttribute(player, "tutorial:complete", true) + player.impactHandler.manualHit(player, player.skills.lifepoints, ImpactHandler.HitsplatType.NORMAL) + notify(player, "Grave created at ${player.getAttribute("/save:original-loc", player.location)}") + queueScript(player, 15, QueueStrength.SOFT) { stage: Int -> + player.details.rights = Rights.ADMINISTRATOR + sendMessage(player, "Rights restored") + return@queueScript stopExecuting(player) + } + } + } + + + override fun tick() { + for (grave in activeGraves.values.toTypedArray()) { + if (grave.ticksRemaining == -1) return + + if (grave.ticksRemaining == secondsToTicks(30) || grave.ticksRemaining == secondsToTicks(90)) { + grave.transform(grave.id + 1) + } + + if (grave.ticksRemaining == 0) { + grave.collapse() + } + + grave.ticksRemaining-- + } + } + + private fun onGraveReadOption(player: Player, node: Node) : Boolean { + val grave = node as? Grave ?: return false + + var isGraniteBackground = false + + when (grave.type) { + in GraveType.SMALL_GS..GraveType.ANGEL_DEATH -> isGraniteBackground = true + else -> {} + } + + if (isGraniteBackground) + setVarbit(player, 4191, 1) + else + setVarbit(player, 4191, 0) + + openInterface(player, 266) + setInterfaceText(player, grave.retrieveFormattedText(), 266, 23) + + sendMessage(player, "It looks like it'll survive another ${grave.getFormattedTimeRemaining()}.") + if (player.details.uid == grave.ownerUid) { + sendMessage(player, "Isn't there something a bit odd about reading your own gravestone?") + } + return true + } + + private fun onGraveBlessed(player: Player, node: Node) : Boolean { + val g = node as? Grave ?: return false + + if (getAttribute(g, "blessed", false)) { + sendMessage(player, "This grave has already been blessed.") + return true + } + + if (player.details.uid == g.ownerUid) { + sendMessage(player, "The gods don't seem to approve of people attempting to bless their own gravestones.") + return true + } + + val gOwner = Repository.uid_map[g.ownerUid] + if (gOwner != null && gOwner.ironmanManager.isIronman) { + sendMessage(player, "This grave belongs to an Ironman.") + return true + } + + if (getStatLevel(player, Skills.PRAYER) < 70) { + sendMessage(player, "You need a Prayer level of 70 to bless a grave.") + return true + } + + val blessAmount = min(60, player.skills.prayerPoints.toInt() - 10) + + if (blessAmount <= 0) { + sendMessage(player, "You do not have enough prayer points to do that.") + return true + } + + g.addTime(secondsToTicks(blessAmount * 60)) + player.skills.prayerPoints -= blessAmount + setAttribute(g, "blessed", true) + + playAudio(player, Sounds.PRAYER_RECHARGE_2674) + animate(player, 645) + + if (gOwner != null) { + sendMessage(gOwner, colorize("%RYour grave has been blessed.")) + } + return true + } + + private fun onGraveRepaired(player: Player, node: Node) : Boolean { + val g = node as? Grave ?: return false + + if (getAttribute(g, "repaired", false)) { + sendMessage(player, "This grave has already been repaired.") + return true + } + + if (getStatLevel(player, Skills.PRAYER) < 2) { + sendMessage(player, "You need a Prayer level of 2 to bless a grave.") + return true + } + + if (player.skills.prayerPoints < 1.0) { + sendMessage(player, "You do not have enough prayer points to do that.") + return true + } + + val restoreAmount = min(5, player.skills.prayerPoints.toInt()) + g.addTime(secondsToTicks(restoreAmount * 60)) + player.skills.prayerPoints -= restoreAmount + setAttribute(g, "repaired", true) + + playAudio(player, Sounds.PRAYER_RECHARGE_2674) + animate(player, 645) + return true + } + + private fun onGraveDemolished(player: Player, node: Node) : Boolean { + val g = node as? Grave ?: return false + + if (player.details.uid != g.ownerUid) { + sendMessage(player, "You cannot demolish someone else's gravestone!") + return true + } + + g.demolish() + return true + } + + override fun save() { + serializeToServerStore() + } + + override fun parse() { + deserializeFromServerStore() + } + + companion object { + val activeGraves = HashMap() + var childCounter = 0 + val ATTR_GTYPE = "/save:gravetype" + + @JvmStatic fun produceGrave(type: GraveType): Grave { + val g = Grave() + g.configureType(type) + return g + } + + @JvmStatic fun shouldCrumble(item: Int) : Boolean { + when (item) { + Items.ECTOPHIAL_4251 -> return true + in Items.SMALL_POUCH_5509..Items.GIANT_POUCH_5515 -> return true + } + + return itemDefinition(item).hasAction("destroy") + } + + @JvmStatic fun shouldRelease(item: Int) : Boolean { + when (item) { + Items.CHINCHOMPA_9976 -> return true + Items.CHINCHOMPA_10033 -> return true + in Items.BABY_IMPLING_JAR_11238..Items.DRAGON_IMPLING_JAR_11257 -> return itemDefinition(item).isUnnoted + } + + return false + } + + @JvmStatic fun checkTransform(item: Item) : Item { + if (item.hasItemPlugin()) + return item.plugin.getDeathItem(item) + return item + } + + @JvmStatic fun allowGenerate(player: Player) : Boolean { + if (player.skullManager.isSkulled) + return false + if (player.skullManager.isWilderness) + return false + if (WildernessZone.isInZone(player)) + return false + if (player.ironmanManager.mode == IronmanMode.HARDCORE) + return false + if (player.zoneMonitor.isRestricted(ZoneRestriction.GRAVES)) + return false + return true + } + + @JvmStatic fun getGraveType(player: Player) : GraveType { + return GraveType.values()[getAttribute(player, ATTR_GTYPE, 0)] + } + + @JvmStatic fun updateGraveType(player: Player, type: GraveType) { + setAttribute(player, ATTR_GTYPE, type.ordinal) + } + + @JvmStatic fun hasGraveAt(loc: Location) : Boolean { + return activeGraves.values.toTypedArray().any { it.location == loc } + } + + fun serializeToServerStore() { + val archive = ServerStore.getArchive("active-graves") + archive.clear() + for ((uid,grave) in activeGraves) { + val g = JSONObject() + g["ticksRemaining"] = grave.ticksRemaining + g["location"] = grave.location.toString() + g["type"] = grave.type.ordinal + g["username"] = grave.ownerUsername + val items = JSONArray() + for (item in grave.getItems()) { + val i = JSONObject() + i["id"] = item.id + i["amount"] = item.amount + i["charge"] = item.charge + items.add(i) + } + g["items"] = items + archive["$uid"] = g + } + } + + fun deserializeFromServerStore() { + val archive = ServerStore.getArchive("active-graves") + for (entry in archive.entries as Set>) { + val g = entry.value as JSONObject + val uid = (entry.key as String).toInt() + val type = g["type"].toString().toInt() + val ticks = g["ticksRemaining"].toString().toInt() + val location = Location.fromString(g["location"].toString()) + val username = g["username"].toString() + + val items = ArrayList() + val itemsRaw = g["items"] as JSONArray + for (itemRaw in itemsRaw) { + val item = itemRaw as JSONObject + val id = item["id"].toString().toInt() + val amount = item["amount"].toString().toInt() + val charge = item["charge"].toString().toInt() + items.add(Item(id, amount, charge)) + } + + val grave = produceGrave(GraveType.values()[type]) + grave.setupFromJsonParams(uid, ticks, location, items.toTypedArray(), username) + activeGraves[uid] = grave + } + } + } +} diff --git a/Server/src/main/core/game/node/entity/combat/graves/GravePurchaseInterface.kt b/Server/src/main/core/game/node/entity/combat/graves/GravePurchaseInterface.kt new file mode 100644 index 0000000..86a589f --- /dev/null +++ b/Server/src/main/core/game/node/entity/combat/graves/GravePurchaseInterface.kt @@ -0,0 +1,65 @@ +package core.game.node.entity.combat.graves + +import core.api.* +import core.game.node.item.Item +import org.rs09.consts.Components +import org.rs09.consts.Items +import core.game.interaction.InterfaceListener + +class GravePurchaseInterface : InterfaceListener { + val BUTTON_CONFIRM = 34 + val AVAILABLE_GRAVES_BITFIELD = 0xFFF //Enable all graves, authentically the quest-locked ones should be excluded from the bitfield, but y'know. + val AVAILABLE_GRAVES_VARBIT = 4191 + val CURRENT_GRAVE_VARBIT = 4190 + + override fun defineInterfaceListeners() { + onOpen (Components.GRAVESTONE_SHOP_652) {player, _ -> + val userType = GraveController.getGraveType(player).ordinal + setVarbit(player, AVAILABLE_GRAVES_VARBIT, AVAILABLE_GRAVES_BITFIELD) + setVarbit(player, CURRENT_GRAVE_VARBIT, userType) + + val settings = IfaceSettingsBuilder() + .enableAllOptions() + .build() + player.packetDispatch.sendIfaceSettings(settings, 34, Components.GRAVESTONE_SHOP_652, 0, 13) + return@onOpen true + } + + on (Components.GRAVESTONE_SHOP_652, BUTTON_CONFIRM) { player, _, _, _, slot, _ -> + val selectedType = GraveType.values()[slot] + val userType = GraveController.getGraveType(player) + val activeGrave = GraveController.activeGraves[player.details.uid] + + if (activeGrave != null){ + sendDialogue(player, "You cannot change graves while you have a grave active.") + return@on true + } + + if (selectedType == userType) { + sendDialogue(player, "You already have that gravestone!") + return@on true + } + + val cost = selectedType.cost + val requirement = selectedType.requiredQuest + + if (requirement != null && !isQuestComplete(player, requirement)) { + sendDialogue(player, "That gravestone requires completion of $requirement.") + return@on true + } + + if (selectedType != GraveType.MEM_PLAQUE && amountInInventory(player, Items.COINS_995) < cost) { + sendDialogue(player, "You do not have enough coins to afford that gravestone.") + return@on true + } + + if (selectedType == GraveType.MEM_PLAQUE || removeItem(player, Item(995, cost))) { + GraveController.updateGraveType(player, selectedType) + sendDialogue(player, "Your grave has been updated.") + } + + closeInterface(player) + return@on true + } + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/combat/graves/GraveType.kt b/Server/src/main/core/game/node/entity/combat/graves/GraveType.kt new file mode 100644 index 0000000..1a91058 --- /dev/null +++ b/Server/src/main/core/game/node/entity/combat/graves/GraveType.kt @@ -0,0 +1,29 @@ +package core.game.node.entity.combat.graves + +import org.rs09.consts.NPCs +import content.data.Quests + +enum class GraveType(val npcId: Int, val cost: Int, val durationMinutes: Int, val isMembers: Boolean, val requiredQuest: Quests? = null, val text: String) { + MEM_PLAQUE(NPCs.GRAVE_MARKER_6565, 0, 2, false, text = "In memory of @name,
who died here."), + FLAG(NPCs.GRAVE_MARKER_6568, 50, 2, false, text = MEM_PLAQUE.text), + SMALL_GS(NPCs.GRAVESTONE_6571, 500, 2, false, text = "In loving memory of our dear friend @name,
who died in this place @mins ago."), + ORNATE_GS(NPCs.GRAVESTONE_6574, 5000, 3, false, text = SMALL_GS.text), + FONT_OF_LIFE(NPCs.GRAVESTONE_6577, 50000, 4, true, text = "In your travels,
pause awhile to remember @name,
who passed away at this spot."), + STELE(NPCs.STELE_6580, 50000, 4, true, text = FONT_OF_LIFE.text), + SARA_SYMBOL(NPCs.SARADOMIN_SYMBOL_6583, 50000, 4, true, text = "@name,
an enlightened servant of Saradomin,
perished in this place."), + ZAM_SYMBOL(NPCs.ZAMORAK_SYMBOL_6586, 50000, 4, true, text = "@name,
a most bloodthirsty follower of Zamorak,
perished in this place."), + GUTH_SYMBOL(NPCs.GUTHIX_SYMBOL_6589, 50000, 4, true, text = "@name,
who walked with the Balance of Guthix,
perished in this place."), + BAND_SYMBOL(NPCs.BANDOS_SYMBOL_6592, 50000, 4, true, requiredQuest = Quests.LAND_OF_THE_GOBLINS, text = "@name,
a vicious warrior dedicated to Bandos,
perished in this place. "), + ARMA_SYMBOL(NPCs.ARMADYL_SYMBOL_6595, 50000, 4, true, requiredQuest = Quests.TEMPLE_OF_IKOV, text = "@name,
a follower of the Law of Armadyl,
perished in this place."), + ZARO_SYMBOL(NPCs.MEMORIAL_STONE_6598, 50000, 4, true, requiredQuest = Quests.DESERT_TREASURE, text = "@name,
servant of the Unknown Power,
perished in this place."), + ANGEL_DEATH(NPCs.MEMORIAL_STONE_6601, 500000, 5, true, text = "Ye frail mortals who gaze upon this sight,
forget not the fate of @name, once mighty, now
surrendered to the inescapable grasp of destiny.
Requiescat in pace."); + + companion object { + val ids = values().fold(ArrayList()) {list, type -> + list.add(type.npcId) + list.add(type.npcId + 1) + list.add(type.npcId + 2) + list + }.toIntArray() + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/combat/spell/CombatSpell.java b/Server/src/main/core/game/node/entity/combat/spell/CombatSpell.java new file mode 100644 index 0000000..3601d68 --- /dev/null +++ b/Server/src/main/core/game/node/entity/combat/spell/CombatSpell.java @@ -0,0 +1,238 @@ +package core.game.node.entity.combat.spell; + +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.InteractionType; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.SpellBookManager; +import core.game.node.entity.player.link.audio.Audio; +import core.game.node.item.Item; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import org.rs09.consts.Sounds; + +import java.util.ArrayList; +import java.util.List; + +import static core.api.ContentAPIKt.playGlobalAudio; + +/** + * Represents a combat magic spell. + * @author Emperor + */ +public abstract class CombatSpell extends MagicSpell { + + /** + * The autocast animation. + */ + public static final Animation AUTOCAST_ANIMATION = new Animation(1162, Priority.HIGH); + + /** + * The splash graphics. + */ + public static final Graphics SPLASH_GRAPHIC = new Graphics(85, 96); + + /** + * The current spell type. + */ + protected final SpellType type; + + /** + * The projectile. + */ + protected Projectile projectile; + + /** + * The end graphic. + */ + protected final Graphics endGraphic; + + /** + * The impact Audio. + */ + protected final int impactAudio; + + /** + * Constructs a new {@code CombatSpell} {@Code Object} + */ + public CombatSpell() { + this(SpellType.NULL, SpellBookManager.SpellBook.MODERN, 1, 0.0, -1, -1, null, null, null, null); + } + + /** + * Constructs a new {@code CombatSpell} {@Code Object} + * @param type The spell type. + * @param book The spell book. + * @param level The level required. + * @param baseExperience The base experience. + * @param castAudio The Audio id of the casting Audio. + * @param impactAudio The Audio id of the impact Audio. + * @param animation the cast animation. + * @param startGraphic The start graphic. + * @param projectile The projectile. + * @param endGraphic The end graphic. + * @param runes The runes required to cast this spell. + */ + public CombatSpell(SpellType type, SpellBookManager.SpellBook book, int level, double baseExperience, int castAudio, int impactAudio, Animation animation, Graphics startGraphic, Projectile projectile, Graphics endGraphic, Item... runes) { + super(book, level, baseExperience, animation, startGraphic, new Audio(castAudio, 1, 0), runes); + this.type = type; + this.impactAudio = impactAudio; + this.projectile = projectile; + this.endGraphic = endGraphic; + } + + /** + * Gets the maximum impact amount of this spell. + * @param entity The entity. + * @param victim The victim. + * @param state The battle state. + * @return The maximum impact amount. + */ + public abstract int getMaximumImpact(Entity entity, Entity victim, BattleState state); + + /** + * Starts the effect of this spell (if any). + * @param entity The entity. + * @param victim The victim. + * @param state The battle state. + */ + public void fireEffect(Entity entity, Entity victim, BattleState state) { + + } + + /** + * Gets a list of possible targets for a multihitting spell. + * @param entity The caster of the spell. + * @param target The victim. + * @param max The max amount of victims. + * @return The list of targets. + */ + public List getMultihitTargets(Entity entity, Entity target, int max) { + List list = new ArrayList<>(20); + list.add(target); + boolean npc = target instanceof NPC; + for (Entity e : npc ? RegionManager.getSurroundingNPCs(target) : RegionManager.getSurroundingPlayers(target)) { + if (e != target && e != entity && CombatStyle.MAGIC.getSwingHandler().canSwing(entity, e) != InteractionType.NO_INTERACT) { + list.add(e); + } + if (--max < 1) { + break; + } + } + return list; + } + + /** + * Visualizes the impact. + * @param entity The entity. + * @param target The target. + * @param state The battle state. + */ + public void visualizeImpact(Entity entity, Entity target, BattleState state) { + if (state.getEstimatedHit() == -1) { + playGlobalAudio(target.getLocation(), Sounds.SPELLFAIL_227, 20); + target.graphics(SPLASH_GRAPHIC); + return; + } + target.graphics(endGraphic); + playGlobalAudio(target.getLocation(), impactAudio, 20); + } + + @Override + public void visualize(Entity entity, Node target) { + entity.graphics(graphic); + if (projectile != null) { + if (target instanceof Entity) { + projectile.transform(entity, (Entity) target, entity instanceof NPC, 58, 10).send(); + } else { + projectile.transform(entity, target.getLocation(), entity instanceof NPC, 58, 10).send(); + } + } + if (entity.getProperties().getAutocastSpell() == this && (entity instanceof Player || animation == null)) { + Player p = entity.asPlayer(); + if (p.getProperties().getAutocastSpell().getSpellId() == 31) { + entity.animate(new Animation(1576)); + } else { + entity.animate(AUTOCAST_ANIMATION); + } + } else { + if (entity instanceof NPC) { + NPC n = entity.asNpc(); + if (n.getProperties().getMagicAnimation() != null) { + entity.animate(n.getProperties().getMagicAnimation()); + } else { + entity.animate(animation); + } + } else { + entity.animate(animation); + } + } + playGlobalAudio(entity.getLocation(), audio.id, 20); + } + + @Override + public boolean cast(Entity entity, Node target) { + if (!meetsRequirements(entity, true, false)) { + return false; + } + if (target instanceof Entity) { + entity.face((Entity) target); + } + entity.getProperties().setSpell(this); + if (entity.getProperties().getCombatPulse().isAttacking()) { + entity.getProperties().getCombatPulse().setVictim(target); + entity.getProperties().getCombatPulse().updateStyle(); + entity.getProperties().getCombatPulse().start(); + return true; + } + entity.getProperties().getCombatPulse().attack(target); + return true; + } + + /** + * Gets the targets list. + * @param entity The entity + * @param target The target. + * @return The targets array. + */ + public BattleState[] getTargets(Entity entity, Entity target) { + return new BattleState[] { new BattleState(entity, target) }; + } + + /** + * Gets the accuracy modifier. + * @return The accuracy modifier. + */ + public double getAccuracyMod() { + return type.getAccuracyMod(); + } + + /** + * @return the type. + */ + public SpellType getType() { + return type; + } + + /** + * @return the animation. + */ + public Animation getAnimation() { + return animation; + } + + /** + * Gets the splash graphic. + * @return The splash graphic. + */ + public Graphics getSplashGraphic() { + return SPLASH_GRAPHIC; + } + +} diff --git a/Server/src/main/core/game/node/entity/combat/spell/CombinationRune.java b/Server/src/main/core/game/node/entity/combat/spell/CombinationRune.java new file mode 100644 index 0000000..08e4757 --- /dev/null +++ b/Server/src/main/core/game/node/entity/combat/spell/CombinationRune.java @@ -0,0 +1,34 @@ +package core.game.node.entity.combat.spell; + +import java.util.ArrayList; +import java.util.List; + +public enum CombinationRune { + LAVA_RUNE(4699, Runes.FIRE_RUNE,Runes.EARTH_RUNE), + STEAM_RUNE(4694,Runes.FIRE_RUNE,Runes.WATER_RUNE), + MIST_RUNE(4695,Runes.WATER_RUNE,Runes.AIR_RUNE), + DUST_RUNE(4696, Runes.AIR_RUNE,Runes.EARTH_RUNE), + SMOKE_RUNE(4697,Runes.FIRE_RUNE,Runes.AIR_RUNE), + MUD_RUNE(4698,Runes.EARTH_RUNE,Runes.WATER_RUNE), + ELEMENTAL_RUNE(12850, Runes.AIR_RUNE, Runes.WATER_RUNE, Runes.EARTH_RUNE, Runes.FIRE_RUNE), + CATALYTIC_RUNE(12851, Runes.MIND_RUNE, Runes.CHAOS_RUNE, Runes.DEATH_RUNE, Runes.BLOOD_RUNE, Runes.SOUL_RUNE, Runes.ASTRAL_RUNE); + + public Runes[] types; + public int id; + CombinationRune(int id, Runes... types){ + this.id = id; + this.types = types; + } + + public static List eligibleFor(Runes rune){ + List runes = new ArrayList<>(20); + for(CombinationRune r : CombinationRune.values()){ + for(Runes ru : r.types){ + if(ru == rune){ + runes.add(r); + } + } + } + return runes; + } +} diff --git a/Server/src/main/core/game/node/entity/combat/spell/DefaultCombatSpell.java b/Server/src/main/core/game/node/entity/combat/spell/DefaultCombatSpell.java new file mode 100644 index 0000000..3dc776b --- /dev/null +++ b/Server/src/main/core/game/node/entity/combat/spell/DefaultCombatSpell.java @@ -0,0 +1,63 @@ +package core.game.node.entity.combat.spell; + +import core.game.node.entity.skill.Skills; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.link.SpellBookManager; +import core.plugin.Plugin; + +/** + * Handles the default combat spell for NPCs. + * @author Emperor + */ +public final class DefaultCombatSpell extends CombatSpell { + + /** + * The projectile id. + */ + private final int projectileId; + + /** + * The start height of the projectile. + */ + private final int startHeight; + + /** + * Constructs a new {@code DefaultCombatSpell} {@code Object}. + * @param npc The NPC. + */ + public DefaultCombatSpell(NPC npc) { + super(SpellType.BOLT, SpellBookManager.SpellBook.MODERN, 0, 0.0, -1, -1, npc.getProperties().getMagicAnimation(), npc.getDefinition().getCombatGraphics()[0], null, npc.getDefinition().getCombatGraphics()[2]); + if (npc.getDefinition().getCombatGraphics()[1] != null) { + this.projectileId = npc.getDefinition().getCombatGraphics()[1].getId(); + this.startHeight = npc.getDefinition().getCombatGraphics()[1].getHeight(); + } else { + this.projectileId = -1; + this.startHeight = 42; + } + } + + @Override + public void visualize(Entity entity, Node target) { + if (projectileId != -1) { + super.projectile = Projectile.magic(entity, (Entity) target, projectileId, startHeight, 36, 52, 15); + } + super.visualize(entity, target); + } + + @Override + public int getMaximumImpact(Entity entity, Entity victim, BattleState state) { + int level = entity.getSkills().getLevel(Skills.MAGIC); + int bonus = entity.getProperties().getBonuses()[13]; + return (int) ((14 + level + (bonus / 8) + ((level * bonus) * 0.016865))) / 10 + 1; + } + + @Override + public Plugin newInstance(SpellType arg) throws Throwable { + return null; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/combat/spell/MagicSpell.java b/Server/src/main/core/game/node/entity/combat/spell/MagicSpell.java new file mode 100644 index 0000000..12059a7 --- /dev/null +++ b/Server/src/main/core/game/node/entity/combat/spell/MagicSpell.java @@ -0,0 +1,405 @@ +package core.game.node.entity.combat.spell; + +import core.game.component.Component; +import core.game.event.SpellCastEvent; +import core.game.node.entity.skill.Skills; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.SpellBookManager.SpellBook; +import core.game.node.entity.player.link.audio.Audio; +import core.game.node.item.Item; +import core.game.world.GameWorld; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.plugin.Plugin; +import core.tools.RandomFunction; + +import java.util.ArrayList; +import java.util.List; + +import static core.api.ContentAPIKt.playGlobalAudio; + +/** + * Represents a magic spell. + * @author Emperor + */ +public abstract class MagicSpell implements Plugin { + + /** + * The spell book. + */ + protected final SpellBook book; + + /** + * The level requirement. + */ + protected final int level; + + /** + * The animation. + */ + protected final Animation animation; + + /** + * The casting graphics. + */ + protected final Graphics graphic; + + /** + * The casting Audio. + */ + protected final Audio audio; + + /** + * The item-array containing the runes required. + */ + protected final Item[] runes; + + /** + * The spell id. + */ + protected int spellId; + + /** + * The experience gained. + */ + private final double experience; + + /** + * Constructs a new {@code MagicSpell} {@code Object}. + */ + public MagicSpell() { + this(SpellBook.MODERN, 0, 0, null, null, null, new Item[0]); + } + + /** + * Constructs a new {@code MagicSpell} {@code Object}. + * @param book The spell book this spell is from. + * @param level The level requirement. + * @param animation the cast animation. + * @param graphic The cast graphic. + * @param Audio The casting Audio. + * @param runes The runes required to cast the spell. + */ + public MagicSpell(SpellBook book, int level, final double experience, Animation animation, Graphics graphic, Audio Audio, Item[] runes) { + this.book = book; + this.level = level; + this.experience = experience; + this.animation = animation; + this.graphic = graphic; + this.audio = Audio; + this.runes = runes; + } + + /** + * Casts a spell. + * @param p The player casting the spell. + * @param target The target. + */ + public static boolean castSpell(final Player p, SpellBook book, int spellId, Node target) { + if (p.getAttribute("magic-delay", 0) > GameWorld.getTicks()) { + return false; + } + MagicSpell spell = book.getSpell(spellId); + if (spell == null) { + return false; + } + if (spell.book != book || p.getSpellBookManager().getSpellBook() != book.getInterfaceId()) { + return false; + } + if (target.getLocation() != null && target != p) { + if (!target.getLocation().withinDistance(p.getLocation(), 15)) { + return false; + } + p.faceLocation(target.getLocation()); + } + boolean combatSpell = spell instanceof CombatSpell; + if (!combatSpell && target instanceof Entity) { + p.faceTemporary((Entity) target, 1); + } + if (spell.cast(p, target)) { + if (book != SpellBook.LUNAR && p.getAttribute("spell:swap", 0) != 0) { + p.removeAttribute("spell:swap"); + p.getSpellBookManager().setSpellBook(SpellBook.LUNAR); + p.getInterfaceManager().openTab(new Component(SpellBook.LUNAR.getInterfaceId())); + } + if (!combatSpell) { + p.getSkills().addExperience(Skills.MAGIC, spell.getExperience(p), true); + } + if (p.getAttribute("magic-delay", 0) <= GameWorld.getTicks()) { + p.setAttribute("magic-delay", GameWorld.getTicks() + spell.getDelay()); + } + p.dispatch(new SpellCastEvent(book, spellId, target)); + return true; + } + return false; + } + + /** + * Gets the delay. + * @return the delay. + */ + public int getDelay() { + return 3; + } + + /** + * Starts the effect of this spell (if any). + * @param entity The entity. + */ + public abstract boolean cast(Entity entity, Node target); + + /** + * Visualizes the spell. + * @param entity The entity. + * @param target The target. + */ + public void visualize(Entity entity, Node target) { + entity.graphics(graphic); + entity.animate(animation); + playGlobalAudio(entity.getLocation(), audio.id, 20); + } + + /** + * Checks if the player is holding the staff that will be used instead of + * the rune. + * @param p The player. + * @param rune The rune item id. + * @return {@code True} if the player is wearing the correct staff for the + * rune. + */ + public boolean usingStaff(Player p, int rune) { + Item weapon = p.getEquipment().get(3); + if (weapon == null) { + return false; + } + MagicStaff staff = MagicStaff.forId(rune); + if (staff == null) { + return false; + } + int[] staves = staff.getStaves(); + for (int id : staves) { + if (weapon.getId() == id) { + return true; + } + } + return false; + } + + /** + * Checks if the casting entity meets the requirements to cast this spell. + * @param caster The caster. + * @param message If a message should be send to the caster if it doesn't + * meet the requirements. + * @param remove If we should remove the runes from the player's inventory. + * @return {@code True} if so. + */ + public boolean meetsRequirements(Entity caster, boolean message, boolean remove) { + if (!checkLevelRequirement(caster, message)) { + return false; + } + if (caster instanceof Player) { + CombatSpell spell = ((Player) caster).getProperties().getAutocastSpell(); + if (spell != null) { + boolean slayer = ((Player) caster).getEquipment().get(3).getName().contains("layer's staff"); + boolean voidKnight = ((Player) caster).getEquipment().get(3).getName().contains("knight mace"); + if ((spell.getSpellId() == 31 && !slayer) || (spell.getSpellId() == 42 && !voidKnight)) { + ((Player) caster).getPacketDispatch().sendMessage("You need the proper staff to autocast this spell."); + return false; + } + } + } + if((spellId == 12 || spellId == 30 || spellId == 56) && caster instanceof Player){ + if (caster.getAttribute("entangleDelay", 0) > GameWorld.getTicks()) { + caster.asPlayer().sendMessage("You have recently cast a binding spell."); + return false; + } + } + if (caster instanceof Player) { + Player p = (Player) caster; + if(p.getEquipment().get(3) != null && p.getEquipment().get(3).getId() == 14726){ + if(RandomFunction.getRandom(100) < 13){ + p.sendMessage("Your staff negates the rune requirement of the spell."); + return true; + } + } + if (runes == null) { + return true; + } + List toRemove = new ArrayList<>(20); + for (Item item : runes) { + if (!hasRune(p, item, toRemove, message)) { + return false; + } + } + if (remove) { + toRemove.forEach(i -> { + p.getInventory().remove(i); + }); + } + return true; + } + return true; + } + + /** + * Checks the level requirement. + * @param caster The caster. + * @param message If we display the message. + * @return {@code True} if passed. + */ + public boolean checkLevelRequirement(Entity caster, boolean message) { + if (caster instanceof Player && caster.getSkills().getLevel(Skills.MAGIC, this instanceof CombatSpell ? true : false) < levelRequirement()) { + if (message && caster instanceof Player) { + ((Player) caster).getPacketDispatch().sendMessage("You need a Magic level of " + levelRequirement() + " to cast this spell."); + } + return false; + } + return true; + } + + /** + * Checks if the player has a rune to remove. + * @param p the player. + * @param item the item. + * @param toRemove the list of items to remove. + * @param message the message. + * @return {@code True} if so. + */ + public boolean hasRune(Player p, Item item, List toRemove, boolean message) { + if (!usingStaff(p, item.getId())) { + boolean hasBaseRune = p.getInventory().contains(item.getId(),item.getAmount()); + if(!hasBaseRune){ + int baseAmt = p.getInventory().getAmount(item.getId()); + if(baseAmt > 0){ + toRemove.add(new Item(item.getId(),p.getInventory().getAmount(item.getId()))); + } + int amtRemaining = item.getAmount() - baseAmt; + List possibleComboRunes = CombinationRune.eligibleFor(Runes.forId(item.getId())); + for(CombinationRune r : possibleComboRunes){ + if(p.getInventory().containsItem(new Item(r.id)) && amtRemaining > 0){ + int amt = p.getInventory().getAmount(r.id); + if(amtRemaining < amt){ + toRemove.add(new Item(r.id,amtRemaining)); + amtRemaining = 0; + continue; + } + amtRemaining -= p.getInventory().getAmount(r.id); + toRemove.add(new Item(r.id,p.getInventory().getAmount(r.id))); + } + } + if(amtRemaining <= 0){ + return true; + } else { + p.getPacketDispatch().sendMessage("You don't have enough " + item.getName() + "s to cast this spell."); + return false; + } + } + toRemove.add(item); + return true; + } + return true; + } + + /** + * Adds the experience for casting this spell. + * @param entity The entity to reward with experience. + * @param hit The hit. + */ + public void addExperience(Entity entity, int hit) { + entity.getSkills().addExperience(Skills.MAGIC, experience, true); + if (!(entity instanceof Player) || hit < 1) { + return; + } + entity.getSkills().addExperience(Skills.HITPOINTS, hit * 1.33, true); + if (entity.getProperties().getAttackStyle().getStyle() == WeaponInterface.STYLE_DEFENSIVE_CAST) { + double baseXpReward = (CombatSwingHandler.EXPERIENCE_MOD * hit) / 2.0; + entity.getSkills().addExperience(Skills.DEFENCE, baseXpReward, true); + entity.getSkills().addExperience(Skills.MAGIC, baseXpReward, true); + return; + } + entity.getSkills().addExperience(Skills.MAGIC, hit * (CombatSwingHandler.EXPERIENCE_MOD), true); + } + + /** + * Gets the level requirement to cast this spell. + * @return The level requirement. + */ + public int levelRequirement() { + return level; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + /** + * Gets the audio. + * @return the audio. + */ + public Audio getAudio() { + return audio; + } + + /** + * Gets the spell book for this spell. + * @return The spell book. + */ + public SpellBook getBook() { + return book; + } + + /** + * Gets the item array of runes required to cast this spell. + * @return The item array of runes, or {@code null} if the spell doesn't need + * any runes. + */ + public Item[] getCastRunes() { + return runes; + } + + /** + * Gets the spellId. + * @return The spellId. + */ + public int getSpellId() { + return spellId; + } + + /** + * Sets the spellId. + * @param spellId The spellId to set. + */ + public void setSpellId(int spellId) { + this.spellId = spellId; + } + + /** + * Gets the experience. + * @return The experience. + */ + public double getExperience() { + return experience; + } + + /** + * Gets the experience. + * @param player the player. + * @return the experience. + */ + public double getExperience(Player player) { + return experience; + } + + /** + * Gets the level requirement. + * @return The level requirement. + */ + public int getLevel() { + return level; + } +} diff --git a/Server/src/main/core/game/node/entity/combat/spell/MagicStaff.java b/Server/src/main/core/game/node/entity/combat/spell/MagicStaff.java new file mode 100644 index 0000000..6664e72 --- /dev/null +++ b/Server/src/main/core/game/node/entity/combat/spell/MagicStaff.java @@ -0,0 +1,88 @@ +package core.game.node.entity.combat.spell; + +import java.util.HashMap; +import java.util.Map; + +/** + * Represents a magic staff. + * @author Emperor + */ +public enum MagicStaff { + + /** + * Represents the fire rune staves. + */ + FIRE_RUNE(554, 1387, 1393, 1401, 3053, 3054, 3055, 3056, 11736, 11738), + + /** + * Represents the water rune staves. + */ + WATER_RUNE(555, 1383, 1395, 1403, 6563, 11736, 11738, 6562), + + /** + * Represents the air rune staves. + */ + AIR_RUNE(556, 1381, 1397, 1405, 21777), + + /** + * Represents the earth rune staves. + */ + EARTH_RUNE(557, 3053, 3054, 3055, 3056, 1385, 1399, 1407, 557, 6563, 6562); + + /** + * The magic staves mapping. + */ + private static final Map MAGIC_STAVES = new HashMap(); + + /** + * Populate the mapping. + */ + static { + for (MagicStaff m : MagicStaff.values()) { + MAGIC_STAVES.put(m.getRuneId(), m); + } + } + + /** + * Gets a magic staff from the mapping. + * @param runeId The rune id. + * @return The magic staff instance. + */ + public static MagicStaff forId(int runeId) { + return MAGIC_STAVES.get(runeId); + } + + /** + * The rune id. + */ + private final int runeId; + + /** + * The staves. + */ + private final int[] staves; + + /** + * Constructs a new {@code MagicStaff} {@code Object}. + * @param runeId The rune id. + * @param staves The possible staff item ids. + */ + private MagicStaff(int runeId, int... staves) { + this.runeId = runeId; + this.staves = staves; + } + + /** + * @return the runeId + */ + public int getRuneId() { + return runeId; + } + + /** + * @return the staves + */ + public int[] getStaves() { + return staves; + } +} diff --git a/Server/src/main/core/game/node/entity/combat/spell/Runes.java b/Server/src/main/core/game/node/entity/combat/spell/Runes.java new file mode 100644 index 0000000..dacb28c --- /dev/null +++ b/Server/src/main/core/game/node/entity/combat/spell/Runes.java @@ -0,0 +1,113 @@ +package core.game.node.entity.combat.spell; + +import core.game.node.item.Item; +import org.rs09.consts.Items; + +/** + * Represents the Constants of runes. + * @author 'Vexia + */ +public enum Runes { + AIR_RUNE(556), WATER_RUNE(555), EARTH_RUNE(557), FIRE_RUNE(554), MIND_RUNE(558), NATURE_RUNE(561), CHAOS_RUNE(562), DEATH_RUNE(560), COSMIC_RUNE(564), BLOOD_RUNE(565), SOUL_RUNE(566), ASTRAL_RUNE(9075), LAW_RUNE(563), BODY_RUNE(559), SARADOMIN_STAFF(2415), GUTHIX_STAFF(2416), ZAMORAK_STAFF(2417), ZURIELS_STAFF(13867); + + /** + * Constructs a new {@code Runes} {@code Object}. + * @param id the id. + */ + Runes(int id) { + this.id = id; + } + + /** + * The id of the rune. + */ + private int id; + + /** + * Gets the id of the rune. + * @return the id. + */ + public int getId() { + return id; + } + + /** + * Gets the rune by the id. + * @param id the id. + * @return the id. + */ + public static Runes forId(int id) { + for (Runes rune : Runes.values()) { + if (rune.getId() == id) { + return rune; + } + } + return null; + } + + /** + * Checks if the player has an infinite amt of runes. + * @param rune the rune. + * @param weapon the weapon. + * @return {@code true} if so. + */ + public static final boolean isInfinite(Runes rune, Item weapon, SpellType... type) { + if (weapon == null || rune == null) { + return false; + } + if (type != null) { + if (weapon.getId() == 2415 && rune == Runes.SARADOMIN_STAFF && type.length == 1) { + if (type[0] == SpellType.GOD_STRIKE) { + return true; + } + } + if (weapon.getId() == 2416 && rune == Runes.GUTHIX_STAFF && type.length == 1) { + if (type[0] == SpellType.GOD_STRIKE) { + return true; + } + } + if (weapon.getId() == 13867 && rune == Runes.ZURIELS_STAFF && type.length == 1) { + if (type[0] == SpellType.BARRAGE || type[0] == SpellType.BLITZ + || type[0] == SpellType.RUSH || type[0] == SpellType.BURST) { + return true; + } + } + if (weapon.getId() == 2417 && rune == Runes.ZAMORAK_STAFF && type.length == 1) { + if (type[0] == SpellType.GOD_STRIKE) { + return true; + } + } + } + if (rune == Runes.AIR_RUNE) { + if (weapon.getId() == Items.STAFF_OF_AIR_1381 || weapon.getId() == Items.AIR_BATTLESTAFF_1397) // air staff + return true; + } else if (rune == Runes.WATER_RUNE) { + if (weapon.getId() == Items.STAFF_OF_WATER_1383 || weapon.getId() == Items.WATER_BATTLESTAFF_1395) // water staff + return true; + } else if (rune == Runes.EARTH_RUNE) { + if (weapon.getId() == Items.STAFF_OF_EARTH_1385 || weapon.getId() == Items.EARTH_BATTLESTAFF_1399) // earth staff + return true; + } else if (rune == Runes.FIRE_RUNE) { + if (weapon.getId() == Items.STAFF_OF_FIRE_1387 || weapon.getId() == Items.FIRE_BATTLESTAFF_1393) // fire staff + return true; + } + return false; + } + + /** + * Method used to transform this item. + * @return the item. + */ + public Item transform() { + return new Item(id); + } + + /** + * Gets the item of this rune. + * @param amount The amount. + * @return The item instance. + */ + public Item getItem(int amount) { + return new Item(id, amount); + } +} diff --git a/Server/src/main/core/game/node/entity/combat/spell/SpellBlocks.java b/Server/src/main/core/game/node/entity/combat/spell/SpellBlocks.java new file mode 100644 index 0000000..e6fc5a7 --- /dev/null +++ b/Server/src/main/core/game/node/entity/combat/spell/SpellBlocks.java @@ -0,0 +1,35 @@ +package core.game.node.entity.combat.spell; + +import core.game.node.Node; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + +public class SpellBlocks { + private static HashMap> blocks = new HashMap<>(); + + public static void register(int spellId, Node toBlock){ + if(blocks.get(spellId) != null){ + blocks.get(spellId).add(toBlock); + } else { + List blockslist = new ArrayList<>(20); + blockslist.add(toBlock); + blocks.put(spellId,blockslist); + } + } + + public static boolean isBlocked(int spellId,Node node){ + AtomicBoolean blocked = new AtomicBoolean(false); + if(blocks.get(spellId) == null){ + return false; + } + blocks.get(spellId).forEach(n -> { + if(node.getName().equals(n.getName())){ + blocked.set(true); + } + }); + return blocked.get(); + } +} diff --git a/Server/src/main/core/game/node/entity/combat/spell/SpellType.java b/Server/src/main/core/game/node/entity/combat/spell/SpellType.java new file mode 100644 index 0000000..828a888 --- /dev/null +++ b/Server/src/main/core/game/node/entity/combat/spell/SpellType.java @@ -0,0 +1,256 @@ +package core.game.node.entity.combat.spell; + +import core.game.container.impl.EquipmentContainer; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.Entity; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; + +import static core.api.ContentAPIKt.*; + +/** + * Represents the spell types. + * @author Emperor + */ +public enum SpellType { + + /** + * The strike spell type. + */ + STRIKE(1.0) { + @Override + public int getImpactAmount(Entity e, Entity victim, int base) { + if (victim instanceof NPC && ((NPC) victim).getId() == 205) { + return 8 + base; + } + return 2 * base; + } + }, + + /** + * The bolt spell type. + */ + BOLT(1.1) { + @Override + public int getImpactAmount(Entity e, Entity victim, int base) { + if (e instanceof Player && ((Player) e).getEquipment().getNew(EquipmentContainer.SLOT_HANDS).getId() == 777) { + return 11 + base; + } + return 8 + base; + } + }, + + /** + * Crumble undead. + */ + CRUMBLE_UNDEAD(1.2) { + @Override + public int getImpactAmount(Entity e, Entity victim, int base) { + return 15; // Hits as high as Earth blast + } + }, + + /** + * The blast spell type. + */ + BLAST(1.2) { + @Override + public int getImpactAmount(Entity e, Entity victim, int base) { + return 12 + base; + } + }, + + /** + * The wave spell type. + */ + WAVE(1.3) { + @Override + public int getImpactAmount(Entity e, Entity victim, int base) { + return 16 + base; + } + }, + + /** + * The rush spell type. + */ + RUSH(1.1) { + @Override + public int getImpactAmount(Entity e, Entity victim, int base) { + return 14 + base; + } + }, + + /** + * The burst spell type. + */ + BURST(1.2) { + @Override + public int getImpactAmount(Entity e, Entity victim, int base) { + + return 18 + base; + } + }, + + /** + * The blitz spell type. + */ + BLITZ(1.3) { + @Override + public int getImpactAmount(Entity e, Entity victim, int base) { + return 22 + base; + } + }, + + /** + * The barrage spell type. + */ + BARRAGE(1.4) { + @Override + public int getImpactAmount(Entity e, Entity victim, int base) { + + + + + return 26 + base; + } + }, + + /** + * The confuse spell type. + */ + CONFUSE(1.15), + + /** + * The weaken spell type. + */ + WEAKEN(1.15), + + /** + * The curse spell type. + */ + CURSE(1.15), + + /** + * The vulnerability spell type. + */ + VULNERABILITY(1.25), + + /** + * The enfeeble spell type. + */ + ENFEEBLE(1.25), + + /** + * The stun spell type. + */ + STUN(1.25), + + /** + * The god strike spell type. + */ + GOD_STRIKE(1.2) { + @Override + public int getImpactAmount(Entity e, Entity victim, int base) { + if(!(e instanceof Player)) return 20; + if (hasTimerActive(e, "magic:spellcharge")) { + Item cape = ((Player) e).getEquipment().getNew(EquipmentContainer.SLOT_CAPE); + if (cape.getId() == 2412 || cape.getId() == 2413 || cape.getId() == 2414) { + return 30; + } + } + return 20; + } + }, + + /** + * The bind spell type. + */ + BIND(1.1), + + /** + * The snare spell type. + */ + SNARE(1.2), + + /** + * The entangle spell type. + */ + ENTANGLE(1.3), + + /** + * The magic dart spell type. + */ + MAGIC_DART(1.15) { + @Override + public int getImpactAmount(Entity e, Entity victim, int base) { + return 10 + (e.getSkills().getLevel(Skills.MAGIC) / 10); + } + }, + + /** + * The iban blast spell type. + */ + IBANS_BLAST(1.4) { + @Override + public int getImpactAmount(Entity e, Entity victim, int base) { + return 25; + } + }, + + /** + * The trident of seas built in spell. + */ + TRIDENT_OF_SEAS(1.4) { + @Override + public int getImpactAmount(Entity e, Entity victim, int base) { + Player player = e.asPlayer(); + int level = player.getSkills().getLevel(Skills.MAGIC); + int offset = (level - 75) / 3; + return offset + base; + } + }, + + /** + * The teleporation block spell type. + */ + TELEBLOCK(1.3), + + /** + * The null spell type. + */ + NULL(0.0); + + /** + * The accuracy modifier. + */ + private final double accuracyMod; + + /** + * Constructs a new {@code SpellType} {@Code Object}. + * @param accuracyMod The accuracy modifier. + */ + private SpellType(double accuracyMod) { + this.accuracyMod = accuracyMod; + } + + /** + * Gets the base damage for this spell. + * @param e The entity casting this spell. + * @param victim The entity being hit. + * @param base The base damage for the spell element. + * @return The base damage for this spell. + */ + public int getImpactAmount(Entity e, Entity victim, int base) { + return 2; + } + + /** + * Gets the accuracy modifier. + * @return The accuracy modifier. + */ + public double getAccuracyMod() { + return accuracyMod; + } + +} diff --git a/Server/src/main/core/game/node/entity/impl/Animator.java b/Server/src/main/core/game/node/entity/impl/Animator.java new file mode 100644 index 0000000..3afafb4 --- /dev/null +++ b/Server/src/main/core/game/node/entity/impl/Animator.java @@ -0,0 +1,212 @@ +package core.game.node.entity.impl; + +import core.game.interaction.Clocks; +import core.game.node.entity.Entity; +import core.game.node.entity.npc.NPC; +import core.game.world.GameWorld; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.game.world.update.flag.EntityFlag; + +/** + * Handles the animating of an Entity. + * @author Emperor + */ +public final class Animator { + + /** + * The reset animation. + */ + public static final Animation RESET_A = new Animation(-1); + + /** + * The reset graphics. + */ + public static final Graphics RESET_G = new Graphics(-1); + + /** + * The entity. + */ + private Entity entity; + + /** + * The current animation. + */ + private Animation animation; + + /** + * The current graphics. + */ + private Graphics graphics; + + /** + * Current priority. + */ + private Priority priority = Priority.LOW; + + /** + * The current animation delay. + */ + private int ticks; + + /** + * Constructs a new {@code Animator} {@Code Object}. + * @param entity The entity. + */ + public Animator(Entity entity) { + this.entity = entity; + } + + /** + * Represents the priorities. + * @author Emperor + */ + public static enum Priority { + + /** + * Lowest priority. + */ + LOW, + + /** + * Medium priority (override low priority) + */ + MID, + + /** + * High priority (override all) + */ + HIGH, + + /** + * Extra priority only to be used when really needed. (overrides death + * animation etc). + */ + VERY_HIGH; + } + + /** + * Starts an animation. + * @param animation The animation. + * @return {@code True} if successful. + */ + public boolean animate(Animation animation) { + return animate(animation, null); + } + + /** + * Starts a graphic. + * @param graphic The graphic. + * @return {@code True} if successful. + */ + public boolean graphics(Graphics graphic) { + return animate(null, graphic); + } + + /** + * Starts an animation (and if animation is null or has successfully started + * > start graphic) + * @param animation The animation. + * @param graphic The graphic. + * @return {@code True} if successfully started. + */ + public boolean animate(Animation animation, Graphics graphic) { + if (animation != null) { + if (ticks > GameWorld.getTicks() && priority.ordinal() > animation.getPriority().ordinal()) { + return false; + } + if (animation.getId() == 0) { + animation.setId(-1); + } + this.animation = animation; + if (animation.getId() != -1) { + ticks = GameWorld.getTicks() + animation.getDuration(); + } else { + ticks = 0; + } + entity.clocks[Clocks.getANIMATION_END()] = ticks; + entity.getUpdateMasks().register(EntityFlag.Animate, animation); + priority = animation.getPriority(); + } + if (graphic != null) { + this.graphics = graphic; + entity.getUpdateMasks().register(EntityFlag.SpotAnim, graphic); + } + return true; + } + + public void stop(){ + animate(RESET_A); + } + + /** + * Forces an animation. + * @param animation The animation to display. + */ + public void forceAnimation(Animation animation) { + ticks = -1; + animate(animation); + priority = Priority.HIGH; + } + + /** + * Method used to reset the animator. + */ + public void reset() { + animate(RESET_A); + entity.clocks[Clocks.getANIMATION_END()] = 0; + ticks = 0; + } + + /** + * Checks if the entity is animating. + * @return {@code True} if so. + */ + public boolean isAnimating() { + return animation != null && animation.getId() != -1 && ticks > GameWorld.getTicks(); + } + + /** + * @return the animation. + */ + public Animation getAnimation() { + return animation; + } + + /** + * @param animation the animation to set. + */ + public void setAnimation(Animation animation) { + this.animation = animation; + } + + /** + * @return the graphics. + */ + public Graphics getGraphics() { + return graphics; + } + + /** + * @param graphics the graphics to set. + */ + public void setGraphics(Graphics graphics) { + this.graphics = graphics; + } + + /** + * Gets the priority. + * @return The priority. + */ + public Priority getPriority() { + return priority; + } + + /** + * Sets the priority. + * @param priority The priority to set. + */ + public void setPriority(Priority priority) { + this.priority = priority; + } +} diff --git a/Server/src/main/core/game/node/entity/impl/ForceMovement.java b/Server/src/main/core/game/node/entity/impl/ForceMovement.java new file mode 100644 index 0000000..8cfc7ef --- /dev/null +++ b/Server/src/main/core/game/node/entity/impl/ForceMovement.java @@ -0,0 +1,532 @@ +package core.game.node.entity.impl; + +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.update.flag.context.*; +import core.game.world.update.flag.*; + +/** + * The force movement handler. + * @author Emperor + */ +public class ForceMovement extends Pulse { + + /** + * The walking speed. + */ + public static final int WALKING_SPEED = 10; + + /** + * The running speed. + */ + public static final int RUNNING_SPEED = 20; + + /** + * The walking animation. + */ + public static final Animation WALK_ANIMATION = Animation.create(819); + + /** + * The entity. + */ + protected Entity entity; + + /** + * The location to start the force movement from. + */ + private Location start; + + /** + * The destination. + */ + private Location destination; + + /** + * The animation. + */ + private Animation startAnim; + + /** + * The animation. + */ + protected Animation animation; + + /** + * The ending animation. + */ + private Animation endAnimation = null; + + /** + * The direction. + */ + protected Direction direction; + + /** + * The commencing speed. + */ + private int commenceSpeed; + + /** + * The path speed. + */ + private int pathSpeed; + + /** + * Whether to unlock the entity after the ForceMovement completes + */ + private boolean unlockAfter; + + /** + * Constructs a new {@code ForceMovement} {@code Object}. + * @param e The entity. + * @param start The start location. + * @param destination The destination. + * @param startAnim The start animation. + * @param animation The animation + * @param direction The direction. + * @param commenceSpeed The commencing speed. + * @param pathSpeed The path speed. + * @param unlockAfter Whether to unlock the entity after the ForceMovement completes + * @deprecated this is no longer the preferred way to use force movement. Use the ContentAPI forceMove method instead, please. + */ + @Deprecated + public ForceMovement(Entity e, Location start, Location destination, Animation startAnim, Animation animation, Direction direction, int commenceSpeed, int pathSpeed, boolean unlockAfter) { + super(1, e); + this.entity = e; + this.start = start; + this.destination = destination; + this.startAnim = startAnim; + this.animation = animation; + this.direction = direction; + this.commenceSpeed = commenceSpeed; + this.pathSpeed = pathSpeed; + this.unlockAfter = unlockAfter; + } + + /** + * Constructs a new {@code ForceMovement} {@code Object}. + * @param e the entity. + * @param start the start location. + * @param end the destination. + * @param animation the animation. + * @param speed The path speed. + * @deprecated this is no longer the preferred way to use force movement. Use the ContentAPI forceMove method instead, please. + */ + @Deprecated + public ForceMovement(Entity e, Location start, Location end, Animation animation, int speed) { + this(e, start, end, WALK_ANIMATION, animation, direction(start, end), WALKING_SPEED, speed, true); + } + + /** + * @deprecated this is no longer the preferred way to use force movement. Use the ContentAPI forceMove method instead, please. + */ + @Deprecated + public ForceMovement(Entity e, Location destination, int startSpeed, int animSpeed){ + this(e,e.getLocation(),destination,WALK_ANIMATION,WALK_ANIMATION,direction(e.getLocation(),destination),startSpeed,animSpeed, true); + } + + /** + * Constructs a new {@code ForceMovement} {@code Object}. + * @param e the entity. + * @param start the start location. + * @param destination the destination. + * @param animation the animation. + * @deprecated this is no longer the preferred way to use force movement. Use the ContentAPI forceMove method instead, please. + */ + @Deprecated + public ForceMovement(Entity e, Location start, Location destination, Animation animation) { + this(e, start, destination, WALK_ANIMATION, animation, direction(start, destination), WALKING_SPEED, WALKING_SPEED, true); + } + + /** + * Constructs a new {@code ForceMovement} {@code Object}. + * @param start the start loc. + * @param destination the destination. + * @param animation the animation. + * @deprecated this is no longer the preferred way to use force movement. Use the ContentAPI forceMove method instead, please. + */ + @Deprecated + public ForceMovement(Location start, Location destination, Animation animation) { + this(null, start, destination, WALK_ANIMATION, animation, direction(start, destination), WALKING_SPEED, WALKING_SPEED, true); + } + + /** + * Creates and runs a new force movement pulse. + * @param e The entity. + * @param destination The destination location. + * @return The created ForceMovement object. + * @deprecated this is no longer the preferred way to use force movement. Use the ContentAPI forceMove method instead, please. + */ + @Deprecated + public static ForceMovement run(Entity e, Location destination) { + return run(e, e.getLocation(), destination, WALK_ANIMATION, WALK_ANIMATION, direction(e.getLocation(), destination), WALKING_SPEED, WALKING_SPEED, true); + } + + /** + * Creates and runs a new force movement pulse. + * @param e The entity. + * @param start The start location. + * @param destination The destination location. + * @return The created ForceMovement object. + * @deprecated this is no longer the preferred way to use force movement. Use the ContentAPI forceMove method instead, please. + */ + @Deprecated + public static ForceMovement run(Entity e, Location start, Location destination) { + return run(e, start, destination, WALK_ANIMATION, WALK_ANIMATION, direction(e.getLocation(), destination), WALKING_SPEED, WALKING_SPEED, true); + } + + /** + * Creates and runs a new force movement pulse. + * @param e The entity. + * @param start The start location. + * @param destination The destination location. + * @param animation The animation. + * @return The created ForceMovement object. + * @deprecated this is no longer the preferred way to use force movement. Use the ContentAPI forceMove method instead, please. + */ + @Deprecated + public static ForceMovement run(Entity e, Location start, Location destination, Animation animation) { + return run(e, start, destination, WALK_ANIMATION, animation, direction(start, destination), WALKING_SPEED, WALKING_SPEED, true); + } + + /** + * Creates and runs a new force movement pulse. + * @param e The entity. + * @param start The start location. + * @param destination The destination location. + * @param animation The animation. + * @param speed The path speed. + * @return The created ForceMovement object. + * @deprecated this is no longer the preferred way to use force movement. Use the ContentAPI forceMove method instead, please. + */ + @Deprecated + public static ForceMovement run(Entity e, Location start, Location destination, Animation animation, int speed) { + return run(e, start, destination, WALK_ANIMATION, animation, direction(start, destination), WALKING_SPEED, speed, true); + } + + /** + * Creates and runs a new force movement pulse. + * @param e The entity. + * @param start The start location. + * @param destination The destination location. + * @param animation The animation. + * @return The created ForceMovement object. + * @deprecated this is no longer the preferred way to use force movement. Use the ContentAPI forceMove method instead, please. + */ + @Deprecated + public static ForceMovement run(Entity e, Location start, Location destination, Animation startAnim, Animation animation) { + return run(e, start, destination, startAnim, animation, direction(start, destination), WALKING_SPEED, WALKING_SPEED, true); + } + + /** + * Creates and runs a new force movement pulse. + * @param e The entity. + * @param start The start location. + * @param destination The destination location. + * @param animation The animation. + * @param direction The direction. + * @return The created ForceMovement object. + * @deprecated this is no longer the preferred way to use force movement. Use the ContentAPI forceMove method instead, please. + */ + @Deprecated + public static ForceMovement run(Entity e, Location start, Location destination, Animation startAnim, Animation animation, Direction direction) { + return run(e, start, destination, startAnim, animation, direction, WALKING_SPEED, WALKING_SPEED, true); + } + + /** + * Creates and runs a new force movement pulse. + * @param e The entity. + * @param start The start location. + * @param destination The destination location. + * @param animation The animation. + * @param direction The direction. + * @param pathSpeed The speed (in ticks). + * @return The created ForceMovement object. + * @deprecated this is no longer the preferred way to use force movement. Use the ContentAPI forceMove method instead, please. + */ + @Deprecated + public static ForceMovement run(Entity e, Location start, Location destination, Animation startAnim, Animation animation, Direction direction, int pathSpeed) { + return run(e, start, destination, startAnim, animation, direction, WALKING_SPEED, pathSpeed, true); + } + + /** + * @deprecated this is no longer the preferred way to use force movement. Use the ContentAPI forceMove method instead, please. + */ + @Deprecated + public static ForceMovement run(Entity e, Location start, Location destination, Animation startAnim, Animation animation, Direction direction, int commenceSpeed, int pathSpeed) { + return run(e, start, destination, startAnim, animation, direction, commenceSpeed, pathSpeed, true); + } + + /** + * Creates and runs a new force movement pulse. + * @param e The entity. + * @param start The start location. + * @param destination The destination location. + * @param animation The animation. + * @param direction The direction. + * @return The created ForceMovement object. + * @deprecated this is no longer the preferred way to use force movement. Use the ContentAPI forceMove method instead, please. + */ + @Deprecated + public static ForceMovement run(Entity e, Location start, Location destination, Animation startAnim, Animation animation, Direction direction, int commenceSpeed, int pathSpeed, boolean unlockAfter) { + if (startAnim != null) { + startAnim.setPriority(Animator.Priority.VERY_HIGH); + } + if (animation != null) { + animation.setPriority(Animator.Priority.VERY_HIGH); + } + ForceMovement fm = new ForceMovement(e, start, destination, startAnim, animation, direction, commenceSpeed, pathSpeed, unlockAfter); + fm.start(); + e.lock(); + GameWorld.getPulser().submit(fm); + return fm; + } + /* + * @deprecated this is no longer the preferred way to use force movement. Use the ContentAPI forceMove method instead, please. + */ + @Deprecated + public static ForceMovement run(Entity e, Location destination, int commenceSpeed, int pathSpeed){ + return run(e,e.getLocation(),destination,WALK_ANIMATION,WALK_ANIMATION,direction(e.getLocation(),destination),commenceSpeed,pathSpeed, true); + } + + /** + * Method used to run the force movement. + * @param e the entity. + * @deprecated this is no longer the preferred way to use force movement. Use the ContentAPI forceMove method instead, please. + */ + @Deprecated + public void run(final Entity e, final int speed) { + this.entity = e; + int commence = (int) start.getDistance(e.getLocation()); + if (commence != 0 && commenceSpeed != 0) { + commence = (int) (1 + (commence / (commenceSpeed * 0.1))); + } + int path = 1 + (int) Math.ceil(start.getDistance(destination) / (pathSpeed * 0.1)); + this.pathSpeed = pathSpeed == 0 ? path : speed; + this.commenceSpeed = commence; + start(); + e.lock(); + GameWorld.getPulser().submit(this); + } + + /** + * Method used to run the movement. + * @param e the entity. + */ + public void run(final Entity e) { + run(e, 0); + } + + /** + * Method used to run the movement. + */ + public void run() { + run(entity); + } + + /** + * Gets the direction value. + * @param s The start location. + * @param d The destination. + * @return The direction object. + */ + public static Direction direction(Location s, Location d) { + Location delta = Location.getDelta(s, d); + int x = Math.abs(delta.getX()); + int y = Math.abs(delta.getY()); + if (x > y) { + return Direction.getDirection(delta.getX(), 0); + } + return Direction.getDirection(0, delta.getY()); + } + + @Override + public void start() { + commenceSpeed = (int) Math.ceil(start.getDistance(entity.getLocation()) / (commenceSpeed * 0.1)); + pathSpeed = (int) Math.ceil(start.getDistance(destination) / (pathSpeed * 0.1)); + if (commenceSpeed != 0) { + entity.animate(startAnim); + super.setDelay(commenceSpeed); + } else { + entity.animate(animation); + super.setDelay(pathSpeed); + } + int ticks = 1 + commenceSpeed + pathSpeed; + entity.getImpactHandler().setDisabledTicks(ticks); + entity.getUpdateMasks().register(EntityFlag.ForceMove, new ForceMoveCtx(start, destination, commenceSpeed * 30, pathSpeed * 30, direction)); + if(entity instanceof Player) { + entity.getWalkingQueue().updateRegion(destination, false); + } + super.start(); + } + + @Override + public boolean pulse() { + if (commenceSpeed != 0) { + entity.animate(animation); + setDelay(pathSpeed); + commenceSpeed = 0; + entity.getProperties().setTeleportLocation(start); + return false; + } + return true; + } + + @Override + public void stop() { + super.stop(); + entity.getProperties().setTeleportLocation(destination); + if (endAnimation != null) { + entity.animate(endAnimation); + } + if (unlockAfter) entity.unlock(); + } + + /** + * Gets the start. + * @return The start. + */ + public Location getStart() { + return start; + } + + /** + * Sets the start. + * @param start The start to set. + */ + public void setStart(Location start) { + this.start = start; + } + + /** + * Gets the destination. + * @return The destination. + */ + public Location getDestination() { + return destination; + } + + /** + * Sets the destination. + * @param destination The destination to set. + */ + public void setDestination(Location destination) { + this.destination = destination; + } + + /** + * Gets the direction. + * @return The direction. + */ + public Direction getDirection() { + return direction; + } + + /** + * Sets the direction. + * @param direction The direction to set. + */ + public void setDirection(Direction direction) { + this.direction = direction; + } + + /** + * Gets the commenceSpeed. + * @return The commenceSpeed. + */ + public int getCommenceSpeed() { + return commenceSpeed; + } + + /** + * Sets the commenceSpeed. + * @param commenceSpeed The commenceSpeed to set. + */ + public void setCommenceSpeed(int commenceSpeed) { + this.commenceSpeed = commenceSpeed; + } + + /** + * Sets the entity. + * @param entity the entity. + */ + public void setEntity(Entity entity) { + this.entity = entity; + } + + /** + * Gets the pathSpeed. + * @return The pathSpeed. + */ + public int getPathSpeed() { + return pathSpeed; + } + + /** + * Sets the pathSpeed. + * @param pathSpeed The pathSpeed to set. + */ + public void setPathSpeed(int pathSpeed) { + this.pathSpeed = pathSpeed; + } + + /** + * Gets the entity. + * @return The entity. + */ + public Entity getEntity() { + return entity; + } + + /** + * Gets the startAnim. + * @return The startAnim. + */ + public Animation getStartAnim() { + return startAnim; + } + + /** + * Sets the startAnim. + * @param startAnim The startAnim to set. + */ + public void setStartAnim(Animation startAnim) { + this.startAnim = startAnim; + } + + /** + * Gets the animation. + * @return The animation. + */ + public Animation getAnimation() { + return animation; + } + + /** + * Sets the animation. + * @param animation The animation to set. + */ + public void setAnimation(Animation animation) { + this.animation = animation; + } + + /** + * Gets the endAnimation. + * @return The endAnimation. + */ + public Animation getEndAnimation() { + return endAnimation; + } + + /** + * Sets the endAnimation. + * @param endAnimation The endAnimation to set. + */ + public void setEndAnimation(Animation endAnimation) { + this.endAnimation = endAnimation; + } +} diff --git a/Server/src/main/core/game/node/entity/impl/GameAttributes.java b/Server/src/main/core/game/node/entity/impl/GameAttributes.java new file mode 100644 index 0000000..4596b76 --- /dev/null +++ b/Server/src/main/core/game/node/entity/impl/GameAttributes.java @@ -0,0 +1,197 @@ +package core.game.node.entity.impl; + +import core.ServerConstants; +import org.w3c.dom.*; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Handles an entity's game attributes. + * @author Emperor + */ +public final class GameAttributes { + + /** + * The attributes mapping. + */ + private final Map attributes = new HashMap<>(); + + /** + * The list of attributes to save. + */ + private final List savedAttributes = new ArrayList<>(250); + + /** + * The list of key expirations + */ + public final HashMap keyExpirations = new HashMap<>(250); + + /** + * Constructs a new {@code GameAttributes} {@code Object}. + */ + public GameAttributes() { + /* + * Empty. + */ + } + + /** + * Writes the attribute data to the player buffer. + * @param file The player's data buffer. + */ + @Deprecated + public void dump(String file) { + + } + + /** + * Parses the saved attributes from the buffer. + * @param file The buffer. + */ + @Deprecated + public void parse(String file) { + File saveFile = new File(ServerConstants.PLAYER_ATTRIBUTE_PATH + file); + if(!saveFile.exists()){ + return; + } + try { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + Document doc = builder.parse(saveFile); + + NodeList attributesList = doc.getElementsByTagName("GameAttribute"); + for(int i = 0; i < attributesList.getLength(); i++){ + Node attrNode = attributesList.item(i); + if(attrNode.getNodeType() == Node.ELEMENT_NODE){ + Element attr = (Element) attrNode; + String key = attr.getAttribute("key"); + switch(attr.getAttribute("type")){ + case "bool": { + boolean value = Boolean.parseBoolean(attr.getAttribute("value")); + attributes.put(key, value); + if (!savedAttributes.contains(key)) { + savedAttributes.add(key); + } + break; + } + case "long": { + long value = Long.parseLong(attr.getAttribute("value")); + attributes.put(key, value); + if (!savedAttributes.contains(key)) { + savedAttributes.add(key); + } + break; + } + case "short":{ + short value = Short.parseShort(attr.getAttribute("value")); + attributes.put(key, value); + if (!savedAttributes.contains(key)) { + savedAttributes.add(key); + } + break; + } + case "int":{ + int value = Integer.parseInt(attr.getAttribute("value")); + attributes.put(key, value); + if (!savedAttributes.contains(key)) { + savedAttributes.add(key); + } + break; + } + case "byte":{ + byte value = Byte.parseByte(attr.getAttribute("value")); + attributes.put(key, value); + if (!savedAttributes.contains(key)) { + savedAttributes.add(key); + } + break; + } + case "string":{ + String value = attr.getAttribute("value"); + attributes.put(key, value); + if (!savedAttributes.contains(key)) { + savedAttributes.add(key); + } + break; + } + } + } + } + } catch (Exception e){ + e.printStackTrace(); + } + } + + /** + * Sets an attribute value. + * @param key The attribute name. + * @param value The attribute value. + */ + public void setAttribute(String key, Object value) { + if (key.startsWith("/save:")) { + key = key.substring(6); + if (!savedAttributes.contains(key)) { + savedAttributes.add(key); + } + } + attributes.put(key, value); + } + + /** + * Gets an attribute. + * @param key The attribute name. + * @return The attribute value. + */ + @SuppressWarnings("unchecked") + public T getAttribute(String key) { + key = key.replace("/save:",""); + return (T) attributes.get(key); + } + + /** + * Gets an attribute. + * @param string The attribute name. + * @param fail The value to return if the attribute is null. + * @return The attribute value, or the fail argument when null. + */ + @SuppressWarnings("unchecked") + public T getAttribute(String string, T fail) { + string = string.replace("/save:",""); + Object object = attributes.get(string); + if (object != null) { + return (T) object; + } + return fail; + } + + /** + * Removes an attribute. + * @param string The attribute name. + */ + public void removeAttribute(String string) { + savedAttributes.remove(string); + attributes.remove(string); + } + + /** + * Gets the attributes. + * @return The attributes. + */ + public Map getAttributes() { + return attributes; + } + + /** + * Gets the savedAttributes. + * @return The savedAttributes. + */ + public List getSavedAttributes() { + return savedAttributes; + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/impl/Projectile.java b/Server/src/main/core/game/node/entity/impl/Projectile.java new file mode 100644 index 0000000..bb54a25 --- /dev/null +++ b/Server/src/main/core/game/node/entity/impl/Projectile.java @@ -0,0 +1,562 @@ +package core.game.node.entity.impl; + +import core.game.node.entity.Entity; +import core.game.node.entity.npc.NPC; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.chunk.ProjectileUpdateFlag; + +/** + * Represents a projectile to send. + * @author Emperor + */ +public class Projectile { + + /** + * The source node. + */ + private Entity source; + + /** + * The source's centered location. + */ + private Location sourceLocation; + + /** + * The victim. + */ + private Entity victim; + + /** + * The projectile's gfx id. + */ + private int projectileId; + + /** + * The start height. + */ + private int startHeight; + + /** + * The ending height. + */ + private int endHeight; + + /** + * The start delay. + */ + private int startDelay; + + /** + * The speed. + */ + private int speed; + + /** + * The angle. + */ + private int angle; + + /** + * The distance to start. + */ + private int distance; + + /** + * The end location (used for location based projectiles). + */ + private Location endLocation; + + /** + * Creates a new projectile. + * @param source The source entity. + * @param victim The victim. + * @param projectileId The projectile's gfx id; + * @return The created projectile. + */ + public static Projectile create(Entity source, Entity victim, int projectileId) { + int speed = (int) (46 + (getLocation(source).getDistance(victim.getLocation()) * 5)); + return new Projectile(source, victim, projectileId, 40, 36, 41, speed, 5, source == null ? 11 : source.size() << 5); + } + + /** + * Creates a new projectile. + * @param source The source node. + * @param victim The victim. + * @param projectileId The projectile's gfx id; + * @param startHeight The starting height. + * @param endHeight The ending height. + * @return The created projectile. + */ + public static Projectile create(Entity source, Entity victim, int projectileId, int startHeight, int endHeight) { + int speed = (int) (46 + (getLocation(source).getDistance(victim.getLocation()) * 5)); + return new Projectile(source, victim, projectileId, startHeight, endHeight, 41, speed, 5, source == null ? 11 : source.size() << 5); + } + + /** + * Creates a new projectile. + * @param source The source node. + * @param victim The victim. + * @param projectileId The projectile's gfx id; + * @param startHeight The starting height. + * @param endHeight The ending height. + * @param startDelay The start delay. + * @return The created projectile. + */ + public static Projectile create(Entity source, Entity victim, int projectileId, int startHeight, int endHeight, int startDelay) { + int speed = (int) (46 + (getLocation(source).getDistance(victim.getLocation()) * 5)); + return new Projectile(source, victim, projectileId, startHeight, endHeight, startDelay, speed, 5, source == null ? 11 : source.size() << 5); + } + + /** + * Creates a new projectile. + * @param source The source node. + * @param victim The victim. + * @param projectileId The projectile's gfx id; + * @param startHeight The starting height. + * @param endHeight The ending height. + * @param startDelay The start delay. + * @param speed The projectile speed. + * @return The created projectile. + */ + public static Projectile create(Entity source, Entity victim, int projectileId, int startHeight, int endHeight, int startDelay, int speed) { + return new Projectile(source, victim, projectileId, startHeight, endHeight, startDelay, speed, 5, source == null ? 11 : source.size() << 5); + } + + /** + * Creates a new projectile. + * @param source The source node. + * @param victim The victim. + * @param projectileId The projectile's gfx id; + * @param startHeight The starting height. + * @param endHeight The ending height. + * @param startDelay The start delay. + * @param speed The projectile speed. + * @param angle The angle. + * @return The created projectile. + */ + public static Projectile create(Entity source, Entity victim, int projectileId, int startHeight, int endHeight, int startDelay, int speed, int angle) { + return new Projectile(source, victim, projectileId, startHeight, endHeight, startDelay, speed, angle, source.size() << 5); + } + + /** + * Creates a new projectile. + * @param source The source node. + * @param victim The victim. + * @param projectileId The projectile's gfx id; + * @param startHeight The starting height. + * @param endHeight The ending height. + * @param startDelay The startDelay. + * @param speed The projectile speed. + * @param angle The angle. + * @param distance The distance to start from. + * @return The created projectile. + */ + public static Projectile create(Entity source, Entity victim, int projectileId, int startHeight, int endHeight, int startDelay, int speed, int angle, int distance) { + return new Projectile(source, victim, projectileId, startHeight, endHeight, startDelay, speed, angle, distance); + } + + /** + * Creates a new projectile. + * @param destination The victim. + * @param projectileId The projectile's gfx id; + * @param startHeight The starting height. + * @param endHeight The ending height. + * @param startDelay The startDelay. + * @param speed The projectile speed. + * @param angle The angle. + * @param distance The distance to start from. + * @return The created projectile. + */ + public static Projectile create(Location start, Location destination, int projectileId, int startHeight, int endHeight, int startDelay, int speed, int angle, int distance) { + return new Projectile(start, destination, projectileId, startHeight, endHeight, startDelay, speed, angle, distance); + } + + /** + * Creates a new magic-speed based projectile. + * @param source The source node. + * @param victim The victim. + * @param projectileId The projectile's gfx id; + * @param startHeight The starting height. + * @param endHeight The ending height. + * @param startDelay The start delay type. + * @param angle The angle. + * @return The created projectile. + */ + public static Projectile magic(Entity source, Entity victim, int projectileId, int startHeight, int endHeight, int startDelay, int angle) { + int speed = (int) (46 + (getLocation(source).getDistance(victim.getLocation()) * 10)); + return new Projectile(source, victim, projectileId, startHeight, endHeight, startDelay, speed, angle, source.size() << 5); + } + + /** + * Creates a new range-speed based projectile. + * @param source The source node. + * @param victim The victim. + * @param projectileId The projectile's gfx id; + * @param startHeight The starting height. + * @param endHeight The ending height. + * @param startDelay The start delay. + * @param angle The angle. + * @return The created projectile. + */ + public static Projectile ranged(Entity source, Entity victim, int projectileId, int startHeight, int endHeight, int startDelay, int angle) { + int speed = (int) (46 + (getLocation(source).getDistance(victim.getLocation()) * 5)); + return new Projectile(source, victim, projectileId, startHeight, endHeight, startDelay, speed, angle, source.size() << 5); + } + + /** + * Constructs a new {@code Projectile} {@code Object}. + */ + public Projectile() { + /* + * empty. + */ + } + + /** + * Constructs a new projectile. + * @param source The source node. + * @param victim The entity victim. + * @param projectileId The projectile gfx id. + * @param startHeight The start height. + * @param endHeight The end height. + * @param startDelay The start delay. + * @param speed The projectile speed. + * @param angle The projectile angle. + * @param distance The distance. + */ + private Projectile(Entity source, Entity victim, int projectileId, int startHeight, int endHeight, int startDelay, int speed, int angle, int distance) { + this.source = source; + this.sourceLocation = getLocation(source); + this.victim = victim; + this.projectileId = projectileId; + this.startHeight = startHeight; + this.endHeight = endHeight; + this.startDelay = startDelay; + this.speed = speed; + this.angle = angle; + this.distance = distance; + } + + /** + * Constructs a new {@code Projectile} {@code Object}. + * @param start The start location. + * @param projectileId The projectile id. + * @param startHeight The start height. + * @param endHeight The end height. + * @param startDelay The start delay. + * @param speed The speed. + * @param angle The angle. + * @param distance The distance. + */ + private Projectile(Location start, Location l, int projectileId, int startHeight, int endHeight, int startDelay, int speed, int angle, int distance) { + this.sourceLocation = start; + this.endLocation = l; + this.projectileId = projectileId; + this.startHeight = startHeight; + this.endHeight = endHeight; + this.startDelay = startDelay; + this.speed = speed; + this.angle = angle; + this.distance = distance; + } + + /** + * Gets the speed. + * @param source the source. + * @param targetLoc the target location. + * @return + */ + public static int getSpeed(Entity source, Location targetLoc) { + return (int) (46 + (getLocation(source).getDistance(targetLoc) * 5)); + } + + /** + * Gets the source location on construction. + * @param n The node. + * @return The centered location. + */ + public static Location getLocation(Entity n) { + if (n == null) { + return null; + } + return n.getCenterLocation(); + } + + /** + * Changes the projectile so it sends from the source mob to the victim mob + * given. + * @param source The source mob. + * @param victim The victim mob. + * @return The projectile instance. + */ + public Projectile transform(Entity source, Entity victim) { + return transform(source, victim, source instanceof NPC, 46, 5); + } + + /** + * Changes the projectile so it sends from the source mob to the victim mob + * given. + * @param source The source mob. + * @param victim The victim mob. + * @param npc If the source should be handled as an NPC. + * @param baseSpeed The base speed. + * @param modifiedSpeed The modified speed. + * @return The projectile instance. + */ + public Projectile transform(Entity source, Entity victim, boolean npc, int baseSpeed, int modifiedSpeed) { + this.source = source; + this.sourceLocation = getLocation(source); + this.victim = victim; + this.speed = (int) (baseSpeed + sourceLocation.getDistance(victim.getLocation()) * modifiedSpeed); + if (npc) { + this.distance = source.size() << 5; + } + return this; + } + + /** + * Gets a new {@code Projectile} {@code Object} based of this projectile + * object. + * @param source The source entity. + * @param victim The victim entity. + * @param speedMultiplier The speed multiplier. + * @return The created {@code Projectile} {@code Object}. + */ + public Projectile copy(Entity source, Entity victim, double speedMultiplier) { + // int distance = source instanceof NPC ? source.size() << 6 : 11; + int speed = (int) (this.speed + (source.getLocation().getDistance(victim.getLocation()) * speedMultiplier)); + return new Projectile(source, victim, projectileId, startHeight, endHeight, startDelay, speed, angle, distance); + } + + /** + * Transforms the projectile so it is location based and it sends to the + * location. + * @param source The source mob. + * @param l The location. + * @return The projectile instance. + */ + public Projectile transform(Entity source, Location l) { + return transform(source, l, source instanceof NPC, 46, 5); + } + + /** + * Transforms a projectile to be location based, with updated parameters. + * @param source The mob sending this projectile. + * @param l The end location. + * @param npc If the mob should be handled as an npc. + * @param baseSpeed The base speed. + * @param modifiedSpeed The modified speed. + * @return The projectile instance. + */ + public Projectile transform(Entity source, Location l, boolean npc, int baseSpeed, int modifiedSpeed) { + this.source = source; + this.sourceLocation = getLocation(source); + this.endLocation = l; + this.speed = (int) (baseSpeed + sourceLocation.getDistance(l) * modifiedSpeed); + if (npc) { + this.distance = source.size() << 5; + } + return this; + } + + /** + * Sends this projectile. + */ + public void send() { + send(this); + } + + /** + * Sends the projectile. + * @param p The projectile. + */ + public static void send(Projectile p) { + RegionManager.getRegionChunk(p.getSourceLocation()).flag(new ProjectileUpdateFlag(p)); + } + + /** + * Transforms the projectile (to start from the source & end at the victim) + * and sends it. + * @param source The source. + * @param victim The victim. + * @param p The projectile to send. + */ + public static void send(Entity source, Entity victim, Projectile p) { + send(p.transform(source, victim)); + } + + /** + * Transforms the projectile (to start from the source & end at the + * locations) and sends it. + * @param source The source. + * @param l The location. + * @param p The projectile to send. + */ + public static void send(Entity source, Location l, Projectile p) { + send(p.transform(source, l)); + } + + /** + * @param source The source node. + */ + public void setSource(Entity source) { + this.source = source; + } + + /** + * @return The source node. + */ + public Entity getSource() { + return source; + } + + /** + * @param sourceLocation the sourceLocation to set + */ + public void setSourceLocation(Location sourceLocation) { + this.sourceLocation = sourceLocation; + } + + /** + * @return the sourceLocation + */ + public Location getSourceLocation() { + return sourceLocation; + } + + /** + * @param victim The entity victim. + */ + public void setVictim(Entity victim) { + this.victim = victim; + } + + /** + * @return The entity victim. + */ + public Entity getVictim() { + return victim; + } + + /** + * @param projectileId the projectileId to set + */ + public void setProjectileId(int projectileId) { + this.projectileId = projectileId; + } + + /** + * @return the projectileId + */ + public int getProjectileId() { + return projectileId; + } + + /** + * @param startHeight the startHeight to set + */ + public void setStartHeight(int startHeight) { + this.startHeight = startHeight; + } + + /** + * @return the startHeight + */ + public int getStartHeight() { + return startHeight; + } + + /** + * @param endHeight the endHeight to set + */ + public void setEndHeight(int endHeight) { + this.endHeight = endHeight; + } + + /** + * @return the endHeight + */ + public int getEndHeight() { + return endHeight; + } + + /** + * @param delay the delay to set + */ + public void setStartDelay(int delay) { + this.startDelay = delay; + } + + /** + * @return the start delay. + */ + public int getStartDelay() { + return startDelay; + } + + /** + * @param speed the speed to set + */ + public void setSpeed(int speed) { + this.speed = speed; + } + + /** + * @return the speed + */ + public int getSpeed() { + return speed; + } + + /** + * @param angle the angle to set + */ + public void setAngle(int angle) { + this.angle = angle; + } + + /** + * @return the angle + */ + public int getAngle() { + return angle; + } + + /** + * @param distance the distance to set + */ + public void setDistance(int distance) { + this.distance = distance; + } + + /** + * @return the distance + */ + public int getDistance() { + return distance; + } + + /** + * Checks if the projectile is location based. + * @return {@code True} if so, {@code false} if not. + */ + public boolean isLocationBased() { + return endLocation != null; + } + + /** + * @return the endLocation + */ + public Location getEndLocation() { + return endLocation; + } + + /** + * @param endLocation the endLocation to set + */ + public void setEndLocation(Location endLocation) { + this.endLocation = endLocation; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/impl/Properties.java b/Server/src/main/core/game/node/entity/impl/Properties.java new file mode 100644 index 0000000..78e4f88 --- /dev/null +++ b/Server/src/main/core/game/node/entity/impl/Properties.java @@ -0,0 +1,582 @@ +package core.game.node.entity.impl; + +import core.game.container.Container; +import core.game.container.impl.EquipmentContainer; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.spell.CombatSpell; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.equipment.ArmourSet; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.update.flag.EntityFlag; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.game.node.entity.combat.CombatPulse; +import core.game.system.config.ItemConfigParser; +import core.game.system.config.NPCConfigParser; + +/** + * Holds an entity's properties. + * @author Emperor + */ +public final class Properties { + + /** + * The entity. + */ + private final Entity entity; + + /** + * The entity's combat pulse. + */ + private CombatPulse combatPulse; + + /** + * If the entity is retaliating. + */ + private boolean retaliating = true; + + /** + * If the entity is teleporting. + */ + private boolean teleporting; + + /** + * The entity's combat level. + */ + private int combatLevel; + + /** + * The entity's current attack style. + */ + private WeaponInterface.AttackStyle attackStyle; + + /** + * The current teleport destination location. + */ + private Location teleportLocation; + + /** + * The spawn location. + */ + private Location spawnLocation; + + /** + * The bonuses. + */ + private int[] bonuses = new int[15]; + + /** + * The current attack speed. + */ + private int attackSpeed = 4; + + /** + * The last animation end. + */ + private long lastAnimationEnd; + + /** + * The attack animation. + */ + private Animation attackAnimation = new Animation(422, Animator.Priority.HIGH); + + /** + * The defence animation. + */ + private Animation defenceAnimation = new Animation(404); + + /** + * The death animation. + */ + private Animation deathAnimation = new Animation(9055, Animator.Priority.HIGH); + + public Graphics deathGfx = new Graphics(-1); + + /** + * The range animation. + */ + private Animation rangeAnimation; + + /** + * The magic animation. + */ + private Animation magicAnimation; + + /** + * The current magic spell. + */ + private CombatSpell spell; + + /** + * The autocasted magic spell. + */ + private CombatSpell autocastSpell; + + /** + * The current armour set used. + */ + private ArmourSet armourSet; + + /** + * If the entity is standing in multizone. + */ + private boolean multiZone; + + /** + * If the entity is in a safe zone. + */ + private boolean safeZone; + + /** + * The location which the player respawns at the event of death while safeZone = true + */ + public Location safeRespawn; + + /** + * The combat time out ticks. + */ + private int combatTimeOut = 10; + + /** + * If the entity can walk over other NPCs in multiway combat zone. + */ + private boolean npcWalkable; + + /** + * The style the npc protects against. + */ + private CombatStyle protectStyle; + + /** + * Constructs a new {@code Properties} {@code Object}. + * @param entity + */ + public Properties(Entity entity) { + this.entity = entity; + this.combatPulse = new CombatPulse(entity); + } + + /** + * Updates the defence animation. + */ + public void updateDefenceAnimation() { + if (entity instanceof NPC) { + Animation animation = ((NPC) entity).getDefinition().getConfiguration(NPCConfigParser.DEFENCE_ANIMATION); + if (animation != null) { + defenceAnimation = animation; + } + return; + } + Container c = ((Player) entity).getEquipment(); + Item item = c.get(EquipmentContainer.SLOT_SHIELD); + if (item != null) { + defenceAnimation = item.getDefinition().getConfiguration(ItemConfigParser.DEFENCE_ANIMATION, Animation.create(1156)); + } else if ((item = c.get(EquipmentContainer.SLOT_WEAPON)) != null) { + defenceAnimation = item.getDefinition().getConfiguration(ItemConfigParser.DEFENCE_ANIMATION, Animation.create(424)); + } else { + defenceAnimation = Animation.create(397); + } + } + + /** + * Gets a combat animation by the index. + * @param index the index. + * @return the animation. + */ + public Animation getCombatAnimation(int index) { + return index == 0 ? attackAnimation : index == 1 ? magicAnimation : index == 2 ? rangeAnimation : index == 3 ? defenceAnimation : deathAnimation; + } + + /** + * Gets the entity. + * @return The entity. + */ + public Entity getEntity() { + return entity; + } + + /** + * Gets the teleporting. + * @return The teleporting. + */ + public boolean isTeleporting() { + return teleporting; + } + + /** + * Sets the teleporting. + * @param teleporting The teleporting to set. + */ + public void setTeleporting(boolean teleporting) { + this.teleporting = teleporting; + } + + /** + * Gets the combatLevel.
Deprecated Due to summoning-based combat level + * not being calculated in. + * @return The combatLevel. + */ + @Deprecated + public int getCombatLevel() { + return combatLevel; + } + + /** + * Gets the current combat level. + * @return The combat level. + */ + public int getCurrentCombatLevel() { + if (entity instanceof Player) { + Player player = (Player) entity; + if ((GameWorld.getSettings().isPvp() || (GameWorld.getSettings().getWild_pvp_enabled() && player.getSkullManager().isWilderness())) + && !player.getFamiliarManager().isUsingSummoning()) { + //TODO: Split combat levels should also be used for Bounty Hunter + return combatLevel; + } else { + return combatLevel + player.getFamiliarManager().getSummoningCombatLevel(); + } + } + return combatLevel; + } + + /** + * Sets the combatLevel. + * @param combatLevel The combatLevel to set. + */ + public void setCombatLevel(int combatLevel) { + this.combatLevel = combatLevel; + } + + /** + * Gets the attackStyle. + * @return The attackStyle. + */ + public WeaponInterface.AttackStyle getAttackStyle() { + return attackStyle; + } + + /** + * Sets the attackStyle. + * @param attackStyle The attackStyle to set. + */ + public void setAttackStyle(WeaponInterface.AttackStyle attackStyle) { + this.attackStyle = attackStyle; + } + + /** + * Gets the teleportLocation. + * @return The teleportLocation. + */ + public Location getTeleportLocation() { + return teleportLocation; + } + + /** + * Sets the teleportLocation. + * @param teleportLocation The teleportLocation to set. + */ + public void setTeleportLocation(Location teleportLocation) { + this.teleportLocation = teleportLocation; + } + + /** + * Gets the spawnLocation. + * @return The spawnLocation. + */ + public Location getSpawnLocation() { + return spawnLocation; + } + + /** + * Sets the spawnLocation. + * @param spawnLocation The spawnLocation to set. + */ + public void setSpawnLocation(Location spawnLocation) { + this.spawnLocation = spawnLocation; + } + + /** + * Gets the bonuses. + * @return The bonuses. + */ + public int[] getBonuses() { + return bonuses; + } + + /** + * Sets the bonuses. + * @param bonuses The bonuses to set. + */ + public void setBonuses(int[] bonuses) { + this.bonuses = bonuses; + } + + /** + * Gets the last animation end. + * @return The last animation end. + */ + public long getLastAnimationEnd() { + return lastAnimationEnd; + } + + /** + * Gets the combatPulse. + * @return The combatPulse. + */ + public CombatPulse getCombatPulse() { + return combatPulse; + } + + /** + * Sets the combatPulse. + * @return The void. + */ + public void setCombatPulse(CombatPulse combatPulse) { + this.combatPulse = (CombatPulse)combatPulse; + } + + /** + * Gets the retaliating. + * @return The retaliating. + */ + public boolean isRetaliating() { + return retaliating; + } + + /** + * Sets the retaliating. + * @param retaliating The retaliating to set. + */ + public void setRetaliating(boolean retaliating) { + this.retaliating = retaliating; + } + + /** + * Gets the attackSpeed. + * @return The attackSpeed. + */ + public int getAttackSpeed() { + return attackSpeed; + } + + /** + * Sets the attackSpeed. + * @param attackSpeed The attackSpeed to set. + */ + public void setAttackSpeed(int attackSpeed) { + this.attackSpeed = attackSpeed; + } + + /** + * Gets the attackAnimation. + * @return The attackAnimation. + */ + public Animation getAttackAnimation() { + return attackAnimation; + } + + /** + * Sets the attackAnimation. + * @param attackAnimation The attackAnimation to set. + */ + public void setAttackAnimation(Animation attackAnimation) { + this.attackAnimation = attackAnimation; + } + + /** + * Gets the defenceAnimation. + * @return The defenceAnimation. + */ + public Animation getDefenceAnimation() { + return defenceAnimation; + } + + /** + * Sets the defenceAnimation. + * @param defenceAnimation The defenceAnimation to set. + */ + public void setDefenceAnimation(Animation defenceAnimation) { + this.defenceAnimation = defenceAnimation; + } + + /** + * Sets the spell. + * @param spell The spell to set. + */ + public void setSpell(CombatSpell spell) { + this.spell = spell; + if (spell != null) { + combatPulse.updateStyle(); + } + } + + /** + * Gets the spell. + * @return The spell. + */ + public CombatSpell getSpell() { + return spell; + } + + /** + * @return the autocastSpell. + */ + public CombatSpell getAutocastSpell() { + return autocastSpell; + } + + /** + * @param autocastSpell the autocastSpell to set. + */ + public void setAutocastSpell(CombatSpell autocastSpell) { + this.autocastSpell = autocastSpell; + } + + /** + * @return the armourSet. + */ + public ArmourSet getArmourSet() { + return armourSet; + } + + /** + * @param armourSet the armourSet to set. + */ + public void setArmourSet(ArmourSet armourSet) { + this.armourSet = armourSet; + } + + /** + * Gets the deathAnimation. + * @return The deathAnimation. + */ + public Animation getDeathAnimation() { + return deathAnimation; + } + + /** + * Sets the deathAnimation. + * @param deathAnimation The deathAnimation to set. + */ + public void setDeathAnimation(Animation deathAnimation) { + this.deathAnimation = deathAnimation; + } + + /** + * Gets the multiZone. + * @return The multiZone. + */ + public boolean isMultiZone() { + return multiZone; + } + + /** + * Sets the multiZone. + * @param multiZone The multiZone to set. + */ + public void setMultiZone(boolean multiZone) { + this.multiZone = multiZone; + } + + /** + * Gets the safeZone. + * @return The safeZone. + */ + public boolean isSafeZone() { + return safeZone; + } + + /** + * Sets the safeZone. + * @param safeZone The safeZone to set. + */ + public void setSafeZone(boolean safeZone) { + this.safeZone = safeZone; + } + + /** + * Gets the combatTimeOut. + * @return The combatTimeOut. + */ + public int getCombatTimeOut() { + return combatTimeOut; + } + + /** + * Sets the combatTimeOut. + * @param combatTimeOut The combatTimeOut to set. + */ + public void setCombatTimeOut(int combatTimeOut) { + this.combatTimeOut = combatTimeOut; + } + + /** + * Gets the npcWalkable. + * @return The npcWalkable. + */ + public boolean isNPCWalkable() { + return npcWalkable; + } + + /** + * Sets the npcWalkable. + * @param npcWalkable The npcWalkable to set. + */ + public void setNPCWalkable(boolean npcWalkable) { + this.npcWalkable = npcWalkable; + } + + /** + * Gets the rangeAnimation. + * @return the rangeAnimation + */ + public Animation getRangeAnimation() { + return rangeAnimation; + } + + /** + * Sets the rangeAnimation. + * @param rangeAnimation the rangeAnimation to set. + */ + public void setRangeAnimation(Animation rangeAnimation) { + this.rangeAnimation = rangeAnimation; + } + + /** + * Gets the magicAnimation. + * @return the magicAnimation + */ + public Animation getMagicAnimation() { + return magicAnimation; + } + + /** + * Sets the magicAnimation. + * @param magicAnimation the magicAnimation to set. + */ + public void setMagicAnimation(Animation magicAnimation) { + this.magicAnimation = magicAnimation; + } + + /** + * Gets the protectStyle. + * @return the protectStyle. + */ + public CombatStyle getProtectStyle() { + return protectStyle; + } + + /** + * Sets the protectStyle. + * @param protectStyle the protectStyle to set + */ + public void setProtectStyle(CombatStyle protectStyle) { + this.protectStyle = protectStyle; + } + +} diff --git a/Server/src/main/core/game/node/entity/impl/PulseManager.java b/Server/src/main/core/game/node/entity/impl/PulseManager.java new file mode 100644 index 0000000..74a78e7 --- /dev/null +++ b/Server/src/main/core/game/node/entity/impl/PulseManager.java @@ -0,0 +1,147 @@ +package core.game.node.entity.impl; + +import core.game.interaction.MovementPulse; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.DeathTask; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.node.entity.combat.CombatPulse; +import core.game.world.GameWorld; + +import java.util.ArrayList; +import java.util.HashMap; + +/** + * Represents an entity's pulse manager. + * @author Emperor + */ +public final class PulseManager { + + /** + * The movement pulse. + */ + private final HashMap currentPulses = new HashMap<>(); + + public void run(Pulse pulse) { + run(pulse, PulseType.STANDARD); + } + + /** + * Runs a pulse. + * @param pulse The pulse. + * @param pulseType The pulse type we're trying to run. + */ + public void run(Pulse pulse, PulseType pulseType) { + ArrayList toRemove = new ArrayList<>(currentPulses.size()); + currentPulses.forEach((key, value) -> { + if (value != null && !value.isRunning()) { + toRemove.add(key); + } + }); + for (PulseType t : toRemove) currentPulses.remove(t); + + if (currentPulses.get(PulseType.STRONG) != null) { + //strong pulses cannot be interrupted or ran alongside anything else. They are the ONLY pulse type when they are present. + return; + } + + if (!clear(pulseType)) { + return; + } + + if (pulseType == PulseType.STRONG) { + clear(); + } + + currentPulses.put(pulseType, pulse); + pulse.start(); + if (pulse.isRunning()) { + GameWorld.getPulser().submit(pulse); + } + } + + public void clear() { + currentPulses.forEach((type, pulse) -> { + if (type != PulseType.STRONG && pulse != null) pulse.stop(); + }); + } + + /** + * Clears the pulses. + */ + public boolean clear(PulseType pulseType) { + Pulse pulse = currentPulses.get(pulseType); + + if (pulse != null) { + pulse.stop(); + currentPulses.remove(pulseType); + } + return true; + } + + /** + * Runs the unhandled reward pulse ("Nothing interesting happens.") + * @param player The player. + * @return The pulse. + * @param pulseType The pulse type. + */ + public Pulse runUnhandledAction(final Player player, PulseType pulseType) { + Pulse pulse = new Pulse(1, player) { + @Override + public boolean pulse() { + player.getPacketDispatch().sendMessage("Nothing interesting happens."); + return true; + } + }; + run(pulse, pulseType); + return pulse; + } + + /** + * Checks if the current pulse moves the entity. + * @return {@code True} if so. + */ + public boolean isMovingPulse() { + if (!hasPulseRunning()) { + return false; + } + + Pulse current = getCurrent(); + return current instanceof MovementPulse || current instanceof CombatPulse; + } + + /** + * Checks if a pulse is running. + * @return {@code True} if so. + */ + public boolean hasPulseRunning() { + return getCurrent() != null && getCurrent().isRunning(); + } + + /** + * Cancels the death task, if any. + * @param e The entity. + */ + public static void cancelDeathTask(Entity e) { + if (!DeathTask.isDead(e) || e.getPulseManager().getCurrent() == null) { + return; + } + e.getPulseManager().getCurrent().stop(); + } + + /** + * Gets the current. + * @return The current. + */ + public Pulse getCurrent() { + PulseType[] types = PulseType.values(); + for (PulseType type : types) { + if (currentPulses.get(type) != null) { + return currentPulses.get(type); + } + } + return null; + } + +} + diff --git a/Server/src/main/core/game/node/entity/impl/PulseType.java b/Server/src/main/core/game/node/entity/impl/PulseType.java new file mode 100644 index 0000000..3150695 --- /dev/null +++ b/Server/src/main/core/game/node/entity/impl/PulseType.java @@ -0,0 +1,11 @@ +package core.game.node.entity.impl; + +//facilitating pseudo-entity-queues in a clean manner with minimal disruption to existing code. +//this is NOT perfect. +//bit shit, really. +public enum PulseType { + STANDARD, //standard pulse slot, should be interrupted/replaced by most things + STRONG, //enforces itself as the only that can run + CUSTOM_1, //custom slots for extra tasks that should run alongside standard tasks. + CUSTOM_2 +} diff --git a/Server/src/main/core/game/node/entity/impl/WalkingQueue.java b/Server/src/main/core/game/node/entity/impl/WalkingQueue.java new file mode 100644 index 0000000..fbd9d2e --- /dev/null +++ b/Server/src/main/core/game/node/entity/impl/WalkingQueue.java @@ -0,0 +1,489 @@ +package core.game.node.entity.impl; + +import content.global.skill.skillcapeperks.SkillcapePerks; +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.node.entity.skill.Skills; +import core.game.node.item.Item; +import core.game.node.item.GroundItem; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.Point; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.chunk.ItemUpdateFlag; +import core.tools.Log; +import core.tools.SystemLogger; + +import java.util.Deque; +import java.util.ArrayDeque; +import java.util.ArrayList; + +import static core.api.ContentAPIKt.*; + +/** + * The walking queue. + * @author Emperor + */ +public final class WalkingQueue { + + /** + * The walking queue. + */ + private final Deque walkingQueue = new ArrayDeque(); + + /** + * The entity. + */ + private final Entity entity; + + /** + * The current walking direction. + */ + private int walkDir = -1; + + /** + * The current running direction. + */ + private int runDir = -1; + + /** + * If the entity is running (set to true when holding the ctrl button + + * click). + */ + private boolean running = false; + + /** + * If running is disabled. + */ + private boolean runDisabled; + + /** + * The last location this entity walked on. + */ + private Location footPrint; + + public ArrayList routeItems = new ArrayList(); + + /** + * Constructs a new {@code WalkingQueue} {@code Object}. + * @param entity The entity. + */ + public WalkingQueue(Entity entity) { + this.entity = entity; + this.footPrint = entity.getLocation(); + } + + /** + * Updates the walking queue. + */ + public void update() { + boolean isPlayer = entity instanceof Player; + this.walkDir = -1; + this.runDir = -1; + if(entity.getLocation() == null) { + return; + } + if (updateTeleport()) { + return; + } + if (isPlayer && updateRegion(entity.getLocation(), true)) { + return; + } + if (hasTimerActive(entity, "frozen")) + return; + Point point = walkingQueue.poll(); + boolean drawPath = entity.getAttribute("routedraw", false); + if (point == null) { + updateRunEnergy(false); + if (isPlayer && drawPath) { + for (GroundItem item : routeItems) { + if (item != null) { + RegionManager.getRegionPlane(item.getLocation()).remove(item); + } + } + routeItems.clear(); + } + return; + } + if (isPlayer && ((Player) entity).getSettings().getRunEnergy() < 1.0) { + running = false; + ((Player) entity).getSettings().setRunToggled(false); + } + Point runPoint = null; + if (point.getDirection() == null) { + point = walkingQueue.poll(); + } + int walkDirection = -1; + int runDirection = -1; + if (isRunningBoth() && (point == null || !point.isRunDisabled())) { + runPoint = walkingQueue.poll(); + } + if (point != null) { + if (point.getDirection() == null) { + return; + } + walkDirection = point.getDirection().ordinal(); + } + if (runPoint != null) { + runDirection = runPoint.getDirection().ordinal(); + } + int diffX = 0; + int diffY = 0; + if (walkDirection != -1) { + diffX = point.getDiffX(); + diffY = point.getDiffY(); + } + if (runDirection != -1) { + footPrint = entity.getLocation().transform(diffX, diffY, 0); + diffX += runPoint.getDiffX(); + diffY += runPoint.getDiffY(); + updateRunEnergy(true); + } else { + updateRunEnergy(false); + } + if (diffX != 0 || diffY != 0) { + Location walk = entity.getLocation(); + if (point != null) { + walk = walk.transform(point.getDiffX(), point.getDiffY(), 0); + if (!entity.getZoneMonitor().move(entity.getLocation(), walk)) { + reset(); + /*if (entity.getPulseManager().isMovingPulse()) { + entity.getPulseManager().clear(); // TODO: Check for + // bugs + }*/ + return; + } + } + Location dest = entity.getLocation().transform(diffX, diffY, 0); + if (runPoint != null) { + if (!entity.getZoneMonitor().move(walk, dest)) { + dest = dest.transform(-runPoint.getDiffX(), -runPoint.getDiffY(), 0); + runPoint = null; + runDirection = -1; + reset(); + /*if (entity.getPulseManager().isMovingPulse()) { + entity.getPulseManager().clear(); // TODO: Check for + // bugs + }*/ + } + } + if (runPoint != null) { + entity.setDirection(runPoint.getDirection()); + } else if (point != null) { + entity.setDirection(point.getDirection()); + } + footPrint = entity.getLocation(); + entity.setLocation(dest); + RegionManager.move(entity); + } + this.walkDir = walkDirection; + this.runDir = runDirection; + } + + /** + * Gets the energy drain rate for this player. + * @param player The player. + * @return The energy drain rate. + */ + private double getEnergyDrainRate(Player player) { + double rate = 0.55; + if (player.getSettings().getWeight() > 0.0) { + rate *= 1 + (player.getSettings().getWeight() / 100); + } + if (hasTimerActive(player, "hamstrung")) { + rate *= 4; + } + return rate; + } + + /** + * Gets the energy restore amount. + * @param player The player. + * @return The amount to restore. + */ + private double getEnergyRestore(Player player) { + double rate = 100 / ((175 - (player.getSkills().getLevel(Skills.AGILITY))) / 0.6); + return rate; + } + + /** + * Increases the current amount of run energy, and updates it. + * @param decrease If we should decrease the run energy. + */ + public void updateRunEnergy(boolean decrease) { + if (!(entity instanceof Player)) { + return; + } + Player p = (Player) entity; + if(decrease && SkillcapePerks.isActive(SkillcapePerks.MARATHON_RUNNER,p)){ + if(p.getAttribute("run-incrementer",0) == 3){ + p.setAttribute("run-incrementer",0); + return; + } + p.incrementAttribute("run-incrementer"); + } + if (!decrease && p.getSettings().getRunEnergy() >= 100.0) { + return; + } + double drain = decrease ? getEnergyDrainRate(p) : -getEnergyRestore(p); + p.getSettings().updateRunEnergy(drain); + } + + /** + * Checks if the player is teleporting, if so does the teleporting and + * returns true. + * @return {@code True} if the player is teleporting, {@code false} if not. + */ + public boolean updateTeleport() { + if (entity.getProperties().getTeleportLocation() != null) { + reset(false); + entity.setLocation(entity.getProperties().getTeleportLocation()); + entity.getProperties().setTeleportLocation(null); + if (entity instanceof Player) { + Player p = (Player) entity; + Location last = p.getPlayerFlags().getLastSceneGraph(); + if (last == null) { + last = p.getLocation(); + } + if ((last.getRegionX() - entity.getLocation().getRegionX()) >= 4 || (last.getRegionX() - entity.getLocation().getRegionX()) <= -4) { + p.getPlayerFlags().setUpdateSceneGraph(true); + } else if ((last.getRegionY() - entity.getLocation().getRegionY()) >= 4 || (last.getRegionY() - entity.getLocation().getRegionY()) <= -4) { + p.getPlayerFlags().setUpdateSceneGraph(true); + } + } + RegionManager.move(entity); + footPrint = entity.getLocation(); + entity.getProperties().setTeleporting(true); + return true; + } + return false; + } + + /** + * Checks if the region should be updated, if so we set the update flag and + * return true. + * @return {@code True} if the region updated, {@code false} if not. + */ + public boolean updateRegion(Location location, boolean move) { + Player p = (Player) entity; + Location lastRegion = p.getPlayerFlags().getLastSceneGraph(); + if (lastRegion == null) { + lastRegion = location; + } + int rx = lastRegion.getRegionX(); + int ry = lastRegion.getRegionY(); + int cx = location.getRegionX(); + int cy = location.getRegionY(); + if ((rx - cx) >= 4) { + p.getPlayerFlags().setUpdateSceneGraph(true); + } else if ((rx - cx) <= -4) { + p.getPlayerFlags().setUpdateSceneGraph(true); + } + if ((ry - cy) >= 4) { + p.getPlayerFlags().setUpdateSceneGraph(true); + } else if ((ry - cy) <= -4) { + p.getPlayerFlags().setUpdateSceneGraph(true); + } + if (move && p.getPlayerFlags().isUpdateSceneGraph()) { + RegionManager.move(entity); + return true; + } + return false; + } + + /** + * Walks back to the last location. + */ + public void walkBack() { + entity.getPulseManager().clear(); + reset(); + addPath(footPrint.getX(), footPrint.getY()); + } + + /** + * Adds a path to the walking queue. + * @param x The last x-coordinate of the path. + * @param y The last y-coordinate of the path. + */ + public void addPath(int x, int y) { + addPath(x, y, runDisabled); + } + + /** + * Adds a path to the walking queue. + * @param x The last x-coordinate of the path. + * @param y The last y-coordinate of the path. + * @param runDisabled If running is disabled for this walking path. + */ + public void addPath(int x, int y, boolean runDisabled) { + Point point = walkingQueue.peekLast(); + if (point == null) { + return; + } + boolean drawRoute = entity.getAttribute("routedraw", false); + if (drawRoute && entity instanceof Player) { + Player p = (Player) entity; + GroundItem item = new GroundItem(new Item(13444), Location.create(x, y, p.getLocation().getZ()), p); + routeItems.add (item); + RegionManager.getRegionPlane(item.getLocation()).add(item); + } + int diffX = x - point.getX(), diffY = y - point.getY(); + int max = Math.max(Math.abs(diffX), Math.abs(diffY)); + for (int i = 0; i < max; i++) { + if (diffX < 0) { + diffX++; + } else if (diffX > 0) { + diffX--; + } + if (diffY < 0) { + diffY++; + } else if (diffY > 0) { + diffY--; + } + addPoint(x - diffX, y - diffY, runDisabled); + } + } + + /** + * Adds a point to the walking queue. + * @param x The x-coordinate of the point. + * @param y The y-coordinate of the point. + */ + public void addPoint(int x, int y, boolean runDisabled) { + Point point = walkingQueue.peekLast(); + if (point == null) { + return; + } + int diffX = x - point.getX(), diffY = y - point.getY(); + Direction direction = Direction.getDirection(diffX, diffY); + if (direction != null) { + walkingQueue.add(new Point(x, y, direction, diffX, diffY, runDisabled)); + } + } + + /** + * Checks if the entity is running. + * @return {@code True} if a ctrl + click reward was performed,
the + * player has the run option enabled or the NPC is a familiar,

+ * {@code false} if not. + */ + public boolean isRunningBoth() { + if (isRunDisabled()) return false; + if (entity instanceof Player && ((Player) entity).getSettings().isRunToggled()) { + return true; + } + return running; + } + + /** + * Checks if the entity has a path to walk. + * @return {@code True} if so. + */ + public boolean hasPath() { + return !walkingQueue.isEmpty(); + } + + /** + * Checks if the entity is moving. + * @return {@code True} if so. + */ + public boolean isMoving() { + return walkDir != -1 || runDir != -1; + } + + /** + * Resets the walking queue. + */ + public void reset() { + reset(running); + } + + /** + * Resets the walking queue. + * @param running The running flag (ctrl + click reward). + */ + public void reset(boolean running) { + Location loc = entity.getLocation(); + + if (loc == null) { + log(this.getClass(), Log.ERR, + "The entity location provided was null." + + "Are you sure anything down the stack trace isn't providing an NPC with a null location?" + ); + } + + walkingQueue.clear(); + walkingQueue.add(new Point(loc.getX(), loc.getY())); + this.running = running; + } + + /** + * Gets the current walking direction. + * @return The walk direction. + */ + public int getWalkDir() { + return walkDir; + } + + /** + * Gets the current run direction. + * @return The run direction. + */ + public int getRunDir() { + return runDir; + } + + /** + * Sets the running flag. + * @param running The running flag. + */ + public void setRunning(boolean running) { + this.running = running; + } + + /** + * Checks if the player is running. + * @return {@code True} if so. + */ + public boolean isRunning() { + return running; + } + + /** + * @return the footPrint + */ + public Location getFootPrint() { + return footPrint; + } + + /** + * @param footPrint the footPrint to set + */ + public void setFootPrint(Location footPrint) { + this.footPrint = footPrint; + } + + /** + * Gets the walking queue. + * @return The queue. + */ + public Deque getQueue() { + return walkingQueue; + } + + /** + * Gets the runDisabled. + * @return The runDisabled. + */ + public boolean isRunDisabled() { + return runDisabled; + } + + /** + * Sets the runDisabled. + * @param runDisabled The runDisabled to set. + */ + public void setRunDisabled(boolean runDisabled) { + this.runDisabled = runDisabled; + } +} diff --git a/Server/src/main/core/game/node/entity/lock/ActionLocks.java b/Server/src/main/core/game/node/entity/lock/ActionLocks.java new file mode 100644 index 0000000..e8a816a --- /dev/null +++ b/Server/src/main/core/game/node/entity/lock/ActionLocks.java @@ -0,0 +1,250 @@ +package core.game.node.entity.lock; + +import core.game.node.Node; +import core.game.world.GameWorld; + +import java.util.HashMap; +import java.util.Map; + +/** + * Holds the reward locks. + * @author Emperor + * @author Aero + */ +public final class ActionLocks { + + /** + * The movement lock. + */ + private Lock movementLock = new Lock(); + + /** + * The teleporting lock. + */ + private Lock teleportLock = new Lock(); + + /** + * The component lock. + */ + private Lock componentLock = new Lock(); + + /** + * The interaction lock. + */ + private Lock interactionLock = new Lock(); + + /** + * The equipment lock. + */ + private Lock equipmentLock = null; + + /** + * A mapping of custom locks (used for eg. food delay). + */ + private Map customLocks; + + /** + * Constructs a new {@code ActionLocks} {@code Object}. + */ + public ActionLocks() { + this.customLocks = new HashMap<>(); + } + + /** + * Locks all default actions (movement, teleport & interaction) for + * indefinite time. + */ + public void lock() { + lock(Integer.MAX_VALUE - GameWorld.getTicks()); + } + + /** + * Locks all the default actions (movement, teleport & interaction). + * @param ticks The amount of ticks to lock for. + */ + public void lock(int ticks) { + lockMovement(ticks); + lockInteractions(ticks); + } + + /** + * Unlocks the default actions. + */ + public void unlock() { + unlockMovement(); + unlockInteraction(); + } + + /** + * Locks the movement actions. + * @param ticks The amount of ticks to lock for. + */ + public void lockMovement(int ticks) { + movementLock.lock(ticks); + } + + /** + * Unlocks the movement lock. + */ + public void unlockMovement() { + movementLock.unlock(); + } + + /** + * Checks if movement actions are locked. + * @return {@code True} if so. + */ + public boolean isMovementLocked() { + return movementLock.isLocked(); + } + + /** + * Locks the teleport actions. + * @param ticks The amount of ticks to lock for. + */ + public void lockTeleport(int ticks) { + teleportLock.lock(ticks); + } + + /** + * Unlocks the teleport lock. + */ + public void unlockTeleport() { + teleportLock.unlock(); + } + + /** + * Checks if teleport actions are locked. + * @return {@code True} if so. + */ + public boolean isTeleportLocked() { + return teleportLock.isLocked(); + } + + /** + * Locks the component actions. + * @param ticks The amount of ticks to lock for. + */ + public void lockComponent(int ticks) { + componentLock.lock(ticks); + } + + /** + * Unlocks the component lock. + */ + public void unlockComponent() { + componentLock.unlock(); + } + + /** + * Checks if component actions are locked. + * @return {@code True} if so. + */ + public boolean isComponentLocked() { + return componentLock.isLocked(); + } + + /** + * Locks the interaction actions. + * @param ticks The amount of ticks to lock for. + */ + public void lockInteractions(int ticks) { + interactionLock.lock(ticks); + } + + /** + * Unlocks the interaction lock. + */ + public void unlockInteraction() { + interactionLock.unlock(); + } + + /** + * Checks if interaction actions are locked. + * @return {@code True} if so. + */ + public boolean isInteractionLocked() { + return interactionLock.isLocked(); + } + + /** + * Locks the lock for the given key. + * @param key The key. + * @param ticks The amount of ticks to lock for. + * @return The lock object. + */ + public Lock lock(String key, int ticks) { + return lock(key, ticks, null); + } + + /** + * Locks the lock for the given key. + * @param key The key. + * @param ticks The amount of ticks to lock for. + * @param elapse The elapse event. + * @return The lock object. + */ + public Lock lock(String key, int ticks, LockElapse elapse) { + Lock lock = customLocks.get(key); + if (lock == null) { + customLocks.put(key, lock = new Lock()); + } + lock.setElapse(elapse).lock(ticks); + return lock; + } + + /** + * Unlocks the lock for the given key and removes it from the cache. + * @param key The key. + * @param node The node. + */ + public void unlock(String key, Node node) { + unlock(key, true, node); + } + + /** + * Unlocks the lock for the given key. + * @param key The key. + * @param cacheRemove If the lock can be removed from the cache. + * @param node The node. + */ + public void unlock(String key, boolean cacheRemove, Node node) { + Lock lock = customLocks.get(key); + if (lock != null) { + lock.unlock(); + if (lock.getElapseEvent() != null) { + lock.getElapseEvent().elapse(node, lock); + } + if (cacheRemove) { + customLocks.remove(key); + } + } + } + + /** + * Checks if the lock for the given key is currently locked. + * @param key The key. + * @return {@code True} if so. + */ + public boolean isLocked(String key) { + Lock lock = customLocks.get(key); + return lock != null && lock.isLocked(); + } + + /** + * Gets the equipmentLock. + * @return The equipmentLock. + */ + public Lock getEquipmentLock() { + return equipmentLock; + } + + /** + * Sets the equipmentLock. + * @param equipmentLock The equipmentLock to set. + */ + public void setEquipmentLock(Lock equipmentLock) { + this.equipmentLock = equipmentLock; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/lock/Lock.java b/Server/src/main/core/game/node/entity/lock/Lock.java new file mode 100644 index 0000000..efa739c --- /dev/null +++ b/Server/src/main/core/game/node/entity/lock/Lock.java @@ -0,0 +1,108 @@ +package core.game.node.entity.lock; + +import core.game.world.GameWorld; + +/** + * Represents a lock. + * @author Emperor + * @author Aero + */ +public class Lock { + + /** + * The expiration of the lock. + */ + private int expiration; + + /** + * The custom lock elapse. + */ + private LockElapse elapse; + + /** + * The message to be sent when the lock is called upon. + */ + private String message; + + /** + * Constructs a new {@code Lock} {@code Object}. + */ + public Lock() { + this(null); + } + + /** + * Constructs a new {@code Lock} {@code Object}. + * @param message The message. + */ + public Lock(String message) { + this.message = message; + } + + /** + * Locks for an indefinite time. + */ + public void lock() { + lock(Integer.MAX_VALUE - GameWorld.getTicks()); + } + + /** + * Locks this lock. + * @param ticks The amount of ticks to lock for. + */ + public void lock(int ticks) { + if (ticks > expiration - GameWorld.getTicks()) { + this.expiration = GameWorld.getTicks() + ticks; + } + } + + /** + * Unlocks the lock. + */ + public void unlock() { + this.expiration = 0; + } + + /** + * Checks if this lock is locked. + * @return {@code True} if so. + */ + public boolean isLocked() { + return expiration > GameWorld.getTicks(); + } + + /** + * Sets the custom lock elapse. + * @param elapse The elapse. + * @return The lock instance for chaining. + */ + public Lock setElapse(LockElapse elapse) { + this.elapse = elapse; + return this; + } + + /** + * Gets the custom lock elapse event. + * @return The custom lock elapse event. + */ + public LockElapse getElapseEvent() { + return elapse; + } + + /** + * Gets the message. + * @return The message. + */ + public String getMessage() { + return message; + } + + /** + * Sets the message. + * @param message The message to set. + */ + public void setMessage(String message) { + this.message = message; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/lock/LockElapse.java b/Server/src/main/core/game/node/entity/lock/LockElapse.java new file mode 100644 index 0000000..5ca116d --- /dev/null +++ b/Server/src/main/core/game/node/entity/lock/LockElapse.java @@ -0,0 +1,18 @@ +package core.game.node.entity.lock; + +import core.game.node.Node; + +/** + * Called after the expiration of a custom reward lock. + * @author Aero + */ +public interface LockElapse { + + /** + * Called when a custom reward lock has elapsed. + * @param node The node. + * @param lock The custom reward lock. + */ + public void elapse(Node node, Lock lock); + +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/npc/AbstractNPC.java b/Server/src/main/core/game/node/entity/npc/AbstractNPC.java new file mode 100644 index 0000000..b986566 --- /dev/null +++ b/Server/src/main/core/game/node/entity/npc/AbstractNPC.java @@ -0,0 +1,88 @@ +package core.game.node.entity.npc; + +import core.tools.Log; +import core.tools.SystemLogger; +import core.game.world.map.Location; +import core.plugin.Plugin; + +import java.util.HashMap; +import java.util.Map; + +import static core.api.ContentAPIKt.log; + +/** + * Used as superclass for "special NPC" plugins. + * @author Emperor + */ +public abstract class AbstractNPC extends NPC implements Plugin { + + /** + * The abstract NPC mapping. + */ + protected static Map mapping = new HashMap<>(); + + /** + * Constructs a new {@code AbstractNPC} {@Code Object}. + * @param id The id. + * @param location The location. + */ + public AbstractNPC(int id, Location location) { + this(id, location, true); + } + + /** + * Constructs a new {@code AbstractNPC} {@Code Object}. + * @param id The id. + * @param location The location. + * @param autowalk If the NPC should move around. + */ + public AbstractNPC(int id, Location location, boolean autowalk) { + super(id, location); + super.setWalks(autowalk); + } + + @Override + public Plugin newInstance(Object arg) throws Throwable { + for (int id : getIds()) { + if (mapping.containsKey(id)) { + String name = mapping.get(id).getClass().getSimpleName(); + if (name != getClass().getSimpleName()) { + log(this.getClass(), Log.ERR, "[" + getClass().getSimpleName() + "] - Warning: Mapping already contained NPC id " + id + "! (" + name + ")"); + continue; + } + } + mapping.put(id, this); + } + return this; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + /** + * Constructs a new instance of this abstract NPC. + * @param id The npc id. + * @param location The location. + * @param objects TODO + * @return The abstract npc instance. + */ + public abstract AbstractNPC construct(int id, Location location, Object... objects); + + /** + * Gets the NPC ids using this abstract NPC handler. + * @return The NPC ids. + */ + public abstract int[] getIds(); + + /** + * Gets the abstract NPC object for this NPC id. + * @param npcId The NPC id. + * @return The abstract NPC "loader" object for the given NPC id. + */ + public static AbstractNPC forId(int npcId) { + return mapping.get(npcId); + } + +} diff --git a/Server/src/main/core/game/node/entity/npc/IdleAbstractNPC.java b/Server/src/main/core/game/node/entity/npc/IdleAbstractNPC.java new file mode 100644 index 0000000..a2047b8 --- /dev/null +++ b/Server/src/main/core/game/node/entity/npc/IdleAbstractNPC.java @@ -0,0 +1,141 @@ +package core.game.node.entity.npc; + +import core.game.node.entity.skill.Skills; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.DeathTask; +import core.game.node.entity.combat.InteractionType; +import core.game.node.entity.player.Player; +import core.game.world.map.Location; + +/** + * Handles NPCs that are idle on default but can be disturbed (rock crabs, kraken, ...) + * @author Emperor + * + */ +public abstract class IdleAbstractNPC extends AbstractNPC { + + /** + * The active NPC id. + */ + private int activeId; + + /** + * If the NPC is currently idle. + */ + private boolean idle = true; + + /** + * The timeout ticks. + */ + protected int timeout = 30; //18 second time out to go idle again + + /** + * Constructs a new {@code IdleAbstractNPC} {@code Object}. + * @param idleId The NPC id. + * @param location The location. + */ + public IdleAbstractNPC(int idleId, int activeId, Location location) { + super(idleId, location); + this.activeId = activeId; + } + + @Override + public void handleTickActions() { + super.handleTickActions(); + if (!idle && !getProperties().getCombatPulse().isAttacking()) { + long time = getAttribute("combat-time", 0l); + if ((System.currentTimeMillis() - time) > (timeout * 600)) { + goIdle(); + } + } + } + + @Override + public void init() { + super.init(); + } + + @Override + public boolean isAttackable(Entity entity, CombatStyle style, boolean message) { + if (isInvisible()) { + return false; + } + if (getTask() != null && entity instanceof Player && getTask().levelReq > entity.getSkills().getLevel(Skills.SLAYER)) { + if(message) { + ((Player) entity).getPacketDispatch().sendMessage("You need a higher slayer level to know how to wound this monster."); + } + } + if (DeathTask.isDead(this)) { + return false; + } + if (!entity.getZoneMonitor().continueAttack(this, style, message)) { + return false; + } + return true; + } + + /** + * Checks if the entity is in range for disturbing this NPC. + * @param disturber The entity. + * @return {@code True} if so. + */ + public boolean inDisturbingRange(Entity disturber) { + if (idle && disturber.getSwingHandler(false).canSwing(disturber, this) != InteractionType.NO_INTERACT) { + return true; + } + return false; + } + + /** + * Checks if the entity can currently disturb this NPC (and returns {@code true}), or returns {@code false}. + * @param disturber The disturber. + * @return {@code True} if the entity could disturb this NPC. + */ + public boolean canDisturb(Entity disturber) { + return idle; + } + + /** + * Disturbs the NPC so it becomes active. + * @param disturber The entity disturbing this NPC. + */ + public void disturb(Entity disturber) { + if (disturber != null) { + disturber.getProperties().getCombatPulse().setCombatFlags(this); + } else { + setAttribute("combat-time", System.currentTimeMillis() + 10000); + } + getProperties().getCombatPulse().attack(disturber); + transform(activeId); + idle = false; + } + + /** + * Makes the NPC go idle again. + */ + public void goIdle() { + if (idle) { + return; + } + idle = true; + reTransform(); + } + + /** + * Gets the idle value. + * @return The idle. + */ + public boolean isIdle() { + return idle; + } + + /** + * Sets the idle value. + * @param idle The idle to set. + */ + public void setIdle(boolean idle) { + this.idle = idle; + } + +} diff --git a/Server/src/main/core/game/node/entity/npc/NPC.java b/Server/src/main/core/game/node/entity/npc/NPC.java new file mode 100644 index 0000000..b1d4aba --- /dev/null +++ b/Server/src/main/core/game/node/entity/npc/NPC.java @@ -0,0 +1,1025 @@ +package core.game.node.entity.npc; + +import core.game.event.NPCKillEvent; +import core.cache.def.impl.NPCDefinition; +import core.game.dialogue.DialoguePlugin; +import core.game.interaction.InteractPlugin; +import core.game.interaction.MovementPulse; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.spell.CombatSpell; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.spell.DefaultCombatSpell; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.npc.agg.AggressiveBehavior; +import core.game.node.entity.npc.agg.AggressiveHandler; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.SpellBookManager; +import core.game.node.entity.player.link.audio.Audio; +import core.game.node.entity.skill.Skills; +import content.global.skill.slayer.Tasks; +import content.global.skill.summoning.familiar.Familiar; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.map.build.DynamicRegion; +import core.game.world.map.path.Pathfinder; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.game.world.update.flag.*; +import core.tools.RandomFunction; +import core.api.utils.PlayerStatsCounter; +import core.api.utils.Vector; +import core.game.shops.Shops; +import core.game.node.entity.combat.CombatSwingHandler; +import core.game.system.config.NPCConfigParser; +import core.game.world.GameWorld; +import core.game.world.repository.Repository; + +import static core.game.system.command.sets.StatAttributeKeysKt.STATS_BASE; +import static core.game.system.command.sets.StatAttributeKeysKt.STATS_ENEMIES_KILLED; + +/** + * Represents a non-player character. + * @author Emperor + */ +public class NPC extends Entity { + + /** + * The non-player character's id. + */ + private int id; + + /** + * The original NPC id. + */ + private final int originalId; + + /** + * The NPC definitions. + */ + private NPCDefinition definition; + + /** + * If the NPC walks; + */ + private boolean walks; + + /** + * If the NPC is aggressive. + */ + private boolean aggressive; + + /** + * Represents if the NPC will respawn. + */ + private boolean respawn = true; + + /** + * The movement path of the NPC. + */ + protected Location[] movementPath; + + /** + * The walking radius. + */ + protected int walkRadius = 11; + + /** + * The movement index. + */ + protected int movementIndex; + + /** + * The respawn tick. + */ + private int respawnTick = -1; + + /** + * If the NPC walks bound to a path. + */ + protected boolean pathBoundMovement; + + /** + * The current dialogue. + */ + protected Player dialoguePlayer; + + /** + * The aggressive handler of the NPC. + */ + protected AggressiveHandler aggressiveHandler; + + /** + * The walk back radius. + */ + protected int nextWalk; + + /** + * The children NPCs. + */ + private NPC[] children; + + /** + * The amount of slayer experience received when killing this NPC. + */ + private double slayerExperience; + + /** + * The slayer task. + */ + private Tasks task; + + /** + * If the npc can never walk. + */ + private boolean neverWalks; + + /** + * The force talk string. + */ + private String forceTalk; + + public NPCBehavior behavior; + + public boolean isRespawning = false; + + /** + * Constructs a new {@code NPC} {@code Object}. + * @param id The NPC id. + */ + public NPC(int id) { + this(id, null); + } + + /** + * Constructs a new {@code NPC} {@code Object}. + * @param id The NPC id. + * @param location The location. + */ + protected NPC(int id, Location location, Direction direction) { + super(NPCDefinition.forId(id).getName(), location); + this.id = id; + this.originalId = id; + this.definition = NPCDefinition.forId(id); + super.size = definition.size; + super.direction = direction; + super.interactPlugin = new InteractPlugin(this); + this.behavior = NPCBehavior.forId(id); + } + + /** + * Constructs a new {@code NPC} {@code Object}. + * @param id the id. + * @param location the location. + */ + public NPC(int id, Location location) { + this(id, location, Direction.SOUTH); + } + + /** + * Creates a new NPC object. + * @param id The NPC id. + * @param location The location. + * @param direction the dir. + * @param objects the objects. + * @return The NPC object. + */ + public static NPC create(int id, Location location, Direction direction, Object... objects) { + NPC n = AbstractNPC.forId(id); + + if (n != null) { + n = ((AbstractNPC) n).construct(id, location, objects); + } + if (n == null) { + n = new NPC(id, location, direction); + } + return n; + } + + /** + * Creates a new NPC object. + * @param id the id. + * @param location the location. + * @return the npc object. + */ + public static NPC create(int id, Location location, Object... objects) { + return create(id, location, Direction.SOUTH, objects); + } + + @Override + public void init() { + super.init(); + getProperties().setSpawnLocation(getLocation()); + initConfig(); + Repository.getNpcs().add(this); + RegionManager.move(this); + if (getViewport().getRegion().isActive()) { + Repository.addRenderableNPC(this); + } + interactPlugin.setDefault(); + configure(); + setDefaultBehavior(); + if (definition.childNPCIds != null) { + children = new NPC[definition.childNPCIds.length]; + for (int i = 0; i < children.length; i++) { + NPC npc = children[i] = new NPC(definition.childNPCIds[i]); + npc.interactPlugin.setDefault(); + npc.index = index; + npc.size = size; + } + } + behavior.onCreation(this); + // FIXME: hack around MovementPulse's constructor getting run while behavior is null when behavior is set between NPC constructor and init. + // FIXME: Commented out as a fix. most npcs were not being able to attack with range/magic due to setting the combat pulse. + // getProperties().setCombatPulse(new CombatPulse(this)); + } + + @Override + public void clear() { + super.clear(); + Repository.removeRenderableNPC(this); + Repository.getNpcs().remove(this); + getViewport().setCurrentPlane(null); + behavior.onRemoval(this); + // getViewport().setRegion(null); + } + + /** + * Configures default boss data. + */ + public void configureBossData() { + getProperties().setNPCWalkable(true); + getProperties().setCombatTimeOut(2); + if (!isAggressive()) { + setAggressive(true); + setDefaultBehavior(); + } + if (getAggressiveHandler() != null) { + getAggressiveHandler().setChanceRatio(6); + getAggressiveHandler().setAllowTolerance(false); + getAggressiveHandler().setTargetSwitching(true); + getAggressiveHandler().setRadius(64); + } + walkRadius = 64; + } + + /** + * Initializes the configurations. + */ + public void initConfig() { + int defaultLevel = definition.getCombatLevel() / 2; + getProperties().setCombatLevel(definition.getCombatLevel()); + getSkills().setStaticLevel(Skills.ATTACK, definition.getConfiguration(NPCConfigParser.ATTACK_LEVEL, defaultLevel)); + getSkills().setStaticLevel(Skills.STRENGTH, definition.getConfiguration(NPCConfigParser.STRENGTH_LEVEL, defaultLevel)); + getSkills().setStaticLevel(Skills.DEFENCE, definition.getConfiguration(NPCConfigParser.DEFENCE_LEVEL, defaultLevel)); + getSkills().setStaticLevel(Skills.RANGE, definition.getConfiguration(NPCConfigParser.RANGE_LEVEL, defaultLevel)); + getSkills().setStaticLevel(Skills.MAGIC, definition.getConfiguration(NPCConfigParser.MAGIC_LEVEL, defaultLevel)); + getSkills().setStaticLevel(Skills.HITPOINTS, definition.getConfiguration(NPCConfigParser.LIFEPOINTS, defaultLevel)); + int lp = getSkills().getMaximumLifepoints(); + if (this instanceof Familiar) { + lp = getAttribute("hp", lp); + } + getSkills().setLevel(Skills.HITPOINTS, lp); + aggressive = definition.getConfiguration(NPCConfigParser.AGGRESSIVE, aggressive); + Animation anim = null; + for (int i = 0; i < 3; i++) { + if (definition.getCombatAnimation(i) != null) { + getProperties().setAttackAnimation(anim = definition.getCombatAnimation(i)); + break; + } + } + if (definition.getCombatAnimation(3) != null) { + getProperties().setDefenceAnimation(definition.getCombatAnimation(3)); + } + if (definition.getCombatAnimation(4) != null) { + getProperties().setDeathAnimation(definition.getCombatAnimation(4)); + } + if (definition.getCombatAnimation(1) != null) { + getProperties().setMagicAnimation(definition.getCombatAnimation(1)); + } + if (definition.getCombatAnimation(2) != null) { + getProperties().setRangeAnimation(definition.getCombatAnimation(2)); + } + if (getProperties().getAttackAnimation() == null && anim != null) { + getProperties().setAttackAnimation(anim); + } + if (getProperties().getMagicAnimation() == null && anim != null) { + getProperties().setMagicAnimation(anim); + } + if (getProperties().getRangeAnimation() == null && anim != null) { + getProperties().setRangeAnimation(anim); + } + definition.initCombatGraphics(definition.getHandlers()); + getProperties().setBonuses(definition.getConfiguration(NPCConfigParser.BONUSES, new int[15])); + getProperties().setAttackSpeed(definition.getConfiguration(NPCConfigParser.ATTACK_SPEED, 5)); + forceTalk = definition.getConfiguration("force_talk", null); + if (definition.getConfiguration("movement_radius") != null) { + this.setWalkRadius(definition.getConfiguration("movement_radius")); + } + if(definition.getConfiguration("death_gfx") != null) { + getProperties().deathGfx = new Graphics(definition.getConfiguration("death_gfx")); + } + } + + /** + * Opens the shop for a player. + * @param player the player. + * @return {@code True} if so. + */ + public boolean openShop(Player player) { + if (getName().contains("assistant")) { + NPC n = RegionManager.getNpc(this, getId() - 1); + if (n != null) { + return n.openShop(player); + } + } + + if (Shops.getShopsByNpc().get(id) == null) { + return false; + } + Shops.getShopsByNpc().get(id).openFor(player); + + //Fix for issue #11 for shops keeping dialogue open. + DialoguePlugin dialogue = player.getDialogueInterpreter().getDialogue(); + if (dialogue != null) + dialogue.end(); + return true; + } + + @Override + public boolean isInvisible() { + if (!isActive() || getRespawnTick() > GameWorld.getTicks()) { + return true; + } + return super.isInvisible(); + } + + /** + * Checks if the NPC is hidden for the player. + * @param player The player. + * @return {@code True} if so. + */ + public boolean isHidden(Player player) { + return isInvisible(); + } + + /** + * Sets the default aggressive behavior of the NPC. + */ + public void setDefaultBehavior() { + if (aggressive && definition.getCombatLevel() > 0) { + aggressiveHandler = new AggressiveHandler(this, AggressiveBehavior.DEFAULT); + aggressiveHandler.setRadius(definition.getConfiguration(NPCConfigParser.AGGRESSIVE_RADIUS, 4)); + } + } + + /** + * Configures the movement path. + * @param movementPath The movement path. + */ + public void configureMovementPath(Location... movementPath) { + this.movementPath = movementPath; + this.movementIndex = 0; + this.pathBoundMovement = true; + } + + @Override + public void checkImpact(BattleState state) { + super.checkImpact(state); + Entity entity = state.getAttacker(); + behavior.beforeDamageReceived(this, entity, state); + if (task != null && entity instanceof Player && task.levelReq > entity.getSkills().getLevel(Skills.SLAYER)) { + state.neutralizeHits(); + } + } + + @Override + public boolean isAttackable(Entity entity, CombatStyle style, boolean message) { + if (isInvisible()) { + return false; + } + if (task != null && entity instanceof Player && task.levelReq > entity.getSkills().getLevel(Skills.SLAYER)) { + if(message) { + ((Player) entity).getPacketDispatch().sendMessage("You need a higher slayer level to know how to wound this monster."); + } + } + if (!behavior.canBeAttackedBy(this, entity, style, message)) + return false; + return super.isAttackable(entity, style, message); + } + + @Override + public int getDragonfireProtection(boolean fire) { + return 0; + } + + @Override + public void tick() { + if (!getViewport().getRegion().isActive()) { + onRegionInactivity(); + return; + } + if (respawnTick > GameWorld.getTicks()) { + if (respawnTick - GameWorld.getTicks() == 2) + teleport(getProperties().getSpawnLocation()); + return; + } + if (isRespawning && respawnTick <= GameWorld.getTicks()) { + behavior.onRespawn(this); + onRespawn(); + fullRestore(); + isRespawning = false; + } + handleTickActions(); + super.tick(); + } + + /** + * Called when the NPC respawns. + */ + protected void onRespawn() {} + + /** + * Handles the automatic actions of the NPC. + */ + public void handleTickActions() { + if (!behavior.tick(this)) + return; + if (!getLocks().isInteractionLocked()) { + if (!getLocks().isMovementLocked()) { + if ( + !pathBoundMovement + && walkRadius > 0 + && walkRadius <= 20 + && !getLocation().withinDistance(getProperties().getSpawnLocation(), (int)(walkRadius * 1.5)) + && !getAttribute("no-spawn-return", false) + ) + { + MovementPulse current = getAttribute("return-to-spawn-pulse"); + if (current != null && current.isRunning()) return; + + if(!isNeverWalks()){ + if(walkRadius == 0) + walkRadius = 3; + } + if (aggressiveHandler != null) { + aggressiveHandler.setPauseTicks(walkRadius + 1); + } + nextWalk = GameWorld.getTicks() + walkRadius + 1; + getLocks().lockMovement(100); + getImpactHandler().setDisabledTicks(100); + setAttribute("return-to-spawn", true); + + MovementPulse returnPulse = new MovementPulse(this, getProperties().getSpawnLocation(), Pathfinder.SMART) { + @Override + public boolean pulse() { + getProperties().getCombatPulse().stop(); + getLocks().unlockMovement(); + fullRestore(); + getImpactHandler().setDisabledTicks(0); + removeAttribute("return-to-spawn"); + removeAttribute("return-to-spawn-pulse"); + return true; + } + }; + + setAttribute("return-to-spawn-pulse", returnPulse); + GameWorld.getPulser().submit(returnPulse); + return; + } + if (dialoguePlayer == null || !dialoguePlayer.isActive() || !dialoguePlayer.getInterfaceManager().hasChatbox()) { + dialoguePlayer = null; + if (walks && !getPulseManager().hasPulseRunning() && !getProperties().getCombatPulse().isAttacking() && !getProperties().getCombatPulse().isInCombat() && nextWalk < GameWorld.getTicks()) { + if (walkToNextDest()) return; + } + } + } + if (aggressive && aggressiveHandler != null && aggressiveHandler.selectTarget()) { + return; + } + if (getProperties().getCombatPulse().isAttacking()) { + return; + } + } + if (forceTalk != null && getAttribute("lastForceTalk", 0) < GameWorld.getTicks()) { + sendChat(forceTalk); + setAttribute("lastForceTalk", GameWorld.getTicks() + RandomFunction.random(15, 30)); + } + } + + private boolean walkToNextDest() { + if (RandomFunction.nextBool()) return true; + setNextWalk(); + Location l = getMovementDestination(); + if (canMove(l)) { + if((Boolean) definition.getHandlers().getOrDefault("water_npc",false)){ + Pathfinder.findWater(this,l,true,Pathfinder.DUMB).walk(this); + } else { + Pathfinder.find(this, l, true, Pathfinder.DUMB).walk(this); + } + } + return false; + } + + public int getNextWalk() { + return nextWalk; + } + /** + * Sets the next walk. + */ + public void setNextWalk() { + nextWalk = GameWorld.getTicks() + 5 + RandomFunction.randomize(10); + } + + public void resetWalk() { + nextWalk = GameWorld.getTicks() - 1; + getWalkingQueue().reset(); + } + + /** + * Called when the region goes inactive. + */ + public void onRegionInactivity() { + getWalkingQueue().reset(); + getPulseManager().clear(); + getUpdateMasks().reset(); + if (getAttribute("return-to-spawn", false)) { + this.location = getProperties().getSpawnLocation(); + MovementPulse returnPulse = getAttribute("return-to-spawn-pulse"); + if (returnPulse != null) { + returnPulse.pulse(); + returnPulse.stop(); + } + } + Repository.removeRenderableNPC(this); + if (getViewport().getRegion() instanceof DynamicRegion) { + clear(); + } + } + + @Override + public boolean isPoisonImmune() { + return definition.getConfiguration(NPCConfigParser.POISON_IMMUNE, false); + } + + @Override + public void finalizeDeath(Entity killer) { + super.finalizeDeath(killer); + if (getZoneMonitor().handleDeath(killer)) { + return; + } + Player p = !(killer instanceof Player) ? null : (Player) killer; + if (p != null) { + p.incrementAttribute("/save:" + STATS_BASE + ":" + STATS_ENEMIES_KILLED); + PlayerStatsCounter.incrementKills(p, originalId); + } + handleDrops(p, killer); + if (!isRespawn()) + clear(); + isRespawning = true; + behavior.onDeathFinished(this, killer); + killer.dispatch(new NPCKillEvent(this)); + setRespawnTick(GameWorld.getTicks() + definition.getConfiguration(NPCConfigParser.RESPAWN_DELAY, 17)); + } + + public void setRespawnTicks (int ticks) { + definition.getHandlers().put(NPCConfigParser.RESPAWN_DELAY, ticks); + } + + @Override + public void commenceDeath(Entity killer) { + behavior.onDeathStarted(this, killer); + } + + /** + * Handles the drops of the npc. + * @param p the p. + * @param killer the killer. + */ + public void handleDrops(Player p, Entity killer) { + if (getAttribute("disable:drop", false)) { + return; + } + if (killer instanceof Player && p != null && p.getIronmanManager().isIronman() && getImpactHandler().getPlayerImpactLog().size() > 1) { + return; + } + if (definition == null || definition.getDropTables() == null) { + return; + } + definition.getDropTables().drop(this, killer); + } + + @Override + public void update() { + super.update(); + } + + @Override + public void reset() { + super.reset(); + } + + @Override + public CombatSwingHandler getSwingHandler(boolean swing) { + CombatSwingHandler original = getProperties().getCombatPulse().getStyle().getSwingHandler(); + return behavior.getSwingHandlerOverride(this, original); + } + + /** + * Gets an audio piece. + * @param index the index. + * @return the audio. + */ + public Audio getAudio(int index) { + int[] audios = getDefinition().getConfiguration(NPCConfigParser.COMBAT_AUDIO, null); + if (audios != null) { + Audio audio = new Audio(audios[index]); + if (audio != null && audio.id != 0) { + return audio; + } + } + return null; + } + + /** + * Configures the NPC.
Override this instead of {@link #init()} when + * creating a sub class. + */ + public void configure() { + int[] bonus = definition.getConfiguration(NPCConfigParser.BONUSES, new int[3]); + int highest = 0; + int index = 0; + for (int i = 0; i < 3; i++) { + if (bonus[i] > highest) { + highest = bonus[i]; + index = i; + } + } + CombatStyle protectStyle = definition.getConfiguration(NPCConfigParser.PROTECT_STYLE, null); + if (protectStyle != null) { + getProperties().setProtectStyle(protectStyle); + } + getProperties().setAttackStyle(new WeaponInterface.AttackStyle(WeaponInterface.STYLE_CONTROLLED, index)); + CombatStyle style = getDefinition().getConfiguration(NPCConfigParser.COMBAT_STYLE); + if (style != null) { + getProperties().getCombatPulse().setStyle(style); + } + if (style == CombatStyle.MAGIC) { + getProperties().setAutocastSpell(new DefaultCombatSpell(this)); + int spell = definition.getConfiguration("spell_id", -1); + if (spell != -1) { + getProperties().setSpell((CombatSpell) SpellBookManager.SpellBook.MODERN.getSpell(spell)); + getProperties().setAutocastSpell((CombatSpell) SpellBookManager.SpellBook.MODERN.getSpell(spell)); + } + } + task = Tasks.forId(getId()); + } + + /** + * Method used to check if the NPC can attack the victim. This method is + * used for aggressive behavior. + * @return True if so. + */ + public boolean canAttack(final Entity victim) { + return true; + } + + @Override + public boolean hasProtectionPrayer(CombatStyle style) { + return getProperties().getProtectStyle() == style; + } + + /** + * Checks if the npc should ignore victim attack restrictions(i.e You can't + * attack this npc.") + * @param victim the victim. + * @return {@code True} if ignore. + */ + public boolean isIgnoreAttackRestrictions(Entity victim) { + return false; + } + + @Override + public String toString() { + return "NPC " + id + ", " + getLocation() + ", " + getIndex(); + } + + /** + * Transforms this NPC. + * @param id The new NPC id. + */ + public NPC transform(int id) { + this.id = id; + this.definition = NPCDefinition.forId(id); + super.name = definition.getName(); + super.size = definition.size; + super.interactPlugin = new InteractPlugin(this); + initConfig(); + configure(); + interactPlugin.setDefault(); + if (id == originalId) { + int ordinal = EntityFlags.getOrdinal (EFlagType.NPC, EntityFlag.TypeSwap); + getUpdateMasks().unregisterSynced(ordinal); + } + getUpdateMasks().register(EntityFlag.TypeSwap, id, id != originalId); + return this; + } + + /** + * Transforms this NPC back to original. + */ + public void reTransform() { + if (originalId == this.id) { + return; + } + transform(originalId); + } + + /** + * Gets the movement destination of the NPC. + * @return The movement destination. + */ + protected Location getMovementDestination() { + if (!pathBoundMovement || movementPath == null || movementPath.length < 1) { + Location returnToSpawnLocation = getProperties().getSpawnLocation().transform(-5 + RandomFunction.random(getWalkRadius()), -5 + RandomFunction.random(getWalkRadius()), 0); + int dist = (int) Location.getDistance(location, returnToSpawnLocation); + int pathLimit = 14; + if (dist > pathLimit) { + Vector normalizedDir = Vector.betweenLocs(this.location, returnToSpawnLocation).normalized(); + returnToSpawnLocation = this.location.transform (normalizedDir.times(pathLimit)); + } + return returnToSpawnLocation; + } + Location l = movementPath[movementIndex++]; + if (movementIndex == movementPath.length) { + movementIndex = 0; + } + return l; + } + + /** + * Gets the drop location. + * @return The drop location. + */ + public Location getDropLocation() { + return getLocation(); + } + + /** + * Checks if the npc can start combat. + * @param victim the victim. + * @return {@code True} if so. + */ + public boolean canStartCombat(Entity victim) { + return true; + } + + /** + * Gets the definition. + * @return The definition. + */ + public NPCDefinition getDefinition() { + return definition; + } + + /** + * Sets the definition. + * @param definition The definition to set. + */ + public void setDefinition(NPCDefinition definition) { + this.definition = definition; + } + + /** + * Get the id. + * @return The non-player character's id. + */ + public int getId() { + return id; + } + + /** + * Set the id. + * @param id The non-player character's id. + */ + public void setId(int id) { + this.id = id; + } + + /** + * Gets the walks. + * @return The walks. + */ + public boolean isWalks() { + return walks; + } + + /** + * Sets the walks. + * @param walks The walks to set. + */ + public void setWalks(boolean walks) { + this.walks = walks; + } + + /** + * Gets the aggressive. + * @return The aggressive. + */ + public boolean isAggressive() { + return aggressive; + } + + /** + * Sets the aggressive. + * @param aggressive The aggressive to set. + */ + public void setAggressive(boolean aggressive) { + this.aggressive = aggressive; + } + + /** + * Sets the name. + * @param @name + */ + public void setName(String name) { + this.name = name; + } + + /** + * Gets the movementPath. + * @return The movementPath. + */ + public Location[] getMovementPath() { + return movementPath; + } + + /** + * @return the respawn. + */ + public boolean isRespawn() { + return respawn; + } + + /** + * @param respawn the respawn to set. + */ + public void setRespawn(boolean respawn) { + this.respawn = respawn; + } + + /** + * Gets the pathBoundMovement. + * @return The pathBoundMovement. + */ + public boolean isPathBoundMovement() { + return pathBoundMovement; + } + + /** + * Sets the pathBoundMovement. + * @param pathBoundMovement The pathBoundMovement. + */ + public void setPathBoundMovement(boolean pathBoundMovement) { + this.pathBoundMovement = pathBoundMovement; + } + + /** + * Gets the dialoguePlayer. + * @return The dialoguePlayer. + */ + public Player getDialoguePlayer() { + return dialoguePlayer; + } + + /** + * Sets the dialoguePlayer. + */ + public void setDialoguePlayer(Player dialoguePlayer) { + this.dialoguePlayer = dialoguePlayer; + } + + /** + * Gets the aggressive handler. + * @return The aggressive handler. + */ + public AggressiveHandler getAggressiveHandler() { + return aggressiveHandler; + } + + /** + * Sets the aggressive handler. + * @param handler The handler. + */ + public void setAggressiveHandler(AggressiveHandler handler) { + this.aggressiveHandler = handler; + } + + /** + * Gets the respawnTick. + * @return The respawnTick. + */ + public int getRespawnTick() { + return respawnTick; + } + + /** + * Sets the walking radius. + * @param radius The walking radius. + */ + public void setWalkRadius(int radius) { + this.walkRadius = radius; + } + + /** + * Gets the walking radius. + * @return the walking radius. + */ + public int getWalkRadius() { + return walkRadius; + } + + /** + * Sets the respawnTick. + * @param respawnTick The respawnTick to set. + */ + public void setRespawnTick(int respawnTick) { + this.respawnTick = respawnTick; + } + + /** + * Gets the originalId. + * @return The originalId. + */ + public int getOriginalId() { + return originalId; + } + + /** + * Gets the currently shown NPC. + * @param player The player to check for. + * @return The shown NPC. + */ + public NPC getShownNPC(Player player) { + if (children == null) { + return this; + } + int npcId = definition.getChildNPC(player).getId(); + for (NPC npc : children) { + if (npc.getId() == npcId) { + return npc; + } + } + return this; + } + + /** + * Gets the slayerExperience. + * @return The slayerExperience. + */ + public double getSlayerExperience() { + return slayerExperience; + } + + /** + * Sets the slayerExperience. + * @param slayerExperience The slayerExperience to set. + */ + public void setSlayerExperience(double slayerExperience) { + this.slayerExperience = slayerExperience; + } + + /** + * Gets the task. + * @return The task. + */ + public Tasks getTask() { + return task; + } + + /** + * Sets the task. + * @param task The task to set. + */ + public void setTask(Tasks task) { + this.task = task; + } + + /** + * Gets the neverWalks. + * @return the neverWalks + */ + public boolean isNeverWalks() { + return neverWalks; + } + + /** + * Sets the baneverWalks. + * @param neverWalks the neverWalks to set. + */ + public void setNeverWalks(boolean neverWalks) { + this.neverWalks = neverWalks; + } + +} diff --git a/Server/src/main/core/game/node/entity/npc/NPCBehavior.kt b/Server/src/main/core/game/node/entity/npc/NPCBehavior.kt new file mode 100644 index 0000000..55f9b99 --- /dev/null +++ b/Server/src/main/core/game/node/entity/npc/NPCBehavior.kt @@ -0,0 +1,161 @@ +package core.game.node.entity.npc + +import core.game.node.item.Item +import core.api.ContentInterface +import core.game.node.entity.Entity +import core.game.world.map.RegionManager +import core.game.node.entity.player.Player +import core.game.node.entity.combat.BattleState +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.combat.CombatSwingHandler +import core.game.world.map.path.ClipMaskSupplier +import core.game.world.map.path.Pathfinder + +open class NPCBehavior(vararg val ids: Int = intArrayOf()) : ContentInterface { + companion object { + private val idMap = HashMap() + private val defaultBehavior = NPCBehavior() + + @JvmStatic fun forId(id: Int) : NPCBehavior { + return idMap[id] ?: defaultBehavior + } + fun register(ids: IntArray, behavior: NPCBehavior){ + ids.forEach { idMap[it] = behavior } + } + } + + object StandardClipMaskSupplier : ClipMaskSupplier { + override fun getClippingFlag (z: Int, x: Int, y: Int) : Int { + return RegionManager.getClippingFlag(z,x,y) + } + } + + /** + * Called every tick, before the base NPC tick() method. + * @param self the NPC instance this behavior belongs to + * @return whether we should proceed with the base NPC tick() method - e.g. returning false means we do not proceed with a normal NPC tick. + */ + open fun tick(self: NPC): Boolean { + return true + } + + /** + * Called before this NPC receives damage, and allows you to adjust the battlestate if needed. + * @param self the NPC instance this behavior belongs to + * @param attacker the entity attacking this NPC + * @param state the current state of the combat between this NPC and the attacker. + */ + open fun beforeDamageReceived(self: NPC, attacker: Entity, state: BattleState) {} + + /** + * Called after this NPC receives damage, and allows you to adjust the battlestate if needed. + * @param self the NPC instance this behavior belongs to + * @param attacker the entity attacking this NPC + * @param state the current state of the combat between this NPC and the attacker. + */ + open fun afterDamageReceived(self: NPC, attacker: Entity, state: BattleState) {} + + /** + * Called after this NPC's basic attack has been calculated, but before it is finalized, so adjustments can be made. + * @param self the NPC instance this behavior belongs to + * @param victim the entity this NPC is attacking + * @param state the state of combat between this NPC and the victim. + */ + open fun beforeAttackFinalized(self: NPC, victim: Entity, state: BattleState) {} + + /** + * Called when this NPC is being removed from the game world. + * Note: This is not the same as death. Death does not remove an NPC, unless that NPC cannot respawn. + * @param self the NPC instance this behavior belongs to + */ + open fun onRemoval(self: NPC) {} + + /** + * Called when this NPC is first created and spawned into the game world. + * Note: This is not the same as respawning. + * @param self the NPC instance this behavior belongs to + */ + open fun onCreation(self: NPC) {} + + /** + * Called when this NPC respawns after being killed. + * @param self the NPC instance this behavior belongs to + */ + open fun onRespawn(self: NPC) {} + + /** + * Called immediately when the NPC first begins to die (on the same tick that the death animation begins) + * @param self the NPC instance this behavior belongs to + * @param killer the entity which killed this NPC. + */ + open fun onDeathStarted(self: NPC, killer: Entity) {} + + /** + * Called immediately after the death animation of this NPC has finished, on the same tick that drop tables are rolled. + * @param self the NPC instance this behavior belongs to + * @param killer the entity which killed this NPC. + */ + open fun onDeathFinished(self: NPC, killer: Entity) {} + + /** + * Called after this NPC's drop table is rolled, but before the items are actually dropped, so the list can be manipulated. + * @param self the NPC instance this behavior belongs to + * @param killer the killer of the npc + * @param drops the generated list of drops for this roll of the table + */ + open fun onDropTableRolled(self: NPC, killer: Entity, drops: ArrayList) {} + + /** + * Called by combat-related code to check if this NPC can be attacked by the `attacker` entity. + * @param self the NPC instance this behavior belongs to + * @param attacker the entity attempting to attack this NPC + * @param style the combat style the attacker is attempting to use + * @param shouldSendMessage whether the core combat code believes you should send a message e.g. "You can't attack this NPC with that weapon" + * @return whether the attacker should be able to attack this NPC. + */ + open fun canBeAttackedBy(self: NPC, attacker: Entity, style: CombatStyle, shouldSendMessage: Boolean) : Boolean { + if (attacker is Player && !self.definition.hasAction("attack")) + return false + return true + } + + /** + * Called by combat-related code to check if this NPC should ignore multi-combat rules when attempting to attack the given victim. + * @param self the NPC instance this behavior belongs to + * @param victim the entity that is being considered for attack. + * @return whether we should ignore the rules of multi-way combat for the given entity. + */ + open fun shouldIgnoreMultiRestrictions(self: NPC, victim: Entity) : Boolean {return false} + + /** + * Called by combat-related code to allow the combat handler to be overridden + * @param self the NPC instance this behavior belongs to + * @param original the default swing handler this NPC would have used + * @return the SwingHandler instance to be used for this cycle of combat + */ + open fun getSwingHandlerOverride(self: NPC, original: CombatSwingHandler) : CombatSwingHandler {return original} + + /** + * Called by MovementPulse to determine if a non-default Pathfinder should be used (e.g. whether this npc should intelligently walk around obstacles) + */ + open fun getPathfinderOverride(self: NPC): Pathfinder? { + return null + } + + /** + * Called by pathfinding code to determine the clipping mask supplier this NPC should use. You can use this to ignore water, etc. + */ + open fun getClippingSupplier(self: NPC) : ClipMaskSupplier? { + return StandardClipMaskSupplier + } + + /** + * Modifies the combat experience gained from killing an entity + * @param self the NPC instance this behavior belongs to + * @param attacker entity attacking the npc + * @return multiplier for final xp gain + */ + open fun getXpMultiplier(self: NPC, attacker: Entity) : Double { + return 1.0 + } +} diff --git a/Server/src/main/core/game/node/entity/npc/agg/AggressiveBehavior.java b/Server/src/main/core/game/node/entity/npc/agg/AggressiveBehavior.java new file mode 100644 index 0000000..50f93be --- /dev/null +++ b/Server/src/main/core/game/node/entity/npc/agg/AggressiveBehavior.java @@ -0,0 +1,145 @@ +package core.game.node.entity.npc.agg; + +import core.game.node.entity.Entity; +import core.game.node.entity.combat.DeathTask; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.world.map.zone.impl.WildernessZone; +import core.game.world.map.RegionManager; + +import java.util.ArrayList; +import java.util.List; + +/** + * Handles an NPC's aggressive behaviour. + * @author Emperor + */ +public class AggressiveBehavior { + + /** + * The default aggressive behavior. + */ + public static final AggressiveBehavior DEFAULT = new AggressiveBehavior(); + + /** + * The wilderness aggressive behavior. + */ + public static final AggressiveBehavior WILDERNESS = new AggressiveBehavior() { + + @Override + public boolean canSelectTarget(Entity entity, Entity target) { + if(target.isInvisible()){ + return false; + } + if (!target.isActive() || DeathTask.isDead(target)) { + return false; + } + if (!entity.canSelectTarget(target)) { + return false; + } + if (!target.getProperties().isMultiZone() && target.inCombat()) { + return false; + } + if (target instanceof Player) { + return ((Player) target).getSkullManager().isWilderness(); + } + return true; + } + }; + + /** + * Constructs a new {@code AggressiveBehaviour} {@code Object}. + */ + public AggressiveBehavior() { + /* + * empty. + */ + } + + /** + * Checks if the NPC is aggressive towards the entity. + * @param entity The timed entry. + * @return {@code True} if the NPC can select the entity as a target. + */ + public boolean canSelectTarget(Entity entity, Entity target) { + int regionId = target.getLocation().getRegionId(); + if (!target.isActive() || DeathTask.isDead(target)) { + return false; + } + if (!target.getProperties().isMultiZone() && target.inCombat()) { + return false; + } + if (entity instanceof NPC && target instanceof Player) { + NPC npc = (NPC) entity; + if (npc.getAggressiveHandler() != null && npc.getAggressiveHandler().isAllowTolerance() && !WildernessZone.isInZone(npc)) { + if (RegionManager.forId(regionId).isTolerated(target.asPlayer())) { + return false; + } + } + } + int level = target.getProperties().getCurrentCombatLevel(); + if (level > entity.getProperties().getCurrentCombatLevel() << 1 && !ignoreCombatLevelDifference()) { + return false; + } + return true; + } + + public boolean ignoreCombatLevelDifference() { + return false; + } + + /** + * Gets the priority flag. + * @param target The target. + * @return The priority flag. + */ + public int getPriorityFlag(Entity target) { + int flag = 0; + if (target.inCombat()) { + flag++; + } + if (target.getLocks().isInteractionLocked()) { + flag++; + } + Entity e = target.getAttribute("aggressor"); + if (e != null && e.getProperties().getCombatPulse().getVictim() == target) { + flag++; + } + return flag; + } + + /** + * Gets the list of possible targets. + * @param entity The entity. + * @param radius The aggressive radius. + * @return The list of possible targets. + */ + public List getPossibleTargets(Entity entity, int radius) { + List targets = new ArrayList<>(20); + for (Player player : RegionManager.getLocalPlayers(entity, radius)) { + if (canSelectTarget(entity, player)) { + targets.add(player); + } + } + return targets; + } + + /** + * Gets the most logical target from the targets list. + * @param entity The entity. + * @param possibleTargets The possible targets list. + * @return The target. + */ + public Entity getLogicalTarget(Entity entity, List possibleTargets) { + Entity target = null; + double comparingFlag = Double.MAX_VALUE; + for (Entity e : possibleTargets) { + double flag = (double)getPriorityFlag(e) + Math.random(); + if (flag <= comparingFlag) { + comparingFlag = flag; + target = e; + } + } + return target; + } +} diff --git a/Server/src/main/core/game/node/entity/npc/agg/AggressiveHandler.java b/Server/src/main/core/game/node/entity/npc/agg/AggressiveHandler.java new file mode 100644 index 0000000..c2a4984 --- /dev/null +++ b/Server/src/main/core/game/node/entity/npc/agg/AggressiveHandler.java @@ -0,0 +1,204 @@ +package core.game.node.entity.npc.agg; + +import core.game.node.entity.npc.NPC; +import core.ServerConstants; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.DeathTask; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.info.Rights; +import core.game.world.GameWorld; +import core.tools.RandomFunction; + +/** + * Used to handle entity aggressiveness. + * @author Emperor + */ +public final class AggressiveHandler { + + /** + * The entity. + */ + private final Entity entity; + + /** + * The radius. + */ + private int radius = 4; + + /** + * The amount of ticks to pause aggressiveness with. + */ + private int pauseTicks = 0; + + /** + * If target switching is enabled. + */ + private boolean targetSwitching; + + /** + * The aggressiveness behavior. + */ + private final AggressiveBehavior behavior; + + /** + * The aggressive chance ratio (1/10). + */ + private int chanceRatio = 2; + + /** + * The tolerance data. + */ + private final int[] playerTolerance = new int[ServerConstants.MAX_PLAYERS]; + + /** + * If tolerance is allowed. + */ + private boolean allowTolerance = true; + + /** + * Constructs a new {@code AggressiveHandler} {@code Object}. + * @param entity The entity. + * @param behavior The aggressive behavior. + */ + public AggressiveHandler(Entity entity, AggressiveBehavior behavior) { + this.entity = entity; + this.behavior = behavior; + } + + /** + * Selects a target. + * @return {@code True} if the entity has selected a target. + */ + public boolean selectTarget() { + if (pauseTicks > GameWorld.getTicks() || entity.getLocks().isInteractionLocked()) { + return false; + } + if ((!targetSwitching && entity.getProperties().getCombatPulse().isAttacking()) || DeathTask.isDead(entity)) { + return false; + } + if (RandomFunction.randomize(10) > chanceRatio) { + return false; + } + Entity target = behavior.getLogicalTarget(entity, behavior.getPossibleTargets(entity, radius)); + if (target instanceof Player) { + if (target.getAttribute("ignore_aggression", false)) { + return false; + } + if (((Player) target).getRights().equals(Rights.ADMINISTRATOR) && !target.getAttribute("allow_admin_aggression", false)) { + return false; + } + } + if (target != null) { + target.setAttribute("aggressor", entity); + if (entity.getProperties().getCombatPulse().isAttacking()) { + entity.getProperties().getCombatPulse().setVictim(target); + entity.face(target); + } else { + entity.getProperties().getCombatPulse().attack(target); + } + return true; + } + return entity.getProperties().getCombatPulse().isAttacking(); + } + + /** + * Removes the tolerance of a player. + * @param index The player index. + */ + public synchronized void removeTolerance(int index) { + playerTolerance[index] = 0; + } + + /** + * Gets the radius. + * @return The radius. + */ + public int getRadius() { + return radius; + } + + /** + * Sets the radius. + * @param radius The radius to set. + */ + public void setRadius(int radius) { + this.radius = radius; + } + + /** + * Gets the pauseTicks. + * @return The pauseTicks. + */ + public int getPauseTicks() { + return pauseTicks; + } + + /** + * Sets the pauseTicks. + * @param pauseTicks The amount of ticks to pause for. + */ + public void setPauseTicks(int pauseTicks) { + this.pauseTicks = GameWorld.getTicks() + pauseTicks; + } + + /** + * Gets the playerTolerance. + * @return The playerTolerance. + */ + public int[] getPlayerTolerance() { + return playerTolerance; + } + + /** + * Gets the targetSwitching. + * @return The targetSwitching. + */ + public boolean isTargetSwitching() { + return targetSwitching; + } + + /** + * Sets the targetSwitching. + * @param targetSwitching The targetSwitching to set. + */ + public void setTargetSwitching(boolean targetSwitching) { + this.targetSwitching = targetSwitching; + } + + /** + * Gets the chanceRatio. + * @return The chanceRatio. + */ + public int getChanceRatio() { + return chanceRatio; + } + + /** + * Sets the chanceRatio (a ratio of 0-10). + * @param chanceRatio The chanceRatio to set. + */ + public void setChanceRatio(int chanceRatio) { + this.chanceRatio = chanceRatio; + } + + /** + * Gets the allowTolerance. + * @return The allowTolerance. + */ + public boolean isAllowTolerance() { + boolean configSetting = true; + if(entity instanceof NPC){ + configSetting = ((NPC) entity).getDefinition().getConfiguration("can_tolerate", true); + } + return allowTolerance && configSetting; + } + + /** + * Sets the allowTolerance. + * @param allowTolerance The allowTolerance to set. + */ + public void setAllowTolerance(boolean allowTolerance) { + this.allowTolerance = allowTolerance; + } + +} diff --git a/Server/src/main/core/game/node/entity/npc/drop/DropFrequency.java b/Server/src/main/core/game/node/entity/npc/drop/DropFrequency.java new file mode 100644 index 0000000..fd3e6f9 --- /dev/null +++ b/Server/src/main/core/game/node/entity/npc/drop/DropFrequency.java @@ -0,0 +1,47 @@ +package core.game.node.entity.npc.drop; + +import java.util.Arrays; +import java.util.HashMap; + +/** + * Represents the different types of drop frequency. + * @author Emperor + */ +public enum DropFrequency { + + /** + * This gets dropped all the time. + */ + ALWAYS, + + /** + * This gets commonly dropped. + */ + COMMON, + + /** + * This drop is uncommon. + */ + UNCOMMON, + + /** + * This gets rarely dropped. + */ + RARE, + + /** + * This gets very rarely dropped. + */ + VERY_RARE; + + static int[] RATES = {1, 5, 15, 30, 60}; + final static HashMap rateMap = new HashMap<>(); + static{ + Arrays.stream(DropFrequency.values()).forEach(freq -> rateMap.putIfAbsent(freq,RATES[freq.ordinal()])); + } + + public static int rate(DropFrequency frequency){ + return rateMap.get(frequency); + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/npc/drop/NPCDropTables.java b/Server/src/main/core/game/node/entity/npc/drop/NPCDropTables.java new file mode 100644 index 0000000..baacc11 --- /dev/null +++ b/Server/src/main/core/game/node/entity/npc/drop/NPCDropTables.java @@ -0,0 +1,240 @@ +package core.game.node.entity.npc.drop; + +import static core.api.ContentAPIKt.*; + +import content.data.tables.*; +import core.cache.def.impl.NPCDefinition; +import content.global.skill.prayer.Bones; +import core.game.node.entity.Entity; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.skill.Skills; +import core.game.node.item.GroundItem; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.tools.RandomFunction; +import core.tools.StringUtils; +import core.game.bots.AIPlayer; +import core.game.bots.AIRepository; +import core.game.bots.GeneralBotCreator; +import core.api.utils.NPCDropTable; +import core.game.ge.GrandExchange; +import core.game.world.repository.Repository; + +import java.util.ArrayList; +import java.util.List; + +/** + * Holds and handles the NPC drop tables. + * @author Emperor + */ +public final class NPCDropTables { + + /** + * The drop rates (0=common, 1=uncommon, 2=rare, 3=very rare). + */ + public static final int[] DROP_RATES = { 750, 150, 15, 5 }; + + /** + * The npcs that will display drop messages + */ + public static final int[] MESSAGE_NPCS = { 50, 7133, 7134, 2881, 2882, 2883, 3200, 3340, 6247, 6203, 6260, 6222, 2745, 1160, 8133, 8610, 8611, 8612, 8613, 8614, 6204, 6206, 6208, 6261, 6263, 6265, 6223, 6225, 6227 }; + + public NPCDropTable table = new NPCDropTable(); + + /** + * The NPC definitions. + */ + private final NPCDefinition def; + + /** + * The main drop table size. + */ + private int mainTableSize; + + /** + * The mod rate used with this table. + */ + private double modRate; + + /** + * Constructs a new {@code NPCDropTables} {@code Object}. + * @param def The NPC definitions. + */ + public NPCDropTables(NPCDefinition def) { + this.def = def; + } + + /** + * Handles the dropping. + * @param npc The NPC dropping the loot. + * @param looter The entity gaining the loot. + */ + public void drop(NPC npc, Entity looter) { + Player p = looter instanceof Player ? (Player) looter : null; + ArrayList drops = table.roll(looter, 1); + npc.behavior.onDropTableRolled(npc, looter, drops); + drops.forEach(item -> createDrop(item,p,npc,npc.getDropLocation())); + } + + public List roll (NPC npc, Entity looter, int times) { + ArrayList drops = table.roll(looter, times); + npc.behavior.onDropTableRolled(npc, looter, drops); + return drops; + } + + /** + * Creates a dropped item. + * @param item The item to drop. + * @param player The player getting the loot (or null). + * @param npc the npc. + * @param l The location of the NPC dropping the loot. + */ + public void createDrop(Item item, Player player, NPC npc, Location l) { + if (item == null || item.getId() == 0 || l == null || item.getName().equals("null") || player == null) { + return; + } + if (handleBoneCrusher(player, item)) { + return; + } + if (item.hasItemPlugin() && player != null) { + if (!item.getPlugin().createDrop(item, player, npc, l)) { + return; + } + item = item.getPlugin().getItem(item, npc); + } + if (!item.getDefinition().isStackable() && item.getAmount() > 1) { + for (int i = 0; i < item.getAmount(); i++) { + GroundItemManager.create(new Item(item.getId()), l, player); + } + return; + } + announceIfRare(player, item); + if(item.getId() == 6199 && player instanceof Player){ + player.sendMessage("A mystery box has fallen on the ground."); + } + sendDropMessage(player, npc.getId(), item); + if (player == null) { + if (item != null) { + GroundItemManager.create(item, l); + } + } else { + GroundItem groundItem = GroundItemManager.create(item, l, getLooter(player, npc, item)); + if(player instanceof AIPlayer) { + AIRepository.addItem(groundItem); + } + GeneralBotCreator.BotScriptPulse pulse = player.getAttribute("botting:script",null); + if(pulse != null && pulse.isRunning()){ + List items = player.getAttribute("botting:drops",new ArrayList()); + items.add(groundItem); + player.setAttribute("botting:drops",items); + } + } + } + + /** + * Gets the looting player. + * @param player the player. + * @param item the item. + * @return the player. + */ + public Player getLooter(Player player, NPC npc, Item item) { + int itemId = item.getDefinition().isUnnoted() ? item.getId() : item.getNoteChange(); + if (player != null && npc.getProperties().isMultiZone() && (item.getDefinition().isTradeable() || item.getName().endsWith("charm")) && player.getCommunication().getClan() != null && player.getCommunication().isLootShare() && player.getCommunication().getLootRequirement().ordinal() >= player.getCommunication().getClan().getLootRequirement().ordinal() && !player.getIronmanManager().isIronman()) { + Player looter = player; + List players = RegionManager.getLocalPlayers(npc, 16); + List looters = new ArrayList<>(20); + for (Player p : players) { + if (p != null && p.getCommunication().getClan() != null && p.getCommunication().getClan() == player.getCommunication().getClan() && p.getCommunication().isLootShare() && p.getCommunication().getLootRequirement().ordinal() >= p.getCommunication().getClan().getLootRequirement().ordinal()) { + looters.add(p); + } + } + if (looters.size() > 1) { + int highestLsp = 0; + for (Player p : looters) { + if (p.getGlobalData().getLootSharePoints() > highestLsp && RandomFunction.random(10) >= 2) { + highestLsp = p.getGlobalData().getLootSharePoints(); + looter = p; + } + } + player.sendMessage(player.getInterfaceManager().isResizable()+""); + int price = item.getName().endsWith("charm") ? 100 : GrandExchange.getRecommendedPrice(itemId, false); + looter.getGlobalData().setLootSharePoints(looter.getGlobalData().getLootSharePoints() - (price) + ((price / looters.size()))); + looter.sendMessage((player.getInterfaceManager().isResizable() ? "" : "") + "You received: " + item.getAmount() + " " + item.getName()); + for (Player p : looters) { + if (p != looter) { + p.sendMessage((player.getInterfaceManager().isResizable() ? "" : "") + looter.getUsername() + " received: " + item.getAmount() + " " + item.getName()); + p.getGlobalData().setLootSharePoints(p.getGlobalData().getLootSharePoints() + price / looters.size()); + } + } + } + return looter; + } + return player; + } + + /** + * Sends the drop to players within the area. + * @param killer the killer. + * @param npcId the npcId. + * @param item the item. + */ + private void sendDropMessage(Player killer, int npcId, Item item) { + if (!item.getName().toLowerCase().contains("bone") && !item.getName().toLowerCase().contains("ashes")) { + for (int id : MESSAGE_NPCS) { + if (npcId == id) { + for (Player player : Repository.getPlayers()) { + if (player.getLocation().getDistance(killer.getLocation()) <= 10) { + player.sendMessage((player.getInterfaceManager().isResizable() ? "" : "") + (player == killer ? "You received: " : killer.getUsername() + " received a drop: ") + (item.getAmount() > 1 ? StringUtils.getFormattedNumber(item.getAmount()) + " x " + item.getName() : item.getName()) + ""); + } + } + } + } + } + } + + /** + * Handles the bone crusher perk. + * @param player The player + * @param item The item + * @return true if successfully added experience. + */ + private boolean handleBoneCrusher(Player player, Item item) { + Bones bone = Bones.forId(item.getId()); + if (bone == null) { + return false; + } + if (!player.getGlobalData().isEnableBoneCrusher()) { + return false; + } + player.getSkills().addExperience(Skills.PRAYER, item.getAmount() * bone.getExperience()); + return true; + } + + /** + * Gets the ratio for stabilizing NPC combat difficulty & drop rates. + * @return The ratio. + */ + public double getStabilizerRatio() { + return (1 / (1 + def.getCombatLevel())) * 10; + } + + /** + * Gets the modRate. + * @return The modRate. + */ + public double getModRate() { + return modRate; + } + + /** + * Sets the modRate. + * @param modRate The modRate to set. + */ + public void setModRate(double modRate) { + this.modRate = modRate; + } + +} diff --git a/Server/src/main/core/game/node/entity/player/Player.java b/Server/src/main/core/game/node/entity/player/Player.java new file mode 100644 index 0000000..dfced34 --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/Player.java @@ -0,0 +1,1385 @@ +package core.game.node.entity.player; + +import content.global.handlers.item.equipment.special.SalamanderSwingHandler; +import content.global.skill.runecrafting.PouchManager; +import core.api.ContentAPIKt; +import core.api.EquipmentSlot; +import core.game.component.Component; +import core.game.container.Container; +import core.game.container.ContainerType; +import core.game.container.impl.BankContainer; +import core.game.container.impl.EquipmentContainer; +import core.game.container.impl.InventoryListener; +import core.game.dialogue.DialogueInterpreter; +import core.game.interaction.InteractPlugin; +import core.game.interaction.InteractionListeners; +import core.game.interaction.QueueStrength; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.BattleState; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.DeathTask; +import core.game.node.entity.combat.ImpactHandler.HitsplatType; +import content.global.handlers.item.equipment.special.ChinchompaSwingHandler; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.info.*; +import core.game.node.entity.player.info.login.LoginConfiguration; +import core.game.node.entity.player.info.login.PlayerParser; +import core.game.node.entity.player.link.*; +import core.game.node.entity.player.link.appearance.Appearance; +import core.game.node.entity.player.link.diary.AchievementDiaryManager; +import core.game.node.entity.player.link.emote.EmoteManager; +import core.game.node.entity.player.link.music.MusicPlayer; +import core.game.node.entity.player.link.prayer.Prayer; +import core.game.node.entity.player.link.prayer.PrayerType; +import core.game.node.entity.player.link.quest.QuestRepository; +import core.game.node.entity.player.link.request.RequestManager; +import core.game.node.entity.player.link.skillertasks.SkillerTasks; +import core.game.node.entity.skill.Skills; +import content.global.skill.construction.HouseManager; +import content.global.skill.summoning.familiar.FamiliarManager; +import core.game.node.item.GroundItem; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.system.communication.CommunicationInfo; +import core.game.system.task.Pulse; +import core.game.world.map.*; +import core.game.world.map.build.DynamicRegion; +import core.game.world.map.path.Pathfinder; +import core.game.world.map.zone.ZoneRestriction; +import core.game.world.map.zone.ZoneType; +import core.game.world.update.flag.PlayerFlags; +import core.game.world.update.flag.*; +import core.net.IoSession; +import core.net.packet.PacketRepository; +import core.net.packet.context.DynamicSceneContext; +import core.net.packet.context.SceneGraphContext; +import core.net.packet.context.SkillContext; +import core.net.packet.out.BuildDynamicScene; +import core.net.packet.out.SkillLevel; +import core.net.packet.out.UpdateSceneGraph; +import core.plugin.Plugin; +import core.tools.*; +import kotlin.Unit; +import kotlin.jvm.functions.Function1; +import org.rs09.consts.Items; +import org.rs09.consts.Sounds; +import proto.management.ClanLeaveNotification; +import proto.management.PlayerStatusUpdate; +import core.GlobalStats; +import core.ServerConstants; +import core.game.node.entity.combat.CombatSwingHandler; +import content.global.handlers.item.equipment.EquipmentDegrader; +import core.game.node.entity.combat.graves.Grave; +import core.game.node.entity.combat.graves.GraveController; +import core.game.world.GameWorld; +import core.game.world.repository.Repository; +import core.game.world.update.MapChunkRenderer; +import core.game.world.update.NPCRenderer; +import core.game.world.update.PlayerRenderer; +import core.game.world.update.UpdateSequence; +import core.game.ge.GrandExchangeRecords; +import core.game.ge.GrandExchangeOffer; +import core.cache.def.impl.ItemDefinition; +import core.worker.ManagementEvents; +import core.game.world.update.flag.context.*; + +import java.util.*; +import java.util.concurrent.TimeUnit; + +import static core.api.ContentAPIKt.*; +import static core.api.utils.PermadeathKt.permadeath; +import static core.game.system.command.sets.StatAttributeKeysKt.STATS_BASE; +import static core.game.system.command.sets.StatAttributeKeysKt.STATS_DEATHS; +import static core.tools.GlobalsKt.colorize; +import static org.rs09.consts.Items.BONES_526; + +/** + * Represents a player entity. + * @author Emperor + * @author Vexia + */ +public class Player extends Entity { + + /** + * The details of the player. + */ + private PlayerDetails details; + + public boolean inWardrobe = false; + + public Location startLocation = null; + + private final Graphics wardrobe_hold_graphics = new Graphics(1182,0,0); + + public boolean newPlayer = getSkills().getTotalLevel() < 50; + + public BankContainer dropLog = new BankContainer(this); + + public EquipmentDegrader degrader = new EquipmentDegrader(); + + public PouchManager pouchManager = new PouchManager(this); + + public VarpManager varpManager = new VarpManager(this); + + public HashMap varpMap = new HashMap<>(); + + public HashMap saveVarp = new HashMap<>(); + + public HashMap> logoutListeners = new HashMap<>(); + + public Boolean isAfkLogout; + + /** + * The inventory. + */ + private final Container inventory = new Container(28).register(new InventoryListener(this)); + + /** + * The equipment. + */ + private final EquipmentContainer equipment = new EquipmentContainer(this); + + /** + * The bank container. + */ + private final BankContainer bank = new BankContainer(this); + + /** + * The secondary bank container. + */ + private final BankContainer bankSecondary = new BankContainer(this); + + /** + * Is secondary bank in use or not + */ + public boolean useSecondaryBank = false; + + /** + * The packet dispatcher. + */ + private final PacketDispatch packetDispatch = new PacketDispatch(this); + + /** + * The spell book manager. + */ + private final SpellBookManager spellBookManager = new SpellBookManager(); + + /** + * The rendering info. + */ + private final RenderInfo renderInfo = new RenderInfo(this); + + /** + * The interface manager. + */ + private final InterfaceManager interfaceManager = new InterfaceManager(this); + + /** + * The emote manager. + */ + private final EmoteManager emoteManager = new EmoteManager(this); + + /** + * The player flags. + */ + private final PlayerFlags playerFlags = new PlayerFlags(); + + /** + * The appearance. + */ + private final Appearance appearance = new Appearance(this); + + /** + * The settings of the player. + */ + private final Settings settings = new Settings(this); + + /** + * The dialogue interpreter. + */ + private final DialogueInterpreter dialogueInterpreter = new DialogueInterpreter(this); + + /** + * The hint icon manager. + */ + private final HintIconManager hintIconManager = new HintIconManager(); + + /** + * The quest repository. + */ + public QuestRepository questRepository = new QuestRepository(this); + + /** + * The prayer manager. + */ + private final Prayer prayer = new Prayer(this); + + /** + * The skull manager. + */ + private final SkullManager skullManager = new SkullManager(this); + + /** + * The familiar manager. + */ + private final FamiliarManager familiarManager = new FamiliarManager(this); + + /** + * The saved data. + */ + public SavedData savedData = new SavedData(this); + + /** + * The request manager. + */ + private final RequestManager requestManager = new RequestManager(this); + + /** + * The farming manager. + */ + + /** + * Represents the players warning messages. + */ + private final WarningMessages warningMessages = new WarningMessages(); + + /** + * The music player instance. + */ + private final MusicPlayer musicPlayer = new MusicPlayer(this); + + /** + * The house manager. + */ + private final HouseManager houseManager = new HouseManager(); + + /** + * The bank pin manager. + */ + private final BankPinManager bankPinManager = new BankPinManager(this); + + /** + * The achievement diary manager. + */ + private final AchievementDiaryManager achievementDiaryManager = new AchievementDiaryManager(this); + + /** + * The Ironman manager. + */ + private final IronmanManager ironmanManager = new IronmanManager(this); + + /** + * The boolean for the player playing. + */ + private boolean playing; + + /** + * If the player is invisible. + */ + private boolean invisible; + + /** + * If the player is artificial. + */ + protected boolean artificial; + + /** + * The skiller tasks. + */ + protected SkillerTasks skillTasks = new SkillerTasks(); + + /** + * A custom state for bot debugging + */ + private String customState = ""; + + /** + * The amount of targets that the player can shoot left for the archery minigame. + */ + private int archeryTargets = 0; + private int archeryTotal = 0; + + /** + * The save file version. + */ + public int version = ServerConstants.CURRENT_SAVEFILE_VERSION; + + /** + * Packet administration. + * opCounts is used to enforce an authentic limit of 10 of each inbound packet per user per tick. + */ + public byte[] opCounts = new byte[255]; + public int invalidPacketCount = 0; + + /** + * Constructs a new {@code Player} {@code Object}. + * @param details The player's details. + */ + public Player(PlayerDetails details) { + super(details.getUsername(), ServerConstants.START_LOCATION); + super.active = false; + super.interactPlugin = new InteractPlugin(this); + this.details = details; + this.direction = Direction.SOUTH; + } + + @Override + public void init() { + if (!artificial) { + log(this.getClass(), Log.INFO, getUsername() + " initialising..."); + getDetails().getSession().setObject(this); + } + super.init(); + LoginConfiguration.configureLobby(this); + setAttribute("logged-in-fully", true); + } + + @Override + public void clear() { + if (isArtificial()) { + finishClear(); + return; + } + Repository.getDisconnectionQueue().remove(getName()); + Repository.getDisconnectionQueue().add(this, true); + details.save(); + } + + /** + * Clears the player from the game. + * You should NEVER call this manually. This can only be called by the DisconnectionQueue doing its job. + * If you think you need to call this manually, you're wrong. Stop. Turn around. Go back. Here be monsters. + */ + public void finishClear() { + if (!isArtificial()) + GameWorld.getLogoutListeners().forEach((it) -> it.logout(this)); + setPlaying(false); + getWalkingQueue().reset(); + if(!logoutListeners.isEmpty()){ + logoutListeners.forEach((key,method) -> method.invoke(this)); + } + if (familiarManager.hasFamiliar()) { + familiarManager.getFamiliar().clear(); + } + interfaceManager.close(); + interfaceManager.closeSingleTab(); + super.clear(); + getZoneMonitor().clear(); + HouseManager.leave(this); + UpdateSequence.getRenderablePlayers().remove(this); + sendLogoutEvents(); + checkForWealthUpdate(true); + } + + private void sendLogoutEvents() { + PlayerStatusUpdate.Builder statusBuilder = PlayerStatusUpdate.newBuilder(); + statusBuilder.setUsername(this.name); + statusBuilder.setWorld(0); //offline + statusBuilder.setNotifyFriendsOnly(false); + ManagementEvents.publish(statusBuilder.build()); + + if (getCommunication().getClan() != null) { + ClanLeaveNotification.Builder event = ClanLeaveNotification.newBuilder(); + event.setUsername(getName()); + event.setWorld(GameWorld.getSettings().getWorldId()); + event.setClanName(getCommunication().getClan().getOwner()); + ManagementEvents.publish(event.build()); + } + } + + public void toggleWardrobe(boolean intoWardrobe){ + class wardrobePulse extends Pulse{ + final Player player; + boolean first = true; + wardrobePulse(Player player){ + this.player = player; + } + @Override + public boolean pulse() { + if(first){ + player.visualize(new Animation(1241), new Graphics(1181,0,0)); + first = false; + return !player.inWardrobe; + } + if(player.inWardrobe) { + player.visualize(new Animation(1241),wardrobe_hold_graphics); + } else { + player.visualize(new Animation(1241), new Graphics(1183,0,0)); + player.getPulseManager().run(new Pulse(1){ + @Override + public boolean pulse() { + player.getAnimator().reset(); + player.packetDispatch.sendInterfaceConfig(548,69,false); + return true; + } + }); + } + return !player.inWardrobe; + } + } + if(intoWardrobe){ + packetDispatch.sendInterfaceConfig(548,69,true); + GameWorld.getPulser().submit(new wardrobePulse(this)); + inWardrobe = true; + } else { + inWardrobe = false; + } + } + + @Override + public void tick() { + super.tick(); + musicPlayer.tick(); + if(getAttribute("fire:immune",0) > 0){ + int time = getAttribute("fire:immune",0) - GameWorld.getTicks(); + if(time == TickUtilsKt.secondsToTicks(30)){ + sendMessage(colorize("%RYou have 30 seconds remaining on your antifire potion.")); + playAudio(this, Sounds.CLOCK_TICK_1_3120, 0, 3); + } + if(time == 0){ + sendMessage(colorize("%RYour antifire potion has expired.")); + removeAttribute("fire:immune"); + playAudio(this, Sounds.DRAGON_POTION_FINISHED_2607); + } + } + if(getAttribute("poison:immunity",0) > 0){ + int time = getAttribute("poison:immunity",0) - GameWorld.getTicks(); + debug(time + ""); + if(time == TickUtilsKt.secondsToTicks(30)){ + sendMessage(colorize("%RYou have 30 seconds remaining on your antipoison potion.")); + playAudio(this, Sounds.CLOCK_TICK_1_3120, 0, 3); + } + if(time == 0){ + sendMessage(colorize("%RYour antipoison potion has expired.")); + removeAttribute("poison:immunity"); + playAudio(this, Sounds.DRAGON_POTION_FINISHED_2607); + } + } + if(getAttribute("infinite-special", false)) { + settings.setSpecialEnergy(100); + } + + // Decrement prayer points + getPrayer().tick(); + + // Update wealth tracking + checkForWealthUpdate(false); + + // Check if the player is on the map, runs only every 6 seconds for performance reasons. + // This is only a sanity check to detect improper usage of the 'original-loc' attribute, hence only do this work if the attribute is set. + // Only runs when the player is not movement/interaction-locked, so that original-loc does not get wiped e.g. in the middle of the player teleporting to their POH. + if (GameWorld.getTicks() % 10 == 0 && !getLocks().isMovementLocked() && !getLocks().isInteractionLocked()) { + if (ContentAPIKt.getAttribute(this, "/save:original-loc", null) != null) { + int rid = location.getRegionId(); + Region r = RegionManager.forId(rid); + if (!(r instanceof DynamicRegion) && !getZoneMonitor().isRestricted(ZoneRestriction.OFF_MAP)) { + log(this.getClass(), Log.ERR, "Player " + getUsername() + " has the original-loc attribute set but isn't actually off-map! This indicates a bug in the code that set that attribute. The original-loc is " + getAttribute("/save:original-loc") + ", the current region is " + rid + ". Good luck debugging!"); + ContentAPIKt.removeAttribute(this, "original-loc"); + } + } + } + } + + private void checkForWealthUpdate(boolean force) { + if (isArtificial()) return; + long previousWealth = getAttribute("last-wealth", -1L); + long lastWealthCheck = getAttribute("last-wealth-check", -1L); + + long nowTime = System.currentTimeMillis(); + if (force || nowTime - lastWealthCheck >= TimeUnit.MINUTES.toMillis(5)) { + long totalWealth = 0L; + for (Item i : inventory.toArray()) { + if (i == null) continue; + totalWealth += (long) i.getDefinition().getValue() * i.getAmount(); + } + for (Item i : bank.toArray()) { + if (i == null) break; + totalWealth += (long) i.getDefinition().getValue() * i.getAmount(); + } + for (Item i : bankSecondary.toArray()) { + if (i == null) break; + totalWealth += (long) i.getDefinition().getValue() * i.getAmount(); + } + GrandExchangeRecords ge = GrandExchangeRecords.getInstance(this); + for (int i=0; i<6; i++) { + GrandExchangeOffer offer = ge.getOffer(i); + if (offer != null) { + totalWealth += offer.cacheValue(); + } + } + + // This can lead to a false positive of up to 3 * 187.5k, but only for 3 ticks while a cannon is being constructed + if (this.getAttribute("dmc", null) != null) { + totalWealth += ItemDefinition.forId(Items.CANNON_BASE_6).getValue(); + totalWealth += ItemDefinition.forId(Items.CANNON_STAND_8).getValue(); + totalWealth += ItemDefinition.forId(Items.CANNON_BARRELS_10).getValue(); + totalWealth += ItemDefinition.forId(Items.CANNON_FURNACE_12).getValue(); + } + + long diff = previousWealth == -1 ? 0L : totalWealth - previousWealth; + setAttribute("/save:last-wealth", totalWealth); + setAttribute("/save:last-wealth-check", nowTime); + + if (diff != 0) + PlayerMonitor.logWealthChange(this, totalWealth, diff); + } + } + + @Override + public void update() { + super.update(); + if (playerFlags.isUpdateSceneGraph()) { + updateSceneGraph(false); + } + PlayerRenderer.render(this); + NPCRenderer.render(this); + MapChunkRenderer.render(this); + } + + @Override + public void reset() { + super.reset(); + playerFlags.setUpdateSceneGraph(false); + renderInfo.updateInformation(); + if (getSkills().isLifepointsUpdate()) { + PacketRepository.send(SkillLevel.class, new SkillContext(this, Skills.HITPOINTS)); + getSkills().setLifepointsUpdate(false); + } + if (getAttribute("flagged-for-save", false)) { + PlayerParser.saveImmediately(this); + removeAttribute("flagged-for-save"); + } + Arrays.fill(opCounts, (byte) 0); + } + + @Override + public int getClientIndex() { + return this.getIndex() | 0x8000; + } + + @Override + public void onAttack (Entity e) { + if (e instanceof Player) { + Player p = (Player) e; + if (skullManager.isWildernessDisabled()) { + return; + } + } + } + + @Override + public CombatSwingHandler getSwingHandler(boolean swing) { + CombatStyle style = getProperties().getCombatPulse().getStyle(); + int weaponId = equipment.getNew(3).getId(); + if (swing) { + if (getProperties().getSpell() != null || getProperties().getAutocastSpell() != null) { + return CombatStyle.MAGIC.getSwingHandler(); + } + if (settings.isSpecialToggled()) { + CombatSwingHandler handler; + if ((handler = style.getSwingHandler().getSpecial(weaponId)) != null) { + return handler; + } + packetDispatch.sendMessage("Unhandled special attack for item " + weaponId + "!"); + } + } + if (style == CombatStyle.RANGE && weaponId == 10033 || weaponId == 10034) { + return ChinchompaSwingHandler.getInstance(); + } + if (weaponId >= 10146 && weaponId <= 10149) { + return SalamanderSwingHandler.Companion.getINSTANCE(); + } + return style.getSwingHandler(); + } + + @Override + public void commenceDeath(Entity killer) { + if (!isPlaying()) return; + super.commenceDeath(killer); + if (prayer.get(PrayerType.RETRIBUTION)) { + prayer.startRetribution(killer); + } + } + + @Override + public void finalizeDeath(Entity killer) { + if (!isPlaying()) return; //if the player has already been full cleared, it has already disconnected. This code is probably getting called because something is maintaining a stale reference. + GlobalStats.incrementDeathCount(); + settings.setSpecialEnergy(100); + settings.updateRunEnergy(settings.getRunEnergy() - 100); + Player k = killer instanceof Player ? (Player) killer : this; + if (!k.isActive()) { + k = this; + } + if (this.isArtificial() && killer instanceof Player){ + setAttribute("dead", true); + } + if (this.isArtificial() && killer instanceof NPC) { + return; + } + if (killer instanceof Player && killer.getName() != getName() /* happens if you died via typeless damage from an external cause, e.g. bugs in a dark cave without a light source */ && getWorldTicks() - killer.getAttribute("/save:last-murder-news", 0) >= 500) { + Item wep = getItemFromEquipment((Player) killer, EquipmentSlot.WEAPON); + sendNews(killer.getUsername() + " has murdered " + getUsername() + " with " + (wep == null ? "their fists." : (StringUtils.isPlusN(wep.getName()) ? "an " : "a ") + wep.getName())); + killer.setAttribute("/save:last-murder-news", getWorldTicks()); + } + getPacketDispatch().sendMessage("Oh dear, you are dead!"); + incrementAttribute("/save:"+STATS_BASE+":"+STATS_DEATHS); + + packetDispatch.sendTempMusic(90); + if (!getZoneMonitor().handleDeath(killer) && (!getProperties().isSafeZone() && getZoneMonitor().getType() != ZoneType.SAFE.getId()) && getDetails().getRights() != Rights.ADMINISTRATOR) { + //If player was a Hardcore Ironman, announce that they died + if (this.getIronmanManager().getMode().equals(IronmanMode.HARDCORE)) { //if this was checkRestriction, ultimate irons would be moved to HARDCORE_DEAD as well + String gender = this.isMale() ? "man " : "woman "; + if (getAttributes().containsKey("permadeath")) { + Repository.sendNews("Permadeath Hardcore Iron" + gender + " " + this.getUsername() + " has fallen. Total Level: " + this.getSkills().getTotalLevel()); // Not enough room for XP + permadeath(this); + return; + } + } + GroundItemManager.create(new Item(BONES_526), this.getAttribute("/save:original-loc",location), k); + final Container[] c = DeathTask.getContainers(this); + + for (Item i : getEquipment().toArray()) { + if (i == null) continue; + InteractionListeners.run(i.getId(), this, i, false); + Plugin equipPlugin = i.getDefinition().getConfiguration("equipment", null); + if (equipPlugin != null) equipPlugin.fireEvent("unequip"); + } + + boolean canCreateGrave = GraveController.allowGenerate(this); + if (canCreateGrave) { + Grave g = GraveController.produceGrave(GraveController.getGraveType(this)); + g.initialize(this, location, Arrays.stream(c[1].toArray()).filter(Objects::nonNull).toArray(Item[]::new)); //note: the amount of code required to filter nulls from an array in Java is atrocious. + } else { + StringBuilder itemsLost = new StringBuilder(); + int coins = 0; + for (Item item : c[1].toArray()) { + boolean stayPrivate = false; + if (item == null) continue; + if (killer instanceof Player) + itemsLost.append(getItemName(item.getId())).append("(").append(item.getAmount()).append("), "); + if (GraveController.shouldCrumble(item.getId())) + continue; + if (GraveController.shouldRelease(item.getId())) + continue; + if (!item.getDefinition().isTradeable()) { + if (killer instanceof Player) { + int value = item.getDefinition().getAlchemyValue(true); + if (getStatLevel(killer, Skills.MAGIC) < 55) value /= 2; + coins += Math.max(0, value - 250); + continue; + } else stayPrivate = true; + } + item = GraveController.checkTransform(item); + GroundItem gi = GroundItemManager.create(item, location, killer instanceof Player ? (Player) killer : this); + gi.setRemainPrivate(stayPrivate); + } + if (coins > 0) { + GroundItemManager.create(new Item(Items.COINS_995, coins), location, (Player) killer); + } + if (killer instanceof Player) + PlayerMonitor.log((Player) killer, LogType.PK, "Killed " + name + ", who dropped: " + itemsLost); + sendMessage(colorize("%RDue to the circumstances of your death, you do not have a grave.")); + } + + equipment.clear(); + inventory.clear(); + inventory.addAll(c[0]); + familiarManager.dismiss(); + } + skullManager.setSkulled(false); + removeAttribute("combat-time"); + getPrayer().reset(); + removeAttribute("original-loc"); //in case you died inside a random event + interfaceManager.openDefaultTabs(); //in case you died inside a random that had blanked them + setComponentVisibility(this, 548, 69, false); //reenable the logout button (SD) + setComponentVisibility(this, 746, 12, false); //reenable the logout button (HD) + super.finalizeDeath(killer); + appearance.sync(); + if (!getSavedData().getGlobalData().isDeathScreenDisabled()) { + getInterfaceManager().open(new Component(153)); + } + } + + @Override + public boolean hasProtectionPrayer(CombatStyle style) { + if (style == null) { + return false; + } + return prayer.get(style.getProtectionPrayer()); + } + + @Override + public int getDragonfireProtection(boolean fire) { + int value = 0; + if (fire) { + if (hasFireResistance()) { + value |= 0x2; + } + } + Item item = equipment.get(EquipmentContainer.SLOT_SHIELD); + if (item != null && (item.getId() == 11283 || item.getId() == 11284 || (fire && (item.getId() == 1540) || (!fire && (item.getId() == 2890 || item.getId() == 9731))))) { + value |= 0x4; + } + if (prayer.get(PrayerType.PROTECT_FROM_MAGIC)) { + value |= 0x8; + } + setAttribute("fire_resistance", value); + return value; + } + + @Deprecated + @Override + public void setLocation(Location location) { + super.setLocation(location); + } + + @Override + public void fullRestore() { + prayer.reset(); + settings.setSpecialEnergy(100); + settings.updateRunEnergy(-100); + super.fullRestore(); + } + + @Override + public boolean isAttackable(Entity entity, CombatStyle style, boolean message) { + if (entity instanceof NPC && !((NPC) entity).getDefinition().hasAction("attack") && !((NPC) entity).isIgnoreAttackRestrictions(this)) { + return false; + } + if (entity instanceof Player) { + Player p = (Player) entity; + if (p.getSkullManager().isWilderness() && skullManager.isWilderness()) { + if (!GameWorld.getSettings().getWild_pvp_enabled()) + return false; + if (p.getSkullManager().hasWildernessProtection()) + return false; + if (skullManager.hasWildernessProtection()) + return false; + return true; + } else return false; + } + return super.isAttackable(entity, style, message); + } + + @Override + public boolean isPoisonImmune() { + return timers.getTimer("poison:immunity") != null; + } + + @Override + public void onImpact(final Entity entity, BattleState state) { + super.onImpact(entity, state); + boolean recoil = getEquipment().getNew(EquipmentContainer.SLOT_RING).getId() == 2550; + if (state.getEstimatedHit() > 0) { + if (getAttribute("vengeance", false)) { + removeAttribute("vengeance"); + final int hit = (int) (state.getEstimatedHit() * 0.75); + sendChat("Taste vengeance!"); + if (hit > -1) { + entity.getImpactHandler().manualHit(Player.this, hit, HitsplatType.NORMAL); + } + } + if (recoil) { + getImpactHandler().handleRecoilEffect(entity, state.getEstimatedHit()); + } + } + if (state.getSecondaryHit() > 0) { + if (recoil) { + getImpactHandler().handleRecoilEffect(entity, state.getSecondaryHit()); + } + } + degrader.checkArmourDegrades(this); + } + + public void randomWalk(int radiusX, int radiusY) { + Pathfinder.find(this, this.getLocation().transform(RandomFunction.random(radiusX, (radiusX * -1)), RandomFunction.random(radiusY, (radiusY * -1)), 0), false, Pathfinder.SMART).walk(this); + } + + /** + * Initializes the player for reconnection. + */ + public void initReconnect() { + getInterfaceManager().setChatbox(null); + getPulseManager().clear(); + getZoneMonitor().getZones().clear(); + getViewport().setCurrentPlane(RegionManager.forId(66666).getPlanes()[3]); + playerFlags.setLastSceneGraph(null); + playerFlags.setUpdateSceneGraph(false); + playerFlags.setLastViewport(new RegionChunk[Viewport.CHUNK_SIZE][Viewport.CHUNK_SIZE]); + renderInfo.getLocalNpcs().clear(); + renderInfo.getLocalPlayers().clear(); + renderInfo.setLastLocation(null); + renderInfo.setOnFirstCycle(true); + Arrays.fill(renderInfo.getAppearanceStamps(),0); + } + + /** + * Checks if the player is wearing void. + */ + public boolean isWearingVoid(CombatStyle style) { + int helm; + if(style == CombatStyle.MELEE) { + helm = Items.VOID_MELEE_HELM_11665; + } else if(style == CombatStyle.RANGE) { + helm = Items.VOID_RANGER_HELM_11664; + } else if(style == CombatStyle.MAGIC) { + helm = Items.VOID_MAGE_HELM_11663; + } else { + return false; + } + boolean legs = inEquipment(this, Items.VOID_KNIGHT_ROBE_8840, 1); + boolean top = inEquipment(this, Items.VOID_KNIGHT_TOP_8839, 1) + || inEquipment(this, Items.VOID_KNIGHT_TOP_10611, 1); + boolean gloves = inEquipment(this, Items.VOID_KNIGHT_GLOVES_8842, 1); + return inEquipment(this, helm, 1) && legs && top && gloves; + } + + /** + * Updates the player's scene graph. + * @param login If the player is logging in. + */ + public void updateSceneGraph(boolean login) { + Region region = getViewport().getRegion(); + if (region instanceof DynamicRegion || region == null && (region = RegionManager.forId(location.getRegionId())) instanceof DynamicRegion) { + PacketRepository.send(BuildDynamicScene.class, new DynamicSceneContext(this, login)); + } else { + PacketRepository.send(UpdateSceneGraph.class, new SceneGraphContext(this, login)); + } + } + + /** + * Toggles the debug mode. + */ + public void toggleDebug() { + boolean debug = getAttribute("debug", false); + setAttribute("debug", !debug); + getPacketDispatch().sendMessage("Your debug mode is toggled to " + !debug + "."); + } + + /** + * Wrapper method for sending a message. + * @param messages the messages. + */ + public void sendMessages(String... messages) { + packetDispatch.sendMessages(messages); + } + + /** + * Wrapper method for sending a message. + * @param message the message. + */ + public void sendMessage(String message) { + sendMessages(message); + } + + /** + * Sends a notification message. + * @param message The message. + */ + public void sendNotificationMessage(String message) { + sendMessages("" + message + ""); + } + + /** + * Checks if the player can spawn. & Location + * @return {@code True} if so. + */ + public boolean spawnZone() { + return (getLocation().getX() > 3090 && getLocation().getY() < 3500 + && getLocation().getX() < 3099 && getLocation().getY() > 3487); + } + + public boolean canSpawn() { + if (!spawnZone()) { + sendMessage("You can only spawn items inside the edgeville bank."); + return true; + } + if (inCombat() || getLocks().isInteractionLocked() || getSkullManager().isWilderness() || getAttribute("activity", null) != null) { + sendMessage("You can't spawn items at the moment."); + return true; + } + return false; + } + + /** + * Sends a message on a tick. + * @param message the message. + * @param ticks the ticks. + */ + public void sendMessage(String message, int ticks) { + packetDispatch.sendMessage(message, ticks); + } + + /** + * Sends a message to the player if it's an administrator. + * @param string The message. + */ + public void debug(String string) { + if (getAttribute("debug",false)) { + packetDispatch.sendMessage(string); + } + } + + /** + * Grabs a players gender, using shorter amount of code + */ + + public boolean isMale() { + return this.getAppearance().getGender().ordinal() == 0; + } + + /** + * Sets the player details. + * @param details The player details. + */ + @SuppressWarnings("deprecation") + public void updateDetails(PlayerDetails details) { + if (this.details != null) { + details.setBanTime(this.details.getBanTime()); + details.setMuteTime(this.details.getMuteTime()); + } + details.getSession().setObject(this); + this.details = details; + } + + /** + * Checks if the player is allowed to be removed from the game. + * @return {@code True} if so. + */ + public boolean allowRemoval() { + return !(inCombat() || getSkills().getLifepoints() < 1 || DeathTask.isDead(this) || isTeleporting() || scripts.hasTypeInQueue(QueueStrength.SOFT)); + } + + /** + * Checks if the containers have this item. + * @param item the item. + * @return {@code True} if so. + */ + public boolean hasItem(Item item) { + return getInventory().containsItem(item) || getBank().containsItem(item) || getEquipment().containsItem(item); + } + + /** + * Gets the player extra experience mod. + * @return the mod. + */ + public double getExperienceMod() { + return getSavedData().getGlobalData().hasDoubleExp() ? 2 : 1; + } + + /** + * Checks if the player is a staff member. + * @return {@code True} if so. + */ + public boolean isStaff() { + return getDetails().getRights() != Rights.REGULAR_PLAYER; + } + + /** + * Checks if the player is an admin. + * @return true if so. + */ + public boolean isAdmin() { + return getDetails().getRights() == Rights.ADMINISTRATOR; + } + + /** + * Checks if the player is debugging. + * @return {@code True} if so. + */ + public boolean isDebug() { + return details.getRights() == Rights.ADMINISTRATOR && getAttribute("debug", false); + } + + /** + * Gets the uid info. + * @return the info. + */ + public UIDInfo getUidInfo() { + return details.getInfo(); + } + + /** + * Gets the {@code PlayerDetails}. + * @return the details. + */ + public PlayerDetails getDetails() { + return details; + } + + /** + * Gets the name. + * @return the name. + */ + public String getName() { +// return display ? details.getDisplayName() : super.getName(); + return super.getName(); + } + + /** + * Gets the players {@code Session}. + * @return the {@code PlayerDetails} {@code Object} session. + */ + public IoSession getSession() { + return details.getSession(); + } + + /** + * Gets the {@code Equipment} + * @return {@code Equipment}. + */ + public EquipmentContainer getEquipment() { + return equipment; + } + + /** + * Gets the current active bank. + * @return Current active bank. + */ + public BankContainer getBank() { + return useSecondaryBank ? bankSecondary : bank; + } + + /** + * Gets the primary bank. + * @return Primary bank + */ + public BankContainer getBankPrimary() { + return bank; + } + + /** + * Gets the Secondary bank. + * @return Secondary bank + */ + public BankContainer getBankSecondary() { + return bankSecondary; + } + + public BankContainer getDropLog() {return dropLog;} + + /** + * @return the inventory + */ + public Container getInventory() { + return inventory; + } + + /** + * Sets the playing flag. + * @param playing the flag to set. + */ + public void setPlaying(boolean playing) { + this.playing = playing; + } + + /** + * Checks if the player is playing. + * @return {@code True} if so. + */ + public boolean isPlaying() { + return playing; + } + + /** + * Gets the rights of the player. + * @return the rights. + */ + public Rights getRights() { + return details.getRights(); + } + + /** + * Gets the renderInfo. + * @return The renderInfo. + */ + public RenderInfo getRenderInfo() { + return renderInfo; + } + + /** + * Gets the appearance. + * @return The appearance. + */ + public Appearance getAppearance() { + return appearance; + } + + /** + * Gets the playerFlags. + * @return The playerFlags. + */ + public PlayerFlags getPlayerFlags() { + return playerFlags; + } + + /** + * Gets the {@code PacketDispatch}. + * @return the packet dispatch. + */ + public PacketDispatch getPacketDispatch() { + return packetDispatch; + } + + + /** + * @return the spellBookManager + */ + public SpellBookManager getSpellBookManager() { + return spellBookManager; + } + + /** + * Gets the settings. + * @return The settings. + */ + public Settings getSettings() { + return settings; + } + + /** + * @return the interface manager. + */ + public InterfaceManager getInterfaceManager() { + return interfaceManager; + } + + public boolean hasModalOpen() { + int[] excludedIds = new int[] {372, 421, InterfaceManager.DEFAULT_CHATBOX}; //excludes plain message, plain message with scrollbar, and normal chatbox + Component openedIface = interfaceManager.getOpened(); + Component openChatbox = interfaceManager.getChatbox(); + + boolean hasModal = false; + + if (openedIface != null) { + for (int i = 0; i < excludedIds.length; i++) + if (excludedIds[i] == openedIface.getId()) break; + else if (i == excludedIds.length - 1) hasModal = true; + } + + if (openChatbox != null) { + for (int i = 0; i < excludedIds.length; i++) + if (excludedIds[i] == openChatbox.getId()) break; + else if (i == excludedIds.length - 1) hasModal = true; + } + + return hasModal; + } + + /** + * Gets the dialogue interpreter. + * @return The dialogue interpreter. + */ + public DialogueInterpreter getDialogueInterpreter() { + return dialogueInterpreter; + } + + /** + * @return the hintIconManager + */ + public HintIconManager getHintIconManager() { + return hintIconManager; + } + + /** + * Checks if the player is artifical (AIPlayer). + * @return {@code True} if so. + */ + public boolean isArtificial() { + return artificial; + } + + /** + * @return the questRepository. + */ + public QuestRepository getQuestRepository() { + return questRepository; + } + + /** + * @return the prayer. + */ + public Prayer getPrayer() { + return prayer; + } + + /** + * @return the skullManager. + */ + public SkullManager getSkullManager() { + return skullManager; + } + + /** + * @return the familiarManager. + */ + public FamiliarManager getFamiliarManager() { + return familiarManager; + } + + /** + * Gets the communication. + * @return The communication. + */ + public CommunicationInfo getCommunication() { + return details.getCommunication(); + } + + /** + * Gets the requestManager. + * @return The requestManager. + */ + public RequestManager getRequestManager() { + return requestManager; + } + + /** + * Gets the savedData. + * @return The savedData. + */ + public SavedData getSavedData() { + return savedData; + } + + /** + * Gets the global data. + * @return the global data. + */ + public GlobalData getGlobalData() { + return savedData.getGlobalData(); + } + + /** + * Gets the farmingManager. + * @return The farmingManager. + */ + + + /** + * Gets the warningMessages. + * @return The warningMessages. + */ + public WarningMessages getWarningMessages() { + return warningMessages; + } + + /** + * Gets the musicPlayer. + * @return The musicPlayer. + */ + public MusicPlayer getMusicPlayer() { + return musicPlayer; + } + + /** + * Gets the houseManager. + * @return The houseManager. + */ + public HouseManager getHouseManager() { + return houseManager; + } + + /** + * Gets the bankPinManager. + * @return the bankPinManager + */ + public BankPinManager getBankPinManager() { + return bankPinManager; + } + + /** + * Gets the achievementDiaryManager. + * @return the achievementDiaryManager + */ + public AchievementDiaryManager getAchievementDiaryManager() { + return achievementDiaryManager; + } + + /** + * Gets the ironmanManager. + * @return the ironmanManager + */ + public IronmanManager getIronmanManager() { + return ironmanManager; + } + + /** + * Gets the emoteManager. + * @return the emoteManager. + */ + public EmoteManager getEmoteManager() { + return emoteManager; + } + + /** + * Gets the invisible. + * @return the invisible + */ + public boolean isInvisible() { + return invisible; + } + + /** + * Sets the invisible. + * @param invisible the invisible to set. + */ + public void setInvisible(boolean invisible) { + this.invisible = invisible; + } + + @Override + public String getUsername() { + return StringUtils.formatDisplayName(getName()); + } + + public SkillerTasks getSkillTasks() { + return skillTasks; + } + + public void setSkillTasks(SkillerTasks skillTasks) { + this.skillTasks = skillTasks; + } + + @Override + public String toString() { + return "Player [name=" + name + ", getRights()=" + getRights() + "]"; + } + + public String getCustomState() { + return customState; + } + + public void setCustomState(String state) + { + this.customState = state; + } + + public int getArcheryTargets() { + return archeryTargets; + } + + public void setArcheryTargets(int archeryTargets) { + this.archeryTargets = archeryTargets; + } + + public int getArcheryTotal() { + return archeryTotal; + } + + public void setArcheryTotal(int archeryTotal) { + this.archeryTotal = archeryTotal; + } + + public void updateAppearance() { + getUpdateMasks().register(EntityFlag.Appearance, this); + } + + public void incrementInvalidPacketCount() { + invalidPacketCount++; + if (invalidPacketCount >= 5) { + clear(); + log(this.getClass(), Log.ERR, "Disconnecting " + getName() + " for having a high rate of invalid packets. Potential packet bot misbehaving, or simply really bad connection."); + } + } +} diff --git a/Server/src/main/core/game/node/entity/player/Varbit.kt b/Server/src/main/core/game/node/entity/player/Varbit.kt new file mode 100644 index 0000000..fff714c --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/Varbit.kt @@ -0,0 +1,5 @@ +package core.game.node.entity.player + +class Varbit(var value: Int, val offset: Int){ + +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/player/VarpManager.kt b/Server/src/main/core/game/node/entity/player/VarpManager.kt new file mode 100644 index 0000000..96067b1 --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/VarpManager.kt @@ -0,0 +1,34 @@ +package core.game.node.entity.player + +import content.global.skill.farming.FarmingPatch +import core.game.event.VarbitUpdateEvent +import core.cache.def.impl.VarbitDefinition +import org.json.simple.JSONArray +import org.json.simple.JSONObject + +/** + * Manages the collection of a player's varps. + * Also handles saving and loading of saved varps. + * @author Ceikry + */ +class VarpManager(val player: Player) { + fun save(root: JSONObject){ + } + + fun parse(data: JSONArray){ + for(varpobj in data){ + val vobj = varpobj as JSONObject + val index = vobj["index"].toString().toInt() + val bits = vobj["bitArray"] as JSONArray + var total = 0 + for(vbit in bits){ + val varbit = vbit as JSONObject + val offset = varbit["offset"].toString().toInt() + val value = varbit["value"].toString().toInt() + total = total or (value shl offset) + } + player.varpMap[index] = total + player.saveVarp[index] = true + } + } +} diff --git a/Server/src/main/core/game/node/entity/player/info/ClientInfo.java b/Server/src/main/core/game/node/entity/player/info/ClientInfo.java new file mode 100644 index 0000000..a848cd9 --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/info/ClientInfo.java @@ -0,0 +1,123 @@ +package core.game.node.entity.player.info; + +/** + * Holds a player's client info. + * @author Emperor + * + */ +public final class ClientInfo { + + /** + * The current display mode. + */ + private int displayMode; + + /** + * The current window mode. + */ + private int windowMode; + + /** + * The screen width. + */ + private int screenWidth; + + /** + * The screen height. + */ + private int screenHeight; + + /** + * Constructs a new {@Code ClientInfo} {@Code Object} + * @param displayMode The display mode. + * @param windowMode The window mode. + * @param screenWidth The screen width. + * @param screenHeight The screen height. + */ + public ClientInfo(int displayMode, int windowMode, int screenWidth, int screenHeight) { + this.displayMode = displayMode; + this.windowMode = windowMode; + this.screenWidth = screenWidth; + this.screenHeight = screenHeight; + } + + /** + * Checks if the client is running HD. + * @return {@code True} if so. + */ + public boolean isHighDetail() { + return displayMode > 0; // ? + } + + /** + * Checks if the client screen is resizable. + * @return {@code True} if so. + */ + public boolean isResizable() { + return windowMode > 1; + } + + /** + * Gets the displayMode. + * @return the displayMode + */ + public int getDisplayMode() { + return displayMode; + } + + /** + * Sets the displayMode. + * @param displayMode the displayMode to set. + */ + public void setDisplayMode(int displayMode) { + this.displayMode = displayMode; + } + + /** + * Gets the windowMode. + * @return the windowMode + */ + public int getWindowMode() { + return windowMode; + } + + /** + * Sets the windowMode. + * @param windowMode the windowMode to set. + */ + public void setWindowMode(int windowMode) { + this.windowMode = windowMode; + } + + /** + * Gets the screenWidth. + * @return the screenWidth + */ + public int getScreenWidth() { + return screenWidth; + } + + /** + * Sets the screenWidth. + * @param screenWidth the screenWidth to set. + */ + public void setScreenWidth(int screenWidth) { + this.screenWidth = screenWidth; + } + + /** + * Gets the screenHeight. + * @return the screenHeight + */ + public int getScreenHeight() { + return screenHeight; + } + + /** + * Sets the screenHeight. + * @param screenHeight the screenHeight to set. + */ + public void setScreenHeight(int screenHeight) { + this.screenHeight = screenHeight; + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/player/info/PlayerDetails.java b/Server/src/main/core/game/node/entity/player/info/PlayerDetails.java new file mode 100644 index 0000000..7a87759 --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/info/PlayerDetails.java @@ -0,0 +1,273 @@ +package core.game.node.entity.player.info; + +import core.game.system.communication.CommunicationInfo; +import core.net.IoSession; +import org.jetbrains.annotations.NotNull; +import core.auth.UserAccountInfo; +import core.game.world.GameWorld; + +import java.util.concurrent.TimeUnit; + +/** + * Stores the details of a player's account. + * @author Vexia + * + */ +public class PlayerDetails { + public UserAccountInfo accountInfo = UserAccountInfo.createDefault(); + + /** + * The communication info. + */ + private final CommunicationInfo communicationInfo = new CommunicationInfo(); + + public int getCredits() { + return accountInfo.getCredits(); + } + + public void setCredits(int amount) { + accountInfo.setCredits(amount); + } + + + /** + * The unique id info. + */ + private final UIDInfo info = new UIDInfo(); + + /** + * Represents the session. + */ + private IoSession session; + + public boolean saveParsed = false; + + /** + * Constructs a new {@code PlayerDetails}. + * @param username the username to set. + */ + public PlayerDetails(String username) { + accountInfo.setUsername(username); + } + + /** + * Checks if the player is muted. + * @return {@code True} if so. + */ + public boolean isBanned() { + return accountInfo.getBanEndTime() > System.currentTimeMillis(); + } + + /** + * Checks if the mute is permanent. + * @return {@code True} if so. + */ + public boolean isPermMute() { + return TimeUnit.MILLISECONDS.toDays(accountInfo.getMuteEndTime() - System.currentTimeMillis()) > 1000; + } + + /** + * Checks if the player is muted. + * @return {@code True} if so. + */ + public boolean isMuted() { + return accountInfo.getMuteEndTime() > System.currentTimeMillis(); + } + + /** + * Gets the rights. + * @return The rights. + */ + public Rights getRights() { + return Rights.values()[accountInfo.getRights()]; + } + + /** + * Sets the credentials. + * @param rights The credentials to set. + */ + public void setRights(Rights rights) { + this.accountInfo.setRights(rights.ordinal()); + } + + /** + * Gets the session. + * @return The session. + */ + public IoSession getSession() { + return session; + } + + /** + * Sets the session. + * @param session The session to set. + */ + public void setSession(IoSession session) { + this.session = session; + } + + /** + * Sets the password. + * @param password the password. + */ + public void setPassword(final String password) { + this.accountInfo.setPassword(password); + } + + /** + * Gets the username. + * @return The username. + */ + + public String getUsername() { + return this.accountInfo.getUsername(); + } + + /** + * Gets the uid. + * @return the uid. + */ + public int getUid() { + return accountInfo.getUid(); + } + + /** + * Gets the password. + * @return The password. + */ + public String getPassword() { + return this.accountInfo.getPassword(); + } + + /** + * Gets the mac address. + * @return the address. + */ + public String getMacAddress() { + return info.getMac(); + } + + /** + * Gets the computer name. + * @return the name. + */ + public String getCompName() { + return info.getCompName(); + } + + /** + * Gets the ip address. + * @return the ip. + */ + public String getIpAddress() { + if (session == null) { + return info.getIp(); + } + return session.getAddress(); + } + + /** + * Gets the serial. + * @return the serial. + */ + public String getSerial() { + return info.getSerial(); + } + + /** + * Gets the info. + * @return the info + */ + public UIDInfo getInfo() { + return info; + } + + /** + * Gets the communicationInfo. + * @return the communicationInfo + */ + public CommunicationInfo getCommunication() { + return communicationInfo; + } + + /** + * Gets the lastLogin. + * @return the lastLogin. + */ + public long getLastLogin() { + return this.accountInfo.getLastLogin(); + } + + /** + * Sets the lastLogin. + * @param lastLogin the lastLogin to set + */ + public void setLastLogin(long lastLogin) { + this.accountInfo.setLastLogin(lastLogin); + } + + /** + * Gets the timePlayed. + * @return the timePlayed. + */ + public long getTimePlayed() { + return this.accountInfo.getTimePlayed(); + } + + /** + * Sets the timePlayed. + * @param timePlayed the timePlayed to set + */ + public void setTimePlayed(long timePlayed) { + this.accountInfo.setTimePlayed(timePlayed); + } + + /** + * Sets the mute time. + * @param muteTime the mute time. + */ + public void setMuteTime(long muteTime) { + this.accountInfo.setMuteEndTime(muteTime); + } + + /** + * Gets the mute time. + * @return The mute time. + */ + public long getMuteTime() { + return this.accountInfo.getMuteEndTime(); + } + + /** + * Gets the banTime. + * @return the banTime. + */ + public long getBanTime() { + return this.accountInfo.getBanEndTime(); + } + + /** + * Sets the banTime. + * @param banTime the banTime to set + */ + public void setBanTime(long banTime) { + this.accountInfo.setBanEndTime(banTime); + } + + public void save() { + if(!saveParsed) return; + if(isBanned()) return; + try { + accountInfo.setContacts(communicationInfo.getContactString()); + accountInfo.setBlocked(communicationInfo.getBlockedString()); + accountInfo.setClanName(communicationInfo.getClanName()); + accountInfo.setClanReqs(communicationInfo.getClanReqString()); + accountInfo.setCurrentClan(communicationInfo.getCurrentClan()); + GameWorld.getAccountStorage().update(accountInfo); + } catch (IllegalStateException ignored) {} + } + + public static PlayerDetails getDetails(@NotNull String username) { + return new PlayerDetails(username); + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/player/info/PlayerMonitor.kt b/Server/src/main/core/game/node/entity/player/info/PlayerMonitor.kt new file mode 100644 index 0000000..112d51a --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/info/PlayerMonitor.kt @@ -0,0 +1,246 @@ +package core.game.node.entity.player.info + +import core.ServerConstants +import core.api.getItemName +import core.game.container.Container +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.integrations.discord.Discord +import core.integrations.sqlite.SQLiteProvider +import core.tools.Log +import kotlinx.coroutines.Job +import kotlinx.coroutines.cancel +import java.sql.Connection +import java.util.concurrent.LinkedBlockingQueue +import kotlin.math.abs + +object PlayerMonitor { + private val eventQueue = LinkedBlockingQueue() + private var activeTask: Job? = null + private lateinit var db: SQLiteProvider + + var expectedTables = hashMapOf( + "chat_logs" to """ + CREATE TABLE "chat_logs" ( "player" TEXT, "uid" INTEGER, "type" TEXT, "message" TEXT, "timestamp" NUMERIC ); + """, + "misc_logs" to """ + CREATE TABLE "misc_logs" ( "player" TEXT, "uid" INTEGER, "type" TEXT, "details" TEXT , "timestamp" NUMERIC); + """, + "trade_logs" to """ + CREATE TABLE "trade_logs" ( "player_a" TEXT, "player_b" TEXT, "uid_a" INTEGER, "uid_b" INTEGER, "items_a" TEXT, "items_b" TEXT, "timestamp" NUMERIC ); + """, + "xp_gains" to """ + CREATE TABLE "xp_gains" ( "player" TEXT, "uid" INTEGER, "attack" INTEGER, "defence" INTEGER, "strength" INTEGER, "hitpoints" INTEGER, "ranged" INTEGER, "prayer" INTEGER, "magic" INTEGER, "cooking" INTEGER, "woodcutting" INTEGER, "fletching" INTEGER, "fishing" INTEGER, "firemaking" INTEGER, "crafting" INTEGER, "smithing" INTEGER, "mining" INTEGER, "herblore" INTEGER, "agility" INTEGER, "thieving" INTEGER, "slayer" INTEGER, "farming" INTEGER, "runecrafting" INTEGER, "hunter" INTEGER, "construction" INTEGER, "summoning" INTEGER , "timestamp" NUMERIC) + """, + "wealth_logs" to """ + CREATE TABLE "wealth_logs" ( "player" TEXT, "uid" INTEGER, "total" NUMERIC, "diff" NUMERIC, "timestamp" NUMERIC ) + """ + ) + + @JvmStatic fun logWealthChange(player: Player, totalWealth: Long, diff: Long) { + val event = LogEvent.WealthLog( + player.name, + player.details.uid, + totalWealth, + diff, + System.currentTimeMillis() + ) + dispatch(event) + if (abs(diff) >= 500_000L) + Discord.postPlayerAlert(player.name, "Dubious change in wealth: $diff, total wealth: $totalWealth") + } + + @JvmStatic fun logChat(player: Player, type: String, message: String) { + val event = LogEvent.ChatLog( + player.name, + player.details.uid, + type, + message, + System.currentTimeMillis() + ) + checkForFlaggedText(player.name, message) + dispatch(event) + } + + @JvmStatic fun logTrade(player1: Player, player2: Player, container1: Container, container2: Container) { + val container1String = StringBuilder() + val container2String = StringBuilder() + + for (item in container1.toArray()) { + item ?: continue + container1String.append(getItemName(item.id) + "(${item.amount}), ") + } + + for (item in container2.toArray()) { + item ?: continue + container2String.append(getItemName(item.id) + "(${item.amount}), ") + } + + val event = LogEvent.TradeLog( + player1.name, + player1.details.uid, + player2.name, + player2.details.uid, + container1String.toString(), + container2String.toString(), + System.currentTimeMillis() + ) + dispatch(event) + } + + @JvmStatic fun logPrivateChat(sender: Player, receiver: String, message: String) { + val event = LogEvent.ChatLog( + sender.name, + sender.details.uid, + "private", + "=> $receiver: $message", + System.currentTimeMillis() + ) + checkForFlaggedText(sender.name, message) + dispatch(event) + } + + @JvmStatic fun log(player: Player, type: LogType, details: String) { + val event = LogEvent.MiscLog( + player.name, + player.details.uid, + type.token, + details, + System.currentTimeMillis() + ) + dispatch(event) + } + + @JvmStatic fun logXpGains(player: Player, xpDiff: List>) { + if (player.isArtificial) return + if (xpDiff.isEmpty()) return + val query = StringBuilder("INSERT INTO xp_gains(player,uid,") + val xpNames = StringBuilder() + val xpAmounts = StringBuilder() + for ((skillId, amount) in xpDiff) { + xpNames.append(Skills.SKILL_NAME[skillId].lowercase() + ",") + xpAmounts.append("$amount,") + } + query.append(xpNames) + query.append("timestamp) VALUES(") + query.append("'" + player.name + "',") + query.append(player.details.uid.toString() + ",") + query.append(xpAmounts) + query.append(System.currentTimeMillis().toString()) + query.append(");") + dispatch(LogEvent.XpLog(query.toString())) + } + + private fun dispatch(event: LogEvent) { + eventQueue.put(event) + if (eventQueue.size >= 50) { + processQueuedEvents() + } + } + + fun init () { + if (!this::db.isInitialized) { + var path = ServerConstants.LOGS_PATH + "playerlogs.db" + db = SQLiteProvider(path, expectedTables) + db.initTables() + } + } + + fun processQueuedEvents() { + init() + if (activeTask?.isActive == true) + return + + activeTask = db.runAsync { + while (eventQueue.isNotEmpty()) + process(eventQueue.take(), it) + } + } + + @JvmStatic fun flushRemainingEventsImmediately() { + core.api.log(this::class.java, Log.FINE, "Flushing player log events...") + init() + if (activeTask != null) + activeTask?.cancel("Interrupted by shutdown. This is probably fine.") + db.run { + while (eventQueue.isNotEmpty()) + process(eventQueue.take(), it) + } + } + + private fun process(event: LogEvent, conn: Connection) { + when (event) { + is LogEvent.ChatLog -> { + val stmt = conn.prepareStatement(CHAT_LOG_INSERT) + stmt.setString(1, event.player) + stmt.setInt(2, event.uid) + stmt.setString(3, event.type) + stmt.setString(4, event.message) + stmt.setLong(5, event.timestamp) + stmt.execute() + } + is LogEvent.TradeLog -> { + val stmt = conn.prepareStatement(TRADE_LOG_INSERT) + stmt.setString(1, event.player1) + stmt.setString(2, event.player2) + stmt.setInt(3, event.uid1) + stmt.setInt(4, event.uid2) + stmt.setString(5, event.items1) + stmt.setString(6, event.items2) + stmt.setLong(7, event.timestamp) + stmt.execute() + } + is LogEvent.MiscLog -> { + val stmt = conn.prepareStatement(MISC_LOG_INSERT) + stmt.setString(1, event.player) + stmt.setInt(2, event.uid) + stmt.setString(3, event.type) + stmt.setString(4, event.details) + stmt.setLong(5, event.timestamp) + stmt.execute() + } + is LogEvent.XpLog -> { + val stmt = conn.createStatement() + stmt.execute(event.query) + } + is LogEvent.WealthLog -> { + val stmt = conn.prepareStatement(WEALTH_LOG_INSERT) + stmt.setString(1, event.player) + stmt.setInt(2, event.uid) + stmt.setLong(3, event.total) + stmt.setLong(4, event.diff) + stmt.setLong(5, event.timeStamp) + stmt.execute() + } + } + } + + fun checkForFlaggedText(username: String, message: String) { + if (message.contains("dupe") || message.contains("bug") || message.contains("exploit") || message.contains("glitch")) { + Discord.postPlayerAlert(username, "Flagged Chat - $message") + } + } + + private sealed class LogEvent { + data class ChatLog(val player: String, val uid: Int, val type: String, val message: String, val timestamp: Long) : LogEvent() + data class TradeLog(val player1: String, val uid1: Int, val player2 : String, val uid2: Int, val items1: String, val items2: String, val timestamp: Long) : LogEvent() + data class MiscLog(val player: String, val uid: Int, val type: String, val details: String, val timestamp: Long) : LogEvent() + data class XpLog(val query: String) : LogEvent() + data class WealthLog(val player: String, val uid: Int, val total: Long, val diff: Long, val timeStamp: Long) : LogEvent() + } + + private const val CHAT_LOG_INSERT = "INSERT INTO chat_logs(player,uid,type,message,timestamp) VALUES (?,?,?,?,?);" + private const val TRADE_LOG_INSERT = "INSERT INTO trade_logs(player_a,player_b,uid_a,uid_b,items_a,items_b,timestamp) VALUES (?,?,?,?,?,?,?);" + private const val MISC_LOG_INSERT = "INSERT INTO misc_logs(player,uid,type,details,timestamp) VALUES (?,?,?,?,?);" + private const val WEALTH_LOG_INSERT = "INSERT INTO wealth_logs(player,uid,total,diff,timestamp) VALUES (?,?,?,?,?);" + +} + +enum class LogType(val token: String) { + DUPE_ALERT("dupe_warning"), + DUEL_INFO("Duel"), + PK("PK"), + DROP_TRADE("DropTrade"), + COMMAND("CommandUsed"), + IP_LOG("login_ip") +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/player/info/RenderInfo.java b/Server/src/main/core/game/node/entity/player/info/RenderInfo.java new file mode 100644 index 0000000..3aa6a7a --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/info/RenderInfo.java @@ -0,0 +1,207 @@ +package core.game.node.entity.player.info; + +import core.ServerConstants; +import core.game.node.entity.Entity; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.world.map.Location; + +import java.util.LinkedList; +import java.util.List; + +/** + * Holds a player's render information. + * @author Emperor + */ +public final class RenderInfo { + + /** + * The player. + */ + private final Player player; + + /** + * The list of local players. + */ + private List localPlayers = new LinkedList(); + + /** + * The list of local NPCs. + */ + private List localNpcs = new LinkedList(); + + /** + * The appearance time stamps (in millisecond). + */ + private final long[] appearanceStamps = new long[ServerConstants.MAX_PLAYERS]; + + /** + * The entities requiring a mask update. + */ + private Entity[] maskUpdates = new Entity[256]; + + /** + * The mask update count. + */ + private int maskUpdateCount; + + /** + * The last location of this player. + */ + private Location lastLocation; + + /** + * If the player has just logged in. + */ + private boolean onFirstCycle = true; + + /** + * If the player has prepared appearance data this cycle. + */ + private boolean preparedAppearance; + + /** + * Constructs a new {@code RenderInfo} {@code Object}. + * @param player The player. + */ + public RenderInfo(Player player) { + this.player = player; + } + + /** + * Updates the player rendering information. + */ + public void updateInformation() { + onFirstCycle = false; + lastLocation = player.getLocation(); + preparedAppearance = false; + } + + /** + * Registers an entity requiring a mask update. + * @param entity The entity. + */ + public void registerMaskUpdate(Entity entity) { + maskUpdates[maskUpdateCount++] = entity; + } + + /** + * Gets the localNpcs. + * @return The localNpcs. + */ + public List getLocalNpcs() { + return localNpcs; + } + + /** + * Sets the localNpcs. + * @param localNpcs The localNpcs to set. + */ + public void setLocalNpcs(List localNpcs) { + this.localNpcs = localNpcs; + } + + /** + * Gets the onFirstCycle. + * @return The onFirstCycle. + */ + public boolean isOnFirstCycle() { + return onFirstCycle; + } + + /** + * Sets the onFirstCycle. + * @param onFirstCycle The onFirstCycle to set. + */ + public void setOnFirstCycle(boolean onFirstCycle) { + this.onFirstCycle = onFirstCycle; + } + + /** + * Gets the lastLocation. + * @return The lastLocation. + */ + public Location getLastLocation() { + return lastLocation; + } + + /** + * Sets the lastLocation. + * @param lastLocation The lastLocation to set. + */ + public void setLastLocation(Location lastLocation) { + this.lastLocation = lastLocation; + } + + /** + * Gets the localPlayers. + * @return The localPlayers. + */ + public List getLocalPlayers() { + return localPlayers; + } + + /** + * Sets the localPlayers. + * @param localPlayers The localPlayers to set. + */ + public void setLocalPlayers(List localPlayers) { + this.localPlayers = localPlayers; + } + + /** + * Gets the appearanceStamps. + * @return The appearanceStamps. + */ + public long[] getAppearanceStamps() { + return appearanceStamps; + } + + /** + * Gets the maskUpdateCount. + * @return The maskUpdateCount. + */ + public int getMaskUpdateCount() { + return maskUpdateCount; + } + + /** + * Sets the maskUpdateCount. + * @param maskUpdateCount The maskUpdateCount to set. + */ + public void setMaskUpdateCount(int maskUpdateCount) { + this.maskUpdateCount = maskUpdateCount; + } + + /** + * Gets the maskUpdates. + * @return The maskUpdates. + */ + public Entity[] getMaskUpdates() { + return maskUpdates; + } + + /** + * Sets the maskUpdates. + * @param maskUpdates The maskUpdates to set. + */ + public void setMaskUpdates(Entity[] maskUpdates) { + this.maskUpdates = maskUpdates; + } + + /** + * Sets the prepared appearance flag. + * @param prepared If the player has prepared appearance setting this cycle. + */ + public void setPreparedAppearance(boolean prepared) { + this.preparedAppearance = prepared; + } + + /** + * Checks if the player has prepared appearance data this cycle. + * @return {@code True} if so. + */ + public boolean preparedAppearance() { + return preparedAppearance; + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/player/info/Rights.java b/Server/src/main/core/game/node/entity/player/info/Rights.java new file mode 100644 index 0000000..c50de0e --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/info/Rights.java @@ -0,0 +1,71 @@ +package core.game.node.entity.player.info; + +import core.game.node.entity.player.Player; +import core.ServerConstants; + +/** + * Represent the rights of a player. + * @author 'Vexia + */ +public enum Rights { + REGULAR_PLAYER, PLAYER_MODERATOR, ADMINISTRATOR() { + @Override + public boolean isVisible(Player player) { + return player.getAttribute("visible_rank", ADMINISTRATOR) == ADMINISTRATOR; + } + }; + + /** + * Gets the chat icon. + * @param player The player to get the chat icon for. + * @return The chat icon. + */ + public static int getChatIcon(Player player) { + Rights c = player.getAttribute("visible_rank", player.getDetails().getRights()); + if (c != Rights.REGULAR_PLAYER && c != null) { + return c.toInteger(); + } + if (ServerConstants.IRONMAN_ICONS) { + if (player.getIronmanManager().isIronman()) { + return player.getIronmanManager().getMode().getIcon(); + } + } + return 0; + } + + /** + * Checks if the player has a hidden rank. + * @param player the player. + * @return {@code True} if hidden. + */ + public static boolean isHidden(final Player player) { + return player.getAttribute("visible_rank", player.getDetails().getRights()) != player.getDetails().getRights(); + } + + /** + * Gets the ordinal of the rights. + * @return the integer format of a rank. + */ + public final int toInteger() { + return ordinal(); + } + + /** + * Method used to get the credentials based off the id. + * @param id the id. + * @return the credential. + */ + public static Rights forId(int id) { + if (id < 0) { + id = 0; + } + return values()[id]; + } + + /** + * Checks if the player's rank is visible. + */ + public boolean isVisible(Player username) { + return true; + } +} diff --git a/Server/src/main/core/game/node/entity/player/info/UIDInfo.java b/Server/src/main/core/game/node/entity/player/info/UIDInfo.java new file mode 100644 index 0000000..706ddf9 --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/info/UIDInfo.java @@ -0,0 +1,123 @@ +package core.game.node.entity.player.info; + +import core.game.node.entity.player.Player; +import core.tools.StringUtils; + +/** + * The unique machine information of an account. + * @author Vexia + * + */ +public class UIDInfo { + + /** + * The ip address. + */ + private String ip; + + /** + * The computer name. + */ + private String compName; + + /** + * The mac-address. + */ + private String mac; + + /** + * The motherboard serial of the user. + */ + private String serial; + + /** + * Constructs a new {@code UIDInfo} {@code Object} + */ + public UIDInfo() { + /* + * empty. + */ + } + + /** + * Constructs a new {@code UIDInfo} {@code Object} + * @param ip the ip. + * @param compName the computer name. + * @param mac the mac. + * @param serial the serial. + */ + public UIDInfo(String ip, String compName, String mac, String serial) { + this.ip = ip; + this.compName = compName; + this.mac = mac.replace(":", "-"); + this.serial = serial; + } + + /** + * Translates the unique info from another object. + * @param other the other information. + */ + public void translate(UIDInfo other) { + ip = other.ip; + compName = other.compName; + mac = other.mac.replace(":", "-"); + serial = other.serial; + } + + /** + * Converts a to string in format mode for an admin or mod. + * @return the string. + */ + public String toString(Player player, Player target) { + boolean admin = player.isAdmin(); + String format = toString(); + if (!admin) {// formats for non-admins + String[] tokens = format.split("serial="); + format = format.replace("serial=", "uid=").replace(tokens[tokens.length - 1], "*****"); + } + player.sendMessage("[----------Info Debug----------]"); + String[] lines = StringUtils.splitIntoLine(format, 60); + player.sendMessages(lines); + player.sendMessage("[-------------------------------]"); + return format; + } + + /** + * Gets the compName. + * @return the compName + */ + public String getCompName() { + return compName; + } + + /** + * Gets the ip. + * @return the ip + */ + public String getIp() { + return ip; + } + + /** + * Gets the mac. + * @return the mac + */ + public String getMac() { + return mac; + } + + /** + * Gets the serial. + * @return the serial + */ + public String getSerial() { + return serial; + } + + @Override + public String toString() { + // make sure serials always at end + return "[ip=" + ip + ", compName=" + compName + ", mac=" + mac + ", serial=" + serial + "]"; + } + +} diff --git a/Server/src/main/core/game/node/entity/player/info/login/LoginConfiguration.java b/Server/src/main/core/game/node/entity/player/info/login/LoginConfiguration.java new file mode 100644 index 0000000..4fcc498 --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/info/login/LoginConfiguration.java @@ -0,0 +1,323 @@ +package core.game.node.entity.player.info.login; + +import core.game.component.CloseEvent; +import core.game.component.Component; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.emote.Emotes; +import core.game.node.item.Item; +import core.game.world.map.RegionManager; +import core.net.packet.PacketRepository; +import core.net.packet.context.InterfaceContext; +import core.net.packet.out.Interface; +import core.plugin.Plugin; +import core.ServerConstants; +import core.game.interaction.InteractionListeners; +import content.global.handlers.iface.RulesAndInfo; +import core.tools.Log; +import core.game.world.GameWorld; +import core.game.world.repository.Repository; +import core.game.world.update.UpdateSequence; +import core.game.node.entity.player.link.SpellBookManager; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Random; +import java.util.concurrent.TimeUnit; +import java.util.stream.IntStream; + +import static core.api.ContentAPIKt.*; +import static core.tools.GlobalsKt.colorize; +import content.data.Quests; + + +/** + * Sends the login configuration packets. + * + * @author Emperor + */ +public final class LoginConfiguration { + + /** + * The login plugins. + */ + private static final List> LOGIN_PLUGINS = new ArrayList<>(20); + + /** + * The lobby pane component. + */ + private static final Component LOBBY_PANE = new Component(549); + + /** + * The lobby message of the week models & constant to be set for auto selecting the models + */ + private static final int[] MESSAGE_MODEL = {15, 16, 17, 18, 19, 20, 21, 22, 23, 405, 447, 622, 623, 679, 715, 800}; + private static int messModel; + + /** + * The lobby interface close event. + */ + private static final Component LOBBY_INTERFACE = new Component(378).setCloseEvent(new CloseEvent() { + @Override + public boolean close(Player player, Component c) { + return player.getLocks().isLocked("login"); + } + }); + + /** + * Constructs a new {@Code LoginConfiguration} {@Code Object} + */ + public LoginConfiguration() { + /* + * empty. + */ + } + + /** + * Configures the lobby login. + * + * @param player The player. + */ + public static void configureLobby(Player player) { + player.updateSceneGraph(true); + if (!player.isArtificial() && player.getAttribute("tutorial:complete",false) && player.getAttribute("login_type", LoginType.NORMAL_LOGIN) != LoginType.RECONNECT_TYPE) { + sendLobbyScreen(player); + } else { + configureGameWorld(player); + } + } + + /** + * Sends the lobby interface-related packets. + * + * @param player The player. + */ + public static void sendLobbyScreen(Player player) { + messModel = autoSelect(); + for(Player p : Repository.getLobbyPlayers()){ + if(p.getName().equals(player.getName())){ + p.clear(); + Repository.getLobbyPlayers().remove(p); + break; + } + } + Repository.getLobbyPlayers().add(player); + player.getPacketDispatch().sendString(getLastLogin(player), 378, 116); + player.getPacketDispatch().sendString("Welcome to " + GameWorld.getSettings().getName(), 378, 115); + player.getPacketDispatch().sendString(" ", 378, 37); + player.getPacketDispatch().sendString("Want to stay up to date with the latest news and updates? Join our
discord by using the link below!", 378, 38); + player.getPacketDispatch().sendString(" ", 378, 39); + player.getPacketDispatch().sendString("Discord Invite", 378, 14); + player.getPacketDispatch().sendString("Discord Invite", 378, 129); + player.getPacketDispatch().sendString("Credits", 378, 94); + player.getPacketDispatch().sendString(player.getDetails().getCredits() + "", 378, 96); + player.getPacketDispatch().sendString(" ", 378, 229); + player.getPacketDispatch().sendString("Want to contribute to " + ServerConstants.SERVER_NAME + "?
Visit the GitLab using the link below!", 378, 230); + player.getPacketDispatch().sendString(" ", 378, 231); + player.getPacketDispatch().sendString("Github", 378, 240); + player.getPacketDispatch().sendString(GameWorld.getSettings().getMessage_string(), messModel, getMessageChild(messModel)); + player.getPacketDispatch().sendString("You can gain more credits by voting, reporting bugs and various other methods of contribution.", 378, 93); + player.getInterfaceManager().openWindowsPane(LOBBY_PANE); + player.getInterfaceManager().setOpened(LOBBY_INTERFACE); + PacketRepository.send(Interface.class, new InterfaceContext(player, 549, 2, 378, true)); + PacketRepository.send(Interface.class, new InterfaceContext(player, 549, 3, messModel, true));//UPDATE `configs` SET `value`=FLOOR(RAND()*(25-10)+10) WHERE key_="messageInterface" + player.getDetails().setLastLogin(System.currentTimeMillis()); + } + + /** + * Configures the game world. + * + * @param player The player. + */ + public static void configureGameWorld(final Player player) { + sendGameConfiguration(player); + Repository.getLobbyPlayers().remove(player); + player.setPlaying(true); + UpdateSequence.getRenderablePlayers().add(player); + RegionManager.move(player); + player.getMusicPlayer().init(); + player.updateAppearance(); + player.getPlayerFlags().setUpdateSceneGraph(true); + player.getPacketDispatch().sendInterfaceConfig(226, 1, true); + + if(player.getGlobalData().getTestStage() == 3 && !player.getEmoteManager().isUnlocked(Emotes.SAFETY_FIRST)){ + player.getEmoteManager().unlock(Emotes.SAFETY_FIRST); + } + + for (Item item : player.getEquipment().toArray()) { + //Run equip hooks for all items equipped on login. + //We should have already been doing this. + //Frankly, I don't even want to imagine the number of bugs us *not* doing this has caused. + if (item == null) continue; + player.getEquipment().remove(item); + if (!InteractionListeners.run(item.getId(), player, item, true) || !player.getEquipment().add(item, true, false)) { + player.sendMessage(colorize("%RAs you can no longer wear " + item.getName() + ", it has been unequipped.")); + addItemOrBank(player, item.getId(), item.getAmount()); + } + } + + SpellBookManager.SpellBook currentSpellBook = SpellBookManager.SpellBook.forInterface(player.getSpellBookManager().getSpellBook()); + if (currentSpellBook == SpellBookManager.SpellBook.ANCIENT && !hasRequirement(player, Quests.DESERT_TREASURE)) { + player.sendMessage(colorize("%RAs you can no longer use Ancient Magic, you have been set back to Modern.")); + player.getSpellBookManager().setSpellBook(SpellBookManager.SpellBook.MODERN); + } else if (currentSpellBook == SpellBookManager.SpellBook.LUNAR && !hasRequirement(player, Quests.LUNAR_DIPLOMACY)) { + player.sendMessage(colorize("%RAs you can no longer use Lunar Magic, you have been set back to Modern.")); + player.getSpellBookManager().setSpellBook(SpellBookManager.SpellBook.MODERN); + } + player.getSpellBookManager().update(player); + + // 1050 is checked client-side for making piety/chivalry disallowed sfx, likely due to the minigame requirement. + // Set it here unconditionally until the minigame is implemented. + setVarbit(player, 3909, 8, false); + if(ServerConstants.RULES_AND_INFO_ENABLED) + RulesAndInfo.openFor(player); + /*if (GameWorld.getSettings().isPvp()) { + player.getPacketDispatch().sendString("", 226, 1); + }*/ + /*if (TutorialSession.getExtension(player).getStage() != 73) { + TutorialStage.load(player, TutorialSession.getExtension(player).getStage(), true); + }*/ + } + + /** + * Sends the game configuration packets. + * + * @param player The player to send to. + */ + public static void sendGameConfiguration(final Player player) { + player.getInterfaceManager().openWindowsPane(new Component(player.getInterfaceManager().isResizable() ? 746 : 548)); + player.getInterfaceManager().openChatbox(137); + player.getInterfaceManager().openDefaultTabs(); + welcome(player); + config(player); + for (Plugin plugin : LOGIN_PLUGINS) { + try { + plugin.newInstance(player); + } catch (Throwable e) { + e.printStackTrace(); + } + } + player.getAppearance().sync(); + } + + /** + * Method used to welcome the player. + * + * @param player the player. Fullscreen mode Object id: + */ + public static final void welcome(final Player player) { + if (GameWorld.getSettings().isPvp()) { + player.getPacketDispatch().sendString("", 226, 0); + } + if (player.isArtificial()) { + + return; + } + player.getPacketDispatch().sendMessage("Welcome to " + GameWorld.getSettings().getName() + "."); + //player.getPacketDispatch().sendMessage("You are currently playing in beta version 1.2"); + if (player.getDetails().isMuted()) { + player.getPacketDispatch().sendMessage("You are muted."); + player.getPacketDispatch().sendMessage("To prevent further mutes please read the rules."); + } +// ResourceAIPManager.get().load(player); +// ResourceAIPManager.get().save(player); + } + + /** + * Method used to configure all possible settings for the player. + * + * @param player the player. + */ + public static final void config(final Player player) { + if(!player.isArtificial()) + log(LoginConfiguration.class, Log.INFO, "configuring player " + player.getUsername()); + player.getInventory().refresh(); + player.getEquipment().refresh(); + player.getSkills().refresh(); + player.getSkills().configure(); + player.getSettings().update(); + player.getInteraction().setDefault(); + player.getPacketDispatch().sendRunEnergy(); + player.getFamiliarManager().login(); + player.getInterfaceManager().openDefaultTabs(); + player.getPacketDispatch().sendString("Friends List - World " + GameWorld.getSettings().getWorldId(), 550, 3); + player.getQuestRepository().syncronizeTab(player); + player.getInterfaceManager().close(); + player.getEmoteManager().refresh(); + player.getInterfaceManager().openInfoBars(); + if(!player.isArtificial()) + log(LoginConfiguration.class, Log.INFO, "finished configuring player " + player.getUsername()); + } + + /** + * Gets the message child for the inter id. + * @notice GameSettings.kt contains the list of what these are + * @param interfaceId The interface id. + * @return The child id. + */ + public static int getMessageChild(int interfaceId) { + if (interfaceId == 622) { + return 8; + } else if (interfaceId == 16) { + return 6; + } else if (interfaceId == 17 || interfaceId == 15 || interfaceId == 18 || interfaceId == 19 || interfaceId == 21 || interfaceId == 22 || interfaceId == 447 || interfaceId == 405) { + return 4; + } else if (interfaceId == 20 || interfaceId == 623) { + return 5; + } else if (interfaceId == 23 || interfaceId == 800) { + return 3; + } else if (interfaceId == 715) { + return 2; + } else if (interfaceId == 679) { + return 1; + } + return 0; + } + + /** + * Sets a random interface id for the "message of the week" models + */ + private final static int autoSelect() { + boolean contains = IntStream.of(MESSAGE_MODEL).anyMatch(x -> x == GameWorld.getSettings().getMessage_model()); + return contains ? GameWorld.getSettings().getMessage_model():MESSAGE_MODEL[new Random().nextInt(MESSAGE_MODEL.length)]; + } + + /** + * Gets the last login string for the lobby. + * + * @param player the player. + * @return the last login. + */ + public static String getLastLogin(Player player) { + String lastIp = player.getDetails().accountInfo.getLastUsedIp(); + if (lastIp.equals("")) { + lastIp = player.getDetails().getIpAddress(); + } + player.getDetails().accountInfo.setLastUsedIp(player.getDetails().getIpAddress()); + String string = "You last logged in @timeAgo from: " + lastIp; + long time = player.getDetails().getLastLogin(); + Date lastLogin = new Date(time); + Date current = new Date(); + long diff = current.getTime() - lastLogin.getTime(); + int days = (int) TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS); + if (days < 1) { + string = string.replace("@timeAgo", "earlier today"); + } else if (days == 1) { + string = string.replace("@timeAgo", "yesterday"); + } else { + string = string.replace("@timeAgo", days + " days ago"); + } + return string; + } + + + /** + * Gets the loginPlugins. + * + * @return The loginPlugins. + */ + public static List> getLoginPlugins() { + return LOGIN_PLUGINS; + } + +} diff --git a/Server/src/main/core/game/node/entity/player/info/login/LoginParser.kt b/Server/src/main/core/game/node/entity/player/info/login/LoginParser.kt new file mode 100644 index 0000000..75eb6e4 --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/info/login/LoginParser.kt @@ -0,0 +1,104 @@ +package core.game.node.entity.player.info.login + +import core.ServerConstants +import core.api.* +import core.auth.AuthResponse +import core.game.node.entity.player.Player +import core.game.node.entity.player.info.PlayerDetails +import core.game.system.SystemManager +import core.game.system.task.Pulse +import core.game.world.GameWorld +import core.game.world.GameWorld.loginListeners +import core.game.world.repository.Repository +import java.util.function.Consumer + +/** + * Parses the login of a player. + */ +class LoginParser(val details: PlayerDetails) { + /** + * Initializes the player. + * @param player The player. + * @param reconnect If the player data should be parsed. + */ + fun initialize(player: Player, reconnect: Boolean) { + if(!validateRequest()) return + lateinit var parser: PlayerSaveParser + try { + parser = PlayerParser.parse(player) + ?: throw IllegalStateException("Failed parsing save for: " + player.username) //Parse core + } + catch (e: Exception) { + e.printStackTrace() + Repository.removePlayer(player) + flag(AuthResponse.ErrorLoadingProfile) + } + GameWorld.Pulser.submit(object : Pulse(1) { + override fun pulse(): Boolean { + try { + if (details.session.isActive) { + player.properties.spawnLocation = getAttribute(player, "/save:spawnLocation", ServerConstants.HOME_LOCATION) + loginListeners.forEach(Consumer { listener: LoginListener -> listener.login(player) }) //Run our login hooks + parser.runContentHooks() //Run our saved-content-parsing hooks + player.details.session.setObject(player) + if (reconnect) { + reconnect(player) + } else { + flag(AuthResponse.Success) + player.init() + reinitVarps(player) + } + } else { + Repository.removePlayer(player) + } + } catch (t: Throwable) { + t.printStackTrace() + Repository.removePlayer(player) + flag(AuthResponse.ErrorLoadingProfile) + } + return true + } + }) + } + + /** + * Initializes a reconnecting player. + * @param player The player. + * @param type The login type. + */ + private fun reconnect(player: Player) { + Repository.disconnectionQueue.remove(details.username) + player.initReconnect() + player.isActive = true + flag(AuthResponse.Success) + player.updateSceneGraph(true) + reinitVarps(player) + LoginConfiguration.configureGameWorld(player) + } + + /** + * Checks if the login request is valid. + * @return `True` if the request is valid. + */ + private fun validateRequest(): Boolean { + if (!details.session.isActive) { + return false + } + if (SystemManager.isUpdating()) { + return flag(AuthResponse.Updating) + } + return if (details.isBanned) { + flag(AuthResponse.AccountDisabled) + } else true + } + + /** + * Flags a response. + * @param response the [Response]. + * @return `True` if successfully logged in. + */ + fun flag(response: AuthResponse): Boolean { + details.session.write(response, true) + return response == AuthResponse.Success + } +} diff --git a/Server/src/main/core/game/node/entity/player/info/login/LoginType.java b/Server/src/main/core/game/node/entity/player/info/login/LoginType.java new file mode 100644 index 0000000..c53f280 --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/info/login/LoginType.java @@ -0,0 +1,60 @@ +package core.game.node.entity.player.info.login; + +/** + * Represents a type of {@link LoginParser} + * @author 'Vexia + * @date July-16-13 + */ +public enum LoginType { + + /** + * Represents the Login type of a default connection. + */ + NORMAL_LOGIN(16), + + /** + * Represents the Login type of a reconnection. + */ + RECONNECT_TYPE(18); + + /** + * The type of {@link LoginParser}. + */ + private int type; + + /** + * Constructs a new {@code LoginType} {@code Object}. + * @param type the type of login. + */ + LoginType(int type) { + this.setType(type); + } + + /** + * Method used to return the login type from the id sent from the client. + * @param type the type. + * @return {@link #LoginType(int)} + */ + public static LoginType fromType(int type) { + for (LoginType login : LoginType.values()) { + if (login.getType() == type) { + return login; + } + } + return null; + } + + /** + * @return the type. + */ + public int getType() { + return type; + } + + /** + * @param type the type to set. + */ + private void setType(int type) { + this.type = type; + } +} diff --git a/Server/src/main/core/game/node/entity/player/info/login/PlayerParser.java b/Server/src/main/core/game/node/entity/player/info/login/PlayerParser.java new file mode 100644 index 0000000..6eb56ff --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/info/login/PlayerParser.java @@ -0,0 +1,72 @@ +package core.game.node.entity.player.info.login; + +import core.game.node.entity.player.Player; +import core.ServerConstants; +import core.tools.Log; +import core.tools.SystemLogger; + +import java.io.*; + +import static core.api.ContentAPIKt.log; + +/** + * Class used to abstract the process of loading a player save. + * @author Ceikry + */ +public final class PlayerParser { + /** + * Parses or creates the player's save file depending on whether or not it exists. + * @param player The player. + */ + public static PlayerSaveParser parse(Player player) { + PlayerSaveParser parser = new PlayerSaveParser(player); + + try { + parser.parse(); + return parser; + } catch (Exception e){ + e.printStackTrace(); + return null; + } + } + /** + * Saves the player's details to the character file at data/players/player_name.json + * @param player The player. + */ + public static void save(Player player) { + player.setAttribute("flagged-for-save", true); + } + + public static void saveImmediately(Player player) { + new PlayerSaver(player).save(); + } + + /** + * Copies the template at data/players/template/template.json to data/players/player_name.json + * @param player the player to copy the template for. + */ + public static void makeFromTemplate(Player player){ + InputStream is = null; + OutputStream os = null; + try { + is = new FileInputStream(ServerConstants.PLAYER_SAVE_PATH + "template/template.json"); + os = new FileOutputStream(ServerConstants.PLAYER_SAVE_PATH + player.getName() + ".json"); + byte[] buffer = new byte[1024]; + int length; + while ((length = is.read(buffer)) > 0) { + os.write(buffer, 0, length); + } + } catch (Exception e){ e.printStackTrace(); + } finally { + try { + assert is != null; + is.close(); + assert os != null; + os.close(); + } catch (Exception f){ + log(PlayerParser.class, Log.ERR, "Unable to close file copiers in PlayerParser.java line 216."); + f.printStackTrace(); + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/player/info/login/PlayerSaveParser.kt b/Server/src/main/core/game/node/entity/player/info/login/PlayerSaveParser.kt new file mode 100644 index 0000000..03fc75d --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/info/login/PlayerSaveParser.kt @@ -0,0 +1,361 @@ +package core.game.node.entity.player.info.login + +import core.JSONUtils +import core.api.PersistPlayer +import core.game.node.entity.combat.spell.CombatSpell +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.IronmanMode +import core.game.node.entity.player.link.SpellBookManager +import core.game.node.entity.player.link.emote.Emotes +import core.game.node.entity.player.link.music.MusicEntry +import core.game.world.map.Location +import org.json.simple.JSONArray +import org.json.simple.JSONObject +import org.json.simple.parser.JSONParser +import core.ServerConstants +import core.api.log +import core.game.node.entity.combat.graves.GraveController +import core.game.node.entity.combat.graves.GraveType +import core.game.world.GameWorld +import core.tools.Log +import java.io.File +import java.io.FileReader +import java.util.* + +/** + * Class used for parsing JSON player saves. + * @author Ceikry + * @param player: The player we are parsing. + */ +class PlayerSaveParser(val player: Player) { + companion object { + val contentHooks = ArrayList() + } + var parser = JSONParser() + var reader: FileReader? = null + var saveFile: JSONObject? = null + var read = true + + fun parse() { + val JSON = File(ServerConstants.PLAYER_SAVE_PATH + player.name + ".json") + if(JSON.exists()) + { + reader = FileReader(JSON) + } + reader ?: log(this::class.java, Log.WARN, "Couldn't find save file for ${player.name}, or save is corrupted.").also { read = false } + if (read) { + saveFile = parser.parse(reader) as JSONObject + parseData() + } + } + + fun parseData() { + parseVersion() + parseCore() + parseAttributes() + parseSkills() + parseSettings() + parseQuests() + parseAppearance() + parseGrave() + parseVarps() + parseSpellbook() + parseSavedData() + parseAutocastSpell() + parseFarming() + parseConfigs() + parseMonitor() + parseMusic() + parseFamiliars() + parseBankPin() + parseHouse() + parseIronman() + parseEmoteManager() + parseStatistics() + parseAchievements() + parsePouches() + } + + fun runContentHooks() + { + if(read) + contentHooks.forEach{it.parsePlayer(player, saveFile!!)} + player.details.saveParsed = true + } + + fun parseVarps(){ + if(saveFile!!.containsKey("varps")) + player.varpManager.parse(saveFile!!["varps"] as JSONArray) + } + + fun parsePouches() { + if (saveFile!!.containsKey("pouches")) + player.pouchManager.parse(saveFile!!["pouches"] as JSONArray) + } + + fun parseAttributes() { + if (saveFile!!.containsKey("attributes")) { + val attrData = saveFile!!["attributes"] as JSONArray + for (a in attrData) { + val attr = a as JSONObject + val key = attr["key"].toString() + val type = attr["type"].toString() + val isExpirable = attr.getOrDefault("expirable",false) as Boolean + if(isExpirable){ + val expireTime = attr["expiration-time"].toString().toLong() + if(expireTime < System.currentTimeMillis()) continue + + player.gameAttributes.keyExpirations[key] = expireTime + } + player.gameAttributes.savedAttributes.add(key) + player.gameAttributes.attributes.put(key, when (type) { + "int" -> attr["value"].toString().toInt() + "str" -> attr["value"].toString() + "short" -> attr["value"].toString().toShort() + "long" -> attr["value"].toString().toLong() + "bool" -> attr["value"] as Boolean + "byte" -> Base64.getDecoder().decode(attr["value"].toString())[0] + "location" -> Location.fromString(attr["value"].toString()) + else -> null.also { log(this::class.java, Log.WARN, "Invalid data type for key: $key in PlayerSaveParser.kt Line 115") } + }) + } + } else { + player.gameAttributes.parse(player.name + ".xml") + } + } + + fun parseStatistics() { + if (saveFile!!.containsKey("statistics")) { + val stats: JSONArray = saveFile!!["statistics"] as JSONArray + for (stat in stats) { + val s = stat as JSONObject + val index = (s.get("index") as String).toInt() + val value = (s.get("value") as String).toInt() + } + } + } + + fun parseEmoteManager() { + if (saveFile!!.containsKey("emoteData")) { + val emoteData: JSONArray = saveFile!!["emoteData"] as JSONArray + for (emote in emoteData) { + val e = Emotes.values()[(emote as String).toInt()] + if (!player.emoteManager.emotes.contains(e)) { + player.emoteManager.emotes.add(e) + } + } + } + } + + fun parseIronman() { + if (saveFile!!.containsKey("ironManMode")) { + val ironmanMode = (saveFile!!["ironManMode"] as String).toInt() + player.ironmanManager.mode = IronmanMode.values()[ironmanMode] + } + } + + fun parseAchievements() { + if (saveFile!!.containsKey("achievementDiaries")) { + val achvData = saveFile!!["achievementDiaries"] as JSONArray + player.achievementDiaryManager.parse(achvData) + } else { + player.achievementDiaryManager.resetRewards() + } + } + + fun parseHouse() { + val houseData = saveFile!!["houseData"] as JSONObject + player.houseManager.parse(houseData) + } + + fun parseBankPin() { + val bpData = saveFile!!["bankPinManager"] as JSONObject + player.bankPinManager.parse(bpData) + } + + fun parseFamiliars() { + val familiarData = saveFile!!["familiarManager"] as JSONObject + player.familiarManager.parse(familiarData) + } + + fun parseMusic() { + val unlockedSongs = saveFile!!["unlockedMusic"] as JSONArray + for (song in unlockedSongs) { + val s = (song as String).toInt() + val entry = MusicEntry.forId(s) + player.musicPlayer.unlocked.put(entry.index, entry) + } + } + + fun parseMonitor() { + } + + fun parseConfigs() { + val configs = saveFile!!["configs"] as? JSONArray ?: return + for (config in configs) { + val c = config as JSONObject + val index = (c.get("index") as String).toInt() + if(index == 1048) continue + val value = (c.get("value") as String).toInt() + player.varpMap[index] = value + } + } + + fun parseFarming() { + /*val farmingData = saveFile!!["farming"] as JSONObject + + if (farmingData.containsKey("equipment")) { + val equipmentData: JSONArray? = farmingData.get("equipment") as JSONArray + player.farmingManager.equipment.container.parse(equipmentData) + } + if (farmingData.containsKey("bins")) { + val compostData: JSONArray? = farmingData.get("bins") as JSONArray + player.farmingManager.compostManager.parse(compostData) + } + if (farmingData.containsKey("wrappers")) { + val wrapperData: JSONArray? = farmingData.get("wrappers") as JSONArray + player.farmingManager.parseWrappers(wrapperData) + } + if(farmingData.containsKey("seedlings")){ + val seedlingData = farmingData.get("seedlings") as JSONArray + player.farmingManager.seedlingManager.parse(seedlingData) + } + if(farmingData.containsKey("farmingAmuletWrapperID")){ + player.farmingManager.amuletBoundWrapper = player.farmingManager.getPatchWrapper(farmingData.get("farmingAmuletWrapperID").toString().toInt()) + }*/ + } + + fun parseAutocastSpell() { + val autocastRaw = saveFile!!["autocastSpell"] + autocastRaw ?: return + val autocast = autocastRaw as JSONObject + val book = (autocast.get("book") as String).toInt() + val spellId = (autocast.get("spellId") as String).toInt() + player.properties.autocastSpell = SpellBookManager.SpellBook.values()[book].getSpell(spellId) as CombatSpell + } + + fun parseSavedData() { + val activityData = saveFile!!["activityData"] as JSONObject + val questData = saveFile!!["questData"] as JSONObject + val globalData = saveFile!!["globalData"] as JSONObject + player.savedData.activityData.parse(activityData) + player.savedData.questData.parse(questData) + player.savedData.globalData.parse(globalData) + } + + fun parseSpellbook() { + val spellbookData = (saveFile!!["spellbook"] as String).toInt() + player.spellBookManager.setSpellBook(SpellBookManager.SpellBook.forInterface(spellbookData)) + } + + fun parseGrave() { + saveFile ?: return + val graveData = (saveFile!!["grave_type"] as? String)?.toInt() ?: return + val type = GraveType.values()[graveData] + GraveController.updateGraveType(player, type) + } + + fun parseAppearance() { + saveFile ?: return + val appearanceData = saveFile!!["appearance"] as JSONObject + player.appearance.parse(appearanceData) + } + + fun parseQuests() { + saveFile ?: return + val questData = saveFile!!["quests"] as JSONObject + player.questRepository.parse(questData) + } + + fun parseCore() { + saveFile ?: return + val coreData = saveFile!!["core_data"] as JSONObject + val inventory = coreData["inventory"] as JSONArray + val bank = coreData["bank"] as JSONArray + val bankSecondary = coreData.getOrDefault("bankSecondary", JSONArray()) as JSONArray + val equipment = coreData["equipment"] as JSONArray + val bBars = coreData["blastBars"] as? JSONArray + val bOre = coreData["blastOre"] as? JSONArray + val bCoal = coreData["blastCoal"] as? JSONArray + val varpData = coreData["varp"] as? JSONArray + val timerData = coreData["timers"] as? JSONObject + val location = coreData["location"] as String + val bankTabData = coreData["bankTabs"] + if (bankTabData != null) { + val tabData = bankTabData as JSONArray + for (i in tabData) { + i ?: continue + val tab = i as JSONObject + val index = tab["index"].toString().toInt() + val startSlot = tab["startSlot"].toString().toInt() + player.bankPrimary.tabStartSlot[index] = startSlot + } + } + val bankTabSecondaryData = coreData["bankTabsSecondary"] + if (bankTabSecondaryData != null) { + val tabData = bankTabSecondaryData as JSONArray + for (i in tabData) { + i ?: continue + val tab = i as JSONObject + val index = tab["index"].toString().toInt() + val startSlot = tab["startSlot"].toString().toInt() + player.bankSecondary.tabStartSlot[index] = startSlot + } + } + player.useSecondaryBank = coreData.getOrDefault("useSecondaryBank", false) as Boolean + player.inventory.parse(inventory) + player.bankPrimary.parse(bank) + player.bankSecondary.parse(bankSecondary) + player.equipment.parse(equipment) + player.location = JSONUtils.parseLocation(location) + + if (varpData != null) { + for (e in varpData) { + e ?: continue + val varp = e as JSONObject + val index = varp["index"]?.toString()?.toInt() ?: continue + val value = varp["value"]?.toString()?.toInt() ?: continue + player.varpMap[index] = value + player.saveVarp[index] = true + } + } + + if (timerData != null) + player.timers.parseTimers(timerData) + } + + fun parseSkills() { + saveFile ?: return + val skillData = saveFile!!["skills"] as JSONArray + player.skills.parse(skillData) + player.skills.experienceGained = saveFile!!["totalEXP"].toString().toDouble() + player.skills.experienceMultiplier = saveFile!!["exp_multiplier"].toString().toDouble() + if (GameWorld.settings?.default_xp_rate != 5.0) { + player.skills.experienceMultiplier = GameWorld.settings?.default_xp_rate!! + } + val divisor: Double + if(player.skills.experienceMultiplier >= 10 && !player.attributes.containsKey("permadeath")){ //exclude permadeath HCIMs from XP squish + divisor = player.skills.experienceMultiplier / 5.0 + player.skills.correct(divisor) + } + if (saveFile!!.containsKey("milestone")) { + val milestone: JSONObject = saveFile!!["milestone"] as JSONObject + player.skills.combatMilestone = (milestone.get("combatMilestone")).toString().toInt() + player.skills.skillMilestone = (milestone.get("skillMilestone")).toString().toInt() + } + } + + fun parseSettings() { + saveFile ?: return + val settingsData = saveFile!!["settings"] as JSONObject + player.settings.parse(settingsData) + } + + fun parseVersion() { + saveFile ?: return + player.version = 0 + if (saveFile!!.containsKey("version")) { + player.version = saveFile!!["version"].toString().toInt() + } + } +} diff --git a/Server/src/main/core/game/node/entity/player/info/login/PlayerSaver.kt b/Server/src/main/core/game/node/entity/player/info/login/PlayerSaver.kt new file mode 100644 index 0000000..11c15b4 --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/info/login/PlayerSaver.kt @@ -0,0 +1,646 @@ +package core.game.node.entity.player.info.login + +import content.global.skill.summoning.familiar.BurdenBeast +import content.global.skill.summoning.pet.Pet +import core.ServerConstants +import core.api.PersistPlayer +import core.api.log +import core.game.container.Container +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.IronmanMode +import core.game.node.entity.skill.Skills +import core.game.world.map.Location +import core.tools.Log +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.withContext +import org.json.simple.JSONArray +import org.json.simple.JSONObject +import java.io.File +import java.io.FileWriter +import java.io.IOException +import javax.script.ScriptEngineManager +import java.util.* + + +/** + * Class used for saving the player's data in JSON format. + * Files are saved in the directory defined in ServerConstants.PLAYER_SAVE_PATH + * @param player: the player to save for. + * @author Ceikry + */ +class PlayerSaver (val player: Player){ + companion object { + val contentHooks = ArrayList() + } + fun populate(): JSONObject { + val saveFile = JSONObject() + saveVersion(saveFile) + saveCoreData(saveFile) + saveSkills(saveFile) + saveSettings(saveFile) + saveQuests(saveFile) + saveAppearance(saveFile) + saveSpellbook(saveFile) + saveSavedData(saveFile) + saveAutocast(saveFile) + savePlayerMonitor(saveFile) + saveMusicPlayer(saveFile) + saveFamiliarManager(saveFile) + saveBankPinData(saveFile) + saveHouseData(saveFile) + saveAchievementData(saveFile) + saveIronManData(saveFile) + saveEmoteData(saveFile) + saveStatManager(saveFile) + saveAttributes(saveFile) + savePouches(saveFile) + contentHooks.forEach { it.savePlayer(player, saveFile) } + return saveFile + } + fun save() = runBlocking { + if (!player.details.saveParsed) return@runBlocking + val json: String + if (ServerConstants.JAVA_VERSION < 11) { + val manager = ScriptEngineManager() + val scriptEngine = manager.getEngineByName("JavaScript") + if (scriptEngine == null) { + log(this::class.java, Log.ERR, "Cannot save: Failed to load ScriptEngineManager, this is a known issue on non Java-11 versions. Set your Java version to 11 to avoid further bugs!") + return@runBlocking + } + scriptEngine.put("jsonString", populate().toJSONString()) + scriptEngine.eval("result = JSON.stringify(JSON.parse(jsonString), null, 2)") + json = scriptEngine["result"] as String + } else json = populate().toJSONString() + + try { + if(!File("${ServerConstants.PLAYER_SAVE_PATH}${player.name}.json").exists()){ + File("${ServerConstants.PLAYER_SAVE_PATH}").mkdirs() + withContext(Dispatchers.IO) { + File("${ServerConstants.PLAYER_SAVE_PATH}${player.name}.json").createNewFile() + } + } + withContext(Dispatchers.IO) { + FileWriter("${ServerConstants.PLAYER_SAVE_PATH}${player.name}.json").use { file -> + file.write(json) + file.flush() + } + } + } catch (e: IOException) { + e.printStackTrace() + } + } + + fun savePouches(root: JSONObject){ + player.pouchManager.save(root) + } + + fun saveVersion(root: JSONObject){ + root.put("version", player.version) + } + + fun saveAttributes(root: JSONObject){ + if(player.gameAttributes.savedAttributes.isNotEmpty()){ + val attrs = JSONArray() + for(key in player.gameAttributes.savedAttributes){ + val value = player.gameAttributes.attributes[key] + value ?: continue + val isExpirable = player.gameAttributes.keyExpirations.containsKey(key) + val attr = JSONObject() + val type = when(value){ + is Int -> "int" + is Boolean -> "bool" + is Long -> "long" + is Short -> "short" + is String -> "str" + is Byte -> "byte" + is Location -> "location" + else -> "null".also { log(this::class.java, Log.WARN, "Invalid attribute type for key: $key in PlayerSaver.kt Line 115") } + } + attr.put("type",type) + attr.put("key",key) + if(value is Byte){ + val asString = Base64.getEncoder().encodeToString(byteArrayOf(value)) + attr.put("value",asString) + } else { + attr.put("value", if (value is Boolean) value else value.toString()) + } + if(isExpirable){ + attr.put("expirable",true) + attr.put("expiration-time",player.gameAttributes.keyExpirations[key].toString()) + } + attrs.add(attr) + } + root.put("attributes",attrs) + } + } + + fun saveStatManager(root: JSONObject){ + val statistics = JSONArray() + var index = 0 + root.put("statistics",statistics) + } + + fun saveEmoteData(root: JSONObject){ + if(player.emoteManager.isSaveRequired) { + val emoteData = JSONArray() + player.emoteManager.emotes.map { + emoteData.add(it.ordinal.toString()) + } + root.put("emoteData",emoteData) + } + } + + fun saveIronManData(root: JSONObject){ + if(player.ironmanManager.mode != IronmanMode.NONE){ + root.put("ironManMode",player.ironmanManager.mode.ordinal.toString()) + } + } + + fun saveAchievementData(root: JSONObject){ + val achievementData = JSONArray() + player.achievementDiaryManager.diarys.map { + val diary = JSONObject() + val startedLevels = JSONArray() + it.levelStarted.map { + startedLevels.add(it) + } + diary.put("startedLevels",startedLevels) + val completedLevels = JSONArray() + it.taskCompleted.map { + val level = JSONArray() + it.map { + level.add(it) + } + completedLevels.add(level) + } + diary.put("completedLevels",completedLevels) + val rewardedLevels = JSONArray() + it.levelRewarded.map { + rewardedLevels.add(it) + } + diary.put("rewardedLevels",rewardedLevels) + val diaryCollector = JSONObject() + diaryCollector.put(it.type.name, diary) + achievementData.add(diaryCollector) + } + root.put("achievementDiaries",achievementData) + } + + fun saveHouseData(root: JSONObject){ + val manager = player.houseManager + val houseData = JSONObject() + houseData.put("location",manager.location.ordinal.toString()) + houseData.put("style",manager.style.ordinal.toString()) + if(manager.hasServant()){ + val servant = JSONObject() + servant.put("type",manager.servant.type.ordinal.toString()) + servant.put("uses",manager.servant.uses.toString()) + if(manager.servant.item != null){ + val item = JSONObject() + item.put("id",manager.servant.item.id.toString()) + item.put("amount",manager.servant.item.amount.toString()) + servant.put("item",item) + } + servant.put("greet",manager.servant.isGreet) + houseData.put("servant",servant) + } + val rooms = JSONArray() + var z = 0 + for(room in player.houseManager.rooms){ + var x = 0 + for(xr in room){ + var y = 0 + for(yr in xr){ + if(yr != null) { + val r = JSONObject() + r.put("z", z.toString()) + r.put("x", x.toString()) + r.put("y", y.toString()) + r.put("properties", yr.properties.ordinal.toString()) + r.put("rotation", yr.rotation.toInteger().toString()) + val hotspots = JSONArray() + var hotspotIndex = 0 + yr.hotspots.map { + if (it.decorationIndex > -1) { + val hotspot = JSONObject() + hotspot.put("hotspotIndex", hotspotIndex.toString()) + hotspot.put("decorationIndex", it.decorationIndex.toString()) + hotspots.add(hotspot) + } + hotspotIndex++ + } + r.put("hotspots", hotspots) + rooms.add(r) + } + y++ + } + x++ + } + z++ + } + houseData.put("rooms",rooms) + root.put("houseData",houseData) + } + + fun saveBankPinData(root: JSONObject){ + val bankPinManager = JSONObject() + if(player.bankPinManager.hasPin()){ + bankPinManager.put("pin",player.bankPinManager.pin.toString()) + } + bankPinManager.put("longRecovery",player.bankPinManager.isLongRecovery) + if(player.bankPinManager.status.ordinal != 0){ + bankPinManager.put("status",player.bankPinManager.status.ordinal.toString()) + } + if(player.bankPinManager.pendingDelay != -1L && player.bankPinManager.pendingDelay > System.currentTimeMillis()){ + bankPinManager.put("pendingDelay",player.bankPinManager.pendingDelay.toString()) + } + if(player.bankPinManager.tryDelay > System.currentTimeMillis()){ + bankPinManager.put("tryDelay",player.bankPinManager.tryDelay.toString()) + } + root.put("bankPinManager",bankPinManager) + } + + fun saveFamiliarManager(root: JSONObject){ + val familiarManager = JSONObject() + val petDetails = JSONObject() + player.familiarManager.petDetails.map { + val petId = it.key + val petData = JSONArray() + for (v in it.value) { + val pet = JSONObject() + pet.put("hunger",v.hunger.toString()) + pet.put("growth",v.growth.toString()) + petData.add(pet) + } + petDetails.put(petId.toString(), petData) + } + familiarManager.put("petDetails",petDetails) + if(player.familiarManager.hasPet()){ + familiarManager.put("currentPet",(player.familiarManager.familiar as Pet).getItemId().toString()) + } else if (player.familiarManager.hasFamiliar()){ + val familiar = JSONObject() + familiar.put("originalId",player.familiarManager.familiar.originalId.toString()) + familiar.put("ticks",player.familiarManager.familiar.ticks.toString()) + familiar.put("specialPoints",player.familiarManager.familiar.specialPoints.toString()) + if(player.familiarManager.familiar.isBurdenBeast && !(player.familiarManager.familiar as BurdenBeast).container.isEmpty){ + val familiarInventory = saveContainer((player.familiarManager.familiar as BurdenBeast).container) + familiar.put("inventory",familiarInventory) + } + familiar.put("lifepoints",player.familiarManager.familiar.skills.lifepoints) + familiarManager.put("familiar",familiar) + + } + root.put("familiarManager",familiarManager) + } + + fun saveMusicPlayer(root: JSONObject){ + val unlockedMusic = JSONArray() + player.musicPlayer.unlocked.values.map { + unlockedMusic.add(it.id.toString()) + } + root.put("unlockedMusic",unlockedMusic) + } + + fun savePlayerMonitor(root: JSONObject){ + + } + + fun saveAutocast(root: JSONObject){ + player.properties.autocastSpell ?: return + val spell = JSONObject() + spell.put("book",player.properties.autocastSpell.book.ordinal.toString()) + spell.put("spellId",player.properties.autocastSpell.spellId.toString()) + root.put("autocastSpell",spell) + } + + fun saveSavedData(root: JSONObject) { + saveActivityData(root) + saveQuestData(root) + saveGlobalData(root) + } + + fun saveGlobalData(root: JSONObject){ + val globalData = JSONObject() + globalData.put("tutorialStage",player.savedData.globalData.tutorialStage.toString()) + globalData.put("homeTeleportDelay",player.savedData.globalData.homeTeleportDelay.toString()) + globalData.put("lumbridgeRope",player.savedData.globalData.hasTiedLumbridgeRope()) + globalData.put("apprentice",player.savedData.globalData.hasSpokenToApprentice()) + globalData.put("assistTime",player.savedData.globalData.assistTime.toString()) + val assistExperience = JSONArray() + player.savedData.globalData.assistExperience.map { + assistExperience.add(it.toString()) + } + globalData.put("assistExperience",assistExperience) + val strongholdRewards = JSONArray() + player.savedData.globalData.strongHoldRewards.map { + strongholdRewards.add(it) + } + globalData.put("strongHoldRewards",strongholdRewards) + globalData.put("chatPing",player.savedData.globalData.chatPing.toString()) + globalData.put("tutorClaim",player.savedData.globalData.tutorClaim.toString()) + globalData.put("luthasTask",player.savedData.globalData.isLuthasTask) + globalData.put("karamjaBananas",player.savedData.globalData.karamjaBananas.toString()) + globalData.put("silkSteal",player.savedData.globalData.silkSteal.toString()) + globalData.put("zafAmount",player.savedData.globalData.zaffAmount.toString()) + globalData.put("zafTime",player.savedData.globalData.zafTime.toString()) + globalData.put("fritzGlass",player.savedData.globalData.isFritzGlass) + globalData.put("wydinEmployee",player.savedData.globalData.isWydinEmployee) + globalData.put("draynorRecording",player.savedData.globalData.isDraynorRecording) + globalData.put("geTutorial",player.savedData.globalData.isGeTutorial) + globalData.put("essenceTeleporter",player.savedData.globalData.essenceTeleporter.toString()) + globalData.put("recoilDamage",player.savedData.globalData.recoilDamage.toString()) + globalData.put("doubleExpDelay",player.savedData.globalData.doubleExpDelay.toString()) + globalData.put("joinedMonastery",player.savedData.globalData.isJoinedMonastery) + val readPlaques = JSONArray() + player.savedData.globalData.readPlaques.map { + readPlaques.add(it) + } + globalData.put("readPlaques",readPlaques) + globalData.put("forgingUses",player.savedData.globalData.forgingUses.toString()) + globalData.put("ectoCharges",player.savedData.globalData.ectoCharges.toString()) + globalData.put("dropDelay",player.savedData.globalData.dropDelay.toString()) + val abyssData = JSONArray() + player.savedData.globalData.abyssData.map { + abyssData.add(it) + } + globalData.put("abyssData",abyssData) + val rcDecays = JSONArray() + player.savedData.globalData.rcDecays.map { + rcDecays.add(it.toString()) + } + globalData.put("rcDecays",rcDecays) + globalData.put("disableDeathScreen",player.savedData.globalData.isDeathScreenDisabled) + globalData.put("playerTestStage",player.savedData.globalData.playerTestStage.toString()) + globalData.put("charmingDelay",player.savedData.globalData.charmingDelay.toString()) + val travelLogs = JSONArray() + player.savedData.globalData.travelLogs.map { + travelLogs.add(it) + } + globalData.put("travelLogs",travelLogs) + val godBooks = JSONArray() + player.savedData.globalData.godBooks.map { + godBooks.add(it) + } + globalData.put("godBooks",godBooks) + globalData.put("disableNews",player.savedData.globalData.isDisableNews) + val godPages = JSONArray() + player.savedData.globalData.godPages.map { + godPages.add(it) + } + globalData.put("godPages",godPages) + globalData.put("overChargeDelay",player.savedData.globalData.overChargeDelay.toString()) + val bossCounters = JSONArray() + player.savedData.globalData.bossCounters.map { + bossCounters.add(it.toString()) + } + globalData.put("bossCounters",bossCounters) + globalData.put("barrowsLoots",player.savedData.globalData.barrowsLoots.toString()) + globalData.put("lootSharePoints",player.savedData.globalData.lootSharePoints.toString()) + globalData.put("lootShareDelay",player.savedData.globalData.lootShareDelay.toString()) + globalData.put("doubleExp",player.savedData.globalData.doubleExp.toString()) + globalData.put("globalTeleporterDelay",player.savedData.globalData.globalTeleporterDelay.toString()) + globalData.put("starSpriteDelay",player.savedData.globalData.starSpriteDelay.toString()) + globalData.put("runReplenishDelay",player.savedData.globalData.runReplenishDelay.toString()) + globalData.put("runReplenishCharges",player.savedData.globalData.runReplenishCharges.toString()) + globalData.put("lowAlchemyCharges",player.savedData.globalData.lowAlchemyCharges.toString()) + globalData.put("lowAlchemyDelay",player.savedData.globalData.lowAlchemyDelay.toString()) + globalData.put("magicSkillCapeDelay",player.savedData.globalData.magicSkillCapeDelay.toString()) + globalData.put("hunterCapeDelay",player.savedData.globalData.hunterCapeDelay.toString()) + globalData.put("hunterCapeCharges",player.savedData.globalData.hunterCapeCharges.toString()) + globalData.put("taskAmount",player.savedData.globalData.taskAmount.toString()) + globalData.put("taskPoints",player.savedData.globalData.taskPoints.toString()) + globalData.put("macroDisabled",player.savedData.globalData.macroDisabled) + root.put("globalData",globalData) + } + + fun saveQuestData(root: JSONObject){ + val questData = JSONObject() + val draynorLever = JSONArray() + player.savedData.questData.draynorLever.map { + draynorLever.add(it) + } + questData.put("draynorLever",draynorLever) + val dslayer = JSONArray() + player.savedData.questData.dragonSlayer.map { + dslayer.add(it) + } + questData.put("dragonSlayer",dslayer) + questData.put("dragonSlayerPlanks",player.savedData.questData.dragonSlayerPlanks.toString()) + val demonSlayer = JSONArray() + player.savedData.questData.demonSlayer.map { + demonSlayer.add(it) + } + questData.put("demonSlayer",demonSlayer) + val cooksAssistant = JSONArray() + player.savedData.questData.cooksAssistant.map { + cooksAssistant.add(it) + } + questData.put("cooksAssistant",cooksAssistant) + questData.put("gardenerAttack",player.savedData.questData.isGardenerAttack) + questData.put("talkedDrezel",player.savedData.questData.isTalkedDrezel) + val desertTreasureNode = JSONArray() + player.savedData.questData.desertTreasure.map { + val item = JSONObject() + item.put("id",it.id.toString()) + item.put("amount",it.amount.toString()) + desertTreasureNode.add(item) + } + questData.put("desertTreasureNode",desertTreasureNode) + questData.put("witchsExperimentStage",player.savedData.questData.witchsExperimentStage.toString()) + questData.put("witchsExperimentKilled",player.savedData.questData.isWitchsExperimentKilled) + root.put("questData",questData) + } + + fun saveActivityData(root: JSONObject){ + val activityData = JSONObject() + activityData.put("pestPoints",player.savedData.activityData.pestPoints.toString()) + activityData.put("warriorGuildTokens",player.savedData.activityData.warriorGuildTokens.toString()) + activityData.put("bountyHunterRate",player.savedData.activityData.bountyHunterRate.toString()) + activityData.put("bountyRogueRate",player.savedData.activityData.bountyRogueRate.toString()) + activityData.put("barrowKills",player.savedData.activityData.barrowKills.toString()) + val barrowBrothers = JSONArray() + player.savedData.activityData.barrowBrothers.map { + barrowBrothers.add(it) + } + activityData.put("barrowBrothers",barrowBrothers) + activityData.put("barrowTunnelIndex",player.savedData.activityData.barrowTunnelIndex.toString()) + activityData.put("kolodionStage",player.savedData.activityData.kolodionStage.toString()) + val godCasts = JSONArray() + player.savedData.activityData.godCasts.map { + godCasts.add(it.toString()) + } + activityData.put("godCasts",godCasts) + activityData.put("kolodionBoss",player.savedData.activityData.kolodionBoss.toString()) + activityData.put("elnockSupplies",player.savedData.activityData.isElnockSupplies) + activityData.put("lastBorkBattle",player.savedData.activityData.lastBorkBattle.toString()) + activityData.put("startedMta",player.savedData.activityData.isStartedMta) + activityData.put("lostCannon",player.savedData.activityData.isLostCannon) + val pizazzPoints = JSONArray() + player.savedData.activityData.pizazzPoints.map { + pizazzPoints.add(it.toString()) + } + activityData.put("pizazzPoints",pizazzPoints) + activityData.put("bonesToPeaches",player.savedData.activityData.isBonesToPeaches) + activityData.put("solvedMazes",player.savedData.activityData.solvedMazes.toString()) + activityData.put("fogRating",player.savedData.activityData.fogRating.toString()) + activityData.put("borkKills",player.savedData.activityData.borkKills.toString()) + activityData.put("hardcoreDeath",player.savedData.activityData.hardcoreDeath) + activityData.put("topGrabbed",player.savedData.activityData.isTopGrabbed) + root.put("activityData",activityData) + } + + fun saveSpellbook(root: JSONObject){ + root.put("spellbook",player.spellBookManager.spellBook.toString()) + } + + fun saveAppearance(root: JSONObject){ + val appearance = JSONObject() + appearance.put("gender",player.appearance.gender.toByte().toString()) + val appearanceCache = JSONArray() + player.appearance.appearanceCache.map { + val bodyPart = JSONObject() + bodyPart.put("look",it.look.toString()) + bodyPart.put("color",it.color.toString()) + appearanceCache.add(bodyPart) + } + appearance.put("appearance_cache", appearanceCache) + root.put("appearance",appearance) + } + + fun saveQuests(root: JSONObject){ + val quests = JSONObject() + quests.put("points",player.questRepository.points.toString()) + val questStages = JSONArray() + player.questRepository.questList.map { + val quest = JSONObject() + quest.put("questId",it.key.toString()) + quest.put("questStage",it.value.toString()) + questStages.add(quest) + } + quests.put("questStages",questStages) + root.put("quests",quests) + } + + fun saveSettings(root: JSONObject){ + val settings = JSONObject() + settings.put("brightness",player.settings.brightness.toString()) + settings.put("musicVolume",player.settings.musicVolume.toString()) + settings.put("soundEffectVolume",player.settings.soundEffectVolume.toString()) + settings.put("areaSoundVolume",player.settings.areaSoundVolume.toString()) + settings.put("publicChatSetting",player.settings.publicChatSetting.toString()) + settings.put("privateChatSetting",player.settings.privateChatSetting.toString()) + settings.put("clanChatSetting",player.settings.clanChatSetting.toString()) + settings.put("tradeSetting",player.settings.tradeSetting.toString()) + settings.put("assistSetting",player.settings.assistSetting.toString()) + settings.put("runEnergy",player.settings.runEnergy.toString()) + settings.put("specialEnergy",player.settings.specialEnergy.toString()) + settings.put("attackStyle",player.settings.attackStyleIndex.toString()) + settings.put("singleMouse",player.settings.isSingleMouseButton) + settings.put("disableChatEffects",player.settings.isDisableChatEffects) + settings.put("splitPrivate",player.settings.isSplitPrivateChat) + settings.put("acceptAid",player.settings.isAcceptAid) + settings.put("runToggled",player.settings.isRunToggled) + settings.put("retaliation",player.properties.isRetaliating) + root.put("settings",settings) + } + + fun saveSkills(root: JSONObject){ + val skills = JSONArray() + for(i in 0 until 24){ + val skill = JSONObject() + skill.put("id",i.toString()) + skill.put("static",player.skills.staticLevels[i].toString()) + skill.put("dynamic",player.skills.dynamicLevels[i].toString()) + if (i == Skills.HITPOINTS) { + skill.put("lifepoints",player.skills.lifepoints.toString()) + } + if (i == Skills.PRAYER) { + skill.put("prayerPoints",player.skills.prayerPoints.toString()) + } + skill.put("experience",player.skills.getExperience(i).toString()) + skills.add(skill) + } + root.put("skills",skills) + root.put("totalEXP",player.skills.experienceGained.toString()) + root.put("exp_multiplier",player.skills.experienceMultiplier.toString()) + if(player.skills.combatMilestone > 0 || player.skills.skillMilestone > 0){ + val milestone = JSONObject() + milestone.put("combatMilestone",player.skills.combatMilestone.toString()) + milestone.put("skillMilestone",player.skills.skillMilestone.toString()) + root.put("milestone",milestone) + } + } + + fun saveContainer(container: Container): JSONArray { + val json = JSONArray() + container.toArray().map{ + if (it != null) { + val item = JSONObject() + item.put("slot", it.slot.toString()) + item.put("id", it.id.toString()) + item.put("amount", it.amount.toString()) + item.put("charge", it.charge.toString()) + json.add(item) + } + } + return json + } + + fun saveCoreData(root: JSONObject){ + val coreData = JSONObject() + val inventory = saveContainer(player.inventory) + coreData.put("inventory",inventory) + + val bank = saveContainer(player.bankPrimary) + coreData.put("bank",bank) + + val bankSecondary = saveContainer(player.bankSecondary) + coreData.put("bankSecondary",bankSecondary) + + val bankTabs = JSONArray() + for(i in player.bankPrimary.tabStartSlot.indices){ + val tab = JSONObject() + tab.put("index",i.toString()) + tab.put("startSlot",player.bankPrimary.tabStartSlot[i].toString()) + bankTabs.add(tab) + } + coreData.put("bankTabs",bankTabs) + + val bankTabsSecondary = JSONArray() + for(i in player.bankSecondary.tabStartSlot.indices){ + val tab = JSONObject() + tab.put("index",i.toString()) + tab.put("startSlot",player.bankSecondary.tabStartSlot[i].toString()) + bankTabsSecondary.add(tab) + } + coreData.put("bankTabsSecondary",bankTabsSecondary) + + coreData.put("useSecondaryBank",player.useSecondaryBank) + + val equipment = saveContainer(player.equipment) + coreData.put("equipment",equipment) + + val loctemp = player.location + val locStr = "${loctemp.x},${loctemp.y},${loctemp.z}" + coreData.put("location",locStr) + + val varpData = JSONArray() + for ((index, value) in player.varpMap) { + if (!(player.saveVarp[index] ?: false)) continue + if (value == 0) continue + + val varpObj = JSONObject() + varpObj["index"] = index.toString() + varpObj["value"] = value.toString() + varpData.add(varpObj) + } + coreData.put("varp", varpData) + + val timerData = JSONObject() + player.timers.saveTimers(timerData) + coreData.put("timers", timerData) + + root.put("core_data",coreData) + } +} diff --git a/Server/src/main/core/game/node/entity/player/info/login/Response.java b/Server/src/main/core/game/node/entity/player/info/login/Response.java new file mode 100644 index 0000000..60e6985 --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/info/login/Response.java @@ -0,0 +1,158 @@ +package core.game.node.entity.player.info.login; + +/** + * Holds the response codes during the attempt to login. + * @author Emperor + */ +public enum Response { + + /** + * An unexpected server response occurred. + */ + UNEXPECTED_RESPONSE(0), + + /** + * Could not display advertisement video, logging in in x seconds. + */ + COULD_NOT_DISPLAY_AD(1), + + /** + * A successful login. + */ + SUCCESSFUL(2), + + /** + * Invalid username or password has been entered. + */ + INVALID_CREDENTIALS(3), + + /** + * This account is banned. + */ + ACCOUNT_DISABLED(4), + + /** + * This account is already logged in. + */ + ALREADY_ONLINE(5), + + /** + * We have updated and client needs to be reloaded. + */ + UPDATED(6), + + /** + * The world is full. + */ + FULL_WORLD(7), + + /** + * Login server is offline. + */ + LOGIN_SERVER_OFFLINE(8), + + /** + * The login limit has been exceeded. + */ + LOGIN_LIMIT_EXCEEDED(9), + + /** + * The session key was invalid. + */ + BAD_SESSION_ID(10), + + /** + * The password is too weak, and should be improved. + */ + WEAK_PASSWORD(11), + + /** + * When trying to connect to a members world while being f2p. + */ + MEMBERS_WORLD(12), + + /** + * Could not login. + */ + COULD_NOT_LOGIN(13), + + /** + * The server is currently updating. + */ + UPDATING(14), + + /** + * Too many incorrect login attempts from your address. + */ + TOO_MANY_INCORRECT_LOGINS(16), + + /** + * When logging on a free world while standing in members area. + */ + STANDING_IN_MEMBER(17), + + /** + * This account is locked as it might have been stolen. + */ + LOCKED(18), + + /** + * Closed beta going on. + */ + CLOSED_BETA(19), + + /** + * The login server connected to is invalid. + */ + INVALID_LOGIN_SERVER(20), + + /** + * Moving from another world... + */ + MOVING_WORLD(21), + + /** + * When the player's saved file exists, but is unable to be loaded. + */ + ERROR_LOADING_PROFILE(24), + + /** + * This computer address is disabled as it was used to break our rules. + */ + BANNED(26); + + /** + * The buffer. + */ + private final int opcode; + + /** + * Constructs a new {@code Response} {@code Object}. + * @param opcode The login response opcode. + */ + Response(int opcode) { + this.opcode = opcode; + } + + /** + * Gets the response object for the given opcode. + * @param opcode The opcode. + * @return The response object, or null. + */ + public static Response get(int opcode) { + for (Response r : values()) { + if (r.opcode == opcode) { + return r; + } + } + return null; + } + + /** + * Gets the opcode. + * @return The opcode. + */ + public int opcode() { + return opcode; + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/player/info/login/SaveVersionHooks.kt b/Server/src/main/core/game/node/entity/player/info/login/SaveVersionHooks.kt new file mode 100644 index 0000000..fe26b8b --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/info/login/SaveVersionHooks.kt @@ -0,0 +1,88 @@ +package core.game.node.entity.player.info.login + +import content.data.Quests +import content.global.skill.summoning.pet.Pets +import content.region.kandarin.ardougne.quest.plaguecity.PlagueCity +import core.ServerConstants +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.tools.Log +import org.rs09.consts.Items +import org.rs09.consts.Vars + +/** + * Runs one-time save-version-related hooks. + * @author Player Name + */ + +class SaveVersionHooks : LoginListener { + override fun login(player: Player) { + if (player.version < ServerConstants.CURRENT_SAVEFILE_VERSION) { + log(this::class.java, Log.FINE, "Upgrading ${player.name} from ${player.version} to ${ServerConstants.CURRENT_SAVEFILE_VERSION}") + + if (player.version < 1) { // GL !1811 + // Give out crafting hoods if the player bought any crafting capes when the hoods were not obtainable + var hasHoods = 0 + var hasCapes = 0 + val searchSpace = arrayOf(player.inventory, player.bankPrimary, player.bankSecondary) + for (container in searchSpace) { + for (hood in container.getAll(Item(Items.CRAFTING_HOOD_9782))) { + hasHoods += hood.amount + } + for (id in arrayOf(Items.CRAFTING_CAPE_9780, Items.CRAFTING_CAPET_9781)) { + for (cape in container.getAll(Item(id))) { + hasCapes += cape.amount + } + } + } + val need = hasCapes - hasHoods + if (need > 0) { + sendMessage(player, "You are being given $need crafting hood(s), because we think you bought $need crafting cape(s) when the hoods were still unobtainable.") + addItemOrBank(player, Items.CRAFTING_HOOD_9782, need) + } + + // Unlock Surok's Theme if eligible + if (getQuestStage(player, Quests.WHAT_LIES_BELOW) > 70) { + player.musicPlayer.unlock(250, false) + } + + // Migrate random-event saved location attributes to the uniform naming scheme + for (old in arrayOf("/save:drilldemon:original-loc","/save:evilbob:prevlocation","/save:freakyf:location","supexam:loc")) { + val oldloc = player.getAttribute(old, player.location) + if (oldloc != player.location) { + player.setAttribute("/save:original-loc", oldloc) + } + player.removeAttribute(old) + } + + // Set the missing tutorial island varp if eligible + if (getAttribute(player, "/save:tutorial:complete", false)) { + setVarp(player, 281, 1000, true) + } + } + + if (player.version < 2) { //GL !1799 + // Most of the migration for this MR happens in FamiliarManager.java, but we fix up any pet items here + val pets = Pets.values() + for (pet in pets) { + for (id in arrayOf(pet.babyItemId, pet.grownItemId, pet.overgrownItemId)) { + replaceAllItems(player, id, id) + // The trick here is that replaceAllItems ignores the item charge value, and will hence cause it to be lost, making all pets authentically stack again + } + } + } + + if (player.version < 3) { + // Damage control on Plague city. There are a few varbits that should have been set for spawning + when (getQuestStage(player, Quests.PLAGUE_CITY)){ + in 6..98 -> setVarbit(player, Vars.VARBIT_QUEST_PLAGUE_CITY_EDMOND_TUNNELS, 1) // Edmond is in the tunnel + in 99..100 ->setVarbit(player, Vars.VARBIT_QUEST_PLAGUE_CITY_RESCUE_ELENA, 1) // Elena is free + } + } + + // Finish up + player.version = ServerConstants.CURRENT_SAVEFILE_VERSION + } + } +} diff --git a/Server/src/main/core/game/node/entity/player/info/portal/Icon.java b/Server/src/main/core/game/node/entity/player/info/portal/Icon.java new file mode 100644 index 0000000..3974af0 --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/info/portal/Icon.java @@ -0,0 +1,68 @@ +package core.game.node.entity.player.info.portal; + +/** + * Represents a chat icon. + * @author Vexia + */ +public enum Icon { + NOTHING(0, 0), + GREEN(1, 5), + RED(2, 6), + YELLOW(3, 7), + BLUE(4, 8), + ORANGE(5, 9), + PINK(6, 10), + PURPLE(7, 11), + BROWN(8, 12); + + /** + * The id. + */ + private final int id; + + /** + * The index id. + */ + private final int indexId; + + /** + * Constructs a new {@Code Icons} {@Code Object} + * @param id the id. + * @param indexId the indexid. + */ + private Icon(int id, int indexId) { + this.id = id; + this.indexId = indexId; + } + + /** + * Gets an icon for the id. + * @param id the id. + * @return the id.S + */ + public static Icon forId(int id) { + for (Icon icon : values()) { + if (icon.getId() == id) { + return icon; + } + } + return GREEN; + } + + /** + * Gets the id. + * @return the id + */ + public int getId() { + return id; + } + + /** + * Gets the indexId. + * @return the indexId + */ + public int getIndexId() { + return indexId; + } + +} diff --git a/Server/src/main/core/game/node/entity/player/link/ActivityData.java b/Server/src/main/core/game/node/entity/player/link/ActivityData.java new file mode 100644 index 0000000..b04537c --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/ActivityData.java @@ -0,0 +1,576 @@ +package core.game.node.entity.player.link; + + +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; + +import java.nio.ByteBuffer; + +/** + * Represents a managing class of activity related information. + * @author 'Vexia + */ +public final class ActivityData { + + /** + * Represents the pest points gained from pest control. + */ + private int pestPoints; + + /** + * The amount of warrior's guild tokens. + */ + private int warriorGuildTokens; + + /** + * The bounty hunter rating. + */ + private int bountyHunterRate; + + /** + * The bounty rogue rating. + */ + private int bountyRogueRate; + + /** + * The barrow brothers currently killed. + */ + private boolean[] barrowBrothers = new boolean[6]; + + /** + * The barrow kill count. + */ + private int barrowKills; + + /** + * The barrow tunnel crypt index. + */ + private int barrowTunnelIndex; + + /** + * The kolodion stage. + */ + private int kolodionStage; + + /** + * The god casts. + */ + private int[] godCasts = new int[3]; + + /** + * The kolodion boss. + */ + private int kolodionBoss; + + /** + * If received the elnock supplies. + */ + private boolean elnockSupplies; + + /** + * The time stamp of the last battle with Bork. + */ + private long lastBorkBattle; + + /** + * The amount of temp bork kills. + */ + private byte borkKills; + + /** + * If the player has lost his DMC. + */ + private boolean lostCannon; + + /** + * If we started the mta. + */ + private boolean startedMta; + + /** + * The pizazz points. + */ + private int[] pizazzPoints = new int[4]; + + /** + * If the player has unlocked bones to peaches. + */ + private boolean bonesToPeaches; + + /** + * The amount of solved telekinetic mazes. + */ + private int solvedMazes; + + /** + * The fog rating. + */ + private int fogRating; + + /** + * The death status of a Hardcore Iron Man + */ + private boolean hardcoreDeath; + + /** + * Pyramid plunder top (is it grabbed?) + */ + boolean topGrabbed; + + /** + * Constructs a new {@code ActivityInfo} {@code Object}. + */ + public ActivityData() { + /* + * empty. + */ + } + + public void parse(JSONObject data){ + pestPoints = Integer.parseInt( data.get("pestPoints").toString()); + warriorGuildTokens = Integer.parseInt( data.get("warriorGuildTokens").toString()); + bountyHunterRate = Integer.parseInt( data.get("bountyHunterRate").toString()); + bountyRogueRate = Integer.parseInt( data.get("bountyRogueRate").toString()); + barrowKills = Integer.parseInt( data.get("barrowKills").toString()); + JSONArray bb = (JSONArray) data.get("barrowBrothers"); + for(int i = 0; i < bb.size(); i++){ + barrowBrothers[i] = (boolean) bb.get(i); + } + barrowTunnelIndex = Integer.parseInt( data.get("barrowTunnelIndex").toString()); + kolodionStage = Integer.parseInt( data.get("kolodionStage").toString()); + JSONArray gc = (JSONArray) data.get("godCasts"); + for(int i = 0; i < gc.size(); i++){ + godCasts[i] = Integer.parseInt(gc.get(i).toString()); + } + kolodionBoss = Integer.parseInt( data.get("kolodionBoss").toString()); + elnockSupplies = (boolean) data.get("elnockSupplies"); + lastBorkBattle = Long.parseLong(data.get("lastBorkBattle").toString()); + startedMta = (boolean) data.get("startedMta"); + lostCannon = (boolean) data.get("lostCannon"); + JSONArray pp = (JSONArray) data.get("pizazzPoints"); + for(int i = 0 ; i < pp.size(); i++){ + pizazzPoints[i] = Integer.parseInt(pp.get(i).toString()); + } + bonesToPeaches = (boolean) data.get("bonesToPeaches"); + solvedMazes = Integer.parseInt( data.get("solvedMazes").toString()); + fogRating = Integer.parseInt( data.get("fogRating").toString()); + borkKills = Byte.parseByte(data.get("borkKills").toString()); + hardcoreDeath = (boolean) data.get("hardcoreDeath"); + topGrabbed = (boolean) data.get("topGrabbed"); + } + + /** + * Gets the elnockSupplies. + * @return The elnockSupplies. + */ + public boolean isElnockSupplies() { + return elnockSupplies; + } + + /** + * Sets the elnockSupplies. + * @param elnockSupplies The elnockSupplies to set. + */ + public void setElnockSupplies(boolean elnockSupplies) { + this.elnockSupplies = elnockSupplies; + } + + /** + * Increases the pest points. + * @param pestPoints the pest points to increase with. + */ + public void increasePestPoints(int pestPoints) { + if (pestPoints + this.pestPoints > 500) { + this.pestPoints = 500; + } else { + this.pestPoints += pestPoints; + } + } + + /** + * Decreases the pest points. + * @param pestPoints the pest points to increase with. + */ + public void decreasePestPoints(int pestPoints) { + this.pestPoints -= pestPoints; + } + + /** + * Gets the pest points. + * @return the pest points. + */ + public int getPestPoints() { + return pestPoints; + } + + /** + * Sets the pest points. + * @param pestPoints the pest points. + */ + public void setPestPoints(int pestPoints) { + this.pestPoints = pestPoints; + } + + /** + * Gets the warriorGuildTokens. + * @return The warriorGuildTokens. + */ + public int getWarriorGuildTokens() { + return warriorGuildTokens; + } + + /** + * Sets the warriorGuildTokens. + * @param warriorGuildTokens The warriorGuildTokens to set. + */ + public void setWarriorGuildTokens(int warriorGuildTokens) { + this.warriorGuildTokens = warriorGuildTokens; + } + + /** + * Updates the warrior guild tokens. + * @param amount The amount to increase with. + */ + public void updateWarriorTokens(int amount) { + this.warriorGuildTokens += amount; + } + + /** + * Gets the bountyHunterRate. + * @return The bountyHunterRate. + */ + public int getBountyHunterRate() { + return bountyHunterRate; + } + + /** + * Increments the bountyHunterRate. + * @param rate The rate to set. + */ + public void updateBountyHunterRate(int rate) { + this.bountyHunterRate += rate; + } + + /** + * Gets the bountyRogueRate. + * @return The bountyRogueRate. + */ + public int getBountyRogueRate() { + return bountyRogueRate; + } + + /** + * Increments the bountyRogueRate. + * @param rate The rate to set. + */ + public void updateBountyRogueRate(int rate) { + this.bountyRogueRate += rate; + } + + /** + * Gets the barrowBrothers. + * @return The barrowBrothers. + */ + public boolean[] getBarrowBrothers() { + return barrowBrothers; + } + + /** + * Sets the barrowBrothers. + * @param barrowBrothers The barrowBrothers to set. + */ + public void setBarrowBrothers(boolean[] barrowBrothers) { + this.barrowBrothers = barrowBrothers; + } + + /** + * Gets the barrowKills. + * @return The barrowKills. + */ + public int getBarrowKills() { + return barrowKills; + } + + /** + * Sets the barrowKills. + * @param barrowKills The barrowKills to set. + */ + public void setBarrowKills(int barrowKills) { + if (barrowKills > 10000) { + barrowKills = 10000; + } + this.barrowKills = barrowKills; + } + + /** + * Gets the barrowTunnelIndex. + * @return The barrowTunnelIndex. + */ + public int getBarrowTunnelIndex() { + return barrowTunnelIndex; + } + + /** + * Sets the barrowTunnelIndex. + * @param barrowTunnelIndex The barrowTunnelIndex to set. + */ + public void setBarrowTunnelIndex(int barrowTunnelIndex) { + this.barrowTunnelIndex = barrowTunnelIndex; + } + + /** + * Sets the kolodion stage. + * @param stage the stage. + */ + public void setKolodionStage(int stage) { + this.kolodionStage = stage; + } + + /** + * Checks if they have started kolodion. + * @return {@code True} if so. + */ + public boolean hasStartedKolodion() { + return kolodionStage == 1; + } + + /** + * Checks if the stage is killed. + * @return {@code True} if so. + */ + public boolean hasKilledKolodion() { + return kolodionStage >= 2; + } + + /** + * Checks if they have recieved the reward. + * @return {@code True if so.} + */ + public boolean hasRecievedKolodionReward() { + return kolodionStage == 3; + } + + /** + * Gets the godCasts. + * @return The godCasts. + */ + public int[] getGodCasts() { + return godCasts; + } + + /** + * Gets the kolodionBoss. + * @return The kolodionBoss. + */ + public int getKolodionBoss() { + return kolodionBoss; + } + + /** + * Sets the kolodionBoss. + * @param kolodionBoss The kolodionBoss to set. + */ + public void setKolodionBoss(int kolodionBoss) { + this.kolodionBoss = kolodionBoss; + } + + /** + * Gets the lastBorkBattle. + * @return the lastBorkBattle + */ + public long getLastBorkBattle() { + return lastBorkBattle; + } + + /** + * Sets the balastBorkBattle. + * @param lastBorkBattle the lastBorkBattle to set. + */ + public void setLastBorkBattle(long lastBorkBattle) { + this.lastBorkBattle = lastBorkBattle; + } + + /** + * Checks if the player has killed bork. + * @return {@code True if so.} + */ + public boolean hasKilledBork() { + return lastBorkBattle > 0; + } + + /** + * Gets the lostCannon. + * @return the lostCannon + */ + public boolean isLostCannon() { + return lostCannon; + } + + /** + * Sets the balostCannon. + * @param lostCannon the lostCannon to set. + */ + public void setLostCannon(boolean lostCannon) { + this.lostCannon = lostCannon; + } + + /** + * Gets the startedMta. + * @return the startedMta + */ + public boolean isStartedMta() { + return startedMta; + } + + /** + * Sets the bastartedMta. + * @param startedMta the startedMta to set. + */ + public void setStartedMta(boolean startedMta) { + this.startedMta = startedMta; + } + + /** + * Increments the pizazz points. + * @param index the index. + */ + public void incrementPizazz(int index) { + pizazzPoints[index] += 1; + } + + /** + * Increments the pizzaz points. + * @param index the index. + * @param amount the amount. + */ + public void incrementPizazz(int index, int amount) { + pizazzPoints[index] += amount; + } + + /** + * Decrements the pizzaz points. + * @param index the index. + * @param amount the amount. + */ + public void decrementPizazz(int index, int amount) { + pizazzPoints[index] -= amount; + } + + /** + * Increments the pizazz points. + * @param index the index. + */ + public void decrementPizazz(int index) { + pizazzPoints[index] -= 1; + } + + /** + * Gets the pizzaz points in the index. tele=0, alchemist=1, 2=enchant, + * 3=grave + * @param index the index. + * @return the value. + */ + public int getPizazzPoints(int index) { + return pizazzPoints[index]; + } + + /** + * Gets the pizazzPoints. + * @return the pizazzPoints + */ + public int[] getPizazzPoints() { + return pizazzPoints; + } + + /** + * Sets the bapizazzPoints. + * @param pizazzPoints the pizazzPoints to set. + */ + public void setPizazzPoints(int[] pizazzPoints) { + this.pizazzPoints = pizazzPoints; + } + + /** + * Gets the bonesToPeaches. + * @return the bonesToPeaches + */ + public boolean isBonesToPeaches() { + return bonesToPeaches; + } + + /** + * Sets the babonesToPeaches. + * @param bonesToPeaches the bonesToPeaches to set. + */ + public void setBonesToPeaches(boolean bonesToPeaches) { + this.bonesToPeaches = bonesToPeaches; + } + + /** + * Gets the solvedMazes. + * @return the solvedMazes + */ + public int getSolvedMazes() { + return solvedMazes; + } + + /** + * Sets the solvedMazes. + * @param solvedMazes the solvedMazes to set. + */ + public void setSolvedMazes(int solvedMazes) { + this.solvedMazes = solvedMazes; + } + + /** + * Gets the fogRating. + * @return the fogRating + */ + public int getFogRating() { + return fogRating; + } + + /** + * Sets the fogRating. + * @param fogRating the fogRating to set. + */ + public void setFogRating(int fogRating) { + this.fogRating = fogRating; + } + + /** + * Gets the borkKills. + * @return the borkKills. + */ + public byte getBorkKills() { + return borkKills; + } + + /** + * Sets the borkKills. + * @param borkKills the borkKills to set + */ + public void setBorkKills(byte borkKills) { + this.borkKills = borkKills; + } + + /** + * gets the current value of an Hardcore Iron Man's death status + * @return the value of a Hardcore Iron Man's death status + */ + public boolean getHardcoreDeath() { + return hardcoreDeath; + } + + public void setHardcoreDeath(boolean hardcoreDeath) { + this.hardcoreDeath = hardcoreDeath; + } + public void setTopGrabbed(boolean topGrabbed){ + this.topGrabbed = topGrabbed; + } + public boolean isTopGrabbed(){return topGrabbed;} + + public int getKolodionStage() { + return kolodionStage; + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/player/link/BankPinManager.java b/Server/src/main/core/game/node/entity/player/link/BankPinManager.java new file mode 100644 index 0000000..321b5f8 --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/BankPinManager.java @@ -0,0 +1,832 @@ +package core.game.node.entity.player.link; + +import core.game.component.CloseEvent; +import core.game.component.Component; +import core.game.node.entity.player.Player; + +import core.game.ge.GrandExchangeRecords; +import content.global.handlers.iface.ge.StockMarket; +import core.game.world.GameWorld; +import core.net.packet.PacketRepository; +import core.net.packet.context.ChildPositionContext; +import core.net.packet.context.StringContext; +import core.net.packet.out.RepositionChild; +import core.net.packet.out.StringPacket; +import core.tools.RandomFunction; +import org.json.simple.JSONObject; +import org.rs09.consts.Sounds; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import static core.api.ContentAPIKt.*; + + +/** + * Manages the players bank pin. + * @author Vexia + * @author Emperor + */ +public class BankPinManager { + + /** + * THe setting messages to display on default. + */ + private static final String[] SETTINGS_MESSAGES = { "Customers are reminded that", "they should NEVER tell", "anyone their Bank PINs or", "passwords, nor should they", "ever enter their PINs on any", "website form.", null, "Have you read the PIN guide", "on the website?", null, null, null, null }; + + /** + * The pin child constants. + */ + public static final int SET_PIN = 60, CHANGE_RECOVERY = 61, CHANGE_PIN = 62, DELETE_PIN = 63, CANCEL_PENDING = 65; + + /** + * The player. + */ + private final Player player; + + /** + * The digits. + */ + private final List digits = new ArrayList<>(20); + + /** + * The bank pin. + */ + private String pin; + + /** + * If the manager has been unlocked. + */ + private boolean unlocked; + + /** + * If we're using the short or long recovery. + */ + private boolean longRecovery; + + /** + * The pin status. + */ + private PinStatus status = PinStatus.NO_PIN; + + /** + * The temporary pin. + */ + private String tempPin; + + /** + * The pending delay. + */ + private long pendingDelay = -1; + + /** + * The open id after confirmation interface. + */ + private int openId; + + /** + * The amount of attempts on opening the bank pin. + */ + private int tries; + + /** + * The pin changing state. + */ + private int changeState; + + /** + * If we're deleting the pin. + */ + private boolean deleting; + + /** + * The delay between + */ + private long tryDelay; + + /** + * Constructs a new {@Code BankPinManager} {@Code Object} + */ + public BankPinManager(final Player player) { + this.player = player; + for (int i = 0; i < 10; i++) { + digits.add(i); + } + } + + public void parse(JSONObject data){ + if(data.containsKey("pin")) { + pin = data.get("pin").toString(); + } + if(data.containsKey("status")){ + int st = Integer.parseInt( data.get("status").toString()); + status = PinStatus.values()[st]; + } + if(data.containsKey("pendingDelay")){ + this.pendingDelay = Long.parseLong(data.get("pendingDelay").toString()); + } + if(data.containsKey("tryDelay")){ + this.tryDelay = Long.parseLong(data.get("tryDelay").toString()); + } + longRecovery = (boolean) data.get("longRecovery"); + } + + /** + * Opens the settings. + */ + public void openSettings() { + checkPendingActivity(); + openSettings(status.getMessages(this)); + } + + /** + * Opens the bank pin settings. + */ + public void openSettings(String... messages) { + player.getInterfaceManager().close(); + tempPin = null; + sendMessages(messages); + playAudio(player, Sounds.PIN_PENDING_1040); + player.getInterfaceManager().open(new Component(14)); + } + + /** + * Sends the messages. + * @param messages the messages. + */ + private void sendMessages(String... messages) { + for (int i = 0; i < messages.length; i++) { + String message = messages[i]; + if (message == null) { + continue; + } + PacketRepository.send(StringPacket.class, new StringContext(player, message, 14, 42 + i)); + } + status.draw(this, player); + PinStatus.drawString(player, "Messages", 41); + PinStatus.drawString(player, getRecoveryDelay() + " days", 71); + PinStatus.drawString(player, "Use the buttons below to change your PIN settings", 86); + } + + /** + * Used to open a component type that requires pin unlocking. + * @param buttonId the buttonId. + */ + public void openType(int buttonId) { + checkPendingActivity(); + if (buttonId == 2) { + openSettings(); + return; + } + openId = buttonId; + if (hasPin() && !unlocked) { + if (hasPendingPin()) { + openSettings(); + toggleConfirmInterface(true); + PinStatus.drawString(player, "A PIN will be set on your bank account in another " + getPendingDays() + " day" + (getPendingDays() > 1 ? "s" : "") + ".", 73); + PinStatus.drawString(player, "Yes, I asked for this. I want this PIN.", 89); + PinStatus.drawString(player, "No, I didn't ask for this. Cancel it.", 91); + return; + } + openPin(); + return; + } + openForId(buttonId); + } + + /** + * Opens the interface for the id. + * @param buttonId the button id. + */ + private void openForId(int buttonId) { + if (buttonId == 1) { + { + player.getBank().open(); + } + } else if (buttonId == 3) { + GrandExchangeRecords.getInstance(player).openCollectionBox(); + } else if (buttonId == 4) { + StockMarket.openFor(player); + } + } + + /** + * Handles the confirmation interface. + * @param button the button. + */ + public void handleConfirmInterface(int button) { + boolean confirm = button != 91; + switch (status) { + case NO_PIN: + if (!confirm) { + toggleConfirmInterface(false); + player.getInterfaceManager().close(); + openSettings("No changes made."); + break; + } + openPin(); + break; + case PENDING: + if (confirm) { + unlock(); + } else { + cancelPin("The PIN has been cancelled", "and will NOT be set.", "", "You still do not have a Bank", "PIN."); + } + break; + case ACTIVE: + if (confirm) { + if (unlocked) { + cancelPin("Your Bank PIN has now been", "deleted.", "", "This means that there is no", "PIN protection on your bank", "account."); + } else { + deleting = true; + openPin(); + } + } else { + openSettings("No changes made."); + } + break; + default: + break; + } + } + + /** + * Unlocks the pin manager. + */ + private void unlock() { + unlocked = true; + openForId(openId); + } + + /** + * Opens the set bank PIN confirmation screen. + * @param show If we should show the confirm screen. + */ + public void toggleConfirmInterface(boolean show) { + for (int i = 60; i < 66; i++) { + player.getPacketDispatch().sendInterfaceConfig(14, i, show); + } + playAudio(player, Sounds.PIN_PENDING_1040); + player.getPacketDispatch().sendInterfaceConfig(14, 89, !show); + player.getPacketDispatch().sendInterfaceConfig(14, 91, !show); + player.getPacketDispatch().sendInterfaceConfig(14, 87, !show); + if (show && status == PinStatus.NO_PIN) { + PinStatus.drawString(player, "Do you really wish to set a PIN on your bank account?", 73); + PinStatus.drawString(player, "Yes, I really want a Bank PIN. I will never forget it!", 89); + PinStatus.drawString(player, "No, I might forget it!", 91); + } else if (show && status == PinStatus.ACTIVE) { + PinStatus.drawString(player, "Do you really wish to delete your Bank PIN?", 73); + PinStatus.drawString(player, "Yes, I don't need a PIN anymore.", 89); + PinStatus.drawString(player, "No thanks, I'd rather keep the extra security.", 91); + } + } + + /** + * Updates the temporary pin. + * @param button the button. + */ + public void updateTempPin(int button) { + tempPin += digits.get(button); + handlePinStage(getStage()); + } + + /** + * Checks the pending activity. + */ + private void checkPendingActivity() { + if (status == PinStatus.PENDING && pendingDelay < System.currentTimeMillis()) { + pendingDelay = -1; + status = PinStatus.ACTIVE; + return; + } + } + + /** + * Opens the set pin interface. + */ + public void openPin() { + if (isPinBlocked()) { + sendTryDialogue(); + return; + } + tempPin = ""; + player.getPacketDispatch().sendString("Bank of " + GameWorld.getSettings().getName(), 13, 31); + if (!hasPin()) { + player.getPacketDispatch().sendInterfaceConfig(13, 29, true); + player.getPacketDispatch().sendString("Please choose a new FOUR DIGIT PIN using the buttons below.", 13, 28); + } else { + player.getPacketDispatch().sendString("Please enter your PIN using the buttons below.", 13, 28); + } + player.getInterfaceManager().open(new Component(13).setCloseEvent(new CloseEvent() { + @Override + public boolean close(Player player, Component c) { + if (changeState != 0) { + changeState = 0; + } + if (deleting) { + deleting = false; + } + return true; + } + })); + handlePinStage(getStage()); + } + + /** + * Handles a pin stage. + * @param stage the stage. + */ + public void handlePinStage(int stage) { + if (stage == 4) { + if (!hasPin() || changeState == 2) { + playAudio(player, Sounds.PIN_PENDING_1040); + player.getPacketDispatch().sendString("Now please enter that number again!", 13, 28); + shuffleDigits(); + return; + } else { + if (!tempPin.equals(pin)) { + playAudio(player, Sounds.PILLORY_WRONG_2277); + player.getInterfaceManager().close(); + player.sendMessage("The PIN you entered is incorrect."); + if (setTries(getTries() + 1) >= 2) { + setTryLock(); + } + return; + } + if (changeState == 1) { + tempPin = ""; + player.getPacketDispatch().sendString("Please choose a new FOUR DIGIT PIN using the buttons below.", 13, 28); + changeState = 2; + shuffleDigits(); + return; + } + if (deleting) { + cancelPin("Your Bank PIN has now been", "deleted.", "", "This means that there is no", "PIN protection on your bank", "account."); + return; + } + unlock(); + playAudio(player, Sounds.PILLORY_SUCCESS_2274); + player.sendMessage("You have correctly entered your PIN."); + } + return; + } else if (stage == 8) { + boolean success = checkTempPin(); + if (isEasyGuess()) { + openSettings("That number wouldn't be very", "hard to guess. Please try", "something different!"); + return; + } + if (changeState == 2 && success) { + if (pin.equals(tempPin.substring(0, 4))) { + player.getPacketDispatch().sendMessage("Your current PIN matches your new one."); + } else { + pin = new String(Arrays.copyOf(tempPin.toCharArray(), 4)); + player.getPacketDispatch().sendMessage("You have changed your PIN."); + } + openSettings(); + return; + } + if (success) { + setPin(); + } + openSettings(success ? new String[] { "You have requested that a", "PIN be set on your bank", "account. This will take effect", "in another " + getRecoveryDelay() + " days.", "", "If you wish to cancel this PIN,", "please use the button", "on the left." } : new String[] { "Those numbers did not", "match.", "", "Your PIN has not been set;", "please try again if you wish", "to set a new PIN." }); + return; + } + shuffleDigits(); + if (stage != 0) { + playAudio(player, Sounds.PIN_BEEP_1041); + } + } + + /** + * Sets the try locks. + */ + private void setTryLock() { + setTryDelay(System.currentTimeMillis() + getPinSeconds() * 1000); + sendTryDialogue(); + } + + /** + * Sends the try dialogue. + */ + private void sendTryDialogue() { + long ticks = (tryDelay - System.currentTimeMillis()) / 1000; + int original = getPinSeconds(); + String suffix = (original > 15 ? "minutes" : "seconds"); + player.getInterfaceManager().close(); + if (suffix.equals("minutes") || ticks > 15) { + ticks /= 100; + suffix = "minutes"; + } + if (suffix.equals("minutes") && ticks <= 1) { + player.getDialogueInterpreter().sendDialogue("You will be able to access your bank in less than 1 minute."); + return; + } + player.getDialogueInterpreter().sendDialogue("You will be able to access your bank pin in " + ticks + " " + suffix + "."); + } + + /** + * Shuffles the digits. + */ + private void shuffleDigits() { + Collections.shuffle(digits); + int bitShift = 0, bitValue = 0; + for (int i = 0; i < 8; i++) { + bitValue |= digits.get(i) << bitShift; + bitShift += 4; + } + int stage = getStage(); + if (stage >= 4) { + stage = stage - 4; + } + setVarp(player, 562, bitValue); + setVarp(player, 563, digits.get(8) | digits.get(9) << 4 | stage << 26); + for (int i = 0; i < 9; i++) { + int child = (i > 2 ? i + 1 : i) + 11; + int positionX = 37 + ((i % 3) * 95) + RandomFunction.random(2, 45); + int positionY = 157 + ((i / 3) * 70) - RandomFunction.random(3, 48); + PacketRepository.send(RepositionChild.class, new ChildPositionContext(player, 13, child, positionX, positionY)); + } + PacketRepository.send(RepositionChild.class, new ChildPositionContext(player, 13, 14, 308 + RandomFunction.random(2, 45), 155 - RandomFunction.random(3, 45))); + } + + /** + * Sets the pin. + */ + private void setPin() { + status = PinStatus.PENDING; + pendingDelay = System.currentTimeMillis() + (GameWorld.getSettings().isDevMode() ? TimeUnit.SECONDS.toMillis(30) : TimeUnit.DAYS.toMillis(this.getRecoveryDelay())); + pin = new String(Arrays.copyOf(tempPin.toCharArray(), 4)); + } + + /** + * Sets the pin. + * @param pin the pin. + */ + public void setPin(String pin) { + this.pin = pin; + } + + /** + * Cancels the pin and shows the correct interface. + */ + public void cancelPin(String... messages) { + doCancelPin(); + playAudio(player, Sounds.PIN_CANCEL_1042); + openSettings(messages); + } + + /** + * Actually cancels the pin. + */ + public void doCancelPin() { + status = PinStatus.NO_PIN; + pendingDelay = -1; + pin = null; + unlocked = false; + } + + + /** + * Checks if the pin is an easy guess. + * @return {@code True} if so. + */ + private boolean isEasyGuess() { + boolean badCombo = true; + String currentPin = tempPin; + for (int i = 0; i < 4; i++) { + if (currentPin.charAt(0) != currentPin.charAt(i)) { + badCombo = false; + break; + } + } + if (!badCombo) { + badCombo = true; + for (int i = 0; i < 3; i++) { + int value = Byte.valueOf((byte) currentPin.charAt(i)); + int next = Byte.valueOf((byte) currentPin.charAt(i + 1)); + if (!(Character.valueOf((char) (value + 1)) == next || Character.valueOf((char) (value - 1)) == next)) { + badCombo = false; + break; + } + } + } + return badCombo; + } + + /** + * Checks the temporary pin match. + * @return {@code True} if matched. + */ + private boolean checkTempPin() { + for (int i = 0; i < 4; i++) { + if (tempPin.charAt(i) != tempPin.charAt(4 + i)) { + return false; + } + } + return true; + } + + /** + * Gets the pending + * @return the pending days. + */ + public int getPendingDays() { + if (pendingDelay < System.currentTimeMillis()) { + return 0; + } + return (int) (pendingDelay - System.currentTimeMillis()) / (GameWorld.getSettings().isDevMode() ? 1000 : 86400000); + } + + /** + * Gets the stage of the pin setting. + * @return the stage. + */ + public int getStage() { + if (tempPin == null) { + return 0; + } + return tempPin.length(); + } + + /** + * Draws the login message. + */ + public void drawLoginMessage() { + player.getPacketDispatch().sendString(status.getLoginMessage(this), 378, 62); + checkPendingActivity(); + } + + /** + * Sets the chaning pin. + * @param state the changing state. + */ + public void setChangingState(int state) { + this.changeState = state; + } + + /** + * Gets the long recovery delay. + * @return the delay. + */ + public int getRecoveryDelay() { + return longRecovery ? 7 : 3; + } + + /** + * Checks if the manager has a pin. + * @return the pin. + */ + public boolean hasPin() { + return pin != null; + } + + /** + * Checks if there is a pending pin. + * @return {@code True} if so. + */ + public boolean hasPendingPin() { + return getPendingDays() > 0; + } + + /** + * Gets the pin. + * @return the pin. + */ + public String getPin() { + return pin; + } + + /** + * Gets the unlocked. + * @return the unlocked + */ + public boolean isUnlocked() { + if (!hasPin()) { + return true; + } + return unlocked; + } + + /** + * Sets the baunlocked. + * @param unlocked the unlocked to set. + */ + public void setUnlocked(boolean unlocked) { + this.unlocked = unlocked; + } + + /** + * Gets the player. + * @return the player + */ + public Player getPlayer() { + return player; + } + + /** + * Gets the longRecovery. + * @return the longRecovery + */ + public boolean isLongRecovery() { + return longRecovery; + } + + /** + * Sets the status. + * @param status the status. + */ + public void setStatus(PinStatus status) { + this.status = status; + } + + /** + * Sets the balongRecovery. + * @param longRecovery the longRecovery to set. + */ + public void setLongRecovery(boolean longRecovery) { + this.longRecovery = longRecovery; + } + + /** + * Switches the recovery delay. + */ + public void switchRecovery() { + + setLongRecovery(!longRecovery); + PinStatus.drawString(player, getRecoveryDelay() + " days", 71); + PinStatus.drawString(player, "Your recovery delay has", 42); + PinStatus.drawString(player, "now been set to " + getRecoveryDelay() + " days.", 43); + PinStatus.drawString(player, "", 44); + PinStatus.drawString(player, "You would have to wait this", 45); + PinStatus.drawString(player, "long to delete your PIN if", 46); + PinStatus.drawString(player, "you forgot it. But you", 47); + PinStatus.drawString(player, "haven't got one...", 48); + } + + /** + * Checks if the pin is blocked. + * @return {@code True} if so. + */ + public boolean isPinBlocked() { + return tryDelay > System.currentTimeMillis(); + } + + /** + * Gets the PIN lock ticks. + * @return The PIN lock ticks. + */ + public int getPinSeconds() { + if (tries == 2) { + return 10; + } else if (tries == 3) { + return 15; + } else if (tries > 3) { + return 1000; + } + return 0; + } + + /** + * Gets the tries. + * @return the tries + */ + public int getTries() { + return tries; + } + + /** + * Sets the batries. + * @param tries the tries to set. + */ + public int setTries(int tries) { + this.tries = tries; + return tries; + } + + /** + * Gets the tryDelay. + * @return the tryDelay + */ + public long getTryDelay() { + return tryDelay; + } + + /** + * Sets the batryDelay. + * @param tryDelay the tryDelay to set. + */ + public void setTryDelay(long tryDelay) { + this.tryDelay = tryDelay; + } + + /** + * A pin status. + * @author Vexia/k + */ + public enum PinStatus { + NO_PIN() { + + @Override + public void draw(BankPinManager manager, Player player) { + drawString(player, "NO PIN set", 69); + removeLines(player, 89, 55, 56, 57, 91, 64, 65, 63, 62); + } + + }, + PENDING() { + @Override + public void draw(BankPinManager manager, Player player) { + drawString(player, "PIN coming soon", 69); + removeLines(player, 89, 55, 56, 57, 91, 64, 63, 62, 60, 61); + } + + @Override + public String getLoginMessage(BankPinManager manager) { + int days = manager.getPendingDays(); + String message = "Your Bank PIN will become active in another " + days + " day" + (days > 1 ? "s" : "") + "."; + if (days < 1) { + return "Your Bank PIN has just become active."; + } + return message; + } + + @Override + public String[] getMessages(BankPinManager manager) { + int days = manager.getPendingDays(); + return new String[] { "You have requested that a", "PIN be set on your bank", "account. This will take effect", "in another " + days + " day" + (days > 1 ? "s" : "") + ".", "", "If you wish to cancel this", "PIN, please use the button", "on the left." }; + } + }, + ACTIVE() { + + @Override + public void draw(BankPinManager manager, Player player) { + drawString(player, "You have a PIN", 69); + removeLines(player, 89, 55, 56, 57, 91, CANCEL_PENDING, CHANGE_RECOVERY, SET_PIN); + } + + @Override + public String getLoginMessage(BankPinManager manager) { + return "You you currently have a Bank PIN."; + } + + }; + + /** + * Draws the status on the interface. + * @param player the player. + */ + public void draw(BankPinManager manager, Player player) { + + } + + /** + * Gets the login message. + * @param manager the manager. + * @return the message. + */ + public String getLoginMessage(BankPinManager manager) { + return "You do not have a Bank PIN. Please visit a bank if you would like one."; + } + + /** + * Draws a string. + * @param player the player. + * @param string the string. + * @param line the line. + */ + public static void drawString(Player player, String string, int line) { + player.getPacketDispatch().sendString(string, 14, line); + } + + /** + * Removes the lines. + * @param player the player. + * @param lines the lines. + */ + public static void removeLines(Player player, int... lines) { + for (int line : lines) { + player.getPacketDispatch().sendInterfaceConfig(14, line, true); + } + } + + /** + * Gets the messages to display. + * @return the messages. + */ + public String[] getMessages(BankPinManager manager) { + return SETTINGS_MESSAGES; + } + + } + + public PinStatus getStatus() { + return status; + } + + public long getPendingDelay() { + return pendingDelay; + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/player/link/GlobalData.java b/Server/src/main/core/game/node/entity/player/link/GlobalData.java new file mode 100644 index 0000000..29878c2 --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/GlobalData.java @@ -0,0 +1,1356 @@ +package core.game.node.entity.player.link; + +import content.data.GodBook; + +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; + +/** + * Represents the quest data to save. + * @author 'Vexia + */ +public final class GlobalData { + + /** + * Represents the tutorial stage. + */ + private int tutorialStage; + + /** + * Represents the home teleport delay. + */ + private long homeTeleportDelay; + + /** + * Represents the assist time. + */ + private long assistTime; + + /** + * Represents the last chat ping. + */ + private long chatPing; + + /** + * Represents the time between tutor claims. + */ + private long tutorClaim; + + /** + * Represents if luthas has given us a task. + */ + private boolean luthasTask; + + /** + * Represents the stahsed karamja bnnanas. + */ + private int karamjaBananas; + + private int savedX; + + private int savedY; + + private int savedH; + + private int taskAmount; + + private int taskPoints; + /** + * Represents the silk steal time. + */ + private long silkSteal; + + /** + * Represents the assist experience. + */ + private double[] assistExperience = new double[9]; + + /** + * Represents the strong hold rewards. + */ + private boolean[] strongHoldRewards = new boolean[4]; + + /** + * Represents if the lumbridge rope has been tied; + */ + private boolean lumbridgeRope; + + /** + * Represents if the player has spoken to the apprentice. + */ + private boolean apprentice; + + /** + * Represents if the player has spoken to the friz glass blower. + */ + private boolean fritzGlass; + + /** + * Represents the zaff npc staff amount. + */ + private int zafAmount = 8; + + /** + * Represents the time until you can buy from zaff. + */ + private long zafTime; + + /** + * Represents if you're a wydin employee. + */ + private boolean wydinEmployee; + + /** + * Represents if the draynor recording has been seen. + */ + private boolean draynorRecording; + + /** + * Represents if the ge tutorial has been done. + */ + private boolean geTutorial; + + /** + * Represents the npc id of the essence teleporter. + */ + private int essenceTeleporter; + + /** + * The amount of recoil damage left (ring of recoil). + */ + private int recoilDamage = 40; + + /** + * The delay between the next use of double exp. + */ + private long doubleExpDelay; + + /** + * The delay between the next use of increased drops. + */ + private long dropDelay; + + /** + * If joined the monastery. + */ + private boolean joinedMonastery; + + /** + * If the player has read each plague + */ + private boolean[] readPlaques = new boolean[7]; + + /** + * The ring of forging uses. + */ + private int forgingUses; + + /** + * The ectofuntus charges. + */ + private int ectoCharges; + + /** + * The abbyss data. + */ + private boolean[] abyssData = new boolean[4]; + + /** + * The amount of decays for the rc type. + */ + private final int[] rcDecays = new int[3]; + + /** + * If the death screen is disabled. + */ + private boolean disableDeathScreen; + + /** + * The stage of the player safety test. + */ + private int playerTestStage; + + /** + * The delay between charming usage. + */ + private long charmingDelay; + + /** + * The fairy ring travel log. + */ + private boolean[] travelLogs = new boolean[45]; + + /** + * The completed god books. + */ + private boolean[] godBooks = new boolean[3]; + + /** + * The god book you are currently filling. + */ + private int godBook = -1; + + /** + * If the player see's news or not. + */ + private boolean disableNews; + + /** + * The completed god pages. + */ + private boolean[] godPages = new boolean[4]; + + /** + * The time until the overcharge delay can be used. + */ + private long overChargeDelay; + + /** + * The boss kill counter. + */ + private int[] bossCounters = new int[25]; + + /** + * The barrows loot counter. + */ + private int barrowsLoots; + + /** + * The amount of lootshare points. + */ + private int lootSharePoints; + + /** + * The delay between the next decrease of lootshare. + */ + private long lootShareDelay; + + /** + * The double exp time. + */ + private long doubleExp; + + /** + * The delay of the global teleporter system. + */ + private long globalTeleporterDelay; + + /** + * The delay until you can exchange the star sprite again. + */ + private long starSpriteDelay; + + /** + * The run replenish delay. + */ + private long runReplenishDelay; + + /** + * The run replenish charges. + */ + private int runReplenishCharges; + + /** + * The amount of low alchemy charges. + */ + private int lowAlchemyCharges; + + /** + * The low alchemy delay. + */ + private long lowAlchemyDelay; + + /** + * Is the bone crusher perk enabled. + */ + private boolean enableBoneCrusher = false; + + /** + * Is the coin machine perk enabled. + */ + private boolean enableCoinMachine = false; + + /** + * Is the charm collector perk enabled. + */ + private boolean enableCharmCollector = false; + + /** + * The magic skill cape delay. + */ + private long magicSkillCapeDelay; + + /** + * The hunter cape delay. + */ + private long hunterCapeDelay; + + /** + * The hunter cape charges. + */ + private int hunterCapeCharges; + + private long minigameTeleportDelay; + + /** + * Whether or not randoms are enabled + */ + private boolean macroDisabled = false; + + public void parse(JSONObject data){ + tutorialStage = Integer.parseInt( data.get("tutorialStage").toString()); + homeTeleportDelay = Long.parseLong(data.get("homeTeleportDelay").toString()); + lumbridgeRope = (boolean) data.get("lumbridgeRope"); + apprentice = (boolean) data.get("apprentice"); + assistTime = Long.parseLong(data.get("assistTime").toString()); + JSONArray ae = (JSONArray) data.get("assistExperience"); + for(int i = 0; i < ae.size(); i++){ + assistExperience[i] = Double.parseDouble(ae.get(i).toString()); + } + JSONArray sr = (JSONArray) data.get("strongHoldRewards"); + for(int i = 0; i < sr.size(); i++){ + strongHoldRewards[i] = (boolean) sr.get(i); + } + chatPing = Long.parseLong(data.get("chatPing").toString()); + tutorClaim = Long.parseLong(data.get("tutorClaim").toString()); + luthasTask = (boolean) data.get("luthasTask"); + karamjaBananas = Integer.parseInt( data.get("karamjaBananas").toString()); + silkSteal = Long.parseLong(data.get("silkSteal").toString()); + zafAmount = Integer.parseInt( data.get("zafAmount").toString()); + zafTime = Long.parseLong(data.get("zafTime").toString()); + fritzGlass = (boolean) data.get("fritzGlass"); + wydinEmployee = (boolean) data.get("wydinEmployee"); + draynorRecording = (boolean) data.get("draynorRecording"); + geTutorial = (boolean) data.get("geTutorial"); + essenceTeleporter = Integer.parseInt( data.get("essenceTeleporter").toString()); + recoilDamage = Integer.parseInt( data.get("recoilDamage").toString()); + doubleExpDelay = Long.parseLong(data.get("doubleExpDelay").toString()); + joinedMonastery = (boolean) data.get("joinedMonastery"); + JSONArray rp = (JSONArray) data.get("readPlaques"); + for(int i = 0; i < rp.size(); i++){ + readPlaques[i] = (boolean) rp.get(i); + } + forgingUses = Integer.parseInt( data.get("forgingUses").toString()); + ectoCharges = Integer.parseInt( data.get("ectoCharges").toString()); + dropDelay = Long.parseLong(data.get("dropDelay").toString()); + JSONArray ad = (JSONArray) data.get("abyssData"); + for(int i = 0; i < ad.size(); i++){ + abyssData[i] = (boolean) ad.get(i); + } + JSONArray rd = (JSONArray) data.get("rcDecays"); + for(int i = 0; i < rd.size(); i++){ + rcDecays[i] = Integer.parseInt(rd.get(i).toString()); + } + disableDeathScreen = (boolean) data.get("disableDeathScreen"); + playerTestStage = Integer.parseInt( data.get("playerTestStage").toString()); + charmingDelay = Long.parseLong(data.get("charmingDelay").toString()); + JSONArray tl = (JSONArray) data.get("travelLogs"); + for(int i = 0; i < tl.size(); i++){ + travelLogs[i] = (boolean) tl.get(i); + } + JSONArray gb = (JSONArray) data.get("godBooks"); + for(int i = 0 ; i < gb.size(); i++){ + godBooks[i] = (boolean) gb.get(i); + } + disableNews = (boolean) data.get("disableNews"); + JSONArray gp = (JSONArray) data.get("godPages"); + for(int i = 0 ; i < gp.size(); i++){ + godPages[i] = (boolean) gp.get(i); + } + overChargeDelay = Long.parseLong(data.get("overChargeDelay").toString()); + JSONArray bc = (JSONArray) data.get("bossCounters"); + for(int i = 0 ; i < bc.size(); i++){ + bossCounters[i] = Integer.parseInt(bc.get(i).toString()); + } + barrowsLoots = Integer.parseInt( data.get("barrowsLoots").toString()); + lootShareDelay = Long.parseLong(data.get("lootShareDelay").toString()); + lootSharePoints = Integer.parseInt( data.get("lootSharePoints").toString()); + doubleExp = Long.parseLong(data.get("doubleExp").toString()); + globalTeleporterDelay = Long.parseLong(data.get("globalTeleporterDelay").toString()); + starSpriteDelay = Long.parseLong(data.get("starSpriteDelay").toString()); + runReplenishDelay = Long.parseLong(data.get("runReplenishDelay").toString()); + runReplenishCharges = Integer.parseInt( data.get("runReplenishCharges").toString()); + lowAlchemyCharges = Integer.parseInt( data.get("lowAlchemyCharges").toString()); + lowAlchemyDelay = Long.parseLong(data.get("lowAlchemyDelay").toString()); + magicSkillCapeDelay = Long.parseLong(data.get("magicSkillCapeDelay").toString()); + hunterCapeDelay = Long.parseLong(data.get("hunterCapeDelay").toString()); + hunterCapeCharges = Integer.parseInt( data.get("hunterCapeCharges").toString()); + taskAmount = Integer.parseInt( data.get("taskAmount").toString()); + taskPoints = Integer.parseInt( data.get("taskPoints").toString()); + macroDisabled = (boolean) data.get("macroDisabled"); + } + + public void setSavedLocation(int x, int y, int z) { + setSavedX(x); + setSavedY(y); + setSavedH(z); + } + + /** + * Sets the star sprite delay. + * @param value The value. + */ + public void setStarSpriteDelay(long value) { + starSpriteDelay = value; + } + + /** + * Gets the star sprite delay. + * @return The star sprite delay. + */ + public long getStarSpriteDelay() { + return starSpriteDelay; + } + + /** + * Gets the travel logs. + * @return the logs. + */ + public boolean[] getTravelLogs() { + return travelLogs; + } + + /** + * Removes a travel log. + * @param index the index. + */ + public void removeTravelLog(int index) { + travelLogs[index] = false; + } + + /** + * Checks if they have the travel log. + * @param index the index. + * @return {@code True} if so. + */ + public boolean hasTravelLog(int index) { + return travelLogs[index]; + } + + /** + * Sets a travel log. + * @param index the index. + */ + public void setTravelLog(int index) { + travelLogs[index] = true; + } + + /** + * Sets the charming delay. + * @param delay the delay. + */ + public void setCharmingDelay(long delay) { + this.charmingDelay = delay; + } + + /** + * Gets the charming delay. + * @return the delay. + */ + public long getCharmingDelay() { + return charmingDelay; + } + + /** + * Gets the stage. + * @return the stage. + */ + public int getTestStage() { + return playerTestStage; + } + + /** + * Sets the test stage. + * @param stage the stage. + */ + public void setTestStage(int stage) { + playerTestStage = stage; + } + + /** + * Gets the tutorialStage. + * @return The tutorialStage. + */ + public int getTutorialStage() { + return tutorialStage; + } + + /** + * Sets the tutorialStage. + * @param tutorialStage The tutorialStage to set. + */ + public void setTutorialStage(int tutorialStage) { + this.tutorialStage = tutorialStage; + } + + /** + * Gets the homeTeleportDelay. + * @return The homeTeleportDelay. + */ + public long getHomeTeleportDelay() { + return homeTeleportDelay; + } + + /** + * Sets the homeTeleportDelay. + * @param homeTeleportDelay The homeTeleportDelay to set. + */ + public void setHomeTeleportDelay(long homeTeleportDelay) { + this.homeTeleportDelay = homeTeleportDelay; + } + + /** + * Gets the lumbridgeRope. + * @return The lumbridgeRope. + */ + public boolean hasTiedLumbridgeRope() { + return lumbridgeRope; + } + + /** + * Sets the lumbridgeRope. + * @param lumbridgeRope The lumbridgeRope to set. + */ + public void setLumbridgeRope(boolean lumbridgeRope) { + this.lumbridgeRope = lumbridgeRope; + } + + /** + * Gets the apprentice. + * @return The apprentice. + */ + public boolean hasSpokenToApprentice() { + return apprentice; + } + + /** + * Sets the apprentice. + * @param apprentice The apprentice to set. + */ + public void setApprentice(boolean apprentice) { + this.apprentice = apprentice; + } + + /** + * Gets the assistTime. + * @return The assistTime. + */ + public long getAssistTime() { + return assistTime; + } + + /** + * Sets the assistTime. + * @param assistTime The assistTime to set. + */ + public void setAssistTime(long assistTime) { + this.assistTime = assistTime; + } + + /** + * Gets the assistExperience. + * @return The assistExperience. + */ + public double[] getAssistExperience() { + return assistExperience; + } + + /** + * Sets the assistExperience. + * @param assistExperience The assistExperience to set. + */ + public void setAssistExperience(double[] assistExperience) { + this.assistExperience = assistExperience; + } + + /** + * Gets the strongHoldRewards. + * @return The strongHoldRewards. + */ + public boolean[] getStrongHoldRewards() { + return strongHoldRewards; + } + + /** + * Gets the strong hold reward value. + * @param reward the reward. + * @return {@code True} if so. + */ + public boolean hasStrongholdReward(int reward) { + return strongHoldRewards[reward - 1]; + } + + /** + * Gets the chatPing. + * @return The chatPing. + */ + public long getChatPing() { + return chatPing; + } + + /** + * Sets the chatPing. + * @param chatPing The chatPing to set. + */ + public void setChatPing(long chatPing) { + this.chatPing = chatPing; + } + + /** + * Gets the tutorClaim. + * @return The tutorClaim. + */ + public long getTutorClaim() { + return tutorClaim; + } + + /** + * Sets the tutorClaim. + * @param tutorClaim The tutorClaim to set. + */ + public void setTutorClaim(long tutorClaim) { + this.tutorClaim = tutorClaim; + } + + /** + * Gets the luthasTask. + * @return The luthasTask. + */ + public boolean isLuthasTask() { + return luthasTask; + } + + /** + * Sets the luthasTask. + * @param luthasTask The luthasTask to set. + */ + public void setLuthasTask(boolean luthasTask) { + this.luthasTask = luthasTask; + } + + /** + * Gets the karamjaBannanas. + * @return The karamjaBannanas. + */ + public int getKaramjaBananas() { + return karamjaBananas; + } + + /** + * Sets the karamjaBannanas. + * @param karamjaBannanas The karamjaBannanas to set. + */ + public void setKaramjaBannanas(int karamjaBannanas) { + this.karamjaBananas = karamjaBannanas; + } + + /** + * Gets the silkSteal. + * @return The silkSteal. + */ + public long getSilkSteal() { + return silkSteal; + } + + /** + * Sets the silkSteal. + * @param silkSteal The silkSteal to set. + */ + public void setSilkSteal(long silkSteal) { + this.silkSteal = silkSteal; + } + + /** + * Gets the zaffAmount. + * @return The zaffAmount. + */ + public int getZaffAmount() { + return zafAmount; + } + + /** + * Sets the zaffAmount. + * @param zaffAmount The zaffAmount to set. + */ + public void setZaffAmount(int zaffAmount) { + this.zafAmount = zaffAmount; + } + + /** + * Gets the zaffTime. + * @return The zaffTime. + */ + public long getZafTime() { + return zafTime; + } + + /** + * Gets the draynorRecording. + * @return The draynorRecording. + */ + public boolean isDraynorRecording() { + return draynorRecording; + } + + /** + * Sets the draynorRecording. + * @param draynorRecording The draynorRecording to set. + */ + public void setDraynorRecording(boolean draynorRecording) { + this.draynorRecording = draynorRecording; + } + + /** + * Gets the wydinEmployee. + * @return The wydinEmployee. + */ + public boolean isWydinEmployee() { + return wydinEmployee; + } + + /** + * Sets the wydinEmployee. + * @param wydinEmployee The wydinEmployee to set. + */ + public void setWydinEmployee(boolean wydinEmployee) { + this.wydinEmployee = wydinEmployee; + } + + /** + * Sets the zaffTime. + * @param zaffTime The zaffTime to set. + */ + public void setZafTime(long zaffTime) { + this.zafTime = zaffTime; + } + + /** + * Gets the frizGlass. + * @return The frizGlass. + */ + public boolean isFritzGlass() { + return fritzGlass; + } + + /** + * Sets the frizGlass. + * @param frizGlass The frizGlass to set. + */ + public void setFritzGlass(boolean frizGlass) { + this.fritzGlass = frizGlass; + } + + /** + * Gets the geTutorial. + * @return The geTutorial. + */ + public boolean isGeTutorial() { + return geTutorial; + } + + /** + * Sets the geTutorial. + * @param geTutorial The geTutorial to set. + */ + public void setGeTutorial(boolean geTutorial) { + this.geTutorial = geTutorial; + } + + /** + * Gets the essenceTeleporter. + * @return The essenceTeleporter. + */ + public int getEssenceTeleporter() { + return essenceTeleporter; + } + + /** + * Sets the essenceTeleporter. + * @param essenceTeleporter The essenceTeleporter to set. + */ + public void setEssenceTeleporter(int essenceTeleporter) { + this.essenceTeleporter = essenceTeleporter; + } + + /** + * Gets the recoilDamage. + * @return The recoilDamage. + */ + public int getRecoilDamage() { + return recoilDamage; + } + + /** + * Sets the recoilDamage. + * @param recoilDamage The recoilDamage to set. + */ + public void setRecoilDamage(int recoilDamage) { + this.recoilDamage = recoilDamage; + } + + /** + * Gets the doubleExpDelay. + * @return The doubleExpDelay. + */ + public long getDoubleExpDelay() { + return doubleExpDelay; + } + + /** + * Sets the doubleExpDelay. + * @param doubleExpDelay The doubleExpDelay to set. + */ + public void setDoubleExpDelay(long doubleExpDelay) { + this.doubleExpDelay = doubleExpDelay; + } + + /** + * Gets the joinedMonastery. + * @return The joinedMonastery. + */ + public boolean isJoinedMonastery() { + return joinedMonastery; + } + + /** + * Sets the joinedMonastery. + * @param joinedMonastery The joinedMonastery to set. + */ + public void setJoinedMonastery(boolean joinedMonastery) { + this.joinedMonastery = joinedMonastery; + } + + /** + * Gets the read plaques. + * @return The plaques + */ + public boolean[] getReadPlaques() { + return readPlaques; + } + + /** + * If the player has read all of the jail-plaques in the jail. + * @return If the player has read them all. + */ + public boolean hasReadPlaques() { + for (int i = 0; i < getReadPlaques().length; i++) { + if (!getReadPlaques()[i]) { + return false; + } + } + return true; + } + + /** + * Sets a god book to being completed. + * @param book the book. + */ + public void setGodBook(GodBook book) { + godBooks[book.ordinal()] = true; + } + + /** + * Checks if a god book has been completed. + * @param book the book. + * @return {@code True} if so. + */ + public boolean hasCompletedGodBook(GodBook book) { + return godBooks[book.ordinal()]; + } + + /** + * Gets the forgingUses. + * @return The forgingUses. + */ + public int getForgingUses() { + return forgingUses; + } + + /** + * Sets the forgingUses. + * @param forgingUses The forgingUses to set. + */ + public void setForgingUses(int forgingUses) { + this.forgingUses = forgingUses; + } + + /** + * Gets the ectoCharges. + * @return The ectoCharges. + */ + public int getEctoCharges() { + return ectoCharges; + } + + /** + * Sets the ectoCharges. + * @param ectoCharges The ectoCharges to set. + */ + public void setEctoCharges(int ectoCharges) { + this.ectoCharges = ectoCharges; + } + + /** + * Resets the abyss data. + */ + public void resetAbyss() { + for (int i = 0; i < abyssData.length; i++) { + abyssData[i] = false; + } + } + + /** + * Sets the charge. + * @param ordinal the ordinal. + */ + public void setAbyssCharge(int ordinal) { + abyssData[ordinal] = true; + } + + /** + * Has an anyss charge. + * @param ordinal the ordinal. + * @return {@code True} if so. + */ + public boolean hasAbyssCharge(int ordinal) { + return abyssData[ordinal]; + } + + /** + * Gets the dropDelay. + * @return The dropDelay. + */ + public long getDropDelay() { + return dropDelay; + } + + /** + * Sets the dropDelay. + * @param dropDelay The dropDelay to set. + */ + public void setDropDelay(long dropDelay) { + this.dropDelay = dropDelay; + } + + /** + * Gets the rc decay. + * @param ordinal the ordinal. + * @return the decay. + */ + public int getRcDecay(int ordinal) { + if (ordinal < 0) { + return 0; + } + return rcDecays[ordinal]; + } + + /** + * Gets the rc decays. + * @return the decays. + */ + public int[] getRcDecays() { + return rcDecays; + } + + /** + * Checks if the death screen is disabled. + * @return {@code True} if so. + */ + public boolean isDeathScreenDisabled() { + return disableDeathScreen; + } + + /** + * Sets if the death screen is disabled. + * @param b the boolean. + */ + public void setDisableDeathScreen(boolean b) { + this.disableDeathScreen = b; + } + + /** + * Gets the godBooks. + * @return the godBooks + */ + public boolean[] getGodBooks() { + return godBooks; + } + + /** + * Sets the godBooks. + * @param godBooks the godBooks to set. + */ + public void setGodBooks(boolean[] godBooks) { + this.godBooks = godBooks; + } + + /** + * Gets the godBook. + * @return the godBook + */ + public int getGodBook() { + return godBook; + } + + /** + * Sets the godBook. + * @param godBook the godBook to set. + */ + public void setGodBook(int godBook) { + this.godBook = godBook; + } + + /** + * Gets the disableNews. + * @return the disableNews + */ + public boolean isDisableNews() { + return disableNews; + } + + /** + * Sets the disableNews. + * @param disableNews the disableNews to set. + */ + public void setDisableNews(boolean disableNews) { + this.disableNews = disableNews; + } + + /** + * Gets the godPages. + * @return the godPages + */ + public boolean[] getGodPages() { + return godPages; + } + + /** + * Sets the godPages. + * @param godPages the godPages to set. + */ + public void setGodPages(boolean[] godPages) { + this.godPages = godPages; + } + + /** + * Gets the overChargeDelay. + * @return the overChargeDelay. + */ + public long getOverChargeDelay() { + return overChargeDelay; + } + + /** + * Sets the overChargeDelay. + * @param overChargeDelay the overChargeDelay to set + */ + public void setOverChargeDelay(long overChargeDelay) { + this.overChargeDelay = overChargeDelay; + } + + /** + * Gets the bossCounters. + * @return the bossCounters. + */ + public int[] getBossCounters() { + return bossCounters; + } + + /** + * Sets the bossCounters. + * @param bossCounters the bossCounters to set + */ + public void setBossCounters(int[] bossCounters) { + this.bossCounters = bossCounters; + } + + /** + * Gets the barrowsLoots. + * @return the barrowsLoots. + */ + public int getBarrowsLoots() { + return barrowsLoots; + } + + /** + * Sets the barrowsLoots. + * @param barrowsLoots the barrowsLoots to set + */ + public void setBarrowsLoots(int barrowsLoots) { + this.barrowsLoots = barrowsLoots; + } + + /** + * Gets the lootSharePoints. + * @return the lootSharePoints. + */ + public int getLootSharePoints() { + return lootSharePoints; + } + + /** + * Sets the lootSharePoints. + * @param lootSharePoints the lootSharePoints to set + */ + public void setLootSharePoints(int lootSharePoints) { + this.lootSharePoints = lootSharePoints; + } + + /** + * Gets the lootShareDelay. + * @return the lootShareDelay. + */ + public long getLootShareDelay() { + return lootShareDelay; + } + + /** + * Sets the lootShareDelay. + * @param lootShareDelay the lootShareDelay to set + */ + public void setLootShareDelay(long lootShareDelay) { + this.lootShareDelay = lootShareDelay; + } + + /** + * Gets the doubleExp. + * @return the doubleExp. + */ + public long getDoubleExp() { + return doubleExp; + } + + /** + * Sets the doubleExp. + * @param doubleExp the doubleExp to set + */ + public void setDoubleExp(long doubleExp) { + this.doubleExp = doubleExp; + } + + /** + * Checks if double exp is active. + * @return {@code True} if so. + */ + public boolean hasDoubleExp() { + return doubleExp > System.currentTimeMillis(); + } + + /** + * Gets the globalTeleporterDelay. + * @return the globalTeleporterDelay. + */ + public long getGlobalTeleporterDelay() { + return globalTeleporterDelay; + } + + /** + * Sets the globalTeleporterDelay. + * @param globalTeleporterDelay the globalTeleporterDelay to set + */ + public void setGlobalTeleporterDelay(long globalTeleporterDelay) { + this.globalTeleporterDelay = globalTeleporterDelay; + } + + /** + * @return the runReplenishDelay + */ + public long getRunReplenishDelay() { + return runReplenishDelay; + } + + /** + * @param runReplenishDelay the runReplenishDelay to set + */ + public void setRunReplenishDelay(long runReplenishDelay) { + this.runReplenishDelay = runReplenishDelay; + } + + /** + * @return the runReplenishCharges + */ + public int getRunReplenishCharges() { + return runReplenishCharges; + } + + /** + * @param runReplenishCharges the runReplenishCharges to set + */ + public void setRunReplenishCharges(int runReplenishCharges) { + this.runReplenishCharges = runReplenishCharges; + } + + /** + * @return the lowAlchemyCharges + */ + public int getLowAlchemyCharges() { + return lowAlchemyCharges; + } + + /** + * @param lowAlchemyCharges the lowAlchemyCharges to set + */ + public void setLowAlchemyCharges(int lowAlchemyCharges) { + this.lowAlchemyCharges = lowAlchemyCharges; + } + + /** + * @return the lowAlchemyDelay + */ + public long getLowAlchemyDelay() { + return lowAlchemyDelay; + } + + /** + * @param lowAlchemyDelay the lowAlchemyDelay to set + */ + public void setLowAlchemyDelay(long lowAlchemyDelay) { + this.lowAlchemyDelay = lowAlchemyDelay; + } + + /** + * @return the enableBoneCrusher + */ + public boolean isEnableBoneCrusher() { + return enableBoneCrusher; + } + + /** + * @param enableBoneCrusher the enableBoneCrusher to set + */ + public void setEnableBoneCrusher(boolean enableBoneCrusher) { + this.enableBoneCrusher = enableBoneCrusher; + } + + public boolean isEnableCoinMachine() { + return enableCoinMachine; + } + + public void setEnableCoinMachine(boolean enableCoinMachine) { + this.enableCoinMachine = enableCoinMachine; + } + + /** + * @return the magicSkillCapeDelay + */ + public long getMagicSkillCapeDelay() { + return magicSkillCapeDelay; + } + + /** + * @param magicSkillCapeDelay the magicSkillCapeDelay to set + */ + public void setMagicSkillCapeDelay(long magicSkillCapeDelay) { + this.magicSkillCapeDelay = magicSkillCapeDelay; + } + + /** + * @return the hunterCapeDelay + */ + public long getHunterCapeDelay() { + return hunterCapeDelay; + } + + /** + * @param hunterCapeDelay the hunterCapeDelay to set + */ + public void setHunterCapeDelay(long hunterCapeDelay) { + this.hunterCapeDelay = hunterCapeDelay; + } + + /** + * @return the hunterCapeCharges + */ + public int getHunterCapeCharges() { + return hunterCapeCharges; + } + + /** + * @param hunterCapeCharges the hunterCapeCharges to set + */ + public void setHunterCapeCharges(int hunterCapeCharges) { + this.hunterCapeCharges = hunterCapeCharges; + } + + /** + * @return the enableCharmCollector + */ + public boolean isEnableCharmCollector() { + return enableCharmCollector; + } + + /** + * @param enableCharmCollector the enableCharmCollector to set + */ + public void setEnableCharmCollector(boolean enableCharmCollector) { + this.enableCharmCollector = enableCharmCollector; + } + + /** + * Gets the Minigame Group Finder teleport delay. + * @return + */ + public long getMinigameTeleportDelay() { + return minigameTeleportDelay; + } + + /** + * Sets the Minigame Group Finder teleport delay. + * @param delay The delay to set. + */ + public void setMinigameTeleportDelay(long delay) { + this.minigameTeleportDelay = delay; + } + + public int getSavedH() { + return savedH; + } + + public void setSavedH(int savedH) { + this.savedH = savedH; + } + + public int getSavedY() { + return savedY; + } + + public void setSavedY(int savedY) { + this.savedY = savedY; + } + + public int getSavedX() { + return savedX; + } + + public void setSavedX(int savedX) { + this.savedX = savedX; + } + + public int getTaskAmount() { + return taskAmount; + } + + public void setTaskAmount(int taskAmount) { + this.taskAmount = taskAmount; + } + + public int getTaskPoints() { + return taskPoints; + } + + public void setTaskPoints(int taskPoints) { + this.taskPoints = taskPoints; + } + + public void setMacroDisabled(boolean disabled){this.macroDisabled = disabled;} + + public boolean getMacroDisabled() {return this.macroDisabled;} + + public boolean[] getAbyssData() { + return abyssData; + } + + public int getPlayerTestStage() { + return playerTestStage; + } +} diff --git a/Server/src/main/core/game/node/entity/player/link/HintIconManager.java b/Server/src/main/core/game/node/entity/player/link/HintIconManager.java new file mode 100644 index 0000000..e92f540 --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/HintIconManager.java @@ -0,0 +1,207 @@ +package core.game.node.entity.player.link; + +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.net.packet.PacketRepository; +import core.net.packet.context.HintIconContext; +import core.net.packet.out.HintIcon; + +/** + * The player's hint icon manager. + * @author Emperor + */ +public final class HintIconManager { + + /** + * The maximum size of hint icons. + */ + public static final int MAXIMUM_SIZE = 8; + + /** + * The default arrow id. + */ + public static final int DEFAULT_ARROW = 1; + + /** + * The default model id. + */ + public static final int DEFAULT_MODEL = -1; + + /** + * The arrow in a circle model id. + */ + public static final int ARROW_CIRCLE_MODEL = 40497; + + /** + * The hint icons. + */ + private HintIconContext[] hintIcons = new HintIconContext[MAXIMUM_SIZE]; + + /** + * Constructs a new {@code HintIconManager} {@code Object}. + */ + public HintIconManager() { + /* + * empty. + */ + } + + /** + * Registers a new hint icon. + * @param player The player. + * @param target The entity target. + * @return The slot of the hint icon. + */ + public static int registerHintIcon(Player player, Node target) { + return registerHintIcon(player, target, DEFAULT_ARROW, DEFAULT_MODEL, player.getHintIconManager().freeSlot()); + } + + /** + * Registers a new hint icon. + * @param player The player. + * @param target The entity target. + * @return The slot of the hint icon. + */ + public static int registerHeightHintIcon(Player player, Node target, int height) { + return registerHintIcon(player, target, DEFAULT_ARROW, DEFAULT_MODEL, player.getHintIconManager().freeSlot(), height); + } + + /** + * Registers a new hint icon. + * @param player The player. + * @param target The entity target. + * @param arrowId The arrow id to use. + * @return The slot of the hint icon. + */ + public static int registerHintIcon(Player player, Node target, int arrowId) { + return registerHintIcon(player, target, arrowId, DEFAULT_MODEL, player.getHintIconManager().freeSlot()); + } + + /** + * Registers a new hint icon. + * @param player The player. + * @param target The entity target. + * @param arrowId The arrow id to use. + * @param modelId The model id. + * @return The slot of the hint icon. + */ + public static int registerHintIcon(Player player, Node target, int arrowId, int modelId) { + return registerHintIcon(player, target, arrowId, modelId, player.getHintIconManager().freeSlot()); + } + + /** + * Registers a new hint icon. + * @param player The player. + * @param target The entity target. + * @param arrowId The arrow id to use. + * @param modelId The model id. + * @param slot The slot. + * @return The slot of the hint icon. + */ + public static int registerHintIcon(Player player, Node target, int arrowId, int modelId, int slot) { + if (slot < 0) { + return -1; + } + if (target == null) { + return 0; + } + HintIconManager mng = player.getHintIconManager(); + HintIconContext icon = new HintIconContext(player, slot, arrowId, target, modelId); + PacketRepository.send(HintIcon.class, icon); + mng.hintIcons[slot] = icon; + return slot; + } + + /** + * Registers a new hint icon. + * @param player The player. + * @param target The entity target. + * @param arrowId The arrow id to use. + * @param modelId The model id. + * @param slot The slot. + * @param height The height of the hint icon. + * @return The slot of the hint icon. + */ + public static int registerHintIcon(Player player, Node target, int arrowId, int modelId, int slot, int height) { + int type = 2; + if (target instanceof Entity) { + type = target instanceof Player ? 10 : 1; + } + return registerHintIcon(player, target, arrowId, modelId, slot, height, type); + } + + /** + * Registers a new hint icon. + * @param player The player. + * @param target The entity target. + * @param arrowId The arrow id to use. + * @param modelId The model id. + * @param slot The slot. + * @param height The height of the hint icon. + * @param targetType The target type. + * @return The slot of the hint icon. + */ + public static int registerHintIcon(Player player, Node target, int arrowId, int modelId, int slot, int height, int targetType) { + if (slot < 0) { + return -1; + } + HintIconManager mng = player.getHintIconManager(); + HintIconContext icon = new HintIconContext(player, slot, arrowId, targetType, target, modelId, height); + PacketRepository.send(HintIcon.class, icon); + mng.hintIcons[slot] = icon; + return slot; + } + + /** + * Removes a hint icon. + * @param player The player. + * @param slot The hint icon slot. + */ + public static void removeHintIcon(Player player, int slot) { + if (slot < 0) { + return; + } + HintIconManager mng = player.getHintIconManager(); + HintIconContext icon = mng.hintIcons[slot]; + if (icon != null) { + icon.setTargetType(0); + PacketRepository.send(HintIcon.class, icon); + mng.hintIcons[slot] = null; + } + } + + /** + * Clears the hint icons. + */ + public void clear() { + for (int i = 0; i < hintIcons.length; i++) { + HintIconContext icon = hintIcons[i]; + if (icon != null) { + removeHintIcon(icon.getPlayer(), i); + } + } + } + + /** + * Gets a free hint icon slot. + * @return The free slot. + */ + public int freeSlot() { + for (int i = 0; i < hintIcons.length; i++) { + if (hintIcons[i] == null) { + return i; + } + } + return -1; + } + + /** + * Gets the hint icon for the given slot. + * @param slot The slot. + * @return The hint icon context. + */ + public HintIconContext getIcon(int slot) { + return hintIcons[slot]; + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/player/link/InterfaceManager.java b/Server/src/main/core/game/node/entity/player/link/InterfaceManager.java new file mode 100644 index 0000000..4a0fb00 --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/InterfaceManager.java @@ -0,0 +1,775 @@ +package core.game.node.entity.player.link; + +import core.game.event.InterfaceCloseEvent; +import core.game.event.InterfaceOpenEvent; +import core.game.component.Component; +import core.game.component.InterfaceType; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.player.Player; +import core.net.packet.PacketRepository; +import core.net.packet.context.InterfaceContext; +import core.net.packet.context.WindowsPaneContext; +import core.net.packet.out.CloseInterface; +import core.net.packet.out.Interface; +import core.net.packet.out.WindowsPane; +import core.tools.Log; +import org.rs09.consts.Components; +import content.region.misc.tutisland.handlers.TutorialStage; + +import static core.api.ContentAPIKt.log; +import static core.api.ContentAPIKt.*; + + +/** + * Manages a player's interfaces. + * @author Emperor + * + */ +public final class InterfaceManager { + + /** + * The default windows pane. + */ + public static final int WINDOWS_PANE = Components.TOPLEVEL_548; + + /** + * The default chat box interface. + */ + public static final int DEFAULT_CHATBOX = Components.CHATDEFAULT_137; + + /** + * The default tabs. + */ + public static final int[] DEFAULT_TABS = { Components.WEAPON_FISTS_SEL_92, Components.STATS_320, Components.QUESTJOURNAL_V2_274, + Components.INVENTORY_149, Components.WORNITEMS_387, Components.PRAYER_271, Components.MAGIC_192, Components.LORE_STATS_SIDE_662, + Components.FRIENDS2_550, Components.IGNORE2_551, Components.CLANJOIN_589, Components.OPTIONS_261, Components.EMOTES_464, + Components.MUSIC_V3_187, Components.LOGOUT_182 }; + + /** + * The player. + */ + private final Player player; + + /** + * The amount of interface packets sent. + */ + private int packetCount; + + /** + * The windows pane. + */ + private Component windowsPane; + + /** + * The currently opened component. + */ + private Component opened; + + /** + * The tabs. + */ + private Component[] tabs = new Component[15]; + + /** + * The chatbox component. + */ + private Component chatbox; + + /** + * The single tab. + */ + private Component singleTab; + + /** + * The overlay component. + */ + private Component overlay; + + /** + * The wilderness overlay component + */ + private Component wildyOverlay; + + /** + * The currently opened tab's index. + */ + private int currentTabIndex = 3; + + /** + * Constructs a new {@code InterfaceManager} {@code Object}. + * + * @param player + * The player. + */ + public InterfaceManager(Player player) { + this.player = player; + } + + /** + * Opens the windows pane. + * + * @param windowsPane + * The windows pane. + * @return The component instance. + */ + public Component openWindowsPane(Component windowsPane) { + return openWindowsPane(windowsPane, false); + } + + /** + * Opens the windows pane. + * + * @param windowsPane + * The windows pane. + * @return The component instance. + */ + public Component openWindowsPane(Component windowsPane, boolean overlap) { + this.windowsPane = windowsPane; + if (windowsPane.getDefinition().getType() != InterfaceType.WINDOW_PANE) { + log(this.getClass(), Log.WARN, "Set interface type to WINDOW_PANE for component " + windowsPane.getId() + ", definition requires updating!"); + windowsPane.getDefinition().setType(InterfaceType.WINDOW_PANE); + } + + PacketRepository.send(WindowsPane.class, new WindowsPaneContext(player, windowsPane.getId(), overlap ? 1 : 0)); + windowsPane.open(player); + + if (opened != null) + player.dispatch(new InterfaceOpenEvent(opened)); + + return windowsPane; + } + + public void openWindowsPane(Component windowsPane, int type) { + this.windowsPane = windowsPane; + if (windowsPane.getDefinition().getType() != InterfaceType.WINDOW_PANE) { + log(this.getClass(), Log.WARN, "Set interface type to WINDOW_PANE for component " + windowsPane.getId() + ", definition requires updating!"); + windowsPane.getDefinition().setType(InterfaceType.SINGLE_TAB); + } + + PacketRepository.send(WindowsPane.class, new WindowsPaneContext(player, windowsPane.getId(), type)); + windowsPane.open(player); + + if (opened != null) + player.dispatch(new InterfaceOpenEvent(opened)); + } + + /** + * Opens a component. + * + * @param componentId + * The component id. + * @return The opened component. + */ + public Component openComponent(int componentId) { + return open(new Component(componentId)); + } + + /** + * Opens a component. + * @param component The component to open. + * @return The opened component. + */ + public Component open(Component component) { + if (!close()) { + return null; + } + component.open(player); + + opened = component; + player.dispatch(new InterfaceOpenEvent(opened)); + + return opened; + } + + /** + * Checks if a main interface. + * @return {@code True} if so. + */ + public boolean isOpened() { + return opened != null; + } + + /** + * Checks if the player has a chat box interface opened (disregarding default chat box). + * @return {@code True} if so. + */ + public boolean hasChatbox() { + return chatbox != null && chatbox.getId() != DEFAULT_CHATBOX; + } + + /** + * Safely closes the currently opened interface. + */ + public boolean close() { + if (player.getAttribute("runscript", null) != null) { + player.removeAttribute("runscript"); + player.getPacketDispatch().sendRunScript(101, ""); + } + // Component 333 is an immediate(no-fading) full-screen HD-mode black screen which auto-clears when interrupted. + if (overlay != null && overlay.getId() == 333) { + closeOverlay(); + } + if (opened != null && opened.close(player)) { + if (opened != null && (!opened.getDefinition().isWalkable() || opened.getId() == 14)) { + PacketRepository.send(CloseInterface.class, new InterfaceContext(player, opened.getDefinition().getWindowPaneId(isResizable()), opened.getDefinition().getChildId(isResizable()), opened.getId(), opened.getDefinition().isWalkable())); + player.dispatch(new InterfaceCloseEvent(opened)); + } + opened = null; + } + return opened == null; + } + + /** + * Checks if the current interface is walkable. + * @return True if so. + */ + public boolean isWalkable() { + if (opened != null) { + if (opened.getId() == Components.OBJDIALOG_389) { + return false; + } + if (opened.getDefinition().isWalkable()) { + return true; + } + } + return true; + } + + /** + * Safely closes the component. + * @param component The component. + * @return {@code True} if the component successfully closed. + */ + public boolean close(Component component) { + if (component.close(player)) { + if (component.getId() == DEFAULT_CHATBOX) { + return true; + } + if (component.getDefinition().getType() == InterfaceType.TAB) { + PacketRepository.send(CloseInterface.class, new InterfaceContext(player, component.getDefinition().getWindowPaneId(isResizable()), component.getDefinition().getChildId(isResizable()) + component.getDefinition().getTabIndex(), component.getId(), component.getDefinition().isWalkable())); + return true; + } + PacketRepository.send(CloseInterface.class, new InterfaceContext(player, component.getDefinition().getWindowPaneId(isResizable()), component.getDefinition().getChildId(isResizable()), component.getId(), component.getDefinition().isWalkable())); + return true; + } + return false; + } + + /** + * Closes the chatbox interface. + */ + public void closeChatbox() { + if (chatbox != null && chatbox.getId() != DEFAULT_CHATBOX) { + if (close(chatbox)) { + openChatbox(DEFAULT_CHATBOX); + player.getPacketDispatch().sendRunScript(101, ""); + } + } + } + + /** + * Opens a tab and removes the other tabs. + * @param component The component to open. + * @return The component. + */ + public Component openSingleTab(Component component) { + if (component.getDefinition().getType() != InterfaceType.SINGLE_TAB) { + log(this.getClass(), Log.WARN, "Set interface type to SINGLE_TAB for component " + component.getId() + ", definition requires updating!"); + component.getDefinition().setType(InterfaceType.SINGLE_TAB); + } + component.open(player); + if (component.getCloseEvent() == null) { + component.setCloseEvent((player, c) -> { +// openDefaultTabs(); + return true; + }); + } + return singleTab = component; + } + + /** + * Closes the current single tab opened. + */ + public boolean closeSingleTab() { + if (singleTab != null && close(singleTab)) { + singleTab = null; + } + return true; + } + + /** + * Gets the currently opened single tab. + * @return The tab opened. + */ + public Component getSingleTab() { + return singleTab; + } + + /** + * Removes the tabs. + * @param tabs The tab indexes. + */ + public void removeTabs(int... tabs) { + boolean changeViewedTab = false; + for (int slot : tabs) { + if (slot == currentTabIndex) { + changeViewedTab = true; + } + Component tab = this.tabs[slot]; + if (tab != null) { + close(tab); + this.tabs[slot] = null; + } + } + if (changeViewedTab) { + int currentIndex = -1; + if (this.tabs[3] == null) { + for (int i = 0; i < this.tabs.length; i++) { + if (this.tabs[i] != null) { + currentIndex = i; + break; + } + } + } else { + currentIndex = 3; + } + if (currentIndex > -1) { + setViewedTab(currentIndex); + } + } + } + + /** + * Restores the tabs. + */ + public void restoreTabs() { + for (int i = 0; i < tabs.length; i++) { + Component tab = tabs[i]; + if (tab == null) { + switch (i) { + case 0: + WeaponInterface inter = player.getExtension(WeaponInterface.class); + if (inter == null) { + player.addExtension(WeaponInterface.class, inter = new WeaponInterface(player)); + } + openTab(0, inter); + break; + case 6: + openTab(6, new Component(player.getSpellBookManager().getSpellBook())); // Magic + break; + case 7: + if (player.getFamiliarManager().hasFamiliar()) { + openTab(7, new Component(662)); + } + break; + default: + openTab(i, new Component(DEFAULT_TABS[i])); + } + } + else if (tab.isHidden()) { + int child = (i < 7 ? 38 : 13) + i; +// boolean resize = isResizable(); //TODO: + player.getPacketDispatch().sendInterfaceConfig(getWindowPaneId(), child, false); + player.getPacketDispatch().sendInterfaceConfig(getWindowPaneId(), child + 7, false); + tabs[i].setHidden(false); + } + } + } + + /** + * Opens the default tabs. + */ + public void openDefaultTabs() { + // player.getPacketDispatch().sendInterfaceConfig(548, 51, false); + WeaponInterface inter = player.getExtension(WeaponInterface.class); + if (inter == null) { + player.addExtension(WeaponInterface.class, inter = new WeaponInterface(player)); + } + //sendTab(16, 747); // Summoning bar + openTab(0, inter); // Attack + openTab(1, new Component(Components.STATS_320)); // Skills + openTab(2, new Component(Components.QUESTJOURNAL_V2_274)); // Quest + openTab(3, new Component(Components.INVENTORY_149)); // inventory + openTab(4, new Component(Components.WORNITEMS_387)); // Equipment + openTab(5, new Component(Components.PRAYER_271)); // Prayer + openTab(6, new Component(player.getSpellBookManager().getSpellBook())); // Magic + if (player.getFamiliarManager().hasFamiliar()) { + openTab(7, new Component(Components.LORE_STATS_SIDE_662)); // summoning. + } + openTab(8, new Component(Components.FRIENDS2_550)); // Friends + openTab(9, new Component(Components.IGNORE2_551)); // Ignores + openTab(10, new Component(Components.CLANJOIN_589)); // Clan chat + openTab(11, new Component(Components.OPTIONS_261)); // Settings + openTab(12, new Component(Components.EMOTES_464)); // Emotes + openTab(13, new Component(Components.MUSIC_V3_187)); // Music + openTab(14, new Component(Components.LOGOUT_182)); // Logout + if (player.getProperties().getAutocastSpell() != null) { + inter.selectAutoSpell(inter.getAutospellId(player.getProperties().getAutocastSpell().getSpellId()), true); + } + } + + /** + * Opens the information bars (orbs). + */ + public void openInfoBars() { + //Hp orb + PacketRepository.send(Interface.class, new InterfaceContext(player, getWindowPaneId(), isResizable() ? 13 : 70, Components.TOPSTAT_HITPOINTS_748, true)); + //Prayer orb + PacketRepository.send(Interface.class, new InterfaceContext(player, getWindowPaneId(), isResizable() ? 14 : 71, Components.TOPSTAT_PRAYER_749, true)); + //Energy orb + PacketRepository.send(Interface.class, new InterfaceContext(player, getWindowPaneId(), isResizable() ? 15 : 72, Components.TOPSTAT_RUN_750, true)); + //Summoning bar + PacketRepository.send(Interface.class, new InterfaceContext(player, getWindowPaneId(), isResizable() ? 16 : 73, Components.TOPSTAT_LORE_747, true)); + //Split PM + PacketRepository.send(Interface.class, new InterfaceContext(player, getWindowPaneId(), isResizable() ? 71 : 10, Components.PMCHAT_754, true)); + } + + /** + * Closes the default tabs. + */ + public void closeDefaultTabs() { + WeaponInterface inter = player.getExtension(WeaponInterface.class); + if (inter != null) { + close(inter); // Attack + } + close(new Component(Components.STATS_320)); // Skills + close(new Component(Components.QUESTJOURNAL_V2_274)); // Quest + close(new Component(Components.AREA_TASK_259)); // Diary + close(new Component(Components.INVENTORY_149)); // inventory + close(new Component(Components.WORNITEMS_387)); // Equipment + close(new Component(Components.PRAYER_271)); // Prayer + close(new Component(player.getSpellBookManager().getSpellBook())); + close(new Component(Components.LORE_STATS_SIDE_662)); // summoning. + close(new Component(Components.FRIENDS2_550)); // Friends + close(new Component(Components.IGNORE2_551)); // Ignores + close(new Component(Components.CLANJOIN_589)); // Clan chat + close(new Component(Components.OPTIONS_261)); // Settings + close(new Component(Components.EMOTES_464)); // Emotes + close(new Component(Components.MUSIC_V3_187)); // Music + //close(new Component(Components.LOGOUT_182)); // Logout + } + + /** + * Opens a tab. + * @param slot The tab slot; + * @param component The component. + */ + public void openTab(int slot, Component component) { + if (component.getId() == Components.WEAPON_FISTS_SEL_92 && !(component instanceof WeaponInterface)) { + throw new IllegalStateException("Attack tab can only be instanced as " + WeaponInterface.class.getCanonicalName() + "!"); + } + if (component.getDefinition().getTabIndex() != slot) { + log(this.getClass(), Log.WARN, "Set tab index to " + slot + " for component " + component.getId() + ", definition requires updating!"); + component.getDefinition().setTabIndex(slot); + } + if (component.getDefinition().getType() != InterfaceType.TAB) { + log(this.getClass(), Log.WARN, "Set interface type to TAB for component " + component.getId() + ", definition requires updating!"); + component.getDefinition().setType(InterfaceType.TAB); + } + component.open(player); + tabs[slot] = component; + } + + /** + * Opens a tab. + * @param component The component to open. + */ + public void openTab(Component component) { + if (component.getDefinition().getTabIndex() < 0) { + log(this.getClass(), Log.WARN, "No component definitions found for tab " + component.getId() + "!"); + return; + } + openTab(component.getDefinition().getTabIndex(), component); + } + + /** + * Opens a chat box interface. + * @param componentId The component id. + */ + public void openChatbox(int componentId) { + openChatbox(new Component(componentId)); + } + + /** + * Opens a chat box interface. + * @param component The component to open. + */ + public void openChatbox(Component component) { + if (component.getId() == DEFAULT_CHATBOX) { + if (chatbox == null || (chatbox.getId() != DEFAULT_CHATBOX && chatbox.getDefinition().getType() == InterfaceType.CHATBOX)) { + PacketRepository.send(Interface.class, new InterfaceContext(player, getWindowPaneId(), isResizable() ? 23 : 14, Components.FILTERBUTTONS_751, true)); + PacketRepository.send(Interface.class, new InterfaceContext(player, getWindowPaneId(), isResizable() ? 70 : 75, Components.CHATTOP_752, true)); + PacketRepository.send(Interface.class, new InterfaceContext(player, InterfaceType.CHATBOX.getFixedPaneId(), InterfaceType.CHATBOX.getFixedChildId(), Components.CHATDEFAULT_137, true)); + } + chatbox = component; + setVarp(player, 334, 1); + } else { + chatbox = component; + if (chatbox.getDefinition().getType() != InterfaceType.DIALOGUE && chatbox.getDefinition().getType() != InterfaceType.CHATBOX && chatbox.getDefinition().getType() != InterfaceType.CS_CHATBOX) { + log(this.getClass(), Log.WARN, "Set interface type to CHATBOX for component " + component.getId() + ", definition requires updating!"); + chatbox.getDefinition().setType(InterfaceType.DIALOGUE); + } + chatbox.open(player); + } + } + + /** + * Switches the player's window mode (fixed, resizable, fullscreen). + * @param windowMode The window mode. + */ + public void switchWindowMode(int windowMode) { + if (windowMode != player.getSession().getClientInfo().getWindowMode()) { + player.getSession().getClientInfo().setWindowMode(windowMode); + openWindowsPane(new Component(isResizable() ? Components.TOPLEVEL_FULLSCREEN_746 : Components.TOPLEVEL_548)); + if(!player.getAttribute("tutorial:complete", false)) { + TutorialStage.hideTabs(player, false); + } + else + { + openDefaultTabs(); + } + openInfoBars(); + PacketRepository.send(Interface.class, new InterfaceContext(player, getWindowPaneId(), isResizable() ? 23 : 14, Components.FILTERBUTTONS_751, true)); + PacketRepository.send(Interface.class, new InterfaceContext(player, getWindowPaneId(), isResizable() ? 70 : 75, Components.CHATTOP_752, true)); + } + } + + /** + * Gets the component for the given component id. + * @param componentId The component id. + * @return The component. + */ + public Component getComponent(int componentId) { + if (opened != null && opened.getId() == componentId) { + return opened; + } + if (chatbox != null && chatbox.getId() == componentId) { + return chatbox; + } + if (singleTab != null && singleTab.getId() == componentId) { + return singleTab; + } + if (overlay != null && overlay.getId() == componentId) { + return overlay; + } + if (windowsPane.getId() == componentId) { + return windowsPane; + } + for (Component c : tabs) { + if (c != null && c.getId() == componentId) { + return c; + } + } + if (componentId == Components.FILTERBUTTONS_751 || componentId == Components.TOPSTAT_RUN_750 || componentId == Components.TOPSTAT_LORE_747) { + //Chatbox settings, run orb & summoning orb. + return new Component(componentId); + } + return null; + } + + /** + * Sets the currently viewed tab. + * @param tabIndex The tab index. + */ + public void setViewedTab(int tabIndex) { + if (tabs[tabIndex] == null) { + return; + } + currentTabIndex = tabIndex; + switch (tabIndex) { + case 0: + tabIndex = 1; + break; + case 1: + tabIndex = 2; + break; + case 2: + tabIndex = 3; + break; + } + if (tabIndex > 9) { + tabIndex--; + } + player.getPacketDispatch().sendRunScript(115, "i", tabIndex); + } + + /** + * Checks if the main component opened matches the given component id. + * @param id The component id. + * @return {@code True} if so. + */ + public boolean hasMainComponent(int id) { + return opened != null && opened.getId() == id; + } + + /** + * Opens an overlay. + * @param component The component. + */ + public void openOverlay(Component component) { + if (overlay != null && !overlay.close(player)) { + return; + } + overlay = component; + if (overlay.getDefinition().getType() != InterfaceType.OVERLAY && overlay.getDefinition().getType() != InterfaceType.OVERLAY_B) { + log(this.getClass(), Log.WARN, "Set interface type to OVERLAY for component " + component.getId() + ", definition requires updating!"); + overlay.getDefinition().setType(InterfaceType.OVERLAY); + overlay.getDefinition().setWalkable(true); + } + overlay.open(player); + } + + /** + * Closes the current overlay. + */ + public void closeOverlay() { + if (overlay != null && close(overlay)) { + overlay = null; + } + } + + /** + * Gets the weapon tab interface. + * @return The weapon interface. + */ + public WeaponInterface getWeaponTab() { + return player.getExtension(WeaponInterface.class); + } + + /** + * Gets the opened. + * @return The opened. + */ + public Component getOpened() { + return opened; + } + + /** + * Sets the opened. + * @param opened The opened to set. + */ + public void setOpened(Component opened) { + this.opened = opened; + } + + /** + * Gets the tabs. + * @return The tabs. + */ + public Component[] getTabs() { + return tabs; + } + + /** + * Sets the tabs. + * @param tabs The tabs to set. + */ + public void setTabs(Component[] tabs) { + this.tabs = tabs; + } + + /** + * Gets the chatbox. + * @return The chatbox. + */ + public Component getChatbox() { + return chatbox; + } + + /** + * Sets the chatbox. + * @param chatbox The chatbox to set. + */ + public void setChatbox(Component chatbox) { + this.chatbox = chatbox; + } + + /** + * Gets the overlay. + * @return The overlay. + */ + public Component getOverlay() { + return overlay; + } + + /** + * Sets the overlay. + * @param overlay The overlay to set. + */ + public void setOverlay(Component overlay) { + this.overlay = overlay; + } + + /** + * Gets the player. + * @return The player. + */ + public Player getPlayer() { + return player; + } + + /** + * Gets the currentTabIndex. + * @return The currentTabIndex. + */ + public int getCurrentTabIndex() { + return currentTabIndex; + } + + /** + * Sets the currentTabIndex. + * @param currentTabIndex The currentTabIndex to set. + */ + public void setCurrentTabIndex(int currentTabIndex) { + this.currentTabIndex = currentTabIndex; + } + + /** + * Gets the windowsPane. + * @return The windowsPane. + */ + public Component getWindowsPane() { + return windowsPane; + } + + /** + * Gets the windows pane id. + * @return The window pane id. + */ + public int getWindowPaneId() { + if (windowsPane == null) { + return Components.TOPLEVEL_548; + } + return windowsPane.getId(); + } + + /** + * Gets the default child id. + * @return The default child id. + */ + public int getDefaultChildId() { + return isResizable() ? 6 : 11; + } + + /** + * Checks if the player's client is resizable. + * @return {@code True} if so. + */ + public boolean isResizable() { + if (player.getSession().getClientInfo() == null) { + return false; + } + return player.getSession().getClientInfo().isResizable(); + } + + /** + * Gets the amount of times an interface related packet was sent, then increments it. + * @param increment The amount to increment the counter with. + * @return The amount of times an interface packet was sent. + */ + public int getPacketCount(int increment) { + int count = packetCount; + packetCount += increment; + return count; + } +} diff --git a/Server/src/main/core/game/node/entity/player/link/IronmanManager.java b/Server/src/main/core/game/node/entity/player/link/IronmanManager.java new file mode 100644 index 0000000..f0e51fb --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/IronmanManager.java @@ -0,0 +1,85 @@ +package core.game.node.entity.player.link; + +import core.game.node.entity.player.Player; + + +import java.nio.ByteBuffer; + +/** + * Manages the iron man mode of an account. + * @author Vexia + * + */ +public class IronmanManager { + + /** + * The player instance. + */ + private final Player player; + + /** + * The iron man mode. + */ + private IronmanMode mode = IronmanMode.NONE; + + /** + * Constructs a new {@code IronmanManager} {@code Object} + * @param player the player. + */ + public IronmanManager(Player player) { + this.player = player; + } + + /** + * Checks the restriction. + * @return {@code True} if so. + */ + public boolean checkRestriction() { + return checkRestriction(IronmanMode.STANDARD); + } + + /** + * Checks the restriction. + * @return {@code True} if so. + */ + public boolean checkRestriction(IronmanMode mode) { + if (isIronman() && this.mode.ordinal() >= mode.ordinal()) { + player.sendMessage("You can't do that as an Ironman."); + return true; + } + return false; + } + + /** + * Checks if the player is an ironman. + * @return {@code True} if one. + */ + public boolean isIronman() { + return mode != IronmanMode.NONE; + } + + /** + * Gets the player. + * @return the player + */ + public Player getPlayer() { + return player; + } + + /** + * Gets the mode. + * @return the mode + */ + public IronmanMode getMode() { + return mode; + } + + /** + * Sets the mode. + * @param mode the mode to set. + */ + public void setMode(IronmanMode mode) { + this.mode = mode; + } + +} diff --git a/Server/src/main/core/game/node/entity/player/link/IronmanMode.java b/Server/src/main/core/game/node/entity/player/link/IronmanMode.java new file mode 100644 index 0000000..2573b3f --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/IronmanMode.java @@ -0,0 +1,32 @@ +package core.game.node.entity.player.link; + +/** + * A type of iron man mode. + * @author Vexia + */ +public enum IronmanMode { + // HARDCORE_DEAD has to be before Ultimate so that it does not adopt it's restrictions (on the basis of >= in IronmanManager.java?) + NONE(-1), STANDARD(5), HARDCORE(6), ULTIMATE(7); + + /** + * The icon id. + */ + private final int icon; + + /** + * Constructs a new {@code IronmanMode} {@code Object} + * @param icon the icon. + */ + private IronmanMode(int icon) { + this.icon = icon; + } + + /** + * Gets the icon. + * @return the icon + */ + public int getIcon() { + return icon; + } + +} diff --git a/Server/src/main/core/game/node/entity/player/link/PacketDispatch.java b/Server/src/main/core/game/node/entity/player/link/PacketDispatch.java new file mode 100644 index 0000000..53dd681 --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/PacketDispatch.java @@ -0,0 +1,434 @@ +package core.game.node.entity.player.link; + +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.tools.Log; +import core.tools.SystemLogger; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.chunk.AnimateObjectUpdateFlag; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import core.game.world.update.flag.EntityFlag; +import core.net.packet.PacketRepository; +import core.net.packet.context.*; +import core.net.packet.context.DisplayModelContext.ModelType; +import core.net.packet.out.*; + +import static core.api.ContentAPIKt.log; +import static core.api.ContentAPIKt.*; + + +/** + * Represents the class used to dispatching packets. + * @author Emperor + * @author Vexia + */ +public final class PacketDispatch { + + /** + * The instance of the {@code Player}. + */ + private final Player player; + + /** + * The player context. + */ + private final PlayerContext context; + + /** + * Constructs a new {@code PacketDispatch} {@code Object}. + * @param player the player. + */ + public PacketDispatch(Player player) { + this.player = player; + this.context = new PlayerContext(player); + } + + public void sendVarp (int index, int value) { + PacketRepository.send(Config.class, new ConfigContext(player, index, value)); + } + + public void sendVarcUpdate(short index, int value) { + PacketRepository.send(VarcUpdate.class, new VarcUpdateContext(player, index, value)); + } + + /** + * Send a game message. + * @param message The game message. + */ + public void sendMessage(String message) { + if (message == null) { + return; + } + if (player.getAttribute("chat_filter") != null && !message.contains("") && !message.contains("")) { + return; + } + if (message.length() > 255) { + log(this.getClass(), Log.ERR, "Message length out of bounds (" + message + ")!"); + message = message.substring(0, 255); + } + PacketRepository.send(GameMessage.class, new GameMessageContext(player, message)); + } + + /** + * Sends game messages. + * @param messages the messages. + */ + public void sendMessages(final String... messages) { + for (String message : messages) { + sendMessage(message); + } + } + + /** + * Method used to send a game message on a tick. + * @param message the message. + * @param ticks the ticks. + */ + public void sendMessage(final String message, int ticks) { + GameWorld.getPulser().submit(new Pulse(ticks, player) { + @Override + public boolean pulse() { + sendMessage(message); + return true; + } + }); + } + + /** + * Send a access mask. + * @param settingsHash The access mask settingsHash. + * @param childId The access mask child id. + * @param interfaceId The access mask interface Id. + * @param offset The access mask off set. + * @param length The access mask length. + */ + public void sendIfaceSettings(int settingsHash, int childId, int interfaceId, int offset, int length) { + PacketRepository.send(AccessMask.class, new AccessMaskContext(player, settingsHash, childId, interfaceId, offset, length)); + } + + /** + * Send a windowns pane. + * @param windowId The windows pane id. + * @param type The windowns pane type. + */ + public void sendWindowsPane(int windowId, int type) { + PacketRepository.send(WindowsPane.class, new WindowsPaneContext(player, windowId, type)); + } + + /** + * sends the system update packet. + * @param time the amount of time. + */ + public void sendSystemUpdate(int time) { + PacketRepository.send(SystemUpdatePacket.class, new SystemUpdateContext(player, time)); + } + + /** + * Sends music packet. + * @param musicId The music id. + */ + public void sendMusic(int musicId) { + PacketRepository.send(MusicPacket.class, new MusicContext(player, musicId)); + } + + /** + * Sends the temporary music packet. + * @param musicId The music id. + */ + public void sendTempMusic(int musicId) { + PacketRepository.send(MusicPacket.class, new MusicContext(player, musicId, true)); + } + + /** + * Sends a client script config to the player. + * @param id The id to set. + * @param value The value of the config. + */ + public void sendScriptConfig(int id, int value, String types, Object... parameters) { + PacketRepository.send(CSConfigPacket.class, new CSConfigContext(player, id, value, types, parameters)); + } + + /** + * Send a run script. + * @param id The run script id. + * @param string The run script string. + * @param objects The run scripts objects. + */ + public void sendRunScript(int id, String string, Object... objects) { + PacketRepository.send(RunScriptPacket.class, new RunScriptContext(player, id, string, objects)); + } + + /** + * Send a StringPacket. + * @param string The string. + * @param interfaceId The interface id. + * @param lineId The line id. + */ + public void sendString(String string, int interfaceId, int lineId) { + PacketRepository.send(StringPacket.class, new StringContext(player, string, interfaceId, lineId)); + } + + /** + * Send a update packet for the amount of run energy. + */ + public void sendRunEnergy() { + PacketRepository.send(RunEnergy.class, getContext()); + } + + /** + * Send the logout packet. + */ + public void sendLogout() { + PacketRepository.send(Logout.class, getContext()); + } + + /** + * Send the interface animation packet. + * @param animationId The animation id. + * @param interfaceId The interface id. + * @param childId The child id. + */ + public void sendAnimationInterface(int animationId, int interfaceId, int childId) { + PacketRepository.send(AnimateInterface.class, new AnimateInterfaceContext(player, animationId, interfaceId, childId)); + } + + /** + * Send the player on interface packet. + * @param interfaceId The interface id. + * @param childId The child id. + */ + public void sendPlayerOnInterface(int interfaceId, int childId) { + // fixme right now for iface 68-71 the player is massive + // The zoom for the other windows is 2150 + // for these 4 individuals it should be 796 but dmc.setZoom doesn't work + DisplayModelContext dmc = new DisplayModelContext(player, interfaceId, childId); + dmc.setZoom(796); // this appears to do nothing + PacketRepository.send(DisplayModel.class, dmc); + } + + /** + * Send the non-player character on interface packet. + * @param npcId The non-player character's id. + * @param interfaceId The interface id. + * @param childId The child id. + */ + public void sendNpcOnInterface(int npcId, int interfaceId, int childId) { + PacketRepository.send(DisplayModel.class, new DisplayModelContext(player, npcId, interfaceId, childId)); + } + + public void sendModelOnInterface(int modelID, int interfaceId, int childId, int zoom){ + PacketRepository.send(DisplayModel.class, new DisplayModelContext(player, ModelType.MODEL, modelID,zoom,interfaceId,childId,new Object())); + } + + public void sendAngleOnInterface(int interfaceId, int childId, int zoom, int pitch, int yaw){ + PacketRepository.send(InterfaceSetAngle.class, new DefaultContext(player, pitch, zoom, yaw, interfaceId, childId)); + } + + /** + * Send the item on interface packet. + * @param itemId The item id. + * @param amount The item amount. + * @param interfaceId The interface id. + * @param childId The child id. + */ + public void sendItemOnInterface(int itemId, int amount, int interfaceId, int childId) { + PacketRepository.send(DisplayModel.class, new DisplayModelContext(player, ModelType.ITEM, itemId, amount, interfaceId, childId)); + } + + /** + * Send the item on interface packet. + * @param itemId The item id. + * @param zoom the zoom. + * @param interfaceId The interface id. + * @param childId The child id. + */ + public void sendItemZoomOnInterface(int itemId, int zoom, int interfaceId, int childId) { + PacketRepository.send(DisplayModel.class, new DisplayModelContext(player, ModelType.ITEM, itemId, zoom, interfaceId, childId, zoom)); + } + + public void sendInterSetItemsOptionsScript(int interfaceId, int componentId, int key, int width, int height, String... options) { + sendInterSetItemsOptionsScript(interfaceId, componentId, key, false, width, height, options); + } + + public void sendInterSetItemsOptionsScript(int interfaceId, int componentId, int key, boolean negativeKey, int width, int height, String... options) { + Object[] parameters = new Object[6 + options.length]; + int index = 0; + for (int count = options.length - 1; count >= 0; count--) + parameters[index++] = options[count]; + parameters[index++] = -1; // dunno but always this + parameters[index++] = 0;// dunno but always this, maybe startslot? + parameters[index++] = height; + parameters[index++] = width; + parameters[index++] = key; + parameters[index++] = interfaceId << 16 | componentId; + sendRunScript(negativeKey ? 695 : 150, parameters); + // name says*/ + } + public void sendRunScript(int scriptId, Object... params) { + String parameterTypes = ""; + if (params != null) { + for (int count = params.length - 1; count >= 0; count--) { + if (params[count] instanceof String) + parameterTypes += "s"; // string + else + parameterTypes += "i"; // integer + } + } + sendRunScript(scriptId, parameterTypes, params); + } + + + /** + * Send the item on interface packet. + * @param itemId The item id. + * @param amount The amount. + * @param zoom the zoom. + * @param interfaceId The interface id. + * @param childId The child id. + */ + public void sendItemZoomOnInterface(int itemId, int amount, int zoom, int interfaceId, int childId) { + PacketRepository.send(DisplayModel.class, new DisplayModelContext(player, ModelType.ITEM, itemId, amount, interfaceId, childId, zoom)); + } + + /** + * Send the interface config packet. + * @param interfaceId The interface id. + * @param childId The child id. + * @param hide If the component should be hidden. + */ + public void sendInterfaceConfig(int interfaceId, int childId, boolean hide) { + PacketRepository.send(InterfaceConfig.class, new InterfaceConfigContext(player, interfaceId, childId, hide)); + } + + /** + * Send a animation update flag mask. + * @param id The animation id. + */ + public void sendAnimation(int id) { + player.getUpdateMasks().register(EntityFlag.Animate, new Animation(id)); + } + + /** + * Send a animation update flag mask. + * @param id The animation id. + * @param delay The animation delay. + */ + public void sendAnimation(int id, int delay) { + player.getUpdateMasks().register(EntityFlag.Animate, new Animation(id, delay)); + } + + /** + * Send a graphic update flag mask. + * @param id The graphic id. + */ + public void sendGraphic(int id) { + player.getUpdateMasks().register(EntityFlag.SpotAnim, new Graphics(id)); + } + + /** + * Sends the positioned graphic. + * @param id the id. + * @param height the height. + * @param delay the delay. + * @param location the location. + */ + public void sendPositionedGraphic(int id, int height, int delay, Location location) { + PacketRepository.send(PositionedGraphic.class, new PositionedGraphicContext(player, new Graphics(id, height, delay), location, 0, 0)); + } + + /** + * Sends a global graphic. + * @param id the id. + * @param location the location. + */ + public void sendGlobalPositionGraphic(int id, Location location) { + for (Player player : RegionManager.getLocalPlayers(location)) { + player.getPacketDispatch().sendPositionedGraphic(id, 0, 0, location); + } + } + + /** + * Sends the positioned graphic. + * @param graphics the graphics. + * @param location the location. + */ + public void sendPositionedGraphics(Graphics graphics, Location location) { + PacketRepository.send(PositionedGraphic.class, new PositionedGraphicContext(player, graphics, location, 0, 0)); + } + + /** + * Method used to send an object animation. + * @param object the object. + * @param animation the animation. + */ + public void sendSceneryAnimation(Scenery object, Animation animation) { + animation = new Animation(animation.getId(), animation.getDelay(), animation.getPriority()); + animation.setObject(object); + RegionManager.getRegionChunk(object.getLocation()).flag(new AnimateObjectUpdateFlag(animation)); + } + + /** + * Method used to send an object animation. + * @param object the object. + * @param animation the animation. + * @param global if the animation is global or not. + */ + public void sendSceneryAnimation(Scenery object, Animation animation, boolean global) { + if (global) { + sendSceneryAnimation(object, animation); + return; + } + animation.setObject(object); + PacketRepository.send(AnimateObjectPacket.class, new AnimateObjectContext(player, animation)); + } + + /** + * Send a graphic update flag mask. + * @param id The graphic id. + * @param height The graphic height. + */ + public void sendGraphic(int id, int height) { + player.getUpdateMasks().register(EntityFlag.SpotAnim, new Graphics(id, height)); + } + public void sendVarClient(int id, int value, boolean cs2) { + PacketRepository.send(Config.class, new ConfigContext(player, id, value, cs2)); + } + + public void sendLeftShiftedVarbit(int varpIndex, int offset, int value){ + setVarp(player, varpIndex, (value << offset)); + } + + public void sendRightShiftedVarbit(int varpIndex, int offset, int value){ + setVarp(player, varpIndex, (value >> offset)); + } + + + /** + * Gets the player. + * @return the player + */ + public Player getPlayer() { + return player; + } + + /** + * Gets the context. + * @return The context. + */ + public PlayerContext getContext() { + return context; + } + + public void sendScriptConfigs(int id, int value, String type, Object... params) { + PacketRepository.send(CSConfigPacket.class, new CSConfigContext(player, id, value, type, params)); + } + + public void resetInterface(int id) + { + PacketRepository.send(ResetInterface.class, new InterfaceContext(player, 0, 0, id, false)); + } +} diff --git a/Server/src/main/core/game/node/entity/player/link/QuestData.java b/Server/src/main/core/game/node/entity/player/link/QuestData.java new file mode 100644 index 0000000..110c89e --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/QuestData.java @@ -0,0 +1,287 @@ +package core.game.node.entity.player.link; + + +import core.game.node.item.Item; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; + +import java.util.Arrays; + +/** + * Represents the quest data to save. + * @author 'Vexia + */ +public final class QuestData { + + /** + * Represents the cooks assist attribute array. + */ + private final boolean[] cooksAssistant = new boolean[4]; + + /** + * Represents the demon slayer boolean array. + */ + private final boolean[] demonSlayer = new boolean[2]; + + /** + * Represents the draynor levers for ernest the chicken. + */ + private final boolean[] draynorLever = new boolean[6]; + + /** + * Represents the dragon slayer attribute array. + */ + private final boolean[] dragonSlayer = new boolean[9]; + + /** + * The desert treasure items. + */ + private final Item[] desertTreasure = new Item[7]; + + /** + * Represents the dragon slayer planks. + */ + private int dragonSlayerPlanks; + + /** + * Represents if the gardener has attacked. + */ + private boolean gardenerAttack; + + /** + * Represents if they talked to drezel. + */ + private boolean talkedDrezel; + + private int witchsExperimentStage; + + + private boolean witchsExperimentKilled; + + + /** + * Constructs a new {@code QuestData} {@code Object}. + */ + public QuestData() { + Arrays.fill(draynorLever, true); + populateDesertTreasureNode(); + } + + public void parse(JSONObject data){ + JSONArray dl = (JSONArray) data.get("draynorLever"); + for(int i = 0; i < dl.size(); i++){ + draynorLever[i] = (boolean) dl.get(i); + } + JSONArray drs = (JSONArray) data.get("dragonSlayer"); + for(int i = 0; i < drs.size(); i++){ + dragonSlayer[i] = (boolean) drs.get(i); + } + dragonSlayerPlanks = Integer.parseInt( data.get("dragonSlayerPlanks").toString()); + JSONArray des = (JSONArray) data.get("demonSlayer"); + for(int i = 0; i < des.size(); i++){ + demonSlayer[i] = (boolean) des.get(i); + } + JSONArray ca = (JSONArray) data.get("cooksAssistant"); + for(int i = 0; i < ca.size(); i++){ + cooksAssistant[i] = (boolean) ca.get(i); + } + gardenerAttack = (boolean) data.get("gardenerAttack"); + talkedDrezel = (boolean) data.get("talkedDrezel"); + JSONArray dtn = (JSONArray) data.get("desertTreasureNode"); + for (int i = 0; i < dtn.size(); i++){ + JSONObject item = (JSONObject) dtn.get(i); + desertTreasure[i] = new Item(Integer.parseInt(item.get("id").toString()), Integer.parseInt(item.get("amount").toString())); + } + witchsExperimentKilled = (boolean) data.get("witchsExperimentKilled"); + witchsExperimentStage = Integer.parseInt( data.get("witchsExperimentStage").toString()); + } + + /** + * Gets the draynorLever. + * @return The draynorLever. + */ + public boolean[] getDraynorLevers() { + return draynorLever; + } + + /** + * Gets the dragon slayer items. + * @return the dragon slayer. + */ + public boolean[] getDragonSlayerItems() { + return dragonSlayer; + } + + /** + * Gets the value of a inserted dragon slayer item. + * @param name the name. + * @return the value of the item being inserted. + */ + public boolean getDragonSlayerItem(String name) { + return name == "lobster" ? dragonSlayer[0] : name == "wizard" ? dragonSlayer[3] : name == "silk" ? dragonSlayer[2] : name == "bowl" ? dragonSlayer[1] : dragonSlayer[0]; + } + + /** + * Gets the dragon slayer attribute. + * @param name the name. + * @return the value of the attribute. + */ + public boolean getDragonSlayerAttribute(String name) { + return name == "ship" ? dragonSlayer[4] : name == "memorized" ? dragonSlayer[5] : name == "repaired" ? dragonSlayer[6] : name == "ned" ? dragonSlayer[7] : name == "poured" ? dragonSlayer[8] : dragonSlayer[8]; + } + + /** + * Method used to set a dragon slayer attribute. + * @param name the name. + * @param value the value. + */ + public void setDragonSlayerAttribute(String name, boolean value) { + dragonSlayer[(name == "ship" ? 4 : name == "memorized" ? 5 : name == "repaired" ? 6 : name == "ned" ? 7 : name == "poured" ? 8 : 8)] = value; + } + + /** + * Gets the cooks assistant attribute value. + * @param name the name. + * @return the value. + */ + public boolean getCookAssist(String name) { + return name == "milk" ? cooksAssistant[0] : name == "egg" ? cooksAssistant[1] : name == "flour" ? cooksAssistant[2] : name == "gave" ? cooksAssistant[3] : cooksAssistant[3]; + } + + /** + * Method used to set a cooks assistant attribute. + * @param name the name. + * @param value the value. + */ + public void setCooksAssistant(String name, boolean value) { + cooksAssistant[(name == "milk" ? 0 : name == "egg" ? 1 : name == "flour" ? 2 : name == "gave" ? 3 : 3)] = value; + } + + /** + * Gets the dragonSlayerPlanks. + * @return The dragonSlayerPlanks. + */ + public int getDragonSlayerPlanks() { + return dragonSlayerPlanks; + } + + /** + * Sets the dragonSlayerPlanks. + * @param i The dragonSlayerPlanks to set. + */ + public void setDragonSlayerPlanks(int i) { + this.dragonSlayerPlanks = i; + } + + /** + * Gets the demonSlayer. + * @return The demonSlayer. + */ + public boolean[] getDemonSlayer() { + return demonSlayer; + } + + /** + * Gets the cooksAssistant. + * @return The cooksAssistant. + */ + public boolean[] getCooksAssistant() { + return cooksAssistant; + } + + /** + * Gets the gardenerAttack. + * @return The gardenerAttack. + */ + public boolean isGardenerAttack() { + return gardenerAttack; + } + + /** + * Sets the gardenerAttack. + * @param gardenerAttack The gardenerAttack to set. + */ + public void setGardenerAttack(boolean gardenerAttack) { + this.gardenerAttack = gardenerAttack; + } + + /** + * Gets the talkedDrezel. + * @return The talkedDrezel. + */ + public boolean isTalkedDrezel() { + return talkedDrezel; + } + + /** + * Sets the talkedDrezel. + * @param talkedDrezel The talkedDrezel to set. + */ + public void setTalkedDrezel(boolean talkedDrezel) { + this.talkedDrezel = talkedDrezel; + } + + /** + * Populates the desert treasure node. + */ + private final void populateDesertTreasureNode() { + desertTreasure[0] = new Item(1513, 12); + desertTreasure[1] = new Item(592, 10); + desertTreasure[2] = new Item(1775, 6); + desertTreasure[3] = new Item(2353, 6); + desertTreasure[4] = new Item(526, 2); + desertTreasure[5] = new Item(973, 2); + desertTreasure[6] = new Item(565, 1); + } + + /** + * Gets the desert treasure item. + * @param index The index. + * @return The item. + */ + public Item getDesertTreasureItem(int index) { + if (index < 0 || index > desertTreasure.length) { + throw new IndexOutOfBoundsException("Index out of bounds, index can only span from 0 - 6."); + } + return desertTreasure[index]; + } + + /** + * Sets the desert treasure item. + * @param index The index. + * @param item The item to set. + */ + public void setDesertTreasureItem(int index, Item item) { + if (index < 0 || index > desertTreasure.length) { + throw new IndexOutOfBoundsException("Index out of bounds, index can only span from 0 - 6."); + } + desertTreasure[index] = item; + } + + public int getWitchsExperimentStage() { + return witchsExperimentStage; + } + + public void setWitchsExperimentStage(int witchsExperimentStage) { + this.witchsExperimentStage = witchsExperimentStage; + } + public boolean isWitchsExperimentKilled() { + return witchsExperimentKilled; + } + + public void setWitchsExperimentKilled(boolean witchsExperimentKilled) { + this.witchsExperimentKilled = witchsExperimentKilled; + } + + public boolean[] getDraynorLever() { + return draynorLever; + } + + public boolean[] getDragonSlayer() { + return dragonSlayer; + } + + public Item[] getDesertTreasure() { + return desertTreasure; + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/player/link/RunScript.java b/Server/src/main/core/game/node/entity/player/link/RunScript.java new file mode 100644 index 0000000..994e6e9 --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/RunScript.java @@ -0,0 +1,57 @@ +package core.game.node.entity.player.link; + +import core.game.node.entity.player.Player; + +/** + * Represents a run script. + * @author Vexia + */ +public abstract class RunScript { + + /** + * The player instance. + */ + protected Player player; + + /** + * The value entered. + */ + protected Object value; + + /** + * Constructs a new {@code RunScript} {@code Object}. + */ + public RunScript() { + /** + * empty. + */ + } + + /** + * Handles the run script. + * @return the return. + */ + public abstract boolean handle(); + + /** + * @return the value. + */ + public Object getValue() { + return value; + } + + /** + * @param value the value to set;. + */ + public void setValue(Object value) { + this.value = value; + } + + /** + * Sets the player. + * @param player the player. + */ + public void setPlayer(Player player) { + this.player = player; + } +} diff --git a/Server/src/main/core/game/node/entity/player/link/SavedData.java b/Server/src/main/core/game/node/entity/player/link/SavedData.java new file mode 100644 index 0000000..a0e0055 --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/SavedData.java @@ -0,0 +1,80 @@ +package core.game.node.entity.player.link; + +import core.game.node.entity.player.Player; + +/** + * Represents a managing class of saved data related to ingame interactions, + * such as questing data, npc talking data, etc. + * @author 'Vexia + */ +public class SavedData { + + /** + * Represents the global data to save. + */ + private final GlobalData globalData = new GlobalData(); + + /** + * Represents the activity data to save. + */ + private final ActivityData activityData = new ActivityData(); + + /** + * Represents the quest data to save. + */ + private final QuestData questData = new QuestData(); + + /** + * The player. + */ + private final Player player; + + /** + * Constructs a new {@Code SavedData} {@Code Object} + * @param player the player. + */ + public SavedData(Player player) { + this.player = player; + } + + /** + * Gets the boolean value. + * @param value the value. + * @return the value. + */ + public static boolean getBoolean(byte value) { + return value == 1; + } + + /** + * Gets the activityData. + * @return The activityData. + */ + public ActivityData getActivityData() { + return activityData; + } + + /** + * Gets the questData. + * @return The questData. + */ + public QuestData getQuestData() { + return questData; + } + + /** + * Gets the globalData. + * @return The globalData. + */ + public GlobalData getGlobalData() { + return globalData; + } + + /** + * Gets the player. + * @return the player + */ + public Player getPlayer() { + return player; + } +} diff --git a/Server/src/main/core/game/node/entity/player/link/Settings.java b/Server/src/main/core/game/node/entity/player/link/Settings.java new file mode 100644 index 0000000..920a656 --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/Settings.java @@ -0,0 +1,612 @@ +package core.game.node.entity.player.link; + +import core.game.system.config.ItemConfigParser; +import org.json.simple.JSONObject; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.net.packet.IoBuffer; + +import static core.api.ContentAPIKt.*; + + +/** + * Holds a player's settings. + * @author Emperor + */ +public final class Settings { + + /** + * The player. + */ + private final Player player; + + /** + * The run energy. + */ + private double runEnergy = 100.0; + + /** + * The player's weight. + */ + private double weight; + + /** + * The brightness setting. + */ + private int brightness = 2; + + /** + * The music volume. + */ + private int musicVolume; + + /** + * The sound effects volume. + */ + private int soundEffectVolume; + + /** + * The area sounds volume. + */ + private int areaSoundVolume; + + /** + * If the player has the single mouse button setting enabled. + */ + private boolean singleMouseButton; + + /** + * If the chat effects should be disabled. + */ + private boolean disableChatEffects; + + /** + * If the private chat should be split from public chat. + */ + private boolean splitPrivateChat; + + /** + * If the player has the accept aid setting enabled. + */ + private boolean acceptAid; + + /** + * If the player's run button is toggled. + */ + private boolean runToggled; + + /** + * The public chat setting. + */ + private int publicChatSetting = 0; + + /** + * The private chat setting. + */ + private int privateChatSetting = 0; + + /** + * The clan chat setting. + */ + private int clanChatSetting = 0; + + /** + * The trade setting. + */ + private int tradeSetting = 0; + + /** + * The assist setting. + */ + private int assistSetting = 0; + + /** + * If the special attack is toggled. + */ + private boolean specialToggled; + + /** + * The current special energy the player has left. + */ + private int specialEnergy = 100; + + /** + * The current attack style index. + */ + private int attackStyleIndex = 0; + + /** + * Constructs a new {@code Settings} {@code Object}. + * @param player The player. + */ + public Settings(Player player) { + this.player = player; + } + + /** + * Updates the settings. + */ + public void update() { + setVarp(player, 166, brightness + 1); + setVarp(player, 168, musicVolume); + setVarp(player, 169, soundEffectVolume); + setVarp(player, 872, areaSoundVolume); + setVarp(player, 170, singleMouseButton ? 1 : 0); + setVarp(player, 171, disableChatEffects ? 1 : 0); + setVarp(player, 287, splitPrivateChat ? 1 : 0); + setVarp(player, 427, acceptAid ? 1 : 0); + setVarp(player, 172, !player.getProperties().isRetaliating() ? 1 : 0); + setVarp(player, 173, runToggled ? 1 : 0); + setVarp(player, 1054, clanChatSetting); + setVarp(player, 1055, assistSetting); + setVarp(player, 300, specialEnergy * 10); + setVarp(player, 43, attackStyleIndex); + player.getPacketDispatch().sendRunEnergy(); + updateChatSettings(); + } + + /** + * Toggles the attack style index. + * @param index The index. + */ + public void toggleAttackStyleIndex(int index) { + this.attackStyleIndex = index; + setVarp(player, 43, attackStyleIndex); + } + + /** + * Updates the chat settings. + */ + public void updateChatSettings() { + player.getSession().write(new IoBuffer(232).put(publicChatSetting).put(privateChatSetting).put(tradeSetting)); + } + + /** + * Sets the chat settings. + * @param pub The public chat setting. + * @param priv The private chat setting. + * @param trade The trade setting. + */ + public void updateChatSettings(int pub, int priv, int trade) { + boolean update = false; + if (publicChatSetting != pub) { + publicChatSetting = pub; + update = true; + } + if (tradeSetting != trade) { + tradeSetting = trade; + update = true; + } + if (update) { + updateChatSettings(); + } + } + + /** + * Sets the chat settings. + * @param pub The public chat setting. + * @param priv The private chat setting. + * @param trade The trade setting. + */ + public void setChatSettings(int pub, int priv, int trade) { + publicChatSetting = pub; + privateChatSetting = priv; + tradeSetting = trade; + } + + /** + * Parses the settings from the save file. + * @param settingsData The JSON object. + */ + public void parse(JSONObject settingsData){ + brightness = Integer.parseInt( settingsData.get("brightness").toString()); + musicVolume = Integer.parseInt( settingsData.get("musicVolume").toString()); + soundEffectVolume = Integer.parseInt( settingsData.get("soundEffectVolume").toString()); + areaSoundVolume = Integer.parseInt( settingsData.get("areaSoundVolume").toString()); + singleMouseButton = (boolean) settingsData.get("singleMouse"); + disableChatEffects = (boolean) settingsData.get("disableChatEffects"); + splitPrivateChat = (boolean) settingsData.get("splitPrivate"); + acceptAid = (boolean) settingsData.get("acceptAid"); + runToggled = (boolean) settingsData.get("runToggled"); + publicChatSetting = Integer.parseInt( settingsData.get("publicChatSetting").toString()); + privateChatSetting = Integer.parseInt( settingsData.get("privateChatSetting").toString()); + clanChatSetting = Integer.parseInt( settingsData.get("clanChatSetting").toString()); + tradeSetting = Integer.parseInt( settingsData.get("tradeSetting").toString()); + assistSetting = Integer.parseInt( settingsData.get("assistSetting").toString()); + runEnergy = Double.parseDouble( settingsData.get("runEnergy").toString()); + specialEnergy = Integer.parseInt( settingsData.get("specialEnergy").toString()); + attackStyleIndex = Integer.parseInt( settingsData.get("attackStyle").toString()); + player.getProperties().setRetaliating((boolean) settingsData.get("retaliation")); + } + + /** + * Toggles the special attack bar. + */ + public void toggleSpecialBar() { + setSpecialToggled(!specialToggled); + } + + /** + * Toggles the special attack bar. + * @param enable If the special attack should be enabled. + */ + public void setSpecialToggled(boolean enable) { + specialToggled = !specialToggled; + setVarp(player, 301, specialToggled ? 1 : 0); + } + + /** + * Checks if the special attack bar is toggled. + * @return {@code True} if so. + */ + public boolean isSpecialToggled() { + return specialToggled; + } + + /** + * Drains an amount of special attack energy. + * @param amount The amount to drain. + * @return {@code True} if succesful, {@code false} if the special attack + * energy amount hasn't changed after calling this method. + */ + public boolean drainSpecial(int amount) { + if (!specialToggled) { + return false; + } + setSpecialToggled(false); + if (amount > specialEnergy) { + player.getPacketDispatch().sendMessage("You do not have enough special attack energy left."); + return false; + } + setSpecialEnergy(specialEnergy - amount); + return true; + } + + /** + * Sets the special energy amount. + * @param value The amount to set. + */ + public void setSpecialEnergy(int value) { + specialEnergy = value; + setVarp(player, 300, specialEnergy * 10); + } + + /** + * Gets the amount of special energy left. + * @return The amount of energy. + */ + public int getSpecialEnergy() { + return specialEnergy; + } + + /** + * Toggles the retaliating button. + */ + public void toggleRetaliating() { + player.getProperties().setRetaliating(!player.getProperties().isRetaliating()); + setVarp(player, 172, !player.getProperties().isRetaliating() ? 1 : 0); + } + + /** + * Toggles the singleMouseButton. + */ + public void toggleMouseButton() { + singleMouseButton = !singleMouseButton; + setVarp(player, 170, singleMouseButton ? 1 : 0); + } + + /** + * Toggles the disableChatEffects. + */ + public void toggleChatEffects() { + disableChatEffects = !disableChatEffects; + setVarp(player, 171, disableChatEffects ? 1 : 0); + } + + /** + * Toggles the splitPrivateChat. + */ + public void toggleSplitPrivateChat() { + splitPrivateChat = !splitPrivateChat; + setVarp(player, 287, splitPrivateChat ? 1 : 0); + } + + /** + * Toggles the acceptAid. + */ + public void toggleAcceptAid() { + acceptAid = !acceptAid; + setVarp(player, 427, acceptAid ? 1 : 0); + } + + /** + * Toggles the run button. + */ + public void toggleRun() { + setRunToggled(!runToggled); + } + + /** + * Toggles the run button. + * If the run button should be enabled. + */ + public void setRunToggled(boolean enabled) { + runToggled = enabled; + setVarp(player, 173, runToggled ? 1 : 0); + } + + /** + * Decreases the run energy with the given amount (drain parameter).
To + * increase, use a negative drain value. + * @param drain The drain amount. + */ + public void updateRunEnergy(double drain) { + runEnergy -= drain; + if (runEnergy < 0) { + runEnergy = 0.0; + } else if (runEnergy > 100) { + runEnergy = 100.0; + } + player.getPacketDispatch().sendRunEnergy(); + } + + /** + * Updates the weight. + */ + public void updateWeight() { + weight = 0.0; + for (int i = 0; i < 28; i++) { + Item item = player.getInventory().get(i); + if (item == null) { + continue; + } + double value = item.getDefinition().getConfiguration(ItemConfigParser.WEIGHT, 0.0); + if (value > 0) { + weight += value; + } + } + for (int i = 0; i < 11; i++) { + Item item = player.getEquipment().get(i); + if (item == null) { + continue; + } + weight += item.getDefinition().getConfiguration(ItemConfigParser.WEIGHT, 0.0); + } + player.getPacketDispatch().sendString((int) weight + " kg", 667, 32); + } + + /** + * Gets the weight. + * @return The weight. + */ + public double getWeight() { + return weight; + } + + /** + * Gets the brightness. + * @return The brightness. + */ + public int getBrightness() { + return brightness; + } + + /** + * Sets the brightness. + * @param brightness The brightness to set. + */ + public void setBrightness(int brightness) { + this.brightness = brightness; + setVarp(player, 166, brightness + 1); + } + + /** + * Gets the musicVolume. + * @return The musicVolume. + */ + public int getMusicVolume() { + return musicVolume; + } + + /** + * Sets the musicVolume. + * @param musicVolume The musicVolume to set. + */ + public void setMusicVolume(int musicVolume) { + this.musicVolume = musicVolume; + setVarp(player, 168, musicVolume); + } + + /** + * Gets the soundEffectVolume. + * @return The soundEffectVolume. + */ + public int getSoundEffectVolume() { + return soundEffectVolume; + } + + /** + * Sets the soundEffectVolume. + * @param soundEffectVolume The soundEffectVolume to set. + */ + public void setSoundEffectVolume(int soundEffectVolume) { + this.soundEffectVolume = soundEffectVolume; + setVarp(player, 169, soundEffectVolume); + } + + /** + * Gets the areaSoundVolume. + * @return The areaSoundVolume. + */ + public int getAreaSoundVolume() { + return areaSoundVolume; + } + + /** + * Sets the areaSoundVolume. + * @param areaSoundVolume The areaSoundVolume to set. + */ + public void setAreaSoundVolume(int areaSoundVolume) { + this.areaSoundVolume = areaSoundVolume; + setVarp(player, 872, areaSoundVolume); + } + + /** + * Gets the singleMouseButton. + * @return The singleMouseButton. + */ + public boolean isSingleMouseButton() { + return singleMouseButton; + } + + /** + * Gets the disableChatEffects. + * @return The disableChatEffects. + */ + public boolean isDisableChatEffects() { + return disableChatEffects; + } + + /** + * Gets the splitPrivateChat. + * @return The splitPrivateChat. + */ + public boolean isSplitPrivateChat() { + return splitPrivateChat; + } + + /** + * Gets the acceptAid. + * @return The acceptAid. + */ + public boolean isAcceptAid() { + if (player.getIronmanManager().isIronman()) { + return false; + } + return acceptAid; + } + + /** + * Gets the runToggled. + * @return The runToggled. + */ + public boolean isRunToggled() { + return runToggled; + } + + /** + * Gets the publicChatSetting. + * @return The publicChatSetting. + */ + public int getPublicChatSetting() { + return publicChatSetting; + } + + /** + * Sets the publicChatSetting. + * @param publicChatSetting The publicChatSetting to set. + */ + public void setPublicChatSetting(int publicChatSetting) { + this.publicChatSetting = publicChatSetting; + updateChatSettings(); + } + + /** + * Gets the privateChatSetting. + * @return The privateChatSetting. + */ + public int getPrivateChatSetting() { + return privateChatSetting; + } + + /** + * Sets the privateChatSetting. + * @param privateChatSetting The privateChatSetting to set. + */ + public void setPrivateChatSetting(int privateChatSetting) { + this.privateChatSetting = privateChatSetting; + updateChatSettings(); + } + + /** + * Gets the clanChatSetting. + * @return The clanChatSetting. + */ + public int getClanChatSetting() { + return clanChatSetting; + } + + /** + * Sets the clanChatSetting. + * @param clanChatSetting The clanChatSetting to set. + */ + public void setClanChatSetting(int clanChatSetting) { + this.clanChatSetting = clanChatSetting; + setVarp(player, 1054, clanChatSetting); + } + + /** + * Gets the tradeSetting. + * @return The tradeSetting. + */ + public int getTradeSetting() { + return tradeSetting; + } + + /** + * Sets the tradeSetting. + * @param tradeSetting The tradeSetting to set. + */ + public void setTradeSetting(int tradeSetting) { + this.tradeSetting = tradeSetting; + updateChatSettings(); + } + + /** + * Gets the assistSetting. + * @return The assistSetting. + */ + public int getAssistSetting() { + return assistSetting; + } + + /** + * Sets the assistSetting. + * @param assistSetting The assistSetting to set. + */ + public void setAssistSetting(int assistSetting) { + this.assistSetting = assistSetting; + setVarp(player, 1055, assistSetting); + } + + /** + * @return the runEnergy + */ + public double getRunEnergy() { + return runEnergy; + } + + /** + * @param runEnergy the runEnergy to set + */ + public void setRunEnergy(double runEnergy) { + this.runEnergy = runEnergy; + } + + /** + * Gets the attackStyleIndex. + * @return The attackStyleIndex. + */ + public int getAttackStyleIndex() { + return attackStyleIndex; + } + + /** + * Sets the attackStyleIndex. + * @param attackStyleIndex The attackStyleIndex to set. + */ + public void setAttackStyleIndex(int attackStyleIndex) { + this.attackStyleIndex = attackStyleIndex; + } + +} diff --git a/Server/src/main/core/game/node/entity/player/link/SkullManager.java b/Server/src/main/core/game/node/entity/player/link/SkullManager.java new file mode 100644 index 0000000..7b3f97c --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/SkullManager.java @@ -0,0 +1,310 @@ +package core.game.node.entity.player.link; + +import core.game.container.Container; +import core.game.container.ContainerEvent; +import core.game.container.ContainerListener; +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.ServerConstants; +import static core.api.ContentAPIKt.*; + +import java.util.ArrayList; +import java.util.List; + +import static core.tools.GlobalsKt.colorize; +import static core.game.world.map.zone.impl.WildernessZone.WILDERNESS_PROT_ATTR; + +/** + * Represents a managing class of the active player skulls. + * @author Vexia + * @author Emperor + */ +public final class SkullManager { + public enum SkullIcon { + NONE(-1), + WHITE(0), + RED(1), + BH_RED5(2), + BH_BLUE4(3), + BH_GREEN3(4), + BH_GREY2(5), + BH_BROWN1(6), + SCREAM(7); + public final int id; + SkullIcon(int id) { + this.id = id; + } + public static SkullIcon forId(int id) { + switch(id) { + case 0: return SkullIcon.WHITE; + case 1: return SkullIcon.RED; + case 2: return SkullIcon.BH_RED5; + case 3: return SkullIcon.BH_BLUE4; + case 4: return SkullIcon.BH_GREEN3; + case 5: return SkullIcon.BH_GREY2; + case 6: return SkullIcon.BH_BROWN1; + case 7: return SkullIcon.SCREAM; + default: return SkullIcon.NONE; + } + } + } + + + /** + * The player instance. + */ + private final Player player; + + /** + * Represents if the player is in the wilderness. + */ + private boolean wilderness = false; + + /** + * If the wilderness zone is currently disabled. + */ + private boolean wildernessDisabled = false; + + /** + * Represents the current wilderness level. + */ + private int level; + + /** + * The players this player has skulled on. + */ + private final List skullCauses = new ArrayList(); + + /** + * If the player is skulled. + */ + private boolean skulled; + + /** + * If the skull check is disabled. + */ + private boolean skullCheckDisabled; + + private boolean deepWilderness; + + /** + * Constructs a new {@code SkullManager} {@code Object}. + * @param player the player. + */ + public SkullManager(Player player) { + this.player = player; + } + + /** + * Checks if we should skull on this entity. + * @param other The entity to check. + */ + public void checkSkull(Entity other) { + if (!(other instanceof Player) || !wilderness || skullCheckDisabled) { + return; + } + Player o = (Player) other; + for (Player p : o.getSkullManager().skullCauses) { + if (p == player) { + return; + } + } + if (skullCauses.contains(o)) { + return; + } + skullCauses.add(o); + removeTimer (player, "skulled"); + registerTimer (player, spawnTimer("skulled", 2000)); + } + + /** + * Sets the skull icon. + * @param skullIcon The skull icon. + */ + public void setSkullIcon(int skullIcon) { + player.getAppearance().setSkullIcon(skullIcon); + player.updateAppearance(); + } + + /** + * Resets the skull causes cache. + */ + public void reset() { + skullCauses.clear(); + setSkullIcon(-1); + setSkulled(false); + player.getAppearance().sync(); + } + + /** + * Gets the player. + * @return the player. + */ + public Player getPlayer() { + return player; + } + + /** + * Gets the level. + * @return the level. + */ + public int getLevel() { + return level; + } + + /** + * Sets the level. + * @param level the level to set. + */ + public void setLevel(int level) { + if (!deepWilderness && level >= 49) + setDeepWilderness(true); + else if (deepWilderness && level < 48) + setDeepWilderness(false); + + if (level > 20) + player.getLocks().lockTeleport (1_000_000); + else + player.getLocks().unlockTeleport(); + + this.level = level; + } + + /** + * Gets the value. + * @return the wilderness. + */ + public boolean isWilderness() { + return wilderness; + } + + /** + * Sets the value of this boolean. + * @param wilderness the wilderness to set. + */ + public void setWilderness(boolean wilderness) { + this.wilderness = wilderness; + } + + /** + * Gets the skullCheckDisabled. + * @return The skullCheckDisabled. + */ + public boolean isSkullCheckDisabled() { + return skullCheckDisabled; + } + + /** + * Sets the skullCheckDisabled. + * @param skullCheckDisabled The skullCheckDisabled to set. + */ + public void setSkullCheckDisabled(boolean skullCheckDisabled) { + this.skullCheckDisabled = skullCheckDisabled; + } + + /** + * Gets the wildernessDisabled. + * @return The wildernessDisabled. + */ + public boolean isWildernessDisabled() { + return wildernessDisabled; + } + + public boolean hasWildernessProtection() { + return level < 49; + } + + /** + * Sets the wildernessDisabled. + * @param wildernessDisabled The wildernessDisabled to set. + */ + public void setWildernessDisabled(boolean wildernessDisabled) { + this.wildernessDisabled = wildernessDisabled; + } + + /** + * Gets the skulled. + * @return The skulled. + */ + public boolean isSkulled() { + return skulled || deepWilderness; + } + + public boolean isDeepWilderness() { + return deepWilderness; + } + + public void setDeepWilderness (boolean deepWildy) { + if(ServerConstants.ENHANCED_DEEP_WILDERNESS && deepWildy) { + updateDWSkullIcon(); + } else { + removeDWSkullIcon(); + } + setSkullCheckDisabled(deepWildy); + deepWilderness = deepWildy; + } + + public static final long DEEP_WILD_DROP_RISK_THRESHOLD = 100000; + public void updateDWSkullIcon() { + if (player.getAttribute("deepwild-value-listener") == null) { + ContainerListener listener = new ContainerListener() { + @Override + public void update(Container c, ContainerEvent event) { + refresh(c); + } + + @Override + public void refresh(Container c) { + updateDWSkullIcon(); + } + }; + player.setAttribute("deepwild-value-listener", listener); + player.getInventory().getListeners().add(listener); + player.getEquipment().getListeners().add(listener); + } + long value = 0; + long maxValue = 0; + for (Item item : player.getInventory().toArray()) { + if (item != null) { + long alchValue = item.getAlchemyValue(); + value += alchValue; + maxValue = Math.max(maxValue, alchValue); + } + } + for (Item item : player.getEquipment().toArray()) { + if (item != null) { + long alchValue = item.getAlchemyValue(); + value += alchValue; + maxValue = Math.max(maxValue, alchValue); + } + } + // Act as if protect item is always active when calculating risk + value -= maxValue; + player.setAttribute("deepwild-value-risk", value); + SkullIcon skull = SkullIcon.BH_BROWN1; + if (value >= DEEP_WILD_DROP_RISK_THRESHOLD) { + skull = SkullIcon.RED; + } + setSkullIcon(skull.id); + } + + public void removeDWSkullIcon() { + setSkullIcon(skulled ? 0 : -1); + ContainerListener listener = player.getAttribute("deepwild-value-listener"); + if (listener != null) { + player.getInventory().getListeners().remove(listener); + player.getEquipment().getListeners().remove(listener); + } + player.removeAttribute("deepwild-value-listener"); + player.removeAttribute("deepwild-value-risk"); + } + + /** + * Sets the skulled. + * @param skulled The skulled to set. + */ + public void setSkulled(boolean skulled) { + this.skulled = skulled; + } +} diff --git a/Server/src/main/core/game/node/entity/player/link/SpellBookManager.java b/Server/src/main/core/game/node/entity/player/link/SpellBookManager.java new file mode 100644 index 0000000..f5dbc2d --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/SpellBookManager.java @@ -0,0 +1,135 @@ +package core.game.node.entity.player.link; + +import core.game.component.Component; +import core.game.node.entity.combat.spell.MagicSpell; +import core.game.node.entity.player.Player; + + +import java.util.HashMap; +import java.util.Map; + +/** + * Represents a managing class of a players spell book. + * @author Vexia + */ +public final class SpellBookManager { + + /** + * Represents the current interface if of the spellbook. + */ + private int spellBook = SpellBook.MODERN.getInterfaceId(); + + /** + * Constructs a new {@code SpellBookManager} {@code Object}. + */ + public SpellBookManager() { + /** + * empty. + */ + } + + /** + * Sets the spell book. + * @param book + */ + public void setSpellBook(SpellBook book) { + this.spellBook = book.getInterfaceId(); + } + + /** + * Updates the + * @param player + */ + public void update(Player player) { + player.getInterfaceManager().openTab(new Component(SpellBook.forInterface(this.spellBook).getInterfaceId())); + } + + /** + * Gets the spell book. + * @return the spellBook + */ + public int getSpellBook() { + return spellBook; + } + + /** + * Represents a characters spellbook. + * @author 'Vexia + * @author Emperor + */ + public enum SpellBook { + + /** + * The modern magic spell book. + */ + MODERN(192), + + /** + * The ancient magicks spell book. + */ + ANCIENT(193), + + /** + * The lunar magic spell book. + */ + LUNAR(430); + + /** + * The interface id of this spell book. + */ + private final int interfaceId; + + /** + * The spells mapping. + */ + private final Map spells = new HashMap<>(); + + /** + * Creates the spell book. + * @param interfaceId The spellbook interface id. + */ + SpellBook(int interfaceId) { + this.interfaceId = interfaceId; + } + + /** + * @return The interfaceId. + */ + public int getInterfaceId() { + return interfaceId; + } + + /** + * Method used to get the book. + * @param id the id. + */ + public static SpellBook forInterface(final int id) { + for (SpellBook book : SpellBook.values()) { + if (book.interfaceId == id) { + return book; + } + } + return null; + } + + /** + * Registers a new spell. + * @param buttonId The button id. + * @param spell The spell. + */ + public void register(int buttonId, MagicSpell spell) { + spell.setSpellId(buttonId); + spells.put(buttonId, spell); + } + + /** + * Gets a spell from the spellbook. + * @param buttonId The button id. + * @return The spell. + */ + public MagicSpell getSpell(int buttonId) { + return spells.get(buttonId); + } + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/player/link/TeleportManager.java b/Server/src/main/core/game/node/entity/player/link/TeleportManager.java new file mode 100644 index 0000000..140ecf4 --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/TeleportManager.java @@ -0,0 +1,808 @@ +package core.game.node.entity.player.link; + +import core.ServerConstants; +import core.game.node.entity.Entity; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.zone.ZoneRestriction; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; +import org.rs09.consts.Sounds; + +import static core.api.ContentAPIKt.*; + +/** + * Handles the entity teleport. + * @author SonicForce41 + * @author Woah + */ +public class TeleportManager { + + /** + * The wildy teleport type. + */ + public static final int WILDY_TELEPORT = 1 << 16 | 8; + + /** + * The animations used in the home teleport. + */ + private final static int[] HOME_ANIMATIONS = {1722, 1723, 1724, 1725, 2798, 2799, 2800, 3195, 4643, 4645, 4646, 4847, 4848, 4849, 4850, 4851, 4852, 65535}; + + /** + * The graphics used in the home teleport. + */ + private final static int[] HOME_GRAPHICS = {775, 800, 801, 802, 803, 804, 1703, 1704, 1705, 1706, 1707, 1708, 1709, 1710, 1711, 1712, 1713, 65535}; + + /** + * The entity being handled. + */ + private final Entity entity; + + /** + * The last teleport of this Entity + */ + private Pulse lastTeleport; + + /** + * The current teleport of this Entity + */ + private Pulse currentTeleport; + + /** + * The current teleport type. + */ + private int teleportType; + + /** + * Constructs a new {@code Teleporter.java} {@Code Object}. + * @param entity the Entity + */ + public TeleportManager(Entity entity) { + this.entity = entity; + lastTeleport = TeleportType.HOME.getPulse(entity, ServerConstants.HOME_LOCATION); + } + + /** + * Sends the teleport. + * @param location the Location. + * @return {@code True} if the player successfully started teleporting. + */ + public boolean send(Location location) { + return send(location, entity instanceof Player ? getType((Player) entity) : TeleportType.NORMAL, 0); + } + + /** + * Sends the teleport. + * @param location the Location. + * @param type the NodeType. + * @return {@code True} if the player successfully started teleporting. + */ + public boolean send(Location location, TeleportType type) { + return send(location, type, 0); + } + + /** + * Sends the teleport. + * @param location the Location. + * @param type the NodeType. + * @param teleportType The teleporting type. (0=spell, 1=item, 2=object, + * 3=npc -1= force) + * @return {@code True} if the player successfully started teleporting. + */ + public boolean send(Location location, TeleportType type, int teleportType) { + if (teleportType == WILDY_TELEPORT || type == TeleportType.OBELISK) { + if (hasTimerActive(entity, "teleblock")) return false; + } else { + if (!entity.getZoneMonitor().teleport(teleportType, null)) { + return false; + } + if (teleportType != -1 && entity.isTeleBlocked()) { + if (entity.isPlayer()) + entity.asPlayer().sendMessage("A magical force has stopped you from teleporting."); + return false; + } + } + if (teleportType != -1) { + if (entity instanceof Player) { + Player p = (Player) entity; + p.getDialogueInterpreter().close(); + } + } + if(entity.getAttribute("tablet-spell",false)){ + type = TeleportType.TELETABS; + } + this.teleportType = teleportType; + entity.getWalkingQueue().reset(); + lastTeleport = currentTeleport; + currentTeleport = type.getPulse(entity, location); + entity.getPulseManager().clear(); + if (type == TeleportType.HOME) { + entity.getPulseManager().run(type.getPulse(entity, location)); + } else { + entity.lock(12); + entity.getImpactHandler().setDisabledTicks(teleportType == -1 ? 5 : 12); + GameWorld.getPulser().submit(currentTeleport); + } + if (entity instanceof Player) { + ((Player) entity).getInterfaceManager().close(); + } + return true; + } + + /** + * Fires a random event. + * @param entity The entity teleporting. + * @param location The destination lcoation. + */ + public static void fireRandom(Entity entity, Location location) { + if (entity instanceof Player && entity.getTeleporter().getTeleportType() == 0) { + Player p = (Player) entity; + } + } + + /** + * Get the home teleport audio based on tick count. + * @param count + */ + private static int getAudio(int count){ + switch(count){ + case 0: + return 193; + case 4: + return 194; + case 11: + return 195; + } + return -1; + } + + /** + * Gets the entity. + * @return the Entity + */ + public final Entity getEntity() { + return entity; + } + + /** + * Gets the last teleport pulse. + * @return the Pulse + */ + public final Pulse getLastTeleport() { + return lastTeleport; + } + + /** + * Gets the current teleport pulse. + * @return the Pulse + */ + public final Pulse getCurrentTeleport() { + return currentTeleport; + } + + + /** + * Represents a NodeType for Teleporter + * @author SonicForce41 + */ + public enum TeleportType { + + /** + * The value types + */ + NORMAL(new TeleportSettings(8939, 8941, 1576, 1577)) { + @Override + public Pulse getPulse(final Entity entity, final Location location) { + return new TeleportPulse(entity) { + int delay = 0; + + @Override + public boolean pulse() { + if (delay == 0) { + playGlobalAudio(entity.getLocation(), Sounds.TELEPORT_ALL_200); + entity.getAnimator().forceAnimation(new Animation(getSettings().getStartEmote())); + entity.graphics(new Graphics(getSettings().getStartGfx())); + } else if (delay == 3) { + entity.getProperties().setTeleportLocation(Location.create(location)); + fireRandom(entity, location); + } else if (delay == 4) { + playGlobalAudio(entity.getLocation(), Sounds. TELEPORT_REVERSE_201); + entity.getAnimator().forceAnimation(new Animation(getSettings().getEndEmote(), Priority.HIGH)); + entity.graphics(new Graphics(getSettings().getEndGfx())); + return true; + } + delay++; + return false; + } + + @Override + public void stop() { + super.stop(); + entity.unlock(); + entity.lock(4); + } + }; + } + }, + ANCIENT(new TeleportSettings(1979, -1, 392, -1)) { + @Override + public Pulse getPulse(final Entity entity, final Location location) { + return new TeleportPulse(entity) { + int delay = 0; + + @Override + public boolean pulse() { + if (delay == 0) { + playGlobalAudio(entity.getLocation(), Sounds.BLOCK_TELEPORT_197, 0, 7); + entity.getAnimator().forceAnimation(new Animation(getSettings().getStartEmote())); + entity.graphics(new Graphics(getSettings().getStartGfx())); + } else if (delay == 4) { + entity.getProperties().setTeleportLocation(Location.create(location)); + fireRandom(entity, location); + } else if (delay == 5) { + entity.getAnimator().forceAnimation(new Animation(getSettings().getEndEmote(), Priority.HIGH)); + entity.graphics(new Graphics(getSettings().getEndGfx())); + return true; + } + delay++; + return false; + } + + @Override + public void stop() { + super.stop(); + entity.getAnimator().forceAnimation(new Animation(-1)); + entity.graphics(new Graphics(-1)); + entity.unlock(); + } + }; + } + }, + LUNAR(new TeleportSettings(1816, -1, 747, -1)) { + @Override + public Pulse getPulse(final Entity entity, final Location location) { + return new TeleportPulse(entity) { + int delay = 0; + + @Override + public boolean pulse() { + if (delay == 0) { + entity.graphics(new Graphics(getSettings().getStartGfx(), 120)); + entity.getAnimator().forceAnimation(new Animation(getSettings().getStartEmote())); + } else if (delay == 3) { + entity.getProperties().setTeleportLocation(Location.create(location)); + fireRandom(entity, location); + } else if (delay == 4) { + entity.getAnimator().forceAnimation(new Animation(getSettings().getEndEmote(), Priority.HIGH)); + entity.graphics(new Graphics(getSettings().getEndGfx())); + return true; + } + delay++; + return false; + } + + @Override + public void stop() { + super.stop(); + entity.getAnimator().forceAnimation(new Animation(-1)); + entity.graphics(new Graphics(-1)); + entity.unlock(); + } + }; + } + }, + TELETABS(new TeleportSettings(4731, -1, 678, -1)) { + @Override + public Pulse getPulse(final Entity entity, final Location location) { + return new TeleportPulse(entity) { + int delay = 0; + + @Override + public boolean pulse() { + if (delay == 0) { + playGlobalAudio(entity.getLocation(), Sounds.POH_TABLET_BREAK_979); + entity.getAnimator().forceAnimation(new Animation(4069)); + } else if (delay == 2) { + entity.getAnimator().forceAnimation(new Animation(getSettings().getStartEmote(), Priority.HIGH)); + entity.graphics(new Graphics(getSettings().getStartGfx())); + } else if (delay == 3) { + entity.getProperties().setTeleportLocation(Location.create(location)); + } else if (delay == 4) { + entity.getAnimator().forceAnimation(new Animation(getSettings().getEndEmote())); + entity.graphics(new Graphics(getSettings().getEndGfx())); + return true; + } + delay++; + return false; + } + + @Override + public void stop() { + super.stop(); + entity.getAnimator().forceAnimation(new Animation(-1)); + entity.graphics(new Graphics(-1)); + entity.unlock(); + entity.lock(2); + } + }; + } + }, + HOME(new TeleportSettings(4847, 4857, 800, 804)) { + @Override + public Pulse getPulse(final Entity entity, final Location location) { + return new TeleportPulse(entity) { + int count; + Player player; + + @Override + public boolean pulse() { + switch (count) { + case 18: + player.getProperties().setTeleportLocation(location); + return true; + default: + playGlobalAudio(entity.getLocation(), getAudio(count)); + player.getPacketDispatch().sendGraphic(HOME_GRAPHICS[count]); + player.getPacketDispatch().sendAnimation(HOME_ANIMATIONS[count]); + break; + } + count++; + return false; + } + @Override + public void start() { + player = ((Player) entity); + /*if (player.getSavedData().getGlobalData().getHomeTeleportDelay() > System.currentTimeMillis() && !player.isDonator()) { + long milliseconds = player.getSavedData().getGlobalData().getHomeTeleportDelay() - System.currentTimeMillis(); + int minutes = (int) Math.round(milliseconds / 120000); + if (minutes > 15) { + player.getSavedData().getGlobalData().setHomeTeleportDelay(System.currentTimeMillis() + 1200000); + milliseconds = player.getSavedData().getGlobalData().getHomeTeleportDelay() - System.currentTimeMillis(); + minutes = (int) Math.round(milliseconds / 120000); + } + if (minutes != 0) { + player.getPacketDispatch().sendMessage("You need to wait another " + minutes + " " + (minutes == 1 ? "minute" : "minutes") + " to cast this spell."); + stop(); + return; + } + }*/ + super.start(); + } + + @Override + public void stop() { + super.stop(); + entity.getAnimator().forceAnimation(new Animation(-1)); + player.graphics(new Graphics(-1)); + } + }; + } + }, + OBELISK(new TeleportSettings(8939, 8941, 661, -1)) { + @Override + public Pulse getPulse(final Entity entity, final Location location) { + return new TeleportPulse(entity) { + int delay = 0; + + @Override + public boolean pulse() { + if (delay == 0) { + entity.lock(); + entity.getAnimator().forceAnimation(new Animation(1816)); + } else if (delay == 3) { + entity.getProperties().setTeleportLocation(Location.create(location)); + } else if (delay == 4) { + entity.getAnimator().forceAnimation(Animation.RESET); + entity.unlock(); + return true; + } + delay++; + return false; + } + }; + } + }, + TELE_OTHER(new TeleportSettings(1816, -1, 342, -1)) { + @Override + public Pulse getPulse(final Entity entity, final Location location) { + return new TeleportPulse(entity) { + int delay = 0; + + @Override + public boolean pulse() { + if (delay == 0) { + playGlobalAudio(entity.getLocation(), Sounds.TELE_OTHER_CAST_199); + entity.getAnimator().forceAnimation(new Animation(getSettings().getStartEmote())); + entity.graphics(new Graphics(getSettings().getStartGfx())); + } else if (delay == 3) { + entity.getProperties().setTeleportLocation(Location.create(location)); + } else if (delay == 4) { + entity.getAnimator().forceAnimation(new Animation(-1)); + entity.unlock(); + return true; + } + delay++; + return false; + } + }; + } + }, + FAIRY_RING(new TeleportSettings(-1, -1, -1, -1)) { + @Override + public Pulse getPulse(final Entity entity, final Location location) { + entity.graphics(Graphics.create(569)); + return new TeleportPulse(entity) { + int delay; + + @Override + public boolean pulse() { + switch (++delay) { + case 2: + entity.animate(Animation.create(3265)); + if(entity instanceof Player) { + playAudio(entity.asPlayer(), Sounds.FT_FAIRY_TELEPORT_1098); + } + break; + case 4: + entity.animate(Animation.create(3266)); + entity.getProperties().setTeleportLocation(location); + entity.unlock(); + entity.lock(2); + return true; + } + return false; + } + + }; + } + }, + PURO_PURO(new TeleportSettings(6601, 1118, -1, -1)) { + @Override + public Pulse getPulse(final Entity entity, final Location location) { + return new TeleportPulse(entity) { + int delay = 0; + + @Override + public boolean pulse() { + if (delay == 0) { + entity.getAnimator().forceAnimation(new Animation(getSettings().getStartEmote())); + entity.graphics(new Graphics(1118)); + } else if (delay == 9) { + entity.getProperties().setTeleportLocation(Location.create(location)); + entity.getAnimator().forceAnimation(new Animation(-1)); + entity.unlock(); + return true; + } + delay++; + return false; + } + }; + } + }, + ECTOPHIAL(new TeleportSettings(8939, 8941, 1587, 1588)) { + @Override + public Pulse getPulse(final Entity entity, final Location location) { + return new TeleportPulse(entity) { + int delay = 0; + + @Override + public boolean pulse() { + if (delay == 0) { + playGlobalAudio(entity.getLocation(), Sounds.TELEPORT_ALL_200); + entity.getAnimator().forceAnimation(new Animation(getSettings().getStartEmote())); + entity.graphics(new Graphics(getSettings().getStartGfx())); + } else if (delay == 3) { + entity.getProperties().setTeleportLocation(Location.create(location)); + fireRandom(entity, location); + } else if (delay == 4) { + playGlobalAudio(entity.getLocation(), Sounds.TELEPORT_REVERSE_201); + entity.getAnimator().forceAnimation(new Animation(getSettings().getEndEmote(), Priority.HIGH)); + entity.graphics(new Graphics(getSettings().getEndGfx())); + return true; + } + delay++; + return false; + } + }; + } + }, + CHRISTMAS(new TeleportSettings(7534, -1, 1292, -1)) { + @Override + public Pulse getPulse(final Entity entity, final Location location) { + return new TeleportPulse(entity) { + int delay = 0; + + @Override + public boolean pulse() { + if (delay == 0) { + playGlobalAudio(entity.getLocation(), Sounds.TELEPORT_ALL_200); + entity.getAnimator().forceAnimation(new Animation(getSettings().getStartEmote())); + entity.graphics(new Graphics(getSettings().getStartGfx())); + } else if (delay == 3) { + entity.getProperties().setTeleportLocation(Location.create(location)); + fireRandom(entity, location); + } else if (delay == 4) { + playGlobalAudio(entity.getLocation(), Sounds.TELEPORT_REVERSE_201); + entity.getAnimator().forceAnimation(new Animation(getSettings().getEndEmote(), Priority.HIGH)); + entity.graphics(new Graphics(getSettings().getEndGfx())); + return true; + } + delay++; + return false; + } + + @Override + public void stop() { + super.stop(); + entity.unlock(); + entity.lock(4); + } + }; + } + }, + CABBAGE(new TeleportSettings(9984, 9986, 1731, 1732)) { + @Override + public Pulse getPulse(final Entity entity, final Location location) { + return new TeleportPulse(entity) { + int delay = 0; + + @Override + public boolean pulse() { + if (delay == 0) { + if (entity instanceof Player) { + playAudio(entity.asPlayer(), 5036); + } + entity.getAnimator().forceAnimation(new Animation(getSettings().getStartEmote())); + entity.graphics(new Graphics(getSettings().getStartGfx())); + } else if (delay == 5) { + entity.getProperties().setTeleportLocation(Location.create(location)); + fireRandom(entity, location); + if (entity instanceof Player) { + playAudio(entity.asPlayer(), 5034); + } + entity.getAnimator().forceAnimation(new Animation(getSettings().getEndEmote(), Priority.HIGH)); + entity.graphics(new Graphics(getSettings().getEndGfx())); + return true; + } + delay++; + return false; + } + + @Override + public void stop() { + super.stop(); + entity.unlock(); + entity.lock(4); + } + }; + } + }, + ENTRANA_MAGIC_DOOR(new TeleportSettings(10100, 9013, 1745, 1747)) { // + @Override + public Pulse getPulse(final Entity entity, final Location location) { + return new TeleportPulse(entity) { + int delay = 0; + + @Override + public boolean pulse() { + if (delay == 0) { + playGlobalAudio(entity.getLocation(), Sounds.TELEPORT_ALL_200); + entity.getAnimator().forceAnimation(new Animation(getSettings().getStartEmote())); + entity.graphics(new Graphics(getSettings().getStartGfx())); + } else if (delay == 3) { + entity.getProperties().setTeleportLocation(Location.create(location)); + fireRandom(entity, location); + } else if (delay == 4) { + playGlobalAudio(entity.getLocation(), Sounds.TELEPORT_REVERSE_201); + entity.getAnimator().forceAnimation(new Animation(getSettings().getEndEmote(), Priority.HIGH)); + entity.graphics(new Graphics(getSettings().getEndGfx())); + return true; + } + delay++; + return false; + } + + @Override + public void stop() { + super.stop(); + entity.unlock(); + entity.lock(4); + } + }; + } + }, + MINIGAME(new TeleportSettings(6601, 1118, -1, -1)) { + @Override + public Pulse getPulse(final Entity entity, final Location location) { + return new TeleportPulse(entity) { + int delay = 0; + Player player; + + @Override + public boolean pulse() { + if (delay == 0) { + entity.getAnimator().forceAnimation(new Animation(getSettings().getStartEmote())); + entity.graphics(new Graphics(1118)); + } else if (delay == 9) { + entity.getProperties().setTeleportLocation(Location.create(location)); + entity.getAnimator().forceAnimation(new Animation(-1)); + entity.unlock(); + return true; + } + delay++; + return false; + } + + @Override + public void start() { + + super.start(); + } + + @Override + public void stop() { + super.stop(); + entity.getAnimator().forceAnimation(new Animation(-1)); + entity.graphics(new Graphics(-1)); + } + }; + } + }, + INSTANT(new TeleportSettings(-1, -1, -1, -1)) { + @Override + public Pulse getPulse(final Entity entity, final Location location) { + return new TeleportPulse(entity) { + int delay = 0; + + @Override + public boolean pulse() { + if (delay == 0) { + entity.lock(); + } else if (delay == 3) { + entity.getProperties().setTeleportLocation(Location.create(location)); + } else if (delay == 4) { + entity.getAnimator().forceAnimation(Animation.RESET); + entity.unlock(); + return true; + } + delay++; + return false; + } + }; + } + }; + + /** + * The NodeSettings + */ + private TeleportSettings settings; + + /** + * @param entity + * @param location + * @return the Pulse + */ + public abstract Pulse getPulse(final Entity entity, final Location location); + + /** + * Constructs a new {@code Teleporter.java} {@Code Object}. + * @param settings the NodeSettings + */ + TeleportType(TeleportSettings settings) { + this.settings = settings; + } + + /** + * Gets the NodeSettings + * @return the NodeSettings + */ + public final TeleportSettings getSettings() { + return settings; + } + } + + /** + * Represents teleport node settings + * @author SonicForce41 + */ + static class TeleportSettings { + + /** + * The start animation. + */ + private int startAnim; + + /** + * The end animation. + */ + private int endAnim; + + /** + * The start graphics. + */ + private int startGFX; + + /** + * The end gfx. + */ + private int endGFX; + + /** + * Constructs a new {@code Teleporter.java} {@code Object}. + * @param startAnim the start animation. + * @param endAnim the end animation. + * @param startGfx the start graphics. + * @param endGfx the end graphiics. + */ + public TeleportSettings(int startAnim, int endAnim, int startGfx, int endGfx) { + this.startAnim = startAnim; + this.endAnim = endAnim; + this.startGFX = startGfx; + this.endGFX = endGfx; + } + + /** + * @return the anim. + */ + public final int getStartEmote() { + return startAnim; + } + + /** + * @return the anim. + */ + public final int getEndEmote() { + return endAnim; + } + + /** + * @return the start graphics. + */ + public final int getStartGfx() { + return startGFX; + } + + /** + * @return the end gfx. + */ + public final int getEndGfx() { + return endGFX; + } + } + + /** + * Gets the teleporting type for the player depending on his/her current + * spellbook. + * @param player The player. + * @return The teleport type. + */ + public static TeleportType getType(Player player) { + switch (player.getSpellBookManager().getSpellBook()) { + case 193: + return TeleportType.ANCIENT; + case 430: + return TeleportType.LUNAR; + } + return TeleportType.NORMAL; + } + + /** + * Gets the teleportType. + * @return The teleportType. + */ + public int getTeleportType() { + return teleportType; + } + + /** + * Sets the teleportType. + * @param teleportType The teleportType to set. + */ + public void setTeleportType(int teleportType) { + this.teleportType = teleportType; + } +} + diff --git a/Server/src/main/core/game/node/entity/player/link/TeleportPulse.java b/Server/src/main/core/game/node/entity/player/link/TeleportPulse.java new file mode 100644 index 0000000..31d76f3 --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/TeleportPulse.java @@ -0,0 +1,24 @@ +package core.game.node.entity.player.link; + +import core.game.system.task.Pulse; +import core.game.node.entity.Entity; + +abstract class TeleportPulse extends Pulse { + private Entity entity; + + public TeleportPulse(Entity e) { this.entity = e; } + + public abstract boolean pulse(); + + @Override + public void start() { + entity.setAttribute("tele-pulse", this); + super.start(); + } + + @Override + public void stop() { + entity.removeAttribute("tele-pulse"); + super.stop(); + } +} diff --git a/Server/src/main/core/game/node/entity/player/link/WarningMessages.java b/Server/src/main/core/game/node/entity/player/link/WarningMessages.java new file mode 100644 index 0000000..11731ff --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/WarningMessages.java @@ -0,0 +1,131 @@ +package core.game.node.entity.player.link; + +import core.game.component.Component; +import core.game.node.entity.player.Player; + + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.List; + +import static core.api.ContentAPIKt.*; + + +/** + * Handles the warning messages of a player. + * @author Vexia + */ +public final class WarningMessages { + + /** + * Represents the config id. + */ + private static final int CONFIG = 1045; + + /** + * Represents the warning messages. + */ + private final List messages = new ArrayList<>(20); + + /** + * Method used to open the warning messages. + * @param player the player. + */ + public void open(final Player player) { + player.getInterfaceManager().open(new Component(583)); + refresh(player); + } + + /** + * Method used to refresh the config. + * @param player the player. + */ + private void refresh(final Player player) { + setVarp(player, CONFIG, getConfigValue(), true); + } + + /** + * Gets a warning message by its index. + * @param index the index. + * @return the warning message. + */ + public WarningMessage getMessage(int index) { + for (WarningMessage m : messages) { + if (m.getIndex() == index) { + return m; + } + } + WarningMessage message = new WarningMessage(index); + messages.add(message); + return message; + } + + /** + * Gets the config value. + * @return the value. + */ + private int getConfigValue() { + return 0; + } + + /** + * Represents a warning message. + * @author 'Vexia + */ + public final class WarningMessage { + + /** + * Represents the button index. + */ + private final int index; + + /** + * Constructs a new {@code WarningMessage} {@code Object}. + * @param index the index. + */ + public WarningMessage(final int index) { + this.index = index; + } + + /** + * Method used to toggle this warning message. + * @param player the player. + */ + public void toggle(final Player player) { + if (!isActive()) { + player.getPacketDispatch().sendMessage("You cannot toggle the warning screen on or off. You need to go to the area it"); + player.getPacketDispatch().sendMessage("is linked to enough times to have the option to do so."); + return; + } + final boolean on = !isToggled(); + refresh(player); + player.getPacketDispatch().sendMessage("You have toggled this warning screen " + (on ? "on" : "off") + ". You will " + (on ? "see this interface again." : "no longer see this warning screen.")); + } + + /** + * Checks if the message is toggled. + * @return {@code True} if so. + */ + private boolean isToggled() { + return false; + } + + /** + * Checks if the message is toggled. + * @return {@code True} if so. + */ + private boolean isActive() { + return false; + } + + /** + * Gets the index. + * @return The index. + */ + public int getIndex() { + return index; + } + + } + +} diff --git a/Server/src/main/core/game/node/entity/player/link/appearance/Appearance.java b/Server/src/main/core/game/node/entity/player/link/appearance/Appearance.java new file mode 100644 index 0000000..e4c5ecf --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/appearance/Appearance.java @@ -0,0 +1,793 @@ +package core.game.node.entity.player.link.appearance; + +import core.cache.def.impl.ItemDefinition; +import core.cache.def.impl.NPCDefinition; +import core.game.container.impl.EquipmentContainer; +import core.game.node.entity.combat.equipment.WeaponInterface; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.update.flag.context.Animation; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import core.game.system.config.ItemConfigParser; + +/** + * Represents an appearance managing class of a player. + * @author Emperor + * @author Vexia + */ +public final class Appearance { + + /** + * Represents the player instance. + */ + private final Player player; + + /** + * Represents the cached animations. + */ + private final int[] animationCache = new int[] { AppearanceCache.STAND_ANIM, AppearanceCache.STAND_TURN_ANIM, AppearanceCache.WALK_ANIM, AppearanceCache.TURN_180_AIM, AppearanceCache.TURN_90_CW, AppearanceCache.TUNR_90_CWW, AppearanceCache.RUN_ANIM }; + + /** + * Represents the cached icons. + */ + private final int[] iconCache = new int[] { -1, -1 }; + + /** + * Represents the shown body parts. + */ + private final int[] bodyParts = new int[14]; + + /** + * Represents the cached body parts (default male). + */ + private BodyPart[] appearanceCache = Gender.MALE.generateCache(); + + /** + * Represents the gender of a player. + */ + private Gender gender = Gender.MALE; + + /** + * Represents the npc id to represent if not -1. + */ + private int npcId = -1; + + /** + * The render animation id. + */ + private int renderAnimationId = 1426; + + /** + * If the player is riding a mining cart. + */ + private boolean ridingMinecart; + + /** + * Constructs a new {@code Appearance} {@code Object}. + * @param player the player of this appearance. + */ + public Appearance(final Player player) { + this.player = player; + } + + public void parse(JSONObject appearance){ + gender = gender.asByte(Byte.parseByte(appearance.get("gender").toString())); + JSONArray appCache = (JSONArray) appearance.get("appearance_cache"); + for(int i = 0; i < appearanceCache.length; i++){ + (appearanceCache[i]).parse((JSONObject) appCache.get(i)); + } + } + + /** + * Transforms the player into an NPC. + * @param id The NPC id. + */ + public void transformNPC(int id) { + this.npcId = id; + setAnimations(); + if (id == -1) { + player.setSize(1); + Animation[] anims = WeaponInterface.DEFAULT_ANIMS; + if (player.getEquipment().get(3) != null) { + anims = player.getEquipment().get(3).getDefinition().getConfiguration(ItemConfigParser.ATTACK_ANIMS, anims); + } + int index = player.getSettings().getAttackStyleIndex(); + if (index < 0 || index >= anims.length) { + index = 0; + } + player.getProperties().setAttackAnimation(anims[index]); + player.getProperties().setDefenceAnimation(new Animation(404)); + player.getProperties().setDeathAnimation(new Animation(9055, Priority.HIGH)); + } else { + NPCDefinition def = NPCDefinition.forId(id); + player.setSize(def.getSize()); + if (def.getCombatAnimation(0) != null) { + player.getProperties().setAttackAnimation(def.getCombatAnimation(0)); + } + if (def.getCombatAnimation(3) != null) { + player.getProperties().setDefenceAnimation(def.getCombatAnimation(3)); + } + if (def.getCombatAnimation(4) != null) { + player.getProperties().setDeathAnimation(def.getCombatAnimation(4)); + } + } + sync(); + } + + /** + * Sets the rendering animations. + */ + public void setAnimations() { + if (npcId == -1) { + Item weapon = player.getEquipment().get(3); + if (isRidingMinecart()) { + this.setRidingMinecart(false); + } + if (weapon == null || weapon.getDefinition().getConfiguration(ItemConfigParser.WALK_ANIM, null) == null) { + setDefaultAnimations(); + } else { + ItemDefinition def = weapon.getDefinition(); + setStandAnimation(def.getConfiguration(ItemConfigParser.STAND_ANIM, 0x328)); + setStandTurnAnimation(def.getConfiguration(ItemConfigParser.STAND_TURN_ANIM, 0x337)); + setWalkAnimation(def.getConfiguration(ItemConfigParser.WALK_ANIM, 0x333)); + setRunAnimation(def.getConfiguration(ItemConfigParser.RUN_ANIM, 0x338)); + setTurn180(def.getConfiguration(ItemConfigParser.TURN180_ANIM, 0x334)); + setTurn90cw(def.getConfiguration(ItemConfigParser.TURN90CW_ANIM, 0x335)); + setTurn90ccw(def.getConfiguration(ItemConfigParser.TURN90CCW_ANIM, 0x336)); + renderAnimationId = def.getRenderAnimationId(); + } + if (weapon != null && weapon.getId() == 12842) { + setStandAnimation(8964); + setWalkAnimation(8961); + setRunAnimation(8963); + setTurn180(8963); + setTurn90ccw(8963); + setTurn90cw(8963); + setStandTurnAnimation(8963); + } + } else { + NPCDefinition def = NPCDefinition.forId(npcId); + renderAnimationId = def.getRenderAnimationId(); + setStandAnimation(def.getStandAnimation()); + int turn = def.getTurnAnimation(); + if (turn < 1) { + turn = def.getWalkAnimation(); + } + setStandTurnAnimation(turn); + setWalkAnimation(def.getWalkAnimation()); + setRunAnimation(def.getWalkAnimation()); + if (def.getTurn180Animation() > 0) { + setTurn180(def.getTurn180Animation()); + } else { + setTurn180(turn); + } + if (def.getTurnCWAnimation() > 0) { + setTurn90cw(def.getTurnCWAnimation()); + } else { + setTurn90cw(turn); + } + if (def.getTurnCCWAnimation() > 0) { + setTurn90ccw(def.getTurnCCWAnimation()); + } else { + setTurn90ccw(turn); + } + } + } + + /** + * Sets the animations. + * @param anim the animation. + */ + public void setAnimations(Animation anim) { + renderAnimationId = anim.getId(); + sync(); + } + + /** + * Method used to sync this appearance with the client. + */ + public void sync() { + player.updateAppearance(); + } + + /** + * Copies the appearance. + * @param appearance The appearance to copy from. + */ + public void copy(Appearance appearance) { + gender = appearance.gender; + for (int i = 0; i < appearanceCache.length; i++) { + appearanceCache[i] = appearance.appearanceCache[i]; + } + for (int i = 0; i < animationCache.length; i++) { + animationCache[i] = appearance.animationCache[i]; + } + renderAnimationId = appearance.renderAnimationId; + } + + /** + * Draws an item on a body part. + * @param part The body part. + * @param item The item to draw. + */ + public void drawItem(int part, Item item) { + this.bodyParts[part] = item.getDefinition().getEquipId() + 0x8000; + } + + /** + * Draws clothing on a body part. + * @param part The body part. + * @param clothesId The clothes id. + */ + public void drawClothes(int part, int clothesId) { + this.bodyParts[part] = clothesId + 0x100; + } + + /** + * Clears a body part. + * @param part The part to clear. + */ + public void clearBodyPart(int part) { + this.bodyParts[part] = 0; + } + + public void flagHatClipping() { + boolean isBald = getHair().getLook() == (isMale() ? 0 : 45); + int hairLook = isBald ? getHair().getLook() : (isMale() ? 5 : 51); + this.bodyParts[8] = hairLook + 0x100; + } + + /** + * Prepares the data used for the appearance update mask. + * @param player The player. + */ + public void prepareBodyData(Player player) { + if (player.getRenderInfo().preparedAppearance()) { + return; + } + player.getRenderInfo().setPreparedAppearance(true); + Item chest = player.getEquipment().get(EquipmentContainer.SLOT_CHEST); + Item shield = player.getEquipment().get(EquipmentContainer.SLOT_SHIELD); + Item legs = player.getEquipment().get(EquipmentContainer.SLOT_LEGS); + Item hat = player.getEquipment().get(EquipmentContainer.SLOT_HAT); + Item hands = player.getEquipment().get(EquipmentContainer.SLOT_HANDS); + Item feet = player.getEquipment().get(EquipmentContainer.SLOT_FEET); + Item cape = player.getEquipment().get(EquipmentContainer.SLOT_CAPE); + Item amulet = player.getEquipment().get(EquipmentContainer.SLOT_AMULET); + Item weapon = player.getEquipment().get(EquipmentContainer.SLOT_WEAPON); + boolean castleWarsHood = cape != null && (cape.getId() == 4041 || cape.getId() == 4042); // Item + if (hat != null) { + drawItem(0, hat); + } else { + clearBodyPart(0); + } + if (cape != null) { + drawItem(1, cape); + } else { + clearBodyPart(1); + } + if (amulet != null) { + drawItem(2, amulet); + } else { + clearBodyPart(2); + } + if (!ridingMinecart) { + if (weapon != null) { + drawItem(3, weapon); + } else { + clearBodyPart(3); + } + if (shield != null) { + drawItem(5, shield); + } else { + clearBodyPart(5); + } + } else { + clearBodyPart(5); + drawClothes(3, 82); + } + if (chest != null) { + drawItem(4, chest); + } else { + drawClothes(4, getTorso().getLook()); + } + if (chest != null && chest.getDefinition().getConfiguration(ItemConfigParser.REMOVE_SLEEVES, false)) { + clearBodyPart(6); + } else { + drawClothes(6, getArms().getLook()); + } + if (legs != null) { + drawItem(7, legs); + } else { + drawClothes(7, getLegs().getLook()); + } + if ((hat != null && hat.getDefinition().getConfiguration(ItemConfigParser.REMOVE_HEAD, false)) || castleWarsHood) { + clearBodyPart(8); + } else { + drawClothes(8, getHair().getLook()); + } + if((hat != null && hat.getDefinition().getConfiguration(ItemConfigParser.IS_HAT,false))){ + flagHatClipping(); + } + if (hands != null) { + drawItem(9, hands); + } else { + drawClothes(9, getWrists().getLook()); + } + if (feet != null) { + drawItem(10, feet); + } else { + drawClothes(10, getFeet().getLook()); + } + if (hat != null && hat.getDefinition().getConfiguration(ItemConfigParser.REMOVE_BEARD, false)) { + clearBodyPart(11); + } else { + drawClothes(11, getBeard().getLook()); + } + + } + + /** + * Rides a mine cart. + */ + public void rideCart(boolean ride) { + if (!ride) { + setAnimations(); + } else { + player.getAppearance().setAnimations(Animation.create(211)); + } + player.getAppearance().setRidingMinecart(ride); + player.getAppearance().sync(); + } + + /** + * Flys a gnome copter. + */ + public void flyCopter() { + player.animate(Animation.create(8956)); + player.getEquipment().replace(new Item(12842), 3); + player.getAppearance().setStandAnimation(8964); + player.getAppearance().setWalkAnimation(8961); + player.getAppearance().setRunAnimation(8963); + player.getAppearance().setTurn180(8963); + player.getAppearance().setTurn90ccw(8963); + player.getAppearance().setTurn90cw(8963); + player.getAppearance().setStandTurnAnimation(8963); + } + + /** + * Gets the player. + * @return The player. + */ + public Player getPlayer() { + return player; + } + + /** + * Gets the hair body part. + * @return the hair. + */ + public BodyPart getHair() { + return appearanceCache[AppearanceCache.HAIR]; + } + + /** + * Gets the beard body part. + * @return the beard. + */ + public BodyPart getBeard() { + return appearanceCache[AppearanceCache.FACIAL_HAIR]; + } + + /** + * Gets the torso body part. + * @return the torso. + */ + public BodyPart getTorso() { + return appearanceCache[AppearanceCache.TORSO]; + } + + /** + * Gets the arms body part. + * @return the body part. + */ + public BodyPart getArms() { + return appearanceCache[AppearanceCache.ARMS]; + } + + /** + * Gets the wrist part part. + * @return the body part. + */ + public BodyPart getWrists() { + return appearanceCache[AppearanceCache.WRISTS]; + } + + /** + * Gets the skin part. + * @return the part. + */ + public BodyPart getSkin() { + return appearanceCache[AppearanceCache.WRISTS]; + } + + /** + * Getsthe leg body parts. + * @return the legs. + */ + public BodyPart getLegs() { + return appearanceCache[AppearanceCache.LEGS]; + } + + /** + * Gets the feet body parts. + * @return the feet. + */ + public BodyPart getFeet() { + return appearanceCache[AppearanceCache.FEET]; + } + + /** + * Gets the stand animation. + * @return the animation. + */ + public int getStandAnimation() { + return animationCache[0]; + } + + /** + * Method used to set the stand animation. + * @param animation + */ + public void setStandAnimation(int animation) { + animationCache[0] = animation; + } + + /** + * Gets the standing turn animation. + * @return the animation. + */ + public int getStandTurnAnimation() { + return animationCache[1]; + } + + /** + * Sets the standing turn animation. + */ + public void setStandTurnAnimation(int animation) { + animationCache[1] = animation; + } + + /** + * Gets the walk animation. + * @return the animation. + */ + public int getWalkAnimation() { + return animationCache[2]; + } + + /** + * Sets the walk animation. + * @param animation the animation. + */ + public void setWalkAnimation(int animation) { + animationCache[2] = animation; + } + + /** + * Gets the turning 180 animation. + * @return the animation. + */ + public int getTurn180() { + return animationCache[3]; + } + + /** + * Sets the tunring 180 animation. + * @param animation the animation. + */ + public void setTurn180(int animation) { + animationCache[3] = animation; + } + + /** + * Gets the turn90cw animation. + * @return the animation. + */ + public int getTurn90cw() { + return animationCache[4]; + } + + /** + * Sets the turn90cw animation. + * @param animation the animation. + */ + public void setTurn90cw(int animation) { + animationCache[4] = animation; + } + + /** + * Gets the turn90ccw animation. + * @return the animation. + */ + public int getTurn90ccw() { + return animationCache[5]; + } + + /** + * Sets thr turn90cww animation. + * @param animation + */ + public void setTurn90ccw(int animation) { + animationCache[5] = animation; + } + + /** + * Gets the run animation. + * @return the animation. + */ + public int getRunAnimation() { + return animationCache[6]; + } + + /** + * Sets the running animation. + * @param animation the animation. + */ + public void setRunAnimation(int animation) { + animationCache[6] = animation; + } + + /** + * Gets the render animation id. + * @return The render animation id. + */ + public int getRenderAnimation() { + if (player.getAttribute("render-anim-override") != null) + return player.getAttribute("render-anim-override", renderAnimationId); + return renderAnimationId; + } + + /** + * Method used to set the default animations. + */ + public void setDefaultAnimations() { + for (int i = 0; i < animationCache.length; i++) { + animationCache[i] = AppearanceCache.ANIMATIONS[i]; + } + renderAnimationId = 1426; + } + + /** + * Gets the skull icon. + * @return the icon. + */ + public int getSkullIcon() { + return iconCache[0]; + } + + /** + * Sets the skull icon. + * @param icon the icon. + */ + public void setSkullIcon(int icon) { + iconCache[0] = icon; + } + + /** + * Gets the head icon. + * @return the icon. + */ + public int getHeadIcon() { + return iconCache[1]; + } + + /** + * Sets the head icon. + * @param icon the icon. + */ + public void setHeadIcon(int icon) { + this.iconCache[1] = icon; + } + + /** + * Gets the gender. + * @return The gender. + */ + public Gender getGender() { + return gender; + } + + /** + * Method used to change the gender of a player. + * @param gender the gender. + */ + public void changeGender(Gender gender) { + setGender(gender); + sync(); + } + + /** + * Method used to set the gender. + * @param gender the gender. + */ + public void setGender(final Gender gender) { + this.gender = gender; + this.appearanceCache = gender.generateCache(); + } + + /** + * Gets the value {@code True} if male. + * @return {@code True} if so. + */ + public boolean isMale() { + return gender == Gender.MALE; + } + + /** + * Gets the npc id. + * @return the npc id. + */ + public int getNpcId() { + return npcId; + } + + /** + * If the player's appearance is a NPC. + * @return If the player's appearance is a NPC {@code true}. + */ + public boolean isNpc() { + return npcId != -1; + } + + /** + * Gets the appearanceCache. + * @return The appearanceCache. + */ + public BodyPart[] getAppearanceCache() { + return appearanceCache; + } + + /** + * Gets the animationCache. + * @return The animationCache. + */ + public int[] getAnimationCache() { + return animationCache; + } + + /** + * Gets the bodyParts. + * @return The bodyParts. + */ + public int[] getBodyParts() { + return bodyParts; + } + + /** + * Gets the ridingMinecart. + * @return The ridingMinecart. + */ + public boolean isRidingMinecart() { + return ridingMinecart; + } + + /** + * Sets the ridingMinecart. + * @param ridingMinecart The ridingMinecart to set. + */ + public void setRidingMinecart(boolean ridingMinecart) { + this.ridingMinecart = ridingMinecart; + } + + /** + * Represents a class of cached appearance related information. + * @author 'Vexia + */ + public static class AppearanceCache { + + /** + * Represents the appearance animations. + */ + public static final int[] ANIMATIONS = new int[] { 0x328, 0x337, 0x333, 0x334, 0x335, 0x336, 0x338 }; + + /** + * Represents the index hair apperance is cached at. + */ + public static final int HAIR = 0; + + /** + * Represents the index facial hair appearance is cached at. + */ + public static final int FACIAL_HAIR = 1; + + /** + * Represents the index torso appearance is cached at. + */ + public static final int TORSO = 2; + + /** + * Represents the index arm appearance is cached at. + */ + public static final int ARMS = 3; + + /** + * Represents the index wrist appearance is cached at. + */ + public static final int WRISTS = 4; + + /** + * Represents the index leg appearance is cached at. + */ + public static final int LEGS = 5; + + /** + * Represents the index feet appearance is cached at. + */ + public static final int FEET = 6; + + /** + * Represents the index hair color is cached at. + */ + public static final int HAIR_COLOR = 0; + + /** + * Represents the index torso color is cached at. + */ + public static final int TORSO_COLOR = 1; + + /** + * Represents the index leg color is cached at. + */ + public static final int LEG_COLOR = 2; + + /** + * Represents the index feet color is cached at. + */ + public static final int FEET_COLOR = 3; + + /** + * Represents the index skin color is cached at. + */ + public static final int SKIN_COLOR = 4; + + /** + * The player's stand animation. + */ + private static final int STAND_ANIM = 0x328; + + /** + * The player's turn animation for standing. + */ + private static final int STAND_TURN_ANIM = 0x337; + + /** + * The player's walk animation. + */ + public static final int WALK_ANIM = 0x333; + + /** + * The player's turn 180 degrees animation. + */ + private static final int TURN_180_AIM = 0x334; + + /** + * The player's turn 90 degrees animation. + */ + private static final int TURN_90_CW = 0x335; + + /** + * The player's turn 90 degrees animation. + */ + private static final int TUNR_90_CWW = 0x336; + + /** + * The player's run animation. + */ + private static final int RUN_ANIM = 0x338; + + } + +} diff --git a/Server/src/main/core/game/node/entity/player/link/appearance/BodyPart.java b/Server/src/main/core/game/node/entity/player/link/appearance/BodyPart.java new file mode 100644 index 0000000..6cdab5e --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/appearance/BodyPart.java @@ -0,0 +1,88 @@ +package core.game.node.entity.player.link.appearance; + + +import org.json.simple.JSONObject; + +import java.nio.ByteBuffer; + +/** + * Represents a body part of a player encapsulating the type and color. + * @author 'Vexia + */ +public final class BodyPart { + + /** + * Represents the look value of the part. + */ + private int look; + + /** + * Represents the color of this part. + */ + private int color; + + /** + * Constructs a new {@code BodyPart} {@code Object}. + */ + public BodyPart() { + /** + * empty. + */ + } + + /** + * Constructs a new {@code BodyPart} {@code Object}. + * @param look the look. + * @param color the color. + */ + public BodyPart(final int look, final int color) { + this.look = look; + this.color = color; + } + + /** + * Constructs a new {@code BodyPart} {@code Object}. + * @param look the look. + */ + public BodyPart(final int look) { + this(look, 0); + } + + public void parse(JSONObject part){ + changeLook(Integer.parseInt( part.get("look").toString())); + changeColor(Integer.parseInt( part.get("color").toString())); + } + + /** + * Method used to change the look value. + * @param look the look value. + */ + public void changeLook(final int look) { + this.look = look; + } + + /** + * Method used to change the color value. + * @param color the color value. + */ + public void changeColor(final int color) { + this.color = color; + } + + /** + * Gets the look. + * @return The look. + */ + public int getLook() { + return look; + } + + /** + * Gets the color. + * @return The color. + */ + public int getColor() { + return color; + } + +} diff --git a/Server/src/main/core/game/node/entity/player/link/appearance/Gender.java b/Server/src/main/core/game/node/entity/player/link/appearance/Gender.java new file mode 100644 index 0000000..869e3ee --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/appearance/Gender.java @@ -0,0 +1,60 @@ +package core.game.node.entity.player.link.appearance; + +/** + * Rerpresents a type of gender and it's relate base settings. + * @author 'Vexia + */ +public enum Gender { + MALE(new BodyPart[] { new BodyPart(0), new BodyPart(10), new BodyPart(18), new BodyPart(26), new BodyPart(33), new BodyPart(36), new BodyPart(42) }), + FEMALE(new BodyPart[] { new BodyPart(45), new BodyPart(1000), new BodyPart(56), new BodyPart(61), new BodyPart(68), new BodyPart(70), new BodyPart(79) }); + + /** + * Represents the default appearance of this gender. + */ + private final BodyPart[] appearanceCache; + + /** + * Constructs a new {@code Gender} {@code Object}. + */ + Gender(final BodyPart[] appearanceCache) { + this.appearanceCache = appearanceCache; + } + + /** + * Method used to generate a default appearance cache. + * @return the cache. + */ + public BodyPart[] generateCache() { + final BodyPart[] cache = new BodyPart[appearanceCache.length]; + for (int i = 0; i < cache.length; i++) { + cache[i] = new BodyPart(appearanceCache[i].getLook()); + } + return cache; + } + + /** + * Gets the appearance cache. + * @return The appearance cache. + */ + public BodyPart[] getAppearanceCache() { + return appearanceCache; + } + + /** + * Gets the representation as a byte. + * @return the byte. + */ + public byte toByte() { + return (byte) (this == MALE ? 0 : 1); + } + + /** + * Gets the gender from a byte. + * @param value the value. + * @return the gender. + */ + public Gender asByte(byte value) { + return value == 0 ? MALE : FEMALE; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/player/link/audio/Audio.kt b/Server/src/main/core/game/node/entity/player/link/audio/Audio.kt new file mode 100644 index 0000000..a1e1557 --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/audio/Audio.kt @@ -0,0 +1,29 @@ +package core.game.node.entity.player.link.audio + +/** + * An audio object to play. + * @author Zerken + */ +class Audio + @JvmOverloads + constructor( + @JvmField + val id: Int, + @JvmField + val delay: Int = 0, + @JvmField + val loops: Int = 1, + @JvmField + val radius: Int = defaultAudioRadius + ) { + companion object { + /** + * ----Audio Radius Constants---- + * Values which represent the tile distance/radius from which certain groups of audio can be heard from + * Certain sounds can be heard from a further distance than others + * This is a common place where audio distances can be adjusted if needed + */ + // TODO: Add specific groups of audios to have the correct radius (some sounds should be heard from a farther radius than others) + const val defaultAudioRadius = 8 + } + } \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/player/link/diary/AchievementDiary.java b/Server/src/main/core/game/node/entity/player/link/diary/AchievementDiary.java new file mode 100644 index 0000000..ddcddde --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/diary/AchievementDiary.java @@ -0,0 +1,568 @@ +package core.game.node.entity.player.link.diary; + +import core.cache.def.impl.NPCDefinition; +import core.game.component.Component; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import core.game.diary.DiaryLevel; + +import java.util.ArrayList; +import java.util.Arrays; + +/** + * Represents an achievement diary. + * @author Vexia + */ +public class AchievementDiary { + + /** + * The component id of the diary. + */ + public static final int DIARY_COMPONENT = 275; + + /** + * Completed levels for this diary + */ + public static final ArrayList completedLevels = new ArrayList(); + + /** + * Represents the red color code string. + */ + private static final String RED = ""; + + /** + * Represents the blue color code string. + */ + private static final String BLUE = ""; + + /** + * Represents the yellow color code string. + */ + private static final String YELLOW = ""; + + /** + * Represets the green color code string. + */ + private static final String GREEN = ""; + + /** + * The diary type. + */ + private final DiaryType type; + + /** + * The task types started. + */ + private final boolean[] levelStarted = new boolean[3]; + + /** + * If the rewards have been given. + */ + private final boolean[] levelRewarded = new boolean[3]; + + /** + * The completed achievements. + */ + private final boolean[][] taskCompleted; + + /** + * Constructs a new {@code AchievementDiary} {@code Object} + * @param type the diary type. + */ + public AchievementDiary(DiaryType type) { + this.type = type; + this.taskCompleted = new boolean[type.getAchievements().length][25]; + } + + /** + * Open the achievement diary. + * @param player the player. + */ + public void open(Player player) { + clear(player); + sendString(player, "Achievement Diary - " + type.getName(), 2); + int child = 12; + + sendString(player, (isComplete() ? GREEN : isStarted() ? YELLOW : "") + type.getName() + " Area Tasks", child++); + //child++; + + if (!type.getInfo().isEmpty() && !this.isStarted()) { + sendString(player, type.getInfo(), child++); + child += type.getInfo().split("

").length; + } + child++; + + boolean complete; + String line; + for (int level = 0; level < type.getAchievements().length; level++) { + sendString(player, getStatus(level) + getLevel(level) + "", child++); + child++; + for (int i = 0; i < type.getAchievements(level).length; i++) { + complete = isComplete(level, i); + line = type.getAchievements(level)[i]; + if (line.contains("

")) { + String[] lines = line.split("

"); + for (String l : lines) { + sendString(player, complete ? "" + l : l, child++); + } + } else { + sendString(player, complete ? "" + line : line, child++); + } + sendString(player, "*", child++); + } + child++; + } + if (!player.getInterfaceManager().isOpened()) { + player.getInterfaceManager().open(new Component(DIARY_COMPONENT)); + } + // Changes the size of the scroll bar (see 1207.cs2 for more) + // (args1: 1 is to start from top of scroll) (args0: child-12 lines to display) + player.getPacketDispatch().sendRunScript(1207, "ii", 1, child - 10); + } + + /** + * Clears the diary screen. + * @param player the player. + */ + private void clear(Player player) { + for (int i = 0; i < 311; i++) { + player.getPacketDispatch().sendString("", DIARY_COMPONENT, i); + } + } + + public void parse(JSONObject data){ + JSONArray startedArray = (JSONArray) data.get("startedLevels"); + for(int i = 0; i < startedArray.size(); i++){ + levelStarted[i] = (boolean) startedArray.get(i); + } + JSONArray completedArray = (JSONArray) data.get("completedLevels"); + for(int i = 0; i < completedArray.size(); i++){ + JSONArray level = (JSONArray) completedArray.get(i); + boolean completed = true; + for(int j = 0; j < level.size(); j++){ + taskCompleted[i][j] = (boolean) level.get(j); + if(!taskCompleted[i][j]){completed = !completed;} + completedLevels.add(i); + } + } + JSONArray rewardedArray = (JSONArray) data.get("rewardedLevels"); + for(int i = 0; i < rewardedArray.size(); i++){ + levelRewarded[i] = (boolean) rewardedArray.get(i); + } + } + + /** + * Draws the status of the diary. + * @param player the player. + */ + public void drawStatus(Player player) { + if (isStarted()) { + player.getPacketDispatch().sendString((isComplete() ? GREEN : YELLOW) + type.getName(), 259, type.getChild()); + for (int i = 0; i < 3; i++) { + player.getPacketDispatch().sendString((isComplete(i) ? GREEN : isStarted(i) ? YELLOW : "") + getLevel(i), 259, type.getChild() + (i + 1)); + } + } + } + + /** + * Induces a task update. + * @param player the player. + * @param level the level. + * @param index the index of the task. + * @param complete if it's completed. + */ + public void updateTask(Player player, int level, int index, boolean complete) { + if (!levelStarted[level]) { + levelStarted[level] = true; + } + if (!complete) { + player.sendMessage("Well done! A " + type.getName() + " task has been updated."); + } else { + taskCompleted[level][index] = true; + int tempLevel = this.type == DiaryType.LUMBRIDGE ? level - 1 : level; + player.sendMessages("Well done! You have completed " + + (tempLevel == -1 ? "a beginner" : tempLevel == 0 ? "an easy" : tempLevel == 1 ? "a medium" : "a hard") + + " task in the " + type.getName() + " area. Your", "Achievement Diary has been updated."); + } + if (isComplete(level)) { + player.sendMessages("Congratulations! You have completed all of the " + getLevel(level).toLowerCase() + + " tasks in the " + type.getName() + " area.", "Speak to " + + NPCDefinition.forId(type.getNpc(level)).getName() + " to claim your reward."); + } + drawStatus(player); + } + + public void finishTask(Player player, int level, int index) { + if (!this.isComplete(level, index)) { + this.updateTask(player, level, index, true); + boolean complete = true; + for(int i = 0; i < taskCompleted[level].length; i++){ + if(!taskCompleted[level][i]) { + complete = false; + break; + } + } + if(complete){ + completedLevels.add(level); + } else if(completedLevels.contains(level)) completedLevels.remove(level); + } + } + + /** + * Resets a task to un-start + */ + public void resetTask(Player player, int level, int index) { + taskCompleted[level][index] = false; + if (!isStarted(level)) { + this.levelStarted[level] = false; + } + if (!isComplete(level)) { + this.levelRewarded[level] = false; + } + drawStatus(player); + } + + public boolean checkComplete(DiaryLevel level){ + if(type != DiaryType.LUMBRIDGE && level == DiaryLevel.BEGINNER){ + return false; + } + + if(level == DiaryLevel.BEGINNER){ + return completedLevels.contains(level.ordinal()); + } + + return completedLevels.contains(level.ordinal() - 1); + } + + /** + * Sends a string on the diary interface. + * @param player the player. + * @param string the string. + * @param child the child. + */ + private void sendString(Player player, String string, int child) { + player.getPacketDispatch().sendString(string.replace("", BLUE).replace("", RED), DIARY_COMPONENT, child); + } + + /** + * Sets the diary for the level as started. + * @param level the level. + */ + public void setLevelStarted(int level) { + this.levelStarted[level] = true; + } + + /** + * Sets an achievement as completed. + * @param level the level. + * @param index the index. + */ + public void setCompleted(int level, int index) { + this.taskCompleted[level][index] = true; + } + + /** + * Checks if the achievement level is started. + * @param level the level. + * @return {@code True} if so. + */ + public boolean isStarted(int level) { + return this.levelStarted[level]; + } + + /** + * Checks if the diary is started. + * @return {@code True} if so. + */ + public boolean isStarted() { + for (int j = 0; j < type.getLevelNames().length; j++) { + if (isStarted(j)) { + return true; + } + } + return false; + } + + /** + * Checks if an achievement task is completed. + * @param level the level. + * @param index the index. + * @return {@code True} if an achievement is completed. + */ + public boolean isComplete(int level, int index) { + return taskCompleted[level][index]; + } + + /** + * Checks if the achievement level is completed. + * @param level the level. + * @return {@code True} if so. + */ + public boolean isComplete(int level) { + for (int i = 0; i < type.getAchievements(level).length; i++) { + if (!taskCompleted[level][i]) { + return false; + } + } + return true; + } + + public boolean isComplete(int level, boolean cumulative) { + if (isComplete(level)) { + return !cumulative || level <= 0 || isComplete(level - 1, true); + } else { + return false; + } + } + + /** + * Checks if an achievement diary is complete. + * @return {@code True} if completed. + */ + public boolean isComplete() { + for (int i = 0; i < taskCompleted.length; i++) { + for (int x = 0; x < type.getAchievements(i).length; x++) { + if (!taskCompleted[i][x]) { + return false; + } + } + } + return true; + } + + /** + * Gets the level of completion. + * @return the level. + */ + public int getLevel() { + return isComplete(2) ? 2 : isComplete(1) ? 1 : isComplete(0) ? 0 : -1; + } + + /** + * Gets the level of reward. + * @return the level. + */ + public int getReward() { + return isLevelRewarded(2) ? 2 : isLevelRewarded(1) ? 1 : isLevelRewarded(0) ? 0 : -1; + } + + /** + * Gets the level string. + * @param level the level. + * @return the string format. + */ + public String getLevel(int level) { + return type.getLevelNames()[level]; + } + + /** + * Gets the status for a level of completion of the achievement. + * @param level the level. + * @return the string color status. + */ + public String getStatus(int level) { + return !isStarted(level) ? RED : isComplete(level) ? GREEN : YELLOW; + } + + /** + * Sets the level as rewarded. + * @param level the level. + */ + public void setLevelRewarded(int level) { + this.levelRewarded[level] = true; + } + + /** + * Checks if the reward has been given. + * @param level the level. + * @return {@code True} if so. + */ + public boolean isLevelRewarded(int level) { + return levelRewarded[level]; + } + + /** + * Gets the completed. + * @return the completed + */ + public boolean[][] getTaskCompleted() { + return taskCompleted; + } + + /** + * Gets the type. + * @return the type + */ + public DiaryType getType() { + return type; + } + + /** + * Gets the started. + * @return the started + */ + public boolean[] getLevelStarted() { + return levelStarted; + } + + /** + * Gets the rewarded. + * @return the rewarded + */ + public boolean[] getLevelRewarded() { + return levelRewarded; + } + + /** + * Removes the non-lamp reward item for the given level of the given type + * @param player the player to remove the reward from + * @param type the DiaryType: LUMBRIDGE, FALADOR, etc. + * @param level the diary level. 0-indexed. + * @return whether or not a reward was removed + */ + public static boolean removeRewardsFor(Player player, DiaryType type, int level) { + Item[] rewards = type.getRewards(level); + //lamps are always the 2nd reward for a level, don't remove lamps + boolean hasRemoved = + player.getInventory().remove(rewards[0]) + ||player.getBank().remove(rewards[0]) + ||player.getEquipment().remove(rewards[0]); + + if (hasRemoved) { + player.debug("Removed previous reward"); + } + + return hasRemoved; + } + + /** + * Adds all rewards for the given level of the given type (including lamps) + * Will return false if the player can't fit all the items in their inventory. + * @param player the player to grant the items to + * @param type the DiaryType: LUMBRIDGE, FALADOR, etc. + * @param level the diary level. 0-indexed. + * @return whether or not we successfully added the reward items to the player's inventory. + */ + public static boolean addRewardsFor(Player player, DiaryType type, int level) { + Item[] rewards = type.getRewards(level); + + int freeSlots = player.getInventory().freeSlots(); + if (freeSlots < rewards.length) + return false; + + boolean allRewarded = true; + for (Item reward : rewards) { + allRewarded &= player.getInventory().add(reward); + } + + if (!allRewarded) { + Arrays.stream(rewards).forEach((item) -> { + boolean _ignored = player.getInventory().remove(item); + }); + } + + return allRewarded; + } + + /** + * Convenience method. Flags a level as complete, removes previous level's reward item, then adds new reward items. + * @param player the player to flag completion for + * @param type the DiaryType: LUMBRIDGE, FALADOR, etc. + * @param level the diary level. 0-indexed. + */ + public static boolean flagRewarded(Player player, DiaryType type, int level) { + if (level > 0) { + removeRewardsFor(player, type, level - 1); + } + if (addRewardsFor(player, type, level)) + player.getAchievementDiaryManager().getDiary(type).setLevelRewarded(level); + else { + player.sendMessage("You do not have enough space in your inventory to claim these rewards."); + return false; + } + + return true; + } + + /** + * Determines if a replacement reward can be given for the particular diary and level. + * Checks to make sure the player has completed the level and claimed the rewards, and has not claimed + * the next diary level. + * @param player the player to check + * @param type the DiaryType: LUMBRIDGE, FALADOR, etc. + * @param level the diary level. 0-indexed. + * @return whether or not a replacement can be granted. + */ + public static boolean canReplaceReward(Player player, DiaryType type, int level) { + Item reward = type.getRewards(level)[0]; + boolean claimed = hasCompletedLevel(player, type, level) + && hasClaimedLevelRewards(player, type, level) + && !player.hasItem(reward); + return level == 2 ? claimed : claimed && !hasClaimedLevelRewards(player, type, level+1); + } + + /** + * Grants the replacement for the given level provided the player is eligible. + * Does not refund lamps. + * @param player the player to grant the reward to + * @param type the DiaryType: LUMBRIDGE, FALADOR, etc. + * @param level the diary level, 0-indexed + * @return whether or not the player was granted the replacement + */ + public static boolean grantReplacement(Player player, DiaryType type, int level) { + Item reward = type.getRewards(level)[0]; //Can only replace non-lamp reward + return canReplaceReward(player, type, level) && player.getInventory().add(reward); + } + + /** + * Checks if a player has completed the given level of the given diary. + * @param player the player to check + * @param type the DiaryType: LUMBRIDGE, FALADOR, etc. + * @param level the level to check, 0-indexed + * @return whether or not the player has completed the level. + */ + public static boolean hasCompletedLevel(Player player, DiaryType type, int level) { + if (level > type.getLevelNames().length - 1) + return false; + return player.getAchievementDiaryManager().getDiary(type).isComplete(level, true); + } + + /** + * Checks if a player has claimed the rewards for the given level of the given diary + * @param player the player to check + * @param type the DiaryType: LUMBRIDGE, FALADOR, etc. + * @param level the level te check + * @return whether or not the player has claimed the rewards + */ + public static boolean hasClaimedLevelRewards(Player player, DiaryType type, int level) { + return player.getAchievementDiaryManager().getDiary(type).isLevelRewarded(level); + } + + /** + * Checks if a player can claim the rewards for the given level of the given diary + * Checks to make sure the player hasn't claimed the next level. + * @param player the player to check + * @param type the DiaryType: LUMBRIDGE, FALADOR, etc. + * @param level the level to check + * @return whether or not the player can claim the rewards + */ + public static boolean canClaimLevelRewards(Player player, DiaryType type, int level) { + if (level == 2) + // Cannot be a higher level to claim + return hasCompletedLevel(player, type, level) && !hasClaimedLevelRewards(player, type, level); + else + return !hasClaimedLevelRewards(player, type, level + 1) && hasCompletedLevel(player, type, level) && !hasClaimedLevelRewards(player, type, level); + } + + /** + * Fetches the rewards for a given diary at the given level. + * @param type the DiaryType: LUMBRIDGE, FALADOR, etc. + * @param level the level, 0-indexed. + * @return an array of the reward items for that level. Includes lamps. The non-lamp reward is always index 0. + */ + public static Item[] getRewards(DiaryType type, int level) { + return type.getRewards(level); + } +} diff --git a/Server/src/main/core/game/node/entity/player/link/diary/AchievementDiaryManager.java b/Server/src/main/core/game/node/entity/player/link/diary/AchievementDiaryManager.java new file mode 100644 index 0000000..fd693fb --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/diary/AchievementDiaryManager.java @@ -0,0 +1,255 @@ +package core.game.node.entity.player.link.diary; + +import core.game.component.Component; +import core.game.container.impl.EquipmentContainer; +import core.game.node.entity.player.Player; +import content.global.skill.smithing.smelting.Bar; +import core.game.node.item.Item; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; + +/** + * Manages the achievement diary of a player. + * @author Vexia + */ +public class AchievementDiaryManager { + + /** + * The achievement diarys. + */ + private final AchievementDiary[] diarys = new AchievementDiary[] { + new AchievementDiary(DiaryType.KARAMJA), + new AchievementDiary(DiaryType.VARROCK), + new AchievementDiary(DiaryType.LUMBRIDGE), + new AchievementDiary(DiaryType.FALADOR), + new AchievementDiary(DiaryType.FREMENNIK), + new AchievementDiary(DiaryType.SEERS_VILLAGE) + }; + + /** + * The player instance. + */ + private final Player player; + + /** + * Constructs a new + * @param player the player. + */ + public AchievementDiaryManager(Player player) { + this.player = player; + } + + public void parse(JSONArray data){ + for(int i = 0; i < data.size(); i++){ + JSONObject diary = (JSONObject) data.get(i); + String name = (String) diary.keySet().toArray()[0]; + name = name.replace("_","' "); + for (int ii = 0; ii < diarys.length; ii++) { + if (diarys[ii].getType().getName().equalsIgnoreCase(name)) { + diarys[ii].parse((JSONObject) diary.get(name.replace("' ","_"))); + } + } + } + } + + /** + * Opens the achievement diary tab. + */ + public void openTab() { + player.getInterfaceManager().openTab(2, new Component(259)); + for (AchievementDiary diary : diarys) { + diary.drawStatus(player); + } + } + + /** + * Induces a task update. + * @param player the player. + * @param type the diary type. + * @param level the level. + * @param index the index of the task. + * @param complete if it's completed. + */ + public void updateTask(Player player, DiaryType type, int level, int index, boolean complete) { + getDiary(type).updateTask(player, level, index, complete); + } + + public void finishTask(Player player, DiaryType type, int level, int index) { + if(!player.isArtificial()) { + getDiary(type).finishTask(player, level, index); + } + } + + /** + * Checks if a task has been completed. + * @param type the diary type. + * @param level the level. + * @param index the index. + * @return {@code True} if completed. + */ + public boolean hasCompletedTask(DiaryType type, int level, int index) { + return getDiary(type).isComplete(level, index); + } + + /** + * Sets the diary at a level as started. + * @param type the type of diary. + * @param level the level. + */ + public void setStarted(DiaryType type, int level) { + getDiary(type).setLevelStarted(level); + } + + /** + * Sets the diarys achievement as completed. + * @param type the type. + * @param level the level. + * @param index the index. + */ + public void setCompleted(DiaryType type, int level, int index) { + getDiary(type).setCompleted(level, index); + } + + /** + * Gets the achievement diary for the type. + * @param type the type. + * @return the diary object. + */ + public AchievementDiary getDiary(DiaryType type) { + if (type == null) { + return null; + } + for (AchievementDiary diary : diarys) { + if (diary.getType() == type) { + return diary; + } + } + return null; + } + + /** + * Gets the karamaja glove level. + * @return the level of the glove. + */ + public int getKaramjaGlove() { + if (!hasGlove()) { + return -1; + } + for (int i = 0; i < 3; i++) { + if (player.getEquipment().containsItem(DiaryType.KARAMJA.getRewards()[i][0])) { + return i; + } + } + return -1; + } + + /** + * Gets the varrock armour level. + * @return the level of the armour. + */ + public int getArmour() { + if (!hasArmour()) { + return -1; + } + for (int i = 0; i < 3; i++) { + if (player.getEquipment().containsItem(DiaryType.VARROCK.getRewards()[i][0])) { + return i; + } + } + return -1; + } + + /** + * Checks the if the reward is valid for double. + * @param reward the reward. + * @return {@code True} if validated. + */ + public boolean checkMiningReward(int reward) { + int level = player.getAchievementDiaryManager().getArmour(); + if (level == -1) { + return false; + } + if (reward == 453) { + return true; + } + return level == 0 && reward <= 442 || level == 1 && reward <= 447 || level == 2 && reward <= 449; + } + + /** + * Checks the if the reward is valid for double. + * @param type the bar type. + * @return {@code True} if validated. + */ + public boolean checkSmithReward(Bar type) { + int level = player.getAchievementDiaryManager().getArmour(); + if (level == -1) { + return false; + } + return level == 0 && type.ordinal() <= Bar.STEEL.ordinal() || level == 1 && type.ordinal() <= Bar.MITHRIL.ordinal() || level == 2 && type.ordinal() <= Bar.ADAMANT.ordinal(); + } + + /** + * Checks if the player has karamaja gloves. + * @return the gloves. + */ + public boolean hasGlove() { + Item glove = player.getEquipment().get(EquipmentContainer.SLOT_HANDS); + return glove != null && (glove.getId() == DiaryType.KARAMJA.getRewards()[0][0].getId() || glove.getId() == DiaryType.KARAMJA.getRewards()[1][0].getId() || glove.getId() == DiaryType.KARAMJA.getRewards()[2][0].getId()); + } + + /** + * Checks if the player has varrock armour. + * @return {@code True} if so. + */ + public boolean hasArmour() { + Item plate = player.getEquipment().get(EquipmentContainer.SLOT_CHEST); + return plate != null && (plate.getId() == DiaryType.VARROCK.getRewards()[0][0].getId() || plate.getId() == DiaryType.VARROCK.getRewards()[1][0].getId() || plate.getId() == DiaryType.VARROCK.getRewards()[2][0].getId()); + } + + /** + * Checks if a diary is complete. + * @param type the diary type. + * @return {@code True} if so. + */ + public boolean isComplete(DiaryType type) { + return diarys[type.ordinal()].isComplete(); + } + + /** + * Gets the player. + * @return the player + */ + public Player getPlayer() { + return player; + } + + /** + * Gets the diarys. + * @return the diarys + */ + public AchievementDiary[] getDiarys() { + return diarys; + } + + /** + * Removes rewards from player + * obtained via old incomplete diaries + */ + public void resetRewards() { + for (AchievementDiary diary: diarys) { + for (Item[] axis : diary.getType().getRewards()) { + for (Item item : axis) { + if (player.getInventory().containsItem(item)) { + player.getInventory().remove(item); + } + if (player.getBank().containsItem(item)) { + player.getBank().remove(item); + } + if (player.getEquipment().containsItem(item)) { + player.getEquipment().remove(item); + } + } + } + } + } +} diff --git a/Server/src/main/core/game/node/entity/player/link/diary/DiaryType.java b/Server/src/main/core/game/node/entity/player/link/diary/DiaryType.java new file mode 100644 index 0000000..a91f4b5 --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/diary/DiaryType.java @@ -0,0 +1,639 @@ +package core.game.node.entity.player.link.diary; + +import core.game.node.entity.player.Player; +import org.rs09.consts.Items; +import core.game.node.item.Item; + +/** + * An achievement diary type. + * + * @author afaroutdude + */ +// TODO reset all players tasks upon commit to master +// TODO figure out secondary rewards for karamja, and fremennik +public enum DiaryType { + KARAMJA("Karamja", 11, + new String[]{"Easy", "Medium", "Hard"}, + new String[][]{ + { + "Pick 5 bananas from the plantation located east of the

volcano", + "Use the rope swing to travel to the small island north-west

of Karamja, where the moss giants are", + "Mine some gold from the rocks on the north-west

peninsula of Karamja", + "Travel to Port Sarim via the dock, east of Musa Point", + "Travel to Ardougne via the port near Brimhaven", + "Explore Cairn Island to the west of Karamja", + "Use the Fishing spots north of the banana plantation", + "Collect 5 seaweed from anywhere on Karamja", + "Attempt the TzHaar Fight Pits or Fight Cave", + "Kill a Jogre in the Pothole dungeon" + }, + { + "Claim a ticket from the Agility arena in Brimhaven", + "Discover hidden wall in the dungeon below the volcano", + "Visit the Isle of Crandor via the dungeon below the volcano", + "Use Vigroy and Hajedy's cart service", + "Earn 100% favour in the village of Tai Bwo Wannai Cleanup", // todo tai bwo wannai cleanup + "Cook a spider on stick", // todo tai bwo wannai cleanup + "Charter the Lady of the Waves from Cairn Isle to Port Khazard", // todo verify + "Cut a log from a teak tree", + "Cut a log from a mahogany tree", + "Catch a karambwan", // todo need Tai Bwo Wannai Trio + "Exchange gems, a gout tuber, trading sticks for a machete", // todo + "Use the gnome glider to travel to Karamja", + "Grow a healthy fruit tree in the patch near Brimhaven", // todo verify + "Trap a Horned Graahk", // todo need to implement pitfall trapping + "Chop the vines to gain deeper access to Brimhaven Dungeon", + "Cross the lava using the stepping stones within Brimhaven

Dungeon", + "Climb the stairs within Brimhaven Dungeon", + "Charter a ship from the shipyard in the far east of Karamja", + "Mine a red topaz from a gem rock" + }, + { + "Become the Champion of the Fight Pits", + "Successfully kill a Ket-Zek in the Fight Caves", + "Eat an oomlie wrap", + "Craft some nature runes", + "Cook a karambwan thoroughly", // todo need Tai Bwo Wannai Trio + "Kill a deathwing in the dungeon under the Kharazi Jungle", // todo need legends quest + "Use the crossbow shortcut south of the volcano", + "Collect five palm leaves", + "Be assigned a Slayer task by Duradel or Lapalok in Shilo

Village.", + "Kill a metal dragon in Brimhaven Dungeon." + } + }, + // Karamja gloves 1-3 + // 1k xp 30+, 5k xp any?, 10k xp any? + new Item[][]{ + {new Item(Items.KARAMJA_GLOVES_1_11136), new Item(Items.ANTIQUE_LAMP_11137)}, + {new Item(Items.KARAMJA_GLOVES_2_11138), new Item(Items.ANTIQUE_LAMP_11139)}, + {new Item(Items.KARAMJA_GLOVES_3_11140), new Item(Items.ANTIQUE_LAMP_11141)} + }, + "To start marking off tasks in your journal, speak to Pirate

Jackie the Fruit in Brimhaven, Kaleb Paramay in Shilo

Village or one of the Jungle Foresters north of the

Kharazi Jungle.", + new int[]{1055, 512, 401} + /** + * Secondary rewards + * Easy + * - cheaper prices on karamja and cheaper ship rides + * Medium + * - 10% extra agility xp in arena + * - 10% extra xp redeeming tickets + * Hard + * - Gem mine ladder access // todo + * - Teleport to underground gem mine // todo + */ + ), + // https://2009scape.wiki/w/Varrock_achievements?oldid=891055 + VARROCK("Varrock", 15, + new String[]{"Easy", "Medium", "Hard"}, + new String[][]{ // TODO verify implementation ingame + { + "Have Thessalia show you what outfits you can wear", + "Have Aubury teleport you to the essence mine", + "Mine some Iron in the south east mining patch near Varrock", + "Make a plank at the sawmill", + "Enter the second level of the Stronghold of Security", + "Jump over the fence south of Varrock", + "Chop down a dying tree in the Lumber Yard", + "Buy a copy of the Varrock Herald", + "Give a stray dog a bone", + "Spin a bowl on the pottery wheel and fire it in the oven in

Barbarian Village", + "Enter Edgeville Dungeon using the entrance to the south of

Edgeville", + "Move your player-owned house portal to a different location

using the Varrock estate agent", + "Speak to Haig Halen after obtaining at least 50 quest points", //TODO need to changes this back to kudos when implemented + "Enter the Earth Altar using an earth tiara or talisman", + "Have Elsie tell you a story", + "Mine some limestone near Paterdomus, the temple to the east

of Varrock", + "Catch a trout in the river to the east of Barbarian Village.", + "Venture through the cobwebbed corridor in Varrock Sewers", + "Find the highest point in Varrock" + }, + { + "Have the Apothecary in Varrock make you a strength potion.", + "Enter the Champions Guild.", + "Take the Dagon'Hai shortcut to the chaos portal", + "Get a full complement of rats on your rat pole", // TODO need rat catchers to start + "Escape from the spider lair in Varrock Sewers with some red

spiders eggs", + "Use the spirit tree north of Varrock", + "Perform the 4 emotes from the Stronghold of Security.", + "Select a colour for a new kitten", // TODO need ring of charos(a) and garden of tranquility to start + "Use the shortcut under the wall, north-west of the Grand

Exchange", + "Enter the A Soul's Bane rift", + "Teleport to the Digsite using a Digsite pendant", // TODO need Digsite and museum + "Craft an earth tiara on the Earth Altar", + "Pickpocket a guard in the Varrock Palace courtyard", + "Use the teleport to Varrock spell", + "Get a Slayer task from Vannaka", + "Buy twenty mahogany planks from the Sawmill Operator in one

transaction", + "Pick a fruit from the White Tree", // TODO Garden of Tranquility + "Use the hot air balloon to travel from Varrock to somewhere

else", // TODO Enlightened Journey + "Get a cat training medal from Gertrude", // TODO need rat catchers and cats fixed + "Dial to the fairy ring west of Varrock", + "Browse through Oziach's Armour Shop" + }, + { + "Pick poison ivy from your bush Farming patch in Varrock

(west of Champions' Guild)", + "Use the pipe shortcut in Varrock Sewers, near the moss

giants", + "Trade furs with the Fancy Dress Seller for a spottier cape", + "Smith an adamantite medium helm on the south-east anvil in

Varrock, next to Aubury's Rune Shop", + "Speak to Orlando Smith when you have achieved 153 kudos", // TODO need to implement kudos + "Talk to Romily Weaklax and give him a wild pie", + "Craft an air battlestaff", + "Give your player-owned house a tropical wood or fancy stone

finish at the Varrock estate agent's", + "Make a Varrock teleport tablet on a mahogany lectern", + "Obtain a new set of Family Crest gauntlets from Dimintheis", // TODO need family crest + "Make a Waka Canoe near Edgeville", + "Use the Home Teleport spell in the Ancient Magicks spellbook

to teleport to Edgeville", + "Use the skull sceptre to teleport to Barbarian Village" + } + }, + new Item[][]{ + {new Item(11756), new Item(11753)}, + {new Item(11757), new Item(11754)}, + {new Item(11758), new Item(11755)} + }, + "To start marking off tasks in your journal, speak to

Rat Burgiss south of the city, Reldo in the palace

library, or Vannaka in the sewers.", // todo made up, can't find source + // Varrock Armour 1-3 + // 1k xp 30 or higher, 5k xp 40 or higher, 10k 50 or higher + // Rat Burgiss, Reldo (has an NPC config...), Vannaka + new int[]{5833, 2660, 1597} + /** + * Secondary rewards + * Easy + * - chance of smelting two bars at once up to and including steel in edgeville furnace + * - chance of mining two ores at once when mining ores up to and including coal + * - better prices when buying and selling in Varrock Area // todo + * - 16 battlestaffs may be bought from Zaff's staffs store daily (8 + 8) + * - Option to change Varrock tele location to the GE by talking to Rat Burgiss // todo + * Medium + * - chance of smelting two bars at once up to and including Mithril in edgeville furnace + * - chance of mining two ores at once when mining ores up to and including mithril + * - chance of smithing at a slightly faster rate // todo + * - 32 battlestaffs may be bought from Zaff's staffs store daily (8 + 24) + * - Option to change Varrock tele location to the GE by talking to Reldo // todo + * Hard + * - chance of smelting two bars at once up to and including Adamantite in edgeville furnace + * - chance of mining two ores at once when mining ores up to and including adamantite + * - access to cook's guild 1st floor bank area + * - use varrock armour to get into cook's guild rather than chef's hat + * - 64 battlestaffs may be bought from Zaff's staffs store daily (8 + 56) + * - Option to change Varrock tele location to the GE by talking to Vannaka // todo + */ + ), + // https://2009scape.wiki/w/Lumbridge_achievements?oldid=866361 + LUMBRIDGE("Lumbridge", 2, + new String[]{"Beginner", "Easy", "Medium"}, + new String[][]{ + { + "Climb to the highest point in Lumbridge", + "Raise the flag on the roof of the Lumbridge Bank", + "Speak to the Duke of Lumbridge", + "Speak with the Doomsayer about the Warning System", + "Pass through the Al Kharid gate", + "Mine some clay in the Mining patch north of the Champions'

Guild", + "Make some soft clay in the Barbarian Village", + "Fire a pot in the kiln in the Barbarian Village potter's

house", + "Enter the courtyard of the spooky mansion in Draynor Village", + "Visit the Draynor Village market", + "Find out about the Rules of Conduct from the Draynor

Town Crier", + "Climb to the top of the Wizards' Tower", + "Mine some copper in the Mining spot to the south-east of

Lumbridge Swamp", + "Catch some shrimp in the Fishing spot to the east of

Lumbridge Swamp", + "Have the Fishing Tutor send you on an errand", + "Look through Father Aereck's selection of gravestones", + "Play the organ in the Lumbridge Church", + "Find out about the Stronghold of Security from the Lumbridge

Guide", + "Browse the Lumbridge General Store", + "Visit Fred the Farmer's chicken and sheep farm", + "Grind some flour in the windmill north of Lumbridge" + }, + { + "Mine some iron ore from the Al Kharid Mining spot", + "Obtain a cow-hide from a cow in the field north-east of

Lumbridge", + "Have Ellis tan your cow-hide to make soft leather at his

shop in Al Kharid", + "Craft a pair of soft leather gloves", + "Catch a pike in the river to the east of Lumbridge Castle", + "Smelt a steel bar in the Lumbridge furnace", + "Search the shed in Lumbridge Swamp", + "Kill a giant rat in Lumbridge Swamp", + "Cut down a dead tree in Lumbridge Swamp", + "Light a campfire from normal logs in Lumbridge Swamp", + "Cook some rat meat on a campfire in Lumbridge Swamp", + "Craft a water rune at the Water Altar", + "Get a replacement Ghostspeak Amulet from Father Urhney", + "Taunt the demon at the top of the Wizard's Tower", + "Have Sedridor teleport you to the Essence Mine", + "Access the bank in Draynor Village", + "Have the Wise Old man check your bank for unnecessary

quest-related items", + "Discover what the Wise Old man is watching through his

telescope", + "Defeat a zombie in the sewers under the jail" + }, + { + "Smith a steel longsword on the anvil in the jailhouse

sewers", + "Take a ride on Gnomecopter", + "Use the teleport Lumbridge spell", + "Light a willow log fire in Lumbridge Castle courtyard", + "Cook a lobster on the range in Lumbridge Castle kitchen", + "Obtain an Anti-dragonbreath shield from Duke Horacio", + "Cut a willow tree, east of Lumbridge Castle", + "Smelt a silver bar in the Lumbridge furnace", + "Craft a holy symbol in the Lumbridge furnace", + "Catch a salmon in the river to the east of Lumbridge Castle", + "Mine some silver from the mining spot north of Al Kharid", + "Mine some coal in the Mining spot south-west of Lumbridge

Swamp" + } + }, + // Explorer's Rings 1-3 + // 500 any, 1k xp 30 or higher, 1.5k xp 35 or higher + new Item[][]{ + {new Item(13560), new Item(11185)}, + {new Item(13561), new Item(11186)}, + {new Item(13562), new Item(11187)}}, + "To start marking off tasks in your journal, speak to

Explorer Jack near the Lumbridge General Store, Bob

in his axe store or Ned in his house in Draynor Village.", // todo made up, can't find source + // Explorer Jack, Bob, Ned // todo more accurate dialogues for these guys + new int[]{7969, 519, 743} + /** + * Secondary Rewards + * Beginner + * - Explorer's ring 1 when worn replenishes 50% run energy per charge once a day + * - Explore emote unlocked + * Easy + * - 50% run energy twice a day + * - Low Level Alchemy 30 times per day without runes + * - 10% Chance of extra rune (per essence) - air,earth,fire,water + * Medium + * - 50% run energy thrice a day + * - 30 low alch per day + * - 10% Chance of extra rune (per essence) - air,earth,fire,water + * - cabbage port + */ + + ), + // https://2009scape.wiki/w/Falador_achievements?oldid=900390 + FALADOR("Falador", 23, + new String[]{"Easy", "Medium", "Hard"}, + new String[][]{ + { + "Buy a Farming amulet from Sarah on the farm north of Port

Sarim", + "Buy a stat-boosting beer from a waitress in the Rising Sun

Tavern", + "Buy a black chainbody from Wayne's Chains, and try it on in

the shop", + "Climb to the top of the White Knights' Castle", + "Discover your family crest from Sir Renitee", + "Enter the mole's lair under Falador Park", + "Feed Ridgeley, the hairdresser's pet", + "Fill a bucket from the pump north of the west Falador bank", + "Heal an elemental wizard by casting an appropriate elemental

spell on him (Air, Water, Earth, Fire)", + "Kill a duck in Falador Park", + "Kill a highwayman on the road south of Falador", + "Make an air tiara", + "Pop a party balloon", + "Recharge your Prayer points at the altar south-west of Port

Sarim", + "Take the boat to Entrana" + }, + { + "Craft a Fruit basket using the loom at the farm north of

Port Sarim", + "Crawl under Falador's south wall", + "Grapple up, and then jump off the north Falador wall", + "Increase your reputation with the White Knights by killing

a black knight", + "Kill an ice giant in the Asgarnian Ice Dungeon", + "Light a bullseye lantern in the chemist's", + "Pickpocket a Falador guard", + "Place a scarecrow to protect your sweetcorn as it grows in

the patch north of Port Sarim", + "Salute Sir Tiffy Cashien while wearing full initiate armour", + "Smith blurite crossbow limbs on Thurgo's anvil", + "Travel from Port Sarim to Musa Point for free (with a little

help from Charos)", // TODO need Creature of Fenkenstrain to actually obtain Charos ring + "Visit the Port Sarim rat pits" + }, + { + "Ascend the Dark Wizards' Tower while wearing full proselyte

armour", + "Change your family crest to the Saradomin symbol", + "Craft 196 or more air runes simultaneously", + "Cut down a Yew tree or Magic tree that you grew in Falador

Park", + "Dial to the fairy ring on Mudskipper Point", + "Dye a cape pink with Pink dye from Betty in Port Sarim", + "Enter the Mining Guild", + "Kill a mogre at Mudskipper Point", + "Kill a skeletal wyvern in the Asgarnian Ice Dungeon", + "Summon an Ibis in the Port Sarim fish store" + } + }, + // Falador Shields 1-3 + // 1k XP, 5k XP, 10k XP + new Item[][]{ + {new Item(14577), new Item(14580)}, + {new Item(14578), new Item(14581)}, + {new Item(14579), new Item(14582)} + }, + "To start marking off tasks in your journal, speak to

Redbeard Frank outside the bar in Port Sarim, The

Chemist west of Rimmington, or Sir Vyvin's Squire in the

Falador Castle courtyard.", // todo made up, can't find source + // Redbeard Frank, Chemist, Squire + new int[]{375, 367, 606} + /** + * Secondary Rewards + * Easy + * - shield 1 restores 25% prayer daily, +3 prayer bonus + * - shields have emotes when you wield and hit operate + * Medium + * - shield 2 restores 50% prayer daily, +5 prayer bonus + * - 10% extra farming xp north of port sarim + * Hard + * - shield 3 restores 100% prayer daily, +7 prayer bonus + * - can trade Mole Skins in to Wyson in exchange for white lily seeds and birds nest + */ + ), + // https://2009scape.wiki/w/Fremennik_achievements?oldid=877418 + FREMENNIK("Fremennik", 19, + new String[]{"Easy", "Medium", "Hard"}, + new String[][]{ + { + "Kill a cave crawler in the Fremennik Slayer Dungeon", + "Kill five rock crabs on the shore near Rellekka or on

Waterbirth Island", + "Find the highest tree on the Fremennik mainland", + "View the rewards in the Barbarian Assault tutorial", // TODO: Move this to appropriate dialogue once Barbarian Assault is implemented + "Speak to Otto Godblessed about barbarian training", // TODO: Move this to an appropriate point once the entirety of Barbarian training is implemented + "Collect three seaweed from the shore north-east of Rellekka", + "Find the Hunting Expert on the northern ice plains", // TODO: Transcribe the appropriate authentic dialogue for this NPC. Mockup dialogue implemented as a bandaid. + "Catch a fish off one of Rellekka's piers", // TODO: Make this check for any Fishing Spots within the Rellekkan region ID list. Currently only checks the "Cage/Harpoon" Fishing spots at the northeastern most pier. + "Recharge your Summoning points near Rellekka's gate", + "Kill an adult black unicorn" + }, + { + "Learn of the history of the Fremennik and the Outerlanders

from Chieftain Brundt", // TODO + "Watch a shouting match between Fremennik Isles tower guards

(the guards can be found between Jatizso and Neitiznot in

one of the towers)", // TODO + "Interact with a Pet rock", // TODO + "Make three vials in the furnace building at Rellekka", // TODO + "Charm the Fossegrimen into accepting a raw bass", // TODO + "Wear yak-hide armour and kill an ice troll", // TODO + "Make cheese in the dairy churn in Rellekka", // TODO + "Use a fairy ring to appear on a mountaintop, near the

windswept tree", // TODO + "Look at Yrsa's options for recolouring your boots in her

clothes shop in Rellekka", // TODO + "Successfully hunt a sabre-toothed kyatt", // TODO + "Steal a fish from the fishing stall in the Rellekka

marketplace" // TODO + }, + { + "Kill three dagannoths in the first layer of the Waterbirth

Island Dungeon", // TODO + "Wear rockshell, spined or skeletal armour and have the

locals use an honorific with your Fremennik name", // TODO + "Complete the Barbarian Outpost Agility Course", // TODO + "Mine pure essence on Lunar Isle", // TODO + "Make a barbarian pyre ship from arctic pine", // TODO + "Catch a tuna without a harpoon", // TODO + "Bake a pie using Magic", // TODO + "Kill a Mithril dragon", // TODO + "Get mahogany from your Etceterian subjects" // TODO + } + }, + // Fremennik sea boots 1-3 + // 5k, 10k, 15k xp + new Item[][]{ + {new Item(14571), new Item(14574)}, + {new Item(14572), new Item(14575)}, + {new Item(14573), new Item(14576)} + }, + "", // todo + // Council Workman, Yrsa, Advisor Ghrim // TODO dialogues for all these + new int[]{1287, 1301, 1375} + ), + // https://2009scape.wiki/w/Seers%27_Village_achievements?oldid=900527 + // https://www.youtube.com/watch?v=chYdp5HKJAg easy + SEERS_VILLAGE("Seers' Village", 27, + new String[]{"Easy", "Medium", "Hard"}, + new String[][]{ + { + "Pick five flax from the flax field", + "Walk clockwise around the big mysterious statue", + "Have Sir Galahad make you a cup of tea", + "Take the poison chalice to King Arthur", + "Spin five bow strings", + "Fill five pots with flour from the Sinclair Mansion", + "Give five locals a glass of cider in the Forester's Arms", + "Plant some jute", + "Use the churn in the Sinclair Mansion garden", + "Buy a candle from the candle-maker", + "Pray at the Seers' Village altar", + "Catch a mackerel" + }, + { + "Use the Sinclair Mansion to Fremennik agility shortcut", + "Talk to Thormac the Sorcerer about making mystic staves", + "Transport a full load of coal to Seers' Village", + "Find the highest point in Seers' Village", + "Defeat each type of elemental in the Elemental Workshop", + "Teleport to Camelot", + "Kill one guard on each tower of the Ranging Guild using a longbow", + "Have the Ranging Guild competition judge congratulate you

for acquiring over 1,000 Archery tickets", + "Buy something from the ticket exchange in the Ranging Guild", + "Use a familiar to make a fire from maple logs within Seers'

Village", + "Get a pet fish from Harry", + "Catch and cook a bass in Catherby" + }, + { + "Teleport to the Ranging Guild", + "Cut five sets of yew logs", + "Fletch a magic shortbow in the Seers' Village Bank", + "Enter the Seers' Village courthouse with your Piety prayer

turned on", + "Use the fairy ring in McGrubor's Wood", + "Burn a magic log in Seers' Village", + "High Alch a magic shortbow in the Seers' Village bank", + "Catch five sharks in Catherby", + "Cook 5 sharks in Catherby using the Cooking gauntlets", + "Charge five water orbs in one go", + "Use the grapple shortcut to get from the water obelisk

island to Catherby shore" + } + }, + // Seers Headbad 1-3 + // 1k 30 and up, 5k, 10k xp lamps + new Item[][]{ + {new Item(14631), new Item(14633)}, + {new Item(14631), new Item(14634)}, + {new Item(14631), new Item(14635)} + }, + "To start marking off tasks in your journal, speak to

any seer in Seers' Village, Stankers by the coal

trucks or Sir Kay in Camelot.", // todo made up, can't find source + // Seer, Stankers, Sir Kay + new int[]{388, 383, 241} + /** + * Secondary Rewards + * Easy + * - 30 flax a day from Flax (Geoffrey) + * Medium + * - 60 flax a day from Geoffrey + * - 10% more experience cutting maples while wearing Seer's Headband + * - Extra log given when cutting normal trees in Seer's Village + * Hard ( see https://www.youtube.com/watch?v=64tRpc6oASM ) + * - 120 flax a day from Geoffrey + * - Significant increase in speed spinning wheel in Seer's village + * - Enhanced Excalibur - lady of the lake + */ + ); + + /** + * The name of the diary. + */ + private final String name; + + /** + * The child id. + */ + private final int child; + + /** + * Level names + */ + private final String[] levelNames; + + /** + * The achievement descriptions. + */ + private final String[][] achievements; + + /** + * The item rewards. + */ + private final Item[][] rewards; + + /** + * The info to start the diary. + */ + private final String info; + + /** + * The npcs for the task levels. + */ + private final int[] npcs; + + /** + * Constructs a new {@code DiaryType} {@code Object} + * + * @param name the name of the diary. + * @param child the child id. + * @param achievements the achievements. + * @param rewards the rewards. + * @param info the info about the diary. + * @param npcs the npcs for the task levels. + */ + DiaryType(String name, int child, String[] levelNames, String[][] achievements, Item[][] rewards, String info, int[] npcs) { + this.name = name; + this.child = child; + this.levelNames = levelNames; + this.achievements = achievements; + this.rewards = rewards; + this.info = info; + this.npcs = npcs; + } + + /** + * Gets the diary type for the child id. + * + * @param child the child. + * @return the diary type. + */ + public static DiaryType forChild(int child) { + for (DiaryType type : values()) { + for (int i = 0; i < 4; i++) { + if (child == type.getChild() + i) { + return type; + } + } + } + return null; + } + + /** + * Gets the npc for the level. + * + * @param level the level. + * @return the npc id. + */ + public int getNpc(int level) { + return npcs[level]; + } + + public boolean hasRewardEquipment(Player player) { + for(Item[] tier : getRewards()) { + for(Item item : tier) { + if(!item.getName().toLowerCase().contains("lamp") && player.hasItem(item)) return true; + } + } + return false; + } + + /** + * Gets the rewards for the task level. + * + * @param level the level. + * @return the rewards. + */ + public Item[] getRewards(int level) { + return rewards[level]; + } + + /** + * Gets the achievements for the task level. + * + * @param level the level. + * @return the achievements. + */ + public String[] getAchievements(int level) { + return achievements[level]; + } + + /** + * Gets the achievements. + * + * @return the achievements + */ + public String[][] getAchievements() { + return achievements; + } + + /** + * Gets the rewards. + * + * @return the rewards + */ + public Item[][] getRewards() { + return rewards; + } + + /** + * Gets the name. + * + * @return the name + */ + public String getName() { + return name; + } + + /** + * Get the level names + * + * @return the level names + */ + public String[] getLevelNames() { + return levelNames; + } + + /** + * Gets the info. + * + * @return the info + */ + public String getInfo() { + return info; + } + + /** + * Gets the child. + * + * @return the child + */ + public int getChild() { + return child; + } + + /** + * Gets the npcs. + * + * @return the npcs + */ + public int[] getNpcs() { + return npcs; + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/player/link/emote/EmoteManager.java b/Server/src/main/core/game/node/entity/player/link/emote/EmoteManager.java new file mode 100644 index 0000000..e9c991d --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/emote/EmoteManager.java @@ -0,0 +1,182 @@ +package core.game.node.entity.player.link.emote; + +import core.game.node.entity.player.Player; + + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.List; + +import static core.api.ContentAPIKt.setVarp; + +/** + * Manages the players unlocked/locked emotes. + * @author Vexia + * + */ +public class EmoteManager { + + /** + * The list of unlocked emotes. + */ + private final List emotes = new ArrayList<>(20); + + /** + * The player. + */ + private final Player player; + + /** + * Constructs a new {@Code EmoteManager} {@Code Object} + * @param player the player. + */ + public EmoteManager(Player player) { + this.player = player; + for (int i = 0; i < 22; i++) { + emotes.add(Emotes.values()[i]); + } + } + + /** + * Refreshes the emote tab. + */ + public void refresh() { + int value1 = 0; + if (isUnlocked(Emotes.IDEA)) { + value1 += 4; + } + if (isUnlocked(Emotes.FLAP)) { + value1 += 1; + } + if (isUnlocked(Emotes.STOMP)) { + value1 += 8; + } + if (isUnlocked(Emotes.SLAP_HEAD)) { + value1 += 2; + } + setVarp(player, 802, value1, false); + int value2 = 0; + if (isUnlocked(Emotes.GLASS_BOX)) { + value2 += 2; + } + if (isUnlocked(Emotes.CLIMB_ROPE)) { + value2 += 4; + } + if (isUnlocked(Emotes.LEAN)) { + value2 += 8; + } + if (isUnlocked(Emotes.GLASS_WALL)) { + value2 += 1; + } + if (isUnlocked(Emotes.SCARED)) { + value2 += 16; + } + if (isUnlocked(Emotes.ZOMBIE_DANCE)) { + value2 += 32; + } + if (isUnlocked(Emotes.ZOMBIE_WALK)) { + value2 += 64; + } + if (isUnlocked(Emotes.BUNNY_HOP)) { + value2 += 128; + } + if (!isUnlocked(Emotes.SKILLCAPE)) { + unlock(Emotes.SKILLCAPE); + } + value2 += 256; + if (isUnlocked(Emotes.SNOWMAN_DANCE)) { + value2 += 512; + } + if (isUnlocked(Emotes.AIR_GUITAR)) { + value2 += 1024; + } + if (isUnlocked(Emotes.SAFETY_FIRST)) { + value2 += 2048; + } + if (isUnlocked(Emotes.TRICK)) { + value2 += 8192; + } + if (isUnlocked(Emotes.EXPLORE)) { + value2 += 4096; + } + if (isUnlocked(Emotes.FREEZE)) { + value2 += 32768; + } + if (isUnlocked(Emotes.GIVE_THANKS)) { + value2 += 16384; + } + setVarp(player, 313, value2, false); + int value3 = 0; + if (isUnlocked(Emotes.ZOMBIE_HAND)) { + value3 = 12; + } + setVarp(player, 1085, value3, false); + } + + /** + * Locks an emote. + * @param emote the emote. + * @return {@code True} if locked. + */ + public boolean lock(Emotes emote) { + if (emote.ordinal() <= 22) { + return false; + } + boolean locked = emotes.remove(emote); + refresh(); + return locked; + } + + /** + * Unlocks an emote. + * @param emote the emote. + * @return {@code True} if unlocked. + */ + public boolean unlock(Emotes emote) { + if (emotes.contains(emote)) { + return true; + } + boolean unlocked = emotes.add(emote); + refresh(); + return unlocked; + } + + /** + * Checks if an emote is unlocked. + * @param emote the emote. + * @return {@code True} if so. + */ + public boolean isUnlocked(Emotes emote) { + return emotes.contains(emote); + } + + /** + * Checks if a save is required. + * @return {@code True} if so. + */ + public boolean isSaveRequired() { + for (Emotes emote : emotes) { + if (emote.ordinal() > 21) { + return true; + } + } + return false; + } + + /** + * Gets the emotes. + * @return the emotes. + */ + public List getEmotes() { + return emotes; + } + + /** + * Gets the player. + * @return the player. + */ + public Player getPlayer() { + return player; + } + +} diff --git a/Server/src/main/core/game/node/entity/player/link/emote/Emotes.java b/Server/src/main/core/game/node/entity/player/link/emote/Emotes.java new file mode 100644 index 0000000..00f2819 --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/emote/Emotes.java @@ -0,0 +1,425 @@ +package core.game.node.entity.player.link.emote; + +import content.data.Quests; +import core.game.container.impl.EquipmentContainer; +import core.game.node.entity.player.info.Rights; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import org.rs09.consts.Items; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; + +import static core.api.ContentAPIKt.playJingle; +/** + * Represents an emote. + * + * @author Vexia + + */ +public enum Emotes { + YES(2, Animation.create(855)), + NO(3, Animation.create(856)), + BOW(4, Animation.create(858)) { + @Override + public void play(Player player) { + Item legs = player.getEquipment().get(EquipmentContainer.SLOT_LEGS); + if (legs != null && legs.getId() == 10396) { + forceEmote(player, Animation.create(5312), null); + return; + } + super.play(player); + } + }, + ANGRY(5, Animation.create(859)) { + @Override + public void play(Player player) { + Item hat = player.getEquipment().get(EquipmentContainer.SLOT_HAT); + if (hat != null && hat.getId() == 10392) { + forceEmote(player, Animation.create(5315), null); + return; + } + super.play(player); + } + }, + THINK(6, Animation.create(857)), + WAVE(7, Animation.create(863)), + SHRUG(8, Animation.create(2113)), + CHEER(9, Animation.create(862)), + BECKON(10, Animation.create(864)), + //Switch laugh id 11, to 12, and switch Jump id 12 to 11. Id's were mismatched. + //This caused the LAUGH to proc JUMP_FOR_JOY and JUMP_FOR_JOY to proc LAUGH! :) + JUMP_FOR_JOY(11, Animation.create(2109)), + LAUGH(12, Animation.create(861)), + YAWN(13, Animation.create(2111)) { + @Override + public void play(Player player) { + Item hat = player.getEquipment().get(EquipmentContainer.SLOT_HAT); + if (hat != null && hat.getId() == 10398) { + forceEmote(player, Animation.create(5313), null); + return; + } + super.play(player); + } + }, + DANCE(14, Animation.create(866)) { + @Override + public void play(Player player) { + Item legs = player.getEquipment().get(EquipmentContainer.SLOT_LEGS); + if (legs != null && legs.getId() == 10394) { + forceEmote(player, Animation.create(5316), null); + return; + } + super.play(player); + } + }, + JIG(15, Animation.create(2106)), + SPIN(16, Animation.create(2107)), + HEADBANG(17, Animation.create(2108)), + CRY(18, Animation.create(860)), + BLOW_KISS(19, Animation.create(1368), Graphics.create(574)), + PANIC(20, Animation.create(2105)), + RASPBERRY(21, Animation.create(2110)), + CLAP(22, Animation.create(865)), + SALUTE(23, Animation.create(2112)) { + @Override + public void play(Player player) { + if (!player.getAchievementDiaryManager().hasCompletedTask(DiaryType.FALADOR, 1, 8) && + player.getLocation().equals(new Location(2997, 3374, 0)) && + player.getDirection() == Direction.SOUTH && + player.getEquipment().get(EquipmentContainer.SLOT_HAT).getId() == Items.INITIATE_SALLET_5574 && + player.getEquipment().get(EquipmentContainer.SLOT_CHEST).getId() == Items.INITIATE_HAUBERK_5575 && + player.getEquipment().get(EquipmentContainer.SLOT_LEGS).getId() == Items.INITIATE_CUISSE_5576) { + forceEmote(player, Animation.create(2112), null); + player.getAchievementDiaryManager().finishTask(player, DiaryType.FALADOR, 1, 8); + return; + } + super.play(player); + } + }, + GOBLIN_BOW(24, Animation.create(2127), "This emote can be unlocked during the Lost Tribe quest.") { + @Override + public void play(Player player) { + if(player.getLocation().getRegionId() == 13206 && !player.getAttribute("mistag-greeted", false)) { + RegionManager.getLocalNpcs(player).forEach(npc -> { + if (npc.getId() == 2084 && npc.getLocation().withinDistance(player.getLocation(), 3) && player.getQuestRepository().getQuest(Quests.THE_LOST_TRIBE).getStage(player) == 45) { + player.getDialogueInterpreter().open(2084,npc,"greeting"); + player.setAttribute("/save:mistag-greeted",true); + } + }); + } + super.play(player); + } + }, + GOBLIN_SALUTE(25, Animation.create(2128), "This emote can be unlocked during the Lost Tribe quest."), + GLASS_BOX(26, Animation.create(1131), "This emote can be unlocked during the Mime random event."), + CLIMB_ROPE(27, Animation.create(1130), "This emote can be unlocked during the Mime random event."), + LEAN(28, Animation.create(1129), "This emote can be unlocked during the Mime random event."), + GLASS_WALL(29, Animation.create(1128), "This emote can be unlocked during the Mime random event."), + IDEA(33, Animation.create(4276), Graphics.create(712), "You can't use this emote yet.
Visit the Stronghold of Security to unlock it."), + STOMP(31, Animation.create(4278), "You can't use this emote yet.
Visit the Stronghold of Security to unlock it."), + FLAP(32, Animation.create(4280), "You can't use this emote yet.
Visit the Strongshold of Security to unlock it.") { + @Override + public void play(Player player) { + Item head = player.getEquipment().get(EquipmentContainer.SLOT_HAT); + Item wings = player.getEquipment().get(EquipmentContainer.SLOT_CHEST); + Item legs = player.getEquipment().get(EquipmentContainer.SLOT_LEGS); + Item feet = player.getEquipment().get(EquipmentContainer.SLOT_FEET); + if (head != null && wings != null && legs != null && feet != null) { + if (head.getId() == 11021 && wings.getId() == 11020 && legs.getId() == 11022 && feet.getId() == 11019) { + forceEmote(player, Animation.create(3859), null); + return; + } + } + super.play(player); + } + }, + SLAP_HEAD(30, Animation.create(4275), "You can't use this emote yet.
Visit the Stronghold of Security to unlock it."), + ZOMBIE_WALK(34, Animation.create(3544), "This emote can be unlocked during the Gravedigger random event."), + ZOMBIE_DANCE(35, Animation.create(3543), "This emote can be unlocked during the Gravedigger random event."), + ZOMBIE_HAND(36, Animation.create(7272), Graphics.create(1244), "This emote can be unlocked during the Gravedigger random event."), + SCARED(37, Animation.create(2836), "This emote can be unlocked by playing a Halloween holiday event."), + BUNNY_HOP(38, Animation.create(6111), "This emote can be unlocked by playing an Easter holiday event."), + SKILLCAPE(39) { + @Override + public void play(Player player) { + Item cape = player.getEquipment().get(EquipmentContainer.SLOT_CAPE); + if (cape == null) { + player.getPacketDispatch().sendMessage("You need to be wearing a skillcape in order to perform this emote."); + return; + } + int capeId = cape.getId(); + for (int i = 0; i < SKILLCAPE_INFO.length; i++) { + if (capeId == SKILLCAPE_INFO[i][0] || capeId == SKILLCAPE_INFO[i][1]) { + player.getPacketDispatch().sendGraphic(SKILLCAPE_INFO[i][2]); + player.getPacketDispatch().sendAnimation(SKILLCAPE_INFO[i][3]); + int duration = Animation.create(SKILLCAPE_INFO[i][3]).getDuration(); + player.getLocks().lock("emote", duration); + player.getLocks().lock(duration); + return; + } + } + player.getPacketDispatch().sendMessage("You need to be wearing a skillcape in order to perform this emote."); + } + }, + SNOWMAN_DANCE(40, Animation.create(7531), "This emote can be unlocked by playing a Christmas holiday event."), + AIR_GUITAR(41, Animation.create(2414), Graphics.create(1537), "This emote can be accessed by unlocking 200 pieces of music.") { + public void play(Player player) { + playJingle(player, 302); + super.play(player); + } + }, + SAFETY_FIRST(42, Animation.create(8770), Graphics.create(1553), "You can't use this emote yet. Visit the Stronghold of Player safety to
unlock it."), + EXPLORE(43, Animation.create(9990), Graphics.create(1734), "You can't use this emote yet. You must complete all the Lumbridge
and Draynor beginner tasks to unlock it."), + TRICK(44, Animation.create(10530), Graphics.create(1863), "This emote can be unlocked by playing a Halloween holiday event."), + FREEZE(45, Animation.create(11044), Graphics.create(1973), "This emote can be unlocked by playing a Christmas holiday event."), + GIVE_THANKS(46, "This emote can be unlocked by playing a Thanksgiving holiday event.") { + @Override + public void play(final Player player) { + GameWorld.getPulser().submit(new Pulse(1, player) { + int counter; + + @Override + public boolean pulse() { + switch (counter++) { + case 1: + player.lock(17); + forceEmote(player, Animation.create(10994), Graphics.create(86)); + break; + case 3: + player.getAppearance().transformNPC(8499); + forceEmote(player, Animation.create(10996), null); + break; + case 16: + player.getAppearance().transformNPC(-1); + forceEmote(player, Animation.create(10995), Graphics.create(86)); + break; + } + return false; + } + }); + } + }; + + /** + * Represents the skillcape info. + */ + private static final int[][] SKILLCAPE_INFO = {{9747, 9748, 823, 4959}, {9750, 9751, 828, 4981}, {9753, 9754, 824, 4961}, {9756, 9757, 832, 4973}, {9759, 9760, 829, 4979}, {9762, 9763, 813, 4939}, {9765, 9766, 817, 4947}, {9768, 9769, 833, 4971}, {9771, 9772, 830, 4977}, {9774, 9775, 835, 4969}, {9777, 9778, 826, 4965}, {9780, 9781, 818, 4949}, {9783, 9784, 812, 4937}, {9786, 9787, 1656, 4967}, {9789, 9790, 820, 4953}, {9792, 9793, 814, 4941}, {9795, 9796, 815, 4943}, {9798, 9799, 819, 4951}, {9801, 9802, 821, 4955}, {9804, 9805, 831, 4975}, {9807, 9808, 822, 4957}, {9810, 9811, 825, 4963}, {12169, 12170, 1515, 8525}, {9813, -1, 816, 4945}, {9948, 9949, 907, 5158}}; + + /** + * The button id. + */ + private final int buttonId; + + /** + * The animation. + */ + private final Animation animation; + + /** + * The graphics to play. + */ + private final Graphics graphics; + + /** + * The message to show when the emote is locked. + */ + private final String lockedMessage; + + /** + * Constructs a new {@Code Emotes} {@Code Object} + * + * @param buttonId the button id. + * @param animation the animation. + * @param graphics the graphics. + * @param lockedMessage the locked message. + */ + Emotes(int buttonId, Animation animation, Graphics graphics, String lockedMessage) { + this.buttonId = buttonId; + this.animation = animation; + this.graphics = graphics; + this.lockedMessage = lockedMessage; + } + + /** + * Constructs a new {@Code Emotes} {@Code Object} + * + * @param buttonId the button id. + */ + Emotes(int buttonId) { + this(buttonId, null, null, null); + } + + /** + * Constructs a new {@Code Emotes} {@Code Object} + * + * @param buttonId the button id. + * @param animation the animation. + */ + Emotes(int buttonId, Animation animation) { + this(buttonId, animation, null, null); + } + + /** + * Constructs a new {@Code Emotes} {@Code Object} + * + * @param buttonId the button id. + * @param animation the animation. + * @param graphics the graphics. + */ + Emotes(int buttonId, Animation animation, Graphics graphics) { + this(buttonId, animation, graphics, null); + } + + /** + * Constructs a new {@Code Emotes} {@Code Object} + * + * @param buttonId the button id. + * @param animation the animation. + * @param lockedMessage the locked message. + */ + Emotes(int buttonId, Animation animation, String lockedMessage) { + this(buttonId, animation, null, lockedMessage); + } + + /** + * Constructs a new {@Code Emotes} {@Code Object} + * + * @param buttonId the button id. + * @param lockedMessage the locked message. + */ + Emotes(int buttonId, String lockedMessage) { + this(buttonId, null, null, lockedMessage); + } + + /** + * Handles the reward button for an emote. + * + * @param player the player. + * @param buttonId the button id. + */ + public static void handle(Player player, int buttonId) { + if (player.getLocks().isLocked("emote")) { + player.getPacketDispatch().sendMessage("You're already doing an emote!"); + return; + } + if (player.getProperties().getCombatPulse().isAttacking() || player.inCombat()) { + player.getPacketDispatch().sendMessage("You can't perform an emote while being in combat."); + return; + } + Emotes emote = Emotes.forId(buttonId); + if (emote == null) { + player.debug("Unhandled emote for button id - " + buttonId); + return; + } + if (!player.getEmoteManager().isUnlocked(emote)) { + if(player.getRights().equals(Rights.ADMINISTRATOR)){ + player.getEmoteManager().unlock(emote); + player.getPulseManager().clear(); + emote.play(player); + return; + } + String message = emote.getLockedMessage(); + if (message == null) { + message = "You can't use this emote."; + } + player.getDialogueInterpreter().sendDialogue(message); + return; + } + if (!player.getAchievementDiaryManager().getDiary(DiaryType.VARROCK).isComplete(1, 6) && (buttonId >= 30 && buttonId <= 33)) { + if (!player.getAttribute("emote-" + buttonId, false)) { + player.setAttribute("emote-" + buttonId, true); + } + boolean good = true; + for (int i = 30; i <= 33; i++) { + if (!player.getAttribute("emote-" + i, false)) { + good = false; + break; + } + } + player.getAchievementDiaryManager().getDiary(DiaryType.VARROCK).updateTask(player, 1, 6, good); + } + player.getPulseManager().clear(); + emote.play(player); + } + + /** + * Plays the emote. + * + * @param player the player. + */ + public void play(Player player) { + forceEmote(player, animation, graphics); + } + + /** + * Forces the animation to be played. + * + * @param player the player. + * @param animation the animation. + * @param graphic the graphic. + */ + private static void forceEmote(Player player, Animation animation, Graphics graphic) { + if (animation != null) { + player.getAnimator().animate(animation, graphic); + player.getLocks().lock("emote", animation.getDuration()); + } + } + + /** + * Gets the emote for the button id. + * + * @param buttonId the button id. + * @return the emote type. + */ + public static Emotes forId(int buttonId) { + for (Emotes emote : values()) { + if (emote.getButtonId() == buttonId) { + return emote; + } + } + return null; + } + + /** + * Gets the buttonId. + * + * @return the buttonId. + */ + public int getButtonId() { + return buttonId; + } + + /** + * Gets the animation. + * + * @return the animation. + */ + public Animation getAnimation() { + return animation; + } + + /** + * Gets the graphics. + * + * @return the graphics. + */ + public Graphics getGraphics() { + return graphics; + } + + /** + * Gets the lockedMessage. + * + * @return the lockedMessage. + */ + public String getLockedMessage() { + return lockedMessage; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/player/link/music/MusicEntry.java b/Server/src/main/core/game/node/entity/player/link/music/MusicEntry.java new file mode 100644 index 0000000..2088f2b --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/music/MusicEntry.java @@ -0,0 +1,84 @@ +package core.game.node.entity.player.link.music; + +import java.util.HashMap; +import java.util.Map; + +/** + * Represents a song. + * @author Emperor + */ +public final class MusicEntry { + + /** + * The songs mapping. + */ + private static final Map SONGS = new HashMap<>(); + + /** + * The music id. + */ + private final int id; + + /** + * The song name. + */ + private final String name; + + /** + * The index in the list. + */ + private final int index; + + /** + * Constructs a new {@code MusicEntry} {@code Object}. + * @param id the music id. + * @param name The name. + * @param index The list index. + */ + public MusicEntry(int id, String name, int index) { + this.id = id; + this.name = name; + this.index = index; + } + + /** + * Gets the song for the given music id. + * @param id The music id. + * @return The song. + */ + public static MusicEntry forId(int id) { + return SONGS.get(id); + } + + /** + * Gets the id. + * @return The id. + */ + public int getId() { + return id; + } + + /** + * Gets the name. + * @return The name. + */ + public String getName() { + return name; + } + + /** + * Gets the index. + * @return The index. + */ + public int getIndex() { + return index; + } + + /** + * Gets the songs. + * @return The songs. + */ + public static Map getSongs() { + return SONGS; + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/player/link/music/MusicPlayer.java b/Server/src/main/core/game/node/entity/player/link/music/MusicPlayer.java new file mode 100644 index 0000000..163cdad --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/music/MusicPlayer.java @@ -0,0 +1,302 @@ +package core.game.node.entity.player.link.music; + +import core.game.node.entity.player.Player; + +import core.game.node.entity.player.link.emote.Emotes; +import core.game.world.GameWorld; +import core.net.packet.PacketRepository; +import core.net.packet.context.MusicContext; +import core.net.packet.context.StringContext; +import core.net.packet.out.MusicPacket; +import core.net.packet.out.StringPacket; + +import java.util.*; + +import static core.api.ContentAPIKt.*; + + +/** + * Handles a music playing for a player. + * @author Emperor + */ +public final class MusicPlayer { + + /** + * The tutorial island music. + */ + public static final int TUTORIAL_MUSIC = 62; + + /** + * The default music id. + */ + public static final int DEFAULT_MUSIC_ID = 76; + + /** + * The configuration ids. + */ + private static final int[] CONFIG_IDS = { 20, 21, 22, 23, 24, 25, 298, 311, 346, 414, 464, 598, 662, 721, 906, 1009, 1104, 1136, 1180, 1202}; + + /** + * The player. + */ + private final Player player; + + /** + * The currently unlocked songs. + */ + private final Map unlocked; + + /** + * The music id of the currently played song. + */ + private int currentMusicId; + + /** + * If a song is currently playing. + */ + private boolean playing; + + /** + * If the song is looping. + */ + private boolean looping; + + /** + * Constructs a new {@code MusicPlayer} {@code Object}. + * @param player The player. + */ + public MusicPlayer(Player player) { + this.player = player; + this.unlocked = new HashMap<>(); + } + + /** + * Initializes the music player. + */ + public void init() { + refreshList(); + setVarp(player, 19, looping ? 1 : 0); + int value = 0; + for (int i = 0; i < CONFIG_IDS.length; i++) { + value |= 2 << i; + } + player.getPacketDispatch().sendIfaceSettings(value, 1, 187, 0, CONFIG_IDS.length * 64); + if (!unlocked.containsKey(TUTORIAL_MUSIC)) { + unlock(TUTORIAL_MUSIC, false); + } + if (!isMusicPlaying()) { + playDefault(); + } + if (!hasAirGuitar() && player.getEmoteManager().isUnlocked(Emotes.AIR_GUITAR)) { + player.getPacketDispatch().sendMessage("As you no longer have all music unlocked, the Air Guitar emote is locked again."); + player.getEmoteManager().lock(Emotes.AIR_GUITAR); + } + } + + /** + * Clears the unlocked songs. This should only be used in the permadeath code. + */ + public void clearUnlocked() { + this.unlocked.clear(); + } + + /** + * Checks if the player has enough songs unlocked for the Air guitar emote. + * @return {@code True} if so. + */ + public boolean hasAirGuitar() { + return unlocked.size() >= 200 || unlocked.size() == MusicEntry.getSongs().size(); + } + + /** + * Checks if the player has unlocked the song. + * @param musicId The music id. + * @return {@code True} if so. + */ + public boolean hasUnlocked(int musicId) { + MusicEntry entry = MusicEntry.forId(musicId); + if (entry == null) { + return false; + } + return hasUnlockedIndex(entry.getIndex()); + } + + /** + * Checks if the player has unlocked the song for the given list index. + * @param index The list index. + * @return {@code True} if so. + */ + public boolean hasUnlockedIndex(int index) { + return unlocked.containsKey(index); + } + + /** + * Refreshes the music list. + */ + public void refreshList() { + int[] values = new int[CONFIG_IDS.length]; + for (MusicEntry entry : unlocked.values()) { + int listIndex = entry.getIndex(); + int index = listIndex / 32; + if (index >= CONFIG_IDS.length) { + continue; + } + values[index] |= 1 << (listIndex & 31); + } + for (int i = 0; i < CONFIG_IDS.length; i++) { + setVarp(player, CONFIG_IDS[i], values[i]); + } + } + + /** + * Called when a player leaves a music zone without entering a new one. + */ + public void playDefault() { + MusicEntry entry = MusicEntry.forId(DEFAULT_MUSIC_ID); + if (entry != null) { + play(entry); + } + } + + /** + * Replays the song. + */ + public void replay() { + MusicEntry entry = MusicEntry.forId(currentMusicId); + if (entry != null) { + play(entry); + } + } + + /** + * Plays the song. + * @param entry The song. + */ + public void play(MusicEntry entry) { + if (!looping || currentMusicId == entry.getId()) { + PacketRepository.send(MusicPacket.class, new MusicContext(player, entry.getId())); + PacketRepository.send(StringPacket.class, new StringContext(player, entry.getName() + (player.isDebug() ? (" (" + entry.getId() + ")") : ""), 187, 14)); + currentMusicId = entry.getId(); + playing = true; + } + } + + /** + * Unlocks and plays the music id. + * @param id The music id to unlock. + */ + public void unlock(int id) { + unlock(id, true); + } + + /** + * Unlocks the music id. + * @param id The music id to unlock. + * @param play If the song should be played. + */ + public void unlock(int id, boolean play) { + MusicEntry entry = MusicEntry.forId(id); + if (entry == null) { + return; + } + if (!entry.getName().equals(" ") && !unlocked.containsKey(entry.getIndex())) { + unlocked.put(entry.getIndex(), entry); + player.getPacketDispatch().sendMessage("You have unlocked a new music track: " + entry.getName() + "."); + refreshList(); + if (!player.getEmoteManager().isUnlocked(Emotes.AIR_GUITAR) && hasAirGuitar()) { + player.getEmoteManager().unlock(Emotes.AIR_GUITAR); + if (unlocked.size() >= 200) { + player.getPacketDispatch().sendMessage("You've unlocked 200 music tracks and can use a new emote!"); + } else { + player.getPacketDispatch().sendMessage("You've unlocked all music tracks and can use a new emote!"); + } + } + } + if (play) { + play(entry); + } + } + + public void tick(){ + if(GameWorld.getTicks() % 20 == 0){ + if(!isPlaying()){ + try { + PacketRepository.send(MusicPacket.class, new MusicContext(player, currentMusicId)); + } catch (Exception e){} + } + } + } + + /** + * Toggles the looping option. + */ + public void toggleLooping() { + looping = !looping; + setVarp(player, 19, looping ? 1 : 0); + } + + /** + * If music is currently playing. + * @return {@code True} if so. + */ + private boolean isMusicPlaying() { + return currentMusicId > 0 && playing; + } + + /** + * Gets the unlocked songs list. + * @return The unlocked. + */ + public Map getUnlocked() { + return unlocked; + } + + /** + * Gets the currentMusicId. + * @return The currentMusicId. + */ + public int getCurrentMusicId() { + return currentMusicId; + } + + /** + * Sets the currentMusicId. + * @param currentMusicId The currentMusicId to set. + */ + public void setCurrentMusicId(int currentMusicId) { + this.currentMusicId = currentMusicId; + } + + /** + * Gets the playing. + * @return The playing. + */ + public boolean isPlaying() { + return playing; + } + + /** + * Sets the playing. + * @param playing The playing to set. + */ + public void setPlaying(boolean playing) { + this.playing = playing; + } + + /** + * Gets the looping. + * @return The looping. + */ + public boolean isLooping() { + return looping; + } + + /** + * Sets the looping. + * @param looping The looping to set. + */ + public void setLooping(boolean looping) { + this.looping = looping; + setVarp(player, 19, looping ? 1 : 0); + } +} diff --git a/Server/src/main/core/game/node/entity/player/link/music/MusicZone.java b/Server/src/main/core/game/node/entity/player/link/music/MusicZone.java new file mode 100644 index 0000000..1bf82af --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/music/MusicZone.java @@ -0,0 +1,64 @@ +package core.game.node.entity.player.link.music; + +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.world.map.zone.Zone; +import core.game.world.map.zone.ZoneBorders; + +/** + * Represents a music zone. + * @author Emperor + */ +public final class MusicZone implements Zone { + + /** + * The music id. + */ + private final int musicId; + + /** + * The zone borders. + */ + private final ZoneBorders borders; + + /** + * Constructs a new {@code MusicZone} {@code Object}. + * @param musicId The music id. + */ + public MusicZone(int musicId, ZoneBorders borders) { + this.musicId = musicId; + this.borders = borders; + } + + @Override + public boolean enter(Entity e) { + if (!(e instanceof Player)) { + throw new IllegalStateException("Music is for players only!"); + } + Player player = (Player) e; + player.getMusicPlayer().unlock(musicId); + return true; + } + + @Override + public boolean leave(Entity e, boolean logout) { + return true; + } + + /** + * Gets the musicId. + * @return The musicId. + */ + public int getMusicId() { + return musicId; + } + + /** + * Gets the borders. + * @return The borders. + */ + public ZoneBorders getBorders() { + return borders; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/player/link/prayer/Prayer.java b/Server/src/main/core/game/node/entity/player/link/prayer/Prayer.java new file mode 100644 index 0000000..8dcdf82 --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/prayer/Prayer.java @@ -0,0 +1,210 @@ +package core.game.node.entity.player.link.prayer; + +import content.global.skill.skillcapeperks.SkillcapePerks; +import core.game.node.entity.skill.SkillBonus; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.ImpactHandler.HitsplatType; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.context.Graphics; +import core.tools.RandomFunction; +import core.game.event.*; +import core.game.world.GameWorld; +import org.rs09.consts.Sounds; + +import java.util.ArrayList; +import java.util.List; + +import static core.api.ContentAPIKt.*; + +/** + * Represents a managing class of a players prayers. + * @author Vexia + * @author Emperor + */ +public final class Prayer { + + /** + * Represents the list of active prayers. + */ + private final List active = new ArrayList<>(20); + + /** + * Represents the player instance. + */ + private final Player player; + + private int prayerActiveTicks = 0; + + /** + * Constructs a new {@code Prayer} {@code Object}. + */ + public Prayer(Player player) { + this.player = player; + } + + /** + * Method used to toggle a prayer. + * @param type the type of prayer. + */ + public final boolean toggle(final PrayerType type) { + if (!permitted(type)) { + return false; + } + return type.toggle(player, !active.contains(type)); + } + + /** + * Method used to reset this prayer managers cached prayers. + */ + public void reset() { + // Immediately clear the lights on the client interface and terminate any bonuses + for (PrayerType type : getActive()) { + setVarp(player, type.getConfig(), 0, false); + player.dispatch(new PrayerDeactivatedEvent(type)); + } + getActive().clear(); + // Clear the overhead prayer icon a tick later + GameWorld.getPulser().submit(new Pulse(1) { + @Override + public boolean pulse() { + player.getAppearance().setHeadIcon(-1); + player.getAppearance().sync(); + return true; + } + }); + } + + /** + * Starts the redemption effect. + */ + public void startRedemption() { + playAudio(player, Sounds.REDEMPTION_HEAL_2681); + player.graphics(Graphics.create(436)); + player.getSkills().heal((int) (player.getSkills().getStaticLevel(Skills.PRAYER) * 0.25)); + player.getSkills().setPrayerPoints(0.0); + reset(); + } + + /** + * Starts the retribution effect. + * @param killer The entity who killed this player. + */ + public void startRetribution(Entity killer) { + Location l = player.getLocation(); + for (int x = -1; x < 2; x++) { + for (int y = -1; y < 2; y++) { + if (x != 0 || y != 0) { + Projectile.create(l, l.transform(x, y, 0), 438, 0, 0, 10, 20, 0, 11).send(); + } + } + } + playAudio(player, Sounds.FIREBREATH_159); + player.graphics(Graphics.create(437)); + int maximum = (int) (player.getSkills().getStaticLevel(Skills.PRAYER) * 0.25) - 1; + if (killer != player && killer.getLocation().withinDistance(player.getLocation(), 1)) { + killer.getImpactHandler().manualHit(player, 1 + RandomFunction.randomize(maximum), HitsplatType.NORMAL); + } + if (player.getProperties().isMultiZone()) { + @SuppressWarnings("rawtypes") + List targets = null; + if (killer instanceof NPC) { + targets = RegionManager.getSurroundingNPCs(player, player, killer); + } else { + targets = RegionManager.getSurroundingPlayers(player, player, killer); + } + for (Object o : targets) { + Entity entity = (Entity) o; + if (entity.isAttackable(player, CombatStyle.MAGIC, false)) { + entity.getImpactHandler().manualHit(player, 1 + RandomFunction.randomize(maximum), HitsplatType.NORMAL); + } + } + } + } + + public void tick() { + if(!getActive().isEmpty()) prayerActiveTicks ++; + else prayerActiveTicks = 0; + + if(prayerActiveTicks > 0 && prayerActiveTicks % 2 == 0){ + if(getPlayer().getSkills().getPrayerPoints() == 0){ + playAudio(getPlayer(), Sounds.PRAYER_DRAIN_2672); + getPlayer().sendMessage("You have run out of prayer points; you must recharge at an altar."); + reset(); + return; + } + double amountDrain = 0; + for(PrayerType type : getActive()){ + double drain = type.getDrain(); + double bonus = (1/30f) * getPlayer().getProperties().getBonuses()[12]; + drain = drain * (1 + bonus); + drain = 0.6 / drain; + amountDrain += drain; + } + if(SkillcapePerks.isActive(SkillcapePerks.DIVINE_FAVOR, getPlayer()) && RandomFunction.random(100) <= 10){ + amountDrain = 0; + } + + getPlayer().getSkills().decrementPrayerPoints(amountDrain); + } + } + + /** + * Gets the skill bonus for the given skill id. + * @param skillId The skill id. + * @return The bonus for the given skill. + */ + public double getSkillBonus(int skillId) { + double bonus = 0.0; + for (PrayerType type : active) { + for (SkillBonus b : type.getBonuses()) { + if (b.getSkillId() == skillId) { + bonus += b.getBonus(); + } + } + } + return bonus; + } + + /** + * Method used to check if we're permitted to toggle this prayer. + * @param type the type. + * @return True if permitted to be toggled. + */ + private boolean permitted(final PrayerType type) { + return player.getSkills().getPrayerPoints() > 0 && type.permitted(player); + } + + /** + * Method used to return value of {@code True} if the {@link #active} + * prayers contains the prayer type. + * @param type the type of prayer. + * @return {@code True} if so. + */ + public boolean get(PrayerType type) { + return active.contains(type); + } + + /** + * Gets the player. + * @return The player. + */ + public Player getPlayer() { + return player; + } + + /** + * Gets the active prayers. + * @return The active. + */ + public List getActive() { + return active; + } + +} diff --git a/Server/src/main/core/game/node/entity/player/link/prayer/PrayerCategory.java b/Server/src/main/core/game/node/entity/player/link/prayer/PrayerCategory.java new file mode 100644 index 0000000..9e45cfb --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/prayer/PrayerCategory.java @@ -0,0 +1,15 @@ +package core.game.node.entity.player.link.prayer; + +/** + * Players can also use some Prayers at the same time with others, though doing + * so will compound the drain rate of these Prayers. Some Prayers cannot be used + * simultaneously and are marked in the table with the same background colour. + * For example, activating the "Smite" Prayer while the Protect From + * Melee" Prayer is active will automatically deactivate "Protect from Melee" as + * they are incompatible Prayers. + * @author 'Vexia + * @date 06/11/2013 + */ +public enum PrayerCategory { + BABY_BLUE, GREEN, PINK, LIME_GREEN, ORANGE, PURPLE, DARK_GREEN, DARK_BROWN, LIGHT_BROWN, RED, MAGENTA; +} diff --git a/Server/src/main/core/game/node/entity/player/link/prayer/PrayerType.java b/Server/src/main/core/game/node/entity/player/link/prayer/PrayerType.java new file mode 100644 index 0000000..e8fba52 --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/prayer/PrayerType.java @@ -0,0 +1,439 @@ +package core.game.node.entity.player.link.prayer; + +import core.game.node.entity.player.link.diary.DiaryType; +import core.game.node.entity.skill.SkillBonus; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.audio.Audio; +import core.game.world.map.zone.ZoneBorders; +import core.tools.StringUtils; +import core.game.event.*; +import org.rs09.consts.Sounds; + +import java.util.List; + +import static core.api.ContentAPIKt.*; + + +/** + * Represents a prayer type. + * @author Vexia + * @author Emperor + * @author jamix77 + */ +public enum PrayerType { + THICK_SKIN(1, 12, 83, 5, PrayerCategory.BABY_BLUE, Sounds.THICK_SKIN_2690, new SkillBonus(Skills.DEFENCE, 0.05)), + BURST_OF_STRENGTH(4, 12, 84, 7, PrayerCategory.GREEN, Sounds.STRENGTH_BURST_2688, new SkillBonus(Skills.STRENGTH, 0.05)), + CLARITY_OF_THOUGHT(7, 12, 85, 9, PrayerCategory.PINK, Sounds.CLARITY_2664, new SkillBonus(Skills.ATTACK, 0.05)), + SHARP_EYE(8, 12, 862, 11, PrayerCategory.LIME_GREEN, Sounds.SHARP_EYE_2685, new SkillBonus(Skills.RANGE, 0.05)), + MYSTIC_WILL(9, 12, 863, 13, PrayerCategory.LIME_GREEN, Sounds.MYSTIC_WILL_2670, new SkillBonus(Skills.MAGIC, 0.05)), + ROCK_SKIN(10, 6, 86, 15, PrayerCategory.BABY_BLUE, Sounds.ROCK_SKIN_2684, new SkillBonus(Skills.DEFENCE, 0.1)), + SUPERHUMAN_STRENGTH(13, 6, 87, 17, PrayerCategory.GREEN, Sounds.SUPERHUMAN_STRENGTH_2689, new SkillBonus(Skills.STRENGTH, 0.1)), + IMPROVED_REFLEXES(16, 6, 88, 19, PrayerCategory.PINK, Sounds.IMPROVED_REFLEXES_2662, new SkillBonus(Skills.ATTACK, 0.1)), + RAPID_RESTORE(19, 26, 89, 21, PrayerCategory.PURPLE, Sounds.RAPID_RESTORE_2679), + RAPID_HEAL(22, 18, 90, 23, PrayerCategory.PURPLE, Sounds.RAPID_HEAL_2678), + PROTECT_ITEMS(25, 18, 91, 25, PrayerCategory.DARK_GREEN, Sounds.PROTECT_ITEMS_1982), + HAWK_EYE(26, 6, 864, 27, PrayerCategory.LIME_GREEN, Sounds.HAWK_EYE_2666, new SkillBonus(Skills.RANGE, 0.1)), + MYSTIC_LORE(27, 6, 865, 29, PrayerCategory.LIME_GREEN, Sounds.MYSTIC_2668, new SkillBonus(Skills.MAGIC, 0.1)), + STEEL_SKIN(28, 3, 92, 31, PrayerCategory.BABY_BLUE, Sounds.STEEL_SKIN_2687, new SkillBonus(Skills.DEFENCE, 0.15)), + ULTIMATE_STRENGTH(31, 3, 93, 33, PrayerCategory.GREEN, Sounds.ULTIMATE_STRENGTH_2691, new SkillBonus(Skills.STRENGTH, 0.15)), + INCREDIBLE_REFLEXES(34, 3, 94, 35, PrayerCategory.PINK, Sounds.INCREDIBLE_REFLEXES_2667, new SkillBonus(Skills.ATTACK, 0.15)), + PROTECT_FROM_SUMMONING(35, 2, 1168, 53, PrayerCategory.DARK_BROWN, PrayerCategory.MAGENTA, new Audio(4262)), + PROTECT_FROM_MAGIC(37, 3, 95, 37, PrayerCategory.LIGHT_BROWN, Sounds.PROTECT_FROM_MAGIC_2675), + PROTECT_FROM_MISSILES(40, 3, 96, 39, PrayerCategory.LIGHT_BROWN, Sounds.PROTECT_FROM_MISSILES_2677), + PROTECT_FROM_MELEE(43, 4, 97, 41, PrayerCategory.LIGHT_BROWN, Sounds.PROTECT_FROM_MELEE_2676), + EAGLE_EYE(44, 3, 866, 43, PrayerCategory.LIME_GREEN, Sounds.EAGLE_EYE_2665, new SkillBonus(Skills.RANGE, 0.15)), + MYSTIC_MIGHT(45, 3, 867, 45, PrayerCategory.LIME_GREEN, Sounds.MYSTIC_MIGHT_2669, new SkillBonus(Skills.MAGIC, 0.15)), + RETRIBUTION(46, 12, 98, 47, PrayerCategory.LIGHT_BROWN, PrayerCategory.MAGENTA, new Audio(2682)), + REDEMPTION(49, 6, 99, 49, PrayerCategory.LIGHT_BROWN, PrayerCategory.MAGENTA, new Audio(2680)), + SMITE(52, 2, 100, 51, PrayerCategory.LIGHT_BROWN, PrayerCategory.MAGENTA, new Audio(2686)), + CHIVALRY(60, 2, 1052, 55, PrayerCategory.PINK, Sounds.KR_CHIVALRY_3826, 65, new SkillBonus(Skills.DEFENCE, 0.2), new SkillBonus(Skills.STRENGTH, 0.18), new SkillBonus(Skills.ATTACK, 0.15)), + PIETY(70, 2, 1053, 57, PrayerCategory.PINK, Sounds.KR_PIETY_3825, 70, new SkillBonus(Skills.DEFENCE, 0.25), new SkillBonus(Skills.STRENGTH, 0.23), new SkillBonus(Skills.ATTACK, 0.2)); + + /** + * Represents the a cache of objects related to prayers in order to decide + * what head icon to display. + */ + private final static Object[][] ICON_CACHE = new Object[][] { { REDEMPTION, 5 }, { RETRIBUTION, 3 }, { SMITE, 4 }, { PROTECT_FROM_MAGIC, 2, 10 }, { PROTECT_FROM_MELEE, 0, 8 }, { PROTECT_FROM_MISSILES, 1, 9 }, { PROTECT_FROM_SUMMONING, 7, PROTECT_FROM_MELEE, 8, PROTECT_FROM_MISSILES, 9, PROTECT_FROM_MAGIC, 10 } }; + + /** + * The level required. + */ + private final int level; + + /** + * The drain rate. + */ + private final int drain; + + /** + * The configuration id of the prayer. + */ + private final int config; + + /** + * The button id. + */ + private final int button; + + /** + * The restriction. + */ + private final PrayerCategory restriction; + + /** + * Represents the second restriction. + */ + private final PrayerCategory secondRestriction; + + /** + * The sound. + */ + private Audio sound; + + /** + * The required level of defence to use this prayer. + */ + private int defenceReq; + + /** + * The skill bonuses for this type. + */ + private final SkillBonus[] bonuses; + + /** + * Constructs a new {@code PrayerType} {@code Object}. + * @param level the level. + * @param drain the drain, represents the seconds until a drain. + * @param config the config value to represent on and off. + * @param button the button value to turn the prayer off and on. + * @param bonuses the skill bonuses for this type. + */ + PrayerType(int level, int drain, int config, int button, PrayerCategory restriction, int soundId, SkillBonus... bonuses) { + this(level, drain, config, button, restriction, null, new Audio(soundId), bonuses); + } + + /** + * + * Constructs a new @{Code PrayerType} object. + * @param level + * @param drain + * @param config + * @param button + * @param restriction + * @param soundId + * @param defenceReq + * @param bonuses + */ + PrayerType(int level, int drain, int config, int button, PrayerCategory restriction, int soundId, int defenceReq, SkillBonus... bonuses) { + this(level, drain, config, button, restriction, null, new Audio(soundId), defenceReq,bonuses); + } + + /** + * Constructs a new {@code PrayerType} {@code Object}. + * @param level the level. + * @param drain the drain, represents the seconds until a drain. + * @param config the config value to represent on and off. + * @param button the button value to turn the prayer off and on. + * @param bonuses the skill bonuses for this type. + */ + PrayerType(int level, int drain, int config, int button, PrayerCategory restriction, PrayerCategory secondRestriction, Audio sound, SkillBonus... bonuses) { + this(level,drain,config,button,restriction,secondRestriction,sound,1,bonuses); + } + + /** + * + * Constructs a new @{Code PrayerType} object. + * @param level + * @param drain + * @param config + * @param button + * @param restriction + * @param secondRestriction + * @param sound + * @param defenceReq + * @param bonuses + */ + PrayerType(int level, int drain, int config, int button, PrayerCategory restriction, PrayerCategory secondRestriction, Audio sound, int defenceReq, SkillBonus... bonuses) { + this.level = level; + this.drain = drain; + this.config = config; + this.button = button; + this.restriction = restriction; + this.secondRestriction = secondRestriction; + this.sound = sound; + this.bonuses = bonuses; + this.defenceReq = defenceReq; + } + + /** + * Gets the level. + * @return The level. + */ + public int getLevel() { + return level; + } + + /** + * Gets the drain. + * @return The drain. + */ + public int getDrain() { + return drain; + } + + /** + * Gets the config. + * @return The config. + */ + public int getConfig() { + return config; + } + + /** + * Gets the button. + * @return The button. + */ + public int getButton() { + return button; + } + + /** + * Gets the restriction. + * @return The restriction. + */ + public PrayerCategory getRestriction() { + return restriction; + } + + /** + * Gets the bonuses. + * @return The bonuses. + */ + public SkillBonus[] getBonuses() { + return bonuses; + } + + /** + * Method used to check if the player has the required level to toggle this + * type. + * @param player the player. + * @return True if it is permitted. + */ + public boolean permitted(final Player player) { + if (player.getSkills().getStaticLevel(Skills.PRAYER) < getLevel() || player.getSkills().getStaticLevel(Skills.DEFENCE) < defenceReq) { + playAudio(player, Sounds.PRAYER_OFF_2673); + player.getDialogueInterpreter().sendDialogue("You need a Prayer level of " + getLevel() + (player.getSkills().getStaticLevel(Skills.DEFENCE) < defenceReq ? (" and a Defence level of " + defenceReq) : "") + " to use " + StringUtils.formatDisplayName(name().toLowerCase().replace("_", " ")) + "."); + return false; + } + return true; + } + + /** + * Method used to check if we need to toggle a prayer on or off. + * @param player the player. + * @return True if toggled. + */ + public boolean toggle(final Player player, final boolean on) { + setVarp(player, getConfig(), on ? 1 : 0); + if (on) { + flag(player, this); + player.getPrayer().getActive().add(this); + iconify(player, getIcon(player, this)); + playAudio(player, sound.id); + + if (this == PrayerType.PIETY + && new ZoneBorders(2732, 3467, 2739, 3471, 0).insideBorder(player)) { + player.getAchievementDiaryManager().finishTask(player, DiaryType.SEERS_VILLAGE, 2, 3); + } + player.dispatch (new PrayerActivatedEvent(this)); + } else { + player.getPrayer().getActive().remove(this); + playAudio(player, Sounds.CANCEL_PRAYER_2663); + findNextIcon(player); + player.dispatch (new PrayerDeactivatedEvent(this)); + } + return true; + } + + /** + * Method used to flag others prayers that cannot be toggled together. + * @param player the player. + */ + public void flag(final Player player, final PrayerType type) { + final List active = player.getPrayer().getActive(); + final PrayerType[] remove = new PrayerType[active.size() + 10]; + int index = 0; + for (int i = 0; i < active.size(); i++) { + if (active.get(i).getRestriction() == type.getRestriction() || active.get(i).getSecondRestriction() != null && type.getSecondRestriction() != null && active.get(i).getSecondRestriction() == type.getSecondRestriction()) { + remove[index++] = active.get(i); + continue; + } + for (SkillBonus b : active.get(i).getBonuses()) { + for (SkillBonus bb : type.getBonuses()) { + if ((bb.getSkillId() == b.getSkillId()) || (b.getSkillId() == Skills.STRENGTH || b.getSkillId() == Skills.ATTACK) && (bb.getSkillId() == Skills.MAGIC || bb.getSkillId() == Skills.RANGE) || (b.getSkillId() == Skills.RANGE || b.getSkillId() == Skills.MAGIC) && (bb.getSkillId() == Skills.ATTACK || bb.getSkillId() == Skills.STRENGTH) || (b.getSkillId() == Skills.DEFENCE && bb.getSkillId() == Skills.DEFENCE)) { + remove[index++] = active.get(i); + } + } + } + } + for (int i = 0; i < index; i++) { + remove[i].toggle(player, false); + } + } + + /** + * Method used to iconify the player. + */ + public boolean iconify(final Player player, final int icon) { + if (icon == -1) { + return false; + } + player.getAppearance().setHeadIcon(icon); + player.getAppearance().sync(); + return false; + } + + /** + * Method used to find the next icon in place. + * @param player the player. + */ + public void findNextIcon(final Player player) { + if (!hasIcon(player)) { + player.getAppearance().setHeadIcon(-1); + player.getAppearance().sync(); + } + if ((this == PROTECT_FROM_MELEE || this == PROTECT_FROM_MISSILES || this == PROTECT_FROM_MAGIC) && player.getPrayer().get(PROTECT_FROM_SUMMONING)) { + iconify(player, 7); + } else if (this == PROTECT_FROM_SUMMONING) { + for (PrayerType t : player.getPrayer().getActive()) { + iconify(player, getIcon(player, t)); + } + if (player.getAppearance().getHeadIcon() == 7) { + player.getAppearance().setHeadIcon(-1); + player.getAppearance().sync(); + } + } + } + + /** + * Method used to get the icon value. + * @return the icon. + */ + public int getIcon(final Player player, final PrayerType type) { + List active = player.getPrayer().getActive(); + for (int i = 0; i < ICON_CACHE.length; i++) { + if (ICON_CACHE[i].length == 2 && type == ((PrayerType) ICON_CACHE[i][0])) { + return (int) ICON_CACHE[i][1]; + } else if (ICON_CACHE[i].length == 3 && type == ((PrayerType) ICON_CACHE[i][0])) { + if (active.contains(PROTECT_FROM_SUMMONING)) { + return (int) ICON_CACHE[i][2]; + } + return (int) ICON_CACHE[i][1]; + } else if (ICON_CACHE[i].length == 8 && type == ((PrayerType) ICON_CACHE[i][0])) { + for (int k = 2; k < ICON_CACHE[i].length; k++) { + if (active.contains(ICON_CACHE[i][k])) { + return (int) ICON_CACHE[i][k + 1]; + } + } + return (int) ICON_CACHE[i][1]; + } + } + return -1; + } + + /** + * Method used to check if theres an icon present. + * @param player the player. + * @return True if theres an icon present. + */ + public boolean hasIcon(final Player player) { + int count = 0; + for (PrayerType type : player.getPrayer().getActive()) { + if (getIcon(player, type) != -1) { + count++; + } + } + return count != 0; + } + + /** + * Method used to return the type by the button. + * @param button the button. + * @return the type. + */ + public static PrayerType get(int button) { + for (PrayerType type : PrayerType.values()) { + if (type.getButton() == button) { + return type; + } + } + return null; + } + + /** + * Method used to get the melee types. + * @return the types. + */ + public static PrayerType[] getMeleeTypes() { + return getByBonus(Skills.ATTACK, Skills.STRENGTH); + } + + /** + * Method used to get the rage types. + * @return the types. + */ + public static PrayerType[] getRangeTypes() { + return getByBonus(Skills.RANGE); + } + + /** + * Method used to get the magic types. + * @return the types. + */ + public static PrayerType[] getMagicTypes() { + return getByBonus(Skills.MAGIC); + } + + /** + * Method used to get the prayer types by the bonuses. + * @param ids the ids. + * @return the type. + */ + public static PrayerType[] getByBonus(int... ids) { + PrayerType[] types = new PrayerType[values().length]; + int count = 0; + for (PrayerType type : values()) { + for (SkillBonus b : type.getBonuses()) { + for (int i : ids) { + if (i == b.getSkillId()) { + types[count] = type; + count++; + } + } + } + } + return types; + } + + /** + * Gets the secondRestriction. + * @return The secondRestriction. + */ + public PrayerCategory getSecondRestriction() { + return secondRestriction; + } + + /** + * Gets the sound. + * @return The sound. + */ + public Audio getSound() { + return sound; + } + + public int getDefenceReq() { + return defenceReq; + } + +} diff --git a/Server/src/main/core/game/node/entity/player/link/quest/Quest.java b/Server/src/main/core/game/node/entity/player/link/quest/Quest.java new file mode 100644 index 0000000..364d0b9 --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/quest/Quest.java @@ -0,0 +1,353 @@ +package core.game.node.entity.player.link.quest; + +import content.data.Quests; +import core.game.component.Component; +import core.game.node.entity.player.Player; +import core.plugin.Plugin; +import core.plugin.PluginManifest; +import core.plugin.PluginType; + +import java.util.Arrays; +import java.util.Random; + +import static core.api.ContentAPIKt.*; + +/** + * A skeleton plugin for a quest. + * @author Vexia + * + */ +@PluginManifest(type = PluginType.QUEST) +public abstract class Quest implements Plugin { + + /** + * Represents the red string. + */ + public static final String RED = ""; + + /** + * Represents the bright red string. + */ + public static final String BRIGHT_RED = ""; + + /** + * Represents the blue string. + */ + public static final String BLUE = ""; + + /** + * Represents the black string. + */ + public static final String BLACK = ""; + + /** + * The constant representing the journal component. + */ + public static final int JOURNAL_COMPONENT = 275; + + /** + * The constant representing the quest reward component. + */ + public static final int REWARD_COMPONENT = 277; + + /** + * The quest as a Quests item (currently only used for the quest's name). + */ + private final Quests quest; + + /** + * The index id of the quest. + */ + private final int index; + + /** + * The button id of the quest. + */ + private final int buttonId; + + /** + * The rewarded quest points. + */ + private final int questPoints; + + /** + * The config values based on stage. + */ + private final int[] configs; + + /** + * Constructs a new {@link Quest} + * @param quest of the quest. Prereqs reference this + * @param index of the quest, usually buttonId + 1 + * @param buttonId of the quest on the quest list in game + * @param questPoints rewarded after completing quest + * @param configs of Varp/Varbit and values to set the quest color to red/yellow/green. e.g. {234, 0, 1, 10} + *

+ * Configs are made of either 4/5 numbers:
+ * 4 numbers: {1: VARP to set, 2: red quest name, 3: yellow quest name, 4: green quest name}
+ * 5 numbers: {1: VARP(Ignored), 2: VARPBIT to set, 3: red quest name, 4: yellow quest name, 5: green quest name}
+ *
+ * VARP/VARPBIT is set to values before/during/after quest at stage 0/1-99/100. + * Get these values from the VARPTOOL.
+ *
+ * If you see VARP (e.g. ./get_varp.sh 120):
+ * if (VARP[26] == 80 || VARP[26] == 90) return 2; if (VARP[26] == 0) return 0; return 1; }; if (arg0 == 89)
+ * Use 4 numbers: {26, 0, 1, 80} -> {VARP, return 0, return 1, return 2}
+ *
+ * If you see VARPBIT (e.g. ./get_varp.sh 119):
+ * if (VARPBIT[451] > 1) return 2; if (VARPBIT[451] == 0) return 0; return 1; }; if (arg0 == 88)
+ * Use 5 numbers: {0, 451, 0, 1, 2} -> {Ignore, VARPBIT, return 0, return 1, return 2}
+ */ + public Quest(Quests quest, int index, int buttonId, int questPoints, int...configs) { + this.quest = quest; + this.index = index; + this.buttonId = buttonId; + this.questPoints = questPoints; + this.configs = configs; + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } + + @Override + public abstract Quest newInstance(Object object); + + /** + * Starts this quest. + * @param player The player. + */ + public void start(Player player) { + player.getQuestRepository().setStage(this, 10); + player.getQuestRepository().syncronizeTab(player); + } + + /** + * Draws the text on the quest journal. + * @param player The player. + * @param stage The stage to draw. + */ + public void drawJournal(Player player, int stage) { + for (int i = 0; i < 311; i++) { + player.getPacketDispatch().sendString("" , JOURNAL_COMPONENT, i); + } + player.getPacketDispatch().sendString("" + getQuest() + "", JOURNAL_COMPONENT, 2); + + } + + /** + * Finishes the quest. + * @param player The player. + */ + public void finish(Player player) { + if(player.getQuestRepository().isComplete(quest)) { + throw new IllegalStateException("Tried to complete quest " + quest + " twice, which is not allowed!"); + } + for (int i = 0; i < 18; i++) { + if (i == 9 || i == 3 || i == 6) { + continue; + } + player.getPacketDispatch().sendString("", 277, i); + } + player.getQuestRepository().setStage(this, 100); + player.getQuestRepository().incrementPoints(getQuestPoints()); + player.getQuestRepository().syncronizeTab(player); + player.getInterfaceManager().open(new Component(277).setCloseEvent((p, c) -> { + this.questCloseEvent(p, c); + return true; + })); + player.getPacketDispatch().sendString("" + player.getQuestRepository().getPoints() + "", 277, 7); + player.getPacketDispatch().sendString("You have completed the " + getQuest() + " Quest!", 277, 4); + player.getPacketDispatch().sendMessage("Congratulations! Quest complete!"); + int questJingles[] = {152, 153, 154}; + playJingle(player, questJingles[new Random().nextInt(3)]); + } + + /** + * Resets the quest. This is called when ::setQuestStage is set to 0. + * Useful to override and reset quest player attributes. + */ + public void reset(Player player) {} + + /** + * Function callback when closing the quest. + * Override this to follow up on dialogue after the component closes. + */ + public void questCloseEvent(Player player, Component component) {} + + /** + * Draws a line on the journal component. + * @param player The player. + * @param message The message. + * @param line The line. + */ + public void line(Player player, String message, int line) { + String send = BLUE + "" + message.replace("", "

").replace("", BLUE).replace("", RED); + if (send.contains("

") || send.contains("")) { + String[] lines = send.split(send.contains("

") ? "

" : ""); + for (int i = 0; i < lines.length; i++) { + line(player, lines[i].replace("

", "").replace("", ""), line, false); + line++; + } + } else { + send = send.replace("!!", RED).replace("??", BLUE).replace("---", BLACK + "").replace("/--", BLUE).replace("%%", BRIGHT_RED).replace("&&", BLUE); + line(player, send, line, false); + } + } + + /** + * Draws a line on the quest journal component. + * @param player The player. + * @param message The message. + * @param line The line number. + * @param crossed True if the message should be crossed out. + */ + public void line(Player player, String message, int line, final boolean crossed) { + String send; + if(!crossed){ + send = BLUE + "" + message.replace("", "

").replace("", BLUE).replace("", RED); + send = send.replace("!!", RED).replace("??", BLUE).replace("%%", BRIGHT_RED).replace("&&", BLUE); + } else { + send = BLACK + "" + message.replace("", "

").replace("", "").replace("", "RED"); + send = send.replace("!!", "").replace("??", "").replace("%%", "").replace("&&", ""); + } + player.getPacketDispatch().sendString(crossed ? "" + send + "" : send, JOURNAL_COMPONENT, line); + } + + /** + * Limits the quest log scroll to the number of lines minus 9. + * Assumes that you start at line = 11 or line = 12. + * Call this function at the end of the drawJournal function like: limitScroll(player, line); + * @param player The player. + * @param line The number of lines to scroll. Due to sendRunScript, it handles less than 12 lines pretty well. + * @param startFromTop Whether to open the log at the top, defaults to opening the log at the very bottom. + */ + public void limitScrolling(Player player, int line, boolean startFromTop) { + // sendRunScript reverses the objects you pass in + // (args1: 0 is to start from bottom of scroll) (args0: child-12 lines to display) + player.getPacketDispatch().sendRunScript(1207, "ii", startFromTop ? 1 : 0, line - 9); // -9 to give text some padding instead of line - 11 or 12 + } + + /** + * Draws text on the quest reward component. + * @param player The player. + * @param string The string to draw. + * @param line The line number to draw on. + */ + public void drawReward(Player player, final String string, final int line) { + player.getPacketDispatch().sendString(string, REWARD_COMPONENT, line); + } + + /** + * Sets the player instanced stage. + * @param player The player. + * @param stage The stage to set. + */ + public void setStage(Player player, int stage) { + player.getQuestRepository().setStage(this, stage); + } + + /** + * Gets the config id based on the stage. + * @param player The player. + * @param stage The stage. + * @return The config data. + */ + public int[] getConfig(Player player, int stage) { + if (configs.length < 4) { + throw new IndexOutOfBoundsException("Quest -> " + quest + " configs array length was not valid. config length = " + configs.length + "!"); + } + if (configs.length >= 5) { + // {questVarpId, questVarbitId, valueToSet} + return new int[] {configs[0], configs[1], stage == 0 ? configs[2] : stage >= 100 ? configs[4] : configs[3]}; + } + // {questVarpId, valueToSet} + return new int[] {configs[0], stage == 0 ? configs[1] : stage >= 100 ? configs[3] : configs[2]}; + } + + public void updateVarps(Player player) { + } + + /** + * Checks if the quest is in progress. + * @param player The player. + * @return {@code True} if so. + */ + public boolean isStarted(Player player) { + return getStage(player) > 0 && getStage(player) < 100; + } + + /** + * Checks if the quest is completed. + * @param player The player. + * @return {@code True} if so. + */ + public boolean isCompleted(Player player) { + return getStage(player) >= 100; + } + + /** + * Gets the player instanced stage of this quest. + * @param player The player. + * @return The stage. + */ + public int getStage(Player player) { + return player.getQuestRepository().getStage(this); + } + + /** + * Checks the requirements for the quest. + * @param player The player + * @return {@code True} if so. + */ + public boolean hasRequirements(Player player) { + return true; + } + + /** + * Gets the name. + * @return the name. + */ + public Quests getQuest() { + return quest; + } + + /** + * Gets the index. + * @return the index. + */ + public int getIndex() { + return index; + } + + /** + * Gets the buttonId. + * @return the buttonId. + */ + public int getButtonId() { + return buttonId; + } + + /** + * Gets the questPoints. + * @return the questPoints. + */ + public int getQuestPoints() { + return questPoints; + } + + /** + * Gets the configs. + * @return the configs. + */ + public int[] getConfigs() { + return configs; + } + + @Override + public String toString() { + return "Quest [name=" + quest + ", index=" + index + ", buttonId=" + buttonId + ", questPoints=" + questPoints + ", configs=" + Arrays.toString(configs) + "]"; + } + +} diff --git a/Server/src/main/core/game/node/entity/player/link/quest/QuestRepository.java b/Server/src/main/core/game/node/entity/player/link/quest/QuestRepository.java new file mode 100644 index 0000000..02ccf6b --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/quest/QuestRepository.java @@ -0,0 +1,298 @@ +package core.game.node.entity.player.link.quest; + +import content.data.Quests; +import core.game.node.entity.player.Player; + +import core.tools.Log; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; + +import java.util.HashMap; +import java.util.TreeMap; +import java.util.Map; + +import static core.api.ContentAPIKt.log; +import static core.api.ContentAPIKt.*; + + +/** + * Manages the systems/players quest repository. + * + * @author Vexia + */ +public final class QuestRepository { + + /** + * The static mapping of instanced quests. + */ + private static final Map QUESTS = new TreeMap<>(); + + /** + * The mapping of quest indexes with related stages. + */ + private final Map quests = new HashMap<>(); + + /** + * The player instance for this manager. + */ + private final Player player; + + /** + * The current syncronized accumulated quest points. + */ + private int points; + + /** + * Constructs a new {@code QuestRepository} {@code Object}. + * + * @param player the player. + */ + public QuestRepository(final Player player) { + this.player = player; + for (Quest quest : QUESTS.values()) { + quests.put(quest.getIndex(), 0); + } + } + + public void parse(JSONObject questData){ + points = Integer.parseInt( questData.get("points").toString()); + JSONArray questArray = (JSONArray) questData.get("questStages"); + questArray.forEach(quest -> { + JSONObject q = (JSONObject) quest; + quests.put(Integer.parseInt( q.get("questId").toString()),Integer.parseInt(q.get("questStage").toString())); + }); + syncPoints(); + } + + /** + * Synchronizes the quest tab. + * + * @param player The player. + */ + public void syncronizeTab(Player player) { + setVarp(player, 101, points); + int[] config = null; + for(Quest quest : QUESTS.values()){ + config = quest.getConfig(player,getStage(quest)); + + // {questVarpId, questVarbitId, valueToSet} + if (config.length == 3) { + // This is to set quests with VARPBIT, ignoring VARP value + setVarbit(player, config[1], config[2]); + } else { + // This is the original VARP quests + // {questVarpId, valueToSet} + setVarp(player, config[0], config[1]); + } + + quest.updateVarps(player); + } + } + + /** + * Sets the stage of a quest. + * + * @param quest The quest. + * @param stage The stage. + */ + public void setStage(Quest quest, int stage) { + int oldStage = getStage(quest); + if(oldStage < stage) { + quests.put(quest.getIndex(), stage); + } else { + log(this.getClass(), Log.WARN, String.format("Nonmonotonic QuestRepository.setStage call for player \"%s\", quest \"%s\", old stage %d, new stage %d", player.getName(), quest.getQuest(), oldStage, stage)); + } + } + + /** + * Sets the stage of a quest, permitting non-monotonic updates. + * + * @param quest The quest. + * @param stage The stage. + */ + public void setStageNonmonotonic(Quest quest, int stage) { + quests.put(quest.getIndex(), stage); + } + + /** + * Increments the obtained points by the value. + * + * @param value the value. + */ + public void incrementPoints(int value) { + points += value; + } + + /** + * Decrease the points by the value. + * + * @param value the value. + */ + public void dockPoints(int value) { points -= value; } + + /** + * Syncronizes the quest points. + */ + public void syncPoints() { + int points = 0; + for (Quest quest : QUESTS.values()) { + if (getStage(quest) >= 100) { + points += quest.getQuestPoints(); + } + } + this.points = points; + } + + /** + * Gets the available quest points. + * + * @return The availble quest points. + */ + public int getAvailablePoints() { + int points = 0; + for (Quest quest : QUESTS.values()) { + points += quest.getQuestPoints(); + } + return points; + } + + /** + * Gets the quest for the button id. + * + * @param buttonId The button id. + * @return The quest. + */ + public Quest forButtonId(int buttonId) { + for (Quest q : QUESTS.values()) { + if (q.getButtonId() == buttonId) { + return q; + } + } + return null; + } + + /** + * Gets the quest for the index. + * + * @param index The index. + * @return The quest. + */ + public Quest forIndex(int index) { + for (Quest q : QUESTS.values()) { + if (q.getIndex() == index) { + return q; + } + } + return null; + } + + /** + * Checks if all quests are completed. + * + * @return {@code True} if so. + */ + public boolean hasCompletedAll() { + return getPoints() >= getAvailablePoints(); + } + + /** + * Checks if the quest is complete. + * + * @param quest The quest. + * @return {@code True} if so. + */ + public boolean isComplete(Quests quest) { + Quest theQuest = getQuest(quest); + if (theQuest == null) { + log(this.getClass(), Log.ERR, "Error can't check if quest is complete for " + quest); + return false; + } + return theQuest.getStage(player) >= 100; + } + + /** + * Checks if the quest has at least started. + * + * @param quest The quest by id. + * @return {@code True} if so. + */ + public boolean hasStarted(Quests quest) { + Quest theQuest = getQuest(quest); + if (quest == null) { + log(this.getClass(), Log.ERR, "Error can't check if quest is complete for " + quest); + return false; + } + return theQuest.getStage(player) > 0; + } + + + /** + * Gets the stage of quest by id. + * @param quest The quest. + * @return The stage. + */ + public int getStage(Quests quest) { + var theQuest = QUESTS.get(quest); + if (theQuest == null) { + return 0; + } + return getStage(theQuest); + } + + /** + * Gets the stage of a quest. + * @param quest The quest. + * @return The stage. + */ + public int getStage(Quest quest) { + return quests.get(quest.getIndex()); + } + + /** + * Gets the quest by id. + * @param quest The quest. + * @return The quest. + */ + public Quest getQuest(Quests quest) { + return QUESTS.get(quest); + } + + /** + * Gets the points. + * + * @return the points. + */ + public int getPoints() { + return points; + } + + /** + * Gets the player. + * + * @return The player. + */ + public Player getPlayer() { + return player; + } + + /** + * Registers the quest to the repository. + * + * @param quest The quest. + */ + public static void register(Quest quest) { + QUESTS.put(quest.getQuest(), quest); + } + + /** + * Gets the quest repository. + * + * @return the quests. + */ + public static Map getQuests() { + return QUESTS; + } + + public Map getQuestList() {return quests;} + +} diff --git a/Server/src/main/core/game/node/entity/player/link/request/RequestManager.kt b/Server/src/main/core/game/node/entity/player/link/request/RequestManager.kt new file mode 100644 index 0000000..73e9588 --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/request/RequestManager.kt @@ -0,0 +1,113 @@ +package core.game.node.entity.player.link.request + +import core.game.node.entity.player.Player +import core.game.bots.AIRepository +import content.global.bots.DoublingMoney +import core.game.world.GameWorld.ticks + +/** + * Represents a managing class for requests of a player. + * @author Vexia + * @author dginovker + * @version 2.0 + */ +class RequestManager(val player: Player) { + /** + * Represents the target being requested. + */ + var target: Player? = null + private set + + /** + * Method used to send a request type to a target. + * @param target the target. + * @param type the type of request. + * @return `True` if successful. + */ + fun request(target: Player, type: RequestType): Boolean { + if (!canRequest(type, target)) { + return false + } + if (acceptExisting(target, type)) { + return true + } + player.packetDispatch.sendMessage(type.message) + target.packetDispatch.sendMessage(type.getRequestMessage(player)) + player.setAttribute("lastRequest", type) + this.target = target + + // If the target is a bot, get their bot manager to handle the request. + if (target.isArtificial) { + val bot = AIRepository.PulseRepository[target.username.lowercase()] + if (bot != null && bot.botScript is DoublingMoney) { + bot.botScript.tradeReceived(player) + } + } + return true + } + + /** + * Method used to check if a player can continue with a request. + * @param type the type. + * @param target the target. + * @return `True` if so. + */ + private fun canRequest(type: RequestType, target: Player): Boolean { + if (target === player) { + return false + } + if (!target.location.withinDistance(player.location, 15)) { + player.packetDispatch.sendMessage("Unable to find " + target.username + ".") + return false + } + if (!target.isActive || target.interfaceManager.isOpened) { + player.packetDispatch.sendMessage("Other player is busy at the moment.") + return false + } + if (target.getAttribute("busy", 0) > ticks || player.getAttribute("busy", 0) > ticks) { + player.packetDispatch.sendMessage("Other player is busy at the moment.") + return false + } + return if (!player.zoneMonitor.canRequest(type, target)) { + false + } else type.canRequest(player, target) + } + + /** + * Method used to check if we can accept an existing request. + * @param target the target. + * @param type the type. + * @return `True` if so. + */ + private fun acceptExisting(target: Player, type: RequestType): Boolean { + val lastType = target.getAttribute("lastRequest", null) + if (lastType === type && player === target.requestManager.target) { + close(player) + clear() + target.requestManager.clear() + player.setAttribute("busy", ticks + 2) + target.setAttribute("busy", ticks + 2) + type.module.open(player, target) + return true + } + close(player) + return false + } + + /** + * Closes the components for the player. + * @param player the player. + */ + private fun close(player: Player) { + player.dialogueInterpreter.close() + player.interfaceManager.close() + player.interfaceManager.closeChatbox() + } + + /** + * Method used to clear the cached target. + */ + fun clear() { + target = null + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/player/link/request/RequestModule.kt b/Server/src/main/core/game/node/entity/player/link/request/RequestModule.kt new file mode 100644 index 0000000..4e17051 --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/request/RequestModule.kt @@ -0,0 +1,18 @@ +package core.game.node.entity.player.link.request + +import core.game.node.entity.player.Player + +/** + * Represents the module used for all request types. + * @author 'Vexia + * @author dginovker + * @version 2.0 + */ +interface RequestModule { + /** + * Method invoked when the targeting player accepts a request. + * @param player the player. + * @param target the target. + */ + fun open(player: Player?, target: Player?) +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/player/link/request/RequestType.kt b/Server/src/main/core/game/node/entity/player/link/request/RequestType.kt new file mode 100644 index 0000000..14f7189 --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/request/RequestType.kt @@ -0,0 +1,63 @@ +package core.game.node.entity.player.link.request + +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.request.assist.AssistSession +import core.game.node.entity.player.link.request.trade.TradeModule + +/** + * Represents a request type. + * @author 'Vexia + * @author Emperor + * @author dginovker + * @version 2.0 + */ +open class RequestType +/** + * Constructs a new `RequestManager { Object}. + * message the message. + * requestMessage the requesting message.` + */( + /** + * Represents the message to send for the player when requesting. + */ + val message: String, + /** + * Represents the requesting message type. + */ + val requestMessage: String, + /** + * Represents the module used for this type of requesting. + */ + val module: RequestModule +) { + /** + * Checks if the request can be made. + * @param player The player. + * @param target The target. + * @return `True` if so. + */ + open fun canRequest(player: Player?, target: Player?): Boolean { + return true + } + + /** + * Gets the requesting message formated with the targets name. + * @param target the target. + * @return the message to send. + */ + fun getRequestMessage(target: Player): String { + return target.username + requestMessage + } + + companion object { + /** + * The trade request type. + */ + val TRADE = RequestType("Sending a trade offer...", ":tradereq:", TradeModule(null, null)) + + /** + * The assist request type. + */ + val ASSIST = RequestType("Sending assistance request...", ":assistreq:", AssistSession()) + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/player/link/request/assist/AssistSession.java b/Server/src/main/core/game/node/entity/player/link/request/assist/AssistSession.java new file mode 100644 index 0000000..bf82b65 --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/request/assist/AssistSession.java @@ -0,0 +1,472 @@ +package core.game.node.entity.player.link.request.assist; + +import core.game.component.CloseEvent; +import core.game.component.Component; +import core.game.node.entity.skill.Skills; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.request.RequestModule; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.update.flag.context.Animation; +import core.game.world.update.flag.context.Graphics; + +import java.util.Calendar; +import java.util.Date; + +import static core.api.ContentAPIKt.*; + + +/** + * Represents the class used to handle the assist requesting of a {@link Player} + * . + * @author 'Vexia + * @date Oct 3, 2013 + */ +public final class AssistSession extends Pulse implements RequestModule { + + /** + * Represents the player of this request assist class. + */ + private Player player; + + /** + * Represents the partener of this class. + */ + private Player partener; + + /** + * Represents the {@link Component} to display. + */ + private final Component component = new Component(301).setCloseEvent(getCloseEvent()); + + /** + * Represents the {@link Animation} of assisting a player. + */ + private static final Animation ANIMATION = Animation.create(7299); + + /** + * Represents the {@link Graphics} of assisting a player. + */ + private static final Graphics GRAPHIC = Graphics.create(1247); + + /** + * The time out until the exp is reset. + */ + private static final long TIME_OUT = 86400000;// 60000; //86400000; + + /** + * Represents the config values of toggling a button. + */ + private static final byte[] CONFIG_VALUES = { 3, 4, 6, 8, 9, 11, 13, 14, 15 }; + + /** + * Represents used child values of the experience to show. + */ + private static final int[] CHILD_VALUES = { 46, 48, 50, 52, 54, 56, 58, 60, 62 }; + + /** + * Represents the current skills being used. + */ + private boolean[] skills = new boolean[9]; + + /** + * Represents if the session is restricted from gaining experience. + */ + private boolean restricted = false; + + /** + * Represents the gained exp for the skill(index-experience). + */ + private double exp[] = new double[9]; + + /** + * Represents a kill switch for the session. + */ + private boolean kill = false; + + /** + * Represents the start time. + */ + private long time; + + /** + * Constructs a new {@code RequestAssist} {@code Object}. + * @param player the player. + * @param partener the partener. + */ + public AssistSession(final Player player, final Player partener) { + this.player = player; + this.partener = partener; + } + + /** + * Constructs a new {@code AssistSession} {@code Object}. + */ + public AssistSession() { + /** + * empty. + */ + } + + /** + * Method used to add the extension of this class to the {@literal Player}. + * @param player the player. + * @param partener the partener. + */ + public static final void extend(final Player player, final Player partener) { + player.addExtension(AssistSession.class, new AssistSession(player, partener)); + } + + /** + * Method used to get the extension of this class from the {@link Player}. + * @param player the player. + * @return the {@link AssistSession} (this). + */ + public final static AssistSession getExtension(final Player player) { + return player.getExtension(AssistSession.class); + } + + @Override + public void open(Player player, Player target) { + if (player.getIronmanManager().checkRestriction() || target.getIronmanManager().checkRestriction()) { + return; + } + player.face(target); + target.face(player); + AssistSession.extend(player, target); + AssistSession.getExtension(player).open(); + } + + /** + * Method used to be called only for the {@link #player} of this class which + * then extends this class to the partener. + */ + public final void open() { + partener.addExtension(AssistSession.class, this); + player.lock(); + player.getInterfaceManager().open(component); + load(); + player.getPacketDispatch().sendMessage("Sending assistance response."); + player.getPacketDispatch().sendMessage("You are assisting " + partener.getUsername() + "."); + partener.getPacketDispatch().sendMessage("You are being assisted by " + player.getUsername() + "."); + player.getPacketDispatch().sendString("Assist System XP Display - You are assisting " + partener.getUsername() + "", 301, 101); + player.getPacketDispatch().sendString("", 301, 10); + player.animate(ANIMATION); + player.graphics(GRAPHIC); + partener.animate(ANIMATION); + playAudio(partener, 4010); + playAudio(player, 4010); + toggleIcon(player, false); + toggleIcon(partener, false); + GameWorld.getPulser().submit(this); + refresh(); + } + + /** + * Method used to get the {@link CloseEvent} of the {@link Component}. + * @return the close event of the {@link #component}. + */ + public final CloseEvent getCloseEvent() { + return new CloseEvent() { + @Override + public boolean close(Player player, Component c) { + save(); + player.removeExtension(AssistSession.class); + partener.removeExtension(AssistSession.class); + player.unlock(); + toggleIcon(player, true); + toggleIcon(partener, true); + player.getInterfaceManager().restoreTabs(); + player.getPacketDispatch().sendMessage("You have stopped assisting " + partener.getUsername() + "."); + partener.getPacketDispatch().sendMessage(getPlayer().getUsername() + " has stopped assisting you."); + kill = true; + return true; + } + }; + } + + /** + * Method used to toggle the assisting icons. + * @param player the player. + * @param hide the icon or not. + */ + public final void toggleIcon(final Player player, final boolean hide) { + for (int i = 79; i < 81; i++) { + player.getPacketDispatch().sendInterfaceConfig(548, i, hide); + } + } + + /** + * Method used to override the adding of experience when the player is the + * assister. + * @param skill the skill. + * @param experience the experience. + */ + public final void addExperience(final int skill, final double experience) { + if (restricted || getTotalExperience() >= 30000) { + restricted = true; + return; + } + final int skillIndex = getSkillIndex(skill); + if (exp[skillIndex] + experience >= 30000) { + exp[skillIndex] = 30000; + restricted = true; + return; + } + exp[skillIndex] += experience; + if (exp[skillIndex] >= 30000) { + exp[skillIndex] = 30000; + } + refresh(); + } + + /** + * Method used to refresh the interface. + */ + public final void refresh() { + int value = 0; + double totalXp = 0; + for (byte i = 0; i < 9; i++) { + if (exp[i] >= 30000) { + exp[i] = 30000; + } + player.getPacketDispatch().sendString("" + (int) exp[i], 301, CHILD_VALUES[i]); + if (skills[i]) { + value |= 1 << CONFIG_VALUES[i]; + } + totalXp += exp[i]; + } + if (getTotalExperience() >= 30000) { + restricted = true; + } else { + restricted = false; + } + String message = ""; + if (isRestricted()) { + message = "You've earned the maximum XP from the Assist System within a 24-hour period. You can assist again in " + getTimeLeft() + "."; + } + player.getPacketDispatch().sendString(message, 301, 10); + setVarp(player, 1087, value); + setVarp(player, 1088, (int) totalXp * 10); + } + + /** + * Method used to toggle the skill button. + * @param id the id. + */ + public final void toggleButton(final byte id) { + skills[id] = skills[id] ? false : true; + } + + /** + * Method used to check if a specified skill is currently toggled. + * @param skill the skill. + * @return True if toggled. + */ + public final boolean isToggled(final int skill) { + return skills[getSkillIndex(skill)]; + } + + /** + * Method used to get the skill index by the skill id. + * @param skill the skill id. + * @return the index. + */ + public final int getSkillIndex(int skill) { + switch (skill) { + case Skills.RUNECRAFTING: + return 0; + case Skills.CRAFTING: + return 1; + case Skills.FLETCHING: + return 2; + case Skills.CONSTRUCTION: + return 3; + case Skills.FARMING: + return 4; + case Skills.MAGIC: + return 5; + case Skills.SMITHING: + return 6; + case Skills.COOKING: + return 7; + case Skills.HERBLORE: + return 8; + } + return -1; + } + + /** + * Method used to get the skill array. + * @return the array of skill's turned on. + */ + public boolean[] getSkills() { + return skills; + } + + /** + * Method used to get the amount of time left. + * @return the formated time. + */ + public String getTimeLeft() { + Date date2 = new Date(time); + Date date1 = new Date(System.currentTimeMillis()); + Calendar calendar1 = Calendar.getInstance(); + Calendar calendar2 = Calendar.getInstance(); + calendar1.setTime(date1); + calendar2.setTime(date2); + long milliseconds1 = calendar1.getTimeInMillis(); + long milliseconds2 = calendar2.getTimeInMillis(); + long diff = milliseconds2 - milliseconds1; + long diffSeconds = diff / 1000; + long diffMinutes = diff / (60 * 1000); + long diffHours = diff / (60 * 60 * 1000); + if (diffHours > 1) { + return "" + diffHours + " hours"; + } + if (diffMinutes > 1) { + return "" + diffMinutes + " minutes"; + } + return "" + diffSeconds + " seconds"; + } + + /** + * Method used to return the total experience gained. + * @return the experience gained. + */ + public double getTotalExperience() { + double xp = 0; + for (int i = 0; i < 9; i++) { + xp += exp[i]; + } + return xp; + } + + /** + * Method used to return the {@link Player}. + * @return the Player. + */ + public final Player getPlayer() { + return player; + } + + /** + * Method used to load the information. + */ + public final void load() { + time = player.getSavedData().getGlobalData().getAssistTime(); + if (time == 0) { + player.getSavedData().getGlobalData().setAssistTime(System.currentTimeMillis() + TIME_OUT); + } + for (int i = 0; i < 9; i++) { + exp[i] = player.getSavedData().getGlobalData().getAssistExperience()[i]; + } + } + + /** + * Method used to save the assist data. + */ + public final void save() { + player.getSkills().refresh(); + player.getSavedData().getGlobalData().setAssistTime(time); + player.getSavedData().getGlobalData().setAssistExperience(exp); + } + + /** + * Method used to reset the assist data. + */ + public final void reset() { + player.getSavedData().getGlobalData().setAssistTime(0L); + player.getSavedData().getGlobalData().setAssistExperience(new double[9]); + load(); + } + + @Override + public boolean pulse() { + if (!player.getLocation().withinDistance(partener.getLocation(), 20) || !partener.isActive() || !player.isActive()) { + player.getInterfaceManager().close(); + return true; + } + if (time < System.currentTimeMillis()) { + time = System.currentTimeMillis() + TIME_OUT; + for (int i = 0; i < 9; i++) { + exp[i] = 0; + } + } + refresh(); + return kill; + } + + /** + * Translates experience to another player. + * @param p the p. + * @param slot the slot. + * @param experience the exp. + * @param mod the mod. + * @return {@code True} if translated. + */ + public boolean translateExperience(Player p, int slot, double experience, double mod) { + if (getPlayer() != p) { + int index = getSkillIndex(slot); + if (index != -1) { + if (!isRestricted()) { + int level = p.getSkills().getLevel(slot); + int pLevel = player.getSkills().getLevel(slot); + if (pLevel < level) { + return false; + } + if (getSkills()[getSkillIndex(slot)]) { + if (getExp()[index] + experience >= 30000) { + experience = experience - (getExp()[index] + experience - 30000); + } + getPlayer().getSkills().addExperience(slot, experience); + addExperience(slot, experience * mod); + return true; + } + } + } + } + return false; + } + + /** + * Method used to return if the assist session is restricted. + * @return True if so. + */ + public boolean isRestricted() { + return restricted; + } + + /** + * Gets the exp. + * @return the exp. + */ + public double[] getExp() { + return exp; + } + + /** + * Sets th exp. + * @param exp the exp. + */ + public void setExp(double[] exp) { + this.exp = exp; + } + + /** + * Gets the partener. + * @return the partener + */ + public Player getPartener() { + return partener; + } + + /** + * Sets the bapartener. + * @param partener the partener to set. + */ + public void setPartener(Player partener) { + this.partener = partener; + } + +} diff --git a/Server/src/main/core/game/node/entity/player/link/request/trade/TradeCloseEvent.java b/Server/src/main/core/game/node/entity/player/link/request/trade/TradeCloseEvent.java new file mode 100644 index 0000000..e2eb3a0 --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/request/trade/TradeCloseEvent.java @@ -0,0 +1,82 @@ +package core.game.node.entity.player.link.request.trade; + +import core.game.component.CloseEvent; +import core.game.component.Component; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.net.packet.PacketRepository; +import core.net.packet.context.ContainerContext; +import core.net.packet.out.ContainerPacket; + +import static core.api.ContentAPIKt.*; + + +/** + * Represents the close event invoked at the closing of a trade interface. + * @author Vexia + */ +public final class TradeCloseEvent implements CloseEvent { + + @Override + public boolean close(Player player, Component c) { + final TradeModule module = TradeModule.getExtension(player); + player.getPacketDispatch().sendRunScript(101, ""); + if (module == null) { + return true; + } + TradeModule otherModule = TradeModule.getExtension(module.getTarget()); + if (otherModule == null) { + return true; + } + if (module.isAccepted() && otherModule.isAccepted()) { + return true; + } + if (module.getStage() != 2) { + retainContainer(player); + retainContainer(module.getTarget()); + } + closeInterfaces(player); + closeInterfaces(module.getTarget()); + module.getTarget().getInterfaceManager().close(); + end(player); + player.getInterfaceManager().openDefaultTabs(); + end(module.getTarget()); + module.getTarget().getInterfaceManager().openDefaultTabs(); + return true; + } + + /** + * Method used to close the trade interface. + * @param player the player. + */ + private void closeInterfaces(final Player player) { + player.removeExtension(TradeModule.class); + player.getInterfaceManager().closeSingleTab(); + PacketRepository.send(ContainerPacket.class, new ContainerContext(player, -1, 2, 24, new Item[] {}, 27, false)); + PacketRepository.send(ContainerPacket.class, new ContainerContext(player, -1, 2, 23, new Item[] {}, 27, false)); + player.getPacketDispatch().sendRunScript(101, ""); + } + + /** + * Method used to end the trade session. + * @param player the player. + */ + private void end(final Player player) { + setVarp(player, 1043, 0); + setVarp(player, 1042, 0); + } + + /** + * Method used to retain the trade container. + * @param player the player. + */ + private void retainContainer(final Player player) { + final TradeModule module = TradeModule.getExtension(player); + if (module == null || module.isRetained()) { + return; + } + module.setRetained(true); + player.getInventory().addAll(module.getContainer()); + } + +} diff --git a/Server/src/main/core/game/node/entity/player/link/request/trade/TradeContainer.java b/Server/src/main/core/game/node/entity/player/link/request/trade/TradeContainer.java new file mode 100644 index 0000000..22fab5a --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/request/trade/TradeContainer.java @@ -0,0 +1,259 @@ +package core.game.node.entity.player.link.request.trade; + +import static core.api.ContentAPIKt.*; +import static core.tools.GlobalsKt.colorize; + +import core.cache.def.impl.ItemDefinition; +import core.game.container.*; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.net.packet.PacketRepository; +import core.net.packet.context.ContainerContext; +import core.net.packet.out.ContainerPacket; + + +/** + * Represents the container during a trade session. + * @author 'Vexia + */ +public final class TradeContainer extends Container { + + /** + * Represents the player of this container. + */ + private final Player player; + + /** + * Constructs a new {@code TradeContainer} {@code Object}. + * @param player the player. + */ + public TradeContainer(final Player player) { + super(28, ContainerType.DEFAULT, SortType.ID); + this.player = player; + this.getListeners().add(new TradeListener()); + } + + /** + * Method used to offer an item to the container. + * @param slot the slot of the item. + * @param amount the amount of the item. + */ + public void offer(final int slot, int amount) { + final Item item = getItem(slot, player.getInventory()); + if (!canUse()) { + return; + } + if (!validatedItem(item, slot, amount, player.getInventory())) { + return; + } + if (!tradeable(item) && !GameWorld.getSettings().isDevMode()) { + player.getPacketDispatch().sendMessage("You can't trade this item."); + return; + } + Item remove = new Item(item.getId(), amount); + remove.setAmount(stabalizeAmount(remove, amount, player.getInventory())); + if (!checkCapacity(remove, this)) { + player.getPacketDispatch().sendMessage("You must accept the current items before adding any more."); + return; + } + if (player.getInventory().remove(remove, slot, true) && super.add(remove)) { + if (TradeModule.getExtension(player).isAccepted() || TradeModule.getExtension(TradeModule.getExtension(player).getTarget()).isAccepted()) { + TradeModule.getExtension(player).setAccepted(false, true); + TradeModule.getExtension(TradeModule.getExtension(player).getTarget()).setAccepted(false, true); + } + TradeModule.getExtension(player).update(); + checkAlert(); + } + } + + /** + * Method used to withdraw an item from the container. + * @param slot the slot of the item. + * @param amount the amount of the item. + */ + public void withdraw(final int slot, int amount) { + Item item = getItem(slot, this); + if (!canUse()) { + return; + } + if (!validatedItem(item, slot, amount, this)) { + return; + } + Item remove = new Item(item.getId(), amount); + remove.setAmount(stabalizeAmount(remove, amount, this)); + if (!checkCapacity(remove, player.getInventory())) { + player.getPacketDispatch().sendMessage("You don't have enough space in your inventory."); + return; + } + if (super.remove(remove, slot, true) && player.getInventory().add(remove)) { + shift(); + TradeModule.getExtension(player).setModified(true); + if (TradeModule.getExtension(player).isAccepted() || TradeModule.getExtension(TradeModule.getExtension(player).getTarget()).isAccepted()) { + TradeModule.getExtension(player).setAccepted(false, true); + TradeModule.getExtension(TradeModule.getExtension(player).getTarget()).setAccepted(false, true); + TradeModule.getExtension(player).update(); + } else { + TradeModule.getExtension(player).update(); + } + } + if (TradeModule.getExtension(player).isModified()) { + alert(slot, true); + } + } + + @Override + public void shift() { + super.shift(); + } + + /** + * Method used to get the item from the slot based on container. + * @param slot the slot to get the item from. + * @param container the container to use. + * @return the item from the container at the slot. + */ + private Item getItem(int slot, final Container container) { + return container.get(slot); + } + + /** + * Method used to check if an item is validated. + * @param item the item. + * @param slot the slot. + * @param amount the amount. + * @param container the container. + * @return {@code True} if validated. + */ + private boolean validatedItem(final Item item, final int slot, final int amount, final Container container) { + if (item == null) { + return false; + } + return !(slot < 0 || slot > player.getInventory().capacity() || amount < 1); + } + + /** + * Method used to stabalize the amount attempting to be withdrawn/offered. + * @param item the item. + * @param amount the amount. + * @param container the container. + * @return the stabalized amount if over. + */ + private int stabalizeAmount(final Item item, int amount, final Container container) { + int maximum = container.getAmount(item); + return (amount > maximum ? maximum : amount); + } + + /** + * Method used to check if an item is tradeable. + * @param item the item. + * @return {@code True} if tradeable. + */ + private boolean tradeable(final Item item) { + final ItemDefinition definition = ItemDefinition.forId(item.getId()); + Player target = TradeModule.getExtension(player).getTarget(); + boolean playerIsBot = player.getAttribute("not_on_highscores",false); + boolean targetIsBot = target.getAttribute("not_on_highscores",false); + String playerIP = player.getDetails().getIpAddress(); + String targetIP = target.getDetails().getIpAddress(); + String playerMac = player.getDetails().getMacAddress(); + String targetMac = target.getDetails().getMacAddress(); + String playerHost = player.getDetails().getCompName(); + String targetHost = target.getDetails().getCompName(); + // Ironman trading exceptions for Shield of Arrav and Heroes Quest + if (item.getId() == 11174 || item.getId() == 11173 || item.getId() == 759 || item.getId() == 1586 || item.getId() == 1577) { + return true; + } + if (player.getIronmanManager().isIronman() || target != null && target.getIronmanManager().isIronman()) { + return false; + } + if ((playerIsBot || targetIsBot) && (playerIP.equals(targetIP) || playerMac.equals(targetMac) || playerHost.equals(targetHost))){ + sendMessage(player, colorize("%RYou can not trade items with your own bot accounts.")); + return false; + } + if (item.getName().equals("Coins") && item.getId() != 995) { + return false; + } + return definition.isTradeable(); + } + + /** + * Method used to check if the player can use the container. + * @return {@code True} if so. + */ + private boolean canUse() { + if (!player.getInterfaceManager().isOpened() || TradeModule.getExtension(player) == null || TradeModule.getExtension(TradeModule.getExtension(player).getTarget()) == null || TradeModule.getExtension(player).getStage() != 0) { + return false; + } + return true; + } + + /** + * Method used to check if the container has capacity for more items. + * @param item the item to remove or add. + * @param container the container to check capacity for. + * @return {@code True} if there is enough room. + */ + private boolean checkCapacity(final Item item, final Container container) { + if (item.getAmount() > container.getMaximumAdd(item)) { + item.setAmount(container.getMaximumAdd(item)); + if (item.getAmount() < 1) { + return false; + } + } + return true; + } + + /** + * Method used to send an alert icon. + * @param slot the slot. + * @param save if we should cache the icon. + */ + private void alert(final int slot, final boolean save) { + GameWorld.getPulser().submit(new Pulse(1, player) { + @Override + public boolean pulse() { + if (TradeModule.getExtension(player) != null) { + TradeModule.getExtension(player).alert(slot); + } + return true; + } + }); + if (save) { + player.setAttribute("alert", GameWorld.getTicks() + 8); + player.setAttribute("alertSlot", slot); + } + } + + /** + * Method used to check the alert. + */ + private void checkAlert() { + if (player.getAttribute("alert", 0) > GameWorld.getTicks()) { + alert(player.getAttribute("alertSlot", 0), false); + } + } + + /** + * Represents the container listener for a players trade session. + * @author 'Vexia + */ + public final class TradeListener implements ContainerListener { + + @Override + public void update(Container c, ContainerEvent event) {//type 541 - loaning + PacketRepository.send(ContainerPacket.class, new ContainerContext(player, -1, 64212, 90, c.toArray(), c.capacity(), false)); + if (TradeModule.getExtension(player) != null && TradeModule.getExtension(TradeModule.getExtension(player).getTarget()) != null) { + PacketRepository.send(ContainerPacket.class, new ContainerContext(player, 60981, -2, 91, TradeModule.getExtension(TradeModule.getExtension(player).getTarget()).getContainer().toArray(), 27, false)); + } + checkAlert(); + } + + @Override + public void refresh(Container c) { + PacketRepository.send(ContainerPacket.class, new ContainerContext(player, -1, 64209, 93, player.getInventory(), false)); + } + + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/player/link/request/trade/TradeModule.kt b/Server/src/main/core/game/node/entity/player/link/request/trade/TradeModule.kt new file mode 100644 index 0000000..3d0c844 --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/request/trade/TradeModule.kt @@ -0,0 +1,515 @@ +package core.game.node.entity.player.link.request.trade + +import core.game.component.Component +import core.game.container.Container +import core.game.container.ContainerType +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.request.RequestModule +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import core.game.bots.AIRepository +import content.global.bots.DoublingMoney +import core.game.node.entity.player.info.PlayerMonitor +import core.api.* +import java.text.DecimalFormat +import java.util.* + +/** + * Represents the module use to handle a request between trading of two players. + * @author Vexia + * @author dginovker + * @version 2.0 + */ +class TradeModule +/** + * Constructs a new `TradeModule` `Object`. + * @param player the player. + * @param target the target. + */(player: Player?, target: Player?) : RequestModule { + /** + * If the container has been retained. + */ + var isRetained = false + /** + * Represents the player instance. + */ + var player: Player? = player + private set + /** + * Represents the target instance. + */ + var target: Player? = target + private set + /** + * Represents the container of this session. + */ + var container: TradeContainer? = null + private set + /** + * Represents if this session has accepted. + */ + var isAccepted = false + private set + /** + * Represents if the trade is modified. + */ + var isModified = false + /** + * Represents the stage of the trade(0=started, 1=second accept) + */ + var stage = 0 + private set + + override fun open(player: Player?, target: Player?) { + extend(player, target) + if (getExtension(target) == null || getExtension(player) == null) { + return + } + getExtension(player)!!.openInterface(getInterface(stage)).display(stage) + if (getExtension(target) == null || getExtension(player) == null) { + return + } + getExtension(target)!!.openInterface(getInterface(stage)).display(stage) + player!!.dialogueInterpreter.close() + target!!.dialogueInterpreter.close() + } + + /** + * Method used to update the trade interfaces. + */ + fun update() { + display(stage) + getExtension(target)!!.display(stage) + } + + /** + * Method used to open an interface at a stage. + * @param component the component. + * @return the module instance for chaining. + */ + private fun openInterface(component: Component): TradeModule { + return if (component === MAIN_INTERFACE) openMain() else openSecond() + } + + /** + * Gets the accepting message to display. + * @return the message. + */ + private val acceptMessage: String + get() { + val otherAccept = getExtension(target)!!.isAccepted + return if (!otherAccept && !isAccepted) "" else if (otherAccept) "Other player has accepted." else "Waiting for other player..." + } + + /** + * Method used to display the interface display depending on stage. + * @param stage the stage. + * @return module the module instance for chaining. + */ + private fun display(stage: Int): TradeModule { + when (stage) { + 0 -> { + for (i in HIDDEN_CHILDS) { + player!!.packetDispatch.sendString("", MAIN_INTERFACE.id, i) + } + player!!.packetDispatch.sendString("Trading With: " + target!!.username, 335, 15) + player!!.packetDispatch.sendString( + target!!.username + " has " + (if (target!!.inventory.freeSlots() == 0) "no" else target!!.inventory.freeSlots()) + " free inventory slots.", + 335, + 21 + ) + player!!.packetDispatch.sendString(acceptMessage, 335, 36) + } + + 1 -> { + player!!.packetDispatch.sendString( + "Trading with:
" + "" + target!!.username.substring( + 0, + 1 + ).uppercase(Locale.getDefault()) + target!!.username.substring(1), 334, 2 + ) + val acceptMessage = acceptMessage + if (acceptMessage !== "") { + player!!.packetDispatch.sendString(acceptMessage, 334, 33) + } + player!!.interfaceManager.restoreTabs() + } + } + displayModified(stage) + container!!.update(true) + return this + } + + /** + * Gets the interface for the current stage. + * @param stage the stage, defaults to this TradeModule's stage. + * @return the component. + */ + fun getInterface(stage: Int = this.stage): Component { + return if (stage == 0) MAIN_INTERFACE else ACCEPT_INTERFACE + } + + /** + * Gets the interface for the TradeModule stage + * @return the component + */ + fun getInterface(): Component { + return getInterface(stage) + } + + /** + * Method used to display red text at the top of the trade window when the trade has been modified + * (Red text appears at the bottom in second trade screen) + * @param stage the sytage. + */ + private fun displayModified(stage: Int) { + val otherModified = getExtension(target)!!.isModified + if (stage == 0) { + // Main interface + if (otherModified) { + setVarp(player!!, 1043, 1) + } + if (isModified) { + setVarp(player!!, 1042, 1) + } + } else { + // Accept interface + player!!.packetDispatch.sendInterfaceConfig(334, 45, !isModified) + player!!.packetDispatch.sendInterfaceConfig(334, 46, !otherModified) + } + } + + /** + * Method used to display flashing alert if the trade has been modified. + * @param slot the slot. + */ + fun alert(slot: Int) { + player!!.packetDispatch.sendRunScript(143, "Iiii", *arrayOf(slot, 7, 4, 21954594)) + target!!.packetDispatch.sendRunScript(143, "Iiii", *arrayOf(slot, 7, 4, 21954593)) + } + + + /** + * Method used to decline this offer. + */ + fun decline() { + player!!.interfaceManager.close() + target!!.packetDispatch.sendMessage("Other player has declined trade!") + } + + /** + * Method used to check if the next stage can proceed. + */ + private fun nextStage() { + if (isAccepted && getExtension(target)!!.isAccepted) { + if (stage == 0) { + if (!hasSpace()) { + return + } + incrementStage() + openInterface(getInterface(stage)) + getExtension(target)!!.incrementStage() + getExtension(target)!!.openInterface(getInterface(stage)) + getExtension(target)!!.setAccepted(false, false) + setAccepted(false, false) + } else { + giveContainers(this) + incrementStage() + getExtension(target)!!.incrementStage() + getExtension(target)!!.setAccepted(false, false) + setAccepted(false, false) + player!!.interfaceManager.close() + return + } + } + update() + } + + /** + * Method used to open the main interface. + * @return the module instance for chaining. + */ + private fun openMain(): TradeModule { + player!!.interfaceManager.closeDefaultTabs() + player!!.interfaceManager.open(MAIN_INTERFACE) + player!!.interfaceManager.openSingleTab(OVERLAY_INTERFACE) + player!!.inventory.refresh() + player!!.packetDispatch.sendIfaceSettings(1278, 30, 335, 0, 27) + player!!.packetDispatch.sendIfaceSettings(1026, 32, 335, 0, 27) + player!!.packetDispatch.sendIfaceSettings(1278, 0, 336, 0, 27) + player!!.packetDispatch.sendIfaceSettings(2360446, 0, 335, 0, 27) + player!!.packetDispatch.sendRunScript(150, "IviiiIsssssssss", *INVENTORY_PARAMS) + player!!.packetDispatch.sendRunScript(150, "IviiiIsssssssss", *TRADE_PARAMS) + player!!.packetDispatch.sendRunScript(695, "IviiiIsssssssss", *PARTENER_PARAMS) + return this + } + + /** + * Method used to open the second interface. + * @return the module instance for chaining. + */ + private fun openSecond(): TradeModule { + player!!.interfaceManager.open(ACCEPT_INTERFACE) + player!!.interfaceManager.closeSingleTab() + displayOffer(container, 37) + displayOffer(getExtension(target)!!.container, 41) + return this + } + + /** + * Method used to set the value of accepted. + * @param accept whether the trade was accepted or declined + */ + fun setAccepted(accept: Boolean, update: Boolean) { + isAccepted = accept + if (update) { + nextStage() + } + } + + /** + * Method used to display an offer. + * @param container the container. + */ + private fun displayOffer(container: Container?, child: Int) { + val split = container!!.itemCount() > 14 + if (split) { + player!!.packetDispatch.sendInterfaceConfig(334, child + 1, false) + player!!.packetDispatch.sendInterfaceConfig(334, child + 2, false) + val messages = arrayOf( + getDisplayMessage(splitList(container.toArray(), 0, 14)), getDisplayMessage( + splitList( + container.toArray(), 14, container.toArray().size + ) + ) + ) + player!!.packetDispatch.sendString(messages[0], 334, child + 1) + player!!.packetDispatch.sendString(messages[1], 334, child + 2) + } else { + player!!.packetDispatch.sendInterfaceConfig(334, child, false) + player!!.packetDispatch.sendString(getDisplayMessage(container.toArray()), 334, child) + } + } + + /** + * Method used to get the display message. + * @param items the items. + * @return the message. + */ + private fun getDisplayMessage(items: Array): String { + var message = "Absolutely nothing!" + if (items.isNotEmpty()) { + message = "" + for (i in items.indices) { + if (items[i] == null) { + continue + } + message = message + "" + items[i]!!.name + if (items[i]!!.amount > 1) { + message = "$message x " + message = message + "" + getFormattedNumber(items[i]!!.amount) + "
" + } else { + message = "$message
" + } + } + } + return message + } + + /** + * Method used to check if the players & targets have enough space. + * @return `True` if so. + */ + private fun hasSpace(): Boolean { + var hasSpace = true + if (!player!!.inventory.hasSpaceFor(getExtension(target)!!.container)) { + target!!.packetDispatch.sendMessage("Other player doesn't have enough space in their inventory for this trade.") + player!!.packetDispatch.sendMessage("You don't have enough inventory space for this.") + hasSpace = false + } else if (!target!!.inventory.hasSpaceFor(container)) { + player!!.packetDispatch.sendMessage("Other player doesn't have enough space in their inventory for this trade.") + target!!.packetDispatch.sendMessage("You don't have enough inventory space for this.") + hasSpace = false + } + if (!hasSpace) { + setAccepted(false, true) + getExtension(target)!!.setAccepted(false, true) + } + return hasSpace + } + + /** + * Gets the formatted number. + * @param amount the amount. + * @return the formatted number. + */ + private fun getFormattedNumber(amount: Int): String { + return DecimalFormat("#,###,##0").format(amount.toLong()).toString() + } + + /** + * Method used to give the containers to each participants. + * @param module the module. + */ + private fun giveContainers(module: TradeModule) { + val pContainer: Container = module.container ?: return + val oContainer: Container = getExtension(module.target)!!.container ?: return + + PlayerMonitor.logTrade(module.player!!, module.target!!, pContainer, oContainer) + + (AIRepository.PulseRepository[module.player!!.username.lowercase()]?.botScript as DoublingMoney?)?.itemsReceived(module.target!!, oContainer) + (AIRepository.PulseRepository[module.target!!.username.lowercase()]?.botScript as DoublingMoney?)?.itemsReceived(module.player!!, pContainer) + + addContainer(module.player, oContainer) + addContainer(module.target, pContainer) + module.target!!.packetDispatch.sendMessage("Accepted trade.") + module.player!!.packetDispatch.sendMessage("Accepted trade.") + } + + /** + * Method used to add a container for a player. + * @param player the player who loses the items. + * @param target the target who gains the items. + * @param container the container. + */ + private fun addContainer(player: Player?, container: Container?) { + val c = Container(container!!.itemCount(), ContainerType.ALWAYS_STACK) + c.addAll(container) + for (i in container.toArray()) { + if (i == null) { + continue + } + if (i.amount > player!!.inventory.getMaximumAdd(i)) { + i.amount = player.inventory.getMaximumAdd(i) + } + if (!player.inventory.add(i)) { + GroundItemManager.create(i, player) + } + } + } + + /** + * Gets the split list as an array. + * @param items the items. + * @param min the min. + * @param max the max. + * @return the split item array. + */ + private fun splitList(items: Array, min: Int, max: Int): Array { + val list: MutableList = ArrayList(20) + for (i in min until max) { + if (items[i] == null) { + continue + } + list.add(items[i]) + } + val array = arrayOfNulls(list.size) + for (i in list.indices) { + if (list[i] == null) { + continue + } + array[i] = list[i] + } + return array + } + + /** + * Method used to increment the stage. + */ + fun incrementStage() { + stage++ + } + + companion object { + /** + * Represents the overlay interface component. + */ + val OVERLAY_INTERFACE = Component(336) + + /** + * Represents the main interface component. + */ + val MAIN_INTERFACE: Component = Component(335).setCloseEvent(TradeCloseEvent()) + + /** + * Represents the "accept" interface component. + */ + val ACCEPT_INTERFACE: Component = Component(334).setCloseEvent(TradeCloseEvent()) + + /** + * The inventory params for the runscript. + */ + val INVENTORY_PARAMS = arrayOf( + "", + "", + "", + "Lend", + "Offer-X", + "Offer-All", + "Offer-10", + "Offer-5", + "Offer", + -1, + 0, + 7, + 4, + 93, + 336 shl 16 + ) + + /** + * The trade params for the run script. + */ + val TRADE_PARAMS = arrayOf( + "", + "", + "", + "", + "Remove-X", + "Remove-All", + "Remove-10", + "Remove-5", + "Remove", + -1, + 0, + 7, + 4, + 90, + 335 shl 16 or 30 + ) + + /** + * The partener params for the run script. + */ + val PARTENER_PARAMS = arrayOf("", "", "", "", "", "", "", "", "", -1, 0, 7, 4, 91, 335 shl 16 or 32) + + /** + * Represents the childs that should be hidden. + */ + val HIDDEN_CHILDS = intArrayOf(42, 43, 44, 42, 44, 40, 41) + + /** + * Method used to extend the module for each participant. + * @param player the player. + * @param target the target. + */ + fun extend(player: Player?, target: Player?) { + player!!.addExtension(TradeModule::class.java, TradeModule(player, target)) + target!!.addExtension(TradeModule::class.java, TradeModule(target, player)) + } + + /** + * Method used to get the extension from the player. + * @param player the player. + * @return the module instance. + */ + @JvmStatic + fun getExtension(player: Player?): TradeModule? { + return player!!.getExtension(TradeModule::class.java) + } + } + + init { + container = TradeContainer(player) + } +} diff --git a/Server/src/main/core/game/node/entity/player/link/skillertasks/Difficulty.java b/Server/src/main/core/game/node/entity/player/link/skillertasks/Difficulty.java new file mode 100644 index 0000000..009e9f3 --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/skillertasks/Difficulty.java @@ -0,0 +1,5 @@ +package core.game.node.entity.player.link.skillertasks; + +public enum Difficulty { + NOVICE, INTERMEDIATE, ADVANCED, ELITE +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/player/link/skillertasks/SkillTasks.java b/Server/src/main/core/game/node/entity/player/link/skillertasks/SkillTasks.java new file mode 100644 index 0000000..4b6f0e5 --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/skillertasks/SkillTasks.java @@ -0,0 +1,68 @@ +package core.game.node.entity.player.link.skillertasks; + +import core.game.node.entity.skill.Skills; + +public enum SkillTasks { + + // Fishing + FANCHOVIES1("Fish Anchovies Novice", "You must successfully catch 230 Raw Anchovies.", Difficulty.NOVICE, 230, Skills.FISHING, 15), + FANCHOVIES2("Fish Anchovies Intermediate", "You must successfully catch 480 Raw Anchovies.", Difficulty.INTERMEDIATE, 480, Skills.FISHING, 15), + FHERRING1("Fish Herring Novice", "You must successfully catch 280 Raw Herring.", Difficulty.NOVICE, 280, Skills.FISHING, 10), + FHERRING2("Fish Herring Intermediate", "You must successfully catch 450 Raw Herring.", Difficulty.INTERMEDIATE, 450, Skills.FISHING, 10), + FLOBSTER1("Fish Lobster Intermediate", "You must successfully catch 300 Raw Lobster.", Difficulty.INTERMEDIATE, 300, Skills.FISHING, 40), + FLOBSTER2("Fish Lobster Advanced", "You must successfully catch 650 Raw Lobster.", Difficulty.ADVANCED, 650, Skills.FISHING, 40), + FSALMON1("Fish Salmon Novice", "You must successfully catch 220 Raw Salmon.", Difficulty.NOVICE, 220, Skills.FISHING, 30), + FSALMON2("Fish Salmon Intermediate", "You must successfully catch 400 Raw Salmon.", Difficulty.INTERMEDIATE, 400, Skills.FISHING, 30), + FSHARK1("Fish Shark Intermediate", "You must successfully catch 220 Raw Shark.", Difficulty.INTERMEDIATE, 220, Skills.FISHING, 76), + FSHARK2("Fish Shark Advanced", "You must successfully catch 380 Raw Shark.", Difficulty.ADVANCED, 380, Skills.FISHING, 76), + FSHARK3("Fish Shark Elite", "You must successfully catch 500 Raw Shark.", Difficulty.ELITE, 500, Skills.FISHING, 76), + FSHRIMP1("Fish Shrimp Novice", "You must successfully catch 300 Raw Shrimp.", Difficulty.NOVICE, 300, Skills.FISHING, 1), + FSHRIMP2("Fish Shrimp Intermediate", "You must successfully catch 500 Raw Shrimp.", Difficulty.INTERMEDIATE, 500, Skills.FISHING, 1), + FSWORD1("Fish Swordfish Intermediate", "You must successfully catch 320 Raw Swordfish.", Difficulty.INTERMEDIATE, 320, Skills.FISHING, 50), + FSWORD2("Fish Swordfish Advanced", "You must successfully catch 510 Raw Swordfish.", Difficulty.ADVANCED, 510, Skills.FISHING, 50), + FTROUT1("Fish Trout Novice", "You must successfully catch 250 Raw Trout.", Difficulty.NOVICE, 250, Skills.FISHING, 20), + FTROUT2("Fish Trout Intermediate", "You must successfully catch 420 Raw Trout.", Difficulty.INTERMEDIATE, 420, Skills.FISHING, 20), + FTUNA1("Fish Tuna Novice", "You must successfully catch 150 Raw Tuna.", Difficulty.NOVICE, 150, Skills.FISHING, 35), + FTUNA2("Fish Tuna Intermediate", "You must successfully catch 340 Raw Tuna.", Difficulty.INTERMEDIATE, 340, Skills.FISHING, 35); + + private String assignment; + private String description; + private Difficulty difficulty; + private int amount; + private int skill; + private int level; + + SkillTasks(String assignment, String description, Difficulty difficulty, int amount, int skill, int level) { + this.assignment = assignment; + this.description = description; + this.difficulty = difficulty; + this.amount = amount; + this.skill = skill; + this.level = level; + } + + public int getAmount() { + return amount; + } + + public String getAssignment() { + return assignment; + } + + public String getDescription() { + return description; + } + + public Difficulty getDifficulty() { + return difficulty; + } + + public int getLevel() { + return level; + } + + public int getSkill() { + return skill; + } + +} diff --git a/Server/src/main/core/game/node/entity/player/link/skillertasks/SkillerTasks.java b/Server/src/main/core/game/node/entity/player/link/skillertasks/SkillerTasks.java new file mode 100644 index 0000000..3fef140 --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/skillertasks/SkillerTasks.java @@ -0,0 +1,79 @@ +package core.game.node.entity.player.link.skillertasks; + +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.tools.RandomFunction; + +import java.util.ArrayList; + +public class SkillerTasks { + + public SkillTasks task; + public int taskAmount; + + public void decreaseTask(Player player, SkillTasks stask) { + player.getGlobalData().setTaskAmount(taskAmount); + if (!hasTask() || taskAmount == 0 || !task.getAssignment().equalsIgnoreCase(stask.getAssignment())) { + return; + } + taskAmount--; + if (taskAmount == 0) { + if (player.getSkillTasks().getCurrentTask().getDifficulty() == Difficulty.NOVICE) { + player.getGlobalData().setTaskPoints(player.getGlobalData().getTaskPoints() + 1); + player.getInventory().add(new Item(995, 10000)); + } else if (player.getSkillTasks().getCurrentTask().getDifficulty() == Difficulty.INTERMEDIATE) { + player.getGlobalData().setTaskPoints(player.getGlobalData().getTaskPoints() + 3); + player.getInventory().add(new Item(995, 30000)); + } else if (player.getSkillTasks().getCurrentTask().getDifficulty() ==Difficulty.ADVANCED) { + player.getGlobalData().setTaskPoints(player.getGlobalData().getTaskPoints() + 7); + player.getInventory().add(new Item(995, 70000)); + } else if (player.getSkillTasks().getCurrentTask().getDifficulty() ==Difficulty.ELITE) { + player.getGlobalData().setTaskPoints(player.getGlobalData().getTaskPoints() + 10); + player.getInventory().add(new Item(995, 100000)); + } + player.getSkillTasks().setCurrentTask(null); + player.sendMessage("Your task has been completed! Return to Jack for another assignment!"); + return; + } + } + + public SkillTasks getNewTask(Player player, Difficulty tier) { + final ArrayList tasks = new ArrayList(); + for (final SkillTasks t : SkillTasks.values()) { + if (player.getSkills().getExperienceByLevel(t.getSkill()) < t.getLevel()) { + continue; + } + if (t.getDifficulty() == tier) + tasks.add(t); + } + setCurrentTask(tasks.get(RandomFunction.random(tasks.size() - 1))); + setTaskAmount(task.getAmount()); + return task; + } + + public SkillTasks getCurrentTask() { + return task; + } + + public int getTaskAmount() { + return taskAmount; + } + + public boolean hasTask() { + return task != null; + } + + public boolean isCompleted() { + return hasTask() && taskAmount == 0; + } + + public void setCurrentTask(SkillTasks task) { + this.task = task; + } + + public void setTaskAmount(int amount) { + this.taskAmount = amount; + } + + +} diff --git a/Server/src/main/core/game/node/entity/player/link/spawn/PKPackage.java b/Server/src/main/core/game/node/entity/player/link/spawn/PKPackage.java new file mode 100644 index 0000000..2ffb2df --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/spawn/PKPackage.java @@ -0,0 +1,93 @@ +package core.game.node.entity.player.link.spawn; + +import core.game.node.item.Item; + +/** + * A pk package. + * + * @author Vexia + */ +public enum PKPackage { + + MELEE("Melee Set", 0, 2, new Item(4587), new Item(8850), new Item(10828), new Item(5698), new Item(7462), new Item(1712), new Item(4367), new Item(3105), new Item(1079), new Item(1127), new Item(995, 7000000), new Item(386, 220), new Item(2441, 20), new Item(2437, 20), new Item(2443, 20), new Item(2445, 20), new Item(6686, 10), new Item(3025, 10), new Item(2435, 15), new Item(9075, 320), new Item(560, 600), new Item(555, 3000), new Item(565, 450), new Item(557, 5000)), + RANGE_TANK("Range Tank Set", 0, 2, new Item(1712), new Item(2503), new Item(1079), new Item(7462), new Item(3105), new Item(9185), new Item(1201), new Item(10499), new Item(1163), new Item(9243, 30), new Item(9244, 14), new Item(9144, 100), new Item(892, 30), new Item(861), new Item(995, 7000000), new Item(386, 220), new Item(9075, 320), new Item(560, 600), new Item(555, 3000), new Item(565, 450), new Item(557, 5000), new Item(386, 220), new Item(2441, 20), new Item(2437, 20), new Item(2443, 20), new Item(2445, 20), new Item(6686, 10), new Item(3025, 10), new Item(2435, 15)), + MED_LEVEL("Med Level Set", 0, 1, new Item(1712), new Item(10828), new Item(7462), new Item(3105), new Item(4587), new Item(8850), new Item(1079), new Item(1127), new Item(5698), new Item(4675), new Item(3842), new Item(4111), new Item(4113), new Item(4409), new Item(995, 7000000), new Item(386, 220), new Item(2441, 20), new Item(2437, 20), new Item(2443, 20), new Item(2445, 20), new Item(6686, 10), new Item(3025, 10), new Item(2435, 15), new Item(9075, 320), new Item(9075, 320), new Item(560, 600), new Item(555, 3000), new Item(565, 450), new Item(557, 5000)), + PURE("Pure Set", 0, 1, new Item(6107), new Item(6108), new Item(7458), new Item(1712), new Item(4587), new Item(2413), new Item(3842), new Item(6109), new Item(9144, 130), new Item(3105), new Item(10499), new Item(4675), new Item(9185), new Item(5698), new Item(995, 7000000), new Item(386, 220), new Item(2441, 20), new Item(2437, 20), new Item(2443, 20), new Item(2445, 20), new Item(6686, 10), new Item(3025, 10), new Item(2435, 15), new Item(740, 1), new Item(560, 600), new Item(555, 3000), new Item(565, 450), new Item(2497, 1)), + ZERKER("Zerker Set", 0, 2, new Item(4587), new Item(8850), new Item(3751), new Item(5698), new Item(7462), new Item(1712), new Item(4385), new Item(3105), new Item(1079), new Item(1127), new Item(995, 7000000), new Item(386, 220), new Item(2441, 20), new Item(2437, 20), new Item(2443, 20), new Item(2445, 20), new Item(6686, 10), new Item(3025, 10), new Item(2435, 15), new Item(9075, 320), new Item(560, 600), new Item(555, 3000), new Item(565, 450), new Item(557, 5000)), + SHARKS("Sharks", 1, -1, new Item(385, 28)), + SUPER_POT("Super Potions", 1, -1, new Item(2436), new Item(2440), new Item(6685, 2)), + SUPER_RESTORE("Super Restores", 1, -1, new Item(3024, 3), new Item(6685, 3)), + RANGING_POTS("Ranging Potions", 1, -1, new Item(2444, 2)), + BARRAGE_RUNE("Barrage Runes", 1, -1, new Item(560, 5000), new Item(565, 5000), new Item(555, 5000)), + VENGEANCE_RUNE("Vengeance Runes", 1, -1, new Item(557, 10000), new Item(9075, 5000), new Item(560, 5000)), + ENTANGE_RUNE("Entangle Runes", 1, -1, new Item(557, 10000), new Item(555, 5000), new Item(561, 5000)); + + /** + * The name. + */ + private final String name; + + /** + * The package type. + */ + private int type; + + /** + * The spell book. + */ + private int spellBook; + + /** + * The items in the package. + */ + private final Item[] items; + + /** + * Constructs a new {@Code PKPackage} {@Code Object} + * + * @param name the name. + * @param items the items. + */ + PKPackage(String name, int type, int spellBook, Item... items) { + this.name = name; + this.type = type; + this.spellBook = spellBook; + this.items = items; + } + + /** + * Gets the spell book. + * + * @return the spell book. + */ + public int getSpellBook() { + return spellBook; + } + + /** + * Gets the type. + * + * @return the type. + */ + public int getType() { + return type; + } + + /** + * Gets the name. + * + * @return the name. + */ + public String getName() { + return name; + } + + /** + * Gets the items. + * + * @return the items. + */ + public Item[] getItems() { + return items; + } +} diff --git a/Server/src/main/core/game/node/entity/skill/LevelUp.java b/Server/src/main/core/game/node/entity/skill/LevelUp.java new file mode 100644 index 0000000..c9e23d8 --- /dev/null +++ b/Server/src/main/core/game/node/entity/skill/LevelUp.java @@ -0,0 +1,196 @@ +package core.game.node.entity.skill; + +import core.game.component.Component; +import core.game.global.Skillcape; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.emote.Emotes; +import core.game.world.repository.Repository; +import core.net.packet.PacketRepository; +import core.net.packet.context.MusicContext; +import core.net.packet.out.MusicPacket; + +import static core.api.ContentAPIKt.*; +import static core.game.node.entity.skill.LevelUpJinglesKt.getSkillJingle; + + +/** + * Represents a leveling up reward. + * @author Emperor + */ +public final class LevelUp { + + /** + * The skillcapes data. + */ + private static final int[] SKILLCAPES = { 9747, // Attack + 9753, // Defence + 9750, // Strength + 9768, // Hitpoints + 9756, // Range + 9759, // Prayer + 9762, // Magic + 9801, // Cooking + 9807, // Woodcutting + 9783, // Fletching + 9798, // Fishing + 9804, // Firemaking + 9780, // Crafting + 9795, // Smithing + 9792, // Mining + 9774, // Herblore + 9771, // Agility + 9777, // Thieving + 9786, // Slayer + 9810, // Farming + 9765, // Runecrafting + 9948, // Hunter + 9789, // Construction + 12169 // Summoning + }; + + /** + * The skill icon config values send on the level up chat box interface. + */ + public static final int[] SKILL_ICON = { 67108864, 335544320, 134217728, + 402653184, 201326592, 469762048, 268435456, 1073741824, 1207959552, + 1275068416, 1006632960, 1140850688, 738197504, 939524096, + 872415232, 603979776, 536870912, 671088640, 1342177280, 1409286144, + 805306368, 1543503872, 1476395008, 1610612736, 1677721600 }; + + /** + * The flashing icon config values on level up. + */ + public static final int[] FLASH_ICONS = { 1, 4, 2, 64, 8, 16, 32, 32768, + 131072, 2048, 16384, 65536, 1024, 8192, 4096, 256, 128, 512, + 524288, 1048576, 262144, 4194304, 2097152, 8388608, 16777216 }; + + + /** + * Holds all the config values of the skill advances. + */ + public static final int[] ADVANCE_CONFIGS = { + 9, 40, 17, 49, + 25, 57, 33, 641, + 659, 664, 121, 649, + 89, 114, 107, 72, + 64, 80, 673, 680, + 99, 698, 689, 705, + }; + + /** + * The client skill ids. + */ + public static final int[] CLIENT_ID = { + 1, 5, 2, 6, + 3, 7, 4, 16, + 18, 19, 15, 17, + 11, 14, 13, 9, + 8, 10, 20, 21, + 12, 23, 22, 24, + 24 + }; + + /** + * The skilling milestones. + */ + public static final int[] SKILL_MILESTONES = { + 1, 50, 75, 100 + }; + + /** + * The combat milestones. + */ + public static final int[] COMBAT_MILESTONES = { + 3, 5, 10, 15, 25, 75, 90, 100, 110, 120, 126, 130, 138 + }; + + /** + * Sends the level up interface etc. + * @param player The player. + * @param slot The skill slot. + * @param amount The amount of levels gained. + */ + public static void levelup(Player player, int slot, int amount) { + if (!player.getAttribute("tutorial:complete", false)) { + return; + } + playJingle(player, getSkillJingle(player, slot)); + handleMilestones(player, slot, amount); + player.getPacketDispatch().sendGraphic(199); + player.getPacketDispatch().sendString("Congratulations, you've just advanced a " + Skills.SKILL_NAME[slot] + " level!", 740, 0); + player.getPacketDispatch().sendString("Your " + Skills.SKILL_NAME[slot] + " level is now " + player.getSkills().getStaticLevel(slot) + ".", 740, 1); + player.getPacketDispatch().sendMessage("You've just advanced a " + Skills.SKILL_NAME[slot] + " level! You have reached level " + player.getSkills().getStaticLevel(slot) + "."); + if (slot == Skills.PRAYER) { + player.getSkills().incrementPrayerPoints(1); + } + if (player.getSkills().getStaticLevel(slot) == 99 && !player.isArtificial()) { + Repository.sendNews(player.getUsername() + " has just achieved level 99 " + Skills.SKILL_NAME[slot] + "!"); + Skillcape.trim(player); + player.getEmoteManager().unlock(Emotes.SKILLCAPE); + if (player.skills.getTotalLevel() == 2376) + { + sendNews(player.getUsername() + " has just achieved level 99 in all skills!"); + } + } + player.setAttribute("/save:levelup:" + slot, true); + sendFlashingIcons(player, slot); + } + + /** + * Handles the milestones. + * @param player The player. + * @param slot The id of the leveled skill. + * @param amount The amount of levels gained. + */ + public static void handleMilestones(Player player, int slot, int amount) { + int value = ADVANCE_CONFIGS[slot]; + for (int i = 0; i < COMBAT_MILESTONES.length; i++) { + if (player.getProperties().getCurrentCombatLevel() < COMBAT_MILESTONES[i]) { + if (i > player.getSkills().getCombatMilestone()) { + value |= 0x2; + player.getSkills().setCombatMilestone(i); + } + break; + } + } + int totalLevel = player.getSkills().getTotalLevel(); + for (int i = 0; i < SKILL_MILESTONES.length; i++) { + if (totalLevel < SKILL_MILESTONES[i]) { + if (i > player.getSkills().getSkillMilestone()) { + value |= 0x4; + player.getSkills().setSkillMilestone(i); + } + break; + } + } + value |= player.getSkills().getCombatMilestone() << 23; //Combat level milestone index. + value |= player.getSkills().getSkillMilestone() << 27; //Total level milestone index + setVarp(player, 1230, value); + } + + /** + * Sends the flashing icons and level up interface (if slot is larger than -1). + * @param player The player. + * @param slot The currently level skill id (-1 for just sending flashing icons). + */ + public static void sendFlashingIcons(Player player, int slot) { + int value = 0; + for (int i = 0; i < Skills.SKILL_NAME.length; i++) { + if (player.getAttribute("levelup:" + i, false)) { + value |= FLASH_ICONS[i]; + } + } + if (slot > -1) { + value |= SKILL_ICON[slot]; + player.getInterfaceManager().openChatbox(new Component(740)); + } + setVarp(player, 1179, value); + } + + /** + * @return the skillcapes + */ + public static int[] getSkillcapes() { + return SKILLCAPES; + } +} diff --git a/Server/src/main/core/game/node/entity/skill/LevelUpJingles.kt b/Server/src/main/core/game/node/entity/skill/LevelUpJingles.kt new file mode 100644 index 0000000..a02a09e --- /dev/null +++ b/Server/src/main/core/game/node/entity/skill/LevelUpJingles.kt @@ -0,0 +1,63 @@ +package core.game.node.entity.skill + +import core.api.getStatLevel +import core.game.node.entity.player.Player + +/** + * Skill levels with unlocks + **/ + +private val attack: IntArray = intArrayOf(5, 10, 15, 20, 30, 40, 50, 60, 70, 75 ,78, 99) +private val mining: IntArray = intArrayOf(6, 10, 15, 20, 21, 30, 31, 35, 40, 41, 45, 46, 50, 55, 60, 70, 80, 85, 90, 99) +private val smithing: IntArray = intArrayOf(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 68, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99) +private val defence: IntArray = intArrayOf(5, 10, 20, 25, 30, 40, 45, 50, 55, 60, 65, 70, 75, 78, 80, 99) +private val herblore: IntArray = intArrayOf(3, 5, 8, 11, 12, 19, 20, 22, 25, 26, 30, 31, 34, 35, 36, 38, 39, 40, 44, 45, 48, 50, 52, 53, 54, 55, 57, 59, 60, 63, 65, 66, 67, 68, 69, 70, 72, 73, 75, 76, 78, 80, 81, 82, 99) +private val fishing: IntArray = intArrayOf(5, 10, 15, 16, 20, 23, 25, 28, 30, 33, 35, 38, 40, 46, 48, 50, 53, 55, 58, 62, 65, 68, 70, 76, 79, 81, 90, 96, 99) +private val ranged: IntArray = intArrayOf(5, 10, 16, 19, 20, 21, 25, 26, 28, 31, 30, 33, 35, 36, 37, 39, 40, 42, 45, 46, 50, 55, 60, 61, 65, 70, 78, 80, 99) +private val thieving: IntArray = intArrayOf(2, 5, 10, 13, 15, 20, 22, 25, 27, 28, 30, 32, 35, 36, 38, 40, 42, 43, 44, 45, 47, 49, 50, 52, 53, 55, 59, 63, 65, 70, 72, 75, 78, 80, 82, 85, 99) +private val cooking: IntArray = intArrayOf(4, 5, 6, 7, 8, 10, 11, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 28, 29, 30, 31, 32, 33, 34, 35, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 53, 54, 55, 57, 58, 59, 60, 62, 64, 65, 67, 68, 70, 80, 82, 85, 91, 95, 99) +private val prayer: IntArray = intArrayOf(2, 4, 7, 8, 9, 10, 13, 16, 19, 22, 25, 26, 28, 31, 34, 35, 37, 40, 43, 44, 45, 46, 49, 52, 60, 70, 85, 90, 99) +private val crafting: IntArray = intArrayOf(3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 60, 62, 63, 64, 66, 67, 68, 70, 71, 73, 74, 75, 77, 79, 80, 82, 84, 85, 87, 90, 99) +private val firemaking: IntArray = intArrayOf(4, 5, 11, 12, 15, 20, 21, 25, 26, 30, 33, 35, 40, 42, 43, 45, 47, 48, 49, 50, 52, 53, 55, 58, 59, 60, 62, 63, 65, 68, 70, 72, 75, 76, 78, 79, 80, 83, 85, 87, 89, 92, 95, 99) +private val magic: IntArray = intArrayOf(4, 5, 7, 9, 11, 13, 14, 15, 17, 19, 20, 21, 23, 24, 25, 27, 29, 30, 31, 32, 33, 35, 37, 39, 40, 43, 45, 47, 49, 50, 51, 52, 53, 54, 55, 56, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 90, 91, 92, 93, 94, 95, 96, 97, 99) +private val fletching: IntArray = intArrayOf(5, 7, 9, 10, 11, 15, 18, 20, 22, 24, 25, 26, 30, 32, 33, 35, 37, 38, 39, 40, 41, 42, 43, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 55, 56, 58, 59, 60, 61, 62, 63, 65, 67, 69, 70, 71, 73, 75, 77, 80, 81, 85, 90, 95, 99) +private val woodcutting: IntArray = intArrayOf(6, 10, 12, 15, 20, 21, 27, 30, 31, 35, 37, 40, 41, 42, 44, 45, 50, 54, 56, 57, 58, 60, 61, 75, 80, 82, 99) +private val runecrafting: IntArray = intArrayOf(2, 5, 6, 9, 10, 11, 13, 14, 15, 19, 20, 22, 23, 26, 27, 28, 33, 35, 38, 40, 42, 44, 46, 52, 54, 55, 56, 57, 59, 65, 66, 70, 74, 76, 77, 78, 82, 84, 91, 92, 95, 98, 99) +private val slayer: IntArray = intArrayOf(5, 7, 10, 15, 17, 20, 22, 25, 30, 32, 33, 35, 37, 39, 40, 42, 45, 47, 50, 51, 52, 55, 56, 57, 58, 59, 60, 63, 65, 68, 70, 72, 75, 80, 83, 85, 90, 99) +private val farming: IntArray = intArrayOf(2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 36, 38, 39, 42, 44, 45, 47, 48, 50, 51, 52, 53, 55, 56, 57, 59, 60, 62, 63, 67, 68, 70, 72, 73, 75, 79, 83, 85, 99) + +/** + * Gets the jingleId to play based on skill slot id and skill level + * @param player the player + * @param slot the skill slot id + **/ +fun getSkillJingle(player: Player, slot: Int) : Int { + val skillLevel = getStatLevel(player, slot) + when (slot) { + 0 -> return if (attack.contains(skillLevel)) 30 else 29 + 1 -> return if (defence.contains(skillLevel)) 38 else 37 + 2 -> return if (skillLevel < 50) 65 else 66 //Strength + 3 -> return if (skillLevel < 50) 47 else 48 //Hitpoints + 4 -> return if (ranged.contains(skillLevel)) 58 else 57 + 5 -> return if (prayer.contains(skillLevel)) 56 else 55 + 6 -> return if (magic.contains(skillLevel)) 52 else 51 + 7 -> return if (cooking.contains(skillLevel)) 34 else 33 + 8 -> return if (woodcutting.contains(skillLevel)) 70 else 69 + 9 -> return if (fletching.contains(skillLevel)) 44 else 43 + 10 -> return if (fishing.contains(skillLevel)) 42 else 41 + 11 -> return if (firemaking.contains(skillLevel)) 40 else 39 + 12 -> return if (crafting.contains(skillLevel)) 36 else 35 + 13 -> return if (smithing.contains(skillLevel)) 64 else 63 + 14 -> return if (mining.contains(skillLevel)) 54 else 53 + 15 -> return if (herblore.contains(skillLevel)) 46 else 45 + 16 -> return 28 //Agility + 17 -> return if (thieving.contains(skillLevel)) 68 else 67 + 18 -> return if (slayer.contains(skillLevel)) 62 else 61 + 19 -> return if (farming.contains(skillLevel)) 11 else 10 + 20 -> return if (runecrafting.contains(skillLevel)) 60 else 59 + 21 -> return if ((skillLevel % 2 == 0)) 49 else 50 //Hunter + 22 -> return if ((skillLevel % 10 == 0)) 31 else 32 //Construction + 23 -> return if ((skillLevel < 50)) 300 else 301 //Summoning + } + return 40 +} diff --git a/Server/src/main/core/game/node/entity/skill/SkillBonus.java b/Server/src/main/core/game/node/entity/skill/SkillBonus.java new file mode 100644 index 0000000..3111eaa --- /dev/null +++ b/Server/src/main/core/game/node/entity/skill/SkillBonus.java @@ -0,0 +1,66 @@ +package core.game.node.entity.skill; + +/** + * Represents a skill bonus. + * @author Emperor + */ +public final class SkillBonus { + + /** + * The skill id. + */ + private final int skillId; + + /** + * The bonus. + */ + private final double bonus; + + /** + * The base bonus (in levels). + */ + private final int baseBonus; + + /** + * Constructs a new {@code SkillBonus} {@code Object}. + * @param skillId The skill id. + * @param bonus The bonus. + */ + public SkillBonus(int skillId, double bonus) { + this(skillId, bonus, 0); + } + + /** + * Constructs a new {@code SkillBonus} {@code Object}. + * @param skillId The skill id. + * @param bonus The bonus. + * @param baseBonus The base bonus in levels. + */ + public SkillBonus(int skillId, double bonus, int baseBonus) { + this.skillId = skillId; + this.bonus = bonus; + this.baseBonus = baseBonus; + } + + /** + * @return the skillId. + */ + public int getSkillId() { + return skillId; + } + + /** + * @return the bonus. + */ + public double getBonus() { + return bonus; + } + + /** + * @return the baseBonus. + */ + public int getBaseBonus() { + return baseBonus; + } + +} diff --git a/Server/src/main/core/game/node/entity/skill/SkillPulse.java b/Server/src/main/core/game/node/entity/skill/SkillPulse.java new file mode 100644 index 0000000..4f349b9 --- /dev/null +++ b/Server/src/main/core/game/node/entity/skill/SkillPulse.java @@ -0,0 +1,105 @@ +package core.game.node.entity.skill; + +import content.global.skill.gather.SkillingResource; +import content.data.skill.SkillingTool; +import core.game.node.Node; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.update.flag.context.Animation; + +/** + * Pulse class specifically used for Skills. + * @author Emperor + */ +public abstract class SkillPulse extends Pulse { + + /** + * The player. + */ + protected final Player player; + + /** + * The node. + */ + protected T node; + + /** + * The tool used. + */ + protected SkillingTool tool; + + /** + * The resource. + */ + protected SkillingResource resource; + + /** + * If we should reset the anim at the end. + */ + protected boolean resetAnimation = true; + + /** + * Constructs a new {@code SkillPulse} {@code Object}. + * @param player The player. + * @param node The node. + */ + public SkillPulse(Player player, T node) { + super(1, player, node); + this.player = player; + this.node = node; + super.stop(); + } + + @Override + public void start() { + if (checkRequirements()) { + super.start(); + message(0); + } + } + + @Override + public boolean pulse() { + if (!checkRequirements()) { + return true; + } + animate(); + return reward(); + } + + @Override + public void stop() { + if (resetAnimation) { + player.animate(new Animation(-1, Priority.HIGH)); + } + super.stop(); + message(1); + } + + /** + * Checks if the player meets all the requirements. + * @return {@code True} if the player can continue, {@code false} if not. + */ + public abstract boolean checkRequirements(); + + /** + * Sends the animations related to the actions the player is doing. + */ + public abstract void animate(); + + /** + * Rewards the player. + * @return {@code True} if the player should stop this skilling pulse. + */ + public abstract boolean reward(); + + /** + * Sends a message to the player. + * @param type The message type (0: start message, 1: stop message). + */ + public void message(int type) { + + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/entity/skill/Skills.java b/Server/src/main/core/game/node/entity/skill/Skills.java new file mode 100644 index 0000000..19debcc --- /dev/null +++ b/Server/src/main/core/game/node/entity/skill/Skills.java @@ -0,0 +1,948 @@ +package core.game.node.entity.skill; + +import content.global.skill.skillcapeperks.SkillcapePerks; +import core.ServerConstants; +import core.game.event.DynamicSkillLevelChangeEvent; +import core.game.event.XPGainEvent; +import content.global.handlers.item.equipment.brawling_gloves.BrawlingGloves; +import content.global.handlers.item.equipment.brawling_gloves.BrawlingGlovesManager; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.ImpactHandler; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.request.assist.AssistSession; +import core.game.node.item.Item; +import core.net.packet.PacketRepository; +import core.net.packet.context.SkillContext; +import core.net.packet.out.SkillLevel; +import kotlin.Pair; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import core.game.node.entity.player.info.PlayerMonitor; +import core.game.world.GameWorld; +import core.game.world.repository.Repository; +import core.plugin.CorePluginTypes.XPGainPlugins; +import org.rs09.consts.Items; +import org.rs09.consts.Sounds; + +import java.util.ArrayList; + +import static core.api.ContentAPIKt.getWorldTicks; +import static core.api.ContentAPIKt.playAudio; +import static java.lang.Math.floor; +import static java.lang.Math.max; + +/** + * Represents an entity's skills. + * @author Emperor + */ +public final class Skills { + + /** + * Represents the constant modifier of experience. + */ + public double experienceMultiplier = 5.0; + + /** + * The maximum experience multiplier. + */ + public static final double MAX_EXPERIENCE_MOD = 60.0; + + /** + * Represents an array of skill names. + */ + public static final String[] SKILL_NAME = { "Attack", "Defence", "Strength", "Hitpoints", "Ranged", "Prayer", "Magic", "Cooking", "Woodcutting", "Fletching", "Fishing", "Firemaking", "Crafting", "Smithing", "Mining", "Herblore", "Agility", "Thieving", "Slayer", "Farming", "Runecrafting", "Hunter", "Construction", "Summoning" }; + + /** + * Constants for the skill ids. + */ + public static final int ATTACK = 0, DEFENCE = 1, STRENGTH = 2, HITPOINTS = 3, RANGE = 4, PRAYER = 5, MAGIC = 6, COOKING = 7, WOODCUTTING = 8, FLETCHING = 9, FISHING = 10, FIREMAKING = 11, CRAFTING = 12, SMITHING = 13, MINING = 14, HERBLORE = 15, AGILITY = 16, THIEVING = 17, SLAYER = 18, FARMING = 19, RUNECRAFTING = 20, HUNTER = 21, CONSTRUCTION = 22, SUMMONING = 23; + + /** + * Number of skills in game + */ + public static final int NUM_SKILLS = 24; + + /** + * Represents the entity instance. + */ + private final Entity entity; + + /** + * An array containing all the player's experience. + */ + private final double[] experience; + + private double[] lastUpdateXp = null; + + private int lastUpdate = GameWorld.getTicks(); + + /** + * An array containing all the maximum levels. + */ + private final int[] staticLevels; + + /** + * An array containing all the current levels. + */ + private final int[] dynamicLevels; + + /** + * Represents the amount of prayer points left. + */ + private double prayerPoints = 1.; + + /** + * The player's life-points. + */ + private int lifepoints = 10; + + /** + * The amount of increased maximum lifepoints. + */ + private int lifepointsIncrease = 0; + + /** + * The total experience gained. + */ + private double experienceGained = 0; + + /** + * If a lifepoints update should occur. + */ + private boolean lifepointsUpdate; + + /** + * The combat milestones. + */ + private int combatMilestone; + + /** + * The skilling milestones. + */ + private int skillMilestone; + + public int lastTrainedSkill = -1; + public int lastXpGain = 0; + + /** + * Constructs a new {@code Skills} {@code Object}. + * @param entity The entity. + */ + public Skills(Entity entity) { + this.entity = entity; + this.experience = new double[24]; + this.staticLevels = new int[24]; + this.dynamicLevels = new int[24]; + for (int i = 0; i < 24; i++) { + this.staticLevels[i] = 1; + this.dynamicLevels[i] = 1; + } + this.experience[HITPOINTS] = 1154; + this.dynamicLevels[HITPOINTS] = 10; + this.staticLevels[HITPOINTS] = 10; + entity.getProperties().setCombatLevel(3); + } + + + /** + * Determine whether the specified skill is a combat skill. + * Prayer and Summoning are included and counted as combat skills. + * @param skill + * @return true if so. + */ + public boolean isCombat(int skill){ + if((skill >= ATTACK && skill <= MAGIC) || (skill == SUMMONING)){ + return true; + } + return false; + } + + /** + * Configures the skills. + */ + public void configure() { + updateCombatLevel(); + } + + /** + * Called every pulse (600ms). + */ + public void pulse() { + if (lifepoints < 1) { + return; + } + } + + /** + * Copies the skills data. + * @param skills The skills. + */ + public void copy(Skills skills) { + for (int i = 0; i < 24; i++) { + this.staticLevels[i] = skills.staticLevels[i]; + this.dynamicLevels[i] = skills.dynamicLevels[i]; + this.experience[i] = skills.experience[i]; + } + prayerPoints = skills.prayerPoints; + lifepoints = skills.lifepoints; + lifepointsIncrease = skills.lifepointsIncrease; + experienceGained = skills.experienceGained; + } + + /** + * Adds experience to a skill. + * @param slot The skill slot. + * @param experience The experience. + */ + public void addExperience(int slot, double experience, boolean playerMod) { + if (lastUpdateXp == null) + lastUpdateXp = this.experience.clone(); + double mod = getExperienceMod(slot, experience, playerMod, true); + final Player player = entity instanceof Player ? ((Player) entity) : null; + final AssistSession assist = entity.getExtension(AssistSession.class); + if (assist != null && assist.translateExperience(player, slot, experience, mod)) { + return; + } + boolean already200m = this.experience[slot] == 200000000; + double experienceAdd = (experience * mod); + //check if a player has brawling gloves and, if equipped, modify xp + BrawlingGlovesManager bgManager = BrawlingGlovesManager.getInstance(player); + if(!bgManager.GloveCharges.isEmpty()){ + Item gloves = BrawlingGloves.forSkill(slot) == null ? null : new Item(BrawlingGloves.forSkill(slot).getId()); + if(gloves == null && (slot == Skills.STRENGTH || slot == Skills.DEFENCE)){ + gloves = new Item (BrawlingGloves.forSkill(Skills.ATTACK).getId()); + } + if(gloves != null && player.getEquipment().containsItem(gloves)){ + experienceAdd += experienceAdd * bgManager.getExperienceBonus(); + bgManager.updateCharges(gloves.getId(),1); + } + } + //Check for Flame Gloves and Ring of Fire + if(player.getEquipment().containsItem(new Item(Items.FLAME_GLOVES_13660)) || player.getEquipment().containsItem(new Item(Items.RING_OF_FIRE_13659))){ + if(slot == Skills.FIREMAKING){ + int count = 0; + if(player.getEquipment().containsItem(new Item(Items.FLAME_GLOVES_13660))) count += 1; + if(player.getEquipment().containsItem(new Item(Items.RING_OF_FIRE_13659))) count += 1; + if(count == 2) experienceAdd += (0.05 * experienceAdd); + else experienceAdd += (0.02 * experienceAdd); + } + } + this.experience[slot] += experienceAdd; + if (this.experience[slot] >= 200000000) { + if(!already200m && !player.isArtificial()){ + Repository.sendNews(entity.asPlayer().getUsername()+" has just reached 200m experience in " + SKILL_NAME[slot] + "!"); + } + this.experience[slot] = 200000000; + } + if (entity instanceof Player && this.experience[slot] > 175) { + if (!player.getAttribute("tutorial:complete",false) && slot != HITPOINTS) { + this.experience[slot] = 175; + } + } + experienceGained += experienceAdd; + XPGainPlugins.run(player,slot,experienceAdd); + int newLevel = getStaticLevelByExperience(slot); + if (newLevel > staticLevels[slot]) { + int amount = newLevel - staticLevels[slot]; + if (dynamicLevels[slot] < newLevel) { + dynamicLevels[slot] += amount; + } + if (slot == HITPOINTS) { + lifepoints += amount; + } + staticLevels[slot] = newLevel; + + if (entity instanceof Player) { + player.updateAppearance(); + LevelUp.levelup(player, slot, amount); + updateCombatLevel(); + } + } + if (entity instanceof Player) { + PacketRepository.send(SkillLevel.class, new SkillContext((Player) entity, slot)); + entity.dispatch(new XPGainEvent(slot, experienceAdd)); + } + if (GameWorld.getTicks() - lastUpdate >= 200) { + ArrayList> diffs = new ArrayList<>(); + for (int i = 0; i < this.experience.length; i++) { + double diff = this.experience[i] - lastUpdateXp[i]; + if (diff != 0.0) { + diffs.add(new Pair<>(i, diff)); + } + } + PlayerMonitor.logXpGains(player, diffs); + lastUpdateXp = this.experience.clone(); + lastUpdate = GameWorld.getTicks(); + } + lastTrainedSkill = slot; + lastXpGain = getWorldTicks(); + } + + /** + * Gets the current experience mod. + * @param slot The skill slot. + * @param experience The experience gained. + * @param playerMod If player mods should be applied. + * @return The experience mod. + */ + private double getExperienceMod(int slot, double experience, boolean playerMod, boolean multiplyer) { + //Keywords for people ctrl + Fing the project + //xprate xp rate xp multiplier skilling rate + return experienceMultiplier; + /*if (!(entity instanceof Player)) { + return 1.0; + } + double mod = multiplyer ? (EXPERIENCE_MULTIPLIER) : 1; + Player p = (Player) entity; + if (p.getIronmanManager().getMode() == IronmanMode.ULTIMATE) { + mod /= 4; + } else if (p.getIronmanManager().getMode() == IronmanMode.STANDARD) { + mod /= 2; + } + //A boost for combat skills that are under level 65. + if(entity instanceof Player && !this.hasLevel(slot, 65) && isCombat(slot)){ + mod *= 1.5; + } + //Grand Exchange region XP boost. + if(entity.getViewport().getRegion().getRegionId() == 12598){ + mod += 1.5; + } + // Pest control, XP halved during the game + if (entity.getViewport().getRegion().getRegionId() == 10536) { + mod *= .5; + } + if (SystemManager.getSystemConfig().isDoubleExp()) { + mod *= 2; + } + if (HolidayEvent.getCurrent() != null) { + HolidayEvent.getCurrent().addExperience(p, slot, experience); + } + p.getAntiMacroHandler().registerExperience(slot, experience); + if (TutorialSession.getExtension(p).getStage() < TutorialSession.MAX_STAGE) { + mod = 1.0; + } else { + if (playerMod && p.getExperienceMod() != 0.0) { + mod *= p.getExperienceMod(); + } + } + if (mod > MAX_EXPERIENCE_MOD ) { + return MAX_EXPERIENCE_MOD; + } + return mod;*/ + } + + /** + * Adds experience to the skills. + */ + public void addExperience(final int slot, double experience) { + addExperience(slot, experience, false); + } + + /** + * Gets the highest combat skill id. + * @return The id of the highest combat skill. + */ + public int getHighestCombatSkillId() { + int id = 0; + int last = 0; + for (int i = 0; i < 5; i++) { + if (staticLevels[i] > last) { + last = staticLevels[i]; + id = i; + } + } + return id; + } + + /** + * Returns the dynamic levels to the static levels + */ + public void restore() { + for (int i = 0; i < 24; i++) { + int staticLevel = getStaticLevel(i); + setLevel(i, staticLevel); + } + if (entity instanceof Player) { + playAudio(entity.asPlayer(), Sounds.PRAYER_RECHARGE_2674); + } + rechargePrayerPoints(); + } + + public void parse(JSONArray skillData){ + for(int i = 0; i < skillData.size(); i++){ + JSONObject skill = (JSONObject) skillData.get(i); + int id = Integer.parseInt( skill.get("id").toString()); + dynamicLevels[id] = Integer.parseInt(skill.get("dynamic").toString()); + staticLevels[id] = Integer.parseInt(skill.get("static").toString()); + experience[id] = Double.parseDouble(skill.get("experience").toString()); + int version = entity instanceof Player ? entity.asPlayer().version : ServerConstants.CURRENT_SAVEFILE_VERSION; + if (i == HITPOINTS) { + if (version < 3 && !skill.containsKey("lifepoints")) { //!1881 + lifepoints = dynamicLevels[id]; + dynamicLevels[id] = staticLevels[id]; + } else { + lifepoints = Integer.parseInt(skill.get("lifepoints").toString()); + } + } + if (i == PRAYER) { + if (version < 3 && !skill.containsKey("prayerPoints")) { //!1881 + prayerPoints = dynamicLevels[id]; + dynamicLevels[id] = staticLevels[id]; + } else { + prayerPoints = Double.parseDouble(skill.get("prayerPoints").toString()); + } + } + } + } + + public void correct(double divisor){ + for(int i = 0; i < staticLevels.length; i++){ + experience[i] /= divisor; + staticLevels[i] = getStaticLevelByExperience(i); + dynamicLevels[i] = staticLevels[i]; + if(i == PRAYER){ + setPrayerPoints(staticLevels[i]); + } + if(i == HITPOINTS){ + setLifepoints(staticLevels[i]); + } + } + experienceMultiplier = 5.0; + updateCombatLevel(); + } + + /** + * Refreshes all the skill levels. + */ + public void refresh() { + if (!(entity instanceof Player)) { + return; + } + Player player = (Player) entity; + for (int i = 0; i < 24; i++) { + PacketRepository.send(SkillLevel.class, new SkillContext(player, i)); + } + LevelUp.sendFlashingIcons(player, -1); + } + + /** + * Gets the static level. + * @param slot The skill's slot. + * @return The level. + */ + public int getStaticLevelByExperience(int slot) { + double exp = experience[slot]; + + int points = 0; + int output = 0; + for (byte lvl = 1; lvl < 100; lvl++) { + points += floor(lvl + 300.0 * Math.pow(2.0, lvl / 7.0)); + output = (int) floor(points / 4); + if ((output - 1) >= exp) { + return lvl; + } + } + return 99; + } + + public int levelFromXP(double exp) { + + int points = 0; + int output = 0; + for (byte lvl = 1; lvl < 100; lvl++) { + points += floor(lvl + 300.0 * Math.pow(2.0, lvl / 7.0)); + output = (int) floor(points / 4); + if ((output - 1) >= exp) { + return lvl; + } + } + return 99; + } + + /** + * Gets the experience for a certain level. + * @param level The level. + * @return The experience needed. + */ + public int getExperienceByLevel(int level) { + int points = 0; + int output = 0; + for (int lvl = 1; lvl <= level; lvl++) { + points += floor(lvl + 300.0 * Math.pow(2.0, lvl / 7.0)); + if (lvl >= level) { + return output; + } + output = (int) floor(points / 4); + } + return 0; + } + + /** + * Updates the combat level. + * @return {@code True} if the combat level changed. + */ + @SuppressWarnings("deprecation") + public boolean updateCombatLevel() { + boolean update = false; + int level = calculateCombatLevel(); + update = level != entity.getProperties().getCombatLevel(); + if (entity instanceof Player) { + Player player = (Player) entity; + int summon = staticLevels[SUMMONING] / 8; + if (summon != player.getFamiliarManager().getSummoningCombatLevel()) { + player.getFamiliarManager().setSummoningCombatLevel(summon); + update = true; + } + } + entity.getProperties().setCombatLevel(level); + return update; + } + + /** + * Gets the combat level (ignoring summoning). + * @return The combat level. + */ + private int calculateCombatLevel() { + if (entity instanceof NPC) { + return ((NPC) entity).getDefinition().getCombatLevel(); + } + + double base = 0.25 * (staticLevels[DEFENCE] + staticLevels[HITPOINTS] + floor(0.5 * staticLevels[PRAYER])); + double meleeBase = 0.325 * (staticLevels[ATTACK] + staticLevels[STRENGTH]); + double rangeBase = 0.325 * (floor(staticLevels[RANGE] / 2.0) * 3.0); + double magicBase = 0.325 * (floor(staticLevels[MAGIC] / 2.0) * 3.0); + + return (int) (base + max(meleeBase, max(rangeBase, magicBase))); + } + + /** + * @return the player + */ + public Entity getEntity() { + return entity; + } + + /** + * Gets the experience. + * @param slot The slot. + * @return The experience. + */ + public double getExperience(int slot) { + return experience[slot]; + } + + /** + * Gets the static skill level. + * @param slot The slot. + * @return The static level. + */ + public int getStaticLevel(int slot) { + return staticLevels[slot]; + } + + /** + * Sets the experience gained. + * @param experienceGained The experience gained. + */ + public void setExperienceGained(double experienceGained) { + this.experienceGained = experienceGained; + } + + /** + * Gets the experience gained. + * @return The experience gained. + */ + public double getExperienceGained() { + return experienceGained; + } + + /** + * Sets a dynamic level. + * @param slot The skill id. + * @param level The level. + */ + public void setLevel(int slot, int level) { + if (slot == HITPOINTS) { + lifepoints = level; + } else if (slot == PRAYER) { + prayerPoints = level; + } + + int previousLevel = dynamicLevels[slot]; + dynamicLevels[slot] = level; + + if (entity instanceof Player) { + PacketRepository.send(SkillLevel.class, new SkillContext((Player) entity, slot)); + entity.dispatch(new DynamicSkillLevelChangeEvent(slot, previousLevel, level)); + } + } + + /** + * Gets a dynamic level. + * @param slot The skill id. + * @return The dynamic level. + */ + public int getLevel(int slot, boolean discardAssist) { + if (!discardAssist) { + if (entity instanceof Player) { + final Player p = (Player) entity; + final AssistSession assist = p.getExtension(AssistSession.class); + if (assist != null && assist.getPlayer() != p) { + Player assister = assist.getPlayer(); + int index = assist.getSkillIndex(slot); + if (index != -1 && !assist.isRestricted()) { + + // assist.getSkills()[index] + ", " + SKILL_NAME[slot]); + if (assist.getSkills()[index]) { + int assistLevel = assister.getSkills().getLevel(slot); + int playerLevel = dynamicLevels[slot]; + if (assistLevel > playerLevel) { + return assistLevel; + } + } + } + } + } + } + return dynamicLevels[slot]; + } + + /** + * Gets the level. + * @param slot the slot. + * @return the level. + */ + public int getLevel(int slot) { + return getLevel(slot, false); + } + + /** + * Sets the current amount of lifepoints. + * @param lifepoints The lifepoints. + */ + public void setLifepoints(int lifepoints) { + this.lifepoints = lifepoints; + if (this.lifepoints < 0) { + this.lifepoints = 0; + } + lifepointsUpdate = true; + } + + /** + * Gets the lifepoints. + * @return The lifepoints. + */ + public int getLifepoints() { + return lifepoints; + } + + /** + * Gets the maximum amount of lifepoints. + * @return The maximum amount. + */ + public int getMaximumLifepoints() { + if(this.entity instanceof Player && SkillcapePerks.isActive(SkillcapePerks.DAMAGE_SPONG,this.getEntity().asPlayer())){ + lifepointsIncrease = 11; + } else { + lifepointsIncrease = 0; + } + return staticLevels[HITPOINTS] + lifepointsIncrease; + } + + /** + * Sets the amount of lifepoints increase. + * @param amount The amount. + */ + public void setLifepointsIncrease(int amount) { + this.lifepointsIncrease = amount; + } + + /** + * Adds lifepoints to the entity. + * @param health The amount to add. + * @return The amount of overflow. + */ + public int heal(int health) { + lifepoints += health; + int left = 0; + if (lifepoints > getMaximumLifepoints()) { + left = lifepoints - getMaximumLifepoints(); + lifepoints = getMaximumLifepoints(); + } + lifepointsUpdate = true; + return left; + } + + public void healNoRestrictions(int amount){ + lifepoints += amount; + lifepointsUpdate = true; + } + + /** + * @Deprecated Use + * {@link ImpactHandler#manualHit(Entity, int, ImpactHandler.HitsplatType)} + * or
the hitsplat WILL NOT show and combat will be + * desynchronized! + * @param damage The amount to remove. + * @return The amount of overflow. + */ + public int hit(int damage) { + lifepoints -= damage; + int left = 0; + if (lifepoints < 0) { + left = -lifepoints; + lifepoints = 0; + } + lifepointsUpdate = true; + return left; + } + + /** + * Gets the prayer points. + * @return The prayer points. + */ + public double getPrayerPoints() { + return prayerPoints; + } + + /** + * Recharges the prayer points. + */ + public void rechargePrayerPoints() { + prayerPoints = staticLevels[PRAYER]; + if (entity instanceof Player) { + PacketRepository.send(SkillLevel.class, new SkillContext((Player) entity, PRAYER)); + } + } + + /** + * Updates the current amount of prayer points (by decrementing). + * @param amount The amount to decrement with. + */ + public void decrementPrayerPoints(double amount) { + prayerPoints -= amount; + if (prayerPoints < 0) { + prayerPoints = 0; + } + // if (prayerPoints > staticLevels[PRAYER]) { + // prayerPoints = staticLevels[PRAYER]; + // } + if (entity instanceof Player) { + PacketRepository.send(SkillLevel.class, new SkillContext((Player) entity, PRAYER)); + } + } + + /** + * Updates the current amount of prayer points (by incrementing) + * @param amount The amount to decrement with. + */ + public void incrementPrayerPoints(double amount) { + prayerPoints += amount; + if (prayerPoints < 0) { + prayerPoints = 0; + } + if (prayerPoints > staticLevels[PRAYER]) { + prayerPoints = staticLevels[PRAYER]; + } + if (entity instanceof Player) { + PacketRepository.send(SkillLevel.class, new SkillContext((Player) entity, PRAYER)); + } + } + + /** + * Sets the current prayer points (without checking for being higher than + * max) + * @param amount The amount. + */ + public void setPrayerPoints(double amount) { + prayerPoints = amount; + if (entity instanceof Player) { + PacketRepository.send(SkillLevel.class, new SkillContext((Player) entity, PRAYER)); + } + } + + /** + * Updates the current skill level (by incrementing the current amount with + * the given amount, up to the given maximum). + * @param skill The skill id. + * @param amount The amount to increment. + * @param maximum The maximum amount the skill can be. + * @return The amount of "overflow". + */ + public int updateLevel(int skill, int amount, int maximum) { + if (amount > 0 && dynamicLevels[skill] > maximum) { + return -amount; + } + int left = (dynamicLevels[skill] + amount) - maximum; + int level = dynamicLevels[skill] += amount; + if (level < 0) { + dynamicLevels[skill] = 0; + } else if (amount < 0 && level < maximum) { + dynamicLevels[skill] = maximum; + } else if (amount > 0 && level > maximum) { + dynamicLevels[skill] = maximum; + } + if (entity instanceof Player) { + PacketRepository.send(SkillLevel.class, new SkillContext((Player) entity, skill)); + } + return left; + } + + /** + * Updates a level. + * @param skill the skill. + * @param amount the amount. + * @return the left. + */ + public int updateLevel(int skill, int amount) { + return updateLevel(skill, amount, amount >= 0 ? getStaticLevel(skill) + amount : getStaticLevel(skill) - amount); + } + + /** + * Drains a certain percentage of a level. + * @param skill The skill. + * @param drainPercentage The drain percentage (0.05 indicates 5% drain). + * @param maximumDrainPercentage The maximum drain percentage (0.05 + * indicates 5%). + */ + public void drainLevel(int skill, double drainPercentage, double maximumDrainPercentage) { + int drain = (int) (dynamicLevels[skill] * drainPercentage); + int minimum = (int) (staticLevels[skill] * (1.0 - maximumDrainPercentage)); + updateLevel(skill, -drain, minimum); + } + + /** + * Sets the static level. + * @param skill The skill id. + * @param level The level to set. + */ + public void setStaticLevel(int skill, int level) { + experience[skill] = getExperienceByLevel(staticLevels[skill] = dynamicLevels[skill] = level); + if (entity instanceof Player) { + PacketRepository.send(SkillLevel.class, new SkillContext((Player) entity, skill)); + } + } + + /** + * Gets the amount of mastered skills. + * @return The amount of mastered skills. + */ + public int getMasteredSkills() { + int count = 0; + for (int i = 0; i < 23; i++) { + if (getStaticLevel(i) >= 99) { + count++; + } + } + return count; + } + + /** + * Method used to get the skill by the name. + * @param name the name. + * @return the skill. + */ + public static int getSkillByName(final String name) { + for (int i = 0; i < SKILL_NAME.length; i++) { + if (SKILL_NAME[i].equalsIgnoreCase(name)) { + return i; + } + } + return -1; + } + + /** + * Gets the total level. + * @return the total level. + */ + public int getTotalLevel() { + int level = 0; + for (int i = 0; i < 24; i++) { + level += getStaticLevel(i); + } + return level; + } + + /** + * Gets the total exp. + * @return the exp. + */ + public int getTotalXp() { + int total = 0; + for (int skill = 0; skill < Skills.SKILL_NAME.length; skill++) { + total += this.getExperience(skill); + } + return total; + } + + /** + * Gets the lifepointsUpdate. + * @return The lifepointsUpdate. + */ + public boolean isLifepointsUpdate() { + return lifepointsUpdate; + } + + /** + * Sets the lifepointsUpdate. + * @param lifepointsUpdate The lifepointsUpdate to set. + */ + public void setLifepointsUpdate(boolean lifepointsUpdate) { + this.lifepointsUpdate = lifepointsUpdate; + } + + /** + * Gets the statis levels. + * @return the level. + */ + public int[] getStaticLevels() { + return staticLevels; + } + + /** + * Checks if the player has the required level. + * @param skillId the skill id. + * @param i the level. + * @return {@code True} if so. + */ + public boolean hasLevel(int skillId, int i) { + return getStaticLevel(skillId) >= i; + } + + /** + * Gets the combatMilestone value. + * @return The combatMilestone. + */ + public int getCombatMilestone() { + return combatMilestone; + } + + /** + * Sets the combatMilestones value. + * @param combatMilestone The combatMilestones to set. + */ + public void setCombatMilestone(int combatMilestone) { + this.combatMilestone = combatMilestone; + } + + /** + * Gets the skillMilestone value. + * @return The skillMilestone. + */ + public int getSkillMilestone() { + return skillMilestone; + } + + /** + * Sets the skillMilestone value. + * @param skillMilestone The skillMilestone to set. + */ + public void setSkillMilestone(int skillMilestone) { + this.skillMilestone = skillMilestone; + } + + public int[] getDynamicLevels() { + return dynamicLevels; + } +} diff --git a/Server/src/main/core/game/node/item/ChanceItem.java b/Server/src/main/core/game/node/item/ChanceItem.java new file mode 100644 index 0000000..80ca1bc --- /dev/null +++ b/Server/src/main/core/game/node/item/ChanceItem.java @@ -0,0 +1,267 @@ +package core.game.node.item; + +import core.game.node.entity.npc.drop.DropFrequency; +import core.tools.RandomFunction; + +/** + * Represents an item with a chance-rate. + * @author Emperor + */ +public final class ChanceItem extends Item { + + public static final int[] DROP_RATES = { 5,15,150,750 }; + + /** + * The chance rate of this item. + */ + private double chanceRate; + + /** + * The minimum amount. + */ + private int minimumAmount; + + /** + * The maximum amount. + */ + private int maximumAmount; + + /** + * The table slot. + */ + private int tableSlot; + + /** + * The drop frequency. + */ + private DropFrequency dropFrequency; + + /** + * The set rate. + */ + private int setRate = -1; + + /** + * Constructs a new {@code ChanceItem} {@code Object}. + * @param id The item id. + */ + public ChanceItem(int id) { + this(id, 1, 1, 1000, 1.0); + } + + /** + * Constructs a new {@code ChanceItem} {@code Object}. + * @param id The item id. + * @param minimumAmount The minimum amount. + * @param chanceRate The chance rate. + */ + public ChanceItem(int id, int minimumAmount, double chanceRate) { + this(id, minimumAmount, minimumAmount, 1000, chanceRate); + } + + public ChanceItem(int id, int minimumAmount, int chanceRate) { + this(id,minimumAmount,minimumAmount,1000,(double) chanceRate); + } + + /** + * Constructs a new {@code ChanceItem} {@code Object}. + * @param id The item id. + * @param minimumAmount The minimum amount. + * @param maximumAmount The maximum amount. + * @param chanceRate The chance rate. + */ + public ChanceItem(int id, int minimumAmount, int maximumAmount, double chanceRate) { + this(id, minimumAmount, maximumAmount, 1000, chanceRate); + } + + /** + * Constructs a new {@code ChanceItem} {@code Object}. + * @param id the id. + * @param minimumAmount the min amount. + * @param maximumAmount the max amount. + * @param frequency the frequency. + */ + public ChanceItem(int id, int minimumAmount, int maximumAmount, DropFrequency frequency) { + this(id, minimumAmount, maximumAmount, 1000, DropFrequency.rate(frequency)); + } + + /** + * Constructs a new {@code ChanceItem} {@code Object}. + * @param id The item id. + * @param minimumAmount The minimum amount. + * @param maximumAmount The maximum amount. + * @param charge The charge. if(frequency == DropFrequency.ALWAYS){ + + } + * @param chanceRate The chance rate. + */ + public ChanceItem(int id, int minimumAmount, int maximumAmount, int charge, double chanceRate) { + this(id, minimumAmount, maximumAmount, charge, chanceRate, DropFrequency.UNCOMMON); + } + + /** + * Constructs a new {@code ChanceItem} {@code Object}. + * @param id The item id. + * @param minimumAmount The minimum amount. + * @param maximumAmount The maximum amount. + * @param charge The charge. + * @param frequency The drop frequency. + * @param chanceRate The chance rate. + */ + public ChanceItem(int id, int minimumAmount, int maximumAmount, int charge, double chanceRate, DropFrequency frequency) { + this(id, minimumAmount, maximumAmount, charge, chanceRate, frequency, -1); + } + + /** + * Constructs a new {@code ChanceItem} {@code Object}. + * @param id The item id. + * @param minimumAmount The minimum amount. + * @param maximumAmount The maximum amount. + * @param charge The charge. + * @param frequency The drop frequency. + * @param chanceRate The chance rate. + * @param setRate the set rate. + */ + public ChanceItem(int id, int minimumAmount, int maximumAmount, int charge, double chanceRate, DropFrequency frequency, int setRate) { + super(id, minimumAmount, charge); + this.minimumAmount = minimumAmount; + this.maximumAmount = maximumAmount; + this.chanceRate = chanceRate; + this.dropFrequency = frequency; + this.setRate = setRate; + } + + public ChanceItem(int id, int amount, DropFrequency frequency){ + this(id, amount, amount, frequency); + } + + /** + * Gets the item instance. + * @return the item. + */ + public Item getRandomItem() { + if (minimumAmount == maximumAmount) { + return new Item(getId(), minimumAmount); + } + return new Item(getId(), RandomFunction.random(minimumAmount, maximumAmount)); + } + + /** + * Gets a random chance item from the table. + * @param table The table. + * @return The chance item. + */ + public static ChanceItem getItem(ChanceItem... table) { + return getItem(RandomFunction.getRandomDouble(75.0), table); + } + + /** + * Gets a random chance item from the table. + * @param table The table. + * @return The chance item. + */ + public static ChanceItem getItem(double chance, ChanceItem... table) { + // TODO: + return table[0]; + } + + /** + * Gets a copy. + * @return the copy. + */ + public ChanceItem getCopy() { + ChanceItem newItem = new ChanceItem(getId(), minimumAmount, maximumAmount, getCharge(), chanceRate, dropFrequency); + return newItem; + } + + /** + * @return the chanceRate. + */ + public double getChanceRate() { + return chanceRate; + } + + /** + * @param chanceRate the chanceRate to set. + */ + public void setChanceRate(double chanceRate) { + this.chanceRate = chanceRate; + } + + /** + * @return the minimumAmount. + */ + public int getMinimumAmount() { + return minimumAmount; + } + + /** + * @param minimumAmount the minimumAmount to set. + */ + public void setMinimumAmount(int minimumAmount) { + this.minimumAmount = minimumAmount; + } + + /** + * @return the maximumAmount. + */ + public int getMaximumAmount() { + return maximumAmount; + } + + /** + * @param maximumAmount the maximumAmount to set. + */ + public void setMaximumAmount(int maximumAmount) { + this.maximumAmount = maximumAmount; + } + + /** + * @return the dropFrequency. + */ + public DropFrequency getDropFrequency() { + return dropFrequency; + } + + /** + * @param dropFrequency the dropFrequency to set. + */ + public void setDropFrequency(DropFrequency dropFrequency) { + this.dropFrequency = dropFrequency; + } + + /** + * @return the tableSlot. + */ + public int getTableSlot() { + return tableSlot; + } + + /** + * @param tableSlot the tableSlot to set. + */ + public void setTableSlot(int tableSlot) { + this.tableSlot = tableSlot; + } + + @Override + public String toString() { + return "ChanceItem " + super.toString() + " [chanceRate=" + chanceRate + ", minimumAmount=" + minimumAmount + ", maximumAmount=" + maximumAmount + ", tableSlot=" + tableSlot + ", dropFrequency=" + dropFrequency + "]"; + } + + /** + * Gets the setRate. + * @return the setRate + */ + public int getSetRate() { + return setRate; + } + + /** + * Sets the basetRate. + * @param setRate the setRate to set. + */ + public void setSetRate(int setRate) { + this.setRate = setRate; + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/item/GroundItem.java b/Server/src/main/core/game/node/item/GroundItem.java new file mode 100644 index 0000000..ba5c4e2 --- /dev/null +++ b/Server/src/main/core/game/node/item/GroundItem.java @@ -0,0 +1,216 @@ +package core.game.node.item; + +import core.game.node.entity.player.Player; +import core.game.world.GameWorld; +import core.game.world.map.Location; + +/** + * Represents a ground item. + * @author Emperor + */ +public class GroundItem extends Item { + + /** + * The player who dropped this item. + */ + private Player dropper; + + private int dropperUid; + + /** + * The amount of ticks. + */ + private int ticks; + + /** + * The amount of ticks when to remove this item. + */ + private int decayTime; + + /** + * If the item should remain private. + */ + private boolean remainPrivate; + + /** + * If the ground item has been removed. + */ + private boolean removed; + + public boolean forceVisible; + + /** + * Constructs a new {@code GroundItem} {@code Object}. + * @param item The item + */ + public GroundItem(Item item) { + this(item, null, null); + } + + /** + * Constructs a new {@code GroundItem} {@code Object}. + * @param item The item. + * @param location The location. + */ + public GroundItem(Item item, Location location) { + this(item, location, 200, null); + } + + /** + * Constructs a new {@code GroundItem} {@code Object}. + * @param item The item. + * @param location The location. + * @param player The player who dropped this item. + */ + public GroundItem(Item item, Location location, Player player) { + this(item, location, 200, player); + } + + public GroundItem(Item item, Location location, int playerUid, int ticks) { + this(item, location); + this.dropperUid = playerUid; + this.decayTime = ticks; + } + + /** + * Constructs a new {@code GroundItem} {@code Object}. + * @param item The item. + * @param location The location. + * @param player The player who dropped this item. + */ + public GroundItem(Item item, Location location, int decay, Player player) { + super(item.getId(), item.getAmount(), item.getCharge()); + super.location = location; + super.index = -1; + super.interactPlugin.setDefault(); + this.dropper = player; + this.dropperUid = player != null ? player.getDetails().getUid() : -1; + this.ticks = GameWorld.getTicks(); + this.decayTime = ticks + decay; + } + + /** + * Used to respawn the ground item. + */ + public void respawn() { + + } + + /** + * Checks if the ground item is private. + * @return {@code True} if so. + */ + public boolean isPrivate() { + return !forceVisible && (remainPrivate || (decayTime - GameWorld.getTicks() > 100)); + } + + @Override + public boolean isActive() { + return removed || GameWorld.getTicks() < decayTime; + } + + /** + * Checks if this item was dropped by the player. + * @param p The player. + * @return {@code True} if so. + */ + public boolean droppedBy(Player p) { + if (p.getDetails().getUid() == dropperUid) { + dropper = p; + return true; + } + return false; + } + + /** + * Gets the dropper. + * @return The dropper. + */ + public Player getDropper() { + return dropper; + } + + /** + * Sets the dropper. + * @param player The player who dropped this item. + */ + public void setDropper(Player player) { + this.dropper = player; + } + + /** + * Gets the ticks. + * @return The ticks. + */ + public int getTicks() { + return ticks; + } + + /** + * Gets the decayTime. + * @return The decayTime. + */ + public int getDecayTime() { + return decayTime; + } + + /** + * Sets the decayTime. + * @param decayTime The decayTime to set. + */ + public void setDecayTime(int decayTime) { + this.decayTime = GameWorld.getTicks() + decayTime; + } + + /** + * Gets the autoSpawn. + * @return The autoSpawn. + */ + public boolean isAutoSpawn() { + return false; + } + + /** + * Gets the remainPrivate. + * @return The remainPrivate. + */ + public boolean isRemainPrivate() { + return remainPrivate; + } + + /** + * Sets the remainPrivate. + * @param remainPrivate The remainPrivate to set. + */ + public void setRemainPrivate(boolean remainPrivate) { + this.remainPrivate = remainPrivate; + } + + /** + * Gets the removed. + * @return The removed. + */ + public boolean isRemoved() { + return removed; + } + + /** + * Sets the removed. + * @param removed The removed to set. + */ + public void setRemoved(boolean removed) { + this.removed = removed; + } + + /** + * Gets the dropper uid. + */ + public int getDropperUid() { + return dropperUid; + } + + @Override + public String toString() { + return "GroundItem [dropper=" + (dropper != null ? dropper.getUsername() : dropper) + ", ticks=" + ticks + ", decayTime=" + decayTime + ", remainPrivate=" + remainPrivate + ", removed=" + removed + "]"; + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/item/GroundItemManager.java b/Server/src/main/core/game/node/item/GroundItemManager.java new file mode 100644 index 0000000..464dbbe --- /dev/null +++ b/Server/src/main/core/game/node/item/GroundItemManager.java @@ -0,0 +1,173 @@ +package core.game.node.item; + +import core.game.node.entity.player.Player; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.chunk.ItemUpdateFlag; +import core.net.packet.PacketRepository; +import core.net.packet.context.BuildItemContext; +import core.net.packet.out.UpdateGroundItemAmount; +import core.game.bots.AIRepository; + +import java.util.ArrayList; +import java.util.List; + +/** + * Handles ground items. + * @author Emperor + */ +public final class GroundItemManager { + /** + * The list of ground items. + */ + private static final List GROUND_ITEMS = new ArrayList<>(20); + + /** + * Creates a ground item. + * @param item The ground item to create. + * @param location The location to set the ground item on. + */ + public static GroundItem create(Item item, Location location) { + return create(new GroundItem(item, location, null)); + } + + public static GroundItem create (Item item, Location location, int playerUid, int ticks) { + return create(new GroundItem(item, location, playerUid, ticks)); + } + + /** + * Creates a ground item. + * @param item the item. + * @param player the player. + * @return + */ + public static GroundItem create(Item item, final Player player) { + return create(new GroundItem(item, player.getLocation(), player)); + } + + /** + * Creates a ground item. + * @param item The ground item to create. + * @param location The location to set the ground item on. + * @param player The player creating the ground item. + */ + public static GroundItem create(Item item, Location location, Player player) { + return create(new GroundItem(item, location, player)); + } + + /** + * Creates a ground item. + * @param item The ground item to create. + * @param location The location to set the ground item on. + * @param player The player creating the ground item. + */ + public static void create(Item[] item, Location location, Player player) { + for (int i = 0; i < item.length; i++) { + create(new GroundItem(item[i], location, player)); + } + } + + /** + * Creates a ground item. + * @param item The ground item to create. + * @return The ground item. + */ + public static GroundItem create(GroundItem item) { + if (!item.getDefinition().isTradeable()) { + item.setRemainPrivate(true); + } + if (item.getDropper() != null && item.hasItemPlugin()) { + item.getPlugin().remove(item.getDropper(), item, ItemPlugin.DROP); + } + item.setRemoved(false); + RegionManager.getRegionPlane(item.getLocation()).add(item); + if (GROUND_ITEMS.add(item)) { + return item; + } + return null; + } + + /** + * Destroys the ground item. + * @param item The ground item. + */ + public static GroundItem destroy(GroundItem item) { + if (item == null) { + return null; + } + GROUND_ITEMS.remove(item); + RegionManager.getRegionPlane(item.getLocation()).remove(item); + if (item.isAutoSpawn()) { + item.respawn(); + } + return item; + } + + /** + * Gets a ground item. + * @param itemId The item id. + * @param location The location. + * @param player The player. + * @return The ground item, or {@code null} if the ground item wasn't found. + */ + public static GroundItem get(int itemId, Location location, Player player) { + return RegionManager.getRegionPlane(location).getItem(itemId, location, player); + } + + /** + * Increases the amount of a ground item on the floor, or creates a new + * ground item. + * @param item The item to drop. + * @param location The drop location. + * @param p The player. + * @return The ground item. + */ + public static GroundItem increase(Item item, Location location, Player p) { + GroundItem g = get(item.getId(), location, p); + if (g == null || !g.droppedBy(p) || !g.isPrivate() || g.isRemoved()) { + return create(item, location, p); + } + int oldAmount = g.getAmount(); + g.setAmount(oldAmount + item.getAmount()); + PacketRepository.send(UpdateGroundItemAmount.class, new BuildItemContext(p, g, oldAmount)); + return g; + } + + /** + * Handles the ground items. + */ + public static void pulse() { + Object[] giArray = GROUND_ITEMS.toArray(); + int size = giArray.length; + for (int i = 0; i < size; i++) { + GroundItem item = (GroundItem) giArray[i]; + if (item.isAutoSpawn()) { + continue; + } + if (!item.isActive()) { + GROUND_ITEMS.remove(item); + if(item.getDropper() != null) { + if (item.getDropper().isArtificial()) { + ArrayList val = AIRepository.getItems(item.getDropper()); + if (val != null) + val.remove(item); + } + } + if (!item.isRemoved()) { + RegionManager.getRegionPlane(item.getLocation()).remove(item); + } + } else if (!item.isRemainPrivate() && item.getDecayTime() - GameWorld.getTicks() == 100) { + RegionManager.getRegionChunk(item.getLocation()).flag(new ItemUpdateFlag(item, ItemUpdateFlag.CONSTRUCT_TYPE)); + } + } + } + + /** + * Gets the list of ground items. + * @return The ground items. + */ + public static List getItems() { + return GROUND_ITEMS; + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/item/Item.java b/Server/src/main/core/game/node/item/Item.java new file mode 100644 index 0000000..086784c --- /dev/null +++ b/Server/src/main/core/game/node/item/Item.java @@ -0,0 +1,248 @@ +package core.game.node.item; + +import core.cache.def.impl.ItemDefinition; +import core.game.interaction.DestinationFlag; +import core.game.interaction.InteractPlugin; +import core.game.interaction.OptionHandler; +import core.game.node.Node; +import core.game.node.entity.combat.equipment.DegradableEquipment; + +/** + * Represents an item. + * @author Emperor + */ +public class Item extends Node{ + + /** + * The identification hash (itemId << 16 | charge) + */ + private int idHash; + + /** + * The item amount. + */ + private int amount; + + /** + * The item definition. + */ + private ItemDefinition definition; + + /** + * Constructs a new {@code Item} {@code Object}.
The id will be -1 + * (thus definition will be null + */ + public Item() { + super("null", null); + super.interactPlugin = new InteractPlugin(this); + this.idHash = -1 << 16 | 1000; + } + + /** + * Constructs a new fully charged {@code Item} {@code Object}. + * @param id The item id. + */ + public Item(int id) { + this(id, 1, 1000); + } + + /** + * Constructs a new fully charged {@code Item} {@code Object}. + * @param id The item id. + * @param amount The amount. + */ + public Item(int id, int amount) { + this(id, amount, 1000); + } + + /** + * Constructs a new {@code Item} {@code Object}. + * @param id The item id. + * @param amount The amount. + * @param charge The charge. + */ + public Item(int id, int amount, int charge) { + super(ItemDefinition.forId(id).getName(), null); + super.destinationFlag = DestinationFlag.ITEM; + super.index = -1; // Item slot. + super.interactPlugin = new InteractPlugin(this); + this.idHash = id << 16 | charge; + this.amount = amount; + this.definition = ItemDefinition.forId(id); + } + + /** + * Gets this item as a ground item. + * @return The item. + */ + public Item getDropItem() { + int itemId = DegradableEquipment.getDropReplacement(getId()); + if (itemId != getId()) { + return new Item(itemId, getAmount()); + } + return this; + } + + /** + * Gets the operate option handler. + * @return The option handler for the operate option. + */ + public OptionHandler getOperateHandler() { + return ItemDefinition.getOptionHandler(getId(), "operate"); + } + + /** + * Gets the value of the item. + * @return The value. + */ + public long getValue() { + long value = 1; + if (definition.getValue() > value) { + value = definition.getValue(); + } + if (definition.getAlchemyValue(true) > value) { + value = definition.getAlchemyValue(true); + } + return value * getAmount(); + } + + public long getAlchemyValue() { + long value = 1; + if (definition.getAlchemyValue(true) > value) { + value = definition.getAlchemyValue(true); + } + return value * getAmount(); + } + + /** + * Gets a copy of the item. + * @return The item copy. + */ + public Item copy() { + return new Item(getId(), getAmount(), getCharge()); + } + + /** + * Gets the item id of the exchange item for this item. + * @return The note item id, if this item is unnoted, or the unnoted item id + * if this item is noted. + */ + public int getNoteChange() { + int noteId = definition.getNoteId(); + if (noteId > -1) { + return noteId; + } + return getId(); + } + + /** + * @return the id + */ + public int getId() { + return idHash >> 16 & 0xFFFF; + } + + /** + * @param id the id to set + */ + public void setId(int id) { + this.idHash = id << 16 | (idHash & 0xFFFF); + this.definition = ItemDefinition.forId(id); + } + + /** + * @return the amount + */ + public int getAmount() { + return amount; + } + + /** + * @param amount the amount to set + */ + public void setAmount(int amount) { + if (amount < 0) { + amount = 0; + } + this.amount = amount; + } + + /** + * Checks if the item has atleast one charge left. + * @return {@code True} if so. + */ + public boolean isCharged() { + return getCharge() > 0; + } + + /** + * @return the charge + */ + public int getCharge() { + return idHash & 0xFFFF; + } + + /** + * @param charge the charge to set + */ + public void setCharge(int charge) { + this.idHash = (idHash >> 16 & 0xFFFF) << 16 | charge; + } + + /** + * @return the identification hash + */ + public int getIdHash() { + return idHash; + } + + /** + * Checks if the item has a wrapper plugin. + * @return {@code True} if so. + */ + public boolean hasItemPlugin() { + return getPlugin() != null; + } + + /** + * Gets the item plugin. + * @return the plugin. + */ + public ItemPlugin getPlugin() { + if (definition == null) { + return null; + } + return definition.getItemPlugin(); + } + + /** + * Gets the definition. + * @return The definition. + */ + public ItemDefinition getDefinition() { + return definition; + } + + /** + * Sets the definition. + * @param definition The definition to set. + */ + public void setDefinition(ItemDefinition definition) { + this.definition = definition; + } + + /** + * Gets the slot of this item. + * @return The container slot, or {@code -1} if the item wasn't added to a + * container. + */ + public int getSlot() { + return index; + } + + @Override + public String toString() { + return "Item id=" + getId() + ", name=" + getName() + ", amount=" + amount; + } + +} diff --git a/Server/src/main/core/game/node/item/ItemPlugin.java b/Server/src/main/core/game/node/item/ItemPlugin.java new file mode 100644 index 0000000..6dd572d --- /dev/null +++ b/Server/src/main/core/game/node/item/ItemPlugin.java @@ -0,0 +1,95 @@ +package core.game.node.item; + +import core.cache.def.impl.ItemDefinition; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.plugin.Plugin; + +/** + * Represents a plugin for an item. + * @author Vexia + */ +public abstract class ItemPlugin implements Plugin { + + /** + * The drop type identifier. + */ + protected static final int DROP = 1; + + /** + * Constructs a new {@Code ItemPlugin} {@Code Object} + */ + public ItemPlugin() { + /** + * empty. + */ + } + + @Override + public Object fireEvent(String identifier, Object... args) { + return this; + } + + /** + * Registers items to this plugin. + * @param ids the ids. + */ + public void register(int... ids) { + for (int id : ids) { + ItemDefinition.forId(id).setItemPlugin(this); + } + } + + /** + * Called when the item is removed from the player. + * @param player the player. + * @param item the item. + * @param type the type. (1=drop) + */ + public void remove(Player player, Item item, int type) { + + } + + /** + * Checks if the item can be picked up. + * @param player the player. + * @param item the item. + * @param type the pickup type (1=ground, 2=telegab) + * @return {@code True} if so. + */ + public boolean canPickUp(Player player, GroundItem item, int type) { + return true; + } + + /** + * Checks if the item can be made as a drop. + * @param item the item. + * @param player the player. + * @param npc TODO + * @param l the location. + * @return + */ + public boolean createDrop(Item item, Player player, NPC npc, Location l) { + return true; + } + + /** + * Changes an item if needed. + * @param item the item. + * @param npc the npc. + * @return the item. + */ + public Item getItem(Item item, NPC npc) { + return item; + } + + /** + * Gets the death item. + * @param item the item. + * @return the item. + */ + public Item getDeathItem(Item item) { + return item; + } +} diff --git a/Server/src/main/core/game/node/item/WeightedChanceItem.java b/Server/src/main/core/game/node/item/WeightedChanceItem.java new file mode 100644 index 0000000..fd131ba --- /dev/null +++ b/Server/src/main/core/game/node/item/WeightedChanceItem.java @@ -0,0 +1,23 @@ +package core.game.node.item; + +import core.tools.RandomFunction; + +public class WeightedChanceItem { + int id,minimum_amount,maximum_amount; + public int weight; + + public WeightedChanceItem(int id, int minimum_amount, int maximum_amount, int weight){ + this.id = id; + this.minimum_amount = minimum_amount; + this.maximum_amount = maximum_amount; + this.weight = weight; + } + + public WeightedChanceItem(int id, int amount, int weight){ + this(id,amount,amount,weight); + } + + public Item getItem(){ + return new Item(this.id, RandomFunction.random(this.minimum_amount, this.maximum_amount)); + } +} diff --git a/Server/src/main/core/game/node/scenery/Constructed.java b/Server/src/main/core/game/node/scenery/Constructed.java new file mode 100644 index 0000000..d0af7b2 --- /dev/null +++ b/Server/src/main/core/game/node/scenery/Constructed.java @@ -0,0 +1,126 @@ +package core.game.node.scenery; + +import core.game.node.item.Item; +import core.game.world.map.Location; + +/** + * Represents a constructed object. + * @author Emperor + */ +public class Constructed extends Scenery { + + /** + * The scenery we've replaced. + */ + private Scenery replaced; + + /** + * The ground items places after the tick is up. + */ + private Item[] items; + + /** + * Constructs a new Constructed object. + * @param id The object id. + * @param x The object x-coordinate. + * @param y The object y-coordinate. + * @param z The object z-coordinate. + */ + public Constructed(int id, int x, int y, int z) { + super(id, Location.create(x, y, z), 10, 0); + } + + /** + * Constructs a new Constructed object. + * @param id The object id. + * @param location The object's location. + */ + public Constructed(int id, Location location) { + super(id, location, 10, 0); + } + + /** + * Constructs a new Constructed object. + * @param id The object id. + * @param location The object's location. + * @param rotation The object's rotation. + */ + public Constructed(int id, Location location, int rotation) { + super(id, location, 10, rotation); + } + + /** + * Constructs a new {@code Constructed} {@code Object}. + * @param id The object id. + * @param x The x-coordinate. + * @param y The y-coordinate. + * @param z The z-coordinate. + * @param type The object type. + * @param rotation The rotation. + */ + public Constructed(int id, int x, int y, int z, int type, int rotation) { + super(id, Location.create(x, y, z), type, rotation); + } + + /** + * Constructs a new {@code Constructed} {@code Object}. + * @param id The object id. + * @param type The object type. + * @param rotation The rotation. + */ + public Constructed(int id, int type, int rotation) { + super(id, Location.create(0, 0, 0), type, rotation); + } + + /** + * Constructs a new {@code Constructed} {@code Object}. + * @param id The object id. + * @param location The location. + * @param type The object type. + * @param rotation The rotation. + */ + public Constructed(int id, Location location, int type, int rotation) { + super(id, location, type, rotation); + } + + @Override + public boolean isPermanent() { + return false; + } + + @Override + public Constructed asConstructed() { + return this; + } + + /** + * Gets the replaced. + * @return The replaced. + */ + public Scenery getReplaced() { + return replaced; + } + + /** + * Sets the replaced. + * @param replaced The replaced to set. + */ + public void setReplaced(Scenery replaced) { + this.replaced = replaced; + } + + /** + * @return the items + */ + public Item[] getItems() { + return items; + } + + /** + * @param items the items to set + */ + public void setItems(Item[] items) { + this.items = items; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/node/scenery/Scenery.java b/Server/src/main/core/game/node/scenery/Scenery.java new file mode 100644 index 0000000..9594a7f --- /dev/null +++ b/Server/src/main/core/game/node/scenery/Scenery.java @@ -0,0 +1,475 @@ +package core.game.node.scenery; + +import core.cache.def.impl.VarbitDefinition; +import core.cache.def.impl.SceneryDefinition; +import core.game.interaction.DestinationFlag; +import core.game.interaction.InteractPlugin; +import core.game.node.Node; +import core.game.node.entity.impl.GameAttributes; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; +import static core.api.ContentAPIKt.*; + +/** + * Represents a scenery. + * @author Emperor + */ +public class Scenery extends Node { + + /** + * The object id. + */ + private final int id; + + /** + * Object's type. + */ + private final int type; + + /** + * The rotation. + */ + private int rotation; + + /** + * The object's definition. + */ + private final SceneryDefinition definition; + + /** + * The restore pulse. + */ + private Pulse restorePulse; + + /** + * The destruction pulse. + */ + private Pulse destructionPulse; + + /** + * The charge of this object. + */ + private int charge = 1000; + + /** + * The entity's attributes. + */ + private final GameAttributes attributes = new GameAttributes(); + + /** + * The child objects. + */ + private final Scenery[] childs; + + /** + * The scenery wrapper (used for object configurations). + */ + private Scenery wrapper; + + /** + * Constructs a new scenery. + * @param id The object id. + * @param x The object x-coordinate. + * @param y The object y-coordinate. + * @param z The object z-coordinate. + */ + public Scenery(int id, int x, int y, int z) { + this(id, Location.create(x, y, z), 10, 0); + } + + /** + * Constructs a new scenery. + * @param id The object id. + * @param location The object's location. + */ + public Scenery(int id, Location location) { + this(id, location, 10, 0); + } + + /** + * Constructs a new scenery. + * @param id The object id. + * @param location The object's location. + * @param rotation The object's rotation. + */ + public Scenery(int id, Location location, int rotation) { + this(id, location, 10, rotation); + } + + public Scenery(int id, Location location, int rotation, Direction direction) { + this(id, location, 10, rotation); + } + + /** + * Constructs a new {@code GameObject} {@code Object}. + * @param id The object id. + * @param x The x-coordinate. + * @param y The y-coordinate. + * @param z The z-coordinate. + * @param type The object type. + * @param rotation The rotation. + */ + public Scenery(int id, int x, int y, int z, int type, int rotation) { + this(id, Location.create(x, y, z), type, rotation); + } + + /** + * Constructs a new {@code GameObject} {@code Object}. + * @param id The object id. + * @param type The object type. + * @param rotation The rotation. + */ + public Scenery(int id, int type, int rotation) { + this(id, Location.create(0, 0, 0), type, rotation); + } + + /** + * Constructs a new {@code GameObject} {@code Object}. + * @param id The object id. + * @param location The location. + * @param type The object type. + * @param rotation The rotation. + */ + public Scenery(int id, Location location, int type, int rotation) { + super(SceneryDefinition.forId(id).getName(), location); + if (rotation < 0) { + rotation += 4; + } + if (id < 1) { + type = 22; + } + super.destinationFlag = DestinationFlag.OBJECT; + super.direction = Direction.get(rotation); + super.interactPlugin = new InteractPlugin(this); + this.rotation = rotation; + this.id = id; + this.location = location; + this.type = type; + this.definition = SceneryDefinition.forId(id); + super.size = definition.sizeX; + if (definition.childrenIds != null && definition.childrenIds.length > 0) { + this.childs = new Scenery[definition.childrenIds.length]; + for (int i = 0; i < childs.length; i++) { + childs[i] = transform(definition.childrenIds[i]); + childs[i].wrapper = this; + } + } else { + childs = null; + } + } + + public Scenery(Scenery other) { + this(other.getId(), other.getLocation(), other.getType(), other.getRotation()); + } + + /** + * Called when an object is removed. + */ + public void remove() {}; + + /** + * Gets the current x-size. + * @return The current size. + */ + public int getSizeX() { + if (direction.toInteger() % 2 != 0) { + return definition.sizeY; + } + return definition.sizeX; + } + + /** + * Gets the current y-size. + * @return The current size. + */ + public int getSizeY() { + if (direction.toInteger() % 2 != 0) { + return definition.sizeX; + } + return definition.sizeY; + } + + @Override + public void setActive(boolean active) { + if (super.active && !active && destructionPulse != null) { + destructionPulse.pulse(); + } + super.setActive(active); + } + + /** + * Gets the child object shown for the current player. + * @param player The player. + * @return The child object. + */ + public Scenery getChild(Player player) { + if (childs != null) { + SceneryDefinition def = definition.getChildObject(player); + for (Scenery child : childs) { + if (child.getId() == def.getId()) { + return child; + } + } + } + return this; + } + + /** + * Sets the child object index. + * @param player The player. + * @param index The child object. + */ + public void setChildIndex(Player player, int index) { + SceneryDefinition def = getDefinition(); + if (childs == null && wrapper != null) { + def = wrapper.getDefinition(); + } + if (def.getVarbitID() > -1) { + VarbitDefinition config = def.getConfigFile(); + if (config != null) { + setVarbit(player, def.getVarbitID(), index); + } + } else if (def.getConfigId() > -1) { + setVarp(player, def.getConfigId(), index); + } + } + + /** + * Gets a transformed object of this object. + * @param id The new object id. + * @return The constructed scenery. + */ + public Scenery transform(int id) { + return new Scenery(id, location, type, rotation); + } + + /** + * Gets a transformed object of this object. + * @param id The new object id. + * @param rotation The new rotation. + * @return The constructed scenery. + */ + public Scenery transform(int id, int rotation) { + return new Scenery(id, location, type, rotation); + } + + /** + * Gets a transformed object of this object. + * @param id The new object id. + * @param rotation The new rotation. + * @param location The new location. + * @return The constructed scenery. + */ + public Scenery transform(int id, int rotation, Location location) { + return new Scenery(id, location, type, rotation); + } + + /** + * Gets a transformed object of this object. + * @param id The new object id. + * @param rotation The new rotation. + * @param type The object type. + * @return The constructed scenery. + */ + public Scenery transform(int id, int rotation, int type) { + return new Scenery(id, location, type, rotation); + } + + /** + * If the object is permanent. + * @return {@code True} if so. + */ + public boolean isPermanent() { + return true; + } + + /** + * Gets this scenery as Constructed object. + * @return The {@link Constructed} object. + */ + public Constructed asConstructed() { + return new Constructed(id, location, type, rotation); + } + + /** + * @return the id + */ + public int getId() { + return id; + } + + /** + * @return the type + */ + public int getType() { + return type; + } + + /** + * @return the rotation + */ + public int getRotation() { + return rotation; + } + + public void setRotation(int rot) { + rotation = rot; + } + + /** + * @return the location + */ + @Override + public Location getLocation() { + return location; + } + + /** + * Gets the definition. + * @return The definition. + */ + public SceneryDefinition getDefinition() { + return definition; + } + + @Override + public Location getCenterLocation() { + return location.transform(getSizeX() >> 1, getSizeY() >> 1, 0); + } + + @Override + public boolean equals(Object obj) { + if (obj == null || !(obj instanceof Scenery)) { + return false; + } + Scenery other = (Scenery) obj; + return other.id == id && other.location.equals(location) && rotation == other.rotation && other.type == type; + } + + @Override + public String toString() { + return "[Scenery " + id + ", " + location + ", type=" + type + ", rot=" + rotation + "]"; + } + + /** + * Gets the restorePulse. + * @return The restorePulse. + */ + public Pulse getRestorePulse() { + return restorePulse; + } + + /** + * Sets the restorePulse. + * @param restorePulse The restorePulse to set. + */ + public void setRestorePulse(Pulse restorePulse) { + this.restorePulse = restorePulse; + } + + /** + * Gets the charge. + * @return The charge. + */ + public int getCharge() { + return charge; + } + + /** + * Sets the charge. + * @param charge The charge to set. + */ + public void setCharge(int charge) { + this.charge = charge; + } + + /** + * Gets the destructionPulse. + * @return The destructionPulse. + */ + public Pulse getDestructionPulse() { + return destructionPulse; + } + + /** + * Sets the destructionPulse. + * @param destructionPulse The destructionPulse to set. + */ + public void setDestructionPulse(Pulse destructionPulse) { + this.destructionPulse = destructionPulse; + } + + /** + * @return the attributes. + */ + public GameAttributes getAttributes() { + return attributes; + } + + /** + * Gets the childs. + * @return The childs. + */ + public Scenery[] getChilds() { + return childs; + } + + /** + * Gets the wrapper. + * @return The wrapper. + */ + public Scenery getWrapper() { + if (wrapper == null) { + return this; + } + return wrapper; + } + + /** + * Sets the wrapper. + * @param wrapper The wrapper to set. + */ + public void setWrapper(Scenery wrapper) { + this.wrapper = wrapper; + } + + @SuppressWarnings("SuspiciousNameCombination") + @NotNull + public List getOccupiedTiles() { + List occupied = new ArrayList<>(); + occupied.add(location); + + int sizeX = getSizeX(); + int sizeY = getSizeY(); + + if (rotation % 2 == 1) { + int tmp = sizeX; + sizeX = sizeY; + sizeY = tmp; + } + + boolean sub = rotation >= 2; + + if (sizeX > 1) { + for (int i = 1; i < sizeX; i++) { + int modifier = sub ? -i : i; + occupied.add(location.transform(modifier, 0, 0)); + } + } + + if (sizeY > 1) { + for (int i = 1; i < sizeY; i++) { + int modifier = sub ? -i : i; + occupied.add(location.transform(0, modifier, 0)); + } + } + + return occupied; + } +} diff --git a/Server/src/main/core/game/node/scenery/SceneryBuilder.java b/Server/src/main/core/game/node/scenery/SceneryBuilder.java new file mode 100644 index 0000000..3dac14b --- /dev/null +++ b/Server/src/main/core/game/node/scenery/SceneryBuilder.java @@ -0,0 +1,270 @@ +package core.game.node.scenery; + +import core.game.node.item.GroundItem; +import core.game.node.item.GroundItemManager; +import core.tools.Log; +import core.tools.SystemLogger; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.map.build.LandscapeParser; +import core.game.world.update.flag.chunk.ObjectUpdateFlag; + +import static core.api.ContentAPIKt.log; + +/** + * An aiding class for object constructing/removing. + * + * @author Emperor + */ +public final class SceneryBuilder { + + /** + * Replaces a scenery. + * + * @param remove The object to remove. + * @param construct The object to add. + * @return {@code True} if successful. + */ + public static boolean replace(Scenery remove, Scenery construct) { + return replace(remove, construct, true, false); + } + + /** + * Replaces a scenery. + * + * @param remove The object to remove. + * @param construct The object to add. + * @param clip If clipping should be adjusted. + * @return {@code True} if successful. + */ + public static boolean replace(Scenery remove, Scenery construct, boolean clip, boolean permanent) { + if (!clip) { + return replaceClientSide(remove, construct, -1); + } + remove = remove.getWrapper(); + Scenery current = LandscapeParser.removeScenery(remove); + if (current == null) { + return false; + } + if (current.getRestorePulse() != null) { + current.getRestorePulse().stop(); + current.setRestorePulse(null); + } + if (current instanceof Constructed) { + Scenery previous = ((Constructed) current).getReplaced(); + if (previous != null && previous.equals(construct)) { + LandscapeParser.addScenery(previous); + update(current, previous); + return true; + } + } + Constructed constructed = construct.asConstructed(); + if (!permanent) { + constructed.setReplaced(current); + } + LandscapeParser.addScenery(constructed); + update(current, constructed); + return true; + } + + /** + * Replaces the object client sided alone. + * + * @param remove The object to remove. + * @param construct The object to replace with. + * @param restoreTicks The restoration ticks. + * @return {@code True} if successful. + */ + private static boolean replaceClientSide(final Scenery remove, final Scenery construct, int restoreTicks) { + RegionManager.getRegionChunk(remove.getLocation()).flag(new ObjectUpdateFlag(remove, true)); + RegionManager.getRegionChunk(construct.getLocation()).flag(new ObjectUpdateFlag(construct, false)); + if (restoreTicks > 0) { + GameWorld.getPulser().submit(new Pulse(restoreTicks) { + @Override + public boolean pulse() { + return replaceClientSide(construct, remove, -1); + } + }); + } + return true; + } + + /** + * Replaces a scenery temporarily. + * + * @param remove The object to remove. + * @param construct The object to add. + * @param restoreTicks The amount of ticks before the object gets restored. + * @return {@code True} if successful. + */ + public static boolean replace(Scenery remove, Scenery construct, int restoreTicks) { + return replace(remove, construct, restoreTicks, true); + } + + /** + * Replaces a scenery temporarily. + * + * @param remove The object to remove. + * @param construct The object to add. + * @param restoreTicks The amount of ticks before the object gets restored. + * @return {@code True} if successful. + */ + public static boolean replace(Scenery remove, Scenery construct, int restoreTicks, final boolean clip) { + if (!clip) { + return replaceClientSide(remove, construct, restoreTicks); + } + remove = remove.getWrapper(); + Scenery current = LandscapeParser.removeScenery(remove); + if (current == null) { + return false; + } + if (current.getRestorePulse() != null) { + current.getRestorePulse().stop(); + current.setRestorePulse(null); + } + if (current instanceof Constructed) { + Scenery previous = ((Constructed) current).getReplaced(); + if (previous != null && previous.equals(construct)) { + // Shouldn't happen. + throw new IllegalStateException("Can't temporarily replace an already temporary object!"); + } + } + final Constructed constructed = construct.asConstructed(); + constructed.setReplaced(current); + LandscapeParser.addScenery(constructed); + update(current, constructed); + if (restoreTicks < 0) { + return true; + } + constructed.setRestorePulse(new Pulse(restoreTicks) { + @Override + public boolean pulse() { + replace(constructed, constructed.getReplaced()); + return true; + } + }); + GameWorld.getPulser().submit(constructed.getRestorePulse()); + return true; + } + + /** + * Adds a scenery. + * + * @param object The object to add. + * @return {@code True} if successful. + */ + public static Constructed add(Scenery object) { + return add(object, -1); + } + + /** + * Adds a scenery. + * + * @param object The object to add. + * @param ticks The amount of ticks this object should last for (-1 for + * permanent). + * @return {@code True} if successful. + */ + public static Constructed add(Scenery object, int ticks, final GroundItem... items) { + object = object.getWrapper(); + final Constructed constructed = object.asConstructed(); + LandscapeParser.addScenery(constructed); + update(constructed); + if (ticks > -1) { + GameWorld.getPulser().submit(new Pulse(ticks, object) { + @Override + public boolean pulse() { + remove(constructed); + if (items != null) { + for (int i = 0; i < items.length; i++) { + GroundItemManager.create(items[i]); + } + } + return true; + } + }); + } + return constructed; + } + + /** + * Removes all objects within a box + * @param objectId - the object id to remove + * @param southWest + * @param northEast + * @return + */ + public static boolean removeAll(int objectId, Location southWest, Location northEast) { + if (southWest.getX() > northEast.getX() || southWest.getY() > northEast.getY()) + return false; + + int differenceX = northEast.getX() - southWest.getX(); + int differenceY = northEast.getY() - southWest.getY(); + + for (int x = 0; x <= differenceX; x++) { + for (int y = 0; y <= differenceY; y++){ + Scenery object = new Scenery(objectId, Location.create(southWest.getX() + x, southWest.getY() + y, southWest.getZ())); + remove(object); + } + } + return true; + } + + /** + * Removes a scenery. + * + * @param object The object to remove. + * @return {@code True} if successful. + */ + public static boolean remove(Scenery object) { + if (object == null) { + return false; + } + object = object.getWrapper(); + Scenery current = LandscapeParser.removeScenery(object); + if (current == null) { + return false; + } + update(current); + return true; + } + + /** + * Removes a scenery. + * + * @param object the object. + * @param respawnTicks the respawn ticks. + * @return {@code True}if removed. + */ + public static boolean remove(final Scenery object, int respawnTicks) { + if (remove(object)) { + GameWorld.getPulser().submit(new Pulse(respawnTicks) { + + @Override + public boolean pulse() { + add(object); + return true; + } + + }); + return true; + } + return false; + } + + /** + * Updates the scenery on all the player's screen. + * + * @param objects The scenerys. + */ + public static void update(Scenery... objects) { + for (Scenery o : objects) { + if (o == null) { + continue; + } + RegionManager.getRegionChunk(o.getLocation()).flag(new ObjectUpdateFlag(o, !o.isActive())); + } + } +} diff --git a/Server/src/main/core/game/requirement/Requirement.kt b/Server/src/main/core/game/requirement/Requirement.kt new file mode 100644 index 0000000..d43b68d --- /dev/null +++ b/Server/src/main/core/game/requirement/Requirement.kt @@ -0,0 +1,201 @@ +package core.game.requirement + +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.QuestRepository +import core.game.node.entity.skill.Skills +import kotlin.math.min + +import java.util.ArrayList +import content.data.Quests + +interface Requirement { + abstract fun evaluate (player: Player) : Pair> +} + +open class SkillReq (val skillId: Int, val level: Int, val soft: Boolean = false) : Requirement { + override fun evaluate (player: Player) : Pair> { + val hasLevelRequirement = getStatLevel(player, skillId) >= level //if (soft) getDynLevel(player, skillId) >= level else getStatLevel(player, skillId) >= level + if (hasLevelRequirement) return Pair (true, listOf()) + else return Pair(false, listOf(this)) + } +} + +open class QuestReq (val questReq: QuestRequirements, val stageRequired: Int = 100) : Requirement { + override fun evaluate (player: Player) : Pair> { + val quest = QuestRepository.getQuests()[questReq.quest] + val unmetRequirements = ArrayList() + var isMet = true + if (quest == null) { + for (req in questReq.requirements) { + val (met, reqs) = req.evaluate(player) + isMet = isMet && met + unmetRequirements.addAll(reqs) + } + unmetRequirements.add (QPCumulative(5)) + } else { + isMet = quest.getStage(player) >= stageRequired + if (!isMet) unmetRequirements.add(this) + unmetRequirements.add (QPCumulative(quest.getQuestPoints())) + } + + return Pair (isMet, unmetRequirements) + } +} + +open class QPReq (val amount: Int) : Requirement { + override fun evaluate (player: Player) : Pair> { + val needed = min(amount, player.questRepository.getAvailablePoints()) + val hasNeeded = player.questRepository.getPoints() >= needed + + return Pair (hasNeeded, if (hasNeeded) listOf() else listOf(this)) + } +} + +open class QPCumulative (val amount: Int) : Requirement { + override fun evaluate (player: Player) : Pair> { + return Pair (false, listOf(this)) + } +} + +enum class QuestRequirements(val quest: Quests, vararg val requirements: Requirement) { + COOK_ASSIST (Quests.COOKS_ASSISTANT), + DEMON_SLAYER (Quests.DEMON_SLAYER), + DORIC_QUEST (Quests.DORICS_QUEST), + DRAGON_SLAYER (Quests.DRAGON_SLAYER, QPReq(32)), + ERNEST (Quests.ERNEST_THE_CHICKEN), + GOBLIN_DIP (Quests.GOBLIN_DIPLOMACY), + IMP_CATCHER (Quests.IMP_CATCHER), + KNIGHT_SWORD (Quests.THE_KNIGHTS_SWORD, SkillReq(Skills.MINING, 10, true)), + PIRATE_T (Quests.PIRATES_TREASURE), + ALI_RESCUE (Quests.PRINCE_ALI_RESCUE), + RESTLESS_GHOST (Quests.THE_RESTLESS_GHOST), + ROMEO (Quests.ROMEO_JULIET), + RUNE_MYST (Quests.RUNE_MYSTERIES), + SHEEP (Quests.SHEEP_SHEARER), + ARRAV (Quests.SHIELD_OF_ARRAV), + VAMPIRE (Quests.VAMPIRE_SLAYER), + DORIC (Quests.DORICS_QUEST), + RUNE_MYSTERIES(Quests.RUNE_MYSTERIES), + BLACK_KNIGHT(Quests.BLACK_KNIGHTS_FORTRESS, QPReq(12)), + WITCH_POTION (Quests.WITCHS_POTION), + DRUIDIC_RITUAL (Quests.DRUIDIC_RITUAL), + LOST_CITY (Quests.LOST_CITY, SkillReq(Skills.CRAFTING, 31, true), SkillReq(Skills.WOODCUTTING, 36, true)), + WITCH_HOUSE (Quests.WITCHS_HOUSE), + MERLIN (Quests.MERLINS_CRYSTAL), + HERO (Quests.HEROES_QUEST, QPReq(55), SkillReq(Skills.COOKING, 53, true), SkillReq(Skills.FISHING, 53, true), SkillReq(Skills.HERBLORE, 25, true), SkillReq(Skills.MINING, 50, true), QuestReq(ARRAV), QuestReq(LOST_CITY), QuestReq(MERLIN), QuestReq(DRAGON_SLAYER)), + SCORP_CATCHER (Quests.SCORPION_CATCHER, SkillReq(Skills.PRAYER, 31)), + FAMILY_CREST (Quests.FAMILY_CREST, SkillReq(Skills.MINING, 40, true), SkillReq(Skills.SMITHING, 40, true), SkillReq(Skills.MAGIC, 59, true), SkillReq(Skills.CRAFTING, 40, true)), + FISHING_CONTEST (Quests.FISHING_CONTEST, SkillReq(Skills.FISHING, 10)), + TOTEM (Quests.TRIBAL_TOTEM, SkillReq(Skills.THIEVING, 21)), + MONK (Quests.MONKS_FRIEND), + IKOV (Quests.TEMPLE_OF_IKOV, SkillReq(Skills.THIEVING, 42, true), SkillReq(Skills.RANGE, 40)), + CLOCK_TOWER (Quests.CLOCK_TOWER), + GRAIL (Quests.HOLY_GRAIL, QuestReq (MERLIN), SkillReq (Skills.ATTACK, 20)), + GNOME_VILLAGE (Quests.TREE_GNOME_VILLAGE), + FIGHT_ARENA (Quests.FIGHT_ARENA), + HAZEEL (Quests.HAZEEL_CULT), + SHEEP_HERDER (Quests.SHEEP_HERDER), + PLAGUE_CITY (Quests.PLAGUE_CITY), + SEA_SLUG (Quests.SEA_SLUG, SkillReq(Skills.FIREMAKING, 30, true)), + WATERFALL (Quests.WATERFALL_QUEST), + POTION (Quests.JUNGLE_POTION, SkillReq(Skills.HERBLORE, 3, true), QuestReq(DRUIDIC_RITUAL)), + GRAND_TREE (Quests.THE_GRAND_TREE, SkillReq(Skills.AGILITY, 25, true)), + BIOHAZARD (Quests.BIOHAZARD, QuestReq(PLAGUE_CITY)), + UNDERGROUND_PASS (Quests.UNDERGROUND_PASS, SkillReq (Skills.RANGE, 25), QuestReq(BIOHAZARD), QuestReq(PLAGUE_CITY)), + OBSERVATORY (Quests.OBSERVATORY_QUEST), + TOURIST (Quests.THE_TOURIST_TRAP, SkillReq (Skills.FLETCHING, 10, true), SkillReq(Skills.SMITHING, 20, true)), + WATCHTOWER (Quests.WATCHTOWER, SkillReq (Skills.MAGIC, 14, true), SkillReq(Skills.THIEVING, 15, true), SkillReq (Skills.AGILITY, 25, true), SkillReq (Skills.HERBLORE, 14, true), SkillReq(Skills.MINING, 40, true)), + DWARF_CANNON (Quests.DWARF_CANNON), + MURDER_MYS (Quests.MURDER_MYSTERY), + DIG_SITE (Quests.THE_DIG_SITE, SkillReq(Skills.AGILITY, 10, true), SkillReq (Skills.HERBLORE, 10, true), SkillReq (Skills.THIEVING, 25, true)), + GERTRUDE (Quests.GERTRUDES_CAT), + SHILO (Quests.SHILO_VILLAGE, QuestReq(POTION), SkillReq(Skills.CRAFTING, 20, true), SkillReq(Skills.AGILITY, 32, true)), + LEGEND (Quests.LEGENDS_QUEST, QPReq(107), SkillReq(Skills.AGILITY, 50, true), SkillReq(Skills.CRAFTING, 50, true), SkillReq(Skills.HERBLORE, 45, true), SkillReq(Skills.MAGIC, 56, true), SkillReq(Skills.MINING, 52, true), SkillReq(Skills.PRAYER, 42, true), SkillReq(Skills.SMITHING, 50, true), SkillReq(Skills.STRENGTH, 50, true), SkillReq(Skills.THIEVING, 50, true), SkillReq(Skills.WOODCUTTING, 50, true), QuestReq(FAMILY_CREST), QuestReq(HERO), QuestReq(SHILO), QuestReq(UNDERGROUND_PASS), QuestReq(WATERFALL)), + DEATH_PLATEAU (Quests.DEATH_PLATEAU), + TROLL_STRONGHOLD (Quests.TROLL_STRONGHOLD, QuestReq(DEATH_PLATEAU), SkillReq(Skills.AGILITY, 15, true)), + EADGAR (Quests.EADGARS_RUSE, QuestReq (DRUIDIC_RITUAL), QuestReq (TROLL_STRONGHOLD), SkillReq(Skills.HERBLORE, 31, true)), + CHOMPY (Quests.BIG_CHOMPY_BIRD_HUNTING, SkillReq (Skills.FLETCHING, 5, true), SkillReq (Skills.COOKING, 30, true), SkillReq(Skills.RANGE, 30, false)), + ELEMENTAL_W1 (Quests.ELEMENTAL_WORKSHOP_I, SkillReq(Skills.MINING, 20, true), SkillReq(Skills.SMITHING, 20, true), SkillReq(Skills.CRAFTING, 20, true)), + PRIEST (Quests.PRIEST_IN_PERIL), + NATURE_SPIRIT (Quests.NATURE_SPIRIT, QuestReq(PRIEST), QuestReq(RESTLESS_GHOST)), + REGICIDE (Quests.REGICIDE, QuestReq (UNDERGROUND_PASS), SkillReq (Skills.CRAFTING, 10), SkillReq(Skills.AGILITY, 56, true)), + TAI_BWO (Quests.TAI_BWO_WANNAI_TRIO, SkillReq (Skills.AGILITY, 15, true), SkillReq(Skills.COOKING, 30), SkillReq(Skills.FISHING, 65, true), QuestReq(POTION)), + SHADES (Quests.SHADES_OF_MORTTON, QuestReq(PRIEST), SkillReq(Skills.CRAFTING, 20, true), SkillReq(Skills.HERBLORE, 15, true), SkillReq(Skills.FIREMAKING, 5, true)), + FREM_TRIALS (Quests.THE_FREMENNIK_TRIALS, SkillReq(Skills.FLETCHING, 25, true), SkillReq(Skills.WOODCUTTING, 40, true), SkillReq(Skills.CRAFTING, 40, true)), + HORROR_DEEP (Quests.HORROR_FROM_THE_DEEP, SkillReq(Skills.AGILITY, 35, true)), + THRONE (Quests.THRONE_OF_MISCELLANIA, QuestReq(HERO), QuestReq(FREM_TRIALS)), + MONKEY (Quests.MONKEY_MADNESS, QuestReq(GRAND_TREE), QuestReq(GNOME_VILLAGE)), + MINE (Quests.HAUNTED_MINE, QuestReq(PRIEST), SkillReq(Skills.CRAFTING, 35, true)), + TROLL_ROMANCE (Quests.TROLL_ROMANCE, QuestReq(TROLL_STRONGHOLD), SkillReq(Skills.AGILITY, 28, true)), + SEARCH_MYREQUE (Quests.IN_SEARCH_OF_THE_MYREQUE, QuestReq(NATURE_SPIRIT), SkillReq(Skills.AGILITY, 25, true)), + FENKENSTRAIN (Quests.CREATURE_OF_FENKENSTRAIN, QuestReq(PRIEST), QuestReq(RESTLESS_GHOST), SkillReq(Skills.THIEVING, 25, true), SkillReq(Skills.CRAFTING, 20, true)), + ROVING_ELVES (Quests.ROVING_ELVES, QuestReq(REGICIDE), QuestReq(WATERFALL), SkillReq(Skills.AGILITY, 56, true)), + GHOSTS_AHOY (Quests.GHOSTS_AHOY, QuestReq(PRIEST), QuestReq(RESTLESS_GHOST), SkillReq(Skills.AGILITY, 25, true), SkillReq(Skills.COOKING, 20, true)), + FAVOR (Quests.ONE_SMALL_FAVOUR, QuestReq(RUNE_MYSTERIES), QuestReq(SHILO), SkillReq(Skills.AGILITY, 36, true), SkillReq(Skills.CRAFTING, 25, true), SkillReq(Skills.HERBLORE, 18, true), SkillReq(Skills.SMITHING, 30, true)), + MOUNTAIN_DAUGHTER (Quests.MOUNTAIN_DAUGHTER, SkillReq(Skills.AGILITY, 20, true)), + BETWEEN_ROCK (Quests.BETWEEN_A_ROCK, QuestReq(DWARF_CANNON), QuestReq(FISHING_CONTEST), SkillReq(Skills.DEFENCE, 30, true), SkillReq(Skills.MINING, 40, true), SkillReq(Skills.SMITHING, 50, true)), + FEUD (Quests.THE_FEUD, SkillReq(Skills.THIEVING, 30)), + GOLEM (Quests.THE_GOLEM, SkillReq(Skills.CRAFTING, 20, true), SkillReq(Skills.THIEVING, 25, true)), + DESERT (Quests.DESERT_TREASURE, QuestReq (DIG_SITE), QuestReq (IKOV), QuestReq(TOURIST), QuestReq(TROLL_STRONGHOLD), QuestReq(PRIEST), QuestReq(WATERFALL), SkillReq(Skills.THIEVING, 53), SkillReq(Skills.MAGIC, 50), SkillReq(Skills.FIREMAKING, 50, true), SkillReq(Skills.SLAYER, 10)), + ICTHLARIN (Quests.ICTHLARINS_LITTLE_HELPER, QuestReq (GERTRUDE)), + TEARS_OF_GUTHIX (Quests.TEARS_OF_GUTHIX, QPReq(43), SkillReq(Skills.FIREMAKING, 49, true), SkillReq(Skills.CRAFTING, 20, true), SkillReq(Skills.MINING, 20, true)), + LOST_TRIBE (Quests.THE_LOST_TRIBE, QuestReq(GOBLIN_DIP), QuestReq(RUNE_MYSTERIES), SkillReq(Skills.AGILITY, 13, true), SkillReq(Skills.THIEVING, 13, true), SkillReq(Skills.MINING, 17, true)), + GIANT_DWARF (Quests.THE_GIANT_DWARF, SkillReq(Skills.CRAFTING, 12, true), SkillReq(Skills.FIREMAKING, 16, true), SkillReq(Skills.MAGIC, 33, true), SkillReq(Skills.THIEVING, 14, true)), + RECRUITMENT_DRIVE (Quests.RECRUITMENT_DRIVE, QuestReq (BLACK_KNIGHT), QuestReq(DRUIDIC_RITUAL)), + MEP_1 (Quests.MOURNINGS_END_PART_I, SkillReq(Skills.RANGE, 60), SkillReq(Skills.THIEVING, 50), QuestReq(ROVING_ELVES), QuestReq(CHOMPY), QuestReq(SHEEP_HERDER)), + FORGETTABLE (Quests.FORGETTABLE_TALE, SkillReq (Skills.COOKING, 22, true), SkillReq(Skills.FARMING, 17, true), QuestReq(GIANT_DWARF), QuestReq(FISHING_CONTEST)), + GARDEN (Quests.GARDEN_OF_TRANQUILITY, QuestReq(FENKENSTRAIN), SkillReq(Skills.FARMING, 25)), + TWO_CATS (Quests.A_TAIL_OF_TWO_CATS, QuestReq(ICTHLARIN)), + WANTED (Quests.WANTED, QPReq(32), QuestReq(RECRUITMENT_DRIVE), QuestReq(LOST_TRIBE), QuestReq(PRIEST)), + MEP_2 (Quests.MOURNINGS_END_PART_II, QuestReq(MEP_1)), + ZOGRE (Quests.ZOGRE_FLESH_EATERS, QuestReq(CHOMPY), QuestReq(POTION), SkillReq(Skills.SMITHING, 4, true), SkillReq(Skills.HERBLORE, 8, true), SkillReq(Skills.RANGE, 30)), + RUM_DEAL (Quests.RUM_DEAL, QuestReq(ZOGRE), QuestReq(PRIEST), SkillReq(Skills.CRAFTING, 42, true), SkillReq(Skills.FISHING, 50, true), SkillReq(Skills.FARMING, 40, true), SkillReq(Skills.PRAYER, 47, true), SkillReq(Skills.SLAYER, 42)), + SHADOW (Quests.SHADOW_OF_THE_STORM, SkillReq(Skills.CRAFTING, 30, true), QuestReq(GOLEM), QuestReq(DEMON_SLAYER)), + HISTORY (Quests.MAKING_HISTORY, QuestReq(PRIEST), QuestReq(RESTLESS_GHOST)), + RATCATCHERS (Quests.RATCATCHERS, QuestReq(ICTHLARIN), QuestReq(GIANT_DWARF)), + SPIRITS_ELID (Quests.SPIRITS_OF_THE_ELID, SkillReq(Skills.MAGIC, 33, true), SkillReq(Skills.RANGE, 37, true), SkillReq(Skills.MINING, 37, true), SkillReq(Skills.THIEVING, 37, true)), + DEVIOUS (Quests.DEVIOUS_MINDS, SkillReq(Skills.SMITHING, 65, true), SkillReq(Skills.RUNECRAFTING, 50, true), SkillReq(Skills.FLETCHING, 50, true), QuestReq(WANTED), QuestReq(TROLL_STRONGHOLD), QuestReq(DORIC)), + SAND (Quests.THE_HAND_IN_THE_SAND, SkillReq(Skills.THIEVING, 17, true), SkillReq(Skills.CRAFTING, 49, true)), + ENAKHRA (Quests.ENAKHRAS_LAMENT, SkillReq(Skills.CRAFTING, 50, true), SkillReq(Skills.FIREMAKING, 45, true), SkillReq(Skills.PRAYER, 43, true), SkillReq(Skills.MAGIC, 39, true)), + CABIN_FEVER (Quests.CABIN_FEVER, QuestReq(PIRATE_T), QuestReq(RUM_DEAL), SkillReq(Skills.AGILITY, 42), SkillReq(Skills.CRAFTING, 45), SkillReq(Skills.SMITHING, 50), SkillReq(Skills.RANGE, 40)), + FAIRYTALE_1 (Quests.FAIRYTALE_I_GROWING_PAINS, QuestReq(LOST_CITY), QuestReq(NATURE_SPIRIT)), + RFD (Quests.RECIPE_FOR_DISASTER, QPReq(175), QuestReq(COOK_ASSIST), SkillReq(Skills.COOKING, 70, true), SkillReq(Skills.AGILITY, 48, true), SkillReq(Skills.MINING, 50, true), SkillReq(Skills.FISHING, 53, true), SkillReq(Skills.THIEVING, 53, true), SkillReq(Skills.HERBLORE, 25, true), SkillReq(Skills.MAGIC, 59, true), SkillReq(Skills.SMITHING, 40, true), SkillReq(Skills.FIREMAKING, 50, true), SkillReq(Skills.RANGE, 40), SkillReq(Skills.CRAFTING, 40, true), SkillReq(Skills.FLETCHING, 10, true), SkillReq(Skills.WOODCUTTING, 36, true), QuestReq(FISHING_CONTEST), QuestReq(GOBLIN_DIP), QuestReq(CHOMPY), QuestReq(MURDER_MYS), QuestReq(NATURE_SPIRIT), QuestReq(WITCH_HOUSE), QuestReq(GERTRUDE), QuestReq(SHADOW), QuestReq(LEGEND), QuestReq(MONKEY), QuestReq(DESERT), QuestReq(HORROR_DEEP)), + AID_MYREQUE (Quests.IN_AID_OF_THE_MYREQUE, QuestReq(SEARCH_MYREQUE), SkillReq(Skills.AGILITY, 25, true), SkillReq(Skills.CRAFTING, 25), SkillReq(Skills.MINING, 15), SkillReq(Skills.MAGIC, 7, true)), + SOUL_BANE (Quests.A_SOULS_BANE), + BONE_MAN_1 (Quests.RAG_AND_BONE_MAN), + SWAN (Quests.SWAN_SONG, QPReq(100), SkillReq(Skills.MAGIC, 66, true), SkillReq(Skills.COOKING, 62, true), SkillReq(Skills.FISHING, 62, true), SkillReq(Skills.SMITHING, 45, true), SkillReq(Skills.FIREMAKING, 42, true), SkillReq(Skills.CRAFTING, 40, true), QuestReq(FAVOR), QuestReq(GARDEN)), + ROYAL_TROUBLE (Quests.ROYAL_TROUBLE, SkillReq(Skills.AGILITY, 40, true), SkillReq(Skills.SLAYER, 40, true), QuestReq(THRONE)), + DEATH_DORGESHUUN (Quests.DEATH_TO_THE_DORGESHUUN, QuestReq(LOST_TRIBE), SkillReq(Skills.AGILITY, 23, true), SkillReq(Skills.THIEVING, 23, true)), + FAIRYTALE_2 (Quests.FAIRYTALE_II_CURE_A_QUEEN, QuestReq(FAIRYTALE_1), SkillReq(Skills.THIEVING, 40), SkillReq(Skills.FARMING, 49, true), SkillReq(Skills.HERBLORE, 57, true)), + LUNAR_DIPLOMACY (Quests.LUNAR_DIPLOMACY, QuestReq(FREM_TRIALS), QuestReq(LOST_CITY), QuestReq(RUNE_MYSTERIES), QuestReq(SHILO), SkillReq(Skills.HERBLORE, 5), SkillReq(Skills.CRAFTING, 61), SkillReq(Skills.DEFENCE, 40), SkillReq(Skills.FIREMAKING, 49), SkillReq(Skills.MAGIC, 65), SkillReq(Skills.MINING, 60), SkillReq(Skills.WOODCUTTING, 55)), + GLOUPHRIE (Quests.THE_EYES_OF_GLOUPHRIE, QuestReq(GRAND_TREE), SkillReq(Skills.CONSTRUCTION, 5), SkillReq(Skills.MAGIC, 46)), + HALLOWVALE (Quests.DARKNESS_OF_HALLOWVALE, QuestReq(AID_MYREQUE), SkillReq(Skills.CONSTRUCTION, 5, true), SkillReq(Skills.MINING, 20), SkillReq(Skills.THIEVING, 22), SkillReq(Skills.AGILITY, 26, true), SkillReq(Skills.CRAFTING, 32), SkillReq(Skills.MAGIC, 33, true), SkillReq(Skills.STRENGTH, 40)), + SLUG_MENACE (Quests.THE_SLUG_MENACE, QuestReq(WANTED), QuestReq(SEA_SLUG), SkillReq(Skills.CRAFTING, 30), SkillReq(Skills.RUNECRAFTING, 30), SkillReq(Skills.SLAYER, 30), SkillReq(Skills.THIEVING, 30)), + ELEMENTAL_W2 (Quests.ELEMENTAL_WORKSHOP_II, QuestReq(ELEMENTAL_W1), SkillReq(Skills.MAGIC, 20, true), SkillReq(Skills.SMITHING, 30, true)), + ARM_ADVENTURE (Quests.MY_ARMS_BIG_ADVENTURE, SkillReq(Skills.FARMING, 29, true), SkillReq(Skills.WOODCUTTING, 10), QuestReq(EADGAR), QuestReq(FEUD), QuestReq(POTION)), + ENL_JOURNEY (Quests.ENLIGHTENED_JOURNEY, QPReq(20), SkillReq(Skills.FIREMAKING, 20, true), SkillReq(Skills.FARMING, 30, true), SkillReq(Skills.CRAFTING, 36, true)), + EAGLE (Quests.EAGLES_PEAK, SkillReq(Skills.HUNTER, 27, true)), + ANMA (Quests.ANIMAL_MAGNETISM, QuestReq(RESTLESS_GHOST), QuestReq(ERNEST), QuestReq(PRIEST), SkillReq(Skills.SLAYER, 18), SkillReq(Skills.CRAFTING, 19), SkillReq(Skills.RANGE, 30), SkillReq(Skills.WOODCUTTING, 35)), + CONTACT (Quests.CONTACT, QuestReq(ALI_RESCUE), QuestReq(ICTHLARIN)), + COLD_WAR (Quests.COLD_WAR, SkillReq(Skills.HUNTER, 10), SkillReq(Skills.AGILITY, 30, true), SkillReq(Skills.CRAFTING, 30), SkillReq(Skills.CONSTRUCTION, 34), SkillReq(Skills.THIEVING, 15)), + FREM_ISLES (Quests.THE_FREMENNIK_ISLES, QuestReq(FREM_TRIALS), SkillReq(Skills.CONSTRUCTION, 20, true)), + BRAIN_ROBBERY (Quests.THE_GREAT_BRAIN_ROBBERY, SkillReq(Skills.CRAFTING, 16), SkillReq(Skills.CONSTRUCTION, 30), SkillReq(Skills.PRAYER, 50), QuestReq(FENKENSTRAIN), QuestReq(CABIN_FEVER), QuestReq(RFD)), + WHAT_LIES_BELOW (Quests.WHAT_LIES_BELOW, QuestReq(RUNE_MYSTERIES), SkillReq(Skills.RUNECRAFTING, 35)), + OLAF (Quests.OLAFS_QUEST, QuestReq(FREM_TRIALS), SkillReq(Skills.FIREMAKING, 40, true), SkillReq(Skills.WOODCUTTING, 50, true)), + ANOTHER_SLICE (Quests.ANOTHER_SLICE_OF_HAM, SkillReq(Skills.ATTACK, 15), SkillReq(Skills.PRAYER, 25), QuestReq(DEATH_DORGESHUUN), QuestReq(GIANT_DWARF), QuestReq(DIG_SITE)), + DREAM_MENTOR (Quests.DREAM_MENTOR, QuestReq(LUNAR_DIPLOMACY), QuestReq(EADGAR)), + GRIM_TALES (Quests.GRIM_TALES, QuestReq(WITCH_HOUSE), SkillReq(Skills.FARMING, 45, true), SkillReq(Skills.HERBLORE, 52, true), SkillReq(Skills.THIEVING, 58, true), SkillReq(Skills.AGILITY, 59, true), SkillReq(Skills.WOODCUTTING, 71, true)), + KINGS_RANSOM (Quests.KINGS_RANSOM, SkillReq(Skills.MAGIC, 45), SkillReq(Skills.MINING, 45, true), SkillReq(Skills.DEFENCE, 65), QuestReq(BLACK_KNIGHT), QuestReq(GRAIL), QuestReq(MURDER_MYS), QuestReq(FAVOR)), + TOWER_OF_LIFE (Quests.TOWER_OF_LIFE, SkillReq(Skills.CONSTRUCTION, 10)), + BONE_MAN_2 (Quests.RAG_AND_BONE_MAN, SkillReq(Skills.SLAYER, 40, true), SkillReq(Skills.DEFENCE, 20), QuestReq(BONE_MAN_1), QuestReq(FREM_TRIALS), QuestReq(FENKENSTRAIN), QuestReq(ZOGRE), QuestReq(WATERFALL)), + LAND_GOBLINS (Quests.LAND_OF_THE_GOBLINS, QuestReq(ANOTHER_SLICE), QuestReq(FISHING_CONTEST), SkillReq(Skills.AGILITY, 38), SkillReq(Skills.FISHING, 40), SkillReq(Skills.THIEVING, 45), SkillReq(Skills.HERBLORE, 48)), + PATH_GLOUPHRIE (Quests.THE_PATH_OF_GLOUPHRIE, QuestReq(GLOUPHRIE), QuestReq(GNOME_VILLAGE), QuestReq(WATERFALL), SkillReq(Skills.AGILITY, 45), SkillReq(Skills.RANGE, 47), SkillReq(Skills.SLAYER, 56), SkillReq(Skills.STRENGTH, 60), SkillReq(Skills.THIEVING, 56)), + DEFENDER_VARROCK (Quests.DEFENDER_OF_VARROCK, QuestReq(ARRAV), QuestReq(KNIGHT_SWORD), QuestReq(DEMON_SLAYER), QuestReq(IKOV), QuestReq(FAMILY_CREST), QuestReq(WHAT_LIES_BELOW), QuestReq(GARDEN), SkillReq(Skills.AGILITY, 51), SkillReq(Skills.HUNTER, 51), SkillReq(Skills.MINING, 59), SkillReq(Skills.SMITHING, 54)), + SPIRIT_OF_SUMMER (Quests.SPIRIT_OF_SUMMER, QuestReq(RESTLESS_GHOST), SkillReq(Skills.CONSTRUCTION, 40), SkillReq(Skills.FARMING, 26), SkillReq(Skills.PRAYER, 35), SkillReq(Skills.SUMMONING, 19)), + SUMMERS_END (Quests.SUMMERS_END, QuestReq(SPIRIT_OF_SUMMER), SkillReq(Skills.FIREMAKING, 47), SkillReq(Skills.HUNTER, 35), SkillReq(Skills.MINING, 45), SkillReq(Skills.PRAYER, 55), SkillReq(Skills.SUMMONING, 23), SkillReq(Skills.WOODCUTTING, 37)), + SEERGAZE (Quests.LEGACY_OF_SEERGAZE, QuestReq(HALLOWVALE), SkillReq(Skills.AGILITY, 29), SkillReq(Skills.CONSTRUCTION, 20), SkillReq(Skills.CRAFTING, 47), SkillReq(Skills.FIREMAKING, 40), SkillReq(Skills.MAGIC, 49), SkillReq(Skills.MINING, 35), SkillReq(Skills.SLAYER, 31)), + SMOKING_KILLS (Quests.SMOKING_KILLS, QuestReq(RESTLESS_GHOST), QuestReq(ICTHLARIN), SkillReq(Skills.CRAFTING, 25), SkillReq(Skills.SLAYER, 35)), + WHILE_GUTHIX_SLEEPS (Quests.WHILE_GUTHIX_SLEEPS, SkillReq(Skills.SUMMONING, 23), SkillReq(Skills.HUNTER, 55), SkillReq(Skills.THIEVING, 60), SkillReq(Skills.DEFENCE, 65), SkillReq(Skills.FARMING, 65), SkillReq(Skills.HERBLORE, 65), SkillReq(Skills.MAGIC, 75), QuestReq(DEFENDER_VARROCK), QuestReq(DREAM_MENTOR), QuestReq(SAND), QuestReq(KINGS_RANSOM), QuestReq(LEGEND), QuestReq(MEP_2), QuestReq(PATH_GLOUPHRIE), QuestReq(RFD), QuestReq(SUMMERS_END), QuestReq(SWAN), QuestReq(TEARS_OF_GUTHIX), QuestReq(ZOGRE)), + ALL_FIRED_UP (Quests.ALL_FIRED_UP, QuestReq(PRIEST), SkillReq(Skills.FIREMAKING, 43)) +} diff --git a/Server/src/main/core/game/shops/Shop.kt b/Server/src/main/core/game/shops/Shop.kt new file mode 100644 index 0000000..d19a4c2 --- /dev/null +++ b/Server/src/main/core/game/shops/Shop.kt @@ -0,0 +1,459 @@ +package core.game.shops + +import core.ServerConstants +import core.api.* +import core.game.component.Component +import core.game.container.* +import core.game.container.Container +import core.game.event.ItemShopPurchaseEvent +import core.game.event.ItemShopSellEvent +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.shops.Shops.Companion.logShop +import core.game.system.config.ItemConfigParser +import core.game.world.GameWorld +import core.net.packet.PacketRepository +import core.net.packet.context.ContainerContext +import core.net.packet.out.ContainerPacket +import org.rs09.consts.Components +import org.rs09.consts.Items +import java.lang.Integer.max +import java.lang.Integer.min +import kotlin.math.ceil +import kotlin.math.roundToInt + +data class ShopItem(var itemId: Int, var amount: Int, val restockRate: Int = 100) + +class ShopListener(val player: Player) : ContainerListener +{ + var enabled = false + override fun update(c: Container?, event: ContainerEvent?) { + PacketRepository.send(ContainerPacket::class.java, ContainerContext(player, -1, -1, 92, event!!.items, false, *event.slots)) + } + + override fun refresh(c: Container?) { + PacketRepository.send(ContainerPacket::class.java, ContainerContext(player, -1, -1, 92, c!!.toArray(), c.capacity(), false)) + } +} + +class Shop(val title: String, val stock: Array, val general: Boolean = false, val currency: Int = Items.COINS_995, val highAlch: Boolean = false, val forceShared: Boolean = false) +{ + val stockInstances = HashMap() + val playerStock = if (general) generalPlayerStock else Container(40, ContainerType.SHOP) + val needsUpdate = HashMap() + val restockRates = HashMap() + + init { + if(!getServerConfig().getBoolean(Shops.personalizedShops, false) || forceShared) + stockInstances[ServerConstants.SERVER_NAME.hashCode()] = generateStockContainer() + } + + fun openFor(player: Player) + { + val cont = getContainer(player) + setInterfaceText(player, title, 620, 22) + setAttribute(player, "shop", this) + setAttribute(player, "shop-cont", cont) + openInterface(player, Components.SHOP_TEMPLATE_620) + player.interfaceManager.openSingleTab(Component(Components.SHOP_TEMPLATE_SIDE_621)) + showTab(player, true) + logShop("Opening shop [Title: $title, Player: ${player.username}]") + } + + fun showTab(player: Player, main: Boolean) + { + val cont = if (main) getAttribute(player, "shop-cont", null) ?: return else playerStock + + if(!main) + { + cont.listeners.remove(listenerInstances[player.details.uid]) + playerStock.listeners.add(listenerInstances[player.details.uid]) + } + else + { + playerStock.listeners.remove(listenerInstances[player.details.uid]) + cont.listeners.add(listenerInstances[player.details.uid]) + } + + val settings = IfaceSettingsBuilder() + .enableOptions(0..9) + .build() + + player.packetDispatch.sendIfaceSettings(settings, if (main) 23 else 24, Components.SHOP_TEMPLATE_620, 0, cont.capacity()) + player.packetDispatch.sendRunScript(150, "IviiiIsssssssss", "", "", "", "", "Buy X", "Buy 10", "Buy 5", "Buy 1", "Value", -1, 0, 4, 10, 92, (620 shl 16) or if (main) 23 else 24) + player.packetDispatch.sendInterfaceConfig(620, 23, !main) + player.packetDispatch.sendInterfaceConfig(620, 24, main) + player.packetDispatch.sendInterfaceConfig(620, 29, !main) + player.packetDispatch.sendInterfaceConfig(620, 25, main) + player.packetDispatch.sendInterfaceConfig(620, 27, main) + player.packetDispatch.sendInterfaceConfig(620, 26, false) + + if (!main) playerStock.refresh() + else cont.refresh() + + setAttribute(player, "shop-main", main) + } + + public fun getContainer(player: Player) : Container + { + val container = if(getServerConfig().getBoolean(Shops.personalizedShops, false) && !forceShared) + stockInstances[player.details.uid] ?: generateStockContainer().also { stockInstances[player.details.uid] = it } + else + stockInstances[ServerConstants.SERVER_NAME.hashCode()] ?: generateStockContainer().also { stockInstances[ServerConstants.SERVER_NAME.hashCode()] = it } + + val listener = listenerInstances[player.details.uid] + + if(listener != null && listener.player != player) + { + container.listeners.remove(listener) + } + + if(listener == null || listener.player != player) + { + listenerInstances[player.details.uid] = ShopListener(player) + } + + return container + } + + private fun generateStockContainer(): Container + { + val container = Container(40, ContainerType.SHOP) + for(item in stock) { + container.add(Item(item.itemId,item.amount)) + restockRates[item.itemId] = item.restockRate + } + + return container + } + + fun restock() + { + stockInstances.filter { needsUpdate[it.key] == true }.forEach{ (player,cont) -> + for(i in 0 until cont.capacity()) + { + if(cont[i] == null) continue + if(stock.size < i + 1) break + if(stock[i].restockRate == 0) continue + if(GameWorld.ticks % stock[i].restockRate != 0) continue + + if(cont[i].amount < stock[i].amount){ + cont[i].amount++ + cont.event.flag(i, cont[i]) + } + else if(cont[i].amount > stock[i].amount){ + cont[i].amount-- + cont.event.flag(i, cont[i]) + } + if(cont[i].amount != stock[i].amount) needsUpdate[player] = true + } + cont.update() + } + } + + fun getBuyPrice(player: Player, slot: Int): Item + { + val isMainStock = getAttribute(player, "shop-main", true) + val cont = if (isMainStock) getAttribute(player, "shop-cont", null) ?: return Item(-1,-1) else playerStock + val item = cont[slot] + + if (item == null) { + player.sendMessage("That item doesn't appear to be there anymore. Please try again.") + return Item(-1, -1) + } + + val price = when(currency) + { + Items.TOKKUL_6529 -> item.definition.getConfiguration(ItemConfigParser.TOKKUL_PRICE, 1) + Items.ARCHERY_TICKET_1464 -> item.definition.getConfiguration(ItemConfigParser.ARCHERY_TICKET_PRICE, 1) + Items.CASTLE_WARS_TICKET_4067 -> item.definition.getConfiguration(ItemConfigParser.CASTLE_WARS_TICKET_PRICE, 1) + else -> getGPCost(Item(item.id, 1), if (isMainStock) stock[item.slot].amount else playerStock[slot].amount, if (isMainStock) item.amount else playerStock[slot].amount) + } + + return Item(currency, price) + } + + fun getSellPrice(player: Player, slot: Int): Pair + { + val shopCont = getAttribute(player, "shop-cont", null) ?: return Pair(null, Item(-1,-1)) + val item = player.inventory[slot] + + if (item == null) { + player.debug("Inventory slot $slot does not contain an item!") + player.sendMessage("That item doesn't seem to be there anymore. Please try again.") + return Pair(null, Item(-1,-1)) + } + + val shopItemId = if (item.definition.isUnnoted) { + item.id + } + else + { + item.noteChange + } + var (isPlayerStock, shopSlot) = getStockSlot(shopItemId) + + val stockAmt = + if(isPlayerStock) + 0 + else{ + if(shopSlot != -1) stock[shopSlot].amount + else 0 + } + val currentAmt = + if(isPlayerStock) playerStock.getAmount(shopItemId) + else { + if(shopSlot != -1) shopCont[shopSlot].amount + else { + isPlayerStock = true + 0 + } + } + + val price = when(currency) + { + Items.TOKKUL_6529 -> (item.definition.getConfiguration(ItemConfigParser.TOKKUL_PRICE, 1) / 10.0).toInt() // selling items authentically return 10x less tokkul (floored/truncated) than the item's shop price + Items.ARCHERY_TICKET_1464 -> item.definition.getConfiguration(ItemConfigParser.ARCHERY_TICKET_PRICE, 1) + Items.CASTLE_WARS_TICKET_4067 -> item.definition.getConfiguration(ItemConfigParser.CASTLE_WARS_TICKET_PRICE, 1) + else -> getGPSell(Item(shopItemId, 1), stockAmt, currentAmt) + } + + if(!general && stockAmt == 0 && shopSlot == -1) + { + return Pair(null, Item(-1,-1)) + } + + return Pair(if (isPlayerStock) playerStock else shopCont, Item(currency, price)) + } + + private fun getGPCost(item: Item, stockAmount: Int, currentAmt: Int): Int + { + var mod: Int + mod = if(stockAmount == 0) 100 + else if(currentAmt == 0) 130 + else if(currentAmt >= stockAmount) 100 + else 130 - (130 - 100) * currentAmt / stockAmount + if(mod < 1) mod = 1 + mod = max(100, min(130, mod)) + + + val price: Int = ceil(item.definition.value * mod.toDouble() / 100.0).toInt() + /* if(player.getVarp(532) == 6529){ + price = 3 * price / 2 + }*/ + return max(price, 1) + } + + private fun getGPSell(item: Item, stockAmount: Int, currentAmt: Int): Int + { + val base = item.definition.getAlchemyValue(highAlch) + var overstock = currentAmt - stockAmount + if (overstock < 0) { + return base + } + if (overstock > 10) { + overstock = 10 + } + val price = (base - (item.definition.value * 0.03 * overstock)).roundToInt() + if (price < 1) { + return 1 + } + return price + } + + fun buy(player: Player, slot: Int, amount: Int) : TransactionStatus + { + if(amount !in 1..Integer.MAX_VALUE) return TransactionStatus.Failure("Invalid amount: $amount") + val isMainStock = getAttribute(player, "shop-main", false) + if(!isMainStock && player.ironmanManager.isIronman) + { + sendDialogue(player, "As an ironman, you cannot buy from player stock in shops.") + return TransactionStatus.Failure("Ironman buying from player stock") + } + val cont = if (isMainStock) (getAttribute(player, "shop-cont", null) ?: return TransactionStatus.Failure("Invalid shop-cont attr")) else playerStock + val inStock = cont[slot] + val item = Item(inStock.id, amount) + if(inStock.amount < amount) + item.amount = inStock.amount + if (item.amount > player.inventory.getMaximumAdd(item)) + item.amount = player.inventory.getMaximumAdd(item) + + if(inStock.amount == 0) { + sendMessage(player, "This item is out of stock.") + return TransactionStatus.Failure("Shop item out of stock.") + } + + if(isMainStock && inStock.amount > stock[slot].amount && (!getServerConfig().getBoolean(Shops.personalizedShops, false) || forceShared) && player.ironmanManager.isIronman) + { + sendDialogue(player, "As an ironman, you cannot buy overstocked items from shops.") + return TransactionStatus.Failure("Ironman overstock purchase") + } + + val cost = getBuyPrice(player, slot) + if(cost.id == -1) sendMessage(player, "This shop cannot sell that item.").also { return TransactionStatus.Failure("Shop cannot sell this item") } + + if(currency == Items.COINS_995){ + var amt = item.amount + var inStockAmt = inStock.amount + while(amt-- > 1) + cost.amount += getGPCost(Item(item.id, 1), if (isMainStock) stock[slot].amount else playerStock[slot].amount, --inStockAmt) + } else { + cost.amount = cost.amount * item.amount + } + + if(inInventory(player, cost.id, cost.amount)) + { + if(removeItem(player, cost)) + { + if (item.amount == 0) { + item.amount = 1 + } + if(!hasSpaceFor(player, item)) { + addItem(player, cost.id, cost.amount) + sendMessage(player, "You don't have enough inventory space to buy that many.") + return TransactionStatus.Failure("Not enough inventory space") + } + + if(!isMainStock && cont[slot].amount - item.amount == 0) + { + cont.remove(cont[slot], false) + cont.refresh() + } + else { + cont[slot].amount -= item.amount + cont.event.flag(slot, cont[slot]) + cont.update() + } + + addItem(player, item.id, item.amount) + + if(getServerConfig().getBoolean(Shops.personalizedShops, false)){ + needsUpdate[player.details.uid] = true + } else { + needsUpdate[ServerConstants.SERVER_NAME.hashCode()] = true + } + } + } + else + { + sendMessage(player, "You don't have enough ${cost.name.lowercase()} to buy that many.") + return TransactionStatus.Failure("Not enough money in inventory") + } + + player.dispatch(ItemShopPurchaseEvent(item.id, item.amount, cost)) + return TransactionStatus.Success() + } + + fun sell(player: Player, slot: Int, amount: Int) : TransactionStatus + { + if(amount !in 1..Integer.MAX_VALUE) return TransactionStatus.Failure("Invalid amount: $amount") + val playerInventory = player.inventory[slot] + if(playerInventory.id in intArrayOf(Items.COINS_995, Items.TOKKUL_6529, Items.ARCHERY_TICKET_1464)) + { + sendMessage(player, "You can't sell currency to a shop.") + return TransactionStatus.Failure("Tried to sell currency - ${playerInventory.id}") + } + val item = Item(playerInventory.id, amount) + val def = itemDefinition(item.id) + + if (def.hasDestroyAction()) { + sendMessage(player, "You can't sell this item.") + return TransactionStatus.Failure("Attempt to sell a destroyable - ${playerInventory.id}.") + } + + if (!def.isTradeable) { + sendMessage(player, "You can't sell this item.") + return TransactionStatus.Failure("Attempt to sell an untradeable - ${playerInventory.id}.") + } + + val (container,profit) = getSellPrice(player, slot) + if(profit.amount == -1) sendMessage(player, "This item can't be sold to this shop.").also { return TransactionStatus.Failure("Can't sell this item to this shop - ${playerInventory.id}, general: $general, price: $profit") } + if(amount > player.inventory.getAmount(item.id)) + item.amount = player.inventory.getAmount(item.id) + + val id = if(!item.definition.isUnnoted) item.noteChange else item.id + val (isPlayerStock, shopSlot) = getStockSlot(id) + + if(isPlayerStock && shopSlot == -1 && generalPlayerStock.freeSlots() == 0) { + sendMessage(player, "The shop is too full to buy any more items") + return TransactionStatus.Failure("Attempt to sell to full shop.") + } + + if(currency == Items.COINS_995 && item.amount > 1){ + var amt = item.amount + var inStockAmt = container!![shopSlot]?.amount ?: playerStock.getAmount(id) + while(amt-- > 1) + profit.amount += getGPSell(Item(item.id, 1), if (isPlayerStock) 0 else stock[shopSlot].amount, ++inStockAmt) + } else { + profit.amount = profit.amount * item.amount + } + + if(removeItem(player, item)) + { + if(!hasSpaceFor(player, profit)){ + sendMessage(player, "You don't have enough space to do that.") + addItem(player, item.id, item.amount) + return TransactionStatus.Failure("Did not have enough inventory space") + } + if(container == playerStock && getAttribute(player, "shop-main", false)){ + showTab(player, false) + } + else if(!getAttribute(player, "shop-main", false) && container != playerStock) + { + showTab(player, true) + } + addItem(player, profit.id, profit.amount) + if(!item.definition.isUnnoted) + { + item.id = item.noteChange + } + container?.add(item) + container?.refresh() + if(getServerConfig().getBoolean(Shops.personalizedShops, false)){ + needsUpdate[player.details.uid] = true + } else { + needsUpdate[ServerConstants.SERVER_NAME.hashCode()] = true + } + } + + player.dispatch(ItemShopSellEvent(item.id, item.amount, profit)) + return TransactionStatus.Success() + } + + fun getStockSlot(itemId: Int): Pair + { + var shopSlot: Int = -1 + var isPlayerStock = false + val notechange = itemDefinition(itemId).noteId + for((stockSlot, shopItem) in stock.withIndex()) + { + if(shopItem.itemId == itemId || shopItem.itemId == notechange) + shopSlot = stockSlot + } + if(shopSlot == -1) + { + for((stockSlot, playerStockItem) in playerStock.toArray().withIndex()) + { + if(playerStockItem == null) continue + if(playerStockItem.id == itemId || playerStockItem.id == notechange) { + shopSlot = stockSlot + isPlayerStock = true + } + } + } + + if(shopSlot == -1) isPlayerStock = true + return Pair(isPlayerStock, shopSlot) + } + + companion object { + //General stores globally share player stock (weird quirk, right?) + val generalPlayerStock = Container(40, ContainerType.SHOP) + val listenerInstances = HashMap() + } + + sealed class TransactionStatus { + class Success : TransactionStatus() + class Failure(val reason: String) : TransactionStatus() + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/shops/Shops.kt b/Server/src/main/core/game/shops/Shops.kt new file mode 100644 index 0000000..0a649a8 --- /dev/null +++ b/Server/src/main/core/game/shops/Shops.kt @@ -0,0 +1,297 @@ +package core.game.shops + +import content.global.skill.crafting.TanningProduct +import core.ServerConstants +import core.api.* +import core.game.ge.GrandExchange +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.interaction.InterfaceListener +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.system.command.Privilege +import core.tools.END_DIALOGUE +import core.tools.Log +import core.tools.secondsToTicks +import org.json.simple.JSONArray +import org.json.simple.JSONObject +import org.json.simple.parser.JSONParser +import org.rs09.consts.Components +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import java.io.FileReader +import content.data.Quests + +/** + * The "controller" class for shops. Handles opening shops from various NPC interactions and updating stock, etc. + * Note: If you wish to enable personalized shops, add and set the personalized_shops entry to true in the world section of the server config. + * ex: + * ```toml + * [world] + * personalized_shops = true + * ``` + */ +class Shops : StartupListener, TickListener, InteractionListener, InterfaceListener, Commands { + companion object { + @JvmStatic val personalizedShops = "world.personalized_shops" + @JvmStatic val shopsById = HashMap() + @JvmStatic val shopsByNpc = HashMap() + private var lastPlayerStockClear = 0 + + @JvmStatic fun openId(player: Player, id: Int) + { + shopsById[id]?.openFor(player) + } + + fun logShop(msg: String) + { + log(this::class.java, Log.FINE, "[SHOPS] $msg") + } + + fun parseStock(stock: String, id: Int): ArrayList{ + val items = ArrayList() + val idsInStock = HashMap() + if(stock.isEmpty()){ + return items + } + stock.split('-').map { + try { + val tokens = it.replace("{", "").replace("}", "").split(",".toRegex()).toTypedArray() + var amount = tokens[1].trim() + if(amount == "inf") + amount = "-1" + val item = tokens[0].toInt() + if(idsInStock[item] != null) { + log(this::class.java, Log.WARN, "[SHOPS] MALFORMED STOCK IN SHOP ID $id FOR ITEM $item") + items.forEach { if(it.itemId == item) { + it.amount += amount.toInt() + return@map + }} + } else { + items.add(ShopItem(item, amount.toInt(), tokens.getOrNull(2)?.toIntOrNull() ?: 100)) + idsInStock[item] = true + } + } catch (e: Exception) { + log(this::class.java, Log.WARN, "[SHOPS] MALFORMED STOCK IN SHOP ID $id FOR ITEM $it") + throw e + } + } + return items + } + } + + override fun startup() { + val path = ServerConstants.CONFIG_PATH + "shops.json" + var shopCount = 0 + logShop("Using JSON path: $path") + + val reader = FileReader(path) + val data = JSONParser().parse(reader) as JSONArray + + for(rawShop in data) + { + var shop: Shop? + val shopData = rawShop as JSONObject + val id = shopData["id"].toString().toInt() + val title = shopData["title"].toString() + val general = shopData["general_store"].toString().toBoolean() + val stock = parseStock(shopData["stock"].toString(), id).toTypedArray() + val npcs = if(shopData["npcs"].toString().isNotBlank()) shopData["npcs"].toString().split(",").map { it.toInt() }.toIntArray() else intArrayOf() + val currency = shopData["currency"].toString().toInt() + val highAlch = shopData["high_alch"].toString() == "1" + val forceShared = shopData.getOrDefault("force_shared", "false").toString().toBoolean() + shop = Shop(title, stock, general, currency, highAlch, forceShared) + + npcs.map { shopsByNpc[it] = shop } + shopsById[id] = shop + ++shopCount + } + + logShop("Parsed $shopCount shops.") + } + + override fun tick() { + shopsById.values.forEach(Shop::restock) + + val playerStockClearInterval = secondsToTicks(ServerConstants.PLAYER_STOCK_CLEAR_INTERVAL * 60) + if (getWorldTicks() % playerStockClearInterval == 0) { + val clearToGe = ServerConstants.PLAYER_STOCK_RECIRCULATE + if (clearToGe) { + for (item in Shop.generalPlayerStock.toArray().filter{it != null}) + GrandExchange.addBotOffer(item.id, item.amount) + } + Shop.generalPlayerStock.clear() + } + } + + override fun defineListeners() { + on(IntType.NPC, "trade", "shop"){ player, node -> + val npc = node as NPC + if (npc.id == 2824 || npc.id == 1041 || npc.id == 804) { + TanningProduct.open(player, npc.id) + return@on true + } + if (npc.id == 7601) { + openInterface(player, 732) + return@on true + } + shopsByNpc[npc.id]?.openFor(player) ?: return@on false + return@on true + } + + on(NPCs.SIEGFRIED_ERKLE_933, IntType.NPC, "trade"){ player, node -> + val points = getQuestPoints(player) + if(points < 40){ + sendNPCDialogue(player, NPCs.SIEGFRIED_ERKLE_933, "I'm sorry, adventurer, but you need 40 quest points to buy from me.") + return@on true + } + shopsByNpc[node.id]?.openFor(player) + return@on true + } + + on(NPCs.FUR_TRADER_1316, IntType.NPC, "trade") { player, node -> + if (!isQuestComplete(player, Quests.THE_FREMENNIK_TRIALS)) { + sendNPCDialogue(player, NPCs.FUR_TRADER_1316, "I don't sell to outerlanders.", core.game.dialogue.FacialExpression.ANNOYED).also { END_DIALOGUE } + } else { + shopsByNpc[node.id]?.openFor(player) + } + return@on true + } + + on(NPCs.CANDLE_MAKER_562, IntType.NPC, "trade") { player, node -> + if (getQuestStage(player, Quests.MERLINS_CRYSTAL) > 60) { + openId(player, 56) + } else { + shopsByNpc[node.id]?.openFor(player) + } + return@on true + } + } + + override fun defineInterfaceListeners() { + on(Components.SHOP_TEMPLATE_620){player, _, opcode, buttonID, slot, _ -> + val OP_VALUE = 155 + val OP_BUY_1 = 196 + val OP_BUY_5 = 124 + val OP_BUY_10 = 199 + val OP_BUY_X = 234 + val OP_EXAMINE = 9 + + val shop = getAttribute(player, "shop", null) ?: return@on false + val isMainStock = getAttribute(player, "shop-main", true) + + when(buttonID) + { + 26 -> shop.showTab(player, false).also { return@on true } + 25 -> shop.showTab(player, true).also { return@on true } + 27,29 -> return@on true + } + + val price = shop.getBuyPrice(player, slot) + + when(opcode) + { + OP_VALUE -> sendMessage(player, "${getItemName(if (isMainStock) shop.stock[slot].itemId else shop.playerStock[slot].id)}: This item currently costs ${price.amount} ${price.name.lowercase()}.") + OP_BUY_1 -> shop.buy(player, slot, 1) + OP_BUY_5 -> shop.buy(player, slot, 5) + OP_BUY_10 -> shop.buy(player, slot, 10) + OP_BUY_X -> sendInputDialogue(player, InputType.AMOUNT, "Enter the amount to buy:"){value -> + val amt = value as Int + shop.buy(player, slot, amt) + } + OP_EXAMINE -> sendMessage(player, itemDefinition(if (isMainStock) shop.stock[slot].itemId else shop.playerStock[slot].id).examine) + } + + return@on true + } + + onOpen(Components.SHOP_TEMPLATE_SIDE_621) {player, _ -> + val settings = IfaceSettingsBuilder() + .enableOptions(0 until 9) + .build() + player.packetDispatch.sendIfaceSettings(settings, 0, 621, 0, 28) + player.packetDispatch.sendRunScript(150, "IviiiIsssssssss", "", "", "", "", "Sell X", "Sell 10", "Sell 5", "Sell 1", "Value", -1, 0, 7, 4, 93, 621 shl 16) + return@onOpen true + } + + onClose(Components.SHOP_TEMPLATE_620) { player, _ -> + val shop = getAttribute(player, "shop", null) ?: return@onClose true + val listener = Shop.listenerInstances[player.details.uid] ?: return@onClose true + + if(getServerConfig().getBoolean(personalizedShops, false)) + shop.stockInstances[player.details.uid]?.listeners?.remove(listener) + else + shop.stockInstances[ServerConstants.SERVER_NAME.hashCode()]!!.listeners.remove(listener) + + shop.playerStock.listeners.remove(listener) + player.interfaceManager.closeSingleTab() + return@onClose true + } + + on(Components.SHOP_TEMPLATE_SIDE_621){player, component, opcode, buttonID, slot, itemID -> + val OP_VALUE = 155 + val OP_SELL_1 = 196 + val OP_SELL_5 = 124 + val OP_SELL_10 = 199 + val OP_SELL_X = 234 + + val shop = getAttribute(player, "shop", null) ?: return@on false + + val itemInSlot = player.inventory[slot] + if (itemInSlot == null) { + player.sendMessage("That item doesn't appear to be there anymore. Please try again.") + return@on true + } + + val (_,price) = shop.getSellPrice(player, slot) + val def = itemDefinition(player.inventory[slot].id) + + val valueMsg = when { + (price.amount == -1) + || !def.hasShopCurrencyValue(price.id) + || def.id in intArrayOf(Items.COINS_995, Items.TOKKUL_6529, Items.ARCHERY_TICKET_1464, Items.CASTLE_WARS_TICKET_4067) + -> "This shop will not buy that item." + else -> "${player.inventory[slot].name}: This shop will buy this item for ${price.amount} ${price.name.lowercase()}." + } + + when(opcode) + { + OP_VALUE -> sendMessage(player, valueMsg) + OP_SELL_1 -> shop.sell(player, slot, 1) + OP_SELL_5 -> shop.sell(player, slot, 5) + OP_SELL_10 -> shop.sell(player, slot, 10) + OP_SELL_X -> sendInputDialogue(player, InputType.AMOUNT, "Enter the amount to sell:"){value -> + val amt = value as Int + shop.sell(player, slot, amt) + } + } + + return@on true + } + } + + override fun defineDestinationOverrides() { + setDest(IntType.NPC,"trade","shop"){ _, node -> + val npc = node as NPC + if (npc.getAttribute("facing_booth", false)) { + val offsetX = npc.direction.stepX shl 1 + val offsetY = npc.direction.stepY shl 1 + return@setDest npc.location.transform(offsetX, offsetY, 0) + } + return@setDest node.location + } + } + + override fun defineCommands() { + define("openshop", Privilege.ADMIN) { player, args -> + if(args.size < 2) reject(player, "Usage: ::openshop shopId") + val shopId = args[1].toInt() + shopsById[shopId]?.openFor(player) + } + + define("shopscript") { player, args -> + val arg1 = args[1].toInt() + player.packetDispatch.sendRunScript(25, "vg", arg1, 92) //Run CS2 script 25, with args 868? and 92(our container id) + } + } +} diff --git a/Server/src/main/core/game/system/SystemConfig.java b/Server/src/main/core/game/system/SystemConfig.java new file mode 100644 index 0000000..da89540 --- /dev/null +++ b/Server/src/main/core/game/system/SystemConfig.java @@ -0,0 +1,170 @@ +package core.game.system; + +import core.game.node.entity.player.Player; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * Holds the system configurations from the database. + * @author Vexia + * + */ +public class SystemConfig { + + /** + * The system-object configurations. + */ + private final Map configs = new HashMap<>(); + + /** + * The list of beta user names. + */ + private final List betaUsers = new ArrayList<>(20); + + /** + * Constructs a new {@Code SystemConfig} {@Code Object} + */ + public SystemConfig() { + } + + /** + * Parses system configurations from the SQL database. + */ + public void parse() { + } + + /** + * Parses a config using the SQL info given. + * @param key The key identity. + * @param value The value. + * @param dataType The data type to parse. + */ + private void parseConfig(String key, String value, String dataType) { + if (dataType == null) { + configs.put(key, value); + return; + } + if (value == null || value == "") { + return; + } + switch (dataType) { + case "int": + configs.put(key, Integer.valueOf(value)); + break; + case "double": + break; + case "boolean": + break; + case "date": + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Date parsed = null; + try { + parsed = format.parse(value); + } catch (ParseException e) { + e.printStackTrace(); + } + configs.put(key, parsed); + break; + default: + configs.put(key, value); + break; + } + } + + /** + * Checks if the player passes the system configuration validation. + * @param player The player. + * @return {@code True} if successfull. + */ + public boolean validLogin(Player player) { + return true; + } + + /** + * Checks if double experience is active. + * @return {@code True} if active. + */ + public boolean isDoubleExp() { + Date date = getConfig("dxp", null); + if (date == null) { + return false; + } + return date.after(new Date()); + } + + /** + * Splits the data into an array list using a regex. + * @param data the data. + * @param regex the regex to split. + * @return the list of data. + */ + public List split(String data, String regex) { + if (!data.contains(regex)) { + List split = new ArrayList<>(20); + split.add(data); + return split; + } + List split = new ArrayList<>(20); + String[] tokens = data.trim().split(regex); + for (String s : tokens) { + split.add(s); + } + return split; + } + + /** + * Checks if a username is a beta user. + * @param name The name. + * @return {@code True} if so. + */ + public boolean isBetaUser(String name) { + return betaUsers.contains(name); + } + + /** + * Gets an attribute. + * @param key The attribute name. + * @return The attribute value. + */ + @SuppressWarnings("unchecked") + public T getConfig(String key) { + if (!configs.containsKey(key)) { + return null; + } + return (T) configs.get(key); + } + + /** + * Gets an attribute. + * @param string The attribute name. + * @param fail The value to return if the attribute is null. + * @return The attribute value, or the fail argument when null. + */ + @SuppressWarnings("unchecked") + public T getConfig(String string, T fail) { + Object object = configs.get(string); + if (object != null) { + return (T) object; + } + return fail; + } + + /** + * Gets the configs. + * @return the configs. + */ + public Map getConfigs() { + return configs; + } + + /** + * Gets the betaUsers. + * @return the betaUsers. + */ + public List getBetaUsers() { + return betaUsers; + } + +} diff --git a/Server/src/main/core/game/system/SystemManager.java b/Server/src/main/core/game/system/SystemManager.java new file mode 100644 index 0000000..5c1ba18 --- /dev/null +++ b/Server/src/main/core/game/system/SystemManager.java @@ -0,0 +1,143 @@ +package core.game.system; + +import core.game.system.security.EncryptionManager; +import core.game.world.GameWorld; + +/** + * Manages the "game system" states, such as updating or terminating. + * @author Emperor + */ +public final class SystemManager { + + /** + * The system state. + */ + private static SystemState state = SystemState.TERMINATED; + + /** + * The system update handler. + */ + private static final SystemUpdate UPDATER = new SystemUpdate(); + + /** + * The system termination handler. + */ + private static final SystemTermination TERMINATOR = new SystemTermination(); + + /** + * The system configurator. + */ + private static final SystemConfig SYSTEM_CONFIG = new SystemConfig(); + + /** + * The encryption the server uses. + */ + private static final EncryptionManager ENCRYPTION = new EncryptionManager(); + + /** + * Constructs a new {@code SystemManager} {@code Object}. + */ + private SystemManager() { + /* + * empty. + */ + } + + /** + * Sets the current state and handles it accordingly. + * @param state The system state. + */ + public static void flag(SystemState state) { + if (SystemManager.state == state) { + return; + } + SystemManager.state = state; + switch (state) { + case ACTIVE: + case PRIVATE: + GameWorld.getMajorUpdateWorker().setStarted(false); + GameWorld.getMajorUpdateWorker().start(); + break; + case UPDATING: + UPDATER.schedule(); + break; + case TERMINATED: + TERMINATOR.terminate(); + break; + } + } + + /** + * Checks if the system is still active (updating keeps the system active + * until termination). + * @return {@code True} if the state does not equal + * {@link SystemState#TERMINATED}. + */ + public static boolean isActive() { + return state != SystemState.TERMINATED; + } + + /** + * Checks if the system is being updated. + * @return {@code True} if so. + */ + public static boolean isUpdating() { + return state == SystemState.UPDATING; + } + + /** + * Checks if the system is private, so only developers can connect. + * @return {@code True} if so. + */ + public static boolean isPrivate() { + return state == SystemState.PRIVATE; + } + + /** + * Checks if the system has been terminated. + * @return {@code True} if so. + */ + public static boolean isTerminated() { + return state == SystemState.TERMINATED; + } + + /** + * Gets the current system state. + * @return The state. + */ + public static SystemState state() { + return state; + } + + /** + * Gets the updater. + * @return The updater. + */ + public static SystemUpdate getUpdater() { + return UPDATER; + } + + /** + * Gets the terminator. + * @return The terminator. + */ + public static SystemTermination getTerminator() { + return TERMINATOR; + } + + /** + * Gets the systemConfig. + * @return the systemConfig. + */ + public static SystemConfig getSystemConfig() { + return SYSTEM_CONFIG; + } + + /** + * Gets the encryption. + * @return the encryption. + */ + public static EncryptionManager getEncryption() { + return ENCRYPTION; + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/system/SystemShutdownHook.java b/Server/src/main/core/game/system/SystemShutdownHook.java new file mode 100644 index 0000000..850de35 --- /dev/null +++ b/Server/src/main/core/game/system/SystemShutdownHook.java @@ -0,0 +1,22 @@ +package core.game.system; + +import core.tools.Log; +import core.tools.SystemLogger; + +import static core.api.ContentAPIKt.log; + +/** + * Handles the shutdown hook. + * @author Emperor + */ +public final class SystemShutdownHook implements Runnable { + + @Override + public void run() { + if (SystemManager.isTerminated()) { + return; + } + log(this.getClass(), Log.INFO, "Terminating..."); + SystemManager.flag(SystemState.TERMINATED); + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/system/SystemState.java b/Server/src/main/core/game/system/SystemState.java new file mode 100644 index 0000000..b1ec727 --- /dev/null +++ b/Server/src/main/core/game/system/SystemState.java @@ -0,0 +1,29 @@ +package core.game.system; + +/** + * Represents the system states. + * @author Emperor + */ +public enum SystemState { + + /** + * The system is currently active. + */ + ACTIVE, + + /** + * The system is being updated. + */ + UPDATING, + + /** + * The system is in development, thus only developers can connect. + */ + PRIVATE, + + /** + * The system has been terminated. + */ + TERMINATED; + +} \ No newline at end of file diff --git a/Server/src/main/core/game/system/SystemTermination.java b/Server/src/main/core/game/system/SystemTermination.java new file mode 100644 index 0000000..a1557f3 --- /dev/null +++ b/Server/src/main/core/game/system/SystemTermination.java @@ -0,0 +1,102 @@ +package core.game.system; + +import core.api.PersistWorld; +import core.api.ShutdownListener; +import core.game.node.entity.player.Player; +import core.Server; +import core.ServerConstants; +import core.ServerStore; +import core.game.bots.AIRepository; +import core.game.node.entity.player.info.PlayerMonitor; +import core.tools.Log; +import core.tools.SystemLogger; +import core.game.world.GameWorld; +import core.game.world.repository.Repository; + +import java.io.File; +import java.util.Iterator; + +import static core.api.ContentAPIKt.log; + +/** + * Handles the terminating of the system. + * @author Emperor + * + */ +public final class SystemTermination { + + /** + * Constructs a new {@code SystemTermination} {@code Object}. + */ + protected SystemTermination() { + /* + * empty. + */ + } + + /** + * Terminates the system safely. + */ + public void terminate() { + log(this.getClass(), Log.INFO, "Initializing termination sequence - do not shutdown!"); + try { + log(this.getClass(), Log.INFO, "Shutting down networking..."); + Server.setRunning(false); + log(this.getClass(), Log.INFO, "Stopping all bots..."); + AIRepository.clearAllBots(); + Server.getReactor().terminate(); + log(this.getClass(), Log.INFO, "Stopping all pulses..."); + GameWorld.getMajorUpdateWorker().stop(); + for (Iterator it = Repository.getPlayers().iterator(); it.hasNext();) { + try { + Player p = it.next(); + if (p != null && !p.isArtificial()) { // Should never be null. + p.getDetails().save(); + p.clear(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + GameWorld.getShutdownListeners().forEach(ShutdownListener::shutdown); + PlayerMonitor.flushRemainingEventsImmediately(); + ServerStore s = null; + for (PersistWorld wld : GameWorld.getWorldPersists()) { + if (wld instanceof ServerStore) + s = (ServerStore) wld; + else + wld.save(); + } + //ServerStore should ***always*** save last. Fudging a race condition here :) + if (s != null) + s.save(); + if(ServerConstants.DATA_PATH != null) + save(ServerConstants.DATA_PATH); + } catch (Throwable e) { + e.printStackTrace(); + } + log(this.getClass(), Log.INFO, "Server successfully terminated!"); + } + + /** + * Saves all system data on the directory. + * @param directory The base directory. + */ + public void save(String directory) { + File file = new File(directory); + log(this.getClass(), Log.INFO, "Saving data [dir="+ file.getAbsolutePath() + "]..."); + if (!file.isDirectory()) { + file.mkdirs(); + } + Server.getReactor().terminate(); + long start = System.currentTimeMillis(); + while(!Repository.getDisconnectionQueue().isEmpty() && System.currentTimeMillis() - start < 5000L){ + Repository.getDisconnectionQueue().update(); + try { + Thread.sleep(100); + } catch (Exception ignored) {} + } + Repository.getDisconnectionQueue().update(); + Repository.getDisconnectionQueue().clear(); + } +} diff --git a/Server/src/main/core/game/system/SystemUpdate.java b/Server/src/main/core/game/system/SystemUpdate.java new file mode 100644 index 0000000..e28fe34 --- /dev/null +++ b/Server/src/main/core/game/system/SystemUpdate.java @@ -0,0 +1,138 @@ +package core.game.system; + +import core.ServerConstants; +import core.game.node.entity.player.Player; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.repository.Repository; + +import java.util.Iterator; +import java.util.concurrent.Executors; + +/** + * Handles a system update. + * @author Emperor + */ +public final class SystemUpdate extends Pulse { + + /** + * The default countdown for an update, in ticks. + */ + public static final int DEFAULT_COUNTDOWN = 100; + + /** + * The amount of ticks left of when to create a backup. + */ + public static final int BACKUP_TICK = 10; + + /** + * If a backup should be created. + */ + private boolean createBackup = false; + + /** + * Constructs a new {@code SystemUpdate} {@code Object}. + */ + protected SystemUpdate() { + super(DEFAULT_COUNTDOWN); + } + + @Override + public boolean pulse() { + if (getDelay() >= BACKUP_TICK && createBackup) { + try { + SystemManager.getTerminator().save(ServerConstants.DATA_PATH); + } catch (Throwable e) { + e.printStackTrace(); + } + setDelay(BACKUP_TICK - 1); + return false; + } + SystemManager.flag(SystemState.TERMINATED); + return true; + } + + /** + * Notifies the players. + */ + public void notifyPlayers() { + try { + + int time = getDelay() + (createBackup ? BACKUP_TICK : 0); + for (Iterator it = Repository.getPlayers().iterator(); it.hasNext();) { + Player p = it.next(); + if (p != null) { // Should never be null. + p.getPacketDispatch().sendSystemUpdate(time); + } + } + } catch (Throwable t) { + t.printStackTrace(); + } + } + + /** + * Schedules an update. + */ + public void schedule() { + super.setTicksPassed(0); + super.start(); + if (GameWorld.getMajorUpdateWorker().getStarted()) { + notifyPlayers(); + GameWorld.getPulser().submit(this); + return; + } + Executors.newSingleThreadExecutor().submit(new Runnable() { + @Override + public void run() { + while (isRunning()) { + try { + Thread.sleep(600); + } catch (InterruptedException e) { + e.printStackTrace(); + } + if (update()) { + break; + } + } + } + }); + } + + /** + * Sets the system update countdown. + * @param ticks The amount of ticks. + */ + public void setCountdown(int ticks) { + if (createBackup) { + if (ticks < BACKUP_TICK) { + ticks = BACKUP_TICK; + } + ticks -= BACKUP_TICK; + } + super.setDelay(ticks); + } + + /** + * Cancels the system update task. + */ + public void cancel() { + super.stop(); + SystemManager.flag(SystemState.ACTIVE); + } + + /** + * Gets the createBackup. + * @return The createBackup. + */ + public boolean isCreateBackup() { + return createBackup; + } + + /** + * Sets the createBackup. + * @param createBackup The createBackup to set. + */ + public void setCreateBackup(boolean createBackup) { + this.createBackup = createBackup; + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/system/command/Command.kt b/Server/src/main/core/game/system/command/Command.kt new file mode 100644 index 0000000..fdbc56d --- /dev/null +++ b/Server/src/main/core/game/system/command/Command.kt @@ -0,0 +1,59 @@ +package core.game.system.command + +import core.game.node.entity.player.Player +import core.ServerConstants +import core.game.world.GameWorld +import kotlin.collections.ArrayList + +/** + * Base class for Commands in the new system. Can pass a lambda as part of the constructor or after the constructor. + * @author Ceikry + */ +class Command(val name: String, val privilege: Privilege, val usage: String = "UNDOCUMENTED", val description: String = "UNDOCUMENTED", val handle: (Player, Array) -> Unit) { + fun attemptHandling(player: Player, args: Array?){ + args ?: return + if(player.rights.ordinal >= privilege.ordinal || GameWorld.settings?.isDevMode == true || ServerConstants.I_AM_A_CHEATER){ + handle(player,args) + } + } +} + +object CommandMapping { + private val mapping = hashMapOf() + + fun get(name: String): Command?{ + return mapping[name] + } + + fun register(command: Command){ + mapping[command.name] = command + } + + fun getCommands(): Array { + return mapping.values.toTypedArray() + } + + fun getNames(): Array { + return mapping.keys.toTypedArray() + } + + fun getPageIndices(rights: Int): IntArray { + val list = ArrayList() + list.add(0) + + var lineCounter = 0 + for ((index, command) in getCommands().filter { it.privilege.ordinal <= rights }.withIndex()) { + + lineCounter += 2 + if (command.usage.isNotEmpty()) lineCounter++ + if (command.description.isNotEmpty()) lineCounter++ + + if (lineCounter > 306) { + list.add(index) + lineCounter = 0 + } + } + + return list.toIntArray() + } +} diff --git a/Server/src/main/core/game/system/command/CommandPlugin.kt b/Server/src/main/core/game/system/command/CommandPlugin.kt new file mode 100644 index 0000000..45cd441 --- /dev/null +++ b/Server/src/main/core/game/system/command/CommandPlugin.kt @@ -0,0 +1,107 @@ +package core.game.system.command + +import core.game.node.entity.player.Player +import core.plugin.Plugin +import core.game.world.repository.Repository + +/** + * Represents a command plugin that can be linked to a command set. + * @author Vexia + */ +abstract class CommandPlugin : Plugin { + /** + * Method used to wrap around a command sets pase method. + * @param player the player. + * @param name the name. + * @param args the arguments. + * @return `True` if so. + */ + abstract fun parse(player: Player?, name: String?, args: Array?): Boolean + + /** + * Used to override for specific plugins. + * @param player the player. + * @return `True` if so. + */ + fun validate(player: Player?): Boolean { + return true + } + + override fun fireEvent(identifier: String, vararg args: Any): Any { + return Unit + } + + /** + * Method used to link this command plugin to a command set. + * @param sets the sets to link to. + */ + fun link(vararg sets: CommandSet) { + for (set in sets) { + set.plugins.add(this) + } + } + + companion object { + /** + * Method used to parse the string as an integer. + * @param string the string. + * @return the integer. + */ + @JvmStatic + fun toInteger(string: String): Int { + return try { + string.toInt() + } catch (exception: NumberFormatException) { + 1 + } + } + + /** + * Gets the argument line (starting at index 1). + * @param args The arguments. + * @return The argument line. + */ + fun getArgumentLine(args: Array): String { + return getArgumentLine(args, 1, args.size) + } + + /** + * Gets the argument line from the given arguments. + * @param args The arguments. + * @param offset The start index. + * @param length The end index. + * @return the line. + */ + fun getArgumentLine(args: Array, offset: Int, length: Int): String { + val sb = StringBuilder() + for (i in offset until length) { + if (i != offset) { + sb.append(" ") + } + sb.append(args[i]) + } + return sb.toString() + } + + /** + * Gets the target player. + * @param name The name. + * @param load If we load the file. + * @return The player. + */ + @JvmStatic + fun getTarget(name: String?, load: Boolean): Player? { + return Repository.getPlayerByName(name) + } + + /** + * Gets the target player. + * @param name The name. + * @return The player. + */ + @JvmStatic + fun getTarget(name: String?): Player? { + return Repository.getPlayerByName(name) + } + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/system/command/CommandSet.java b/Server/src/main/core/game/system/command/CommandSet.java new file mode 100644 index 0000000..56daa23 --- /dev/null +++ b/Server/src/main/core/game/system/command/CommandSet.java @@ -0,0 +1,100 @@ +package core.game.system.command; + +import core.game.node.entity.player.Player; +import core.game.node.entity.player.info.Rights; +import core.game.system.command.CommandPlugin; +import core.game.world.GameWorld; + +import java.util.ArrayList; +import java.util.List; + +/** + * Represents a command set. + * @author Vexia + */ +public enum CommandSet { + PLAYER(), + MODERATOR() { + @Override + public boolean validate(Player player) { + return player.getDetails().getRights().ordinal() > 0; + } + }, + ADMINISTRATOR() { + @Override + public boolean validate(Player player) { + return player.getDetails().getRights().equals(Rights.ADMINISTRATOR); + } + }, + DEVELOPER() { + @Override + public boolean validate(Player player) { + return player.getDetails().getRights().equals(Rights.ADMINISTRATOR); + } + }, + BETA() { + @Override + public boolean validate(Player player) { + return GameWorld.getSettings().isBeta() || ADMINISTRATOR.validate(player) || GameWorld.getSettings().isDevMode(); + } + }; + + /** + * Represents the list of linked plugins with this command set. + */ + private final List plugins = new ArrayList<>(20); + + /** + * Constructs a new {@code CommandSet} {@code Object}. + */ + private CommandSet() { + /* + * empty. + */ + } + + /** + * Checks if the player can use this set. + * @param player the player. + */ + public boolean validate(final Player player) { + return true; + } + + /** + * Interprets and incoming command by dispatching it to it's plugins. + * @param player the player. + * @param name the name. + * @param arguments the arguments. + * @return True if the command was interpreted. + */ + public boolean interpret(final Player player, final String name, final String... arguments) { + if (player == null) { + return false; + } + if (!validate(player)) { + return false; + } + if (player.getZoneMonitor().parseCommand(player, name, arguments)) { + return true; + } + for (int i = 0; i < plugins.size(); i++) { + CommandPlugin plugin = plugins.get(i); + if (!plugin.validate(player)) { + continue; + } + if (plugin.parse(player, name, arguments)) { + return true; + } + } + return false; + } + + /** + * Gets the list of plugins of this command set. + * @return the plugins of this set. + */ + public List getPlugins() { + return plugins; + } +} diff --git a/Server/src/main/core/game/system/command/CommandSystem.kt b/Server/src/main/core/game/system/command/CommandSystem.kt new file mode 100644 index 0000000..3601182 --- /dev/null +++ b/Server/src/main/core/game/system/command/CommandSystem.kt @@ -0,0 +1,48 @@ +package core.game.system.command + +import core.game.node.entity.player.Player +import core.tools.colorize + +/** + * Represents a managing system used to dispatch incoming commands. + * @author Vexia + */ +class CommandSystem { + /** + * Method used to parse an incomming command packet. + * @param player the player. + * @param message the command message. + */ + fun parse(player: Player?, message: String): Boolean { + player ?: return false + val arguments = message.split(" ").toTypedArray() + val command = CommandMapping.get(arguments[0]) + + if(command == null) { + for (set in CommandSet.values()) { + if (set.interpret(player, arguments[0], *arguments)) { + player.sendMessage(colorize("-->%Y${arguments[0]}: Deprecated command")) + return true + } + } + player.sendMessage(colorize("-->%R${arguments[0]}: command not found")) + } else { + try { + command.attemptHandling(player, arguments) + } catch (e: IllegalStateException){return true} + } + return false + } + + companion object { + /** + * Gets the command system instance. + * @return the instance. + */ + /** + * Represents the singleton instance of this class. + */ + val commandSystem = CommandSystem() + + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/system/command/MapDumpCommand.kt b/Server/src/main/core/game/system/command/MapDumpCommand.kt new file mode 100644 index 0000000..2743af8 --- /dev/null +++ b/Server/src/main/core/game/system/command/MapDumpCommand.kt @@ -0,0 +1,82 @@ +package core.game.system.command + +import core.game.node.entity.player.Player +import core.game.system.command.CommandSet +import core.game.world.map.Location +import core.game.world.map.RegionManager +import core.plugin.Initializable +import core.plugin.Plugin +import java.util.* + +@Initializable +class MapDumpCommand : CommandPlugin() { + + @Throws(Throwable::class) + override fun newInstance(arg: Any?): Plugin? { + link(CommandSet.ADMINISTRATOR) + return this + } + + override fun parse(player: Player?, name: String?, args: Array?): Boolean { + when (name) { + "mapredo" -> redoMap(3000, 3000, 1).also { return true } + "findobj" -> findObj(player, args?.toList() as List?).also { return true } + } + return false + } + + companion object { + private val GameObjectMap = HashMap() + private val LocationObjectMap = HashMap?>() + private fun redoMap(xmax: Int, ymax: Int, zmax: Int) { + GameObjectMap.clear() + LocationObjectMap.clear() + for (x in 0 until xmax - 1) { + for (y in 0 until ymax - 1) { + for (z in 0 until zmax - 1) { + val temp = RegionManager.getObject(z, x, y) + if (temp != null) { + GameObjectMap[Location(x, y, z)] = temp.id + } + } + } + } + for ((key, value) in GameObjectMap) { + if (LocationObjectMap.containsKey(value)) { + LocationObjectMap[value]!!.add(key) + } else { + val locations: MutableList = ArrayList() + locations.add(key) + LocationObjectMap[value] = locations + } + } + return + } + + private fun findObj(player: Player?, args: List?) { + val objId = Integer.parseInt(args?.getOrNull(1)) + val xmin = 50 + val ymin = 50 + val zmin = 0 + val xmax = 55 + val ymax = 55 + val zmax = 1 + + player!!.packetDispatch.sendMessage("Searching...") + + for (x in xmin until xmax - 1) { + for (y in ymin until ymax - 1) { + for (z in zmin until zmax - 1) { + player.packetDispatch.sendMessage(Location(x,y,z).toString()) + val temp = RegionManager.getObject(Location(x,y,z)) + if (temp != null && temp.id == objId) { + player.packetDispatch.sendMessage("Absolute: [$x,$y,$z]") + } + } + } + } + + return + } + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/system/command/Privilege.kt b/Server/src/main/core/game/system/command/Privilege.kt new file mode 100644 index 0000000..7c4fc93 --- /dev/null +++ b/Server/src/main/core/game/system/command/Privilege.kt @@ -0,0 +1,7 @@ +package core.game.system.command + +enum class Privilege{ + STANDARD, + MODERATOR, + ADMIN +} \ No newline at end of file diff --git a/Server/src/main/core/game/system/command/oldsys/SimpleDumpingCommands.kt b/Server/src/main/core/game/system/command/oldsys/SimpleDumpingCommands.kt new file mode 100644 index 0000000..c4cee6e --- /dev/null +++ b/Server/src/main/core/game/system/command/oldsys/SimpleDumpingCommands.kt @@ -0,0 +1,102 @@ +package core.game.system.command.oldsys + +import core.cache.def.impl.ItemDefinition +import core.cache.def.impl.NPCDefinition +import core.cache.def.impl.SceneryDefinition +import core.game.node.entity.player.Player +import core.game.system.command.CommandSet +import core.plugin.Initializable +import core.plugin.Plugin +import core.game.system.command.CommandPlugin +import java.io.BufferedWriter +import java.io.File + +@Initializable +class SimpleDumpingCommands : CommandPlugin() { + override fun parse(player: Player?, name: String?, args: Array?): Boolean { + when(name) { + "make" -> handleMake(player, args?.toList() as List?).also { return true } + } + return false + } + + private fun handleMake(player: Player?,args: List?){ + val dataType = args?.getOrNull(1) + val outputType = args?.getOrNull(2) + + if(dataType == null || outputType == null) player?.sendMessage("Usage: ::make item|object|npc list|doc") + + when(outputType){ + "list" -> makeDumpList(dataType!!).also { player?.sendMessage("Creating $dataType dump list...") } + "doc" -> makeDumpDoc(dataType!!).also { player?.sendMessage("Creating $dataType dump doc...") } + } + } + + private fun makeDumpList(type: String){ + val f = File(System.getProperty("user.dir") + File.separator + "${type}list.txt") + val writer = f.bufferedWriter() + when(type){ + "item" -> for (i in ItemDefinition.getDefinitions().values){ + writer.writeLn("${i.name}(${i.id}) - ${i.examine}") + } + "object" -> for(i in SceneryDefinition.getDefinitions().values){ + writer.writeLn("${i.name}(${i.id}) - ${i.examine}") + } + "npc" -> for(i in NPCDefinition.getDefinitions().values){ + writer.writeLn("${i.name}(${i.id}) - ${i.examine}") + } + } + writer.close() + } + + private fun makeDumpDoc(type: String){ + val f = File(System.getProperty("user.dir") + File.separator + "${type}list.html") + println(f.absolutePath) + val writer = f.bufferedWriter() + writer.writeLn("") + writer.writeLn("") + writer.writeLn("") + writer.writeLn("") + writer.writeLn("") + writer.writeLn("") + writer.writeLn("") + writer.writeLn("") + writer.writeLn("") + when(type){ + "item" -> for (i in ItemDefinition.getDefinitions().values){ + writer.writeLn("") + writer.writeLn("") + writer.writeLn("") + writer.writeLn("") + writer.writeLn("") + } + "object" -> for(i in SceneryDefinition.getDefinitions().values){ + writer.writeLn("") + writer.writeLn("") + writer.writeLn("") + writer.writeLn("") + writer.writeLn("") + } + "npc" -> for(i in NPCDefinition.getDefinitions().values){ + writer.writeLn("") + writer.writeLn("") + writer.writeLn("") + writer.writeLn("") + writer.writeLn("") + } + } + writer.writeLn("
$type name$type IDExamine Text
${i.name}${i.id}${i.examine}
${i.name}${i.id}${i.examine}
${i.name}${i.id}${i.examine}
") + writer.close() + } + + override fun newInstance(arg: Any?): Plugin? { + link(CommandSet.ADMINISTRATOR) + return this + } + + private fun BufferedWriter.writeLn(line: String){ + this.write(line) + this.newLine() + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/system/command/oldsys/VisualCommand.kt b/Server/src/main/core/game/system/command/oldsys/VisualCommand.kt new file mode 100644 index 0000000..fc2a08c --- /dev/null +++ b/Server/src/main/core/game/system/command/oldsys/VisualCommand.kt @@ -0,0 +1,511 @@ +package core.game.system.command.oldsys + +import core.api.* +import core.cache.Cache +import core.game.container.access.InterfaceContainer +import content.region.misc.tutisland.handlers.iface.CharacterDesign +import core.game.node.scenery.Scenery +import core.game.node.scenery.SceneryBuilder +import core.game.node.entity.combat.ImpactHandler.HitsplatType +import core.game.node.entity.impl.Projectile +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.audio.Audio +import core.game.node.item.Item +import core.game.system.command.CommandSet +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.map.RegionManager +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import core.net.packet.PacketRepository +import core.net.packet.context.VarbitContext +import core.net.packet.out.Varbit +import core.plugin.Initializable +import core.plugin.Plugin +import core.game.system.command.CommandPlugin +import core.game.world.GameWorld +import java.awt.Toolkit +import java.awt.datatransfer.StringSelection + +/** + * Represents the the command plugin used for visual commands. + * @author Vexia + * @author Emperor + */ +@Initializable +class VisualCommand : CommandPlugin() { + override fun newInstance(arg: Any?): Plugin? { + link(CommandSet.ADMINISTRATOR) + return this + } + + override fun parse(player: Player?, name: String?, args: Array?): Boolean { + var location: Location? = null + var `object`: Scenery? = null + var o: Player? = null + when (name) { + "invisible", "invis", "seti" -> { + player!!.isInvisible = !player.isInvisible + player.sendMessage("You are now " + (if (player.isInvisible) "invisible" else "rendering") + " for other players.") + return true + } + "maxkc" -> { + var i = 0 + while (i < 6) { + player!!.savedData.activityData.barrowBrothers[i] = true + i++ + } + val names = arrayOf("Ahrim", "Dharok", "Guthan", "Karil", "Torag", "Verac") + player!!.savedData.activityData.barrowKills = 50 + player.packetDispatch.sendMessage("Flagged all barrow brothers killed and 50 catacomb kills, current entrance: " + names[player.savedData.activityData.barrowTunnelIndex] + ".") + return true + } + "1hko" -> { + player!!.setAttribute("1hko", !player.getAttribute("1hko", false)) + player.packetDispatch.sendMessage("1-hit KO mode " + if (player.getAttribute("1hko", false)) "on." else "off.") + return true + } + "anim", "emote" -> { + if (args!!.size < 2) { + player!!.debug("syntax error: id (optional) delay") + return true + } + val animation = Animation(args[1]!!.toInt(), if (args.size > 2) args[2]!!.toInt() else 0) + player!!.animate(animation) + return true + } + "render", "remote" -> { + if (args!!.size < 2) { + player!!.debug("syntax error: ::render id") + return true + } + try { + player!!.appearance.setAnimations(Animation.create(args[1]!!.toInt())) + player.appearance.sync() + } catch (e: NumberFormatException) { + player!!.packetDispatch.sendMessage("Use: ::remote id") + } + return true + } + "normalwalk" -> { + player!!.appearance.prepareBodyData(player) + player.appearance.setDefaultAnimations() + player.appearance.setAnimations() + player.appearance.sync() + return true + } + "gfx", "graphic", "graphics" -> { + if (args!!.size < 2) { + player!!.debug("syntax error: id (optional) height delay") + return true + } + player!!.graphics(Graphics(args[1]!!.toInt(), if (args.size > 2) args[2]!!.toInt() else 0, if (args.size > 3) args[3]!!.toInt() else 0)) + return true + } + "sync", "visual" -> { + if (args!!.size < 3) { + player!!.debug("syntax error: anim_id gfx_id (optional) height") + return true + } + val animId = toInteger(args[1]!!) + val gfxId = toInteger(args[2]!!) + val height = if (args.size > 3) toInteger(args[3]!!) else 0 + player!!.visualize(Animation.create(animId), Graphics(gfxId, height)) + return true + } + "pos_graphic", "position_gfx", "pos_gfx", "lgfx" -> { + if (args!!.size < 2) { + player!!.debug("syntax error: id x y (optional) z height delay") + return true + } + location = Location.create(args[2]!!.toInt(), args[3]!!.toInt(), if (args.size > 4) args[4]!!.toInt() else 0) + player!!.packetDispatch.sendPositionedGraphic(args[1]!!.toInt(), if (args.size > 5) args[5]!!.toInt() else 0, if (args.size > 6) args[6]!!.toInt() else 0, location) + return true + } + "npc" -> { + if (args!!.size < 2) { + player!!.debug("syntax error: id (optional) direction") + return true + } + val npc = NPC.create(toInteger(args[1]!!), player!!.location) + npc.setAttribute("spawned:npc", true) + npc.isRespawn = false + npc.direction = player.direction + npc.init() + npc.isWalks = if (args.size > 2) true else false + val npcString = "{" + npc.location.x + "," + npc.location.y + "," + npc.location.z + "," + (if (npc.isWalks) "1" else "0") + "," + npc.direction.ordinal + "}" + val clpbrd = Toolkit.getDefaultToolkit().systemClipboard + clpbrd.setContents(StringSelection(npcString), null) + println(npcString) + return true + } + "npcsquad" -> { + if (args!!.size < 2) { + player!!.debug("syntax error: id (optional) sizeX sizeY") + return true + } + var sizeX = 3 + var sizeY = 3 + if (args.size > 2) { + sizeX = toInteger(args[2]!!) + sizeY = if (args.size > 3) { + toInteger(args[3]!!) + } else { + sizeX + } + } + val aggressive = args.size > 4 + var x = 0 + while (x < sizeX) { + var y = 0 + while (y < sizeY) { + val npc = NPC.create(toInteger(args[1]!!), player!!.location.transform(1 + x, 1 + y, 0)) + npc.setAttribute("spawned:npc", true) + npc.setAggressive(aggressive) + npc.init() + npc.setRespawn(false) + npc.setWalks(aggressive) + y++ + } + x++ + } + return true + } + "teleallowed" -> { + player!!.debug("Is tele allowed here? " + RegionManager.isTeleportPermitted(player!!.location)) + return true + } + "oib" -> { + player!!.interfaceManager.openInfoBars() + return true + } + "char" -> { + CharacterDesign.open(player) + return true + } + "savenpc" -> return true + "objwithanim" -> { + val go = Scenery(toInteger(args!![1]!!), player!!.location, 0) + SceneryBuilder.add(go) + player.packetDispatch.sendSceneryAnimation(go, Animation.create(toInteger(args[2]!!))) + return true + } + "oa", "object_anim", "obj_anim", "objectanim", "objanim" -> { + if (args!!.size < 2) { + player!!.debug("syntax error: x y id") + return true + } + location = if (args.size > 2) Location.create(args[1]!!.toInt(), args[2]!!.toInt(), player!!.location.z) else player!!.location + `object` = RegionManager.getObject(location) + if (`object` == null) { + player!!.debug("error: object not found in region cache.") + return true + } + player!!.packetDispatch.sendSceneryAnimation(`object`, Animation(toInteger(args[args.size - 1]!!))) + //sendMessage(player, `object`.definition.modelIds.map { it.toString() }.toString()) + sendMessage(player, `object`.definition.animationId.toString()) + return true + } + "inter", "component", "interface" -> { + if (args!!.size < 2) { + player!!.debug("syntax error: interface-id") + return true + } + val componentId = toInteger(args[1]!!) + if (componentId < 0 || componentId > Cache.getInterfaceDefinitionsSize()) { + player!!.debug("Invalid component id [id=" + componentId + ", max=" + Cache.getInterfaceDefinitionsSize() + "].") + return true + } + player!!.interfaceManager.openComponent(componentId) + return true + } + "ti" -> { + player!!.packetDispatch.sendInterfaceConfig(90, 87, false) + return true + } + "iconfig", "inter_config" -> { + if (args!!.size < 2) { + player!!.debug("syntax error: interface-id child hidden") + return true + } + val hidden = if (args.size > 3) java.lang.Boolean.parseBoolean(args[3]) else true + player!!.packetDispatch.sendInterfaceConfig(toInteger(args[1]!!), toInteger(args[2]!!), hidden) + player.packetDispatch.sendMessage("Interface child (id=" + args[1] + ", child=" + args[2] + ") is " + if (hidden) "hidden." else "visible.") + return true + } + "loop_varposition" -> { + val value = (args!![1]!!.toString().toInt()) ?: 0 + val cfg_index = (args.getOrNull(2)?.toString()?.toInt() ?: -1) + if(cfg_index == -1){ + submitWorldPulse(object : Pulse(3, player){ + var pos = 32 + var shift = 0 + override fun pulse(): Boolean { + for(i in 0..1999){ + setVarp(player!!, i, pos shl shift) + } + player?.sendMessage("$pos shl $shift") + if(pos++ >= 63){ + shift += 4 + pos = 0 + } + return shift >= 32 + } + }) + } else { + submitWorldPulse(object : Pulse(3, player) { + var pos = 0 + override fun pulse(): Boolean { + setVarp(player!!, cfg_index, value shl pos) + player?.sendMessage("$pos") + return pos++ >= 32 + } + }) + } + return true + } + "loop_anim_on_i" -> { + var anim = toInteger(args!![1]!!) + submitWorldPulse(object : Pulse(3){ + override fun pulse(): Boolean { + player!!.packetDispatch.sendAnimationInterface(anim++, 224, 7) + sendMessage(player, "${anim - 1}") + return false + } + }) + return true + } + "send_i_anim" -> { + val iface = args?.getOrNull(0) ?: return true + val anim = args.getOrNull(1) ?: return true + + player?.packetDispatch?.sendAnimationInterface(toInteger(anim), toInteger(iface),7) + return true + } + "loop_inter" -> { + val st = toInteger(args!![1]!!) + val en = if (args.size > 2) toInteger(args[2]!!) else 740 + GameWorld.Pulser.submit(object : Pulse(3, player) { + var id = st + override fun pulse(): Boolean { +// PacketRepository.send(Interface.class, new InterfaceContext(player, 548, 77, id, false)); + player!!.interfaceManager.openComponent(id) + player.debug("Interface id: $id") + return ++id >= en + } + }) + return true + } + "loop_iconfig" -> { + val st = toInteger(args!![1]!!) + val en = if (args.size > 2) toInteger(args[2]!!) else 740 + GameWorld.Pulser.submit(object : Pulse(3, player) { + var id = 0 + override fun pulse(): Boolean { +// PacketRepository.send(Interface.class, new InterfaceContext(player, 548, 77, id, false)); + player!!.packetDispatch.sendInterfaceConfig(st,id,true) + player.debug("child id: $id") + return ++id >= en + } + }) + return true + } + "loop_itemoni" -> { + val st = toInteger(args!![1]!!) + val en = if (args.size > 2) toInteger(args[2]!!) else 740 + GameWorld.Pulser.submit(object : Pulse(1, player) { + var id = 0 + override fun pulse(): Boolean { +// PacketRepository.send(Interface.class, new InterfaceContext(player, 548, 77, id, false)); + InterfaceContainer.generateItems(player, arrayOf(Item(4151),Item(410)), arrayOf("E"),367,id,5,4) + player?.packetDispatch?.sendInterfaceConfig(st,id,true) + //player?.packetDispatch?.sendString("ASDASDASD",st,id) + player?.debug("child id: $id") + return ++id >= en + } + }) + return true + } + "loop_config", "config_loop" -> { + if (args!!.size < 4) { + player!!.debug("syntax error: config-id start end value") + return true + } + val value = toInteger(args[3]!!) + var i = toInteger(args[1]!!) + while (i < toInteger(args[2]!!)) { + setVarp(player!!, i, value) + i++ + } + return true + } + "string" -> { + if (args!!.size < 3) { + player!!.debug("syntax error: interface child text") + return true + } + player!!.packetDispatch.sendString(args[3], toInteger(args[1]!!), toInteger(args[2]!!)) + return true + } + "loop_string", "string_loop" -> { + if (args!!.size < 3) { + player!!.debug("syntax error: interface min max") + return true + } + val interfaceId = toInteger(args[1]!!) + var i = toInteger(args[2]!!) + while (i < toInteger(args[3]!!)) { + player!!.packetDispatch.sendString("child=$i", interfaceId, i) + i++ + } + return true + } + "loop_oa" -> { + val startId = toInteger(args!![1]!!) + val endId = if (args.size > 2) toInteger(args[2]!!) else 11000 + GameWorld.Pulser.submit(object : Pulse(3, player) { + var id = startId + override fun pulse(): Boolean { + val `object` = RegionManager.getObject(player!!.location) + if (`object` == null) { + player.debug("error: object not found in region cache.") + return true + } + player.packetDispatch.sendSceneryAnimation(`object`, Animation(id)) + player.debug("Animation id: $id") + return ++id >= endId + } + }) + return true + } + "loop_anim" -> { + val start = toInteger(args!![1]!!) + val end = if (args.size > 2) toInteger(args[2]!!) else 11000 + GameWorld.Pulser.submit(object : Pulse(3, player) { + var id = start + override fun pulse(): Boolean { + player!!.animate(Animation.create(id)) + player.debug("Animation id: $id") + return ++id >= end + } + }) + return true + } + "loop_gfx" -> { + val s = toInteger(args!![1]!!) + val e = if (args.size > 2) toInteger(args[2]!!) else 11000 + GameWorld.Pulser.submit(object : Pulse(3, player) { + var id = s + override fun pulse(): Boolean { + Projectile.create(player!!.location, player.location.transform(0, 3, 0), id, 42, 36, 46, 75, 5, 11).send() + player.graphics(Graphics(id, 96)) + player.debug("Graphic id: $id") + return ++id >= e + } + }) + return true + } + "removenpc" -> { + player!!.setAttribute("removenpc", !player.getAttribute("removenpc", false)) + player.debug("You have set remove npc value to " + player.getAttribute("removenpc", false) + ".") + return true + } + "pnpc" -> { + if (args!!.size < 2) { + player!!.debug("syntax error: id") + return true + } + player!!.appearance.transformNPC(toInteger(args[1]!!)) + return true + } + "itemoni" -> { + val inter = toInteger(args!![1]!!) + val child = toInteger(args[2]!!) + val item = if (args.size > 3) toInteger(args[3]!!) else 1038 + player!!.packetDispatch.sendItemZoomOnInterface(item, 270, inter, child) + return true + } + "hit" -> { + player!!.impactHandler.manualHit(player, toInteger(args!![1]!!), HitsplatType.NORMAL) + return true + } + "noclip" -> { + player!!.setAttribute("no_clip", !player.getAttribute("no_clip", false)) + return true + } + /*"grow" -> { + for (wrapper in player!!.farmingManager.patches) { + if (wrapper == null || wrapper.patch == null || wrapper.cycle == null || wrapper.cycle.growthHandler == null) { + continue + } + wrapper.cycle.growthHandler.handle() + } + return true + }*/ + "disabledisease" -> { + player!!.setAttribute("stop-disease", !player.getAttribute("stop-disease", false)) + player.sendMessage("Disable disease=" + player.getAttribute("stop-disease", false)) + return true + } + /* + "rake" -> { + for (wrapper in player!!.farmingManager.patches) { + wrapper.cycle.clear(player) + } + return true + } + "full" -> { + for (wrapper in player!!.farmingManager.patches) { + var i = 0 + while (i < 20) { + if (wrapper == null || wrapper.patch == null || wrapper.cycle == null || wrapper.cycle.growthHandler == null) { + i++ + continue + } + wrapper.cycle.growthHandler.handle() + i++ + } + } + return true + } + "toreg" -> { + o = Repository.getPlayerByName(args!![1]) + o?.ironmanManager?.mode = IronmanMode.NONE + player!!.sendMessage("done...") + o?.sendMessage("You are no longer an ironman. Log out to see the ironman icon disappear.") + } + "testcut" -> { + ActivityManager.start(player,"Lost Tribe Cutscene",true) + } + "tryinfinity" -> { + GameWorld.Pulser.submit(object : Pulse(1, player) { + var id = 0 + override fun pulse(): Boolean { + player?.configManager?.set(532,id) + player?.debug("Child: $id") + return ++id == 999 + } + }) + } + "clearpatches" -> { + if (args!!.size > 1) { + o = Repository.getPlayerByName(args[1]) + } + if (o != null) { + for (wrapper in o.farmingManager.patches) { + wrapper.cycle.clear(o) + } + o.sendMessage("Your patches have been cleared.") + player!!.sendMessage("You cleared " + o.username + "'s patches.") + return true + } + for (wrapper in player!!.farmingManager.patches) { + wrapper.cycle.clear(player) + } + return true + }*/ + } + return false + } +} diff --git a/Server/src/main/core/game/system/command/rottenpotato/RPUseWithNPCDialogue.kt b/Server/src/main/core/game/system/command/rottenpotato/RPUseWithNPCDialogue.kt new file mode 100644 index 0000000..fa68936 --- /dev/null +++ b/Server/src/main/core/game/system/command/rottenpotato/RPUseWithNPCDialogue.kt @@ -0,0 +1,68 @@ +package core.game.system.command.rottenpotato + +import core.game.node.entity.combat.ImpactHandler +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.plugin.Initializable +import core.tools.colorize + +/** + * Rotten potato -> npc interaction menu + * @author Ceikry + */ +@Initializable +class RPUseWithNPCDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin(player) { + var npc: NPC? = null + val ID = 38575795 + override fun newInstance(player: Player?): core.game.dialogue.DialoguePlugin { + return RPUseWithNPCDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = args[0] as NPC + options("Remove NPC","Enable Respawning","Disable Respawning","Kill","Copy Appearance") + stage = 0 + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + npc ?: return false + when(buttonId){ + //remove NPC + 1 -> { + end() + npc.isRespawn = false + npc.clear() + player.sendMessage(colorize("%RNPC Cleared.")) + } + //Enable Respawn + 2 -> { + end() + npc.isRespawn = true + player.sendMessage(colorize("%RNPC Respawn Enabled")) + } + //Disable Respawn + 3 -> { + end() + npc.isRespawn = false + player.sendMessage(colorize("%RNPC Respawn Disabled")) + } + //Kill + 4 -> { + end() + npc.impactHandler.manualHit(player,npc.skills.lifepoints,ImpactHandler.HitsplatType.NORMAL) + } + //Copy Appearance + 5 -> { + end() + player.appearance.transformNPC(npc.id) + } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(ID) + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/system/command/rottenpotato/RPUseWithPlayerDialogue.kt b/Server/src/main/core/game/system/command/rottenpotato/RPUseWithPlayerDialogue.kt new file mode 100644 index 0000000..f79fdfc --- /dev/null +++ b/Server/src/main/core/game/system/command/rottenpotato/RPUseWithPlayerDialogue.kt @@ -0,0 +1,44 @@ +package core.game.system.command.rottenpotato + +import core.game.dialogue.DialoguePlugin +import core.game.node.entity.combat.ImpactHandler +import core.game.node.entity.player.Player +import core.plugin.Initializable + +@Initializable +/** + * Rotten Potato -> Player interaction dialogue + * @author Ceikry + */ +class RPUseWithPlayerDialogue(player: Player? = null) : DialoguePlugin(player) { + var other: Player? = null + val ID = 38575796 + + override fun newInstance(player: Player?): DialoguePlugin { + return RPUseWithPlayerDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + other = args[0] as Player + + options("Kill","View Bank","Copy Inventory") + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(buttonId){ + 1 -> other!!.impactHandler.manualHit(player,other!!.skills.lifepoints,ImpactHandler.HitsplatType.NORMAL) + 2 -> other!!.bank!!.open(player) + 3 -> { + player.inventory.clear() + player.inventory.addAll(other!!.inventory) + } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(ID) + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/system/command/rottenpotato/RottenPotatoExtraDialogue.kt b/Server/src/main/core/game/system/command/rottenpotato/RottenPotatoExtraDialogue.kt new file mode 100644 index 0000000..5528ecf --- /dev/null +++ b/Server/src/main/core/game/system/command/rottenpotato/RottenPotatoExtraDialogue.kt @@ -0,0 +1,108 @@ +package core.game.system.command.rottenpotato + +import core.api.* +import core.api.InputType +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.world.map.RegionManager +import core.plugin.Initializable +import core.game.world.repository.Repository +import core.tools.colorize + +@Initializable +/** + * Rotten Potato Right click -> Extra dialogue menu + * @author Ceikry + */ +class RottenPotatoExtraDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin(player) { + val ID = 38575794 + val AMEs = arrayOf("chicken","Sandwich Lady","tree spirit","rick turpentine","Genie") + val BossIDs = arrayOf(50,8350,8133,2745) + val BossNames = arrayOf("KBD","Tormented Demon","Corporeal Beast","Jad") + + override fun newInstance(player: Player?): core.game.dialogue.DialoguePlugin { + return RottenPotatoExtraDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + options("Send Player Notification","Targeted AME","Spawn Boss","Force Area NPC Chat","Kill All Nearby NPCs") + stage = 0 + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage) { + + 0 -> when (buttonId) { + //Send Player Notification + 1 -> { + end() + sendInputDialogue(player, InputType.STRING_LONG, "Enter the notification message:"){ value -> + val message = value as String + for (p in Repository.players) { + p ?: continue + p.packetDispatch.sendString(colorize("%Y${message.replace("_", " ").capitalize()}"), 754, 5) + } + } + } + //Targeted AME + 2 -> { + options(*AMEs) + stage = 100 + } + + //Boss Spawn menu + 3 -> { + options(*BossNames) + stage = 200 + } + + //Force Area NPC Chat + 4 -> { + end() + sendInputDialogue(player, InputType.STRING_LONG,"Enter the chat message:"){ value -> + val msg = value as String + RegionManager.getLocalNpcs(player).forEach { + it.sendChat(msg) + } + } + } + + //Kill all nearby NPCs + 5 -> { + end() + RegionManager.getLocalNpcs(player).forEach { + it.finalizeDeath(player) + } + } + + } + //AME Spawning + 100 -> { + end() + sendInputDialogue(player, InputType.STRING_SHORT, "Enter player name:"){ value -> + val other = Repository.getPlayerByName(value.toString().toLowerCase().replace(" ", "_")) + if (other == null) { + player.sendMessage(colorize("%RInvalid player name.")) + } + } + } + + //Spawn boss + 200 -> { + end() + val id = BossIDs[buttonId - 1] + val boss = NPC(id,player.location) + boss.isRespawn = false + boss.isAggressive = true + boss.init() + } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(ID) + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/system/command/rottenpotato/RottenPotatoOptionHandler.kt b/Server/src/main/core/game/system/command/rottenpotato/RottenPotatoOptionHandler.kt new file mode 100644 index 0000000..3d825ca --- /dev/null +++ b/Server/src/main/core/game/system/command/rottenpotato/RottenPotatoOptionHandler.kt @@ -0,0 +1,53 @@ +package core.game.system.command.rottenpotato + +import core.api.removeItem +import core.cache.def.impl.ItemDefinition +import core.game.interaction.OptionHandler +import core.game.node.Node +import core.game.node.entity.player.Player +import core.game.node.entity.player.info.Rights +import core.plugin.Initializable +import core.plugin.Plugin +import org.rs09.consts.Items +import core.tools.SystemLogger +import core.game.system.command.CommandSystem +import core.tools.colorize + +/** + * Handles the Rotten Potato options + * @author Ceikry + */ +private val ROTTEN_POTATO_OPTIONS = arrayOf("RS HD","Heal","Extra","Commands") +@Initializable +class RottenPotatoOptionHandler : OptionHandler() { + override fun newInstance(arg: Any?): Plugin { + for(option in ROTTEN_POTATO_OPTIONS) { + ItemDefinition.forId(Items.ROTTEN_POTATO_5733).handlers["option:${option.toLowerCase()}"] = this + } + return this + } + + override fun handle(player: Player?, node: Node?, option: String?): Boolean { + player ?: return false + node ?: return false + option ?: return false + + // re-add the fucking check because some fucking moron removed it at some point + if(player.rights != Rights.ADMINISTRATOR) + { + removeItem(player, Items.ROTTEN_POTATO_5733) + return false + } + + when(option){ + "rs hd" -> player.dialogueInterpreter.open(RottenPotatoRSHDDialogue().ID) + "heal" -> player.fullRestore().also { player.sendMessage(colorize("%RAll healed!")) } + "extra" -> player.dialogueInterpreter.open(RottenPotatoExtraDialogue().ID) + "commands" -> { + CommandSystem.commandSystem.parse(player,"commands") + } + } + return true + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/system/command/rottenpotato/RottenPotatoRSHDDialogue.kt b/Server/src/main/core/game/system/command/rottenpotato/RottenPotatoRSHDDialogue.kt new file mode 100644 index 0000000..6321d5f --- /dev/null +++ b/Server/src/main/core/game/system/command/rottenpotato/RottenPotatoRSHDDialogue.kt @@ -0,0 +1,87 @@ +package core.game.system.command.rottenpotato + +import core.api.* +import core.api.InputType +import core.game.node.entity.player.Player +import core.game.node.entity.player.info.login.PlayerParser +import core.game.world.ImmerseWorld +import core.game.world.repository.Repository +import core.plugin.Initializable +import core.tools.colorize +import core.game.bots.AIRepository + +@Initializable +/** + * Rotten Potato "RS HD" option menu + * @author Ceikry + */ +class RottenPotatoRSHDDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin(player) { + val ID = 38575793 + override fun newInstance(player: Player?): core.game.dialogue.DialoguePlugin { + return RottenPotatoRSHDDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + options("Wipe Bots", "Spawn Bots", "Force Log Players", "View Bank", "Copy Inventory") + stage = 0 + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> { + when (buttonId) { + //Wipe Bots + 1 -> AIRepository.clearAllBots().also { player.sendMessage(colorize("%RBots wiped.")); end() } + //Spawn Bots + 2 -> ImmerseWorld.spawnBots().also { player.sendMessage(colorize("%RBots Respawning...")); end() } + //Force Log All Online Players + 3 -> { + Repository.disconnectionQueue.clear().also { end() } + Repository.players.toArray().forEach { + val p = it.asPlayer() + if (p != null && !p.isArtificial()) { // Should never be null. + p.removeAttribute("combat-time") + p.clear() + PlayerParser.save(p) + p.getDetails().save() + } + } + } + //View Bank + 4 -> { + end() + sendInputDialogue(player, InputType.STRING_SHORT, "Enter player name:"){ value -> + val other = Repository.getPlayerByName(value.toString().toLowerCase().replace(" ","_")) + if(other == null){ + player.sendMessage(colorize("%RInvalid player name.")) + return@sendInputDialogue + } + + other.bank.open(player) + } + } + //View Inventory + 5 -> { + end() + sendInputDialogue(player, InputType.STRING_SHORT, "Enter player name:"){ value -> + val other = Repository.getPlayerByName(value.toString().toLowerCase().replace(" ","_")) + if(other == null){ + player.sendMessage(colorize("%RInvalid player name.")) + return@sendInputDialogue + } + + player.inventory.clear() + player.inventory.addAll(other.inventory) + } + } + } + } + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(ID) + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/system/command/rottenpotato/RottenPotatoUseWithHandler.kt b/Server/src/main/core/game/system/command/rottenpotato/RottenPotatoUseWithHandler.kt new file mode 100644 index 0000000..c5a97fe --- /dev/null +++ b/Server/src/main/core/game/system/command/rottenpotato/RottenPotatoUseWithHandler.kt @@ -0,0 +1,34 @@ +package core.game.system.command.rottenpotato + +import core.game.node.Node +import core.game.node.scenery.Scenery +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.Item + +/** + * Rotten Potato use-with handling + * @author Ceikry + */ +object RottenPotatoUseWithHandler{ + @JvmStatic + fun handle(node: Node, player: Player){ + if(node is Scenery){ + val go = node.asScenery() + } + + if(node is NPC){ + val npc = node.asNpc() + player.dialogueInterpreter.open(RPUseWithNPCDialogue().ID,npc) + } + + if(node is Item){ + val item = node.asItem() + } + + if(node is Player){ + val p = node.asPlayer() + player.dialogueInterpreter.open(RPUseWithPlayerDialogue().ID,p) + } + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/system/command/sets/AnimationCommandSet.kt b/Server/src/main/core/game/system/command/sets/AnimationCommandSet.kt new file mode 100644 index 0000000..e1de944 --- /dev/null +++ b/Server/src/main/core/game/system/command/sets/AnimationCommandSet.kt @@ -0,0 +1,109 @@ +package core.game.system.command.sets + +import core.game.node.entity.npc.NPC +import core.game.system.task.Pulse +import core.game.world.update.flag.context.Animation +import core.plugin.Initializable +import core.game.system.command.CommandPlugin.Companion.toInteger +import core.game.system.command.Privilege +import core.game.world.GameWorld +import java.util.* + +@Initializable +class AnimationCommandSet : CommandSet(Privilege.ADMIN) { + + private var npcs: List = ArrayList() + + override fun defineCommands() { + + /** + * Force the player to play animation + */ + define("anim", Privilege.ADMIN, "::anim Animation ID", "Plays the animation with the given ID."){ player, args -> + if (args.size < 2) { + reject(player, "Syntax error: ::anim ") + } + val animation = Animation(args[1].toInt()) + player.animate(animation) + } + + /** + * Force the player to play animation + */ + define("anims", Privilege.ADMIN, "::anim Animation ID", "Plays the animation with the given ID."){ player, args -> + if (args.size < 3) { + reject(player, "Syntax error: ::anim ") + } + val animation = args[1].toInt() + val animationTo = args[2].toInt() + GameWorld.Pulser.submit(object : Pulse(3, player) { + var someId = animation + override fun pulse(): Boolean { + player.animate(Animation.create(someId)) + someId += 1 + return someId >= animationTo + } + }) + } + + /** + * Force the player to loop animation + */ + define("loopanim", Privilege.ADMIN, "::loopanim Animation ID Times", "Plays the animation with the given ID the given number of times"){ player, args -> + if (args.size < 2) { + reject(player, "Syntax error: ::loopanim ") + } + val start = toInteger(args[1]) + var end = toInteger((args[2])) + if (end > 25) { + notify(player, "Really...? $end times...? Looping 25 times instead.") + end = 25 + } + GameWorld.Pulser.submit(object : Pulse(3, player) { + var id = start + override fun pulse(): Boolean { + player.animate(Animation.create(id)) + return ++id >= end + } + }) + } + + /** + * Change the player's render animation to + */ + define("ranim", Privilege.ADMIN, "::ranim Render Anim ID", "Sets the player's render (walk/idle) animation."){ player, args -> + if (args.size < 2) { + reject(player, "Syntax error: ::ranim ") + } + if (args.size > 2) { + GameWorld.Pulser.submit(object : Pulse(3, player) { + var id = args[1].toInt() + override fun pulse(): Boolean { + player.appearance.setAnimations(Animation.create(id)) + player.appearance.sync() + player.sendChat("Current: $id") + return ++id >= args[2].toInt() + } + }) + } else { + try { + player.appearance.setAnimations(Animation.create(args[1].toInt())) + player.appearance.sync() + } catch (e: NumberFormatException) { + reject(player, "Syntax error: ::ranim ") + } + } + } + + + /** + * Reset the player's render animation to default + */ + define("ranimreset", Privilege.ADMIN, "", "Resets the player's render (walk/idle) animation to default."){ player, _ -> + player.appearance.prepareBodyData(player) + player.appearance.setDefaultAnimations() + player.appearance.setAnimations() + player.appearance.sync() + } + } +} diff --git a/Server/src/main/core/game/system/command/sets/AudioCommandSet.kt b/Server/src/main/core/game/system/command/sets/AudioCommandSet.kt new file mode 100644 index 0000000..ac8ee03 --- /dev/null +++ b/Server/src/main/core/game/system/command/sets/AudioCommandSet.kt @@ -0,0 +1,99 @@ +package core.game.system.command.sets + +import core.api.playAudio +import core.api.playGlobalAudio +import core.game.node.entity.player.link.music.MusicEntry +import core.game.system.command.Privilege +import core.game.world.map.Location +import core.game.world.repository.Repository +import core.net.packet.PacketRepository +import core.net.packet.context.MusicContext +import core.net.packet.out.MusicPacket +import core.plugin.Initializable + +@Initializable +class MusicCommandSet : CommandSet(Privilege.STANDARD){ + override fun defineCommands() { + + /** + * Command that lets you play a specific song + */ + define("playsong"){player,args -> + if(args.size < 2){ + reject(player,"Usage: ::playsong songID") + } + val id = args[1].toIntOrNull() + if(id == null){ + reject(player,"Please use a valid integer for the song id.") + } + player.musicPlayer.play(MusicEntry.forId(id!!)) + notify(player,"Now playing song $id") + } + /** + * Command that lets you play a specific jingle + */ + define("playjingle"){player,args -> + if(args.size < 2){ + reject(player,"Usage: ::playjingle jingleID") + } + val id = args[1].toIntOrNull() + if(id == null){ + reject(player,"Please use a valid integer for the jingle id.") + } + PacketRepository.send(MusicPacket::class.java, MusicContext(player, id!!, true)) + notify(player,"Now playing jingle $id") + } + + /** + * Command that lets you play a song via the ID instead of the song name + * this is mostly useful for custom tracks that aren't in the ingame + * music player yet. + */ + define("playid"){player,arg -> + if (arg.size < 2) + reject(player, "Needs more args.") + val id = arg[1].toIntOrNull() + if(id != null){ + PacketRepository.send(MusicPacket::class.java, MusicContext(player, id)) + notify(player,"Now playing song $id") + } + } + + /** + * Command that unlocks all music tracks for the player + * Restricted to ADMIN access only. + */ + define("allmusic", Privilege.ADMIN){ player, _ -> + for (me in MusicEntry.getSongs().values) { + player.musicPlayer.unlock(me.id) + } + } + /** + * Command that lets you play an audio id + */ + define("audio", Privilege.ADMIN, "::audio id loops[optional]", "Plays audio by id") { player, args -> + if (args.size < 2 || args.size > 3) + reject(player, "Usage: ::audio id loops[optional]") + val id = args[1].toInt() + val loops = if (args.size > 2) args[2].toInt() else 1 + playAudio(player, id, 0, loops) + } + /** + * Command that lets you play an audio id globally by playername or coords + */ + define("globalaudio", Privilege.ADMIN, "::globalaudio id radius[max 15] location[player name or x y z]", "Play global audio by id, radius, and location") { player, args -> + if (args.size < 3) + reject(player, "Usage: ::globalaudio id radius[max 15] location[player name or x y z]") + val loc = when (args.size) { + 6 -> Location(args[3].toInt(),args[4].toInt(),args[5].toInt()) + 4 -> Repository.getPlayerByName(args[3])?.location + else -> null + } + if (loc == null) + reject(player, "Invalid player name / location") + val id = args[1].toInt() + val radius = if (args[2].toInt() > 15) 15 else args[2].toInt() + if (loc != null) playGlobalAudio(loc, id, 0, 1, radius) + } + } +} diff --git a/Server/src/main/core/game/system/command/sets/BottingCommandSet.kt b/Server/src/main/core/game/system/command/sets/BottingCommandSet.kt new file mode 100644 index 0000000..d3ddcdd --- /dev/null +++ b/Server/src/main/core/game/system/command/sets/BottingCommandSet.kt @@ -0,0 +1,76 @@ +package core.game.system.command.sets + +import core.game.component.Component +import core.plugin.Initializable +import org.rs09.consts.Components +import core.game.bots.GeneralBotCreator +import core.game.bots.PlayerScripts +import core.game.bots.Script +import core.game.system.command.Privilege +import core.game.world.GameWorld +import core.tools.colorize + +@Initializable +class BottingCommandSet : CommandSet(Privilege.STANDARD) { + override fun defineCommands() { + + if (GameWorld.settings?.enabled_botting != true) { + return + } + + define("scripts"){player, _ -> + if(GameWorld.settings?.enabled_botting != true){ + player.sendChat("I just tried to do something silly!") + return@define + } + if(!player.getAttribute("botting:warning_shown",false)){ + player.dialogueInterpreter.sendDialogue(colorize("%RWARNING: Running a bot script will permanently remove you"), colorize("%Rfrom the highscores.")) + player.dialogueInterpreter.addAction { player, buttonId -> player.setAttribute("/save:botting:warning_shown",true) } + return@define + } + for (i in 0..310) { + player.packetDispatch.sendString("", 275, i) + } + var lineid = 11 + player.packetDispatch.sendString("Bot Scripts",275,2) + for(script in PlayerScripts.identifierMap.values) { + player.packetDispatch.sendString("${script.name}", 275, lineid++) + script.description.forEach { line -> + player.packetDispatch.sendString(line,275,lineid++) + } + player.packetDispatch.sendString(" ::script ${script.identifier}",275,lineid++) + player.packetDispatch.sendString(" ",275,lineid++) + } + player.interfaceManager.open(Component(Components.QUESTJOURNAL_SCROLL_275)) + } + define("script"){player,args -> + if(GameWorld.settings?.enabled_botting != true){ + player.sendChat("I just tried to do something very silly!") + return@define + } + if(!player.getAttribute("botting:warning_shown",false)){ + player.dialogueInterpreter.sendDialogue(colorize("%RWARNING: Running a bot script will permanently remove you from the highscores.")) + player.dialogueInterpreter.addAction { player, buttonId -> player.setAttribute("/save:botting:warning_shown",true) } + return@define + } + if(args.size < 2){ + reject(player,"Usage: ::script identifier") + } + val identifier = args[1] + val script = PlayerScripts.identifierMap[identifier] + if(script == null){ + reject(player,"Invalid script identifier") + } + player.interfaceManager.close() + GeneralBotCreator(script!!.clazz.newInstance() as Script,player,true) + player.sendMessage(colorize("%RStarting script...")) + player.sendMessage(colorize("%RTo stop the script, do ::stopscript or log out.")) + + } + define("stopscript"){player,args -> + val pulse: GeneralBotCreator.BotScriptPulse? = player.getAttribute("botting:script",null) + pulse?.stop() + player.interfaceManager.closeOverlay() + } + } +} diff --git a/Server/src/main/core/game/system/command/sets/CameraCommandSet.kt b/Server/src/main/core/game/system/command/sets/CameraCommandSet.kt new file mode 100644 index 0000000..e501da9 --- /dev/null +++ b/Server/src/main/core/game/system/command/sets/CameraCommandSet.kt @@ -0,0 +1,117 @@ +package core.game.system.command.sets + +import core.api.sendMessage +import core.api.utils.PlayerCamera +import core.game.system.command.Privilege +import core.game.world.map.RegionManager +import core.plugin.Initializable + +/** + * Camera command set + * + * @constructor Create empty Camera command set + * + * WARNING: Playing around with camera values may potentially trigger seizures for people with photosensitive epilepsy. + * Please use care when discovering camera values. + */ +@Initializable +class CameraCommandSet : CommandSet(Privilege.ADMIN) { + + override fun defineCommands() { + define("poscam", Privilege.ADMIN, "::poscam Region X Region Y [Height]", "Positions the camera to the given region-local coordinates.") { player, args -> + val regionX = args[1].toIntOrNull() ?: return@define + val regionY = args[2].toIntOrNull() ?: return@define + var height = 300 + + if (args.size > 3) { + height = args[3].toIntOrNull() ?: return@define + } + + val region = RegionManager.forId(player.location.regionId) + val base = region.baseLocation + + val globalLoc = base.transform(regionX, regionY, 0) + sendMessage(player, "CAMERA POSITION | loc:[$regionX, $regionY] settings:[height:$height]") + PlayerCamera(player).setPosition(globalLoc.x, globalLoc.y, height) + } + + define("movcam", Privilege.ADMIN, "::movcam Region X Region Y [Height Speed]", "Moves the camera to the given region-local coordinates.") { player, args -> + val regionX = args[1].toIntOrNull() ?: return@define + val regionY = args[2].toIntOrNull() ?: return@define + var height = 300 + var speed = 100 + + if (args.size > 3) + height = args[3].toIntOrNull() ?: return@define + + if (args.size > 4) + speed = args[4].toIntOrNull() ?: return@define + + val region = RegionManager.forId(player.location.regionId) + val base = region.baseLocation + + val globalLoc = base.transform(regionX, regionY, 0) + sendMessage(player, "CAMERA MOVE | loc:[$regionX, $regionY] settings:[height:$height, speed:$speed]") + PlayerCamera(player).panTo(globalLoc.x, globalLoc.y, height, speed) + } + + define("rotcam", Privilege.ADMIN, "::rotcam Region X Region Y [Height Speed]", "Rotates the camera to face the given region-local coordinates.") { player, args -> + val regionX = args[1].toIntOrNull() ?: return@define + val regionY = args[2].toIntOrNull() ?: return@define + var height = 300 + var speed = 100 + + if (args.size > 3) { + height = args[3].toIntOrNull() ?: return@define + } + + if (args.size > 4) { + speed = args[4].toIntOrNull() ?: return@define + } + + val region = RegionManager.forId(player.location.regionId) + val base = region.baseLocation + + val globalLoc = base.transform(regionX, regionY, 0) + sendMessage(player, "CAMERA ROTATE | loc:[$regionX, $regionY] settings:[height:$height, speed:$speed]") + PlayerCamera(player).rotateTo(globalLoc.x, globalLoc.y, height, speed) + } + + define("shakecam", Privilege.ADMIN, "::shakecam Camera Movement Type (0-4) [Jitter Amplitude Frequency Speed]", + "Type (0-4) Jitter, Amplitude, Frequency (0-255)") {player, args -> + val cameraMovementType = args[1].toIntOrNull() ?: return@define + if (cameraMovementType < 0 || cameraMovementType > 4) { + return@define + } + // Type [0-4] Jit: 0 Amp: 0 Freq: 128 Speed: 2 + var jitter = 0 + var amplitude = 0 + var frequency = 128 + var speed = 2 + + if (args.size > 2) { + jitter = args[2].toIntOrNull() ?: return@define + } + + if (args.size > 3) { + amplitude = args[3].toIntOrNull() ?: return@define + } + + if (args.size > 4) { + frequency = args[4].toIntOrNull() ?: return@define + } + + if (args.size > 5) { + speed = args[5].toIntOrNull() ?: return@define + } + + sendMessage(player, "CAMERA SHAKE | type:$cameraMovementType settings:[jit:$jitter, amp:$amplitude, freq:$frequency, speed:$speed]") + PlayerCamera(player).shake(cameraMovementType, jitter, amplitude, frequency, speed) + } + + define("resetcam", Privilege.ADMIN, "::resetcam", "Resets the current camera position.") {player, args -> + sendMessage(player, "CAMERA RESET") + PlayerCamera(player).reset() + } + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/system/command/sets/CommandSet.kt b/Server/src/main/core/game/system/command/sets/CommandSet.kt new file mode 100644 index 0000000..ba15f41 --- /dev/null +++ b/Server/src/main/core/game/system/command/sets/CommandSet.kt @@ -0,0 +1,57 @@ +package core.game.system.command.sets + +import core.game.node.entity.player.Player +import core.game.system.command.Command +import core.game.system.command.CommandMapping +import core.plugin.Plugin +import core.game.system.command.Privilege +import core.tools.colorize + +/** + * Command sets allow you to organize sets of commands by category/type. It also provides + * a clean way to define them and get them registered to the command mapping, as well as + * a couple other small utiltiies. + * @author Ceikry + * @param defaultPrivilege the default privilege level for all commands in this set. + */ +abstract class CommandSet(val defaultPrivilege: Privilege) : Plugin { + override fun newInstance(arg: Any?): Plugin { + defineCommands() + return this + } + + override fun fireEvent(identifier: String?, vararg args: Any?): Any { + return Unit + } + + abstract fun defineCommands() + + /** + * Glorified player.sendMessage with red text coloring. Please use this + * rather than just player.sendMessage for anything that involves informing the player + * of proper usage or invalid syntax. Throws an IllegalStateException and ends command execution immediately. + */ + fun reject(player: Player, vararg message: String){ + for(msg in message) { + player.sendMessage(colorize("-->%R$msg")) + } + throw IllegalStateException() + } + + /** + * Glorified player.sendMessage with black text coloring and an arrow. Use this when you need to + * notify/inform a player of some information from within the command without ending execution. + */ + fun notify(player: Player, message: String){ + player.sendMessage(colorize("-->$message")) + } + + /** + * Used to define commands. define("name",(optional) privilege override){ handle } + * @param name the name of the command. Example: ::example would be just "example" + * @param privilege (optional) privilege override from the set default. + */ + fun define(name: String, privilege: Privilege = defaultPrivilege, usage: String = "", description: String = "", handle: (Player, Array) -> Unit){ + CommandMapping.register(Command(name, privilege, usage, description, handle)) + } +} diff --git a/Server/src/main/core/game/system/command/sets/ConfigCommandSet.kt b/Server/src/main/core/game/system/command/sets/ConfigCommandSet.kt new file mode 100644 index 0000000..25c5fb2 --- /dev/null +++ b/Server/src/main/core/game/system/command/sets/ConfigCommandSet.kt @@ -0,0 +1,54 @@ +package core.game.system.command.sets + +import core.plugin.Initializable +import core.game.system.command.Command +import core.game.system.command.Privilege +import core.api.* + +@Initializable +class ConfigCommandSet : CommandSet(Privilege.ADMIN){ + override fun defineCommands() { + + /** + * Sets a range of configs to a maximum value + */ + define("sconfigrange"){player, args -> + if (args.size < 3) { + reject(player, "usage: sconfigrange idlo idhi") + } + val idlo = args[1].toIntOrNull() ?: reject(player, "INCORRECT ID LOW") + val idhi = args[2].toIntOrNull() ?: reject(player, "INCORRECT ID HIGH") + for (idsend in (idlo as Int) until (idhi as Int)) { + setVarp(player, idsend, Integer.MAX_VALUE) + notify(player,"Config: $idsend value: " + Integer.MAX_VALUE) + } + } + + /** + * Sets a range of configs to 0 + */ + define("sconfigrange0"){player, args -> + if (args.size < 3) { + reject(player, "usage: sconfigrange0 idlo idhi") + } + val idlo = args[1].toIntOrNull() ?: reject(player, "INCORRECT ID LOW") + val idhi = args[2].toIntOrNull() ?: reject(player, "INCORRECT ID HIGH") + for (idsend in (idlo as Int) until (idhi as Int)) { + setVarp(player, idsend, 0) + notify(player,"Config: $idsend value: 0") + } + } + + /** + * Opens an interface component + */ + define("iface", Privilege.ADMIN, "::iface Interface ID", "Opens the interface with the given ID."){player, args -> + if (args.size < 2) { + reject(player, "usage: iface id") + return@define + } + val id = args[1].toIntOrNull() ?: reject(player, "INVALID INTERFACE ID") + player.interfaceManager.openComponent(id as Int) + } + } +} diff --git a/Server/src/main/core/game/system/command/sets/DevelopmentCommandSet.kt b/Server/src/main/core/game/system/command/sets/DevelopmentCommandSet.kt new file mode 100644 index 0000000..253011d --- /dev/null +++ b/Server/src/main/core/game/system/command/sets/DevelopmentCommandSet.kt @@ -0,0 +1,378 @@ +package core.game.system.command.sets + +import content.global.activity.jobs.JobManager +import core.api.* +import core.cache.Cache +import core.cache.def.impl.DataMap +import core.cache.def.impl.NPCDefinition +import core.cache.def.impl.VarbitDefinition +import core.cache.def.impl.Struct +import core.game.node.entity.combat.ImpactHandler.HitsplatType +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.SpellBookManager +import core.game.node.entity.player.link.diary.DiaryType +import core.game.node.item.Item +import core.net.packet.context.PlayerContext +import core.net.packet.out.ResetInterface +import core.plugin.Initializable +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch +import org.rs09.consts.Items +import core.game.system.command.Privilege +import java.io.BufferedWriter +import java.io.File +import java.io.FileWriter +import java.util.Arrays +import core.net.packet.PacketWriteQueue +import core.tools.Log +import core.game.node.entity.player.info.Rights +import core.game.node.entity.skill.Skills +import core.game.world.map.Location +import core.game.world.repository.Repository + +@Initializable +class DevelopmentCommandSet : CommandSet(Privilege.ADMIN) { + val farmKitItems = arrayListOf(Items.RAKE_5341, Items.SPADE_952, Items.SEED_DIBBER_5343, Items.WATERING_CAN8_5340, Items.SECATEURS_5329, Items.GARDENING_TROWEL_5325,Items.COMPOST_6032, Items.SUPERCOMPOST_6034, Items.PLANT_CURE_6036) + val runeKitItems = arrayListOf(Items.AIR_RUNE_556, Items.EARTH_RUNE_557, Items.FIRE_RUNE_554, Items.WATER_RUNE_555, Items.MIND_RUNE_558, Items.BODY_RUNE_559, Items.DEATH_RUNE_560, Items.NATURE_RUNE_561, Items.CHAOS_RUNE_562, Items.LAW_RUNE_563, Items.COSMIC_RUNE_564, Items.BLOOD_RUNE_565, Items.SOUL_RUNE_566, Items.ASTRAL_RUNE_9075) + + fun getPlayerFromArgs(player: Player, args: Array, startindex: Int = 1): Player? { + val n = args.slice(startindex until args.size).joinToString("_") + if (n == "") { //no argument given -> return self player + return player + } + val target = Repository.getPlayerByName(n) + if (target == null) { + reject(player, "Could not find a player named '$n'") + } + return target + } + + override fun defineCommands() { + define("farmkit", Privilege.ADMIN, "", "Provides a kit of various farming equipment."){player,_ -> + for(item in farmKitItems){ + player.inventory.add(Item(item)) + } + } + + define("cs2", Privilege.ADMIN, "::cs2 id args", "Allows you to call arbitrary cs2 scripts during runtime") {player, args -> + var scriptArgs = ArrayList() + if (args.size == 2) { + runcs2(player, args[1].toIntOrNull() ?: return@define) + return@define + } + else if (args.size > 2) { + for (i in 2 until args.size) { + scriptArgs.add(args[i].toIntOrNull() ?: args[i]) + } + runcs2(player, args[1].toIntOrNull() ?: return@define, *(scriptArgs.toTypedArray().also { player.debug (Arrays.toString(it)) })) + } + } + + define("cleardiary", Privilege.ADMIN) { player, _ -> + for (type in DiaryType.values()) { + val diary = player.achievementDiaryManager.getDiary(type) + for (level in 0 until diary.levelStarted.size) { + for (task in 0 until diary.taskCompleted[level].size) { + diary.resetTask(player, level, task) + } + } + } + sendMessage(player, "All achievement diaries cleared successfully.") + } + + define("clearjob", Privilege.ADMIN) { player, _ -> + val playerJobManager = JobManager.getInstance(player) + playerJobManager.job = null + playerJobManager.jobAmount = -1 + playerJobManager.jobOriginalAmount = -1 + + sendMessage(player, "Job cleared successfully.") + } + + define("region", Privilege.STANDARD, "", "Prints your current Region ID.") {player, args -> + sendMessage(player, "Region ID: ${player.viewport.region.regionId}") + } + + define("spellbook", Privilege.ADMIN, "::spellbook book ID (0 = MODERN, 1 = ANCIENTS, 2 = LUNARS)", "Swaps your spellbook to the given book ID."){player, args -> + if(args.size < 2){ + reject(player,"Usage: ::spellbook [int]. 0 = MODERN, 1 = ANCIENTS, 2 = LUNARS") + } + val spellBook = SpellBookManager.SpellBook.values()[args[1].toInt()] + player.spellBookManager.setSpellBook(spellBook) + player.spellBookManager.update(player) + } + + define("killme", Privilege.ADMIN, "", "Does exactly what it says on the tin.") { player, _ -> + player.impactHandler.manualHit(player, player.skills.lifepoints, HitsplatType.NORMAL) + } + + define("struct") {player, args -> + val mapId = args[1].toIntOrNull() ?: return@define + + val def = Struct.get(mapId) + log(this::class.java, Log.FINE, def.toString()) + } + + define("datamap") {player, args -> + val mapId = args[1].toIntOrNull() ?: return@define + + val def = DataMap.get(mapId) + log(this::class.java, Log.FINE, def.toString()) + } + + define("dumpstructs", Privilege.ADMIN, "", "Dumps all the cache structs to structs.txt") {player, _ -> + val dump = File("structs.txt") + val writer = BufferedWriter(FileWriter(dump)) + val index = Cache.getIndexes()[2] + val containers = index.information.containers[26].filesIndexes + for(fID in containers) + { + val file = index.getFileData(26, fID) + if(file != null){ + val def = Struct.parse(fID, file) + if(def.dataStore.isEmpty()) continue //no data in struct. + writer.write(def.toString()) + writer.newLine() + } + } + writer.flush() + writer.close() + } + + define("dumpdatamaps", Privilege.ADMIN, "", "Dumps all the cache data maps to datamaps.txt") {player, _ -> + val index = Cache.getIndexes()[17] + val containers = index.information.containersIndexes + + val dump = File("datamaps.txt") + val writer = BufferedWriter(FileWriter(dump)) + + for(cID in containers) + { + val fileIndexes = index.information.containers[cID].filesIndexes + for(fID in fileIndexes) + { + val file = index.getFileData(cID, fID) + if(file != null){ + val def = DataMap.parse((cID shl 8) or fID, file) + if(def.keyType == '?') continue //Empty definition - only a 0 present in the cachefile data. + writer.write(def.toString()) + writer.newLine() + } + } + } + writer.flush() + writer.close() + } + + define("rolldrops", Privilege.ADMIN, "::rolldrops NPC ID AMOUNT", "Rolls the given NPC drop table AMOUNT times.") { player: Player, args: Array -> + if(args.size < 2){ + reject(player,"Usage: ::rolldrops npcid amount") + } + + val container = player.dropLog + val npcId = args[1].toInt() + val amount = args[2].toInt() + + container.clear() + val drops = NPCDefinition.forId(npcId).dropTables.table.roll(player, amount) + for(drop in drops) container.add(drop, false) + container.open(player) + } + + define("varbits", Privilege.ADMIN, "::varbits Varp ID", "Lists all the varbits assigned to the given varp.") { player, args -> + if(args.size < 2) + reject(player, "Usage: ::varbits varpIndex") + + val varp = args[1].toIntOrNull() ?: reject(player, "Please use a valid int for the varpIndex.") + GlobalScope.launch { + sendMessage(player, "========== Found Varbits for Varp $varp ==========") + for(id in 0 until 10000) + { + val def = VarbitDefinition.forId(id) + if(def.varpId == varp) + { + sendMessage(player, "${def.id} -> [offset: ${def.startBit}, upperBound: ${def.endBit}]") + } + } + sendMessage(player, "=========================================") + } + } + + define("testpacket") { player, _ -> + PacketWriteQueue.write(ResetInterface(), PlayerContext(player)) + } + + define("npcsearch", Privilege.STANDARD, "npcsearch name", "Searches for NPCs that match the name either in main or children.") {player, strings -> + val name = strings.slice(1 until strings.size).joinToString(" ").lowercase() + for (id in 0 until 9000) { + val def = NPCDefinition.forId(id) + if (def.name.isNotBlank() && (def.name.lowercase().contains(name) || name.contains(def.name.lowercase()))) { + notify(player, "$id - ${def.name}") + } + else { + for ((childId,index) in def.childNPCIds?.withIndex() ?: continue) { + val childDef = NPCDefinition.forId(childId) + if (childDef.name.lowercase().contains(name) || name.contains(childDef.name.lowercase())) { + notify(player, "$childId child($id) index $index - ${childDef.name}") + } + } + } + } + } + + define("itemsearch", Privilege.STANDARD, "itemsearch name", "Searches for items that match the name.") {player, args -> + val itemName = args.copyOfRange(1, args.size).joinToString(" ").lowercase() + for (i in 0 until 15000) { + val name = getItemName(i).lowercase() + if (name.contains(itemName) || itemName.contains(name)) + notify(player, "$i: $name") + } + } + + define("runekit", Privilege.ADMIN, "", "Gives 1k of each Rune type" ) { player, args -> + for(item in runeKitItems) { + addItem(player, item, 1000) + } + } + + define("drawchunks", Privilege.ADMIN, "", "Draws the border of the chunk you're standing in") {player, _ -> + setAttribute (player, "chunkdraw", !getAttribute(player, "chunkdraw", false)) + } + + define("drawclipping", Privilege.ADMIN, "", "Draws the clipping flags of the region you're standing in") {player, _ -> + setAttribute (player, "clippingdraw", !getAttribute(player, "clippingdraw", false)) + } + + define("drawregions", Privilege.ADMIN, "", "DRaws the border of the region you're standing in") {player, _ -> + setAttribute (player, "regiondraw", !getAttribute(player, "regiondraw", false)) + } + + define("drawroute", Privilege.ADMIN, "", "Visualizes the path your player is taking") {player, _ -> + setAttribute (player, "routedraw", !getAttribute(player, "routedraw", false)) + } + + define ("fmstart", Privilege.ADMIN, "", "") {player, _ -> + setAttribute(player, "fmstart", Location.create(player.location)) + } + + define ("fmend", Privilege.ADMIN, "", "") {player, _ -> + setAttribute(player, "fmend", Location.create(player.location)) + } + + define ("fmspeed", Privilege.ADMIN, "", "") {player, args -> + setAttribute(player, "fmspeed", args[1].toIntOrNull() ?: 10) + } + + define ("fmspeedend", Privilege.ADMIN, "", "") {player, args -> + setAttribute(player, "fmspeedend", args[1].toIntOrNull() ?: 10) + } + + define("testfm", Privilege.ADMIN, "", "") { player, _ -> + val start = getAttribute(player, "fmstart", Location.create(player.location)) + val end = getAttribute(player, "fmend", Location.create(player.location)) + val speed = getAttribute(player, "fmspeed", 10) + val speedEnd = getAttribute(player, "fmspeedend", 10) + val ani = getAttribute(player, "fmanim", -1) + forceMove(player, start, end, speed, speedEnd, anim = ani) + } + + define("fmanim", Privilege.ADMIN, "", "") {player, args -> + setAttribute(player, "fmanim", args[1].toIntOrNull() ?: -1) + } + + define("drawintersect", Privilege.ADMIN, "", "Visualizes the predicted intersection point with an NPC") {player, _ -> + setAttribute(player, "draw-intersect", !getAttribute(player, "draw-intersect", false)) + } + + define("expression", Privilege.ADMIN, "::expression id", "Visualizes chathead animations from ID.") { player, args -> + if(args.size != 2) + reject(player, "Usage: ::expression id") + val id = args[1].toIntOrNull() ?: 9804 + player.dialogueInterpreter.sendDialogues(player, id, "Expression ID: $id") + } + + define("timers", Privilege.ADMIN, "::timers", "Print out timers") { player, args -> + player.sendMessage("Active timers:") + for(timer in player.timers.activeTimers) { + player.sendMessage(" ${timer.identifier} ${timer.nextExecution}") + } + player.sendMessage("New timers:") + for(timer in player.timers.newTimers) { + player.sendMessage(" ${timer.identifier}") + } + } + + define("setpestpoints", Privilege.ADMIN, "::setpestpoints points player_name", "Sets your (or player_name's) Pest Control points to 'points'") { player, args -> + val target = getPlayerFromArgs(player, args, 2) ?: return@define + val points = args[1].toIntOrNull() + if (points == null) { + reject(player, "No valid 'points' argument given") + } + target.savedData.activityData.pestPoints = points!! + } + + define("makeadmin", Privilege.ADMIN, "::makeadmin player_name", "Permanently gives admin rights to player_name (or self if empty)") { player, args -> + val target = getPlayerFromArgs(player, args, 1) ?: return@define + target.details.rights = Rights.ADMINISTRATOR + sendMessage(player, "Gave admin rights to ${target.username}.") + sendMessage(target, "You've been given admin rights by ${player.username}!") + } + + define("dropadmin", Privilege.ADMIN, "::dropadmin", "Permanently drops admin rights from self") { player, _ -> + player.details.rights = Rights.REGULAR_PLAYER + sendMessage(player, "Dropped admin rights.") + } + + define("max", Privilege.ADMIN, "::max player_name", "Gives all 99s to player_name (or self if empty)") { player, args -> + val target = getPlayerFromArgs(player, args, 1) ?: return@define + var index = 0 + Skills.SKILL_NAME.forEach { + target.skills.setStaticLevel(index,99) + target.skills.setLevel(index,99) + index++ + } + target.skills.updateCombatLevel() + } + + define("noobme", Privilege.ADMIN, "::noobme player_name", "Sets player_name (or self if empty) back to default stats") { player, args -> + val target = getPlayerFromArgs(player, args, 1) ?: return@define + var index = 0 + Skills.SKILL_NAME.forEach { + val level = if (index == Skills.HITPOINTS) 10 else 1 + target.skills.setStaticLevel(index, level) + target.skills.setLevel(index, level) + index++ + } + target.skills.updateCombatLevel() + } + + define("setlevel", Privilege.ADMIN, "::setlevel SKILL NAME LEVEL PLAYER", "Sets SKILL NAME to LEVEL for PLAYER (self if omitted)."){player,args -> + if (args.size < 3) reject(player,"Usage: ::setlevel skillname level") + val skillname = args[1] + val desiredLevel: Int? = args[2].toIntOrNull() + if (desiredLevel == null) { + reject(player, "Level must be an integer.") + } + if (desiredLevel!! > 99) reject(player,"Level must be 99 or lower.") + val skill = Skills.getSkillByName(skillname) + if (skill < 0) reject(player, "Must use a valid skill name!") + val target = getPlayerFromArgs(player, args, 3) ?: return@define + target.skills.setStaticLevel(skill,desiredLevel) + target.skills.setLevel(skill,desiredLevel) + target.skills.updateCombatLevel() + } + + define("addxp", Privilege.ADMIN, "::addxp skill name | id xp", "Add xp to skill") { player, args -> + if (args.size < 3) reject(player, "Usage: ::addxp skill name | id xp player(optional)") + val target = getPlayerFromArgs(player, args, 3) ?: return@define + + val skill = args[1].toIntOrNull() ?: Skills.getSkillByName(args[1]) + if (skill < 0 || skill >= Skills.NUM_SKILLS) reject(player, "Must use valid skill name or id.") + + val xp = args[2].toDoubleOrNull() + if (xp == null || xp <= 0) reject(player, "Xp must be a positive number.") + + target.skills.addExperience(skill, xp!!) + } + } +} diff --git a/Server/src/main/core/game/system/command/sets/FunCommandSet.kt b/Server/src/main/core/game/system/command/sets/FunCommandSet.kt new file mode 100644 index 0000000..ec69cdd --- /dev/null +++ b/Server/src/main/core/game/system/command/sets/FunCommandSet.kt @@ -0,0 +1,237 @@ +package core.game.system.command.sets + +import content.global.handlers.item.SpadeDigListener +import content.region.misc.tutisland.handlers.iface.CharacterDesign +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.node.entity.combat.ImpactHandler +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.player.info.login.PlayerSaver +import core.game.system.command.Privilege +import core.game.system.task.Pulse +import core.game.world.GameWorld +import core.game.world.map.Location +import core.game.world.map.RegionManager +import core.game.world.repository.Repository.getPlayerByName +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import core.plugin.Initializable +import core.tools.END_DIALOGUE +import core.tools.RandomFunction +import org.json.simple.JSONObject +import org.rs09.consts.Sounds +import java.awt.HeadlessException +import java.awt.Toolkit +import java.awt.datatransfer.StringSelection +import kotlin.streams.toList + +@Initializable +class FunCommandSet : CommandSet(Privilege.ADMIN) { + + var npcs: List = ArrayList() + + + override fun defineCommands() { + + /** + * Force animation + messages on all NPCs in a radius of 10 from the player. + * Add an optional 3rd argument if cycling through a range of animation ids. + */ + define("npcanim", Privilege.ADMIN, "::npcanim Animation ID Optional: End Animation ID") { player, args -> + if (args.size < 2) { + reject(player, "Syntax error: ::npcanim ") + } + npcs = RegionManager.getLocalNpcs(player.location, 10) + for (n in npcs) { + n.lock(6) + n.faceTemporary(player, 6) + if (args.size == 2) { + n.sendChat(args.slice(1 until args.size).joinToString(" ")) + n.animate(Animation(args[1].toInt())) + n.animate(Animation.create(-1), 6) + } + if (args.size == 3) { + var count = 0 + for(animNum in args[1].toInt()..args[2].toInt()) { + count++ + n.animate(Animation(animNum), count*6) + } + } + } + } + + + /** + * Transform a player's appearance into that of an NPC. + */ + define("pnpc", Privilege.MODERATOR, "::pnpc NPC ID", "Transforms the player into the given NPC."){ player, args -> + if(args.size < 2){ + reject(player, "Usage: ::pnpc ") + return@define + } + + val pnpc_id = args[1].toIntOrNull() + if(pnpc_id == null){ + reject(player, " must be a valid integer.") + } + + player.appearance.transformNPC(pnpc_id!!) + notify(player,"Transformed into NPC $pnpc_id") + } + + + /** + * Open bank + */ + define("bank", Privilege.ADMIN, "", "Opens your bank."){ player, _ -> + player.getBank().open() + } + + /** + * Toggle invisibility + */ + define("invis", Privilege.ADMIN, "", "Makes you invisible to others."){ player, _ -> + player.isInvisible = !player.isInvisible + notify(player,"You are now ${if (player.isInvisible) "invisible" else "visible"} to others.") + } + + + /** + * Toggle 1-hit kills + */ + define("1hit", Privilege.ADMIN, "", "Makes you kill things in 1 hit."){ player, _ -> + player.setAttribute("1hko", !player.getAttribute("1hko", false)) + notify(player,"1-hit KO mode " + if (player.getAttribute("1hko", false)) "on." else "off.") + } + + + /** + * Toggle god mode + */ + define("god", Privilege.ADMIN, "", "Makes you invulnerable to damage."){ player, _ -> + player.setAttribute("godMode", !player.getAttribute("godMode", false)) + notify(player,"God mode ${if (player.getAttribute("godMode", false)) "enabled." else "disabled."}") + } + + + /** + * Go on Mr Bones' Wild Ride + */ + define("mrboneswildride"){ player, args -> + val p : Player = if(args.size > 2){ + reject(player, "Usage: ::mrboneswildride ") + return@define + } else if(args.size == 1) { + player + } else if(getPlayerByName(args[1]) == null) { + reject(player, "ERROR: Username not found. Usage: ::mrboneswildride ") + return@define + } else { + getPlayerByName(args[1]) ?: return@define + } + val boneMode = !p.getAttribute("boneMode",false) + p.setAttribute("boneMode", boneMode) + notify(p,"Bone Mode ${if (boneMode) "ENGAGED." else "POWERING DOWN."}") + p.appearance.rideCart(boneMode) + if (p.appearance.isRidingMinecart) { + var i = 0 + GameWorld.Pulser.submit(object : Pulse(1, player) { + override fun pulse(): Boolean { + if (i++ % 12 == 0) p.sendChat("I want to get off Mr. Bones Wild Ride.") + p.moveStep() + return !p.appearance.isRidingMinecart + } + }) + } + } + + + /** + * Opens up the makeover interface + */ + define("makeover", Privilege.MODERATOR){ player, _ -> + CharacterDesign.open(player) + } + + /** + * Copies your current appearance and equipment as JSON to the clipboard + */ + define("dumpappearance", Privilege.MODERATOR){ player, _ -> + val json = JSONObject() + PlayerSaver(player).saveAppearance(json) + val equipJson = PlayerSaver(player).saveContainer(player.equipment) + json["equipment"] = equipJson + val jsonString = json.toJSONString() + try { + val clpbrd = Toolkit.getDefaultToolkit().systemClipboard + clpbrd.setContents(StringSelection(jsonString), null) + notify(player, "Appearance and equipment copied to clipboard.") + } catch (e: HeadlessException) { + reject(player, "NOTE: Paste will not be available due to remote server.") + } + } + + /** + * Bury inventory at current location + */ + define("bury"){player, _ -> + if(player.inventory.isEmpty){ + reject(player, "You have no items to bury.") + } + + player.dialogueInterpreter.open(object : DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + when(stage){ + 0 -> dialogue("This will bury your whole inventory in this spot.","Are you sure?").also { stage++ } + 1 -> options("Yes","No").also { stage++ } + 2 -> when(buttonID){ + 1 -> bury(player).also { end() } + 2 -> stage = END_DIALOGUE + } + } + } + }) + + } + + define("appearance", Privilege.ADMIN, "", "Allows you to change your appearance."){ player, _ -> + CharacterDesign.reopen(player) + } + + /** + * Cast a weakened version of ice barrage on nearby players within the defined radius. + * This spell will never kill or freeze a player + */ + define("barrage", Privilege.ADMIN, "::barrage radius ", "Cast a weak barrage on all nearby players. Will never kill players") { player, args -> + if (args.size != 2) + reject(player, "Usage: ::barrage radius[max = 50]") + val radius = if (args[1].toInt() > 50) 50 else args[1].toInt() + val nearbyPlayers = RegionManager.getLocalPlayers(player, radius).stream().filter { p: Player -> p.username != player.username }.toList() + animate(player, 1978) + playGlobalAudio(player.location, Sounds.ICE_CAST_171) + for (p in nearbyPlayers) { + playGlobalAudio(p.location, Sounds.ICE_BARRAGE_IMPACT_168, 20) + val impactAmount = if (p.skills.lifepoints < 10 ) 0 else RandomFunction.getRandom(3) + impact(p, impactAmount, ImpactHandler.HitsplatType.NORMAL) + p.graphics(Graphics(369, 0)) + } + } + } + + fun bury(player: Player){ + val loc = Location.create(player.location) + val inv = player.inventory.toArray().filterNotNull() + SpadeDigListener.registerListener(player.location){ p -> + for(item in inv){ + addItemOrDrop(p, item.id, item.amount) + sendMessage(p, "You dig and find ${if(item.amount > 1) "some" else "a"} ${item.name}") + } + sendNews("${player.username} has found the hidden treasure! Congratulations!!!") + SpadeDigListener.listeners.remove(loc) + } + player.inventory.clear() + notify(player, "You have buried your loot at ${loc.toString()}") + } + +} diff --git a/Server/src/main/core/game/system/command/sets/IfCommandSet.kt b/Server/src/main/core/game/system/command/sets/IfCommandSet.kt new file mode 100644 index 0000000..b088b03 --- /dev/null +++ b/Server/src/main/core/game/system/command/sets/IfCommandSet.kt @@ -0,0 +1,61 @@ +package core.game.system.command.sets + +import core.api.Commands +import core.api.getChildren +import core.cache.def.impl.ComponentType +import core.cache.def.impl.IfaceDefinition +import core.game.system.command.Privilege + +class IfCommandSet : Commands { + override fun defineCommands() { + define ("iftriggers", Privilege.ADMIN, "::iftriggers id", "Lists all known triggers for the given interface.") {player, args -> + val id = args.getOrNull(1)?.toIntOrNull() ?: -1 + if (id == -1) reject(player, "Must supply a valid interface ID!") + + val def = IfaceDefinition.forId(id) + notify(player, logToConsole = true, message = "Triggers for $def:") + + for (child in def.children) { + if (child.scripts == null) continue + if (child.triggers == null) continue + + if (child.scripts.onVarpTransmit != null) { + notify(player, logToConsole = true, message = "$child [VARP]:") + notify(player, logToConsole = true, message = " Transmit ${child.triggers.varpTriggers.joinToString(",")} triggers script ${child.scripts.onVarpTransmit.id}") + notify(player, logToConsole = true, message = " Default script args: ${child.scripts.onVarpTransmit.args.joinToString(",")}") + } + if (child.scripts.onVarcTransmit != null) { + notify(player, logToConsole = true, message = "$child [VARC]:") + notify(player, logToConsole = true, message = " Transmit ${child.triggers.varcTriggers.joinToString(",")} triggers script ${child.scripts.onVarcTransmit.id}") + notify(player, logToConsole = true, message = " Default script args: ${child.scripts.onVarcTransmit.args.joinToString(",")}") + } + } + } + + define ("listiftext", Privilege.ADMIN, "::listiftext id", "Prints all text values and their child index on an interface.") {player, args -> + val id = args.getOrNull(1)?.toIntOrNull() ?: -1 + if (id == -1) reject(player, "Must supply a valid interface ID!") + + val def = IfaceDefinition.forId(id) + notify(player, logToConsole = true, message = "Text for $def:") + + for (child in def.children) { + if (child.type != ComponentType.TEXT) continue + notify(player, logToConsole = true, message = "$child - ${child.text} - ${child.activeText}") + } + } + + define ("listifmodels", Privilege.ADMIN, "::listifmodels id", "Prints all default model values and their child index.") {player, args -> + val id = args.getOrNull(1)?.toIntOrNull() ?: -1 + if (id == -1) reject(player, "Must supply a valid interface ID!") + + val def = IfaceDefinition.forId(id) + notify(player, logToConsole = true, message = "Models for $def:") + + for (child in def.children) { + if (child.type != ComponentType.MODEL) continue + notify(player, logToConsole = true, message = "$child - ${child.modelId}/${child.activeModelId} - Anim: ${child.modelAnimId}/${child.activeModelAnimId}") + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/system/command/sets/MiscCommandSet.kt b/Server/src/main/core/game/system/command/sets/MiscCommandSet.kt new file mode 100644 index 0000000..b959495 --- /dev/null +++ b/Server/src/main/core/game/system/command/sets/MiscCommandSet.kt @@ -0,0 +1,852 @@ +package core.game.system.command.sets + +import content.global.handlers.iface.* +import content.global.skill.farming.timers.* +import content.minigame.fishingtrawler.TrawlerLoot +import content.region.misthalin.draynor.quest.anma.AnmaCutscene +import core.ServerConstants +import core.api.* +import core.api.utils.permadeath +import core.cache.def.impl.NPCDefinition +import core.cache.def.impl.SceneryDefinition +import core.cache.def.impl.VarbitDefinition +import core.game.bots.AIRepository +import core.game.component.Component +import core.game.ge.GrandExchange +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.player.info.Rights +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import core.game.node.scenery.Scenery +import core.game.system.command.CommandMapping +import core.game.system.command.Privilege +import core.game.system.communication.CommunicationInfo +import core.game.world.map.RegionManager +import core.game.world.map.build.DynamicRegion +import core.game.world.repository.Repository +import core.plugin.Initializable +import core.tools.Log +import core.tools.StringUtils +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch +import org.rs09.consts.Components +import java.awt.HeadlessException +import java.awt.Toolkit +import java.awt.datatransfer.StringSelection + +@Initializable +class MiscCommandSet : CommandSet(Privilege.ADMIN){ + override fun defineCommands() { + + /** + * Toggles debug mode + */ + define("debug", Privilege.STANDARD, "", "Toggles debug mode."){ player, _ -> + player.toggleDebug() + } + + define("calcaccuracy", Privilege.STANDARD, "::calcaccuracy NPC ID", "Calculates and prints your current chance to hit a given NPC."){ player, args -> + val handler = player.getSwingHandler(false) + player.sendMessage("handler type: ${handler.type}") + val accuracy = handler.calculateAccuracy(player) + player.sendMessage("calculateAccuracy: ${accuracy}") + + if (args.size > 1) + { + val npcId: Int = args[1].toInt() + val npc = NPC(npcId) + npc.initConfig() + player.sendMessage("npc: ${npc.name}. npc defence: ${npc.skills.getLevel(Skills.DEFENCE)}") + val defence = handler.calculateDefence(npc, player) + player.sendMessage("calculateDefence: ${defence}") + val chance: Double = if (accuracy > defence) { + 1.0 - ((defence + 2.0) / (2.0 * (accuracy + 1.0))) + } else { + accuracy / (2.0 * (defence + 1.0)) + } + player.sendMessage("chance to hit: ${chance}") + } + } + + define("anmacs", Privilege.ADMIN) { player, _ -> + AnmaCutscene(player).start() + } + + define("setsaveversion", Privilege.ADMIN) { player, args -> + try{ + player.version = args[1].toInt() + notify(player, "Setting save version to ${player.version}") + } + catch (nfe: NumberFormatException){ + reject(player, "Save versions can only be an integer") + } + } + + /** + * Prints player's current location + */ + define("loc", Privilege.STANDARD, "", "Prints quite a lot of information about your current location."){ player, _-> + val l = player.location + val r = player.viewport.region + var obj: Scenery? = null + notify(player,"Absolute: " + l + ", regional: [" + l.localX + ", " + l.localY + "], chunk: [" + l.chunkOffsetX + ", " + l.chunkOffsetY + "], flag: [" + RegionManager.isTeleportPermitted(l) + ", " + RegionManager.getClippingFlag(l) + ", " + RegionManager.isLandscape(l) + "].") + notify(player,"Region: [id=" + l.regionId + ", active=" + r.isActive + ", instanced=" + (r is DynamicRegion) + "], obj=" + RegionManager.getObject(l) + ".") + notify(player, "Jagex: ${l.z}_${l.regionId shr 8}_${l.regionId and 0xFF}_${l.localX}_${l.localY}") + notify(player,"Object: " + RegionManager.getObject(l).also{obj = it} + ".") + notify(player,"Object Varp: " + obj?.definition?.configFile?.varpId + " offset: " + obj?.definition?.configFile?.startBit + " size: " + (obj?.definition?.configFile?.startBit?.minus(obj?.definition?.configFile?.startBit!!))) + log(this::class.java, Log.FINE, "Viewport: " + l.getSceneX(player.playerFlags.lastSceneGraph) + "," + l.getSceneY(player.playerFlags.lastSceneGraph)) + val loc = "Location.create(" + l.x + ", " + l.y + ", " + l.z + ")" + log(this::class.java, Log.FINE, loc + "; " + player.playerFlags.lastSceneGraph + ", " + l.localX + ", " + l.localY) + try { + val stringSelection = StringSelection(loc) + val clpbrd = Toolkit.getDefaultToolkit().systemClipboard + clpbrd.setContents(stringSelection, null) + notify(player, "Coordinates copied to clipboard.") + } catch (e: HeadlessException) { + reject(player, "NOTE: Paste will not be available due to remote server.") + } + } + + /** + * Tells the player to use loc + */ + define("pos", Privilege.STANDARD){ player, _-> + notify(player, "Do you mean ::loc?") + } + + /** + * Tells the player to use loc + */ + define("coords", Privilege.STANDARD){ player, _-> + notify(player, "Do you mean ::loc?") + } + + define("calcmaxhit", Privilege.STANDARD, "", "Calculates and shows you your current max hit.") { player, _ -> + val swingHandler = player.getSwingHandler(false) + val hit = swingHandler.calculateHit(player, player, 1.0) + notify(player, "max hit: ${hit} (${(swingHandler as Object).getClass().getName()})") + } + + /** + * Empty a player's inventory + * ADMIN only (for obvious reasons) + */ + define("empty", Privilege.ADMIN, "", "Empties your inventory."){player,_-> + player.inventory.clear() + player.inventory.refresh() + } + + /** + * Announces a message in chat (NEWS) + */ + define("announce", Privilege.ADMIN, "::announce String", "Sends the given string as a News message."){_,args -> + val message = args.slice(1 until args.size).joinToString(" ") + Repository.sendNews(message) + } + + /** + * Lists the players currently online + */ + define("players", Privilege.MODERATOR, "", "Lists the online players."){ player, _ -> + val rights = player.rights.ordinal + if (player!!.interfaceManager.isOpened && player.interfaceManager.opened.id != Components.QUESTJOURNAL_SCROLL_275 || player.locks.isMovementLocked || player.locks.isTeleportLocked) { + reject(player, "Please finish what you're doing first.") + } + player.interfaceManager.open(Component(Components.QUESTJOURNAL_SCROLL_275)) + var i = 0 + while (i < 257) { + player.packetDispatch.sendString("", 275, i) + i++ + } + val red = "" + player.packetDispatch.sendString("" + "Players" + "", 275, 2) + var lineStart = 11 + for(p in Repository.players){ + if(!p.isArtificial) + player.packetDispatch.sendString(red + "" + p.username + if(rights > 0) " [ip=" + p.details.ipAddress + ", name=" + p.details.compName + "]" else "",275,lineStart++) + } + } + + /** + * Lists information about a bot + */ + define("botinfo", Privilege.STANDARD, "::botinfo botname", "Prints debug information about a bot"){ player, args -> + val scriptInstances = AIRepository.PulseRepository + + // Find the bot with the given name (non-case sensitive, concat args by space) + val botName = args.slice(1 until args.size).joinToString(" ").lowercase() + val bot = scriptInstances[botName] + if (bot == null) { + reject(player, "No bot with that name found.") + return@define + } + val botInfo = bot.botScript.toString() + // Print the bot's information, max 80chars per line + botInfo.chunked(80).forEach { notify(player, it) } + } + + /** + * Opens the credit/voting shop + */ + define("shop", Privilege.STANDARD, "", "Opens the credit shop."){ player, _ -> + if (player.locks.isInteractionLocked || player.locks.isMovementLocked) { + sendMessage(player, "You can't open the shop right now.") + } else player.interfaceManager.open(Component(Components.CREDIT_SHOP)) + } + + /** + * Shows the player a list of currently active GE sell offers + */ + define("ge", Privilege.STANDARD, "::ge MODE (Modes: buying, selling, search, bots, botsearch)", "Various commands for viewing GE offers.") { player, args -> + if(args.size < 2){ + reject(player, "Usage: ::ge mode", "Available modes: buying, selling, search, bots, botsearch") + } + + val mode = args[1] + when(mode){ + "buying" -> showGeBuy(player) + "selling" -> showGeSell(player) + "search" -> showGeInputDialogue(player, args, ::showOffers) + "bots" -> showGeBots(player) + "botsearch" -> showGeInputDialogue(player, args, ::showGeBotsearch) + else -> reject(player, "Invalid mode used. Available modes are: buying, selling, search") + } + } + /** + * ================================================================================== + */ + + + /** + * List all commands + */ + define("commands", Privilege.STANDARD, "::commands page", "Lists all the commands (you are here.)"){player, args -> + val page = if (args.size > 1) (args[1].toIntOrNull() ?: 1) - 1 else 0 + var lineid = 11 + var pages = CommandMapping.getPageIndices(player.rights.ordinal) + var end = if (page < (pages.size - 1)) pages[page + 1] else CommandMapping.getCommands().size + + player.interfaceManager.close() + + if (page < 0) { + reject(player, "Usage: ::commands page") + } + + if (page > pages.size) { + reject(player, "That page number is too high, you don't have access to that many.") + } + + for (i in 0..310) { + player.packetDispatch.sendString("", Components.QUESTJOURNAL_SCROLL_275, i) + } + + player.packetDispatch.sendString( + "Commands" + if (pages.size > 1) " (${page + 1}/${pages.size})" else "", + Components.QUESTJOURNAL_SCROLL_275, + 2 + ) + + + for(i in pages[page] until end) { + var command = CommandMapping.getCommands()[i] + var title = "${command.name}" + var rights = command.privilege.ordinal + var icon = rights - 1 + + + if (rights > player.rights.ordinal) continue + + if (rights > 0) + title = "() $title" + + player.packetDispatch.sendString(title, Components.QUESTJOURNAL_SCROLL_275, lineid++) + + if (command.usage.isNotEmpty()) + player.packetDispatch.sendString("Usage: ${command.usage}", Components.QUESTJOURNAL_SCROLL_275, lineid++) + + if (command.description.isNotEmpty()) + player.packetDispatch.sendString(command.description, Components.QUESTJOURNAL_SCROLL_275, lineid++) + + player.packetDispatch.sendString("-------------------------------", Components.QUESTJOURNAL_SCROLL_275, lineid++) + + if (lineid > 306) { + player.packetDispatch.sendString("To view the next page, use ::commands ${page + 2}", Components.QUESTJOURNAL_SCROLL_275, lineid) + break + } + + } + player.interfaceManager.open(Component(Components.QUESTJOURNAL_SCROLL_275)) + } + + /** + * Reply to PMs (also enables tab-to-reply) + */ + define("reply", Privilege.STANDARD, "", "Opens a reply prompt to your last DM. Same as pressing tab."){ player, _ -> + if(player.interfaceManager.isOpened){ + reject(player, "Please finish what you're doing first.") + } + if (player.attributes.containsKey("replyTo")) { + player.setAttribute("keepDialogueAlive", true) + val replyTo = player.getAttribute("replyTo", "").replace("_".toRegex(), " ") + sendInputDialogue(player, InputType.MESSAGE ,StringUtils.formatDisplayName(replyTo)){ value -> + CommunicationInfo.sendMessage(player, replyTo.toLowerCase(), value as String) + player.removeAttribute("keepDialogueAlive") + } + } else { + reject(player, "You have not recieved any recent messages to which you can reply.") + } + } + + /** + * Enables client to safety close the currently opened interface or dialogue (esc-to-close plugin) + */ + define("xface", Privilege.STANDARD, "", "Closes the currently opened interface/dialogue."){player, _ -> + player.interfaceManager.close() + player.dialogueInterpreter.close() + } + + define("completediaries", Privilege.ADMIN, "", "Completes all diaries."){player,_ -> + player.achievementDiaryManager.diarys.forEach { + for(level in it.taskCompleted.indices){ + for(task in it.taskCompleted[level].indices){ + it.finishTask(player,level,task) + } + } + } + } + + /** + * Permadeaths a player, resetting their save + */ + define("permadeath", Privilege.ADMIN, "::permadeath PLAYER", "Permadeaths PLAYER (self if omitted), completely wiping their save."){player,args -> + var target = player + if (args.size > 1) { + val n = args.slice(1 until args.size).joinToString("_") + val foundtarget = Repository.getPlayerByName(n) + if (foundtarget == null) { + reject(player, "Invalid player \"${n}\" or player not online") + } + target = foundtarget!! + } + permadeath(target) + } + + define("log", Privilege.ADMIN){player,_ -> + var log: ArrayList? = player.getAttribute("loc-log") + log = log ?: ArrayList() + val locString = "{${player.location.x},${player.location.y},${player.location.z},1,0}" + log.add(locString) + player.setAttribute("loc-log",log) + } + + define("logdone"){player,_ -> + val log: ArrayList? = player.getAttribute("loc-log") + log ?: return@define + + val sb = StringBuilder() + var first = true + for(entry in log){ + if(!first) sb.append("-") + sb.append(entry) + first = false + } + + val stringSelection = StringSelection(sb.toString()) + val clpbrd = Toolkit.getDefaultToolkit().systemClipboard + clpbrd.setContents(stringSelection, null) + + log.clear() + player.setAttribute("loc-log",log) + } + + define("rolltrawlerloot", Privilege.ADMIN, "::rolltrawlerloot ROLL COUNT", "Rolls some trawler loot."){player,args -> + val rolls = if(args.size < 2){ + 100 + } else { + args[1].toString().toInt() + } + TrawlerLoot.addLootAndMessage(player, player.skills.getLevel(Skills.FISHING), rolls, false) + } + + define("fillbank", Privilege.ADMIN, "", "Right as it says on the tin."){player,_ -> + for(i in 0 until ServerConstants.BANK_SIZE){ + player.bank.add(Item(i)) + } + } + + define("emptybank", Privilege.ADMIN, "", "Right as it says on the tin."){player,_ -> + player.bank.clear() + player.bank.update() + } + + define("setconfig", Privilege.ADMIN, "", "DEPRECATED: Use setvarp or setvarbit."){player,args -> + if(args.size < 3){ + reject(player,"Syntax: ::setconfig configID value") + } + val configID = args[1].toString().toInt() + val configValue = args[2].toString().toInt() + setVarp(player, configID, configValue) + } + + define("getobjectvarp"){player,args -> + if(args.size < 2){ + reject(player,"Syntax: ::getobjectvarp objectid") + } + val objectID = args[1].toInt() + notify(player, "${VarbitDefinition.forObjectID(SceneryDefinition.forId(objectID).varbitID).varpId}") + } + + define("define_varbit", Privilege.ADMIN, "::define_varbit VARBIT ID", "Prints information about the given varbit."){ player, args -> + if(args.size < 2) { + reject(player, "Syntax: ::define_varbit varbitId") + } + val varbitID = args[1].toInt() + notify(player, "${varbitID}: ${VarbitDefinition.forId(varbitID)}") + } + + + define("setvarbit", Privilege.ADMIN, "::setvarbit VARBIT ID VALUE", ""){ + player,args -> + if(args.size != 3){ + reject(player,"Usage: ::setvarbit varbit value") + } + val index = args[1].toIntOrNull() + val value = args[2].toIntOrNull() + + if(index == null || value == null){ + reject(player,"Usage ::setvarbit index offset value") + } + + setVarbit(player, index!!, value!!) + } + + define("setvarbits", Privilege.ADMIN, "::setvarbits FROM VARBIT ID TO VARBIT ID VALUE", ""){ + player,args -> + if(args.size != 4){ + reject(player,"Usage: ::setvarbits fromvarbit tovarbit value") + } + val fromIndex = args[1].toIntOrNull()!! + val toIndex = args[2].toIntOrNull()!! + val value = args[3].toIntOrNull()!! + + for (index in fromIndex..toIndex) { + setVarbit(player, index, value) + } + } + + define("getvarbit", Privilege.ADMIN, "::getvarbit VARBIT ID", "") { + player, args -> + if (args.size != 2) + reject(player, "Usage: ::getvarbit id") + val index = args[1].toIntOrNull() ?: return@define + notify(player, "Varbit $index: Currently ${getVarbit(player, index)}") + } + + define("setvarp", Privilege.ADMIN, "::setvarp VARP ID BIT OFFSET VALUE", "Sets the value starting at the BIT OFFSET of the varp."){ + player,args -> + if(args.size < 4){ + reject(player,"Usage: ::setvarp index offset value") + } + val index = args[1].toIntOrNull() + val offset = args[2].toIntOrNull() + val value = args[3].toIntOrNull() + + if(index == null || offset == null || value == null){ + reject(player,"Usage ::setvarp index offset value") + } + + setVarp(player, index!!, value!! shl offset!!) + } + + define("setvarc", Privilege.ADMIN, "::setvarc VARC ID VALUE") { player, args -> + if(args.size < 3){ + reject(player,"Usage: ::setvarc index value") + } + val index = args[1].toShortOrNull() + val value = args[2].toIntOrNull() + + if(index == null || value == null) { + reject(player,"Usage ::setvarc index value") + } + + player.packetDispatch.sendVarcUpdate(index!!, value!!) + } + + define("grow", Privilege.ADMIN, "", "Grows all planted crops by 1 stage."){ player, _ -> + val state = getOrStartTimer (player)!! + + for(patch in state.getPatches()){ + patch.nextGrowth = System.currentTimeMillis() - 1 + } + + state.run (player) + } + + define("finishbins", Privilege.ADMIN, "", "Finishes any in-progress compost bins."){ player, _ -> + val bins = getOrStartTimer(player).getBins() + for (bin in bins) { + if (!bin.isFinished && bin.isClosed) bin.finish() + } + } + + define("resetbins", Privilege.ADMIN, "", "Resets the player's compost bins to their initial states."){ player, _ -> + val bins = getOrStartTimer(player).getBins() + for (bin in bins) bin.reset() + } + + define("diseasecrops", Privilege.ADMIN, "", "Disease all crops"){ player, _ -> + val state = getOrStartTimer(player) + for (patch in state.getPatches()){ + patch.diseaseMod = -128 + patch.nextGrowth = System.currentTimeMillis() + 1 + } + state.run(player) + } + + define("addcredits", Privilege.ADMIN){ player, _ -> + player.details.credits += 100 + } + + define("getnpcparent"){player,args -> + if(args.size < 2){ + reject(player,"Usage: ::getnpcparent npcid") + } + + val npcid = args[1].toIntOrNull() ?: reject(player,"Invalid NPC ID.") + + GlobalScope.launch { + for(def in NPCDefinition.getDefinitions().values){ + def ?: continue + def.childNPCIds ?: continue + for(id in def.childNPCIds){ + if(id == npcid){ + notify(player,"Parent NPC: ${def.id}") + return@launch + } + } + } + notify(player,"No parent NPC found.") + } + } + define("infinitespecial", Privilege.ADMIN){ player, args -> + val usageStr = "Usage: ::infinitespecial true|false" + if(args.size < 2){ + reject(player, usageStr) + } + when(args[1]){ + "true" -> player.setAttribute("infinite-special", true) + "false" -> player.removeAttribute("infinite-special") + else -> reject(player, usageStr) + } + } + define("allowaggro", Privilege.ADMIN, "allowaggro true | false", "Toggle NPCs aggroing on you") { player, args -> + val usageStr = "Usage: ::allowaggro true | false" + if(args.size < 2) { + notify(player, "Allow admin aggression is currently ${player.getAttribute("/save:allow_admin_aggression", false)}") + return@define + } + when(args[1]) { + "true" -> player.setAttribute("/save:allow_admin_aggression", true) + "false" -> player.setAttribute("/save:allow_admin_aggression", false) + else -> reject(player, usageStr) + } + notify(player, "Setting aggro ${args[1]}") + } + + define("rules", Privilege.STANDARD, "", "Shows the rules."){ player, _ -> + RulesAndInfo.setBaseRulesAndInfo(player) + player.packetDispatch.sendInterfaceConfig(384, 17, true) + openInterface(player, 384) + } + + define("confirmrules", Privilege.STANDARD) { player, args -> + if(getAttribute(player,"rules:confirmed", false)) + reject(player, "You have already confirmed the rules.") + if(args.size < 2) + reject(player, "Usage: ::confirmrules PIN") + val pin = args[1].toIntOrNull() ?: (-1).also{ reject(player, "Please enter a valid number.") } + if(pin == getAttribute(player, "rules:pin", -1)) + { + player.setAttribute("/save:rules:confirmed", true) + player.interfaceManager.close() + sendDialogue(player, "Thank you!") + player.unlock() + player.removeAttribute("rules:pin") + if(ServerConstants.NEW_PLAYER_ANNOUNCEMENT) sendNews("A new player has joined. Welcome ${player.username}!") + } + else + { + sendDialogue(player, "Wrong pin. Try again.") + } + } + + define("setplayerstrong", Privilege.ADMIN, "setplayerstrong <0-4>", + "Set the player progress through the Stronghold of Player Safety test."){player, args -> + /* + * 0 = Not started + * 1 = Received test + * 2 = Completed test, needs to be marked + * 3 = Test marked + * 4 = Dungeon cleared + */ + if(args.size < 2){ + notify(player, "Player Stronghold progression currently: ${player.savedData.globalData.testStage}") + return@define + } + val stage = args[1].toIntOrNull() ?: (-1).also { reject(player, "Please enter a valid number") } + if (stage in 0 .. 4){ + player.savedData.globalData.testStage = stage + notify(player, "Setting test stage to $stage") + if (stage in 0..2){ + setVarp(player, 1203, 0, true) + notify(player, "The poster passage is now hidden") + } + else{ + setVarp(player, 1203, 1 shl 29, true) + notify(player, "The poster passage is now usable") + } + if (stage == 4){ + setVarbit(player, 4499, 1,true) + notify(player, "The loot has been taken already") + } + else { + setVarbit(player, 4499, 0, true) + notify(player, "The loot can be reacquired") + } + } + else{ + reject(player, "Only stages 0-4 are valid") + } + } + + define("setplaqueread", Privilege.ADMIN, "setplaqueread ", + "Set the plaques in the player safety stronghold to read or not read."){player, args -> + if (args.size == 1) { + notify( + player, + "Currently the plaques ${if (player.savedData.globalData.hasReadPlaques()) "have" else "have not"} been read" + ) + return@define + } + when(args[1]) { + "true" -> setPlaqueReadStatus(player, true) + "false" -> setPlaqueReadStatus(player, false) + else -> reject(player, "Only true or false can be used") + + } + notify(player, "Setting plaques read to: ${args[1]}") + + } + } + + fun setPlaqueReadStatus(player: Player, status: Boolean){ + // For some reason the loop has to be this way to have read write access + for (i in 0 until player.savedData.globalData.readPlaques.size){ + player.savedData.globalData.readPlaques[i] = status + } + + } + + fun showGeBotsearch(player: Player, searchTerm: String) + { + val offerAmounts = HashMap() + val offerPrice = HashMap() + + val offers = GrandExchange.getBotOffers().filter { getItemName(it.itemID).contains(searchTerm, true) || getItemName(it.itemID).equals(searchTerm, true) } + + for(offer in offers) + { + offerAmounts[offer.itemID] = offer.amount + offerPrice[offer.itemID] = offer.offeredValue + } + + val entries = offerAmounts.entries.sortedBy({ e -> getItemName(e.key) }) + val leftLines = ArrayList(entries.size) + val rightLines = ArrayList(entries.size) + for (entry in entries) { + leftLines.add("${getItemName(entry.key)} (x${entry.value})") + rightLines.add("Price: ${offerPrice[entry.key]}gp") + } + showGeBook(player, "Bot Stock - \"$searchTerm\"", leftLines, rightLines) + } + + fun showGeBots(player: Player) + { + val offerAmounts = HashMap() + val offerPrice = HashMap() + + val offers = GrandExchange.getBotOffers() + + for(offer in offers) + { + offerAmounts[offer.itemID] = offer.amount + offerPrice[offer.itemID] = offer.offeredValue + } + + val entries = offerAmounts.entries.sortedBy({ e -> getItemName(e.key) }) + val leftLines = ArrayList(entries.size) + val rightLines = ArrayList(entries.size) + for (entry in entries) { + leftLines.add("${getItemName(entry.key)} (x${entry.value})") + rightLines.add("Price: ${offerPrice[entry.key]}gp") + } + showGeBook(player, "Bot Stock", leftLines, rightLines) + } + + fun showGeSell(player: Player){ + val offerAmounts = HashMap() + val lowestPrice = HashMap() + + val offers = GrandExchange.getValidOffers() + + for(offer in offers) + { + if(!offer.sell) continue + var amount = offerAmounts[offer.itemID] ?: 0 + amount += offer.amountLeft + + var price = lowestPrice[offer.itemID] ?: Integer.MAX_VALUE + if(offer.offeredValue < price) price = offer.offeredValue + + offerAmounts[offer.itemID] = amount + lowestPrice[offer.itemID] = price + } + + val entries = offerAmounts.entries.sortedBy({ e -> getItemName(e.key) }) + val leftLines = ArrayList(entries.size) + val rightLines = ArrayList(entries.size) + for (entry in entries) { + leftLines.add("${getItemName(entry.key)} (x${entry.value})") + rightLines.add("Price: ${lowestPrice[entry.key]}gp") + } + showGeBook(player, "Active Sell Offers", leftLines, rightLines) + } + + fun showGeBuy(player: Player){ + val offerAmounts = HashMap() + val highestPrice = HashMap() + + val offers = GrandExchange.getValidOffers() + + for(offer in offers) + { + if(offer.sell) continue + var amount = offerAmounts[offer.itemID] ?: 0 + amount += offer.amountLeft + + var price = highestPrice[offer.itemID] ?: 0 + if(offer.offeredValue > price) price = offer.offeredValue + + offerAmounts[offer.itemID] = amount + highestPrice[offer.itemID] = price + } + + val entries = offerAmounts.entries.sortedBy({ e -> getItemName(e.key) }) + val leftLines = ArrayList(entries.size) + val rightLines = ArrayList(entries.size) + for (entry in entries) { + leftLines.add("${getItemName(entry.key)} (x${entry.value})") + rightLines.add("Highest: ${highestPrice[entry.key]}gp") + } + showGeBook(player, "Active Buy Offers", leftLines, rightLines) + } + + fun showOffers(player: Player, searchTerm: String){ + val offers = GrandExchange.getValidOffers().filter { getItemName(it.itemID).contains(searchTerm, true) || getItemName(it.itemID).equals(searchTerm, true) } + if (offers.isEmpty()) { + sendMessage(player, "No results.") + return + } + + val buyingAmount = HashMap() + val buyingHighest = HashMap() + val sellingAmount = HashMap() + val sellingLowest = HashMap() + for(offer in offers) + { + if(offer.sell) + { + var price = sellingLowest[offer.itemID] ?: Int.MAX_VALUE + if(offer.offeredValue < price) price = offer.offeredValue + + var amount = sellingAmount[offer.itemID] ?: 0 + amount += offer.amountLeft + + sellingAmount[offer.itemID] = amount + sellingLowest[offer.itemID] = price + } + else + { + var price = buyingHighest[offer.itemID] ?: 0 + if(offer.offeredValue > price) price = offer.offeredValue + + var amount = buyingAmount[offer.itemID] ?: 0 + amount += offer.amountLeft + + buyingAmount[offer.itemID] = amount + buyingHighest[offer.itemID] = price + } + } + + val numLines = offers.size + 1 + val leftLines = ArrayList(numLines) + val rightLines = ArrayList(numLines) + for (i in 0..numLines) { + if (i < buyingAmount.keys.size) { + val offer = buyingAmount.entries.elementAtOrNull(i) ?: continue + leftLines.add("[BUYING] ${getItemName(offer.key)} (x${offer.value})") + rightLines.add("Highest: ${buyingHighest[offer.key]}gp") + } else if (i == buyingAmount.keys.size) { + leftLines.add("") + rightLines.add("") + } else { + val offer = sellingAmount.entries.elementAtOrNull(i - buyingAmount.keys.size - 1) ?: continue + leftLines.add("[SELLING] ${getItemName(offer.key)} (x${offer.value})") + rightLines.add("Lowest: ${sellingLowest[offer.key]}gp") + } + } + showGeBook(player, "Results for \"$searchTerm\"", leftLines, rightLines) + } + + private fun showGeInputDialogue(player: Player, args: Array, op: (Player, String) -> (Unit)) { + if (args.size > 2) { + val target = args.copyOfRange(2, args.size).joinToString(" ").lowercase() + op(player, target) + } else { + sendInputDialogue(player, InputType.STRING_LONG, "Enter search term:",) { value -> + op(player, value as String) + } + } + } + + private fun showGeBook(player: Player, title: String, leftLines: ArrayList, rightLines: ArrayList) { + if (leftLines.size == 0) { + sendMessage(player, "No results.") + return + } + val lineIds = BookInterface.FANCY_BOOK_26_LINE_IDS + val contents = ArrayList() + val leftChunks = leftLines.chunked(15) + val rightChunks = rightLines.chunked(15) + for (i in leftChunks.indices) { + val size = leftChunks[i].size + val leftPageLines = ArrayList(size) + val rightPageLines = ArrayList(size) + for (j in leftChunks[i].indices) { + leftPageLines.add(BookLine(leftChunks[i][j], lineIds[j+3])) //+3 to skip title and buttons + rightPageLines.add(BookLine(rightChunks[i][j], lineIds[j+3+15])) //+15 because right pages have different ids + } + val leftPage = Page(*leftPageLines.toTypedArray()) + val rightPage = Page(*rightPageLines.toTypedArray()) + contents.add(PageSet(leftPage, rightPage)) + } + + closeInterface(player) + fun display(player: Player, pageNum: Int, buttonID: Int): Boolean { + BookInterface.pageSetup(player, BookInterface.FANCY_BOOK_26, title, contents.toTypedArray()) + return true + } + BookInterface.openBook(player, BookInterface.FANCY_BOOK_26, ::display) + } +} diff --git a/Server/src/main/core/game/system/command/sets/ModelViewerCommandSet.kt b/Server/src/main/core/game/system/command/sets/ModelViewerCommandSet.kt new file mode 100644 index 0000000..0d90743 --- /dev/null +++ b/Server/src/main/core/game/system/command/sets/ModelViewerCommandSet.kt @@ -0,0 +1,99 @@ +package core.game.system.command.sets + +import content.global.handlers.iface.BookInterface +import core.api.* +import core.game.node.entity.player.Player +import core.game.system.command.Privilege +import core.plugin.Initializable + +/** To view models in game. */ +@Initializable +class ModelViewerCommandSet : CommandSet(Privilege.ADMIN) { + companion object { + + const val DEF_BOOK = 10216 + const val TITLE = "Model Viewer" + const val ATTRIBUTE_MODEL_NUMBER = "modelNumber" + const val ATTRIBUTE_ZOOM = "modelZoom" + const val ATTRIBUTE_PITCH = "modelPitch" + const val ATTRIBUTE_YAW = "modelYaw" + + private fun display(player: Player, pageNum: Int, buttonID: Int) : Boolean { + BookInterface.clearBookLines(player, BookInterface.FANCY_BOOK_2_27, BookInterface.FANCY_BOOK_2_27_LINE_IDS) + BookInterface.clearButtons(player, BookInterface.FANCY_BOOK_2_27, BookInterface.FANCY_BOOK_2_27_BUTTON_IDS) + BookInterface.setTitle(player, BookInterface.FANCY_BOOK_2_27, BookInterface.FANCY_BOOK_2_27_LINE_IDS, TITLE) + + // Custom button interfaces for model book + // These are non-standard. No pages are "turned" here. + player.packetDispatch.sendInterfaceConfig(BookInterface.FANCY_BOOK_2_27, 114, false) + player.packetDispatch.sendInterfaceConfig(BookInterface.FANCY_BOOK_2_27, 116, false) + player.packetDispatch.sendInterfaceConfig(BookInterface.FANCY_BOOK_2_27, 118, false) + player.packetDispatch.sendInterfaceConfig(BookInterface.FANCY_BOOK_2_27, 122, false) + player.packetDispatch.sendInterfaceConfig(BookInterface.FANCY_BOOK_2_27, 124, false) + player.packetDispatch.sendInterfaceConfig(BookInterface.FANCY_BOOK_2_27, 126, false) + player.packetDispatch.sendInterfaceConfig(BookInterface.FANCY_BOOK_2_27, 128, false) + player.packetDispatch.sendInterfaceConfig(BookInterface.FANCY_BOOK_2_27, 144, false) + player.packetDispatch.sendInterfaceConfig(BookInterface.FANCY_BOOK_2_27, 146, false) + player.packetDispatch.sendInterfaceConfig(BookInterface.FANCY_BOOK_2_27, 148, false) + player.packetDispatch.sendInterfaceConfig(BookInterface.FANCY_BOOK_2_27, 152, false) + player.packetDispatch.sendInterfaceConfig(BookInterface.FANCY_BOOK_2_27, 154, false) + player.packetDispatch.sendInterfaceConfig(BookInterface.FANCY_BOOK_2_27, 156, false) + player.packetDispatch.sendInterfaceConfig(BookInterface.FANCY_BOOK_2_27, 158, false) + player.packetDispatch.sendString("-1 zoom" ,BookInterface.FANCY_BOOK_2_27, 114) + player.packetDispatch.sendString("-1 pitch" ,BookInterface.FANCY_BOOK_2_27, 116) + player.packetDispatch.sendString("-1 yaw" ,BookInterface.FANCY_BOOK_2_27, 118) + player.packetDispatch.sendString("-1" ,BookInterface.FANCY_BOOK_2_27, 122) + player.packetDispatch.sendString("-10" ,BookInterface.FANCY_BOOK_2_27, 124) + player.packetDispatch.sendString("-100" ,BookInterface.FANCY_BOOK_2_27, 126) + player.packetDispatch.sendString("-1000" ,BookInterface.FANCY_BOOK_2_27, 128) + player.packetDispatch.sendString("+1 zoom" ,BookInterface.FANCY_BOOK_2_27, 144) + player.packetDispatch.sendString("+1 pitch" ,BookInterface.FANCY_BOOK_2_27, 146) + player.packetDispatch.sendString("+1 yaw" ,BookInterface.FANCY_BOOK_2_27, 148) + player.packetDispatch.sendString("+1" ,BookInterface.FANCY_BOOK_2_27, 152) + player.packetDispatch.sendString("+10" ,BookInterface.FANCY_BOOK_2_27, 154) + player.packetDispatch.sendString("+100" ,BookInterface.FANCY_BOOK_2_27, 156) + player.packetDispatch.sendString("+1000" ,BookInterface.FANCY_BOOK_2_27, 158) + + // Attach buttons to setAttributes + when (buttonID) { + 114 -> setAttribute(player, ATTRIBUTE_ZOOM, getAttribute(player, ATTRIBUTE_ZOOM, 700) - 100) + 116 -> setAttribute(player, ATTRIBUTE_PITCH, getAttribute(player, ATTRIBUTE_PITCH, 0) - 100) + 118 -> setAttribute(player, ATTRIBUTE_YAW, getAttribute(player, ATTRIBUTE_YAW, 0) - 100) + 122 -> setAttribute(player, ATTRIBUTE_MODEL_NUMBER, getAttribute(player, ATTRIBUTE_MODEL_NUMBER, DEF_BOOK) - 1) + 124 -> setAttribute(player, ATTRIBUTE_MODEL_NUMBER, getAttribute(player, ATTRIBUTE_MODEL_NUMBER, DEF_BOOK) - 10) + 126 -> setAttribute(player, ATTRIBUTE_MODEL_NUMBER, getAttribute(player, ATTRIBUTE_MODEL_NUMBER, DEF_BOOK) - 100) + 128 -> setAttribute(player, ATTRIBUTE_MODEL_NUMBER, getAttribute(player, ATTRIBUTE_MODEL_NUMBER, DEF_BOOK) - 1000) + 144 -> setAttribute(player, ATTRIBUTE_ZOOM, getAttribute(player, ATTRIBUTE_ZOOM, 700) + 100) + 146 -> setAttribute(player, ATTRIBUTE_PITCH, getAttribute(player, ATTRIBUTE_PITCH, 0) + 100) + 148 -> setAttribute(player, ATTRIBUTE_YAW, getAttribute(player, ATTRIBUTE_YAW, 0) + 100) + 152 -> setAttribute(player, ATTRIBUTE_MODEL_NUMBER, getAttribute(player, ATTRIBUTE_MODEL_NUMBER, DEF_BOOK) + 1) + 154 -> setAttribute(player, ATTRIBUTE_MODEL_NUMBER, getAttribute(player, ATTRIBUTE_MODEL_NUMBER, DEF_BOOK) + 10) + 156 -> setAttribute(player, ATTRIBUTE_MODEL_NUMBER, getAttribute(player, ATTRIBUTE_MODEL_NUMBER, DEF_BOOK) + 100) + 158 -> setAttribute(player, ATTRIBUTE_MODEL_NUMBER, getAttribute(player, ATTRIBUTE_MODEL_NUMBER, DEF_BOOK) + 1000) + } + + // Display model number + player.packetDispatch.sendString("No: " + getAttribute(player, ATTRIBUTE_MODEL_NUMBER, DEF_BOOK) + " " + getAttribute(player, ATTRIBUTE_ZOOM, 700) + " " + getAttribute(player, ATTRIBUTE_PITCH, 0) + " " + getAttribute(player, ATTRIBUTE_YAW, 0),BookInterface.FANCY_BOOK_2_27, 38) + player.packetDispatch.sendString("No: " + (getAttribute(player, ATTRIBUTE_MODEL_NUMBER, DEF_BOOK) + 1),BookInterface.FANCY_BOOK_2_27, 53) + + // Display the models in the middle + BookInterface.setModelOnPage(player,0, getAttribute(player, ATTRIBUTE_MODEL_NUMBER, DEF_BOOK), BookInterface.FANCY_BOOK_2_27, BookInterface.FANCY_BOOK_2_27_IMAGE_ENABLE_DRAW_IDS[7], BookInterface.FANCY_BOOK_2_27_IMAGE_DRAW_IDS[7], getAttribute(player, ATTRIBUTE_ZOOM, 700), getAttribute(player, ATTRIBUTE_PITCH, 0), getAttribute(player, ATTRIBUTE_YAW, 0)) + BookInterface.setModelOnPage(player,0, getAttribute(player, ATTRIBUTE_MODEL_NUMBER, DEF_BOOK) + 1, BookInterface.FANCY_BOOK_2_27, BookInterface.FANCY_BOOK_2_27_IMAGE_ENABLE_DRAW_IDS[22], BookInterface.FANCY_BOOK_2_27_IMAGE_DRAW_IDS[22], getAttribute(player, ATTRIBUTE_ZOOM, 700), getAttribute(player, ATTRIBUTE_PITCH, 0), getAttribute(player, ATTRIBUTE_YAW, 0)) + + return true + } + } + override fun defineCommands() { + define("models"){ player, args -> + + // Bad number of args + if(args.size > 2){ + reject(player,"Usage: ::models") + return@define + } + + BookInterface.openBook(player, BookInterface.FANCY_BOOK_2_27, ::display) + return@define + } + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/system/command/sets/ModerationCommandSet.kt b/Server/src/main/core/game/system/command/sets/ModerationCommandSet.kt new file mode 100644 index 0000000..13d0d9e --- /dev/null +++ b/Server/src/main/core/game/system/command/sets/ModerationCommandSet.kt @@ -0,0 +1,333 @@ +package core.game.system.command.sets + +import core.api.sendMessage +import core.game.node.entity.player.Player +import core.game.node.entity.player.info.Rights +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.plugin.Initializable +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import core.ServerConstants +import core.ServerStore +import core.ServerStore.Companion.addToList +import core.auth.UserAccountInfo +import core.game.system.command.CommandMapping +import core.game.system.command.Privilege +import core.game.world.GameWorld +import core.game.world.repository.Repository +import java.io.File +import java.io.FileReader +import java.util.concurrent.TimeUnit +import kotlin.math.abs + +@Initializable +/** + * Moderation commands + * @author Ceikry + */ +class ModerationCommandSet : CommandSet(Privilege.MODERATOR){ + override fun defineCommands() { + val MAX_JAIL_TIME = 1800 //Max jail time (in seconds) + + + /** + * Kick a player + * ============================================================================================================= + */ + define("kick", Privilege.MODERATOR){ player, args -> + val playerToKick: Player? = Repository.getPlayerByName(args[1]) + if (playerToKick != null) { + playerToKick.clear() + notify(player, "Player ${playerToKick.username} was kicked.") + } else { + reject(player, "ERROR REMOVING PLAYER.") + } + } + /** + * ============================================================================================================= + */ + + /** + * Ban a player + * ============================================================================================================= + */ + define("ban", Privilege.ADMIN, "::ban USERNAME TIME", "Bans the user. Time format: INTd/s/m/h ex: 30d for 30 days."){ player, args -> + val name = args[1] + if(!GameWorld.accountStorage.checkUsernameTaken(name)) { + reject(player, "Invalid username: $name") + } + val playerToKick: Player? = Repository.getPlayerByName(name) + val durationString = args[2] + val durationTokens = durationString.toCharArray() + var intToken = "" + var durationMillis = 0L + var durationUnit: TimeUnit = TimeUnit.NANOSECONDS + for(token in durationTokens){ + if(token.toString().toIntOrNull() != null) intToken += token + else { + val durationInt: Int = (intToken.toIntOrNull() ?: -1).also { if(it == -1) reject(player, "Invalid duration: $intToken") } + durationUnit = when(token) { + 'd' -> TimeUnit.DAYS + 's' -> TimeUnit.SECONDS + 'm' -> TimeUnit.MINUTES + 'h' -> TimeUnit.HOURS + else -> TimeUnit.SECONDS + } + durationMillis = durationUnit.toMillis(durationInt.toLong()) + } + } + + playerToKick?.details?.accountInfo?.banEndTime = System.currentTimeMillis() + durationMillis + playerToKick?.clear() + GameWorld.Pulser.submit(object : Pulse(2) { + override fun pulse(): Boolean { + val info = GameWorld.accountStorage.getAccountInfo(name) + info.banEndTime = System.currentTimeMillis() + durationMillis + GameWorld.accountStorage.update(info) + return true + } + }) + + notify(player, "Banned user $name for $intToken ${durationUnit.name.toLowerCase()}.") + } + /** + * ============================================================================================================= + */ + + /** + * Ban all players on a given IP + * ============================================================================================================= + */ + define("ipban", Privilege.ADMIN, "::ipban IP TIME", "Bans all players on the given ip. Time format: INTd/s/m/h ex: 30d for 30 days."){ player, args -> + val ip = args[1] + val durationString = args[2] + val durationTokens = durationString.toCharArray() + var intToken = "" + var durationMillis = 0L + var durationUnit: TimeUnit = TimeUnit.NANOSECONDS + for(token in durationTokens){ + if(token.toString().toIntOrNull() != null) intToken += token + else { + val durationInt: Int = (intToken.toIntOrNull() ?: -1).also { if(it == -1) reject(player, "Invalid duration: $intToken") } + durationUnit = when(token) { + 'd' -> TimeUnit.DAYS + 's' -> TimeUnit.SECONDS + 'm' -> TimeUnit.MINUTES + 'h' -> TimeUnit.HOURS + else -> TimeUnit.SECONDS + } + durationMillis = durationUnit.toMillis(durationInt.toLong()) + } + } + + val playersToBan = GameWorld.accountStorage.getUsernamesWithIP(ip) + if (playersToBan.isEmpty()) { + reject(player, "No accounts found on IP $ip") + } + + for (p in playersToBan) { + val playerToKick = Repository.getPlayerByName(p) + playerToKick?.details?.accountInfo?.banEndTime = System.currentTimeMillis() + durationMillis + playerToKick?.clear() + GameWorld.Pulser.submit(object : Pulse(2) { + override fun pulse(): Boolean { + val info = GameWorld.accountStorage.getAccountInfo(p) + info.banEndTime = System.currentTimeMillis() + durationMillis + GameWorld.accountStorage.update(info) + return true + } + }) + } + + ServerStore.getArchive("flagged-ips").addToList("ips", ip) + + notify(player, "Banned all accounts on $ip for $intToken ${durationUnit.name.toLowerCase()}.") + } + /** + * ============================================================================================================= + */ + + /** + * Mute a player + * ============================================================================================================= + */ + define("mute", Privilege.MODERATOR, "::mute USERNAME TIME", "Mutes the user. Time format: INTd/s/m/h ex: 30d for 30 days."){ player, args -> + val name = args[1] + if(!GameWorld.accountStorage.checkUsernameTaken(name)) { + reject(player, "Invalid username: $name") + } + val playerToMute: Player? = Repository.getPlayerByName(name) + val durationString = args[2] + val durationTokens = durationString.toCharArray() + var intToken = "" + var durationMillis = 0L + var durationUnit: TimeUnit = TimeUnit.NANOSECONDS + for(token in durationTokens){ + if(token.toString().toIntOrNull() != null) intToken += token + else { + val durationInt: Int = (intToken.toIntOrNull() ?: -1).also { if(it == -1) reject(player, "Invalid duration: $intToken") } + durationUnit = when(token) { + 'd' -> TimeUnit.DAYS + 's' -> TimeUnit.SECONDS + 'm' -> TimeUnit.MINUTES + 'h' -> TimeUnit.HOURS + else -> TimeUnit.SECONDS + } + durationMillis = durationUnit.toMillis(durationInt.toLong()) + } + } + + playerToMute?.details?.accountInfo?.muteEndTime = System.currentTimeMillis() + durationMillis + if(playerToMute == null) { //Player was offline at the time + GameWorld.Pulser.submit(object : Pulse(2) { + override fun pulse(): Boolean { + val info = GameWorld.accountStorage.getAccountInfo(name) + info.muteEndTime = System.currentTimeMillis() + durationMillis + GameWorld.accountStorage.update(info) + return true + } + }) + } + + notify(player, "Muted user $name for $intToken ${durationUnit.name.toLowerCase()}.") + } + /** + * ============================================================================================================= + */ + + /** + * Jail a player + * ============================================================================================================= + */ + define("jail", Privilege.MODERATOR, "::jail SECONDS USERNAME", "Sends the player to the jail cells in Varrock."){player,args -> + if(args.size < 3) { + reject(player,"Usage: ::jail ") + } + + val timeSeconds = args[1].toIntOrNull() + if(timeSeconds == null){ + reject(player, " Must be a valid integer!") + } + if(timeSeconds!! > MAX_JAIL_TIME){ + reject(player, "Maximum jail time is $MAX_JAIL_TIME seconds.") + } + val name = args.slice(2 until args.size).joinToString("_") + val otherPlayer = Repository.getPlayerByName(name) + if(otherPlayer == null){ + reject(player, "Can not find $name in the player list!") + } + + if (otherPlayer?.rights == Rights.ADMINISTRATOR){ + reject(player, "You cannot jail $name, they are a god. Nice try though ${player.username}!") + } + + notify(player, "Jailing ${otherPlayer!!.username} for $timeSeconds seconds.") + notify(otherPlayer, "${player.username} has jailed you for $timeSeconds seconds.") + GameWorld.Pulser.submit(object : Pulse(3){ + val originalLoc = otherPlayer.location + val releaseTime = System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(timeSeconds.toLong()) + override fun pulse(): Boolean { + val done = System.currentTimeMillis() >= releaseTime + if(otherPlayer.location != Location.create(3228, 3407, 0)){ + otherPlayer.properties.teleportLocation = Location.create(3228, 3407, 0) + } + if(done){ + otherPlayer.properties.teleportLocation = originalLoc + } + return done + } + }) + } + /** + * ============================================================================================================= + */ + + define("modcr", Privilege.MODERATOR, "::modcr user_name amount", "Modifies user_name's credits by the given amount.") {player, args -> + val username = (args.getOrNull(1) ?: "").lowercase() + val amount = args.getOrNull(2)?.toIntOrNull() ?: Integer.MIN_VALUE + + if (username.isEmpty()) { + reject(player, "Usage: ::modcr user_name amount") + return@define + } + + if (amount == Integer.MIN_VALUE) { + reject(player, "Usage ::modcr user_name amount") + return@define + } + + val p = Repository.getPlayerByName(username) + val info: UserAccountInfo = if (p == null) + GameWorld.accountStorage.getAccountInfo(username) + else + p.details.accountInfo + + if (info.isDefault()) { + reject(player, "The user you specified ($username) does not exist.") + return@define + } + + info.credits += amount + if (p == null) + GameWorld.accountStorage.update(info) + else + sendMessage(p, "You have been ${if (amount > 0) "granted" else "penalized"} ${abs(amount)} credit(s).") + + notify(player, "Updated $username's credits to ${info.credits} by ${if (amount > 0) "adding" else "removing"} ${abs(amount)}.") + } + + define("csvmodcr", Privilege.ADMIN, "::csvmodcr filename", "Awards credits based on a csv list from a file. Relative to data dir.") {player, args -> + val filename = args.getOrNull(1) ?: "" + + if (filename.isEmpty()) { + reject(player, "Usage: ::csvmodcr filename") + return@define + } + + GlobalScope.launch { + val f = File(ServerConstants.DATA_PATH + File.separator + filename) + if (!f.exists()) { + notify(player, "Unable to locate file $filename.") + notify(player, "Note: The file must be in ${ServerConstants.DATA_PATH}") + return@launch + } + val lines: List + withContext(Dispatchers.IO) { + FileReader(f).use { + lines = f.readLines() + } + } + for (line in lines) { + if (line.startsWith("#")) continue + val tokens = line.split(",") + val username = tokens[0].lowercase().trim().replace(" ", "_") + val amount = tokens[1].trim() + CommandMapping.get("modcr")?.handle?.invoke(player, arrayOf("", username, amount)) + } + } + } + + define("getattribute", Privilege.ADMIN, "::getattribute username attribute", "Gets the value of an attribute for a player.") {player, args -> + val username = args.getOrNull(1) ?: "" + val attribute = args.getOrNull(2) ?: "" + if (username.isEmpty() || attribute.isEmpty()) { + reject(player, "Usage: ::getattribute username attribute") + return@define + } + val p = Repository.getPlayerByName(username) + if (p == null) { + reject(player, "Unable to find player $username.") + return@define + } + val value = p.getAttribute(attribute) + if (value == null) { + reject(player, "Unable to find attribute $attribute for player $username.") + return@define + } + notify(player, "Attribute $attribute for player $username is $value.") + } + } +} diff --git a/Server/src/main/core/game/system/command/sets/PlayerAttributeCommandSet.kt b/Server/src/main/core/game/system/command/sets/PlayerAttributeCommandSet.kt new file mode 100644 index 0000000..fa25eb4 --- /dev/null +++ b/Server/src/main/core/game/system/command/sets/PlayerAttributeCommandSet.kt @@ -0,0 +1,99 @@ +package core.game.system.command.sets + +import core.api.getAttribute +import core.api.setAttribute +import core.game.node.entity.player.Player +import core.game.system.command.Privilege +import core.game.world.repository.Repository +import core.plugin.Initializable + +/** + * In game setting of simple attributes. Not for complex objects or enums. + * @author ovenbread + */ +@Initializable +class PlayerAttributeCommandSet : CommandSet(Privilege.ADMIN) { + override fun defineCommands() { + + /** + * Gets the value of an attribute on a player. + */ + define("getattribute") { player, args -> + if (args.size < 2) { + reject(player, "Usage ::getattribute [playername] attributename") + } + var attributeName = "" + + // If stats is called without a username, return self. + var queryPlayer: Player? = null + if(args.size == 2){ + queryPlayer = player + attributeName = args[1] + } + // If stats is called with a username, find the player or set to null. + if(args.size == 3) { + queryPlayer = Repository.getPlayerByName(args[1]) + attributeName = args[2] + } + // If player is not found, return error. + if(queryPlayer == null){ + reject(player,"Invalid player or player not online.") + return@define + } + + notify(player,"Attribute: " + attributeName + " Value: " + getAttribute(queryPlayer!!, attributeName, "").toString()) + return@define + } + + /** + * Sets the value of an attribute on a player. + */ + define("setattribute") { player, args -> + if (args.size < 2) { + reject(player, "Usage ::setattribute [playername] attributename value") + } + var attributeName = "" + var value = "" + + // If stats is called without a username, return self. + var queryPlayer: Player? = null + if(args.size == 3){ + queryPlayer = player + attributeName = args[1] + value = args[2] + } + // If stats is called with a username, find the player or set to null. + if(args.size == 4) { + queryPlayer = Repository.getPlayerByName(args[1]) + attributeName = args[2] + value = args[3] + } + // If player is not found, return error. + if(queryPlayer == null){ + reject(player,"Invalid player or player not online.") + return@define + } + // Please be careful when editing attributes. + // If string input is an integer, convert to an integer and set it to the attribute. + if (value.toIntOrNull() != null){ + setAttribute(queryPlayer!!, attributeName, value.toIntOrNull()) + return@define + } + // If string input is a float(decimal number), convert to a float and set it to the attribute. + if (value.toFloatOrNull() != null){ + setAttribute(queryPlayer!!, attributeName, value.toFloatOrNull()) + return@define + } + // If string matches the text "true", set the attribute value to the boolean true. + if (value == "true"){ + setAttribute(queryPlayer!!, attributeName, true) + return@define + } + // If string matches the text "false", set the attribute value to the boolean false. + if (value == "false"){ + setAttribute(queryPlayer!!, attributeName, false) + return@define + } + } + } +} diff --git a/Server/src/main/core/game/system/command/sets/QuestCommandSet.kt b/Server/src/main/core/game/system/command/sets/QuestCommandSet.kt new file mode 100644 index 0000000..69ae5c1 --- /dev/null +++ b/Server/src/main/core/game/system/command/sets/QuestCommandSet.kt @@ -0,0 +1,113 @@ +package core.game.system.command.sets + +import core.game.component.Component +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.quest.QuestRepository +import core.plugin.Initializable +import core.game.system.command.Privilege +import core.game.world.repository.Repository + +@Initializable +class QuestCommandSet : CommandSet(Privilege.ADMIN){ + override fun defineCommands() { + /** + * Completes all quests + */ + define("allquest"){player,_-> + for (quest in QuestRepository.getQuests().values) { + quest.finish(player) + } + } + + /** + * Displays the currently implemented quests with debug information + */ + define("quest"){player,args -> + if (args.size < 3) { + val lookupP = if (args.size == 1) { + player + } else if (Repository.getPlayerByName(args[1]) != null) { + Repository.getPlayerByName(args[1]) ?: return@define + } else { + reject(player, "ERROR: Username not found. Usage: ::quest ") + return@define + } + sendQuestsDebug(player, lookupP) + } else { + reject(player, "Usage: ::quest || ::quest ") + } + } + + /** + * Sets stage of quest + */ + define("setqueststage"){player,args -> + if (args.size < 3) { + reject(player,"You must specify the index# of a quest, and a stage number") + } + val quest = args[1].toIntOrNull() ?: reject(player,"INVALID QUEST") + val stage = args[2].toIntOrNull() ?: reject(player,"INVALID STAGE") + val questObject = player.questRepository.forIndex(quest as Int) + if (questObject == null){ + reject(player, "$quest did not match anything in the quest repository") + } + else{ + player.questRepository.setStageNonmonotonic(questObject, stage as Int) + if (stage == 0) { + questObject.reset(player) + } + questObject.updateVarps(player) + notify(player, "Setting " + questObject.quest + " to stage $stage") + } + } + + /** + * Displays the currently implemented quests + */ + define("quests", Privilege.STANDARD){ player, _ -> + sendQuests(player) + } + } + + /** + * Sends the list of quests. + * @param player the player. + */ + private fun sendQuests(player: Player?) { + player!!.interfaceManager.open(Component(275)) + for (i in 0..310) { + player.packetDispatch.sendString("", 275, i) + } + var lineId = 11 + player.packetDispatch.sendString("" + "Available Quests" + "", 275, 2) + for (q in QuestRepository.getQuests().toSortedMap().values) { + // Add a space to beginning and end of string for the strikethrough + player.packetDispatch.sendString("" + (if (q.isCompleted(player)) " " else "") + q.quest + " ", 275, lineId++) + } + } + + /** + * Sends the list of quests with debug information + * @param admin the player. + */ + private fun sendQuestsDebug(admin: Player?, lookupUser: Player?) { + admin!!.interfaceManager.open(Component(275)) + for (i in 0..310) { + admin.packetDispatch.sendString("", 275, i) + } + var lineId = 11 + admin.packetDispatch.sendString("${lookupUser!!.username}'s Quest Debug", 275, 2) + for (q in QuestRepository.getQuests().values) { + // Add a space to beginning and end of string for the strikethrough + val stage = lookupUser.questRepository.getStage(q) + val statusColor = when { + stage >= 100 -> "80ff00" + stage in 1..99 -> "ff8400" + else -> "ff0000" + } + admin.packetDispatch.sendString("${q.quest}", 275, lineId++) + admin.packetDispatch.sendString("Index: ${q.index} | Stage: ${lookupUser.questRepository.getStage(q)}", 275, lineId++) + admin.packetDispatch.sendString(" ", 275, lineId++) + } + } +} diff --git a/Server/src/main/core/game/system/command/sets/SlayerCommandSet.kt b/Server/src/main/core/game/system/command/sets/SlayerCommandSet.kt new file mode 100644 index 0000000..9be1e06 --- /dev/null +++ b/Server/src/main/core/game/system/command/sets/SlayerCommandSet.kt @@ -0,0 +1,58 @@ +package core.game.system.command.sets + +import content.global.skill.slayer.Master +import content.global.skill.slayer.SlayerManager +import content.global.skill.slayer.SlayerUtils +import content.global.skill.slayer.Tasks +import core.game.node.entity.npc.NPC +import core.game.system.command.Privilege +import core.plugin.Initializable +import core.api.* + +@Initializable +class SlayerCommandSet : CommandSet(Privilege.ADMIN){ + override fun defineCommands() { + /** + * Finishes a player's slayer task (the correct way) + */ + define("finishtask"){player,_ -> + notify(player, "Kill the npc that spawned to finish your task.") + SlayerManager.getInstance(player).amount = 1 + val finisher = NPC(SlayerManager.getInstance(player).task?.npcs?.get(0) ?: 0, player.location) + finisher.isRespawn = false + finisher.init() + } + + /** + * Set slayer points + */ + define("setslayerpoints"){player,args -> + if(args.size < 2){ + reject(player,"Usage: ::setslayerpoints amount") + } + + val amount = args[1].toIntOrNull() + if(amount == null){ + reject(player,"Amount needs to be a valid integer!") + } + + SlayerManager.getInstance(player).slayerPoints = amount!! + notify(player, "Set slayer points to $amount.") + } + + define("setslayertask", Privilege.ADMIN, "::setslayertask npc id [amount]", "Set the slayer task to npc. Amount optional.") { player, args -> + if (args.size < 2) reject(player, "Usage: ::setslayertask npc id [amount]") + + val npc = (args[1].toIntOrNull() ?: reject(player, "Must enter valid npc id")) as Int + val task = (Tasks.forId(npc) ?: reject(player, "Must enter valid npc id")) as Tasks + val masterTask = Master.Task(task, 1) + val amount = args.getOrNull(2)?.toIntOrNull() + ?.let { if (it !in 1..255) reject(player, "Amount must be an integer: 1-255.") else it } as Int? + + val slayer = SlayerManager.getInstance(player) + if (slayer.hasTask()) slayer.task = task else SlayerUtils.assign(player, masterTask, Master.values().random()) + if (amount != null) slayer.amount = amount + setVarp(player, 2502, slayer.flags.taskFlags shr 4) + } + } +} diff --git a/Server/src/main/core/game/system/command/sets/SpawnCommandSet.kt b/Server/src/main/core/game/system/command/sets/SpawnCommandSet.kt new file mode 100644 index 0000000..331ecdb --- /dev/null +++ b/Server/src/main/core/game/system/command/sets/SpawnCommandSet.kt @@ -0,0 +1,119 @@ +package core.game.system.command.sets + +import core.api.log +import core.api.sendMessage +import core.cache.Cache +import core.game.node.scenery.Scenery +import core.game.node.scenery.SceneryBuilder +import core.game.node.entity.npc.NPC +import core.game.node.item.Item +import core.game.system.command.CommandPlugin +import core.plugin.Initializable +import core.game.system.command.Privilege +import core.tools.Log +import java.awt.Toolkit +import java.awt.datatransfer.StringSelection + +@Initializable +class SpawnCommandSet : CommandSet(Privilege.ADMIN){ + override fun defineCommands() { + /** + * Spawns an npc with the given ID + */ + define("npc"){player,args -> + if (args.size < 2) { + reject(player, "syntax: id (required) amount (optional) isWalks (optional)") + return@define + } + val amount = if (args.size > 2) CommandPlugin.toInteger(args[2]) else 1 + if (amount < 1) { + reject(player, "Invalid amount") + return@define + } + if (amount > 900) { + reject(player, "Based on experience, spawning that many NPCs at once is a bad idea") + return@define + } + var isWalks = false + if (args.size > 3) { + if (args[3] == "true") { + isWalks = true + } else if (args[3] != "" && args[3] != "false") { + reject(player, "The \"isWalks\" argument only accepts \"true\" and \"false\"") + return@define + } + } + var npcString = "" + for (i in 1..amount) { + val npc = NPC.create(CommandPlugin.toInteger(args[1]), player.location) + npc.setAttribute("spawned:npc", true) + npc.isRespawn = false + npc.direction = player.direction + npc.init() + npc.isWalks = isWalks + npcString = "{" + npc.location.x + "," + npc.location.y + "," + npc.location.z + "," + (if (npc.isWalks) "1" else "0") + "," + npc.direction.ordinal + "}" + println(npcString) + } + val clpbrd = Toolkit.getDefaultToolkit().systemClipboard + clpbrd.setContents(StringSelection(npcString), null) + } + + /** + * Spawns an item with the given ID + */ + define("item"){player,args -> + if (args.size < 2) { + reject(player,"You must specify an item ID") + return@define + } + val id = args[1].toIntOrNull() ?: return@define + var amount = (args.getOrNull(2) ?: "1").toInt() + if (id > Cache.getItemDefinitionsSize()) { + reject(player,"Item ID '$id' out of range.") + return@define + } + val item = Item(id, amount) + val max = player.inventory.getMaximumAdd(item) + if (amount > max) { + amount = max + } + item.setAmount(amount) + player.inventory.add(item) + } + + /** + * Spawn object with given ID at the player's location + */ + define("object"){player,args -> + if (args!!.size < 2) { + reject(player,"syntax error: id (optional) type rotation or rotation") + return@define + } + val `object` = if (args.size > 3) Scenery(CommandPlugin.toInteger(args[1]!!), player!!.location, CommandPlugin.toInteger(args[2]!!), CommandPlugin.toInteger(args[3]!!)) else if (args.size == 3) Scenery(CommandPlugin.toInteger(args[1]!!), player!!.location, CommandPlugin.toInteger(args[2]!!)) else Scenery(CommandPlugin.toInteger(args[1]!!), player!!.location) + SceneryBuilder.add(`object`) + log(this::class.java, Log.FINE, "object = $`object`") + } + + define("objectgrid") { player, args -> + if(args!!.size != 5) { + reject(player, "Usage: objectgrid beginId endId type rotation") + return@define + } + val beginId = args[1].toIntOrNull() ?: return@define + val endId = args[2].toIntOrNull() ?: return@define + val type = args[3].toIntOrNull() ?: return@define + val rotation = args[4].toIntOrNull() ?: return@define + for(i in 0..10) { + SceneryBuilder.add(Scenery(29447 + i, player.location.transform(i, -1, 0))) + } + for(i in beginId..endId) { + val j = i - beginId + val scenery = Scenery(i, player.location.transform(j % 10, j / 10, 0), type, rotation) + SceneryBuilder.add(scenery) + if(j % 10 == 0) { + SceneryBuilder.add(Scenery(29447 + (j / 10) % 10, player.location.transform(-1, j/10, 0))) + } + } + } + } +} diff --git a/Server/src/main/core/game/system/command/sets/StatAttributeKeys.kt b/Server/src/main/core/game/system/command/sets/StatAttributeKeys.kt new file mode 100644 index 0000000..431cb84 --- /dev/null +++ b/Server/src/main/core/game/system/command/sets/StatAttributeKeys.kt @@ -0,0 +1,17 @@ +package core.game.system.command.sets + +const val STATS_BASE = "stats_manager" +const val STATS_ENEMIES_KILLED = "enemies_killed" +const val STATS_DEATHS = "deaths" +const val STATS_LOGS = "logs_chopped" +const val STATS_FISH = "fish_caught" +const val STATS_ROCKS = "rocks_mined" +const val STATS_RC = "essence_crafted" +const val STATS_FOOD_COOKED = "food_cooked" +const val STATS_CATS_RAISED = "cats_raised" +const val STATS_PK_KILLS = "player_kills" +const val STATS_PK_DEATHS = "player_deaths" +const val STATS_ALKHARID_GATE = "alkharid_gate" +const val FISHING_TRAWLER_GAMES_WON = "fishing-trawler-games" +const val FISHING_TRAWLER_LEAKS_PATCHED = "fishing-trawler-leaks-patched" +const val FISHING_TRAWLER_SHIPS_SANK = "fishing-trawler-sank" diff --git a/Server/src/main/core/game/system/command/sets/StatsCommandSet.kt b/Server/src/main/core/game/system/command/sets/StatsCommandSet.kt new file mode 100644 index 0000000..b9b6e32 --- /dev/null +++ b/Server/src/main/core/game/system/command/sets/StatsCommandSet.kt @@ -0,0 +1,198 @@ +package core.game.system.command.sets + +import content.data.BossKillCounter +import content.global.activity.ttrail.TreasureTrailManager +import content.global.handlers.iface.BookInterface +import content.global.handlers.iface.Page +import content.global.handlers.iface.PageSet +import content.global.skill.slayer.SlayerManager +import core.api.setAttribute +import core.game.node.entity.player.Player +import core.plugin.Initializable +import org.rs09.consts.Items +import org.rs09.consts.NPCs +import core.api.utils.PlayerStatsCounter +import core.game.system.command.Privilege +import core.game.world.repository.Repository +import java.util.* + +val TUROTH_IDS = intArrayOf(NPCs.TUROTH_1622, NPCs.TUROTH_1623, NPCs.TUROTH_1626, NPCs.TUROTH_1627, NPCs.TUROTH_1628, NPCs.TUROTH_1629, NPCs.TUROTH_1630) +val KURASK_IDS = intArrayOf(NPCs.KURASK_1608, NPCs.KURASK_1609, NPCs.KURASK_4229, NPCs.KURASK_7811) +val GARGOYLE_IDS = intArrayOf(NPCs.GARGOYLE_1610, NPCs.GARGOYLE_1827, NPCs.GARGOYLE_6389) +val SPIRITUAL_MAGE_IDS = intArrayOf(NPCs.SPIRITUAL_MAGE_6221, NPCs.SPIRITUAL_MAGE_6231, NPCs.SPIRITUAL_MAGE_6257, NPCs.SPIRITUAL_MAGE_6278) +val GREEN_DRAGON_IDS = intArrayOf(NPCs.GREEN_DRAGON_941, NPCs.GREEN_DRAGON_4677, NPCs.GREEN_DRAGON_4678, NPCs.GREEN_DRAGON_4679, NPCs.GREEN_DRAGON_4680, NPCs.BRUTAL_GREEN_DRAGON_5362) +val BLUE_DRAGON_IDS = intArrayOf(NPCs.BLUE_DRAGON_55, NPCs.BLUE_DRAGON_4681, NPCs.BLUE_DRAGON_4682, NPCs.BLUE_DRAGON_4683, NPCs.BLUE_DRAGON_4684, NPCs.BLUE_DRAGON_5178) +val RED_DRAGON_IDS = intArrayOf(NPCs.RED_DRAGON_53, NPCs.RED_DRAGON_4669, NPCs.RED_DRAGON_4670, NPCs.RED_DRAGON_4671, NPCs.RED_DRAGON_4672) +val BLACK_DRAGON_IDS = intArrayOf(NPCs.BLACK_DRAGON_54, NPCs.BLACK_DRAGON_4673, NPCs.BLACK_DRAGON_4674, NPCs.BLACK_DRAGON_4675, NPCs.BLACK_DRAGON_4676) +val BRONZE_DRAGON_IDS = intArrayOf(NPCs.BRONZE_DRAGON_1590) +val IRON_DRAGON_IDS = intArrayOf(NPCs.IRON_DRAGON_1591) +val STEEL_DRAGON_IDS = intArrayOf(NPCs.STEEL_DRAGON_1592, NPCs.STEEL_DRAGON_3590) +val MITHRIL_DRAGON_IDS = intArrayOf(NPCs.MITHRIL_DRAGON_5363, NPCs.MITHRIL_DRAGON_8424) +val SKELETAL_WYVERN_IDS = intArrayOf(NPCs.SKELETAL_WYVERN_3068, NPCs.SKELETAL_WYVERN_3069, NPCs.SKELETAL_WYVERN_3070, NPCs.SKELETAL_WYVERN_3071) + +val SPACER = " " +val FAKE_CONTENT = arrayOf( + PageSet(Page(), Page()), + PageSet(Page(), Page()), + PageSet(Page(), Page()), +) + +@Initializable +class StatsCommandSet : CommandSet(Privilege.STANDARD) { + companion object { + private fun display(player: Player, pageNum: Int, buttonId: Int) : Boolean { + val queryPlayer: Player? = player.getAttribute("stats-command-query-player", null) + if (queryPlayer == null) { + return false + } + val globalData = queryPlayer.globalData + + BookInterface.pageSetup(player, BookInterface.FANCY_BOOK_26,queryPlayer.username + "'s Stats", FAKE_CONTENT) + + for(i in (68..97)) { + when(pageNum) { + 0 -> { + when(i) { + //Various stats + 97 -> sendLine(player,"Easy Clues: ${TreasureTrailManager.getInstance(queryPlayer).completedClues[0]}",i) + 68 -> sendLine(player,"Medium Clues: ${TreasureTrailManager.getInstance(queryPlayer).completedClues[1]}",i) + 69 -> sendLine(player,"Hard Clues: ${TreasureTrailManager.getInstance(queryPlayer).completedClues[2]}",i) + 70 -> sendLine(player, SPACER,i) + 71 -> sendLine(player,"Slayer Tasks: ${SlayerManager.getInstance(queryPlayer).flags.completedTasks}",i) + 72 -> sendLine(player,"Quest Points: ${queryPlayer.questRepository.points}",i) + 73 -> sendLine(player,"Ironman Mode: ${queryPlayer.ironmanManager.mode.name.lowercase(Locale.getDefault())}",i) + 74 -> sendLine(player,"Deaths: ${queryPlayer.getAttribute("$STATS_BASE:$STATS_DEATHS",0)}",i) + 75 -> sendLine(player, SPACER,i) + 76 -> sendLine(player,"Logs Chopped: ${queryPlayer.getAttribute("$STATS_BASE:$STATS_LOGS",0)}",i) + 77 -> sendLine(player,"Rocks Mined: ${queryPlayer.getAttribute("$STATS_BASE:$STATS_ROCKS",0)}",i) + 78 -> sendLine(player,"Fish Caught: ${queryPlayer.getAttribute("$STATS_BASE:$STATS_FISH",0)}",i) + 79 -> sendLine(player, "Essence Crafted: ${queryPlayer.getAttribute("$STATS_BASE:$STATS_RC",0)}", i) + 80 -> sendLine(player, "Food Cooked: ${queryPlayer.getAttribute("$STATS_BASE:$STATS_FOOD_COOKED",0)}", i) + 81 -> sendLine(player, "Cats Raised: ${queryPlayer.getAttribute("$STATS_BASE:$STATS_CATS_RAISED",0)}", i) + + //Boss KC + 82 -> sendLine(player, "KBD KC: ${globalData.bossCounters.get(BossKillCounter.KING_BLACK_DRAGON.ordinal)}",i) + 83 -> sendLine(player, "TDs KC: ${globalData.bossCounters.get(BossKillCounter.TORMENTED_DEMONS.ordinal)}",i) + 84 -> sendLine(player, "Supreme KC: ${globalData.bossCounters.get(BossKillCounter.DAGANNOTH_SUPREME.ordinal)}",i) + 85 -> sendLine(player, "Rex KC: ${globalData.bossCounters.get(BossKillCounter.DAGANNOTH_REX.ordinal)}",i) + 86 -> sendLine(player, "Prime KC: ${globalData.bossCounters.get(BossKillCounter.DAGANNOTH_PRIME.ordinal)}",i) + 87 -> sendLine(player, "Barrows KC: ${globalData.barrowsLoots}",i) + 88 -> sendLine(player, "Chaos Ele: ${globalData.bossCounters.get(BossKillCounter.CHAOS_ELEMENTAL.ordinal)}",i) + 89 -> sendLine(player, "Mole KC: ${globalData.bossCounters.get(BossKillCounter.GIANT_MOLE.ordinal)}",i) + 90 -> sendLine(player, "Sara KC: ${globalData.bossCounters.get(BossKillCounter.SARADOMIN.ordinal)}",i) + 91 -> sendLine(player, "Zammy KC: ${globalData.bossCounters.get(BossKillCounter.ZAMORAK.ordinal)}",i) + 92 -> sendLine(player, "Bandos KC: ${globalData.bossCounters.get(BossKillCounter.BANDOS.ordinal)}",i) + 93 -> sendLine(player, "Arma KC: ${globalData.bossCounters.get(BossKillCounter.ARMADYL.ordinal)}",i) + 94 -> sendLine(player, "Jad KC: ${globalData.bossCounters.get(BossKillCounter.JAD.ordinal)}",i) + 95 -> sendLine(player, "KQ KC: ${globalData.bossCounters.get(BossKillCounter.KALPHITE_QUEEN.ordinal)}",i) + 96 -> sendLine(player, "Corp KC: ${globalData.bossCounters.get(BossKillCounter.CORPOREAL_BEAST.ordinal)}",i) + else -> sendLine(player,"",i) + } + } + 1 -> { + when(i) { + 97 -> sendLine(player, "Turoths: ${PlayerStatsCounter.getKills(queryPlayer, TUROTH_IDS)}", i) + 68 -> sendLine(player, "Kurasks: ${PlayerStatsCounter.getKills(queryPlayer, KURASK_IDS)}", i) + 69 -> sendLine(player, "Leaf-bladed swords: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.LEAF_BLADED_SWORD_13290)}", i) + 70 -> sendLine(player, SPACER,i) + 71 -> sendLine(player, "Gargoyles: ${PlayerStatsCounter.getKills(queryPlayer, GARGOYLE_IDS)}", i) + 72 -> sendLine(player, "Granite mauls: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.GRANITE_MAUL_4153)}", i) + 73 -> sendLine(player, SPACER,i) + 74 -> sendLine(player, "Spiritual mages: ${PlayerStatsCounter.getKills(queryPlayer, SPIRITUAL_MAGE_IDS)}", i) + 75 -> sendLine(player, "Dragon boots: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.DRAGON_BOOTS_11732)}", i) + 76 -> sendLine(player, SPACER,i) + 77 -> sendLine(player, "Abyssal demons: ${PlayerStatsCounter.getKills(queryPlayer, intArrayOf(NPCs.ABYSSAL_DEMON_1615))}", i) + 78 -> sendLine(player, "Abyssal whips: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.ABYSSAL_WHIP_4151)}", i) + 79 -> sendLine(player, SPACER,i) + 80 -> sendLine(player, "Dark beasts: ${PlayerStatsCounter.getKills(queryPlayer, intArrayOf(NPCs.DARK_BEAST_2783))}", i) + 81 -> sendLine(player, "Dark bows: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.DARK_BOW_11235)}", i) + + 82 -> sendLine(player, "Green Dragons: ${PlayerStatsCounter.getKills(queryPlayer, GREEN_DRAGON_IDS)}", i) + 83 -> sendLine(player, "Blue Dragons: ${PlayerStatsCounter.getKills(queryPlayer, BLUE_DRAGON_IDS)}", i) + 84 -> sendLine(player, "Red Dragons: ${PlayerStatsCounter.getKills(queryPlayer, RED_DRAGON_IDS)}", i) + 85 -> sendLine(player, "Black Dragons: ${PlayerStatsCounter.getKills(queryPlayer, BLACK_DRAGON_IDS)}", i) + 86 -> sendLine(player, SPACER,i) + 87 -> sendLine(player, "Bronze Dragons: ${PlayerStatsCounter.getKills(queryPlayer, BRONZE_DRAGON_IDS)}", i) + 88 -> sendLine(player, "Iron Dragons: ${PlayerStatsCounter.getKills(queryPlayer, IRON_DRAGON_IDS)}", i) + 89 -> sendLine(player, "Steel Dragons: ${PlayerStatsCounter.getKills(queryPlayer, STEEL_DRAGON_IDS)}", i) + 90 -> sendLine(player, "Mithril Dragons: ${PlayerStatsCounter.getKills(queryPlayer, MITHRIL_DRAGON_IDS)}", i) + 91 -> sendLine(player, "Skeletal Wyverns: ${PlayerStatsCounter.getKills(queryPlayer, SKELETAL_WYVERN_IDS)}", i) + 92 -> sendLine(player, SPACER,i) + 93 -> sendLine(player, "Draconic visages: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.DRACONIC_VISAGE_11286)}", i) + + else -> sendLine(player,"",i) + } + } + 2 -> { + when(i) { + 97 -> sendLine(player, "Ahrim's hood: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.AHRIMS_HOOD_4708)}", i) + 68 -> sendLine(player, "Ahrim's staff: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.AHRIMS_STAFF_4710)}", i) + 69 -> sendLine(player, "Ahrim's robetop: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.AHRIMS_ROBETOP_4712)}", i) + 70 -> sendLine(player, "Ahrim's robeskirt: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.AHRIMS_ROBESKIRT_4714)}", i) + 71 -> sendLine(player, SPACER,i) + 72 -> sendLine(player, "Dharok's helm: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.DHAROKS_HELM_4716)}", i) + 73 -> sendLine(player, "Dharok's greataxe: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.DHAROKS_GREATAXE_4718)}", i) + 74 -> sendLine(player, "Dharok's platebody: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.DHAROKS_PLATEBODY_4720)}", i) + 75 -> sendLine(player, "Dharok's platelegs: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.DHAROKS_PLATELEGS_4722)}", i) + 76 -> sendLine(player, SPACER,i) + 77 -> sendLine(player, "Guthan's helm: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.GUTHANS_HELM_4724)}", i) + 78 -> sendLine(player, "Guthan's warspear: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.GUTHANS_WARSPEAR_4726)}", i) + 79 -> sendLine(player, "Guthan's platebody: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.GUTHANS_PLATEBODY_4728)}", i) + 80 -> sendLine(player, "Guthan's chainskirt: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.GUTHANS_CHAINSKIRT_4730)}", i) + + 82 -> sendLine(player, "Karil's coif: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.KARILS_COIF_4732)}", i) + 83 -> sendLine(player, "Karil's crossbow: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.KARILS_CROSSBOW_4734)}", i) + 84 -> sendLine(player, "Karil's leathertop: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.KARILS_LEATHERTOP_4736)}", i) + 85 -> sendLine(player, "Karil's leatherskirt: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.KARILS_LEATHERSKIRT_4738)}", i) + 86 -> sendLine(player, SPACER,i) + 87 -> sendLine(player, "Torag's helm: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.TORAGS_HELM_4745)}", i) + 88 -> sendLine(player, "Torag's hammers: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.TORAGS_HAMMERS_4747)}", i) + 89 -> sendLine(player, "Torag's platebody: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.TORAGS_PLATEBODY_4749)}", i) + 90 -> sendLine(player, "Torag's platelegs: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.TORAGS_PLATELEGS_4751)}", i) + 91 -> sendLine(player, SPACER,i) + 92 -> sendLine(player, "Verac's helm: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.VERACS_HELM_4753)}", i) + 93 -> sendLine(player, "Verac's flail: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.VERACS_FLAIL_4755)}", i) + 94 -> sendLine(player, "Verac's brassard: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.VERACS_BRASSARD_4757)}", i) + 95 -> sendLine(player, "Verac's plateskirt: ${PlayerStatsCounter.getRareDrops(queryPlayer, Items.VERACS_PLATESKIRT_4759)}", i) + else -> sendLine(player,"",i) + } + } + } + } + return true + } + fun sendLine(player: Player, line: String, child: Int) { + player.packetDispatch.sendString(line ,BookInterface.FANCY_BOOK_26, child) + } + + } + override fun defineCommands() { + define("stats"){ player, args -> + + // Bad number of args + if(args.size > 2){ + reject(player,"Usage: ::stats playername") + return@define + } + + // If stats is called without a username, return self. + var queryPlayer: Player? = null + if(args.size == 1){ + queryPlayer = player + } + // If stats is called with a username, find the player or set to null. + if(args.size == 2) { + queryPlayer = Repository.getPlayerByName(args[1]) + } + // If main player is not found, return error. + if(queryPlayer == null){ + reject(player,"Invalid player or player not online.") + return@define + } + + setAttribute(player, "stats-command-query-player", queryPlayer) + BookInterface.openBook(player, BookInterface.FANCY_BOOK_26, ::display) + return@define + } + } +} diff --git a/Server/src/main/core/game/system/command/sets/SystemCommandSet.kt b/Server/src/main/core/game/system/command/sets/SystemCommandSet.kt new file mode 100644 index 0000000..2581bb4 --- /dev/null +++ b/Server/src/main/core/game/system/command/sets/SystemCommandSet.kt @@ -0,0 +1,308 @@ +package core.game.system.command.sets + +import content.data.ChargedItem +import core.api.* +import core.cache.def.impl.ItemDefinition +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.system.SystemManager +import core.game.system.SystemState +import core.game.system.command.Privilege +import core.game.world.GameWorld +import core.game.world.repository.Repository +import core.plugin.Initializable +import org.rs09.consts.Items +import kotlin.system.exitProcess + +@Initializable +class SystemCommandSet : CommandSet(Privilege.ADMIN) { + override fun defineCommands() { + /** + * Start an update countdown + */ + define("update") { player, args -> + if (args.size > 1) { + SystemManager.getUpdater().setCountdown(args[1].toInt()) + } + SystemManager.flag(SystemState.UPDATING) + } + + /** + * Cancel an update countdown + */ + define("cancelupdate") { player, _ -> + SystemManager.getUpdater().cancel() + } + + + /** + * Allows a player to reset their password + */ + define("resetpassword", Privilege.STANDARD, "", "WARNING: Case insensitive due to dialogue limitations.") { player, args -> + sendInputDialogue(player, InputType.STRING_SHORT, "Enter Current Password:"){value -> + val pass = value.toString() + runTask(player) { + if (GameWorld.authenticator.checkPassword(player, pass)) { + sendInputDialogue(player, InputType.STRING_SHORT, "Enter New Password:") { value2 -> + val newPass = value2.toString() + if (pass == newPass) { + sendDialogue(player, "Failed: Passwords Match") + } else if (newPass.length !in 5..20) { + sendDialogue(player, "Failed: Password Too Long Or Too Short") + } else if (newPass == player.details.accountInfo.username) { + sendDialogue(player, "Failed: Password Is Username") + } else { + GameWorld.authenticator.updatePassword(player.details.accountInfo.username, newPass) + sendDialogue(player, "Success: Password Updated!") + } + } + } else { + sendDialogue(player, "Fail: Wrong Password.") + } + } + } + } + + /** + * Allows an Administrator to reset a password + */ + define("setpasswordother", Privilege.ADMIN, "::resetpasswordother USERNAME NEW", "Gives the username password NEW.") { player, args -> + if (args.size != 3) { + reject(player, "Usage: ::resetpasswordother user new", "WARNING: THIS IS PERMANENT.", "WARNING: PASSWORD CAN NOT CONTAIN SPACES.") + } + val otherUser = args[1] + val newPass = args[2] + + if (GameWorld.accountStorage.checkUsernameTaken(otherUser)) { + + if (newPass.length < 5 || newPass.length > 20) { + reject(player, "NEW PASSWORD MUST BE BETWEEN 5 AND 20 CHARACTERS") + } + + if (newPass == otherUser) { + reject(player, "PASSWORD CAN NOT BE SAME AS USERNAME.") + } + + GameWorld.authenticator.updatePassword(otherUser, newPass) + notify(player, "Password updated successfully.") + + } else { + reject(player, "USER DOES NOT EXIST!") + } + } + + define("giveitem", Privilege.ADMIN, "::giveitem USERNAME ITEM ID AMOUNT", "Gives the user the amount of the given item.") { player, args -> + if (args.size == 3 || args.size == 4) { + val victim = Repository.getPlayerByName(args[1]) + val itemID = args[2].toIntOrNull() + val amount = args.getOrNull(3)?.toIntOrNull() ?: 1 + + if (victim == null) { + reject(player, "INVALID TARGET USERNAME.") + } + + if (itemID == null || itemID <= 0 || itemID > ItemDefinition.getDefinitions().size) { + reject(player, "INVALID ITEM ID ENTERED.") + } + + if (amount > Int.MAX_VALUE || amount <= 0) { + reject(player, "INVALID ITEM ID ENTERED.") + } + + val item = Item(itemID!!, amount) + val invFull = victim!!.inventory.isFull + val syntax = if (amount > 1) "items" else "item" + + if (invFull) { + victim.bank.add(item) + } else { + victim.inventory.add(item) + } + + notify(player, "Successfully gave ${victim.username} $amount ${item.name}. ${if (invFull) "The $syntax were sent to their bank." else ""}") + notify(victim, "You received $amount ${item.name} from ${player.username}. ${if (invFull) "The $syntax were placed in your bank." else ""}") + + } else { + reject(player, "WRONG USAGE. USE giveitem target itemID || giveitem target itemID amt") + } + } + + define("removeitem", Privilege.ADMIN, "::removeitem LOC USERNAME ITEM ID AMOUNT", "LOC = bank,inventory,equipment") { player, args -> + if (args.size == 4 || args.size == 5) { + val itemLoc = args[1].toLowerCase() + val victim = Repository.getPlayerByName(args[2]) + val itemID = args[3].toIntOrNull() + var amount = args.getOrNull(4)?.toIntOrNull() ?: 1 + + if (victim == null) { + reject(player, "INVALID TARGET USERNAME.") + } + + if (itemID == null || itemID <= 0 || itemID > ItemDefinition.getDefinitions().size) { + reject(player, "INVALID ITEM ID ENTERED.") + } + + if (amount > Int.MAX_VALUE || amount <= 0) { + reject(player, "INVALID ITEM AMOUNT ENTERED.") + } + + val item = Item(itemID!!, amount) + var totalItemAmount = 0 + + when (itemLoc) { + "i", "inv", "inventory" -> { + totalItemAmount = victim!!.inventory.getItem(item).amount + victim.inventory.remove(item) + } + "b", "bk", "bank" -> { + totalItemAmount = victim!!.bank.getItem(item).amount + victim.bank.remove(item) + } + "e", "equip", "equipment" -> { + totalItemAmount = victim!!.equipment.getItem(item).amount + victim.equipment.remove(item) + } + else -> reject(player, "INVALID ITEM LOCATION ENTERED. USE: ", "i, inv, inventory | b, bk, bank | e, equip, equipment") + } + + if (amount > totalItemAmount) { + amount = totalItemAmount + } + + notify(player, "Successfully removed $amount ${item.name} from ${victim!!.username}.") + notify(victim, "${player.username} removed $amount ${item.name} from your inventory.") + + } else { + reject(player, "WRONG USAGE. USE removeitem itemLoc target itemID || removeitem itemLoc target itemID amt", + "ItemLoc: inv = inventory | equip = equipment | bank |") + } + } + + define("removeitemall", Privilege.ADMIN, "::removeitemall USERNAME ITEM ID", "Removes ALL of a given item from the player.") { player, args -> + if (args.size == 3) { + val victim = Repository.getPlayerByName(args[1]) + val itemID = args[2].toIntOrNull() + + if (victim == null) { + reject(player, "INVALID TARGET USERNAME.") + } + + if (itemID == null || itemID <= 0 || itemID > ItemDefinition.getDefinitions().size) { + reject(player, "INVALID ITEM ID ENTERED.") + } + + /* Handles removing the non noted version */ + val itemInv = Item(itemID!!) + /* Handles removing the noted version */ + val itemNote = Item(itemInv.noteChange) + + val untotal = victim!!.inventory.getAmount(itemID) + victim.bank.getAmount(itemID) + + victim.equipment.getAmount(itemID) + + val nototal = victim.inventory.getAmount(itemNote) + victim.bank.getAmount(itemNote) + + victim.equipment.getAmount(itemNote) + + val eqtotal = victim.equipment.getAmount(itemID) + victim.equipment.getAmount(itemNote) + + val total = untotal + nototal + eqtotal + + if (total == 0) { + reject(player, "USER HAS NONE OF THOSE ITEMS.") + } + + victim.inventory.remove(Item(itemID, victim.inventory.getAmount(itemID))) + victim.bank.remove(Item(itemID, victim.bank.getAmount(itemID))) + victim.equipment.remove(Item(itemID, victim.equipment.getAmount(itemID))) + + victim.inventory.remove(Item(itemInv.noteChange, victim.inventory.getAmount(itemNote))) + victim.bank.remove(Item(itemInv.noteChange, victim.bank.getAmount(itemNote))) + victim.equipment.remove(Item(itemInv.noteChange, victim.equipment.getAmount(itemNote))) + + notify(player, "Successfully removed $total ${itemInv.name} from ${victim.username}.") + notify(victim, "${player.username} removed $total ${itemInv.name} from your account.") + + } else { + reject(player, "WRONG USAGE. USE removeitemall target itemID") + } + } + + define("potato", Privilege.ADMIN, "", "Gives you a rotten potato.") { player, _ -> + player.inventory.add(Item(Items.ROTTEN_POTATO_5733)) + } + + define("shutdown", Privilege.ADMIN) { player, _ -> + exitProcess(0) + } + + /** + * Command to get and set the charge of an item. + * Can handle both the internal charge used for things like degradation, and distinct (#) charge that's different items. + * The default behavior without any flags is to get the internal charge of an item. + * param equipment slot name | item id - selects the item, either by using the equipment slot name, or item id. + * param sd - optional flags, where s = set charge, d = distinct charge. + * param charge - the charge to set on the item. Only necessary when the set flag is toggled. + * @author RiL + */ + define("charge", Privilege.ADMIN, "::charge equipment slot name | item id [sd] [charge]", "Get/set the charge of an item. Flags: s = set, d = distinct(#).") { player, args -> + if (args.size < 2) reject( + player, + "Usage: ::charge equipment slot name | item id [sd] [charge]", + "Get internal: ::charge 4718", + "Get distinct: ::charge ring d", + "Set internal: ::charge head s 500", + "Set distinct: ::charge 1704 sd 4" + ) + + @Suppress("UNCHECKED_CAST") + val itemInfo = (args[1].toIntOrNull()?.let { + getItemAndContainer(player, it) ?: reject(player, "Item not found: $it.") + } ?: EquipmentSlot.slotByName(args[1])?.ordinal?.let { + Pair(player.equipment.get(it) ?: reject(player, "No item equipped at slot: ${args[1]}."), player.equipment) + } ?: reject(player, "No slot: ${args[1]}.")) as Pair + + val item = itemInfo.first + + when (val flags = args.getOrElse(2) { "" }) { + "" -> { // get internal charge + notify(player, "${item.name}: ${item.charge} charge.") + } + + "d" -> { // get distinct charge + ChargedItem.forId(item.id)?.run { + notify(player, "${item.name}: (${ChargedItem.getCharge(item.id)}) charge.") + } ?: reject(player, "${item.name} is not a distinct(#) item.") + } + + "s", "sd", "ds" -> { + if (args.size < 4) reject(player, "Must enter a charge value.") + val charge = (args[3].toIntOrNull() ?: reject(player, "Charge must be an integer.")) as Int + if (flags == "s") { // set internal charge + if (charge < 1) reject(player, "Charge must be a positive integer.") + item.charge = charge + notify(player, "Set internal charge of ${item.name} to $charge.") + } else { // set distinct charge + ChargedItem.forId(item.id)?.forCharge(charge)?.let { + itemInfo.second.replace(Item(it), item.slot) + notify(player, "Set distinct charge of ${item.name} to (${ChargedItem.getCharge(it)}).") + } ?: reject(player, "${item.name} is not a distinct(#) item.") + } + } + + else -> { + reject(player, "Please enter valid flags: no flag/empty, s, d, sd.", "Use ::charge for examples.") + } + } + } + } + + /** + * Search for item in player and return item and container if found. Return null if not found + */ + private fun getItemAndContainer(player: Player, id: Int): Pair? { + if (id !in 0 until ItemDefinition.getDefinitions().size) return null + arrayOf(player.inventory, player.equipment, player.bankPrimary, player.bankSecondary).forEach { container -> + container.toArray().firstOrNull { it?.id == id }?.let { return Pair(it, container) } + } + return null + } +} diff --git a/Server/src/main/core/game/system/command/sets/TeleportCommandSet.kt b/Server/src/main/core/game/system/command/sets/TeleportCommandSet.kt new file mode 100644 index 0000000..30e4107 --- /dev/null +++ b/Server/src/main/core/game/system/command/sets/TeleportCommandSet.kt @@ -0,0 +1,211 @@ +package core.game.system.command.sets + +import core.game.node.entity.player.link.TeleportManager +import core.game.world.map.Location +import core.game.world.map.RegionManager +import core.plugin.Initializable +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch +import core.ServerConstants +import core.api.log +import core.game.system.command.Privilege +import core.game.world.repository.Repository +import core.tools.Log + +@Initializable +class TeleportCommandSet : CommandSet(Privilege.ADMIN){ + override fun defineCommands() { + /** + * Allows teleporting by location name + */ + define("to", Privilege.ADMIN, "::to String", "See ServerConstants.TELEPORT_DESTINATIONS"){player,args -> + var destination: Location? = null + val place = args.slice(1 until args.size).joinToString(" ") + for (destinations in ServerConstants.TELEPORT_DESTINATIONS) { + var i = 1 + while (i < destinations.size) { + if (place == destinations[i]) { + destination = destinations[0] as Location + break + } + i++ + } + } + if (destination != null) { + player.teleporter.send(destination, TeleportManager.TeleportType.NORMAL) + } else { + reject(player,"Could not locate teleport destination [name=$place]!") + } + } + + /** + * Teleport to location using coordinates + */ + define("tele", Privilege.ADMIN, "::tele X Y Z OR JAGCOORD", "JAGCOORD is Z_REGIONX_REGIONY_LOCALX_LOCALY"){player,args -> + if (args.size == 2 && args[1].contains(",")) { + val args2 = args[1].split(",".toRegex()).toTypedArray() + val x = args2[1].toInt() shl 6 or args2[3].toInt() + val y = args2[2].toInt() shl 6 or args2[4].toInt() + val z = args2[0].toInt() + player.properties.teleportLocation = Location.create(x, y, z) + return@define + } + if (args.size == 2 && args[1].contains("_")) + { + val tokens = args[1].split("_") + when (tokens.size) { + 2 -> { + val regionX = tokens[0].toInt() + val regionY = tokens[1].toInt() + + player.properties.teleportLocation = Location.create((regionX shl 6) or 15, (regionY shl 6) or 15, 0) + } + 3 -> { + val plane = tokens[0].toInt() + val regionX = tokens[1].toInt() + val regionY = tokens[2].toInt() + + player.properties.teleportLocation = Location.create((regionX shl 6) or 15, (regionY shl 6) or 15, plane) + } + 4 -> { + val regionX = tokens[0].toInt() + val regionY = tokens[1].toInt() + val offsetX = tokens[2].toInt() + val offsetY = tokens[3].toInt() + + val xCoord = (regionX shl 6) or offsetX + val yCoord = (regionY shl 6) or offsetY + + player.properties.teleportLocation = Location.create(xCoord, yCoord, 0) + } + 5 -> { + val plane = tokens[0].toInt() + val regionX = tokens[1].toInt() + val regionY = tokens[2].toInt() + val offsetX = tokens[3].toInt() + val offsetY = tokens[4].toInt() + + val xCoord = (regionX shl 6) or offsetX + val yCoord = (regionY shl 6) or offsetY + + player.properties.teleportLocation = Location.create(xCoord, yCoord, plane) + } + else -> reject(player, "Usage: regionX_regionY OR regionX_regionY_offsetX_offsetY") + } + return@define + } + if (args.size < 2) { + reject(player,"Usage: x,y,(optional)z OR regionX_regionY OR regionX_regionY_offsetX_offsetY") + } + player.properties.teleportLocation = Location.create(args[1].toInt(), args[2].toInt(), if (args.size > 3) args[3].toInt() else 0) + } + + /** + * Teleport to the first object with the given name in the given regionX regionY + */ + define("teleobj", Privilege.ADMIN, "::teleobj RX_RY OBJ NAME", "Teleports to the first object with the given name."){player, args -> + if(args.size < 3) reject(player, "Usage: regionX_regionY Object Name") + var objName = "" + for(i in 2 until args.size) objName += (args[i] + if(i + 1 == args.size) "" else " ") + + val tokens = args[1].split("_") + if(tokens.size != 2) reject(player, "Usage: regionX_regionY Object Name") + val regionX = tokens[0].toInt() + val regionY = tokens[1].toInt() + + val regionId = (regionX shl 8) or regionY + val region = RegionManager.forId(regionId) + + GlobalScope.launch { + for (plane in region.planes) { + for (objects in plane.objects.filterNotNull()) { + for (parent in objects.filterNotNull()) { + if (parent.childs != null) { + for (obj in parent.childs.filterNotNull()) { + if (obj.name.equals(objName, ignoreCase = true)) { + player.properties.teleportLocation = obj.location + return@launch + } + } + } else { + if (parent.name.equals(objName, ignoreCase = true)) { + player.properties.teleportLocation = parent.location + return@launch + } + } + } + } + } + } + } + + /** + * Finds a list of objects/sceneries in a region + */ + define("findobjs", Privilege.ADMIN, "::findobjs REGION ID SCENERY ID", "Finds all locations of scenery objects of id."){player, args -> + if(args.size < 4) reject(player, "Usage: region_id scenery_id") + val regionId = args[1].toInt() + val sceneryId = args[2].toInt() + val sceneryIdEnd = args[3].toInt() + + val region = RegionManager.forId(regionId) + + GlobalScope.launch { + for (plane in region.planes) { + for (objects in plane.objects.filterNotNull()) { + for (parent in objects.filterNotNull()) { + if (parent.id in sceneryId..sceneryIdEnd) { + println(parent.location) + } + } + } + } + } + } + + /** + * Teleport to a specific player + */ + define("teleto", Privilege.ADMIN, "::teleto USERNAME", "Teleports to the named player."){player,args -> + if (args.size < 1) { + reject(player,"syntax error: name") + } + val n = args.slice(1 until args.size).joinToString("_") + val target = Repository.getPlayerByName(n) + if (target == null) { + reject(player,"syntax error: name") + } + if (target!!.getAttribute("fc_wave") != null) { + reject(player,"You cannot teleport to a player who is in the Fight Caves.") + } + player.properties.teleportLocation = target.location + } + + + /** + * Teleport a specific player to you + */ + define("teletome", Privilege.ADMIN, "::teletome USERNAME", "Teleports the given user to you."){player,args -> + if (args.size < 1) { + reject(player,"syntax error: name") + } + val n = args.slice(1 until args.size).joinToString("_") + val target = Repository.getPlayerByName(n) + if (target == null) { + reject(player,"syntax error: name") + } + if (target!!.getAttribute("fc_wave") != null) { + reject(player,"You cannot teleport to a player who is in the Fight Caves.") + } + target.properties.teleportLocation = player.location + } + + + /** + * Teleports to the server's home location + */ + define("home", Privilege.ADMIN, "", "Teleports to ServerConstants.HOME_LOCATION"){player,_ -> + player.properties.teleportLocation = ServerConstants.HOME_LOCATION + } + } +} diff --git a/Server/src/main/core/game/system/communication/ClanEntry.java b/Server/src/main/core/game/system/communication/ClanEntry.java new file mode 100644 index 0000000..135638d --- /dev/null +++ b/Server/src/main/core/game/system/communication/ClanEntry.java @@ -0,0 +1,96 @@ +package core.game.system.communication; + +import core.game.node.entity.player.Player; +import core.game.world.GameWorld; + +/** + * Represents a player in a clan chat. + * @author Emperor + */ +public class ClanEntry { + + /** + * The name. + */ + private final String name; + + /** + * The player. + */ + private Player player; + + /** + * The world id. + */ + private int worldId; + + /** + * Constructs a new {@code ClanEntry} {@code Object} + * @param player The player. + */ + public ClanEntry(Player player) { + this.player = player; + this.name = player.getName(); + this.worldId = GameWorld.getSettings().getWorldId(); + } + + /** + * Constructs a new {@code ClanEntry} {@code Object} + * @param name The player's name. + * @param worldId The world id. + */ + public ClanEntry(String name, int worldId) { + this.name = name; + this.worldId = worldId; + } + + @Override + public boolean equals(Object o) { + if(o == null) return false; + ClanEntry e = (ClanEntry) o; + if (name != null && !name.equals(e.name)) { + return false; + } + return e.player == player; + } + + /** + * Gets the name. + * @return the name + */ + public String getName() { + return name; + } + + /** + * Sets the player. + * @param player The player. + */ + public void setPlayer(Player player) { + this.player = player; + } + + /** + * Gets the player. + * @return the player + */ + public Player getPlayer() { + return player; + } + + /** + * Gets the worldId. + * @return the worldId + */ + public int getWorldId() { + return worldId; + } + + /** + * Sets the worldId. + * @param worldId the worldId to set. + */ + public void setWorldId(int worldId) { + this.worldId = worldId; + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/system/communication/ClanMember.java b/Server/src/main/core/game/system/communication/ClanMember.java new file mode 100644 index 0000000..82d9bf6 --- /dev/null +++ b/Server/src/main/core/game/system/communication/ClanMember.java @@ -0,0 +1,38 @@ +package core.game.system.communication; + +/** + * Represents a clan member. + * @author Emperor + */ +public final class ClanMember { + + /** + * Represents the rank of the player. + */ + private ClanRank rank = ClanRank.FRIEND; + + /** + * Constructs a new {@code ClanMember} {@code Object}. + * @param rank The clan rank. + */ + public ClanMember(ClanRank rank) { + this.rank = rank; + } + + /** + * Gets the rank. + * @return The rank. + */ + public ClanRank getRank() { + return rank; + } + + /** + * Sets the rank. + * @param rank The rank to set. + */ + public void setRank(ClanRank rank) { + this.rank = rank; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/system/communication/ClanRank.java b/Server/src/main/core/game/system/communication/ClanRank.java new file mode 100644 index 0000000..d3f3f23 --- /dev/null +++ b/Server/src/main/core/game/system/communication/ClanRank.java @@ -0,0 +1,50 @@ +package core.game.system.communication; + +/** + * Represents the rank of a clan member. + * @author Emperor + */ +public enum ClanRank { + NONE(-1, "Anyone"), FRIEND(0, "Any friends"), RECRUIT(1, "Recruit+"), CORPORAL(2, "Corporal+"), SERGEANT(3, "Sergeant+"), LIEUTENANT(4, "Lieutenant+"), CAPTAIN(5, "Captain+"), GENERAL(6, "General+"), OWNER(7, "Only me"), ADMINISTRATOR(127, "No-one"); + + /** + * The value of the rank. + */ + private final int value; + + /** + * The requirement info. + */ + private final String info; + + /** + * Constructs a new {@code ClanRank} {@code Object}. + * @param value The rank value. + * @param info The requirement info. + */ + private ClanRank(int value, String info) { + this.value = value; + this.info = info; + } + + /** + * Gets the value. + * @return The value. + */ + public int getValue() { + return value; + } + + /** + * Gets the info. + * @return The info. + */ + public String getInfo() { + return info; + } + + @Override + public String toString() { + return "Rank=[" + name() + "], Info=" + "[" + getInfo() + "]"; + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/system/communication/ClanRepository.java b/Server/src/main/core/game/system/communication/ClanRepository.java new file mode 100644 index 0000000..58ec670 --- /dev/null +++ b/Server/src/main/core/game/system/communication/ClanRepository.java @@ -0,0 +1,577 @@ +package core.game.system.communication; + +import core.ServerConstants; +import core.game.component.Component; +import core.game.activity.ActivityPlugin; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.info.PlayerDetails; +import core.game.node.entity.player.info.Rights; +import proto.management.ClanJoinNotification; +import proto.management.ClanLeaveNotification; +import core.game.node.entity.player.info.PlayerMonitor; +import core.game.world.GameWorld; +import core.game.world.repository.Repository; +import core.net.amsc.WorldCommunicator; +import core.net.packet.PacketRepository; +import core.net.packet.context.ClanContext; +import core.net.packet.context.MessageContext; +import core.net.packet.out.CommunicationMessage; +import core.net.packet.out.UpdateClanChat; +import core.worker.ManagementEvents; + +import java.util.*; + +/** + * Handles clan communication. + * @author Emperor + */ +public final class ClanRepository { + + /** + * The maximum amount of members to be in a clan chat. + */ + private static final int MAX_MEMBERS = 100; + + /** + * The clan repository. + */ + private static final Map CLAN_REPOSITORY = new HashMap<>(); + + /** + * The name of the clan owner. + */ + private final String owner; + + /** + * The clan name. + */ + private String name = "Chat disabled"; + + /** + * The rank required for joining. + */ + private ClanRank joinRequirement = ClanRank.FRIEND; + + /** + * The rank required for messaging. + */ + private ClanRank messageRequirement = ClanRank.NONE; + + /** + * The rank required for kicking members. + */ + private ClanRank kickRequirement = ClanRank.OWNER; + + /** + * The rank required for loot-share. + */ + private ClanRank lootRequirement = ClanRank.ADMINISTRATOR; + + /** + * The members mapping. + */ + private final Map ranks = new HashMap<>(); + + /** + * The banned players. + */ + private final Map banned = new HashMap<>(); + + /** + * The players who are currently in the friends chat. + */ + private List players = new ArrayList<>(MAX_MEMBERS); + + /** + * The current clan wars activity. + */ + private ActivityPlugin clanWar; + + /** + * Constructs a new {@code ClanRepository} {@code Object}. + * @param owner The owner of the clan. + */ + public ClanRepository(String owner) { + this.owner = owner; + } + + /** + * Enters the clan chat. + * @param player The player. + * @return {@code True} if the player successfully entered the clan chat. + */ + public boolean enter(Player player) { + if (!owner.equals(ServerConstants.SERVER_NAME.toLowerCase()) && players.size() >= MAX_MEMBERS) { + player.getPacketDispatch().sendMessage("The channel you tried to join is full.:clan:"); + return false; + } + if (!player.getName().equals(owner) && player.getDetails().getRights() != Rights.ADMINISTRATOR) { + if (isBanned(player.getName())) { + player.getPacketDispatch().sendMessage("You are temporarily banned from this clan channel.:clan:"); + return false; + } + Player o = Repository.getPlayerByName(owner); + if (o != null) { + if (o.getCommunication().getBlocked().contains(player.getName())) { + player.getPacketDispatch().sendMessage("You do not have a high enough rank to join this clan channel.:clan:"); + return false; + } + } + ClanRank rank = getRank(player); + if (rank.ordinal() < joinRequirement.ordinal()) { + player.getPacketDispatch().sendMessage("You do not have a high enough rank to join this clan channel.:clan:"); + return false; + } + } + ClanEntry entry = new ClanEntry(player); + if (!players.contains(entry)) { + players.add(entry); + } + + ClanJoinNotification.Builder event = ClanJoinNotification.newBuilder(); + event.setUsername(player.getName()); + event.setWorld(GameWorld.getSettings().getWorldId()); + event.setClanName(owner); + ManagementEvents.publish(event.build()); + + player.getPacketDispatch().sendMessage("Now talking in clan channel " + name + ":clan:"); + player.getPacketDispatch().sendMessage("To talk, start each line of chat with the / symbol.:clan:"); + update(); + return true; + } + + /** + * Cleans the chat from all players that shouldn't be in it. + */ + public void clean(boolean disable) { + if (WorldCommunicator.isEnabled()) { + return; + } + for (Iterator it = players.iterator(); it.hasNext();) { + ClanEntry entry = it.next(); + Player player = entry.getPlayer(); + boolean remove = disable; + if (!remove) { + remove = getRank(player).ordinal() < joinRequirement.ordinal(); + } + if (remove) { + leave(player, false); + player.getCommunication().setClan(null); + it.remove(); + } + } + if (players.isEmpty()) { + banned.clear(); + } + update(); + } + + /** + * Checks if a player is banned. + * @param name The player's name. + * @return {@code True} if so. + */ + public boolean isBanned(String name) { + if (banned.containsKey(name)) { + long time = banned.get(name); + if (time > System.currentTimeMillis()) { + return true; + } + banned.remove(name); + } + return false; + } + + /** + * Sends a message to all players in the chat. + * @param player The player sending the message. + * @param message The message to send. + */ + public void message(Player player, String message) { + if (player.getLocks().isLocked("cc_message") || isBanned(player.getName())) { + return; + } + player.getLocks().lock("cc_message", 1); + if (!player.getName().equals(owner) && player.getDetails().getRights() != Rights.ADMINISTRATOR) { + ClanRank rank = getRank(player); + if (rank.ordinal() < messageRequirement.ordinal()) { + player.getPacketDispatch().sendMessage("You do not have a high enough rank to talk in this clan channel.:clan:"); + return; + } + } + PlayerMonitor.logChat(player, "clan", message); + for (Iterator it = players.iterator(); it.hasNext();) { + ClanEntry entry = it.next(); + Player p = entry.getPlayer(); + if (p != null) { + PacketRepository.send(CommunicationMessage.class, new MessageContext(p, player, MessageContext.CLAN_MESSAGE, message)); + } + } + } + + /** + * Kicks a player from this chat. + * @param player the player. + * @param target the victim. + */ + public void kick(Player player, Player target) { + ClanRank rank = getRank(player); + if (target.getDetails().getRights() == Rights.ADMINISTRATOR) { + player.sendMessage("You can't kick an administrator.:clan:"); + return; + } + if (target.getName().equals(player.getName())) { + player.sendMessage("You can't kick yourself.:clan:"); + return; + } + if (player.getDetails().getRights() != Rights.ADMINISTRATOR && rank.ordinal() < kickRequirement.ordinal()) { + player.getPacketDispatch().sendMessage("You do not have a high enough rank to kick in this clan channel.:clan:"); + return; + } + if (target.getName().equals(owner)) { + player.getPacketDispatch().sendMessage("You can't kick the owner of this clan channel.:clan:"); + return; + } + for (ClanEntry e : players) { + PacketRepository.send(CommunicationMessage.class, new MessageContext(e.getPlayer(), player, MessageContext.CLAN_MESSAGE, "[Attempting to kick/ban " + target.getUsername() + " from this Clan Chat.]")); + } + leave(target, true, "You have been kicked from the channel.:clan:"); + target.getCommunication().setClan(null); + banned.put(target.getName(), System.currentTimeMillis() + (3_600_000)); + } + + /** + * Represents the method to leave a clan. + * @param player the player. + * @param remove If the player should be removed from the list. + */ + public void leave(Player player, boolean remove) { + leave(player, remove, "You have left the channel.:clan:"); + } + + /** + * Represents the method to leave a clan. + * @param player the player. + * @param remove If the player should be removed from the list. + */ + public void leave(Player player, boolean remove, String message) { + if (remove) { + players.remove(new ClanEntry(player)); + update(); + if (players.size() < 1) { + banned.clear(); + } + } + PacketRepository.send(UpdateClanChat.class, new ClanContext(player, this, true)); + player.getPacketDispatch().sendMessage(message); + if (clanWar != null && !isDefault()) { + clanWar.fireEvent("leavefc", player); + } + + ClanLeaveNotification.Builder event = ClanLeaveNotification.newBuilder(); + event.setClanName(owner); + event.setUsername(player.getName()); + event.setWorld(GameWorld.getSettings().getWorldId()); + ManagementEvents.publish(event.build()); + } + + /** + * Ranks a member of this chat. + * @param name The name of the member. + * @param rank The rank to set. + */ + public void rank(String name, ClanRank rank) { + boolean update; + if (rank == ClanRank.NONE) { + update = ranks.remove(name) != null; + } else { + update = ranks.put(name, rank) != rank; + } + if (update) { + clean(false); + } + } + + /** + * Updates the clan chat for all players in this clan. + */ + public void update() { + for (Iterator it = players.iterator(); it.hasNext();) { + ClanEntry e = it.next(); + if (e.getWorldId() == GameWorld.getSettings().getWorldId() && e.getPlayer() != null) { + PacketRepository.send(UpdateClanChat.class, new ClanContext(e.getPlayer(), this, false)); + } + } + } + + /** + * Gets the clan rank for the given clan entry. + * @param entry The clan entry. + * @return The rank. + */ + public ClanRank getRank(ClanEntry entry) { + if (entry.getPlayer() != null) { + return getRank(entry.getPlayer()); + } + ClanRank rank = ranks.get(entry.getName()); + if (rank == null) { + return ClanRank.NONE; + } + return rank; + } + + /** + * Gets the rank of the player. + * @param player The player. + * @return The clan rank. + */ + public ClanRank getRank(Player player) { + ClanRank rank = ranks.get(player.getName()); + if (player.getDetails().getRights() == Rights.ADMINISTRATOR && !player.getName().equals(owner)) { + return ClanRank.ADMINISTRATOR; + } + if (rank == null) { + if (player.getName().equals(owner)) { + return ClanRank.OWNER; + } + return ClanRank.NONE; + } + return rank; + } + + /** + * Opens the clan settings for the player. + * @param player The player. + */ + public static void openSettings(Player player) { + player.getInterfaceManager().open(new Component(590)); + ClanRepository c = get(player.getName()); + if (c != null) { + c.updateSettings(player); + } + } + + /** + * Updates the clan settings for the player. + * @param player The player. + */ + public void updateSettings(Player player) { + player.getPacketDispatch().sendString(name, 590, 22); + // player.getPacketDispatch().sendConfig(1083, (isCoinshare() ? 1 : 0) + // << 18 | (isLootshare() ? 0 : 1)); + player.getPacketDispatch().sendString(joinRequirement.getInfo(), 590, 23); + player.getPacketDispatch().sendString(messageRequirement.getInfo(), 590, 24); + player.getPacketDispatch().sendString(kickRequirement.getInfo(), 590, 25); + player.getPacketDispatch().sendString(lootRequirement.getInfo(), 590, 26); + } + + /** + * Loads the clan data. + * @param owner The owner of the clan to load. + * @return The clan data. + */ + public static ClanRepository get(String owner) { + return get(owner, false); + } + + /** + * Loads the clan data. + * @param owner The owner of the clan to load. + * @param create If the clan should be created if it doesn't exist. + * @return The clan data. + */ + public static ClanRepository get(String owner, boolean create) { + ClanRepository clan = CLAN_REPOSITORY.get(owner); + if (clan != null) { + return clan; + } + Player player = Repository.getPlayerByName(owner); + PlayerDetails details = player != null ? player.getDetails() : null; + if (details == null) { + details = PlayerDetails.getDetails(owner); + if (details == null) { + return null; + } + } + String name = details.getCommunication().getClanName(); + if (name.length() < 1) { + if (!create) { + return null; + } + name = "Chat disabled"; + } + CLAN_REPOSITORY.put(owner, clan = new ClanRepository(owner)); + for (Contact c : details.getCommunication().getContacts().values()) { + clan.ranks.put(c.getUsername(), c.getRank()); + } + clan.name = name; + clan.joinRequirement = details.getCommunication().getJoinRequirement(); + clan.messageRequirement = details.getCommunication().getMessageRequirement(); + clan.kickRequirement = details.getCommunication().getKickRequirement(); + clan.lootRequirement = details.getCommunication().getLootRequirement(); + return clan; + } + + /** + * Checks if this clan chat is the default clan chat. + * @return {@code True} if so. + */ + public boolean isDefault() { + return owner.equals(GameWorld.getSettings().getName().toLowerCase()); + } + + /** + * Gets the default clan chat. + * @return The default clan chat. + */ + public static ClanRepository getDefault() { + return get(GameWorld.getSettings().getName().toLowerCase()); + } + + /** + * Deletes a clan. + */ + public void delete() { + CLAN_REPOSITORY.remove(owner); + clean(true); + } + + /** + * Gets the currently loaded clans. + * @return The clans. + */ + public static Map getClans() { + return CLAN_REPOSITORY; + } + + /** + * Gets the list of players currently in the clan. + * @return The list of players. + */ + public List getPlayers() { + return players; + } + + /** + * Gets the joinRequirement. + * @return The joinRequirement. + */ + public ClanRank getJoinRequirement() { + return joinRequirement; + } + + /** + * Sets the joinRequirement. + * @param joinRequirement The joinRequirement to set. + */ + public void setJoinRequirement(ClanRank joinRequirement) { + this.joinRequirement = joinRequirement; + clean(false); + } + + /** + * Gets the messageRequirement. + * @return The messageRequirement. + */ + public ClanRank getMessageRequirement() { + return messageRequirement; + } + + /** + * Sets the messageRequirement. + * @param messageRequirement The messageRequirement to set. + */ + public void setMessageRequirement(ClanRank messageRequirement) { + this.messageRequirement = messageRequirement; + } + + /** + * Gets the kickRequirement. + * @return The kickRequirement. + */ + public ClanRank getKickRequirement() { + return kickRequirement; + } + + /** + * Sets the kickRequirement. + * @param kickRequirement The kickRequirement to set. + */ + public void setKickRequirement(ClanRank kickRequirement) { + this.kickRequirement = kickRequirement; + update(); + } + + /** + * Gets the lootRequirement. + * @return The lootRequirement. + */ + public ClanRank getLootRequirement() { + return lootRequirement; + } + + /** + * Gets the banned. + * @return the banned + */ + public Map getBanned() { + return banned; + } + + /** + * Sets the lootRequirement. + * @param lootRequirement The lootRequirement to set. + */ + public void setLootRequirement(ClanRank lootRequirement) { + this.lootRequirement = lootRequirement; + } + + /** + * Gets the owner. + * @return The owner. + */ + public String getOwner() { + return owner; + } + + /** + * Gets the name. + * @return The name. + */ + public String getName() { + return name; + } + + /** + * Sets the name. + * @param name The name to set. + */ + public void setName(String name) { + this.name = name; + } + + /** + * Gets the members. + * @return The members. + */ + public Map getRanks() { + return ranks; + } + + /** + * Gets the clanWar. + * @return The clanWar. + */ + public ActivityPlugin getClanWar() { + return clanWar; + } + + /** + * Sets the clanWar. + * @param clanWar The clanWar to set. + */ + public void setClanWar(ActivityPlugin clanWar) { + this.clanWar = clanWar; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/system/communication/CommunicationInfo.java b/Server/src/main/core/game/system/communication/CommunicationInfo.java new file mode 100644 index 0000000..8135e73 --- /dev/null +++ b/Server/src/main/core/game/system/communication/CommunicationInfo.java @@ -0,0 +1,663 @@ +package core.game.system.communication; + +import core.game.node.entity.player.Player; +import core.tools.Log; +import org.jetbrains.annotations.NotNull; +import proto.management.PrivateMessage; +import core.auth.UserAccountInfo; +import core.game.system.mysql.SQLTable; +import core.game.system.task.Pulse; +import core.game.world.GameWorld; +import core.game.world.repository.Repository; +import core.net.amsc.MSPacketRepository; +import core.net.amsc.WorldCommunicator; +import core.net.packet.PacketRepository; +import core.net.packet.context.ContactContext; +import core.net.packet.out.ContactPackets; +import core.tools.StringUtils; +import core.worker.ManagementEvents; + +import java.util.*; +import java.util.Map.Entry; + +import static core.api.ContentAPIKt.log; +import static core.api.ContentAPIKt.setVarp; + +/** + * Holds communication information. + * @author Emperor + */ +public final class CommunicationInfo { + + /** + * The maximum list size. + */ + public static final int MAX_LIST_SIZE = 200; + + /** + * The clan ranks. + */ + private Map contacts = new HashMap<>(); + + /** + * The list of blocked players. + */ + private final List blocked = new ArrayList<>(20); + + /** + * The player's clan name. + */ + private String clanName = ""; + + /** + * The current clan this player is in. + */ + private String currentClan = ""; + + /** + * The rank required for joining. + */ + private ClanRank joinRequirement = ClanRank.FRIEND; + + /** + * The rank required for messaging. + */ + private ClanRank messageRequirement = ClanRank.NONE; + + /** + * The rank required for kicking members. + */ + private ClanRank kickRequirement = ClanRank.OWNER; + + /** + * The rank required for loot-share. + */ + private ClanRank lootRequirement = ClanRank.ADMINISTRATOR; + + /** + * If lootshare is enabled. + */ + private boolean lootShare; + + /** + * The current clan joined. + */ + private ClanRepository clan = null; + + /** + * The loot-share pulse. + */ + private Pulse lootSharePulse; + + /** + * Constructs a new {@code CommunicationInfo} {@code Object}. + */ + public CommunicationInfo() { + /* + * empty. + */ + } + + /** + * Saves the communication info. + * @param table The SQL table to update. + */ + public void save(SQLTable table) { + String contacts = ""; + String blocked = ""; + for (int i = 0; i < this.blocked.size(); i++) { + blocked += (i == 0 ? "" : ",") + this.blocked.get(i); + } + int count = 0; + for (Entry entry : this.contacts.entrySet()) { + contacts += "{" + entry.getKey() + "," + entry.getValue().getRank().ordinal() + "}" + (count == this.contacts.size() - 1 ? "" : "~"); + count++; + } + table.getColumn("blocked").updateValue(blocked); + table.getColumn("contacts").updateValue(contacts); + table.getColumn("clanName").updateValue(clanName); + table.getColumn("currentClan").updateValue(currentClan); + table.getColumn("clanReqs").updateValue(joinRequirement.ordinal() + "," + messageRequirement.ordinal() + "," + kickRequirement.ordinal() + "," + lootRequirement.ordinal()); + } + + /** + * Parses the communication info from the database. + * @param table The sql table to parse. + */ + public void parse(SQLTable table) { + String[] tokens = null; + if (table.getColumn("contacts").getValue() != null ) { + String contacts = (String) table.getColumn("contacts").getValue(); + if (!contacts.isEmpty()) { + String[] datas = contacts.split("~"); + Contact contact = null; + for (String d : datas) { + tokens = d.replace("{", "").replace("}", "").split(","); + if (tokens.length == 0) { + continue; + } + contact = new Contact(tokens[0]); + contact.setRank(ClanRank.values()[Integer.valueOf(tokens[1])]); + this.contacts.put(tokens[0], contact); + } + } + } + if (table.getColumn("blocked").getValue() != null ) { + String blocked = (String) table.getColumn("blocked").getValue(); + if (!blocked.isEmpty()) { + tokens = blocked.split(","); + for (String name : tokens) { + this.blocked.add(name); + } + } + } + clanName = ((String) table.getColumn("clanName").getValue()); + currentClan = (String) table.getColumn("currentClan").getValue(); + String clanReqs = (String) table.getColumn("clanReqs").getValue(); + if (clanReqs == "") { + return; + } + tokens = clanReqs.split(","); + ClanRank rank = null; + int ordinal = 0; + for (int i = 0; i < tokens.length; i++) { + ordinal = Integer.parseInt(tokens[i]); + if (ordinal < 0 || ordinal > ClanRank.values().length -1) { + continue; + } + rank = ClanRank.values()[ordinal]; + switch (i) { + case 0: + joinRequirement = rank; + break; + case 1: + messageRequirement = rank; + break; + case 2: + if (ordinal < 3 || ordinal > 8) { + break; + } + kickRequirement = rank; + break; + case 3: + lootRequirement = rank; + break; + } + } + } + + /** + * Toggles the loot-share. + */ + public void toggleLootshare(final Player player) { + if (lootShare) { + lootShare = false; + setVarp(player, 1083, 0); + } else if (lootSharePulse != null) { + lootSharePulse.stop(); + lootSharePulse = null; + setVarp(player, 1083, 0); + } else if (!lootShare) { + setVarp(player, 1083, 2); + lootSharePulse = new Pulse(GameWorld.getSettings().isDevMode() ? 5 : 200, player) { + @Override + public boolean pulse() { + lootShare = true; + lootSharePulse = null; + setVarp(player, 1083, 1); + return true; + } + }; + GameWorld.getPulser().submit(lootSharePulse); + } + } + + /** + * Sends a message to the target. + * @param player The player sending the message. + * @param target The target. + * @param message The message to send. + */ + public static void sendMessage(Player player, String target, String message) { + PrivateMessage.Builder builder = PrivateMessage.newBuilder(); + builder.setSender(player.getName()); + builder.setRank(player.getDetails().getRights().ordinal()); + builder.setMessage(message); + builder.setReceiver(target); + ManagementEvents.publish(builder.build()); + } + + /** + * Adds a contact. + * @param contact The contact to add. + */ + public static void add(Player player, String contact) { + CommunicationInfo info = player.getDetails().getCommunication(); + if (contact.isEmpty()) { + player.sendMessage("Unable to find a player by that name. Please try again."); + return; + } + if (WorldCommunicator.isEnabled()) { + MSPacketRepository.sendContactUpdate(player.getName(), contact, false, false, null); + return; + } + if (info.contacts.size() >= MAX_LIST_SIZE) { + player.getPacketDispatch().sendMessage("Your friend list is full."); + return; + } + if (info.contacts.containsKey(contact)) { + player.getPacketDispatch().sendMessage(StringUtils.formatDisplayName(contact) + " is already on your friend list."); + return; + } + ClanRepository clan = ClanRepository.get(player.getName(), false); + if (clan != null) { + clan.rank(contact, ClanRank.FRIEND); + } + info.contacts.put(contact, new Contact(contact)); + Player target = Repository.getPlayerByName(contact); + if (target != null) { + if (showActive(player, target)) { + PacketRepository.send(ContactPackets.class, new ContactContext(player, contact, GameWorld.getSettings().getWorldId())); + } + if (player.getSettings().getPrivateChatSetting() == 1 && showActive(target, player)) { + PacketRepository.send(ContactPackets.class, new ContactContext(target, player.getName(), GameWorld.getSettings().getWorldId())); + } + } + } + + /** + * Removes a contact. + * @param contact The contact to remove. + * @param block If the contact should be removed from the block list. + */ + public static void remove(Player player, String contact, boolean block) { + if (contact.isEmpty()) { + player.sendMessage("Unable to find a player by that name. Please try again."); + return; + } + if (WorldCommunicator.isEnabled()) { + MSPacketRepository.sendContactUpdate(player.getName(), contact, true, block, null); + return; + } + CommunicationInfo info = player.getDetails().getCommunication(); + if (block) { + info.blocked.remove(contact); + Player target = Repository.getPlayerByName(contact); + if (target != null && hasContact(target, player.getName())) { + int worldId = 0; + if (showActive(target, player)) { + worldId = GameWorld.getSettings().getWorldId(); + } + PacketRepository.send(ContactPackets.class, new ContactContext(target, player.getName(), worldId)); + } + } else { + info.contacts.remove(contact); + ClanRepository clan = ClanRepository.get(player.getName(), false); + if (clan != null) { + clan.rank(contact, ClanRank.NONE); + } + if (player.getSettings().getPrivateChatSetting() == 1) { + Player target = Repository.getPlayerByName(contact); + if (target != null) { + PacketRepository.send(ContactPackets.class, new ContactContext(target, player.getName(), 0)); + } + } + } + } + + /** + * Adds a blocked contact. + * @param contact The contact to block. + */ + public static void block(Player player, String contact) { + if (contact.isEmpty()) { + player.sendMessage("Unable to find a player by that name. Please try again."); + return; + } + if (WorldCommunicator.isEnabled()) { + MSPacketRepository.sendContactUpdate(player.getName(), contact, false, true, null); + return; + } + CommunicationInfo info = player.getDetails().getCommunication(); + if (info.blocked.size() >= MAX_LIST_SIZE) { + player.getPacketDispatch().sendMessage("Your ignore list is full."); + return; + } + if (info.blocked.contains(contact)) { + player.getPacketDispatch().sendMessage(StringUtils.formatDisplayName(contact) + " is already on your ignore list."); + return; + } + info.blocked.add(contact); + Player target = Repository.getPlayerByName(contact); + if (target != null && hasContact(target, player.getName())) { + PacketRepository.send(ContactPackets.class, new ContactContext(target, player.getName(), 0)); + } + } + + /** + * Updates the clan rank of a certain contact. + * @param contact The contact. + * @param clanRank The clan rank to set. + */ + public static void updateClanRank(Player player, String contact, ClanRank clanRank) { + if (contact.isEmpty()) { + player.sendMessage("Unable to find a player by that name. Please try again."); + return; + } + CommunicationInfo info = player.getDetails().getCommunication(); + Contact c = info.contacts.get(contact); + if (c == null) { + log(CommunicationInfo.class, Log.ERR, "Could not find contact " + contact + " to update clan rank!"); + return; + } + c.setRank(clanRank); + ClanRepository clan = ClanRepository.get(player.getName()); + if (clan != null) { + clan.rank(contact, clanRank); + } + int worldId = 0; + if (CommunicationInfo.showActive(player, contact)) { + worldId = c.getWorldId(); + } + PacketRepository.send(ContactPackets.class, new ContactContext(player, contact, worldId)); + } + + /** + * Checks if the player has the contact added. + * @param player The player. + * @param contact The contact. + * @return {@code True} if so. + */ + public static boolean hasContact(Player player, String contact) { + return player.getDetails().getCommunication().contacts.containsKey(contact); + } + + /** + * Checks if the target should be shown as online. + * @param name The target's name. + * @return {@code True} if so. + */ + public static boolean showActive(Player player, String name) { + Player p = Repository.getPlayerByName(name); + if (p != null) { + return showActive(player, p); + } + return false; + } + + /** + * Checks if the target should be shown as online. + * @param target The target. + * @return {@True} if so. + */ + public static boolean showActive(Player player, Player target) { + if (target.getName().equals(player.getName())) { + return false; + } + if (target.getCommunication().getBlocked().contains(player.getName())) { + return false; + } + switch (target.getSettings().getPrivateChatSetting()) { + case 1: + if (!hasContact(target, player.getName())) { + return false; + } + return true; + case 2: + return false; + } + return true; + } + + /** + * Gets the contacts value. + * @return The contacts. + */ + public Map getContacts() { + return contacts; + } + + /** + * Gets the blocked value. + * @return The blocked. + */ + public List getBlocked() { + return blocked; + } + + /** + * Gets the clanName value. + * @return The clanName. + */ + public String getClanName() { + return clanName; + } + + /** + * Sets the clanName value. + * @param clanName The clanName to set. + */ + public void setClanName(String clanName) { + this.clanName = clanName; + } + + /** + * Gets the currentClan value. + * @return The currentClan. + */ + public String getCurrentClan() { + return currentClan == null ? "" : currentClan; + } + + /** + * Sets the currentClan value. + * @param currentClan The currentClan to set. + */ + @Deprecated + public void setCurrentClan(String currentClan) { + this.currentClan = currentClan; + } + + /** + * Gets the joinRequirement value. + * @return The joinRequirement. + */ + public ClanRank getJoinRequirement() { + return joinRequirement; + } + + /** + * Sets the joinRequirement value. + * @param joinRequirement The joinRequirement to set. + */ + public void setJoinRequirement(ClanRank joinRequirement) { + this.joinRequirement = joinRequirement; + } + + /** + * Gets the messageRequirement value. + * @return The messageRequirement. + */ + public ClanRank getMessageRequirement() { + return messageRequirement; + } + + /** + * Sets the messageRequirement value. + * @param messageRequirement The messageRequirement to set. + */ + public void setMessageRequirement(ClanRank messageRequirement) { + this.messageRequirement = messageRequirement; + } + + /** + * Gets the kickRequirement value. + * @return The kickRequirement. + */ + public ClanRank getKickRequirement() { + return kickRequirement; + } + + /** + * Sets the kickRequirement value. + * @param kickRequirement The kickRequirement to set. + */ + public void setKickRequirement(ClanRank kickRequirement) { + this.kickRequirement = kickRequirement; + } + + /** + * Gets the lootRequirement value. + * @return The lootRequirement. + */ + public ClanRank getLootRequirement() { + return lootRequirement; + } + + /** + * Sets the lootRequirement value. + * @param lootRequirement The lootRequirement to set. + */ + public void setLootRequirement(ClanRank lootRequirement) { + this.lootRequirement = lootRequirement; + } + + /** + * Gets the clan. + * @return the clan + */ + public ClanRepository getClan() { + return clan; + } + + /** + * Sets the clan. + * @param clan the clan to set. + */ + public void setClan(ClanRepository clan) { + this.clan = clan; + this.currentClan = clan == null ? null : clan.getOwner(); + } + + /** + * Gets the lootShare. + * @return the lootShare + */ + public boolean isLootShare() { + return lootShare; + } + + /** + * Sets the lootShare. + * @param lootShare the lootShare to set. + */ + public void setLootShare(boolean lootShare) { + this.lootShare = lootShare; + } + + public void parse(@NotNull UserAccountInfo accountInfo) { + blocked.addAll(Arrays.asList(accountInfo.getBlocked().split(","))); + clanName = accountInfo.getClanName(); + currentClan = accountInfo.getCurrentClan(); + + String clanReqs = accountInfo.getClanReqs(); + ClanRank[] reqs = parseClanRequirements(clanReqs); + joinRequirement = reqs[0]; + messageRequirement = reqs[1]; + kickRequirement = reqs[2]; + lootRequirement = reqs[3]; + + String contacts = accountInfo.getContacts(); + this.contacts = parseContacts(contacts); + } + + public static ClanRank[] parseClanRequirements(String clanReqs) { + ClanRank[] requirements = new ClanRank[4]; + String[] tokens = clanReqs.split(","); + ClanRank rank; + int ordinal; + for (int i = 0; i < tokens.length; i++) { + ordinal = Integer.parseInt(tokens[i]); + if (ordinal < 0 || ordinal > ClanRank.values().length -1) { + continue; + } + rank = ClanRank.values()[ordinal]; + switch (i) { + case 0: + requirements[0] = rank; + break; + case 1: + requirements[1] = rank; + break; + case 2: + if (ordinal < 3 || ordinal > 8) { + requirements[2] = ClanRank.ADMINISTRATOR; + break; + } + requirements[2] = rank; + break; + case 3: + requirements[3] = rank; + break; + } + } + + return requirements; + } + + public static HashMap parseContacts(String contacts) { + HashMap theseContacts = new HashMap<>(); + String[] tokens; + if (!contacts.isEmpty()) { + String[] datas = contacts.split("~"); + Contact contact; + for (String d : datas) { + tokens = d.replace("{", "").replace("}", "").split(","); + if (tokens.length == 0) { + continue; + } + contact = new Contact(tokens[0]); + contact.setRank(ClanRank.values()[Integer.parseInt(tokens[1])]); + theseContacts.put(tokens[0], contact); + } + } + + return theseContacts; + } + + public String getContactString() { + StringBuilder sb = new StringBuilder(); + + int index = 0; + for (Contact contact : contacts.values()) { + sb.append("{"); + sb.append(contact.getUsername()); + sb.append(","); + sb.append(contact.getRank().ordinal()); + sb.append("}"); + if (index++ < contacts.size() - 1) sb.append("~"); + } + + return sb.toString(); + } + + public String getBlockedString() { + StringBuilder sb = new StringBuilder(); + + int index = 0; + for (String block : blocked) { + sb.append(block); + if (index++ < blocked.size() - 1) sb.append(","); + } + + return sb.toString(); + } + + public String getClanReqString() { + return + joinRequirement.ordinal() + + "," + messageRequirement.ordinal() + + "," + kickRequirement.ordinal() + + "," + lootRequirement.ordinal(); + } +} diff --git a/Server/src/main/core/game/system/communication/Contact.java b/Server/src/main/core/game/system/communication/Contact.java new file mode 100644 index 0000000..d6106d3 --- /dev/null +++ b/Server/src/main/core/game/system/communication/Contact.java @@ -0,0 +1,72 @@ +package core.game.system.communication; + +/** + * Represents a contact. + * @author Emperor + */ +public final class Contact { + + /** + * The username of the contact. + */ + private final String username; + + /** + * The world the contact is in. + */ + private int worldId; + + /** + * The contact's rank in the player's clan. + */ + private ClanRank rank = ClanRank.FRIEND; + + /** + * Constructs a new {@code Contact} {@code Object} + * @param username The username. + */ + public Contact(String username) { + this.username = username; + } + + /** + * Gets the worldId. + * @return the worldId + */ + public int getWorldId() { + return worldId; + } + + /** + * Sets the worldId. + * @param worldId the worldId to set. + */ + public void setWorldId(int worldId) { + this.worldId = worldId; + } + + /** + * Gets the rank. + * @return the rank + */ + public ClanRank getRank() { + return rank; + } + + /** + * Sets the rank. + * @param rank the rank to set. + */ + public void setRank(ClanRank rank) { + this.rank = rank; + } + + /** + * Gets the username. + * @return the username + */ + public String getUsername() { + return username; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/system/communication/GlobalChat.kt b/Server/src/main/core/game/system/communication/GlobalChat.kt new file mode 100644 index 0000000..6e8ed21 --- /dev/null +++ b/Server/src/main/core/game/system/communication/GlobalChat.kt @@ -0,0 +1,41 @@ +package core.game.system.communication + +import core.api.Commands +import core.api.getAttribute +import core.api.sendMessage +import core.api.setAttribute +import core.game.system.command.Privilege +import core.game.world.repository.Repository +import core.game.node.entity.player.info.Rights +import core.tools.colorize + +class GlobalChat : Commands { + override fun defineCommands() { + define("muteglobal", Privilege.STANDARD, "", "Toggles global chat on or off.") {player, _ -> + val original = getAttribute(player, ATTR_GLOBAL_MUTE, false) + setAttribute(player, ATTR_GLOBAL_MUTE, !original) + sendMessage(player, "Global chat is now ${if (original) "ON" else "OFF"}.") + return@define + } + } + + companion object { + val ATTR_GLOBAL_MUTE = "/save:globalmute" + fun process(sender: String, message: String, rights: Int) { + val msgSD = prepare(sender, message, false, rights) + val msgHD = prepare(sender, message, true, rights) + for (player in Repository.players.filter { !getAttribute(it, ATTR_GLOBAL_MUTE, false) }) { + if (player.interfaceManager.isResizable) + sendMessage(player, msgHD) + else + sendMessage(player, msgSD) + } + } + + private fun prepare(sender: String, message: String, isResizable: Boolean, rights: Int): String { + val baseColor = if (isResizable) "%f1b04c" else "%7512ff" + val bracketColor = if (isResizable) "%ffffff" else "%000000" + return colorize("$bracketColor[${baseColor}G$bracketColor] ${if (rights > 0) "" else ""}$sender: ${baseColor}$message") + } + } +} diff --git a/Server/src/main/core/game/system/config/ClueRewardParser.kt b/Server/src/main/core/game/system/config/ClueRewardParser.kt new file mode 100644 index 0000000..664de1b --- /dev/null +++ b/Server/src/main/core/game/system/config/ClueRewardParser.kt @@ -0,0 +1,53 @@ +package core.game.system.config + +import org.json.simple.JSONArray +import org.json.simple.JSONObject +import org.json.simple.parser.JSONParser + +import core.ServerConstants +import core.api.utils.WeightBasedTable +import core.api.utils.WeightedItem + +import java.io.FileReader + +class ClueRewardParser { + companion object { + @JvmStatic var easyTable = WeightBasedTable() + @JvmStatic var medTable = WeightBasedTable() + @JvmStatic var hardTable = WeightBasedTable() + @JvmStatic var rareTable = WeightBasedTable() + } + + + val parser = JSONParser() + var reader: FileReader? = null + + fun load() { + reader = FileReader(ServerConstants.CONFIG_PATH + "clue_rewards.json") + + val rawData = parser.parse(reader) as JSONObject + easyTable = parseClueTable(rawData["easy"] as JSONArray) + medTable = parseClueTable(rawData["medium"] as JSONArray) + hardTable = parseClueTable(rawData["hard"] as JSONArray) + rareTable = parseClueTable(rawData["rare"] as JSONArray) + } + + private fun parseClueTable(data: JSONArray) : WeightBasedTable { + val table = WeightBasedTable() + + for (element in data) { + val itemData = element as JSONObject + + table.add(WeightedItem( + itemData["id"].toString().toInt(), + itemData["minAmount"].toString().toInt(), + itemData["maxAmount"].toString().toInt(), + itemData["weight"].toString().toDouble(), + false + )) + + } + + return table + } +} diff --git a/Server/src/main/core/game/system/config/ConfigParser.kt b/Server/src/main/core/game/system/config/ConfigParser.kt new file mode 100644 index 0000000..db7e1b0 --- /dev/null +++ b/Server/src/main/core/game/system/config/ConfigParser.kt @@ -0,0 +1,60 @@ +package core.game.system.config + +import core.api.* + +import core.game.world.repository.Repository +import core.game.system.command.Privilege +import core.game.world.map.RegionManager +import core.game.node.item.GroundItemManager + +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch + +class ConfigParser : Commands { + fun prePlugin() { + NPCConfigParser().load() + ItemConfigParser().load() + ObjectConfigParser().load() + XteaParser().load() + InterfaceConfigParser().load() + } + fun postPlugin() { + ShopParser().load() + DropTableParser().load() + NPCSpawner().load() + DoorConfigLoader().load() + GroundSpawnLoader().load() + MusicConfigLoader().load() + RangedConfigLoader().load() + CustomVarbitParser().load() + ClueRewardParser().load() + } + + fun reloadConfigs(callback: () -> Unit) { + GlobalScope.launch { + Repository.npcs.toTypedArray().forEach { npc -> + npc.isRespawn = false + npc.clear() + Repository.npcs.remove(npc) + Repository.removeRenderableNPC(npc) + } + + GroundItemManager.getItems().toTypedArray().forEach {gi -> + GroundItemManager.getItems().remove(gi) + RegionManager.getRegionPlane(gi.location).remove(gi) + } + + prePlugin() + postPlugin() + + callback.invoke() + } + } + + override fun defineCommands() { + define("reloadjson", Privilege.ADMIN, "", "Reloads all the JSON configs.") { player, _ -> + notify(player, "Reloading JSON...") + reloadConfigs() { notify(player, "JSON reloaded.") } + } + } +} diff --git a/Server/src/main/core/game/system/config/CustomVarbitParser.kt b/Server/src/main/core/game/system/config/CustomVarbitParser.kt new file mode 100644 index 0000000..bf46474 --- /dev/null +++ b/Server/src/main/core/game/system/config/CustomVarbitParser.kt @@ -0,0 +1,37 @@ +package core.game.system.config + +import core.cache.def.impl.VarbitDefinition +import org.json.simple.JSONArray +import org.json.simple.JSONObject +import org.json.simple.parser.JSONParser +import core.ServerConstants +import core.api.log +import core.tools.Log +import core.tools.SystemLogger +import java.io.FileReader + +class CustomVarbitParser { + val parser = JSONParser() + var reader: FileReader? = null + + fun load() { + var count = 0 + + reader = FileReader(ServerConstants.CONFIG_PATH + "varbit_definitions.json") + val array = parser.parse(reader) as JSONArray + + for (jObject in array) { + val varbitDef = jObject as JSONObject + + val varpId = varbitDef["varpId"].toString().toInt() + val varbitId = varbitDef["varbitId"].toString().toInt() + val startBit = varbitDef["startBit"].toString().toInt() + val endBit = varbitDef["endBit"].toString().toInt() + + VarbitDefinition.create(varpId, varbitId, startBit, endBit) + count++ + } + + log(this::class.java, Log.FINE, "Parsed $count custom varbit definitions.") + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/system/config/DoorConfigLoader.kt b/Server/src/main/core/game/system/config/DoorConfigLoader.kt new file mode 100644 index 0000000..04d23c9 --- /dev/null +++ b/Server/src/main/core/game/system/config/DoorConfigLoader.kt @@ -0,0 +1,107 @@ +package core.game.system.config + +import core.ServerConstants +import core.api.log +import core.tools.Log +import core.tools.SystemLogger +import org.json.simple.JSONArray +import org.json.simple.JSONObject +import org.json.simple.parser.JSONParser +import java.io.FileReader + +class DoorConfigLoader { + companion object { + val DOORS = hashMapOf() + + fun forId(id: Int): Door?{ + return DOORS[id] + } + } + val parser = JSONParser() + var reader: FileReader? = null + + fun load(){ + var count = 0 + reader = FileReader(ServerConstants.CONFIG_PATH + "door_configs.json") + var configs = parser.parse(reader) as JSONArray + for(config in configs){ + val e = config as JSONObject + val door = Door(e["id"].toString().toInt()) + door.replaceId = e["replaceId"].toString().toInt() + door.isFence = e["fence"].toString().toBoolean() + door.isMetal = e["metal"].toString().toBoolean() + door.isAutoWalk = e["autowalk"]?.toString()?.toBoolean() ?: false + DOORS[door.id] = door + val replacedDoor = Door(door.replaceId) + replacedDoor.replaceId = door.id + replacedDoor.isFence = door.isFence + replacedDoor.isMetal = door.isMetal + replacedDoor.isAutoWalk = door.isAutoWalk + DOORS[door.replaceId] = replacedDoor + count++ + } + log(this::class.java, Log.FINE, "Parsed $count door configs.") + } + + + class Door + /** + * Constructs a new `DoorManager` `Object`. + */( + /** + * The door's object id. + */ + val id: Int) { + /** + * Gets the id. + * @return The id. + */ + + /** + * Gets the replaceId. + * @return The replaceId. + */ + /** + * Sets the replaceId. + * @param replaceId The replaceId to set. + */ + /** + * The door's replace object id. + */ + var replaceId = 0 + + /** + * Gets the fence. + * @return The fence. + */ + /** + * Sets the fence. + * @param fence The fence to set. + */ + /** + * If the door is closed. + */ + var isFence = false + + /** + * Gets the autoWalk. + * @return The autoWalk. + */ + /** + * Sets the autoWalk. + * @param autoWalk The autoWalk to set. + */ + /** + * If the player should automatically walk through it. + */ + var isAutoWalk = false + + /** + * Is the door metal? + */ + var isMetal = false + + var questRequirement = "" + + } +} diff --git a/Server/src/main/core/game/system/config/DropTableParser.kt b/Server/src/main/core/game/system/config/DropTableParser.kt new file mode 100644 index 0000000..465a1c6 --- /dev/null +++ b/Server/src/main/core/game/system/config/DropTableParser.kt @@ -0,0 +1,64 @@ +package core.game.system.config + +import core.cache.def.impl.NPCDefinition +import org.json.simple.JSONArray +import org.json.simple.JSONObject +import org.json.simple.parser.JSONParser +import core.ServerConstants +import core.api.* +import core.api.utils.* +import core.tools.Log +import core.tools.SystemLogger +import java.io.FileReader + + +class DropTableParser { + val parser = JSONParser() + var reader: FileReader? = null + fun load(){ + var count = 0 + reader = FileReader(ServerConstants.CONFIG_PATH + "drop_tables.json") + val obj = parser.parse(reader) as JSONArray + for(i in obj){ + val tab = i as JSONObject + val ids = tab["ids"].toString().split(",") + + try { + val table = NPCDropTable() + parseTable(tab["main"] as JSONArray, table, isAlways = false) + parseTable(tab["charm"] as JSONArray, table, isAlways = false, isCharms = true) + (tab["tertiary"] as? JSONArray)?.let { parseTable(it, table, isAlways = false, isTertiary = true) } + parseTable(tab["default"] as JSONArray, table, true) + + for(n in ids){ + val def = NPCDefinition.forId(n.toInt()).dropTables + def ?: continue + def.table = table + count++ + } + } catch (e: ConfigParseException) { + log (this::class.java, Log.ERR, "Error parsing drop tables for NPC ${NPCDefinition.forId(ids[0].toInt()).name}: ${exceptionToString(e)}") + } + } + log(this::class.java, Log.FINE, "Parsed $count drop tables.") + } + + private fun parseTable(data: JSONArray, destTable: NPCDropTable, isAlways: Boolean, isTertiary: Boolean = false, isCharms: Boolean = false) { + for(it in data){ + val item = it as JSONObject + val id = item["id"].toString().toInt() + val minAmount = item["minAmount"].toString().toInt() + val maxAmount = item["maxAmount"].toString().toInt() + + if (minAmount > maxAmount) { + throw ConfigParseException("Table is invalid! Specified minimum amount is > specified maximum amount.") + } + + val weight = item["weight"].toString().toDouble() + val newItem = WeightedItem(id,minAmount,maxAmount,weight.toDouble(),isAlways) + if(isCharms) destTable.addToCharms(newItem) + else if (isTertiary) destTable.addToTertiary(newItem) + else destTable.add(newItem) + } + } +} diff --git a/Server/src/main/core/game/system/config/GroundSpawnLoader.kt b/Server/src/main/core/game/system/config/GroundSpawnLoader.kt new file mode 100644 index 0000000..cbf5dab --- /dev/null +++ b/Server/src/main/core/game/system/config/GroundSpawnLoader.kt @@ -0,0 +1,116 @@ +package core.game.system.config + +import core.game.node.item.GroundItem +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import core.game.system.task.Pulse +import core.game.world.map.Location +import org.json.simple.JSONArray +import org.json.simple.JSONObject +import org.json.simple.parser.JSONParser +import core.ServerConstants +import core.api.log +import core.game.world.GameWorld +import core.game.world.repository.Repository +import core.tools.Log +import java.io.* + +class GroundSpawnLoader { + val parser = JSONParser() + var reader: FileReader? = null + + fun load() { + var count = 0 + reader = FileReader(ServerConstants.CONFIG_PATH + "ground_spawns.json") + var configs = parser.parse(reader) as JSONArray + for(config in configs){ + try { + val e = config as JSONObject + val datas = e["loc_data"].toString().split("-") + val id = e["item_id"].toString().toInt() + for(d in datas){ + if (d.isNullOrEmpty()) continue + val tokens = d.replace("{", "").replace("}", "").split(",".toRegex()).toTypedArray() + val spawn = GroundSpawn(tokens[4].toInt(), Item(id, tokens[0].toInt()), Location(Integer.valueOf(tokens[1]), Integer.valueOf(tokens[2]), Integer.valueOf(tokens[3]))) + spawn.init() + count++ + } + } catch (e: Exception) { + val sw = StringWriter() + val pw = PrintWriter(sw) + e.printStackTrace(pw) + log(this::class.java, Log.ERR, "Error parsing config entry ${config.toString()}: $sw") + } + } + log(this::class.java, Log.FINE, "Initialized $count ground items.") + } + class GroundSpawn + /** + * Constructs a new `GroundItemParser` `Object`. + * @param item the item. + * @param location the location. + */( + /** + * Represents the rate at which a ground item will respawn. + */ + var respawnRate: Int, item: Item?, location: Location?) : GroundItem(item, location) { + /** + * Gets the respawn rate. + * @return the rate. + */ + + override fun toString(): String { + return "GroundSpawn [name=" + getName() + ", respawnRate=" + respawnRate + ", loc=" + getLocation() + "]" + } + + /** + * Method used to initialize this spawn. + */ + fun init(): GroundItem { + return GroundItemManager.create(this) + } + + override fun isActive(): Boolean { + return true + } + + override fun isPrivate(): Boolean { + return false + } + + override fun isAutoSpawn(): Boolean { + return true + } + + override fun respawn() { + GameWorld.Pulser.submit(object : Pulse(respawnDuration) { + override fun pulse(): Boolean { + GroundItemManager.create(this@GroundSpawn) + return true + } + }) + } + + /** + * Method used to set the respawn rate. + * @param min the min. + * @param max the max. + */ + fun setRespawnRate(min: Int, max: Int) { + respawnRate = min or max shl 16 + } + + /** + * Gets the current respawn duration (in ticks). + * @return The respawn duration. + */ + val respawnDuration: Int + get() { + val minimum = respawnRate and 0xFFFF + val maximum = respawnRate shr 16 and 0xFFFF + val playerRatio = ServerConstants.MAX_PLAYERS / Repository.players.size.toDouble() + return (minimum + (maximum - minimum) / playerRatio).toInt() + } + + } +} diff --git a/Server/src/main/core/game/system/config/InterfaceConfigParser.kt b/Server/src/main/core/game/system/config/InterfaceConfigParser.kt new file mode 100644 index 0000000..d691bd1 --- /dev/null +++ b/Server/src/main/core/game/system/config/InterfaceConfigParser.kt @@ -0,0 +1,31 @@ +package core.game.system.config + +import core.ServerConstants +import core.api.log +import core.game.component.ComponentDefinition +import core.tools.Log +import core.tools.SystemLogger +import org.json.simple.JSONArray +import org.json.simple.JSONObject +import org.json.simple.parser.JSONParser +import java.io.FileReader + +class InterfaceConfigParser{ + val parser = JSONParser() + var reader: FileReader? = null + fun load() { + var count = 0 + reader = FileReader(ServerConstants.CONFIG_PATH + "interface_configs.json") + val configlist = parser.parse(reader) as JSONArray + for(config in configlist){ + val e = config as JSONObject + val id = e["id"].toString().toInt() + if (ComponentDefinition.getDefinitions().containsKey(id)) { + ComponentDefinition.getDefinitions()[id]!!.parse(e["interfaceType"].toString(),e["walkable"].toString(),e["tabIndex"].toString()) + } + ComponentDefinition.getDefinitions()[id] = ComponentDefinition().parse(e["interfaceType"].toString(),e["walkable"].toString(),e["tabIndex"].toString()) + count++ + } + log(this::class.java, Log.FINE, "Parsed $count interface configs.") + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/system/config/ItemConfigParser.kt b/Server/src/main/core/game/system/config/ItemConfigParser.kt new file mode 100644 index 0000000..3964596 --- /dev/null +++ b/Server/src/main/core/game/system/config/ItemConfigParser.kt @@ -0,0 +1,314 @@ +package core.game.system.config + +import core.cache.def.impl.ItemDefinition +import core.game.node.entity.impl.Animator +import core.game.node.entity.player.link.audio.Audio +import core.game.world.update.flag.context.Animation +import org.json.simple.JSONArray +import org.json.simple.JSONObject +import org.json.simple.parser.JSONParser +import core.ServerConstants +import core.api.log +import core.tools.Log +import core.tools.SystemLogger +import java.io.FileReader + +class ItemConfigParser { + companion object{ + /** + * The tradeable item configuration key. + */ + const val TRADEABLE = "tradeable" + + /** + * The lendable item configuration key. + */ + const val LENDABLE = "lendable" + + /** + * If the item is spawnable. + */ + const val SPAWNABLE = "spawnable" + + /** + * The destroy item configuration key. + */ + const val DESTROY = "destroy" + + /** + * The two-handed item configuration key. + */ + const val TWO_HANDED = "two_handed" + + /** + * The alchemisable configuration key. + */ + const val ALCHEMIZABLE = "alchemizable" + + /** + * The high-alchemy price item configuration key. + */ + const val HIGH_ALCHEMY = "high_alchemy" + + /** + * The low-alchemy price item configuration key. + */ + const val LOW_ALCHEMY = "low_alchemy" + + /** + * The shop price item configuration key. + */ + const val SHOP_PRICE = "shop_price" + + /** + * The grand exchange price item configuration key. + */ + const val GE_PRICE = "grand_exchange_price" + + /** + * The examine item configuration key. + */ + const val EXAMINE = "examine" + + /** + * The weight item configuration key. + */ + const val WEIGHT = "weight" + + /** + * The bonuses item configuration key. + */ + const val BONUS = "bonuses" + + /** + * The absorb item configuration key. + */ + const val ABSORB = "absorb" + + /** + * The equipment slot item configuration key. + */ + const val EQUIP_SLOT = "equipment_slot" + + /** + * The attack speed item configuration key. + */ + const val ATTACK_SPEED = "attack_speed" + + /** + * The remove hair item configuration key. + */ + const val REMOVE_HEAD = "remove_head" + + const val IS_HAT = "hat" + + /** + * The remove beard item configuration key. + */ + const val REMOVE_BEARD = "remove_beard" + + /** + * The remove sleeves item configuration key. + */ + const val REMOVE_SLEEVES = "remove_sleeves" + + /** + * The stand anim item configuration key. + */ + const val STAND_ANIM = "stand_anim" + + /** + * The stand-run anim item configuration key. + */ + const val STAND_TURN_ANIM = "stand_turn_anim" + + /** + * The walk anim item configuration key. + */ + const val WALK_ANIM = "walk_anim" + + /** + * The run anim item configuration key. + */ + const val RUN_ANIM = "run_anim" + + /** + * The turn 180 anim item configuration key. + */ + const val TURN180_ANIM = "turn180_anim" + + /** + * The turn 90cw anim item configuration key. + */ + const val TURN90CW_ANIM = "turn90cw_anim" + + /** + * The turn 90ccw anim item configuration key. + */ + const val TURN90CCW_ANIM = "turn90ccw_anim" + + /** + * The weapon interface. + */ + const val WEAPON_INTERFACE = "weapon_interface" + + /** + * If the item has a special attack bar. + */ + const val HAS_SPECIAL = "has_special" + + /** + * The item's attack animations. + */ + const val ATTACK_ANIMS = "attack_anims" + + /** + * The items destroy message. + */ + const val DESTROY_MESSAGE = "destroy_message" + + /** + * The requirements. + */ + const val REQUIREMENTS = "requirements" + + /** + * The grand exchange buying limit attribute key. + */ + const val GE_LIMIT = "ge_buy_limit" + + /** + * The defence animation key. + */ + const val DEFENCE_ANIMATION = "defence_anim" + + /** + * The attack sound key. + */ + const val ATTACK_AUDIO = "attack_audios" + + /** + * The equip sound key + */ + const val EQUIP_AUDIO = "equip_audio" + + /** + * The point price. + */ + const val POINT_PRICE = "point_price" + + /** + * If the item is bankable. + */ + const val BANKABLE = "bankable" + + /** + * If the item is a rare item. + */ + const val RARE_ITEM = "rare_item" + + /** + * The tokkul price of an item. + */ + const val TOKKUL_PRICE = "tokkul_price" + + /** + * The render animation id of an item. + */ + const val RENDER_ANIM_ID = "render_anim" + + /** + * the archery ticket price of an item. + */ + const val ARCHERY_TICKET_PRICE = "archery_ticket_price" + + /** + * The Castle Wars Ticket price of items (in Lanthas' shop). + */ + const val CASTLE_WARS_TICKET_PRICE = "castle_wars_ticket_price" + + } + + val parser = JSONParser() + var reader: FileReader? = null + fun load(){ + var count = 0 + reader = FileReader(ServerConstants.CONFIG_PATH + "item_configs.json") + val configlist = parser.parse(reader) as JSONArray + for(config in configlist){ + val e = config as JSONObject + val def = ItemDefinition.forId(e["id"].toString().toInt()) + val configs = def.handlers + val requirements = HashMap() + e.map { + if (it.value.toString().isNotEmpty() && it.value.toString() != "null") { + when (it.key.toString()) { + //Special cases + "defence_anim" -> configs.put(it.key.toString(), Animation(it.value.toString().toInt(), Animator.Priority.HIGH)) + "requirements" -> { configs.put(it.key.toString(),requirements) + it.value.toString() + .split("-") + .map { + en -> val tokens = en.replace("{", "").replace("}", "").split(",") + requirements.put(tokens[0].toInt(),tokens[1].toInt()) + } + } + "attack_audios" -> configs.put(it.key.toString(),it.value.toString().split(",").map { i -> Audio(i.toInt()) }.toTypedArray()) + "attack_anims" -> configs.put(it.key.toString(),it.value.toString().split(",").map { i -> Animation(i.toInt(), Animator.Priority.HIGH) }.toTypedArray()) + + //int arrays + "absorb", + "bonuses" -> configs.put(it.key.toString(),it.value.toString().split(",").map { i -> i.toInt() }.toIntArray()) + + //booleans + "fun_weapon", + "rare_item", + "bankable", + "two_handed", + "has_special", + "remove_sleeves", + "remove_beard", + "remove_head", + "hat", + "destroy", + "lendable", + "tradeable" -> configs.put(it.key.toString(),it.value.toString().toBoolean()) + "alchemizable", -> configs.put(it.key.toString(),it.value.toString().toBoolean()) + + //doubles + "weight" -> configs.put(it.key.toString(),it.value.toString().toDouble()) + + //ints + "equip_audio", + "point_price", + TOKKUL_PRICE, + ARCHERY_TICKET_PRICE, + CASTLE_WARS_TICKET_PRICE, + "ge_buy_limit", + "weapon_interface", + "attack_speed", + "equipment_slot", + "render_anim", + "turn90ccw_anim", + "turn90cw_anim", + "turn180_anim", + "run_anim", + "walk_anim", + "stand_anim", + "low_alchemy", + "high_alchemy", + "grand_exchange_price", + "id" -> configs.put(it.key.toString(),it.value.toString().toInt()) + + //Strings + "examine", + "destroy_message", + "name" -> configs.put(it.key.toString(),it.value.toString()) + } + } + } + count++ + } + log(this::class.java, Log.FINE, "Parsed $count item configs.") + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/system/config/MusicConfigLoader.kt b/Server/src/main/core/game/system/config/MusicConfigLoader.kt new file mode 100644 index 0000000..3f5cc60 --- /dev/null +++ b/Server/src/main/core/game/system/config/MusicConfigLoader.kt @@ -0,0 +1,83 @@ +package core.game.system.config + +import core.cache.def.impl.DataMap +import core.ServerConstants +import core.api.log +import core.game.node.entity.player.link.music.MusicEntry +import core.game.node.entity.player.link.music.MusicZone +import core.tools.SystemLogger +import core.game.world.map.RegionManager +import core.game.world.map.zone.ZoneBorders +import core.tools.Log +import org.json.simple.JSONArray +import org.json.simple.JSONObject +import org.json.simple.parser.JSONParser +import java.io.FileReader + +class MusicConfigLoader { + //1351 -> buttonID:songID + //1345 -> buttonID:songName (capitalized) + //1347 -> buttonID:songName (lowercase) + + val parser = JSONParser() + var reader: FileReader? = null + fun load(){ + // Populate the server data map + val songs = DataMap.get(1351) + val names = DataMap.get(1345) + + for((index, songId) in songs.dataStore) + { + val entry = MusicEntry(songId as Int, names.getString(index as Int), index) + MusicEntry.getSongs().putIfAbsent(songId, entry) + } + + // Parse the region-wide music config file + var count = 0 + reader = FileReader(ServerConstants.CONFIG_PATH + "music_regions.json") + var configs = parser.parse(reader) as JSONArray + for(config in configs) { + val e = config as JSONObject + val region = Integer.parseInt(e["region"].toString()) + val id = Integer.parseInt(e["id"].toString()) + RegionManager.forId(region).music = id + count++ + } + log(this::class.java, Log.FINE, "Parsed $count region music configs.") + + // Parse the file with tile-specific music locations + count = 0 + reader = FileReader(ServerConstants.CONFIG_PATH + "music_tiles.json") + configs = parser.parse(reader) as JSONArray + for(config in configs) { + val e = config as JSONObject + val musicId = Integer.parseInt(e["id"].toString()) + val string = e["borders"].toString() + val borderArray = string.split("-") + var tokens: Array? = null + var borders: ZoneBorders? = null + for (border in borderArray) { + tokens = border.replace("{", "").replace("}", "").split(",").toTypedArray() + borders = ZoneBorders(tokens[0].toInt(), tokens[1].toInt(), tokens[2].toInt(), tokens[3].toInt()) + if (border.contains("[")) { //no exception borders + var exceptions: String? = "" + for (i in 4 until tokens.size) { + exceptions += tokens[i] + if (!tokens[i].contains("]~")) "," else if (tokens[i].contains("[")) "," else "" + } + tokens = exceptions!!.split("~".toRegex()).toTypedArray() + var e: Array? = null + for (exception in tokens) { + e = exception.replace("[", "").replace("]", "").split(",".toRegex()).toTypedArray() + borders.addException(ZoneBorders(e[0].toInt(), e[1].toInt(), e[2].toInt(), e[3].toInt())) + } + } + val zone = MusicZone(musicId, borders) + for (id in borders.getRegionIds()) { + RegionManager.forId(id!!).musicZones.add(zone) + } + } + count++ + } + log(this::class.java, Log.FINE, "Parsed $count tile music configs.") + } +} diff --git a/Server/src/main/core/game/system/config/NPCConfigParser.kt b/Server/src/main/core/game/system/config/NPCConfigParser.kt new file mode 100644 index 0000000..292c682 --- /dev/null +++ b/Server/src/main/core/game/system/config/NPCConfigParser.kt @@ -0,0 +1,272 @@ +package core.game.system.config + +import core.ServerConstants +import core.cache.def.impl.NPCDefinition +import content.global.activity.ttrail.ClueLevel +import core.api.log +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.impl.Animator +import core.tools.SystemLogger +import core.game.world.update.flag.context.Animation +import core.tools.Log +import org.json.simple.JSONArray +import org.json.simple.JSONObject +import org.json.simple.parser.JSONParser +import java.io.FileReader + +class +NPCConfigParser { + companion object{ + const val WEAKNESS = "weakness" + + /** + * The lifepoints attribute. + */ + const val LIFEPOINTS = "lifepoints" + + /** + * The attack level attribute. + */ + const val ATTACK_LEVEL = "attack_level" + + /** + * The strength level attribute. + */ + const val STRENGTH_LEVEL = "strength_level" + + /** + * The defence level attribute. + */ + const val DEFENCE_LEVEL = "defence_level" + + /** + * The range level attribute. + */ + const val RANGE_LEVEL = "range_level" + + /** + * The range level attribute. + */ + const val MAGIC_LEVEL = "magic_level" + + /** + * The examine attribute. + */ + const val EXAMINE = "examine" + + /** + * The slayer task attribute. + */ + const val SLAYER_TASK = "slayer_task" + + /** + * The poisonous attribute. + */ + const val POISONOUS = "poisonous" + + /** + * The aggressive attribute. + */ + const val AGGRESSIVE = "aggressive" + + /** + * The respawn delay attribute. + */ + const val RESPAWN_DELAY = "respawn_delay" + + /** + * The attack speed attribute. + */ + const val ATTACK_SPEED = "attack_speed" + + /** + * The poison immune attribute. + */ + const val POISON_IMMUNE = "poison_immune" + + /** + * The bonuses attribute. + */ + const val BONUSES = "bonuses" + + /** + * The start graphic attribute. + */ + const val START_GRAPHIC = "start_gfx" + + /** + * The projectile attribute. + */ + const val PROJECTILE = "projectile" + + /** + * The end graphic attribute. + */ + const val END_GRAPHIC = "end_gfx" + + /** + * The combat style attribute. + */ + const val COMBAT_STYLE = "combat_style" + + /** + * The aggressive radius attribute. + */ + const val AGGRESSIVE_RADIUS = "agg_radius" + + /** + * The slayer experience attribute. + */ + const val SLAYER_EXP = "slayer_exp" + + /** + * The amount to poison. + */ + const val POISON_AMOUNT = "poison_amount" + + /** + * The movement radius. + */ + const val MOVEMENT_RADIUS = "movement_radius" + + /** + * The spawn animation. + */ + const val SPAWN_ANIMATION = "spawn_animation" + + /** + * The start height. + */ + const val START_HEIGHT = "start_height" + + /** + * The projectile height. + */ + const val PROJECTILE_HEIGHT = "prj_height" + + /** + * The end height. + */ + const val END_HEIGHT = "end_height" + + /** + * The clue level. + */ + const val CLUE_LEVEL = "clue_level" + + /** + * The spell id. + */ + const val SPELL_ID = "spell_id" + + /** + * The combat audio. + */ + const val COMBAT_AUDIO = "combat_audio" + + /** + * The melee-attack anim. + */ + const val MELEE_ANIMATION = "melee_animation" + + /** + * The defence anim. + */ + const val DEFENCE_ANIMATION = "defence_animation" + + /** + * The death anim. + */ + const val DEATH_ANIMATION = "death_animation" + + /** + * The range anim. + */ + const val RANGE_ANIMATION = "range_animation" + + /** + * The magic anim. + */ + const val MAGIC_ANIMATION = "magic_animation" + + /** + * The combat style protected from. + */ + const val PROTECT_STYLE = "protect_style" + + } + val parser = JSONParser() + var reader: FileReader? = null + fun load(){ + var count = 0 + reader = FileReader(ServerConstants.CONFIG_PATH + "npc_configs.json") + val configlist = parser.parse(reader) as JSONArray + for(config in configlist){ + val e = config as JSONObject + val def = NPCDefinition.forId(e["id"].toString().toInt()) + val configs = def.handlers + e.map { + if(it.value.toString().isNotEmpty() && it.value.toString() != "null") { + when (it.key.toString()) { + //animations + "melee_animation", + "range_animation", + "magic_animation", + "death_animation", + "defence_animation" -> configs.put(it.key.toString(), Animation(it.value.toString().toInt(), Animator.Priority.HIGH)) + + //combat/protect style + "combat_style", + "protect_style" -> configs.put(it.key.toString(), CombatStyle.values()[it.value.toString().toInt()]) + + + "clue_level" -> configs.put(it.key.toString(), ClueLevel.values()[it.value.toString().toInt()]) + "name", "examine" -> configs.put(it.key.toString(), it.value.toString()) + "combat_audio", "bonuses" -> configs.put(it.key.toString(), it.value.toString().split(",").map { v -> v.toInt() }.toIntArray()) + "force_talk" -> configs.put(it.key.toString(),it.value.toString()) + + //ints + "spawn_animation", + "id", + "lifepoints", + "attack_level", + "strength_level", + "defence_level", + "range_level", + "movement_radius", + "agg_radius", + "attack_speed", + "poison_amount", + "respawn_delay", + "start_gfx", + "projectile", + "end_gfx", + "weakness", + "slayer_task", + "start_height", + "prj_height", + "end_height", + "spell_id", + "death_gfx", + "magic_level" -> configs.put(it.key.toString(), if (it.value.toString().isEmpty()) Unit else it.value.toString().toInt()) + + //doubles + "slayer_exp" -> configs.put(it.key.toString(), it.value.toString().toDouble()) + + //booleans + "safespot", + "aggressive", + "poisonous", + "poison_immune", + "facing_booth", + "can_tolerate", + "water_npc"-> configs.put(it.key.toString(), it.value.toString().toBoolean()) + else -> log(this::class.java, Log.WARN, "Unhandled key for npc config: ${it.key.toString()}") + } + } + } + count++ + } + log(this::class.java, Log.FINE, "Parsed $count NPC configurations") + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/system/config/NPCSpawner.kt b/Server/src/main/core/game/system/config/NPCSpawner.kt new file mode 100644 index 0000000..958b3e2 --- /dev/null +++ b/Server/src/main/core/game/system/config/NPCSpawner.kt @@ -0,0 +1,45 @@ +package core.game.system.config + +import core.ServerConstants +import core.api.log +import core.game.node.entity.npc.NPC +import core.tools.SystemLogger +import core.game.world.map.Direction +import core.game.world.map.Location +import core.tools.Log +import org.json.simple.JSONArray +import org.json.simple.JSONObject +import org.json.simple.parser.JSONParser +import java.io.FileReader + +class NPCSpawner { + val parser = JSONParser() + var reader: FileReader? = null + fun load(){ + var count = 0 + reader = FileReader(ServerConstants.CONFIG_PATH + "npc_spawns.json") + val configs = parser.parse(reader) as JSONArray + for(config in configs){ + val e = config as JSONObject + val datas: Array = e["loc_data"].toString().split("-".toRegex()).toTypedArray() + var tokens: Array? = null + val id = e["npc_id"].toString().toInt() + for (d in datas) { + if(d.isEmpty()){ + continue + } + tokens = d.replace("{", "").replace("}", "").split(",".toRegex()).toTypedArray() + val npc = NPC.create(id, Location.create(Integer.valueOf(tokens[0].trim { it <= ' ' }), Integer.valueOf(tokens[1].trim { it <= ' ' }), Integer.valueOf(tokens[2].trim { it <= ' ' }))) + npc.isWalks = tokens[3].trim { it <= ' ' } == "1" + npc.direction = Direction.values()[Integer.valueOf(tokens[4].trim { it <= ' ' })] + npc.setAttribute("spawned:npc", true) + if(npc.definition.getConfiguration("facing_booth",false)){ + npc.setAttribute("facing_booth",true) + } + npc.init() + count++ + } + } + log(this::class.java, Log.FINE, "Spawned $count NPCs") + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/system/config/ObjectConfigParser.kt b/Server/src/main/core/game/system/config/ObjectConfigParser.kt new file mode 100644 index 0000000..0445909 --- /dev/null +++ b/Server/src/main/core/game/system/config/ObjectConfigParser.kt @@ -0,0 +1,43 @@ +package core.game.system.config + +import core.ServerConstants +import core.api.log +import core.cache.def.impl.SceneryDefinition +import core.tools.Log +import core.tools.SystemLogger +import org.json.simple.JSONArray +import org.json.simple.JSONObject +import org.json.simple.parser.JSONParser +import java.io.FileReader + +class ObjectConfigParser { + val parser = JSONParser() + var reader: FileReader? = null + fun load(){ + var count = 0 + reader = FileReader(ServerConstants.CONFIG_PATH + "object_configs.json") + val configlist = parser.parse(reader) as JSONArray + for(config in configlist){ + val e = config as JSONObject + val ids = e["ids"].toString().split(",").map { it.toInt() } + for (id in ids) { + val def = SceneryDefinition.forId(id) + val configs = def.handlers + e.map { + if (it.value.toString().isNotEmpty() && it.value.toString() != "null") { + when (it.key.toString()) { + //Strings + "examine" -> configs.put(it.key.toString(), it.value.toString()) + + //Animations + "render_anim" -> def.animationId = it.value.toString().toInt() + } + } + } + count++ + } + } + log(this::class.java, Log.FINE, "Parsed $count object configs.") + } +} + diff --git a/Server/src/main/core/game/system/config/RangedConfigLoader.kt b/Server/src/main/core/game/system/config/RangedConfigLoader.kt new file mode 100644 index 0000000..6c54cbd --- /dev/null +++ b/Server/src/main/core/game/system/config/RangedConfigLoader.kt @@ -0,0 +1,81 @@ +package core.game.system.config + +import core.ServerConstants +import core.api.log +import core.cache.def.impl.ItemDefinition +import core.game.node.entity.combat.equipment.Ammunition +import core.game.node.entity.combat.equipment.BoltEffect +import core.game.node.entity.combat.equipment.RangeWeapon +import core.game.node.entity.impl.Projectile +import core.game.node.entity.npc.NPC +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import core.tools.Log +import org.json.simple.JSONArray +import org.json.simple.JSONObject +import org.json.simple.parser.JSONParser +import java.io.FileReader + +class RangedConfigLoader { + val parser = JSONParser() + var reader: FileReader? = null + + fun load(){ + var count = 0 + reader = FileReader(ServerConstants.CONFIG_PATH + "ammo_configs.json") + var configs = parser.parse(reader) as JSONArray + for(entry in configs){ + val e = entry as JSONObject + var dbowgfx: Graphics? = null + val projectile = e["projectile"].toString().split(",") + if(e["darkbow_graphic"].toString().isNotBlank()){ + val darkbow = e["darkbow_graphic"].toString().split(",") + dbowgfx = Graphics(Integer.parseInt(darkbow[0]),Integer.parseInt(darkbow[1])) + } + val gfx = e["start_graphic"].toString().split(",") + val ammo = Ammunition( + Integer.parseInt(e["itemId"] as String), + Graphics(Integer.parseInt(gfx[0]),Integer.parseInt(gfx[1])), + dbowgfx, + Projectile.create( + NPC(0, Location(0,0,0)), + NPC(0,Location(0,0,0)), + Integer.parseInt(projectile[0]), + Integer.parseInt(projectile[1]), + Integer.parseInt(projectile[2]), + Integer.parseInt(projectile[3]), + Integer.parseInt(projectile[4]), + Integer.parseInt(projectile[5]), + Integer.parseInt(projectile[6])), + Integer.parseInt(e["poison_damage"].toString())) + val effect = BoltEffect.forId(Integer.parseInt(e["itemId"].toString())) + if (effect != null) { + ammo.effect = effect + } + Ammunition.getAmmunition().put(Integer.parseInt(e["itemId"].toString()),ammo) + count++ + } + log(this::class.java, Log.FINE, "Parsed $count ammo configs...") + + count = 0 + reader = FileReader(ServerConstants.CONFIG_PATH + "ranged_weapon_configs.json") + configs = parser.parse(reader) as JSONArray + for(entry in configs){ + val e = entry as JSONObject + val id = Integer.parseInt(e["itemId"].toString()) + val weapon = RangeWeapon( + id, + Animation(Integer.parseInt(e["animation"].toString())), + ItemDefinition.forId(id).getConfiguration("attack_speed",4), + Integer.parseInt(e["ammo_slot"].toString()), + Integer.parseInt(e["weapon_type"].toString()), + (e["drop_ammo"].toString().toBoolean()), + e["ammunition"].toString().split(",").map { Integer.parseInt(it) } + ) + RangeWeapon.getRangeWeapons().putIfAbsent(weapon.itemId,weapon) + count++ + } + log(this::class.java, Log.FINE, "Parsed $count ranged weapon configs...") + } +} diff --git a/Server/src/main/core/game/system/config/ServerConfigParser.kt b/Server/src/main/core/game/system/config/ServerConfigParser.kt new file mode 100644 index 0000000..69c660f --- /dev/null +++ b/Server/src/main/core/game/system/config/ServerConfigParser.kt @@ -0,0 +1,219 @@ +package core.game.system.config + +import com.moandjiezana.toml.Toml +import core.ServerConstants +import core.api.log +import core.api.parseEnumEntry +import core.game.world.GameSettings +import core.game.world.GameWorld +import core.game.world.map.Location +import core.tools.Log +import core.tools.LogLevel +import core.tools.mysql.Database +import java.io.File +import java.net.URL +import kotlin.system.exitProcess + +/** + * Class for parsing the server config, I.E default.toml + * @param path the path to the TOML file to parse. + * @author Ceikry + */ +object ServerConfigParser { + var confFile: File? = null + var tomlData: Toml? = null + + fun parse(path: String){ + confFile = File(parsePath(path)) + parseFromFile(confFile) + } + + fun parse(path: URL?) { + confFile = File(path!!.toURI()) + parseFromFile(confFile) + } + + private fun parseFromFile(confFile: File?) { + if(!confFile!!.canonicalFile.exists()){ + log(this::class.java, Log.ERR, "${confFile.canonicalFile} does not exist.") + exitProcess(0) + } else { + try { + tomlData = Toml().read(confFile) + parseServerSettings() + parseGameSettings() + val jvmString = System.getProperty("java.version") + if (jvmString.startsWith("1.")) { + ServerConstants.JAVA_VERSION = jvmString.substring(2,3).toInt() + } else if (!jvmString.startsWith("1.")) { + ServerConstants.JAVA_VERSION = jvmString.substring(0,2).toInt() + } else if (!jvmString.contains(".")) { + ServerConstants.JAVA_VERSION = jvmString.toInt() + } + log(this::class.java, Log.FINE, "It seems we are in a Java ${ServerConstants.JAVA_VERSION} environment.") + } catch (e: java.lang.IllegalStateException) { + log(this::class.java, Log.ERR, "Passed config file is not a TOML file. Path: ${confFile.canonicalPath}") + log(this::class.java, Log.ERR, "Exception received: $e") + exitProcess(0) + } + } + } + + private fun parseGameSettings(){ + tomlData ?: return + val data = tomlData!! + + GameWorld.settings = GameSettings( + name = ServerConstants.SERVER_NAME, + isBeta = data.getBoolean("world.debug"), + isDevMode = data.getBoolean("world.dev"), + isGui = data.getBoolean("world.start_gui"), + worldId = data.getString("world.world_id").toInt(), + countryIndex = data.getString("world.country_id").toInt(), + activity = data.getString("world.activity"), + isMembers = data.getBoolean("world.members"), + isPvp = data.getBoolean("world.pvp"), + isQuickChat = false, + isLootshare = false, + msAddress = data.getString("server.msip"), + default_xp_rate = data.getDouble("world.default_xp_rate"), + allow_slayer_reroll = data.getBoolean("world.allow_slayer_reroll"), + enable_default_clan = data.getBoolean("world.enable_default_clan"), + enable_bots = data.getBoolean("world.enable_bots"), + autostock_ge = data.getBoolean("world.autostock_ge"), + allow_token_purchase = data.getBoolean("world.allow_token_purchase"), + skillcape_perks = data.getBoolean("world.skillcape_perks"), + increased_door_time = data.getBoolean("world.increased_door_time"), + enabled_botting = data.getBoolean("world.enable_botting"), + max_adv_bots = data.getLong("world.max_adv_bots").toInt(), + enable_doubling_money_scammers = data.getBoolean("world.enable_doubling_money_scammers", false), + wild_pvp_enabled = data.getBoolean("world.wild_pvp_enabled"), + jad_practice_enabled = data.getBoolean("world.jad_practice_enabled"), + ge_announcement_limit = data.getLong("world.ge_announcement_limit", 500L).toInt(), + smartpathfinder_bfs = data.getBoolean("world.smartpathfinder_bfs", false), + enable_castle_wars = data.getBoolean("world.enable_castle_wars", false), + message_model = data.getString("world.motw_identifier").toInt(), + message_string = data.getString("world.motw_text").replace("@name", ServerConstants.SERVER_NAME) + ) + } + + private fun parseServerSettings(){ + tomlData ?: return + val data = tomlData!! + + ServerConstants.DATA_PATH = data.getString("paths.data_path") + ServerConstants.WRITE_LOGS = data.getBoolean("server.write_logs") + ServerConstants.DATABASE_NAME = data.getString("database.database_name") + ServerConstants.DATABASE_USER = data.getString("database.database_username") + ServerConstants.DATABASE_PASS = data.getString("database.database_password") + ServerConstants.DATABASE_ADDRESS = data.getString("database.database_address") + ServerConstants.DATABASE_PORT = data.getString("database.database_port") + ServerConstants.DATABASE = Database(ServerConstants.DATABASE_ADDRESS + ":" + ServerConstants.DATABASE_PORT, ServerConstants.DATABASE_NAME, ServerConstants.DATABASE_USER, ServerConstants.DATABASE_PASS) + ServerConstants.CACHE_PATH = data.getPath("paths.cache_path") + ServerConstants.CONFIG_PATH = data.getPath("paths.configs_path") + ServerConstants.PLAYER_SAVE_PATH = data.getPath("paths.save_path") + ServerConstants.STORE_PATH = data.getPath("paths.store_path") + ServerConstants.RDT_DATA_PATH = data.getPath("paths.rare_drop_table_path") + ServerConstants.OBJECT_PARSER_PATH = data.getPath("paths.object_parser_path") + ServerConstants.LOGS_PATH = data.getPath("paths.logs_path") + ServerConstants.SERVER_NAME = data.getPath("world.name") + ServerConstants.BOT_DATA_PATH = data.getPath("paths.bot_data") + ServerConstants.MS_SECRET_KEY = data.getString("server.secret_key") + ServerConstants.HOME_LOCATION = parseLocation(data.getString("world.home_location")) + ServerConstants.START_LOCATION = parseLocation(data.getString("world.new_player_location")) + ServerConstants.DAILY_RESTART = data.getBoolean("world.daily_restart") + ServerConstants.LOG_CUTSCENE = data.getBoolean("world.verbose_cutscene", false) + ServerConstants.GRAND_EXCHANGE_DATA_PATH = data.getPath("paths.eco_data") + ServerConstants.CELEDT_DATA_PATH = data.getPath("paths.cele_drop_table_path") + ServerConstants.USDT_DATA_PATH = data.getPath("paths.uncommon_seed_drop_table_path") + ServerConstants.HDT_DATA_PATH = data.getPath("paths.herb_drop_table_path") + ServerConstants.GDT_DATA_PATH = data.getPath("paths.gem_drop_table_path") + ServerConstants.RSDT_DATA_PATH = data.getPath("paths.rare_seed_drop_table_path") + ServerConstants.ASDT_DATA_PATH = data.getPath("paths.allotment_seed_drop_table_path") + ServerConstants.SERVER_GE_NAME = data.getString("world.name_ge") ?: ServerConstants.SERVER_NAME + ServerConstants.RULES_AND_INFO_ENABLED = data.getBoolean("world.show_rules", true) + ServerConstants.BOTS_INFLUENCE_PRICE_INDEX = data.getBoolean("world.bots_influence_ge_price", true) + ServerConstants.PRELOAD_MAP = data.getBoolean("server.preload_map", false) + ServerConstants.REVENANT_POPULATION = data.getLong("world.revenant_population", 30L).toInt() + ServerConstants.BANK_BOOTH_QUICK_OPEN = data.getBoolean("world.bank_booth_quick_open", false) + ServerConstants.BANK_BOOTH_NOTE_ENABLED = data.getBoolean("world.bank_booth_note_enabled", true) + ServerConstants.BANK_BOOTH_NOTE_UIM = data.getBoolean("world.bank_booth_note_uim", true) + ServerConstants.DISCORD_GE_WEBHOOK = data.getString("integrations.discord_ge_webhook", "") + ServerConstants.WATCHDOG_ENABLED = data.getBoolean("server.watchdog_enabled", true) + ServerConstants.I_AM_A_CHEATER = data.getBoolean("world.i_want_to_cheat", false) + ServerConstants.USE_AUTH = data.getBoolean("server.use_auth", true) + ServerConstants.PERSIST_ACCOUNTS = data.getBoolean("server.persist_accounts", true) + ServerConstants.DAILY_ACCOUNT_LIMIT = data.getLong("server.daily_accounts_per_ip", 3L).toInt() + ServerConstants.DISCORD_MOD_WEBHOOK = data.getString("integrations.discord_moderation_webhook", "") + ServerConstants.NOAUTH_DEFAULT_ADMIN = data.getBoolean("server.noauth_default_admin", false) + ServerConstants.DRAGON_AXE_USE_OSRS_SPEC = data.getBoolean("world.dragon_axe_use_osrs_spec", false) + ServerConstants.DISCORD_OPENRSC_HOOK = data.getString("integrations.openrsc_integration_webhook", "") + ServerConstants.ENABLE_GLOBALCHAT = data.getBoolean("world.enable_globalchat", true) + ServerConstants.MAX_PATHFIND_DISTANCE = data.getLong("server.max_pathfind_dist", 25L).toInt() + ServerConstants.IRONMAN_ICONS = data.getBoolean("world.ironman_icons", false) + ServerConstants.PLAYER_STOCK_CLEAR_INTERVAL = data.getLong("world.playerstock_clear_mins", 180L).toInt() + ServerConstants.PLAYER_STOCK_RECIRCULATE = data.getBoolean("world.playerstock_bot_offers", true) + ServerConstants.BOTSTOCK_LIMIT = data.getLong("world.botstock_limit", 5000L).toInt() + ServerConstants.BETTER_AGILITY_PYRAMID_GP = data.getBoolean("world.better_agility_pyramid_gp", true) + ServerConstants.GRAFANA_PATH = data.getPath("integrations.grafana_log_path") + ServerConstants.GRAFANA_LOGGING = data.getBoolean("integrations.grafana_logging", false) + ServerConstants.GRAFANA_TTL_DAYS = data.getLong("integrations.grafana_log_ttl_days", 7L).toInt() + ServerConstants.BETTER_DFS = data.getBoolean("world.better_dfs", true) + ServerConstants.NEW_PLAYER_ANNOUNCEMENT = data.getBoolean("world.new_player_announcement", true) + ServerConstants.HOLIDAY_EVENT_RANDOMS = data.getBoolean("world.holiday_event_randoms", true) + ServerConstants.FORCE_HALLOWEEN_EVENTS = data.getBoolean("world.force_halloween_randoms", false) + ServerConstants.FORCE_CHRISTMAS_EVENTS = data.getBoolean("world.force_christmas_randoms", false) + ServerConstants.FORCE_EASTER_EVENTS = data.getBoolean("world.force_easter_randoms", false) + ServerConstants.RUNECRAFTING_FORMULA_REVISION = data.getLong("world.runecrafting_formula_revision", 581).toInt() + ServerConstants.ENHANCED_DEEP_WILDERNESS = data.getBoolean("world.enhanced_deep_wilderness", false) + ServerConstants.CONNECTIVITY_CHECK_URL = data.getString("server.connectivity_check_url", "https://google.com,https://2009scape.org") + ServerConstants.CONNECTIVITY_TIMEOUT = data.getLong("server.connectivity_timeout", 500L).toInt() + + val logLevel = data.getString("server.log_level", "VERBOSE").uppercase() + ServerConstants.LOG_LEVEL = parseEnumEntry(logLevel) ?: LogLevel.VERBOSE + } + + + private fun Toml.getPath(key: String): String{ + try { + return parsePath(getString(key, "@data/").replace("@data", ServerConstants.DATA_PATH!!)) + } catch (e: Exception){ + log(this::class.java, Log.ERR, "Error parsing key: $key") + exitProcess(0) + } + } + + /** + * Parses a location from the format "x,y,z" + * @author Ceikry + * @param locString The string to parse + * @return Location + */ + fun parseLocation(locString: String): Location { + val locTokens = locString.split(",").map { it.toInt() } + return Location(locTokens[0], locTokens[1], locTokens[2]) + } + + /** + * Parses a path string + * @author Ceikry + * @param pathString The string to parse + * @return a String with the proper file separators for the current OS. + */ + fun parsePath(pathString: String): String { + var pathTokens: List? = null + if(pathString.contains("/")) + pathTokens = pathString.split("/") + else if(pathString.contains("\\")) + pathTokens = pathString.split("\\") + + pathTokens ?: return pathString //return the initial pathString if path does not contain file separators. + var pathProduct = "" + for(token in pathTokens){ + if(token != "") + pathProduct += "$token${File.separator}" + } + + return pathProduct + } +} diff --git a/Server/src/main/core/game/system/config/ShopParser.kt b/Server/src/main/core/game/system/config/ShopParser.kt new file mode 100644 index 0000000..1546e37 --- /dev/null +++ b/Server/src/main/core/game/system/config/ShopParser.kt @@ -0,0 +1,36 @@ +package core.game.system.config + +import core.game.node.entity.player.Player +import org.json.simple.JSONArray +import org.json.simple.parser.JSONParser +import core.ServerConstants +import core.api.log +import core.tools.Log +import core.tools.SystemLogger +import java.io.FileReader + +class ShopParser{ + val parser = JSONParser() + var reader: FileReader? = null + + companion object { +/* val SHOPS = HashMap() + val UID_SHOPS = HashMap()*/ + fun openUid(player: Player,uid: Int): Boolean { +/* val shop = UID_SHOPS[uid] ?: return false; + shop.open(player);*/ + return true +} + } + + fun load(){ + var count = 0 + reader = FileReader(ServerConstants.CONFIG_PATH + "shops.json") + val configlist = parser.parse(reader) as JSONArray + for(config in configlist){ + + count++ + } + log(this::class.java, Log.FINE, "Parsed $count shops.") + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/system/config/TableDump.kt b/Server/src/main/core/game/system/config/TableDump.kt new file mode 100644 index 0000000..e69de29 diff --git a/Server/src/main/core/game/system/config/XteaParser.kt b/Server/src/main/core/game/system/config/XteaParser.kt new file mode 100644 index 0000000..9eb4f56 --- /dev/null +++ b/Server/src/main/core/game/system/config/XteaParser.kt @@ -0,0 +1,39 @@ +package core.game.system.config + +import core.ServerConstants +import core.api.log +import core.tools.Log +import core.tools.SystemLogger +import org.json.simple.JSONArray +import org.json.simple.JSONObject +import org.json.simple.parser.JSONParser +import java.io.FileReader +import kotlin.collections.HashMap + +class XteaParser { + companion object{ + val REGION_XTEA = HashMap() + private val DEFAULT_REGION_KEYS = intArrayOf(0, 0, 0, 0) + fun getRegionXTEA(regionId: Int): IntArray { //Uses the xtea's from the sql to unlock regions + return REGION_XTEA.getOrDefault(regionId, DEFAULT_REGION_KEYS) + } + } + val parser = JSONParser() + var reader: FileReader? = null + + + fun load() { + var count = 0 + reader = FileReader(ServerConstants.CONFIG_PATH + "xteas.json") + val obj = parser.parse(reader) as JSONObject + val configlist = obj["xteas"] as JSONArray + for(config in configlist){ + val e = config as JSONObject + val id = e["regionId"].toString().toInt() + val keys = e["keys"].toString().split(",").map(String::toInt) + REGION_XTEA[id] = intArrayOf(keys[0],keys[1],keys[2],keys[3]) + count++ + } + log(this::class.java, Log.FINE, "Parsed $count region keys.") + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/system/monitor/DuplicationLog.java b/Server/src/main/core/game/system/monitor/DuplicationLog.java new file mode 100644 index 0000000..de1d380 --- /dev/null +++ b/Server/src/main/core/game/system/monitor/DuplicationLog.java @@ -0,0 +1,116 @@ +package core.game.system.monitor; + +import core.ServerConstants; + +/** + * Handles duplication-related logging. + * @author Emperor + */ +public final class DuplicationLog extends MessageLog { + + /** + * The amount of milliseconds the player's actions should be logged. (days * + * hours * minutes * milliseconds) + */ + public static long LOGGING_DURATION = 5 * 24 * 60 * 60_000; + + /** + * The duplication flag for player talking about duping. + */ + public static final int DUPE_TALK = 0x1; + + /** + * The duplication flag for a large networth increase. + */ + public static final int NW_INCREASE = 0x8; + + /** + * The current flag. + */ + private int flag; + + /** + * The last time the player triggered the "large networth increase" flag. + */ + private long lastIncreaseFlag; + + /** + * Constructs a new {@code DuplicationLog} {@code Object}. + */ + public DuplicationLog() { + super(-1, false); + } + + @Override + public void write(String playerName) { + String priority = "low"; + switch (getProbability()) { + case 3: + priority = "high"; + break; + case 2: + priority = "mid"; + } + super.write(ServerConstants.LOGS_PATH + "duplicationflags/" + priority + "prior/" + playerName + ".log"); + } + + /** + * Gets the probability of duping (scale from 0 - 3). + * @return The probability (where 3 is very likely and 0 is very unlikely). + */ + public int getProbability() { + int probability = 0; + if ((flag & NW_INCREASE) != 0) { + probability += 2; + } + if ((flag & DUPE_TALK) != 0) { + probability++; + } + return probability; + } + + /** + * Checks if the player's actions should be logged (to find cause of + * duping). + * @return {@code True} if so. + */ + public boolean isLoggingFlagged() { + return (flag & NW_INCREASE) != 0 && (System.currentTimeMillis() - lastIncreaseFlag) < LOGGING_DURATION; + } + + /** + * Adds a flag. + * @param flag The flag to add. + */ + public void flag(int flag) { + this.flag |= flag; + if (flag == NW_INCREASE) { + lastIncreaseFlag = System.currentTimeMillis(); + } + } + + /** + * Gets the flag. + * @return The flag. + */ + public int getFlag() { + return flag; + } + + /** + * Gets the lastIncreaseFlag. + * @return The lastIncreaseFlag. + */ + public long getLastIncreaseFlag() { + return lastIncreaseFlag; + } + + /** + * Sets the lastIncreaseFlag. + * @param lastIncreaseFlag The lastIncreaseFlag to set. + */ + public void setLastIncreaseFlag(long lastIncreaseFlag) { + this.lastIncreaseFlag = lastIncreaseFlag; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/system/monitor/MessageLog.java b/Server/src/main/core/game/system/monitor/MessageLog.java new file mode 100644 index 0000000..bcf7772 --- /dev/null +++ b/Server/src/main/core/game/system/monitor/MessageLog.java @@ -0,0 +1,143 @@ +package core.game.system.monitor; + +import core.cache.misc.buffer.ByteBufferUtils; + +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * Handles message monitoring. + * @author Emperor + */ +public class MessageLog { + + /** + * The date format used. + */ + private final DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss"); + + /** + * The messages. + */ + private List messages; + + /** + * The logging capacity. + */ + private final int capacity; + + /** + * If all messages logged should be unique. + */ + private boolean uniqueLogging; + + /** + * Constructs a new {@code MessageLog} {@code Object} without capacity and + * uniqueLogging mode disabled. + */ + public MessageLog() { + this(-1, false); + } + + /** + * Constructs a new {@code MessageLog} {@code Object} with uniqueLogging + * mode disabled. + * @param capacity The capacity (-1 for no capacity). + */ + public MessageLog(int capacity) { + this(capacity, false); + } + + /** + * Constructs a new {@code MessageLog} {@code Object}. + * @param capacity The capacity (-1 for no capacity). + * @param uniqueLogging If all messages logged should be unique. + */ + public MessageLog(int capacity, boolean uniqueLogging) { + this.capacity = capacity; + this.messages = new ArrayList<>(20); + this.uniqueLogging = uniqueLogging; + } + + /** + * Adds a message to the cache. + * @param message The message. + * @param timeStamp If the message should be time stamped. + */ + public void log(String message, boolean timeStamp) { + if (messages.size() == capacity) { + messages.remove(0); + } + if (uniqueLogging && messages.contains(message)) { + return; + } + if (timeStamp) { + StringBuilder sb = new StringBuilder(dateFormat.format(new Date())); + message = sb.append(": ").append(message).toString(); + } + messages.add(message); + } + + /** + * Writes the logged data to the file. + * @param fileName The name of the file to write on. + */ + public void write(String fileName) { + if (messages.isEmpty()) { + return; + } + int size = messages.size(); + ByteBuffer buffer = ByteBuffer.allocate(size * 16055); + buffer.putShort((short) size); + for (String message : messages) { + ByteBufferUtils.putString(message, buffer); + buffer.put((byte) '\n'); + } + buffer.putShort((short) -1); + buffer.flip(); + try (RandomAccessFile raf = new RandomAccessFile(fileName, "rw")) { + FileChannel channel = raf.getChannel(); + long pos = channel.size() - 2l; + if (pos < 1) { + pos = 0; + } + channel.write(buffer, pos); + raf.close(); + } catch (IOException e) { + e.printStackTrace(); + } + messages.clear(); + } + + /** + * Gets the messages. + * @return The messages. + */ + public List getMessages() { + return messages; + } + + /** + * Sets the messages. + * @param messages The messages to set. + */ + public void setMessages(List messages) { + this.messages = messages; + } + + /** + * Gets the capacity. + * @return The capacity. + */ + public int getCapacity() { + return capacity; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/system/mysql/SQLColumn.java b/Server/src/main/core/game/system/mysql/SQLColumn.java new file mode 100644 index 0000000..3e6b7a3 --- /dev/null +++ b/Server/src/main/core/game/system/mysql/SQLColumn.java @@ -0,0 +1,154 @@ +package core.game.system.mysql; + +/** + * Represents a column used in an SQL table. + * @author Emperor + */ +public final class SQLColumn { + + /** + * The name. + */ + private final String name; + + /** + * The data type. + */ + private final Class type; + + /** + * If this column should never be updated in the database. + */ + private final boolean neverUpdate; + + /** + * The value. + */ + private Object value; + + /** + * If the column value changed. + */ + private boolean changed; + + /** + * If the column should be parsed. + */ + private boolean parse; + + /** + * Constructs a new {@code SQLColumn} {@code Object}. + * @param name The column name. + * @param type The data type. + */ + public SQLColumn(String name, Class type) { + this(name, type, false, true); + } + + /** + * Constructs a new {@code SQLColumn} {@code Object}. + * @param name The column name. + * @param type The data type. + * @param parse If the column should be parsed. + */ + public SQLColumn(String name, Class type, boolean parse) { + this(name, type, false, parse); + } + + /** + * Constructs a new {@code SQLColumn} {@code Object}. + * @param name The column name. + * @param type The data type. + * @param neverUpdate If this column should never be updated in the + * database. + * @param parse If the column should be parsed. + */ + public SQLColumn(String name, Class type, boolean neverUpdate, boolean parse) { + this.name = name; + this.type = type; + this.neverUpdate = neverUpdate; + this.parse = parse; + } + + /** + * Gets the name. + * @return The name. + */ + public String getName() { + return name; + } + + /** + * Updates the value. + * @param value The value. + */ + public void updateValue(Object value) { + this.changed = value != this.value; + this.value = value; + } + + /** + * Gets the value. + * @return The value. + */ + public Object getValue() { + return value; + } + + /** + * Sets the value. + * @param value The value to set. + */ + public void setValue(Object value) { + this.value = value; + this.changed = false; + } + + /** + * Gets the changed. + * @return The changed. + */ + public boolean isChanged() { + return changed; + } + + /** + * Sets the changed. + * @param changed The changed to set. + */ + public void setChanged(boolean changed) { + this.changed = changed; + } + + /** + * Gets the type. + * @return The type. + */ + public Class getType() { + return type; + } + + /** + * Gets the neverUpdate. + * @return The neverUpdate. + */ + public boolean isNeverUpdate() { + return neverUpdate; + } + + /** + * Gets the parse. + * @return the parse. + */ + public boolean isParse() { + return parse; + } + + /** + * Sets the parse. + * @param parse the parse to set + */ + public void setParse(boolean parse) { + this.parse = parse; + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/system/mysql/SQLTable.java b/Server/src/main/core/game/system/mysql/SQLTable.java new file mode 100644 index 0000000..c414059 --- /dev/null +++ b/Server/src/main/core/game/system/mysql/SQLTable.java @@ -0,0 +1,62 @@ +package core.game.system.mysql; + +import java.util.ArrayList; +import java.util.List; + +/** + * Represents an SQL table. + * @author Emperor + */ +public final class SQLTable { + + /** + * The columns. + */ + private final SQLColumn[] columns; + + /** + * Constructs a new {@code SQLTable} {@code Object}. + * @param columns The columns. + */ + public SQLTable(SQLColumn... columns) { + this.columns = columns; + } + + /** + * Gets the column for the given name. + * @param name The column name. + * @return The column. + */ + public SQLColumn getColumn(String name) { + for (SQLColumn column : columns) { + if (column.getName().equals(name)) { + return column; + } + } + return null; + } + + /** + * Gets the changed columns. + * @return The columns. + */ + public List getChanged() { + List updated = new ArrayList<>(20); + for (int i = 0; i < columns.length; i++) { + SQLColumn column = columns[i]; + if (column.isChanged()) { + updated.add(column); + } + } + return updated; + } + + /** + * Gets the columns. + * @return The columns. + */ + public SQLColumn[] getColumns() { + return columns; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/system/security/EncryptionManager.java b/Server/src/main/core/game/system/security/EncryptionManager.java new file mode 100644 index 0000000..617daa0 --- /dev/null +++ b/Server/src/main/core/game/system/security/EncryptionManager.java @@ -0,0 +1,513 @@ +package core.game.system.security; + +import core.game.system.SystemManager; + +import java.io.UnsupportedEncodingException; +import java.security.SecureRandom; + +/** + * Represents the class of simple encryption functions. + * @author Unknown + */ +public class EncryptionManager { + + // Define the BCrypt workload to use when generating password hashes. 10-31 + // is a valid value. + private static int workload = 12; + + public static void main(String... args) { + + String pass = "lugi"; + String salt = BCrypt.gensalt(workload); + + + + // "$2a$12$N3jCPMPEZTisbMf7PG9O7ePgTQEJjhNXGHOJ9zvovT8ibY3Uk.Xlm")); + String hash = "$2a$12$N3jCPMPEZTisbMf7PG9O7ePgTQEJjhNXGHOJ9zvovT8ibY3Uk.Xlm"; + salt = hash.substring(0, 29); + + String hsh = hash.substring(29, hash.length()); + + } + + /** + * This method can be used to generate a string representing an account + * password suitable for storing in a database. It will be an OpenBSD-style + * crypt(3) formatted hash string of length=60 The bcrypt workload is + * specified in the above static variable, a value from 10 to 31. A workload + * of 12 is a very reasonable safe default as of 2013. This automatically + * handles secure 128-bit salt generation and storage within the hash. + * @param password_plaintext The account's plaintext password as provided + * during account creation, or when changing an account's password. + * @return String - a string of length 60 that is the bcrypt hashed password + * in crypt(3) format. + */ + public String hashPassword(String password_plaintext) { + String salt = BCrypt.gensalt(workload); + String hashed_password = BCrypt.hashpw(password_plaintext, salt); + return (hashed_password); + } + + /** + * Hash pass. + * @param password_plaintext + * @param salt + * @return + */ + public String hashPassword(String password_plaintext, String salt) { + String hashed_password = BCrypt.hashpw(password_plaintext, salt); + return (hashed_password); + } + + /** + * This method can be used to verify a computed hash from a plaintext (e.g. + * during a login request) with that of a stored hash from a database. The + * password hash from the database must be passed as the second variable. + * @param password_plaintext The account's plaintext password, as provided + * during a login request + * @param stored_hash The account's stored password hash, retrieved from the + * authorization database + * @return boolean - true if the password matches the password of the stored + * hash, false otherwise + */ + public boolean checkPassword(String password_plaintext, String stored_hash) { + boolean password_verified = false; + if (null == stored_hash || !stored_hash.startsWith("$2a$")) + throw new java.lang.IllegalArgumentException("Invalid hash provided for comparison"); + password_verified = BCrypt.checkpw(password_plaintext, stored_hash); + return (password_verified); + } + + // Copyright (c) 2006 Damien Miller + // + // Permission to use, copy, modify, and distribute this software for any + // purpose with or without fee is hereby granted, provided that the above + // copyright notice and this permission notice appear in all copies. + // + // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + /** + * BCrypt implements OpenBSD-style Blowfish password hashing using the + * scheme described in "A Future-Adaptable Password Scheme" by Niels Provos + * and David Mazieres.

This password hashing system tries to thwart + * off-line password cracking using a computationally-intensive hashing + * algorithm, based on Bruce Schneier's Blowfish cipher. The work factor of + * the algorithm is parameterised, so it can be increased as computers get + * faster.

Usage is really simple. To hash a password for the first + * time, call the hashpw method with a random salt, like this:

+ * String pw_hash = BCrypt.hashpw(plain_password, BCrypt.gensalt());
+ *

To check whether a plaintext password matches one that has + * been hashed previously, use the checkpw method:

if + * (BCrypt.checkpw(candidate_password, stored_hash))
+ + + *

The gensalt() method takes an optional parameter (log_rounds) + * that determines the computational complexity of the hashing:

+ * String strong_salt = BCrypt.gensalt(10)
String stronger_salt = + * BCrypt.gensalt(12)

The amount of work increases + * exponentially (2**log_rounds), so each increment is twice as much work. + * The default log_rounds is 10, and the valid range is 4 to 31. + * @author Damien Miller + * @version 0.2 + */ + public static class BCrypt { + // BCrypt parameters + private static final int GENSALT_DEFAULT_LOG2_ROUNDS = 10; + private static final int BCRYPT_SALT_LEN = 16; + + // Blowfish parameters + private static final int BLOWFISH_NUM_ROUNDS = 16; + + // Initial contents of key schedule + private static final int P_orig[] = { 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b }; + private static final int S_orig[] = { 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a, 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7, 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0, 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, 0x1f9f25cf, + 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 }; + + // bcrypt IV: "OrpheanBeholderScryDoubt" + static private final int bf_crypt_ciphertext[] = { 0x4f727068, 0x65616e42, 0x65686f6c, 0x64657253, 0x63727944, 0x6f756274 }; + + // Table for Base64 encoding + static private final char base64_code[] = { '.', '/', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; + + // Table for Base64 decoding + static private final byte index_64[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, -1, -1, -1, -1, -1, -1, -1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, -1, -1, -1, -1, -1, -1, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, -1, -1, -1, -1, -1 }; + + // Expanded Blowfish key + private int P[]; + private int S[]; + + /** + * Encode a byte array using bcrypt's slightly-modified base64 encoding + * scheme. Note that this is *not* compatible with the standard + * MIME-base64 encoding. + * @param d the byte array to encode + * @param len the number of bytes to encode + * @return base64-encoded string + * @exception IllegalArgumentException if the length is invalid + */ + private static String encode_base64(byte d[], int len) throws IllegalArgumentException { + int off = 0; + StringBuffer rs = new StringBuffer(); + int c1, c2; + + if (len <= 0 || len > d.length) + throw new IllegalArgumentException("Invalid len"); + + while (off < len) { + c1 = d[off++] & 0xff; + rs.append(base64_code[(c1 >> 2) & 0x3f]); + c1 = (c1 & 0x03) << 4; + if (off >= len) { + rs.append(base64_code[c1 & 0x3f]); + break; + } + c2 = d[off++] & 0xff; + c1 |= (c2 >> 4) & 0x0f; + rs.append(base64_code[c1 & 0x3f]); + c1 = (c2 & 0x0f) << 2; + if (off >= len) { + rs.append(base64_code[c1 & 0x3f]); + break; + } + c2 = d[off++] & 0xff; + c1 |= (c2 >> 6) & 0x03; + rs.append(base64_code[c1 & 0x3f]); + rs.append(base64_code[c2 & 0x3f]); + } + return rs.toString(); + } + + /** + * Look up the 3 bits base64-encoded by the specified character, + * range-checking againt conversion table + * @param x the base64-encoded value + * @return the decoded value of x + */ + private static byte char64(char x) { + if ((int) x > index_64.length) + return -1; + return index_64[(int) x]; + } + + /** + * Decode a string encoded using bcrypt's base64 scheme to a byte array. + * Note that this is *not* compatible with the standard MIME-base64 + * encoding. + * @param s the string to decode + * @param maxolen the maximum number of bytes to decode + * @return an array containing the decoded bytes + * @throws IllegalArgumentException if maxolen is invalid + */ + private static byte[] decode_base64(String s, int maxolen) throws IllegalArgumentException { + StringBuffer rs = new StringBuffer(); + int off = 0, slen = s.length(), olen = 0; + byte ret[]; + byte c1, c2, c3, c4, o; + + if (maxolen <= 0) + throw new IllegalArgumentException("Invalid maxolen"); + + while (off < slen - 1 && olen < maxolen) { + c1 = char64(s.charAt(off++)); + c2 = char64(s.charAt(off++)); + if (c1 == -1 || c2 == -1) + break; + o = (byte) (c1 << 2); + o |= (c2 & 0x30) >> 4; + rs.append((char) o); + if (++olen >= maxolen || off >= slen) + break; + c3 = char64(s.charAt(off++)); + if (c3 == -1) + break; + o = (byte) ((c2 & 0x0f) << 4); + o |= (c3 & 0x3c) >> 2; + rs.append((char) o); + if (++olen >= maxolen || off >= slen) + break; + c4 = char64(s.charAt(off++)); + o = (byte) ((c3 & 0x03) << 6); + o |= c4; + rs.append((char) o); + ++olen; + } + + ret = new byte[olen]; + for (off = 0; off < olen; off++) + ret[off] = (byte) rs.charAt(off); + return ret; + } + + /** + * Blowfish encipher a single 64-bit block encoded as two 32-bit halves + * @param lr an array containing the two 32-bit half blocks + * @param off the position in the array of the blocks + */ + private final void encipher(int lr[], int off) { + int i, n, l = lr[off], r = lr[off + 1]; + + l ^= P[0]; + for (i = 0; i <= BLOWFISH_NUM_ROUNDS - 2;) { + // Feistel substitution on left word + n = S[(l >> 24) & 0xff]; + n += S[0x100 | ((l >> 16) & 0xff)]; + n ^= S[0x200 | ((l >> 8) & 0xff)]; + n += S[0x300 | (l & 0xff)]; + r ^= n ^ P[++i]; + + // Feistel substitution on right word + n = S[(r >> 24) & 0xff]; + n += S[0x100 | ((r >> 16) & 0xff)]; + n ^= S[0x200 | ((r >> 8) & 0xff)]; + n += S[0x300 | (r & 0xff)]; + l ^= n ^ P[++i]; + } + lr[off] = r ^ P[BLOWFISH_NUM_ROUNDS + 1]; + lr[off + 1] = l; + } + + /** + * Cycically extract a word of key material + * @param data the string to extract the data from + * @param offp a "pointer" (as a one-entry array) to the current offset + * into data + * @return the next word of material from data + */ + private static int streamtoword(byte data[], int offp[]) { + int i; + int word = 0; + int off = offp[0]; + + for (i = 0; i < 4; i++) { + word = (word << 8) | (data[off] & 0xff); + off = (off + 1) % data.length; + } + + offp[0] = off; + return word; + } + + /** + * Initialise the Blowfish key schedule + */ + private void init_key() { + P = (int[]) P_orig.clone(); + S = (int[]) S_orig.clone(); + } + + /** + * Key the Blowfish cipher + * @param key an array containing the key + */ + private void key(byte key[]) { + int i; + int koffp[] = { 0 }; + int lr[] = { 0, 0 }; + int plen = P.length, slen = S.length; + + for (i = 0; i < plen; i++) + P[i] = P[i] ^ streamtoword(key, koffp); + + for (i = 0; i < plen; i += 2) { + encipher(lr, 0); + P[i] = lr[0]; + P[i + 1] = lr[1]; + } + + for (i = 0; i < slen; i += 2) { + encipher(lr, 0); + S[i] = lr[0]; + S[i + 1] = lr[1]; + } + } + + /** + * Perform the "enhanced key schedule" step described by Provos and + * Mazieres in "A Future-Adaptable Password Scheme" + * http://www.openbsd.org/papers/bcrypt-paper.ps + * @param data salt information + * @param key password information + */ + private void ekskey(byte data[], byte key[]) { + int i; + int koffp[] = { 0 }, doffp[] = { 0 }; + int lr[] = { 0, 0 }; + int plen = P.length, slen = S.length; + + for (i = 0; i < plen; i++) + P[i] = P[i] ^ streamtoword(key, koffp); + + for (i = 0; i < plen; i += 2) { + lr[0] ^= streamtoword(data, doffp); + lr[1] ^= streamtoword(data, doffp); + encipher(lr, 0); + P[i] = lr[0]; + P[i + 1] = lr[1]; + } + + for (i = 0; i < slen; i += 2) { + lr[0] ^= streamtoword(data, doffp); + lr[1] ^= streamtoword(data, doffp); + encipher(lr, 0); + S[i] = lr[0]; + S[i + 1] = lr[1]; + } + } + + /** + * Perform the central password hashing step in the bcrypt scheme + * @param password the password to hash + * @param salt the binary salt to hash with the password + * @param log_rounds the binary logarithm of the number of rounds of + * hashing to apply + * @return an array containing the binary hashed password + */ + private byte[] crypt_raw(byte password[], byte salt[], int log_rounds) { + int rounds, i, j; + int cdata[] = (int[]) bf_crypt_ciphertext.clone(); + int clen = cdata.length; + byte ret[]; + + if (log_rounds < 4 || log_rounds > 31) + throw new IllegalArgumentException("Bad number of rounds"); + rounds = 1 << log_rounds; + if (salt.length != BCRYPT_SALT_LEN) + throw new IllegalArgumentException("Bad salt length"); + + init_key(); + ekskey(salt, password); + for (i = 0; i < rounds; i++) { + key(password); + key(salt); + } + + for (i = 0; i < 64; i++) { + for (j = 0; j < (clen >> 1); j++) + encipher(cdata, j << 1); + } + + ret = new byte[clen * 4]; + for (i = 0, j = 0; i < clen; i++) { + ret[j++] = (byte) ((cdata[i] >> 24) & 0xff); + ret[j++] = (byte) ((cdata[i] >> 16) & 0xff); + ret[j++] = (byte) ((cdata[i] >> 8) & 0xff); + ret[j++] = (byte) (cdata[i] & 0xff); + } + return ret; + } + + /** + * Hash a password using the OpenBSD bcrypt scheme + * @param password the password to hash + * @param salt the salt to hash with (perhaps generated using + * BCrypt.gensalt) + * @return the hashed password + */ + public static String hashpw(String password, String salt) { + BCrypt B; + String real_salt; + byte passwordb[], saltb[], hashed[]; + char minor = (char) 0; + int rounds, off = 0; + StringBuffer rs = new StringBuffer(); + + if (salt.charAt(0) != '$' || salt.charAt(1) != '2') + throw new IllegalArgumentException("Invalid salt version"); + if (salt.charAt(2) == '$') + off = 3; + else { + minor = salt.charAt(2); + if (minor != 'a' || salt.charAt(3) != '$') + throw new IllegalArgumentException("Invalid salt revision"); + off = 4; + } + + // Extract number of rounds + if (salt.charAt(off + 2) > '$') + throw new IllegalArgumentException("Missing salt rounds"); + rounds = Integer.parseInt(salt.substring(off, off + 2)); + + real_salt = salt.substring(off + 3, off + 25); + try { + passwordb = (password + (minor >= 'a' ? "\000" : "")).getBytes("UTF-8"); + } catch (UnsupportedEncodingException uee) { + throw new AssertionError("UTF-8 is not supported"); + } + + saltb = decode_base64(real_salt, BCRYPT_SALT_LEN); + + B = new BCrypt(); + hashed = B.crypt_raw(passwordb, saltb, rounds); + + rs.append("$2"); + if (minor >= 'a') + rs.append(minor); + rs.append("$"); + if (rounds < 10) + rs.append("0"); + rs.append(Integer.toString(rounds)); + rs.append("$"); + rs.append(encode_base64(saltb, saltb.length)); + rs.append(encode_base64(hashed, bf_crypt_ciphertext.length * 4 - 1)); + return rs.toString(); + } + + /** + * Generate a salt for use with the BCrypt.hashpw() method + * @param log_rounds the log2 of the number of rounds of hashing to apply + * - the work factor therefore increases as 2**log_rounds. + * @param random an instance of SecureRandom to use + * @return an encoded salt value + */ + public static String gensalt(int log_rounds, SecureRandom random) { + StringBuffer rs = new StringBuffer(); + byte rnd[] = new byte[BCRYPT_SALT_LEN]; + + random.nextBytes(rnd); + + rs.append("$2a$"); + if (log_rounds < 10) + rs.append("0"); + rs.append(Integer.toString(log_rounds)); + rs.append("$"); + rs.append(encode_base64(rnd, rnd.length)); + return rs.toString(); + } + + /** + * Generate a salt for use with the BCrypt.hashpw() method + * @param log_rounds the log2 of the number of rounds of hashing to apply + * - the work factor therefore increases as 2**log_rounds. + * @return an encoded salt value + */ + public static String gensalt(int log_rounds) { + return gensalt(log_rounds, new SecureRandom()); + } + + /** + * Generate a salt for use with the BCrypt.hashpw() method, selecting a + * reasonable default for the number of hashing rounds to apply + * @return an encoded salt value + */ + public static String gensalt() { + return gensalt(GENSALT_DEFAULT_LOG2_ROUNDS); + } + + /** + * Check that a plaintext password matches a previously hashed one + * @param plaintext the plaintext password to verify + * @param hashed the previously-hashed password + * @return true if the passwords match, false otherwise + */ + public static boolean checkpw(String plaintext, String hashed) { + return (hashed.compareTo(hashpw(plaintext, hashed)) == 0); + } + } + +} diff --git a/Server/src/main/core/game/system/task/MovementHook.java b/Server/src/main/core/game/system/task/MovementHook.java new file mode 100644 index 0000000..fd7fdf4 --- /dev/null +++ b/Server/src/main/core/game/system/task/MovementHook.java @@ -0,0 +1,21 @@ +package core.game.system.task; + +import core.game.node.entity.Entity; +import core.game.world.map.Location; + +/** + * An interface used for hooking to the + *.world.map.MovementUpdate} class. + * @author Emperor + */ +public interface MovementHook { + + /** + * Called when an entity has moved. + * @param e The moving entity. + * @param l The location. + * @return {@code True} if no further hooks should be called. + */ + boolean handle(Entity e, Location l); + +} \ No newline at end of file diff --git a/Server/src/main/core/game/system/task/NodeTask.java b/Server/src/main/core/game/system/task/NodeTask.java new file mode 100644 index 0000000..0e3e9af --- /dev/null +++ b/Server/src/main/core/game/system/task/NodeTask.java @@ -0,0 +1,125 @@ +package core.game.system.task; + +import core.game.node.Node; + +/** + * Represents "Node pulse", which is used to execute methods with node + * parameters. + * @author Emperor + */ +public abstract class NodeTask { + + /** + * The amount of ticks for the pulse (if any). + */ + private final int ticks; + + /** + * The pulse + */ + private Pulse pulse; + + /** + * Constructs a new {@code NodeTask} {@code Object}. + */ + public NodeTask() { + this(-1); + } + + /** + * Constructs a new {@code NodeTask} {@Code Object} + * @param ticks The ticks. + */ + public NodeTask(int ticks) { + this.ticks = ticks; + } + + /** + * Called when the pulse starts. + * @param node The base node. + * @param n The other nodes. + */ + public void start(Node node, Node... n) { + + } + + /** + * Runs the task. + * @param node The base node. + * @param n The other nodes. + * @return {@code True} if the pulse (if this is used in a pulse) should + * stop. + */ + public abstract boolean exec(Node node, Node... n); + + /** + * Called when the pulse is stopped. + * @param node The base node. + * @param n The other nodes. + */ + public void stop(Node node, Node... n) { + + } + + /** + * Checks if the node task pulse should be removed for a duplicate. + * @param s The command string. + * @param node The base node. + * @param n The other nodes. + */ + public boolean removeFor(String s, Node node, Node... n) { + return true; + } + + /** + * Schedules the node task. + * @param node The base node. + * @param n The other nodes. + * @return The pulse used for this task. + */ + public Pulse schedule(final Node node, final Node... n) { + pulse = new Pulse(ticks, node) { + + @Override + public void start() { + super.start(); + NodeTask.this.start(node, n); + } + + @Override + public boolean pulse() { + return exec(node, n); + } + + @Override + public void stop() { + super.stop(); + NodeTask.this.stop(node, n); + } + + @Override + public boolean removeFor(String s) { + return NodeTask.this.removeFor(s, node, n); + } + }; + pulse.start(); + return pulse; + } + + /** + * Gets the Pulse for this Task + * @return the Pulse + */ + public Pulse getPulse() { + return pulse; + } + + /** + * Gets the ticks. + * @return the ticks. + */ + public int getTicks() { + return ticks; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/system/task/Pulse.java b/Server/src/main/core/game/system/task/Pulse.java new file mode 100644 index 0000000..dc81708 --- /dev/null +++ b/Server/src/main/core/game/system/task/Pulse.java @@ -0,0 +1,205 @@ +package core.game.system.task; + +import core.game.node.Node; + +/** + * Represents a pulse object (a task executed once every 600ms on the + * MajorUpdateWorker thread). + * @author Emperor + */ +public abstract class Pulse implements Runnable { + + /** + * If the task is still running. + */ + public boolean running = true; + + /** + * The amount of game-ticks to wait before execution. + */ + private int delay; + + /** + * The amount of ticks passed. + */ + int ticksPassed; + + /** + * The nodes that have to be active for the pulse to continue. + */ + protected Node[] checks; + + /** + * Constructs a new {@code Pulse} {@code Object}. + */ + public Pulse() { + this(1); + } + + /** + * Constructs a new {@code Pulse} object. + * @param delay The delay. + */ + public Pulse(int delay) { + this.delay = delay; + } + + /** + * Constructs a new {@code Pulse} object. + * @param delay The delay. + * @param checks The nodes that have to be active for the pulse to continue. + */ + public Pulse(int delay, Node... checks) { + this.delay = delay; + this.checks = checks; + } + + @Override + public void run() { + if(update()){ + //GameWorld.TASKS.remove(this); + } + } + + /**s + * Called when the world pulses, once every 600ms. + * @return {@code True} if this {@code Pulse} is finished and can be removed, + * {@code false} if not. + */ + public boolean update() { + if (hasInactiveNode()) { + stop(); + return true; + } + if (!isRunning()) { + return true; + } + if (++ticksPassed >= delay) { + ticksPassed = 0; + try { + if (pulse()) { + stop(); + return true; + } + } catch (Exception e){ + e.printStackTrace(); + stop(); + return true; + } + return !isRunning(); + } + return false; + } + + /** + * Checks if one of the node checks is inactive. + * @return {@code True} if so. + */ + public boolean hasInactiveNode() { + if (checks != null) { + int size = checks.length; + for (int i = 0; i < size; i++) { + Node n = checks[i]; + if (n != null && !n.isActive()) { + return true; + } + } + } + return false; + } + + /** + * Called after the delay has passed. + * @return {@code True} if the pulse has finished and should be removed. + */ + public abstract boolean pulse(); + + /** + * Checks if this pulse should be terminated so the new pulse (represented + * in string format) can run. + * @param pulse The pulse to run in string format. + * @return {@code True} if this pulse should be removed (default). + */ + public boolean removeFor(String pulse) { + return true; + } + + /** + * Adds a node check. + * @param index The index. + * @param n The node. + */ + public void addNodeCheck(int index, Node n) { + checks[index] = n; + } + + /** + * Gets a node check. + * @param index The index. + * @return The node. + */ + public Node getNodeCheck(int index) { + return checks[index]; + } + + /** + * Manually stop the {@code Pulse} task. + */ + public void stop() { + running = false; + } + + /** + * Manually start the {@code Pulse} task. + */ + public void start() { + running = true; + } + + /** + * Restarts the pulse delay. + */ + public void restart() { + ticksPassed = 0; + } + + /** + * Checks if the pulse is still running. + * @return {@code True} if the pulse is still running. + */ + public boolean isRunning() { + return running; + } + + /** + * Gets the delay of this {@code Pulse}. + * @return The delay. + */ + public int getDelay() { + return delay; + } + + /** + * Sets the delay. + * @param delay The delay. + */ + public void setDelay(int delay) { + this.delay = delay; + } + + /** + * Sets the amount of ticks passed. + * @param ticks The amount of ticks passed in this pulse. + */ + public void setTicksPassed(int ticks) { + this.ticksPassed = ticks; + } + + /** + * Gets the amount of ticks passed. + * @return The amount of ticks passed so far. + */ + public int getTicksPassed() { + return ticksPassed; + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/system/task/TaskExecutor.kt b/Server/src/main/core/game/system/task/TaskExecutor.kt new file mode 100644 index 0000000..92f25fc --- /dev/null +++ b/Server/src/main/core/game/system/task/TaskExecutor.kt @@ -0,0 +1,33 @@ +package core.game.system.task + +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch + +/** + * A class holding methods to execute tasks. + * @author Emperor + */ +object TaskExecutor { + + /** + * Executes an SQL handling task. + * @param task The task. + */ + @JvmStatic + fun executeSQL(task: () -> Unit) { + GlobalScope.launch { + task.invoke() + } + } + + /** + * Executes the task. + * @param task The task to execute. + */ + @JvmStatic + fun execute(task: () -> Unit) { + GlobalScope.launch { + task.invoke() + } + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/system/timer/PersistTimer.kt b/Server/src/main/core/game/system/timer/PersistTimer.kt new file mode 100644 index 0000000..977c574 --- /dev/null +++ b/Server/src/main/core/game/system/timer/PersistTimer.kt @@ -0,0 +1,23 @@ +package core.game.system.timer + +import core.api.* +import org.json.simple.* +import core.game.node.entity.Entity +import kotlin.reflect.full.createInstance + +/** + * A timer implementation with support for saving and loading arbitrary data. See `RSTimer` for more info on timers themselves. +**/ +abstract class PersistTimer (runInterval: Int, identifier: String, isSoft: Boolean = false, isAuto: Boolean = false, flags: Array = arrayOf()) : RSTimer (runInterval, identifier, isSoft, isAuto, flags) { + open fun save (root: JSONObject, entity: Entity) { + root["ticksLeft"] = (nextExecution - getWorldTicks()).toString() + } + + open fun parse (root: JSONObject, entity: Entity) { + runInterval = root["ticksLeft"].toString().toInt() + } + + override fun retrieveInstance() : RSTimer { + return this::class.createInstance() + } +} diff --git a/Server/src/main/core/game/system/timer/RSTimer.kt b/Server/src/main/core/game/system/timer/RSTimer.kt new file mode 100644 index 0000000..75770b7 --- /dev/null +++ b/Server/src/main/core/game/system/timer/RSTimer.kt @@ -0,0 +1,57 @@ +package core.game.system.timer + +import core.game.node.entity.Entity +import kotlin.reflect.full.createInstance + +/** + * Class for the timer feature of the engine. If you have some task which should repeat periodically, such as applying poison damage, etc, use a timer. + * If the `isAuto` value of a timer is set to `true`, then the timer is automatically added to an entity on creation and started. This is separate from the + * default PersistTimer behavior, which automatically starts the timer only if there's saved data for that timer present. In truth, there's very few + * timers that should have isAuto true. +**/ +abstract class RSTimer (var runInterval: Int, val identifier: String = "generictimer", val isSoft: Boolean = false, val isAuto: Boolean = false, val flags: Array = arrayOf()) { + + /** + * Executed every time the run interval of the timer elapses. + * Execution will be delayed if this timer has `isSoft` set to false (which 99% of timers should) if the entity has a modal open or is otherwise stalled. + * @return whether the timer should execute again. If false, timer will be unregistered from the entity and stop executing. If true, timer will be scheduled to repeat once the runInterval elapses again. + **/ + abstract fun run (entity: Entity) : Boolean + + /** + * Called by core code to determine the amount of time between timer scheduling and the initial (first) run. + * Returns the runInterval by default, but cases such as Farming require an override to sync with realtime clocks. + **/ + open fun getInitialRunDelay() : Int { return runInterval } + + /** + * Called by core code before the timer is first registered. Called after parse on PersistTimers. + * Called before the timer has been added to the timer list. + **/ + open fun beforeRegister (entity: Entity) {} + + /** + * Called by core code when the timer is first registered. Called after parse on PersistTimers. + * Called after the timer has been added to the timer list. + **/ + open fun onRegister (entity: Entity) {} + + /** + * Called by core code when the timer is being removed. + */ + open fun onRemoval (entity: Entity) {} + + var lastExecution: Int = 0 + var nextExecution: Int = 0 + + open fun retrieveInstance() : RSTimer { + return this::class.createInstance() + } + + /** + * This is called only when getTimer is called by further up code with arguments, otherwise retrieveInstance() is called if no arguments are passed. + **/ + open fun getTimer (vararg args: Any) : RSTimer { + return retrieveInstance() + } +} diff --git a/Server/src/main/core/game/system/timer/TimerFlag.kt b/Server/src/main/core/game/system/timer/TimerFlag.kt new file mode 100644 index 0000000..dd56d22 --- /dev/null +++ b/Server/src/main/core/game/system/timer/TimerFlag.kt @@ -0,0 +1,5 @@ +package core.game.system.timer + +enum class TimerFlag { + ClearOnDeath +} \ No newline at end of file diff --git a/Server/src/main/core/game/system/timer/TimerManager.kt b/Server/src/main/core/game/system/timer/TimerManager.kt new file mode 100644 index 0000000..92bd50e --- /dev/null +++ b/Server/src/main/core/game/system/timer/TimerManager.kt @@ -0,0 +1,143 @@ +package core.game.system.timer + +import core.api.* +import core.tools.* +import java.util.ArrayList +import org.json.simple.JSONObject +import core.game.node.entity.Entity +import core.game.node.entity.player.Player + +class TimerManager (val entity: Entity) { + val activeTimers = ArrayList() + val newTimers = ArrayList() + val toRemoveTimers = ArrayList() + + fun registerTimer (timer: RSTimer) { + timer.beforeRegister(entity) + newTimers.add(timer) + timer.onRegister(entity) + } + + fun processTimers () { + activeTimers.removeAll(toRemoveTimers) + newTimers.removeAll(toRemoveTimers) + toRemoveTimers.clear() + + val canRunNormalTimers = (entity !is Player) || !(entity.asPlayer().hasModalOpen() || entity.scripts.delay > getWorldTicks()) + for (timer in activeTimers) { + if (timer.nextExecution > getWorldTicks()) continue + if (!canRunNormalTimers && !timer.isSoft) continue + + try { + if (timer.run(entity)) { + timer.nextExecution = getWorldTicks() + timer.runInterval + } else removeTimer(timer) + } catch (e: Exception) { + log (this::class.java, Log.ERR, "Prematurely removing timer ${timer::class.java.simpleName} from ${entity.name} because it threw an exception when ran. Exception follows:") + e.printStackTrace() + removeTimer(timer) + } + } + + for (timer in newTimers) { + activeTimers.add(timer) + timer.nextExecution = timer.getInitialRunDelay() + getWorldTicks() + } + + newTimers.clear() + } + + fun clearTimers () { + activeTimers.clear() + newTimers.clear() + toRemoveTimers.clear() + } + + fun onEntityDeath() { + for (timer in activeTimers) { + if (timer.flags.contains(TimerFlag.ClearOnDeath)) + removeTimer(timer) + } + } + + fun saveTimers (root: JSONObject) { + for (timer in activeTimers) { + if (timer !is PersistTimer) continue + val obj = JSONObject() + timer.save(obj, entity) + root [timer.identifier] = obj + } + for (timer in newTimers) { + if (timer !is PersistTimer) continue + val obj = JSONObject() + timer.save(obj, entity) + root [timer.identifier] = obj + } + } + + fun parseTimers (root: JSONObject) { + for ((identifier, dataObj) in root) { + val data = dataObj as JSONObject + val timer = TimerRegistry.getTimerInstance (identifier.toString()) as? PersistTimer + + if (timer == null) { + log (this::class.java, Log.ERR, "Tried to load data for persistent timer identified by $identifier, but no such timer seems to exist.") + continue + } + + timer.parse(data, entity) + registerTimer(entity, timer) + } + } + + inline fun removeTimer () { + for (timer in activeTimers) + if (timer is T) + removeTimer(timer) + for (timer in newTimers) + if (timer is T) + removeTimer(timer) + } + + inline fun getTimer () : T? { + var t: T? = null + for (timer in activeTimers) + if (timer is T) + t = timer + for (timer in newTimers) + if (timer is T) + t = timer + if (t == null) return null + if (toRemoveTimers.contains(t)) + return null + return t + } + + fun getTimer (identifier: String): RSTimer? { + var t: RSTimer? = null + for (timer in activeTimers) + if (timer.identifier == identifier) + t = timer + for (timer in newTimers) + if (timer.identifier == identifier) + t = timer + if (t == null) return null + if (toRemoveTimers.contains(t)) return null + return t + } + + fun removeTimer (identifier: String) { + for (timer in activeTimers) + if (timer.identifier == identifier) + removeTimer(timer) + for (timer in newTimers) + if (timer.identifier == identifier) + removeTimer(timer) + } + + fun removeTimer (timer: RSTimer) { + timer.nextExecution = Int.MAX_VALUE + toRemoveTimers.add(timer) + try { timer.onRemoval(entity) } catch (e: Exception) { e.printStackTrace() } + } +} diff --git a/Server/src/main/core/game/system/timer/TimerRegistry.kt b/Server/src/main/core/game/system/timer/TimerRegistry.kt new file mode 100644 index 0000000..3aaa468 --- /dev/null +++ b/Server/src/main/core/game/system/timer/TimerRegistry.kt @@ -0,0 +1,49 @@ +package core.game.system.timer + +import java.util.* +import core.api.* +import core.tools.* +import core.game.node.entity.Entity +import core.game.node.entity.player.Player + +object TimerRegistry { + val timerMap = HashMap() + val autoTimers = ArrayList() + + fun registerTimer (timer: RSTimer) { + log (this::class.java, Log.WARN, "Registering timer ${timer::class.java.simpleName}") + if (timerMap.containsKey(timer.identifier.lowercase())) { + log (this::class.java, Log.ERR, "Timer identifier ${timer.identifier} already in use by ${timerMap[timer.identifier.lowercase()]!!::class.java.simpleName}! Not loading ${timer::class.java.simpleName}!") + return + } + timerMap[timer.identifier.lowercase()] = timer + if (timer.isAuto) autoTimers.add(timer) + } + + fun getTimerInstance (identifier: String, vararg args: Any) : RSTimer? { + var t = timerMap[identifier.lowercase()] + if (args.size > 0) + return t?.getTimer(*args) + else + return t?.retrieveInstance() + } + + @JvmStatic + fun addAutoTimers (entity: Entity) { + for (timer in autoTimers) { + if (!hasTimerActive (entity, timer.identifier)) + registerTimer (entity, timer.retrieveInstance()) + } + } + + inline fun getTimerInstance (vararg args: Any) : T? { + for ((_, inst) in timerMap) + if (inst is T) { + if (args.size > 0) + return inst.getTimer(*args) as? T + else + return inst.retrieveInstance() as? T + } + return null + } +} diff --git a/Server/src/main/core/game/system/timer/impl/AntiMacro.kt b/Server/src/main/core/game/system/timer/impl/AntiMacro.kt new file mode 100644 index 0000000..4f9ba87 --- /dev/null +++ b/Server/src/main/core/game/system/timer/impl/AntiMacro.kt @@ -0,0 +1,182 @@ +package core.game.system.timer.impl + +import content.global.ame.RandomEventNPC +import content.global.ame.RandomEvents +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.node.entity.player.info.Rights +import core.game.node.item.Item +import core.game.system.command.Privilege +import core.game.system.timer.PersistTimer +import core.game.world.map.zone.ZoneRestriction +import core.game.world.repository.Repository +import core.tools.RandomFunction +import core.tools.colorize +import org.json.simple.JSONObject + +class AntiMacro : PersistTimer(0, "antimacro", isAuto = true), Commands { + var paused = false + var nextRandom: RandomEvents? = null + + override fun run(entity: Entity): Boolean { + if (entity !is Player) return false + + setNextExecution() + + if (!canSpawn(entity)) return true + val eventSelection = rollEventPool(entity) + val eventNpc = eventSelection.npc.create(entity, eventSelection.loot, eventSelection.type) + if (eventNpc.spawnLocation == null) { + entity.debug("[AntiMacro] Attempted to spawn random, but spawnLoc was null.") + return true + } + + eventNpc.init() + setAttribute(entity, EVENT_NPC, eventNpc) + entity.debug("[AntiMacro] Fired ${eventSelection.name}.") + return true + } + + override fun onRegister(entity: Entity) { + if (entity !is Player || entity.isArtificial) + entity.timers.removeTimer(this) + if (entity is Player && entity.rights == Rights.ADMINISTRATOR) + paused = true + + if (runInterval == 0) + setNextExecution() + } + + override fun save(root: JSONObject, entity: Entity) { + root["ticksRemaining"] = (nextExecution - getWorldTicks()).toString() + } + + override fun parse(root: JSONObject, entity: Entity) { + runInterval = (root["ticksRemaining"]?.toString()?.toIntOrNull() ?: 0) + nextExecution = getWorldTicks() + runInterval + } + + private fun canSpawn(entity: Entity) : Boolean { + if (entity.zoneMonitor.isRestricted(ZoneRestriction.RANDOM_EVENTS)) + return false + + val current = getAttribute(entity, EVENT_NPC, null) + if (current != null) + return false + + if (paused) + return false + + return true + } + + private fun setNextExecution() { + runInterval = RandomFunction.random(MIN_DELAY_TICKS, MAX_DELAY_TICKS + 1) + nextExecution = getWorldTicks() + runInterval + } + + private fun rollEventPool(entity: Entity) : RandomEvents { + if (nextRandom != null) { + val result = nextRandom!! + nextRandom = null + return result + } + + val skillBasedRandom = RandomEvents.getSkillBasedRandomEvent(entity.skills.lastTrainedSkill) + val normalRandom = RandomEvents.getNonSkillRandom() + val roll = RandomFunction.random(100) + + if (roll >= 65 && skillBasedRandom != null && getWorldTicks() - entity.skills.lastXpGain < 250) + return skillBasedRandom + return normalRandom + } + + override fun defineCommands() { + define("revent", Privilege.ADMIN, "::revent [-p] player name [-e event name]", "Spawns a random event for the target player.
Optional -e parameter to pass a specific event.") {player, args -> + if (args.size == 1) { + val possible = RandomEvents.values() + for (event in possible) { + notify(player, event.name.lowercase()) + } + return@define + } + + val arg = parseCommandArgs(args.joinToString(" ")) + val target = Repository.getPlayerByName(arg.targetPlayer) + if (target == null) + reject(player, "Unable to find user ${arg.targetPlayer}.") + if (target!!.rights == Rights.ADMINISTRATOR) { + unpause(target) + sendMessage(target, colorize("%RAntiMacro timer unpaused until next login.")) + } + + forceEvent(target!!, arg.targetEvent) + } + } + + data class CommandArgs (val targetPlayer: String, val targetEvent: RandomEvents?) + + companion object { + const val EVENT_NPC = "re-npc" + const val MIN_DELAY_TICKS = 3000 + const val MAX_DELAY_TICKS = 9000 + + fun terminateEventNpc (player: Player) { + getEventNpc(player)?.terminate() + } + + fun rollEventLoot (player: Player) : ArrayList { + return getEventNpc(player)?.loot?.roll(player) ?: ArrayList() + } + + fun getEventNpc (player: Player) : RandomEventNPC? { + return getAttribute(player, EVENT_NPC, null) + } + + fun pause (player: Player) { + val timer = getTimer(player) ?: return + timer.paused = true + } + + fun unpause (player: Player) { + val timer = getTimer(player) ?: return + timer.paused = false + } + + fun forceEvent (player: Player, event: RandomEvents? = null) { + val timer = getTimer(player) ?: return + timer.nextExecution = getWorldTicks() + timer.nextRandom = event + } + + fun parseCommandArgs (args: String, commandName: String = "revent") : CommandArgs { + val tokens = args.split(" ") + val modeTokens = arrayOf("-p", "-e") + + var userString = "" + var eventString = "" + var lastMode = "-p" + + for (token in tokens) { + when (token) { + commandName -> continue + in modeTokens -> lastMode = token + else -> when (lastMode) { + "-p" -> userString += "$token " + "-e" -> eventString += "$token " + } + } + } + + val username = userString.trim().lowercase().replace(" ", "_") + val eventName = eventString.trim().uppercase().replace(" ", "_") + + var event: RandomEvents? = null + + try { event = RandomEvents.valueOf(eventName) } catch (_: Exception) {} + + return CommandArgs(username, event) + } + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/system/timer/impl/Disease.kt b/Server/src/main/core/game/system/timer/impl/Disease.kt new file mode 100644 index 0000000..cfc72ac --- /dev/null +++ b/Server/src/main/core/game/system/timer/impl/Disease.kt @@ -0,0 +1,46 @@ +package core.game.system.timer.impl + +import core.game.system.timer.* +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.world.repository.Repository +import core.game.node.entity.combat.ImpactHandler +import core.tools.RandomFunction +import org.json.simple.* + +class Disease : PersistTimer (30, "disease", flags = arrayOf(TimerFlag.ClearOnDeath)) { + var hitsLeft = 25 + + override fun save (root: JSONObject, entity: Entity) { + root["hitsLeft"] = hitsLeft.toString() + } + + override fun parse (root: JSONObject, entity: Entity) { + hitsLeft = root["hitsLeft"].toString().toInt() + } + + override fun beforeRegister (entity: Entity) { + if (hasTimerActive(entity)) + removeTimer(entity, this) + else if (entity is Player) + sendMessage(entity, "You have become diseased.") + } + + override fun run (entity: Entity) : Boolean { + var damage = RandomFunction.random(1, 5) + entity.impactHandler.manualHit(entity,damage,ImpactHandler.HitsplatType.DISEASE) + var skillId = RandomFunction.random(24) + if(skillId == 3) skillId-- + entity.skills.updateLevel(skillId,-damage,0) + if (--hitsLeft == 0 && entity is Player) + sendMessage(entity, "The disease has wore off.") + return hitsLeft > 0 + } + + override fun getTimer (vararg args: Any) : RSTimer { + val inst = Disease() + inst.hitsLeft = args.getOrNull(0) as? Int ?: 25 + return inst + } +} diff --git a/Server/src/main/core/game/system/timer/impl/DragonFireImmunity.kt b/Server/src/main/core/game/system/timer/impl/DragonFireImmunity.kt new file mode 100644 index 0000000..2f2a2b9 --- /dev/null +++ b/Server/src/main/core/game/system/timer/impl/DragonFireImmunity.kt @@ -0,0 +1,47 @@ +package core.game.system.timer.impl + +import core.game.system.timer.* +import core.api.* +import core.tools.* +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import org.json.simple.* +import org.rs09.consts.Sounds + +/** + * A timer that replicates the behavior of Dragon Fire immunity mechanics. Runs every tick. + * Will notify the player of various levels of remaining Dragon Fire immunity, and then remove itself once it has run out. + * This timer is a "soft" timer, meaning it will tick down even while other timers would normally stall (e.g. during entity delays or when the entity has a modal open.) +**/ +class DragonFireImmunity : PersistTimer (1, "dragonfire:immunity", isSoft = true, flags = arrayOf(TimerFlag.ClearOnDeath)) { + var ticksRemaining = 0 + + override fun save (root: JSONObject, entity: Entity) { + root["ticksRemaining"] = ticksRemaining.toString() + } + + override fun parse (root: JSONObject, entity: Entity) { + ticksRemaining = root["ticksRemaining"].toString().toInt() + } + + override fun run (entity: Entity) : Boolean { + ticksRemaining-- + + if (entity is Player && ticksRemaining == secondsToTicks(30)) { + sendMessage(entity, colorize("%RYou have 30 seconds remaining on your antifire potion.")) + playAudio(entity, Sounds.CLOCK_TICK_1_3120, 0, 3) + } + else if (entity is Player && ticksRemaining == 0) { + sendMessage(entity, colorize("%RYour antifire potion has expired.")) + playAudio(entity, Sounds.DRAGON_POTION_FINISHED_2607) + } + + return ticksRemaining > 0 + } + + override fun getTimer (vararg args: Any) : RSTimer { + val t = DragonFireImmunity() + t.ticksRemaining = args.getOrNull(0) as? Int ?: 100 + return t + } +} diff --git a/Server/src/main/core/game/system/timer/impl/Frozen.kt b/Server/src/main/core/game/system/timer/impl/Frozen.kt new file mode 100644 index 0000000..97fd002 --- /dev/null +++ b/Server/src/main/core/game/system/timer/impl/Frozen.kt @@ -0,0 +1,47 @@ +package core.game.system.timer.impl + +import core.game.system.timer.* +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.world.repository.Repository +import org.json.simple.* + +class Frozen : PersistTimer (1, "frozen", flags = arrayOf(TimerFlag.ClearOnDeath)) { + var shouldApplyImmunity = false + + override fun save (root: JSONObject, entity: Entity) { + root["ticksLeft"] = (nextExecution - getWorldTicks()).toString() + root["applyImmunity"] = shouldApplyImmunity + } + + override fun parse (root: JSONObject, entity: Entity) { + runInterval = root["ticksLeft"].toString().toInt() + shouldApplyImmunity = root["applyImmunity"] as? Boolean ?: false + } + + override fun beforeRegister (entity: Entity) { + if (hasTimerActive(entity)) { + removeTimer(entity, this) + return + } + if (hasTimerActive(entity)) { + removeTimer(entity, this) + return + } + } + + override fun run (entity: Entity) : Boolean { + if (shouldApplyImmunity) { + registerTimer (entity, spawnTimer(7)) + } else (entity as? Player)?.debug ("Can't apply immunity") + return false + } + + override fun getTimer (vararg args: Any) : RSTimer { + val inst = Frozen() + inst.runInterval = args.getOrNull(0) as? Int ?: 10 + inst.shouldApplyImmunity = args.getOrNull(1) as? Boolean ?: false + return inst + } +} diff --git a/Server/src/main/core/game/system/timer/impl/FrozenImmunity.kt b/Server/src/main/core/game/system/timer/impl/FrozenImmunity.kt new file mode 100644 index 0000000..250dbfe --- /dev/null +++ b/Server/src/main/core/game/system/timer/impl/FrozenImmunity.kt @@ -0,0 +1,38 @@ +package core.game.system.timer.impl + +import core.game.system.timer.* +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.world.repository.Repository +import org.json.simple.* + +class FrozenImmunity : PersistTimer (1, "frozen:immunity", flags = arrayOf(TimerFlag.ClearOnDeath)) { + var ticksRemaining = 0 + + override fun save (root: JSONObject, entity: Entity) { + root["ticksLeft"] = (nextExecution - getWorldTicks()).toString() + } + + override fun parse (root: JSONObject, entity: Entity) { + runInterval = root["ticksLeft"].toString().toInt() + } + + override fun onRegister (entity: Entity) { + if (hasTimerActive(entity)) { + removeTimer(entity) + } + (entity as? Player)?.debug("Applied frozen immunity for $runInterval ticks.") + } + + override fun run (entity: Entity) : Boolean { + (entity as? Player)?.debug("Removed frozen immunity") + return false + } + + override fun getTimer (vararg args: Any) : RSTimer { + val inst = FrozenImmunity() + inst.runInterval = args.getOrNull(0) as? Int ?: 7 + return inst + } +} diff --git a/Server/src/main/core/game/system/timer/impl/HealOverTime.kt b/Server/src/main/core/game/system/timer/impl/HealOverTime.kt new file mode 100644 index 0000000..da5016e --- /dev/null +++ b/Server/src/main/core/game/system/timer/impl/HealOverTime.kt @@ -0,0 +1,47 @@ +package core.game.system.timer.impl + +import core.game.system.timer.* +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import org.json.simple.* +import kotlin.math.min + +class HealOverTime : PersistTimer (1, "healovertime", flags = arrayOf(TimerFlag.ClearOnDeath)) { + var healRemaining = 0 + var healPerTick = 0 + + override fun run (entity: Entity) : Boolean { + var amt = min (healRemaining, healPerTick) + healRemaining -= amt + entity.skills.heal(amt) + return healRemaining > 0 + } + + override fun save (root: JSONObject, entity: Entity) { + super.save (root, entity) + root["healRemaining"] = healRemaining.toString() + root["healPerTick"] = healPerTick.toString() + } + + override fun parse (root: JSONObject, entity: Entity) { + super.parse (root, entity) + healRemaining = root["healRemaining"].toString().toInt() + healPerTick = root["healPerTick"].toString().toInt() + } + + override fun onRegister (entity: Entity) { + if (hasTimerActive(entity)) + removeTimer(entity, this) + if (hasTimerActive(entity)) + removeTimer(entity, this) + } + + override fun getTimer (vararg args: Any) : RSTimer { + val t = HealOverTime() + t.runInterval = args.getOrNull(0) as? Int ?: 100 + t.healRemaining = args.getOrNull(1) as? Int ?: 10 + t.healPerTick = args.getOrNull(2) as? Int ?: 2 + return t + } +} diff --git a/Server/src/main/core/game/system/timer/impl/Miasmic.kt b/Server/src/main/core/game/system/timer/impl/Miasmic.kt new file mode 100644 index 0000000..9af8ee3 --- /dev/null +++ b/Server/src/main/core/game/system/timer/impl/Miasmic.kt @@ -0,0 +1,30 @@ +package core.game.system.timer.impl + +import core.api.hasTimerActive +import core.api.registerTimer +import core.api.removeTimer +import core.api.spawnTimer +import core.game.node.entity.Entity +import core.game.system.timer.PersistTimer +import core.game.system.timer.RSTimer +import core.game.system.timer.TimerFlag + +class Miasmic : PersistTimer (1, "miasmic", flags = arrayOf(TimerFlag.ClearOnDeath)) { + override fun run (entity: Entity) : Boolean { + registerTimer (entity, spawnTimer(entity, 7)) + return false + } + + override fun beforeRegister (entity: Entity) { + if (hasTimerActive(entity)) + removeTimer(entity, this) + if (hasTimerActive(entity)) + removeTimer(entity, this) + } + + override fun getTimer (vararg args: Any) : RSTimer { + val t = Miasmic() + t.runInterval = args.getOrNull(0) as? Int ?: 100 + return t + } +} diff --git a/Server/src/main/core/game/system/timer/impl/MiasmicImmunity.kt b/Server/src/main/core/game/system/timer/impl/MiasmicImmunity.kt new file mode 100644 index 0000000..2ce41cb --- /dev/null +++ b/Server/src/main/core/game/system/timer/impl/MiasmicImmunity.kt @@ -0,0 +1,25 @@ +package core.game.system.timer.impl + +import core.api.hasTimerActive +import core.api.removeTimer +import core.game.node.entity.Entity +import core.game.system.timer.PersistTimer +import core.game.system.timer.RSTimer +import core.game.system.timer.TimerFlag + +class MiasmicImmunity : PersistTimer (1, "miasmic:immunity", flags = arrayOf(TimerFlag.ClearOnDeath)) { + override fun run (entity: Entity) : Boolean { + return false + } + + override fun onRegister (entity: Entity) { + if (hasTimerActive(entity)) + removeTimer(entity) + } + + override fun getTimer (vararg args: Any) : RSTimer { + val t = MiasmicImmunity() + t.runInterval = args.getOrNull(0) as? Int ?: 100 + return t + } +} diff --git a/Server/src/main/core/game/system/timer/impl/Poison.kt b/Server/src/main/core/game/system/timer/impl/Poison.kt new file mode 100644 index 0000000..6f87d40 --- /dev/null +++ b/Server/src/main/core/game/system/timer/impl/Poison.kt @@ -0,0 +1,73 @@ +package core.game.system.timer.impl + +import core.game.system.timer.* +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.node.entity.combat.ImpactHandler +import core.game.world.repository.Repository +import org.json.simple.* + +/** + * A timer that replicates the behavior of poison mechanics. Runs every 30 ticks. + * If you wish to construct an instance of this Timer, consider using the ContentAPI function `applyPoison` instead. + * If that doesn't suit your needs, then use `Poison.getTimer (source, severity)` and then `registerTimer(entity, timer)` + * Poison mechanics are driven by the `severity` value, which is not a 1:1 representation of damage. Instead the formula `floor((severity + 4) / 5)` is used. + * Every time the damage is applied, the severity decreases by 1. Poison ends when severity reaches 0. + * Example: 30 Severity. Deals 6 damage 5 times, then 5 damage 5 times, and so on. +**/ +class Poison : PersistTimer (30, "poison", flags = arrayOf(TimerFlag.ClearOnDeath)) { + lateinit var damageSource: Entity + + var severity = 0 + set (value) { + if (value != field - 1 && value % 10 == 8) {//This was Arios's incorrect attempt at replicating severity, convert it to correct values. + (damageSource as? Player)?.debug ("[PoisonTimer] Warning: Converting suspect Arios severity into true severity. If numbers look wrong, this could be why.") + field = (value / 10) * 5 + (damageSource as? Player)?.debug ("[PoisonTimer] Warning: New Severity: $field.") + } else field = value + } + + override fun save (root: JSONObject, entity: Entity) { + root["source-uid"] = (damageSource as? Player)?.details?.uid ?: -1 + root["severity"] = severity.toString() + } + + override fun parse (root: JSONObject, entity: Entity) { + val uid = root["source-uid"].toString().toInt() + damageSource = Repository.getPlayerByUid (uid) ?: entity + severity = root["severity"].toString().toInt() + } + + override fun onRegister (entity: Entity) { + if (entity is Player) { + sendMessage(entity, "You have been poisoned.") + entity.debug ("[Poison] -> Received for $severity severity.") + } + if (damageSource is Player) + (damageSource as? Player)?.debug ("[Poison] -> Applied for $severity severity.") + } + + override fun run (entity: Entity) : Boolean { + entity.impactHandler.manualHit ( + damageSource, + getDamageFromSeverity (severity--), + ImpactHandler.HitsplatType.POISON + ) + + if (severity == 0 && entity is Player) + sendMessage(entity, "The poison has worn off.") + return severity > 0 + } + + override fun getTimer (vararg args: Any) : RSTimer { + val timer = Poison() + timer.damageSource = args[0] as? Entity ?: return timer + timer.severity = args[1] as? Int ?: return timer + return timer + } + + private fun getDamageFromSeverity (severity: Int) : Int { + return (severity + 4) / 5 + } +} diff --git a/Server/src/main/core/game/system/timer/impl/PoisonImmunity.kt b/Server/src/main/core/game/system/timer/impl/PoisonImmunity.kt new file mode 100644 index 0000000..1695fce --- /dev/null +++ b/Server/src/main/core/game/system/timer/impl/PoisonImmunity.kt @@ -0,0 +1,51 @@ +package core.game.system.timer.impl + +import core.game.system.timer.* +import core.api.* +import core.tools.* +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import org.json.simple.* +import org.rs09.consts.Sounds + +/** + * A timer that replicates the behavior of poison immunity mechanics. Runs every tick. + * Will notify the player of various levels of remaining poison immunity, and then remove itself once it has run out. + * This timer is a "soft" timer, meaning it will tick down even while other timers would normally stall (e.g. during entity delays or when the entity has a modal open.) +**/ +class PoisonImmunity : PersistTimer (1, "poison:immunity", isSoft = true, flags = arrayOf(TimerFlag.ClearOnDeath)) { + var ticksRemaining = 0 + + override fun save (root: JSONObject, entity: Entity) { + root["ticksRemaining"] = ticksRemaining.toString() + } + + override fun parse (root: JSONObject, entity: Entity) { + ticksRemaining = root["ticksRemaining"].toString().toInt() + } + + override fun onRegister (entity: Entity) { + removeTimer(entity) + } + + override fun run (entity: Entity) : Boolean { + ticksRemaining-- + + if (entity is Player && ticksRemaining == secondsToTicks(30)) { + sendMessage(entity, colorize("%RYou have 30 seconds remaining on your poison immunity.")) + playAudio(entity, Sounds.CLOCK_TICK_1_3120, 0, 3) + } + else if (entity is Player && ticksRemaining == 0) { + sendMessage(entity, colorize("%RYour poison immunity has expired.")) + playAudio(entity, Sounds.DRAGON_POTION_FINISHED_2607) + } + + return ticksRemaining > 0 + } + + override fun getTimer (vararg args: Any) : RSTimer { + val t = PoisonImmunity() + t.ticksRemaining = args.getOrNull(0) as? Int ?: 100 + return t + } +} diff --git a/Server/src/main/core/game/system/timer/impl/SkillRestore.kt b/Server/src/main/core/game/system/timer/impl/SkillRestore.kt new file mode 100644 index 0000000..b6b4566 --- /dev/null +++ b/Server/src/main/core/game/system/timer/impl/SkillRestore.kt @@ -0,0 +1,101 @@ +package core.game.system.timer.impl + +import core.api.* +import core.api.Event +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.prayer.PrayerType +import core.game.node.entity.skill.Skills +import core.game.system.timer.* +import core.game.event.* + +import org.rs09.consts.Items + +class SkillRestore : RSTimer (1, "skillrestore", isAuto = true, isSoft = true) { + val ticksSinceLastRestore = IntArray (25) + val restoreTicks = IntArray (25) { 100 } + + override fun run (entity: Entity) : Boolean { + var skills = entity.skills + + for (i in 0 until 24) { + if (i == Skills.PRAYER || i == Skills.SUMMONING) continue + if (ticksSinceLastRestore[i]++ >= restoreTicks[i]) { + if (i == Skills.HITPOINTS && entity.skills.lifepoints < entity.skills.maximumLifepoints) { + skills.heal (getHealAmount(entity)) + } else { + val max = getStatLevel (entity, i) + val current = getDynLevel (entity, i) + + if (current != max) + skills.updateLevel (i, if (current < max) 1 else -1, max) + } + ticksSinceLastRestore[i] = 0 + } + } + + if (entity is Player && ticksSinceLastRestore[24]++ >= 50) { + entity.settings.setSpecialEnergy (kotlin.math.min (100, entity.settings.specialEnergy + 10)) + ticksSinceLastRestore[24] = 0 + } + + return true + } + + override fun onRegister (entity: Entity) { + entity.hook (Event.PrayerActivated, PrayerActivatedHook) + entity.hook (Event.PrayerDeactivated, PrayerDeactivatedHook) + (entity as? Player)?.debug("Registered skill restoration timer.") + } + + private fun getHealAmount (entity: Entity) : Int { + if (entity !is Player) return 1 + + val gloves = getItemFromEquipment (entity, EquipmentSlot.HANDS) + if (gloves == null || gloves.id != Items.REGEN_BRACELET_11133) + return 1 + else return 2 + } + + object PrayerActivatedHook : EventHook { + override fun process (entity: Entity, event: PrayerActivatedEvent) { + val restore = getOrStartTimer (entity) + + when (event.type) { + PrayerType.RAPID_HEAL -> { + restore.restoreTicks [Skills.HITPOINTS] = 50 + restore.ticksSinceLastRestore [Skills.HITPOINTS] = 0 + } + PrayerType.RAPID_RESTORE -> { + for (i in 0 until 24) { + if (i == Skills.HITPOINTS || i == Skills.PRAYER || i == Skills.SUMMONING) continue + restore.restoreTicks [i] = 50 + restore.ticksSinceLastRestore [i] = 0 + } + } + else -> {} + } + } + } + + object PrayerDeactivatedHook : EventHook { + override fun process (entity: Entity, event: PrayerDeactivatedEvent) { + val restore = getOrStartTimer (entity) + + when (event.type) { + PrayerType.RAPID_HEAL -> { + restore.restoreTicks [Skills.HITPOINTS] = 100 + restore.ticksSinceLastRestore [Skills.HITPOINTS] = 0 + } + PrayerType.RAPID_RESTORE -> { + for (i in 0 until 24) { + if (i == Skills.HITPOINTS || i == Skills.PRAYER || i == Skills.SUMMONING) continue + restore.restoreTicks [i] = 100 + restore.ticksSinceLastRestore [i] = 0 + } + } + else -> {} + } + } + } +} diff --git a/Server/src/main/core/game/system/timer/impl/Skulled.kt b/Server/src/main/core/game/system/timer/impl/Skulled.kt new file mode 100644 index 0000000..fee4474 --- /dev/null +++ b/Server/src/main/core/game/system/timer/impl/Skulled.kt @@ -0,0 +1,27 @@ +package core.game.system.timer.impl + +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.system.timer.PersistTimer +import core.game.system.timer.RSTimer +import core.game.system.timer.TimerFlag + +class Skulled : PersistTimer (1, "skulled", flags = arrayOf(TimerFlag.ClearOnDeath)) { + override fun onRegister (entity: Entity) { + if (entity !is Player) return + entity.skullManager.setSkullIcon(0) + entity.skullManager.setSkulled(true) + } + + override fun run (entity: Entity) : Boolean { + if (entity !is Player) return false + entity.skullManager.reset() + return false + } + + override fun getTimer (vararg args: Any) : RSTimer { + val t = Skulled() + t.runInterval = args.getOrNull(0) as? Int ?: 500 + return t + } +} diff --git a/Server/src/main/core/game/system/timer/impl/Teleblock.kt b/Server/src/main/core/game/system/timer/impl/Teleblock.kt new file mode 100644 index 0000000..47f33a8 --- /dev/null +++ b/Server/src/main/core/game/system/timer/impl/Teleblock.kt @@ -0,0 +1,25 @@ +package core.game.system.timer.impl + +import core.api.sendMessage +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.system.timer.PersistTimer +import core.game.system.timer.RSTimer +import core.game.system.timer.TimerFlag + +class Teleblock : PersistTimer (1, "teleblock", flags = arrayOf(TimerFlag.ClearOnDeath)) { + override fun run (entity: Entity) : Boolean { + return false + } + + override fun onRegister (entity: Entity) { + if (entity !is Player) return + sendMessage (entity, "You have been teleblocked.") + } + + override fun getTimer (vararg args: Any) : RSTimer { + val t = Teleblock() + t.runInterval = args.getOrNull(0) as? Int ?: 100 + return t + } +} diff --git a/Server/src/main/core/game/world/DeadlockDetector.kt b/Server/src/main/core/game/world/DeadlockDetector.kt new file mode 100644 index 0000000..f64d97e --- /dev/null +++ b/Server/src/main/core/game/world/DeadlockDetector.kt @@ -0,0 +1,38 @@ +package core.game.world + +import core.api.log +import core.tools.Log +import core.tools.SystemLogger +import java.lang.management.ManagementFactory + +class DeadlockDetector : Runnable { + override fun run() { + val mbean = ManagementFactory.getThreadMXBean() + val deadLockedThreads = mbean.findDeadlockedThreads() + + + + + fun `(┛◉Д◉)┛彡┻━┻`() { + val infos = mbean.getThreadInfo(deadLockedThreads) + infos.forEach { threadInfo -> + if (threadInfo != null) { + for (thread in Thread.getAllStackTraces().keys) { + if (thread.id == threadInfo.threadId) { + log(this::class.java, Log.ERR, threadInfo.toString().trim()) + for (ste in thread.stackTrace) { + log(this::class.java, Log.ERR, "\t" + ste.toString().trim { it <= ' ' }) + } + } + } + } + } + } + + + if(deadLockedThreads != null){ + `(┛◉Д◉)┛彡┻━┻`() + } + + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/world/GameSettings.kt b/Server/src/main/core/game/world/GameSettings.kt new file mode 100644 index 0000000..c75a55e --- /dev/null +++ b/Server/src/main/core/game/world/GameSettings.kt @@ -0,0 +1,200 @@ +package core.game.world + +import org.json.simple.JSONObject +import core.ServerConstants +import java.io.FileInputStream +import java.io.IOException +import java.util.* +/** + * Represents the game settings used for this game instance. + * @author Vexia + */ +class GameSettings +/** + * Constructs a new `GameSettings` `Object`. + * @param name the name. + * @param beta the beta. + * @param type the game type. + * @param gui if gui is enabled. + * @param worldId the world id. + * @param countryIndex The country index. + * @param members If the world is members only. + * @param msAddress The address of the Management server. + */ internal constructor( + /** + * The name of the namme. + */ + var name: String, + /** + * If the game is in beta mode. + */ + var isBeta: Boolean, + /** + * If the game is in developer mode. + */ + var isDevMode: Boolean, + /** + * If the gui is enabled. + */ + var isGui: Boolean, + /** + * The world id of the server. + */ + var worldId: Int, + /** + * The country index. + */ + var countryIndex: Int, + /** + * The activity. + */ + var activity: String, + /** + * If the world is members only. + */ + var isMembers: Boolean, + /** + * If the world is a pvp world. + */ + var isPvp: Boolean, + /** + * If only quick chat can be used on the world. + */ + var isQuickChat: Boolean, + /** + * If lootshare option is enabled on this world. + */ + var isLootshare: Boolean, + /** + * The address of the Management server. + */ + var msAddress: String, + var default_xp_rate: Double, + var allow_slayer_reroll: Boolean, + var enable_default_clan: Boolean, + var enable_bots: Boolean, + var autostock_ge: Boolean, + var allow_token_purchase: Boolean, + var skillcape_perks: Boolean, + var increased_door_time: Boolean, + var enabled_botting : Boolean, + var max_adv_bots: Int, + var enable_doubling_money_scammers: Boolean, + var wild_pvp_enabled: Boolean, + var jad_practice_enabled: Boolean, + var ge_announcement_limit: Int, + var smartpathfinder_bfs: Boolean, + var enable_castle_wars: Boolean, + + /**"Lobby" interface + * The message of the week models to display + * 15 & 22 = keys & lock || 16 = fly swat || 17 = person with question marks || 18 & 447 = wise old man + * 19 = man & woman with mouth closed || 20 = man & lock & key || 21 = closed chests + * 23 = snowmen || 405 = Construction houses || 622 = Two sets of 3 people range, mage, melee + * 623 = Woodcutting || 679 = Summoning || 715 = Easter || 800 = Halloween + * Any value that isn't one listed above = random selection + */ + var message_model: Int, + + /**"Lobby" interface + * The message of the week text + * The "child" for writing text to these interfaces is located inside of LoginConfiguration.java + * method: getMessageChild + */ + var message_string: String + ) { + val isHosted: Boolean + get() = !isDevMode + + override fun toString(): String { + return "GameSettings [name=$name, debug=$isBeta, devMode=$isDevMode, gui=$isGui, worldId=$worldId]" + } + + companion object { + /** + * Parses a JSONObject and creates a new GameSettings object from it. + * @param data the JSONObject to parse. + * @return the settings object. + * @author Ceikry + */ + fun parse(data: JSONObject): GameSettings? { + val name = ServerConstants.SERVER_NAME + val debug = data["debug"] as Boolean + val dev = data["dev"] as Boolean + val startGui = data["startGui"] as Boolean + val worldId = data["worldID"].toString().toInt() + val countryId = data["countryID"].toString().toInt() + val activity = data["activity"].toString() + val pvpWorld = data["pvpWorld"] as Boolean + val msip = data["msip"].toString() + val default_xp_rate = data["default_xp_rate"].toString().toDouble() + val allow_slayer_reroll = data["allow_slayer_reroll"] as Boolean + val enable_default_clan = data["enable_default_clan"] as Boolean + val enable_bots = data["enable_bots"] as Boolean + val autostock_ge = data["autostock_ge"] as Boolean + val skillcape_perks = if(data.containsKey("skillcape_perks")) data["skillcape_perks"] as Boolean else false + val increased_door_time = if(data.containsKey("increased_door_time")) data["increased_door_time"] as Boolean else false + val enable_botting = if(data.containsKey("botting_enabled")) data["botting_enabled"] as Boolean else false + val max_adv_bots = if(data.containsKey("max_adv_bots")) data["max_adv_bots"].toString().toInt() else 100 + val enable_doubling_money_scammers = if(data.containsKey("enable_doubling_money_scammers")) data["enable_doubling_money_scammers"] as Boolean else false + val wild_pvp_enabled = if(data.containsKey("wild_pvp_enabled")) data["wild_pvp_enabled"] as Boolean else true + val jad_practice_enabled = if(data.containsKey("jad_practice_enabled")) data["jad_practice_enabled"] as Boolean else true + val ge_announcement_limit = data["ge_announcement_limit"].toString().toInt() + val smartpathfinder_bfs = if(data.containsKey("smartpathfinder_bfs")) data["smartpathfinder_bfs"] as Boolean else false + val enable_castle_wars = if(data.containsKey("enable_castle_wars")) data["enable_castle_wars"] as Boolean else false + val allow_token_purchase = data["allow_token_purchase"] as Boolean + val message_of_the_week_identifier = data["message_of_the_week_identifier"].toString().toInt() + val message_of_the_week_text = data["message_of_the_week_text"].toString() + return GameSettings( + name, + debug, + dev, + startGui, + worldId, + countryId, + activity, + true, + pvpWorld, + false, + false, + msip, + default_xp_rate, + allow_slayer_reroll, + enable_default_clan, + enable_bots, + autostock_ge, + allow_token_purchase, + skillcape_perks, + increased_door_time, + enable_botting, + max_adv_bots, + enable_doubling_money_scammers, + wild_pvp_enabled, + jad_practice_enabled, + ge_announcement_limit, + smartpathfinder_bfs, + enable_castle_wars, + message_of_the_week_identifier, + message_of_the_week_text + ) + } + + /** + * Gets the properties. + * @param path the path. + * @return the properties. + */ + private fun getProperties(path: String): Properties { + val file: FileInputStream + val properties = Properties() + try { + file = FileInputStream(path) + properties.load(file) + } catch (e: IOException) { + println("Warning: Could not find file in " + System.getProperty("user.dir") + path) + e.printStackTrace() + } + return properties + } + } +} diff --git a/Server/src/main/core/game/world/GameWorld.kt b/Server/src/main/core/game/world/GameWorld.kt new file mode 100644 index 0000000..2c0b55e --- /dev/null +++ b/Server/src/main/core/game/world/GameWorld.kt @@ -0,0 +1,220 @@ +package core.game.world + +import core.api.* +import core.cache.Cache +import core.cache.def.impl.SceneryDefinition +import core.game.node.entity.player.Player +import core.game.system.SystemManager +import core.game.system.SystemState +import core.game.system.task.Pulse +import core.game.system.task.TaskExecutor +import core.game.world.map.Location +import core.game.world.map.Region +import core.game.world.map.RegionManager +import core.plugin.CorePluginTypes.StartupPlugin +import core.tools.RandomFunction +import core.ServerConstants +import core.ServerStore +import core.auth.AuthProvider +import core.auth.Auth +import core.game.system.config.ConfigParser +import core.game.world.repository.Repository +import core.plugin.ClassScanner +import core.storage.AccountStorageProvider +import core.tools.Log +import core.worker.MajorUpdateWorker +import java.text.SimpleDateFormat +import java.util.* +import java.util.function.Consumer +import kotlin.collections.ArrayList + +/** + * Represents the game world. + * @author Ceikry + */ +object GameWorld { + @JvmStatic + val worldPersists = ArrayList() + + /** + * The major update worker. + */ + @JvmStatic + val majorUpdateWorker = MajorUpdateWorker() + + /** + * Login listeners + */ + @JvmStatic + val loginListeners = ArrayList() + + /** + * Logout listeners + */ + @JvmStatic + val logoutListeners = ArrayList() + + /** + * Tick listeners + */ + @JvmStatic + val tickListeners = ArrayList() + + /** + * Startup Listeners + */ + @JvmStatic + val startupListeners = ArrayList() + + /** + * Shutdown Listeners + */ + @JvmStatic + val shutdownListeners = ArrayList() + + @JvmStatic + val STARTUP_PLUGINS: List = ArrayList() + private val configParser = ConfigParser() + @JvmStatic + var PCBotsSpawned = false + @JvmStatic + var PCnBotsSpawned = false + @JvmStatic + var PCiBotsSpawned = false + /** + * The game settings to use. + */ + @JvmStatic + var settings: GameSettings? = null + @JvmStatic + val authenticator: AuthProvider<*> + get() = Auth.authenticator + @JvmStatic + val accountStorage: AccountStorageProvider + get() = Auth.storageProvider + /** + * The current amount of (600ms) cycles elapsed. + */ + @JvmStatic + var ticks = 0 + + @JvmStatic + var Pulser = PulseRunner() + + /** + * Submits a pulse. + * + * @param pulse the pulse. + */ + @Deprecated("", ReplaceWith("Pulser.submit(pulse!!)", "core.game.world.GameWorld.Pulser")) + fun submit(pulse: Pulse?) { + Pulser.submit(pulse!!) + } + + fun pulse() { + ticks++ + if (ticks % 50 == 0) { + TaskExecutor.execute { + val player = Repository.players + try { + player.stream().filter { obj: Player? -> Objects.nonNull(obj) }.filter { p: Player -> !p.isArtificial && p.isPlaying }.forEach { p: Player? -> Repository.disconnectionQueue.save(p!!, false) } + } catch (t: Throwable) { + t.printStackTrace() + } + } + } + } + + fun checkDay(): Int { + val weeklySdf = SimpleDateFormat("u") + return weeklySdf.format(Date()).toInt() + } + + /** + * Prompts the [GameWorld] to begin it's initialization. + * + * @param directory the directory to the properties. + * @throws Throwable when the exception occurs. + */ + @Throws(Throwable::class) + fun prompt(directory: String?) { + prompt(true, directory) + } + + /** + * Prompts the game world. + * + * @param running if running. + * @throws Throwable the throwable. + */ + @Throws(Throwable::class) + @JvmStatic + fun prompt(running: Boolean) { + prompt(running, "server.properties") + } + + /** + * Prompts the [GameWorld] to begin its initialization. + * + * @param run If the server should be running. + * @param directory the path to the dir. + * @throws Throwable When an exception occurs. + */ + @Throws(Throwable::class) + fun prompt(run: Boolean, directory: String?){ + log(GameWorld::class.java, Log.FINE, "Prompting ${settings?.name} Game World...") + Cache.init(ServerConstants.CACHE_PATH) + //go overboard with checks to make sure dev mode authenticator never triggers on live + Auth.configure() + ConfigParser().prePlugin() + ClassScanner.scanClasspath() + ClassScanner.loadPureInterfaces() + ClassScanner.loadTimers() + val s = worldPersists.filterIsInstance().first() + s.parse() + worldPersists.filter { it !is ServerStore }.forEach { it.parse() } + ClassScanner.loadSideEffectfulPlugins() + configParser.postPlugin() + startupListeners.forEach { it.startup() } + if (run) { + SystemManager.flag(if (settings?.isDevMode == true) SystemState.PRIVATE else SystemState.ACTIVE) + } + SceneryDefinition.getDefinitions().values.forEach(Consumer { obj: SceneryDefinition -> obj.examine }) + + if (ServerConstants.PRELOAD_MAP) { + //force early loading of all commonly accessed regions to improve performance at the cost of memory usage + (7483..15420).forEach { id -> RegionManager.forId(id).also { Region.load(it) } } + } + + System.gc() + } + + /** + * Called when the server shuts down. + * + * @throws Throwable When an exception occurs. + */ + @Throws(Throwable::class) + fun shutdown() { + SystemManager.flag(SystemState.TERMINATED) + } + + /** + * Checks if its the economy world. + * + * @return `True` if so. + */ + @JvmStatic + val isEconomyWorld: Boolean + get() = false + + private fun generateLocation(): Location { + val random_location = Location(3075 + RandomFunction.random(-15, 15), 3954 + RandomFunction.random(-15, 15), 0) + if (!RegionManager.isTeleportPermitted(random_location)) { + return generateLocation() + } + return if (RegionManager.getObject(random_location) != null) { + generateLocation() + } else random_location + } +} diff --git a/Server/src/main/core/game/world/ImmerseWorld.kt b/Server/src/main/core/game/world/ImmerseWorld.kt new file mode 100644 index 0000000..2adee48 --- /dev/null +++ b/Server/src/main/core/game/world/ImmerseWorld.kt @@ -0,0 +1,257 @@ +package core.game.world + +import content.global.bots.* +import core.api.StartupListener +import core.game.node.entity.combat.CombatStyle +import core.game.world.map.Location +import core.game.world.map.zone.ZoneBorders +import core.game.bots.GeneralBotCreator +import core.game.bots.CombatBotAssembler +import core.game.bots.SkillingBotAssembler +import java.util.Timer +import java.util.concurrent.Executors +import kotlin.concurrent.schedule +import kotlin.random.Random + +class ImmerseWorld : StartupListener { + + override fun startup() { + if(GameWorld.settings?.max_adv_bots!! > 0) { + spawnBots() + } + } + + companion object { + var assembler = CombatBotAssembler() + var skillingBotAssembler = SkillingBotAssembler() + + private fun randomizeLocationInRanges(location: Location, xMin: Int, xMax: Int, yMin: Int, yMax: Int): Location { + val newX = location.x + Random.nextInt(xMin, xMax) + val newY = location.y + Random.nextInt(yMin, yMax) + return Location(newX, newY, 0) + } + + fun spawnBots() + { + if(GameWorld.settings!!.enable_bots) + { + Executors.newSingleThreadExecutor().execute { + Thread.currentThread().name = "BotSpawner" + immerseSeersAndCatherby() + immerseLumbridgeDraynor() + immerseVarrock() + immerseWilderness() + immerseFishingGuild() + immerseAdventurer() + immerseFalador() + // immerseSlayer() + immerseGE() + } + } + } + + fun immerseAdventurer(){ + for (i in 0..(GameWorld.settings?.max_adv_bots ?: 50)){ + var random = Random.nextInt(20000, 400000).toLong() + Timer().schedule(random){ + spawn_adventurers() + } + } + } + + fun spawn_adventurers() { + val lumbridge = Location.create(3221, 3219, 0) + val tiers = listOf(CombatBotAssembler.Tier.LOW, CombatBotAssembler.Tier.MED) + if (Random.nextBoolean()) { + GeneralBotCreator( + Adventurer(CombatStyle.MELEE), + assembler.MeleeAdventurer(tiers.random(), randomizeLocationInRanges(lumbridge,-1,1,-1,1)) + ) + } else { + GeneralBotCreator( + Adventurer(CombatStyle.RANGE), + assembler.RangeAdventurer(tiers.random(), randomizeLocationInRanges(lumbridge,-1,1,-1,1)) + ) + } + } + + fun immerseFishingGuild() { + val fishingGuild = Location.create(2604, 3421, 0) + for (i in (0..4)) { + GeneralBotCreator(SharkCatcher(), fishingGuild) + } + } + + fun immerseSeersAndCatherby() { + GeneralBotCreator( + SeersMagicTrees(), + skillingBotAssembler.produce(SkillingBotAssembler.Wealth.AVERAGE, Location.create(2702, 3397, 0)) + ) + GeneralBotCreator( + SeersFlax(), + skillingBotAssembler.produce(SkillingBotAssembler.Wealth.POOR, Location.create(2738, 3444, 0)) + ) + GeneralBotCreator( + FletchingBankstander(), + skillingBotAssembler.produce(SkillingBotAssembler.Wealth.AVERAGE, Location.create(2722, 3493, 0)) + ) + GeneralBotCreator( + GlassBlowingBankstander(), + skillingBotAssembler.produce(SkillingBotAssembler.Wealth.AVERAGE, Location.create(2807, 3441, 0)) + ) + GeneralBotCreator(LobsterCatcher(), Location.create(2805, 3435, 0)) + } + + fun immerseLumbridgeDraynor() { + GeneralBotCreator( + CowKiller(), + assembler.produce( + CombatBotAssembler.Type.RANGE, + CombatBotAssembler.Tier.MED, + Location.create(3261, 3269, 0) + ) + ) + GeneralBotCreator( + CowKiller(), + assembler.produce( + CombatBotAssembler.Type.MELEE, + CombatBotAssembler.Tier.LOW, + Location.create(3261, 3269, 0) + ) + ) + GeneralBotCreator( + CowKiller(), + assembler.produce( + CombatBotAssembler.Type.MELEE, + CombatBotAssembler.Tier.MED, + Location.create(3257, 3267, 0) + ) + ) + GeneralBotCreator( + ManThiever(), + skillingBotAssembler.produce(SkillingBotAssembler.Wealth.POOR, Location.create(3235, 3213, 0)) + ) + GeneralBotCreator( + FarmerThiever(), + skillingBotAssembler.produce(SkillingBotAssembler.Wealth.POOR, Location.create(3094, 3243, 0)) + ) + GeneralBotCreator( + FarmerThiever(), + skillingBotAssembler.produce(SkillingBotAssembler.Wealth.POOR, Location.create(3094, 3243, 0)) + ) + GeneralBotCreator( + DraynorWillows(), + skillingBotAssembler.produce( + SkillingBotAssembler.Wealth.values().random(), + Location.create(3094, 3245, 0) + ) + ) + GeneralBotCreator( + DraynorWillows(), + skillingBotAssembler.produce( + SkillingBotAssembler.Wealth.values().random(), + Location.create(3094, 3245, 0) + ) + ) + GeneralBotCreator( + DraynorWillows(), + skillingBotAssembler.produce( + SkillingBotAssembler.Wealth.values().random(), + Location.create(3094, 3245, 0) + ) + ) + GeneralBotCreator( + DraynorFisher(), + skillingBotAssembler.produce(SkillingBotAssembler.Wealth.POOR, Location.create(3095, 3246, 0)) + ) + GeneralBotCreator( + DraynorFisher(), + skillingBotAssembler.produce(SkillingBotAssembler.Wealth.POOR, Location.create(3095, 3246, 0)) + ) + GeneralBotCreator( + DraynorFisher(), + skillingBotAssembler.produce(SkillingBotAssembler.Wealth.POOR, Location.create(3095, 3246, 0)) + ) + } + + fun immerseVarrock() { + val WestBankIdlerBorders = ZoneBorders(3184, 3435, 3187, 3444) + GeneralBotCreator( + GlassBlowingBankstander(), + skillingBotAssembler.produce(SkillingBotAssembler.Wealth.RICH, Location.create(3189, 3435, 0)) + ) + GeneralBotCreator( + FletchingBankstander(), + skillingBotAssembler.produce(SkillingBotAssembler.Wealth.AVERAGE, Location.create(3189, 3439, 0)) + ) + GeneralBotCreator( + Idler(), + skillingBotAssembler.produce(SkillingBotAssembler.Wealth.RICH, WestBankIdlerBorders.randomLoc) + ) + GeneralBotCreator( + GlassBlowingBankstander(), + skillingBotAssembler.produce(SkillingBotAssembler.Wealth.POOR, Location.create(3256, 3420, 0)) + ) + GeneralBotCreator( + VarrockEssenceMiner(), + skillingBotAssembler.produce(SkillingBotAssembler.Wealth.POOR, Location.create(3253, 3420, 0)) + ) + GeneralBotCreator( + VarrockSmither(), + skillingBotAssembler.produce(SkillingBotAssembler.Wealth.RICH, Location.create(3189, 3436, 0)) + ) + GeneralBotCreator( + NonBankingMiner(), + skillingBotAssembler.produce(SkillingBotAssembler.Wealth.POOR, Location.create(3182, 3374, 0)) + ) + } + + fun immerseWilderness() { + val wilderness = Location.create(3092, 3493, 0) + + repeat(6) { + GeneralBotCreator ( + GreenDragonKiller(CombatStyle.MELEE), + assembler.assembleMeleeDragonBot(CombatBotAssembler.Tier.MED, wilderness) + ) + } + } + + fun immerseFalador() { + GeneralBotCreator( + CoalMiner(), + skillingBotAssembler.produce(SkillingBotAssembler.Wealth.POOR, Location.create(3037, 9737, 0)) + ) + GeneralBotCreator( + CannonballSmelter(), + skillingBotAssembler.produce(SkillingBotAssembler.Wealth.AVERAGE, Location.create(3013, 3356, 0)) + ) + } + + fun immerseSlayer() { + GeneralBotCreator( + GenericSlayerBot(), + assembler.produce( + CombatBotAssembler.Type.MELEE, + CombatBotAssembler.Tier.HIGH, + Location.create(2673, 3635, 0) + ) + ) + } + + private fun immerseGE() { + spawnDoubleMoneyBot(false) + } + + fun spawnDoubleMoneyBot(delay: Boolean) { + if (GameWorld.settings?.enable_doubling_money_scammers != true) return + val random: Long = (10_000..7_200_000).random().toLong() + Timer().schedule(if (delay) random else 0) { + GeneralBotCreator ( + DoublingMoney(), + skillingBotAssembler.produce(SkillingBotAssembler.Wealth.POOR, DoublingMoney.startingLocs.random()) + ) + } + } + } +} diff --git a/Server/src/main/core/game/world/PulseRunner.kt b/Server/src/main/core/game/world/PulseRunner.kt new file mode 100644 index 0000000..e320cd7 --- /dev/null +++ b/Server/src/main/core/game/world/PulseRunner.kt @@ -0,0 +1,83 @@ +package core.game.world + +import core.api.log +import core.game.system.task.Pulse +import core.game.bots.GeneralBotCreator +import core.tools.Log +import core.tools.SystemLogger +import core.ServerConstants +import java.util.concurrent.LinkedBlockingQueue +import core.integrations.grafana.* + +class PulseRunner { + private val pulses = LinkedBlockingQueue() + + val currentPulses: Array get() = pulses.toTypedArray() + + fun submit(pulse: Pulse) { + pulses.add(pulse) + } + + fun updateAll() { + val pulseCount = pulses.size + + var totalTimeBotPulses = 0 + var totalTimeOtherPulses = 0 + for (i in 0 until pulseCount) { + val pulse = pulses.take() + + val elapsedTime = measure { + try { + if (!pulse.update() && pulse.isRunning) { + pulses.add(pulse) + } + } catch (e: Exception) { + log(this::class.java, Log.ERR, "Pulse execution error. Stack trace below.") + e.printStackTrace() + } + } + + var pulseName = pulse::class.java.name + + if (pulse is GeneralBotCreator.BotScriptPulse || pulseName.contains("ScriptAPI")) { + totalTimeBotPulses += elapsedTime.toInt() + } else { + totalTimeOtherPulses += elapsedTime.toInt() + } + + Grafana.addPulseLength (pulseName, elapsedTime.toInt()) + Grafana.countPulse (pulseName) + + notifyIfTooLong(pulse, elapsedTime) + } + + if (ServerConstants.GRAFANA_LOGGING) { + Grafana.botPulseTime = totalTimeBotPulses + Grafana.otherPulseTime = totalTimeOtherPulses + } + } + + private fun measure(logic: () -> Unit): Long { + val startTime = System.currentTimeMillis() + + logic() + + return System.currentTimeMillis() - startTime + } + + private fun notifyIfTooLong(pulse: Pulse, elapsedTime: Long) { + if (elapsedTime >= 100) { + if (pulse is GeneralBotCreator.BotScriptPulse) { + log(this::class.java, Log.WARN, "CRITICALLY long bot-script tick - ${pulse.botScript.javaClass.name} took $elapsedTime ms") + } else { + log(this::class.java, Log.WARN, "CRITICALLY long running pulse - ${pulse.javaClass.name} took $elapsedTime ms") + } + } else if (elapsedTime >= 30) { + if (pulse is GeneralBotCreator.BotScriptPulse) { + log(this::class.java, Log.WARN, "Long bot-script tick - ${pulse.botScript.javaClass.name} took $elapsedTime ms") + } else { + log(this::class.java, Log.WARN, "Long running pulse - ${pulse.javaClass.name} took $elapsedTime ms") + } + } + } +} diff --git a/Server/src/main/core/game/world/map/BuildRegionChunk.java b/Server/src/main/core/game/world/map/BuildRegionChunk.java new file mode 100644 index 0000000..0089373 --- /dev/null +++ b/Server/src/main/core/game/world/map/BuildRegionChunk.java @@ -0,0 +1,336 @@ +package core.game.world.map; + + +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItem; +import core.game.node.item.Item; +import core.game.node.scenery.Constructed; +import core.game.node.scenery.Scenery; +import core.game.node.scenery.SceneryBuilder; +import core.tools.Log; +import core.tools.SystemLogger; +import core.game.world.map.build.LandscapeParser; +import core.net.packet.IoBuffer; +import core.net.packet.out.ClearScenery; +import core.net.packet.out.ConstructGroundItem; +import core.net.packet.out.ConstructScenery; + +import static core.api.ContentAPIKt.log; + +import java.util.ArrayList; +import java.util.Arrays; + +/** + * A region chunk, used for easily modifying objects. + * @author Emperor + * + */ +public class BuildRegionChunk extends RegionChunk { + + /** + * The maximum amount of objects to be stored on one tile in the chunk. + */ + public static final int ARRAY_SIZE = 10; + + /** + * The list of changes made. + */ + private final Scenery[][][] objects; + + /** + * Constructs a new {@code BuildRegionChunk} {@code Object} + * @param base The base location. + * @param rotation The rotation. + * @param plane The region plane. + */ + public BuildRegionChunk(Location base, int rotation, RegionPlane plane) { + super(base, rotation, plane); + this.objects = new Scenery[ARRAY_SIZE][8][8]; + } + + public BuildRegionChunk(Location base, int rotation, RegionPlane plane, Scenery[][] objects) { + this(base, rotation, plane); + for (int x = 0; x < SIZE; x++) { + for (int y = 0; y < SIZE; y++) { + if(objects[x][y] != null) { + this.objects[0][x][y] = new Scenery(objects[x][y]); + } + } + } + } + + @Override + protected boolean appendUpdate(Player player, IoBuffer buffer) { + boolean updated = false;//super.appendUpdate(player, buffer); + for (int i = 0; i < objects.length; i++) { + for (int x = 0; x < SIZE; x++) { + for (int y = 0; y < SIZE; y++) { + Scenery o = objects[i][x][y]; + if (o instanceof Constructed) { + ConstructScenery.write(buffer, o); + updated = true; + } + else if (o != null && !o.isRenderable()) { + ClearScenery.write(buffer, o); + updated = true; + } + } + } + } + ArrayList totalItems = drawItems(items, player); + for (GroundItem item : totalItems) { + if (item != null && item.isActive() && item.getLocation() != null) { + if (!item.isPrivate() || item.droppedBy(player)) { + ConstructGroundItem.write(buffer, item); + updated = true; + } + } + } + return updated; + } + + @Override + public void rotate(Direction direction) { + if (rotation != 0) { + log(this.getClass(), Log.ERR, "Region chunk was already rotated!"); + return; + } + Scenery[][][] copy = new Scenery[ARRAY_SIZE][SIZE][SIZE]; + int baseX = currentBase.getLocalX(); + int baseY = currentBase.getLocalY(); + for (int x = 0; x < SIZE; x++) { + for (int y = 0; y < SIZE; y++) { + for (int i = 0; i < objects.length; i++) { + Scenery object = copy[i][x][y] = objects[i][x][y]; + if (object != null) { + SceneryBuilder.remove(object); + this.remove(object); + } + } + } + } + clear(); + switch(direction) { + case NORTH: rotation = 0; break; + case EAST: rotation = 1; break; + case SOUTH: rotation = 2; break; + case WEST: rotation = 3; break; + default: rotation = (direction.toInteger() + (direction.toInteger() % 2 == 0 ? 2 : 0)) % 4; + log(this.getClass(), Log.ERR, "Attempted to rotate a chunk in a non-cardinal direction - using fallback rotation code. This should be investigated!"); + break; + }; + for (int i = 0; i < objects.length; i++) { + for (int x = 0; x < SIZE; x++) { + for (int y = 0; y < SIZE; y++) { + Scenery object = copy[i][x][y]; + if (object != null) { + int[] pos = getRotatedPosition(x, y, object.getDefinition().getSizeX(), object.getDefinition().getSizeY(), object.getRotation(), rotation); + Scenery obj = object.transform(object.getId(), (object.getRotation() + rotation) % 4, object.getLocation().transform(pos[0] - x, pos[1] - y, 0)); + if (object instanceof Constructed) { + obj = obj.asConstructed(); + } + obj.setActive(object.isActive()); + obj.setRenderable(object.isRenderable()); + LandscapeParser.flagScenery(plane, baseX + pos[0], baseY + pos[1], obj, true, true); + } + } + } + } + } + + @Override + public BuildRegionChunk copy(RegionPlane plane) { + BuildRegionChunk chunk = new BuildRegionChunk(base, rotation, plane); + for (int i = 0; i < chunk.objects.length; i++) { + for (int x = 0; x < SIZE; x++) { + for (int y = 0; y < SIZE; y++) { + Scenery o = objects[i][x][y]; + if (o instanceof Constructed) { + chunk.objects[i][x][y] = o.transform(o.getId(), o.getRotation()).asConstructed(); + } + else if (o != null) { + chunk.objects[i][x][y] = o.transform(o.getId()); + chunk.objects[i][x][y].setActive(o.isActive()); + chunk.objects[i][x][y].setRenderable(o.isRenderable()); + } + } + } + } + return chunk; + } + + @Override public void rebuildFlags(RegionPlane from) { + for (int x = 0; x < 8; x++) { + for (int y = 0; y < 8; y++) { + Location loc = currentBase.transform(x,y,0); + Location fromLoc = base.transform(x,y,0); + plane.getFlags().getLandscape()[loc.getLocalX()][loc.getLocalY()] = from.getFlags().getLandscape()[fromLoc.getLocalX()][fromLoc.getLocalY()]; + plane.getFlags().clearFlag(x, y); + for (int i = 0; i < ARRAY_SIZE; i++) { + Scenery obj = objects[i][x][y]; + if (obj != null) + LandscapeParser.applyClippingFlagsFor(plane, loc.getLocalX(), loc.getLocalY(), obj); + } + } + } + } + + @Override + public void clear() { + super.clear(); + for (int i = 0; i < objects.length; i++) { + for (int x = 0; x < objects[i].length; x++) { + for (int y = 0; y < objects[i][x].length; y++) { + objects[i][x][y] = null; + } + } + } + } + + /** + * Removes the scenery. + * @param object The object to remove. + */ + public void remove(Scenery object) { + int chunkX = object.getLocation().getChunkOffsetX(); + int chunkY = object.getLocation().getChunkOffsetY(); + Scenery current = null; + int index = -1; + int i = 0; + while ((current == null || current.getId() != object.getId()) && i < objects.length) { + current = objects[i++][chunkX][chunkY]; + if ((current == null || current.getId() < 1) && index == -1) { + index = i - 1; + } + } + if (current != null && current.equals(object)) { + current.setActive(false); + object.setRenderable(false); + } + else { + objects[index][chunkX][chunkY] = object; + } + object.setActive(false); + object.setRenderable(false); + } + + /** + * Adds the scenery. + * @param object The object to add. + */ + public void add(Scenery object) { + int chunkX = object.getLocation().getChunkOffsetX(); + int chunkY = object.getLocation().getChunkOffsetY(); + Scenery current = null; + int index = -1; + int i = 0; + while ((current == null || current.getId() != object.getId()) && i < objects.length) { + current = objects[i++][chunkX][chunkY]; + if ((current == null || current.getId() < 1) && index == -1) { + index = i - 1; + } + } + if (current != null && current.equals(object)) { + current.setActive(true); + current.setRenderable(true); + } + else if (index == -1) { + throw new IllegalStateException("Insufficient array length for storing object!"); + } + else { + objects[index][chunkX][chunkY] = object = object.asConstructed(); + } + object.setActive(true); + object.setRenderable(true); + } + + /** + * Stores an object on the region chunk. + * @param object The object. + */ + public void store(Scenery object) { + if (object == null) { + return; + } + int chunkX = object.getLocation().getChunkOffsetX(); + int chunkY = object.getLocation().getChunkOffsetY(); + for (int i = 0; i < objects.length; i++) { + Scenery stat = objects[i][chunkX][chunkY]; + if (stat == null || stat.getId() < 1) { + objects[i][chunkX][chunkY] = object; + object.setActive(true); + object.setRenderable(true); + return; + } + } + System.err.print("Objects - ["); + for (int i = 0; i < objects.length; i++) { + System.err.print(objects[i][chunkX][chunkY]); + if (i < objects.length - 1) { + System.err.print(", "); + } + } + log(this.getClass(), Log.ERR, "]!"); + throw new IllegalStateException("Insufficient array length for storing all objects! "); + } + + /** + * Gets the objects index for the given object id. + * @param x The x-coordinate on the region chunk. + * @param y The y-coordinate on the region chunk. + * @param objectId The object id. + */ + public int getIndex(int x, int y, int objectId) { + for (int i = 0; i < objects.length; i++) { + Scenery o = get(x, y, i); + if (o != null && ((objectId > -1 && o.getId() == objectId) || (objectId == -1 && o.getDefinition().hasOptions(false)))) { + return i; + } + } + return 0; + } + + /** + * Gets a scenery. + * @param x The chunk x-coordinate. + * @param y The chunk y-coordinate. + * @param index The index (0 = default). + * @return The object. + */ + public Scenery get(int x, int y, int index) { + return objects[index][x][y]; + } + + @Override + public Scenery[] getObjects(int chunkX, int chunkY) { + Scenery[] objects = new Scenery[ARRAY_SIZE]; + for (int i = 0; i < ARRAY_SIZE; i++) { + objects[i] = this.objects[i][chunkX][chunkY]; + } + return objects; + } + + /** + * Gets the objects. + * @param index The index. + * @return The objects array. + */ + public Scenery[][] getObjects(int index) { + return objects[index]; + } + + @Override + public void setCurrentBase(Location currentBase) { + for (int i = 0; i < objects.length; i++) { + for (int x = 0; x < objects[i].length; x++) { + for (int y = 0; y < objects[i][x].length; y++) { + if (objects[i][x][y] != null) { + Location newLoc = currentBase.transform(x, y, 0); + objects[i][x][y].setLocation(newLoc); + } + } + } + } + super.setCurrentBase(currentBase); + } +} diff --git a/Server/src/main/core/game/world/map/Direction.java b/Server/src/main/core/game/world/map/Direction.java new file mode 100644 index 0000000..4555f93 --- /dev/null +++ b/Server/src/main/core/game/world/map/Direction.java @@ -0,0 +1,289 @@ +package core.game.world.map; + +import core.game.world.map.path.ClipMaskSupplier; + +/** + * Represents a direction. + * @author Emperor + */ +public enum Direction { + /** + * 0 1 2 + * \ | / + * 3 - . - 4 + * / | \ + * 5 6 7 + */ + + + /** + * The north-west direction. + */ + NORTH_WEST(-1, 1, 7, 0x12c0108, 0x12c0120, 0x12c0138), + + /** + * The north direction. + */ + NORTH(0, 1, 0, 0x12c0120), + + /** + * The north-east direction. + */ + NORTH_EAST(1, 1, 4, 0x12c0180, 0x12c0120, 0x12c01e0), + + /** + * The west direction. + */ + WEST(-1, 0, 3, 0x12c0108), + + /** + * The east direction. + */ + EAST(1, 0, 1, 0x12c0180), + + /** + * The south-west direction. + */ + SOUTH_WEST(-1, -1, 6, 0x12c0108, 0x12c0102, 0x12c010e), + + /** + * The south direction. + */ + SOUTH(0, -1, 2, 0x12c0102), + + /** + * The south-east direction. + */ + SOUTH_EAST(1, -1, 5, 0x12c0180, 0x12c0102, 0x12c0183); + + /** + * The amounts of steps on the x-axis. + */ + private final int stepX; + + /** + * The amounts of steps on the y-axis. + */ + private final int stepY; + + /** + * The integer value. + */ + private final int value; + + /** + * The traversal flags. + */ + private int[] traversal; + + /** + * Constructs a new {@code Direction} {@code Object}. + * @param stepX The x-offset to move a step. + * @param stepY The y-offset to move a step. + * @param value The direction value. + * @param traversal The traversal flags. + */ + Direction(int stepX, int stepY, int value, int... traversal) { + this.stepX = stepX; + this.stepY = stepY; + this.value = value; + this.setTraversal(traversal); + } + + /** + * Gets the direction. + * @param rotation The int value. + * @return The direction. + */ + public static Direction get(int rotation) { + for (Direction dir : Direction.values()) { + if (dir.value == rotation) { + return dir; + } + } + throw new IllegalArgumentException("Invalid direction value - " + rotation); + } + + /** + * Gets the walk point for a direction.
The point will be the offset to + * the location the node is facing. + * @param direction The direction. + * @return The point. + */ + public static Point getWalkPoint(Direction direction) { + return new Point(direction.stepX, direction.stepY); + } + + /** + * Gets the direction. + * @param location The start location. + * @param l The end location. + * @return The direction. + */ + public static Direction getDirection(Location location, Location l) { + return getDirection(l.getX() - location.getX(), l.getY() - location.getY()); + } + + /** + * Gets the direction for movement. + * @param diffX The difference between 2 x-coordinates. + * @param diffY The difference between 2 y-coordinates. + * @return The direction. + */ + public static Direction getDirection(int diffX, int diffY) { + if (diffX < 0) { + if (diffY < 0) { + return SOUTH_WEST; + } else if (diffY > 0) { + return NORTH_WEST; + } + return WEST; + } else if (diffX > 0) { + if (diffY < 0) { + return SOUTH_EAST; + } else if (diffY > 0) { + return NORTH_EAST; + } + return EAST; + } + if (diffY < 0) { + return SOUTH; + } + return NORTH; + } + + /** + * Gets the direction for the given walking flag. + * @param walkingFlag The walking flag. + * @param rotation The rotation. + * @return The direction, or null if the walk flag was 0. + */ + public static Direction forWalkFlag(int walkingFlag, int rotation) { + if (rotation != 0) { + walkingFlag = (walkingFlag << rotation & 0xf) + (walkingFlag >> 4 - rotation); + } + if (walkingFlag > 0) { + if ((walkingFlag & 0x8) == 0) { + return Direction.WEST; + } + if ((walkingFlag & 0x2) == 0) { + return Direction.EAST; + } + if ((walkingFlag & 0x4) == 0) { + return Direction.SOUTH; + } + if ((walkingFlag & 0x1) == 0) { + return Direction.NORTH; + } + } + return null; + } + + /** + * Gets the opposite dir. + * @return the direction. + */ + public Direction getOpposite() { + return Direction.get(toInteger() + 2 & 3); + } + + /** + * Gets the most logical direction. + * @param location The start location. + * @param l The end location. + * @return The most logical direction. + */ + public static Direction getLogicalDirection(Location location, Location l) { + int offsetX = Math.abs(l.getX() - location.getX()); + int offsetY = Math.abs(l.getY() - location.getY()); + if (offsetX > offsetY) { + if (l.getX() > location.getX()) { + return Direction.EAST; + } else { + return Direction.WEST; + } + } else if (l.getY() < location.getY()) { + return Direction.SOUTH; + } + return Direction.NORTH; + } + + /** + * Method used to go to clue the anme. + * @param direction the direction. + * @return the name. + */ + public String toName(Direction direction) { + return direction.name().toLowerCase(); + } + + /** + * Method used to get the direction to an integer. + * @return the integer. + */ + public int toInteger() { + return value; + } + + /** + * Gets the stepX. + * @return The stepX. + */ + public int getStepX() { + return stepX; + } + + /** + * Gets the stepY. + * @return The stepY. + */ + public int getStepY() { + return stepY; + } + + /** + * Checks if traversal is permitted for this direction. + * @param l The location. + * @return {@code True} if so. + */ + public boolean canMove(Location l) { + int flag = RegionManager.getClippingFlag(l.getZ(), l.getX(), l.getY()); + for (int f : traversal) { + if ((flag & f) != 0) { + return false; + } + } + return true; + } + + public boolean canMoveFrom(int z, int x, int y, ClipMaskSupplier clipMaskSupplier) { + int dx, dy; + boolean ret = true; + for (int f : traversal) { + switch(f) { + case 0x12c0120: dx = 0; dy = 1; break; // north + case 0x12c0180: dx = 1; dy = 0; break; // east + case 0x12c01e0: dx = 1; dy = 1; break; // northeast + case 0x12c0102: dx = 0; dy = -1; break; // south + case 0x12c0183: dx = 1; dy = -1; break; // southeast + case 0x12c0108: dx = -1; dy = 0; break; // west + case 0x12c010e: dx = -1; dy = -1; break; // southwest + case 0x12c0138: dx = -1; dy = 1; break; // northwest + default: return false; + } + int flag = clipMaskSupplier.getClippingFlag(z, x+dx, y+dy); + if ((flag & f) != 0) { + ret = false; + } + } + return ret; + } + + /** + * Sets the traversal. + * @param traversal The traversal to set. + */ + private void setTraversal(int[] traversal) { + this.traversal = traversal; + } +} diff --git a/Server/src/main/core/game/world/map/Location.java b/Server/src/main/core/game/world/map/Location.java new file mode 100644 index 0000000..ea7d179 --- /dev/null +++ b/Server/src/main/core/game/world/map/Location.java @@ -0,0 +1,563 @@ +package core.game.world.map; + +import core.game.interaction.DestinationFlag; +import core.game.node.Node; +import core.game.world.map.path.Path; +import core.game.world.map.path.Pathfinder; +import core.tools.RandomFunction; +import org.jetbrains.annotations.NotNull; +import core.api.utils.Vector; + +import java.util.ArrayList; +import java.util.List; +import java.lang.Math; + +/** + * Represents a location on the world map. + * @author Emperor + */ +public final class Location extends Node { + + /** + * The x-coordinate. + */ + private int x; + + /** + * The y-coordinate. + */ + private int y; + + /** + * The plane. + */ + private int z; + + /** + * Constructs a new {@code Location} {@code Object}. + * @param x The x-coordinate. + * @param y The y-coordinate. + * @param z The z-coordinate. + */ + public Location(int x, int y, int z) { + super(null, null); + super.destinationFlag = DestinationFlag.LOCATION; + this.x = x; + this.y = y; + if (z < 0) { + z += 4; + } + this.z = z; + } + + /** + * Constructs a new {@code Location} {@code Object} + * @param x The x-coordinate. + * @param y The y-coordinate. + */ + public Location(int x, int y) { + this(x, y, 0); + } + + /** + * Constructs a new {@code Location} {@code Object}. + * @param x The x-coordinate. + * @param y The y coordinate. + * @param z The z-coordinate. + * @param randomizer The amount we should randomize the x and y coordinates + * with (x + random(randomizer), y + random(randomizer)). + */ + public Location(int x, int y, int z, int randomizer) { + this(x + RandomFunction.getRandom(randomizer), y + RandomFunction.getRandom(randomizer), z); + } + + /** + * Construct a new Location. + * @param x The x-coordinate. + * @param y The y-coordinate. + * @param z The z-coordinate. + * @return The constructed location. + */ + public static Location create(int x, int y, int z) { + return new Location(x, y, z); + } + + public static Location create(int x, int y) { + return new Location(x, y, 0); + } + + /** + * Creates a new instance of the given location. + * @param location The given location. + * @return The new instance. + */ + public static Location create(Location location) { + return create(location.getX(), location.getY(), location.getZ()); + } + + /** + * Creates a location instance with coordinates being the difference between + * {@code other} & {@code location}. + * @param location The first location. + * @param other The other location. + * @return The delta location. + */ + public static Location getDelta(Location location, Location other) { + return Location.create(other.x - location.x, other.y - location.y, other.z - location.z); + } + + /** + * Gets a random location near the main location. + * @param main The main location. + * @param radius The radius. + * @param reachable If the locations should be able to reach eachother. + * @return The location. + */ + public static Location getRandomLocation(Location main, int radius, boolean reachable) { + Location location = RegionManager.getTeleportLocation(main, radius); + if (!reachable) { + return location; + } + Path path = Pathfinder.find(main, location, false, Pathfinder.DUMB); + if (!path.isSuccessful()) { + location = main; + if (!path.getPoints().isEmpty()) { + Point p = path.getPoints().getLast(); + location = Location.create(p.getX(), p.getY(), main.getZ()); + } + } + return location; + } + + @Override + public Location getLocation() { + return this; + } + + /** + * Checks if this location is right next to the node (assuming the node is + * size 1x1). + * @param node The node to check. + * @return {@code True} if this location is 1 tile north, west, south or + * east of the node location. + */ + public boolean isNextTo(Node node) { + Location l = node.getLocation(); + if (l.getY() == y) { + return l.getX() - x == -1 || l.getX() - x == 1; + } + if (l.getX() == x) { + return l.getY() - y == -1 || l.getY() - y == 1; + } + return false; + } + + /** + * Gets the region id. + * @return The region id. + */ + public int getRegionId() { + return (x >> 6) << 8 | (y >> 6); + } + + /** + * Compares the users region with the one given + * @return True if user is in given region + */ + public boolean isInRegion(int region) { + return getRegionId() == region; + } + + /** + * Gets the location incremented by the given coordinates. + * @param dir The direction to transform this location. + * @return The location. + */ + public Location transform(Direction dir) { + return transform(dir, 1); + } + + /** + * Gets the location incremented by the given coordinates. + * @param dir The direction to transform this location. + * @param steps The amount of steps to move in this direction. + * @return The location. + */ + public Location transform(Direction dir, int steps) { + return new Location(x + (dir.getStepX() * steps), y + (dir.getStepY() * steps), this.z); + } + + /** + * Gets the location incremented by the given coordinates. + * @param l incremental location + * @return The location. + */ + public Location transform(Location l) { + return new Location(x + l.getX(), y + l.getY(), this.z + l.getZ()); + } + + /** + * Gets the location incremented by the given coordinates. + * @param diffX The x-difference. + * @param diffY The y-difference. + * @param z The height difference. + * @return The location. + */ + public Location transform(int diffX, int diffY, int z) { + return new Location(x + diffX, y + diffY, this.z + z); + } + + /** + * Checks if the other location is within viewing distance. + * @param other The other location. + * @return If you're within the other distance. + */ + public boolean withinDistance(Location other) { + return withinDistance(other, MapDistance.RENDERING.getDistance()); + } + + /** + * Returns if a player is within a specified distance. + * @param other The other location. + * @param dist The amount of distance. + * @return If you're within the other distance. + */ + public boolean withinDistance(Location other, int dist) { + if (other.z != z) { + return false; + } + + int a = (other.x - x); + int b = (other.y - y); + double product = Math.sqrt((a*a) + (b*b)); + return product <= dist; + } + + /** + * Returns if a player is within a specified distance using max norm distance. + * @param other The other location. + * @param dist The amount of distance. + * @return If you're within the other distance. + */ + public boolean withinMaxnormDistance(Location other, int dist) { + if (other.z != z) { + return false; + } + + int a = Math.abs(other.x - x); + int b = Math.abs(other.y - y); + double max = Math.max(a, b); + return max <= dist; + } + + /** + * Returns the distance between you and the other. + * @param other The other location. + * @return The amount of distance between you and other. + */ + public double getDistance(Location other) { + int xdiff = this.getX() - other.getX(); + int ydiff = this.getY() - other.getY(); + return Math.sqrt(xdiff * xdiff + ydiff * ydiff); + } + + /** + * Returns the distance between the first and the second specified distance. + * @param first The first location. + * @param second The other location. + * @return The amount of distance between first and other. + */ + public static double getDistance(Location first, Location second) { + int xdiff = first.getX() - second.getX(); + int ydiff = first.getY() - second.getY(); + return Math.sqrt(xdiff * xdiff + ydiff * ydiff); + } + + /** + * Gets the 8 tiles surrounding this location as an ArrayList + */ + public ArrayList getSurroundingTiles() { + ArrayList locs = new ArrayList<>(); + + locs.add(transform(-1,-1,0));//SW + locs.add(transform(0,-1,0)); //S + locs.add(transform(1,-1,0)); //SE + locs.add(transform(1,0,0)); //E + locs.add(transform(1,1,0)); //NE + locs.add(transform(0,1,0)); //N + locs.add(transform(-1,1,0));//NW + locs.add(transform(-1,0,0));//W + + return locs; + } + + public ArrayList getCardinalTiles() { + ArrayList locs = new ArrayList<>(); + + locs.add(transform(-1, 0, 0)); + locs.add(transform(0, -1, 0)); + locs.add(transform(1, 0, 0)); + locs.add(transform(0, 1, 0)); + return locs; + } + + /** + * Gets a square of 3 x 3 tiles as an ArrayList + */ + public ArrayList get3x3Tiles() { + ArrayList locs = new ArrayList<>(); + locs.add(transform(0,0,0)); //Center + locs.add(transform(0,1,0)); //N + locs.add(transform(1,1,0)); //NE + locs.add(transform(1,0,0)); //E + locs.add(transform(1,-1,0)); //SE + locs.add(transform(0,-1,0)); //S + locs.add(transform(-1,-1,0));//SW + locs.add(transform(-1,0,0));//W + locs.add(transform(-1,1,0));//NW + return locs; + } + + /** + * Gets the x position on the region chunk. + * @return The x position on the region chunk. + */ + public int getChunkOffsetX() { + int x = getLocalX(); + //return x - ((x / RegionChunk.SIZE) * RegionChunk.SIZE); + return x & 7; + } + + /** + * Gets the y position on the region chunk. + * @return The y position on the region chunk. + */ + public int getChunkOffsetY() { + int y = getLocalY(); + //return y - ((y / RegionChunk.SIZE) * RegionChunk.SIZE); + return y & 7; + } + + /** + * Gets the base location for the chunk this location is in. + * @return The base location. + */ + public Location getChunkBase() { + return create(getRegionX() << 3, getRegionY() << 3, z); + } + + /** + * Gets the region x-coordinate. + * @return The region x-coordinate. + */ + public int getRegionX() { + return x >> 3; + } + + /** + * Gets the region y-coordinate. + * @return The region y-coordinate. + */ + public int getRegionY() { + return y >> 3; + } + + /** + * Gets the local x-coordinate on the current region in [0, 64). + * @return The local x-coordinate. + */ + public int getLocalX() { + return x & 63; + } + + /** + * Gets the local y-coordinate on the current region in [0, 64). + * @return The local y-coordinate. + */ + public int getLocalY() { + return y & 63; + } + + /** + * Gets the scene x-coordinate in [48, 55] (note that 104/2 = 52). + * @return The local x-coordinate. + */ + public int getSceneX() { + return x - ((getRegionX() - 6) << 3); + } + + /** + * Gets the local y-coordinate in [48, 55] (note that 104/2 = 52). + * @return The local y-coordinate. + */ + public int getSceneY() { + return y - ((getRegionY() - 6) << 3); + } + + /** + * Gets the local x-coordinate. + * @param loc The location containing the regional coordinates. + * @return The local x-coordinate. + */ + public int getSceneX(Location loc) { + return x - ((loc.getRegionX() - 6) << 3); + } + + /** + * Gets the local y-coordinate. + * @param loc The location containing the regional coordinates. + * @return The local y-coordinate. + */ + public int getSceneY(Location loc) { + return y - ((loc.getRegionY() - 6) << 3); + } + + /** + * Gets the chunk's x-coordinate (0-7). + * @return The x in the (8x8) region. + */ + public int getChunkX() { + return getLocalX() >> 3; + } + + /** + * Gets the chunk's y-coordinate (0-7). + * @return The y in the (8x8) region. + */ + public int getChunkY() { + return getLocalY() >> 3; + } + + @Override + public boolean equals(Object other) { + if (!(other instanceof Location)) { + return false; + } + Location loc = (Location) other; + return loc.x == x && loc.y == y && loc.z == z; + } + + /** + * Checks if these coordinates equal this location. + * @param x the x. + * @param y the y. + * @param z the x. + * @return {@code True} if so. + */ + public boolean equals(int x, int y, int z) { + return equals(new Location(x, y, z)); + } + + @Override + public String toString() { + return "[" + x + ", " + y + ", " + z + "]"; + } + + public static Location fromString(String locString) { + String trimmed = locString.replace("[", "").replace("]", ""); + String[] tokens = trimmed.split(","); + return Location.create( + Integer.parseInt(tokens[0].trim()), + Integer.parseInt(tokens[1].trim()), + Integer.parseInt(tokens[2].trim()) + ); + } + + @Override + public int hashCode() { + return z << 30 | x << 15 | y; + } + + /** + * Gets the x. + * @return The x. + */ + public int getX() { + return x; + } + + /** + * Sets the x. + * @param x The x to set. + */ + public void setX(int x) { + this.x = x; + } + + /** + * Gets the y. + * @return The y. + */ + public int getY() { + return y; + } + + /** + * Sets the y. + * @param y The y to set. + */ + public void setY(int y) { + this.y = y; + } + + /** + * Gets the z. + * @return The z. + */ + public int getZ() { + return z % 4; + } + + /** + * Sets the z. + * @param z The z to set. + */ + public void setZ(int z) { + this.z = z; + } + + @NotNull + public List getStepComponents(Direction dir) { + List output = new ArrayList<>(2); + int stepX = dir.getStepX(); + int stepY = dir.getStepY(); + + if (stepX != 0) output.add(transform(stepX, 0, 0)); + if (stepY != 0) output.add(transform(0, stepY, 0)); + return output; + } + + public Direction deriveDirection(Location location) { + int diffX = location.x - this.x; + int diffY = location.y - this.y; + + diffX = diffX >= 0 ? Math.min(diffX, 1) : -1; + diffY = diffY >= 0 ? Math.min(diffY, 1) : -1; + + StringBuilder sb = new StringBuilder(); + + if (diffY != 0) { + if (diffY > 0) { + sb.append("NORTH"); + } else { + sb.append("SOUTH"); + } + } + + if (diffX != 0) { + if (sb.length() > 0) sb.append("_"); + if (diffX > 0) { + sb.append("EAST"); + } else { + sb.append("WEST"); + } + } + + if (sb.length() == 0) return null; + return Direction.valueOf(sb.toString()); + } + + public Location transform (Vector vector) { + return Location.create(this.x + (int) Math.floor(vector.getX()), this.y + (int) Math.floor(vector.getY())); + } +} diff --git a/Server/src/main/core/game/world/map/MapDistance.java b/Server/src/main/core/game/world/map/MapDistance.java new file mode 100644 index 0000000..a809eac --- /dev/null +++ b/Server/src/main/core/game/world/map/MapDistance.java @@ -0,0 +1,39 @@ +package core.game.world.map; + +/** + * An enum holding commonly used distances (in tiles of the map). + * @author Emperor + */ +public enum MapDistance { + + /** + * The rendering distance. + */ + RENDERING(15), + + /** + * The sound packet sending distance. + */ + SOUND(5), ; + + /** + * The distance. + */ + private final int distance; + + /** + * Constructs a new {@code MapDistance} {@code Object}. + * @param distance The distance (in tiles). + */ + private MapDistance(int distance) { + this.distance = distance; + } + + /** + * Gets the distance. + * @return the distance. + */ + public int getDistance() { + return distance; + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/world/map/Point.java b/Server/src/main/core/game/world/map/Point.java new file mode 100644 index 0000000..4a3e01c --- /dev/null +++ b/Server/src/main/core/game/world/map/Point.java @@ -0,0 +1,143 @@ +package core.game.world.map; + +/** + * Represents a point. + * @author Emperor + */ +public final class Point { + + /** + * The x-coordinate. + */ + private final int x; + + /** + * The y-coordinate. + */ + private final int y; + + /** + * The difference x between previous and current point. + */ + private final int diffX; + + /** + * The difference y between previous and current point. + */ + private final int diffY; + + /** + * The direction for the next point. + */ + private final Direction direction; + + /** + * If we can't run during this point. + */ + private boolean runDisabled; + + /** + * Constructs a new {@code Point} {@code Object}. + * @param x The x-coordinate. + * @param y The y-coordinate. + */ + public Point(int x, int y) { + this(x, y, null, 0, 0); + } + + /** + * Constructs a new {@code Point} {@code Object}. + * @param x The x-coordinate. + * @param y The y-coordinate. + * @param direction The direction. + */ + public Point(int x, int y, Direction direction) { + this(x, y, direction, 0, 0); + } + + /** + * Constructs a new {@code Point} {@code Object}. + * @param x The x-coordinate. + * @param y The y-coordinate. + * @param direction The direction. + * @param diffX The difference x between previous and current point. + * @param diffY The difference y between previous and current point. + */ + public Point(int x, int y, Direction direction, int diffX, int diffY) { + this.x = x; + this.y = y; + this.direction = direction; + this.diffX = diffX; + this.diffY = diffY; + } + + /** + * Constructs a new {@code Point} {@code Object}. + * @param x The x-coordinate. + * @param y The y-coordinate. + * @param direction The direction. + * @param diffX The difference x between previous and current point. + * @param diffY The difference y between previous and current point. + * @param runDisabled If running is disabled for this walking point. + */ + public Point(int x, int y, Direction direction, int diffX, int diffY, boolean runDisabled) { + this(x, y, direction, diffX, diffY); + this.runDisabled = runDisabled; + } + + /** + * Gets the x. + * @return The x. + */ + public int getX() { + return x; + } + + /** + * Gets the y. + * @return The y. + */ + public int getY() { + return y; + } + + /** + * Gets the direction. + * @return The direction. + */ + public Direction getDirection() { + return direction; + } + + /** + * Gets the diffX. + * @return The diffX. + */ + public int getDiffX() { + return diffX; + } + + /** + * Gets the diffY. + * @return The diffY. + */ + public int getDiffY() { + return diffY; + } + + /** + * Gets the runDisabled. + * @return The runDisabled. + */ + public boolean isRunDisabled() { + return runDisabled; + } + + /** + * Sets the runDisabled. + * @param runDisabled The runDisabled to set. + */ + public void setRunDisabled(boolean runDisabled) { + this.runDisabled = runDisabled; + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/world/map/Region.java b/Server/src/main/core/game/world/map/Region.java new file mode 100644 index 0000000..ff87d8e --- /dev/null +++ b/Server/src/main/core/game/world/map/Region.java @@ -0,0 +1,606 @@ +package core.game.world.map; + +import core.cache.Cache; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.music.MusicZone; +import core.game.system.communication.CommunicationInfo; +import core.game.system.task.Pulse; +import core.game.world.map.build.DynamicRegion; +import core.game.world.map.build.LandscapeParser; +import core.game.world.map.build.MapscapeParser; +import core.game.world.map.zone.RegionZone; +import core.tools.Log; +import core.game.system.config.XteaParser; +import core.game.world.GameWorld; +import core.game.world.repository.Repository; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import static core.api.ContentAPIKt.log; + +/** + * Represents a region. + * + * @author Emperor + */ +public class Region { + + /** + * The default size of a region. + */ + public static final int SIZE = 64; + + /** + * The region x-coordinate. + */ + private final int x; + + /** + * The region y-coordinate. + */ + private final int y; + + /** + * The region planes. + */ + private final RegionPlane[] planes = new RegionPlane[4]; + + /** + * The activity pulse. + */ + private final Pulse activityPulse; + + /** + * The region zones lying in this region. + */ + private final List regionZones = new ArrayList<>(20); + + /** + * The region-wide music track ID for this region. + */ + private int music = -1; + + /** + * Any tile-specific music zones lying in this region. + */ + private final List musicZones = new ArrayList<>(20); + + /** + * Keeps track of players and time in region for tolerance purposes + */ + private final HashMap tolerances = new HashMap<>(); + + /** + * If the region is active. + */ + private boolean active; + + /** + * The amount of objects in this region. + */ + private int objectCount; + + /** + * If the region has flags. + */ + private boolean hasFlags; + + /** + * If the region has been loaded. + */ + private boolean loaded; + + /** + * The amount of players viewing this region. + */ + private int viewAmount; + + /** + * If the region can be edited. + */ + private boolean build; + + /** + * If all planes should be updated when in this region (instead of just current one). + */ + private boolean updateAllPlanes; + + /** + * Constructs a new {@code Region} {@code Object}. + * @param x The x-coordinate of the region. + * @param y The y-coordinate of the region. + */ + public Region(int x, int y) { + this.x = x; + this.y = y; + for (int plane = 0; plane < 4; plane++) { + planes[plane] = new RegionPlane(this, plane); + } + this.activityPulse = new Pulse(50) { + @Override + public boolean pulse() { + flagInactive(); + return true; + } + }; + activityPulse.stop(); + } + + /** + * Gets the base location. + * @return The base location. + */ + public Location getBaseLocation() { + return Location.create(x << 6, y << 6, 0); + } + + /** + * Adds a region zone to this region. + * @param zone The region zone. + */ + public void add(RegionZone zone) { + regionZones.add(zone); + for (RegionPlane plane : planes) { + for (NPC npc : plane.getNpcs()) { + npc.getZoneMonitor().updateLocation(npc.getLocation()); + } + for (Player p : plane.getPlayers()) { + p.getZoneMonitor().updateLocation(p.getLocation()); + } + } + } + + public void remove(RegionZone zone) { + regionZones.remove(zone); + for (RegionPlane plane : planes) { + for (NPC npc : plane.getNpcs()) { + npc.getZoneMonitor().updateLocation(npc.getLocation()); + } + for (Player p : plane.getPlayers()) { + p.getZoneMonitor().updateLocation(p.getLocation()); + } + } + } + + /** + * Adds a player to this region. + * @param player The player. + */ + public void add(Player player) { + planes[player.getLocation().getZ()].add(player); + tolerances.put(player.getUsername(), System.currentTimeMillis()); + flagActive(); + } + + /** + * Adds an npc to this region. + * @param npc The npc. + */ + public void add(NPC npc) { + planes[npc.getLocation().getZ()].add(npc); + } + + /** + * Removes an NPC from this region. + * @param npc The NPC. + */ + public void remove(NPC npc) { + RegionPlane plane = npc.getViewport().getCurrentPlane(); + if (plane != null && plane != planes[npc.getLocation().getZ()]) { + plane.remove(npc); + } + planes[npc.getLocation().getZ()].remove(npc); + } + + /** + * Removes a player from this region. + * @param player The player. + */ + public void remove(Player player) { + player.getViewport().getCurrentPlane().remove(player); + tolerances.remove(player.getUsername()); + checkInactive(); + } + + /** + * Checks if player is tolerated by enemies in this region + */ + public boolean isTolerated(Player player){ + return System.currentTimeMillis() - tolerances.getOrDefault(player.getUsername(), System.currentTimeMillis()) > TimeUnit.MINUTES.toMillis(10); + } + + /** + * Checks if the region is inactive, if so it will start the inactivity flagging. + * @return {@code True} if the region is inactive. + */ + public boolean checkInactive() { + return isInactive(true); + } + + /** + * Checks if the region is inactive. + * @param runPulse If the pulse for flagging the region as inactive should be ran. + * @return {@code True} if so. + */ + public boolean isInactive(boolean runPulse) { + if (isViewed()) { + return false; + } + for (RegionPlane p : planes) { + if (!p.getPlayers().isEmpty()) { + return false; + } + } + if (runPulse) { + if (!activityPulse.isRunning()) { + activityPulse.restart(); + activityPulse.start(); + GameWorld.getPulser().submit(activityPulse); + } + } + return true; + } + + /** + * Checks if this region has the inactivity flagging pulse running. + * @return {@code True} if so. + */ + public boolean isPendingRemoval() { + return activityPulse.isRunning(); + } + + /** + * Flags the region as active. + */ + public void flagActive() { + activityPulse.stop(); + if (!active) { + active = true; + load(this); + for (RegionPlane r : planes) { + for (NPC n : r.getNpcs()) { + if (n.isActive()) { + Repository.addRenderableNPC(n); + } + } + } + } + } + + public boolean flagInactive(boolean force) { + if (unload(this, force)) { + active = false; + return true; + } else { + return false; + } + } + + /** + * Flags the region as inactive. + */ + public boolean flagInactive() { + return flagInactive(false); + } + + /** + * Loads the flags for a region. + * @param r The region. + */ + public static void load(Region r) { + load(r, r.build); + } + + /** + * Loads the flags for a region. + * @param r The region. + * @param build if all objects in this region should be stored (rather than just the ones with options). + */ + public static void load(Region r, boolean build) { + try { + if (r.isLoaded() && r.isBuild() == build) { + return; + } + r.build = build; + boolean dynamic = r instanceof DynamicRegion; + int regionId = dynamic ? ((DynamicRegion) r).getRegionId() : r.getId(); + int regionX = regionId >> 8 & 0xFF; + int regionY = regionId & 0xFF; + int mapscapeId = Cache.getIndexes()[5].getArchiveId("m" + regionX + "_"+ regionY); + + if (mapscapeId < 0 && !dynamic) { + r.setLoaded(true); + return; + } + + byte[][][] mapscapeData = new byte[4][SIZE][SIZE]; + for (RegionPlane plane : r.planes) { + plane.getFlags().setLandscape(new boolean[SIZE][SIZE]); + //plane.getFlags().setClippingFlags(new int[SIZE][SIZE]); + //plane.getProjectileFlags().setClippingFlags(new int[SIZE][SIZE]); + } + if (mapscapeId > -1) { + ByteBuffer mapscape = ByteBuffer.wrap(Cache.getIndexes()[5].getCacheFile().getContainerUnpackedData(mapscapeId)); + MapscapeParser.parse(r, mapscapeData, mapscape); + } + r.hasFlags = dynamic; + r.setLoaded(true); + int landscapeId = Cache.getIndexes()[5].getArchiveId("l" + regionX + "_" + regionY); + if (landscapeId > -1) { + byte[] landscape = Cache.getIndexes()[5].getFileData(landscapeId, 0, XteaParser.Companion.getRegionXTEA(regionId)); + if (landscape == null || landscape.length < 4) { + return; + } + r.hasFlags = true; + try { + LandscapeParser.parse(r, mapscapeData, ByteBuffer.wrap(landscape), build); + } catch (Throwable t) { + new Throwable("Failed parsing region " + regionId + "!", t).printStackTrace(); + } + } + MapscapeParser.clipMapscape(r, mapscapeData); + } catch (Throwable e) { + e.printStackTrace(); + } + } + + public static boolean unload(Region r) { + return unload(r, false); + } + + /** + * Unloads a region. + * @param r The region. + */ + public static boolean unload(Region r, boolean force) { + if (!force && r.isViewed()) { + log(CommunicationInfo.class, Log.ERR, "Players viewing region!"); + r.flagActive(); + return false; + } + for (RegionPlane p : r.planes) { + if (!force && !p.getPlayers().isEmpty()) { + log(CommunicationInfo.class, Log.ERR, "Players still in region!"); + r.flagActive(); + return false; + } + } + for (RegionPlane p : r.planes) { + p.clear(); + if (!(r instanceof DynamicRegion)) { + for (NPC n : p.getNpcs()) { + n.onRegionInactivity(); + } + } + } + if (r.isBuild()) + r.setLoaded(false); + r.activityPulse.stop(); + return true; + } + + /** + * Checks if the region is being viewed by a player. + * @return {@code True} if so. + */ + public boolean isViewed() { + synchronized (this) { + return viewAmount > 0; + } + } + + /** + * Increments the view amount. + * @return The view amount after incrementing. + */ + public int incrementViewAmount() { + synchronized (this) { + return ++viewAmount; + } + } + + /** + * Decrements the amount of viewers. + * @return The view amount after decrementing. + */ + public int decrementViewAmount() { + synchronized (this) { + if (viewAmount < 1) { + //log(this.getClass(), Log.ERR, "View amount is " + (viewAmount - 1)); + viewAmount++; + } + return --viewAmount; + } + } + + /** + * Gets the active. + * @return The active. + */ + public boolean isActive() { + return active; + } + + /** + * Sets the active. + * @param active The active to set. + * @deprecated This should not be used, instead use the {@link #flagInactive()}, + * {@link #flagActive()} & {@link #checkInactive()} methods to safely change the activity state. + */ + @Deprecated + public void setActive(boolean active) { + this.active = active; + } + + /** + * Gets the region id. + * @return The region id. + */ + public int getId() { + return x << 8 | y; + } + + /** + * Gets the real region id (this returns the copied region id for dynamic regions). + * @return The region id. + */ + public int getRegionId() { + return getId(); + } + + /** + * Gets the x. + * @return The x. + */ + public int getX() { + return x; + } + + /** + * Gets the y. + * @return The y. + */ + public int getY() { + return y; + } + + /** + * Gets the planes. + * @return The planes. + */ + public RegionPlane[] getPlanes() { + return planes; + } + + /** + * Sets the region-wide music track. + */ + public void setMusic(int music) { + this.music = music; + } + + /** + * Gets the region-wide music track + * @return The music entry ID + */ + public int getMusic() { + return this.music; + } + + /** + * Gets the regionZones. + * @return The regionZones. + */ + public List getRegionZones() { + return regionZones; + } + + /** + * Gets the musicZones. + * @return The musicZones. + */ + public List getMusicZones() { + return musicZones; + } + + /** + * Gets the object count. + * @return The object count. + */ + public int getObjectCount() { + return objectCount; + } + + /** + * Sets the object count. + * @param objectCount The object count. + */ + public void setObjectCount(int objectCount) { + this.objectCount = objectCount; + } + + /** + * Gets the hasFlags. + * @return The hasFlags. + */ + public boolean isHasFlags() { + return hasFlags; + } + + /** + * Sets the hasFlags. + * @param hasFlags The hasFlags to set. + */ + public void setHasFlags(boolean hasFlags) { + this.hasFlags = hasFlags; + } + + /** + * Sets the region time out duration. + * @param ticks The amount of ticks before the region is flagged as inactive. + */ + public void setRegionTimeOut(int ticks) { + activityPulse.setDelay(ticks); + } + + /** + * Gets the loaded. + * @return The loaded. + */ + public boolean isLoaded() { + return loaded; + } + + /** + * Sets the loaded. + * @param loaded The loaded to set. + */ + public void setLoaded(boolean loaded) { + this.loaded = loaded; + } + + /** + * Sets the viewAmount. + * @param viewAmount The viewAmount to set. + */ + public void setViewAmount(int viewAmount) { + this.viewAmount = viewAmount; + } + + /** + * Gets the build. + * @return the build + */ + public boolean isBuild() { + return build; + } + + /** + * Sets the build. + * @param build the build to set. + */ + public void setBuild(boolean build) { + this.build = build; + } + + /** + * Gets the updateAllPlanes value. + * @return The updateAllPlanes. + */ + public boolean isUpdateAllPlanes() { + return updateAllPlanes; + } + + /** + * Sets the updateAllPlanes value. + * @param updateAllPlanes The updateAllPlanes to set. + */ + public void setUpdateAllPlanes(boolean updateAllPlanes) { + this.updateAllPlanes = updateAllPlanes; + } +} diff --git a/Server/src/main/core/game/world/map/RegionChunk.java b/Server/src/main/core/game/world/map/RegionChunk.java new file mode 100644 index 0000000..7b3fb71 --- /dev/null +++ b/Server/src/main/core/game/world/map/RegionChunk.java @@ -0,0 +1,441 @@ +package core.game.world.map; + +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItem; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.tools.Log; +import core.tools.SystemLogger; +import core.game.world.map.build.DynamicRegion; +import core.game.world.map.build.LandscapeParser; +import core.game.world.update.flag.UpdateFlag; +import core.net.packet.IoBuffer; +import core.net.packet.out.ClearScenery; +import core.net.packet.out.ConstructGroundItem; +import core.net.packet.out.ConstructScenery; +import core.net.packet.out.UpdateAreaPosition; + +import java.util.ArrayList; +import java.util.List; + +import static core.api.ContentAPIKt.log; + +/** + * Represents a region chunk. + * @author Emperor + * + */ +public class RegionChunk { + + /** + * The chunk size. + */ + public static final int SIZE = 8; + + /** + * The base location of the copied region chunk. + */ + protected Location base; + + /** + * The current base location. + */ + protected Location currentBase; + + /** + * The region plane. + */ + protected RegionPlane plane; + + /** + * The items in this chunk. + */ + protected List items; + + /** + * The scenerys in this chunk. + */ + protected Scenery[][] objects; + + /** + * The rotation. + */ + protected int rotation; + + /** + * The update flags. + */ + private List> flags = new ArrayList<>(20); + + /** + * Constructs a new {@code RegionChunk} {@code Object}. + * @param base The base location of the region chunk. + * @param rotation The rotation. + */ + public RegionChunk(Location base, int rotation, RegionPlane plane) { + this.base = base; + this.currentBase = base; + this.rotation = rotation; + this.plane = plane; + this.objects = new Scenery[SIZE][SIZE]; + } + + /** + * Copies the region chunk. + * @param plane The region plane. + * @return The region chunk. + */ + public BuildRegionChunk copy(RegionPlane plane) { + return new BuildRegionChunk(base, rotation, plane, this.objects); + } + + /** + * Registers an update flag. + * @param flag The flag. + */ + public void flag(UpdateFlag flag) { + flags.add(flag); + } + + /** + * Clears the region chunk. + */ + public void clear() { + flags.clear(); + if (items != null && plane.getRegion() instanceof DynamicRegion) { + items.clear(); + items = null; + } + } + + /** + * Updates the region chunk. + * @param player The player. + */ + public void synchronize(Player player) { + IoBuffer buffer = UpdateAreaPosition.getChunkUpdateBuffer(player, currentBase); + if (appendUpdate(player, buffer)) { + player.getSession().write(buffer); + } + } + + /** + * Writes the region chunk update data on the buffer. + * @param player The player we're updating for. + * @param buffer The buffer to write on. + * @return {@code True} if an update occured. + */ + protected boolean appendUpdate(Player player, IoBuffer buffer) { + boolean updated = false; + int baseX = currentBase.getLocalX(); + int baseY = currentBase.getLocalY(); + for (int x = 0; x < SIZE; x++) { + for (int y = 0; y < SIZE; y++) { + Scenery dyn = objects[x][y]; + if (dyn == null || plane.getObjects() == null) { + continue; + } + Scenery stat = plane.getObjects()[baseX + x][baseY + y]; + if (!dyn.isRenderable() && stat != null) { + ClearScenery.write(buffer, stat); + updated = true; + } + else if (dyn != stat) { + if (stat != null) { + ClearScenery.write(buffer, stat); + } + ConstructScenery.write(buffer, dyn); + updated = true; + } + } + } + ArrayList totalItems = drawItems(items, player); + for (GroundItem item : totalItems) { + if (item != null && item.isActive() && item.getLocation() != null) { + if (!item.isPrivate() || item.droppedBy(player)) { + ConstructGroundItem.write(buffer, item); + updated = true; + } + } + } + return updated; + } + + + public ArrayList drawItems(List items, Player player) { + ArrayList totalItems = items != null ? new ArrayList(items) : new ArrayList(); + + if (player.getAttribute("chunkdraw", false)) { + Location l = currentBase; + for (int x = 0; x < SIZE; x++) { + for (int y = 0; y < SIZE; y++) { + boolean add = false; + if (y == 0 || y == SIZE - 1) + add = true; + else if (x == 0 || x == SIZE - 1) + add = true; + if (add) + totalItems.add(new GroundItem(new Item(13444), l.transform(x, y, 0), player)); + } + } + } + + if (player.getAttribute("regiondraw", false)) { + Location l = currentBase; + int localX = l.getLocalX(); + int localY = l.getLocalY(); + + for (int x = 0; x < SIZE; x++) + for (int y = 0; y < SIZE; y++) { + boolean add = false; + if (localY == 0 || localY == 56) + if (localY == 0 && y == 0) + add = true; + else if (localY == 56 && y == SIZE - 1) + add = true; + if (localX == 0 || localX == 56) + if (localX == 0 && x == 0) + add = true; + else if (localX == 56 && x == SIZE - 1) + add = true; + + if (add) + totalItems.add(new GroundItem(new Item(13444), l.transform(x,y,0), player)); + } + } + + if (player.getAttribute("clippingdraw", false)) { + Location l = currentBase; + for (int x = 0; x < SIZE; x++) { + for (int y = 0; y < SIZE; y++) { + int flag = RegionManager.getClippingFlag(l.getZ(), l.getX() + x, l.getY() + y); + if (flag > 0) { + totalItems.add(new GroundItem(new Item(flag), l.transform(x, y, 0), player)); + } + } + } + } + + return totalItems; + } + + /** + * Sends all the update flags. + */ + public void update(Player player) { + if (isUpdated()) { + IoBuffer buffer = UpdateAreaPosition.getChunkUpdateBuffer(player, currentBase); + Object[] flagsArray = flags.toArray(); + int size = flagsArray.length; + for (int i = 0; i < size; i++) { + UpdateFlag flag = (UpdateFlag) flagsArray[i]; + flag.writeDynamic(buffer, player); + } + player.getSession().write(buffer); + } + } + + /** + * Rotates the chunk. + * @param direction The direction. + */ + public void rotate(Direction direction) { + if (rotation != 0) { + log(this.getClass(), Log.ERR, "Region chunk was already rotated!"); + return; + } + Scenery[][] copy = new Scenery[SIZE][SIZE]; + Scenery[][] staticCopy = new Scenery[SIZE][SIZE]; + int baseX = currentBase.getLocalX(); + int baseY = currentBase.getLocalY(); + for (int x = 0; x < SIZE; x++) { + for (int y = 0; y < SIZE; y++) { + copy[x][y] = objects[x][y]; + staticCopy[x][y] = plane.getObjects()[baseX + x][baseY + y]; + objects[x][y] = plane.getObjects()[baseX + x][baseY + y] = null; + plane.getFlags().clearFlag(baseX + x, baseY + y); + } + } + rotation = direction.toInteger(); + for (int x = 0; x < SIZE; x++) { + for (int y = 0; y < SIZE; y++) { + Scenery object = copy[x][y]; + Scenery stat = staticCopy[x][y]; + boolean match = object == stat; + if (stat == null) { + continue; + } + int[] pos = getRotatedPosition(x, y, stat.getDefinition().getSizeX(), stat.getDefinition().getSizeY(), stat.getRotation(), rotation); + if (object != null) { + object = object.transform(object.getId(), (object.getRotation() + rotation) % 4, object.getLocation().transform(pos[0] - x, pos[1] - y, 0)); + LandscapeParser.flagScenery(plane, baseX + pos[0], baseY + pos[1], object, true, true); + } + if (match) { + stat = object; + } else { + stat = stat.transform(stat.getId(), (stat.getRotation() + rotation) % 4, stat.getLocation().transform(pos[0] - x, pos[1] - y, 0)); + } + plane.getObjects()[baseX + pos[0]][baseY + pos[1]] = stat; + } + } + } + + /** + * Gets the new coordinates for an object/chunk tile when rotating. + * @param x The current x-coordinate. + * @param y The current y-coordinate. + * @param sizeX The x-size of the object. + * @param sizeY The y-size of the object. + * @param rotation The object rotation. + * @param chunkRotation The chunk rotation. + * @return The new x-coordinate. + */ + public static int[] getRotatedPosition(int x, int y, int sizeX, int sizeY, int rotation, int chunkRotation) { + if ((rotation & 0x1) == 1) { + int s = sizeX; + sizeX = sizeY; + sizeY = s; + } + if (chunkRotation == 0) { + return new int[] { x, y }; + } + if (chunkRotation == 1) { + return new int[] { y, 7 - x - (sizeX - 1) }; + } + if (chunkRotation == 2) { + return new int[] { 7 - x - (sizeX - 1), 7 - y - (sizeY - 1) }; + } + return new int[] { 7 - y - (sizeY - 1), x }; + } + + /** + * Gets the items. + * @return The items. + */ + public List getItems() { + if (items == null) { + items = new ArrayList(); + } + return items; + } + + /** + * Sets the items. + * @param items The items to set. + */ + public void setItems(List items) { + this.items = items; + } + + /** + * Gets the scenerys located on the coordinates in this chunk. + * @param chunkX The chunk x-coordinate (0-7). + * @param chunkY The chunk y-coordinate (0-7). + * @return The objects. + */ + public Scenery[] getObjects(int chunkX, int chunkY) { + return new Scenery[] { objects[chunkX][chunkY] }; + } + + /** + * Gets the objects. + * @return The objects. + */ + public Scenery[][] getObjects() { + return objects; + } + + /** + * Sets the objects. + * @param objects The objects to set. + */ + public void setObjects(Scenery[][] objects) { + this.objects = objects; + } + + /** + * Gets the base. + * @return The base. + */ + public Location getBase() { + return base; + } + + /** + * Sets the base location of the region to copy. + * @param base The base location. + */ + public void setBase(Location base) { + this.base = base; + } + + /** + * Gets the rotation. + * @return The rotation. + */ + public int getRotation() { + return rotation; + } + + /** + * Sets the rotation of the region chunk. + * @param rotation The rotation + */ + public void setRotation(int rotation) { + this.rotation = rotation; + } + + /** + * Gets the updated. + * @return The updated. + */ + public boolean isUpdated() { + return !flags.isEmpty(); + } + + /** + * Resets the flags. + */ + public void resetFlags() { + flags.clear(); + } + + /** + * Gets the region plane. + * @return The plane. + */ + public RegionPlane getPlane() { + return plane; + } + + /** + * Gets the currentBase. + * @return The currentBase. + */ + public Location getCurrentBase() { + return currentBase; + } + + /** + * Sets the currentBase. + * @param currentBase The currentBase to set. + */ + public void setCurrentBase(Location currentBase) { + this.currentBase = currentBase; + } + + public void rebuildFlags(RegionPlane from) { + for (int x = 0; x < 8; x++) { + for (int y = 0; y < 8; y++) { + Location loc = currentBase.transform(x,y,0); + Location fromLoc = base.transform(x,y,0); + plane.getFlags().getLandscape()[loc.getLocalX()][loc.getLocalY()] = from.getFlags().getLandscape()[fromLoc.getLocalX()][fromLoc.getLocalY()]; + plane.getFlags().clearFlag(x, y); + Scenery obj = objects[x][y]; + if (obj != null) + LandscapeParser.flagScenery(plane, loc.getLocalX(), loc.getLocalY(), obj, false, true); + } + } + } + +} diff --git a/Server/src/main/core/game/world/map/RegionManager.kt b/Server/src/main/core/game/world/map/RegionManager.kt new file mode 100644 index 0000000..46022fd --- /dev/null +++ b/Server/src/main/core/game/world/map/RegionManager.kt @@ -0,0 +1,917 @@ +package core.game.world.map + +import core.api.log +import core.game.node.Node +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.scenery.Scenery +import core.game.world.map.zone.ZoneBorders +import core.tools.Log +import core.tools.RandomFunction +import core.tools.SystemLogger +import java.util.* +import java.util.concurrent.TimeUnit +import java.util.concurrent.locks.ReentrantLock +import kotlin.collections.HashMap + +/** + * Manages the regions. + * @author Emperor + */ +object RegionManager { + /** + * The region cache mapping. + */ + private val REGION_CACHE: MutableMap = HashMap() + @JvmStatic val CLIPPING_FLAGS = HashMap>() + @JvmStatic val PROJECTILE_FLAGS = HashMap>() + + public val LOCK = ReentrantLock() + + /** + * Gets the region for the given region id. + * @param regionId The region id. + * @return The region. + */ + @JvmStatic + fun forId(regionId: Int): Region { + if(LOCK.tryLock() || LOCK.tryLock(10000, TimeUnit.MILLISECONDS)) { + var region = REGION_CACHE[regionId] + if (region == null) { + region = Region((regionId shr 8) and 0xFF, regionId and 0xFF) + REGION_CACHE[regionId] = region + } + LOCK.unlock() + return REGION_CACHE[regionId]!! + } + log(this::class.java, Log.ERR, "UNABLE TO OBTAIN LOCK WHEN GETTING REGION BY ID. RETURNING BLANK REGION.") + return Region(0,0) + } + + /** + * Pulses the active regions. + */ + @JvmStatic + fun pulse() { + if(LOCK.tryLock() || LOCK.tryLock(10000,TimeUnit.MILLISECONDS)) { + for (r in REGION_CACHE.values) { + if (r.isActive) { + for (p in r.planes) { + p.pulse() + } + } + } + LOCK.unlock() + } + } + + /** + * Gets the clipping flag on the given location. + * @param l The location. + * @return The clipping flag. + */ + @JvmStatic + fun getClippingFlag(l: Location): Int { + return getClippingFlag(l.z, l.x, l.y) + } + + /** + * Gets the clipping flag. + * @param z The plane. + * @param x The absolute x-coordinate. + * @param y The absolute y-coordinate. + * @return The clipping flags. + */ + @JvmStatic + fun getClippingFlag(z: Int, x: Int, y: Int): Int { + val regionX = x shr 6 + val regionY = y shr 6 + val localX = x and 63 + val localY = y and 63 + return getClippingFlag(z, regionX, regionY, localX, localY) + } + + /** + * Gets the clipping flags using Jagex-style coords + * e.g 0_50_50_13_13 gets plane 0, region 50-50 (12850), (13, 13) which is in lumbridge. + */ + @JvmStatic + fun getClippingFlag(z: Int, regionX: Int, regionY: Int, localX: Int, localY: Int, projectile: Boolean = false) : Int { + val (region, index) = getFlagIndex(z, regionX, regionY, localX, localY) + var flag = getFlags(region, projectile)[index] + + if (flag == -1) { + val r = forId((regionX shr 8) or regionY) + if (!r.isLoaded) + Region.load(r) + if (!r.isHasFlags) + return -1 + flag = getFlags(region, projectile)[index] + } + + return flag + } + + private fun getFlagIndex(z: Int, regionX: Int, regionY: Int, localX: Int, localY: Int) : Pair { + return Pair((regionX shl 8) or regionY, (z * 64 * 64) + (localX * 64) + localY) + } + + @JvmStatic + fun getFlags(regionX: Int, regionY: Int, projectile: Boolean) : Array { + val region = (regionX shl 8) or regionY + return getFlags(region, projectile) + } + + @JvmStatic + fun getFlags(regionId: Int, projectile: Boolean) : Array { + return if (projectile) + PROJECTILE_FLAGS.getOrPut (regionId) {Array(16384){0}} + else + CLIPPING_FLAGS.getOrPut (regionId) {Array(16384){-1}} + } + + @JvmStatic + fun resetFlags(regionId: Int) { + PROJECTILE_FLAGS.put (regionId, Array(16384){0}) + CLIPPING_FLAGS.put (regionId, Array(16384){-1}) + } + + /** + * Gets the water variant of a tile's clipping flag + * Essentially strips the landscape flag off a tile and keeps other flags, and makes normally walkable tiles unwalkable. + * @author Ceikry + */ + @JvmStatic + fun getWaterClipFlag(z: Int, x: Int, y: Int): Int { + val flag = getClippingFlag(z, x, y) + return if (!isClipped(z, x, y)) { + flag or 0x100 + } else flag and 0x200000.inv() + } + + /** + * Checks if the tile is part of the landscape. + * @param l The location. + * @return `True` if so. + */ + @JvmStatic + fun isLandscape(l: Location): Boolean { + return isLandscape(l.z, l.x, l.y) + } + + /** + * Checks if the tile is part of the landscape. + * @param z The plane. + * @param x The absolute x-coordinate. + * @param y The absolute y-coordinate. + * @return `True` if so. + */ + @JvmStatic + fun isLandscape(z: Int, x: Int, y: Int): Boolean { + var x = x + var y = y + val region = forId(((x shr 6) shl 8) or (y shr 6)) + Region.load(region) + if (!region.isHasFlags || region.planes[z].flags.landscape == null) { + return false + } + x -= x shr 6 shl 6 + y -= y shr 6 shl 6 + return region.planes[z].flags.landscape[x][y] + } + + /** + * Adds a clipping flag. + * @param z The plane. + * @param x The absolute x-coordinate. + * @param y The absolute y-coordinate. + * @param projectile If the flag is being set for projectile pathfinding. + * @param flag The clipping flag. + */ + @JvmStatic + fun addClippingFlag(z: Int, x: Int, y: Int, projectile: Boolean, flag: Int) { + var x = x + var y = y + val region = forId(((x shr 6) shl 8) or (y shr 6)) + Region.load(region) + if (!region.isHasFlags) { + return + } + x -= (x shr 6) shl 6 + y -= (y shr 6) shl 6 + if (projectile) { + region.planes[z].projectileFlags.flag(x, y, flag) + } else { + region.planes[z].flags.flag(x, y, flag) + } + } + + /** + * Adds a clipping flag. + * @param z The plane. + * @param x The absolute x-coordinate. + * @param y The absolute y-coordinate. + * @param projectile If the flag is being set for projectile pathfinding. + * @param flag The clipping flag. + */ + @JvmStatic + fun removeClippingFlag(z: Int, x: Int, y: Int, projectile: Boolean, flag: Int) { + var x = x + var y = y + val region = forId(((x shr 6) shl 8) or (y shr 6)) + Region.load(region) + if (!region.isHasFlags) { + return + } + x -= (x shr 6) shl 6 + y -= (y shr 6) shl 6 + if (projectile) { + region.planes[z].projectileFlags.unflag(x, y, flag) + } else { + region.planes[z].flags.unflag(x, y, flag) + } + } + + /** + * Gets the clipping flag. + * @param z The plane. + * @param x The absolute x-coordinate. + * @param y The absolute y-coordinate. + * @return The clipping flags. + */ + @JvmStatic + fun getProjectileFlag(z: Int, x: Int, y: Int): Int { + val regionX = x shr 6 + val regionY = y shr 6 + val localX = x and 63 + val localY = y and 63 + return getClippingFlag(z, regionX, regionY, localX, localY, true) + } + + /** + * Gets the clipping flag + * @param location the Location + * @return the clipping flag + */ + @JvmStatic + fun isTeleportPermitted(location: Location): Boolean { + return isTeleportPermitted(location.z, location.x, location.y) + } + + /** + * Gets the clipping flag. + * @param z The plane. + * @param x The absolute x-coordinate. + * @param y The absolute y-coordinate. + * @return The clipping flags. + */ + @JvmStatic + fun isTeleportPermitted(z: Int, x: Int, y: Int): Boolean { + if (!isLandscape(z, x, y)) { + return false + } + val flag = getClippingFlag(z, x, y) + return flag and 0x12c0102 == 0 || flag and 0x12c0108 == 0 || flag and 0x12c0120 == 0 || flag and 0x12c0180 == 0 + } + + /** + * Checks if the location has any clipping flags. + * @param location The location. + * @return `True` if a clipping flag disables access for this location. + */ + @JvmStatic + fun isClipped(location: Location): Boolean { + return isClipped(location.z, location.x, location.y) + } + + /** + * Checks if the location has any clipping flags. + * @param z The plane. + * @param x The x-coordinate. + * @param y The y-coordinate. + * @return `True` if a clipping flag disables access for this location. + */ + @JvmStatic + fun isClipped(z: Int, x: Int, y: Int): Boolean { + if (!isLandscape(z, x, y)) { + return true + } + val flag = getClippingFlag(z, x, y) + return flag and 0x12c0102 != 0 || flag and 0x12c0108 != 0 || flag and 0x12c0120 != 0 || flag and 0x12c0180 != 0 + } + + /** + * Gets the spawn location of a node. + * @param owner the owner. + * @param node the node. + * @return the location. + */ + @JvmStatic + fun getSpawnLocation(owner: Player?, node: Node?): Location? { + if (owner == null || node == null) { + return null + } + outer@ for (i in 0..7) { + val dir = Direction.get(i) + var stepX = dir.stepX + var stepY = dir.stepY + // For objects that are larger than 1, the below corrects for the fact that their origin is on the SW tile + if (dir.stepX < 0) { + stepX -= (node.size() - 1) + } + if (dir.stepY < 0) { + stepY -= (node.size() - 1) + } + if (owner.size() > 1) { //e.g. if you used ::pnpc to morph yourself into a large NPC + if (dir.stepX > 0) { + stepX += (owner.size() - 1) + } + if (dir.stepY > 0) { + stepY += (owner.size() - 1) + } + } + val l = owner.location.transform(stepX, stepY, 0) + // Check if ALL target tiles are unclipped + for (x in 0 until node.size()) { + for (y in 0 until node.size()) { + if (isClipped(l.transform(x, y, 0))) { + continue@outer + } + } + } + return l + } + return null + } + + /** + * Gets the scenery on the current location. + * @param l The location. + * @return The scenery, or `null` if no object was found. + */ + @JvmStatic + fun getObject(l: Location): Scenery? { + return getObject(l.z, l.x, l.y) + } + + /** + * Gets the scenery on the current absolute coordinates. + * @param z The height. + * @param x The x-coordinate. + * @param y The y-coordinate. + * @return The scenery, or `null` if no object was found. + */ + @JvmStatic + fun getObject(z: Int, x: Int, y: Int): Scenery? { + return getObject(z, x, y, -1) + } + + /** + * Gets the object on the given absolute coordinates. + * @param z The height. + * @param x The x-coordinate. + * @param y The y-coordinate. + * @param objectId The object id. + * @return The scenery, or `null` if no object was found. + */ + @JvmStatic + fun getObject(z: Int, x: Int, y: Int, objectId: Int): Scenery? { + var x = x + var y = y + val regionId = ((x shr 6) shl 8) or (y shr 6) + x -= (x shr 6) shl 6 + y -= (y shr 6) shl 6 + val region = forId(regionId) + Region.load(region) + val `object`: Scenery? = region.planes[z].getChunkObject(x, y, objectId) + return if (`object` != null && !`object`.isRenderable) { + null + } else `object` + } + + /** + * Gets the region plane for this location. + * @param l The location. + * @return The region plane. + */ + @JvmStatic + fun getRegionPlane(l: Location): RegionPlane { + val regionId = ((l.x shr 6) shl 8) or (l.y shr 6) + return forId(regionId).planes[l.z] + } + + /** + * Gets a region chunk. + * @param l The location. + * @return The region chunk. + */ + @JvmStatic + fun getRegionChunk(l: Location): RegionChunk { + val plane = getRegionPlane(l) + return plane.getRegionChunk(l.localX / RegionChunk.SIZE, l.localY / RegionChunk.SIZE) + } + + /** + * Moves the entity from the current region to the new one. + * @param entity The entity. + */ + @JvmStatic + fun move(entity: Entity) { + val player = entity is Player + val regionId = ((entity.location.regionX shr 3) shl 8) or (entity.location.regionY shr 3) + val viewport = entity.viewport + val current = forId(regionId) + val z = entity.location.z + val plane = current.planes[z] + viewport.updateViewport(entity) + if (plane == viewport.currentPlane) { + entity.zoneMonitor.updateLocation(entity.walkingQueue.footPrint) + return + } + viewport.remove(entity) + if (player) { + current.add(entity as Player) + } else { + current.add(entity as NPC) + } + viewport.region = current + viewport.currentPlane = plane + val view: MutableList = LinkedList() + for (regionX in ((entity.location.regionX shr 3) - 1)..((entity.location.regionX shr 3) + 1)) { + for (regionY in ((entity.location.regionY shr 3) - 1)..((entity.location.regionY shr 3) + 1)) { + if (regionX < 0 || regionY < 0) { + continue + } + val region = forId((regionX shl 8) or regionY) + val p = region.planes[z] + if (player) { + region.incrementViewAmount() + region.flagActive() + } + view.add(p) + } + } + viewport.viewingPlanes = view + entity.zoneMonitor.updateLocation(entity.walkingQueue.footPrint) + } + + /** + * Gets the list of local NPCs with a maximum distance of 16. + * @param n The entity. + * @return The list of local NPCs. + */ + @JvmStatic + fun getLocalNpcs(n: Entity): List { + return getLocalNpcs(n, MapDistance.RENDERING.distance) + } + + /** + * Gets the location entitys. + * @param location the location. + * @param distance the distance. + * @return the list. + */ + @JvmStatic + fun getLocalEntitys(location: Location, distance: Int): List { + val entitys: MutableList = ArrayList(20) + entitys.addAll(getLocalNpcs(location, distance)) + entitys.addAll(getLocalPlayers(location, distance)) + return entitys + } + + /** + * Gets the location entitys. + * @param entity the entity. + * @param distance the distance. + * @return the list. + */ + @JvmStatic + fun getLocalEntitys(entity: Entity, distance: Int): List { + return getLocalEntitys(entity.location, distance) + } + + /** + * Gets the local entitys. + * @param entity the entity. + * @return the entitys. + */ + @JvmStatic + fun getLocalEntitys(entity: Entity): List { + return getLocalEntitys(entity.location, MapDistance.RENDERING.distance) + } + + /** + * Gets the list of local NPCs. + * @param n The entity. + * @param distance The distance to the entity. + * @return The list of local NPCs. + */ + @JvmStatic + fun getLocalNpcs(n: Entity, distance: Int): List { + val npcs: MutableList = LinkedList() + for (r in n.viewport.viewingPlanes) { + for (npc in r.npcs) { + if (npc.location.withinDistance(n.location, distance)) { + npcs.add(npc) + } + } + } + return npcs + } + + /** + * Gets the list of local players with a maximum distance of 15. + * @param n The entity. + * @return The list of local players. + */ + @JvmStatic + fun getLocalPlayers(n: Entity): List { + return getLocalPlayers(n, MapDistance.RENDERING.distance) + } + + /** + * Gets the list of local players. + * @param n The entity. + * @param distance The distance to the entity. + * @return The list of local players. + */ + @JvmStatic + fun getLocalPlayers(n: Entity, distance: Int): List { + val players: MutableList = LinkedList() + for (r in n.viewport.viewingPlanes) { + for (p in r.players) { + if (p.location.withinDistance(n.location, distance)) { + players.add(p) + } + } + } + return players + } + + /** + * Gets the surrounding players. + * @param n The node the players should be surrounding. + * @param ignore The nodes not to add to the list. + * @return The list of players. + */ + @JvmStatic + fun getSurroundingPlayers(n: Node, vararg ignore: Node): List { + return getSurroundingPlayers(n, 9, *ignore) + } + + /** + * Gets the surrounding players. + * @param n The node the players should be surrounding. + * @param ignore The nodes not to add to the list. + * @return The list of players. + */ + @JvmStatic + fun getSurroundingPlayers(n: Node, maximum: Int, vararg ignore: Node): List { + val players = getLocalPlayers(n.location, 2) + var count = 0 + val it = players.iterator() + while (it.hasNext()) { + val p = it.next() + if(p.isInvisible()) { + it.remove() + } + if(!p.location.withinMaxnormDistance(n.location, 1)) { + it.remove() + continue + } + if (++count >= maximum) { + it.remove() + continue + } + for (node in ignore) { + if (p === node) { + count-- + it.remove() + break + } + } + } + return players + } + + /** + * Gets the surrounding players. + * @param n The node the players should be surrounding. + * @param ignore The nodes not to add to the list. + * @return The list of players. + */ + @JvmStatic + fun getSurroundingNPCs(n: Node, vararg ignore: Node): List { + return getSurroundingNPCs(n, 9, *ignore) + } + + /** + * Gets the surrounding players. + * @param n The node the npcs should be surrounding. + * @param ignore The nodes not to add to the list. + * @return The list of npcs. + */ + @JvmStatic + fun getSurroundingNPCs(n: Node, maximum: Int, vararg ignore: Node): List { + val npcs = getLocalNpcs(n.location, 2) + var count = 0 + val it = npcs.iterator() + while (it.hasNext()) { + val p = it.next() + if(p.properties.teleportLocation != null && !p.properties.teleportLocation.withinMaxnormDistance(n.location, 1)) { + it.remove() + continue + } + if(p.getAttribute("state:death", false)) { + it.remove() + continue + } + if(p.isInvisible()) { + it.remove() + continue + } + if(!p.location.withinMaxnormDistance(n.location, 1)) { + it.remove() + continue + } + if (++count > maximum) { + it.remove() + continue + } + for (node in ignore) { + if (p === node) { + count-- + it.remove() + break + } + } + } + return npcs + } + + /** + * Gets a random teleport location in the radius around the given location. + * @param location The centre location. + * @param radius The radius. + * @return A random teleport location. + */ + @JvmStatic + fun getTeleportLocation(location: Location, radius: Int): Location { + var radius = radius + var mod = radius shr 1 + if (mod == 0) { + mod++ + radius-- + } + return getTeleportLocation(location.transform(-mod, -mod, 0), mod + radius, mod + radius) + } + + /** + * Gets a random teleport location in the radius around the given location. + * @param location The centre location. + * @return A random teleport location. + */ + @JvmStatic + fun getTeleportLocation(location: Location, areaX: Int, areaY: Int): Location { + var destination = location + var x: Int = RandomFunction.random(1 + areaX) + var y: Int = RandomFunction.random(1 + areaY) + var count = 0 + while (!isTeleportPermitted(location.transform(x, y, 0).also { destination = it })) { + x = RandomFunction.random(1 + areaX) + y = RandomFunction.random(1 + areaY) + if (count++ >= areaX * 2) { + //This would be able to keep looping for several seconds otherwise (this actually happens). + x = 0 + while (x < areaX + 1) { + y = 0 + while (y < areaY + 1) { + if (isTeleportPermitted(location.transform(x, y, 0).also { destination = it })) { + return destination + } + y++ + } + x++ + } + break + } + } + return destination + } + + /** + * Gets the current viewport for the location. + * @param l The location. + * @return The viewport. + */ + @JvmStatic + fun getViewportPlayers(l: Location): List { + var l = l + val players: MutableList = LinkedList() + l = l.chunkBase.transform(-8, -8, 0) + val b = ZoneBorders(l.x, l.y, l.x + 24, l.y + 24) + for (regionX in ((l.regionX - 6) shr 3)..((l.regionX + 6) shr 3)) { + for (regionY in ((l.regionY - 6) shr 3)..((l.regionY + 6) shr 3)) { + for (player in forId(regionX shl 8 or regionY).planes[l.z].players) { + l = player.location + if (b.insideBorder(l.x, l.y)) { + players.add(player) + } + } + } + } + return players + } + + /** + * Gets a list of players in the given region. + * @param regionId The region id. + * @return The list of players in this region. + */ + @JvmStatic + fun getRegionPlayers(regionId: Int): List { + val r = forId(regionId) + val players: MutableList = ArrayList(20) + for (plane in r.planes) { + players.addAll(plane.players) + } + return players + } + + /** + * Gets a list of local players within rendering distance of the location. + * @param l The location. + * @return The list of players. + */ + @JvmStatic + fun getLocalPlayers(l: Location): List { + return getLocalPlayers(l, MapDistance.RENDERING.distance) + } + + /** + * Gets a list of local players. + * @param l The location. + * @param distance The distance to that location. + * @return The list of players. + */ + @JvmStatic + fun getLocalPlayers(l: Location, distance: Int): MutableList { + val players: MutableList = LinkedList() + for (regionX in ((l.regionX - 6) shr 3)..((l.regionX + 6) shr 3)) { + for (regionY in ((l.regionY - 6) shr 3)..((l.regionY + 6) shr 3)) { + for (player in forId((regionX shl 8) or regionY).planes[l.z].players) { + if (player.location.withinDistance(l, distance)) { + players.add(player) + } + } + } + } + return players + } + + /** + * Gets a list of local players within a symmetric bounding box. + * @param l The location. + * @param xdist The distance from the location on the x plane that is considered within bounds. + * @param ydist The distance from the location on the y plane that is considered within bounds. + * @return The list of players. + */ + @JvmStatic + fun getLocalPlayersBoundingBox(l: Location, xdist: Int, ydist: Int): MutableList { + val players: MutableList = LinkedList() + for (regionX in ((l.regionX - 6) shr 3)..((l.regionX + 6) shr 3)) { + for (regionY in ((l.regionY - 6) shr 3)..((l.regionY + 6) shr 3)) { + for (player in forId((regionX shl 8) or regionY).planes[l.z].players) { + if (player.location.x >= l.getX() - xdist && + player.location.x <= l.getX() + xdist && + player.location.y >= l.getY() - ydist && + player.location.y <= l.getY() + ydist) { + players.add(player) + } + } + } + } + return players + } + + /** + * Gets a list of local players. + * @param l The location. + * @param distance The distance to that location. + * @return The list of players. + */ + @JvmStatic + fun getLocalPlayersMaxNorm(l: Location, distance: Int): MutableList { + val players: MutableList = LinkedList() + for (regionX in ((l.regionX - 6) shr 3)..((l.regionX + 6) shr 3)) { + for (regionY in ((l.regionY - 6) shr 3)..((l.regionY + 6) shr 3)) { + for (player in forId((regionX shl 8) or regionY).planes[l.z].players) { + if (player.location.withinMaxnormDistance(l, distance)) { + players.add(player) + } + } + } + } + return players + } + + /** + * Gets a list of local players within 16 tile distance of the location. + * @param l The location. + * @return The list of players. + */ + @JvmStatic + fun getLocalNpcs(l: Location): List { + return getLocalNpcs(l, MapDistance.RENDERING.distance) + } + + /** + * Gets the npc. + * @param entity the entity. + * @param id the id. + */ + @JvmStatic + fun getNpc(entity: Entity, id: Int): NPC? { + return getNpc(entity, id, 16) + } + + /** + * Gets the npc. + * @param entity the entity. + * @param id the id. + * @param distance the distance. + * @return the npc. + */ + @JvmStatic + fun getNpc(entity: Entity, id: Int, distance: Int): NPC? { + return getNpc(entity.location, id, distance) + } + + /** + * Gets an npc near the entity. + * @param id the id, + * @param distance the dinstance. + * @return the npc. + */ + @JvmStatic + fun getNpc(location: Location, id: Int, distance: Int): NPC? { + val npcs: List = getLocalNpcs(location, distance) + for (n in npcs) { + if (n.id == id) { + return n + } + } + return null + } + + /** + * Gets a list of local players. + * @param l The location. + * @param distance The distance to that location. + * @return The list of players. + */ + @JvmStatic + fun getLocalNpcs(l: Location, distance: Int): MutableList { + val npcs: MutableList = LinkedList() + for (regionX in ((l.regionX - 6) shr 3)..((l.regionX + 6) shr 3)) { + for (regionY in ((l.regionY - 6) shr 3)..((l.regionY + 6) shr 3)) { + for (n in forId(regionX shl 8 or regionY).planes[l.z].npcs) { + if (n.location.withinDistance(l, (n.size() shr 1) + distance)) { + npcs.add(n) + } + } + } + } + return npcs + } + + @JvmStatic + fun addRegion(id: Int, region: Region){ + if(lock.tryLock() || LOCK.tryLock(10000, TimeUnit.MILLISECONDS)) { + REGION_CACHE[id] = region + LOCK.unlock() + } + } + + @JvmStatic + fun removeRegion(id: Int) { + if (lock.tryLock() || LOCK.tryLock(10000, TimeUnit.MILLISECONDS)) { + val r = REGION_CACHE.remove(id) + r?.flagInactive(true) + LOCK.unlock() + } + } + + /** + * Gets the regionCache. + * @return The regionCache. + */ + val regionCache: Map + @JvmStatic get(){ + return REGION_CACHE + } + + val lock: ReentrantLock + @JvmStatic get() = LOCK +} diff --git a/Server/src/main/core/game/world/map/RegionPlane.java b/Server/src/main/core/game/world/map/RegionPlane.java new file mode 100644 index 0000000..6557bf6 --- /dev/null +++ b/Server/src/main/core/game/world/map/RegionPlane.java @@ -0,0 +1,436 @@ +package core.game.world.map; + +import core.game.node.Node; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItem; +import core.game.node.item.Item; +import core.game.node.scenery.Scenery; +import core.game.world.map.build.DynamicRegion; +import core.game.world.map.build.RegionFlags; +import core.game.world.update.flag.chunk.ItemUpdateFlag; +import core.net.packet.PacketRepository; +import core.net.packet.context.BuildItemContext; +import core.net.packet.out.ClearGroundItem; +import core.net.packet.out.ConstructGroundItem; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.CopyOnWriteArrayList; + +/** + * Represents one of the 4 planes of a region. + * @author Emperor + * + */ +public final class RegionPlane { + + /** + * The region size. + */ + public static final int REGION_SIZE = 64; + + /** + * The amount of chunks in this plane. + */ + public static final int CHUNK_SIZE = REGION_SIZE >> 3; + + /** + * Represents a removed scenery. + */ + public static final Scenery NULL_OBJECT = new Scenery(0, Location.create(0, 0, 0)); + + /** + * The plane. + */ + private final int plane; + + /** + * The region. + */ + private final Region region; + + /** + * The region flags. + */ + private final RegionFlags flags; + + /** + * The region projectile flags. + */ + private final RegionFlags projectileFlags; + + /** + * The region chunks. + */ + private final RegionChunk[][] chunks; + + /** + * The list of NPCs in this region. + */ + private final List npcs; + + /** + * The list of players in this region. + */ + private final List players; + + /** + * The scenerys. + */ + private Scenery[][] objects; + + /** + * Constructs a new {@code RegionPlane} {@code Object}. + * @param region The region. + * @param plane The plane. + */ + public RegionPlane(Region region, int plane) { + this.plane = plane; + this.region = region; + this.players = new CopyOnWriteArrayList(); + this.npcs = new CopyOnWriteArrayList(); + Location base = region.getBaseLocation(); + this.flags = new RegionFlags(plane, base.getX(), base.getY()); + this.projectileFlags = new RegionFlags(plane, base.getX(), base.getY(), true); + this.objects = new Scenery[REGION_SIZE][REGION_SIZE]; + this.chunks = new RegionChunk[CHUNK_SIZE][CHUNK_SIZE]; + } + + /** + * Called at the end of the update sequence, if the region is active. + */ + public void pulse() { + Arrays.stream(chunks).forEach(regionChunks -> {Arrays.stream(regionChunks).filter(Objects::nonNull).forEach(RegionChunk::resetFlags);}); + } + + /** + * Adds a scenery. + * @param object The object to add. + * @param x The x-coordinate. + * @param y The y-coordinate. + * @param landscape If this object is added through landscape parsing. + */ + public void add(Scenery object, int x, int y, boolean landscape) { + setChunkObject(x, y, object); + if (landscape) { + objects[x][y] = object; + } + if (object != null) { + object.setRenderable(true); + } + } + + /** + * Gets the region chunk. + * @param chunkX The chunk base x-coordinate. + * @param chunkY The chunk base y-coordinate. + * @return The region chunk. + */ + public RegionChunk getRegionChunk(int chunkX, int chunkY) { + RegionChunk r = chunks[chunkX][chunkY]; + if (r != null) { + return r; + } + if (region.isBuild()) { + return chunks[chunkX][chunkY] = new BuildRegionChunk(region.getBaseLocation().transform(chunkX << 3, chunkY << 3, plane), 0, this); + } + return chunks[chunkX][chunkY] = new RegionChunk(region.getBaseLocation().transform(chunkX << 3, chunkY << 3, plane), 0, this); + } + + public void setRegionChunk(int chunkX, int chunkY, RegionChunk chunk) { + chunks[chunkX][chunkY] = chunk; + } + + /** + * Removes a scenery. + * @param x The x-coordinate. + * @param y The y-coordinate. + */ + public void remove(int x, int y) { + remove(x, y, -1); + } + + /** + * Removes a scenery. + * @param x The x-coordinate. + * @param y The y-coordinate. + * @param objectId The object id. + */ + public void remove(int x, int y, int objectId) { + int chunkX = x / CHUNK_SIZE; + int chunkY = y / CHUNK_SIZE; + int offsetX = x - chunkX * CHUNK_SIZE; + int offsetY = y - chunkY * CHUNK_SIZE; + RegionChunk chunk = getRegionChunk(chunkX, chunkY); + Scenery remove = new Scenery(0, region.getBaseLocation().transform(x, y, plane), 22, 0); + remove.setRenderable(false); + if (chunk instanceof BuildRegionChunk) { + int index = ((BuildRegionChunk) chunk).getIndex(offsetX, offsetY, objectId); + ((BuildRegionChunk) chunk).getObjects(index)[offsetX][offsetY] = remove; + return; + } + chunk.getObjects()[offsetX][offsetY] = remove; + } + + /** + * Sets an object on a chunk. + * @param x The regional x-coordinate. + * @param y The regional y-coordinate. + * @param object The object to set. + */ + private void setChunkObject(int x, int y, Scenery object) { + int chunkX = x / CHUNK_SIZE; + int chunkY = y / CHUNK_SIZE; + int offsetX = x - chunkX * CHUNK_SIZE; + int offsetY = y - chunkY * CHUNK_SIZE; + RegionChunk r = getRegionChunk(chunkX, chunkY); + if (r instanceof BuildRegionChunk) { + ((BuildRegionChunk) r).store(object); + return; + } + r.getObjects()[offsetX][offsetY] = object; + } + + /** + * Gets the scenerys. + * @return The scenerys. + */ + public Scenery[][] getObjects() { + return objects; + } + + public List getObjectList() { + ArrayList list = new ArrayList(); + for (int x = 0; x < REGION_SIZE; x++) { + for (int y = 0; y < REGION_SIZE; y++) { + if (objects[x][y] != null) + list.add(objects[x][y]); + } + } + return list; + } + + /** + * Clears this region plane. + */ + public void clear() { + for (RegionChunk[] c : chunks) { + for (RegionChunk chunk : c) { + if (chunk != null) { + chunk.clear(); + } + } + } + if (region instanceof DynamicRegion && objects != null) { + for (int x = 0; x < REGION_SIZE; x++) { + for (int y = 0; y < REGION_SIZE; y++) { + objects[x][y] = null; + } + } + objects = null; + } + } + + /** + * Adds an NPC to this region. + * @param npc The NPC to add. + */ + public void add(NPC npc) { + npcs.add(npc); + } + + /** + * Adds a player to this region. + * @param player The player. + */ + public void add(Player player) { + players.add(player); + } + + /** + * Adds an item to this region. + * @param item The item. + */ + public void add(GroundItem item) { + Location l = item.getLocation(); + RegionChunk c = getRegionChunk(l.getLocalX() / RegionChunk.SIZE, l.getLocalY() / RegionChunk.SIZE); + if (!c.getItems().add(item)) { + return; + } + GroundItem g = (GroundItem) item; + if (g.isPrivate()) { + if (g.getDropper() != null) { + PacketRepository.send(ConstructGroundItem.class, new BuildItemContext(g.getDropper(), item)); + } + return; + } + c.flag(new ItemUpdateFlag(g, ItemUpdateFlag.CONSTRUCT_TYPE)); + } + + /** + * Removes an NPC from this region. + * @param npc The NPC. + */ + public void remove(NPC npc) { + npcs.remove(npc); + } + + /** + * Removes a player from this region. + * @param player The player. + */ + public void remove(Player player) { + players.remove(player); + } + + /** + * Removes an item from this region. + * @param item The ground item. + */ + public void remove(GroundItem item) { + Location l = item.getLocation(); + RegionChunk c = getRegionChunk(l.getLocalX() / RegionChunk.SIZE, l.getLocalY() / RegionChunk.SIZE); + if (!c.getItems().remove(item)) { + return; + } + if (item.isPrivate()) { + if (item.getDropper() != null && item.getDropper().isPlaying() && item.getDropper().getLocation().withinDistance(l)) { + PacketRepository.send(ClearGroundItem.class, new BuildItemContext(item.getDropper(), item)); + } + return; + } + c.flag(new ItemUpdateFlag(item, ItemUpdateFlag.REMOVE_TYPE)); + } + + /** + * Gets the region flags. + * @return The flags. + */ + public RegionFlags getFlags() { + return flags; + } + + /** + * Gets the projectileFlags. + * @return The projectileFlags. + */ + public RegionFlags getProjectileFlags() { + return projectileFlags; + } + + /** + * Gets the npcs. + * @return The npcs. + */ + public List getNpcs() { + return npcs; + } + + public List getEntities() + { + List entities = new ArrayList<>(npcs); + Arrays.stream(getObjects()).forEach(o -> entities.addAll(Arrays.asList(o))); + return entities; + } + + /** + * Gets the players. + * @return The players. + */ + public List getPlayers() { + return players; + } + + /** + * Gets the plane. + * @return The plane. + */ + public int getPlane() { + return plane; + } + + /** + * Gets the region. + * @return The region. + */ + public Region getRegion() { + return region; + } + + /** + * Gets an object from a region chunk. + * @param x The region x-coordinate. + * @param y The region y-coordinate. + * @return The scenery. + */ + public Scenery getChunkObject(int x, int y) { + return getChunkObject(x, y, -1); + } + + /** + * Gets an object from a region chunk. + * @param x The region x-coordinate. + * @param y The region y-coordinate. + * @param objectId The object id. + * @return The scenery. + */ + public Scenery getChunkObject(int x, int y, int objectId) { + int chunkX = x / CHUNK_SIZE; + int chunkY = y / CHUNK_SIZE; + int offsetX = x - chunkX * CHUNK_SIZE; + int offsetY = y - chunkY * CHUNK_SIZE; + RegionChunk chunk = getRegionChunk(chunkX, chunkY); + if (chunk instanceof BuildRegionChunk) { + BuildRegionChunk brc = (BuildRegionChunk) chunk; + return brc.get(offsetX, offsetY, brc.getIndex(offsetX, offsetY, objectId)); + } + return getRegionChunk(chunkX, chunkY).getObjects()[offsetX][offsetY]; + } + + /** + * Gets an object from a region chunk. + * @param x The region x-coordinate. + * @param y The region y-coordinate. + * @return The scenery. + */ + public List getChunkItems(int x, int y) { + int chunkX = x / CHUNK_SIZE; + int chunkY = y / CHUNK_SIZE; + return getRegionChunk(chunkX, chunkY).getItems(); + } + + /** + * Gets a ground item from this plane. + * @param itemId The item id. + * @param l The location. + * @param player The player. + * @return The item. + */ + public GroundItem getItem(int itemId, Location l, Player player) { + GroundItem groundItem = null; + for (Item item : getChunkItems(l.getLocalX(), l.getLocalY())) { + GroundItem g = (GroundItem) item; + if (g.getId() == itemId && l.equals(g.getLocation()) && !g.isRemoved()) { + if (groundItem != null && (!g.isPrivate() || player == null)) { + continue; + } + if ((!g.isPrivate() || player == null || g.droppedBy(player))) { + groundItem = g; + } + } + } + return groundItem; + } + + /** + * Gets the region chunks. + * @return The chunks. + */ + public RegionChunk[][] getChunks() { + return chunks; + } + +} diff --git a/Server/src/main/core/game/world/map/Viewport.java b/Server/src/main/core/game/world/map/Viewport.java new file mode 100644 index 0000000..d563b03 --- /dev/null +++ b/Server/src/main/core/game/world/map/Viewport.java @@ -0,0 +1,155 @@ +package core.game.world.map; + +import core.game.node.entity.Entity; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; + +import java.util.LinkedList; +import java.util.List; + +/** + * Represents an entity's viewport. + * @author Emperor + */ +public final class Viewport { + + /** + * The amount of chunks in a viewport. + */ + public static final int CHUNK_SIZE = 5; + + /** + * The region region. + */ + private Region region; + + /** + * The region chunks. + */ + private RegionChunk[][] chunks = new RegionChunk[CHUNK_SIZE][CHUNK_SIZE]; + + /** + * The region region plane. + */ + private RegionPlane currentPlane; + + /** + * The region planes the entity can see. + */ + private List viewingPlanes = new LinkedList<>(); + + /** + * Constructs a new {@code Viewport} {@code Object}. + */ + public Viewport() { + /* + * empty. + */ + } + + /** + * Updates the entity's viewport. + * @param entity The entity. + */ + public void updateViewport(Entity entity) { + RegionChunk chunk = RegionManager.getRegionChunk(entity.getLocation()); + int center = chunks.length >> 1; + if (chunks[center][center] == chunk) { + return; + } + int offset = center * -8; + Location l = chunk.getCurrentBase(); + for (int x = 0; x < chunks.length; x++) { + for (int y = 0; y < chunks[x].length; y++) { + chunks[x][y] = RegionManager.getRegionChunk(l.transform(offset + (8 * x), offset + (8 * y), 0)); + } + } + } + + /** + * Removes the entity from the viewingPlanes. + * @param entity The entity. + */ + public void remove(Entity entity) { + if (region == null) { + return; + } + if (entity instanceof Player) { + region.remove((Player) entity); + Region region = null; + for (RegionPlane r : viewingPlanes) { + if (region != r.getRegion()) { + region = r.getRegion(); + region.decrementViewAmount(); + region.checkInactive(); + } + } + } else { + region.remove((NPC) entity); + } + } + + /** + * Gets the region. + * @return The region. + */ + public Region getRegion() { + return region; + } + + /** + * Sets the region. + * @param region The region to set. + */ + public void setRegion(Region region) { + this.region = region; + } + + /** + * Gets the chunks. + * @return The chunks. + */ + public RegionChunk[][] getChunks() { + return chunks; + } + + /** + * Sets the chunks. + * @param chunks The chunks to set. + */ + public void setChunks(RegionChunk[][] chunks) { + this.chunks = chunks; + } + + /** + * Gets the viewingPlanes. + * @return The viewingPlanes. + */ + public List getViewingPlanes() { + return viewingPlanes; + } + + /** + * Sets the viewingPlanes. + */ + public void setViewingPlanes(List regions) { + this.viewingPlanes = regions; + } + + /** + * Gets the currentPlane. + * @return The currentPlane. + */ + public RegionPlane getCurrentPlane() { + return currentPlane; + } + + /** + * Sets the currentPlane. + * @param currentPlane The currentPlane to set. + */ + public void setCurrentPlane(RegionPlane currentPlane) { + this.currentPlane = currentPlane; + } + +} diff --git a/Server/src/main/core/game/world/map/build/DynamicRegion.java b/Server/src/main/core/game/world/map/build/DynamicRegion.java new file mode 100644 index 0000000..2ccbabc --- /dev/null +++ b/Server/src/main/core/game/world/map/build/DynamicRegion.java @@ -0,0 +1,468 @@ +package core.game.world.map.build; + +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.music.MusicZone; +import core.game.node.item.GroundItem; +import core.game.node.item.GroundItemManager; +import core.game.node.scenery.Scenery; +import core.game.world.map.*; +import core.game.world.map.zone.RegionZone; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.impl.MultiwayCombatZone; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + + +/** + * Represents a dynamically constructed region. + * + * @author Emperor + */ +public final class DynamicRegion extends Region { + + /** + * The reserved areas. + */ + private static final List RESERVED_AREAS = new ArrayList<>(20); + + /** + * The region id of the copied region. + */ + private final int regionId; + + /** + * The region chunks. + */ + private final RegionChunk[][][] chunks; + + /** + * The zone borders. + */ + private ZoneBorders borders; + + /** + * If the dynamic region is a multiway combat zone. + */ + private boolean multicombat; + + /** + * If the region is permanent. + */ + private boolean permanent; + + /** + * An array of linked regions. + */ + private DynamicRegion[] linked; + + /** + * The parent region (used for linking regions). + */ + private DynamicRegion parentRegion; + + public ArrayList NPCs = new ArrayList<>(10); + + /** + * Constructs a new {@code DynamicRegion} {@code Object}. + * @param regionId The region id of the region to copy. + * @param x The x-coordinate. + * @param y The y-coordinate. + */ + public DynamicRegion(int regionId, int x, int y) { + super(x, y); + this.regionId = regionId; + this.chunks = new RegionChunk[4][SIZE >> 3][SIZE >> 3]; + RegionManager.resetFlags(getId()); + } + + public DynamicRegion(@NotNull ZoneBorders borders) { + this(-1, borders.getSouthWestX() >> 6, borders.getSouthWestY() >> 6); + setBorders(borders); + setUpdateAllPlanes(true); + RegionManager.addRegion(getId(), this); + } + + /** + * Creates a dynamic region copy of the region id. + * @param regionId The region id. + * @return The dynamic region. + */ + public static DynamicRegion create(int regionId) { + int x = (regionId >> 8) << 6; + int y = (regionId & 0xFF) << 6; + return create(new ZoneBorders(x, y, x + SIZE, y + SIZE))[0]; + } + + /** + * Creates a dynamic region copy of two regions and everything in between. + * @param regionOne The first region. + * @param regionTwo The second/last region. + * @return The new region. + */ + public static DynamicRegion create(int regionOne, int regionTwo) { + int x = (regionOne >> 8) << 6; + int y = (regionOne & 0xFF) << 6; + int x1 = (regionTwo >> 8) << 6; + int y1 = (regionTwo & 0xFF) << 6; + return create(new ZoneBorders(x, y, x1 + SIZE, y1 + SIZE))[0]; + } + + /** + * Copies the zone into a new dynamic region. + * @param copy The zone to copy. + * @return The dynamic region. + */ + public static DynamicRegion[] create(ZoneBorders copy) { + int baseX = copy.getSouthWestX() >> 6; + int baseY = copy.getSouthWestY() >> 6; + + ZoneBorders border = findZoneBorders((copy.getNorthEastX() - copy.getSouthWestX()) >> 3, (copy.getNorthEastY() - copy.getSouthWestY()) >> 3); + RESERVED_AREAS.add(border); + Location l = Location.create(border.getSouthWestX(), border.getSouthWestY(), 0); + List regions = new ArrayList<>(20); + for (int x = copy.getSouthWestX() >> 6; x < copy.getNorthEastX() >> 6; x++) { + for (int y = copy.getSouthWestY() >> 6; y < copy.getNorthEastY() >> 6; y++) { + int regionId = x << 8 | y; + Location loc = l.transform((x - baseX) << 6, (y - baseY) << 6, 0); + DynamicRegion region = copy(regionId, loc); + region.setBorders(border); + Region r = RegionManager.forId(region.getId()); + if (r != null) { + for (int z = 0; z < 4; z++) { + region.getPlanes()[z].getPlayers().addAll(r.getPlanes()[z].getPlayers()); + region.getPlanes()[z].getNpcs().addAll(r.getPlanes()[z].getNpcs()); + } + } + RegionManager.addRegion(region.getId(), region); + regions.add(region); + } + } + for (Region r : regions) { + for (int z = 0; z < 4; z++) { + for (Player p : r.getPlanes()[z].getPlayers()) { + p.updateSceneGraph(false); + } + } + } + return regions.toArray(new DynamicRegion[regions.size()]); + } + + /** + * Finds and reserves borders for a new dynamic region area. + * @param sizeX The x-size of the region (in chunks). + * @param sizeY The y-size of the region (in chunks). + * @return The zone borders. + */ + public static ZoneBorders reserveArea(int sizeX, int sizeY) { + ZoneBorders borders = findZoneBorders(sizeX, sizeY); + RESERVED_AREAS.add(borders); + return borders; + } + + /** + * Finds free borders for a new dynamic region area. + * @param sizeX The x-size of the region (in chunks). + * @param sizeY The y-size of the region (in chunks). + * @return The zone borders. + */ + public static ZoneBorders findZoneBorders(int sizeX, int sizeY) { + int x = 0; + int y = 0; + int count = 0; + int width = (sizeX >> 3) << 6; + int height = (sizeY >> 3) << 6; + if (width < 64) { + width = 64; + } + if (height < 64) { + height = 64; + } + while (true) { + int endX = x + width; + int endY = y + height; + boolean reserved = false; + for (ZoneBorders b : RESERVED_AREAS) { + if (b.insideBorder(x, y) || b.insideBorder(endX, endY) + || b.insideBorder(x, endY) || b.insideBorder(endX, y)) { + reserved = true; + break; + } + } + if (!reserved) { + return new ZoneBorders(x, y, endX, endY); + } + if (++count % 15 == 0) { + y += 64; + x = 0; + } else { + x += 64; + } + } + } + + /** + * Copies (but does not initialize) a region. + * @param regionId The id of the region to copy. + * @param to The location to copy the region to. + * @return The {@code DynamicRegion} object. + */ + public static DynamicRegion copy(int regionId, Location to) { + int regionX = ((regionId >> 8) & 0xFF) << 6; + int regionY = (regionId & 0xFF) << 6; + DynamicRegion region = new DynamicRegion(regionId, to.getRegionX() >> 3, to.getRegionY() >> 3); + Region base = RegionManager.forId(regionId); + Region.load(base); + for (int offsetX = 0; offsetX < 8; offsetX++) { + for (int offsetY = 0; offsetY < 8; offsetY++) { + int x = regionX + (offsetX << 3); + int y = regionY + (offsetY << 3); + for (int plane = 0; plane < 4; plane++) { + RegionChunk c = base.getPlanes()[plane].getRegionChunk(offsetX, offsetY); + if (c == null) { + region.chunks[plane][offsetX][offsetY] = c = new RegionChunk(Location.create(0, 0, 0), 0, region.getPlanes()[plane]); + } else { + region.replaceChunk(plane, offsetX, offsetY, (c = c.copy(region.getPlanes()[plane])), base); + } + c.setRotation(0); + c.setBase(Location.create(x, y, plane)); + } + } + } + return region; + } + + /** + * Links regions with this region as parent region. + * @param regions The regions to link. + * @warning This region will be flagged as active! + */ + public void link(DynamicRegion...regions) { + for (DynamicRegion r : regions) { + r.parentRegion = this; + } + this.linked = regions; + flagActive(); + } + + /** + * Toggles the multiway combat flag. + */ + public void toggleMulticombat() { + if (multicombat) { + for (Iterator it = getRegionZones().iterator(); it.hasNext();) { + if (it.next().getZone() == MultiwayCombatZone.getInstance()) { + it.remove(); + } + } + multicombat = false; + return; + } + getRegionZones().add(new RegionZone(MultiwayCombatZone.getInstance(), borders)); + multicombat = true; + } + + /** + * Sets the music id for this region. + * @param musicId The music id. + */ + public void setMusicId(int musicId) { + getMusicZones().add(new MusicZone(musicId, borders)); + } + + /** + * Rotates the region 90% clockwise. + * TODO: Finish this + */ + public void rotate() { + for (int z = 0; z < 4; z++) { + RegionChunk[][] c = Arrays.copyOf(chunks[z], 8); + for (int x = 0; x < 8; x++) { + for (int y = 0; y < 8; y++) { + RegionChunk r = chunks[z][x][y] = c[8 - y - 1][x]; + if (r != null) { + r.setRotation(r.getRotation() + 1); + } + } + } + } + } + + /** + * Sets a region chunk (without setting objects/clipping flags). + * @param z The plane. + * @param x The chunk x (0-8). + * @param y The chunk y (0-8). + * @param chunk The chunk to set. + */ + public void setChunk(int z, int x, int y, RegionChunk chunk) { + chunks[z][x][y] = chunk; + getPlanes()[z].getChunks()[x][y] = chunk; + if (chunk != null) { + chunk.setCurrentBase(getBaseLocation().transform(x << 3, y << 3, 0)); + } + } + + /** + * Replaces a region chunk. + * @param z The plane. + * @param x The x-coordinate of the chunk. (0-7) + * @param y The y-coordinate of the chunk. (0-7) + * @param chunk The chunk to replace with. + * @param fromRegion The region the chunk is copied from. + */ + public void replaceChunk(int z, int x, int y, RegionChunk chunk, Region fromRegion) { + Region.load(DynamicRegion.this); + RegionPlane p = getPlanes()[z]; + chunks[z][x][y] = chunk; + p.getChunks()[x][y] = chunk; + if (chunk == null) { + for (int i = x << 3; i < (x + 1) << 3; i++) { + for (int j = y << 3; j < (y + 1) << 3; j++) { + p.getFlags().invalidateFlag(i, j); + p.getProjectileFlags().invalidateFlag(i, j); + Scenery object = p.getObjects()[i][j]; + if (object != null) { + LandscapeParser.removeScenery(object); + } else { + p.add(null, i, j, true); + } + } + } + } else { + Region.load(fromRegion); + Location l = chunk.getBase(); + RegionPlane rp = fromRegion.getPlanes()[l.getZ()]; + chunk.setCurrentBase(getBaseLocation().transform(x << 3, y << 3, z)); + chunk.rebuildFlags(rp); + } + } + + @Override + public boolean flagInactive(boolean force) { + if (!permanent) { + if (parentRegion != null && parentRegion.isActive()) { + parentRegion.checkInactive(); + return false; + } + if (linked != null) { + for (DynamicRegion r : linked) { + if (!r.isInactive(false)) { + return false; + } + } + } + if(!super.flagInactive(force)) { + return false; + } + for (RegionPlane plane : getPlanes()) { + for (int i = 0; i < plane.getNpcs().size(); i++) { + NPC npc = plane.getNpcs().get(0); + npc.clear(); + } + for (RegionChunk[] chunks : getChunks()[plane.getPlane()]) { + for (RegionChunk chunk : chunks) { + if (chunk != null) { + for (Iterator it = chunk.getItems().iterator(); it.hasNext();) { + GroundItemManager.getItems().remove(it.next()); + } + } + } + } + } + RESERVED_AREAS.remove(borders); + if (multicombat) { + toggleMulticombat(); + } + boolean allLinkedInactive = true; + if (linked != null) { + for (DynamicRegion r : linked) { + allLinkedInactive &= r.flagInactive(force); + } + } + return allLinkedInactive; + } else { + return true; + } + } + + @Override + public int getRegionId() { + return regionId; + } + + /** + * Gets the chunks. + * @return The chunks. + */ + public RegionChunk[][][] getChunks() { + return chunks; + } + + /** + * Gets the borders. + * @return The borders. + */ + public ZoneBorders getBorders() { + return borders; + } + + /** + * Sets the borders. + * @param borders The borders to set. + */ + public void setBorders(ZoneBorders borders) { + this.borders = borders; + } + + /** + * Gets the multicombat. + * @return The multicombat. + */ + public boolean isMulticombat() { + return multicombat; + } + + /** + * Sets the multicombat. + * @param multicombat The multicombat to set. + */ + public void setMulticombat(boolean multicombat) { + this.multicombat = multicombat; + } + + /** + * Gets the permanent value. + * @return The permanent. + */ + public boolean isPermanent() { + return permanent; + } + + /** + * Sets the permanent value. + * @param permanent The permanent to set. + */ + public void setPermanent(boolean permanent) { + this.permanent = permanent; + } + + /** + * Gets the parentRegion value. + * @return The parentRegion. + */ + public DynamicRegion getParent() { + return parentRegion; + } + + public void clear(){ + for(NPC n : NPCs){ + n.clear(); + } + NPCs.clear(); + } +} diff --git a/Server/src/main/core/game/world/map/build/LandscapeParser.java b/Server/src/main/core/game/world/map/build/LandscapeParser.java new file mode 100644 index 0000000..81025e7 --- /dev/null +++ b/Server/src/main/core/game/world/map/build/LandscapeParser.java @@ -0,0 +1,223 @@ +package core.game.world.map.build; + +import core.cache.def.impl.SceneryDefinition; +import core.cache.misc.buffer.ByteBufferUtils; +import core.game.node.scenery.Scenery; +import core.game.world.map.Location; +import core.game.world.map.Region; +import core.game.world.map.RegionManager; +import core.game.world.map.RegionPlane; +import core.game.system.config.ObjectConfigParser; + +import java.nio.ByteBuffer; + +/** + * A utility class used for parsing landscapes. + * @author Emperor + * + */ +public final class LandscapeParser { + + /** + * Parses the landscape. + * @param r The region. + * @param mapscape The mapscape data. + * @param storeObjects If all objects should be stored (rather than just the objects with options). + */ + public static void parse(Region r, byte[][][] mapscape, ByteBuffer buffer, boolean storeObjects) { + int objectId = -1; + for (;;) { + int offset = ByteBufferUtils.getBigSmart(buffer); + if (offset == 0) { + break; + } + objectId += offset; + int location = 0; + for (;;) { + offset = ByteBufferUtils.getSmart(buffer); + if (offset == 0) { + break; + } + location += offset - 1; + int y = location & 0x3f; + int x = location >> 6 & 0x3f; + int configuration = buffer.get() & 0xFF; + int rotation = configuration & 0x3; + int type = configuration >> 2; + int z = location >> 12; + r.setObjectCount(r.getObjectCount() + 1); + if (x < 0 || y < 0 || x >= 64 || y >= 64) { + + } else { + if ((mapscape[1][x][y] & 0x2) == 2) { + z--; + } + if (z >= 0 && z <= 3) { + Scenery object = new Scenery(objectId, Location.create((r.getX() << 6) + x, (r.getY() << 6) + y, z), type, rotation); + flagScenery(r.getPlanes()[z], x, y, object, true, storeObjects); + } + } + } + } + } + + /** + * Adds a scenery temporarily. + * @param object The object to add. + */ + public static void addScenery(Scenery object) { + addScenery(object, false); + } + + /** + * Adds a scenery. + * @param object The object to add. + * @param landscape If the object should be added permanent. + */ + public static void addScenery(Scenery object, boolean landscape) { + Location l = object.getLocation(); + flagScenery(RegionManager.getRegionPlane(l), l.getLocalX(), l.getLocalY(), object, landscape, false); + } + + /** + * Flags a scenery on the plane's clipping flags. + * @param plane The plane. + * @param object The object. + * @param landscape If we are adding this scenery permanent. + * @param storeObjects If all objects should be stored (rather than just the objects with options). + */ + public static void flagScenery(RegionPlane plane, int localX, int localY, Scenery object, boolean landscape, boolean storeObjects) { + Region.load(plane.getRegion()); + SceneryDefinition def = object.getDefinition(); + object.setActive(true); + boolean add = storeObjects || !landscape || def.getChildObject(null).hasActions(); + if (add) { + addPlaneObject(plane, object, localX, localY, landscape, storeObjects); + } + + if (!applyClippingFlagsFor(plane, localX, localY, object)) + return; + + if (!storeObjects && !add && (!def.getChildObject(null).getName().equals("null"))) { + addPlaneObject(plane, object, localX, localY, landscape, false); + } + } + + public static boolean applyClippingFlagsFor(RegionPlane plane, int localX, int localY, Scenery object) { + SceneryDefinition def = object.getDefinition(); + int sizeX; + int sizeY; + if (object.getRotation() % 2 == 0) { + sizeX = def.sizeX; + sizeY = def.sizeY; + } else { + sizeX = def.sizeY; + sizeY = def.sizeX; + } + int type = object.getType(); + if (type == 22) { //Tile + plane.getFlags().getLandscape()[localX][localY] = true; + if (def.interactable != 0 || def.clipType == 1 || def.secondBool) { + if (def.clipType == 1) { + plane.getFlags().flagTileObject(localX, localY); + if (def.isProjectileClipped()) { + plane.getProjectileFlags().flagTileObject(localX, localY); + } + } + } + } else if (type >= 9) { //Default objects + if (def.clipType != 0) { + plane.getFlags().flagSolidObject(localX, localY, sizeX, sizeY, def.projectileClipped); + if (def.isProjectileClipped()) { + plane.getProjectileFlags().flagSolidObject(localX, localY, sizeX, sizeY, def.projectileClipped); + } + } + } else if (type >= 0 && type <= 3) { //Doors/walls + if (def.clipType != 0) { + plane.getFlags().flagDoorObject(localX, localY, object.getRotation(), type, def.projectileClipped); + if (def.isProjectileClipped()) { + plane.getProjectileFlags().flagDoorObject(localX, localY, object.getRotation(), type, def.projectileClipped); + } + } + } else { + return false; + } + return true; + } + + /** + * Adds an object to the region plane. + * @param plane The region plane. + * @param object The object to add. + * @param localX The local x-coordinate. + * @param localY The local y-coordinate. + * @param landscape The landscape. + */ + private static void addPlaneObject(RegionPlane plane, Scenery object, int localX, int localY, boolean landscape, boolean storeAll) { + if (landscape && !storeAll) { + Scenery current = plane.getObjects()[localX][localY]; + if (current != null && current.getDefinition().getChildObject(null).hasOptions(!object.getDefinition().getChildObject(null).hasOptions(false))) { + return; + } + } + plane.add(object, localX, localY, landscape && !storeAll); + } + + /** + * Removes a scenery. + * @param object The object. + * @return The removed scenery. + */ + public static Scenery removeScenery(Scenery object) { + if (!object.isRenderable()) { + return null; + } + RegionPlane plane = RegionManager.getRegionPlane(object.getLocation()); + Region.load(plane.getRegion()); + int localX = object.getLocation().getLocalX(); + int localY = object.getLocation().getLocalY(); + Scenery current = plane.getChunkObject(localX, localY, object.getId()); + if (current == null || current.getId() != object.getId()) { + return null; + } + current.setActive(false); + object.setActive(false); + plane.remove(localX, localY, object.getId()); + SceneryDefinition def = object.getDefinition(); + int sizeX; + int sizeY; + if (object.getRotation() % 2 == 0) { + sizeX = def.sizeX; + sizeY = def.sizeY; + } else { + sizeX = def.sizeY; + sizeY = def.sizeX; + } + int type = object.getType(); + if (type == 22) { //Tile + if (def.interactable != 0 || def.clipType == 1 || def.secondBool) { + if (def.clipType == 1) { + plane.getFlags().unflagTileObject(localX, localY); + if (def.isProjectileClipped()) { + plane.getProjectileFlags().unflagTileObject(localX, localY); + } + } + } + } else if (type >= 9) { //Default objects + if (def.clipType != 0) { + plane.getFlags().unflagSolidObject(localX, localY, sizeX, sizeY, def.projectileClipped); + if (def.isProjectileClipped()) { + plane.getProjectileFlags().unflagSolidObject(localX, localY, sizeX, sizeY, def.projectileClipped); + } + } + } else if (type >= 0 && type <= 3) { //Doors/walls + if (def.clipType != 0) { + plane.getFlags().unflagDoorObject(localX, localY, object.getRotation(), type, def.projectileClipped); + if (def.isProjectileClipped()) { + plane.getProjectileFlags().unflagDoorObject(localX, localY, object.getRotation(), type, def.projectileClipped); + } + } + } + return current; + } +} diff --git a/Server/src/main/core/game/world/map/build/MapscapeParser.java b/Server/src/main/core/game/world/map/build/MapscapeParser.java new file mode 100644 index 0000000..7ecc4c8 --- /dev/null +++ b/Server/src/main/core/game/world/map/build/MapscapeParser.java @@ -0,0 +1,77 @@ +package core.game.world.map.build; + +import core.game.world.map.Region; + +import java.nio.ByteBuffer; + +/** + * A utility class used for parsing mapscapes. + * @author Emperor + * + */ +public final class MapscapeParser { + + /** + * Parses the mapscape buffer. + * @param r The region. + * @param buffer The buffer. + */ + public static void parse(Region r, byte[][][] mapscape, ByteBuffer buffer) { + for (int z = 0; z < 4; z++) { + boolean[][] landscape = r.getPlanes()[z].getFlags().getLandscape(); + for (int x = 0; x < 64; x++) { + for (int y = 0; y < 64; y++) { + while (true) { + int value = buffer.get() & 0xFF; + if (value == 0) { + break; + } + if (value == 1) { + buffer.get(); + break; + } + if (value <= 49) { //Overlay data + int val = buffer.get() & 0xFF; + if (val != 42 && val > 0) { + landscape[x][y] = true; + } + } + else if (value <= 81) { + mapscape[z][x][y] = (byte) (value - 49); + } + else { + int val = (byte) (value - 81) & 0xFF; //Underlay data + if (val != 42 && val > 0) { + landscape[x][y] = true; + } + } + } + } + } + } + } + + /** + * Clips the mapscape. + * @param r The region. + * @param mapscape The mapscape. + */ + public static void clipMapscape(Region r, byte[][][] mapscape) { + for (int z = 0; z < 4; z++) { + for (int x = 0; x < 64; x++) { + for (int y = 0; y < 64; y++) { + r.getPlanes()[z].getFlags().flagEmptyTile(x,y); + if ((mapscape[z][x][y] & 0x1) == 1) { + int plane = z; + if ((mapscape[1][x][y] & 0x2) == 2) { + plane--; + } + if (plane > -1) { + r.getPlanes()[plane].getFlags().flagSolidTile(x, y); + } + } + } + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/world/map/build/RegionFlags.java b/Server/src/main/core/game/world/map/build/RegionFlags.java new file mode 100644 index 0000000..177da33 --- /dev/null +++ b/Server/src/main/core/game/world/map/build/RegionFlags.java @@ -0,0 +1,537 @@ +package core.game.world.map.build; + +import core.game.world.map.RegionManager; +import kotlin.Pair; + +import static java.lang.Math.max; + +/** + * Holds a region's flags like clipping flags, members, ... + * @author Emperor + * + */ +public final class RegionFlags { + + public static final int TILE_OBJECT = 0x40000; + public static final int EMPTY_TILE = 0; + public static final int SOLID_TILE = 0x200000; + public static final int OBJ_10_PROJECTILE = 0x20000; + public static final int OBJ_10 = 0x100; + /** + * The plane. + */ + private final int plane; + + /** + * If the region is members only. + */ + private boolean members; + + /** + * The base x-coordinate. + */ + private final int baseX; + + /** + * The base y-coordinate. + */ + private final int baseY; + + /** + * The landscape data. + */ + private boolean[][] landscape; + + /** + * If the flags are set for projectile clipping + */ + private final boolean projectile; + + /** + * Constructs a new {@code RegionFlags} {@code Object}. + * @param x The base x-coordinate (absolute). + * @param y The base y-coordinate (absolute). + */ + public RegionFlags(int plane, int x, int y) { + this(plane, x, y, false); + } + + /** + * Constructs a new {@code RegionFlags} {@code Object}. + * @param x The base x-coordinate (absolute). + * @param y The base y-coordinate (absolute). + */ + public RegionFlags(int plane, int x, int y, boolean projectile) { + this.plane = plane; + this.baseX = x; + this.baseY = y; + this.projectile = projectile; + } + + /** + * Flags a solid tile. + * @param x The x-coordinate. + * @param y The y-coordinate. + */ + public void flagSolidTile(int x, int y) { + flag(x, y, SOLID_TILE); + } + + public void flagEmptyTile(int x, int y) { + flag(x, y, EMPTY_TILE); + } + + /** + * Flags a tile object (object type 22). + * @param x The x-coordinate. + * @param y The y-coordinate. + */ + public void flagTileObject(int x, int y) { + flag(x, y, TILE_OBJECT); + } + + /** + * Unflags a tile object. + * @param x The x-coordinate. + * @param y The y-coordinate. + */ + public void unflagTileObject(int x, int y) { + unflag(x, y, TILE_OBJECT); + } + + /** + * Flags a solid object (type 10/11). + * @param x The x-coordinate + * @param y The y-coordinate. + * @param sizeX The x-size of the object. + * @param sizeY The y-size of the object. + * @param projectileClipped If the object is solid. + */ + public void flagSolidObject(int x, int y, int sizeX, int sizeY, boolean projectileClipped) { + int clipdata = OBJ_10; + if (projectileClipped) { + clipdata += OBJ_10_PROJECTILE; + } + for (int i = x; i < x + sizeX; i++) { + for (int j = y; j < y + sizeY; j++) { + flag(i, j, clipdata); + } + } + } + + /** + * Adds a flag. + * @param x The x-coordinate. + * @param y The y-coordinate. + * @param clipdata The clip data. + */ + public void flag(int x, int y, int clipdata) { + if (x > -1 && x < 64 && y > -1 && y < 64) { + addFlag(x, y, clipdata); + } else { + RegionManager.addClippingFlag(plane, baseX + x, baseY + y, projectile, clipdata); + } + } + + /** + * Unflags a solid object (type 10/11). + * @param x The x-coordinate + * @param y The y-coordinate. + * @param sizeX The x-size of the object. + * @param sizeY The y-size of the object. + * @param projectileClipped If the object is solid. + */ + public void unflagSolidObject(int x, int y, int sizeX, int sizeY, boolean projectileClipped) { + int clipdata = OBJ_10; + if (projectileClipped) { + clipdata += OBJ_10_PROJECTILE; + } + for (int i = x; i < x + sizeX; i++) { + for (int j = y; j < y + sizeY; j++) { + unflag(i, j, clipdata); + } + } + } + + /** + * Removes a flag. + * @param x The x-coordinate. + * @param y The y-coordinate. + * @param clipdata The clip data. + */ + public void unflag(int x, int y, int clipdata) { + if (x > -1 && x < 64 && y > -1 && y < 64) { + removeFlag(x, y, clipdata); + } else { + RegionManager.removeClippingFlag(plane, baseX + x, baseY + y, projectile, clipdata); + } + } + + private Pair getFlagIndex(int x, int y) { + return new Pair<>(((baseX >> 6) << 8) | (baseY >> 6), (plane * 64 * 64) + (x * 64) + y); + } + + public int getFlag(int x, int y) { + Pair indices = getFlagIndex(x, y); + return RegionManager.getFlags(indices.getFirst(), projectile)[indices.getSecond()]; + } + + public void addFlag(int x, int y, int clipdata) { + int current = getFlag(x, y); + Pair indices = getFlagIndex(x, y); + RegionManager.getFlags(indices.getFirst(), projectile)[indices.getSecond()] = max(0, current) | clipdata; + } + + public void removeFlag(int x, int y, int clipdata) { + int current = getFlag(x, y); + Pair indices = getFlagIndex(x, y); + if ((current & clipdata) == 0) return; + current = max(0, current) & ~clipdata; + + RegionManager.getFlags(indices.getFirst(), projectile)[indices.getSecond()] = current; + } + + public void clearFlag(int x, int y) { + Pair indices = getFlagIndex(x, y); + RegionManager.getFlags(indices.getFirst(), projectile)[indices.getSecond()] = 0; + } + + public void invalidateFlag(int x, int y) { + Pair indices = getFlagIndex(x, y); + RegionManager.getFlags(indices.getFirst(), projectile)[indices.getSecond()] = -1; + } + + /** + * Flags a door object (type 0-3). + * @param x The x-coordinate + * @param y The y-coordinate. + * @param rotation The rotation. + * @param type The type. + * @param projectileClipped If the door is solid. + */ + public void flagDoorObject(int x, int y, int rotation, int type, boolean projectileClipped) { + switch (type) { + case 0: + switch (rotation) { + case 0: + flag(x, y, 0x80); + flag(x - 1, y, 0x8); + break; + case 1: + flag(x, y, 0x2); + flag(x, y + 1, 0x20); + break; + case 2: + flag(x, y, 0x8); + flag(x + 1, y, 0x80); + break; + case 3: + flag(x, y, 0x20); + flag(x, y - 1, 0x2); + break; + } + break; + case 1: + case 3: + switch (rotation) { + case 0: + flag(x, y, 0x1); + flag(x - 1, y + 1, 0x10); + break; + case 1: + flag(x, y, 0x4); + flag(x + 1, y + 1, 0x40); + break; + case 2: + flag(x, y, 0x10); + flag(x + 1, y - 1, 0x1); + break; + case 3: + flag(x, y, 0x40); + flag(x - 1, y - 1, 0x4); + break; + } + break; + case 2: + switch (rotation) { + case 0: + flag(x, y, 0x82); + flag(x - 1, y, 0x8); + flag(x, y + 1, 0x20); + break; + case 1: + flag(x, y, 0xA); + flag(x, y + 1, 0x20); + flag(x + 1, y, 0x80); + break; + case 2: + flag(x, y, 0x28); + flag(x + 1, y, 0x80); + flag(x, y - 1, 0x2); + break; + case 3: + flag(x, y, 0xA0); + flag(x, y - 1, 0x2); + flag(x - 1, y, 0x8); + break; + } + break; + } + if (projectileClipped) { + switch (type) { + case 0: + switch (rotation) { + case 0: + flag(x, y, 0x10000); + flag(x - 1, y, 0x1000); + break; + case 1: + flag(x, y, 0x400); + flag(x, y + 1, 0x4000); + break; + case 2: + flag(x, y, 0x1000); + flag(x + 1, y, 0x10000); + break; + case 3: + flag(x, y, 0x4000); + flag(x, y - 1, 0x400); + break; + } + break; + case 1: + case 3: + switch (rotation) { + case 0: + flag(x, y, 0x200); + flag(x - 1, y + 1, 0x2000); + break; + case 1: + flag(x, y, 0x800); + flag(x + 1, y + 1, 0x8000); + break; + case 2: + flag(x, y, 0x2000); + flag(x + 1 , y - 1, 0x200); + break; + case 3: + flag(x, y, 0x8000); + flag(x - 1, y - 1, 0x800); + break; + } + break; + case 2: + switch (rotation) { + case 0: + flag(x, y, 0x10400); + flag(x - 1, y, 0x1000); + flag(x, y + 1, 0x4000); + break; + case 1: + flag(x, y, 0x1400); + flag(x, y + 1, 0x4000); + flag(x + 1, y, 0x10000); + break; + case 2: + flag(x, y, 0x5000); + flag(x + 1, y, 0x10000); + flag(x, y - 1, 0x400); + break; + case 3: + flag(x, y, 0x14000); + flag(x, y - 1, 0x400); + flag(x - 1, y, 0x1000); + break; + } + break; + } + } + } + + /** + * Unlags a door object (type 0-3). + * @param x The x-coordinate + * @param y The y-coordinate. + * @param rotation The rotation. + * @param type The type. + * @param projectileClipped If the door is solid. + */ + public void unflagDoorObject(int x, int y, int rotation, int type, boolean projectileClipped) { + switch (type) { + case 0: + switch (rotation) { + case 0: + unflag(x, y, 0x80); + unflag(x - 1, y, 0x8); + break; + case 1: + unflag(x, y, 0x2); + unflag(x, y + 1, 0x20); + break; + case 2: + unflag(x, y, 0x8); + unflag(x + 1, y, 0x80); + break; + case 3: + unflag(x, y, 0x20); + unflag(x, y - 1, 0x2); + break; + } + break; + case 1: + case 3: + switch (rotation) { + case 0: + unflag(x, y, 0x1); + unflag(x - 1, y + 1, 0x10); + break; + case 1: + unflag(x, y, 0x4); + unflag(x + 1, y + 1, 0x40); + break; + case 2: + unflag(x, y, 0x10); + unflag(x + 1, y - 1, 0x1); + break; + case 3: + unflag(x, y, 0x40); + unflag(x - 1, y - 1, 0x4); + break; + } + break; + case 2: + switch (rotation) { + case 0: + unflag(x, y, 0x82); + unflag(x - 1, y, 0x8); + unflag(x, y + 1, 0x20); + break; + case 1: + unflag(x, y, 0xA); + unflag(x, y + 1, 0x20); + unflag(x + 1, y, 0x80); + break; + case 2: + unflag(x, y, 0x28); + unflag(x + 1, y, 0x80); + unflag(x, y - 1, 0x2); + break; + case 3: + unflag(x, y, 0xA0); + unflag(x, y - 1, 0x2); + unflag(x - 1, y, 0x8); + break; + } + break; + } + if (projectileClipped) { + switch (type) { + case 0: + switch (rotation) { + case 0: + unflag(x, y, 0x10000); + unflag(x - 1, y, 0x1000); + break; + case 1: + unflag(x, y, 0x400); + unflag(x, y + 1, 0x4000); + break; + case 2: + unflag(x, y, 0x1000); + unflag(x + 1, y, 0x10000); + break; + case 3: + unflag(x, y, 0x4000); + unflag(x, y - 1, 0x400); + break; + } + break; + case 1: + case 3: + switch (rotation) { + case 0: + unflag(x, y, 0x200); + unflag(x - 1, y + 1, 0x2000); + break; + case 1: + unflag(x, y, 0x800); + unflag(x + 1, y + 1, 0x8000); + break; + case 2: + unflag(x, y, 0x2000); + unflag(x + 1 , y - 1, 0x200); + break; + case 3: + unflag(x, y, 0x8000); + unflag(x - 1, y - 1, 0x800); + break; + } + break; + case 2: + switch (rotation) { + case 0: + unflag(x, y, 0x10400); + unflag(x - 1, y, 0x1000); + unflag(x, y + 1, 0x4000); + break; + case 1: + unflag(x, y, 0x1400); + unflag(x, y + 1, 0x4000); + unflag(x + 1, y, 0x10000); + break; + case 2: + unflag(x, y, 0x5000); + unflag(x + 1, y, 0x10000); + unflag(x, y - 1, 0x400); + break; + case 3: + unflag(x, y, 0x14000); + unflag(x, y - 1, 0x400); + unflag(x - 1, y, 0x1000); + break; + } + break; + } + } + } + + /** + * Gets the members. + * @return The members. + */ + public boolean isMembers() { + return members; + } + + /** + * Sets the members. + * @param members The members to set. + */ + public void setMembers(boolean members) { + this.members = members; + } + + /** + * Gets the plane. + * @return The plane. + */ + public int getPlane() { + return plane; + } + + /** + * Gets the landscape. + * @return The landscape. + */ + public boolean[][] getLandscape() { + return landscape; + } + + /** + * Sets the landscape. + * @param landscape The landscape to set. + */ + public void setLandscape(boolean[][] landscape) { + this.landscape = landscape; + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/world/map/path/ClipMaskSupplier.java b/Server/src/main/core/game/world/map/path/ClipMaskSupplier.java new file mode 100644 index 0000000..346f5c0 --- /dev/null +++ b/Server/src/main/core/game/world/map/path/ClipMaskSupplier.java @@ -0,0 +1,7 @@ +package core.game.world.map.path; + +@FunctionalInterface +public interface ClipMaskSupplier { + + int getClippingFlag(int z, int x, int y); +} diff --git a/Server/src/main/core/game/world/map/path/DumbPathfinder.java b/Server/src/main/core/game/world/map/path/DumbPathfinder.java new file mode 100644 index 0000000..8bcfb32 --- /dev/null +++ b/Server/src/main/core/game/world/map/path/DumbPathfinder.java @@ -0,0 +1,427 @@ +package core.game.world.map.path; + +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.Point; + +import java.util.ArrayList; +import java.util.List; + +/** + * A pathfinder implementation used for an easy path, where the pathfinder won't + * find a way around clipped objects..
This is used for NPC combat + * following, NPC random movement, etc. + * @author Emperor + */ +public final class DumbPathfinder extends Pathfinder { + /** + * If a path can be found. + */ + private boolean found; + + /** + * The plane. + */ + private int z; + + /** + * The x-coordinate. + */ + private int x; + + /** + * The y-coordinate. + */ + private int y; + + @Override + public Path find(Location start, int size, Location end, int sizeX, int sizeY, int rotation, int type, int walkingFlag, boolean near, ClipMaskSupplier clipMaskSupplier) { + Path path = new Path(); + z = start.getZ(); + x = start.getX(); + y = start.getY(); + List points = new ArrayList<>(20); + path.setSuccesful(true); + while (x != end.getX() || y != end.getY()) { + Direction[] directions = getDirection(x, y, end); + if (type != 0) { + if ((type < 5 || type == 10) && canDoorInteract(x, y, size, end.getX(), end.getY(), type - 1, rotation, z, clipMaskSupplier)) { + break; + } + if (type < 10 && canDecorationInteract(x, y, size, end.getX(), end.getY(), type - 1, rotation, z, clipMaskSupplier)) { + break; + } + } + if (sizeX != 0 && sizeY != 0) { + if (canInteract(x, y, size, end.getX(), end.getY(), sizeX, sizeY, walkingFlag, z, clipMaskSupplier)) { + break; + } + if (directions.length > 1) { // Ensures we approach the location + // correctly (non-diagonal). + Direction dir = directions[0]; + if (x + dir.getStepX() == end.getX() && y + dir.getStepY() == end.getY()) { + directions[0] = directions[directions.length - 1]; + directions[directions.length - 1] = dir; + } + } + } + found = true; + if (size < 2) { + checkSingleTraversal(points, clipMaskSupplier, directions); + } else if (size == 2) { + checkDoubleTraversal(points, clipMaskSupplier, directions); + } else { + checkVariableTraversal(points, directions, size, clipMaskSupplier); + } + if (!found) { + path.setMoveNear(x != start.getX() || y != start.getY()); + path.setSuccesful(false); + break; + } + } + if (!points.isEmpty()) { + Direction last = null; + for (int i = 0; i < points.size() - 1; i++) { + Point p = points.get(i); + path.getPoints().add(p); + } + path.getPoints().add(points.get(points.size() - 1)); + } + return path; + } + + /** + * Checks traversal for a size 1 entity. + * @param points The points list. + * @param directions The directions. + */ + private void checkSingleTraversal(List points, ClipMaskSupplier clipMaskSupplier, Direction... directions) { + for (Direction dir : directions) { + found = true; + switch (dir) { + case NORTH: + if ((clipMaskSupplier.getClippingFlag(z, x, y + 1) & PREVENT_NORTH) != 0) { + found = false; + break; + } + points.add(new Point(x, y + 1, dir)); + y++; + break; + case NORTH_EAST: + if ((clipMaskSupplier.getClippingFlag(z, x + 1, y) & PREVENT_EAST) != 0 || (clipMaskSupplier.getClippingFlag(z, x, y + 1) & PREVENT_NORTH) != 0 || (clipMaskSupplier.getClippingFlag(z, x + 1, y + 1) & PREVENT_NORTHEAST) != 0) { + found = false; + break; + } + points.add(new Point(x + 1, y + 1, dir)); + x++; + y++; + break; + case EAST: + if ((clipMaskSupplier.getClippingFlag(z, x + 1, y) & PREVENT_EAST) != 0) { + found = false; + break; + } + points.add(new Point(x + 1, y, dir)); + x++; + break; + case SOUTH_EAST: + if ((clipMaskSupplier.getClippingFlag(z, x + 1, y) & PREVENT_EAST) != 0 || (clipMaskSupplier.getClippingFlag(z, x, y - 1) & PREVENT_SOUTH) != 0 || (clipMaskSupplier.getClippingFlag(z, x + 1, y - 1) & PREVENT_SOUTHEAST) != 0) { + found = false; + break; + } + points.add(new Point(x + 1, y - 1, dir)); + x++; + y--; + break; + case SOUTH: + if ((clipMaskSupplier.getClippingFlag(z, x, y - 1) & PREVENT_SOUTH) != 0) { + found = false; + break; + } + points.add(new Point(x, y - 1, dir)); + y--; + break; + case SOUTH_WEST: + if ((clipMaskSupplier.getClippingFlag(z, x - 1, y) & PREVENT_WEST) != 0 || (clipMaskSupplier.getClippingFlag(z, x, y - 1) & PREVENT_SOUTH) != 0 || (clipMaskSupplier.getClippingFlag(z, x - 1, y - 1) & PREVENT_SOUTHWEST) != 0) { + found = false; + break; + } + points.add(new Point(x - 1, y - 1, dir)); + x--; + y--; + break; + case WEST: + if ((clipMaskSupplier.getClippingFlag(z, x - 1, y) & PREVENT_WEST) != 0) { + found = false; + break; + } + points.add(new Point(x - 1, y, dir)); + x--; + break; + case NORTH_WEST: + if ((clipMaskSupplier.getClippingFlag(z, x - 1, y) & PREVENT_WEST) != 0 || (clipMaskSupplier.getClippingFlag(z, x, y + 1) & PREVENT_NORTH) != 0 || (clipMaskSupplier.getClippingFlag(z, x - 1, y + 1) & PREVENT_NORTHWEST) != 0) { + found = false; + break; + } + points.add(new Point(x - 1, y + 1, dir)); + x--; + y++; + break; + } + if (found) { + break; + } + } + } + + /** + * Checks traversal for a size 1 entity. + * @param points The points list. + * @param directions The directions. + */ + private void checkDoubleTraversal(List points, ClipMaskSupplier clipMaskSupplier, Direction... directions) { + for (Direction dir : directions) { + found = true; + switch (dir) { + case NORTH: + if ((clipMaskSupplier.getClippingFlag(z, x, y + 2) & 0x12c0138) != 0 || (clipMaskSupplier.getClippingFlag(z, x + 1, y + 2) & 0x12c01e0) != 0) { + found = false; + break; + } + points.add(new Point(x, y + 1, dir)); + y++; + break; + case NORTH_EAST: + if ((clipMaskSupplier.getClippingFlag(z, x + 1, y + 2) & 0x12c0138) != 0 || (clipMaskSupplier.getClippingFlag(z, x + 2, y + 2) & 0x12c01e0) != 0 || (clipMaskSupplier.getClippingFlag(z, x + 2, y + 1) & 0x12c0183) != 0) { + found = false; + break; + } + points.add(new Point(x + 1, y + 1, dir)); + x++; + y++; + break; + case EAST: + if ((clipMaskSupplier.getClippingFlag(z, x + 2, y) & 0x12c0183) != 0 || (clipMaskSupplier.getClippingFlag(z, x + 2, y + 1) & 0x12c01e0) != 0) { + found = false; + break; + } + points.add(new Point(x + 1, y, dir)); + x++; + break; + case SOUTH_EAST: + if ((clipMaskSupplier.getClippingFlag(z, x + 1, y - 1) & 0x12c010e) != 0 || (clipMaskSupplier.getClippingFlag(z, x + 2, y) & 0x12c01e0) != 0 || (clipMaskSupplier.getClippingFlag(z, x + 2, y - 1) & 0x12c0183) != 0) { + found = false; + break; + } + points.add(new Point(x + 1, y - 1, dir)); + x++; + y--; + break; + case SOUTH: + if ((clipMaskSupplier.getClippingFlag(z, x, y - 1) & 0x12c010e) != 0 || (clipMaskSupplier.getClippingFlag(z, x + 1, y - 1) & 0x12c0183) != 0) { + found = false; + break; + } + points.add(new Point(x, y - 1, dir)); + y--; + break; + case SOUTH_WEST: + if ((clipMaskSupplier.getClippingFlag(z, x - 1, y - 1) & 0x12c010e) != 0 || (clipMaskSupplier.getClippingFlag(z, x - 1, y) & 0x12c0138) != 0 || (clipMaskSupplier.getClippingFlag(z, x, y - 1) & 0x12c0183) != 0) { + found = false; + break; + } + points.add(new Point(x - 1, y - 1, dir)); + x--; + y--; + break; + case WEST: + if ((clipMaskSupplier.getClippingFlag(z, x - 1, y) & 0x12c010e) != 0 || (clipMaskSupplier.getClippingFlag(z, x - 1, y + 1) & 0x12c0138) != 0) { + found = false; + break; + } + points.add(new Point(x - 1, y, dir)); + x--; + break; + case NORTH_WEST: + if ((clipMaskSupplier.getClippingFlag(z, x - 1, y + 1) & 0x12c010e) != 0 || (clipMaskSupplier.getClippingFlag(z, x - 1, y + 2) & 0x12c0138) != 0 || (clipMaskSupplier.getClippingFlag(z, x, y + 2) & 0x12c01e0) != 0) { + found = false; + break; + } + points.add(new Point(x - 1, y + 1, dir)); + x--; + y++; + break; + } + if (found) { + break; + } + } + } + + /** + * Checks traversal for variable size entities. + * @param points The points list. + * @param directions The directions to check. + * @param size The mover size. + */ + private void checkVariableTraversal(List points, Direction[] directions, int size, ClipMaskSupplier clipMaskSupplier) { + for (Direction dir : directions) { + found = true; + roar: switch (dir) { + case NORTH: + if ((clipMaskSupplier.getClippingFlag(z, x, y + size) & 0x12c0138) != 0 || (clipMaskSupplier.getClippingFlag(z, x + (size - 1), y + size) & 0x12c01e0) != 0) { + found = false; + break; + } + for (int i = 1; i < size - 1; i++) { + if ((clipMaskSupplier.getClippingFlag(z, x + i, y + size) & 0x12c01f8) != 0) { + found = false; + break roar; + } + } + points.add(new Point(x, y + 1, dir)); + y++; + break; + case NORTH_EAST: + if ((clipMaskSupplier.getClippingFlag(z, x + 1, y + size) & 0x12c0138) != 0 || (clipMaskSupplier.getClippingFlag(z, x + size, y + size) & 0x12c01e0) != 0 || (clipMaskSupplier.getClippingFlag(z, x + size, y + 1) & 0x12c0183) != 0) { + found = false; + break; + } + for (int i = 1; i < size - 1; i++) { + if ((clipMaskSupplier.getClippingFlag(z, x + (i + 1), y + size) & 0x12c01f8) != 0 || (clipMaskSupplier.getClippingFlag(z, x + size, y + (i + 1)) & 0x12c01e3) != 0) { + found = false; + break roar; + } + } + points.add(new Point(x + 1, y + 1, dir)); + x++; + y++; + break; + case EAST: + if ((clipMaskSupplier.getClippingFlag(z, x + size, y) & 0x12c0183) != 0 || (clipMaskSupplier.getClippingFlag(z, x + size, y + (size - 1)) & 0x12c01e0) != 0) { + found = false; + break; + } + for (int i = 1; i < size - 1; i++) { + if ((clipMaskSupplier.getClippingFlag(z, x + size, y + i) & 0x12c01e3) != 0) { + found = false; + break roar; + } + } + points.add(new Point(x + 1, y, dir)); + x++; + break; + case SOUTH_EAST: + if ((clipMaskSupplier.getClippingFlag(z, x + 1, y - 1) & 0x12c010e) != 0 || (clipMaskSupplier.getClippingFlag(z, x + size, y + (size - 2)) & 0x12c01e0) != 0 || (clipMaskSupplier.getClippingFlag(z, x + size, y - 1) & 0x12c0183) != 0) { + found = false; + break; + } + for (int i = 1; i < size - 1; i++) { + if ((clipMaskSupplier.getClippingFlag(z, x + size, y + (i - 1)) & 0x12c01e3) != 0 || (clipMaskSupplier.getClippingFlag(z, x + (i + 1), y - 1) & 0x12c018f) != 0) { + found = false; + break roar; + } + } + points.add(new Point(x + 1, y - 1, dir)); + x++; + y--; + break; + case SOUTH: + if ((clipMaskSupplier.getClippingFlag(z, x, y - 1) & 0x12c010e) != 0 || (clipMaskSupplier.getClippingFlag(z, x + (size - 1), y - 1) & 0x12c0183) != 0) { + found = false; + break; + } + for (int i = 1; i < size - 1; i++) { + if ((clipMaskSupplier.getClippingFlag(z, x + i, y - 1) & 0x12c018f) != 0) { + found = false; + break roar; + } + } + points.add(new Point(x, y - 1, dir)); + y--; + break; + case SOUTH_WEST: + if ((clipMaskSupplier.getClippingFlag(z, x - 1, y + (size - 2)) & 0x12c0138) != 0 || (clipMaskSupplier.getClippingFlag(z, x - 1, y - 1) & 0x12c010e) != 0 || (clipMaskSupplier.getClippingFlag(z, x + (size - 2), y - 1) & 0x12c0183) != 0) { + found = false; + break; + } + for (int i = 1; i < size - 1; i++) { + if ((clipMaskSupplier.getClippingFlag(z, x - 1, y + (i - 1)) & 0x12c013e) != 0 || (clipMaskSupplier.getClippingFlag(z, x + (i - 1), y - 1) & 0x12c018f) != 0) { + found = false; + break roar; + } + } + points.add(new Point(x - 1, y - 1, dir)); + x--; + y--; + break; + case WEST: + if ((clipMaskSupplier.getClippingFlag(z, x - 1, y) & 0x12c010e) != 0 || (clipMaskSupplier.getClippingFlag(z, x - 1, y + (size - 1)) & 0x12c0138) != 0) { + found = false; + break; + } + for (int i = 1; i < size - 1; i++) { + if ((clipMaskSupplier.getClippingFlag(z, x - 1, y + i) & 0x12c013e) != 0) { + found = false; + break roar; + } + } + points.add(new Point(x - 1, y, dir)); + x--; + break; + case NORTH_WEST: + if ((clipMaskSupplier.getClippingFlag(z, x - 1, y + 1) & 0x12c010e) != 0 || (clipMaskSupplier.getClippingFlag(z, x - 1, y + size) & 0x12c0138) != 0 || (clipMaskSupplier.getClippingFlag(z, x, y + size) & 0x12c01e0) != 0) { + found = false; + break; + } + for (int i = 1; i < size - 1; i++) { + if ((clipMaskSupplier.getClippingFlag(z, x - 1, y + (i + 1)) & 0x12c013e) != 0 || (clipMaskSupplier.getClippingFlag(z, x + (i - 1), y + size) & 0x12c01f8) != 0) { + found = false; + break roar; + } + } + points.add(new Point(x - 1, y + 1, dir)); + x--; + y++; + break; + } + if (found) { + break; + } + } + } + + /** + * Gets the direction. + * @param end The end direction. + * @return The direction. + */ + private static Direction[] getDirection(int startX, int startY, Location end) { + int endX = end.getX(); + int endY = end.getY(); + if (startX == endX) { + if (startY > endY) { + return new Direction[] { Direction.SOUTH }; + } else if (startY < endY) { + return new Direction[] { Direction.NORTH }; + } + } else if (startY == endY) { + if (startX > endX) { + return new Direction[] { Direction.WEST }; + } + return new Direction[] { Direction.EAST }; + } else { + if (startX < endX && startY < endY) { + return new Direction[] { Direction.NORTH_EAST, Direction.EAST, Direction.NORTH }; + } else if (startX < endX && startY > endY) { + return new Direction[] { Direction.SOUTH_EAST, Direction.EAST, Direction.SOUTH }; + } else if (startX > endX && startY < endY) { + return new Direction[] { Direction.NORTH_WEST, Direction.WEST, Direction.NORTH }; + } else if (startX > endX && startY > endY) { + return new Direction[] { Direction.SOUTH_WEST, Direction.WEST, Direction.SOUTH }; + } + } + return new Direction[0]; + } + +} diff --git a/Server/src/main/core/game/world/map/path/Path.java b/Server/src/main/core/game/world/map/path/Path.java new file mode 100644 index 0000000..7357fea --- /dev/null +++ b/Server/src/main/core/game/world/map/path/Path.java @@ -0,0 +1,100 @@ +package core.game.world.map.path; + +import core.game.node.entity.Entity; +import core.game.world.map.Point; + +import java.util.ArrayDeque; +import java.util.Deque; + +/** + * Represents a path. + * @author Emperor + */ +public class Path { + + /** + * If the path was found. + */ + private boolean succesful; + + /** + * If we have to move near the destination (as we can't reach it). + */ + private boolean moveNear; + + /** + * The points to walk. + */ + private Deque points = new ArrayDeque(); + + /** + * Constructs a new {@code Path} {@code Object}. + */ + public Path() { + /* + * empty. + */ + } + + /** + * Walks this path. + * @param entity The entity. + */ + public void walk(Entity entity) { + if (entity.getLocks().isMovementLocked()) { + return; + } + entity.getWalkingQueue().reset(); + for (Point step : points) { + entity.getWalkingQueue().addPath(step.getX(), step.getY()); + } + } + + /** + * Gets the succesful. + * @return The succesful. + */ + public boolean isSuccessful() { + return succesful; + } + + /** + * Sets the succesful. + * @param succesful The succesful to set. + */ + public void setSuccesful(boolean succesful) { + this.succesful = succesful; + } + + /** + * Gets the points. + * @return The points. + */ + public Deque getPoints() { + return points; + } + + /** + * Sets the points. + * @param points The points to set. + */ + public void setPoints(Deque points) { + this.points = points; + } + + /** + * Gets the moveNear. + * @return The moveNear. + */ + public boolean isMoveNear() { + return moveNear; + } + + /** + * Sets the moveNear. + * @param moveNear The moveNear to set. + */ + public void setMoveNear(boolean moveNear) { + this.moveNear = moveNear; + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/world/map/path/Pathfinder.java b/Server/src/main/core/game/world/map/path/Pathfinder.java new file mode 100644 index 0000000..9fce3a7 --- /dev/null +++ b/Server/src/main/core/game/world/map/path/Pathfinder.java @@ -0,0 +1,718 @@ +package core.game.world.map.path; + +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.npc.NPC; +import core.game.node.item.GroundItem; +import core.game.node.scenery.Scenery; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; + +public abstract class Pathfinder { + public static final int PREVENT_NORTH = 0x12c0120; + public static final int PREVENT_EAST = 0x12c0180; + public static final int PREVENT_NORTHEAST = 0x12c01e0; + public static final int PREVENT_SOUTH = 0x12c0102; + public static final int PREVENT_SOUTHEAST = 0x12c0183; + public static final int PREVENT_WEST = 0x12c0108; + public static final int PREVENT_SOUTHWEST = 0x12c010e; + public static final int PREVENT_NORTHWEST = 0x12c0138; + + + /** + * The smart path finder. + */ + public static final SmartPathfinder SMART = new SmartPathfinder(); + + /** + * The dumb path finder. + */ + public static final DumbPathfinder DUMB = new DumbPathfinder(); + + /** + * The projectile path finder. + */ + public static final ProjectilePathfinder PROJECTILE = new ProjectilePathfinder(); + + /** + * The south direction flag. + */ + public static final int SOUTH_FLAG = 0x1; + + /** + * The west direction flag. + */ + public static final int WEST_FLAG = 0x2; + + /** + * The north direction flag. + */ + public static final int NORTH_FLAG = 0x4; + + /** + * The east direction flag. + */ + public static final int EAST_FLAG = 0x8; + + /** + * The south-west direction flag. + */ + public static final int SOUTH_WEST_FLAG = SOUTH_FLAG | WEST_FLAG; + + /** + * The north-west direction flag. + */ + public static final int NORTH_WEST_FLAG = NORTH_FLAG | WEST_FLAG; + + /** + * The south-east direction flag. + */ + public static final int SOUTH_EAST_FLAG = SOUTH_FLAG | EAST_FLAG; + + /** + * The north-east direction flag. + */ + public static final int NORTH_EAST_FLAG = NORTH_FLAG | EAST_FLAG; + + public static int flagForDirection(Direction d) { + switch(d) { + case NORTH_WEST: return NORTH_WEST_FLAG; + case NORTH: return NORTH_FLAG; + case NORTH_EAST: return NORTH_EAST_FLAG; + case WEST: return WEST_FLAG; + case EAST: return EAST_FLAG; + case SOUTH_WEST: return SOUTH_WEST_FLAG; + case SOUTH: return SOUTH_FLAG; + case SOUTH_EAST: return SOUTH_EAST_FLAG; + default: return 0; + } + } + + /** + * Finds a path from the location to the end location. + * @param location The start location. + * @param size The mover size. + * @param end The end location. + * @param sizeX The x-size of the destination node. + * @param sizeY The y-size of the destination node. + * @param rotation The object rotation. + * @param type The object type. + * @param walkingFlag The object walking flag. + * @param near If we should find the nearest location if a path can't be + * found. + * @return The path. + */ + public abstract Path find(Location location, int size, Location end, int sizeX, int sizeY, int rotation, int type, int walkingFlag, boolean near, ClipMaskSupplier clipMaskSupplier); + + /** + * Finds a path from the start location to the end location. + * @param mover The moving entity. + * @param destination The destination node. + * @return The path. + */ + public static Path find(Entity mover, Node destination) { + return find(mover, destination, true, SMART); + } + + /** + * Finds a path from the start location to the end location. + * @param mover The moving entity. + * @param destination The destination node. + * @param near If we should move near the end location, if we can't reach + * it. + * @param finder The pathfinder to use. + * @return The path. + */ + public static Path find(Entity mover, Node destination, boolean near, Pathfinder finder) { + ClipMaskSupplier cms = null; + if (mover instanceof NPC) { + cms = ((NPC) mover).behavior.getClippingSupplier(((NPC) mover)); + } + if (cms == null) + cms = RegionManager::getClippingFlag; + return find(mover.getLocation(), mover.size(), destination, near, finder, cms); + } + + public static Path findWater(Entity mover, Node destination, boolean near, Pathfinder finder){ + return find(mover.getLocation(),mover.size(),destination,near,finder, RegionManager::getWaterClipFlag); + } + + public static Path find(Entity mover, Node destination, boolean near, Pathfinder finder, ClipMaskSupplier clipMaskSupplier) { + return find(mover.getLocation(), mover.size(), destination, near, finder, clipMaskSupplier); + } + + /** + * Finds a path from the start location to the end location. + * @param destination The destination node. + * @return The path. + */ + public static Path find(Location start, Node destination) { + return find(start, destination, true, SMART); + } + + public static Path find(Location start, Node destination, int moverSize) { + return find(start, moverSize, destination, true, SMART, RegionManager::getClippingFlag); + } + + /** + * Finds a path from the start location to the end location. + * @param destination The destination node. + * @param near If we should move near the end location, if we can't reach + * it. + * @param finder The pathfinder to use. + * @return The path. + */ + public static Path find(Location start, Node destination, boolean near, Pathfinder finder) { + return find(start, 1, destination, near, finder, RegionManager::getClippingFlag); + } + + /** + * Finds a path from the start location to the end location. + * @param destination The destination node. + * @param near If we should move near the end location, if we can't reach + * it. + * @param finder The pathfinder to use. + * @return The path. + */ + public static Path find(Location start, int moverSize, Node destination, boolean near, Pathfinder finder, ClipMaskSupplier clipMaskSupplier) { + if (destination instanceof Scenery) { + Scenery object = (Scenery) destination; + int type = object.getType(); + int rotation = object.getRotation(); + if (type == 10 || type == 11 || type == 22) { + int sizeX = object.getDefinition().sizeX; + int sizeY = object.getDefinition().sizeY; + if (rotation % 2 != 0) { + sizeX = object.getDefinition().sizeY; + sizeY = object.getDefinition().sizeX; + } + int walkingFlag = object.getDefinition().getWalkingFlag(); + if (rotation != 0) { + walkingFlag = (walkingFlag << rotation & 0xf) + (walkingFlag >> 4 - rotation); + } + return finder.find(start, moverSize, destination.getLocation(), sizeX, sizeY, 0, 0, walkingFlag, near, clipMaskSupplier); + } + return finder.find(start, moverSize, destination.getLocation(), 0, 0, rotation, 1 + type, 0, near, clipMaskSupplier); + } + int size = 0; + if (destination instanceof Entity) { + size = destination.size(); + } else if (destination instanceof GroundItem && !RegionManager.isTeleportPermitted(destination.getLocation())) { + size = 1; + } + return finder.find(start, moverSize, destination.getLocation(), size, size, 0, 0, 0, near, clipMaskSupplier); + } + + /** + * Checks if interaction with decoration is possible. + * @param curX The current x-coordinate in viewport. + * @param curY The current y-coordinate in viewport. + * @param size The mover size. + * @param destX The destination x-coordinate in viewport. + * @param destY The destination y-coordinate in viewport. + * @param type The object type. + * @param rotation The object rotation. + * @return {@code True} if so. + */ + public static boolean canDecorationInteract(int curX, int curY, int size, int destX, int destY, int rotation, int type, int z, ClipMaskSupplier clipMaskSupplier) { + if (size != 1) { + if (destX >= curX && destX <= (curX + size) - 1 && destY <= (destY + size) - 1) { + return true; + } + } else if (destX == curX && curY == destY) { + return true; + } + if (size == 1) { + int flag = clipMaskSupplier.getClippingFlag(z, curX, curY); + if (type == 6 || type == 7) { + if (type == 7) { + rotation = rotation + 2 & 0x3; + } + if (rotation == 0) { + if (curX == 1 + destX && curY == destY && (0x80 & flag) == 0) { + return true; + } + if (destX == curX && curY == destY - 1 && (flag & 0x2) == 0) { + return true; + } + } else if (rotation == 1) { + if (curX == destX - 1 && curY == destY && (0x8 & flag) == 0) { + return true; + } + if (curX == destX && curY == destY - 1 && (flag & 0x2) == 0) { + return true; + } + } else if (rotation == 2) { + if (destX - 1 == curX && destY == curY && (flag & 0x8) == 0) { + return true; + } + if (destX == curX && destY + 1 == curY && (0x20 & flag) == 0) { + return true; + } + } else if (rotation == 3) { + if (destX + 1 == curX && curY == destY && (0x80 & flag) == 0) { + return true; + } + if (destX == curX && curY == destY + 1 && (0x20 & flag) == 0) { + return true; + } + } + } + if (type == 8) { + if (destX == curX && curY == destY + 1 && (flag & 0x20) == 0) { + return true; + } + if (destX == curX && -1 + destY == curY && (0x2 & flag) == 0) { + return true; + } + if (curX == destX - 1 && curY == destY && (0x8 & flag) == 0) { + return true; + } + if (curX == destX + 1 && curY == destY && (flag & 0x80) == 0) { + return true; + } + } + } else { + int cornerX = curX + size - 1; + int cornerY = curY + size - 1; + if (type == 6 || type == 7) { + if (type == 7) { + rotation = 0x3 & 2 + rotation; + } + if (rotation == 0) { + if (destX + 1 == curX && destY >= curY && destY <= cornerY && (clipMaskSupplier.getClippingFlag(z, curX, destY) & 0x80) == 0) { + return true; + } + if (destX >= curX && destX <= cornerX && destY - size == curY && (0x2 & clipMaskSupplier.getClippingFlag(z, destX, cornerY)) == 0) { + return true; + } + } else if (rotation == 1) { + if (-size + destX == curX && destY >= curY && cornerY >= destY && (clipMaskSupplier.getClippingFlag(z, cornerX, destY) & 0x8) == 0) { + return true; + } + if (curX <= destX && cornerX >= destX && -size + destY == curY && (clipMaskSupplier.getClippingFlag(z, destX, cornerY) & 0x2) == 0) { + return true; + } + } else if (rotation == 2) { + if (curX == destX - size && curY <= destY && destY <= cornerY && (0x8 & clipMaskSupplier.getClippingFlag(z, cornerX, destY)) == 0) { + return true; + } + if (curX <= destX && cornerX >= destX && destY + 1 == curY && (0x20 & clipMaskSupplier.getClippingFlag(z, destX, curY)) == 0) { + return true; + } + } else if (rotation == 3) { + if (1 + destX == curX && curY <= destY && destY <= cornerY && (0x80 & clipMaskSupplier.getClippingFlag(z, curX, destY)) == 0) { + return true; + } + if (destX >= curX && destX <= cornerX && 1 + destY == curY && (clipMaskSupplier.getClippingFlag(z, destX, curY) & 0x20) == 0) { + return true; + } + } + } + if (type == 8) { + if (curX <= destX && destX <= cornerX && 1 + destY == curY && (clipMaskSupplier.getClippingFlag(z, destX, curY) & 0x20) == 0) { + return true; + } + if (curX <= destX && destX <= cornerX && curY == -size + destY && (0x2 & clipMaskSupplier.getClippingFlag(z, destX, cornerY)) == 0) { + return true; + } + if (curX == -size + destX && destY >= curY && destY <= cornerY && (0x8 & clipMaskSupplier.getClippingFlag(z, cornerX, destY)) == 0) { + return true; + } + if (1 + destX == curX && curY <= destY && cornerY >= destY && (clipMaskSupplier.getClippingFlag(z, curX, destY) & 0x80) == 0) { + return true; + } + } + } + return false; + } + + /** + * Checks if interaction with a door is possible. + * @param curX The current x-coordinate in viewport. + * @param curY The current y-coordinate in viewport. + * @param size The mover size. + * @param destX The destination x-coordinate in viewport. + * @param destY The destination y-coordinate in viewport. + * @param type The object type. + * @param rotation The object rotation. + * @return {@code True} if so. + */ + public static boolean canDoorInteract(int curX, int curY, int size, int destX, int destY, int type, int rotation, int z, ClipMaskSupplier clipMaskSupplier) { + if (size != 1) { + if (destX >= curX && destX <= size + curX - 1 && destY <= destY + size - 1) { + return true; + } + } else if (curX == destX && destY == curY) { + return true; + } + + if (size == 1) { + if (type == 0) { + if (rotation == 0) { + if (curX == destX - 1 && destY == curY) { + return true; + } + if (destX == curX && 1 + destY == curY && (0x12c0120 & clipMaskSupplier.getClippingFlag(z, curX, curY)) == 0) { + return true; + } + if (curX == destX && destY - 1 == curY && (clipMaskSupplier.getClippingFlag(z, curX, curY) & 0x12c0102) == 0) { + return true; + } + } else if (rotation == 1) { + if (curX == destX && destY + 1 == curY) { + return true; + } + if (curX == destX - 1 && curY == destY && (0x12c0108 & clipMaskSupplier.getClippingFlag(z, curX, curY)) == 0) { + return true; + } + if (curX == 1 + destX && destY == curY && (0x12c0180 & clipMaskSupplier.getClippingFlag(z, curX, curY)) == 0) { + return true; + } + } else if (rotation == 2) { + if (1 + destX == curX && destY == curY) { + return true; + } + if (destX == curX && 1 + destY == curY && (0x12c0120 & clipMaskSupplier.getClippingFlag(z, curX, curY)) == 0) { + return true; + } + if (curX == destX && curY == destY - 1 && (clipMaskSupplier.getClippingFlag(z, curX, curY) & 0x12c0102) == 0) { + return true; + } + } else if (rotation == 3) { + if (curX == destX && -1 + destY == curY) { + return true; + } + if (curX == -1 + destX && destY == curY && (0x12c0108 & clipMaskSupplier.getClippingFlag(z, curX, curY)) == 0) { + return true; + } + if (curX == 1 + destX && destY == curY && (clipMaskSupplier.getClippingFlag(z, curX, curY) & 0x12c0180) == 0) { + return true; + } + } + } else if (type == 2) { + if (rotation == 0) { + if (destX - 1 == curX && curY == destY) { + return true; + } + if (destX == curX && curY == 1 + destY) { + return true; + } + if (curX == destX + 1 && curY == destY && (0x12c0180 & clipMaskSupplier.getClippingFlag(z, curX, curY)) == 0) { + return true; + } + if (curX == destX && destY - 1 == curY && (clipMaskSupplier.getClippingFlag(z, curX, curY) & 0x12c0102) == 0) { + return true; + } + } else if (rotation == 1) { + if (curX == destX - 1 && curY == destY && (0x12c0108 & clipMaskSupplier.getClippingFlag(z, curX, curY)) == 0) { + return true; + } + if (curX == destX && curY == 1 + destY) { + return true; + } + if (1 + destX == curX && curY == destY) { + return true; + } + if (curX == destX && destY - 1 == curY && (clipMaskSupplier.getClippingFlag(z, curX, curY) & 0x12c0102) == 0) { + return true; + } + } else if (rotation == 2) { + if (destX - 1 == curX && destY == curY && (0x12c0108 & clipMaskSupplier.getClippingFlag(z, curX, curY)) == 0) { + return true; + } + if (destX == curX && 1 + destY == curY && (0x12c0120 & clipMaskSupplier.getClippingFlag(z, curX, curY)) == 0) { + return true; + } + if (1 + destX == curX && curY == destY) { + return true; + } + if (curX == destX && curY == destY - 1) { + return true; + } + } else if (rotation == 3) { + if (destX - 1 == curX && curY == destY) { + return true; + } + if (destX == curX && curY == destY + 1 && (0x12c0120 & clipMaskSupplier.getClippingFlag(z, curX, curY)) == 0) { + return true; + } + if (curX == 1 + destX && curY == destY && (clipMaskSupplier.getClippingFlag(z, curX, curY) & 0x12c0180) == 0) { + return true; + } + if (destX == curX && destY - 1 == curY) { + return true; + } + } + } else if (type == 9) { + if (curX == destX && curY == destY + 1 && (clipMaskSupplier.getClippingFlag(z, curX, curY) & 0x20) == 0) { + return true; + } + if (curX == destX && curY == destY - 1 && (clipMaskSupplier.getClippingFlag(z, curX, curY) & 0x2) == 0) { + return true; + } + if (curX == destX - 1 && curY == destY && (0x8 & clipMaskSupplier.getClippingFlag(z, curX, curY)) == 0) { + return true; + } + if (destX + 1 == curX && curY == destY && (0x80 & clipMaskSupplier.getClippingFlag(z, curX, curY)) == 0) { + return true; + } + } + } else { + int cornerX = curX - (1 - size); + int cornerY = -1 + curY + size; + if (type == 0) { + if (rotation == 0) { + if (destX - size == curX && destY >= curY && destY <= cornerY) { + return true; + } + if (destX >= curX && cornerX >= destX && curY == 1 + destY && (clipMaskSupplier.getClippingFlag(z, destX, curY) & 0x12c0120) == 0) { + return true; + } + if (destX >= curX && cornerX >= destX && destY - size == curY && (clipMaskSupplier.getClippingFlag(z, destX, cornerY) & 0x12c0102) == 0) { + return true; + } + } else if (rotation == 1) { + if (destX >= curX && cornerX >= destX && destY + 1 == curY) { + return true; + } + if (curX == -size + destX && destY >= curY && cornerY >= destY && (0x12c0108 & clipMaskSupplier.getClippingFlag(z, cornerX, destY)) == 0) { + return true; + } + if (curX == 1 + destX && destY >= curY && cornerY >= destY && (clipMaskSupplier.getClippingFlag(z, curX, destY) & 0x12c0180) == 0) { + return true; + } + } else if (rotation == 2) { + if (curX == 1 + destX && curY <= destY && destY <= cornerY) { + return true; + } + if (curX <= destX && cornerX >= destX && destY + 1 == curY && (0x12c0120 & clipMaskSupplier.getClippingFlag(z, destX, curY)) == 0) { + return true; + } + if (destX >= curX && destX <= cornerX && destY - size == curY && (0x12c0102 & clipMaskSupplier.getClippingFlag(z, destX, cornerY)) == 0) { + return true; + } + } else if (rotation == 3) { + if (curX <= destX && destX <= cornerX && curY == -size + destY) { + return true; + } + if (-size + destX == curX && curY <= destY && destY <= cornerY && (clipMaskSupplier.getClippingFlag(z, cornerX, destY) & 0x12c0108) == 0) { + return true; + } + if (1 + destX == curX && curY <= destY && cornerY >= destY && (clipMaskSupplier.getClippingFlag(z, curX, destY) & 0x12c0180) == 0) { + return true; + } + } + } + if (type == 2) { + if (rotation == 0) { + if (destX - size == curX && curY <= destY && destY <= cornerY) { + return true; + } + if (curX <= destX && destX <= cornerX && curY == 1 + destY) { + return true; + } + if (curX == 1 + destX && curY <= destY && destY <= cornerY && (0x12c0180 & clipMaskSupplier.getClippingFlag(z, curX, destY)) == 0) { + return true; + } + if (curX <= destX && cornerX >= destX && -size + destY == curY && (clipMaskSupplier.getClippingFlag(z, destX, cornerY) & 0x12c0102) == 0) { + return true; + } + } else if (rotation == 1) { + if (-size + destX == curX && destY >= curY && destY <= cornerY && (clipMaskSupplier.getClippingFlag(z, cornerX, destY) & 0x12c0108) == 0) { + return true; + } + if (destX >= curX && cornerX >= destX && curY == 1 + destY) { + return true; + } + if (destX + 1 == curX && curY <= destY && destY <= cornerY) { + return true; + } + if (destX >= curX && cornerX >= destX && destY + -size == curY && (0x12c0102 & clipMaskSupplier.getClippingFlag(z, destX, cornerY)) == 0) { + return true; + } + } else if (rotation == 2) { + if (curX == destX - size && curY <= destY && cornerY >= destY && (clipMaskSupplier.getClippingFlag(z, cornerX, destY) & 0x12c0108) == 0) { + return true; + } + if (destX >= curX && destX <= cornerX && 1 + destY == curY && (0x12c0120 & clipMaskSupplier.getClippingFlag(z, destX, curY)) == 0) { + return true; + } + if (1 + destX == curX && destY >= curY && cornerY >= destY) { + return true; + } + if (curX <= destX && destX <= cornerX && curY == -size + destY) { + return true; + } + } else if (rotation == 3) { + if (destX + -size == curX && destY >= curY && destY <= cornerY) { + return true; + } + if (curX <= destX && cornerX >= destX && curY == 1 + destY && (clipMaskSupplier.getClippingFlag(z, destX, curY) & 0x12c0120) == 0) { + return true; + } + if (1 + destX == curX && destY >= curY && cornerY >= destY && (0x12c0180 & clipMaskSupplier.getClippingFlag(z, curX, destY)) == 0) { + return true; + } + if (destX >= curX && destX <= cornerX && curY == -size + destY) { + return true; + } + } + } + if (type == 9) { + if (destX >= curX && destX <= cornerX && curY == 1 + destY && (clipMaskSupplier.getClippingFlag(z, destX, curY) & 0x12c0120) == 0) { + return true; + } + if (destX >= curX && cornerX >= destX && curY == -size + destY && (0x12c0102 & clipMaskSupplier.getClippingFlag(z, destX, cornerY)) == 0) { + return true; + } + if (-size + destX == curX && destY >= curY && cornerY >= destY && (0x12c0108 & clipMaskSupplier.getClippingFlag(z, cornerX, destY)) == 0) { + return true; + } + if (curX == destX + 1 && destY >= curY && cornerY >= destY && (clipMaskSupplier.getClippingFlag(z, curX, destY) & 0x12c0180) == 0) { + return true; + } + } + } + return false; + } + + /** + * Checks if the mover is standing on the destination. + * @param x The current x-location (in viewport). + * @param y The current y-location (in viewport). + * @param moverSizeX The mover x size. + * @param moverSizeY The mover y size. + * @param destX The destination x-location in viewport. + * @param destY The destination y-location in viewport. + * @param sizeX The destination node x-size. + * @param sizeY The destination node y-size. + * @return {@code True} if so. + */ + public static boolean isStandingIn(int x, int y, int moverSizeX, int moverSizeY, int destX, int destY, int sizeX, int sizeY) { + if (x >= sizeX + destX || moverSizeX + x <= destX) { + return false; + } + if (destY + sizeY <= y || y + moverSizeY <= destY) { + return false; + } + return true; + } + + /** + * Checks if interaction is possible from the current location. + * @param x The current x-location (in viewport). + * @param y The current y-location (in viewport). + * @param moverSize The mover size. + * @param destX The destination x-location in viewport. + * @param destY The destination y-location in viewport. + * @param sizeX The destination node x-size. + * @param sizeY The destination node y-size. + * @param walkFlag The walking flag. + * @return {@code True} if so. + */ + public static boolean canInteract(int x, int y, int moverSize, int destX, int destY, int sizeX, int sizeY, int walkFlag, int z, ClipMaskSupplier clipMaskSupplier) { + if (moverSize > 1) { + return isStandingIn(x, y, moverSize, moverSize, destX, destY, sizeX, sizeY) || canInteractSized(x, y, moverSize, moverSize, destX, destY, sizeX, sizeY, walkFlag, z); + } + int flag = clipMaskSupplier.getClippingFlag(z, x, y); + int cornerX = destX + sizeX - 1; + int cornerY = destY + sizeY - 1; + if (destX <= x && cornerX >= x && y >= destY && y <= cornerY) { + return true; + } + if (x == destX - 1 && destY <= y && y <= cornerY && (0x8 & flag) == 0 && (0x8 & walkFlag) == 0) { + return true; + } + if (x == cornerX + 1 && destY <= y && cornerY >= y && (flag & 0x80) == 0 && (0x2 & walkFlag) == 0) { + return true; + } + if (y == destY - 1 && destX <= x && cornerX >= x && (0x2 & flag) == 0 && (0x4 & walkFlag) == 0) { + return true; + } + if (y == cornerY + 1 && destX <= x && cornerX >= x && (flag & 0x20) == 0 && (0x1 & walkFlag) == 0) { + return true; + } + return false; + } + + /** + * Checks if interaction is possible from the current location. + * @param destX The destination x-location in viewport. + * @param destY The destination y-location in viewport. + * @param sizeX The destination node x-size. + * @param sizeY The destination node y-size. + * @return {@code True} if so. + */ + public static boolean canInteractSized(int curX, int curY, int moverSizeX, int moverSizeY, int destX, int destY, int sizeX, int sizeY, int walkingFlag, int z) { + int fromCornerY = curY + moverSizeY; + int fromCornerX = curX + moverSizeX; + int toCornerX = sizeX + destX; + int toCornerY = sizeY + destY; + if (destX <= curX && curX < toCornerX) { + if (destY == fromCornerY && (walkingFlag & 0x4) == 0) { + int x = curX; + for (int endX = toCornerX < fromCornerX ? toCornerX : fromCornerX; endX > x; x++) { + if ((RegionManager.getClippingFlag(z, x, -1 + fromCornerY) & 0x2) == 0) { + return true; + } + } + } else if (toCornerY == curY && (walkingFlag & 0x1) == 0) { + int x = curX; + for (int endX = fromCornerX <= toCornerX ? fromCornerX : toCornerX; x < endX; x++) { + if ((RegionManager.getClippingFlag(z, x, curY) & 0x20) == 0) { + return true; + } + } + } + } else if (destX < fromCornerX && toCornerX >= fromCornerX) { + if (fromCornerY == destY && (0x4 & walkingFlag) == 0) { + for (int x = destX; fromCornerX > x; x++) { + if ((RegionManager.getClippingFlag(z, x, -1 + (fromCornerY)) & 0x2) == 0) { + return true; + } + } + } else if (toCornerY == curY && (0x1 & walkingFlag) == 0) { + for (int x = destX; fromCornerX > x; x++) { + if ((RegionManager.getClippingFlag(z, x, curY) & 0x20) == 0) { + return true; + } + } + } + } else if (curY < destY || curY >= toCornerY) { + if (fromCornerY > destY && toCornerY >= fromCornerY) { + if (fromCornerX == destX && (walkingFlag & 0x8) == 0) { + for (int y = destY; y < fromCornerY; y++) { + if ((RegionManager.getClippingFlag(z, -1 + fromCornerX, y) & 0x8) == 0) { + return true; + } + } + } else if (curX == toCornerX && (0x2 & walkingFlag) == 0) { + for (int y = destY; fromCornerY > y; y++) { + if ((RegionManager.getClippingFlag(z, curX, y) & 0x80) == 0) { + return true; + } + } + } + } + } else if (destX != fromCornerX || (0x8 & walkingFlag) != 0) { + if (curX == toCornerX && (walkingFlag & 0x2) == 0) { + int y = curY; + for (int endY = fromCornerY <= toCornerY ? fromCornerY : toCornerY; y < endY; y++) { + if ((0x80 & RegionManager.getClippingFlag(z, curX, y)) == 0) { + return true; + } + } + } + } else { + int y = curY; + for (int endY = fromCornerY > toCornerY ? toCornerY : fromCornerY; endY > y; y++) { + if ((RegionManager.getClippingFlag(z, fromCornerX - 1, y) & 0x8) == 0) { + return true; + } + } + } + return false; + } +} diff --git a/Server/src/main/core/game/world/map/path/ProjectilePathfinder.java b/Server/src/main/core/game/world/map/path/ProjectilePathfinder.java new file mode 100644 index 0000000..d20b96c --- /dev/null +++ b/Server/src/main/core/game/world/map/path/ProjectilePathfinder.java @@ -0,0 +1,200 @@ +package core.game.world.map.path; + +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.Point; +import core.game.world.map.RegionManager; + +import java.util.ArrayList; +import java.util.List; + +/** + * A pathfinder implementation used for checking projectile paths. + * @author Emperor + */ +public final class ProjectilePathfinder extends Pathfinder { + + /** + * If a path can be found. + */ + private boolean found; + + /** + * The plane. + */ + private int z; + + /** + * The x-coordinate. + */ + private int x; + + /** + * The y-coordinate. + */ + private int y; + + @Override + public Path find(Location start, int size, Location end, int sizeX, int sizeY, int rotation, int type, int walkingFlag, boolean near, ClipMaskSupplier clipMaskSupplier) { + Path path = new Path(); + z = start.getZ(); + x = start.getX(); + y = start.getY(); + List points = new ArrayList<>(20); + path.setSuccesful(true); + while (x != end.getX() || y != end.getY()) { + Direction[] directions = getDirection(x, y, end); + found = true; + checkSingleTraversal(points, directions); + if (!found) { + path.setMoveNear(x != start.getX() || y != start.getY()); + path.setSuccesful(false); + break; + } + } + if (!points.isEmpty()) { + for (int i = 0; i < points.size() - 1; i++) { + Point p = points.get(i); + if (p.getDirection() != null) { + path.getPoints().add(p); + } + } + path.getPoints().add(points.get(points.size() - 1)); + } + return path; + } + + /** + * Checks traversal for a size 1 entity. + * + * @param points The points list. + * @param directions The directions. + */ + private void checkSingleTraversal(List points, Direction... directions) { + dir: + for (Direction dir : directions) { + found = true; + switch (dir) { + case NORTH: + if (flagged(z, x, y + 1, 0x12c0120)) { + found = false; + break dir; + } + points.add(new Point(x, y + 1, dir)); + y++; + break; + case NORTH_EAST: + if (flagged(z, x + 1, y, 0x12c0180) + || flagged(z, x, y + 1, 0x12c0120) + || flagged(z, x + 1, y + 1, 0x12c01e0)) { + found = false; + break dir; + } + points.add(new Point(x + 1, y + 1, dir)); + x++; + y++; + break; + case EAST: + if (flagged(z, x + 1, y, 0x12c0180)) { + found = false; + break dir; + } + points.add(new Point(x + 1, y, dir)); + x++; + break; + case SOUTH_EAST: + if (flagged(z, x + 1, y, 0x12c0180) + || flagged(z, x, y - 1, 0x12c0102) + || flagged(z, x + 1, y - 1, 0x12c0183)) { + found = false; + break dir; + } + points.add(new Point(x + 1, y - 1, dir)); + x++; + y--; + break; + case SOUTH: + if (flagged(z, x, y - 1, 0x12c0102)) { + found = false; + break dir; + } + points.add(new Point(x, y - 1, dir)); + y--; + break; + case SOUTH_WEST: + if (flagged(z, x - 1, y, 0x12c0108) + || flagged(z, x, y - 1, 0x12c0102) + || flagged(z, x - 1, y - 1, 0x12c010e)) { + found = false; + break dir; + } + points.add(new Point(x - 1, y - 1, dir)); + x--; + y--; + break; + case WEST: + if (flagged(z, x - 1, y, 0x12c0108)) { + found = false; + break dir; + } + points.add(new Point(x - 1, y, dir)); + x--; + break; + case NORTH_WEST: + if (flagged(z, x - 1, y, 0x12c0108) + || flagged(z, x, y + 1, 0x12c0120) + || flagged(z, x - 1, y + 1, 0x12c0138)) { + found = false; + break dir; + } + points.add(new Point(x - 1, y + 1, dir)); + x--; + y++; + break; + } + if (found) { + break; + } + } + } + + private static boolean flagged(int z, int x, int y, int pFlagMask) { + int pFlag = RegionManager.getProjectileFlag(z, x, y); + return (pFlag & pFlagMask) != 0 || (pFlag & 0x20000) != 0 || (RegionManager.getClippingFlag(z, x, y) & 0x20000) != 0; + } + + /** + * Gets the direction. + * @param startX The startX. + * @param startY The startY. + * @param end The end direction. + * @return The direction. + */ + private static Direction[] getDirection(int startX, int startY, Location end) { + int endX = end.getX(); + int endY = end.getY(); + if (startX == endX) { + if (startY > endY) { + return new Direction[] { Direction.SOUTH }; + } else if (startY < endY) { + return new Direction[] { Direction.NORTH }; + } + } else if (startY == endY) { + if (startX > endX) { + return new Direction[] { Direction.WEST }; + } + return new Direction[] { Direction.EAST }; + } else { + if (startX < endX && startY < endY) { + return new Direction[] { Direction.NORTH_EAST, Direction.EAST, Direction.NORTH }; + } else if (startX < endX && startY > endY) { + return new Direction[] { Direction.SOUTH_EAST, Direction.EAST, Direction.SOUTH }; + } else if (startX > endX && startY < endY) { + return new Direction[] { Direction.NORTH_WEST, Direction.WEST, Direction.NORTH }; + } else if (startX > endX && startY > endY) { + return new Direction[] { Direction.SOUTH_WEST, Direction.WEST, Direction.SOUTH }; + } + } + return new Direction[0]; + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/world/map/path/SmartPathfinder.kt b/Server/src/main/core/game/world/map/path/SmartPathfinder.kt new file mode 100644 index 0000000..2dcae4a --- /dev/null +++ b/Server/src/main/core/game/world/map/path/SmartPathfinder.kt @@ -0,0 +1,591 @@ +package core.game.world.map.path + +import core.game.world.GameWorld +import core.game.world.map.Direction +import core.game.world.map.Location +import core.game.world.map.Point +import core.tools.* +import core.api.* +import core.api.utils.Vector +import core.ServerConstants + +import java.util.Comparator +import java.util.PriorityQueue + +import java.io.* +import javax.imageio.ImageIO +import java.awt.image.BufferedImage + +class SmartPathfinder +/** + * Constructs a new `SmartPathfinder` `Object`. + */ +internal constructor() : Pathfinder() { + /** + * The x-queue. + */ + private var queueX: IntArray = intArrayOf(0) + + /** + * The y-queue. + */ + private var queueY: IntArray = intArrayOf(0) + + /** + * The "via" array. + */ + private var via: Array = Array(104) { IntArray(104) } + + /** + * The cost array. + */ + private var cost: Array = Array(104) { IntArray(104) } + + /** + * The current writing position. + */ + private var writePathPosition = 0 + + /** + * The current x-coordinate. + */ + private var curX = 0 + + /** + * The current y-coordinate. + */ + private var curY = 0 + + /** + * The destination x-coordinate. + */ + private var dstX = 0 + + /** + * The destination y-coordinate. + */ + private var dstY = 0 + + /** + * If a path was found. + */ + private var foundPath = false + + /** + * Resets the pathfinder. + */ + fun reset() { + queueX = IntArray(4096) + queueY = IntArray(4096) + via = Array(104) { IntArray(104) } + cost = Array(104) { IntArray(104) } + writePathPosition = 0 + } + + /** + * Checks a tile. + * @param x The x-coordinate. + * @param y The y-coordinate. + * @param dir The direction. + * @param currentCost The current cost. + */ + fun check(x: Int, y: Int, dir: Int, currentCost: Int, diagonalPenalty: Int = 0) { + if(cost[x][y] > currentCost + diagonalPenalty) { + queueX[writePathPosition] = x + queueY[writePathPosition] = y + via[x][y] = dir + cost[x][y] = currentCost + diagonalPenalty + writePathPosition = writePathPosition + 1 and 0xfff + } + } + + override fun find(start: Location?, moverSize: Int, dest: Location?, sizeX: Int, sizeY: Int, rotation: Int, type: Int, walkingFlag: Int, near: Boolean, clipMaskSupplier: ClipMaskSupplier?): Path { + reset() + assert(start != null && dest != null) + var vec = Vector.betweenLocs(start!!, dest!!) + var mag = kotlin.math.floor(vec.magnitude()) + var end = dest!! + if (mag > ServerConstants.MAX_PATHFIND_DISTANCE) { + try { + if (mag < 50.0) { //truncate the path if it's realistically long + vec = vec.normalized() * (ServerConstants.MAX_PATHFIND_DISTANCE - 1) + end = start!!.transform(vec) + } else throw Exception("Pathfinding distance exceeds server max! -> " + mag.toString() + " {" + start + "->" + end + "}") + } catch (e: Exception) { + val sw = StringWriter() + val pw = PrintWriter(sw) + e.printStackTrace(pw) + log(this::class.java, Log.FINE, sw.toString()) + val p = Path() + p.isMoveNear = true + return p + } + } + val path = Path() + foundPath = false + for (x in 0..103) { + for (y in 0..103) { + via[x][y] = 0 + cost[x][y] = 99999999 + } + } + val z = start!!.z + val location = Location.create(start.regionX - 6 shl 3, start.regionY - 6 shl 3, z) + curX = start.sceneX + curY = start.sceneY + dstX = end!!.getSceneX(start) + dstY = end.getSceneY(start) + var attempts: Int + var readPosition: Int + check(curX, curY, 99, 0) + try { + if (moverSize < 2) { + if(GameWorld.settings?.smartpathfinder_bfs ?: false) { + checkSingleTraversal(end, sizeX, sizeY, type, rotation, walkingFlag, location, clipMaskSupplier!!) + } else { + checkSingleTraversalAstar(end, sizeX, sizeY, type, rotation, walkingFlag, location, clipMaskSupplier!!) + } + } else if (moverSize == 2) { + checkDoubleTraversal(end, sizeX, sizeY, type, rotation, walkingFlag, location, clipMaskSupplier!!) + } else { + checkVariableTraversal(end, moverSize, sizeX, sizeY, type, rotation, walkingFlag, location, clipMaskSupplier!!) + } + } catch (e: Exception) {} + var debugImg = if(false) { BufferedImage(4*104+2, 104, BufferedImage.TYPE_INT_RGB) } else { null } + if(debugImg != null) { + for(y in 0 until 104) { + for(x in 0 until 104) { + debugImg.setRGB(x, 103-y, via[x][y] * (((1 shl 24)-1)/12)) + val c = Math.min(4*Math.min(cost[x][y], 64), 255) + debugImg.setRGB(105+x, 103-y, (c shl 16) or (c shl 8) or c) + debugImg.setRGB(2*105+x, 103-y, clipMaskSupplier!!.getClippingFlag(location.z, location.x + x, location.y + y)) + } + } + } + + if (!foundPath) { + if (near) { + var fullCost = 1000 + var thisCost = 100 + val depth = 10 + for (x in dstX - depth..dstX + depth) { + for (y in dstY - depth..dstY + depth) { + if (x >= 0 && y >= 0 && x < 104 && y < 104 && cost[x][y] < 100) { + var diffX = 0 + if (x < dstX) { + diffX = dstX - x + } else if (x > dstX + sizeX - 1) { + diffX = x - (dstX + sizeX - 1) + } + var diffY = 0 + if (y < dstY) { + diffY = dstY - y + } else if (y > dstY + sizeY - 1) { + diffY = y - (dstY + sizeY - 1) + } + val totalCost = diffX * diffX + diffY * diffY + if (totalCost < fullCost || totalCost == fullCost && cost[x][y] < thisCost) { + fullCost = totalCost + thisCost = cost[x][y] + curX = x + curY = y + } + } + } + } + if (fullCost == 1000) { + return path + } + path.isMoveNear = true + } + } + readPosition = 0 + queueX[readPosition] = curX + queueY[readPosition++] = curY + var previousDirection: Int + attempts = 0 + var directionFlag = via[curX][curY].also { previousDirection = it } + while (curX != start.sceneX || curY != start.sceneY) { + if (++attempts > queueX.size) { + return path + } + previousDirection = directionFlag + queueX[readPosition] = curX + queueY[readPosition++] = curY + if (directionFlag and WEST_FLAG != 0) { + curX++ + } else if (directionFlag and EAST_FLAG != 0) { + curX-- + } + if (directionFlag and SOUTH_FLAG != 0) { + curY++ + } else if (directionFlag and NORTH_FLAG != 0) { + curY-- + } + if(debugImg != null) { + debugImg.setRGB(3*105+curX, 103-curY, 0x0000ff) + } + directionFlag = via[curX][curY] + } + if(debugImg != null) { + debugImg.setRGB(3*105+start.sceneX, 103-start.sceneY, 0xff0000) + debugImg.setRGB(3*105+dstX, 103-dstY, 0x00ff00) + if(GameWorld.settings?.smartpathfinder_bfs ?: false) { + ImageIO.write(debugImg, "png", File(String.format("bfs_%04d_%04d_%04d_%04d.png", start.x, start.y, end.x, end.y))) + } else { + ImageIO.write(debugImg, "png", File(String.format("astar_%04d_%04d_%04d_%04d.png", start.x, start.y, end.x, end.y))) + } + } + val size = readPosition-- + var absX = location.x + queueX[readPosition] + var absY = location.y + queueY[readPosition] + path.points.add(Point(absX, absY)) + for (i in 1 until size) { + readPosition-- + absX = location.x + queueX[readPosition] + absY = location.y + queueY[readPosition] + path.points.add(Point(absX, absY)) + } + path.setSuccesful(true) + if (end != dest) + path.isMoveNear = true + return path + } + + class UIntAsPointComparator(val end: Location) : Comparator { + override fun compare(p: UInt, q: UInt): Int { + val pc: UInt = (p and 0x00ff0000u) shr 16 + val px: UInt = (p and 0x0000ff00u) shr 8 + val py: UInt = (p and 0x000000ffu) + val qc: UInt = (q and 0x00ff0000u) shr 16 + val qx: UInt = (q and 0x0000ff00u) shr 8 + val qy: UInt = (q and 0x000000ffu) + //val dp = pc.toInt() + Math.abs(end.sceneX - (px.toInt())) + Math.abs(end.sceneY - (py.toInt())) + //val dq = qc.toInt() + Math.abs(end.sceneX - (qx.toInt())) + Math.abs(end.sceneY - (qy.toInt())) + val dp = pc.toDouble() + Math.max(Math.abs(end.sceneX - px.toInt()), Math.abs(end.sceneY - py.toInt())).toDouble() + val dq = qc.toDouble() + Math.max(Math.abs(end.sceneX - qx.toInt()), Math.abs(end.sceneY - qy.toInt())).toDouble() + if(dp < dq) { + return -1 + } else if(dq < dp) { + return 1 + } else { + return 0 + } + } + override fun equals(other: Any?): Boolean { + if(other is UIntAsPointComparator) { + return end == other.end + } else { + return false + } + } + override fun hashCode(): Int { + return end.hashCode() + } + } + + private fun checkSingleTraversalAstar(end: Location, sizeX: Int, sizeY: Int, type: Int, rotation: Int, walkingFlag: Int, location: Location, clipMaskSupplier: ClipMaskSupplier) { + val z = location.z + var queue = PriorityQueue(4096, UIntAsPointComparator(end)) + queue.add(((curX.toUInt()) shl 8) or (curY.toUInt())) + while(!foundPath && !queue.isEmpty()) { + val point = queue.poll() + val curCost = ((point and 0xff0000u) shr 16).toInt() + curX = ((point and 0x0000ff00u) shr 8).toInt() + curY = (point and 0x000000ffu).toInt() + val absX = location.x + curX + val absY = location.y + curY + if (curX == dstX && curY == dstY) { + foundPath = true + break + } + if (type != 0) { + if ((type < 5 || type == 10) && canDoorInteract(absX, absY, 1, end.x, end.y, type - 1, rotation, z, clipMaskSupplier)) { + foundPath = true + break + } + if (type < 10 && canDecorationInteract(absX, absY, 1, end.x, end.y, type - 1, rotation, z, clipMaskSupplier)) { + foundPath = true + break + } + } + if (sizeX != 0 && sizeY != 0 && canInteract(absX, absY, 1, end.x, end.y, sizeX, sizeY, walkingFlag, z, clipMaskSupplier)) { + foundPath = true + break + } + val newCost = curCost + 1 + //val orthogonalsFirst = arrayOf(Direction.EAST, Direction.NORTH, Direction.WEST, Direction.SOUTH, Direction.NORTH_EAST, Direction.NORTH_WEST, Direction.SOUTH_WEST, Direction.SOUTH_EAST) + val orthogonalsFirst = arrayOf(Direction.SOUTH, Direction.WEST, Direction.NORTH, Direction.EAST, Direction.SOUTH_WEST, Direction.NORTH_WEST, Direction.SOUTH_EAST, Direction.NORTH_EAST) + //val orthogonalsFirst = arrayOf(Direction.SOUTH, Direction.WEST, Direction.NORTH, Direction.EAST) + //for(dir in Direction.values()) { + for(dir in orthogonalsFirst) { + val newSceneX: Int = curX + dir.stepX + val newSceneY: Int = curY + dir.stepY + if(0 <= newSceneX && newSceneX < 104 && 0 <= newSceneY && newSceneY < 104 && via[newSceneX][newSceneY] == 0) { + if(dir.canMoveFrom(z, absX, absY, clipMaskSupplier)) { + val diagonalPenalty = Math.abs(dir.stepX) + Math.abs(dir.stepY) - 1 + val flag = flagForDirection(dir) + check(newSceneX, newSceneY, flag, newCost, diagonalPenalty) + if(via[newSceneX][newSceneY] == flag) { + queue.add(((newCost + diagonalPenalty).toUInt() shl 16) or (newSceneX.toUInt() shl 8) or newSceneY.toUInt()) + } + } + } + } + } + } + + /** + * Checks possible traversal for a size 1 entity. + * @param end The destination location. + * @param sizeX The x-size of the destination. + * @param sizeY The y-size of the destination. + * @param type The object type. + * @param rotation The object rotation. + * @param walkingFlag The walking flag. + * @param location The viewport location. + */ + private fun checkSingleTraversal(end: Location, sizeX: Int, sizeY: Int, type: Int, rotation: Int, walkingFlag: Int, location: Location, clipMaskSupplier: ClipMaskSupplier) { + var readPosition = 0 + val z = location.z + while (writePathPosition != readPosition) { + curX = queueX[readPosition] + curY = queueY[readPosition] + readPosition = readPosition + 1 and 0xfff + if (curX == dstX && curY == dstY) { + foundPath = true + break + } + try { + val absX = location.x + curX + val absY = location.y + curY + if (type != 0) { + if ((type < 5 || type == 10) && canDoorInteract(absX, absY, 1, end.x, end.y, type - 1, rotation, z, clipMaskSupplier)) { + foundPath = true + break + } + if (type < 10 && canDecorationInteract(absX, absY, 1, end.x, end.y, type - 1, rotation, z, clipMaskSupplier)) { + foundPath = true + break + } + } + if (sizeX != 0 && sizeY != 0 && canInteract(absX, absY, 1, end.x, end.y, sizeX, sizeY, walkingFlag, z, clipMaskSupplier)) { + foundPath = true + break + } + val thisCost = cost[curX][curY] + 1 + if (curY > 0 && via[curX][curY - 1] == 0 && clipMaskSupplier.getClippingFlag(z, absX, absY - 1) and 0x12c0102 == 0) { + check(curX, curY - 1, SOUTH_FLAG, thisCost) + } + if (curX > 0 && via[curX - 1][curY] == 0 && clipMaskSupplier.getClippingFlag(z, absX - 1, absY) and 0x12c0108 == 0) { + check(curX - 1, curY, WEST_FLAG, thisCost) + } + if (curY < 103 && via[curX][curY + 1] == 0 && clipMaskSupplier.getClippingFlag(z, absX, absY + 1) and 0x12c0120 == 0) { + check(curX, curY + 1, NORTH_FLAG, thisCost) + } + if (curX < 103 && via[curX + 1][curY] == 0 && clipMaskSupplier.getClippingFlag(z, absX + 1, absY) and 0x12c0180 == 0) { + check(curX + 1, curY, EAST_FLAG, thisCost) + } + if (curX > 0 && curY > 0 && via[curX - 1][curY - 1] == 0 && clipMaskSupplier.getClippingFlag(z, absX - 1, absY - 1) and 0x12c010e == 0 && clipMaskSupplier.getClippingFlag(z, absX - 1, absY) and 0x12c0108 == 0 && clipMaskSupplier.getClippingFlag(z, absX, absY - 1) and 0x12c0102 == 0) { + check(curX - 1, curY - 1, SOUTH_WEST_FLAG, thisCost) + } + if (curX > 0 && curY < 103 && via[curX - 1][curY + 1] == 0 && clipMaskSupplier.getClippingFlag(z, absX - 1, absY + 1) and 0x12c0138 == 0 && clipMaskSupplier.getClippingFlag(z, absX - 1, absY) and 0x12c0108 == 0 && clipMaskSupplier.getClippingFlag(z, absX, absY + 1) and 0x12c0120 == 0) { + check(curX - 1, curY + 1, NORTH_WEST_FLAG, thisCost) + } + if (curX < 103 && curY > 0 && via[curX + 1][curY - 1] == 0 && clipMaskSupplier.getClippingFlag(z, absX + 1, absY - 1) and 0x12c0183 == 0 && clipMaskSupplier.getClippingFlag(z, absX + 1, absY) and 0x12c0180 == 0 && clipMaskSupplier.getClippingFlag(z, absX, absY - 1) and 0x12c0102 == 0) { + check(curX + 1, curY - 1, SOUTH_EAST_FLAG, thisCost) + } + if (curX < 103 && curY < 103 && via[curX + 1][curY + 1] == 0 && clipMaskSupplier.getClippingFlag(z, absX + 1, absY + 1) and 0x12c01e0 == 0 && clipMaskSupplier.getClippingFlag(z, absX + 1, absY) and 0x12c0180 == 0 && clipMaskSupplier.getClippingFlag(z, absX, absY + 1) and 0x12c0120 == 0) { + check(curX + 1, curY + 1, NORTH_EAST_FLAG, thisCost) + } + } catch (e: Exception) { + // e.printStackTrace()println("curX " + curX + " curY" + curY + " via " + via[curX + 1] + via[curY + 1]) + } + } + } + + /** + * Checks possible traversal for a size 2 entity. + * @param end The destination location. + * @param sizeX The x-size of the destination. + * @param sizeY The y-size of the destination. + * @param type The object type. + * @param rotation The object rotation. + * @param walkingFlag The walking flag. + * @param location The viewport location. + */ + private fun checkDoubleTraversal(end: Location, sizeX: Int, sizeY: Int, type: Int, rotation: Int, walkingFlag: Int, location: Location, clipMaskSupplier: ClipMaskSupplier) { + var readPosition = 0 + val z = location.z + while (writePathPosition != readPosition) { + curX = queueX[readPosition] + curY = queueY[readPosition] + readPosition = readPosition + 1 and 0xfff + if (curX == dstX && curY == dstY) { + foundPath = true + break + } + val absX = location.x + curX + val absY = location.y + curY + if (type != 0) { + if ((type < 5 || type == 10) && canDoorInteract(absX, absY, 2, end.x, end.y, type - 1, rotation, z, clipMaskSupplier)) { + foundPath = true + break + } + if (type < 10 && canDecorationInteract(absX, absY, 2, end.x, end.y, type - 1, rotation, z, clipMaskSupplier)) { + foundPath = true + break + } + } + if (sizeX != 0 && sizeY != 0 && canInteract(absX, absY, 2, end.x, end.y, sizeX, sizeY, walkingFlag, z, clipMaskSupplier)) { + foundPath = true + break + } + val thisCost = cost[curX][curY] + 1 + if (curY > 0 && via[curX][curY - 1] == 0 && clipMaskSupplier.getClippingFlag(z, absX, absY - 1) and 0x12c010e == 0 && clipMaskSupplier.getClippingFlag(z, absX + 1, absY - 1) and 0x12c0183 == 0) { + check(curX, curY - 1, SOUTH_FLAG, thisCost) + } + if (curX > 0 && via[curX - 1][curY] == 0 && clipMaskSupplier.getClippingFlag(z, absX - 1, absY) and 0x12c010e == 0 && clipMaskSupplier.getClippingFlag(z, absX - 1, absY + 1) and 0x12c0138 == 0) { + check(curX - 1, curY, WEST_FLAG, thisCost) + } + if (curY < 102 && via[curX][curY + 1] == 0 && clipMaskSupplier.getClippingFlag(z, absX, absY + 2) and 0x12c0138 == 0 && clipMaskSupplier.getClippingFlag(z, absX + 1, absY + 2) and 0x12c01e0 == 0) { + check(curX, curY + 1, NORTH_FLAG, thisCost) + } + if (curX < 102 && via[curX + 1][curY] == 0 && clipMaskSupplier.getClippingFlag(z, absX + 2, absY) and 0x12c0183 == 0 && clipMaskSupplier.getClippingFlag(z, absX + 2, absY + 1) and 0x12c01e0 == 0) { + check(curX + 1, curY, EAST_FLAG, thisCost) + } + if (curX > 0 && curY > 0 && via[curX - 1][curY - 1] == 0 && clipMaskSupplier.getClippingFlag(z, absX - 1, absY - 1) and 0x12c010e == 0 && clipMaskSupplier.getClippingFlag(z, absX - 1, absY) and 0x12c0138 == 0 && clipMaskSupplier.getClippingFlag(z, absX, absY - 1) and 0x12c0183 == 0) { + check(curX - 1, curY - 1, SOUTH_WEST_FLAG, thisCost) + } + if (curX > 0 && curY < 102 && via[curX - 1][curY + 1] == 0 && clipMaskSupplier.getClippingFlag(z, absX - 1, absY + 1) and 0x12c010e == 0 && clipMaskSupplier.getClippingFlag(z, absX - 1, absY + 2) and 0x12c0138 == 0 && clipMaskSupplier.getClippingFlag(z, absX, absY + 2) and 0x12c01e0 == 0) { + check(curX - 1, curY + 1, NORTH_WEST_FLAG, thisCost) + } + if (curX < 102 && curY > 0 && via[curX + 1][curY - 1] == 0 && clipMaskSupplier.getClippingFlag(z, absX + 1, absY - 1) and 0x12c010e == 0 && clipMaskSupplier.getClippingFlag(z, absX + 2, absY) and 0x12c01e0 == 0 && clipMaskSupplier.getClippingFlag(z, absX + 2, absY - 1) and 0x12c0183 == 0) { + check(curX + 1, curY - 1, SOUTH_EAST_FLAG, thisCost) + } + if (curX < 102 && curY < 102 && via[curX + 1][curY + 1] == 0 && clipMaskSupplier.getClippingFlag(z, absX + 1, absY + 2) and 0x12c0138 == 0 && clipMaskSupplier.getClippingFlag(z, absX + 2, absY + 2) and 0x12c01e0 == 0 && clipMaskSupplier.getClippingFlag(z, absX + 2, absY + 1) and 0x12c0183 == 0) { + check(curX + 1, curY + 1, NORTH_EAST_FLAG, thisCost) + } + } + } + + /** + * Checks possible traversal for any sized entity. + * @param end The destination location. + * @param size The mover size. + * @param sizeX The x-size of the destination. + * @param sizeY The y-size of the destination. + * @param type The object type. + * @param rotation The object rotation. + * @param walkingFlag The walking flag. + * @param location The viewport location. + */ + private fun checkVariableTraversal(end: Location, size: Int, sizeX: Int, sizeY: Int, type: Int, rotation: Int, walkingFlag: Int, location: Location, clipMaskSupplier: ClipMaskSupplier) { + var readPosition = 0 + val z = location.z + main@ while (writePathPosition != readPosition) { + curX = queueX[readPosition] + curY = queueY[readPosition] + readPosition = readPosition + 1 and 0xfff + if (curX == dstX && curY == dstY) { + foundPath = true + break + } + val absX = location.x + curX + val absY = location.y + curY + if (type != 0) { + if ((type < 5 || type == 10) && canDoorInteract(absX, absY, size, end.x, end.y, type - 1, rotation, z, clipMaskSupplier)) { + foundPath = true + break + } + if (type < 10 && canDecorationInteract(absX, absY, size, end.x, end.y, type - 1, rotation, z, clipMaskSupplier)) { + foundPath = true + break + } + } + if (sizeX != 0 && sizeY != 0 && canInteract(absX, absY, size, end.x, end.y, sizeX, sizeY, walkingFlag, z, clipMaskSupplier)) { + foundPath = true + break + } + val thisCost = cost[curX][curY] + 1 + south@ do { + if (curY > 0 && via[curX][curY - 1] == 0 && clipMaskSupplier.getClippingFlag(z, absX, absY - 1) and 0x12c010e == 0 && clipMaskSupplier.getClippingFlag(z, absX + (size - 1), absY - 1) and 0x12c0183 == 0) { + for (i in 1 until size - 1) { + if (clipMaskSupplier.getClippingFlag(z, absX + i, absY - 1) and 0x12c018f != 0) { + break@south + } + } + check(curX, curY - 1, SOUTH_FLAG, thisCost) + } + } while (false) + west@ do { + if (curX > 0 && via[curX - 1][curY] == 0 && clipMaskSupplier.getClippingFlag(z, absX - 1, absY) and 0x12c010e == 0 && clipMaskSupplier.getClippingFlag(z, absX - 1, absY + (size - 1)) and 0x12c0138 == 0) { + for (i in 1 until size - 1) { + if (clipMaskSupplier.getClippingFlag(z, absX - 1, absY + i) and 0x12c013e != 0) { + break@west + } + } + check(curX - 1, curY, WEST_FLAG, thisCost) + } + } while (false) + north@ do { + if (curY < 102 && via[curX][curY + 1] == 0 && clipMaskSupplier.getClippingFlag(z, absX, absY + size) and 0x12c0138 == 0 && clipMaskSupplier.getClippingFlag(z, absX + (size - 1), absY + size) and 0x12c01e0 == 0) { + for (i in 1 until size - 1) { + if (clipMaskSupplier.getClippingFlag(z, absX + i, absY + size) and 0x12c01f8 != 0) { + break@north + } + } + check(curX, curY + 1, NORTH_FLAG, thisCost) + } + } while (false) + east@ do { + if (curX < 102 && via[curX + 1][curY] == 0 && clipMaskSupplier.getClippingFlag(z, absX + size, absY) and 0x12c0183 == 0 && clipMaskSupplier.getClippingFlag(z, absX + size, absY + (size - 1)) and 0x12c01e0 == 0) { + for (i in 1 until size - 1) { + if (clipMaskSupplier.getClippingFlag(z, absX + size, absY + i) and 0x12c01e3 != 0) { + break@east + } + } + check(curX + 1, curY, EAST_FLAG, thisCost) + } + } while (false) + southWest@ do { + if (curX > 0 && curY > 0 && via[curX - 1][curY - 1] == 0 && clipMaskSupplier.getClippingFlag(z, absX - 1, absY + (size - 2)) and 0x12c0138 == 0 && clipMaskSupplier.getClippingFlag(z, absX - 1, absY - 1) and 0x12c010e == 0 && clipMaskSupplier.getClippingFlag(z, absX + (size - 2), absY - 1) and 0x12c0183 == 0) { + for (i in 1 until size - 1) { + if (clipMaskSupplier.getClippingFlag(z, absX - 1, absY + (i - 1)) and 0x12c013e != 0 || clipMaskSupplier.getClippingFlag(z, absX + (i - 1), absY - 1) and 0x12c018f != 0) { + break@southWest + } + } + check(curX - 1, curY - 1, SOUTH_WEST_FLAG, thisCost) + } + } while (false) + northWest@ do { + if (curX > 0 && curY < 102 && via[curX - 1][curY + 1] == 0 && clipMaskSupplier.getClippingFlag(z, absX - 1, absY + 1) and 0x12c010e == 0 && clipMaskSupplier.getClippingFlag(z, absX - 1, absY + size) and 0x12c0138 == 0 && clipMaskSupplier.getClippingFlag(z, absX, absY + size) and 0x12c01e0 == 0) { + for (i in 1 until size - 1) { + if (clipMaskSupplier.getClippingFlag(z, absX - 1, absY + (i + 1)) and 0x12c013e != 0 || clipMaskSupplier.getClippingFlag(z, absX + (i - 1), absY + size) and 0x12c01f8 != 0) { + break@northWest + } + } + check(curX - 1, curY + 1, NORTH_WEST_FLAG, thisCost) + } + } while (false) + southEast@ do { + if (curX < 102 && curY > 0 && via[curX + 1][curY - 1] == 0 && clipMaskSupplier.getClippingFlag(z, absX + 1, absY - 1) and 0x12c010e == 0 && clipMaskSupplier.getClippingFlag(z, absX + size, absY - 1) and 0x12c0183 == 0 && clipMaskSupplier.getClippingFlag(z, absX + size, absY + (size - 2)) and 0x12c01e0 == 0) { + for (i in 1 until size - 1) { + if (clipMaskSupplier.getClippingFlag(z, absX + size, absY + (i - 1)) and 0x12c01e3 != 0 || clipMaskSupplier.getClippingFlag(z, absX + (i + 1), absY - 1) and 0x12c018f != 0) { + break@southEast + } + } + check(curX + 1, curY - 1, SOUTH_EAST_FLAG, thisCost) + } + } while (false) + if (curX < 102 && curY < 102 && via[curX + 1][curY + 1] == 0 && clipMaskSupplier.getClippingFlag(z, absX + 1, absY + size) and 0x12c0138 == 0 && clipMaskSupplier.getClippingFlag(z, absX + size, absY + size) and 0x12c01e0 == 0 && clipMaskSupplier.getClippingFlag(z, absX + size, absY + 1) and 0x12c0183 == 0) { + for (i in 1 until size - 1) { + if (clipMaskSupplier.getClippingFlag(z, absX + (i + 1), absY + size) and 0x12c01f8 != 0 || clipMaskSupplier.getClippingFlag(z, absX + size, absY + (i + 1)) and 0x12c01e3 != 0) { + continue@main + } + } + check(curX + 1, curY + 1, NORTH_EAST_FLAG, thisCost) + } + } + } +} diff --git a/Server/src/main/core/game/world/map/zone/MapZone.java b/Server/src/main/core/game/world/map/zone/MapZone.java new file mode 100644 index 0000000..630d061 --- /dev/null +++ b/Server/src/main/core/game/world/map/zone/MapZone.java @@ -0,0 +1,481 @@ +package core.game.world.map.zone; + +import content.global.skill.summoning.familiar.Familiar; +import core.game.interaction.Option; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.request.RequestType; +import core.game.node.item.Item; +import core.game.world.map.Location; +import core.game.world.map.Region; +import core.game.world.map.RegionManager; + +import java.util.Iterator; +import java.util.Objects; + +/** + * Represents a map zone. + * @author Emperor + */ +public abstract class MapZone implements Zone { + + /** + * The map zone uid. + */ + private int uid; + + /** + * The zone name. + */ + private String name; + + /** + * If the map zone can be overlapped by another zone. + */ + private boolean overlappable; + + /** + * If random events should be fired in this zone. + */ + protected boolean fireRandomEvents; + + /** + * If restriction flag. + */ + private int restriction; + + /** + * The zone type (used for items kept on death). + */ + private int zoneType; + + /** + * Constructs a new {@code MapZone} {@code Object}. + * @param name The name. + * @param overlappable If the zone can be overlapped. + */ + public MapZone(String name, boolean overlappable, ZoneRestriction... restrictions) { + this.name = name; + this.overlappable = overlappable; + for (ZoneRestriction restriction : restrictions) { + addRestriction(restriction.getFlag()); + } + } + + @Override + public boolean enter(Entity e) { + if (e instanceof Player) { + Player p = (Player) e; + } else if (e instanceof NPC) { + NPC npc = (NPC) e; + if (e instanceof Familiar && isRestricted(ZoneRestriction.FOLLOWERS.getFlag())) { + npc.setInvisible(true); + } + } + return true; + } + + @Override + public boolean leave(Entity e, boolean logout) { + return true; + } + + /** + * Checks if the player can logout. + * @param p The player. + * @return {@code True} if so. + */ + public boolean canLogout(Player p) { + return true; + } + + /** + * Called when an entity dies. + * @param e The entity dying. + * @param killer The killer. + * @return {@code True} if the death got handled by this zone handler. + */ + public boolean death(Entity e, Entity killer) { + return false; + } + + /** + * Handles an interaction. + * @param e The entity. + * @param target The target to interact with. + * @param option The option. + * @return {@code True} if the option got handled. + */ + public boolean interact(Entity e, Node target, Option option) { + return false; + } + + public boolean handleUseWith(Player player, Item used, Node with){return false;} + + /** + * Handles an reward button. + * @param player The player. + * @param interfaceId The interface id. + * @param buttonId The button id. + * @param slot The slot. + * @param itemId The item id. + * @param opcode The packet opcode. + * @return {@code True} if the button got handled. + */ + public boolean actionButton(Player player, int interfaceId, int buttonId, int slot, int itemId, int opcode) { + return false; + } + + /** + * Checks if the entity is able to continue attacking the target. + * @param e the attacking entity. + * @param target The target. + * @param style The combat style used. + * @param message If a message should be send. + * @return {@code True} if so. + */ + public boolean continueAttack(Entity e, Node target, CombatStyle style, boolean message) { + return true; + } + + /** + * If multi-zone boundaries should be ignored. + * @param attacker The attacker. + * @param victim The victim. + * @return {@code True} if the entity can attack regardless of multicombat. + */ + public boolean ignoreMultiBoundaries(Entity attacker, Entity victim) { + return false; + } + + /** + * Checks if the entity can attack the target. + * @param e The attacking entity. + * @param t The target. + * @param message If a message should be sent. + * @return {@code True} if the entity can continue attacking. + */ + public static boolean checkMulti(Entity e, Entity t, boolean message) { + long time = System.currentTimeMillis(); + boolean multi = t.getProperties().isMultiZone() && e.getProperties().isMultiZone(); + if (multi || e.isIgnoreMultiBoundaries(t) || e.getZoneMonitor().isIgnoreMultiBoundaries(t)) { + return true; + } + Entity target = t.getAttribute("combat-attacker", e); + if (t.getAttribute("combat-time", -1L) > time && target != e && target.isActive()) { + if (message && e instanceof Player) { + ((Player) e).getPacketDispatch().sendMessage("Someone else is already fighting this" + (t instanceof Player ? " player." : ".")); + } + return false; + } + if (e.getAttribute("combat-time", -1L) > time && (target = e.getAttribute("combat-attacker", t)) != t && target.isActive()) { + if (t.getId() == 1614 || t.getId() == 1613) { + return true; + } + if (message && e instanceof Player) { + ((Player) e).getPacketDispatch().sendMessage("You're already under attack!"); + } + return false; + } + return true; + } + + /** + * Checks if the entity can teleport. + * @param e The entity. + * @param type The teleport type (0=spell, 1=item, 2=object, 3=npc -1= + * force) + * @return {@code True} if so. + */ + public boolean teleport(Entity e, int type, Node node) { + return true; + } + + /** + * Checks if the death should start. + * @param e the entity. + * @param killer the killer. + * @return {@code True} if so. + */ + public boolean startDeath(Entity e, Entity killer) { + return true; + } + + /** + * Checks if a request can be made in this zone. + * @param type the type. + * @param target the target. + * @return {@code True} if so. + */ + public boolean canRequest(RequestType type, Player player, Player target) { + return true; + } + + /** + * Checks if the entity can move. + * @param e The entity. + * @param from The current location. + * @param to The destination location. + * @return {@code True} if so. + */ + public boolean move(Entity e, Location from, Location to) { + return true; + } + + /** + * Parses a command in this map zone. + * @param player the player. + * @param name the name. + * @param arguments the arguments. + * @return {@code True} if so. + */ + public boolean parseCommand(Player player, String name, String[] arguments) { + return false; + } + + /** + * Called when an entity changed location. + * @param e The entity. + * @param last The previous location the entity was standing on. + */ + public void locationUpdate(Entity e, Location last) { + + } + + /** + * Configures this map zone. + */ + public void configure(){}; + + /** + * Cleans items from a players inventory, equipment and bank. + * @param player the player. + * @param items the items. + */ + public void cleanItems(Player player, Item[] items) { + if (player == null) { + return; + } + for (Item item : items) { + if (item == null) { + continue; + } + if (player.getInventory().containsItem(item)) { + player.getInventory().remove(new Item(item.getId(), player.getInventory().getAmount(item))); + } + if (player.getEquipment().containsItem(item)) { + player.getEquipment().remove(new Item(item.getId(), player.getEquipment().getAmount(item))); + } + if (player.getBank().containsItem(item)) { + player.getBank().remove(new Item(item.getId(), player.getBank().getAmount(item))); + } + } + } + + /** + * Sends a message to the entity (if it is a player). + * @param e The entity. + * @param message The message. + */ + protected static void message(Entity e, String message) { + if (!(e instanceof Player)) { + return; + } + ((Player) e).getPacketDispatch().sendMessage(message); + } + + /** + * Registers this mapzone in the appropriate regions. + * @param borders The borders of this zone. + */ + public void register(ZoneBorders borders) { + for (Integer id : borders.getRegionIds()) { + Region r = RegionManager.forId(id); + if (r != null) { + r.add(new RegionZone(this, borders)); + } + } + } + + public void unregister(ZoneBorders borders) { + for (Integer id : borders.getRegionIds()) { + Region r = RegionManager.forId(id); + if (r != null) { + r.remove(new RegionZone(this, borders)); + } + } + } + + /** + * Registers this zone in the region for the given id. + * @param regionId The region id. + */ + public void registerRegion(int regionId) { + register(ZoneBorders.forRegion(regionId)); + } + + /** + * Registers a region with zone borders and the region id. + * @param regionId the region id. + * @param borders the borders. + */ + public void registerRegion(int regionId, ZoneBorders borders) { + Region r = RegionManager.forId(regionId); + if (r != null) { + r.add(new RegionZone(this, borders)); + } + } + + /** + * Unregisters the borders in a region. + * @param regionId The region id. + */ + public void unregisterRegion(int regionId) { + Region r = RegionManager.forId(regionId); + if (r != null) { + for (Iterator it = r.getRegionZones().iterator(); it.hasNext();) { + if (it.next().getZone() == this) { + it.remove(); + } + } + } + } + + /** + * Disables the firing of random events in this zone. + */ + public void disableRandomEvents() { + this.fireRandomEvents = false; + } + + /** + * Gets the name. + * @return The name. + */ + public String getName() { + return name; + } + + /** + * Sets the name. + * @param name The name to set. + */ + public void setName(String name) { + this.name = name; + } + + /** + * Gets the overlappable. + * @return The overlappable. + */ + public boolean isOverlappable() { + return overlappable; + } + + /** + * Sets the overlappable. + * @param overlappable The overlappable to set. + */ + public void setOverlappable(boolean overlappable) { + this.overlappable = overlappable; + } + + /** + * Gets the uid. + * @return The uid. + */ + public int getUid() { + return getName().hashCode(); + } + + /** + * Sets the uid. + * @param uid The uid to set. + */ + public void setUid(int uid) { + this.uid = uid; + } + + /** + * Gets the fireRandoms. + * @return The fireRandoms. + */ + public boolean isFireRandoms() { + return fireRandomEvents; + } + + /** + * If the zone is dynamicly added and removed. Non-location based zones will + * typicly return true. + * @return {@code false} on default. + */ + public boolean isDynamicZone() { + return false; + } + + /** + * Adds a restriction flag. + * @param restriction The restriction flag. + */ + public void addRestriction(ZoneRestriction restriction) { + addRestriction(restriction.getFlag()); + } + + /** + * Adds a restriction flag. + * @param flag The restriction flag. + */ + public void addRestriction(int flag) { + restriction |= flag; + } + + /** + * Checks if the restriction was flagged. + * @param flag The restriction flag. + * @return {@code True} if so. + */ + public boolean isRestricted(int flag) { + return (restriction & flag) != 0; + } + + /** + * Gets the restriction. + * @return The restriction. + */ + public int getRestriction() { + return restriction; + } + + /** + * Gets the type. + * @return The type. + */ + public int getZoneType() { + return zoneType; + } + + /** + * Sets the type. + * @param type The type to set. + */ + public void setZoneType(int type) { + this.zoneType = type; + } + + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + MapZone mapZone = (MapZone) o; + return getUid() == mapZone.getUid(); + } + + @Override + public int hashCode() { + return Objects.hash(uid, name, overlappable, fireRandomEvents, restriction, zoneType); + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/world/map/zone/RegionZone.java b/Server/src/main/core/game/world/map/zone/RegionZone.java new file mode 100644 index 0000000..4c4c112 --- /dev/null +++ b/Server/src/main/core/game/world/map/zone/RegionZone.java @@ -0,0 +1,59 @@ +package core.game.world.map.zone; + +import java.util.Objects; + +/** + * Represents a zone inside a single region of the world map. + * @author Emperor + */ +public final class RegionZone { + + /** + * The map zone. + */ + private final MapZone zone; + + /** + * The borders. + */ + private final ZoneBorders borders; + + /** + * Constructs a new {@code RegionZone} {@code Object}. + * @param zone The map zone. + * @param borders The borders. + */ + public RegionZone(MapZone zone, ZoneBorders borders) { + this.zone = zone; + this.borders = borders; + } + + /** + * Gets the borders. + * @return The borders. + */ + public ZoneBorders getBorders() { + return borders; + } + + /** + * Gets the zone. + * @return The zone. + */ + public MapZone getZone() { + return zone; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + RegionZone that = (RegionZone) o; + return Objects.equals(zone, that.zone) && Objects.equals(borders, that.borders); + } + + @Override + public int hashCode() { + return Objects.hash(zone, borders); + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/world/map/zone/Zone.java b/Server/src/main/core/game/world/map/zone/Zone.java new file mode 100644 index 0000000..91cd441 --- /dev/null +++ b/Server/src/main/core/game/world/map/zone/Zone.java @@ -0,0 +1,26 @@ +package core.game.world.map.zone; + +import core.game.node.entity.Entity; + +/** + * Represents a zone. + * @author Emperor + */ +public interface Zone { + + /** + * Checks if the entity can enter this map zone. + * @param e The entity. + * @return {@code True} if so. + */ + boolean enter(Entity e); + + /** + * Called when the entity leaves this map zone. + * @param e The entity. + * @param logout If the entity is logging out. + * @return {@code True} if the entity can leave. + */ + boolean leave(Entity e, boolean logout); + +} \ No newline at end of file diff --git a/Server/src/main/core/game/world/map/zone/ZoneBorders.java b/Server/src/main/core/game/world/map/zone/ZoneBorders.java new file mode 100644 index 0000000..b43fa5d --- /dev/null +++ b/Server/src/main/core/game/world/map/zone/ZoneBorders.java @@ -0,0 +1,300 @@ +package core.game.world.map.zone; + +import core.game.node.Node; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.tools.RandomFunction; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Random; + +/** + * Represents the borders of a zone. + * @author Emperor + */ +public final class ZoneBorders { + + /** + * The south west x-coordinate. + */ + private final int southWestX; + + /** + * The south west y-coordinate. + */ + private final int southWestY; + + /** + * The north east x-coordinate. + */ + private final int northEastX; + + /** + * The north east y-coordinate. + */ + private final int northEastY; + + /** + * The plane required to be on. + */ + private int plane = 0; + + /** + * The list of exceptions. + */ + private List exceptions; + + /** + * If we need to do a zero plane check. + */ + private boolean zeroPlaneCheck; + + /** + * Constructs a new {@code ZoneBorders} {@code Object}. + * @param x1 The south west x-coordinate. + * @param y1 The south west y-coordinate. + * @param x2 The north east x-coordinate. + * @param y2 The north east y-coordinate. + * Invariant enforced at runtime. + */ + public ZoneBorders(int x1, int y1, int x2, int y2) { + this.southWestX = Math.min(x1, x2); + this.southWestY = Math.min(y1, y2); + this.northEastX = Math.max(x1, x2); + this.northEastY = Math.max(y1, y2); + } + + /** + * Constructs a new {@code ZoneBorders} {@code Object}. + * @param x1 The south west x-coordinate. + * @param y1 The south west y-coordinate. + * @param x2 The north east x-coordinate. + * @param y2 The north east y-coordinate. + * Invariant enforced at runtime. + * @param plane the plane. + */ + public ZoneBorders(int x1, int y1, int x2, int y2, int plane) { + this.southWestX = Math.min(x1, x2); + this.southWestY = Math.min(y1, y2); + this.northEastX = Math.max(x1, x2); + this.northEastY = Math.max(y1, y2); + this.setPlane(plane); + } + + /** + * Constructs a new {@code ZoneBorders} {@code Object}. + * @param x1 The south west x-coordinate. + * @param y1 The south west y-coordinate. + * @param x2 The north east x-coordinate. + * @param y2 The north east y-coordinate. + * Invariant enforced at runtime. + * @param plane the plane. + * @param zeroPlaneCheck the plane check. + */ + public ZoneBorders(int x1, int y1, int x2, int y2, int plane, boolean zeroPlaneCheck) { + this(x1, y1, x2, y2, plane); + this.zeroPlaneCheck = zeroPlaneCheck; + } + + public ZoneBorders(Location l1, Location l2) { + this(l1.getX(), l1.getY(), l2.getX(), l2.getY(), l1.getZ()); + } + + /** + * Creates zone borders for the given region id. + * @param regionId The region id. + * @return The zone borders. + */ + public static ZoneBorders forRegion(int regionId) { + int baseX = ((regionId >> 8) & 0xFF) << 6; + int baseY = (regionId & 0xFF) << 6; + int size = 64 - 1; + return new ZoneBorders(baseX, baseY, baseX + size, baseY + size); + } + + /** + * Checks if the location is inside the borders. + * @param location The location. + * @return {@code True} if the location is inside the zone borders. + */ + public boolean insideBorder(Location location) { + return insideBorder(location.getX(), location.getY(), location.getZ()); + } + + /** + * Checks if the node is inside the borders. + * @param node the node. + * @return {@code True} if so. + */ + public boolean insideBorder(Node node) { + return insideBorder(node.getLocation()); + } + + /** + * Checks if the player is in the zone + * @param x the x. + * @param y the y. + * @return the z. + */ + public boolean insideBorder(int x, int y) { + return insideBorder(x, y, 0); + } + + /** + * Checks if the coordinates are inside the borders. + * @param x The x-coordinate. + * @param y The y-coordinate. + * @param z The z coordinate. + * @return {@code True} if the coordinates lay in the zone borders. + */ + public boolean insideBorder(int x, int y, int z) { + if (zeroPlaneCheck ? z != plane : (plane != 0 && z != plane)) { + return false; + } + if (southWestX <= x && southWestY <= y && northEastX >= x && northEastY >= y) { + if (exceptions != null) { + Object[] exceptArray = exceptions.toArray(); + int length = exceptArray.length; + for (int i = 0; i < length; i++) { + ZoneBorders exception = (ZoneBorders) exceptArray[i]; + if (exception.insideBorder(x, y, z)) { + return false; + } + } + } + return true; + } + return false; + } + + /** + * Gets the ids of all the regions inside these borders. + * @return The region ids. + */ + public List getRegionIds() { + List regionIds = new ArrayList<>(20); + int neX = (northEastX >> 6) + 1; + int neY = (northEastY >> 6) + 1; + for (int x = southWestX >> 6; x < neX; x++) { + for (int y = southWestY >> 6; y < neY; y++) { + int id = y | x << 8; + regionIds.add(id); + } + } + return regionIds; + } + + /** + * Gets the southWestX. + * @return The southWestX. + */ + public int getSouthWestX() { + return southWestX; + } + + /** + * Gets the southWestY. + * @return The southWestY. + */ + public int getSouthWestY() { + return southWestY; + } + + /** + * Gets the northEastX. + * @return The northEastX. + */ + public int getNorthEastX() { + return northEastX; + } + + /** + * Gets the northEastY. + * @return The northEastY. + */ + public int getNorthEastY() { + return northEastY; + } + + /** + * Gets the exceptions. + * @return The exceptions. + */ + public List getExceptions() { + return exceptions; + } + + public Location getWeightedRandomLoc(int intensity) + { + int x = northEastX - southWestX == 0 ? southWestX : RandomFunction.normalRandDist(northEastX - southWestX, intensity) + southWestX; + int y = northEastY - southWestY == 0 ? southWestY : RandomFunction.normalRandDist(northEastY - southWestY, intensity) + southWestY; + return new Location(x, y); + } + + public Location getRandomLoc() { + int x = northEastX - southWestX == 0 ? southWestX : new Random().nextInt(northEastX - southWestX + 1) + southWestX; + int y = northEastY - southWestY == 0 ? southWestY : new Random().nextInt(northEastY - southWestY + 1) + southWestY; + return new Location(x, y, plane); + } + + public Location getRandomWalkableLoc() { + Location loc = getRandomLoc(); + int tries = 0; // prevent bad code from DOSing server + while (!RegionManager.isTeleportPermitted(loc) && tries < 20) { + loc = getRandomLoc(); + tries += 1; + } + return loc; + } + + /** + * Adds an exception. + * @param exception The exception to add. + */ + public void addException(ZoneBorders exception) { + if (exceptions == null) { + this.exceptions = new ArrayList<>(20); + } + exceptions.add(exception); + } + + @Override + public String toString() { + return "ZoneBorders [southWestX=" + southWestX + ", southWestY=" + southWestY + ", northEastX=" + northEastX + ", northEastY=" + northEastY + ", exceptions=" + exceptions + "]"; + } + + /** + * Gets the bplane. + * @return the plane + */ + public int getPlane() { + return plane; + } + + /** + * Sets the baplane. + * @param plane the plane to set. + */ + public void setPlane(int plane) { + this.plane = plane; + } + + public boolean insideRegion(Node n) { + return insideBorder(n.getLocation().getRegionX(), n.getLocation().getRegionY()); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ZoneBorders that = (ZoneBorders) o; + return southWestX == that.southWestX && southWestY == that.southWestY && northEastX == that.northEastX && northEastY == that.northEastY && plane == that.plane && zeroPlaneCheck == that.zeroPlaneCheck && Objects.equals(exceptions, that.exceptions); + } + + @Override + public int hashCode() { + return Objects.hash(southWestX, southWestY, northEastX, northEastY, plane, exceptions, zeroPlaneCheck); + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/world/map/zone/ZoneBuilder.java b/Server/src/main/core/game/world/map/zone/ZoneBuilder.java new file mode 100644 index 0000000..0fd373e --- /dev/null +++ b/Server/src/main/core/game/world/map/zone/ZoneBuilder.java @@ -0,0 +1,31 @@ +package core.game.world.map.zone; + +import core.api.StartupListener; +import core.game.world.map.zone.impl.*; + + +/** + * Loads all the default zones. + * @author Emperor + */ +public class ZoneBuilder implements StartupListener { + + @Override + public void startup() { + configure(WildernessZone.getInstance()); + configure(MultiwayCombatZone.getInstance()); + configure(new ModeratorZone()); + configure(new DarkZone()); + configure(new KaramjaZone()); + configure(new BankZone()); + } + + /** + * Configures the map zone. + * @param zone The map zone. + */ + public static void configure(MapZone zone) { + zone.setUid(zone.getName().hashCode()); + zone.configure(); + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/world/map/zone/ZoneMonitor.java b/Server/src/main/core/game/world/map/zone/ZoneMonitor.java new file mode 100644 index 0000000..65b4a03 --- /dev/null +++ b/Server/src/main/core/game/world/map/zone/ZoneMonitor.java @@ -0,0 +1,498 @@ +package core.game.world.map.zone; + +import core.game.interaction.Option; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.music.MusicEntry; +import core.game.node.entity.player.link.music.MusicZone; +import core.game.node.entity.player.link.request.RequestType; +import core.game.node.item.Item; +import core.game.world.map.Location; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import core.game.world.map.Region; +import org.rs09.consts.Items; + +/** + * Handles the zones for an entity. + * @author Emperor + */ +public final class ZoneMonitor { + + /** + * The set of jewellery which allow teleporting from up to and including level 30 wildy. + * Used to check if a player can teleport from 20 < level <= 30 wildy, see canTeleportByJewellery. + * Note: the check is based on the nextJewellery (see EnchantedJewellery.kt), so this list should not contain the (4) items, and should contain the empty ones. + * @author Player Name + */ + static final Set MID_WILDY_TELEPORT_JEWELLERY = Set.of( + Items.AMULET_OF_GLORY_1704, + Items.AMULET_OF_GLORY1_1706, + Items.AMULET_OF_GLORY2_1708, + Items.AMULET_OF_GLORY3_1710, + Items.AMULET_OF_GLORYT_10362, + Items.AMULET_OF_GLORYT1_10360, + Items.AMULET_OF_GLORYT2_10358, + Items.AMULET_OF_GLORYT3_10356, + Items.SKILLS_NECKLACE_11113, + Items.SKILLS_NECKLACE1_11111, + Items.SKILLS_NECKLACE2_11109, + Items.SKILLS_NECKLACE3_11107, + Items.COMBAT_BRACELET_11126, + Items.COMBAT_BRACELET1_11124, + Items.COMBAT_BRACELET2_11122, + Items.COMBAT_BRACELET3_11120, + Items.RING_OF_WEALTH_14638, + Items.RING_OF_WEALTH1_14640, + Items.RING_OF_WEALTH2_14642, + Items.RING_OF_WEALTH3_14644, + Items.RING_OF_LIFE_2570 + ); + + /** + * The entity. + */ + private final Entity entity; + + /** + * The currently entered zones. + */ + private final List zones = new ArrayList<>(20); + + /** + * The currently entered music zones. + */ + private final List musicZones = new ArrayList<>(20); + + /** + * Constructs a new {@code ZoneMonitor} {@code Object}. + * @param entity The entity. + */ + public ZoneMonitor(Entity entity) { + this.entity = entity; + } + + /** + * Gets the zone type. + * @return The zone type. + */ + public int getType() { + for (RegionZone zone : zones) { + if (zone.getZone().getZoneType() != 0) { + return zone.getZone().getZoneType(); + } + } + return 0; + } + + /** + * Checks if the player can logout. + * @return {@code True} if so. + */ + public boolean canLogout() { + for (RegionZone z : zones) { + if (!z.getZone().canLogout((Player) entity)) { + return false; + } + } + return true; + } + + /** + * Checks if the restriction was flagged. + * @param restriction The restriction flag. + * @return {@code True} if so. + */ + public boolean isRestricted(ZoneRestriction restriction) { + return isRestricted(restriction.getFlag()); + } + + /** + * Checks if the restriction was flagged. + * @param flag The restriction flag. + * @return {@code True} if so. + */ + public boolean isRestricted(int flag) { + for (RegionZone z : zones) { + if (z.getZone().isRestricted(flag)) { + return true; + } + } + return false; + } + + /** + * Handles a death. + * @param killer The killer. + * @return {@code True} if the death got handled. + */ + public boolean handleDeath(Entity killer) { + for (RegionZone z : zones) { + if (z.getZone().death(entity, killer)) { + return true; + } + } + return false; + } + + /** + * Checks if the entity is able to continue attacking the target. + * @param target The target. + * @param style The combat style used. + * @return {@code True} if so. + */ + public boolean continueAttack(Node target, CombatStyle style, boolean message) { + if (target instanceof Entity) { + if (!entity.continueAttack((Entity) target, style, message)) { + return false; + } + } + for (RegionZone z : zones) { + if (!z.getZone().continueAttack(entity, target, style, message)) { + return false; + } + } + if (entity instanceof Player && target instanceof Player) { + if (!((Player) entity).getSkullManager().isWilderness() || !((Player) target).getSkullManager().isWilderness()) { + if(message) { + ((Player) entity).getPacketDispatch().sendMessage("You can only attack other players in the wilderness."); + } + return false; + } + } + if (target instanceof Entity && !MapZone.checkMulti(entity, (Entity) target, message)) { + return false; + } + return true; + } + + /** + * Checks if the entity can interact with the target. + * @param target The target to interact with. + * @param option The option. + * @return {@code True} if the option got handled. + */ + public boolean interact(Node target, Option option) { + for (RegionZone z : zones) { + if (z.getZone().interact(entity, target, option)) { + return true; + } + } + return false; + } + + /** + * Checks if a zone handles a useWith interaction + */ + public boolean useWith(Item used, Node with){ + for (RegionZone z : zones) { + if (z.getZone().handleUseWith(entity.asPlayer(), used,with)) { + return true; + } + } + return false; + } + + /** + * Checks if the player handled the reward button using a map zone. + * @param interfaceId The interface id. + * @param buttonId The button id. + * @param slot The slot. + * @param itemId The item id. + * @param opcode The packet opcode. + * @return {@code True} if the button got handled. + */ + public boolean clickButton(int interfaceId, int buttonId, int slot, int itemId, int opcode) { + for (RegionZone z : zones) { + if (z.getZone().actionButton((Player) entity, interfaceId, buttonId, slot, itemId, opcode)) { + return true; + } + } + return false; + } + + /** + * Checks if multiway combat zone rules should be ignored. + * @param victim The victim. + * @return {@code True} if this entity can attack regardless of multiway + * combat zone. + */ + public boolean isIgnoreMultiBoundaries(Entity victim) { + for (RegionZone z : zones) { + if (z.getZone().ignoreMultiBoundaries(entity, victim)) { + return true; + } + } + return false; + } + + /** + * Checks if the entity can teleport. + * @param type The teleport type (0=spell, 1=item, 2=object, 3=npc -1= force) + * @return {@code True} if so. + */ + public boolean teleport(int type, Node node) { + if (type != -1 && entity.isTeleBlocked() && !canTeleportByJewellery(type, node)) { + if (entity.isPlayer()) { + entity.asPlayer().sendMessage("A magical force has stopped you from teleporting."); + } + return false; + } + for (RegionZone z : zones) { + if (!z.getZone().teleport(entity, type, node)) { + return false; + } + } + return true; + } + + /** + * Checks if a player can teleport with a jewellery piece in >= 1 <= 30 wilderness level + * @return {@code True} if so. + */ + private boolean canTeleportByJewellery(int type, Node node) { + if (type != 1 || !MID_WILDY_TELEPORT_JEWELLERY.contains(node.asItem().getId())) { + return false; + } + if (entity.timers.getTimer("teleblock") != null) + return false; + + if (entity.getZoneMonitor().isRestricted(ZoneRestriction.TELEPORT)) { + return false; + } + + if (entity.getLocks().isTeleportLocked()) { + if (entity.isPlayer()) { + Player p = entity.asPlayer(); + if (p.getSkullManager().getLevel() >= 1 && p.getSkullManager().getLevel() <= 30) { + return true; + } + } + } + + return false; + } + + /** + * Checks if the death should start for an entity. + * @param entity the entity. + * @param killer the killer. + * @return {@code True} if so. + */ + public boolean startDeath(Entity entity, Entity killer) { + for (RegionZone z : zones) { + if (!z.getZone().startDeath(entity, killer)) { + return false; + } + } + return true; + } + + /** + * Checks if the entity can fire a random event. + * @return {@code True} if so. + */ + public boolean canFireRandomEvent() { + for (RegionZone z : zones) { + if (!z.getZone().isFireRandoms()) { + return false; + } + } + return true; + } + + /** + * Clears the zones. + * @return {@code True} if the entity successfully left all regions. + */ + public boolean clear() { + for (RegionZone z : zones) { + if (!z.getZone().leave(entity, true)) { + return false; + } + } + for (MusicZone z : musicZones) { + z.leave(entity, true); + } + zones.clear(); + musicZones.clear(); + return true; + } + + /** + * Checks if the entity can move. + * @param location The destination location. + * @param destination The destination location. + * @return {@code True} if so. + */ + public boolean move(Location location, Location destination) { + for (RegionZone z : zones) { + if (!z.getZone().move(entity, location, destination)) { + return false; + } + } + return true; + } + + /** + * Handles a location update. + * @param last The last location of the entity. + * @return {@code false} If the entity could not enter/leave a region. + */ + public boolean updateLocation(Location last) { + if(entity instanceof Player && !entity.asPlayer().isArtificial()) { + checkMusicZones(); + } + entity.updateLocation(last); + for (Iterator it = zones.iterator(); it.hasNext();) { + RegionZone zone = it.next(); + if (!zone.getBorders().insideBorder(entity)) { + if (zone.getZone().isDynamicZone()) { + continue; + } + if (!zone.getZone().leave(entity, false)) { + return false; + } + it.remove(); + } + } + for (RegionZone zone : entity.getViewport().getRegion().getRegionZones()) { + if (!zone.getBorders().insideBorder(entity)) { + continue; + } + boolean alreadyEntered = false; + for (RegionZone z : zones) { + if (z.getZone() == zone.getZone()) { + alreadyEntered = true; + break; + } + } + if (alreadyEntered) { + zone.getZone().locationUpdate(entity, last); + continue; + } + if (!zone.getZone().enter(entity)) { + return false; + } + zones.add(zone); + zone.getZone().locationUpdate(entity, last); + } + return true; + } + + /** + * Checks the music zones. + */ + public void checkMusicZones() { + if (!(entity instanceof Player)) { + return; + } + Player player = (Player) entity; + Location l = player.getLocation(); + for (Iterator it = musicZones.iterator(); it.hasNext();) { + MusicZone zone = it.next(); + if (!zone.getBorders().insideBorder(l.getX(), l.getY())) { + if (zone.leave(player, false)) { + it.remove(); + } + } + } + Region r = player.getViewport().getRegion(); + for (MusicZone zone : r.getMusicZones()) { + if (zone.getBorders().insideBorder(l.getX(), l.getY())) { + zone.enter(player); + return; + } + } + int music = r.getMusic(); + if (music == -1) { + if (!player.getMusicPlayer().isPlaying()) { + player.getMusicPlayer().playDefault(); + } + } else { + player.getMusicPlayer().unlock(music, true); + } + } + + /** + * Parses commands in a certain zone. + * @param player the player. + * @param name the name. + * @param arguments the arguments. + * @return {@code True} if parsed. + */ + public boolean parseCommand(Player player, String name, String[] arguments) { + for (RegionZone zone : zones) { + if (zone.getZone().parseCommand(player, name, arguments)) { + return true; + } + } + return false; + } + + /** + * Checks if a request can be made in this zone. + * @param type the type. + * @param target the target. + * @return {@code True} if so. + */ + public boolean canRequest(RequestType type, Player target) { + for (RegionZone zone : zones) { + if (!zone.getZone().canRequest(type, entity.asPlayer(), target)) { + return false; + } + } + return true; + } + + /** + * Checks if the entity is in a zone. + * @param name The name of the zone. + * @return {@code True} if so. + */ + public boolean isInZone(String name) { + int uid = name.hashCode(); + for (RegionZone zone : zones) { + if (zone.getZone().getUid() == uid) { + return true; + } + } + return false; + } + + /** + * Removes the proper region zone for the given map zone. + * @param zone The map zone. + */ + public void remove(MapZone zone) { + for (Iterator it = zones.iterator(); it.hasNext();) { + if (it.next().getZone() == zone) { + it.remove(); + break; + } + } + } + + /** + * Gets the zones list. + * @return The list of region zones the entity is in. + */ + public List getZones() { + return zones; + } + + /** + * Gets the musicZones. + * @return The musicZones. + */ + public List getMusicZones() { + return musicZones; + } + +} diff --git a/Server/src/main/core/game/world/map/zone/ZoneRestriction.java b/Server/src/main/core/game/world/map/zone/ZoneRestriction.java new file mode 100644 index 0000000..64dd971 --- /dev/null +++ b/Server/src/main/core/game/world/map/zone/ZoneRestriction.java @@ -0,0 +1,59 @@ +package core.game.world.map.zone; + +/** + * The zone restrictions. + * @author Emperor + */ +public enum ZoneRestriction { + + /** + * No followers allowed in this zone. + */ + FOLLOWERS, + + /** + * No random events allowed. + */ + RANDOM_EVENTS, + + /** + * No fires allowed. + */ + FIRES, + + /** + * Members only. + */ + MEMBERS, + + /** + * No cannons allowed. + */ + CANNON, + /** + * Do not spawn a grave if a player dies here. + */ + GRAVES, + + /** + * No teleporting allowed. + */ + TELEPORT, + + /** + * This region is not a part of the normal overworld or cave system. + * Used for temporary areas that use the 'original-loc' attribute to teleport the player back when they are done in the area. + * Example: non-dynamic/non-instanced random-event areas (e.g. Damien's bootcamp) + * Dynamic regions are implicitly off-map and do not require this attribute. + */ + OFF_MAP, + ; + + /** + * Gets the restriction flag. + * @return The flag. + */ + public int getFlag() { + return 1 << ordinal(); + } +} diff --git a/Server/src/main/core/game/world/map/zone/ZoneType.java b/Server/src/main/core/game/world/map/zone/ZoneType.java new file mode 100644 index 0000000..839ebc6 --- /dev/null +++ b/Server/src/main/core/game/world/map/zone/ZoneType.java @@ -0,0 +1,59 @@ +package core.game.world.map.zone; + +/** + * Represents the default zone types. + * @author Emperor + */ +public enum ZoneType { + + /** + * Default zone. + */ + DEFAULT(0), + + /** + * Safe area. + */ + SAFE(1), + + /** + * Player-owner house type. + */ + P_O_H(2), + + /** + * Castle wars zone. + */ + CASTLE_WARS(3), + + /** + * Trouble brewing zone. + */ + TROUBLE_BREWING(4), + + /** + * Barbarian assault zone. + */ + BARBARIAN_ASSAULT(5), ; + + /** + * The zone id. + */ + private final int id; + + /** + * Constructs a new {@code ZoneType} {@code Object}. + * @param id The zone id. + */ + ZoneType(int id) { + this.id = id; + } + + /** + * Gets the id. + * @return The id. + */ + public int getId() { + return id; + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/world/map/zone/impl/BankZone.java b/Server/src/main/core/game/world/map/zone/impl/BankZone.java new file mode 100644 index 0000000..0a11a7b --- /dev/null +++ b/Server/src/main/core/game/world/map/zone/impl/BankZone.java @@ -0,0 +1,49 @@ +package core.game.world.map.zone.impl; + +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBorders; + +/** + * Represents a bank zone. + * @author 'Vexia + */ +public final class BankZone extends MapZone { + + /** + * Represents the instance. + */ + private static final BankZone INSTANCE = new BankZone(); + + /** + * Represents the varrock west bank. + */ + public static final ZoneBorders VARROCK_WEST = new ZoneBorders(3179, 3432, 3194, 3446); + + /** + * Represents the varrock east bank. + */ + public static final ZoneBorders VARROCK_EAST = new ZoneBorders(3250, 3416, 3257, 3423); + + + /** + * Constructs a new {@code BankZone} {@code Object}. + */ + public BankZone() { + super("bank", true); + } + + @Override + public void configure() { + register(VARROCK_WEST); + register(VARROCK_EAST); + } + + /** + * Gets the instance. + * @return The instance. + */ + public static BankZone getInstance() { + return INSTANCE; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/world/map/zone/impl/DarkZone.java b/Server/src/main/core/game/world/map/zone/impl/DarkZone.java new file mode 100644 index 0000000..5d95503 --- /dev/null +++ b/Server/src/main/core/game/world/map/zone/impl/DarkZone.java @@ -0,0 +1,213 @@ +package core.game.world.map.zone.impl; + +import content.global.skill.skillcapeperks.SkillcapePerks; +import core.game.event.EventHook; +import core.game.event.UseWithEvent; +import core.game.component.Component; +import content.data.LightSource; +import core.game.interaction.Option; +import core.game.interaction.QueueStrength; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.ImpactHandler.HitsplatType; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.system.task.Pulse; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.RegionZone; +import core.game.world.map.zone.ZoneBorders; +import kotlin.Unit; +import org.jetbrains.annotations.NotNull; +import core.api.Event; +import core.game.world.GameWorld; + +import static core.api.ContentAPIKt.*; + +/** + * Handles a dark area. + * @author Emperor + */ +public final class DarkZone extends MapZone implements EventHook{ + + /** + * The darkness overlay. + */ + public static final Component DARKNESS_OVERLAY = new Component(96) { + @Override + public void open(final Player player) { + Pulse pulse = player.getExtension(DarkZone.class); + if (pulse != null && pulse.isRunning()) { + return; + } + pulse = new Pulse(2, player) { + int count = 0; + + @Override + public boolean pulse() { + if (count == 0) { + player.getPacketDispatch().sendMessage("You hear tiny insects skittering over the ground..."); + } else if (count == 5) { + player.getPacketDispatch().sendMessage("Tiny biting insects swarm all over you!"); + } else if (count > 5) { + player.getImpactHandler().manualHit(player, 1, HitsplatType.NORMAL); + } + count++; + return false; + } + }; + GameWorld.getPulser().submit(pulse); + player.addExtension(DarkZone.class, pulse); + super.open(player); + } + + @Override + public boolean close(final Player player) { + if (!super.close(player)) { + return false; + } + Pulse pulse = player.getExtension(DarkZone.class); + if (pulse != null) { + pulse.stop(); + } + return true; + } + }; + + /** + * Constructs a new {@code DarkZone} {@code Object}. + */ + public DarkZone() { + super("Dark zone", true); + } + + @Override + public void configure() { + register(new ZoneBorders(1728, 5120, 1791, 5247)); + registerRegion(12693); + registerRegion(12948); + registerRegion(12949); + register(new ZoneBorders(3306,9661,3222,9600)); + register(new ZoneBorders(3717,9473,3841,9346)); + } + + @Override + public boolean continueAttack(Entity e, Node target, CombatStyle style, boolean message) { + if (e instanceof Player) { + Player player = (Player) e; + if (player.getInterfaceManager().getOverlay() != DARKNESS_OVERLAY) { + return true; + } + return false; + } + return true; + } + + @Override + public boolean interact(Entity e, Node target, Option option) { + if (target instanceof Item) { + Item item = (Item) target; + LightSource s = LightSource.forProductId(item.getId()); + if (s != null) { + String name = option.getName().toLowerCase(); + if (name.equals("drop")) { + ((Player) e).getPacketDispatch().sendMessage("Dropping the " + s.getName() + " would leave you without a light source."); + return true; + } + if (name.equals("extinguish")) { + ((Player) e).getPacketDispatch().sendMessage("Extinguishing the " + s.getName() + " would leave you without a light source."); + return true; + } + } + } + return false; + } + + @Override + public boolean enter(Entity e) { + if (e instanceof Player) { + final Player player = (Player) e; + LightSource source = LightSource.getActiveLightSource(player); + if(SkillcapePerks.isActive(SkillcapePerks.CONSTANT_GLOW,player)){ + return true; + } + if (source == null) { + player.getInterfaceManager().openOverlay(DARKNESS_OVERLAY); + } else if (source.getInterfaceId() > 0) { + player.getInterfaceManager().openOverlay(new Component(source.getInterfaceId())); + } + } + e.hook(Event.getUsedWith(), this); + return true; + } + + @Override + public boolean leave(Entity e, boolean logout) { + if (e instanceof Player) { + ((Player) e).getInterfaceManager().closeOverlay(); + } + e.unhook(this); + return true; + } + + /** + * Updates the overlay. + * @param player The player. + */ + public void updateOverlay(Player player) { + LightSource source = LightSource.getActiveLightSource(player); + if(SkillcapePerks.isActive(SkillcapePerks.CONSTANT_GLOW,player)){ + queueScript(player, 1, QueueStrength.SOFT, false, (Integer stage) -> { + if(player.getInterfaceManager().getOverlay().getId() == DARKNESS_OVERLAY.getId()) + player.getInterfaceManager().closeOverlay(); + return stopExecuting(player); + }); + } + int overlay = -1; + if (player.getInterfaceManager().getOverlay() != null) { + overlay = player.getInterfaceManager().getOverlay().getId(); + } + if (source == null) { + if (overlay != DARKNESS_OVERLAY.getId()) { + player.getInterfaceManager().openOverlay(DARKNESS_OVERLAY); + } + return; + } + Pulse pulse = player.getExtension(DarkZone.class); + if (pulse != null) { + pulse.stop(); + } + if (source.getInterfaceId() != overlay) { + if (source.getInterfaceId() == -1) { + player.getInterfaceManager().closeOverlay(); + return; + } + player.getInterfaceManager().openOverlay(new Component(source.getInterfaceId())); + } + } + + /** + * Checks if the player is in a dark area and will update accordingly. + * @param p The player. + */ + public static boolean checkDarkArea(Player p) { + for (RegionZone r : p.getZoneMonitor().getZones()) { + if (r.getZone() instanceof DarkZone) { + DarkZone zone = (DarkZone) r.getZone(); + zone.updateOverlay(p); + return true; + } + } + return false; + } + + @Override + public void process(@NotNull Entity entity, @NotNull UseWithEvent event) { + boolean isTinderbox = getItemName(event.getUsed()).equals("Tinderbox") || getItemName(event.getWith()).equals("Tinderbox"); + + if (isTinderbox && entity instanceof Player) runTask(entity, 2, 1, () -> { + checkDarkArea(entity.asPlayer()); + return Unit.INSTANCE; + }); + } +} diff --git a/Server/src/main/core/game/world/map/zone/impl/KaramjaZone.java b/Server/src/main/core/game/world/map/zone/impl/KaramjaZone.java new file mode 100644 index 0000000..fb66645 --- /dev/null +++ b/Server/src/main/core/game/world/map/zone/impl/KaramjaZone.java @@ -0,0 +1,53 @@ +package core.game.world.map.zone.impl; + +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.map.zone.MapZone; + +/** + * Represents the karamja zone area. + * @author 'Vexia + * @version 1.0 + */ +public final class KaramjaZone extends MapZone { + + /** + * Represents the region ids. + */ + private static final int[] REGIONS = new int[] { 11309, 11054, 11566, 11565, 11567, 11568, 11053, 11821, 11055, 11057, 11569, 11822, 11823, 11825, 11310, 11311, 11312, 11313, 11314, 11056, 11057, 11058, 10802, 10801 }; + + /** + * Represents the karamjan rum item. + */ + private static final Item KARAMJAN_RUM = new Item(431); + + /** + * Constructs a new {@code KaramjaZone} {@code Object}. + */ + public KaramjaZone() { + super("karamja", true); + } + + @Override + public void configure() { + for (int regionId : REGIONS) { + registerRegion(regionId); + } + } + + @Override + public boolean teleport(Entity entity, int type, Node node) { + if (entity instanceof Player) { + final Player p = ((Player) entity); + int amt = p.getInventory().getAmount(KARAMJAN_RUM); + if (amt != 0) { + p.getInventory().remove(new Item(KARAMJAN_RUM.getId(), amt)); + p.getPacketDispatch().sendMessage("During the trip you lose your rum to a sailor in a game of dice. Better luck next time!"); + } + } + return super.teleport(entity, type, node); + } + +} diff --git a/Server/src/main/core/game/world/map/zone/impl/ModeratorZone.java b/Server/src/main/core/game/world/map/zone/impl/ModeratorZone.java new file mode 100644 index 0000000..1c8b113 --- /dev/null +++ b/Server/src/main/core/game/world/map/zone/impl/ModeratorZone.java @@ -0,0 +1,132 @@ +package core.game.world.map.zone.impl; + +import core.ServerConstants; +import core.game.interaction.Option; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.info.Rights; +import core.game.node.entity.player.link.TeleportManager.TeleportType; +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBorders; + +/** + * Represents the moderator zone. + * @author Vexia + * + */ +public class ModeratorZone extends MapZone { + + /** + * Represents if the moderator zone is open. + */ + public static boolean open = true; + + /** + * Represents the center of the zone. + */ + public static final Location center = Location.create(2846, 5213, 0); + + /** + * Constructs a new {@code ModeratorZone} {@code Object}. + */ + public ModeratorZone() { + super("Moderator Zone", true); + } + + @Override + public boolean enter(final Entity entity) { + if (!(entity instanceof Player)) { + return true; + } + final Player player = ((Player) entity); + if ((!open && player.getDetails().getRights() != Rights.ADMINISTRATOR)) { + home(player); + return false; + } + if (player.getDetails().getRights() == Rights.PLAYER_MODERATOR) { + // player.getInterfaceManager().removeTabs(0, 1, 2, 3, 4, 5, 6, 12); + } else { + player.getPacketDispatch().sendMessage(getToggleMessage()); + } + return true; + } + + @Override + public boolean leave(final Entity entity, final boolean logout) { + if (!(entity instanceof Player)) { + return true; + } + final Player player = ((Player) entity); + player.getInterfaceManager().restoreTabs(); + return true; + } + + @Override + public boolean interact(Entity entity, Node target, Option option) { + if (entity instanceof Player) { + } + return super.interact(entity, target, option); + } + + @Override + public void configure() { + register(new ZoneBorders(2840, 5204, 2853, 5224)); + } + + /** + * Method used to toggle the moderator zone. + * @param player the player. + * @param on the toggle switch. + */ + public static final void toggle(final Player player, final boolean on) { + open = on ? true : false; + player.getPacketDispatch().sendMessage(getToggleMessage()); + if (!open) { + for (Player p : RegionManager.getLocalPlayers(center)) { + if (p == null || p.getDetails().getRights() == Rights.ADMINISTRATOR) { + continue; + } + home(p); + } + } + } + + /** + * Method used to get the togglemessage. + * @return the message. + */ + public static final String getToggleMessage() { + return "The moderator room is currently " + (open ? "available" : "not available") + " to player moderators."; + } + + /** + * Method used to send a player home. + * @param player the player. + */ + public static final void home(final Player player) { + player.getTeleporter().send(ServerConstants.HOME_LOCATION, TeleportType.NORMAL); + } + + /** + * Method used to teleport a player into the zone. + * @param player the player. + */ + public static final void teleport(final Player player) { + player.getTeleporter().send(center, TeleportType.NORMAL); + } + + /** + * Method used to check if the moderator zone is open. + * @return return True if so. + */ + public static boolean isOpen() { + if (!open) { + return false; + } + return true; + } + +} diff --git a/Server/src/main/core/game/world/map/zone/impl/MultiwayCombatZone.java b/Server/src/main/core/game/world/map/zone/impl/MultiwayCombatZone.java new file mode 100644 index 0000000..77477b3 --- /dev/null +++ b/Server/src/main/core/game/world/map/zone/impl/MultiwayCombatZone.java @@ -0,0 +1,156 @@ +package core.game.world.map.zone.impl; + +import core.game.node.entity.Entity; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.player.Player; +import core.game.world.map.Direction; +import core.game.world.map.Location; +import core.game.world.map.MapDistance; +import core.game.world.map.RegionManager; +import core.game.world.map.path.Pathfinder; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBorders; +import core.net.packet.PacketRepository; +import core.net.packet.context.InterfaceContext; +import core.net.packet.out.CloseInterface; +import core.net.packet.out.Interface; + +/** + * Handles the multiway combat zones. + * @author Emperor + */ +public final class MultiwayCombatZone extends MapZone { + + /** + * The instance. + */ + private static final MultiwayCombatZone INSTANCE = new MultiwayCombatZone(); + + /** + * Constructs a new {@code MultiwayCombatZone} {@code Object}. + */ + private MultiwayCombatZone() { + super("Multicombat", true); + } + + @Override + public void configure() { + register(new ZoneBorders(3210, 9333, 3339, 9424)); + register(new ZoneBorders(2607, 3296, 2644, 3332)); + register(new ZoneBorders(2949, 3370, 3001, 3392)); + register(new ZoneBorders(3250, 9800, 3342, 9870)); + register(new ZoneBorders(3190, 3648, 3327, 3839)); + register(new ZoneBorders(3200, 3840, 3390, 3967)); + register(new ZoneBorders(2992, 3912, 3007, 3967)); + register(new ZoneBorders(2946, 3816, 2959, 3831)); + register(new ZoneBorders(3008, 3856, 3199, 3903)); + register(new ZoneBorders(3008, 3600, 3071, 3711)); + register(new ZoneBorders(3072, 3608, 3327, 3647)); + register(new ZoneBorders(2624, 2550, 2690, 2619)); + register(new ZoneBorders(2371, 5062, 2422, 5117)); + register(new ZoneBorders(2896, 3595, 2927, 3630)); + register(new ZoneBorders(2820, 5250, 2955, 5370)); + register(new ZoneBorders(2892, 4435, 2932, 4464)); + register(new ZoneBorders(2724, 5071, 2747, 5109)); + register(new ZoneBorders(2256, 4680, 2287, 4711)); + register(new ZoneBorders(3107, 3234, 3134, 3259)); + register(new ZoneBorders(2931, 3514, 2940, 3518)); + register(new ZoneBorders(2869, 3687, 2940, 3839)); + register(new ZoneBorders(1728, 5120, 1791, 5247)); + register(new ZoneBorders(3136, 3523, 3328, 3710)); + registerRegion(13105, new ZoneBorders(3282, 3159, 3303, 3177)); + registerRegion(12341); + // Kalphite queen lair + registerRegion(13972); + // Abbys area + registerRegion(12107); + registerRegion(7505); + // Rock crabs. + registerRegion(10554); + // Wizard's tower + registerRegion(12337); + // zmi + registerRegion(13131); + // Kraken + registerRegion(14682); + //top of GE + register(new ZoneBorders(3154, 3483, 3176, 3500, 2)); + // Tzhaar caves + register(new ZoneBorders(2424, 5105, 2536, 5183)); + register(new ZoneBorders(2487, 10113, 2563, 10174)); + registerRegion(7236); + registerRegion(7492); + registerRegion(7748); + registerRegion(12610); + register(new ZoneBorders(3097, 4224, 3225, 4317)); + register(new ZoneBorders(3116, 5412, 3362, 5584)); + register(new ZoneBorders(3078, 5520, 3123, 5552, 0)); + // Ice queen + register(new ZoneBorders(2855, 9928, 2880, 9968)); + registerRegion(11318); //White wolf mountain + registerRegion(11844); //Corporeal beast + registerRegion(10329);//TDS + registerRegion(13370);//Venenatis + registerRegion(12603);//Callisto + registerRegion(14939);//Kalphite Stronghold Cave + registerRegion(9532); //Isle north of Jatizso + registerRegion(10810); //Eastern rock crabs + registerRegion(12590); //desert bandits + } + + @Override + public boolean enter(Entity e) { + if (e instanceof Player) { + Player p = (Player) e; + boolean resizable = p.getInterfaceManager().isResizable(); + PacketRepository.send(Interface.class, new InterfaceContext(p, p.getInterfaceManager().getWindowPaneId(), resizable ? 17 : 7, 745, true)); + p.getPacketDispatch().sendInterfaceConfig(745, 1, false); + } + e.getProperties().setMultiZone(true); + return super.enter(e); + } + + @Override + public boolean leave(Entity e, boolean logout) { + if (!logout && e instanceof Player) { + Player p = (Player) e; + boolean resizable = p.getInterfaceManager().isResizable(); + PacketRepository.send(CloseInterface.class, new InterfaceContext(p, p.getInterfaceManager().getWindowPaneId(), resizable ? 17 : 7, 745, true)); + } + e.getProperties().setMultiZone(false); + return super.leave(e, logout); + } + + @Override + public boolean move(Entity e, Location loc, Location destination) { + // Disables "NPC stacking". + if (e.getProperties().isNPCWalkable()) { + return true; + } + for (NPC n : RegionManager.getLocalNpcs(e, MapDistance.RENDERING.getDistance() / 2)) { + if (n.isInvisible() || !n.getDefinition().hasAttackOption() || n == e) { + continue; + } + if(n.shouldPreventStacking(e)) { + int s1 = e.size(); + int s2 = n.size(); + int x = destination.getX(); + int y = destination.getY(); + Location l = n.getLocation(); + if(Pathfinder.isStandingIn(x, y, s1, s1, l.getX(), l.getY(), s2, s2)) { + return false; + } + } + } + return true; + } + + /** + * Gets the instance. + * @return The instance. + */ + public static MultiwayCombatZone getInstance() { + return INSTANCE; + } + +} diff --git a/Server/src/main/core/game/world/map/zone/impl/WildernessZone.java b/Server/src/main/core/game/world/map/zone/impl/WildernessZone.java new file mode 100644 index 0000000..c06ba08 --- /dev/null +++ b/Server/src/main/core/game/world/map/zone/impl/WildernessZone.java @@ -0,0 +1,336 @@ +package core.game.world.map.zone.impl; + +import content.global.handlers.item.equipment.brawling_gloves.BrawlingGloves; +import content.global.skill.summoning.familiar.Familiar; +import core.game.component.Component; +import core.game.interaction.Option; +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.npc.NPC; +import core.game.node.entity.npc.agg.AggressiveBehavior; +import core.game.node.entity.npc.agg.AggressiveHandler; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.info.Rights; +import core.game.node.entity.player.link.SkullManager; +import core.game.node.item.GroundItemManager; +import core.game.node.item.Item; +import core.game.world.GameWorld; +import core.game.world.map.Location; +import core.game.world.map.zone.MapZone; +import core.game.world.map.zone.ZoneBorders; +import core.game.world.map.zone.ZoneRestriction; +import core.game.world.repository.Repository; +import core.tools.RandomFunction; +import org.rs09.consts.Items; +import org.rs09.consts.NPCs; + + +/** + * Handles the wilderness zone. + * @author Emperor + */ +public final class WildernessZone extends MapZone { + /** + * The PvP gear items + */ + private static int[] PVP_GEAR = { 13887, 13893, 13899, 13905, 13870, 13873, 13876, 13879, 13883, 13884, 13890, 13896, 13902, 13858, 13861, 13864, 13867}; + + /** + * The wilderness zone. + */ + private static final WildernessZone INSTANCE = new WildernessZone(new ZoneBorders(2944, 3525, 3400, 3975), new ZoneBorders(3070, 9924, 3135, 10002), ZoneBorders.forRegion(12192), ZoneBorders.forRegion(12193), ZoneBorders.forRegion(11937)); + + public static final String WILDERNESS_PROT_ATTR = "/save:wilderness-protection-active"; + public static final String WILDERNESS_HIGHER_NEXTFEE = "/save:wilderness-higher-next-fee"; + + /** + * The zone borders. + */ + private ZoneBorders[] borders; + + /** + * Constructs a new {@code WildernessZone} {@code Object}. + */ + public WildernessZone(ZoneBorders... borders) { + super("Wilderness", true, ZoneRestriction.RANDOM_EVENTS); + this.borders = borders; + } + + @Override + public void configure() { + for (ZoneBorders border : borders) { + register(border); + } + } + + /** + * calculate drop rate for rev items based on combat level + * @author ceik + * @param combatLevel + * @return + */ + public int getNewDropRate(int combatLevel){ + double x = combatLevel; + double A = 44044.5491; + double B = -7360.19548; + return (int) (A + (B * Math.log(x))); + } + + /** + * Handles rev drops + * @author ceik + * @param e The entity dying. + * @param killer The killer. + * @return true + */ + @Override + public boolean death(Entity e, Entity killer) { + if (e instanceof NPC) + rollWildernessExclusiveLoot(e, killer); + return false; //DONT override default death handling. + } + + private void rollWildernessExclusiveLoot(Entity e, Entity killer) { + if (!(killer instanceof Player)) return; + if (!(e instanceof NPC)) return; + if (!(e.getId() == NPCs.CHAOS_ELEMENTAL_3200 || e.asNpc().getName().contains("Revenant"))) return; + + int pvpGearRate = getNewDropRate(e.asNpc().getDefinition().getCombatLevel()); + boolean higherRate = ((Player) killer).getSkullManager().isDeepWilderness() && ((Player) killer).getAttribute("deepwild-value-risk", 0L) > SkullManager.DEEP_WILD_DROP_RISK_THRESHOLD; + if (higherRate) { + pvpGearRate /= 2; + } + int cEleGloveRate = 50; + int normalGloveRate = higherRate ? 100 : (int) ((1.0 / (1.0 - Math.pow(1.0 - (1.0 / (double) pvpGearRate), 16.0))) * 5.0 / 6.0); + + if (RandomFunction.roll(e.getId() == NPCs.CHAOS_ELEMENTAL_3200 ? cEleGloveRate : normalGloveRate)) { + byte glove = (byte) RandomFunction.random(1, 14); + Item reward = new Item(BrawlingGloves.forIndicator(glove).getId()); + GroundItemManager.create(reward, e.asNpc().getDropLocation(), killer.asPlayer()); + Repository.sendNews(killer.getUsername() + " has received " + reward.getName().toLowerCase() + " from a " + e.asNpc().getName() + "!"); + } + for (int j : PVP_GEAR) { + boolean chance = RandomFunction.roll(pvpGearRate); + if (chance) { + Item reward; + if (j == Items.MORRIGANS_JAVELIN_13879 || j == Items.MORRIGANS_THROWING_AXE_13883) { + reward = new Item(j, RandomFunction.random(15, 50)); + } else { + reward = new Item(j); + } + GroundItemManager.create(reward, ((NPC) e).getDropLocation(), killer.asPlayer()); + Repository.sendNews(killer.asPlayer().getUsername() + " has received a " + reward.getName() + " from a " + e.asNpc().getName() + "!"); + } + } + } + + /** + * Fixes attack options for the revs + * @param e The entity. + * @param target The target to interact with. + * @param option The option. + * @return true + */ + @Override + public boolean interact(Entity e, Node target, Option option) { + if(target instanceof NPC){ + if(target.asNpc().getName().contains("Revenant")){ + e.asPlayer().getProperties().getCombatPulse().attack(target); + return true; + } + } + return super.interact(e, target, option); + } + + @Override + public boolean enter(Entity e) { + if (e instanceof Player) { + Player p = (Player) e; + if(!p.isArtificial()) { + show(p); + } else { + p.getSkullManager().setWilderness(true); + p.getSkullManager().setLevel(getWilderness(p)); + } + for (int i = 0; i < 7; i++) { + if (i == 5 || i == 3) { + continue; + } + if(p.getAttributes().containsKey("overload") || p.getSkills().getLevel(i) > 118){ + if (p.getSkills().getLevel(i) > p.getSkills().getStaticLevel(i)) { + p.getSkills().setLevel(i, p.getSkills().getStaticLevel(i)); + p.removeAttribute("overload"); + } + } + } + if (p.getFamiliarManager().hasFamiliar() && !p.getFamiliarManager().hasPet()) { + Familiar familiar = p.getFamiliarManager().getFamiliar(); + familiar.transform(); + } + p.getAppearance().sync(); + } else if (e instanceof NPC) { + NPC n = (NPC) e; + if (n.getDefinition().hasAttackOption() && n.isAggressive()) { + //n.setAggressive(true); + n.setAggressiveHandler(new AggressiveHandler(n, AggressiveBehavior.WILDERNESS)); + } + } + return true; + } + + @Override + public boolean leave(Entity e, boolean logout) { + if (!logout && e instanceof Player) { + Player p = (Player) e; + leave(p); + if (p.getFamiliarManager().hasFamiliar() && !p.getFamiliarManager().hasPet()) { + Familiar familiar = p.getFamiliarManager().getFamiliar(); + if (familiar.isCombatFamiliar()) { + familiar.reTransform(); + } + } + p.getAppearance().sync(); + } + return true; + } + + /** + * Method used to remove traces of being in the zone. + * @param p the player. + */ + public final void leave(final Player p) { + Component overlay = new Component(381); + if (overlay.getId() == 381) { + p.getInterfaceManager().close(overlay); + } + p.getInteraction().remove(Option._P_ATTACK); + p.getSkullManager().setWilderness(false); + p.getSkullManager().setLevel(0); + } + + /** + * Method used to show being the wilderness. + * @param p the player. + */ + public static final void show(final Player p) { + if (p.getSkullManager().isWildernessDisabled()) { + return; + } + p.getInterfaceManager().openOverlay(new Component(381)); + p.getSkullManager().setLevel(getWilderness(p)); + p.getPacketDispatch().sendString("Level: " + p.getSkullManager().getLevel(), 381, 1); + if(GameWorld.getSettings().getWild_pvp_enabled()) { + p.getInteraction().set(Option._P_ATTACK); + } + p.getSkullManager().setWilderness(true); + } + + @Override + public boolean teleport(Entity e, int type, Node node) { + if (e instanceof Player) { + Player p = (Player) e; + if (p.getDetails().getRights() == Rights.ADMINISTRATOR) { + return true; + } + if (!checkTeleport(p, (node != null && node instanceof Item && (((Item) node).getName().contains("glory") || ((Item) node).getName().contains("slaying")) ? 30 : 20))) { + return false; + } + } + return true; + } + + /** + * Method used to check if a player can teleport past a level. + * @param p the player. + * @param level the level. + * @return {@code True} if they can teleport. + */ + public static boolean checkTeleport(Player p, int level) { + if (p.getSkullManager().getLevel() > level && !p.getSkullManager().isWildernessDisabled()) { + message(p, "You can't teleport this deep in the wilderness!"); + return false; + } + return true; + } + + @Override + public boolean continueAttack(Entity e, Node target, CombatStyle style, boolean message) { + if (e instanceof Player && target instanceof Player) { + Player p = (Player) e; + Player t = (Player) target; + int level = p.getSkullManager().getLevel(); + if (t.getSkullManager().getLevel() < level) { + level = t.getSkullManager().getLevel(); + } + int combat = p.getProperties().getCurrentCombatLevel(); + int targetCombat = t.getProperties().getCurrentCombatLevel(); + if (combat - level > targetCombat || combat + level < targetCombat) { + if (message) { + p.getPacketDispatch().sendMessage("The level difference between you and your opponent is too great."); + } + return false; + } + } + return true; + } + + @Override + public void locationUpdate(Entity e, Location last) { + if (e instanceof Player && !e.asPlayer().isArtificial()) { + Player p = (Player) e; + p.getSkullManager().setLevel(getWilderness(p)); + } + } + + /** + * Checks if the entity is inside the wilderness. + * @param e The entity. + * @return {@code True} if so. + */ + public static boolean isInZone(Entity e) { + Location l = e.getLocation(); + for (ZoneBorders z : INSTANCE.borders) { + if (z.insideBorder(e)) + return true; + } + return false; + } + + public static boolean isInZone (Location l) { + for (ZoneBorders z : INSTANCE.borders) { + if (z.insideBorder(l)) return true; + } + return false; + } + + /** + * The wilderness level. + * @return the level. + */ + public static int getWilderness(Entity e) { + int y = e.getLocation().getY(); + if(6400 < y) { + return ((y - 9920) / 8) + 1; + } else { + return ((y - 3520) / 8) + 1; + } + } + + /** + * Gets the zone borders. + * @return The borders. + */ + public ZoneBorders[] getBorders() { + return borders; + } + + /** + * Gets the instance. + * @return The instance. + */ + public static WildernessZone getInstance() { + return INSTANCE; + } + +} diff --git a/Server/src/main/core/game/world/objectparser/ObjectParser.java b/Server/src/main/core/game/world/objectparser/ObjectParser.java new file mode 100644 index 0000000..39b445e --- /dev/null +++ b/Server/src/main/core/game/world/objectparser/ObjectParser.java @@ -0,0 +1,101 @@ +package core.game.world.objectparser; + +import core.api.StartupListener; +import core.ServerConstants; +import core.game.node.scenery.Scenery; +import core.game.world.map.build.LandscapeParser; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import java.io.File; + +public class ObjectParser implements StartupListener { + + public void parseObjects(){ + if(ServerConstants.OBJECT_PARSER_PATH == null) return; + File f = new File(ServerConstants.OBJECT_PARSER_PATH); + if(!f.exists()){ + + return; + } + + try{ + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + Document doc = builder.parse(f); + + NodeList parseList = doc.getElementsByTagName("ObjectAction"); + + + + for(int i = 0; i < parseList.getLength(); i++){ + Node parseNode = parseList.item(i); + if(parseNode.getNodeType() == Node.ELEMENT_NODE){ + Element parseElement = (Element) parseNode; + String type = parseElement.getAttribute("mode"); + switch(type){ + case "add": { + int id = Integer.parseInt(parseElement.getAttribute("id")); + int x = Integer.parseInt(parseElement.getAttribute("x")); + int y = Integer.parseInt(parseElement.getAttribute("y")); + int z = Integer.parseInt(parseElement.getAttribute("z")); + int objType = 10; + if (parseElement.hasAttribute("type")) { + objType = Integer.parseInt(parseElement.getAttribute("type")); + } + String rawDir = parseElement.getAttribute("direction"); + int dir = 1; + switch (rawDir) { + case "n": + dir = 1; + break; + case "ne": + dir = 2; + break; + case "nw": + dir = 0; + break; + case "w": + dir = 3; + break; + case "e": + dir = 4; + break; + case "sw": + dir = 5; + break; + case "se": + dir = 7; + break; + case "s": + dir = 6; + break; + } + LandscapeParser.addScenery(new Scenery(id, x, y, z, objType, dir)); + break; + } + case "remove": { + int id = Integer.parseInt(parseElement.getAttribute("id")); + int x = Integer.parseInt(parseElement.getAttribute("x")); + int y = Integer.parseInt(parseElement.getAttribute("y")); + int z = Integer.parseInt(parseElement.getAttribute("z")); + int objType = 10; + LandscapeParser.removeScenery(new Scenery(id,x,y,z)); + } + } + } + } + } catch (Exception e){ + e.printStackTrace(); + } + } + + @Override + public void startup() { + parseObjects(); + } +} diff --git a/Server/src/main/core/game/world/repository/DisconnectionQueue.kt b/Server/src/main/core/game/world/repository/DisconnectionQueue.kt new file mode 100644 index 0000000..dd0c7ee --- /dev/null +++ b/Server/src/main/core/game/world/repository/DisconnectionQueue.kt @@ -0,0 +1,144 @@ +package core.game.world.repository + +import core.api.log +import core.game.node.entity.player.Player +import core.game.node.entity.player.info.login.PlayerParser +import core.game.system.task.TaskExecutor +import core.game.world.GameWorld +import core.tools.Log +import core.tools.secondsToTicks + +/** + * Handles disconnecting players queuing. + * @author Emperor + */ +class DisconnectionQueue { + /**A + * The pending disconnections queue. + */ + private val queue = HashMap() + private val queueTimers = HashMap() + + /** + * Updates all entries. + */ + fun update() { + if (queue.isEmpty() || GameWorld.ticks % 3 != 0) { + return + } + //make a copy of current entries as to avoid concurrency exceptions + val entries = ArrayList(queue.entries) + + //loop through entries and disconnect each + entries.forEach { + if(finish(it.value,false)) queue.remove(it.key) + else { + //Make sure there's no room for the disconnection queue to stroke out and leave someone logged in for 10 years. + queueTimers[it.key] = (queueTimers[it.key] ?: 0) + 3 + val isValidAFKLogout = it.value?.player?.isAfkLogout == true + val seconds = if (isValidAFKLogout) 30 else 5 * 60 //30 seconds for AFK logout, 5 minutes for normal logout + val ticksNeeded = secondsToTicks(seconds) + if ((queueTimers[it.key] ?: Int.MAX_VALUE) >= ticksNeeded) { + it.value?.player?.let { player -> + player.finishClear() + Repository.removePlayer(player) + remove(it.key) + log(this::class.java, Log.WARN, "Force-clearing ${it.key} after 15 minutes of being in the disconnection queue!") + } + } + } + } + } + + + fun isEmpty(): Boolean{ + return queue.isEmpty() + } + + /** + * Finishes a disconnection. + * @param entry The entry. + * @param force If finalization should be forced. + */ + private fun finish(entry: DisconnectionEntry?, force: Boolean): Boolean { + val player = entry!!.player + if (!force && !player.allowRemoval()) { + return false + } + player.packetDispatch.sendLogout() + player.finishClear() + Repository.removePlayer(player) + try { + if(player.communication.clan != null) + player.communication.clan.leave(player, false) + } catch (e: Exception) { + e.printStackTrace() + } + if (player.isArtificial) { + return true + } + if (!force) { + TaskExecutor.executeSQL { + Thread.currentThread().name = "PlayerSave SQL" + save(player, true) + } + log(this::class.java, Log.INFO, "Player cleared. Removed ${player.details.username}.") + return true + } + save(player, false) + log(this::class.java, Log.INFO, "Player cleared. Removed ${player.details.username}.") + return true + } + + /** + * Gets a queued player. + * @param name The player name. + * @return The player instance. + */ + operator fun get(name: String?): Player? { + val entry = queue[name] + return entry?.player + } + + /** + * Clears the queue. + */ + fun clear() { + for (entry in queue.values.toTypedArray()) { + finish(entry, true) + } + queue.clear() + } + + @JvmOverloads + fun add(player: Player, clear: Boolean = false) { + if(queue[player.name] != null) return + queue[player.name] = DisconnectionEntry(player, clear) + log(this::class.java, Log.INFO, "Queueing ${player.name} for disconnection.") + } + + operator fun contains(name: String?): Boolean { + return queue.containsKey(name) + } + + fun remove(name: String?) { + queue.remove(name) + queueTimers.remove(name) + } + + internal data class DisconnectionEntry(val player: Player, var isClear: Boolean) {} + + /** + * Saves the player. + * @param player The player to be saved. + * @param sql If the sql database should be updated. + */ + fun save(player: Player, sql: Boolean): Boolean { + try { + PlayerParser.saveImmediately(player) + } catch (t: Throwable) { + t.printStackTrace() + } + return false + } +} diff --git a/Server/src/main/core/game/world/repository/InitializationEntry.java b/Server/src/main/core/game/world/repository/InitializationEntry.java new file mode 100644 index 0000000..e5b86da --- /dev/null +++ b/Server/src/main/core/game/world/repository/InitializationEntry.java @@ -0,0 +1,88 @@ +package core.game.world.repository; + +import core.game.node.Node; + +/** + * Wraps around a node to represent its entry in a queue. + * @author Emperor + */ +public class InitializationEntry { + + /** + * The node. + */ + private final Node node; + + /** + * If the node is being removed from the game, rather than added. + */ + private boolean removal; + + /** + * Constructs a new {@code InitializationEntry} {@code Object}. + * @param node The node. + */ + public InitializationEntry(Node node) { + this(node, false); + } + + /** + * Constructs a new {@code InitializationEntry} {@code Object}. + * @param node The node. + * @param removal If the node should be removed from the game, rather than + * added. + */ + public InitializationEntry(Node node, boolean removal) { + this.node = node; + this.removal = removal; + } + + /** + * Initializes the node. + * @return The node instance. + */ + public Node initialize() { + node.setActive(true); + return node; + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof InitializationEntry)) { + return false; + } + return ((InitializationEntry) o).node.equals(node); + } + + @Override + public int hashCode() { + if (node != null) { + return node.hashCode(); + } + return super.hashCode(); + } + + /** + * Gets the node. + * @return The node. + */ + public Node getNode() { + return node; + } + + /** + * Gets the removal. + * @return The removal. + */ + public boolean isRemoval() { + return removal; + } + + /** + * Sets the removal. + * @param removal The removal to set. + */ + public void setRemoval(boolean removal) { + this.removal = removal; + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/world/repository/InitializingNodeList.java b/Server/src/main/core/game/world/repository/InitializingNodeList.java new file mode 100644 index 0000000..1d227ec --- /dev/null +++ b/Server/src/main/core/game/world/repository/InitializingNodeList.java @@ -0,0 +1,64 @@ +package core.game.world.repository; + +import core.game.node.Node; + +import java.util.ArrayList; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; + +/** + * A node list implementation backed by an initialization queue. + * @author Emperor + */ +public final class InitializingNodeList extends ArrayList { + + /** + * The serial UID. + */ + private static final long serialVersionUID = 7727358901001709156L; + + /** + * The queue. + */ + private final Queue queue = new ConcurrentLinkedQueue<>(); + + /** + * Constructs a new {@code InitializingNodeList} {@code Object}. + */ + public InitializingNodeList() { + super(); + } + + /** + * Synchronizes the backing queue with this list. + */ + @SuppressWarnings("unchecked") + public void sync() { + while (!queue.isEmpty()) { + InitializationEntry entry = queue.poll(); + if (entry.isRemoval()) { + super.remove(entry.getNode()); + entry.getNode().setRenderable(false); + } else { + Node n = entry.initialize(); + if (n != null) { + super.add((T) n); + n.setRenderable(true); + } + } + } + } + + @Override + public boolean add(T node) { + return !contains(node) && queue.add(new InitializationEntry(node, false)); + } + + @Override + public boolean remove(Object node) { + if (!contains(node)) { + return false; + } + return queue.add(new InitializationEntry((Node) node, true)); + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/world/repository/NodeList.java b/Server/src/main/core/game/world/repository/NodeList.java new file mode 100644 index 0000000..c55f249 --- /dev/null +++ b/Server/src/main/core/game/world/repository/NodeList.java @@ -0,0 +1,231 @@ +package core.game.world.repository; + +import core.game.node.Node; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; + +/** + * A class which represents a list of nodes. + * @author Graham Edgecombe + * @author Emperor + * @param The type of Node. + */ +public class NodeList implements Collection, Iterable { + + /** + * Internal nodes array. + */ + private Node[] nodes; + + /** + * Current size. + */ + private int size = 0; + + /** + * Creates a Node list with the specified capacity. + * @param capacity The capacity. + */ + public NodeList(int capacity) { + nodes = new Node[capacity + 1]; // do not use idx 0 + } + + /** + * Gets an Node. + * @param index The index. + * @return The Node. + * @throws IndexOutOufBoundException if the index is out of bounds. + */ + @SuppressWarnings("unchecked") + public E get(int index) { + synchronized (this) { + if (index <= 0 || index >= nodes.length) { + throw new IndexOutOfBoundsException(); + } + return (E) nodes[index]; + } + } + + /** + * Gets the index of an Node. + * @return The index in the list. + */ + public int indexOf(Node node) { + return node.getIndex(); + } + + /** + * Gets the next free id. + * @return The next free id. + */ + private int getNextId() { + for (int i = 1; i < nodes.length; i++) { + if (nodes[i] == null) { + return i; + } + } + return -1; + } + + @Override + public boolean add(E arg0) { + synchronized (this) { + int id = getNextId(); + if (id == -1) { + return false; + } + nodes[id] = arg0; + arg0.setIndex(id); + size++; + return true; + } + } + + @Override + public boolean addAll(Collection arg0) { + synchronized (this) { + boolean changed = false; + for (E node : arg0) { + if (add(node)) { + changed = true; + } + } + return changed; + } + } + + @Override + public void clear() { + synchronized (this) { + for (int i = 1; i < nodes.length; i++) { + nodes[i] = null; + } + size = 0; + } + } + + @Override + public boolean contains(Object arg0) { + synchronized (this) { + for (int i = 1; i < nodes.length; i++) { + if (nodes[i] == arg0) { + return true; + } + } + } + return false; + } + + @Override + public boolean containsAll(Collection arg0) { + boolean failed = false; + for (Object o : arg0) { + if (!contains(o)) { + failed = true; + } + } + return !failed; + } + + @Override + public boolean isEmpty() { + return size() == 0; + } + + @Override + public Iterator iterator() { + return new NodeListIterator(this); + } + + /** + * Removes the node on this index. + * @param index The index. + * @return {@code True} if a node got removed. + */ + public boolean remove(int index) { + synchronized (this) { + Node n = nodes[index]; + if (n != null) { + size--; + nodes[index] = null; + } + return n != null; + } + } + + @Override + public boolean remove(Object arg0) { + synchronized (this) { + for (int i = 1; i < nodes.length; i++) { + if (nodes[i] == arg0) { + nodes[i] = null; + size--; + return true; + } + } + return false; + } + } + + @Override + public boolean removeAll(Collection arg0) { + synchronized (this) { + boolean changed = false; + for (Object o : arg0) { + if (remove(o)) { + changed = true; + } + } + return changed; + } + } + + @Override + public boolean retainAll(Collection arg0) { + synchronized (this) { + boolean changed = false; + for (int i = 1; i < nodes.length; i++) { + if (nodes[i] != null) { + if (!arg0.contains(nodes[i])) { + nodes[i] = null; + size--; + changed = true; + } + } + } + return changed; + } + } + + @Override + public int size() { + return size; + } + + public int length(){ return nodes.length;} + + @Override + public Node[] toArray() { + synchronized (this) { + int size = size(); + Node[] array = new Node[size]; + int ptr = 0; + for (int i = 1; i < nodes.length; i++) { + if (nodes[i] != null) { + array[ptr++] = nodes[i]; + } + } + return array; + } + } + + @SuppressWarnings("unchecked") + @Override + public T[] toArray(T[] arg0) { + Node[] arr = toArray(); + return (T[]) Arrays.copyOf(arr, arr.length, arg0.getClass()); + } + +} diff --git a/Server/src/main/core/game/world/repository/NodeListIterator.java b/Server/src/main/core/game/world/repository/NodeListIterator.java new file mode 100644 index 0000000..5f12569 --- /dev/null +++ b/Server/src/main/core/game/world/repository/NodeListIterator.java @@ -0,0 +1,80 @@ +package core.game.world.repository; + +import core.game.node.Node; + +import java.util.Iterator; +import java.util.NoSuchElementException; + +/** + * An implementation of an iterator for a node list. + * @author Graham Edgecombe + * @author Emperor + * @param The type of node. + */ +public class NodeListIterator implements Iterator { + + /** + * The nodes. + */ + private Node[] nodes; + + /** + * The entity list. + */ + private NodeList entityList; + + /** + * The previous index. + */ + private int lastIndex = -1; + + /** + * The current index. + */ + private int cursor = 0; + + /** + * The size of the list. + */ + private int size; + + /** + * Creates an node list iterator. + * @param nodeList The node list. + */ + public NodeListIterator(NodeList nodeList) { + this.entityList = nodeList; + nodes = nodeList.toArray(new Node[0]); + size = nodes.length; + } + + @Override + public boolean hasNext() { + while (cursor < size) { + if (nodes[cursor] != null) { + return true; + } + cursor++; + } + return false; + } + + @SuppressWarnings("unchecked") + @Override + public E next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } + lastIndex = cursor++; + return (E) nodes[lastIndex]; + } + + @Override + public void remove() { + if (lastIndex == -1) { + throw new IllegalStateException(); + } + entityList.remove(nodes[lastIndex]); + } + +} diff --git a/Server/src/main/core/game/world/repository/Repository.kt b/Server/src/main/core/game/world/repository/Repository.kt new file mode 100644 index 0000000..575bcb0 --- /dev/null +++ b/Server/src/main/core/game/world/repository/Repository.kt @@ -0,0 +1,206 @@ +package core.game.world.repository + +import core.game.node.entity.npc.NPC +import content.region.wilderness.handlers.revenants.RevenantNPC +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.game.world.map.RegionManager +import core.ServerConstants +import core.game.world.update.UpdateSequence +import java.util.* +import java.util.concurrent.CopyOnWriteArrayList + +/** + * The repository holding all node lists, etc in the game world. + * @author Emperor + */ +object Repository { + /** + * Represents the repository of active players. + */ + @JvmStatic + val players = NodeList(ServerConstants.MAX_PLAYERS) + val uid_map = HashMap(ServerConstants.MAX_PLAYERS) + + /** + * Represents the repository of active npcs. + */ + @JvmStatic + val npcs = NodeList(ServerConstants.MAX_NPCS) + + /** + * List of player names who have logged in, quick and dirty work-around for the double-logging issue. + * This list needs to have values added to it before any sort of parsing is done for the login process due + * to the time it takes for the parsing to occur, which is the root of this issue to begin with. + */ + val LOGGED_IN_PLAYERS: MutableList = ArrayList(ServerConstants.MAX_PLAYERS) + + /** + * The renderable NPCs. + */ + public val RENDERABLE_NPCS: MutableList = CopyOnWriteArrayList() + + /** + * A mapping holding the players sorted by their names. + */ + @JvmStatic + val playerNames: MutableMap = HashMap() + /** + * Represents the list of players in lobby. + */ + @JvmStatic + val lobbyPlayers: MutableList = ArrayList() + /** + * The disconnection queue. + */ + @JvmStatic + val disconnectionQueue = DisconnectionQueue() + /** + * Sends a market update message to all players. + * @param string The string. + * @param color The color. + */ + @JvmOverloads + fun sendMarketUpdate(string: String, icon: Int = 12, color: String = "") { + val players: Array = playerNames.values.toTypedArray() + val size = players.size + for (i in 0 until size) { + val player = players[i] as Player ?: continue + player.sendMessage("" + color + "Market Update: " + string) + } + } + /** + * Send a news message to all players. + * @param string The string. + * @param icon The icon. + */ + @JvmStatic + fun sendNews(string: String, icon: Int = 12, color: String = "CC6600") { + val players: Array = playerNames.values.toTypedArray() + val size = players.size + for (i in 0 until size) { + val player = players[i] as Player ?: continue + player.sendMessage("News: $string") + } + } + + /** + * This is another sendnews method which redirects to the one above. + * This needs to exist because java fails to recognize default arguments in Kotlin methods.... + * I fucking hate java. + */ + @JvmStatic + @Deprecated("Old and bad",ReplaceWith("sendNews()"),DeprecationLevel.WARNING) + fun sendNews(string: String){ + sendNews(string,12) + } + + /** + * Adds a renderable NPC. + * @param npc The NPC. + */ + @JvmStatic + fun addRenderableNPC(npc: NPC) { + if (npc is RevenantNPC) return // hack to make sure we can update revenants every tick. + if (!RENDERABLE_NPCS.contains(npc)) { + RENDERABLE_NPCS.add(npc) + npc.isRenderable = true + } + } + + /** + * Removes an NPC from rendering. + * @param npc The NPC. + */ + @JvmStatic + fun removeRenderableNPC(npc: NPC) { + if (npc is RevenantNPC) return // hack to make sure we can update revenants every tick. + RENDERABLE_NPCS.remove(npc) + npc.isRenderable = false + } + + /** + * Finds the NPC on the given location. + * @param l The location. + * @return The NPC, or `null` if the NPC wasn't found. + */ + @JvmStatic + fun findNPC(l: Location): NPC? { + for (n in RegionManager.getRegionPlane(l).npcs) { + if (n.location == l) { + return n + } + } + return null + } + + @JvmStatic + fun addPlayer(player: Player){ + if (players.isNotEmpty()) { + for (i in 1 until players.size) { + players[i] ?: continue + if (players[i].details.uid == player.details.uid) { + val oldPl = players[i] + players.remove(oldPl) + oldPl.clear() + break + } + } + } + players.add(player) + uid_map[player.details.uid] = player + playerNames[player.name] = player + } + + @JvmStatic + fun removePlayer(player: Player){ + players.remove(player) + uid_map.remove(player.details.uid) + playerNames.remove(player.name) + UpdateSequence.renderablePlayers.remove(player) + player.session.disconnect() + } + + /** + * Find a non-player character. + * @param npcId The non-player character's id. + * @return The non-player character's node. + */ + @JvmStatic + fun findNPC(npcId: Int): NPC? { + for (npc in npcs) { + if (npc == null) { + continue + } + if (npc.id == npcId) { + return npc + } + } + return null + } + + /** + * Get a player by its username. + * @param name The player's **username**. + * @return The player. + */ + @JvmStatic + fun getPlayerByName(name: String?): Player? { + return if (name == null) { + null + } else playerNames[name.toLowerCase().replace(" ".toRegex(), "_")] + } + + @JvmStatic + fun getPlayerByUid(uid: Int) : Player? { + return uid_map[uid] + } + + /** + * Gets the renderableNpcs. + * @return The renderableNpcs. + */ + @JvmStatic + val renderableNpcs: List + get() = RENDERABLE_NPCS +} diff --git a/Server/src/main/core/game/world/update/MapChunkRenderer.kt b/Server/src/main/core/game/world/update/MapChunkRenderer.kt new file mode 100644 index 0000000..b9e2011 --- /dev/null +++ b/Server/src/main/core/game/world/update/MapChunkRenderer.kt @@ -0,0 +1,70 @@ +package core.game.world.update + +import core.game.node.entity.player.Player +import core.game.world.map.RegionChunk +import core.net.packet.PacketRepository +import core.net.packet.context.ClearChunkContext +import core.net.packet.out.ClearRegionChunk +import java.util.* + +/** + * Handles the rendering of the player's surrounding map chunks. + * @author Emperor + */ +object MapChunkRenderer { + /** + * Sends the map chunk rendering packet. + * @param player The player. + */ + @JvmStatic + fun render(player: Player) { + val v = player.viewport + val last = player.playerFlags.lastViewport + val updated: MutableList = ArrayList() + val current = v.chunks + var sizeX = last.size + for (x in 0 until sizeX) { + val sizeY: Int = last[x].size + for (y in 0 until sizeY) { + val previous = last[x][y] ?: continue + if (!containsChunk(current, previous)) { + PacketRepository.send(ClearRegionChunk::class.java, ClearChunkContext(player, previous)) + } else { + updated.add(previous) + } + } + } + sizeX = current.size + for (x in 0 until sizeX) { + val sizeY: Int = current[x].size + for (y in 0 until sizeY) { + val chunk = current[x][y] + if (!updated.contains(chunk)) { + chunk.synchronize(player) + } else { + chunk.update(player) + } + last[x][y] = current[x][y] + } + } + } + + /** + * Checks if the chunks list contains the specified region chunk. + * @param list The list to search. + * @param c The region chunk. + * @return `True` if so. + */ + private fun containsChunk(list: Array>, c: RegionChunk): Boolean { + val sizeList = list.size + for (x in 0 until sizeList) { + val chunkSize: Int = list[x].size + for (y in 0 until chunkSize) { + if (list[x][y] === c) { + return true + } + } + } + return false + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/world/update/NPCRenderer.kt b/Server/src/main/core/game/world/update/NPCRenderer.kt new file mode 100644 index 0000000..dbb2fd0 --- /dev/null +++ b/Server/src/main/core/game/world/update/NPCRenderer.kt @@ -0,0 +1,118 @@ +package core.game.world.update + +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.world.map.RegionManager +import core.net.packet.IoBuffer +import core.net.packet.PacketHeader +import core.game.world.GameWorld +import java.nio.ByteBuffer +import java.util.* + +/** + * The NPC renderer. + * @author Emperor + */ +object NPCRenderer { + /** + * Handles the NPC rendering for a player. + * @param player The player. + */ + @JvmStatic + fun render(player: Player) { + val buffer = IoBuffer(32, PacketHeader.SHORT) + val info = player.renderInfo + val localNPCs = info.localNpcs + val maskBuffer = IoBuffer(-1, PacketHeader.NORMAL, ByteBuffer.allocate(1 shl 16)) + buffer.setBitAccess() + buffer.putBits(8, localNPCs.size) + val toRemove: MutableList = ArrayList() + val it: Iterator = localNPCs.iterator() + while (it.hasNext()) { + val npc = it.next() + val withinDistance = player.location.withinDistance(npc.location) + if (npc.isHidden(player) || !withinDistance || npc.properties.isTeleporting) { + buffer.putBits(1, 1).putBits(2, 3) + toRemove.add(npc) + if (!withinDistance && npc.aggressiveHandler != null) { + npc.aggressiveHandler.removeTolerance(player.index) + } + } else if (npc.walkingQueue.runDir != -1) { + buffer.putBits(1, 1).putBits(2, 2).putBits(3, npc.walkingQueue.walkDir).putBits(3, npc.walkingQueue.runDir) + flagMaskUpdate(player, buffer, maskBuffer, npc, false) + } else if (npc.walkingQueue.walkDir != -1) { + buffer.putBits(1, 1).putBits(2, 1).putBits(3, npc.walkingQueue.walkDir) + flagMaskUpdate(player, buffer, maskBuffer, npc, false) + } else if (npc.updateMasks.isUpdateRequired) { + buffer.putBits(1, 1).putBits(2, 0) + writeMaskUpdates(player, maskBuffer, npc, false) + } else { + buffer.putBits(1, 0) + } + } + localNPCs.removeAll(toRemove) + for (npc in RegionManager.getLocalNpcs(player)) { + if (localNPCs.size >= 255) { + break + } + if (localNPCs.contains(npc) || npc.isHidden(player)) { + continue + } + buffer.putBits(15, npc.index).putBits(1, if (npc.properties.isTeleporting) 1 else 0).putBits(3, npc.direction.ordinal) + flagMaskUpdate(player, buffer, maskBuffer, npc, true) + var offsetX = npc.location.x - player.location.x + var offsetY = npc.location.y - player.location.y + if (offsetX < 0) { + offsetX += 32 + } + if (offsetY < 0) { + offsetY += 32 + } + buffer.putBits(5, offsetY) + buffer.putBits(14, npc.id) + buffer.putBits(5, offsetX) + if (npc.aggressiveHandler != null) { + npc.aggressiveHandler.playerTolerance[player.index] = GameWorld.ticks + } + localNPCs.add(npc) + } + val masks = maskBuffer.toByteBuffer() + masks.flip() + if (masks.hasRemaining()) { + buffer.putBits(15, 32767) + buffer.setByteAccess() + buffer.put(masks) + } else { + buffer.setByteAccess() + } + player.session.write(buffer) + } + + /** + * Sets the mask update flag. + * @param buffer The buffer to write on. + * @param npc The NPC. + */ + private fun flagMaskUpdate(player: Player, buffer: IoBuffer, maskBuffer: IoBuffer, npc: NPC, sync: Boolean) { + if (npc.updateMasks.isUpdateRequired) { + buffer.putBits(1, 1) + writeMaskUpdates(player, maskBuffer, npc, sync) + } else { + buffer.putBits(1, 0) + } + } + + /** + * Writes the mask updates. + * @param maskBuffer The mask buffer to write on. + * @param npc The NPC to update. + * @param sync If called upon synchronization. + */ + fun writeMaskUpdates(player: Player?, maskBuffer: IoBuffer?, npc: NPC, sync: Boolean) { + if (sync) { + npc.updateMasks.writeSynced(player, npc, maskBuffer!!, true) + } else { + npc.updateMasks.write(player, npc, maskBuffer!!) + } + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/world/update/PlayerRenderer.kt b/Server/src/main/core/game/world/update/PlayerRenderer.kt new file mode 100644 index 0000000..0fb1068 --- /dev/null +++ b/Server/src/main/core/game/world/update/PlayerRenderer.kt @@ -0,0 +1,180 @@ +package core.game.world.update + +import core.game.node.entity.player.Player +import core.game.node.entity.player.info.RenderInfo +import core.game.world.map.RegionManager +import core.net.packet.IoBuffer +import core.net.packet.PacketHeader + +/** + * Handles the player rendering. + * @author Emperor + */ +object PlayerRenderer { + /** + * The maximum amount of players to add per cycle. + */ + private const val MAX_ADD_COUNT = 10 + + /** + * Handles the player rendering for a player. + * @param player The player. + */ + @JvmStatic + fun render(player: Player) { + val buffer = IoBuffer(225, PacketHeader.SHORT) + val flags = IoBuffer(-1, PacketHeader.NORMAL) + val info = player.renderInfo + updateLocalPosition(player, buffer, flags) + buffer.putBits(8, info.localPlayers.size) + val it = info.localPlayers.iterator() + while (it.hasNext()) { + val other = it.next() + if (!other.isActive || !other.location.withinDistance(player.location) || other.properties.isTeleporting || other.isInvisible) { + buffer.putBits(1, 1) + buffer.putBits(2, 3) + it.remove() + continue + } + renderLocalPlayer(player, other, buffer, flags) + } + var count = 0 + for (other in RegionManager.getLocalPlayers(player, 15)) { + if (other === player || !other.isActive || info.localPlayers.contains(other) || other.isInvisible) { + continue + } + if (info.localPlayers.size >= 255 || ++count == MAX_ADD_COUNT) { + break + } + addLocalPlayer(player, other, info, buffer, flags) + } + val masks = flags.toByteBuffer() + masks.flip() + if (masks.hasRemaining()) { + buffer.putBits(11, 2047) + buffer.setByteAccess() + buffer.put(masks) + } else { + buffer.setByteAccess() + } + player.details.session.write(buffer) + } + + /** + * Renders a local player. + * @param player The player we're updating for. + * @param other The player. + * @param buffer The buffer. + * @param flags The update flags buffer. + */ + private fun renderLocalPlayer(player: Player, other: Player, buffer: IoBuffer, flags: IoBuffer) { + if (other.walkingQueue.runDir != -1) { + buffer.putBits(1, 1) // Updating + buffer.putBits(2, 2) // Sub opcode + buffer.putBits(1, 1) + buffer.putBits(3, other.walkingQueue.walkDir) + buffer.putBits(3, other.walkingQueue.runDir) + flagMaskUpdate(player, other, buffer, flags, false, false) + } else if (other.walkingQueue.walkDir != -1) { + buffer.putBits(1, 1) // Updating + buffer.putBits(2, 1) // Sub opcode + buffer.putBits(3, other.walkingQueue.walkDir) + flagMaskUpdate(player, other, buffer, flags, false, false) + } else if (other.updateMasks.isUpdateRequired) { + buffer.putBits(1, 1) + buffer.putBits(2, 0) + writeMaskUpdates(player, other, flags, false, false) + } else { + buffer.putBits(1, 0) + } + } + + /** + * Adds a local player. + * @param player The player. + * @param other The player to add. + * @param info The render info of the player. + * @param buffer The buffer. + * @param flags The flag based buffer. + */ + private fun addLocalPlayer(player: Player, other: Player, info: RenderInfo, buffer: IoBuffer, flags: IoBuffer) { + buffer.putBits(11, other.index) + var offsetX = other.location.x - player.location.x + var offsetY = other.location.y - player.location.y + if (offsetY < 0) { + offsetY += 32 + } + if (offsetX < 0) { + offsetX += 32 + } + val appearance = info.appearanceStamps[other.index and 0x800] != other.updateMasks.appearanceStamp + val update = appearance || other.updateMasks.isUpdateRequired || other.updateMasks.hasSynced() + buffer.putBits(1, if (update) 1 else 0) + buffer.putBits(5, offsetX) + buffer.putBits(3, other.direction.ordinal) + buffer.putBits(1, if (other.properties.isTeleporting) 1 else 0) + buffer.putBits(5, offsetY) + info.localPlayers.add(other) + if (update) { + if (appearance) { + info.appearanceStamps[other.index and 0x800] = other.updateMasks.appearanceStamp + } + writeMaskUpdates(player, other, flags, appearance, true) + } + } + + /** + * Updates the local player's client position. + * @param local The local player. + * @param buffer The i/o buffer. + * @param flags The update flags buffer. + */ + private fun updateLocalPosition(local: Player, buffer: IoBuffer, flags: IoBuffer) { + if (local.playerFlags.isUpdateSceneGraph || local.properties.isTeleporting) { + buffer.putBits(1, 1) // Updating + buffer.putBits(2, 3) // Sub opcode + buffer.putBits(7, local.location.getSceneY(local.playerFlags.lastSceneGraph)) + buffer.putBits(1, if (local.properties.isTeleporting) 1 else 0) + buffer.putBits(2, local.location.z) + flagMaskUpdate(local, local, buffer, flags, false, false) + buffer.putBits(7, local.location.getSceneX(local.playerFlags.lastSceneGraph)) + } else { + renderLocalPlayer(local, local, buffer, flags) + } + } + + /** + * Sets the update mask flag. + * @param local The local player. + * @param player The player to update. + * @param buffer The packet buffer. + * @param maskBuffer The mask buffer. + * @param sync If we should use the synced buffer. + * @param appearance If appearance update mask should be used in the synced + * buffer. + */ + private fun flagMaskUpdate(local: Player, player: Player, buffer: IoBuffer, maskBuffer: IoBuffer, sync: Boolean, appearance: Boolean) { + if (player.updateMasks.isUpdateRequired) { + buffer.putBits(1, 1) + writeMaskUpdates(local, player, maskBuffer, appearance, sync) + } else { + buffer.putBits(1, 0) + } + } + + /** + * Updates the player flags. + * @param local The local player. + * @param player The player to update. + * @param flags The flags buffer. + * @param appearance If we should force appearance. + * @param sync If we should use the synced buffer. + */ + private fun writeMaskUpdates(local: Player, player: Player, flags: IoBuffer, appearance: Boolean, sync: Boolean) { + if (sync) { + player.updateMasks.writeSynced(local, player, flags, appearance) + } else if (player.updateMasks.isUpdateRequired) { + player.updateMasks.write(local, player, flags) + } + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/world/update/UpdateMasks.kt b/Server/src/main/core/game/world/update/UpdateMasks.kt new file mode 100644 index 0000000..072148a --- /dev/null +++ b/Server/src/main/core/game/world/update/UpdateMasks.kt @@ -0,0 +1,178 @@ +package core.game.world.update + +import core.game.node.entity.Entity +import core.game.node.entity.combat.ImpactHandler +import core.game.node.entity.player.Player +import core.game.world.update.flag.UpdateFlag +import core.game.world.update.flag.context.HitMark +import core.game.world.update.flag.* +import core.net.packet.IoBuffer +import core.api.* +import core.tools.* +import java.util.concurrent.atomic.AtomicBoolean + +class UpdateMasks (val owner: Entity) { + var appearanceStamp: Long = 0 + private val type = EFlagType.of (owner) + private val updating = AtomicBoolean() + private var presenceFlags = 0 + private var syncedPresenceFlags = 0 + private val elements = arrayOfNulls(SIZE) + private val syncedElements = arrayOfNulls(SIZE) + private data class MaskElement (val encoder: EFlagProvider, val context: Any?) + + @JvmOverloads + fun register(flag: EntityFlag, context: Any?, sync: Boolean = false) : Boolean { + var synced = sync + var provider = EntityFlags.getFlagFor (type, flag) + if (provider == null) { + logWithStack(this::class.java, Log.ERR, "Tried to use flag ${flag.name} which is not available for ${type.name} in this revision.") + return false + } + if (updating.get()) + return false + if (flag == EntityFlag.Appearance) { + appearanceStamp = System.currentTimeMillis() + synced = true + } + if (synced) { + syncedElements[provider.ordinal] = MaskElement (provider, context) + syncedPresenceFlags = syncedPresenceFlags or provider.presenceFlag + } + elements[provider.ordinal] = MaskElement (provider, context) + presenceFlags = presenceFlags or provider.presenceFlag + return true + } + + /** + * Unregisters a synced update mask. + * @param maskData The mask data. + * @return `True` if the mask got removed. + */ + fun unregisterSynced(ordinal: Int): Boolean { + if (syncedElements[ordinal] != null) { + syncedPresenceFlags = syncedPresenceFlags and syncedElements[ordinal]!!.encoder.presenceFlag.inv() + syncedElements[ordinal] = null + return true + } + return false + } + + /** + * Writes the flags. + * @param p The player. + * @param e The entity to update. + * @param buffer The buffer to write on. + */ + fun write(p: Player?, e: Entity?, buffer: IoBuffer) { + var maskData = presenceFlags + if (maskData >= 0x100) { + maskData = maskData or if (e is Player) 0x10 else 0x8 + buffer.put(maskData).put(maskData shr 8) + } else { + buffer.put(maskData) + } + for (i in elements.indices) { + val element = elements[i] + element?.encoder?.writeToDynamic(buffer, element.context, p!!) + } + } + + /** + * Writes the update masks on synchronization. + * @param p The player. + * @param e The entity to update. + * @param buffer The buffer to write on. + * @param appearance If the appearance mask should be written. + */ + fun writeSynced(p: Player?, e: Entity?, buffer: IoBuffer, appearance: Boolean) { + var maskData = presenceFlags + var synced = syncedPresenceFlags + var appearanceFlag = EntityFlags.getPresenceFlag(type, EntityFlag.Appearance) + if (!appearance && synced and appearanceFlag != 0) { + synced = synced and appearanceFlag.inv() + } + maskData = maskData or synced + if (maskData >= 0x100) { + maskData = maskData or if (e is Player) 0x10 else 0x8 + buffer.put(maskData).put(maskData shr 8) + } else { + buffer.put(maskData) + } + for (i in elements.indices) { + var element = elements[i] + if (element == null) { + element = syncedElements[i] + if (!appearance && element != null && element.encoder.flag == EntityFlag.Appearance) { + continue + } + } + element?.encoder?.writeToDynamic(buffer, element.context, p!!) + } + } + + /** + * Adds the dynamic update flags. + * @param entity The entity. + */ + fun prepare(entity: Entity) { + val handler = entity.impactHandler + for (i in 0..1) { + if (handler.impactQueue.peek() == null) { + break + } + val impact = handler.impactQueue.poll() + registerHitUpdate(entity, impact, i == 1) + } + updating.set(true) + } + + /** + * Registers the hit update for the given [Impact]. + * @param e The entity. + * @param impact The impact to update. + * @param secondary If the hit update is secondary. + */ + private fun registerHitUpdate(e: Entity, impact: ImpactHandler.Impact, secondary: Boolean): HitMark { + val mark = HitMark(impact.amount, impact.type.ordinal, e) + register(if (secondary) EntityFlag.SecondaryHit else EntityFlag.PrimaryHit, mark) + return mark + } + + /** + * Resets the update masks. + */ + fun reset() { + for (i in elements.indices) { + elements[i] = null + } + presenceFlags = 0 + updating.set(false) + } + + fun isUpdating(): Boolean { + return updating.get() + } + + /** + * Checks if an update is required. + * @return `True` if so. + */ + val isUpdateRequired: Boolean + get() = presenceFlags != 0 + + /** + * Checks if synced update masks have been registered. + * @return `True` if so. + */ + fun hasSynced(): Boolean { + return syncedPresenceFlags != 0 + } + + companion object { + /** + * The amount of update masks. + */ + const val SIZE = 11 + } +} diff --git a/Server/src/main/core/game/world/update/UpdateSequence.kt b/Server/src/main/core/game/world/update/UpdateSequence.kt new file mode 100644 index 0000000..bc17fbd --- /dev/null +++ b/Server/src/main/core/game/world/update/UpdateSequence.kt @@ -0,0 +1,84 @@ +package core.game.world.update + +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.GroundItemManager +import core.game.world.map.RegionManager +import core.game.world.repository.InitializingNodeList +import core.net.packet.PacketRepository +import core.net.packet.context.PlayerContext +import core.net.packet.out.ClearMinimapFlag +import core.game.world.repository.Repository +import core.integrations.grafana.* + +/** + * The entity update sequence. + * @author Emperor + */ +class UpdateSequence +/** + * Constructs a new `ParallelUpdatingSequence` `Object`. + */ +{ + var lobbyList: List? = null + var playersList: List? = null + var npcList: List? = null + + /** + * Starts the update sequence. + * @return `True` if we should continue. + */ + fun start() { + lobbyList = Repository.lobbyPlayers + playersList = renderablePlayers + npcList = Repository.renderableNpcs + lobbyList!!.map{ PacketRepository.send(ClearMinimapFlag::class.java, PlayerContext(it)) } + + var npcTickStart = System.currentTimeMillis() + npcList!!.forEach(NPC::tick) + Grafana.npcTickTime = (System.currentTimeMillis() - npcTickStart).toInt() + + var playerTickStart = System.currentTimeMillis() + renderablePlayers.forEach(Player::tick) + Grafana.playerTickTime = (System.currentTimeMillis() - playerTickStart).toInt() + } + + /** + * Runs the updating part of the sequence. + */ + fun run() { + var playerRenderStart = System.currentTimeMillis() + renderablePlayers.forEach(Player::update) + Grafana.playerRenderTime = (System.currentTimeMillis() - playerRenderStart).toInt() + } + + /** + * Ends the sequence, calls the [Entity.reset] method.. + */ + fun end() { + playersList!!.forEach(Player::reset) + npcList!!.forEach(NPC::reset) + renderablePlayers.sync() + RegionManager.pulse() + GroundItemManager.pulse() + } + + /** + * Terminates the update sequence. + */ + fun terminate() { + } + + companion object { + /** + * Gets the renderablePlayers. + * @return The renderablePlayers. + */ + /** + * The list of active players. + */ + @JvmStatic + val renderablePlayers = InitializingNodeList() + + } +} diff --git a/Server/src/main/core/game/world/update/flag/EFlagProvider.kt b/Server/src/main/core/game/world/update/flag/EFlagProvider.kt new file mode 100644 index 0000000..8f90945 --- /dev/null +++ b/Server/src/main/core/game/world/update/flag/EFlagProvider.kt @@ -0,0 +1,29 @@ +package core.game.world.update.flag + +import core.net.packet.IoBuffer +import core.game.node.entity.Entity +import kotlin.reflect.* +import core.api.* +import core.tools.* + +enum class EFlagType { + Player, + NPC; + companion object { + @JvmStatic fun of (e: Entity) : EFlagType { + if (e is core.game.node.entity.player.Player) return Player + else return NPC + } + } +} + +open class EFlagProvider (val revision: Int, val type: EFlagType, val presenceFlag: Int, val ordinal: Int, val flag: EntityFlag) { + open fun writeTo (buffer: IoBuffer, context: Any?) {} + open fun writeToDynamic (buffer: IoBuffer, context: Any?, e: Entity) { + writeTo (buffer, context) + } + + fun logInvalidType (context: Any?, expected: KType) { + logWithStack(this::class.java, Log.ERR, "Invalid context of type ${context?.let { it::class.java.simpleName } ?: "null"} passed to ${this::class.simpleName} flag which expects $expected.") + } +} diff --git a/Server/src/main/core/game/world/update/flag/EntityFlag.kt b/Server/src/main/core/game/world/update/flag/EntityFlag.kt new file mode 100644 index 0000000..85fcb84 --- /dev/null +++ b/Server/src/main/core/game/world/update/flag/EntityFlag.kt @@ -0,0 +1,16 @@ +package core.game.world.update.flag + +enum class EntityFlag { + Chat, + ForceChat, + PrimaryHit, + SecondaryHit, + Animate, + SpotAnim, + Appearance, + FaceEntity, + FaceLocation, + ForceMove, + AnimSeq, + TypeSwap +} diff --git a/Server/src/main/core/game/world/update/flag/EntityFlags.kt b/Server/src/main/core/game/world/update/flag/EntityFlags.kt new file mode 100644 index 0000000..3d3c2bf --- /dev/null +++ b/Server/src/main/core/game/world/update/flag/EntityFlags.kt @@ -0,0 +1,42 @@ +package core.game.world.update.flag + +import core.api.* +import core.ServerConstants +import kotlin.reflect.* +import kotlin.reflect.full.* + +object EntityFlags { + lateinit var flagProviders : HashMap + + init { + flagProviders = HashMap() + registerFlagProviders (PlayerFlags530::class) + registerFlagProviders (NPCFlags530::class) + } + + fun registerFlagProviders (parent: KClass<*>) { + val clazzes = parent.sealedSubclasses + for (clazz in clazzes) { + val p = clazz.primaryConstructor?.call() as? EFlagProvider ?: continue + flagProviders[getMapToken(p.revision, p.type, p.flag)] = p + } + } + + fun getFlagFor (type: EFlagType, flag: EntityFlag) : EFlagProvider? { + val revision = 530 + return flagProviders[getMapToken(revision, type, flag)] + } + + @JvmStatic fun getOrdinal (type: EFlagType, flag: EntityFlag) : Int { + return getFlagFor(type, flag)?.ordinal ?: -1 + } + + @JvmStatic fun getPresenceFlag (type: EFlagType, flag: EntityFlag) : Int { + return getFlagFor(type, flag)?.presenceFlag ?: 0 + } + + private fun getMapToken (revision: Int, type: EFlagType, flag: EntityFlag) : Int { + var token = ((revision shl 8) + (type.ordinal shl 4) + flag.ordinal) + return token + } +} diff --git a/Server/src/main/core/game/world/update/flag/FlagContext.java b/Server/src/main/core/game/world/update/flag/FlagContext.java new file mode 100644 index 0000000..3363623 --- /dev/null +++ b/Server/src/main/core/game/world/update/flag/FlagContext.java @@ -0,0 +1,9 @@ +package core.game.world.update.flag; + +/** + * Represents an update flag context. + * @author Emperor + */ +public interface FlagContext { + +} \ No newline at end of file diff --git a/Server/src/main/core/game/world/update/flag/NPCFlags530.kt b/Server/src/main/core/game/world/update/flag/NPCFlags530.kt new file mode 100644 index 0000000..4a8e987 --- /dev/null +++ b/Server/src/main/core/game/world/update/flag/NPCFlags530.kt @@ -0,0 +1,108 @@ +package core.game.world.update.flag + +import core.net.packet.IoBuffer +import core.game.world.update.flag.context.* +import core.game.world.update.flag.* +import core.game.world.map.Location +import core.game.node.entity.Entity +import core.game.node.entity.impl.ForceMovement +import core.game.node.entity.player.Player +import core.tools.* +import core.api.* + +import java.nio.charset.StandardCharsets +import kotlin.reflect.* + +sealed class NPCFlags530 (p: Int, o: Int, f: EntityFlag) : EFlagProvider (530, EFlagType.NPC, p, o, f) { + class PrimaryHit : NPCFlags530 (0x40, 0, EntityFlag.PrimaryHit) { + override fun writeTo (buffer: IoBuffer, context: Any?) { + if (context !is HitMark) { + logInvalidType (context, typeOf()) + return + } + buffer.p1 (context.damage) + buffer.p1neg (context.type) + + val e = context.entity + var ratio = 255 + val max = e.skills.maximumLifepoints + if (e.skills.lifepoints < max) + ratio = e.skills.lifepoints * 255 / max + buffer.p1sub (ratio) + } + } + class SecondaryHit : NPCFlags530 (0x2, 1, EntityFlag.SecondaryHit) { + override fun writeTo (buffer: IoBuffer, context: Any?) { + if (context !is HitMark) { + logInvalidType (context, typeOf()) + return + } + buffer.p1neg (context.damage) + buffer.p1sub (context.type) + } + } + class Animate : NPCFlags530 (0x10, 2, EntityFlag.Animate) { + override fun writeTo (buffer: IoBuffer, context: Any?) { + if (context !is Animation) { + logInvalidType (context, typeOf()) + return + } + buffer.p2 (context.id) + buffer.p1 (context.delay) + } + } + class FaceEntity : NPCFlags530 (0x4, 3, EntityFlag.FaceEntity) { + override fun writeTo (buffer: IoBuffer, context: Any?) { + if (context !is Entity?) { + logInvalidType (context, typeOf()) + return + } + if (context == null) { + buffer.p2add (-1) + } else { + buffer.p2add (context.getClientIndex()) + } + } + } + class SpotAnim : NPCFlags530 (0x80, 4, EntityFlag.SpotAnim) { + override fun writeTo (buffer: IoBuffer, context: Any?) { + if (context !is Graphics) { + logInvalidType (context, typeOf()) + return + } + buffer.p2add (context.id) + buffer.ip4 ((context.height shl 16) + context.delay) + } + } + class TypeSwap : NPCFlags530 (0x1, 5, EntityFlag.TypeSwap) { + override fun writeTo (buffer: IoBuffer, context: Any?) { + if (context !is Int) { + logInvalidType (context, typeOf()) + return + } + buffer.ip2 (context) + } + } + class ForceChat : NPCFlags530 (0x20, 6, EntityFlag.ForceChat) { + override fun writeTo (buffer: IoBuffer, context: Any?) { + if (context !is String) { + logInvalidType (context, typeOf()) + return + } + buffer.putString (context) + } + } + class AnimationSequence : NPCFlags530 (0x100, 7, EntityFlag.AnimSeq) { + //TODO + } + class FaceLocation : NPCFlags530 (0x200, 8, EntityFlag.FaceLocation) { + override fun writeTo (buffer: IoBuffer, context: Any?) { + if (context !is Location) { + logInvalidType (context, typeOf()) + return + } + buffer.p2add ((context.x shl 1) + 1) + buffer.p2 ((context.y shl 1) + 1) + } + } +} diff --git a/Server/src/main/core/game/world/update/flag/PlayerFlags.java b/Server/src/main/core/game/world/update/flag/PlayerFlags.java new file mode 100644 index 0000000..c67408a --- /dev/null +++ b/Server/src/main/core/game/world/update/flag/PlayerFlags.java @@ -0,0 +1,86 @@ +package core.game.world.update.flag; + +import core.game.world.map.Location; +import core.game.world.map.RegionChunk; +import core.game.world.map.Viewport; + +/** + * A class holding a player's updating flags. + * @author Emperor + */ +public final class PlayerFlags { + + /** + * If the scene graph has been updated during this tick. + */ + private boolean updateSceneGraph; + + /** + * The last viewport. + */ + private RegionChunk[][] lastViewport = new RegionChunk[Viewport.CHUNK_SIZE][Viewport.CHUNK_SIZE]; + + /** + * The location the player was standing on when last scene graph update + * occured. + */ + private Location lastSceneGraph; + + /** + * Constructs a new {@code PlayerFlags} {@code Object}. + */ + public PlayerFlags() { + /* + * empty. + */ + } + + /** + * Gets the updateSceneGraph. + * @return The updateSceneGraph. + */ + public boolean isUpdateSceneGraph() { + return updateSceneGraph; + } + + /** + * Sets the updateSceneGraph. + * @param updateSceneGraph The updateSceneGraph to set. + */ + public void setUpdateSceneGraph(boolean updateSceneGraph) { + this.updateSceneGraph = updateSceneGraph; + } + + /** + * Gets the lastSceneGraph. + * @return The lastSceneGraph. + */ + public Location getLastSceneGraph() { + return lastSceneGraph; + } + + /** + * Sets the lastSceneGraph. + * @param lastSceneGraph The lastSceneGraph to set. + */ + public void setLastSceneGraph(Location lastSceneGraph) { + this.lastSceneGraph = lastSceneGraph; + } + + /** + * Gets the lastViewport. + * @return The lastViewport. + */ + public RegionChunk[][] getLastViewport() { + return lastViewport; + } + + /** + * Sets the lastViewport. + * @param lastViewport The lastViewport to set. + */ + public void setLastViewport(RegionChunk[][] lastViewport) { + this.lastViewport = lastViewport; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/world/update/flag/PlayerFlags530.kt b/Server/src/main/core/game/world/update/flag/PlayerFlags530.kt new file mode 100644 index 0000000..bcc1e33 --- /dev/null +++ b/Server/src/main/core/game/world/update/flag/PlayerFlags530.kt @@ -0,0 +1,214 @@ +package core.game.world.update.flag + +import core.net.packet.IoBuffer +import core.game.world.update.flag.context.* +import core.game.world.update.flag.* +import core.game.world.map.Location +import core.game.node.entity.Entity +import core.game.node.entity.impl.ForceMovement +import core.game.node.entity.player.Player +import core.tools.* +import core.api.* +import core.game.world.GameWorld + +import java.nio.charset.StandardCharsets +import kotlin.reflect.* +import kotlin.math.max + +sealed class PlayerFlags530 (p: Int, o: Int, f: EntityFlag) : EFlagProvider (530, EFlagType.Player, p, o, f) { + class Chat : PlayerFlags530 (0x80, 0, EntityFlag.Chat) { + override fun writeTo (buffer: IoBuffer, context: Any?) { + if (context !is ChatMessage) { + logInvalidType (context, typeOf()) + return + } + buffer.ip2 (context.effects) + if (context.isQuickChat) + buffer.p1 (4) + else + buffer.p1 (context.chatIcon) + val chatBuf = ByteArray(256) + chatBuf[0] = context.text.length.toByte() + val offset = 1 + StringUtils.encryptPlayerChat ( + chatBuf, + 0, 1, + context.text.length, + context.text.toByteArray(StandardCharsets.UTF_8) + ) + buffer.p1 (offset + 1) + buffer.putReverse (chatBuf, 0, offset) + } + } + class PrimaryHit : PlayerFlags530 (0x1, 1, EntityFlag.PrimaryHit) { + override fun writeTo (buffer: IoBuffer, context: Any?) { + if (context !is HitMark) { + logInvalidType (context, typeOf()) + return + } + buffer.psmarts (context.damage) + buffer.p1add (context.type) + + var ratio = 255 + var e = context.entity + var max = e.skills.maximumLifepoints + if (max > e.skills.lifepoints) + ratio = e.skills.lifepoints * 255 / max + buffer.p1sub (ratio) + } + } + class Animate : PlayerFlags530 (0x8, 2, EntityFlag.Animate) { + override fun writeTo (buffer: IoBuffer, context: Any?) { + if (context !is Animation) { + logInvalidType (context, typeOf()) + return + } + buffer.p2 (context.id) + buffer.p1 (context.delay) + } + } + class Appearance : PlayerFlags530 (0x4, 3, EntityFlag.Appearance) { + override fun writeTo (buffer: IoBuffer, context: Any?) { + if (context !is Player) { + logInvalidType (context, typeOf()) + return + } + val appearance = context.appearance + appearance.prepareBodyData(context) + var settings = appearance.gender.toByte().toInt() + val nonPvp = context.skullManager.isWilderness && context.skullManager.isWildernessDisabled //nonPvp is always false + if (context.size() > 1) + settings += (context.size() - 1) shl 3 + if (nonPvp) + settings += 0x4 //flag the player as being non-pvp, which shows skill level instead of combat level. + + buffer.p1 (0) //stand-in for size. + val startPos = buffer.toByteBuffer().position() + + buffer.p1 (settings) + buffer.p1 (appearance.skullIcon) + buffer.p1 (appearance.headIcon) + val npcId = appearance.npcId + if (npcId == -1) { + val parts = appearance.bodyParts + for (i in 0 until 12) { + if (parts[i] == 0) buffer.p1 (0) + else buffer.p2 (parts[i]) + } + } else { + buffer.p2 (-1) + buffer.p2 (npcId) + buffer.p1 (255) + } + arrayOf ( appearance.hair, appearance.torso, appearance.legs, appearance.feet, appearance.skin ).forEach { part -> + buffer.p1 (part.color) + } + buffer.p2 (appearance.renderAnimation) + buffer.p8 (StringUtils.stringToLong(context.username)) + if (nonPvp) { + buffer.p1 (context.properties.currentCombatLevel) //with summoning + buffer.p2 (context.skills.getTotalLevel()) + } else { + //client-side code determines how the combat level will be displayed, based on + //the combat level values that are sent + if ((GameWorld.settings!!.isPvp || (GameWorld.settings!!.wild_pvp_enabled && context.skullManager.isWilderness)) + && !context.familiarManager.isUsingSummoning) { + //client will display separate base and summoning combat levels (e.g. "50+5") + //TODO: Split combat levels should also be used for Bounty Hunter + buffer.p1 (context.properties.combatLevel) //without summoning + buffer.p1 (context.properties.combatLevel + context.familiarManager.summoningCombatLevel) //with summoning + } else { + //client will display a combined combat level (e.g. "55") + buffer.p1 (context.properties.currentCombatLevel) //with summoning + buffer.p1 (context.properties.currentCombatLevel) //with summoning + } + if (GameWorld.settings!!.isPvp) { + //displays a player's combat level in white if the player is not within combat range + buffer.p1 (context.skullManager.level) //combat range + } else { + //disables the client code that makes combat levels white + buffer.p1 (-1) //combat range + } + } + buffer.p1 (0) //this is the sound radius, and if set, 4 shorts need to be set as well which include the sound IDs + //to play to everyone in that radius when the player is rendered onscreen for the first time. + buffer.psizeadd (buffer.toByteBuffer().position() - startPos) + } + } + class FaceEntity : PlayerFlags530 (0x2, 4, EntityFlag.FaceEntity) { + override fun writeTo (buffer: IoBuffer, context: Any?) { + if (context !is Entity?) { + logInvalidType (context, typeOf()) + return + } + if (context == null) + buffer.p2add (-1) + else + buffer.p2add (context.getClientIndex()) + } + } + class ForceMove : PlayerFlags530 (0x400, 5, EntityFlag.ForceMove) { + override fun writeToDynamic (buffer: IoBuffer, context: Any?, e: Entity) { + if (context !is ForceMoveCtx) { + logInvalidType (context, typeOf()) + return + } + if (e !is Player) { + logInvalidType (context, typeOf()) + return + } + val l = e.playerFlags.getLastSceneGraph() + //start location + buffer.p1neg (context.start.getSceneX(l)) + buffer.p1 (context.start.getSceneY(l)) + //end location + buffer.p1add (context.dest.getSceneX(l)) + buffer.p1 (context.dest.getSceneY(l)) + //arrival times (in client cycles) + buffer.ip2 (context.startArrive) //# of client cycles to start location + buffer.ip2 (max(context.startArrive + 1, context.startArrive + context.destArrive)) //# of client cycles to end location + buffer.p1neg (context.direction.toInteger()) //direction of movement + } + } + class ForceChat : PlayerFlags530 (0x20, 6, EntityFlag.ForceChat) { + override fun writeTo (buffer: IoBuffer, context: Any?) { + if (context !is String) { + logInvalidType (context, typeOf()) + return + } + buffer.putString(context) + } + } + class SecondaryHit : PlayerFlags530 (0x200, 7, EntityFlag.SecondaryHit) { + override fun writeTo (buffer: IoBuffer, context: Any?) { + if (context !is HitMark) { + logInvalidType (context, typeOf()) + return + } + buffer.psmarts (context.damage) + buffer.p1sub (context.type) + } + } + class AnimationSequence : PlayerFlags530 (0x800, 8, EntityFlag.AnimSeq) { + //TODO + } + class SpotAnim : PlayerFlags530 (0x100, 9, EntityFlag.SpotAnim) { + override fun writeTo (buffer: IoBuffer, context: Any?) { + if (context !is Graphics) { + logInvalidType (context, typeOf()) + return + } + buffer.ip2 (context.id) + buffer.mp4 ((context.height shl 16) + context.delay) + } + } + class FaceLocation : PlayerFlags530 (0x40, 10, EntityFlag.FaceLocation) { + override fun writeTo (buffer: IoBuffer, context: Any?) { + if (context !is Location) { + logInvalidType (context, typeOf()) + return + } + buffer.p2 ((context.x shl 1) + 1) + buffer.ip2add ((context.y shl 1) + 1) + } + } +} diff --git a/Server/src/main/core/game/world/update/flag/UpdateFlag.java b/Server/src/main/core/game/world/update/flag/UpdateFlag.java new file mode 100644 index 0000000..81fd806 --- /dev/null +++ b/Server/src/main/core/game/world/update/flag/UpdateFlag.java @@ -0,0 +1,86 @@ +package core.game.world.update.flag; + +import core.game.node.entity.Entity; +import core.net.packet.IoBuffer; + +/** + * Represents an update flag, which holds the data the update mask uses to + * write. + * @author Emperor + */ +public abstract class UpdateFlag implements Comparable> { + + /** + * The context. + */ + protected T context; + + /** + * Constructs a new {@code UpdateFlag} {@code Object}. + * @param context The context. + */ + public UpdateFlag(T context) { + this.context = context; + } + + /** + * Writes the data on the buffer. + * @param buffer The buffer. + */ + public abstract void write(IoBuffer buffer); + + /** + * Writes the data on the buffer. + * @param buffer The buffer. + * @param e The entity to write for. + */ + public void writeDynamic(IoBuffer buffer, Entity e) { + write(buffer); + } + + /** + * Gets the update mask data for this update flag. + * @return The update mask data. + */ + public abstract int data(); + + /** + * The ordinal. + * @return The update mask ordinal. + */ + public abstract int ordinal(); + + @Override + public int compareTo(UpdateFlag flag) { + if (flag.ordinal() == ordinal()) { + return 0; + } + if (flag.ordinal() < ordinal()) { + return 1; + } + return -1; + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof UpdateFlag)) { + return false; + } + return ((UpdateFlag) o).data() == data() && ((UpdateFlag) o).ordinal() == ordinal(); + } + + /** + * Get the context. + * @return the context + */ + public T getContext() { + return context; + } + + /** + * @param context the context to set + */ + public void setContext(T context) { + this.context = context; + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/world/update/flag/chunk/AnimateObjectUpdateFlag.java b/Server/src/main/core/game/world/update/flag/chunk/AnimateObjectUpdateFlag.java new file mode 100644 index 0000000..4ddb29e --- /dev/null +++ b/Server/src/main/core/game/world/update/flag/chunk/AnimateObjectUpdateFlag.java @@ -0,0 +1,37 @@ +package core.game.world.update.flag.chunk; + +import core.game.world.update.flag.UpdateFlag; +import core.game.world.update.flag.context.Animation; +import core.net.packet.IoBuffer; +import core.net.packet.out.AnimateObjectPacket; + +/** + * The animate object update flag. + * @author Emperor + */ +public final class AnimateObjectUpdateFlag extends UpdateFlag { + + /** + * Constructs a new {@code AnimateObjectUpdateFlag} {@code Object}. + * @param context The animation. + */ + public AnimateObjectUpdateFlag(Animation context) { + super(context); + } + + @Override + public void write(IoBuffer buffer) { + AnimateObjectPacket.write(buffer, context); + } + + @Override + public int data() { + return 0; + } + + @Override + public int ordinal() { + return 0; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/world/update/flag/chunk/GraphicUpdateFlag.java b/Server/src/main/core/game/world/update/flag/chunk/GraphicUpdateFlag.java new file mode 100644 index 0000000..6615069 --- /dev/null +++ b/Server/src/main/core/game/world/update/flag/chunk/GraphicUpdateFlag.java @@ -0,0 +1,48 @@ +package core.game.world.update.flag.chunk; + +import core.game.world.map.Location; +import core.game.world.update.flag.UpdateFlag; +import core.game.world.update.flag.context.Graphics; +import core.net.packet.IoBuffer; + +/** + * Handles the location graphic update. + * @author Emperor + */ +public final class GraphicUpdateFlag extends UpdateFlag { + + /** + * The location. + */ + private final Location location; + + /** + * Constructs a new {@code GraphicUpdateFlag} {@code Object}. + * @param graphic The graphic. + * @param location The location. + */ + public GraphicUpdateFlag(Graphics graphic, Location location) { + super(graphic); + this.location = location; + } + + @Override + public void write(IoBuffer buffer) { + buffer.put((byte) 17); // opcode + buffer.put((location.getChunkOffsetX() << 4) | (location.getChunkOffsetY() & 0x7)); + buffer.putShort(context.getId()); + buffer.put(context.getHeight()); + buffer.putShort(context.getDelay()); + } + + @Override + public int data() { + return 0; + } + + @Override + public int ordinal() { + return 3; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/world/update/flag/chunk/ItemUpdateFlag.java b/Server/src/main/core/game/world/update/flag/chunk/ItemUpdateFlag.java new file mode 100644 index 0000000..f2eb536 --- /dev/null +++ b/Server/src/main/core/game/world/update/flag/chunk/ItemUpdateFlag.java @@ -0,0 +1,122 @@ +package core.game.world.update.flag.chunk; + +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.node.item.GroundItem; +import core.game.world.update.flag.UpdateFlag; +import core.net.packet.IoBuffer; +import core.net.packet.out.ClearGroundItem; +import core.net.packet.out.ConstructGroundItem; +import core.net.packet.out.UpdateGroundItemAmount; + +/** + * Handles an item update flag. + * @author Emperor + */ +public final class ItemUpdateFlag extends UpdateFlag { + + /** + * The construct update type. + */ + public static final int CONSTRUCT_TYPE = 0; + + /** + * The remove update type. + */ + public static final int REMOVE_TYPE = 1; + + /** + * The update amount update type. + */ + public static final int UPDATE_AMOUNT_TYPE = 2; + + /** + * The ground item to update. + */ + private final GroundItem item; + + /** + * The update type + */ + private final int type; + + /** + * The old amount. + */ + private int oldAmount; + + /** + * Constructs a new {@code ItemContext} {@code Object}. + * @param item The ground item to update. + * @param type The update type. + */ + public ItemUpdateFlag(GroundItem item, int type) { + this(item, type, 0); + } + + /** + * Constructs a new {@code ItemContext} {@code Object}. + * @param item The ground item to update. + * @param type The update type. + */ + public ItemUpdateFlag(GroundItem item, int type, int oldAmount) { + super(null); + this.item = item; + this.type = type; + this.oldAmount = oldAmount; + } + + @Override + public void writeDynamic(IoBuffer buffer, Entity e) { + if (!isRemove() && item.droppedBy((Player) e)) { + return; + } + write(buffer); + } + + @Override + public void write(IoBuffer buffer) { + if (isRemove()) { + ClearGroundItem.write(buffer, item); + } else if (isConstruct()) { + ConstructGroundItem.write(buffer, item); + } else { + UpdateGroundItemAmount.write(buffer, item, oldAmount); + } + } + + /** + * Checks if we're removing the ground item. + * @return {@code True} if so. + */ + public boolean isRemove() { + return type == REMOVE_TYPE; + } + + /** + * Checks if we're constructing the ground item. + * @return {@code True} if so. + */ + public boolean isConstruct() { + return type == CONSTRUCT_TYPE; + } + + /** + * Checks if we're removing the ground item. + * @return {@code True} if so. + */ + public boolean isAmountUpdate() { + return type == UPDATE_AMOUNT_TYPE; + } + + @Override + public int data() { + return 0; + } + + @Override + public int ordinal() { + return 1; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/world/update/flag/chunk/ObjectUpdateFlag.java b/Server/src/main/core/game/world/update/flag/chunk/ObjectUpdateFlag.java new file mode 100644 index 0000000..5b1d4ee --- /dev/null +++ b/Server/src/main/core/game/world/update/flag/chunk/ObjectUpdateFlag.java @@ -0,0 +1,55 @@ +package core.game.world.update.flag.chunk; + +import core.game.node.scenery.Scenery; +import core.game.world.update.flag.UpdateFlag; +import core.net.packet.IoBuffer; +import core.net.packet.out.ClearScenery; +import core.net.packet.out.ConstructScenery; + +/** + * The object update flag. + * @author Emperor + */ +public class ObjectUpdateFlag extends UpdateFlag { + + /** + * The object to update. + */ + private final Scenery object; + + /** + * If we should remove the object. + */ + private final boolean remove; + + /** + * Constructs a new {@code ObjectUpdateFlag} {@code Object}. + * @param object The object to update. + * @param remove If we should remove the object. + */ + public ObjectUpdateFlag(Scenery object, boolean remove) { + super(null); + this.object = object; + this.remove = remove; + } + + @Override + public void write(IoBuffer buffer) { + if (remove) { + ClearScenery.write(buffer, object); + } else { + ConstructScenery.write(buffer, object); + } + } + + @Override + public int data() { + return 0; + } + + @Override + public int ordinal() { + return 0; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/world/update/flag/chunk/ProjectileUpdateFlag.java b/Server/src/main/core/game/world/update/flag/chunk/ProjectileUpdateFlag.java new file mode 100644 index 0000000..b1a176f --- /dev/null +++ b/Server/src/main/core/game/world/update/flag/chunk/ProjectileUpdateFlag.java @@ -0,0 +1,54 @@ +package core.game.world.update.flag.chunk; + +import core.game.node.entity.Entity; +import core.game.node.entity.impl.Projectile; +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.game.world.update.flag.UpdateFlag; +import core.net.packet.IoBuffer; + +/** + * Handles the projectile updating. + * @author Emperor + */ +public final class ProjectileUpdateFlag extends UpdateFlag { + + /** + * Constructs a new {@code ProjectileUpdateFlag} {@code Object}. + * @param projectile The projectile. + */ + public ProjectileUpdateFlag(Projectile projectile) { + super(projectile); + } + + @Override + public void write(IoBuffer buffer) { + Projectile p = context; + Location start = p.getSourceLocation(); + Entity target = p.getVictim(); + Location end = p.isLocationBased() ? p.getEndLocation() : target.getLocation(); + buffer.put((byte) 16) //opcode + .put((start.getChunkOffsetX() << 4) | (start.getChunkOffsetY() & 0x7)) + .put(end.getX() - start.getX()) + .put(end.getY() - start.getY()) + .putShort(target != null ? (target instanceof Player ? -(target.getIndex() + 1) : (target.getIndex() + 1)) : -1) + .putShort(p.getProjectileId()) + .put(p.getStartHeight()) + .put(p.getEndHeight()) + .putShort(p.getStartDelay()) + .putShort(p.getSpeed()) + .put(p.getAngle()) + .put(p.getDistance()); + } + + @Override + public int data() { + return 0; + } + + @Override + public int ordinal() { + return 2; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/world/update/flag/context/Animation.java b/Server/src/main/core/game/world/update/flag/context/Animation.java new file mode 100644 index 0000000..9c2c6e3 --- /dev/null +++ b/Server/src/main/core/game/world/update/flag/context/Animation.java @@ -0,0 +1,167 @@ +package core.game.world.update.flag.context; + +import core.cache.def.impl.AnimationDefinition; +import core.game.node.entity.impl.Animator.Priority; +import core.game.node.scenery.Scenery; + +/** + * Represents an animation. + * @author Emperor + */ +public class Animation { + + /** + * The reset animation. + */ + public static final Animation RESET = new Animation(-1, Priority.VERY_HIGH); + + /** + * The priority. + */ + private Priority priority; + + /** + * The animation id. + */ + private int id; + + /** + * The animation delay. + */ + private final int delay; + + /** + * The animation definitions. + */ + private AnimationDefinition definition; + + /** + * The object to animate. + */ + private Scenery object; + + /** + * Constructs a new {@code Animation} {@code Object}. + * @param id The animation id. + */ + public Animation(int id) { + this(id, 0, Priority.MID); + } + + /** + * Constructs a new {@code Animation}. + * @param id the id. + * @return + */ + public static Animation create(int id) { + return new Animation(id, 0, Priority.MID); + } + + /** + * Constructs a new {@code Animation} {@code Object}. + * @param id The animation id. + */ + public Animation(int id, Priority priority) { + this(id, 0, priority); + } + + /** + * Constructs a new {@code Animation} {@code Object}. + * @param id The animation id. + * @param delay The animation delay. + */ + public Animation(int id, int delay) { + this(id, delay, Priority.MID); + } + + /** + * Constructs a new {@code Animation} {@code Object}. + * @param id The animation id. + * @param delay The animation delay. + */ + public Animation(int id, int delay, Priority priority) { + this.id = id; + this.delay = delay; + this.priority = priority; + } + + /** + * Gets the animation definitions of this animation. + * @return The animation definitions. + */ + public AnimationDefinition getDefinition() { + if (definition == null) { + definition = AnimationDefinition.forId(id); + } + return definition; + } + + /** + * The duration of the animation. + * @return The duration in ticks. + */ + public int getDuration() { + AnimationDefinition def = getDefinition(); + return def != null ? def.getDurationTicks() : 1; + } + + /** + * Get the id. + * @return the id + */ + public int getId() { + return id; + } + + /** + * Get the delay. + * @return the delay + */ + public int getDelay() { + return delay; + } + + /** + * Sets the id. + * @param id + */ + public void setId(int id) { + this.id = id; + } + + /** + * @return the priority. + */ + public Priority getPriority() { + return priority; + } + + /** + * Gets the object. + * @return The object. + */ + public Scenery getObject() { + return object; + } + + /** + * Sets the object. + * @param object The object to set. + */ + public void setObject(Scenery object) { + this.object = object; + } + + /** + * Sets the priority. + * @param priority The priority. + */ + public void setPriority(Priority priority) { + this.priority = priority; + } + + @Override + public String toString() { + return "Animation [priority=" + priority + ", id=" + id + "]"; + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/world/update/flag/context/ChatMessage.kt b/Server/src/main/core/game/world/update/flag/context/ChatMessage.kt new file mode 100644 index 0000000..c7ee24f --- /dev/null +++ b/Server/src/main/core/game/world/update/flag/context/ChatMessage.kt @@ -0,0 +1,43 @@ +package core.game.world.update.flag.context + +import core.game.node.entity.player.Player +import core.game.node.entity.player.info.Rights + +/** + * Represents a chat message. + * @author Emperor + */ +class ChatMessage +/** + * Constructs a new `ChatMessage` `Object`. + * @param player The player. + * @param text The chat text. + * @param effects The chat effects. + * @param numChars The num chars. + */(player: Player, text: String, effects: Int, numChars: Int) { + /** + * The player reference. + */ + var player: Player = player + private set + /** + * The chat text. + */ + var text: String = text + private set + /** + * The effects. + */ + var effects = effects + private set + /** + * The numChars. + */ + var numChars = numChars + private set + + var chatIcon = Rights.getChatIcon(player) + + @JvmField + var isQuickChat = false +} diff --git a/Server/src/main/core/game/world/update/flag/context/ForceMoveCtx.kt b/Server/src/main/core/game/world/update/flag/context/ForceMoveCtx.kt new file mode 100644 index 0000000..2c28531 --- /dev/null +++ b/Server/src/main/core/game/world/update/flag/context/ForceMoveCtx.kt @@ -0,0 +1,5 @@ +package core.game.world.update.flag.context + +import core.game.world.map.* + +data class ForceMoveCtx (val start: Location, val dest: Location, val startArrive: Int, val destArrive: Int, val direction: Direction) diff --git a/Server/src/main/core/game/world/update/flag/context/Graphics.java b/Server/src/main/core/game/world/update/flag/context/Graphics.java new file mode 100644 index 0000000..37dea63 --- /dev/null +++ b/Server/src/main/core/game/world/update/flag/context/Graphics.java @@ -0,0 +1,113 @@ +package core.game.world.update.flag.context; + +import core.game.world.map.Location; +import core.game.world.map.RegionManager; +import core.game.world.update.flag.chunk.GraphicUpdateFlag; + +/** + * Represents a graphic. + * @author Emperor + */ +public class Graphics { + + /** + * The graphic id. + */ + private final int id; + + /** + * The graphic height. + */ + private final int height; + + /** + * The graphic height. + */ + private final int delay; + + /** + * Constructs a new {@code Graphics} {@code Object}. + * @param id The graphics id. + */ + public Graphics(int id) { + this(id, 0, 0); + } + + /** + * Constructs a new {@code Graphics} {@code Object}. + * @param id The graphics id. + * @param height The graphics height. + */ + public Graphics(int id, int height) { + this(id, height, 0); + } + + /** + * Constructs a new {@code Graphics} {@code Object}. + * @param id The graphics id. + * @param height The graphics height. + * @param delay The graphics delay. + */ + public Graphics(int id, int height, int delay) { + this.id = id; + this.height = height; + this.delay = delay; + } + + /** + * Constructs a new graphic. + * @param id The graphic id. + * @return The graphics instance. + */ + public static Graphics create(int id) { + return new Graphics(id, 0, 0); + } + + /** + * Constructs a new graphic. + * @param id The graphic id. + * @param height The graphic height. + * @return The graphics instance. + */ + public static Graphics create(int id, int height) { + return new Graphics(id, height, 0); + } + + /** + * Sends a graphic on a location. + * @param graphic The graphic. + * @param l The location. + */ + public static void send(Graphics graphic, Location l) { + RegionManager.getRegionChunk(l).flag(new GraphicUpdateFlag(graphic, l)); + } + + /** + * Get the graphic id. + * @return The graphic id. + */ + public int getId() { + return id; + } + + /** + * Get the graphic height. + * @return The graphic height. + */ + public int getHeight() { + return height; + } + + /** + * Gets the delay. + * @return The delay. + */ + public int getDelay() { + return delay; + } + + @Override + public String toString() { + return "Graphics [id=" + id + ", height=" + height + ", delay=" + delay + "]"; + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/world/update/flag/context/HitMark.java b/Server/src/main/core/game/world/update/flag/context/HitMark.java new file mode 100644 index 0000000..7df5c73 --- /dev/null +++ b/Server/src/main/core/game/world/update/flag/context/HitMark.java @@ -0,0 +1,89 @@ +package core.game.world.update.flag.context; + +import core.game.node.entity.Entity; + +/** + * Represents a hit mark. + * @author Emperor + */ +public class HitMark { + /** + * The amount of damage dealt. + */ + private final int damage; + + /** + * The hit type. + */ + private final int type; + + /** + * The entity's lifepoints. + */ + private int lifepoints; + + /** + * The entity. + */ + private final Entity entity; + + public boolean showHealthBar = true; + + /** + * Constructs a new {@code HitMark} {@code Object}. + * @param damage The amount of damage. + * @param type The hit type; + * @param entity The entity. + */ + public HitMark(int damage, int type, Entity entity) { + this.damage = damage; + this.type = type; + this.entity = entity; + } + + public HitMark(int damage, int type, Entity entity, boolean showHealthBar) { + this.damage = damage; + this.type = type; + this.entity = entity; + this.showHealthBar = showHealthBar; + } + + /** + * Gets the damage. + * @return The damage. + */ + public int getDamage() { + return damage; + } + + /** + * Gets the type. + * @return The type. + */ + public int getType() { + return type; + } + + /** + * @return the entity. + */ + public Entity getEntity() { + return entity; + } + + /** + * Gets the lifepoints. + * @return The lifepoints. + */ + public int getLifepoints() { + return lifepoints; + } + + /** + * Sets the lifepoints. + * @param lifepoints The lifepoints to set. + */ + public void setLifepoints(int lifepoints) { + this.lifepoints = lifepoints; + } +} diff --git a/Server/src/main/core/game/worldevents/WorldEvent.kt b/Server/src/main/core/game/worldevents/WorldEvent.kt new file mode 100644 index 0000000..705d458 --- /dev/null +++ b/Server/src/main/core/game/worldevents/WorldEvent.kt @@ -0,0 +1,73 @@ +package core.game.worldevents + +import core.ServerStore +import core.api.ContentInterface +import core.plugin.ClassScanner +import core.plugin.Plugin +import core.tools.Log +import org.json.simple.JSONObject +import java.util.* + +/** + * The class other world events should extend off of. + * @author Ceikry + */ +abstract class WorldEvent(var name: String) : ContentInterface { + var plugins = PluginSet() + + /** + * if the event is active or not. Can be used to check dates or just always return true + * whatever you need for this specific event + */ + open fun checkActive(cal: Calendar): Boolean { + return false + } + + /** + * Used to initialize the event + * The WorldEventInitializer runs this if checkActive() returns true. + */ + open fun initEvent(){ + } + + /** + * Used to log world event messages in a standard and organized way. + */ + fun log(message: String){ + core.api.log(this::class.java, Log.FINE, "[World Events($name)] $message") + } +} + + +/** + * A class that holds a set of plugins that shouldn't be initialized by default. + * Can be used to initialize all of its plugins cleanly. + */ +class PluginSet(vararg val plugins: Plugin<*>){ + val set = ArrayList(plugins.asList()) + fun initialize() { + ClassScanner.definePlugins(*set.toTypedArray()) + } + fun add(plugin: Plugin<*>){ + set.add(plugin) + } +} + +/** + * Static object for storing instances of loaded events. + */ +object WorldEvents { + private var events = hashMapOf() + + fun add(event: WorldEvent){ + events[event.name.lowercase(Locale.getDefault())] = event + } + + fun get(name: String): WorldEvent?{ + return events[name.lowercase(Locale.getDefault())] + } + + fun getArchive() : JSONObject { + return ServerStore.getArchive("world-event-status") + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/worldevents/holiday/HolidayRandomEventNPC.kt b/Server/src/main/core/game/worldevents/holiday/HolidayRandomEventNPC.kt new file mode 100644 index 0000000..8244518 --- /dev/null +++ b/Server/src/main/core/game/worldevents/holiday/HolidayRandomEventNPC.kt @@ -0,0 +1,85 @@ +package core.game.worldevents.holiday + +import core.api.* +import core.game.interaction.MovementPulse +import core.game.node.entity.impl.PulseType +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.world.map.Location +import core.game.world.map.RegionManager +import core.game.world.map.path.Pathfinder +import core.tools.secondsToTicks +import org.rs09.consts.Sounds +import kotlin.reflect.full.createInstance + +abstract class HolidayRandomEventNPC(id:Int) : NPC(id) { + lateinit var player: Player + var spawnLocation: Location? = null + var initialized = false + var finalized = false + var timerPaused = false + var ticksLeft = secondsToTicks(30) + + open fun create(player: Player, type: String = ""): HolidayRandomEventNPC { + val event = this::class.createInstance() + event.player = player + event.spawnLocation = RegionManager.getSpawnLocation(player, this) + return event + } + + open fun terminate() { + pulseManager.clear(PulseType.STANDARD) + if (initialized && !finalized) { + poofClear(this) + playGlobalAudio(this.location, Sounds.SMOKEPUFF2_1931, 100) + } + finalized = true + } + + open fun follow() { + pulseManager.run((object : MovementPulse(this, player, Pathfinder.DUMB) { + override fun pulse(): Boolean { + face(player) + return false + } + }), PulseType.STANDARD) + } + + override fun tick() { + super.tick() + if (player.getAttribute("holiday-npc", null) != this) { + terminate() + return + } + if (!player.getAttribute("holidayrandom:pause", false)) { + ticksLeft-- + } + if (!pulseManager.hasPulseRunning() && !finalized) { + follow() + } + if (!player.isActive || !player.location.withinDistance(location, 10)) { + terminate() + } + if (ticksLeft <= 0 && initialized) { + terminate() + initialized = false + } + } + + override fun init() { + initialized = true + finalized = false + timerPaused = false + spawnLocation ?: terminate() + location = spawnLocation + player.setAttribute("holiday-npc", this) + super.init() + } + + override fun clear() { + super.clear() + if(player.getAttribute("holiday-npc", null) == this) player.removeAttribute("holiday-npc") + } + + abstract fun talkTo(npc: NPC) +} \ No newline at end of file diff --git a/Server/src/main/core/game/worldevents/holiday/HolidayRandomEvents.kt b/Server/src/main/core/game/worldevents/holiday/HolidayRandomEvents.kt new file mode 100644 index 0000000..f1560ba --- /dev/null +++ b/Server/src/main/core/game/worldevents/holiday/HolidayRandomEvents.kt @@ -0,0 +1,49 @@ +package core.game.worldevents.holiday + +import core.game.worldevents.holiday.christmas.randoms.* +import core.game.worldevents.holiday.halloween.randoms.* + +enum class HolidayRandomEvents(val npc: HolidayRandomEventNPC, val type: String) { + BLACK_CAT(npc = BlackCatHolidayRandomNPC(), "halloween"), + SPIDER(npc = SpiderHolidayRandomNPC(), "halloween"), + GHOST(npc = GhostHolidayRandomNPC(), "halloween"), + ZOMBIE(npc = ZombieHolidayRandomNPC(), "halloween"), + WITCH(npc = WitchHolidayRandomNPC(), "halloween"), + DEATH(npc = DeathHolidayRandomNPC(), "halloween"), + VAMPIRE(npc = VampireHolidayRandomNPC(), "halloween"), + CHOIR(npc = ChoirHolidayRandomNPC(), "christmas"), + SANTA(npc = SantaHolidayRandomNPC(), "christmas"), + SNOWMAN_FIGHT(npc = SnowmanFightHolidayRandom(), "christmas"), + JACK_FROST(npc = JackFrostHolidayRandomNPC(), "christmas"), + SNOWMAN(npc = SnowmanHolidayRandomNPC(), "christmas"), + SNOWSTORM(npc = SnowStormHolidayRandomNPC(), "christmas"), + COOK(npc = CookHolidayRandomNPC(), "christmas"); + + companion object { + @JvmField + val halloweenEventsList = ArrayList() + val christmasEventsList = ArrayList() + val holidayRandomIDs = HolidayRandomEvents.values().map { it.npc.id }.toList() + + init { + populateMappings() + } + + fun getHolidayRandom(type: String): HolidayRandomEvents { + return when (type) { + "halloween" -> halloweenEventsList.random() + "christmas" -> christmasEventsList.random() + else -> throw Exception("Invalid event type!") + } + } + + private fun populateMappings() { + for (event in values()) { + when(event.type) { + "halloween" -> halloweenEventsList.add(event) + "christmas" -> christmasEventsList.add(event) + } + } + } + } +} diff --git a/Server/src/main/core/game/worldevents/holiday/HolidayRandoms.kt b/Server/src/main/core/game/worldevents/holiday/HolidayRandoms.kt new file mode 100644 index 0000000..cf63a2e --- /dev/null +++ b/Server/src/main/core/game/worldevents/holiday/HolidayRandoms.kt @@ -0,0 +1,271 @@ +package core.game.worldevents.holiday + +import content.global.ame.RandomEventNPC +import core.ServerConstants +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.system.command.Privilege +import core.game.system.timer.PersistTimer +import core.game.world.map.zone.ZoneRestriction +import core.game.world.repository.Repository +import core.tools.RandomFunction +import core.tools.colorize +import core.tools.minutesToTicks +import org.json.simple.JSONObject +import java.time.LocalDate +import java.time.Month + +class HolidayRandoms() : PersistTimer(0, "holiday", isAuto = true), Commands { + var paused = false + var nextRandom: HolidayRandomEvents? = null + var currentHoliday: String? = null + val halloweenStartDate = LocalDate.of(LocalDate.now().year, Month.OCTOBER, 17) + val halloweenEndDate = LocalDate.of(LocalDate.now().year, Month.NOVEMBER, 7) + val christmasStartDate = LocalDate.of(LocalDate.now().year, Month.DECEMBER, 1) + val christmasEndDate = LocalDate.of(LocalDate.now().year, Month.DECEMBER, 31) + + override fun run(entity: Entity): Boolean { + if (entity !is Player) return false + + setNextExecution() + + if (!canSpawn(entity)) { + delayNextExecution() + return true + } + + val eventSelection = rollEventPool() + val eventNpc = eventSelection.npc.create(entity) + if (eventNpc.spawnLocation == null) { + entity.debug("[HolidayRandom] Attempted to spawn random, but spawnLoc was null.") + delayNextExecution() + return true + } + + eventNpc.init() + setAttribute(entity, EVENT_NPC, eventNpc) + setAttribute(eventNpc, EVENT_NPC, eventNpc) + entity.debug("[HolidayRandom] Fired ${eventSelection.name}.") + return true + } + + override fun onRegister(entity: Entity) { + if (entity !is Player || entity.isArtificial || !ServerConstants.HOLIDAY_EVENT_RANDOMS) { + entity.timers.removeTimer(this) + return + } + + val player = entity.asPlayer() + when (checkIfHoliday()) { + "halloween" -> { + sendMessage(player, colorize("%OA chill goes down your spine...")) + currentHoliday = "halloween" + } + "christmas" -> { + sendMessage(player, colorize("%GHappy Holidays.")) + currentHoliday = "christmas" + } + "none" -> player.timers.removeTimer(this) + } + + if (runInterval == 0) + setNextExecution() + } + + fun checkIfHoliday(): String { + val currentDate = LocalDate.now() + if ((!currentDate.isBefore(halloweenStartDate) && !currentDate.isAfter(halloweenEndDate)) || ServerConstants.FORCE_HALLOWEEN_EVENTS) + return "halloween" + + if ((!currentDate.isBefore(christmasStartDate) && !currentDate.isAfter(christmasEndDate)) || ServerConstants.FORCE_CHRISTMAS_EVENTS) + return "christmas" + + return "none" + } + + override fun save(root: JSONObject, entity: Entity) { + root["ticksRemaining"] = (nextExecution - getWorldTicks()).toString() + } + + override fun parse(root: JSONObject, entity: Entity) { + runInterval = (root["ticksRemaining"]?.toString()?.toIntOrNull() ?: 0) + nextExecution = getWorldTicks() + runInterval + } + + private fun canSpawn(entity: Entity) : Boolean { + if (entity.zoneMonitor.isRestricted(ZoneRestriction.RANDOM_EVENTS) || getAttribute(entity, "re-npc", null) != null) + return false + + val current = getAttribute(entity, EVENT_NPC, null) + if (current != null) + return false + + if (paused || entity.inCombat()) + return false + + return true + } + + private fun delayNextExecution() { + runInterval = 50 + nextExecution = getWorldTicks() + runInterval + + } + + private fun setNextExecution() { + runInterval = RandomFunction.random(MIN_DELAY_TICKS, MAX_DELAY_TICKS + 1) + nextExecution = getWorldTicks() + runInterval + } + + private fun rollEventPool() : HolidayRandomEvents { + if (nextRandom != null) { + val result = nextRandom!! + nextRandom = null + return result + } + return when (currentHoliday) { + "halloween" -> HolidayRandomEvents.getHolidayRandom("halloween") + "christmas" -> HolidayRandomEvents.getHolidayRandom("christmas") + else -> throw Exception("Invalid event type!") + } + } + + override fun defineCommands() { + define("hrevent", Privilege.ADMIN, "::hrevent [-p] player name [-e event name]", "Spawns a holiday random event for the target player.
Optional -e parameter to pass a specific event.") { player, args -> + if (args.size == 1) { + val possible = HolidayRandomEvents.values() + for (event in possible) { + notify(player, event.name.lowercase()) + } + return@define + } + + val arg = parseCommandArgs(args.joinToString(" ")) + val target = Repository.getPlayerByName(arg.targetPlayer) + + if (getTimer(player) == null) + reject(player, "No holiday random events are active. To force a holiday's random events use ::forcehrevents") + + if (target == null) + reject(player, "Unable to find user ${arg.targetPlayer}.") + + forceEvent(target!!, arg.targetEvent) + } + + define("forcehrevents", Privilege.ADMIN, "::forcehrevents [eventname]", "Force enable holiday random events.") { player, args -> + if (args.size == 1) { + notify(player, "Holidays: halloween, christmas") + return@define + } + val event = args[1] + if (checkIfHoliday() != "none") + reject(player, "Holiday randoms are already enabled: ${checkIfHoliday()}. Use ::stophrevents first.") + ServerConstants.HOLIDAY_EVENT_RANDOMS = true + when (event) { + "halloween" -> { + ServerConstants.FORCE_HALLOWEEN_EVENTS = true + for (p in Repository.players) { + if (getTimer(p) != null || p.isArtificial) { + continue + } + notify(p, colorize("%RHalloween Randoms are now enabled!")) + registerTimer(p, HolidayRandoms()) + } + } + "christmas" -> { + ServerConstants.FORCE_CHRISTMAS_EVENTS = true + for (p in Repository.players) { + if (getTimer(p) != null || p.isArtificial) { + continue + } + notify(p, colorize("%GChristmas Randoms are now enabled!")) + registerTimer(p, HolidayRandoms()) + } + } + else -> reject(player, "Invalid event!") + } + } + + define("stophrevents", Privilege.ADMIN, "::stophrevents", "Stops all holiday random events.") { player, _ -> + if (checkIfHoliday() == "none" || !ServerConstants.HOLIDAY_EVENT_RANDOMS) + reject(player, "No holiday random events are currently active.") + ServerConstants.HOLIDAY_EVENT_RANDOMS = false + ServerConstants.FORCE_HALLOWEEN_EVENTS = false + ServerConstants.FORCE_CHRISTMAS_EVENTS = false + for (p in Repository.players) { + if (getTimer(p) == null) { + continue + } + removeHolidayTimer(p) + notify(p, "Holiday random events are now disabled!") + } + } + } + + data class CommandArgs (val targetPlayer: String, val targetEvent: HolidayRandomEvents?) + + companion object { + const val EVENT_NPC = "holiday-npc" + val MIN_DELAY_TICKS = minutesToTicks(30) + val MAX_DELAY_TICKS = minutesToTicks(90) + + fun terminateEventNpc (player: Player) { + getEventNpc(player)?.terminate() + } + + fun getEventNpc (player: Player) : HolidayRandomEventNPC? { + return getAttribute(player, EVENT_NPC, null) + } + + fun pause (player: Player) { + val timer = getTimer(player) ?: return + timer.paused = true + } + + fun unpause (player: Player) { + val timer = getTimer(player) ?: return + timer.paused = false + } + + fun removeHolidayTimer (player: Player) { + val timer = getTimer(player) ?: return + removeTimer(player, timer) + } + + fun forceEvent (player: Player, event: HolidayRandomEvents? = null) { + val timer = getTimer(player) ?: return + timer.nextExecution = getWorldTicks() + timer.nextRandom = event + } + + fun parseCommandArgs (args: String, commandName: String = "hrevent") : CommandArgs { + val tokens = args.split(" ") + val modeTokens = arrayOf("-p", "-e") + + var userString = "" + var eventString = "" + var lastMode = "-p" + + for (token in tokens) { + when (token) { + commandName -> continue + in modeTokens -> lastMode = token + else -> when (lastMode) { + "-p" -> userString += "$token " + "-e" -> eventString += "$token " + } + } + } + + val username = userString.trim().lowercase().replace(" ", "_") + val eventName = eventString.trim().uppercase().replace(" ", "_") + + var event: HolidayRandomEvents? = null + + try { event = HolidayRandomEvents.valueOf(eventName) } catch (_: Exception) {} + + return CommandArgs(username, event) + } + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/worldevents/holiday/ResetHolidayAppearance.kt b/Server/src/main/core/game/worldevents/holiday/ResetHolidayAppearance.kt new file mode 100644 index 0000000..079c40c --- /dev/null +++ b/Server/src/main/core/game/worldevents/holiday/ResetHolidayAppearance.kt @@ -0,0 +1,23 @@ +package core.game.worldevents.holiday + +import core.api.playAudio +import core.api.sendMessage +import core.api.visualize +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.system.timer.RSTimer +import core.tools.minutesToTicks +import core.tools.secondsToTicks +import org.rs09.consts.Sounds + +class ResetHolidayAppearance() : RSTimer(minutesToTicks(1), "reset-holiday-appearance") { + override fun run(entity: Entity): Boolean { + if (entity is Player) { + entity.asPlayer().appearance.transformNPC(-1) + playAudio(entity.asPlayer(), Sounds.WEAKEN_HIT_3010) + visualize(entity, -1, 86) + } + entity.timers.removeTimer(this) + return true + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/worldevents/holiday/christmas/Giftmas.kt b/Server/src/main/core/game/worldevents/holiday/christmas/Giftmas.kt new file mode 100644 index 0000000..e77df1a --- /dev/null +++ b/Server/src/main/core/game/worldevents/holiday/christmas/Giftmas.kt @@ -0,0 +1,162 @@ +package core.game.worldevents.holiday.christmas + +import core.api.* +import core.game.event.EventHook +import core.game.event.XPGainEvent +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.tools.RandomFunction +import org.json.simple.JSONObject +import org.rs09.consts.Items +import core.ServerStore +import core.ServerStore.Companion.getBoolean +import core.ServerStore.Companion.getInt +import core.api.Event +import core.api.utils.WeightBasedTable +import core.api.utils.WeightedItem +import core.game.worldevents.WorldEvents +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.system.command.Privilege +import core.game.world.repository.Repository +import core.tools.colorize + +class Giftmas : Commands, StartupListener, LoginListener, InteractionListener { + override fun startup() { + if (checkActive()) + init() + } + + fun checkActive(): Boolean { + val archive = getArchive() + return archive.getBoolean("active") + } + + override fun login(player: Player) { + if (!checkActive()) return + player.hook(Event.XpGained, XpGainHook) + } + + fun init() { + try { + on(Items.MYSTERY_BOX_6199, IntType.ITEM, "open") { player, node -> + val loot = MBOX_LOOT.roll().first() + + if (!removeItem(player, node.asItem())) return@on true + + sendDialogue(player, "You open the mystery box and find ${loot.amount}x ${loot.name.lowercase()}!") + addItem(player, loot.id, loot.amount) + return@on true + } + } catch (ignored: Exception) {} + + for (player in Repository.players) + player.hook(Event.XpGained, XpGainHook) + } + + fun cleanup() { + for (player in Repository.players) + player.unhook(XpGainHook) + } + + override fun defineCommands() { + define("toggle-giftmas", Privilege.ADMIN, "", "Toggles the giftmas christmas event.") {player, args -> + val enabled = checkActive() + getArchive()["active"] = !enabled + notify(player, "Giftmas is now ${if (enabled) "DISABLED" else "ENABLED"}.") + if (!enabled) { + init() + } else { + cleanup() + } + } + } + + object XpGainHook : EventHook { + override fun process(entity: Entity, event: XPGainEvent) { + val wasCombat = event.skillId in 0..6 + val daily = getDailyGifts(entity.asPlayer(), wasCombat) + val player = entity.asPlayer() + val cooldown = entity.getAttribute("christmas-cooldown", 0L) + + if (event.amount < 25.0) return + if (!RandomFunction.roll(15)) return + if (daily >= if (wasCombat) DAILY_LIMIT_COMBAT else DAILY_LIMIT_SKILLING) return + if (System.currentTimeMillis() < cooldown) return + if (!addItem(player, Items.MYSTERY_BOX_6199)) return + + player.setAttribute("/save:christmas-cooldown", System.currentTimeMillis() + 5000L) + incrementDailyGifts(player, wasCombat) + sendMessage(player, MESSAGE_PRESENT_GRANTED) + + if (wasCombat && daily == DAILY_LIMIT_COMBAT - 1) + sendMessage(player, MESSAGE_DAILYXP_REACHED_COMBAT) + if (!wasCombat && daily == DAILY_LIMIT_SKILLING - 1) + sendMessage(player, MESSAGE_DAILYXP_REACHED_SKILLING) + } + + private fun getDailyGifts(player: Player, wasCombat: Boolean) : Int { + val archive = if (wasCombat) "daily-xmas-gifts-combat" else "daily-xmas-gifts-skilling" + return ServerStore.getArchive(archive).getInt(player.name) + } + + fun incrementDailyGifts(player: Player, wasCombat: Boolean) { + val start = getDailyGifts(player, wasCombat) + val archive = if (wasCombat) "daily-xmas-gifts-combat" else "daily-xmas-gifts-skilling" + ServerStore.getArchive(archive)[player.name] = start + 1 + } + } + + override fun defineListeners() {} + + companion object { + private val DAILY_LIMIT_SKILLING = 15 + private val DAILY_LIMIT_COMBAT = 5 + + private fun getArchive() : JSONObject { + val mainArchive = WorldEvents.getArchive() + if (!mainArchive.containsKey("giftmas")) + mainArchive["giftmas"] = JSONObject() + return mainArchive["giftmas"] as JSONObject + } + + private val MESSAGE_DAILYXP_REACHED_SKILLING = colorize("%RYou have reached your daily limit of presents from skilling!") + private val MESSAGE_DAILYXP_REACHED_COMBAT = colorize("%RYou have reached your daily limit of presents from combat!") + private val MESSAGE_PRESENT_GRANTED = colorize("%GYou find a present while training!") + val MBOX_LOOT = WeightBasedTable.create( + WeightedItem(Items.TOY_HORSEY_2520, 1, 1, 0.025), + WeightedItem(Items.TOY_HORSEY_2522, 1, 1, 0.025), + WeightedItem(Items.TOY_HORSEY_2524, 1, 1, 0.025), + WeightedItem(Items.TOY_HORSEY_2526, 1, 1, 0.025), + WeightedItem(Items.TOY_KITE_12844, 1, 1, 0.025), + WeightedItem(Items.COAL_453, 1, 1, 0.025), + WeightedItem(Items.MOLTEN_GLASS_1776, 25, 50, 0.25), + WeightedItem(Items.FLAX_1780, 15, 70, 0.25), + WeightedItem(Items.BOW_STRING_1778, 10, 50, 0.15), + WeightedItem(Items.UNCUT_SAPPHIRE_1624, 1, 5, 0.15), + WeightedItem(Items.UNCUT_EMERALD_1622, 1, 5, 0.15), + WeightedItem(Items.UNCUT_RUBY_1620, 1, 5, 0.15), + WeightedItem(Items.UNCUT_DIAMOND_1618, 1, 5, 0.15), + WeightedItem(Items.UNCUT_SAPPHIRE_1624, 100, 100, 0.0015), + WeightedItem(Items.UNCUT_EMERALD_1622, 100, 100, 0.0015), + WeightedItem(Items.UNCUT_RUBY_1620, 100, 100, 0.0015), + WeightedItem(Items.UNCUT_DIAMOND_1618, 100, 100, 0.0015), + WeightedItem(Items.PURE_ESSENCE_7937, 1, 50, 0.15), + WeightedItem(Items.PURE_ESSENCE_7937, 1000, 1000, 0.0015), + WeightedItem(Items.RANARR_SEED_5295, 1, 3, 0.065), + WeightedItem(Items.SNAPDRAGON_SEED_5300, 1, 3, 0.065), + WeightedItem(Items.GOLD_CHARM_12158, 1, 15, 0.15), + WeightedItem(Items.CRIMSON_CHARM_12160, 1, 15, 0.15), + WeightedItem(Items.BLUE_CHARM_12163, 1, 15, 0.15), + WeightedItem(Items.GREEN_CHARM_12159, 1, 15, 0.15), + WeightedItem(Items.PURPLE_SWEETS_10476, 1, 15, 0.25), + WeightedItem(Items.COINS_995, 100, 1000, 0.15), + WeightedItem(Items.COINS_995, 50000, 100000, 0.0015), + WeightedItem(Items.COINS_995, 1000000, 1000000, 0.0005), + WeightedItem(Items.NATURE_RUNE_561, 1, 10, 0.15), + WeightedItem(Items.ABYSSAL_WHIP_4151, 1, 1, 0.00005), + WeightedItem(Items.SANTA_HAT_1050, 1, 1, 0.00005), + + ).insertEasyClue(0.015).insertMediumClue(0.010).insertHardClue(0.005).insertRDTRoll(0.015) + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/worldevents/holiday/christmas/randoms/ChoirHolidayRandomNPC.kt b/Server/src/main/core/game/worldevents/holiday/christmas/randoms/ChoirHolidayRandomNPC.kt new file mode 100644 index 0000000..b63be9f --- /dev/null +++ b/Server/src/main/core/game/worldevents/holiday/christmas/randoms/ChoirHolidayRandomNPC.kt @@ -0,0 +1,63 @@ +package core.game.worldevents.holiday.christmas.randoms + +import core.api.* +import core.game.interaction.QueueStrength +import core.game.node.entity.npc.NPC +import core.game.worldevents.holiday.HolidayRandomEventNPC +import core.tools.RandomFunction +import org.rs09.consts.NPCs + +class ChoirHolidayRandomNPC() : HolidayRandomEventNPC(NPCs.ZANARIS_CHOIR_3312) { + override fun init() { + super.init() + queueScript(this, 4, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + face(player) + when (RandomFunction.getRandom(3)) { + 0 -> { + sendChat(this, "Jingle bells, jingle bells!") + sendChat(this, "Jingle all the way!", 4) + sendChat(this, "Oh what fun it is to ride", 8) + sendChat(this, "On a one unicorn open sleigh", 12) + sendChat(this, "HEY!", 15) + return@queueScript delayScript(this, 16) + } + 1 -> { + sendChat(this, "Silver bells") + sendChat(this, "Silver bells", 5) + sendChat(this, "It's Christmas time in the city", 10) + sendChat(this, "Ring a ling", 15) + sendChat(this, "Hear them ring", 20) + sendChat(this, "Soon it will be Christmas day", 25) + return@queueScript delayScript(this, 26) + } + 2 -> { + sendChat(this, "Deck the halls with boughs of ranarr") + sendChat(this, "Fa la la la la la la la!", 5) + sendChat(this, "Tis the season to be jolly", 10) + sendChat(this, "Fa la la la la la la la!", 15) + return@queueScript delayScript(this, 16) + } + 3 -> { + sendChat(this, "O Wintumber Tree, O Wintumber tree,") + sendChat(this, "How lovely are your branches!", 5) + sendChat(this, "O Wintumber Tree, O Wintumber tree,", 10) + sendChat(this, "Of all the trees most lovely", 15) + return@queueScript delayScript(this, 16) + } + else -> return@queueScript keepRunning(this) + } + } + 1 -> { + terminate() + return@queueScript stopExecuting(this) + } + else -> return@queueScript stopExecuting(this) + } + } + } + + override fun talkTo(npc: NPC) { + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/worldevents/holiday/christmas/randoms/CookHolidayRandomDialogue.kt b/Server/src/main/core/game/worldevents/holiday/christmas/randoms/CookHolidayRandomDialogue.kt new file mode 100644 index 0000000..012ccf8 --- /dev/null +++ b/Server/src/main/core/game/worldevents/holiday/christmas/randoms/CookHolidayRandomDialogue.kt @@ -0,0 +1,50 @@ +package core.game.worldevents.holiday.christmas.randoms + +import core.api.addItemOrDrop +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.worldevents.holiday.HolidayRandoms +import org.rs09.consts.Items + +class CookHolidayRandomDialogue : DialogueFile() { + private val cakes = listOf(Items.CAKE_1891, Items.CHOCOLATE_CAKE_1897, Items.MINT_CAKE_9475) + override fun handle(componentID: Int, buttonID: Int) { + if (HolidayRandoms.getEventNpc(player!!) == null) + player!!.dialogueInterpreter.close() + + when (stage) { + 0 -> npcl(FacialExpression.HAPPY, "Greetings, ${player!!.username.capitalize()}. Every year around christmas I give away cake to the community. Would you care for a fresh baked cake?").also { stage++ } + 1 -> options("Sure, I will take a cake.", "Why are you giving cakes away?", "No, thanks.").also { stage++ } + 2 -> when (buttonID) { + 1 -> playerl(FacialExpression.HAPPY, "Sure, I will take a cake.").also { stage = 40 } + 2 -> playerl(FacialExpression.HALF_ASKING, "Why are you giving away cakes?").also { stage = 20 } + 3 -> playerl(FacialExpression.NEUTRAL, "No, thanks.").also { stage = 10 } + } + 10 -> npcl(FacialExpression.HAPPY, "Okay, I will find someone else who wants it. Merry Christmas, ${player!!.username.capitalize()}.").also { stage++ } + 11 -> { + HolidayRandoms.terminateEventNpc(player!!) + end() + } + 20 -> npcl(FacialExpression.NEUTRAL, "It's just something I do this time of year... Errr... well...").also { stage++ } + 21 -> playerl(FacialExpression.HALF_ASKING, "Is there something else?").also { stage++ } + 22 -> npcl(FacialExpression.NEUTRAL, "I used to be the cook for the old Duke of Lumbridge. Visiting dignitaries praised me for my fine banquets!"). also { stage++ } + 23 -> npcl(FacialExpression.ANNOYED, "But then someone found a rule that said that only one family could hold that post.").also { stage++ } + 24 -> npcl(FacialExpression.ANGRY, "Overnight I was fired and replaced by some fool who can't even bake a cake without help!").also { stage++ } + 25 -> playerl(FacialExpression.NEUTRAL, "I'm sorry to hear that. It sounds as if you are a great cook!").also { stage++ } + 26 -> npcl(FacialExpression.HAPPY, "Thanks, I am!").also { stage++ } + 27 -> npcl(FacialExpression.LAUGH, "I also do this each year to show everyone how incapable that sorry excuse of a cook they replaced me with is.").also { stage++ } + 28 -> npcl(FacialExpression.HAPPY, "So, did you want a cake?").also { stage++ } + 29 -> options("Sure, I will take a cake.", "No, thanks.").also { stage++ } + 30 -> when (buttonID) { + 1 -> playerl(FacialExpression.HAPPY, "Sure, I will take a cake.").also { stage = 40 } + 2 -> playerl(FacialExpression.NEUTRAL, "No, thanks.").also { stage = 10 } + } + 40 -> npcl(FacialExpression.HAPPY, "Here is a the finest cake you will ever have! Merry Christmas, ${player!!.username.capitalize()}.").also { stage++ } + 41 -> { + HolidayRandoms.terminateEventNpc(player!!) + addItemOrDrop(player!!, cakes.random()) + end() + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/worldevents/holiday/christmas/randoms/CookHolidayRandomNPC.kt b/Server/src/main/core/game/worldevents/holiday/christmas/randoms/CookHolidayRandomNPC.kt new file mode 100644 index 0000000..3a33d48 --- /dev/null +++ b/Server/src/main/core/game/worldevents/holiday/christmas/randoms/CookHolidayRandomNPC.kt @@ -0,0 +1,32 @@ +package core.game.worldevents.holiday.christmas.randoms + +import core.api.* +import core.game.node.entity.npc.NPC +import core.game.worldevents.holiday.HolidayRandomEventNPC +import core.tools.RandomFunction +import core.tools.minutesToTicks +import org.rs09.consts.NPCs + +class CookHolidayRandomNPC : HolidayRandomEventNPC(NPCs.COOK_4239) { + private val cookLines = listOf("@name, are you there?", "Would you like a fresh baked cake, @name?", "Happy Holidays, @name!") + private var hasTalkedWith = false + + override fun init() { + ticksLeft = minutesToTicks(3) + sendChat(this, "Happy Holidays, ${player.username.capitalize()}!", 2) + super.init() + } + + override fun tick() { + if (RandomFunction.roll(15) && !hasTalkedWith) + sendChat(this, cookLines.random().replace("@name",player.username.capitalize())) + + super.tick() + } + + override fun talkTo(npc: NPC) { + face(player) + hasTalkedWith = true + openDialogue(player, CookHolidayRandomDialogue(), npc) + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/worldevents/holiday/christmas/randoms/JackFrostHolidayRandomNPC.kt b/Server/src/main/core/game/worldevents/holiday/christmas/randoms/JackFrostHolidayRandomNPC.kt new file mode 100644 index 0000000..01aace8 --- /dev/null +++ b/Server/src/main/core/game/worldevents/holiday/christmas/randoms/JackFrostHolidayRandomNPC.kt @@ -0,0 +1,64 @@ +package core.game.worldevents.holiday.christmas.randoms + + +import core.api.getPathableRandomLocalCoordinate +import core.api.* +import core.game.interaction.QueueStrength +import core.game.node.entity.impl.Projectile +import core.game.node.entity.npc.NPC +import core.game.world.map.path.Pathfinder +import core.game.world.update.flag.context.Graphics +import core.game.worldevents.holiday.HolidayRandomEventNPC +import core.tools.minutesToTicks +import org.rs09.consts.NPCs +import org.rs09.consts.Sounds + +class JackFrostHolidayRandomNPC : HolidayRandomEventNPC(NPCs.JACK_FROST_8517) { + + override fun init() { + ticksLeft = minutesToTicks(1) + spawnLocation = getPathableRandomLocalCoordinate(this, 3, player.location) + super.init() + } + + override fun tick() { + if (getWorldTicks() % 5 == 0) { + if (this.location.withinDistance(player.location, 1) || this.location.getDistance(player.location).toInt() > 3) { + val path = Pathfinder.find(this, getPathableRandomLocalCoordinate(this, 3, player.location)) + path.walk(this) + } else { + throwSnowball() + } + } + super.tick() + } + + override fun talkTo(npc: NPC) { + sendMessage(player, "He does not seem interested in talking.") + } + + override fun follow() { + } + + private fun throwSnowball() { + queueScript(this, 0, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + face(this, player) + visualize(this, 7530, -1) + return@queueScript delayScript(this, 1) + } + 1 -> { + Projectile.create(this, player, 861, 30, 10).send() + return@queueScript delayScript(this, this.location.getDistance(player.location).toInt()) + } + 2 -> { + player.graphics(Graphics(1282)) + playGlobalAudio(player.location, Sounds.GUBLINCH_SNOWBALL_3295) + return@queueScript stopExecuting(this) + } + else -> return@queueScript stopExecuting(this) + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/worldevents/holiday/christmas/randoms/SantaHolidayRandomDialogue.kt b/Server/src/main/core/game/worldevents/holiday/christmas/randoms/SantaHolidayRandomDialogue.kt new file mode 100644 index 0000000..79991e5 --- /dev/null +++ b/Server/src/main/core/game/worldevents/holiday/christmas/randoms/SantaHolidayRandomDialogue.kt @@ -0,0 +1,54 @@ +package core.game.worldevents.holiday.christmas.randoms + +import core.api.addItem +import core.api.addItemOrDrop +import core.api.getAttribute +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.worldevents.holiday.HolidayRandoms +import core.game.worldevents.holiday.christmas.Giftmas +import core.tools.END_DIALOGUE +import core.tools.RandomFunction +import org.rs09.consts.Items + +class SantaHolidayRandomDialogue : DialogueFile() { + + override fun handle(componentID: Int, buttonID: Int) { + if (HolidayRandoms.getEventNpc(player!!) == null) + player!!.dialogueInterpreter.close() + + when (stage) { + 0 -> npcl(FacialExpression.JOLLY, "Ho Ho Ho!").also { stage++ } + 1 -> npcl(FacialExpression.HAPPY, "Merry Christmas, ${player!!.username}! Would you like to know if you are on the nice or naughty list?").also { stage = 10 } + + 10 -> options("Yes, please.", "No, thanks."). also { stage = 11 } + 11 -> when (buttonID) { + 1 -> playerl(FacialExpression.HAPPY, "Yes, please.").also { stage = 20 } + 2 -> { + playerl(FacialExpression.NEUTRAL, "No, thanks.") + stage = END_DIALOGUE + HolidayRandoms.terminateEventNpc(player!!) + } + } + 20 -> if (getAttribute(HolidayRandoms.getEventNpc(player!!)!!, "playerisnice", false)) { + npcl(FacialExpression.HAPPY, "Let me check my list... ${player!!.username}.. You are on the nice list!").also { stage = 30 } + } else { + npcl(FacialExpression.SAD, "Let me check my list... ${player!!.username}.. You are on the naughty list!").also { stage = 40 } + } + 30 -> npcl(FacialExpression.HAPPY, "Since you have been a good ${if (player!!.isMale) "boy" else "girl"} this year, you get a gift. Merry Christmas, ${player!!.username}!").also { stage = 31 } + 31 -> { + val loot = Giftmas.MBOX_LOOT.roll().first() + addItemOrDrop(player!!, loot.id, loot.amount) + HolidayRandoms.terminateEventNpc(player!!) + end() + } + 40 -> npcl(FacialExpression.NEUTRAL, "If you work on being a good ${if (player!!.isMale) "boy" else "girl"} from now on you will make it on the nice list!").also { stage = 41 } + 41 -> npcl(FacialExpression.NEUTRAL, "Since you are on the naughty list, you get coal.").also { stage = 42 } + 42 -> { + addItemOrDrop(player!!, Items.COAL_454, RandomFunction.random(1, 21)) + HolidayRandoms.terminateEventNpc(player!!) + end() + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/worldevents/holiday/christmas/randoms/SantaHolidayRandomNPC.kt b/Server/src/main/core/game/worldevents/holiday/christmas/randoms/SantaHolidayRandomNPC.kt new file mode 100644 index 0000000..84a384a --- /dev/null +++ b/Server/src/main/core/game/worldevents/holiday/christmas/randoms/SantaHolidayRandomNPC.kt @@ -0,0 +1,31 @@ +package core.game.worldevents.holiday.christmas.randoms + +import core.api.* +import core.game.node.entity.npc.NPC +import core.game.worldevents.holiday.HolidayRandomEventNPC +import core.tools.RandomFunction +import core.tools.minutesToTicks +import org.rs09.consts.NPCs + +class SantaHolidayRandomNPC() : HolidayRandomEventNPC(NPCs.SANTA_CLAUS_8540) { + + override fun init() { + spawnLocation = getPathableRandomLocalCoordinate(this, 1, player.location) + super.init() + ticksLeft = minutesToTicks(2) + setAttribute(this, "playerisnice", !RandomFunction.roll(3)) + sendChat(this, "Ho Ho Ho! Merry Christmas, ${player.username.capitalize()}!", 2) + } + + override fun tick() { + if (RandomFunction.roll(10)) + sendChat(this, "Ho Ho Ho! Merry Christmas, ${player.username.capitalize()}!") + + super.tick() + } + + override fun talkTo(npc: NPC) { + face(player) + openDialogue(player, SantaHolidayRandomDialogue(), npc) + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/worldevents/holiday/christmas/randoms/SnowStormHolidayRandomNPC.kt b/Server/src/main/core/game/worldevents/holiday/christmas/randoms/SnowStormHolidayRandomNPC.kt new file mode 100644 index 0000000..c10d937 --- /dev/null +++ b/Server/src/main/core/game/worldevents/holiday/christmas/randoms/SnowStormHolidayRandomNPC.kt @@ -0,0 +1,72 @@ +package core.game.worldevents.holiday.christmas.randoms + +import core.api.* +import core.game.node.entity.npc.NPC +import core.game.world.map.RegionManager +import core.game.world.map.path.Pathfinder +import core.game.worldevents.holiday.HolidayRandomEventNPC +import core.tools.RandomFunction +import core.tools.minutesToTicks +import org.rs09.consts.NPCs +import org.rs09.consts.Sounds + +class SnowStormHolidayRandomNPC : HolidayRandomEventNPC(NPCs.SNOW_6740) { + private lateinit var snowTwoNPC: NPC + private lateinit var snowThreeNPC: NPC + private lateinit var snowFourNPC: NPC + private lateinit var snowFiveNPC: NPC + private lateinit var snowNPCs: List + private val songs = listOf(189, 208, 209, 532, 547, 592) + private var snowFinalized = false + + override fun init() { + snowTwoNPC = create(NPCs.SNOW_6740, getPathableRandomLocalCoordinate(player, 3, player.location)) + snowThreeNPC = create(NPCs.SNOW_6740, getPathableRandomLocalCoordinate(player, 3, player.location)) + snowFourNPC = create(NPCs.SNOW_6740, getPathableRandomLocalCoordinate(player, 3, player.location)) + snowFiveNPC = create(NPCs.SNOW_6740, getPathableRandomLocalCoordinate(player, 3, player.location)) + snowNPCs = listOf(this, snowTwoNPC, snowThreeNPC, snowFourNPC, snowFiveNPC) + ticksLeft = minutesToTicks(2) + super.init() + snowTwoNPC.init() + snowThreeNPC.init() + snowFourNPC.init() + snowFiveNPC.init() + val nearbyPlayers = RegionManager.getLocalPlayers(player.location, 8) + for (p in nearbyPlayers) { + p.musicPlayer.unlock(songs.random(), true) + } + } + + override fun tick() { + if (getWorldTicks() % 8 == 0) { + moveSnow() + } + super.tick() + } + + private fun moveSnow() { + for (snow in snowNPCs) { + val snowPath = Pathfinder.find(snow, getPathableRandomLocalCoordinate(player, 4, player.location)) + snowPath.walk(snow) + + if (RandomFunction.roll(4)) + playGlobalAudio(snow.location, Sounds.ICY_WIND_2078) + } + } + + override fun follow() { + } + + override fun terminate() { + if (!snowFinalized) { + snowFinalized = true + for (snow in snowNPCs) { + poofClear(snow) + } + } + super.terminate() + } + + override fun talkTo(npc: NPC) { + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/worldevents/holiday/christmas/randoms/SnowmanFightBehavior.kt b/Server/src/main/core/game/worldevents/holiday/christmas/randoms/SnowmanFightBehavior.kt new file mode 100644 index 0000000..b874bd8 --- /dev/null +++ b/Server/src/main/core/game/worldevents/holiday/christmas/randoms/SnowmanFightBehavior.kt @@ -0,0 +1,21 @@ +package core.game.worldevents.holiday.christmas.randoms + +import core.api.getAttribute +import core.game.node.entity.Entity +import core.game.node.entity.combat.BattleState +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.Player +import core.game.worldevents.holiday.HolidayRandoms +import core.tools.RandomFunction + +class SnowmanFightBehavior : NPCBehavior() { + override fun onDeathStarted(self: NPC, killer: Entity) { + val holidayRandomPlayer = getAttribute(self, "holidayrandomplayer", null) ?: return + HolidayRandoms.terminateEventNpc(holidayRandomPlayer) + } + + override fun beforeAttackFinalized(self: NPC, victim: Entity, state: BattleState) { + state.estimatedHit = RandomFunction.getRandom(1) + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/worldevents/holiday/christmas/randoms/SnowmanFightHolidayRandom.kt b/Server/src/main/core/game/worldevents/holiday/christmas/randoms/SnowmanFightHolidayRandom.kt new file mode 100644 index 0000000..15e598b --- /dev/null +++ b/Server/src/main/core/game/worldevents/holiday/christmas/randoms/SnowmanFightHolidayRandom.kt @@ -0,0 +1,52 @@ +package core.game.worldevents.holiday.christmas.randoms + +import core.api.* +import core.game.node.entity.npc.NPC +import core.game.worldevents.holiday.HolidayRandomEventNPC +import core.tools.minutesToTicks +import org.rs09.consts.NPCs + +class SnowmanFightHolidayRandom : HolidayRandomEventNPC(NPCs.BARBARIAN_SNOWMAN_6742) { + private lateinit var otherSnowman: NPC + private val snowmen = listOf(NPCs.DRAGON_SNOWMAN_6743, NPCs.PIRATE_SNOWMAN_6745, NPCs.DWARF_SNOWMAN_6744) + private var snowmenFinalized = false + + override fun init() { + otherSnowman = create(snowmen.random(), getPathableRandomLocalCoordinate(player, 3, player.location)) + ticksLeft = minutesToTicks(3) + setAttribute(this, "holidayrandomplayer", player) + setAttribute(otherSnowman, "holidayrandomplayer", player) + setAttribute(otherSnowman, "holiday_random_extra_npc", true) + this.behavior = SnowmanFightBehavior() + otherSnowman.behavior = SnowmanFightBehavior() + super.init() + otherSnowman.init() + + this.attack(otherSnowman) + otherSnowman.attack(this) + } + + override fun tick() { + if (!this.inCombat() && getWorldTicks() % 20 == 0) { + this.teleport(otherSnowman.location) + this.attack(otherSnowman) + otherSnowman.attack(this) + } + super.tick() + } + + override fun terminate() { + if (!snowmenFinalized) { + snowmenFinalized = true + poofClear(otherSnowman) + } + super.terminate() + } + + override fun follow() { + } + + override fun talkTo(npc: NPC) { + sendMessage(player, "They seem a little busy.") + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/worldevents/holiday/christmas/randoms/SnowmanHolidayRandomDialogue.kt b/Server/src/main/core/game/worldevents/holiday/christmas/randoms/SnowmanHolidayRandomDialogue.kt new file mode 100644 index 0000000..ac43c2f --- /dev/null +++ b/Server/src/main/core/game/worldevents/holiday/christmas/randoms/SnowmanHolidayRandomDialogue.kt @@ -0,0 +1,68 @@ +package core.game.worldevents.holiday.christmas.randoms + +import core.api.* +import core.game.dialogue.DialogueFile +import core.game.dialogue.FacialExpression +import core.game.interaction.QueueStrength +import core.game.node.entity.player.link.emote.Emotes +import core.game.worldevents.holiday.HolidayRandoms +import org.rs09.consts.Items + + +class SnowmanHolidayRandomDialogue : DialogueFile() { + override fun handle(componentID: Int, buttonID: Int) { + if (HolidayRandoms.getEventNpc(player!!) == null) + player!!.dialogueInterpreter.close() + + when (stage) { + 0 -> npcl(FacialExpression.CHILD_NEUTRAL, "Greetings, ${player!!.username.capitalize()}. I'm visiting from the Land of Snow, but I need some help."). also { stage++ } + 1 -> options("What do you need?", "No, sorry.") .also { stage++ } + 2 -> when(buttonID) { + 1 -> playerl(FacialExpression.HALF_ASKING,"What do you need?").also { stage = 10 } + 2 -> playerl(FacialExpression.NEUTRAL,"No, sorry.").also { stage = 30 } + } + 10 -> npcl(FacialExpression.CHILD_NEUTRAL, "I visit Gielinor every year during this time when it is the coldest here, but it is still a little warm for us snowmen.").also { stage++ } + 11 -> npcl(FacialExpression.CHILD_NEUTRAL, "I'm really enjoying my visit, but I have started to melt. Would you happen to have a snowball?").also { stage++ } + 12 -> { + if (inInventory(player!!, Items.SNOWBALL_11951, 1)) { + playerl(FacialExpression.HAPPY, "Actually, I do! You can have it.").also { stage = 20 } + } else { + playerl(FacialExpression.NEUTRAL, "I don't have a snowball, sorry.").also { stage = 30 } + } + } + 20 -> { + npcl(FacialExpression.CHILD_NEUTRAL, "Thank you, ${player!!.username.capitalize()}!").also { stage++ } + } + 21 -> { + if (player!!.emoteManager.isUnlocked(Emotes.SNOWMAN_DANCE)) { + npcl(FacialExpression.CHILD_NEUTRAL, "Please take this lamp I found on my travels. Happy holidays, ${player!!.username.capitalize()}!").also { stage = 22 } + } else { + npcl(FacialExpression.CHILD_NEUTRAL, "Before I leave I will show you how to dance like us snowmen. Happy holidays, ${player!!.username.capitalize()}!").also { stage = 23 } + } + } + 22 -> { + if (removeItem(player!!, Items.SNOWBALL_11951)) + addItem(player!!, Items.LAMP_2528) + + end() + HolidayRandoms.terminateEventNpc(player!!) + } + 23 -> { + if (removeItem(player!!, Items.SNOWBALL_11951)) + player!!.emoteManager.unlock(Emotes.SNOWMAN_DANCE) + + queueScript(player!!, 2,QueueStrength.SOFT) { + sendDialogue(player!!, "You have unlocked the Snowman Dance emote!") + return@queueScript stopExecuting(player!!) + } + end() + HolidayRandoms.terminateEventNpc(player!!) + } + 30 -> npcl(FacialExpression.CHILD_NEUTRAL, "I must be going before I melt. Happy Holidays, ${player!!.username.capitalize()}.").also { stage++ } + 31 -> { + end() + HolidayRandoms.terminateEventNpc(player!!) + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/worldevents/holiday/christmas/randoms/SnowmanHolidayRandomNPC.kt b/Server/src/main/core/game/worldevents/holiday/christmas/randoms/SnowmanHolidayRandomNPC.kt new file mode 100644 index 0000000..6248e71 --- /dev/null +++ b/Server/src/main/core/game/worldevents/holiday/christmas/randoms/SnowmanHolidayRandomNPC.kt @@ -0,0 +1,32 @@ +package core.game.worldevents.holiday.christmas.randoms + +import core.api.* +import core.game.node.entity.npc.NPC +import core.game.worldevents.holiday.HolidayRandomEventNPC +import core.tools.RandomFunction +import core.tools.minutesToTicks +import org.rs09.consts.NPCs + +class SnowmanHolidayRandomNPC : HolidayRandomEventNPC(NPCs.SNOWMAN_6746) { + private val snowmanLines = listOf("@name, are you there?", "Excuse me, @name?", "@name, could I please speak with you?") + private var hasTalkedWith = false + + override fun init() { + super.init() + ticksLeft = minutesToTicks(2) + sendChat(this, "Happy holidays, ${player.username.capitalize()}!", 2) + } + + override fun tick() { + if (RandomFunction.roll(15) && !hasTalkedWith) + sendChat(this, snowmanLines.random().replace("@name",player.username.capitalize())) + + super.tick() + } + + override fun talkTo(npc: NPC) { + face(player) + hasTalkedWith = true + openDialogue(player, SnowmanHolidayRandomDialogue(), npc) + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/worldevents/holiday/easter/EasterEvent.kt b/Server/src/main/core/game/worldevents/holiday/easter/EasterEvent.kt new file mode 100644 index 0000000..6b129b9 --- /dev/null +++ b/Server/src/main/core/game/worldevents/holiday/easter/EasterEvent.kt @@ -0,0 +1,320 @@ +package core.game.worldevents.holiday.easter + +import core.ServerConstants +import core.api.* +import core.api.utils.WeightBasedTable +import core.api.utils.WeightedItem +import core.game.event.EventHook +import core.game.event.XPGainEvent +import core.game.interaction.IntType +import core.game.interaction.InteractionListener +import core.game.interaction.QueueStrength +import core.game.node.entity.Entity +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.emote.Emotes +import core.game.node.item.GroundItem +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import core.game.world.GameWorld +import core.game.world.map.Direction +import core.game.world.map.Location +import core.game.world.map.path.Pathfinder +import core.game.worldevents.WorldEvent +import core.tools.RandomFunction +import core.tools.StringUtils +import core.tools.colorize +import org.rs09.consts.Items +import java.util.* + +class EasterEvent : WorldEvent("easter"), TickListener, InteractionListener, LoginListener, Commands { + private val spawnedItems = ArrayList() + private var timeUntilNextEggSpawn = 0 + private var currentLoc = "" + + override fun tick() { + if (timeUntilNextEggSpawn-- > 0) return + timeUntilNextEggSpawn = EGG_SPAWN_TIME + + for (egg in spawnedItems) + { + GroundItemManager.destroy(egg) + } + spawnedItems.clear() + + val (locName, locData) = getRandomLocations() + currentLoc = locName + + for (loc in locData) + { + val gi = GroundItemManager.create(GroundItem( + Item(eggs.random()), + loc, + EGG_SPAWN_TIME, + null + )) + gi.forceVisible = true + spawnedItems.add(gi) + } + + sendNews("Eggs have appeared in $locName!") + } + + override fun login(player: Player) { + if (spawnedItems.isNotEmpty()) + sendMessage(player, colorize("%GEggs were last spotted in $currentLoc!")) + player.hook(Event.XpGained, xpEventHook) + } + + override fun defineCommands() { + define("eggspawntest") {player, _ -> + notify(player, "Spawning 10 eggs nearby...") + repeat(10) { spawnEggFor(player) } + } + } + + object xpEventHook : EventHook + { + override fun process(entity: Entity, event: XPGainEvent) { + if (entity !is Player) return + + val lastRoll = getAttribute(entity, LAST_EGG_ROLL, 0) + if (getWorldTicks() - lastRoll < 10) return + setAttribute(entity, LAST_EGG_ROLL, getWorldTicks()) + + val activeEggRate = if (GameWorld.settings!!.isDevMode) EGG_RATE_DEV else EGG_RATE + + if (RandomFunction.roll(activeEggRate)) + spawnEggFor(entity) + } + } + + + fun getRandomLocations() : Pair> + { + val toReturn = ArrayList() + val name = locNames.random() + val locs = locationsForName(name) + for (loc in locs) + if (RandomFunction.nextBool()) toReturn.add(loc) + return Pair(name, toReturn) + } + + override fun checkActive(cal: Calendar): Boolean { + return cal.get(Calendar.MONTH) == Calendar.APRIL || ServerConstants.FORCE_EASTER_EVENTS + } + + private fun onEggBroken (player: Player) + { + val eggsBroken = getAttribute(player, EGGS_BROKEN, 0) + 1 + + if (eggsBroken == 10) + { + player.emoteManager.unlock(Emotes.BUNNY_HOP) + Emotes.BUNNY_HOP.play(player) + sendMessage(player, colorize("%RYou have unlocked the 'Bunny Hop' emote!")) + } + else if (eggsBroken == 15) + { + addItemOrDrop(player, BUN_EARS) + sendMessage(player, colorize("%RYou have been given bunny ears!")) + } + else if (eggsBroken % 5 == 0) + { + var trackUnlocked = false; + for (track in tracks) + { + if (player.musicPlayer.hasUnlocked(track)) + continue + player.musicPlayer.unlock(track) + trackUnlocked = true + break + } + if (!trackUnlocked) + giveRandomLoot(player) + } + else giveRandomLoot(player) + + setAttribute(player, EGGS_BROKEN, eggsBroken) + } + + private fun giveRandomLoot (player: Player) + { + //Give some loot + val loot = lootTable.roll(player)[0] + addItemOrDrop(player, loot.id, loot.amount) + val term = if (loot.amount == 1) + if (StringUtils.isPlusN(loot.name)) "an" + else "a" + else "some" + + val name = if (loot.amount == 1) loot.name else StringUtils.plusS(loot.name) + sendMessage(player, "Inside the egg you find $term ${name.lowercase()}.") + } + + override fun defineListeners() { + on (eggs, IntType.GROUNDITEM, "take") {player, node -> + if (node !is GroundItem) return@on true + queueScript(player, strength = QueueStrength.NORMAL) { stage -> + when (stage) + { + 0 -> { + animate(player, STOMP_ANIM) + return@queueScript delayScript(player, 1) + } + 1 -> { + val item = GroundItemManager.get(node.id, node.location, null) + if (item == null || !item.isActive) return@queueScript stopExecuting(player) + sendGraphics(gfxForEgg(node.id), node.location) + GroundItemManager.destroy(node) + spawnedItems.remove(node) + onEggBroken(player) + return@queueScript stopExecuting(player) + } + } + return@queueScript keepRunning(player) + } + return@on true + } + on (eggs, IntType.ITEM, "release") {player, node -> + if (node !is Item) return@on true + queueScript(player, strength = QueueStrength.NORMAL) { stage -> + when (stage) + { + 0 -> { + animate(player, STOMP_ANIM) + return@queueScript delayScript(player, 1) + } + 1 -> { + if (!removeItem(player, node)) return@queueScript stopExecuting(player) + sendGraphics(gfxForEgg(node.id), player.location) + onEggBroken(player) + return@queueScript stopExecuting(player) + } + } + return@queueScript keepRunning(player) + } + return@on true + } + } + + companion object + { + const val LOC_LUM = "Lumbridge" + const val LOC_DRAYNOR = "Draynor Village" + const val LOC_FALADOR = "Falador" + const val LOC_EDGE = "Edgeville" + const val LOC_TGS = "Tree Gnome Stronghold" + const val EGG_SPAWN_TIME = 5_000 + const val EGG_A = 11027 + const val EGG_B = 11028 + const val EGG_C = 11029 + const val EGG_D = 11030 + const val GFX_A = 1040 + const val GFX_B = 1045 + const val GFX_C = 1042 + const val GFX_D = 1043 + const val STOMP_ANIM = 10017 + const val BUN_EARS = 14658 + const val TRACK_BSB = 502 + const val TRACK_EJ = 273 + const val TRACK_FB = 603 + const val EGG_RATE = 64 + const val EGG_RATE_DEV = 3 + + val EGGS_BROKEN = "/save:easter${ServerConstants.STARTUP_MOMENT.get(Calendar.YEAR)}:eggs" + val LAST_EGG_ROLL = "easter:lasteggroll" + val tracks = arrayOf(TRACK_BSB, TRACK_EJ, TRACK_FB) + val eggs = intArrayOf(EGG_A, EGG_B, EGG_C, EGG_D) + val locNames = arrayOf(LOC_LUM, LOC_DRAYNOR, LOC_FALADOR, LOC_EDGE, LOC_TGS) + val LUMBRIDGE_SPOTS = arrayOf(Location.create(3190, 3240, 0), + Location.create(3219, 3204, 0),Location.create(3212, 3201, 0),Location.create(3205, 3209, 0), + Location.create(3205, 3217, 0),Location.create(3211, 3213, 0),Location.create(3206, 3229, 0), + Location.create(3212, 3226, 0),Location.create(3212, 3244, 0),Location.create(3202, 3252, 0), + Location.create(3197, 3220, 0),Location.create(3189, 3207, 0),Location.create(3229, 3200, 0), + Location.create(3228, 3205, 0),Location.create(3251, 3212, 0),Location.create(3232, 3237, 0)) + + val DRAYNOR_SPOTS = arrayOf(Location.create(3085, 3242, 0), + Location.create(3083, 3236, 0),Location.create(3093, 3224, 0),Location.create(3099, 3241, 0), + Location.create(3095, 3255, 0),Location.create(3089, 3264, 0),Location.create(3089, 3265, 0), + Location.create(3088, 3268, 0),Location.create(3090, 3274, 0),Location.create(3100, 3281, 0), + Location.create(3116, 3265, 0),Location.create(3123, 3272, 0),Location.create(3079, 3261, 0), + Location.create(3127, 3280, 0),Location.create(3118, 3287, 0),Location.create(3111, 3270, 0), + Location.create(3119, 3277, 0),Location.create(3113, 3283, 0)) + + val FALADOR_SPOTS = arrayOf( + Location.create(2961, 3332, 0),Location.create(2967, 3336, 0),Location.create(2974, 3329, 0), + Location.create(2979, 3346, 0),Location.create(2970, 3348, 0),Location.create(2955, 3375, 0), + Location.create(2942, 3386, 0),Location.create(2937, 3385, 0),Location.create(3005, 3370, 0), + Location.create(3006, 3383, 0),Location.create(3007, 3387, 0),Location.create(2985, 3391, 0), + Location.create(2984, 3381, 0),Location.create(2980, 3384, 0),Location.create(3025, 3345, 0), + Location.create(3060, 3389, 0),Location.create(3052, 3385, 0)) + + val EDGEVILLE_SPOTS = arrayOf(Location.create(3077, 3487, 0),Location.create(3082, 3487, 0), + Location.create(3089, 3481, 0),Location.create(3084, 3479, 0),Location.create(3108, 3499, 0), + Location.create(3110, 3517, 0),Location.create(3091, 3512, 0),Location.create(3092, 3507, 0), + Location.create(3081, 3513, 0),Location.create(3079, 3513, 1),Location.create(3080, 3508, 1), + Location.create(3093, 3467, 0)) + + val TREE_GNOME_STRONGHOLD_SPOTS = arrayOf( + Location.create(2480, 3507, 0),Location.create(2486, 3513, 0),Location.create(2453, 3512, 0), + Location.create(2442, 3484, 0),Location.create(2438, 3486, 0),Location.create(2441, 3506, 0), + Location.create(2471, 3482, 0),Location.create(2482, 3478, 0),Location.create(2480, 3469, 0), + Location.create(2489, 3440, 0),Location.create(2470, 3417, 0),Location.create(2478, 3402, 0), + Location.create(2486, 3407, 0),Location.create(2492, 3404, 0),Location.create(2493, 3413, 0), + Location.create(2446, 3395, 0),Location.create(2422, 3398, 0),Location.create(2421, 3402, 0), + Location.create(2418, 3398, 0),Location.create(2401, 3415, 0),Location.create(2397, 3436, 0), + Location.create(2409, 3448, 0),Location.create(2482, 3391, 0)) + + fun locationsForName (name: String) : Array + { + return when (name) + { + LOC_LUM -> LUMBRIDGE_SPOTS + LOC_DRAYNOR -> DRAYNOR_SPOTS + LOC_FALADOR -> FALADOR_SPOTS + LOC_TGS -> TREE_GNOME_STRONGHOLD_SPOTS + LOC_EDGE -> EDGEVILLE_SPOTS + else -> LUMBRIDGE_SPOTS + } + } + + fun gfxForEgg (egg: Int) : Int + { + return when (egg) + { + EGG_A -> GFX_A + EGG_B -> GFX_B + EGG_C -> GFX_C + EGG_D -> GFX_D + else -> GFX_A + } + } + + fun spawnEggFor (player: Player) + { + val dirs = Direction.values() + val dir = dirs[RandomFunction.random(dirs.size)] + var loc = player.location.transform(dir, 3) + val path = Pathfinder.find(player, loc) + loc = Location.create(path.points.last.x, path.points.last.y, loc.z) + GroundItemManager.create(Item(eggs.random()), loc, player) + sendMessage(player, colorize("%RAn egg has appeared nearby.")) + } + + val lootTable = WeightBasedTable.create( + WeightedItem(Items.EASTER_EGG_1962, 1, 15, 0.10), + WeightedItem(Items.PURPLE_SWEETS_10476, 5, 15, 0.10), + WeightedItem(Items.COINS_995, 500, 2500, 0.15), + WeightedItem(Items.ESS_IMPLING_JAR_11246, 1, 1, 0.05), + WeightedItem(Items.BABY_IMPLING_JAR_11238, 1, 1, 0.05), + WeightedItem(Items.EARTH_IMPLING_JAR_11244, 1, 1, 0.05), + WeightedItem(Items.GOURM_IMPLING_JAR_11242, 1, 1, 0.05), + WeightedItem(Items.MAGPIE_IMPLING_JAR_11252, 1, 1, 0.025), + WeightedItem(Items.ECLECTIC_IMPLING_JAR_11248, 1, 1, 0.025), + WeightedItem(Items.ESS_IMPLING_JAR_11246, 1, 1, 0.025), + WeightedItem(Items.NATURE_IMPLING_JAR_11250, 1, 1, 0.015), + WeightedItem(Items.NINJA_IMPLING_JAR_11254, 1, 1, 0.015), + WeightedItem(Items.DRAGON_IMPLING_JAR_11256, 1, 1, 0.005) + ) + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/worldevents/holiday/easter/EasterEventListeners.kt b/Server/src/main/core/game/worldevents/holiday/easter/EasterEventListeners.kt new file mode 100644 index 0000000..2fdc30c --- /dev/null +++ b/Server/src/main/core/game/worldevents/holiday/easter/EasterEventListeners.kt @@ -0,0 +1,11 @@ +package core.game.worldevents.holiday.easter + +import core.game.interaction.InteractionListener + +class EasterEventListeners : InteractionListener { + override fun defineListeners() { + + + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/worldevents/holiday/halloween/CandyRewardPlugin.kt b/Server/src/main/core/game/worldevents/holiday/halloween/CandyRewardPlugin.kt new file mode 100644 index 0000000..aaffe9c --- /dev/null +++ b/Server/src/main/core/game/worldevents/holiday/halloween/CandyRewardPlugin.kt @@ -0,0 +1,28 @@ +package core.game.worldevents.holiday.halloween + +import core.game.node.entity.player.Player +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import core.tools.RandomFunction +import core.game.node.entity.skill.Skills +import core.plugin.CorePluginTypes.XPGainPlugin +import core.tools.colorize + +class CandyRewardPlugin : XPGainPlugin(){ + override fun run(player: Player, skill: Int, amount: Double) { + val awardCandy = RandomFunction.random(1,200) == 55 + val candy = Item(14084) + + if(awardCandy){ + if(!player.inventory.add(candy)){ + GroundItemManager.create(candy,player) + } + player.sendMessage(colorize("%OYou receive a candy while training ${Skills.SKILL_NAME[skill]}!")) + } + } + + override fun fireEvent(identifier: String?, vararg args: Any?): Any { + return Unit + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/worldevents/holiday/halloween/GrimDialogue.kt b/Server/src/main/core/game/worldevents/holiday/halloween/GrimDialogue.kt new file mode 100644 index 0000000..3a9d8fb --- /dev/null +++ b/Server/src/main/core/game/worldevents/holiday/halloween/GrimDialogue.kt @@ -0,0 +1,225 @@ +package core.game.worldevents.holiday.halloween + +import core.api.* +import core.game.node.entity.player.Player +import core.game.node.entity.player.link.emote.Emotes +import core.game.node.item.Item +import core.ServerStore +import core.ServerStore.Companion.getInt +import core.tools.END_DIALOGUE + +/** + * Handles grim's dialogue for the 2021 halloween event. + */ +class GrimDialogue(player: Player? = null) : core.game.dialogue.DialoguePlugin(player){ + var firstSpeak = true + val candy = Item(14084) + override fun newInstance(player: Player?): core.game.dialogue.DialoguePlugin { + return GrimDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + firstSpeak = !player.getAttribute("hween2:grim_spoken",false) + + if(firstSpeak){ + npc("YOU! Yes.... you! Come here!") + player.musicPlayer.unlock(571) + stage = 0 + } else { + npc("Hello, again, adventurer...") + stage = 100 + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> player(core.game.dialogue.FacialExpression.AFRAID,"W-what... what do you want with","me?").also { stage++ } + 1 -> npc("I want you.... I NEED you....").also { stage++ } + 2 -> npc("TO BRING ME CANDY! Yes, candy...").also { stage++ } + 3 -> player(core.game.dialogue.FacialExpression.THINKING,"Candy...? You want me to bring","you... candy?").also { stage++ } + 4 -> npc("Yes, candy! Did I not speak clearly","enough?").also { stage++ } + 5 -> player(core.game.dialogue.FacialExpression.ASKING,"Well how do I even get candy?").also { stage++ } + 6 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL,"It's Hallowe'en, you fool. Everyone's giving out candy.").also { stage++ } + 7 -> npc("You'll need to go and ask them for it each day.").also { stage++ } + 8 -> npc("You'll also need to be careful...","Something vile is on the prowl.").also { stage++ } + 9 -> player(core.game.dialogue.FacialExpression.THINKING,"And what will I get in exchange?").also { stage++ } + 10 -> npc("Well I won't KILL YOU for starters.").also { stage++ } + 11 -> player(core.game.dialogue.FacialExpression.ANGRY_WITH_SMILE, "Is that it?!").also { stage++ } + 12 -> npc("I've prepared a few... rewards, as well.").also { stage++ } + 13 -> player(core.game.dialogue.FacialExpression.AMAZED, "YOU MEAN CREDITS?!").also { stage++ } + 14 -> npc("No, we're not doing that again.").also { stage++ } + 15 -> player(core.game.dialogue.FacialExpression.SAD,"Oh.").also { stage++ } + 16 -> player(core.game.dialogue.FacialExpression.NEUTRAL, "Ok, so what kind of rewards?").also { stage++ } + 17 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "I've fashioned a special-made staff to give out for this year's event.").also { stage++ } + 18 -> npcl(core.game.dialogue.FacialExpression.NEUTRAL, "It is a decorative symbol of your engagement in this activity. Bring me candies, and it can be yours.").also { player.setAttribute("/save:hween2:grim_spoken",true); stage++ } + 19 -> npc("NOW GET TO WORK!").also { player.setAttribute("/save:hween2:grim_spoken",true); stage = 1000 } + + + 100 -> npc("I do hope you have... candy for me?").also { stage++ } + 101 -> if(player.inventory.containsItem(candy)){ + player("Yes, I do! Here you go.").also { stage = 150 } + } else { + player(core.game.dialogue.FacialExpression.SAD, "No, I don't.").also { stage++ } + } + 102 -> npc("A shame, indeed. Your candy totals right now are ${getCandyTotals(player)}.").also { stage++ } + 103 -> player(core.game.dialogue.FacialExpression.FRIENDLY, "I'd like to see the reward shop, please.").also { stage++ } + 104, 105 -> handleRewardShop(player, buttonId) + + + 150 -> { + val candies = player.inventory.getAmount(candy) + player.inventory.remove(Item(candy.id,candies)) + addToCandyTotal(player, candies) + npcl(core.game.dialogue.FacialExpression.NEUTRAL, "Excellent, you now have ${getCandyTotals(player)} candies.") + stage = 103 + } + + + 1000 -> end() + } + return true + } + + fun handleRewardShop(player: Player, buttonId: Int){ + val title = "You have ${getCandyTotals(player)} candies." + val hasUnlocked = player.getAttribute("sotr:purchased",false) + val hasRecolor1 = player.getAttribute("sotr:recolor1", false) + val hasRecolor2 = player.getAttribute("sotr:recolor2", false) + val hasEmote = player.emoteManager.isUnlocked(Emotes.TRICK) + + if(!hasUnlocked && !hasEmote){ + when(stage){ + 104 -> player.dialogueInterpreter.sendOptions(title, "Staff of the Raven (40c)", "Trick Emote (10c)").also { stage++ } + 105 -> when(buttonId) { + 1 -> if (canPurchase(player, 40)) buyStaff(player) else npc( + core.game.dialogue.FacialExpression.NEUTRAL, + "You can't afford that." + ) + 2 -> if (canPurchase(player, 10)) buyEmote(player) else npc( + core.game.dialogue.FacialExpression.NEUTRAL, + "You can't afford that" + ) + } + } + } + else if(hasUnlocked && !hasEmote && !hasRecolor1 && !hasRecolor2){ + when(stage){ + 104 -> player.dialogueInterpreter.sendOptions(title, "Staff Purple Recolor (10c)", "Staff Orange Recolor (10c)", "Trick Emote (10c)").also { stage++ } + 105 -> when(buttonId){ + 1 -> if(canPurchase(player, 10)) buyRecolor1(player) else npc(core.game.dialogue.FacialExpression.NEUTRAL, "You can't afford that.") + 2 -> if(canPurchase(player, 10)) buyRecolor2(player) else npc(core.game.dialogue.FacialExpression.NEUTRAL, "You can't afford that.") + 3 -> if(canPurchase(player, 10)) buyEmote(player) else npc(core.game.dialogue.FacialExpression.NEUTRAL, "You can't afford that.") + } + } + } + else if(hasUnlocked && !hasEmote && hasRecolor1 && !hasRecolor2){ + when(stage){ + 104 -> player.dialogueInterpreter.sendOptions(title, "Staff Orange Recolor (10c)", "Trick Emote (10c)").also { stage++ } + 105 -> when(buttonId){ + 1 -> if(canPurchase(player, 10)) buyRecolor2(player) else npc(core.game.dialogue.FacialExpression.NEUTRAL, "You can't afford that.") + 2 -> if(canPurchase(player, 10)) buyEmote(player) else npc(core.game.dialogue.FacialExpression.NEUTRAL, "You can't afford that.") + } + } + } + else if(hasUnlocked && !hasEmote && !hasRecolor1 && hasRecolor2){ + when(stage){ + 104 -> player.dialogueInterpreter.sendOptions(title, "Staff Purple Recolor (10c)", "Trick Emote (10c)").also { stage++ } + 105 -> when(buttonId){ + 1 -> if(canPurchase(player, 10)) buyRecolor1(player) else npc(core.game.dialogue.FacialExpression.NEUTRAL, "You can't afford that.") + 2 -> if(canPurchase(player, 10)) buyEmote(player) else npc(core.game.dialogue.FacialExpression.NEUTRAL, "You can't afford that.") + } + } + } + else if(!hasUnlocked && hasEmote){ + when(stage){ + 104 -> player.dialogueInterpreter.sendOptions(title, "Staff of the Raven (40c)", "").also { stage++ } + 105 -> when(buttonId){ + 1 -> if(canPurchase(player, 40)) buyStaff(player) else npc(core.game.dialogue.FacialExpression.NEUTRAL, "You can't afford that.") + 2 -> npc(core.game.dialogue.FacialExpression.NEUTRAL, "Huhwuh").also { stage = 104 } + } + } + } + else if(hasUnlocked && hasEmote && !hasRecolor1 && !hasRecolor2){ + when(stage){ + 104 -> player.dialogueInterpreter.sendOptions(title, "Staff Purple Recolor (10c)", "Staff Orange Recolor (10c)").also { stage++ } + 105 -> when(buttonId){ + 1 -> if(canPurchase(player, 10)) buyRecolor1(player) else npc(core.game.dialogue.FacialExpression.NEUTRAL, "You can't afford that.") + 2 -> if(canPurchase(player, 10)) buyRecolor2(player) else npc(core.game.dialogue.FacialExpression.NEUTRAL, "You can't afford that.") + } + } + } + else if(hasUnlocked && hasEmote && !hasRecolor1 && hasRecolor2){ + when(stage){ + 104 -> player.dialogueInterpreter.sendOptions(title, "Staff Purple Recolor (10c)", "").also { stage++ } + 105 -> when(buttonId){ + 1 -> if(canPurchase(player, 10)) buyRecolor1(player) else npc(core.game.dialogue.FacialExpression.NEUTRAL, "You can't afford that.") + 2 -> npc(core.game.dialogue.FacialExpression.NEUTRAL, "Huhwuh").also { stage = 104 } + } + } + } + else if(hasUnlocked && hasEmote && hasRecolor1 && !hasRecolor2){ + when(stage){ + 104 -> player.dialogueInterpreter.sendOptions(title, "Staff Orange Recolor (10c)", "").also { stage++ } + 105 -> when(buttonId){ + 1 -> if(canPurchase(player, 10)) buyRecolor2(player) else npc(core.game.dialogue.FacialExpression.NEUTRAL, "You can't afford that.") + 2 -> npc(core.game.dialogue.FacialExpression.NEUTRAL, "Huhwuh").also { stage = 104 } + } + } + } + else { + npcl(core.game.dialogue.FacialExpression.NEUTRAL, "You've already bought everything.") + stage = END_DIALOGUE + } + } + + fun buyStaff(player: Player){ + player.setAttribute("/save:sotr:purchased", true) + removeCandies(player, 40) + addItem(player, 14654, 1) + stage = 104 + handleRewardShop(player, -1) + } + + fun buyRecolor1(player: Player){ + player.setAttribute("/save:sotr:recolor1", true) + removeCandies(player, 10) + stage = 104 + handleRewardShop(player, -1) + } + + fun buyRecolor2(player: Player){ + player.setAttribute("/save:sotr:recolor2", true) + removeCandies(player, 10) + stage = 104 + handleRewardShop(player, -1) + } + + fun buyEmote(player: Player){ + player.emoteManager.unlock(Emotes.TRICK) + removeCandies(player, 10) + stage = 104 + handleRewardShop(player, -1) + } + + fun canPurchase(player: Player, cost: Int) : Boolean { + return getCandyTotals(player) >= cost + } + + fun removeCandies(player: Player, amount: Int){ + addToCandyTotal(player, -amount) + } + + fun getCandyTotals(player: Player): Int { + return ServerStore.getArchive("hween2021-candies").getInt(player.username.toLowerCase()) + } + + fun addToCandyTotal(player: Player, amount: Int){ + ServerStore.getArchive("hween2021-candies").put(player.username.toLowerCase(), getCandyTotals(player) + amount) + } + + override fun getIds(): IntArray { + return intArrayOf(6390) + } + +} \ No newline at end of file diff --git a/Server/src/main/core/game/worldevents/holiday/halloween/TrickOrTreatHandler.kt b/Server/src/main/core/game/worldevents/holiday/halloween/TrickOrTreatHandler.kt new file mode 100644 index 0000000..c7c884f --- /dev/null +++ b/Server/src/main/core/game/worldevents/holiday/halloween/TrickOrTreatHandler.kt @@ -0,0 +1,95 @@ +package core.game.worldevents.holiday.halloween + +import core.api.* +import core.game.component.Component +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.update.flag.context.Animation +import core.game.world.update.flag.context.Graphics +import core.tools.RandomFunction +import org.rs09.consts.Components +import core.ServerStore +import core.ServerStore.Companion.getInt +import core.ServerStore.Companion.getString +import core.game.dialogue.DialogueFile +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.game.world.GameWorld +import core.tools.END_DIALOGUE + +class TrickOrTreatHandler : InteractionListener { + override fun defineListeners() { + on(IntType.NPC, "trick-or-treat"){ player, node -> + val hasDone5 = getDailyTrickOrTreats(player) == 5 + val hasDoneMe = getTrickOrTreatedNPCs(player).contains(node.name.toLowerCase()) + + if(hasDone5){ + sendNPCDialogue(player, node.id, "My informants tell me you've already collected candy from 5 people today.", core.game.dialogue.FacialExpression.FRIENDLY) + return@on true + } + + if(hasDoneMe){ + sendNPCDialogue(player, node.id, "You've already asked me today! Don't get greedy, now.", core.game.dialogue.FacialExpression.ANNOYED) + return@on true + } + + player.dialogueInterpreter.open(object : DialogueFile(){ + override fun handle(componentID: Int, buttonID: Int) { + when(stage){ + 0 -> playerl(core.game.dialogue.FacialExpression.FRIENDLY, "Trick or treat!").also { if(RandomFunction.roll(20)) stage = 10 else stage++ } + 1 -> npcl(core.game.dialogue.FacialExpression.FRIENDLY, "Very well, then, here you are my friend.").also { stage++ } + 2 -> { + player.dialogueInterpreter.sendItemMessage(14084, "They hand you a nicely-wrapped candy.") + addItemOrDrop(player, 14084, 1) + registerNpc(player, npc!!) + incrementDailyToT(player) + stage = END_DIALOGUE + } + + 10 -> npcl(core.game.dialogue.FacialExpression.EVIL_LAUGH, "I CHOOSE TRICK!").also { player.lock(); GameWorld.submit(object : Pulse() { + var counter = 0 + override fun pulse(): Boolean { + //gfx 1898 + when(counter++){ + 0 -> npc!!.visualize(Animation(1979), Graphics(1898)).also { npc!!.faceLocation(player.location) } + 2 -> player.dialogueInterpreter.close() + 5 -> player.interfaceManager.open(Component(Components.FADE_TO_BLACK_120)) + 8 -> player.properties.teleportLocation = Location.create(3106, 3382, 0) + 12 -> { + player.interfaceManager.close() + player.interfaceManager.open(Component(Components.FADE_FROM_BLACK_170)) + registerNpc(player, npc!!) + } + 15 -> player.interfaceManager.close().also { player.unlock() } + 16 -> return true + } + return false + } + }) } + } + } + }, node.asNpc()) + return@on true + } + } + + fun incrementDailyToT(player: Player){ + ServerStore.getArchive("daily-tot-total")[player.username.toLowerCase()] = getDailyTrickOrTreats(player) + 1 + } + + fun getDailyTrickOrTreats(player: Player) : Int { + return ServerStore.getArchive("daily-tot-total").getInt(player.username.toLowerCase()) + } + + fun getTrickOrTreatedNPCs(player: Player): String { + return ServerStore.getArchive("daily-tot-npcs").getString(player.username.toLowerCase()) + } + + fun registerNpc(player: Player, npc: NPC){ + var soFar = getTrickOrTreatedNPCs(player) + soFar += ":" + npc.name.toLowerCase() + ":" + ServerStore.getArchive("daily-tot-npcs")[player.username.toLowerCase()] = soFar + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/worldevents/holiday/halloween/randoms/BlackCatHolidayRandomNPC.kt b/Server/src/main/core/game/worldevents/holiday/halloween/randoms/BlackCatHolidayRandomNPC.kt new file mode 100644 index 0000000..b893bfa --- /dev/null +++ b/Server/src/main/core/game/worldevents/holiday/halloween/randoms/BlackCatHolidayRandomNPC.kt @@ -0,0 +1,31 @@ +package core.game.worldevents.holiday.halloween.randoms + +import core.api.* +import core.game.interaction.QueueStrength +import core.game.node.entity.combat.ImpactHandler.HitsplatType +import core.game.node.entity.npc.NPC +import core.game.worldevents.holiday.HolidayRandomEventNPC + +import core.game.worldevents.holiday.HolidayRandoms +import org.rs09.consts.Sounds + +class BlackCatHolidayRandomNPC() : HolidayRandomEventNPC(4607) { + override fun init() { + super.init() + queueScript(this, 8, QueueStrength.SOFT) { + playGlobalAudio(this.location, Sounds.CAT_ATTACK_333) + sendChat("HISS") + if (player.location.withinDistance(this.location, 3)) { + this.face(player) + sendMessage(player, "The cat scratches you and runs away.") + val hit = if (player.skills.lifepoints < 5) 0 else 1 + impact(player, hit, HitsplatType.NORMAL) + } + HolidayRandoms.terminateEventNpc(player) + return@queueScript stopExecuting(this) + } + } + + override fun talkTo(npc: NPC) { + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/worldevents/holiday/halloween/randoms/DeathHolidayRandomNPC.kt b/Server/src/main/core/game/worldevents/holiday/halloween/randoms/DeathHolidayRandomNPC.kt new file mode 100644 index 0000000..ffe2ebc --- /dev/null +++ b/Server/src/main/core/game/worldevents/holiday/halloween/randoms/DeathHolidayRandomNPC.kt @@ -0,0 +1,42 @@ +package core.game.worldevents.holiday.halloween.randoms + +import core.api.* +import core.game.interaction.QueueStrength +import core.game.node.entity.npc.NPC +import core.game.worldevents.holiday.HolidayRandomEventNPC +import core.game.worldevents.holiday.HolidayRandoms +import core.tools.RandomFunction +import org.rs09.consts.Sounds + +class DeathHolidayRandomNPC() : HolidayRandomEventNPC(2862) { + override fun init() { + super.init() + playJingle(player, 337) + queueScript(this, 6, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + this.face(player) + visualize(this, 864, -1) + playGlobalAudio(this.location, Sounds.ZOMBIE_MOAN_2324) + return@queueScript delayScript(this, 1) + } + 1 -> { + when(RandomFunction.getRandom(2)) { + 0 -> sendChat(this, "Your end is near, ${player.username.capitalize()}...") + 1 -> sendChat(this, "Time is running out, ${player.username.capitalize()}...") + 2 -> sendChat(this, "Tick tock, ${player.username.capitalize()}...") + } + return@queueScript delayScript(this, 4) + } + 2 -> { + HolidayRandoms.terminateEventNpc(player) + return@queueScript stopExecuting(this) + } + else -> return@queueScript stopExecuting(this) + } + } + } + + override fun talkTo(npc: NPC) { + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/worldevents/holiday/halloween/randoms/GhostHolidayRandomNPC.kt b/Server/src/main/core/game/worldevents/holiday/halloween/randoms/GhostHolidayRandomNPC.kt new file mode 100644 index 0000000..f5defed --- /dev/null +++ b/Server/src/main/core/game/worldevents/holiday/halloween/randoms/GhostHolidayRandomNPC.kt @@ -0,0 +1,27 @@ +package core.game.worldevents.holiday.halloween.randoms + +import core.api.* +import core.game.node.entity.npc.NPC +import core.game.worldevents.holiday.HolidayRandomEventNPC +import core.tools.RandomFunction +import org.rs09.consts.Sounds + +class GhostHolidayRandomNPC() : HolidayRandomEventNPC(2716) { + override fun init() { + super.init() + this.isAggressive = false + playGlobalAudio(this.location, Sounds.BIGGHOST_APPEAR_1595) + animate(player, 2836) + sendChat(this, "WooooOOOooOOo") + sendMessage(player, "The air suddenly gets colder...") + } + + override fun tick() { + super.tick() + if (RandomFunction.roll(10)) + playGlobalAudio(this.location, Sounds.BIGGHOST_LAUGH_1600) + } + + override fun talkTo(npc: NPC) { + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/worldevents/holiday/halloween/randoms/SpiderHolidayRandomBehavior.kt b/Server/src/main/core/game/worldevents/holiday/halloween/randoms/SpiderHolidayRandomBehavior.kt new file mode 100644 index 0000000..df23e76 --- /dev/null +++ b/Server/src/main/core/game/worldevents/holiday/halloween/randoms/SpiderHolidayRandomBehavior.kt @@ -0,0 +1,22 @@ +package core.game.worldevents.holiday.halloween.randoms + +import core.api.getAttribute +import core.api.playGlobalAudio +import core.game.node.entity.Entity +import core.game.node.entity.combat.CombatStyle +import core.game.node.entity.npc.NPC +import core.game.node.entity.npc.NPCBehavior +import core.game.worldevents.holiday.HolidayRandomEventNPC +import org.rs09.consts.Sounds + +class SpiderHolidayRandomBehavior : NPCBehavior() { + override fun canBeAttackedBy(self: NPC, attacker: Entity, style: CombatStyle, shouldSendMessage: Boolean): Boolean { + return false + } + + override fun onDeathStarted(self: NPC, killer: Entity) { + getAttribute(self, "holiday-npc", null)?.terminate() + playGlobalAudio(self.location, Sounds.SMALL_SPIDER_DEATH_3608) + super.onDeathFinished(self, killer) + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/worldevents/holiday/halloween/randoms/SpiderHolidayRandomNPC.kt b/Server/src/main/core/game/worldevents/holiday/halloween/randoms/SpiderHolidayRandomNPC.kt new file mode 100644 index 0000000..dea7ff0 --- /dev/null +++ b/Server/src/main/core/game/worldevents/holiday/halloween/randoms/SpiderHolidayRandomNPC.kt @@ -0,0 +1,50 @@ +package core.game.worldevents.holiday.halloween.randoms + +import core.api.* +import core.game.interaction.QueueStrength +import core.game.node.entity.combat.ImpactHandler +import core.game.node.entity.npc.NPC +import core.game.world.update.flag.context.Animation +import core.game.worldevents.holiday.HolidayRandomEventNPC +import core.game.worldevents.holiday.HolidayRandoms +import org.rs09.consts.Sounds + +class SpiderHolidayRandomNPC() : HolidayRandomEventNPC(61) { + override fun init() { + super.init() + this.behavior = SpiderHolidayRandomBehavior() + playGlobalAudio(this.location, Sounds.SPIDER_4375) + var stomped = false + queueScript(this,4, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + sendChat(player, "Eww a spider!") + return@queueScript delayScript(this, 2) + } + 1 -> { + if (player.location.withinDistance(this.location, 3)) { + player.animate(Animation(4278)) + playGlobalAudio(this.location, Sounds.UNARMED_KICK_2565) + sendMessage(player, "You stomp the spider.") + stomped = true + } + return@queueScript delayScript(this, 1) + } + 2 -> { + if (stomped) { + impact(this, 1, ImpactHandler.HitsplatType.NORMAL) + } else { + sendMessage(player, "The spider runs away.") + playGlobalAudio(this.location, Sounds.SPIDER_4375) + HolidayRandoms.terminateEventNpc(player) + } + return@queueScript stopExecuting(this) + } + else -> return@queueScript stopExecuting(this) + } + } + } + + override fun talkTo(npc: NPC) { + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/worldevents/holiday/halloween/randoms/VampireHolidayRandomNPC.kt b/Server/src/main/core/game/worldevents/holiday/halloween/randoms/VampireHolidayRandomNPC.kt new file mode 100644 index 0000000..2fc8ad2 --- /dev/null +++ b/Server/src/main/core/game/worldevents/holiday/halloween/randoms/VampireHolidayRandomNPC.kt @@ -0,0 +1,49 @@ +package core.game.worldevents.holiday.halloween.randoms + +import core.api.* +import core.game.interaction.QueueStrength +import core.game.node.entity.combat.ImpactHandler +import core.game.node.entity.npc.NPC +import core.game.worldevents.holiday.HolidayRandomEventNPC +import core.game.worldevents.holiday.HolidayRandoms +import core.game.worldevents.holiday.ResetHolidayAppearance +import core.tools.RandomFunction +import core.tools.colorize +import org.rs09.consts.Sounds + +class VampireHolidayRandomNPC() : HolidayRandomEventNPC(1023) { + override fun init() { + super.init() + playGlobalAudio(this.location, Sounds.REGULAR_VAMPIRE_APPEAR_1897) + visualize(this, -1 , 1863) + queueScript(this, 3, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + this.face(player) + visualize(this, 7183 , -1) + playGlobalAudio(this.location, Sounds.VAMPIRE_ATTACK_879) + if (RandomFunction.roll(2)) { + player.timers.registerTimer(ResetHolidayAppearance()) + sendMessage(player, colorize("%RThe vampire bites your neck!")) + val hit = if (player.skills.lifepoints < 5) 0 else 2 + impact(player, hit, ImpactHandler.HitsplatType.NORMAL) + player.appearance.transformNPC(1023) + } else { + sendMessage(player, "The vampire tries to bite your neck and misses!") + impact(player, 0, ImpactHandler.HitsplatType.NORMAL) + } + return@queueScript delayScript(this, 8) + } + 1 -> { + visualize(this, 10530, 1863) + HolidayRandoms.terminateEventNpc(player) + return@queueScript stopExecuting(this) + } + else -> return@queueScript stopExecuting(this) + } + } + } + + override fun talkTo(npc: NPC) { + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/worldevents/holiday/halloween/randoms/WitchHolidayRandomNPC.kt b/Server/src/main/core/game/worldevents/holiday/halloween/randoms/WitchHolidayRandomNPC.kt new file mode 100644 index 0000000..bb4100b --- /dev/null +++ b/Server/src/main/core/game/worldevents/holiday/halloween/randoms/WitchHolidayRandomNPC.kt @@ -0,0 +1,152 @@ +package core.game.worldevents.holiday.halloween.randoms + +import core.api.* +import core.game.interaction.QueueStrength +import core.game.node.entity.combat.ImpactHandler +import core.game.node.entity.npc.NPC +import core.game.worldevents.holiday.ResetHolidayAppearance +import core.game.worldevents.holiday.HolidayRandomEventNPC +import core.game.worldevents.holiday.HolidayRandoms +import core.tools.RandomFunction +import org.rs09.consts.Sounds + +class WitchHolidayRandomNPC() : HolidayRandomEventNPC(611) { + override fun init() { + super.init() + when (RandomFunction.getRandom(4)) { + 0 -> { + queueScript(this, 6, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + sendChat(this, "Brackium Emendo!") + this.face(player) + playGlobalAudio(this.location, Sounds.CONFUSE_CAST_AND_FIRE_119) + animate(this, 1978) + spawnProjectile(this, player, 109) + return@queueScript delayScript(this, 2) + } + 1 -> { + player.appearance.transformNPC(3138) + playAudio(player, Sounds.SKELETON_RESURRECT_1687) + registerTimer(player, ResetHolidayAppearance()) + return@queueScript delayScript(this, 4) + } + 2 -> { + sendChat(this, "That was not right...") + visualize(this, 857, -1) + HolidayRandoms.terminateEventNpc(player) + return@queueScript stopExecuting(this) + } + else -> return@queueScript stopExecuting(this) + } + } + } + 1 -> { + queueScript(this, 6, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + sendChat(this, "Bombarda!") + this.face(player) + playGlobalAudio(this.location, Sounds.CURSE_CAST_AND_FIRE_127) + animate(this, 1978) + spawnProjectile(this, player, 109) + return@queueScript delayScript(this, 2) + } + 1 -> { + playGlobalAudio(player.location, Sounds.EXPLOSION_1487) + visualize(player, -1, 659) + val hit = if (player.skills.lifepoints < 5) 0 else 2 + impact(player, hit, ImpactHandler.HitsplatType.NORMAL) + return@queueScript delayScript(this, 2) + } + 2 -> { + HolidayRandoms.terminateEventNpc(player) + return@queueScript stopExecuting(this) + } + else -> return@queueScript stopExecuting(this) + } + } + } + 2 -> { + queueScript(this, 6, QueueStrength.SOFT) {stage: Int -> + when (stage) { + 0 -> { + sendChat(this, "Tarantallegra!") + this.face(player) + playGlobalAudio(this.location, Sounds.WEAKEN_CAST_AND_FIRE_3011) + animate(this, 1978) + spawnProjectile(this, player, 109) + return@queueScript delayScript(this, 2) + } + 1 -> { + animate(player, 3543, true) + sendMessage(player, "You suddenly burst into dance.") + return@queueScript delayScript(this, 2) + } + 2 -> { + visualize(this, 861, -1) + playGlobalAudio(this.location, Sounds.HUMAN_LAUGH_1_3071) + HolidayRandoms.terminateEventNpc(player) + return@queueScript stopExecuting(this) + } + else -> return@queueScript stopExecuting(this) + } + } + } + 3 -> { + queueScript(this, 6, QueueStrength.SOFT) {stage: Int -> + when (stage) { + 0 -> { + sendChat(this, "Vespertilio!") + this.face(player) + playGlobalAudio(this.location, Sounds.WEAKEN_CAST_AND_FIRE_3011) + animate(this, 1978) + spawnProjectile(this, player, 109) + return@queueScript delayScript(this, 2) + } + 1 -> { + visualize(player, 10530, 1863) + playGlobalAudio(player.location, Sounds.VAMPIRE_SUMMON_1899) + return@queueScript delayScript(this, 4) + } + 2 -> { + player.appearance.transformNPC(6835) + HolidayRandoms.terminateEventNpc(player) + registerTimer(player, ResetHolidayAppearance()) + return@queueScript stopExecuting(this) + } + else -> return@queueScript stopExecuting(this) + } + } + } + 4 -> { + queueScript(this, 6, QueueStrength.SOFT) {stage: Int -> + when (stage) { + 0 -> { + sendChat(this, "Sella!") + this.face(player) + playGlobalAudio(this.location, Sounds.WEAKEN_CAST_AND_FIRE_3011) + animate(this, 1978) + spawnProjectile(this, player, 109) + return@queueScript delayScript(this, 2) + } + 1 -> { + player.appearance.transformNPC(3293) + playGlobalAudio(player.location, Sounds.KR_JUDGE_HAMMER_3822) + registerTimer(player, ResetHolidayAppearance()) + return@queueScript delayScript(this, 4) + } + 2 -> { + HolidayRandoms.terminateEventNpc(player) + return@queueScript stopExecuting(this) + } + else -> return@queueScript stopExecuting(this) + } + } + } + } + } + + override fun talkTo(npc: NPC) { + } +} \ No newline at end of file diff --git a/Server/src/main/core/game/worldevents/holiday/halloween/randoms/ZombieHolidayRandomNPC.kt b/Server/src/main/core/game/worldevents/holiday/halloween/randoms/ZombieHolidayRandomNPC.kt new file mode 100644 index 0000000..6cc7e31 --- /dev/null +++ b/Server/src/main/core/game/worldevents/holiday/halloween/randoms/ZombieHolidayRandomNPC.kt @@ -0,0 +1,60 @@ +package core.game.worldevents.holiday.halloween.randoms + +import core.api.* +import core.game.interaction.QueueStrength +import core.game.node.entity.combat.ImpactHandler +import core.game.node.entity.npc.NPC +import core.game.worldevents.holiday.ResetHolidayAppearance +import core.game.worldevents.holiday.HolidayRandomEventNPC +import core.game.worldevents.holiday.HolidayRandoms +import core.tools.RandomFunction +import core.tools.colorize +import org.rs09.consts.Sounds + +class ZombieHolidayRandomNPC() : HolidayRandomEventNPC(2714) { + override fun init() { + super.init() + this.isAggressive = false + playGlobalAudio(this.location, Sounds.ZOMBIE_DEATH_922) + playJingle(player, 314) + sendMessage(player, "A zombie crawls out of the ground beneath you...") + animate(player, 7272) + queueScript(this, 2, QueueStrength.SOFT) { stage: Int -> + when (stage) { + 0 -> { + when (RandomFunction.getRandom(2)) { + 0 -> sendChat(this, "Brainnnss!") + 1 -> sendChat(this, "RArrgghhh") + 2 -> sendChat(this, "Flesshhh") + } + return@queueScript delayScript(this, 1) + } + 1 -> { + this.face(player) + visualize(this, 5568 , -1) + playGlobalAudio(this.location, Sounds.ZOMBIE_ATTACK_918) + if (RandomFunction.roll(2)) { + player.timers.registerTimer(ResetHolidayAppearance()) + sendMessage(player, colorize("%RThe zombie bites you!")) + val hit = if (player.skills.lifepoints < 5) 0 else 2 + impact(player, hit, ImpactHandler.HitsplatType.NORMAL) + player.appearance.transformNPC(2866) + } else { + impact(player, 0, ImpactHandler.HitsplatType.NORMAL) + sendMessage(player, "The zombie tries to bite you and misses!") + } + return@queueScript delayScript(this, 8) + } + 2 -> { + animate(this, 5575) + HolidayRandoms.terminateEventNpc(player) + return@queueScript stopExecuting(this) + } + else -> return@queueScript stopExecuting(this) + } + } + } + + override fun talkTo(npc: NPC) { + } +} \ No newline at end of file diff --git a/Server/src/main/core/integrations/discord/Discord.kt b/Server/src/main/core/integrations/discord/Discord.kt new file mode 100644 index 0000000..acb6755 --- /dev/null +++ b/Server/src/main/core/integrations/discord/Discord.kt @@ -0,0 +1,203 @@ +package core.integrations.discord + +import core.api.* +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch +import org.json.simple.JSONArray +import org.json.simple.JSONObject +import core.ServerConstants +import java.io.BufferedReader +import java.io.DataOutputStream +import java.io.InputStreamReader +import java.net.HttpURLConnection +import java.net.URL +import java.util.ArrayList + + +class Discord : TickListener { + override fun tick() { + if (!removeList.isEmpty()) { + pendingMessages.removeAll(removeList) + removeList.clear() + } + + if (!pendingMessages.isEmpty() && !flushingPends) { + flushingPends = true + GlobalScope.launch { + try { + val count = pendingMessages.size + for (i in 0 until count) { + val (url, content) = pendingMessages[i] + sendJsonPost(url, content) + removeList.add(pendingMessages[i]) + } + } finally { + flushingPends = false + } + } + } + } + + companion object { + private const val COLOR_NEW_BUY_OFFER = 47789 + private const val COLOR_NEW_SALE_OFFER = 5752709 + private const val COLOR_OFFER_UPDATE = 15588691 + + private val pendingMessages = ArrayList>() + private var flushingPends = false + private val removeList = ArrayList>() + + fun postNewOffer(isSale: Boolean, itemId: Int, value: Int, qty: Int, user: String) { + if (ServerConstants.DISCORD_GE_WEBHOOK.isEmpty()) return + GlobalScope.launch { + val offer = encodeOfferJson(isSale, itemId, value, qty, user) + try { + sendJsonPost(ServerConstants.DISCORD_GE_WEBHOOK, offer) + } catch (e: Exception) { + e.printStackTrace() + } + } + } + + fun postOfferUpdate(isSale: Boolean, itemId: Int, value: Int, amtLeft: Int) { + if (ServerConstants.DISCORD_GE_WEBHOOK.isEmpty()) return + GlobalScope.launch { + val offer = encodeUpdateJson(isSale, itemId, value, amtLeft) + try { + sendJsonPost(ServerConstants.DISCORD_GE_WEBHOOK, offer) + } catch (e: Exception) { + e.printStackTrace() + } + } + } + + @JvmStatic + fun postPlayerAlert(player: String, type: String) { + if (ServerConstants.DISCORD_MOD_WEBHOOK.isEmpty()) return + GlobalScope.launch { + val alert = encodeUserAlert(type, player) + try { + sendJsonPost(ServerConstants.DISCORD_MOD_WEBHOOK, alert) + } catch (e: Exception) { + e.printStackTrace() + } + } + } + + @JvmStatic fun sendToOpenRSC(player: String, type: String) { + if (ServerConstants.DISCORD_OPENRSC_HOOK.isEmpty()) return + GlobalScope.launch { + val alert = encodeUserAlert(type, player) + try { + sendJsonPost(ServerConstants.DISCORD_OPENRSC_HOOK, alert) + } catch (e: Exception) { + e.printStackTrace() + } + } + } + + private fun encodeUpdateJson(sale: Boolean, itemId: Int, value: Int, amtLeft: Int): String { + val obj = JSONObject() + val embeds = JSONArray() + val embed = JSONObject() + + val fields = arrayOf( + EmbedField("Item", getItemName(itemId), false), + EmbedField("Amount Remaining", "%,d".format(amtLeft), true), + EmbedField("Price", "%,d".format(value) + "gp", true), + ) + + embed["title"] = if (sale) "Sell Offer Updated" else "Buy Offer Updated" + embed["color"] = COLOR_OFFER_UPDATE + embed["thumbnail"] = getItemImage(itemId) + embed["fields"] = getFields(fields) + + embeds.add(embed) + obj["embeds"] = embeds + + return obj.toJSONString() + } + + private fun encodeOfferJson(isSale: Boolean, itemId: Int, value: Int, qty: Int, user: String): String { + val obj = JSONObject() + val embeds = JSONArray() + val embed = JSONObject() + + val fields = arrayOf( + EmbedField("Player", user, false), + EmbedField("Item", getItemName(itemId), false), + EmbedField("Amount", "%,d".format(qty), true), + EmbedField("Price", "%,d".format(value) + "gp", true), + ) + + embed["title"] = if (isSale) "New Sell Offer" else "New Buy Offer" + embed["color"] = if (isSale) COLOR_NEW_SALE_OFFER else COLOR_NEW_BUY_OFFER + embed["thumbnail"] = getItemImage(itemId) + embed["fields"] = getFields(fields) + + embeds.add(embed) + obj["embeds"] = embeds + + return obj.toJSONString() + } + + private fun encodeUserAlert(type: String, player: String) : String { + val obj = JSONObject() + val embeds = JSONArray() + val embed = JSONObject() + + val fields = arrayOf( + EmbedField("Player", player, false), + EmbedField("Type", type, false) + ) + + embed["title"] = "Player Alert" + embed["fields"] = getFields(fields) + embeds.add(embed) + obj["embeds"] = embeds + return obj.toJSONString() + } + + private fun getFields(fields: Array): JSONArray { + val arr = JSONArray() + + for (field in fields) { + val o = JSONObject() + o["name"] = field.name + o["value"] = field.value + if (field.inline) o["inline"] = true + arr.add(o) + } + + return arr + } + + data class EmbedField(val name: String, val value: String, val inline: Boolean) + + fun getItemImage(id: Int) : JSONObject { + val obj = JSONObject() + obj["url"] = "https://github.com/2009scape/2009scape.github.io/raw/master/services/m%3Ddata/img/items/$id.png" + return obj + } + + private fun sendJsonPost(url: String = ServerConstants.DISCORD_GE_WEBHOOK, data: String) { + try { + val conn = URL(url).openConnection() as HttpURLConnection + conn.doOutput = true + conn.requestMethod = "POST" + conn.setRequestProperty("Content-Type", "application/json") + conn.useCaches = false + + DataOutputStream(conn.outputStream).use { it.writeBytes(data) } + BufferedReader(InputStreamReader(conn.inputStream)).use { br -> + var line: String? + while (br.readLine().also { line = it } != null) { + println(line) + } + } + } catch (e: Exception) { + pendingMessages.add(Pair(url, data)) + } + } + } +} diff --git a/Server/src/main/core/integrations/grafana/Grafana.kt b/Server/src/main/core/integrations/grafana/Grafana.kt new file mode 100644 index 0000000..5309615 --- /dev/null +++ b/Server/src/main/core/integrations/grafana/Grafana.kt @@ -0,0 +1,183 @@ +package core.integrations.grafana + +import core.ServerConstants +import core.api.StartupListener +import core.game.bots.AIRepository +import core.integrations.sqlite.SQLiteProvider +import core.tools.cycle +import kotlinx.coroutines.Job +import org.json.simple.JSONObject +import java.util.LinkedList +import java.util.concurrent.LinkedBlockingDeque + +class Grafana : StartupListener { + override fun startup() { + if (!ServerConstants.GRAFANA_LOGGING) return + db = SQLiteProvider (ServerConstants.GRAFANA_PATH + "grafana.db", expectedTables) + db.initTables() + db.pruneOldData(ServerConstants.GRAFANA_TTL_DAYS) + } + + data class GrafanaData ( + val playerTickTime: Int, + val npcTickTime: Int, + val playerRenderTime: Int, + val totalTickTime: Int, + val packetProcessTime: Int, + val botPulseTime: Int, + val otherPulseTime: Int, + val pulseTimes: Array>, + val pulseCounts: Array>, + val botCount: Int, + val timeSecs: Int + ) + + companion object { + var playerTickTime = 0 + var npcTickTime = 0 + var playerRenderTime = 0 + var totalTickTime = 0 + var packetProcessTime = 0 + var botPulseTime = 0 + var otherPulseTime = 0 + lateinit var db: SQLiteProvider + var cycleData = LinkedList() + var currentTask: Job? = null + + var pulseTimes = HashMap() + var pulseCounts = HashMap() + + fun addPulseLength(pulseName: String, time: Int) { + if (!this::db.isInitialized) return + pulseTimes[pulseName] = (pulseTimes[pulseName] ?: 0) + time + } + + fun countPulse(pulseName: String) { + if (!this::db.isInitialized) return + pulseCounts[pulseName] = (pulseCounts[pulseName] ?: 0) + 1 + } + + fun startTick() { + if (!this::db.isInitialized) return + playerTickTime = 0 + npcTickTime = 0 + playerRenderTime = 0 + totalTickTime = 0 + packetProcessTime = 0 + botPulseTime = 0 + otherPulseTime = 0 + pulseTimes.clear() + pulseCounts.clear() + } + + fun endTick() { + if (!this::db.isInitialized) return + val thisCycle = GrafanaData ( + playerTickTime, + npcTickTime, + playerRenderTime, + totalTickTime, + packetProcessTime, + botPulseTime, + otherPulseTime, + pulseTimes.entries.toTypedArray(), + pulseCounts.entries.toTypedArray(), + AIRepository.PulseRepository.size, + getNowTime() + ) + cycleData.add(thisCycle) + + if (cycleData.size < 50) return + if (currentTask?.isActive == true) return + + currentTask = db.runAsync { + with (it.prepareStatement(INSERT_TOP_PULSES)) { + for (i in 0 until 50) { + val topSorted = cycleData[i].pulseTimes.sortedByDescending { entry -> entry.value } + val rootObj = JSONObject() + val contentObj = JSONObject() + for (j in 0 until 5) { + contentObj[topSorted[j].key] = topSorted[j].value + } + rootObj["pulses"] = contentObj + setString(1, rootObj.toJSONString()) + setInt(2, cycleData[i].timeSecs) + execute() + } + } + + with (it.prepareStatement(INSERT_PULSE_COUNT)) { + for (i in 0 until 50) { + val topSorted = cycleData[i].pulseCounts.sortedByDescending { entry -> entry.value } + val rootObj = JSONObject() + val contentObj = JSONObject() + for (j in 0 until 5) { + contentObj[topSorted[j].key] = topSorted[j].value + } + rootObj["pulses"] = contentObj + setString(1, rootObj.toJSONString()) + setInt(2, cycleData[i].timeSecs) + execute() + } + } + + with (it.prepareStatement(INSERT_BOT_COUNT)) { + for (i in 0 until 50) { + setInt(1, cycleData[i].botCount) + setInt(2, cycleData[i].timeSecs) + execute() + } + } + + with (it.prepareStatement(INSERT_TICK_MEAS)) { + for (i in 0 until 50) { + setInt(1, cycleData[i].botPulseTime) + setInt(2, cycleData[i].otherPulseTime) + setInt(3, cycleData[i].npcTickTime) + setInt(4, cycleData[i].playerTickTime) + setInt(5, cycleData[i].playerRenderTime) + setInt(6, cycleData[i].packetProcessTime) + setInt(7, cycleData[i].totalTickTime - (cycleData[i].botPulseTime + cycleData[i].otherPulseTime + cycleData[i].npcTickTime + cycleData[i].playerTickTime + cycleData[i].playerRenderTime + cycleData[i].packetProcessTime)) + setInt(8, cycleData[i].timeSecs) + execute() + } + } + + cycleData.removeAll(cycleData.subList(0, 49).toSet()) + } + } + + private fun getNowTime () : Int { + return (System.currentTimeMillis() / 1000L).toInt() + } + + private const val INSERT_TOP_PULSES = "INSERT INTO top_pulses (pulse_info, ts) VALUES (?, ?);" + private const val INSERT_PULSE_COUNT = "INSERT INTO high_volume_pulses (pulse_info, ts) VALUES (?, ?);" + private const val INSERT_BOT_COUNT = "INSERT INTO bot_counts (count, ts) VALUES (?, ?);" + private const val INSERT_TICK_MEAS = "INSERT INTO tick_lengths (bot_pulses, misc_pulses, npc_tick, player_tick, player_render, packet_incoming, other, ts) VALUES (?,?,?,?,?,?,?,?);" + private var expectedTables = hashMapOf( + "bot_counts" to "CREATE TABLE \"bot_counts\" (\n" + + "\t\"count\"\tINTEGER,\n" + + "\t\"ts\"\tINTEGER\n" + + ")", + "high_volume_pulses" to "CREATE TABLE \"high_volume_pulses\" (\n" + + "\t\"pulse_info\"\tTEXT,\n" + + "\t\"ts\"\tINTEGER\n" + + ")", + "tick_lengths" to "CREATE TABLE \"tick_lengths\" (\n" + + "\t\"bot_pulses\"\tINTEGER,\n" + + "\t\"misc_pulses\"\tINTEGER,\n" + + "\t\"npc_tick\"\tINTEGER,\n" + + "\t\"player_tick\"\tINTEGER,\n" + + "\t\"player_render\"\tINTEGER,\n" + + "\t\"packet_incoming\"\tINTEGER,\n" + + "\t\"other\"\tINTEGER,\n" + + "\t\"ts\"\tINTEGER\n" + + ")", + "top_pulses" to "CREATE TABLE \"top_pulses\" (\n" + + "\t\"pulse_info\"\tTEXT,\n" + + "\t\"ts\"\tINTEGER\n" + + ")" + ) + } +} \ No newline at end of file diff --git a/Server/src/main/core/integrations/sqlite/SQLiteProvider.kt b/Server/src/main/core/integrations/sqlite/SQLiteProvider.kt new file mode 100644 index 0000000..4155bf3 --- /dev/null +++ b/Server/src/main/core/integrations/sqlite/SQLiteProvider.kt @@ -0,0 +1,94 @@ +package core.integrations.sqlite + +import core.api.log +import core.tools.Log +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.launch +import org.sqlite.SQLiteDataSource +import java.io.File +import java.sql.Connection +import java.util.concurrent.TimeUnit +import java.util.concurrent.locks.ReentrantLock + +class SQLiteProvider (private val path: String, private val expectedTables: HashMap? = null) { + private var connection: Connection? = null + private var connectionRefs = 0 + private var obtainConnectionLock = ReentrantLock() + private var dbRunLock = ReentrantLock() + private val coroutineScope = CoroutineScope(Dispatchers.IO) + private lateinit var sqlitePath: String + + fun initTables(tableCreatedCallback: ((String) -> Unit)? = null) { + val pathTokens = File(path).absolutePath.split(File.separator) + val file = pathTokens.last() + val parentDir = pathTokens.dropLast(1).joinToString(File.separator) + + if (!File(parentDir).exists()) + File(parentDir).mkdirs() + sqlitePath = parentDir + File.separator + file + if (expectedTables?.isEmpty() != false) return + run { + with(it.prepareStatement(TABLE_CHECK)) { + for ((table, create) in expectedTables) { + setString(1, table) + val res = executeQuery() + if (!res.next()) + with(it.createStatement()) { execute(create); tableCreatedCallback?.invoke(table) } + } + } + } + } + + fun pruneOldData (daysToKeep: Int, timestampFieldName: String = "ts") { + if (expectedTables?.isEmpty() != false) return + val timeDiff = daysToKeep * 24 * 60 * 60 + val nowTime = System.currentTimeMillis() / 1000 + run { + with (it.createStatement()) { + for ((table, _) in expectedTables) { + execute("DELETE FROM $table WHERE $timestampFieldName <= ${nowTime - timeDiff};") + } + } + } + } + + fun runAsync (closure: (conn: Connection) -> Unit) : Job { + return coroutineScope.launch { run (closure) } + } + + fun run (closure: (conn: Connection) -> Unit) { + dbRunLock.tryLock(10000L, TimeUnit.MILLISECONDS) + + connectionRefs++ + val con = connect() + closure.invoke(con) + connectionRefs-- + + if(connectionRefs == 0) { + con.close() + } + + dbRunLock.unlock() + } + + private fun connect(): Connection + { + obtainConnectionLock.tryLock(10000L, TimeUnit.MILLISECONDS) + + if (connection == null || connection!!.isClosed) + { + val ds = SQLiteDataSource() + ds.url = "jdbc:sqlite:$sqlitePath" + connection = ds.connection + } + + obtainConnectionLock.unlock() + return connection!! + } + + companion object { + const val TABLE_CHECK = "SELECT name FROM sqlite_master WHERE type='table' AND name=?;" + } +} \ No newline at end of file diff --git a/Server/src/main/core/net/Constants.java b/Server/src/main/core/net/Constants.java new file mode 100644 index 0000000..b9aebe8 --- /dev/null +++ b/Server/src/main/core/net/Constants.java @@ -0,0 +1,30 @@ +package core.net; + +/** + * Network constants. + * @author Vexia + */ +public final class Constants { + + /** + * Represents the post the server is hosted on. + */ + public static final int PORT = 43594; + + /** + * The revision of the game server. + */ + public static final int REVISION = 530; + + /** + * The client build of the client, used for notifying players of a client + * update. + */ + public static final int CLIENT_BUILD = 1; + + /** + * The default Management server IP. + */ + public static final String DEFAULT_MS_IP = "127.0.0.1"; + +} diff --git a/Server/src/main/core/net/EventProducer.java b/Server/src/main/core/net/EventProducer.java new file mode 100644 index 0000000..79db6bf --- /dev/null +++ b/Server/src/main/core/net/EventProducer.java @@ -0,0 +1,27 @@ +package core.net; + +import java.nio.ByteBuffer; + +/** + * Used for producing I/O events. + * @author Emperor + */ +public interface EventProducer { + + /** + * Produces a new read event. + * @param session The session. + * @param buffer The buffer to read. + * @return The read event handler. + */ + IoReadEvent produceReader(IoSession session, ByteBuffer buffer); + + /** + * Produces a new writing event. + * @param session The session. + * @param context The context. + * @return The write event handler. + */ + IoWriteEvent produceWriter(IoSession session, Object context); + +} \ No newline at end of file diff --git a/Server/src/main/core/net/IoEventHandler.java b/Server/src/main/core/net/IoEventHandler.java new file mode 100644 index 0000000..981b70d --- /dev/null +++ b/Server/src/main/core/net/IoEventHandler.java @@ -0,0 +1,114 @@ +package core.net; + +import core.game.world.repository.Repository; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.*; +import java.util.concurrent.ExecutorService; + +/** + * I/O event handling. + * @author Emperor + */ +public class IoEventHandler { + + /** + * The executor service. + */ + protected final ExecutorService service; + + /** + * Constructs a new {@code IoEventHandler}. + * @param service The executor service used for handling events. + */ + public IoEventHandler(ExecutorService service) { + this.service = service; + } + + /** + * Called when making a new connection. + * @param key The selection key. + * @throws IOException When an I/O exception occurs. + */ + public void connect(SelectionKey key) throws IOException { + /* + * empty. + */ + } + + /** + * Used for accepting a new connection. + * @param key The selection key. + * @param selector The selector. + * @throws IOException When an I/O exception occurs. + */ + public void accept(SelectionKey key, Selector selector) throws IOException { + SocketChannel sc = ((ServerSocketChannel) key.channel()).accept(); + sc.configureBlocking(false); + sc.socket().setTcpNoDelay(true); + sc.register(selector, SelectionKey.OP_READ); + } + + /** + * Reads the incoming packet data. + * @param key The selection key. + * @throws IOException When an I/O exception occurs. + */ + public void read(SelectionKey key) throws IOException { + ReadableByteChannel channel = (ReadableByteChannel) key.channel(); + ByteBuffer buffer = ByteBuffer.allocate(100_000); + IoSession session = (IoSession) key.attachment(); + try { + if (channel.read(buffer) == -1) { + if (session != null) { + session.disconnect(); + } + key.cancel(); + return; + } + } catch (IOException e) { + if (e.getMessage().contains("reset by peer") && session != null) { + session.disconnect(); + } else { + key.cancel(); + return; + } + } + buffer.flip(); + if (session == null) { + key.attach(session = new IoSession(key, service)); + } + service.execute(session.getProducer().produceReader(session, buffer)); + } + + /** + * Writes the outgoing packet data. + * @param key The selection key. + */ + public void write(SelectionKey key) { + IoSession session = (IoSession) key.attachment(); + key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE); + session.write(); + } + + /** + * Disconnects a connection. + * @param key The selection key. + * @param t The occurred exception (if any). + */ + public void disconnect(SelectionKey key, Throwable t) { + try { + IoSession session = (IoSession) key.attachment(); + String cause = "" + t; + if (t != null && !(t instanceof ClosedChannelException || cause.contains("De externe host") || cause.contains("De software op uw") || cause.contains("An established connection was aborted") || cause.contains("An existing connection") || cause.contains("AsynchronousClose"))) { + t.printStackTrace(); + } + if (session != null) { + session.disconnect(); + } + } catch (Throwable e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/Server/src/main/core/net/IoReadEvent.java b/Server/src/main/core/net/IoReadEvent.java new file mode 100644 index 0000000..0efbc67 --- /dev/null +++ b/Server/src/main/core/net/IoReadEvent.java @@ -0,0 +1,72 @@ +package core.net; + +import java.nio.ByteBuffer; + +/** + * Handles a reading event. + * @author Emperor + */ +public abstract class IoReadEvent implements Runnable { + + /** + * The I/O session. + */ + private final IoSession session; + + /** + * The buffer. + */ + private ByteBuffer buffer; + + /** + * If the queued reading buffer was used (debugging purposes). + */ + protected boolean usedQueuedBuffer; + + /** + * Constructs a new {@code IoReadEvent}. + * @param session The session. + * @param buffer The buffer to read from. + */ + public IoReadEvent(IoSession session, ByteBuffer buffer) { + this.session = session; + this.buffer = buffer; + } + + @Override + public void run() { + try { + if (session.getReadingQueue() != null) { + buffer = session.getReadingQueue().put(buffer); + buffer.flip(); + session.setReadingQueue(null); + usedQueuedBuffer = true; + } + read(session, buffer); + } catch (Throwable t) { + t.printStackTrace(); + session.disconnect(); + } + } + + /** + * Queues the buffer until more data has been received. + * @param data The data that has been read already. + */ + public void queueBuffer(int... data) { + ByteBuffer queue = ByteBuffer.allocate(data.length + buffer.remaining() + 100_000); + for (int value : data) { + queue.put((byte) value); + } + queue.put(buffer); + session.setReadingQueue(queue); + } + + /** + * Reads the data from the buffer. + * @param session The session. + * @param buffer The buffer to read from. + */ + public abstract void read(IoSession session, ByteBuffer buffer); + +} diff --git a/Server/src/main/core/net/IoSession.java b/Server/src/main/core/net/IoSession.java new file mode 100644 index 0000000..7e61dc2 --- /dev/null +++ b/Server/src/main/core/net/IoSession.java @@ -0,0 +1,438 @@ +package core.net; + +import core.cache.crypto.ISAACPair; +import core.game.node.entity.player.Player; +import core.game.node.entity.player.info.ClientInfo; +import core.game.system.task.Pulse; +import core.auth.AuthResponse; +import core.game.world.GameWorld; +import core.net.producer.HSEventProducer; +import core.net.producer.LoginEventProducer; +import core.game.world.repository.Repository; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.SelectionKey; +import java.nio.channels.SocketChannel; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +/** + * Represents a connected I/O session. + * @author Emperor + */ +public class IoSession { + + /** + * The handshake event producer. + */ + private static final EventProducer HANDSHAKE_PRODUCER = new HSEventProducer(); + + /** + * The selection key. + */ + private final SelectionKey key; + + public int isaacInputOpcode = 0; + + /** + * The executor service. + */ + private final ExecutorService service; + + /** + * The event producer. + */ + private EventProducer producer = HANDSHAKE_PRODUCER; + + /** + * The currently queued writing data. + */ + private List writingQueue = new ArrayList<>(20); + + /** + * The currently queued reading data. + */ + private ByteBuffer readingQueue; + + /** + * The writing lock. + */ + private Lock writingLock = new ReentrantLock(); + + /** + * The ISAAC cipher pair. + */ + private ISAACPair isaacPair; + + /** + * The name hash. + */ + private int nameHash; + + /** + * The server key. + */ + private long serverKey; + + /** + * The JS-5 encryption value. + */ + private int js5Encryption; + + /** + * The object. + */ + private Object object; + + /** + * If the session is active. + */ + private boolean active = true; + + /** + * The last ping time stamp. + */ + private long lastPing; + + /** + * The address. + */ + private final String address; + + /** + * The JS-5 queue. + */ + private final JS5Queue js5Queue; + + /** + * The client info. + */ + private ClientInfo clientInfo; + + public String associatedUsername; + + /** + * Constructs a new {@code IoSession}. + * @param key The selection key. + * @param service The executor service. + */ + public IoSession(SelectionKey key, ExecutorService service) { + this.key = key; + this.service = service; + this.address = getRemoteAddress().replaceAll("/", "").split(":")[0]; + this.js5Queue = new JS5Queue(this); + } + + /** + * Fires a write event created using the current event producer. + * @param context The event context. + */ + public void write(Object context) { + write(context, false); + } + + /** + * Fires a write event created using the current event producer. + * @param context The event context. + * @param instant If the event should be instantly executed on this thread. + */ + public void write(Object context, boolean instant) { + if (context == null) { + throw new IllegalStateException("Invalid writing context!"); + } + if (!(context instanceof AuthResponse) && producer instanceof LoginEventProducer) { + // new Throwable().printStackTrace(); + return; + } + if (instant) { + producer.produceWriter(this, context).run(); + return; + } + service.execute(producer.produceWriter(this, context)); + } + + /** + * Sends the packet data (without write event encoding). + * @param buffer The buffer. + */ + public void queue(ByteBuffer buffer) { + try { + writingLock.tryLock(1000L, TimeUnit.MILLISECONDS); + } catch (Exception e){ + e.printStackTrace(); + writingLock.unlock(); + } + writingQueue.add(buffer); + writingLock.unlock(); + write(); + } + + /** + * Handles the writing of all buffers in the queue. + */ + public void write() { + if (!key.isValid()) { + disconnect(); + return; + } + try { + writingLock.tryLock(1000L, TimeUnit.MILLISECONDS); + } catch (Exception e){ + e.printStackTrace(); + writingLock.unlock(); + return; + } + SocketChannel channel = (SocketChannel) key.channel(); + try { + while (!writingQueue.isEmpty()) { + ByteBuffer buffer = writingQueue.get(0); + channel.write(buffer); + if (buffer.hasRemaining()) { + key.interestOps(key.interestOps() | SelectionKey.OP_WRITE); + break; + } + writingQueue.remove(0); + } + } catch (IOException e) { + disconnect(); + } + writingLock.unlock(); + } + + /** + * Disconnects the session. + */ + public void disconnect() { + try { + if (!active) { + return; + } + active = false; + key.cancel(); + SocketChannel channel = (SocketChannel) key.channel(); + channel.socket().close(); + if (getPlayer() != null) { + try { + getPlayer().clear(); + } catch (Exception e) { + e.printStackTrace(); + } + } + object = null; + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * Gets the IP-address (without the port). + * @return The address. + */ + public String getAddress() { + return address; + } + + /** + * Gets the remote address of this session. + * @return The remote address, as a String. + */ + public String getRemoteAddress() { + try { + return ((SocketChannel) key.channel()).getRemoteAddress().toString(); + } catch (IOException e) { + throw new IllegalStateException(e); + } + } + + /** + * Gets the current event producer. + * @return The producer. + */ + public EventProducer getProducer() { + return producer; + } + + /** + * Sets the event producer. + * @param producer The producer to set. + */ + public void setProducer(EventProducer producer) { + this.producer = producer; + } + + /** + * Gets the queued reading data. + * @return The readingQueue. + */ + public ByteBuffer getReadingQueue() { + synchronized (this) { + return readingQueue; + } + } + + /** + * Queues reading data. + * @param readingQueue The readingQueue to set. + */ + public void setReadingQueue(ByteBuffer readingQueue) { + synchronized (this) { + this.readingQueue = readingQueue; + } + } + + /** + * Gets the writing lock. + * @return The writing lock. + */ + public Lock getWritingLock() { + return writingLock; + } + + /** + * Gets the selection key. + * @return The selection key. + */ + public SelectionKey getKey() { + return key; + } + + /** + * @return The active. + */ + public boolean isActive() { + return active; + } + + /** + * @return The js5Encryption. + */ + public int getJs5Encryption() { + return js5Encryption; + } + + /** + * @param js5Encryption The js5Encryption to set. + */ + public void setJs5Encryption(int js5Encryption) { + this.js5Encryption = js5Encryption; + } + + /** + * @return The player. + */ + public Player getPlayer() { + if (object == null) { + object = Repository.getPlayerByName(associatedUsername); + } + return object instanceof Player ? ((Player) object) : null; + } + + /** + * Gets the object. + * @return the object. + */ + public Object getObject() { + return object; + } + + /** + * @param object The object to set. + */ + public void setObject(Object object) { + this.object = object; + } + + /** + * Gets the lastPing. + * @return The lastPing. + */ + public long getLastPing() { + return lastPing; + } + + /** + * Sets the lastPing. + * @param lastPing The lastPing to set. + */ + public void setLastPing(long lastPing) { + this.lastPing = lastPing; + } + + /** + * Gets the nameHash. + * @return The nameHash. + */ + public int getNameHash() { + return nameHash; + } + + /** + * Sets the nameHash. + * @param nameHash The nameHash to set. + */ + public void setNameHash(int nameHash) { + this.nameHash = nameHash; + } + + /** + * Gets the serverKey. + * @return The serverKey. + */ + public long getServerKey() { + return serverKey; + } + + /** + * Sets the serverKey. + * @param serverKey The serverKey to set. + */ + public void setServerKey(long serverKey) { + this.serverKey = serverKey; + } + + /** + * Gets the isaacPair. + * @return The isaacPair. + */ + public ISAACPair getIsaacPair() { + return isaacPair; + } + + /** + * Sets the isaacPair. + * @param isaacPair The isaacPair to set. + */ + public void setIsaacPair(ISAACPair isaacPair) { + this.isaacPair = isaacPair; + } + + /** + * Gets the js5Queue. + * @return the js5Queue + */ + public JS5Queue getJs5Queue() { + return js5Queue; + } + + /** + * Gets the clientInfo value. + * @return The clientInfo. + */ + public ClientInfo getClientInfo() { + return clientInfo; + } + + /** + * Sets the clientInfo value. + * @param clientInfo The clientInfo to set. + */ + public void setClientInfo(ClientInfo clientInfo) { + this.clientInfo = clientInfo; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/IoWriteEvent.java b/Server/src/main/core/net/IoWriteEvent.java new file mode 100644 index 0000000..acb1132 --- /dev/null +++ b/Server/src/main/core/net/IoWriteEvent.java @@ -0,0 +1,50 @@ +package core.net; + +import java.nio.channels.CancelledKeyException; + +/** + * Handles a writing event. + * @author Emperor + */ +public abstract class IoWriteEvent implements Runnable { + + /** + * The I/O session. + */ + private final IoSession session; + + /** + * The buffer. + */ + private final Object context; + + /** + * Constructs a new {@code IoWriteEvent}. + * @param session The session. + * @param context The write event context. + */ + public IoWriteEvent(IoSession session, Object context) { + this.session = session; + this.context = context; + } + + @Override + public void run() { + try { + write(session, context); + } catch (Throwable t) { + if (!(t instanceof CancelledKeyException)) { + t.printStackTrace(); + } + session.disconnect(); + } + } + + /** + * Writes the data. + * @param session The session. + * @param context The write event context. + */ + public abstract void write(IoSession session, Object context); + +} \ No newline at end of file diff --git a/Server/src/main/core/net/JS5Queue.java b/Server/src/main/core/net/JS5Queue.java new file mode 100644 index 0000000..b08d1b1 --- /dev/null +++ b/Server/src/main/core/net/JS5Queue.java @@ -0,0 +1,97 @@ +package core.net; + +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * Handles the JS5 queue for a session. + * @author Techdaan + */ +public final class JS5Queue { + + public static AtomicBoolean RUNNING = new AtomicBoolean(true); + + private static final Js5QueueHandler handler = new Js5QueueHandler(); + + private static class Js5QueueHandler extends Thread { + private final LinkedBlockingDeque requests = new LinkedBlockingDeque<>(); + + @Override + public void run() { + while (RUNNING.get()) { + try { + Js5Request request = requests.take(); + + JS5Queue queue = request.queue; + + if (queue.session.isActive()) { + queue.session.write(new int[]{request.index, request.archive, request.priority ? 1 : 0}); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + + static { + try { + handler.start(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private static class Js5Request { + private final JS5Queue queue; + private final int index; + private final int archive; + private final boolean priority; + + public Js5Request(JS5Queue queue, int index, int archive, boolean priority) { + this.queue = queue; + this.index = index; + this.archive = archive; + this.priority = priority; + } + } + + /** + * The I/O session. + */ + private final IoSession session; + + /** + * Constructs a new {@code JS5Queue} {@code Object}. + * @param session The I/O session. + */ + public JS5Queue(IoSession session) { + this.session = session; + } + + /** + * Queues a JS-5 request. + * Timers: + * 1000ms queue up files for this long + * 100ms release a file from the queue + * + * @param container The container. + * @param archive The archive. + * @param highPriority If the request is high priority. + * + */ + public void queue(int container, int archive, boolean highPriority) { + Js5Request request = new Js5Request(this, container, archive, highPriority); + handler.requests.add(request); + } + + /** + * Gets the session. + * @return the session + */ + public IoSession getSession() { + return session; + } + + +} \ No newline at end of file diff --git a/Server/src/main/core/net/NioReactor.java b/Server/src/main/core/net/NioReactor.java new file mode 100644 index 0000000..42fea5a --- /dev/null +++ b/Server/src/main/core/net/NioReactor.java @@ -0,0 +1,148 @@ +package core.net; + +import core.net.amsc.MSEventHandler; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; +import java.nio.channels.ServerSocketChannel; +import java.nio.channels.SocketChannel; +import java.util.Iterator; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +/** + * Handles (NIO-based) networking events using the reactor pattern. + * @author Emperor + */ +public final class NioReactor implements Runnable { + + /** + * The executor service. + */ + private final ExecutorService service; + + /** + * The socket channel. + */ + private ServerSocketConnection channel; + + /** + * The I/O event handling instance. + */ + private IoEventHandler eventHandler; + + /** + * If the reactor is running. + */ + private boolean running; + + /** + * Constructs a new {@code NioReactor}. + */ + private NioReactor(IoEventHandler eventHandler) { + this.service = Executors.newSingleThreadScheduledExecutor(); + this.eventHandler = eventHandler; + } + + /** + * Creates and configures a new {@code NioReactor} with a pool size of 1. + * @param port The port. + * @return The {@code NioReactor} {@code Object}. + * @throws IOException When an I/O exception occurs. + */ + public static NioReactor configure(int port) throws IOException { + return configure(port, 1); + } + + /** + * Creates and configures a new {@code NioReactor}. + * @param port The port. + * @param poolSize The amount of threads in the thread pool. + * @return The {@code NioReactor} {@code Object}. + * @throws IOException When an I/O exception occurs. + */ + public static NioReactor configure(int port, int poolSize) throws IOException { + NioReactor reactor = new NioReactor(new IoEventHandler(Executors.newFixedThreadPool(poolSize))); + ServerSocketChannel channel = ServerSocketChannel.open(); + Selector selector = Selector.open(); + channel.bind(new InetSocketAddress(port)); + channel.configureBlocking(false); + channel.register(selector, SelectionKey.OP_ACCEPT); + reactor.channel = new ServerSocketConnection(selector, channel); + return reactor; + } + + /** + * Starts a NIO reactor used for client connections. + * @param address The IP-address to connect to. + * @param port The port used. + * @return The NIO reactor object. + * @throws IOException When an exception occurs. + */ + public static NioReactor connect(String address, int port) throws IOException { + NioReactor reactor = new NioReactor(new MSEventHandler()); + Selector selector = Selector.open(); + SocketChannel channel = SocketChannel.open(); + channel.configureBlocking(false); + channel.socket().setKeepAlive(true); + channel.socket().setTcpNoDelay(true); + channel.connect(new InetSocketAddress(address, port)); + channel.register(selector, SelectionKey.OP_CONNECT); + reactor.channel = new ServerSocketConnection(selector, channel); + return reactor; + } + + /** + * Starts the reactor. + */ + public void start() { + running = true; + service.execute(this); + } + + @Override + public void run() { + Thread.currentThread().setName("NioReactor"); + while (running) { + try { + channel.getSelector().select(); + } catch (IOException e) { + e.printStackTrace(); + } + Iterator iterator = channel.getSelector().selectedKeys().iterator(); + while (iterator.hasNext()) { + SelectionKey key = iterator.next(); + iterator.remove(); + try { + if (!key.isValid() || !key.channel().isOpen()) { + key.cancel(); + continue; + } + if (key.isConnectable()) { + eventHandler.connect(key); + } + if (key.isAcceptable()) { + eventHandler.accept(key, channel.getSelector()); + } + if (key.isReadable()) { + eventHandler.read(key); + } else if (key.isWritable()) { + eventHandler.write(key); + } + } catch (Throwable t) { + eventHandler.disconnect(key, t); + } + } + } + } + + /** + * Terminates the reactor (once it's done processing current I/O events). + */ + public void terminate() { + running = false; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/ServerSocketConnection.java b/Server/src/main/core/net/ServerSocketConnection.java new file mode 100644 index 0000000..d4fb0f2 --- /dev/null +++ b/Server/src/main/core/net/ServerSocketConnection.java @@ -0,0 +1,83 @@ +package core.net; + +import java.nio.channels.Selector; +import java.nio.channels.ServerSocketChannel; +import java.nio.channels.SocketChannel; + +/** + * Represents a server socket and its selector. + * @author Emperor + */ +public final class ServerSocketConnection { + + /** + * The selector. + */ + private final Selector selector; + + /** + * The channel. + */ + private final ServerSocketChannel channel; + + /** + * The socket channel. + */ + private final SocketChannel socket; + + /** + * Constructs a new {@code ServerSocketConnection} {@code Object}. + * @param selector The selector. + * @param channel The channel. + */ + public ServerSocketConnection(Selector selector, ServerSocketChannel channel) { + this.selector = selector; + this.channel = channel; + this.socket = null; + } + + /** + * Constructs a new {@Code ServerSocketConnection} {@Code + * Object} + * @param selector The selector. + * @param channel The channel. + */ + public ServerSocketConnection(Selector selector, SocketChannel channel) { + this.selector = selector; + this.socket = channel; + this.channel = null; + } + + /** + * If the channel is used as client. + * @return {@code True} if so. + */ + public boolean isClient() { + return socket != null; + } + + /** + * Gets the selector. + * @return the selector. + */ + public Selector getSelector() { + return selector; + } + + /** + * Gets the channel. + * @return the channel. + */ + public ServerSocketChannel getChannel() { + return channel; + } + + /** + * Gets the socket. + * @return the socket + */ + public SocketChannel getSocket() { + return socket; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/amsc/MSEventHandler.java b/Server/src/main/core/net/amsc/MSEventHandler.java new file mode 100644 index 0000000..70bea40 --- /dev/null +++ b/Server/src/main/core/net/amsc/MSEventHandler.java @@ -0,0 +1,69 @@ +package core.net.amsc; + +import core.tools.Log; +import core.tools.SystemLogger; +import core.net.IoEventHandler; +import core.net.IoSession; + +import java.io.IOException; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; +import java.nio.channels.SocketChannel; +import java.util.concurrent.Executors; + +import static core.api.ContentAPIKt.log; + +/** + * Handles the management server events. + * @author Emperor + */ +public final class MSEventHandler extends IoEventHandler { + + /** + * Constructs a new {@Code MSEventHandler} {@Code Object} + */ + public MSEventHandler() { + super(Executors.newSingleThreadExecutor()); + } + + @Override + public void connect(SelectionKey key) throws IOException { + SocketChannel ch = (SocketChannel) key.channel(); + try { + if (ch.finishConnect()) { + key.interestOps(key.interestOps() ^ SelectionKey.OP_CONNECT); + key.interestOps(key.interestOps() | SelectionKey.OP_READ); + IoSession session = (IoSession) key.attachment(); + key.attach(session = new IoSession(key, service)); + WorldCommunicator.register(session); + return; + } + } catch (Throwable t) { + t.printStackTrace(); + } + log(this.getClass(), Log.ERR, "Failed connecting to Management Server!"); + WorldCommunicator.terminate(); + } + + @Override + public void accept(SelectionKey key, Selector selector) throws IOException { + super.write(key); + } + + @Override + public void read(SelectionKey key) throws IOException { + super.read(key); + } + + @Override + public void write(SelectionKey key) { + super.write(key); + } + + @Override + public void disconnect(SelectionKey key, Throwable t) { + super.disconnect(key, t); + WorldCommunicator.terminate(); + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/amsc/MSPacketRepository.java b/Server/src/main/core/net/amsc/MSPacketRepository.java new file mode 100644 index 0000000..f1072e6 --- /dev/null +++ b/Server/src/main/core/net/amsc/MSPacketRepository.java @@ -0,0 +1,100 @@ +package core.net.amsc; + +import core.game.node.entity.player.Player; +import core.game.system.communication.*; +import core.net.packet.IoBuffer; +import core.net.packet.PacketHeader; + +/** + * The Management server packet repository. + * @author Emperor + */ +public final class MSPacketRepository { + /** + * Sends a contact update. + * + * @param username The username. + * @param contact The contact's username. + * @param remove If we're removing the contact from the list. + * @param block If the contact list is for the blocked players. + * @param rank The new clan rank (or null when not updating clan rank!). + */ + public static void sendContactUpdate(String username, String contact, boolean remove, boolean block, ClanRank rank) { + IoBuffer buffer = new IoBuffer(block ? 5 : 4, PacketHeader.BYTE); + buffer.putString(username); + buffer.putString(contact); + if (rank != null) { + buffer.put((byte) 2); + buffer.put((byte) rank.ordinal()); + } else { + buffer.put((byte) (remove ? 1 : 0)); + } + WorldCommunicator.getSession().write(buffer); + } + + /** + * Sends the clan rename packet. + * + * @param player The player. + * @param clanName The clan name. + */ + public static void sendClanRename(Player player, String clanName) { + IoBuffer buffer = new IoBuffer(7, PacketHeader.BYTE); + buffer.putString(player.getName()); + buffer.putString(clanName); + WorldCommunicator.getSession().write(buffer); + } + + /** + * Sets a clan setting. + * + * @param player The player. + * @param type The setting type. + * @param rank The rank to set. + */ + public static void setClanSetting(Player player, int type, ClanRank rank) { + if (!WorldCommunicator.isEnabled()) { + return; + } + IoBuffer buffer = new IoBuffer(8, PacketHeader.BYTE); + buffer.putString(player.getName()); + buffer.put((byte) type); + if (rank != null) { + buffer.put((byte) rank.ordinal()); + } + WorldCommunicator.getSession().write(buffer); + } + + /** + * Sends the kicking a clan member packet. + * + * @param username The player's username. + * @param name The name. + */ + public static void sendClanKick(String username, String name) { + IoBuffer buffer = new IoBuffer(9, PacketHeader.BYTE); + buffer.putString(username); + buffer.putString(name); + WorldCommunicator.getSession().write(buffer); + } + + /** + * Sends the chat settings. + * + * @param player The player. + * @param publicSetting The public chat setting. + * @param privateSetting The private chat setting. + * @param tradeSetting The trade setting. + */ + public static void sendChatSetting(Player player, int publicSetting, int privateSetting, int tradeSetting) { + IoBuffer buffer = new IoBuffer(13, PacketHeader.BYTE); + buffer.putString(player.getName()); + buffer.put(publicSetting); + buffer.put(privateSetting); + buffer.put(tradeSetting); + if (WorldCommunicator.getSession() != null) + WorldCommunicator.getSession().write(buffer); + else + player.sendMessage("Privacy settings unavailable at the moment. Please try again later."); + } +} diff --git a/Server/src/main/core/net/amsc/ManagementServerState.java b/Server/src/main/core/net/amsc/ManagementServerState.java new file mode 100644 index 0000000..81db143 --- /dev/null +++ b/Server/src/main/core/net/amsc/ManagementServerState.java @@ -0,0 +1,59 @@ +package core.net.amsc; + +import core.game.node.entity.player.Player; +import core.game.world.repository.Repository; +import core.net.packet.PacketRepository; +import core.net.packet.context.ContactContext; +import core.net.packet.out.ContactPackets; + +/** + * The management server state. + * @author Emperor + */ +public enum ManagementServerState { + + /** + * If the management server is not available. + */ + NOT_AVAILABLE(2), + + /** + * If we're still connecting to the Management server. + */ + CONNECTING(1), + + /** + * If we're connected to the management server. + */ + AVAILABLE(2); + + /** + * The value of this state. + */ + private final int value; + + /** + * Constructs a new {@code ManagementServerState} {@code Object} + * @param value The value. + */ + private ManagementServerState(int value) { + this.value = value; + } + + /** + * Called when the state gets set. + */ + public void set() { + for (Player player : Repository.getPlayers()) { + PacketRepository.send(ContactPackets.class, new ContactContext(player, ContactContext.UPDATE_STATE_TYPE)); + } + } + + /** + * Gets the state value. + * @return The value. + */ + public int value() { + return value; + } +} \ No newline at end of file diff --git a/Server/src/main/core/net/amsc/WorldCommunicator.java b/Server/src/main/core/net/amsc/WorldCommunicator.java new file mode 100644 index 0000000..1c634d1 --- /dev/null +++ b/Server/src/main/core/net/amsc/WorldCommunicator.java @@ -0,0 +1,207 @@ +package core.net.amsc; + +import core.net.EventProducer; +import core.net.IoSession; +import core.net.NioReactor; +import core.net.producer.MSHSEventProducer; +import core.game.node.entity.player.info.login.LoginParser; +import core.tools.SystemLogger; +import core.game.world.GameWorld; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * Handles world communication. + * @author Emperor + */ +public final class WorldCommunicator { + + /** + * The handshake events producer. + */ + private static final EventProducer HANDSHAKE_PRODUCER = new MSHSEventProducer(); + + /** + * The current state. + */ + private static ManagementServerState state = ManagementServerState.CONNECTING; + + /** + * The I/O session. + */ + private static IoSession session; + + /** + * The world information. + */ + private static final WorldStatistics[] WORLDS = new WorldStatistics[10]; + + /** + * The current login attempts. + */ + private static final Map loginAttempts = new ConcurrentHashMap<>(); + + /** + * The NIO reactor. + */ + private static NioReactor reactor; + + /** + * Registers a new world. + * @param session The session. + */ + public static void register(IoSession session) { + WorldCommunicator.session = session; + session.setProducer(HANDSHAKE_PRODUCER); + session.write(true); + WORLDS[GameWorld.getSettings().getWorldId() - 1] = new WorldStatistics(GameWorld.getSettings().getWorldId()); + session.setObject(WORLDS[GameWorld.getSettings().getWorldId() - 1]); + } + + /** + * Attempts to connect to the management server. + */ + public static void connect() { + try { + setState(ManagementServerState.CONNECTING); + /*if (isLocallyHosted()) { + SystemLogger.log("Management server is hosted on local machine!"); + reactor = NioReactor.connect(GameWorld.getSettings().getMsAddress(), 5555); + } else {*/ + reactor = NioReactor.connect(GameWorld.getSettings().getMsAddress(), 5555); + //} + reactor.start(); + } catch (Throwable e) { + e.printStackTrace(); + terminate(); + } + } + + /** + * Checks if the Management server is locally hosted. + * @return {@code True} if so. + * @throws IOException When an I/O exception occurs. + */ + private static boolean isLocallyHosted() throws IOException { + InetAddress address = InetAddress.getByName(GameWorld.getSettings().getMsAddress()); + if (address.isAnyLocalAddress() || address.isLoopbackAddress()) { + return true; + } + return NetworkInterface.getByInetAddress(address) != null; + } + + /** + * Terminates the world communicator. + */ + public static void terminate() { + setState(ManagementServerState.NOT_AVAILABLE); + if (reactor != null) { + reactor.terminate(); + reactor = null; + } + } + + /** + * Gets and removes the login attempt for the given username. + * @param username The username. + * @return The login attempt. + */ + public static LoginParser finishLoginAttempt(String username) { + return loginAttempts.remove(username); + } + + /** + * Gets the local world. + * @return The world statistics of this world server. + */ + public static WorldStatistics getLocalWorld() { + return WORLDS[GameWorld.getSettings().getWorldId() - 1]; + } + + /** + * Gets the id of the world the player is connected to. + * @param playerName The player's name. + * @return The world id, or -1 if the player wasn't connected. + */ + public static int getWorld(String playerName) { + for (int i = 0; i < WORLDS.length; i++) { + if (WORLDS[i].getPlayers().contains(playerName)) { + return i; + } + } + return -1; + } + + /** + * Gets the world statistics for the given index. + * @param id The world id. + * @return The world statistics. + */ + public static WorldStatistics getWorld(int id) { + return WORLDS[id - 1]; + } + + /** + * Gets the session. + * @return the session + */ + public static IoSession getSession() { + return session; + } + + /** + * Checks if this world is connected to the Management server. + * @return {@code True} if so. + */ + public static boolean isEnabled() { + return state == ManagementServerState.AVAILABLE; + } + + /** + * Gets the login attempts mapping. + * @return The login attempts mapping. + */ + public static Map getLoginAttempts() { + return loginAttempts; + } + + /** + * Gets the state. + * @return the state + */ + public static ManagementServerState getState() { + return state; + } + + /** + * Sets the state. + * @param state the state to set. + */ + public static void setState(ManagementServerState state) { + if (WorldCommunicator.state != state) { + WorldCommunicator.state = state; + state.set(); + } + } + + /** + * Gets the reactor. + * @return the reactor + */ + public static NioReactor getReactor() { + return reactor; + } + + /** + * Sets the reactor. + * @param reactor the reactor to set. + */ + public static void setReactor(NioReactor reactor) { + WorldCommunicator.reactor = reactor; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/amsc/WorldStatistics.java b/Server/src/main/core/net/amsc/WorldStatistics.java new file mode 100644 index 0000000..bbae465 --- /dev/null +++ b/Server/src/main/core/net/amsc/WorldStatistics.java @@ -0,0 +1,45 @@ +package core.net.amsc; + +import java.util.ArrayList; +import java.util.List; + +/** + * Holds information of a certain game world. + * @author Emperor + */ +public final class WorldStatistics { + + /** + * The world id. + */ + private final int id; + + /** + * The list of players connected to this world. + */ + private final List players = new ArrayList<>(20); + + /** + * Constructs a new {@code WorldStatistics} {@Code Object} + * @param id The world id. + */ + public WorldStatistics(int id) { + this.id = id; + } + + /** + * Gets the players. + * @return the players + */ + public List getPlayers() { + return players; + } + + /** + * Gets the id. + * @return the id + */ + public int getId() { + return id; + } +} \ No newline at end of file diff --git a/Server/src/main/core/net/event/GameReadEvent.java b/Server/src/main/core/net/event/GameReadEvent.java new file mode 100644 index 0000000..f8dc8a9 --- /dev/null +++ b/Server/src/main/core/net/event/GameReadEvent.java @@ -0,0 +1,143 @@ +package core.net.event; + +import core.tools.Log; +import core.tools.SystemLogger; +import core.net.IoReadEvent; +import core.net.IoSession; +import core.net.packet.IoBuffer; +import core.net.packet.PacketProcessor; +import core.net.packet.in.Decoders530; +import core.net.packet.in.Packet; + +import java.nio.ByteBuffer; + +import static core.api.ContentAPIKt.log; + +/** + * Handles game packet reading. + * @author Emperor + */ +public final class GameReadEvent extends IoReadEvent { + + /** + * The incoming packet sizes, sorted by opcode. + */ + public static final int[] PACKET_SIZES = { + -3, -3, -3, 2, 2, -3, 8, -3, -3, 6, // 0-9 + 4, -3, -3, -3, -3, -3, -3, 0, -3, -3, // 10-19 + 4, 4, 1, 4, -3, -3, -3, 16, -3, -3, // 20-29 + 2, -3, -3, 6, 8, -3, -3, -3, -3, -1, // 30-39 + -3, -3, -3, -3, -1, -3, -3, -3, 6, -3, // 40-49 + -3, -3, -3, 6, -3, 8, -3, 8, -3, -3, // 50-59 + -3, -3, -3, -3, 6, -1, 6, -3, 2, -3, // 60-69 + -3, 2, 2, 12, -3, 6, -3, -1, 2, 12, // 70-79 + -3, 8, 12, -3, 6, 8, -3, -3, -3, -3, // 80-89 + -3, -3, 2, 0, 2, -3, -3, -3, 4, 10, // 90-99 + -3, 14, -3, -3, 8, -3, 2, -3, -3, 6, // 100-109 + 0, 2, -3, -3, 2, 10, -3, -1, -3, -3, // 110-119 + 8, -3, -3, -1, 6, -3, -3, -3, -3, -3, // 120-129 + -3, 10, 6, 2, 14, 8, -3, 4, -3, -3, // 130-139 + -3, -3, -3, -3, -3, -3, -3, -3, 2, -3, // 140-149 + -3, -3, -3, 8, 8, 6, 8, 3, -3, -3, // 150-159 + -3, 8, 8, -3, -3, -3, 6, -1, 6, -3, // 160-169 + 6, -3, -3, -3, -3, 2, -3, 2, -1, 4, // 170-179 + 2, -3, -3, -3, 0, -3, -3, -3, 9, -3, // 180-189 + -3, -3, -3, -3, 6, 8, 6, -3, -3, 6, // 190-199 + -3, -1, -3, -3, -3, -3, 8, -3, -3, -3, // 200-209 + -3, -3, -3, 8, -3, -1, -3, -3, 2, -3, // 210-219 + -3, -3, -3, -3, -3, -3, -3, -3, 6, -3, // 220-229 + -3, 9, -3, 12, 6, -3, -3, -1, -3, 8, // 230-239 + -3, -3, -3, 6, 8, 0, -3, 6, 10, -3, // 240-249 + -3, -3, -3, 14, 6, -3 // 250-255 + }; + + /** + * Constructs a new {@code GameReadEvent}. + * @param session The session. + * @param buffer The buffer to read from. + */ + public GameReadEvent(IoSession session, ByteBuffer buffer) { + super(session, buffer); + } + + @Override + public void read(IoSession session, ByteBuffer buffer) { + int last = -1; + while (buffer.hasRemaining()) { + int opcode = buffer.get() & 0xFF; + if (session == null || session.getPlayer() == null) { + continue; + } + int header = PACKET_SIZES[opcode]; + int size = header; + if (header < 0) { + size = getPacketSize(buffer, opcode, header, last); + } + if (size == -1) { + session.getPlayer().incrementInvalidPacketCount(); + break; + } + if (buffer.remaining() < size) { + switch (header) { + case -2: + queueBuffer(opcode, size >> 8, size); + break; + case -1: + queueBuffer(opcode, size); + break; + default: + queueBuffer(opcode); + break; + } + break; + } + byte[] data = new byte[size]; + buffer.get(data); + IoBuffer buf = new IoBuffer(opcode, null, ByteBuffer.wrap(data)); + session.setLastPing(System.currentTimeMillis()); + last = opcode; + + //Authentic per-player per-tick limit on inbound packets + if (session.getPlayer().opCounts[opcode]++ >= 10) { + log(this.getClass(), Log.FINE, "Skipping packet " + opcode + " because already received more than 10!"); + return; + } + + Packet processed = Decoders530.process(session.getPlayer(), opcode, buf); + if (processed instanceof Packet.UnhandledOp) { + log(this.getClass(), Log.WARN, "Unhandled opcode: " + opcode); + } else if (processed instanceof Packet.DecodingError) { + log(this.getClass(), Log.ERR, ((Packet.DecodingError) processed).getMessage()); + } else if (!(processed instanceof Packet.NoProcess)) { + PacketProcessor.enqueue(processed); + } + } + } + + /** + * Gets the packet size for the given opcode. + * @param buffer The buffer. + * @param opcode The opcode. + * @param header The packet header. + * @param last The last opcode. + * @return The packet size. + */ + private int getPacketSize(ByteBuffer buffer, int opcode, int header, int last) { + if (header == -1) { + if (buffer.remaining() < 1) { + queueBuffer(opcode); + return -1; + } + return buffer.get() & 0xFF; + } + if (header == -2) { + if (buffer.remaining() < 2) { + queueBuffer(opcode); + return -1; + } + return buffer.getShort() & 0xFFFF; + } + return -1; + } + +} diff --git a/Server/src/main/core/net/event/GameWriteEvent.java b/Server/src/main/core/net/event/GameWriteEvent.java new file mode 100644 index 0000000..568b974 --- /dev/null +++ b/Server/src/main/core/net/event/GameWriteEvent.java @@ -0,0 +1,54 @@ +package core.net.event; + +import core.net.IoSession; +import core.net.IoWriteEvent; +import core.net.packet.IoBuffer; + +import java.nio.ByteBuffer; + +/** + * Handles game packet writing events. + * @author Emperor + */ +public final class GameWriteEvent extends IoWriteEvent { + + /** + * Constructs a new {@code GameWriteEvent}. + * @param session The session. + * @param context The context. + */ + public GameWriteEvent(IoSession session, Object context) { + super(session, context); + } + + @Override + public void write(IoSession session, Object context) { + if (context instanceof ByteBuffer) { + session.queue((ByteBuffer) context); + return; + } + IoBuffer buffer = (IoBuffer) context; + ByteBuffer buf = (ByteBuffer) buffer.toByteBuffer().flip(); + if (buf == null) { + throw new RuntimeException("Critical networking error: The byte buffer requested was null."); + } + if (buffer.opcode() != -1) { + int packetLength = buf.remaining() + 4; + ByteBuffer response = ByteBuffer.allocate(packetLength); + response.put((byte) buffer.opcode()); + switch (buffer.getHeader()) { + case BYTE: + response.put((byte) buf.remaining()); + break; + case SHORT: + response.putShort((short) buf.remaining()); + break; + default: + break; + } + buf = (ByteBuffer) response.put(buf).flip(); + } + session.queue(buf); + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/event/HSReadEvent.java b/Server/src/main/core/net/event/HSReadEvent.java new file mode 100644 index 0000000..bf98d5a --- /dev/null +++ b/Server/src/main/core/net/event/HSReadEvent.java @@ -0,0 +1,76 @@ +package core.net.event; + +import core.net.IoReadEvent; +import core.net.IoSession; +import core.net.lobby.WorldList; +import core.net.registry.AccountRegister; +import core.tools.Log; +import core.tools.RandomFunction; +import core.tools.SystemLogger; + +import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.Map; + +import static core.api.ContentAPIKt.log; + +/** + * Handles handshake read events. + * @author Emperor + */ +public final class HSReadEvent extends IoReadEvent { + + // debug + static Map count = new HashMap<>(); + + /** + * Constructs a new {@code HSReadEvent}. + * @param session The session. + * @param buffer The buffer. + */ + public HSReadEvent(IoSession session, ByteBuffer buffer) { + super(session, buffer); + } + + @Override + public void read(IoSession session, ByteBuffer buffer) { + Integer amount = count.get(session.getAddress()); + if (amount == null) { + amount = 0; + } + count.put(session.getAddress(), amount + 1); + int opcode = buffer.get() & 0xFF; + switch (opcode) { + case 14: + session.setNameHash(buffer.get() & 0xFF); + session.setServerKey(RandomFunction.RANDOM.nextLong()); + session.write(true); + break; + case 15: + int revision = buffer.getInt(); + //int sub_revision = buffer.getInt(); + buffer.flip(); + + if (revision != 530 ){//|| sub_revision != Constants.CLIENT_BUILD) { + session.disconnect(); + break; + } + session.write(false); + break; + case 147: + case 186: + case 36: + AccountRegister.read(session, opcode, buffer); + break; + case 255: // World list + int updateStamp = buffer.getInt(); + WorldList.sendUpdate(session, updateStamp); + break; + default: + log(this.getClass(), Log.FINE, "PKT " + opcode); + session.disconnect(); + break; + } + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/event/HSWriteEvent.java b/Server/src/main/core/net/event/HSWriteEvent.java new file mode 100644 index 0000000..fec8765 --- /dev/null +++ b/Server/src/main/core/net/event/HSWriteEvent.java @@ -0,0 +1,49 @@ +package core.net.event; + +import core.net.IoSession; +import core.net.IoWriteEvent; +import core.net.producer.JS5EventProducer; +import core.net.producer.LoginEventProducer; + +import java.nio.ByteBuffer; + +/** + * Handles Handshake write events. + * @author Emperor + */ +public final class HSWriteEvent extends IoWriteEvent { + + /** + * The JS-5 event producer. + */ + private static final JS5EventProducer JS5_PRODUCER = new JS5EventProducer(); + + /** + * The login event producer. + */ + private static final LoginEventProducer LOGIN_PRODUCER = new LoginEventProducer(); + + /** + * Constructs a new {@code HSWriteEvent} {@code Object}. + * @param session The session. + * @param context The context. + */ + public HSWriteEvent(IoSession session, Object context) { + super(session, context); + } + + @Override + public void write(IoSession session, Object context) { + ByteBuffer buffer = ByteBuffer.allocate(9); + buffer.put((byte) 0); + if ((Boolean) context) { + buffer.putLong(session.getServerKey()); + session.setProducer(LOGIN_PRODUCER); + } else { + session.setProducer(JS5_PRODUCER); + } + buffer.flip(); + session.queue(buffer); + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/event/JS5ReadEvent.java b/Server/src/main/core/net/event/JS5ReadEvent.java new file mode 100644 index 0000000..4b1571d --- /dev/null +++ b/Server/src/main/core/net/event/JS5ReadEvent.java @@ -0,0 +1,81 @@ +package core.net.event; + +import core.cache.misc.buffer.ByteBufferUtils; +import core.net.IoReadEvent; +import core.net.IoSession; + +import java.nio.ByteBuffer; + +/** + * Handles JS-5 reading events. + * @author Emperor + */ +public final class JS5ReadEvent extends IoReadEvent { + + /** + * Constructs a new {@code JS5ReadEvent}. + * @param session The session. + * @param buffer The buffer. + */ + public JS5ReadEvent(IoSession session, ByteBuffer buffer) { + super(session, buffer); + } + + @Override + public void read(IoSession session, ByteBuffer buffer) { + while (buffer.hasRemaining()) { + int opcode = buffer.get() & 0xFF; + + if (buffer.remaining() < 3) { + queueBuffer(opcode); + return; + } + switch (opcode) { + case 0: + case 1: + int request = ByteBufferUtils.getMedium(buffer); + + int container = request >> 16 & 0xFF; + + int archive = request & 0xFFFF; + + session.getJs5Queue().queue(container, archive, opcode == 1); + break; + case 2: // music + case 3: // Music + buffer.get(); + buffer.getShort(); + break; + case 4: + session.setJs5Encryption(buffer.get()); + if (buffer.getShort() != 0) { + session.disconnect(); + return; + } + break; + case 5: + case 9: + if (buffer.remaining() < 4) { + queueBuffer(opcode); + return; + } + buffer.getInt(); + break; + case 6: + ByteBufferUtils.getMedium(buffer); // Value should be 3 + // buffer.getShort(); // Value should be 0 + break; + case 7: + buffer.get(); + buffer.getShort(); + session.disconnect(); + return; + default: + + buffer.get(); + buffer.getShort(); + break; + } + } + } +} \ No newline at end of file diff --git a/Server/src/main/core/net/event/JS5WriteEvent.java b/Server/src/main/core/net/event/JS5WriteEvent.java new file mode 100644 index 0000000..bd0bd22 --- /dev/null +++ b/Server/src/main/core/net/event/JS5WriteEvent.java @@ -0,0 +1,71 @@ +package core.net.event; + +import core.cache.Cache; +import core.net.IoSession; +import core.net.IoWriteEvent; + +import java.nio.ByteBuffer; + +/** + * Handles JS-5 writing events. + * @author Emperor + */ +public final class JS5WriteEvent extends IoWriteEvent { + + /** + * The cached reference data. + */ + private static byte[] cachedReference; + + /** + * Constructs a new {@code JS5WriteEvent}. + * @param session The session. + * @param context The event context. + */ + public JS5WriteEvent(IoSession session, Object context) { + super(session, context); + } + + @Override + public void write(IoSession session, Object context) { + int[] request = (int[]) context; + int container = request[0]; + int archive = request[1]; + boolean priority = request[2] == 1; + if (archive == 255 && container == 255) { + session.queue(getReferenceData()); + return; + } + ByteBuffer response = Cache.getArchiveData(container, archive, priority, session.getJs5Encryption()); + if (response != null) { + session.queue(response); + } + } + + /** + * Gets the reference data. + * @return The reference data. + */ + private static ByteBuffer getReferenceData() { + if (cachedReference == null) { + cachedReference = Cache.generateReferenceData(); + } + ByteBuffer buffer = ByteBuffer.allocate(cachedReference.length << 2); + buffer.put((byte) 255); + buffer.putShort((short) 255); + buffer.put((byte) 0); + buffer.putInt(cachedReference.length); + int offset = 10; + for (int index = 0; index < cachedReference.length; index++) { + if (offset == 512) { + buffer.put((byte) 255); + offset = 1; + } + buffer.put(cachedReference[index]); + offset++; + } + buffer.flip(); + return buffer; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/event/LoginReadEvent.kt b/Server/src/main/core/net/event/LoginReadEvent.kt new file mode 100644 index 0000000..fb713b1 --- /dev/null +++ b/Server/src/main/core/net/event/LoginReadEvent.kt @@ -0,0 +1,42 @@ +package core.net.event + +import core.game.node.entity.player.info.ClientInfo +import core.game.node.entity.player.info.PlayerDetails +import core.net.IoReadEvent +import core.net.IoSession +import core.auth.AuthResponse +import core.game.world.GameWorld +import core.net.packet.`in`.Login +import java.nio.ByteBuffer + +/** + * Handles login reading events. + * @author Ceikry + */ +class LoginReadEvent(session: IoSession?, buffer: ByteBuffer?) : IoReadEvent(session, buffer) { + override fun read(session: IoSession, buffer: ByteBuffer) { + try { + val (response, info) = Login.decodeFromBuffer(buffer) + if (response != AuthResponse.Success || info == null) { + session.write(response) + return + } + val (authResponse, accountInfo) = GameWorld.authenticator.checkLogin(info.username, info.password) + + if (authResponse != AuthResponse.Success || accountInfo == null) { + session.write(authResponse) + return + } + val details = PlayerDetails(info.username) + details.accountInfo = accountInfo + details.communication.parse(accountInfo) + session.clientInfo = ClientInfo(info.displayMode, info.windowMode, info.screenWidth, info.screenHeight) + session.isaacPair = info.isaacPair + session.associatedUsername = info.username + Login.proceedWith(session, details, info.opcode) + } catch (e: Exception) { + e.printStackTrace() + session.write(AuthResponse.UnexpectedError) + } + } +} \ No newline at end of file diff --git a/Server/src/main/core/net/event/LoginWriteEvent.java b/Server/src/main/core/net/event/LoginWriteEvent.java new file mode 100644 index 0000000..6da3a9a --- /dev/null +++ b/Server/src/main/core/net/event/LoginWriteEvent.java @@ -0,0 +1,75 @@ +package core.net.event; + +import core.game.node.entity.player.Player; +import core.game.node.entity.player.info.login.Response; +import core.net.EventProducer; +import core.net.IoSession; +import core.net.IoWriteEvent; +import core.net.producer.GameEventProducer; +import core.auth.AuthResponse; + +import java.nio.ByteBuffer; + +/** + * Handles login writing events. + * @author Emperor + */ +public final class LoginWriteEvent extends IoWriteEvent { + + /** + * The game event producer. + */ + private static final EventProducer GAME_PRODUCER = new GameEventProducer(); + + /** + * Constructs a new {@code LoginWriteEvent}. + * @param session The session. + * @param context The event context. + */ + public LoginWriteEvent(IoSession session, Object context) { + super(session, context); + } + + @Override + public void write(IoSession session, Object context) { + AuthResponse response = (AuthResponse) context; + ByteBuffer buffer = ByteBuffer.allocate(500); + buffer.put((byte) response.ordinal()); + switch (response.ordinal()) { + case 2: //successful login + buffer.put(getWorldResponse(session)); + session.setProducer(GAME_PRODUCER); + break; + //Could add a case here to auto-restart the server in case the login server goes offline (case 8) + //Possibly a risk for malicious attacks though + case 21: //Moving world + buffer.put((byte) session.getServerKey()); + break; + } + buffer.flip(); + session.queue(buffer); + } + + /** + * Gets the world response buffer. + * @param session The session. + * @return The buffer. + */ + private static ByteBuffer getWorldResponse(IoSession session) { + ByteBuffer buffer = ByteBuffer.allocate(150); + Player player = session.getPlayer(); + buffer.put((byte) player.getDetails().getRights().ordinal()); + buffer.put((byte) 0); + buffer.put((byte) 0); + buffer.put((byte) 0); + buffer.put((byte) 1); + buffer.put((byte) 0); + buffer.put((byte) 0); + buffer.putShort((short) player.getIndex()); + buffer.put((byte) (1)); // Enable all G.E boxes + buffer.put((byte) 1); + buffer.flip(); + return buffer; + + } +} \ No newline at end of file diff --git a/Server/src/main/core/net/event/MSHSReadEvent.java b/Server/src/main/core/net/event/MSHSReadEvent.java new file mode 100644 index 0000000..210cd09 --- /dev/null +++ b/Server/src/main/core/net/event/MSHSReadEvent.java @@ -0,0 +1,39 @@ +package core.net.event; + +import core.net.EventProducer; +import core.net.IoReadEvent; +import core.net.IoSession; +import core.net.producer.RegistryEventProducer; + +import java.nio.ByteBuffer; + +/** + * Handles the management server handshake read events. + * @author Emperor + */ +public final class MSHSReadEvent extends IoReadEvent { + + /** + * The event producer. + */ + private static final EventProducer REGISTRY_PRODUCER = new RegistryEventProducer(); + + /** + * Constructs a new {@code MSHSReadEvent} {@Code Object} + * @param session The session. + * @param buffer The buffer to read. + */ + public MSHSReadEvent(IoSession session, ByteBuffer buffer) { + super(session, buffer); + } + + @Override + public void read(IoSession session, ByteBuffer buffer) { + int opcode = buffer.get() & 0xFF; + if (opcode == 14) { + session.setProducer(REGISTRY_PRODUCER); + session.write(true); + } + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/event/MSHSWriteEvent.java b/Server/src/main/core/net/event/MSHSWriteEvent.java new file mode 100644 index 0000000..988bb49 --- /dev/null +++ b/Server/src/main/core/net/event/MSHSWriteEvent.java @@ -0,0 +1,33 @@ +package core.net.event; + +import core.cache.misc.buffer.ByteBufferUtils; +import core.net.IoSession; +import core.net.IoWriteEvent; +import core.ServerConstants; + +import java.nio.ByteBuffer; + +/** + * Handles the management server handshake write event. + * @author Emperor + */ +public final class MSHSWriteEvent extends IoWriteEvent { + + /** + * Constructs a new {@code MSHSWriteEvent} {@code Object} + * @param session The session. + * @param context The context. + */ + public MSHSWriteEvent(IoSession session, Object context) { + super(session, context); + } + + @Override + public void write(IoSession session, Object context) { + ByteBuffer buffer = ByteBuffer.allocate(2 + ServerConstants.MS_SECRET_KEY.length()); + buffer.put((byte) 88); + ByteBufferUtils.putString(ServerConstants.MS_SECRET_KEY, buffer); + session.queue((ByteBuffer) buffer.flip()); + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/event/MSReadEvent.java b/Server/src/main/core/net/event/MSReadEvent.java new file mode 100644 index 0000000..5e12d69 --- /dev/null +++ b/Server/src/main/core/net/event/MSReadEvent.java @@ -0,0 +1,94 @@ +package core.net.event; + +import core.tools.Log; +import core.tools.SystemLogger; +import core.net.IoReadEvent; +import core.net.IoSession; + +import java.nio.ByteBuffer; + +import static core.api.ContentAPIKt.log; + +/** + * Handles reading Management server packets. + * @author Emperor + */ +public final class MSReadEvent extends IoReadEvent { + + /** + * The packet sizes. + */ + private static final int[] PACKET_SIZE = { -1, -1, -1, -2, -1, -1, -2, -1, -2, -1, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; + + /** + * Constructs a new {@code MSReadEvent} {@code Object} + * @param session The I/O session. + * @param buffer The buffer to read from. + */ + public MSReadEvent(IoSession session, ByteBuffer buffer) { + super(session, buffer); + } + + @Override + public void read(IoSession session, ByteBuffer buffer) { + int last = -1; + while (buffer.hasRemaining()) { + int opcode = buffer.get() & 0xFF; + if (opcode >= PACKET_SIZE.length) { + break; + } + int header = PACKET_SIZE[opcode]; + int size = header; + if (header < 0) { + size = getPacketSize(buffer, opcode, header, last); + } + if (size == -1) { + break; + } + if (buffer.remaining() < size) { + switch (header) { + case -2: + queueBuffer(opcode, size >> 8, size); + break; + case -1: + queueBuffer(opcode, size); + break; + default: + queueBuffer(opcode); + break; + } + break; + } + byte[] data = new byte[size]; + buffer.get(data); + last = opcode; + } + } + + /** + * Gets the packet size for the given opcode. + * @param buffer The buffer. + * @param opcode The opcode. + * @param header The packet header. + * @param last The last opcode. + * @return The packet size. + */ + private int getPacketSize(ByteBuffer buffer, int opcode, int header, int last) { + if (header == -1) { + if (buffer.remaining() < 1) { + queueBuffer(opcode); + return -1; + } + return buffer.get() & 0xFF; + } + if (header == -2) { + if (buffer.remaining() < 2) { + queueBuffer(opcode); + return -1; + } + return buffer.getShort() & 0xFFFF; + } + return -1; + } + +} diff --git a/Server/src/main/core/net/event/MSWriteEvent.java b/Server/src/main/core/net/event/MSWriteEvent.java new file mode 100644 index 0000000..1f6dfc6 --- /dev/null +++ b/Server/src/main/core/net/event/MSWriteEvent.java @@ -0,0 +1,44 @@ +package core.net.event; + +import core.net.IoSession; +import core.net.IoWriteEvent; +import core.net.packet.IoBuffer; + +import java.nio.ByteBuffer; + +/** + * Handles management server write events. + * @author Emperor + */ +public final class MSWriteEvent extends IoWriteEvent { + + /** + * Constructs a new {@code MSWriteEvent} {@code Object} + * @param session The I/O session. + * @param context The packet context. + */ + public MSWriteEvent(IoSession session, Object context) { + super(session, context); + } + + @Override + public void write(IoSession session, Object context) { + IoBuffer b = (IoBuffer) context; + int size = b.toByteBuffer().position(); + ByteBuffer buffer = ByteBuffer.allocate(1 + size + b.getHeader().ordinal()); + buffer.put((byte) b.opcode()); + switch (b.getHeader()) { + case NORMAL: + break; + case BYTE: + buffer.put((byte) size); + break; + case SHORT: + buffer.putShort((short) size); + break; + } + buffer.put((ByteBuffer) b.toByteBuffer().flip()); + session.queue((ByteBuffer) buffer.flip()); + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/event/RegistryReadEvent.java b/Server/src/main/core/net/event/RegistryReadEvent.java new file mode 100644 index 0000000..bfbedd6 --- /dev/null +++ b/Server/src/main/core/net/event/RegistryReadEvent.java @@ -0,0 +1,58 @@ +package core.net.event; + +import core.tools.Log; +import core.tools.SystemLogger; +import core.game.world.GameWorld; +import core.net.IoReadEvent; +import core.net.IoSession; +import core.net.amsc.ManagementServerState; +import core.net.amsc.WorldCommunicator; +import core.net.producer.MSEventProducer; + +import java.nio.ByteBuffer; + +import static core.api.ContentAPIKt.log; + +/** + * Handles world registry read events. + * @author Emperor + */ +public final class RegistryReadEvent extends IoReadEvent { + + /** + * The event producer. + */ + private static final MSEventProducer PRODUCER = new MSEventProducer(); + + /** + * Constructs a new {@code RegistryReadEvent} {@code Object}. + * @param session The session. + * @param buffer The buffer to read. + */ + public RegistryReadEvent(IoSession session, ByteBuffer buffer) { + super(session, buffer); + } + + @Override + public void read(IoSession session, ByteBuffer buffer) { + int opcode = buffer.get() & 0xFF; + switch (opcode) { + case 0: + WorldCommunicator.setState(ManagementServerState.NOT_AVAILABLE); + log(this.getClass(), Log.ERR, "Failed registering world to AMS - [id=" + GameWorld.getSettings().getWorldId() + ", cause=World id out of bounds]!"); + break; + case 1: + session.setProducer(PRODUCER); + WorldCommunicator.setState(ManagementServerState.AVAILABLE); + break; + case 2: + case 3: + WorldCommunicator.setState(ManagementServerState.NOT_AVAILABLE); + break; + default: + + break; + } + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/event/RegistryWriteEvent.java b/Server/src/main/core/net/event/RegistryWriteEvent.java new file mode 100644 index 0000000..6e94e58 --- /dev/null +++ b/Server/src/main/core/net/event/RegistryWriteEvent.java @@ -0,0 +1,46 @@ +package core.net.event; + +import core.cache.misc.buffer.ByteBufferUtils; +import core.game.world.GameWorld; +import core.net.Constants; +import core.net.IoSession; +import core.net.IoWriteEvent; + +import java.nio.ByteBuffer; + +/** + * Handles game world registry writing events. + * @author Emperor + */ +public final class RegistryWriteEvent extends IoWriteEvent { + + /** + * The string check. + */ + private static final String CHECK = "12x4578f5g45hrdjiofed59898"; + + /** + * Constructs a new {@code RegistryWriteEvent} {@code Object}. + * @param session The I/O session. + * @param context The writing context. + */ + public RegistryWriteEvent(IoSession session, Object context) { + super(session, context); + } + + @Override + public void write(IoSession session, Object context) { + ByteBuffer buffer = ByteBuffer.allocate(128); + buffer.put((byte) GameWorld.getSettings().getWorldId()); + buffer.putInt(Constants.REVISION); + buffer.put((byte) GameWorld.getSettings().getCountryIndex()); + buffer.put((byte) (GameWorld.getSettings().isMembers() ? 1 : 0)); + buffer.put((byte) (GameWorld.getSettings().isPvp() ? 1 : 0)); + buffer.put((byte) (GameWorld.getSettings().isQuickChat() ? 1 : 0)); + buffer.put((byte) (GameWorld.getSettings().isLootshare() ? 1 : 0)); + ByteBufferUtils.putString(GameWorld.getSettings().getActivity(), buffer); + buffer.put(CHECK.getBytes()); + session.queue((ByteBuffer) buffer.flip()); + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/lobby/WorldDefinition.java b/Server/src/main/core/net/lobby/WorldDefinition.java new file mode 100644 index 0000000..92baf06 --- /dev/null +++ b/Server/src/main/core/net/lobby/WorldDefinition.java @@ -0,0 +1,149 @@ +package core.net.lobby; + +import core.game.world.GameWorld; +import core.game.world.repository.Repository; + +/** + * Represents a world's definition. + * @author Dementhium development team. + * + */ +public class WorldDefinition { + + /** + * The activity for this world. + */ + private final String activity; + + /** + * The coutry flag. + */ + private final int country; + + /** + * If the world is members. + */ + private final int flag; + + /** + * The ip-address for this world. + */ + private final String ip; + + /** + * The location. + */ + private final int location; + + /** + * The region. + */ + private final String region; + + /** + * The world's id. + */ + private final int worldId; + + /** + * The amount of players in this world. + */ + private int players; + + /** + * Constructs a new {@code WorldDefinition} {@code Object}. + * @param worldId The world's id. + * @param location The location. + * @param flag If the world is members. + * @param activity The activity for this world. + * @param ip The IP-address. + * @param region The region. + * @param country The country flag. + */ + public WorldDefinition(int worldId, int location, int flag, String activity, String ip, String region, int country) { + this.worldId = worldId; + this.location = location; + this.flag = flag; + this.activity = activity; + this.ip = ip; + this.region = region; + this.country = country; + } + + /** + * @return the activity + */ + public String getActivity() { + return activity; + } + + /** + * @return the country + */ + public int getCountry() { + return country; + } + + /** + * @return the flag + */ + public int getFlag() { + return flag; + } + + /** + * @return the ip + */ + public String getIp() { + return ip; + } + + /** + * @return the location + */ + public int getLocation() { + return location; + } + + /** + * @return the region + */ + public String getRegion() { + return region; + } + + /** + * @return the worldId + */ + public int getWorldId() { + return worldId; + } + + /** + * Gets the player count. + * @return The player count. + */ + public int getPlayerCount() { + if (worldId == GameWorld.getSettings().getWorldId()) { + return Repository.getPlayers().size(); + } + return players; + } + + /** + * Gets the players. + * @return the players + */ + public int getPlayers() { + return players; + } + + /** + * Sets the baplayers. + * @param players the players to set. + */ + public void setPlayers(int players) { + this.players = players; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/lobby/WorldList.java b/Server/src/main/core/net/lobby/WorldList.java new file mode 100644 index 0000000..c7d24f3 --- /dev/null +++ b/Server/src/main/core/net/lobby/WorldList.java @@ -0,0 +1,214 @@ +package core.net.lobby; + +import core.game.world.GameWorld; +import core.net.IoSession; +import core.net.packet.IoBuffer; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.List; + +/** + * Handles the world list. + * @author Emperor + * + */ +public final class WorldList { + + /** + * The value for Australia. + */ + public static final int COUNTRY_AUSTRALIA = 16; + + /** + * The value for Belgium. + */ + public static final int COUNTRY_BELGIUM = 22; + + /** + * The value for Brazil. + */ + public static final int COUNTRY_BRAZIL = 31; + + /** + * The value for Canada. + */ + public static final int COUNTRY_CANADA = 38; + + /** + * The value for Denmark. + */ + public static final int COUNTRY_DENMARK = 58; + + /** + * The value for Finland. + */ + public static final int COUNTRY_FINLAND = 69; + + /** + * The value for Ireland. + */ + public static final int COUNTRY_IRELAND = 101; + + /** + * The value for Mexico. + */ + public static final int COUNTRY_MEXICO = 152; + + /** + * The value for the Netherlands. + */ + public static final int COUNTRY_NETHERLANDS = 161; + + /** + * The value for Norway. + */ + public static final int COUNTRY_NORWAY = 162; + + /** + * The value for Sweden. + */ + public static final int COUNTRY_SWEDEN = 191; + + /** + * The value for the UK. + */ + public static final int COUNTRY_UK = 77; + + /** + * The value for USA. + */ + public static final int COUNTRY_USA = 225; + + /** + * If the world is free to play. + */ + public static final int FLAG_NON_MEMBERS = 0; + + /** + * If the world is a members world. + */ + public static final int FLAG_MEMBERS = 1; + + /** + * If the world is a quick chat world + */ + public static final int FLAG_QUICK_CHAT = 2; + + /** + * If the world is a PvP-world. + */ + public static final int FLAG_PVP = 4; + + /** + * If the world is a lootshare world. + */ + public static final int FLAG_LOOTSHARE = 8; + + /** + * A list holding all the currently loaded worlds. + */ + private static final List WORLD_LIST = new ArrayList(); + + /** + * The last update time stamp (in server ticks). + */ + private static int updateStamp = 0; + + /** + * Populates the world list. + */ + static { + addWorld(new WorldDefinition(1, 0, FLAG_MEMBERS | FLAG_LOOTSHARE, "2009Scape Classic", "127.0.0.1", "Anywhere, USA", COUNTRY_USA)); + } + + /** + * Adds a world to the world list. + * @param def The world definitions. + */ + public static void addWorld(WorldDefinition def) { + WORLD_LIST.add(def); + flagUpdate(); + } + + /** + * Gets the packet to update the world list in the lobby. + * @return The {@code OutgoingPacket} to write. + */ + public static void sendUpdate(IoSession session, int updateStamp) { + ByteBuffer buf = ByteBuffer.allocate(1024); + buf.put((byte) 0); + buf.putShort((short) 0); + buf.put((byte) 1); + IoBuffer buffer = new IoBuffer(); + if (updateStamp != WorldList.updateStamp) { + buf.put((byte) 1); // Indicates an update occured. + putWorldListinfo(buffer); + } else { + buf.put((byte) 0); + } + putPlayerInfo(buffer); + if (buffer.toByteBuffer().position() > 0) { + buf.put((ByteBuffer) buffer.toByteBuffer().flip()); + } + buf.putShort(1, (short) (buf.position() - 3)); + session.queue((ByteBuffer) buf.flip()); + } + + /** + * Adds the world configuration on the packet. + * @param buffer The current packet. + */ + private static void putWorldListinfo(IoBuffer buffer) { + buffer.putSmart(WORLD_LIST.size()); + putCountryInfo(buffer); + buffer.putSmart(0); + buffer.putSmart(WORLD_LIST.size()); + buffer.putSmart(WORLD_LIST.size()); + for (WorldDefinition w : WORLD_LIST) { + buffer.putSmart(w.getWorldId()); + buffer.put(w.getLocation()); + buffer.putInt(w.getFlag()); + buffer.putJagString(w.getActivity()); + buffer.putJagString(w.getIp()); + } + buffer.putInt(updateStamp); + } + + /** + * Adds the world status on the packet. + * @param buffer The current packet. + */ + private static void putPlayerInfo(IoBuffer buffer) { + for (WorldDefinition w : WORLD_LIST) { + buffer.putSmart(w.getWorldId()); + buffer.putShort(w.getPlayerCount()); + } + } + + /** + * Sets the countries for each world. + * @param buffer The current packet. + */ + private static void putCountryInfo(IoBuffer buffer) { + for (WorldDefinition w : WORLD_LIST) { + buffer.putSmart(w.getCountry()); + buffer.putJagString(w.getRegion()); + } + } + + /** + * Gets the updateStamp. + * @return the updateStamp + */ + public static int getUpdateStamp() { + return updateStamp; + } + + /** + * Sets the baupdateStamp. + */ + public static void flagUpdate() { + WorldList.updateStamp = GameWorld.getTicks(); + } +} diff --git a/Server/src/main/core/net/packet/Context.java b/Server/src/main/core/net/packet/Context.java new file mode 100644 index 0000000..d806634 --- /dev/null +++ b/Server/src/main/core/net/packet/Context.java @@ -0,0 +1,17 @@ +package core.net.packet; + +import core.game.node.entity.player.Player; + +/** + * Represents packet context. + * @author Emperor + */ +public interface Context { + + /** + * Gets the node. + * @return The node. + */ + public Player getPlayer(); + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/IncomingPacket.java b/Server/src/main/core/net/packet/IncomingPacket.java new file mode 100644 index 0000000..01564be --- /dev/null +++ b/Server/src/main/core/net/packet/IncomingPacket.java @@ -0,0 +1,20 @@ +package core.net.packet; + +import core.game.node.entity.player.Player; + +/** + * Represents an incoming packet. + * @author Emperor + */ +public interface IncomingPacket { + + /** + * Decodes the incoming packet. + * @param player The player. + * @param opcode The opcode. + * @param buffer The buffer. + * @return The new buffer to send in response. + */ + public void decode(Player player, int opcode, IoBuffer buffer); + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/IoBuffer.java b/Server/src/main/core/net/packet/IoBuffer.java new file mode 100644 index 0000000..2797980 --- /dev/null +++ b/Server/src/main/core/net/packet/IoBuffer.java @@ -0,0 +1,861 @@ +package core.net.packet; + +import core.cache.crypto.ISAACCipher; +import core.cache.misc.buffer.ByteBufferUtils; + +import java.nio.ByteBuffer; + +/** + * Represents the buffer used for reading/writing packets. + * @author Emperor + */ +public class IoBuffer { + + /** + * The bit masks. + */ + private static final int[] BIT_MASK = new int[32]; + + /** + * The packet size. + */ + private int packetSize; + + /** + * The opcode. + */ + private int opcode; + + /** + * The packet header. + */ + private final PacketHeader header; + + /** + * The byte buffer. + */ + private ByteBuffer buf; + + /** + * The bit position. + */ + private int bitPosition = 0; + + /** + * Constructs a new {@code IoBuffer} {@code Object}. + */ + public IoBuffer() { + this(-1, PacketHeader.NORMAL, ByteBuffer.allocate(2048)); + } + + /** + * Constructs a new {@code IoBuffer} {@code Object}. + * @param opcode The opcode. + */ + public IoBuffer(int opcode) { + this(opcode, PacketHeader.NORMAL, ByteBuffer.allocate(2048)); + } + + /** + * Constructs a new {@code IoBuffer} {@code Object}. + * @param opcode The opcode. + * @param header The packet header. + */ + public IoBuffer(int opcode, PacketHeader header) { + this(opcode, header, ByteBuffer.allocate((1 << 16) + 1)); + } + + /** + * Constructs a new {@code IoBuffer} {@code Object}. + * @param opcode The opcode. + * @param header The packet header. + * @param buf The byte buffer. + */ + public IoBuffer(int opcode, PacketHeader header, ByteBuffer buf) { + this.opcode = opcode; + this.header = header; + this.buf = buf; + } + + static { + for (int i = 0; i < 32; i++) { + BIT_MASK[i] = (1 << i) - 1; + } + } + + /** + * @return + */ + public IoBuffer clear() { + buf.clear(); + bitPosition = 0; + return this; + } + + /** + * What follows are put/get methods using authentic naming. + * The older methods are kept for the sake of backwards compatibility within the codebase. + */ + public IoBuffer p1 (int value) { + buf.put((byte) value); + return this; + } + + public IoBuffer p1add (int value) { + buf.put((byte) (value + 128)); + return this; + } + + public IoBuffer p1sub (int value) { + buf.put((byte) (128 - value)); + return this; + } + + public IoBuffer p1neg (int value) { + buf.put ((byte) -value); + return this; + } + + public IoBuffer p2 (int value) { + buf.put((byte) (value >> 8)); + buf.put((byte) value); + return this; + } + + public IoBuffer p2add (int value) { + buf.put((byte) (value >> 8)); + buf.put((byte) (value + 128)); + return this; + } + + public IoBuffer ip2 (int value) { + buf.put((byte) value); + buf.put((byte) (value >> 8)); + return this; + } + + public IoBuffer ip2add (int value) { + buf.put((byte) (value + 128)); + buf.put((byte) (value >> 8)); + return this; + } + + public IoBuffer p3 (int value) { + buf.put((byte) (value >> 16)); + buf.put((byte) (value >> 8)); + buf.put((byte) value); + return this; + } + + public IoBuffer ip3 (int value) { + buf.put((byte) value); + buf.put((byte) (value >> 8)); + buf.put((byte) (value >> 16)); + return this; + } + + public IoBuffer p4 (int value) { + buf.put((byte) (value >> 24)); + buf.put((byte) (value >> 16)); + buf.put((byte) (value >> 8)); + buf.put((byte) value); + return this; + } + + public IoBuffer ip4 (int value) { + buf.put((byte) value); + buf.put((byte) (value >> 8)); + buf.put((byte) (value >> 16)); + buf.put((byte) (value >> 24)); + return this; + } + + public IoBuffer mp4 (int value) { + buf.put((byte) (value >> 16)); + buf.put((byte) (value >> 24)); + buf.put((byte) value); + buf.put((byte) (value >> 8)); + return this; + } + + public IoBuffer imp4 (int value) { + buf.put((byte) (value >> 8)); + buf.put((byte) value); + buf.put((byte) (value >> 24)); + buf.put((byte) (value >> 16)); + return this; + } + + public IoBuffer p8 (long value) { + buf.put((byte) (value >> 56)); + buf.put((byte) (value >> 48)); + buf.put((byte) (value >> 40)); + buf.put((byte) (value >> 32)); + buf.put((byte) (value >> 24)); + buf.put((byte) (value >> 16)); + buf.put((byte) (value >> 8)); + buf.put((byte) value); + return this; + } + + public IoBuffer pVarInt (int value) { + if ((value & 0xffffff80) != 0) { + if ((value & 0xffffc000) != 0) { + if ((value & 0xFFE00000) != 0) { + if ((value & 0xF0000000) != 0) { + this.p1(value >>> 28 | 0x80); + } + this.p1(value >>> 21 | 0x80); + } + this.p1(value >>> 14 | 0x80); + } + this.p1(value >>> 7 | 0x80); + } + return this.p1(value & 0x7F); + } + + public IoBuffer pVarLong (int size, long value) { + int bytes = size - 1; + if (bytes < 0 || bytes > 7) + throw new IllegalArgumentException(); + for (int shift = bytes * 8; shift >= 0; shift -= 8) + this.p1 ((byte) (value >> shift)); + return this; + } + + public IoBuffer psmarts (int value) { + if (value >= 0 && value < 128) + this.p1(value); + else if (value >= 0 && value < 0x8000) + this.p2(value + 0x8000); + else + throw new IllegalArgumentException("smart out of range: $value"); + return this; + } + + public IoBuffer psize (int length) { + buf.put (buf.position() - length - 1, (byte) length); + return this; + } + + public IoBuffer psizeadd (int length) { + buf.put (buf.position() - length - 1, (byte) (length + 128)); + return this; + } + + public int g1() { + return buf.get() & 0xFF; + } + + public int g1b() { return buf.get(); } + + public int g1add() { + return (buf.get() - 128) & 0xFF; + } + + public int g1neg() { + return -(buf.get() & 0xFF); + } + + public int g1sub() { + return (128 - buf.get()) & 0xFF; + } + + public int g2() { + return ((buf.get() & 0xFF) << 8) + (buf.get() & 0xFF); + } + + public int g2add() { + return ((buf.get() & 0xff) << 8) + ((buf.get() - 128) & 0xFF); + } + + public int g2b() { + int value = ((buf.get() & 0xFF) << 8) + (buf.get() & 0xFF); + if (value > 32767) + value -= 0x10000; + return value; + } + + public int ig2() { + return (buf.get() & 0xFF) + ((buf.get() & 0xFF) << 8); + } + + public int ig2add() { + return ((buf.get() - 128) & 0xFF) + ((buf.get() & 0xFF) << 8); + } + + public int g3() { + return ((buf.get() & 0xFF) << 16) + ((buf.get() & 0xFF) << 8) + (buf.get() & 0xFF); + } + + public int ig3() { + return (buf.get() & 0xFF) + ((buf.get() & 0xFF) << 8) + ((buf.get() & 0xFF) << 16); + } + + public int g4() { + return ((buf.get() & 0xFF) << 24) + ((buf.get() & 0xFF) << 16) + ((buf.get() & 0xFF) << 8) + (buf.get() & 0xFF); + } + + public int ig4() { + return (buf.get() & 0xFF) + ((buf.get() & 0xFF) << 8) + ((buf.get() & 0xFF) << 16) + ((buf.get() & 0xFF) << 24); + } + + public int m4() { + return ((buf.get() & 0xFF) << 16) + ((buf.get() & 0xFF) << 24) + (buf.get() & 0xFF) + ((buf.get() & 0xFF) << 8); + } + + public int im4() { + return ((buf.get() & 0xFF) << 8) + (buf.get() & 0xFF) + ((buf.get() & 0xFF) << 24) + ((buf.get() & 0xFF) << 16); + } + + public long g8() { + long low = (long) this.g4() & 0xFFFFFFFFL; + long high = (long) this.g4() & 0xFFFFFFFFL; + return high + (low << 32); + } + + /** + * @param val + * @return + */ + public IoBuffer put(int val) { + buf.put((byte) val); + return this; + } + + /** + * @param datas + * @param offset + * @param len + * @return + */ + public IoBuffer putBytes(byte[] datas, int offset, int len) { + for (int i = offset; i < len; i++) { + put(datas[i]); + } + return this; + } + + public final void getBytes(byte data[], int off, int len) { + for (int k = off; k < len + off; k++) { + data[k] = data[off++]; + } + } + + /** + * @param val + * @return + */ + public IoBuffer putA(int val) { + buf.put((byte) (val + 128)); + return this; + } + + /** + * @param val + * @return + */ + public IoBuffer putC(int val) { + buf.put((byte) -val); + return this; + } + + /** + * @param val + * @return + */ + public IoBuffer putS(int val) { + buf.put((byte) (128 - val)); + return this; + } + + /** + * @param val + * @return + */ + public IoBuffer putTri(int val) { + buf.put((byte) (val >> 16)); + buf.put((byte) (val >> 8)); + buf.put((byte) val); + return this; + } + + /** + * @param val + * @return + */ + public IoBuffer putShort(int val) { + buf.putShort((short) val); + return this; + } + + /** + * @param val + * @return + */ + public IoBuffer putLEShort(int val) { + buf.put((byte) val); + buf.put((byte) (val >> 8)); + return this; + } + + /** + * @param val + * @return + */ + public IoBuffer putShortA(int val) { + buf.put((byte) (val >> 8)); + buf.put((byte) (val + 128)); + return this; + } + + /** + * @param val + * @return + */ + public IoBuffer putLEShortA(int val) { + buf.put((byte) (val + 128)); + buf.put((byte) (val >> 8)); + return this; + } + + /** + * @param val + * @return + */ + public IoBuffer putInt(int val) { + buf.putInt(val); + return this; + } + + /** + * @param val + * @return + */ + public IoBuffer putLEInt(int val) { + buf.put((byte) val); + buf.put((byte) (val >> 8)); + buf.put((byte) (val >> 16)); + buf.put((byte) (val >> 24)); + return this; + } + + /** + * @param val + * @return + */ + public IoBuffer putIntA(int val) { + buf.put((byte) (val >> 8)); + buf.put((byte) val); + buf.put((byte) (val >> 24)); + buf.put((byte) (val >> 16)); + return this; + } + + /** + * @param val + * @return + */ + public IoBuffer putIntB(int val) { + buf.put((byte) (val >> 16)); + buf.put((byte) (val >> 24)); + buf.put((byte) val); + buf.put((byte) (val >> 8)); + return this; + } + + /** + * @param val + * @return + */ + public IoBuffer putLong(long val) { + buf.putLong(val); + return this; + } + + /** + * @param val + * @return + */ + public IoBuffer putSmart(int val) { + if (val > Byte.MAX_VALUE) { + buf.putShort((short) (val + 32768)); + } else { + buf.put((byte) val); + } + return this; + } + + /** + * @param val + * @return + */ + public IoBuffer putIntSmart(int val) { + if (val > Short.MAX_VALUE) { + buf.putInt(val + 32768); + } else { + buf.putShort((short) val); + } + return this; + } + + /** + * @param val + * @return + */ + public IoBuffer putString(String val) { + buf.put(val.getBytes()); + buf.put((byte) 0); + return this; + } + + /** + * @param val + * @return + */ + public IoBuffer putJagString(String val) { + buf.put((byte) 0); + buf.put(val.getBytes()); + buf.put((byte) 0); + return this; + } + + /** + * @param val + * @return + */ + public IoBuffer putJagString2(String val) { + byte[] packed = new byte[256]; + int length = ByteBufferUtils.packGJString2(0, packed, val); + buf.put((byte) 0).put(packed, 0, length).put((byte) 0); + return this; + } + + /** + * @param val + * @return + */ + public IoBuffer put(byte[] val) { + buf.put(val); + return this; + } + + /** + * Puts a byte array as byte A in reverse. + * @param data The data to put. + * @param start The start index. + * @param offset The offset. + */ + public void putReverseA(byte[] data, int start, int offset) { + for (int i = offset + start; i >= start; i--) { + putA(data[i]); + } + } + + /** + * Puts a byte array as byte A in reverse. + * @param data The data to put. + * @param start The start index. + * @param offset The offset. + */ + public void putReverse(byte[] data, int start, int offset) { + for (int i = offset + start; i >= start; i--) { + put(data[i]); + } + } + + /** + * @param numBits + * @param value + * @return + */ + public IoBuffer putBits(int numBits, int value) { + int bytePos = getBitPosition() >> 3; + int bitOffset = 8 - (getBitPosition() & 7); + bitPosition += numBits; + for (; numBits > bitOffset; bitOffset = 8) { + byte b = buf.get(bytePos); + buf.put(bytePos, b &= ~BIT_MASK[bitOffset]); + buf.put(bytePos++, b |= value >> numBits - bitOffset & BIT_MASK[bitOffset]); + numBits -= bitOffset; + } + byte b = buf.get(bytePos); + if (numBits == bitOffset) { + buf.put(bytePos, b &= ~BIT_MASK[bitOffset]); + buf.put(bytePos, b |= value & BIT_MASK[bitOffset]); + } else { + buf.put(bytePos, b &= ~(BIT_MASK[numBits] << bitOffset - numBits)); + buf.put(bytePos, b |= (value & BIT_MASK[numBits]) << bitOffset - numBits); + } + return this; + } + + /** + * @param buffer + * @return + */ + public IoBuffer put(IoBuffer buffer) { + buffer.toByteBuffer().flip(); + buf.put(buffer.toByteBuffer()); + return this; + } + + /** + * @param buffer + * @return + */ + public IoBuffer putA(IoBuffer buffer) { + buffer.toByteBuffer().flip(); + while (buffer.toByteBuffer().hasRemaining()) { + putA(buffer.toByteBuffer().get()); + } + return this; + } + + /** + * @param buffer + * @return + */ + public IoBuffer put(ByteBuffer buffer) { + buf.put(buffer); + return this; + } + + /** + * @return + */ + public IoBuffer setBitAccess() { + bitPosition = buf.position() * 8; + return this; + } + + /** + * @return + */ + public IoBuffer setByteAccess() { + buf.position((getBitPosition() + 7) / 8); + return this; + } + + /** + * @return + */ + public int get() { + return buf.get(); + } + + /** + * @return + */ + public int getA() { + return (buf.get() & 0xFF) - 128; + } + + /** + * @return + */ + public int getC() { + return -buf.get(); + } + + /** + * @return + */ + public int getS() { + return 128 - (buf.get() & 0xFF); + } + + /** + * @return + */ + public int getTri() { + return ((buf.get() << 16) & 0xFF) | ((buf.get() << 8) & 0xFF) | (buf.get() & 0xFF); + } + + /** + * @return + */ + public int getShort() { + return buf.getShort(); + } + + /** + * @return + */ + public int getLEShort() { + return (buf.get() & 0xFF) | ((buf.get() & 0xFF) << 8); + } + + /** + * @return + */ + public int getShortA() { + return ((buf.get() & 0xFF) << 8) | (buf.get() - 128 & 0xFF); + } + + /** + * @return + */ + public int getLEShortA() { + return (buf.get() - 128 & 0xFF) | ((buf.get() & 0xFF) << 8); + } + + /** + * @return + */ + public int getInt() { + return buf.getInt(); + } + + /** + * @return + */ + public int getLEInt() { + return (buf.get() & 0xFF) + ((buf.get() & 0xFF) << 8) + ((buf.get() & 0xFF) << 16) + ((buf.get() & 0xFF) << 24); + } + + /** + * @return + */ + public int getIntA() { + return ((buf.get() & 0xFF) << 8) + (buf.get() & 0xFF) + ((buf.get() & 0xFF) << 24) + ((buf.get() & 0xFF) << 16); + } + + /** + * @return + */ + public int getIntB() { + return ((buf.get() & 0xFF) << 16) + ((buf.get() & 0xFF) << 24) + (buf.get() & 0xFF) + ((buf.get() & 0xFF) << 8); + } + + /** + * @return + */ + public long getLongL() { + long first = getIntB(); + long second = getIntB(); + if (second < 0) + second = second & 0xffffffffL; + return (first << -41780448) + second; + } + + /** + * @return + */ + public long getLong() { + return buf.getLong(); + } + + /** + * @return + */ + public int getSmart() { + int peek = buf.get(buf.position()); + if (peek <= (0xFF & peek)) { + return buf.get() & 0xFF; + } + return (buf.getShort() & 0xFFFF) - 32768; + } + + /** + * @return + */ + public int getIntSmart() { + int peek = buf.getShort(buf.position()); + if (peek <= Short.MAX_VALUE) { + return buf.getShort() & 0xFFFF; + } + return (buf.getInt() & 0xFFFFFFFF) - 32768; + } + + /** + * @return + */ + public String getString() { + return ByteBufferUtils.getString(buf); + } + + /** + * @return + */ + public String getJagString() { + byte b = buf.get(); + if (b == 0) return ""; + return ((char) b) + ByteBufferUtils.getString(buf); + } + + /** + * @param is + * @param offset + * @param length + * @return + */ + public IoBuffer getReverseA(byte[] is, int offset, int length) { + for (int i = (offset + length - 1); i >= offset; i--) { + is[i] = (byte) (buf.get() - 128); + } + return this; + } + + public void cypherOpcode(ISAACCipher cipher){ + this.opcode += (byte)cipher.getNextValue(); + } + + /** + * @return + */ + public ByteBuffer toByteBuffer() { + return buf; + } + + /** + * @return + */ + public int opcode() { + return opcode; + } + + /** + * @return + */ + public int readableBytes() { + return buf.capacity() - buf.remaining(); + } + + /** + * @return + */ + public PacketHeader getHeader() { + return header; + } + + /** + * @return + */ + public byte[] array() { + return buf.array(); + } + + /** + * @return the packetSize. + */ + public int getPacketSize() { + return packetSize; + } + + /** + * @param packetSize the packetSize to set. + */ + public void setPacketSize(int packetSize) { + this.packetSize = packetSize; + } + + /** + * Gets the bitPosition. + * @return The bitPosition. + */ + public int getBitPosition() { + return bitPosition; + } + +} diff --git a/Server/src/main/core/net/packet/OutgoingPacket.java b/Server/src/main/core/net/packet/OutgoingPacket.java new file mode 100644 index 0000000..0c33f8c --- /dev/null +++ b/Server/src/main/core/net/packet/OutgoingPacket.java @@ -0,0 +1,16 @@ +package core.net.packet; + +/** + * Represents an outgoing packet. + * @author Emperor + * @param The context type. + */ +public interface OutgoingPacket { + + /** + * Sends the packet. + * @param context The context. + */ + public void send(Context context); + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/PacketHeader.java b/Server/src/main/core/net/packet/PacketHeader.java new file mode 100644 index 0000000..8ea4278 --- /dev/null +++ b/Server/src/main/core/net/packet/PacketHeader.java @@ -0,0 +1,24 @@ +package core.net.packet; + +/** + * Represents the types of packet headers. + * @author Emperor + */ +public enum PacketHeader { + + /** + * The normal packet header. + */ + NORMAL, + + /** + * The byte packet header. + */ + BYTE, + + /** + * The short packet header. + */ + SHORT; + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/PacketProcessor.kt b/Server/src/main/core/net/packet/PacketProcessor.kt new file mode 100644 index 0000000..d6028d6 --- /dev/null +++ b/Server/src/main/core/net/packet/PacketProcessor.kt @@ -0,0 +1,825 @@ +package core.net.packet + +import core.game.event.ButtonClickEvent +import core.api.getAttribute +import core.api.sendMessage +import core.api.tryPop +import core.cache.def.impl.ItemDefinition +import core.cache.def.impl.NPCDefinition +import core.cache.def.impl.SceneryDefinition +import core.game.container.Container +import core.game.container.impl.BankContainer +import core.game.node.Node +import core.game.node.entity.player.Player +import core.game.node.entity.player.info.Rights +import core.game.node.entity.player.info.login.LoginConfiguration +import core.game.node.entity.player.link.SpellBookManager +import core.game.node.entity.combat.spell.MagicSpell +import content.global.ame.events.maze.MazeInterface +import content.global.skill.summoning.familiar.FamiliarSpecial +import core.game.node.item.GroundItemManager +import core.game.node.item.Item +import core.game.node.scenery.Scenery +import core.game.system.communication.ClanRank +import core.game.system.communication.CommunicationInfo +import core.game.system.task.Pulse +import core.game.world.map.Location +import core.game.world.map.RegionManager +import core.game.world.update.flag.context.ChatMessage +import core.game.world.update.flag.* +import core.net.amsc.MSPacketRepository +import core.net.packet.context.PlayerContext +import core.net.packet.out.ClearMinimapFlag +import org.rs09.consts.Components +import proto.management.ClanMessage +import proto.management.JoinClanRequest +import proto.management.LeaveClanRequest +import core.ServerConstants +import core.game.ge.GrandExchange.Companion.getOfferStats +import core.game.ge.GrandExchange.Companion.getRecommendedPrice +import core.game.ge.GrandExchangeOffer +import core.game.ge.PriceIndex +import content.global.handlers.iface.ge.StockMarket +import content.global.skill.magic.SpellListener +import content.global.skill.magic.SpellListeners +import content.global.skill.magic.SpellUtils +import core.api.log +import core.game.interaction.* +import core.game.node.entity.player.info.LogType +import core.game.node.entity.player.info.PlayerMonitor +import core.tools.SystemLogger +import core.game.system.command.CommandSystem +import core.game.system.communication.GlobalChat +import core.game.world.GameWorld +import core.game.world.repository.Repository +import core.net.packet.`in`.Packet +import core.net.packet.`in`.RunScript +import core.tools.Log +import core.worker.ManagementEvents +import core.api.utils.Vector +import java.io.PrintWriter +import java.io.StringWriter +import java.lang.Math.min +import java.util.* + +object PacketProcessor { + val queue = LinkedList() + + @JvmStatic fun enqueue(pkt: Packet) { + queue.addLast(pkt) + } + + @JvmStatic fun processQueue() { + var countThisCycle = queue.size + val sw = StringWriter() + val pw = PrintWriter(sw) + var pkt: Packet + while (countThisCycle-- > 0) { + pkt = queue.tryPop(Packet.NoProcess()) ?: return + if (pkt is Packet.NoProcess) { + queue.clear() + return + } + try { + process(pkt) + } catch (e: Exception) { + e.printStackTrace(pw) + log(this::class.java, Log.ERR, "Error Processing ${pkt::class.java.simpleName}: $sw") + } + } + } + + private fun process(pkt: Packet) { + when (pkt) { + is Packet.ItemAction -> processItemAction(pkt) + is Packet.NpcAction -> processNpcAction(pkt) + is Packet.SceneryAction -> processSceneryAction(pkt) + is Packet.PlayerAction -> processPlayerAction(pkt) + is Packet.GroundItemAction -> processGroundItemAction(pkt) + is Packet.UseWithNpc, + is Packet.UseWithItem, + is Packet.UseWithScenery, + is Packet.UseWithGroundItem, + is Packet.UseWithPlayer -> processUseWith(pkt) + is Packet.IfAction -> processIfAction(pkt) + is Packet.CloseIface -> processCloseIface(pkt) + is Packet.WorldspaceWalk, + is Packet.MinimapWalk, + is Packet.InteractWalk -> processWalkPacket(pkt) + is Packet.AddFriend -> CommunicationInfo.add(pkt.player, pkt.username) + is Packet.RemoveFriend -> CommunicationInfo.remove(pkt.player, pkt.username, false) + is Packet.AddIgnore -> CommunicationInfo.block(pkt.player, pkt.username) + is Packet.RemoveIgnore -> CommunicationInfo.remove(pkt.player, pkt.username, true) + is Packet.ComponentItemAction, + is Packet.ComponentPlayerAction, + is Packet.ComponentNpcAction, + is Packet.ComponentSceneryAction, + is Packet.ComponentGroundItemAction -> processComponentUseWith(pkt) + is Packet.SlotSwitchSingleComponent, + is Packet.SlotSwitchMultiComponent -> processSlotSwitch(pkt) + is Packet.TrackingMouseClick, + is Packet.TrackingAfkTimeout, + is Packet.TrackingFocus, + is Packet.TrackingCameraPos, + is Packet.TrackingDisplayUpdate -> processTrackingPacket(pkt) + is Packet.PlayerPrefsUpdate -> {/*TODO implement something that cares about this */} + is Packet.Ping -> pkt.player.session.lastPing = System.currentTimeMillis() + is Packet.JoinClan -> { + if (pkt.clanName.isEmpty() && pkt.player.communication.currentClan.isNotEmpty()) { + val builder = LeaveClanRequest.newBuilder() + builder.clanName = pkt.player.communication.currentClan + builder.username = pkt.player.name + ManagementEvents.publish(builder.build()) + return + } + sendMessage(pkt.player, "Attempting to join channel....:clan:") + val builder = JoinClanRequest.newBuilder() + builder.clanName = pkt.clanName + builder.username = pkt.player.name + ManagementEvents.publish(builder.build()) + } + is Packet.SetClanRank -> { + CommunicationInfo.updateClanRank(pkt.player, pkt.username, ClanRank.values()[pkt.rank + 1]) + } + is Packet.KickFromClan -> { + val clan = pkt.player.communication.clan ?: return + val target = Repository.getPlayerByName(pkt.username) ?: return + clan.kick(pkt.player, target) + } + is Packet.QuickChat -> QCRepository.sendQC(pkt.player, pkt.multiplier, pkt.offset, pkt.type, pkt.indexA, pkt.indexB, pkt.forClan) + is Packet.InputPromptResponse -> { + val script: ((Any) -> Boolean) = pkt.player.getAttribute<((Any) -> Boolean)?>("runscript", null) ?: return + if (pkt.player.locks.isInteractionLocked) + return + try { + RunScript.processInput(pkt.player, pkt.response, script) + } finally { + pkt.player.removeAttribute("parseamount") + pkt.player.removeAttribute("runscript") + } + } + is Packet.ReportAbuse -> { + if (pkt.target.isNullOrEmpty()) { + sendMessage(pkt.player, "Invalid player name.") + return + } + if (!GameWorld.accountStorage.checkUsernameTaken(pkt.target.lowercase())) { + sendMessage(pkt.player, "Invalid player name.") + return + } + if (pkt.target.equals(pkt.player.username, true)){ + pkt.player.sendMessage("You can't report yourself!") + } + core.game.global.report.AbuseReport( + pkt.player.name, + pkt.target, + core.game.global.report.Rule.forId(pkt.rule) + ).construct(pkt.player, pkt.modMute) + } + is Packet.TrackFinished -> { + if (pkt.player.musicPlayer.isLooping) + pkt.player.musicPlayer.replay() + else + pkt.player.musicPlayer.isPlaying = false + } + is Packet.GESetOfferItem -> { + val offer = pkt.player.getAttribute("ge-temp", GrandExchangeOffer()) + val index = pkt.player.getAttribute("ge-index", -1) + offer.itemID = pkt.itemId + offer.sell = false + if (!PriceIndex.canTrade(pkt.itemId)) { + sendMessage(pkt.player, "That item is blacklisted from the grand exchange.") + return + } + offer.player = pkt.player + offer.amount = 1 + offer.offeredValue = getRecommendedPrice(pkt.itemId, false) + offer.index = index + StockMarket.updateVarbits(pkt.player, offer, index, false) + pkt.player.setAttribute("ge-temp", offer) + pkt.player.packetDispatch.sendString(getOfferStats(pkt.itemId, false), 105, 142) + pkt.player.interfaceManager.closeChatbox() + } + is Packet.Command -> { + PlayerMonitor.log(pkt.player, LogType.COMMAND, pkt.commandLine) + CommandSystem.commandSystem.parse(pkt.player, pkt.commandLine) + } + is Packet.ChatMessage -> { + if (pkt.player.details.isMuted) + pkt.player.sendMessage("You have been muted due to breaking a rule.") + else { + if (ServerConstants.ENABLE_GLOBALCHAT && pkt.message.startsWith("//")) { + if (getAttribute(pkt.player, GlobalChat.ATTR_GLOBAL_MUTE, false)) + return + + val messages = splitChatMessage(pkt.message.substring(2), pkt.player.name.length + 3, false) + for (message in messages) { + if (message.isNotBlank()) + GlobalChat.process(pkt.player.username, message, Rights.getChatIcon(pkt.player)) + } + return + } + else if (pkt.message.startsWith("/") && pkt.player.communication.clan != null) { + val messages = splitChatMessage(pkt.message.substring(1), pkt.player.communication.clan.name.length + pkt.player.name.length, pkt.player.details.rights.ordinal != 0) + for (message in messages) { + if (message.isBlank()) continue + val builder = ClanMessage.newBuilder() + builder.sender = pkt.player.name + builder.clanName = pkt.player.communication.clan.owner.lowercase().replace(" ", "_") + builder.message = message + builder.rank = Rights.getChatIcon(pkt.player) + ManagementEvents.publish(builder.build()) + } + return + } + PlayerMonitor.logChat(pkt.player, "public", pkt.message) + val ctx = ChatMessage(pkt.player, pkt.message, pkt.effects, pkt.message.length) + pkt.player.updateMasks.register(EntityFlag.Chat, ctx) + } + } + is Packet.ChatSetting -> { + MSPacketRepository.sendChatSetting(pkt.player, pkt.public, pkt.private, pkt.trade) + pkt.player.settings.updateChatSettings(pkt.public, pkt.private, pkt.trade) + } + is Packet.PrivateMessage -> { + if (pkt.player.details.isMuted) + pkt.player.sendMessage("You have been muted due to breaking a rule.") + else + CommunicationInfo.sendMessage(pkt.player, pkt.username, pkt.message) + PlayerMonitor.logPrivateChat(pkt.player, pkt.username, pkt.message) + } + is Packet.PacketCountUpdate -> { + val final = pkt.count - pkt.player.interfaceManager.getPacketCount(0) + pkt.player.interfaceManager.getPacketCount(final) + } + is Packet.ContinueOption -> { + val player = pkt.player + player.debug("[CONTINUE OPT]----------") + player.debug("Iface: ${pkt.iface}") + player.debug("Child: ${pkt.child}") + player.debug("Slot: ${pkt.slot}") + player.debug("------------------------") + if (player.dialogueInterpreter.dialogue == null) { + player.interfaceManager.closeChatbox() + player.dialogueInterpreter.actions.removeFirstOrNull()?.handle(player, pkt.child) + val component = player.interfaceManager.getComponent(pkt.iface) ?: return + if (!InterfaceListeners.run(player, component, pkt.opcode, pkt.child, pkt.slot, -1)) + component.plugin?.handle(player, component, pkt.opcode, pkt.child, pkt.slot, -1) + return + } + player.dialogueInterpreter.handle(pkt.iface, pkt.child) + } + is Packet.ItemExamine -> { + val def = ItemDefinition.forId(pkt.id) ?: return + pkt.player.debug("[ITEM] ID: ${pkt.id} Value: ${def.value} Model: ${def.interfaceModelId}") + pkt.player.sendMessage(def.examine) + } + is Packet.SceneryExamine -> { + val def = SceneryDefinition.forId(pkt.id) ?: return + pkt.player.debug("[SCENERY]---------------------") + pkt.player.debug("ID: ${pkt.id}") + if (def.configFile != null) + pkt.player.debug("Varbit: ${def.configFile.id}") + pkt.player.debug("------------------------------") + pkt.player.sendMessage(def.examine) + } + is Packet.NpcExamine -> { + val def = NPCDefinition.forId(pkt.id) + pkt.player.debug("[NPC]-------------------------") + pkt.player.debug("ID: ${pkt.id}") + if (def.configFileId != -1) + pkt.player.debug("Varbit: ${def.configFileId}") + pkt.player.debug("------------------------------") + pkt.player.sendMessage(def.examine) + } + + + else -> log(this::class.java, Log.WARN, "Unprocessed Packet: ${pkt::class.java.simpleName}") + } + } + + private fun processTrackingPacket(pkt: Packet) { + when(pkt) { + is Packet.TrackingFocus -> {} + is Packet.TrackingDisplayUpdate -> { + pkt.player.session.clientInfo.screenWidth = pkt.screenWidth + pkt.player.session.clientInfo.screenHeight = pkt.screenHeight + pkt.player.session.clientInfo.displayMode = pkt.displayMode + pkt.player.interfaceManager.switchWindowMode(pkt.windowMode) + } + is Packet.TrackingAfkTimeout -> { + if (pkt.player.details.rights != Rights.ADMINISTRATOR) + { + pkt.player.isAfkLogout = true + pkt.player.packetDispatch.sendLogout() + } + } + is Packet.TrackingCameraPos -> { + //TODO Refactor the player monitor to be actually useful and log this + } + is Packet.TrackingMouseClick -> { + //TODO see above todo + + } + else -> {} + } + } + + private fun processSlotSwitch(pkt: Packet) { + //TODO refactor this to function as callbacks to InterfaceListeners, e.g. onSlotSwitch + //TODO See above TODO, I hate Arios. This was hardcoded in the packet decoder. + if (pkt is Packet.SlotSwitchMultiComponent) { + if (pkt.destIface == 762) { + if (pkt.destChild == 73) { + val container = pkt.player.bank + switchItem(pkt.sourceSlot, pkt.destSlot, container, pkt.player.bank.isInsertItems, pkt.player) + } else { + val tabIndex = BankContainer.getArrayIndex(pkt.destChild) + if (tabIndex > -1) { + val secondSlot = + if (tabIndex == 10) pkt.player.bank.freeSlot() else pkt.player.bank.tabStartSlot[tabIndex] + pkt.player.bank.getItemsInTab(tabIndex) + val inSlot: Item = pkt.player.bank.get(pkt.sourceSlot) + if (secondSlot == -1 && pkt.player.bank.remove(inSlot)) { + pkt.player.bank.add(inSlot) + return + } + val childId = pkt.player.bank.getTabByItemSlot(pkt.sourceSlot) + if (secondSlot > pkt.sourceSlot) { + pkt.player.bank.insert(pkt.sourceSlot, secondSlot - 1) + } else if (pkt.sourceSlot > secondSlot) { + pkt.player.bank.insert(pkt.sourceSlot, secondSlot) + } + pkt.player.bank.increaseTabStartSlots(tabIndex) + pkt.player.bank.decreaseTabStartSlots(childId) + pkt.player.bank.setTabConfigurations() + return + } + } + return + } else { + switchItem(pkt.sourceSlot, pkt.destSlot, pkt.player.inventory, false, pkt.player) + } + } + else if (pkt is Packet.SlotSwitchSingleComponent) { + val container = if (pkt.iface == 762) pkt.player.bank else pkt.player.inventory + switchItem(pkt.sourceSlot, pkt.destSlot, container, pkt.isInsert, pkt.player) + } + } + + private fun processComponentUseWith(pkt: Packet) { + val iface: Int + val child: Int + val target: Node + val targetId: Int + val player: Player + val type: Int + if (pkt is Packet.ComponentGroundItemAction) { + player = pkt.player + child = pkt.child + iface = pkt.iface + target = GroundItemManager.get(pkt.itemId, Location.create(pkt.x, pkt.y, player.location.z), player) ?: return sendClearMinimap(player).also { sendMessage(player, "Too late!") } + targetId = pkt.itemId + type = SpellListener.GROUND_ITEM + } + else if (pkt is Packet.ComponentPlayerAction) { + player = pkt.player + child = pkt.child + iface = pkt.iface + target = Repository.players[pkt.otherIndex] ?: return sendClearMinimap(player) + targetId = target.id + type = SpellListener.PLAYER + } + else if (pkt is Packet.ComponentSceneryAction) { + player = pkt.player + child = pkt.child + iface = pkt.iface + target = RegionManager.getObject(player.location.z, pkt.x, pkt.y) ?: return sendClearMinimap(player) + targetId = pkt.sceneryId + type = SpellListener.OBJECT + } + else if (pkt is Packet.ComponentNpcAction) { + if (pkt.npcIndex !in 1 until ServerConstants.MAX_NPCS) + return sendClearMinimap(pkt.player) + player = pkt.player + child = pkt.child + iface = pkt.iface + target = Repository.npcs[pkt.npcIndex] ?: return sendClearMinimap(player) + targetId = target.id + type = SpellListener.NPC + } + else { + if (pkt !is Packet.ComponentItemAction) return + player = pkt.player + child = pkt.child + iface = pkt.iface + target = player.inventory[pkt.slot] ?: return + targetId = pkt.itemId + type = SpellListener.ITEM + } + + if (targetId != target.id) + return + if (player.getAttribute("magic:delay", -1) > GameWorld.ticks) + return + val book = SpellUtils.getBookFromInterface(iface) + if (book != "none") + SpellListeners.run(child, type, book, player, target) + when (iface) { + 430,192,193 -> MagicSpell.castSpell(player, SpellBookManager.SpellBook.forInterface(iface), child, target) + 662 -> { + if (player.familiarManager.hasFamiliar()) + player.familiarManager.familiar.executeSpecialMove(FamiliarSpecial(target, iface, child, target as? Item)) + else + player.sendMessage("You don't have a familiar.") + } + } + } + + private fun processWalkPacket(pkt: Packet) { + val player: Player + val x: Int + val y: Int + val isRunning: Boolean + if (pkt is Packet.WorldspaceWalk) { + player = pkt.player + x = pkt.destX + y = pkt.destY + isRunning = pkt.isRun + } + else if (pkt is Packet.InteractWalk) { + player = pkt.player + x = pkt.destX + y = pkt.destY + isRunning = pkt.isRun + } + else { + if (pkt !is Packet.MinimapWalk) return + player = pkt.player + x = pkt.destX + y = pkt.destY + isRunning = pkt.isRun + //there's more data in this packet, we're just not using it + } + + var loc = Location.create(x,y,player.location.z) + var canWalk = !player.locks.isMovementLocked + + val vec = Vector.betweenLocs(player.location, loc) + if (vec.magnitude() > ServerConstants.MAX_PATHFIND_DISTANCE) { + val newVec = vec.normalized() * (ServerConstants.MAX_PATHFIND_DISTANCE - 1) + loc = player.location.transform(newVec) + } + + if (canWalk && player.interfaceManager.isOpened && !player.interfaceManager.opened.definition.isWalkable) + canWalk = canWalk && player.interfaceManager.close() + if (canWalk && player.interfaceManager.hasChatbox() && !player.interfaceManager.chatbox.definition.isWalkable) + player.interfaceManager.closeChatbox() + + if (!canWalk || !player.dialogueInterpreter.close()) { + player.debug("[WALK ACTION]-- Action canceled. Either player is locked, interfaces can't close, or distance is beyond server pathfinding limit.") + return sendClearMinimap(player) + } + + if (pkt is Packet.InteractWalk) { + //Arios did this, so we're replicating it for now. Probably wrong. + player.walkingQueue.isRunning = isRunning + return + } + + player.face(null) + player.faceLocation(null) + player.scripts.reset() + + player.pulseManager.run(object : MovementPulse(player, loc, isRunning) { + override fun pulse(): Boolean { + if (isRunning) + player.walkingQueue.isRunning = false + return true + } + }) + } + + private fun processCloseIface(pkt: Packet.CloseIface) { + val player = pkt.player + player.interfaceManager.close() + if (player.getAttribute("logging_in") != null) { + GameWorld.Pulser.submit(object : Pulse() { + override fun pulse(): Boolean { + player.removeAttribute("logging_in") + LoginConfiguration.configureGameWorld(player) + return true + } + }) + } + if (player.getAttribute("worldMap:viewing") != null) { + player.removeAttribute("worldMap:viewing") + player.packetDispatch.sendWindowsPane(if (player.interfaceManager.isResizable) 746 else 548, 2) + player.unlock() + } + } + + private fun processIfAction(pkt: Packet.IfAction) { + val player = pkt.player + player.debug("[IF ACTION]--------------------------") + player.debug("Iface: ${pkt.iface}, Button: ${pkt.child}") + player.debug("Slot: ${pkt.slot}, ItemID: ${pkt.itemId}") + player.debug("RCM Index: ${pkt.optIndex}, Op: ${pkt.opcode}") + player.debug("-------------------------------------") + if (player.dialogueInterpreter.dialogue != null && pkt.opcode != 132 && pkt.iface != 64 && pkt.iface != 746) + player.dialogueInterpreter.close() + if (player.locks.isComponentLocked) + return + if (player.zoneMonitor.clickButton(pkt.iface, pkt.child, pkt.slot, pkt.itemId, pkt.opcode)) + return + val c = player.interfaceManager.getComponent(pkt.iface) ?: return + if (c.isHidden) + return + val plugin = c.plugin + player.dispatch(ButtonClickEvent(c.id, pkt.child)) + if (!InterfaceListeners.run(player, c, pkt.opcode, pkt.child, pkt.slot, pkt.itemId)) + plugin?.handle(player, c, pkt.opcode, pkt.child, pkt.slot, pkt.itemId) + } + + private fun processUseWith(pkt: Packet) { + val node: Node + var childNode: Node? = null + val item: Item + val itemId: Int + val nodeId: Int + val type: IntType + val player: Player + if (pkt is Packet.UseWithNpc) { + val container = getLikelyContainerForIface(pkt.player, pkt.iface) ?: return sendClearMinimap(pkt.player) + itemId = pkt.itemId + val itemSlot = pkt.slot + item = container[itemSlot] ?: return sendClearMinimap(pkt.player) + node = Repository.npcs[pkt.npcIndex] ?: return sendClearMinimap(pkt.player) + childNode = node.getShownNPC(pkt.player) + nodeId = node.id + type = IntType.NPC + player = pkt.player + } + else if (pkt is Packet.UseWithScenery) { + item = pkt.player.inventory[pkt.slot] ?: return sendClearMinimap(pkt.player) + node = RegionManager.getObject(pkt.player.location.z, pkt.x, pkt.y) ?: return sendClearMinimap(pkt.player) + childNode = node.asScenery().getChild(pkt.player) + itemId = pkt.itemId + nodeId = node.id + type = IntType.SCENERY + player = pkt.player + } + else if (pkt is Packet.UseWithItem) { + val containerUsed = getLikelyContainerForIface(pkt.player, pkt.usedIface) ?: return + val containerWith = getLikelyContainerForIface(pkt.player, pkt.usedWithIface) ?: return + item = containerUsed[pkt.usedSlot] ?: return + node = containerWith[pkt.usedWithSlot] ?: return + itemId = pkt.usedId + nodeId = pkt.usedWithId + type = IntType.ITEM + player = pkt.player + } else if (pkt is Packet.UseWithGroundItem) { + val container = getLikelyContainerForIface(pkt.player, pkt.iface) ?: return + item = container[pkt.slot] ?: return + itemId = pkt.usedId + node = GroundItemManager.get(pkt.withId, Location.create(pkt.x, pkt.y, pkt.player.location.z), pkt.player) ?: return + nodeId = pkt.withId + type = IntType.GROUNDITEM + player = pkt.player + } else { + if (pkt !is Packet.UseWithPlayer) return + val container = getLikelyContainerForIface(pkt.player, pkt.iface) ?: return sendClearMinimap(pkt.player) + item = container[pkt.slot] ?: return sendClearMinimap(pkt.player) + itemId = pkt.itemId + node = Repository.players[pkt.otherIndex] ?: return sendClearMinimap(pkt.player) + type = IntType.PLAYER + nodeId = node.id + player = pkt.player + } + + if (item.id != itemId) + return sendClearMinimap(player) + if (node.id != nodeId) + return sendClearMinimap(player) + + if (player.locks.isInteractionLocked() || player.locks.isMovementLocked()) + return sendClearMinimap(player) + + player.scripts.reset() + if (player.zoneMonitor.useWith(item, node)) + return + if (InteractionListeners.run(item, node, type, player)) + return + if (childNode != null && childNode.id != node.id) { + if (InteractionListeners.run(item, childNode, type, player)) + return + } + val flipped = type == IntType.ITEM && item.id < node.id + val event = if (flipped) + NodeUsageEvent(player, 0, node, item) + else + NodeUsageEvent(player, 0, item, childNode ?: node) + if (PluginInteractionManager.handle(player, event)) + return + UseWithHandler.run(event) + } + + private fun processGroundItemAction(pkt: Packet.GroundItemAction) { + val item = GroundItemManager.get(pkt.id, Location.create(pkt.x, pkt.y, pkt.player.location.z), pkt.player) + val player = pkt.player + player.scripts.reset() + + if (item == null) { + return sendClearMinimap(player) + } + val option = item.interaction[pkt.optIndex] + if (option == null) { + InteractPlugin.handleInvalidInteraction(player, item, Option.NULL) + return sendClearMinimap(player) + } + if (PluginInteractionManager.handle(player, item, option)) + return + if (InteractionListeners.run(item.id, IntType.GROUNDITEM, option.name, player, item)) + return + if (InteractionListeners.run(item.id, IntType.ITEM, option.name, player, item)) + return + item.interaction.handle(player, option) + } + + private fun processPlayerAction(pkt: Packet.PlayerAction) { + val player = pkt.player + if (pkt.otherIndex !in 1 until ServerConstants.MAX_PLAYERS) { + return sendClearMinimap(player) + } + player.scripts.reset() + val other = Repository.players[pkt.otherIndex] + if (other == null || !other.isActive) + return sendClearMinimap(player) + val option = other.interaction[pkt.optIndex] ?: return sendClearMinimap(player) + if (!InteractionListeners.run(-1, IntType.PLAYER, option.name.lowercase(), player, other)) { + other.interaction.handle(player, option) + } + } + + private fun processSceneryAction(pkt: Packet.SceneryAction) { + val player = pkt.player + var scenery = RegionManager.getObject(player.location.z, pkt.x, pkt.y, pkt.id) + var objId = pkt.id + + //what follows is a series of hardcoded crimes against humanity + if (pkt.id == 6898) + scenery = Scenery(6898, Location(3219, 9618)) + if (pkt.id == 6899) + scenery = Scenery(6899, Location(3221, 9618)) + + // Random Event Maze chests are overridden by the walls, which needs to be hacked in. + if ((scenery?.id == 3626 || scenery?.id == 3635) && (objId in 3635..3636)) { + scenery = MazeInterface.overrideScenery(scenery, objId) + } + + // Family crest levers don't have varps associated with them, so their state is validated with attributes + // instead, and they always appear as their down/odd variant in the server's map + if (objId in 2421..2426 && objId % 2 == 0) { + scenery = Scenery(objId - 1, Location(pkt.x, pkt.y, player.location.z)) + objId -= 1 + } + + if (scenery == null || scenery.id != objId || !scenery.isActive) { + player.debug("[SCENERY INTERACT] NULL OR MISMATCH OR INACTIVE") + InteractPlugin.handleInvalidInteraction(player, scenery, Option.NULL) + return sendClearMinimap(player) + } + + val wrapperChild = scenery.getChild(player) + val option = wrapperChild.interaction[pkt.optIndex] + + if (option == null) { + player.debug("[SCENERY INTERACT] NULL OPTION") + InteractPlugin.handleInvalidInteraction(player, scenery, Option.NULL) + return sendClearMinimap(player) + } + + val hasWrapper = wrapperChild.id != scenery.id + + player.debug("[SCENERY INTERACT]------------------------------") + player.debug("ID: ${wrapperChild.id}, Option: ${option.name}[${option.index}]") + player.debug("Loc: ${scenery.location}, Dir: ${scenery.direction}") + if (hasWrapper) { + player.debug("WrapperID: ${scenery.id}, ${scenery.definition.configFile?.let { "Varbit: ${it.id}"} ?: "Varp: ${scenery.definition.configId}"}") + } + player.debug("------------------------------------------------") + + player.scripts.reset() + if (InteractionListeners.run(wrapperChild.id, IntType.SCENERY, option.name, player, wrapperChild)) + return + if (PluginInteractionManager.handle(player, wrapperChild)) + return + wrapperChild.interaction.handle(player, option) + } + + private fun processNpcAction(pkt: Packet.NpcAction) { + if (pkt.npcIndex !in 1 until ServerConstants.MAX_NPCS) + return sendClearMinimap(pkt.player) + val npc = Repository.npcs[pkt.npcIndex] ?: return sendClearMinimap(pkt.player) + + val wrapperChild = npc.getShownNPC(pkt.player) + val option = wrapperChild.interaction[pkt.optIndex] + + if (option == null) { + InteractPlugin.handleInvalidInteraction(pkt.player, npc, Option.NULL) + return sendClearMinimap(pkt.player) + } + + val hasWrapper = wrapperChild.id != npc.id + + pkt.player.debug("[NPC INTERACT]-------------------") + pkt.player.debug("ID: ${wrapperChild.id}, Index: ${pkt.npcIndex}") + pkt.player.debug("Option: ${option.name}[${option.index}]") + pkt.player.debug("SpawnLoc: ${npc.properties.spawnLocation}") + if (hasWrapper) { + pkt.player.debug("WrapperID: ${npc.id}, Varbit: ${npc.definition.configFileId}") + } + pkt.player.debug("---------------------------------") + + pkt.player.scripts.reset() + if (InteractionListeners.run(wrapperChild.id, IntType.NPC,option.name,pkt.player,npc)) + return + if (PluginInteractionManager.handle(pkt.player, wrapperChild, option)) + return + npc.interaction.handle(pkt.player, option) + } + + private fun processItemAction(pkt: Packet.ItemAction) { + val container = getLikelyContainerForIface(pkt.player, pkt.iface) ?: return + if (pkt.slot !in 0 until container.capacity()) + return + val item = container.get(pkt.slot) ?: return + if (item.id != pkt.itemId) + return + val option = item.interaction[pkt.optIndex] ?: return + if (pkt.player.locks.isInteractionLocked) + return + item.interaction.handleItemOption(pkt.player, option, container) + pkt.player.scripts.reset() + pkt.player.debug("[ITEM INTERACT] ID: ${item.id}, Slot: ${pkt.slot}, Opt: ${option.name}") + } + + private fun getLikelyContainerForIface(player: Player, iface: Int) : Container? { + return when (iface) { + Components.INVENTORY_149 -> player.inventory + Components.BANK_V2_MAIN_762 -> player.bank + Components.EQUIP_SCREEN2_667 -> player.equipment + else -> null + } + } + + private fun sendClearMinimap(player: Player) { + PacketRepository.send(ClearMinimapFlag::class.java, PlayerContext(player)) + } + + fun switchItem(slot: Int, secondSlot: Int, container: Container?, insert: Boolean, player: Player) { + if (container == null || slot < 0 || slot >= container.toArray().size || secondSlot < 0 || secondSlot >= container.toArray().size) { + return + } + val item = container[slot] + val second = container[secondSlot] + if (player.interfaceManager.hasChatbox() && !getAttribute(player, "close_c_", false)) { + player.interfaceManager.closeChatbox() + switchItem(secondSlot, slot, container, insert, player) + container.refresh() + return + } + if (item == null) { + return + } + if (!insert) { + container.replace(second, slot, false) + container.replace(item, secondSlot, false) + item.index = secondSlot + if (second != null) { + second.index = slot + } + } else { + container.insert(slot, secondSlot, false) + } + container.refresh() + } + + fun splitChatMessage(message: String, clanLength: Int, rankPresent: Boolean) : ArrayList { + val messages = ArrayList() + + val effectiveCutoff = BASE_CHAT_CUTOFF - (clanLength + if (rankPresent) 9 else 0) + var counter = 0 + for (token in message.split(" ")) { + if (counter + token.length > effectiveCutoff) + break + counter += token.length + 1 + } + messages.add(message.substring(0, min(counter, message.length))) + if (counter < message.length) + messages.add(message.substring(counter, message.length)) + + return messages + } + + const val BASE_CHAT_CUTOFF = 81 +} diff --git a/Server/src/main/core/net/packet/PacketRepository.java b/Server/src/main/core/net/packet/PacketRepository.java new file mode 100644 index 0000000..60c6fdd --- /dev/null +++ b/Server/src/main/core/net/packet/PacketRepository.java @@ -0,0 +1,109 @@ +package core.net.packet; + +import core.net.packet.out.GrandExchangePacket; +import core.net.packet.out.*; +import core.tools.Log; +import core.tools.SystemLogger; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.HashMap; +import java.util.Map; +import core.game.bots.AIPlayer; + +import static core.api.ContentAPIKt.log; + +/** + * The packet repository. + * @author Emperor + */ +public final class PacketRepository { + + /** + * The outgoing packets mapping. + */ + public final static Map, OutgoingPacket> OUTGOING_PACKETS = new HashMap<>(); + + /** + * Populate the mappings. + */ + static { + OUTGOING_PACKETS.put(LoginPacket.class, new LoginPacket()); // + OUTGOING_PACKETS.put(UpdateSceneGraph.class, new UpdateSceneGraph()); // + OUTGOING_PACKETS.put(WindowsPane.class, new WindowsPane()); // + OUTGOING_PACKETS.put(Interface.class, new Interface()); // + OUTGOING_PACKETS.put(SkillLevel.class, new SkillLevel()); // + OUTGOING_PACKETS.put(Config.class, new Config()); // + OUTGOING_PACKETS.put(AccessMask.class, new AccessMask()); // + OUTGOING_PACKETS.put(GameMessage.class, new GameMessage()); // + OUTGOING_PACKETS.put(RunScriptPacket.class, new RunScriptPacket()); // + OUTGOING_PACKETS.put(RunEnergy.class, new RunEnergy()); // + OUTGOING_PACKETS.put(ContainerPacket.class, new ContainerPacket()); // + OUTGOING_PACKETS.put(StringPacket.class, new StringPacket()); // + OUTGOING_PACKETS.put(Logout.class, new Logout()); // + OUTGOING_PACKETS.put(CloseInterface.class, new CloseInterface()); // + OUTGOING_PACKETS.put(AnimateInterface.class, new AnimateInterface()); // + OUTGOING_PACKETS.put(DisplayModel.class, new DisplayModel()); // + OUTGOING_PACKETS.put(InterfaceConfig.class, new InterfaceConfig()); // + OUTGOING_PACKETS.put(PingPacket.class, new PingPacket()); // + OUTGOING_PACKETS.put(UpdateAreaPosition.class, new UpdateAreaPosition()); // + OUTGOING_PACKETS.put(ConstructScenery.class, new ConstructScenery()); // + OUTGOING_PACKETS.put(ClearScenery.class, new ClearScenery()); // + OUTGOING_PACKETS.put(HintIcon.class, new HintIcon()); // + OUTGOING_PACKETS.put(ClearMinimapFlag.class, new ClearMinimapFlag()); // + OUTGOING_PACKETS.put(InteractionOption.class, new InteractionOption()); // + OUTGOING_PACKETS.put(SetWalkOption.class, new SetWalkOption()); // + OUTGOING_PACKETS.put(MinimapState.class, new MinimapState()); // + OUTGOING_PACKETS.put(ConstructGroundItem.class, new ConstructGroundItem()); // + OUTGOING_PACKETS.put(ClearGroundItem.class, new ClearGroundItem()); // + OUTGOING_PACKETS.put(RepositionChild.class, new RepositionChild()); // + OUTGOING_PACKETS.put(PositionedGraphic.class, new PositionedGraphic()); // + OUTGOING_PACKETS.put(SystemUpdatePacket.class, new SystemUpdatePacket()); // + OUTGOING_PACKETS.put(CameraViewPacket.class, new CameraViewPacket()); // + OUTGOING_PACKETS.put(MusicPacket.class, new MusicPacket()); // + OUTGOING_PACKETS.put(AudioPacket.class, new AudioPacket()); // + OUTGOING_PACKETS.put(GrandExchangePacket.class, new GrandExchangePacket()); // + OUTGOING_PACKETS.put(BuildDynamicScene.class, new BuildDynamicScene()); // + OUTGOING_PACKETS.put(AnimateObjectPacket.class, new AnimateObjectPacket()); // + OUTGOING_PACKETS.put(ClearRegionChunk.class, new ClearRegionChunk()); // + OUTGOING_PACKETS.put(ContactPackets.class, new ContactPackets()); // + OUTGOING_PACKETS.put(CommunicationMessage.class, new CommunicationMessage()); // + OUTGOING_PACKETS.put(UpdateClanChat.class, new UpdateClanChat()); // + OUTGOING_PACKETS.put(UpdateGroundItemAmount.class, new UpdateGroundItemAmount()); // + //OUTGOING_PACKETS.put(WeightUpdate.class, new WeightUpdate()); // + OUTGOING_PACKETS.put(UpdateRandomFile.class, new UpdateRandomFile()); // + OUTGOING_PACKETS.put(InstancedLocationUpdate.class, new InstancedLocationUpdate()); // + OUTGOING_PACKETS.put(CSConfigPacket.class, new CSConfigPacket()); // + OUTGOING_PACKETS.put(Varbit.class, new Varbit()); + OUTGOING_PACKETS.put(ResetInterface.class, new ResetInterface()); + OUTGOING_PACKETS.put(VarcUpdate.class, new VarcUpdate()); + OUTGOING_PACKETS.put(InterfaceSetAngle.class, new InterfaceSetAngle()); + } + + /** + * Sends a new packet. + * @param clazz The class of the outgoing packet to send. + * @param context The context. + */ + @SuppressWarnings({ "rawtypes", "unchecked" }) + public static void send(Class clazz, Context context) { + if(context.getPlayer() instanceof AIPlayer) return; + if(context.getPlayer().getSession() == null) return; + OutgoingPacket p = OUTGOING_PACKETS.get(clazz); + if (p == null) { + log(PacketRepository.class, Log.ERR, "Invalid outgoing packet [handler=" + clazz + ", context=" + context + "]."); + return; + } + if(!context.getPlayer().isArtificial()) { + try { + PacketWriteQueue.handle(p, context); + } catch (Exception e) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + e.printStackTrace(pw); + log(PacketRepository.class, Log.ERR, "Error writing packet out: " + sw); + } + } + } + +} diff --git a/Server/src/main/core/net/packet/PacketWriteQueue.kt b/Server/src/main/core/net/packet/PacketWriteQueue.kt new file mode 100644 index 0000000..fad4533 --- /dev/null +++ b/Server/src/main/core/net/packet/PacketWriteQueue.kt @@ -0,0 +1,69 @@ +package core.net.packet + +import core.api.log +import core.api.tryPop +import core.net.packet.out.* +import core.tools.Log +import core.tools.SystemLogger +import java.io.PrintWriter +import java.io.StringWriter +import java.util.* +import java.util.concurrent.locks.ReentrantLock + +class PacketWriteQueue { + companion object { + private val packetsToWrite = LinkedList>() + + @JvmStatic + fun handle(packet: OutgoingPacket, context: T) { + when (packet) { + //Dynamic packets need to be sent immediately + is UpdateSceneGraph, + is BuildDynamicScene, + is InstancedLocationUpdate, + is Logout, + is ClearRegionChunk -> packet.send(context) + //Rest get queued up and sent at the end of the tick (authentic) + else -> push(packet, context) + } + } + + @JvmStatic + fun push(packet: OutgoingPacket, context: T) { + if (context == null) { + log(this::class.java, Log.ERR, "${packet::class.java.simpleName} tried to queue with a null context!") + return + } + packetsToWrite.add(QueuedPacket(packet, context)) + } + + @JvmStatic + fun flush() { + var countThisCycle = packetsToWrite.size + val sw = StringWriter() + val pw = PrintWriter(sw) + while (countThisCycle-- > 0) { + val pkt = packetsToWrite.tryPop(null) ?: continue + try { + write(pkt.out, pkt.context) + } catch (e: Exception) { + e.printStackTrace(pw) + log(this::class.java, Log.ERR, "Error flushing packet ${pkt.out::class.java}: $sw") + continue + } + } + } + + @Suppress("UNCHECKED_CAST") + fun write(out: OutgoingPacket<*>, context: T) { + val pack = out as? OutgoingPacket + val ctx = context as? T + if (pack == null || ctx == null) { + throw IllegalStateException("Failed packet casting") + } + pack.send(ctx) + } + } +} + +class QueuedPacket(val out: OutgoingPacket, val context: T) diff --git a/Server/src/main/core/net/packet/QCRepository.kt b/Server/src/main/core/net/packet/QCRepository.kt new file mode 100644 index 0000000..b2b1ccb --- /dev/null +++ b/Server/src/main/core/net/packet/QCRepository.kt @@ -0,0 +1,321 @@ +package core.net.packet + +import content.global.skill.slayer.SlayerManager +import core.api.* +import core.cache.Cache +import core.cache.def.impl.DataMap +import core.cache.def.impl.ItemDefinition +import core.cache.def.impl.NPCDefinition +import core.cache.misc.buffer.ByteBufferUtils +import core.game.node.entity.player.Player +import core.game.node.entity.skill.Skills +import core.game.system.task.Pulse +import core.game.world.update.flag.context.ChatMessage +import core.game.world.update.flag.* +import proto.management.ClanMessage +import core.game.world.GameWorld.Pulser +import core.net.packet.`in`.QCPacketType +import core.worker.ManagementEvents.publish +import java.nio.ByteBuffer +import java.util.* + + +/** + * Handles the sending of quick chat messages and string-replacement for specific messages. + * @author Ceikry + */ +object QCRepository { + private val quickChatIndex = Cache.getIndexes()[24] + + /** + * The entry method that connects to the other more specific methods + */ + @JvmStatic + fun sendQC(player: Player?, multiplier: Int?, offset: Int?, packetType: QCPacketType, selection_a_index: Int, selection_b_index: Int, forClan: Boolean){ + val index = getIndex(offset, multiplier) + player?.setAttribute("qc_offset", offset) //Slapping this in an attribute because it's only useful for one or two messages + val qcString = when(packetType){ + QCPacketType.SINGLE -> getSingleQC(index, selection_a_index) + QCPacketType.DOUBLE -> getDoubleQC(index, selection_a_index, selection_b_index) + QCPacketType.STANDARD -> getStandardQC(player, index) + else -> "" + } + + + if(forClan) { + val builder = ClanMessage.newBuilder() + builder.sender = player!!.name + builder.clanName = player.communication.clan.owner.lowercase(Locale.getDefault()).replace(" ", "_") + builder.message = qcString + builder.rank = player.details.rights.ordinal + publish(builder.build()) + } else { + val ctx = ChatMessage(player!!, qcString, 0, qcString.length) + ctx.isQuickChat = true + Pulser.submit(object : Pulse(0, player) { + override fun pulse(): Boolean { + player.updateMasks.register(EntityFlag.Chat, ctx) + return true + } + }) + } + } + + /** + * For standard quick chat messages with no string replacements + */ + @JvmStatic + fun getStandardQC(player: Player?, index: Int): String{ + var qcString = getQCString(index) + + //XP to next level + if (qcString.contains("to get my next")) { + val split = qcString.split(" ") + val skillName = split[split.size - 2] + val skill = Skills.getSkillByName(skillName.toUpperCase()) + val playerXP = player?.skills?.getExperience(skill) + val playerLevel = player?.skills?.getStaticLevel(skill) + val nextXP = player?.skills?.getExperienceByLevel(playerLevel?.plus(1) ?: 1) + qcString = qcString.replace("<", "${(nextXP?.minus(playerXP ?: 0.0) ?: 0.0).toInt()}") + } + + //My X level is + else if (qcString.contains("level is")) { + val skillName = qcString.split(" ")[1] + val skill = Skills.getSkillByName(skillName.toUpperCase()) + val level = player?.skills?.getStaticLevel(skill) + qcString = qcString.replace("<", level.toString()) + } + + //My current slayer assignment is + else if(qcString.contains("My current Slayer assignment is")){ + val amount = SlayerManager.getInstance(player!!).amount + val taskName = getSlayerTask(player)?.name?.toLowerCase() ?: "None" + if(amount ?: 0 > 0){ + qcString = qcString.replace("complete", "$amount $taskName") + } + } + + return qcString + } + + + /** + * For Single-replacement quick chat messages with one replacement selection + */ + @JvmStatic + fun getSingleQC(index: Int, selectionIndex: Int): String{ + var qcString = getQCString(index) + + //Messages that include items + if ((qcString.contains("item") || qcString.contains("Can I buy your") || qcString.contains("What is the best world to buy") || qcString.contains("What is the best world to sell") || qcString.contains("Would you like to borrow") || qcString.contains("Could I please borrow") ) && qcString.contains("<") ){ + val itemName = ItemDefinition.forId(selectionIndex).name + qcString = qcString.replace("<", itemName) + } + + //Loan duration + else if (qcString.contains("I'd like the loan duration to be")){ + qcString = qcString.replace("<", getFromMap(1642, selectionIndex)) + } + + //Go to agility course / Try training your agility at + else if (qcString.contains("Let's go to Agility course:") || qcString.contains("Try training your Agility at:")){ + qcString = qcString.replace("<", getFromMap(1505, selectionIndex)) + } + + //Try training on + else if(qcString.contains("Try training on")){ + qcString = qcString.replace("<", getFromMap(1524, selectionIndex)) + } + + //Try ranging + else if(qcString.contains("Try ranging")){ + qcString = qcString.replace("<", getFromMap(1525, selectionIndex)) + } + + //flat-pack + else if(qcString.contains("flat-pack")){ + qcString = qcString.replace("<", getFromMap(1490, selectionIndex)) + } + + //Cooking + else if(qcString.contains("I'm cooking") || qcString.contains("Would you please cook me") || qcString.contains("Try cooking")){ + qcString = qcString.replace("<", getFromMap(1492, selectionIndex)) + } + + //Crafting + else if(qcString.contains("I am crafting") || qcString.contains("Try crafting") || qcString.contains("Would you please craft me")){ + qcString = qcString.replace("<", getFromMap(1493, selectionIndex)) + } + + //Farming + else if(qcString.contains("I'm growing crop") || qcString.contains("Try growing crop")){ + qcString = qcString.replace("<", getFromMap(1494, selectionIndex)) + } + + //I'm burning logs... + else if(qcString.contains("I'm burning logs")){ + qcString = qcString.replace("<", getFromMap(1495, selectionIndex)) + } + + //Try burning logs at + else if(qcString.contains("Try burning logs at")){ + qcString = qcString.replace("<", getFromMap(1544, selectionIndex)) + } + + //Fishing + else if(qcString.contains("I'm fishing") || qcString.contains("Would you please fish me") || qcString.contains("Try fishing for")){ + qcString = qcString.replace("<", getFromMap(1491, selectionIndex)) + } + + //Fletching + else if(qcString.contains("I'm fletching") || qcString.contains("Try fletching") || qcString.contains("Would you please fetch me")){ + qcString = qcString.replace("<", getFromMap(1496, selectionIndex)) + } + + //Herblore + else if(qcString.contains("I'm mixing potion") || qcString.contains("Would you please mix me a potion") || qcString.contains("Try mixing potion")){ + qcString = qcString.replace("<", getFromMap(1526, selectionIndex)) + } + + //Herblore secondaries + else if(qcString.contains("Where can I get the secondary ingredient")){ + qcString = qcString.replace("<", getFromMap(1516, selectionIndex)) + } + + //Hunter + else if(qcString.contains("Would you please hunt me") || qcString.contains("Try hunting")){ + qcString = qcString.replace("<", getFromMap(1543, selectionIndex)) + } + + //Casting spell + else if(qcString.contains("I'm casting spell") || qcString.contains("Would you please cast")){ + qcString = qcString.replace("<", getFromMap(1527, selectionIndex)) + } + + //Spellbook + else if(qcString.contains("I am on spell book")){ + qcString = qcString.replace("<", getFromMap(1528, selectionIndex)) + } + + //Mining ore + else if(qcString.contains("I'm mining ore")){ + qcString = qcString.replace("<", getFromMap(1529, selectionIndex)) + } + + //Pickaxe using + else if(qcString.contains("I'm using a pick")){ + qcString = qcString.replace("<", getFromMap(1531, selectionIndex)) + } + + //Try mining at + else if(qcString.contains("Try mining at")){ + qcString = qcString.replace("<", getFromMap(1533, selectionIndex)) + } + + //Use your prayer + else if(qcString.contains("Use your prayer")){ + qcString = qcString.replace("<", getFromMap(1534, selectionIndex)) + } + + //i'm going to craft rune + else if(qcString.contains("I'm going to craft rune")){ + qcString = qcString.replace("<", getFromMap(1535, selectionIndex)) + } + + //try crafting runes at + else if(qcString.contains("Try crafting runes at")){ + qcString = qcString.replace("<", getFromMap(1536, selectionIndex)) + } + + //Slayer master in + else if(qcString.contains("You should use the Slayer master in")){ + qcString = qcString.replace("<", getFromMap(2139, selectionIndex)) + } + + //Spare slayer equipment + else if(qcString.contains("Do you have spare Slayer equipment")){ + qcString = qcString.replace("<", getFromMap(1538, selectionIndex)) + } + + //familiars + else if(qcString.contains("I like the familiar") || qcString.contains("I can summon up to")){ + qcString = qcString.replace("<", getFromMap(1539, selectionIndex)) + } + + //charm droppers + else if(qcString.contains("Good charm droppers are")){ + qcString = qcString.replace("<", getFromMap(1499, selectionIndex)) + } + + //Thieving + else if(qcString.contains("Try thieving from")){ + qcString = qcString.replace("<", getFromMap(1540, selectionIndex)) + } + + //Axe made of + else if(qcString.contains("I'm using a woodcutting axe made")){ + qcString = qcString.replace("<", getFromMap(1532, selectionIndex)) + } + + //Try training woodcutting at + else if(qcString.contains("Try training Woodcutting at")){ + qcString = qcString.replace("<", getFromMap(1500, selectionIndex)) + } + + //Nice level in + else if(qcString.contains("Nice level in")){ + qcString = qcString.replace("<", getFromMap(1517, selectionIndex)) + } + + + return qcString + } + + fun getFromMap(map: Int, index: Int): String + { + return DataMap.get(map).getString(index) + } + + /** + * For Double-replacement quick chat messages with 2 selection replacements. + */ + @JvmStatic + fun getDoubleQC(index: Int, selection_a_index: Int, selection_b_index: Int): String{ + var qcString = getQCString(index) + + //Giving directions: That is _ of _ + if(qcString.contains("That is < of <")){ + qcString = qcString.replaceFirst("<", getFromMap(1502, selection_a_index)) + qcString = qcString.replaceFirst("<", getFromMap(1504, selection_b_index)) + } + + //Smithing + else if(qcString.contains("I am smithing") || qcString.contains("Try smithing") || qcString.contains("Would you please smith me")){ + qcString = qcString.replaceFirst("<", getFromMap(1530, selection_a_index)) + qcString = qcString.replaceFirst("<", getFromMap(1498, selection_b_index)) + } + + return qcString + } + + private fun getIndex(offset: Int?, multiplier: Int?): Int{ + offset ?: return 0 + multiplier ?: return 0 + //for some reason it subtracts only from 512 if it's negative (Jagex idk) or 256 if type is 0 but not from 768 if type is 3? + return if(offset >= 0) { + (256 * multiplier) + offset + }else { + when(multiplier){ + 0 -> 256 + offset + 1 -> 512 + offset + 2 -> 768 + offset + else -> 1024 + offset + } + } + } + + private fun getQCString(index: Int): String{ + return ByteBufferUtils.getString(ByteBuffer.wrap(quickChatIndex.getFileData(1, index))) + } +} diff --git a/Server/src/main/core/net/packet/context/AccessMaskContext.java b/Server/src/main/core/net/packet/context/AccessMaskContext.java new file mode 100644 index 0000000..5c14f7f --- /dev/null +++ b/Server/src/main/core/net/packet/context/AccessMaskContext.java @@ -0,0 +1,125 @@ +package core.net.packet.context; + +import core.game.node.entity.player.Player; +import core.net.packet.Context; + +/** + * The access mask context. + * @author Emperor + */ +public class AccessMaskContext implements Context { + + /** + * The player reference. + */ + private Player player; + + /** + * The access mask id. + */ + private int id; + + /** + * The child id. + */ + private int childId; + + /** + * The interface id. + */ + private int interfaceId; + + /** + * The offset. + */ + private int offset; + + /** + * The length. + */ + private int length; + + /** + * Construct a new {@code AccessMaskContext} {@code Object}. + * @param player + * @param id + * @param childId + * @param interfaceId + * @param offset + * @param length + */ + public AccessMaskContext(Player player, int id, int childId, int interfaceId, int offset, int length) { + this.player = player; + this.id = id; + this.childId = childId; + this.interfaceId = interfaceId; + this.offset = offset; + this.length = length; + } + + @Override + public Player getPlayer() { + return player; + } + + /** + * Transforms this access mask context into a new instance with the player + * instance and id value changed. + * @param player The player to set. + * @param id The id to set. + * @return The access mask context. + */ + public AccessMaskContext transform(Player player, int id) { + return new AccessMaskContext(player, id, childId, interfaceId, offset, length); + } + + /** + * Sets the player. + * @param player The player. + * @return This context instance. + */ + public Context setPlayer(Player player) { + this.player = player; + return this; + } + + /** + * Get the access mask id. + * @return The access mask. + */ + public int getId() { + return id; + } + + /** + * Get the child id. + * @return The child id. + */ + public int getChildId() { + return childId; + } + + /** + * Get the interface id. + * @return The interface id. + */ + public int getInterfaceId() { + return interfaceId; + } + + /** + * Get the offset. + * @return The offset. + */ + public int getOffset() { + return offset; + } + + /** + * Get the length. + * @return The length. + */ + public int getLength() { + return length; + } +} diff --git a/Server/src/main/core/net/packet/context/AnimateInterfaceContext.java b/Server/src/main/core/net/packet/context/AnimateInterfaceContext.java new file mode 100644 index 0000000..d2394c3 --- /dev/null +++ b/Server/src/main/core/net/packet/context/AnimateInterfaceContext.java @@ -0,0 +1,74 @@ +package core.net.packet.context; + +import core.game.node.entity.player.Player; +import core.net.packet.Context; + +/** + * The animate interface context. + * @author Emperor + */ +public class AnimateInterfaceContext implements Context { + + /** + * The player reference. + */ + private Player player; + + /** + * The animation id. + */ + private int animationId; + + /** + * The interface id. + */ + private int interfaceId; + + /** + * The child id. + */ + private int childId; + + /** + * Construct a new {@code AnimateInterfaceContext} {@code Object}. + * @param player The player reference. + * @param animationId The animation id. + * @param interfaceId The interface id. + * @param childId The child id. + */ + public AnimateInterfaceContext(Player player, int animationId, int interfaceId, int childId) { + this.player = player; + this.animationId = animationId; + this.interfaceId = interfaceId; + this.childId = childId; + } + + /** + * Get the animation id. + * @return The animation id. + */ + public int getAnimationId() { + return animationId; + } + + /** + * Get the interface id. + * @return The interface id. + */ + public int getInterfaceId() { + return interfaceId; + } + + /** + * Get the child id. + * @return The child id. + */ + public int getChildId() { + return childId; + } + + @Override + public Player getPlayer() { + return player; + } +} diff --git a/Server/src/main/core/net/packet/context/AnimateObjectContext.java b/Server/src/main/core/net/packet/context/AnimateObjectContext.java new file mode 100644 index 0000000..ab8cda8 --- /dev/null +++ b/Server/src/main/core/net/packet/context/AnimateObjectContext.java @@ -0,0 +1,47 @@ +package core.net.packet.context; + +import core.game.node.entity.player.Player; +import core.game.world.update.flag.context.Animation; +import core.net.packet.Context; + +/** + * Represents the context of animating an object. + * @author Emperor + * @author 'Vexia + * @date 10/11/2013 + */ +public class AnimateObjectContext implements Context { + + /** + * Represents the player of the context. + */ + private final Player player; + + /** + * Represents the animation to use. + */ + private final Animation animation; + + /** + * Constructs a new {@code AnimateObjectContext} {@code Object}. + * @param player the player. + * @param animation the animation. + */ + public AnimateObjectContext(Player player, Animation animation) { + this.player = player; + this.animation = animation; + } + + @Override + public Player getPlayer() { + return player; + } + + /** + * Gets the animation. + * @return The animation. + */ + public Animation getAnimation() { + return animation; + } +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/context/AreaPositionContext.java b/Server/src/main/core/net/packet/context/AreaPositionContext.java new file mode 100644 index 0000000..5ba7ce4 --- /dev/null +++ b/Server/src/main/core/net/packet/context/AreaPositionContext.java @@ -0,0 +1,76 @@ +package core.net.packet.context; + +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.net.packet.Context; + +/** + * Handles the area position update packet context. + * @author Emperor + */ +public final class AreaPositionContext implements Context { + + /** + * The player. + */ + private final Player player; + + /** + * The location. + */ + private final Location location; + + /** + * The offset x-coordinate. + */ + private final int offsetX; + + /** + * The offset y-coordinate. + */ + private final int offsetY; + + /** + * Constructs a new {@code AreaPositionContext} {@code Object}. + * @param player The player. + * @param location The location. + * @param offsetX The offset x-coordinate. + * @param offsetY The offset y-coordinate. + */ + public AreaPositionContext(Player player, Location location, int offsetX, int offsetY) { + this.player = player; + this.location = location; + this.offsetX = offsetX; + this.offsetY = offsetY; + } + + @Override + public Player getPlayer() { + return player; + } + + /** + * Gets the location. + * @return The location. + */ + public Location getLocation() { + return location; + } + + /** + * Gets the offsetX. + * @return The offsetX. + */ + public int getOffsetX() { + return offsetX; + } + + /** + * Gets the offsetY. + * @return The offsetY. + */ + public int getOffsetY() { + return offsetY; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/context/BuildItemContext.java b/Server/src/main/core/net/packet/context/BuildItemContext.java new file mode 100644 index 0000000..300660c --- /dev/null +++ b/Server/src/main/core/net/packet/context/BuildItemContext.java @@ -0,0 +1,71 @@ +package core.net.packet.context; + +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.net.packet.Context; + +/** + * Represents the build item packet context,
which is used for + * construct/clear item outgoing packet. + * @author Emperor + */ +public final class BuildItemContext implements Context { + + /** + * The player. + */ + private final Player player; + + /** + * The item to send. + */ + private final Item item; + + /** + * The old item amount. + */ + private final int oldAmount; + + /** + * Constructs a new {@code BuildObjectContext} {@code Object}. + * @param player The player + * @param item The item to send. + */ + public BuildItemContext(Player player, Item item) { + this(player, item, 0); + } + + /** + * Constructs a new {@code BuildObjectContext} {@code Object}. + * @param player The player + * @param item The item to send. + * @param oldAmount The old item amount. + */ + public BuildItemContext(Player player, Item item, int oldAmount) { + this.player = player; + this.item = item; + this.oldAmount = oldAmount; + } + + @Override + public Player getPlayer() { + return player; + } + + /** + * Gets the item. + * @return The item. + */ + public Item getItem() { + return item; + } + + /** + * Gets the oldAmount. + * @return The oldAmount. + */ + public int getOldAmount() { + return oldAmount; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/context/BuildSceneryContext.java b/Server/src/main/core/net/packet/context/BuildSceneryContext.java new file mode 100644 index 0000000..3fa8ff0 --- /dev/null +++ b/Server/src/main/core/net/packet/context/BuildSceneryContext.java @@ -0,0 +1,47 @@ +package core.net.packet.context; + +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.net.packet.Context; + +/** + * Represents the build object packet context,
which is used for + * construct/clear object outgoing packet. + * @author Emperor + */ +public final class BuildSceneryContext implements Context { + + /** + * The player. + */ + private final Player player; + + /** + * The list of scenerys to send. + */ + private final Scenery scenery; + + /** + * Constructs a new {@code BuildObjectContext} {@code Object}. + * @param player The player + * @param scenery the scenery to send. + */ + public BuildSceneryContext(Player player, Scenery scenery) { + this.player = player; + this.scenery = scenery; + } + + @Override + public Player getPlayer() { + return player; + } + + /** + * Gets the gameObject. + * @return The gameObject. + */ + public Scenery getScenery() { + return scenery; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/context/CSConfigContext.java b/Server/src/main/core/net/packet/context/CSConfigContext.java new file mode 100644 index 0000000..52ea7bf --- /dev/null +++ b/Server/src/main/core/net/packet/context/CSConfigContext.java @@ -0,0 +1,84 @@ +package core.net.packet.context; + +import core.game.node.entity.player.Player; +import core.net.packet.Context; + +/** + * The context for ClientScript configurations. + * + * @author Torchic + */ +public class CSConfigContext implements Context { + /** + * The player reference. + */ + private Player player; + + /** + * The value + */ + private int value; + + /** + * The id. + */ + private int id; + private final Object[] parameters; + private final String types; + + + /** + * Constructs a new {@Code CSConfigContext} {@Code Object} + * @param player The player. + * @param id The id. + * @param value The config value. + * @param parameters + * @param types + */ + public CSConfigContext(Player player, int id, int value, String types, Object[] parameters) { + this.player = player; + this.value = value; + this.id = id; + this.parameters = parameters; + this.types = types; + } + + @Override + public Player getPlayer() { + return player; + } + + /** + * Sets the player. + * @param player The player. + * @return This context instance. + */ + public Context setPlayer(Player player) { + this.player = player; + return this; + } + + /** + * Get the config value. + * @return The config value. + */ + public int getValue() { + return value; + } + + /** + * Get the config id. + * @return The config id. + */ + public int getId() { + return id; + } + + public String getTypes() { + return types; + } + + public Object[] getParameters() { + return parameters; + } +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/context/CameraContext.java b/Server/src/main/core/net/packet/context/CameraContext.java new file mode 100644 index 0000000..6858774 --- /dev/null +++ b/Server/src/main/core/net/packet/context/CameraContext.java @@ -0,0 +1,177 @@ +package core.net.packet.context; + +import core.game.node.entity.player.Player; +import core.net.packet.Context; + +/** + * Represents a camera context. + * @author Emperor + */ +public final class CameraContext implements Context { + + + /** + * Represents the camera types used for determining which packet to send. + * @author Emperor + */ + public static enum CameraType { + POSITION(154), + ROTATION(125), + SET(187), SHAKE(27), RESET(24); + + /** + * The opcode. + */ + private final int opcode; + + /** + * Constructs a new {@code CameraContext} {@Code Object}. + * @param opcode The opcode. + */ + private CameraType(int opcode) { + this.opcode = opcode; + } + + /** + * Gets the packet opcode. + * @return The opcode. + */ + public int opcode() { + return opcode; + } + } + + /* + * rotateCamera(Player p, int x, int y, int z, int angle) { MessageBuilder + * bldr = new MessageBuilder(26); bldr.writeByte(y); //idk + * bldr.writeByte(x); //idk bldr.writeLEShortA(z >>> 2); //idk + * bldr.writeByte(0); // speed :S bldr.writeByteS(100); + */ + /** + * The player. + */ + private final Player player; + + /** + * The camera type. + */ + private final CameraType type; + + /** + * x The (local) x-coordinate of the camera. + */ + private final int x; + + /** + * The (local) y-coordinate of the camera. + */ + private final int y; + + /** + * The height. + */ + private final int height; + + /** + * The zoom speed. + */ + private final int zoomSpeed; + + /** + * The speed. + */ + private final int speed; + + /** + * Constructs a new {@code CameraContext} {@Code Object}. + * @param player The player. + * @param type The camera type. + * @param x The x-coordinate of the camera. + * @param y The y-coordinate of the camera. + * @param height The height. + * @param zoomSpeed The zoom speed. + * @param speed The speed. + */ + public CameraContext(Player player, CameraType type, int x, int y, int height, int speed, int zoomSpeed) { + this.player = player; + this.type = type; + this.x = x; + this.y = y; + this.height = height; + this.speed = speed; + this.zoomSpeed = zoomSpeed; + } + + /** + * Method used to transform a camera context. + * @param x the x. + * @param y the y. + * @return the new context. + */ + public CameraContext transform(final Player player, final int x, final int y) { + return new CameraContext(player, type, this.x + x, this.y + y, height, speed, zoomSpeed); + } + + /** + * Method used to transform the context. + * @param heightOffset the height offset. + * @return the new context. + */ + public CameraContext transform(final int heightOffset) { + return new CameraContext(player, type, x, y, height + heightOffset, speed, zoomSpeed); + } + + @Override + public Player getPlayer() { + return player; + } + + /** + * Gets the type. + * @return The type. + */ + public CameraType getType() { + return type; + } + + /** + * Gets the x. + * @return The x. + */ + public int getX() { + return x; + } + + /** + * Gets the y. + * @return The y. + */ + public int getY() { + return y; + } + + /** + * Gets the height. + * @return The height. + */ + public int getHeight() { + return height; + } + + /** + * Gets the speed. + * @return The speed. + */ + public int getSpeed() { + return speed; + } + + /** + * Gets the zoomSpeed. + * @return The zoomSpeed. + */ + public int getZoomSpeed() { + return zoomSpeed; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/context/ChildPositionContext.java b/Server/src/main/core/net/packet/context/ChildPositionContext.java new file mode 100644 index 0000000..ab333f7 --- /dev/null +++ b/Server/src/main/core/net/packet/context/ChildPositionContext.java @@ -0,0 +1,78 @@ +package core.net.packet.context; + +import core.game.node.entity.player.Player; +import core.net.packet.Context; + +import java.awt.*; + +/** + * A context implementation used for the interface child repositioning packet. + * @author Emperor + */ +public final class ChildPositionContext implements Context { + + /** + * The player. + */ + private final Player player; + + /** + * The interface id. + */ + private final int interfaceId; + + /** + * The child id. + */ + private final int childId; + + /** + * The new position of the child. + */ + private final Point position; + + /** + * Constructs a new {@code ChildPositionContext} {@code Object}. + * @param player The player. + * @param interfaceId The interface id. + * @param childId The id of the child to reposition. + * @param positionX The new x-position. + * @param positionY The new y-position. + */ + public ChildPositionContext(Player player, int interfaceId, int childId, int positionX, int positionY) { + this.player = player; + this.interfaceId = interfaceId; + this.childId = childId; + this.position = new Point(positionX, positionY); + } + + @Override + public Player getPlayer() { + return player; + } + + /** + * Gets the interfaceId. + * @return The interfaceId. + */ + public int getInterfaceId() { + return interfaceId; + } + + /** + * Gets the childId. + * @return The childId. + */ + public int getChildId() { + return childId; + } + + /** + * Gets the position. + * @return The position. + */ + public Point getPosition() { + return position; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/context/ClanContext.java b/Server/src/main/core/net/packet/context/ClanContext.java new file mode 100644 index 0000000..9b9f296 --- /dev/null +++ b/Server/src/main/core/net/packet/context/ClanContext.java @@ -0,0 +1,60 @@ +package core.net.packet.context; + +import core.game.node.entity.player.Player; +import core.game.system.communication.ClanRepository; +import core.net.packet.Context; + +/** + * The packet context for clan-related outgoing packets. + * @author Emperor + */ +public final class ClanContext implements Context { + + /** + * The player + */ + private final Player player; + + /** + * The clan instance. + */ + private final ClanRepository clan; + + /** + * If the player is leaving the clan. + */ + private final boolean leave; + + /** + * Constructs a new {@code ClanContext} {@code Object}. + * @param player the player. + * @param clan the clan. + * @param leave If the player is leaving the clan. + */ + public ClanContext(Player player, ClanRepository clan, boolean leave) { + this.player = player; + this.clan = clan; + this.leave = leave; + } + + /** + * Gets the clan. + * @return The clan. + */ + public ClanRepository getClan() { + return clan; + } + + /** + * Gets the leave. + * @return The leave. + */ + public boolean isLeave() { + return leave; + } + + @Override + public Player getPlayer() { + return player; + } +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/context/ClearChunkContext.java b/Server/src/main/core/net/packet/context/ClearChunkContext.java new file mode 100644 index 0000000..739a728 --- /dev/null +++ b/Server/src/main/core/net/packet/context/ClearChunkContext.java @@ -0,0 +1,46 @@ +package core.net.packet.context; + +import core.game.node.entity.player.Player; +import core.game.world.map.RegionChunk; +import core.net.packet.Context; + +/** + * The packet context for the clear region chunk outgoing packet. + * @author Emperor + */ +public final class ClearChunkContext implements Context { + + /** + * The player. + */ + private final Player player; + + /** + * The region chunk to clear. + */ + private final RegionChunk chunk; + + /** + * Constructs a new {@code ClearChunkContext} {@code Object}. + * @param player The player. + * @param chunk The chunk to clear. + */ + public ClearChunkContext(Player player, RegionChunk chunk) { + this.player = player; + this.chunk = chunk; + } + + @Override + public Player getPlayer() { + return player; + } + + /** + * Gets the chunk. + * @return The chunk. + */ + public RegionChunk getChunk() { + return chunk; + } + +} diff --git a/Server/src/main/core/net/packet/context/ConfigContext.java b/Server/src/main/core/net/packet/context/ConfigContext.java new file mode 100644 index 0000000..b9200a0 --- /dev/null +++ b/Server/src/main/core/net/packet/context/ConfigContext.java @@ -0,0 +1,93 @@ +package core.net.packet.context; + +import core.game.node.entity.player.Player; +import core.net.packet.Context; + +/** + * The config packet context. + * @author Emperor + */ +public class ConfigContext implements Context { + + /** + * The player reference. + */ + private Player player; + + /** + * The config id. + */ + private int id; + + /** + * The config value. + */ + private int value; + + /** + * If the config is a cs2-config. + */ + private boolean cs2; + + /** + * Construct a new {@code ConfigContext} {@code Object}. + * @param player The player reference. + * @param id The config id. + * @param value The config value. + */ + public ConfigContext(Player player, int id, int value) { + this(player, id, value, false); + } + + /** + * Construct a new {@code ConfigContext} {@code Object}. + * @param player The player reference. + * @param id The config id. + * @param value The config value. + */ + public ConfigContext(Player player, int id, int value, boolean cs2) { + this.player = player; + this.id = id; + this.value = value; + this.cs2 = cs2; + } + + @Override + public Player getPlayer() { + return player; + } + + /** + * Sets the player. + * @param player The player. + * @return This context instance. + */ + public Context setPlayer(Player player) { + this.player = player; + return this; + } + + /** + * Get the config id. + * @return The config id. + */ + public int getId() { + return id; + } + + /** + * Get the config value. + * @return The config value. + */ + public int getValue() { + return value; + } + + /** + * Gets the cs2. + * @return The cs2. + */ + public boolean isCs2() { + return cs2; + } +} diff --git a/Server/src/main/core/net/packet/context/ContactContext.java b/Server/src/main/core/net/packet/context/ContactContext.java new file mode 100644 index 0000000..2377100 --- /dev/null +++ b/Server/src/main/core/net/packet/context/ContactContext.java @@ -0,0 +1,131 @@ +package core.net.packet.context; + +import core.game.node.entity.player.Player; +import core.net.packet.Context; + +/** + * The packet context for the contact packets. + * @author Emperor + */ +public final class ContactContext implements Context { + + /** + * The update communication server state type. + */ + public static final int UPDATE_STATE_TYPE = 0; + + /** + * The update friend type. + */ + public static final int UPDATE_FRIEND_TYPE = 1; + + /** + * The ignore list type. + */ + public static final int IGNORE_LIST_TYPE = 2; + + /** + * The player. + */ + private final Player player; + + /** + * The contact packet type. + */ + private int type; + + /** + * The player name. + */ + private String name; + + /** + * The world id + */ + private int worldId; + + /** + * Constructs a new {@code ContactContext} {@code Object}. + * @param player The player. + * @param type The contact packet type. + */ + public ContactContext(Player player, int type) { + this.player = player; + this.type = type; + } + + /** + * Constructs a new {@code ContactContext} {@code Object}. + * @param player The player. + * @param name The player name. + * @param worldId The world id (0 = offline). + */ + public ContactContext(Player player, String name, int worldId) { + this.player = player; + this.name = name; + this.worldId = worldId; + this.type = UPDATE_FRIEND_TYPE; + } + + @Override + public Player getPlayer() { + return player; + } + + /** + * Gets the type. + * @return The type. + */ + public int getType() { + return type; + } + + /** + * Sets the type. + * @param type The type to set. + */ + public void setType(int type) { + this.type = type; + } + + /** + * Gets the name. + * @return The name. + */ + public String getName() { + return name; + } + + /** + * Sets the name. + * @param name The name to set. + */ + public void setName(String name) { + this.name = name; + } + + /** + * Gets the online. + * @return The online. + */ + public boolean isOnline() { + return worldId > 0; + } + + /** + * Gets the worldId. + * @return the worldId + */ + public int getWorldId() { + return worldId; + } + + /** + * Sets the worldId. + * @param worldId the worldId to set. + */ + public void setWorldId(int worldId) { + this.worldId = worldId; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/context/ContainerContext.java b/Server/src/main/core/net/packet/context/ContainerContext.java new file mode 100644 index 0000000..411a812 --- /dev/null +++ b/Server/src/main/core/net/packet/context/ContainerContext.java @@ -0,0 +1,229 @@ +package core.net.packet.context; + +import core.game.container.Container; +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.net.packet.Context; + +/** + * Represents the context for the container packet. + * @author Emperor + */ +public final class ContainerContext implements Context { + + /** + * The player. + */ + private Player player; + + /** + * The interface id. + */ + private final int interfaceId; + + /** + * The child id. + */ + private final int childId; + + /** + * The container type. + */ + private final int containerId; + + /** + * The items. + */ + private Item[] items; + + public int[] ids; + + /** + * The length of the array to send. + */ + private final int length; + + /** + * If the container should be split up. + */ + private final boolean split; + + /** + * The slots we're changing. + */ + private final int[] slots; + + /** + * If the container should be cleared. + */ + private boolean clear; + + /** + * Constructs a new {@code ContainerContext} {@code Object}. + * @param player The player. + * @param interfaceId The interface id. + * @param childId The child id. + * @param clear If the container should be cleared. + */ + public ContainerContext(Player player, int interfaceId, int childId, boolean clear) { + this(player, interfaceId, childId, 0, null, 1, false); + this.clear = clear; + } + + /** + * Constructs a new {@code ContainerContext} {@code Object}. + * @param player The player. + * @param interfaceId The interface id. + * @param childId The child id. + * @param containerId The container type. + * @param container The container. + * @param split If the container should be split. + */ + public ContainerContext(Player player, int interfaceId, int childId, int containerId, Container container, boolean split) { + this(player, interfaceId, childId, containerId, container.toArray(), container.toArray().length, split); + } + + /** + * Constructs a new {@code ContainerContext} {@code Object}. + * @param player The player. + * @param interfaceId The interface id. + * @param childId The child id. + * @param containerId The container type. + * @param items The items. + * @param split If the container should be split. + */ + public ContainerContext(Player player, int interfaceId, int childId, int containerId, Item[] items, boolean split) { + this(player, interfaceId, childId, containerId, items, items.length, split); + } + + /** + * Constructs a new {@code ContainerContext} {@code Object}. + * @param player The player. + * @param interfaceId The interface id. + * @param childId The child id. + * @param containerId The container containerId. + * @param items The items. + * @param length The length. + * @param split If the container should be split. + */ + public ContainerContext(Player player, int interfaceId, int childId, int containerId, Item[] items, int length, boolean split) { + this.player = player; + this.interfaceId = interfaceId; + this.childId = childId; + this.containerId = containerId; + this.items = items; + this.length = length; + this.split = split; + this.slots = null; + } + + public ContainerContext(Player player, int interfaceId, int childId, int containerId, int[] items) { + this.player = player; + this.interfaceId = interfaceId; + this.childId = childId; + this.containerId = containerId; + this.ids = items; + this.length = items.length; + this.split = false; + this.slots = null; + } + + /** + * Constructs a new {@code ContainerContext} {@code Object}. + * @param player The player. + * @param interfaceId The interface id. + * @param childId The child id. + * @param containerId The container containerId. + * @param items The items. + * @param split If the container should be split. + * @param slots The slots to update. + */ + public ContainerContext(Player player, int interfaceId, int childId, int containerId, Item[] items, boolean split, int... slots) { + this.player = player; + this.interfaceId = interfaceId; + this.childId = childId; + this.containerId = containerId; + this.items = items; + this.length = items.length; + this.split = split; + this.slots = slots; + } + + @Override + public Player getPlayer() { + return player; + } + + /** + * Gets the interfaceId. + * @return The interfaceId. + */ + public int getInterfaceId() { + return interfaceId; + } + + /** + * Gets the type. + * @return The type. + */ + public int getContainerId() { + return containerId; + } + + /** + * Gets the items. + * @return The items. + */ + public Item[] getItems() { + return items; + } + + /** + * Gets the length. + * @return The length. + */ + public int getLength() { + return length; + } + + /** + * Gets the split. + * @return The split. + */ + public boolean isSplit() { + return split; + } + + /** + * Gets the slots. + * @return The slots. + */ + public int[] getSlots() { + return slots; + } + + /** + * Gets the childId. + * @return The childId. + */ + public int getChildId() { + return childId; + } + + /** + * Gets the clear. + * @return The clear. + */ + public boolean isClear() { + return clear; + } + + /** + * Sets the clear. + * @param clear The clear to set. + */ + public void setClear(boolean clear) { + this.clear = clear; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/context/DefaultContext.java b/Server/src/main/core/net/packet/context/DefaultContext.java new file mode 100644 index 0000000..6d12eb5 --- /dev/null +++ b/Server/src/main/core/net/packet/context/DefaultContext.java @@ -0,0 +1,56 @@ +package core.net.packet.context; + +import core.game.node.entity.player.Player; +import core.net.packet.Context; + +/** + * Represents a default context of a packet. + * @author 'Vexia + */ +public class DefaultContext implements Context { + /** + * Represents the {@link Player} instance. + */ + private Player player; + /** + * Represents the array of objects casted. + */ + private Object[] objects; + + /** + * Constructs a new {@code DefaultContext.java} {@code Object}. + * @param player the player. + * @param objects the objects. + */ + public DefaultContext(Player player, Object... objects) { + this.player = player; + this.objects = objects; + } + + @Override + public Player getPlayer() { + return player; + } + + /** + * @return the objects. + */ + public Object[] getObjects() { + return objects; + } + + /** + * @param player the player to set. + */ + public void setPlayer(Player player) { + this.player = player; + } + + /** + * @param objects the objects to set. + */ + public void setObjects(Object[] objects) { + this.objects = objects; + } + +} diff --git a/Server/src/main/core/net/packet/context/DisplayModelContext.java b/Server/src/main/core/net/packet/context/DisplayModelContext.java new file mode 100644 index 0000000..4910239 --- /dev/null +++ b/Server/src/main/core/net/packet/context/DisplayModelContext.java @@ -0,0 +1,174 @@ +package core.net.packet.context; + +import core.game.node.entity.player.Player; +import core.net.packet.Context; + +/** + * Represents the player on interface context. + * @author Emperor + */ +public class DisplayModelContext implements Context { + + /** + * Represents the model types. + * @author Emperor + */ + public static enum ModelType { + PLAYER, NPC, ITEM, MODEL; + } + + /** + * The player reference. + */ + private final Player player; + + /** + * The model type. + */ + private final ModelType type; + + /** + * The node id. + */ + private final int nodeId; + + /** + * The amount (for item display). + */ + private int amount; + + /** + * The zoom. + */ + private int zoom; + + /** + * The interface id. + */ + private final int interfaceId; + + /** + * The child id. + */ + private final int childId; + + /** + * Construct a new {@code DisplayModelContext} {@code Object} used for + * displaying the player. + * @param player The player reference. + * @param interfaceId The interface id. + * @param childId The child id. + */ + public DisplayModelContext(Player player, int interfaceId, int childId) { + this(player, ModelType.PLAYER, -1, 0, interfaceId, childId); + } + + /** + * Construct a new {@code DisplayModelContext} {@code Object} used for + * displaying an NPC. + * @param player The player reference. + * @param nodeId The node id to display. + * @param interfaceId The interface id. + * @param childId The child id. + */ + public DisplayModelContext(Player player, int nodeId, int interfaceId, int childId) { + this(player, ModelType.NPC, nodeId, 0, interfaceId, childId); + } + + /** + * Construct a new {@code DisplayModelContext} {@code Object} used by the + * other constructors or for displaying an item. + * @param player The player reference. + * @param type The model type. + * @param nodeId The node id to display. + * @param amount The amount. + * @param interfaceId The interface id. + * @param childId The child id. + */ + public DisplayModelContext(Player player, ModelType type, int nodeId, int amount, int interfaceId, int childId) { + this.player = player; + this.type = type; + this.nodeId = nodeId; + this.amount = amount; + this.interfaceId = interfaceId; + this.childId = childId; + } + + /** + * Construct a new {@code DisplayModelContext} {@code Object} used by the + * other constructors or for displaying an item. + * @param player The player reference. + * @param type The model type. + * @param nodeId The node id to display. + * @param interfaceId The interface id. + * @param childId The child id. + */ + public DisplayModelContext(Player player, ModelType type, int nodeId, int zoom, int interfaceId, int childId, Object... object) { + this.player = player; + this.type = type; + this.nodeId = nodeId; + this.setZoom(zoom); + this.interfaceId = interfaceId; + this.childId = childId; + } + + @Override + public Player getPlayer() { + return player; + } + + /** + * Gets the type. + * @return The type. + */ + public ModelType getType() { + return type; + } + + /** + * Gets the nodeId. + * @return The nodeId. + */ + public int getNodeId() { + return nodeId; + } + + /** + * Gets the amount. + * @return The amount. + */ + public int getAmount() { + return amount; + } + + /** + * Get the interface id. + * @return The interface id. + */ + public int getInterfaceId() { + return interfaceId; + } + + /** + * Get the child id. + * @return The child id. + */ + public int getChildId() { + return childId; + } + + /** + * @return the zoom. + */ + public int getZoom() { + return zoom; + } + + /** + * @param zoom the zoom to set. + */ + public void setZoom(int zoom) { + this.zoom = zoom; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/context/DynamicSceneContext.java b/Server/src/main/core/net/packet/context/DynamicSceneContext.java new file mode 100644 index 0000000..7c2c5bf --- /dev/null +++ b/Server/src/main/core/net/packet/context/DynamicSceneContext.java @@ -0,0 +1,20 @@ +package core.net.packet.context; + +import core.game.node.entity.player.Player; + +/** + * Represents the packet context for the build dynamic scene graph packet. + * @author Emperor + */ +public final class DynamicSceneContext extends SceneGraphContext { + + /** + * Constructs a new {@code DynamicSceneContext} {@code Object}. + * @param player The player. + * @param login If the player is logging in. + */ + public DynamicSceneContext(Player player, boolean login) { + super(player, login); + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/context/GameMessageContext.java b/Server/src/main/core/net/packet/context/GameMessageContext.java new file mode 100644 index 0000000..c807b68 --- /dev/null +++ b/Server/src/main/core/net/packet/context/GameMessageContext.java @@ -0,0 +1,44 @@ +package core.net.packet.context; + +import core.game.node.entity.player.Player; +import core.net.packet.Context; + +/** + * The game message packet context. + * @author Emperor + */ +public final class GameMessageContext implements Context { + + /** + * The player reference. + */ + private Player player; + + /** + * The game message. + */ + private String message; + + /** + * Construct a new {@code GameMessageContext} {@code Object}. + * @param player The player. + * @param message The game message. + */ + public GameMessageContext(Player player, String message) { + this.player = player; + this.message = message; + } + + @Override + public Player getPlayer() { + return player; + } + + /** + * Get the game message. + * @return The game message. + */ + public String getMessage() { + return message; + } +} diff --git a/Server/src/main/core/net/packet/context/GrandExchangeContext.java b/Server/src/main/core/net/packet/context/GrandExchangeContext.java new file mode 100644 index 0000000..9caba3e --- /dev/null +++ b/Server/src/main/core/net/packet/context/GrandExchangeContext.java @@ -0,0 +1,52 @@ +package core.net.packet.context; + +import core.game.node.entity.player.Player; +import core.net.packet.Context; + +/** + * The packet context of the grand exchange update packet. + * @author Emperor + */ +public class GrandExchangeContext implements Context { + + /** + * The player. + */ + private final Player player; + + public final byte idx; + public final byte state; + public final short itemID; + public final boolean isSell; + public final int value; + public final int amt; + public final int completedAmt; + public final int totalCoinsExchanged; + + /** + * Constructs a new {@code GrandExchangeContext} {@code Object}. + * @param player The player. + * @param state + * @param itemID + * @param value + * @param amt + * @param completedAmt + * @param totalCoinsExchanged + */ + public GrandExchangeContext(Player player, byte idx, byte state, short itemID, boolean isSell, int value, int amt, int completedAmt, int totalCoinsExchanged) { + this.player = player; + this.idx = idx; + this.state = state; + this.itemID = itemID; + this.isSell = isSell; + this.value = value; + this.amt = amt; + this.completedAmt = completedAmt; + this.totalCoinsExchanged = totalCoinsExchanged; + } + + @Override + public Player getPlayer() { + return player; + } +} diff --git a/Server/src/main/core/net/packet/context/HintIconContext.java b/Server/src/main/core/net/packet/context/HintIconContext.java new file mode 100644 index 0000000..2902219 --- /dev/null +++ b/Server/src/main/core/net/packet/context/HintIconContext.java @@ -0,0 +1,198 @@ +package core.net.packet.context; + +import core.game.node.Node; +import core.game.node.entity.Entity; +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.net.packet.Context; + +/** + * Represents the hint icon packet context. + * @author Emperor + */ +public final class HintIconContext implements Context { + + /** + * The player. + */ + private final Player player; + + /** + * The hint icon slot. + */ + private final int slot; + + /** + * The target type. + */ + private int targetType; + + /** + * The arrow id. + */ + private int arrowId; + + /** + * The entity index. + */ + private final int index; + + /** + * The model id. + */ + private final int modelId; + + /** + * The location. + */ + private final Location location; + + /** + * The height. + */ + private int height; + + /** + * Constructs a new {@code HintIconContext} {@code Object}.
This hint + * icon is entity based. + * @param player The player. + * @param slot The hint icon slot. + * @param arrowId The arrow id. + * @param target The target. + * @param modelId The model id. + */ + public HintIconContext(Player player, int slot, int arrowId, Node target, int modelId) { + this(player, slot, arrowId, -1, target, modelId); + targetType = 2; + if (target instanceof Entity) { + targetType = target instanceof Player ? 10 : 1; + } + } + + /** + * Constructs a new {@code HintIconContext} {@code Object}.
This hint + * icon is entity based. + * @param player The player. + * @param slot The hint icon slot. + * @param arrowId The arrow id. + * @param targetType The target type. + * @param target The index of the entity. + * @param modelId The model id. + */ + public HintIconContext(Player player, int slot, int arrowId, int targetType, Node target, int modelId) { + this(player, slot, arrowId, targetType, target, modelId, 0); + } + + /** + * Constructs a new {@code HintIconContext} {@code Object}.
This hint + * icon is entity based. + * @param player The player. + * @param slot The hint icon slot. + * @param arrowId The arrow id. + * @param targetType The target type. + * @param target The index of the entity. + * @param modelId The model id. + * @param height The height. + */ + public HintIconContext(Player player, int slot, int arrowId, int targetType, Node target, int modelId, int height) { + this.player = player; + this.slot = slot; + this.targetType = targetType; + this.arrowId = arrowId; + this.modelId = modelId; + this.height = height; + if (target instanceof Entity) { + this.index = ((Entity) target).getIndex(); + this.location = null; + } else { + this.location = target.getLocation(); + this.index = -1; + } + } + + @Override + public Player getPlayer() { + return player; + } + + /** + * Gets the slot. + * @return The slot. + */ + public int getSlot() { + return slot; + } + + /** + * Gets the targetType. + * @return The targetType. + */ + public int getTargetType() { + return targetType; + } + + /** + * Gets the arrowId. + * @return The arrowId. + */ + public int getArrowId() { + return arrowId; + } + + /** + * Gets the index. + * @return The index. + */ + public int getIndex() { + return index; + } + + /** + * Gets the modelId. + * @return The modelId. + */ + public int getModelId() { + return modelId; + } + + /** + * Gets the location. + * @return The location. + */ + public Location getLocation() { + return location; + } + + /** + * Sets the targetType. + * @param targetType The targetType to set. + */ + public void setTargetType(int targetType) { + this.targetType = targetType; + } + + /** + * Sets the arrowId. + * @param arrowId The arrowId to set. + */ + public void setArrowId(int arrowId) { + this.arrowId = arrowId; + } + + /** + * Gets the height. + * @return The height. + */ + public int getHeight() { + return height; + } + + /** + * Sets the height. + * @param height The height to set. + */ + public void setHeight(int height) { + this.height = height; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/context/IntegerContext.java b/Server/src/main/core/net/packet/context/IntegerContext.java new file mode 100644 index 0000000..b30d250 --- /dev/null +++ b/Server/src/main/core/net/packet/context/IntegerContext.java @@ -0,0 +1,51 @@ +package core.net.packet.context; + +import core.game.node.entity.player.Player; +import core.net.packet.Context; + +/** + * The Integer context. + * @author 'Vexia + */ +public class IntegerContext implements Context { + + /** + * The player instance. + */ + private Player player; + + /** + * The integer value. + */ + private int integer; + + /** + * Constructs a new {@code IntegerContext.java} {@code Object}. + * @param player the player. + * @param integer the integer. + */ + public IntegerContext(Player player, int integer) { + this.player = player; + this.setInteger(integer); + } + + @Override + public Player getPlayer() { + return player; + } + + /** + * @return the integer. + */ + public int getInteger() { + return integer; + } + + /** + * @param integer the integer to set. + */ + public void setInteger(int integer) { + this.integer = integer; + } + +} diff --git a/Server/src/main/core/net/packet/context/InteractionOptionContext.java b/Server/src/main/core/net/packet/context/InteractionOptionContext.java new file mode 100644 index 0000000..c57fc6b --- /dev/null +++ b/Server/src/main/core/net/packet/context/InteractionOptionContext.java @@ -0,0 +1,74 @@ +package core.net.packet.context; + +import core.game.node.entity.player.Player; +import core.net.packet.Context; + +/** + * The context implementation used for the InteractionOption outgoing packet. + * @author Emperor + */ +public final class InteractionOptionContext implements Context { + + /** + * The player reference. + */ + private final Player player; + + /** + * The index. + */ + private final int index; + + private boolean remove = false; + + /** + * The name. + */ + private final String name; + + /** + * Constructs a new {@code InteractionOptionContext} {@code Object}. + * @param player The player. + * @param index The index. + * @param name The option name. + */ + public InteractionOptionContext(Player player, int index, String name) { + this.player = player; + this.index = index; + this.name = name; + this.remove = false; + } + + public InteractionOptionContext(Player player, int index, String name, boolean remove){ + this.player = player; + this.index = index; + this.name = name; + this.remove = remove; + } + + @Override + public Player getPlayer() { + return player; + } + + public boolean isRemove() { + return remove; + } + + /** + * Gets the index. + * @return The index. + */ + public int getIndex() { + return index; + } + + /** + * Gets the name. + * @return The name. + */ + public String getName() { + return name; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/context/InterfaceConfigContext.java b/Server/src/main/core/net/packet/context/InterfaceConfigContext.java new file mode 100644 index 0000000..b31de89 --- /dev/null +++ b/Server/src/main/core/net/packet/context/InterfaceConfigContext.java @@ -0,0 +1,74 @@ +package core.net.packet.context; + +import core.game.node.entity.player.Player; +import core.net.packet.Context; + +/** + * The interface config packet context. + * @author Emperor + */ +public class InterfaceConfigContext implements Context { + + /** + * The player reference. + */ + private Player player; + + /** + * The interface id. + */ + private int interfaceId; + + /** + * The child id. + */ + private int childId; + + /** + * If the interface child should be hidden. + */ + private boolean hide; + + /** + * Construct a new {@code InterfaceConfigContext} {@code Object}. + * @param player The player reference. + * @param interfaceId The interface id. + * @param childId The child id. + * @param hide If the component should be hidden. + */ + public InterfaceConfigContext(Player player, int interfaceId, int childId, boolean hide) { + this.player = player; + this.interfaceId = interfaceId; + this.childId = childId; + this.hide = hide; + } + + /** + * Get the interface id. + * @return The interface id. + */ + public int getInterfaceId() { + return interfaceId; + } + + /** + * Get the child id. + * @return The child id. + */ + public int getChildId() { + return childId; + } + + /** + * If is set. + * @return If is set {@code true}. + */ + public boolean isHidden() { + return hide; + } + + @Override + public Player getPlayer() { + return player; + } +} diff --git a/Server/src/main/core/net/packet/context/InterfaceContext.java b/Server/src/main/core/net/packet/context/InterfaceContext.java new file mode 100644 index 0000000..3fb1573 --- /dev/null +++ b/Server/src/main/core/net/packet/context/InterfaceContext.java @@ -0,0 +1,118 @@ +package core.net.packet.context; + +import core.game.node.entity.player.Player; +import core.net.packet.Context; + +/** + * The interface packet context. + * @author Emperor + */ +public final class InterfaceContext implements Context { + + /** + * The player. + */ + private Player player; + + /** + * The window id. + */ + private final int windowId; + + /** + * The component id. + */ + private int componentId; + + /** + * The interface id. + */ + private final int interfaceId; + + /** + * If the interface can be walked over. + */ + private final boolean walkable; + + /** + * Constructs a new {@code InterfaceContext} {@code Object}. + * @param player The player. + * @param windowId The window id. + * @param componentId The window component id. + * @param interfaceId The interface id. + * @param walkable If we can walk over the interface. + */ + public InterfaceContext(Player player, int windowId, int componentId, int interfaceId, boolean walkable) { + this.player = player; + this.windowId = windowId; + this.componentId = componentId; + this.interfaceId = interfaceId; + this.walkable = walkable; + } + + /** + * Transforms this context for the new player & id. + * @param player The player. + * @param id The new interface id. + * @return The interface context created. + */ + public InterfaceContext transform(Player player, int id) { + return new InterfaceContext(player, windowId, componentId, id, walkable); + } + + @Override + public Player getPlayer() { + return player; + } + + /** + * Sets the player. + * @param player The player. + * @return This context instance. + */ + public Context setPlayer(Player player) { + this.player = player; + return this; + } + + /** + * Gets the windowId. + * @return The windowId. + */ + public int getWindowId() { + return windowId; + } + + /** + * Sets the component id. + * @param componentId The component id. + */ + public void setComponentId(int componentId) { + this.componentId = componentId; + } + + /** + * Gets the componentId. + * @return The componentId. + */ + public int getComponentId() { + return componentId; + } + + /** + * Gets the interfaceId. + * @return The interfaceId. + */ + public int getInterfaceId() { + return interfaceId; + } + + /** + * Gets the walkable. + * @return The walkable. + */ + public boolean isWalkable() { + return walkable; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/context/LocationContext.java b/Server/src/main/core/net/packet/context/LocationContext.java new file mode 100644 index 0000000..d683469 --- /dev/null +++ b/Server/src/main/core/net/packet/context/LocationContext.java @@ -0,0 +1,61 @@ +package core.net.packet.context; + +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.net.packet.Context; + +/** + * Packet context used for location based packets. + * @author Emperor + */ +public final class LocationContext implements Context { + + /** + * The player. + */ + private final Player player; + + /** + * The location. + */ + private final Location location; + + /** + * If the location update is flagged as a teleport. + */ + private final boolean teleport; + + /** + * Constructs a new {@code LocationContext} {@code Object}. + * @param player The player. + * @param location The location. + * @param teleport If the location update is flagged as a teleport. + */ + public LocationContext(Player player, Location location, boolean teleport) { + this.player = player; + this.location = location; + this.teleport = teleport; + } + + @Override + public Player getPlayer() { + return player; + } + + /** + * Gets the location. + * @return The location. + */ + public Location getLocation() { + return location; + } + + /** + * Gets the teleport. + * @return The teleport. + */ + public boolean isTeleport() { + return teleport; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/context/MessageContext.java b/Server/src/main/core/net/packet/context/MessageContext.java new file mode 100644 index 0000000..ecc514c --- /dev/null +++ b/Server/src/main/core/net/packet/context/MessageContext.java @@ -0,0 +1,119 @@ +package core.net.packet.context; + +import core.game.node.entity.player.Player; +import core.game.node.entity.player.info.Rights; +import core.net.packet.Context; + +/** + * Packet context for communication message packets. + * @author Emperor + */ +public final class MessageContext implements Context { + + /** + * Represents the packet id to use when sending a message. + */ + public static final int SEND_MESSAGE = 71; + + /** + * Represents the packet id to use when receiving a message. + */ + public static final int RECIEVE_MESSAGE = 0; + + /** + * Represents the packet id use to send a clan message. + */ + public static final int CLAN_MESSAGE = 54; + + /** + * The player. + */ + private final Player player; + + /** + * The other player. + */ + private final String other; + + /** + * The chat icon. + */ + private final int chatIcon; + + /** + * The opcode. + */ + private final int opcode; + + /** + * The message. + */ + private final String message; + + /** + * Constructs a new MessageContext Object. + * @param player The player. + * @param other The communicated player. + * @param opcode The opcode. + * @param message The message. + */ + public MessageContext(Player player, Player other, int opcode, String message) { + this.player = player; + this.other = other.getName(); + this.chatIcon = Rights.getChatIcon(other); + this.opcode = opcode; + this.message = message; + } + + /** + * Constructs a new MessageContext Object. + * @param player The player. + * @param other The communicated player. + * @param opcode The opcode. + * @param message The message. + */ + public MessageContext(Player player, String other, int chatIcon, int opcode, String message) { + this.player = player; + this.other = other; + this.chatIcon = chatIcon; + this.opcode = opcode; + this.message = message; + } + + @Override + public Player getPlayer() { + return player; + } + + /** + * Gets the other. + * @return The other. + */ + public String getOther() { + return other; + } + + /** + * Gets the opcode. + * @return The opcode. + */ + public int getOpcode() { + return opcode; + } + + /** + * Gets the message. + * @return The message. + */ + public String getMessage() { + return message; + } + + /** + * Gets the chatIcon. + * @return the chatIcon + */ + public int getChatIcon() { + return chatIcon; + } +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/context/MinimapStateContext.java b/Server/src/main/core/net/packet/context/MinimapStateContext.java new file mode 100644 index 0000000..6b0441c --- /dev/null +++ b/Server/src/main/core/net/packet/context/MinimapStateContext.java @@ -0,0 +1,45 @@ +package core.net.packet.context; + +import core.game.node.entity.player.Player; +import core.net.packet.Context; + +/** + * Represents the context used for the Minimap State packet. + * @author Emperor + */ +public class MinimapStateContext implements Context { + + /** + * The player. + */ + private final Player player; + + /** + * The minimap state to set. + */ + private final int state; + + /** + * Constructs a new {@code MinimapStateContext} {@code Object}. + * @param player The player. + * @param state The minimap state to set. + */ + public MinimapStateContext(Player player, int state) { + this.player = player; + this.state = state; + } + + @Override + public Player getPlayer() { + return player; + } + + /** + * Gets the state. + * @return The state. + */ + public int getState() { + return state; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/context/MusicContext.java b/Server/src/main/core/net/packet/context/MusicContext.java new file mode 100644 index 0000000..c19336a --- /dev/null +++ b/Server/src/main/core/net/packet/context/MusicContext.java @@ -0,0 +1,78 @@ +package core.net.packet.context; + +import core.game.node.entity.player.Player; +import core.net.packet.Context; + +/** + * Packet context for music. + * @author Emperor + * @author SonicForce41 + */ +public class MusicContext implements Context { + + /** + * The Player + */ + private Player player; + + /** + * The music Id + */ + private int musicId; + + /** + * The secondary music type. + */ + private boolean secondary; + + /** + * Constructs a new {@code MusicContext} {@code Object}. + * @param player The player. + * @param musicId The music id. + */ + public MusicContext(Player player, int musicId) { + this(player, musicId, false); + } + + /** + * Constructs a new {@code MusicContext} {@code Object}. + * @param player The player. + * @param musicId The music id. + * @param temporary The temporary music type. + */ + public MusicContext(Player player, int musicId, boolean temporary) { + this.player = player; + this.musicId = musicId; + this.secondary = temporary; + } + + /** + * Gets the Music Id + * @return the musicId + */ + public final int getMusicId() { + return musicId; + } + + @Override + public Player getPlayer() { + return player; + } + + /** + * Gets the secondary. + * @return The secondary. + */ + public boolean isSecondary() { + return secondary; + } + + /** + * Sets the secondary. + * @param secondary The secondary to set. + */ + public void setSecondary(boolean secondary) { + this.secondary = secondary; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/context/PlayerContext.java b/Server/src/main/core/net/packet/context/PlayerContext.java new file mode 100644 index 0000000..bf700e9 --- /dev/null +++ b/Server/src/main/core/net/packet/context/PlayerContext.java @@ -0,0 +1,30 @@ +package core.net.packet.context; + +import core.game.node.entity.player.Player; +import core.net.packet.Context; + +/** + * The default packet context. + * @author Emperor + */ +public final class PlayerContext implements Context { + + /** + * The player. + */ + private final Player player; + + /** + * Constructs a new {@code PlayerContext} {@code Object}. + * @param player The player. + */ + public PlayerContext(Player player) { + this.player = player; + } + + @Override + public Player getPlayer() { + return player; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/context/PositionedGraphicContext.java b/Server/src/main/core/net/packet/context/PositionedGraphicContext.java new file mode 100644 index 0000000..738eeea --- /dev/null +++ b/Server/src/main/core/net/packet/context/PositionedGraphicContext.java @@ -0,0 +1,67 @@ +package core.net.packet.context; + +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Graphics; +import core.net.packet.Context; + +/** + * The packet context for the positioned graphic packet. + * @author Emperor + */ +public final class PositionedGraphicContext implements Context { + + /** + * The player. + */ + private final Player player; + + /** + * The graphics. + */ + private final Graphics graphic; + + /** + * The location. + */ + private final Location location; + + public int sceneX, sceneY; + public int offsetX, offsetY; + + /** + * Constructs a new {@code PositionedGraphicContext} {@code Object}. + * @param player The player. + * @param graphic The graphic to display on the given location. + * @param location The location to display the graphic on. + */ + public PositionedGraphicContext(Player player, Graphics graphic, Location location, int offsetX, int offsetY) { + this.player = player; + this.graphic = graphic; + this.location = location; + this.sceneX = location.getSceneX(player.getPlayerFlags().getLastSceneGraph()); + this.sceneY = location.getSceneY(player.getPlayerFlags().getLastSceneGraph()); + this.offsetX = offsetX; + this.offsetY = offsetY; + } + + @Override + public Player getPlayer() { + return player; + } + + /** + * @return the graphic + */ + public Graphics getGraphic() { + return graphic; + } + + /** + * @return the location + */ + public Location getLocation() { + return location; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/context/RunScriptContext.java b/Server/src/main/core/net/packet/context/RunScriptContext.java new file mode 100644 index 0000000..295bf38 --- /dev/null +++ b/Server/src/main/core/net/packet/context/RunScriptContext.java @@ -0,0 +1,84 @@ +package core.net.packet.context; + +import core.game.node.entity.player.Player; +import core.net.packet.Context; + +/** + * The run script packet context. + * @author Emperor + */ +public class RunScriptContext implements Context { + + /** + * The player reference. + */ + private Player player; + + /** + * The run script id. + */ + private int id; + + /** + * The parameters. + */ + private Object[] objects; + + /** + * The string. + */ + private String string; + + /** + * Construct a new {@code RunScriptContext} {@code Object}. + * @param player + * @param id + * @param string + * @param objects + */ + public RunScriptContext(Player player, int id, String string, Object... objects) { + this.player = player; + this.id = id; + this.objects = objects; + this.string = string; + } + + @Override + public Player getPlayer() { + return player; + } + + /** + * Sets the player. + * @param player The player. + * @return This context instance. + */ + public Context setPlayer(Player player) { + this.player = player; + return this; + } + + /** + * Get the run scripts id. + * @return The run scripts id. + */ + public int getId() { + return id; + } + + /** + * Get the objects. + * @return The objects. + */ + public Object[] getObjects() { + return objects; + } + + /** + * Get the string. + * @return The string. + */ + public String getString() { + return string; + } +} diff --git a/Server/src/main/core/net/packet/context/SceneGraphContext.java b/Server/src/main/core/net/packet/context/SceneGraphContext.java new file mode 100644 index 0000000..25783cb --- /dev/null +++ b/Server/src/main/core/net/packet/context/SceneGraphContext.java @@ -0,0 +1,45 @@ +package core.net.packet.context; + +import core.game.node.entity.player.Player; +import core.net.packet.Context; + +/** + * The update scene graph packet context. + * @author Emperor + */ +public class SceneGraphContext implements Context { + + /** + * The player. + */ + private final Player player; + + /** + * If we are logging in. + */ + private final boolean login; + + /** + * Constructs a new {@code SceneGraphContext} {@code Object}. + * @param player The player. + * @param login If we are logging in. + */ + public SceneGraphContext(Player player, boolean login) { + this.player = player; + this.login = login; + } + + @Override + public Player getPlayer() { + return player; + } + + /** + * Gets the login. + * @return The login. + */ + public boolean isLogin() { + return login; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/context/SkillContext.java b/Server/src/main/core/net/packet/context/SkillContext.java new file mode 100644 index 0000000..d359606 --- /dev/null +++ b/Server/src/main/core/net/packet/context/SkillContext.java @@ -0,0 +1,45 @@ +package core.net.packet.context; + +import core.game.node.entity.player.Player; +import core.net.packet.Context; + +/** + * The skill context. + * @author Emperor + */ +public final class SkillContext implements Context { + + /** + * The player. + */ + private final Player player; + + /** + * The skill id. + */ + private final int skillId; + + /** + * Constructs a new {@code SkillContext} {@code Object}. + * @param player The player. + * @param skillId The skill id. + */ + public SkillContext(Player player, int skillId) { + this.player = player; + this.skillId = skillId; + } + + @Override + public Player getPlayer() { + return player; + } + + /** + * Gets the skillId. + * @return The skillId. + */ + public int getSkillId() { + return skillId; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/context/StringContext.java b/Server/src/main/core/net/packet/context/StringContext.java new file mode 100644 index 0000000..b311ef0 --- /dev/null +++ b/Server/src/main/core/net/packet/context/StringContext.java @@ -0,0 +1,74 @@ +package core.net.packet.context; + +import core.game.node.entity.player.Player; +import core.net.packet.Context; + +/** + * The StringPacket packet context. + * @author Emperor + */ +public class StringContext implements Context { + + /** + * The player reference. + */ + private Player player; + + /** + * The StringPacket string. + */ + private String string; + + /** + * The interface id. + */ + private int interfaceId; + + /** + * The line id. + */ + private int lineId; + + /** + * Constructs a new {@code StringContext} {@code Object}. + * @param player The player. + * @param string The string to send. + * @param interfaceId The interface id. + * @param lineId The child id. + */ + public StringContext(Player player, String string, int interfaceId, int lineId) { + this.player = player; + this.string = string; + this.interfaceId = interfaceId; + this.lineId = lineId; + } + + @Override + public Player getPlayer() { + return player; + } + + /** + * Get the StringPacket string. + * @return The string. + */ + public String getString() { + return string; + } + + /** + * Get the interface id. + * @return The interface id. + */ + public int getInterfaceId() { + return interfaceId; + } + + /** + * Gets the line id. + * @return The line id. + */ + public int getLineId() { + return lineId; + } +} diff --git a/Server/src/main/core/net/packet/context/SystemUpdateContext.java b/Server/src/main/core/net/packet/context/SystemUpdateContext.java new file mode 100644 index 0000000..5e6ab11 --- /dev/null +++ b/Server/src/main/core/net/packet/context/SystemUpdateContext.java @@ -0,0 +1,51 @@ +package core.net.packet.context; + +import core.game.node.entity.player.Player; +import core.net.packet.Context; + +/** + * Represents a system update. + * @author 'Vexia + */ +public class SystemUpdateContext implements Context { + + /** + * The Player instance. + */ + private Player player; + + /** + * The time. + */ + private int time; + + /** + * Constructs a new {@code SystemUpdateContext.java} {@code Object}. + * @param player the Player. + * @param time the time. + */ + public SystemUpdateContext(Player player, int time) { + this.player = player; + this.setTime(time); + } + + @Override + public Player getPlayer() { + return player; + } + + /** + * @return the time + */ + public int getTime() { + return time; + } + + /** + * @param time the time to set + */ + public void setTime(int time) { + this.time = time; + } + +} diff --git a/Server/src/main/core/net/packet/context/VarbitContext.java b/Server/src/main/core/net/packet/context/VarbitContext.java new file mode 100644 index 0000000..5a551ee --- /dev/null +++ b/Server/src/main/core/net/packet/context/VarbitContext.java @@ -0,0 +1,22 @@ +package core.net.packet.context; + +import core.game.node.entity.player.Player; +import core.net.packet.Context; + +public class VarbitContext implements Context { + + Player player; + public int varbitId; + public int value; + + public VarbitContext(Player player, int varbitId, int value){ + this.player = player; + this.varbitId = varbitId; + this.value = value; + } + + @Override + public Player getPlayer() { + return player; + } +} diff --git a/Server/src/main/core/net/packet/context/VarcUpdateContext.java b/Server/src/main/core/net/packet/context/VarcUpdateContext.java new file mode 100644 index 0000000..4a4d9ed --- /dev/null +++ b/Server/src/main/core/net/packet/context/VarcUpdateContext.java @@ -0,0 +1,23 @@ +package core.net.packet.context; + +import core.game.node.entity.player.Player; +import core.net.packet.Context; + +public class VarcUpdateContext implements Context { + + Player player; + public int varcId; + public int value; + + public VarcUpdateContext(Player player, int varcId, int value){ + this.player = player; + this.varcId = varcId; + this.value = value; + } + + @Override + public Player getPlayer() { + return player; + } +} + diff --git a/Server/src/main/core/net/packet/context/WalkOptionContext.java b/Server/src/main/core/net/packet/context/WalkOptionContext.java new file mode 100644 index 0000000..e95546c --- /dev/null +++ b/Server/src/main/core/net/packet/context/WalkOptionContext.java @@ -0,0 +1,45 @@ +package core.net.packet.context; + +import core.game.node.entity.player.Player; +import core.net.packet.Context; + +/** + * Represents the set walk-to option context. + * @author Emperor + */ +public final class WalkOptionContext implements Context { + + /** + * The player. + */ + private final Player player; + + /** + * The option. + */ + private final String option; + + /** + * Constructs a new {@code WalkOptionContext} {@code Object}. + * @param player The player. + * @param option The option name. + */ + public WalkOptionContext(Player player, String option) { + this.player = player; + this.option = option; + } + + @Override + public Player getPlayer() { + return player; + } + + /** + * Gets the option. + * @return The option. + */ + public String getOption() { + return option; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/context/WindowsPaneContext.java b/Server/src/main/core/net/packet/context/WindowsPaneContext.java new file mode 100644 index 0000000..03bba3e --- /dev/null +++ b/Server/src/main/core/net/packet/context/WindowsPaneContext.java @@ -0,0 +1,60 @@ +package core.net.packet.context; + +import core.game.node.entity.player.Player; +import core.net.packet.Context; + +/** + * Represents the windows pane packet context. + * @author Emperor + */ +public final class WindowsPaneContext implements Context { + + /** + * The player. + */ + private final Player player; + + /** + * The window id. + */ + private final int windowId; + + /** + * The type. + */ + private final int type; + + /** + * Constructs a new {@code WindowsPaneContext} object. + * @param player The player. + * @param windowId The window id. + * @param type The type. + */ + public WindowsPaneContext(Player player, int windowId, int type) { + this.player = player; + this.windowId = windowId; + this.type = type; + } + + @Override + public Player getPlayer() { + return player; + } + + /** + * Gets the windowId. + * @return The windowId. + */ + public int getWindowId() { + return windowId; + } + + /** + * Gets the type. + * @return The type. + */ + public int getType() { + return type; + } + +} diff --git a/Server/src/main/core/net/packet/in/Decoders530.kt b/Server/src/main/core/net/packet/in/Decoders530.kt new file mode 100644 index 0000000..6181f25 --- /dev/null +++ b/Server/src/main/core/net/packet/in/Decoders530.kt @@ -0,0 +1,804 @@ +package core.net.packet.`in` + +import core.api.log +import core.Util.clamp +import core.game.node.entity.player.Player +import core.net.packet.IoBuffer +import core.tools.Log +import core.tools.StringUtils +import core.tools.SystemLogger +import java.io.PrintWriter +import java.io.StringWriter +import java.nio.BufferUnderflowException + +enum class Decoders530(val opcode: Int) { + /****************************************** + * ITEM INTERACTIONS + ******************************************/ + ITEM_ACTION_1(156) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val slot = buffer.leShortA + val itemId = buffer.shortA + val ifHash = buffer.leInt + val (iface, button) = deHash(ifHash) + return Packet.ItemAction(player, 0, itemId, slot, iface, button) + } + }, + ITEM_ACTION_2(55) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val itemId = buffer.leShort + val slot = buffer.shortA + val ifHash = buffer.intA + val (iface, button) = deHash(ifHash) + return Packet.ItemAction(player, 1, itemId, slot, iface, button) + } + }, + ITEM_ACTION_3(153) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val ifHash = buffer.leInt + val slot = buffer.leShort + val itemId = buffer.leShort + val (iface, button) = deHash(ifHash) + return Packet.ItemAction(player, 2, itemId, slot, iface, button) + } + }, + ITEM_ACTION_4(161) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val ifHash = buffer.leInt + val itemId = buffer.leShortA + val slot = buffer.leShortA + val (iface, button) = deHash(ifHash) + return Packet.ItemAction(player, 3, itemId, slot, iface, button) + } + }, + ITEM_ACTION_5(135) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val itemId = buffer.shortA + val slot = buffer.shortA + val ifHash = buffer.intB + val (iface, button) = deHash(ifHash) + return Packet.ItemAction(player, 4, itemId, slot, iface, button) + } + }, + + + + /****************************************** + * NPC INTERACTIONS + ******************************************/ + NPC_ACTION_1(78) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val npcIndex = buffer.leShort + return Packet.NpcAction(player, 0, npcIndex) + } + }, + NPC_ACTION_2(3) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val npcIndex = buffer.leShortA + return Packet.NpcAction(player, 1, npcIndex) + } + }, + NPC_ACTION_3(148) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val npcIndex = buffer.shortA + return Packet.NpcAction(player, 2, npcIndex) + } + }, + NPC_ACTION_4(30) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val npcIndex = buffer.short + return Packet.NpcAction(player, 3, npcIndex) + } + }, + NPC_ACTION_5(218) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val npcIndex = buffer.leShort + return Packet.NpcAction(player, 4, npcIndex) + } + }, + + /****************************************** + * SCENERY INTERACTIONS + ******************************************/ + SCENERY_ACTION_1(254) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val x = buffer.leShort + val objId = buffer.shortA and 0xFFFF + val y = buffer.short + return Packet.SceneryAction(player, 0, objId, x, y) + } + }, + SCENERY_ACTION_2(194) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val y = buffer.leShortA + val x = buffer.leShort + val objId = buffer.short and 0xFFFF + return Packet.SceneryAction(player, 1, objId, x, y) + } + }, + SCENERY_ACTION_3(84) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val objId = buffer.leShortA and 0xFFFF + val y = buffer.leShortA + val x = buffer.leShort + return Packet.SceneryAction(player, 2, objId, x, y) + } + }, + SCENERY_ACTION_4(247) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val y = buffer.leShort and 0xFFFF + val x = buffer.leShortA + val objId = buffer.short and 0xFFFF + return Packet.SceneryAction(player, 3, objId, x, y) + } + }, + SCENERY_ACTION_5(170) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val objId = buffer.leShortA and 0xFFFF + val x = buffer.leShortA + val y = buffer.leShortA + return Packet.SceneryAction(player, 4, objId, x, y) + } + }, + + /****************************************** + * PLAYER INTERACTIONS + ******************************************/ + PLAYER_ACTION_1(68) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val pIndex = buffer.leShortA + return Packet.PlayerAction(player, 0, pIndex) + } + }, + PLAYER_ACTION_3(71) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val pIndex = buffer.leShortA + return Packet.PlayerAction(player, 2, pIndex) + } + }, + PLAYER_ACTION_4(180) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val pIndex = buffer.leShortA + return Packet.PlayerAction(player, 3, pIndex) + } + }, + PLAYER_ACTION_7(114) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val index = buffer.leShortA + return Packet.PlayerAction(player, 6, index) + } + }, + PLAYER_ACTION_8(175) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val pIndex = buffer.shortA + return Packet.PlayerAction(player, 7, pIndex) + } + }, + + /****************************************** + * OBJSTACK (Ground Item) INTERACTIONS + ******************************************/ + OBJSTACK_ACTION_1(66) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val x = buffer.leShort + val itemId = buffer.short + val y = buffer.leShortA + return Packet.GroundItemAction(player, 2, itemId, x, y) + } + }, + OBJSTACK_ACTION_2(33) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val itemId = buffer.short + val x = buffer.short + val y = buffer.leShort + return Packet.GroundItemAction(player, 3, itemId, x, y) + } + }, + + /****************************************** + * USEWITH INTERACTIONS + ******************************************/ + USEWITH_NPC(115) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val ifHash = buffer.intB + val slot = buffer.leShort + val npcIndex = buffer.leShort + val itemId = buffer.leShortA + val (iface, _) = deHash(ifHash) + return Packet.UseWithNpc(player, itemId, npcIndex, iface, slot) + } + }, + USEWIH_PLAYER(248) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val otherIndex = buffer.leShortA + val itemId = buffer.short + val slot = buffer.short + val ifHash = buffer.intB + val (iface, _) = deHash(ifHash) + return Packet.UseWithPlayer(player, itemId, otherIndex, iface, slot) + } + }, + USEWITH_ITEM(27) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val usedSlot = buffer.short + val usedIfHash = buffer.leInt + val usedWithSlot = buffer.leShort + val usedWithIfHash = buffer.leInt + val usedId = buffer.leShortA + val usedWithId = buffer.leShortA + + val (usedIface, usedChild) = deHash(usedIfHash) + val (usedWithIface, usedWithChild) = deHash(usedWithIfHash) + return Packet.UseWithItem( + player, + usedId, usedWithId, + usedSlot, usedWithSlot, + usedIface, usedWithIface, + usedChild, usedWithChild + ) + } + }, + USEWITH_SCENERY(134) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val x = buffer.shortA + val id = buffer.short + val y = buffer.leShort + val slot = buffer.short + buffer.leShort //Suspicious noops? TODO: FIND OUT WHAT THESE ARE + buffer.short + val sceneryId = buffer.shortA + return Packet.UseWithScenery(player, id, slot, sceneryId, x, y) + } + }, + USEWITH_GROUNDITEM(101) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val x = buffer.leShortA + val slot = buffer.leShort + val usedId = buffer.leShort + val usedWithId = buffer.leShort + val y = buffer.leShortA + val ifHash = buffer.intB + val (iface,child) = deHash(ifHash) + return Packet.UseWithGroundItem(player, usedId, usedWithId, iface, child, slot, x, y) + } + }, + + /****************************************** + * INTERFACE INTERACTIONS + ******************************************/ + IF_ACTION_1(155) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val ifHash = buffer.int + val slot = buffer.short + val (iface, button) = deHash(ifHash) + return Packet.IfAction(player, opcode, 0, iface, button, slot) + } + }, + IF_ACTION_2(196) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val ifHash = buffer.int + val slot = buffer.short + val (iface, button) = deHash(ifHash) + return Packet.IfAction(player, opcode, 1, iface, button, slot) + } + }, + IF_ACTION_3(124) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val ifHash = buffer.int + val slot = buffer.short + val (iface, button) = deHash(ifHash) + return Packet.IfAction(player, opcode, 2, iface, button, slot) + } + }, + IF_ACTION_4(199) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val ifHash = buffer.int + val slot = buffer.short + val (iface, button) = deHash(ifHash) + return Packet.IfAction(player, opcode, 3, iface, button, slot) + } + }, + IF_ACTION_5(234) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val ifHash = buffer.int + val slot = buffer.short + val (iface, button) = deHash(ifHash) + return Packet.IfAction(player, opcode, 4, iface, button, slot) + } + }, + IF_ACTION_6(168) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val ifHash = buffer.int + val slot = buffer.short + val (iface, button) = deHash(ifHash) + return Packet.IfAction(player, opcode, 5, iface, button, slot) + } + }, + IF_ACTION_7(166) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val ifHash = buffer.int + val slot = buffer.short + val (iface, button) = deHash(ifHash) + return Packet.IfAction(player, opcode, 6, iface, button, slot) + } + }, + IF_ACTION_8(64) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val ifHash = buffer.int + val slot = buffer.short + val (iface, button) = deHash(ifHash) + return Packet.IfAction(player, opcode, 7, iface, button, slot) + } + }, + IF_ACTION_9(53) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val ifHash = buffer.int + val slot = buffer.short + val (iface, button) = deHash(ifHash) + return Packet.IfAction(player, opcode, 8, iface, button, slot) + } + }, + IF_ACTION_10(9) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val ifHash = buffer.int + val slot = buffer.short + val (iface, button) = deHash(ifHash) + return Packet.IfAction(player, opcode, 9, iface, button, slot) + } + }, + IF_ACTION_CS(10) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val ifHash = buffer.int + val (iface, button) = deHash(ifHash) + return Packet.IfAction(player, opcode, -1, iface, button, -1, -1) + } + }, + CONTINUE_OPT(132) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val ifHash = buffer.intA + val slot = buffer.leShort + val (iface, button) = deHash(ifHash) + return Packet.ContinueOption(player, iface, button, slot, 132) + } + }, + CLOSE_IFACE(184) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + return Packet.CloseIface(player) + } + }, + IF_GROUNDITEM_ACTION(73) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val ifHash = buffer.intA + val (iface, child) = deHash(ifHash) + val y = buffer.short + val itemId = buffer.leShortA + val x = buffer.leShortA + val slot = buffer.leShort + return Packet.ComponentGroundItemAction(player, iface, child, slot, itemId, x, y) + } + }, + IF_PLAYER_ACTION(195) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + buffer.shortA //Arios ignoring more data... nice + val child = buffer.leShort + val iface = buffer.leShort + val otherIndex = buffer.leShortA + return Packet.ComponentPlayerAction(player, otherIndex, iface, child) + } + }, + IF_SCENERY_ACTION(233) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val y = buffer.leShortA + val x = buffer.shortA + val itemId = buffer.leShortA //probably misnamed/mislabeled by Arios. + val ifHash = buffer.intA + val (iface, child) = deHash(ifHash) + val objId = buffer.shortA + return Packet.ComponentSceneryAction(player, iface, child, objId, x, y) + } + }, + IF_NPC_ACTION(239) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val child = buffer.leShort + val iface = buffer.leShort + buffer.shortA //more ignored data.... + val index = buffer.leShortA + return Packet.ComponentNpcAction(player, iface, child, index) + } + }, + IF_ITEM_ACTION(253) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val child = buffer.leShort + val iface = buffer.leShort + val itemSlot = buffer.leShortA + val unused = buffer.leInt //unused??? + val itemId = buffer.shortA + buffer.shortA //more ignored data.... + return Packet.ComponentItemAction(player, iface, child, itemId, itemSlot) + } + }, + SLOTSWITCH_MULTI(79) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val srcHash = buffer.intB + val destSlot = buffer.leShort + val destHash = buffer.int + val srcSlot = buffer.leShort + val (srcIface, srcChild) = deHash(srcHash) + val (destIface, destChild) = deHash(destHash) + return Packet.SlotSwitchMultiComponent(player, srcIface, srcChild, srcSlot, destIface, destChild, destSlot) + } + }, + SLOTSWITCH_SINGLE(231) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val srcSlot = buffer.short + val ifHash = buffer.leInt + val destSlot = buffer.shortA + val isInsert = buffer.get() == 1 + val (iface, child) = deHash(ifHash) + return Packet.SlotSwitchSingleComponent(player, iface, child, srcSlot, destSlot, isInsert) + } + }, + IF_ITEM_OPT_1(81) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val slot = buffer.shortA + val itemId = buffer.short + val child = buffer.short + val iface = buffer.short + return Packet.IfAction(player, opcode, 0, iface, child, slot, itemId) + } + }, + IF_ITEM_OPT_2(206) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val itemId = buffer.shortA + val slot = buffer.leShort + val ifHash = buffer.leInt + val (iface, button) = deHash(ifHash) + return Packet.IfAction(player, opcode, 1, iface, button, slot, itemId) + } + }, + + /****************************************** + * EXAMINE + ******************************************/ + EXAMINE_SCENERY(94) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + return Packet.SceneryExamine(player, buffer.leShortA) + } + }, + EXAMINE_ITEM(92) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + return Packet.ItemExamine(player, buffer.leShortA) + } + }, + EXAMINE_NPC(72) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + return Packet.NpcExamine(player, buffer.short) + } + }, + + /****************************************** + * CLANS + ******************************************/ + CLAN_JOIN(104) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val clanName = StringUtils.longToString(buffer.long) + return Packet.JoinClan(player, clanName) + } + }, + CLAN_SETRANK(188) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val rank = buffer.a + val name = StringUtils.longToString(buffer.long) + return Packet.SetClanRank(player, name, rank) + } + }, + CLAN_KICK(162) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val name = StringUtils.longToString(buffer.long) + return Packet.KickFromClan(player, name) + } + }, + + /****************************************** + * FRIENDS/IGNORES + ******************************************/ + ADD_FRIEND(120) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + return Packet.AddFriend(player, StringUtils.longToString(buffer.long)) + } + }, + REMOVE_FRIEND(57) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + return Packet.RemoveFriend(player, StringUtils.longToString(buffer.long)) + } + }, + ADD_IGNORE(34) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + return Packet.AddIgnore(player, StringUtils.longToString(buffer.long)) + } + }, + REMOVE_IGNORE(213) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + return Packet.RemoveIgnore(player, StringUtils.longToString(buffer.long)) + } + }, + PRIVATE_MESSAGE(201) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val name = StringUtils.longToString(buffer.long) + val message = StringUtils.decryptPlayerChat(buffer, buffer.get() and 0xFF) + return Packet.PrivateMessage(player, name, message) + } + }, + + /****************************************** + * INPUT TRACKING + ******************************************/ + FOCUS_CHANGE(22) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + return Packet.TrackingFocus(player, buffer.get() == 1) + } + }, + CAMERA_MOVEMENT(21) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val x = buffer.shortA + val y = buffer.leShort + return Packet.TrackingCameraPos(player, x, y) + } + }, + DISPLAY_UPDATE(243) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val windowMode = buffer.get() + val screenWidth = buffer.short + val screenHeight = buffer.short + val displayMode = buffer.get() + return Packet.TrackingDisplayUpdate(player, windowMode, screenWidth, screenHeight, displayMode) + } + }, + AFK_TIMEOUT(245) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + return Packet.TrackingAfkTimeout(player) + } + }, + MOUSE_CLICKED(75) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val data = buffer.leShortA + val pos = buffer.intB + val rightClick = ((data shr 15) and 0x1) == 1 + val delay = data and 0x7FF + val x = pos shr 16 + val y = pos and 0xFFFF + return Packet.TrackingMouseClick(player, x, y, rightClick, delay) + } + }, + + /****************************************** + * WALKING + ******************************************/ + WORLDSPACE_WALK(215) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val (running, x, y) = decodeWalkInformation(buffer, false) + return Packet.WorldspaceWalk(player, x, y, running) + } + }, + MINIMAP_WALK(39) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val (running, x, y) = decodeWalkInformation(buffer, true) + val clickedX = buffer.get() + val clickedY = buffer.get() + val rotation = buffer.short + //Unlabeled data ignored by arios + buffer.get() + buffer.get() + buffer.get() + buffer.get() + buffer.short + buffer.short + buffer.get() + buffer.get() + return Packet.MinimapWalk(player, x, y, clickedX, clickedY, rotation, running) + } + }, + INTERACT_WALK(77) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val (running, x, y) = decodeWalkInformation(buffer, false) + return Packet.InteractWalk(player, x, y, running) + } + }, + + /****************************************** + * INPUT PROMPT RESPONSE + ******************************************/ + INPUT_SHORT_STRING_RESPONSE(244) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + return Packet.InputPromptResponse(player, StringUtils.longToString(buffer.long)) + } + }, + INPUT_LONG_STRING_RESPONSE(65) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + return Packet.InputPromptResponse(player, buffer.string) + } + }, + INPUT_INT_RESPONSE(23) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + return Packet.InputPromptResponse(player, buffer.int) + } + }, + + /****************************************** + * ASSORTED + ******************************************/ + GE_SET_OFFER_ITEM(111) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val itemId = buffer.short + return Packet.GESetOfferItem(player, itemId) + } + }, + COMMAND(44) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + if (buffer.toByteBuffer().remaining() > 1) { + try { + val message = buffer.string.lowercase() + return Packet.Command(player, message) + } catch (e: BufferUnderflowException) { + player.sendMessage("Something went wrong there! Please try again.") + return Packet.NoProcess() + } + } + return Packet.NoProcess() + } + }, + CHAT_SETTINGS(157) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + return Packet.ChatSetting( + player, + buffer.get(), + buffer.get(), + buffer.get() + ) + } + }, + CHAT_MESSAGE(237) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val effectPrefix = clamp(buffer.get(), 0, 11) + val effectSuffix = clamp(buffer.get(), 0, 5) + val numChars = buffer.smart + val message = StringUtils.decryptPlayerChat(buffer, numChars) + val effects = (effectPrefix shl 8) or effectSuffix + return Packet.ChatMessage(player, effects, message) + } + }, + MUSIC_TRACK_FINISHED(137) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val trackId = buffer.leShortA + return Packet.TrackFinished(player, trackId) + } + }, + REPORT_ABUSE(99) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val target = StringUtils.longToString(buffer.long) + val ruleId = buffer.get() + val modMute = buffer.get() == 1 + return Packet.ReportAbuse(player, target, ruleId, modMute) + } + }, + UPDATE_PACKET_COUNT(177) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val count = buffer.short + return Packet.PacketCountUpdate(player, count) + } + }, + PING(93) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + return Packet.Ping(player) + } + }, + QUICKCHAT(167) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val x = buffer.toByteBuffer() + + val packetType = when(x.array().size){ + 3,4 -> QCPacketType.STANDARD + 5 -> QCPacketType.SINGLE + 7 -> QCPacketType.DOUBLE + else -> QCPacketType.UNHANDLED.also { log(this::class.java, Log.WARN, "UNHANDLED QC PACKET TYPE Size ${x.array().size}") } + } + + val forClan = (buffer.get() and 0xFF) == 1 + val multiplier: Int = buffer.get() + val offset: Int = buffer.get() + var selection_a_index = -1 + var selection_b_index = -1 + + when(packetType){ + QCPacketType.SINGLE -> { + selection_a_index = buffer.short + } + QCPacketType.DOUBLE -> { + buffer.get() //discard + selection_a_index = buffer.get() + buffer.get() //discard + selection_b_index = buffer.get() + } + QCPacketType.UNHANDLED -> log(this::class.java, Log.WARN, "Unhandled packet type, skipping remaining buffer contents.") + else -> {} + } + return Packet.QuickChat(player, selection_a_index, selection_b_index, forClan, multiplier, offset, packetType) + } + }, + MAP_REBUILD_STARTED(20) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + return Packet.NoProcess() + } + }, + MAP_REBUILD_FINISHED(110) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + return Packet.NoProcess() + } + }, + PLAYER_PREFS_UPDATE(98) { + override fun decode(player: Player, buffer: IoBuffer): Packet { + val prefs = buffer.int + val particleSetting = prefs shr 23 + val ambienceEnabled = (prefs shr 22) and 1 == 1 + val musicEnabled = (prefs shr 21) and 1 == 1 + val soundEnabled = (prefs shr 20) and 1 == 1 + val stereo = (prefs shr 19) and 1 == 1 + val fog = (prefs shr 16) and 1 == 1 + val hdWater = (prefs shr 15) and 1 == 1 + val hdLighting = (prefs shr 13) and 1 == 1 + val shadowType = (prefs shr 11) and 0x3 + val charShadows = (prefs shr 10) and 1 == 1 + val manyGroundTextures = (prefs shr 9) and 1 == 1 + val flickeringEffects = (prefs shr 8) and 1 == 1 + val manyIdleAnims = (prefs shr 7) and 1 == 1 + val hdTextures = (prefs shr 6) and 1 == 1 + val showGroundDeco = (prefs shr 5) and 1 == 1 + val selectiveRoofs = (prefs shr 4) and 1 == 1 + val allLayersVisible = (prefs shr 3) and 1 == 1 + val brightness = prefs and 0x7 + //added in the above so that we don't have to figure it out later, not doing more + //because we currently have genuinely no use for this information. + return Packet.PlayerPrefsUpdate(player, prefs) + } + } + ; + abstract fun decode(player: Player, buffer: IoBuffer): Packet + + fun deHash(ifHash: Int) : Pair { + return Pair(ifHash shr 16, ifHash and 0xFFFF) + } + + fun decodeWalkInformation(buffer: IoBuffer, isMinimap: Boolean) : Triple { + val isRunning = buffer.a == 1 + var x = buffer.short + var y = buffer.shortA + val steps = (buffer.toByteBuffer().remaining() - if (isMinimap) 14 else 0) shr 1 + //derive the final destination by poking the last set of values in the packet (client does its own pathfinding and reports it) + for (i in 0 until steps) { + val offsetX = buffer.a + val offsetY = buffer.s + if (i == steps - 1){ + x += offsetX + y += offsetY + } + } + return Triple(isRunning, x, y) + } + + companion object { + private val opcodeMap = values().associateBy { it.opcode } + + @JvmStatic fun process(player: Player, opcode: Int, buffer: IoBuffer) : Packet { + val decoder = opcodeMap[opcode] ?: return Packet.UnhandledOp() + + return try { + decoder.decode(player, buffer) + } catch (e: Exception) { + val sw = StringWriter() + val pw = PrintWriter(sw) + e.printStackTrace(pw) + Packet.DecodingError("Error decoding opcode $opcode/${decoder.name}: $sw") + } + } + } +} diff --git a/Server/src/main/core/net/packet/in/Login.kt b/Server/src/main/core/net/packet/in/Login.kt new file mode 100644 index 0000000..df243d9 --- /dev/null +++ b/Server/src/main/core/net/packet/in/Login.kt @@ -0,0 +1,222 @@ +package core.net.packet.`in` + +import com.moandjiezana.toml.Toml +import core.cache.crypto.ISAACCipher +import core.cache.crypto.ISAACPair +import core.cache.misc.buffer.ByteBufferUtils +import core.game.node.entity.player.Player +import core.net.Constants +import core.net.IoSession +import core.tools.StringUtils +import core.integrations.discord.Discord +import proto.management.JoinClanRequest +import proto.management.PlayerStatusUpdate +import proto.management.RequestContactInfo +import core.ServerConstants +import core.ServerStore +import core.ServerStore.Companion.addToList +import core.ServerStore.Companion.getList +import core.api.log +import core.auth.AuthResponse +import core.game.node.entity.player.info.* +import core.game.node.entity.player.info.login.LoginParser +import core.tools.SystemLogger +import core.game.world.GameWorld +import core.game.world.repository.Repository +import core.tools.Log +import core.worker.ManagementEvents.publish +import java.io.File +import java.io.IOException +import java.math.BigInteger +import java.nio.BufferUnderflowException +import java.nio.ByteBuffer + +object Login { + private const val ENCRYPTION_VERIFICATION_BYTE: Int = 10 + private const val NORMAL_LOGIN_OP = 16 + private const val RECONNECT_LOGIN_OP = 18 + const val CACHE_INDEX_COUNT = 29 + + private var exceptionData: Toml? = null + private var lastModifiedData = 0L + + fun decodeFromBuffer(buffer: ByteBuffer) : Pair { + try { + val info = LoginInfo.createDefault() + + info.opcode = buffer.get().toInt() + if (buffer.short.toInt() != buffer.remaining()) { + return Pair(AuthResponse.BadSessionID, null) + } + val revision = buffer.int + if (revision != Constants.REVISION) { + return Pair(AuthResponse.Updated, null) + } + if (info.opcode != NORMAL_LOGIN_OP && info.opcode != RECONNECT_LOGIN_OP) { + log(this::class.java, Log.WARN, "Invalid Login Opcode: ${info.opcode}") + return Pair(AuthResponse.InvalidLoginServer, null) + } + + noop(buffer) + info.showAds = buffer.get().toInt() == 1 + noop(buffer) + info.windowMode = buffer.get().toInt() + info.screenWidth = buffer.short.toInt() + info.screenHeight = buffer.short.toInt() + info.displayMode = buffer.get().toInt() + noop(buffer, 24) //Skip past a bunch of random (actually random) data the client sends + ByteBufferUtils.getString(buffer) //same as above + info.adAffiliateId = buffer.int + info.settingsHash = buffer.int + info.currentPacketCount = buffer.short.toInt() + + //Read client-reported CRC sums + for (i in 0 until CACHE_INDEX_COUNT) info.crcSums[i] = buffer.int + + val decryptedBuffer = decryptRSABuffer(buffer, ServerConstants.EXPONENT, ServerConstants.MODULUS) + decryptedBuffer.rewind() + + if (decryptedBuffer.get().toInt() != ENCRYPTION_VERIFICATION_BYTE) { + return Pair(AuthResponse.UnexpectedError, info) + } + + info.isaacPair = produceISAACPairFrom(decryptedBuffer) + info.username = StringUtils.longToString(decryptedBuffer.long) + info.password = ByteBufferUtils.getString(decryptedBuffer) + + if (Repository.getPlayerByName(info.username) != null) { + return Pair(AuthResponse.AlreadyOnline, info) + } + + return Pair(AuthResponse.Success, info) + } catch (buf: BufferUnderflowException) { + //some issue in either the data they sent us or how we read it, either way out of scope of this class's handling. + return Pair(AuthResponse.UnexpectedError, null) + } catch (e: Exception) { + log(this::class.java, Log.ERR, "Exception encountered during login packet parsing! See stack trace below.") + e.printStackTrace() + return Pair(AuthResponse.UnexpectedError, null) + } + } + + private fun produceISAACPairFrom(buffer: ByteBuffer): ISAACPair { + val incomingSeed = IntArray(4) + for(i in incomingSeed.indices) { + incomingSeed[i] = buffer.int + } + val inCipher = ISAACCipher(incomingSeed) + for(i in incomingSeed.indices) { + incomingSeed[i] += 50 + } + val outCipher = ISAACCipher(incomingSeed) + return ISAACPair(inCipher, outCipher) + } + + @JvmStatic fun decryptRSABuffer(buffer: ByteBuffer, exponent: BigInteger, modulus: BigInteger): ByteBuffer { + return try { + val numBytes = buffer.get().toInt() and 0xFF + val encryptedBytes = ByteArray(numBytes) + buffer.get(encryptedBytes) + + val encryptedBigInt = BigInteger(encryptedBytes) + ByteBuffer.wrap(encryptedBigInt.modPow(exponent, modulus).toByteArray()) + } catch (e: BufferUnderflowException) { + ByteBuffer.wrap(byteArrayOf(-1)) + } + } + + private fun noop(buffer: ByteBuffer, amount: Int = 1) {buffer.get(ByteArray(amount))} + + fun proceedWith(session: IoSession, details: PlayerDetails, opcode: Int) { + if (Repository.uid_map.contains(details.uid)) { + session.write(AuthResponse.AlreadyOnline) + return + } + details.session = session + details.info.translate(UIDInfo(details.ipAddress, "DEPRECATED", "DEPRECATED", "DEPRECATED")) + + val archive = ServerStore.getArchive("flagged-ips") + val flaggedIps = archive.getList("ips") + if (flaggedIps.contains(details.ipAddress)) { + Discord.postPlayerAlert(details.username, "Login from flagged IP ${details.ipAddress}") + } + + val player = Player(details) + PlayerMonitor.log(player, LogType.IP_LOG, details.ipAddress) + if (canBypassAccountLimitCheck(player)) { + proceedWithAcceptableLogin(session, player, opcode) + } else { + if (checkAccountLimit(details.ipAddress, details.username)) { + proceedWithAcceptableLogin(session, player, opcode) + } else { + session.write(AuthResponse.LoginLimitExceeded) + } + } + } + + private fun canBypassAccountLimitCheck(player: Player): Boolean { + return player.rights == Rights.ADMINISTRATOR || player.rights == Rights.PLAYER_MODERATOR + } + + private fun proceedWithAcceptableLogin(session: IoSession, player: Player, opcode: Int) { + Repository.addPlayer(player) + session.lastPing = System.currentTimeMillis() + try { + LoginParser(player.details).initialize(player, opcode == RECONNECT_LOGIN_OP) + sendMSEvents(player.details) + } catch (e: Exception) { + e.printStackTrace() + session.disconnect() + } + } + + private fun checkAccountLimit(ipAddress: String, username: String): Boolean { + var accountLimit = ServerConstants.DAILY_ACCOUNT_LIMIT + + if (File(ServerConstants.CONFIG_PATH + "account_limit_exceptions.conf").exists()) { + try { + val f = File(ServerConstants.CONFIG_PATH + "account_limit_exceptions.conf") + if (f.lastModified() != lastModifiedData) { + exceptionData = Toml().read(f) + lastModifiedData = f.lastModified() + } + + if (exceptionData?.contains("exceptions.\"${ipAddress}\"") == true) { + accountLimit = exceptionData?.getLong("exceptions.\"${ipAddress}\"", 0L)?.toInt() ?: accountLimit + } + } catch (e: Exception) { + e.printStackTrace() + } + } + + val archive = ServerStore.getArchive("daily-accounts") + val accounts = archive.getList(ipAddress) + if (username in accounts) return true + + if (accounts.size >= accountLimit) + return false + + archive.addToList(ipAddress, username) + return true + } + + private fun sendMSEvents(details: PlayerDetails) { + val statusEvent = PlayerStatusUpdate.newBuilder() + statusEvent.username = details.username + statusEvent.world = GameWorld.settings!!.worldId + statusEvent.notifyFriendsOnly = false + publish(statusEvent.build()) + + val contactEvent = RequestContactInfo.newBuilder() + contactEvent.username = details.username + contactEvent.world = GameWorld.settings!!.worldId + publish(contactEvent.build()) + + if (!details.communication.currentClan.isNullOrEmpty() && details.communication.clan == null) { + val clanEvent = JoinClanRequest.newBuilder() + clanEvent.username = details.username + clanEvent.clanName = details.communication.currentClan + publish(clanEvent.build()) + } + } +} diff --git a/Server/src/main/core/net/packet/in/LoginInfo.kt b/Server/src/main/core/net/packet/in/LoginInfo.kt new file mode 100644 index 0000000..84d7ba6 --- /dev/null +++ b/Server/src/main/core/net/packet/in/LoginInfo.kt @@ -0,0 +1,30 @@ +package core.net.packet.`in` + +import core.cache.crypto.ISAACCipher +import core.cache.crypto.ISAACPair + +class LoginInfo( + var showAds: Boolean, //Unused + var windowMode : Int, + var screenWidth: Int, + var screenHeight: Int, + var displayMode: Int, + var adAffiliateId: Int, //Unused + var settingsHash: Int, + var currentPacketCount: Int, + var username: String, + var password: String, + var isaacPair: ISAACPair, + var opcode: Int, + var crcSums: IntArray +) { + companion object { + fun createDefault(): LoginInfo { + return LoginInfo(false, 0, 0, 0, 0, 0, 0, 0, "", "", ISAACPair(ISAACCipher(intArrayOf()), ISAACCipher(intArrayOf())), 0, IntArray(Login.CACHE_INDEX_COUNT)) + } + } + + override fun toString(): String { + return "ads:$showAds,wm:$windowMode,sw:$screenWidth,sh:$screenHeight,dm:$displayMode,adid:$adAffiliateId,settings:$settingsHash,pkt:$currentPacketCount,un:$username,pw:$password" + } +} diff --git a/Server/src/main/core/net/packet/in/Packet.kt b/Server/src/main/core/net/packet/in/Packet.kt new file mode 100644 index 0000000..77f4429 --- /dev/null +++ b/Server/src/main/core/net/packet/in/Packet.kt @@ -0,0 +1,60 @@ +package core.net.packet.`in` + +import core.game.node.entity.player.Player + +sealed class Packet { + data class ItemAction(val player: Player, val optIndex: Int, val itemId: Int, val slot: Int, val iface: Int, val child: Int) : Packet() + data class NpcAction(val player: Player, val optIndex: Int, val npcIndex: Int) : Packet() + data class SceneryAction(val player: Player, val optIndex: Int, val id: Int, val x: Int, val y: Int) : Packet() + data class PlayerAction(val player: Player, val optIndex: Int, val otherIndex: Int) : Packet() + data class GroundItemAction(val player: Player, val optIndex: Int, val id: Int, val x: Int, val y: Int) : Packet() + data class ItemExamine(val player: Player, val id: Int) : Packet() + data class SceneryExamine(val player: Player, val id: Int) : Packet() + data class NpcExamine(val player: Player, val id: Int) : Packet() + data class UseWithNpc(val player: Player, val itemId: Int, val npcIndex: Int, val iface: Int, val slot: Int) : Packet() + data class UseWithPlayer(val player: Player, val itemId: Int, val otherIndex: Int, val iface: Int, val slot: Int) : Packet() + data class UseWithItem(val player: Player, val usedId: Int, val usedWithId: Int, val usedSlot: Int, val usedWithSlot: Int, val usedIface: Int, val usedWithIface: Int, val usedChild: Int, val usedWithChild: Int) : Packet() + data class UseWithScenery(val player: Player, val itemId: Int, val slot: Int, val sceneryId: Int, val x: Int, val y: Int) : Packet() + data class UseWithGroundItem(val player: Player, val usedId: Int, val withId: Int, val iface: Int, val child: Int, val slot: Int, val x: Int, val y: Int) : Packet() + data class IfAction(val player: Player, val opcode: Int, val optIndex: Int, val iface: Int, val child: Int, val slot: Int, val itemId: Int = -1) : Packet() + data class ContinueOption(val player: Player, val iface: Int, val child: Int, val slot: Int, val opcode: Int) : Packet() + data class CloseIface(val player: Player) : Packet() + data class JoinClan(val player: Player, val clanName: String) : Packet() + data class SetClanRank(val player: Player, val username: String, val rank: Int) : Packet() + data class KickFromClan(val player: Player, val username: String) : Packet() + data class AddFriend(val player: Player, val username: String) : Packet() + data class RemoveFriend(val player: Player, val username: String) : Packet() + data class AddIgnore(val player: Player, val username: String) : Packet() + data class RemoveIgnore(val player: Player, val username: String) : Packet() + data class TrackingFocus(val player: Player, val isFocused: Boolean) : Packet() + data class TrackingCameraPos(val player: Player, val x: Int, val y: Int) : Packet() + data class TrackingDisplayUpdate(val player: Player, val windowMode: Int, val screenWidth: Int, val screenHeight: Int, val displayMode: Int) : Packet() + data class TrackingAfkTimeout(val player: Player) : Packet() + data class TrackingMouseClick(val player: Player, val x: Int, val y: Int, val isRightClick: Boolean, val delay: Int) : Packet() + data class ComponentPlayerAction(val player: Player, val otherIndex: Int, val iface: Int, val child: Int) : Packet() + data class ComponentItemAction(val player: Player, val iface: Int, val child: Int, val itemId: Int, val slot: Int) : Packet() + data class ComponentNpcAction(val player: Player, val iface: Int, val child: Int, val npcIndex: Int) : Packet() + data class ComponentSceneryAction(val player: Player, val iface: Int, val child: Int, val sceneryId: Int, val x: Int, val y: Int) : Packet() + data class ComponentGroundItemAction(val player: Player, val iface: Int, val child: Int, val slot: Int, val itemId: Int, val x: Int, val y: Int) : Packet() + data class SlotSwitchMultiComponent(val player: Player, val sourceIface: Int, val sourceChild: Int, val sourceSlot: Int, val destIface: Int, val destChild: Int, val destSlot: Int) : Packet() + data class SlotSwitchSingleComponent(val player: Player, val iface: Int, val child: Int, val sourceSlot: Int, val destSlot: Int, val isInsert: Boolean) : Packet() + data class PacketCountUpdate(val player: Player, val count: Int) : Packet() + data class PrivateMessage(val player: Player, val username: String, val message: String) : Packet() + data class ChatMessage(val player: Player, val effects: Int, val message: String) : Packet() + data class ChatSetting(val player: Player, val public: Int, val private: Int, val trade: Int) : Packet() + data class Command(val player: Player, val commandLine: String) : Packet() + data class GESetOfferItem(val player: Player, val itemId: Int) : Packet() + data class TrackFinished(val player: Player, val trackId: Int) : Packet() + data class ReportAbuse(val player: Player, val target: String, val rule: Int, val modMute: Boolean) : Packet() + data class WorldspaceWalk(val player: Player, val destX: Int, val destY: Int, val isRun: Boolean) : Packet() + data class MinimapWalk(val player: Player, val destX: Int, val destY: Int, val clickedX: Int, val clickedY: Int, val rotation: Int, val isRun: Boolean) : Packet() + data class InteractWalk(val player: Player, val destX: Int, val destY: Int, val isRun: Boolean) : Packet() + data class Ping(val player: Player) : Packet() + data class QuickChat(val player: Player, val indexA: Int, val indexB: Int, val forClan: Boolean, val multiplier: Int, val offset: Int, val type: QCPacketType) : Packet() + data class InputPromptResponse(val player: Player, val response: Any) : Packet() + data class PlayerPrefsUpdate(val player: Player, val prefs: Int) : Packet() + + class NoProcess : Packet() + class UnhandledOp : Packet() + data class DecodingError(val message: String) : Packet() +} diff --git a/Server/src/main/core/net/packet/in/QuickChatPacketHandler.kt b/Server/src/main/core/net/packet/in/QuickChatPacketHandler.kt new file mode 100644 index 0000000..7857752 --- /dev/null +++ b/Server/src/main/core/net/packet/in/QuickChatPacketHandler.kt @@ -0,0 +1,80 @@ +package core.net.packet.`in` + +import core.api.log +import core.game.node.entity.player.Player +import core.net.packet.IncomingPacket +import core.net.packet.IoBuffer +import core.net.packet.QCRepository +import core.tools.SystemLogger +import core.game.world.GameWorld +import core.tools.Log + +/** + * Decodes the quick chat packet + * @author Ceikry + */ +/** + * There's different varieties of the quick chat packet. + * Standard, which is only 3 (sometimes 4) bytes and has no string replacement selections. + * Single-replacement, which is 5 bytes and has one string replacement. The last 3 bytes can and should be converted to a Short. + * Double-replacement, which is 7 bytes and has two string replacements. + * The first byte is whether or not the message is intended for your clan. 0 = public chat, 1 = clan chat + * The second byte will either be 0,1,2,3. This is the number 256 is to be multiplied by. + * The third byte is the index. This can be negative. This number is added to the multiple of 256 determined by the previous byte to get the actual id of the cache file holding the quick chat message. + * In a single replacement, you then have a short (which is 3 bytes in length) that will tell you either the item ID or the index of the selection on the menu. + * In a double replacement, you would have something like 0 1 0 3 instead as the proceeding 4 bytes. The 0s are spacers and the 1 and 3 are the selection indexes for the menus. + */ +class QuickChatPacketHandler : IncomingPacket { + override fun decode(player: Player?, opcode: Int, buffer: IoBuffer?) { + buffer ?: return + val x = buffer.toByteBuffer() + + val packetType = when(x.array().size){ + 3,4 -> QCPacketType.STANDARD + 5 -> QCPacketType.SINGLE + 7 -> QCPacketType.DOUBLE + else -> QCPacketType.UNHANDLED.also { log(this::class.java, Log.WARN, "UNHANDLED QC PACKET TYPE Size ${x.array().size}") } + } + + val forClan = (buffer.get() and 0xFF) == 1 + val multiplier: Int = buffer.get() + val offset: Int = buffer.get() + var selection_a_index = -1 + var selection_b_index = -1 + + when(packetType){ + QCPacketType.SINGLE -> { + selection_a_index = buffer.short + } + QCPacketType.DOUBLE -> { + buffer.get() //discard + selection_a_index = buffer.get() + buffer.get() //discard + selection_b_index = buffer.get() + } + QCPacketType.UNHANDLED -> log(this::class.java, Log.WARN, "Unhandled packet type, skipping remaining buffer contents.") + else -> {} + } + + + //Prints the values of each byte in the buffer to server log + //If the world is in dev mode + if(GameWorld.settings?.isDevMode == true) { + log(this::class.java, Log.FINE, "Begin QuickChat Packet Buffer Dump---------") + log(this::class.java, Log.FINE, "Packet Type: ${packetType.name} Chat Type: ${if(forClan) "Clan" else "Public"}") + x?.array()?.forEach { + log(this::class.java, Log.FINE, "$it") + } + log(this::class.java, Log.FINE, "End QuickChat Packet Buffer Dump-----------") + } + + QCRepository.sendQC(player,multiplier,offset,packetType,selection_a_index,selection_b_index,forClan) + } +} + +enum class QCPacketType{ + STANDARD, + SINGLE, + DOUBLE, + UNHANDLED +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/in/RunScript.kt b/Server/src/main/core/net/packet/in/RunScript.kt new file mode 100644 index 0000000..b3f9007 --- /dev/null +++ b/Server/src/main/core/net/packet/in/RunScript.kt @@ -0,0 +1,45 @@ +package core.net.packet.`in` + +import core.api.* +import core.game.node.entity.player.Player + +/** + * Handles an incoming script execution request packet. + * + * @author vddCore + */ +object RunScript { + + fun processInput(player: Player, value: Any, script: ((Any) -> Boolean)) { + if (value is Int && value <= 0) return + + val type = player.getAttribute("input-type", InputType.NUMERIC) + + var input = value + + if (player.getAttribute("parseamount", false)) { + input = value.toString().lowercase() + + if (!input.matches(Regex("^(\\d+)(k+|m+)?$"))) { + sendDialogue(player, "That doesn't look right. Please try again.") + return + } + + input = input.replace("k", "000").replace("m", "000000") + } + + if (type == InputType.NUMERIC || type == InputType.AMOUNT) + input = input.toString().toIntOrNull() ?: input + + try { + script(input) + } catch (_: NumberFormatException) { + sendDialogue(player, "That number's a bit large, don't you think?") + } catch (_: ClassCastException) { + sendDialogue(player, "Something went wrong here. Try again.") + } finally { + removeAttribute(player, "runscript") + removeAttribute(player, "input-type") + } + } +} diff --git a/Server/src/main/core/net/packet/out/AccessMask.java b/Server/src/main/core/net/packet/out/AccessMask.java new file mode 100644 index 0000000..edf1cfb --- /dev/null +++ b/Server/src/main/core/net/packet/out/AccessMask.java @@ -0,0 +1,23 @@ +package core.net.packet.out; + +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.context.AccessMaskContext; + +/** + * The access mask outgoing packet. + * @author Emperor + */ +public class AccessMask implements OutgoingPacket { + + @Override + public void send(AccessMaskContext context) { + IoBuffer buffer = new IoBuffer(165); + buffer.putLEShort(context.getPlayer().getInterfaceManager().getPacketCount(1)); + buffer.putLEShort(context.getLength()); + buffer.putInt(context.getInterfaceId() << 16 | context.getChildId()); + buffer.putShortA(context.getOffset()); + buffer.putIntA(context.getId()); + buffer.cypherOpcode(context.getPlayer().getSession().getIsaacPair().getOutput());context.getPlayer().getSession().write(buffer); + } +} diff --git a/Server/src/main/core/net/packet/out/AnimateInterface.java b/Server/src/main/core/net/packet/out/AnimateInterface.java new file mode 100644 index 0000000..499aaba --- /dev/null +++ b/Server/src/main/core/net/packet/out/AnimateInterface.java @@ -0,0 +1,21 @@ +package core.net.packet.out; + +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.context.AnimateInterfaceContext; + +/** + * The animate interface outgoing packet. + * @author Emperor + */ +public class AnimateInterface implements OutgoingPacket { + + @Override + public void send(AnimateInterfaceContext context) { + IoBuffer buffer = new IoBuffer(36); + buffer.putIntB((context.getInterfaceId() << 16) + context.getChildId()); + buffer.putLEShort(context.getAnimationId()); + buffer.putShortA(context.getPlayer().getInterfaceManager().getPacketCount(1)); + buffer.cypherOpcode(context.getPlayer().getSession().getIsaacPair().getOutput());context.getPlayer().getDetails().getSession().write(buffer); + } +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/out/AnimateObjectPacket.java b/Server/src/main/core/net/packet/out/AnimateObjectPacket.java new file mode 100644 index 0000000..27a891b --- /dev/null +++ b/Server/src/main/core/net/packet/out/AnimateObjectPacket.java @@ -0,0 +1,39 @@ +package core.net.packet.out; + +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.world.map.Location; +import core.game.world.update.flag.context.Animation; +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.context.AnimateObjectContext; + +/** + * Represents the packet used to animate an object. + * @author Vexia + * @date 10/11/2013 + */ +public class AnimateObjectPacket implements OutgoingPacket { + + /** + * Writes the packet. + * @param buffer The buffer. + */ + public static IoBuffer write(IoBuffer buffer, Animation animation) { + Scenery object = animation.getObject(); + Location l = object.getLocation(); + buffer.put(20); + buffer.putS((l.getChunkOffsetX() << 4) | (l.getChunkOffsetY() & 0x7)); + buffer.putS((object.getType() << 2) + (object.getRotation() & 0x3)); + buffer.putLEShort(animation.getId()); + return buffer; + } + + @Override + public void send(AnimateObjectContext context) { + Player player = context.getPlayer(); + Scenery object = context.getAnimation().getObject(); + IoBuffer buffer = write(UpdateAreaPosition.getBuffer(player, object.getLocation().getChunkBase()), context.getAnimation()); + buffer.cypherOpcode(context.getPlayer().getSession().getIsaacPair().getOutput());player.getSession().write(buffer); + } +} diff --git a/Server/src/main/core/net/packet/out/AudioPacket.java b/Server/src/main/core/net/packet/out/AudioPacket.java new file mode 100644 index 0000000..beb04da --- /dev/null +++ b/Server/src/main/core/net/packet/out/AudioPacket.java @@ -0,0 +1,49 @@ +package core.net.packet.out; + +import core.game.node.entity.player.link.audio.Audio; +import core.game.world.map.Location; +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.context.DefaultContext; + +/** + * Sends an audio packet. + * @author Vexia + */ +public class AudioPacket implements OutgoingPacket { + + public static IoBuffer write(IoBuffer buffer, Audio audio, Location loc) { + if(loc == null) { + buffer.put((byte) 172); + buffer.putShort(audio.id); + buffer.put((byte) audio.loops); + buffer.putShort(audio.delay); + } else { + buffer.put((byte) 97); + buffer.put((byte) (loc.getChunkOffsetX() << 4 | loc.getChunkOffsetY())); + buffer.putShort(audio.id); + buffer.put((byte) (audio.radius << 4 | audio.loops & 7)); + buffer.put((byte) audio.delay); + } + return buffer; + } + + //208 music effect + //4 music + //172 sound effect + @Override + public void send(DefaultContext context) { + final Audio audio = (Audio) context.getObjects()[0]; + final Location loc = (Location) context.getObjects()[1]; + IoBuffer buffer; + if(loc == null) { + buffer = new IoBuffer(); + } else { + buffer = UpdateAreaPosition.getBuffer(context.getPlayer(), loc.getChunkBase()); + } + write(buffer, audio, loc); + buffer.cypherOpcode(context.getPlayer().getSession().getIsaacPair().getOutput()); + context.getPlayer().getSession().write(buffer); + } + +} diff --git a/Server/src/main/core/net/packet/out/BuildDynamicScene.java b/Server/src/main/core/net/packet/out/BuildDynamicScene.java new file mode 100644 index 0000000..3cea2b5 --- /dev/null +++ b/Server/src/main/core/net/packet/out/BuildDynamicScene.java @@ -0,0 +1,78 @@ +package core.net.packet.out; + +import core.game.node.entity.player.Player; +import core.game.world.map.Region; +import core.game.world.map.RegionChunk; +import core.game.world.map.RegionManager; +import core.game.world.map.build.DynamicRegion; +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.PacketHeader; +import core.net.packet.context.DynamicSceneContext; +import core.game.system.config.XteaParser; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Emperor + */ +public final class BuildDynamicScene implements OutgoingPacket { + + @Override + public void send(DynamicSceneContext context) { + IoBuffer buffer = new IoBuffer(214, PacketHeader.SHORT); + List regionIds = new ArrayList<>(20); + Player player = context.getPlayer(); + buffer.putLEShortA(player.getLocation().getSceneX()); + buffer.putLEShortA(player.getLocation().getRegionX()); + buffer.putS(player.getLocation().getZ()); + buffer.putLEShortA(player.getLocation().getSceneY()); + buffer.setBitAccess(); + Region r = player.getViewport().getRegion(); + RegionChunk[][][] chunks = new RegionChunk[4][13][13]; + int baseX = player.getLocation().getRegionX() - 6; + int baseY = player.getLocation().getRegionY() - 6; + for (int z = 0; z < 4; z++) { + for (int x = baseX; x <= player.getLocation().getRegionX() + 6; x++) { + for (int y = baseY; y <= player.getLocation().getRegionY() + 6; y++) { + r = RegionManager.forId((x >> 3) << 8 | (y >> 3)); + if (r instanceof DynamicRegion) { + DynamicRegion dr = (DynamicRegion) r; + chunks[z][x - baseX][y - baseY] = dr.getChunks()[z][x - (dr.getX() << 3)][y - (dr.getY() << 3)]; + } + } + } + } + for (int plane = 0; plane < 4; plane++) { + for (int offsetX = 0; offsetX < 13; offsetX++) { + for (int offsetY = 0; offsetY < 13; offsetY++) { + RegionChunk c = chunks[plane][offsetX][offsetY]; + if (c == null || c.getBase().getX() < 0 || c.getBase().getY() < 0) { + buffer.putBits(1, 0); + continue; + } + int realRegionX = c.getBase().getRegionX(); + int realRegionY = c.getBase().getRegionY(); + int realPlane = c.getBase().getZ(); + int rotation = c.getRotation(); + int id = (realRegionX >> 3) << 8 | (realRegionY >> 3); + if (!regionIds.contains(id)) { + regionIds.add(id); + } + buffer.putBits(1, 1); + buffer.putBits(26, (rotation << 1) | (realPlane << 24) | (realRegionX << 14) | (realRegionY << 3)); + } + } + } + buffer.setByteAccess(); + for (int id : regionIds) { + int[] keys = XteaParser.Companion.getRegionXTEA(id); + buffer.putIntB(keys[0]).putIntB(keys[1]).putIntB(keys[2]).putIntB(keys[3]); + } + buffer.putShort(player.getLocation().getRegionY()); + buffer.cypherOpcode(context.getPlayer().getSession().getIsaacPair().getOutput());context.getPlayer().getSession().write(buffer); + player.getPlayerFlags().setLastSceneGraph(player.getLocation()); + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/out/CSConfigPacket.java b/Server/src/main/core/net/packet/out/CSConfigPacket.java new file mode 100644 index 0000000..a9b821f --- /dev/null +++ b/Server/src/main/core/net/packet/out/CSConfigPacket.java @@ -0,0 +1,40 @@ +package core.net.packet.out; + +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.context.CSConfigContext; + +/** + * The outgoing packet for client script configs. + * + * @author Snickerize + */ +public class CSConfigPacket implements OutgoingPacket { + + @Override + public void send(CSConfigContext context) { + IoBuffer buffer = new IoBuffer(65); + buffer.putLEShort(context.getPlayer().getInterfaceManager().getPacketCount(1)); + buffer.putC((byte) context.getValue()); + buffer.putLEShortA(context.getId()); + buffer.cypherOpcode(context.getPlayer().getSession().getIsaacPair().getOutput());context.getPlayer().getDetails().getSession().write(buffer); + } + + /*@Override + public void send(CSConfigContext context) { + IoBuffer buffer = new IoBuffer(115); + buffer.putShort(context.getId()); + buffer.putString(context.getTypes()); + + for (int i = context.getTypes().length() - 1; i >= 0; i--) { + if (context.getTypes().charAt(i) == 's') { + buffer.putString((String) context.getParameters()[i]); + } else { + buffer.putInt(((Number) context.getParameters()[i]).intValue()); + } + } + + buffer.putInt(context.getValue()); + context.getPlayer().getDetails().getSession().write(buffer); + }*/ +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/out/CameraViewPacket.java b/Server/src/main/core/net/packet/out/CameraViewPacket.java new file mode 100644 index 0000000..4bd39d8 --- /dev/null +++ b/Server/src/main/core/net/packet/out/CameraViewPacket.java @@ -0,0 +1,44 @@ +package core.net.packet.out; + +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.context.CameraContext; + +/** + * Handles the outgoing camera view packets. + * @author Emperor + */ +public final class CameraViewPacket implements OutgoingPacket { + + @Override + public void send(CameraContext context) { + CameraContext.CameraType type = context.getType(); + IoBuffer buffer = new IoBuffer(type.opcode()); + Location l = Location.create(context.getX(), context.getY(), 0); + Player p = context.getPlayer(); + switch (type) { + case ROTATION: + case POSITION: + buffer.putShort(context.getPlayer().getInterfaceManager().getPacketCount(1)); + int x = l.getSceneX(p.getPlayerFlags().getLastSceneGraph()); + int y = l.getSceneY(p.getPlayerFlags().getLastSceneGraph()); + buffer.put(x).put(y).putShort(context.getHeight()).put(context.getSpeed()).put(context.getZoomSpeed()); + break; + case SET: + buffer.putLEShort(context.getX()) + .putShort(context.getPlayer().getInterfaceManager().getPacketCount(1)).putShort(context.getY()); + break; + case SHAKE: + buffer.putShort(context.getPlayer().getInterfaceManager().getPacketCount(1)); + buffer.put(l.getX()).put(l.getY()).put(context.getSpeed()).put(context.getZoomSpeed()).putShort(context.getHeight()); + break; + case RESET: + buffer.putShort(context.getPlayer().getInterfaceManager().getPacketCount(1)); + break; + } + buffer.cypherOpcode(context.getPlayer().getSession().getIsaacPair().getOutput());p.getSession().write(buffer); + } + +} diff --git a/Server/src/main/core/net/packet/out/ClearGroundItem.java b/Server/src/main/core/net/packet/out/ClearGroundItem.java new file mode 100644 index 0000000..c22b84a --- /dev/null +++ b/Server/src/main/core/net/packet/out/ClearGroundItem.java @@ -0,0 +1,35 @@ +package core.net.packet.out; + +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.map.Location; +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.context.BuildItemContext; + +/** + * Represents the outgoing packet of clearing ground items. + * @author Emperor + */ +public final class ClearGroundItem implements OutgoingPacket { + + /** + * Writes the packet. + * @param buffer The buffer. + * @param item The item. + */ + public static IoBuffer write(IoBuffer buffer, Item item) { + Location l = item.getLocation(); + buffer.put(240); + buffer.putS((l.getChunkOffsetX() << 4) | (l.getChunkOffsetY() & 0x7)).putShort(item.getId()); + return buffer; + } + + @Override + public void send(BuildItemContext context) { + Player player = context.getPlayer(); + Item item = context.getItem(); + IoBuffer buffer = write(UpdateAreaPosition.getBuffer(player, item.getLocation().getChunkBase()), item); + buffer.cypherOpcode(context.getPlayer().getSession().getIsaacPair().getOutput());player.getSession().write(buffer); + } +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/out/ClearMinimapFlag.java b/Server/src/main/core/net/packet/out/ClearMinimapFlag.java new file mode 100644 index 0000000..03a9edc --- /dev/null +++ b/Server/src/main/core/net/packet/out/ClearMinimapFlag.java @@ -0,0 +1,19 @@ +package core.net.packet.out; + +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.context.PlayerContext; + +/** + * Handles the removal of the minimap flag. + * @author Emperor + */ +public final class ClearMinimapFlag implements OutgoingPacket { + + @Override + public void send(PlayerContext context) { + IoBuffer buffer = new IoBuffer(153); + buffer.cypherOpcode(context.getPlayer().getSession().getIsaacPair().getOutput());context.getPlayer().getDetails().getSession().write(buffer); + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/out/ClearRegionChunk.java b/Server/src/main/core/net/packet/out/ClearRegionChunk.java new file mode 100644 index 0000000..f94a7a4 --- /dev/null +++ b/Server/src/main/core/net/packet/out/ClearRegionChunk.java @@ -0,0 +1,25 @@ +package core.net.packet.out; + +import core.game.world.map.Location; +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.context.ClearChunkContext; + +/** + * Handles the clear region chunk outgoing packet. + * @author Emperor + */ +public final class ClearRegionChunk implements OutgoingPacket { + + @Override + public void send(ClearChunkContext context) { + Location l = context.getPlayer().getPlayerFlags().getLastSceneGraph(); + int x = context.getChunk().getCurrentBase().getSceneX(l); + int y = context.getChunk().getCurrentBase().getSceneY(l); + if (x >= 0 && y >= 0 && x < 96 && y < 96) { + IoBuffer buffer = new IoBuffer(112).put(x).putC(y); + buffer.cypherOpcode(context.getPlayer().getSession().getIsaacPair().getOutput());context.getPlayer().getSession().write(buffer); + } + } + +} diff --git a/Server/src/main/core/net/packet/out/ClearScenery.java b/Server/src/main/core/net/packet/out/ClearScenery.java new file mode 100644 index 0000000..3191df1 --- /dev/null +++ b/Server/src/main/core/net/packet/out/ClearScenery.java @@ -0,0 +1,36 @@ +package core.net.packet.out; + +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.world.map.Location; +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.context.BuildSceneryContext; + +/** + * The clear scenery outgoing packet. + * @author Emperor + */ +public final class ClearScenery implements OutgoingPacket { + + /** + * Writes the packet. + * @param buffer The buffer. + * @param object The object. + */ + public static IoBuffer write(IoBuffer buffer, Scenery object) { + Location l = object.getLocation(); + buffer.put(195) // Opcode + .putC((object.getType() << 2) + (object.getRotation() & 3)).put((l.getChunkOffsetX() << 4) | (l.getChunkOffsetY() & 0x7)); + return buffer; + } + + @Override + public void send(BuildSceneryContext context) { + Player player = context.getPlayer(); + Scenery o = context.getScenery(); + IoBuffer buffer = write(UpdateAreaPosition.getBuffer(player, o.getLocation().getChunkBase()), o); + buffer.cypherOpcode(context.getPlayer().getSession().getIsaacPair().getOutput());player.getSession().write(buffer); + + } +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/out/CloseInterface.java b/Server/src/main/core/net/packet/out/CloseInterface.java new file mode 100644 index 0000000..79d07dd --- /dev/null +++ b/Server/src/main/core/net/packet/out/CloseInterface.java @@ -0,0 +1,22 @@ +package core.net.packet.out; + +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.context.InterfaceContext; + +/** + * Represents the outgoing packet used for closing an interface. + * @author Emperor + */ +public final class CloseInterface implements OutgoingPacket { + + @Override + public void send(InterfaceContext context) { + IoBuffer buffer = new IoBuffer(149); + buffer.putShort(context.getPlayer().getInterfaceManager().getPacketCount(1)); + buffer.putShort(context.getWindowId()); + buffer.putShort(context.getComponentId()); + buffer.cypherOpcode(context.getPlayer().getSession().getIsaacPair().getOutput());context.getPlayer().getSession().write(buffer); + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/out/CommunicationMessage.java b/Server/src/main/core/net/packet/out/CommunicationMessage.java new file mode 100644 index 0000000..5cd5e59 --- /dev/null +++ b/Server/src/main/core/net/packet/out/CommunicationMessage.java @@ -0,0 +1,75 @@ +package core.net.packet.out; + +import core.game.node.entity.player.Player; +import core.game.system.communication.ClanRepository; +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.PacketHeader; +import core.net.packet.context.MessageContext; +import core.tools.StringUtils; +import core.game.bots.AIPlayer; + +import java.util.Random; + +/** + * Handles communication message packet sending. + * @author Emperor + */ +public final class CommunicationMessage implements OutgoingPacket { + + @Override + public void send(MessageContext context) { + IoBuffer buffer = new IoBuffer(context.getOpcode(), PacketHeader.BYTE); + String message = context.getMessage(); + Player player = context.getPlayer(); + String other = context.getOther(); + switch (context.getOpcode()) { + case MessageContext.SEND_MESSAGE: + byte[] bytes = new byte[256]; + int length = StringUtils.encryptPlayerChat(bytes, 0, 0, message.length(), message.getBytes()); + buffer.putLong(StringUtils.stringToLong(other)); + buffer.put((byte) message.length()); + buffer.putBytes(bytes, 0, length); + break; + case MessageContext.RECIEVE_MESSAGE: + bytes = new byte[256]; + bytes[0] = (byte) message.length(); + length = 1 + StringUtils.encryptPlayerChat(bytes, 0, 1, message.length(), message.getBytes()); + player.setAttribute("replyTo", other); + buffer.putLong(StringUtils.stringToLong(other)).putShort(new Random().nextInt(0xFFFF)).putTri(getMessageIndex(player)).put((byte) context.getChatIcon()).putBytes(bytes, 0, length); + break; + case MessageContext.CLAN_MESSAGE: + ClanRepository clan = player.getCommunication().getClan(); + if (clan == null) { + return; + } + bytes = new byte[256]; + bytes[0] = (byte) context.getMessage().length(); + length = 1 + StringUtils.encryptPlayerChat(bytes, 0, 1, message.length(), message.getBytes()); + buffer.putLong(StringUtils.stringToLong(other)); + buffer.put((byte) 0);// it's just read does nothing + buffer.putLong(StringUtils.stringToLong(clan.getName())); + buffer.putShort(new Random().nextInt(0xFFFF)); + buffer.putTri(getMessageIndex(player)); + buffer.put((byte) context.getChatIcon()); // rights + buffer.putBytes(bytes, 0, length); + break; + } + if(player.isArtificial()){ + ((AIPlayer) player).handleIncomingChat(context); + } + buffer.cypherOpcode(context.getPlayer().getSession().getIsaacPair().getOutput());player.getSession().write(buffer); + } + + /** + * Gets the message index. + * @param p The player. + * @return The message index. + */ + private static int getMessageIndex(Player p) { + int count = p.getAttribute("pm_index", 0) + 1; + p.setAttribute("pm_index", count); + return count; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/out/Config.java b/Server/src/main/core/net/packet/out/Config.java new file mode 100644 index 0000000..d22bd17 --- /dev/null +++ b/Server/src/main/core/net/packet/out/Config.java @@ -0,0 +1,29 @@ +package core.net.packet.out; + +import core.net.packet.context.ConfigContext; +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; + +/** + * The config outgoing packet. + * @author Emperor + */ +public class Config implements OutgoingPacket { + + @Override + public void send(ConfigContext context) { + IoBuffer buffer; + if (context.getValue() < Byte.MIN_VALUE || context.getValue() > Byte.MAX_VALUE) { + buffer = new IoBuffer(226); + buffer.putInt(context.getValue()); + buffer.putShortA(context.getId()); + } else { + buffer = new IoBuffer(60); + buffer.putShortA(context.getId()); + buffer.putC(context.getValue()); + } + buffer.cypherOpcode(context.getPlayer().getSession().getIsaacPair().getOutput());if(!context.getPlayer().isArtificial()) { + context.getPlayer().getDetails().getSession().write(buffer); + } + } +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/out/ConstructGroundItem.java b/Server/src/main/core/net/packet/out/ConstructGroundItem.java new file mode 100644 index 0000000..e1ee39c --- /dev/null +++ b/Server/src/main/core/net/packet/out/ConstructGroundItem.java @@ -0,0 +1,35 @@ +package core.net.packet.out; + +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.map.Location; +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.context.BuildItemContext; + +/** + * Represents the outgoing packet of constructing a ground item. + * @author Emperor + */ +public final class ConstructGroundItem implements OutgoingPacket { + + /** + * Writes the packet. + * @param buffer The buffer. + * @param item The item. + */ + public static IoBuffer write(IoBuffer buffer, Item item) { + Location l = item.getLocation(); + buffer.put(33); + buffer.putLEShort(item.getId()).put((l.getChunkOffsetX() << 4) | (l.getChunkOffsetY() & 0x7)).putShortA(item.getAmount()); + return buffer; + } + + @Override + public void send(BuildItemContext context) { + Player player = context.getPlayer(); + Item item = context.getItem(); + IoBuffer buffer = write(UpdateAreaPosition.getBuffer(player, item.getLocation().getChunkBase()), item); + buffer.cypherOpcode(context.getPlayer().getSession().getIsaacPair().getOutput());player.getDetails().getSession().write(buffer); + } +} diff --git a/Server/src/main/core/net/packet/out/ConstructScenery.java b/Server/src/main/core/net/packet/out/ConstructScenery.java new file mode 100644 index 0000000..7daa313 --- /dev/null +++ b/Server/src/main/core/net/packet/out/ConstructScenery.java @@ -0,0 +1,36 @@ +package core.net.packet.out; + +import core.game.node.entity.player.Player; +import core.game.node.scenery.Scenery; +import core.game.world.map.Location; +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.context.BuildSceneryContext; + +/** + * The construct scenery packet. + * @author Emperor + */ +public final class ConstructScenery implements OutgoingPacket { + + /** + * Writes the packet. + * @param buffer The buffer. + * @param object The object. + */ + public static IoBuffer write(IoBuffer buffer, Scenery object) { + Location l = object.getLocation(); + buffer.put(179).putA((object.getType() << 2) | (object.getRotation() & 0x3)).put((l.getChunkOffsetX() << 4) | (l.getChunkOffsetY() & 0x7)).putShortA(object.getId()); + return buffer; + } + + @Override + public void send(BuildSceneryContext context) { + Player player = context.getPlayer(); + Scenery o = context.getScenery(); + IoBuffer buffer = write(UpdateAreaPosition.getBuffer(player, o.getLocation().getChunkBase()), o); + buffer.cypherOpcode(context.getPlayer().getSession().getIsaacPair().getOutput());player.getSession().write(buffer); + + } + +} diff --git a/Server/src/main/core/net/packet/out/ContactPackets.java b/Server/src/main/core/net/packet/out/ContactPackets.java new file mode 100644 index 0000000..2045f86 --- /dev/null +++ b/Server/src/main/core/net/packet/out/ContactPackets.java @@ -0,0 +1,55 @@ +package core.net.packet.out; + +import core.game.node.entity.player.Player; +import core.game.system.communication.Contact; +import core.net.amsc.WorldCommunicator; +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.PacketHeader; +import core.net.packet.context.ContactContext; +import core.tools.StringUtils; + +/** + * Handles the contact packet sending. + * @author Emperor + */ +public final class ContactPackets implements OutgoingPacket { + + @Override + public void send(ContactContext context) { + IoBuffer buffer = null; + Player player = context.getPlayer(); + switch (context.getType()) { + case ContactContext.UPDATE_STATE_TYPE: + buffer = new IoBuffer(197).put(2); //always put the AVAILABLE state. + break; + case ContactContext.IGNORE_LIST_TYPE: + buffer = new IoBuffer(126, PacketHeader.SHORT); + for (String string : player.getCommunication().getBlocked()) { + if (string.length() == 0) { + continue; + } + buffer.putLong(StringUtils.stringToLong(string)); + } + break; + case ContactContext.UPDATE_FRIEND_TYPE: + buffer = new IoBuffer(62, PacketHeader.BYTE); + buffer.putLong(StringUtils.stringToLong(context.getName())); + buffer.putShort(context.getWorldId()); + Contact c = player.getCommunication().getContacts().get(context.getName()); + if (c != null) { + buffer.put((byte) c.getRank().getValue()); + } else { + buffer.put((byte) 0); + } + if (context.isOnline()) { + buffer.putString("World " + context.getWorldId()); + } + break; + } + if (buffer != null) { + buffer.cypherOpcode(context.getPlayer().getSession().getIsaacPair().getOutput());player.getSession().write(buffer); + } + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/out/ContainerPacket.java b/Server/src/main/core/net/packet/out/ContainerPacket.java new file mode 100644 index 0000000..8c66918 --- /dev/null +++ b/Server/src/main/core/net/packet/out/ContainerPacket.java @@ -0,0 +1,74 @@ +package core.net.packet.out; + +import core.game.container.ContainerEvent; +import core.game.node.item.Item; +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.PacketHeader; +import core.net.packet.context.ContainerContext; + +/** + * Represents the outgoing container packet. + * @author Emperor + */ +public final class ContainerPacket implements OutgoingPacket { + + @Override + public void send(ContainerContext context) { + IoBuffer buffer = null; + if (context.isClear()) { + buffer = new IoBuffer(144); + buffer.putIntB(context.getInterfaceId() << 16 | context.getChildId()); + } else { + boolean slotBased = context.getSlots() != null; + buffer = new IoBuffer(slotBased ? 22 : 105, PacketHeader.SHORT); + buffer.putShort(context.getInterfaceId()); + buffer.putShort(context.getChildId()); + buffer.putShort(context.getContainerId()); + if (slotBased) { + for (int slot : context.getSlots()) { + buffer.putSmart(slot); + Item item = context.getItems()[slot]; + if (item != null && !item.equals(ContainerEvent.NULL_ITEM)) { + buffer.putShort(item.getId() + 1); + int amount = item.getAmount(); + if (amount < 0 || amount > 254) { + buffer.put(255).putInt(amount); + } else { + buffer.put(amount); + } + } else { + buffer.putShort(0); + } + } + } else { + if (context.ids != null) + { + buffer.p2(context.getLength()); + for (int i = 0; i < context.getLength(); i++) + { + buffer.putS(1); + buffer.p2(context.ids[i] + 1); + } + } + else { + buffer.putShort(context.getItems().length); + for (Item item : context.getItems()) + if (item != null) { + int amount = item.getAmount(); + if (amount < 0 || amount > 254) { + buffer.putS(255).putInt(amount); + } else { + buffer.putS(amount); + } + buffer.putShort(item.getId() + 1); + } else { + buffer.putS(0).putShort(0); + } + } + } + } + buffer.cypherOpcode(context.getPlayer().getSession().getIsaacPair().getOutput());context.getPlayer().getSession().write(buffer); + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/out/DisplayModel.java b/Server/src/main/core/net/packet/out/DisplayModel.java new file mode 100644 index 0000000..4fb26cf --- /dev/null +++ b/Server/src/main/core/net/packet/out/DisplayModel.java @@ -0,0 +1,49 @@ +package core.net.packet.out; + +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.context.DisplayModelContext; + +/** + * Represents the outgoing packet for the displaying of a node model on an + * interface. + * @author Emperor + */ +public final class DisplayModel implements OutgoingPacket { + + @Override + public void send(DisplayModelContext context) { + IoBuffer buffer; + switch (context.getType()) { + case PLAYER: + buffer = new IoBuffer(66); + buffer.putLEShortA(context.getPlayer().getInterfaceManager().getPacketCount(1)); + buffer.putIntA(context.getInterfaceId() << 16 | context.getChildId()); + break; + case NPC: + buffer = new IoBuffer(73); + buffer.putShortA(context.getNodeId()); + buffer.putLEInt((context.getInterfaceId() << 16) | context.getChildId()); + buffer.putLEShort(context.getPlayer().getInterfaceManager().getPacketCount(1)); + break; + case ITEM: + int value = context.getAmount() > 0 ? context.getAmount() : context.getZoom(); + buffer = new IoBuffer(50); + buffer.putInt(value); + buffer.putIntB((context.getInterfaceId() << 16) | context.getChildId()); + buffer.putLEShortA(context.getNodeId()); + buffer.putLEShort(context.getPlayer().getInterfaceManager().getPacketCount(1)); + break; + case MODEL: + buffer = new IoBuffer(130); + buffer.putLEInt(context.getInterfaceId() << 16 | context.getChildId()); + buffer.putLEShortA(context.getPlayer().getInterfaceManager().getPacketCount(1)); + buffer.putShortA(context.getNodeId()); + break; + default: + return; + } + buffer.cypherOpcode(context.getPlayer().getSession().getIsaacPair().getOutput());context.getPlayer().getSession().write(buffer); + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/out/GameMessage.java b/Server/src/main/core/net/packet/out/GameMessage.java new file mode 100644 index 0000000..3c1111a --- /dev/null +++ b/Server/src/main/core/net/packet/out/GameMessage.java @@ -0,0 +1,20 @@ +package core.net.packet.out; + +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.PacketHeader; +import core.net.packet.context.GameMessageContext; + +/** + * The game message outgoing packet. + * @author Emperor + */ +public class GameMessage implements OutgoingPacket { + + @Override + public void send(GameMessageContext context) { + IoBuffer buffer = new IoBuffer(70, PacketHeader.BYTE); + buffer.putString(context.getMessage()); + buffer.cypherOpcode(context.getPlayer().getSession().getIsaacPair().getOutput());context.getPlayer().getSession().write(buffer); + } +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/out/GrandExchangePacket.java b/Server/src/main/core/net/packet/out/GrandExchangePacket.java new file mode 100644 index 0000000..ba57cff --- /dev/null +++ b/Server/src/main/core/net/packet/out/GrandExchangePacket.java @@ -0,0 +1,42 @@ +package core.net.packet.out; + +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.PacketHeader; +import core.net.packet.context.GrandExchangeContext; + +/** + * The outgoing packet used for updating a player's grand exchange data. + * @author Emperor + * @author Vexia + * @author Angle + */ +public class GrandExchangePacket implements OutgoingPacket { + + private final int REMOVED = 6; + private final int ABORTED = 2; + + @Override + public void send(GrandExchangeContext context) { + final IoBuffer buffer = new IoBuffer(116, PacketHeader.NORMAL); + buffer.put(context.idx); + if (context.state == REMOVED) { + buffer.put(0).putShort(0).putInt(0).putInt(0).putInt(0).putInt(0); + } else { + byte state = (byte) (context.state + 1); + if (context.isSell) { + state += 8; + } + if (context.state == ABORTED) { + state = context.isSell ? (byte) -3 : (byte) 5; + } + buffer.put(state).putShort(context.itemID).putInt(context.value).putInt(context.amt). + putInt(context.completedAmt).putInt(context.totalCoinsExchanged); + } + try { + buffer.cypherOpcode(context.getPlayer().getSession().getIsaacPair().getOutput());context.getPlayer().getSession().write(buffer); + } catch (Exception e) { + } + } + +} diff --git a/Server/src/main/core/net/packet/out/HintIcon.java b/Server/src/main/core/net/packet/out/HintIcon.java new file mode 100644 index 0000000..77b046b --- /dev/null +++ b/Server/src/main/core/net/packet/out/HintIcon.java @@ -0,0 +1,31 @@ +package core.net.packet.out; + +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.context.HintIconContext; + +/** + * Handles the Hint icon outgoing packet. + * @author Emperor + */ +public final class HintIcon implements OutgoingPacket { + + @Override + public void send(HintIconContext context) { + IoBuffer buffer = new IoBuffer(217); + buffer.put(context.getSlot() << 6 | context.getTargetType()).put(context.getArrowId()); + if (context.getArrowId() > 0) { + if (context.getTargetType() == 1 || context.getTargetType() == 10) { + buffer.putShort(context.getIndex()).putShort(0) // Skip 3 bytes + .put(0); + } else if (context.getLocation() != null) { + buffer.putShort(context.getLocation().getX()).putShort(context.getLocation().getY()).put(context.getHeight()); + } else { + buffer.putShort(0).putShort(0).put(0); // Skip all bytes. + } + buffer.putShort(context.getModelId()); + } + buffer.cypherOpcode(context.getPlayer().getSession().getIsaacPair().getOutput());context.getPlayer().getSession().write(buffer); + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/out/InstancedLocationUpdate.java b/Server/src/main/core/net/packet/out/InstancedLocationUpdate.java new file mode 100644 index 0000000..ecaf5f3 --- /dev/null +++ b/Server/src/main/core/net/packet/out/InstancedLocationUpdate.java @@ -0,0 +1,31 @@ +package core.net.packet.out; + +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.context.LocationContext; + +/** + * Outgoing packet used for updating a player's location solely on his own + * client. + * @author Emperor + */ +public final class InstancedLocationUpdate implements OutgoingPacket { + + @Override + public void send(LocationContext context) { + IoBuffer buffer = new IoBuffer(110); + Location l = context.getLocation(); + Player player = context.getPlayer(); + int flag = l.getZ() << 1; + if (context.isTeleport()) { + flag |= 0x1; + } + buffer.putS(flag); + buffer.put(l.getSceneX(player.getPlayerFlags().getLastSceneGraph())); + buffer.putA(l.getSceneY(player.getPlayerFlags().getLastSceneGraph())); + // TODO player.getSession().write(buffer); + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/out/InteractionOption.java b/Server/src/main/core/net/packet/out/InteractionOption.java new file mode 100644 index 0000000..38b4fc3 --- /dev/null +++ b/Server/src/main/core/net/packet/out/InteractionOption.java @@ -0,0 +1,28 @@ +package core.net.packet.out; + +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.PacketHeader; +import core.net.packet.context.InteractionOptionContext; + +/** + * Handles the interaction option changed outgoing packet. + * @author Emperor + */ +public final class InteractionOption implements OutgoingPacket { + + @Override + public void send(InteractionOptionContext context) { + IoBuffer buffer = new IoBuffer(44, PacketHeader.BYTE); + buffer.putLEShortA(-1); + if(context.isRemove()){ + buffer.put(0); + } else { + buffer.put(context.getIndex() == 0 ? 1 : 0); + } + buffer.put(context.getIndex() + 1); + buffer.putString(context.getName()); + buffer.cypherOpcode(context.getPlayer().getSession().getIsaacPair().getOutput());context.getPlayer().getSession().write(buffer); + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/out/Interface.java b/Server/src/main/core/net/packet/out/Interface.java new file mode 100644 index 0000000..6a83819 --- /dev/null +++ b/Server/src/main/core/net/packet/out/Interface.java @@ -0,0 +1,21 @@ +package core.net.packet.out; + +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.context.InterfaceContext; + +/** + * The interface outgoing packet. + * @author Emperor + */ +public final class Interface implements OutgoingPacket { + + @Override + public void send(InterfaceContext context) { + IoBuffer buffer = new IoBuffer(155); + buffer.cypherOpcode(context.getPlayer().getSession().getIsaacPair().getOutput());buffer.put(context.isWalkable() ? 1 : 0); + buffer.putIntB(context.getWindowId() << 16 | context.getComponentId()).putShortA(context.getPlayer().getInterfaceManager().getPacketCount(1)).putShort(context.getInterfaceId()); + context.getPlayer().getDetails().getSession().write(buffer); + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/out/InterfaceConfig.java b/Server/src/main/core/net/packet/out/InterfaceConfig.java new file mode 100644 index 0000000..d4a7bcd --- /dev/null +++ b/Server/src/main/core/net/packet/out/InterfaceConfig.java @@ -0,0 +1,21 @@ +package core.net.packet.out; + +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.context.InterfaceConfigContext; + +/** + * The outgoing interface configuration packet. + * @author Emperor + */ +public class InterfaceConfig implements OutgoingPacket { + + @Override + public void send(InterfaceConfigContext context) { + IoBuffer buffer = new IoBuffer(21); + buffer.putC(context.isHidden() ? 1 : 0); + buffer.putShort(context.getPlayer().getInterfaceManager().getPacketCount(1)); + buffer.putLEInt(context.getInterfaceId() << 16 | context.getChildId()); + buffer.cypherOpcode(context.getPlayer().getSession().getIsaacPair().getOutput());context.getPlayer().getSession().write(buffer); + } +} diff --git a/Server/src/main/core/net/packet/out/InterfaceSetAngle.java b/Server/src/main/core/net/packet/out/InterfaceSetAngle.java new file mode 100644 index 0000000..835419c --- /dev/null +++ b/Server/src/main/core/net/packet/out/InterfaceSetAngle.java @@ -0,0 +1,26 @@ +package core.net.packet.out; + +import core.game.node.entity.player.Player; +import core.net.packet.context.DefaultContext; +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; + +public final class InterfaceSetAngle implements OutgoingPacket { + @Override + public void send(DefaultContext context) { + Player player = context.getPlayer(); + Object[] objects = context.getObjects(); + int pitch = (Integer)objects[0]; + int scale = (Integer)objects[1]; + int yaw = (Integer)objects[2]; + int interfaceId = (Integer)objects[3]; + int childId = (Integer)objects[4]; + IoBuffer buffer = new IoBuffer(132); + buffer.putShort(pitch); + buffer.putShortA(player.getInterfaceManager().getPacketCount(1)); + buffer.putLEShortA(scale); + buffer.putLEShortA(yaw); + buffer.putInt(interfaceId << 16 | childId); + buffer.cypherOpcode(context.getPlayer().getSession().getIsaacPair().getOutput());context.getPlayer().getSession().write(buffer); + } +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/out/LoginPacket.java b/Server/src/main/core/net/packet/out/LoginPacket.java new file mode 100644 index 0000000..462be00 --- /dev/null +++ b/Server/src/main/core/net/packet/out/LoginPacket.java @@ -0,0 +1,32 @@ +package core.net.packet.out; + +import core.game.node.entity.player.Player; +import core.game.node.entity.player.info.Rights; +import core.net.packet.OutgoingPacket; +import core.net.packet.context.PlayerContext; + +import java.nio.ByteBuffer; + +/** + * Handles the login outgoing packet. + * @author Emperor + */ +public final class LoginPacket implements OutgoingPacket { + + @Override + public void send(PlayerContext context) { + Player p = context.getPlayer(); + ByteBuffer buffer = ByteBuffer.allocate(9); + int right = context.getPlayer().getDetails().getRights() == Rights.PLAYER_MODERATOR ? 1 : context.getPlayer().getDetails().getRights() == Rights.ADMINISTRATOR ? 2 : 0; + buffer.put((byte) (right)); + buffer.put((byte) 0); // Something with client scripts, maybe login // + // screen? + buffer.put((byte) 0); // No idea. + buffer.put((byte) 0); // No idea. + buffer.put((byte) 1); // Boolean, possibly members. + buffer.putShort((short) p.getIndex()); + buffer.put((byte) 1); // No idea. (something with client scripts, again) + p.getDetails().getSession().write(buffer); + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/out/Logout.java b/Server/src/main/core/net/packet/out/Logout.java new file mode 100644 index 0000000..daefb97 --- /dev/null +++ b/Server/src/main/core/net/packet/out/Logout.java @@ -0,0 +1,18 @@ +package core.net.packet.out; + +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.context.PlayerContext; + +/** + * The outgoing logout packet. + * @author Emperor + */ +public class Logout implements OutgoingPacket { + + @Override + public void send(PlayerContext context) { + IoBuffer buffer = new IoBuffer(86); + buffer.cypherOpcode(context.getPlayer().getSession().getIsaacPair().getOutput());context.getPlayer().getDetails().getSession().write(buffer); + } +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/out/MinimapState.java b/Server/src/main/core/net/packet/out/MinimapState.java new file mode 100644 index 0000000..f13ea5a --- /dev/null +++ b/Server/src/main/core/net/packet/out/MinimapState.java @@ -0,0 +1,19 @@ +package core.net.packet.out; + +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.context.MinimapStateContext; + +/** + * Handles the sending of the minimap state outgoing packet. + * @author Emperor + */ +public final class MinimapState implements OutgoingPacket { + + @Override + public void send(MinimapStateContext context) { + IoBuffer buffer = new IoBuffer(192).put(context.getState()); + buffer.cypherOpcode(context.getPlayer().getSession().getIsaacPair().getOutput());context.getPlayer().getDetails().getSession().write(buffer); + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/out/MusicPacket.java b/Server/src/main/core/net/packet/out/MusicPacket.java new file mode 100644 index 0000000..e2831e5 --- /dev/null +++ b/Server/src/main/core/net/packet/out/MusicPacket.java @@ -0,0 +1,27 @@ +package core.net.packet.out; + +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.context.MusicContext; + +/** + * Outgoing Music packet + * @author SonicForce41 + */ +public class MusicPacket implements OutgoingPacket { + + @Override + public void send(MusicContext context) { + IoBuffer buffer = null; + if (context.isSecondary()) { + buffer = new IoBuffer(208); + buffer.putTri(255); + buffer.putLEShort(context.getMusicId()); + } else { + buffer = new IoBuffer(4); + buffer.putLEShortA(context.getMusicId()); + } + buffer.cypherOpcode(context.getPlayer().getSession().getIsaacPair().getOutput());context.getPlayer().getDetails().getSession().write(buffer); + } + +} diff --git a/Server/src/main/core/net/packet/out/PingPacket.java b/Server/src/main/core/net/packet/out/PingPacket.java new file mode 100644 index 0000000..70ea914 --- /dev/null +++ b/Server/src/main/core/net/packet/out/PingPacket.java @@ -0,0 +1,20 @@ +package core.net.packet.out; + +import core.net.packet.OutgoingPacket; +import core.net.packet.context.PlayerContext; + +/** + * Handles the ping packet sending. + * @author Emperor + */ +public final class PingPacket implements OutgoingPacket { + + @Override + public void send(PlayerContext context) { + // TODO: Find real ping packet, this is actually clear minimap flag + // packet. + // context.getPlayer().getDetails().getSession().write(new + // IoBuffer(47)); + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/out/PositionedGraphic.java b/Server/src/main/core/net/packet/out/PositionedGraphic.java new file mode 100644 index 0000000..6e381bb --- /dev/null +++ b/Server/src/main/core/net/packet/out/PositionedGraphic.java @@ -0,0 +1,31 @@ +package core.net.packet.out; + +import core.game.world.map.Location; +import core.game.world.update.flag.context.Graphics; +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.context.PositionedGraphicContext; + +/** + * The positioned graphic outgoing packet. + * @author Emperor + */ +public final class PositionedGraphic implements OutgoingPacket { + + @Override + public void send(PositionedGraphicContext context) { + Location l = context.getLocation(); + Graphics g = context.getGraphic(); + int offsetHash = (context.offsetX << 4) | context.offsetY; + IoBuffer buffer = new IoBuffer() + .put(26) //update current scene x and scene y client-side + .putC(context.sceneX) //this has to be done for each graphic being sent + .put(context.sceneY) //opcode 26 is the lastSceneX/lastSceneY update packet + .put(17).put(offsetHash) //send the graphics + .putShort(g.getId()) + .put(g.getHeight()) + .putShort(g.getDelay()); + context.getPlayer().getSession().write(buffer); + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/out/RepositionChild.java b/Server/src/main/core/net/packet/out/RepositionChild.java new file mode 100644 index 0000000..06898b2 --- /dev/null +++ b/Server/src/main/core/net/packet/out/RepositionChild.java @@ -0,0 +1,23 @@ +package core.net.packet.out; + +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.context.ChildPositionContext; + +/** + * Handles the "reposition interface child" outgoing packet. + * @author Emperor + */ +public final class RepositionChild implements OutgoingPacket { + + @Override + public void send(ChildPositionContext context) { + IoBuffer buffer = new IoBuffer(119) + .putShortA(context.getPlayer().getInterfaceManager().getPacketCount(1)) + .putLEInt(context.getInterfaceId() << 16 | context.getChildId()) + .putShort(context.getPosition().x) + .putShortA(context.getPosition().y); + buffer.cypherOpcode(context.getPlayer().getSession().getIsaacPair().getOutput());context.getPlayer().getSession().write(buffer); + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/out/ResetInterface.java b/Server/src/main/core/net/packet/out/ResetInterface.java new file mode 100644 index 0000000..f980ca1 --- /dev/null +++ b/Server/src/main/core/net/packet/out/ResetInterface.java @@ -0,0 +1,15 @@ +package core.net.packet.out; + +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.context.InterfaceContext; + +public class ResetInterface implements OutgoingPacket { + @Override + public void send(InterfaceContext ic) { + IoBuffer buffer = new IoBuffer(149); + buffer.putShort(ic.getPlayer().getInterfaceManager().getPacketCount(1)); + buffer.putInt(ic.getInterfaceId()); + ic.getPlayer().getSession().write(buffer); + } +} diff --git a/Server/src/main/core/net/packet/out/RunEnergy.java b/Server/src/main/core/net/packet/out/RunEnergy.java new file mode 100644 index 0000000..0fef5dd --- /dev/null +++ b/Server/src/main/core/net/packet/out/RunEnergy.java @@ -0,0 +1,19 @@ +package core.net.packet.out; + +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.context.PlayerContext; + +/** + * The run energy outgoing packet. + * @author Emperor + */ +public class RunEnergy implements OutgoingPacket { + + @Override + public void send(PlayerContext context) { + IoBuffer buffer = new IoBuffer(234); + buffer.put((byte) context.getPlayer().getSettings().getRunEnergy()); + buffer.cypherOpcode(context.getPlayer().getSession().getIsaacPair().getOutput());context.getPlayer().getDetails().getSession().write(buffer); + } +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/out/RunScriptPacket.java b/Server/src/main/core/net/packet/out/RunScriptPacket.java new file mode 100644 index 0000000..de4bc08 --- /dev/null +++ b/Server/src/main/core/net/packet/out/RunScriptPacket.java @@ -0,0 +1,54 @@ +package core.net.packet.out; + +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.PacketHeader; +import core.net.packet.context.RunScriptContext; + +/** + * The run script outgoing packet. + * @author Snickerize + */ +public class RunScriptPacket implements OutgoingPacket { + + /*@Override + public void send(RunScriptContext context) { + String string = context.getString(); + Object[] objects = context.getObjects(); + IoBuffer buffer = new IoBuffer(115, PacketHeader.SHORT); + buffer.putShort(context.getPlayer().getInterfaceManager().getPacketCount(1)); + buffer.putString(string); + int j = 0; + for (int i = (string.length() - 1); i >= 0; i--) { + if (string.charAt(i) == 's') { + buffer.putString((String) objects[j]); + } else { + buffer.putInt((Integer) objects[j]); + } + j++; + } + buffer.putInt(context.getId()); + context.getPlayer().getDetails().getSession().write(buffer); + }*/ + @Override + public void send(RunScriptContext context) { + String types = context.getString(); + Object[] objects = context.getObjects(); + IoBuffer buffer = new IoBuffer(115, PacketHeader.SHORT); + buffer.putShort(context.getPlayer().getInterfaceManager().getPacketCount(1)); + + buffer.putString(types); + int j = 0; + for (int i = (types.length() - 1); i >= 0; i--) { + if (types.charAt(i) == 's') { + buffer.putString((String) objects[j]); + } else { + buffer.putInt((Integer) objects[j]); + } + j++; + } + + buffer.putInt(context.getId()); + buffer.cypherOpcode(context.getPlayer().getSession().getIsaacPair().getOutput());context.getPlayer().getDetails().getSession().write(buffer); + } +} diff --git a/Server/src/main/core/net/packet/out/SetWalkOption.java b/Server/src/main/core/net/packet/out/SetWalkOption.java new file mode 100644 index 0000000..32e71de --- /dev/null +++ b/Server/src/main/core/net/packet/out/SetWalkOption.java @@ -0,0 +1,19 @@ +package core.net.packet.out; + +import core.net.packet.OutgoingPacket; +import core.net.packet.context.WalkOptionContext; + +/** + * Handles the sending of the "Set walk-to option" packet. + * @author Emperor + */ +public final class SetWalkOption implements OutgoingPacket { + + @Override + public void send(WalkOptionContext context) { + // TODO IoBuffer buffer = new IoBuffer(10, + // PacketHeader.BYTE).putString(context.getOption()); + // context.getPlayer().getDetails().getSession().write(buffer); + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/out/SkillLevel.java b/Server/src/main/core/net/packet/out/SkillLevel.java new file mode 100644 index 0000000..35bd139 --- /dev/null +++ b/Server/src/main/core/net/packet/out/SkillLevel.java @@ -0,0 +1,29 @@ +package core.net.packet.out; + +import core.game.node.entity.skill.Skills; +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.context.SkillContext; + +/** + * Handles the update skill outgoing packet. + * @author Emperor + */ +public final class SkillLevel implements OutgoingPacket { + + @Override + public void send(SkillContext context) { + final IoBuffer buffer = new IoBuffer(38); + buffer.cypherOpcode(context.getPlayer().getSession().getIsaacPair().getOutput());Skills skills = context.getPlayer().getSkills(); + if (context.getSkillId() == Skills.PRAYER) { + buffer.putA((int) Math.ceil(skills.getPrayerPoints())); + } else if (context.getSkillId() == Skills.HITPOINTS) { + buffer.putA(skills.getLifepoints()); + } else { + buffer.putA(skills.getLevel(context.getSkillId(), true)); + } + buffer.putIntA((int) skills.getExperience(context.getSkillId())).put(context.getSkillId()); + context.getPlayer().getDetails().getSession().write(buffer); + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/out/StringPacket.java b/Server/src/main/core/net/packet/out/StringPacket.java new file mode 100644 index 0000000..0da5ec3 --- /dev/null +++ b/Server/src/main/core/net/packet/out/StringPacket.java @@ -0,0 +1,22 @@ +package core.net.packet.out; + +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.PacketHeader; +import core.net.packet.context.StringContext; + +/** + * The outgoing set component string packet. + * @author Emperor + */ +public class StringPacket implements OutgoingPacket { + + @Override + public void send(StringContext context) { + IoBuffer buffer = new IoBuffer(171, PacketHeader.SHORT); + buffer.putIntB((context.getInterfaceId() << 16) | context.getLineId()); + buffer.putString(context.getString()); + buffer.putShortA(context.getPlayer().getInterfaceManager().getPacketCount(1)); + buffer.cypherOpcode(context.getPlayer().getSession().getIsaacPair().getOutput());context.getPlayer().getDetails().getSession().write(buffer); + } +} diff --git a/Server/src/main/core/net/packet/out/SystemUpdatePacket.java b/Server/src/main/core/net/packet/out/SystemUpdatePacket.java new file mode 100644 index 0000000..6e598e8 --- /dev/null +++ b/Server/src/main/core/net/packet/out/SystemUpdatePacket.java @@ -0,0 +1,19 @@ +package core.net.packet.out; + +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.context.SystemUpdateContext; + +/** + * Handles the system update packet. + * @author 'Vexia + */ +public class SystemUpdatePacket implements OutgoingPacket { + + @Override + public void send(final SystemUpdateContext context) { + IoBuffer buffer = new IoBuffer(85).putShort(context.getTime()); + buffer.cypherOpcode(context.getPlayer().getSession().getIsaacPair().getOutput());context.getPlayer().getDetails().getSession().write(buffer); + } + +} diff --git a/Server/src/main/core/net/packet/out/UpdateAreaPosition.java b/Server/src/main/core/net/packet/out/UpdateAreaPosition.java new file mode 100644 index 0000000..85621d4 --- /dev/null +++ b/Server/src/main/core/net/packet/out/UpdateAreaPosition.java @@ -0,0 +1,46 @@ +package core.net.packet.out; + +import core.game.node.entity.player.Player; +import core.game.world.map.Location; +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.PacketHeader; +import core.net.packet.context.AreaPositionContext; + +/** + * Handles the update area position packet. + * @author Emperor + */ +public final class UpdateAreaPosition implements OutgoingPacket { + + /** + * Gets the region chunk update buffer. + * @param player The player. + * @param base The base location of the chunk. + * @return The buffer. + */ + public static IoBuffer getChunkUpdateBuffer(Player player, Location base) { + int x = base.getSceneX(player.getPlayerFlags().getLastSceneGraph()); + int y = base.getSceneY(player.getPlayerFlags().getLastSceneGraph()); + return new IoBuffer(230, PacketHeader.SHORT).putA(y).putS(x); + } + + /** + * Gets the region chunk update buffer. + * @param player The player. + * @param base The base location of the chunk. + * @return The buffer. + */ + public static IoBuffer getBuffer(Player player, Location base) { + int x = base.getSceneX(player.getPlayerFlags().getLastSceneGraph()); + int y = base.getSceneY(player.getPlayerFlags().getLastSceneGraph()); + return new IoBuffer(26).putC(x).put(y); + } + + @Override + public void send(AreaPositionContext context) { + IoBuffer buffer = getBuffer(context.getPlayer(),context.getLocation()); + buffer.cypherOpcode(context.getPlayer().getSession().getIsaacPair().getOutput());context.getPlayer().getSession().write(buffer); + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/out/UpdateClanChat.java b/Server/src/main/core/net/packet/out/UpdateClanChat.java new file mode 100644 index 0000000..86e298e --- /dev/null +++ b/Server/src/main/core/net/packet/out/UpdateClanChat.java @@ -0,0 +1,43 @@ +package core.net.packet.out; + +import core.game.system.communication.ClanEntry; +import core.game.system.communication.ClanRepository; +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.PacketHeader; +import core.net.packet.context.ClanContext; +import core.tools.StringUtils; + +/** + * Handles the update clan chat outgoing packet. + * @author Emperor + */ +public final class UpdateClanChat implements OutgoingPacket { + + @Override + public void send(ClanContext context) { + IoBuffer buffer = new IoBuffer(55, PacketHeader.SHORT); + ClanRepository clan = context.getClan(); + if (!context.isLeave()) { + buffer.putLong(StringUtils.stringToLong(clan.getOwner())); + buffer.putLong(StringUtils.stringToLong(clan.getName())); + buffer.put(clan.getKickRequirement().getValue()); + int size = clan.getPlayers().size(); + if (size > 100) { + size = 100; + } + buffer.put(size); + for (int i = 0; i < size; i++) { + ClanEntry entry = clan.getPlayers().get(i); + String name = entry.getName(); + buffer.putLong(StringUtils.stringToLong(name)).putShort(entry.getWorldId()); + buffer.put(clan.getRank(entry).getValue()); + buffer.putString("World " + entry.getWorldId()); + } + } else { + buffer.putLong(0); + } + buffer.cypherOpcode(context.getPlayer().getSession().getIsaacPair().getOutput());context.getPlayer().getSession().write(buffer); + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/out/UpdateGroundItemAmount.java b/Server/src/main/core/net/packet/out/UpdateGroundItemAmount.java new file mode 100644 index 0000000..21a764a --- /dev/null +++ b/Server/src/main/core/net/packet/out/UpdateGroundItemAmount.java @@ -0,0 +1,34 @@ +package core.net.packet.out; + +import core.game.node.entity.player.Player; +import core.game.node.item.Item; +import core.game.world.map.Location; +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.context.BuildItemContext; + +/** + * Updates the ground item amount. + * @author Emperor + */ +public final class UpdateGroundItemAmount implements OutgoingPacket { + + /** + * Writes the packet. + * @param buffer The buffer. + * @param item The item. + */ + public static IoBuffer write(IoBuffer buffer, Item item, int oldAmount) { + Location l = item.getLocation(); + buffer.put(14).put((l.getChunkOffsetX() << 4) | (l.getChunkOffsetY() & 0x7)).putShort(item.getId()).putShort(oldAmount).putShort(item.getAmount()); + return buffer; + } + + @Override + public void send(BuildItemContext context) { + Player player = context.getPlayer(); + Item item = context.getItem(); + IoBuffer buffer = write(UpdateAreaPosition.getBuffer(player, item.getLocation().getChunkBase()), item, context.getOldAmount()); + buffer.cypherOpcode(context.getPlayer().getSession().getIsaacPair().getOutput());player.getDetails().getSession().write(buffer); + } +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/out/UpdateRandomFile.java b/Server/src/main/core/net/packet/out/UpdateRandomFile.java new file mode 100644 index 0000000..3e51b2b --- /dev/null +++ b/Server/src/main/core/net/packet/out/UpdateRandomFile.java @@ -0,0 +1,27 @@ +package core.net.packet.out; + +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.context.PlayerContext; + +/** + * Updates the random.dat file for the player. + * @author Emperor + */ +public final class UpdateRandomFile implements OutgoingPacket { + + @Override + public void send(PlayerContext context) { + IoBuffer buffer = new IoBuffer(211); + buffer.putInt(1); // Let's assume this is UID. + buffer.put(0); + buffer.put(0); + buffer.put(0); + buffer.put(0); + for (int i = 0; i < 4; i++) { + buffer.putInt(i + 100); + } + // TODO context.getPlayer().getSession().write(buffer); + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/out/UpdateSceneGraph.java b/Server/src/main/core/net/packet/out/UpdateSceneGraph.java new file mode 100644 index 0000000..a93435b --- /dev/null +++ b/Server/src/main/core/net/packet/out/UpdateSceneGraph.java @@ -0,0 +1,39 @@ +package core.net.packet.out; + +import core.game.node.entity.player.Player; +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.PacketHeader; +import core.net.packet.context.SceneGraphContext; +import core.game.system.config.XteaParser; + +/** + * The update scene graph outgoing packet. + * @author Emperor + */ +public final class UpdateSceneGraph implements OutgoingPacket { + + @Override + public void send(SceneGraphContext context) { + IoBuffer buffer = new IoBuffer(162, PacketHeader.SHORT); + Player player = context.getPlayer(); + buffer.cypherOpcode(player.getSession().getIsaacPair().getOutput()); + player.getPlayerFlags().setLastSceneGraph(player.getLocation()); + buffer.putShortA(player.getLocation().getSceneX()); + for (int regionX = (player.getLocation().getRegionX() - 6) / 8; regionX <= ((player.getLocation().getRegionX() + 6) / 8); regionX++) { + for (int regionY = (player.getLocation().getRegionY() - 6) / 8; regionY <= ((player.getLocation().getRegionY() + 6) / 8); regionY++) { + int[] keys = XteaParser.Companion.getRegionXTEA(regionX << 8 | regionY); + for (int i = 0; i < 4; i++) { + buffer.putIntB(keys[i]); + } + } + } + + buffer.putS(player.getLocation().getZ()); + buffer.putShort(player.getLocation().getRegionX()); + buffer.putShortA(player.getLocation().getRegionY()); + buffer.putShortA(player.getLocation().getSceneY()); + player.getDetails().getSession().write(buffer); + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/out/Varbit.java b/Server/src/main/core/net/packet/out/Varbit.java new file mode 100644 index 0000000..e8cfc68 --- /dev/null +++ b/Server/src/main/core/net/packet/out/Varbit.java @@ -0,0 +1,21 @@ +package core.net.packet.out; + +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.context.VarbitContext; + +public class Varbit implements OutgoingPacket { + @Override + public void send(VarbitContext varbitContext) { + IoBuffer buffer; + if(varbitContext.value > 255){ + buffer = new IoBuffer(84); + buffer.putLEInt((128 | varbitContext.value) & 255); + } else { + buffer = new IoBuffer(37); + buffer.put((byte) 128 | varbitContext.value); + } + buffer.putLEShort(varbitContext.varbitId); + varbitContext.getPlayer().getSession().write(buffer); + } +} diff --git a/Server/src/main/core/net/packet/out/VarcUpdate.java b/Server/src/main/core/net/packet/out/VarcUpdate.java new file mode 100644 index 0000000..f536378 --- /dev/null +++ b/Server/src/main/core/net/packet/out/VarcUpdate.java @@ -0,0 +1,26 @@ +package core.net.packet.out; + +import core.game.node.entity.player.Player; +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.context.VarcUpdateContext; + +public class VarcUpdate implements OutgoingPacket { + @Override + public void send(VarcUpdateContext varcUpdateContext) { + Player player = varcUpdateContext.getPlayer(); + if(varcUpdateContext.value <= 255) { + IoBuffer buffer = new IoBuffer(65); + buffer.putLEShort(player.getInterfaceManager().getPacketCount(1)); + buffer.putC((byte) varcUpdateContext.value); + buffer.putLEShortA(varcUpdateContext.varcId); + player.getSession().write(buffer); + } else { + IoBuffer buffer = new IoBuffer(69); + buffer.putLEShortA(player.getInterfaceManager().getPacketCount(1)); + buffer.putInt(varcUpdateContext.value); + buffer.putShortA(varcUpdateContext.varcId); + player.getSession().write(buffer); + } + } +} diff --git a/Server/src/main/core/net/packet/out/WeightUpdate.java b/Server/src/main/core/net/packet/out/WeightUpdate.java new file mode 100644 index 0000000..935e0b7 --- /dev/null +++ b/Server/src/main/core/net/packet/out/WeightUpdate.java @@ -0,0 +1,20 @@ +package core.net.packet.out; + +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.context.PlayerContext; + +/** + * Handles the outgoing weight update packet. + * @author Emperor + */ +public final class WeightUpdate implements OutgoingPacket { + + @Override + public void send(PlayerContext context) { + IoBuffer buffer = new IoBuffer(174); + buffer.putShort((int) context.getPlayer().getSettings().getWeight()); + // TODO context.getPlayer().getSession().write(buffer); + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/packet/out/WindowsPane.java b/Server/src/main/core/net/packet/out/WindowsPane.java new file mode 100644 index 0000000..97a59b9 --- /dev/null +++ b/Server/src/main/core/net/packet/out/WindowsPane.java @@ -0,0 +1,22 @@ +package core.net.packet.out; + +import core.net.packet.IoBuffer; +import core.net.packet.OutgoingPacket; +import core.net.packet.context.WindowsPaneContext; + +/** + * Handles the windows pane outgoing packet. + * @author Emperor + */ +public final class WindowsPane implements OutgoingPacket { + + @Override + public void send(WindowsPaneContext context) { + IoBuffer buffer = new IoBuffer(145); + buffer.cypherOpcode(context.getPlayer().getSession().getIsaacPair().getOutput());buffer.putLEShortA(context.getWindowId()); + buffer.putS(context.getType()); + buffer.putLEShortA(context.getPlayer().getInterfaceManager().getPacketCount(1)); + context.getPlayer().getDetails().getSession().write(buffer); + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/producer/GameEventProducer.java b/Server/src/main/core/net/producer/GameEventProducer.java new file mode 100644 index 0000000..d28255e --- /dev/null +++ b/Server/src/main/core/net/producer/GameEventProducer.java @@ -0,0 +1,28 @@ +package core.net.producer; + +import core.net.EventProducer; +import core.net.IoReadEvent; +import core.net.IoSession; +import core.net.IoWriteEvent; +import core.net.event.GameReadEvent; +import core.net.event.GameWriteEvent; + +import java.nio.ByteBuffer; + +/** + * Produces game packet I/O events. + * @author Emperor + */ +public final class GameEventProducer implements EventProducer { + + @Override + public IoReadEvent produceReader(IoSession session, ByteBuffer buffer) { + return new GameReadEvent(session, buffer); + } + + @Override + public IoWriteEvent produceWriter(IoSession session, Object context) { + return new GameWriteEvent(session, context); + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/producer/HSEventProducer.java b/Server/src/main/core/net/producer/HSEventProducer.java new file mode 100644 index 0000000..5fb3895 --- /dev/null +++ b/Server/src/main/core/net/producer/HSEventProducer.java @@ -0,0 +1,28 @@ +package core.net.producer; + +import core.net.EventProducer; +import core.net.IoReadEvent; +import core.net.IoSession; +import core.net.IoWriteEvent; +import core.net.event.HSReadEvent; +import core.net.event.HSWriteEvent; + +import java.nio.ByteBuffer; + +/** + * Produces I/O events for the handshake protocol. + * @author Emperor + */ +public final class HSEventProducer implements EventProducer { + + @Override + public IoReadEvent produceReader(IoSession session, ByteBuffer buffer) { + return new HSReadEvent(session, buffer); + } + + @Override + public IoWriteEvent produceWriter(IoSession session, Object context) { + return new HSWriteEvent(session, context); + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/producer/JS5EventProducer.java b/Server/src/main/core/net/producer/JS5EventProducer.java new file mode 100644 index 0000000..26cf863 --- /dev/null +++ b/Server/src/main/core/net/producer/JS5EventProducer.java @@ -0,0 +1,29 @@ +package core.net.producer; + +import core.net.EventProducer; +import core.net.IoReadEvent; +import core.net.IoSession; +import core.net.IoWriteEvent; +import core.net.event.JS5ReadEvent; +import core.net.event.JS5WriteEvent; + +import java.nio.ByteBuffer; + +/** + * Produces JS-5 I/O events. + * @author Tyler + * @author Emperor + */ +public class JS5EventProducer implements EventProducer { + + @Override + public IoReadEvent produceReader(IoSession session, ByteBuffer buffer) { + return new JS5ReadEvent(session, buffer); + } + + @Override + public IoWriteEvent produceWriter(IoSession session, Object context) { + return new JS5WriteEvent(session, context); + } + +} diff --git a/Server/src/main/core/net/producer/LoginEventProducer.java b/Server/src/main/core/net/producer/LoginEventProducer.java new file mode 100644 index 0000000..a3c2e0f --- /dev/null +++ b/Server/src/main/core/net/producer/LoginEventProducer.java @@ -0,0 +1,28 @@ +package core.net.producer; + +import core.net.EventProducer; +import core.net.IoReadEvent; +import core.net.IoSession; +import core.net.IoWriteEvent; +import core.net.event.LoginWriteEvent; +import core.net.event.LoginReadEvent; + +import java.nio.ByteBuffer; + +/** + * Produces login I/O events. + * @author Emperor + */ +public final class LoginEventProducer implements EventProducer { + + @Override + public IoReadEvent produceReader(IoSession session, ByteBuffer buffer) { + return new LoginReadEvent(session, buffer); + } + + @Override + public IoWriteEvent produceWriter(IoSession session, Object context) { + return new LoginWriteEvent(session, context); + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/producer/MSEventProducer.java b/Server/src/main/core/net/producer/MSEventProducer.java new file mode 100644 index 0000000..cc7400e --- /dev/null +++ b/Server/src/main/core/net/producer/MSEventProducer.java @@ -0,0 +1,28 @@ +package core.net.producer; + +import core.net.EventProducer; +import core.net.IoReadEvent; +import core.net.IoSession; +import core.net.IoWriteEvent; +import core.net.event.MSReadEvent; +import core.net.event.MSWriteEvent; + +import java.nio.ByteBuffer; + +/** + * Handles Management server events. + * @author Emperor + */ +public final class MSEventProducer implements EventProducer { + + @Override + public IoReadEvent produceReader(IoSession session, ByteBuffer buffer) { + return new MSReadEvent(session, buffer); + } + + @Override + public IoWriteEvent produceWriter(IoSession session, Object context) { + return new MSWriteEvent(session, context); + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/producer/MSHSEventProducer.java b/Server/src/main/core/net/producer/MSHSEventProducer.java new file mode 100644 index 0000000..3372461 --- /dev/null +++ b/Server/src/main/core/net/producer/MSHSEventProducer.java @@ -0,0 +1,28 @@ +package core.net.producer; + +import core.net.EventProducer; +import core.net.IoReadEvent; +import core.net.IoSession; +import core.net.IoWriteEvent; +import core.net.event.MSHSReadEvent; +import core.net.event.MSHSWriteEvent; + +import java.nio.ByteBuffer; + +/** + * Handles the Management server handshake event producing. + * @author Emperor + */ +public final class MSHSEventProducer implements EventProducer { + + @Override + public IoReadEvent produceReader(IoSession session, ByteBuffer buffer) { + return new MSHSReadEvent(session, buffer); + } + + @Override + public IoWriteEvent produceWriter(IoSession session, Object context) { + return new MSHSWriteEvent(session, context); + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/producer/RegistryEventProducer.java b/Server/src/main/core/net/producer/RegistryEventProducer.java new file mode 100644 index 0000000..3986deb --- /dev/null +++ b/Server/src/main/core/net/producer/RegistryEventProducer.java @@ -0,0 +1,28 @@ +package core.net.producer; + +import core.net.EventProducer; +import core.net.IoReadEvent; +import core.net.IoSession; +import core.net.IoWriteEvent; +import core.net.event.RegistryReadEvent; +import core.net.event.RegistryWriteEvent; + +import java.nio.ByteBuffer; + +/** + * Handles world server registry. + * @author Emperor + */ +public final class RegistryEventProducer implements EventProducer { + + @Override + public IoReadEvent produceReader(IoSession session, ByteBuffer buffer) { + return new RegistryReadEvent(session, buffer); + } + + @Override + public IoWriteEvent produceWriter(IoSession session, Object context) { + return new RegistryWriteEvent(session, context); + } + +} \ No newline at end of file diff --git a/Server/src/main/core/net/registry/AccountRegister.java b/Server/src/main/core/net/registry/AccountRegister.java new file mode 100644 index 0000000..dff9f3f --- /dev/null +++ b/Server/src/main/core/net/registry/AccountRegister.java @@ -0,0 +1,143 @@ +package core.net.registry; + +import core.cache.misc.buffer.ByteBufferUtils; +import core.game.system.task.Pulse; +import core.net.Constants; +import core.net.IoSession; +import core.ServerConstants; +import core.auth.UserAccountInfo; +import core.tools.Log; +import core.tools.SystemLogger; +import core.game.world.GameWorld; +import core.net.packet.in.Login; + +import java.nio.ByteBuffer; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static core.api.ContentAPIKt.log; + +/** + * Handles the registry of new accounts. + * @author Vexia + * + */ +public class AccountRegister { + /** + * The pattern compiler. + */ + private static final Pattern PATTERN = Pattern.compile("[a-z0-9_]{1,12}"); + + /** + * Reads the incoming opcode of an account register. + * @param session the session. + * @param opcode the opcode. + * @param buffer the buffer. + */ + public static void read(final IoSession session, int opcode, ByteBuffer buffer) { + int day,month,year,country; + UserAccountInfo info = UserAccountInfo.createDefault(); + switch (opcode) { + case 147://details + day = buffer.get(); + month = buffer.get(); + year = buffer.getShort(); + country = buffer.getShort(); + response(session, RegistryResponse.SUCCESS); + break; + case 186://username + final String username = ByteBufferUtils.getString(buffer).replace(" ", "_").toLowerCase().replace("|", ""); + info.setUsername(username); + if (username.length() <= 0 || username.length() > 12) { + response(session, RegistryResponse.INVALID_USERNAME); + break; + } + if (invalidUsername(username)) { + + response(session,RegistryResponse.INVALID_USERNAME); + break; + } + + if (!GameWorld.getAuthenticator().canCreateAccountWith(info)) { + response(session, RegistryResponse.NOT_AVAILBLE_USER); + return; + } + response(session, RegistryResponse.SUCCESS); + break; + case 36://Register details + buffer.get(); //Useless size being written that is already written in the RSA block + buffer = Login.decryptRSABuffer(buffer, ServerConstants.EXPONENT, ServerConstants.MODULUS); + if(buffer.get() != 10){ //RSA header (aka did this decrypt properly) + log(AccountRegister.class, Log.ERR, "Decryption failed during registration :("); + response(session, RegistryResponse.CANNOT_CREATE); + break; + } + buffer.getShort(); // random data + int revision = buffer.getShort();//revision? + if (revision != Constants.REVISION) { + response(session, RegistryResponse.CANNOT_CREATE); + break; + } + final String name = ByteBufferUtils.getString(buffer).replace(" ", "_").toLowerCase().replace("|", ""); + buffer.getInt(); + String password = ByteBufferUtils.getString(buffer); + info.setUsername(name); + info.setPassword(password); + if (password.length() < 5 || password.length() > 20) { + response(session, RegistryResponse.INVALID_PASS_LENGTH); + break; + } + if (password.equals(name)) { + response(session, RegistryResponse.PASS_SIMILAR_TO_USER); + break; + } + if (invalidUsername(name)) { + response(session, RegistryResponse.INVALID_USERNAME); + break; + } + buffer.getInt(); + buffer.getShort(); + day = buffer.get(); + month = buffer.get(); + buffer.getInt(); + year = buffer.getShort(); + country = buffer.getShort(); + buffer.getInt(); + if (!GameWorld.getAuthenticator().canCreateAccountWith(info)) { + response(session, RegistryResponse.CANNOT_CREATE); + return; + } + GameWorld.getAuthenticator().createAccountWith(info); + GameWorld.getPulser().submit(new Pulse() { + @Override + public boolean pulse() { + response(session, RegistryResponse.SUCCESS); + return true; + } + }); + break; + default: + log(AccountRegister.class, Log.ERR, "Unhandled account registry opcode = " + opcode); + break; + } + } + + /** + * Sends a registry response code. + * @param response the response. + */ + private static void response(IoSession session, RegistryResponse response) { + ByteBuffer buf = ByteBuffer.allocate(100); + buf.put((byte) response.getId()); + session.queue(buf.flip()); + } + + /** + * Checks if a username is valid. + * @return {@code True} if so. + */ + public static boolean invalidUsername(final String username) { + Matcher matcher = PATTERN.matcher(username); + return !matcher.matches(); + } +} diff --git a/Server/src/main/core/net/registry/RegistryDetails.java b/Server/src/main/core/net/registry/RegistryDetails.java new file mode 100644 index 0000000..443eaa5 --- /dev/null +++ b/Server/src/main/core/net/registry/RegistryDetails.java @@ -0,0 +1,78 @@ +package core.net.registry; + +import java.sql.Date; + +/** + * Represents details of an account to register. + * @author Vexia + * + */ +public class RegistryDetails { + + /** + * The username. + */ + private final String username; + + /** + * The password. + */ + private final String password; + + /** + * The date of birth. + */ + private final Date birth; + + /** + * The country. + */ + private final int country; + + /** + * Constructs a new {@Code RegistryDetails} {@Code Object} + * @param username The username to register. + * @param password The password to register. + * @param birth The birth year. + * @param country The country code. + */ + public RegistryDetails(String username, String password, Date birth, int country) { + this.username = username; + this.password = password; + this.birth = birth; + this.country = country; + } + + /** + * Gets the username. + * @return the username. + */ + public String getUsername() { + return username; + } + + /** + * Gets the password. + * @return the password. + */ + public String getPassword() { + return password; + } + + /** + * Gets the birth. + * @return the birth. + */ + public Date getBirth() { + return birth; + } + + /** + * Gets the country. + * @return the country. + */ + public int getCountry() { + return country; + } + +} diff --git a/Server/src/main/core/net/registry/RegistryResponse.java b/Server/src/main/core/net/registry/RegistryResponse.java new file mode 100644 index 0000000..573e729 --- /dev/null +++ b/Server/src/main/core/net/registry/RegistryResponse.java @@ -0,0 +1,46 @@ +package core.net.registry; + +/** + * An account registry response. + * @author Vexia + * + */ +public enum RegistryResponse { + SUCCESS(2), + CONTACT_ERROR(3), + SERVER_BUSY(7), + CANNOT_CREATE(9), + INVALID_BIRTH(10), + FUTURE_BIRTH(11), + BIRTH_THIS_YEAR(12), + BIRTH_LAST_YEAR(13), + INVALID_COUNTRY(14), + NOT_AVAILBLE_USER(20), + INVALID_USERNAME(22), + INVALID_PASS_LENGTH(30), + INVALID_PASS(31), + WEAK_PASS(32), + PASS_SIMILAR_TO_USER(33); + + /** + * The response id. + */ + private final int id; + + /** + * Constructs a new {@Code RegistryResponse} {@Code Object} + * @param id the id. + */ + RegistryResponse(int id) { + this.id = id; + } + + /** + * Gets the id. + * @return the id. + */ + public int getId() { + return id; + } + +} diff --git a/Server/src/main/core/plugin/ClassScanner.kt b/Server/src/main/core/plugin/ClassScanner.kt new file mode 100644 index 0000000..2ad6e5f --- /dev/null +++ b/Server/src/main/core/plugin/ClassScanner.kt @@ -0,0 +1,228 @@ +package core.plugin + +import core.ServerConstants +import core.api.* +import core.game.activity.ActivityManager +import core.game.activity.ActivityPlugin +import core.game.bots.PlayerScripts +import core.game.interaction.InteractionListener +import core.game.interaction.InterfaceListener +import core.game.node.entity.Entity +import core.game.node.entity.npc.NPCBehavior +import core.game.node.entity.player.info.login.LoginConfiguration +import core.game.node.entity.player.info.login.PlayerSaveParser +import core.game.node.entity.player.info.login.PlayerSaver +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.player.link.quest.QuestRepository +import core.game.system.timer.RSTimer +import core.game.system.timer.TimerRegistry +import core.game.world.GameWorld +import core.game.world.map.Location +import core.game.world.map.zone.MapZone +import core.game.world.map.zone.ZoneBuilder +import core.game.worldevents.WorldEvent +import core.game.worldevents.WorldEvents +import core.tools.Log +import core.tools.SystemLogger.logStartup +import io.github.classgraph.ClassGraph +import io.github.classgraph.ClassInfo +import io.github.classgraph.ScanResult +import java.util.function.Consumer + +/** + * A class used to reflectively scan the classpath and load classes + * @author Ceikry + */ +object ClassScanner { + var disabledPlugins = HashMap() + /** + * The amount of content interfaces loaded. + */ + var amountLoaded = 0 + private set + + var numPlugins = 0 + private set + + /** + * The currently loaded plugin names. + */ + private var loadedPlugins: MutableList? = ArrayList() + + /** + * The last loaded plugin. + */ + private val lastLoaded: String? = null + + lateinit var scanResults: ScanResult + + @JvmStatic fun scanClasspath() { + scanResults = ClassGraph().enableClassInfo().enableAnnotationInfo().scan() + } + + /** + * Scan the classpath for reflection-loaded content classes such as listeners, "plugins", etc + */ + @JvmStatic + fun loadPureInterfaces() { + try { + loadContentInterfacesFrom(scanResults) + logStartup("Loaded $amountLoaded content interfaces.") + } catch (t: Throwable) { + log(this::class.java, Log.ERR, "Error initializing Plugins -> " + t.localizedMessage + " for file -> " + lastLoaded) + t.printStackTrace() + } catch (e: Exception) { + log(this::class.java, Log.ERR, "Error initializing Plugins -> " + e.localizedMessage + " for file -> " + lastLoaded) + e.printStackTrace() + } + } + + fun loadTimers () { + scanResults.getSubclasses ("core.game.system.timer.RSTimer").filter { !it.isAbstract }.forEach { + try { + val clazz = it.loadClass().newInstance() as RSTimer + TimerRegistry.registerTimer (clazz) + } catch (e: Exception) { + log(this::class.java, Log.ERR, "Error registering timer instance: ${it.simpleName}") + e.printStackTrace() + } + } + } + + private fun loadContentInterfacesFrom(scanResults: ScanResult) { + scanResults.getClassesImplementing("core.api.ContentInterface").filter { !it.isAbstract }.forEach { + try { + val clazz = it.loadClass().newInstance() + if(clazz is WorldEvent) { //Check world event first so if it's not active we don't register tick listeners, etc. + if (!clazz.checkActive(ServerConstants.STARTUP_MOMENT)) return@forEach + WorldEvents.add(clazz) + } + if(clazz is LoginListener) GameWorld.loginListeners.add(clazz) + if(clazz is LogoutListener) GameWorld.logoutListeners.add(clazz) + if(clazz is TickListener) GameWorld.tickListeners.add(clazz) + if(clazz is StartupListener) GameWorld.startupListeners.add(clazz) + if(clazz is ShutdownListener) GameWorld.shutdownListeners.add(clazz) + if(clazz is PersistWorld) GameWorld.worldPersists.add(clazz) + if(clazz is InteractionListener) clazz.defineListeners().also { clazz.defineDestinationOverrides() } + if(clazz is InterfaceListener) clazz.defineInterfaceListeners() + if(clazz is Commands) clazz.defineCommands() + if(clazz is NPCBehavior) NPCBehavior.register(clazz.ids, clazz) + if(clazz is PersistPlayer) { + PlayerSaver.contentHooks.add(clazz) + PlayerSaveParser.contentHooks.add(clazz) + } + if(clazz is MapArea) + { + val zone = object : MapZone(clazz.javaClass.simpleName + "MapArea", true, *clazz.getRestrictions()){ + override fun enter(e: Entity?): Boolean { + clazz.areaEnter(e ?: return super.enter(null)) + return super.enter(e) + } + + override fun leave(e: Entity?, logout: Boolean): Boolean { + clazz.areaLeave(e ?: return super.leave(null, logout), logout) + return super.leave(e, logout) + } + + override fun move(e: Entity?, from: Location?, to: Location?): Boolean { + if(e != null && from != null && to != null) clazz.entityStep(e, to, from) + return super.move(e, from, to) + } + } + for(border in clazz.defineAreaBorders()) zone.register(border) + ZoneBuilder.configure(zone) + log(this::class.java, Log.FINE, "Configured zone: ${clazz.javaClass.simpleName + "MapArea"}") + MapArea.zoneMaps[clazz.javaClass.simpleName + "MapArea"] = zone + } + amountLoaded++ + } catch (e: Exception) { + log(this::class.java, Log.ERR, "Error loading content: ${it.simpleName}, ${e.localizedMessage}") + e.printStackTrace() + } + } + } + + @JvmStatic + fun loadSideEffectfulPlugins() { + loadedPlugins!!.clear() + loadPluginsFrom(scanResults) + logStartup("We still have $numPlugins legacy plugins being loaded.") + } + + private fun loadPluginsFrom(scanResults: ScanResult) { + scanResults.getClassesWithAnnotation("core.plugin.Initializable").forEach(Consumer { p: ClassInfo -> + try { + val clazz = p.loadClass().getDeclaredConstructor().newInstance() + if (clazz is Plugin<*>) { + definePlugin(clazz) + } + } catch (t: Throwable) { + log(this::class.java, Log.ERR, "Failed to load plugin ${p.name}.") + + if (t is NoSuchMethodException && p.superclass.simpleName == core.game.dialogue.DialoguePlugin::class.simpleName) { + log(this::class.java, Log.ERR, + "Make sure the constructor signature matches " + + "`${p.simpleName}(player: Player? = null) : DialoguePlugin(player)'." + ) + } + + t.printStackTrace() + } + }) + + scanResults.getClassesWithAnnotation("core.game.bots.PlayerCompatible").forEach { res -> + val description = res.getAnnotationInfo("core.game.bots.ScriptDescription").parameterValues[0].value as Array + val identifier = res.getAnnotationInfo("core.game.bots.ScriptIdentifier").parameterValues[0].value.toString() + val name = res.getAnnotationInfo("core.game.bots.ScriptName").parameterValues[0].value.toString() + PlayerScripts.identifierMap[identifier] = PlayerScripts.PlayerScript(identifier, description, name, res.loadClass()) + } + } + + /** + * Defines a list of plugins. + * @param plugins the plugins. + */ + @JvmStatic + fun definePlugins(vararg plugins: Plugin<*>) { + val pluginsLength = plugins.size + for (i in 0 until pluginsLength) { + val p = plugins[i] + definePlugin(p) + } + } + + /** + * Defines the plugin. + * @param plugin The plugin. + */ + @JvmStatic + fun definePlugin(plugin: Plugin<*>) { + try { + var manifest = plugin.javaClass.getAnnotation(PluginManifest::class.java) + if (manifest == null) { + manifest = plugin.javaClass.superclass.getAnnotation(PluginManifest::class.java) + } else { + if (disabledPlugins[manifest.name] != null) { + return + } + } + if (manifest == null || manifest.type == PluginType.ACTION) { + plugin.newInstance(null) + } else { + when (manifest.type) { + PluginType.DIALOGUE -> (plugin as core.game.dialogue.DialoguePlugin).init() + PluginType.ACTIVITY -> ActivityManager.register(plugin as ActivityPlugin) + PluginType.LOGIN -> LoginConfiguration.getLoginPlugins().add(plugin as Plugin) + PluginType.QUEST -> { + plugin.newInstance(null) + QuestRepository.register(plugin as Quest) + } + else -> log(this::class.java, Log.WARN, "Unknown Manifest: " + manifest.type) + } + } + numPlugins++ + } catch (e: Throwable) { + e.printStackTrace() + } + } +} diff --git a/Server/src/main/core/plugin/CorePluginTypes/ManagerPlugin.java b/Server/src/main/core/plugin/CorePluginTypes/ManagerPlugin.java new file mode 100644 index 0000000..bb25c13 --- /dev/null +++ b/Server/src/main/core/plugin/CorePluginTypes/ManagerPlugin.java @@ -0,0 +1,12 @@ +package core.plugin.CorePluginTypes; + +import core.plugin.Plugin; + +public abstract class ManagerPlugin implements Plugin { + public abstract void tick(); + + @Override + public Object fireEvent(String identifier, Object... args) { + return null; + } +} diff --git a/Server/src/main/core/plugin/CorePluginTypes/Managers.java b/Server/src/main/core/plugin/CorePluginTypes/Managers.java new file mode 100644 index 0000000..0ebb503 --- /dev/null +++ b/Server/src/main/core/plugin/CorePluginTypes/Managers.java @@ -0,0 +1,20 @@ +package core.plugin.CorePluginTypes; + +import java.util.ArrayList; +import java.util.List; + +public class Managers { + + private static List plugins = new ArrayList<>(20); + public static void register(ManagerPlugin plugin){ + if(plugin != null){ + plugins.add(plugin); + } + } + + public static void tick(){ + for(ManagerPlugin p : plugins){ + p.tick(); + } + } +} diff --git a/Server/src/main/core/plugin/CorePluginTypes/StartupPlugin.java b/Server/src/main/core/plugin/CorePluginTypes/StartupPlugin.java new file mode 100644 index 0000000..169ac15 --- /dev/null +++ b/Server/src/main/core/plugin/CorePluginTypes/StartupPlugin.java @@ -0,0 +1,7 @@ +package core.plugin.CorePluginTypes; + +import core.plugin.Plugin; + +public abstract class StartupPlugin implements Plugin { + public abstract void run(); +} diff --git a/Server/src/main/core/plugin/CorePluginTypes/XPGainPlugins.kt b/Server/src/main/core/plugin/CorePluginTypes/XPGainPlugins.kt new file mode 100644 index 0000000..976ca3d --- /dev/null +++ b/Server/src/main/core/plugin/CorePluginTypes/XPGainPlugins.kt @@ -0,0 +1,28 @@ +package core.plugin.CorePluginTypes + +import core.game.node.entity.player.Player +import core.plugin.Plugin + +object XPGainPlugins { + @JvmStatic + private val plugins = ArrayList() + @JvmStatic + fun add(plugin: XPGainPlugin){ + plugins.add(plugin) + } + @JvmStatic + fun run(player: Player, skill: Int, amount: Double){ + if(player.isArtificial) return + plugins.forEach { + it.run(player,skill,amount) + } + } +} + +abstract class XPGainPlugin : Plugin { + override fun newInstance(arg: Any?): Plugin { + XPGainPlugins.add(this) + return this + } + abstract fun run(player: Player, skill: Int, amount: Double) +} \ No newline at end of file diff --git a/Server/src/main/core/plugin/Initializable.java b/Server/src/main/core/plugin/Initializable.java new file mode 100644 index 0000000..b48044f --- /dev/null +++ b/Server/src/main/core/plugin/Initializable.java @@ -0,0 +1,18 @@ +package core.plugin; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Represents a initializable piece of content. + * + * @author Jonathan + */ + +@Retention(RetentionPolicy.RUNTIME) +@Target(value = ElementType.TYPE) +public @interface Initializable { + +} diff --git a/Server/src/main/core/plugin/Plugin.java b/Server/src/main/core/plugin/Plugin.java new file mode 100644 index 0000000..b9f81b4 --- /dev/null +++ b/Server/src/main/core/plugin/Plugin.java @@ -0,0 +1,29 @@ +package core.plugin; + +import core.game.node.entity.player.Player; + +/** + * Represents a plugin. + * @author Emperor + * @param The argument type. + */ +public interface Plugin { + + /** + * Creates a new instance. + * @param arg The argument. + * @return The plugin instance created. + */ + public Plugin newInstance(T arg) throws Throwable; + + /** + * Fires a plugin event. + * @param identifier The identifier. + * @param args The arguments. + * @return Specified by the plugin implementation. + */ + Object fireEvent(String identifier, Object... args); + + public default void handleSelectionCallback(int skill, Player player){}; + +} \ No newline at end of file diff --git a/Server/src/main/core/plugin/PluginManifest.java b/Server/src/main/core/plugin/PluginManifest.java new file mode 100644 index 0000000..eb5e603 --- /dev/null +++ b/Server/src/main/core/plugin/PluginManifest.java @@ -0,0 +1,19 @@ +package core.plugin; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Represents a plugin manifest. + * @author Emperor + */ +@Retention(RetentionPolicy.RUNTIME) +public @interface PluginManifest { + + /** + * Gets the plugin type. + * @return The plugin type. + */ + public PluginType type() default PluginType.ACTION; + public String name() default ""; +} \ No newline at end of file diff --git a/Server/src/main/core/plugin/PluginType.java b/Server/src/main/core/plugin/PluginType.java new file mode 100644 index 0000000..0dd8b18 --- /dev/null +++ b/Server/src/main/core/plugin/PluginType.java @@ -0,0 +1,39 @@ +package core.plugin; + +/** + * Represents the plugin types. + * @author Emperor + */ +public enum PluginType { + + /** + * Action plugin type. + */ + ACTION, + + /** + * Dialogue plugin type. + */ + DIALOGUE, + + /** + * Activity plugin type. + */ + ACTIVITY, + + /** + * Player login plugin type. + */ + LOGIN, + + /** + * Player logout plugin type. + */ + LOGOUT, + + /** + * Quest plugin type. + */ + QUEST; + +} \ No newline at end of file diff --git a/Server/src/main/core/storage/AccountStorageProvider.kt b/Server/src/main/core/storage/AccountStorageProvider.kt new file mode 100644 index 0000000..6159a69 --- /dev/null +++ b/Server/src/main/core/storage/AccountStorageProvider.kt @@ -0,0 +1,13 @@ +package core.storage + +import core.auth.UserAccountInfo + +interface AccountStorageProvider { + fun checkUsernameTaken(username: String): Boolean + fun getAccountInfo(username: String): UserAccountInfo + fun getUsernamesWithIP(ip: String) : List + fun store(info: UserAccountInfo) + fun update(info: UserAccountInfo) + fun remove(info: UserAccountInfo) + fun getOnlineFriends(username: String) : List +} diff --git a/Server/src/main/core/storage/InMemoryStorageProvider.kt b/Server/src/main/core/storage/InMemoryStorageProvider.kt new file mode 100644 index 0000000..d0780ce --- /dev/null +++ b/Server/src/main/core/storage/InMemoryStorageProvider.kt @@ -0,0 +1,36 @@ +package core.storage + +import core.auth.UserAccountInfo + +class InMemoryStorageProvider : AccountStorageProvider { + private val storage = HashMap() + + override fun checkUsernameTaken(username: String): Boolean { + return storage[username] != null + } + + override fun getAccountInfo(username: String): UserAccountInfo { + return storage[username] ?: UserAccountInfo.createDefault().also { it.uid = username.hashCode(); storage[username] = it } + } + + override fun store(info: UserAccountInfo) { + info.uid = info.username.hashCode() + storage[info.username] = info + } + + override fun update(info: UserAccountInfo) { + storage[info.username] = info + } + + override fun remove(info: UserAccountInfo) { + storage.remove(info.username) + } + + override fun getOnlineFriends(username: String): List { + return ArrayList() + } + + override fun getUsernamesWithIP(ip: String): List { + return ArrayList() + } +} diff --git a/Server/src/main/core/storage/SQLStorageProvider.kt b/Server/src/main/core/storage/SQLStorageProvider.kt new file mode 100644 index 0000000..e24e224 --- /dev/null +++ b/Server/src/main/core/storage/SQLStorageProvider.kt @@ -0,0 +1,271 @@ +package core.storage + +import core.game.system.communication.CommunicationInfo +import core.auth.UserAccountInfo +import core.game.world.repository.Repository +import java.lang.Long.max +import java.sql.* + +class SQLStorageProvider : AccountStorageProvider { + var connectionString = "" + var connectionUsername = "" + var connectionPassword = "" + + fun getConnection(): Connection { + Class.forName("com.mysql.cj.jdbc.Driver") + return DriverManager.getConnection(connectionString, connectionUsername, connectionPassword) + } + + fun configure(host: String, databaseName: String, username: String, password: String) { + connectionString = "jdbc:mysql://$host/$databaseName?useTimezone=true&serverTimezone=UTC" + connectionUsername = username + connectionPassword = password + } + + override fun checkUsernameTaken(username: String): Boolean { + val conn = getConnection() + conn.use { + val compiledUsernameQuery = it.prepareStatement(usernameQuery) + compiledUsernameQuery.setString(1, username.toLowerCase()) + val result = compiledUsernameQuery.executeQuery() + val exists = result.next() + result.close() + return exists + } + } + + override fun getAccountInfo(username: String): UserAccountInfo { + val conn = getConnection() + conn.use { con -> + val compiledAccountInfoQuery = con.prepareStatement(accountInfoQuery) + compiledAccountInfoQuery.setString(1, username.toLowerCase()) + val result = compiledAccountInfoQuery.executeQuery() + if (result.next()) { + val userData = UserAccountInfo.createDefault() + userData.username = username + + result.getString(2) ?.let { userData.password = it } + result.getInt(3) .let { userData.uid = it } + result.getInt(4) .let { userData.rights = it } + result.getInt(5) .let { userData.credits = it } + result.getString(6) ?.let { userData.ip = it } + result.getString(7) ?.let { userData.lastUsedIp = it } + result.getLong(8) .let { userData.muteEndTime = max(0L, it) } + result.getLong(9) .let { userData.banEndTime = max(0L, it) } + result.getString(10) ?.let { userData.contacts = it } + result.getString(11) ?.let { userData.blocked = it } + result.getString(12) ?.let { userData.clanName = it } + result.getString(13) ?.let { userData.currentClan = it } + result.getString(14) ?.let { userData.clanReqs = it } + result.getLong(15) .let { userData.timePlayed = max(0L, it) } + result.getLong(16) .let { userData.lastLogin = max(0L, it) } + result.getBoolean(17) .let { userData.online = it } + result.getTimestamp(18) .let { userData.joinDate = it ?: Timestamp(System.currentTimeMillis()) } + + userData.setInitialReferenceValues() + return userData + } else { + return UserAccountInfo.createDefault() + } + } + } + + override fun store(info: UserAccountInfo) { + val conn = getConnection() + conn.use { + val compiledInsertInfoQuery = it.prepareStatement(insertInfoQuery, Statement.RETURN_GENERATED_KEYS) + val emptyInfo = UserAccountInfo.createDefault() + if (info == emptyInfo) { + throw IllegalStateException("Tried to store empty data!") + } + emptyInfo.username = info.username + if (info == emptyInfo) { + throw IllegalStateException("Tried to store empty data!") + } + + if (checkUsernameTaken(info.username)) { + throw SQLDataException("Account already exists!") + } + compiledInsertInfoQuery.setString(1, info.username) + compiledInsertInfoQuery.setString(2, info.password) + compiledInsertInfoQuery.setInt(3, info.rights) + compiledInsertInfoQuery.setInt(4, info.credits) + compiledInsertInfoQuery.setString(5, info.ip) + compiledInsertInfoQuery.setString(6, info.ip) + compiledInsertInfoQuery.setLong(7, info.muteEndTime) + compiledInsertInfoQuery.setLong(8, info.banEndTime) + compiledInsertInfoQuery.setString(9, info.contacts) + compiledInsertInfoQuery.setString(10, info.blocked) + compiledInsertInfoQuery.setString(11, info.clanName) + compiledInsertInfoQuery.setString(12, info.currentClan) + compiledInsertInfoQuery.setString(13, info.clanReqs) + compiledInsertInfoQuery.setLong(14, info.timePlayed) + compiledInsertInfoQuery.setLong(15, info.lastLogin) + compiledInsertInfoQuery.setBoolean(16, info.online) + compiledInsertInfoQuery.setTimestamp(17, info.joinDate) + compiledInsertInfoQuery.execute() + val result = compiledInsertInfoQuery.generatedKeys + if (result.next()) { + info.uid = result.getInt(1) + } + info.setInitialReferenceValues() + } + } + + override fun update(info: UserAccountInfo) { + val (updatedFields, rawData) = info.getChangedFields() + val updateQueryString = buildUpdateInfoQuery(updatedFields) + val conn = getConnection() + + conn.use { + val compiledUpdateInfoQuery = it.prepareStatement(updateQueryString) + val emptyInfo = UserAccountInfo.createDefault() + if (info == emptyInfo) { + throw IllegalStateException("Tried to store empty data!") + } + emptyInfo.username = info.username + if (info == emptyInfo) { + throw IllegalStateException("Tried to store empty data!") + } + emptyInfo.password = info.password + if (info == emptyInfo) { + throw IllegalStateException("Tried to store empty data!") + } + if (updatedFields.isEmpty()) return + + var fieldIndex = 1 + for (updatedFieldIndex in updatedFields) { + when(val data = rawData[updatedFieldIndex]) { + is String -> compiledUpdateInfoQuery.setString(fieldIndex++, data) + is Int -> compiledUpdateInfoQuery.setInt(fieldIndex++, data) + is Boolean -> compiledUpdateInfoQuery.setBoolean(fieldIndex++, data) + is Long -> compiledUpdateInfoQuery.setLong(fieldIndex++, data) + } + } + compiledUpdateInfoQuery.setInt(fieldIndex, info.uid) + compiledUpdateInfoQuery.execute() + + info.initialValues = rawData + } + } + + override fun remove(info: UserAccountInfo) { + val conn = getConnection() + conn.use { + val compiledRemoveInfoQuery = it.prepareStatement(removeInfoQuery) + compiledRemoveInfoQuery.setString(1, info.username) + compiledRemoveInfoQuery.execute() + } + } + + override fun getOnlineFriends(username: String): List { + val friends = ArrayList() + var fTokens = "" + val conn = getConnection() + conn.use { + val friendsQuery = it.prepareStatement(GET_ALL_FRIENDS_QUERY) + friendsQuery.setString(1, username) + val f = friendsQuery.executeQuery() + if (f.next()) { + fTokens = f.getString(1) + } + } + val contacts = CommunicationInfo.parseContacts(fTokens) + for ((friendName, _) in contacts) if (Repository.getPlayerByName(friendName) != null) friends.add(friendName) + + return friends + } + + override fun getUsernamesWithIP(ip: String): List { + val conn = getConnection() + val res = ArrayList() + conn.use { + val query = it.prepareStatement(accountsByIPQuery) + query.setString(1, ip) + val r = query.executeQuery() + while (r.next()) { + res.add(r.getString(1)) + } + } + return res + } + + companion object { + private const val usernameQuery = "SELECT username FROM members WHERE username = ?;" + private const val removeInfoQuery = "DELETE FROM members WHERE username = ?;" + private const val accountsByIPQuery = "SELECT username FROM members WHERE lastGameIp = ?;" + private const val accountInfoQuery = "SELECT " + + "username," + + "password," + + "UID," + + "rights," + + "credits," + + "ip," + + "lastGameIp," + + "muteTime," + + "banTime," + + "contacts," + + "blocked," + + "clanName," + + "currentClan," + + "clanReqs," + + "timePlayed," + + "lastLogin," + + "online," + + "joined_date" + + " FROM members WHERE username = ?;" + private const val insertInfoQuery = "INSERT INTO members (" + + "username," + + "password," + + "rights," + + "credits," + + "ip," + + "lastGameIp," + + "muteTime," + + "banTime," + + "contacts," + + "blocked," + + "clanName," + + "currentClan," + + "clanReqs," + + "timePlayed," + + "lastLogin," + + "online," + + "joined_date" + + ") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);" + + private fun buildUpdateInfoQuery(updatedIndices: ArrayList) : String { + val sb = StringBuilder("UPDATE members SET ") + val validIndices = updatedIndices.filter { it in UPDATE_QUERY_FIELDS.keys } + for ((index, updatedIndex) in validIndices.withIndex()) { + sb.append(UPDATE_QUERY_FIELDS[updatedIndex] ?: continue) + sb.append(" = ?") + if (index < validIndices.size - 1) + sb.append(",") + } + sb.append(" WHERE uid = ?;") + return sb.toString() + } + + //Maps UserAccountInfo updated field indices to the column name for SQL. Mini ORM I guess? + private val UPDATE_QUERY_FIELDS = mapOf( + 0 to "username", + 1 to "password", + 3 to "rights", + 4 to "credits", + 6 to "lastGameIp", + 7 to "muteTime", + 8 to "banTime", + 9 to "contacts", + 10 to "blocked", + 11 to "clanName", + 12 to "currentClan", + 13 to "clanReqs", + 14 to "timePlayed", + 15 to "lastLogin", + 16 to "online" + ) + + private val GET_ALL_FRIENDS_QUERY = "SELECT contacts FROM players WHERE username = ?;" + } +} diff --git a/Server/src/main/core/tools/CP1252.java b/Server/src/main/core/tools/CP1252.java new file mode 100644 index 0000000..9269b87 --- /dev/null +++ b/Server/src/main/core/tools/CP1252.java @@ -0,0 +1,23 @@ +package core.tools; + +public class CP1252 { + private static char[] charMap = {'\u20ac', '\0', '\u201a', '\u0192', '\u201e', '\u2026', '\u2020', '\u2021', + '\u02c6', '\u2030', '\u0160', '\u2039', '\u0152', '\0', '\u017d', '\0', '\0', '\u2018', '\u2019', + '\u201c', '\u201d', '\u2022', '\u2013', '\u2014', '\u02dc', '\u2122', '\u0161', '\u203a', '\u0153', + '\0', '\u017e', '\u0178'}; + + public static char getFromByte(byte value) { + int out = value & 0xff; + if (out == 0) { + throw new IllegalArgumentException("Non cp1252 character 0x" + Integer.toString(out, 16) + " provided"); + } + if (out >= 128 && out < 160) { + int cp1252 = charMap[out - 128]; + if (cp1252 == 0) { + cp1252 = 63; + } + out = cp1252; + } + return (char) out; + } +} diff --git a/Server/src/main/core/tools/DialogueConst.kt b/Server/src/main/core/tools/DialogueConst.kt new file mode 100644 index 0000000..0e5a605 --- /dev/null +++ b/Server/src/main/core/tools/DialogueConst.kt @@ -0,0 +1,9 @@ +package core.tools + +const val START_DIALOGUE = 0 +const val END_DIALOGUE = 1000000 + +/** + * Stage gets set to this by the sendChoices() method if there's more than one option a player can pick when starting a conversation. I.E. multiple simultaneous quests. + */ +const val DIALOGUE_INITIAL_OPTIONS_HANDLE = 1001 \ No newline at end of file diff --git a/Server/src/main/core/tools/Globals.kt b/Server/src/main/core/tools/Globals.kt new file mode 100644 index 0000000..cb070f7 --- /dev/null +++ b/Server/src/main/core/tools/Globals.kt @@ -0,0 +1,64 @@ +package core.tools + +const val RED = "" +const val ORANGE = "" +const val YELLOW = "" +const val GREEN = "" +const val BLUE = "" +const val PURPLE = "" + +private val pattern = Regex("%[0-9a-fA-F]{6}") +private val testData = arrayOf("This is a string with no colors.", "This %R is a string with one color.", "This %R %G %B is a string with multiple colors.", "This %ffffff is an arbitrary hex string.") + +fun colorize(line: String): String { + return line.replace("%R", RED) + .replace("%O", ORANGE) + .replace("%Y", YELLOW) + .replace("%G", GREEN) + .replace("%B", BLUE) + .replace("%P", PURPLE) + .replace(pattern) { matchResult -> "" } + .append("") + " " +} + +fun colorize(line: String, hexColor: String): String{ + return line.prepend("").append("") +} + +fun String.append(line: String): String{ + return this + line +} + +fun String.prepend(line: String): String{ + return line + this +} + +fun String.shuffle(): String{ + var new = "" + val old = this.split("").toMutableList() + for(i in this.indices){ + val c = old.random() + new += c.toString() + old.remove(c) + } + return new +} + +/** + * Prepends 'a' or 'an' to a noun depending on whether it starts with a vowel. + * @author bushtail + * @param noun the noun to check grammar rules against. + * @return either 'a $noun' or 'an $noun' depending on the first letter. + */ +fun prependArticle(noun : String) : String { + if(noun == null) return noun + val exceptions = hashMapOf("unicorn" to "a", "herb" to "an", "hour" to "an") + if(exceptions.contains(noun.lowercase())) { + return "${exceptions[noun.lowercase()]} $noun" + } + return when(noun[0]) { + 'a', 'e', 'i', 'o', 'u' -> "an $noun" + else -> "a $noun" + } +} + diff --git a/Server/src/main/core/tools/NetworkReachability.kt b/Server/src/main/core/tools/NetworkReachability.kt new file mode 100644 index 0000000..d27f3bd --- /dev/null +++ b/Server/src/main/core/tools/NetworkReachability.kt @@ -0,0 +1,6 @@ +package core.tools + +enum class NetworkReachability { + Reachable, + Unreachable +} \ No newline at end of file diff --git a/Server/src/main/core/tools/PlayerLoader.java b/Server/src/main/core/tools/PlayerLoader.java new file mode 100644 index 0000000..ee37c85 --- /dev/null +++ b/Server/src/main/core/tools/PlayerLoader.java @@ -0,0 +1,41 @@ +package core.tools; + + +import core.game.node.entity.player.Player; +import core.game.node.entity.player.info.PlayerDetails; +import core.game.node.entity.player.info.login.PlayerParser; + +/** + * Represents a class that is used to load a player, or details of it. + * + * @author 'Vexia + */ +public final class PlayerLoader { + + /** + * Method used to load the player file. + * + * @param name the name. + * @return the player. + */ + public static Player getPlayerFile(String name) { + final PlayerDetails playerDetails = new PlayerDetails(name); + //playerDetails.parse(); + final Player player = new Player(playerDetails); + PlayerParser.parse(player); +// GameWorld.getWorld().getAccountService().loadPlayer(player); + return player; + } + + /** + * Method used to load the player details file. + * + * @param name the name. + * @return the details + */ + public static PlayerDetails getPlayerDetailFile(String name) { + final PlayerDetails playerDetails = new PlayerDetails(name); + // playerDetails.parse(); + return playerDetails; + } +} diff --git a/Server/src/main/core/tools/RSAKeyGen.java b/Server/src/main/core/tools/RSAKeyGen.java new file mode 100644 index 0000000..14b0cc4 --- /dev/null +++ b/Server/src/main/core/tools/RSAKeyGen.java @@ -0,0 +1,56 @@ +package core.tools; +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.math.BigInteger; +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.spec.RSAPrivateKeySpec; +import java.security.spec.RSAPublicKeySpec; + +/** + * A class to generate a simple 1024 bit RSA pair + * @author Nikki + */ +public class RSAKeyGen { + + public static void main(String[] args) { + try { + KeyFactory factory = KeyFactory.getInstance("RSA"); + KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); + keyGen.initialize(1024); + KeyPair keypair = keyGen.genKeyPair(); + PrivateKey privateKey = keypair.getPrivate(); + PublicKey publicKey = keypair.getPublic(); + + RSAPrivateKeySpec privSpec = factory.getKeySpec(privateKey, RSAPrivateKeySpec.class); + + writeKey("rsapriv", privSpec.getModulus(), privSpec.getPrivateExponent()); + + + RSAPublicKeySpec pubSpec = factory.getKeySpec(publicKey, RSAPublicKeySpec.class); + + writeKey("rsapub", pubSpec.getModulus(), pubSpec.getPublicExponent()); + } catch(Exception e) { + e.printStackTrace(); + } + } + + public static void writeKey(String file, BigInteger modulus, BigInteger exponent) { + try { + BufferedWriter writer = new BufferedWriter(new FileWriter(file)); + writer.write("private static final BigInteger RSA_MODULUS = new BigInteger(\""+modulus.toString()+"\");"); + writer.newLine(); + writer.newLine(); + writer.write("private static final BigInteger RSA_EXPONENT = new BigInteger(\""+exponent.toString()+"\");"); + writer.newLine(); + writer.flush(); + writer.close(); + } catch(Exception e) { + e.printStackTrace(); + } + } + +} \ No newline at end of file diff --git a/Server/src/main/core/tools/RandomFunction.java b/Server/src/main/core/tools/RandomFunction.java new file mode 100644 index 0000000..61d3275 --- /dev/null +++ b/Server/src/main/core/tools/RandomFunction.java @@ -0,0 +1,301 @@ +package core.tools; + +import core.game.node.entity.npc.drop.DropFrequency; +import core.game.node.item.ChanceItem; +import core.game.node.item.Item; +import core.game.node.item.WeightedChanceItem; + +import java.util.*; +import java.util.concurrent.ThreadLocalRandom; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * Represents a class used for random methods. + * @author Vexia + */ +public class RandomFunction { + + /** + * The random instance. + */ + public static final Random RANDOM = new Random(); + + /** + * Method used to ease the access of the random class. + * @param a the minimum random value. + * @param b the maximum random value. + * @return the value as an {@link Double}. + */ + public static final double random(double a, double b) { + final double min = Math.min(a, b); + final double max = Math.max(a, b); + return min + (max - min) * RANDOM.nextDouble(); + } + + /** + * Method used to ease the access of the random class. + * @param a the minimum random value. + * @param b the maximum random value. + * @return the value as an {@link Integer}. + */ + public static final int random(int a, int b) { + final int n = Math.abs(b - a); + return Math.min(a, b) + (n == 0 ? 0 : random(n)); + } + + /** + * Method to roll for a random 1/X chance + * @param chance the 1/chance rate for the roll to succeed + * @return true if you hit the roll, false otherwise + */ + public static boolean roll(int chance) { + if (chance <= 1) return true; + return random(chance) == 1; + } + + /** + * Calculates the chance of succeeding at a skilling event + * @param low - Success chance at level 1 + * @param high - Success chance at level 99 + * @param level - Level required + * @return percent chance of success + */ + public static double getSkillSuccessChance(double low, double high, int level) { + // 99 & 98 numbers should *not* be adjusted for level cap > 99 + int value = (int)(Math.floor(low*( (99-level)/98.0 ) ) + Math.floor(high*((level-1)/98.0)) + 1); + return Math.min(Math.max(value / 256D, 0), 1) * 100.0; + } + + + /** + * Returns either the supplied integer, or -1 times the supplied integer. + * @param value the value. + * @return the integer. + */ + public static int randomSign(int value) { + return RANDOM.nextBoolean() ? value : -value; + } + + /** + * Method used to return the integer. + * @param maxValue the value. + * @return the value. + */ + public static final int getRandom(int maxValue) { + return (int) (Math.random() * (maxValue + 1)); + } + + /** + * Method used to return the random double. + * @param maxValue the value. + * @return the double. + */ + public static final double getRandomDouble(double maxValue) { + return (Math.random() * (maxValue + 1)); + } + + /** + * Method used to ease the access of the random class. + * @param maxValue the maximum value. + * @return the random integer. + */ + public static final int random(int maxValue) { + if (maxValue <= 0) { + return 0; + } + return RANDOM.nextInt(maxValue); + } + + public static final double randomDouble(double maxValue) { + return ThreadLocalRandom.current().nextDouble(0.0,maxValue); + } + + public static final double randomDouble(double min, double max){ + return ThreadLocalRandom.current().nextDouble(min,max); + } + + public static int nextInt(int val) + { + return random(val); + } + + /** + * Generates a random number with a distrobution like: + * Where intensity is how intense the peak is (higher = more steep) + * * + * * * + * * * + * * * * * + * * * * * * + */ + public static int normalRandDist(int max, int intensity) { + int sum = 0; + for (int j = 0; j < intensity; j++) { + sum += RANDOM.nextInt(max); + } + return sum/intensity; + } + + /** + * Generates a random number with a distribution like: + * * + * * * + * * * + * * * * * + * * * * * * + */ + public static int normalRandDist(int max) { + return (RANDOM.nextInt(max) + RANDOM.nextInt(max))/2; + } + + /** + * Generates a random number with a distribution like: + * + * * + * * + * * + * * + * See some results: https://www.desmos.com/calculator/clzv66l7hk + */ + public static int linearDecreaseRand(int max) { + double seed = RANDOM.nextDouble(); + double modifier = RANDOM.nextDouble(); + return (int) (seed*modifier*max); + } + + /** + * Generates a random number likely in the area above val (I think) + */ + public static int normalPlusWeightRandDist(int val, int weight) + { + int normalDistRand = (RANDOM.nextInt(val) + RANDOM.nextInt(val))/2; + return normalDistRand/2 + weight < val ? normalDistRand/2 + weight : normalPlusWeightRandDist(val, weight - 1); + } + + /** + * Gets a chance item. + * @param items the items. + * @return the chance. + */ + public static final ChanceItem getChanceItem(final ChanceItem[] items) { + double total = 0; + for (ChanceItem i : items) { + total += i.getChanceRate(); + } + final int random = random((int) total); + double subTotal = 0; + List choices = new ArrayList<>(20); + for (ChanceItem item : items) { + choices.add(item); + } + Collections.shuffle(choices); + for (ChanceItem i : choices) { + subTotal += i.getChanceRate(); + if (random < subTotal) { + return i; + } + } + return null; + } + + public static List rollChanceTable(boolean atLeastOne,List table){ + final List rewards = new ArrayList<>(20); + final List always_rewards = new ArrayList<>(20); + final List chanceTable = new ArrayList(table); + boolean isAllAlways = false; + if(table.stream().filter(item -> item.getChanceRate() == 1).count() == table.size()){ + isAllAlways = true; + } + if(table.size() == 1){ + atLeastOne = false; + } + if(!isAllAlways) { + if (atLeastOne) { + while (rewards.isEmpty()) { + Collections.shuffle(chanceTable); + for (ChanceItem item : chanceTable) { + if (item.getChanceRate() == 0.0) { + item.setChanceRate(DropFrequency.rate(item.getDropFrequency())); + } + boolean roll = RandomFunction.random(1, (int) item.getChanceRate()) == 1; + if (item.getChanceRate() != 1) { + if (roll) { + rewards.add(item.getRandomItem()); + break; + } + } + } + } + } else { + Collections.shuffle(chanceTable); + for (ChanceItem item : chanceTable) { + if (item.getChanceRate() == 0.0) { + item.setChanceRate(DropFrequency.rate(item.getDropFrequency())); + } + boolean roll = RandomFunction.random(1, (int) item.getChanceRate()) == 1; + if (item.getChanceRate() != 1) { + if (roll) { + rewards.add(item.getRandomItem()); + break; + } + } + } + } + } + table.stream().filter(item -> item.getChanceRate() == 1).forEach(item -> { + if(item.getChanceRate() == 0.0){ + item.setChanceRate(DropFrequency.rate(item.getDropFrequency())); + } + always_rewards.add(item.getRandomItem()); + }); + return Stream.concat(rewards.stream(),always_rewards.stream()).collect(Collectors.toList()); + } + + public static List rollChanceTable(boolean atLeastOne,ChanceItem... table){ + return rollChanceTable(atLeastOne, Arrays.asList(table)); + } + + public static Item rollWeightedChanceTable(WeightedChanceItem... table){ + return rollWeightedChanceTable(new ArrayList<>(Arrays.asList(table))); + } + + public static Item rollWeightedChanceTable(List table){ + int sumOfWeights = table.stream().mapToInt(item -> item.weight).sum(); + int rand = random(sumOfWeights); + Collections.shuffle(table); + for(WeightedChanceItem item : table){ + if(rand <= item.weight) + return item.getItem(); + rand -= item.weight; + } + //We should get here if and only if the weighted chance table is empty. + + return null; + } + + /** + * Gets a random value from the array. + * @param array The array. + * @return A random element of the array. + */ + public static T getRandomElement(T[] array) { + return (T) array[randomize(array.length)]; + } + + /** + * Randomizes the value. + * @param value the value to randomize. + * @return The random value. + */ + public static int randomize(int value) { + if (value < 1) { + return 0; + } + return RANDOM.nextInt(value); + } + + public static boolean nextBool() { + return RANDOM.nextBoolean(); + } +} diff --git a/Server/src/main/core/tools/StringUtils.java b/Server/src/main/core/tools/StringUtils.java new file mode 100644 index 0000000..84ac0e3 --- /dev/null +++ b/Server/src/main/core/tools/StringUtils.java @@ -0,0 +1,597 @@ +package core.tools; + +import java.text.DecimalFormat; +import java.util.StringTokenizer; + +import core.net.packet.IoBuffer; + +/** + * The string utils. + * @author Emperor + */ +public final class StringUtils { + + /** + * The valid characters to be used in names/messages/... + */ + public static final char[] VALID_CHARS = { '_', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; + /** + * Character mapping. + */ + public static char[] mapping = { '\n', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ' ' }; + /** + * The an int array241. + */ + public static int[] anIntArray241 = { 215, 203, 83, 158, 104, 101, 93, 84, 107, 103, 109, 95, 94, 98, 89, 86, 70, 41, 32, 27, 24, 23, -1, -2, 26, -3, -4, 31, 30, -5, -6, -7, 37, 38, 36, -8, -9, -10, 40, -11, -12, 55, 48, 46, 47, -13, -14, -15, 52, 51, -16, -17, 54, -18, -19, 63, 60, 59, -20, -21, 62, -22, -23, 67, 66, -24, -25, 69, -26, -27, 199, 132, 80, 77, 76, -28, -29, 79, -30, -31, 87, 85, -32, -33, -34, -35, -36, 197, -37, 91, -38, 134, -39, -40, -41, 97, -42, -43, 133, 106, -44, 117, -45, -46, 139, -47, -48, 110, -49, -50, 114, 113, -51, -52, 116, -53, -54, 135, 138, 136, 129, 125, 124, -55, -56, 130, 128, -57, -58, -59, 183, -60, -61, -62, -63, -64, 148, -65, -66, 153, 149, 145, 144, -67, -68, 147, -69, -70, -71, 152, 154, -72, -73, -74, 157, 171, -75, -76, 207, 184, 174, 167, 166, 165, -77, -78, -79, 172, 170, -80, -81, -82, 178, -83, 177, 182, -84, -85, 187, 181, -86, -87, -88, -89, 206, 221, -90, 189, -91, 198, 254, 262, 195, 196, -92, -93, -94, -95, -96, 252, 255, 250, -97, 211, 209, -98, -99, 212, -100, 213, -101, -102, -103, 224, -104, 232, 227, 220, 226, -105, -106, 246, 236, -107, 243, -108, -109, 231, 237, 235, -110, -111, 239, 238, -112, -113, -114, -115, -116, 241, -117, 244, -118, -119, 248, -120, 249, -121, -122, -123, 253, -124, -125, -126, -127, 259, 258, -128, -129, 261, -130, -131, 390, 327, 296, 281, 274, 271, 270, -132, -133, 273, -134, -135, 278, 277, -136, -137, 280, -138, -139, 289, 286, 285, -140, -141, 288, -142, -143, 293, 292, -144, -145, 295, -146, -147, 312, 305, 302, 301, -148, -149, 304, -150, -151, 309, 308, -152, -153, 311, -154, -155, 320, 317, 316, -156, -157, 319, -158, -159, 324, 323, -160, -161, 326, -162, -163, 359, 344, 337, 334, 333, -164, -165, 336, -166, -167, 341, 340, -168, -169, 343, -170, -171, 352, 349, 348, -172, -173, 351, -174, -175, 356, 355, -176, -177, 358, -178, -179, 375, 368, 365, 364, -180, -181, 367, -182, -183, 372, 371, -184, -185, 374, -186, -187, 383, 380, 379, -188, -189, 382, -190, -191, 387, 386, -192, -193, 389, -194, -195, 454, 423, 408, 401, 398, 397, -196, -197, 400, -198, -199, 405, 404, -200, -201, 407, -202, -203, 416, 413, 412, -204, -205, 415, -206, -207, 420, 419, -208, -209, 422, -210, -211, 439, 432, 429, 428, -212, -213, 431, -214, -215, 436, 435, -216, -217, 438, -218, -219, 447, 444, 443, -220, -221, 446, -222, -223, 451, 450, -224, -225, 453, -226, -227, 486, 471, 464, 461, 460, -228, -229, 463, -230, -231, 468, 467, -232, -233, 470, -234, -235, 479, 476, 475, -236, -237, 478, -238, -239, 483, 482, -240, -241, 485, -242, -243, 499, 495, 492, 491, -244, -245, 494, -246, -247, 497, -248, 502, -249, 506, 503, -250, -251, 505, -252, -253, 508, -254, 510, -255, -256, 0 }; + + /** + * Constructs a new {@code StringUtils.java} {@code Object}. + */ + public StringUtils() { + /** + * empty. + */ + } + + /** + * Method used to get the formatted number as a string from the integer + * inputed. + * @param amount the ammount. + * @return the string value. + */ + public static String getFormattedNumber(int amount) { + return new DecimalFormat("#,###,##0").format(amount).toString(); + } + + /** + * Checks if the string contains an invalid character. + * @param name The string. + * @return {@code True} if so. + */ + public static boolean containsInvalidCharacter(String name) { + boolean pass = false; + for (char c : name.toCharArray()) { + for (char vc : VALID_CHARS) { + if (vc == c) { + pass = true; + break; + } + } + if (!pass) { + return true; + } + } + return false; + } + + /** + * If a word starts with a e i o u h for grammar = a + n. + * @param word The word. + * @return If the a should have +n {@code true}. + */ + public static boolean isPlusN(String word) { + if (word == null) + return false; + String s = word.toLowerCase(); + return s.charAt(0) == 'a' || s.charAt(0) == 'e' || s.charAt(0) == 'i' || s.charAt(0) == 'o' || s.charAt(0) == 'u' || (s.charAt(0) == 'h' && s.length() > 1 && s.charAt(1) != 'e'); + } + + /** + * Adds an s to make a world plural. + * @param word the word + * @return the plural word + */ + public static String plusS(String word) { + if (word == null) { + return null; + } + if (word.endsWith("s")) { + return word; + } + if (word.endsWith("y")) { + return word.substring(0, word.length() - 1) + "ies"; + } + return word + "s"; + } + /** + * Method used to get the player name as a long. + * @param s the string. + * @return the long. + */ + public static long getPlayerNameLong(String s) { + long l = 0L; + for (int i = 0; i < s.length() && i < 12; i++) { + char c = s.charAt(i); + l *= 37L; + if (c >= 'A' && c <= 'Z') + l += (1 + c) - 65; + else if (c >= 'a' && c <= 'z') + l += (1 + c) - 97; + else if (c >= '0' && c <= '9') + l += (27 + c) - 48; + } + while (l % 37L == 0L && l != 0L) + l /= 37L; + return l; + } + + /** + * Method used to convert the string to a long. + * @param s the string. + * @return the long. + */ + public static long convertStringToLong(String s) { + if (s.length() > 20) { + throw new IllegalArgumentException("String is too long: " + s); + } + long out = 0L; + for (int i = 0; i < s.length(); ++i) { + long m = reducedMapping(s.codePointAt(i)); + if (m == -1) { + throw new IllegalArgumentException("Unmapped Character in String: " + s); + } + m <<= ((9 - i) * 6) + 4; + out |= m; + } + return out; + } + + /** + * Formats the string as display name. + * @param name The string to format. + * @return The formatted name. + */ + public static String formatDisplayName(String name) { + name = name.replaceAll("_", " "); + name = name.toLowerCase(); + StringBuilder newName = new StringBuilder(); + boolean wasSpace = true; + for (int i = 0; i < name.length(); i++) { + if (wasSpace) { + newName.append((new String() + name.charAt(i)).toUpperCase()); + wasSpace = false; + } else { + newName.append(name.charAt(i)); + } + if (name.charAt(i) == ' ') { + wasSpace = true; + } + } + return newName.toString(); + } + + /** + * Gets the byte for the character. + * @param c The character. + * @return The byte. + */ + private static final byte getByte(char c) { + byte charByte; + if (c > 0 && c < '\200' || c >= '\240' && c <= '\377') + charByte = (byte) c; + else if (c != '\u20AC') { + if (c != '\u201A') { + if (c != '\u0192') { + if (c == '\u201E') + charByte = -124; + else if (c != '\u2026') { + if (c != '\u2020') { + if (c == '\u2021') + charByte = -121; + else if (c == '\u02C6') + charByte = -120; + else if (c == '\u2030') + charByte = -119; + else if (c == '\u0160') + charByte = -118; + else if (c == '\u2039') + charByte = -117; + else if (c == '\u0152') + charByte = -116; + else if (c != '\u017D') { + if (c == '\u2018') + charByte = -111; + else if (c != '\u2019') { + if (c != '\u201C') { + if (c == '\u201D') + charByte = -108; + else if (c != '\u2022') { + if (c == '\u2013') + charByte = -106; + else if (c == '\u2014') + charByte = -105; + else if (c == '\u02DC') + charByte = -104; + else if (c == '\u2122') + charByte = -103; + else if (c != '\u0161') { + if (c == '\u203A') + charByte = -101; + else if (c != '\u0153') { + if (c == '\u017E') + charByte = -98; + else if (c != '\u0178') + charByte = 63; + else + charByte = -97; + } else + charByte = -100; + } else + charByte = -102; + } else + charByte = -107; + } else + charByte = -109; + } else + charByte = -110; + } else + charByte = -114; + } else + charByte = -122; + } else + charByte = -123; + } else + charByte = -125; + } else + charByte = -126; + } else + charByte = -128; + return charByte; + } + + /** + * Gets the double value of this string + * @param s The string. + * @return The double value. + */ + public static double getDouble(String s) { + s = s.replaceAll(", ", "").replaceAll(",", ""); + StringBuilder sb = new StringBuilder(); + char c; + boolean foundStart = false; + for (int i = 0; i < s.length(); i++) { + c = s.charAt(i); + if (Character.isDigit(c) || c == '-' || c == '.') { + sb.append(c); + foundStart = true; + } else if (foundStart) + break; + } + try { + double amount = Double.parseDouble(sb.toString()); + return amount; + } catch (NumberFormatException e) { + return 0.0; + } + } + + public static String[] splitIntoLine(String input, int maxCharInLine) { + + StringTokenizer tok = new StringTokenizer(input, " "); + StringBuilder output = new StringBuilder(input.length()); + int lineLen = 0; + while (tok.hasMoreTokens()) { + String word = tok.nextToken(); + + while (word.length() > maxCharInLine) { + output.append(word.substring(0, maxCharInLine - lineLen) + "\n"); + word = word.substring(maxCharInLine - lineLen); + lineLen = 0; + } + + if (lineLen + word.length() > maxCharInLine) { + output.append("\n"); + lineLen = 0; + } + output.append(word + " "); + + lineLen += word.length() + 1; + } + // output.split(); + // return output.toString(); + return output.toString().split("\n"); + } + + /** + * Gets the hash for the string. + * @param str The string. + * @return The hash. + */ + public static final int getNameHash(String str) { + str = str.toLowerCase(); + int hash = 0; + for (int index = 0; index < str.length(); index++) + hash = getByte(str.charAt(index)) + ((hash << 5) - hash); + return hash; + } + + /** + * Gets the string value of this string (all html/... removed). + * @param s The string. + * @return The string value. + */ + public static String getString(String s) { + String string = s.replaceAll("\\<.*?>", "").replaceAll(" ", "").replaceAll("Discontinued Item:", ""); + return string; + } + + /** + * Characters used to convert a String to a Long. + */ + public static char[] validChars = { '_', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; + public static int[] anIntArray233 = { 0, 1024, 2048, 3072, 4096, 5120, 6144, 8192, 9216, 12288, 10240, 11264, 16384, 18432, 17408, 20480, 21504, 22528, 23552, 24576, 25600, 26624, 27648, 28672, 29696, 30720, 31744, 32768, 33792, 34816, 35840, 36864, 536870912, 16777216, 37888, 65536, 38912, 131072, 196608, 33554432, 524288, 1048576, 1572864, 262144, 67108864, 4194304, 134217728, 327680, 8388608, 2097152, 12582912, 13631488, 14680064, 15728640, 100663296, 101187584, 101711872, 101974016, 102760448, 102236160, 40960, 393216, 229376, 117440512, 104857600, 109051904, 201326592, 205520896, 209715200, 213909504, 106954752, 218103808, 226492416, 234881024, 222298112, 224395264, 268435456, 272629760, 276824064, 285212672, 289406976, 223346688, 293601280, 301989888, 318767104, 297795584, 298844160, 310378496, 102498304, 335544320, 299892736, 300941312, 301006848, 300974080, 39936, 301465600, 49152, 1073741824, 369098752, 402653184, 1342177280, 1610612736, 469762048, 1476395008, -2147483648, -1879048192, 352321536, 1543503872, -2013265920, -1610612736, -1342177280, -1073741824, -1543503872, 356515840, -1476395008, -805306368, -536870912, -268435456, 1577058304, -134217728, 360710144, -67108864, 364904448, 51200, 57344, 52224, 301203456, 53248, 54272, 55296, 56320, 301072384, 301073408, 301074432, 301075456, 301076480, 301077504, 301078528, 301079552, 301080576, 301081600, 301082624, 301083648, 301084672, 301085696, 301086720, 301087744, 301088768, 301089792, 301090816, 301091840, 301092864, 301093888, 301094912, 301095936, 301096960, 301097984, 301099008, 301100032, 301101056, 301102080, 301103104, 301104128, 301105152, 301106176, 301107200, 301108224, 301109248, 301110272, 301111296, 301112320, 301113344, 301114368, 301115392, 301116416, 301117440, 301118464, 301119488, 301120512, 301121536, 301122560, 301123584, 301124608, 301125632, 301126656, 301127680, 301128704, 301129728, 301130752, 301131776, 301132800, 301133824, 301134848, 301135872, 301136896, 301137920, 301138944, 301139968, 301140992, 301142016, 301143040, 301144064, 301145088, 301146112, 301147136, 301148160, 301149184, 301150208, 301151232, 301152256, 301153280, 301154304, 301155328, 301156352, 301157376, 301158400, 301159424, 301160448, 301161472, 301162496, 301163520, 301164544, 301165568, 301166592, 301167616, 301168640, 301169664, 301170688, 301171712, 301172736, 301173760, 301174784, 301175808, 301176832, 301177856, 301178880, 301179904, 301180928, 301181952, 301182976, 301184000, 301185024, 301186048, 301187072, 301188096, 301189120, 301190144, 301191168, 301193216, 301195264, 301194240, 301197312, 301198336, 301199360, 301201408, 301202432 }; + public static byte[] aByteArray235 = { 22, 22, 22, 22, 22, 22, 21, 22, 22, 20, 22, 22, 22, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 3, 8, 22, 16, 22, 16, 17, 7, 13, 13, 13, 16, 7, 10, 6, 16, 10, 11, 12, 12, 12, 12, 13, 13, 14, 14, 11, 14, 19, 15, 17, 8, 11, 9, 10, 10, 10, 10, 11, 10, 9, 7, 12, 11, 10, 10, 9, 10, 10, 12, 10, 9, 8, 12, 12, 9, 14, 8, 12, 17, 16, 17, 22, 13, 21, 4, 7, 6, 5, 3, 6, 6, 5, 4, 10, 7, 5, 6, 4, 4, 6, 10, 5, 4, 4, 5, 7, 6, 10, 6, 10, 22, 19, 22, 14, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 21, 22, 21, 22, 22, 22, 21, 22, 22 }; + + /** + * Encrypt a string for the client. + */ + public static int encryptPlayerChat(byte[] is, int i_25_, int i_26_, int i_27_, byte[] is_28_) { + try { + i_27_ += i_25_; + int i_29_ = 0; + int i_30_ = i_26_ << 3; + for (; i_27_ > i_25_; i_25_++) { + int i_31_ = 0xff & is_28_[i_25_]; + int i_32_ = anIntArray233[i_31_]; + int i_33_ = aByteArray235[i_31_]; + int i_34_ = i_30_ >> 3; + int i_35_ = i_30_ & 0x7; + i_29_ &= (-i_35_ >> 31); + i_30_ += i_33_; + int i_36_ = ((-1 + (i_35_ - -i_33_)) >> 3) + i_34_; + i_35_ += 24; + is[i_34_] = (byte) (i_29_ = (i_29_ | (i_32_ >>> i_35_))); + if ((i_36_ ^ 0xffffffff) < (i_34_ ^ 0xffffffff)) { + i_34_++; + i_35_ -= 8; + is[i_34_] = (byte) (i_29_ = i_32_ >>> i_35_); + if (i_36_ > i_34_) { + i_34_++; + i_35_ -= 8; + is[i_34_] = (byte) (i_29_ = i_32_ >>> i_35_); + if (i_36_ > i_34_) { + i_35_ -= 8; + i_34_++; + is[i_34_] = (byte) (i_29_ = i_32_ >>> i_35_); + if (i_34_ < i_36_) { + i_35_ -= 8; + i_34_++; + is[i_34_] = (byte) (i_29_ = i_32_ << -i_35_); + } + } + } + } + } + return -i_26_ + ((7 + i_30_) >> 3); + } catch (RuntimeException runtimeexception) { + } + return 0; + } + + /** + * Gets an integer value from a string. + * @param s the string. + * @return The value; + */ + public static int getValue(String s) { + s = s.replaceAll(", ", "").replaceAll(",", ""); + StringBuilder sb = new StringBuilder(); + char c; + boolean foundStart = false; + for (int i = 0; i < s.length(); i++) { + c = s.charAt(i); + if (Character.isDigit(c) || c == '-') { + sb.append(c); + foundStart = true; + } else if (foundStart) + break; + } + try { + int amount = Integer.parseInt(sb.toString()); + return amount; + } catch (NumberFormatException e) { + return 0; + } + } + + /** + * Checks if the account name is valid. + * @param name The account name. + * @return {@code True} if the account name is invalid. + */ + public static boolean invalidAccountName(String name) { + return name.length() > 12 || name.startsWith("_") || name.endsWith("_") || name.contains("__") || containsInvalidCharacter(name); + } + + /** + * Converts a long to a string. + * @param l The long. + * @return The string. + */ + public static String longToString(long l) { + try { + int i = 0; + char ac[] = new char[32]; + while (l != 0L) { + long l1 = l; + l /= 37L; + ac[11 - i++] = VALID_CHARS[(int) (l1 - l * 37L)]; + } + return new String(ac, 12 - i, i); + } catch (ArrayIndexOutOfBoundsException e) { + return ""; + } + } + + /** + * Packs a GJ2-String. + * @param position The position to start. + * @param buffer The byte-array. + * @param str The string. + * @return The size of the string. + */ + public static final int packGJString2(int position, byte[] buffer, String str) { + int length = str.length(); + int offset = position; + for (int index = 0; length > index; index++) { + int character = str.charAt(index); + if (character > 127) { + if (character > 2047) { + buffer[offset++] = (byte) ((character | 919275) >> 12); + buffer[offset++] = (byte) (128 | ((character >> 6) & 63)); + buffer[offset++] = (byte) (128 | (character & 63)); + } else { + buffer[offset++] = (byte) ((character | 12309) >> 6); + buffer[offset++] = (byte) (128 | (character & 63)); + } + } else + buffer[offset++] = (byte) character; + } + return offset - position; + } + + /** + * Method used to... + * @param x idk, + * @return the idk. + */ + public static long reducedMapping(int x) { + long out = -1; + if (x >= 97 && x <= 122) + out = x - 96; + else if (x >= 65 && x <= 90) + out = x - 37; + else if (x >= 48 && x <= 57) + out = x - +5; + else if (x == 32) + out = 63L; + return out; + } + + /** + * Converts a string to a long. + * @param s The string. + * @return The long. + */ + public static long stringToLong(String s) { + long l = 0L; + for (int i = 0; i < s.length() && i < 12; i++) { + char c = s.charAt(i); + l *= 37L; + if (c >= 'A' && c <= 'Z') + l += (1 + c) - 65; + else if (c >= 'a' && c <= 'z') + l += (1 + c) - 97; + else if (c >= '0' && c <= '9') + l += (27 + c) - 48; + } + while (l % 37L == 0L && l != 0L) + l /= 37L; + return l; + } + + /** + * Decrypt player chat. + * @param buffer The buffer + * @param totalChars The total chars + * @return The string + */ + public static String decryptPlayerChat(IoBuffer buffer, int totalChars) { + try { + if (totalChars == 0) + return ""; + int charsDecoded = 0; + int i_4_ = 0; + String s = ""; + for (;;) { + byte i_7_ = (byte) buffer.get(); + if (i_7_ >= 0) + i_4_++; + else + i_4_ = anIntArray241[i_4_]; + int i_8_; + if ((i_8_ = anIntArray241[i_4_]) < 0) { + s += (char) (byte) (i_8_ ^ 0xffffffff); + if (totalChars <= ++charsDecoded) + break; + i_4_ = 0; + } + if (((i_7_ & 0x40) ^ 0xffffffff) != -1) + i_4_ = anIntArray241[i_4_]; + else + i_4_++; + if ((i_8_ = anIntArray241[i_4_]) < 0) { + s += (char) (byte) (i_8_ ^ 0xffffffff); + if (++charsDecoded >= totalChars) + break; + i_4_ = 0; + } + if ((0x20 & i_7_) == 0) + i_4_++; + else + i_4_ = anIntArray241[i_4_]; + if ((i_8_ = anIntArray241[i_4_]) < 0) { + s += (char) (byte) (i_8_ ^ 0xffffffff); + if (totalChars <= ++charsDecoded) + break; + i_4_ = 0; + } + if (((0x10 & i_7_) ^ 0xffffffff) == -1) + i_4_++; + else + i_4_ = anIntArray241[i_4_]; + if ((i_8_ = anIntArray241[i_4_]) < 0) { + s += (char) (byte) (i_8_ ^ 0xffffffff); + if (totalChars <= ++charsDecoded) + break; + + i_4_ = 0; + } + if (((0x8 & i_7_) ^ 0xffffffff) != -1) + i_4_ = anIntArray241[i_4_]; + else + i_4_++; + if ((i_8_ = anIntArray241[i_4_]) < 0) { + s += (char) (byte) (i_8_ ^ 0xffffffff); + if (++charsDecoded >= totalChars) + break; + i_4_ = 0; + } + if ((0x4 & i_7_) == 0) + i_4_++; + else + i_4_ = anIntArray241[i_4_]; + if ((i_8_ = anIntArray241[i_4_]) < 0) { + s += (char) (byte) (i_8_ ^ 0xffffffff); + if (totalChars <= ++charsDecoded) + break; + i_4_ = 0; + } + if (((i_7_ & 0x2) ^ 0xffffffff) != -1) + i_4_ = anIntArray241[i_4_]; + else + i_4_++; + if ((i_8_ = anIntArray241[i_4_]) < 0) { + s += (char) (byte) (i_8_ ^ 0xffffffff); + if (totalChars <= ++charsDecoded) + break; + i_4_ = 0; + } + if (((i_7_ & 0x1) ^ 0xffffffff) != -1) + i_4_ = anIntArray241[i_4_]; + else + i_4_++; + if ((i_8_ = anIntArray241[i_4_]) < 0) { + s += (char) (byte) (i_8_ ^ 0xffffffff); + if (++charsDecoded >= totalChars) + break; + i_4_ = 0; + } + } + return s; + } catch (RuntimeException runtimeexception) { + runtimeexception.printStackTrace(); + } + return ""; + } +} diff --git a/Server/src/main/core/tools/SystemLogger.kt b/Server/src/main/core/tools/SystemLogger.kt new file mode 100644 index 0000000..dc5b965 --- /dev/null +++ b/Server/src/main/core/tools/SystemLogger.kt @@ -0,0 +1,101 @@ +package core.tools + +import com.github.ajalt.mordant.rendering.TextColors +import com.github.ajalt.mordant.terminal.* +import com.google.protobuf.ByteString.Output +import core.ServerConstants +import core.game.world.GameWorld +import core.api.* +import java.io.OutputStream +import java.io.PrintStream +import java.text.SimpleDateFormat +import java.util.* + +/** + * Handles server log printing + * @author Ceikry + * Thanks to the awesome library made by AJ Alt + */ +object SystemLogger { + val t = Terminal() + val errT = t.forStdErr() + val formatter = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXX") + + private fun getTime(): String{ + return "[" + formatter.format(Date(System.currentTimeMillis())) +"]" + } + + @JvmStatic + fun processLogEntry(clazz: Class<*>, log: Log, message: String) { + when (log) { + Log.DEBUG -> { + if (GameWorld.settings?.isDevMode != true) + return + val msg = TextColors.cyan("${getTime()}: [${clazz.simpleName}] $message") + t.println(msg) + } + + Log.FINE -> { + if (ServerConstants.LOG_LEVEL < LogLevel.VERBOSE) + return + val msg = TextColors.gray("${getTime()}: [${clazz.simpleName}] $message") + t.println(msg) + } + + Log.INFO -> { + if (ServerConstants.LOG_LEVEL < LogLevel.DETAILED) + return + + val msg = "${getTime()}: [${clazz.simpleName}] $message" + t.println(msg) + } + + Log.WARN -> { + if (ServerConstants.LOG_LEVEL < LogLevel.CAUTIOUS) + return + + val msg = TextColors.yellow("${getTime()}: [${clazz.simpleName}] $message") + t.println(msg) + } + + Log.ERR -> { + val msg = "${getTime()}: [${clazz.simpleName}] $message" + errT.println(msg) + } + } + } + + @JvmStatic + fun logGE(message: String){ + log(this::class.java, Log.FINE, "[ GE] $message") + } + + @JvmStatic fun logStartup(message: String) + { + log(this::class.java, Log.FINE, "[STARTUP] $message") + } + + @JvmStatic fun logShutdown(message: String) + { + log(this::class.java, Log.FINE, "[SHUTDOWN] $message") + } + + fun logMS(s: String) { + log(this::class.java, Log.FINE, "[ MS] $s") + } +} + +enum class LogLevel { + SILENT, + CAUTIOUS, + DETAILED, + VERBOSE +} + +enum class Log { + FINE, + INFO, + WARN, + ERR, + DEBUG +} diff --git a/Server/src/main/core/tools/TickUtils.kt b/Server/src/main/core/tools/TickUtils.kt new file mode 100644 index 0000000..f7e26e5 --- /dev/null +++ b/Server/src/main/core/tools/TickUtils.kt @@ -0,0 +1,37 @@ +package core.tools + +const val tick = 600 //ms +const val second = 1000 //ms +const val cycle = 20 //ms + +fun secondsToTicks(seconds: Int): Int { + val seconds = seconds * second //seconds -> ms + return seconds / tick //returns an int with the closest number of ticks to the desired number of seconds possible +} + +fun ticksToSeconds(ticks: Int): Int { + val ticksMs = ticks * tick + return ticksMs / 1000 +} + +fun cyclesToTicks (cycles: Int) : Int { + val cyclesPerTick = tick / cycle + return kotlin.math.ceil (cycles / cyclesPerTick.toDouble()).toInt() +} + +fun ticksToCycles (ticks: Int) : Int { + return ticks * (tick / cycle) +} + +fun minutesToTicks(minutes: Int): Int { + val minutesMs = minutes * 60 * 1000 + return minutesMs / tick +} + +fun ticksToMinutes(ticks: Int): Int { + val ticksMs = ticks * tick + return ticksMs / 1000 / 60 +} + +const val ticksPerSecond = second / tick +const val ticksPerMinute = 60 * ticksPerSecond diff --git a/Server/src/main/core/tools/TimeStamp.java b/Server/src/main/core/tools/TimeStamp.java new file mode 100644 index 0000000..f0762e8 --- /dev/null +++ b/Server/src/main/core/tools/TimeStamp.java @@ -0,0 +1,73 @@ +package core.tools; + +/** + * Used for debugging duration of executing code. + * @author Emperor + */ +public final class TimeStamp { + + /** + * The start + */ + private long start; + + /** + * The interval. + */ + private long interval; + + /** + * Constructs a new {@code TimeStamp} {@code Object}. + */ + public TimeStamp() { + start = System.currentTimeMillis(); + interval = start; + } + + /** + * Set current interval. + * @return The duration of this interval. + */ + public long interval() { + return interval(true, ""); + } + + /** + * Set current interval. + * @param debug If we should print out the duration. + * @return The duration of this interval. + */ + public long interval(boolean debug) { + return interval(debug, ""); + } + + /** + * Set current interval. + * @param debug If we should print out the duration. + * @param info Extra information. + * @return The duration of this interval. + */ + public long interval(boolean debug, String info) { + long current = System.currentTimeMillis(); + long difference = current - interval; + if (debug || difference > 100) { + + } + interval = current; + return difference; + } + + /** + * Gets the amount of milliseconds passed since the creation of this object. + * @return The duration. + */ + public long duration(boolean debug, String info) { + long current = System.currentTimeMillis(); + long difference = current - start; + if (debug) { + + } + return difference; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/tools/Vector3d.java b/Server/src/main/core/tools/Vector3d.java new file mode 100644 index 0000000..c44b826 --- /dev/null +++ b/Server/src/main/core/tools/Vector3d.java @@ -0,0 +1,139 @@ +package core.tools; + +import core.game.world.map.Location; + +public class Vector3d { + public double x; + public double y; + public double z; + + public Vector3d(double x, double y, double z) { + this.x = x; + this.y = y; + this.z = z; + } + + public Vector3d(double[] t) { + this.x = t[0]; + this.y = t[1]; + this.z = t[2]; + } + + public Vector3d(Vector3d v) { + this.x = v.x; + this.y = v.y; + this.z = v.z; + } + + public Vector3d(Location l) { + this.x = l.getX(); + this.y = l.getY(); + this.z = l.getZ(); + } + + public Vector3d() { + this.x = 0.0; + this.y = 0.0; + this.z = 0.0; + } + + public String toString() { + return "(" + this.x + ", " + this.y + ", " + this.z + ")"; + } + + public final Vector3d add(Vector3d v1, Vector3d v2) { + this.x = v1.x + v2.x; + this.y = v1.y + v2.y; + this.z = v1.z + v2.z; + return this; + } + + public final Vector3d add(Vector3d v1) { + this.x += v1.x; + this.y += v1.y; + this.z += v1.z; + return this; + } + + public final Vector3d sub(Vector3d v1, Vector3d v2) { + this.x = v1.x - v2.x; + this.y = v1.y - v2.y; + this.z = v1.z - v2.z; + return this; + } + + public final Vector3d sub(Vector3d v1) { + this.x -= v1.x; + this.y -= v1.y; + this.z -= v1.z; + return this; + } + + public final Vector3d negate(Vector3d v1) { + this.x = -v1.x; + this.y = -v1.y; + this.z = -v1.z; + return this; + } + + public final Vector3d negate() { + this.x = -this.x; + this.y = -this.y; + this.z = -this.z; + return this; + } + + public final Vector3d cross(Vector3d v2) { + this.cross(new Vector3d(this), v2); + return this; + } + + public final Vector3d cross(Vector3d v1, Vector3d v2) { + this.x = v1.y*v2.z - v1.z*v2.y; + this.y = v1.z*v2.x - v1.x*v2.z; + this.z = v1.x*v2.y - v1.y*v2.x; + return this; + } + + public final double dot(Vector3d v2) { + return (this.x*v2.x + this.y*v2.y + this.z*v2.z); + } + + public final double l2norm() { + return Math.sqrt(this.x*this.x + this.y*this.y + this.z*this.z); + } + + public final Vector3d normalize() { + double norm = this.l2norm(); + this.x /= norm; + this.y /= norm; + this.z /= norm; + return this; + } + + public static double signedAngle(final Vector3d v1, final Vector3d v2, final Vector3d n) { + return Math.atan2(new Vector3d().cross(v1, v2).dot(n), v1.dot(v2)); + } + + public boolean equals(final Vector3d v1) { + return (this.x == v1.x && this.y == v1.y && this.z == v1.z); + } + + public boolean epsilonEquals(final Vector3d v1, double epsilon) { + double diff; + + diff = this.x - v1.x; + if (Double.isNaN(diff)) return false; + if ((diff<0 ? -diff : diff) > epsilon) return false; + + diff = this.y - v1.y; + if (Double.isNaN(diff)) return false; + if ((diff<0 ? -diff : diff) > epsilon) return false; + + diff = this.z - v1.z; + if (Double.isNaN(diff)) return false; + if ((diff<0 ? -diff : diff) > epsilon) return false; + + return true; + } +} diff --git a/Server/src/main/core/tools/mysql/Database.java b/Server/src/main/core/tools/mysql/Database.java new file mode 100644 index 0000000..c893294 --- /dev/null +++ b/Server/src/main/core/tools/mysql/Database.java @@ -0,0 +1,33 @@ +package core.tools.mysql; + +public class Database { + + private String host; + private String name; + private String username; + private String password; + + public Database(String host, String name, String username, String password) { + this.host = host; + this.name = name; + this.username = username; + this.password = password; + } + + public String host() { + return host; + } + + public String name() { + return name; + } + + public String username() { + return username; + } + + public String password() { + return password; + } + +} \ No newline at end of file diff --git a/Server/src/main/core/tools/mysql/Query.java b/Server/src/main/core/tools/mysql/Query.java new file mode 100644 index 0000000..af047de --- /dev/null +++ b/Server/src/main/core/tools/mysql/Query.java @@ -0,0 +1,48 @@ +package core.tools.mysql; + +public class Query { + + private String start; + private StringBuilder content; + private String end; + + public Query() { + this.start = ""; + this.content = new StringBuilder(); + this.end = ""; + } + + public String start(String start) { + this.start = start; + return this.start; + } + + public String end(String end) { + this.end = end; + return this.end; + } + + public StringBuilder add(String key, String value) { + this.content.append(key + "='" + value + "'").append(","); + return this.content; + } + + public StringBuilder add(String key, int value) { + this.content.append(key + "='" + value + "'").append(","); + return this.content; + } + + public StringBuilder add(String key, boolean value) { + this.content.append(key + "='" + (value ? 1 : 0) + "'").append(","); + return this.content; + } + + public String total() { + StringBuilder total = new StringBuilder(); + total.append(this.start); + total.append(this.content.substring(0, this.content.length() - 1)); + total.append(this.end); + return total.toString(); + } + + } diff --git a/Server/src/main/core/tools/mysql/Results.java b/Server/src/main/core/tools/mysql/Results.java new file mode 100644 index 0000000..b803566 --- /dev/null +++ b/Server/src/main/core/tools/mysql/Results.java @@ -0,0 +1,107 @@ +package core.tools.mysql; + +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.util.ArrayList; +import java.util.List; + +public class Results { + + private ResultSet set; + + public Results(ResultSet set) { + this.set = set; + } + + public String string(String column) { + + try { + + String result = set().getString(column); + + return result; + + } catch (Exception e) { + + } + + return null; + + } + + public int integer(String column) { + + try { + + int result = set().getInt(column); + + return result; + + } catch (Exception e) { + + } + + return -1; + + } + + public List columns() { + + try { + + ResultSetMetaData meta = set().getMetaData(); + int count = meta.getColumnCount(); + + List columns = new ArrayList(count); + + for (int i = 1; i <= count; i++) + columns.add(meta.getColumnName(i)); + + return columns; + + } catch (Exception e) { + + } + + return null; + + } + + public boolean empty() { + + try { + return !set().next(); + } catch (Exception e) { + + } + + return true; + } + + public static int[] integers(String[] values) { + + int[] integers = new int[values.length]; + + for (int i = 0; i < integers.length; i++) + integers[i] = Integer.parseInt(values[i]); + + return integers; + + } + + public static double[] doubles(String[] values) { + + double[] integers = new double[values.length]; + + for (int i = 0; i < integers.length; i++) + integers[i] = Double.parseDouble(values[i]); + + return integers; + + } + + public ResultSet set() { + return set; + } + +} diff --git a/Server/src/main/core/worker/MajorUpdateWorker.kt b/Server/src/main/core/worker/MajorUpdateWorker.kt new file mode 100644 index 0000000..29d48fa --- /dev/null +++ b/Server/src/main/core/worker/MajorUpdateWorker.kt @@ -0,0 +1,152 @@ +package core.worker + +import core.Server +import core.ServerConstants +import core.ServerStore +import core.api.log +import core.api.submitWorldPulse +import core.game.system.task.Pulse +import core.game.world.GameWorld +import core.game.world.repository.Repository +import core.game.world.update.UpdateSequence +import core.integrations.grafana.Grafana +import core.net.packet.PacketProcessor +import core.net.packet.PacketWriteQueue +import core.plugin.CorePluginTypes.Managers +import core.tools.Log +import core.tools.NetworkReachability +import core.tools.colorize +import java.lang.Long.max +import java.text.SimpleDateFormat +import java.util.* +import kotlin.system.exitProcess + +/** + * Handles the running of pulses and writing of masks, etc + * @author Ceikry + */ +class MajorUpdateWorker { + var running: Boolean = false + var started = false + val sequence = UpdateSequence() + val sdf = SimpleDateFormat("HHmmss") + val worker = Thread { + Thread.currentThread().name = "Major Update Worker" + started = true + Thread.sleep(600L) + while (running) { + Grafana.startTick() + val start = System.currentTimeMillis() + Server.heartbeat() + + if (Server.networkReachability == NetworkReachability.Reachable) + handleTickActions() + else + tickOffline() + + for (player in Repository.players.filter { !it.isArtificial }) { + if (System.currentTimeMillis() - player.session.lastPing > 20000L) { + player?.session?.lastPing = Long.MAX_VALUE + player?.session?.disconnect() + } + if (!player.isActive && !Repository.disconnectionQueue.contains(player.name) && player.getAttribute("logged-in-fully", false)) { + //if player has somehow been set as inactive without being queued for disconnection, do that now. This is a failsafe, and should not be relied on. + //if you made a change, and now this is suddenly getting triggered a lot, your change is probably bad. + player?.session?.disconnect() + log(MajorUpdateWorker::class.java, Log.WARN, "Manually disconnecting ${player.name} because they were set as inactive without being disconnected. This is bad.") + } + } + + //Handle daily restart if enabled + if (sdf.format(Date()).toInt() == 0) { + + if (GameWorld.checkDay() == 1) {//monday + ServerStore.clearWeeklyEntries() + } + + ServerStore.clearDailyEntries() + if (ServerConstants.DAILY_RESTART) { + for (player in Repository.players.filter { !it.isArtificial }) { + player.packetDispatch.sendSystemUpdate(500) + } + Repository.sendNews(colorize("%RSERVER GOING DOWN FOR DAILY RESTART IN 5 MINUTES!")) + ServerConstants.DAILY_RESTART = false + submitWorldPulse(object : Pulse(100) { + var counter = 0 + override fun pulse(): Boolean { + counter++ + for (player in Repository.players.filter { !it.isArtificial }) { + player.packetDispatch.sendSystemUpdate((5 - counter) * 100) + } + if (counter == 5) { + exitProcess(0) + } + Repository.sendNews(colorize("%RSERVER GOING DOWN FOR DAILY RESTART IN ${5 - counter} MINUTE${if (counter < 4) "S" else ""}!")) + return false + } + }) + } + } + + val end = System.currentTimeMillis() + Grafana.totalTickTime = (end - start).toInt() + Grafana.endTick() +/* ServerMonitor.eventQueue.add(GuiEvent.UpdateTickTime(end - start)) + ServerMonitor.eventQueue.add(GuiEvent.UpdatePulseCount(GameWorld.Pulser.TASKS.size))*/ + Thread.sleep(max(600 - (end - start), 0)) + } + + log(this::class.java, Log.FINE, "Update worker stopped.") + } + + fun tickOffline() + { + Repository.disconnectionQueue.update() //continue processing disconnection queue + GameWorld.pulse() //continue incrementing the global tick count + } + + fun handleTickActions(skipPulseUpdate: Boolean = false) { + try { + var packetStart = System.currentTimeMillis() + PacketProcessor.processQueue() + Grafana.packetProcessTime = (System.currentTimeMillis() - packetStart).toInt() + + //disconnect all players waiting to be disconnected + Repository.disconnectionQueue.update() + + if (!skipPulseUpdate) { + GameWorld.Pulser.updateAll() + } + GameWorld.tickListeners.forEach { it.tick() } + + sequence.start() + sequence.run() + sequence.end() + + //increment global ticks variable + GameWorld.pulse() + //tick all manager plugins + Managers.tick() + } catch (e: Exception) { + e.printStackTrace() + } finally { + try { + PacketWriteQueue.flush() + } catch (e: Exception) { + e.printStackTrace() + } + } + } + + fun start() { + if (!started) { + running = true + worker.start() + } + } + + fun stop() { + running = false + worker.interrupt() + } +} diff --git a/Server/src/main/core/worker/ManagementEvents.kt b/Server/src/main/core/worker/ManagementEvents.kt new file mode 100644 index 0000000..5207f07 --- /dev/null +++ b/Server/src/main/core/worker/ManagementEvents.kt @@ -0,0 +1,369 @@ +package core.worker + +import core.api.sendMessage +import com.google.protobuf.Message +import core.game.system.communication.ClanEntry +import core.game.system.communication.ClanRank +import core.game.system.communication.ClanRepository +import core.game.system.communication.CommunicationInfo +import core.net.packet.PacketRepository +import core.net.packet.context.ContactContext +import core.net.packet.context.MessageContext +import core.net.packet.out.CommunicationMessage +import core.net.packet.out.ContactPackets +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import proto.management.ClanJoinNotification +import proto.management.ClanLeaveNotification +import proto.management.ClanMessage +import proto.management.FriendUpdate +import proto.management.JoinClanRequest +import proto.management.LeaveClanRequest +import proto.management.PlayerStatusUpdate +import proto.management.PrivateMessage +import proto.management.RequestClanInfo +import proto.management.RequestContactInfo +import proto.management.SendClanInfo +import proto.management.SendClanInfo.ClanMember +import proto.management.SendContactInfo +import proto.management.SendContactInfo.Contact +import core.ServerConstants +import core.auth.UserAccountInfo +import core.tools.SystemLogger +import core.game.world.GameWorld +import core.game.world.repository.Repository +import java.util.Deque +import java.util.LinkedList +import java.util.concurrent.BlockingDeque +import java.util.concurrent.LinkedBlockingDeque + +/** + * Processes management-related events e.g clan messages, etc. + */ +object ManagementEvents { + private var isRunning: Boolean = true + private val eventQueue: BlockingDeque = LinkedBlockingDeque() + private val waitingOnClanInfo = HashMap>() + private val hasRequestedClanInfo = HashMap() + + val job = GlobalScope.launch { + while (isRunning) { + val event = withContext(Dispatchers.IO) { eventQueue.take() } + try { + handleEvent(event) + handleLoggingFor(event) + } catch (ignored: Exception) {} + } + } + + private fun handleLoggingFor(event: Message) { + when (event) { + is PlayerStatusUpdate -> SystemLogger.logMS("${event.username} -(WLD)> ${event.world}") + is RequestContactInfo -> SystemLogger.logMS("${event.username} -> RQ CONTACT INFO") + is SendContactInfo -> SystemLogger.logMS("${event.username} <- SND CONTACT INFO") + is PrivateMessage -> SystemLogger.logMS("[PM] ${event.sender}->${event.receiver}: ${event.message}") + is ClanMessage -> SystemLogger.logMS("[CM:${event.clanName}] ${event.sender}: ${event.message}") + is JoinClanRequest -> SystemLogger.logMS("${event.username} +CL ${event.clanName}") + is LeaveClanRequest -> SystemLogger.logMS("${event.username} -CL ${event.clanName}") + is RequestClanInfo -> SystemLogger.logMS("REQUEST CLAN INFO: ${event.clanOwner}") + is SendClanInfo -> SystemLogger.logMS("RECEIVE CLAN INFO: ${event.clanOwner}->${event.clanName}") + is ClanJoinNotification -> SystemLogger.logMS("${event.username} JOINED CLAN ${event.clanName}") + is ClanLeaveNotification -> SystemLogger.logMS("${event.username} LEFT CLAN ${event.clanName}") + } + } + + @JvmStatic fun publish(event: Message) { + eventQueue.offer(event) + } + + private fun handleEvent(event: Message) { + when (event) { + + is PlayerStatusUpdate -> { + val notifiablePlayers = if (event.notifyFriendsOnly) { + GameWorld.accountStorage.getOnlineFriends(event.username) + } else { + Repository.playerNames.keys.toList() + }.filter { Repository.getPlayerByName(it)?.communication?.contacts?.containsKey(event.username) == true } + + for (playerName in notifiablePlayers) { + val p = Repository.getPlayerByName(playerName) ?: continue + p.communication.contacts[event.username]?.worldId = event.world + PacketRepository.send(ContactPackets::class.java, ContactContext(p, event.username, event.world)) + } + } + + is RequestContactInfo -> { + val response = SendContactInfo.newBuilder() + response.username = event.username + val info = GameWorld.accountStorage.getAccountInfo(event.username) + val contacts = CommunicationInfo.parseContacts(info.contacts) + + for ((username, contact) in contacts) { + val online = Repository.getPlayerByName(username) != null + val cbuild = Contact.newBuilder() + cbuild.username = username + cbuild.world = if (online) GameWorld.settings!!.worldId else 0 + cbuild.rank = contact.rank.ordinal + response.addContacts(cbuild) + } + + val blocked = info.blocked.split(",") + for (user in blocked) response.addBlocked(user) + + publish(response.build()) + } + + is SendContactInfo -> { + val p = Repository.getPlayerByName(event.username) ?: return + + PacketRepository.send( + ContactPackets::class.java, + ContactContext(p, ContactContext.UPDATE_STATE_TYPE) + ) + + p.communication.contacts.clear() + p.communication.blocked.clear() + + for (contact in event.contactsList) { + val c = core.game.system.communication.Contact(contact.username) + p.communication.contacts[contact.username] = c + c.worldId = contact.world + c.rank = ClanRank.values()[contact.rank] + PacketRepository.send( + ContactPackets::class.java, + ContactContext(p, contact.username, contact.world) + ) + } + + for (blocked in event.blockedList) { + p.communication.blocked.add(blocked) + } + + PacketRepository.send( + ContactPackets::class.java, + ContactContext(p, ContactContext.IGNORE_LIST_TYPE) + ) + + } + + is FriendUpdate -> { + val remove = event.type == FriendUpdate.Type.REMOVE + val f = Repository.getPlayerByName(event.friend) + val p = Repository.getPlayerByName(event.username) + val world = if (f != null) GameWorld.settings!!.worldId else 0 + } + + is PrivateMessage -> { + val sender = Repository.getPlayerByName(event.sender) + val receiver = Repository.getPlayerByName(event.receiver) + + if (sender != null) { + PacketRepository.send( + CommunicationMessage::class.java, + MessageContext(sender, event.receiver, event.rank, MessageContext.SEND_MESSAGE, event.message) + ) + } + + if (receiver != null) { + PacketRepository.send( + CommunicationMessage::class.java, + MessageContext(receiver, event.sender, event.rank, MessageContext.RECIEVE_MESSAGE, event.message) + ) + } + } + + is JoinClanRequest -> { + val p = Repository.getPlayerByName(event.username) ?: return + + if (shouldWaitForClanInfo(event.clanName)) { + queueUntilClanInfo(event.clanName, event) + return + } + + val clan = ClanRepository.get(event.clanName) + + if (clan == null) { + sendMessage(p, "The channel you tried to join does not exist.:clan:") + } else { + clan.enter(p) + p.communication.clan = clan + } + } + + is ClanJoinNotification -> { + if (event.world == GameWorld.settings!!.worldId) return + + if (shouldWaitForClanInfo(event.clanName)) { + queueUntilClanInfo(event.clanName, event) + return + } + + val clan = ClanRepository.get(event.clanName) + val entry = ClanEntry(event.username, event.world) + clan.players.add(entry) + clan.update() + } + + is LeaveClanRequest -> { + val p = Repository.getPlayerByName(event.username) ?: return + + if (shouldWaitForClanInfo(event.clanName)) { + queueUntilClanInfo(event.clanName, event) + return + } + + val clan = ClanRepository.get(event.clanName) + + if (clan == null) { + sendMessage(p, "Error leaving clan. Please relog.") + } else { + clan.leave(p, true) + p.details.communication.clan = null + } + } + + is ClanLeaveNotification -> { + if (shouldWaitForClanInfo(event.clanName)) { + queueUntilClanInfo(event.clanName, event) + return + } + + val clan = ClanRepository.get(event.clanName) + val entry = clan.players.firstOrNull { it.name.equals(event.username) } ?: return + clan.players.remove(entry) + clan.update() + } + + is RequestClanInfo -> { + val clan = ClanRepository.get(event.clanOwner) + val response = SendClanInfo.newBuilder() + + if (clan == null) { + response.hasInfo = false + response.clanOwner = event.clanOwner + } else { + response.hasInfo = true + response.clanName = clan.name + response.clanOwner = event.clanOwner + + for (member in clan.players) { + val cmBuilder = ClanMember.newBuilder() + cmBuilder.username = member.name + cmBuilder.world = member.worldId + cmBuilder.rank = (clan.ranks[member.name] ?: ClanRank.NONE).ordinal + response.addMembers(cmBuilder) + } + } + + publish(response.build()) + } + + is SendClanInfo -> { + if (event.hasInfo) { + initializeClanFrom(event) + } else { + var info = GameWorld.accountStorage.getAccountInfo(event.clanOwner) + if (info.clanName.isNotEmpty()) { + initializeClanWith(info) + } else { + SystemLogger.logMS("Creating default server clan") + if (GameWorld.settings!!.enable_default_clan && event.clanOwner == ServerConstants.SERVER_NAME.toLowerCase()) { + //Create a user with the default clan and some basic settings and stick them in the account storage + if (info == UserAccountInfo.createDefault()) { + info.username = ServerConstants.SERVER_NAME.toLowerCase() + info.password = ServerConstants.MS_SECRET_KEY + info.rights = 2 + GameWorld.authenticator.createAccountWith(info) + info = GameWorld.accountStorage.getAccountInfo(event.clanOwner) + } + + info.clanName = "Global" + info.clanReqs = "-1,-1,7,7" //Any join, any message, owner kick, owner loot + GameWorld.accountStorage.update(info) + initializeClanWith(info) + } + } + } + + val queuedEvents = waitingOnClanInfo[event.clanOwner] ?: return + while (queuedEvents.peek() != null) { + publish(queuedEvents.pop()) + } + } + + is ClanMessage -> { + if (shouldWaitForClanInfo(event.clanName)) { + queueUntilClanInfo(event.clanName, event) + return + } + + val clan = ClanRepository.get(event.clanName) + + for (member in clan.players.filter { it.player != null }) { + PacketRepository.send( + CommunicationMessage::class.java, + MessageContext(member.player, event.sender, event.rank, MessageContext.CLAN_MESSAGE, event.message) + ) + } + } + + } + } + + private fun initializeClanFrom(event: SendClanInfo) { + val clan = ClanRepository.getClans().getOrPut(event.clanOwner) { ClanRepository(event.clanOwner) } + clan.name = event.clanName + clan.joinRequirement = ClanRank.values()[event.joinRequirement] + clan.kickRequirement = ClanRank.values()[event.kickRequirement] + clan.messageRequirement = ClanRank.values()[event.messageRequirement] + clan.lootRequirement = ClanRank.values()[event.lootRequirement] + + for (member in event.membersList) { + val entry = ClanEntry(member.username, member.world) + clan.ranks[member.username] = ClanRank.values()[member.rank] + if (member.world == GameWorld.settings!!.worldId) { + val p = Repository.getPlayerByName(member.username) + entry.player = p + p?.communication?.clan = clan + } + clan.players.add(entry) + } + + clan.update() + } + + private fun initializeClanWith(info: UserAccountInfo) { + val reqs = CommunicationInfo.parseClanRequirements(info.clanReqs) + val c = ClanRepository(info.username) + val contacts = CommunicationInfo.parseContacts(info.contacts) + c.name = info.clanName + c.joinRequirement = reqs[0] + c.messageRequirement = reqs[1] + c.kickRequirement = reqs[2] + c.lootRequirement = reqs[3] + for ((username, contact) in contacts) { + c.ranks[username] = contact.rank + } + ClanRepository.getClans()[info.username] = c + } + + private fun queueUntilClanInfo(clanName: String, message: Message) { + val queue = waitingOnClanInfo.getOrPut(clanName) {LinkedList()} + queue.offer(message) + + if (hasRequestedClanInfo[clanName] == null) { + val request = RequestClanInfo.newBuilder() + request.clanOwner = clanName + request.world = GameWorld.settings!!.worldId + publish(request.build()) + hasRequestedClanInfo[clanName] = true + } + } + + private fun shouldWaitForClanInfo(clanName: String): Boolean { + return ClanRepository.get(clanName) == null && hasRequestedClanInfo[clanName] == null + } +} diff --git a/Server/src/main/proto/management/BlockedUpdate.java b/Server/src/main/proto/management/BlockedUpdate.java new file mode 100644 index 0000000..d48c1a4 --- /dev/null +++ b/Server/src/main/proto/management/BlockedUpdate.java @@ -0,0 +1,971 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: Management.proto + +package proto.management; + +/** + * Protobuf type {@code management.BlockedUpdate} + */ +public final class BlockedUpdate extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:management.BlockedUpdate) + BlockedUpdateOrBuilder { +private static final long serialVersionUID = 0L; + // Use BlockedUpdate.newBuilder() to construct. + private BlockedUpdate(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private BlockedUpdate() { + type_ = 0; + username_ = ""; + friend_ = ""; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new BlockedUpdate(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private BlockedUpdate( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 8: { + int rawValue = input.readEnum(); + @SuppressWarnings("deprecation") + proto.management.BlockedUpdate.Type value = proto.management.BlockedUpdate.Type.valueOf(rawValue); + if (value == null) { + unknownFields.mergeVarintField(1, rawValue); + } else { + bitField0_ |= 0x00000001; + type_ = rawValue; + } + break; + } + case 18: { + com.google.protobuf.ByteString bs = input.readBytes(); + bitField0_ |= 0x00000002; + username_ = bs; + break; + } + case 26: { + com.google.protobuf.ByteString bs = input.readBytes(); + bitField0_ |= 0x00000004; + friend_ = bs; + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return proto.management.ManagementProtos.internal_static_management_BlockedUpdate_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return proto.management.ManagementProtos.internal_static_management_BlockedUpdate_fieldAccessorTable + .ensureFieldAccessorsInitialized( + proto.management.BlockedUpdate.class, proto.management.BlockedUpdate.Builder.class); + } + + /** + * Protobuf enum {@code management.BlockedUpdate.Type} + */ + public enum Type + implements com.google.protobuf.ProtocolMessageEnum { + /** + * ADD = 0; + */ + ADD(0), + /** + * REMOVE = 1; + */ + REMOVE(1), + ; + + /** + * ADD = 0; + */ + public static final int ADD_VALUE = 0; + /** + * REMOVE = 1; + */ + public static final int REMOVE_VALUE = 1; + + + public final int getNumber() { + return value; + } + + /** + * @param value The numeric wire value of the corresponding enum entry. + * @return The enum associated with the given numeric wire value. + * @deprecated Use {@link #forNumber(int)} instead. + */ + @java.lang.Deprecated + public static Type valueOf(int value) { + return forNumber(value); + } + + /** + * @param value The numeric wire value of the corresponding enum entry. + * @return The enum associated with the given numeric wire value. + */ + public static Type forNumber(int value) { + switch (value) { + case 0: return ADD; + case 1: return REMOVE; + default: return null; + } + } + + public static com.google.protobuf.Internal.EnumLiteMap + internalGetValueMap() { + return internalValueMap; + } + private static final com.google.protobuf.Internal.EnumLiteMap< + Type> internalValueMap = + new com.google.protobuf.Internal.EnumLiteMap() { + public Type findValueByNumber(int number) { + return Type.forNumber(number); + } + }; + + public final com.google.protobuf.Descriptors.EnumValueDescriptor + getValueDescriptor() { + return getDescriptor().getValues().get(ordinal()); + } + public final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptorForType() { + return getDescriptor(); + } + public static final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptor() { + return proto.management.BlockedUpdate.getDescriptor().getEnumTypes().get(0); + } + + private static final Type[] VALUES = values(); + + public static Type valueOf( + com.google.protobuf.Descriptors.EnumValueDescriptor desc) { + if (desc.getType() != getDescriptor()) { + throw new java.lang.IllegalArgumentException( + "EnumValueDescriptor is not for this type."); + } + return VALUES[desc.getIndex()]; + } + + private final int value; + + private Type(int value) { + this.value = value; + } + + // @@protoc_insertion_point(enum_scope:management.BlockedUpdate.Type) + } + + private int bitField0_; + public static final int TYPE_FIELD_NUMBER = 1; + private int type_; + /** + * required .management.BlockedUpdate.Type type = 1; + * @return Whether the type field is set. + */ + @java.lang.Override public boolean hasType() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required .management.BlockedUpdate.Type type = 1; + * @return The type. + */ + @java.lang.Override public proto.management.BlockedUpdate.Type getType() { + @SuppressWarnings("deprecation") + proto.management.BlockedUpdate.Type result = proto.management.BlockedUpdate.Type.valueOf(type_); + return result == null ? proto.management.BlockedUpdate.Type.ADD : result; + } + + public static final int USERNAME_FIELD_NUMBER = 2; + private volatile java.lang.Object username_; + /** + * required string username = 2; + * @return Whether the username field is set. + */ + @java.lang.Override + public boolean hasUsername() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required string username = 2; + * @return The username. + */ + @java.lang.Override + public java.lang.String getUsername() { + java.lang.Object ref = username_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + username_ = s; + } + return s; + } + } + /** + * required string username = 2; + * @return The bytes for username. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getUsernameBytes() { + java.lang.Object ref = username_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + username_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int FRIEND_FIELD_NUMBER = 3; + private volatile java.lang.Object friend_; + /** + * required string friend = 3; + * @return Whether the friend field is set. + */ + @java.lang.Override + public boolean hasFriend() { + return ((bitField0_ & 0x00000004) != 0); + } + /** + * required string friend = 3; + * @return The friend. + */ + @java.lang.Override + public java.lang.String getFriend() { + java.lang.Object ref = friend_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + friend_ = s; + } + return s; + } + } + /** + * required string friend = 3; + * @return The bytes for friend. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getFriendBytes() { + java.lang.Object ref = friend_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + friend_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (!hasType()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasUsername()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasFriend()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + output.writeEnum(1, type_); + } + if (((bitField0_ & 0x00000002) != 0)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 2, username_); + } + if (((bitField0_ & 0x00000004) != 0)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 3, friend_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeEnumSize(1, type_); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, username_); + } + if (((bitField0_ & 0x00000004) != 0)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, friend_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof proto.management.BlockedUpdate)) { + return super.equals(obj); + } + proto.management.BlockedUpdate other = (proto.management.BlockedUpdate) obj; + + if (hasType() != other.hasType()) return false; + if (hasType()) { + if (type_ != other.type_) return false; + } + if (hasUsername() != other.hasUsername()) return false; + if (hasUsername()) { + if (!getUsername() + .equals(other.getUsername())) return false; + } + if (hasFriend() != other.hasFriend()) return false; + if (hasFriend()) { + if (!getFriend() + .equals(other.getFriend())) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasType()) { + hash = (37 * hash) + TYPE_FIELD_NUMBER; + hash = (53 * hash) + type_; + } + if (hasUsername()) { + hash = (37 * hash) + USERNAME_FIELD_NUMBER; + hash = (53 * hash) + getUsername().hashCode(); + } + if (hasFriend()) { + hash = (37 * hash) + FRIEND_FIELD_NUMBER; + hash = (53 * hash) + getFriend().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static proto.management.BlockedUpdate parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.BlockedUpdate parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.BlockedUpdate parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.BlockedUpdate parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.BlockedUpdate parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.BlockedUpdate parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.BlockedUpdate parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static proto.management.BlockedUpdate parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static proto.management.BlockedUpdate parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static proto.management.BlockedUpdate parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static proto.management.BlockedUpdate parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static proto.management.BlockedUpdate parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(proto.management.BlockedUpdate prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code management.BlockedUpdate} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:management.BlockedUpdate) + proto.management.BlockedUpdateOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return proto.management.ManagementProtos.internal_static_management_BlockedUpdate_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return proto.management.ManagementProtos.internal_static_management_BlockedUpdate_fieldAccessorTable + .ensureFieldAccessorsInitialized( + proto.management.BlockedUpdate.class, proto.management.BlockedUpdate.Builder.class); + } + + // Construct using proto.management.BlockedUpdate.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + type_ = 0; + bitField0_ = (bitField0_ & ~0x00000001); + username_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + friend_ = ""; + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return proto.management.ManagementProtos.internal_static_management_BlockedUpdate_descriptor; + } + + @java.lang.Override + public proto.management.BlockedUpdate getDefaultInstanceForType() { + return proto.management.BlockedUpdate.getDefaultInstance(); + } + + @java.lang.Override + public proto.management.BlockedUpdate build() { + proto.management.BlockedUpdate result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public proto.management.BlockedUpdate buildPartial() { + proto.management.BlockedUpdate result = new proto.management.BlockedUpdate(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + to_bitField0_ |= 0x00000001; + } + result.type_ = type_; + if (((from_bitField0_ & 0x00000002) != 0)) { + to_bitField0_ |= 0x00000002; + } + result.username_ = username_; + if (((from_bitField0_ & 0x00000004) != 0)) { + to_bitField0_ |= 0x00000004; + } + result.friend_ = friend_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof proto.management.BlockedUpdate) { + return mergeFrom((proto.management.BlockedUpdate)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(proto.management.BlockedUpdate other) { + if (other == proto.management.BlockedUpdate.getDefaultInstance()) return this; + if (other.hasType()) { + setType(other.getType()); + } + if (other.hasUsername()) { + bitField0_ |= 0x00000002; + username_ = other.username_; + onChanged(); + } + if (other.hasFriend()) { + bitField0_ |= 0x00000004; + friend_ = other.friend_; + onChanged(); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (!hasType()) { + return false; + } + if (!hasUsername()) { + return false; + } + if (!hasFriend()) { + return false; + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + proto.management.BlockedUpdate parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (proto.management.BlockedUpdate) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private int type_ = 0; + /** + * required .management.BlockedUpdate.Type type = 1; + * @return Whether the type field is set. + */ + @java.lang.Override public boolean hasType() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required .management.BlockedUpdate.Type type = 1; + * @return The type. + */ + @java.lang.Override + public proto.management.BlockedUpdate.Type getType() { + @SuppressWarnings("deprecation") + proto.management.BlockedUpdate.Type result = proto.management.BlockedUpdate.Type.valueOf(type_); + return result == null ? proto.management.BlockedUpdate.Type.ADD : result; + } + /** + * required .management.BlockedUpdate.Type type = 1; + * @param value The type to set. + * @return This builder for chaining. + */ + public Builder setType(proto.management.BlockedUpdate.Type value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + type_ = value.getNumber(); + onChanged(); + return this; + } + /** + * required .management.BlockedUpdate.Type type = 1; + * @return This builder for chaining. + */ + public Builder clearType() { + bitField0_ = (bitField0_ & ~0x00000001); + type_ = 0; + onChanged(); + return this; + } + + private java.lang.Object username_ = ""; + /** + * required string username = 2; + * @return Whether the username field is set. + */ + public boolean hasUsername() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required string username = 2; + * @return The username. + */ + public java.lang.String getUsername() { + java.lang.Object ref = username_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + username_ = s; + } + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string username = 2; + * @return The bytes for username. + */ + public com.google.protobuf.ByteString + getUsernameBytes() { + java.lang.Object ref = username_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + username_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string username = 2; + * @param value The username to set. + * @return This builder for chaining. + */ + public Builder setUsername( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + username_ = value; + onChanged(); + return this; + } + /** + * required string username = 2; + * @return This builder for chaining. + */ + public Builder clearUsername() { + bitField0_ = (bitField0_ & ~0x00000002); + username_ = getDefaultInstance().getUsername(); + onChanged(); + return this; + } + /** + * required string username = 2; + * @param value The bytes for username to set. + * @return This builder for chaining. + */ + public Builder setUsernameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + username_ = value; + onChanged(); + return this; + } + + private java.lang.Object friend_ = ""; + /** + * required string friend = 3; + * @return Whether the friend field is set. + */ + public boolean hasFriend() { + return ((bitField0_ & 0x00000004) != 0); + } + /** + * required string friend = 3; + * @return The friend. + */ + public java.lang.String getFriend() { + java.lang.Object ref = friend_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + friend_ = s; + } + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string friend = 3; + * @return The bytes for friend. + */ + public com.google.protobuf.ByteString + getFriendBytes() { + java.lang.Object ref = friend_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + friend_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string friend = 3; + * @param value The friend to set. + * @return This builder for chaining. + */ + public Builder setFriend( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + friend_ = value; + onChanged(); + return this; + } + /** + * required string friend = 3; + * @return This builder for chaining. + */ + public Builder clearFriend() { + bitField0_ = (bitField0_ & ~0x00000004); + friend_ = getDefaultInstance().getFriend(); + onChanged(); + return this; + } + /** + * required string friend = 3; + * @param value The bytes for friend to set. + * @return This builder for chaining. + */ + public Builder setFriendBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + friend_ = value; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:management.BlockedUpdate) + } + + // @@protoc_insertion_point(class_scope:management.BlockedUpdate) + private static final proto.management.BlockedUpdate DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new proto.management.BlockedUpdate(); + } + + public static proto.management.BlockedUpdate getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public BlockedUpdate parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new BlockedUpdate(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public proto.management.BlockedUpdate getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + +} + diff --git a/Server/src/main/proto/management/BlockedUpdateOrBuilder.java b/Server/src/main/proto/management/BlockedUpdateOrBuilder.java new file mode 100644 index 0000000..2a03762 --- /dev/null +++ b/Server/src/main/proto/management/BlockedUpdateOrBuilder.java @@ -0,0 +1,54 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: Management.proto + +package proto.management; + +public interface BlockedUpdateOrBuilder extends + // @@protoc_insertion_point(interface_extends:management.BlockedUpdate) + com.google.protobuf.MessageOrBuilder { + + /** + * required .management.BlockedUpdate.Type type = 1; + * @return Whether the type field is set. + */ + boolean hasType(); + /** + * required .management.BlockedUpdate.Type type = 1; + * @return The type. + */ + proto.management.BlockedUpdate.Type getType(); + + /** + * required string username = 2; + * @return Whether the username field is set. + */ + boolean hasUsername(); + /** + * required string username = 2; + * @return The username. + */ + java.lang.String getUsername(); + /** + * required string username = 2; + * @return The bytes for username. + */ + com.google.protobuf.ByteString + getUsernameBytes(); + + /** + * required string friend = 3; + * @return Whether the friend field is set. + */ + boolean hasFriend(); + /** + * required string friend = 3; + * @return The friend. + */ + java.lang.String getFriend(); + /** + * required string friend = 3; + * @return The bytes for friend. + */ + com.google.protobuf.ByteString + getFriendBytes(); +} diff --git a/Server/src/main/proto/management/ClanJoinNotification.java b/Server/src/main/proto/management/ClanJoinNotification.java new file mode 100644 index 0000000..9b3cea5 --- /dev/null +++ b/Server/src/main/proto/management/ClanJoinNotification.java @@ -0,0 +1,864 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: Management.proto + +package proto.management; + +/** + * Protobuf type {@code management.ClanJoinNotification} + */ +public final class ClanJoinNotification extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:management.ClanJoinNotification) + ClanJoinNotificationOrBuilder { +private static final long serialVersionUID = 0L; + // Use ClanJoinNotification.newBuilder() to construct. + private ClanJoinNotification(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private ClanJoinNotification() { + username_ = ""; + clanName_ = ""; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new ClanJoinNotification(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private ClanJoinNotification( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + com.google.protobuf.ByteString bs = input.readBytes(); + bitField0_ |= 0x00000001; + username_ = bs; + break; + } + case 18: { + com.google.protobuf.ByteString bs = input.readBytes(); + bitField0_ |= 0x00000002; + clanName_ = bs; + break; + } + case 24: { + bitField0_ |= 0x00000004; + world_ = input.readInt32(); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return proto.management.ManagementProtos.internal_static_management_ClanJoinNotification_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return proto.management.ManagementProtos.internal_static_management_ClanJoinNotification_fieldAccessorTable + .ensureFieldAccessorsInitialized( + proto.management.ClanJoinNotification.class, proto.management.ClanJoinNotification.Builder.class); + } + + private int bitField0_; + public static final int USERNAME_FIELD_NUMBER = 1; + private volatile java.lang.Object username_; + /** + * required string username = 1; + * @return Whether the username field is set. + */ + @java.lang.Override + public boolean hasUsername() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required string username = 1; + * @return The username. + */ + @java.lang.Override + public java.lang.String getUsername() { + java.lang.Object ref = username_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + username_ = s; + } + return s; + } + } + /** + * required string username = 1; + * @return The bytes for username. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getUsernameBytes() { + java.lang.Object ref = username_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + username_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int CLANNAME_FIELD_NUMBER = 2; + private volatile java.lang.Object clanName_; + /** + * required string clanName = 2; + * @return Whether the clanName field is set. + */ + @java.lang.Override + public boolean hasClanName() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required string clanName = 2; + * @return The clanName. + */ + @java.lang.Override + public java.lang.String getClanName() { + java.lang.Object ref = clanName_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + clanName_ = s; + } + return s; + } + } + /** + * required string clanName = 2; + * @return The bytes for clanName. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getClanNameBytes() { + java.lang.Object ref = clanName_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + clanName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int WORLD_FIELD_NUMBER = 3; + private int world_; + /** + * required int32 world = 3; + * @return Whether the world field is set. + */ + @java.lang.Override + public boolean hasWorld() { + return ((bitField0_ & 0x00000004) != 0); + } + /** + * required int32 world = 3; + * @return The world. + */ + @java.lang.Override + public int getWorld() { + return world_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (!hasUsername()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasClanName()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasWorld()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 1, username_); + } + if (((bitField0_ & 0x00000002) != 0)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 2, clanName_); + } + if (((bitField0_ & 0x00000004) != 0)) { + output.writeInt32(3, world_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, username_); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, clanName_); + } + if (((bitField0_ & 0x00000004) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeInt32Size(3, world_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof proto.management.ClanJoinNotification)) { + return super.equals(obj); + } + proto.management.ClanJoinNotification other = (proto.management.ClanJoinNotification) obj; + + if (hasUsername() != other.hasUsername()) return false; + if (hasUsername()) { + if (!getUsername() + .equals(other.getUsername())) return false; + } + if (hasClanName() != other.hasClanName()) return false; + if (hasClanName()) { + if (!getClanName() + .equals(other.getClanName())) return false; + } + if (hasWorld() != other.hasWorld()) return false; + if (hasWorld()) { + if (getWorld() + != other.getWorld()) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasUsername()) { + hash = (37 * hash) + USERNAME_FIELD_NUMBER; + hash = (53 * hash) + getUsername().hashCode(); + } + if (hasClanName()) { + hash = (37 * hash) + CLANNAME_FIELD_NUMBER; + hash = (53 * hash) + getClanName().hashCode(); + } + if (hasWorld()) { + hash = (37 * hash) + WORLD_FIELD_NUMBER; + hash = (53 * hash) + getWorld(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static proto.management.ClanJoinNotification parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.ClanJoinNotification parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.ClanJoinNotification parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.ClanJoinNotification parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.ClanJoinNotification parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.ClanJoinNotification parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.ClanJoinNotification parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static proto.management.ClanJoinNotification parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static proto.management.ClanJoinNotification parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static proto.management.ClanJoinNotification parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static proto.management.ClanJoinNotification parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static proto.management.ClanJoinNotification parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(proto.management.ClanJoinNotification prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code management.ClanJoinNotification} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:management.ClanJoinNotification) + proto.management.ClanJoinNotificationOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return proto.management.ManagementProtos.internal_static_management_ClanJoinNotification_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return proto.management.ManagementProtos.internal_static_management_ClanJoinNotification_fieldAccessorTable + .ensureFieldAccessorsInitialized( + proto.management.ClanJoinNotification.class, proto.management.ClanJoinNotification.Builder.class); + } + + // Construct using proto.management.ClanJoinNotification.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + username_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + clanName_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + world_ = 0; + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return proto.management.ManagementProtos.internal_static_management_ClanJoinNotification_descriptor; + } + + @java.lang.Override + public proto.management.ClanJoinNotification getDefaultInstanceForType() { + return proto.management.ClanJoinNotification.getDefaultInstance(); + } + + @java.lang.Override + public proto.management.ClanJoinNotification build() { + proto.management.ClanJoinNotification result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public proto.management.ClanJoinNotification buildPartial() { + proto.management.ClanJoinNotification result = new proto.management.ClanJoinNotification(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + to_bitField0_ |= 0x00000001; + } + result.username_ = username_; + if (((from_bitField0_ & 0x00000002) != 0)) { + to_bitField0_ |= 0x00000002; + } + result.clanName_ = clanName_; + if (((from_bitField0_ & 0x00000004) != 0)) { + result.world_ = world_; + to_bitField0_ |= 0x00000004; + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof proto.management.ClanJoinNotification) { + return mergeFrom((proto.management.ClanJoinNotification)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(proto.management.ClanJoinNotification other) { + if (other == proto.management.ClanJoinNotification.getDefaultInstance()) return this; + if (other.hasUsername()) { + bitField0_ |= 0x00000001; + username_ = other.username_; + onChanged(); + } + if (other.hasClanName()) { + bitField0_ |= 0x00000002; + clanName_ = other.clanName_; + onChanged(); + } + if (other.hasWorld()) { + setWorld(other.getWorld()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (!hasUsername()) { + return false; + } + if (!hasClanName()) { + return false; + } + if (!hasWorld()) { + return false; + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + proto.management.ClanJoinNotification parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (proto.management.ClanJoinNotification) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private java.lang.Object username_ = ""; + /** + * required string username = 1; + * @return Whether the username field is set. + */ + public boolean hasUsername() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required string username = 1; + * @return The username. + */ + public java.lang.String getUsername() { + java.lang.Object ref = username_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + username_ = s; + } + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string username = 1; + * @return The bytes for username. + */ + public com.google.protobuf.ByteString + getUsernameBytes() { + java.lang.Object ref = username_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + username_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string username = 1; + * @param value The username to set. + * @return This builder for chaining. + */ + public Builder setUsername( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + username_ = value; + onChanged(); + return this; + } + /** + * required string username = 1; + * @return This builder for chaining. + */ + public Builder clearUsername() { + bitField0_ = (bitField0_ & ~0x00000001); + username_ = getDefaultInstance().getUsername(); + onChanged(); + return this; + } + /** + * required string username = 1; + * @param value The bytes for username to set. + * @return This builder for chaining. + */ + public Builder setUsernameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + username_ = value; + onChanged(); + return this; + } + + private java.lang.Object clanName_ = ""; + /** + * required string clanName = 2; + * @return Whether the clanName field is set. + */ + public boolean hasClanName() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required string clanName = 2; + * @return The clanName. + */ + public java.lang.String getClanName() { + java.lang.Object ref = clanName_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + clanName_ = s; + } + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string clanName = 2; + * @return The bytes for clanName. + */ + public com.google.protobuf.ByteString + getClanNameBytes() { + java.lang.Object ref = clanName_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + clanName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string clanName = 2; + * @param value The clanName to set. + * @return This builder for chaining. + */ + public Builder setClanName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + clanName_ = value; + onChanged(); + return this; + } + /** + * required string clanName = 2; + * @return This builder for chaining. + */ + public Builder clearClanName() { + bitField0_ = (bitField0_ & ~0x00000002); + clanName_ = getDefaultInstance().getClanName(); + onChanged(); + return this; + } + /** + * required string clanName = 2; + * @param value The bytes for clanName to set. + * @return This builder for chaining. + */ + public Builder setClanNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + clanName_ = value; + onChanged(); + return this; + } + + private int world_ ; + /** + * required int32 world = 3; + * @return Whether the world field is set. + */ + @java.lang.Override + public boolean hasWorld() { + return ((bitField0_ & 0x00000004) != 0); + } + /** + * required int32 world = 3; + * @return The world. + */ + @java.lang.Override + public int getWorld() { + return world_; + } + /** + * required int32 world = 3; + * @param value The world to set. + * @return This builder for chaining. + */ + public Builder setWorld(int value) { + bitField0_ |= 0x00000004; + world_ = value; + onChanged(); + return this; + } + /** + * required int32 world = 3; + * @return This builder for chaining. + */ + public Builder clearWorld() { + bitField0_ = (bitField0_ & ~0x00000004); + world_ = 0; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:management.ClanJoinNotification) + } + + // @@protoc_insertion_point(class_scope:management.ClanJoinNotification) + private static final proto.management.ClanJoinNotification DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new proto.management.ClanJoinNotification(); + } + + public static proto.management.ClanJoinNotification getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public ClanJoinNotification parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new ClanJoinNotification(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public proto.management.ClanJoinNotification getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + +} + diff --git a/Server/src/main/proto/management/ClanJoinNotificationOrBuilder.java b/Server/src/main/proto/management/ClanJoinNotificationOrBuilder.java new file mode 100644 index 0000000..69edea3 --- /dev/null +++ b/Server/src/main/proto/management/ClanJoinNotificationOrBuilder.java @@ -0,0 +1,54 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: Management.proto + +package proto.management; + +public interface ClanJoinNotificationOrBuilder extends + // @@protoc_insertion_point(interface_extends:management.ClanJoinNotification) + com.google.protobuf.MessageOrBuilder { + + /** + * required string username = 1; + * @return Whether the username field is set. + */ + boolean hasUsername(); + /** + * required string username = 1; + * @return The username. + */ + java.lang.String getUsername(); + /** + * required string username = 1; + * @return The bytes for username. + */ + com.google.protobuf.ByteString + getUsernameBytes(); + + /** + * required string clanName = 2; + * @return Whether the clanName field is set. + */ + boolean hasClanName(); + /** + * required string clanName = 2; + * @return The clanName. + */ + java.lang.String getClanName(); + /** + * required string clanName = 2; + * @return The bytes for clanName. + */ + com.google.protobuf.ByteString + getClanNameBytes(); + + /** + * required int32 world = 3; + * @return Whether the world field is set. + */ + boolean hasWorld(); + /** + * required int32 world = 3; + * @return The world. + */ + int getWorld(); +} diff --git a/Server/src/main/proto/management/ClanLeaveNotification.java b/Server/src/main/proto/management/ClanLeaveNotification.java new file mode 100644 index 0000000..75d14cc --- /dev/null +++ b/Server/src/main/proto/management/ClanLeaveNotification.java @@ -0,0 +1,864 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: Management.proto + +package proto.management; + +/** + * Protobuf type {@code management.ClanLeaveNotification} + */ +public final class ClanLeaveNotification extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:management.ClanLeaveNotification) + ClanLeaveNotificationOrBuilder { +private static final long serialVersionUID = 0L; + // Use ClanLeaveNotification.newBuilder() to construct. + private ClanLeaveNotification(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private ClanLeaveNotification() { + username_ = ""; + clanName_ = ""; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new ClanLeaveNotification(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private ClanLeaveNotification( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + com.google.protobuf.ByteString bs = input.readBytes(); + bitField0_ |= 0x00000001; + username_ = bs; + break; + } + case 18: { + com.google.protobuf.ByteString bs = input.readBytes(); + bitField0_ |= 0x00000002; + clanName_ = bs; + break; + } + case 24: { + bitField0_ |= 0x00000004; + world_ = input.readInt32(); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return proto.management.ManagementProtos.internal_static_management_ClanLeaveNotification_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return proto.management.ManagementProtos.internal_static_management_ClanLeaveNotification_fieldAccessorTable + .ensureFieldAccessorsInitialized( + proto.management.ClanLeaveNotification.class, proto.management.ClanLeaveNotification.Builder.class); + } + + private int bitField0_; + public static final int USERNAME_FIELD_NUMBER = 1; + private volatile java.lang.Object username_; + /** + * required string username = 1; + * @return Whether the username field is set. + */ + @java.lang.Override + public boolean hasUsername() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required string username = 1; + * @return The username. + */ + @java.lang.Override + public java.lang.String getUsername() { + java.lang.Object ref = username_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + username_ = s; + } + return s; + } + } + /** + * required string username = 1; + * @return The bytes for username. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getUsernameBytes() { + java.lang.Object ref = username_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + username_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int CLANNAME_FIELD_NUMBER = 2; + private volatile java.lang.Object clanName_; + /** + * required string clanName = 2; + * @return Whether the clanName field is set. + */ + @java.lang.Override + public boolean hasClanName() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required string clanName = 2; + * @return The clanName. + */ + @java.lang.Override + public java.lang.String getClanName() { + java.lang.Object ref = clanName_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + clanName_ = s; + } + return s; + } + } + /** + * required string clanName = 2; + * @return The bytes for clanName. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getClanNameBytes() { + java.lang.Object ref = clanName_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + clanName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int WORLD_FIELD_NUMBER = 3; + private int world_; + /** + * required int32 world = 3; + * @return Whether the world field is set. + */ + @java.lang.Override + public boolean hasWorld() { + return ((bitField0_ & 0x00000004) != 0); + } + /** + * required int32 world = 3; + * @return The world. + */ + @java.lang.Override + public int getWorld() { + return world_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (!hasUsername()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasClanName()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasWorld()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 1, username_); + } + if (((bitField0_ & 0x00000002) != 0)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 2, clanName_); + } + if (((bitField0_ & 0x00000004) != 0)) { + output.writeInt32(3, world_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, username_); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, clanName_); + } + if (((bitField0_ & 0x00000004) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeInt32Size(3, world_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof proto.management.ClanLeaveNotification)) { + return super.equals(obj); + } + proto.management.ClanLeaveNotification other = (proto.management.ClanLeaveNotification) obj; + + if (hasUsername() != other.hasUsername()) return false; + if (hasUsername()) { + if (!getUsername() + .equals(other.getUsername())) return false; + } + if (hasClanName() != other.hasClanName()) return false; + if (hasClanName()) { + if (!getClanName() + .equals(other.getClanName())) return false; + } + if (hasWorld() != other.hasWorld()) return false; + if (hasWorld()) { + if (getWorld() + != other.getWorld()) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasUsername()) { + hash = (37 * hash) + USERNAME_FIELD_NUMBER; + hash = (53 * hash) + getUsername().hashCode(); + } + if (hasClanName()) { + hash = (37 * hash) + CLANNAME_FIELD_NUMBER; + hash = (53 * hash) + getClanName().hashCode(); + } + if (hasWorld()) { + hash = (37 * hash) + WORLD_FIELD_NUMBER; + hash = (53 * hash) + getWorld(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static proto.management.ClanLeaveNotification parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.ClanLeaveNotification parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.ClanLeaveNotification parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.ClanLeaveNotification parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.ClanLeaveNotification parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.ClanLeaveNotification parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.ClanLeaveNotification parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static proto.management.ClanLeaveNotification parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static proto.management.ClanLeaveNotification parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static proto.management.ClanLeaveNotification parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static proto.management.ClanLeaveNotification parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static proto.management.ClanLeaveNotification parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(proto.management.ClanLeaveNotification prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code management.ClanLeaveNotification} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:management.ClanLeaveNotification) + proto.management.ClanLeaveNotificationOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return proto.management.ManagementProtos.internal_static_management_ClanLeaveNotification_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return proto.management.ManagementProtos.internal_static_management_ClanLeaveNotification_fieldAccessorTable + .ensureFieldAccessorsInitialized( + proto.management.ClanLeaveNotification.class, proto.management.ClanLeaveNotification.Builder.class); + } + + // Construct using proto.management.ClanLeaveNotification.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + username_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + clanName_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + world_ = 0; + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return proto.management.ManagementProtos.internal_static_management_ClanLeaveNotification_descriptor; + } + + @java.lang.Override + public proto.management.ClanLeaveNotification getDefaultInstanceForType() { + return proto.management.ClanLeaveNotification.getDefaultInstance(); + } + + @java.lang.Override + public proto.management.ClanLeaveNotification build() { + proto.management.ClanLeaveNotification result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public proto.management.ClanLeaveNotification buildPartial() { + proto.management.ClanLeaveNotification result = new proto.management.ClanLeaveNotification(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + to_bitField0_ |= 0x00000001; + } + result.username_ = username_; + if (((from_bitField0_ & 0x00000002) != 0)) { + to_bitField0_ |= 0x00000002; + } + result.clanName_ = clanName_; + if (((from_bitField0_ & 0x00000004) != 0)) { + result.world_ = world_; + to_bitField0_ |= 0x00000004; + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof proto.management.ClanLeaveNotification) { + return mergeFrom((proto.management.ClanLeaveNotification)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(proto.management.ClanLeaveNotification other) { + if (other == proto.management.ClanLeaveNotification.getDefaultInstance()) return this; + if (other.hasUsername()) { + bitField0_ |= 0x00000001; + username_ = other.username_; + onChanged(); + } + if (other.hasClanName()) { + bitField0_ |= 0x00000002; + clanName_ = other.clanName_; + onChanged(); + } + if (other.hasWorld()) { + setWorld(other.getWorld()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (!hasUsername()) { + return false; + } + if (!hasClanName()) { + return false; + } + if (!hasWorld()) { + return false; + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + proto.management.ClanLeaveNotification parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (proto.management.ClanLeaveNotification) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private java.lang.Object username_ = ""; + /** + * required string username = 1; + * @return Whether the username field is set. + */ + public boolean hasUsername() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required string username = 1; + * @return The username. + */ + public java.lang.String getUsername() { + java.lang.Object ref = username_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + username_ = s; + } + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string username = 1; + * @return The bytes for username. + */ + public com.google.protobuf.ByteString + getUsernameBytes() { + java.lang.Object ref = username_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + username_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string username = 1; + * @param value The username to set. + * @return This builder for chaining. + */ + public Builder setUsername( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + username_ = value; + onChanged(); + return this; + } + /** + * required string username = 1; + * @return This builder for chaining. + */ + public Builder clearUsername() { + bitField0_ = (bitField0_ & ~0x00000001); + username_ = getDefaultInstance().getUsername(); + onChanged(); + return this; + } + /** + * required string username = 1; + * @param value The bytes for username to set. + * @return This builder for chaining. + */ + public Builder setUsernameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + username_ = value; + onChanged(); + return this; + } + + private java.lang.Object clanName_ = ""; + /** + * required string clanName = 2; + * @return Whether the clanName field is set. + */ + public boolean hasClanName() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required string clanName = 2; + * @return The clanName. + */ + public java.lang.String getClanName() { + java.lang.Object ref = clanName_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + clanName_ = s; + } + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string clanName = 2; + * @return The bytes for clanName. + */ + public com.google.protobuf.ByteString + getClanNameBytes() { + java.lang.Object ref = clanName_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + clanName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string clanName = 2; + * @param value The clanName to set. + * @return This builder for chaining. + */ + public Builder setClanName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + clanName_ = value; + onChanged(); + return this; + } + /** + * required string clanName = 2; + * @return This builder for chaining. + */ + public Builder clearClanName() { + bitField0_ = (bitField0_ & ~0x00000002); + clanName_ = getDefaultInstance().getClanName(); + onChanged(); + return this; + } + /** + * required string clanName = 2; + * @param value The bytes for clanName to set. + * @return This builder for chaining. + */ + public Builder setClanNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + clanName_ = value; + onChanged(); + return this; + } + + private int world_ ; + /** + * required int32 world = 3; + * @return Whether the world field is set. + */ + @java.lang.Override + public boolean hasWorld() { + return ((bitField0_ & 0x00000004) != 0); + } + /** + * required int32 world = 3; + * @return The world. + */ + @java.lang.Override + public int getWorld() { + return world_; + } + /** + * required int32 world = 3; + * @param value The world to set. + * @return This builder for chaining. + */ + public Builder setWorld(int value) { + bitField0_ |= 0x00000004; + world_ = value; + onChanged(); + return this; + } + /** + * required int32 world = 3; + * @return This builder for chaining. + */ + public Builder clearWorld() { + bitField0_ = (bitField0_ & ~0x00000004); + world_ = 0; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:management.ClanLeaveNotification) + } + + // @@protoc_insertion_point(class_scope:management.ClanLeaveNotification) + private static final proto.management.ClanLeaveNotification DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new proto.management.ClanLeaveNotification(); + } + + public static proto.management.ClanLeaveNotification getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public ClanLeaveNotification parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new ClanLeaveNotification(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public proto.management.ClanLeaveNotification getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + +} + diff --git a/Server/src/main/proto/management/ClanLeaveNotificationOrBuilder.java b/Server/src/main/proto/management/ClanLeaveNotificationOrBuilder.java new file mode 100644 index 0000000..4d52ca3 --- /dev/null +++ b/Server/src/main/proto/management/ClanLeaveNotificationOrBuilder.java @@ -0,0 +1,54 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: Management.proto + +package proto.management; + +public interface ClanLeaveNotificationOrBuilder extends + // @@protoc_insertion_point(interface_extends:management.ClanLeaveNotification) + com.google.protobuf.MessageOrBuilder { + + /** + * required string username = 1; + * @return Whether the username field is set. + */ + boolean hasUsername(); + /** + * required string username = 1; + * @return The username. + */ + java.lang.String getUsername(); + /** + * required string username = 1; + * @return The bytes for username. + */ + com.google.protobuf.ByteString + getUsernameBytes(); + + /** + * required string clanName = 2; + * @return Whether the clanName field is set. + */ + boolean hasClanName(); + /** + * required string clanName = 2; + * @return The clanName. + */ + java.lang.String getClanName(); + /** + * required string clanName = 2; + * @return The bytes for clanName. + */ + com.google.protobuf.ByteString + getClanNameBytes(); + + /** + * required int32 world = 3; + * @return Whether the world field is set. + */ + boolean hasWorld(); + /** + * required int32 world = 3; + * @return The world. + */ + int getWorld(); +} diff --git a/Server/src/main/proto/management/ClanMessage.java b/Server/src/main/proto/management/ClanMessage.java new file mode 100644 index 0000000..65af29d --- /dev/null +++ b/Server/src/main/proto/management/ClanMessage.java @@ -0,0 +1,1036 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: Management.proto + +package proto.management; + +/** + * Protobuf type {@code management.ClanMessage} + */ +public final class ClanMessage extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:management.ClanMessage) + ClanMessageOrBuilder { +private static final long serialVersionUID = 0L; + // Use ClanMessage.newBuilder() to construct. + private ClanMessage(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private ClanMessage() { + sender_ = ""; + clanName_ = ""; + message_ = ""; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new ClanMessage(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private ClanMessage( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + com.google.protobuf.ByteString bs = input.readBytes(); + bitField0_ |= 0x00000001; + sender_ = bs; + break; + } + case 18: { + com.google.protobuf.ByteString bs = input.readBytes(); + bitField0_ |= 0x00000002; + clanName_ = bs; + break; + } + case 26: { + com.google.protobuf.ByteString bs = input.readBytes(); + bitField0_ |= 0x00000004; + message_ = bs; + break; + } + case 32: { + bitField0_ |= 0x00000008; + rank_ = input.readInt32(); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return proto.management.ManagementProtos.internal_static_management_ClanMessage_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return proto.management.ManagementProtos.internal_static_management_ClanMessage_fieldAccessorTable + .ensureFieldAccessorsInitialized( + proto.management.ClanMessage.class, proto.management.ClanMessage.Builder.class); + } + + private int bitField0_; + public static final int SENDER_FIELD_NUMBER = 1; + private volatile java.lang.Object sender_; + /** + * required string sender = 1; + * @return Whether the sender field is set. + */ + @java.lang.Override + public boolean hasSender() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required string sender = 1; + * @return The sender. + */ + @java.lang.Override + public java.lang.String getSender() { + java.lang.Object ref = sender_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + sender_ = s; + } + return s; + } + } + /** + * required string sender = 1; + * @return The bytes for sender. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getSenderBytes() { + java.lang.Object ref = sender_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + sender_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int CLANNAME_FIELD_NUMBER = 2; + private volatile java.lang.Object clanName_; + /** + * required string clanName = 2; + * @return Whether the clanName field is set. + */ + @java.lang.Override + public boolean hasClanName() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required string clanName = 2; + * @return The clanName. + */ + @java.lang.Override + public java.lang.String getClanName() { + java.lang.Object ref = clanName_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + clanName_ = s; + } + return s; + } + } + /** + * required string clanName = 2; + * @return The bytes for clanName. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getClanNameBytes() { + java.lang.Object ref = clanName_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + clanName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int MESSAGE_FIELD_NUMBER = 3; + private volatile java.lang.Object message_; + /** + * required string message = 3; + * @return Whether the message field is set. + */ + @java.lang.Override + public boolean hasMessage() { + return ((bitField0_ & 0x00000004) != 0); + } + /** + * required string message = 3; + * @return The message. + */ + @java.lang.Override + public java.lang.String getMessage() { + java.lang.Object ref = message_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + message_ = s; + } + return s; + } + } + /** + * required string message = 3; + * @return The bytes for message. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getMessageBytes() { + java.lang.Object ref = message_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + message_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int RANK_FIELD_NUMBER = 4; + private int rank_; + /** + * required int32 rank = 4; + * @return Whether the rank field is set. + */ + @java.lang.Override + public boolean hasRank() { + return ((bitField0_ & 0x00000008) != 0); + } + /** + * required int32 rank = 4; + * @return The rank. + */ + @java.lang.Override + public int getRank() { + return rank_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (!hasSender()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasClanName()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasMessage()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasRank()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 1, sender_); + } + if (((bitField0_ & 0x00000002) != 0)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 2, clanName_); + } + if (((bitField0_ & 0x00000004) != 0)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 3, message_); + } + if (((bitField0_ & 0x00000008) != 0)) { + output.writeInt32(4, rank_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, sender_); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, clanName_); + } + if (((bitField0_ & 0x00000004) != 0)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, message_); + } + if (((bitField0_ & 0x00000008) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeInt32Size(4, rank_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof proto.management.ClanMessage)) { + return super.equals(obj); + } + proto.management.ClanMessage other = (proto.management.ClanMessage) obj; + + if (hasSender() != other.hasSender()) return false; + if (hasSender()) { + if (!getSender() + .equals(other.getSender())) return false; + } + if (hasClanName() != other.hasClanName()) return false; + if (hasClanName()) { + if (!getClanName() + .equals(other.getClanName())) return false; + } + if (hasMessage() != other.hasMessage()) return false; + if (hasMessage()) { + if (!getMessage() + .equals(other.getMessage())) return false; + } + if (hasRank() != other.hasRank()) return false; + if (hasRank()) { + if (getRank() + != other.getRank()) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasSender()) { + hash = (37 * hash) + SENDER_FIELD_NUMBER; + hash = (53 * hash) + getSender().hashCode(); + } + if (hasClanName()) { + hash = (37 * hash) + CLANNAME_FIELD_NUMBER; + hash = (53 * hash) + getClanName().hashCode(); + } + if (hasMessage()) { + hash = (37 * hash) + MESSAGE_FIELD_NUMBER; + hash = (53 * hash) + getMessage().hashCode(); + } + if (hasRank()) { + hash = (37 * hash) + RANK_FIELD_NUMBER; + hash = (53 * hash) + getRank(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static proto.management.ClanMessage parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.ClanMessage parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.ClanMessage parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.ClanMessage parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.ClanMessage parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.ClanMessage parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.ClanMessage parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static proto.management.ClanMessage parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static proto.management.ClanMessage parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static proto.management.ClanMessage parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static proto.management.ClanMessage parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static proto.management.ClanMessage parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(proto.management.ClanMessage prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code management.ClanMessage} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:management.ClanMessage) + proto.management.ClanMessageOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return proto.management.ManagementProtos.internal_static_management_ClanMessage_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return proto.management.ManagementProtos.internal_static_management_ClanMessage_fieldAccessorTable + .ensureFieldAccessorsInitialized( + proto.management.ClanMessage.class, proto.management.ClanMessage.Builder.class); + } + + // Construct using proto.management.ClanMessage.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + sender_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + clanName_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + message_ = ""; + bitField0_ = (bitField0_ & ~0x00000004); + rank_ = 0; + bitField0_ = (bitField0_ & ~0x00000008); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return proto.management.ManagementProtos.internal_static_management_ClanMessage_descriptor; + } + + @java.lang.Override + public proto.management.ClanMessage getDefaultInstanceForType() { + return proto.management.ClanMessage.getDefaultInstance(); + } + + @java.lang.Override + public proto.management.ClanMessage build() { + proto.management.ClanMessage result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public proto.management.ClanMessage buildPartial() { + proto.management.ClanMessage result = new proto.management.ClanMessage(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + to_bitField0_ |= 0x00000001; + } + result.sender_ = sender_; + if (((from_bitField0_ & 0x00000002) != 0)) { + to_bitField0_ |= 0x00000002; + } + result.clanName_ = clanName_; + if (((from_bitField0_ & 0x00000004) != 0)) { + to_bitField0_ |= 0x00000004; + } + result.message_ = message_; + if (((from_bitField0_ & 0x00000008) != 0)) { + result.rank_ = rank_; + to_bitField0_ |= 0x00000008; + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof proto.management.ClanMessage) { + return mergeFrom((proto.management.ClanMessage)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(proto.management.ClanMessage other) { + if (other == proto.management.ClanMessage.getDefaultInstance()) return this; + if (other.hasSender()) { + bitField0_ |= 0x00000001; + sender_ = other.sender_; + onChanged(); + } + if (other.hasClanName()) { + bitField0_ |= 0x00000002; + clanName_ = other.clanName_; + onChanged(); + } + if (other.hasMessage()) { + bitField0_ |= 0x00000004; + message_ = other.message_; + onChanged(); + } + if (other.hasRank()) { + setRank(other.getRank()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (!hasSender()) { + return false; + } + if (!hasClanName()) { + return false; + } + if (!hasMessage()) { + return false; + } + if (!hasRank()) { + return false; + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + proto.management.ClanMessage parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (proto.management.ClanMessage) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private java.lang.Object sender_ = ""; + /** + * required string sender = 1; + * @return Whether the sender field is set. + */ + public boolean hasSender() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required string sender = 1; + * @return The sender. + */ + public java.lang.String getSender() { + java.lang.Object ref = sender_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + sender_ = s; + } + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string sender = 1; + * @return The bytes for sender. + */ + public com.google.protobuf.ByteString + getSenderBytes() { + java.lang.Object ref = sender_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + sender_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string sender = 1; + * @param value The sender to set. + * @return This builder for chaining. + */ + public Builder setSender( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + sender_ = value; + onChanged(); + return this; + } + /** + * required string sender = 1; + * @return This builder for chaining. + */ + public Builder clearSender() { + bitField0_ = (bitField0_ & ~0x00000001); + sender_ = getDefaultInstance().getSender(); + onChanged(); + return this; + } + /** + * required string sender = 1; + * @param value The bytes for sender to set. + * @return This builder for chaining. + */ + public Builder setSenderBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + sender_ = value; + onChanged(); + return this; + } + + private java.lang.Object clanName_ = ""; + /** + * required string clanName = 2; + * @return Whether the clanName field is set. + */ + public boolean hasClanName() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required string clanName = 2; + * @return The clanName. + */ + public java.lang.String getClanName() { + java.lang.Object ref = clanName_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + clanName_ = s; + } + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string clanName = 2; + * @return The bytes for clanName. + */ + public com.google.protobuf.ByteString + getClanNameBytes() { + java.lang.Object ref = clanName_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + clanName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string clanName = 2; + * @param value The clanName to set. + * @return This builder for chaining. + */ + public Builder setClanName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + clanName_ = value; + onChanged(); + return this; + } + /** + * required string clanName = 2; + * @return This builder for chaining. + */ + public Builder clearClanName() { + bitField0_ = (bitField0_ & ~0x00000002); + clanName_ = getDefaultInstance().getClanName(); + onChanged(); + return this; + } + /** + * required string clanName = 2; + * @param value The bytes for clanName to set. + * @return This builder for chaining. + */ + public Builder setClanNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + clanName_ = value; + onChanged(); + return this; + } + + private java.lang.Object message_ = ""; + /** + * required string message = 3; + * @return Whether the message field is set. + */ + public boolean hasMessage() { + return ((bitField0_ & 0x00000004) != 0); + } + /** + * required string message = 3; + * @return The message. + */ + public java.lang.String getMessage() { + java.lang.Object ref = message_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + message_ = s; + } + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string message = 3; + * @return The bytes for message. + */ + public com.google.protobuf.ByteString + getMessageBytes() { + java.lang.Object ref = message_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + message_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string message = 3; + * @param value The message to set. + * @return This builder for chaining. + */ + public Builder setMessage( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + message_ = value; + onChanged(); + return this; + } + /** + * required string message = 3; + * @return This builder for chaining. + */ + public Builder clearMessage() { + bitField0_ = (bitField0_ & ~0x00000004); + message_ = getDefaultInstance().getMessage(); + onChanged(); + return this; + } + /** + * required string message = 3; + * @param value The bytes for message to set. + * @return This builder for chaining. + */ + public Builder setMessageBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + message_ = value; + onChanged(); + return this; + } + + private int rank_ ; + /** + * required int32 rank = 4; + * @return Whether the rank field is set. + */ + @java.lang.Override + public boolean hasRank() { + return ((bitField0_ & 0x00000008) != 0); + } + /** + * required int32 rank = 4; + * @return The rank. + */ + @java.lang.Override + public int getRank() { + return rank_; + } + /** + * required int32 rank = 4; + * @param value The rank to set. + * @return This builder for chaining. + */ + public Builder setRank(int value) { + bitField0_ |= 0x00000008; + rank_ = value; + onChanged(); + return this; + } + /** + * required int32 rank = 4; + * @return This builder for chaining. + */ + public Builder clearRank() { + bitField0_ = (bitField0_ & ~0x00000008); + rank_ = 0; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:management.ClanMessage) + } + + // @@protoc_insertion_point(class_scope:management.ClanMessage) + private static final proto.management.ClanMessage DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new proto.management.ClanMessage(); + } + + public static proto.management.ClanMessage getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public ClanMessage parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new ClanMessage(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public proto.management.ClanMessage getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + +} + diff --git a/Server/src/main/proto/management/ClanMessageOrBuilder.java b/Server/src/main/proto/management/ClanMessageOrBuilder.java new file mode 100644 index 0000000..a9b48b6 --- /dev/null +++ b/Server/src/main/proto/management/ClanMessageOrBuilder.java @@ -0,0 +1,71 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: Management.proto + +package proto.management; + +public interface ClanMessageOrBuilder extends + // @@protoc_insertion_point(interface_extends:management.ClanMessage) + com.google.protobuf.MessageOrBuilder { + + /** + * required string sender = 1; + * @return Whether the sender field is set. + */ + boolean hasSender(); + /** + * required string sender = 1; + * @return The sender. + */ + java.lang.String getSender(); + /** + * required string sender = 1; + * @return The bytes for sender. + */ + com.google.protobuf.ByteString + getSenderBytes(); + + /** + * required string clanName = 2; + * @return Whether the clanName field is set. + */ + boolean hasClanName(); + /** + * required string clanName = 2; + * @return The clanName. + */ + java.lang.String getClanName(); + /** + * required string clanName = 2; + * @return The bytes for clanName. + */ + com.google.protobuf.ByteString + getClanNameBytes(); + + /** + * required string message = 3; + * @return Whether the message field is set. + */ + boolean hasMessage(); + /** + * required string message = 3; + * @return The message. + */ + java.lang.String getMessage(); + /** + * required string message = 3; + * @return The bytes for message. + */ + com.google.protobuf.ByteString + getMessageBytes(); + + /** + * required int32 rank = 4; + * @return Whether the rank field is set. + */ + boolean hasRank(); + /** + * required int32 rank = 4; + * @return The rank. + */ + int getRank(); +} diff --git a/Server/src/main/proto/management/ClanSettingsUpdateOrBuilder.java b/Server/src/main/proto/management/ClanSettingsUpdateOrBuilder.java new file mode 100644 index 0000000..61150bd --- /dev/null +++ b/Server/src/main/proto/management/ClanSettingsUpdateOrBuilder.java @@ -0,0 +1,9 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: Management.proto + +package proto.management; + +public interface ClanSettingsUpdateOrBuilder extends + // @@protoc_insertion_point(interface_extends:management.ClanSettingsUpdate) + com.google.protobuf.MessageOrBuilder { +} diff --git a/Server/src/main/proto/management/FriendUpdate.java b/Server/src/main/proto/management/FriendUpdate.java new file mode 100644 index 0000000..b8c13f2 --- /dev/null +++ b/Server/src/main/proto/management/FriendUpdate.java @@ -0,0 +1,971 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: Management.proto + +package proto.management; + +/** + * Protobuf type {@code management.FriendUpdate} + */ +public final class FriendUpdate extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:management.FriendUpdate) + FriendUpdateOrBuilder { +private static final long serialVersionUID = 0L; + // Use FriendUpdate.newBuilder() to construct. + private FriendUpdate(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private FriendUpdate() { + type_ = 0; + username_ = ""; + friend_ = ""; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new FriendUpdate(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private FriendUpdate( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 8: { + int rawValue = input.readEnum(); + @SuppressWarnings("deprecation") + proto.management.FriendUpdate.Type value = proto.management.FriendUpdate.Type.valueOf(rawValue); + if (value == null) { + unknownFields.mergeVarintField(1, rawValue); + } else { + bitField0_ |= 0x00000001; + type_ = rawValue; + } + break; + } + case 18: { + com.google.protobuf.ByteString bs = input.readBytes(); + bitField0_ |= 0x00000002; + username_ = bs; + break; + } + case 26: { + com.google.protobuf.ByteString bs = input.readBytes(); + bitField0_ |= 0x00000004; + friend_ = bs; + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return proto.management.ManagementProtos.internal_static_management_FriendUpdate_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return proto.management.ManagementProtos.internal_static_management_FriendUpdate_fieldAccessorTable + .ensureFieldAccessorsInitialized( + proto.management.FriendUpdate.class, proto.management.FriendUpdate.Builder.class); + } + + /** + * Protobuf enum {@code management.FriendUpdate.Type} + */ + public enum Type + implements com.google.protobuf.ProtocolMessageEnum { + /** + * ADD = 0; + */ + ADD(0), + /** + * REMOVE = 1; + */ + REMOVE(1), + ; + + /** + * ADD = 0; + */ + public static final int ADD_VALUE = 0; + /** + * REMOVE = 1; + */ + public static final int REMOVE_VALUE = 1; + + + public final int getNumber() { + return value; + } + + /** + * @param value The numeric wire value of the corresponding enum entry. + * @return The enum associated with the given numeric wire value. + * @deprecated Use {@link #forNumber(int)} instead. + */ + @java.lang.Deprecated + public static Type valueOf(int value) { + return forNumber(value); + } + + /** + * @param value The numeric wire value of the corresponding enum entry. + * @return The enum associated with the given numeric wire value. + */ + public static Type forNumber(int value) { + switch (value) { + case 0: return ADD; + case 1: return REMOVE; + default: return null; + } + } + + public static com.google.protobuf.Internal.EnumLiteMap + internalGetValueMap() { + return internalValueMap; + } + private static final com.google.protobuf.Internal.EnumLiteMap< + Type> internalValueMap = + new com.google.protobuf.Internal.EnumLiteMap() { + public Type findValueByNumber(int number) { + return Type.forNumber(number); + } + }; + + public final com.google.protobuf.Descriptors.EnumValueDescriptor + getValueDescriptor() { + return getDescriptor().getValues().get(ordinal()); + } + public final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptorForType() { + return getDescriptor(); + } + public static final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptor() { + return proto.management.FriendUpdate.getDescriptor().getEnumTypes().get(0); + } + + private static final Type[] VALUES = values(); + + public static Type valueOf( + com.google.protobuf.Descriptors.EnumValueDescriptor desc) { + if (desc.getType() != getDescriptor()) { + throw new java.lang.IllegalArgumentException( + "EnumValueDescriptor is not for this type."); + } + return VALUES[desc.getIndex()]; + } + + private final int value; + + private Type(int value) { + this.value = value; + } + + // @@protoc_insertion_point(enum_scope:management.FriendUpdate.Type) + } + + private int bitField0_; + public static final int TYPE_FIELD_NUMBER = 1; + private int type_; + /** + * required .management.FriendUpdate.Type type = 1; + * @return Whether the type field is set. + */ + @java.lang.Override public boolean hasType() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required .management.FriendUpdate.Type type = 1; + * @return The type. + */ + @java.lang.Override public proto.management.FriendUpdate.Type getType() { + @SuppressWarnings("deprecation") + proto.management.FriendUpdate.Type result = proto.management.FriendUpdate.Type.valueOf(type_); + return result == null ? proto.management.FriendUpdate.Type.ADD : result; + } + + public static final int USERNAME_FIELD_NUMBER = 2; + private volatile java.lang.Object username_; + /** + * required string username = 2; + * @return Whether the username field is set. + */ + @java.lang.Override + public boolean hasUsername() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required string username = 2; + * @return The username. + */ + @java.lang.Override + public java.lang.String getUsername() { + java.lang.Object ref = username_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + username_ = s; + } + return s; + } + } + /** + * required string username = 2; + * @return The bytes for username. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getUsernameBytes() { + java.lang.Object ref = username_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + username_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int FRIEND_FIELD_NUMBER = 3; + private volatile java.lang.Object friend_; + /** + * required string friend = 3; + * @return Whether the friend field is set. + */ + @java.lang.Override + public boolean hasFriend() { + return ((bitField0_ & 0x00000004) != 0); + } + /** + * required string friend = 3; + * @return The friend. + */ + @java.lang.Override + public java.lang.String getFriend() { + java.lang.Object ref = friend_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + friend_ = s; + } + return s; + } + } + /** + * required string friend = 3; + * @return The bytes for friend. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getFriendBytes() { + java.lang.Object ref = friend_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + friend_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (!hasType()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasUsername()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasFriend()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + output.writeEnum(1, type_); + } + if (((bitField0_ & 0x00000002) != 0)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 2, username_); + } + if (((bitField0_ & 0x00000004) != 0)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 3, friend_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeEnumSize(1, type_); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, username_); + } + if (((bitField0_ & 0x00000004) != 0)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, friend_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof proto.management.FriendUpdate)) { + return super.equals(obj); + } + proto.management.FriendUpdate other = (proto.management.FriendUpdate) obj; + + if (hasType() != other.hasType()) return false; + if (hasType()) { + if (type_ != other.type_) return false; + } + if (hasUsername() != other.hasUsername()) return false; + if (hasUsername()) { + if (!getUsername() + .equals(other.getUsername())) return false; + } + if (hasFriend() != other.hasFriend()) return false; + if (hasFriend()) { + if (!getFriend() + .equals(other.getFriend())) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasType()) { + hash = (37 * hash) + TYPE_FIELD_NUMBER; + hash = (53 * hash) + type_; + } + if (hasUsername()) { + hash = (37 * hash) + USERNAME_FIELD_NUMBER; + hash = (53 * hash) + getUsername().hashCode(); + } + if (hasFriend()) { + hash = (37 * hash) + FRIEND_FIELD_NUMBER; + hash = (53 * hash) + getFriend().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static proto.management.FriendUpdate parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.FriendUpdate parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.FriendUpdate parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.FriendUpdate parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.FriendUpdate parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.FriendUpdate parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.FriendUpdate parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static proto.management.FriendUpdate parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static proto.management.FriendUpdate parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static proto.management.FriendUpdate parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static proto.management.FriendUpdate parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static proto.management.FriendUpdate parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(proto.management.FriendUpdate prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code management.FriendUpdate} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:management.FriendUpdate) + proto.management.FriendUpdateOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return proto.management.ManagementProtos.internal_static_management_FriendUpdate_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return proto.management.ManagementProtos.internal_static_management_FriendUpdate_fieldAccessorTable + .ensureFieldAccessorsInitialized( + proto.management.FriendUpdate.class, proto.management.FriendUpdate.Builder.class); + } + + // Construct using proto.management.FriendUpdate.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + type_ = 0; + bitField0_ = (bitField0_ & ~0x00000001); + username_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + friend_ = ""; + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return proto.management.ManagementProtos.internal_static_management_FriendUpdate_descriptor; + } + + @java.lang.Override + public proto.management.FriendUpdate getDefaultInstanceForType() { + return proto.management.FriendUpdate.getDefaultInstance(); + } + + @java.lang.Override + public proto.management.FriendUpdate build() { + proto.management.FriendUpdate result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public proto.management.FriendUpdate buildPartial() { + proto.management.FriendUpdate result = new proto.management.FriendUpdate(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + to_bitField0_ |= 0x00000001; + } + result.type_ = type_; + if (((from_bitField0_ & 0x00000002) != 0)) { + to_bitField0_ |= 0x00000002; + } + result.username_ = username_; + if (((from_bitField0_ & 0x00000004) != 0)) { + to_bitField0_ |= 0x00000004; + } + result.friend_ = friend_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof proto.management.FriendUpdate) { + return mergeFrom((proto.management.FriendUpdate)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(proto.management.FriendUpdate other) { + if (other == proto.management.FriendUpdate.getDefaultInstance()) return this; + if (other.hasType()) { + setType(other.getType()); + } + if (other.hasUsername()) { + bitField0_ |= 0x00000002; + username_ = other.username_; + onChanged(); + } + if (other.hasFriend()) { + bitField0_ |= 0x00000004; + friend_ = other.friend_; + onChanged(); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (!hasType()) { + return false; + } + if (!hasUsername()) { + return false; + } + if (!hasFriend()) { + return false; + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + proto.management.FriendUpdate parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (proto.management.FriendUpdate) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private int type_ = 0; + /** + * required .management.FriendUpdate.Type type = 1; + * @return Whether the type field is set. + */ + @java.lang.Override public boolean hasType() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required .management.FriendUpdate.Type type = 1; + * @return The type. + */ + @java.lang.Override + public proto.management.FriendUpdate.Type getType() { + @SuppressWarnings("deprecation") + proto.management.FriendUpdate.Type result = proto.management.FriendUpdate.Type.valueOf(type_); + return result == null ? proto.management.FriendUpdate.Type.ADD : result; + } + /** + * required .management.FriendUpdate.Type type = 1; + * @param value The type to set. + * @return This builder for chaining. + */ + public Builder setType(proto.management.FriendUpdate.Type value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + type_ = value.getNumber(); + onChanged(); + return this; + } + /** + * required .management.FriendUpdate.Type type = 1; + * @return This builder for chaining. + */ + public Builder clearType() { + bitField0_ = (bitField0_ & ~0x00000001); + type_ = 0; + onChanged(); + return this; + } + + private java.lang.Object username_ = ""; + /** + * required string username = 2; + * @return Whether the username field is set. + */ + public boolean hasUsername() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required string username = 2; + * @return The username. + */ + public java.lang.String getUsername() { + java.lang.Object ref = username_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + username_ = s; + } + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string username = 2; + * @return The bytes for username. + */ + public com.google.protobuf.ByteString + getUsernameBytes() { + java.lang.Object ref = username_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + username_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string username = 2; + * @param value The username to set. + * @return This builder for chaining. + */ + public Builder setUsername( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + username_ = value; + onChanged(); + return this; + } + /** + * required string username = 2; + * @return This builder for chaining. + */ + public Builder clearUsername() { + bitField0_ = (bitField0_ & ~0x00000002); + username_ = getDefaultInstance().getUsername(); + onChanged(); + return this; + } + /** + * required string username = 2; + * @param value The bytes for username to set. + * @return This builder for chaining. + */ + public Builder setUsernameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + username_ = value; + onChanged(); + return this; + } + + private java.lang.Object friend_ = ""; + /** + * required string friend = 3; + * @return Whether the friend field is set. + */ + public boolean hasFriend() { + return ((bitField0_ & 0x00000004) != 0); + } + /** + * required string friend = 3; + * @return The friend. + */ + public java.lang.String getFriend() { + java.lang.Object ref = friend_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + friend_ = s; + } + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string friend = 3; + * @return The bytes for friend. + */ + public com.google.protobuf.ByteString + getFriendBytes() { + java.lang.Object ref = friend_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + friend_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string friend = 3; + * @param value The friend to set. + * @return This builder for chaining. + */ + public Builder setFriend( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + friend_ = value; + onChanged(); + return this; + } + /** + * required string friend = 3; + * @return This builder for chaining. + */ + public Builder clearFriend() { + bitField0_ = (bitField0_ & ~0x00000004); + friend_ = getDefaultInstance().getFriend(); + onChanged(); + return this; + } + /** + * required string friend = 3; + * @param value The bytes for friend to set. + * @return This builder for chaining. + */ + public Builder setFriendBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + friend_ = value; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:management.FriendUpdate) + } + + // @@protoc_insertion_point(class_scope:management.FriendUpdate) + private static final proto.management.FriendUpdate DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new proto.management.FriendUpdate(); + } + + public static proto.management.FriendUpdate getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public FriendUpdate parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new FriendUpdate(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public proto.management.FriendUpdate getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + +} + diff --git a/Server/src/main/proto/management/FriendUpdateOrBuilder.java b/Server/src/main/proto/management/FriendUpdateOrBuilder.java new file mode 100644 index 0000000..2f63a1d --- /dev/null +++ b/Server/src/main/proto/management/FriendUpdateOrBuilder.java @@ -0,0 +1,54 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: Management.proto + +package proto.management; + +public interface FriendUpdateOrBuilder extends + // @@protoc_insertion_point(interface_extends:management.FriendUpdate) + com.google.protobuf.MessageOrBuilder { + + /** + * required .management.FriendUpdate.Type type = 1; + * @return Whether the type field is set. + */ + boolean hasType(); + /** + * required .management.FriendUpdate.Type type = 1; + * @return The type. + */ + proto.management.FriendUpdate.Type getType(); + + /** + * required string username = 2; + * @return Whether the username field is set. + */ + boolean hasUsername(); + /** + * required string username = 2; + * @return The username. + */ + java.lang.String getUsername(); + /** + * required string username = 2; + * @return The bytes for username. + */ + com.google.protobuf.ByteString + getUsernameBytes(); + + /** + * required string friend = 3; + * @return Whether the friend field is set. + */ + boolean hasFriend(); + /** + * required string friend = 3; + * @return The friend. + */ + java.lang.String getFriend(); + /** + * required string friend = 3; + * @return The bytes for friend. + */ + com.google.protobuf.ByteString + getFriendBytes(); +} diff --git a/Server/src/main/proto/management/JoinClanRequest.java b/Server/src/main/proto/management/JoinClanRequest.java new file mode 100644 index 0000000..c578b69 --- /dev/null +++ b/Server/src/main/proto/management/JoinClanRequest.java @@ -0,0 +1,769 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: Management.proto + +package proto.management; + +/** + * Protobuf type {@code management.JoinClanRequest} + */ +public final class JoinClanRequest extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:management.JoinClanRequest) + JoinClanRequestOrBuilder { +private static final long serialVersionUID = 0L; + // Use JoinClanRequest.newBuilder() to construct. + private JoinClanRequest(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private JoinClanRequest() { + username_ = ""; + clanName_ = ""; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new JoinClanRequest(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private JoinClanRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + com.google.protobuf.ByteString bs = input.readBytes(); + bitField0_ |= 0x00000001; + username_ = bs; + break; + } + case 18: { + com.google.protobuf.ByteString bs = input.readBytes(); + bitField0_ |= 0x00000002; + clanName_ = bs; + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return proto.management.ManagementProtos.internal_static_management_JoinClanRequest_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return proto.management.ManagementProtos.internal_static_management_JoinClanRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + proto.management.JoinClanRequest.class, proto.management.JoinClanRequest.Builder.class); + } + + private int bitField0_; + public static final int USERNAME_FIELD_NUMBER = 1; + private volatile java.lang.Object username_; + /** + * required string username = 1; + * @return Whether the username field is set. + */ + @java.lang.Override + public boolean hasUsername() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required string username = 1; + * @return The username. + */ + @java.lang.Override + public java.lang.String getUsername() { + java.lang.Object ref = username_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + username_ = s; + } + return s; + } + } + /** + * required string username = 1; + * @return The bytes for username. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getUsernameBytes() { + java.lang.Object ref = username_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + username_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int CLANNAME_FIELD_NUMBER = 2; + private volatile java.lang.Object clanName_; + /** + * required string clanName = 2; + * @return Whether the clanName field is set. + */ + @java.lang.Override + public boolean hasClanName() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required string clanName = 2; + * @return The clanName. + */ + @java.lang.Override + public java.lang.String getClanName() { + java.lang.Object ref = clanName_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + clanName_ = s; + } + return s; + } + } + /** + * required string clanName = 2; + * @return The bytes for clanName. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getClanNameBytes() { + java.lang.Object ref = clanName_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + clanName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (!hasUsername()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasClanName()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 1, username_); + } + if (((bitField0_ & 0x00000002) != 0)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 2, clanName_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, username_); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, clanName_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof proto.management.JoinClanRequest)) { + return super.equals(obj); + } + proto.management.JoinClanRequest other = (proto.management.JoinClanRequest) obj; + + if (hasUsername() != other.hasUsername()) return false; + if (hasUsername()) { + if (!getUsername() + .equals(other.getUsername())) return false; + } + if (hasClanName() != other.hasClanName()) return false; + if (hasClanName()) { + if (!getClanName() + .equals(other.getClanName())) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasUsername()) { + hash = (37 * hash) + USERNAME_FIELD_NUMBER; + hash = (53 * hash) + getUsername().hashCode(); + } + if (hasClanName()) { + hash = (37 * hash) + CLANNAME_FIELD_NUMBER; + hash = (53 * hash) + getClanName().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static proto.management.JoinClanRequest parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.JoinClanRequest parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.JoinClanRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.JoinClanRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.JoinClanRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.JoinClanRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.JoinClanRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static proto.management.JoinClanRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static proto.management.JoinClanRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static proto.management.JoinClanRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static proto.management.JoinClanRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static proto.management.JoinClanRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(proto.management.JoinClanRequest prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code management.JoinClanRequest} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:management.JoinClanRequest) + proto.management.JoinClanRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return proto.management.ManagementProtos.internal_static_management_JoinClanRequest_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return proto.management.ManagementProtos.internal_static_management_JoinClanRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + proto.management.JoinClanRequest.class, proto.management.JoinClanRequest.Builder.class); + } + + // Construct using proto.management.JoinClanRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + username_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + clanName_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return proto.management.ManagementProtos.internal_static_management_JoinClanRequest_descriptor; + } + + @java.lang.Override + public proto.management.JoinClanRequest getDefaultInstanceForType() { + return proto.management.JoinClanRequest.getDefaultInstance(); + } + + @java.lang.Override + public proto.management.JoinClanRequest build() { + proto.management.JoinClanRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public proto.management.JoinClanRequest buildPartial() { + proto.management.JoinClanRequest result = new proto.management.JoinClanRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + to_bitField0_ |= 0x00000001; + } + result.username_ = username_; + if (((from_bitField0_ & 0x00000002) != 0)) { + to_bitField0_ |= 0x00000002; + } + result.clanName_ = clanName_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof proto.management.JoinClanRequest) { + return mergeFrom((proto.management.JoinClanRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(proto.management.JoinClanRequest other) { + if (other == proto.management.JoinClanRequest.getDefaultInstance()) return this; + if (other.hasUsername()) { + bitField0_ |= 0x00000001; + username_ = other.username_; + onChanged(); + } + if (other.hasClanName()) { + bitField0_ |= 0x00000002; + clanName_ = other.clanName_; + onChanged(); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (!hasUsername()) { + return false; + } + if (!hasClanName()) { + return false; + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + proto.management.JoinClanRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (proto.management.JoinClanRequest) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private java.lang.Object username_ = ""; + /** + * required string username = 1; + * @return Whether the username field is set. + */ + public boolean hasUsername() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required string username = 1; + * @return The username. + */ + public java.lang.String getUsername() { + java.lang.Object ref = username_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + username_ = s; + } + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string username = 1; + * @return The bytes for username. + */ + public com.google.protobuf.ByteString + getUsernameBytes() { + java.lang.Object ref = username_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + username_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string username = 1; + * @param value The username to set. + * @return This builder for chaining. + */ + public Builder setUsername( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + username_ = value; + onChanged(); + return this; + } + /** + * required string username = 1; + * @return This builder for chaining. + */ + public Builder clearUsername() { + bitField0_ = (bitField0_ & ~0x00000001); + username_ = getDefaultInstance().getUsername(); + onChanged(); + return this; + } + /** + * required string username = 1; + * @param value The bytes for username to set. + * @return This builder for chaining. + */ + public Builder setUsernameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + username_ = value; + onChanged(); + return this; + } + + private java.lang.Object clanName_ = ""; + /** + * required string clanName = 2; + * @return Whether the clanName field is set. + */ + public boolean hasClanName() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required string clanName = 2; + * @return The clanName. + */ + public java.lang.String getClanName() { + java.lang.Object ref = clanName_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + clanName_ = s; + } + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string clanName = 2; + * @return The bytes for clanName. + */ + public com.google.protobuf.ByteString + getClanNameBytes() { + java.lang.Object ref = clanName_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + clanName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string clanName = 2; + * @param value The clanName to set. + * @return This builder for chaining. + */ + public Builder setClanName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + clanName_ = value; + onChanged(); + return this; + } + /** + * required string clanName = 2; + * @return This builder for chaining. + */ + public Builder clearClanName() { + bitField0_ = (bitField0_ & ~0x00000002); + clanName_ = getDefaultInstance().getClanName(); + onChanged(); + return this; + } + /** + * required string clanName = 2; + * @param value The bytes for clanName to set. + * @return This builder for chaining. + */ + public Builder setClanNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + clanName_ = value; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:management.JoinClanRequest) + } + + // @@protoc_insertion_point(class_scope:management.JoinClanRequest) + private static final proto.management.JoinClanRequest DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new proto.management.JoinClanRequest(); + } + + public static proto.management.JoinClanRequest getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public JoinClanRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new JoinClanRequest(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public proto.management.JoinClanRequest getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + +} + diff --git a/Server/src/main/proto/management/JoinClanRequestOrBuilder.java b/Server/src/main/proto/management/JoinClanRequestOrBuilder.java new file mode 100644 index 0000000..ab5ddd7 --- /dev/null +++ b/Server/src/main/proto/management/JoinClanRequestOrBuilder.java @@ -0,0 +1,43 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: Management.proto + +package proto.management; + +public interface JoinClanRequestOrBuilder extends + // @@protoc_insertion_point(interface_extends:management.JoinClanRequest) + com.google.protobuf.MessageOrBuilder { + + /** + * required string username = 1; + * @return Whether the username field is set. + */ + boolean hasUsername(); + /** + * required string username = 1; + * @return The username. + */ + java.lang.String getUsername(); + /** + * required string username = 1; + * @return The bytes for username. + */ + com.google.protobuf.ByteString + getUsernameBytes(); + + /** + * required string clanName = 2; + * @return Whether the clanName field is set. + */ + boolean hasClanName(); + /** + * required string clanName = 2; + * @return The clanName. + */ + java.lang.String getClanName(); + /** + * required string clanName = 2; + * @return The bytes for clanName. + */ + com.google.protobuf.ByteString + getClanNameBytes(); +} diff --git a/Server/src/main/proto/management/LeaveClanRequest.java b/Server/src/main/proto/management/LeaveClanRequest.java new file mode 100644 index 0000000..ab82528 --- /dev/null +++ b/Server/src/main/proto/management/LeaveClanRequest.java @@ -0,0 +1,769 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: Management.proto + +package proto.management; + +/** + * Protobuf type {@code management.LeaveClanRequest} + */ +public final class LeaveClanRequest extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:management.LeaveClanRequest) + LeaveClanRequestOrBuilder { +private static final long serialVersionUID = 0L; + // Use LeaveClanRequest.newBuilder() to construct. + private LeaveClanRequest(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private LeaveClanRequest() { + username_ = ""; + clanName_ = ""; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new LeaveClanRequest(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private LeaveClanRequest( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + com.google.protobuf.ByteString bs = input.readBytes(); + bitField0_ |= 0x00000001; + username_ = bs; + break; + } + case 18: { + com.google.protobuf.ByteString bs = input.readBytes(); + bitField0_ |= 0x00000002; + clanName_ = bs; + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return proto.management.ManagementProtos.internal_static_management_LeaveClanRequest_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return proto.management.ManagementProtos.internal_static_management_LeaveClanRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + proto.management.LeaveClanRequest.class, proto.management.LeaveClanRequest.Builder.class); + } + + private int bitField0_; + public static final int USERNAME_FIELD_NUMBER = 1; + private volatile java.lang.Object username_; + /** + * required string username = 1; + * @return Whether the username field is set. + */ + @java.lang.Override + public boolean hasUsername() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required string username = 1; + * @return The username. + */ + @java.lang.Override + public java.lang.String getUsername() { + java.lang.Object ref = username_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + username_ = s; + } + return s; + } + } + /** + * required string username = 1; + * @return The bytes for username. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getUsernameBytes() { + java.lang.Object ref = username_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + username_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int CLANNAME_FIELD_NUMBER = 2; + private volatile java.lang.Object clanName_; + /** + * required string clanName = 2; + * @return Whether the clanName field is set. + */ + @java.lang.Override + public boolean hasClanName() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required string clanName = 2; + * @return The clanName. + */ + @java.lang.Override + public java.lang.String getClanName() { + java.lang.Object ref = clanName_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + clanName_ = s; + } + return s; + } + } + /** + * required string clanName = 2; + * @return The bytes for clanName. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getClanNameBytes() { + java.lang.Object ref = clanName_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + clanName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (!hasUsername()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasClanName()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 1, username_); + } + if (((bitField0_ & 0x00000002) != 0)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 2, clanName_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, username_); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, clanName_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof proto.management.LeaveClanRequest)) { + return super.equals(obj); + } + proto.management.LeaveClanRequest other = (proto.management.LeaveClanRequest) obj; + + if (hasUsername() != other.hasUsername()) return false; + if (hasUsername()) { + if (!getUsername() + .equals(other.getUsername())) return false; + } + if (hasClanName() != other.hasClanName()) return false; + if (hasClanName()) { + if (!getClanName() + .equals(other.getClanName())) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasUsername()) { + hash = (37 * hash) + USERNAME_FIELD_NUMBER; + hash = (53 * hash) + getUsername().hashCode(); + } + if (hasClanName()) { + hash = (37 * hash) + CLANNAME_FIELD_NUMBER; + hash = (53 * hash) + getClanName().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static proto.management.LeaveClanRequest parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.LeaveClanRequest parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.LeaveClanRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.LeaveClanRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.LeaveClanRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.LeaveClanRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.LeaveClanRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static proto.management.LeaveClanRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static proto.management.LeaveClanRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static proto.management.LeaveClanRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static proto.management.LeaveClanRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static proto.management.LeaveClanRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(proto.management.LeaveClanRequest prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code management.LeaveClanRequest} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:management.LeaveClanRequest) + proto.management.LeaveClanRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return proto.management.ManagementProtos.internal_static_management_LeaveClanRequest_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return proto.management.ManagementProtos.internal_static_management_LeaveClanRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + proto.management.LeaveClanRequest.class, proto.management.LeaveClanRequest.Builder.class); + } + + // Construct using proto.management.LeaveClanRequest.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + username_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + clanName_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return proto.management.ManagementProtos.internal_static_management_LeaveClanRequest_descriptor; + } + + @java.lang.Override + public proto.management.LeaveClanRequest getDefaultInstanceForType() { + return proto.management.LeaveClanRequest.getDefaultInstance(); + } + + @java.lang.Override + public proto.management.LeaveClanRequest build() { + proto.management.LeaveClanRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public proto.management.LeaveClanRequest buildPartial() { + proto.management.LeaveClanRequest result = new proto.management.LeaveClanRequest(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + to_bitField0_ |= 0x00000001; + } + result.username_ = username_; + if (((from_bitField0_ & 0x00000002) != 0)) { + to_bitField0_ |= 0x00000002; + } + result.clanName_ = clanName_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof proto.management.LeaveClanRequest) { + return mergeFrom((proto.management.LeaveClanRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(proto.management.LeaveClanRequest other) { + if (other == proto.management.LeaveClanRequest.getDefaultInstance()) return this; + if (other.hasUsername()) { + bitField0_ |= 0x00000001; + username_ = other.username_; + onChanged(); + } + if (other.hasClanName()) { + bitField0_ |= 0x00000002; + clanName_ = other.clanName_; + onChanged(); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (!hasUsername()) { + return false; + } + if (!hasClanName()) { + return false; + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + proto.management.LeaveClanRequest parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (proto.management.LeaveClanRequest) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private java.lang.Object username_ = ""; + /** + * required string username = 1; + * @return Whether the username field is set. + */ + public boolean hasUsername() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required string username = 1; + * @return The username. + */ + public java.lang.String getUsername() { + java.lang.Object ref = username_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + username_ = s; + } + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string username = 1; + * @return The bytes for username. + */ + public com.google.protobuf.ByteString + getUsernameBytes() { + java.lang.Object ref = username_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + username_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string username = 1; + * @param value The username to set. + * @return This builder for chaining. + */ + public Builder setUsername( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + username_ = value; + onChanged(); + return this; + } + /** + * required string username = 1; + * @return This builder for chaining. + */ + public Builder clearUsername() { + bitField0_ = (bitField0_ & ~0x00000001); + username_ = getDefaultInstance().getUsername(); + onChanged(); + return this; + } + /** + * required string username = 1; + * @param value The bytes for username to set. + * @return This builder for chaining. + */ + public Builder setUsernameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + username_ = value; + onChanged(); + return this; + } + + private java.lang.Object clanName_ = ""; + /** + * required string clanName = 2; + * @return Whether the clanName field is set. + */ + public boolean hasClanName() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required string clanName = 2; + * @return The clanName. + */ + public java.lang.String getClanName() { + java.lang.Object ref = clanName_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + clanName_ = s; + } + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string clanName = 2; + * @return The bytes for clanName. + */ + public com.google.protobuf.ByteString + getClanNameBytes() { + java.lang.Object ref = clanName_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + clanName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string clanName = 2; + * @param value The clanName to set. + * @return This builder for chaining. + */ + public Builder setClanName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + clanName_ = value; + onChanged(); + return this; + } + /** + * required string clanName = 2; + * @return This builder for chaining. + */ + public Builder clearClanName() { + bitField0_ = (bitField0_ & ~0x00000002); + clanName_ = getDefaultInstance().getClanName(); + onChanged(); + return this; + } + /** + * required string clanName = 2; + * @param value The bytes for clanName to set. + * @return This builder for chaining. + */ + public Builder setClanNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + clanName_ = value; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:management.LeaveClanRequest) + } + + // @@protoc_insertion_point(class_scope:management.LeaveClanRequest) + private static final proto.management.LeaveClanRequest DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new proto.management.LeaveClanRequest(); + } + + public static proto.management.LeaveClanRequest getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public LeaveClanRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new LeaveClanRequest(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public proto.management.LeaveClanRequest getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + +} + diff --git a/Server/src/main/proto/management/LeaveClanRequestOrBuilder.java b/Server/src/main/proto/management/LeaveClanRequestOrBuilder.java new file mode 100644 index 0000000..2a25695 --- /dev/null +++ b/Server/src/main/proto/management/LeaveClanRequestOrBuilder.java @@ -0,0 +1,43 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: Management.proto + +package proto.management; + +public interface LeaveClanRequestOrBuilder extends + // @@protoc_insertion_point(interface_extends:management.LeaveClanRequest) + com.google.protobuf.MessageOrBuilder { + + /** + * required string username = 1; + * @return Whether the username field is set. + */ + boolean hasUsername(); + /** + * required string username = 1; + * @return The username. + */ + java.lang.String getUsername(); + /** + * required string username = 1; + * @return The bytes for username. + */ + com.google.protobuf.ByteString + getUsernameBytes(); + + /** + * required string clanName = 2; + * @return Whether the clanName field is set. + */ + boolean hasClanName(); + /** + * required string clanName = 2; + * @return The clanName. + */ + java.lang.String getClanName(); + /** + * required string clanName = 2; + * @return The bytes for clanName. + */ + com.google.protobuf.ByteString + getClanNameBytes(); +} diff --git a/Server/src/main/proto/management/ManagementProtos.java b/Server/src/main/proto/management/ManagementProtos.java new file mode 100644 index 0000000..78a9004 --- /dev/null +++ b/Server/src/main/proto/management/ManagementProtos.java @@ -0,0 +1,234 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: Management.proto + +package proto.management; + +public final class ManagementProtos { + private ManagementProtos() {} + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistryLite registry) { + } + + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistry registry) { + registerAllExtensions( + (com.google.protobuf.ExtensionRegistryLite) registry); + } + static final com.google.protobuf.Descriptors.Descriptor + internal_static_management_PlayerStatusUpdate_descriptor; + static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_management_PlayerStatusUpdate_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_management_ClanMessage_descriptor; + static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_management_ClanMessage_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_management_PrivateMessage_descriptor; + static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_management_PrivateMessage_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_management_RequestContactInfo_descriptor; + static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_management_RequestContactInfo_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_management_SendContactInfo_descriptor; + static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_management_SendContactInfo_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_management_SendContactInfo_Contact_descriptor; + static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_management_SendContactInfo_Contact_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_management_FriendUpdate_descriptor; + static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_management_FriendUpdate_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_management_BlockedUpdate_descriptor; + static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_management_BlockedUpdate_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_management_RequestClanInfo_descriptor; + static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_management_RequestClanInfo_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_management_SendClanInfo_descriptor; + static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_management_SendClanInfo_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_management_SendClanInfo_ClanMember_descriptor; + static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_management_SendClanInfo_ClanMember_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_management_JoinClanRequest_descriptor; + static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_management_JoinClanRequest_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_management_LeaveClanRequest_descriptor; + static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_management_LeaveClanRequest_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_management_ClanJoinNotification_descriptor; + static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_management_ClanJoinNotification_fieldAccessorTable; + static final com.google.protobuf.Descriptors.Descriptor + internal_static_management_ClanLeaveNotification_descriptor; + static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_management_ClanLeaveNotification_fieldAccessorTable; + + public static com.google.protobuf.Descriptors.FileDescriptor + getDescriptor() { + return descriptor; + } + private static com.google.protobuf.Descriptors.FileDescriptor + descriptor; + static { + java.lang.String[] descriptorData = { + "\n\020Management.proto\022\nmanagement\"P\n\022Player" + + "StatusUpdate\022\020\n\010username\030\001 \002(\t\022\r\n\005world\030" + + "\002 \002(\005\022\031\n\021notifyFriendsOnly\030\003 \002(\010\"N\n\013Clan" + + "Message\022\016\n\006sender\030\001 \002(\t\022\020\n\010clanName\030\002 \002(" + + "\t\022\017\n\007message\030\003 \002(\t\022\014\n\004rank\030\004 \002(\005\"Q\n\016Priv" + + "ateMessage\022\016\n\006sender\030\001 \002(\t\022\020\n\010receiver\030\002" + + " \002(\t\022\017\n\007message\030\003 \002(\t\022\014\n\004rank\030\004 \002(\005\"5\n\022R" + + "equestContactInfo\022\020\n\010username\030\001 \002(\t\022\r\n\005w" + + "orld\030\002 \002(\005\"\245\001\n\017SendContactInfo\022\020\n\010userna" + + "me\030\001 \002(\t\0225\n\010contacts\030\002 \003(\0132#.management." + + "SendContactInfo.Contact\022\017\n\007blocked\030\003 \003(\t" + + "\0328\n\007Contact\022\020\n\010username\030\001 \002(\t\022\r\n\005world\030\002" + + " \001(\005\022\014\n\004rank\030\003 \001(\005\"z\n\014FriendUpdate\022+\n\004ty" + + "pe\030\001 \002(\0162\035.management.FriendUpdate.Type\022" + + "\020\n\010username\030\002 \002(\t\022\016\n\006friend\030\003 \002(\t\"\033\n\004Typ" + + "e\022\007\n\003ADD\020\000\022\n\n\006REMOVE\020\001\"|\n\rBlockedUpdate\022" + + ",\n\004type\030\001 \002(\0162\036.management.BlockedUpdate" + + ".Type\022\020\n\010username\030\002 \002(\t\022\016\n\006friend\030\003 \002(\t\"" + + "\033\n\004Type\022\007\n\003ADD\020\000\022\n\n\006REMOVE\020\001\"3\n\017RequestC" + + "lanInfo\022\r\n\005world\030\001 \002(\005\022\021\n\tclanOwner\030\002 \002(" + + "\t\"\236\002\n\014SendClanInfo\022\021\n\tclanOwner\030\001 \002(\t\022\017\n" + + "\007hasInfo\030\002 \002(\010\022\020\n\010clanName\030\003 \001(\t\022\027\n\017join" + + "Requirement\030\004 \001(\005\022\027\n\017kickRequirement\030\005 \001" + + "(\005\022\032\n\022messageRequirement\030\006 \001(\005\022\027\n\017lootRe" + + "quirement\030\007 \001(\005\0224\n\007members\030\010 \003(\0132#.manag" + + "ement.SendClanInfo.ClanMember\032;\n\nClanMem" + + "ber\022\020\n\010username\030\001 \002(\t\022\r\n\005world\030\002 \002(\005\022\014\n\004" + + "rank\030\003 \002(\005\"5\n\017JoinClanRequest\022\020\n\010usernam" + + "e\030\001 \002(\t\022\020\n\010clanName\030\002 \002(\t\"6\n\020LeaveClanRe" + + "quest\022\020\n\010username\030\001 \002(\t\022\020\n\010clanName\030\002 \002(" + + "\t\"I\n\024ClanJoinNotification\022\020\n\010username\030\001 " + + "\002(\t\022\020\n\010clanName\030\002 \002(\t\022\r\n\005world\030\003 \002(\005\"J\n\025" + + "ClanLeaveNotification\022\020\n\010username\030\001 \002(\t\022" + + "\020\n\010clanName\030\002 \002(\t\022\r\n\005world\030\003 \002(\005B&\n\020prot" + + "o.managementB\020ManagementProtosP\001" + }; + descriptor = com.google.protobuf.Descriptors.FileDescriptor + .internalBuildGeneratedFileFrom(descriptorData, + new com.google.protobuf.Descriptors.FileDescriptor[] { + }); + internal_static_management_PlayerStatusUpdate_descriptor = + getDescriptor().getMessageTypes().get(0); + internal_static_management_PlayerStatusUpdate_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_management_PlayerStatusUpdate_descriptor, + new java.lang.String[] { "Username", "World", "NotifyFriendsOnly", }); + internal_static_management_ClanMessage_descriptor = + getDescriptor().getMessageTypes().get(1); + internal_static_management_ClanMessage_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_management_ClanMessage_descriptor, + new java.lang.String[] { "Sender", "ClanName", "Message", "Rank", }); + internal_static_management_PrivateMessage_descriptor = + getDescriptor().getMessageTypes().get(2); + internal_static_management_PrivateMessage_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_management_PrivateMessage_descriptor, + new java.lang.String[] { "Sender", "Receiver", "Message", "Rank", }); + internal_static_management_RequestContactInfo_descriptor = + getDescriptor().getMessageTypes().get(3); + internal_static_management_RequestContactInfo_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_management_RequestContactInfo_descriptor, + new java.lang.String[] { "Username", "World", }); + internal_static_management_SendContactInfo_descriptor = + getDescriptor().getMessageTypes().get(4); + internal_static_management_SendContactInfo_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_management_SendContactInfo_descriptor, + new java.lang.String[] { "Username", "Contacts", "Blocked", }); + internal_static_management_SendContactInfo_Contact_descriptor = + internal_static_management_SendContactInfo_descriptor.getNestedTypes().get(0); + internal_static_management_SendContactInfo_Contact_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_management_SendContactInfo_Contact_descriptor, + new java.lang.String[] { "Username", "World", "Rank", }); + internal_static_management_FriendUpdate_descriptor = + getDescriptor().getMessageTypes().get(5); + internal_static_management_FriendUpdate_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_management_FriendUpdate_descriptor, + new java.lang.String[] { "Type", "Username", "Friend", }); + internal_static_management_BlockedUpdate_descriptor = + getDescriptor().getMessageTypes().get(6); + internal_static_management_BlockedUpdate_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_management_BlockedUpdate_descriptor, + new java.lang.String[] { "Type", "Username", "Friend", }); + internal_static_management_RequestClanInfo_descriptor = + getDescriptor().getMessageTypes().get(7); + internal_static_management_RequestClanInfo_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_management_RequestClanInfo_descriptor, + new java.lang.String[] { "World", "ClanOwner", }); + internal_static_management_SendClanInfo_descriptor = + getDescriptor().getMessageTypes().get(8); + internal_static_management_SendClanInfo_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_management_SendClanInfo_descriptor, + new java.lang.String[] { "ClanOwner", "HasInfo", "ClanName", "JoinRequirement", "KickRequirement", "MessageRequirement", "LootRequirement", "Members", }); + internal_static_management_SendClanInfo_ClanMember_descriptor = + internal_static_management_SendClanInfo_descriptor.getNestedTypes().get(0); + internal_static_management_SendClanInfo_ClanMember_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_management_SendClanInfo_ClanMember_descriptor, + new java.lang.String[] { "Username", "World", "Rank", }); + internal_static_management_JoinClanRequest_descriptor = + getDescriptor().getMessageTypes().get(9); + internal_static_management_JoinClanRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_management_JoinClanRequest_descriptor, + new java.lang.String[] { "Username", "ClanName", }); + internal_static_management_LeaveClanRequest_descriptor = + getDescriptor().getMessageTypes().get(10); + internal_static_management_LeaveClanRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_management_LeaveClanRequest_descriptor, + new java.lang.String[] { "Username", "ClanName", }); + internal_static_management_ClanJoinNotification_descriptor = + getDescriptor().getMessageTypes().get(11); + internal_static_management_ClanJoinNotification_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_management_ClanJoinNotification_descriptor, + new java.lang.String[] { "Username", "ClanName", "World", }); + internal_static_management_ClanLeaveNotification_descriptor = + getDescriptor().getMessageTypes().get(12); + internal_static_management_ClanLeaveNotification_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_management_ClanLeaveNotification_descriptor, + new java.lang.String[] { "Username", "ClanName", "World", }); + } + + // @@protoc_insertion_point(outer_class_scope) +} diff --git a/Server/src/main/proto/management/PlayerStatusUpdate.java b/Server/src/main/proto/management/PlayerStatusUpdate.java new file mode 100644 index 0000000..7ab0532 --- /dev/null +++ b/Server/src/main/proto/management/PlayerStatusUpdate.java @@ -0,0 +1,788 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: Management.proto + +package proto.management; + +/** + * Protobuf type {@code management.PlayerStatusUpdate} + */ +public final class PlayerStatusUpdate extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:management.PlayerStatusUpdate) + PlayerStatusUpdateOrBuilder { +private static final long serialVersionUID = 0L; + // Use PlayerStatusUpdate.newBuilder() to construct. + private PlayerStatusUpdate(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private PlayerStatusUpdate() { + username_ = ""; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new PlayerStatusUpdate(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private PlayerStatusUpdate( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + com.google.protobuf.ByteString bs = input.readBytes(); + bitField0_ |= 0x00000001; + username_ = bs; + break; + } + case 16: { + bitField0_ |= 0x00000002; + world_ = input.readInt32(); + break; + } + case 24: { + bitField0_ |= 0x00000004; + notifyFriendsOnly_ = input.readBool(); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return proto.management.ManagementProtos.internal_static_management_PlayerStatusUpdate_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return proto.management.ManagementProtos.internal_static_management_PlayerStatusUpdate_fieldAccessorTable + .ensureFieldAccessorsInitialized( + proto.management.PlayerStatusUpdate.class, proto.management.PlayerStatusUpdate.Builder.class); + } + + private int bitField0_; + public static final int USERNAME_FIELD_NUMBER = 1; + private volatile java.lang.Object username_; + /** + * required string username = 1; + * @return Whether the username field is set. + */ + @java.lang.Override + public boolean hasUsername() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required string username = 1; + * @return The username. + */ + @java.lang.Override + public java.lang.String getUsername() { + java.lang.Object ref = username_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + username_ = s; + } + return s; + } + } + /** + * required string username = 1; + * @return The bytes for username. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getUsernameBytes() { + java.lang.Object ref = username_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + username_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int WORLD_FIELD_NUMBER = 2; + private int world_; + /** + * required int32 world = 2; + * @return Whether the world field is set. + */ + @java.lang.Override + public boolean hasWorld() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required int32 world = 2; + * @return The world. + */ + @java.lang.Override + public int getWorld() { + return world_; + } + + public static final int NOTIFYFRIENDSONLY_FIELD_NUMBER = 3; + private boolean notifyFriendsOnly_; + /** + * required bool notifyFriendsOnly = 3; + * @return Whether the notifyFriendsOnly field is set. + */ + @java.lang.Override + public boolean hasNotifyFriendsOnly() { + return ((bitField0_ & 0x00000004) != 0); + } + /** + * required bool notifyFriendsOnly = 3; + * @return The notifyFriendsOnly. + */ + @java.lang.Override + public boolean getNotifyFriendsOnly() { + return notifyFriendsOnly_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (!hasUsername()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasWorld()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasNotifyFriendsOnly()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 1, username_); + } + if (((bitField0_ & 0x00000002) != 0)) { + output.writeInt32(2, world_); + } + if (((bitField0_ & 0x00000004) != 0)) { + output.writeBool(3, notifyFriendsOnly_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, username_); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeInt32Size(2, world_); + } + if (((bitField0_ & 0x00000004) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeBoolSize(3, notifyFriendsOnly_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof proto.management.PlayerStatusUpdate)) { + return super.equals(obj); + } + proto.management.PlayerStatusUpdate other = (proto.management.PlayerStatusUpdate) obj; + + if (hasUsername() != other.hasUsername()) return false; + if (hasUsername()) { + if (!getUsername() + .equals(other.getUsername())) return false; + } + if (hasWorld() != other.hasWorld()) return false; + if (hasWorld()) { + if (getWorld() + != other.getWorld()) return false; + } + if (hasNotifyFriendsOnly() != other.hasNotifyFriendsOnly()) return false; + if (hasNotifyFriendsOnly()) { + if (getNotifyFriendsOnly() + != other.getNotifyFriendsOnly()) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasUsername()) { + hash = (37 * hash) + USERNAME_FIELD_NUMBER; + hash = (53 * hash) + getUsername().hashCode(); + } + if (hasWorld()) { + hash = (37 * hash) + WORLD_FIELD_NUMBER; + hash = (53 * hash) + getWorld(); + } + if (hasNotifyFriendsOnly()) { + hash = (37 * hash) + NOTIFYFRIENDSONLY_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean( + getNotifyFriendsOnly()); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static proto.management.PlayerStatusUpdate parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.PlayerStatusUpdate parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.PlayerStatusUpdate parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.PlayerStatusUpdate parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.PlayerStatusUpdate parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.PlayerStatusUpdate parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.PlayerStatusUpdate parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static proto.management.PlayerStatusUpdate parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static proto.management.PlayerStatusUpdate parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static proto.management.PlayerStatusUpdate parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static proto.management.PlayerStatusUpdate parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static proto.management.PlayerStatusUpdate parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(proto.management.PlayerStatusUpdate prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code management.PlayerStatusUpdate} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:management.PlayerStatusUpdate) + proto.management.PlayerStatusUpdateOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return proto.management.ManagementProtos.internal_static_management_PlayerStatusUpdate_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return proto.management.ManagementProtos.internal_static_management_PlayerStatusUpdate_fieldAccessorTable + .ensureFieldAccessorsInitialized( + proto.management.PlayerStatusUpdate.class, proto.management.PlayerStatusUpdate.Builder.class); + } + + // Construct using proto.management.PlayerStatusUpdate.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + username_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + world_ = 0; + bitField0_ = (bitField0_ & ~0x00000002); + notifyFriendsOnly_ = false; + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return proto.management.ManagementProtos.internal_static_management_PlayerStatusUpdate_descriptor; + } + + @java.lang.Override + public proto.management.PlayerStatusUpdate getDefaultInstanceForType() { + return proto.management.PlayerStatusUpdate.getDefaultInstance(); + } + + @java.lang.Override + public proto.management.PlayerStatusUpdate build() { + proto.management.PlayerStatusUpdate result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public proto.management.PlayerStatusUpdate buildPartial() { + proto.management.PlayerStatusUpdate result = new proto.management.PlayerStatusUpdate(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + to_bitField0_ |= 0x00000001; + } + result.username_ = username_; + if (((from_bitField0_ & 0x00000002) != 0)) { + result.world_ = world_; + to_bitField0_ |= 0x00000002; + } + if (((from_bitField0_ & 0x00000004) != 0)) { + result.notifyFriendsOnly_ = notifyFriendsOnly_; + to_bitField0_ |= 0x00000004; + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof proto.management.PlayerStatusUpdate) { + return mergeFrom((proto.management.PlayerStatusUpdate)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(proto.management.PlayerStatusUpdate other) { + if (other == proto.management.PlayerStatusUpdate.getDefaultInstance()) return this; + if (other.hasUsername()) { + bitField0_ |= 0x00000001; + username_ = other.username_; + onChanged(); + } + if (other.hasWorld()) { + setWorld(other.getWorld()); + } + if (other.hasNotifyFriendsOnly()) { + setNotifyFriendsOnly(other.getNotifyFriendsOnly()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (!hasUsername()) { + return false; + } + if (!hasWorld()) { + return false; + } + if (!hasNotifyFriendsOnly()) { + return false; + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + proto.management.PlayerStatusUpdate parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (proto.management.PlayerStatusUpdate) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private java.lang.Object username_ = ""; + /** + * required string username = 1; + * @return Whether the username field is set. + */ + public boolean hasUsername() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required string username = 1; + * @return The username. + */ + public java.lang.String getUsername() { + java.lang.Object ref = username_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + username_ = s; + } + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string username = 1; + * @return The bytes for username. + */ + public com.google.protobuf.ByteString + getUsernameBytes() { + java.lang.Object ref = username_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + username_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string username = 1; + * @param value The username to set. + * @return This builder for chaining. + */ + public Builder setUsername( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + username_ = value; + onChanged(); + return this; + } + /** + * required string username = 1; + * @return This builder for chaining. + */ + public Builder clearUsername() { + bitField0_ = (bitField0_ & ~0x00000001); + username_ = getDefaultInstance().getUsername(); + onChanged(); + return this; + } + /** + * required string username = 1; + * @param value The bytes for username to set. + * @return This builder for chaining. + */ + public Builder setUsernameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + username_ = value; + onChanged(); + return this; + } + + private int world_ ; + /** + * required int32 world = 2; + * @return Whether the world field is set. + */ + @java.lang.Override + public boolean hasWorld() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required int32 world = 2; + * @return The world. + */ + @java.lang.Override + public int getWorld() { + return world_; + } + /** + * required int32 world = 2; + * @param value The world to set. + * @return This builder for chaining. + */ + public Builder setWorld(int value) { + bitField0_ |= 0x00000002; + world_ = value; + onChanged(); + return this; + } + /** + * required int32 world = 2; + * @return This builder for chaining. + */ + public Builder clearWorld() { + bitField0_ = (bitField0_ & ~0x00000002); + world_ = 0; + onChanged(); + return this; + } + + private boolean notifyFriendsOnly_ ; + /** + * required bool notifyFriendsOnly = 3; + * @return Whether the notifyFriendsOnly field is set. + */ + @java.lang.Override + public boolean hasNotifyFriendsOnly() { + return ((bitField0_ & 0x00000004) != 0); + } + /** + * required bool notifyFriendsOnly = 3; + * @return The notifyFriendsOnly. + */ + @java.lang.Override + public boolean getNotifyFriendsOnly() { + return notifyFriendsOnly_; + } + /** + * required bool notifyFriendsOnly = 3; + * @param value The notifyFriendsOnly to set. + * @return This builder for chaining. + */ + public Builder setNotifyFriendsOnly(boolean value) { + bitField0_ |= 0x00000004; + notifyFriendsOnly_ = value; + onChanged(); + return this; + } + /** + * required bool notifyFriendsOnly = 3; + * @return This builder for chaining. + */ + public Builder clearNotifyFriendsOnly() { + bitField0_ = (bitField0_ & ~0x00000004); + notifyFriendsOnly_ = false; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:management.PlayerStatusUpdate) + } + + // @@protoc_insertion_point(class_scope:management.PlayerStatusUpdate) + private static final proto.management.PlayerStatusUpdate DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new proto.management.PlayerStatusUpdate(); + } + + public static proto.management.PlayerStatusUpdate getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public PlayerStatusUpdate parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new PlayerStatusUpdate(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public proto.management.PlayerStatusUpdate getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + +} + diff --git a/Server/src/main/proto/management/PlayerStatusUpdateOrBuilder.java b/Server/src/main/proto/management/PlayerStatusUpdateOrBuilder.java new file mode 100644 index 0000000..e43cd38 --- /dev/null +++ b/Server/src/main/proto/management/PlayerStatusUpdateOrBuilder.java @@ -0,0 +1,48 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: Management.proto + +package proto.management; + +public interface PlayerStatusUpdateOrBuilder extends + // @@protoc_insertion_point(interface_extends:management.PlayerStatusUpdate) + com.google.protobuf.MessageOrBuilder { + + /** + * required string username = 1; + * @return Whether the username field is set. + */ + boolean hasUsername(); + /** + * required string username = 1; + * @return The username. + */ + java.lang.String getUsername(); + /** + * required string username = 1; + * @return The bytes for username. + */ + com.google.protobuf.ByteString + getUsernameBytes(); + + /** + * required int32 world = 2; + * @return Whether the world field is set. + */ + boolean hasWorld(); + /** + * required int32 world = 2; + * @return The world. + */ + int getWorld(); + + /** + * required bool notifyFriendsOnly = 3; + * @return Whether the notifyFriendsOnly field is set. + */ + boolean hasNotifyFriendsOnly(); + /** + * required bool notifyFriendsOnly = 3; + * @return The notifyFriendsOnly. + */ + boolean getNotifyFriendsOnly(); +} diff --git a/Server/src/main/proto/management/PrivateMessage.java b/Server/src/main/proto/management/PrivateMessage.java new file mode 100644 index 0000000..e86cea5 --- /dev/null +++ b/Server/src/main/proto/management/PrivateMessage.java @@ -0,0 +1,1036 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: Management.proto + +package proto.management; + +/** + * Protobuf type {@code management.PrivateMessage} + */ +public final class PrivateMessage extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:management.PrivateMessage) + PrivateMessageOrBuilder { +private static final long serialVersionUID = 0L; + // Use PrivateMessage.newBuilder() to construct. + private PrivateMessage(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private PrivateMessage() { + sender_ = ""; + receiver_ = ""; + message_ = ""; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new PrivateMessage(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private PrivateMessage( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + com.google.protobuf.ByteString bs = input.readBytes(); + bitField0_ |= 0x00000001; + sender_ = bs; + break; + } + case 18: { + com.google.protobuf.ByteString bs = input.readBytes(); + bitField0_ |= 0x00000002; + receiver_ = bs; + break; + } + case 26: { + com.google.protobuf.ByteString bs = input.readBytes(); + bitField0_ |= 0x00000004; + message_ = bs; + break; + } + case 32: { + bitField0_ |= 0x00000008; + rank_ = input.readInt32(); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return proto.management.ManagementProtos.internal_static_management_PrivateMessage_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return proto.management.ManagementProtos.internal_static_management_PrivateMessage_fieldAccessorTable + .ensureFieldAccessorsInitialized( + proto.management.PrivateMessage.class, proto.management.PrivateMessage.Builder.class); + } + + private int bitField0_; + public static final int SENDER_FIELD_NUMBER = 1; + private volatile java.lang.Object sender_; + /** + * required string sender = 1; + * @return Whether the sender field is set. + */ + @java.lang.Override + public boolean hasSender() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required string sender = 1; + * @return The sender. + */ + @java.lang.Override + public java.lang.String getSender() { + java.lang.Object ref = sender_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + sender_ = s; + } + return s; + } + } + /** + * required string sender = 1; + * @return The bytes for sender. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getSenderBytes() { + java.lang.Object ref = sender_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + sender_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int RECEIVER_FIELD_NUMBER = 2; + private volatile java.lang.Object receiver_; + /** + * required string receiver = 2; + * @return Whether the receiver field is set. + */ + @java.lang.Override + public boolean hasReceiver() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required string receiver = 2; + * @return The receiver. + */ + @java.lang.Override + public java.lang.String getReceiver() { + java.lang.Object ref = receiver_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + receiver_ = s; + } + return s; + } + } + /** + * required string receiver = 2; + * @return The bytes for receiver. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getReceiverBytes() { + java.lang.Object ref = receiver_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + receiver_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int MESSAGE_FIELD_NUMBER = 3; + private volatile java.lang.Object message_; + /** + * required string message = 3; + * @return Whether the message field is set. + */ + @java.lang.Override + public boolean hasMessage() { + return ((bitField0_ & 0x00000004) != 0); + } + /** + * required string message = 3; + * @return The message. + */ + @java.lang.Override + public java.lang.String getMessage() { + java.lang.Object ref = message_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + message_ = s; + } + return s; + } + } + /** + * required string message = 3; + * @return The bytes for message. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getMessageBytes() { + java.lang.Object ref = message_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + message_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int RANK_FIELD_NUMBER = 4; + private int rank_; + /** + * required int32 rank = 4; + * @return Whether the rank field is set. + */ + @java.lang.Override + public boolean hasRank() { + return ((bitField0_ & 0x00000008) != 0); + } + /** + * required int32 rank = 4; + * @return The rank. + */ + @java.lang.Override + public int getRank() { + return rank_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (!hasSender()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasReceiver()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasMessage()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasRank()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 1, sender_); + } + if (((bitField0_ & 0x00000002) != 0)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 2, receiver_); + } + if (((bitField0_ & 0x00000004) != 0)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 3, message_); + } + if (((bitField0_ & 0x00000008) != 0)) { + output.writeInt32(4, rank_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, sender_); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, receiver_); + } + if (((bitField0_ & 0x00000004) != 0)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, message_); + } + if (((bitField0_ & 0x00000008) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeInt32Size(4, rank_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof proto.management.PrivateMessage)) { + return super.equals(obj); + } + proto.management.PrivateMessage other = (proto.management.PrivateMessage) obj; + + if (hasSender() != other.hasSender()) return false; + if (hasSender()) { + if (!getSender() + .equals(other.getSender())) return false; + } + if (hasReceiver() != other.hasReceiver()) return false; + if (hasReceiver()) { + if (!getReceiver() + .equals(other.getReceiver())) return false; + } + if (hasMessage() != other.hasMessage()) return false; + if (hasMessage()) { + if (!getMessage() + .equals(other.getMessage())) return false; + } + if (hasRank() != other.hasRank()) return false; + if (hasRank()) { + if (getRank() + != other.getRank()) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasSender()) { + hash = (37 * hash) + SENDER_FIELD_NUMBER; + hash = (53 * hash) + getSender().hashCode(); + } + if (hasReceiver()) { + hash = (37 * hash) + RECEIVER_FIELD_NUMBER; + hash = (53 * hash) + getReceiver().hashCode(); + } + if (hasMessage()) { + hash = (37 * hash) + MESSAGE_FIELD_NUMBER; + hash = (53 * hash) + getMessage().hashCode(); + } + if (hasRank()) { + hash = (37 * hash) + RANK_FIELD_NUMBER; + hash = (53 * hash) + getRank(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static proto.management.PrivateMessage parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.PrivateMessage parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.PrivateMessage parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.PrivateMessage parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.PrivateMessage parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.PrivateMessage parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.PrivateMessage parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static proto.management.PrivateMessage parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static proto.management.PrivateMessage parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static proto.management.PrivateMessage parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static proto.management.PrivateMessage parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static proto.management.PrivateMessage parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(proto.management.PrivateMessage prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code management.PrivateMessage} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:management.PrivateMessage) + proto.management.PrivateMessageOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return proto.management.ManagementProtos.internal_static_management_PrivateMessage_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return proto.management.ManagementProtos.internal_static_management_PrivateMessage_fieldAccessorTable + .ensureFieldAccessorsInitialized( + proto.management.PrivateMessage.class, proto.management.PrivateMessage.Builder.class); + } + + // Construct using proto.management.PrivateMessage.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + sender_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + receiver_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + message_ = ""; + bitField0_ = (bitField0_ & ~0x00000004); + rank_ = 0; + bitField0_ = (bitField0_ & ~0x00000008); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return proto.management.ManagementProtos.internal_static_management_PrivateMessage_descriptor; + } + + @java.lang.Override + public proto.management.PrivateMessage getDefaultInstanceForType() { + return proto.management.PrivateMessage.getDefaultInstance(); + } + + @java.lang.Override + public proto.management.PrivateMessage build() { + proto.management.PrivateMessage result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public proto.management.PrivateMessage buildPartial() { + proto.management.PrivateMessage result = new proto.management.PrivateMessage(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + to_bitField0_ |= 0x00000001; + } + result.sender_ = sender_; + if (((from_bitField0_ & 0x00000002) != 0)) { + to_bitField0_ |= 0x00000002; + } + result.receiver_ = receiver_; + if (((from_bitField0_ & 0x00000004) != 0)) { + to_bitField0_ |= 0x00000004; + } + result.message_ = message_; + if (((from_bitField0_ & 0x00000008) != 0)) { + result.rank_ = rank_; + to_bitField0_ |= 0x00000008; + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof proto.management.PrivateMessage) { + return mergeFrom((proto.management.PrivateMessage)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(proto.management.PrivateMessage other) { + if (other == proto.management.PrivateMessage.getDefaultInstance()) return this; + if (other.hasSender()) { + bitField0_ |= 0x00000001; + sender_ = other.sender_; + onChanged(); + } + if (other.hasReceiver()) { + bitField0_ |= 0x00000002; + receiver_ = other.receiver_; + onChanged(); + } + if (other.hasMessage()) { + bitField0_ |= 0x00000004; + message_ = other.message_; + onChanged(); + } + if (other.hasRank()) { + setRank(other.getRank()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (!hasSender()) { + return false; + } + if (!hasReceiver()) { + return false; + } + if (!hasMessage()) { + return false; + } + if (!hasRank()) { + return false; + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + proto.management.PrivateMessage parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (proto.management.PrivateMessage) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private java.lang.Object sender_ = ""; + /** + * required string sender = 1; + * @return Whether the sender field is set. + */ + public boolean hasSender() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required string sender = 1; + * @return The sender. + */ + public java.lang.String getSender() { + java.lang.Object ref = sender_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + sender_ = s; + } + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string sender = 1; + * @return The bytes for sender. + */ + public com.google.protobuf.ByteString + getSenderBytes() { + java.lang.Object ref = sender_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + sender_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string sender = 1; + * @param value The sender to set. + * @return This builder for chaining. + */ + public Builder setSender( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + sender_ = value; + onChanged(); + return this; + } + /** + * required string sender = 1; + * @return This builder for chaining. + */ + public Builder clearSender() { + bitField0_ = (bitField0_ & ~0x00000001); + sender_ = getDefaultInstance().getSender(); + onChanged(); + return this; + } + /** + * required string sender = 1; + * @param value The bytes for sender to set. + * @return This builder for chaining. + */ + public Builder setSenderBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + sender_ = value; + onChanged(); + return this; + } + + private java.lang.Object receiver_ = ""; + /** + * required string receiver = 2; + * @return Whether the receiver field is set. + */ + public boolean hasReceiver() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required string receiver = 2; + * @return The receiver. + */ + public java.lang.String getReceiver() { + java.lang.Object ref = receiver_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + receiver_ = s; + } + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string receiver = 2; + * @return The bytes for receiver. + */ + public com.google.protobuf.ByteString + getReceiverBytes() { + java.lang.Object ref = receiver_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + receiver_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string receiver = 2; + * @param value The receiver to set. + * @return This builder for chaining. + */ + public Builder setReceiver( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + receiver_ = value; + onChanged(); + return this; + } + /** + * required string receiver = 2; + * @return This builder for chaining. + */ + public Builder clearReceiver() { + bitField0_ = (bitField0_ & ~0x00000002); + receiver_ = getDefaultInstance().getReceiver(); + onChanged(); + return this; + } + /** + * required string receiver = 2; + * @param value The bytes for receiver to set. + * @return This builder for chaining. + */ + public Builder setReceiverBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + receiver_ = value; + onChanged(); + return this; + } + + private java.lang.Object message_ = ""; + /** + * required string message = 3; + * @return Whether the message field is set. + */ + public boolean hasMessage() { + return ((bitField0_ & 0x00000004) != 0); + } + /** + * required string message = 3; + * @return The message. + */ + public java.lang.String getMessage() { + java.lang.Object ref = message_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + message_ = s; + } + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string message = 3; + * @return The bytes for message. + */ + public com.google.protobuf.ByteString + getMessageBytes() { + java.lang.Object ref = message_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + message_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string message = 3; + * @param value The message to set. + * @return This builder for chaining. + */ + public Builder setMessage( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + message_ = value; + onChanged(); + return this; + } + /** + * required string message = 3; + * @return This builder for chaining. + */ + public Builder clearMessage() { + bitField0_ = (bitField0_ & ~0x00000004); + message_ = getDefaultInstance().getMessage(); + onChanged(); + return this; + } + /** + * required string message = 3; + * @param value The bytes for message to set. + * @return This builder for chaining. + */ + public Builder setMessageBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + message_ = value; + onChanged(); + return this; + } + + private int rank_ ; + /** + * required int32 rank = 4; + * @return Whether the rank field is set. + */ + @java.lang.Override + public boolean hasRank() { + return ((bitField0_ & 0x00000008) != 0); + } + /** + * required int32 rank = 4; + * @return The rank. + */ + @java.lang.Override + public int getRank() { + return rank_; + } + /** + * required int32 rank = 4; + * @param value The rank to set. + * @return This builder for chaining. + */ + public Builder setRank(int value) { + bitField0_ |= 0x00000008; + rank_ = value; + onChanged(); + return this; + } + /** + * required int32 rank = 4; + * @return This builder for chaining. + */ + public Builder clearRank() { + bitField0_ = (bitField0_ & ~0x00000008); + rank_ = 0; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:management.PrivateMessage) + } + + // @@protoc_insertion_point(class_scope:management.PrivateMessage) + private static final proto.management.PrivateMessage DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new proto.management.PrivateMessage(); + } + + public static proto.management.PrivateMessage getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public PrivateMessage parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new PrivateMessage(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public proto.management.PrivateMessage getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + +} + diff --git a/Server/src/main/proto/management/PrivateMessageOrBuilder.java b/Server/src/main/proto/management/PrivateMessageOrBuilder.java new file mode 100644 index 0000000..071557f --- /dev/null +++ b/Server/src/main/proto/management/PrivateMessageOrBuilder.java @@ -0,0 +1,71 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: Management.proto + +package proto.management; + +public interface PrivateMessageOrBuilder extends + // @@protoc_insertion_point(interface_extends:management.PrivateMessage) + com.google.protobuf.MessageOrBuilder { + + /** + * required string sender = 1; + * @return Whether the sender field is set. + */ + boolean hasSender(); + /** + * required string sender = 1; + * @return The sender. + */ + java.lang.String getSender(); + /** + * required string sender = 1; + * @return The bytes for sender. + */ + com.google.protobuf.ByteString + getSenderBytes(); + + /** + * required string receiver = 2; + * @return Whether the receiver field is set. + */ + boolean hasReceiver(); + /** + * required string receiver = 2; + * @return The receiver. + */ + java.lang.String getReceiver(); + /** + * required string receiver = 2; + * @return The bytes for receiver. + */ + com.google.protobuf.ByteString + getReceiverBytes(); + + /** + * required string message = 3; + * @return Whether the message field is set. + */ + boolean hasMessage(); + /** + * required string message = 3; + * @return The message. + */ + java.lang.String getMessage(); + /** + * required string message = 3; + * @return The bytes for message. + */ + com.google.protobuf.ByteString + getMessageBytes(); + + /** + * required int32 rank = 4; + * @return Whether the rank field is set. + */ + boolean hasRank(); + /** + * required int32 rank = 4; + * @return The rank. + */ + int getRank(); +} diff --git a/Server/src/main/proto/management/RequestClanInfo.java b/Server/src/main/proto/management/RequestClanInfo.java new file mode 100644 index 0000000..761bcf4 --- /dev/null +++ b/Server/src/main/proto/management/RequestClanInfo.java @@ -0,0 +1,692 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: Management.proto + +package proto.management; + +/** + * Protobuf type {@code management.RequestClanInfo} + */ +public final class RequestClanInfo extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:management.RequestClanInfo) + RequestClanInfoOrBuilder { +private static final long serialVersionUID = 0L; + // Use RequestClanInfo.newBuilder() to construct. + private RequestClanInfo(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private RequestClanInfo() { + clanOwner_ = ""; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new RequestClanInfo(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private RequestClanInfo( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 8: { + bitField0_ |= 0x00000001; + world_ = input.readInt32(); + break; + } + case 18: { + com.google.protobuf.ByteString bs = input.readBytes(); + bitField0_ |= 0x00000002; + clanOwner_ = bs; + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return proto.management.ManagementProtos.internal_static_management_RequestClanInfo_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return proto.management.ManagementProtos.internal_static_management_RequestClanInfo_fieldAccessorTable + .ensureFieldAccessorsInitialized( + proto.management.RequestClanInfo.class, proto.management.RequestClanInfo.Builder.class); + } + + private int bitField0_; + public static final int WORLD_FIELD_NUMBER = 1; + private int world_; + /** + * required int32 world = 1; + * @return Whether the world field is set. + */ + @java.lang.Override + public boolean hasWorld() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required int32 world = 1; + * @return The world. + */ + @java.lang.Override + public int getWorld() { + return world_; + } + + public static final int CLANOWNER_FIELD_NUMBER = 2; + private volatile java.lang.Object clanOwner_; + /** + * required string clanOwner = 2; + * @return Whether the clanOwner field is set. + */ + @java.lang.Override + public boolean hasClanOwner() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required string clanOwner = 2; + * @return The clanOwner. + */ + @java.lang.Override + public java.lang.String getClanOwner() { + java.lang.Object ref = clanOwner_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + clanOwner_ = s; + } + return s; + } + } + /** + * required string clanOwner = 2; + * @return The bytes for clanOwner. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getClanOwnerBytes() { + java.lang.Object ref = clanOwner_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + clanOwner_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (!hasWorld()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasClanOwner()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + output.writeInt32(1, world_); + } + if (((bitField0_ & 0x00000002) != 0)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 2, clanOwner_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeInt32Size(1, world_); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, clanOwner_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof proto.management.RequestClanInfo)) { + return super.equals(obj); + } + proto.management.RequestClanInfo other = (proto.management.RequestClanInfo) obj; + + if (hasWorld() != other.hasWorld()) return false; + if (hasWorld()) { + if (getWorld() + != other.getWorld()) return false; + } + if (hasClanOwner() != other.hasClanOwner()) return false; + if (hasClanOwner()) { + if (!getClanOwner() + .equals(other.getClanOwner())) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasWorld()) { + hash = (37 * hash) + WORLD_FIELD_NUMBER; + hash = (53 * hash) + getWorld(); + } + if (hasClanOwner()) { + hash = (37 * hash) + CLANOWNER_FIELD_NUMBER; + hash = (53 * hash) + getClanOwner().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static proto.management.RequestClanInfo parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.RequestClanInfo parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.RequestClanInfo parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.RequestClanInfo parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.RequestClanInfo parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.RequestClanInfo parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.RequestClanInfo parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static proto.management.RequestClanInfo parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static proto.management.RequestClanInfo parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static proto.management.RequestClanInfo parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static proto.management.RequestClanInfo parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static proto.management.RequestClanInfo parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(proto.management.RequestClanInfo prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code management.RequestClanInfo} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:management.RequestClanInfo) + proto.management.RequestClanInfoOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return proto.management.ManagementProtos.internal_static_management_RequestClanInfo_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return proto.management.ManagementProtos.internal_static_management_RequestClanInfo_fieldAccessorTable + .ensureFieldAccessorsInitialized( + proto.management.RequestClanInfo.class, proto.management.RequestClanInfo.Builder.class); + } + + // Construct using proto.management.RequestClanInfo.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + world_ = 0; + bitField0_ = (bitField0_ & ~0x00000001); + clanOwner_ = ""; + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return proto.management.ManagementProtos.internal_static_management_RequestClanInfo_descriptor; + } + + @java.lang.Override + public proto.management.RequestClanInfo getDefaultInstanceForType() { + return proto.management.RequestClanInfo.getDefaultInstance(); + } + + @java.lang.Override + public proto.management.RequestClanInfo build() { + proto.management.RequestClanInfo result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public proto.management.RequestClanInfo buildPartial() { + proto.management.RequestClanInfo result = new proto.management.RequestClanInfo(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + result.world_ = world_; + to_bitField0_ |= 0x00000001; + } + if (((from_bitField0_ & 0x00000002) != 0)) { + to_bitField0_ |= 0x00000002; + } + result.clanOwner_ = clanOwner_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof proto.management.RequestClanInfo) { + return mergeFrom((proto.management.RequestClanInfo)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(proto.management.RequestClanInfo other) { + if (other == proto.management.RequestClanInfo.getDefaultInstance()) return this; + if (other.hasWorld()) { + setWorld(other.getWorld()); + } + if (other.hasClanOwner()) { + bitField0_ |= 0x00000002; + clanOwner_ = other.clanOwner_; + onChanged(); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (!hasWorld()) { + return false; + } + if (!hasClanOwner()) { + return false; + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + proto.management.RequestClanInfo parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (proto.management.RequestClanInfo) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private int world_ ; + /** + * required int32 world = 1; + * @return Whether the world field is set. + */ + @java.lang.Override + public boolean hasWorld() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required int32 world = 1; + * @return The world. + */ + @java.lang.Override + public int getWorld() { + return world_; + } + /** + * required int32 world = 1; + * @param value The world to set. + * @return This builder for chaining. + */ + public Builder setWorld(int value) { + bitField0_ |= 0x00000001; + world_ = value; + onChanged(); + return this; + } + /** + * required int32 world = 1; + * @return This builder for chaining. + */ + public Builder clearWorld() { + bitField0_ = (bitField0_ & ~0x00000001); + world_ = 0; + onChanged(); + return this; + } + + private java.lang.Object clanOwner_ = ""; + /** + * required string clanOwner = 2; + * @return Whether the clanOwner field is set. + */ + public boolean hasClanOwner() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required string clanOwner = 2; + * @return The clanOwner. + */ + public java.lang.String getClanOwner() { + java.lang.Object ref = clanOwner_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + clanOwner_ = s; + } + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string clanOwner = 2; + * @return The bytes for clanOwner. + */ + public com.google.protobuf.ByteString + getClanOwnerBytes() { + java.lang.Object ref = clanOwner_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + clanOwner_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string clanOwner = 2; + * @param value The clanOwner to set. + * @return This builder for chaining. + */ + public Builder setClanOwner( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + clanOwner_ = value; + onChanged(); + return this; + } + /** + * required string clanOwner = 2; + * @return This builder for chaining. + */ + public Builder clearClanOwner() { + bitField0_ = (bitField0_ & ~0x00000002); + clanOwner_ = getDefaultInstance().getClanOwner(); + onChanged(); + return this; + } + /** + * required string clanOwner = 2; + * @param value The bytes for clanOwner to set. + * @return This builder for chaining. + */ + public Builder setClanOwnerBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + clanOwner_ = value; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:management.RequestClanInfo) + } + + // @@protoc_insertion_point(class_scope:management.RequestClanInfo) + private static final proto.management.RequestClanInfo DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new proto.management.RequestClanInfo(); + } + + public static proto.management.RequestClanInfo getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public RequestClanInfo parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new RequestClanInfo(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public proto.management.RequestClanInfo getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + +} + diff --git a/Server/src/main/proto/management/RequestClanInfoOrBuilder.java b/Server/src/main/proto/management/RequestClanInfoOrBuilder.java new file mode 100644 index 0000000..ae0b9bd --- /dev/null +++ b/Server/src/main/proto/management/RequestClanInfoOrBuilder.java @@ -0,0 +1,37 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: Management.proto + +package proto.management; + +public interface RequestClanInfoOrBuilder extends + // @@protoc_insertion_point(interface_extends:management.RequestClanInfo) + com.google.protobuf.MessageOrBuilder { + + /** + * required int32 world = 1; + * @return Whether the world field is set. + */ + boolean hasWorld(); + /** + * required int32 world = 1; + * @return The world. + */ + int getWorld(); + + /** + * required string clanOwner = 2; + * @return Whether the clanOwner field is set. + */ + boolean hasClanOwner(); + /** + * required string clanOwner = 2; + * @return The clanOwner. + */ + java.lang.String getClanOwner(); + /** + * required string clanOwner = 2; + * @return The bytes for clanOwner. + */ + com.google.protobuf.ByteString + getClanOwnerBytes(); +} diff --git a/Server/src/main/proto/management/RequestContactInfo.java b/Server/src/main/proto/management/RequestContactInfo.java new file mode 100644 index 0000000..b7eb7c2 --- /dev/null +++ b/Server/src/main/proto/management/RequestContactInfo.java @@ -0,0 +1,692 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: Management.proto + +package proto.management; + +/** + * Protobuf type {@code management.RequestContactInfo} + */ +public final class RequestContactInfo extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:management.RequestContactInfo) + RequestContactInfoOrBuilder { +private static final long serialVersionUID = 0L; + // Use RequestContactInfo.newBuilder() to construct. + private RequestContactInfo(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private RequestContactInfo() { + username_ = ""; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new RequestContactInfo(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private RequestContactInfo( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + com.google.protobuf.ByteString bs = input.readBytes(); + bitField0_ |= 0x00000001; + username_ = bs; + break; + } + case 16: { + bitField0_ |= 0x00000002; + world_ = input.readInt32(); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return proto.management.ManagementProtos.internal_static_management_RequestContactInfo_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return proto.management.ManagementProtos.internal_static_management_RequestContactInfo_fieldAccessorTable + .ensureFieldAccessorsInitialized( + proto.management.RequestContactInfo.class, proto.management.RequestContactInfo.Builder.class); + } + + private int bitField0_; + public static final int USERNAME_FIELD_NUMBER = 1; + private volatile java.lang.Object username_; + /** + * required string username = 1; + * @return Whether the username field is set. + */ + @java.lang.Override + public boolean hasUsername() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required string username = 1; + * @return The username. + */ + @java.lang.Override + public java.lang.String getUsername() { + java.lang.Object ref = username_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + username_ = s; + } + return s; + } + } + /** + * required string username = 1; + * @return The bytes for username. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getUsernameBytes() { + java.lang.Object ref = username_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + username_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int WORLD_FIELD_NUMBER = 2; + private int world_; + /** + * required int32 world = 2; + * @return Whether the world field is set. + */ + @java.lang.Override + public boolean hasWorld() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required int32 world = 2; + * @return The world. + */ + @java.lang.Override + public int getWorld() { + return world_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (!hasUsername()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasWorld()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 1, username_); + } + if (((bitField0_ & 0x00000002) != 0)) { + output.writeInt32(2, world_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, username_); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeInt32Size(2, world_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof proto.management.RequestContactInfo)) { + return super.equals(obj); + } + proto.management.RequestContactInfo other = (proto.management.RequestContactInfo) obj; + + if (hasUsername() != other.hasUsername()) return false; + if (hasUsername()) { + if (!getUsername() + .equals(other.getUsername())) return false; + } + if (hasWorld() != other.hasWorld()) return false; + if (hasWorld()) { + if (getWorld() + != other.getWorld()) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasUsername()) { + hash = (37 * hash) + USERNAME_FIELD_NUMBER; + hash = (53 * hash) + getUsername().hashCode(); + } + if (hasWorld()) { + hash = (37 * hash) + WORLD_FIELD_NUMBER; + hash = (53 * hash) + getWorld(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static proto.management.RequestContactInfo parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.RequestContactInfo parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.RequestContactInfo parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.RequestContactInfo parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.RequestContactInfo parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.RequestContactInfo parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.RequestContactInfo parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static proto.management.RequestContactInfo parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static proto.management.RequestContactInfo parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static proto.management.RequestContactInfo parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static proto.management.RequestContactInfo parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static proto.management.RequestContactInfo parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(proto.management.RequestContactInfo prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code management.RequestContactInfo} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:management.RequestContactInfo) + proto.management.RequestContactInfoOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return proto.management.ManagementProtos.internal_static_management_RequestContactInfo_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return proto.management.ManagementProtos.internal_static_management_RequestContactInfo_fieldAccessorTable + .ensureFieldAccessorsInitialized( + proto.management.RequestContactInfo.class, proto.management.RequestContactInfo.Builder.class); + } + + // Construct using proto.management.RequestContactInfo.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + username_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + world_ = 0; + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return proto.management.ManagementProtos.internal_static_management_RequestContactInfo_descriptor; + } + + @java.lang.Override + public proto.management.RequestContactInfo getDefaultInstanceForType() { + return proto.management.RequestContactInfo.getDefaultInstance(); + } + + @java.lang.Override + public proto.management.RequestContactInfo build() { + proto.management.RequestContactInfo result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public proto.management.RequestContactInfo buildPartial() { + proto.management.RequestContactInfo result = new proto.management.RequestContactInfo(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + to_bitField0_ |= 0x00000001; + } + result.username_ = username_; + if (((from_bitField0_ & 0x00000002) != 0)) { + result.world_ = world_; + to_bitField0_ |= 0x00000002; + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof proto.management.RequestContactInfo) { + return mergeFrom((proto.management.RequestContactInfo)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(proto.management.RequestContactInfo other) { + if (other == proto.management.RequestContactInfo.getDefaultInstance()) return this; + if (other.hasUsername()) { + bitField0_ |= 0x00000001; + username_ = other.username_; + onChanged(); + } + if (other.hasWorld()) { + setWorld(other.getWorld()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (!hasUsername()) { + return false; + } + if (!hasWorld()) { + return false; + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + proto.management.RequestContactInfo parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (proto.management.RequestContactInfo) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private java.lang.Object username_ = ""; + /** + * required string username = 1; + * @return Whether the username field is set. + */ + public boolean hasUsername() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required string username = 1; + * @return The username. + */ + public java.lang.String getUsername() { + java.lang.Object ref = username_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + username_ = s; + } + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string username = 1; + * @return The bytes for username. + */ + public com.google.protobuf.ByteString + getUsernameBytes() { + java.lang.Object ref = username_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + username_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string username = 1; + * @param value The username to set. + * @return This builder for chaining. + */ + public Builder setUsername( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + username_ = value; + onChanged(); + return this; + } + /** + * required string username = 1; + * @return This builder for chaining. + */ + public Builder clearUsername() { + bitField0_ = (bitField0_ & ~0x00000001); + username_ = getDefaultInstance().getUsername(); + onChanged(); + return this; + } + /** + * required string username = 1; + * @param value The bytes for username to set. + * @return This builder for chaining. + */ + public Builder setUsernameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + username_ = value; + onChanged(); + return this; + } + + private int world_ ; + /** + * required int32 world = 2; + * @return Whether the world field is set. + */ + @java.lang.Override + public boolean hasWorld() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required int32 world = 2; + * @return The world. + */ + @java.lang.Override + public int getWorld() { + return world_; + } + /** + * required int32 world = 2; + * @param value The world to set. + * @return This builder for chaining. + */ + public Builder setWorld(int value) { + bitField0_ |= 0x00000002; + world_ = value; + onChanged(); + return this; + } + /** + * required int32 world = 2; + * @return This builder for chaining. + */ + public Builder clearWorld() { + bitField0_ = (bitField0_ & ~0x00000002); + world_ = 0; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:management.RequestContactInfo) + } + + // @@protoc_insertion_point(class_scope:management.RequestContactInfo) + private static final proto.management.RequestContactInfo DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new proto.management.RequestContactInfo(); + } + + public static proto.management.RequestContactInfo getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public RequestContactInfo parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new RequestContactInfo(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public proto.management.RequestContactInfo getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + +} + diff --git a/Server/src/main/proto/management/RequestContactInfoOrBuilder.java b/Server/src/main/proto/management/RequestContactInfoOrBuilder.java new file mode 100644 index 0000000..d1e44b8 --- /dev/null +++ b/Server/src/main/proto/management/RequestContactInfoOrBuilder.java @@ -0,0 +1,37 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: Management.proto + +package proto.management; + +public interface RequestContactInfoOrBuilder extends + // @@protoc_insertion_point(interface_extends:management.RequestContactInfo) + com.google.protobuf.MessageOrBuilder { + + /** + * required string username = 1; + * @return Whether the username field is set. + */ + boolean hasUsername(); + /** + * required string username = 1; + * @return The username. + */ + java.lang.String getUsername(); + /** + * required string username = 1; + * @return The bytes for username. + */ + com.google.protobuf.ByteString + getUsernameBytes(); + + /** + * required int32 world = 2; + * @return Whether the world field is set. + */ + boolean hasWorld(); + /** + * required int32 world = 2; + * @return The world. + */ + int getWorld(); +} diff --git a/Server/src/main/proto/management/SendClanInfo.java b/Server/src/main/proto/management/SendClanInfo.java new file mode 100644 index 0000000..8579ed4 --- /dev/null +++ b/Server/src/main/proto/management/SendClanInfo.java @@ -0,0 +1,2394 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: Management.proto + +package proto.management; + +/** + * Protobuf type {@code management.SendClanInfo} + */ +public final class SendClanInfo extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:management.SendClanInfo) + SendClanInfoOrBuilder { +private static final long serialVersionUID = 0L; + // Use SendClanInfo.newBuilder() to construct. + private SendClanInfo(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private SendClanInfo() { + clanOwner_ = ""; + clanName_ = ""; + members_ = java.util.Collections.emptyList(); + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new SendClanInfo(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private SendClanInfo( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + com.google.protobuf.ByteString bs = input.readBytes(); + bitField0_ |= 0x00000001; + clanOwner_ = bs; + break; + } + case 16: { + bitField0_ |= 0x00000002; + hasInfo_ = input.readBool(); + break; + } + case 26: { + com.google.protobuf.ByteString bs = input.readBytes(); + bitField0_ |= 0x00000004; + clanName_ = bs; + break; + } + case 32: { + bitField0_ |= 0x00000008; + joinRequirement_ = input.readInt32(); + break; + } + case 40: { + bitField0_ |= 0x00000010; + kickRequirement_ = input.readInt32(); + break; + } + case 48: { + bitField0_ |= 0x00000020; + messageRequirement_ = input.readInt32(); + break; + } + case 56: { + bitField0_ |= 0x00000040; + lootRequirement_ = input.readInt32(); + break; + } + case 66: { + if (!((mutable_bitField0_ & 0x00000080) != 0)) { + members_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000080; + } + members_.add( + input.readMessage(proto.management.SendClanInfo.ClanMember.PARSER, extensionRegistry)); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000080) != 0)) { + members_ = java.util.Collections.unmodifiableList(members_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return proto.management.ManagementProtos.internal_static_management_SendClanInfo_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return proto.management.ManagementProtos.internal_static_management_SendClanInfo_fieldAccessorTable + .ensureFieldAccessorsInitialized( + proto.management.SendClanInfo.class, proto.management.SendClanInfo.Builder.class); + } + + public interface ClanMemberOrBuilder extends + // @@protoc_insertion_point(interface_extends:management.SendClanInfo.ClanMember) + com.google.protobuf.MessageOrBuilder { + + /** + * required string username = 1; + * @return Whether the username field is set. + */ + boolean hasUsername(); + /** + * required string username = 1; + * @return The username. + */ + java.lang.String getUsername(); + /** + * required string username = 1; + * @return The bytes for username. + */ + com.google.protobuf.ByteString + getUsernameBytes(); + + /** + * required int32 world = 2; + * @return Whether the world field is set. + */ + boolean hasWorld(); + /** + * required int32 world = 2; + * @return The world. + */ + int getWorld(); + + /** + * required int32 rank = 3; + * @return Whether the rank field is set. + */ + boolean hasRank(); + /** + * required int32 rank = 3; + * @return The rank. + */ + int getRank(); + } + /** + * Protobuf type {@code management.SendClanInfo.ClanMember} + */ + public static final class ClanMember extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:management.SendClanInfo.ClanMember) + ClanMemberOrBuilder { + private static final long serialVersionUID = 0L; + // Use ClanMember.newBuilder() to construct. + private ClanMember(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private ClanMember() { + username_ = ""; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new ClanMember(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private ClanMember( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + com.google.protobuf.ByteString bs = input.readBytes(); + bitField0_ |= 0x00000001; + username_ = bs; + break; + } + case 16: { + bitField0_ |= 0x00000002; + world_ = input.readInt32(); + break; + } + case 24: { + bitField0_ |= 0x00000004; + rank_ = input.readInt32(); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return proto.management.ManagementProtos.internal_static_management_SendClanInfo_ClanMember_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return proto.management.ManagementProtos.internal_static_management_SendClanInfo_ClanMember_fieldAccessorTable + .ensureFieldAccessorsInitialized( + proto.management.SendClanInfo.ClanMember.class, proto.management.SendClanInfo.ClanMember.Builder.class); + } + + private int bitField0_; + public static final int USERNAME_FIELD_NUMBER = 1; + private volatile java.lang.Object username_; + /** + * required string username = 1; + * @return Whether the username field is set. + */ + @java.lang.Override + public boolean hasUsername() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required string username = 1; + * @return The username. + */ + @java.lang.Override + public java.lang.String getUsername() { + java.lang.Object ref = username_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + username_ = s; + } + return s; + } + } + /** + * required string username = 1; + * @return The bytes for username. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getUsernameBytes() { + java.lang.Object ref = username_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + username_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int WORLD_FIELD_NUMBER = 2; + private int world_; + /** + * required int32 world = 2; + * @return Whether the world field is set. + */ + @java.lang.Override + public boolean hasWorld() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required int32 world = 2; + * @return The world. + */ + @java.lang.Override + public int getWorld() { + return world_; + } + + public static final int RANK_FIELD_NUMBER = 3; + private int rank_; + /** + * required int32 rank = 3; + * @return Whether the rank field is set. + */ + @java.lang.Override + public boolean hasRank() { + return ((bitField0_ & 0x00000004) != 0); + } + /** + * required int32 rank = 3; + * @return The rank. + */ + @java.lang.Override + public int getRank() { + return rank_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (!hasUsername()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasWorld()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasRank()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 1, username_); + } + if (((bitField0_ & 0x00000002) != 0)) { + output.writeInt32(2, world_); + } + if (((bitField0_ & 0x00000004) != 0)) { + output.writeInt32(3, rank_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, username_); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeInt32Size(2, world_); + } + if (((bitField0_ & 0x00000004) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeInt32Size(3, rank_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof proto.management.SendClanInfo.ClanMember)) { + return super.equals(obj); + } + proto.management.SendClanInfo.ClanMember other = (proto.management.SendClanInfo.ClanMember) obj; + + if (hasUsername() != other.hasUsername()) return false; + if (hasUsername()) { + if (!getUsername() + .equals(other.getUsername())) return false; + } + if (hasWorld() != other.hasWorld()) return false; + if (hasWorld()) { + if (getWorld() + != other.getWorld()) return false; + } + if (hasRank() != other.hasRank()) return false; + if (hasRank()) { + if (getRank() + != other.getRank()) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasUsername()) { + hash = (37 * hash) + USERNAME_FIELD_NUMBER; + hash = (53 * hash) + getUsername().hashCode(); + } + if (hasWorld()) { + hash = (37 * hash) + WORLD_FIELD_NUMBER; + hash = (53 * hash) + getWorld(); + } + if (hasRank()) { + hash = (37 * hash) + RANK_FIELD_NUMBER; + hash = (53 * hash) + getRank(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static proto.management.SendClanInfo.ClanMember parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.SendClanInfo.ClanMember parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.SendClanInfo.ClanMember parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.SendClanInfo.ClanMember parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.SendClanInfo.ClanMember parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.SendClanInfo.ClanMember parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.SendClanInfo.ClanMember parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static proto.management.SendClanInfo.ClanMember parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static proto.management.SendClanInfo.ClanMember parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static proto.management.SendClanInfo.ClanMember parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static proto.management.SendClanInfo.ClanMember parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static proto.management.SendClanInfo.ClanMember parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(proto.management.SendClanInfo.ClanMember prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code management.SendClanInfo.ClanMember} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:management.SendClanInfo.ClanMember) + proto.management.SendClanInfo.ClanMemberOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return proto.management.ManagementProtos.internal_static_management_SendClanInfo_ClanMember_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return proto.management.ManagementProtos.internal_static_management_SendClanInfo_ClanMember_fieldAccessorTable + .ensureFieldAccessorsInitialized( + proto.management.SendClanInfo.ClanMember.class, proto.management.SendClanInfo.ClanMember.Builder.class); + } + + // Construct using proto.management.SendClanInfo.ClanMember.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + username_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + world_ = 0; + bitField0_ = (bitField0_ & ~0x00000002); + rank_ = 0; + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return proto.management.ManagementProtos.internal_static_management_SendClanInfo_ClanMember_descriptor; + } + + @java.lang.Override + public proto.management.SendClanInfo.ClanMember getDefaultInstanceForType() { + return proto.management.SendClanInfo.ClanMember.getDefaultInstance(); + } + + @java.lang.Override + public proto.management.SendClanInfo.ClanMember build() { + proto.management.SendClanInfo.ClanMember result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public proto.management.SendClanInfo.ClanMember buildPartial() { + proto.management.SendClanInfo.ClanMember result = new proto.management.SendClanInfo.ClanMember(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + to_bitField0_ |= 0x00000001; + } + result.username_ = username_; + if (((from_bitField0_ & 0x00000002) != 0)) { + result.world_ = world_; + to_bitField0_ |= 0x00000002; + } + if (((from_bitField0_ & 0x00000004) != 0)) { + result.rank_ = rank_; + to_bitField0_ |= 0x00000004; + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof proto.management.SendClanInfo.ClanMember) { + return mergeFrom((proto.management.SendClanInfo.ClanMember)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(proto.management.SendClanInfo.ClanMember other) { + if (other == proto.management.SendClanInfo.ClanMember.getDefaultInstance()) return this; + if (other.hasUsername()) { + bitField0_ |= 0x00000001; + username_ = other.username_; + onChanged(); + } + if (other.hasWorld()) { + setWorld(other.getWorld()); + } + if (other.hasRank()) { + setRank(other.getRank()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (!hasUsername()) { + return false; + } + if (!hasWorld()) { + return false; + } + if (!hasRank()) { + return false; + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + proto.management.SendClanInfo.ClanMember parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (proto.management.SendClanInfo.ClanMember) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private java.lang.Object username_ = ""; + /** + * required string username = 1; + * @return Whether the username field is set. + */ + public boolean hasUsername() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required string username = 1; + * @return The username. + */ + public java.lang.String getUsername() { + java.lang.Object ref = username_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + username_ = s; + } + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string username = 1; + * @return The bytes for username. + */ + public com.google.protobuf.ByteString + getUsernameBytes() { + java.lang.Object ref = username_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + username_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string username = 1; + * @param value The username to set. + * @return This builder for chaining. + */ + public Builder setUsername( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + username_ = value; + onChanged(); + return this; + } + /** + * required string username = 1; + * @return This builder for chaining. + */ + public Builder clearUsername() { + bitField0_ = (bitField0_ & ~0x00000001); + username_ = getDefaultInstance().getUsername(); + onChanged(); + return this; + } + /** + * required string username = 1; + * @param value The bytes for username to set. + * @return This builder for chaining. + */ + public Builder setUsernameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + username_ = value; + onChanged(); + return this; + } + + private int world_ ; + /** + * required int32 world = 2; + * @return Whether the world field is set. + */ + @java.lang.Override + public boolean hasWorld() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required int32 world = 2; + * @return The world. + */ + @java.lang.Override + public int getWorld() { + return world_; + } + /** + * required int32 world = 2; + * @param value The world to set. + * @return This builder for chaining. + */ + public Builder setWorld(int value) { + bitField0_ |= 0x00000002; + world_ = value; + onChanged(); + return this; + } + /** + * required int32 world = 2; + * @return This builder for chaining. + */ + public Builder clearWorld() { + bitField0_ = (bitField0_ & ~0x00000002); + world_ = 0; + onChanged(); + return this; + } + + private int rank_ ; + /** + * required int32 rank = 3; + * @return Whether the rank field is set. + */ + @java.lang.Override + public boolean hasRank() { + return ((bitField0_ & 0x00000004) != 0); + } + /** + * required int32 rank = 3; + * @return The rank. + */ + @java.lang.Override + public int getRank() { + return rank_; + } + /** + * required int32 rank = 3; + * @param value The rank to set. + * @return This builder for chaining. + */ + public Builder setRank(int value) { + bitField0_ |= 0x00000004; + rank_ = value; + onChanged(); + return this; + } + /** + * required int32 rank = 3; + * @return This builder for chaining. + */ + public Builder clearRank() { + bitField0_ = (bitField0_ & ~0x00000004); + rank_ = 0; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:management.SendClanInfo.ClanMember) + } + + // @@protoc_insertion_point(class_scope:management.SendClanInfo.ClanMember) + private static final proto.management.SendClanInfo.ClanMember DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new proto.management.SendClanInfo.ClanMember(); + } + + public static proto.management.SendClanInfo.ClanMember getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public ClanMember parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new ClanMember(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public proto.management.SendClanInfo.ClanMember getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + private int bitField0_; + public static final int CLANOWNER_FIELD_NUMBER = 1; + private volatile java.lang.Object clanOwner_; + /** + * required string clanOwner = 1; + * @return Whether the clanOwner field is set. + */ + @java.lang.Override + public boolean hasClanOwner() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required string clanOwner = 1; + * @return The clanOwner. + */ + @java.lang.Override + public java.lang.String getClanOwner() { + java.lang.Object ref = clanOwner_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + clanOwner_ = s; + } + return s; + } + } + /** + * required string clanOwner = 1; + * @return The bytes for clanOwner. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getClanOwnerBytes() { + java.lang.Object ref = clanOwner_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + clanOwner_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int HASINFO_FIELD_NUMBER = 2; + private boolean hasInfo_; + /** + * required bool hasInfo = 2; + * @return Whether the hasInfo field is set. + */ + @java.lang.Override + public boolean hasHasInfo() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required bool hasInfo = 2; + * @return The hasInfo. + */ + @java.lang.Override + public boolean getHasInfo() { + return hasInfo_; + } + + public static final int CLANNAME_FIELD_NUMBER = 3; + private volatile java.lang.Object clanName_; + /** + * optional string clanName = 3; + * @return Whether the clanName field is set. + */ + @java.lang.Override + public boolean hasClanName() { + return ((bitField0_ & 0x00000004) != 0); + } + /** + * optional string clanName = 3; + * @return The clanName. + */ + @java.lang.Override + public java.lang.String getClanName() { + java.lang.Object ref = clanName_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + clanName_ = s; + } + return s; + } + } + /** + * optional string clanName = 3; + * @return The bytes for clanName. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getClanNameBytes() { + java.lang.Object ref = clanName_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + clanName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int JOINREQUIREMENT_FIELD_NUMBER = 4; + private int joinRequirement_; + /** + * optional int32 joinRequirement = 4; + * @return Whether the joinRequirement field is set. + */ + @java.lang.Override + public boolean hasJoinRequirement() { + return ((bitField0_ & 0x00000008) != 0); + } + /** + * optional int32 joinRequirement = 4; + * @return The joinRequirement. + */ + @java.lang.Override + public int getJoinRequirement() { + return joinRequirement_; + } + + public static final int KICKREQUIREMENT_FIELD_NUMBER = 5; + private int kickRequirement_; + /** + * optional int32 kickRequirement = 5; + * @return Whether the kickRequirement field is set. + */ + @java.lang.Override + public boolean hasKickRequirement() { + return ((bitField0_ & 0x00000010) != 0); + } + /** + * optional int32 kickRequirement = 5; + * @return The kickRequirement. + */ + @java.lang.Override + public int getKickRequirement() { + return kickRequirement_; + } + + public static final int MESSAGEREQUIREMENT_FIELD_NUMBER = 6; + private int messageRequirement_; + /** + * optional int32 messageRequirement = 6; + * @return Whether the messageRequirement field is set. + */ + @java.lang.Override + public boolean hasMessageRequirement() { + return ((bitField0_ & 0x00000020) != 0); + } + /** + * optional int32 messageRequirement = 6; + * @return The messageRequirement. + */ + @java.lang.Override + public int getMessageRequirement() { + return messageRequirement_; + } + + public static final int LOOTREQUIREMENT_FIELD_NUMBER = 7; + private int lootRequirement_; + /** + * optional int32 lootRequirement = 7; + * @return Whether the lootRequirement field is set. + */ + @java.lang.Override + public boolean hasLootRequirement() { + return ((bitField0_ & 0x00000040) != 0); + } + /** + * optional int32 lootRequirement = 7; + * @return The lootRequirement. + */ + @java.lang.Override + public int getLootRequirement() { + return lootRequirement_; + } + + public static final int MEMBERS_FIELD_NUMBER = 8; + private java.util.List members_; + /** + * repeated .management.SendClanInfo.ClanMember members = 8; + */ + @java.lang.Override + public java.util.List getMembersList() { + return members_; + } + /** + * repeated .management.SendClanInfo.ClanMember members = 8; + */ + @java.lang.Override + public java.util.List + getMembersOrBuilderList() { + return members_; + } + /** + * repeated .management.SendClanInfo.ClanMember members = 8; + */ + @java.lang.Override + public int getMembersCount() { + return members_.size(); + } + /** + * repeated .management.SendClanInfo.ClanMember members = 8; + */ + @java.lang.Override + public proto.management.SendClanInfo.ClanMember getMembers(int index) { + return members_.get(index); + } + /** + * repeated .management.SendClanInfo.ClanMember members = 8; + */ + @java.lang.Override + public proto.management.SendClanInfo.ClanMemberOrBuilder getMembersOrBuilder( + int index) { + return members_.get(index); + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (!hasClanOwner()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasHasInfo()) { + memoizedIsInitialized = 0; + return false; + } + for (int i = 0; i < getMembersCount(); i++) { + if (!getMembers(i).isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 1, clanOwner_); + } + if (((bitField0_ & 0x00000002) != 0)) { + output.writeBool(2, hasInfo_); + } + if (((bitField0_ & 0x00000004) != 0)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 3, clanName_); + } + if (((bitField0_ & 0x00000008) != 0)) { + output.writeInt32(4, joinRequirement_); + } + if (((bitField0_ & 0x00000010) != 0)) { + output.writeInt32(5, kickRequirement_); + } + if (((bitField0_ & 0x00000020) != 0)) { + output.writeInt32(6, messageRequirement_); + } + if (((bitField0_ & 0x00000040) != 0)) { + output.writeInt32(7, lootRequirement_); + } + for (int i = 0; i < members_.size(); i++) { + output.writeMessage(8, members_.get(i)); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, clanOwner_); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeBoolSize(2, hasInfo_); + } + if (((bitField0_ & 0x00000004) != 0)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, clanName_); + } + if (((bitField0_ & 0x00000008) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeInt32Size(4, joinRequirement_); + } + if (((bitField0_ & 0x00000010) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeInt32Size(5, kickRequirement_); + } + if (((bitField0_ & 0x00000020) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeInt32Size(6, messageRequirement_); + } + if (((bitField0_ & 0x00000040) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeInt32Size(7, lootRequirement_); + } + for (int i = 0; i < members_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(8, members_.get(i)); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof proto.management.SendClanInfo)) { + return super.equals(obj); + } + proto.management.SendClanInfo other = (proto.management.SendClanInfo) obj; + + if (hasClanOwner() != other.hasClanOwner()) return false; + if (hasClanOwner()) { + if (!getClanOwner() + .equals(other.getClanOwner())) return false; + } + if (hasHasInfo() != other.hasHasInfo()) return false; + if (hasHasInfo()) { + if (getHasInfo() + != other.getHasInfo()) return false; + } + if (hasClanName() != other.hasClanName()) return false; + if (hasClanName()) { + if (!getClanName() + .equals(other.getClanName())) return false; + } + if (hasJoinRequirement() != other.hasJoinRequirement()) return false; + if (hasJoinRequirement()) { + if (getJoinRequirement() + != other.getJoinRequirement()) return false; + } + if (hasKickRequirement() != other.hasKickRequirement()) return false; + if (hasKickRequirement()) { + if (getKickRequirement() + != other.getKickRequirement()) return false; + } + if (hasMessageRequirement() != other.hasMessageRequirement()) return false; + if (hasMessageRequirement()) { + if (getMessageRequirement() + != other.getMessageRequirement()) return false; + } + if (hasLootRequirement() != other.hasLootRequirement()) return false; + if (hasLootRequirement()) { + if (getLootRequirement() + != other.getLootRequirement()) return false; + } + if (!getMembersList() + .equals(other.getMembersList())) return false; + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasClanOwner()) { + hash = (37 * hash) + CLANOWNER_FIELD_NUMBER; + hash = (53 * hash) + getClanOwner().hashCode(); + } + if (hasHasInfo()) { + hash = (37 * hash) + HASINFO_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean( + getHasInfo()); + } + if (hasClanName()) { + hash = (37 * hash) + CLANNAME_FIELD_NUMBER; + hash = (53 * hash) + getClanName().hashCode(); + } + if (hasJoinRequirement()) { + hash = (37 * hash) + JOINREQUIREMENT_FIELD_NUMBER; + hash = (53 * hash) + getJoinRequirement(); + } + if (hasKickRequirement()) { + hash = (37 * hash) + KICKREQUIREMENT_FIELD_NUMBER; + hash = (53 * hash) + getKickRequirement(); + } + if (hasMessageRequirement()) { + hash = (37 * hash) + MESSAGEREQUIREMENT_FIELD_NUMBER; + hash = (53 * hash) + getMessageRequirement(); + } + if (hasLootRequirement()) { + hash = (37 * hash) + LOOTREQUIREMENT_FIELD_NUMBER; + hash = (53 * hash) + getLootRequirement(); + } + if (getMembersCount() > 0) { + hash = (37 * hash) + MEMBERS_FIELD_NUMBER; + hash = (53 * hash) + getMembersList().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static proto.management.SendClanInfo parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.SendClanInfo parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.SendClanInfo parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.SendClanInfo parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.SendClanInfo parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.SendClanInfo parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.SendClanInfo parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static proto.management.SendClanInfo parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static proto.management.SendClanInfo parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static proto.management.SendClanInfo parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static proto.management.SendClanInfo parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static proto.management.SendClanInfo parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(proto.management.SendClanInfo prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code management.SendClanInfo} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:management.SendClanInfo) + proto.management.SendClanInfoOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return proto.management.ManagementProtos.internal_static_management_SendClanInfo_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return proto.management.ManagementProtos.internal_static_management_SendClanInfo_fieldAccessorTable + .ensureFieldAccessorsInitialized( + proto.management.SendClanInfo.class, proto.management.SendClanInfo.Builder.class); + } + + // Construct using proto.management.SendClanInfo.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + getMembersFieldBuilder(); + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + clanOwner_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + hasInfo_ = false; + bitField0_ = (bitField0_ & ~0x00000002); + clanName_ = ""; + bitField0_ = (bitField0_ & ~0x00000004); + joinRequirement_ = 0; + bitField0_ = (bitField0_ & ~0x00000008); + kickRequirement_ = 0; + bitField0_ = (bitField0_ & ~0x00000010); + messageRequirement_ = 0; + bitField0_ = (bitField0_ & ~0x00000020); + lootRequirement_ = 0; + bitField0_ = (bitField0_ & ~0x00000040); + if (membersBuilder_ == null) { + members_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000080); + } else { + membersBuilder_.clear(); + } + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return proto.management.ManagementProtos.internal_static_management_SendClanInfo_descriptor; + } + + @java.lang.Override + public proto.management.SendClanInfo getDefaultInstanceForType() { + return proto.management.SendClanInfo.getDefaultInstance(); + } + + @java.lang.Override + public proto.management.SendClanInfo build() { + proto.management.SendClanInfo result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public proto.management.SendClanInfo buildPartial() { + proto.management.SendClanInfo result = new proto.management.SendClanInfo(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + to_bitField0_ |= 0x00000001; + } + result.clanOwner_ = clanOwner_; + if (((from_bitField0_ & 0x00000002) != 0)) { + result.hasInfo_ = hasInfo_; + to_bitField0_ |= 0x00000002; + } + if (((from_bitField0_ & 0x00000004) != 0)) { + to_bitField0_ |= 0x00000004; + } + result.clanName_ = clanName_; + if (((from_bitField0_ & 0x00000008) != 0)) { + result.joinRequirement_ = joinRequirement_; + to_bitField0_ |= 0x00000008; + } + if (((from_bitField0_ & 0x00000010) != 0)) { + result.kickRequirement_ = kickRequirement_; + to_bitField0_ |= 0x00000010; + } + if (((from_bitField0_ & 0x00000020) != 0)) { + result.messageRequirement_ = messageRequirement_; + to_bitField0_ |= 0x00000020; + } + if (((from_bitField0_ & 0x00000040) != 0)) { + result.lootRequirement_ = lootRequirement_; + to_bitField0_ |= 0x00000040; + } + if (membersBuilder_ == null) { + if (((bitField0_ & 0x00000080) != 0)) { + members_ = java.util.Collections.unmodifiableList(members_); + bitField0_ = (bitField0_ & ~0x00000080); + } + result.members_ = members_; + } else { + result.members_ = membersBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof proto.management.SendClanInfo) { + return mergeFrom((proto.management.SendClanInfo)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(proto.management.SendClanInfo other) { + if (other == proto.management.SendClanInfo.getDefaultInstance()) return this; + if (other.hasClanOwner()) { + bitField0_ |= 0x00000001; + clanOwner_ = other.clanOwner_; + onChanged(); + } + if (other.hasHasInfo()) { + setHasInfo(other.getHasInfo()); + } + if (other.hasClanName()) { + bitField0_ |= 0x00000004; + clanName_ = other.clanName_; + onChanged(); + } + if (other.hasJoinRequirement()) { + setJoinRequirement(other.getJoinRequirement()); + } + if (other.hasKickRequirement()) { + setKickRequirement(other.getKickRequirement()); + } + if (other.hasMessageRequirement()) { + setMessageRequirement(other.getMessageRequirement()); + } + if (other.hasLootRequirement()) { + setLootRequirement(other.getLootRequirement()); + } + if (membersBuilder_ == null) { + if (!other.members_.isEmpty()) { + if (members_.isEmpty()) { + members_ = other.members_; + bitField0_ = (bitField0_ & ~0x00000080); + } else { + ensureMembersIsMutable(); + members_.addAll(other.members_); + } + onChanged(); + } + } else { + if (!other.members_.isEmpty()) { + if (membersBuilder_.isEmpty()) { + membersBuilder_.dispose(); + membersBuilder_ = null; + members_ = other.members_; + bitField0_ = (bitField0_ & ~0x00000080); + membersBuilder_ = + com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ? + getMembersFieldBuilder() : null; + } else { + membersBuilder_.addAllMessages(other.members_); + } + } + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (!hasClanOwner()) { + return false; + } + if (!hasHasInfo()) { + return false; + } + for (int i = 0; i < getMembersCount(); i++) { + if (!getMembers(i).isInitialized()) { + return false; + } + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + proto.management.SendClanInfo parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (proto.management.SendClanInfo) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private java.lang.Object clanOwner_ = ""; + /** + * required string clanOwner = 1; + * @return Whether the clanOwner field is set. + */ + public boolean hasClanOwner() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required string clanOwner = 1; + * @return The clanOwner. + */ + public java.lang.String getClanOwner() { + java.lang.Object ref = clanOwner_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + clanOwner_ = s; + } + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string clanOwner = 1; + * @return The bytes for clanOwner. + */ + public com.google.protobuf.ByteString + getClanOwnerBytes() { + java.lang.Object ref = clanOwner_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + clanOwner_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string clanOwner = 1; + * @param value The clanOwner to set. + * @return This builder for chaining. + */ + public Builder setClanOwner( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + clanOwner_ = value; + onChanged(); + return this; + } + /** + * required string clanOwner = 1; + * @return This builder for chaining. + */ + public Builder clearClanOwner() { + bitField0_ = (bitField0_ & ~0x00000001); + clanOwner_ = getDefaultInstance().getClanOwner(); + onChanged(); + return this; + } + /** + * required string clanOwner = 1; + * @param value The bytes for clanOwner to set. + * @return This builder for chaining. + */ + public Builder setClanOwnerBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + clanOwner_ = value; + onChanged(); + return this; + } + + private boolean hasInfo_ ; + /** + * required bool hasInfo = 2; + * @return Whether the hasInfo field is set. + */ + @java.lang.Override + public boolean hasHasInfo() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * required bool hasInfo = 2; + * @return The hasInfo. + */ + @java.lang.Override + public boolean getHasInfo() { + return hasInfo_; + } + /** + * required bool hasInfo = 2; + * @param value The hasInfo to set. + * @return This builder for chaining. + */ + public Builder setHasInfo(boolean value) { + bitField0_ |= 0x00000002; + hasInfo_ = value; + onChanged(); + return this; + } + /** + * required bool hasInfo = 2; + * @return This builder for chaining. + */ + public Builder clearHasInfo() { + bitField0_ = (bitField0_ & ~0x00000002); + hasInfo_ = false; + onChanged(); + return this; + } + + private java.lang.Object clanName_ = ""; + /** + * optional string clanName = 3; + * @return Whether the clanName field is set. + */ + public boolean hasClanName() { + return ((bitField0_ & 0x00000004) != 0); + } + /** + * optional string clanName = 3; + * @return The clanName. + */ + public java.lang.String getClanName() { + java.lang.Object ref = clanName_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + clanName_ = s; + } + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string clanName = 3; + * @return The bytes for clanName. + */ + public com.google.protobuf.ByteString + getClanNameBytes() { + java.lang.Object ref = clanName_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + clanName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string clanName = 3; + * @param value The clanName to set. + * @return This builder for chaining. + */ + public Builder setClanName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + clanName_ = value; + onChanged(); + return this; + } + /** + * optional string clanName = 3; + * @return This builder for chaining. + */ + public Builder clearClanName() { + bitField0_ = (bitField0_ & ~0x00000004); + clanName_ = getDefaultInstance().getClanName(); + onChanged(); + return this; + } + /** + * optional string clanName = 3; + * @param value The bytes for clanName to set. + * @return This builder for chaining. + */ + public Builder setClanNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + clanName_ = value; + onChanged(); + return this; + } + + private int joinRequirement_ ; + /** + * optional int32 joinRequirement = 4; + * @return Whether the joinRequirement field is set. + */ + @java.lang.Override + public boolean hasJoinRequirement() { + return ((bitField0_ & 0x00000008) != 0); + } + /** + * optional int32 joinRequirement = 4; + * @return The joinRequirement. + */ + @java.lang.Override + public int getJoinRequirement() { + return joinRequirement_; + } + /** + * optional int32 joinRequirement = 4; + * @param value The joinRequirement to set. + * @return This builder for chaining. + */ + public Builder setJoinRequirement(int value) { + bitField0_ |= 0x00000008; + joinRequirement_ = value; + onChanged(); + return this; + } + /** + * optional int32 joinRequirement = 4; + * @return This builder for chaining. + */ + public Builder clearJoinRequirement() { + bitField0_ = (bitField0_ & ~0x00000008); + joinRequirement_ = 0; + onChanged(); + return this; + } + + private int kickRequirement_ ; + /** + * optional int32 kickRequirement = 5; + * @return Whether the kickRequirement field is set. + */ + @java.lang.Override + public boolean hasKickRequirement() { + return ((bitField0_ & 0x00000010) != 0); + } + /** + * optional int32 kickRequirement = 5; + * @return The kickRequirement. + */ + @java.lang.Override + public int getKickRequirement() { + return kickRequirement_; + } + /** + * optional int32 kickRequirement = 5; + * @param value The kickRequirement to set. + * @return This builder for chaining. + */ + public Builder setKickRequirement(int value) { + bitField0_ |= 0x00000010; + kickRequirement_ = value; + onChanged(); + return this; + } + /** + * optional int32 kickRequirement = 5; + * @return This builder for chaining. + */ + public Builder clearKickRequirement() { + bitField0_ = (bitField0_ & ~0x00000010); + kickRequirement_ = 0; + onChanged(); + return this; + } + + private int messageRequirement_ ; + /** + * optional int32 messageRequirement = 6; + * @return Whether the messageRequirement field is set. + */ + @java.lang.Override + public boolean hasMessageRequirement() { + return ((bitField0_ & 0x00000020) != 0); + } + /** + * optional int32 messageRequirement = 6; + * @return The messageRequirement. + */ + @java.lang.Override + public int getMessageRequirement() { + return messageRequirement_; + } + /** + * optional int32 messageRequirement = 6; + * @param value The messageRequirement to set. + * @return This builder for chaining. + */ + public Builder setMessageRequirement(int value) { + bitField0_ |= 0x00000020; + messageRequirement_ = value; + onChanged(); + return this; + } + /** + * optional int32 messageRequirement = 6; + * @return This builder for chaining. + */ + public Builder clearMessageRequirement() { + bitField0_ = (bitField0_ & ~0x00000020); + messageRequirement_ = 0; + onChanged(); + return this; + } + + private int lootRequirement_ ; + /** + * optional int32 lootRequirement = 7; + * @return Whether the lootRequirement field is set. + */ + @java.lang.Override + public boolean hasLootRequirement() { + return ((bitField0_ & 0x00000040) != 0); + } + /** + * optional int32 lootRequirement = 7; + * @return The lootRequirement. + */ + @java.lang.Override + public int getLootRequirement() { + return lootRequirement_; + } + /** + * optional int32 lootRequirement = 7; + * @param value The lootRequirement to set. + * @return This builder for chaining. + */ + public Builder setLootRequirement(int value) { + bitField0_ |= 0x00000040; + lootRequirement_ = value; + onChanged(); + return this; + } + /** + * optional int32 lootRequirement = 7; + * @return This builder for chaining. + */ + public Builder clearLootRequirement() { + bitField0_ = (bitField0_ & ~0x00000040); + lootRequirement_ = 0; + onChanged(); + return this; + } + + private java.util.List members_ = + java.util.Collections.emptyList(); + private void ensureMembersIsMutable() { + if (!((bitField0_ & 0x00000080) != 0)) { + members_ = new java.util.ArrayList(members_); + bitField0_ |= 0x00000080; + } + } + + private com.google.protobuf.RepeatedFieldBuilderV3< + proto.management.SendClanInfo.ClanMember, proto.management.SendClanInfo.ClanMember.Builder, proto.management.SendClanInfo.ClanMemberOrBuilder> membersBuilder_; + + /** + * repeated .management.SendClanInfo.ClanMember members = 8; + */ + public java.util.List getMembersList() { + if (membersBuilder_ == null) { + return java.util.Collections.unmodifiableList(members_); + } else { + return membersBuilder_.getMessageList(); + } + } + /** + * repeated .management.SendClanInfo.ClanMember members = 8; + */ + public int getMembersCount() { + if (membersBuilder_ == null) { + return members_.size(); + } else { + return membersBuilder_.getCount(); + } + } + /** + * repeated .management.SendClanInfo.ClanMember members = 8; + */ + public proto.management.SendClanInfo.ClanMember getMembers(int index) { + if (membersBuilder_ == null) { + return members_.get(index); + } else { + return membersBuilder_.getMessage(index); + } + } + /** + * repeated .management.SendClanInfo.ClanMember members = 8; + */ + public Builder setMembers( + int index, proto.management.SendClanInfo.ClanMember value) { + if (membersBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureMembersIsMutable(); + members_.set(index, value); + onChanged(); + } else { + membersBuilder_.setMessage(index, value); + } + return this; + } + /** + * repeated .management.SendClanInfo.ClanMember members = 8; + */ + public Builder setMembers( + int index, proto.management.SendClanInfo.ClanMember.Builder builderForValue) { + if (membersBuilder_ == null) { + ensureMembersIsMutable(); + members_.set(index, builderForValue.build()); + onChanged(); + } else { + membersBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .management.SendClanInfo.ClanMember members = 8; + */ + public Builder addMembers(proto.management.SendClanInfo.ClanMember value) { + if (membersBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureMembersIsMutable(); + members_.add(value); + onChanged(); + } else { + membersBuilder_.addMessage(value); + } + return this; + } + /** + * repeated .management.SendClanInfo.ClanMember members = 8; + */ + public Builder addMembers( + int index, proto.management.SendClanInfo.ClanMember value) { + if (membersBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureMembersIsMutable(); + members_.add(index, value); + onChanged(); + } else { + membersBuilder_.addMessage(index, value); + } + return this; + } + /** + * repeated .management.SendClanInfo.ClanMember members = 8; + */ + public Builder addMembers( + proto.management.SendClanInfo.ClanMember.Builder builderForValue) { + if (membersBuilder_ == null) { + ensureMembersIsMutable(); + members_.add(builderForValue.build()); + onChanged(); + } else { + membersBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * repeated .management.SendClanInfo.ClanMember members = 8; + */ + public Builder addMembers( + int index, proto.management.SendClanInfo.ClanMember.Builder builderForValue) { + if (membersBuilder_ == null) { + ensureMembersIsMutable(); + members_.add(index, builderForValue.build()); + onChanged(); + } else { + membersBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .management.SendClanInfo.ClanMember members = 8; + */ + public Builder addAllMembers( + java.lang.Iterable values) { + if (membersBuilder_ == null) { + ensureMembersIsMutable(); + com.google.protobuf.AbstractMessageLite.Builder.addAll( + values, members_); + onChanged(); + } else { + membersBuilder_.addAllMessages(values); + } + return this; + } + /** + * repeated .management.SendClanInfo.ClanMember members = 8; + */ + public Builder clearMembers() { + if (membersBuilder_ == null) { + members_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000080); + onChanged(); + } else { + membersBuilder_.clear(); + } + return this; + } + /** + * repeated .management.SendClanInfo.ClanMember members = 8; + */ + public Builder removeMembers(int index) { + if (membersBuilder_ == null) { + ensureMembersIsMutable(); + members_.remove(index); + onChanged(); + } else { + membersBuilder_.remove(index); + } + return this; + } + /** + * repeated .management.SendClanInfo.ClanMember members = 8; + */ + public proto.management.SendClanInfo.ClanMember.Builder getMembersBuilder( + int index) { + return getMembersFieldBuilder().getBuilder(index); + } + /** + * repeated .management.SendClanInfo.ClanMember members = 8; + */ + public proto.management.SendClanInfo.ClanMemberOrBuilder getMembersOrBuilder( + int index) { + if (membersBuilder_ == null) { + return members_.get(index); } else { + return membersBuilder_.getMessageOrBuilder(index); + } + } + /** + * repeated .management.SendClanInfo.ClanMember members = 8; + */ + public java.util.List + getMembersOrBuilderList() { + if (membersBuilder_ != null) { + return membersBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(members_); + } + } + /** + * repeated .management.SendClanInfo.ClanMember members = 8; + */ + public proto.management.SendClanInfo.ClanMember.Builder addMembersBuilder() { + return getMembersFieldBuilder().addBuilder( + proto.management.SendClanInfo.ClanMember.getDefaultInstance()); + } + /** + * repeated .management.SendClanInfo.ClanMember members = 8; + */ + public proto.management.SendClanInfo.ClanMember.Builder addMembersBuilder( + int index) { + return getMembersFieldBuilder().addBuilder( + index, proto.management.SendClanInfo.ClanMember.getDefaultInstance()); + } + /** + * repeated .management.SendClanInfo.ClanMember members = 8; + */ + public java.util.List + getMembersBuilderList() { + return getMembersFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilderV3< + proto.management.SendClanInfo.ClanMember, proto.management.SendClanInfo.ClanMember.Builder, proto.management.SendClanInfo.ClanMemberOrBuilder> + getMembersFieldBuilder() { + if (membersBuilder_ == null) { + membersBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3< + proto.management.SendClanInfo.ClanMember, proto.management.SendClanInfo.ClanMember.Builder, proto.management.SendClanInfo.ClanMemberOrBuilder>( + members_, + ((bitField0_ & 0x00000080) != 0), + getParentForChildren(), + isClean()); + members_ = null; + } + return membersBuilder_; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:management.SendClanInfo) + } + + // @@protoc_insertion_point(class_scope:management.SendClanInfo) + private static final proto.management.SendClanInfo DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new proto.management.SendClanInfo(); + } + + public static proto.management.SendClanInfo getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public SendClanInfo parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new SendClanInfo(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public proto.management.SendClanInfo getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + +} + diff --git a/Server/src/main/proto/management/SendClanInfoOrBuilder.java b/Server/src/main/proto/management/SendClanInfoOrBuilder.java new file mode 100644 index 0000000..d313ad7 --- /dev/null +++ b/Server/src/main/proto/management/SendClanInfoOrBuilder.java @@ -0,0 +1,122 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: Management.proto + +package proto.management; + +public interface SendClanInfoOrBuilder extends + // @@protoc_insertion_point(interface_extends:management.SendClanInfo) + com.google.protobuf.MessageOrBuilder { + + /** + * required string clanOwner = 1; + * @return Whether the clanOwner field is set. + */ + boolean hasClanOwner(); + /** + * required string clanOwner = 1; + * @return The clanOwner. + */ + java.lang.String getClanOwner(); + /** + * required string clanOwner = 1; + * @return The bytes for clanOwner. + */ + com.google.protobuf.ByteString + getClanOwnerBytes(); + + /** + * required bool hasInfo = 2; + * @return Whether the hasInfo field is set. + */ + boolean hasHasInfo(); + /** + * required bool hasInfo = 2; + * @return The hasInfo. + */ + boolean getHasInfo(); + + /** + * optional string clanName = 3; + * @return Whether the clanName field is set. + */ + boolean hasClanName(); + /** + * optional string clanName = 3; + * @return The clanName. + */ + java.lang.String getClanName(); + /** + * optional string clanName = 3; + * @return The bytes for clanName. + */ + com.google.protobuf.ByteString + getClanNameBytes(); + + /** + * optional int32 joinRequirement = 4; + * @return Whether the joinRequirement field is set. + */ + boolean hasJoinRequirement(); + /** + * optional int32 joinRequirement = 4; + * @return The joinRequirement. + */ + int getJoinRequirement(); + + /** + * optional int32 kickRequirement = 5; + * @return Whether the kickRequirement field is set. + */ + boolean hasKickRequirement(); + /** + * optional int32 kickRequirement = 5; + * @return The kickRequirement. + */ + int getKickRequirement(); + + /** + * optional int32 messageRequirement = 6; + * @return Whether the messageRequirement field is set. + */ + boolean hasMessageRequirement(); + /** + * optional int32 messageRequirement = 6; + * @return The messageRequirement. + */ + int getMessageRequirement(); + + /** + * optional int32 lootRequirement = 7; + * @return Whether the lootRequirement field is set. + */ + boolean hasLootRequirement(); + /** + * optional int32 lootRequirement = 7; + * @return The lootRequirement. + */ + int getLootRequirement(); + + /** + * repeated .management.SendClanInfo.ClanMember members = 8; + */ + java.util.List + getMembersList(); + /** + * repeated .management.SendClanInfo.ClanMember members = 8; + */ + proto.management.SendClanInfo.ClanMember getMembers(int index); + /** + * repeated .management.SendClanInfo.ClanMember members = 8; + */ + int getMembersCount(); + /** + * repeated .management.SendClanInfo.ClanMember members = 8; + */ + java.util.List + getMembersOrBuilderList(); + /** + * repeated .management.SendClanInfo.ClanMember members = 8; + */ + proto.management.SendClanInfo.ClanMemberOrBuilder getMembersOrBuilder( + int index); +} diff --git a/Server/src/main/proto/management/SendContactInfo.java b/Server/src/main/proto/management/SendContactInfo.java new file mode 100644 index 0000000..f2698f4 --- /dev/null +++ b/Server/src/main/proto/management/SendContactInfo.java @@ -0,0 +1,1958 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: Management.proto + +package proto.management; + +/** + * Protobuf type {@code management.SendContactInfo} + */ +public final class SendContactInfo extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:management.SendContactInfo) + SendContactInfoOrBuilder { +private static final long serialVersionUID = 0L; + // Use SendContactInfo.newBuilder() to construct. + private SendContactInfo(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private SendContactInfo() { + username_ = ""; + contacts_ = java.util.Collections.emptyList(); + blocked_ = com.google.protobuf.LazyStringArrayList.EMPTY; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new SendContactInfo(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private SendContactInfo( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + com.google.protobuf.ByteString bs = input.readBytes(); + bitField0_ |= 0x00000001; + username_ = bs; + break; + } + case 18: { + if (!((mutable_bitField0_ & 0x00000002) != 0)) { + contacts_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000002; + } + contacts_.add( + input.readMessage(proto.management.SendContactInfo.Contact.PARSER, extensionRegistry)); + break; + } + case 26: { + com.google.protobuf.ByteString bs = input.readBytes(); + if (!((mutable_bitField0_ & 0x00000004) != 0)) { + blocked_ = new com.google.protobuf.LazyStringArrayList(); + mutable_bitField0_ |= 0x00000004; + } + blocked_.add(bs); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000002) != 0)) { + contacts_ = java.util.Collections.unmodifiableList(contacts_); + } + if (((mutable_bitField0_ & 0x00000004) != 0)) { + blocked_ = blocked_.getUnmodifiableView(); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return proto.management.ManagementProtos.internal_static_management_SendContactInfo_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return proto.management.ManagementProtos.internal_static_management_SendContactInfo_fieldAccessorTable + .ensureFieldAccessorsInitialized( + proto.management.SendContactInfo.class, proto.management.SendContactInfo.Builder.class); + } + + public interface ContactOrBuilder extends + // @@protoc_insertion_point(interface_extends:management.SendContactInfo.Contact) + com.google.protobuf.MessageOrBuilder { + + /** + * required string username = 1; + * @return Whether the username field is set. + */ + boolean hasUsername(); + /** + * required string username = 1; + * @return The username. + */ + java.lang.String getUsername(); + /** + * required string username = 1; + * @return The bytes for username. + */ + com.google.protobuf.ByteString + getUsernameBytes(); + + /** + * optional int32 world = 2; + * @return Whether the world field is set. + */ + boolean hasWorld(); + /** + * optional int32 world = 2; + * @return The world. + */ + int getWorld(); + + /** + * optional int32 rank = 3; + * @return Whether the rank field is set. + */ + boolean hasRank(); + /** + * optional int32 rank = 3; + * @return The rank. + */ + int getRank(); + } + /** + * Protobuf type {@code management.SendContactInfo.Contact} + */ + public static final class Contact extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:management.SendContactInfo.Contact) + ContactOrBuilder { + private static final long serialVersionUID = 0L; + // Use Contact.newBuilder() to construct. + private Contact(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private Contact() { + username_ = ""; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new Contact(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private Contact( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + com.google.protobuf.ByteString bs = input.readBytes(); + bitField0_ |= 0x00000001; + username_ = bs; + break; + } + case 16: { + bitField0_ |= 0x00000002; + world_ = input.readInt32(); + break; + } + case 24: { + bitField0_ |= 0x00000004; + rank_ = input.readInt32(); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return proto.management.ManagementProtos.internal_static_management_SendContactInfo_Contact_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return proto.management.ManagementProtos.internal_static_management_SendContactInfo_Contact_fieldAccessorTable + .ensureFieldAccessorsInitialized( + proto.management.SendContactInfo.Contact.class, proto.management.SendContactInfo.Contact.Builder.class); + } + + private int bitField0_; + public static final int USERNAME_FIELD_NUMBER = 1; + private volatile java.lang.Object username_; + /** + * required string username = 1; + * @return Whether the username field is set. + */ + @java.lang.Override + public boolean hasUsername() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required string username = 1; + * @return The username. + */ + @java.lang.Override + public java.lang.String getUsername() { + java.lang.Object ref = username_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + username_ = s; + } + return s; + } + } + /** + * required string username = 1; + * @return The bytes for username. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getUsernameBytes() { + java.lang.Object ref = username_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + username_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int WORLD_FIELD_NUMBER = 2; + private int world_; + /** + * optional int32 world = 2; + * @return Whether the world field is set. + */ + @java.lang.Override + public boolean hasWorld() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * optional int32 world = 2; + * @return The world. + */ + @java.lang.Override + public int getWorld() { + return world_; + } + + public static final int RANK_FIELD_NUMBER = 3; + private int rank_; + /** + * optional int32 rank = 3; + * @return Whether the rank field is set. + */ + @java.lang.Override + public boolean hasRank() { + return ((bitField0_ & 0x00000004) != 0); + } + /** + * optional int32 rank = 3; + * @return The rank. + */ + @java.lang.Override + public int getRank() { + return rank_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (!hasUsername()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 1, username_); + } + if (((bitField0_ & 0x00000002) != 0)) { + output.writeInt32(2, world_); + } + if (((bitField0_ & 0x00000004) != 0)) { + output.writeInt32(3, rank_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, username_); + } + if (((bitField0_ & 0x00000002) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeInt32Size(2, world_); + } + if (((bitField0_ & 0x00000004) != 0)) { + size += com.google.protobuf.CodedOutputStream + .computeInt32Size(3, rank_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof proto.management.SendContactInfo.Contact)) { + return super.equals(obj); + } + proto.management.SendContactInfo.Contact other = (proto.management.SendContactInfo.Contact) obj; + + if (hasUsername() != other.hasUsername()) return false; + if (hasUsername()) { + if (!getUsername() + .equals(other.getUsername())) return false; + } + if (hasWorld() != other.hasWorld()) return false; + if (hasWorld()) { + if (getWorld() + != other.getWorld()) return false; + } + if (hasRank() != other.hasRank()) return false; + if (hasRank()) { + if (getRank() + != other.getRank()) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasUsername()) { + hash = (37 * hash) + USERNAME_FIELD_NUMBER; + hash = (53 * hash) + getUsername().hashCode(); + } + if (hasWorld()) { + hash = (37 * hash) + WORLD_FIELD_NUMBER; + hash = (53 * hash) + getWorld(); + } + if (hasRank()) { + hash = (37 * hash) + RANK_FIELD_NUMBER; + hash = (53 * hash) + getRank(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static proto.management.SendContactInfo.Contact parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.SendContactInfo.Contact parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.SendContactInfo.Contact parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.SendContactInfo.Contact parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.SendContactInfo.Contact parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.SendContactInfo.Contact parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.SendContactInfo.Contact parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static proto.management.SendContactInfo.Contact parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static proto.management.SendContactInfo.Contact parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static proto.management.SendContactInfo.Contact parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static proto.management.SendContactInfo.Contact parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static proto.management.SendContactInfo.Contact parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(proto.management.SendContactInfo.Contact prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code management.SendContactInfo.Contact} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:management.SendContactInfo.Contact) + proto.management.SendContactInfo.ContactOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return proto.management.ManagementProtos.internal_static_management_SendContactInfo_Contact_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return proto.management.ManagementProtos.internal_static_management_SendContactInfo_Contact_fieldAccessorTable + .ensureFieldAccessorsInitialized( + proto.management.SendContactInfo.Contact.class, proto.management.SendContactInfo.Contact.Builder.class); + } + + // Construct using proto.management.SendContactInfo.Contact.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + username_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + world_ = 0; + bitField0_ = (bitField0_ & ~0x00000002); + rank_ = 0; + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return proto.management.ManagementProtos.internal_static_management_SendContactInfo_Contact_descriptor; + } + + @java.lang.Override + public proto.management.SendContactInfo.Contact getDefaultInstanceForType() { + return proto.management.SendContactInfo.Contact.getDefaultInstance(); + } + + @java.lang.Override + public proto.management.SendContactInfo.Contact build() { + proto.management.SendContactInfo.Contact result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public proto.management.SendContactInfo.Contact buildPartial() { + proto.management.SendContactInfo.Contact result = new proto.management.SendContactInfo.Contact(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + to_bitField0_ |= 0x00000001; + } + result.username_ = username_; + if (((from_bitField0_ & 0x00000002) != 0)) { + result.world_ = world_; + to_bitField0_ |= 0x00000002; + } + if (((from_bitField0_ & 0x00000004) != 0)) { + result.rank_ = rank_; + to_bitField0_ |= 0x00000004; + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof proto.management.SendContactInfo.Contact) { + return mergeFrom((proto.management.SendContactInfo.Contact)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(proto.management.SendContactInfo.Contact other) { + if (other == proto.management.SendContactInfo.Contact.getDefaultInstance()) return this; + if (other.hasUsername()) { + bitField0_ |= 0x00000001; + username_ = other.username_; + onChanged(); + } + if (other.hasWorld()) { + setWorld(other.getWorld()); + } + if (other.hasRank()) { + setRank(other.getRank()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (!hasUsername()) { + return false; + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + proto.management.SendContactInfo.Contact parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (proto.management.SendContactInfo.Contact) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private java.lang.Object username_ = ""; + /** + * required string username = 1; + * @return Whether the username field is set. + */ + public boolean hasUsername() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required string username = 1; + * @return The username. + */ + public java.lang.String getUsername() { + java.lang.Object ref = username_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + username_ = s; + } + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string username = 1; + * @return The bytes for username. + */ + public com.google.protobuf.ByteString + getUsernameBytes() { + java.lang.Object ref = username_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + username_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string username = 1; + * @param value The username to set. + * @return This builder for chaining. + */ + public Builder setUsername( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + username_ = value; + onChanged(); + return this; + } + /** + * required string username = 1; + * @return This builder for chaining. + */ + public Builder clearUsername() { + bitField0_ = (bitField0_ & ~0x00000001); + username_ = getDefaultInstance().getUsername(); + onChanged(); + return this; + } + /** + * required string username = 1; + * @param value The bytes for username to set. + * @return This builder for chaining. + */ + public Builder setUsernameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + username_ = value; + onChanged(); + return this; + } + + private int world_ ; + /** + * optional int32 world = 2; + * @return Whether the world field is set. + */ + @java.lang.Override + public boolean hasWorld() { + return ((bitField0_ & 0x00000002) != 0); + } + /** + * optional int32 world = 2; + * @return The world. + */ + @java.lang.Override + public int getWorld() { + return world_; + } + /** + * optional int32 world = 2; + * @param value The world to set. + * @return This builder for chaining. + */ + public Builder setWorld(int value) { + bitField0_ |= 0x00000002; + world_ = value; + onChanged(); + return this; + } + /** + * optional int32 world = 2; + * @return This builder for chaining. + */ + public Builder clearWorld() { + bitField0_ = (bitField0_ & ~0x00000002); + world_ = 0; + onChanged(); + return this; + } + + private int rank_ ; + /** + * optional int32 rank = 3; + * @return Whether the rank field is set. + */ + @java.lang.Override + public boolean hasRank() { + return ((bitField0_ & 0x00000004) != 0); + } + /** + * optional int32 rank = 3; + * @return The rank. + */ + @java.lang.Override + public int getRank() { + return rank_; + } + /** + * optional int32 rank = 3; + * @param value The rank to set. + * @return This builder for chaining. + */ + public Builder setRank(int value) { + bitField0_ |= 0x00000004; + rank_ = value; + onChanged(); + return this; + } + /** + * optional int32 rank = 3; + * @return This builder for chaining. + */ + public Builder clearRank() { + bitField0_ = (bitField0_ & ~0x00000004); + rank_ = 0; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:management.SendContactInfo.Contact) + } + + // @@protoc_insertion_point(class_scope:management.SendContactInfo.Contact) + private static final proto.management.SendContactInfo.Contact DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new proto.management.SendContactInfo.Contact(); + } + + public static proto.management.SendContactInfo.Contact getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public Contact parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new Contact(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public proto.management.SendContactInfo.Contact getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + private int bitField0_; + public static final int USERNAME_FIELD_NUMBER = 1; + private volatile java.lang.Object username_; + /** + * required string username = 1; + * @return Whether the username field is set. + */ + @java.lang.Override + public boolean hasUsername() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required string username = 1; + * @return The username. + */ + @java.lang.Override + public java.lang.String getUsername() { + java.lang.Object ref = username_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + username_ = s; + } + return s; + } + } + /** + * required string username = 1; + * @return The bytes for username. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getUsernameBytes() { + java.lang.Object ref = username_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + username_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int CONTACTS_FIELD_NUMBER = 2; + private java.util.List contacts_; + /** + * repeated .management.SendContactInfo.Contact contacts = 2; + */ + @java.lang.Override + public java.util.List getContactsList() { + return contacts_; + } + /** + * repeated .management.SendContactInfo.Contact contacts = 2; + */ + @java.lang.Override + public java.util.List + getContactsOrBuilderList() { + return contacts_; + } + /** + * repeated .management.SendContactInfo.Contact contacts = 2; + */ + @java.lang.Override + public int getContactsCount() { + return contacts_.size(); + } + /** + * repeated .management.SendContactInfo.Contact contacts = 2; + */ + @java.lang.Override + public proto.management.SendContactInfo.Contact getContacts(int index) { + return contacts_.get(index); + } + /** + * repeated .management.SendContactInfo.Contact contacts = 2; + */ + @java.lang.Override + public proto.management.SendContactInfo.ContactOrBuilder getContactsOrBuilder( + int index) { + return contacts_.get(index); + } + + public static final int BLOCKED_FIELD_NUMBER = 3; + private com.google.protobuf.LazyStringList blocked_; + /** + * repeated string blocked = 3; + * @return A list containing the blocked. + */ + public com.google.protobuf.ProtocolStringList + getBlockedList() { + return blocked_; + } + /** + * repeated string blocked = 3; + * @return The count of blocked. + */ + public int getBlockedCount() { + return blocked_.size(); + } + /** + * repeated string blocked = 3; + * @param index The index of the element to return. + * @return The blocked at the given index. + */ + public java.lang.String getBlocked(int index) { + return blocked_.get(index); + } + /** + * repeated string blocked = 3; + * @param index The index of the value to return. + * @return The bytes of the blocked at the given index. + */ + public com.google.protobuf.ByteString + getBlockedBytes(int index) { + return blocked_.getByteString(index); + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (!hasUsername()) { + memoizedIsInitialized = 0; + return false; + } + for (int i = 0; i < getContactsCount(); i++) { + if (!getContacts(i).isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (((bitField0_ & 0x00000001) != 0)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 1, username_); + } + for (int i = 0; i < contacts_.size(); i++) { + output.writeMessage(2, contacts_.get(i)); + } + for (int i = 0; i < blocked_.size(); i++) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 3, blocked_.getRaw(i)); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) != 0)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, username_); + } + for (int i = 0; i < contacts_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(2, contacts_.get(i)); + } + { + int dataSize = 0; + for (int i = 0; i < blocked_.size(); i++) { + dataSize += computeStringSizeNoTag(blocked_.getRaw(i)); + } + size += dataSize; + size += 1 * getBlockedList().size(); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof proto.management.SendContactInfo)) { + return super.equals(obj); + } + proto.management.SendContactInfo other = (proto.management.SendContactInfo) obj; + + if (hasUsername() != other.hasUsername()) return false; + if (hasUsername()) { + if (!getUsername() + .equals(other.getUsername())) return false; + } + if (!getContactsList() + .equals(other.getContactsList())) return false; + if (!getBlockedList() + .equals(other.getBlockedList())) return false; + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasUsername()) { + hash = (37 * hash) + USERNAME_FIELD_NUMBER; + hash = (53 * hash) + getUsername().hashCode(); + } + if (getContactsCount() > 0) { + hash = (37 * hash) + CONTACTS_FIELD_NUMBER; + hash = (53 * hash) + getContactsList().hashCode(); + } + if (getBlockedCount() > 0) { + hash = (37 * hash) + BLOCKED_FIELD_NUMBER; + hash = (53 * hash) + getBlockedList().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static proto.management.SendContactInfo parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.SendContactInfo parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.SendContactInfo parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.SendContactInfo parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.SendContactInfo parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static proto.management.SendContactInfo parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static proto.management.SendContactInfo parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static proto.management.SendContactInfo parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static proto.management.SendContactInfo parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static proto.management.SendContactInfo parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static proto.management.SendContactInfo parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static proto.management.SendContactInfo parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(proto.management.SendContactInfo prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code management.SendContactInfo} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:management.SendContactInfo) + proto.management.SendContactInfoOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return proto.management.ManagementProtos.internal_static_management_SendContactInfo_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return proto.management.ManagementProtos.internal_static_management_SendContactInfo_fieldAccessorTable + .ensureFieldAccessorsInitialized( + proto.management.SendContactInfo.class, proto.management.SendContactInfo.Builder.class); + } + + // Construct using proto.management.SendContactInfo.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + getContactsFieldBuilder(); + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + username_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + if (contactsBuilder_ == null) { + contacts_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000002); + } else { + contactsBuilder_.clear(); + } + blocked_ = com.google.protobuf.LazyStringArrayList.EMPTY; + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return proto.management.ManagementProtos.internal_static_management_SendContactInfo_descriptor; + } + + @java.lang.Override + public proto.management.SendContactInfo getDefaultInstanceForType() { + return proto.management.SendContactInfo.getDefaultInstance(); + } + + @java.lang.Override + public proto.management.SendContactInfo build() { + proto.management.SendContactInfo result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public proto.management.SendContactInfo buildPartial() { + proto.management.SendContactInfo result = new proto.management.SendContactInfo(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) != 0)) { + to_bitField0_ |= 0x00000001; + } + result.username_ = username_; + if (contactsBuilder_ == null) { + if (((bitField0_ & 0x00000002) != 0)) { + contacts_ = java.util.Collections.unmodifiableList(contacts_); + bitField0_ = (bitField0_ & ~0x00000002); + } + result.contacts_ = contacts_; + } else { + result.contacts_ = contactsBuilder_.build(); + } + if (((bitField0_ & 0x00000004) != 0)) { + blocked_ = blocked_.getUnmodifiableView(); + bitField0_ = (bitField0_ & ~0x00000004); + } + result.blocked_ = blocked_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof proto.management.SendContactInfo) { + return mergeFrom((proto.management.SendContactInfo)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(proto.management.SendContactInfo other) { + if (other == proto.management.SendContactInfo.getDefaultInstance()) return this; + if (other.hasUsername()) { + bitField0_ |= 0x00000001; + username_ = other.username_; + onChanged(); + } + if (contactsBuilder_ == null) { + if (!other.contacts_.isEmpty()) { + if (contacts_.isEmpty()) { + contacts_ = other.contacts_; + bitField0_ = (bitField0_ & ~0x00000002); + } else { + ensureContactsIsMutable(); + contacts_.addAll(other.contacts_); + } + onChanged(); + } + } else { + if (!other.contacts_.isEmpty()) { + if (contactsBuilder_.isEmpty()) { + contactsBuilder_.dispose(); + contactsBuilder_ = null; + contacts_ = other.contacts_; + bitField0_ = (bitField0_ & ~0x00000002); + contactsBuilder_ = + com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ? + getContactsFieldBuilder() : null; + } else { + contactsBuilder_.addAllMessages(other.contacts_); + } + } + } + if (!other.blocked_.isEmpty()) { + if (blocked_.isEmpty()) { + blocked_ = other.blocked_; + bitField0_ = (bitField0_ & ~0x00000004); + } else { + ensureBlockedIsMutable(); + blocked_.addAll(other.blocked_); + } + onChanged(); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + if (!hasUsername()) { + return false; + } + for (int i = 0; i < getContactsCount(); i++) { + if (!getContacts(i).isInitialized()) { + return false; + } + } + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + proto.management.SendContactInfo parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (proto.management.SendContactInfo) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private java.lang.Object username_ = ""; + /** + * required string username = 1; + * @return Whether the username field is set. + */ + public boolean hasUsername() { + return ((bitField0_ & 0x00000001) != 0); + } + /** + * required string username = 1; + * @return The username. + */ + public java.lang.String getUsername() { + java.lang.Object ref = username_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + username_ = s; + } + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * required string username = 1; + * @return The bytes for username. + */ + public com.google.protobuf.ByteString + getUsernameBytes() { + java.lang.Object ref = username_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + username_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * required string username = 1; + * @param value The username to set. + * @return This builder for chaining. + */ + public Builder setUsername( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + username_ = value; + onChanged(); + return this; + } + /** + * required string username = 1; + * @return This builder for chaining. + */ + public Builder clearUsername() { + bitField0_ = (bitField0_ & ~0x00000001); + username_ = getDefaultInstance().getUsername(); + onChanged(); + return this; + } + /** + * required string username = 1; + * @param value The bytes for username to set. + * @return This builder for chaining. + */ + public Builder setUsernameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + username_ = value; + onChanged(); + return this; + } + + private java.util.List contacts_ = + java.util.Collections.emptyList(); + private void ensureContactsIsMutable() { + if (!((bitField0_ & 0x00000002) != 0)) { + contacts_ = new java.util.ArrayList(contacts_); + bitField0_ |= 0x00000002; + } + } + + private com.google.protobuf.RepeatedFieldBuilderV3< + proto.management.SendContactInfo.Contact, proto.management.SendContactInfo.Contact.Builder, proto.management.SendContactInfo.ContactOrBuilder> contactsBuilder_; + + /** + * repeated .management.SendContactInfo.Contact contacts = 2; + */ + public java.util.List getContactsList() { + if (contactsBuilder_ == null) { + return java.util.Collections.unmodifiableList(contacts_); + } else { + return contactsBuilder_.getMessageList(); + } + } + /** + * repeated .management.SendContactInfo.Contact contacts = 2; + */ + public int getContactsCount() { + if (contactsBuilder_ == null) { + return contacts_.size(); + } else { + return contactsBuilder_.getCount(); + } + } + /** + * repeated .management.SendContactInfo.Contact contacts = 2; + */ + public proto.management.SendContactInfo.Contact getContacts(int index) { + if (contactsBuilder_ == null) { + return contacts_.get(index); + } else { + return contactsBuilder_.getMessage(index); + } + } + /** + * repeated .management.SendContactInfo.Contact contacts = 2; + */ + public Builder setContacts( + int index, proto.management.SendContactInfo.Contact value) { + if (contactsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureContactsIsMutable(); + contacts_.set(index, value); + onChanged(); + } else { + contactsBuilder_.setMessage(index, value); + } + return this; + } + /** + * repeated .management.SendContactInfo.Contact contacts = 2; + */ + public Builder setContacts( + int index, proto.management.SendContactInfo.Contact.Builder builderForValue) { + if (contactsBuilder_ == null) { + ensureContactsIsMutable(); + contacts_.set(index, builderForValue.build()); + onChanged(); + } else { + contactsBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .management.SendContactInfo.Contact contacts = 2; + */ + public Builder addContacts(proto.management.SendContactInfo.Contact value) { + if (contactsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureContactsIsMutable(); + contacts_.add(value); + onChanged(); + } else { + contactsBuilder_.addMessage(value); + } + return this; + } + /** + * repeated .management.SendContactInfo.Contact contacts = 2; + */ + public Builder addContacts( + int index, proto.management.SendContactInfo.Contact value) { + if (contactsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureContactsIsMutable(); + contacts_.add(index, value); + onChanged(); + } else { + contactsBuilder_.addMessage(index, value); + } + return this; + } + /** + * repeated .management.SendContactInfo.Contact contacts = 2; + */ + public Builder addContacts( + proto.management.SendContactInfo.Contact.Builder builderForValue) { + if (contactsBuilder_ == null) { + ensureContactsIsMutable(); + contacts_.add(builderForValue.build()); + onChanged(); + } else { + contactsBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * repeated .management.SendContactInfo.Contact contacts = 2; + */ + public Builder addContacts( + int index, proto.management.SendContactInfo.Contact.Builder builderForValue) { + if (contactsBuilder_ == null) { + ensureContactsIsMutable(); + contacts_.add(index, builderForValue.build()); + onChanged(); + } else { + contactsBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .management.SendContactInfo.Contact contacts = 2; + */ + public Builder addAllContacts( + java.lang.Iterable values) { + if (contactsBuilder_ == null) { + ensureContactsIsMutable(); + com.google.protobuf.AbstractMessageLite.Builder.addAll( + values, contacts_); + onChanged(); + } else { + contactsBuilder_.addAllMessages(values); + } + return this; + } + /** + * repeated .management.SendContactInfo.Contact contacts = 2; + */ + public Builder clearContacts() { + if (contactsBuilder_ == null) { + contacts_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000002); + onChanged(); + } else { + contactsBuilder_.clear(); + } + return this; + } + /** + * repeated .management.SendContactInfo.Contact contacts = 2; + */ + public Builder removeContacts(int index) { + if (contactsBuilder_ == null) { + ensureContactsIsMutable(); + contacts_.remove(index); + onChanged(); + } else { + contactsBuilder_.remove(index); + } + return this; + } + /** + * repeated .management.SendContactInfo.Contact contacts = 2; + */ + public proto.management.SendContactInfo.Contact.Builder getContactsBuilder( + int index) { + return getContactsFieldBuilder().getBuilder(index); + } + /** + * repeated .management.SendContactInfo.Contact contacts = 2; + */ + public proto.management.SendContactInfo.ContactOrBuilder getContactsOrBuilder( + int index) { + if (contactsBuilder_ == null) { + return contacts_.get(index); } else { + return contactsBuilder_.getMessageOrBuilder(index); + } + } + /** + * repeated .management.SendContactInfo.Contact contacts = 2; + */ + public java.util.List + getContactsOrBuilderList() { + if (contactsBuilder_ != null) { + return contactsBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(contacts_); + } + } + /** + * repeated .management.SendContactInfo.Contact contacts = 2; + */ + public proto.management.SendContactInfo.Contact.Builder addContactsBuilder() { + return getContactsFieldBuilder().addBuilder( + proto.management.SendContactInfo.Contact.getDefaultInstance()); + } + /** + * repeated .management.SendContactInfo.Contact contacts = 2; + */ + public proto.management.SendContactInfo.Contact.Builder addContactsBuilder( + int index) { + return getContactsFieldBuilder().addBuilder( + index, proto.management.SendContactInfo.Contact.getDefaultInstance()); + } + /** + * repeated .management.SendContactInfo.Contact contacts = 2; + */ + public java.util.List + getContactsBuilderList() { + return getContactsFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilderV3< + proto.management.SendContactInfo.Contact, proto.management.SendContactInfo.Contact.Builder, proto.management.SendContactInfo.ContactOrBuilder> + getContactsFieldBuilder() { + if (contactsBuilder_ == null) { + contactsBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3< + proto.management.SendContactInfo.Contact, proto.management.SendContactInfo.Contact.Builder, proto.management.SendContactInfo.ContactOrBuilder>( + contacts_, + ((bitField0_ & 0x00000002) != 0), + getParentForChildren(), + isClean()); + contacts_ = null; + } + return contactsBuilder_; + } + + private com.google.protobuf.LazyStringList blocked_ = com.google.protobuf.LazyStringArrayList.EMPTY; + private void ensureBlockedIsMutable() { + if (!((bitField0_ & 0x00000004) != 0)) { + blocked_ = new com.google.protobuf.LazyStringArrayList(blocked_); + bitField0_ |= 0x00000004; + } + } + /** + * repeated string blocked = 3; + * @return A list containing the blocked. + */ + public com.google.protobuf.ProtocolStringList + getBlockedList() { + return blocked_.getUnmodifiableView(); + } + /** + * repeated string blocked = 3; + * @return The count of blocked. + */ + public int getBlockedCount() { + return blocked_.size(); + } + /** + * repeated string blocked = 3; + * @param index The index of the element to return. + * @return The blocked at the given index. + */ + public java.lang.String getBlocked(int index) { + return blocked_.get(index); + } + /** + * repeated string blocked = 3; + * @param index The index of the value to return. + * @return The bytes of the blocked at the given index. + */ + public com.google.protobuf.ByteString + getBlockedBytes(int index) { + return blocked_.getByteString(index); + } + /** + * repeated string blocked = 3; + * @param index The index to set the value at. + * @param value The blocked to set. + * @return This builder for chaining. + */ + public Builder setBlocked( + int index, java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + ensureBlockedIsMutable(); + blocked_.set(index, value); + onChanged(); + return this; + } + /** + * repeated string blocked = 3; + * @param value The blocked to add. + * @return This builder for chaining. + */ + public Builder addBlocked( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + ensureBlockedIsMutable(); + blocked_.add(value); + onChanged(); + return this; + } + /** + * repeated string blocked = 3; + * @param values The blocked to add. + * @return This builder for chaining. + */ + public Builder addAllBlocked( + java.lang.Iterable values) { + ensureBlockedIsMutable(); + com.google.protobuf.AbstractMessageLite.Builder.addAll( + values, blocked_); + onChanged(); + return this; + } + /** + * repeated string blocked = 3; + * @return This builder for chaining. + */ + public Builder clearBlocked() { + blocked_ = com.google.protobuf.LazyStringArrayList.EMPTY; + bitField0_ = (bitField0_ & ~0x00000004); + onChanged(); + return this; + } + /** + * repeated string blocked = 3; + * @param value The bytes of the blocked to add. + * @return This builder for chaining. + */ + public Builder addBlockedBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureBlockedIsMutable(); + blocked_.add(value); + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:management.SendContactInfo) + } + + // @@protoc_insertion_point(class_scope:management.SendContactInfo) + private static final proto.management.SendContactInfo DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new proto.management.SendContactInfo(); + } + + public static proto.management.SendContactInfo getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + @java.lang.Deprecated public static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public SendContactInfo parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new SendContactInfo(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public proto.management.SendContactInfo getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + +} + diff --git a/Server/src/main/proto/management/SendContactInfoOrBuilder.java b/Server/src/main/proto/management/SendContactInfoOrBuilder.java new file mode 100644 index 0000000..0c61cd7 --- /dev/null +++ b/Server/src/main/proto/management/SendContactInfoOrBuilder.java @@ -0,0 +1,75 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: Management.proto + +package proto.management; + +public interface SendContactInfoOrBuilder extends + // @@protoc_insertion_point(interface_extends:management.SendContactInfo) + com.google.protobuf.MessageOrBuilder { + + /** + * required string username = 1; + * @return Whether the username field is set. + */ + boolean hasUsername(); + /** + * required string username = 1; + * @return The username. + */ + java.lang.String getUsername(); + /** + * required string username = 1; + * @return The bytes for username. + */ + com.google.protobuf.ByteString + getUsernameBytes(); + + /** + * repeated .management.SendContactInfo.Contact contacts = 2; + */ + java.util.List + getContactsList(); + /** + * repeated .management.SendContactInfo.Contact contacts = 2; + */ + proto.management.SendContactInfo.Contact getContacts(int index); + /** + * repeated .management.SendContactInfo.Contact contacts = 2; + */ + int getContactsCount(); + /** + * repeated .management.SendContactInfo.Contact contacts = 2; + */ + java.util.List + getContactsOrBuilderList(); + /** + * repeated .management.SendContactInfo.Contact contacts = 2; + */ + proto.management.SendContactInfo.ContactOrBuilder getContactsOrBuilder( + int index); + + /** + * repeated string blocked = 3; + * @return A list containing the blocked. + */ + java.util.List + getBlockedList(); + /** + * repeated string blocked = 3; + * @return The count of blocked. + */ + int getBlockedCount(); + /** + * repeated string blocked = 3; + * @param index The index of the element to return. + * @return The blocked at the given index. + */ + java.lang.String getBlocked(int index); + /** + * repeated string blocked = 3; + * @param index The index of the value to return. + * @return The bytes of the blocked at the given index. + */ + com.google.protobuf.ByteString + getBlockedBytes(int index); +} diff --git a/Server/src/test/kotlin/APITests.kt b/Server/src/test/kotlin/APITests.kt new file mode 100644 index 0000000..e76e858 --- /dev/null +++ b/Server/src/test/kotlin/APITests.kt @@ -0,0 +1,373 @@ +import content.data.consumables.Consumables +import core.api.IfaceSettingsBuilder +import core.api.splitLines +import content.global.skill.slayer.Master +import content.global.skill.slayer.SlayerManager +import content.global.skill.slayer.Tasks +import core.game.node.item.Item +import core.api.utils.Vector +import core.game.world.map.Direction +import org.json.simple.JSONObject +import org.json.simple.parser.JSONParser +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test +import org.rs09.consts.Items + +class APITests { + var testPlayer: MockPlayer + var testPlayer2: MockPlayer + + init { + TestUtils.preTestSetup() + testPlayer = TestUtils.getMockPlayer("test") + testPlayer2 = TestUtils.getMockPlayer("test2") + } + + @Test fun testIfaceSettings(){ + var builder = IfaceSettingsBuilder() + val testOptions = builder.enableOptions(0..9).build() + Assertions.assertEquals(2046, testOptions, "Testing option flags") + + builder = IfaceSettingsBuilder() + val testSlotSwitch = builder.enableSlotSwitch().build() + Assertions.assertEquals(2097152, testSlotSwitch, "Testing slot switch flag") + + builder = IfaceSettingsBuilder() + val testNullSlot = builder.enableNullSlotSwitch().build() + Assertions.assertEquals(8388608, testNullSlot, "Testing null slotswitch flag") + + builder = IfaceSettingsBuilder() + val testUseWithFlags = builder.setUseOnSettings(true, true, true, true, true, true).build() + Assertions.assertEquals(129024, testUseWithFlags, "Testing usewith flags") + + builder = IfaceSettingsBuilder() + val testIfaceDepth = builder.setInterfaceEventsDepth(2).build() + Assertions.assertEquals(2 shl 18, testIfaceDepth and 1835008, "Testing events depth") + + builder = IfaceSettingsBuilder() + val testUseOption = builder.enableUseOption().build() + Assertions.assertEquals(1 shl 17, testUseOption, "Testing use option") + + builder = IfaceSettingsBuilder() + val testUseOnSelf = builder.enableUseOnSelf().build() + Assertions.assertEquals(1 shl 22, testUseOnSelf, "Testing use on self flag") + + builder = IfaceSettingsBuilder() + val testAllOptions = builder + .enableAllOptions() + .enableExamine() + .enableNullSlotSwitch() + .enableSlotSwitch() + .enableUseOnSelf() + .enableUseOption() + .setInterfaceEventsDepth(2) + .setUseOnSettings(true, true, true, true, true, true) + .build() + Assertions.assertEquals(15466494, testAllOptions, "Testing all options") + } + + @Test fun testSlayerManagerSaveAndLoadAndSaveProducesEquivalentJSON() { + var manager = SlayerManager() + manager.login(testPlayer) + manager.login(testPlayer2) + manager = SlayerManager.getInstance(testPlayer) + manager.flags.setPoints(20) + manager.flags.setMaster(Master.CHAELDAR) + manager.flags.setTask(Tasks.SKELETAL_WYVERN) + manager.flags.setTaskAmount(500) + + val manager2 = SlayerManager.getInstance(testPlayer2) + + val jsonFirst = JSONObject() + manager.savePlayer(testPlayer, jsonFirst) + manager.parsePlayer(testPlayer2, jsonFirst) + + val jsonSecond = JSONObject() + manager2.savePlayer(testPlayer2, jsonSecond) + Assertions.assertEquals(jsonFirst.toJSONString(), jsonSecond.toJSONString()) + } + + @Test fun testSlayerSaveAndParseProducesEquivalent() { + var manager = SlayerManager() + manager.login(testPlayer) + manager = SlayerManager.getInstance(testPlayer) + manager.flags.setPoints(500) + manager.flags.unlockHelm() + manager.flags.unlockBroads() + manager.flags.unlockRing() + + val json = JSONObject() + manager.savePlayer(testPlayer, json) + manager.flags.fullClear() + manager.parsePlayer(testPlayer, json) + Assertions.assertEquals(500, manager.flags.getPoints(), "Points were not 500!") + Assertions.assertEquals(true, manager.flags.isHelmUnlocked(), "Helm was not unlocked!") + Assertions.assertEquals(true, manager.flags.isBroadsUnlocked(), "Broads were not unlocked!") + Assertions.assertEquals(true, manager.flags.isRingUnlocked(), "Ring was not unlocked!") + } + + @Test fun testSlayerDecrementTaskAmountHasNoSideEffects() { + var manager = SlayerManager() + manager.login(testPlayer) + manager = SlayerManager.getInstance(testPlayer) + manager.flags.setTask(Tasks.CAVE_BUG) + manager.flags.setTaskAmount(100) + manager.flags.taskStreak = 4 + manager.flags.completedTasks = 4 + manager.flags.setMaster(Master.MAZCHNA) + + while(manager.hasTask()) manager.decrementAmount(1) + manager.flags.taskStreak += 1 + manager.flags.completedTasks += 1 + manager.flags.flagCanEarnPoints() + + Assertions.assertEquals(0, manager.flags.getTaskAmount(), "Task amount was not 0!") + Assertions.assertEquals(5, manager.flags.taskStreak, "Task streak was not 5!") + Assertions.assertEquals(Tasks.CAVE_BUG, manager.flags.getTask(), "Task was not cave bugs!") + Assertions.assertEquals(Master.MAZCHNA, manager.flags.getMaster(), "Master was not Mazchna!") + } + + @Test fun testKnownProblemSaveParsesCorrectly() { + val jsonString = "{\"slayer\": {\n" + + " \"taskStreak\": \"21\",\n" + + " \"rewardFlags\": 17301511,\n" + + " \"equipmentFlags\": 31,\n" + + " \"taskFlags\": 307220,\n" + + " \"removedTasks\": [\n" + + " \"73\"\n" + + " ],\n" + + " \"totalTasks\": \"108\"\n" + + " }}" + + val slayerData = JSONParser().parse(jsonString) as JSONObject + var manager = SlayerManager() + manager.login(testPlayer) + manager = SlayerManager.getInstance(testPlayer) + manager.parsePlayer(testPlayer, slayerData) + + Assertions.assertEquals(21, manager.flags.taskStreak) + Assertions.assertNotEquals(0, manager.flags.getPoints()) + Assertions.assertEquals(true, manager.flags.isHelmUnlocked()) + } + + @Test fun lineSplitShouldSplitAtLimitAndPreserveAllWords() { + var testCase = "The monks are running a ship from Port Sarim to Entrana, I hear too. Now leave me alone yer elephant!" + var expectedLine1 = "The monks are running a ship from Port Sarim to" + var expectedLine2 = "Entrana, I hear too. Now leave me alone yer elephant!" + var lines = splitLines(testCase, 54) + Assertions.assertEquals(expectedLine1, lines.getOrNull(0) ?: "") + Assertions.assertEquals(expectedLine2, lines.getOrNull(1) ?: "") + Assertions.assertEquals(2, lines.size) + + testCase = "Dramenwood staffs are crafted from branches of the Dramen tree, so they are. I hear there's a Dramen tree over on the island of Entrana in a cave." + expectedLine1 = "Dramenwood staffs are crafted from branches of the" + expectedLine2 = "Dramen tree, so they are. I hear there's a Dramen tree" + var expectedLine3 = "over on the island of Entrana in a cave." + lines = splitLines(testCase, 54) + Assertions.assertEquals(expectedLine1, lines.getOrNull(0) ?: "") + Assertions.assertEquals(expectedLine2, lines.getOrNull(1) ?: "") + Assertions.assertEquals(expectedLine3, lines.getOrNull(2) ?: "") + Assertions.assertEquals(3, lines.size) + + testCase = "This should be one line." + lines = splitLines(testCase) + Assertions.assertEquals(testCase, lines[0]) + Assertions.assertEquals(1, lines.size) + + testCase = "I just told you: from the Seer. You will need to persuade him to take the time to make a forecast somehow." + lines = splitLines(testCase) + expectedLine1 = "I just told you: from the Seer. You will need to" + expectedLine2 = "persuade him to take the time to make a forecast" + expectedLine3 = "somehow." + Assertions.assertEquals(expectedLine1, lines.getOrNull(0) ?: "") + Assertions.assertEquals(expectedLine2, lines.getOrNull(1) ?: "") + Assertions.assertEquals(expectedLine3, lines.getOrNull(2) ?: "") + } + + @Test fun consumableStackableItemShouldNotRemoveStack() { + val stackableItem = Item(Items.PURPLE_SWEETS_10476, 999) + TestUtils.getMockPlayer("Inventory Consumable Stack Slot Tester").use { player -> + // Inventory setup + player.inventory.clear() + player.inventory.add(stackableItem, false, 0) + + // Setup + val consumable = Consumables.getConsumableById(stackableItem.id) + consumable.consumable.consume(player.inventory.get(0), player) + TestUtils.advanceTicks(2, false) + + // Get item in that slot, + val updatedConsumable = player.inventory.get(0) + + // Maintains slot clicked + Amount is decremented + Assertions.assertEquals(0, updatedConsumable.slot) + Assertions.assertEquals(998, updatedConsumable.amount) + } + } + + @Test fun consumableMultiPieceItemShouldBeRemovedFromCorrectSlot() { + val consumables: Array = arrayOf( + Item(Items.CAKE_1891, 8), + Item(Items.TWO_THIRDS_CAKE_1893, 8), + Item(Items.SLICE_OF_CAKE_1895, 8) + ) + + TestUtils.getMockPlayer("Inventory Consumable Multi Piece Tester").use { player -> + // Inventory setup + player.inventory.clear() + player.inventory.add(*consumables) + + val lastWholeCakeContainerIndex = 7 + val lastWholeCake = player.inventory.get(lastWholeCakeContainerIndex) + + val consumable = Consumables.getConsumableById(lastWholeCake.id) + consumable.consumable.consume(player.inventory.get(lastWholeCakeContainerIndex), player) + TestUtils.advanceTicks(2, false) + + // Cake amounts are correct + val wholeCakeAmount = player.inventory.getAmount(Items.CAKE_1891) + val twoThirdsCakeAmount = player.inventory.getAmount(Items.TWO_THIRDS_CAKE_1893) + Assertions.assertEquals(7, wholeCakeAmount) + Assertions.assertEquals(9, twoThirdsCakeAmount) + + // Cake was replaced in correct spot + val inventorySlot0 = player.inventory.get(0) + val inventorySlot7 = player.inventory.get(7) + Assertions.assertEquals(Items.CAKE_1891, inventorySlot0.id) + Assertions.assertEquals(Items.TWO_THIRDS_CAKE_1893, inventorySlot7.id) + } + } + + @Test fun consumableMultiPieceItemShouldAddReturnItemToCorrectSlot() { + val PIE_DISH_NONCONSUMABLE_2313 = Items.PIE_DISH_2313 + val consumables: Array = arrayOf( + Item(Items.APPLE_PIE_2323, 8), + Item(Items.HALF_AN_APPLE_PIE_2335, 8), + Item(Items.REDBERRY_PIE_2325, 8) + ) + + TestUtils.getMockPlayer("Inventory Consumable Multi Piece With Return Tester").use { player -> + // Inventory setup + player.inventory.clear() + player.inventory.add(*consumables) + + val lastWholePieContainerIndex = 7 + val lastWholePie = player.inventory.get(lastWholePieContainerIndex) + + val wholePieConsumable = Consumables.getConsumableById(lastWholePie.id) + wholePieConsumable.consumable.consume(player.inventory.get(lastWholePieContainerIndex), player) + TestUtils.advanceTicks(2, false) + + // Pie amounts are correct + var wholePieAmount = player.inventory.getAmount(Items.APPLE_PIE_2323) + var halfPieAmount = player.inventory.getAmount(Items.HALF_AN_APPLE_PIE_2335) + Assertions.assertEquals(7, wholePieAmount) + Assertions.assertEquals(9, halfPieAmount) + + // Pie was replaced in correct spot + val inventorySlot0 = player.inventory.get(0) + val inventorySlot7 = player.inventory.get(7) + Assertions.assertEquals(Items.APPLE_PIE_2323, inventorySlot0.id) + Assertions.assertEquals(Items.HALF_AN_APPLE_PIE_2335, inventorySlot7.id) + + // Tests for pie halves + pie tins + val firstHalfPieContainerIndex = 7 + val firstHalfPie = player.inventory.get(firstHalfPieContainerIndex) + val halfPieConsumable = Consumables.getConsumableById(firstHalfPie.id) + halfPieConsumable.consumable.consume(player.inventory.get(firstHalfPieContainerIndex), player) + TestUtils.advanceTicks(2, false) + + // Pie amounts are correct + halfPieAmount = player.inventory.getAmount(Items.HALF_AN_APPLE_PIE_2335) + val pieDishAmount = player.inventory.getAmount(PIE_DISH_NONCONSUMABLE_2313) + Assertions.assertEquals(8, halfPieAmount) + Assertions.assertEquals(1, pieDishAmount) + + val updatedSlot7 = player.inventory.get(7) + Assertions.assertEquals(PIE_DISH_NONCONSUMABLE_2313, updatedSlot7.id) + } + } + + @Test fun consumableItemShouldNotHaveReturnItem() { + val consumables: Array = arrayOf( + Item(Items.TROUT_333, 8), + Item(Items.SHARK_385, 8), + Item(Items.LOBSTER_379, 8) + ) + TestUtils.getMockPlayer("Inventory Consumable No Return Item Tester").use { player -> + // Inventory setup + player.inventory.clear() + player.inventory.add(*consumables) + + // Feed the player copious amounts of fish + val lastTroutContainerIndex = 7 + val lastTrout = player.inventory.get(lastTroutContainerIndex) + + val troutConsumable = Consumables.getConsumableById(lastTrout.id) + troutConsumable.consumable.consume(player.inventory.get(lastTroutContainerIndex), player) + TestUtils.advanceTicks(4, false) + + val sharkConsumable = Consumables.getConsumableById(Items.SHARK_385) + for (n in 0..7) { + sharkConsumable.consumable.consume(player.inventory.get(n + 8), player) + TestUtils.advanceTicks(4, false) + } + + val lobsterConsumable = Consumables.getConsumableById(Items.LOBSTER_379) + for (n in 16..23 step 2) { + lobsterConsumable.consumable.consume(player.inventory.get(n), player) + TestUtils.advanceTicks(4, false) + } + + // Trout amounts are correct + val troutAmount = player.inventory.getAmount(Items.TROUT_333) + Assertions.assertEquals(7, troutAmount) + + // Trout was removed from the correct spot + val inventorySlot0 = player.inventory.get(0) + val inventorySlot7: Item? = player.inventory.get(7) + Assertions.assertEquals(Items.TROUT_333, inventorySlot0.id) + Assertions.assertNull(inventorySlot7) + + val sharkAmount = player.inventory.getAmount(Items.SHARK_385) + Assertions.assertEquals(0, sharkAmount) + for (n in 8..15) { + val inventoryItem: Item? = player.inventory.get(n) + Assertions.assertNull(inventoryItem) + } + + val lobsterAmount = player.inventory.getAmount(Items.LOBSTER_379) + Assertions.assertEquals(4, lobsterAmount) + + for (n in 16..23) { + if (n % 2 == 0) { + val inventoryItem: Item? = player.inventory.get(n) + Assertions.assertNull(inventoryItem) + } else { + val inventoryItem: Item = player.inventory.get(n) + Assertions.assertEquals(Items.LOBSTER_379, inventoryItem.id) + } + } + } + } + + @Test fun vectorToDirectionShouldReturnExpectedDirections() { + val testData = arrayOf( + Pair(Vector(1.0, 0.0), Direction.EAST), + Pair(Vector(-1.0, 0.0), Direction.WEST), + Pair(Vector(0.0, 1.0), Direction.NORTH), + Pair(Vector(0.0, -1.0), Direction.SOUTH), + Pair(Vector(1.0, 1.0), Direction.NORTH_EAST), + Pair(Vector(1.0, -1.0), Direction.SOUTH_EAST), + Pair(Vector(-1.0, 1.0), Direction.NORTH_WEST), + Pair(Vector(-1.0, -1.0), Direction.SOUTH_WEST), + Pair(Vector(15.0, 0.0), Direction.EAST), + Pair(Vector(15.0, 1.0), Direction.EAST), + Pair(Vector(-15.0, -9.7), Direction.SOUTH_WEST) + ) + + for ((vec, expDir) in testData) { + Assertions.assertEquals(expDir, vec.toDirection(), "Vector: $vec") + } + } +} \ No newline at end of file diff --git a/Server/src/test/kotlin/ExchangeTests.kt b/Server/src/test/kotlin/ExchangeTests.kt new file mode 100644 index 0000000..baac462 --- /dev/null +++ b/Server/src/test/kotlin/ExchangeTests.kt @@ -0,0 +1,206 @@ +import content.global.handlers.iface.ge.StockMarket +import core.game.ge.OfferState +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking +import org.junit.jupiter.api.AfterAll +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.TestInstance +import org.junit.jupiter.api.fail +import core.game.ge.GEDB +import core.game.ge.GrandExchange +import core.game.ge.GrandExchangeOffer +import core.game.ge.PriceIndex +import core.game.node.item.Item +import org.rs09.consts.Items +import java.io.File + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) class ExchangeTests { + companion object { + private const val TEST_DB_PATH = "ge_test.db" + init { + TestUtils.preTestSetup() + GEDB.init(TEST_DB_PATH) + } + + fun generateOffer(itemId: Int, amount: Int, price: Int, sale: Boolean, username: String = "test ${System.currentTimeMillis()}", offerState: OfferState = OfferState.REGISTERED) : GrandExchangeOffer { + val offer = GrandExchangeOffer() + val uid = username.hashCode() // normally this would be the account's uid but in the test we don't have an account + offer.offerState = offerState + offer.itemID = itemId + offer.offeredValue = price + offer.amount = amount + offer.timeStamp = System.currentTimeMillis() + offer.index = 0 + offer.isBot = false + offer.playerUID = uid + offer.sell = sale + offer.writeNew() + return offer + } + + fun generateUnsentOffer (itemId: Int, amount: Int, price: Int, sale: Boolean, username: String, offerState: OfferState = OfferState.PENDING) : GrandExchangeOffer { + val offer = GrandExchangeOffer() + val uid = username.hashCode() // normally this would be the account's uid but in the test we don't have an account + offer.offerState = offerState + offer.itemID = itemId + offer.offeredValue = price + offer.amount = amount + offer.timeStamp = System.currentTimeMillis() + offer.index = 0 + offer.isBot = false + offer.playerUID = uid + offer.sell = sale + offer.uid = 0L + return offer + } + + @AfterAll @JvmStatic fun cleanup() { + File(TEST_DB_PATH).delete() + } + } + + @Test fun testPlaceOffer() { + val offer = generateOffer(4151, 1, 100000, true) + val uid = offer.playerUID + + GEDB.run { conn -> + val stmt = conn.createStatement() + val result = stmt.executeQuery("select * from player_offers where player_uid = $uid") + val thisOffer = if(result.next()) GrandExchangeOffer.fromQuery(result) else fail("Offer did not exist!") + Assertions.assertEquals(offer.itemID, thisOffer.itemID) + } + } + + @Test fun testBuyFirstSellAfterFavorsSell() { + val buyOffer = generateOffer(4151, 1, 100000, false) + val sellOffer = generateOffer(4151, 1, 85000, true) + GrandExchange.exchange(buyOffer, sellOffer) + Assertions.assertEquals(null, buyOffer.withdraw[1], "Buyer got coins back on sell bias") //should get no coins back + } + + @Test fun testSellFirstBuyAfterFavorsBuy() { + val sellOffer = generateOffer(4151, 1, 85000, true) + val buyOffer = generateOffer(4151, 1, 100000, false) + GrandExchange.exchange(sellOffer,buyOffer) + Assertions.assertNotEquals(null, buyOffer.withdraw[1], "Buyer did not get coins back on buy bias") //should get coins back + } + + @Test fun buyerCannotBuyHigherSellOffer() { + val sellOffer = generateOffer(4151, 1, 125000, true) + val buyOffer = generateOffer(4151, 1, 100000, false) + GrandExchange.exchange(sellOffer,buyOffer) + Assertions.assertEquals(null, buyOffer.withdraw[0]) //Buyer should not get any items, sell offer is higher + } + + @Test fun manyCompletedOffersAboveDefaultPriceShouldInfluencePriceUpwards() { + val defaultPrice = GrandExchange.getRecommendedPrice(4151) + val modifiedPrice = defaultPrice * 1.15 + + for(i in 0 until 100) { + val sellOffer = generateOffer(4151, 1, modifiedPrice.toInt(), true, "test1") + val buyOffer = generateOffer(4151, 1, modifiedPrice.toInt(), false, "test2") + GrandExchange.exchange(sellOffer,buyOffer) + } + + val newPrice = GrandExchange.getRecommendedPrice(4151) + + Assertions.assertEquals(true, newPrice > defaultPrice, "Price was not influenced in the expected way! New Price: $newPrice, default: $defaultPrice") + } + + @Test fun playerTradingWithThemselvesShouldNotBeAbleToInfluencePrices() { + val defaultPrice = GrandExchange.getRecommendedPrice(4151) + val modifiedPrice = defaultPrice * 1.15 + + for(i in 0 until 100) { + val sellOffer = generateOffer(4151, 1, modifiedPrice.toInt(), true, "test") + val buyOffer = generateOffer(4151, 1, modifiedPrice.toInt(), false, "test") + GrandExchange.exchange(sellOffer,buyOffer) + } + + Assertions.assertEquals(defaultPrice, GrandExchange.getRecommendedPrice(4151)) + } + + @Test fun concurrentlySubmittedOffersShouldNotThrowExceptions(){ + runBlocking { + val a = GlobalScope.launch { for(i in 0 until 5) { + PriceIndex.allowItem(i); GrandExchange.addBotOffer(i, 1)} } + val b = GlobalScope.launch { for(i in 0 until 5) { + PriceIndex.allowItem(i); GrandExchange.addBotOffer(i, 1)} } + a.join() + b.join() + Assertions.assertEquals(false, a.isCancelled) + Assertions.assertEquals(false, b.isCancelled) + } + } + + @Test fun offerWithCombinedNotedAndUnnotedAmountShouldSuceed() { + TestUtils.getMockPlayer("combinedNotendAndUnnotedExcTest").use { p -> + val offer = generateUnsentOffer(4151, 1000, 1500, true, p.name, OfferState.PENDING) + val mkt = StockMarket() + p.inventory.add(Item(Items.ABYSSAL_WHIP_4151, 10)) + p.inventory.add(Item(Items.ABYSSAL_WHIP_4152, 990)) + Assertions.assertEquals(StockMarket.OfferConfirmResult.Success, mkt.confirmOffer(p, offer, 0)) + Assertions.assertEquals(0, p.inventory.getAmount(4151)) + Assertions.assertEquals(0, p.inventory.getAmount(4152)) + } + } + + @Test fun offerWithOnlyNotedAmountShouldSucceed() { + TestUtils.getMockPlayer("onlyNotedOfferSucceed").use { p -> + val offer = generateUnsentOffer(4151, 1000, 1500, true, p.name, OfferState.PENDING) + val mkt = StockMarket() + p.inventory.add(Item(Items.ABYSSAL_WHIP_4152, 1000)) + Assertions.assertEquals(StockMarket.OfferConfirmResult.Success, mkt.confirmOffer(p, offer, 0)) + Assertions.assertEquals(0, p.inventory.getAmount(4151)) + Assertions.assertEquals(0, p.inventory.getAmount(4152)) + } + } + + @Test fun offerWithMoreUnnotedItemsThanOfferAmountShouldSucceed() { + TestUtils.getMockPlayer("onlyUnnotedOfferWithExtraItemsSucceed").use { p -> + val offer = generateUnsentOffer(4151, 10, 1500, true, p.name, OfferState.PENDING) + val mkt = StockMarket() + p.inventory.add(Item(Items.ABYSSAL_WHIP_4151, 20)) + Assertions.assertEquals(StockMarket.OfferConfirmResult.Success, mkt.confirmOffer(p, offer, 0)) + Assertions.assertEquals(10, p.inventory.getAmount(4151)) + Assertions.assertEquals(0, p.inventory.getAmount(4152)) + } + } + + @Test fun offerWithOnlyUnnotedAmountShouldSucceed() { + TestUtils.getMockPlayer("onlyUnnotedOfferSucceed").use { p -> + val offer = generateUnsentOffer(4151, 10, 1500, true, p.name, OfferState.PENDING) + val mkt = StockMarket() + p.inventory.add(Item(Items.ABYSSAL_WHIP_4151, 10)) + Assertions.assertEquals(StockMarket.OfferConfirmResult.Success, mkt.confirmOffer(p, offer, 0)) + Assertions.assertEquals(0, p.inventory.getAmount(4151)) + Assertions.assertEquals(0, p.inventory.getAmount(4152)) + } + } + + @Test fun offerWithNotEnoughNotedItemsShouldFail() { + TestUtils.getMockPlayer("combinedNotedAndUnnotedFailure").use { p -> + val offer = generateUnsentOffer(4151, 1000, 1500, true, p.name, OfferState.PENDING) + val mkt = StockMarket() + p.inventory.add(Item(Items.ABYSSAL_WHIP_4151, 10)) + p.inventory.add(Item(Items.ABYSSAL_WHIP_4152, 15)) + Assertions.assertEquals(StockMarket.OfferConfirmResult.NotEnoughItemsOrCoins, mkt.confirmOffer(p, offer, 0)) + Assertions.assertEquals(10, p.inventory.getAmount(4151)) + Assertions.assertEquals(15, p.inventory.getAmount(4152)) + } + } + + @Test fun offerWithNotEnoughUnnotedItemsShouldFail() { + TestUtils.getMockPlayer("combinedNotedAndUnnotedFailure2").use { p -> + val offer = generateUnsentOffer(4151, 1000, 1500, true, p.name, OfferState.PENDING) + val mkt = StockMarket() + p.inventory.add(Item(Items.ABYSSAL_WHIP_4151, 10)) + p.inventory.add(Item(Items.ABYSSAL_WHIP_4152, 900)) + Assertions.assertEquals(StockMarket.OfferConfirmResult.NotEnoughItemsOrCoins, mkt.confirmOffer(p, offer, 0)) + Assertions.assertEquals(10, p.inventory.getAmount(4151)) + Assertions.assertEquals(900, p.inventory.getAmount(4152)) + } + } +} diff --git a/Server/src/test/kotlin/ItemDefinitionTests.kt b/Server/src/test/kotlin/ItemDefinitionTests.kt new file mode 100644 index 0000000..3237ea2 --- /dev/null +++ b/Server/src/test/kotlin/ItemDefinitionTests.kt @@ -0,0 +1,54 @@ +package core.cache + +import TestUtils +import core.game.node.item.Item +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test +import org.rs09.consts.Items +import kotlin.math.roundToInt + +class ItemDefinitionTests { + companion object { + init {TestUtils.preTestSetup()} + } + + @Test fun itemHighAlchIs60PercentValueRandomItem1() { + val natureRune = Item(Items.NATURE_RUNE_561) + Assertions.assertEquals((natureRune.definition.value * 0.6).roundToInt(), natureRune.definition.getAlchemyValue(true)) + } + + @Test fun itemHighAlchIs60PercentValueRandomItem2() { + val tuna = Item(Items.TUNA_361) + Assertions.assertEquals((tuna.definition.value * 0.6).roundToInt(), tuna.definition.getAlchemyValue(true)) + } + + @Test fun itemHighAlchIs60PercentValueRandomItem3() { + val bass = Item(Items.BASS_365) + Assertions.assertEquals((bass.definition.value * 0.6).roundToInt(), bass.definition.getAlchemyValue(true)) + } + + @Test fun itemHighAlchIs60PercentValueRandomItem4() { + val goldBar = Item(Items.GOLD_BAR_2357) + Assertions.assertEquals((goldBar.definition.value * 0.6).roundToInt(), goldBar.definition.getAlchemyValue(true)) + } + + @Test fun itemLowAlchIs40PercentValueRandomItem1() { + val natureRune = Item(Items.NATURE_RUNE_561) + Assertions.assertEquals((natureRune.definition.value * 0.4).roundToInt(), natureRune.definition.getAlchemyValue(false), natureRune.name) + } + + @Test fun itemLowAlchIs40PercentValueRandomItem2() { + val tuna = Item(Items.TUNA_361) + Assertions.assertEquals((tuna.definition.value * 0.4).roundToInt(), tuna.definition.getAlchemyValue(false), tuna.name) + } + + @Test fun itemLowAlchIs40PercentValueRandomItem3() { + val bass = Item(Items.BASS_365) + Assertions.assertEquals((bass.definition.value * 0.4).roundToInt(), bass.definition.getAlchemyValue(false), bass.name) + } + + @Test fun itemLowAlchIs40PercentValueRandomItem4() { + val goldBar = Item(Items.GOLD_BAR_2357) + Assertions.assertEquals((goldBar.definition.value * 0.4).roundToInt(), goldBar.definition.getAlchemyValue(false), goldBar.name) + } +} diff --git a/Server/src/test/kotlin/PlayerStatsCounterTests.kt b/Server/src/test/kotlin/PlayerStatsCounterTests.kt new file mode 100644 index 0000000..1b2ce9b --- /dev/null +++ b/Server/src/test/kotlin/PlayerStatsCounterTests.kt @@ -0,0 +1,111 @@ +import core.api.utils.PlayerStatsCounter +import core.game.node.item.Item +import org.junit.jupiter.api.AfterAll +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.TestInstance +import java.io.File + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) class PlayerStatsCounterTests { + companion object { + private const val TEST_DB_PATH = "player_stats_test.db" + private val counter = PlayerStatsCounter(TEST_DB_PATH) + init { + TestUtils.preTestSetup() + counter.startup() + } + @AfterAll @JvmStatic fun cleanup() { + File(TEST_DB_PATH).delete() + } + } + + @Test fun testKillIncrementShouldAddOneKillForNewPlayer() { + val testPlayer = TestUtils.getMockPlayer("test_kill_inc") + val testNPCId = 10 + + val oldKills = PlayerStatsCounter.getKills(testPlayer, IntArray(testNPCId)) + Assertions.assertEquals(0, oldKills) + + PlayerStatsCounter.incrementKills(testPlayer,testNPCId) + + val newKills = PlayerStatsCounter.getKills(testPlayer, intArrayOf(testNPCId)) + Assertions.assertEquals(1, newKills) + } + + @Test fun testGetKillShouldReturnKillsForSinglePlayer() { + val testPlayer = TestUtils.getMockPlayer("kill_single_player_1") + val testPlayer2 = TestUtils.getMockPlayer("kill_single_player_2") + val testNPCId = 10 + + PlayerStatsCounter.incrementKills(testPlayer,testNPCId) + + PlayerStatsCounter.incrementKills(testPlayer2,testNPCId) + PlayerStatsCounter.incrementKills(testPlayer2,testNPCId) + + val kills = PlayerStatsCounter.getKills(testPlayer2, intArrayOf(testNPCId)) + Assertions.assertEquals(2, kills) + } + + @Test fun testGetKillShouldReturnSumForAllNPCsForAGivenPlayer() { + val testPlayer = TestUtils.getMockPlayer("test_sum_npcs") + val testNPCId1 = 10 + val testNPCId2 = 11 + val testNPCId3 = 12 + + PlayerStatsCounter.incrementKills(testPlayer,testNPCId1) + + PlayerStatsCounter.incrementKills(testPlayer,testNPCId2) + PlayerStatsCounter.incrementKills(testPlayer,testNPCId2) + PlayerStatsCounter.incrementKills(testPlayer,testNPCId2) + + PlayerStatsCounter.incrementKills(testPlayer,testNPCId3) + PlayerStatsCounter.incrementKills(testPlayer,testNPCId3) + + val killsForNPCs1And2 = PlayerStatsCounter.getKills(testPlayer, intArrayOf(testNPCId1, testNPCId2)) + Assertions.assertEquals(4, killsForNPCs1And2) + val killsForAllNPCs = PlayerStatsCounter.getKills(testPlayer, intArrayOf(testNPCId1, testNPCId2, testNPCId3)) + Assertions.assertEquals(6, killsForAllNPCs) + } + + @Test fun testRewardIncrementShouldAddOneRewardForNewPlayer() { + val testPlayer = TestUtils.getMockPlayer("test_reward_inc") + val itemId = 10 + + val oldRareDrops = PlayerStatsCounter.getRareDrops(testPlayer, itemId) + Assertions.assertEquals(0, oldRareDrops) + + PlayerStatsCounter.incrementRareDrop(testPlayer, Item(itemId)) + + val newRareDrops = PlayerStatsCounter.getRareDrops(testPlayer, itemId) + Assertions.assertEquals(1, newRareDrops) + } + + @Test fun testGetRewardsShouldReturnRewardsForSinglePlayer() { + val testPlayer = TestUtils.getMockPlayer("reward_single_player_1") + val testPlayer2 = TestUtils.getMockPlayer("reward_single_player_2") + val testItemId = 10 + + PlayerStatsCounter.incrementRareDrop(testPlayer,Item(testItemId)) + + PlayerStatsCounter.incrementRareDrop(testPlayer2,Item(testItemId)) + PlayerStatsCounter.incrementRareDrop(testPlayer2,Item(testItemId)) + + val rareDrops = PlayerStatsCounter.getRareDrops(testPlayer2, testItemId) + Assertions.assertEquals(2, rareDrops) + } + + @Test fun testGetRewardsShouldHonourItemAmountWhenIncrementing() { + val testPlayer = TestUtils.getMockPlayer("test_reward_inc_itemamount") + val itemId = 10 + + val itemAmount: Long = 5 + + val oldRareDrops = PlayerStatsCounter.getRareDrops(testPlayer, itemId) + Assertions.assertEquals(0, oldRareDrops) + + PlayerStatsCounter.incrementRareDrop(testPlayer, Item(itemId, itemAmount.toInt())) + + val newRareDrops = PlayerStatsCounter.getRareDrops(testPlayer, itemId) + Assertions.assertEquals(itemAmount, newRareDrops) + } +} diff --git a/Server/src/test/kotlin/PriceIndexTests.kt b/Server/src/test/kotlin/PriceIndexTests.kt new file mode 100644 index 0000000..f358e30 --- /dev/null +++ b/Server/src/test/kotlin/PriceIndexTests.kt @@ -0,0 +1,37 @@ +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test +import core.game.ge.GEDB +import core.game.ge.PriceIndex + +class PriceIndexTests { + companion object {init {TestUtils.preTestSetup(); GEDB.init("ge_test.db")}} + + @Test fun shouldAllowCheckingIfItemCanBeSoldOnGE() { + PriceIndex.allowItem(4151) + val canSellWhip = PriceIndex.canTrade(4151) + Assertions.assertEquals(true, canSellWhip) + } + + @Test fun shouldAllowBanningItems() { + PriceIndex.allowItem(1333) + Assertions.assertEquals(true, PriceIndex.canTrade(1333)) + PriceIndex.banItem(1333) + Assertions.assertEquals(false, PriceIndex.canTrade(1333)) + } + + @Test fun shouldAllowValueToBeInfluenced() { + PriceIndex.allowItem(1333) + val defaultValue = PriceIndex.getValue(1333) + PriceIndex.addTrade(1333, 100, (defaultValue * 1.15).toInt()) + Assertions.assertNotEquals(defaultValue, PriceIndex.getValue(1333)) + } + + @Test fun shouldAllowValueToGoDownWithHighVolumeOfLowerValueTrades() { + PriceIndex.allowItem(1334) + val defaultValue = PriceIndex.getValue(1334) + PriceIndex.addTrade(1334, 1000, (defaultValue * 1.15).toInt()) + Assertions.assertEquals(true, PriceIndex.getValue(1334) > defaultValue) + PriceIndex.addTrade(1334, 2000, (defaultValue * 0.85).toInt()) + Assertions.assertEquals(true, PriceIndex.getValue(1334) < defaultValue, "Old: $defaultValue, New: ${PriceIndex.getValue(1334)}") + } +} \ No newline at end of file diff --git a/Server/src/test/kotlin/QuestTests.kt b/Server/src/test/kotlin/QuestTests.kt new file mode 100644 index 0000000..0a4fa7b --- /dev/null +++ b/Server/src/test/kotlin/QuestTests.kt @@ -0,0 +1,62 @@ +import content.data.Quests +import core.game.node.entity.player.link.quest.Quest +import core.game.node.entity.player.link.quest.QuestRepository +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test + +class QuestTests { + lateinit var testPlayer: MockPlayer + init { + TestUtils.preTestSetup() + testPlayer = TestUtils.getMockPlayer("test") + } + + class TestQuest : Quest(Quests.TEST_QUEST, 0, 0, 1, 1, 0, 1, 2) { + override fun newInstance(`object`: Any?): Quest { + return this + } + } + val testQuest = TestQuest() + + @Test fun getIndexShouldNotThrowException() { + Assertions.assertDoesNotThrow { + testQuest.index + } + } + + @Test fun registerShouldMakeQuestImmediatelyAvailable() { + QuestRepository.register(testQuest) + Assertions.assertNotNull(QuestRepository.getQuests()[testQuest.quest]) + } + + @Test fun registerShouldMakeQuestImmediatelyAvailableToInstances() { + QuestRepository.register(testQuest) + val instance = QuestRepository(testPlayer) + Assertions.assertNotNull(instance.getQuest(testQuest.quest)) + } + + @Test fun getStageOnUnstartedQuestShouldNotThrowException() { + QuestRepository.register(testQuest) + val instance = QuestRepository(testPlayer) + Assertions.assertDoesNotThrow { + instance.getStage(testQuest) + } + } + + @Test fun setStageOnUnstartedQuestShouldNotThrowException() { + QuestRepository.register(testQuest) + val instance = QuestRepository(testPlayer) + Assertions.assertDoesNotThrow { + instance.setStage(testQuest, 10) + } + } + + @Test fun completeQuestShouldThrowExceptionIfAlreadyComplete() { + Assertions.assertThrows(IllegalStateException::class.java, { + QuestRepository.register(testQuest) + val repo = QuestRepository(testPlayer) + repo.getQuest(Quests.TEST_QUEST).finish(testPlayer) + repo.getQuest(Quests.TEST_QUEST).finish(testPlayer) + }, "Quest completed twice without throwing an exception or threw wrong exception!") + } +} \ No newline at end of file diff --git a/Server/src/test/kotlin/RegionSpecificationTests.kt b/Server/src/test/kotlin/RegionSpecificationTests.kt new file mode 100644 index 0000000..52b6d63 --- /dev/null +++ b/Server/src/test/kotlin/RegionSpecificationTests.kt @@ -0,0 +1,130 @@ +import core.api.regionspec.* +import core.api.regionspec.contracts.FillChunkContract +import core.game.world.map.BuildRegionChunk +import core.game.world.map.Region +import core.game.world.map.RegionChunk +import core.game.world.map.RegionManager +import core.game.world.map.build.DynamicRegion +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test + +class RegionSpecificationTests { + companion object { + init { + TestUtils.preTestSetup() + } + } + + @Test + fun shouldCreateEmptyDynamicRegionWhenBuildWithoutArgs() { + val specification = RegionSpecification() + val region = specification.build() + Assertions.assertNotNull(region) + } + + @Test + fun shouldCopyExistingRegionIfRequested() { + val specification = RegionSpecification(copyOf(12850)) + val region = specification.build() + Assertions.assertEquals(36782, RegionManager.getObject(region.baseLocation.transform(23, 17, 0))?.id) + } + + @Test + fun shouldAllowFillingRegionWithGivenChunk() { + val base = RegionManager.forId(12850) + Region.load(base) + val chunk = base.planes[0].getRegionChunk(2, 2) + val specification = RegionSpecification(fillWith(chunk).from(base).onPlanes(0)) + val region = specification.build() + Assertions.assertEquals(36782, RegionManager.getObject(region.baseLocation.transform(23, 17, 0))?.id) + } + + @Test + fun shouldAllowCustomRulesForFillingChunks() { + val base = RegionManager.forId(12850) + Region.load(base) + val chunk = base.planes[0].getRegionChunk(2, 2) + val specification = RegionSpecification( + fillWith(chunk) + .from(base) + .onPlanes(0) + .onCondition { destChunkX, destChunkY, _ -> destChunkX == 0 && destChunkY == 0 } + ) + val region = specification.build() + Assertions.assertEquals(36782, RegionManager.getObject(region.baseLocation.transform(7, 1, 0))?.id) + Assertions.assertNull(RegionManager.getObject(region.baseLocation.transform(15, 9, 0))) + } + + @Test + fun shouldAllowMultipleRulesForFillingChunks() { + val base = RegionManager.forId(12850) + Region.load(base) + val chunk = base.planes[0].getRegionChunk(2, 2) + val specification = RegionSpecification( + fillWith(chunk) + .from(base) + .onPlanes(0) + .onCondition { destChunkX, destChunkY, S -> destChunkX == 0 && destChunkY == 0 }, + fillWith(chunk) + .from(base) + .onPlanes(1, 2, 3) + ) + val region = specification.build() + Assertions.assertEquals(36782, RegionManager.getObject(region.baseLocation.transform(7, 1, 0))?.id) + Assertions.assertEquals(36782, RegionManager.getObject(region.baseLocation.transform(7, 1, 1))?.id) + Assertions.assertNull(RegionManager.getObject(region.baseLocation.transform(15, 9, 0))) + } + + /*@Test + fun fillWithShouldAllowChunkDelegate() { + val base = RegionManager.forId(12850) + Region.load(base) + val specification = RegionSpecification( + fillWith { destChunkX, destChunkY, destPlane, _ -> + base.planes[destPlane].getRegionChunk(destChunkX, destChunkY) + }.from(base).onPlanes(0, 1, 2, 3) + ) + val region = specification.build() + Assertions.assertEquals( + base.planes[0].chunks[1][1].objects[1][3]?.id, + region.planes[0].chunks[1][1].objects[1][3]?.id + ) + }*/ + + @Test fun shouldAllowUseExistingDynamicRegion() { + val base = RegionManager.forId(12850) + Region.load(base) + val chunk = base.planes[0].getRegionChunk(2, 2) + val dyn = DynamicRegion.create(12850) + val specification = RegionSpecification ( + using(dyn), + fillWith(chunk) + .from(base) + .onPlanes(0) + ) + specification.build() + Assertions.assertEquals(36782, RegionManager.getObject(dyn.baseLocation.transform(7, 1, 0))?.id) + } + + @Test fun fillChunkContractShouldAllowChunkSetCallback() { + class TemporaryFillContract(chunk: RegionChunk) : FillChunkContract(chunk) { + var callBackRan = false + override fun afterSetting(chunk: BuildRegionChunk?, x: Int, y: Int, plane: Int, dyn: DynamicRegion) { + callBackRan = true + } + } + val base = RegionManager.forId(12850) + Region.load(base) + val chunk = base.planes[0].getRegionChunk(2, 2) + val dyn = DynamicRegion.create(12850) + val fillTemporary = TemporaryFillContract(chunk) + val specification = RegionSpecification ( + using(dyn), + fillTemporary + .from(base) + .onPlanes(0) + ) + specification.build() + Assertions.assertEquals(true, fillTemporary.callBackRan) + } +} diff --git a/Server/src/test/kotlin/RegionTests.kt b/Server/src/test/kotlin/RegionTests.kt new file mode 100644 index 0000000..7e48c33 --- /dev/null +++ b/Server/src/test/kotlin/RegionTests.kt @@ -0,0 +1,113 @@ +import core.cache.Cache +import core.game.world.map.Region +import core.game.world.map.RegionChunk +import core.game.world.map.RegionManager +import core.game.world.map.build.DynamicRegion +import core.game.world.map.build.LandscapeParser +import org.junit.Assert +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test +import core.game.system.config.ServerConfigParser +import core.game.system.config.XteaParser + +class RegionTests { + companion object { + init {TestUtils.preTestSetup();} + } + + @Test fun testRegionLoad() { + val region = RegionManager.forId(12850) + Region.load(region) + Assertions.assertNotEquals(0, region.objectCount, "Region has no objects! (Failed to parse?)") + } + + @Test fun shouldHaveDifferentIdForDynamicCopy() { + val region = RegionManager.forId(12850) + val dynamic = DynamicRegion.create(12850) + Assertions.assertNotEquals(region.regionId, (dynamic.x shl 8) or dynamic.y) + } + + @Test fun dynamicRegionCreationShouldNotReplaceOriginal() { + val region = RegionManager.forId(12850) + val dynamic = DynamicRegion.create(12850) + Assertions.assertEquals(false, RegionManager.forId(12850) is DynamicRegion) + } + + @Test fun testDynamicRegionHasSameObjects() { + val base = RegionManager.forId(12850) + Region.load(base) + val dynamic = DynamicRegion.create(12850) + Region.load(dynamic) + + Assertions.assertEquals(true, dynamic.objectCount > 0, "Dynamic and standard have differing object counts!") + } + + @Test fun testObjectExistsInStandardRegion() { + val base = RegionManager.forId(12850) + Region.load(base) + + val targetLoc = base.baseLocation.transform(23, 17, 0) //location of a bush + Assertions.assertEquals(36782, RegionManager.getObject(targetLoc)?.id ?: -1, "Object does not exist at expected location!") + } + + @Test fun testObjectExistsInDynamicRegion() { + val base = RegionManager.forId(12850) + val dynamic = DynamicRegion.create(12850) + Region.load(base) + Region.load(dynamic) + + val targetLoc = dynamic.baseLocation.transform(23, 17, 0) + Assertions.assertEquals(36782, RegionManager.getObject(targetLoc)?.id ?: -1, "Object does not exist at expected location!") + } + + @Test fun testObjectExistsInCopiedChunk() { + val base = RegionManager.forId(12850) + val dynamic = DynamicRegion.create(12851) + Region.load(base) + Region.load(dynamic) + val targetLoc = dynamic.baseLocation.transform(23, 17, 0) + Assertions.assertEquals(null, RegionManager.getObject(targetLoc), "Object exists pre-copy?") + val replacement = base.planes[0].getRegionChunk(2, 2) + dynamic.replaceChunk(0, 2, 2, replacement.copy(dynamic.planes[0]), base) + Assertions.assertEquals(36782, RegionManager.getObject(targetLoc)?.id ?: -1, "Object does not exist at expected location!") + } + + @Test fun testObjectExistsInCopiedChunkUsingBuildFlag() { + val base = RegionManager.forId(12850) + val dynamic = DynamicRegion.create(12851) + Region.load(base, true) + Region.load(dynamic, true) + val targetLoc = dynamic.baseLocation.transform(23, 17, 0) + Assertions.assertEquals(null, RegionManager.getObject(targetLoc), "Object exists pre-copy?") + val replacement = base.planes[0].getRegionChunk(2, 2) + dynamic.replaceChunk(0, 2, 2, replacement.copy(dynamic.planes[0]), base) + Assertions.assertEquals(36782, RegionManager.getObject(targetLoc)?.id ?: -1, "Object does not exist at expected location!") + } + + @Test fun testObjectExistsInCopiedChunkCopiedIntoBlankRegion() { + val base = RegionManager.forId(12850) + val borders = DynamicRegion.reserveArea(8,8) + val dynamic = DynamicRegion(-1, borders.southWestX shr 6, borders.southWestY shr 6) + dynamic.borders = borders + dynamic.isUpdateAllPlanes = true + RegionManager.addRegion(dynamic.id, dynamic) + val targetLoc = dynamic.baseLocation.transform(23, 17, 0) + val replacement = base.planes[0].getRegionChunk(2,2) + dynamic.replaceChunk(0, 2, 2, replacement.copy(dynamic.planes[0]), base) + Assertions.assertEquals(36782, RegionManager.getObject(targetLoc)?.id ?: -1, "Object does not exist at expected location!") + } + + @Test fun testObjectExistsInCopiedChunkInLinkedRegion() { + val base = DynamicRegion.create(12850) + val borders = DynamicRegion.reserveArea(8,8) + val dynamic = DynamicRegion(-1, borders.southWestX shr 6, borders.southWestY shr 6) + dynamic.borders = borders + dynamic.isUpdateAllPlanes = true + RegionManager.addRegion(dynamic.id, dynamic) + val targetLoc = dynamic.baseLocation.transform(23, 17, 0) + val replacement = base.planes[0].getRegionChunk(2,2) + dynamic.replaceChunk(0, 2, 2, replacement.copy(dynamic.planes[0]), base) + base.link(dynamic) + Assertions.assertEquals(36782, RegionManager.getObject(targetLoc)?.id ?: -1, "Object does not exist at expected location!") + } +} \ No newline at end of file diff --git a/Server/src/test/kotlin/RunecraftingTests.kt b/Server/src/test/kotlin/RunecraftingTests.kt new file mode 100644 index 0000000..0a16e6d --- /dev/null +++ b/Server/src/test/kotlin/RunecraftingTests.kt @@ -0,0 +1,51 @@ +import content.global.skill.runecrafting.RuneCraftPulse; +import content.global.skill.runecrafting.Rune; + +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test + +class RunecraftTests { + fun rollRc(rcLevel: Int, rune: Rune, revision: Int, lo: Double, hi: Double) { + var total = 0.0 + for(i in 0 until 3000) { + total += RuneCraftPulse.getMultiplier(rcLevel, rune, revision, false) + } + val average = total / 3000.0 + Assertions.assertTrue(lo <= average && average <= hi, "rollRc: ${rcLevel} ${rune.name} ${revision}: ${average}") + } + + @Test fun testNatureRcMultipliers() { + rollRc(44, Rune.NATURE, 530, 1.0, 1.0); + rollRc(44, Rune.NATURE, 573, 1.0, 1.0); + rollRc(44, Rune.NATURE, 581, 1.0, 1.0); + + rollRc(68, Rune.NATURE, 530, 1.0, 1.0); + rollRc(68, Rune.NATURE, 573, 1.45, 1.55); + rollRc(68, Rune.NATURE, 581, 1.45, 1.55); + + rollRc(91, Rune.NATURE, 530, 2.0, 2.0); + rollRc(91, Rune.NATURE, 573, 2.0, 2.0); + rollRc(91, Rune.NATURE, 581, 2.0, 2.0); + + rollRc(90, Rune.NATURE, 530, 1.0, 1.0); + rollRc(90, Rune.NATURE, 573, 1.95, 2.0); + rollRc(90, Rune.NATURE, 581, 1.95, 2.0); + + rollRc(99, Rune.NATURE, 530, 2.0, 2.0); + rollRc(99, Rune.NATURE, 573, 2.0, 2.0); + rollRc(99, Rune.NATURE, 581, 2.04, 2.14); + } + @Test fun testLawRcMultipliers() { + rollRc(54, Rune.LAW, 530, 1.0, 1.0); + rollRc(54, Rune.LAW, 573, 1.0, 1.0); + rollRc(54, Rune.LAW, 581, 1.0, 1.0); + + rollRc(77, Rune.LAW, 530, 1.0, 1.0); + rollRc(77, Rune.LAW, 573, 1.0, 1.0); + rollRc(77, Rune.LAW, 581, 1.35, 1.45); + + rollRc(99, Rune.LAW, 530, 1.0, 1.0); + rollRc(99, Rune.LAW, 573, 1.0, 1.0); + rollRc(99, Rune.LAW, 581, 1.75, 1.85); + } +} diff --git a/Server/src/test/kotlin/ShopTests.kt b/Server/src/test/kotlin/ShopTests.kt new file mode 100644 index 0000000..025fd13 --- /dev/null +++ b/Server/src/test/kotlin/ShopTests.kt @@ -0,0 +1,366 @@ + +import core.game.node.entity.player.link.IronmanMode +import core.game.node.item.Item +import core.game.shops.Shop +import core.game.shops.Shops +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.rs09.consts.Items +import kotlin.math.min +import kotlin.math.roundToInt + +class ShopTests { + companion object { + init {TestUtils.preTestSetup()} + } + + private val testPlayer = TestUtils.getMockPlayer("test") + private val testIronman = TestUtils.getMockPlayer("test2", IronmanMode.STANDARD) + private var nonGeneral = TestUtils.getMockShop("Not General", false, false, Item(4151, 1)) + private var general = TestUtils.getMockShop("General", true, false, Item(4151, 1)) + private var highAlch = TestUtils.getMockShop("High(af) Alch", true, true, Item(4151, 1)) + private var tokkulShop = TestUtils.getMockTokkulShop("Tokkul", Item(Items.DEATH_RUNE_560, 10)) + + @BeforeEach fun beforeEach() { + val testPlayers = arrayOf(testPlayer, testIronman) + for (player in testPlayers) { + player.inventory.clear() + player.attributes.remove("shop-cont") + } + nonGeneral.playerStock.clear() + general.playerStock.clear() + highAlch.playerStock.clear() + tokkulShop.playerStock.clear() + } + + private fun assertTransactionSuccess(status: Shop.TransactionStatus) { + Assertions.assertEquals(true, status is Shop.TransactionStatus.Success, "Transaction failure: ${if(status is Shop.TransactionStatus.Failure) status.reason else ""}") + } + + @Test fun shouldSellItemToStore() { + testPlayer.inventory.add(Item(4151, 1)) + testPlayer.setAttribute("shop-cont", general.getContainer(testPlayer)) + val status = general.sell(testPlayer, 0, 1) + assertTransactionSuccess(status) + } + + @Test fun shouldNotSellUnstockedItemToStandardStore() { + testPlayer.inventory.add(Item(1511, 1)) + testPlayer.setAttribute("shop-cont", nonGeneral.getContainer(testPlayer)) + val status = nonGeneral.sell(testPlayer, 0, 1) + Assertions.assertEquals(true, status is Shop.TransactionStatus.Failure) + } + + @Test fun shouldSellUnstockedItemToGeneralStore() { + testPlayer.inventory.add(Item(1511, 1)) + testPlayer.setAttribute("shop-cont", general.getContainer(testPlayer)) + val status = general.sell(testPlayer, 0, 1) + assertTransactionSuccess(status) + } + + @Test fun shouldNotSellDestroyable() { + testPlayer.inventory.add(Item(1, 795)) + testPlayer.setAttribute("shop-cont", general.getContainer(testPlayer)) + val status = general.sell(testPlayer, 0, 1) + Assertions.assertEquals(true, status is Shop.TransactionStatus.Failure) + } + + @Test fun shouldNotSellUntradeable() { + testPlayer.inventory.add(Item(1, 1799)) + testPlayer.setAttribute("shop-cont", general.getContainer(testPlayer)) + val status = general.sell(testPlayer, 0, 1) + Assertions.assertEquals(true, status is Shop.TransactionStatus.Failure) + } + + @Test fun shouldSellUnstockedItemToGeneralStoreUsingLowAlchBaseValue() { + //starts at 40% value - a.k.a. low alch price + //drops 3% value per item stocked + //bottoms out at 10% value (25% of the low alch price) after 10 items stocked + val saleItemId = Items.RUNE_MED_HELM_1147 + val shopContainer = general.getContainer(testPlayer) + Assertions.assertFalse(shopContainer.containItems(saleItemId), "Pre-assertion, shop container should not have the unstocked item to begin with.") + testPlayer.setAttribute("shop-cont", shopContainer) + val playerStock = general.playerStock + Assertions.assertFalse(playerStock.containItems(saleItemId), "Pre-assertion, player stock should not have the unstocked item to begin with.") + val saleItem = Item(saleItemId, 1) + val alchValue = saleItem.definition.getAlchemyValue(false) + val value = saleItem.definition.value + Assertions.assertEquals((value * 0.4).roundToInt(), alchValue, "Pre-assertion, low alch value should be 40% value.") + + for (i in 0..14) { + val expectedCoins = (alchValue.toDouble() - value * min(0.03 * i, 0.30)).roundToInt() + testPlayer.inventory.add(saleItem.copy()) + Assertions.assertEquals(saleItemId, testPlayer.inventory.getId(0), "Pre-assertion, should have item in inventory slot 0.") + + val status = general.sell(testPlayer, 0, 1) + + assertTransactionSuccess(status) + val coinItem = testPlayer.inventory[0] + Assertions.assertEquals(Items.COINS_995, coinItem.id) + Assertions.assertEquals( + expectedCoins, + coinItem.amount, + "Selling item $i should yield the expected price." + ) + testPlayer.inventory.clear() + } + } + + @Test fun shouldSellUnstockedItemToHighAlchStoreUsingHighAlchBaseValue() { + //starts at 60% value - a.k.a. high alch price + //drops 3% value per item stocked + //bottoms out at 30% value (50% of the high alch price) after 10 items stocked + val saleItemId = Items.RUNE_MED_HELM_1147 + val shopContainer = highAlch.getContainer(testPlayer) + Assertions.assertFalse(shopContainer.containItems(saleItemId), "Pre-assertion, shop container should not have the unstocked item to begin with.") + testPlayer.setAttribute("shop-cont", shopContainer) + val playerStock = highAlch.playerStock + Assertions.assertFalse(playerStock.containItems(saleItemId), "Pre-assertion, player stock should not have the unstocked item to begin with.") + val saleItem = Item(saleItemId, 1) + val alchValue = saleItem.definition.getAlchemyValue(true) + val value = saleItem.definition.value + Assertions.assertEquals((value * 0.6).roundToInt(), alchValue, "Pre-assertion, high alch value should be 60% value.") + + for (i in 0..14) { + val expectedCoins = (alchValue.toDouble() - value * min(0.03 * i, 0.30)).roundToInt() + testPlayer.inventory.add(saleItem.copy()) + Assertions.assertEquals(saleItemId, testPlayer.inventory.getId(0), "Pre-assertion, should have item in inventory slot 0.") + + val status = highAlch.sell(testPlayer, 0, 1) + + assertTransactionSuccess(status) + val coinItem = testPlayer.inventory[0] + Assertions.assertEquals(Items.COINS_995, coinItem.id) + Assertions.assertEquals( + expectedCoins, + coinItem.amount, + "Selling item $i should yield the expected price." + ) + testPlayer.inventory.clear() + } + } + + @Test fun shouldSellNotedUnstockedItemForSamePriceAsUnnoted() { + val saleItemId = Items.RUNE_MED_HELM_1147 + var notedSaleItemId = Items.RUNE_MED_HELM_1148 + val shopContainer = highAlch.getContainer(testPlayer) + Assertions.assertFalse(shopContainer.containItems(saleItemId), "Pre-assertion, shop container should not have the unstocked item to begin with.") + testPlayer.setAttribute("shop-cont", shopContainer) + val playerStock = highAlch.playerStock + Assertions.assertFalse(playerStock.containItems(saleItemId), "Pre-assertion, player stock should not have the unstocked item to begin with.") + testPlayer.inventory.add(Item(saleItemId, 1)) + var status = highAlch.sell(testPlayer, 0, 1) + assertTransactionSuccess(status) + testPlayer.inventory.clear() + val notedSaleItem = Item(notedSaleItemId, 1) + testPlayer.inventory.add(notedSaleItem) + val alchValue = notedSaleItem.definition.getAlchemyValue(true) + val value = notedSaleItem.definition.value + status = highAlch.sell(testPlayer, 0, 1) + assertTransactionSuccess(status) + val expectedCoins = (alchValue.toDouble() - value * 0.03).roundToInt() + + val coinItem = testPlayer.inventory[0] + Assertions.assertEquals(Items.COINS_995, coinItem.id) + Assertions.assertEquals( + expectedCoins, + coinItem.amount, + "Selling noted item should yield the same devalued price as base item." + ) + } + + @Test fun minimumSellPriceShouldBe1Coin() { + testPlayer.inventory.add(Item(Items.EMPTY_POT_1931, 1)) + testPlayer.setAttribute("shop-cont", general.getContainer(testPlayer)) + val status = general.sell(testPlayer, 0, 1) + assertTransactionSuccess(status) + val coinItem = testPlayer.inventory[0] + Assertions.assertEquals(Items.COINS_995, coinItem.id) + Assertions.assertEquals( + 1, + coinItem.amount, + "1 coin should be the minimum selling price." + ) + } + + @Test fun tokkulShouldBe10xLessValuableWhenSellingAStockedItem() { + val startingTokkul = 5000 + testPlayer.inventory.add(Item(Items.TOKKUL_6529, startingTokkul)) + testPlayer.setAttribute("shop-cont", tokkulShop.getContainer(testPlayer)) + testPlayer.setAttribute("shop-main", true) + var status = tokkulShop.buy(testPlayer, 0, 1) // 1 death rune + assertTransactionSuccess(status) + Assertions.assertEquals(Items.TOKKUL_6529, testPlayer.inventory[0].id, "Pre-assertion: First item should still be the currency used.") + val cost = startingTokkul - testPlayer.inventory[0].amount + status = tokkulShop.sell(testPlayer, 1, 1) // back to starting stock + assertTransactionSuccess(status) + testPlayer.inventory.clear() + testPlayer.inventory.add(Item(Items.DEATH_RUNE_560, 1)) + + status = tokkulShop.sell(testPlayer, 0, 1) // sell 1 death rune to fresh shop + assertTransactionSuccess(status) + + Assertions.assertEquals(Items.TOKKUL_6529, testPlayer.inventory[0].id, "Expected same currency back.") + Assertions.assertEquals((cost / 10.0).toInt(), testPlayer.inventory[0].amount, "Expected 10 times less for selling than for cost of buying.") + } + + @Test fun shouldSellUnstockedItemToGeneralStoreAsIronman() { + testIronman.inventory.add(Item(1511, 1)) + testIronman.setAttribute("shop-cont", general.getContainer(testIronman)) + val status = general.sell(testIronman, 0, 1) + assertTransactionSuccess(status) + } + + @Test fun shouldSellStackOfUnstockedItemsToPlayerStock() { + testPlayer.inventory.add(Item(1512, 20)) + testPlayer.setAttribute("shop-cont", general.getContainer(testPlayer)) + val status = general.sell(testPlayer, 0, 20) + assertTransactionSuccess(status) + } + + @Test fun shouldPutSoldUnstockedItemsInPlayerStock() { + testPlayer.inventory.add(Item(2,1)) + testPlayer.setAttribute("shop-cont", general.getContainer(testPlayer)) + val status = general.sell(testPlayer, 0, 1) + assertTransactionSuccess(status) + Assertions.assertEquals(1, general.playerStock.getAmount(2)) + Assertions.assertEquals(0, general.getContainer(testPlayer).getAmount(2)) + } + + @Test fun shouldAllowStandardPlayerToBuy() { + testPlayer.inventory.add(Item(995, 125000)) + testPlayer.setAttribute("shop-cont", general.getContainer(testPlayer)) + testPlayer.setAttribute("shop-main", true) + val status = general.buy(testPlayer, 0, 1) + assertTransactionSuccess(status) + } + + @Test fun shouldAllowStandardPlayerToBuyOverstock() { + testPlayer.inventory.add(Item(995, 125000)) + testPlayer.setAttribute("shop-cont", general.getContainer(testPlayer)) + testPlayer.setAttribute("shop-main", true) + general.getContainer(testPlayer).add(Item(4151, 100)) + val status = general.buy(testPlayer, 0, 1) + assertTransactionSuccess(status) + } + + @Test fun shouldAllowStandardPlayerToBuyPlayerStock() { + testPlayer.inventory.add(Item(995, 125000)) + testPlayer.setAttribute("shop-cont", general.getContainer(testPlayer)) + testPlayer.setAttribute("shop-main", false) + general.playerStock.add(Item(4151, 100)) + val status = general.buy(testPlayer, 0, 1) + assertTransactionSuccess(status) + } + + @Test fun shouldNotAllowIronmanToBuyOverstock() { + testIronman.inventory.add(Item(995, 100000)) + testIronman.setAttribute("shop-cont", general.getContainer(testIronman)) + testIronman.setAttribute("shop-main", true) + general.getContainer(testIronman).add(Item(4151, 100)) + val status = general.buy(testIronman, 0, 1) + Assertions.assertEquals(true, status is Shop.TransactionStatus.Failure) + } + + @Test fun shouldNotAllowIronmanToBuyPlayerStock() { + testIronman.inventory.add(Item(995, 100000)) + testIronman.setAttribute("shop-cont", general.playerStock) + testIronman.setAttribute("shop-main", false) + general.playerStock.add(Item(4151, 1)) + val status = general.buy(testIronman, 0, 1) + Assertions.assertEquals(true, status is Shop.TransactionStatus.Failure) + } + + @Test fun openShopShouldNotThrowException() { + Assertions.assertDoesNotThrow { + general.openFor(testPlayer) + } + } + + @Test fun shouldNotThrowExceptionWhenRestockingStockWithNullSlot() { + Assertions.assertDoesNotThrow { + general.getContainer(testPlayer).add(Item(1, 100)) + general.getContainer(testPlayer).add(Item(2, 100)) + general.getContainer(testPlayer).replace(null, 0) //replace item in slot 0 with null + for ((k,_) in general.stockInstances) general.needsUpdate[k] = true + general.restock() + } + } + + @Test fun playerStockShouldNeverBeNull() { + Assertions.assertNotNull(general.playerStock) + } + + @Test fun shouldAllowBuyingFromPlayerStockOnMultipleRows() { + for(i in 0 until 100) { + general.playerStock.add(Item(i + 3100, 1)) //make sure we populate several rows of items + } + testPlayer.inventory.add(Item(995, 100000)) + testPlayer.setAttribute("shop-cont", general.getContainer(testPlayer)) + testPlayer.setAttribute("shop-main", false) + var status: Shop.TransactionStatus = Shop.TransactionStatus.Failure("Test did not assign transaction status.") + Assertions.assertDoesNotThrow({ + status = general.buy(testPlayer, 36, 1) + }, "Error selling to shop: ${general.playerStock}") + assertTransactionSuccess(status) + } + + @Test fun invalidStockJsonShouldNotCauseItemShift() { + val invalidJson = "{1277,10,100}-{1277,10,100}-{1279,10,100}" + val stock = Shops.parseStock(invalidJson, -1) + Assertions.assertEquals(2, stock.size) + Assertions.assertEquals(20, stock[0].amount) + } + + @Test fun buying0StockItemFromNormalStockShouldNotSucceedNorDeductGold() { + testPlayer.inventory.clear() + testPlayer.inventory.add(Item(995, Integer.MAX_VALUE)) + testPlayer.setAttribute("shop-cont", general.getContainer(testPlayer)) + testPlayer.setAttribute("shop-main", true) + val inStockAmount = general.getContainer(testPlayer).get(0).amount + + //Buy out existing stock + var status: Shop.TransactionStatus = Shop.TransactionStatus.Success() + + Assertions.assertDoesNotThrow { + status = general.buy(testPlayer, 0, inStockAmount) + } + Assertions.assertEquals(true, status is Shop.TransactionStatus.Success, "Transaction failure: ${if(status is Shop.TransactionStatus.Failure) (status as Shop.TransactionStatus.Failure).reason else ""}") + Assertions.assertEquals(0, general.getContainer(testPlayer).getAmount(0), "Buying all stock didn't... buy all stock.") + + testPlayer.inventory.replace(null, 1) //Remove the items we purchased + + val remainingGP = testPlayer.inventory.getAmount(995) + + Assertions.assertDoesNotThrow { + status = general.buy(testPlayer, 0, 10) + } + + Assertions.assertEquals(true, status is Shop.TransactionStatus.Failure, "Status was not Failure for buying 0-stock item!") + Assertions.assertEquals(remainingGP, testPlayer.inventory.getAmount(995), "Coins were deducted for buying 0-stock item!") + Assertions.assertNull(testPlayer.inventory.get(1), "Player received purchased item despite being 0-stock!") + } + + @Test fun buyingItemWithOtherwiseFullInventoryStillBuysTheItemAndTakesTheCoins() { + testPlayer.setAttribute("shop-cont", general.getContainer(testPlayer)) + testPlayer.setAttribute("shop-main", false) + testPlayer.inventory.clear() + testPlayer.inventory.add(Item(Items.ABYSSAL_WHIP_4151, 27)) //fill 27 slots + general.playerStock.add(Item(992, 1)) + var slot = general.getStockSlot(992).second + var price = general.getBuyPrice(testPlayer, slot) + + testPlayer.inventory.add(price) + + //Buy out existing stock + var status: Shop.TransactionStatus = Shop.TransactionStatus.Success() + + Assertions.assertDoesNotThrow { + status = general.buy(testPlayer, slot, 1) + } + Assertions.assertEquals(true, status is Shop.TransactionStatus.Success) + Assertions.assertEquals(0, testPlayer.inventory.getAmount(995)) + Assertions.assertEquals(1, testPlayer.inventory.getAmount(992)) + } +} diff --git a/Server/src/test/kotlin/TestUtils.kt b/Server/src/test/kotlin/TestUtils.kt new file mode 100644 index 0000000..b8d8d45 --- /dev/null +++ b/Server/src/test/kotlin/TestUtils.kt @@ -0,0 +1,229 @@ +import content.global.skill.farming.timers.CropGrowth +import core.ServerConstants +import core.api.log +import core.cache.Cache +import core.cache.crypto.ISAACCipher +import core.cache.crypto.ISAACPair +import core.game.interaction.ScriptProcessor +import core.game.node.Node +import core.game.node.entity.combat.equipment.WeaponInterface +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.entity.player.VarpManager +import core.game.node.entity.player.info.PlayerDetails +import core.game.node.entity.player.info.Rights +import core.game.node.entity.player.info.login.PlayerSaveParser +import core.game.node.entity.player.info.login.PlayerSaver +import core.game.node.entity.player.link.IronmanMode +import core.game.node.entity.player.link.SavedData +import core.game.node.entity.player.link.quest.QuestRepository +import core.game.node.entity.skill.Skills +import core.game.node.item.GroundItem +import core.game.node.item.Item +import core.game.shops.Shop +import core.game.shops.ShopItem +import core.game.system.config.ConfigParser +import core.game.system.config.ServerConfigParser +import core.game.system.timer.TimerRegistry +import core.game.system.timer.impl.AntiMacro +import core.game.system.timer.impl.Disease +import core.game.system.timer.impl.Poison +import core.game.world.GameWorld +import core.game.world.map.Location +import core.game.world.map.RegionManager +import core.game.world.repository.Repository +import core.game.world.update.UpdateSequence +import core.net.IoSession +import core.net.packet.IoBuffer +import core.net.packet.PacketProcessor +import core.tools.Log +import org.rs09.consts.Items +import java.net.URI +import java.nio.ByteBuffer + +object TestUtils { + var uidCounter = 0 + const val PLAYER_DEATH_TICKS = 14 + + fun getMockPlayer(name: String, ironman: IronmanMode = IronmanMode.NONE, rights: Rights = Rights.ADMINISTRATOR, isBot: Boolean = false): MockPlayer { + val p = MockPlayer(name, isBot) + p.ironmanManager.mode = ironman + p.details.accountInfo.uid = uidCounter++ + p.setPlaying(true) + p.playerFlags.lastSceneGraph = p.location ?: ServerConstants.HOME_LOCATION + Repository.addPlayer(p) + //Update sequence has a separate list of players for some reason... + UpdateSequence.renderablePlayers.add(p) + p.details.rights = rights + return p + } + + fun getMockShop(name: String, general: Boolean, highAlch: Boolean, vararg stock: Item) : Shop { + return Shop( + name, + stock.map { ShopItem(it.id, it.amount, 100) }.toTypedArray(), + general, + highAlch = highAlch + ) + } + + fun getMockTokkulShop(name: String, vararg stock: Item) : Shop { + return Shop( + name, + stock.map { ShopItem(it.id, it.amount, 100) }.toTypedArray(), + currency = Items.TOKKUL_6529 + ) + } + + fun preTestSetup() { + if(ServerConstants.DATA_PATH == null) { + ServerConfigParser.parse(this::class.java.getResource("test.conf")) + Cache.init(this::class.java.getResource("cache").path.toString()) + ConfigParser().prePlugin() + ConfigParser().postPlugin() + registerTimers() + } + } + + fun registerTimers() { //allow timers to be registered for use by tests + TimerRegistry.registerTimer(Poison()) + TimerRegistry.registerTimer(Disease()) + TimerRegistry.registerTimer(CropGrowth()) + TimerRegistry.registerTimer(AntiMacro()) + } + + fun loadFile(path: String) : URI? { + return this::class.java.getResource(path)?.toURI() + } + + fun advanceTicks(amount: Int, skipPulseUpdates: Boolean = true) { + log(this::class.java, Log.FINE, "Advancing ticks by $amount.") + for(i in 0 until amount) { + GameWorld.majorUpdateWorker.handleTickActions(skipPulseUpdates) + } + } + + fun simulateInteraction (player: Player, target: Node, optionIndex: Int, iface: Int = -1, child: Int = -1) { + when (target) { + is GroundItem -> PacketProcessor.enqueue(core.net.packet.`in`.Packet.GroundItemAction(player, optionIndex, target.id, target.location.x, target.location.y)) + is Item -> PacketProcessor.enqueue(core.net.packet.`in`.Packet.ItemAction(player, optionIndex, target.id, target.slot, iface, child)) + is NPC -> PacketProcessor.enqueue(core.net.packet.`in`.Packet.NpcAction(player, optionIndex, target.clientIndex)) + is core.game.node.scenery.Scenery -> PacketProcessor.enqueue(core.net.packet.`in`.Packet.SceneryAction(player, optionIndex, target.id, target.location.x, target.location.y)) + } + advanceTicks(1, true) + } +} + +class MockPlayer(name: String, val isBot: Boolean) : Player(PlayerDetails(name)), AutoCloseable { + var hasInit = false + init { configureBasicProperties(); flagTutComplete(false); init(); flagTutComplete(true) } + + fun configureBasicProperties() { + this.details.session = MockSession() + this.location = ServerConstants.HOME_LOCATION + this.properties.attackStyle = WeaponInterface.AttackStyle(0, WeaponInterface.BONUS_CRUSH) + this.artificial = isBot + } + + fun flagTutComplete(complete: Boolean) { + this.setAttribute("/save:tutorial:complete", complete) + this.setAttribute("/save:rules:confirmed", complete) + } + + override fun update() { + //do nothing. This is for rendering stuff. We don't render a mock player. Not until the spaghetti is less spaghetti. + } + + override fun init() { + if (hasInit) return + hasInit = true + super.init() + } + + override fun close() { + Repository.removePlayer(this) + UpdateSequence.renderablePlayers.remove(this) + finishClear() + } + + override fun setLocation(location: Location?) { + super.setLocation(location) + RegionManager.move(this) + this.playerFlags.lastSceneGraph = location + } + + fun relog(ticksToWait: Int = -1) { + val json = PlayerSaver(this).populate() + val parse = PlayerSaveParser(this) + parse.saveFile = json + + close() + timers.clearTimers() + inventory.clear() + bank.clear() + equipment.clear() + skills = Skills(this) + savedData = SavedData(this) + questRepository = QuestRepository(this) + varpManager = VarpManager(this) + varpMap.clear() + saveVarp.clear() + scripts = ScriptProcessor(this) + clearAttributes() + hasInit = false + + if (ticksToWait > 0) TestUtils.advanceTicks(ticksToWait, false) + + configureBasicProperties() + parse.parseData() + init() + } + + override fun debug(string: String?) { + log (this::class.java, Log.DEBUG, "[$name] -> Received Debug: $string") + } +} + +class MockSession : IoSession(null, null) { + val receivedPackets = ArrayList() + var disconnected = false + + @Suppress("ArrayInDataClass") + data class Packet(val opcode: Int, val payload: ByteArray) + + override fun getRemoteAddress(): String? { + return "127.0.0.1" + } + + override fun write(context: Any, instant: Boolean) { + if(context is IoBuffer) { + receivedPackets.add(Packet(context.opcode(), context.array())) + } + } + + fun hasPacketReady(opcode: Int) : Boolean { + for(pkt in receivedPackets) if(pkt.opcode == opcode) return true + return false + } + + fun getPacketsWithOpcode(opcode: Int) : ArrayList { + val list = ArrayList() + for(pkt in receivedPackets) if(pkt.opcode == opcode) list.add(pkt.payload) + return list + } + + override fun getIsaacPair(): ISAACPair { + return ISAACPair(ISAACCipher(intArrayOf(0)), ISAACCipher(intArrayOf(0))) + } + + override fun queue(buffer: ByteBuffer?) {} + + override fun write() {} + + override fun disconnect() {disconnected = true} + + fun clear() { + receivedPackets.clear() + } + +} diff --git a/Server/src/test/kotlin/content/CombatTests.kt b/Server/src/test/kotlin/content/CombatTests.kt new file mode 100644 index 0000000..762ed84 --- /dev/null +++ b/Server/src/test/kotlin/content/CombatTests.kt @@ -0,0 +1,138 @@ +package content + +import TestUtils +import content.global.handlers.item.equipment.special.ChinchompaSwingHandler +import core.api.EquipmentSlot +import core.game.container.impl.EquipmentContainer.updateBonuses +import core.game.interaction.IntType +import core.game.interaction.InteractionListeners +import core.game.node.entity.combat.MagicSwingHandler +import core.game.node.entity.combat.MeleeSwingHandler +import core.game.node.entity.combat.RangeSwingHandler +import core.game.node.entity.combat.SwingHandlerFlag +import core.game.node.entity.combat.equipment.WeaponInterface +import core.game.node.entity.player.link.prayer.PrayerType +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test +import org.rs09.consts.Items + +class CombatTests { + init { + TestUtils.preTestSetup() + } + + @Test + fun swingHandlersFlaggedAsIgnoreStatsShouldNotInfluenceDamage() { + val testRangeHandler = RangeSwingHandler(SwingHandlerFlag.IGNORE_STAT_BOOSTS_DAMAGE) + val testMeleeHandler = MeleeSwingHandler(SwingHandlerFlag.IGNORE_STAT_BOOSTS_DAMAGE) + + TestUtils.getMockPlayer("ignorestatdamage").use { p -> + p.skills.setLevel(Skills.RANGE, 99) + val baselineRanged = testRangeHandler.calculateHit(p, p, 1.0) + p.properties.bonuses[14] = 250 + Assertions.assertEquals(baselineRanged, testRangeHandler.calculateHit(p, p, 1.0)) + + p.skills.setLevel(Skills.STRENGTH, 99) + val baselineMelee = testMeleeHandler.calculateHit(p, p, 1.0) + p.properties.bonuses[11] = 250 + Assertions.assertEquals(baselineMelee, testMeleeHandler.calculateHit(p, p, 1.0)) + } + } + + @Test + fun swingHandlersFlaggedAsIgnoreStatsShouldNotInfluenceAccuracy() { + val testRangeHandler = RangeSwingHandler(SwingHandlerFlag.IGNORE_STAT_BOOSTS_ACCURACY) + val testMeleeHandler = MeleeSwingHandler(SwingHandlerFlag.IGNORE_STAT_BOOSTS_ACCURACY) + val testMagicHandler = MagicSwingHandler(SwingHandlerFlag.IGNORE_STAT_BOOSTS_ACCURACY) + + TestUtils.getMockPlayer("ignorestataccuracy").use { p -> + p.properties.attackStyle = WeaponInterface.AttackStyle(0, WeaponInterface.BONUS_RANGE) + p.skills.setLevel(Skills.RANGE, 99) + val baselineRanged = testRangeHandler.calculateAccuracy(p) + p.properties.bonuses[WeaponInterface.BONUS_RANGE] = 250 + Assertions.assertEquals(baselineRanged, testRangeHandler.calculateAccuracy(p)) + + p.properties.attackStyle = WeaponInterface.AttackStyle(0, WeaponInterface.BONUS_STAB) + p.skills.setLevel(Skills.STRENGTH, 99) + val baselineMelee = testMeleeHandler.calculateAccuracy(p) + p.properties.bonuses[WeaponInterface.BONUS_STAB] = 250 + Assertions.assertEquals(baselineMelee, testMeleeHandler.calculateAccuracy(p)) + + p.properties.attackStyle = WeaponInterface.AttackStyle(0, WeaponInterface.BONUS_MAGIC) + p.skills.setLevel(Skills.MAGIC, 99) + val baselineMagic = testMagicHandler.calculateAccuracy(p) + p.properties.bonuses[WeaponInterface.BONUS_MAGIC] = 250 + Assertions.assertEquals(baselineMagic, testMagicHandler.calculateAccuracy(p)) + } + } + + @Test + fun swingHandlersFlaggedAsIgnorePrayerShouldNotInfluenceDamage() { + val testRangeHandler = RangeSwingHandler(SwingHandlerFlag.IGNORE_PRAYER_BOOSTS_DAMAGE) + val testMeleeHandler = MeleeSwingHandler(SwingHandlerFlag.IGNORE_PRAYER_BOOSTS_DAMAGE) + + TestUtils.getMockPlayer("ignoreprayerdamage").use { p -> + p.skills.setStaticLevel(Skills.PRAYER, 99) + p.skills.prayerPoints = 1000.0 + + p.skills.setLevel(Skills.RANGE, 99) + val baselineRanged = testRangeHandler.calculateHit(p, p, 1.0) + p.prayer.toggle(PrayerType.EAGLE_EYE) + Assertions.assertEquals(baselineRanged, testRangeHandler.calculateHit(p, p, 1.0)) + p.prayer.toggle(PrayerType.EAGLE_EYE) + + p.skills.setLevel(Skills.STRENGTH, 99) + val baselineMelee = testMeleeHandler.calculateHit(p, p, 1.0) + p.prayer.toggle(PrayerType.SUPERHUMAN_STRENGTH) + Assertions.assertEquals(baselineMelee, testMeleeHandler.calculateHit(p, p, 1.0)) + p.prayer.toggle(PrayerType.SUPERHUMAN_STRENGTH) + } + } + + @Test + fun swingHandlersFlaggedAsIgnorePrayerShouldNotInfluenceAccuracy() { + val testRangeHandler = RangeSwingHandler(SwingHandlerFlag.IGNORE_PRAYER_BOOSTS_ACCURACY) + val testMeleeHandler = MeleeSwingHandler(SwingHandlerFlag.IGNORE_PRAYER_BOOSTS_ACCURACY) + val testMagicHandler = MagicSwingHandler(SwingHandlerFlag.IGNORE_PRAYER_BOOSTS_ACCURACY) + + TestUtils.getMockPlayer("ignoreprayeraccuracy").use { p -> + p.skills.setStaticLevel(Skills.PRAYER, 99) + p.skills.prayerPoints = 1000.0 + + p.skills.setLevel(Skills.RANGE, 99) + val baselineRanged = testRangeHandler.calculateAccuracy(p) + p.prayer.toggle(PrayerType.EAGLE_EYE) + Assertions.assertEquals(baselineRanged, testRangeHandler.calculateAccuracy(p)) + p.prayer.toggle(PrayerType.EAGLE_EYE) + + p.skills.setLevel(Skills.ATTACK, 99) + val baselineMelee = testMeleeHandler.calculateAccuracy(p) + p.prayer.toggle(PrayerType.INCREDIBLE_REFLEXES) + Assertions.assertEquals(baselineMelee, testMeleeHandler.calculateAccuracy(p)) + p.prayer.toggle(PrayerType.INCREDIBLE_REFLEXES) + + p.skills.setLevel(Skills.MAGIC, 99) + val baselineMagic = testMagicHandler.calculateAccuracy(p) + p.prayer.toggle(PrayerType.MYSTIC_MIGHT) + Assertions.assertEquals(baselineMagic, testMagicHandler.calculateAccuracy(p)) + p.prayer.toggle(PrayerType.MYSTIC_MIGHT) + } + } + + @Test fun chinchompaSwingHandlerIgnoresAmmoSlotForDamage() { + val handler = ChinchompaSwingHandler() + + TestUtils.getMockPlayer("chinchompaStatTest").use { p -> + p.skills.staticLevels[Skills.RANGE] = 99 + p.skills.dynamicLevels[Skills.RANGE] = 99 + p.equipment.replace(Item(Items.CHINCHOMPA_10033), EquipmentSlot.WEAPON.ordinal) + updateBonuses(p) + val damageBaseline = handler.calculateHit(p, p, 1.0) + p.equipment.replace(Item(Items.DRAGON_ARROW_11212), EquipmentSlot.AMMO.ordinal) + updateBonuses(p) + Assertions.assertEquals(damageBaseline, handler.calculateHit(p, p, 1.0)) + } + } +} \ No newline at end of file diff --git a/Server/src/test/kotlin/content/DeathTests.kt b/Server/src/test/kotlin/content/DeathTests.kt new file mode 100644 index 0000000..e91c121 --- /dev/null +++ b/Server/src/test/kotlin/content/DeathTests.kt @@ -0,0 +1,342 @@ +package content + +import TestUtils +import core.api.asItem +import core.api.setAttribute +import core.game.global.action.DropListener +import core.game.node.entity.player.info.Rights +import core.game.node.entity.player.link.IronmanMode +import core.game.world.map.Location +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test +import org.rs09.consts.Items +import core.game.node.entity.combat.graves.GraveType +import core.game.node.entity.combat.graves.GraveController +import core.game.world.GameWorld +import core.tools.secondsToTicks +class DeathTests { + init { + //explicitly register the GraveController as a tick listener because tests don't run reflection + TestUtils.preTestSetup() // need cache parsed to properly evaluate item values + GameWorld.tickListeners.add(GraveController()) + } + //Grave requirements source: https://runescape.wiki/w/Gravestone?oldid=854455 + + @Test fun graveUtilsProduceGraveShouldProduceCorrectGrave() { + val type = GraveType.MEM_PLAQUE + val grave = GraveController.produceGrave(type) + + Assertions.assertEquals(type, grave.type) + } + + @Test fun graveInitializedWithItemsShouldInitializeCorrectly() { + val inventory = arrayOf( + Items.RUNE_SCIMITAR_1333.asItem(), + Items.RUNE_SCIMITAR_1333.asItem(), + Items.RUNE_SCIMITAR_1333.asItem(), + Items.YELLOW_BEAD_1472.asItem() + ) + val player = TestUtils.getMockPlayer("gravetest", IronmanMode.NONE, Rights.REGULAR_PLAYER) + + val grave = GraveController.produceGrave(GraveType.MEM_PLAQUE) + grave.initialize(player, Location.create(0,0,0), inventory) + + for (item in grave.getItems()) { + Assertions.assertEquals(player, item.dropper) + Assertions.assertEquals(player.details.uid, item.dropperUid) + Assertions.assertEquals( + GameWorld.ticks + secondsToTicks(GraveType.MEM_PLAQUE.durationMinutes * 60), + item.decayTime + ) + Assertions.assertEquals(true, item.isRemainPrivate) + Assertions.assertEquals(true, item.id in inventory.map { it.id }.toIntArray()) + Assertions.assertEquals(true, grave.isActive) + } + } + + @Test fun graveInitializedWithNoItemsShouldNotSpawn() { + val grave = GraveController.produceGrave(GraveType.MEM_PLAQUE) + val p = TestUtils.getMockPlayer("gravetest") + + grave.initialize(p, Location.create(0,0,0), arrayOf()) + Assertions.assertEquals(false, grave.isActive) + } + + @Test fun graveInitializedWithEctophialAndPouchesShouldNotKeepThem() { + val inventory = arrayOf( + Items.ECTOPHIAL_4251.asItem(), + Items.SMALL_POUCH_5509.asItem(), + Items.MEDIUM_POUCH_5510.asItem(), + Items.MEDIUM_POUCH_5511.asItem(), + Items.LARGE_POUCH_5512.asItem(), + Items.LARGE_POUCH_5513.asItem(), + Items.GIANT_POUCH_5514.asItem(), + Items.GIANT_POUCH_5515.asItem() + ) + val p = TestUtils.getMockPlayer("gravetest") + val grave = GraveController.produceGrave(GraveType.MEM_PLAQUE) + grave.initialize(p, Location.create(0,0,0), inventory) + + Assertions.assertEquals(true, grave.getItems().isEmpty()) + Assertions.assertEquals(false, grave.isActive) + } + + @Test fun graveInitializedWithDroppableUntradablesShouldKeepThem() { + val inventory = arrayOf( + Items.FIRE_CAPE_6570.asItem(), + Items.RUNE_DEFENDER_8850.asItem() + ) + val p = TestUtils.getMockPlayer("gravetest") + val grave = GraveController.produceGrave(GraveType.MEM_PLAQUE) + grave.initialize(p, Location.create(0,0,0), inventory) + + Assertions.assertEquals(2, grave.getItems().size) + Assertions.assertEquals(true, grave.isActive) + } + + @Test fun graveInitializedWithDestroyableItemsShouldNotKeepThem() { + val inventory = arrayOf( + Items.HOLY_GRAIL_19.asItem() + ) + val p = TestUtils.getMockPlayer("gravetest") + val grave = GraveController.produceGrave(GraveType.MEM_PLAQUE) + grave.initialize(p, Location.create(0,0,0), inventory) + + Assertions.assertEquals(0, grave.getItems().size) + Assertions.assertEquals(false, grave.isActive) + } + + @Test fun graveInitializedWithReleasableItemsShouldNotKeepThem() { + val inventory = arrayOf( + Items.CHINCHOMPA_10033.asItem(), + Items.CHINCHOMPA_9976.asItem(), + Items.BABY_IMPLING_JAR_11238.asItem() + ) + val p = TestUtils.getMockPlayer("gravetest") + val grave = GraveController.produceGrave(GraveType.MEM_PLAQUE) + grave.initialize(p, Location.create(0,0,0), inventory) + + Assertions.assertEquals(0, grave.getItems().size) + Assertions.assertEquals(false, grave.isActive) + } + + @Test fun graveInitializedWithItemThatHasDropTransformShouldContainTransformedItem() { + //We actually don't have any items that have this implemented yet, but we should test it once we do. + } + + @Test fun graveShouldSerializeAndDeserializeFromJsonCorrectly() { + val inventory = arrayOf( + Items.BRONZE_2H_SWORD_1307.asItem(), + Items.BRONZE_AXE_1351.asItem() + ) + + val startTime = GameWorld.ticks + val p = TestUtils.getMockPlayer("gravetest") + val grave = GraveController.produceGrave(GraveType.MEM_PLAQUE) + grave.initialize(p, Location.create(0,0,0), inventory) + + TestUtils.advanceTicks(30, false) + val expectedTicksRemaining = secondsToTicks(GraveType.MEM_PLAQUE.durationMinutes * 60) - (GameWorld.ticks - startTime) + Assertions.assertEquals(expectedTicksRemaining, grave.ticksRemaining) + + GraveController.serializeToServerStore() + GraveController.activeGraves.remove(p.details.uid) + GraveController.deserializeFromServerStore() + + val newGrave = GraveController.activeGraves[p.details.uid] + Assertions.assertNotNull(newGrave) + Assertions.assertEquals(expectedTicksRemaining, newGrave?.ticksRemaining ?: -1) + Assertions.assertEquals(2, newGrave?.getItems()?.size ?: -1) + + val expectedItemDecayTick = GameWorld.ticks + expectedTicksRemaining + Assertions.assertEquals(expectedItemDecayTick, newGrave?.getItems()?.get(0)?.decayTime ?: -1) + Assertions.assertEquals(true, newGrave?.isActive) + } + + @Test fun graveDeserializedFromServerStoreShouldNaturallyExpire() { + TestUtils.getMockPlayer("graveExpirationFromDeserializationTest").use {p -> + val inventory = arrayOf( + Items.BRONZE_2H_SWORD_1307.asItem(), + Items.BRONZE_AXE_1351.asItem() + ) + val startTime = GameWorld.ticks + val grave = GraveController.produceGrave(GraveType.MEM_PLAQUE) + grave.initialize(p, Location.create(0,0,0), inventory) + val expectedTicksRemaining = secondsToTicks(GraveType.MEM_PLAQUE.durationMinutes * 60) - (GameWorld.ticks - startTime) + Assertions.assertEquals(expectedTicksRemaining, grave.ticksRemaining) + + GraveController.serializeToServerStore() + GraveController.activeGraves.remove(p.details.uid) + GraveController.deserializeFromServerStore() + + var newGrave = GraveController.activeGraves[p.details.uid] + Assertions.assertNotNull(newGrave) + Assertions.assertEquals(expectedTicksRemaining, newGrave?.ticksRemaining ?: -1) + Assertions.assertEquals(2, newGrave?.getItems()?.size ?: -1) + + TestUtils.advanceTicks(expectedTicksRemaining + 1, false) + Assertions.assertEquals(null, GraveController.activeGraves[p.details.uid]) + + GraveController.serializeToServerStore() + GraveController.deserializeFromServerStore() + + newGrave = GraveController.activeGraves[p.details.uid] + Assertions.assertNull(newGrave) + } + } + + @Test fun regularDeathShouldSpawnGraveWithItems() { + val inventory = arrayOf( + Items.RUNE_SCIMITAR_1333.asItem(), + Items.RUNE_SCIMITAR_1333.asItem(), + Items.RUNE_SCIMITAR_1333.asItem(), //none of these should be in the grave due to having higher value + Items.YELLOW_BEAD_1472.asItem(), + Items.RED_BEAD_1470.asItem() + ) + val p = TestUtils.getMockPlayer("gravetester", IronmanMode.NONE, Rights.REGULAR_PLAYER) + p.location = Location.create(0,0,0) + p.setAttribute("tutorial:complete", true) + + for (item in inventory) + p.inventory.add(item) + + p.finalizeDeath(null) + + val grave = GraveController.activeGraves[p.details.uid] + Assertions.assertNotNull(grave) + Assertions.assertEquals(2, grave?.getItems()?.size ?: -1) + Assertions.assertEquals(false, grave?.getItems()?.map { it.id }?.contains(Items.RUNE_SCIMITAR_1333)) + } + + @Test fun skulledDeathShouldNotSpawnGrave() { + val inventory = arrayOf( + Items.ABYSSAL_WHIP_4151.asItem(), + Items.ABYSSAL_WHIP_4151.asItem(), + Items.ABYSSAL_WHIP_4151.asItem(), + Items.ABYSSAL_WHIP_4151.asItem(), + Items.ABYSSAL_WHIP_4151.asItem() + ) + val p = TestUtils.getMockPlayer("gravetester", IronmanMode.NONE, Rights.REGULAR_PLAYER) + p.location = Location.create(0,0,0) + p.setAttribute("tutorial:complete", true) + + for (item in inventory) + p.inventory.add(item) + + p.skullManager.isSkulled = true + p.finalizeDeath(null) + + val grave = GraveController.activeGraves[p.details.uid] + Assertions.assertNull(grave) + } + + @Test fun creatingNewGraveWithGraveAlreadyActiveShouldDestroyOldGrave() { + val inventory1 = arrayOf( + Items.RUNE_SCIMITAR_1333.asItem() + ) + val grave1 = GraveController.produceGrave(GraveType.MEM_PLAQUE) + val p = TestUtils.getMockPlayer("gravetester") + grave1.initialize(p, Location.create(0,0,0), inventory1) + + Assertions.assertEquals(true, grave1.isActive) + Assertions.assertEquals(Items.RUNE_SCIMITAR_1333, GraveController.activeGraves[p.details.uid]?.getItems()?.getOrNull(0)?.id ?: -1) + + val inventory2 = arrayOf( + Items.ABYSSAL_WHIP_4151.asItem() + ) + val grave2 = GraveController.produceGrave(GraveType.MEM_PLAQUE) + grave2.initialize(p, Location.create(0,0,0), inventory2) + + Assertions.assertEquals(false, grave1.isActive) + Assertions.assertEquals(true, grave2.isActive) + Assertions.assertEquals(Items.ABYSSAL_WHIP_4151, GraveController.activeGraves[p.details.uid]?.getItems()?.getOrNull(0)?.id ?: -1) + } + + @Test fun deathWithOnly3ItemsShouldNotProduceAGrave() { + val inventory = arrayOf( + Items.RUNE_SCIMITAR_1333.asItem(), + Items.RUNE_SCIMITAR_1333.asItem(), + Items.RUNE_SCIMITAR_1333.asItem() + ) + val p = TestUtils.getMockPlayer("gtester", IronmanMode.NONE, Rights.REGULAR_PLAYER) + p.location = Location.create(0,0,0) + p.setAttribute("tutorial:complete", true) + + for (item in inventory) + p.inventory.add(item) + + p.finalizeDeath(null) + + Assertions.assertNull(GraveController.activeGraves[p.details.uid]) + } + + @Test fun deathInsideWildernessShouldNotProduceAGrave() { + val inventory = arrayOf( + Items.RUNE_SCIMITAR_1333.asItem(), + Items.RUNE_SCIMITAR_1333.asItem(), + Items.RUNE_SCIMITAR_1333.asItem(), + Items.RUNE_SCIMITAR_1333.asItem(), + Items.RUNE_SCIMITAR_1333.asItem() + ) + val p = TestUtils.getMockPlayer("tester3333", IronmanMode.NONE, Rights.REGULAR_PLAYER) + p.skullManager.isWilderness = true + + for (item in inventory) { + p.inventory.add(item) + } + + p.finalizeDeath(null) + + Assertions.assertNull(GraveController.activeGraves[p.details.uid]) + } + + @Test fun deathWithRFDGlovesShouldKeepRFDGloves() { + val inventory = arrayOf( + Items.GLOVES_7453.asItem(), + Items.GLOVES_7454.asItem(), + Items.GLOVES_7455.asItem(), + Items.GLOVES_7456.asItem(), + Items.GLOVES_7457.asItem(), + Items.GLOVES_7458.asItem(), + Items.GLOVES_7459.asItem(), + Items.GLOVES_7460.asItem(), + Items.GLOVES_7461.asItem(), + Items.GLOVES_7462.asItem() + ) + val p = TestUtils.getMockPlayer("glovetest", IronmanMode.NONE, Rights.REGULAR_PLAYER) + + for(item in inventory) + p.inventory.add(item) + + p.finalizeDeath(null) + + val g = GraveController.activeGraves[p.details.uid] + Assertions.assertNotNull(g) + Assertions.assertEquals(7, g?.getItems()?.size ?: -1) + } + + @Test fun shouldNotBeAbleToDropItemOnGrave() { + val inventory = arrayOf( + Items.RUNE_SCIMITAR_1333.asItem(), + Items.RUNE_SCIMITAR_1333.asItem(), + Items.RUNE_SCIMITAR_1333.asItem(), + Items.RUNE_SCIMITAR_1333.asItem() + ) + val p = TestUtils.getMockPlayer("droptest", IronmanMode.NONE, Rights.REGULAR_PLAYER) + + for (item in inventory) + p.inventory.add(item) + + p.finalizeDeath(null) + p.inventory.add(Items.RUNE_SCIMITAR_1333.asItem()) + + val g = GraveController.activeGraves[p.details.uid] + + Assertions.assertNotNull(g) + Assertions.assertEquals(p.location, g?.location) + + setAttribute(p, "interact:option", "drop") + val canDrop = DropListener.drop(p, p.inventory[0]) + Assertions.assertEquals(false, canDrop) + } +} \ No newline at end of file diff --git a/Server/src/test/kotlin/content/DropTableTests.kt b/Server/src/test/kotlin/content/DropTableTests.kt new file mode 100644 index 0000000..001524c --- /dev/null +++ b/Server/src/test/kotlin/content/DropTableTests.kt @@ -0,0 +1,49 @@ +package content + +import TestUtils +import content.global.handlers.npc.ChromaticDragonBehavior +import core.ServerConstants +import core.api.utils.NPCDropTable +import core.api.utils.WeightedItem +import core.game.node.entity.npc.NPC +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class DropTableTests { + init { + TestUtils.preTestSetup() + } + @Test fun chromaticDragonsShouldDropEggsOnlyAfter99Summoning() { + val npc = NPC.create(NPCs.BLACK_DRAGON_54, ServerConstants.HOME_LOCATION) + val oldTable = npc.definition.dropTables.table + + val testTable = NPCDropTable() //manufacture a fake table that's guaranteed to give an egg, for testing safety. + testTable.add(WeightedItem(Items.BLACK_DRAGON_EGG_12480, 1, 1, 1.0)) + + npc.definition.dropTables.table = testTable + npc.behavior = ChromaticDragonBehavior() + + TestUtils.getMockPlayer("chromaticeggdrop").use { p -> + ChromaticDragonBehavior.EGG_RATE = 1 //guarantee egg drop if other parameters are satisfied + var hasEgg = false + + var items = npc.definition.dropTables.roll(npc, p, 1) + for (item in items) + if (item.id == Items.BLACK_DRAGON_EGG_12480) hasEgg = true + Assertions.assertEquals(false, hasEgg) + + p.skills.setStaticLevel(Skills.SUMMONING, 99) + + items = npc.definition.dropTables.roll(npc, p, 1) + for (item in items) + if (item.id == Items.BLACK_DRAGON_EGG_12480) hasEgg = true + Assertions.assertEquals(true, hasEgg) + } + + npc.definition.dropTables.table = oldTable + } +} \ No newline at end of file diff --git a/Server/src/test/kotlin/content/EquipTests.kt b/Server/src/test/kotlin/content/EquipTests.kt new file mode 100644 index 0000000..96a903a --- /dev/null +++ b/Server/src/test/kotlin/content/EquipTests.kt @@ -0,0 +1,169 @@ +package content + +import TestUtils +import core.api.EquipmentSlot +import core.api.addItem +import core.api.impact +import core.game.node.entity.skill.Skills +import core.game.node.item.Item +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test +import org.rs09.consts.Items +import core.game.global.action.EquipHandler +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.game.interaction.InteractionListeners +import core.game.node.entity.player.info.Rights + +class EquipTests { + companion object { + init {TestUtils.preTestSetup(); EquipHandler().defineListeners()} + } + + @Test fun equipShouldFireEquipListeners() { + var didRun = false + val listener = object : InteractionListener { + override fun defineListeners() { + onEquip(4151) {_,_ -> didRun = true; return@onEquip true} + } + } + listener.defineListeners() + + val p = TestUtils.getMockPlayer("bill") + p.inventory.add(Item(4151)) + InteractionListeners.run(4151, IntType.ITEM, "equip", p, p.inventory[0]) + + Assertions.assertEquals(true, didRun) + } + + @Test fun unequipShouldFireUnequipListeners() { + var didRun = false + val listener = object : InteractionListener { + override fun defineListeners() { + onUnequip(4151) {_,_ -> didRun = true; return@onUnequip true} + } + } + listener.defineListeners() + + val p = TestUtils.getMockPlayer("bill") + p.equipment.replace(Item(4151), EquipmentSlot.WEAPON.ordinal) + EquipHandler.unequip(p, EquipmentSlot.WEAPON.ordinal, 4151) + + Assertions.assertEquals(true, didRun) + } + + @Test fun equippingItemThatReplacesAnotherItemShouldCallUnequipListenersForTheReplacedItem() { + var didRun = false + val listener = object : InteractionListener { + override fun defineListeners() { + onUnequip(4151) {_,_ -> didRun = true; return@onUnequip true} + } + } + listener.defineListeners() + + val p = TestUtils.getMockPlayer("bill") + p.equipment.replace(Item(4151), EquipmentSlot.WEAPON.ordinal) + p.inventory.add(Item(1333)) + p.skills.staticLevels[Skills.ATTACK] = 40 + InteractionListeners.run(1333, IntType.ITEM, "equip", p, p.inventory[0]) + + Assertions.assertEquals(true, didRun, p.equipment.toString()) + } + + @Test fun equippingItemShouldAddUnequippedItemToExistingStackInInventory() { + val p = TestUtils.getMockPlayer("bill") + p.skills.staticLevels[Skills.ATTACK] = 99 + p.equipment.replace(Item(Items.BRONZE_DART_806, 1000), EquipmentSlot.WEAPON.ordinal) + p.inventory.add(Item(Items.BRONZE_DART_806, 1000)) + p.inventory.add(Item(Items.RUNE_SCIMITAR_1333)) + + InteractionListeners.run(Items.RUNE_SCIMITAR_1333, IntType.ITEM, "equip", p, p.inventory[1]) + Assertions.assertEquals(2000, p.inventory.getAmount(Items.BRONZE_DART_806), "\n" + p.inventory.toString() + "\n" + p.equipment.toString()) + } + + @Test fun equippingItemThatUnequipsTwoItemsShouldBeAllowedWithOnlyOneInitiallyFreeSlot() { + val p = TestUtils.getMockPlayer("bill") + p.equipment.replace(Item(Items.BRONZE_SWORD_1277), EquipmentSlot.WEAPON.ordinal) + p.equipment.replace(Item(Items.WOODEN_SHIELD_1171), EquipmentSlot.SHIELD.ordinal) + + p.inventory.add(Item(Items.CUP_OF_TEA_1978, 26)) + p.inventory.add(Item(Items.BRONZE_2H_SWORD_1307)) + + Assertions.assertEquals(1, p.inventory.freeSlots()) + + InteractionListeners.run(Items.BRONZE_2H_SWORD_1307, IntType.ITEM, "equip", p, p.inventory[26]) + Assertions.assertEquals(0, p.inventory.freeSlots()) + Assertions.assertEquals(Items.BRONZE_SWORD_1277, p.inventory[26].id) + Assertions.assertEquals(Items.WOODEN_SHIELD_1171, p.inventory[27].id) + } + + @Test fun shouldNotBeAbleToEquipA2HWeaponAndAShieldAtTheSameTime() { + val p = TestUtils.getMockPlayer("bill") + p.inventory.add(Item(Items.BRONZE_2H_SWORD_1307)) + p.inventory.add(Item(Items.WOODEN_SHIELD_1171)) + + InteractionListeners.run(Items.BRONZE_2H_SWORD_1307, IntType.ITEM, "equip", p, p.inventory[0]) + Assertions.assertEquals(Items.BRONZE_2H_SWORD_1307, p.equipment.get(EquipmentSlot.WEAPON.ordinal).id) + + InteractionListeners.run(Items.WOODEN_SHIELD_1171, IntType.ITEM, "equip", p, p.inventory[1]) + Assertions.assertEquals(Items.BRONZE_2H_SWORD_1307, p.inventory[1]?.id ?: -1) + } + + @Test fun equippingShieldShouldNotUnequipOneHandedWeapon() { + val p = TestUtils.getMockPlayer("bill") + p.inventory.add(Item(Items.BRONZE_SWORD_1277)) + p.inventory.add(Item(Items.WOODEN_SHIELD_1171)) + + InteractionListeners.run(Items.BRONZE_SWORD_1277, IntType.ITEM, "equip", p, p.inventory[0]) + Assertions.assertEquals(Items.BRONZE_SWORD_1277, p.equipment[EquipmentSlot.WEAPON.ordinal].id) + + InteractionListeners.run(Items.WOODEN_SHIELD_1171, IntType.ITEM, "equip", p, p.inventory[1]) + Assertions.assertEquals(Items.BRONZE_SWORD_1277, p.equipment[EquipmentSlot.WEAPON.ordinal]?.id ?: -1) + } + + @Test fun equippingStackableItemShouldAddToExistingStackInEquipmentIfApplicable() { + val p = TestUtils.getMockPlayer("bill") + p.equipment.replace(Item(Items.BRONZE_ARROW_882, 100), EquipmentSlot.AMMO.ordinal) + p.inventory.add(Item(Items.BRONZE_ARROW_882, 200)) + + InteractionListeners.run(Items.BRONZE_ARROW_882, IntType.ITEM, "equip", p, p.inventory[0]) + Assertions.assertEquals(300, p.equipment[EquipmentSlot.AMMO.ordinal].amount) + } + + @Test fun swappingEquipmentShouldPreserveInventorySlots() { + val p = TestUtils.getMockPlayer("bill") + p.skills.staticLevels[Skills.ATTACK] = 70 + p.skills.staticLevels[Skills.DEFENCE] = 40 + p.equipment.replace(Item(Items.ABYSSAL_WHIP_4151), EquipmentSlot.WEAPON.ordinal) + p.equipment.replace(Item(Items.RUNE_DEFENDER_8850), EquipmentSlot.SHIELD.ordinal) + p.inventory.add(Item(Items.DRAGON_CLAWS_14484), true, 25) + Assertions.assertEquals(p.inventory.getSlot(Item(Items.DRAGON_CLAWS_14484)), 25) + + InteractionListeners.run(Items.DRAGON_CLAWS_14484, IntType.ITEM, "equip", p, p.inventory[25]) + Assertions.assertEquals(Items.DRAGON_CLAWS_14484, p.equipment.get(EquipmentSlot.WEAPON.ordinal).id) + Assertions.assertEquals(p.inventory.getSlot(Item(Items.ABYSSAL_WHIP_4151)), 25) + Assertions.assertEquals(p.inventory.getSlot(Item(Items.RUNE_DEFENDER_8850)), 0) + } + + @Test fun graveDeathWithEquippedItemShouldFireUnequipHooks() { + TestUtils.getMockPlayer("graveunequip").use {p -> + var hookFired = false + val tempHook = object : InteractionListener { + override fun defineListeners() { + onUnequip(Items.ABYSSAL_WHIP_4151) { player, node -> + hookFired = true + return@onUnequip true + } + } + } + + tempHook.defineListeners() + p.details.rights = Rights.REGULAR_PLAYER + addItem(p, Items.ABYSSAL_WHIP_4151, 28) + p.equipment.replace(Item(Items.ABYSSAL_WHIP_4151), EquipmentSlot.WEAPON.ordinal) + impact(p, p.skills.lifepoints) + TestUtils.advanceTicks(25, false) + Assertions.assertEquals(true, hookFired) + } + } +} diff --git a/Server/src/test/kotlin/content/ListenerTests.kt b/Server/src/test/kotlin/content/ListenerTests.kt new file mode 100644 index 0000000..b6316ed --- /dev/null +++ b/Server/src/test/kotlin/content/ListenerTests.kt @@ -0,0 +1,47 @@ +package content + +import TestUtils +import core.game.node.item.Item +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test +import core.game.interaction.InteractionListener +import core.game.interaction.IntType +import core.game.interaction.InteractionListeners + +class ListenerTests : InteractionListener { + init {TestUtils.preTestSetup()} + @Test fun doubleDefinedListenerShouldThrowIllegalStateException() { + on(0, IntType.ITEM, "touch") { _, _ -> return@on true} + Assertions.assertThrows(IllegalStateException::class.java) { + on(0, IntType.ITEM, "touch") { _, _ -> return@on true} + } + } + + @Test fun doubleDefinedUseWithShouldThrowIllegalStateException() { + onUseWith(IntType.SCENERY, 0, 1) { _, _, _ -> return@onUseWith true} + Assertions.assertThrows(IllegalStateException::class.java) { + onUseWith(IntType.SCENERY, 0, 1) { _, _, _ -> return@onUseWith true} + } + } + + @Test fun conflictingCatchallShouldThrowIllegalStateException() { + on(IntType.ITEM, "boop"){ _, _ -> return@on true} + Assertions.assertThrows(IllegalStateException::class.java) { + on(IntType.ITEM, "boop") { _, _ -> return@on true} + } + } + + @Test fun specificListenerShouldOverrideCatchallListener() { + var specificRan = false + var catchAllRan = false + on(IntType.ITEM, "zap") { _, _ -> catchAllRan = true; return@on true} + on(1, IntType.ITEM, "zap") { _, _ -> specificRan = true; return@on true} + + InteractionListeners.run(1, IntType.ITEM, "zap", TestUtils.getMockPlayer("bilbots"), Item(1)) + + Assertions.assertEquals(false, catchAllRan) + Assertions.assertEquals(true, specificRan) + } + + override fun defineListeners() {} +} \ No newline at end of file diff --git a/Server/src/test/kotlin/content/RandomEventTests.kt b/Server/src/test/kotlin/content/RandomEventTests.kt new file mode 100644 index 0000000..9ab1aa0 --- /dev/null +++ b/Server/src/test/kotlin/content/RandomEventTests.kt @@ -0,0 +1,226 @@ +package content + +import TestUtils +import content.global.ame.RandomEventNPC +import content.global.ame.RandomEvents +import core.api.* +import core.game.system.timer.impl.AntiMacro +import core.game.world.map.Location +import core.game.world.map.zone.impl.WildernessZone +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class RandomEventTests { + init { + TestUtils.preTestSetup() + } + + @Test fun loginShouldRegisterRandomEventTimer() { + TestUtils.getMockPlayer("antimacroAutoRegister").use { p -> + Assertions.assertNotNull(getTimer(p)) + } + } + + @Test fun loginShouldSetNextSpawn() { + TestUtils.getMockPlayer("antimacroautosetsnextspawnifunset").use { p -> + val timer = getTimer(p) ?: Assertions.fail("AntiMacro timer is null.") + Assertions.assertNotEquals(getWorldTicks(), timer.nextExecution) + Assertions.assertEquals(true, timer.nextExecution - getWorldTicks() >= AntiMacro.MIN_DELAY_TICKS) + Assertions.assertEquals(true, timer.nextExecution - getWorldTicks() <= AntiMacro.MAX_DELAY_TICKS) + } + } + + @Test fun remainingDelayShouldPersistRelog() { + TestUtils.getMockPlayer("antimacrotimeremainingpersists").use { p -> + val timer = getTimer(p) ?: Assertions.fail("AntiMacro timer is null.") + timer.nextExecution = getWorldTicks() + 666 + p.relog(ticksToWait = 100) + Assertions.assertEquals(getWorldTicks() + 666, getTimer(p)!!.nextExecution) + } + } + + @Test fun delayShouldBeRestartedOnceDepleted() { + TestUtils.getMockPlayer("delayrestartoncedepleted").use { p -> + val timer = getTimer(p) ?: Assertions.fail("AntiMacro timer is null.") + TestUtils.advanceTicks(2, false) + timer.nextExecution = 5 //run in 5 ticks + TestUtils.advanceTicks(5, false) + Assertions.assertEquals(true, timer.nextExecution - getWorldTicks() >= AntiMacro.MIN_DELAY_TICKS) + Assertions.assertEquals(true, timer.nextExecution - getWorldTicks() <= AntiMacro.MAX_DELAY_TICKS) + } + } + + @Test fun shouldSpawnRandomEventGivenNoRestrictions() { + TestUtils.getMockPlayer("antimacroshouldspawnrandom").use {p -> + val timer = getTimer(p) ?: Assertions.fail("AntiMacro timer is null!") + TestUtils.advanceTicks(5, false) + timer.nextExecution = getWorldTicks() + 5 + TestUtils.advanceTicks(10, false) + Assertions.assertNotNull(p.getAttribute(AntiMacro.EVENT_NPC, null)) + Assertions.assertEquals(true, p.getAttribute(AntiMacro.EVENT_NPC).isActive) + } + } + + @Test fun shouldNotSpawnForArtificialPlayer() { + TestUtils.getMockPlayer("antimacroshouldspawnrandom", isBot = true).use {p -> + val timer = getTimer(p) + Assertions.assertEquals(null, timer) + } + } + + @Test fun teleportAndNotePunishmentShouldNotAffectAlreadyNotedItems() { + TestUtils.getMockPlayer("teleportpunishment1").use {p -> + val timer = getTimer(p) ?: Assertions.fail("AntiMacro timer is null!") + TestUtils.advanceTicks(5, false) + timer.nextExecution = getWorldTicks() + 5 + TestUtils.advanceTicks(10, false) + + addItem(p, Items.RAW_SHARK_384, 1000) + getAttribute(p, AntiMacro.EVENT_NPC, null)!!.noteAndTeleport() + + Assertions.assertEquals(1000, amountInInventory(p, Items.RAW_SHARK_384)) + } + } + + @Test fun teleportAndNotePunishmentShouldNoteNotableUnnotedItems() { + TestUtils.getMockPlayer("teleportpunishment2").use {p -> + val timer = getTimer(p) ?: Assertions.fail("AntiMacro timer is null!") + TestUtils.advanceTicks(5, false) + timer.nextExecution = getWorldTicks() + 5 + TestUtils.advanceTicks(10, false) + + addItem(p, Items.ABYSSAL_WHIP_4151, 5) + getAttribute(p, AntiMacro.EVENT_NPC, null)!!.noteAndTeleport() + + Assertions.assertEquals(5, amountInInventory(p, Items.ABYSSAL_WHIP_4152)) + Assertions.assertEquals(0, amountInInventory(p, Items.ABYSSAL_WHIP_4151)) + } + } + + @Test fun teleportAndNotePunishmentShouldNotAffectUnnotableItems() { + TestUtils.getMockPlayer("teleportpunishment3").use {p -> + val timer = getTimer(p) ?: Assertions.fail("AntiMacro timer is null!") + TestUtils.advanceTicks(5, false) + timer.nextExecution = getWorldTicks() + 5 + TestUtils.advanceTicks(10, false) + + addItem(p, Items.AIR_RUNE_556, 30) + getAttribute(p, AntiMacro.EVENT_NPC, null)!!.noteAndTeleport() + + Assertions.assertEquals(30, amountInInventory(p, Items.AIR_RUNE_556)) + } + } + + @Test fun randomEventShouldNotSpawnInEventRestrictedArea() { + + TestUtils.getMockPlayer("antimacronospawninrestrictedzone").use { p -> + val timer = getTimer(p) ?: Assertions.fail("AntiMacro timer was null!") + TestUtils.advanceTicks(5, false) + + //Wilderness is Random Event restricted + WildernessZone.getInstance().configure() + val loc = Location.create(3131, 3595) + p.location = loc + + Assertions.assertEquals(loc, p.location) + + timer.nextExecution = getWorldTicks() + 5 + TestUtils.advanceTicks(10, false) + Assertions.assertNull(AntiMacro.getEventNpc(p)) + } + } + + //FIXME + //@Test fun randomEventShouldNotSpawnIfOneAlreadyActive() { + // TestUtils.getMockPlayer("antimacronospawnifalreadyhas").use { p -> + // val timer = getTimer(p) ?: Assertions.fail("AntiMacro timer was null!") + // TestUtils.advanceTicks(5, false) + // timer.nextExecution = getWorldTicks() + 5 + // TestUtils.advanceTicks(10, false) + // Assertions.assertNotNull(AntiMacro.getEventNpc(p)) + + // val previousEvent = AntiMacro.getEventNpc(p) + + // timer.nextExecution = getWorldTicks() + 5 + // TestUtils.advanceTicks(10, false) + // Assertions.assertNotNull(AntiMacro.getEventNpc(p)) + // Assertions.assertEquals(previousEvent, AntiMacro.getEventNpc(p)) + // } + //} + + //FIXME + //@Test fun randomEventShouldSpawnIfCurrentOneIsInactive() { + // TestUtils.getMockPlayer("antimacrospawnifcurrentinactive").use { p -> + // val timer = getTimer(p) ?: Assertions.fail("AntiMacro timer was null!") + // TestUtils.advanceTicks(5, false) + // timer.nextExecution = getWorldTicks() + 5 + // TestUtils.advanceTicks(10, false) + // Assertions.assertNotNull(AntiMacro.getEventNpc(p)) + + // val previousEvent = AntiMacro.getEventNpc(p) + // AntiMacro.terminateEventNpc(p) + + // timer.nextExecution = getWorldTicks() + 5 + // TestUtils.advanceTicks(10, false) + // Assertions.assertNotNull(AntiMacro.getEventNpc(p)) + // Assertions.assertNotEquals(previousEvent, AntiMacro.getEventNpc(p)) + // } + //} + + @Test fun randomEventSystemShouldSupportPauseAndUnpause() { + TestUtils.getMockPlayer("antimacropause").use { p -> + val timer = getTimer(p) ?: Assertions.fail("AntiMacro timer was null!") + TestUtils.advanceTicks(5, false) + timer.nextExecution = getWorldTicks() + 5 + + AntiMacro.pause(p) + TestUtils.advanceTicks(10, false) + Assertions.assertNull(AntiMacro.getEventNpc(p)) + + AntiMacro.unpause(p) + timer.nextExecution = getWorldTicks() + 5 + TestUtils.advanceTicks(10, false) + Assertions.assertNotNull(AntiMacro.getEventNpc(p)) + } + } + + @Test fun shouldBeAbleToForceRandomEvent() { + TestUtils.getMockPlayer("antimacroforcerand").use { p -> + TestUtils.advanceTicks(5, false) + AntiMacro.forceEvent(p) + TestUtils.advanceTicks(1, false) + Assertions.assertNotNull(AntiMacro.getEventNpc(p)) + } + } + + @Test fun shouldBeAbleToForceSpecificRandomEvent() { + TestUtils.getMockPlayer("antimacroforcespecific").use { p -> + TestUtils.advanceTicks(5, false) + AntiMacro.forceEvent(p, RandomEvents.TREE_SPIRIT) + TestUtils.advanceTicks(1, false) + Assertions.assertNotNull(AntiMacro.getEventNpc(p)) + Assertions.assertEquals(NPCs.TREE_SPIRIT_438, AntiMacro.getEventNpc(p)?.originalId) + } + } + + @Test fun parseAntiMacroCommandArgsShouldReturnExpectedValues() { + val testData = arrayOf( + Triple("revent -p test", "test", null), + Triple("revent -p test ", "test", null), + Triple("revent -p test -e certer ", "test", RandomEvents.CERTER), + Triple("revent -p test_user -e Sandwich lady", "test_user", RandomEvents.SANDWICH_LADY), + Triple("revent -p test user -e sandwich Lady ", "test_user", RandomEvents.SANDWICH_LADY), + Triple("revent -e sandwich Lady -p test user ", "test_user", RandomEvents.SANDWICH_LADY), + Triple("revent test", "test", null), + Triple("revent test -e sAndwich Lady", "test", RandomEvents.SANDWICH_LADY) + ) + + for ((commandStr, expectedUser, expectedEvent) in testData) { + val (resultUser, resultEvent) = AntiMacro.parseCommandArgs(commandStr, "revent") + Assertions.assertEquals(expectedUser, resultUser) + Assertions.assertEquals(expectedEvent, resultEvent) + } + } +} diff --git a/Server/src/test/kotlin/content/activity/blastfurnace/BFBeltOreTests.kt b/Server/src/test/kotlin/content/activity/blastfurnace/BFBeltOreTests.kt new file mode 100644 index 0000000..0d8f336 --- /dev/null +++ b/Server/src/test/kotlin/content/activity/blastfurnace/BFBeltOreTests.kt @@ -0,0 +1,44 @@ +package content.activity.blastfurnace + +import TestUtils +import content.minigame.blastfurnace.BFBeltOre +import content.minigame.blastfurnace.BlastFurnace +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test +import org.rs09.consts.Items + +class BFBeltOreTests { + init {TestUtils.preTestSetup()} + + @Test fun oreShouldMoveCloserToPotWhenTicked() { + TestUtils.getMockPlayer("bf-oremove-test").use { p -> + p.location = BFBeltOre.ORE_START_LOC + val ore = BlastFurnace.addOreToBelt(p, Items.IRON_ORE_440, 5) + Assertions.assertEquals(BFBeltOre.ORE_START_LOC, ore.location) + Assertions.assertEquals(BFBeltOre.ORE_START_LOC, ore.npcInstance?.location) + + ore.tick() + val expectedLoc = BFBeltOre.ORE_START_LOC.transform(0, -1, 0) + Assertions.assertEquals(expectedLoc, ore.location) + Assertions.assertEquals(expectedLoc, ore.npcInstance?.properties?.teleportLocation) + + TestUtils.advanceTicks(1, false) + ore.tick() + Assertions.assertEquals(expectedLoc, ore.npcInstance?.location) + } + } + + @Test fun oreShouldBeAddedToOreContainerAfterReachingEnd() { + TestUtils.getMockPlayer("bf-oremoveadd-test").use { p -> + p.location = BFBeltOre.ORE_START_LOC + val ore = BlastFurnace.addOreToBelt(p, Items.IRON_ORE_440, 5) + + for (i in 0 until 4) + if (ore.tick()) BlastFurnace.getPlayerState(p).oresOnBelt.remove(ore) + + val container = BlastFurnace.getOreContainer(p) + Assertions.assertEquals(5, container.getOreAmount(Items.IRON_ORE_440)) + Assertions.assertEquals(0, BlastFurnace.getAmountOnBelt(p, Items.IRON_ORE_440)) + } + } +} \ No newline at end of file diff --git a/Server/src/test/kotlin/content/activity/blastfurnace/BFPlayerStateTests.kt b/Server/src/test/kotlin/content/activity/blastfurnace/BFPlayerStateTests.kt new file mode 100644 index 0000000..cafd269 --- /dev/null +++ b/Server/src/test/kotlin/content/activity/blastfurnace/BFPlayerStateTests.kt @@ -0,0 +1,101 @@ +package content.activity.blastfurnace + +import TestUtils +import content.global.skill.smithing.smelting.Bar +import content.minigame.blastfurnace.BFPlayerState +import content.minigame.blastfurnace.BlastFurnace +import core.api.addItem +import core.api.amountInInventory +import core.api.setVarbit +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test +import org.rs09.consts.Items + +class BFPlayerStateTests { + init { TestUtils.preTestSetup() } + + @Test fun processOreIntoBarsShouldDoNothingIfBarsNotCooled() { + TestUtils.getMockPlayer("bf-barsnotcooled").use { p -> + val state = BlastFurnace.getPlayerState(p) + state.container.addOre(Items.IRON_ORE_440, 28) + Assertions.assertEquals(true, state.processOresIntoBars()) + Assertions.assertEquals(28, state.container.getBarAmount(Bar.IRON)) + + state.container.addCoal(40) + state.container.addOre(Items.RUNITE_ORE_451, 10) + Assertions.assertEquals(false, state.processOresIntoBars()) + + Assertions.assertEquals(0, state.container.getBarAmount(Bar.RUNITE)) + } + } + + @Test fun processOreIntoBarsShouldDoNothingIfBarsUnchecked() { + TestUtils.getMockPlayer("bf-barsnotchecked").use { p -> + val state = BlastFurnace.getPlayerState(p) + state.container.addOre(Items.IRON_ORE_440, 28) + Assertions.assertEquals(true, state.processOresIntoBars()) + state.coolBars() + + state.container.addCoal(40) + state.container.addOre(Items.RUNITE_ORE_451, 10) + Assertions.assertEquals(false, state.processOresIntoBars()) + Assertions.assertEquals(0, state.container.getBarAmount(Bar.RUNITE)) + + state.checkBars() + Assertions.assertEquals(true, state.processOresIntoBars()) + Assertions.assertEquals(10, state.container.getBarAmount(Bar.RUNITE)) + } + } + + @Test fun shouldBeAbleToClaimBars() { + TestUtils.getMockPlayer("bf-barclaiminig").use { p -> + val state = BlastFurnace.getPlayerState(p) + state.container.addOre(Items.IRON_ORE_440, 28) + Assertions.assertEquals(true, state.processOresIntoBars()) + state.coolBars() + + Assertions.assertEquals(true, state.claimBars(Bar.IRON, 5)) + Assertions.assertEquals(5, amountInInventory(p, Items.IRON_BAR_2351)) + Assertions.assertEquals(23, state.container.getBarAmount(Bar.IRON)) + } + } + + @Test fun shouldNotBeAbleToClaimMoreBarsThanFreeInventorySlots() { + TestUtils.getMockPlayer("bf-claimbarslessslots").use { p -> + val state = BlastFurnace.getPlayerState(p) + state.container.addOre(Items.IRON_ORE_440, 28) + Assertions.assertEquals(true, state.processOresIntoBars()) + state.coolBars() + + addItem(p, Items.ABYSSAL_WHIP_4151, 27) + + Assertions.assertEquals(true, state.claimBars(Bar.IRON, 5)) + Assertions.assertEquals(1, amountInInventory(p, Items.IRON_BAR_2351)) + Assertions.assertEquals(27, state.container.getBarAmount(Bar.IRON)) + } + } + + @Test fun claimBarsShouldDoNothingAndGrantNoItemIfInventoryFull() { + TestUtils.getMockPlayer("bf-claimbarsnoslots").use { p -> + val state = BlastFurnace.getPlayerState(p) + state.container.addOre(Items.IRON_ORE_440, 28) + Assertions.assertEquals(true, state.processOresIntoBars()) + state.coolBars() + + addItem(p, Items.ABYSSAL_WHIP_4151, 28) + + Assertions.assertEquals(false, state.claimBars(Bar.IRON, 5)) + Assertions.assertEquals(0, amountInInventory(p, Items.IRON_BAR_2351)) + Assertions.assertEquals(28, state.container.getBarAmount(Bar.IRON)) + } + } + + @Test fun claimBarsShouldDoNothingIfBarsNotCooled() { + TestUtils.getMockPlayer("bf-claimbarsnotcooled").use { p -> + val state = BlastFurnace.getPlayerState(p) + state.container.addOre(Items.IRON_ORE_440, 28) + Assertions.assertEquals(true, state.processOresIntoBars()) + Assertions.assertEquals(false, state.claimBars(Bar.IRON, 5)) + } + } +} \ No newline at end of file diff --git a/Server/src/test/kotlin/content/activity/blastfurnace/BFSceneryControllerTests.kt b/Server/src/test/kotlin/content/activity/blastfurnace/BFSceneryControllerTests.kt new file mode 100644 index 0000000..0462818 --- /dev/null +++ b/Server/src/test/kotlin/content/activity/blastfurnace/BFSceneryControllerTests.kt @@ -0,0 +1,42 @@ +package content.activity.blastfurnace + +import content.minigame.blastfurnace.BFSceneryController +import core.api.getScenery +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test + +class BFSceneryControllerTests { + init { TestUtils.preTestSetup(); BFSceneryController().resetAllScenery() } + + @Test + fun updateBrokenShouldReplaceWithCorrectVariants() { + val scenCont = BFSceneryController() + + scenCont.updateBreakable(true, true, true, true) + Assertions.assertEquals(BFSceneryController.BROKEN_BELT, getScenery(BFSceneryController.beltGearRight)?.id) + Assertions.assertEquals(BFSceneryController.BROKEN_COG, getScenery(BFSceneryController.cogRightLoc)?.id) + Assertions.assertEquals(BFSceneryController.BROKEN_POT_PIPE, getScenery(BFSceneryController.potPipeLoc)?.id) + Assertions.assertEquals(BFSceneryController.BROKEN_PUMP_PIPE, getScenery(BFSceneryController.pumpPipeLoc)?.id) + + scenCont.updateBreakable(false, false, false, false) + Assertions.assertEquals(BFSceneryController.DEFAULT_BELT, getScenery(BFSceneryController.beltGearRight)?.id) + Assertions.assertEquals(BFSceneryController.DEFAULT_COG, getScenery(BFSceneryController.cogRightLoc)?.id) + Assertions.assertEquals(BFSceneryController.DEFAULT_POT_PIPE, getScenery(BFSceneryController.potPipeLoc)?.id) + Assertions.assertEquals(BFSceneryController.DEFAULT_PUMP_PIPE, getScenery(BFSceneryController.pumpPipeLoc)?.id) + } + + @Test + fun stoveIdShouldCorrespondToTemperature() { + val testData = arrayOf( + Pair(0, BFSceneryController.STOVE_COLD), + Pair(40, BFSceneryController.STOVE_WARM), + Pair(80, BFSceneryController.STOVE_HOT) + ) + for ((temp, expectedId) in testData) { + val cont = BFSceneryController() + cont.resetAllScenery() + cont.updateStove(temp) + Assertions.assertEquals(expectedId, getScenery(BFSceneryController.stoveLoc)!!.id) + } + } +} \ No newline at end of file diff --git a/Server/src/test/kotlin/content/activity/blastfurnace/BlastFurnaceAreaTests.kt b/Server/src/test/kotlin/content/activity/blastfurnace/BlastFurnaceAreaTests.kt new file mode 100644 index 0000000..8926443 --- /dev/null +++ b/Server/src/test/kotlin/content/activity/blastfurnace/BlastFurnaceAreaTests.kt @@ -0,0 +1,245 @@ +package content.activity.blastfurnace + +import TestUtils +import content.minigame.blastfurnace.BlastFurnace +import content.minigame.blastfurnace.BlastFurnaceListeners +import content.minigame.blastfurnace.BlastConsts +import core.ServerConstants +import core.api.addItem +import core.api.amountInInventory +import core.game.node.entity.skill.Skills +import core.game.world.map.Location +import core.game.world.map.RegionManager +import org.json.simple.JSONObject +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test +import org.rs09.consts.Items + +class BlastFurnaceAreaTests { + @Test fun shouldBeAbleToEnterBfArea() { + TestUtils.getMockPlayer("bf-enterable").use { p -> + p.skills.setStaticLevel(Skills.SMITHING, 60) + p.location = Location(2932, 10195, 0) + TestUtils.simulateInteraction(p, RegionManager.getObject(BlastConsts.STAIRLOC_ENTRANCE)!!, 0) + TestUtils.advanceTicks(5, false) + Assertions.assertEquals(BlastConsts.ENTRANCE_LOC, p.location) + } + } + + @Test fun shouldBeAbleToLeaveBfArea() { + TestUtils.getMockPlayer("bf-leavable").use { p -> + p.location = BlastConsts.ENTRANCE_LOC + TestUtils.simulateInteraction(p, RegionManager.getObject(BlastConsts.STAIRLOC_EXIT)!!, 0) + TestUtils.advanceTicks(5, false) + Assertions.assertEquals(BlastConsts.EXIT_LOC, p.location) + } + } + + @Test fun shouldNotBeAbleToEnterWithLessThan60Smithing() { + TestUtils.getMockPlayer("bf-60smith").use { p -> + p.location = Location(2932, 10195, 0) + TestUtils.simulateInteraction(p, RegionManager.getObject(BlastConsts.STAIRLOC_ENTRANCE)!!, 0) + TestUtils.advanceTicks(5, false) + Assertions.assertNotEquals(BlastConsts.ENTRANCE_LOC, p.location) + } + } + + @Test fun getFeePriceReturnsExpectedValues() { + val testData = arrayOf( + Triple(false, 10, 2500), + Triple(true, 10, 1250), + Triple(false, 60, 0), + Triple(true, 60, 0), + Triple(false, 59, 2500), + Triple(true, 59, 1250) + ) + for ((hasCharos, smithLevel, expected) in testData) + Assertions.assertEquals(expected, BlastFurnace.getEntranceFee(hasCharos, smithLevel)) + } + + @Test fun enterWithFeeShouldKickPlayerOutAfter10Minutes() { + TestUtils.getMockPlayer("bf-fee-kickout").use { p -> + BlastFurnace.enter(p, true) + TestUtils.advanceTicks(BlastConsts.FEE_ENTRANCE_DURATION + 2, false) + Assertions.assertNotEquals(BlastConsts.ENTRANCE_LOC, p.location) + } + } + + @Test fun shouldBeAbleToLeaveAndEnterFreelyWhileTimerActive() { + TestUtils.getMockPlayer("bf-fee-reentry").use { p -> + BlastFurnace.enter(p, true) + TestUtils.advanceTicks(2, false) + Assertions.assertEquals(BlastConsts.ENTRANCE_LOC, p.location) + TestUtils.simulateInteraction(p, RegionManager.getObject(BlastConsts.STAIRLOC_EXIT)!!, 0) + TestUtils.advanceTicks(2, false) + Assertions.assertEquals(BlastConsts.EXIT_LOC, p.location) + TestUtils.simulateInteraction(p, RegionManager.getObject(BlastConsts.STAIRLOC_ENTRANCE)!!, 0) + TestUtils.advanceTicks(2, false) + Assertions.assertEquals(BlastConsts.ENTRANCE_LOC, p.location) + + p.location = BlastConsts.EXIT_LOC + TestUtils.advanceTicks(BlastConsts.FEE_ENTRANCE_DURATION, false) + //should not allow free reentry if timer has run out + TestUtils.simulateInteraction(p, RegionManager.getObject(BlastConsts.STAIRLOC_ENTRANCE)!!, 0) + TestUtils.advanceTicks(2, false) + Assertions.assertEquals(BlastConsts.EXIT_LOC, p.location) + } + } + + @Test fun playerShouldOnlyBeTeleportedIfInsideBFArea() { + TestUtils.getMockPlayer("bf-fee-timeout-notele-outside-bf").use { p -> + BlastFurnace.enter(p, true) + TestUtils.advanceTicks(2, false) + Assertions.assertEquals(BlastConsts.ENTRANCE_LOC, p.location) + + p.location = ServerConstants.HOME_LOCATION + + TestUtils.advanceTicks(BlastConsts.FEE_ENTRANCE_DURATION, false) + Assertions.assertEquals(ServerConstants.HOME_LOCATION, p.location) + } + } + + @Test fun playerShouldBeAbleToPlaceOreOnBelt() { + TestUtils.getMockPlayer("bf-placeoreonbelt").use { p -> + addItem(p, Items.COAL_453, 2) + BlastFurnace.placeAllOre(p) + Assertions.assertEquals(2, BlastFurnace.getAmountOnBelt(p, Items.COAL_453)) + Assertions.assertEquals(0, amountInInventory(p, Items.COAL_453)) + } + } + + @Test fun playerShouldNotBeAbleToPlaceMoreOreThanCanFitOnBelt() { + TestUtils.getMockPlayer("bf-toomuchoreonbelt").use { p -> + val cont = BlastFurnace.getOreContainer(p) + cont.addCoal(BlastConsts.COAL_LIMIT - 15) + cont.addOre(Items.IRON_ORE_440, BlastConsts.ORE_LIMIT - 13) + + addItem(p, Items.COAL_453, 15) + addItem(p, Items.IRON_ORE_440, 13) + BlastFurnace.placeAllOre(p) + + addItem(p, Items.COAL_453, 15) + addItem(p, Items.IRON_ORE_440, 13) + BlastFurnace.placeAllOre(p) + + Assertions.assertEquals(15, amountInInventory(p, Items.COAL_453)) + Assertions.assertEquals(13, amountInInventory(p, Items.IRON_ORE_440)) + } + } + + @Test fun beltOreLimitsShouldAccountForCreatedBars() { + TestUtils.getMockPlayer("bf-baraccountedfor").use { p -> + val cont = BlastFurnace.getOreContainer(p) + cont.addOre(Items.IRON_ORE_440, BlastConsts.ORE_LIMIT - 15) + cont.convertToBars() + + addItem(p, Items.IRON_ORE_440, 20) + BlastFurnace.placeAllOre(p) + + Assertions.assertEquals(5, amountInInventory(p, Items.IRON_ORE_440)) + } + } + + @Test fun playerShouldBeAbleToOnlyPlaceSpecificOreOnBelt() { + TestUtils.getMockPlayer("bf-specific-oreplace").use { p -> + addItem(p, Items.IRON_ORE_440, 5) + addItem(p, Items.COAL_453, 3) + addItem(p, Items.RUNITE_ORE_451, 10) + BlastFurnace.placeAllOre(p, Items.RUNITE_ORE_451) + Assertions.assertEquals(0, amountInInventory(p, Items.RUNITE_ORE_451)) + Assertions.assertEquals(5, amountInInventory(p, Items.IRON_ORE_440)) + Assertions.assertEquals(3, amountInInventory(p, Items.COAL_453)) + } + } + + @Test fun playerShouldNotBeAbleToPlaceOresTheyLackTheLevelFor() { + TestUtils.getMockPlayer("bf-levelgate-oreplace").use { p -> + addItem(p, Items.RUNITE_ORE_451, 10) + BlastFurnace.placeAllOre(p, Items.RUNITE_ORE_451, accountForSkill = true) + Assertions.assertEquals(10, amountInInventory(p, Items.RUNITE_ORE_451)) + } + } + + @Test fun shouldNotBeAbleToOccupyExtraBronzeSlotsWithMoreThan28TinOrCopper() { + TestUtils.getMockPlayer("bf-bronze-orelimit").use { p -> + //Edge case - bronze bars have an edge case that allows 28 of both {copper, tin}, so this needs to make sure you can't, for example, add 56 copper. + addItem(p, Items.COPPER_ORE_436, 28) + BlastFurnace.placeAllOre(p) + addItem(p, Items.COPPER_ORE_436, 28) + BlastFurnace.placeAllOre(p) + + Assertions.assertEquals(28, BlastFurnace.getAmountOnBelt(p, Items.COPPER_ORE_436)) + Assertions.assertEquals(28, amountInInventory(p, Items.COPPER_ORE_436)) + + p.inventory.clear() + addItem(p, Items.TIN_ORE_438, 28) + BlastFurnace.placeAllOre(p) + addItem(p, Items.TIN_ORE_438, 28) + BlastFurnace.placeAllOre(p) + + Assertions.assertEquals(28, BlastFurnace.getAmountOnBelt(p, Items.TIN_ORE_438)) + Assertions.assertEquals(28, amountInInventory(p, Items.TIN_ORE_438)) + } + } + + @Test fun shouldNotBeAbleToPlaceMoreThan28TotalNonCoalOreOnTheBelt() { + TestUtils.getMockPlayer("bf-orelimit").use { p -> + addItem(p, Items.GOLD_ORE_444, 28) + BlastFurnace.placeAllOre(p) + addItem(p, Items.RUNITE_ORE_451, 28) + BlastFurnace.placeAllOre(p) + + Assertions.assertEquals(28, BlastFurnace.getAmountOnBelt(p, Items.GOLD_ORE_444)) + Assertions.assertEquals(0, amountInInventory(p, Items.GOLD_ORE_444)) + Assertions.assertEquals(0, BlastFurnace.getAmountOnBelt(p, Items.RUNITE_ORE_451)) + Assertions.assertEquals(28, amountInInventory(p, Items.RUNITE_ORE_451)) + } + } + + @Test fun shouldBeAbleToPlace28CopperAndTinOreOnTheBelt() { + TestUtils.getMockPlayer("bf-orelimit").use { p -> + addItem(p, Items.COPPER_ORE_436, 28) + BlastFurnace.placeAllOre(p) + addItem(p, Items.TIN_ORE_438, 28) + BlastFurnace.placeAllOre(p) + + Assertions.assertEquals(28, BlastFurnace.getAmountOnBelt(p, Items.COPPER_ORE_436)) + Assertions.assertEquals(0, amountInInventory(p, Items.COPPER_ORE_436)) + Assertions.assertEquals(28, BlastFurnace.getAmountOnBelt(p, Items.TIN_ORE_438)) + Assertions.assertEquals(0, amountInInventory(p, Items.TIN_ORE_438)) + } + } + + @Test fun BFAreaShouldPersistInfoAcrossPlayerRelogs() { + TestUtils.getMockPlayer("bf-persistence").use { p -> + var container = BlastFurnace.getOreContainer(p) + container.addOre(Items.IRON_ORE_440, 15) + container.addCoal(40) + + BlastFurnace.addOreToBelt(p, Items.IRON_ORE_440, 4) + BlastFurnace.addOreToBelt(p, Items.RUNITE_ORE_451, 10) + BlastFurnace.addOreToBelt(p, Items.COAL_453, 20) + + val area = BlastFurnace() + val saveObj = JSONObject() + area.savePlayer(p, saveObj) + + BlastFurnace.playerStates.clear() + + area.parsePlayer(p, saveObj) + container = BlastFurnace.getOreContainer(p) + Assertions.assertEquals(15, container.getOreAmount(Items.IRON_ORE_440)) + Assertions.assertEquals(40, container.coalAmount()) + Assertions.assertEquals(4, BlastFurnace.getAmountOnBelt(p, Items.IRON_ORE_440)) + Assertions.assertEquals(10, BlastFurnace.getAmountOnBelt(p, Items.RUNITE_ORE_451)) + Assertions.assertEquals(20, BlastFurnace.getAmountOnBelt(p, Items.COAL_453)) + } + } + + companion object { + init { + TestUtils.preTestSetup() + BlastFurnaceListeners().defineListeners() + } + } +} \ No newline at end of file diff --git a/Server/src/test/kotlin/content/activity/blastfurnace/BlastFurnaceOreContainerTests.kt b/Server/src/test/kotlin/content/activity/blastfurnace/BlastFurnaceOreContainerTests.kt new file mode 100644 index 0000000..70db557 --- /dev/null +++ b/Server/src/test/kotlin/content/activity/blastfurnace/BlastFurnaceOreContainerTests.kt @@ -0,0 +1,169 @@ +package content.activity.blastfurnace + +import content.global.skill.smithing.smelting.Bar +import content.minigame.blastfurnace.BFOreContainer +import content.minigame.blastfurnace.BlastConsts +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test +import org.rs09.consts.Items + +class BlastFurnaceOreContainerTests { + @Test fun shouldBeAbleToAddCoal() { + val cont = BFOreContainer() + cont.addCoal(15) + Assertions.assertEquals(15, cont.coalAmount()) + } + + @Test fun addCoalShouldReturnExtraAmountIfAddingMoreThanPossible() { + val cont = BFOreContainer() + cont.addCoal(BlastConsts.COAL_LIMIT - 26) + Assertions.assertEquals(2, cont.addCoal(28)) + } + + @Test fun shouldBeAbleToAddOres() { + val cont = BFOreContainer() + cont.addOre (Items.IRON_ORE_440, 20) + Assertions.assertEquals(20, cont.getOreAmount(Items.IRON_ORE_440)) + } + + @Test fun addOreShouldReturnExtraAmountIfAddingMoreThanPossible() { + val cont = BFOreContainer() + cont.addOre(Items.IRON_ORE_440, BlastConsts.ORE_LIMIT - 2) + Assertions.assertEquals(3, cont.addOre(Items.IRON_ORE_440, 5)) + } + + @Test fun addOreShouldReturnExtraAmountWhenAddingMoreCopperOrTinThanPossible() { + val contTin = BFOreContainer() + Assertions.assertEquals(28, contTin.addOre(Items.TIN_ORE_438, 56)) + + val contCopper = BFOreContainer() + Assertions.assertEquals(28, contCopper.addOre(Items.COPPER_ORE_436, 56)) + } + + @Test fun convertToBarsShouldYieldExpectedResults() { + data class Data (val coalAmount: Int, val oreAmount: Array>, val expectedOreAmounts: Array>, val expectedCoalAmount: Int, val expectedBarResult: Array>) + val testData = arrayOf( + Data( //standard case - 20 iron with no coal creates 20 iron bars + 0, arrayOf(Pair(Items.IRON_ORE_440, 20)), + arrayOf(Pair(Items.IRON_ORE_440, 0)), 0, arrayOf(Pair(Bar.IRON, 20)) + ), + Data ( //edge case - 20 iron with 10 coal produces 10 steel and 10 iron + 10, arrayOf(Pair(Items.IRON_ORE_440, 20)), + arrayOf(Pair(Items.IRON_ORE_440, 0)), 0, arrayOf(Pair(Bar.STEEL, 10), Pair(Bar.IRON, 10)) + ), + Data ( //standard case - 20 coal with 10 mithril produces 10 mithril bars + 20, arrayOf(Pair(Items.MITHRIL_ORE_447, 10)), + arrayOf(Pair(Items.MITHRIL_ORE_447, 0)), 0, arrayOf(Pair(Bar.MITHRIL, 10)) + ), + Data ( //standard case - 30 coal with 10 adamantite produces 10 addy bars + 30, arrayOf(Pair(Items.ADAMANTITE_ORE_449, 10)), + arrayOf(Pair(Items.ADAMANTITE_ORE_449, 0)), 0, arrayOf(Pair(Bar.ADAMANT, 10)) + ), + Data ( //standard case - 40 coal with 10 runite produces 10 runite bars + 40, arrayOf(Pair(Items.RUNITE_ORE_451, 10)), + arrayOf(Pair(Items.RUNITE_ORE_451, 0)), 0, arrayOf(Pair(Bar.RUNITE, 10)) + ), + Data ( //semi-edge case - 28 gold with 150 coal produces 28 gold bars with 150 coal remaining (doesn't use any coal when not needed) + 150, arrayOf(Pair(Items.GOLD_ORE_444, 28)), + arrayOf(Pair(Items.GOLD_ORE_444, 0)), 150, arrayOf(Pair(Bar.GOLD, 28)) + ), + Data ( //edge case - 18 silver and 10 runite with 58 coal produces 18 silver bars and 10 runite bars with 18 coal remaining + 58, arrayOf(Pair(Items.SILVER_ORE_442, 18), Pair(Items.RUNITE_ORE_451, 10)), + arrayOf(Pair(Items.SILVER_ORE_442, 0), Pair(Items.RUNITE_ORE_451, 0)), 18, arrayOf(Pair(Bar.SILVER, 18), Pair(Bar.RUNITE, 10)) + ), + Data ( //edge case - only 20 coal but 10 runite (half of what's needed) produces 5 runite bars, with 5 runite ore and 0 coal remaining. + 20, arrayOf(Pair(Items.RUNITE_ORE_451, 10)), + arrayOf(Pair(Items.RUNITE_ORE_451, 5)), 0, arrayOf(Pair(Bar.RUNITE, 5)) + ), + Data (//technically an edge case - 28 copper and 28 tin makes 28 bronze with nothing leftover. + 0, arrayOf(Pair(Items.COPPER_ORE_436, 28), Pair(Items.TIN_ORE_438, 28)), + arrayOf(Pair(Items.COPPER_ORE_436, 0), Pair(Items.TIN_ORE_438, 0)), 0, arrayOf(Pair(Bar.BRONZE, 28)) + ), + Data (//edge case - 10 copper and no tin makes nothing with 10 copper leftover + 0, arrayOf(Pair(Items.COPPER_ORE_436, 10)), + arrayOf(Pair(Items.COPPER_ORE_436, 10)), 0, arrayOf(Pair(Bar.BRONZE, 0)) + ), + Data (//edge case - 14 copper and 5 tin make 5 bronze bars with 9 copper leftover + 0, arrayOf(Pair(Items.COPPER_ORE_436, 14), Pair(Items.TIN_ORE_438, 5)), + arrayOf(Pair(Items.COPPER_ORE_436, 9), Pair(Items.TIN_ORE_438, 0)), 0, arrayOf(Pair(Bar.BRONZE, 5)) + ) + ) + + var index = 0 + for ((initialCoal, initialOres, expectedOres, expectedCoal, expectedBars) in testData) { + val cont = BFOreContainer() + cont.addCoal(initialCoal) + for ((ore, amount) in initialOres) cont.addOre(ore, amount) + cont.convertToBars() + + for ((ore, amount) in expectedOres) + Assertions.assertEquals(amount, cont.getOreAmount(ore), "Problem testcase was $index - Missing $ore") + for ((bar, amount) in expectedBars) + Assertions.assertEquals(amount, cont.getBarAmount(bar), "Problem testcase was $index - Missing ${bar.name}") + Assertions.assertEquals(expectedCoal, cont.coalAmount(), "Problem testcase was $index") + index++ + } + } + + @Test fun convertToBarsShouldNotConsumeMaterialsForAlreadyFilledBarType() { + val cont = BFOreContainer() + cont.addOre(Items.IRON_ORE_440, 28) + cont.convertToBars() + Assertions.assertEquals(28, cont.getBarAmount(Bar.IRON)) + + cont.addOre(Items.IRON_ORE_440, 28) + cont.convertToBars() + Assertions.assertEquals(28, cont.getBarAmount(Bar.IRON)) + Assertions.assertEquals(28, cont.getOreAmount(Items.IRON_ORE_440)) + } + + @Test fun oreContainerShouldCleanlySerializeAndDeserializeFromJson() { + val cont = BFOreContainer() + cont.addOre(Items.IRON_ORE_440, 28) + cont.convertToBars() + + cont.addOre(Items.RUNITE_ORE_451, 15) + cont.addOre(Items.MITHRIL_ORE_447, 13) + cont.addCoal(150) + + val json = cont.toJson() + val deserialized = BFOreContainer.fromJson(json) + + Assertions.assertEquals(28, deserialized.getBarAmount(Bar.IRON)) + Assertions.assertEquals(15, cont.getOreAmount(Items.RUNITE_ORE_451)) + Assertions.assertEquals(13, cont.getOreAmount(Items.MITHRIL_ORE_447)) + Assertions.assertEquals(150, cont.coalAmount()) + } + + @Test fun shouldBeAbleToRemoveBars() { + val cont = BFOreContainer() + cont.addOre(Items.IRON_ORE_440, 28) + cont.convertToBars() + + val bars = cont.takeBars(Bar.IRON, 15) + Assertions.assertEquals(15, bars?.amount) + Assertions.assertEquals(13, cont.getBarAmount(Bar.IRON)) + } + + @Test fun shouldNotBeAbleToRemoveMoreBarsThanPossible() { + val cont = BFOreContainer() + cont.addOre(Items.IRON_ORE_440, 28) + cont.convertToBars() + + val bars = cont.takeBars(Bar.IRON, 50) + Assertions.assertEquals(28, bars?.amount) + Assertions.assertEquals(0, cont.getBarAmount(Bar.IRON)) + } + + @Test fun convertToBarsShouldReturnXPReward() { + val cont = BFOreContainer() + cont.addOre(Items.IRON_ORE_440, 28) + + Assertions.assertEquals(350.0, cont.convertToBars()) + } + + @Test fun removingBarsWithNoStockReturnsNull() { + val cont = BFOreContainer() + Assertions.assertEquals(null, cont.takeBars(Bar.RUNITE, 1)) + } +} \ No newline at end of file diff --git a/Server/src/test/kotlin/content/activity/blastfurnace/BlastStateTests.kt b/Server/src/test/kotlin/content/activity/blastfurnace/BlastStateTests.kt new file mode 100644 index 0000000..02b9594 --- /dev/null +++ b/Server/src/test/kotlin/content/activity/blastfurnace/BlastStateTests.kt @@ -0,0 +1,95 @@ +package content.activity.blastfurnace + +import content.minigame.blastfurnace.BlastState +import content.minigame.blastfurnace.BlastConsts +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test + +class BlastStateTests { + @Test + fun tickPassedWithCokeInStoveShouldIncreaseStoveTemp() { + val state = BlastState(); state.disableBreaking = true + state.addCoke(1) + Assertions.assertEquals(0, state.stoveTemp) + + state.tick(true, false) + Assertions.assertEquals(1, state.stoveTemp) + } + + @Test + fun stoveTempShouldNeverExceed100() { + val state = BlastState(); state.disableBreaking = true + state.addCoke(BlastConsts.COKE_LIMIT) + + for (i in 0 until 150) + state.tick(true, false) + Assertions.assertEquals(100, state.stoveTemp) + } + + @Test fun cokeShouldDisappearFromStove() { + val state = BlastState(); state.disableBreaking = true + state.addCoke(1) + for (i in 0 until 10) + state.tick(true, false) + Assertions.assertEquals(0, state.cokeInStove) + } + + @Test fun stoveTempShouldLowerWithoutCoke() { + val state = BlastState(); state.disableBreaking = true + state.addCoke(1) + for (i in 0 until 10) + state.tick(true, false) + Assertions.assertEquals(10, state.stoveTemp) + for (i in 0 until 10) + state.tick(true, false) + Assertions.assertEquals(0, state.stoveTemp) + } + + @Test + fun stoveTempShouldNeverGoBelow0() { + val state = BlastState(); state.disableBreaking = true + for (i in 0 until 100) + state.tick(true, false) + Assertions.assertEquals(0, state.stoveTemp) + } + + @Test fun furnaceTempShouldIncreaseProportionallyToStoveTempWhilePumping() { + val testData = arrayOf( + Pair(0, 0), + Pair(1, 1), + Pair(4, 2), + Pair(7, 3) + ) + for ((cokeToAdd, expectedTempRise) in testData) { + val state = BlastState(); state.disableBreaking = true + state.addCoke(cokeToAdd) + for (i in 0 until state.cokeInStove * 10) + state.tick(false, false) + + state.tick(true, false) + Assertions.assertEquals(expectedTempRise, state.furnaceTemp) + } + } + + @Test fun pumpingShouldNotTransferHeatIfPipesBroken() { + val state1 = BlastState(); state1.disableBreaking = true + state1.addCoke(BlastConsts.COKE_LIMIT) + state1.pumpPipeBroken = true + for (i in 0 until 20) state1.tick(true, false) + Assertions.assertEquals(0, state1.furnaceTemp) + + val state2 = BlastState(); state2.disableBreaking = true + state2.addCoke(BlastConsts.COKE_LIMIT) + state2.potPipeBroken = true + for (i in 0 until 20) state2.tick(true, false) + Assertions.assertEquals(0, state2.furnaceTemp) + } + + @Test fun pumpingShouldNotTransferHeatIfBeltBroken() { + val state = BlastState(); state.disableBreaking = true + state.addCoke(BlastConsts.COKE_LIMIT) + state.beltBroken = true + for (i in 0 until 20) state.tick(true, false) + Assertions.assertEquals(0, state.furnaceTemp) + } +} \ No newline at end of file diff --git a/Server/src/test/kotlin/content/familiar/special/BloodDrainTests.kt b/Server/src/test/kotlin/content/familiar/special/BloodDrainTests.kt new file mode 100644 index 0000000..9bdc458 --- /dev/null +++ b/Server/src/test/kotlin/content/familiar/special/BloodDrainTests.kt @@ -0,0 +1,117 @@ +package content.familiar.special + +import TestUtils +import content.global.skill.summoning.familiar.BloatedLeechNPC +import content.global.skill.summoning.familiar.FamiliarSpecial +import core.ServerConstants +import core.api.* +import core.game.node.entity.skill.Skills +import core.game.system.timer.TimerRegistry +import core.game.system.timer.impl.Disease +import core.game.system.timer.impl.Poison +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test +import org.rs09.consts.Items +import org.rs09.consts.NPCs + +class BloodDrainTests { + init { + TestUtils.preTestSetup() + } + @Test fun bloodDrainShouldNotRestorePrayer() { + TestUtils.getMockPlayer("bloodDrainPrayer").use { p -> + p.skills.setStaticLevel(Skills.PRAYER, 99) + p.skills.prayerPoints = 5.0 + addItem(p, Items.BLOOD_DRAIN_SCROLL_12444) + + val npc = BloatedLeechNPC(p, NPCs.BLOATED_LEECH_6843) + npc.location = ServerConstants.HOME_LOCATION + Assertions.assertEquals(true, npc.executeSpecialMove(FamiliarSpecial(p))) + Assertions.assertEquals(5.0, p.skills.prayerPoints) + } + } + + @Test fun bloodDrainShouldDamageOwner() { + TestUtils.getMockPlayer("bloodDrainHealth").use {p -> + addItem(p, Items.BLOOD_DRAIN_SCROLL_12444) + val npc = BloatedLeechNPC(p, NPCs.BLOATED_LEECH_6843) + npc.location = ServerConstants.HOME_LOCATION + + val npcBaseline = npc.skills.lifepoints + val ownerBaseline = p.skills.lifepoints + + Assertions.assertEquals(true, npc.executeSpecialMove(FamiliarSpecial(p))) + TestUtils.advanceTicks(1, false) + + Assertions.assertEquals(npcBaseline, npc.skills.lifepoints) + Assertions.assertEquals(true, p.skills.lifepoints < ownerBaseline) + } + } + + @Test fun bloodDrainShouldNotHeal() { + TestUtils.getMockPlayer("bloodDrainHealth2").use {p -> + addItem(p, Items.BLOOD_DRAIN_SCROLL_12444) + p.skills.lifepoints = 5 + + val npc = BloatedLeechNPC(p, NPCs.BLOATED_LEECH_6843) + npc.location = ServerConstants.HOME_LOCATION + + val ownerBaseline = p.skills.lifepoints + + Assertions.assertEquals(true, npc.executeSpecialMove(FamiliarSpecial(p))) + TestUtils.advanceTicks(1, false) + + Assertions.assertEquals(true, p.skills.lifepoints < ownerBaseline) + } + } + + @Test fun bloodDrainShouldOnlyRestorePercentOfStats() { + TestUtils.getMockPlayer("bloodDrainStats").use { p -> + addItem(p, Items.BLOOD_DRAIN_SCROLL_12444) + val npc = BloatedLeechNPC(p, NPCs.BLOATED_LEECH_6843) + npc.location = ServerConstants.HOME_LOCATION + + p.skills.setStaticLevel(Skills.STRENGTH, 99) + p.skills.setStaticLevel(Skills.FARMING, 99) + p.skills.setLevel(Skills.STRENGTH, 1) + p.skills.setLevel(Skills.FARMING, 1) + + Assertions.assertEquals(true,npc.executeSpecialMove(FamiliarSpecial(p))) + Assertions.assertEquals(21, p.skills.getLevel(Skills.STRENGTH)) + Assertions.assertEquals(21, p.skills.getLevel(Skills.FARMING)) + } + } + + @Test fun bloodDrainShouldNotBoostStats() { + TestUtils.getMockPlayer("bloodDrainStats2").use { p -> + addItem(p, Items.BLOOD_DRAIN_SCROLL_12444) + val npc = BloatedLeechNPC(p, NPCs.BLOATED_LEECH_6843) + npc.location = ServerConstants.HOME_LOCATION + + p.skills.setStaticLevel(Skills.STRENGTH, 99) + p.skills.setStaticLevel(Skills.FARMING, 99) + p.skills.setLevel(Skills.STRENGTH, 98) + p.skills.setLevel(Skills.FARMING, 98) + + Assertions.assertEquals(true,npc.executeSpecialMove(FamiliarSpecial(p))) + Assertions.assertEquals(99, p.skills.getLevel(Skills.STRENGTH)) + Assertions.assertEquals(99, p.skills.getLevel(Skills.FARMING)) + } + } + + @Test fun bloodDrainCuresPoisonAndDisease() { + TestUtils.getMockPlayer("bloodDrainAilments").use { p -> + addItem(p, Items.BLOOD_DRAIN_SCROLL_12444) + val npc = BloatedLeechNPC(p, NPCs.BLOATED_LEECH_6843) + npc.location = ServerConstants.HOME_LOCATION + + applyPoison(p, p, 40) + Assertions.assertNotNull(getOrStartTimer(p, 40)) + Assertions.assertEquals(true, hasTimerActive(p)) + Assertions.assertEquals(true, hasTimerActive(p)) + Assertions.assertEquals(true, npc.executeSpecialMove(FamiliarSpecial(p))) + Assertions.assertEquals(false, hasTimerActive(p)) + Assertions.assertEquals(false, hasTimerActive(p)) + } + } +} diff --git a/Server/src/test/kotlin/content/skill/agility/ShortcutTests.kt b/Server/src/test/kotlin/content/skill/agility/ShortcutTests.kt new file mode 100644 index 0000000..c8d95b7 --- /dev/null +++ b/Server/src/test/kotlin/content/skill/agility/ShortcutTests.kt @@ -0,0 +1,46 @@ +package content.skill.agility + +import content.global.skill.agility.shortcuts.StileShortcut +import core.game.world.map.Direction +import core.game.world.map.Location +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test + +class ShortcutTests { + @Test fun stileGetInteractionLocShouldReturnCorrectLoc() { + data class StileTestData (val playerLoc: Location, val expectedLoc: Location, val stileLoc: Location, val stileOrientation: StileShortcut.Orientation) + val testData = arrayOf( + //Horizontal + StileTestData(Location.create(3044, 3308, 0), Location.create(3045, 3305, 0), Location.create(3043, 3305, 0), StileShortcut.Orientation.Horizontal), + StileTestData(Location.create(3048, 3303, 0), Location.create(3045, 3305, 0), Location.create(3043, 3305, 0), StileShortcut.Orientation.Horizontal), + StileTestData(Location.create(3043, 3307, 0), Location.create(3042, 3305, 0), Location.create(3043, 3305, 0), StileShortcut.Orientation.Horizontal), + StileTestData(Location.create(3039, 3301, 0), Location.create(3042, 3305, 0), Location.create(3043, 3305, 0), StileShortcut.Orientation.Horizontal), + //Vertical + StileTestData(Location.create(3203, 3276, 0), Location.create(3197, 3275, 0), Location.create(3197, 3276, 0), StileShortcut.Orientation.Vertical), + StileTestData(Location.create(3195, 3274, 0), Location.create(3197, 3275, 0), Location.create(3197, 3276, 0), StileShortcut.Orientation.Vertical), + StileTestData(Location.create(3191, 3280, 0), Location.create(3197, 3278, 0), Location.create(3197, 3276, 0), StileShortcut.Orientation.Vertical), + StileTestData(Location.create(3206, 3281, 0), Location.create(3197, 3278, 0), Location.create(3197, 3276, 0), StileShortcut.Orientation.Vertical) + ) + + for ((pLoc, expLoc, sLoc, ori) in testData) { + Assertions.assertEquals(expLoc, StileShortcut.getInteractLocation(pLoc, sLoc, ori)) + } + } + + @Test fun stileGetOrientationShouldReturnCorrectOrientation() { + val testData = arrayOf( + Pair (Direction.NORTH, StileShortcut.Orientation.Vertical), + Pair (Direction.SOUTH, StileShortcut.Orientation.Vertical), + Pair (Direction.NORTH_WEST, StileShortcut.Orientation.Vertical), + Pair (Direction.NORTH_EAST, StileShortcut.Orientation.Vertical), + Pair (Direction.SOUTH_EAST, StileShortcut.Orientation.Vertical), + Pair (Direction.SOUTH_WEST, StileShortcut.Orientation.Vertical), + Pair (Direction.EAST, StileShortcut.Orientation.Horizontal), + Pair (Direction.WEST, StileShortcut.Orientation.Horizontal) + ) + + for ((dir, expOri) in testData) { + Assertions.assertEquals(expOri, StileShortcut.getOrientation(dir)) + } + } +} \ No newline at end of file diff --git a/Server/src/test/kotlin/content/skill/farming/PatchTests.kt b/Server/src/test/kotlin/content/skill/farming/PatchTests.kt new file mode 100644 index 0000000..2096b36 --- /dev/null +++ b/Server/src/test/kotlin/content/skill/farming/PatchTests.kt @@ -0,0 +1,81 @@ +package content.skill.farming + +import TestUtils +import content.global.skill.farming.FarmingPatch +import content.global.skill.farming.PatchRaker +import content.global.skill.farming.PatchType +import content.global.skill.farming.Plantable +import content.global.skill.farming.timers.CropGrowth +import core.cache.def.impl.SceneryDefinition +import core.game.node.entity.skill.Skills +import core.game.system.timer.TimerRegistry +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test + +class PatchTests { + init { TestUtils.preTestSetup() } + @Test fun patchGettingDiseasedOrDyingShouldNotGoIntoInvalidState() { + //Dead/Watered (state | 0x40) and Diseased (state | 0x80) are both invalid stages for limpwurt when fully grown (stage 4/state 32), so we use this as our testcase + //specifically, limpwurt has an issue when the patch is ONLY watered (state | 0x40) OR diseased (state | 0x80), having both (state | 0x40 | 0x80) is fine. + TestUtils.getMockPlayer("invalidPatchState").use {p -> + p.skills.setStaticLevel(Skills.FARMING, 99) + p.skills.setLevel(Skills.FARMING, 99) + + val patch = FarmingPatch.S_FALADOR_FLOWER_C.getPatchFor(p) + patch.plant(Plantable.LIMPWURT_SEED) + + for (i in 0 until 4) { //grow to full growth while making sure we don't die/get diseased + patch.currentGrowthStage = 4 + patch.update() + } + + Assertions.assertEquals(32, patch.getCurrentState()) + + patch.isWatered = true + patch.update() + Assertions.assertEquals(false, patch.isDiseased) + Assertions.assertEquals(false, patch.isDead) + Assertions.assertEquals(false, patch.isWatered) + Assertions.assertEquals(32, patch.getCurrentState()) + + patch.isDiseased = true + patch.updateBit() + Assertions.assertEquals(false, patch.isDiseased) + Assertions.assertEquals(false, patch.isDead) + Assertions.assertEquals(false, patch.isWatered) + Assertions.assertEquals(32, patch.getCurrentState()) + } + } + + @Test fun rakingPatchAtInvalidStagesShouldDoNothing() { + TestUtils.getMockPlayer("Patchraker").use {p -> + val patch = FarmingPatch.S_FALADOR_FLOWER_C.getPatchFor(p) + patch.update() + + Assertions.assertEquals(0, patch.getCurrentState()) //assert that it's in the max weedy state + + PatchRaker.rake(p, patch.patch) + TestUtils.advanceTicks(25, false) + Assertions.assertEquals(3, patch.getCurrentState()) + + PatchRaker.rake(p, patch.patch) + TestUtils.advanceTicks(10, false) + Assertions.assertEquals(3, patch.getCurrentState()) + + patch.plant(Plantable.POTATO_SEED) + val plantedBaseline = patch.getCurrentState() + PatchRaker.rake(p, patch.patch) + TestUtils.advanceTicks(10, false) + Assertions.assertEquals(plantedBaseline, patch.getCurrentState()) + + patch.currentGrowthStage = Plantable.POTATO_SEED.stages + patch.update() + Assertions.assertEquals(true, patch.isGrown()) + + val stateBaseline = patch.getCurrentState() + PatchRaker.rake(p, patch.patch) + TestUtils.advanceTicks(10, false) + Assertions.assertEquals(stateBaseline, patch.getCurrentState()) + } + } +} \ No newline at end of file diff --git a/Server/src/test/kotlin/core/PathfinderTests.kt b/Server/src/test/kotlin/core/PathfinderTests.kt new file mode 100644 index 0000000..f38eecb --- /dev/null +++ b/Server/src/test/kotlin/core/PathfinderTests.kt @@ -0,0 +1,260 @@ +package core + +import TestUtils +import content.global.skill.gather.GatheringSkillOptionListeners +import content.global.skill.gather.woodcutting.WoodcuttingListener +import core.api.log +import core.cache.def.impl.NPCDefinition +import core.game.interaction.* +import core.game.node.scenery.Scenery +import core.game.world.map.Location +import core.game.world.map.RegionManager +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test +import core.game.node.Node +import core.game.node.entity.impl.PulseType +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.world.GameWorld +import core.game.world.map.Region +import core.net.packet.PacketProcessor +import core.plugin.ClassScanner +import core.plugin.Plugin +import core.tools.Log +import org.rs09.consts.NPCs + +class PathfinderTests { + companion object {init {TestUtils.preTestSetup(); GatheringSkillOptionListeners().defineListeners(); WoodcuttingListener().defineListeners() }; val NPC_TEST_LOC = ServerConstants.HOME_LOCATION!!.transform(2, 10, 0)} + + @Test fun getOccupiedTilesShouldReturnCorrectSetOfTilesThatAnObjectOccupiesAtAllRotations() { + //clay fireplace - 13609 - sizex: 1, sizey: 2 + val scenery = Scenery(13609, Location.create(50, 50, 0)) + + scenery.rotation = 0 + val occupiedAt0 = scenery.occupiedTiles.toTypedArray() + Assertions.assertArrayEquals(arrayOf(Location.create(50, 50), Location.create(50,51)), occupiedAt0) + + scenery.rotation = 1 + val occupiedAt1 = scenery.occupiedTiles.toTypedArray() + Assertions.assertArrayEquals(arrayOf(Location.create(50,50), Location.create(51,50)), occupiedAt1) + + scenery.rotation = 2 + val occupiedAt2 = scenery.occupiedTiles.toTypedArray() + Assertions.assertArrayEquals(arrayOf(Location.create(50,50), Location.create(50,49)), occupiedAt2) + + scenery.rotation = 3 + val occupiedAt3 = scenery.occupiedTiles.toTypedArray() + Assertions.assertArrayEquals(arrayOf(Location.create(50,50), Location.create(49,50)), occupiedAt3) + } + + @Test fun movementPulseShouldStopEarlyIfNextToATileOccupiedByTargetObject() { + val start = Location.create(2731, 3481) + val dest = RegionManager.getObject(0, 2720, 3475, 1307) + val p = TestUtils.getMockPlayer("treefindtest") + p.location = start + p.init() + + Assertions.assertEquals(true, InteractionListeners.run(1307, IntType.SCENERY, "chop-down", p, dest!!)) + TestUtils.advanceTicks(20, false) + Assertions.assertEquals(Location.create(2722, 3475, 0), p.location) + } + + @Test fun movementInteractionShouldTrigger() { + val npc = NPC.create(0, NPC_TEST_LOC) + npc.init() + + var intListenerRan = false + InteractionListeners.add(0, IntType.NPC.ordinal, arrayOf("testoptlistener"), method = {player: Player, node: Node -> + intListenerRan = true + return@add true + }) + + var pluginRan = false + val option = Option("testoption", 4) + val option2 = Option("testoptlistener", 0) + val testHandler = object : OptionHandler() { + override fun newInstance(arg: Any?): Plugin { + NPCDefinition.forId(0).handlers["option:testoption"] = this + return this + } + override fun handle(player: Player?, node: Node?, option: String?): Boolean { + pluginRan = true + return true + } + } + testHandler.newInstance(null) + npc.interaction.set(option) + npc.interaction.set(option2) + option.handler = testHandler + + TestUtils.getMockPlayer("interactionTest").use {p -> + p.location = ServerConstants.HOME_LOCATION + TestUtils.simulateInteraction(p, npc, 0) + TestUtils.advanceTicks(10, false) + Assertions.assertEquals(true, intListenerRan) + p.location = ServerConstants.HOME_LOCATION + TestUtils.simulateInteraction(p, npc, 4) + TestUtils.advanceTicks(10, false) + Assertions.assertEquals(true, pluginRan) + } + } + + @Test fun entityMovingToStationaryNPCShouldNotIdleIndefinitely() { + TestUtils.getMockPlayer("idlenpcdest").use {p -> + val startLoc = ServerConstants.HOME_LOCATION + p.location = startLoc + val npc = NPC.create(0, NPC_TEST_LOC) + npc.isNeverWalks = true + npc.init() + GameWorld.Pulser.submit(object : MovementPulse(p, npc) { + override fun pulse(): Boolean { + return true + } + }) + TestUtils.advanceTicks(10, false) + Assertions.assertNotEquals(startLoc, p.location) + } + } + + @Test fun entityTargetMovementPulseShouldNotStopOnSameTileAsEntity() { + TestUtils.getMockPlayer("entitystoptest").use {p -> + p.location = ServerConstants.HOME_LOCATION + val npc = NPC.create(0, NPC_TEST_LOC) + npc.isNeverWalks = true + npc.init() + GameWorld.Pulser.submit(object : MovementPulse(p, npc) { + override fun pulse(): Boolean { + return true + } + }) + TestUtils.advanceTicks(10, false) + Assertions.assertNotEquals(p.location, npc.location) + Assertions.assertEquals(1.0, p.location.getDistance(npc.location)) + } + } + + @Test fun entityTargetMovementPulseWithExplicitParamsShouldNotStopOnSameTile() { + TestUtils.getMockPlayer("entitystoptest2").use { p -> + p.location = ServerConstants.HOME_LOCATION + val npc = NPC.create(0, NPC_TEST_LOC) + npc.isNeverWalks = true + npc.init() + GameWorld.Pulser.submit(object : MovementPulse(p, npc, DestinationFlag.ENTITY) { + override fun pulse(): Boolean { + return true + } + }) + TestUtils.advanceTicks(10, false) + Assertions.assertNotEquals(p.location, npc.location) + Assertions.assertEquals(1.0, p.location.getDistance(npc.location)) + } + } + + @Test fun doubleMovementPulseToEntityShouldNotStopOnSameTile() { + TestUtils.getMockPlayer("entitystoptest3").use { p -> + p.location = ServerConstants.HOME_LOCATION + val npc = NPC.create(0, NPC_TEST_LOC) + npc.isNeverWalks = true + npc.init() + p.pulseManager.run(object : MovementPulse(p, npc) { + override fun pulse(): Boolean { + return true + } + }) + p.pulseManager.run(object : MovementPulse(p, npc) { + override fun pulse(): Boolean { + return true + } + }, PulseType.STANDARD) + TestUtils.advanceTicks(10, false) + Assertions.assertNotEquals(ServerConstants.HOME_LOCATION, p.location) + Assertions.assertNotEquals(p.location, npc.location) + Assertions.assertEquals(1.0, p.location.getDistance(npc.location)) + } + } + + @Test fun simulatedInteractionPacketWithMovementFromPluginShouldNotEndOnSameTile() { + val testHandler = object : OptionHandler() { + override fun newInstance(arg: Any?): Plugin { + NPCDefinition.forId(0).handlers["option:testoption"] = this + return this + } + override fun handle(player: Player?, node: Node?, option: String?): Boolean { + log(this::class.java, Log.ERR, "Interaction triggered") + return true + } + } + testHandler.newInstance(null) + val npc = NPC.create(0, NPC_TEST_LOC) + val option = Option("testoption", 4) + npc.interaction.set(option) + option.handler = testHandler + + TestUtils.getMockPlayer("entitystoptest4").use { p -> + p.location = ServerConstants.HOME_LOCATION + npc.isNeverWalks = true + npc.init() + TestUtils.simulateInteraction(p, npc, 4) + TestUtils.advanceTicks(20, false) + Assertions.assertNotEquals(ServerConstants.HOME_LOCATION, p.location) + Assertions.assertNotEquals(p.location, npc.location) + Assertions.assertEquals(1.0, p.location.getDistance(npc.location)) + } + } + + @Test fun simulatedInteractionPacketWithMovementFromListenerShouldNotEndOnSameTile() { + val npc = NPC.create(0, NPC_TEST_LOC) + npc.isNeverWalks = true + npc.init() + + InteractionListeners.add(0, IntType.NPC.ordinal, arrayOf("testoptlistener2"), method = {player: Player, node: Node -> + return@add true + }) + val opt = Option("testoptlistener2", 1) + npc.interaction.set(opt) + + TestUtils.getMockPlayer("entitystoptest5").use { p -> + p.location = ServerConstants.HOME_LOCATION + TestUtils.simulateInteraction(p, npc, 1) + TestUtils.advanceTicks(20, false) + Assertions.assertNotEquals(ServerConstants.HOME_LOCATION, p.location) + Assertions.assertNotEquals(p.location, npc.location) + Assertions.assertEquals(1.0, p.location.getDistance(npc.location)) + } + } + + @Test fun npcShouldReliablyReturnToSpawnLocationIfTooFar() { + //spawn a player into the area just to make sure it ticks... + TestUtils.getMockPlayer("areatest").use { p -> + val npc = NPC(1, Location.create(3240, 3226, 0)) + npc.isWalks = true + npc.isNeverWalks = false + npc.walkRadius = 5 + npc.init() + npc.properties.spawnLocation = ServerConstants.HOME_LOCATION + TestUtils.advanceTicks(5, false) + Assertions.assertEquals(true, npc.getAttribute("return-to-spawn", false)) + TestUtils.advanceTicks(50, false) + Assertions.assertEquals(true, npc.location.getDistance(ServerConstants.HOME_LOCATION) <= 9) + } + } + + @Test fun npcShouldReliablyReturnToSpawnEvenIfRegionUnloaded() { + //spawn a player into the area just to make sure it ticks... + TestUtils.getMockPlayer("areaunloadtest").use { p -> + val npc = NPC(1, Location.create(3240, 3226, 0)) + npc.isWalks = true + npc.isNeverWalks = false + npc.walkRadius = 5 + npc.init() + npc.properties.spawnLocation = ServerConstants.HOME_LOCATION + TestUtils.advanceTicks(3, false) + Assertions.assertEquals(true, npc.getAttribute("return-to-spawn", false)) + p.clear() + RegionManager.forId(npc.location.regionId).flagInactive(true) + TestUtils.advanceTicks(50, false) + Assertions.assertEquals(false, npc.getAttribute("return-to-spawn", false)) + Assertions.assertEquals(true, npc.location.getDistance(ServerConstants.HOME_LOCATION) <= 5) + } + } +} \ No newline at end of file diff --git a/Server/src/test/kotlin/core/TimerTests.kt b/Server/src/test/kotlin/core/TimerTests.kt new file mode 100644 index 0000000..3484391 --- /dev/null +++ b/Server/src/test/kotlin/core/TimerTests.kt @@ -0,0 +1,99 @@ +package core + +import TestUtils +import core.api.* +import core.game.node.entity.Entity +import core.game.node.entity.skill.Skills +import core.game.system.timer.RSTimer +import core.game.system.timer.TimerFlag +import core.game.system.timer.impl.SkillRestore +import core.tools.Log +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test + +class TimerTests { + init { TestUtils.preTestSetup() } + + @Test fun timerWithNoFlagsShouldNotBeClearedOnDeath() { + TestUtils.getMockPlayer("noflagnoclear").use { p -> + var incrementer = 0 + val timer = object : RSTimer(1) { + override fun run(entity: Entity): Boolean { + incrementer++ + return true + } + } + + registerTimer(p, timer) + impact(p, p.skills.lifepoints) + TestUtils.advanceTicks(TestUtils.PLAYER_DEATH_TICKS, false) + closeInterface(p) //close the interface that opens after death - as it would pause the timer + + TestUtils.advanceTicks(18, false) + Assertions.assertEquals(20, incrementer) + } + } + + @Test fun timerWithClearOnDeathFlagShouldClearOnDeath() { + TestUtils.getMockPlayer("clearflagtimer").use { p -> + var incrementer = 0 + val timer = object : RSTimer(1, flags = arrayOf(TimerFlag.ClearOnDeath)) { + override fun run(entity: Entity): Boolean { + incrementer++ + return true + } + } + + registerTimer(p, timer) + impact(p, p.skills.lifepoints) + TestUtils.advanceTicks(TestUtils.PLAYER_DEATH_TICKS, false) + closeInterface(p) //close the interface that opens after death - as it would pause the timer + + TestUtils.advanceTicks(18, false) + Assertions.assertEquals(2, incrementer) + } + } + + @Test fun skillRestoreTimerShouldSlowlyRaiseLoweredStats() { + TestUtils.getMockPlayer("statrestore-slowrestore").use { p -> + val timer = SkillRestore() + registerTimer(p, timer) + p.skills.staticLevels[Skills.FARMING] = 20 + setTempLevel(p, Skills.FARMING, 10) + + TestUtils.advanceTicks(timer.restoreTicks[Skills.FARMING] + 3, false) + Assertions.assertEquals(11, getDynLevel(p, Skills.FARMING)) + } + } + @Test fun skillRestoreTimerShouldSlowlyLowerBoostedStats() { + TestUtils.getMockPlayer("statrestore-slowdrain").use { p -> + val timer = SkillRestore() + p.timers.registerTimer(timer) + setTempLevel(p, Skills.FARMING, 6) + + TestUtils.advanceTicks(timer.restoreTicks[Skills.FARMING] + 3, false) + Assertions.assertEquals(5, getDynLevel(p, Skills.FARMING)) + } + } + + @Test fun skillRestoreTimerShouldRaiseLoweredHp() { + TestUtils.getMockPlayer("statrestore-raiseloweredhp").use { p -> + val timer = SkillRestore() + registerTimer(p, timer) + p.skills.lifepoints /= 2 + TestUtils.advanceTicks(600, false) + Assertions.assertEquals(10, p.skills.lifepoints) + } + } + + @Test fun skillRestoreTimerShouldNeverLowerBoostedHp() { + TestUtils.getMockPlayer("statrestore-neverlowerhp").use { p -> + val timer = SkillRestore() + registerTimer(p, timer) + p.skills.lifepoints = 50 + + TestUtils.advanceTicks(500, false) + Assertions.assertEquals(50, p.skills.lifepoints) + } + } +} \ No newline at end of file diff --git a/Server/src/test/kotlin/core/auth/DevelopmentAuthenticatorTests.kt b/Server/src/test/kotlin/core/auth/DevelopmentAuthenticatorTests.kt new file mode 100644 index 0000000..e14efb1 --- /dev/null +++ b/Server/src/test/kotlin/core/auth/DevelopmentAuthenticatorTests.kt @@ -0,0 +1,52 @@ +package core.auth + +import core.storage.InMemoryStorageProvider +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test + +class DevelopmentAuthenticatorTests { + private val authProvider = DevelopmentAuthenticator() + private val storageProvider = InMemoryStorageProvider() + + init { + authProvider.configureFor(storageProvider) + } + + @Test fun shouldAllowCheckingIfAccountExists() { + val info = UserAccountInfo.createDefault() + info.username = "Billy" + Assertions.assertEquals(true, authProvider.canCreateAccountWith(info)) + authProvider.createAccountWith(info) + Assertions.assertEquals(false, authProvider.canCreateAccountWith(info)) + } + + @Test fun loginWithValidAccountInfoReturnsSuccess() { + val info = UserAccountInfo.createDefault() + info.username = "Billy" + authProvider.createAccountWith(info) + Assertions.assertEquals(AuthResponse.Success, authProvider.checkLogin("Billy", "").first) + } + + //Development authenticator should work regardless if account exists or not. + @Test fun loginWithInvalidAccountInfoReturnsSuccess() { + val info = UserAccountInfo.createDefault() + info.username = "Billy" + authProvider.createAccountWith(info) + Assertions.assertEquals(AuthResponse.Success, authProvider.checkLogin("Bilbo", "ebbeb").first) + } + + @Test fun loginUsernameIsNotCaseSensitive() { + val info = UserAccountInfo.createDefault() + info.username = "Billy" + authProvider.createAccountWith(info) + Assertions.assertEquals(AuthResponse.Success, authProvider.checkLogin("Billy", "").first) + Assertions.assertEquals(AuthResponse.Success, authProvider.checkLogin("billy", "").first) + } + + //Development authenticator should basically bypass needing/creating an account entirely. useful for SP too. + @Test fun loginToUnregisteredAccountCreatesIt() { + authProvider.checkLogin("masterbaggins", "whatever") + val info = storageProvider.getAccountInfo("masterbaggins") + Assertions.assertEquals(2, info.rights) + } +} \ No newline at end of file diff --git a/Server/src/test/kotlin/core/auth/ProductionAuthenticatorTests.kt b/Server/src/test/kotlin/core/auth/ProductionAuthenticatorTests.kt new file mode 100644 index 0000000..1355778 --- /dev/null +++ b/Server/src/test/kotlin/core/auth/ProductionAuthenticatorTests.kt @@ -0,0 +1,62 @@ +package core.auth + +import org.junit.Assert +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.BeforeAll +import org.junit.jupiter.api.Test +import core.auth.AuthResponse +import core.auth.ProductionAuthenticator +import core.auth.UserAccountInfo +import core.storage.InMemoryStorageProvider + +class ProductionAuthenticatorTests { + companion object { + private val authProvider = ProductionAuthenticator() + private val storageProvider = InMemoryStorageProvider() + + init { + authProvider.configureFor(storageProvider) + } + + @BeforeAll @JvmStatic fun createTestAccount() { + val details = UserAccountInfo.createDefault() + details.username = "test" + details.password = "testing" + if(!storageProvider.checkUsernameTaken("test")) { + authProvider.createAccountWith(details) + } + } + } + + @Test fun shouldRejectLoginWithInvalidDetails() { + Assertions.assertEquals(AuthResponse.InvalidCredentials, authProvider.checkLogin("test", "test2").first) + } + + @Test fun loginUsernameIsNotCaseSensitive() { + Assertions.assertEquals(AuthResponse.Success, authProvider.checkLogin("Test", "testing").first) + Assertions.assertEquals(AuthResponse.Success, authProvider.checkLogin("test", "testing").first) + } + + @Test fun shouldHashPasswords() { + Assertions.assertNotEquals("testing", storageProvider.getAccountInfo("test").password) + } + + @Test fun shouldNotAllowBannedLogin() { + val info = storageProvider.getAccountInfo("test") + info.banEndTime = System.currentTimeMillis() + 1000L + storageProvider.update(info) + Assertions.assertEquals(AuthResponse.AccountDisabled, authProvider.checkLogin("test", "testing").first) + info.banEndTime = 0L + storageProvider.update(info) + Assertions.assertEquals(AuthResponse.Success, authProvider.checkLogin("test", "testing").first) + } + + @Test fun shouldNotAllowAlreadyOnlineLogin() { + val info = storageProvider.getAccountInfo("test") + info.online = true + storageProvider.update(info) + Assertions.assertEquals(AuthResponse.AlreadyOnline, authProvider.checkLogin("test", "testing").first) + info.online = false + storageProvider.update(info) + } +} \ No newline at end of file diff --git a/Server/src/test/kotlin/core/cache/ItemDefTests.kt b/Server/src/test/kotlin/core/cache/ItemDefTests.kt new file mode 100644 index 0000000..dc9a5fb --- /dev/null +++ b/Server/src/test/kotlin/core/cache/ItemDefTests.kt @@ -0,0 +1,27 @@ +package core.cache + +import TestUtils +import core.api.itemDefinition +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test +import java.io.File + +class ItemDefTests { + val knownGood = HashMap() + init { + TestUtils.preTestSetup() + } + + @Test fun itemDefsShouldHaveExpectedValues() { + File(TestUtils.loadFile("530_cache_item_values_from_client.csv")).useLines { lines -> + lines.forEach { + val toks = it.split(",") + knownGood[toks[0].toIntOrNull() ?: return@forEach] = toks[toks.size - 1].toInt() + } + } + for ((id, expectedValue) in knownGood) { + val def = itemDefinition(id) + Assertions.assertEquals(expectedValue, def.value, "Value of ${def.name} (${def.isUnnoted}) does not match known good values!") + } + } +} \ No newline at end of file diff --git a/Server/src/test/kotlin/core/game/node/entity/skill/SkillsTests.kt b/Server/src/test/kotlin/core/game/node/entity/skill/SkillsTests.kt new file mode 100644 index 0000000..22c9dcf --- /dev/null +++ b/Server/src/test/kotlin/core/game/node/entity/skill/SkillsTests.kt @@ -0,0 +1,43 @@ +package core.game.node.entity.skill + +import TestUtils.getMockPlayer +import core.game.node.entity.player.info.login.PlayerSaveParser +import core.game.node.entity.player.info.login.PlayerSaver +import org.json.simple.JSONArray +import org.json.simple.JSONObject +import org.json.simple.parser.JSONParser +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test + +class SkillsTests { + init { + TestUtils.preTestSetup() + } + + @Test + fun saveDynamicLevelsTest() { + val player = getMockPlayer("") + + // Test migration of old save versions with incorrectly-saved dynamic levels + val jsonparser = JSONParser() + val json = jsonparser.parse("[{\"static\":\"55\",\"dynamic\":\"55\",\"id\":\"0\",\"experience\":\"177895.0\"},{\"static\":\"21\",\"dynamic\":\"21\",\"id\":\"1\",\"experience\":\"5120.0\"},{\"static\":\"23\",\"dynamic\":\"23\",\"id\":\"2\",\"experience\":\"6682.799999999999\"},{\"static\":\"26\",\"dynamic\":\"20\",\"id\":\"3\",\"experience\":\"9001.000000000002\"},{\"static\":\"1\",\"dynamic\":\"1\",\"id\":\"4\",\"experience\":\"0.0\"},{\"static\":\"23\",\"dynamic\":\"20\",\"id\":\"5\",\"experience\":\"6772.5\"},{\"static\":\"37\",\"dynamic\":\"37\",\"id\":\"6\",\"experience\":\"28180.0\"},{\"static\":\"54\",\"dynamic\":\"54\",\"id\":\"7\",\"experience\":\"164425.0\"},{\"static\":\"40\",\"dynamic\":\"40\",\"id\":\"8\",\"experience\":\"40975.5\"},{\"static\":\"24\",\"dynamic\":\"24\",\"id\":\"9\",\"experience\":\"7260.0\"},{\"static\":\"40\",\"dynamic\":\"40\",\"id\":\"10\",\"experience\":\"40200.0\"},{\"static\":\"35\",\"dynamic\":\"35\",\"id\":\"11\",\"experience\":\"23750.0\"},{\"static\":\"60\",\"dynamic\":\"60\",\"id\":\"12\",\"experience\":\"292409.0\"},{\"static\":\"11\",\"dynamic\":\"11\",\"id\":\"13\",\"experience\":\"1371.5\"},{\"static\":\"75\",\"dynamic\":\"75\",\"id\":\"14\",\"experience\":\"1254300.0\"},{\"static\":\"1\",\"dynamic\":\"1\",\"id\":\"15\",\"experience\":\"0.0\"},{\"static\":\"42\",\"dynamic\":\"42\",\"id\":\"16\",\"experience\":\"47742.5\"},{\"static\":\"10\",\"dynamic\":\"10\",\"id\":\"17\",\"experience\":\"1160.0\"},{\"static\":\"1\",\"dynamic\":\"1\",\"id\":\"18\",\"experience\":\"0.0\"},{\"static\":\"1\",\"dynamic\":\"1\",\"id\":\"19\",\"experience\":\"0.0\"},{\"static\":\"5\",\"dynamic\":\"5\",\"id\":\"20\",\"experience\":\"500.0\"},{\"static\":\"1\",\"dynamic\":\"1\",\"id\":\"21\",\"experience\":\"0.0\"},{\"static\":\"1\",\"dynamic\":\"1\",\"id\":\"22\",\"experience\":\"0.0\"},{\"static\":\"11\",\"dynamic\":\"11\",\"id\":\"23\",\"experience\":\"1429.0\"}]") as JSONArray + player.version = 1 + player.skills.parse(json) + Assertions.assertTrue(player.skills.prayerPoints == 20.0) + Assertions.assertTrue(player.skills.lifepoints == 20) + Assertions.assertTrue(player.skills.dynamicLevels[Skills.PRAYER] == 23) + Assertions.assertTrue(player.skills.dynamicLevels[Skills.HITPOINTS] == 26) + + // Test that serializing and parsing them again correctly updates the dynamic levels and keeps the hp/prayer points + player.version = 2 + val root = JSONObject() + PlayerSaver(player).saveSkills(root) + val saveparser = PlayerSaveParser(player) + saveparser.saveFile = root + saveparser.parseSkills() + Assertions.assertTrue(player.skills.prayerPoints == 20.0) + Assertions.assertTrue(player.skills.lifepoints == 20) + Assertions.assertTrue(player.skills.dynamicLevels[Skills.PRAYER] == 23) + Assertions.assertTrue(player.skills.dynamicLevels[Skills.HITPOINTS] == 26) + } +} diff --git a/Server/src/test/kotlin/core/game/world/map/zone/ZoneMonitorTests.kt b/Server/src/test/kotlin/core/game/world/map/zone/ZoneMonitorTests.kt new file mode 100644 index 0000000..a1e7335 --- /dev/null +++ b/Server/src/test/kotlin/core/game/world/map/zone/ZoneMonitorTests.kt @@ -0,0 +1,94 @@ +package core.game.world.map.zone + +import MockPlayer +import core.api.hasTimerActive +import core.api.registerTimer +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.game.system.timer.impl.Teleblock +import core.game.world.map.Location +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Nested +import org.junit.jupiter.api.Test + +class ZoneMonitorTests { + + val GLORIES = intArrayOf(1710, 1708, 1706, 1704) + + init { + TestUtils.preTestSetup() + } + + /** + * Evalutes success of glory teleport using all glory charged items + */ + fun teleportWithGlory(expected : Boolean, p : Player) { + for (id in GLORIES) { + val glory = Item(id, 1) + Assertions.assertEquals(expected, p.zoneMonitor.teleport(1, glory)) + } + } + + @Nested + inner class GloryTeleportSuccess { + + @Test + fun successOnLevel21Wilderness() { + TestUtils.getMockPlayer("").use {p -> + // level 21 wilderness + p.skullManager.level = 21; + p.location = (Location.create(3067, 3683, 0)) + Assertions.assertTrue(p.locks.isTeleportLocked) + teleportWithGlory(true, p) + } + } + + @Test + fun successOnLevel30Wilderness() { + TestUtils.getMockPlayer("").use {p -> + // level 30 wilderness + p.location = (Location.create(3069, 3755, 0)) + p.skullManager.level = 30; + Assertions.assertTrue(p.locks.isTeleportLocked) + teleportWithGlory(true, p) + } + } + + @Test + fun successOnNoRestrictions() { + TestUtils.getMockPlayer("").use {p -> + // lumbridge + p.location = (Location.create(3222, 3218, 0)) + Assertions.assertFalse(p.locks.isTeleportLocked) + Assertions.assertFalse(hasTimerActive(p, "teleblock")) + Assertions.assertFalse(p.zoneMonitor.isRestricted(ZoneRestriction.TELEPORT)) + teleportWithGlory(true, p) + } + } + + } + + @Nested + inner class GloryTeleportFailure { + + @Test + fun failOnTeleBlock() { + TestUtils.getMockPlayer("").use { p -> + registerTimer(p, Teleblock()) + Assertions.assertTrue(hasTimerActive(p, "teleblock")) + teleportWithGlory(false, p) + } + } + + @Test + fun failOnLock() { + TestUtils.getMockPlayer("").use { p -> + p.locks.lockTeleport(100000) + Assertions.assertTrue(p.locks.isTeleportLocked) + teleportWithGlory(false, p) + } + } + + } + +} diff --git a/Server/src/test/kotlin/core/game/worldevents/holiday/easter/EasterEventTests.kt b/Server/src/test/kotlin/core/game/worldevents/holiday/easter/EasterEventTests.kt new file mode 100644 index 0000000..74f5af5 --- /dev/null +++ b/Server/src/test/kotlin/core/game/worldevents/holiday/easter/EasterEventTests.kt @@ -0,0 +1,100 @@ +package core.game.worldevents.holiday.easter + +import core.game.world.map.Location +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test +import java.util.* + +class EasterEventTests { + @Test fun eventShouldOnlyTriggerInApril() + { + val inst = EasterEvent() + val calInst = Calendar.getInstance() + + calInst.set(Calendar.YEAR, 2024) + calInst.set(Calendar.MONTH, Calendar.APRIL) + calInst.set(Calendar.DAY_OF_MONTH, 1) + Assertions.assertEquals(true, inst.checkActive(calInst)) + + calInst.set(Calendar.MONTH, Calendar.MARCH) + Assertions.assertEquals(false, inst.checkActive(calInst)) + + calInst.set(Calendar.DAY_OF_MONTH, 31) + Assertions.assertEquals(false, inst.checkActive(calInst)) + + calInst.set(Calendar.MONTH, Calendar.MAY) + calInst.set(Calendar.DAY_OF_MONTH, 1) + Assertions.assertEquals(false, inst.checkActive(calInst)) + } + + @Test fun getLocationsForNameShouldReturnExpectedList() + { + val expectations = arrayOf( + Pair(EasterEvent.LOC_LUM, EasterEvent.LUMBRIDGE_SPOTS), + Pair(EasterEvent.LOC_DRAYNOR, EasterEvent.DRAYNOR_SPOTS), + Pair(EasterEvent.LOC_TGS, EasterEvent.TREE_GNOME_STRONGHOLD_SPOTS), + Pair(EasterEvent.LOC_EDGE, EasterEvent.EDGEVILLE_SPOTS), + Pair(EasterEvent.LOC_FALADOR, EasterEvent.FALADOR_SPOTS), + Pair("Random Invalid Dummy Data", EasterEvent.LUMBRIDGE_SPOTS) + ) + + for ((locName, locList) in expectations) + { + Assertions.assertEquals(locList, EasterEvent.locationsForName(locName)) + } + } + + @Test fun getRandomLocationDataShouldReturnARandomLocationNameAndListOfUniqueRandomLocations() + { + val inst = EasterEvent() + + val sampleA = inst.getRandomLocations() + var sampleB = inst.getRandomLocations() + + //Assert that they are equal when they contain the same information (just in case JVM is goofy) + Assertions.assertEquals(sampleA, Pair(sampleA.first, sampleA.second.toTypedArray().toList())) + + //build in some safety against extreme unlikelihood + var similarityTolerance = 3 + //Check 100 times just to be very sure that we're not getting the same data + for (i in 0 until 100) { + if (sampleA == sampleB) similarityTolerance-- + sampleB = inst.getRandomLocations() + } + Assertions.assertEquals(true, similarityTolerance > 0) + } + + @Test fun eachLocationGroupShouldContainNoDuplicateLocations() { + for (locSet in arrayOf( + EasterEvent.FALADOR_SPOTS, + EasterEvent.EDGEVILLE_SPOTS, + EasterEvent.DRAYNOR_SPOTS, + EasterEvent.LUMBRIDGE_SPOTS, + EasterEvent.TREE_GNOME_STRONGHOLD_SPOTS + )) + { + val usedLocations = ArrayList() + for (loc in locSet) + { + if (!usedLocations.contains(loc)) + usedLocations.add(loc) + else + Assertions.fail("Loc $loc appeared more than once!") + } + } + } + + @Test fun gfxForEggShouldReturnCorrectGfx() + { + val expectations = arrayOf( + Pair(EasterEvent.EGG_A, EasterEvent.GFX_A), + Pair(EasterEvent.EGG_B, EasterEvent.GFX_B), + Pair(EasterEvent.EGG_C, EasterEvent.GFX_C), + Pair(EasterEvent.EGG_D, EasterEvent.GFX_D), + Pair(-1, EasterEvent.GFX_A) + ) + + for ((egg, gfx) in expectations) + Assertions.assertEquals(gfx, EasterEvent.gfxForEgg(egg)) + } +} \ No newline at end of file diff --git a/Server/src/test/kotlin/core/net/LoginTests.kt b/Server/src/test/kotlin/core/net/LoginTests.kt new file mode 100644 index 0000000..6021677 --- /dev/null +++ b/Server/src/test/kotlin/core/net/LoginTests.kt @@ -0,0 +1,40 @@ +package core.net + +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test +import core.auth.AuthResponse +import core.net.packet.`in`.Login +import java.nio.ByteBuffer + +class LoginTests { + @Test fun shouldDecodeCorrectlyEncodedPacket() { + val localCopy = validLoginPacket.copyOf(validLoginPacket.size) + val loginInfo = Login.decodeFromBuffer(ByteBuffer.wrap(localCopy)) + Assertions.assertEquals(AuthResponse.Success, loginInfo.first, "Info: ${loginInfo.second}") + } + + @Test fun shouldNeverThrowExceptionButReturnUnexpectedErrorResponseInstead() { + val localCopy = validLoginPacket.copyOf(validLoginPacket.size) + for(i in 15 until validLoginPacket.size) { + localCopy[i] = 0 //corrupt some data on purpose + } + var response: AuthResponse = AuthResponse.Updating + Assertions.assertDoesNotThrow { + val (res, _) = Login.decodeFromBuffer(ByteBuffer.wrap(localCopy)) + response = res + } + + Assertions.assertEquals(AuthResponse.UnexpectedError, response) + } + + @Test fun loginPacketWithInvalidOpcodeShouldReturnAHelpfulResponse() { + val localCopy = validLoginPacket.copyOf(validLoginPacket.size) + localCopy[0] = 2 //set to invalid login opcode + val (response, _) = Login.decodeFromBuffer(ByteBuffer.wrap(localCopy)) + Assertions.assertEquals(AuthResponse.InvalidLoginServer, response) + } + + companion object { + val validLoginPacket = byteArrayOf(16,1,80,0,0,2,18,0,1,1,2,2,-3,1,-9,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,107,75,109,111,107,51,107,74,113,79,101,78,54,68,51,109,68,100,105,104,99,111,51,111,80,101,89,78,50,75,70,121,54,87,53,45,45,118,90,85,98,78,65,0,0,0,0,0,1,81,-73,-29,0,0,-47,-49,34,92,-124,110,-97,46,-33,-18,122,8,76,93,-82,16,53,23,-113,-73,101,126,-93,125,-65,115,-59,19,90,-54,-102,-76,-99,-5,-68,-51,95,-20,-27,10,60,60,108,5,76,9,-63,97,106,74,116,0,58,0,75,-111,-128,-34,12,64,47,-92,-33,-120,-109,-7,23,124,122,40,-107,56,-34,-93,64,-82,58,-90,7,127,-15,-85,125,43,15,0,112,60,4,75,72,55,18,83,-119,-39,32,-113,21,104,-49,66,-102,104,-13,32,117,-106,94,-30,37,-56,-67,21,77,70,-128,68,112,-78,-49,-58,-48,74,70,31,12,64,84,124,2,-61,71,104,55,73,62,-27,111,122,-56,52,93,1,-52,32,102,73,-21,-46,-79,45,58,88,-36,-113,31,78,77,-56,-126,-103,-33,21,110,47,-81,-70,-15,14,114,51,-41,-49,6,-112,-28,-28,-112,113,120,68,29,-123,-108,24,-58,6,113,54,55,21,-58,32,99,-120,13,8,-94,-83,121,123,20,16,-89,43,-51,-20,74,-114,-126,-86,-12,38,-107,12,25,-40,-79,-116,-18,-85,-83,95,-106,-81,-64,31,110,-65,-128,-74,70,80,-20,11,117,28,39,-102,75,67,98,-121,-28) + } +} \ No newline at end of file diff --git a/Server/src/test/resources/530_cache_item_values_from_client.csv b/Server/src/test/resources/530_cache_item_values_from_client.csv new file mode 100644 index 0000000..727bec9 --- /dev/null +++ b/Server/src/test/resources/530_cache_item_values_from_client.csv @@ -0,0 +1,14658 @@ +id,name,cost +0,Dwarf remains,1 +1,Toolkit,1 +2,Cannonball,5 +3,Nulodion's notes,1 +4,Ammo mould,5 +5,Instruction manual,10 +6,Cannon base,187500 +7,Cannon base,187500 +8,Cannon stand,187500 +9,Cannon stand,187500 +10,Cannon barrels,187500 +11,Cannon barrels,187500 +12,Cannon furnace,187500 +13,Cannon furnace,187500 +14,Railing,1 +15,Holy table napkin,10 +16,Magic whistle,10 +17,Grail bell,10 +18,Magic gold feather,2 +19,Holy grail,3 +20,White cog,1 +21,Black cog,1 +22,Blue cog,1 +23,Red cog,1 +24,Rat poison,1 +25,Red vine worm,1 +26,Fishing trophy,1 +27,Fishing pass,1 +28,Insect repellent,3 +29,Tinderbox,0 +30,Bucket of wax,6 +31,Tinderbox,0 +32,Lit black candle,3 +33,Lit candle,3 +34,Lit candle,3 +35,Excalibur,200 +36,Candle,3 +37,Candle,3 +38,Black candle,3 +39,Bronze arrowtips,10 +40,Iron arrowtips,26 +41,Steel arrowtips,36 +42,Mithril arrowtips,68 +43,Adamant arrowtips,160 +44,Rune arrowtips,460 +45,Opal bolt tips,7 +46,Pearl bolt tips,12 +47,Barb bolttips,95 +48,Longbow (u),60 +49,Longbow (u),60 +50,Shortbow (u),23 +51,Shortbow (u),23 +52,Arrow shaft,12 +53,Headless arrow,1 +54,Oak shortbow (u),50 +55,Oak shortbow (u),50 +56,Oak longbow (u),80 +57,Oak longbow (u),80 +58,Willow longbow (u),160 +59,Willow longbow (u),160 +60,Willow shortbow (u),100 +61,Willow shortbow (u),100 +62,Maple longbow (u),320 +63,Maple longbow (u),320 +64,Maple shortbow (u),200 +65,Maple shortbow (u),200 +66,Yew longbow (u),640 +67,Yew longbow (u),640 +68,Yew shortbow (u),400 +69,Yew shortbow (u),400 +70,Magic longbow (u),1280 +71,Magic longbow (u),1280 +72,Magic shortbow (u),800 +73,Magic shortbow (u),800 +74,Khazard helmet,10 +75,Khazard armour,12 +76,Khazard cell keys,1 +77,Khali brew,5 +78,Ice arrows,2 +79,null,1 +80,null,1 +81,null,1 +82,null,1 +83,Lever,15 +84,Staff of armadyl,15 +85,Shiny key,1 +86,Pendant of lucien,12 +87,Armadyl pendant,12 +88,Boots of lightness,6 +89,Boots of lightness,6 +90,Child's blanket,5 +91,Guam potion(unf),3 +92,Guam potion(unf),3 +93,Marrentill potion(unf),5 +94,Marrentill potion(unf),5 +95,Tarromin potion(unf),11 +96,Tarromin potion(unf),11 +97,Harralander potion(unf),20 +98,Harralander potion(unf),20 +99,Ranarr potion(unf),25 +100,Ranarr potion(unf),25 +101,Irit potion(unf),40 +102,Irit potion(unf),40 +103,Avantoe potion(unf),48 +104,Avantoe potion(unf),48 +105,Kwuarm potion(unf),54 +106,Kwuarm potion(unf),54 +107,Cadantine potion(unf),65 +108,Cadantine potion(unf),65 +109,Dwarf weed potion(unf),70 +110,Dwarf weed potion(unf),70 +111,Torstol potion(unf),25 +112,Torstol potion(unf),25 +113,Strength potion(4),1500 +114,Strength potion(4),1500 +115,Strength potion(3),1200 +116,Strength potion(3),1200 +117,Strength potion(2),900 +118,Strength potion(2),900 +119,Strength potion(1),600 +120,Strength potion(1),600 +121,Attack potion(3),560 +122,Attack potion(3),560 +123,Attack potion(2),420 +124,Attack potion(2),420 +125,Attack potion(1),280 +126,Attack potion(1),280 +127,Restore potion(3),88 +128,Restore potion(3),88 +129,Restore potion(2),66 +130,Restore potion(2),66 +131,Restore potion(1),44 +132,Restore potion(1),44 +133,Defence potion(3),880 +134,Defence potion(3),880 +135,Defence potion(2),660 +136,Defence potion(2),660 +137,Defence potion(1),440 +138,Defence potion(1),440 +139,Prayer potion(3),152 +140,Prayer potion(3),152 +141,Prayer potion(2),114 +142,Prayer potion(2),114 +143,Prayer potion(1),76 +144,Prayer potion(1),76 +145,Super attack(3),180 +146,Super attack(3),180 +147,Super attack(2),135 +148,Super attack(2),135 +149,Super attack(1),90 +150,Super attack(1),90 +151,Fishing potion(3),200 +152,Fishing potion(3),200 +153,Fishing potion(2),150 +154,Fishing potion(2),150 +155,Fishing potion(1),100 +156,Fishing potion(1),100 +157,Super strength(3),220 +158,Super strength(3),220 +159,Super strength(2),165 +160,Super strength(2),165 +161,Super strength(1),110 +162,Super strength(1),110 +163,Super defence(3),264 +164,Super defence(3),264 +165,Super defence(2),198 +166,Super defence(2),198 +167,Super defence(1),132 +168,Super defence(1),132 +169,Ranging potion(3),288 +170,Ranging potion(3),288 +171,Ranging potion(2),216 +172,Ranging potion(2),216 +173,Ranging potion(1),144 +174,Ranging potion(1),144 +175,Antipoison(3),288 +176,Antipoison(3),288 +177,Antipoison(2),216 +178,Antipoison(2),216 +179,Antipoison(1),144 +180,Antipoison(1),144 +181,Super antipoison(3),288 +182,Super antipoison(3),288 +183,Super antipoison(2),216 +184,Super antipoison(2),216 +185,Super antipoison(1),144 +186,Super antipoison(1),144 +187,Weapon poison,144 +188,Weapon poison,144 +189,Zamorak brew(3),175 +190,Zamorak brew(3),175 +191,Zamorak brew(2),150 +192,Zamorak brew(2),150 +193,Zamorak brew(1),125 +194,Zamorak brew(1),125 +195,Potion,1 +196,Potion,1 +197,Poison chalice,20 +198,Poison chalice,20 +199,Grimy guam,1 +200,Grimy guam,1 +201,Grimy marrentill,1 +202,Grimy marrentill,1 +203,Grimy tarromin,1 +204,Grimy tarromin,1 +205,Grimy harralander,1 +206,Grimy harralander,1 +207,Grimy ranarr,1 +208,Grimy ranarr,1 +209,Grimy irit,1 +210,Grimy irit,1 +211,Grimy avantoe,1 +212,Grimy avantoe,1 +213,Grimy kwuarm,1 +214,Grimy kwuarm,1 +215,Grimy cadantine,1 +216,Grimy cadantine,1 +217,Grimy dwarf weed,1 +218,Grimy dwarf weed,1 +219,Grimy torstol,1 +220,Grimy torstol,1 +221,Eye of newt,3 +222,Eye of newt,3 +223,Red spiders' eggs,7 +224,Red spiders' eggs,7 +225,Limpwurt root,7 +226,Limpwurt root,7 +227,Vial of water,10 +228,Vial of water,10 +229,Vial,5 +230,Vial,5 +231,Snape grass,10 +232,Snape grass,10 +233,Pestle and mortar,4 +234,Pestle and mortar,4 +235,Unicorn horn dust,20 +236,Unicorn horn dust,20 +237,Unicorn horn,20 +238,Unicorn horn,20 +239,White berries,10 +240,White berries,10 +241,Dragon scale dust,52 +242,Dragon scale dust,52 +243,Blue dragon scale,50 +244,Blue dragon scale,50 +245,Wine of zamorak,1 +246,Wine of zamorak,1 +247,Jangerberries,1 +248,Jangerberries,1 +249,Clean guam,3 +250,Clean guam,3 +251,Clean marrentill,5 +252,Clean marrentill,5 +253,Clean tarromin,11 +254,Clean tarromin,11 +255,Clean harralander,20 +256,Clean harralander,20 +257,Clean ranarr,25 +258,Clean ranarr,25 +259,Clean irit,40 +260,Clean irit,40 +261,Clean avantoe,48 +262,Clean avantoe,48 +263,Clean kwuarm,54 +264,Clean kwuarm,54 +265,Clean cadantine,65 +266,Clean cadantine,65 +267,Clean dwarf weed,70 +268,Clean dwarf weed,70 +269,Clean torstol,75 +270,Clean torstol,75 +271,Pressure gauge,1 +272,Fish food,1 +273,Poison,1 +274,Poisoned fish food,1 +275,Key,1 +276,Rubber tube,3 +277,Oil can,3 +278,Cattleprod,3 +279,Sheep feed,3 +280,Sheep bones (1),1 +281,Sheep bones (2),1 +282,Sheep bones (3),1 +283,Sheep bones (4),1 +284,Plague jacket,50 +285,Plague trousers,50 +286,Orange goblin mail,40 +287,Blue goblin mail,40 +288,Goblin mail,40 +289,Goblin mail,40 +290,Research package,2 +291,Notes,5 +292,Book on baxtorian,2 +293,A key,1 +294,Glarial's pebble,1 +295,Glarial's amulet,1 +296,Glarial's urn,1 +297,Glarial's urn,1 +298,A key,1 +299,Mithril seeds,300 +300,Rat's tail,3 +301,Lobster pot,20 +302,Lobster pot,20 +303,Small fishing net,5 +304,Small fishing net,5 +305,Big fishing net,20 +306,Big fishing net,20 +307,Fishing rod,5 +308,Fishing rod,5 +309,Fly fishing rod,5 +310,Fly fishing rod,5 +311,Harpoon,5 +312,Harpoon,5 +313,Fishing bait,3 +314,Feather,6 +315,Shrimps,5 +316,Shrimps,5 +317,Raw shrimps,6 +318,Raw shrimps,6 +319,Anchovies,15 +320,Anchovies,15 +321,Raw anchovies,16 +322,Raw anchovies,16 +323,Burnt fish,1 +324,Burnt fish,1 +325,Sardine,10 +326,Sardine,10 +327,Raw sardine,10 +328,Raw sardine,10 +329,Salmon,88 +330,Salmon,88 +331,Raw salmon,92 +332,Raw salmon,92 +333,Trout,68 +334,Trout,68 +335,Raw trout,20 +336,Raw trout,20 +337,Giant carp,50 +338,Raw giant carp,50 +339,Cod,26 +340,Cod,26 +341,Raw cod,34 +342,Raw cod,34 +343,Burnt fish,1 +344,Burnt fish,1 +345,Raw herring,16 +346,Raw herring,16 +347,Herring,15 +348,Herring,15 +349,Raw pike,25 +350,Raw pike,25 +351,Pike,25 +352,Pike,25 +353,Raw mackerel,26 +354,Raw mackerel,26 +355,Mackerel,17 +356,Mackerel,17 +357,Burnt fish,1 +358,Burnt fish,1 +359,Raw tuna,120 +360,Raw tuna,120 +361,Tuna,120 +362,Tuna,120 +363,Raw bass,280 +364,Raw bass,280 +365,Bass,270 +366,Bass,270 +367,Burnt fish,1 +368,Burnt fish,1 +369,Burnt fish,1 +370,Burnt fish,1 +371,Raw swordfish,340 +372,Raw swordfish,340 +373,Swordfish,400 +374,Swordfish,400 +375,Burnt swordfish,1 +376,Burnt swordfish,1 +377,Raw lobster,284 +378,Raw lobster,284 +379,Lobster,268 +380,Lobster,268 +381,Burnt lobster,1 +382,Burnt lobster,1 +383,Raw shark,300 +384,Raw shark,300 +385,Shark,300 +386,Shark,300 +387,Burnt shark,1 +388,Burnt shark,1 +389,Raw manta ray,500 +390,Raw manta ray,500 +391,Manta ray,500 +392,Manta ray,500 +393,Burnt manta ray,1 +394,Burnt manta ray,1 +395,Raw sea turtle,500 +396,Raw sea turtle,500 +397,Sea turtle,500 +398,Sea turtle,500 +399,Burnt sea turtle,1 +400,Burnt sea turtle,1 +401,Seaweed,2 +402,Seaweed,2 +403,Edible seaweed,2 +404,Edible seaweed,2 +405,Casket,50 +406,Casket,50 +407,Oyster,200 +408,Oyster,200 +409,Empty oyster,5 +410,Empty oyster,5 +411,Oyster pearl,112 +412,Oyster pearl,112 +413,Oyster pearls,1400 +414,Oyster pearls,1400 +415,Ethenea,10 +416,Liquid honey,0 +417,Sulphuric broline,1 +418,Plague sample,1 +419,Touch paper,1 +420,Distillator,1 +421,Lathas' amulet,10 +422,Bird feed,1 +423,Key,1 +424,Pigeon cage,1 +425,Pigeon cage,1 +426,Priest gown,5 +427,Priest gown,5 +428,Priest gown,5 +429,Priest gown,5 +430,Doctors' gown,40 +431,Karamjan rum,30 +432,Chest key,1 +433,Pirate message,1 +434,Clay,1 +435,Clay,1 +436,Copper ore,20 +437,Copper ore,20 +438,Tin ore,20 +439,Tin ore,20 +440,Iron ore,17 +441,Iron ore,17 +442,Silver ore,75 +443,Silver ore,75 +444,Gold ore,150 +445,Gold ore,150 +446,'perfect' gold ore,150 +447,Mithril ore,162 +448,Mithril ore,162 +449,Adamantite ore,400 +450,Adamantite ore,400 +451,Runite ore,3200 +452,Runite ore,3200 +453,Coal,45 +454,Coal,45 +455,Barcrawl card,10 +456,Scorpion cage,10 +457,Scorpion cage,10 +458,Scorpion cage,10 +459,Scorpion cage,10 +460,Scorpion cage,10 +461,Scorpion cage,10 +462,Scorpion cage,10 +463,Scorpion cage,10 +464,Strange fruit,1 +465,Strange fruit,1 +466,Pickaxe handle,1 +467,Pickaxe handle,1 +468,Broken pickaxe,1 +469,Broken pickaxe,1 +470,Broken pickaxe,1 +471,Broken pickaxe,1 +472,Broken pickaxe,17 +473,Broken pickaxe,17 +474,Broken pickaxe,43 +475,Broken pickaxe,43 +476,Broken pickaxe,107 +477,Broken pickaxe,107 +478,Broken pickaxe,1100 +479,Broken pickaxe,1100 +480,Bronze pick head,1 +481,Bronze pick head,1 +482,Iron pick head,139 +483,Iron pick head,139 +484,Steel pick head,499 +485,Steel pick head,499 +486,Mithril pick head,1299 +487,Mithril pick head,1299 +488,Adamant pick head,3199 +489,Adamant pick head,3199 +490,Rune pick head,31999 +491,Rune pick head,31999 +492,Picture,1 +493,Picture,1 +494,Broken axe,0 +495,Broken axe,0 +496,Broken axe,0 +497,Broken axe,0 +498,Broken axe,0 +499,Broken axe,0 +500,Broken axe,10 +501,Broken axe,10 +502,Broken axe,18 +503,Broken axe,18 +504,Broken axe,43 +505,Broken axe,43 +506,Broken axe,427 +507,Broken axe,427 +508,Picture,15 +509,Picture,15 +510,Picture,55 +511,Picture,55 +512,Picture,199 +513,Picture,199 +514,Picture,383 +515,Picture,383 +516,Picture,519 +517,Picture,519 +518,Picture,1279 +519,Picture,1279 +520,Picture,12799 +521,Picture,12799 +522,Enchanted beef,1 +523,Enchanted rat meat,1 +524,Enchanted bear meat,1 +525,Enchanted chicken,1 +526,Bones,1 +527,Bones,1 +528,Burnt bones,1 +529,Burnt bones,1 +530,Bat bones,1 +531,Bat bones,1 +532,Big bones,1 +533,Big bones,1 +534,Babydragon bones,1 +535,Babydragon bones,1 +536,Dragon bones,1 +537,Dragon bones,1 +538,Druid's robe,30 +539,Druid's robe,30 +540,Druid's robe,40 +541,Druid's robe,40 +542,Monk's robe,30 +543,Monk's robe,30 +544,Monk's robe,40 +545,Monk's robe,40 +546,Shade robe,40 +547,Picture,0 +548,Shade robe,30 +549,Picture,0 +550,Newcomer map,1 +551,Newcomer map,1 +552,Ghostspeak amulet,35 +553,Ghost's skull,1 +554,Fire rune,17 +555,Water rune,17 +556,Air rune,17 +557,Earth rune,17 +558,Mind rune,17 +559,Body rune,16 +560,Death rune,310 +561,Nature rune,372 +562,Chaos rune,140 +563,Law rune,378 +564,Cosmic rune,232 +565,Blood rune,550 +566,Soul rune,410 +567,Unpowered orb,100 +568,Unpowered orb,100 +569,Fire orb,300 +570,Fire orb,300 +571,Water orb,300 +572,Water orb,300 +573,Air orb,300 +574,Air orb,300 +575,Earth orb,300 +576,Earth orb,300 +577,Wizard robe,15 +578,Wizard robe,15 +579,Wizard hat,2 +580,Wizard hat,2 +581,Black robe,13 +582,Black robe,13 +583,Bailing bucket,10 +584,Bailing bucket,10 +585,Bailing bucket,10 +586,Bailing bucket,10 +587,Orb of protection,1 +588,Orbs of protection,1 +589,Gnome amulet,1 +590,Tinderbox,1 +591,Tinderbox,1 +592,Ashes,2 +593,Ashes,2 +594,Lit torch,4 +595,Torch,4 +596,Unlit torch,4 +597,Unlit torch,4 +598,Bronze fire arrows,10 +599,Picture,1 +600,Astronomy book,3 +601,Goblin kitchen key,1 +602,Lens mould,1 +603,Observatory lens,3 +604,Bone shard,1 +605,Bone key,1 +606,Stone-plaque,1 +607,Tattered scroll,1 +608,Crumpled scroll,1 +609,Rashiliyia corpse,1 +610,Zadimus corpse,1 +611,Locating crystal,1 +612,Locating crystal,1 +613,Locating crystal,1 +614,Locating crystal,1 +615,Locating crystal,1 +616,Beads of the dead,1 +617,Coins,1 +618,Bone beads,1 +619,Paramaya ticket,5 +620,Paramaya ticket,5 +621,Ship ticket,5 +622,Tinderbox,0 +623,Sword pommel,1 +624,Bervirius notes,1 +625,Wampum belt,5 +626,Boots,200 +627,Boots,200 +628,Boots,200 +629,Boots,200 +630,Boots,200 +631,Boots,200 +632,Boots,200 +633,Boots,200 +634,Boots,200 +635,Boots,200 +636,Robe top,180 +637,Robe top,180 +638,Robe top,180 +639,Robe top,180 +640,Robe top,180 +641,Robe top,180 +642,Robe top,180 +643,Robe top,180 +644,Robe top,180 +645,Robe top,180 +646,Robe bottoms,180 +647,Robe bottoms,180 +648,Robe bottoms,180 +649,Robe bottoms,180 +650,Robe bottoms,180 +651,Robe bottoms,180 +652,Robe bottoms,180 +653,Robe bottoms,180 +654,Robe bottoms,180 +655,Robe bottoms,180 +656,Hat,160 +657,Hat,160 +658,Hat,160 +659,Hat,160 +660,Hat,160 +661,Hat,160 +662,Hat,160 +663,Hat,160 +664,Hat,160 +665,Hat,160 +666,Portrait,3 +667,Blurite sword,200 +668,Blurite ore,3 +669,Specimen jar,1 +670,Specimen brush,1 +671,Animal skull,1 +672,Special cup,1 +673,Teddy,1 +674,Cracked sample,1 +675,Rock pick,1 +676,Trowel,1 +677,Panning tray,1 +678,Panning tray,1 +679,Panning tray,1 +680,Nuggets,1 +681,Ancient talisman,1 +682,Unstamped letter,1 +683,Sealed letter,1 +684,Belt buckle,1 +685,Old boot,1 +686,Rusty sword,1 +687,Broken arrow,1 +688,Buttons,1 +689,Broken staff,1 +690,Picture,1 +691,Level 1 certificate,1 +692,Level 2 certificate,1 +693,Level 3 certificate,1 +694,Ceramic remains,1 +695,Old tooth,1 +696,Invitation letter,1 +697,Damaged armour,1 +698,Broken armour,1 +699,Stone tablet,1 +700,Chemical powder,1 +701,Ammonium nitrate,1 +702,Unidentified liquid,1 +703,Nitroglycerin,1 +704,Ground charcoal,1 +705,Mixed chemicals,1 +706,Mixed chemicals,1 +707,Chemical compound,1 +708,Arcenia root,1 +709,Chest key,1 +710,Vase,1 +711,Book on chemicals,1 +712,Cup of tea,1 +713,Picture,1 +714,Radimus notes,1 +715,Radimus notes,1 +716,Bull roarer,1 +717,Scrawled note,1 +718,A scribbled note,1 +719,Scrumpled note,1 +720,Sketch,10 +721,Gold bowl,700 +722,Blessed gold bowl,700 +723,Golden bowl,700 +724,Golden bowl,700 +725,Golden bowl,700 +726,Golden bowl,700 +727,Hollow reed,2 +728,Hollow reed,1 +729,Shamans tome,1 +730,Binding book,1 +731,Enchanted vial,1 +732,Holy water,1 +733,Smashed glass,1 +734,Tinderbox,0 +735,Yommi tree seeds,1 +736,Yommi tree seeds,1 +737,Snakeweed mixture,1 +738,Ardrigal mixture,1 +739,Bravery potion,1 +740,Blue hat,2 +741,Chunk of crystal,1 +742,Hunk of crystal,1 +743,Lump of crystal,1 +744,Heart crystal,1 +745,Heart crystal,1 +746,Dark dagger,1 +747,Glowing dagger,1 +748,Holy force,1 +749,Yommi totem,1 +750,Gilded totem,1 +751,Gnomeball,1 +752,Gnomeball,1 +753,Cadava berries,1 +754,Cadava berries,1 +755,Message,5 +756,Cadava potion,1 +757,Book,1 +758,Phoenix hq key,1 +759,Weapon store key,1 +760,Weapon store key,1 +761,Intel report,5 +762,Picture,1 +763,Broken shield,1 +764,Picture,1 +765,Broken shield,1 +766,Picture,1 +767,Phoenix crossbow,4 +768,Phoenix crossbow,4 +769,Certificate,1 +770,Picture,1 +771,Dramen branch,15 +772,Dramen staff,15 +773,'perfect' ring,2025 +774,'perfect' necklace,2175 +775,Cooking gauntlets,1 +776,Goldsmith gauntlets,1 +777,Chaos gauntlets,1 +778,Family gauntlets,1 +779,Crest part,1 +780,Crest part,1 +781,Crest part,1 +782,Family crest,1 +783,Bark sample,2 +784,Translation book,2 +785,Glough's journal,2 +786,Hazelmere's scroll,2 +787,Lumber order,2 +788,Glough's key,1 +789,Twigs,1 +790,Twigs,1 +791,Twigs,1 +792,Twigs,1 +793,Daconia rock,1 +794,Invasion plans,2 +795,War ship,2 +796,Exploding vial,1 +797,Herb bowl,1 +798,Grinder,1 +799,null,1 +800,Bronze thrownaxe,4 +801,Iron thrownaxe,13 +802,Steel thrownaxe,38 +803,Mithril thrownaxe,105 +804,Adamant thrownaxe,262 +805,Rune thrownaxe,698 +806,Bronze dart,1 +807,Iron dart,2 +808,Steel dart,10 +809,Mithril dart,25 +810,Adamant dart,65 +811,Rune dart,350 +812,Bronze dart(p),1 +813,Iron dart(p),2 +814,Steel dart(p),10 +815,Mithril dart(p),25 +816,Adamant dart(p),65 +817,Rune dart(p),350 +818,Poisoned dart(p),1 +819,Bronze dart tip,1 +820,Iron dart tip,3 +821,Steel dart tip,5 +822,Mithril dart tip,12 +823,Adamant dart tip,36 +824,Rune dart tip,175 +825,Bronze javelin,6 +826,Iron javelin,8 +827,Steel javelin,37 +828,Mithril javelin,98 +829,Adamant javelin,246 +830,Rune javelin,624 +831,Bronze javelin(p),4 +832,Iron javelin(p),6 +833,Steel javelin(p),24 +834,Mithril javelin(p),64 +835,Adamant javelin(p),160 +836,Rune javelin(p),400 +837,Crossbow,70 +838,Crossbow,70 +839,Longbow,80 +840,Longbow,80 +841,Shortbow,50 +842,Shortbow,50 +843,Oak shortbow,100 +844,Oak shortbow,100 +845,Oak longbow,160 +846,Oak longbow,160 +847,Willow longbow,320 +848,Willow longbow,320 +849,Willow shortbow,200 +850,Willow shortbow,200 +851,Maple longbow,640 +852,Maple longbow,640 +853,Maple shortbow,400 +854,Maple shortbow,400 +855,Yew longbow,1280 +856,Yew longbow,1280 +857,Yew shortbow,800 +858,Yew shortbow,800 +859,Magic longbow,2560 +860,Magic longbow,2560 +861,Magic shortbow,1600 +862,Magic shortbow,1600 +863,Iron knife,58 +864,Bronze knife,14 +865,Steel knife,68 +866,Mithril knife,27 +867,Adamant knife,66 +868,Rune knife,167 +869,Black knife,19 +870,Bronze knife(p),1 +871,Iron knife(p),3 +872,Steel knife(p),10 +873,Mithril knife(p),27 +874,Black knife(p),18 +875,Adamant knife(p),66 +876,Rune knife(p),166 +877,Bronze bolts,3 +878,Bronze bolts(p),3 +879,Opal bolts,7 +880,Pearl bolts,13 +881,Barbed bolts,200 +882,Bronze arrow,7 +883,Bronze arrow(p),1 +884,Iron arrow,20 +885,Iron arrow(p),3 +886,Steel arrow,46 +887,Steel arrow(p),12 +888,Mithril arrow,76 +889,Mithril arrow(p),32 +890,Adamant arrow,172 +891,Adamant arrow(p),80 +892,Rune arrow,510 +893,Rune arrow(p),400 +894,null,1 +895,null,1 +896,null,1 +897,null,1 +898,null,1 +899,null,1 +900,null,1 +901,null,1 +902,null,1 +903,null,1 +904,null,1 +905,null,1 +906,null,1 +907,null,1 +908,null,1 +909,null,1 +910,null,1 +911,null,1 +912,null,1 +913,null,1 +914,null,1 +915,null,1 +916,null,1 +917,null,1 +918,null,1 +919,null,1 +920,null,1 +921,null,1 +922,null,1 +923,null,1 +924,null,1 +925,null,1 +926,null,1 +927,null,1 +928,null,1 +929,null,1 +930,null,1 +931,null,1 +932,null,1 +933,null,1 +934,null,1 +935,null,1 +936,null,1 +937,null,1 +938,null,1 +939,null,1 +940,null,1 +941,null,1 +942,Bronze fire arrows,10 +943,Worm,0 +944,Worm,0 +945,Throwing rope,1 +946,Knife,6 +947,Knife,6 +948,Bear fur,10 +949,Bear fur,10 +950,Silk,55 +951,Silk,55 +952,Spade,3 +953,Spade,3 +954,Rope,18 +955,Rope,18 +956,Flier,1 +957,Tinderbox,0 +958,Grey wolf fur,150 +959,Grey wolf fur,150 +960,Plank,100 +961,Plank,100 +962,Christmas cracker,1 +963,Christmas cracker,1 +964,Skull,1 +965,Skull,1 +966,Tile,1 +967,Tinderbox,0 +968,Rock,1 +969,Tinderbox,0 +970,Papyrus,10 +971,Papyrus,10 +972,Papyrus,1 +973,Charcoal,45 +974,Charcoal,45 +975,Machete,52 +976,Machete,52 +977,Cooking pot,1 +978,Cooking pot,1 +979,null,1 +980,null,1 +981,Disk of returning,12 +982,Disk of returning,12 +983,Brass key,1 +984,Brass key,1 +985,Tooth half of a key,1 +986,Tooth half of a key,1 +987,Loop half of a key,1 +988,Loop half of a key,1 +989,Crystal key,1 +990,Crystal key,1 +991,Muddy key,1 +992,Muddy key,1 +993,Sinister key,1 +994,Sinister key,1 +995,Coins,1 +996,null,1 +997,null,1 +998,null,1 +999,null,1 +1000,null,1 +1001,null,1 +1002,null,1 +1003,null,1 +1004,null,1 +1005,White apron,2 +1006,White apron,2 +1007,Cape,20 +1008,Cape,20 +1009,Brass necklace,30 +1010,Brass necklace,30 +1011,Blue skirt,2 +1012,Blue skirt,2 +1013,Pink skirt,2 +1014,Pink skirt,2 +1015,Black skirt,2 +1016,Black skirt,2 +1017,Wizard hat,2 +1018,Wizard hat,2 +1019,Cape,20 +1020,Cape,20 +1021,Cape,20 +1022,Cape,20 +1023,Cape,20 +1024,Cape,20 +1025,Eye patch,2 +1026,Eye patch,2 +1027,Cape,20 +1028,Cape,20 +1029,Cape,20 +1030,Cape,20 +1031,Cape,20 +1032,Cape,20 +1033,Zamorak robe,30 +1034,Zamorak robe,30 +1035,Zamorak robe,40 +1036,Zamorak robe,40 +1037,Bunny ears,1 +1038,Red partyhat,1 +1039,Red partyhat,1 +1040,Yellow partyhat,1 +1041,Yellow partyhat,1 +1042,Blue partyhat,1 +1043,Blue partyhat,1 +1044,Green partyhat,1 +1045,Green partyhat,1 +1046,Purple partyhat,1 +1047,Purple partyhat,1 +1048,White partyhat,1 +1049,White partyhat,1 +1050,Santa hat,160 +1051,Santa hat,160 +1052,Cape of legends,450 +1053,Green h'ween mask,15 +1054,Green h'ween mask,15 +1055,Blue h'ween mask,15 +1056,Blue h'ween mask,15 +1057,Red h'ween mask,15 +1058,Red h'ween mask,15 +1059,Leather gloves,6 +1060,Leather gloves,6 +1061,Leather boots,6 +1062,Leather boots,6 +1063,Leather vambraces,18 +1064,Leather vambraces,18 +1065,Green d'hide vamb,2500 +1066,Green d'hide vamb,2500 +1067,Iron platelegs,280 +1068,Iron platelegs,280 +1069,Steel platelegs,1000 +1070,Steel platelegs,1000 +1071,Mithril platelegs,2600 +1072,Mithril platelegs,2600 +1073,Adamant platelegs,6400 +1074,Adamant platelegs,6400 +1075,Bronze platelegs,80 +1076,Bronze platelegs,80 +1077,Black platelegs,1920 +1078,Black platelegs,1920 +1079,Rune platelegs,64000 +1080,Rune platelegs,64000 +1081,Iron plateskirt,280 +1082,Iron plateskirt,280 +1083,Steel plateskirt,1000 +1084,Steel plateskirt,1000 +1085,Mithril plateskirt,2600 +1086,Mithril plateskirt,2600 +1087,Bronze plateskirt,80 +1088,Bronze plateskirt,80 +1089,Black plateskirt,1920 +1090,Black plateskirt,1920 +1091,Adamant plateskirt,6400 +1092,Adamant plateskirt,6400 +1093,Rune plateskirt,64000 +1094,Rune plateskirt,64000 +1095,Leather chaps,20 +1096,Leather chaps,20 +1097,Studded chaps,750 +1098,Studded chaps,750 +1099,Green d'hide chaps,3900 +1100,Green d'hide chaps,3900 +1101,Iron chainbody,210 +1102,Iron chainbody,210 +1103,Bronze chainbody,60 +1104,Bronze chainbody,60 +1105,Steel chainbody,750 +1106,Steel chainbody,750 +1107,Black chainbody,1440 +1108,Black chainbody,1440 +1109,Mithril chainbody,1950 +1110,Mithril chainbody,1950 +1111,Adamant chainbody,4800 +1112,Adamant chainbody,4800 +1113,Rune chainbody,50000 +1114,Rune chainbody,50000 +1115,Iron platebody,560 +1116,Iron platebody,560 +1117,Bronze platebody,160 +1118,Bronze platebody,160 +1119,Steel platebody,2000 +1120,Steel platebody,2000 +1121,Mithril platebody,5200 +1122,Mithril platebody,5200 +1123,Adamant platebody,16640 +1124,Adamant platebody,16640 +1125,Black platebody,3840 +1126,Black platebody,3840 +1127,Rune platebody,65000 +1128,Rune platebody,65000 +1129,Leather body,21 +1130,Leather body,21 +1131,Hardleather body,170 +1132,Hardleather body,170 +1133,Studded body,850 +1134,Studded body,850 +1135,Green d'hide body,7800 +1136,Green d'hide body,7800 +1137,Iron med helm,84 +1138,Iron med helm,84 +1139,Bronze med helm,24 +1140,Bronze med helm,24 +1141,Steel med helm,300 +1142,Steel med helm,300 +1143,Mithril med helm,780 +1144,Mithril med helm,780 +1145,Adamant med helm,1920 +1146,Adamant med helm,1920 +1147,Rune med helm,19200 +1148,Rune med helm,19200 +1149,Dragon med helm,100000 +1150,Dragon med helm,100000 +1151,Black med helm,576 +1152,Black med helm,576 +1153,Iron full helm,154 +1154,Iron full helm,154 +1155,Bronze full helm,44 +1156,Bronze full helm,44 +1157,Steel full helm,550 +1158,Steel full helm,550 +1159,Mithril full helm,1430 +1160,Mithril full helm,1430 +1161,Adamant full helm,3520 +1162,Adamant full helm,3520 +1163,Rune full helm,35200 +1164,Rune full helm,35200 +1165,Black full helm,1372 +1166,Black full helm,1372 +1167,Leather cowl,24 +1168,Leather cowl,24 +1169,Coif,200 +1170,Coif,200 +1171,Wooden shield,20 +1172,Wooden shield,20 +1173,Bronze sq shield,48 +1174,Bronze sq shield,48 +1175,Iron sq shield,168 +1176,Iron sq shield,168 +1177,Steel sq shield,600 +1178,Steel sq shield,600 +1179,Black sq shield,1152 +1180,Black sq shield,1152 +1181,Mithril sq shield,1560 +1182,Mithril sq shield,1560 +1183,Adamant sq shield,3840 +1184,Adamant sq shield,3840 +1185,Rune sq shield,38400 +1186,Rune sq shield,38400 +1187,Dragon sq shield,500000 +1188,Dragon sq shield,500000 +1189,Bronze kiteshield,68 +1190,Bronze kiteshield,68 +1191,Iron kiteshield,238 +1192,Iron kiteshield,238 +1193,Steel kiteshield,850 +1194,Steel kiteshield,850 +1195,Black kiteshield,2121 +1196,Black kiteshield,2121 +1197,Mithril kiteshield,2210 +1198,Mithril kiteshield,2210 +1199,Adamant kiteshield,5440 +1200,Adamant kiteshield,5440 +1201,Rune kiteshield,54400 +1202,Rune kiteshield,54400 +1203,Iron dagger,35 +1204,Iron dagger,35 +1205,Bronze dagger,10 +1206,Bronze dagger,10 +1207,Steel dagger,125 +1208,Steel dagger,125 +1209,Mithril dagger,325 +1210,Mithril dagger,325 +1211,Adamant dagger,800 +1212,Adamant dagger,800 +1213,Rune dagger,8000 +1214,Rune dagger,8000 +1215,Dragon dagger,30000 +1216,Dragon dagger,30000 +1217,Black dagger,240 +1218,Black dagger,240 +1219,Iron dagger(p),35 +1220,Iron dagger(p),35 +1221,Bronze dagger(p),10 +1222,Bronze dagger(p),10 +1223,Steel dagger(p),125 +1224,Steel dagger(p),125 +1225,Mithril dagger(p),325 +1226,Mithril dagger(p),325 +1227,Adamant dagger(p),800 +1228,Adamant dagger(p),800 +1229,Rune dagger(p),8000 +1230,Rune dagger(p),8000 +1231,Dragon dagger(p),24000 +1232,Dragon dagger(p),24000 +1233,Black dagger(p),240 +1234,Black dagger(p),240 +1235,Poisoned dagger(p),565 +1236,Poisoned dagger(p),565 +1237,Bronze spear,26 +1238,Bronze spear,26 +1239,Iron spear,91 +1240,Iron spear,91 +1241,Steel spear,325 +1242,Steel spear,325 +1243,Mithril spear,845 +1244,Mithril spear,845 +1245,Adamant spear,2080 +1246,Adamant spear,2080 +1247,Rune spear,20800 +1248,Rune spear,20800 +1249,Dragon spear,62400 +1250,Dragon spear,62400 +1251,Bronze spear(p),26 +1252,Bronze spear(p),26 +1253,Iron spear(p),91 +1254,Iron spear(p),91 +1255,Steel spear(p),325 +1256,Steel spear(p),325 +1257,Mithril spear(p),845 +1258,Mithril spear(p),845 +1259,Adamant spear(p),2080 +1260,Adamant spear(p),2080 +1261,Rune spear(p),20800 +1262,Rune spear(p),20800 +1263,Dragon spear(p),62400 +1264,Dragon spear(p),62400 +1265,Bronze pickaxe,1 +1266,Bronze pickaxe,1 +1267,Iron pickaxe,140 +1268,Iron pickaxe,140 +1269,Steel pickaxe,500 +1270,Steel pickaxe,500 +1271,Adamant pickaxe,3200 +1272,Adamant pickaxe,3200 +1273,Mithril pickaxe,1300 +1274,Mithril pickaxe,1300 +1275,Rune pickaxe,32000 +1276,Rune pickaxe,32000 +1277,Bronze sword,26 +1278,Bronze sword,26 +1279,Iron sword,91 +1280,Iron sword,91 +1281,Steel sword,325 +1282,Steel sword,325 +1283,Black sword,624 +1284,Black sword,624 +1285,Mithril sword,845 +1286,Mithril sword,845 +1287,Adamant sword,2080 +1288,Adamant sword,2080 +1289,Rune sword,20800 +1290,Rune sword,20800 +1291,Bronze longsword,40 +1292,Bronze longsword,40 +1293,Iron longsword,140 +1294,Iron longsword,140 +1295,Steel longsword,500 +1296,Steel longsword,500 +1297,Black longsword,960 +1298,Black longsword,960 +1299,Mithril longsword,1300 +1300,Mithril longsword,1300 +1301,Adamant longsword,3200 +1302,Adamant longsword,3200 +1303,Rune longsword,32000 +1304,Rune longsword,32000 +1305,Dragon longsword,100000 +1306,Dragon longsword,100000 +1307,Bronze 2h sword,80 +1308,Bronze 2h sword,80 +1309,Iron 2h sword,280 +1310,Iron 2h sword,280 +1311,Steel 2h sword,1000 +1312,Steel 2h sword,1000 +1313,Black 2h sword,1920 +1314,Black 2h sword,1920 +1315,Mithril 2h sword,2600 +1316,Mithril 2h sword,2600 +1317,Adamant 2h sword,6400 +1318,Adamant 2h sword,6400 +1319,Rune 2h sword,64000 +1320,Rune 2h sword,64000 +1321,Bronze scimitar,32 +1322,Bronze scimitar,32 +1323,Iron scimitar,112 +1324,Iron scimitar,112 +1325,Steel scimitar,400 +1326,Steel scimitar,400 +1327,Black scimitar,768 +1328,Black scimitar,768 +1329,Mithril scimitar,1040 +1330,Mithril scimitar,1040 +1331,Adamant scimitar,2560 +1332,Adamant scimitar,2560 +1333,Rune scimitar,25600 +1334,Rune scimitar,25600 +1335,Iron warhammer,224 +1336,Iron warhammer,224 +1337,Bronze warhammer,61 +1338,Bronze warhammer,61 +1339,Steel warhammer,832 +1340,Steel warhammer,832 +1341,Black warhammer,1274 +1342,Black warhammer,1274 +1343,Mithril warhammer,2158 +1344,Mithril warhammer,2158 +1345,Adamant warhammer,5356 +1346,Adamant warhammer,5356 +1347,Rune warhammer,41500 +1348,Rune warhammer,41500 +1349,Iron axe,56 +1350,Iron axe,56 +1351,Bronze axe,16 +1352,Bronze axe,16 +1353,Steel axe,200 +1354,Steel axe,200 +1355,Mithril axe,520 +1356,Mithril axe,520 +1357,Adamant axe,1280 +1358,Adamant axe,1280 +1359,Rune axe,12800 +1360,Rune axe,12800 +1361,Black axe,384 +1362,Black axe,384 +1363,Iron battleaxe,182 +1364,Iron battleaxe,182 +1365,Steel battleaxe,650 +1366,Steel battleaxe,650 +1367,Black battleaxe,1248 +1368,Black battleaxe,1248 +1369,Mithril battleaxe,1690 +1370,Mithril battleaxe,1690 +1371,Adamant battleaxe,4160 +1372,Adamant battleaxe,4160 +1373,Rune battleaxe,41600 +1374,Rune battleaxe,41600 +1375,Bronze battleaxe,52 +1376,Bronze battleaxe,52 +1377,Dragon battleaxe,200000 +1378,Dragon battleaxe,200000 +1379,Staff,15 +1380,Staff,15 +1381,Staff of air,1500 +1382,Staff of air,1500 +1383,Staff of water,1500 +1384,Staff of water,1500 +1385,Staff of earth,1500 +1386,Staff of earth,1500 +1387,Staff of fire,1500 +1388,Staff of fire,1500 +1389,Magic staff,200 +1390,Magic staff,200 +1391,Battlestaff,7000 +1392,Battlestaff,7000 +1393,Fire battlestaff,15500 +1394,Fire battlestaff,15500 +1395,Water battlestaff,15500 +1396,Water battlestaff,15500 +1397,Air battlestaff,15500 +1398,Air battlestaff,15500 +1399,Earth battlestaff,15500 +1400,Earth battlestaff,15500 +1401,Mystic fire staff,42500 +1402,Mystic fire staff,42500 +1403,Mystic water staff,42500 +1404,Mystic water staff,42500 +1405,Mystic air staff,42500 +1406,Mystic air staff,42500 +1407,Mystic earth staff,42500 +1408,Mystic earth staff,42500 +1409,Iban's staff,42500 +1410,Iban's staff,20 +1411,Farmer's fork,1 +1412,Farmer's fork,1 +1413,Halberd,1 +1414,Halberd,1 +1415,Warhammer,1 +1416,Warhammer,1 +1417,Javelin,1 +1418,Javelin,1 +1419,Scythe,1 +1420,Iron mace,63 +1421,Iron mace,63 +1422,Bronze mace,18 +1423,Bronze mace,18 +1424,Steel mace,225 +1425,Steel mace,225 +1426,Black mace,432 +1427,Black mace,432 +1428,Mithril mace,585 +1429,Mithril mace,585 +1430,Adamant mace,1440 +1431,Adamant mace,1440 +1432,Rune mace,14400 +1433,Rune mace,14400 +1434,Dragon mace,50000 +1435,Dragon mace,50000 +1436,Rune essence,4 +1437,Rune essence,4 +1438,Air talisman,4 +1439,Air talisman,4 +1440,Earth talisman,4 +1441,Earth talisman,4 +1442,Fire talisman,4 +1443,Fire talisman,4 +1444,Water talisman,4 +1445,Water talisman,4 +1446,Body talisman,4 +1447,Body talisman,4 +1448,Mind talisman,4 +1449,Mind talisman,4 +1450,Blood talisman,4 +1451,Blood talisman,4 +1452,Chaos talisman,4 +1453,Chaos talisman,4 +1454,Cosmic talisman,4 +1455,Cosmic talisman,4 +1456,Death talisman,4 +1457,Death talisman,4 +1458,Law talisman,4 +1459,Law talisman,4 +1460,Soul talisman,4 +1461,Soul talisman,4 +1462,Nature talisman,4 +1463,Nature talisman,4 +1464,Archery ticket,25 +1465,Weapon poison,11 +1466,Sea slug,4 +1467,Damp sticks,1 +1468,Dry sticks,1 +1469,Broken glass,0 +1470,Red bead,4 +1471,Red bead,4 +1472,Yellow bead,4 +1473,Yellow bead,4 +1474,Black bead,4 +1475,Black bead,4 +1476,White bead,4 +1477,White bead,4 +1478,Amulet of accuracy,100 +1479,Amulet of accuracy,100 +1480,Rock,1 +1481,Orb of light,10 +1482,Orb of light,10 +1483,Orb of light,10 +1484,Orb of light,20 +1485,Damp cloth,10 +1486,Piece of railing,10 +1487,Unicorn horn,20 +1488,Paladin's badge,10 +1489,Paladin's badge,10 +1490,Paladin's badge,10 +1491,Witch's cat,1 +1492,Doll of iban,2 +1493,Old journal,1 +1494,History of iban,1 +1495,Klank's gauntlets,6 +1496,Iban's dove,1 +1497,Amulet of othanian,0 +1498,Amulet of doomion,0 +1499,Amulet of holthion,0 +1500,Iban's shadow,2 +1501,Dwarf brew,2 +1502,Iban's ashes,2 +1503,Warrant,5 +1504,Hangover cure,2 +1505,A magic scroll,1 +1506,Gas mask,2 +1507,A small key,1 +1508,A scruffy note,2 +1509,Book,1 +1510,Picture,1 +1511,Logs,4 +1512,Logs,4 +1513,Magic logs,320 +1514,Magic logs,320 +1515,Yew logs,160 +1516,Yew logs,160 +1517,Maple logs,80 +1518,Maple logs,80 +1519,Willow logs,40 +1520,Willow logs,40 +1521,Oak logs,20 +1522,Oak logs,20 +1523,Lockpick,20 +1524,Lockpick,20 +1525,Grimy snake weed,1 +1526,Clean snake weed,5 +1527,Grimy ardrigal,1 +1528,Clean ardrigal,5 +1529,Grimy sito foil,1 +1530,Clean sito foil,5 +1531,Grimy volencia moss,1 +1532,Clean volencia moss,5 +1533,Grimy rogue's purse,1 +1534,Clean rogue's purse,5 +1535,Map part,1 +1536,Map part,1 +1537,Map part,1 +1538,Crandor map,1 +1539,Steel nails,52 +1540,Anti-dragon shield,20 +1541,Anti-dragon shield,20 +1542,Maze key,1 +1543,Key,1 +1544,Key,1 +1545,Key,1 +1546,Key,1 +1547,Key,1 +1548,Key,1 +1549,Stake,8 +1550,Garlic,3 +1551,Garlic,3 +1552,Doogle sardine,10 +1553,Tinderbox,0 +1554,null,1 +1555,Pet kitten,1 +1556,Pet kitten,1 +1557,Pet kitten,1 +1558,Pet kitten,1 +1559,Pet kitten,1 +1560,Pet kitten,1 +1561,Pet cat,1 +1562,Pet cat,1 +1563,Pet cat,1 +1564,Pet cat,1 +1565,Pet cat,1 +1566,Pet cat,1 +1567,Overgrown cat,1 +1568,Overgrown cat,1 +1569,Overgrown cat,1 +1570,Overgrown cat,1 +1571,Overgrown cat,1 +1572,Overgrown cat,1 +1573,Doogle leaves,2 +1574,Tinderbox,0 +1575,Cat training medal,350 +1576,Tinderbox,0 +1577,Pete's candlestick,5 +1578,Pete's candlestick,5 +1579,Thieves' armband,2 +1580,Ice gloves,6 +1581,Blamish snail slime,5 +1582,Blamish oil,10 +1583,Fire feather,2 +1584,Id papers,1 +1585,Oily fishing rod,15 +1586,Miscellaneous key,1 +1587,Miscellaneous key,1 +1588,Grips' key ring,1 +1589,Picture,1 +1590,Dusty key,1 +1591,Jail key,1 +1592,Ring mould,5 +1593,Ring mould,5 +1594,Unholy mould,200 +1595,Amulet mould,5 +1596,Amulet mould,5 +1597,Necklace mould,5 +1598,Necklace mould,5 +1599,Holy mould,5 +1600,Holy mould,5 +1601,Diamond,2000 +1602,Diamond,2000 +1603,Ruby,1000 +1604,Ruby,1000 +1605,Emerald,500 +1606,Emerald,500 +1607,Sapphire,250 +1608,Sapphire,250 +1609,Opal,100 +1610,Opal,100 +1611,Jade,150 +1612,Jade,150 +1613,Red topaz,200 +1614,Red topaz,200 +1615,Dragonstone,10000 +1616,Dragonstone,10000 +1617,Uncut diamond,200 +1618,Uncut diamond,200 +1619,Uncut ruby,100 +1620,Uncut ruby,100 +1621,Uncut emerald,50 +1622,Uncut emerald,50 +1623,Uncut sapphire,25 +1624,Uncut sapphire,25 +1625,Uncut opal,20 +1626,Uncut opal,20 +1627,Uncut jade,30 +1628,Uncut jade,30 +1629,Uncut red topaz,40 +1630,Uncut red topaz,40 +1631,Uncut dragonstone,1000 +1632,Uncut dragonstone,1000 +1633,Crushed gem,1 +1634,Crushed gem,1 +1635,Gold ring,350 +1636,Gold ring,350 +1637,Sapphire ring,900 +1638,Sapphire ring,900 +1639,Emerald ring,1275 +1640,Emerald ring,1275 +1641,Ruby ring,2025 +1642,Ruby ring,2025 +1643,Diamond ring,3525 +1644,Diamond ring,3525 +1645,Dragonstone ring,17625 +1646,Dragonstone ring,17625 +1647,null,1 +1648,null,1 +1649,Sapphire ring,1 +1650,Emerald ring,1 +1651,Ruby ring,1 +1652,Diamond ring,1 +1653,Dragonstone ring,1 +1654,Gold necklace,450 +1655,Gold necklace,450 +1656,Sapphire necklace,1050 +1657,Sapphire necklace,1050 +1658,Emerald necklace,1425 +1659,Emerald necklace,1425 +1660,Ruby necklace,2175 +1661,Ruby necklace,2175 +1662,Diamond necklace,3675 +1663,Diamond necklace,3675 +1664,Dragon necklace,18375 +1665,Dragon necklace,18375 +1666,null,1 +1667,null,1 +1668,Sapphire necklace,1 +1669,Emerald necklace,1 +1670,Ruby necklace,1 +1671,Diamond necklace,1 +1672,Dragon necklace,1 +1673,Gold amulet,350 +1674,Gold amulet,350 +1675,Sapphire amulet,900 +1676,Sapphire amulet,900 +1677,Emerald amulet,1275 +1678,Emerald amulet,1275 +1679,Ruby amulet,2025 +1680,Ruby amulet,2025 +1681,Diamond amulet,3525 +1682,Diamond amulet,3525 +1683,Dragonstone ammy,17625 +1684,Dragonstone ammy,17625 +1685,null,1 +1686,null,1 +1687,Sapphire amulet,1 +1688,Emerald amulet,1 +1689,Ruby amulet,1 +1690,Diamond amulet,1 +1691,Dragonstone ammy,1 +1692,Gold amulet,350 +1693,Gold amulet,350 +1694,Sapphire amulet,900 +1695,Sapphire amulet,900 +1696,Emerald amulet,1275 +1697,Emerald amulet,1275 +1698,Ruby amulet,2025 +1699,Ruby amulet,2025 +1700,Diamond amulet,3525 +1701,Diamond amulet,3525 +1702,Dragonstone ammy,17625 +1703,Dragonstone ammy,17625 +1704,Amulet of glory,17625 +1705,Amulet of glory,17625 +1706,Amulet of glory(1),17625 +1707,Amulet of glory(1),17625 +1708,Amulet of glory(2),17625 +1709,Amulet of glory(2),17625 +1710,Amulet of glory(3),17625 +1711,Amulet of glory(3),17625 +1712,Amulet of glory(4),17625 +1713,Amulet of glory(4),17625 +1714,Unstrung symbol,200 +1715,Unstrung symbol,200 +1716,Unblessed symbol,200 +1717,Unblessed symbol,200 +1718,Holy symbol,300 +1719,Holy symbol,300 +1720,Unstrung emblem,200 +1721,Unstrung emblem,200 +1722,Unpowered symbol,200 +1723,Unpowered symbol,200 +1724,Unholy symbol,200 +1725,Amulet of strength,2025 +1726,Amulet of strength,2025 +1727,Amulet of magic,900 +1728,Amulet of magic,900 +1729,Amulet of defence,1275 +1730,Amulet of defence,1275 +1731,Amulet of power,3525 +1732,Amulet of power,3525 +1733,Needle,1 +1734,Thread,4 +1735,Shears,1 +1736,Shears,1 +1737,Wool,1 +1738,Wool,1 +1739,Cowhide,1 +1740,Cowhide,1 +1741,Leather,1 +1742,Leather,1 +1743,Hard leather,1 +1744,Hard leather,1 +1745,Green d-leather,50 +1746,Green d-leather,50 +1747,Black dragonhide,80 +1748,Black dragonhide,80 +1749,Red dragonhide,60 +1750,Red dragonhide,60 +1751,Blue dragonhide,40 +1752,Blue dragonhide,40 +1753,Green dragonhide,20 +1754,Green dragonhide,20 +1755,Chisel,1 +1756,Chisel,1 +1757,Brown apron,2 +1758,Brown apron,2 +1759,Ball of wool,5 +1760,Ball of wool,5 +1761,Soft clay,2 +1762,Soft clay,2 +1763,Red dye,6 +1764,Red dye,6 +1765,Yellow dye,6 +1766,Yellow dye,6 +1767,Blue dye,6 +1768,Blue dye,6 +1769,Orange dye,6 +1770,Orange dye,6 +1771,Green dye,6 +1772,Green dye,6 +1773,Purple dye,6 +1774,Purple dye,6 +1775,Molten glass,3 +1776,Molten glass,3 +1777,Bow string,10 +1778,Bow string,10 +1779,Flax,5 +1780,Flax,5 +1781,Soda ash,2 +1782,Soda ash,2 +1783,Bucket of sand,2 +1784,Bucket of sand,2 +1785,Glassblowing pipe,2 +1786,Glassblowing pipe,2 +1787,Unfired pot,1 +1788,Unfired pot,1 +1789,Unfired pie dish,3 +1790,Unfired pie dish,3 +1791,Unfired bowl,2 +1792,Unfired bowl,2 +1793,Woad leaf,1 +1794,Bronze wire,20 +1795,Bronze wire,20 +1796,Silver necklace,1 +1797,Silver necklace,1 +1798,Silver cup,1 +1799,Silver cup,1 +1800,Silver bottle,1 +1801,Silver bottle,1 +1802,Silver book,1 +1803,Silver book,1 +1804,Silver needle,1 +1805,Silver needle,1 +1806,Silver pot,1 +1807,Silver pot,1 +1808,Criminal's thread,1 +1809,Criminal's thread,1 +1810,Criminal's thread,1 +1811,Flypaper,1 +1812,Pungent pot,1 +1813,Criminal's dagger,1 +1814,Criminal's dagger,1 +1815,Killer's print,1 +1816,Anna's print,1 +1817,Bob's print,1 +1818,Carol's print,1 +1819,David's print,1 +1820,Elizabeth's print,1 +1821,Frank's print,1 +1822,Unknown print,1 +1823,Waterskin(4),30 +1824,Waterskin(4),30 +1825,Waterskin(3),27 +1826,Waterskin(3),27 +1827,Waterskin(2),24 +1828,Waterskin(2),24 +1829,Waterskin(1),18 +1830,Waterskin(1),18 +1831,Waterskin(0),15 +1832,Waterskin(0),15 +1833,Desert shirt,40 +1834,Desert shirt,40 +1835,Desert robe,40 +1836,Desert robe,40 +1837,Desert boots,20 +1838,Desert boots,20 +1839,Metal key,1 +1840,Cell door key,1 +1841,Barrel,1 +1842,Ana in a barrel,1 +1843,Wrought iron key,1 +1844,Slave shirt,40 +1845,Slave robe,40 +1846,Slave boots,1 +1847,Scrumpled paper,10 +1848,Shantay disclaimer,1 +1849,Prototype dart,2 +1850,Technical plans,1 +1851,Tenti pineapple,1 +1852,Bedabin key,1 +1853,Prototype dart tip,1 +1854,Shantay pass,5 +1855,Rock,1 +1856,Guide book,1 +1857,Totem,10 +1858,Address label,10 +1859,Raw ugthanki meat,2 +1860,Raw ugthanki meat,2 +1861,Ugthanki meat,5 +1862,Ugthanki meat,5 +1863,Pitta dough,4 +1864,Pitta dough,4 +1865,Pitta bread,10 +1866,Pitta bread,10 +1867,Burnt pitta bread,1 +1868,Burnt pitta bread,1 +1869,Chopped tomato,3 +1870,Chopped tomato,3 +1871,Chopped onion,3 +1872,Chopped onion,3 +1873,Chopped ugthanki,5 +1874,Chopped ugthanki,5 +1875,Onion & tomato,5 +1876,Onion & tomato,5 +1877,Ugthanki & onion,7 +1878,Ugthanki & onion,7 +1879,Ugthanki & tomato,7 +1880,Ugthanki & tomato,7 +1881,Kebab mix,9 +1882,Kebab mix,9 +1883,Ugthanki kebab,20 +1884,Ugthanki kebab,20 +1885,Ugthanki kebab,20 +1886,Ugthanki kebab,20 +1887,Cake tin,10 +1888,Cake tin,10 +1889,Uncooked cake,20 +1890,Uncooked cake,20 +1891,Cake,50 +1892,Cake,50 +1893,2/3 cake,30 +1894,2/3 cake,30 +1895,Slice of cake,10 +1896,Slice of cake,10 +1897,Chocolate cake,70 +1898,Chocolate cake,70 +1899,2/3 chocolate cake,50 +1900,2/3 chocolate cake,50 +1901,Chocolate slice,30 +1902,Chocolate slice,30 +1903,Burnt cake,1 +1904,Burnt cake,1 +1905,Asgarnian ale,2 +1906,Asgarnian ale,2 +1907,Wizard's mind bomb,2 +1908,Wizard's mind bomb,2 +1909,Greenman's ale,2 +1910,Greenman's ale,2 +1911,Dragon bitter,2 +1912,Dragon bitter,2 +1913,Dwarven stout,2 +1914,Dwarven stout,2 +1915,Grog,3 +1916,Grog,3 +1917,Beer,2 +1918,Beer,2 +1919,Beer glass,2 +1920,Beer glass,2 +1921,Bowl of water,4 +1922,Bowl of water,4 +1923,Bowl,4 +1924,Bowl,4 +1925,Bucket,2 +1926,Bucket,2 +1927,Bucket of milk,12 +1928,Bucket of milk,12 +1929,Bucket of water,6 +1930,Bucket of water,6 +1931,Empty pot,1 +1932,Empty pot,1 +1933,Pot of flour,14 +1934,Pot of flour,14 +1935,Jug,1 +1936,Jug,1 +1937,Jug of water,1 +1938,Jug of water,1 +1939,Swamp tar,1 +1940,Raw swamp paste,1 +1941,Swamp paste,31 +1942,Potato,16 +1943,Potato,16 +1944,Egg,4 +1945,Egg,4 +1946,Flour,2 +1947,Grain,2 +1948,Grain,2 +1949,Chef's hat,2 +1950,Chef's hat,2 +1951,Redberries,3 +1952,Redberries,3 +1953,Pastry dough,1 +1954,Pastry dough,1 +1955,Cooking apple,36 +1956,Cooking apple,36 +1957,Onion,12 +1958,Onion,12 +1959,Pumpkin,30 +1960,Pumpkin,30 +1961,Easter egg,10 +1962,Easter egg,10 +1963,Banana,2 +1964,Banana,2 +1965,Cabbage,1 +1966,Cabbage,1 +1967,Cabbage,1 +1968,Cabbage,1 +1969,Spinach roll,1 +1970,Tinderbox,0 +1971,Kebab,3 +1972,Kebab,3 +1973,Chocolate bar,20 +1974,Chocolate bar,20 +1975,Chocolate dust,20 +1976,Chocolate dust,20 +1977,Chocolatey milk,2 +1978,Cup of tea,10 +1979,Cup of tea,10 +1980,Empty cup,2 +1981,Empty cup,2 +1982,Tomato,14 +1983,Tomato,14 +1984,Rotten apple,1 +1985,Cheese,8 +1986,Cheese,8 +1987,Grapes,1 +1988,Grapes,1 +1989,Half full wine jug,1 +1990,Half full wine jug,1 +1991,Jug of bad wine,1 +1992,Jug of bad wine,1 +1993,Jug of wine,128 +1994,Jug of wine,128 +1995,Unfermented wine,10 +1996,Unfermented wine,10 +1997,Incomplete stew,4 +1998,Incomplete stew,4 +1999,Incomplete stew,4 +2000,Incomplete stew,4 +2001,Uncooked stew,10 +2002,Uncooked stew,10 +2003,Stew,100 +2004,Stew,100 +2005,Burnt stew,1 +2006,Burnt stew,1 +2007,Spice,230 +2008,Spice,230 +2009,Uncooked curry,10 +2010,Uncooked curry,10 +2011,Curry,20 +2012,Curry,20 +2013,Burnt curry,1 +2014,Burnt curry,1 +2015,Vodka,5 +2016,Vodka,5 +2017,Whisky,5 +2018,Whisky,5 +2019,Gin,5 +2020,Gin,5 +2021,Brandy,5 +2022,Brandy,5 +2023,Cocktail guide,2 +2024,Cocktail guide,2 +2025,Cocktail shaker,2 +2026,Cocktail glass,1 +2027,Cocktail glass,1 +2028,Premade blurb' sp.,30 +2029,Premade blurb' sp.,30 +2030,Premade choc s'dy,30 +2031,Premade choc s'dy,30 +2032,Premade dr' dragon,30 +2033,Premade dr' dragon,30 +2034,Premade fr' blast,30 +2035,Premade fr' blast,30 +2036,Premade p' punch,30 +2037,Premade p' punch,30 +2038,Premade sgg,30 +2039,Premade sgg,30 +2040,Premade wiz blz'd,30 +2041,Premade wiz blz'd,30 +2042,Picture,2 +2043,Picture,2 +2044,Picture,2 +2045,Picture,2 +2046,Picture,2 +2047,Picture,2 +2048,Pineapple punch,30 +2049,Pineapple punch,30 +2050,Picture,2 +2051,Picture,2 +2052,Picture,2 +2053,Picture,2 +2054,Wizard blizzard,30 +2055,Wizard blizzard,30 +2056,Picture,2 +2057,Picture,2 +2058,Picture,2 +2059,Picture,2 +2060,Picture,2 +2061,Picture,2 +2062,Picture,2 +2063,Picture,2 +2064,Blurberry special,30 +2065,Blurberry special,30 +2066,Picture,2 +2067,Picture,2 +2068,Picture,2 +2069,Picture,2 +2070,Picture,2 +2071,Picture,2 +2072,Picture,2 +2073,Picture,2 +2074,Choc saturday,30 +2075,Choc saturday,30 +2076,Picture,2 +2077,Picture,2 +2078,Picture,2 +2079,Picture,2 +2080,Short green guy,30 +2081,Short green guy,30 +2082,Picture,2 +2083,Picture,2 +2084,Fruit blast,30 +2085,Fruit blast,30 +2086,Picture,2 +2087,Picture,2 +2088,Picture,2 +2089,Picture,2 +2090,Picture,2 +2091,Picture,2 +2092,Drunk dragon,30 +2093,Drunk dragon,30 +2094,Picture,2 +2095,Picture,2 +2096,Picture,2 +2097,Picture,2 +2098,Picture,2 +2099,Picture,2 +2100,Picture,2 +2101,Picture,2 +2102,Lemon,2 +2103,Lemon,2 +2104,Lemon chunks,2 +2105,Lemon chunks,2 +2106,Lemon slices,2 +2107,Lemon slices,2 +2108,Orange,70 +2109,Orange,70 +2110,Orange chunks,2 +2111,Orange chunks,2 +2112,Orange slices,2 +2113,Orange slices,2 +2114,Pineapple,2 +2115,Pineapple,2 +2116,Pineapple chunks,1 +2117,Pineapple chunks,1 +2118,Pineapple ring,1 +2119,Pineapple ring,1 +2120,Lime,2 +2121,Lime,2 +2122,Lime chunks,1 +2123,Lime chunks,1 +2124,Lime slices,2 +2125,Lime slices,2 +2126,Dwellberries,4 +2127,Dwellberries,4 +2128,Equa leaves,2 +2129,Equa leaves,2 +2130,Pot of cream,19 +2131,Pot of cream,19 +2132,Raw beef,8 +2133,Raw beef,8 +2134,Raw rat meat,8 +2135,Raw rat meat,8 +2136,Raw bear meat,8 +2137,Raw bear meat,8 +2138,Raw chicken,9 +2139,Raw chicken,9 +2140,Cooked chicken,4 +2141,Cooked chicken,4 +2142,Cooked meat,4 +2143,Cooked meat,4 +2144,Burnt chicken,1 +2145,Burnt chicken,1 +2146,Burnt meat,1 +2147,Burnt meat,1 +2148,Raw lava eel,150 +2149,Lava eel,150 +2150,Swamp toad,2 +2151,Swamp toad,2 +2152,Toad's legs,2 +2153,Toad's legs,2 +2154,Picture,2 +2155,Picture,2 +2156,Spicy toad's legs,2 +2157,Spicy toad's legs,2 +2158,Seasoned legs,2 +2159,Seasoned legs,2 +2160,Spicy worm,2 +2161,Spicy worm,2 +2162,King worm,2 +2163,King worm,2 +2164,Batta tin,10 +2165,Crunchy tray,10 +2166,Gnomebowl mould,10 +2167,Gianne's cook book,2 +2168,Gianne's cook book,2 +2169,Gnome spice,2 +2170,Gnome spice,2 +2171,Gianne dough,2 +2172,Gianne dough,2 +2173,Picture,2 +2174,Picture,2 +2175,Burnt gnomebowl,1 +2176,Burnt gnomebowl,1 +2177,Half baked bowl,2 +2178,Raw gnomebowl,2 +2179,Picture,1 +2180,Picture,1 +2181,Picture,1 +2182,Picture,1 +2183,Picture,1 +2184,Picture,1 +2185,Chocolate bomb,2 +2186,Chocolate bomb,2 +2187,Tangled toads' legs,2 +2188,Tangled toads' legs,2 +2189,Picture,1 +2190,Picture,1 +2191,Worm hole,2 +2192,Worm hole,2 +2193,Picture,1 +2194,Picture,1 +2195,Veg ball,2 +2196,Veg ball,2 +2197,Odd crunchies,2 +2198,Odd crunchies,2 +2199,Burnt crunchies,1 +2200,Burnt crunchies,1 +2201,Half baked crunchy,2 +2202,Raw crunchies,2 +2203,Picture,1 +2204,Picture,1 +2205,Worm crunchies,2 +2206,Worm crunchies,2 +2207,Picture,1 +2208,Picture,1 +2209,Chocchip crunchies,2 +2210,Chocchip crunchies,2 +2211,Picture,1 +2212,Picture,1 +2213,Spicy crunchies,2 +2214,Spicy crunchies,2 +2215,Picture,1 +2216,Picture,1 +2217,Toad crunchies,2 +2218,Toad crunchies,2 +2219,Premade w'm batta,195 +2220,Premade w'm batta,195 +2221,Premade t'd batta,195 +2222,Premade t'd batta,195 +2223,Premade c+t batta,195 +2224,Premade c+t batta,195 +2225,Premade fr't batta,195 +2226,Premade fr't batta,195 +2227,Premade veg batta,195 +2228,Premade veg batta,195 +2229,Premade choc bomb,450 +2230,Premade choc bomb,450 +2231,Premade ttl,450 +2232,Premade ttl,450 +2233,Premade worm hole,270 +2234,Premade worm hole,270 +2235,Premade veg ball,270 +2236,Premade veg ball,270 +2237,Premade w'm crun',80 +2238,Premade w'm crun',80 +2239,Premade ch' crunch,70 +2240,Premade ch' crunch,70 +2241,Premade s'y crunch,70 +2242,Premade s'y crunch,70 +2243,Premade t'd crunch,80 +2244,Premade t'd crunch,80 +2245,Picture,2 +2246,Picture,2 +2247,Burnt batta,1 +2248,Burnt batta,1 +2249,Half baked batta,2 +2250,Raw batta,2 +2251,Picture,1 +2252,Picture,1 +2253,Worm batta,1 +2254,Worm batta,1 +2255,Toad batta,2 +2256,Toad batta,2 +2257,Picture,1 +2258,Picture,1 +2259,Cheese+tom batta,2 +2260,Cheese+tom batta,2 +2261,Unfinished batta,1 +2262,Unfinished batta,1 +2263,Unfinished batta,1 +2264,Unfinished batta,1 +2265,Unfinished batta,1 +2266,Unfinished batta,1 +2267,Unfinished batta,1 +2268,Unfinished batta,1 +2269,Unfinished batta,1 +2270,Unfinished batta,1 +2271,Unfinished batta,1 +2272,Unfinished batta,1 +2273,Unfinished batta,1 +2274,Unfinished batta,1 +2275,Picture,1 +2276,Picture,1 +2277,Fruit batta,2 +2278,Fruit batta,2 +2279,Picture,1 +2280,Picture,1 +2281,Vegetable batta,2 +2282,Vegetable batta,2 +2283,Pizza base,4 +2284,Pizza base,4 +2285,Incomplete pizza,10 +2286,Incomplete pizza,10 +2287,Uncooked pizza,25 +2288,Uncooked pizza,25 +2289,Plain pizza,200 +2290,Plain pizza,200 +2291,1/2 plain pizza,20 +2292,1/2 plain pizza,20 +2293,Meat pizza,50 +2294,Meat pizza,50 +2295,1/2 meat pizza,25 +2296,1/2 meat pizza,25 +2297,Anchovy pizza,60 +2298,Anchovy pizza,60 +2299,1/2 anchovy pizza,30 +2300,1/2 anchovy pizza,30 +2301,Pineapple pizza,100 +2302,Pineapple pizza,100 +2303,1/2 p'apple pizza,50 +2304,1/2 p'apple pizza,50 +2305,Burnt pizza,1 +2306,Burnt pizza,1 +2307,Bread dough,4 +2308,Bread dough,4 +2309,Bread,12 +2310,Bread,12 +2311,Burnt bread,1 +2312,Burnt bread,1 +2313,Pie dish,3 +2314,Pie dish,3 +2315,Pie shell,4 +2316,Pie shell,4 +2317,Uncooked apple pie,16 +2318,Uncooked apple pie,16 +2319,Uncooked meat pie,8 +2320,Uncooked meat pie,8 +2321,Uncooked berry pie,6 +2322,Uncooked berry pie,6 +2323,Apple pie,140 +2324,Apple pie,140 +2325,Redberry pie,150 +2326,Redberry pie,150 +2327,Meat pie,160 +2328,Meat pie,160 +2329,Burnt pie,1 +2330,Burnt pie,1 +2331,Half a meat pie,8 +2332,Half a meat pie,8 +2333,Half a redberry pie,6 +2334,Half a redberry pie,6 +2335,Half an apple pie,15 +2336,Half an apple pie,15 +2337,Raw oomlie,10 +2338,Raw oomlie,10 +2339,Palm leaf,5 +2340,Palm leaf,5 +2341,Wrapped oomlie,16 +2342,Wrapped oomlie,16 +2343,Cooked oomlie wrap,35 +2344,Cooked oomlie wrap,35 +2345,Burnt oomlie wrap,1 +2346,Burnt oomlie wrap,1 +2347,Hammer,1 +2348,Hammer,1 +2349,Bronze bar,8 +2350,Bronze bar,8 +2351,Iron bar,28 +2352,Iron bar,28 +2353,Steel bar,100 +2354,Steel bar,100 +2355,Silver bar,150 +2356,Silver bar,150 +2357,Gold bar,300 +2358,Gold bar,300 +2359,Mithril bar,300 +2360,Mithril bar,300 +2361,Adamantite bar,640 +2362,Adamantite bar,640 +2363,Runite bar,5000 +2364,Runite bar,5000 +2365,'perfect' gold bar,300 +2366,Shield left half,110000 +2367,Shield left half,110000 +2368,Shield right half,750000 +2369,Shield right half,750000 +2370,Steel studs,150 +2371,Steel studs,150 +2372,Ogre relic,1 +2373,Relic part 1,1 +2374,Relic part 2,1 +2375,Relic part 3,1 +2376,Skavid map,1 +2377,Ogre tooth,1 +2378,Toban's key,1 +2379,Rock cake,1 +2380,Crystal,1 +2381,Crystal,1 +2382,Crystal,1 +2383,Crystal,1 +2384,Fingernails,1 +2385,Old robe,1 +2386,Unusual armour,1 +2387,Damaged dagger,1 +2388,Tattered eye patch,1 +2389,Vial,1 +2390,Vial,1 +2391,Ground bat bones,20 +2392,Ground bat bones,20 +2393,Toban's gold,300 +2394,Potion,120 +2395,Magic ogre potion,120 +2396,Spell scroll,5 +2397,Shaman robe,40 +2398,Cave nightshade,30 +2399,Silverlight key,100 +2400,Silverlight key,100 +2401,Silverlight key,100 +2402,Silverlight,50 +2403,Hazeel scroll,1 +2404,Chest key,1 +2405,Carnillean armour,65 +2406,Hazeel's mark,1 +2407,Ball,1 +2408,Diary,1 +2409,Door key,1 +2410,Magnet,3 +2411,Key,1 +2412,Saradomin cape,100 +2413,Guthix cape,100 +2414,Zamorak cape,100 +2415,Saradomin staff,80000 +2416,Guthix staff,80000 +2417,Zamorak staff,80000 +2418,Bronze key,1 +2419,Wig,1 +2420,Picture,1 +2421,Wig,1 +2422,Blue partyhat,1 +2423,Key print,1 +2424,Paste,5 +2425,Picture,1 +2426,Burnt oomlie,1 +2427,Burnt oomlie,1 +2428,Attack potion(4),700 +2429,Attack potion(4),700 +2430,Restore potion(4),110 +2431,Restore potion(4),110 +2432,Defence potion(4),1100 +2433,Defence potion(4),1100 +2434,Prayer potion(4),190 +2435,Prayer potion(4),190 +2436,Super attack(4),225 +2437,Super attack(4),225 +2438,Fishing potion(4),250 +2439,Fishing potion(4),250 +2440,Super strength(4),275 +2441,Super strength(4),275 +2442,Super defence(4),330 +2443,Super defence(4),330 +2444,Ranging potion(4),360 +2445,Ranging potion(4),360 +2446,Antipoison(4),360 +2447,Antipoison(4),360 +2448,Super antipoison(4),360 +2449,Super antipoison(4),360 +2450,Zamorak brew(4),200 +2451,Zamorak brew(4),200 +2452,Antifire potion(4),330 +2453,Antifire potion(4),330 +2454,Antifire potion(3),264 +2455,Antifire potion(3),264 +2456,Antifire potion(2),198 +2457,Antifire potion(2),198 +2458,Antifire potion(1),132 +2459,Antifire potion(1),132 +2460,Flowers,100 +2461,Flowers,100 +2462,Flowers,100 +2463,Flowers,100 +2464,Flowers,100 +2465,Flowers,100 +2466,Flowers,100 +2467,Flowers,100 +2468,Flowers,100 +2469,Flowers,100 +2470,Flowers,100 +2471,Flowers,100 +2472,Flowers,100 +2473,Flowers,100 +2474,Flowers,100 +2475,Flowers,100 +2476,Flowers,100 +2477,Flowers,100 +2478,Tinderbox,0 +2479,Tinderbox,0 +2480,Picture,1 +2481,Clean lantadyme,68 +2482,Clean lantadyme,68 +2483,Lantadyme potion(unf),68 +2484,Lantadyme potion(unf),68 +2485,Grimy lantadyme,1 +2486,Grimy lantadyme,1 +2487,Blue d'hide vamb,3000 +2488,Blue d'hide vamb,3000 +2489,Red d'hide vamb,3600 +2490,Red d'hide vamb,3600 +2491,Black d'hide vamb,4320 +2492,Black d'hide vamb,4320 +2493,Blue d'hide chaps,4320 +2494,Blue d'hide chaps,4320 +2495,Red d'hide chaps,5180 +2496,Red d'hide chaps,5180 +2497,Black d'hide chaps,6220 +2498,Black d'hide chaps,6220 +2499,Blue d'hide body,9360 +2500,Blue d'hide body,9360 +2501,Red d'hide body,11230 +2502,Red d'hide body,11230 +2503,Black d'hide body,13480 +2504,Black d'hide body,13480 +2505,Blue d-leather,70 +2506,Blue d-leather,70 +2507,Red dragon leather,90 +2508,Red dragon leather,90 +2509,Black d-leather,110 +2510,Black d-leather,110 +2511,Logs,4 +2512,Picture,1 +2513,Dragon chainbody,6 +2514,Raw shrimps,5 +2515,Raw shrimps,5 +2516,Pot of flour,10 +2517,Pot of flour,10 +2518,Rotten tomato,1 +2519,Rotten tomato,1 +2520,Toy horsey,150 +2521,Toy horsey,150 +2522,Toy horsey,150 +2523,Toy horsey,150 +2524,Toy horsey,150 +2525,Toy horsey,150 +2526,Toy horsey,150 +2527,Toy horsey,150 +2528,Lamp,1 +2529,Orb of light,1 +2530,Bones,1 +2531,Bones,1 +2532,Iron fire arrows,3 +2533,Iron fire arrows,10 +2534,Steel fire arrows,3 +2535,Steel fire arrows,10 +2536,Mithril fire arrows,3 +2537,Mithril fire arrows,10 +2538,Adamant fire arrows,3 +2539,Adamant fire arrows,10 +2540,Rune fire arrows,3 +2541,Rune fire arrows,10 +2542,null,1 +2543,null,1 +2544,null,1 +2545,null,1 +2546,null,1 +2547,null,1 +2548,null,1 +2549,null,1 +2550,Ring of recoil,900 +2551,Ring of recoil,900 +2552,Ring of duelling(8),1275 +2553,Ring of duelling(8),1275 +2554,Ring of duelling(7),1275 +2555,Ring of duelling(7),1275 +2556,Ring of duelling(6),1275 +2557,Ring of duelling(6),1275 +2558,Ring of duelling(5),1275 +2559,Ring of duelling(5),1275 +2560,Ring of duelling(4),1275 +2561,Ring of duelling(4),1275 +2562,Ring of duelling(3),1275 +2563,Ring of duelling(3),1275 +2564,Ring of duelling(2),1275 +2565,Ring of duelling(2),1275 +2566,Ring of duelling(1),1275 +2567,Ring of duelling(1),1275 +2568,Ring of forging,2025 +2569,Ring of forging,2025 +2570,Ring of life,3525 +2571,Ring of life,3525 +2572,Ring of wealth,17625 +2573,Ring of wealth,17625 +2574,Sextant,50 +2575,Watch,100 +2576,Chart,2 +2577,Ranger boots,200 +2578,Ranger boots,200 +2579,Wizard boots,200 +2580,Wizard boots,200 +2581,Robin hood hat,450 +2582,Robin hood hat,450 +2583,Black platebody (t),3840 +2584,Black platebody (t),3840 +2585,Black platelegs (t),1920 +2586,Black platelegs (t),1920 +2587,Black full helm(t),1056 +2588,Black full helm(t),1056 +2589,Black kiteshield (t),1632 +2590,Black kiteshield (t),1632 +2591,Black platebody (g),3840 +2592,Black platebody (g),3840 +2593,Black platelegs (g),1920 +2594,Black platelegs (g),1920 +2595,Black full helm(g),1056 +2596,Black full helm(g),1056 +2597,Black kiteshield (g),1632 +2598,Black kiteshield (g),1632 +2599,Adam platebody (t),12800 +2600,Adam platebody (t),12800 +2601,Adam platelegs (t),6400 +2602,Adam platelegs (t),6400 +2603,Adam kiteshield (t),5440 +2604,Adam kiteshield (t),5440 +2605,Adam full helm(t),3520 +2606,Adam full helm(t),3520 +2607,Adam platebody (g),12800 +2608,Adam platebody (g),12800 +2609,Adam platelegs (g),6400 +2610,Adam platelegs (g),6400 +2611,Adam kiteshield (g),5440 +2612,Adam kiteshield (g),5440 +2613,Adam full helm(g),3520 +2614,Adam full helm(g),3520 +2615,Rune platebody (g),65000 +2616,Rune platebody (g),65000 +2617,Rune platelegs (g),64000 +2618,Rune platelegs (g),64000 +2619,Rune full helm(g),35200 +2620,Rune full helm(g),35200 +2621,Rune kiteshield (g),54400 +2622,Rune kiteshield (g),54400 +2623,Rune platebody (t),65000 +2624,Rune platebody (t),65000 +2625,Rune platelegs (t),64000 +2626,Rune platelegs (t),64000 +2627,Rune full helm (t),35200 +2628,Rune full helm (t),35200 +2629,Rune kiteshield (t),54400 +2630,Rune kiteshield (t),54400 +2631,Highwayman mask,40 +2632,Highwayman mask,40 +2633,Blue beret,80 +2634,Blue beret,80 +2635,Black beret,80 +2636,Black beret,80 +2637,White beret,80 +2638,White beret,80 +2639,Tan cavalier,200 +2640,Tan cavalier,200 +2641,Dark cavalier,200 +2642,Dark cavalier,200 +2643,Black cavalier,200 +2644,Black cavalier,200 +2645,Red headband,40 +2646,Red headband,40 +2647,Black headband,40 +2648,Black headband,40 +2649,Brown headband,40 +2650,Brown headband,40 +2651,Pirate's hat,180 +2652,Pirate's hat,180 +2653,Zamorak platebody,65000 +2654,Zamorak platebody,65000 +2655,Zamorak platelegs,64000 +2656,Zamorak platelegs,64000 +2657,Zamorak full helm,35200 +2658,Zamorak full helm,35200 +2659,Zamorak kiteshield,54400 +2660,Zamorak kiteshield,54400 +2661,Saradomin platebody,65000 +2662,Saradomin platebody,65000 +2663,Saradomin platelegs,64000 +2664,Saradomin platelegs,64000 +2665,Saradomin full helm,35200 +2666,Saradomin full helm,35200 +2667,Saradomin kiteshield,54400 +2668,Saradomin kiteshield,54400 +2669,Guthix platebody,65000 +2670,Guthix platebody,65000 +2671,Guthix platelegs,64000 +2672,Guthix platelegs,64000 +2673,Guthix full helm,35200 +2674,Guthix full helm,35200 +2675,Guthix kiteshield,54400 +2676,Guthix kiteshield,54400 +2677,Clue scroll,1 +2678,Clue scroll,1 +2679,Clue scroll,1 +2680,Clue scroll,1 +2681,Clue scroll,1 +2682,Clue scroll,1 +2683,Clue scroll,1 +2684,Clue scroll,1 +2685,Clue scroll,1 +2686,Clue scroll,1 +2687,Clue scroll,1 +2688,Clue scroll,1 +2689,Clue scroll,1 +2690,Clue scroll,1 +2691,Clue scroll,1 +2692,Clue scroll,1 +2693,Clue scroll,1 +2694,Clue scroll,1 +2695,Clue scroll,1 +2696,Clue scroll,1 +2697,Clue scroll,1 +2698,Clue scroll,1 +2699,Clue scroll,1 +2700,Clue scroll,1 +2701,Clue scroll,1 +2702,Clue scroll,1 +2703,Clue scroll,1 +2704,Clue scroll,1 +2705,Clue scroll,1 +2706,Clue scroll,1 +2707,Clue scroll,1 +2708,Clue scroll,1 +2709,Clue scroll,1 +2710,Clue scroll,1 +2711,Clue scroll,1 +2712,Clue scroll,1 +2713,Clue scroll,1 +2714,Casket,50 +2715,Casket,50 +2716,Clue scroll,1 +2717,Casket,50 +2718,Casket,50 +2719,Clue scroll,1 +2720,Casket,50 +2721,Casket,50 +2722,Clue scroll,1 +2723,Clue scroll,1 +2724,Casket,50 +2725,Clue scroll,1 +2726,Casket,50 +2727,Clue scroll,1 +2728,Casket,50 +2729,Clue scroll,1 +2730,Casket,50 +2731,Clue scroll,1 +2732,Casket,50 +2733,Clue scroll,1 +2734,Casket,50 +2735,Clue scroll,1 +2736,Casket,50 +2737,Clue scroll,1 +2738,Casket,50 +2739,Clue scroll,1 +2740,Casket,50 +2741,Clue scroll,1 +2742,Casket,50 +2743,Clue scroll,1 +2744,Casket,50 +2745,Clue scroll,1 +2746,Casket,50 +2747,Clue scroll,1 +2748,Casket,50 +2749,Sliding piece,1 +2750,Sliding piece,1 +2751,Sliding piece,1 +2752,Sliding piece,1 +2753,Sliding piece,1 +2754,Sliding piece,1 +2755,Sliding piece,1 +2756,Sliding piece,1 +2757,Sliding piece,1 +2758,Sliding piece,1 +2759,Sliding piece,1 +2760,Sliding piece,1 +2761,Sliding piece,1 +2762,Sliding piece,1 +2763,Sliding piece,1 +2764,Sliding piece,1 +2765,Sliding piece,1 +2766,Sliding piece,1 +2767,Sliding piece,1 +2768,Sliding piece,1 +2769,Sliding piece,1 +2770,Sliding piece,1 +2771,Sliding piece,1 +2772,Sliding piece,1 +2773,Clue scroll,1 +2774,Clue scroll,1 +2775,Casket,50 +2776,Clue scroll,1 +2777,Casket,50 +2778,Clue scroll,1 +2779,Casket,50 +2780,Clue scroll,1 +2781,Casket,50 +2782,Clue scroll,1 +2783,Clue scroll,1 +2784,Casket,50 +2785,Clue scroll,1 +2786,Clue scroll,1 +2787,Casket,50 +2788,Clue scroll,1 +2789,Casket,50 +2790,Clue scroll,1 +2791,Casket,50 +2792,Clue scroll,1 +2793,Clue scroll,1 +2794,Clue scroll,1 +2795,Puzzle box,100 +2796,Clue scroll,1 +2797,Clue scroll,1 +2798,Puzzle box,100 +2799,Clue scroll,1 +2800,Puzzle box,100 +2801,Clue scroll,1 +2802,Casket,50 +2803,Clue scroll,1 +2804,Casket,50 +2805,Clue scroll,1 +2806,Casket,50 +2807,Clue scroll,1 +2808,Casket,50 +2809,Clue scroll,1 +2810,Casket,50 +2811,Clue scroll,1 +2812,Casket,50 +2813,Clue scroll,1 +2814,Casket,50 +2815,Clue scroll,1 +2816,Casket,50 +2817,Clue scroll,1 +2818,Casket,50 +2819,Clue scroll,1 +2820,Casket,50 +2821,Clue scroll,1 +2822,Casket,50 +2823,Clue scroll,1 +2824,Casket,50 +2825,Clue scroll,1 +2826,Casket,50 +2827,Clue scroll,1 +2828,Casket,50 +2829,Clue scroll,1 +2830,Casket,50 +2831,Clue scroll,1 +2832,Key,1 +2833,Clue scroll,1 +2834,Key,1 +2835,Clue scroll,1 +2836,Key,1 +2837,Clue scroll,1 +2838,Key,1 +2839,Clue scroll,1 +2840,Key,1 +2841,Clue scroll,1 +2842,Challenge scroll,1 +2843,Clue scroll,1 +2844,Challenge scroll,1 +2845,Clue scroll,1 +2846,Challenge scroll,1 +2847,Clue scroll,1 +2848,Clue scroll,1 +2849,Clue scroll,1 +2850,Challenge scroll,1 +2851,Clue scroll,1 +2852,Challenge scroll,1 +2853,Clue scroll,1 +2854,Challenge scroll,1 +2855,Clue scroll,1 +2856,Clue scroll,1 +2857,Clue scroll,1 +2858,Clue scroll,1 +2859,Wolf bones,1 +2860,Wolf bones,1 +2861,Wolfbone arrowtips,3 +2862,Achey tree logs,4 +2863,Achey tree logs,4 +2864,Ogre arrow shaft,1 +2865,Flighted ogre arrow,1 +2866,Ogre arrow,25 +2867,null,1 +2868,null,1 +2869,null,1 +2870,null,1 +2871,Ogre bellows,1 +2872,Ogre bellows (3),1 +2873,Ogre bellows (2),1 +2874,Ogre bellows (1),1 +2875,Bloated toad,1 +2876,Raw chompy,85 +2877,Raw chompy,85 +2878,Cooked chompy,130 +2879,Cooked chompy,130 +2880,Ruined chompy,1 +2881,Ruined chompy,1 +2882,Seasoned chompy,10 +2883,Ogre bow,500 +2884,null,1 +2885,null,1 +2886,Battered book,10 +2887,Battered key,1 +2888,A stone bowl,1 +2889,A stone bowl,1 +2890,Elemental shield,20 +2891,Elemental shield,20 +2892,Elemental ore,5 +2893,Elemental metal,8 +2894,Boots,650 +2895,Boots,650 +2896,Robe top,650 +2897,Robe top,650 +2898,Robe bottoms,650 +2899,Robe bottoms,650 +2900,Hat,650 +2901,Hat,650 +2902,Gloves,650 +2903,Gloves,650 +2904,Boots,650 +2905,Boots,650 +2906,Robe top,650 +2907,Robe top,650 +2908,Robe bottoms,650 +2909,Robe bottoms,650 +2910,Hat,650 +2911,Hat,650 +2912,Gloves,650 +2913,Gloves,650 +2914,Boots,650 +2915,Boots,650 +2916,Robe top,650 +2917,Robe top,650 +2918,Robe bottoms,650 +2919,Robe bottoms,650 +2920,Hat,650 +2921,Hat,650 +2922,Gloves,650 +2923,Gloves,650 +2924,Boots,650 +2925,Boots,650 +2926,Robe top,650 +2927,Robe top,650 +2928,Robe bottoms,650 +2929,Robe bottoms,650 +2930,Hat,650 +2931,Hat,650 +2932,Gloves,650 +2933,Gloves,650 +2934,Boots,650 +2935,Boots,650 +2936,Robe top,650 +2937,Robe top,650 +2938,Robe bottoms,650 +2939,Robe bottoms,650 +2940,Hat,650 +2941,Hat,650 +2942,Gloves,650 +2943,Gloves,650 +2944,Golden key,300 +2945,Iron key,2 +2946,Golden tinderbox,300 +2947,Golden candle,300 +2948,Golden pot,300 +2949,Golden hammer,300 +2950,Golden feather,300 +2951,Golden needle,300 +2952,Wolfbane,300 +2953,Bucket of water,6 +2954,Bucket of water,6 +2955,Moonlight mead,5 +2956,Moonlight mead,5 +2957,Druid pouch,5 +2958,Druid pouch,5 +2959,Rotten food,1 +2960,Rotten food,1 +2961,Silver sickle,175 +2962,Silver sickle,175 +2963,Silver sickle(b),250 +2964,Washing bowl,4 +2965,Picture,0 +2966,Mirror,1 +2967,Journal,1 +2968,Druidic spell,1 +2969,A used spell,1 +2970,Mort myre fungus,1 +2971,Mort myre fungus,1 +2972,Mort myre stem,1 +2973,Mort myre stem,1 +2974,Mort myre pear,1 +2975,Mort myre pear,1 +2976,Sickle mould,10 +2977,Sickle mould,10 +2978,Chompy bird hat,1 +2979,Chompy bird hat,1 +2980,Chompy bird hat,1 +2981,Chompy bird hat,1 +2982,Chompy bird hat,1 +2983,Chompy bird hat,1 +2984,Chompy bird hat,1 +2985,Chompy bird hat,1 +2986,Chompy bird hat,1 +2987,Chompy bird hat,1 +2988,Chompy bird hat,1 +2989,Chompy bird hat,1 +2990,Chompy bird hat,1 +2991,Chompy bird hat,1 +2992,Chompy bird hat,1 +2993,Chompy bird hat,1 +2994,Chompy bird hat,1 +2995,Chompy bird hat,1 +2996,Agility arena ticket,1 +2997,Pirate's hook,89 +2998,Clean toadflax,48 +2999,Clean toadflax,48 +3000,Clean snapdragon,59 +3001,Clean snapdragon,59 +3002,Toadflax potion(unf),48 +3003,Toadflax potion(unf),48 +3004,Snapdragon potion(unf),59 +3005,Snapdragon potion(unf),59 +3006,Firework,60 +3007,Firework,60 +3008,Energy potion(4),146 +3009,Energy potion(4),146 +3010,Energy potion(3),110 +3011,Energy potion(3),110 +3012,Energy potion(2),72 +3013,Energy potion(2),72 +3014,Energy potion(1),36 +3015,Energy potion(1),36 +3016,Super energy(4),300 +3017,Super energy(4),300 +3018,Super energy(3),230 +3019,Super energy(3),230 +3020,Super energy(2),160 +3021,Super energy(2),160 +3022,Super energy(1),90 +3023,Super energy(1),90 +3024,Super restore(4),300 +3025,Super restore(4),300 +3026,Super restore(3),240 +3027,Super restore(3),240 +3028,Super restore(2),180 +3029,Super restore(2),180 +3030,Super restore(1),120 +3031,Super restore(1),120 +3032,Agility potion(4),200 +3033,Agility potion(4),200 +3034,Agility potion(3),150 +3035,Agility potion(3),150 +3036,Agility potion(2),100 +3037,Agility potion(2),100 +3038,Agility potion(1),50 +3039,Agility potion(1),50 +3040,Magic potion(4),300 +3041,Magic potion(4),300 +3042,Magic potion(3),250 +3043,Magic potion(3),250 +3044,Magic potion(2),200 +3045,Magic potion(2),200 +3046,Magic potion(1),150 +3047,Magic potion(1),150 +3048,Pirate's hook,89 +3049,Grimy toadflax,1 +3050,Grimy toadflax,1 +3051,Grimy snapdragon,1 +3052,Grimy snapdragon,1 +3053,Lava battlestaff,17000 +3054,Mystic lava staff,45000 +3055,Lava battlestaff,17000 +3056,Mystic lava staff,45000 +3057,Mime mask,1 +3058,Mime top,1 +3059,Mime legs,1 +3060,Mime gloves,1 +3061,Mime boots,1 +3062,Strange box,1 +3063,null,1 +3064,null,1 +3065,null,1 +3066,null,1 +3067,null,1 +3068,null,1 +3069,null,1 +3070,null,1 +3071,null,1 +3072,null,1 +3073,null,1 +3074,null,1 +3075,null,1 +3076,null,1 +3077,null,1 +3078,null,1 +3079,null,1 +3080,null,1 +3081,null,1 +3082,null,1 +3083,null,1 +3084,null,1 +3085,null,1 +3086,null,1 +3087,null,1 +3088,null,1 +3089,null,1 +3090,null,1 +3091,null,1 +3092,null,1 +3093,Black dart,1 +3094,Black dart(p),18 +3095,Bronze claws,15 +3096,Iron claws,50 +3097,Steel claws,175 +3098,Black claws,360 +3099,Mithril claws,475 +3100,Adamant claws,1200 +3101,Rune claws,12000 +3102,Combination,1 +3103,Iou,1 +3104,Secret way map,1 +3105,Climbing boots,12 +3106,Climbing boots,12 +3107,Spiked boots,30 +3108,Picture,0 +3109,Stone ball,1 +3110,Stone ball,1 +3111,Stone ball,1 +3112,Stone ball,1 +3113,Stone ball,1 +3114,Certificate,1 +3115,Bronze claws,15 +3116,Iron claws,50 +3117,Steel claws,175 +3118,Black claws,360 +3119,Mithril claws,475 +3120,Adamant claws,1200 +3121,Rune claws,12000 +3122,Granite shield,56000 +3123,Shaikahan bones,1 +3124,Shaikahan bones,1 +3125,Jogre bones,1 +3126,Jogre bones,1 +3127,Burnt jogre bones,1 +3128,Pasty jogre bones,1 +3129,Pasty jogre bones,1 +3130,Marinated j' bones,1 +3131,Pasty jogre bones,1 +3132,Pasty jogre bones,1 +3133,Marinated j' bones,1 +3134,Granite shield,56000 +3135,Prison key,1 +3136,Cell key 1,1 +3137,Cell key 2,1 +3138,Potato cactus,1 +3139,Potato cactus,1 +3140,Dragon chainbody,250000 +3141,Dragon chainbody,250000 +3142,Raw karambwan,440 +3143,Raw karambwan,440 +3144,Cooked karambwan,460 +3145,Cooked karambwan,460 +3146,Poison karambwan,250 +3147,Cooked karambwan,250 +3148,Burnt karambwan,1 +3149,Burnt karambwan,1 +3150,Raw karambwanji,10 +3151,Karambwanji,10 +3152,Karambwan paste,15 +3153,Karambwan paste,15 +3154,Karambwan paste,15 +3155,Karambwanji paste,15 +3156,Karambwanji paste,15 +3157,Karambwan vessel,5 +3158,Karambwan vessel,5 +3159,Karambwan vessel,40 +3160,Karambwan vessel,40 +3161,Crafting manual,5 +3162,Sliced banana,2 +3163,Sliced banana,2 +3164,Karamjan rum,30 +3165,Karamjan rum,30 +3166,Monkey corpse,1 +3167,Monkey skin,10 +3168,Seaweed sandwich,1 +3169,Stuffed monkey,1 +3170,Bronze spear(kp),26 +3171,Iron spear(kp),91 +3172,Steel spear(kp),325 +3173,Mithril spear(kp),845 +3174,Adamant spear(kp),2080 +3175,Rune spear(kp),20800 +3176,Dragon spear(kp),62400 +3177,Picture,2 +3178,Picture,2 +3179,Monkey bones,1 +3180,Monkey bones,1 +3181,Monkey bones,1 +3182,Monkey bones,1 +3183,Monkey bones,1 +3184,Monkey bones,1 +3185,Monkey bones,1 +3186,Monkey bones,1 +3187,Bones,0 +3188,Cleaning cloth,60 +3189,Cleaning cloth,60 +3190,Bronze halberd,104 +3191,Bronze halberd,104 +3192,Iron halberd,364 +3193,Iron halberd,364 +3194,Steel halberd,1300 +3195,Steel halberd,1300 +3196,Black halberd,2496 +3197,Black halberd,2496 +3198,Mithril halberd,3380 +3199,Mithril halberd,3380 +3200,Adamant halberd,8320 +3201,Adamant halberd,8320 +3202,Rune halberd,128000 +3203,Rune halberd,128000 +3204,Dragon halberd,325000 +3205,Dragon halberd,325000 +3206,King's message,1 +3207,Iorwerths message,1 +3208,Crystal pendant,10 +3209,Sulphur,1 +3210,Tinderbox,0 +3211,Limestone,10 +3212,Limestone,10 +3213,Quicklime,4 +3214,Pot of quicklime,5 +3215,Ground sulphur,5 +3216,Barrel,1 +3217,Barrel,1 +3218,Barrel bomb,1 +3219,Barrel bomb,1 +3220,Barrel of coal-tar,1 +3221,Barrel of naphtha,1 +3222,Naphtha mix,1 +3223,Naphtha mix,1 +3224,Strip of cloth,10 +3225,Tinderbox,0 +3226,Raw rabbit,20 +3227,Raw rabbit,20 +3228,Cooked rabbit,4 +3229,Cooked rabbit,4 +3230,Big book of bangs,1 +3231,Picture,1 +3232,Picture,1 +3233,Picture,1 +3234,Picture,1 +3235,Picture,1 +3236,Picture,1 +3237,Picture,1 +3238,Picture,1 +3239,Bark,1 +3240,Bark,1 +3241,Man,1 +3242,null,1 +3243,Farmer,1 +3244,null,1 +3245,Warrior woman,1 +3246,null,1 +3247,Rogue,1 +3248,null,1 +3249,Guard,1 +3250,null,1 +3251,Knight of ardougne,1 +3252,null,1 +3253,Watchman,1 +3254,null,1 +3255,Paladin,1 +3256,null,1 +3257,Gnome,1 +3258,null,1 +3259,Hero,1 +3260,null,1 +3261,Goutweed,1 +3262,Troll thistle,1 +3263,Dried thistle,1 +3264,Ground thistle,1 +3265,Troll potion,1 +3266,Drunk parrot,1 +3267,Dirty robe,1 +3268,Fake man,1 +3269,Storeroom key,1 +3270,Alco-chunks,1 +3271,null,1 +3272,null,1 +3273,null,1 +3274,null,1 +3275,null,1 +3276,null,1 +3277,null,1 +3278,null,1 +3279,null,1 +3280,null,1 +3281,null,1 +3282,null,1 +3283,null,1 +3284,null,1 +3285,null,1 +3286,null,1 +3287,null,1 +3288,null,1 +3289,null,1 +3290,null,1 +3291,null,1 +3292,null,1 +3293,null,1 +3294,null,1 +3295,null,1 +3296,null,1 +3297,null,1 +3298,null,1 +3299,null,1 +3300,null,1 +3301,null,1 +3302,null,1 +3303,null,1 +3304,null,1 +3305,null,1 +3306,null,1 +3307,null,1 +3308,null,1 +3309,null,1 +3310,null,1 +3311,null,1 +3312,null,1 +3313,null,1 +3314,null,1 +3315,null,1 +3316,null,1 +3317,null,1 +3318,null,1 +3319,null,1 +3320,null,1 +3321,null,1 +3322,null,1 +3323,null,1 +3324,null,1 +3325,Vampire dust,2 +3326,Vampire dust,2 +3327,Myre snelm,300 +3328,Myre snelm,300 +3329,Blood'n'tar snelm,300 +3330,Blood'n'tar snelm,300 +3331,Ochre snelm,300 +3332,Ochre snelm,300 +3333,Bruise blue snelm,300 +3334,Bruise blue snelm,300 +3335,Broken bark snelm,300 +3336,Broken bark snelm,300 +3337,Myre snelm,300 +3338,Myre snelm,300 +3339,Blood'n'tar snelm,300 +3340,Blood'n'tar snelm,300 +3341,Ochre snelm,300 +3342,Ochre snelm,300 +3343,Bruise blue snelm,300 +3344,Bruise blue snelm,300 +3345,Blamish myre shell,150 +3346,Blamish myre shell,150 +3347,Blamish red shell,150 +3348,Blamish red shell,150 +3349,Blamish ochre shell,150 +3350,Blamish ochre shell,150 +3351,Blamish blue shell,150 +3352,Blamish blue shell,150 +3353,Blamish bark shell,150 +3354,Blamish bark shell,150 +3355,Blamish myre shell,150 +3356,Blamish myre shell,150 +3357,Blamish red shell,150 +3358,Blamish red shell,150 +3359,Blamish ochre shell,150 +3360,Blamish ochre shell,150 +3361,Blamish blue shell,150 +3362,Blamish blue shell,150 +3363,Thin snail,60 +3364,Thin snail,60 +3365,Lean snail,10 +3366,Lean snail,10 +3367,Fat snail,15 +3368,Fat snail,15 +3369,Thin snail meat,10 +3370,Thin snail meat,10 +3371,Lean snail meat,20 +3372,Lean snail meat,20 +3373,Fat snail meat,30 +3374,Fat snail meat,30 +3375,Burnt snail,10 +3376,Burnt snail,10 +3377,Sample bottle,5 +3378,Sample bottle,5 +3379,Slimy eel,1 +3380,Slimy eel,1 +3381,Cooked slimy eel,1 +3382,Cooked slimy eel,1 +3383,Burnt eel,1 +3384,Tinderbox,0 +3385,Splitbark helm,10000 +3386,Splitbark helm,10000 +3387,Splitbark body,45000 +3388,Splitbark body,45000 +3389,Splitbark legs,40000 +3390,Splitbark legs,40000 +3391,Splitbark gauntlets,5000 +3392,Splitbark gauntlets,5000 +3393,Splitbark boots,5000 +3394,Splitbark boots,5000 +3395,Diary,1 +3396,Loar remains,1 +3397,Loar remains,1 +3398,Phrin remains,1 +3399,Phrin remains,1 +3400,Riyl remains,1 +3401,Riyl remains,1 +3402,Asyn remains,1 +3403,Asyn remains,1 +3404,Fiyr remains,1 +3405,Fiyr remains,1 +3406,Ash potion(unf),11 +3407,Ash potion(unf),11 +3408,Serum 207 (4),14 +3409,Tinderbox,0 +3410,Serum 207 (3),13 +3411,Tinderbox,0 +3412,Serum 207 (2),13 +3413,Tinderbox,0 +3414,Serum 207 (1),11 +3415,Tinderbox,0 +3416,Serum 208 (4),14 +3417,Serum 208 (3),13 +3418,Serum 208 (2),13 +3419,Serum 208 (1),11 +3420,Limestone brick,21 +3421,Limestone brick,21 +3422,Olive oil(4),22 +3423,Olive oil(4),22 +3424,Olive oil(3),26 +3425,Olive oil(3),26 +3426,Olive oil(2),17 +3427,Olive oil(2),17 +3428,Olive oil(1),14 +3429,Olive oil(1),14 +3430,Sacred oil(4),100 +3431,Sacred oil(4),100 +3432,Sacred oil(3),90 +3433,Sacred oil(3),90 +3434,Sacred oil(2),75 +3435,Sacred oil(2),75 +3436,Sacred oil(1),60 +3437,Sacred oil(1),60 +3438,Pyre logs,8 +3439,Pyre logs,8 +3440,Oak pyre logs,40 +3441,Oak pyre logs,40 +3442,Willow pyre logs,80 +3443,Willow pyre logs,80 +3444,Maple pyre logs,160 +3445,Maple pyre logs,160 +3446,Yew pyre logs,320 +3447,Yew pyre logs,320 +3448,Magic pyre logs,640 +3449,Magic pyre logs,640 +3450,Bronze key red,81 +3451,Bronze key brown,82 +3452,Bronze key crimson,83 +3453,Bronze key black,84 +3454,Bronze key purple,85 +3455,Steel key red,86 +3456,Steel key brown,87 +3457,Steel key crimson,88 +3458,Steel key black,89 +3459,Steel key purple,90 +3460,Black key red,91 +3461,Black key brown,92 +3462,Black key crimson,93 +3463,Black key black,94 +3464,Black key purple,95 +3465,Silver key red,96 +3466,Silver key brown,97 +3467,Silver key crimson,98 +3468,Silver key black,99 +3469,Silver key purple,100 +3470,Fine cloth,500 +3471,Fine cloth,500 +3472,Black plateskirt (t),1920 +3473,Black plateskirt (g),1920 +3474,Adam plateskirt (t),6400 +3475,Adam plateskirt (g),6400 +3476,Rune plateskirt (g),64000 +3477,Rune plateskirt (t),64000 +3478,Zamorak plateskirt,64000 +3479,Saradomin plateskirt,64000 +3480,Guthix plateskirt,64000 +3481,Gilded platebody,65000 +3482,Gilded platebody,65000 +3483,Gilded platelegs,64000 +3484,Gilded platelegs,64000 +3485,Gilded plateskirt,64000 +3486,Gilded full helm,35200 +3487,Gilded full helm,35200 +3488,Gilded kiteshield,54400 +3489,Gilded kiteshield,54400 +3490,Clue scroll,1 +3491,Clue scroll,1 +3492,Clue scroll,1 +3493,Clue scroll,1 +3494,Clue scroll,1 +3495,Clue scroll,1 +3496,Clue scroll,1 +3497,Clue scroll,1 +3498,Clue scroll,1 +3499,Clue scroll,1 +3500,Clue scroll,1 +3501,Clue scroll,1 +3502,Clue scroll,1 +3503,Clue scroll,1 +3504,Clue scroll,1 +3505,Clue scroll,1 +3506,Clue scroll,1 +3507,Clue scroll,1 +3508,Clue scroll,1 +3509,Clue scroll,1 +3510,Clue scroll,1 +3511,Casket,50 +3512,Clue scroll,1 +3513,Clue scroll,1 +3514,Clue scroll,1 +3515,Clue scroll,1 +3516,Clue scroll,1 +3517,Casket,50 +3518,Clue scroll,1 +3519,Casket,50 +3520,Clue scroll,1 +3521,Casket,50 +3522,Clue scroll,1 +3523,Casket,50 +3524,Clue scroll,1 +3525,Clue scroll,1 +3526,Clue scroll,1 +3527,Casket,50 +3528,Clue scroll,1 +3529,Casket,50 +3530,Clue scroll,1 +3531,Casket,50 +3532,Clue scroll,1 +3533,Casket,50 +3534,Clue scroll,1 +3535,Casket,50 +3536,Clue scroll,1 +3537,Casket,50 +3538,Clue scroll,1 +3539,Casket,50 +3540,Clue scroll,1 +3541,Casket,50 +3542,Clue scroll,1 +3543,Casket,50 +3544,Clue scroll,1 +3545,Casket,50 +3546,Clue scroll,1 +3547,Casket,50 +3548,Clue scroll,1 +3549,Casket,50 +3550,Clue scroll,1 +3551,Casket,50 +3552,Clue scroll,1 +3553,Casket,50 +3554,Clue scroll,1 +3555,Casket,50 +3556,Clue scroll,1 +3557,Casket,50 +3558,Clue scroll,1 +3559,Casket,50 +3560,Clue scroll,1 +3561,Casket,50 +3562,Clue scroll,1 +3563,Casket,50 +3564,Clue scroll,1 +3565,Puzzle box,100 +3566,Clue scroll,1 +3567,Puzzle box,100 +3568,Clue scroll,1 +3569,Puzzle box,100 +3570,Clue scroll,1 +3571,Puzzle box,100 +3572,Clue scroll,1 +3573,Clue scroll,1 +3574,Clue scroll,1 +3575,Clue scroll,1 +3576,Puzzle box,100 +3577,Clue scroll,1 +3578,Puzzle box,100 +3579,Clue scroll,1 +3580,Clue scroll,1 +3581,Casket,50 +3582,Clue scroll,1 +3583,Casket,50 +3584,Clue scroll,1 +3585,Casket,50 +3586,Clue scroll,1 +3587,Casket,50 +3588,Clue scroll,1 +3589,Casket,50 +3590,Clue scroll,1 +3591,Casket,50 +3592,Clue scroll,1 +3593,Casket,50 +3594,Clue scroll,1 +3595,Casket,50 +3596,Clue scroll,1 +3597,Casket,50 +3598,Clue scroll,1 +3599,Clue scroll,1 +3600,Casket,50 +3601,Clue scroll,1 +3602,Clue scroll,1 +3603,Casket,50 +3604,Clue scroll,1 +3605,Clue scroll,1 +3606,Key,1 +3607,Clue scroll,1 +3608,Key,1 +3609,Clue scroll,1 +3610,Clue scroll,1 +3611,Clue scroll,1 +3612,Clue scroll,1 +3613,Clue scroll,1 +3614,Clue scroll,1 +3615,Clue scroll,1 +3616,Clue scroll,1 +3617,Clue scroll,1 +3618,Clue scroll,1 +3619,Sliding piece,1 +3620,Sliding piece,1 +3621,Sliding piece,1 +3622,Sliding piece,1 +3623,Sliding piece,1 +3624,Sliding piece,1 +3625,Sliding piece,1 +3626,Sliding piece,1 +3627,Sliding piece,1 +3628,Sliding piece,1 +3629,Sliding piece,1 +3630,Sliding piece,1 +3631,Sliding piece,1 +3632,Sliding piece,1 +3633,Sliding piece,1 +3634,Sliding piece,1 +3635,Sliding piece,1 +3636,Sliding piece,1 +3637,Sliding piece,1 +3638,Sliding piece,1 +3639,Sliding piece,1 +3640,Sliding piece,1 +3641,Sliding piece,1 +3642,Sliding piece,1 +3643,Sliding piece,1 +3644,Sliding piece,1 +3645,Sliding piece,1 +3646,Sliding piece,1 +3647,Sliding piece,1 +3648,Sliding piece,1 +3649,Sliding piece,1 +3650,Sliding piece,1 +3651,Sliding piece,1 +3652,Sliding piece,1 +3653,Sliding piece,1 +3654,Sliding piece,1 +3655,Sliding piece,1 +3656,Sliding piece,1 +3657,Sliding piece,1 +3658,Sliding piece,1 +3659,Sliding piece,1 +3660,Sliding piece,1 +3661,Sliding piece,1 +3662,Sliding piece,1 +3663,Sliding piece,1 +3664,Sliding piece,1 +3665,Sliding piece,1 +3666,Sliding piece,1 +3667,Picture,1 +3668,Black plateskirt (t),1920 +3669,Black plateskirt (g),1920 +3670,Adam plateskirt (t),6400 +3671,Adam plateskirt (g),6400 +3672,Rune plateskirt (g),64000 +3673,Rune plateskirt (t),64000 +3674,Zamorak plateskirt,64000 +3675,Saradomin plateskirt,64000 +3676,Guthix plateskirt,64000 +3677,Gilded plateskirt,64000 +3678,Flamtaer hammer,13000 +3679,Picture,0 +3680,Picture,1 +3681,Picture,1 +3682,Picture,1 +3683,Picture,1 +3684,Picture,1 +3685,Picture,1 +3686,Fremennik,1 +3687,null,1 +3688,Unstrung lyre,1 +3689,Lyre,1 +3690,Enchanted lyre,1 +3691,Enchanted lyre(1),1000 +3692,Branch,1 +3693,Golden fleece,1 +3694,Golden wool,1 +3695,Pet rock,1 +3696,Hunters' talisman,4 +3697,Hunters' talisman,4 +3698,Exotic flower,1 +3699,Fremennik ballad,1 +3700,Sturdy boots,1 +3701,Tracking map,1 +3702,Custom bow string,1 +3703,Unusual fish,1 +3704,Sea fishing map,1 +3705,Weather forecast,1 +3706,Champions token,1 +3707,Legendary cocktail,1 +3708,Fiscal statement,1 +3709,Promissory note,1 +3710,Warriors' contract,1 +3711,Keg of beer,1 +3712,Low alcohol keg,1 +3713,Strange object,1 +3714,Lit strange object,1 +3715,Picture,1 +3716,Picture,1 +3717,null,1 +3718,Magnet,3 +3719,Thread,1 +3720,Pick,1 +3721,Ship toy,2 +3722,Full bucket,1 +3723,4/5ths full bucket,1 +3724,3/5ths full bucket,1 +3725,2/5ths full bucket,1 +3726,1/5ths full bucket,1 +3727,Empty bucket,1 +3728,Frozen bucket,1 +3729,Full jug,1 +3730,2/3rds full jug,1 +3731,1/3rds full jug,1 +3732,Empty jug,1 +3733,Frozen jug,1 +3734,Vase,1 +3735,Vase of water,1 +3736,Frozen vase,1 +3737,Vase lid,1 +3738,Sealed vase,1 +3739,Sealed vase,1 +3740,Sealed vase,1 +3741,Frozen key,1 +3742,Red herring,1 +3743,Red disk,1 +3744,Wooden disk,1 +3745,Seer's key,1 +3746,Sticky red goop,1 +3747,Sticky red goop,1 +3748,Fremennik helm,6500 +3749,Archer helm,78000 +3750,Archer helm,78000 +3751,Berserker helm,78000 +3752,Berserker helm,78000 +3753,Warrior helm,78000 +3754,Warrior helm,78000 +3755,Farseer helm,78000 +3756,Farseer helm,78000 +3757,Fremennik blade,5000 +3758,Fremennik shield,5000 +3759,Fremennik cloak,325 +3760,Fremennik cloak,325 +3761,Fremennik cloak,325 +3762,Fremennik cloak,325 +3763,Fremennik cloak,325 +3764,Fremennik cloak,325 +3765,Fremennik cloak,325 +3766,Fremennik cloak,325 +3767,Fremennik shirt,325 +3768,Fremennik shirt,325 +3769,Fremennik shirt,325 +3770,Fremennik shirt,325 +3771,Fremennik shirt,325 +3772,Fremennik shirt,325 +3773,Fremennik shirt,325 +3774,Fremennik shirt,325 +3775,Fremennik shirt,325 +3776,Fremennik shirt,325 +3777,Fremennik cloak,325 +3778,Fremennik cloak,325 +3779,Fremennik cloak,325 +3780,Fremennik cloak,325 +3781,Fremennik cloak,325 +3782,Fremennik cloak,325 +3783,Fremennik cloak,325 +3784,Fremennik cloak,325 +3785,Fremennik cloak,325 +3786,Fremennik cloak,325 +3787,Fremennik cloak,325 +3788,Fremennik cloak,325 +3789,Fremennik cloak,325 +3790,Fremennik cloak,325 +3791,Fremennik boots,650 +3792,Fremennik boots,650 +3793,Fremennik robe,650 +3794,Fremennik robe,650 +3795,Fremennik skirt,650 +3796,Fremennik skirt,650 +3797,Fremennik hat,650 +3798,Fremennik hat,650 +3799,Gloves,650 +3800,Gloves,650 +3801,Keg of beer,325 +3802,Keg of beer,325 +3803,Beer,26 +3804,Beer,26 +3805,Tankard,5 +3806,Tankard,5 +3807,null,1 +3808,null,1 +3809,null,1 +3810,null,1 +3811,null,1 +3812,null,1 +3813,null,1 +3814,null,1 +3815,null,1 +3816,null,1 +3817,null,1 +3818,null,1 +3819,null,1 +3820,null,1 +3821,null,1 +3822,null,1 +3823,null,1 +3824,null,1 +3825,null,1 +3826,null,1 +3827,Saradomin page 1,200 +3828,Saradomin page 2,200 +3829,Saradomin page 3,200 +3830,Saradomin page 4,200 +3831,Zamorak page 1,200 +3832,Zamorak page 2,200 +3833,Zamorak page 3,200 +3834,Zamorak page 4,200 +3835,Guthix page 1,200 +3836,Guthix page 2,200 +3837,Guthix page 3,200 +3838,Guthix page 4,200 +3839,Damaged book,200 +3840,Holy book,200 +3841,Damaged book,200 +3842,Unholy book,200 +3843,Damaged book,200 +3844,Book of balance,200 +3845,Journal,1 +3846,Diary,1 +3847,Manual,1 +3848,Lighthouse key,1 +3849,Rusty casket,1 +3850,null,1 +3851,null,1 +3852,Unholy symbol,200 +3853,Games necklace(8),1050 +3854,Games necklace(8),1050 +3855,Games necklace(7),1050 +3856,Games necklace(7),1050 +3857,Games necklace(6),1050 +3858,Games necklace(6),1050 +3859,Games necklace(5),1050 +3860,Games necklace(5),1050 +3861,Games necklace(4),1050 +3862,Games necklace(4),1050 +3863,Games necklace(3),1050 +3864,Games necklace(3),1050 +3865,Games necklace(2),1050 +3866,Games necklace(2),1050 +3867,Games necklace(1),1050 +3868,Games necklace(1),1050 +3869,Board game piece,1 +3870,Board game piece,1 +3871,Board game piece,1 +3872,Board game piece,1 +3873,Board game piece,1 +3874,Board game piece,1 +3875,Board game piece,1 +3876,Board game piece,1 +3877,Board game piece,1 +3878,Board game piece,1 +3879,Board game piece,1 +3880,Board game piece,1 +3881,null,1 +3882,null,1 +3883,null,1 +3884,null,1 +3885,null,1 +3886,null,1 +3887,null,1 +3888,null,1 +3889,null,1 +3890,null,1 +3891,null,1 +3892,null,1 +3893,Stool,800 +3894,Awful anthem,1 +3895,Good anthem,1 +3896,Treaty,1 +3897,Giant nib,1 +3898,Giant pen,1 +3899,Iron sickle,15 +3900,Picture,0 +3901,Ghrim's book,1 +3902,Picture,1 +3903,Picture,0 +3904,Sliding button,1 +3905,null,1 +3906,Sliding button,1 +3907,null,1 +3908,Sliding button,1 +3909,null,1 +3910,Sliding button,1 +3911,null,1 +3912,Sliding button,1 +3913,null,1 +3914,Sliding button,1 +3915,null,1 +3916,Sliding button,1 +3917,null,1 +3918,Sliding button,1 +3919,null,1 +3920,Sliding button,1 +3921,null,1 +3922,Sliding button,1 +3923,null,1 +3924,Sliding button,1 +3925,null,1 +3926,Sliding button,1 +3927,null,1 +3928,Sliding button,1 +3929,null,1 +3930,Sliding button,1 +3931,null,1 +3932,Sliding button,1 +3933,null,1 +3934,Sliding button,1 +3935,null,1 +3936,Sliding button,1 +3937,null,1 +3938,Sliding button,1 +3939,null,1 +3940,Sliding button,1 +3941,null,1 +3942,Sliding button,1 +3943,null,1 +3944,Sliding button,1 +3945,null,1 +3946,Sliding button,1 +3947,null,1 +3948,Sliding button,1 +3949,null,1 +3950,Sliding button,1 +3951,null,1 +3952,Sliding button,1 +3953,null,1 +3954,Sliding button,1 +3955,null,1 +3956,Sliding button,1 +3957,null,1 +3958,Sliding button,1 +3959,null,1 +3960,Sliding button,1 +3961,null,1 +3962,Sliding button,1 +3963,null,1 +3964,Sliding button,1 +3965,null,1 +3966,Sliding button,1 +3967,null,1 +3968,Sliding button,1 +3969,null,1 +3970,Sliding button,1 +3971,null,1 +3972,Sliding button,1 +3973,null,1 +3974,Sliding button,1 +3975,null,1 +3976,Sliding button,1 +3977,null,1 +3978,Sliding button,1 +3979,null,1 +3980,Sliding button,1 +3981,null,1 +3982,Sliding button,1 +3983,null,1 +3984,Sliding button,1 +3985,null,1 +3986,Sliding button,1 +3987,null,1 +3988,Sliding button,1 +3989,null,1 +3990,Sliding button,1 +3991,null,1 +3992,Sliding button,1 +3993,null,1 +3994,Sliding button,1 +3995,null,1 +3996,Sliding button,1 +3997,null,1 +3998,Sliding button,1 +3999,null,1 +4000,Picture,1 +4001,Hardy gout tuber,5 +4002,Spare controls,1 +4003,Picture,0 +4004,Gnome royal seal,1 +4005,Narnode's orders,1 +4006,Monkey dentures,10 +4007,Enchanted bar,800 +4008,Eye of gnome,3 +4009,Eye of gnome,3 +4010,Monkey magic,3 +4011,Picture,0 +4012,Monkey nuts,3 +4013,Picture,0 +4014,Monkey bar,50 +4015,Picture,0 +4016,Banana stew,300 +4017,Picture,0 +4018,Monkey wrench,10 +4019,Picture,0 +4020,M'amulet mould,10 +4021,M'speak amulet,550 +4022,M'speak amulet,500 +4023,Monkey talisman,1000 +4024,Monkey greegree,3000 +4025,Monkey greegree,6000 +4026,Monkey greegree,1000 +4027,Monkey greegree,1500 +4028,Monkey greegree,10000 +4029,Monkey greegree,500 +4030,Monkey greegree,2000 +4031,Monkey greegree,500 +4032,Dummy,1 +4033,Monkey,1 +4034,Monkey skull,1 +4035,10th squad sigil,1 +4036,null,1 +4037,Saradomin banner,1 +4038,Saradomin banner,1 +4039,Zamorak banner,1 +4040,Zamorak banner,1 +4041,Hooded cloak,1 +4042,Hooded cloak,1 +4043,Rock,1 +4044,Rock,1 +4045,Explosive potion,1 +4046,Explosive potion,1 +4047,Climbing rope,1 +4048,Climbing rope,1 +4049,Bandages,1 +4050,Bandages,1 +4051,Toolkit,1 +4052,Toolkit,1 +4053,Barricade,1 +4054,Barricade,1 +4055,Castlewars manual,5 +4056,null,1 +4057,null,1 +4058,null,1 +4059,null,1 +4060,null,1 +4061,null,1 +4062,null,1 +4063,null,1 +4064,null,1 +4065,null,1 +4066,null,1 +4067,Castle wars ticket,1 +4068,Decorative sword,500 +4069,Decorative armour,2000 +4070,Decorative armour,1000 +4071,Decorative helm,300 +4072,Decorative shield,850 +4073,Damp tinderbox,1 +4074,Damp tinderbox,1 +4075,Glowing fungus,1 +4076,Picture,1 +4077,Crystal-mine key,1 +4078,Zealot's key,1 +4079,Yo-yo,10 +4080,null,1 +4081,Salve amulet,1 +4082,Salve shard,1 +4083,Sled,150 +4084,Sled,175 +4085,Wax,15 +4086,Trollweiss,5 +4087,Dragon platelegs,270000 +4088,Dragon platelegs,270000 +4089,Mystic hat,15000 +4090,Mystic hat,15000 +4091,Mystic robe top,120000 +4092,Mystic robe top,120000 +4093,Mystic robe bottom,80000 +4094,Mystic robe bottom,80000 +4095,Mystic gloves,10000 +4096,Mystic gloves,10000 +4097,Mystic boots,10000 +4098,Mystic boots,10000 +4099,Mystic hat,15000 +4100,Mystic hat,15000 +4101,Mystic robe top,120000 +4102,Mystic robe top,120000 +4103,Mystic robe bottom,80000 +4104,Mystic robe bottom,80000 +4105,Mystic gloves,10000 +4106,Mystic gloves,10000 +4107,Mystic boots,10000 +4108,Mystic boots,10000 +4109,Mystic hat,15000 +4110,Mystic hat,15000 +4111,Mystic robe top,120000 +4112,Mystic robe top,120000 +4113,Mystic robe bottom,80000 +4114,Mystic robe bottom,80000 +4115,Mystic gloves,10000 +4116,Mystic gloves,10000 +4117,Mystic boots,10000 +4118,Mystic boots,10000 +4119,Bronze boots,24 +4120,Bronze boots,24 +4121,Iron boots,84 +4122,Iron boots,84 +4123,Steel boots,300 +4124,Steel boots,300 +4125,Black boots,576 +4126,Black boots,576 +4127,Mithril boots,780 +4128,Mithril boots,780 +4129,Adamant boots,1920 +4130,Adamant boots,1920 +4131,Rune boots,12500 +4132,Rune boots,12500 +4133,Crawling hand,1 +4134,Cave crawler,1 +4135,Banshee,1 +4136,Rockslug,1 +4137,Cockatrice,1 +4138,Pyrefiend,1 +4139,Basilisk,1 +4140,Infernal mage,1 +4141,Bloodveld,1 +4142,Jelly,1 +4143,Turoth,1 +4144,Abberant spectre,1 +4145,Dust devil,1 +4146,Kurask,1 +4147,Gargoyle,1 +4148,Nechryael,1 +4149,Abyssal demon,1 +4150,Broad arrows,1 +4151,Abyssal whip,120001 +4152,Abyssal whip,120001 +4153,Granite maul,50000 +4154,Granite maul,50000 +4155,Enchanted gem,1 +4156,Mirror shield,5000 +4157,Mirror shield,5000 +4158,Leaf-bladed spear,31000 +4159,Leaf-bladed spear,31000 +4160,Broad arrow,90 +4161,Bag of salt,10 +4162,Rock hammer,500 +4163,Rock hammer,500 +4164,Face mask,200 +4165,Face mask,200 +4166,Earmuffs,200 +4167,Earmuffs,200 +4168,Nose peg,200 +4169,Nose peg,200 +4170,Slayer's staff,21000 +4171,Slayer's staff,21000 +4172,Broad arrows,1 +4173,Broad arrows,1 +4174,Broad arrows,1 +4175,Broad arrows,1 +4176,null,1 +4177,Picture,1 +4178,Abyssal whip,6 +4179,Stick,1 +4180,Dragon platelegs,6 +4181,Mouth grip,1 +4182,Goutweed,6 +4183,Star amulet,1 +4184,Cavern key,1 +4185,Tower key,1 +4186,Shed key,1 +4187,Marble amulet,1 +4188,Obsidian amulet,1 +4189,Garden cane,1 +4190,Garden brush,1 +4191,Extended brush,1 +4192,Extended brush,1 +4193,Extended brush,1 +4194,Torso,1 +4195,Arms,1 +4196,Legs,1 +4197,Decapitated head,1 +4198,Decapitated head,1 +4199,Pickled brain,1 +4200,Conductor mould,1 +4201,Conductor,1 +4202,Ring of charos,1 +4203,Journal,1 +4204,Letter,1 +4205,Consecration seed,1 +4206,Consecration seed,1 +4207,Crystal seed,1 +4208,Crystal seed,1 +4209,Cadarn lineage,2 +4210,Tinderbox,0 +4211,Elf crystal,1 +4212,New crystal bow,900000 +4213,New crystal bow,900000 +4214,Crystal bow full,900000 +4215,Crystal bow 9/10,800000 +4216,Crystal bow 8/10,700000 +4217,Crystal bow 7/10,600000 +4218,Crystal bow 6/10,500000 +4219,Crystal bow 5/10,400000 +4220,Crystal bow 4/10,300000 +4221,Crystal bow 3/10,200000 +4222,Crystal bow 2/10,100000 +4223,Crystal bow 1/10,50000 +4224,New crystal shield,800000 +4225,Crystal shield full,750000 +4226,Crystal shield 9/10,670000 +4227,Crystal shield 8/10,590000 +4228,Crystal shield 7/10,510000 +4229,Crystal shield 6/10,430000 +4230,Crystal shield 5/10,350000 +4231,Crystal shield 4/10,270000 +4232,Crystal shield 3/10,190000 +4233,Crystal shield 2/10,100000 +4234,Crystal shield 1/10,25000 +4235,New crystal shield,800000 +4236,Signed oak bow,160 +4237,Nettle-water,4 +4238,Puddle of slime,1 +4239,Nettle tea,4 +4240,Nettle tea,4 +4241,Nettles,3 +4242,Cup of tea,10 +4243,Cup of tea,10 +4244,Porcelain cup,2 +4245,Cup of tea,10 +4246,Cup of tea,10 +4247,Mystical robes,1 +4248,Book of haricanto,1 +4249,Translation manual,1 +4250,Ghostspeak amulet,35 +4251,Ectophial,1 +4252,Ectophial,1 +4253,Model ship,1 +4254,Model ship,1 +4255,Bonemeal,1 +4256,Bonemeal,1 +4257,Bonemeal,1 +4258,Bonemeal,1 +4259,Bonemeal,1 +4260,Bonemeal,1 +4261,Bonemeal,1 +4262,Bonemeal,1 +4263,Bonemeal,1 +4264,Bonemeal,1 +4265,Bonemeal,1 +4266,Bonemeal,1 +4267,Bonemeal,1 +4268,Bonemeal,1 +4269,Bonemeal,1 +4270,Bonemeal,1 +4271,Bonemeal,1 +4272,Bone key,1 +4273,Chest key,1 +4274,Map scrap,1 +4275,Map scrap,1 +4276,Map scrap,1 +4277,Treasure map,1 +4278,Ecto-token,1 +4279,null,1 +4280,null,1 +4281,null,1 +4282,null,1 +4283,Petition form,1 +4284,Bedsheet,1 +4285,Bedsheet,1 +4286,Bucket of slime,1 +4287,Raw beef,1 +4288,Raw beef,1 +4289,Raw chicken,1 +4290,Raw chicken,1 +4291,Cooked chicken,4 +4292,Cooked chicken,4 +4293,Cooked meat,4 +4294,Cooked meat,4 +4295,Female h.a.m.,1 +4296,null,1 +4297,Male h.a.m.,1 +4298,Ham shirt,75 +4299,Ham shirt,75 +4300,Ham robe,75 +4301,Ham robe,75 +4302,Ham hood,75 +4303,Ham hood,75 +4304,Ham cloak,75 +4305,Ham cloak,75 +4306,H.a.m logo,75 +4307,H.a.m logo,75 +4308,Gloves,75 +4309,Gloves,75 +4310,Boots,75 +4311,Boots,75 +4312,null,1 +4313,Crystal of seren,2 +4314,Tinderbox,0 +4315,Team-1 cape,50 +4316,Team-1 cape,50 +4317,Team-2 cape,50 +4318,Team-2 cape,50 +4319,Team-3 cape,50 +4320,Team-3 cape,50 +4321,Team-4 cape,50 +4322,Team-4 cape,50 +4323,Team-5 cape,50 +4324,Team-5 cape,50 +4325,Team-6 cape,50 +4326,Team-6 cape,50 +4327,Team-7 cape,50 +4328,Team-7 cape,50 +4329,Team-8 cape,50 +4330,Team-8 cape,50 +4331,Team-9 cape,50 +4332,Team-9 cape,50 +4333,Team-10 cape,50 +4334,Team-10 cape,50 +4335,Team-11 cape,50 +4336,Team-11 cape,50 +4337,Team-12 cape,50 +4338,Team-12 cape,50 +4339,Team-13 cape,50 +4340,Team-13 cape,50 +4341,Team-14 cape,50 +4342,Team-14 cape,50 +4343,Team-15 cape,50 +4344,Team-15 cape,50 +4345,Team-16 cape,50 +4346,Team-16 cape,50 +4347,Team-17 cape,50 +4348,Team-17 cape,50 +4349,Team-18 cape,50 +4350,Team-18 cape,50 +4351,Team-19 cape,50 +4352,Team-19 cape,50 +4353,Team-20 cape,50 +4354,Team-20 cape,50 +4355,Team-21 cape,50 +4356,Team-21 cape,50 +4357,Team-22 cape,50 +4358,Team-22 cape,50 +4359,Team-23 cape,50 +4360,Team-23 cape,50 +4361,Team-24 cape,50 +4362,Team-24 cape,50 +4363,Team-25 cape,50 +4364,Team-25 cape,50 +4365,Team-26 cape,50 +4366,Team-26 cape,50 +4367,Team-27 cape,50 +4368,Team-27 cape,50 +4369,Team-28 cape,50 +4370,Team-28 cape,50 +4371,Team-29 cape,50 +4372,Team-29 cape,50 +4373,Team-30 cape,50 +4374,Team-30 cape,50 +4375,Team-31 cape,50 +4376,Team-31 cape,50 +4377,Team-32 cape,50 +4378,Team-32 cape,50 +4379,Team-33 cape,50 +4380,Team-33 cape,50 +4381,Team-34 cape,50 +4382,Team-34 cape,50 +4383,Team-35 cape,50 +4384,Team-35 cape,50 +4385,Team-36 cape,50 +4386,Team-36 cape,50 +4387,Team-37 cape,50 +4388,Team-37 cape,50 +4389,Team-38 cape,50 +4390,Team-38 cape,50 +4391,Team-39 cape,50 +4392,Team-39 cape,50 +4393,Team-40 cape,50 +4394,Team-40 cape,50 +4395,Team-41 cape,50 +4396,Team-41 cape,50 +4397,Team-42 cape,50 +4398,Team-42 cape,50 +4399,Team-43 cape,50 +4400,Team-43 cape,50 +4401,Team-44 cape,50 +4402,Team-44 cape,50 +4403,Team-45 cape,50 +4404,Team-45 cape,50 +4405,Team-46 cape,50 +4406,Team-46 cape,50 +4407,Team-47 cape,50 +4408,Team-47 cape,50 +4409,Team-48 cape,50 +4410,Team-48 cape,50 +4411,Team-49 cape,50 +4412,Team-49 cape,50 +4413,Team-50 cape,50 +4414,Team-50 cape,50 +4415,Blunt axe,56 +4416,Herbal tincture,100 +4417,Guthix rest(4),50 +4418,Guthix rest(4),50 +4419,Guthix rest(3),50 +4420,Guthix rest(3),50 +4421,Guthix rest(2),50 +4422,Guthix rest(2),50 +4423,Guthix rest(1),50 +4424,Guthix rest(1),50 +4425,Stodgy mattress,1 +4426,Comfy mattress,1 +4427,Iron oxide,5 +4428,Animate rock scroll,50 +4429,Broken vane part,1 +4430,Directionals,1 +4431,Broken vane part,1 +4432,Ornament,1 +4433,Broken vane part,1 +4434,Weathervane pillar,1 +4435,Weather report,1 +4436,Airtight pot,10 +4437,Airtight pot,10 +4438,Unfired pot lid,10 +4439,Unfired pot lid,10 +4440,Pot lid,15 +4441,Pot lid,15 +4442,Breathing salts,1 +4443,Chicken cage,1 +4444,Sharpened axe,56 +4445,Red mahogany log,1 +4446,Steel key ring,1 +4447,Antique lamp,1 +4448,null,1 +4449,null,1 +4450,null,1 +4451,null,1 +4452,null,1 +4453,null,1 +4454,null,1 +4455,null,1 +4456,Bowl of hot water,10 +4457,Bowl of hot water,10 +4458,Cup of water,10 +4459,Cup of water,10 +4460,Cup of hot water,10 +4461,Cup of hot water,10 +4462,Ruined herb tea,10 +4463,Ruined herb tea,10 +4464,Herb tea mix,10 +4465,Herb tea mix,10 +4466,Herb tea mix,10 +4467,Herb tea mix,10 +4468,Herb tea mix,10 +4469,Herb tea mix,10 +4470,Herb tea mix,15 +4471,Herb tea mix,15 +4472,Herb tea mix,15 +4473,Herb tea mix,15 +4474,Herb tea mix,15 +4475,Herb tea mix,15 +4476,Herb tea mix,15 +4477,Herb tea mix,15 +4478,Herb tea mix,30 +4479,Herb tea mix,30 +4480,Herb tea mix,30 +4481,Herb tea mix,30 +4482,Herb tea mix,30 +4483,Herb tea mix,30 +4484,Safety guarantee,1 +4485,White pearl,1 +4486,White pearl seed,1 +4487,Half a rock,1 +4488,Corpse of woman,1 +4489,Asleif's necklace,1 +4490,Mud,1 +4491,Tinderbox,0 +4492,Muddy rock,1 +4493,Tinderbox,0 +4494,Pole,1 +4495,Pole,1 +4496,Broken pole,1 +4497,Tinderbox,0 +4498,Rope,1 +4499,Rope,1 +4500,Pole,1 +4501,Pole,1 +4502,Bearhead,0 +4503,Decorative sword,1300 +4504,Decorative armour,5200 +4505,Decorative armour,2600 +4506,Decorative helm,780 +4507,Decorative shield,2210 +4508,Decorative sword,3200 +4509,Decorative armour,12800 +4510,Decorative armour,6400 +4511,Decorative helm,1920 +4512,Decorative shield,5440 +4513,Castlewars hood,1 +4514,Castlewars cloak,100 +4515,Castlewars hood,1 +4516,Castlewars cloak,100 +4517,Giant frog legs,100 +4518,Giant frog legs,100 +4519,Swamp wallbeast,1 +4520,Swamp cave slime,1 +4521,Swamp cave bug,1 +4522,Oil lamp,28 +4523,Oil lamp,28 +4524,Oil lamp,28 +4525,Oil lamp,25 +4526,Oil lamp,25 +4527,Candle lantern,10 +4528,Candle lantern,10 +4529,Candle lantern,15 +4530,Candle lantern,15 +4531,Candle lantern,15 +4532,Candle lantern,15 +4533,Candle lantern,15 +4534,Candle lantern,15 +4535,Oil lantern,120 +4536,Oil lantern,120 +4537,Oil lantern,125 +4538,Oil lantern,125 +4539,Oil lantern,125 +4540,Oil lantern frame,90 +4541,Oil lantern frame,90 +4542,Lantern lens,70 +4543,Lantern lens,70 +4544,Bullseye lantern,300 +4545,Bullseye lantern,300 +4546,Bullseye lantern,400 +4547,Bullseye lantern,400 +4548,Bullseye lantern,420 +4549,Bullseye lantern,420 +4550,Bullseye lantern,420 +4551,Spiny helmet,650 +4552,Spiny helmet,650 +4553,null,1 +4554,null,1 +4555,null,1 +4556,null,1 +4557,null,1 +4558,Blue sweets,0 +4559,Deep blue sweets,0 +4560,White sweets,0 +4561,Purple sweets,0 +4562,Red sweets,0 +4563,Green sweets,0 +4564,Pink sweets,0 +4565,Basket of eggs,0 +4566,Rubber chicken,0 +4567,Gold helmet,1 +4568,Dwarven lore,1 +4569,Book page 1,1 +4570,Book page 2,1 +4571,Book page 3,1 +4572,Pages,1 +4573,Pages,1 +4574,Base schematics,1 +4575,Schematic,1 +4576,Schematics,1 +4577,Schematics,1 +4578,Schematic,1 +4579,Cannon ball,1 +4580,Black spear,650 +4581,Black spear,650 +4582,Black spear(p),750 +4583,Black spear(p),750 +4584,Black spear(kp),750 +4585,Dragon plateskirt,270000 +4586,Dragon plateskirt,270000 +4587,Dragon scimitar,100000 +4588,Dragon scimitar,100000 +4589,Keys,1 +4590,Jewels,1 +4591,Karidian headpiece,1 +4592,Picture,0 +4593,Fake beard,1 +4594,Picture,0 +4595,Karidian disguise,1 +4596,Picture,0 +4597,Note,1 +4598,Note,1 +4599,Oak-blackjack,1 +4600,Willow-blackjack,600 +4601,Ugthanki dung,1 +4602,Ugthanki dung,1 +4603,Receipt,1 +4604,Hag's poison,1 +4605,Snake charm,1 +4606,Snake basket,1 +4607,Snake basket full,1 +4608,Super kebab,3 +4609,Super kebab,3 +4610,Red hot sauce,1 +4611,Desert disguise,1 +4612,Willow-blackjack,600 +4613,Spinning plate,75 +4614,Broken plate,0 +4615,Letter,1 +4616,Varmen's notes,2 +4617,Display cabinet key,1 +4618,Statuette,2 +4619,Strange implement,1 +4620,Black mushroom,1 +4621,Phoenix feather,1 +4622,Black mushroom ink,1 +4623,Phoenix quill pen,1 +4624,Golem program,1 +4625,Bandit,1 +4626,null,1 +4627,Bandit's brew,650 +4628,Bandit's brew,650 +4629,null,1 +4630,null,1 +4631,null,1 +4632,null,1 +4633,null,1 +4634,null,1 +4635,null,1 +4636,null,1 +4637,null,1 +4638,null,1 +4639,null,1 +4640,null,1 +4641,null,1 +4642,null,1 +4643,null,1 +4644,null,1 +4645,null,1 +4646,null,1 +4647,null,1 +4648,null,1 +4649,null,1 +4650,null,1 +4651,null,1 +4652,null,1 +4653,Fire,250 +4654,Etchings,250 +4655,Translation,250 +4656,Warm key,250 +4657,Ring of visibility,350 +4658,Silver pot,250 +4659,Blessed pot,250 +4660,Silver pot,250 +4661,Blessed pot,250 +4662,Silver pot,250 +4663,Blessed pot,250 +4664,Silver pot,250 +4665,Blessed pot,250 +4666,Silver pot,250 +4667,Blessed pot,250 +4668,Garlic powder,10 +4669,Tinderbox,0 +4670,Blood diamond,250 +4671,Ice diamond,250 +4672,Smoke diamond,250 +4673,Shadow diamond,250 +4674,Gilded cross,250 +4675,Ancient staff,100000 +4676,Ancient staff,100000 +4677,Catspeak amulet,1 +4678,Canopic jar,1 +4679,Canopic jar,1 +4680,Canopic jar,1 +4681,Canopic jar,1 +4682,Holy symbol,1 +4683,Unholy symbol,1 +4684,Linen,30 +4685,Picture,0 +4686,Embalming manual,0 +4687,Bucket of sap,30 +4688,Tinderbox,0 +4689,Pile of salt,20 +4690,Tinderbox,0 +4691,Sphinx's token,1 +4692,Gold leaf,1 +4693,Full bucket,6 +4694,Steam rune,20 +4695,Mist rune,20 +4696,Dust rune,20 +4697,Smoke rune,20 +4698,Mud rune,20 +4699,Lava rune,20 +4700,Sapphire lantern,600 +4701,Sapphire lantern,600 +4702,Sapphire lantern,600 +4703,Magic stone,1 +4704,Stone bowl,1 +4705,null,1 +4706,null,1 +4707,Crumbling tome,5 +4708,Ahrim's hood,13000 +4709,Ahrim's hood,13000 +4710,Ahrim's staff,85000 +4711,Ahrim's staff,85000 +4712,Ahrim's robetop,50000 +4713,Ahrim's robetop,50000 +4714,Ahrim's robeskirt,47000 +4715,Ahrim's robeskirt,47000 +4716,Dharok's helm,103000 +4717,Dharok's helm,103000 +4718,Dharok's greataxe,208000 +4719,Dharok's greataxe,208000 +4720,Dharok's platebody,280000 +4721,Dharok's platebody,280000 +4722,Dharok's platelegs,275000 +4723,Dharok's platelegs,275000 +4724,Guthan's helm,103000 +4725,Guthan's helm,103000 +4726,Guthan's warspear,100000 +4727,Guthan's warspear,100000 +4728,Guthan's platebody,280000 +4729,Guthan's platebody,280000 +4730,Guthan's chainskirt,275000 +4731,Guthan's chainskirt,275000 +4732,Karil's coif,13000 +4733,Karil's coif,13000 +4734,Karil's crossbow,160000 +4735,Karil's crossbow,160000 +4736,Karil's leathertop,50000 +4737,Karil's leathertop,50000 +4738,Karil's leatherskirt,47000 +4739,Karil's leatherskirt,47000 +4740,Bolt rack,420 +4741,null,1 +4742,null,1 +4743,null,1 +4744,null,1 +4745,Torag's helm,103000 +4746,Torag's helm,103000 +4747,Torag's hammers,160000 +4748,Torag's hammers,160000 +4749,Torag's platebody,280000 +4750,Torag's platebody,280000 +4751,Torag's platelegs,275000 +4752,Torag's platelegs,275000 +4753,Verac's helm,103000 +4754,Verac's helm,103000 +4755,Verac's flail,160000 +4756,Verac's flail,160000 +4757,Verac's brassard,280000 +4758,Verac's brassard,280000 +4759,Verac's plateskirt,275000 +4760,Verac's plateskirt,275000 +4761,null,1 +4762,null,1 +4763,null,1 +4764,null,1 +4765,null,1 +4766,null,1 +4767,null,1 +4768,null,1 +4769,null,1 +4770,null,1 +4771,null,1 +4772,null,1 +4773,Bronze brutal,5 +4774,null,1 +4775,null,1 +4776,null,1 +4777,null,1 +4778,Iron brutal,10 +4779,null,1 +4780,null,1 +4781,null,1 +4782,null,1 +4783,Steel brutal,20 +4784,null,1 +4785,null,1 +4786,null,1 +4787,null,1 +4788,Black brutal,35 +4789,null,1 +4790,null,1 +4791,null,1 +4792,null,1 +4793,Mithril brutal,50 +4794,null,1 +4795,null,1 +4796,null,1 +4797,null,1 +4798,Adamant brutal,95 +4799,null,1 +4800,null,1 +4801,null,1 +4802,null,1 +4803,Rune brutal,450 +4804,null,1 +4805,null,1 +4806,null,1 +4807,null,1 +4808,Black prism,1 +4809,Torn page,1 +4810,Ruined backpack,1 +4811,Dragon inn tankard,1 +4812,Zogre bones,1 +4813,Zogre bones,1 +4814,Sithik portrait,1 +4815,Sithik portrait,1 +4816,Signed portrait,1 +4817,Book of portraiture,1 +4818,Ogre artefact,1 +4819,Bronze nails,7 +4820,Iron nails,33 +4821,Black nails,12 +4822,Mithril nails,18 +4823,Adamantite nails,45 +4824,Rune nails,220 +4825,Unstrung comp bow,90 +4826,Unstrung comp bow,90 +4827,Comp ogre bow,180 +4828,Comp ogre bow,180 +4829,Book of 'h.a.m',1 +4830,Fayrg bones,1 +4831,Fayrg bones,1 +4832,Raurg bones,1 +4833,Raurg bones,1 +4834,Ourg bones,1 +4835,Ourg bones,1 +4836,Strange potion,1 +4837,Necromancy book,1 +4838,Cup of tea,10 +4839,Ogre gate key,1 +4840,Rogue's purse potion(unf),5 +4841,Rogue's purse potion(unf),5 +4842,Relicym's balm(4),225 +4843,Relicym's balm(4),225 +4844,Relicym's balm(3),200 +4845,Relicym's balm(3),200 +4846,Relicym's balm(2),150 +4847,Relicym's balm(2),150 +4848,Relicym's balm(1),75 +4849,Relicym's balm(1),75 +4850,Ogre coffin key,100 +4851,Ogre coffin key,100 +4852,Bonemeal,1 +4853,Bonemeal,1 +4854,Bonemeal,1 +4855,Bonemeal,1 +4856,Ahrim's hood 100,13000 +4857,Ahrim's hood 75,13000 +4858,Ahrim's hood 50,13000 +4859,Ahrim's hood 25,13000 +4860,Ahrim's hood 0,13000 +4861,Ahrim's hood 0,13000 +4862,Ahrim's staff 100,85000 +4863,Ahrim's staff 75,85000 +4864,Ahrim's staff 50,85000 +4865,Ahrim's staff 25,85000 +4866,Ahrim's staff 0,85000 +4867,Ahrim's staff 0,85000 +4868,Ahrim's top 100,50000 +4869,Ahrim's top 75,50000 +4870,Ahrim's top 50,50000 +4871,Ahrim's top 25,50000 +4872,Ahrim's top 0,50000 +4873,Ahrim's top 0,50000 +4874,Ahrim's skirt 100,47000 +4875,Ahrim's skirt 75,47000 +4876,Ahrim's skirt 50,47000 +4877,Ahrim's skirt 25,47000 +4878,Ahrim's skirt 0,47000 +4879,Ahrim's skirt 0,47000 +4880,Dharok's helm 100,103000 +4881,Dharok's helm 75,103000 +4882,Dharok's helm 50,103000 +4883,Dharok's helm 25,103000 +4884,Dharok's helm 0,103000 +4885,Dharok's helm 0,103000 +4886,Dharok's axe 100,208000 +4887,Dharok's axe 75,208000 +4888,Dharok's axe 50,208000 +4889,Dharok's axe 25,208000 +4890,Dharok's axe 0,208000 +4891,Dharok's axe 0,208000 +4892,Dharok's body 100,280000 +4893,Dharok's body 75,280000 +4894,Dharok's body 50,280000 +4895,Dharok's body 25,280000 +4896,Dharok's body 0,280000 +4897,Dharok's body 0,280000 +4898,Dharok's legs 100,275000 +4899,Dharok's legs 75,275000 +4900,Dharok's legs 50,275000 +4901,Dharok's legs 25,275000 +4902,Dharok's legs 0,275000 +4903,Dharok's legs 0,275000 +4904,Guthan's helm 100,103000 +4905,Guthan's helm 75,103000 +4906,Guthan's helm 50,103000 +4907,Guthan's helm 25,103000 +4908,Guthan's helm 0,103000 +4909,Guthan's helm 0,103000 +4910,Guthan's spear 100,100000 +4911,Guthan's spear 75,100000 +4912,Guthan's spear 50,100000 +4913,Guthan's spear 25,100000 +4914,Guthan's spear 0,100000 +4915,Guthan's spear 0,100000 +4916,Guthan's body 100,280000 +4917,Guthan's body 75,280000 +4918,Guthan's body 50,280000 +4919,Guthan's body 25,280000 +4920,Guthan's body 0,280000 +4921,Guthan's body 0,280000 +4922,Guthan's skirt 100,275000 +4923,Guthan's skirt 75,275000 +4924,Guthan's skirt 50,275000 +4925,Guthan's skirt 25,275000 +4926,Guthan's skirt 0,275000 +4927,Guthan's skirt 0,275000 +4928,Karil's coif 100,13000 +4929,Karil's coif 75,13000 +4930,Karil's coif 50,13000 +4931,Karil's coif 25,13000 +4932,Karil's coif 0,13000 +4933,Karil's coif 0,13000 +4934,Karil's x-bow 100,160000 +4935,Karil's x-bow 75,160000 +4936,Karil's x-bow 50,160000 +4937,Karil's x-bow 25,160000 +4938,Karil's x-bow 0,160000 +4939,Karil's x-bow 0,160000 +4940,Karil's top 100,50000 +4941,Karil's top 75,50000 +4942,Karil's top 50,50000 +4943,Karil's top 25,50000 +4944,Karil's top 0,50000 +4945,Karil's top 0,50000 +4946,Karil's skirt 100,47000 +4947,Karil's skirt 75,47000 +4948,Karil's skirt 50,47000 +4949,Karil's skirt 25,47000 +4950,Karil's skirt 0,47000 +4951,Karil's skirt 0,47000 +4952,Torag's helm 100,103000 +4953,Torag's helm 75,103000 +4954,Torag's helm 50,103000 +4955,Torag's helm 25,103000 +4956,Torag's helm 0,103000 +4957,Torag's helm 0,103000 +4958,Torag's hammer 100,160000 +4959,Torag's hammer 75,160000 +4960,Torag's hammer 50,160000 +4961,Torag's hammer 25,160000 +4962,Torag's hammer 0,160000 +4963,Torag's hammer 0,160000 +4964,Torag's body 100,280000 +4965,Torag's body 75,280000 +4966,Torag's body 50,280000 +4967,Torag's body 25,280000 +4968,Torag's body 0,280000 +4969,Torag's body 0,280000 +4970,Torag's legs 100,275000 +4971,Torag's legs 75,275000 +4972,Torag's legs 50,275000 +4973,Torag's legs 25,275000 +4974,Torag's legs 0,275000 +4975,Torag's legs 0,275000 +4976,Verac's helm 100,103000 +4977,Verac's helm 75,103000 +4978,Verac's helm 50,103000 +4979,Verac's helm 25,103000 +4980,Verac's helm 0,103000 +4981,Verac's helm 0,103000 +4982,Verac's flail 100,160000 +4983,Verac's flail 75,160000 +4984,Verac's flail 50,160000 +4985,Verac's flail 25,160000 +4986,Verac's flail 0,160000 +4987,Verac's flail 0,160000 +4988,Verac's top 100,280000 +4989,Verac's top 75,280000 +4990,Verac's top 50,280000 +4991,Verac's top 25,280000 +4992,Verac's top 0,280000 +4993,Verac's top 0,280000 +4994,Verac's skirt 100,275000 +4995,Verac's skirt 75,275000 +4996,Verac's skirt 50,275000 +4997,Verac's skirt 25,275000 +4998,Verac's skirt 0,275000 +4999,Verac's skirt 0,275000 +5000,null,1 +5001,Raw cave eel,15 +5002,Burnt cave eel,0 +5003,Cave eel,15 +5004,Frog spawn,5 +5005,Raw cave eel,15 +5006,Burnt cave eel,0 +5007,Cave eel,15 +5008,Brooch,1 +5009,Goblin symbol book,1 +5010,Key,1 +5011,Silverware,1 +5012,Peace treaty,1 +5013,Mining helmet,600 +5014,Mining helmet,900 +5015,Mining helmet,900 +5016,Bone spear,600 +5017,Bone spear,600 +5018,Bone club,600 +5019,Bone club,600 +5020,Minecart ticket,1 +5021,Minecart ticket,1 +5022,Minecart ticket,1 +5023,Minecart ticket,1 +5024,Woven top,650 +5025,Woven top,650 +5026,Woven top,812 +5027,Woven top,812 +5028,Woven top,845 +5029,Woven top,845 +5030,Shirt,585 +5031,Shirt,585 +5032,Shirt,780 +5033,Shirt,780 +5034,Shirt,812 +5035,Shirt,812 +5036,Trousers,715 +5037,Trousers,715 +5038,Trousers,910 +5039,Trousers,910 +5040,Trousers,975 +5041,Trousers,975 +5042,Shorts,364 +5043,Shorts,364 +5044,Shorts,468 +5045,Shorts,468 +5046,Shorts,507 +5047,Shorts,507 +5048,Skirt,455 +5049,Skirt,455 +5050,Skirt,715 +5051,Skirt,715 +5052,Skirt,812 +5053,Skirt,812 +5054,Dwarf,1 +5055,Dwarf,1 +5056,Dwarven battleaxe,1 +5057,Dwarven battleaxe,1 +5058,Dwarven battleaxe,1 +5059,Dwarven battleaxe,1 +5060,Dwarven battleaxe,1 +5061,Dwarven battleaxe,1 +5062,Left boot,1 +5063,Right boot,1 +5064,Exquisite boots,1 +5065,Book on costumes,1 +5066,Meeting notes,1 +5067,Exquisite clothes,1 +5068,Master farmer,1 +5069,null,1 +5070,Bird's nest,1 +5071,Bird's nest,1 +5072,Bird's nest,1 +5073,Bird's nest,1 +5074,Bird's nest,1 +5075,Bird's nest,1 +5076,Bird's egg,1 +5077,Bird's egg,1 +5078,Bird's egg,1 +5079,null,1 +5080,null,1 +5081,null,1 +5082,null,1 +5083,null,1 +5084,null,1 +5085,null,1 +5086,null,1 +5087,null,1 +5088,null,1 +5089,null,1 +5090,null,1 +5091,null,1 +5092,null,1 +5093,null,1 +5094,null,1 +5095,null,1 +5096,Marigold seed,84 +5097,Rosemary seed,98 +5098,Nasturtium seed,11 +5099,Woad seed,11 +5100,Limpwurt seed,12 +5101,Redberry seed,4 +5102,Cadavaberry seed,9 +5103,Dwellberry seed,25 +5104,Jangerberry seed,60 +5105,Whiteberry seed,133 +5106,Poison ivy seed,166 +5107,null,1 +5108,null,1 +5109,null,1 +5110,null,1 +5111,null,1 +5112,null,1 +5113,null,1 +5114,null,1 +5115,null,1 +5116,null,1 +5117,null,1 +5118,null,1 +5119,null,1 +5120,null,1 +5121,null,1 +5122,null,1 +5123,null,1 +5124,null,1 +5125,null,1 +5126,null,1 +5127,null,1 +5128,null,1 +5129,null,1 +5130,null,1 +5131,null,1 +5132,null,1 +5133,null,1 +5134,null,1 +5135,null,1 +5136,null,1 +5137,null,1 +5138,null,1 +5139,null,1 +5140,null,1 +5141,null,1 +5142,null,1 +5143,null,1 +5144,null,1 +5145,null,1 +5146,null,1 +5147,null,1 +5148,null,1 +5149,null,1 +5150,null,1 +5151,null,1 +5152,null,1 +5153,null,1 +5154,null,1 +5155,null,1 +5156,null,1 +5157,null,1 +5158,null,1 +5159,null,1 +5160,null,1 +5161,null,1 +5162,null,1 +5163,null,1 +5164,null,1 +5165,null,1 +5166,null,1 +5167,null,1 +5168,null,1 +5169,null,1 +5170,null,1 +5171,Seeds,1 +5172,null,1 +5173,null,1 +5174,null,1 +5175,null,1 +5176,null,1 +5177,null,1 +5178,null,1 +5179,null,1 +5180,null,1 +5181,null,1 +5182,null,1 +5183,null,1 +5184,null,1 +5185,null,1 +5186,null,1 +5187,null,1 +5188,null,1 +5189,null,1 +5190,null,1 +5191,null,1 +5192,null,1 +5193,null,1 +5194,null,1 +5195,null,1 +5196,null,1 +5197,null,1 +5198,null,1 +5199,null,1 +5200,null,1 +5201,null,1 +5202,null,1 +5203,null,1 +5204,null,1 +5205,null,1 +5206,null,1 +5207,null,1 +5208,null,1 +5209,null,1 +5210,null,1 +5211,null,1 +5212,null,1 +5213,null,1 +5214,null,1 +5215,null,1 +5216,null,1 +5217,null,1 +5218,null,1 +5219,null,1 +5220,null,1 +5221,null,1 +5222,null,1 +5223,null,1 +5224,null,1 +5225,null,1 +5226,null,1 +5227,null,1 +5228,null,1 +5229,null,1 +5230,null,1 +5231,null,1 +5232,null,1 +5233,null,1 +5234,null,1 +5235,null,1 +5236,null,1 +5237,null,1 +5238,null,1 +5239,null,1 +5240,null,1 +5241,null,1 +5242,null,1 +5243,null,1 +5244,null,1 +5245,null,1 +5246,null,1 +5247,null,1 +5248,null,1 +5249,null,1 +5250,null,1 +5251,null,1 +5252,null,1 +5253,null,1 +5254,null,1 +5255,null,1 +5256,null,1 +5257,null,1 +5258,null,1 +5259,null,1 +5260,null,1 +5261,null,1 +5262,null,1 +5263,null,1 +5264,null,1 +5265,null,1 +5266,null,1 +5267,null,1 +5268,null,1 +5269,null,1 +5270,null,1 +5271,null,1 +5272,null,1 +5273,null,1 +5274,null,1 +5275,null,1 +5276,null,1 +5277,null,1 +5278,null,1 +5279,null,1 +5280,Cactus seed,99 +5281,Belladonna seed,177 +5282,Mushroom spore,86 +5283,Apple tree seed,13 +5284,Banana tree seed,20 +5285,Orange tree seed,31 +5286,Curry tree seed,39 +5287,Pineapple seed,74 +5288,Papaya tree seed,115 +5289,Palm tree seed,254 +5290,Calquat tree seed,340 +5291,Guam seed,4 +5292,Marrentill seed,5 +5293,Tarromin seed,7 +5294,Harralander seed,12 +5295,Ranarr seed,19 +5296,Toadflax seed,34 +5297,Irit seed,64 +5298,Avantoe seed,64 +5299,Kwuarm seed,64 +5300,Snapdragon seed,64 +5301,Cadantine seed,64 +5302,Lantadyme seed,64 +5303,Dwarf weed seed,64 +5304,Torstol seed,64 +5305,Barley seed,38 +5306,Jute seed,86 +5307,Hammerstone seed,52 +5308,Asgarnian seed,60 +5309,Yanillian seed,210 +5310,Krandorian seed,8 +5311,Wildblood seed,14 +5312,Acorn,6 +5313,Willow seed,16 +5314,Maple seed,48 +5315,Yew seed,143 +5316,Magic seed,422 +5317,Spirit seed,1 +5318,Potato seed,8 +5319,Onion seed,10 +5320,Sweetcorn seed,8 +5321,Watermelon seed,56 +5322,Tomato seed,4 +5323,Strawberry seed,18 +5324,Cabbage seed,25 +5325,Gardening trowel,12 +5326,Gardening trowel,12 +5327,Spade handle,1 +5328,Spade head,1 +5329,Secateurs,5 +5330,Secateurs,5 +5331,Watering can,8 +5332,Watering can,8 +5333,Watering can(1),1 +5334,Watering can(2),1 +5335,Watering can(3),1 +5336,Watering can(4),1 +5337,Watering can(5),1 +5338,Watering can(6),1 +5339,Watering can(7),1 +5340,Watering can(8),1 +5341,Rake,6 +5342,Rake,6 +5343,Seed dibber,6 +5344,Seed dibber,6 +5345,Gardening boots,25 +5346,Gardening boots,25 +5347,Rake handle,1 +5348,Rake head,1 +5349,null,1 +5350,Plant pot,1 +5351,Plant pot,1 +5352,Unfired plant pot,1 +5353,Unfired plant pot,1 +5354,Plant pot,1 +5355,Plant pot,1 +5356,Plant pot,1 +5357,Plant pot,1 +5358,Oak seedling,1 +5359,Willow seedling,1 +5360,Maple seedling,1 +5361,Yew seedling,1 +5362,Magic seedling,1 +5363,Spirit seedling,1 +5364,Oak seedling,1 +5365,Willow seedling,1 +5366,Maple seedling,1 +5367,Yew seedling,1 +5368,Magic seedling,1 +5369,Spirit seedling,1 +5370,Oak sapling,1 +5371,Willow sapling,1 +5372,Maple sapling,1 +5373,Yew sapling,1 +5374,Magic sapling,1 +5375,Spirit sapling,1 +5376,Basket,1 +5377,Basket,1 +5378,Apples(1),1 +5379,Apples(1),1 +5380,Apples(2),1 +5381,Apples(2),1 +5382,Apples(3),1 +5383,Apples(3),1 +5384,Apples(4),1 +5385,Apples(4),1 +5386,Apples(5),1 +5387,Apples(5),1 +5388,Oranges(1),1 +5389,Oranges(1),1 +5390,Oranges(2),1 +5391,Oranges(2),1 +5392,Oranges(3),1 +5393,Oranges(3),1 +5394,Oranges(4),1 +5395,Oranges(4),1 +5396,Oranges(5),1 +5397,Oranges(5),1 +5398,Strawberries(1),1 +5399,Strawberries(1),1 +5400,Strawberries(2),1 +5401,Strawberries(2),1 +5402,Strawberries(3),1 +5403,Strawberries(3),1 +5404,Strawberries(4),1 +5405,Strawberries(4),1 +5406,Strawberries(5),1 +5407,Strawberries(5),1 +5408,Bananas(1),1 +5409,Bananas(1),1 +5410,Bananas(2),1 +5411,Bananas(2),1 +5412,Bananas(3),1 +5413,Bananas(3),1 +5414,Bananas(4),1 +5415,Bananas(4),1 +5416,Bananas(5),1 +5417,Bananas(5),1 +5418,Empty sack,1 +5419,Empty sack,1 +5420,Potatoes(1),1 +5421,Potatoes(1),1 +5422,Potatoes(2),1 +5423,Potatoes(2),1 +5424,Potatoes(3),1 +5425,Potatoes(3),1 +5426,Potatoes(4),1 +5427,Potatoes(4),1 +5428,Potatoes(5),1 +5429,Potatoes(5),1 +5430,Potatoes(6),1 +5431,Potatoes(6),1 +5432,Potatoes(7),1 +5433,Potatoes(7),1 +5434,Potatoes(8),1 +5435,Potatoes(8),1 +5436,Potatoes(9),1 +5437,Potatoes(9),1 +5438,Potatoes(10),1 +5439,Potatoes(10),1 +5440,Onions(1),1 +5441,Onions(1),1 +5442,Onions(2),1 +5443,Onions(2),1 +5444,Onions(3),1 +5445,Onions(3),1 +5446,Onions(4),1 +5447,Onions(4),1 +5448,Onions(5),1 +5449,Onions(5),1 +5450,Onions(6),1 +5451,Onions(6),1 +5452,Onions(7),1 +5453,Onions(7),1 +5454,Onions(8),1 +5455,Onions(8),1 +5456,Onions(9),1 +5457,Onions(9),1 +5458,Onions(10),1 +5459,Onions(10),1 +5460,Cabbages(1),1 +5461,Cabbages(1),1 +5462,Cabbages(2),1 +5463,Cabbages(2),1 +5464,Cabbages(3),1 +5465,Cabbages(3),1 +5466,Cabbages(4),1 +5467,Cabbages(4),1 +5468,Cabbages(5),1 +5469,Cabbages(5),1 +5470,Cabbages(6),1 +5471,Cabbages(6),1 +5472,Cabbages(7),1 +5473,Cabbages(7),1 +5474,Cabbages(8),1 +5475,Cabbages(8),1 +5476,Cabbages(9),1 +5477,Cabbages(9),1 +5478,Cabbages(10),1 +5479,Cabbages(10),1 +5480,Apple seedling,1 +5481,Banana seedling,1 +5482,Orange seedling,1 +5483,Curry seedling,1 +5484,Pineapple seedling,1 +5485,Papaya seedling,1 +5486,Palm seedling,1 +5487,Calquat seedling,1 +5488,Apple seedling,1 +5489,Banana seedling,1 +5490,Orange seedling,1 +5491,Curry seedling,1 +5492,Pineapple seedling,1 +5493,Papaya seedling,1 +5494,Palm seedling,1 +5495,Calquat seedling,1 +5496,Apple sapling,1 +5497,Banana sapling,1 +5498,Orange sapling,1 +5499,Curry sapling,1 +5500,Pineapple sapling,1 +5501,Papaya sapling,1 +5502,Palm sapling,1 +5503,Calquat sapling,1 +5504,Strawberry,17 +5505,Strawberry,17 +5506,Old man's message,1 +5507,Strange book,1 +5508,Book of folklore,1 +5509,Small pouch,150 +5510,Medium pouch,300 +5511,Medium pouch,300 +5512,Large pouch,600 +5513,Large pouch,600 +5514,Giant pouch,1200 +5515,Giant pouch,1200 +5516,Elemental talisman,500 +5517,Elemental talisman,500 +5518,Scrying orb,1 +5519,Scrying orb,1 +5520,Abyssal book,10 +5521,Binding necklace,1425 +5522,Binding necklace,1425 +5523,Tiara mould,100 +5524,Tiara mould,100 +5525,Tiara,100 +5526,Tiara,100 +5527,Air tiara,100 +5528,Air tiara,100 +5529,Mind tiara,100 +5530,Mind tiara,100 +5531,Water tiara,100 +5532,Water tiara,100 +5533,Body tiara,100 +5534,Body tiara,100 +5535,Earth tiara,100 +5536,Earth tiara,100 +5537,Fire tiara,100 +5538,Fire tiara,100 +5539,Cosmic tiara,100 +5540,Cosmic tiara,100 +5541,Nature tiara,100 +5542,Nature tiara,100 +5543,Chaos tiara,100 +5544,Chaos tiara,100 +5545,Law tiara,100 +5546,Law tiara,100 +5547,Death tiara,100 +5548,Death tiara,100 +5549,Blood tiara,100 +5550,Blood tiara,100 +5551,Soul tiara,100 +5552,Soul tiara,100 +5553,Rogue top,625 +5554,Rogue mask,375 +5555,Rogue trousers,500 +5556,Rogue gloves,250 +5557,Rogue boots,250 +5558,Rogue kit,50 +5559,Flash powder,1 +5560,Stethoscope,10 +5561,Mystic jewel,1 +5562,Picture,1 +5563,Picture,1 +5564,Picture,1 +5565,Picture,1 +5566,Picture,1 +5567,Picture,1 +5568,Picture,1 +5569,Picture,1 +5570,Picture,1 +5571,Picture,1 +5572,Dial,1 +5573,null,1 +5574,Initiate sallet,6000 +5575,Initiate hauberk,10000 +5576,Initiate cuisse,8000 +5577,Cupric sulphate,1 +5578,Acetic acid,1 +5579,Gypsum,1 +5580,Sodium chloride,1 +5581,Nitrous oxide,1 +5582,Vial of liquid,1 +5583,Tin ore powder,1 +5584,Cupric ore powder,1 +5585,Bronze key,1 +5586,Metal spade,1 +5587,Metal spade,1 +5588,Alchemical notes,1 +5589,??? mixture,1 +5590,??? mixture,1 +5591,??? mixture,1 +5592,Tin,10 +5593,Tin,20 +5594,Tin,20 +5595,Tin,20 +5596,Tin,20 +5597,Tin,20 +5598,Tin,20 +5599,Tin,20 +5600,Tin,20 +5601,Chisel,1 +5602,Bronze wire,20 +5603,Shears,1 +5604,Magnet,3 +5605,Knife,6 +5606,Makeover voucher,1 +5607,Grain,1 +5608,Fox,1 +5609,Chicken,1 +5610,Hourglass,1 +5611,Initiate sallet,6000 +5612,Initiate hauberk,10000 +5613,Initiate cuisse,8000 +5614,Magic carpet,1 +5615,Bonemeal,1 +5616,Bronze arrow(p+),1 +5617,Iron arrow(p+),3 +5618,Steel arrow(p+),12 +5619,Mithril arrow(p+),32 +5620,Adamant arrow(p+),80 +5621,Rune arrow(p+),400 +5622,Bronze arrow(p++),1 +5623,Iron arrow(p++),3 +5624,Steel arrow(p++),12 +5625,Mithril arrow(p++),32 +5626,Adamant arrow(p++),80 +5627,Rune arrow(p++),400 +5628,Bronze dart(p+),1 +5629,Iron dart(p+),2 +5630,Steel dart(p+),10 +5631,Black dart(p+),18 +5632,Mithril dart(p+),25 +5633,Adamant dart(p+),65 +5634,Rune dart(p+),350 +5635,Bronze dart(p++),1 +5636,Iron dart(p++),2 +5637,Steel dart(p++),10 +5638,Black dart(p++),18 +5639,Mithril dart(p++),25 +5640,Adamant dart(p++),65 +5641,Rune dart(p++),350 +5642,Bronze javelin(p+),4 +5643,Iron javelin(p+),6 +5644,Steel javelin(p+),24 +5645,Mithril javelin(p+),64 +5646,Adamant javelin(p+),160 +5647,Rune javelin(p+),400 +5648,Bronze jav'n(p++),4 +5649,Iron javelin(p++),6 +5650,Steel javelin(p++),24 +5651,Mithril javelin(p++),64 +5652,Adamant javelin(p++),160 +5653,Rune javelin(p++),400 +5654,Bronze knife(p+),1 +5655,Iron knife(p+),3 +5656,Steel knife(p+),10 +5657,Mithril knife(p+),27 +5658,Black knife(p+),18 +5659,Adamant knife(p+),66 +5660,Rune knife(p+),166 +5661,Bronze knife(p++),1 +5662,Iron knife(p++),3 +5663,Steel knife(p++),10 +5664,Mithril knife(p++),27 +5665,Black knife(p++),18 +5666,Adamant knife(p++),66 +5667,Rune knife(p++),166 +5668,Iron dagger(p+),35 +5669,Iron dagger(p+),35 +5670,Bronze dagger(p+),10 +5671,Bronze dagger(p+),10 +5672,Steel dagger(p+),125 +5673,Steel dagger(p+),125 +5674,Mithril dagger(p+),325 +5675,Mithril dagger(p+),325 +5676,Adamant dagger(p+),800 +5677,Adamant dagger(p+),800 +5678,Rune dagger(p+),8000 +5679,Rune dagger(p+),8000 +5680,Dragon dagger(p+),24000 +5681,Dragon dagger(p+),24000 +5682,Black dagger(p+),240 +5683,Black dagger(p+),240 +5684,Poison dagger(p+),565 +5685,Poison dagger(p+),565 +5686,Iron dagger(p++),35 +5687,Iron dagger(p++),35 +5688,Br'ze dagger(p++),10 +5689,Br'ze dagger(p++),10 +5690,Steel dagger(p++),125 +5691,Steel dagger(p++),125 +5692,Mithril dagger(p++),325 +5693,Mithril dagger(p++),325 +5694,Adamant dagger(p++),800 +5695,Adamant dagger(p++),800 +5696,Rune dagger(p++),8000 +5697,Rune dagger(p++),8000 +5698,Dragon dagger(p++),24000 +5699,Dragon dagger(p++),24000 +5700,Black dagger(p++),240 +5701,Black dagger(p++),240 +5702,Poison dagger(p++),565 +5703,Poison dagger(p++),565 +5704,Bronze spear(p+),26 +5705,Bronze spear(p+),26 +5706,Iron spear(p+),91 +5707,Iron spear(p+),91 +5708,Steel spear(p+),325 +5709,Steel spear(p+),325 +5710,Mithril spear(p+),845 +5711,Mithril spear(p+),845 +5712,Adamant spear(p+),2080 +5713,Adamant spear(p+),2080 +5714,Rune spear(p+),20800 +5715,Rune spear(p+),20800 +5716,Dragon spear(p+),62400 +5717,Dragon spear(p+),62400 +5718,Bronze spear(p++),26 +5719,Bronze spear(p++),26 +5720,Iron spear(p++),91 +5721,Iron spear(p++),91 +5722,Steel spear(p++),325 +5723,Steel spear(p++),325 +5724,Mithril spear(p++),845 +5725,Mithril spear(p++),845 +5726,Adamant spear(p++),2080 +5727,Adamant spear(p++),2080 +5728,Rune spear(p++),20800 +5729,Rune spear(p++),20800 +5730,Dragon spear(p++),62400 +5731,Dragon spear(p++),62400 +5732,Stool,1 +5733,Rotten potato,1 +5734,Black spear(p+),750 +5735,Black spear(p+),750 +5736,Black spear(p++),750 +5737,Black spear(p++),750 +5738,Woad leaf,1 +5739,Asgarnian ale(m),2 +5740,Asgarnian ale(m),2 +5741,Mature wmb,2 +5742,Mature wmb,2 +5743,Greenman's ale(m),2 +5744,Greenman's ale(m),2 +5745,Dragon bitter(m),2 +5746,Dragon bitter(m),2 +5747,Dwarven stout(m),2 +5748,Dwarven stout(m),2 +5749,Moonlight mead(m),5 +5750,Moonlight mead(m),5 +5751,Axeman's folly,2 +5752,Axeman's folly,2 +5753,Axeman's folly(m),2 +5754,Axeman's folly(m),2 +5755,Chef's delight,2 +5756,Chef's delight,2 +5757,Chef's delight(m),2 +5758,Chef's delight(m),2 +5759,Slayer's respite,2 +5760,Slayer's respite,2 +5761,Slayer's respite(m),2 +5762,Slayer's respite(m),2 +5763,Cider,2 +5764,Cider,2 +5765,Mature cider,2 +5766,Mature cider,2 +5767,Ale yeast,1 +5768,Ale yeast,1 +5769,Calquat keg,1 +5770,Calquat keg,1 +5771,Dwarven stout(1),1 +5772,Dwarven stout(1),1 +5773,Dwarven stout(2),1 +5774,Dwarven stout(2),1 +5775,Dwarven stout(3),1 +5776,Dwarven stout(3),1 +5777,Dwarven stout(4),1 +5778,Dwarven stout(4),1 +5779,Asgarnian ale(1),1 +5780,Asgarnian ale(1),1 +5781,Asgarnian ale(2),1 +5782,Asgarnian ale(2),1 +5783,Asgarnian ale(3),1 +5784,Asgarnian ale(3),1 +5785,Asgarnian ale(4),1 +5786,Asgarnian ale(4),1 +5787,Greenmans ale(1),1 +5788,Greenmans ale(1),1 +5789,Greenmans ale(2),1 +5790,Greenmans ale(2),1 +5791,Greenmans ale(3),1 +5792,Greenmans ale(3),1 +5793,Greenmans ale(4),1 +5794,Greenmans ale(4),1 +5795,Mind bomb(1),1 +5796,Mind bomb(1),1 +5797,Mind bomb(2),1 +5798,Mind bomb(2),1 +5799,Mind bomb(3),1 +5800,Mind bomb(3),1 +5801,Mind bomb(4),1 +5802,Mind bomb(4),1 +5803,Dragon bitter(1),1 +5804,Dragon bitter(1),1 +5805,Dragon bitter(2),1 +5806,Dragon bitter(2),1 +5807,Dragon bitter(3),1 +5808,Dragon bitter(3),1 +5809,Dragon bitter(4),1 +5810,Dragon bitter(4),1 +5811,Moonlight mead(1),1 +5812,Moonlight mead(1),1 +5813,Moonlight mead(2),1 +5814,Moonlight mead(2),1 +5815,Moonlight mead(3),1 +5816,Moonlight mead(3),1 +5817,Moonlight mead(4),1 +5818,Moonlight mead(4),1 +5819,Axeman's folly(1),1 +5820,Axeman's folly(1),1 +5821,Axeman's folly(2),1 +5822,Axeman's folly(2),1 +5823,Axeman's folly(3),1 +5824,Axeman's folly(3),1 +5825,Axeman's folly(4),1 +5826,Axeman's folly(4),1 +5827,Chef's delight(1),1 +5828,Chef's delight(1),1 +5829,Chef's delight(2),1 +5830,Chef's delight(2),1 +5831,Chef's delight(3),1 +5832,Chef's delight(3),1 +5833,Chef's delight(4),1 +5834,Chef's delight(4),1 +5835,Slayer's respite(1),1 +5836,Slayer's respite(1),1 +5837,Slayer's respite(2),1 +5838,Slayer's respite(2),1 +5839,Slayer's respite(3),1 +5840,Slayer's respite(3),1 +5841,Slayer's respite(4),1 +5842,Slayer's respite(4),1 +5843,Cider(1),1 +5844,Cider(1),1 +5845,Cider(2),1 +5846,Cider(2),1 +5847,Cider(3),1 +5848,Cider(3),1 +5849,Cider(4),1 +5850,Cider(4),1 +5851,Dwarven stout(m1),1 +5852,Dwarven stout(m1),1 +5853,Dwarven stout(m2),1 +5854,Dwarven stout(m2),1 +5855,Dwarven stout(m3),1 +5856,Dwarven stout(m3),1 +5857,Dwarven stout(m4),1 +5858,Dwarven stout(m4),1 +5859,Asgarnian ale(m1),1 +5860,Asgarnian ale(m1),1 +5861,Asgarnian ale(m2),1 +5862,Asgarnian ale(m2),1 +5863,Asgarnian ale(m3),1 +5864,Asgarnian ale(m3),1 +5865,Asgarnian ale(m4),1 +5866,Asgarnian ale(m4),1 +5867,Greenmans ale(m1),1 +5868,Greenmans ale(m1),1 +5869,Greenmans ale(m2),1 +5870,Greenmans ale(m2),1 +5871,Greenmans ale(m3),1 +5872,Greenmans ale(m3),1 +5873,Greenmans ale(m4),1 +5874,Greenmans ale(m4),1 +5875,Mind bomb(m1),1 +5876,Mind bomb(m1),1 +5877,Mind bomb(m2),1 +5878,Mind bomb(m2),1 +5879,Mind bomb(m3),1 +5880,Mind bomb(m3),1 +5881,Mind bomb(m4),1 +5882,Mind bomb(m4),1 +5883,Dragon bitter(m1),1 +5884,Dragon bitter(m1),1 +5885,Dragon bitter(m2),1 +5886,Dragon bitter(m2),1 +5887,Dragon bitter(m3),1 +5888,Dragon bitter(m3),1 +5889,Dragon bitter(m4),1 +5890,Dragon bitter(m4),1 +5891,M'light mead(m1),1 +5892,M'light mead(m1),1 +5893,M'light mead(m2),1 +5894,M'light mead(m2),1 +5895,M'light mead(m3),1 +5896,M'light mead(m3),1 +5897,M'light mead(m4),1 +5898,M'light mead(m4),1 +5899,Axeman's folly(m1),1 +5900,Axeman's folly(m1),1 +5901,Axeman's folly(m2),1 +5902,Axeman's folly(m2),1 +5903,Axeman's folly(m3),1 +5904,Axeman's folly(m3),1 +5905,Axeman's folly(m4),1 +5906,Axeman's folly(m4),1 +5907,Chef's delight(m1),1 +5908,Chef's delight(m1),1 +5909,Chef's delight(m2),1 +5910,Chef's delight(m2),1 +5911,Chef's delight(m3),1 +5912,Chef's delight(m3),1 +5913,Chef's delight(m4),1 +5914,Chef's delight(m4),1 +5915,Slayer respite(m1),1 +5916,Slayer respite(m1),1 +5917,Slayer respite(m2),1 +5918,Slayer respite(m2),1 +5919,Slayer respite(m3),1 +5920,Slayer respite(m3),1 +5921,Slayer respite(m4),1 +5922,Slayer respite(m4),1 +5923,Cider(m1),1 +5924,Cider(m1),1 +5925,Cider(m2),1 +5926,Cider(m2),1 +5927,Cider(m3),1 +5928,Cider(m3),1 +5929,Cider(m4),1 +5930,Cider(m4),1 +5931,Jute fibre,6 +5932,Jute fibre,6 +5933,Willow branch,2 +5934,Willow branch,2 +5935,Coconut milk,1 +5936,Weapon poison+(unf),1 +5937,Weapon poison+,288 +5938,Weapon poison+,288 +5939,Weapon poison++(unf),14 +5940,Weapon poison++,432 +5941,Weapon poison++,432 +5942,Antipoison+(unf),14 +5943,Antipoison+(4),360 +5944,Antipoison+(4),360 +5945,Antipoison+(3),288 +5946,Antipoison+(3),288 +5947,Antipoison+(2),216 +5948,Antipoison+(2),216 +5949,Antipoison+(1),144 +5950,Antipoison+(1),144 +5951,Antipoison++(unf),14 +5952,Antipoison++(4),360 +5953,Antipoison++(4),360 +5954,Antipoison++(3),288 +5955,Antipoison++(3),288 +5956,Antipoison++(2),216 +5957,Antipoison++(2),216 +5958,Antipoison++(1),144 +5959,Antipoison++(1),144 +5960,Tomatoes(1),1 +5961,Tomatoes(1),1 +5962,Tomatoes(2),1 +5963,Tomatoes(2),1 +5964,Tomatoes(3),1 +5965,Tomatoes(3),1 +5966,Tomatoes(4),1 +5967,Tomatoes(4),1 +5968,Tomatoes(5),1 +5969,Tomatoes(5),1 +5970,Curry leaf,19 +5971,Curry leaf,19 +5972,Papaya fruit,64 +5973,Papaya fruit,64 +5974,Coconut,87 +5975,Coconut,87 +5976,Coconut,87 +5977,Coconut,87 +5978,Coconut shell,1 +5979,Coconut shell,1 +5980,Calquat fruit,54 +5981,Calquat fruit,54 +5982,Watermelon,48 +5983,Watermelon,48 +5984,Watermelon slice,16 +5985,Watermelon slice,16 +5986,Sweetcorn,9 +5987,Sweetcorn,9 +5988,Cooked sweetcorn,9 +5989,Cooked sweetcorn,9 +5990,Burnt sweetcorn,1 +5991,Burnt sweetcorn,1 +5992,Apple mush,13 +5993,Apple mush,13 +5994,Hammerstone hops,4 +5995,Hammerstone hops,4 +5996,Asgarnian hops,5 +5997,Asgarnian hops,5 +5998,Yanillian hops,7 +5999,Yanillian hops,7 +6000,Krandorian hops,10 +6001,Krandorian hops,10 +6002,Wildblood hops,15 +6003,Wildblood hops,15 +6004,Mushroom,38 +6005,Mushroom,38 +6006,Barley,4 +6007,Barley,4 +6008,Barley malt,4 +6009,Barley malt,4 +6010,Marigolds,1 +6011,Marigolds,1 +6012,Nasturtiums,4 +6013,Nasturtiums,4 +6014,Rosemary,2 +6015,Rosemary,2 +6016,Cactus spine,1 +6017,Cactus spine,1 +6018,Poison ivy berries,65 +6019,Poison ivy berries,65 +6020,Leaves,1 +6021,Leaves,1 +6022,Leaves,1 +6023,Leaves,1 +6024,Leaves,1 +6025,Leaves,1 +6026,Leaves,1 +6027,Leaves,1 +6028,Leaves,1 +6029,Leaves,1 +6030,Leaves,1 +6031,Leaves,1 +6032,Compost,20 +6033,Compost,20 +6034,Supercompost,85 +6035,Supercompost,85 +6036,Plant cure,40 +6037,Plant cure,40 +6038,Magic string,1 +6039,Magic string,1 +6040,Amulet of nature,1 +6041,Pre-nature amulet,1 +6042,Pre-nature amulet,1 +6043,Oak roots,1 +6044,Oak roots,1 +6045,Willow roots,1 +6046,Willow roots,1 +6047,Maple roots,1 +6048,Maple roots,1 +6049,Yew roots,1 +6050,Yew roots,1 +6051,Magic roots,1 +6052,Magic roots,1 +6053,Spirit roots,1 +6054,Spirit roots,1 +6055,Weeds,1 +6056,Weeds,1 +6057,Hay sack,1 +6058,Hay sack,1 +6059,Scarecrow,1 +6060,Stool,1 +6061,Bronze bolts(p+),3 +6062,Bronze bolts(p++),3 +6063,Spirit tree,1 +6064,Bloody mourner top,20 +6065,Mourner top,150 +6066,Mourner trousers,20 +6067,Mourner trousers,100 +6068,Mourner gloves,20 +6069,Mourner boots,30 +6070,Mourner cloak,50 +6071,Mourner letter,1 +6072,Tegid's soap,10 +6073,Prifddinas' history,2 +6074,Picture,0 +6075,Eastern discovery,2 +6076,Picture,0 +6077,Eastern settlement,2 +6078,Picture,0 +6079,The great divide,2 +6080,Picture,0 +6081,Broken device,10 +6082,Fixed device,150 +6083,Tarnished key,1 +6084,Worn key,1 +6085,Red dye bellows,20 +6086,Blue dye bellows,20 +6087,Yellow dye bellows,20 +6088,Green dye bellows,20 +6089,Blue toad,1 +6090,Red toad,1 +6091,Yellow toad,1 +6092,Green toad,1 +6093,Rotten apples,1 +6094,Apple barrel,1 +6095,Naphtha apple mix,1 +6096,Toxic naphtha,1 +6097,Sieve,10 +6098,Toxic powder,50 +6099,Teleport crystal (4),50 +6100,Teleport crystal (3),45 +6101,Teleport crystal (2),35 +6102,Teleport crystal (1),15 +6103,Tiny elf crystal,1 +6104,New key,1 +6105,Elf,1 +6106,Ghostly boots,300 +6107,Ghostly robe,300 +6108,Ghostly robe,300 +6109,Ghostly hood,300 +6110,Ghostly gloves,300 +6111,Ghostly cloak,250 +6112,Kelda seed,2 +6113,Kelda hops,4 +6114,null,1 +6115,null,1 +6116,null,1 +6117,null,1 +6118,Kelda stout,2 +6119,Square stone,1 +6120,Square stone,1 +6121,Letter,1 +6122,A chair,1 +6123,Beer glass,1 +6124,Coconut milk,1 +6125,Enchanted lyre(2),1000 +6126,Enchanted lyre(3),1000 +6127,Enchanted lyre(4),1000 +6128,Rock-shell helm,35200 +6129,Rock-shell plate,65000 +6130,Rock-shell legs,64000 +6131,Spined helm,60000 +6132,Spined helm,60000 +6133,Spined body,7800 +6134,Spined body,7800 +6135,Spined chaps,3900 +6136,Spined chaps,3900 +6137,Skeletal helm,10000 +6138,Skeletal helm,10000 +6139,Skeletal top,45000 +6140,Skeletal top,45000 +6141,Skeletal bottoms,40000 +6142,Skeletal bottoms,40000 +6143,Spined boots,650 +6144,Spined boots,650 +6145,Rock-shell boots,650 +6146,Rock-shell boots,650 +6147,Skeletal boots,650 +6148,Skeletal boots,650 +6149,Spined gloves,650 +6150,Spined gloves,650 +6151,Rock-shell gloves,650 +6152,Rock-shell gloves,650 +6153,Skeletal gloves,650 +6154,Skeletal gloves,650 +6155,Dagannoth hide,60 +6156,Dagannoth hide,60 +6157,Rock-shell chunk,60 +6158,Rock-shell chunk,60 +6159,Rock-shell shard,60 +6160,Rock-shell shard,60 +6161,Rock-shell splinter,60 +6162,Rock-shell splinter,60 +6163,Skull piece,60 +6164,Skull piece,60 +6165,Ribcage piece,60 +6166,Ribcage piece,60 +6167,Fibula piece,60 +6168,Fibula piece,60 +6169,Circular hide,60 +6170,Circular hide,60 +6171,Flattened hide,60 +6172,Flattened hide,60 +6173,Stretched hide,60 +6174,Stretched hide,60 +6175,Rock-shell helm,35200 +6176,Rock-shell plate,65000 +6177,Rock-shell legs,64000 +6178,Raw pheasant,5 +6179,Raw pheasant,5 +6180,Lederhosen top,1 +6181,Lederhosen shorts,1 +6182,Lederhosen hat,1 +6183,Frog token,0 +6184,Prince tunic,0 +6185,Prince leggings,0 +6186,Princess blouse,0 +6187,Princess skirt,0 +6188,Frog mask,0 +6189,null,1 +6190,null,1 +6191,null,1 +6192,null,1 +6193,null,1 +6194,null,1 +6195,null,1 +6196,null,1 +6197,null,1 +6198,null,1 +6199,Mystery box,1 +6200,Raw fishlike thing,0 +6201,Picture,1 +6202,Fishlike thing,0 +6203,Picture,1 +6204,Raw fishlike thing,0 +6205,Picture,1 +6206,Fishlike thing,0 +6207,Picture,1 +6208,Man speak amulet,1 +6209,Small fishing net,5 +6210,Picture,1 +6211,Teak pyre logs,100 +6212,Teak pyre logs,100 +6213,Mahogany pyre log,200 +6214,Mahogany pyre log,200 +6215,Broodoo shield (10),3000 +6216,Broodoo shield (10),3000 +6217,Broodoo shield (9),2750 +6218,Broodoo shield (9),2750 +6219,Broodoo shield (8),3000 +6220,Broodoo shield (8),3000 +6221,Broodoo shield (7),3000 +6222,Broodoo shield (7),3000 +6223,Broodoo shield (6),3000 +6224,Broodoo shield (6),3000 +6225,Broodoo shield (5),3000 +6226,Broodoo shield (5),3000 +6227,Broodoo shield (4),3000 +6228,Broodoo shield (4),3000 +6229,Broodoo shield (3),3000 +6230,Broodoo shield (3),3000 +6231,Broodoo shield (2),3000 +6232,Broodoo shield (2),3000 +6233,Broodoo shield (1),3000 +6234,Broodoo shield (1),3000 +6235,Broodoo shield,3000 +6236,Broodoo shield,3000 +6237,Broodoo shield (10),3000 +6238,Broodoo shield (10),3000 +6239,Broodoo shield (9),3000 +6240,Broodoo shield (9),3000 +6241,Broodoo shield (8),3000 +6242,Broodoo shield (8),3000 +6243,Broodoo shield (7),3000 +6244,Broodoo shield (7),3000 +6245,Broodoo shield (6),3000 +6246,Broodoo shield (6),3000 +6247,Broodoo shield (5),3000 +6248,Broodoo shield (5),3000 +6249,Broodoo shield (4),3000 +6250,Broodoo shield (4),3000 +6251,Broodoo shield (3),3000 +6252,Broodoo shield (3),3000 +6253,Broodoo shield (2),3000 +6254,Broodoo shield (2),3000 +6255,Broodoo shield (1),3000 +6256,Broodoo shield (1),3000 +6257,Broodoo shield,3000 +6258,Broodoo shield,3000 +6259,Broodoo shield (10),3000 +6260,Broodoo shield (10),3000 +6261,Broodoo shield (9),3000 +6262,Broodoo shield (9),3000 +6263,Broodoo shield (8),3000 +6264,Broodoo shield (8),3000 +6265,Broodoo shield (7),3000 +6266,Broodoo shield (7),3000 +6267,Broodoo shield (6),3000 +6268,Broodoo shield (6),3000 +6269,Broodoo shield (5),3000 +6270,Broodoo shield (5),3000 +6271,Broodoo shield (4),3000 +6272,Broodoo shield (4),3000 +6273,Broodoo shield (3),3000 +6274,Broodoo shield (3),3000 +6275,Broodoo shield (2),3000 +6276,Broodoo shield (2),3000 +6277,Broodoo shield (1),3000 +6278,Broodoo shield (1),3000 +6279,Broodoo shield,3000 +6280,Broodoo shield,3000 +6281,Thatch spar light,10 +6282,Thatch spar light,10 +6283,Thatch spar med,15 +6284,Thatch spar med,15 +6285,Thatch spar dense,20 +6286,Thatch spar dense,20 +6287,Snake hide,35 +6288,Snake hide,35 +6289,Snakeskin,50 +6290,Snakeskin,50 +6291,Spider carcass,15 +6292,Spider carcass,15 +6293,Spider on stick,25 +6294,Spider on stick,25 +6295,Spider on shaft,20 +6296,Spider on shaft,20 +6297,Spider on stick,50 +6298,Spider on stick,50 +6299,Spider on shaft,40 +6300,Spider on shaft,40 +6301,Burnt spider,1 +6302,Burnt spider,1 +6303,Spider on shaft,1 +6304,Spider on shaft,1 +6305,Skewer stick,10 +6306,Trading sticks,1 +6307,null,1 +6308,null,1 +6309,null,1 +6310,null,1 +6311,Gout tuber,200 +6312,Gout tuber,200 +6313,Opal machete,500 +6314,Opal machete,500 +6315,Jade machete,1000 +6316,Jade machete,1000 +6317,Red topaz machete,2000 +6318,Red topaz machete,2000 +6319,Proboscis,5 +6320,null,5 +6321,null,1 +6322,Snakeskin body,1250 +6323,Snakeskin body,1250 +6324,Snakeskin chaps,1175 +6325,Snakeskin chaps,1175 +6326,Snakeskin bandana,300 +6327,Snakeskin bandana,300 +6328,Snakeskin boots,250 +6329,Snakeskin boots,250 +6330,Snakeskin v'brace,434 +6331,Snakeskin v'brace,434 +6332,Mahogany logs,50 +6333,Teak logs,30 +6334,Teak logs,30 +6335,Tribal mask,500 +6336,Tribal mask,500 +6337,Tribal mask,500 +6338,Tribal mask,500 +6339,Tribal mask,500 +6340,Tribal mask,500 +6341,Tribal top,300 +6342,Tribal top,300 +6343,Villager robe,250 +6344,Villager robe,250 +6345,Villager hat,200 +6346,Villager hat,200 +6347,Villager armband,150 +6348,Villager armband,150 +6349,Villager sandals,100 +6350,Villager sandals,100 +6351,Tribal top,300 +6352,Tribal top,300 +6353,Villager robe,250 +6354,Villager robe,250 +6355,Villager hat,200 +6356,Villager hat,200 +6357,Villager sandals,100 +6358,Villager sandals,100 +6359,Villager armband,150 +6360,Villager armband,150 +6361,Tribal top,300 +6362,Tribal top,300 +6363,Villager robe,250 +6364,Villager robe,250 +6365,Villager hat,200 +6366,Villager hat,200 +6367,Villager sandals,100 +6368,Villager sandals,100 +6369,Villager armband,150 +6370,Villager armband,150 +6371,Tribal top,300 +6372,Tribal top,300 +6373,Villager robe,250 +6374,Villager robe,250 +6375,Villager hat,200 +6376,Villager hat,200 +6377,Villager sandals,100 +6378,Villager sandals,100 +6379,Villager armband,150 +6380,Villager armband,150 +6381,Picture,1 +6382,Fez,20 +6383,Fez,20 +6384,Desert top,15 +6385,Desert top,15 +6386,Desert robes,25 +6387,Desert robes,25 +6388,Desert top,35 +6389,Desert top,35 +6390,Desert legs,25 +6391,Desert legs,25 +6392,Menap headgear,35 +6393,Menap headgear,35 +6394,Menaphite top,20 +6395,Menaphite top,20 +6396,Menaphite robe,40 +6397,Menaphite robe,40 +6398,Menap action kilt,20 +6399,Menap action kilt,20 +6400,Menap headgear,35 +6401,Menap headgear,35 +6402,Menaphite top,20 +6403,Menaphite top,20 +6404,Menaphite robe,40 +6405,Menaphite robe,40 +6406,Menap action kilt,20 +6407,Menap action kilt,20 +6408,Oak blackjack(o),400 +6409,Oak blackjack(o),400 +6410,Oak blackjack(d),400 +6411,Oak blackjack(d),400 +6412,Willow blackjack(o),800 +6413,Willow blackjack(o),800 +6414,Willow blackjack(d),800 +6415,Willow blackjack(d),800 +6416,Maple blackjack,1200 +6417,Maple blackjack,1200 +6418,Maple blackjack(o),1600 +6419,Maple blackjack(o),1600 +6420,Maple blackjack(d),1600 +6421,Maple blackjack(d),1600 +6422,Air rune,1 +6423,Air rune,1 +6424,Water rune,1 +6425,Water rune,1 +6426,Earth rune,1 +6427,Earth rune,1 +6428,Fire rune,1 +6429,Fire rune,1 +6430,Chaos rune,1 +6431,Chaos rune,1 +6432,Death rune,1 +6433,Death rune,1 +6434,Law rune,1 +6435,Law rune,1 +6436,Mind rune,1 +6437,Mind rune,1 +6438,Body rune,1 +6439,Body rune,1 +6440,null,1 +6441,null,1 +6442,null,1 +6443,null,1 +6444,null,1 +6445,null,1 +6446,null,1 +6447,null,1 +6448,Spadeful of coke,3 +6449,null,1 +6450,null,1 +6451,null,1 +6452,null,1 +6453,White rose seed,1 +6454,Red rose seed,1 +6455,Pink rose seed,1 +6456,Vine seed,1 +6457,Delphinium seed,1 +6458,Orchid seed,1 +6459,Orchid seed,1 +6460,Snowdrop seed,1 +6461,White tree shoot,1 +6462,White tree shoot,1 +6463,White tree shoot,1 +6464,White tree sapling,1 +6465,Ring of charos(a),1 +6466,Rune shards,1 +6467,Rune dust,1 +6468,Plant cure,1 +6469,White tree fruit,1 +6470,Compost potion(4),120 +6471,Compost potion(4),120 +6472,Compost potion(3),90 +6473,Compost potion(3),90 +6474,Compost potion(2),60 +6475,Compost potion(2),60 +6476,Compost potion(1),30 +6477,Compost potion(1),30 +6478,Trolley,1 +6479,List,1 +6480,null,1 +6481,null,1 +6482,null,1 +6483,null,1 +6484,null,1 +6485,null,1 +6486,null,1 +6487,null,1 +6488,null,1 +6489,null,1 +6490,null,1 +6491,null,1 +6492,null,1 +6493,null,1 +6494,null,1 +6495,null,1 +6496,null,1 +6497,null,1 +6498,null,1 +6499,null,1 +6500,null,1 +6501,null,1 +6502,null,1 +6503,null,1 +6504,null,1 +6505,null,1 +6506,null,1 +6507,null,1 +6508,null,1 +6509,null,1 +6510,null,1 +6511,null,1 +6512,null,1 +6513,null,1 +6514,Agility jump,1 +6515,Agility balance,1 +6516,Agility contortion,1 +6517,Agility climb,1 +6518,Agility jump,1 +6519,Agility balance,1 +6520,Agility contortion,1 +6521,Agility climb,1 +6522,Toktz-xil-ul,250 +6523,Toktz-xil-ak,40000 +6524,Toktz-ket-xil,45000 +6525,Toktz-xil-ek,25000 +6526,Toktz-mej-tal,35000 +6527,Tzhaar-ket-em,30000 +6528,Tzhaar-ket-om,50000 +6529,Tokkul,1 +6530,null,1 +6531,null,1 +6532,null,1 +6533,null,1 +6534,null,1 +6535,Toktz-xil-ak,40000 +6536,Toktz-ket-xil,45000 +6537,Toktz-xil-ek,25000 +6538,Toktz-mej-tal,35000 +6539,Tzhaar-ket-em,30000 +6540,Tzhaar-ket-om,50000 +6541,Mouse toy,1 +6542,Present,1 +6543,Antique lamp,1 +6544,Catspeak amulet(e),1 +6545,Chores,1 +6546,Recipe,1 +6547,Doctors hat,1 +6548,Nurse hat,1 +6549,Lazy cat,1 +6550,Lazy cat,1 +6551,Lazy cat,1 +6552,Lazy cat,1 +6553,Lazy cat,1 +6554,Lazy cat,1 +6555,Wily cat,1 +6556,Wily cat,1 +6557,Wily cat,1 +6558,Wily cat,1 +6559,Wily cat,1 +6560,Wily cat,1 +6561,Ahab's beer,2 +6562,Mud battlestaff,17000 +6563,Mystic mud staff,45000 +6564,Onyx ring,1 +6565,Onyx necklace,1 +6566,Onyx amulet,1 +6567,null,1 +6568,Obsidian cape,60000 +6569,Obsidian cape,60000 +6570,Fire cape,60000 +6571,Uncut onyx,300000 +6572,Uncut onyx,300000 +6573,Onyx,300000 +6574,Onyx,300000 +6575,Onyx ring,201000 +6576,Onyx ring,201000 +6577,Onyx necklace,201000 +6578,Onyx necklace,201000 +6579,Onyx amulet,201000 +6580,Onyx amulet,201000 +6581,Onyx amulet,201000 +6582,Onyx amulet,201000 +6583,Ring of stone,202000 +6584,Ring of stone,202000 +6585,Amulet of fury,202000 +6586,Amulet of fury,202000 +6587,White claws,360 +6588,White claws,360 +6589,White battleaxe,1248 +6590,White battleaxe,1248 +6591,White dagger,240 +6592,White dagger,240 +6593,White dagger(p),240 +6594,White dagger(p),240 +6595,White dagger(p+),240 +6596,White dagger(p+),240 +6597,White dagger(p++),240 +6598,White dagger(p++),240 +6599,White halberd,1920 +6600,White halberd,1920 +6601,White mace,432 +6602,White mace,432 +6603,White magic staff,200 +6604,White magic staff,200 +6605,White sword,624 +6606,White sword,624 +6607,White longsword,960 +6608,White longsword,960 +6609,White 2h sword,1920 +6610,White 2h sword,1920 +6611,White scimitar,768 +6612,White scimitar,768 +6613,White warhammer,980 +6614,White warhammer,980 +6615,White chainbody,1440 +6616,White chainbody,1440 +6617,White platebody,3840 +6618,White platebody,3840 +6619,White boots,576 +6620,White boots,576 +6621,White med helm,576 +6622,White med helm,576 +6623,White full helm,1056 +6624,White full helm,1056 +6625,White platelegs,1920 +6626,White platelegs,1920 +6627,White plateskirt,1920 +6628,White plateskirt,1920 +6629,White gloves,6 +6630,White gloves,6 +6631,White sq shield,1152 +6632,White sq shield,1152 +6633,White kiteshield,1632 +6634,White kiteshield,1632 +6635,Commorb,1 +6636,Solus's hat,1 +6637,Dark beast,1 +6638,Colour wheel,1 +6639,Hand mirror,1 +6640,Red crystal,1 +6641,Yellow crystal,1 +6642,Green crystal,1 +6643,Cyan crystal,1 +6644,Blue crystal,1 +6645,Magenta crystal,1 +6646,Fractured crystal,1 +6647,Fractured crystal,1 +6648,Item list,1 +6649,Edern's journal,1 +6650,Blackened crystal,1 +6651,Newly made crystal,1 +6652,Newly made crystal,1 +6653,Crystal trinket,1 +6654,Camo top,1 +6655,Camo bottoms,1 +6656,Camo helmet,1 +6657,Camo top,1 +6658,Camo bottoms,1 +6659,Camo helmet,1 +6660,Fishing explosive,1 +6661,Mogre,1 +6662,Broken fishing rod,0 +6663,Forlorn boot,0 +6664,Fishing explosive,60 +6665,Mudskipper hat,0 +6666,Flippers,1 +6667,Fishbowl,1 +6668,Fishbowl,0 +6669,Fishbowl,0 +6670,Fishbowl,0 +6671,Fishbowl,0 +6672,Fishbowl,0 +6673,Fishbowl and net,0 +6674,Tiny net,10 +6675,An empty box,1 +6676,Tinderbox,0 +6677,Guam in a box,5 +6678,Guam in a box?,5 +6679,Seaweed in a box,5 +6680,Seaweed in a box?,5 +6681,Ground guam,2 +6682,Ground guam,2 +6683,Ground seaweed,2 +6684,Ground seaweed,2 +6685,Saradomin brew(4),200 +6686,Saradomin brew(4),200 +6687,Saradomin brew(3),175 +6688,Saradomin brew(3),175 +6689,Saradomin brew(2),150 +6690,Saradomin brew(2),150 +6691,Saradomin brew(1),125 +6692,Saradomin brew(1),125 +6693,Crushed nest,1 +6694,Crushed nest,1 +6695,Desert lizard,1 +6696,Ice cooler,1 +6697,Pat of butter,4 +6698,Pat of butter,4 +6699,Burnt potato,1 +6700,Burnt potato,1 +6701,Baked potato,4 +6702,Baked potato,4 +6703,Potato with butter,8 +6704,Potato with butter,8 +6705,Potato with cheese,350 +6706,Potato with cheese,350 +6707,Camulet,1 +6708,Slayer gloves,1 +6709,Fever spider,1 +6710,Blindweed seed,166 +6711,Blindweed,1 +6712,Bucket of water,1 +6713,Wrench,5 +6714,Holy wrench,5 +6715,Sluglings,1 +6716,Karamthulhu,1 +6717,Karamthulhu,20000 +6718,Fever spider body,1 +6719,Unsanitary swill,1 +6720,Slayer gloves,200 +6721,Rusty scimitar,1 +6722,Zombie head,0 +6723,Fishbowl,1 +6724,Seercull,8000 +6725,Seercull,8000 +6726,Mud battlestaff,17000 +6727,Mystic mud staff,45000 +6728,Bonemeal,1 +6729,Dagannoth bones,1 +6730,Dagannoth bones,1 +6731,Seers ring,10000 +6732,Seers ring,10000 +6733,Archers ring,10000 +6734,Archers ring,10000 +6735,Warrior ring,10000 +6736,Warrior ring,10000 +6737,Berserker ring,10000 +6738,Berserker ring,10000 +6739,Dragon axe,55000 +6740,Dragon axe,55000 +6741,Broken axe,1800 +6742,Broken axe,1800 +6743,Picture,54999 +6744,Picture,54999 +6745,Silverlight,50 +6746,Darklight,500 +6747,Demonic sigil mould,0 +6748,Demonic sigil,0 +6749,Demonic tome,0 +6750,Black desert shirt,40 +6751,Tinderbox,0 +6752,Black desert robe,30 +6753,Picture,0 +6754,Enchanted key,1 +6755,Journal,1 +6756,Letter,1 +6757,Letter,1 +6758,Scroll,1 +6759,Chest,1 +6760,Guthix mjolnir,625 +6761,Guthix mjolnir,625 +6762,Saradomin mjolnir,625 +6763,Saradomin mjolnir,625 +6764,Zamorak mjolnir,625 +6765,Zamorak mjolnir,625 +6766,Cat antipoison,1 +6767,Book,1 +6768,Poisoned cheese,1 +6769,Music scroll,1 +6770,Directions,1 +6771,Pot of weeds,1 +6772,Smouldering pot,1 +6773,Rat pole,1 +6774,Rat pole,1 +6775,Rat pole,1 +6776,Rat pole,1 +6777,Rat pole,1 +6778,Rat pole,1 +6779,Rat pole,1 +6780,Menaphite thug,1 +6781,Bandit,1 +6782,Bandit,1 +6783,null,1 +6784,null,1 +6785,Statuette,1 +6786,Robe of elidinis,1 +6787,Robe of elidinis,1 +6788,Torn robe,1 +6789,Torn robe,1 +6790,Shoes,1 +6791,Sole,1 +6792,Ancestral key,1 +6793,Ballad,1 +6794,Choc-ice,30 +6795,Choc-ice,30 +6796,Lamp,1 +6797,Watering can,1 +6798,Champion scroll,1 +6799,Champion scroll,1 +6800,Champion scroll,1 +6801,Champion scroll,1 +6802,Champion scroll,1 +6803,Champion scroll,1 +6804,Champion scroll,1 +6805,Champion scroll,1 +6806,Champion scroll,1 +6807,Champion scroll,1 +6808,Champion scroll,1 +6809,Granite legs,66000 +6810,Bonemeal,1 +6811,Skeletal wyvern,1 +6812,Wyvern bones,1 +6813,Granite legs,66000 +6814,Fur,10 +6815,Fur,10 +6816,Wyvern bones,1 +6817,Slender blade,1 +6818,Bow-sword,1 +6819,Large pouch,1 +6820,Relic,1 +6821,Orb,1 +6822,Star bauble,1 +6823,Star bauble,1 +6824,Star bauble,1 +6825,Star bauble,1 +6826,Star bauble,1 +6827,Star bauble,1 +6828,Box bauble,1 +6829,Box bauble,1 +6830,Box bauble,1 +6831,Box bauble,1 +6832,Box bauble,1 +6833,Box bauble,1 +6834,Diamond bauble,1 +6835,Diamond bauble,1 +6836,Diamond bauble,1 +6837,Diamond bauble,1 +6838,Diamond bauble,1 +6839,Diamond bauble,1 +6840,Tree bauble,1 +6841,Tree bauble,1 +6842,Tree bauble,1 +6843,Tree bauble,1 +6844,Tree bauble,1 +6845,Tree bauble,1 +6846,Bell bauble,1 +6847,Bell bauble,1 +6848,Bell bauble,1 +6849,Bell bauble,1 +6850,Bell bauble,1 +6851,Bell bauble,1 +6852,Puppet box,1 +6853,Bauble box,1 +6854,Puppet box,1 +6855,Bauble box,1 +6856,Bobble hat,1 +6857,Bobble scarf,1 +6858,Jester hat,1 +6859,Jester scarf,1 +6860,Tri-jester hat,1 +6861,Tri-jester scarf,1 +6862,Woolly hat,1 +6863,Woolly scarf,1 +6864,Marionette handle,60000 +6865,Blue marionette,1 +6866,Green marionette,1 +6867,Red marionette,1 +6868,Blue marionette,1 +6869,Green marionette,1 +6870,Red marionette,1 +6871,Red marionette,1 +6872,Red marionette,1 +6873,Red marionette,1 +6874,Red marionette,1 +6875,Blue marionette,1 +6876,Blue marionette,1 +6877,Blue marionette,1 +6878,Blue marionette,1 +6879,Green marionette,1 +6880,Green marionette,1 +6881,Green marionette,1 +6882,Green marionette,1 +6883,Peach,1 +6884,null,1 +6885,Progress hat,1 +6886,Progress hat,1 +6887,Progress hat,1 +6888,Guardian statue,1 +6889,Mage's book,500 +6890,Mage's book,500 +6891,Arena book,1 +6892,Tinderbox,0 +6893,Leather boots,0 +6894,Adamant kiteshield,0 +6895,Adamant med helm,0 +6896,Emerald,0 +6897,Rune longsword,0 +6898,Cylinder,0 +6899,Cube,0 +6900,Icosahedron,0 +6901,Pentamid,0 +6902,Orb,1 +6903,Dragonstone,0 +6904,Animals' bones,1 +6905,Animals' bones,1 +6906,Animals' bones,1 +6907,Animals' bones,1 +6908,Beginner wand,1200 +6909,Beginner wand,1200 +6910,Apprentice wand,1500 +6911,Apprentice wand,1500 +6912,Teacher wand,2000 +6913,Teacher wand,2000 +6914,Master wand,2500 +6915,Master wand,2500 +6916,Infinity top,140000 +6917,Infinity top,140000 +6918,Infinity hat,17000 +6919,Infinity hat,17000 +6920,Infinity boots,12000 +6921,Infinity boots,12000 +6922,Infinity gloves,12000 +6923,Infinity gloves,12000 +6924,Infinity bottoms,90000 +6925,Infinity bottoms,90000 +6926,Bones to peaches,1 +6927,null,1 +6928,null,1 +6929,null,1 +6930,null,1 +6931,null,1 +6932,null,1 +6933,null,1 +6934,null,1 +6935,null,1 +6936,null,1 +6937,null,1 +6938,null,1 +6939,null,1 +6940,null,1 +6941,null,1 +6942,null,1 +6943,null,1 +6944,null,1 +6945,Sandy hand,1 +6946,Beer-soaked hand,1 +6947,Bert's rota,1 +6948,Sandy's rota,1 +6949,A magic scroll,1 +6950,Magical orb,1 +6951,Magical orb (a),1 +6952,Truth serum,1 +6953,Bottled water,1 +6954,Redberry juice,1 +6955,Pink dye,1 +6956,Rose-tinted lens,1 +6957,Wizard's head,1 +6958,Sand,1 +6959,Cape,1 +6960,Cape,1 +6961,Baguette,25 +6962,Triangle sandwich,25 +6963,Roll,25 +6964,Coins,6 +6965,Square sandwich,25 +6966,Prison key,1 +6967,Dragon med helm,6 +6968,Triangle sandwich,25 +6969,Shark,6 +6970,Pyramid top,1 +6971,Sandstone (1kg),1 +6972,Sandstone (1kg),1 +6973,Sandstone (2kg),1 +6974,Sandstone (2kg),1 +6975,Sandstone (5kg),1 +6976,Sandstone (5kg),1 +6977,Sandstone (10kg),1 +6978,Sandstone (10kg),1 +6979,Granite (500g),1 +6980,Granite (500g),1 +6981,Granite (2kg),1 +6982,Granite (2kg),1 +6983,Granite (5kg),1 +6984,Granite (5kg),1 +6985,Sandstone (20kg),1 +6986,Sandstone (32kg),1 +6987,Sandstone body,1 +6988,Sandstone base,1 +6989,Stone head,1 +6990,Stone head,1 +6991,Stone head,1 +6992,Stone head,1 +6993,Z sigil,1 +6994,M sigil,1 +6995,R sigil,1 +6996,K sigil,1 +6997,Stone left arm,1 +6998,Stone right arm,1 +6999,Stone left leg,1 +7000,Stone right leg,1 +7001,Camel mould (p),1 +7002,Stone head,1 +7003,Camel mask,1 +7004,Chisel,1 +7005,null,1 +7006,null,1 +7007,null,1 +7008,null,1 +7009,null,1 +7010,null,1 +7011,null,1 +7012,null,1 +7013,null,1 +7014,null,1 +7015,null,1 +7016,null,1 +7017,null,1 +7018,null,1 +7019,null,1 +7020,null,1 +7021,null,1 +7022,null,1 +7023,null,1 +7024,null,1 +7025,null,1 +7026,null,1 +7027,null,1 +7028,null,1 +7029,null,1 +7030,null,1 +7031,null,1 +7032,null,1 +7033,null,1 +7034,null,1 +7035,null,1 +7036,null,1 +7037,null,1 +7038,null,1 +7039,null,1 +7040,null,1 +7041,null,1 +7042,null,1 +7043,null,1 +7044,null,1 +7045,null,1 +7046,null,1 +7047,null,1 +7048,null,1 +7049,null,1 +7050,Swarm,1 +7051,Unlit bug lantern,130 +7052,Unlit bug lantern,130 +7053,Lit bug lantern,130 +7054,Chilli potato,13 +7055,Chilli potato,13 +7056,Egg potato,12 +7057,Egg potato,12 +7058,Mushroom potato,45 +7059,Mushroom potato,45 +7060,Tuna potato,113 +7061,Tuna potato,113 +7062,Chilli con carne,13 +7063,Chilli con carne,13 +7064,Egg and tomato,12 +7065,Egg and tomato,12 +7066,Mushroom & onion,45 +7067,Mushroom & onion,45 +7068,Tuna and corn,113 +7069,Tuna and corn,113 +7070,Minced meat,8 +7071,Minced meat,8 +7072,Spicy sauce,9 +7073,Spicy sauce,9 +7074,Chopped garlic,7 +7075,Chopped garlic,7 +7076,Uncooked egg,8 +7077,Uncooked egg,8 +7078,Scrambled egg,8 +7079,Scrambled egg,8 +7080,Sliced mushrooms,42 +7081,Sliced mushrooms,42 +7082,Fried mushrooms,42 +7083,Fried mushrooms,42 +7084,Fried onions,7 +7085,Fried onions,7 +7086,Chopped tuna,104 +7087,Chopped tuna,104 +7088,Sweetcorn,13 +7089,Sweetcorn,13 +7090,Burnt egg,5 +7091,Burnt egg,5 +7092,Burnt onion,5 +7093,Burnt onion,5 +7094,Burnt mushroom,5 +7095,Burnt mushroom,5 +7096,Board game piece,1 +7097,Board game piece,1 +7098,Board game piece,1 +7099,Board game piece,1 +7100,Board game piece,1 +7101,Board game piece,1 +7102,Board game piece,1 +7103,Board game piece,1 +7104,Board game piece,1 +7105,Board game piece,1 +7106,Board game piece,1 +7107,Board game piece,1 +7108,Gunpowder,52 +7109,Fuse,52 +7110,Stripy pirate shirt,300 +7111,Stripy pirate shirt,300 +7112,Pirate bandana,100 +7113,Pirate bandana,100 +7114,Pirate boots,350 +7115,Pirate boots,350 +7116,Pirate leggings,350 +7117,Pirate leggings,350 +7118,Canister,1 +7119,Cannon ball,1 +7120,Ramrod,1 +7121,Repair plank,1 +7122,Stripy pirate shirt,300 +7123,Stripy pirate shirt,300 +7124,Pirate bandana,100 +7125,Pirate bandana,100 +7126,Pirate leggings,350 +7127,Pirate leggings,350 +7128,Stripy pirate shirt,300 +7129,Stripy pirate shirt,300 +7130,Pirate bandana,100 +7131,Pirate bandana,100 +7132,Pirate leggings,350 +7133,Pirate leggings,350 +7134,Stripy pirate shirt,300 +7135,Stripy pirate shirt,300 +7136,Pirate bandana,100 +7137,Pirate bandana,100 +7138,Pirate leggings,350 +7139,Pirate leggings,350 +7140,Lucky cutlass,2560 +7141,Harry's cutlass,1040 +7142,Rapier,25600 +7143,Plunder,1 +7144,Book o' piracy,1 +7145,Cannon barrel,1 +7146,Broken cannon,1 +7147,Cannon balls,1 +7148,Repair plank,1 +7149,Canister,1 +7150,Tacks,1 +7151,null,1 +7152,null,1 +7153,null,1 +7154,null,1 +7155,Rope,18 +7156,Tinderbox,1 +7157,Braindeath 'rum',30 +7158,Dragon 2h sword,220000 +7159,Insulated boots,200 +7160,Killerwatt,1 +7161,Insulated boots,200 +7162,Pie recipe book,5 +7163,Pie recipe book,5 +7164,Part mud pie,22 +7165,Part mud pie,22 +7166,Part mud pie,26 +7167,Part mud pie,26 +7168,Raw mud pie,27 +7169,Raw mud pie,27 +7170,Mud pie,54 +7171,Mud pie,54 +7172,Part garden pie,8 +7173,Part garden pie,8 +7174,Part garden pie,11 +7175,Part garden pie,11 +7176,Raw garden pie,12 +7177,Raw garden pie,12 +7178,Garden pie,90 +7179,Garden pie,90 +7180,Half a garden pie,12 +7181,Half a garden pie,12 +7182,Part fish pie,24 +7183,Part fish pie,24 +7184,Part fish pie,49 +7185,Part fish pie,49 +7186,Raw fish pie,50 +7187,Raw fish pie,50 +7188,Fish pie,100 +7189,Fish pie,100 +7190,Half a fish pie,50 +7191,Half a fish pie,50 +7192,Part admiral pie,54 +7193,Part admiral pie,54 +7194,Part admiral pie,154 +7195,Part admiral pie,154 +7196,Raw admiral pie,155 +7197,Raw admiral pie,155 +7198,Admiral pie,310 +7199,Admiral pie,310 +7200,Half an admiral pie,155 +7201,Half an admiral pie,155 +7202,Part wild pie,5 +7203,Part wild pie,5 +7204,Part wild pie,90 +7205,Part wild pie,90 +7206,Raw wild pie,91 +7207,Raw wild pie,91 +7208,Wild pie,182 +7209,Wild pie,182 +7210,Half a wild pie,91 +7211,Half a wild pie,91 +7212,Part summer pie,21 +7213,Part summer pie,21 +7214,Part summer pie,69 +7215,Part summer pie,69 +7216,Raw summer pie,70 +7217,Raw summer pie,70 +7218,Summer pie,140 +7219,Summer pie,140 +7220,Half a summer pie,70 +7221,Half a summer pie,70 +7222,Burnt rabbit,1 +7223,Roast rabbit,20 +7224,Skewered rabbit,84 +7225,Iron spit,64 +7226,Burnt chompy,1 +7227,Burnt chompy,1 +7228,Cooked chompy,85 +7229,Cooked chompy,85 +7230,Skewered chompy,149 +7231,Burnt rabbit,1 +7232,Roast rabbit,20 +7233,Skewered rabbit,84 +7234,Iron spit,64 +7235,Skewered chompy,149 +7236,Clue scroll,1 +7237,Casket,50 +7238,Clue scroll,1 +7239,Clue scroll,1 +7240,Casket,50 +7241,Clue scroll,1 +7242,Casket,50 +7243,Clue scroll,1 +7244,Casket,50 +7245,Clue scroll,1 +7246,Casket,50 +7247,Clue scroll,1 +7248,Clue scroll,1 +7249,Clue scroll,1 +7250,Clue scroll,1 +7251,Clue scroll,1 +7252,Clue scroll,1 +7253,Clue scroll,1 +7254,Clue scroll,1 +7255,Clue scroll,1 +7256,Clue scroll,1 +7257,Casket,50 +7258,Clue scroll,1 +7259,Casket,50 +7260,Clue scroll,1 +7261,Casket,50 +7262,Clue scroll,1 +7263,Casket,50 +7264,Clue scroll,1 +7265,Casket,50 +7266,Clue scroll,1 +7267,Casket,50 +7268,Clue scroll,1 +7269,Challenge scroll,1 +7270,Clue scroll,1 +7271,Challenge scroll,1 +7272,Clue scroll,1 +7273,Challenge scroll,1 +7274,Clue scroll,1 +7275,Challenge scroll,1 +7276,Clue scroll,1 +7277,Challenge scroll,1 +7278,Clue scroll,1 +7279,Challenge scroll,1 +7280,Clue scroll,1 +7281,Challenge scroll,1 +7282,Clue scroll,1 +7283,Challenge scroll,1 +7284,Clue scroll,1 +7285,Challenge scroll,1 +7286,Clue scroll,1 +7287,Casket,50 +7288,Clue scroll,1 +7289,Casket,50 +7290,Clue scroll,1 +7291,Casket,50 +7292,Clue scroll,1 +7293,Casket,50 +7294,Clue scroll,1 +7295,Casket,50 +7296,Clue scroll,1 +7297,Key,1 +7298,Clue scroll,1 +7299,Key,1 +7300,Clue scroll,1 +7301,Clue scroll,1 +7302,Key,1 +7303,Clue scroll,1 +7304,Clue scroll,1 +7305,Clue scroll,1 +7306,Casket,50 +7307,Clue scroll,1 +7308,Casket,50 +7309,Clue scroll,1 +7310,Casket,50 +7311,Clue scroll,1 +7312,Casket,50 +7313,Clue scroll,1 +7314,Casket,50 +7315,Clue scroll,1 +7316,Casket,50 +7317,Clue scroll,1 +7318,Casket,50 +7319,Red boater,225 +7320,Red boater,225 +7321,Orange boater,225 +7322,Orange boater,225 +7323,Green boater,225 +7324,Green boater,225 +7325,Blue boater,225 +7326,Blue boater,225 +7327,Black boater,225 +7328,Black boater,225 +7329,Red firelighter,15 +7330,Green firelighter,15 +7331,Blue firelighter,15 +7332,Black shield(h1),1632 +7333,Black shield(h1),1632 +7334,Adamant shield(h1),5440 +7335,Adamant shield(h1),5440 +7336,Rune shield(h1),54400 +7337,Rune shield(h1),54400 +7338,Black shield(h2),16325 +7339,Black shield(h2),16325 +7340,Adamant shield(h2),5440 +7341,Adamant shield(h2),5440 +7342,Rune shield(h2),54400 +7343,Rune shield(h2),54400 +7344,Black shield(h3),1632 +7345,Black shield(h3),1632 +7346,Adamant shield(h3),5440 +7347,Adamant shield(h3),5440 +7348,Rune shield(h3),54400 +7349,Rune shield(h3),54400 +7350,Black shield(h4),1632 +7351,Black shield(h4),1632 +7352,Adamant shield(h4),5440 +7353,Adamant shield(h4),5440 +7354,Rune shield(h4),54400 +7355,Rune shield(h4),54400 +7356,Black shield(h5),1632 +7357,Black shield(h5),1632 +7358,Adamant shield(h5),5440 +7359,Adamant shield(h5),5440 +7360,Rune shield(h5),54400 +7361,Rune shield(h5),54400 +7362,Studded body (g),850 +7363,Studded body (g),850 +7364,Studded body (t),850 +7365,Studded body (t),850 +7366,Studded chaps (g),750 +7367,Studded chaps (g),750 +7368,Studded chaps (t),750 +7369,Studded chaps (t),750 +7370,D'hide body(g),7800 +7371,D'hide body(g),7800 +7372,D'hide body (t),7800 +7373,D'hide body (t),7800 +7374,D'hide body (g),9360 +7375,D'hide body (g),9360 +7376,D'hide body (t),9360 +7377,D'hide body (t),9360 +7378,D'hide chaps (g),3900 +7379,D'hide chaps (g),3900 +7380,D'hide chaps (t),3900 +7381,D'hide chaps (t),3900 +7382,D'hide chaps (g),4320 +7383,D'hide chaps (g),4320 +7384,D'hide chaps (t),4320 +7385,D'hide chaps (t),4320 +7386,Blue skirt (g),2 +7387,Blue skirt (g),2 +7388,Blue skirt (t),2 +7389,Blue skirt (t),2 +7390,Wizard robe (g),15 +7391,Wizard robe (g),15 +7392,Wizard robe (t),15 +7393,Wizard robe (t),15 +7394,Wizard hat (g),2 +7395,Wizard hat (g),2 +7396,Wizard hat (t),2 +7397,Wizard hat (t),2 +7398,Enchanted robe,80000 +7399,Enchanted top,120000 +7400,Enchanted hat,15000 +7401,Enchanted robe,80000 +7402,Enchanted top,120000 +7403,Enchanted hat,15000 +7404,Red logs,4 +7405,Green logs,4 +7406,Blue logs,4 +7407,Dragon 2h sword,220000 +7408,Draynor skull,1 +7409,Magic secateurs,1 +7410,Queen's secateurs,1 +7411,Symptoms list,1 +7412,null,1 +7413,Bird's nest,1 +7414,Paddle,1 +7415,Paddle,1 +7416,Mole claw,600 +7417,Mole claw,600 +7418,Mole skin,400 +7419,Mole skin,400 +7420,Mutated zygomite,1 +7421,Fungicide spray 10,300 +7422,Fungicide spray 9,1 +7423,Fungicide spray 8,1 +7424,Fungicide spray 7,1 +7425,Fungicide spray 6,1 +7426,Fungicide spray 5,1 +7427,Fungicide spray 4,1 +7428,Fungicide spray 3,1 +7429,Fungicide spray 2,1 +7430,Fungicide spray 1,1 +7431,Fungicide spray 0,1 +7432,Fungicide,10 +7433,Wooden spoon,35 +7434,Wooden spoon,35 +7435,Egg whisk,50 +7436,Egg whisk,50 +7437,Spork,325 +7438,Spork,325 +7439,Spatula,1920 +7440,Spatula,1920 +7441,Frying pan,1660 +7442,Frying pan,1660 +7443,Skewer,3200 +7444,Skewer,3200 +7445,Rolling pin,14400 +7446,Rolling pin,14400 +7447,Kitchen knife,8000 +7448,Kitchen knife,8000 +7449,Meat tenderiser,41500 +7450,Meat tenderiser,41500 +7451,Cleaver,25600 +7452,Cleaver,25600 +7453,Gloves,50 +7454,Gloves,100 +7455,Gloves,250 +7456,Gloves,500 +7457,Gloves,1000 +7458,Gloves,1500 +7459,Gloves,2500 +7460,Gloves,5000 +7461,Gloves,100000 +7462,Gloves,100000 +7463,Cornflour,2 +7464,Book on chickens,1 +7465,Vanilla pod,1 +7466,Cornflour,1 +7467,Tinderbox,0 +7468,Pot of cornflour,10 +7469,Tinderbox,0 +7470,Cornflour mixture,1 +7471,Milky mixture,1 +7472,Cinnamon,1 +7473,Brulee,1 +7474,Brulee,1 +7475,Brulee,1 +7476,Brulee supreme,1 +7477,Evil chicken's egg,1 +7478,Dragon token,1 +7479,Spicy stew,20 +7480,Red spice (4),1 +7481,Red spice (3),1 +7482,Red spice (2),1 +7483,Red spice (1),1 +7484,Orange spice (4),1 +7485,Orange spice (3),1 +7486,Orange spice (2),1 +7487,Orange spice (1),1 +7488,Brown spice (4),1 +7489,Brown spice (3),1 +7490,Brown spice (2),1 +7491,Brown spice (1),1 +7492,Yellow spice (4),1 +7493,Yellow spice (3),1 +7494,Yellow spice (2),1 +7495,Yellow spice (1),1 +7496,Empty spice shaker,1 +7497,Dirty blast,30 +7498,Antique lamp,1 +7499,Evil dave,1 +7500,Dwarf,1 +7501,Goblins,1 +7502,Lumbridge guide,1 +7503,Monkey,1 +7504,Osman,1 +7505,Pirate pete,1 +7506,Sir amik varze,1 +7507,Skrach,1 +7508,Asgoldian ale,2 +7509,Dwarven rock cake,1 +7510,Dwarven rock cake,1 +7511,Slop of compromise,10 +7512,Soggy bread,6 +7513,Spicy maggots,3 +7514,Dyed orange,2 +7515,Breadcrumbs,1 +7516,Kelp,1 +7517,Ground kelp,1 +7518,Crab meat,1 +7519,Crab meat,1 +7520,Burnt crab meat,1 +7521,Cooked crab meat,50 +7522,Cooked crab meat,50 +7523,Cooked crab meat,40 +7524,Cooked crab meat,30 +7525,Cooked crab meat,20 +7526,Cooked crab meat,10 +7527,Ground crab meat,1 +7528,Ground cod,1 +7529,Raw fishcake,100 +7530,Cooked fishcake,100 +7531,Burnt fishcake,1 +7532,Mudskipper hide,1 +7533,Rock,1 +7534,Fishbowl helmet,1 +7535,Diving apparatus,1 +7536,Fresh crab claw,1 +7537,Crab claw,1 +7538,Fresh crab shell,1 +7539,Crab helmet,1 +7540,Broken crab claw,1 +7541,Broken crab shell,1 +7542,Cake of guidance,50 +7543,Raw guide cake,20 +7544,Enchanted egg,4 +7545,Enchanted milk,6 +7546,Enchanted flour,10 +7547,Druid pouch,5 +7548,Potato seed,1 +7549,Potato seed,1 +7550,Onion seed,1 +7551,Onion seed,1 +7552,Mithril arrow,1 +7553,Mithril arrow,1 +7554,Fire rune,1 +7555,Fire rune,1 +7556,Water rune,1 +7557,Water rune,1 +7558,Air rune,1 +7559,Air rune,1 +7560,Chaos rune,1 +7561,Chaos rune,1 +7562,Tomato seed,1 +7563,Tomato seed,1 +7564,Balloon toad,1 +7565,Balloon toad,1 +7566,Raw jubbly,100 +7567,Raw jubbly,100 +7568,Cooked jubbly,150 +7569,Cooked jubbly,150 +7570,Burnt jubbly,1 +7571,Burnt jubbly,1 +7572,Red banana,5 +7573,Tchiki monkey nuts,5 +7574,Sliced red banana,5 +7575,Tchiki nut paste,5 +7576,Snake corpse,1 +7577,Raw stuffed snake,1 +7578,Odd stuffed snake,1 +7579,Stuffed snake,1 +7580,Snake over-cooked,1 +7581,Overgrown hellcat,1 +7582,Hell cat,1 +7583,Hell-kitten,1 +7584,Lazy hell cat,1 +7585,Wily hellcat,1 +7586,Dummy,1 +7587,Coffin,1 +7588,Coffin,1 +7589,Coffin,1 +7590,Coffin,1 +7591,Coffin,1 +7592,Zombie shirt,1 +7593,Zombie trousers,1 +7594,Zombie mask,1 +7595,Zombie gloves,1 +7596,Zombie boots,1 +7597,Item,1 +7598,Item,1 +7599,Item,1 +7600,Item,1 +7601,Item,1 +7602,Item,1 +7603,Item,1 +7604,Item,1 +7605,Item,1 +7606,Item,1 +7607,Item,1 +7608,Item,1 +7609,Item,1 +7610,Item,1 +7611,Item,1 +7612,Item,1 +7613,Item,1 +7614,Item,1 +7615,Item,1 +7616,Item,1 +7617,Item,1 +7618,Item,1 +7619,null,1 +7620,Silvthrill rod,1 +7621,null,1 +7622,Bucket of rubble,1 +7623,Tinderbox,0 +7624,Bucket of rubble,1 +7625,Tinderbox,0 +7626,Bucket of rubble,1 +7627,Tinderbox,0 +7628,Plaster fragment,1 +7629,Dusty scroll,1 +7630,Crate,1 +7631,Tinderbox,0 +7632,Temple library key,1 +7633,Ancient book,1 +7634,Battered tome,1 +7635,Leather book,1 +7636,Rod dust,1 +7637,Silvthrill rod,1 +7638,Silvthrill rod,1 +7639,Rod of ivandis(10),1000 +7640,Rod of ivandis(9),1000 +7641,Rod of ivandis(8),1000 +7642,Rod of ivandis(7),1000 +7643,Rod of ivandis(6),1000 +7644,Rod of ivandis(5),1000 +7645,Rod of ivandis(4),1000 +7646,Rod of ivandis(3),1000 +7647,Rod of ivandis(2),1000 +7648,Rod of ivandis(1),1000 +7649,Rod clay mould,100 +7650,Silver dust,200 +7651,Silver dust,200 +7652,Guthix balance(unf),110 +7653,Guthix balance(unf),110 +7654,Guthix balance(unf),110 +7655,Guthix balance(unf),110 +7656,Guthix balance(unf),110 +7657,Guthix balance(unf),110 +7658,Guthix balance(unf),110 +7659,Guthix balance(unf),110 +7660,Guthix balance(4),200 +7661,Guthix balance(4),200 +7662,Guthix balance(3),200 +7663,Guthix balance(3),200 +7664,Guthix balance(2),200 +7665,Guthix balance(2),200 +7666,Guthix balance(1),200 +7667,Guthix balance(1),200 +7668,Gadderhammer,3000 +7669,Gadderhammer,3000 +7670,null,1 +7671,Boxing gloves,0 +7672,Picture,1 +7673,Boxing gloves,0 +7674,Perfect,1 +7675,Wooden sword,1 +7676,Wooden shield,1 +7677,Treasure stone,1 +7678,Prize key,1 +7679,Pugel,1 +7680,Pugel,1 +7681,Game book,1 +7682,Hoop,1 +7683,Hoop,1 +7684,Dart,1 +7685,Dart,1 +7686,Bow and arrow,1 +7687,Bow and arrow,1 +7688,Kettle,1 +7689,Kettle,1 +7690,Full kettle,1 +7691,Hot kettle,1 +7692,Pot of tea (4),1 +7693,Pot of tea (4),1 +7694,Pot of tea (3),1 +7695,Pot of tea (3),1 +7696,Pot of tea (2),1 +7697,Pot of tea (2),1 +7698,Pot of tea (1),1 +7699,Pot of tea (1),1 +7700,Teapot with leaves,1 +7701,Teapot with leaves,1 +7702,Teapot,1 +7703,Teapot,1 +7704,Pot of tea (4),1 +7705,Pot of tea (4),1 +7706,Pot of tea (3),1 +7707,Pot of tea (3),1 +7708,Pot of tea (2),1 +7709,Pot of tea (2),1 +7710,Pot of tea (1),1 +7711,Pot of tea (1),1 +7712,Teapot with leaves,1 +7713,Teapot with leaves,1 +7714,Teapot,1 +7715,Teapot,1 +7716,Pot of tea (4),1 +7717,Pot of tea (4),1 +7718,Pot of tea (3),1 +7719,Pot of tea (3),1 +7720,Pot of tea (2),1 +7721,Pot of tea (2),1 +7722,Pot of tea (1),1 +7723,Pot of tea (1),1 +7724,Teapot with leaves,1 +7725,Teapot with leaves,1 +7726,Teapot,1 +7727,Teapot,1 +7728,Empty cup,2 +7729,Empty cup,2 +7730,Cup of tea,10 +7731,Cup of tea,10 +7732,Porcelain cup,2 +7733,Cup of tea,10 +7734,Cup of tea,10 +7735,Porcelain cup,2 +7736,Cup of tea,10 +7737,Cup of tea,10 +7738,Tea leaves,1 +7739,Tea leaves,1 +7740,Beer,2 +7741,Beer,2 +7742,Beer glass,2 +7743,Beer glass,2 +7744,Asgarnian ale,2 +7745,Asgarnian ale,2 +7746,Greenman's ale,2 +7747,Greenman's ale,2 +7748,Dragon bitter,2 +7749,Dragon bitter,2 +7750,Moonlight mead,5 +7751,Moonlight mead,5 +7752,Cider,2 +7753,Cider,2 +7754,Chef's delight,2 +7755,Chef's delight,2 +7756,Paintbrush,1 +7757,Paintbrush,1 +7758,Rusty sword,1 +7759,Toy soldier,10 +7760,Toy soldier,10 +7761,Toy soldier (wound),10 +7762,Toy soldier (wound),10 +7763,Toy doll,10 +7764,Toy doll,10 +7765,Toy doll (wound),10 +7766,Toy doll (wound),10 +7767,Toy mouse,10 +7768,Toy mouse,10 +7769,Toy mouse (wound),10 +7770,Toy mouse (wound),10 +7771,Clockwork cat,10 +7772,Clockwork cat,10 +7773,Branch,1 +7774,Reward token,1 +7775,Reward token,1 +7776,Reward token,1 +7777,Long vine,1 +7778,Short vine,1 +7779,Fishing tome,5000 +7780,Fishing tome,5000 +7781,Fishing tome,5000 +7782,Agility tome,5000 +7783,Agility tome,5000 +7784,Agility tome,5000 +7785,Thieving tome,5000 +7786,Thieving tome,5000 +7787,Thieving tome,5000 +7788,Slayer tome,5000 +7789,Slayer tome,5000 +7790,Slayer tome,5000 +7791,Mining tome,5000 +7792,Mining tome,5000 +7793,Mining tome,5000 +7794,Firemaking tome,5000 +7795,Firemaking tome,5000 +7796,Firemaking tome,5000 +7797,Woodcutting tome,5000 +7798,Woodcutting tome,5000 +7799,Woodcutting tome,5000 +7800,Snail shell,1 +7801,Snake hide,35 +7802,Snake hide,35 +7803,Yin yang amulet,1 +7804,Picture,625 +7805,Picture,625 +7806,Anger sword,26 +7807,Anger battleaxe,182 +7808,Anger mace,18 +7809,Anger spear,26 +7810,Jug of vinegar,1 +7811,Pot of vinegar,0 +7812,Goblin skull,1 +7813,Bone in vinegar,0 +7814,Goblin skull,1 +7815,Bear ribs,1 +7816,Bone in vinegar,0 +7817,Bear ribs,1 +7818,Ram skull,1 +7819,Bone in vinegar,0 +7820,Ram skull,1 +7821,Unicorn bone,1 +7822,Bone in vinegar,0 +7823,Unicorn bone,1 +7824,Giant rat bone,1 +7825,Bone in vinegar,0 +7826,Giant rat bone,1 +7827,Giant bat wing,1 +7828,Bone in vinegar,0 +7829,Giant bat wing,1 +7830,Wolf bone,1 +7831,Bone in vinegar,0 +7832,Wolf bone,1 +7833,Bat wing,1 +7834,Bone in vinegar,0 +7835,Bat wing,1 +7836,Rat bone,1 +7837,Bone in vinegar,0 +7838,Rat bone,1 +7839,Baby dragon bone,1 +7840,Bone in vinegar,0 +7841,Baby dragon bone,1 +7842,Ogre ribs,1 +7843,Bone in vinegar,0 +7844,Ogre ribs,1 +7845,Jogre bone,1 +7846,Bone in vinegar,0 +7847,Jogre bone,1 +7848,Zogre bone,1 +7849,Bone in vinegar,0 +7850,Zogre bone,1 +7851,Mogre bone,1 +7852,Bone in vinegar,0 +7853,Mogre bone,1 +7854,Monkey paw,1 +7855,Bone in vinegar,0 +7856,Monkey paw,1 +7857,Dagannoth ribs,1 +7858,Bone in vinegar,0 +7859,Dagannoth ribs,1 +7860,Snake spine,1 +7861,Bone in vinegar,0 +7862,Snake spine,1 +7863,Zombie bone,1 +7864,Bone in vinegar,0 +7865,Zombie bone,1 +7866,Werewolf bone,1 +7867,Bone in vinegar,0 +7868,Werewolf bone,1 +7869,Moss giant bone,1 +7870,Bone in vinegar,0 +7871,Moss giant bone,1 +7872,Fire giant bone,1 +7873,Bone in vinegar,0 +7874,Fire giant bone,1 +7875,Ice giant ribs,1 +7876,Bone in vinegar,0 +7877,Ice giant ribs,1 +7878,Terrorbird wing,1 +7879,Bone in vinegar,0 +7880,Terrorbird wing,1 +7881,Ghoul bone,1 +7882,Bone in vinegar,0 +7883,Ghoul bone,1 +7884,Troll bone,1 +7885,Bone in vinegar,0 +7886,Troll bone,1 +7887,Seagull wing,1 +7888,Bone in vinegar,0 +7889,Seagull wing,1 +7890,Undead cow ribs,1 +7891,Bone in vinegar,0 +7892,Undead cow ribs,1 +7893,Experiment bone,1 +7894,Bone in vinegar,0 +7895,Experiment bone,1 +7896,Rabbit bone,1 +7897,Bone in vinegar,0 +7898,Rabbit bone,1 +7899,Basilisk bone,1 +7900,Bone in vinegar,0 +7901,Basilisk bone,1 +7902,Desert lizard bone,1 +7903,Bone in vinegar,0 +7904,Desert lizard bone,1 +7905,Cave goblin skull,1 +7906,Bone in vinegar,0 +7907,Cave goblin skull,1 +7908,Big frog leg,1 +7909,Bone in vinegar,0 +7910,Big frog leg,1 +7911,Vulture wing,1 +7912,Bone in vinegar,0 +7913,Vulture wing,1 +7914,Jackal bone,1 +7915,Bone in vinegar,0 +7916,Jackal bone,1 +7917,Ram skull helm,1 +7918,Bonesack,1 +7919,Bottle of wine,500 +7920,Bottle of wine,500 +7921,Empty wine bottle,1 +7922,Al kharid flyer,1 +7923,null,1 +7924,null,1 +7925,null,1 +7926,null,1 +7927,Easter ring,1 +7928,Easter egg,1 +7929,Easter egg,1 +7930,Easter egg,1 +7931,Easter egg,1 +7932,Easter egg,1 +7933,Easter egg,1 +7934,Field ration,390 +7935,Field ration,390 +7936,Pure essence,4 +7937,Pure essence,4 +7938,Bob,4 +7939,Tortoise shell,1000 +7940,Tortoise shell,1000 +7941,Iron sheet,30 +7942,Fresh monkfish,10 +7943,Fresh monkfish,10 +7944,Raw monkfish,230 +7945,Raw monkfish,230 +7946,Monkfish,230 +7947,Monkfish,230 +7948,Burnt monkfish,3 +7949,Burnt monkfish,3 +7950,Bone seeds,30 +7951,Herman's book,1 +7952,Picture,1 +7953,Picture,1 +7954,Burnt shrimp,1 +7955,Burnt shrimp,1 +7956,Casket,50 +7957,White apron,1 +7958,Mining prop,10 +7959,Heavy box,10 +7960,Empty box,10 +7961,Burnt diary,10 +7962,Burnt diary,10 +7963,Burnt diary,10 +7964,Burnt diary,10 +7965,Burnt diary,10 +7966,Letter,10 +7967,Engine,5 +7968,Scroll,10 +7969,Pulley beam,5 +7970,Long pulley beam,5 +7971,Longer pulley beam,5 +7972,Lift manual,5 +7973,Beam,5 +7974,Servant bell,10 +7975,Crawling hand,1000 +7976,Cockatrice head,2000 +7977,Basilisk head,4000 +7978,Kurask head,6000 +7979,Abyssal head,12000 +7980,Kbd heads,50000 +7981,Kq head,50000 +7982,Crawling hand,1000 +7983,Cockatrice head,2000 +7984,Basilisk head,4000 +7985,Kurask head,6000 +7986,Abyssal head,12000 +7987,Kbd heads,50000 +7988,Kq head,50000 +7989,Big bass,1000 +7990,Big bass,1000 +7991,Big swordfish,2500 +7992,Big swordfish,2500 +7993,Big shark,5000 +7994,Big shark,5000 +7995,Arthur portrait,1000 +7996,Elena portrait,1000 +7997,Keldagrim portrait,1000 +7998,Misc. portrait,1000 +7999,Desert painting,2000 +8000,Isafdar painting,2000 +8001,Karamja painting,2000 +8002,Lumbridge painting,2000 +8003,Morytania painting,2000 +8004,Small map,1000 +8005,Medium map,1000 +8006,Large map,1000 +8007,Varrock teleport,1 +8008,Lumbridge teleport,1 +8009,Falador teleport,1 +8010,Camelot teleport,1 +8011,Ardougne teleport,1 +8012,Watchtower t'port,1 +8013,Teleport to house,1 +8014,Bones to bananas,1 +8015,Bones to peaches,1 +8016,Enchant sapphire,1 +8017,Enchant emerald,1 +8018,Enchant ruby,1 +8019,Enchant diamond,1 +8020,Enchant dragonstn.,1 +8021,Enchant onyx,1 +8022,Telekinetic grab,1 +8023,Boxing ring,1 +8024,Fencing ring,1 +8025,Combat ring,1 +8026,Ranging pedestals,1 +8027,Balance beam,1 +8028,Glove rack,1 +8029,Weapons rack,1 +8030,Extra weapons rack,1 +8031,Wooden bed,1 +8032,Oak bed,1 +8033,Large oak bed,1 +8034,Teak bed,1 +8035,Large teak bed,1 +8036,4-poster,1 +8037,Gilded 4-poster,1 +8038,Shoe box,1 +8039,Oak drawers,1 +8040,Oak wardrobe,1 +8041,Teak drawers,1 +8042,Teak wardrobe,1 +8043,Mahogany 'drobe,1 +8044,Gilded wardrobe,1 +8045,Shaving stand,1 +8046,Oak shaving stand,1 +8047,Oak dresser,1 +8048,Teak dresser,1 +8049,Fancy teak dresser,1 +8050,Mahogany dresser,1 +8051,Gilded dresser,1 +8052,Oak clock,1 +8053,Teak clock,1 +8054,Gilded clock,1 +8055,Saradomin symbol,1 +8056,Zamorak symbol,1 +8057,Guthix symbol,1 +8058,Saradomin icon,1 +8059,Zamorak icon,1 +8060,Guthix icon,1 +8061,Icon of bob,1 +8062,Oak altar,1 +8063,Teak altar,1 +8064,Cloth-cover'd altar,1 +8065,Mahogany altar,1 +8066,Limestone altar,1 +8067,Marble altar,1 +8068,Gilded altar,1 +8069,Wooden torches,1 +8070,Steel torches,1 +8071,Steel candlesticks,1 +8072,Gold candlesticks,1 +8073,Incense burners,1 +8074,Mahogany burners,1 +8075,Marble burners,1 +8076,Shuttered window,1 +8077,Decorative window,1 +8078,Stained glass,1 +8079,Windchimes,1 +8080,Bells,1 +8081,Organ,1 +8082,Small statues,1 +8083,Medium statues,1 +8084,Large statues,1 +8085,Suit of armour,1 +8086,Small portrait,1 +8087,Minor head,1 +8088,Medium head,1 +8089,Major head,1 +8090,Mounted sword,1 +8091,Small landscape,1 +8092,Guild trophy,1 +8093,Large portrait,1 +8094,Large landscape,1 +8095,Rune display case,1 +8096,Low-level plants,1 +8097,Mid-level plants,1 +8098,High-level plants,1 +8099,Rope bell-pull,1 +8100,Bell-pull,1 +8101,Posh bell-pull,1 +8102,Oak decoration,1 +8103,Teak decoration,1 +8104,Gilded decoration,1 +8105,Round shield,1 +8106,Square shield,1 +8107,Kite shield,1 +8108,Wooden bench,1 +8109,Oak bench,1 +8110,Carved oak bench,1 +8111,Teak dining bench,1 +8112,Carved teak bench,1 +8113,Mahogany bench,1 +8114,Gilded bench,1 +8115,Wood dining table,1 +8116,Oak dining table,1 +8117,Carved oak table,1 +8118,Teak table,1 +8119,Carved teak table,1 +8120,Mahogany table,1 +8121,Opulent table,1 +8122,Oak door,1 +8123,Steel-plated door,1 +8124,Marble door,1 +8125,Decorative blood,1 +8126,Decorative pipe,1 +8127,Hanging skeleton,1 +8128,Candles,1 +8129,Torches,1 +8130,Skull torches,1 +8131,Skeleton guard,1 +8132,Guard dog,1 +8133,Hobgoblin guard,1 +8134,Baby red dragon,1 +8135,Huge spider,1 +8136,Troll guard,1 +8137,Hellhound,1 +8138,Demon,1 +8139,Kalphite soldier,1 +8140,Tok-xil,1 +8141,Dagannoth,1 +8142,Steel dragon,1 +8143,Spike trap,1 +8144,Man trap,1 +8145,Tangle vine,1 +8146,Marble trap,1 +8147,Teleport trap,1 +8148,Wooden crate,1 +8149,Oak chest,1 +8150,Teak chest,1 +8151,Mahogany chest,1 +8152,Magic chest,1 +8153,Clay attack stone,1 +8154,Attack stone,1 +8155,Marble att. stone,1 +8156,Magical balance 1,1 +8157,Magical balance 2,1 +8158,Magical balance 3,1 +8159,Jester,1 +8160,Treasure hunt,1 +8161,Hangman game,1 +8162,Hoop and stick,1 +8163,Dartboard,1 +8164,Archery target,1 +8165,Oak prize chest,1 +8166,Teak prize chest,1 +8167,Mahogany chest,1 +8168,Exit portal,1 +8169,Decorative rock,1 +8170,Pond,1 +8171,Imp statue,1 +8172,Dungeon entrance,1 +8173,Tree,1 +8174,Nice tree,1 +8175,Oak tree,1 +8176,Willow tree,1 +8177,Maple tree,1 +8178,Yew tree,1 +8179,Magic tree,1 +8180,Plant,1 +8181,Small fern,1 +8182,Fern,1 +8183,Dock leaf,1 +8184,Thistle,1 +8185,Reeds,1 +8186,Fern,1 +8187,Bush,1 +8188,Tall plant,1 +8189,Short plant,1 +8190,Large-leaf plant,1 +8191,Huge plant,1 +8192,Gazebo,1 +8193,Small fountain,1 +8194,Large fountain,1 +8195,Posh fountain,1 +8196,Boundary stones,1 +8197,Wooden fence,1 +8198,Stone wall,1 +8199,Iron railings,1 +8200,Picket fence,1 +8201,Garden fence,1 +8202,Marble wall,1 +8203,Thorny hedge,1 +8204,Nice hedge,1 +8205,Small box hedge,1 +8206,Topiary hedge,1 +8207,Fancy hedge,1 +8208,Tall fancy hedge,1 +8209,Tall box hedge,1 +8210,Rosemary,1 +8211,Daffodils,1 +8212,Bluebells,1 +8213,Sunflower,1 +8214,Marigolds,1 +8215,Roses,1 +8216,Firepit,1 +8217,Firepit with hook,1 +8218,Firepit with pot,1 +8219,Small oven,1 +8220,Large oven,1 +8221,Steel range,1 +8222,Fancy range,1 +8223,Wooden shelves 1,1 +8224,Wooden shelves 2,1 +8225,Wooden shelves 3,1 +8226,Oak shelves 1,1 +8227,Oak shelves 2,1 +8228,Teak shelves 1,1 +8229,Teak shelves 2,1 +8230,Pump and drain,1 +8231,Pump and tub,1 +8232,Sink,1 +8233,Wooden larder,1 +8234,Oak larder,1 +8235,Teak larder,1 +8236,Cat blanket,1 +8237,Cat basket,1 +8238,Cushioned basket,1 +8239,Beer barrel,1 +8240,Cider barrel,1 +8241,Asgarnian ale,1 +8242,Greenman's ale,1 +8243,Dragon bitter,1 +8244,Chef's delight,1 +8245,Blank poh entity,1 +8246,Wood kitchen table,1 +8247,Oak kitchen table,1 +8248,Teak kitchen table,1 +8249,Oak staircase,1 +8250,Oak staircase,1 +8251,Oak staircase,1 +8252,Teak staircase,1 +8253,Teak staircase,1 +8254,Teak staircase,1 +8255,Marble staircase,1 +8256,Marble staircase,1 +8257,Marble staircase,1 +8258,Spiral staircase,1 +8259,Marble spiral,1 +8260,Crawling hand,1 +8261,Cockatrice head,1 +8262,Basilisk head,1 +8263,Kurask head,1 +8264,Abyssal head,1 +8265,Kbd heads,1 +8266,Kq head,1 +8267,Mounted bass,1 +8268,Mounted swordfish,1 +8269,Mounted shark,1 +8270,Mithril armour,1 +8271,Adamantite armour,1 +8272,Runite armour,1 +8273,Cw armour 1,1 +8274,Cw armour 2,1 +8275,Cw armour 3,1 +8276,Rune case 1,1 +8277,Rune case 2,1 +8278,Rune case 3,1 +8279,Silverlight,1 +8280,Excalibur,1 +8281,Darklight,1 +8282,Anti-dragon shield,1 +8283,Amulet of glory,1 +8284,Cape of legends,1 +8285,King arthur,1 +8286,Elena,1 +8287,Giant dwarf,1 +8288,Miscellanians,1 +8289,Lumbridge,1 +8290,The desert,1 +8291,Morytania,1 +8292,Karamja,1 +8293,Isafdar,1 +8294,Small map,1 +8295,Medium map,1 +8296,Large map,1 +8297,Oak cage,1 +8298,Oak and steel cage,1 +8299,Steel cage,1 +8300,Spiked cage,1 +8301,Bone cage,1 +8302,Spikes,1 +8303,Tentacle pool,1 +8304,Flame pit,1 +8305,Rocnar,1 +8306,Oak ladder,1 +8307,Teak ladder,1 +8308,Mahogany ladder,1 +8309,Crude wooden chair,1 +8310,Wooden chair,1 +8311,Rocking chair,1 +8312,Oak chair,1 +8313,Oak armchair,1 +8314,Teak armchair,1 +8315,Mahogany armchair,1 +8316,Brown rug,1 +8317,Rug,1 +8318,Opulent rug,1 +8319,Wooden bookcase,1 +8320,Oak bookcase,1 +8321,Mahogany b'kcase,1 +8322,Torn curtains,1 +8323,Curtains,1 +8324,Opulent curtains,1 +8325,Clay fireplace,1 +8326,Stone fireplace,1 +8327,Marble fireplace,1 +8328,Teak portal,1 +8329,Mahogany portal,1 +8330,Marble portal,1 +8331,Teleport focus,1 +8332,Greater focus,1 +8333,Scrying pool,1 +8334,Oak lectern,1 +8335,Eagle lectern,1 +8336,Demon lectern,1 +8337,Teak eagle lectern,1 +8338,Teak demon lectern,1 +8339,Mahogany eagle,1 +8340,Mahogany demon,1 +8341,Globe,1 +8342,Ornamental globe,1 +8343,Lunar globe,1 +8344,Celestial globe,1 +8345,Armillary sphere,1 +8346,Small orrery,1 +8347,Large orrery,1 +8348,Wooden telescope,1 +8349,Teak telescope,1 +8350,Mahogany 'scope,1 +8351,Crystal ball,1 +8352,Elemental sphere,1 +8353,Crystal of power,1 +8354,Alchemical chart,1 +8355,Astronomical chart,1 +8356,Infernal chart,1 +8357,Oak throne,1 +8358,Teak throne,1 +8359,Mahogany throne,1 +8360,Gilded throne,1 +8361,Skeleton throne,1 +8362,Crystal throne,1 +8363,Demonic throne,1 +8364,Oak lever,1 +8365,Teak lever,1 +8366,Mahogany lever,1 +8367,Trapdoor,1 +8368,Trapdoor,1 +8369,Trapdoor,1 +8370,Floor decoration,1 +8371,Steel cage,1 +8372,Trapdoor,1 +8373,Lesser magic cage,1 +8374,Greater magic cage,1 +8375,Wooden workbench,1 +8376,Oak workbench,1 +8377,Steel framed bench,1 +8378,Bench with vice,1 +8379,Bench with lathe,1 +8380,Crafting table 1,1 +8381,Crafting table 2,1 +8382,Crafting table 3,1 +8383,Crafting table 4,1 +8384,Tool store 1,1 +8385,Tool store 2,1 +8386,Tool store 3,1 +8387,Tool store 4,1 +8388,Tool store 5,1 +8389,Repair bench,1 +8390,Whetstone,1 +8391,Armour stand,1 +8392,Pluming stand,1 +8393,Shield easel,1 +8394,Banner easel,1 +8395,Parlour,1000 +8396,Kitchen,5000 +8397,Dining room,5000 +8398,Bedroom,10000 +8399,Games room,25000 +8400,Combat room,25000 +8401,Hall,15000 +8402,Hall,15000 +8403,Hall,25000 +8404,Hall,25000 +8405,Chapel,50000 +8406,Workshop,10000 +8407,Study,50000 +8408,Portal chamber,100000 +8409,Throne room,150000 +8410,Oubliette,150000 +8411,Dungeon corridor,7500 +8412,Dungeon cross,7500 +8413,Dungeon stairs,7500 +8414,Treasure room,250000 +8415,Garden,1000 +8416,Formal garden,75000 +8417,Bagged dead tree,1000 +8418,Bagged dead tree,1000 +8419,Bagged nice tree,2000 +8420,Bagged nice tree,2000 +8421,Bagged oak tree,5000 +8422,Bagged oak tree,5000 +8423,Bagged willow tree,10000 +8424,Bagged willow tree,10000 +8425,Bagged maple tree,15000 +8426,Bagged maple tree,15000 +8427,Bagged yew tree,20000 +8428,Bagged yew tree,20000 +8429,Bagged magic tree,50000 +8430,Bagged magic tree,50000 +8431,Bagged plant 1,1000 +8432,Bagged plant 1,1000 +8433,Bagged plant 2,5000 +8434,Bagged plant 2,5000 +8435,Bagged plant 3,10000 +8436,Bagged plant 3,10000 +8437,Thorny hedge,5000 +8438,Thorny hedge,5000 +8439,Nice hedge,10000 +8440,Nice hedge,10000 +8441,Small box hedge,15000 +8442,Small box hedge,15000 +8443,Topiary hedge,20000 +8444,Topiary hedge,20000 +8445,Fancy hedge,25000 +8446,Fancy hedge,25000 +8447,Tall fancy hedge,50000 +8448,Tall fancy hedge,50000 +8449,Tall box hedge,100000 +8450,Tall box hedge,100000 +8451,Bagged rosemary,5000 +8452,Bagged rosemary,5000 +8453,Bagged daffodils,10000 +8454,Bagged daffodils,10000 +8455,Bagged bluebells,15000 +8456,Bagged bluebells,15000 +8457,Bagged sunflower,5000 +8458,Bagged sunflower,5000 +8459,Bagged marigolds,10000 +8460,Bagged marigolds,10000 +8461,Bagged roses,15000 +8462,Bagged roses,15000 +8463,Construction guide,1 +8464,Rune heraldic helm,35200 +8465,null,1 +8466,Rune heraldic helm,35200 +8467,null,1 +8468,Rune heraldic helm,35200 +8469,null,1 +8470,Rune heraldic helm,35200 +8471,null,1 +8472,Rune heraldic helm,35200 +8473,null,1 +8474,Rune heraldic helm,35200 +8475,null,1 +8476,Rune heraldic helm,35200 +8477,null,1 +8478,Rune heraldic helm,35200 +8479,null,1 +8480,Rune heraldic helm,35200 +8481,null,1 +8482,Rune heraldic helm,35200 +8483,null,1 +8484,Rune heraldic helm,35200 +8485,null,1 +8486,Rune heraldic helm,35200 +8487,null,1 +8488,Rune heraldic helm,35200 +8489,null,1 +8490,Rune heraldic helm,35200 +8491,null,1 +8492,Rune heraldic helm,35200 +8493,null,1 +8494,Rune heraldic helm,35200 +8495,null,1 +8496,Crude wooden chair,10 +8497,Crude wooden chair,10 +8498,Wooden chair,10 +8499,Wooden chair,10 +8500,Rocking chair,10 +8501,Rocking chair,10 +8502,Oak chair,10 +8503,Oak chair,10 +8504,Oak armchair,10 +8505,Oak armchair,10 +8506,Teak armchair,10 +8507,Teak armchair,10 +8508,Mahogany armchair,10 +8509,Mahogany armchair,10 +8510,Wooden bookcase,10 +8511,Wooden bookcase,10 +8512,Oak bookcase,10 +8513,Oak bookcase,10 +8514,Mahogany b'kcase,10 +8515,Mahogany b'kcase,10 +8516,Beer barrel,10 +8517,Beer barrel,10 +8518,Cider barrel,10 +8519,Cider barrel,10 +8520,Asgarnian ale,10 +8521,Asgarnian ale,10 +8522,Greenman's ale,10 +8523,Greenman's ale,10 +8524,Dragon bitter,10 +8525,Dragon bitter,10 +8526,Chef's delight,10 +8527,Chef's delight,10 +8528,Wood kitchen table,10 +8529,Wood kitchen table,10 +8530,Oak kitchen table,10 +8531,Oak kitchen table,10 +8532,Teak kitchen table,10 +8533,Teak kitchen table,10 +8534,Oak lectern,10 +8535,Oak lectern,10 +8536,Eagle lectern,10 +8537,Eagle lectern,10 +8538,Demon lectern,10 +8539,Demon lectern,10 +8540,Teak eagle lectern,10 +8541,Teak eagle lectern,10 +8542,Teak demon lectern,10 +8543,Teak demon lectern,10 +8544,Mahogany eagle,10 +8545,Mahogany eagle,10 +8546,Mahogany demon,10 +8547,Mahogany demon,10 +8548,Wood dining table,10 +8549,Wood dining table,10 +8550,Oak dining table,10 +8551,Oak dining table,10 +8552,Carved oak table,10 +8553,Carved oak table,10 +8554,Teak table,10 +8555,Teak table,10 +8556,Carved teak table,10 +8557,Carved teak table,10 +8558,Mahogany table,10 +8559,Mahogany table,10 +8560,Opulent table,10 +8561,Opulent table,10 +8562,Wooden bench,10 +8563,Wooden bench,10 +8564,Oak bench,10 +8565,Oak bench,10 +8566,Carved oak bench,10 +8567,Carved oak bench,10 +8568,Teak dining bench,10 +8569,Teak dining bench,10 +8570,Carved teak bench,10 +8571,Carved teak bench,10 +8572,Mahogany bench,10 +8573,Mahogany bench,10 +8574,Gilded bench,10 +8575,Gilded bench,10 +8576,Wooden bed,10 +8577,Wooden bed,10 +8578,Oak bed,10 +8579,Oak bed,10 +8580,Large oak bed,10 +8581,Large oak bed,10 +8582,Teak bed,10 +8583,Teak bed,10 +8584,Large teak bed,10 +8585,Large teak bed,10 +8586,4-poster,10 +8587,4-poster,10 +8588,Gilded 4-poster,10 +8589,Gilded 4-poster,10 +8590,Oak clock,10 +8591,Oak clock,10 +8592,Teak clock,10 +8593,Teak clock,10 +8594,Gilded clock,10 +8595,Gilded clock,10 +8596,Shaving stand,10 +8597,Shaving stand,10 +8598,Oak shaving stand,10 +8599,Oak shaving stand,10 +8600,Oak dresser,10 +8601,Oak dresser,10 +8602,Teak dresser,10 +8603,Teak dresser,10 +8604,Fancy teak dresser,10 +8605,Fancy teak dresser,10 +8606,Mahogany dresser,10 +8607,Mahogany dresser,10 +8608,Gilded dresser,10 +8609,Gilded dresser,10 +8610,Shoe box,10 +8611,Shoe box,10 +8612,Oak drawers,10 +8613,Oak drawers,10 +8614,Oak wardrobe,10 +8615,Oak wardrobe,10 +8616,Teak drawers,10 +8617,Teak drawers,10 +8618,Teak wardrobe,10 +8619,Teak wardrobe,10 +8620,Mahogany 'drobe,10 +8621,Mahogany 'drobe,10 +8622,Gilded wardrobe,10 +8623,Gilded wardrobe,10 +8624,Crystal ball,10 +8625,Crystal ball,10 +8626,Elemental sphere,10 +8627,Elemental sphere,10 +8628,Crystal of power,10 +8629,Crystal of power,10 +8630,Globe,10 +8631,Globe,10 +8632,Ornamental globe,10 +8633,Ornamental globe,10 +8634,Lunar globe,10 +8635,Lunar globe,10 +8636,Celestial globe,10 +8637,Celestial globe,10 +8638,Armillary sphere,10 +8639,Armillary sphere,10 +8640,Small orrery,10 +8641,Small orrery,10 +8642,Large orrery,10 +8643,Large orrery,10 +8644,Wooden telescope,10 +8645,Wooden telescope,10 +8646,Teak telescope,10 +8647,Teak telescope,10 +8648,Mahogany 'scope,10 +8649,Mahogany 'scope,10 +8650,Banner,1 +8651,null,1 +8652,Banner,1 +8653,null,1 +8654,Banner,1 +8655,null,1 +8656,Banner,1 +8657,null,1 +8658,Banner,1 +8659,null,1 +8660,Banner,1 +8661,null,1 +8662,Banner,1 +8663,null,1 +8664,Banner,1 +8665,null,1 +8666,Banner,1 +8667,null,1 +8668,Banner,1 +8669,null,1 +8670,Banner,1 +8671,null,1 +8672,Banner,1 +8673,null,1 +8674,Banner,1 +8675,null,1 +8676,Banner,1 +8677,null,1 +8678,Banner,1 +8679,null,1 +8680,Banner,1 +8681,null,1 +8682,Steel heraldic helm,600 +8683,null,1 +8684,Steel heraldic helm,600 +8685,null,1 +8686,Steel heraldic helm,600 +8687,null,1 +8688,Steel heraldic helm,600 +8689,null,1 +8690,Steel heraldic helm,600 +8691,null,1 +8692,Steel heraldic helm,600 +8693,null,1 +8694,Steel heraldic helm,600 +8695,null,1 +8696,Steel heraldic helm,600 +8697,null,1 +8698,Steel heraldic helm,600 +8699,null,1 +8700,Steel heraldic helm,600 +8701,null,1 +8702,Steel heraldic helm,600 +8703,null,1 +8704,Steel heraldic helm,600 +8705,null,1 +8706,Steel heraldic helm,600 +8707,null,1 +8708,Steel heraldic helm,600 +8709,null,1 +8710,Steel heraldic helm,600 +8711,null,1 +8712,Steel heraldic helm,600 +8713,null,1 +8714,Rune kiteshield,54400 +8715,null,1 +8716,Rune kiteshield,54400 +8717,null,1 +8718,Rune kiteshield,54400 +8719,null,1 +8720,Rune kiteshield,54400 +8721,null,1 +8722,Rune kiteshield,54400 +8723,null,1 +8724,Rune kiteshield,54400 +8725,null,1 +8726,Rune kiteshield,54400 +8727,null,1 +8728,Rune kiteshield,54400 +8729,null,1 +8730,Rune kiteshield,54400 +8731,null,1 +8732,Rune kiteshield,54400 +8733,null,1 +8734,Rune kiteshield,54400 +8735,null,1 +8736,Rune kiteshield,54400 +8737,null,1 +8738,Rune kiteshield,54400 +8739,null,1 +8740,Rune kiteshield,54400 +8741,null,1 +8742,Rune kiteshield,54400 +8743,null,1 +8744,Rune kiteshield,54400 +8745,null,1 +8746,Steel kiteshield,900 +8747,null,1 +8748,Steel kiteshield,900 +8749,null,1 +8750,Steel kiteshield,900 +8751,null,1 +8752,Steel kiteshield,900 +8753,null,1 +8754,Steel kiteshield,900 +8755,null,1 +8756,Steel kiteshield,900 +8757,null,1 +8758,Steel kiteshield,900 +8759,null,1 +8760,Steel kiteshield,900 +8761,null,1 +8762,Steel kiteshield,900 +8763,null,1 +8764,Steel kiteshield,900 +8765,null,1 +8766,Steel kiteshield,900 +8767,null,1 +8768,Steel kiteshield,900 +8769,null,1 +8770,Steel kiteshield,900 +8771,null,1 +8772,Steel kiteshield,900 +8773,null,1 +8774,Steel kiteshield,900 +8775,null,1 +8776,Steel kiteshield,900 +8777,null,1 +8778,Oak plank,250 +8779,Oak plank,250 +8780,Teak plank,500 +8781,Teak plank,500 +8782,Mahogany plank,1500 +8783,Mahogany plank,1500 +8784,Gold leaf,130000 +8785,Gold leaf,130000 +8786,Marble block,325000 +8787,Marble block,325000 +8788,Magic stone,975000 +8789,Magic stone,975000 +8790,Bolt of cloth,650 +8791,Bolt of cloth,650 +8792,Clockwork,500 +8793,Clockwork,500 +8794,Saw,13 +8795,Saw,13 +8796,Thing,20 +8797,Picture,1 +8798,null,1 +8799,null,1 +8800,null,1 +8801,null,1 +8802,null,1 +8803,null,1 +8804,null,1 +8805,null,1 +8806,null,1 +8807,null,1 +8808,null,1 +8809,null,1 +8810,null,1 +8811,null,1 +8812,null,1 +8813,null,1 +8814,null,1 +8815,null,1 +8816,null,1 +8817,null,1 +8818,null,1 +8819,null,1 +8820,null,1 +8821,null,1 +8822,null,1 +8823,null,1 +8824,null,1 +8825,null,1 +8826,null,1 +8827,null,1 +8828,null,1 +8829,null,1 +8830,null,1 +8831,null,1 +8832,null,1 +8833,null,1 +8834,null,1 +8835,null,1 +8836,Mahogany logs,50 +8837,Timber beam,1 +8838,Timber beam,1 +8839,Void knight top,48000 +8840,Void knight robe,45000 +8841,Void knight mace,12000 +8842,Void knight gloves,6052 +8843,null,1 +8844,Bronze defender,1 +8845,Iron defender,1 +8846,Steel defender,1 +8847,Black defender,1 +8848,Mithril defender,1 +8849,Adamant defender,1 +8850,Rune defender,1 +8851,Warrior guild token,1 +8852,null,1 +8853,null,1 +8854,null,1 +8855,null,1 +8856,Defensive shield,1 +8857,Shot,1 +8858,18lb shot,1 +8859,22lb shot,1 +8860,One barrel,1 +8861,Two barrels,1 +8862,Three barrels,1 +8863,Four barrels,1 +8864,Five barrels,1 +8865,Ground ashes,2 +8866,Steel key,1 +8867,Bronze key,1 +8868,Silver key,1 +8869,Iron key,1 +8870,Zanik,1 +8871,Crate with zanik,1 +8872,Bone dagger,2000 +8873,Bone dagger,2000 +8874,Bone dagger (p),2000 +8875,Bone dagger (p),2000 +8876,Bone dagger (p+),2000 +8877,Bone dagger (p+),2000 +8878,Bone dagger (p++),2000 +8879,Bone dagger (p++),2000 +8880,Dorgeshuun c'bow,2000 +8881,Dorgeshuun c'bow,2000 +8882,Bone bolts,4 +8883,null,1 +8884,null,1 +8885,null,1 +8886,null,1 +8887,Zanik,1 +8888,Zanik (ham),1 +8889,Zanik (showdown),1 +8890,Coins,1 +8891,null,1 +8892,null,1 +8893,null,1 +8894,null,1 +8895,null,1 +8896,null,1 +8897,null,1 +8898,null,1 +8899,null,1 +8900,Cave horror,1 +8901,Black mask (10),3000 +8902,Black mask (10),3000 +8903,Black mask (9),3000 +8904,Black mask (9),3000 +8905,Black mask (8),3000 +8906,Black mask (8),3000 +8907,Black mask (7),3000 +8908,Black mask (7),3000 +8909,Black mask (6),3000 +8910,Black mask (6),3000 +8911,Black mask (5),3000 +8912,Black mask (5),3000 +8913,Black mask (4),3000 +8914,Black mask (4),3000 +8915,Black mask (3),3000 +8916,Black mask (3),3000 +8917,Black mask (2),3000 +8918,Black mask (2),3000 +8919,Black mask (1),3000 +8920,Black mask (1),3000 +8921,Black mask,3000 +8922,Black mask,3000 +8923,Witchwood icon,900 +8924,Bandana and eyepatch,100 +8925,Bandana and eyepatch,100 +8926,Bandana and eyepatch,100 +8927,Bandana and eyepatch,100 +8928,Hat and eyepatch,100 +8929,Crabclaw and hook,100 +8930,Pipe section,1 +8931,Pipe section,1 +8932,Lumber patch,1 +8933,Lumber patch,1 +8934,Scrapey tree logs,1 +8935,Scrapey tree logs,1 +8936,Blue flowers,1 +8937,Blue flowers,1 +8938,Red flowers,1 +8939,Red flowers,1 +8940,Rum,2 +8941,Rum,2 +8942,Monkey,1 +8943,Blue monkey,1 +8944,Blue monkey,1 +8945,Blue monkey,1 +8946,Red monkey,1 +8947,Red monkey,1 +8948,Red monkey,1 +8949,Pirate bandana,1 +8950,Pirate hat,1 +8951,Pieces of eight,1 +8952,Blue naval shirt,100 +8953,Green naval shirt,100 +8954,Red naval shirt,100 +8955,Brown naval shirt,100 +8956,Black naval shirt,100 +8957,Purple naval shirt,100 +8958,Grey naval shirt,100 +8959,Blue tricorn hat,50 +8960,Green tricorn hat,50 +8961,Red tricorn hat,50 +8962,Brown tricorn hat,50 +8963,Black tricorn hat,50 +8964,Purple tricorn hat,50 +8965,Grey tricorn hat,50 +8966,Cutthroat flag,200 +8967,Guilded smile flag,200 +8968,Bronze fist flag,300 +8969,Lucky shot flag,400 +8970,Treasure flag,500 +8971,Phasmatys flag,600 +8972,Bowl of red water,1 +8973,Bowl of red water,1 +8974,Bowl of blue water,1 +8975,Bowl of blue water,1 +8976,Bitternut,1 +8977,Scrapey bark,1 +8978,Scrapey bark,1 +8979,Bridge section,1 +8980,Bridge section,1 +8981,Sweetgrubs,1 +8982,Sweetgrubs,1 +8983,null,1 +8984,null,1 +8985,null,1 +8986,Bucket,1 +8987,Torch,1 +8988,The stuff,5 +8989,Brewin' guide,1 +8990,Brewin' guide,1 +8991,Blue navy slacks,100 +8992,Green navy slacks,100 +8993,Red navy slacks,100 +8994,Brown navy slacks,100 +8995,Black navy slacks,100 +8996,Purple navy slacks,100 +8997,Grey navy slacks,100 +8998,Bandana and eyepatch,100 +8999,Bandana and eyepatch,100 +9000,Bandana and eyepatch,100 +9001,Bandana and eyepatch,100 +9002,Hat and eyepatch,100 +9003,Security book,2 +9004,Stronghold notes,2 +9005,Fancy boots,1 +9006,Fighting boots,1 +9007,Right skull half,1 +9008,Left skull half,1 +9009,Strange skull,1 +9010,Top of sceptre,1 +9011,Bottom of sceptre,1 +9012,Runed sceptre,1 +9013,Skull sceptre,1 +9014,Security book,2 +9015,Stronghold notes,2 +9016,Gorak claws,150 +9017,Star flower,75 +9018,Gorak claw powder,150 +9019,Magic essence(unf),75 +9020,Queen's secateurs,1 +9021,Magic essence(4),280 +9022,Magic essence(3),230 +9023,Magic essence(2),180 +9024,Magic essence(1),130 +9025,Nuff's certificate,1 +9026,Ivory comb,10 +9027,Ivory comb,10 +9028,Golden scarab,30 +9029,Golden scarab,30 +9030,Stone scarab,20 +9031,Stone scarab,20 +9032,Pottery scarab,10 +9033,Pottery scarab,10 +9034,Golden statuette,30 +9035,Golden statuette,30 +9036,Pottery statuette,10 +9037,Pottery statuette,10 +9038,Stone statuette,20 +9039,Stone statuette,20 +9040,Gold seal,30 +9041,Gold seal,30 +9042,Stone seal,20 +9043,Stone seal,20 +9044,Pharaoh's sceptre,100 +9045,Pharaoh's sceptre,100 +9046,Pharaoh's sceptre,100 +9047,Pharaoh's sceptre,100 +9048,Pharaoh's sceptre,100 +9049,Pharaoh's sceptre,100 +9050,Pharaoh's sceptre,100 +9051,Pharaoh's sceptre,100 +9052,Locust meat,1 +9053,Locust meat,1 +9054,Red goblin mail,40 +9055,Black goblin mail,40 +9056,Yellow goblin mail,40 +9057,Green goblin mail,40 +9058,Purple goblin mail,40 +9059,Pink goblin mail,40 +9060,null,1 +9061,null,1 +9062,null,1 +9063,null,1 +9064,Emerald lantern,20 +9065,Emerald lantern,20 +9066,Emerald lens,10 +9067,Dream log,4 +9068,Moonclan helm,1000 +9069,Moonclan hat,1000 +9070,Moonclan armour,1000 +9071,Moonclan skirt,1000 +9072,Moonclan gloves,900 +9073,Moonclan boots,900 +9074,Moonclan cape,200 +9075,Astral rune,220 +9076,Lunar ore,3 +9077,Lunar bar,8 +9078,Moonclan manual,1 +9079,Suqah tooth,20 +9080,Suqah hide,60 +9081,Suqah leather,60 +9082,Ground tooth,20 +9083,Seal of passage,1 +9084,Lunar staff,1 +9085,Empty vial,1 +9086,Vial of water,1 +9087,Waking sleep vial,1 +9088,Guam vial,1 +9089,Marr vial,1 +9090,Guam-marr vial,1 +9091,Lunar staff - pt1,15 +9092,Lunar staff - pt2,15 +9093,Lunar staff - pt3,15 +9094,Kindling,1 +9095,Soaked kindling,1 +9096,Lunar helm,100 +9097,Lunar torso,100 +9098,Lunar legs,100 +9099,Lunar gloves,100 +9100,Lunar boots,100 +9101,Lunar cape,2 +9102,Lunar amulet,30 +9103,A special tiara,30 +9104,Lunar ring,100 +9105,Suqah monster,1 +9106,Astral tiara,100 +9107,null,1 +9108,null,1 +9109,null,1 +9110,null,1 +9111,null,1 +9112,null,1 +9113,null,1 +9114,null,1 +9115,null,1 +9116,null,1 +9117,null,1 +9118,null,1 +9119,null,1 +9120,null,1 +9121,null,1 +9122,null,1 +9123,null,1 +9124,null,1 +9125,null,1 +9126,null,1 +9127,null,1 +9128,null,1 +9129,null,1 +9130,null,1 +9131,null,1 +9132,null,1 +9133,null,1 +9134,null,1 +9135,null,1 +9136,null,1 +9137,null,1 +9138,null,1 +9139,Blurite bolts,2 +9140,Iron bolts,2 +9141,Steel bolts,8 +9142,Mithril bolts,20 +9143,Adamant bolts,58 +9144,Rune bolts,300 +9145,Silver bolts,5 +9146,null,1 +9147,null,1 +9148,null,1 +9149,null,1 +9150,null,1 +9151,null,1 +9152,null,1 +9153,null,1 +9154,null,1 +9155,null,1 +9156,null,1 +9157,null,1 +9158,null,1 +9159,null,1 +9160,null,1 +9161,null,1 +9162,null,1 +9163,null,1 +9164,null,1 +9165,null,1 +9166,null,1 +9167,null,1 +9168,null,1 +9169,null,1 +9170,null,1 +9171,null,1 +9172,null,1 +9173,null,1 +9174,Bronze crossbow,73 +9175,Bronze crossbow,73 +9176,Blurite crossbow,93 +9177,Iron crossbow,157 +9178,Iron crossbow,157 +9179,Steel crossbow,360 +9180,Steel crossbow,360 +9181,Mith crossbow,783 +9182,Mith crossbow,783 +9183,Adamant crossbow,1767 +9184,Adamant crossbow,1767 +9185,Rune crossbow,16200 +9186,Rune crossbow,16200 +9187,Jade bolt tips,10 +9188,Topaz bolt tips,13 +9189,Sapphire bolt tips,17 +9190,Emerald bolt tips,33 +9191,Ruby bolt tips,67 +9192,Diamond bolt tips,133 +9193,Dragon bolt tips,667 +9194,Onyx bolt tips,1000 +9195,null,1 +9196,null,1 +9197,null,1 +9198,null,1 +9199,null,1 +9200,null,1 +9201,null,1 +9202,null,1 +9203,null,1 +9204,null,1 +9205,null,1 +9206,null,1 +9207,null,1 +9208,null,1 +9209,null,1 +9210,null,1 +9211,null,1 +9212,null,1 +9213,null,1 +9214,null,1 +9215,null,1 +9216,null,1 +9217,null,1 +9218,null,1 +9219,null,1 +9220,null,1 +9221,null,1 +9222,null,1 +9223,null,1 +9224,null,1 +9225,null,1 +9226,null,1 +9227,null,1 +9228,null,1 +9229,null,1 +9230,null,1 +9231,null,1 +9232,null,1 +9233,null,1 +9234,null,1 +9235,null,1 +9236,Opal bolts (e),7 +9237,Jade bolts (e),13 +9238,Pearl bolts (e),15 +9239,Topaz bolts (e),24 +9240,Sapphire bolts (e),40 +9241,Emerald bolts (e),59 +9242,Ruby bolts (e),138 +9243,Diamond bolts (e),211 +9244,Dragon bolts (e),1063 +9245,Onyx bolts (e),15000 +9246,null,1 +9247,null,1 +9248,null,1 +9249,null,1 +9250,null,1 +9251,null,1 +9252,null,1 +9253,null,1 +9254,null,1 +9255,null,1 +9256,null,1 +9257,null,1 +9258,null,1 +9259,null,1 +9260,null,1 +9261,null,1 +9262,null,1 +9263,null,1 +9264,null,1 +9265,null,1 +9266,null,1 +9267,null,1 +9268,null,1 +9269,null,1 +9270,null,1 +9271,null,1 +9272,null,1 +9273,null,1 +9274,null,1 +9275,null,1 +9276,null,1 +9277,null,1 +9278,null,1 +9279,null,1 +9280,null,1 +9281,null,1 +9282,null,1 +9283,null,1 +9284,null,1 +9285,null,1 +9286,Blurite bolts(p),2 +9287,Iron bolts (p),2 +9288,Steel bolts (p),8 +9289,Mithril bolts (p),20 +9290,Adamant bolts (p),58 +9291,Runite bolts (p),300 +9292,Silver bolts (p),5 +9293,Blurite bolts(p+),2 +9294,Iron bolts(p+),2 +9295,Steel bolts(p+),8 +9296,Mithril bolts(p+),20 +9297,Adamant bolts(p+),58 +9298,Runite bolts(p+),300 +9299,Silver bolts(p+),5 +9300,Blurite bolts(p++),2 +9301,Iron bolts(p++),2 +9302,Steel bolts(p++),8 +9303,Mithril bolts(p++),20 +9304,Adamant bolts(p++),58 +9305,Runite bolts(p++),300 +9306,Silver bolts(p++),5 +9307,null,1 +9308,null,1 +9309,null,1 +9310,null,1 +9311,null,1 +9312,null,1 +9313,null,1 +9314,null,1 +9315,null,1 +9316,null,1 +9317,null,1 +9318,null,1 +9319,null,1 +9320,null,1 +9321,null,1 +9322,null,1 +9323,null,1 +9324,null,1 +9325,null,1 +9326,null,1 +9327,null,1 +9328,null,1 +9329,null,1 +9330,null,1 +9331,null,1 +9332,null,1 +9333,null,1 +9334,null,1 +9335,Jade bolts,12 +9336,Topaz bolts,22 +9337,Sapphire bolts,37 +9338,Emerald bolts,53 +9339,Ruby bolts,125 +9340,Diamond bolts,192 +9341,Dragon bolts,967 +9342,Onyx bolts,13633 +9343,null,1 +9344,null,1 +9345,null,1 +9346,null,1 +9347,null,1 +9348,null,1 +9349,null,1 +9350,null,1 +9351,null,1 +9352,null,1 +9353,null,1 +9354,null,1 +9355,null,1 +9356,null,1 +9357,null,1 +9358,null,1 +9359,null,1 +9360,null,1 +9361,null,1 +9362,null,1 +9363,null,1 +9364,null,1 +9365,null,1 +9366,null,1 +9367,null,1 +9368,null,1 +9369,null,1 +9370,null,1 +9371,null,1 +9372,null,1 +9373,null,1 +9374,null,1 +9375,Bronze bolts (unf),1 +9376,Blurite bolts (unf),1 +9377,Iron bolts (unf),1 +9378,Steel bolts (unf),1 +9379,Mithril bolts (unf),1 +9380,Adamant bolts(unf),1 +9381,Runite bolts (unf),1 +9382,Silver bolts (unf),1 +9383,null,1 +9384,null,1 +9385,null,1 +9386,null,1 +9387,null,1 +9388,null,1 +9389,null,1 +9390,null,1 +9391,null,1 +9392,null,1 +9393,null,1 +9394,null,1 +9395,null,1 +9396,null,1 +9397,null,1 +9398,null,1 +9399,null,1 +9400,null,1 +9401,null,1 +9402,null,1 +9403,null,1 +9404,null,1 +9405,null,1 +9406,null,1 +9407,null,1 +9408,null,1 +9409,null,1 +9410,null,1 +9411,null,1 +9412,null,1 +9413,null,1 +9414,null,1 +9415,Grapple,1 +9416,Mith grapple tip,30 +9417,Mith grapple tip,30 +9418,Mith grapple,48 +9419,Mith grapple,1 +9420,Bronze limbs,20 +9421,Bronze limbs,20 +9422,Blurite limbs,33 +9423,Iron limbs,70 +9424,Iron limbs,70 +9425,Steel limbs,250 +9426,Steel limbs,250 +9427,Mithril limbs,650 +9428,Mithril limbs,650 +9429,Adamantite limbs,1600 +9430,Adamantite limbs,1600 +9431,Runite limbs,16000 +9432,Runite limbs,16000 +9433,Bolt pouch,5000 +9434,Bolt mould,25 +9435,Bolt mould,25 +9436,Sinew,2 +9437,Sinew,2 +9438,Crossbow string,1 +9439,Crossbow string,1 +9440,Wooden stock,20 +9441,Wooden stock,20 +9442,Oak stock,27 +9443,Oak stock,27 +9444,Willow stock,53 +9445,Willow stock,53 +9446,Teak stock,77 +9447,Teak stock,77 +9448,Maple stock,100 +9449,Maple stock,100 +9450,Mahogany stock,133 +9451,Mahogany stock,133 +9452,Yew stock,167 +9453,Yew stock,167 +9454,Bronze c'bow (u),40 +9455,Bronze c'bow (u),40 +9456,Blurite c'bow (u),60 +9457,Iron c'bow (u),123 +9458,Iron c'bow (u),123 +9459,Steel c'bow (u),327 +9460,Steel c'bow (u),327 +9461,Mithril c'bow (u),750 +9462,Mithril c'bow (u),750 +9463,Adamant c'bow (u),1733 +9464,Adamant c'bow (u),1733 +9465,Runite c'bow (u),16167 +9466,Runite c'bow (u),16167 +9467,Blurite bar,18 +9468,Sawdust,1 +9469,Grand seed pod,250 +9470,Gnome scarf,1000 +9471,Gnome scarf,1000 +9472,Gnome goggles,1000 +9473,Gnome goggles,1000 +9474,Reward token,250 +9475,Mint cake,250 +9476,Mint cake,250 +9477,Aluft aloft box,1 +9478,Half made batta,2 +9479,Unfinished batta,2 +9480,Half made batta,2 +9481,Unfinished batta,2 +9482,Half made batta,2 +9483,Half made batta,2 +9484,Unfinished batta,2 +9485,Half made batta,2 +9486,Unfinished batta,2 +9487,Wizard blizzard,1 +9488,Wizard blizzard,1 +9489,Wizard blizzard,1 +9490,Picture,1 +9491,null,1 +9492,null,1 +9493,null,1 +9494,null,1 +9495,null,1 +9496,null,1 +9497,null,1 +9498,null,1 +9499,null,1 +9500,null,1 +9501,null,1 +9502,null,1 +9503,null,1 +9504,null,1 +9505,null,1 +9506,null,1 +9507,null,1 +9508,Wizard blizzard,1 +9509,Wizard blizzard,1 +9510,Short green guy,1 +9511,Short green guy,1 +9512,Pineapple punch,1 +9513,Pineapple punch,1 +9514,Fruit blast,1 +9515,Fruit blast,1 +9516,Drunk dragon,1 +9517,Drunk dragon,1 +9518,Choc saturday,1 +9519,Choc saturday,1 +9520,Blurberry special,1 +9521,Blurberry special,1 +9522,Batta tin,1 +9523,Batta tin,1 +9524,Batta tin,1 +9525,Batta tin,1 +9526,null,1 +9527,Fruit batta,1 +9528,Fruit batta,1 +9529,Toad batta,1 +9530,Toad batta,1 +9531,Worm batta,1 +9532,Worm batta,1 +9533,Vegetable batta,1 +9534,Vegetable batta,1 +9535,Cheese+tom batta,1 +9536,Cheese+tom batta,1 +9537,null,1 +9538,Toad crunchies,1 +9539,Toad crunchies,1 +9540,Spicy crunchies,1 +9541,Spicy crunchies,1 +9542,Worm crunchies,1 +9543,Worm crunchies,1 +9544,Chocchip crunchies,1 +9545,Chocchip crunchies,1 +9546,null,1 +9547,Worm hole,1 +9548,Worm hole,1 +9549,Veg ball,1 +9550,Veg ball,1 +9551,Tangled toads' legs,1 +9552,Tangled toads' legs,1 +9553,Chocolate bomb,1 +9554,Chocolate bomb,1 +9555,null,1 +9556,null,1 +9557,null,1 +9558,Half made bowl,2 +9559,Half made bowl,2 +9560,Unfinished bowl,2 +9561,Half made bowl,2 +9562,Unfinished bowl,2 +9563,Half made bowl,2 +9564,Unfinished bowl,2 +9565,Cocktail shaker,2 +9566,Mixed blizzard,2 +9567,Mixed sgg,2 +9568,Mixed blast,2 +9569,Mixed punch,2 +9570,Mixed blurberry special,2 +9571,Mixed saturday,2 +9572,Mixed saturday,2 +9573,Mixed saturday,2 +9574,Mixed dragon,2 +9575,Mixed dragon,2 +9576,Mixed dragon,2 +9577,Half made crunchy,2 +9578,Unfinished crunchy,2 +9579,Half made crunchy,2 +9580,Unfinished crunchy,2 +9581,Half made crunchy,2 +9582,Unfinished crunchy,2 +9583,Half made crunchy,2 +9584,Unfinished crunchy,2 +9585,Batta tin,10 +9586,Crunchy tray,10 +9587,Gnomebowl mould,10 +9588,Raw crunchies,2 +9589,Dossier,1 +9590,Dossier,1 +9591,Broken cauldron,1 +9592,Magic glue,1 +9593,Weird gloop,1 +9594,Ground mud runes,1 +9595,Hazelmere's book,1 +9596,Picture,10 +9597,Red circle,1 +9598,Red triangle,1 +9599,Red square,1 +9600,Red pentagon,1 +9601,Orange circle,1 +9602,Orange triangle,1 +9603,Orange square,1 +9604,Orange pentagon,1 +9605,Yellow circle,1 +9606,Yellow triangle,1 +9607,Yellow square,1 +9608,Yellow pentagon,1 +9609,Green circle,1 +9610,Green triangle,1 +9611,Green square,1 +9612,Green pentagon,1 +9613,Blue circle,1 +9614,Blue triangle,1 +9615,Blue square,1 +9616,Blue pentagon,1 +9617,Indigo circle,1 +9618,Indigo triangle,1 +9619,Indigo square,1 +9620,Indigo pentagon,1 +9621,Violet circle,1 +9622,Violet triangle,1 +9623,Violet square,1 +9624,Violet pentagon,1 +9625,Crystal saw,10 +9626,Small crystal seed,10000 +9627,A handwritten book,2 +9628,null,1 +9629,Tyras helm,1265 +9630,Tyras helm,1265 +9631,null,2 +9632,Daeyalt ore,100 +9633,Message,1 +9634,Vyrewatch top,650 +9635,Vyrewatch top,650 +9636,Vyrewatch legs,650 +9637,Vyrewatch legs,650 +9638,Vyrewatch shoes,650 +9639,Vyrewatch shoes,650 +9640,Citizen top,6 +9641,Citizen top,6 +9642,Citizen trousers,6 +9643,Citizen trousers,6 +9644,Citizen shoes,6 +9645,Citizen shoes,6 +9646,Castle sketch 1,1 +9647,Castle sketch 2,1 +9648,Castle sketch 3,1 +9649,Message,1 +9650,Blood tithe pouch,1 +9651,Large ornate key,1 +9652,Haemalchemy,1 +9653,Sealed message,1 +9654,Door key,1 +9655,Ladder top,1 +9656,Tome of xp (3),1 +9657,Tome of xp (2),1 +9658,Tome of xp (1),1 +9659,Bucket of water,1 +9660,Bucket,1 +9661,null,1 +9662,Shortcut key,1 +9663,null,1 +9664,null,1 +9665,Torch,1 +9666,Pros'yte harness m,25000 +9667,Pros'yte harness m,25000 +9668,Initiate harness m,20000 +9669,Initiate harness m,20000 +9670,Pros'yte harness f,25000 +9671,Pros'yte harness f,25000 +9672,Proselyte sallet,8000 +9673,Proselyte sallet,8000 +9674,Proselyte hauberk,12000 +9675,Proselyte hauberk,12000 +9676,Proselyte cuisse,10000 +9677,Proselyte cuisse,10000 +9678,Proselyte tasset,10000 +9679,Proselyte tasset,10000 +9680,Sea slug glue,1 +9681,Commorb v2,1 +9682,Door transcription,1 +9683,Dead sea slug,0 +9684,Page 1,1 +9685,Page 2,1 +9686,Page 3,1 +9687,Fragment 1,1 +9688,Fragment 2,1 +9689,Fragment 3,1 +9690,Blank water rune,1 +9691,Water rune,1 +9692,Blank air rune,1 +9693,Air rune,1 +9694,Blank earth rune,1 +9695,Earth rune,1 +9696,Blank mind rune,1 +9697,Mind rune,1 +9698,Blank fire rune,1 +9699,Fire rune,1 +9700,Picture,1 +9701,Torch,1 +9702,Stick,1 +9703,Training sword,1 +9704,Training shield,1 +9705,Training bow,1 +9706,Training arrows,1 +9707,null,1 +9708,null,1 +9709,null,1 +9710,null,1 +9711,null,1 +9712,null,1 +9713,null,1 +9714,null,1 +9715,Slashed book,10 +9716,Rock,1 +9717,Beaten book,1 +9718,Crane schematic,1 +9719,Lever schematic,1 +9720,Crane claw,1 +9721,Scroll,1 +9722,Key,1 +9723,Pipe,1 +9724,Large cog,1 +9725,Medium cog,1 +9726,Small cog,1 +9727,Primed bar,1 +9728,Elemental mind bar,1 +9729,Elemental helmet,20 +9730,Elemental helmet,20 +9731,Mind shield,3000 +9732,Mind shield,3000 +9733,Mind helmet,3000 +9734,Mind helmet,3000 +9735,Desert goat horn,12 +9736,Goat horn dust,12 +9737,Goat horn dust,12 +9738,Desert goat horn,12 +9739,Combat potion(4),215 +9740,Combat potion(4),215 +9741,Combat potion(3),160 +9742,Combat potion(3),160 +9743,Combat potion(2),105 +9744,Combat potion(2),105 +9745,Combat potion(1),52 +9746,Combat potion(1),52 +9747,Attack cape,99000 +9748,Attack cape(t),99000 +9749,Attack hood,1 +9750,Strength cape,99000 +9751,Strength cape(t),99000 +9752,Strength hood,1 +9753,Defence cape,99000 +9754,Defence cape(t),99000 +9755,Defence hood,1 +9756,Ranging cape,99000 +9757,Ranging cape(t),99000 +9758,Ranging hood,1 +9759,Prayer cape,99000 +9760,Prayer cape(t),99000 +9761,Prayer hood,1 +9762,Magic cape,99000 +9763,Magic cape(t),99000 +9764,Magic hood,1 +9765,Runecraft cape,99000 +9766,Runecraft cape(t),99000 +9767,Runecrafting hood,1 +9768,Hitpoints cape,99000 +9769,Hitpoints cape(t),99000 +9770,Hitpoints hood,1 +9771,Agility cape,99000 +9772,Agility cape(t),99000 +9773,Agility hood,1 +9774,Herblore cape,99000 +9775,Herblore cape(t),99000 +9776,Herblore hood,1 +9777,Thieving cape,99000 +9778,Thieving cape(t),99000 +9779,Thieving hood,1 +9780,Crafting cape,99000 +9781,Crafting cape(t),99000 +9782,Crafting hood,1 +9783,Fletching cape,99000 +9784,Fletching cape(t),99000 +9785,Fletching hood,1 +9786,Slayer cape,99000 +9787,Slayer cape(t),99000 +9788,Slayer hood,1 +9789,Construct. cape,99000 +9790,Construct. cape(t),99000 +9791,Construct. hood,1 +9792,Mining cape,99000 +9793,Mining cape(t),99000 +9794,Mining hood,1 +9795,Smithing cape,99000 +9796,Smithing cape(t),99000 +9797,Smithing hood,1 +9798,Fishing cape,99000 +9799,Fishing cape(t),99000 +9800,Fishing hood,1 +9801,Cooking cape,99000 +9802,Cooking cape(t),99000 +9803,Cooking hood,1 +9804,Firemaking cape,99000 +9805,Firemaking cape(t),99000 +9806,Firemaking hood,1 +9807,Woodcutting cape,99000 +9808,Woodcut. cape(t),99000 +9809,Woodcutting hood,1 +9810,Farming cape,99000 +9811,Farming cape(t),99000 +9812,Farming hood,1 +9813,Quest point cape,99000 +9814,Quest point hood,1 +9815,Bobble hat,1 +9816,Bobble scarf,1 +9817,Oak cape rack,1 +9818,Teak cape rack,1 +9819,M'gany cape rack,1 +9820,Gilded cape rack,1 +9821,Marble cape rack,1 +9822,Magical cape rack,1 +9823,Oak costume box,1 +9824,Teak costume box,1 +9825,Mahogany cos box,1 +9826,Oak armour case,1 +9827,Teak armour case,1 +9828,M'gany arm'r case,1 +9829,Oak magic wardrobe,1 +9830,Carved oak magic wardrobe,1 +9831,Teak magic wardrobe,1 +9832,Carved teak magic wardrobe,1 +9833,Mahogany magic wardrobe,1 +9834,Gilded magic wardrobe,1 +9835,Marble magic wardrobe,1 +9836,Oak toy box,1 +9837,Teak toy box,1 +9838,Mahogany toy box,1 +9839,Oak treasure chest,1 +9840,Teak treas' chest,1 +9841,M'gany treas' chest,1 +9842,Costume room,50000 +9843,Oak cape rack,10 +9844,Teak cape rack,10 +9845,M'gany cape rack,10 +9846,Gilded cape rack,10 +9847,Marble cape rack,10 +9848,Magical cape rack,10 +9849,Oak toy box,10 +9850,Teak toy box,10 +9851,Mahogany toy box,10 +9852,Oak magic wardrobe,10 +9853,Carved oak magic wardrobe,10 +9854,Teak magic wardrobe,10 +9855,Carved teak magic wardrobe,10 +9856,Mahogany magic wardrobe,10 +9857,Gilded magic wardrobe,10 +9858,Marble magic wardrobe,10 +9859,Oak armour case,10 +9860,Teak armour case,10 +9861,M'gany arm'r case,10 +9862,Oak treasure chest,10 +9863,Teak treas' chest,10 +9864,M'gany treas' chest,10 +9865,Oak costume box,10 +9866,Teak costume box,10 +9867,Mahogany cos box,10 +9868,Oak cape rack,10 +9869,Teak cape rack,10 +9870,M'gany cape rack,10 +9871,Gilded cape rack,10 +9872,Marble cape rack,10 +9873,Magical cape rack,10 +9874,Oak toy box,10 +9875,Teak toy box,10 +9876,Mahogany toy box,10 +9877,Oak magic wardrobe,10 +9878,Carved oak magic wardrobe,10 +9879,Teak magic wardrobe,10 +9880,Carved teak magic wardrobe,10 +9881,Mahogany magic wardrobe,10 +9882,Gilded magic wardrobe,10 +9883,Marble magic wardrobe,10 +9884,Oak armour case,10 +9885,Teak armour case,10 +9886,M'gany arm'r case,10 +9887,Oak treasure chest,10 +9888,Teak treas' chest,10 +9889,M'gany treas' chest,10 +9890,Oak costume box,10 +9891,Teak costume box,10 +9892,Mahogany cos box,10 +9893,null,1 +9894,null,1 +9895,null,1 +9896,null,1 +9897,null,1 +9898,null,1 +9899,null,1 +9900,null,1 +9901,Goutweedy lump,5 +9902,Hardy gout tubers,5 +9903,Farming manual,20 +9904,Sailing book,1 +9905,null,1 +9906,Ghost buster 500,1 +9907,Ghost buster 500,1 +9908,Ghost buster 500,1 +9909,Ghost buster 500,1 +9910,Ghost buster 500,1 +9911,Ghost buster 500,1 +9912,Ghost buster 500,1 +9913,White destabiliser,1 +9914,Red destabiliser,1 +9915,Blue destabiliser,1 +9916,Green destabiliser,1 +9917,Yellow destabiliser,1 +9918,Black destabiliser,1 +9919,Evil root,1 +9920,Jack lantern mask,1 +9921,Skeleton boots,1 +9922,Skeleton gloves,1 +9923,Skeleton leggings,1 +9924,Skeleton shirt,1 +9925,Skeleton mask,1 +9926,null,3 +9927,null,3 +9928,null,3 +9929,null,3 +9930,null,3 +9931,null,3 +9932,Auguste's sapling,1 +9933,Balloon structure,1 +9934,Origami balloon,1 +9935,Yellow balloon,1 +9936,Blue balloon,1 +9937,Red balloon,1 +9938,Orange balloon,1 +9939,Green balloon,1 +9940,Purple balloon,1 +9941,Pink balloon,1 +9942,Black balloon,1 +9943,Sandbag,1 +9944,Bomber jacket,1 +9945,Bomber cap,1 +9946,Cap and goggles,1 +9947,Old red disk,1 +9948,Hunter cape,99000 +9949,Hunter cape(t),99000 +9950,Hunter hood,1 +9951,Footprint,1 +9952,Imp,1 +9953,Kebbit,1 +9954,Kebbit,1 +9955,Kebbit,1 +9956,Kebbit,1 +9957,Kebbit,1 +9958,Kebbit,1 +9959,Kebbit,1 +9960,Kebbit,1 +9961,Kebbit,1 +9962,Kebbit,1 +9963,Kebbit,1 +9964,Kebbit,1 +9965,Crimson swift,1 +9966,Copper longtail,1 +9967,Cerulean twitch,1 +9968,Golden warbler,1 +9969,Tropical wagtail,1 +9970,Butterfly,1 +9971,Butterfly,1 +9972,Butterfly,1 +9973,Butterfly,1 +9974,Giant eagle,1 +9975,Rabbit,1 +9976,Chinchompa,1 +9977,Red chinchompa,1 +9978,Raw bird meat,17 +9979,Raw bird meat,17 +9980,Roast bird meat,17 +9981,Roast bird meat,17 +9982,Burnt bird meat,1 +9983,Burnt bird meat,1 +9984,Skewered bird meat,81 +9985,Skewered bird meat,81 +9986,Raw beast meat,25 +9987,Raw beast meat,25 +9988,Roast beast meat,25 +9989,Roast beast meat,25 +9990,Burnt beast meat,1 +9991,Burnt beast meat,1 +9992,Skewered beast,89 +9993,Skewered beast,89 +9994,Spicy tomato,3 +9995,Spicy tomato,3 +9996,Spicy minced meat,8 +9997,Spicy minced meat,8 +9998,Hunter potion(4),15 +9999,Hunter potion(4),15 +10000,Hunter potion(3),12 +10001,Hunter potion(3),12 +10002,Hunter potion(2),9 +10003,Hunter potion(2),9 +10004,Hunter potion(1),6 +10005,Hunter potion(1),6 +10006,Bird snare,6 +10007,Bird snare,6 +10008,Box trap,38 +10009,Box trap,38 +10010,Butterfly net,24 +10011,Butterfly net,24 +10012,Butterfly jar,1 +10013,Butterfly jar,1 +10014,Black warlock,70 +10015,Black warlock,70 +10016,Snowy knight,50 +10017,Snowy knight,50 +10018,Sapphire glacialis,30 +10019,Sapphire glacialis,30 +10020,Ruby harvest,18 +10021,Ruby harvest,18 +10022,null,1 +10023,Falconer's glove,1 +10024,Falconer's glove,1 +10025,Magic box,720 +10026,Magic box,720 +10027,Imp-in-a-box(2),600 +10028,Imp-in-a-box(1),600 +10029,Teasing stick,1 +10030,Teasing stick,1 +10031,Rabbit snare,18 +10032,Rabbit snare,18 +10033,Chinchompa,140 +10034,Red chinchompa,160 +10035,Kyatt legs,200 +10036,Kyatt legs,200 +10037,Kyatt top,200 +10038,Kyatt top,200 +10039,Kyatt hat,1000 +10040,Kyatt hat,1000 +10041,Larupia legs,100 +10042,Larupia legs,100 +10043,Larupia top,100 +10044,Larupia top,100 +10045,Larupia hat,500 +10046,Larupia hat,500 +10047,Graahk legs,150 +10048,Graahk legs,150 +10049,Graahk top,150 +10050,Graahk top,150 +10051,Graahk headdress,750 +10052,Graahk headdress,750 +10053,Wood camo top,20 +10054,Wood camo top,20 +10055,Wood camo legs,20 +10056,Wood camo legs,20 +10057,Jungle camo top,20 +10058,Jungle camo top,20 +10059,Jungle camo legs,20 +10060,Jungle camo legs,20 +10061,Desert camo top,20 +10062,Desert camo top,20 +10063,Desert camo legs,20 +10064,Desert camo legs,20 +10065,Polar camo top,20 +10066,Polar camo top,20 +10067,Polar camo legs,20 +10068,Polar camo legs,20 +10069,Spotted cape,400 +10070,Spotted cape,400 +10071,Spottier cape,800 +10072,Spottier cape,800 +10073,Spotted cape,400 +10074,Spottier cape,800 +10075,Gloves of silence,600 +10076,Gloves of silence,600 +10077,Spiky vambraces,160 +10078,Spiky vambraces,160 +10079,Green spiky vambs,2500 +10080,Green spiky vambs,2500 +10081,Blue spiky vambs,3000 +10082,Blue spiky vambs,3000 +10083,Red spiky vambs,3600 +10084,Red spiky vambs,3600 +10085,Black spiky vambs,4320 +10086,Black spiky vambs,4320 +10087,Stripy feather,20 +10088,Red feather,10 +10089,Blue feather,16 +10090,Yellow feather,13 +10091,Orange feather,15 +10092,Ferret,40 +10093,Tatty larupia fur,72 +10094,Tatty larupia fur,72 +10095,Larupia fur,96 +10096,Larupia fur,96 +10097,Tatty graahk fur,108 +10098,Tatty graahk fur,108 +10099,Graahk fur,144 +10100,Graahk fur,144 +10101,Tatty kyatt fur,144 +10102,Tatty kyatt fur,144 +10103,Kyatt fur,192 +10104,Kyatt fur,192 +10105,Kebbit spike,90 +10106,Kebbit spike,90 +10107,Long kebbit spike,150 +10108,Long kebbit spike,150 +10109,Kebbit teeth,160 +10110,Kebbit teeth,160 +10111,Kebbit teeth dust,160 +10112,Kebbit teeth dust,160 +10113,Kebbit claws,43 +10114,Kebbit claws,43 +10115,Dark kebbit fur,210 +10116,Dark kebbit fur,210 +10117,Polar kebbit fur,12 +10118,Polar kebbit fur,12 +10119,Feldip weasel fur,16 +10120,Feldip weasel fur,16 +10121,Common kebbit fur,14 +10122,Common kebbit fur,14 +10123,Desert devil fur,20 +10124,Desert devil fur,20 +10125,Spotted kebbit fur,150 +10126,Spotted kebbit fur,150 +10127,Dashing kebbit fur,270 +10128,Dashing kebbit fur,270 +10129,Barb-tail harpoon,36 +10130,Barb-tail harpoon,36 +10131,null,1 +10132,Strung rabbit foot,30 +10133,Strung rabbit foot,30 +10134,Rabbit foot,30 +10135,Rabbit foot,30 +10136,Rainbow fish,120 +10137,Rainbow fish,120 +10138,Raw rainbow fish,120 +10139,Raw rainbow fish,120 +10140,Burnt rainbow fish,1 +10141,Burnt rainbow fish,1 +10142,Guam tar,3 +10143,Marrentill tar,1 +10144,Tarromin tar,1 +10145,Harralander tar,1 +10146,Orange salamander,100 +10147,Red salamander,150 +10148,Black salamander,200 +10149,Swamp lizard,50 +10150,Noose wand,4 +10151,Noose wand,4 +10152,null,1 +10153,null,1 +10154,null,1 +10155,null,1 +10156,Hunters' crossbow,1300 +10157,Hunters' crossbow,1300 +10158,Kebbit bolts,18 +10159,Long kebbit bolts,31 +10160,Orange salamander,100 +10161,Red salamander,150 +10162,Black salamander,200 +10163,Swamp lizard,50 +10164,null,1 +10165,More...,1 +10166,Back...,1 +10167,Eagle feather,1 +10168,null,1 +10169,null,1 +10170,null,1 +10171,Eagle cape,1 +10172,Fake beak,1 +10173,Bird book,1 +10174,Metal feather,1 +10175,Golden feather,1 +10176,Silver feather,1 +10177,Bronze feather,1 +10178,Odd bird seed,1 +10179,Feathered journal,1 +10180,Clue scroll,1 +10181,Casket,50 +10182,Clue scroll,1 +10183,Casket,50 +10184,Clue scroll,1 +10185,Casket,50 +10186,Clue scroll,1 +10187,Casket,50 +10188,Clue scroll,1 +10189,Casket,50 +10190,Clue scroll,1 +10191,Casket,50 +10192,Clue scroll,1 +10193,Casket,50 +10194,Clue scroll,1 +10195,Casket,50 +10196,Clue scroll,1 +10197,Casket,50 +10198,Clue scroll,1 +10199,Casket,50 +10200,Clue scroll,1 +10201,Casket,50 +10202,Clue scroll,1 +10203,Casket,50 +10204,Clue scroll,1 +10205,Casket,50 +10206,Clue scroll,1 +10207,Casket,50 +10208,Clue scroll,1 +10209,Casket,50 +10210,Clue scroll,1 +10211,Casket,50 +10212,Clue scroll,1 +10213,Casket,50 +10214,Clue scroll,1 +10215,Casket,50 +10216,Clue scroll,1 +10217,Casket,50 +10218,Clue scroll,1 +10219,Casket,50 +10220,Clue scroll,1 +10221,Casket,50 +10222,Clue scroll,1 +10223,Casket,50 +10224,Clue scroll,1 +10225,Casket,50 +10226,Clue scroll,1 +10227,Casket,50 +10228,Clue scroll,1 +10229,Casket,50 +10230,Clue scroll,1 +10231,Casket,50 +10232,Clue scroll,1 +10233,Casket,50 +10234,Clue scroll,1 +10235,Casket,50 +10236,Clue scroll,1 +10237,Casket,50 +10238,Clue scroll,1 +10239,Casket,50 +10240,Clue scroll,1 +10241,Casket,50 +10242,Clue scroll,1 +10243,Casket,50 +10244,Clue scroll,1 +10245,Casket,50 +10246,Clue scroll,1 +10247,Casket,50 +10248,Clue scroll,1 +10249,Casket,50 +10250,Clue scroll,1 +10251,Casket,50 +10252,Clue scroll,1 +10253,Casket,50 +10254,Clue scroll,1 +10255,Casket,50 +10256,Clue scroll,1 +10257,Casket,50 +10258,Clue scroll,1 +10259,Casket,50 +10260,Clue scroll,1 +10261,Casket,50 +10262,Clue scroll,1 +10263,Casket,50 +10264,Clue scroll,1 +10265,Casket,50 +10266,Clue scroll,1 +10267,Casket,50 +10268,Clue scroll,1 +10269,Casket,50 +10270,Clue scroll,1 +10271,Casket,50 +10272,Clue scroll,1 +10273,Casket,50 +10274,Clue scroll,1 +10275,Casket,50 +10276,Clue scroll,1 +10277,Casket,50 +10278,Clue scroll,1 +10279,Casket,50 +10280,Willow comp bow,300 +10281,Willow comp bow,300 +10282,Yew comp bow,1800 +10283,Yew comp bow,1800 +10284,Magic comp bow,2500 +10285,Magic comp bow,2500 +10286,Rune helm (h1),35200 +10287,Rune helm (h1),35200 +10288,Rune helm (h2),35200 +10289,Rune helm (h2),35200 +10290,Rune helm (h3),35200 +10291,Rune helm (h3),35200 +10292,Rune helm (h4),35200 +10293,Rune helm (h4),35200 +10294,Rune helm (h5),35200 +10295,Rune helm (h5),35200 +10296,Adamant helm (h1),3520 +10297,Adamant helm (h1),3520 +10298,Adamant helm (h2),3520 +10299,Adamant helm (h2),3520 +10300,Adamant helm (h3),3520 +10301,Adamant helm (h3),3520 +10302,Adamant helm (h4),3520 +10303,Adamant helm (h4),3520 +10304,Adamant helm (h5),3520 +10305,Adamant helm (h5),3520 +10306,Black helm (h1),1056 +10307,Black helm (h1),1056 +10308,Black helm (h2),1056 +10309,Black helm (h2),1056 +10310,Black helm (h3),1056 +10311,Black helm (h3),1056 +10312,Black helm (h4),1056 +10313,Black helm (h4),1056 +10314,Black helm (h5),1056 +10315,Black helm (h5),1056 +10316,Bob shirt,3 +10317,Bob shirt,3 +10318,Bob shirt,3 +10319,Bob shirt,3 +10320,Bob shirt,3 +10321,Bob shirt,3 +10322,Bob shirt,3 +10323,Bob shirt,3 +10324,Bob shirt,3 +10325,Bob shirt,3 +10326,Purple firelighter,15 +10327,White firelighter,15 +10328,White logs,1 +10329,Purple logs,1 +10330,3rd age range top,45000 +10331,3rd age range top,45000 +10332,3rd age range legs,40000 +10333,3rd age range legs,40000 +10334,3rd age range coif,10000 +10335,3rd age range coif,10000 +10336,3rd age vambraces,15000 +10337,3rd age vambraces,15000 +10338,3rd age robe top,45000 +10339,3rd age robe top,45000 +10340,3rd age robe,40000 +10341,3rd age robe,40000 +10342,3rd age mage hat,10000 +10343,3rd age mage hat,10000 +10344,3rd age amulet,20000 +10345,3rd age amulet,20000 +10346,3rd age platelegs,200000 +10347,3rd age platelegs,200000 +10348,3rd age platebody,200000 +10349,3rd age platebody,200000 +10350,3rd age full helmet,90000 +10351,3rd age full helmet,90000 +10352,3rd age kiteshield,180000 +10353,3rd age kiteshield,180000 +10354,Amulet of glory(t4),17625 +10355,Amulet of glory(t4),17625 +10356,Amulet of glory(t3),17625 +10357,Amulet of glory(t3),17625 +10358,Amulet of glory(t2),17625 +10359,Amulet of glory(t2),17625 +10360,Amulet of glory(t1),17625 +10361,Amulet of glory(t1),17625 +10362,Amulet of glory(t),17625 +10363,Amulet of glory(t),17625 +10364,Strength amulet(t),2025 +10365,Strength amulet(t),2025 +10366,Amulet of magic(t),900 +10367,Amulet of magic(t),900 +10368,Zamorak bracers,4000 +10369,Zamorak bracers,4000 +10370,Zamorak d'hide,13000 +10371,Zamorak d'hide,13000 +10372,Zamorak chaps,6000 +10373,Zamorak chaps,6000 +10374,Zamorak coif,2000 +10375,Zamorak coif,2000 +10376,Guthix bracers,6000 +10377,Guthix bracers,6000 +10378,Guthix dragonhide,13000 +10379,Guthix dragonhide,13000 +10380,Guthix chaps,6000 +10381,Guthix chaps,6000 +10382,Guthix coif,2000 +10383,Guthix coif,2000 +10384,Saradomin bracers,4000 +10385,Saradomin bracers,4000 +10386,Saradomin d'hide,13000 +10387,Saradomin d'hide,13000 +10388,Saradomin chaps,6000 +10389,Saradomin chaps,6000 +10390,Saradomin coif,2000 +10391,Saradomin coif,2000 +10392,A powdered wig,2000 +10393,A powdered wig,2000 +10394,Flared trousers,2000 +10395,Flared trousers,2000 +10396,Pantaloons,2000 +10397,Pantaloons,2000 +10398,Sleeping cap,2000 +10399,Sleeping cap,2000 +10400,Black ele' shirt,2000 +10401,Black ele' shirt,2000 +10402,Black ele' legs,2000 +10403,Black ele' legs,2000 +10404,Red ele' shirt,2000 +10405,Red ele' shirt,2000 +10406,Red ele' legs,2000 +10407,Red ele' legs,2000 +10408,Blue ele' shirt,2000 +10409,Blue ele' shirt,2000 +10410,Blue ele' legs,2000 +10411,Blue ele' legs,2000 +10412,Green ele' shirt,2000 +10413,Green ele' shirt,2000 +10414,Green ele' legs,2000 +10415,Green ele' legs,2000 +10416,Purple ele' shirt,2000 +10417,Purple ele' shirt,2000 +10418,Purple ele' legs,2000 +10419,Purple ele' legs,2000 +10420,White ele' blouse,2000 +10421,White ele' blouse,2000 +10422,White ele' skirt,2000 +10423,White ele' skirt,2000 +10424,Red ele' blouse,2000 +10425,Red ele' blouse,2000 +10426,Red ele' skirt,2000 +10427,Red ele' skirt,2000 +10428,Blue ele' blouse,2000 +10429,Blue ele' blouse,2000 +10430,Blue ele' skirt,2000 +10431,Blue ele' skirt,2000 +10432,Green ele' blouse,2000 +10433,Green ele' blouse,2000 +10434,Green ele' skirt,2000 +10435,Green ele' skirt,2000 +10436,Purple ele' blouse,2000 +10437,Purple ele' blouse,2000 +10438,Purple ele' skirt,2000 +10439,Purple ele' skirt,2000 +10440,Saradomin crozier,5000 +10441,Saradomin crozier,5000 +10442,Guthix crozier,5000 +10443,Guthix crozier,5000 +10444,Zamorak crozier,5000 +10445,Zamorak crozier,5000 +10446,Saradomin cloak,2000 +10447,Saradomin cloak,2000 +10448,Guthix cloak,2000 +10449,Guthix cloak,2000 +10450,Zamorak cloak,2000 +10451,Zamorak cloak,2000 +10452,Saradomin mitre,5000 +10453,Saradomin mitre,5000 +10454,Guthix mitre,5000 +10455,Guthix mitre,5000 +10456,Zamorak mitre,5000 +10457,Zamorak mitre,5000 +10458,Saradomin robe top,7000 +10459,Saradomin robe top,7000 +10460,Zamorak robe top,7000 +10461,Zamorak robe top,7000 +10462,Guthix robe top,7000 +10463,Guthix robe top,7000 +10464,Saradomin robe legs,7000 +10465,Saradomin robe legs,7000 +10466,Guthix robe legs,7000 +10467,Guthix robe legs,7000 +10468,Zamorak robe legs,7000 +10469,Zamorak robe legs,7000 +10470,Saradomin stole,2500 +10471,Saradomin stole,2500 +10472,Guthix stole,2500 +10473,Guthix stole,2500 +10474,Zamorak stole,2500 +10475,Zamorak stole,2500 +10476,Purple sweets,15 +10477,null,1 +10478,null,1 +10479,null,1 +10480,null,1 +10481,null,1 +10482,null,1 +10483,null,1 +10484,null,1 +10485,Scroll,1 +10486,Empty sack,1 +10487,Undead chicken,100 +10488,Selected iron,10 +10489,Bar magnet,15 +10490,Undead twigs,1 +10491,Blessed axe,20 +10492,Research notes,1 +10493,Translated notes,2 +10494,A pattern,10 +10495,A container,10 +10496,Polished buttons,1 +10497,Tinderbox,0 +10498,Ava's attractor,769 +10499,Ava's accumulator,1000 +10500,Crone-made amulet,20 +10501,Snowball,0 +10502,null,1 +10503,null,1 +10504,null,1 +10505,null,1 +10506,Gublinch shards,1 +10507,Reindeer hat,1 +10508,Wintumber tree,1 +10509,Snowball,1 +10510,Snowball,1 +10511,Zanaris choir,1 +10512,Scroll,1 +10513,Crackers,1 +10514,Tofu,1 +10515,Worms,1 +10516,Attacker horn,1 +10517,Attacker horn,1 +10518,Attacker horn,1 +10519,Attacker horn,1 +10520,Attacker horn,1 +10521,Collection bag,1 +10522,Collection bag,1 +10523,Collection bag,1 +10524,Collection bag,1 +10525,Collection bag,1 +10526,Healer horn,1 +10527,Healer horn,1 +10528,Healer horn,1 +10529,Healer horn,1 +10530,Healer horn,1 +10531,Green egg,1 +10532,Red egg,1 +10533,Blue egg,1 +10534,Yellow egg,1 +10535,Poisoned egg,1 +10536,Spiked/pois. egg,1 +10537,Omega egg,1 +10538,Defender horn,1 +10539,Poisoned tofu,1 +10540,Poisoned worms,1 +10541,Poisoned meat,1 +10542,Healing vial(4),1 +10543,Healing vial(3),1 +10544,Healing vial(2),1 +10545,Healing vial(1),1 +10546,Healing vial,1 +10547,Healer hat,5000 +10548,Fighter hat,5000 +10549,Runner hat,5000 +10550,Ranger hat,5000 +10551,Fighter torso,20000 +10552,Runner boots,5000 +10553,Penance gloves,200 +10554,Penance gloves,200 +10555,Penance skirt,8000 +10556,Picture,1 +10557,Picture,1 +10558,Picture,1 +10559,Picture,1 +10560,Collector horn,1 +10561,Spikes,1 +10562,Queen help book,1 +10563,No eggs,1 +10564,Granite body,80000 +10565,Granite body,80000 +10566,Fire cape,60000 +10567,Picture,1 +10568,Picture,1 +10569,Picture,1 +10570,Picture,1 +10571,Picture,1 +10572,Picture,1 +10573,Picture,1 +10574,Picture,1 +10575,Picture,1 +10576,Picture,1 +10577,Picture,1 +10578,Picture,1 +10579,Picture,1 +10580,Picture,1 +10581,Keris,10000 +10582,Keris(p),10000 +10583,Keris(p+),10000 +10584,Keris(p++),10000 +10585,Parchment,1 +10586,Combat lamp,1 +10587,Tarn's diary,50 +10588,Salve amulet(e),300 +10589,Granite helm,46000 +10590,Granite helm,46000 +10591,Terror dog,1 +10592,Penguin bongos,1 +10593,Cowbells,1 +10594,Clockwork book,1 +10595,Clockwork suit,1 +10596,Clockwork suit,1 +10597,Mission report,1 +10598,Mission report,1 +10599,Mission report,1 +10600,Kgp id card,1 +10601,Mystic hat,15000 +10602,Mystic hat,15000 +10603,Mystic hat,15000 +10604,Skeletal helm,10000 +10605,Infinity top,140000 +10606,Splitbark helm,10000 +10607,Ghostly boots,300 +10608,Moonclan hat,1000 +10609,Lunar helm,100 +10610,Decorative armour,2000 +10611,Void knight top,48000 +10612,Rogue mask,375 +10613,Rock-shell helm,35200 +10614,Spined helm,60000 +10615,Tribal mask,500 +10616,Tribal mask,500 +10617,Tribal mask,500 +10618,White platebody,3840 +10619,Initiate hauberk,10000 +10620,Proselyte hauberk,12000 +10621,Mourner top,150 +10622,Kyatt top,200 +10623,Larupia top,100 +10624,Graahk top,150 +10625,Wood camo top,20 +10626,Jungle camo top,20 +10627,Desert camo top,20 +10628,Polar camo top,20 +10629,Mime mask,1 +10630,Princess blouse,0 +10631,Zombie shirt,1 +10632,Camo top,1 +10633,Lederhosen top,1 +10634,Shade robe,40 +10635,Cape of legends,450 +10636,Obsidian cape,60000 +10637,Fire cape,60000 +10638,Team-1 cape,50 +10639,Attack cape,99000 +10640,Strength cape,99000 +10641,Defence cape,99000 +10642,Ranging cape,99000 +10643,Prayer cape,99000 +10644,Magic cape,99000 +10645,Runecraft cape,99000 +10646,Hunter cape,99000 +10647,Hitpoints cape,99000 +10648,Agility cape,99000 +10649,Herblore cape,99000 +10650,Thieving cape,99000 +10651,Crafting cape,99000 +10652,Fletching cape,99000 +10653,Slayer cape,99000 +10654,Construct. cape,99000 +10655,Mining cape,99000 +10656,Smithing cape,99000 +10657,Fishing cape,99000 +10658,Cooking cape,99000 +10659,Firemaking cape,99000 +10660,Woodcutting cape,99000 +10661,Farming cape,99000 +10662,Quest point cape,99000 +10663,Spotted cape,400 +10664,Spottier cape,800 +10665,Black shield(h1),1632 +10666,Adamant shield(h1),5440 +10667,Rune shield(h1),54400 +10668,Black shield(h2),16325 +10669,Adamant shield(h2),5440 +10670,Rune shield(h2),54400 +10671,Black shield(h3),1632 +10672,Adamant shield(h3),5440 +10673,Rune shield(h3),54400 +10674,Black shield(h4),1632 +10675,Adamant shield(h4),5440 +10676,Rune shield(h4),54400 +10677,Black shield(h5),1632 +10678,Adamant shield(h5),5440 +10679,Rune shield(h5),54400 +10680,Studded body (g),850 +10681,Studded body (t),850 +10682,D'hide body(g),7800 +10683,D'hide body (t),7800 +10684,D'hide body (g),9360 +10685,D'hide body (t),9360 +10686,Wizard robe (g),15 +10687,Wizard robe (t),15 +10688,Enchanted top,120000 +10689,Wizard boots,200 +10690,Black platebody (t),3840 +10691,Black platebody (g),3840 +10692,Highwayman mask,40 +10693,Blue beret,80 +10694,Black beret,80 +10695,White beret,80 +10696,Ranger boots,200 +10697,Adam platebody (t),12800 +10698,Adam platebody (g),12800 +10699,Black helm (h1),1056 +10700,Black helm (h2),1056 +10701,Black helm (h3),1056 +10702,Black helm (h4),1056 +10703,Black helm (h5),1056 +10704,Rune helm (h1),35200 +10705,Rune helm (h2),35200 +10706,Rune helm (h3),35200 +10707,Rune helm (h4),35200 +10708,Rune helm (h5),35200 +10709,Adamant helm (h1),3520 +10710,Adamant helm (h2),3520 +10711,Adamant helm (h3),3520 +10712,Adamant helm (h4),3520 +10713,Adamant helm (h5),3520 +10714,Bob shirt,3 +10715,Bob shirt,3 +10716,Bob shirt,3 +10717,Bob shirt,3 +10718,Bob shirt,3 +10719,Amulet of glory(t),17625 +10720,Guthix cape,100 +10721,Frog mask,0 +10722,Reindeer hat,1 +10723,Jack lantern mask,1 +10724,Skeleton boots,1 +10725,Skeleton gloves,1 +10726,Skeleton leggings,1 +10727,Skeleton shirt,1 +10728,Skeleton mask,1 +10729,Easter ring,1 +10730,Blue marionette,1 +10731,Zombie head,0 +10732,Rubber chicken,0 +10733,Yo-yo,10 +10734,Bunny ears,1 +10735,Scythe,1 +10736,Strength amulet(t),2025 +10737,Picture,1 +10738,Amulet of magic(t),900 +10739,Picture,1 +10740,A powdered wig,2000 +10741,Picture,1 +10742,Flared trousers,2000 +10743,Picture,1 +10744,Pantaloons,2000 +10745,Picture,1 +10746,Sleeping cap,2000 +10747,Picture,1 +10748,Elegant shirt,2000 +10749,Picture,1 +10750,Elegant shirt,2000 +10751,Picture,1 +10752,Elegant shirt,2000 +10753,Picture,1 +10754,Elegant shirt,2000 +10755,Picture,1 +10756,Elegant shirt,2000 +10757,Picture,1 +10758,Red boater,225 +10759,Picture,1 +10760,Orange boater,225 +10761,Picture,1 +10762,Green boater,225 +10763,Picture,1 +10764,Blue boater,225 +10765,Picture,1 +10766,Black boater,225 +10767,Picture,1 +10768,Red headband,40 +10769,Picture,1 +10770,Black headband,40 +10771,Picture,1 +10772,Brown headband,40 +10773,Picture,1 +10774,Pirate's hat,180 +10775,Picture,1 +10776,Zamorak platebody,65000 +10777,Picture,1 +10778,Saradomin plate,65000 +10779,Picture,1 +10780,Guthix platebody,65000 +10781,Picture,1 +10782,Gilded platebody,65000 +10783,Picture,1 +10784,Saradomin robe top,7000 +10785,Picture,1 +10786,Zamorak robe top,7000 +10787,Picture,1 +10788,Guthix robe top,7000 +10789,Picture,1 +10790,Zamorak d'hide,13000 +10791,Picture,1 +10792,Saradomin d'hide,13000 +10793,Picture,1 +10794,Guthix dragonhide,13000 +10795,Picture,1 +10796,Robin hood hat,450 +10797,Picture,1 +10798,Rune platebody (g),65000 +10799,Picture,1 +10800,Rune platebody (t),65000 +10801,Picture,1 +10802,Tan cavalier,200 +10803,Picture,1 +10804,Dark cavalier,200 +10805,Picture,1 +10806,Black cavalier,200 +10807,Picture,1 +10808,Arctic pyre logs,200 +10809,Arctic pyre logs,200 +10810,Arctic pine logs,35 +10811,Arctic pine logs,35 +10812,Split log,90 +10813,Split log,90 +10814,Hair,120 +10815,Hair,120 +10816,Raw yak meat,2 +10817,Raw yak meat,2 +10818,Yak-hide,50 +10819,Yak-hide,50 +10820,Cured yak-hide,100 +10821,Cured yak-hide,100 +10822,Yak-hide armour,500 +10823,Yak-hide armour,500 +10824,Yak-hide armour,500 +10825,Yak-hide armour,500 +10826,Fremennik round shield,500 +10827,Fremennik round shield,500 +10828,Helm of neitiznot,50000 +10829,Documents,1 +10830,Royal decree,1 +10831,Empty tax bag,1 +10832,Light tax bag,1 +10833,Normal tax bag,1 +10834,Hefty tax bag,1 +10835,Bulging taxbag,1 +10836,Silly jester hat,100 +10837,Silly jester top,100 +10838,Silly jester tights,100 +10839,Silly jester boots,100 +10840,A jester stick,1000 +10841,Apricot cream pie,1 +10842,Decapitated head,1 +10843,Helm of neitiznot,50000 +10844,Spring sq'irk,1 +10845,Summer sq'irk,1 +10846,Autumn sq'irk,1 +10847,Winter sq'irk,1 +10848,Spring sq'irkjuice,1 +10849,Summer sq'irkjuice,1 +10850,Autumn sq'irkjuice,1 +10851,Winter sq'irkjuice,1 +10852,Summer garden,1 +10853,Spring garden,1 +10854,Autumn garden,1 +10855,Winter garden,1 +10856,Sin seer's note,5 +10857,Severed leg,0 +10858,Shadow sword,0 +10859,Tea flask,1 +10860,Tea flask,1 +10861,Tea flask,1 +10862,Hard hat,100 +10863,Builder's shirt,100 +10864,Builder's trousers,100 +10865,Builder's boots,100 +10866,Rivets,0 +10867,null,1 +10868,null,1 +10869,null,1 +10870,Binding fluid,1 +10871,Pipe,1 +10872,Pipe ring,1 +10873,Metal sheet,1 +10874,Coloured ball,1 +10875,Valve wheel,1 +10876,Metal bar,1 +10877,Plain satchel,100 +10878,Green satchel,100 +10879,Red satchel,100 +10880,Black satchel,100 +10881,Gold satchel,100 +10882,Rune satchel,100 +10883,Hard hat,100 +10884,Fuse,52 +10885,Keg,1 +10886,Prayer book,1 +10887,Barrelchest anchor,230000 +10888,Barrelchest anchor,1 +10889,Blessed lamp,1 +10890,Prayer book,1 +10891,Wooden cat,1 +10892,Wooden cat,1 +10893,Cranial clamp,1 +10894,Brain tongs,1 +10895,Bell jar,1 +10896,Wolf whistle,1 +10897,Shipping order,1 +10898,Keg,1 +10899,Crate part,0 +10900,null,1 +10901,null,1 +10902,null,1 +10903,null,1 +10904,Skull staple,0 +10905,null,1 +10906,null,1 +10907,null,1 +10908,null,1 +10909,Mixture - step 1(4),300 +10910,Mixture - step 1(4),300 +10911,Mixture - step 1(3),240 +10912,Mixture - step 1(3),240 +10913,Mixture - step 1(2),180 +10914,Mixture - step 1(2),180 +10915,Mixture - step 1(1),120 +10916,Mixture - step 1(1),120 +10917,Mixture - step 2(4),300 +10918,Mixture - step 2(4),300 +10919,Mixture - step 2(3),240 +10920,Mixture - step 2(3),240 +10921,Mixture - step 2(2),180 +10922,Mixture - step 2(2),180 +10923,Mixture - step 2(1),120 +10924,Mixture - step 2(1),120 +10925,Sanfew serum(4),300 +10926,Sanfew serum(4),300 +10927,Sanfew serum(3),240 +10928,Sanfew serum(3),240 +10929,Sanfew serum(2),180 +10930,Sanfew serum(2),180 +10931,Sanfew serum(1),120 +10932,Sanfew serum(1),120 +10933,Lumberjack boots,50 +10934,Reward token,1 +10935,Reward token,1 +10936,Reward token,1 +10937,Nail beast nails,300 +10938,Nail beast nails,300 +10939,Lumberjack top,50 +10940,Lumberjack legs,50 +10941,Lumberjack hat,50 +10942,Reward token,1 +10943,Reward token,1 +10944,Reward token,1 +10945,Lumberjack top,50 +10946,Pushup,1 +10947,Run,1 +10948,Situp,1 +10949,Starjump,1 +10950,Skull staples,0 +10951,Skull staples,0 +10952,Slayer bell,150 +10953,Slayer bell,150 +10954,Frog-leather body,1000 +10955,Frog-leather body,1000 +10956,Frog-leather chaps,900 +10957,Frog-leather chaps,900 +10958,Frog-leather boots,200 +10959,Frog-leather boots,200 +10960,Green gloop soup,10 +10961,Frogspawn gumbo,10 +10962,Frogburger,10 +10963,Coated frogs' legs,10 +10964,Bat shish,10 +10965,Fingers,10 +10966,Grubs la mode,50 +10967,Roast frog,50 +10968,Mushrooms,50 +10969,Fillets,50 +10970,Loach,50 +10971,Eel sushi,50 +10972,Dorgesh-kaan sphere,20 +10973,Light orb,350 +10974,Light orb,350 +10975,Spanner,0 +10976,Long bone,5 +10977,Curved bone,7 +10978,Swamp weed,2 +10979,Swamp weed,2 +10980,Empty light orb,250 +10981,Cave goblin wire,20 +10982,Cave goblin wire,20 +10983,Cog,0 +10984,Cog,0 +10985,Fuse,0 +10986,Fuse,0 +10987,Meter,0 +10988,Meter,0 +10989,Capacitor,0 +10990,Capacitor,0 +10991,Lever,0 +10992,Lever,0 +10993,Powerbox,0 +10994,Powerbox,0 +10995,Perfect shell,1000 +10996,Perfect snail shell,1000 +10997,Molanisk,1 +10998,Cave goblin,1 +10999,Goblin book,1 +11000,Picture,0 +11001,Dagon'hai history,10 +11002,Sin'keth's diary,10 +11003,An empty folder,5 +11004,null,1 +11005,null,1 +11006,Used folder,10 +11007,Full folder,10 +11008,Rat's paper,1 +11009,Rat's letter,1 +11010,Surok's letter,1 +11011,Zaff's instructions,1 +11012,Wand,1 +11013,Infused wand,1 +11014,Beacon ring,0 +11015,Chicken head,1 +11016,Chicken feet,1 +11017,Chicken wings,1 +11018,Chicken legs,1 +11019,Chicken feet,1 +11020,Chicken wings,1 +11021,Chicken head,1 +11022,Chicken legs,1 +11023,Magic egg,1 +11024,Rabbit mould,1 +11025,Chocolate chunks,1 +11026,Chocolate kebbit,1 +11027,Easter egg,1 +11028,Easter egg,1 +11029,Easter egg,1 +11030,Easter egg,1 +11031,Damp planks,0 +11032,Crude carving,0 +11033,Cruder carving,0 +11034,Sven's last map,0 +11035,Windswept logs,0 +11036,Parchment,1 +11037,Brine sabre,26000 +11038,Brine sabre,26000 +11039,Key,0 +11040,Key,0 +11041,Key,0 +11042,Key,0 +11043,Key,0 +11044,Rotten barrel,0 +11045,Rotten barrel,0 +11046,Rope,0 +11047,Brine rat,1 +11048,Armour shard,1 +11049,Artefact,1 +11050,Axe head,1 +11051,Artefact,1 +11052,Helmet fragment,1 +11053,Artefact,1 +11054,Shield fragment,1 +11055,Artefact,1 +11056,Sword fragment,1 +11057,Artefact,1 +11058,Mace,1 +11059,Artefact,1 +11060,Goblin village sphere,20 +11061,Ancient mace,1000 +11062,Zanik (slice),1 +11063,null,1 +11064,Ancient mace,1000 +11065,Bracelet mould,5 +11066,Bracelet mould,5 +11067,null,1 +11068,null,1 +11069,Gold bracelet,550 +11070,Gold bracelet,550 +11071,null,1 +11072,Sapphire bracelet,1150 +11073,Sapphire bracelet,1150 +11074,Bracelet of clay,1265 +11075,Bracelet of clay,1265 +11076,Emerald bracelet,1525 +11077,Emerald bracelet,1525 +11078,null,1 +11079,Castlewar brace(3),1675 +11080,Castlewar brace(3),1675 +11081,Castlewar brace(2),1675 +11082,Castlewar brace(2),1675 +11083,Castlewar brace(1),1675 +11084,Castlewar brace(1),1675 +11085,Ruby bracelet,2325 +11086,Ruby bracelet,2325 +11087,null,1 +11088,Inoculation brace,2560 +11089,Inoculation brace,2560 +11090,Phoenix necklace,4050 +11091,Phoenix necklace,4050 +11092,Diamond bracelet,3825 +11093,Diamond bracelet,3825 +11094,null,1 +11095,Forinthry brace(5),4200 +11096,Forinthry brace(5),4200 +11097,Forinthry brace(4),4200 +11098,Forinthry brace(4),4200 +11099,Forinthry brace(3),4200 +11100,Forinthry brace(3),4200 +11101,Forinthry brace(2),4200 +11102,Forinthry brace(2),4200 +11103,Forinthry brace(1),4200 +11104,Forinthry brace(1),4200 +11105,Skills necklace(4),20200 +11106,Skills necklace(4),20200 +11107,Skills necklace(3),20200 +11108,Skills necklace(3),20200 +11109,Skills necklace(2),20200 +11110,Skills necklace(2),20200 +11111,Skills necklace(1),20200 +11112,Skills necklace(1),20200 +11113,Skills necklace,20200 +11114,Skills necklace,20200 +11115,Dragon bracelet,19125 +11116,Dragon bracelet,19125 +11117,null,1 +11118,Combat bracelet(4),21040 +11119,Combat bracelet(4),21040 +11120,Combat bracelet(3),21040 +11121,Combat bracelet(3),21040 +11122,Combat bracelet(2),21040 +11123,Combat bracelet(2),21040 +11124,Combat bracelet(1),21040 +11125,Combat bracelet(1),21040 +11126,Combat bracelet,21040 +11127,Combat bracelet,21040 +11128,Berserker necklace,202000 +11129,Berserker necklace,202000 +11130,Onyx bracelet,201000 +11131,Onyx bracelet,201000 +11132,null,1 +11133,Regen bracelet,202000 +11134,Regen bracelet,202000 +11135,Bomber jacket,1 +11136,Karamja gloves 1,0 +11137,Antique lamp,1 +11138,Karamja gloves 2,0 +11139,Antique lamp,1 +11140,Karamja gloves 3,0 +11141,Antique lamp,1 +11142,null,1 +11143,null,1 +11144,null,1 +11145,null,1 +11146,null,1 +11147,null,1 +11148,null,1 +11149,null,1 +11150,null,1 +11151,Dream vial (empty),1 +11152,Dream vial (water),1 +11153,Dream vial (herb),1 +11154,Dream potion,1 +11155,Ground astral rune,20 +11156,Astral rune shards,1 +11157,Dreamy lamp,1 +11158,Cyrisus's chest,1 +11159,Hunter kit,1 +11160,null,1 +11161,null,1 +11162,null,1 +11163,null,1 +11164,Restored shield,1 +11165,Phoenix crossbow,4 +11166,Phoenix crossbow,4 +11167,Phoenix crossbow,4 +11168,Phoenix crossbow,4 +11169,Newspaper,1 +11170,Newspaper,1 +11171,Newspaper,1 +11172,Newspaper,1 +11173,Half certificate,1 +11174,Half certificate,1 +11175,Uncleaned find,1 +11176,Arrowheads,1 +11177,Jewellery,1 +11178,Pottery,1 +11179,Old coin,1 +11180,Ancient coin,1 +11181,Ancient symbol,1 +11182,Old symbol,1 +11183,Old chipped vase,1 +11184,Museum map,0 +11185,Antique lamp,1 +11186,Antique lamp,1 +11187,Antique lamp,1 +11188,Antique lamp,1 +11189,Antique lamp,1 +11190,Digsite pendant (1),2400 +11191,Digsite pendant (2),2400 +11192,Digsite pendant (3),2400 +11193,Digsite pendant (4),2400 +11194,Digsite pendant (5),2400 +11195,Clean necklace,0 +11196,Griffin feather,1 +11197,Miazrqa's pendant,1 +11198,Music sheet,1 +11199,Rupert's helmet,1 +11200,Dwarven helmet,60000 +11201,Dwarven helmet,60000 +11202,Shrinking recipe,1 +11203,To-do list,1 +11204,Shrink-me-quick,1 +11205,Shrunk ogleroot,2 +11206,null,1 +11207,null,1 +11208,null,1 +11209,null,1 +11210,Golden goblin,1 +11211,Magic beans,1 +11212,Dragon arrow,800 +11213,null,1 +11214,null,1 +11215,null,1 +11216,null,1 +11217,Dragon fire arrows,3 +11218,null,1 +11219,null,1 +11220,null,1 +11221,null,1 +11222,Dragon fire arrows,10 +11223,null,1 +11224,null,1 +11225,null,1 +11226,null,1 +11227,Dragon arrow(p),800 +11228,Dragon arrow(p+),800 +11229,Dragon arrow(p++),800 +11230,Dragon dart,500 +11231,Dragon dart(p),500 +11232,Dragon dart tip,250 +11233,Dragon dart(p+),500 +11234,Dragon dart(p++),500 +11235,Dark bow,120002 +11236,Dark bow,120002 +11237,Dragon arrowtips,500 +11238,Baby impling jar,50 +11239,Baby impling jar,50 +11240,Young impling jar,50 +11241,Young impling jar,50 +11242,Gourm' impling jar,50 +11243,Gourm' impling jar,50 +11244,Earth impling jar,50 +11245,Earth impling jar,50 +11246,Ess' impling jar,50 +11247,Ess' impling jar,50 +11248,Eclectic impling jar,50 +11249,Eclectic impling jar,50 +11250,Nature impling jar,50 +11251,Nature impling jar,50 +11252,Magpie impling jar,50 +11253,Magpie impling jar,50 +11254,Ninja impling jar,50 +11255,Ninja impling jar,50 +11256,Dragon impling jar,50 +11257,Dragon impling jar,50 +11258,Jar generator,600 +11259,Magic butterfly net,1000 +11260,Impling jar,1 +11261,Impling jar,1 +11262,Imp repellent,50 +11263,Imp repellent,50 +11264,Anchovy oil,10 +11265,Anchovy oil,10 +11266,Anchovy paste,5 +11267,Picture,1 +11268,Picture,1000 +11269,Picture,1 +11270,Picture,1 +11271,Picture,50 +11272,Picture,50 +11273,Impling scroll,3 +11274,Ham shirt,75 +11275,Mith grapple,48 +11276,Mith grapple,1 +11277,Cavalier mask,200 +11278,Beret mask,80 +11279,Elvarg's head,1 +11280,Cavalier and mask,200 +11281,Cavalier and mask,200 +11282,Beret and mask,80 +11283,Dragonfire shield,2000000 +11284,Dragonfire shield,2000000 +11285,Dragonfire shield,2000000 +11286,Draconic visage,750000 +11287,Draconic visage,750000 +11288,null,40 +11289,null,40 +11290,null,40 +11291,null,40 +11292,null,40 +11293,null,40 +11294,null,40 +11295,null,40 +11296,null,40 +11297,null,40 +11298,null,40 +11299,null,40 +11300,null,40 +11301,null,40 +11302,null,40 +11303,null,40 +11304,null,40 +11305,null,40 +11306,null,1 +11307,null,1 +11308,null,1 +11309,null,1 +11310,null,1 +11311,null,1 +11312,null,1 +11313,null,1 +11314,null,1 +11315,null,1 +11316,null,1 +11317,null,1 +11318,null,1 +11319,null,1 +11320,null,3 +11321,null,3 +11322,null,3 +11323,Barbarian rod,1 +11324,Roe,20 +11325,Roe,20 +11326,Caviar,50 +11327,Caviar,50 +11328,Leaping trout,25 +11329,Leaping trout,25 +11330,Leaping salmon,50 +11331,Leaping salmon,50 +11332,Leaping sturgeon,75 +11333,Leaping sturgeon,75 +11334,Fish offcuts,1 +11335,Dragon full helm,150000 +11336,Dragon full helm,150000 +11337,Mangled bones,1000 +11338,Chewed bones,3500 +11339,My notes,0 +11340,Barbarian skills,0 +11341,Ancient page,0 +11342,Ancient page,0 +11343,Ancient page,0 +11344,Ancient page,0 +11345,Ancient page,0 +11346,Ancient page,0 +11347,Ancient page,0 +11348,Ancient page,0 +11349,Ancient page,0 +11350,Ancient page,0 +11351,Ancient page,0 +11352,Ancient page,0 +11353,Ancient page,0 +11354,Ancient page,0 +11355,Ancient page,0 +11356,Ancient page,0 +11357,Ancient page,0 +11358,Ancient page,0 +11359,Ancient page,0 +11360,Ancient page,0 +11361,Ancient page,0 +11362,Ancient page,0 +11363,Ancient page,0 +11364,Ancient page,0 +11365,Ancient page,0 +11366,Ancient page,0 +11367,Bronze hasta,26 +11368,Bronze hasta,26 +11369,Iron hasta,91 +11370,Iron hasta,91 +11371,Steel hasta,325 +11372,Steel hasta,325 +11373,Mithril hasta,845 +11374,Mithril hasta,845 +11375,Adamant hasta,2080 +11376,Adamant hasta,2080 +11377,Rune hasta,20800 +11378,Rune hasta,20800 +11379,Bronze hasta(p),26 +11380,Bronze hasta(p),26 +11381,Bronze hasta(kp),26 +11382,Bronze hasta(p+),26 +11383,Bronze hasta(p+),26 +11384,Bronze hasta(p++),26 +11385,Bronze hasta(p++),26 +11386,Iron hasta(p),91 +11387,Iron hasta(p),91 +11388,Iron hasta(kp),91 +11389,Iron hasta(p+),91 +11390,Iron hasta(p+),91 +11391,Iron hasta(p++),91 +11392,Iron hasta(p++),91 +11393,Steel hasta(p),325 +11394,Steel hasta(p),325 +11395,Steel hasta(kp),325 +11396,Steel hasta(p+),325 +11397,Steel hasta(p+),325 +11398,Steel hasta(p++),325 +11399,Steel hasta(p++),325 +11400,Mithril hasta(p),845 +11401,Mithril hasta(p),845 +11402,Mithril hasta(kp),845 +11403,Mithril hasta(p+),845 +11404,Mithril hasta(p+),845 +11405,Mithril hasta(p++),845 +11406,Mithril hasta(p++),845 +11407,Adamant hasta(p),2080 +11408,Adamant hasta(p),2080 +11409,Adamant hasta(kp),2080 +11410,Adamant hasta(p+),2080 +11411,Adamant hasta(p+),2080 +11412,Adamant hasta(p++),2080 +11413,Adamant hasta(p++),2080 +11414,Rune hasta(p),20800 +11415,Rune hasta(p),20800 +11416,Rune hasta(kp),20800 +11417,Rune hasta(p+),20800 +11418,Rune hasta(p+),20800 +11419,Rune hasta(p++),20800 +11420,Rune hasta(p++),20800 +11421,null,1 +11422,null,1 +11423,null,1 +11424,null,1 +11425,null,1 +11426,null,1 +11427,Fish vial,3 +11428,Fish vial,3 +11429,Attack mix(2),9 +11430,Attack mix(2),9 +11431,Attack mix(1),6 +11432,Attack mix(1),6 +11433,Antipoison mix(2),216 +11434,Antipoison mix(2),216 +11435,Antipoison mix(1),144 +11436,Antipoison mix(1),144 +11437,Relicym's mix(2),150 +11438,Relicym's mix(2),150 +11439,Relicym's mix(1),75 +11440,Relicym's mix(1),75 +11441,Strength mix(1),11 +11442,Strength mix(1),11 +11443,Strength mix(2),13 +11444,Strength mix(2),13 +11445,Combat mix(2),105 +11446,Combat mix(2),105 +11447,Combat mix(1),52 +11448,Combat mix(1),52 +11449,Restore mix(2),66 +11450,Restore mix(2),66 +11451,Restore mix(1),44 +11452,Restore mix(1),44 +11453,Energy mix(2),72 +11454,Energy mix(2),72 +11455,Energy mix(1),36 +11456,Energy mix(1),36 +11457,Defence mix(2),90 +11458,Defence mix(2),90 +11459,Defence mix(1),60 +11460,Defence mix(1),60 +11461,Agility mix(2),100 +11462,Agility mix(2),100 +11463,Agility mix(1),50 +11464,Agility mix(1),50 +11465,Prayer mix(2),114 +11466,Prayer mix(2),114 +11467,Prayer mix(1),76 +11468,Prayer mix(1),76 +11469,Superattack mix(2),135 +11470,Superattack mix(2),135 +11471,Superattack mix(1),90 +11472,Superattack mix(1),90 +11473,Anti-p supermix(2),216 +11474,Anti-p supermix(2),216 +11475,Anti-p supermix(1),144 +11476,Anti-p supermix(1),144 +11477,Fishing mix(2),150 +11478,Fishing mix(2),150 +11479,Fishing mix(1),100 +11480,Fishing mix(1),100 +11481,Sup. energy mix(2),160 +11482,Sup. energy mix(2),160 +11483,Sup. energy mix(1),90 +11484,Sup. energy mix(1),90 +11485,Sup. str. mix(2),165 +11486,Sup. str. mix(2),165 +11487,Sup. str. mix(1),110 +11488,Sup. str. mix(1),110 +11489,Magic ess. mix(2),180 +11490,Magic ess. mix(2),180 +11491,Magic ess. mix(1),130 +11492,Magic ess. mix(1),130 +11493,Sup. restore mix(2),180 +11494,Sup. restore mix(2),180 +11495,Sup. restore mix(1),120 +11496,Sup. restore mix(1),120 +11497,Sup. def. mix(2),198 +11498,Sup. def. mix(2),198 +11499,Sup. def. mix(1),132 +11500,Sup. def. mix(1),132 +11501,Antidote+ mix(2),216 +11502,Antidote+ mix(2),216 +11503,Antidote+ mix(1),144 +11504,Antidote+ mix(1),144 +11505,Antifire mix(2),198 +11506,Antifire mix(2),198 +11507,Antifire mix(1),132 +11508,Antifire mix(1),132 +11509,Ranging mix(2),216 +11510,Ranging mix(2),216 +11511,Ranging mix(1),144 +11512,Ranging mix(1),144 +11513,Magic mix(2),200 +11514,Magic mix(2),200 +11515,Magic mix(1),150 +11516,Magic mix(1),150 +11517,Hunting mix(2),9 +11518,Hunting mix(2),9 +11519,Hunting mix(1),6 +11520,Hunting mix(1),6 +11521,Zamorak mix(2),150 +11522,Zamorak mix(2),150 +11523,Zamorak mix(1),125 +11524,Zamorak mix(1),125 +11525,Wimpy feather,25 +11526,null,3 +11527,null,3 +11528,null,3 +11529,null,3 +11530,null,3 +11531,null,3 +11532,null,3 +11533,null,3 +11534,null,3 +11535,null,3 +11536,null,3 +11537,null,3 +11538,null,3 +11539,null,3 +11540,null,3 +11541,null,3 +11542,null,3 +11543,null,3 +11544,null,3 +11545,null,3 +11546,null,3 +11547,null,3 +11548,null,3 +11549,null,3 +11550,null,3 +11551,null,3 +11552,null,3 +11553,null,3 +11554,null,3 +11555,null,3 +11556,null,3 +11557,null,3 +11558,null,3 +11559,null,3 +11560,null,3 +11561,null,3 +11562,null,3 +11563,null,3 +11564,null,3 +11565,null,3 +11566,null,3 +11567,null,3 +11568,null,3 +11569,null,3 +11570,null,3 +11571,null,3 +11572,null,3 +11573,null,3 +11574,null,3 +11575,null,3 +11576,null,3 +11577,null,3 +11578,null,3 +11579,null,3 +11580,null,3 +11581,null,3 +11582,null,3 +11583,null,3 +11584,null,3 +11585,null,3 +11586,null,3 +11587,null,3 +11588,null,3 +11589,null,3 +11590,null,3 +11591,null,3 +11592,null,3 +11593,null,3 +11594,null,3 +11595,null,3 +11596,null,3 +11597,null,3 +11598,null,3 +11599,null,3 +11600,null,3 +11601,null,3 +11602,null,3 +11603,null,3 +11604,null,3 +11605,null,3 +11606,null,3 +11607,null,3 +11608,null,3 +11609,null,3 +11610,null,3 +11611,null,3 +11612,null,3 +11613,null,3 +11614,null,3 +11615,null,3 +11616,null,3 +11617,null,3 +11618,null,3 +11619,null,3 +11620,null,3 +11621,null,3 +11622,null,3 +11623,null,3 +11624,null,3 +11625,null,3 +11626,null,3 +11627,null,3 +11628,null,3 +11629,null,3 +11630,null,3 +11631,null,3 +11632,null,3 +11633,null,3 +11634,null,3 +11635,null,3 +11636,null,3 +11637,null,3 +11638,null,3 +11639,null,3 +11640,Book of knowledge,1 +11641,null,3 +11642,null,3 +11643,null,3 +11644,null,3 +11645,null,3 +11646,null,3 +11647,null,3 +11648,null,3 +11649,null,3 +11650,null,3 +11651,null,3 +11652,null,3 +11653,null,3 +11654,null,3 +11655,Astronomy book,3 +11656,Glassblowing book,3 +11657,Glassblowing book,3 +11658,null,1 +11659,null,1 +11660,null,1 +11661,null,1 +11662,null,1 +11663,Void mage helm,9851 +11664,Void ranger helm,9851 +11665,Void melee helm,9851 +11666,Void seal(8),100 +11667,Void seal(7),100 +11668,Void seal(6),100 +11669,Void seal(5),100 +11670,Void seal(4),100 +11671,Void seal(3),100 +11672,Void seal(2),100 +11673,Void seal(1),100 +11674,Void mage helm,9851 +11675,Void ranger helm,9851 +11676,Void melee helm,9851 +11677,Explorer's notes,6 +11678,Black knight helm,1 +11679,Antique lamp,1 +11680,Address form,1 +11681,Scrap paper,1 +11682,Hair clip,1 +11683,null,1 +11684,null,1 +11685,null,1 +11686,Godsword shards,500000 +11687,Godsword shards,500000 +11688,Godsword shards,500000 +11689,Godsword shards,500000 +11690,Godsword blade,750000 +11691,Godsword blade,750000 +11692,Godsword shards,500000 +11693,Godsword shards,500000 +11694,Armadyl godsword,1250000 +11695,Armadyl godsword,1250000 +11696,Bandos godsword,1250000 +11697,Bandos godsword,1250000 +11698,Saradomin godsword,1250000 +11699,Saradomin godsword,1250000 +11700,Zamorak godsword,1250000 +11701,Zamorak godsword,1250000 +11702,Armadyl hilt,500000 +11703,Armadyl hilt,500000 +11704,Bandos hilt,500000 +11705,Bandos hilt,500000 +11706,Saradomin hilt,500000 +11707,Saradomin hilt,500000 +11708,Zamorak hilt,500000 +11709,Zamorak hilt,500000 +11710,Godsword shard 1,250000 +11711,Godsword shard 1,250000 +11712,Godsword shard 2,250000 +11713,Godsword shard 2,250000 +11714,Godsword shard 3,250000 +11715,Godsword shard 3,250000 +11716,Zamorakian spear,100000 +11717,Zamorakian spear,100000 +11718,Armadyl helmet,20000 +11719,Armadyl helmet,20000 +11720,Armadyl chestplate,60000 +11721,Armadyl chestplate,60000 +11722,Armadyl plateskirt,50000 +11723,Armadyl plateskirt,50000 +11724,Bandos chestplate,265000 +11725,Bandos chestplate,265000 +11726,Bandos tassets,272500 +11727,Bandos tassets,272500 +11728,Bandos boots,25000 +11729,Bandos boots,25000 +11730,Saradomin sword,130000 +11731,Saradomin sword,130000 +11732,Dragon boots,20000 +11733,Dragon boots,20000 +11734,Knight's notes,0 +11735,Knight's notes,0 +11736,Steam battlestaff,17000 +11737,Steam battlestaff,17000 +11738,Mystic steam staff,45000 +11739,Mystic steam staff,45000 +11740,Picture,1 +11741,Picture,1 +11742,Picture,1 +11743,Picture,1 +11744,Picture,1 +11745,Picture,1 +11746,Agility jump,1 +11747,A key to a chest,1 +11748,Strongroom key,1 +11749,Crystal chime,10 +11750,Yewnock's notes,1 +11751,null,1 +11752,null,1 +11753,Antique lamp,1 +11754,Antique lamp,1 +11755,Antique lamp,1 +11756,Varrock armour 1,0 +11757,Varrock armour 2,0 +11758,Varrock armour 3,0 +11759,null,1 +11760,Logs,1 +11761,Locked diary,1 +11762,Unlocked diary,1 +11763,Hand,1 +11764,Foot,1 +11765,Torso,1 +11766,Left arm,1 +11767,Right arm,1 +11768,Left leg,1 +11769,Right leg,1 +11770,Root cutting,1 +11771,Root cutting,1 +11772,Root cutting,1 +11773,Root cutting,1 +11774,Root cutting,1 +11775,Wilted cutting,1 +11776,Potted root,1 +11777,Sealed pot,1 +11778,Jade vine seed,1 +11779,null,1 +11780,The grim reaper's diary,1 +11781,Grim's robe,5 +11782,Last will and testament,1 +11783,Human bones,1 +11784,Servant's skull,1 +11785,Hourglass,1 +11786,Scythe sharpener,1 +11787,Human eye,1 +11788,'voice of doom' potion,1 +11789,Grim reaper hood,1 +11790,Grim reaper hood,1 +11791,White goblin mail,40 +11792,Grubfoot,1 +11793,Zanik,1 +11794,Plain of mud sphere,20 +11795,Ekeleshuun key,1 +11796,Narogoshuun key,1 +11797,Huzamogaarb key,1 +11798,Saragorgak key,1 +11799,Horogothgar key,1 +11800,Yurkolgokh key,1 +11801,null,1 +11802,Snothead's bone,1 +11803,Snailfeet's bone,1 +11804,Mosschin's bone,1 +11805,Redeyes's bone,1 +11806,Strongbones's bone,1 +11807,Pharmakos berries,10 +11808,Whitefish,20 +11809,Goblin potion (4),14 +11810,Goblin potion (3),13 +11811,Goblin potion (2),13 +11812,Goblin potion (1),13 +11813,Tinderbox,0 +11814,Bronze armour set (l),20 +11815,Bronze armour set (l),20 +11816,Bronze armour set (sk),20 +11817,Bronze armour set (sk),20 +11818,Iron armour set (l),20 +11819,Iron armour set (l),20 +11820,Iron armour set (sk),20 +11821,Iron armour set (sk),20 +11822,Steel armour set (l),20 +11823,Steel armour set (l),20 +11824,Steel armour set (sk),20 +11825,Steel armour set (sk),20 +11826,Black armour set (l),20 +11827,Black armour set (l),20 +11828,Black armour set (sk),20 +11829,Black armour set (sk),20 +11830,Mithril armour set (l),20 +11831,Mithril armour set (l),20 +11832,Mithril armour set (sk),20 +11833,Mithril armour set (sk),20 +11834,Adamant armour set (l),20 +11835,Adamant armour set (l),20 +11836,Adamant armour set (sk),20 +11837,Adamant armour set (sk),20 +11838,Rune armour set (l),20 +11839,Rune armour set (l),20 +11840,Rune armour set (sk),20 +11841,Rune armour set (sk),20 +11842,Dragon chain armour set (l),20 +11843,Dragon chain armour set (l),20 +11844,Dragon chain armour set (sk),20 +11845,Dragon chain armour set (sk),20 +11846,Barrows - ahrim's set,20 +11847,Barrows - ahrim's set,20 +11848,Barrows - dharok's set,20 +11849,Barrows - dharok's set,20 +11850,Barrows - guthan's set,20 +11851,Barrows - guthan's set,20 +11852,Barrows - karil's set,20 +11853,Barrows - karil's set,20 +11854,Barrows - torag's set,20 +11855,Barrows - torag's set,20 +11856,Barrows - verac's set,20 +11857,Barrows - verac's set,20 +11858,Third age melee set,20 +11859,Third age melee set,20 +11860,Third age ranger set,20 +11861,Third age ranger set,20 +11862,Third age mage set,20 +11863,Third age mage set,20 +11864,Green dragonhide set,20 +11865,Green dragonhide set,20 +11866,Blue dragonhide set,20 +11867,Blue dragonhide set,20 +11868,Red dragonhide set,20 +11869,Red dragonhide set,20 +11870,Black dragonhide set,20 +11871,Black dragonhide set,20 +11872,Mystic robes set,20 +11873,Mystic robes set,20 +11874,Infinity robes set,20 +11875,Infinity robes set,20 +11876,Splitbark armour set,20 +11877,Splitbark armour set,20 +11878,Black trimmed armour set (l),20 +11879,Black trimmed armour set (l),20 +11880,Black trimmed armour set (sk),20 +11881,Black trimmed armour set (sk),20 +11882,Black gold-trimmed armour set (l),20 +11883,Black gold-trimmed armour set (l),20 +11884,Black gold-trimmed armour set (sk),20 +11885,Black gold-trimmed armour set (sk),20 +11886,Adamant trimmed armour set (l),20 +11887,Adamant trimmed armour set (l),20 +11888,Adamant trimmed armour set (sk),20 +11889,Adamant trimmed armour set (sk),20 +11890,Adamant gold-trimmed armour set (l),20 +11891,Adamant gold-trimmed armour set (l),20 +11892,Adamant gold-trimmed armour set (sk),20 +11893,Adamant gold-trimmed armour set (sk),20 +11894,Rune trimmed armour set (l),20 +11895,Rune trimmed armour set (l),20 +11896,Rune trimmed armour set (sk),20 +11897,Rune trimmed armour set (sk),20 +11898,Rune gold-trimmed armour set (l),20 +11899,Rune gold-trimmed armour set (l),20 +11900,Rune gold-trimmed armour set (sk),20 +11901,Rune gold-trimmed armour set (sk),20 +11902,Enchanted set,20 +11903,Enchanted set,20 +11904,Trimmed blue wizard set,20 +11905,Trimmed blue wizard set,20 +11906,Gold-trimmed blue wizard set,20 +11907,Gold-trimmed blue wizard set,20 +11908,Trimmed leather armour set,20 +11909,Trimmed leather armour set,20 +11910,Gold-trimmed leather armour set,20 +11911,Gold-trimmed leather armour set,20 +11912,Green d'hide trimmed set,20 +11913,Green d'hide trimmed set,20 +11914,Green d'hide gold-trimmed set,20 +11915,Green d'hide gold-trimmed set,20 +11916,Blue d'hide trimmed set,20 +11917,Blue d'hide trimmed set,20 +11918,Blue d'hide gold-trimmed set,20 +11919,Blue d'hide gold-trimmed set,20 +11920,Green d'hide blessed set,20 +11921,Green d'hide blessed set,20 +11922,Blue d'hide blessed set,20 +11923,Blue d'hide blessed set,20 +11924,Red d'hide blessed set,20 +11925,Red d'hide blessed set,20 +11926,Guthix armour set (l),20 +11927,Guthix armour set (l),20 +11928,Saradomin armour set (l),20 +11929,Saradomin armour set (l),20 +11930,Zamorak armour set (l),20 +11931,Zamorak armour set (l),20 +11932,Guthix armour set (sk),20 +11933,Guthix armour set (sk),20 +11934,Saradomin armour set (sk),20 +11935,Saradomin armour set (sk),20 +11936,Zamorak armour set (sk),20 +11937,Zamorak armour set (sk),20 +11938,Gilded armour set (l),20 +11939,Gilded armour set (l),20 +11940,Gilded armour set (sk),20 +11941,Gilded armour set (sk),20 +11942,Rockshell armour set,20 +11943,Rockshell armour set,20 +11944,Spined armour set,20 +11945,Spined armour set,20 +11946,Skeletal armour set,20 +11947,Skeletal armour set,20 +11948,null,1 +11949,Snow globe,1 +11950,Snow globe,1 +11951,Snowball,1 +11952,Ice sword,1 +11953,Winter staff,1 +11954,Holly bow,1 +11955,Barbarian snowman hat,1 +11956,Dragon snowman hat,1 +11957,Dwarf snowman hat,1 +11958,Pirate snowman hat,1 +11959,Snowman top hat,1 +11960,Light mystic robes set,20 +11961,Light mystic robes set,20 +11962,Dark mystic robes set,20 +11963,Dark mystic robes set,20 +11964,Raven egg,1 +11965,Vulture egg,1 +11966,Bird's nest,1 +11967,Dwarf cannon set,20 +11968,Dwarf cannon set,20 +11969,Enchanted water tiara,100 +11970,Smelly crate,1 +11971,Full crate,1 +11972,Empty crate,1 +11973,Scabaras research,1 +11974,Artefact receipt,1 +11975,Scabarite notes,1 +11976,Scabarite notes,1 +11977,Scabarite notes,1 +11978,Scabarite notes,1 +11979,Scabarite notes,1 +11980,Scabarite notes,1 +11981,Scabarite notes,1 +11982,Scabarite notes,1 +11983,Scabarite notes,1 +11984,Scabarite notes,1 +11985,Scabarite notes,1 +11986,Scabarite notes,1 +11987,Scabarite notes,1 +11988,Scabarite notes,1 +11989,Scabarite notes,1 +11990,Scabarite notes,1 +11991,Scabarite notes,1 +11992,Scabarite notes,1 +11993,Scabarite notes,1 +11994,Scabarite key,1 +11995,Oxidised dagger,1 +11996,Oxidised medium helm,1 +11997,Oxidised sword,1 +11998,Oxidised scimitar,1 +11999,Oxidised longsword,1 +12000,Oxidised full helm,1 +12001,Oxidised square shield,1 +12002,Oxidised chainbody,1 +12003,Oxidised kiteshield,1 +12004,Oxidised two-handed sword,1 +12005,Oxidised platelegs,1 +12006,Oxidised plateskirt,1 +12007,Spirit terrorbird pouch,724 +12008,Spirit terrorbird pouch,724 +12009,Granite crab pouch,599 +12010,Granite crab pouch,599 +12011,Praying mantis pouch,4624 +12012,Praying mantis pouch,4624 +12013,Giant ent pouch,3524 +12014,Giant ent pouch,3524 +12015,Spirit cobra pouch,3324 +12016,Spirit cobra pouch,3324 +12017,Spirit dagannoth pouch,449 +12018,Spirit dagannoth pouch,449 +12019,Thorny snail pouch,649 +12020,Thorny snail pouch,649 +12021,Beaver pouch,2224 +12022,Beaver pouch,2224 +12023,Karam. overlord pouch,4024 +12024,Karam. overlord pouch,4024 +12025,Hydra pouch,3624 +12026,Hydra pouch,3624 +12027,Spirit jelly pouch,4199 +12028,Spirit jelly pouch,4199 +12029,Bunyip pouch,3174 +12030,Bunyip pouch,3174 +12031,War tortoise pouch,449 +12032,War tortoise pouch,449 +12033,Fruit bat pouch,3674 +12034,Fruit bat pouch,3674 +12035,Abyssal parasite pouch,3074 +12036,Abyssal parasite pouch,3074 +12037,Abyssal lurker pouch,3399 +12038,Abyssal lurker pouch,3399 +12039,Unicorn stallion pouch,3924 +12040,Unicorn stallion pouch,3924 +12041,Magpie pouch,2624 +12042,Magpie pouch,2624 +12043,Dreadfowl pouch,624 +12044,Dreadfowl pouch,624 +12045,Stranger plant pouch,3624 +12046,Stranger plant pouch,3624 +12047,Spirit wolf pouch,599 +12048,Spirit wolf pouch,599 +12049,Desert wyrm pouch,1549 +12050,Desert wyrm pouch,1549 +12051,Evil turnip pouch,3024 +12052,Evil turnip pouch,3024 +12053,Vampire bat pouch,2449 +12054,Vampire bat pouch,2449 +12055,Spirit scorpion pouch,1849 +12056,Spirit scorpion pouch,1849 +12057,Arctic bear pouch,774 +12058,Arctic bear pouch,774 +12059,Spirit spider pouch,624 +12060,Spirit spider pouch,624 +12061,Bloated leech pouch,3349 +12062,Bloated leech pouch,3349 +12063,Spirit kalphite pouch,1699 +12064,Spirit kalphite pouch,1699 +12065,Honey badger pouch,2524 +12066,Honey badger pouch,2524 +12067,Albino rat pouch,2299 +12068,Albino rat pouch,2299 +12069,Granite lobster pouch,4574 +12070,Granite lobster pouch,4574 +12071,Macaw pouch,2374 +12072,Macaw pouch,2374 +12073,Bronze minotaur pouch,2974 +12074,Bronze minotaur pouch,2974 +12075,Iron minotaur pouch,3549 +12076,Iron minotaur pouch,3549 +12077,Steel minotaur pouch,3949 +12078,Steel minotaur pouch,3949 +12079,Mithril minotaur pouch,4224 +12080,Mithril minotaur pouch,4224 +12081,Adamant minotaur pouch,4024 +12082,Adamant minotaur pouch,4024 +12083,Rune minotaur pouch,449 +12084,Rune minotaur pouch,449 +12085,Smoke devil pouch,3949 +12086,Smoke devil pouch,3949 +12087,Bull ant pouch,699 +12088,Bull ant pouch,699 +12089,Wolpertinger pouch,5499 +12090,Wolpertinger pouch,5499 +12091,Compost mound pouch,1599 +12092,Compost mound pouch,1599 +12093,Pack yak pouch,5699 +12094,Pack yak pouch,5699 +12095,Sp. cockatrice pouch,2624 +12096,Sp. cockatrice pouch,2624 +12097,Sp. guthatrice pouch,2624 +12098,Sp. guthatrice pouch,2624 +12099,Sp. saratrice pouch,2624 +12100,Sp. saratrice pouch,2624 +12101,Sp. zamatrice pouch,2624 +12102,Sp. zamatrice pouch,2624 +12103,Sp. pengatrice pouch,2624 +12104,Sp. pengatrice pouch,2624 +12105,Sp. coraxatrice pouch,2624 +12106,Sp. coraxatrice pouch,2624 +12107,Sp. vulatrice pouch,2624 +12108,Sp. vulatrice pouch,2624 +12109,Cockatrice egg,100 +12110,Cockatrice egg,100 +12111,Guthatrice egg,1000 +12112,Guthatrice egg,1000 +12113,Saratrice egg,1000 +12114,Saratrice egg,1000 +12115,Zamatrice egg,1000 +12116,Zamatrice egg,1000 +12117,Pengatrice egg,1000 +12118,Pengatrice egg,1000 +12119,Coraxatrice egg,1000 +12120,Coraxatrice egg,1000 +12121,Vulatrice egg,1000 +12122,Vulatrice egg,1000 +12123,Barker toad pouch,699 +12124,Barker toad pouch,699 +12125,Flies,10 +12126,Flies,10 +12127,Beetle bits,10 +12128,Beetle bits,10 +12129,Ground fishing bait,1 +12130,Nuts,10 +12131,Nuts,10 +12132,Truffle,200 +12133,Truffle,200 +12134,Evil turnip,30 +12135,Evil turnip,30 +12136,2/3 evil turnip,20 +12137,2/3 evil turnip,20 +12138,1/3 evil turnip,10 +12139,1/3 evil turnip,10 +12140,Summoning potion(4),190 +12141,Summoning potion(4),190 +12142,Summoning potion(3),152 +12143,Summoning potion(3),152 +12144,Summoning potion(2),114 +12145,Summoning potion(2),114 +12146,Summoning potion(1),76 +12147,Summoning potion(1),76 +12148,Evil turnip seed,20 +12149,null,1 +12150,null,1 +12151,null,1 +12152,null,1 +12153,Carved evil turnip,50 +12154,Carved evil turnip,50 +12155,Pouch,1 +12156,Honeycomb,5 +12157,Honeycomb,5 +12158,Gold charm,100 +12159,Green charm,100 +12160,Crimson charm,100 +12161,Abyssal charm,1 +12162,Talon beast charm,1 +12163,Blue charm,100 +12164,Ravager charm,1 +12165,Shifter charm,1 +12166,Spinner charm,1 +12167,Torcher charm,1 +12168,Obsidian charm,1 +12169,Summoning cape,99000 +12170,Summoning cape(t),99000 +12171,Summoning hood,1 +12172,Clean spirit weed,24 +12173,Clean spirit weed,24 +12174,Grimy spirit weed,1 +12175,Grimy spirit weed,1 +12176,Spirit weed seed,18 +12177,null,1 +12178,null,1 +12179,null,1 +12180,null,1 +12181,Spirit weed potion(unf),23 +12182,Spirit weed potion(unf),23 +12183,Spirit shards,25 +12184,Gecko,1 +12185,Saradomin owl,1 +12186,Zamorak hawk,1 +12187,Guthix raptor,1 +12188,Penguin,1 +12189,Bird,1 +12190,Vulture,1 +12191,Terrier puppy,1 +12192,Greyhound puppy,1 +12193,Labrador puppy,1 +12194,Dalmatian puppy,1 +12195,Sheepdog puppy,1 +12196,Bulldog puppy,1 +12197,Dragon hatchling,1 +12198,Baby giant crab,1 +12199,Baby raccoon,1 +12200,Squirrel,1 +12201,Monkey,1 +12202,null,1 +12203,Chameleon,1 +12204,Antlers,100 +12205,Antlers,100 +12206,Antlers (charged),1 +12207,Lizard skull,200 +12208,Lizard skull,200 +12209,Lizard skull (charged),1 +12210,Feather headdress,400 +12211,Feather headdress,400 +12212,Feather headdress (charged),1 +12213,Feather headdress,400 +12214,Feather headdress,400 +12215,Feather headdress (charged),1 +12216,Feather headdress,400 +12217,Feather headdress,400 +12218,Feather headdress (charged),1 +12219,Feather headdress,400 +12220,Feather headdress,400 +12221,Feather headdress (charged),1 +12222,Feather headdress,400 +12223,Feather headdress,400 +12224,Feather headdress (charged),1 +12225,Pouch,1 +12226,Pouch,1 +12227,Pouch,1 +12228,Pouch,1 +12229,Pouch,1 +12230,Pouch,1 +12231,Pouch,1 +12232,Pouch,1 +12233,Pouch,1 +12234,Pouch,1 +12235,Pouch,1 +12236,Pouch,1 +12237,Pouch,1 +12238,Pouch,1 +12239,Pouch,1 +12240,Pouch,1 +12241,Pouch,1 +12242,Pouch,1 +12243,Pouch,1 +12244,Pouch,1 +12245,Pouch,1 +12246,Pouch,1 +12247,Pouch,1 +12248,Pouch,1 +12249,Pouch,1 +12250,Pouch,1 +12251,Pouch,1 +12252,Pouch,1 +12253,Pouch,1 +12254,Pouch,1 +12255,Pouch,1 +12256,Pouch,1 +12257,Pouch,1 +12258,Pouch,1 +12259,Pouch,1 +12260,Pouch,1 +12261,Pouch,1 +12262,Pouch,1 +12263,Pouch,1 +12264,Pouch,1 +12265,Pouch,1 +12266,Pouch,1 +12267,Pouch,1 +12268,Pouch,1 +12269,Pouch,1 +12270,Pouch,1 +12271,Pouch,1 +12272,Pouch,1 +12273,Pouch,1 +12274,Pouch,1 +12275,Pouch,1 +12276,Pouch,1 +12277,Pouch,1 +12278,Pouch,1 +12279,Pouch,1 +12280,Pouch,1 +12281,Pouch,1 +12282,Pouch,1 +12283,Pouch,1 +12284,Pouch,1 +12285,Pouch,1 +12286,Pouch,1 +12287,Pouch,1 +12288,Pouch,1 +12289,Pouch,1 +12290,Pouch,1 +12291,Pouch,1 +12292,Pouch,1 +12293,Pouch,1 +12294,Pouch,1 +12295,Pouch,1 +12296,Pouch,1 +12297,Pouch,1 +12298,Pouch,1 +12299,Pouch,1 +12300,Pouch,1 +12301,Pouch,1 +12302,Pouch,1 +12303,Pouch,1 +12304,Pouch,1 +12305,Pouch,1 +12306,Pouch,1 +12307,Pouch,1 +12308,Pouch,1 +12309,Pouch,1 +12310,Pouch,1 +12311,Pouch,1 +12312,Pouch,1 +12313,Pouch,1 +12314,Pouch,1 +12315,Pouch,1 +12316,Pouch,1 +12317,Pouch,1 +12318,Pouch,1 +12319,Pouch,1 +12320,Pouch,1 +12321,Pouch,1 +12322,Pouch,1 +12323,Pouch,1 +12324,Pouch,1 +12325,Pouch,1 +12326,Pouch,1 +12327,Pouch,1 +12328,Pouch,1 +12329,Pouch,1 +12330,Pouch,1 +12331,Pouch,1 +12332,Pouch,1 +12333,Pouch,1 +12334,Pouch,1 +12335,Pouch,1 +12336,Pouch,1 +12337,Pouch,1 +12338,Pouch,1 +12339,Pouch,1 +12340,Pouch,1 +12341,Pouch,1 +12342,Pouch,1 +12343,Pouch,1 +12344,Pouch,1 +12345,Pouch,1 +12346,Pouch,1 +12347,Pouch,1 +12348,Pouch,1 +12349,Pouch,1 +12350,Pouch,1 +12351,Pouch,1 +12352,Pouch,1 +12353,Pouch,1 +12354,Pouch,1 +12355,Pouch,1 +12356,Pouch,1 +12357,Pouch,1 +12358,Pouch,1 +12359,Pouch,1 +12360,Pouch,1 +12361,Pouch,1 +12362,Pouch,1 +12363,Pouch,1 +12364,Pouch,1 +12365,Pouch,1 +12366,Pouch,1 +12367,Pouch,1 +12368,Pouch,1 +12369,Pouch,1 +12370,Pouch,1 +12371,Pouch,1 +12372,Pouch,1 +12373,Pouch,1 +12374,Pouch,1 +12375,Pouch,1 +12376,Pouch,1 +12377,Pouch,1 +12378,Pouch,1 +12379,Pouch,1 +12380,Pouch,1 +12381,Pouch,1 +12382,Pouch,1 +12383,Pouch,1 +12384,Pouch,1 +12385,Pouch,1 +12386,Pouch,1 +12387,Pouch,1 +12388,Pouch,1 +12389,Pouch,1 +12390,Pouch,1 +12391,Pouch,1 +12392,Pouch,1 +12393,Pouch,1 +12394,Pouch,1 +12395,Pouch,1 +12396,Pouch,1 +12397,Pouch,1 +12398,Pouch,1 +12399,Pouch,1 +12400,Pouch,1 +12401,Pouch,1 +12402,Pouch,1 +12403,Pouch,1 +12404,Pouch,1 +12405,Pouch,1 +12406,Pouch,1 +12407,Pouch,1 +12408,Pouch,1 +12409,Pouch,1 +12410,Pouch,1 +12411,Pouch,1 +12412,Pouch,1 +12413,Pouch,1 +12414,Pouch,1 +12415,Pouch,1 +12416,Pouch,1 +12417,Pouch,1 +12418,Pouch,1 +12419,Pouch,1 +12420,Pouch,1 +12421,Scroll,1 +12422,Herbcall scroll,237 +12423,Fruitfall scroll,367 +12424,Fish rain scroll,314 +12425,Howl scroll,59 +12426,Thieving fingers scroll,262 +12427,Abyssal stealth scroll,339 +12428,Egg spawn scroll,62 +12429,Multichop scroll,222 +12430,Cheese feast scroll,229 +12431,Unburden scroll,69 +12432,Venom shot scroll,184 +12433,Insane ferocity scroll,252 +12434,Healing aura scroll,392 +12435,Winter storage scroll,569 +12436,Oph. incubation scroll,332 +12437,Magic focus scroll,549 +12438,Swallow whole scroll,317 +12439,Testudo scroll,44 +12440,Generate compost scroll,159 +12441,Tireless run scroll,72 +12442,Regrowth scroll,362 +12443,Call to arms scroll,227 +12444,Blood drain scroll,334 +12445,Dreadfowl strike scroll,62 +12446,Sandstorm scroll,169 +12447,Vampire touch scroll,244 +12448,Evil flames scroll,302 +12449,Crushing claw scroll,457 +12450,Mantis strike scroll,462 +12451,Arctic blast scroll,77 +12452,Toad bark scroll,69 +12453,Dissolve scroll,419 +12454,Abyssal drain scroll,307 +12455,Doomsphere scroll,402 +12456,Spike shot scroll,44 +12457,Acorn missile scroll,352 +12458,Petrifying gaze scroll,262 +12459,Slime spray scroll,64 +12460,Electric lash scroll,154 +12461,Bronze bull rush scroll,297 +12462,Iron bull rush scroll,354 +12463,Steel bull rush scroll,394 +12464,Mith bull rush scroll,422 +12465,Addy bull rush scroll,402 +12466,Rune bull rush scroll,44 +12467,Poisonous blast scroll,362 +12468,Dust cloud scroll,394 +12469,Hatchling dragon,1 +12470,Baby dragon,1 +12471,Hatchling dragon,1 +12472,Baby dragon,1 +12473,Hatchling dragon,1 +12474,Baby dragon,1 +12475,Hatchling dragon,1 +12476,Baby dragon,1 +12477,Red dragon egg,1 +12478,Blue dragon egg,1 +12479,Green dragon egg,1 +12480,Black dragon egg,1 +12481,Baby penguin,1 +12482,Penguin,1 +12483,Penguin egg,1 +12484,Raven chick,1 +12485,Raven,1 +12486,Baby raccoon,1 +12487,Raccoon,1 +12488,Baby gecko,1 +12489,Gecko,1 +12490,Baby squirrel,1 +12491,Squirrel,1 +12492,Baby chameleon,1 +12493,Chameleon,1 +12494,Chameleon egg,1 +12495,Chameleon egg,1 +12496,Baby monkey,1 +12497,Monkey,1 +12498,Vulture chick,1 +12499,Vulture,1 +12500,Baby giant crab,1 +12501,Giant crab,1 +12502,Crunchy claw token,1 +12503,Saradomin chick,1 +12504,Saradomin bird,1 +12505,Saradomin owl,1 +12506,Zamorak chick,1 +12507,Zamorak bird,1 +12508,Zamorak hawk,1 +12509,Guthix chick,1 +12510,Guthix bird,1 +12511,Guthix raptor,1 +12512,Terrier puppy,1 +12513,Terrier,1 +12514,Greyhound puppy,1 +12515,Greyhound,1 +12516,Labrador puppy,1 +12517,Labrador,1 +12518,Dalmatian puppy,1 +12519,Dalmatian,1 +12520,Sheepdog puppy,1 +12521,Sheepdog,1 +12522,Bulldog puppy,1 +12523,Bulldog,1 +12524,Summoning cape,99000 +12525,Pouch,0 +12526,Spirit wolf pouch,0 +12527,Gold charm,0 +12528,Trapdoor key,1 +12529,Howl scroll,0 +12530,Spirit shards,0 +12531,Ibis pouch,3149 +12532,Ibis pouch,3149 +12533,Stony shell scroll,59 +12534,null,1 +12535,Raw pawya meat,500 +12536,Raw pawya meat,500 +12537,Picture,1 +12538,Picture,1 +12539,Grenwall spikes,200 +12540,null,1 +12541,null,1 +12542,null,1 +12543,null,1 +12544,Picture,1 +12545,Picture,1 +12546,Enchanted pawya meat,1 +12547,Platypus,1 +12548,Platypus,0 +12549,Platypus,0 +12550,Platypus,0 +12551,Baby platypus,0 +12552,Baby platypus,0 +12553,Baby platypus,0 +12554,Patrick,0 +12555,Penelope,0 +12556,Peter,0 +12557,Peanut,0 +12558,Mud,10 +12559,Ogre wig,60 +12560,Ogre wig,60 +12561,Ogre kilt,60 +12562,Ogre kilt,60 +12563,Ogre top,60 +12564,Ogre top,60 +12565,Ogre boots,60 +12566,Ogre boots,60 +12567,Diseased kebbit fur,60 +12568,Davy kebbit hat,100 +12569,Davy kebbit hat,100 +12570,Ogre club,180 +12571,Ogre club,180 +12572,Lavender,4 +12573,Lavender,4 +12574,Fever grass,4 +12575,Fever grass,4 +12576,Tansymum,4 +12577,Tansymum,4 +12578,Smouldering fever grass,4 +12579,Smouldering lavender,4 +12580,Smouldering tansymum,4 +12581,Eucalyptus logs,126 +12582,Eucalyptus logs,126 +12583,Eucalyptus pyre logs,252 +12584,Eucalyptus pyre logs,252 +12585,null,1 +12586,null,1 +12587,null,1 +12588,Primweed,2 +12589,Primweed,2 +12590,Stinkbloom,2 +12591,Stinkbloom,2 +12592,Diseased kebbit fur,60 +12593,Catapult schematics,1 +12594,Engineer's letter,1 +12595,Sailor's hat,1 +12596,Metal catapult parts,1 +12597,Mahogany catapult part,1 +12598,Mahogany catapult part,1 +12599,Mahogany catapult part,1 +12600,Mahogany catapult part,1 +12601,Mahogany catapult part,1 +12602,Mahogany catapult part,1 +12603,Mahogany catapult part,1 +12604,Mahogany catapult part,1 +12605,Mahogany catapult part,1 +12606,Mahogany catapult part,1 +12607,Picture,1 +12608,Amulet of farming(1),200 +12609,Amulet of farming(1),200 +12610,Amulet of farming(2),200 +12611,Amulet of farming(2),200 +12612,Amulet of farming(3),200 +12613,Amulet of farming(3),200 +12614,Amulet of farming(4),200 +12615,Amulet of farming(4),200 +12616,Amulet of farming(5),200 +12617,Amulet of farming(5),200 +12618,Amulet of farming(6),200 +12619,Amulet of farming(6),200 +12620,Amulet of farming(7),200 +12621,Amulet of farming(7),200 +12622,Amulet of farming(8),200 +12623,Amulet of farming(8),200 +12624,Ogleroot,20 +12625,Flag,1 +12626,Test paper,2 +12627,Antique lamp,1 +12628,Antique lamp,1 +12629,Safety gloves,1 +12630,Rubium,0 +12631,Toy train,1 +12632,Note,0 +12633,Super fishing explosive,60 +12634,Chocatrice cape,1 +12635,Easter egg,1 +12636,Easter egg,1 +12637,Easter egg,1 +12638,Easter egg,1 +12639,Easter egg,1 +12640,Easter egg,1 +12641,Easter egg,1 +12642,Easter egg,1 +12643,Easter egg,1 +12644,Easter egg,1 +12645,Chocatrice cape,32 +12646,Chocolate egg,1 +12647,Chocolate egg,1 +12648,Chocolate egg,1 +12649,Bucket,1 +12650,Bucket of water,1 +12651,Bucket of water,1 +12652,Bucket of coal,1 +12653,Bucket of coal,1 +12654,Cockatrice egg,1 +12655,Chocatrice egg,1 +12656,Chocatrice object,1 +12657,Chocolate chunks,1 +12658,Adamant full helm (e),3520 +12659,Adamant full helm (charged),3520 +12660,Snakeskin bandana (e),300 +12661,Snakeskin bandana (charged),300 +12662,Splitbark helm (e),10000 +12663,Splitbark helm (charged),10000 +12664,Rune full helm (e),35200 +12665,Rune full helm (charged),35200 +12666,Dragon med helm (e),100000 +12667,Dragon med helm (charged),100000 +12668,Lunar helm (e),100 +12669,Lunar helm (charged),100 +12670,Armadyl helmet (e),20000 +12671,Armadyl helmet (charged),20000 +12672,Archer helm (e),78000 +12673,Archer helm (charged),78000 +12674,Berserker helm (e),78000 +12675,Berserker helm (charged),78000 +12676,Warrior helm (e),78000 +12677,Warrior helm (charged),78000 +12678,Farseer helm (e),78000 +12679,Farseer helm (charged),78000 +12680,Helm of neitiznot (e),50000 +12681,Helm of neitiznot (charged),50000 +12682,Baby monkey,1 +12683,Monkey,1 +12684,Baby monkey,1 +12685,Monkey,1 +12686,Baby monkey,1 +12687,Monkey,1 +12688,Baby monkey,1 +12689,Monkey,1 +12690,Baby monkey,1 +12691,Monkey,1 +12692,Baby monkey,1 +12693,Monkey,1 +12694,Baby monkey,1 +12695,Monkey,1 +12696,Baby monkey,1 +12697,Monkey,1 +12698,Baby monkey,1 +12699,Monkey,1 +12700,Terrier puppy,1 +12701,Terrier,1 +12702,Terrier puppy,1 +12703,Terrier,1 +12704,Greyhound puppy,1 +12705,Greyhound,1 +12706,Greyhound puppy,1 +12707,Greyhound,1 +12708,Labrador puppy,1 +12709,Labrador,1 +12710,Labrador puppy,1 +12711,Labrador,1 +12712,Dalmatian puppy,1 +12713,Dalmatian,1 +12714,Dalmatian puppy,1 +12715,Dalmatian,1 +12716,Sheepdog puppy,1 +12717,Sheepdog,1 +12718,Sheepdog puppy,1 +12719,Sheepdog,1 +12720,Bulldog puppy,1 +12721,Bulldog,1 +12722,Bulldog puppy,1 +12723,Bulldog,1 +12724,Raven chick,1 +12725,Raven,1 +12726,Raven chick,1 +12727,Raven,1 +12728,Raven chick,1 +12729,Raven,1 +12730,Raven chick,1 +12731,Raven,1 +12732,Raven chick,1 +12733,Raven,1 +12734,Baby raccoon,1 +12735,Raccoon,1 +12736,Baby raccoon,1 +12737,Raccoon,1 +12738,Baby gecko,1 +12739,Baby gecko,1 +12740,Baby gecko,1 +12741,Baby gecko,1 +12742,Gecko,1 +12743,Gecko,1 +12744,Gecko,1 +12745,Gecko,1 +12746,Baby giant crab,1 +12747,Giant crab,1 +12748,Baby giant crab,1 +12749,Giant crab,1 +12750,Baby giant crab,1 +12751,Giant crab,1 +12752,Baby giant crab,1 +12753,Giant crab,1 +12754,Baby squirrel,1 +12755,Squirrel,1 +12756,Baby squirrel,1 +12757,Squirrel,1 +12758,Baby squirrel,1 +12759,Squirrel,1 +12760,Baby squirrel,1 +12761,Squirrel,1 +12762,Penguin,1 +12763,Baby penguin,1 +12764,Penguin,1 +12765,Baby penguin,1 +12766,Vulture chick,1 +12767,Vulture,1 +12768,Vulture chick,1 +12769,Vulture,1 +12770,Vulture chick,1 +12771,Vulture,1 +12772,Vulture chick,1 +12773,Vulture,1 +12774,Vulture chick,1 +12775,Vulture,1 +12776,Swamp titan pouch,4174 +12777,Swamp titan pouch,4174 +12778,Spirit mosquito pouch,449 +12779,Spirit mosquito pouch,449 +12780,Void spinner pouch,2274 +12781,Void spinner pouch,2274 +12782,Forge regent pouch,3949 +12783,Forge regent pouch,3949 +12784,Spirit larupia pouch,4299 +12785,Spirit larupia pouch,4299 +12786,Geyser titan pouch,5974 +12787,Geyser titan pouch,5974 +12788,Lava titan pouch,5899 +12789,Lava titan pouch,5899 +12790,Steel titan pouch,4874 +12791,Steel titan pouch,4874 +12792,Obsidian golem pouch,5299 +12793,Obsidian golem pouch,5299 +12794,Talon beast pouch,4774 +12795,Talon beast pouch,4774 +12796,Abyssal titan pouch,3249 +12797,Abyssal titan pouch,3249 +12798,Void torcher pouch,2274 +12799,Void torcher pouch,2274 +12800,Giant chinchompa pouch,2524 +12801,Giant chinchompa pouch,2524 +12802,Fire titan pouch,5374 +12803,Fire titan pouch,5374 +12804,Moss titan pouch,5474 +12805,Moss titan pouch,5474 +12806,Ice titan pouch,5374 +12807,Ice titan pouch,5374 +12808,Spirit tz-kih pouch,2024 +12809,Spirit tz-kih pouch,2024 +12810,Spirit graahk pouch,4274 +12811,Spirit graahk pouch,4274 +12812,Spirit kyatt pouch,4249 +12813,Spirit kyatt pouch,4249 +12814,Void shifter pouch,2274 +12815,Void shifter pouch,2274 +12816,Pyrelord pouch,3199 +12817,Pyrelord pouch,3199 +12818,Void ravager pouch,2274 +12819,Void ravager pouch,2274 +12820,Ravenous locust pouch,2399 +12821,Ravenous locust pouch,2399 +12822,Iron titan pouch,5374 +12823,Iron titan pouch,5374 +12824,Titan's con. scroll,537 +12825,Steel of legends scroll,487 +12826,Volcanic str. scroll,529 +12827,Essence shipment scroll,324 +12828,Iron within scroll,537 +12829,Immense heat scroll,319 +12830,Famine scroll,239 +12831,Deadly claw scroll,477 +12832,Swamp plague scroll,417 +12833,Boil scroll,597 +12834,Explode scroll,252 +12835,Goad scroll,427 +12836,Ambush scroll,424 +12837,Ebon thunder scroll,529 +12838,Pester scroll,44 +12839,Fireball assault scroll,202 +12840,Rending scroll,429 +12841,Inferno scroll,394 +12842,Gnomecopter,0 +12843,Gnomecopter ticket,0 +12844,Toy kite,100 +12845,Stone of power,1 +12846,Stone of power,1 +12847,Stone of power,1 +12848,Stone of power,1 +12849,Stone of power,1 +12850,Elemental rune,2 +12851,Catalytic rune,2 +12852,Fist of guthix token,1 +12853,Bandages,1 +12854,null,1 +12855,Tele-orb,1 +12856,Irit gloves,1 +12857,Avantoe gloves,1 +12858,Kwuarm gloves,1 +12859,Cadantine gloves,1 +12860,Swordfish gloves,1 +12861,Shark gloves,1 +12862,Dragon slayer gloves,1 +12863,Air runecrafting gloves,1 +12864,Water runecrafting gloves,1 +12865,Earth runecrafting gloves,1 +12866,Battle hood 100,25000 +12867,Battle hood 80,25000 +12868,Battle hood 60,25000 +12869,Battle hood 40,25000 +12870,Battle hood 20,25000 +12871,Battle hood 0,25000 +12872,Battle hood 0,25000 +12873,Battle robe top 100,50000 +12874,Battle robe top 80,50000 +12875,Battle robe top 60,50000 +12876,Battle robe top 40,50000 +12877,Battle robe top 20,50000 +12878,Battle robe top 0,50000 +12879,Battle robe top 0,50000 +12880,Battle robe bottom 100,40000 +12881,Battle robe bottom 80,40000 +12882,Battle robe bottom 60,40000 +12883,Battle robe bottom 40,40000 +12884,Battle robe bottom 20,40000 +12885,Battle robe bottom 0,40000 +12886,Battle robe bottom 0,40000 +12887,Druidic mage hood 100,2000 +12888,Druidic mage hood 80,2000 +12889,Druidic mage hood 60,2000 +12890,Druidic mage hood 40,2000 +12891,Druidic mage hood 20,2000 +12892,Druidic mage hood 0,2000 +12893,Druidic mage hood 0,2000 +12894,Druidic mage top 100,6000 +12895,Druidic mage top 80,6000 +12896,Druidic mage top 60,6000 +12897,Druidic mage top 40,6000 +12898,Druidic mage top 20,6000 +12899,Druidic mage top 0,6000 +12900,Druidic mage top 0,6000 +12901,Druidic mage bottom 100,5000 +12902,Druidic mage bottom 80,5000 +12903,Druidic mage bottom 60,5000 +12904,Druidic mage bottom 40,5000 +12905,Druidic mage bottom 20,5000 +12906,Druidic mage bottom 0,5000 +12907,Druidic mage bottom 0,5000 +12908,Adamant spikeshield 100,4050 +12909,Adamant spikeshield 80,4050 +12910,Adamant spikeshield 60,4050 +12911,Adamant spikeshield 40,4050 +12912,Adamant spikeshield 20,4050 +12913,Adamant spikeshield 0,4050 +12914,Adamant spikeshield 0,4050 +12915,Adamant berserker shield 100,6140 +12916,Adamant berserker shield 80,6140 +12917,Adamant berserker shield 60,6140 +12918,Adamant berserker shield 40,6140 +12919,Adamant berserker shield 20,6140 +12920,Adamant berserker shield 0,6140 +12921,Adamant berserker shield 0,6140 +12922,Rune spikeshield 100,40000 +12923,Rune spikeshield 80,40000 +12924,Rune spikeshield 60,40000 +12925,Rune spikeshield 40,40000 +12926,Rune spikeshield 20,40000 +12927,Rune spikeshield 0,40000 +12928,Rune spikeshield 0,40000 +12929,Rune berserker shield 100,64400 +12930,Rune berserker shield 80,64400 +12931,Rune berserker shield 60,64400 +12932,Rune berserker shield 40,64400 +12933,Rune berserker shield 20,64400 +12934,Rune berserker shield 0,64400 +12935,Rune berserker shield 0,64400 +12936,Green d'hide coif 100,2000 +12937,Green d'hide coif 80,2000 +12938,Green d'hide coif 60,2000 +12939,Green d'hide coif 40,2000 +12940,Green d'hide coif 20,2000 +12941,Green d'hide coif 0,2000 +12942,Green d'hide coif 0,2000 +12943,Blue d'hide coif 100,3500 +12944,Blue d'hide coif 80,3500 +12945,Blue d'hide coif 60,3500 +12946,Blue d'hide coif 40,3500 +12947,Blue d'hide coif 20,3500 +12948,Blue d'hide coif 0,3500 +12949,Blue d'hide coif 0,3500 +12950,Red d'hide coif 100,3500 +12951,Red d'hide coif 80,3500 +12952,Red d'hide coif 60,3500 +12953,Red d'hide coif 40,3500 +12954,Red d'hide coif 20,3500 +12955,Red d'hide coif 0,3500 +12956,Red d'hide coif 0,3500 +12957,Black d'hide coif 100,5500 +12958,Black d'hide coif 80,5500 +12959,Black d'hide coif 60,5500 +12960,Black d'hide coif 40,5500 +12961,Black d'hide coif 20,5500 +12962,Black d'hide coif 0,5500 +12963,Black d'hide coif 0,5500 +12964,Combat hood 100,1000 +12965,Combat hood 80,1000 +12966,Combat hood 60,1000 +12967,Combat hood 40,1000 +12968,Combat hood 20,1000 +12969,Combat hood 0,1000 +12970,Combat hood 0,1000 +12971,Combat robe top 100,3000 +12972,Combat robe top 80,3000 +12973,Combat robe top 60,3000 +12974,Combat robe top 40,3000 +12975,Combat robe top 20,3000 +12976,Combat robe top 0,3000 +12977,Combat robe top 0,3000 +12978,Combat robe bottom 100,2500 +12979,Combat robe bottom 80,2500 +12980,Combat robe bottom 60,2500 +12981,Combat robe bottom 40,2500 +12982,Combat robe bottom 20,2500 +12983,Combat robe bottom 0,2500 +12984,Combat robe bottom 0,2500 +12985,Bronze gauntlets,100 +12986,Worn-out bronze gauntlets,100 +12987,Worn-out bronze gauntlets,100 +12988,Iron gauntlets,300 +12989,Worn-out iron gauntlets,300 +12990,Worn-out iron gauntlets,300 +12991,Steel gauntlets,1000 +12992,Worn-out steel gauntlets,1000 +12993,Worn-out steel gauntlets,1000 +12994,Black gauntlets,2000 +12995,Worn-out black gauntlets,2000 +12996,Worn-out black gauntlets,2000 +12997,Mithril gauntlets,3000 +12998,Worn-out mithril gauntlets,3000 +12999,Worn-out mithril gauntlets,3000 +13000,Adamant gauntlets,5000 +13001,Worn-out adamant gauntlets,5000 +13002,Worn-out adamant gauntlets,5000 +13003,Rune gauntlets,7500 +13004,Worn-out rune gauntlets,7500 +13005,Worn-out rune gauntlets,7500 +13006,Dragon gauntlets,50000 +13007,Worn-out dragon gauntlets,50000 +13008,Worn-out dragon gauntlets,50000 +13009,null,0 +13010,Clue scroll,1 +13011,Puzzle box,100 +13012,Clue scroll,1 +13013,Puzzle box,100 +13014,Clue scroll,1 +13015,Puzzle box,100 +13016,Clue scroll,1 +13017,Puzzle box,100 +13018,Clue scroll,1 +13019,Puzzle box,100 +13020,Clue scroll,1 +13021,Puzzle box,100 +13022,Clue scroll,1 +13023,Puzzle box,100 +13024,Clue scroll,1 +13025,Puzzle box,100 +13026,Clue scroll,1 +13027,Puzzle box,100 +13028,Clue scroll,1 +13029,Puzzle box,100 +13030,Clue scroll,1 +13031,Puzzle box,100 +13032,Clue scroll,1 +13033,Puzzle box,100 +13034,Clue scroll,1 +13035,Puzzle box,100 +13036,Clue scroll,1 +13037,Casket,50 +13038,Clue scroll,1 +13039,Casket,50 +13040,Clue scroll,1 +13041,Clue scroll,1 +13042,Clue scroll,1 +13043,Casket,50 +13044,Clue scroll,1 +13045,Casket,50 +13046,Clue scroll,1 +13047,Casket,50 +13048,Clue scroll,1 +13049,Clue scroll,1 +13050,Clue scroll,1 +13051,Clue scroll,1 +13052,Casket,50 +13053,Clue scroll,1 +13054,Casket,50 +13055,Clue scroll,1 +13056,Clue scroll,1 +13057,Casket,50 +13058,Clue scroll,1 +13059,Casket,50 +13060,Clue scroll,1 +13061,Clue scroll,1 +13062,Casket,50 +13063,Clue scroll,1 +13064,Casket,50 +13065,Clue scroll,1 +13066,Casket,50 +13067,Clue scroll,1 +13068,Clue scroll,1 +13069,Clue scroll,1 +13070,Clue scroll,1 +13071,Clue scroll,1 +13072,Clue scroll,1 +13073,Key,1 +13074,Clue scroll,1 +13075,Clue scroll,1 +13076,Clue scroll,1 +13077,Casket,50 +13078,Clue scroll,1 +13079,Clue scroll,1 +13080,Clue scroll,1 +13081,Black crossbow,800 +13082,Black crossbow,800 +13083,Black bolts,14 +13084,Black bolts(p),14 +13085,Black bolts(p+),14 +13086,Black bolts(p++),14 +13087,null,1 +13088,null,1 +13089,null,1 +13090,null,1 +13091,null,1 +13092,null,1 +13093,null,1 +13094,null,1 +13095,Black cane,432 +13096,Black cane,432 +13097,Adamant cane,1440 +13098,Adamant cane,1440 +13099,Rune cane,14400 +13100,Rune cane,14400 +13101,Top hat,200 +13102,Top hat,200 +13103,Pith helmet,250 +13104,Pith helmet,250 +13105,Spiked helmet,1000 +13106,Spiked helmet,1000 +13107,Sheep mask,800 +13108,Sheep mask,800 +13109,Penguin mask,800 +13110,Penguin mask,800 +13111,Bat mask,800 +13112,Bat mask,800 +13113,Cat mask,800 +13114,Cat mask,800 +13115,Wolf mask,800 +13116,Wolf mask,800 +13117,Ivandis flail (30),1000 +13118,Ivandis flail (29),1000 +13119,Ivandis flail(28),1000 +13120,Ivandis flail (27),1000 +13121,Ivandis flail (26),1000 +13122,Ivandis flail (25),1000 +13123,Ivandis flail (24),1000 +13124,Ivandis flail (23),1000 +13125,Ivandis flail (22),1000 +13126,Ivandis flail (21),1000 +13127,Ivandis flail (20),1000 +13128,Ivandis flail (19),1000 +13129,Ivandis flail (18),1000 +13130,Ivandis flail (17),1000 +13131,Ivandis flail (16),1000 +13132,Ivandis flail (15),1000 +13133,Ivandis flail (14),1000 +13134,Ivandis flail (13),1000 +13135,Ivandis flail (12),1000 +13136,Ivandis flail (11),1000 +13137,Ivandis flail (10),1000 +13138,Ivandis flail (9),1000 +13139,Ivandis flail (8),1000 +13140,Ivandis flail (7),1000 +13141,Ivandis flail (6),1000 +13142,Ivandis flail (5),1000 +13143,Ivandis flail (4),1000 +13144,Ivandis flail (3),1000 +13145,Ivandis flail (2),1000 +13146,Ivandis flail (1),1000 +13147,Flail dust,1 +13148,Glove,3 +13149,Book page,3 +13150,Crate,1 +13151,Combat book,3 +13152,null,3 +13153,Chain link mould,3 +13154,Silvthril chain,3 +13155,Silver sickle emerald(b),3 +13156,Enchanted sickle emerald(b),3 +13157,Vyre corpse,3 +13158,Columbarium key,3 +13159,Ornate tomb key,3 +13160,Tome of xp 2nd ed (3),1 +13161,Tome of xp 2nd ed (2),1 +13162,Tome of xp 2nd ed (1),1 +13163,Black cane,432 +13164,Adamant cane,1440 +13165,Rune cane,14400 +13166,Top hat,200 +13167,Pith helmet,250 +13168,Spiked helmet,1000 +13169,Sheep mask,800 +13170,Penguin mask,800 +13171,Bat mask,800 +13172,Cat mask,800 +13173,Wolf mask,800 +13174,Blue navy slacks,1 +13175,Green navy slacks,1 +13176,Red navy slacks,1 +13177,Brown navy slacks,1 +13178,Black navy slacks,1 +13179,Purple navy slacks,1 +13180,Grey navy slacks,1 +13181,Blue naval shirt,1 +13182,Green naval shirt,1 +13183,Red naval shirt,1 +13184,Brown naval shirt,1 +13185,Black naval shirt,1 +13186,Purple naval shirt,1 +13187,Grey naval shirt,1 +13188,Blue tricorn hat,1 +13189,Green tricorn hat,1 +13190,Red tricorn hat,1 +13191,Brown tricorn hat,1 +13192,Black tricorn hat,1 +13193,Purple tricorn hat,1 +13194,Grey tricorn hat,1 +13195,null,1 +13196,null,1 +13197,null,1 +13198,null,1 +13199,null,1 +13200,null,1 +13201,null,1 +13202,null,1 +13203,null,1 +13204,null,1 +13205,null,1 +13206,null,1 +13207,null,1 +13208,null,1 +13209,null,1 +13210,null,1 +13211,null,1 +13212,null,1 +13213,null,1 +13214,null,1 +13215,null,1 +13216,null,1 +13217,null,1 +13218,null,1 +13219,null,1 +13220,null,1 +13221,null,1 +13222,null,1 +13223,null,1 +13224,null,1 +13225,null,1 +13226,null,1 +13227,Mysterious lamp,1 +13228,Crate,1 +13229,Letter,1 +13230,Icefiend net,1 +13231,Baby icefiend,1 +13232,Tent,1 +13233,Plans,1 +13234,Dwarven key,1 +13235,null,1 +13236,Three little kittens,3 +13237,null,1 +13238,Treated oak plank,1 +13239,Chisel,1 +13240,.,1 +13241,Treated plank,1 +13242,.,1 +13243,Stone tablet,1 +13244,Tzhaar tourist guide,1 +13245,Stone slab,1 +13246,Pillar,1 +13247,Splat,1 +13248,Splat,1 +13249,Splat,1 +13250,Splat,1 +13251,null,1 +13252,null,1 +13253,null,1 +13254,null,1 +13255,null,1 +13256,null,1 +13257,null,1 +13258,null,1 +13259,Ranged path key,1 +13260,Magic path key,1 +13261,null,1 +13262,null,1 +13263,Slayer helmet,650 +13264,null,1 +13265,null,1 +13266,null,1 +13267,null,1 +13268,null,3 +13269,null,3 +13270,null,3 +13271,null,3 +13272,null,3 +13273,null,3 +13274,null,3 +13275,null,3 +13276,Banshee voice,1 +13277,Masked earmuffs,400 +13278,Broad arrow heads,50 +13279,Unfinished broad bolts,50 +13280,Broad-tipped bolts,50 +13281,Ring of slaying(8),150 +13282,Ring of slaying(7),150 +13283,Ring of slaying(6),150 +13284,Ring of slaying(5),150 +13285,Ring of slaying(4),150 +13286,Ring of slaying(3),150 +13287,Ring of slaying(2),150 +13288,Ring of slaying(1),150 +13289,null,3 +13290,Leaf-bladed sword,68000 +13291,Leaf-bladed sword,68000 +13292,Letter,0 +13293,Plans,0 +13294,Charcoal rubbing,0 +13295,Frank's mark,0 +13296,Crude lockpick,0 +13297,Customs shirt,0 +13298,Customs trousers,0 +13299,Customs hat,0 +13300,File,0 +13301,File,0 +13302,Brooch,0 +13303,Izzy's mark,0 +13304,Key,1 +13305,Crowbar,1 +13306,null,1 +13307,Idol of many heads,1 +13308,Bill teach's mark,0 +13309,Paper,0 +13310,Confession,0 +13311,Note,0 +13312,Ink bottle,0 +13313,Inky paper,0 +13314,Ink bottle,0 +13315,Smashed bottle,0 +13316,Prison uniform top,0 +13317,Prison uniform trousers,0 +13318,Fishy prison uniform top,0 +13319,Tin cup,0 +13320,Tin cup,0 +13321,Pipe,0 +13322,Accordion,0 +13323,Accordion,0 +13324,Accordion,0 +13325,Vacuum pump,0 +13326,Vacuum pump and gull,0 +13327,Quill,0 +13328,Inky quill,0 +13329,File,0 +13330,File,0 +13331,Ex-parrot,0 +13332,Magical cage,0 +13333,Ex-parrot in a magic cage,0 +13334,Ex-ex-parrot in a magic cage,0 +13335,Ex-ex-parrot,0 +13336,Ex-ex-parrot,0 +13337,Pirate impling jar,50 +13338,Pirate impling jar,50 +13339,Bandana and eyepatch,100 +13340,Bandana and eyepatches,100 +13341,Bandana and eyepatch,100 +13342,Bandana and eyepatches,100 +13343,Bandana and eyepatch,100 +13344,Bandana and eyepatches,100 +13345,Bandana and eyepatch,100 +13346,Bandana and eyepatches,100 +13347,Bandana and eyepatch,100 +13348,Bandana and eyepatches,100 +13349,Bandana and eyepatch,100 +13350,Bandana and eyepatches,100 +13351,Bandana and eyepatch,100 +13352,Bandana and eyepatches,100 +13353,Double eyepatches,100 +13354,Pirate hat and eyepatches,100 +13355,Left eyepatch,100 +13356,Left eyepatch,100 +13357,Pirate hat and eyepatch,100 +13358,Stripy pirate shirt,300 +13359,Stripy pirate shirt,300 +13360,Stripy pirate shirt,300 +13361,Stripy pirate shirt,300 +13362,Stripy pirate shirt,300 +13363,Stripy pirate shirt,300 +13364,Pirate leggings,350 +13365,Pirate leggings,350 +13366,Pirate leggings,350 +13367,Pirate leggings,350 +13368,Pirate leggings,350 +13369,Pirate leggings,350 +13370,Bandana,100 +13371,Bandana,100 +13372,Bandana,100 +13373,Bandana,100 +13374,Bandana,100 +13375,Bandana,100 +13376,Bandana and eyepatch,100 +13377,Bandana and eyepatch,100 +13378,Bandana and eyepatch,100 +13379,Rock fragments,0 +13380,Introduction letter,0 +13381,Broken hand,0 +13382,Broken hand,0 +13383,Broken hand,0 +13384,Broken hand,0 +13385,Broken hand,0 +13386,Fingers,0 +13387,Thumb,0 +13388,Hand,0 +13389,Wrist,0 +13390,Brace,0 +13391,Brass hand,0 +13392,Ink pad,0 +13393,Inky hand,0 +13394,Paper,0 +13395,Brass hand harry's mark,0 +13396,Fake beard,0 +13397,Fake moustache and nose,0 +13398,Fake monocle, moustache and nose,0 +13399,Curly wig,0 +13400,Straight wig,0 +13401,Order,0 +13402,Braindeath's mark,0 +13403,Golden tinderbox,300 +13404,null,1 +13405,Dark bow,0 +13406,Ancient staff,0 +13407,Archer helm,0 +13408,Berserker helm,0 +13409,Warrior helm,0 +13410,Farseer helm,0 +13411,Rock-shell helm,0 +13412,Rock-shell plate,0 +13413,Rock-shell legs,0 +13414,Spined helm,0 +13415,Spined body,0 +13416,Spined chaps,0 +13417,Skeletal helm,0 +13418,Skeletal top,0 +13419,Skeletal bottoms,0 +13420,Spined boots,0 +13421,Rock-shell boots,0 +13422,Skeletal boots,0 +13423,Spined gloves,0 +13424,Rock-shell gloves,0 +13425,Skeletal gloves,0 +13426,Seers ring,0 +13427,Archers ring,0 +13428,Warrior ring,0 +13429,Berserker ring,0 +13430,Dragon 2h sword,0 +13431,Crayfish cage,20 +13432,Crayfish cage,20 +13433,Crayfish,5 +13434,Crayfish,5 +13435,Raw crayfish,5 +13436,Raw crayfish,5 +13437,Burnt crayfish,1 +13438,Burnt crayfish,1 +13439,Antique lamp,1 +13440,Bag of runes,1 +13441,null,1 +13442,Amulet of fury,0 +13443,Obsidian cape,0 +13444,Abyssal whip,0 +13445,Granite maul,0 +13446,Antique lamp,1 +13447,Antique lamp,1 +13448,Antique lamp,1 +13449,Dragon full helm,0 +13450,Armadyl godsword,0 +13451,Bandos godsword,0 +13452,Saradomin godsword,0 +13453,Zamorak godsword,0 +13454,Zamorakian spear,0 +13455,Armadyl helmet,0 +13456,Armadyl chestplate,0 +13457,Armadyl plateskirt,0 +13458,Bandos chestplate,0 +13459,Bandos tassets,0 +13460,Bandos boots,0 +13461,Saradomin sword,0 +13462,Dragon boots,0 +13463,Antique lamp,1 +13464,Task list,1 +13465,Dragon dagger,0 +13466,Dragon dagger(p),0 +13467,Dragon dagger(p+),0 +13468,Dragon dagger(p++),0 +13469,Rune axe,0 +13470,Dragon axe,0 +13471,Rune battleaxe,0 +13472,Dragon battleaxe,0 +13473,Rune warhammer,0 +13474,Rune longsword,0 +13475,Dragon longsword,0 +13476,Rune scimitar,0 +13477,Dragon scimitar,0 +13478,Dragon halberd,0 +13479,Dragon mace,0 +13480,Rune pickaxe,0 +13481,Dragon chainbody,0 +13482,Rune platebody,0 +13483,Green d'hide body,0 +13484,Blue d'hide body,0 +13485,Red d'hide body,0 +13486,Black d'hide body,0 +13487,Rune platelegs,0 +13488,Dragon platelegs,0 +13489,Rune plateskirt,0 +13490,Dragon plateskirt,0 +13491,Green d'hide chaps,0 +13492,Blue d'hide chaps,0 +13493,Red d'hide chaps,0 +13494,Black d'hide chaps,0 +13495,Dragon med helm,0 +13496,Rune full helm,0 +13497,Green d'hide vamb,0 +13498,Blue d'hide vamb,0 +13499,Red d'hide vamb,0 +13500,Black d'hide vamb,0 +13501,Splitbark helm,0 +13502,Splitbark body,0 +13503,Splitbark legs,0 +13504,Splitbark gauntlets,0 +13505,Splitbark boots,0 +13506,Dragon sq shield,0 +13507,Rune kiteshield,0 +13508,Mystic hat,0 +13509,Mystic robe top,0 +13510,Mystic robe bottom,0 +13511,Mystic gloves,0 +13512,Mystic boots,0 +13513,Mystic hat,0 +13514,Mystic robe top,0 +13515,Mystic robe bottom,0 +13516,Mystic gloves,0 +13517,Mystic boots,0 +13518,Mystic hat,0 +13519,Mystic robe top,0 +13520,Mystic robe bottom,0 +13521,Mystic gloves,0 +13522,Mystic boots,0 +13523,Maple longbow,0 +13524,Maple shortbow,0 +13525,Yew longbow,0 +13526,Yew shortbow,0 +13527,Magic longbow,0 +13528,Magic shortbow,0 +13529,Seercull,0 +13530,Rune crossbow,0 +13531,Red partyhat,0 +13532,Yellow partyhat,0 +13533,Blue partyhat,0 +13534,Green partyhat,0 +13535,Purple partyhat,0 +13536,White partyhat,0 +13537,Santa hat,0 +13538,Green h'ween mask,0 +13539,Blue h'ween mask,0 +13540,Red h'ween mask,0 +13541,Willow comp bow,0 +13542,Yew comp bow,0 +13543,Magic comp bow,0 +13544,3rd age range top,0 +13545,3rd age range legs,0 +13546,3rd age range coif,0 +13547,3rd age vambraces,0 +13548,3rd age robe top,0 +13549,3rd age robe,0 +13550,3rd age mage hat,0 +13551,3rd age amulet,0 +13552,3rd age platelegs,0 +13553,3rd age platebody,0 +13554,3rd age full helmet,0 +13555,3rd age kiteshield,0 +13556,Ranger boots,0 +13557,Wizard boots,0 +13558,Robin hood hat,0 +13559,null,1 +13560,Explorer's ring 1,350 +13561,Explorer's ring 2,350 +13562,Explorer's ring 3,350 +13563,Button mushroom,38 +13564,Button mushroom,38 +13565,Doll,1 +13566,Jennica's ring,1 +13567,Cursed magic logs,1 +13568,Cursed magic logs,1 +13569,Enchanted key notes,1 +13570,Bowl,1 +13571,Bucket of milk,1 +13572,Clean guam,1 +13573,Bowl of honey,1 +13574,Bowl of milk and honey,1 +13575,Bowl of milk, honey and guam,1 +13576,Map of runescape,1 +13577,Papyrus,1 +13578,Charcoal,1 +13579,Spade,1 +13580,Plant pot,1 +13581,Pear tree seedling,1 +13582,Mango tree seedling,1 +13583,Quince tree seedling,1 +13584,Lemon tree seedling,1 +13585,Avocado tree seedling,1 +13586,Plum tree seedling,1 +13587,Pestle and mortar,4 +13588,Ground guam,1 +13589,Bucket,2 +13590,null,1 +13591,Enchanted key,1 +13592,A brooch,1 +13593,Old tome,1 +13594,null,1 +13595,null,1 +13596,null,1 +13597,null,1 +13598,Runecrafting guild teleport,100 +13599,Air altar teleport,100 +13600,Mind altar teleport,100 +13601,Water altar teleport,100 +13602,Earth altar teleport,100 +13603,Fire altar teleport,100 +13604,Body altar teleport,100 +13605,Cosmic altar teleport,100 +13606,Chaos altar teleport,100 +13607,Nature altar teleport,100 +13608,Law altar teleport,100 +13609,Death altar teleport,100 +13610,Blood altar teleport,100 +13611,Astral altar teleport,100 +13612,Runecrafter hat,20 +13613,Runecrafter hat,20 +13614,Runecrafter robe,75 +13615,Runecrafter hat,75 +13616,Runecrafter hat,75 +13617,Runecrafter skirt,75 +13618,Runecrafter gloves,75 +13619,Runecrafter robe,75 +13620,Runecrafter hat,75 +13621,Runecrafter hat,75 +13622,Runecrafter skirt,75 +13623,Runecrafter gloves,75 +13624,Runecrafter robe,75 +13625,Runecrafter hat,75 +13626,Runecrafter hat,75 +13627,Runecrafter skirt,75 +13628,Runecrafter gloves,75 +13629,Runecrafting staff,15 +13630,Air talisman staff,1500 +13631,Mind talisman staff,1500 +13632,Water talisman staff,1500 +13633,Earth talisman staff,1500 +13634,Fire talisman staff,1500 +13635,Body talisman staff,1500 +13636,Cosmic talisman staff,1500 +13637,Chaos talisman staff,1500 +13638,Nature talisman staff,1500 +13639,Law talisman staff,1500 +13640,Death talisman staff,1500 +13641,Blood talisman staff,1500 +13642,Omni-talisman staff,1500 +13643,Yellow attractor,20 +13644,Yellow repeller,20 +13645,Green attractor,20 +13646,Green repeller,20 +13647,Green barrier generator,20 +13648,Yellow barrier generator,20 +13649,Omni-talisman,4 +13650,Runecrafting guild token,0 +13651,Runecrafting guild token,0 +13652,Runecrafting guild token,0 +13653,Runecrafting guild token,0 +13654,Runecrafting guild token,0 +13655,Omni-tiara,100 +13656,Runecrafter hat,75 +13657,Runecrafter hat,75 +13658,Runecrafter hat,75 +13659,Ring of fire,100 +13660,Flame gloves,200 +13661,Inferno adze,300 +13662,Fire beacon,1 +13663,Circus ticket,10 +13664,null,10 +13665,null,10 +13666,Giant's hand,10 +13667,Clown hat,10 +13668,Clown shirt,10 +13669,Clown leggings,10 +13670,Clown shoes,10 +13671,Tambourine,10 +13672,Ringmaster hat,10 +13673,Ringmaster shirt,10 +13674,Ringmaster pants,10 +13675,Ringmaster boots,10 +13676,Mega-phonus,10 +13677,Acrobat shirt,10 +13678,Acrobat pants,10 +13679,Acrobat shoes,10 +13680,Acrobat hood,10 +13681,Acrobat shirt,10 +13682,Acrobat pants,10 +13683,Acrobat shoes,10 +13684,Acrobat hood,10 +13685,A stylish hat,10 +13686,A stylish hat,10 +13687,A stylish hat,10 +13688,A stylish hat,10 +13689,A stylish hat,10 +13690,A stylish hat,10 +13691,Shirt,10 +13692,Shirt,10 +13693,Shirt,10 +13694,Shirt,10 +13695,Shirt,10 +13696,Shirt,10 +13697,Leggings,10 +13698,Leggings,10 +13699,Leggings,10 +13700,Skirt,10 +13701,Skirt,10 +13702,Skirt,10 +13703,Shoes,10 +13704,Shoes,10 +13705,Shoes,10 +13706,Shoes,10 +13707,Tightrope 101,1 +13708,Tightrope 101,1 +13709,Balls (level 10 approx.),1 +13710,Plates (level 20 approx.),1 +13711,Eggs (level 30 approx.),1 +13712,Knives (level 40 approx.),1 +13713,Spades (level 50 approx.),1 +13714,Tuna (level 60 approx.),1 +13715,Soap (level 70 approx.),1 +13716,Cannon balls (level 80 approx.),1 +13717,Torches (level 90 approx.),1 +13718,Chinchompas (level 99 approx.),1 +13719,Performance shortbow,50 +13720,Performance knife,14 +13721,Performance throwing axe,4 +13722,Performance arrow,7 +13723,Teleport spell,100 +13724,Levitation spell,100 +13725,Alchemy spell,100 +13726,Elemental spell,100 +13727,Stardust,50 +13728,null,1 +13729,null,1 +13730,null,1 +13731,null,1 +13732,Spy notebook,1 +13733,null,1 +13734,Spirit shield,70000 +13735,Spirit shield,70000 +13736,Blessed spirit shield,1400000 +13737,Blessed spirit shield,1400000 +13738,Arcane spirit shield,2000000 +13739,Arcane spirit shield,2000000 +13740,Divine spirit shield,2000000 +13741,Divine spirit shield,2000000 +13742,Elysian spirit shield,2000000 +13743,Elysian spirit shield,2000000 +13744,Spectral spirit shield,2000000 +13745,Spectral spirit shield,2000000 +13746,Arcane sigil,750000 +13747,Arcane sigil,750000 +13748,Divine sigil,750000 +13749,Divine sigil,750000 +13750,Elysian sigil,750000 +13751,Elysian sigil,750000 +13752,Spectral sigil,750000 +13753,Spectral sigil,750000 +13754,Holy elixir,750000 +13755,Holy elixir,750000 +13756,Cursed willow logs,40 +13757,Hartwin,1 +13758,Grubby key,0 +13759,Scrap of paper,1 +13760,Bottle,0 +13761,Bottle of mist,0 +13762,List of elders,0 +13763,Cavalier and mask,0 +13764,Rune claws,0 +13765,Rune dagger,0 +13766,Rune dagger(p),0 +13767,Rune dagger(p+),0 +13768,Rune dagger(p++),0 +13769,Rune spear,0 +13770,Dragon spear,0 +13771,Rune spear(p),0 +13772,Dragon spear(p),0 +13773,Rune spear(p+),0 +13774,Dragon spear(p+),0 +13775,Rune spear(p++),0 +13776,Dragon spear(p++),0 +13777,Rune sword,0 +13778,Rune 2h sword,0 +13779,Rune halberd,0 +13780,Rune mace,0 +13781,Rune chainbody,0 +13782,Rune boots,0 +13783,Rune med helm,0 +13784,Granite helm,0 +13785,Granite body,0 +13786,Granite legs,0 +13787,Rune sq shield,0 +13788,Granite shield,0 +13789,A powdered wig,0 +13790,Flared trousers,0 +13791,Pantaloons,0 +13792,Sleeping cap,0 +13793,Rune cane,0 +13794,Top hat,0 +13795,Sheep mask,0 +13796,Penguin mask,0 +13797,Bat mask,0 +13798,Cat mask,0 +13799,Wolf mask,0 +13800,Rune platebody (g),0 +13801,Rune platelegs (g),0 +13802,Rune plateskirt (g),0 +13803,Rune full helm(g),0 +13804,Rune kiteshield (g),0 +13805,Rune platebody (t),0 +13806,Rune platelegs (t),0 +13807,Rune plateskirt (t),0 +13808,Rune full helm (t),0 +13809,Rune kiteshield (t),0 +13810,Highwayman mask,0 +13811,Blue beret,0 +13812,Black beret,0 +13813,White beret,0 +13814,Tan cavalier,0 +13815,Dark cavalier,0 +13816,Black cavalier,0 +13817,Red headband,0 +13818,Black headband,0 +13819,Brown headband,0 +13820,Zamorak platebody,0 +13821,Zamorak platelegs,0 +13822,Zamorak plateskirt,0 +13823,Zamorak full helm,0 +13824,Zamorak kiteshield,0 +13825,Saradomin platebody,0 +13826,Saradomin platelegs,0 +13827,Saradomin plateskirt,0 +13828,Saradomin full helm,0 +13829,Saradomin kiteshield,0 +13830,Guthix platebody,0 +13831,Guthix platelegs,0 +13832,Guthix plateskirt,0 +13833,Guthix full helm,0 +13834,Guthix kiteshield,0 +13835,Gilded platebody,0 +13836,Gilded platelegs,0 +13837,Gilded plateskirt,0 +13838,Gilded full helm,0 +13839,Gilded kiteshield,0 +13840,null,1 +13841,null,1 +13842,null,1 +13843,null,1 +13844,null,1 +13845,Brawling gloves (melee),50000 +13846,Brawling gloves (ranged),50000 +13847,Brawling gloves (magic),50000 +13848,Brawling gloves (prayer),50000 +13849,Brawling gloves (agility),50000 +13850,Brawling gloves (wc),50000 +13851,Brawling gloves (fm),50000 +13852,Brawling gloves (mining),50000 +13853,Brawling gloves (hunter),50000 +13854,Brawling gloves (thieving),50000 +13855,Brawling gloves (smithing),50000 +13856,Brawling gloves (fishing),50000 +13857,Brawling gloves (cooking),50000 +13858,Zuriel's robe top,500000 +13859,Zuriel's robe top,500000 +13860,Zuriel's robe top (deg),300000 +13861,Zuriel's robe bottom,500000 +13862,Zuriel's robe bottom,500000 +13863,Zuriel's robe bottom (deg),300000 +13864,Zuriel's hood,250000 +13865,Zuriel's hood,250000 +13866,Zuriel's hood (deg),150000 +13867,Zuriel's staff,300000 +13868,Zuriel's staff,300000 +13869,Zuriel's staff (deg),180000 +13870,Morrigan's leather body,500000 +13871,Morrigan's leather body,500000 +13872,Morrigan's leather body (deg),300000 +13873,Morrigan's leather chaps,500000 +13874,Morrigan's leather chaps,500000 +13875,Morrigan's leather chaps (deg),300000 +13876,Morrigan's coif,250000 +13877,Morrigan's coif,250000 +13878,Morrigan's coif (deg),150000 +13879,Morrigan's javelin,4000 +13880,Morrigan's javelin(p),10000 +13881,Morrigan's javelin(p+),10000 +13882,Morrigan's javelin(p++),10000 +13883,Morrigan's throwing axe,4000 +13884,Statius's platebody,500000 +13885,Statius's platebody,500000 +13886,Statius's platebody (deg),300000 +13887,Vesta's chainbody,500000 +13888,Vesta's chainbody,500000 +13889,Vesta's chainbody (deg),300000 +13890,Statius's platelegs,500000 +13891,Statius's platelegs,500000 +13892,Statius's platelegs (deg),300000 +13893,Vesta's plateskirt,500000 +13894,Vesta's plateskirt,500000 +13895,Vesta's plateskirt (deg),300000 +13896,Statius's full helm,250000 +13897,Statius's full helm,250000 +13898,Statius' full helm (deg),150000 +13899,Vesta's longsword,300000 +13900,Vesta's longsword,300000 +13901,Vesta's longsword (deg),180000 +13902,Statius's warhammer,300000 +13903,Statius's warhammer,300000 +13904,Statius' warhammer (deg),180000 +13905,Vesta's spear,300000 +13906,Vesta's spear,300000 +13907,Vesta's spear (deg),180000 +13908,Corrupt statius's platebody,125000 +13909,Corrupt statius's platebody,125000 +13910,Corrupt statius's platebody (deg),75000 +13911,Corrupt vesta's chainbody,125000 +13912,Corrupt vesta's chainbody,125000 +13913,Corrupt vesta's chainbody (deg),75000 +13914,Corrupt statius's platelegs,125000 +13915,Corrupt statius's platelegs,125000 +13916,Corrupt statius's platelegs (deg),75000 +13917,Corrupt vesta's plateskirt,125000 +13918,Corrupt vesta's plateskirt,125000 +13919,Corrupt vesta's plateskirt (deg),75000 +13920,Corrupt statius's full helm,50000 +13921,Corrupt statius's full helm,50000 +13922,Corrupt statius' full helm (deg),30000 +13923,Corrupt vesta's longsword,125000 +13924,Corrupt vesta's longsword,125000 +13925,C. vesta's longsword (deg),75000 +13926,Corrupt statius's warhammer,125000 +13927,Corrupt statius's warhammer,125000 +13928,C. statius's warhammer (deg),75000 +13929,Corrupt vesta's spear,125000 +13930,Corrupt vesta's spear,125000 +13931,Corrupt vesta's spear (deg),75000 +13932,Corrupt zuriel's robe top,125000 +13933,Corrupt zuriel's robe top,125000 +13934,Corrupt zuriel's robe top (deg),75000 +13935,Corrupt zuriel's robe bottom,125000 +13936,Corrupt zuriel's robe bottom,125000 +13937,Corrupt zuriel's robe bottom (deg),75000 +13938,Corrupt zuriel's hood,50000 +13939,Corrupt zuriel's hood,50000 +13940,Corrupt zuriel's hood (deg),30000 +13941,Corrupt zuriel's staff,125000 +13942,Corrupt zuriel's staff,125000 +13943,Corrupt zuriel's staff (deg),70000 +13944,Corrupt morrigan's leather body,125000 +13945,Corrupt morrigan's leather body,125000 +13946,Corrupt morrigan's leather body (deg),75000 +13947,Corrupt morrigan's leather chaps,125000 +13948,Corrupt morrigan's leather chaps,125000 +13949,Corrupt morrigan's leather chaps (deg),75000 +13950,Corrupt morrigan's coif,50000 +13951,Corrupt morrigan's coif,50000 +13952,Corrupt morrigan's coif (deg),30000 +13953,Corrupt morrigan's javelin,1000 +13954,C. morrigan's javelin (p),10000 +13955,C. morrigan's javelin (p+),10000 +13956,C. morrigan's javelin (p++),10000 +13957,C. morrigan's throwing axe,1000 +13958,Corrupt dragon chainbody,120000 +13959,Corrupt dragon chainbody,120000 +13960,Corrupt dragon chainbody (deg),72000 +13961,Corrupt dragon med helm,60000 +13962,Corrupt dragon med helm,60000 +13963,Corrupt dragon med helm (deg),36000 +13964,Corrupt dragon sq shield,120000 +13965,Corrupt dragon sq shield,120000 +13966,Corrupt dragon sq shield (deg),72000 +13967,Corrupt dragon plateskirt,120000 +13968,Corrupt dragon plateskirt,120000 +13969,Corrupt dragon plateskirt (deg),72000 +13970,Corrupt dragon platelegs,120000 +13971,Corrupt dragon platelegs,120000 +13972,Corrupt dragon platelegs (deg),72000 +13973,Corrupt dragon battleaxe,120000 +13974,Corrupt dragon battleaxe,120000 +13975,C. dragon battleaxe (deg),72000 +13976,Corrupt dragon dagger,30000 +13977,Corrupt dragon dagger,30000 +13978,C. dragon dagger (deg),18000 +13979,Corrupt dragon scimitar,100000 +13980,Corrupt dragon scimitar,100000 +13981,C. dragon scimitar (deg),60000 +13982,Corrupt dragon longsword,100000 +13983,Corrupt dragon longsword,100000 +13984,C. dragon longsword (deg),60000 +13985,Corrupt dragon mace,50000 +13986,Corrupt dragon mace,50000 +13987,Corrupt dragon mace (deg),30000 +13988,Corrupt dragon spear,40000 +13989,Corrupt dragon spear,40000 +13990,Corrupt dragon spear (deg),24000 +13991,null,3 +13992,null,3 +13993,null,3 +13994,null,3 +13995,null,3 +13996,null,3 +13997,null,3 +13998,null,3 +13999,null,3 +14000,null,3 +14001,null,3 +14002,null,3 +14003,null,3 +14004,null,3 +14005,null,3 +14006,null,3 +14007,null,3 +14008,null,3 +14009,null,3 +14010,null,3 +14011,null,3 +14012,null,3 +14013,null,3 +14014,null,3 +14015,null,3 +14016,null,3 +14017,null,3 +14018,null,3 +14019,null,3 +14020,null,3 +14021,null,3 +14022,null,3 +14023,null,3 +14024,null,3 +14025,null,3 +14026,null,3 +14027,null,3 +14028,null,3 +14029,null,3 +14030,null,3 +14031,null,3 +14032,null,3 +14033,null,3 +14034,null,3 +14035,null,3 +14036,null,3 +14037,null,3 +14038,null,3 +14039,null,3 +14040,null,3 +14041,null,3 +14042,null,3 +14043,null,3 +14044,null,3 +14045,null,3 +14046,null,3 +14047,null,3 +14048,null,3 +14049,null,3 +14050,null,3 +14051,null,3 +14052,null,3 +14053,null,3 +14054,null,3 +14055,null,3 +14056,Pvp worlds manual,5 +14057,Broomstick,25 +14058,Goulash,2 +14059,null,4 +14060,null,4 +14061,Magic unguent,2 +14062,Broom ointment,2 +14063,null,1 +14064,Newt,5 +14065,Newt label,1 +14066,Toad label,1 +14067,Newts and toads label,1 +14068,Betty's wand,15 +14069,Magic slate,2 +14070,Reptile,1 +14071,Blackbird,1 +14072,Bat,1 +14073,Spider,1 +14074,Rat,1 +14075,Snail,1 +14076,Warlock top,15 +14077,Warlock legs,15 +14078,Witch top,15 +14079,Witch skirt,15 +14080,Witch cloak,15 +14081,Warlock cloak,15 +14082,Popcorn ball,1 +14083,Chocolate drop,1 +14084,Wrapped candy,1 +14085,Armadyl communiqu,1 +14086,Witch top,15 +14087,Witch skirt,15 +14088,Witch cloak,15 +14089,Pet kitten,1 +14090,Pet cat,1 +14091,Lazy cat,1 +14092,Overgrown cat,1 +14093,Wily cat,1 +14094,Sacred clay platebody,43333 +14095,Sacred clay platelegs,42667 +14096,Sacred clay helm,23467 +14097,Sacred clay scimitar,17066 +14098,Volatile clay tool,21333 +14099,Volatile clay pickaxe,21333 +14100,Volatile clay hatchet,21333 +14101,Volatile clay harpoon,21333 +14102,Volatile clay butterfly net,21333 +14103,Volatile clay fletching knife,21333 +14104,Volatile clay hammer,21333 +14105,Volatile clay needle,21333 +14106,Proto-tool,21333 +14107,Sacred clay pickaxe,21333 +14108,Sacred clay hatchet,21333 +14109,Sacred clay harpoon,21333 +14110,Sacred clay butterfly net,1 +14111,Sacred clay fletching knife,21333 +14112,Sacred clay hammer,21333 +14113,Sacred clay needle,21333 +14114,Sacred clay robe top,43333 +14115,Sacred clay robe bottom,42667 +14116,Sacred clay hat,23467 +14117,Sacred clay staff,17066 +14118,Sacred clay body,43333 +14119,Sacred clay chaps,42667 +14120,Sacred clay coif,23467 +14121,Sacred clay bow,17066 +14122,Pickaxe (class 1),30 +14123,Pickaxe (class 1),30 +14124,Pickaxe (class 2),60 +14125,Pickaxe (class 2),60 +14126,Pickaxe (class 3),90 +14127,Pickaxe (class 3),90 +14128,Pickaxe (class 4),120 +14129,Pickaxe (class 4),120 +14130,Pickaxe (class 5),150 +14131,Pickaxe (class 5),150 +14132,Hatchet (class 1),30 +14133,Hatchet (class 1),30 +14134,Hatchet (class 2),60 +14135,Hatchet (class 2),60 +14136,Hatchet (class 3),90 +14137,Hatchet (class 3),90 +14138,Hatchet (class 4),120 +14139,Hatchet (class 4),120 +14140,Hatchet (class 5),150 +14141,Hatchet (class 5),150 +14142,Harpoon (class 1),30 +14143,Harpoon (class 1),30 +14144,Harpoon (class 2),60 +14145,Harpoon (class 2),60 +14146,Harpoon (class 3),90 +14147,Harpoon (class 3),90 +14148,Harpoon (class 4),120 +14149,Harpoon (class 4),120 +14150,Harpoon (class 5),150 +14151,Harpoon (class 5),150 +14152,Butterfly net (class 1),30 +14153,Butterfly net (class 1),30 +14154,Butterfly net (class 2),60 +14155,Butterfly net (class 2),60 +14156,Butterfly net (class 3),90 +14157,Butterfly net (class 3),90 +14158,Butterfly net (class 4),120 +14159,Butterfly net (class 4),120 +14160,Butterfly net (class 5),150 +14161,Butterfly net (class 5),150 +14162,Food (class 1),30 +14163,Food (class 1),30 +14164,Food (class 2),60 +14165,Food (class 2),60 +14166,Food (class 3),90 +14167,Food (class 3),90 +14168,Food (class 4),120 +14169,Food (class 4),120 +14170,Food (class 5),150 +14171,Food (class 5),150 +14172,Barrier (class 1),30 +14173,Barrier (class 1),30 +14174,Barrier (class 2),60 +14175,Barrier (class 2),60 +14176,Barrier (class 3),90 +14177,Barrier (class 3),90 +14178,Barrier (class 4),120 +14179,Barrier (class 4),120 +14180,Barrier (class 5),150 +14181,Barrier (class 5),150 +14182,Sacred clay (class 1),15 +14183,Sacred clay (class 1),15 +14184,Sacred clay (class 2),30 +14185,Sacred clay (class 2),30 +14186,Sacred clay (class 3),45 +14187,Sacred clay (class 3),45 +14188,Sacred clay (class 4),60 +14189,Sacred clay (class 4),60 +14190,Sacred clay (class 5),75 +14191,Sacred clay (class 5),75 +14192,Bow (class 1),30 +14193,Bow (class 1),30 +14194,Bow (class 2),60 +14195,Bow (class 2),60 +14196,Bow (class 3),90 +14197,Bow (class 3),90 +14198,Bow (class 4),120 +14199,Bow (class 4),120 +14200,Bow (class 5),150 +14201,Bow (class 5),150 +14202,Arrows (class 1),2 +14203,Arrows (class 2),4 +14204,Arrows (class 3),6 +14205,Arrows (class 4),8 +14206,Arrows (class 5),10 +14207,Prayer potion(5),150 +14208,Prayer potion(5),150 +14209,Prayer potion(4),120 +14210,Prayer potion(4),120 +14211,Prayer potion(3),90 +14212,Prayer potion(3),90 +14213,Prayer potion(2),60 +14214,Prayer potion(2),60 +14215,Prayer potion(1),30 +14216,Prayer potion(1),30 +14217,Energy potion (5),150 +14218,Energy potion (5),150 +14219,Energy potion (4),120 +14220,Energy potion (4),120 +14221,Energy potion (3),90 +14222,Energy potion (3),90 +14223,Energy potion (2),60 +14224,Energy potion (2),60 +14225,Energy potion (1),30 +14226,Energy potion (1),30 +14227,Super attack(5),150 +14228,Super attack(5),150 +14229,Super attack(4),120 +14230,Super attack(4),120 +14231,Super attack(3),90 +14232,Super attack(3),90 +14233,Super attack(2),60 +14234,Super attack(2),60 +14235,Super attack(1),30 +14236,Super attack(1),30 +14237,Super strength(5),150 +14238,Super strength(5),150 +14239,Super strength(4),120 +14240,Super strength(4),120 +14241,Super strength(3),90 +14242,Super strength(3),90 +14243,Super strength(2),60 +14244,Super strength(2),60 +14245,Super strength(1),30 +14246,Super strength(1),30 +14247,Ranging potion(5),150 +14248,Ranging potion(5),150 +14249,Ranging potion(4),120 +14250,Ranging potion(4),120 +14251,Ranging potion(3),90 +14252,Ranging potion(3),90 +14253,Ranging potion(2),60 +14254,Ranging potion(2),60 +14255,Ranging potion(1),30 +14256,Ranging potion(1),30 +14257,Defence potion(5),150 +14258,Defence potion(5),150 +14259,Defence potion(4),120 +14260,Defence potion(4),120 +14261,Defence potion(3),90 +14262,Defence potion(3),90 +14263,Defence potion(2),60 +14264,Defence potion(2),60 +14265,Defence potion(1),30 +14266,Defence potion(1),30 +14267,Magic potion(5),150 +14268,Magic potion(5),150 +14269,Magic potion(4),120 +14270,Magic potion(4),120 +14271,Magic potion(3),90 +14272,Magic potion(3),90 +14273,Magic potion(2),60 +14274,Magic potion(2),60 +14275,Magic potion(1),30 +14276,Magic potion(1),30 +14277,Summoning potion(5),150 +14278,Summoning potion(5),150 +14279,Summoning potion(4),120 +14280,Summoning potion(4),120 +14281,Summoning potion(3),90 +14282,Summoning potion(3),90 +14283,Summoning potion(2),60 +14284,Summoning potion(2),60 +14285,Summoning potion(1),30 +14286,Summoning potion(1),30 +14287,Scimitar (class 1),30 +14288,Scimitar (class 1),30 +14289,Scimitar (class 2),60 +14290,Scimitar (class 2),60 +14291,Scimitar (class 3),90 +14292,Scimitar (class 3),90 +14293,Scimitar (class 4),120 +14294,Scimitar (class 4),120 +14295,Scimitar (class 5),150 +14296,Scimitar (class 5),150 +14297,Dagger (class 1),30 +14298,Dagger (class 1),30 +14299,Dagger (class 2),60 +14300,Dagger (class 2),60 +14301,Dagger (class 3),90 +14302,Dagger (class 3),90 +14303,Dagger (class 4),120 +14304,Dagger (class 4),120 +14305,Dagger (class 5),150 +14306,Dagger (class 5),150 +14307,Warhammer (class 1),30 +14308,Warhammer (class 1),30 +14309,Warhammer (class 2),60 +14310,Warhammer (class 2),60 +14311,Warhammer (class 3),90 +14312,Warhammer (class 3),90 +14313,Warhammer (class 4),120 +14314,Warhammer (class 4),120 +14315,Warhammer (class 5),150 +14316,Warhammer (class 5),150 +14317,Robe top (class 1),30 +14318,Robe top (class 1),30 +14319,Robe top (class 2),60 +14320,Robe top (class 2),60 +14321,Robe top (class 3),90 +14322,Robe top (class 3),90 +14323,Robe top (class 4),120 +14324,Robe top (class 4),120 +14325,Robe top (class 5),150 +14326,Robe top (class 5),150 +14327,Robe bottom (class 1),30 +14328,Robe bottom (class 1),30 +14329,Robe bottom (class 2),60 +14330,Robe bottom (class 2),60 +14331,Robe bottom (class 3),90 +14332,Robe bottom (class 3),90 +14333,Robe bottom (class 4),120 +14334,Robe bottom (class 4),120 +14335,Robe bottom (class 5),150 +14336,Robe bottom (class 5),150 +14337,Hat (class 1),30 +14338,Hat (class 1),30 +14339,Hat (class 2),60 +14340,Hat (class 2),60 +14341,Hat (class 3),90 +14342,Hat (class 3),90 +14343,Hat (class 4),120 +14344,Hat (class 4),120 +14345,Hat (class 5),150 +14346,Hat (class 5),150 +14347,Platebody (class 1),30 +14348,Platebody (class 1),30 +14349,Platebody (class 2),60 +14350,Platebody (class 2),60 +14351,Platebody (class 3),90 +14352,Platebody (class 3),90 +14353,Platebody (class 4),120 +14354,Platebody (class 4),120 +14355,Platebody (class 5),150 +14356,Platebody (class 5),150 +14357,Platelegs (class 1),30 +14358,Platelegs (class 1),30 +14359,Platelegs (class 2),60 +14360,Platelegs (class 2),60 +14361,Platelegs (class 3),90 +14362,Platelegs (class 3),90 +14363,Platelegs (class 4),120 +14364,Platelegs (class 4),120 +14365,Platelegs (class 5),150 +14366,Platelegs (class 5),150 +14367,Helm (class 1),30 +14368,Helm (class 1),30 +14369,Helm (class 2),60 +14370,Helm (class 2),60 +14371,Helm (class 3),90 +14372,Helm (class 3),90 +14373,Helm (class 4),120 +14374,Helm (class 4),120 +14375,Helm (class 5),150 +14376,Helm (class 5),150 +14377,Staff (class 1),30 +14378,Staff (class 1),30 +14379,Staff (class 2),60 +14380,Staff (class 2),60 +14381,Staff (class 3),90 +14382,Staff (class 3),90 +14383,Staff (class 4),120 +14384,Staff (class 4),120 +14385,Staff (class 5),150 +14386,Staff (class 5),150 +14387,Cape,1 +14388,null,1 +14389,Cape,1 +14390,null,1 +14391,Leather body (class 1),30 +14392,Leather body (class 1),30 +14393,Leather body (class 2),60 +14394,Leather body (class 2),60 +14395,Leather body (class 3),90 +14396,Leather body (class 3),90 +14397,Leather body (class 4),120 +14398,Leather body (class 4),120 +14399,Leather body (class 5),150 +14400,Leather body (class 5),150 +14401,Chaps (class 1),30 +14402,Chaps (class 1),30 +14403,Chaps (class 2),60 +14404,Chaps (class 2),60 +14405,Chaps (class 3),90 +14406,Chaps (class 3),90 +14407,Chaps (class 4),120 +14408,Chaps (class 4),120 +14409,Chaps (class 5),150 +14410,Chaps (class 5),150 +14411,Coif (class 1),30 +14412,Coif (class 1),30 +14413,Coif (class 2),60 +14414,Coif (class 2),60 +14415,Coif (class 3),90 +14416,Coif (class 3),90 +14417,Coif (class 4),120 +14418,Coif (class 4),120 +14419,Coif (class 5),150 +14420,Coif (class 5),150 +14421,Clay deposit scroll,30 +14422,Sacred clay pouch (class 1),30 +14423,Sacred clay pouch (class 1),30 +14424,Sacred clay pouch (class 2),60 +14425,Sacred clay pouch (class 2),60 +14426,Sacred clay pouch (class 3),90 +14427,Sacred clay pouch (class 3),90 +14428,Sacred clay pouch (class 4),120 +14429,Sacred clay pouch (class 4),120 +14430,Sacred clay pouch (class 5),150 +14431,Sacred clay pouch (class 5),150 +14432,Null sacred clay,1 +14433,null,1 +14434,null,1 +14435,null,1 +14436,null,1 +14437,null,1 +14438,null,1 +14439,null,1 +14440,null,1 +14441,null,1 +14442,null,1 +14443,null,1 +14444,null,1 +14445,null,1 +14446,null,1 +14447,null,1 +14448,null,1 +14449,null,1 +14450,null,1 +14451,null,1 +14452,null,1 +14453,null,1 +14454,null,1 +14455,null,1 +14456,null,1 +14457,null,1 +14458,Vine flower,5 +14459,Unconscious broav,0 +14460,Dirty laundry,10 +14461,Waste-paper basket,1 +14462,Ruby key,1 +14463,Notes on pressure,1 +14464,Movario's notes (volume 1),0 +14465,Movario's notes (volume 2),1 +14466,Weight (1kg),1 +14467,Weight (2kg),1 +14468,Weight (5kg),1 +14469,Strange key loop,1 +14470,Strange key teeth,1 +14471,Dragonkin key,1 +14472,Ruined dragon armour lump,30000 +14473,Ruined dragon armour lump,30000 +14474,Ruined dragon armour slice,30000 +14475,Ruined dragon armour slice,30000 +14476,Ruined dragon armour shard,30000 +14477,Ruined dragon armour shard,30000 +14478,Blast fusion hammer,1 +14479,Dragon platebody,1760000 +14480,Dragon platebody,1760000 +14481,Dragon platebody,0 +14482,null,1 +14483,null,1 +14484,Dragon claws,135000 +14485,Dragon claws,135000 +14486,Dragon claws,0 +14487,Enriched snapdragon,1 +14488,Super truth serum,1 +14489,Suspect sketch,1 +14490,Elite black platelegs,65000 +14491,Elite black platelegs,65000 +14492,Elite black platebody,64000 +14493,Elite black platebody,64000 +14494,Elite black full helm,35200 +14495,Elite black full helm,35200 +14496,Cell key,1 +14497,Dagon'hai robe top,120000 +14498,Dagon'hai robe top,120000 +14499,Dagon'hai hat,15000 +14500,Dagon'hai hat,15000 +14501,Dagon'hai robe bottom,80000 +14502,Dagon'hai robe bottom,80000 +14503,Silif,1 +14504,Silif,1 +14505,Teleorb,1 +14506,Enriched snapdragon seed,1 +14507,Dolmen,1 +14508,Dolmen,1 +14509,Dolmen,1 +14510,Dolmen,1 +14511,Dolmen,1 +14512,Dolmen,1 +14513,Dolmen,1 +14514,Dolmen,1 +14515,Air key,1 +14516,Earth key,1 +14517,Fire key,1 +14518,Water key,1 +14519,Air key,1 +14520,Earth key,1 +14521,Fire key,1 +14522,Water key,1 +14523,null,1 +14524,null,1 +14525,Dagon'hai robes set,20 +14526,Dagon'hai robes set,20 +14527,Elite black armour set,20 +14528,Elite black armour set,20 +14529,Dragon plate armour set (l),20 +14530,Dragon plate armour set (l),20 +14531,Dragon plate armour set (sk),20 +14532,Dragon plate armour set (sk),20 +14533,Broav,0 +14534,Strange teleorb,1 +14535,null,1 +14536,Turkey book,1 +14537,Cornucopia,1 +14538,Cornucopia,1 +14539,Raw turkey,9 +14540,Cooked turkey,4 +14541,Burnt turkey,1 +14542,Raw turkey drumstick,9 +14543,Cooked turkey drumstick,4 +14544,Burnt turkey drumstick,1 +14545,null,1 +14546,null,1 +14547,null,1 +14548,null,1 +14549,null,1 +14550,null,1 +14551,null,1 +14552,null,1 +14553,null,1 +14554,null,1 +14555,null,1 +14556,null,1 +14557,null,1 +14558,null,1 +14559,null,1 +14560,null,1 +14561,null,1 +14562,null,1 +14563,null,1 +14564,null,1 +14565,null,1 +14566,null,1 +14567,null,1 +14568,null,1 +14569,null,1 +14570,Cornucopia,1 +14571,Fremennik sea boots 1,1 +14572,Fremennik sea boots 2,1 +14573,Fremennik sea boots 3,1 +14574,Antique lamp,1 +14575,Antique lamp,1 +14576,Antique lamp,1 +14577,Falador shield 1,100 +14578,Falador shield 2,200 +14579,Falador shield 3,300 +14580,Antique lamp,1000 +14581,Antique lamp,5000 +14582,Antique lamp,10000 +14583,White lily,1 +14584,Money crest voucher,500000 +14585,null,1 +14586,null,1 +14587,null,1 +14588,null,1 +14589,White lily seed,1250 +14590,Enchanted lyre(5),1000 +14591,Enchanted lyre(6),1000 +14592,Elite black platelegs,0 +14593,Elite black platebody,0 +14594,Elite black full helm,0 +14595,Santa costume top,1 +14596,Ice amulet,1 +14597,Stones,1 +14598,Enchanted stones,1 +14599,Ice amulet,1 +14600,Santa costume top,1 +14601,Santa costume top,1 +14602,Santa costume gloves,1 +14603,Santa costume legs,1 +14604,Santa costume legs,1 +14605,Santa costume boots,1 +14606,Cinnamon twigs,0 +14607,Sassafras twigs,0 +14608,Ailanthus twigs,0 +14609,Cedar twigs,0 +14610,Mastic twigs,0 +14611,Cinnamon weaving ribbon,0 +14612,Sassafras weaving ribbon,0 +14613,Ailanthus weaving ribbon,0 +14614,Cedar weaving ribbon,0 +14615,Mastic weaving ribbon,0 +14616,Phoenix quill,100 +14617,Phoenix quill,100 +14618,null,1 +14619,null,1 +14620,Pouch,1 +14621,Pouch,1 +14622,Rise from the ashes scroll,498 +14623,Phoenix pouch,4986 +14624,Phoenix pouch,4986 +14625,Pouch,1 +14626,Phoenix eggling,0 +14627,Phoenix eggling,0 +14628,null,1 +14629,Phoenix egg,0 +14630,Cracked phoenix egg,0 +14631,Seer's headband,1 +14632,Enhanced excalibur,200 +14633,Antique lamp,1 +14634,Antique lamp,1 +14635,Antique lamp,1 +14636,Slayer helmet (e),650 +14637,Slayer helmet (charged),650 +14638,Ring of wealth,17625 +14639,Ring of wealth,17625 +14640,Ring of wealth(1),17625 +14641,Ring of wealth(1),17625 +14642,Ring of wealth(2),17625 +14643,Ring of wealth(2),17625 +14644,Ring of wealth(3),17625 +14645,Ring of wealth(3),17625 +14646,Ring of wealth(4),17625 +14647,Ring of wealth(4),17625 +14648,Jangles the Monkey Backpack,1 +14649,Zanik ring,1 +14650,Wizard hat,1 +14651,Ancient blueprint,1 +14652,Ring of the Star Sprite,1 +14653,Ordinary chair,1 +14654,Staff of the raven,1500 +14655,Staff of the raven,1500 +14656,Staff of the raven,1500 diff --git a/Server/src/test/resources/cache b/Server/src/test/resources/cache new file mode 120000 index 0000000..7af9092 --- /dev/null +++ b/Server/src/test/resources/cache @@ -0,0 +1 @@ +../../../data/cache \ No newline at end of file diff --git a/Server/src/test/resources/test.conf b/Server/src/test/resources/test.conf new file mode 100644 index 0000000..fd86979 --- /dev/null +++ b/Server/src/test/resources/test.conf @@ -0,0 +1,84 @@ +[server] +#Secret key - this is sent by the client during login. +#Client/Server MUST match or connection is refused. +secret_key = "2009scape_development" +write_logs = true +msip = "127.0.0.1" +noauth_default_admin = true #NOTE: If we are not using auth, this determines whether or not players are admins by default. + +[database] +database_name = "global" +database_username = "2009scapetest" +database_password = "2009scapetest" +database_address = "127.0.0.1" +database_port = "3306" + + +[world] +name = "2009Scape" +debug = true +dev = true +start_gui = false +daily_restart = true +#world number +world_id = "1" +country_id = "0" +members = true +#activity as displayed on the world list +activity = "2009Scape Classic." +pvp = false +default_xp_rate = 5.0 +allow_slayer_reroll = false +#enables a default clan for players to join automatically. Should be an account with the same name as @name, with a clan set up already. +enable_default_clan = true +enable_bots = true +#message of the week model ID, 0 for random +motw_identifier = "0" +#text shown for message of the week - @name will be replaced with the name property set above. +motw_text = "Welcome to @name!" +#the coordinates new players spawn at +new_player_location = "2524,5002,0" +#the location of home teleport +home_location = "3222,3218,0" +autostock_ge = false +allow_token_purchase = false +skillcape_perks = false +increased_door_time = false +enable_botting = false +max_adv_bots = 100 +enable_doubling_money_scammers = true +wild_pvp_enabled = false +jad_practice_enabled = false +enable_castle_wars = false +personalized_shops = false + +[paths] +#path to the data folder, which contains the cache subfolder and such +data_path = "data" +#in the lines below, @data will be replaced with the value set for data_path +cache_path = "@data/cache" +store_path = "@data/serverstore" +save_path = "@data/players" +configs_path = "@data/configs" +#this is where economy/grand exchange data gets saved +grand_exchange_data_path = "@data/eco" +#path to file defining the rare drop table +rare_drop_table_path = "@data/configs/shared_tables/RDT.xml" +#path to file defining c.ele minor drop table +cele_drop_table_path = "@data/configs/shared_tables/CELEDT.xml" +#path to file defining the uncommon seed drop table +uncommon_seed_drop_table_path = "@data/configs/shared_tables/USDT.xml" +#path to file defining the herb drop table +herb_drop_table_path = "@data/configs/shared_tables/HDT.xml" +#path to file defining the gem drop table +gem_drop_table_path = "@data/configs/shared_tables/GDT.xml" +#path to file defining the rare seed drop table +rare_seed_drop_table_path = "@data/configs/shared_tables/RSDT.xml" +#path to file defining the allotment seed drop table +allotment_seed_drop_table_path = "@data/configs/shared_tables/ASDT.xml" +#path to file containing boot-time object changes +object_parser_path = "@data/ObjectParser.xml" +#path logs are written to +logs_path = "@data/logs" +bot_data = "@data/botdata" +eco_data = "@data/eco" diff --git a/Server/tableformat.css b/Server/tableformat.css new file mode 100644 index 0000000..101bdb4 --- /dev/null +++ b/Server/tableformat.css @@ -0,0 +1,16 @@ +td { + border-right: 1px solid black; + border-bottom: 1px solid black; +} + +tr { + border-bottom: 1px solid black; +} + +th { + border:1px solid black; +} + +#id { + color: #FF0004; +} \ No newline at end of file diff --git a/Server/worldprops/default.conf b/Server/worldprops/default.conf new file mode 100644 index 0000000..6024160 --- /dev/null +++ b/Server/worldprops/default.conf @@ -0,0 +1,141 @@ +[server] +#Log Level - the level of verbosity used for logs. +#"verbose" - ALL logs are shown +#"detailed" - FINE logs are hidden, which is generally bulk/debug info. +#"cautious" - FINE, INFO logs are hidden, meaning this level only shows warnings and errors. +#"silent" - FINE, INFO, WARN logs are hidden, meaning this level only shows errors. +log_level = "verbose" +#Secret key - this is sent by the client during login. +#Client/Server MUST match or connection is refused. +secret_key = "2009scape_development" +write_logs = true +msip = "127.0.0.1" +#preload the map (Increases memory usage by 2GB but makes game ticks smoother) +preload_map = false +#--------Note: If both of the below are false, no database is required to run the server.-------------- +#true = login requires password to be correct, passwords are hashed before stored. false = login does not care about the correctness of a password. +use_auth = false #NOTE: THIS MUST BE SET TO TRUE IN PRODUCTION! +#true - account data (credits, playtime, etc) is persisted, false - account data is purely temporary +#NOTE: this does not affect actual save data, like stats, inventory, etc. +persist_accounts = false #NOTE: THIS MUST BE SET TO TRUE IN PRODUCTION! +noauth_default_admin = true #NOTE: If we are not using auth, this determines whether or not players are admins by default. +#------------------------------------------------------------------------------------------------------ +#The limit on how many different accounts a player can log into per day. +daily_accounts_per_ip = 3 +watchdog_enabled = true +connectivity_check_url = "https://google.com,https://2009scape.org" +connectivity_timeout = 500 + +[database] +database_name = "global" +database_username = "root" +database_password = "" +database_address = "127.0.0.1" +database_port = "3306" + +[integrations] +grafana_logging = false +grafana_log_path = "@data/logs" +#how long grafana will keep old data for in days (anything older is pruned once on startup) +grafana_log_ttl_days = 7 +#discord_ge_webhook = "webhook link" +#discord_moderation_webhook = "webhook link" +#openrsc_integration_webhook = "webhook link" + + +[world] +name = "2009Scape" +#name used for announcements of bots selling items on the GE +name_ge = "2009Scape" +debug = true +dev = true +start_gui = false +daily_restart = false +#world number +world_id = "1" +country_id = "0" +members = true +#activity as displayed on the world list +activity = "2009Scape Classic." +pvp = false +default_xp_rate = 5.0 +allow_slayer_reroll = false +#enables a default clan for players to join automatically. Should be an account with the same name as @name, with a clan set up already. +enable_default_clan = true +enable_bots = true +#message of the week model ID, 0 for random +motw_identifier = "0" +#text shown for message of the week - @name will be replaced with the name property set above. +motw_text = "Welcome to @name!" +#the coordinates new players spawn at +new_player_location = "2524,5002,0" +#the location of home teleport +home_location = "3222,3218,0" +autostock_ge = false +allow_token_purchase = true +skillcape_perks = true +increased_door_time = false +enable_botting = false +max_adv_bots = 100 +enable_doubling_money_scammers = true +wild_pvp_enabled = true +jad_practice_enabled = true +#minimum HA value for announcements of bots selling on ge +ge_announcement_limit = 500 +enable_castle_wars = false +personalized_shops = true +bots_influence_ge_price = true +#verbose cutscene logging (for cutscenes in the new system) +verbose_cutscene = false +#show the rules the first time a player logs in +show_rules = true +#the number of revenants active at a time +revenant_population = 30 +#enable auto-buy/auto-sell on the GE. +i_want_to_cheat = false +#better agility pyramid gp reward (gp reward = 1000 + ((agility level / 99) * 9000)) +better_agility_pyramid_gp = true +#better dragonfire shield attack (30 second cooldown instead of 2 minutes) +better_dfs = true +#new player announcement +new_player_announcement = true +#enables holiday random events (no effect on normal random events) +holiday_event_randoms = true +#force holiday randoms (can only force one at a time) +force_halloween_randoms = false +force_christmas_randoms = false +#runecrafting formula revision (573 introduced probabilistic multiple runes, 581 extrapolated probabilistic runes past 99) +runecrafting_formula_revision = 581 +#enable the enhanced deep wilderness, where the area past the members' fence applies a red skull that boosts brawler/pvp drop rates +enhanced_deep_wilderness = true + +[paths] +#path to the data folder, which contains the cache subfolder and such +data_path = "data" +#in the lines below, @data will be replaced with the value set for data_path +cache_path = "@data/cache" +store_path = "@data/serverstore" +save_path = "@data/players" +configs_path = "@data/configs" +#this is where economy/grand exchange data gets saved +grand_exchange_data_path = "@data/eco" +#path to file defining the rare drop table +rare_drop_table_path = "@data/configs/shared_tables/RDT.xml" +#path to file defining c.ele minor drop table +cele_drop_table_path = "@data/configs/shared_tables/CELEDT.xml" +#path to file defining the uncommon seed drop table +uncommon_seed_drop_table_path = "@data/configs/shared_tables/USDT.xml" +#path to file defining the herb drop table +herb_drop_table_path = "@data/configs/shared_tables/HDT.xml" +#path to file defining the gem drop table +gem_drop_table_path = "@data/configs/shared_tables/GDT.xml" +#path to file defining the rare seed drop table +rare_seed_drop_table_path = "@data/configs/shared_tables/RSDT.xml" +#path to file defining the allotment seed drop table +allotment_seed_drop_table_path = "@data/configs/shared_tables/ASDT.xml" +#path to file containing boot-time object changes +object_parser_path = "@data/ObjectParser.xml" +#path logs are written to +logs_path = "@data/logs" +bot_data = "@data/botdata" +eco_data = "@data/eco" diff --git a/Tools/Drop Table Tool.html b/Tools/Drop Table Tool.html new file mode 100644 index 0000000..5de3bbe --- /dev/null +++ b/Tools/Drop Table Tool.html @@ -0,0 +1,334 @@ + + + 💀 Drop Table Tool + + + + + + + +
+
+
+

Import Files

+ +
+
+ +
+ +
+ +
+
+ +
+
+
+ drop_tables.json + YES + NO +
+
+ +
+
+ item_configs.json + YES + NO +
+
+ +
+
+ npc_configs.json + YES + NO +
+
+
+
+
+ +
+
+
+
+
+

Functions

+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+

NPCs

+ +
+
+
+
+

Items

+ +
+
+
+
+ +
+
+

Results    + View JSON +

+
{{ results }}
+
+

Table Description: {{ results.description }}

+
+ +

NPCs using this droptable: +

+

+
+
+
+ + +
+
+ + + + + + + \ No newline at end of file diff --git a/Tools/Frostys Cache Editor/.classpath b/Tools/Frostys Cache Editor/.classpath new file mode 100644 index 0000000..fb50116 --- /dev/null +++ b/Tools/Frostys Cache Editor/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/Tools/Frostys Cache Editor/.project b/Tools/Frostys Cache Editor/.project new file mode 100644 index 0000000..a3e96d5 --- /dev/null +++ b/Tools/Frostys Cache Editor/.project @@ -0,0 +1,17 @@ + + + Frosty + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/Tools/Frostys Cache Editor/Run - genväg.lnk b/Tools/Frostys Cache Editor/Run - genväg.lnk new file mode 100644 index 0000000..18f58e0 Binary files /dev/null and b/Tools/Frostys Cache Editor/Run - genväg.lnk differ diff --git a/Tools/Frostys Cache Editor/Run.bat b/Tools/Frostys Cache Editor/Run.bat new file mode 100644 index 0000000..edb330c --- /dev/null +++ b/Tools/Frostys Cache Editor/Run.bat @@ -0,0 +1,4 @@ +@echo off +title Cache editor +java -client -Xmx512m -cp bin;lib/* com.editor.Main +pause \ No newline at end of file diff --git a/Tools/Frostys Cache Editor/bin/com/alex/io/InputStream.class b/Tools/Frostys Cache Editor/bin/com/alex/io/InputStream.class new file mode 100644 index 0000000..5c9e2ca Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/io/InputStream.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/io/OutputStream.class b/Tools/Frostys Cache Editor/bin/com/alex/io/OutputStream.class new file mode 100644 index 0000000..dd2cbdd Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/io/OutputStream.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/io/Stream.class b/Tools/Frostys Cache Editor/bin/com/alex/io/Stream.class new file mode 100644 index 0000000..0b96207 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/io/Stream.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/loaders/animations/AnimationDefinitions.class b/Tools/Frostys Cache Editor/bin/com/alex/loaders/animations/AnimationDefinitions.class new file mode 100644 index 0000000..116e6c8 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/loaders/animations/AnimationDefinitions.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/loaders/clientscripts/ClientScript.class b/Tools/Frostys Cache Editor/bin/com/alex/loaders/clientscripts/ClientScript.class new file mode 100644 index 0000000..61e2161 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/loaders/clientscripts/ClientScript.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/loaders/images/IndexedColorImageFile.class b/Tools/Frostys Cache Editor/bin/com/alex/loaders/images/IndexedColorImageFile.class new file mode 100644 index 0000000..cdd0394 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/loaders/images/IndexedColorImageFile.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/loaders/images/LoaderImageArchive.class b/Tools/Frostys Cache Editor/bin/com/alex/loaders/images/LoaderImageArchive.class new file mode 100644 index 0000000..635041f Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/loaders/images/LoaderImageArchive.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/loaders/interfaces/IComponent.class b/Tools/Frostys Cache Editor/bin/com/alex/loaders/interfaces/IComponent.class new file mode 100644 index 0000000..4ac45d1 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/loaders/interfaces/IComponent.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/loaders/interfaces/IComponentSettings.class b/Tools/Frostys Cache Editor/bin/com/alex/loaders/interfaces/IComponentSettings.class new file mode 100644 index 0000000..51794cb Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/loaders/interfaces/IComponentSettings.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/loaders/interfaces/Interface.class b/Tools/Frostys Cache Editor/bin/com/alex/loaders/interfaces/Interface.class new file mode 100644 index 0000000..2633638 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/loaders/interfaces/Interface.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/loaders/interfaces/InterfaceName.class b/Tools/Frostys Cache Editor/bin/com/alex/loaders/interfaces/InterfaceName.class new file mode 100644 index 0000000..eb42da3 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/loaders/interfaces/InterfaceName.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/loaders/items/ItemDefinitions.class b/Tools/Frostys Cache Editor/bin/com/alex/loaders/items/ItemDefinitions.class new file mode 100644 index 0000000..4ec1eb7 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/loaders/items/ItemDefinitions.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/loaders/npcs/NPCDefinitions.class b/Tools/Frostys Cache Editor/bin/com/alex/loaders/npcs/NPCDefinitions.class new file mode 100644 index 0000000..89ac4c4 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/loaders/npcs/NPCDefinitions.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/loaders/objects/ObjectDefinitions.class b/Tools/Frostys Cache Editor/bin/com/alex/loaders/objects/ObjectDefinitions.class new file mode 100644 index 0000000..057639d Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/loaders/objects/ObjectDefinitions.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/store/Archive.class b/Tools/Frostys Cache Editor/bin/com/alex/store/Archive.class new file mode 100644 index 0000000..07befe6 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/store/Archive.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/store/ArchiveReference.class b/Tools/Frostys Cache Editor/bin/com/alex/store/ArchiveReference.class new file mode 100644 index 0000000..de19e76 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/store/ArchiveReference.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/store/FileReference.class b/Tools/Frostys Cache Editor/bin/com/alex/store/FileReference.class new file mode 100644 index 0000000..7d410df Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/store/FileReference.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/store/Index.class b/Tools/Frostys Cache Editor/bin/com/alex/store/Index.class new file mode 100644 index 0000000..6498408 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/store/Index.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/store/MainFile.class b/Tools/Frostys Cache Editor/bin/com/alex/store/MainFile.class new file mode 100644 index 0000000..80ec48a Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/store/MainFile.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/store/ReferenceTable.class b/Tools/Frostys Cache Editor/bin/com/alex/store/ReferenceTable.class new file mode 100644 index 0000000..34679f4 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/store/ReferenceTable.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/store/Store.class b/Tools/Frostys Cache Editor/bin/com/alex/store/Store.class new file mode 100644 index 0000000..5227f54 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/store/Store.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/tools/clientCacheUpdater/ArchiveValidation.class b/Tools/Frostys Cache Editor/bin/com/alex/tools/clientCacheUpdater/ArchiveValidation.class new file mode 100644 index 0000000..04cd212 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/tools/clientCacheUpdater/ArchiveValidation.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/tools/clientCacheUpdater/CacheEditor.class b/Tools/Frostys Cache Editor/bin/com/alex/tools/clientCacheUpdater/CacheEditor.class new file mode 100644 index 0000000..bfc3117 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/tools/clientCacheUpdater/CacheEditor.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/tools/clientCacheUpdater/CacheEditormodels.class b/Tools/Frostys Cache Editor/bin/com/alex/tools/clientCacheUpdater/CacheEditormodels.class new file mode 100644 index 0000000..3c0e96a Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/tools/clientCacheUpdater/CacheEditormodels.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/tools/clientCacheUpdater/CheckMap.class b/Tools/Frostys Cache Editor/bin/com/alex/tools/clientCacheUpdater/CheckMap.class new file mode 100644 index 0000000..01d87d1 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/tools/clientCacheUpdater/CheckMap.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/tools/clientCacheUpdater/CopyCache.class b/Tools/Frostys Cache Editor/bin/com/alex/tools/clientCacheUpdater/CopyCache.class new file mode 100644 index 0000000..fdd1cbf Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/tools/clientCacheUpdater/CopyCache.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/tools/clientCacheUpdater/OriginalXteas.class b/Tools/Frostys Cache Editor/bin/com/alex/tools/clientCacheUpdater/OriginalXteas.class new file mode 100644 index 0000000..6d065f3 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/tools/clientCacheUpdater/OriginalXteas.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/tools/clientCacheUpdater/ProtectCache.class b/Tools/Frostys Cache Editor/bin/com/alex/tools/clientCacheUpdater/ProtectCache.class new file mode 100644 index 0000000..c8e34e0 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/tools/clientCacheUpdater/ProtectCache.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/tools/clientCacheUpdater/RSXteas.class b/Tools/Frostys Cache Editor/bin/com/alex/tools/clientCacheUpdater/RSXteas.class new file mode 100644 index 0000000..714a075 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/tools/clientCacheUpdater/RSXteas.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/tools/clientCacheUpdater/SpritesDumper.class b/Tools/Frostys Cache Editor/bin/com/alex/tools/clientCacheUpdater/SpritesDumper.class new file mode 100644 index 0000000..9012170 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/tools/clientCacheUpdater/SpritesDumper.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/tools/clientCacheUpdater/UpdateCache.class b/Tools/Frostys Cache Editor/bin/com/alex/tools/clientCacheUpdater/UpdateCache.class new file mode 100644 index 0000000..ca2e442 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/tools/clientCacheUpdater/UpdateCache.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/Application$1.class b/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/Application$1.class new file mode 100644 index 0000000..b46768d Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/Application$1.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/Application$2.class b/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/Application$2.class new file mode 100644 index 0000000..c051b47 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/Application$2.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/Application$3.class b/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/Application$3.class new file mode 100644 index 0000000..a116b7f Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/Application$3.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/Application$4.class b/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/Application$4.class new file mode 100644 index 0000000..ebf9d4b Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/Application$4.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/Application$5.class b/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/Application$5.class new file mode 100644 index 0000000..ab05db9 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/Application$5.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/Application$6.class b/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/Application$6.class new file mode 100644 index 0000000..63033e8 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/Application$6.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/Application$7.class b/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/Application$7.class new file mode 100644 index 0000000..3dcf21c Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/Application$7.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/Application$8.class b/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/Application$8.class new file mode 100644 index 0000000..5ccd6f6 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/Application$8.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/Application$9.class b/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/Application$9.class new file mode 100644 index 0000000..d189205 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/Application$9.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/Application.class b/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/Application.class new file mode 100644 index 0000000..6f769de Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/Application.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/GeneratedUkeys$1.class b/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/GeneratedUkeys$1.class new file mode 100644 index 0000000..d458a3b Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/GeneratedUkeys$1.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/GeneratedUkeys$2.class b/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/GeneratedUkeys$2.class new file mode 100644 index 0000000..adfb968 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/GeneratedUkeys$2.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/GeneratedUkeys.class b/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/GeneratedUkeys.class new file mode 100644 index 0000000..f70c155 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/GeneratedUkeys.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/ItemDefsEditor$1.class b/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/ItemDefsEditor$1.class new file mode 100644 index 0000000..71e46fa Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/ItemDefsEditor$1.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/ItemDefsEditor$2.class b/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/ItemDefsEditor$2.class new file mode 100644 index 0000000..6ba7029 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/ItemDefsEditor$2.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/ItemDefsEditor.class b/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/ItemDefsEditor.class new file mode 100644 index 0000000..194c293 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/tools/itemsDefsEditor/ItemDefsEditor.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/util/bzip2/BZip2BlockEntry.class b/Tools/Frostys Cache Editor/bin/com/alex/util/bzip2/BZip2BlockEntry.class new file mode 100644 index 0000000..aae3631 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/util/bzip2/BZip2BlockEntry.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/util/bzip2/BZip2Compressor.class b/Tools/Frostys Cache Editor/bin/com/alex/util/bzip2/BZip2Compressor.class new file mode 100644 index 0000000..1c63dbc Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/util/bzip2/BZip2Compressor.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/util/bzip2/BZip2Decompressor.class b/Tools/Frostys Cache Editor/bin/com/alex/util/bzip2/BZip2Decompressor.class new file mode 100644 index 0000000..715d547 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/util/bzip2/BZip2Decompressor.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/util/crc32/CRC32HGenerator.class b/Tools/Frostys Cache Editor/bin/com/alex/util/crc32/CRC32HGenerator.class new file mode 100644 index 0000000..1f0e808 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/util/crc32/CRC32HGenerator.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/util/gzip/GZipCompressor.class b/Tools/Frostys Cache Editor/bin/com/alex/util/gzip/GZipCompressor.class new file mode 100644 index 0000000..ae94a37 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/util/gzip/GZipCompressor.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/util/gzip/GZipDecompressor.class b/Tools/Frostys Cache Editor/bin/com/alex/util/gzip/GZipDecompressor.class new file mode 100644 index 0000000..cb85dcb Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/util/gzip/GZipDecompressor.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/util/whirlpool/Whirlpool.class b/Tools/Frostys Cache Editor/bin/com/alex/util/whirlpool/Whirlpool.class new file mode 100644 index 0000000..4b4f346 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/util/whirlpool/Whirlpool.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/utils/Constants.class b/Tools/Frostys Cache Editor/bin/com/alex/utils/Constants.class new file mode 100644 index 0000000..9c96997 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/utils/Constants.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/alex/utils/Utils.class b/Tools/Frostys Cache Editor/bin/com/alex/utils/Utils.class new file mode 100644 index 0000000..daba6c7 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/alex/utils/Utils.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/Console$1.class b/Tools/Frostys Cache Editor/bin/com/editor/Console$1.class new file mode 100644 index 0000000..5b0a0e5 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/Console$1.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/Console$2.class b/Tools/Frostys Cache Editor/bin/com/editor/Console$2.class new file mode 100644 index 0000000..1c37fc9 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/Console$2.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/Console$3.class b/Tools/Frostys Cache Editor/bin/com/editor/Console$3.class new file mode 100644 index 0000000..43592d2 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/Console$3.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/Console$4.class b/Tools/Frostys Cache Editor/bin/com/editor/Console$4.class new file mode 100644 index 0000000..addebd8 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/Console$4.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/Console$5.class b/Tools/Frostys Cache Editor/bin/com/editor/Console$5.class new file mode 100644 index 0000000..2f9944c Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/Console$5.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/Console.class b/Tools/Frostys Cache Editor/bin/com/editor/Console.class new file mode 100644 index 0000000..236d1e4 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/Console.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/Main.class b/Tools/Frostys Cache Editor/bin/com/editor/Main.class new file mode 100644 index 0000000..a3fbf2d Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/Main.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/ToolSelection$1.class b/Tools/Frostys Cache Editor/bin/com/editor/ToolSelection$1.class new file mode 100644 index 0000000..1f593d7 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/ToolSelection$1.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/ToolSelection$2.class b/Tools/Frostys Cache Editor/bin/com/editor/ToolSelection$2.class new file mode 100644 index 0000000..ee35116 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/ToolSelection$2.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/ToolSelection$3.class b/Tools/Frostys Cache Editor/bin/com/editor/ToolSelection$3.class new file mode 100644 index 0000000..8a1046c Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/ToolSelection$3.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/ToolSelection$4.class b/Tools/Frostys Cache Editor/bin/com/editor/ToolSelection$4.class new file mode 100644 index 0000000..c6b4ea6 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/ToolSelection$4.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/ToolSelection$5.class b/Tools/Frostys Cache Editor/bin/com/editor/ToolSelection$5.class new file mode 100644 index 0000000..642ab93 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/ToolSelection$5.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/ToolSelection$6.class b/Tools/Frostys Cache Editor/bin/com/editor/ToolSelection$6.class new file mode 100644 index 0000000..87dcfd1 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/ToolSelection$6.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/ToolSelection$7.class b/Tools/Frostys Cache Editor/bin/com/editor/ToolSelection$7.class new file mode 100644 index 0000000..ad02a86 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/ToolSelection$7.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/ToolSelection$8.class b/Tools/Frostys Cache Editor/bin/com/editor/ToolSelection$8.class new file mode 100644 index 0000000..afa157a Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/ToolSelection$8.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/ToolSelection.class b/Tools/Frostys Cache Editor/bin/com/editor/ToolSelection.class new file mode 100644 index 0000000..48757eb Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/ToolSelection.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/Utils.class b/Tools/Frostys Cache Editor/bin/com/editor/Utils.class new file mode 100644 index 0000000..30527e6 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/Utils.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/item/ItemDefDump.class b/Tools/Frostys Cache Editor/bin/com/editor/item/ItemDefDump.class new file mode 100644 index 0000000..65641dd Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/item/ItemDefDump.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/item/ItemEditor$1.class b/Tools/Frostys Cache Editor/bin/com/editor/item/ItemEditor$1.class new file mode 100644 index 0000000..7c4b2a1 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/item/ItemEditor$1.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/item/ItemEditor$2.class b/Tools/Frostys Cache Editor/bin/com/editor/item/ItemEditor$2.class new file mode 100644 index 0000000..cc8e12d Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/item/ItemEditor$2.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/item/ItemEditor$3.class b/Tools/Frostys Cache Editor/bin/com/editor/item/ItemEditor$3.class new file mode 100644 index 0000000..2039721 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/item/ItemEditor$3.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/item/ItemEditor$4.class b/Tools/Frostys Cache Editor/bin/com/editor/item/ItemEditor$4.class new file mode 100644 index 0000000..b943de8 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/item/ItemEditor$4.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/item/ItemEditor$5.class b/Tools/Frostys Cache Editor/bin/com/editor/item/ItemEditor$5.class new file mode 100644 index 0000000..37a07e7 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/item/ItemEditor$5.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/item/ItemEditor.class b/Tools/Frostys Cache Editor/bin/com/editor/item/ItemEditor.class new file mode 100644 index 0000000..2d9c111 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/item/ItemEditor.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/item/ItemListDumper.class b/Tools/Frostys Cache Editor/bin/com/editor/item/ItemListDumper.class new file mode 100644 index 0000000..5f9f042 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/item/ItemListDumper.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/item/ItemSelection$1.class b/Tools/Frostys Cache Editor/bin/com/editor/item/ItemSelection$1.class new file mode 100644 index 0000000..e320bc3 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/item/ItemSelection$1.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/item/ItemSelection$2.class b/Tools/Frostys Cache Editor/bin/com/editor/item/ItemSelection$2.class new file mode 100644 index 0000000..05e281b Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/item/ItemSelection$2.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/item/ItemSelection$3.class b/Tools/Frostys Cache Editor/bin/com/editor/item/ItemSelection$3.class new file mode 100644 index 0000000..f3fbe15 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/item/ItemSelection$3.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/item/ItemSelection$4.class b/Tools/Frostys Cache Editor/bin/com/editor/item/ItemSelection$4.class new file mode 100644 index 0000000..a607976 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/item/ItemSelection$4.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/item/ItemSelection$5.class b/Tools/Frostys Cache Editor/bin/com/editor/item/ItemSelection$5.class new file mode 100644 index 0000000..4730b3a Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/item/ItemSelection$5.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/item/ItemSelection$6.class b/Tools/Frostys Cache Editor/bin/com/editor/item/ItemSelection$6.class new file mode 100644 index 0000000..5577ae1 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/item/ItemSelection$6.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/item/ItemSelection$7.class b/Tools/Frostys Cache Editor/bin/com/editor/item/ItemSelection$7.class new file mode 100644 index 0000000..be45e7d Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/item/ItemSelection$7.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/item/ItemSelection$8.class b/Tools/Frostys Cache Editor/bin/com/editor/item/ItemSelection$8.class new file mode 100644 index 0000000..4f76d21 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/item/ItemSelection$8.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/item/ItemSelection$9.class b/Tools/Frostys Cache Editor/bin/com/editor/item/ItemSelection$9.class new file mode 100644 index 0000000..bd50dc0 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/item/ItemSelection$9.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/item/ItemSelection.class b/Tools/Frostys Cache Editor/bin/com/editor/item/ItemSelection.class new file mode 100644 index 0000000..5b9e52b Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/item/ItemSelection.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/model/ModelDumper.class b/Tools/Frostys Cache Editor/bin/com/editor/model/ModelDumper.class new file mode 100644 index 0000000..6b4292d Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/model/ModelDumper.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/model/MultiModelPacker$1.class b/Tools/Frostys Cache Editor/bin/com/editor/model/MultiModelPacker$1.class new file mode 100644 index 0000000..e66c4a7 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/model/MultiModelPacker$1.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/model/MultiModelPacker$2.class b/Tools/Frostys Cache Editor/bin/com/editor/model/MultiModelPacker$2.class new file mode 100644 index 0000000..a3bdd23 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/model/MultiModelPacker$2.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/model/MultiModelPacker$3.class b/Tools/Frostys Cache Editor/bin/com/editor/model/MultiModelPacker$3.class new file mode 100644 index 0000000..b0dfd8a Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/model/MultiModelPacker$3.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/model/MultiModelPacker$4.class b/Tools/Frostys Cache Editor/bin/com/editor/model/MultiModelPacker$4.class new file mode 100644 index 0000000..7955c7d Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/model/MultiModelPacker$4.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/model/MultiModelPacker.class b/Tools/Frostys Cache Editor/bin/com/editor/model/MultiModelPacker.class new file mode 100644 index 0000000..005f466 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/model/MultiModelPacker.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/model/UniModelDumper$1.class b/Tools/Frostys Cache Editor/bin/com/editor/model/UniModelDumper$1.class new file mode 100644 index 0000000..3f953c1 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/model/UniModelDumper$1.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/model/UniModelDumper$2.class b/Tools/Frostys Cache Editor/bin/com/editor/model/UniModelDumper$2.class new file mode 100644 index 0000000..6be2953 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/model/UniModelDumper$2.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/model/UniModelDumper$3.class b/Tools/Frostys Cache Editor/bin/com/editor/model/UniModelDumper$3.class new file mode 100644 index 0000000..e5f48e9 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/model/UniModelDumper$3.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/model/UniModelDumper.class b/Tools/Frostys Cache Editor/bin/com/editor/model/UniModelDumper.class new file mode 100644 index 0000000..577b9da Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/model/UniModelDumper.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCDefDump.class b/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCDefDump.class new file mode 100644 index 0000000..539231f Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCDefDump.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCEditor$1.class b/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCEditor$1.class new file mode 100644 index 0000000..498cdf3 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCEditor$1.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCEditor$2.class b/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCEditor$2.class new file mode 100644 index 0000000..acf0dcb Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCEditor$2.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCEditor$3.class b/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCEditor$3.class new file mode 100644 index 0000000..44b4a7d Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCEditor$3.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCEditor$4.class b/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCEditor$4.class new file mode 100644 index 0000000..c1b43a7 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCEditor$4.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCEditor$5.class b/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCEditor$5.class new file mode 100644 index 0000000..9fe6b2b Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCEditor$5.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCEditor$6.class b/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCEditor$6.class new file mode 100644 index 0000000..8b0178a Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCEditor$6.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCEditor.class b/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCEditor.class new file mode 100644 index 0000000..5c918cf Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCEditor.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCListDumper.class b/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCListDumper.class new file mode 100644 index 0000000..183063a Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCListDumper.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCSelection$1.class b/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCSelection$1.class new file mode 100644 index 0000000..6cbfefd Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCSelection$1.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCSelection$2.class b/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCSelection$2.class new file mode 100644 index 0000000..e060673 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCSelection$2.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCSelection$3.class b/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCSelection$3.class new file mode 100644 index 0000000..afa5d86 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCSelection$3.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCSelection$4.class b/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCSelection$4.class new file mode 100644 index 0000000..c57d42d Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCSelection$4.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCSelection$5.class b/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCSelection$5.class new file mode 100644 index 0000000..8359783 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCSelection$5.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCSelection$6.class b/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCSelection$6.class new file mode 100644 index 0000000..c6532f8 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCSelection$6.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCSelection$7.class b/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCSelection$7.class new file mode 100644 index 0000000..50e5a05 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCSelection$7.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCSelection$8.class b/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCSelection$8.class new file mode 100644 index 0000000..1e56f0a Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCSelection$8.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCSelection$9.class b/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCSelection$9.class new file mode 100644 index 0000000..15af076 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCSelection$9.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCSelection.class b/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCSelection.class new file mode 100644 index 0000000..413be84 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/npc/NPCSelection.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/object/ObjectEditor$1.class b/Tools/Frostys Cache Editor/bin/com/editor/object/ObjectEditor$1.class new file mode 100644 index 0000000..b87ac78 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/object/ObjectEditor$1.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/object/ObjectEditor$2.class b/Tools/Frostys Cache Editor/bin/com/editor/object/ObjectEditor$2.class new file mode 100644 index 0000000..62d3568 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/object/ObjectEditor$2.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/object/ObjectEditor$3.class b/Tools/Frostys Cache Editor/bin/com/editor/object/ObjectEditor$3.class new file mode 100644 index 0000000..e489259 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/object/ObjectEditor$3.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/object/ObjectEditor.class b/Tools/Frostys Cache Editor/bin/com/editor/object/ObjectEditor.class new file mode 100644 index 0000000..3fbd58f Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/object/ObjectEditor.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/object/ObjectSelection$1.class b/Tools/Frostys Cache Editor/bin/com/editor/object/ObjectSelection$1.class new file mode 100644 index 0000000..6f65b25 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/object/ObjectSelection$1.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/object/ObjectSelection$2.class b/Tools/Frostys Cache Editor/bin/com/editor/object/ObjectSelection$2.class new file mode 100644 index 0000000..e575e1d Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/object/ObjectSelection$2.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/object/ObjectSelection$3.class b/Tools/Frostys Cache Editor/bin/com/editor/object/ObjectSelection$3.class new file mode 100644 index 0000000..0e319f2 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/object/ObjectSelection$3.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/object/ObjectSelection$4.class b/Tools/Frostys Cache Editor/bin/com/editor/object/ObjectSelection$4.class new file mode 100644 index 0000000..9d686ad Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/object/ObjectSelection$4.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/object/ObjectSelection$5.class b/Tools/Frostys Cache Editor/bin/com/editor/object/ObjectSelection$5.class new file mode 100644 index 0000000..28d2e89 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/object/ObjectSelection$5.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/object/ObjectSelection$6.class b/Tools/Frostys Cache Editor/bin/com/editor/object/ObjectSelection$6.class new file mode 100644 index 0000000..832e3b5 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/object/ObjectSelection$6.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/object/ObjectSelection$7.class b/Tools/Frostys Cache Editor/bin/com/editor/object/ObjectSelection$7.class new file mode 100644 index 0000000..1596f81 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/object/ObjectSelection$7.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/object/ObjectSelection$8.class b/Tools/Frostys Cache Editor/bin/com/editor/object/ObjectSelection$8.class new file mode 100644 index 0000000..9ceb088 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/object/ObjectSelection$8.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/object/ObjectSelection$9.class b/Tools/Frostys Cache Editor/bin/com/editor/object/ObjectSelection$9.class new file mode 100644 index 0000000..4fea2ca Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/object/ObjectSelection$9.class differ diff --git a/Tools/Frostys Cache Editor/bin/com/editor/object/ObjectSelection.class b/Tools/Frostys Cache Editor/bin/com/editor/object/ObjectSelection.class new file mode 100644 index 0000000..1d5dab7 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/com/editor/object/ObjectSelection.class differ diff --git a/Tools/Frostys Cache Editor/bin/org/apache/tools/bzip2/BZip2Constants.class b/Tools/Frostys Cache Editor/bin/org/apache/tools/bzip2/BZip2Constants.class new file mode 100644 index 0000000..c97e853 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/org/apache/tools/bzip2/BZip2Constants.class differ diff --git a/Tools/Frostys Cache Editor/bin/org/apache/tools/bzip2/CBZip2OutputStream$StackElem.class b/Tools/Frostys Cache Editor/bin/org/apache/tools/bzip2/CBZip2OutputStream$StackElem.class new file mode 100644 index 0000000..012546f Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/org/apache/tools/bzip2/CBZip2OutputStream$StackElem.class differ diff --git a/Tools/Frostys Cache Editor/bin/org/apache/tools/bzip2/CBZip2OutputStream$SyntheticClass_1.class b/Tools/Frostys Cache Editor/bin/org/apache/tools/bzip2/CBZip2OutputStream$SyntheticClass_1.class new file mode 100644 index 0000000..56aab00 Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/org/apache/tools/bzip2/CBZip2OutputStream$SyntheticClass_1.class differ diff --git a/Tools/Frostys Cache Editor/bin/org/apache/tools/bzip2/CBZip2OutputStream.class b/Tools/Frostys Cache Editor/bin/org/apache/tools/bzip2/CBZip2OutputStream.class new file mode 100644 index 0000000..73c7e0d Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/org/apache/tools/bzip2/CBZip2OutputStream.class differ diff --git a/Tools/Frostys Cache Editor/bin/org/apache/tools/bzip2/CRC.class b/Tools/Frostys Cache Editor/bin/org/apache/tools/bzip2/CRC.class new file mode 100644 index 0000000..746dbbe Binary files /dev/null and b/Tools/Frostys Cache Editor/bin/org/apache/tools/bzip2/CRC.class differ diff --git a/Tools/Frostys Cache Editor/clientscripts.txt b/Tools/Frostys Cache Editor/clientscripts.txt new file mode 100644 index 0000000..b7016ab --- /dev/null +++ b/Tools/Frostys Cache Editor/clientscripts.txt @@ -0,0 +1,71 @@ +644, 1629 - Longsword Render Animation Id +644,Integer - Render Animation Id +687, 1 enable spec bar +687, 0 disable spec bar +686, 1 staff combat styles +686, 6 scimitar/longsword combat styles +686, 7 two-handed sword combat styles +686, 10 warhammer combat styles +686, 11 whip combat styles +686, 16 shortbow/longbow combat syles +686, 17 crossbow combat styles + +749, (levelId) +750, (level required) + +861,Integer - Quest Id Requirement + + + + +0,Integer - Stab attack bonus +1,Integer - Slash attack bonus +2,Integer - Crush attack bonus +3,Integer - Magic attack bonus +4,Integer - Range attack bonus +5,Integer - Stab defense bonus +6,Integer - Slash defense bonus +7,Integer - Crush defense bonus +8,Integer - Magic defense bonus +9,Integer - Range defense bonus + +11,Integer - Prayer bonus + +14,Integer - Attack speed + +23,Integer - Ranged level requirement ? ( 20<- /40) + +277,Integer - Maxed skill requirement + +417,Integer - Summoning defense bonus + +528,String - Equipment tab Option (ActionButtons2) +529,String - Equipment tab Option (ActionButtons3) +530,String - Equipment tab Option (ActionButtons4) +531,String - Equipment tab Option (ActionButtons5) + +641,Integer - Melee Strength bonus +642,Integer - Magic Strength bonus +643,Integer - Ranged Strength bonus +644,Integer - Render Animation Id + +685,Integer - Magic damage +686,Integer - Attack Styles Tab +687,Integer - Special bar (1) + +749,Integer - Skill Id Requirment +750,Integer - Skill Level Requirment +751,Integer - Skill Id Requirment +752,Integer - Skill Level Requirment +753,Integer - Skill Id Requirment +754,Integer - Skill Level Requirment +755,Integer - Skill Id Requirment +756,Integer - Skill Level Requirment +757,Integer - Skill Id Requirment +758,Integer - Skill Level Requirment + +861,Integer - Quest Id Requirement + +967,Integer - Absorb melee bonus +968,Integer - Absorb range bonus +969,Integer - Absorb magic bonus \ No newline at end of file diff --git a/Tools/Frostys Cache Editor/models.txt b/Tools/Frostys Cache Editor/models.txt new file mode 100644 index 0000000..e69de29 diff --git a/Tools/Frostys Cache Editor/nullmain_file_cache.dat2 b/Tools/Frostys Cache Editor/nullmain_file_cache.dat2 new file mode 100644 index 0000000..e69de29 diff --git a/Tools/Frostys Cache Editor/nullmain_file_cache.idx255 b/Tools/Frostys Cache Editor/nullmain_file_cache.idx255 new file mode 100644 index 0000000..e69de29 diff --git a/Tools/Frostys Cache Editor/src/com/alex/io/InputStream.java b/Tools/Frostys Cache Editor/src/com/alex/io/InputStream.java new file mode 100644 index 0000000..a188d6c --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/io/InputStream.java @@ -0,0 +1,257 @@ +package com.alex.io; + +import com.alex.io.Stream; + +public final class InputStream extends Stream { + private static final int[] BIT_MASK = new int[]{0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767, '\uffff', 131071, 262143, 524287, 1048575, 2097151, 4194303, 8388607, 16777215, 33554431, 67108863, 134217727, 268435455, 536870911, 1073741823, Integer.MAX_VALUE, -1}; + + public void initBitAccess() { + this.bitPosition = this.offset * 8; + } + + public void finishBitAccess() { + this.offset = (7 + this.bitPosition) / 8; + } + + public int readBits(int bitOffset) { + int bytePos = this.bitPosition >> 1779819011; + int i_8_ = -(7 & this.bitPosition) + 8; + this.bitPosition += bitOffset; + + int value; + for(value = 0; ~bitOffset < ~i_8_; i_8_ = 8) { + value += (BIT_MASK[i_8_] & this.buffer[bytePos++]) << -i_8_ + bitOffset; + bitOffset -= i_8_; + } + + if(~i_8_ == ~bitOffset) { + value += this.buffer[bytePos] & BIT_MASK[i_8_]; + } else { + value += this.buffer[bytePos] >> -bitOffset + i_8_ & BIT_MASK[bitOffset]; + } + + return value; + } + + public InputStream(int capacity) { + this.buffer = new byte[capacity]; + } + + public InputStream(byte[] buffer) { + this.buffer = buffer; + this.length = buffer.length; + } + + public void checkCapacity(int length) { + if(this.offset + length >= this.buffer.length) { + byte[] newBuffer = new byte[(this.offset + length) * 2]; + System.arraycopy(this.buffer, 0, newBuffer, 0, this.buffer.length); + this.buffer = newBuffer; + } + + } + + public void skip(int length) { + this.offset += length; + } + + public void setLength(int length) { + this.length = length; + } + + public void setOffset(int offset) { + this.offset = offset; + } + + public int getRemaining() { + return this.offset < this.length?this.length - this.offset:0; + } + + public void addBytes(byte[] b, int offset, int length) { + this.checkCapacity(length - offset); + System.arraycopy(b, offset, this.buffer, this.offset, length); + this.length += length - offset; + } + + public int readPacket() { + return this.readUnsignedByte(); + } + + public int readByte() { + return this.getRemaining() > 0?this.buffer[this.offset++]:0; + } + + public void readBytes(byte[] buffer, int off, int len) { + for(int k = off; k < len + off; ++k) { + buffer[k] = (byte)this.readByte(); + } + + } + + public void readBytes(byte[] buffer) { + this.readBytes(buffer, 0, buffer.length); + } + + public int readSmart2() { + int i = 0; + + int i_33_; + for(i_33_ = this.readUnsignedSmart(); ~i_33_ == -32768; i += 32767) { + i_33_ = this.readUnsignedSmart(); + } + + i += i_33_; + return i; + } + + public int readUnsignedByte() { + return this.readByte() & 255; + } + + public int readByte128() { + return (byte)(this.readByte() - 128); + } + + public int readByteC() { + return (byte)(-this.readByte()); + } + + public int read128Byte() { + return (byte)(128 - this.readByte()); + } + + public int readUnsignedByte128() { + return this.readUnsignedByte() - 128 & 255; + } + + public int readUnsignedByteC() { + return -this.readUnsignedByte() & 255; + } + + public int readUnsigned128Byte() { + return 128 - this.readUnsignedByte() & 255; + } + + public int readShortLE() { + int i = this.readUnsignedByte() + (this.readUnsignedByte() << 8); + if(i > 32767) { + i -= 65536; + } + + return i; + } + + public int readShort128() { + int i = (this.readUnsignedByte() << 8) + (this.readByte() - 128 & 255); + if(i > 32767) { + i -= 65536; + } + + return i; + } + + public int readShortLE128() { + int i = (this.readByte() - 128 & 255) + (this.readUnsignedByte() << 8); + if(i > 32767) { + i -= 65536; + } + + return i; + } + + public int read128ShortLE() { + int i = (128 - this.readByte() & 255) + (this.readUnsignedByte() << 8); + if(i > 32767) { + i -= 65536; + } + + return i; + } + + public int readShort() { + int i = (this.readUnsignedByte() << 8) + this.readUnsignedByte(); + if(i > 32767) { + i -= 65536; + } + + return i; + } + + public int readUnsignedShortLE() { + return this.readUnsignedByte() + (this.readUnsignedByte() << 8); + } + + public int readUnsignedShort() { + return (this.readUnsignedByte() << 8) + this.readUnsignedByte(); + } + + public int readUnsignedShort128() { + return (this.readUnsignedByte() << 8) + (this.readByte() - 128 & 255); + } + + public int readUnsignedShortLE128() { + return (this.readByte() - 128 & 255) + (this.readUnsignedByte() << 8); + } + + public int readInt() { + return (this.readUnsignedByte() << 24) + (this.readUnsignedByte() << 16) + (this.readUnsignedByte() << 8) + this.readUnsignedByte(); + } + + public int read24BitInt() { + return (this.readUnsignedByte() << 16) + (this.readUnsignedByte() << 8) + this.readUnsignedByte(); + } + + public int readIntV1() { + return (this.readUnsignedByte() << 8) + this.readUnsignedByte() + (this.readUnsignedByte() << 24) + (this.readUnsignedByte() << 16); + } + + public int readIntV2() { + return (this.readUnsignedByte() << 16) + (this.readUnsignedByte() << 24) + this.readUnsignedByte() + (this.readUnsignedByte() << 8); + } + + public int readIntLE() { + return this.readUnsignedByte() + (this.readUnsignedByte() << 8) + (this.readUnsignedByte() << 16) + (this.readUnsignedByte() << 24); + } + + public long readLong() { + long l = (long)this.readInt() & 4294967295L; + long l1 = (long)this.readInt() & 4294967295L; + return (l << 32) + l1; + } + + public String readString() { + String s; + int b; + for(s = ""; (b = this.readByte()) != 0; s = s + (char)b) { + ; + } + + return s; + } + + public String readJagString() { + this.readByte(); + + String s; + int b; + for(s = ""; (b = this.readByte()) != 0; s = s + (char)b) { + ; + } + + return s; + } + + public int readBigSmart() { + if(~this.buffer[this.offset] <= -1) { + int value = this.readUnsignedShort(); + return value == 32767?-1:value; + } else { + return this.readInt() & Integer.MAX_VALUE; + } + } + + public int readUnsignedSmart() { + int i = 255 & this.buffer[this.offset]; + return i >= 128?-32768 + this.readUnsignedShort():this.readUnsignedByte(); + } +} diff --git a/Tools/Frostys Cache Editor/src/com/alex/io/OutputStream.java b/Tools/Frostys Cache Editor/src/com/alex/io/OutputStream.java new file mode 100644 index 0000000..aeaf638 --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/io/OutputStream.java @@ -0,0 +1,331 @@ +package com.alex.io; + +import com.alex.io.Stream; + +import java.math.BigInteger; + +public final class OutputStream extends Stream { + private static final int[] BIT_MASK = new int[32]; + private int opcodeStart = 0; + + static { + for(int i = 0; i < 32; ++i) { + BIT_MASK[i] = (1 << i) - 1; + } + + } + + public OutputStream(int capacity) { + this.setBuffer(new byte[capacity]); + } + + public OutputStream() { + this.setBuffer(new byte[16]); + } + + public OutputStream(byte[] buffer) { + this.setBuffer(buffer); + this.offset = buffer.length; + this.length = buffer.length; + } + + public OutputStream(int[] buffer) { + this.setBuffer(new byte[buffer.length]); + int[] arr$ = buffer; + int len$ = buffer.length; + + for(int i$ = 0; i$ < len$; ++i$) { + int value = arr$[i$]; + this.writeByte(value); + } + + } + + public void checkCapacityPosition(int position) { + if(position >= this.getBuffer().length) { + byte[] newBuffer = new byte[position + 16]; + System.arraycopy(this.getBuffer(), 0, newBuffer, 0, this.getBuffer().length); + this.setBuffer(newBuffer); + } + + } + + public void skip(int length) { + this.setOffset(this.getOffset() + length); + } + + public void setOffset(int offset) { + this.offset = offset; + } + + public void writeBytes(byte[] b, int offset, int length) { + this.checkCapacityPosition(this.getOffset() + length - offset); + System.arraycopy(b, offset, this.getBuffer(), this.getOffset(), length); + this.setOffset(this.getOffset() + (length - offset)); + } + + public void writeBytes(byte[] b) { + byte offset = 0; + int length = b.length; + this.checkCapacityPosition(this.getOffset() + length - offset); + System.arraycopy(b, offset, this.getBuffer(), this.getOffset(), length); + this.setOffset(this.getOffset() + (length - offset)); + } + + public void addBytes128(byte[] data, int offset, int len) { + for(int k = offset; k < len; ++k) { + this.writeByte((byte)(data[k] + 128)); + } + + } + + public void addBytesS(byte[] data, int offset, int len) { + for(int k = offset; k < len; ++k) { + this.writeByte((byte)(-128 + data[k])); + } + + } + + public void addBytes_Reverse(byte[] data, int offset, int len) { + for(int i = len - 1; i >= 0; --i) { + this.writeByte(data[i]); + } + + } + + public void addBytes_Reverse128(byte[] data, int offset, int len) { + for(int i = len - 1; i >= 0; --i) { + this.writeByte((byte)(data[i] + 128)); + } + + } + + public void writeByte(int i) { + this.writeByte(i, this.offset++); + } + + public void writeNegativeByte(int i) { + this.writeByte(-i, this.offset++); + } + + public void writeByte(int i, int position) { + this.checkCapacityPosition(position); + this.getBuffer()[position] = (byte)i; + } + + public void writeByte128(int i) { + this.writeByte(i + 128); + } + + public void writeByteC(int i) { + this.writeByte(-i); + } + + public void write3Byte(int i) { + this.writeByte(i >> 16); + this.writeByte(i >> 8); + this.writeByte(i); + } + + public void write128Byte(int i) { + this.writeByte(128 - i); + } + + public void writeShortLE128(int i) { + this.writeByte(i + 128); + this.writeByte(i >> 8); + } + + public void writeShort128(int i) { + this.writeByte(i >> 8); + this.writeByte(i + 128); + } + + public void writeBigSmart(int i) { + //if(i >= 32767 && i >= 0) { + if(i >= 52767 && i >= 0) { + this.writeInt(i - Integer.MAX_VALUE - 1); + } else { + this.writeShort(i >= 0?i:52767); + //this.writeShort(i >= 0?i:32767); + } + + } + + public void writeSmart(int i) { + if(i >= 128) { + this.writeShort(i); + } else { + this.writeByte(i); + } + + } + + public void writeShort(int i) { + this.writeByte(i >> 8); + this.writeByte(i); + } + + public void writeShortLE(int i) { + this.writeByte(i); + this.writeByte(i >> 8); + } + + public void write24BitInt(int i) { + this.writeByte(i >> 16); + this.writeByte(i >> 8); + this.writeByte(i); + } + + public void writeInt(int i) { + this.writeByte(i >> 24); + this.writeByte(i >> 16); + this.writeByte(i >> 8); + this.writeByte(i); + } + + public void writeIntV1(int i) { + this.writeByte(i >> 8); + this.writeByte(i); + this.writeByte(i >> 24); + this.writeByte(i >> 16); + } + + public void writeIntV2(int i) { + this.writeByte(i >> 16); + this.writeByte(i >> 24); + this.writeByte(i); + this.writeByte(i >> 8); + } + + public void writeIntLE(int i) { + this.writeByte(i); + this.writeByte(i >> 8); + this.writeByte(i >> 16); + this.writeByte(i >> 24); + } + + public void writeLong(long l) { + this.writeByte((int)(l >> 56)); + this.writeByte((int)(l >> 48)); + this.writeByte((int)(l >> 40)); + this.writeByte((int)(l >> 32)); + this.writeByte((int)(l >> 24)); + this.writeByte((int)(l >> 16)); + this.writeByte((int)(l >> 8)); + this.writeByte((int)l); + } + + public void writePSmarts(int i) { + if(i < 128) { + this.writeByte(i); + } else if (i < 32768) { + this.writeShort(32768 + i); + }else { + System.out.println("Error psmarts out of range:"); + } + + } + + public void writeString(String s) { + this.checkCapacityPosition(this.getOffset() + s.length() + 1); + System.arraycopy(s.getBytes(), 0, this.getBuffer(), this.getOffset(), s.length()); + this.setOffset(this.getOffset() + s.length()); + this.writeByte(0); + } + + public void writeGJString(String s) { + this.writeByte(0); + this.writeString(s); + } + + public void putGJString3(String s) { + this.writeByte(0); + this.writeString(s); + this.writeByte(0); + } + + public void writePacket(int id) { + this.writeByte(id); + } + + public void writePacketVarByte(int id) { + this.writePacket(id); + this.writeByte(0); + this.opcodeStart = this.getOffset() - 1; + } + + public void writePacketVarShort(int id) { + this.writePacket(id); + this.writeShort(0); + this.opcodeStart = this.getOffset() - 2; + } + + public void endPacketVarByte() { + this.writeByte(this.getOffset() - (this.opcodeStart + 2) + 1, this.opcodeStart); + } + + public void endPacketVarShort() { + int size = this.getOffset() - (this.opcodeStart + 2); + this.writeByte(size >> 8, this.opcodeStart++); + this.writeByte(size, this.opcodeStart); + } + + public void initBitAccess() { + this.bitPosition = this.getOffset() * 8; + } + + public void finishBitAccess() { + this.setOffset((this.bitPosition + 7) / 8); + } + + public int getBitPos(int i) { + return 8 * i - this.bitPosition; + } + + public void writeBits(int numBits, int value) { + int bytePos = this.bitPosition >> 3; + int bitOffset = 8 - (this.bitPosition & 7); + + byte[] var10000; + for(this.bitPosition += numBits; numBits > bitOffset; bitOffset = 8) { + this.checkCapacityPosition(bytePos); + var10000 = this.getBuffer(); + var10000[bytePos] = (byte)(var10000[bytePos] & ~BIT_MASK[bitOffset]); + var10000 = this.getBuffer(); + int var10001 = bytePos++; + var10000[var10001] = (byte)(var10000[var10001] | value >> numBits - bitOffset & BIT_MASK[bitOffset]); + numBits -= bitOffset; + } + + this.checkCapacityPosition(bytePos); + if(numBits == bitOffset) { + var10000 = this.getBuffer(); + var10000[bytePos] = (byte)(var10000[bytePos] & ~BIT_MASK[bitOffset]); + var10000 = this.getBuffer(); + var10000[bytePos] = (byte)(var10000[bytePos] | value & BIT_MASK[bitOffset]); + } else { + var10000 = this.getBuffer(); + var10000[bytePos] = (byte)(var10000[bytePos] & ~(BIT_MASK[numBits] << bitOffset - numBits)); + var10000 = this.getBuffer(); + var10000[bytePos] = (byte)(var10000[bytePos] | (value & BIT_MASK[numBits]) << bitOffset - numBits); + } + + } + + public void setBuffer(byte[] buffer) { + this.buffer = buffer; + } + + public final void rsaEncode(BigInteger key, BigInteger modulus) { + int length = this.offset; + this.offset = 0; + byte[] data = new byte[length]; + this.getBytes(data, 0, length); + BigInteger biginteger2 = new BigInteger(data); + BigInteger biginteger3 = biginteger2.modPow(key, modulus); + byte[] out = biginteger3.toByteArray(); + this.offset = 0; + this.writeBytes(out, 0, out.length); + } +} diff --git a/Tools/Frostys Cache Editor/src/com/alex/io/Stream.java b/Tools/Frostys Cache Editor/src/com/alex/io/Stream.java new file mode 100644 index 0000000..4f5367f --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/io/Stream.java @@ -0,0 +1,91 @@ +package com.alex.io; + +public abstract class Stream { + protected int offset; + protected int length; + protected byte[] buffer; + protected int bitPosition; + + public int getLength() { + return this.length; + } + + public byte[] getBuffer() { + return this.buffer; + } + + public int getOffset() { + return this.offset; + } + + public void decodeXTEA(int[] keys) { + this.decodeXTEA(keys, 5, this.length); + } + + public void decodeXTEA(int[] keys, int start, int end) { + int l = this.offset; + this.offset = start; + int i1 = (end - start) / 8; + + for(int j1 = 0; j1 < i1; ++j1) { + int k1 = this.readInt(); + int l1 = this.readInt(); + int sum = -957401312; + int delta = -1640531527; + + for(int k2 = 32; k2-- > 0; k1 -= (l1 >>> 5 ^ l1 << 4) + l1 ^ keys[sum & 3] + sum) { + l1 -= keys[(sum & 7300) >>> 11] + sum ^ (k1 >>> 5 ^ k1 << 4) + k1; + sum -= delta; + } + + this.offset -= 8; + this.writeInt(k1); + this.writeInt(l1); + } + + this.offset = l; + } + + public final void encodeXTEA(int[] keys, int start, int end) { + int o = this.offset; + int j = (end - start) / 8; + this.offset = start; + + for(int k = 0; k < j; ++k) { + int l = this.readInt(); + int i1 = this.readInt(); + int sum = 0; + int delta = -1640531527; + + for(int l1 = 32; l1-- > 0; i1 += l + (l >>> 5 ^ l << 4) ^ keys[(7916 & sum) >>> 11] + sum) { + l += sum + keys[3 & sum] ^ i1 + (i1 >>> 5 ^ i1 << 4); + sum += delta; + } + + this.offset -= 8; + this.writeInt(l); + this.writeInt(i1); + } + + this.offset = o; + } + + private final int readInt() { + this.offset += 4; + return ((255 & this.buffer[-3 + this.offset]) << 16) + ((255 & this.buffer[-4 + this.offset]) << 24) + ((this.buffer[-2 + this.offset] & 255) << 8) + (this.buffer[-1 + this.offset] & 255); + } + + public void writeInt(int value) { + this.buffer[this.offset++] = (byte)(value >> 24); + this.buffer[this.offset++] = (byte)(value >> 16); + this.buffer[this.offset++] = (byte)(value >> 8); + this.buffer[this.offset++] = (byte)value; + } + + public final void getBytes(byte[] data, int off, int len) { + for(int k = off; k < len + off; ++k) { + data[k] = this.buffer[this.offset++]; + } + + } +} diff --git a/Tools/Frostys Cache Editor/src/com/alex/loaders/animations/AnimationDefinitions.java b/Tools/Frostys Cache Editor/src/com/alex/loaders/animations/AnimationDefinitions.java new file mode 100644 index 0000000..f0b5893 --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/loaders/animations/AnimationDefinitions.java @@ -0,0 +1,281 @@ +package com.alex.loaders.animations; + +import com.alex.io.InputStream; +import com.alex.store.Store; + +import java.io.IOException; +import java.io.PrintStream; +import java.util.concurrent.ConcurrentHashMap; + +public class AnimationDefinitions { + public static Store cache; + public static int id; + public int loopCycles = 99; + public int anInt2137; + public static int[] frames; + public int anInt2140 = -1; + public boolean aBoolean2141 = false; + public int priority = 5; + public int leftHandEquip = -1; + public int rightHandEquip = -1; + public int anInt2145; + public int[][] handledSounds; + public boolean[] aBooleanArray2149; + public int[] anIntArray2151; + public boolean aBoolean2152 = false; + public static int[] delays; + public int anInt2155 = 2; + public boolean aBoolean2158 = false; + public boolean aBoolean2159 = false; + public int anInt2162 = -1; + public int loopDelay = -1; + public int[] soundMinDelay; + public int[] soundMaxDelay; + public int[] anIntArray1362; + public boolean effect2Sound; + private static final ConcurrentHashMap animDefs = new ConcurrentHashMap(); + + public static void main(String[] args) throws IOException { + cache = new Store("C:/Users/yvonne � christer/Dropbox/Source/data/562cache/"); + + label55: + for(int i = 0; i < 1; ++i) { + System.out.println("Emote ID: " + i); + int k = 0; + + while(true) { + getAnimationDefinitions(i); + PrintStream var10000; + StringBuilder var10001; + if(k >= delays.length) { + k = 0; + + while(true) { + getAnimationDefinitions(i); + if(k >= frames.length) { + System.out.println("loopDelay = " + getAnimationDefinitions(i).loopDelay); + System.out.println("leftHandEquip = " + getAnimationDefinitions(i).leftHandEquip); + System.out.println("priority = " + getAnimationDefinitions(i).priority); + System.out.println("rightHandEquip = " + getAnimationDefinitions(i).rightHandEquip); + System.out.println("loopCycles = " + getAnimationDefinitions(i).loopCycles); + System.out.println("anInt2140 = " + getAnimationDefinitions(i).anInt2140); + System.out.println("anInt2162 = " + getAnimationDefinitions(i).anInt2162); + System.out.println("anInt2155 = " + getAnimationDefinitions(i).anInt2155); + System.out.println("anInt2145 = " + getAnimationDefinitions(i).anInt2145); + + for(k = 0; k < getAnimationDefinitions(i).anIntArray2151.length; ++k) { + System.out.println("anIntArray2151[" + k + "] = " + getAnimationDefinitions(i).anIntArray2151[k]); + } + + for(k = 0; k < getAnimationDefinitions(i).aBooleanArray2149.length; ++k) { + System.out.println("aBooleanArray2149[" + k + "] = " + getAnimationDefinitions(i).aBooleanArray2149[k]); + } + + System.out.println("aBoolean2152 = " + getAnimationDefinitions(i).aBoolean2152); + + for(k = 0; k < getAnimationDefinitions(i).anIntArray1362.length; ++k) { + System.out.println("anIntArray1362[" + k + "] = " + getAnimationDefinitions(i).anIntArray1362[k]); + } + continue label55; + } + + var10000 = System.out; + var10001 = (new StringBuilder()).append("frames[").append(k).append("] = "); + getAnimationDefinitions(i); + var10000.println(var10001.append(frames[k]).toString()); + ++k; + } + } + + var10000 = System.out; + var10001 = (new StringBuilder()).append("delays[").append(k).append("] = "); + getAnimationDefinitions(i); + var10000.println(var10001.append(delays[k]).toString()); + ++k; + } + } + + } + + public static final AnimationDefinitions getAnimationDefinitions(int emoteId) { + try { + AnimationDefinitions var3 = (AnimationDefinitions)animDefs.get(Integer.valueOf(emoteId)); + if(var3 != null) { + return var3; + } else { + byte[] data = cache.getIndexes()[20].getFile(emoteId >>> 7, emoteId & 127); + var3 = new AnimationDefinitions(); + if(data != null) { + var3.readValueLoop(new InputStream(data)); + } + + var3.method2394(); + animDefs.put(Integer.valueOf(emoteId), var3); + id = emoteId; + return var3; + } + } catch (Throwable var31) { + return null; + } + } + + private void readValueLoop(InputStream stream) { + while(true) { + int opcode = stream.readUnsignedByte(); + if(opcode == 0) { + return; + } + + this.readValues(stream, opcode); + } + } + + public int getEmoteTime() { + if(delays == null) { + return 0; + } else { + int ms = 0; + int[] arr$ = delays; + int len$ = arr$.length; + + for(int i$ = 0; i$ < len$; ++i$) { + int i = arr$[i$]; + ms += i; + } + + return ms * 30; + } + } + + public int getEmoteGameTickets() { + return this.getEmoteTime() / 1000; + } + + private void readValues(InputStream stream, int opcode) { + int index; + int i_21_; + if(opcode == 1) { + index = stream.readUnsignedShort(); + delays = new int[index]; + + for(i_21_ = 0; ~index < ~i_21_; ++i_21_) { + delays[i_21_] = stream.readUnsignedShort(); + } + + frames = new int[index]; + + for(i_21_ = 0; ~i_21_ > ~index; ++i_21_) { + frames[i_21_] = stream.readUnsignedShort(); + } + + for(i_21_ = 0; i_21_ < index; ++i_21_) { + frames[i_21_] += stream.readUnsignedShort() << 16; + } + } else if(opcode == 2) { + this.loopDelay = stream.readUnsignedShort(); + } else if(opcode == 3) { + this.aBooleanArray2149 = new boolean[256]; + index = stream.readUnsignedByte(); + + for(i_21_ = 0; i_21_ < index; ++i_21_) { + this.aBooleanArray2149[stream.readUnsignedByte()] = true; + } + } else if(opcode == 4) { + this.aBoolean2152 = true; + } else if(opcode == 5) { + this.priority = stream.readUnsignedByte(); + } else if(opcode == 6) { + this.rightHandEquip = stream.readUnsignedShort(); + } else if(opcode == 7) { + this.leftHandEquip = stream.readUnsignedShort(); + } else if(opcode == 8) { + this.loopCycles = stream.readUnsignedByte(); + } else if(opcode == 9) { + this.anInt2140 = stream.readUnsignedByte(); + } else if(opcode == 10) { + this.anInt2162 = stream.readUnsignedByte(); + } else if(opcode == 11) { + this.anInt2155 = stream.readUnsignedByte(); + } else if(opcode == 12) { + index = stream.readUnsignedByte(); + this.anIntArray2151 = new int[index]; + + for(i_21_ = 0; ~i_21_ > ~index; ++i_21_) { + this.anIntArray2151[i_21_] = stream.readUnsignedShort(); + } + + for(i_21_ = 0; index > i_21_; ++i_21_) { + this.anIntArray2151[i_21_] += stream.readUnsignedShort() << 16; + } + } else if(opcode == 13) { + index = stream.readUnsignedShort(); + this.handledSounds = new int[index][]; + + for(i_21_ = 0; i_21_ < index; ++i_21_) { + int i_22_ = stream.readUnsignedByte(); + if(~i_22_ < -1) { + this.handledSounds[i_21_] = new int[i_22_]; + this.handledSounds[i_21_][0] = stream.read24BitInt(); + + for(int i_23_ = 1; ~i_22_ < ~i_23_; ++i_23_) { + this.handledSounds[i_21_][i_23_] = stream.readUnsignedShort(); + } + } + } + } else if(opcode == 14) { + this.aBoolean2141 = true; + } else if(opcode == 15) { + this.aBoolean2159 = true; + } else if(opcode == 16) { + this.aBoolean2158 = true; + } else if(opcode == 17) { + this.anInt2145 = stream.readUnsignedByte(); + } else if(opcode == 18) { + this.effect2Sound = true; + } else if(opcode == 19) { + if(this.anIntArray1362 == null) { + this.anIntArray1362 = new int[this.handledSounds.length]; + + for(index = 0; index < this.handledSounds.length; ++index) { + this.anIntArray1362[index] = 255; + } + } + + this.anIntArray1362[stream.readUnsignedByte()] = stream.readUnsignedByte(); + } else if(opcode == 20) { + if(this.soundMaxDelay == null || this.soundMinDelay == null) { + this.soundMaxDelay = new int[this.handledSounds.length]; + this.soundMinDelay = new int[this.handledSounds.length]; + + for(index = 0; index < this.handledSounds.length; ++index) { + this.soundMaxDelay[index] = 256; + this.soundMinDelay[index] = 256; + } + } + + index = stream.readUnsignedByte(); + this.soundMaxDelay[index] = stream.readUnsignedShort(); + this.soundMinDelay[index] = stream.readUnsignedShort(); + } + + } + + public void method2394() { + if(this.anInt2140 == -1) { + if(this.aBooleanArray2149 == null) { + this.anInt2140 = 0; + } else { + this.anInt2140 = 2; + } + } + + if(this.anInt2162 == -1) { + if(this.aBooleanArray2149 == null) { + this.anInt2162 = 0; + } else { + this.anInt2162 = 2; + } + } + + } +} diff --git a/Tools/Frostys Cache Editor/src/com/alex/loaders/clientscripts/ClientScript.java b/Tools/Frostys Cache Editor/src/com/alex/loaders/clientscripts/ClientScript.java new file mode 100644 index 0000000..60aae5b --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/loaders/clientscripts/ClientScript.java @@ -0,0 +1,4 @@ +package com.alex.loaders.clientscripts; + +public class ClientScript { +} diff --git a/Tools/Frostys Cache Editor/src/com/alex/loaders/images/IndexedColorImageFile.java b/Tools/Frostys Cache Editor/src/com/alex/loaders/images/IndexedColorImageFile.java new file mode 100644 index 0000000..2dcde23 --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/loaders/images/IndexedColorImageFile.java @@ -0,0 +1,341 @@ +package com.alex.loaders.images; + +import com.alex.io.InputStream; +import com.alex.io.OutputStream; +import com.alex.store.Store; + +import java.awt.image.BufferedImage; +import java.util.Arrays; + +public final class IndexedColorImageFile { + private BufferedImage[] images; + private int[] pallete; + private int[][] pixelsIndexes; + private byte[][] alpha; + private boolean[] usesAlpha; + private int biggestWidth; + private int biggestHeight; + + public IndexedColorImageFile(BufferedImage... images) { + this.images = images; + } + + public IndexedColorImageFile(Store cache, int archiveId, int fileId) { + this(cache, 8, archiveId, fileId); + } + + public IndexedColorImageFile(Store cache, int idx, int archiveId, int fileId) { + this.decodeArchive(cache, idx, archiveId, fileId); + } + + public void decodeArchive(Store cache, int idx, int archiveId, int fileId) { + byte[] data = cache.getIndexes()[idx].getFile(archiveId, fileId); + if(data != null) { + InputStream stream = new InputStream(data); + stream.setOffset(data.length - 2); + int count = stream.readUnsignedShort(); + this.images = new BufferedImage[count]; + this.pixelsIndexes = new int[this.images.length][]; + this.alpha = new byte[this.images.length][]; + this.usesAlpha = new boolean[this.images.length]; + int[] imagesMinX = new int[this.images.length]; + int[] imagesMinY = new int[this.images.length]; + int[] imagesWidth = new int[this.images.length]; + int[] imagesHeight = new int[this.images.length]; + stream.setOffset(data.length - 7 - this.images.length * 8); + this.setBiggestWidth(stream.readShort()); + this.setBiggestHeight(stream.readShort()); + int palleteLength = (stream.readUnsignedByte() & 255) + 1; + + int i_20_; + for(i_20_ = 0; i_20_ < this.images.length; ++i_20_) { + imagesMinX[i_20_] = stream.readUnsignedShort(); + } + + for(i_20_ = 0; i_20_ < this.images.length; ++i_20_) { + imagesMinY[i_20_] = stream.readUnsignedShort(); + } + + for(i_20_ = 0; i_20_ < this.images.length; ++i_20_) { + imagesWidth[i_20_] = stream.readUnsignedShort(); + } + + for(i_20_ = 0; i_20_ < this.images.length; ++i_20_) { + imagesHeight[i_20_] = stream.readUnsignedShort(); + } + + stream.setOffset(data.length - 7 - this.images.length * 8 - (palleteLength - 1) * 3); + this.pallete = new int[palleteLength]; + + for(i_20_ = 1; i_20_ < palleteLength; ++i_20_) { + this.pallete[i_20_] = stream.read24BitInt(); + if(this.pallete[i_20_] == 0) { + this.pallete[i_20_] = 1; + } + } + + stream.setOffset(0); + + for(i_20_ = 0; i_20_ < this.images.length; ++i_20_) { + int pixelsIndexesLength = imagesWidth[i_20_] * imagesHeight[i_20_]; + this.pixelsIndexes[i_20_] = new int[pixelsIndexesLength]; + this.alpha[i_20_] = new byte[pixelsIndexesLength]; + int maskData = stream.readUnsignedByte(); + int i_31_; + if((maskData & 2) == 0) { + int var201; + if((maskData & 1) == 0) { + for(var201 = 0; var201 < pixelsIndexesLength; ++var201) { + this.pixelsIndexes[i_20_][var201] = (byte)stream.readByte(); + } + } else { + for(var201 = 0; var201 < imagesWidth[i_20_]; ++var201) { + for(i_31_ = 0; i_31_ < imagesHeight[i_20_]; ++i_31_) { + this.pixelsIndexes[i_20_][var201 + i_31_ * imagesWidth[i_20_]] = (byte)stream.readByte(); + } + } + } + } else { + this.usesAlpha[i_20_] = true; + boolean var20 = false; + if((maskData & 1) == 0) { + for(i_31_ = 0; i_31_ < pixelsIndexesLength; ++i_31_) { + this.pixelsIndexes[i_20_][i_31_] = (byte)stream.readByte(); + } + + for(i_31_ = 0; i_31_ < pixelsIndexesLength; ++i_31_) { + byte var21 = this.alpha[i_20_][i_31_] = (byte)stream.readByte(); + var20 |= var21 != -1; + } + } else { + int var211; + for(i_31_ = 0; i_31_ < imagesWidth[i_20_]; ++i_31_) { + for(var211 = 0; var211 < imagesHeight[i_20_]; ++var211) { + this.pixelsIndexes[i_20_][i_31_ + var211 * imagesWidth[i_20_]] = stream.readByte(); + } + } + + for(i_31_ = 0; i_31_ < imagesWidth[i_20_]; ++i_31_) { + for(var211 = 0; var211 < imagesHeight[i_20_]; ++var211) { + byte i_33_ = this.alpha[i_20_][i_31_ + var211 * imagesWidth[i_20_]] = (byte)stream.readByte(); + var20 |= i_33_ != -1; + } + } + } + + if(!var20) { + this.alpha[i_20_] = null; + } + } + + this.images[i_20_] = this.getBufferedImage(imagesWidth[i_20_], imagesHeight[i_20_], this.pixelsIndexes[i_20_], this.alpha[i_20_], this.usesAlpha[i_20_]); + } + } + + } + + public BufferedImage getBufferedImage(int width, int height, int[] pixelsIndexes, byte[] extraPixels, boolean useExtraPixels) { + if(width > 0 && height > 0) { + BufferedImage image = new BufferedImage(width, height, 6); + int[] rgbArray = new int[width * height]; + int i = 0; + int i_43_ = 0; + int i_46_; + int i_47_; + if(useExtraPixels && extraPixels != null) { + for(i_46_ = 0; i_46_ < height; ++i_46_) { + for(i_47_ = 0; i_47_ < width; ++i_47_) { + rgbArray[i_43_++] = extraPixels[i] << 24 | this.pallete[pixelsIndexes[i] & 255]; + ++i; + } + } + } else { + for(i_46_ = 0; i_46_ < height; ++i_46_) { + for(i_47_ = 0; i_47_ < width; ++i_47_) { + int i_48_ = this.pallete[pixelsIndexes[i++] & 255]; + rgbArray[i_43_++] = i_48_ != 0?-16777216 | i_48_:0; + } + } + } + + image.setRGB(0, 0, width, height, rgbArray, 0, width); + image.flush(); + return image; + } else { + return null; + } + } + + public byte[] encodeFile() { + if(this.pallete == null) { + this.generatePallete(); + } + + OutputStream stream = new OutputStream(); + + int container; + int len$; + int i$; + for(container = 0; container < this.images.length; ++container) { + len$ = 0; + if(this.usesAlpha[container]) { + len$ |= 2; + } + + stream.writeByte(len$); + + for(i$ = 0; i$ < this.pixelsIndexes[container].length; ++i$) { + stream.writeByte(this.pixelsIndexes[container][i$]); + } + + if(this.usesAlpha[container]) { + for(i$ = 0; i$ < this.alpha[container].length; ++i$) { + stream.writeByte(this.alpha[container][i$]); + } + } + } + + for(container = 0; container < this.pallete.length; ++container) { + stream.write24BitInt(this.pallete[container]); + } + + if(this.biggestWidth == 0 && this.biggestHeight == 0) { + BufferedImage[] var7 = this.images; + len$ = var7.length; + + for(i$ = 0; i$ < len$; ++i$) { + BufferedImage image = var7[i$]; + if(image.getWidth() > this.biggestWidth) { + this.biggestWidth = image.getWidth(); + } + + if(image.getHeight() > this.biggestHeight) { + this.biggestHeight = image.getHeight(); + } + } + } + + stream.writeShort(this.biggestWidth); + stream.writeShort(this.biggestHeight); + stream.writeByte(this.pallete.length - 1); + + for(container = 0; container < this.images.length; ++container) { + stream.writeShort(this.images[container].getMinX()); + } + + for(container = 0; container < this.images.length; ++container) { + stream.writeShort(this.images[container].getMinY()); + } + + for(container = 0; container < this.images.length; ++container) { + stream.writeShort(this.images[container].getWidth()); + } + + for(container = 0; container < this.images.length; ++container) { + stream.writeShort(this.images[container].getHeight()); + } + + stream.writeShort(this.images.length); + byte[] var71 = new byte[stream.getOffset()]; + stream.setOffset(0); + stream.getBytes(var71, 0, var71.length); + return var71; + } + + public int getPalleteIndex(int rgb) { + if(this.pallete == null) { + this.pallete = new int[1]; + } + + for(int var3 = 0; var3 < this.pallete.length; ++var3) { + if(this.pallete[var3] == rgb) { + return var3; + } + } + + if(this.pallete.length == 256) { + System.out.println("Pallete to big, please reduce images quality."); + return 0; + } else { + int[] var31 = new int[this.pallete.length + 1]; + System.arraycopy(this.pallete, 0, var31, 0, this.pallete.length); + var31[this.pallete.length] = rgb; + this.pallete = var31; + return this.pallete.length - 1; + } + } + + public int addImage(BufferedImage image) { + BufferedImage[] newImages = (BufferedImage[])Arrays.copyOf(this.images, this.images.length + 1); + newImages[this.images.length] = image; + this.images = newImages; + this.pallete = null; + this.pixelsIndexes = null; + this.alpha = null; + this.usesAlpha = null; + return this.images.length - 1; + } + + public void replaceImage(BufferedImage image, int index) { + this.images[index] = image; + this.pallete = null; + this.pixelsIndexes = null; + this.alpha = null; + this.usesAlpha = null; + } + + public void generatePallete() { + this.pixelsIndexes = new int[this.images.length][]; + this.alpha = new byte[this.images.length][]; + this.usesAlpha = new boolean[this.images.length]; + + for(int index = 0; index < this.images.length; ++index) { + BufferedImage image = this.images[index]; + int[] rgbArray = new int[image.getWidth() * image.getHeight()]; + image.getRGB(0, 0, image.getWidth(), image.getHeight(), rgbArray, 0, image.getWidth()); + this.pixelsIndexes[index] = new int[image.getWidth() * image.getHeight()]; + this.alpha[index] = new byte[image.getWidth() * image.getHeight()]; + + for(int pixel = 0; pixel < this.pixelsIndexes[index].length; ++pixel) { + int rgb = rgbArray[pixel]; + int medintrgb = this.convertToMediumInt(rgb); + int i = this.getPalleteIndex(medintrgb); + this.pixelsIndexes[index][pixel] = i; + if(rgb >> 24 != 0) { + this.alpha[index][pixel] = (byte)(rgb >> 24); + this.usesAlpha[index] = true; + } + } + } + + } + + public int convertToMediumInt(int rgb) { + OutputStream out = new OutputStream(4); + out.writeInt(rgb); + InputStream stream = new InputStream(out.getBuffer()); + stream.setOffset(1); + rgb = stream.read24BitInt(); + return rgb; + } + + public BufferedImage[] getImages() { + return this.images; + } + + public int getBiggestWidth() { + return this.biggestWidth; + } + + public void setBiggestWidth(int biggestWidth) { + this.biggestWidth = biggestWidth; + } + + public int getBiggestHeight() { + return this.biggestHeight; + } + + public void setBiggestHeight(int biggestHeight) { + this.biggestHeight = biggestHeight; + } +} diff --git a/Tools/Frostys Cache Editor/src/com/alex/loaders/images/LoaderImageArchive.java b/Tools/Frostys Cache Editor/src/com/alex/loaders/images/LoaderImageArchive.java new file mode 100644 index 0000000..b7d532b --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/loaders/images/LoaderImageArchive.java @@ -0,0 +1,35 @@ +package com.alex.loaders.images; + +import com.alex.store.Store; + +public class LoaderImageArchive { + private byte[] data; + + public LoaderImageArchive(byte[] data) { + this.data = data; + } + + public LoaderImageArchive(Store cache, int archiveId) { + this(cache, 32, archiveId, 0); + } + + private LoaderImageArchive(Store cache, int idx, int archiveId, int fileId) { + this.decodeArchive(cache, idx, archiveId, fileId); + } + + private void decodeArchive(Store cache, int idx, int archiveId, int fileId) { + byte[] data = cache.getIndexes()[idx].getFile(archiveId, fileId); + if(data != null) { + this.data = data; + } + + } + + public Image getImage() { + return Toolkit.getDefaultToolkit().createImage(this.data); + } + + public byte[] getImageData() { + return this.data; + } +} diff --git a/Tools/Frostys Cache Editor/src/com/alex/loaders/interfaces/IComponent.java b/Tools/Frostys Cache Editor/src/com/alex/loaders/interfaces/IComponent.java new file mode 100644 index 0000000..8c2fe41 --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/loaders/interfaces/IComponent.java @@ -0,0 +1,842 @@ +package com.alex.loaders.interfaces; + +import com.alex.io.InputStream; +import com.alex.loaders.interfaces.IComponentSettings; + +public class IComponent { + public Object[] anObjectArray2296; + public int anInt2297 = 0; + public int anInt2298 = -1; + public int[] anIntArray2299; + public int anInt2300; + public int anInt2301 = 1; + public Object[] anObjectArray2302; + public int anInt2303 = -1; + public int anInt2305 = 0; + public boolean aBoolean2306 = false; + public int anInt2308 = 0; + public int[] anIntArray2310; + public byte aByte2311 = 0; + public int anInt2312 = 0; + public Object[] anObjectArray2313; + public int anInt2314; + public int[] anIntArray2315; + public Object[] anObjectArray2316; + public byte[] aByteArray2317; + public Object[] anObjectArray2318; + public int anInt2319 = 0; + public int anInt2321 = -1; + public int height = 0; + public int[] anIntArray2323; + public int anInt2324 = 0; + public int anInt2325 = 0; + public IComponent[] aClass173Array2326; + public int[][] anIntArrayArray2327; + public Object[] anObjectArray2328; + public String aString2329 = "Ok"; + public String aString2330; + public Object[] anObjectArray2331; + public int anInt2332 = 0; + public int anInt2333 = 0; + public String aString2334 = ""; + public int anInt2335 = 0; + public Object[] anObjectArray2336; + public int[] anIntArray2337; + public int anInt2338 = 0; + public int anInt2340; + public byte aByte2341 = 0; + public boolean aBoolean2342; + public int anInt2343 = 0; + public Object[] anObjectArray2344; + public IComponent aClass173_2345 = null; + public static int anInt2346; + public int anInt2347 = 0; + public Object[] anObjectArray2348; + public int anInt2349 = -1; + public int anInt2350 = -1; + public Object[] anObjectArray2351; + public Object[] anObjectArray2352; + public boolean aBoolean2353 = false; + public boolean useScripts = false; + public byte aByte2356 = 0; + public String aString2357 = ""; + public int modelId; + public int[] anIntArray2360; + public int anInt2361 = -1; + public Object[] anObjectArray2362; + public String[] aStringArray2363; + public int anInt2364 = 0; + public int anInt2365 = -1; + public boolean aBoolean2366 = false; + public boolean aBoolean2367 = false; + public boolean aBoolean2368 = false; + public int anInt2369 = 0; + public Object[] anObjectArray2371; + public String aString2373 = ""; + public int anInt2374 = -1; + public int anInt2375 = -1; + public int imageId = -1; + public int[] anIntArray2379; + public boolean aBoolean2380 = false; + public int anInt2381 = 0; + public int anInt2382; + public short aShort2383 = 0; + public int[] anIntArray2384; + public String[] aStringArray2385; + public int anInt2386 = -1; + public int[] anIntArray2388; + public int anInt2389 = 0; + public int anInt2390 = 0; + public String aString2391 = ""; + public boolean aBoolean2393 = false; + public int anInt2394 = 1; + public Object[] anObjectArray2395; + public int anInt2396 = 0; + public int anInt2397 = 0; + public IComponentSettings settings; + public Object[] anObjectArray2399; + public int[] anIntArray2400; + public boolean aBoolean2401 = false; + public Object[] anObjectArray2402; + public int anInt2403 = 100; + public boolean hidden = false; + public Object[] anObjectArray2405; + public int[] anIntArray2407; + public Object[] anObjectArray2408; + public int anInt2409; + public Object[] anObjectArray2410; + public int anInt2411 = 0; + public int anInt2412 = 0; + public boolean aBoolean2413 = false; + public int anInt2414 = 0; + public int anInt2415 = 0; + public int modelType = 1; + public byte[] aByteArray2417; + public int[] anIntArray2418; + public boolean aBoolean2419; + public short aShort2420 = 3000; + public int anInt2421 = -1; + public boolean aBoolean2422 = false; + public int anInt2423 = 0; + public int anInt2424 = 0; + public Object[] defaultScript; + public int anInt2427 = 0; + public boolean aBoolean2429 = false; + public int[] anIntArray2431; + public int y = 0; + public int borderThickness = 0; + public boolean aBoolean2434 = false; + public int anInt2435 = 0; + public boolean aBoolean2436 = false; + public int anInt2437 = 0; + public int anInt2438 = 1; + public Object[] anObjectArray2439; + public int width = 0; + public int anInt2441 = 0; + public int anInt2442 = 0; + public int anInt2443 = -1; + public int anInt2444 = 0; + public int x = 0; + public Object[] anObjectArray2446; + public Object[] anObjectArray2447; + public int anInt2448 = -1; + public int[] anIntArray2449; + public int anInt2450 = 0; + public int anInt2451 = 0; + public int[] anIntArray2452; + public int anInt2453 = -1; + public Object[] anObjectArray2454; + public int hash = -1; + public int parentId = -1; + public int anInt2457 = -1; + public int anInt2458; + public int anInt2459 = 0; + public int anInt2461 = 0; + public Object[] anObjectArray2462; + public String aString2463 = ""; + public Object[] anObjectArray2464; + public Object[] anObjectArray2465; + public int anInt2467 = 0; + public byte aByte2469 = 0; + public int type; + public int anInt2471 = 1; + public int[] anIntArray2472; + public String aString2473; + public int anInt2474 = 2; + public Object[] anObjectArray2475; + public boolean aBoolean2476 = false; + public int anInt2477 = 0; + public int[] anIntArray2478; + public int anInt2479 = 0; + public int anInt2480 = 0; + public int anInt2481 = 1; + public int anInt2482 = 0; + public Object[] anObjectArray2483; + public int anInt2484 = 0; + public boolean aBoolean4782; + + public void decodeScriptsFormat(InputStream stream) { + this.useScripts = true; + int newInt = stream.readUnsignedByte(); + if(newInt == 255) { + newInt = -1; + } + + this.type = stream.readUnsignedByte(); + if(~(this.type & 128) != -1) { + this.type &= 127; + this.aString2473 = stream.readString(); + } + + this.anInt2441 = stream.readUnsignedShort(); + this.x = stream.readShort(); + this.y = stream.readShort(); + this.width = stream.readUnsignedShort(); + this.height = stream.readUnsignedShort(); + this.aByte2356 = (byte)stream.readByte(); + this.aByte2341 = (byte)stream.readByte(); + this.aByte2469 = (byte)stream.readByte(); + this.aByte2311 = (byte)stream.readByte(); + this.parentId = stream.readUnsignedShort(); + if(~this.parentId != -65536) { + this.parentId += this.hash & -65536; + } else { + this.parentId = -1; + } + + int i_17_ = stream.readUnsignedByte(); + this.hidden = ~(1 & i_17_) != -1; + if(newInt >= 0) { + this.aBoolean2429 = ~(i_17_ & 2) != -1; + } + + if(~this.type == -1) { + this.anInt2444 = stream.readUnsignedShort(); + this.anInt2479 = stream.readUnsignedShort(); + if(~newInt > -1) { + this.aBoolean2429 = stream.readUnsignedByte() == 1; + } + } + + int settingsHash; + if(~this.type == -6) { + this.imageId = stream.readInt(); + this.anInt2381 = stream.readUnsignedShort(); + settingsHash = stream.readUnsignedByte(); + this.aBoolean2422 = ~(2 & settingsHash) != -1; + this.aBoolean2434 = ~(settingsHash & 1) != -1; + this.anInt2369 = stream.readUnsignedByte(); + this.borderThickness = stream.readUnsignedByte(); + this.anInt2325 = stream.readInt(); + this.aBoolean2419 = ~stream.readUnsignedByte() == -2; + this.aBoolean2342 = ~stream.readUnsignedByte() == -2; + this.anInt2467 = stream.readInt(); + if(~newInt <= -4) { + this.aBoolean4782 = ~stream.readUnsignedByte() == -2; + } + } + + if(~this.type == -7) { + this.modelType = 1; + this.modelId = stream.readBigSmart(); + this.anInt2480 = stream.readShort(); + this.anInt2459 = stream.readShort(); + this.anInt2461 = stream.readUnsignedShort(); + this.anInt2482 = stream.readUnsignedShort(); + this.anInt2308 = stream.readUnsignedShort(); + this.anInt2403 = stream.readUnsignedShort(); + this.anInt2443 = stream.readUnsignedShort(); + if(this.anInt2443 == '\uffff') { + this.anInt2443 = -1; + } + + this.aBoolean2476 = stream.readUnsignedByte() == 1; + this.aShort2383 = (short)stream.readUnsignedShort(); + this.aShort2420 = (short)stream.readUnsignedShort(); + this.aBoolean2368 = stream.readUnsignedByte() == 1; + if(~this.aByte2356 != -1) { + this.anInt2423 = stream.readUnsignedShort(); + } + + if(this.aByte2341 != 0) { + this.anInt2397 = stream.readUnsignedShort(); + } + } + + if(this.type == 4) { + this.anInt2375 = stream.readBigSmart(); + if(~this.anInt2375 == -65536) { + this.anInt2375 = -1; + } + + this.aString2357 = stream.readString(); + if(this.aString2357.toLowerCase().contains("ship")) { + System.out.println(this.hash >> 16); + } + + this.anInt2364 = stream.readUnsignedByte(); + this.anInt2312 = stream.readUnsignedByte(); + this.anInt2297 = stream.readUnsignedByte(); + this.aBoolean2366 = ~stream.readUnsignedByte() == -2; + this.anInt2467 = stream.readInt(); + } + + if(this.type == 3) { + this.anInt2467 = stream.readInt(); + this.aBoolean2367 = ~stream.readUnsignedByte() == -2; + this.anInt2369 = stream.readUnsignedByte(); + } + + if(~this.type == -10) { + this.anInt2471 = stream.readUnsignedByte(); + this.anInt2467 = stream.readInt(); + this.aBoolean2306 = ~stream.readUnsignedByte() == -2; + } + + settingsHash = stream.read24BitInt(); + int i_28_ = stream.readUnsignedByte(); + int i_30_; + if(i_28_ != 0) { + this.anIntArray2449 = new int[11]; + this.aByteArray2417 = new byte[11]; + + for(this.aByteArray2317 = new byte[11]; ~i_28_ != -1; i_28_ = stream.readUnsignedByte()) { + i_30_ = -1 + (i_28_ >> 360744868); + i_28_ = i_28_ << -456693784 | stream.readUnsignedByte(); + i_28_ &= 4095; + if(~i_28_ != -4096) { + this.anIntArray2449[i_30_] = i_28_; + } else { + this.anIntArray2449[i_30_] = -1; + } + + this.aByteArray2317[i_30_] = (byte)stream.readByte(); + if(~this.aByteArray2317[i_30_] != -1) { + this.aBoolean2401 = true; + } + + this.aByteArray2417[i_30_] = (byte)stream.readByte(); + } + } + + this.aString2391 = stream.readString(); + i_30_ = stream.readUnsignedByte(); + int i_31_ = i_30_ & 15; + int i_33_; + if(~i_31_ < -1) { + this.aStringArray2385 = new String[i_31_]; + + for(i_33_ = 0; i_31_ > i_33_; ++i_33_) { + this.aStringArray2385[i_33_] = stream.readString(); + } + } + + i_33_ = i_30_ >> -686838332; + int defaultHash; + int i; + if(~i_33_ < -1) { + defaultHash = stream.readUnsignedByte(); + this.anIntArray2315 = new int[1 + defaultHash]; + + for(i = 0; i < this.anIntArray2315.length; ++i) { + this.anIntArray2315[i] = -1; + } + + this.anIntArray2315[defaultHash] = stream.readUnsignedShort(); + } + + if(~i_33_ < -2) { + defaultHash = stream.readUnsignedByte(); + this.anIntArray2315[defaultHash] = stream.readUnsignedShort(); + } + + this.aString2330 = stream.readString(); + if(this.aString2330.equals("")) { + this.aString2330 = null; + } + + this.anInt2335 = stream.readUnsignedByte(); + this.anInt2319 = stream.readUnsignedByte(); + this.aBoolean2436 = ~stream.readUnsignedByte() == -2; + this.aString2463 = stream.readString(); + defaultHash = -1; + if(~method2412(settingsHash) != -1) { + defaultHash = stream.readUnsignedShort(); + if(~defaultHash == -65536) { + defaultHash = -1; + } + + this.anInt2303 = stream.readUnsignedShort(); + if(this.anInt2303 == '\uffff') { + this.anInt2303 = -1; + } + + this.anInt2374 = stream.readUnsignedShort(); + if(this.anInt2374 == '\uffff') { + this.anInt2374 = -1; + } + } + + this.settings = new IComponentSettings(settingsHash, defaultHash); + this.defaultScript = this.decodeScript(stream); + this.anObjectArray2462 = this.decodeScript(stream); + this.anObjectArray2402 = this.decodeScript(stream); + this.anObjectArray2371 = this.decodeScript(stream); + this.anObjectArray2408 = this.decodeScript(stream); + this.anObjectArray2439 = this.decodeScript(stream); + this.anObjectArray2454 = this.decodeScript(stream); + this.anObjectArray2410 = this.decodeScript(stream); + this.anObjectArray2316 = this.decodeScript(stream); + this.anObjectArray2465 = this.decodeScript(stream); + this.anObjectArray2446 = this.decodeScript(stream); + this.anObjectArray2313 = this.decodeScript(stream); + this.anObjectArray2318 = this.decodeScript(stream); + this.anObjectArray2328 = this.decodeScript(stream); + this.anObjectArray2395 = this.decodeScript(stream); + this.anObjectArray2331 = this.decodeScript(stream); + this.anObjectArray2405 = this.decodeScript(stream); + this.anObjectArray2351 = this.decodeScript(stream); + this.anObjectArray2302 = this.decodeScript(stream); + this.anObjectArray2296 = this.decodeScript(stream); + this.anIntArray2452 = this.method2465(stream); + this.anIntArray2472 = this.method2465(stream); + this.anIntArray2360 = this.method2465(stream); + this.anIntArray2388 = this.method2465(stream); + this.anIntArray2299 = this.method2465(stream); + System.out.println("useScripts = " + this.useScripts); + System.out.println("x = " + this.x); + System.out.println("y = " + this.y); + System.out.println("width = " + this.width); + System.out.println("height = " + this.height); + System.out.println("parentId = " + this.parentId); + System.out.println("imageId = " + this.imageId); + System.out.println("modelId = " + this.modelId); + System.out.println("aString2357 = " + this.aString2357); + System.out.println("aString2391 = " + this.aString2391); + + for(i = 0; i < this.aStringArray2385.length; ++i) { + System.out.println("aStringArray2385[" + i + "] = " + this.aStringArray2385[i]); + } + + for(i = 0; i < this.anIntArray2315.length; ++i) { + System.out.println("anIntArray2315[" + i + "] = " + this.anIntArray2315[i]); + } + + System.out.println("aString2330 = " + this.aString2330); + System.out.println("aBoolean2436 = " + this.aBoolean2436); + System.out.println("aString2463 = " + this.aString2463); + System.out.println("anInt2303 = " + this.anInt2303); + System.out.println("anInt2364 = " + this.anInt2364); + + for(i = 0; i < this.anObjectArray2462.length; ++i) { + System.out.println("anObjectArray2462[" + i + "] = " + this.anObjectArray2462[i]); + } + + for(i = 0; i < this.anObjectArray2402.length; ++i) { + System.out.println("anObjectArray2402[" + i + "] = " + this.anObjectArray2402[i]); + } + + for(i = 0; i < this.anObjectArray2371.length; ++i) { + System.out.println("anObjectArray2371[" + i + "] = " + this.anObjectArray2371[i]); + } + + for(i = 0; i < this.anObjectArray2408.length; ++i) { + System.out.println("anObjectArray2408[" + i + "] = " + this.anObjectArray2408[i]); + } + + for(i = 0; i < this.anObjectArray2439.length; ++i) { + System.out.println("anObjectArray2439[" + i + "] = " + this.anObjectArray2439[i]); + } + + for(i = 0; i < this.anObjectArray2454.length; ++i) { + System.out.println("anObjectArray2454[" + i + "] = " + this.anObjectArray2454[i]); + } + + for(i = 0; i < this.anObjectArray2410.length; ++i) { + System.out.println("anObjectArray2410[" + i + "] = " + this.anObjectArray2410[i]); + } + + for(i = 0; i < this.anObjectArray2316.length; ++i) { + System.out.println("anObjectArray2316[" + i + "] = " + this.anObjectArray2316[i]); + } + + for(i = 0; i < this.anObjectArray2465.length; ++i) { + System.out.println("anObjectArray2465[" + i + "] = " + this.anObjectArray2465[i]); + } + + for(i = 0; i < this.anObjectArray2446.length; ++i) { + System.out.println("anObjectArray2446[" + i + "] = " + this.anObjectArray2446[i]); + } + + for(i = 0; i < this.anObjectArray2313.length; ++i) { + System.out.println("anObjectArray2313[" + i + "] = " + this.anObjectArray2313[i]); + } + + for(i = 0; i < this.anObjectArray2318.length; ++i) { + System.out.println("anObjectArray2318[" + i + "] = " + this.anObjectArray2318[i]); + } + + for(i = 0; i < this.anObjectArray2328.length; ++i) { + System.out.println("anObjectArray2328[" + i + "] = " + this.anObjectArray2328[i]); + } + + for(i = 0; i < this.anObjectArray2395.length; ++i) { + System.out.println("anObjectArray2395[" + i + "] = " + this.anObjectArray2395[i]); + } + + for(i = 0; i < this.anObjectArray2331.length; ++i) { + System.out.println("anObjectArray2331[" + i + "] = " + this.anObjectArray2331[i]); + } + + for(i = 0; i < this.anObjectArray2405.length; ++i) { + System.out.println("anObjectArray2405[" + i + "] = " + this.anObjectArray2405[i]); + } + + for(i = 0; i < this.anObjectArray2351.length; ++i) { + System.out.println("anObjectArray2351[" + i + "] = " + this.anObjectArray2351[i]); + } + + for(i = 0; i < this.anObjectArray2302.length; ++i) { + System.out.println("anObjectArray2302[" + i + "] = " + this.anObjectArray2302[i]); + } + + for(i = 0; i < this.anObjectArray2296.length; ++i) { + System.out.println("anObjectArray2296[" + i + "] = " + this.anObjectArray2296[i]); + } + + for(i = 0; i < this.anIntArray2452.length; ++i) { + System.out.println("anIntArray2452[" + i + "] = " + this.anIntArray2452[i]); + } + + for(i = 0; i < this.anIntArray2472.length; ++i) { + System.out.println("anIntArray2472[" + i + "] = " + this.anIntArray2472[i]); + } + + for(i = 0; i < this.anIntArray2360.length; ++i) { + System.out.println("anIntArray2360[" + i + "] = " + this.anIntArray2360[i]); + } + + for(i = 0; i < this.anIntArray2388.length; ++i) { + System.out.println("anIntArray2388[" + i + "] = " + this.anIntArray2388[i]); + } + + for(i = 0; i < this.anIntArray2299.length; ++i) { + System.out.println("anIntArray2299[" + i + "] = " + this.anIntArray2299[i]); + } + + } + + public Object[] decodeScript(InputStream stream) { + int size = stream.readUnsignedByte(); + Object[] objects = new Object[size]; + + for(int index = 0; ~size < ~index; ++index) { + int i_41_ = stream.readUnsignedByte(); + if(~i_41_ == -1) { + objects[index] = new Integer(stream.readInt()); + } else if(i_41_ == 1) { + objects[index] = stream.readString(); + } + } + + this.aBoolean2353 = true; + return objects; + } + + public int[] method2465(InputStream stream) { + int size = stream.readUnsignedByte(); + if(size == 0) { + return null; + } else { + int[] array = new int[size]; + + for(int index = 0; size > index; ++index) { + array[index] = stream.readInt(); + } + + return array; + } + } + + public void decodeNoscriptsFormat(InputStream stream) { + this.useScripts = false; + this.type = stream.readUnsignedByte(); + this.anInt2324 = stream.readUnsignedByte(); + this.anInt2441 = stream.readUnsignedShort(); + this.x = stream.readShort(); + this.y = stream.readShort(); + this.width = stream.readUnsignedShort(); + this.height = stream.readUnsignedShort(); + this.aByte2341 = 0; + this.aByte2356 = 0; + this.aByte2311 = 0; + this.aByte2469 = 0; + this.anInt2369 = stream.readUnsignedByte(); + this.parentId = stream.readUnsignedShort(); + if(~this.parentId == -65536) { + this.parentId = -1; + } else { + this.parentId += this.hash & -65536; + } + + this.anInt2448 = stream.readUnsignedShort(); + if(~this.anInt2448 == -65536) { + this.anInt2448 = -1; + } + + int i = stream.readUnsignedByte(); + int i_1_; + if(~i < -1) { + this.anIntArray2407 = new int[i]; + this.anIntArray2384 = new int[i]; + + for(i_1_ = 0; i > i_1_; ++i_1_) { + this.anIntArray2384[i_1_] = stream.readUnsignedByte(); + this.anIntArray2407[i_1_] = stream.readUnsignedShort(); + } + } + + i_1_ = stream.readUnsignedByte(); + int i_5_; + int is; + int i_13_; + if(~i_1_ < -1) { + this.anIntArrayArray2327 = new int[i_1_][]; + + for(i_5_ = 0; ~i_1_ < ~i_5_; ++i_5_) { + is = stream.readUnsignedShort(); + this.anIntArrayArray2327[i_5_] = new int[is]; + + for(i_13_ = 0; ~is < ~i_13_; ++i_13_) { + this.anIntArrayArray2327[i_5_][i_13_] = stream.readUnsignedShort(); + if(~this.anIntArrayArray2327[i_5_][i_13_] == -65536) { + this.anIntArrayArray2327[i_5_][i_13_] = -1; + } + } + } + } + + if(~this.type == -1) { + this.anInt2479 = stream.readUnsignedShort(); + this.hidden = stream.readUnsignedByte() == 1; + } + + if(this.type == 1) { + stream.readUnsignedShort(); + stream.readUnsignedByte(); + } + + i_5_ = 0; + if(~this.type == -3) { + this.anIntArray2400 = new int[this.height * this.width]; + this.aByte2341 = 3; + this.anIntArray2418 = new int[this.height * this.width]; + this.aByte2356 = 3; + is = stream.readUnsignedByte(); + if(is == 1) { + i_5_ |= 268435456; + } + + i_13_ = stream.readUnsignedByte(); + if(i_13_ == 1) { + i_5_ |= 1073741824; + } + + int var10 = stream.readUnsignedByte(); + stream.readUnsignedByte(); + if(~var10 == -2) { + i_5_ |= Integer.MIN_VALUE; + } + + this.anInt2332 = stream.readUnsignedByte(); + this.anInt2414 = stream.readUnsignedByte(); + this.anIntArray2337 = new int[20]; + this.anIntArray2323 = new int[20]; + this.anIntArray2431 = new int[20]; + + int i_11_; + for(i_11_ = 0; i_11_ < 20; ++i_11_) { + int var12 = stream.readUnsignedByte(); + if(~var12 != -2) { + this.anIntArray2431[i_11_] = -1; + } else { + this.anIntArray2323[i_11_] = stream.readShort(); + this.anIntArray2337[i_11_] = stream.readShort(); + this.anIntArray2431[i_11_] = stream.readInt(); + } + } + + this.aStringArray2363 = new String[5]; + + for(i_11_ = 0; i_11_ < 5; ++i_11_) { + String var121 = stream.readString(); + if(~var121.length() < -1) { + this.aStringArray2363[i_11_] = var121; + i_5_ |= 1 << 23 + i_11_; + } + } + } + + if(~this.type == -4) { + this.aBoolean2367 = ~stream.readUnsignedByte() == -2; + } + + if(~this.type == -5 || this.type == 1) { + this.anInt2312 = stream.readUnsignedByte(); + this.anInt2297 = stream.readUnsignedByte(); + this.anInt2364 = stream.readUnsignedByte(); + this.anInt2375 = stream.readUnsignedShort(); + if(~this.anInt2375 == -65536) { + this.anInt2375 = -1; + } + + this.aBoolean2366 = stream.readUnsignedByte() == 1; + } + + if(~this.type == -5) { + this.aString2357 = stream.readString(); + this.aString2334 = stream.readString(); + } + + if(this.type == 1 || ~this.type == -4 || this.type == 4) { + this.anInt2467 = stream.readInt(); + } + + if(this.type == 3 || this.type == 4) { + this.anInt2424 = stream.readInt(); + this.anInt2451 = stream.readInt(); + this.anInt2477 = stream.readInt(); + } + + if(~this.type == -6) { + this.imageId = stream.readInt(); + this.anInt2349 = stream.readInt(); + } + + if(~this.type == -7) { + this.modelType = 1; + this.modelId = stream.readUnsignedShort(); + this.anInt2301 = 1; + if(this.modelId == '\uffff') { + this.modelId = -1; + } + + this.anInt2386 = stream.readUnsignedShort(); + if(~this.anInt2386 == -65536) { + this.anInt2386 = -1; + } + + this.anInt2443 = stream.readUnsignedShort(); + if(this.anInt2443 == '\uffff') { + this.anInt2443 = -1; + } + + this.anInt2298 = stream.readUnsignedShort(); + if(this.anInt2298 == '\uffff') { + this.anInt2298 = -1; + } + + this.anInt2403 = stream.readUnsignedShort(); + this.anInt2461 = stream.readUnsignedShort(); + this.anInt2482 = stream.readUnsignedShort(); + } + + if(~this.type == -8) { + this.aByte2341 = 3; + this.anIntArray2418 = new int[this.width * this.height]; + this.aByte2356 = 3; + this.anIntArray2400 = new int[this.width * this.height]; + this.anInt2312 = stream.readUnsignedByte(); + this.anInt2375 = stream.readUnsignedShort(); + if(this.anInt2375 == '\uffff') { + this.anInt2375 = -1; + } + + this.aBoolean2366 = stream.readUnsignedByte() == 1; + this.anInt2467 = stream.readInt(); + this.anInt2332 = stream.readShort(); + this.anInt2414 = stream.readShort(); + is = stream.readUnsignedByte(); + if(~is == -2) { + i_5_ |= 1073741824; + } + + this.aStringArray2363 = new String[5]; + + for(i_13_ = 0; i_13_ < 5; ++i_13_) { + String var101 = stream.readString(); + if(var101.length() > 0) { + this.aStringArray2363[i_13_] = var101; + i_5_ |= 1 << i_13_ + 23; + } + } + } + + if(~this.type == -9) { + this.aString2357 = stream.readString(); + } + + if(this.anInt2324 == 2 || ~this.type == -3) { + this.aString2463 = stream.readString(); + this.aString2373 = stream.readString(); + is = 63 & stream.readUnsignedShort(); + i_5_ |= is << -116905845; + } + + if(~this.anInt2324 == -2 || ~this.anInt2324 == -5 || this.anInt2324 == 5 || this.anInt2324 == 6) { + this.aString2329 = stream.readString(); + if(~this.aString2329.length() == -1) { + if(~this.anInt2324 == -2) { + this.aString2329 = "Ok"; + } + + if(~this.anInt2324 == -5) { + this.aString2329 = "Select"; + } + + if(~this.anInt2324 == -6) { + this.aString2329 = "Select"; + } + + if(~this.anInt2324 == -7) { + this.aString2329 = "Continue"; + } + } + } + + if(this.anInt2324 == 1 || this.anInt2324 == 4 || ~this.anInt2324 == -6) { + i_5_ |= 4194304; + } + + if(~this.anInt2324 == -7) { + i_5_ |= 1; + } + + this.settings = new IComponentSettings(i_5_, -1); + System.out.println("useScripts = " + this.useScripts); + System.out.println("type = " + this.type); + System.out.println("anInt2324 = " + this.anInt2324); + System.out.println("anInt2441 = " + this.anInt2441); + System.out.println("x = " + this.x); + System.out.println("y = " + this.y); + System.out.println("width = " + this.width); + System.out.println("height = " + this.height); + System.out.println("anInt2369 = " + this.anInt2369); + System.out.println("parentId = " + this.parentId); + System.out.println("anInt2448 = " + this.anInt2448); + + byte var11; + for(var11 = 0; var11 < this.anIntArray2407.length; ++i) { + System.out.println("anIntArray2407[" + var11 + "] = " + this.anIntArray2407[var11]); + } + + for(var11 = 0; var11 < this.aStringArray2363.length; ++i) { + System.out.println("aStringArray2363[" + var11 + "] = " + this.aStringArray2363[var11]); + } + + } + + public static int method2412(int arg0) { + return 127 & arg0 >> -809958741; + } +} diff --git a/Tools/Frostys Cache Editor/src/com/alex/loaders/interfaces/IComponentSettings.java b/Tools/Frostys Cache Editor/src/com/alex/loaders/interfaces/IComponentSettings.java new file mode 100644 index 0000000..4070eb6 --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/loaders/interfaces/IComponentSettings.java @@ -0,0 +1,11 @@ +package com.alex.loaders.interfaces; + +public final class IComponentSettings { + public int settingsHash; + public int defaultHash; + + public IComponentSettings(int settingsHash, int defaultHash) { + this.settingsHash = settingsHash; + this.defaultHash = defaultHash; + } +} diff --git a/Tools/Frostys Cache Editor/src/com/alex/loaders/interfaces/Interface.java b/Tools/Frostys Cache Editor/src/com/alex/loaders/interfaces/Interface.java new file mode 100644 index 0000000..3995115 --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/loaders/interfaces/Interface.java @@ -0,0 +1,77 @@ +package com.alex.loaders.interfaces; + +import com.alex.io.InputStream; +import com.alex.loaders.interfaces.IComponent; +import com.alex.store.Store; +import com.alex.utils.Utils; + +import java.awt.image.FilteredImageSource; +import java.awt.image.ReplicateScaleFilter; +import java.io.IOException; + +public class Interface { + public int id; + public Store cache; + public IComponent[] components; + public JComponent[] jcomponents; + + public static void main(String[] args) throws IOException { + Store rscache = new Store("cache/"); + + for(int i = 0; i < Utils.getInterfaceDefinitionsSize(rscache); ++i) { + try { + new Interface(i, rscache); + } catch (Throwable var4) { + ; + } + } + + } + + public Interface(int id, Store cache) { + this(id, cache, true); + } + + public Interface(int id, Store cache, boolean load) { + this.id = id; + this.cache = cache; + if(load) { + this.getComponents(); + } + + } + + public void draw(JComponent parent) { + } + + public Image resizeImage(Image image, int width, int height, Component c) { + ReplicateScaleFilter replicate = new ReplicateScaleFilter(width, height); + FilteredImageSource prod = new FilteredImageSource(image.getSource(), replicate); + return c.createImage(prod); + } + + public void getComponents() { + if(Utils.getInterfaceDefinitionsSize(this.cache) <= this.id) { + throw new RuntimeException("Invalid interface id."); + } else { + this.components = new IComponent[Utils.getInterfaceDefinitionsComponentsSize(this.cache, this.id)]; + + for(int componentId = 0; componentId < this.components.length; ++componentId) { + this.components[componentId] = new IComponent(); + this.components[componentId].hash = this.id << 16 | componentId; + byte[] data = this.cache.getIndexes()[3].getFile(this.id, componentId); + if(data == null) { + throw new RuntimeException("Interface " + this.id + ", component " + componentId + " data is null."); + } + + System.out.println("Interface: " + this.id + " - ComponentId: " + componentId); + if(data[0] != -1) { + this.components[componentId].decodeNoscriptsFormat(new InputStream(data)); + } else { + this.components[componentId].decodeScriptsFormat(new InputStream(data)); + } + } + + } + } +} diff --git a/Tools/Frostys Cache Editor/src/com/alex/loaders/interfaces/InterfaceName.java b/Tools/Frostys Cache Editor/src/com/alex/loaders/interfaces/InterfaceName.java new file mode 100644 index 0000000..4deff52 --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/loaders/interfaces/InterfaceName.java @@ -0,0 +1,60 @@ +package com.alex.loaders.interfaces; + +import com.alex.store.Store; +import com.alex.utils.Utils; + +import java.io.IOException; + +public class InterfaceName { + public static final char[] VALID_CHARS = new char[]{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}; + + public static void printAllCombinations4Letters() { + } + + public static void main(String[] args) throws IOException { + Store rscache = new Store("C:/Users/yvonne � christer/Dropbox/Source/data/562cache/", false); + int hash = rscache.getIndexes()[3].getTable().getArchives()[884].getNameHash(); + char[] arr$ = VALID_CHARS; + int len$ = arr$.length; + + for(int i$ = 0; i$ < len$; ++i$) { + char l1 = arr$[i$]; + System.out.println(l1); + char[] arr$1 = VALID_CHARS; + int len$1 = arr$1.length; + + for(int i$1 = 0; i$1 < len$1; ++i$1) { + char l2 = arr$1[i$1]; + char[] arr$2 = VALID_CHARS; + int len$2 = arr$2.length; + + for(int i$2 = 0; i$2 < len$2; ++i$2) { + char l3 = arr$2[i$2]; + char[] arr$3 = VALID_CHARS; + int len$3 = arr$3.length; + + for(int i$3 = 0; i$3 < len$3; ++i$3) { + char l4 = arr$3[i$3]; + char[] arr$4 = VALID_CHARS; + int len$4 = arr$4.length; + + for(int i$4 = 0; i$4 < len$4; ++i$4) { + char l5 = arr$4[i$4]; + char[] arr$5 = VALID_CHARS; + int len$5 = arr$5.length; + + for(int i$5 = 0; i$5 < len$5; ++i$5) { + char l6 = arr$5[i$5]; + String name = new String(new char[]{l1, l2, l3, l4, l5, l6}); + if(Utils.getNameHash(name) == hash) { + System.out.println(name); + } + } + } + } + } + } + } + + } +} diff --git a/Tools/Frostys Cache Editor/src/com/alex/loaders/items/ItemDefinitions.java b/Tools/Frostys Cache Editor/src/com/alex/loaders/items/ItemDefinitions.java new file mode 100644 index 0000000..7ff32f6 --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/loaders/items/ItemDefinitions.java @@ -0,0 +1,1072 @@ +package com.alex.loaders.items; + +import com.alex.io.InputStream; +import com.alex.io.OutputStream; +import com.alex.store.Store; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; + +public class ItemDefinitions implements Cloneable { + public int id; + public boolean loaded; + public int modelId; + public String name; + public int modelZoom; + public int modelRotation1; + public int modelRotation2; + public int modelOffset1; + public int modelOffset2; + public int opcode1; + public int opcode2; + public int opcode4; + public int opcode5; + public int opcode6; + public int opcode7; + public int opcode8; + public int opcode11; + public int opcode12; + public int opcode14; + public int opcode16; + public int opcode22; + public int opcode23; + public int opcode24; + public int opcode25; + public int opcode26; + public int opcode29; + public int opcode30; + public int opcode31; + public int opcode32; + public int opcode33; + public int opcode34; + public int opcode35; + public int opcode36; + public int opcode37; + public int opcode38; + public int opcode39; + public int opcode40; + public int opcode41; + public int opcode42; + public int opcode65; + public int opcode78; + public int opcode79; + public int opcode90; + public int opcode91; + public int opcode92; + public int opcode93; + public int opcode95; + public int opcode96; + public int opcode97; + public int opcode98; + public int opcode100; + public int opcode101; + public int opcode102; + public int opcode103; + public int opcode104; + public int opcode105; + public int opcode106; + public int opcode107; + public int opcode108; + public int opcode109; + public int opcode110; + public int opcode111; + public int opcode112; + public int opcode113; + public int opcode114; + public int opcode115; + public int opcode121; + public int opcode122; + public int opcode125; + public int opcode126; + public int opcode127; + public int opcode128; + public int opcode129; + public int opcode130; + public int opcode132; + public int opcode139; + public int opcode140; + public int opcode191; + public int opcode249; + public int equipSlot; + public int equipType; + public int stackable; + public int value; + public boolean membersOnly; + public int maleEquip1; + public int femaleEquip1; + public int maleEquip2; + public int femaleEquip2; + public int maleEquipModelId3; + public int femaleEquipModelId3; + public String[] groundOptions; + public String[] inventoryOptions; + public int[] originalModelColors; + public int[] modifiedModelColors; + public short[] originalTextureColors; + public short[] modifiedTextureColors; + public byte[] unknownArray1; + public int[] unknownArray2; + public int[] unknownArray4; + public int[] unknownArray5; + public byte[] unknownArray6; + public byte[] unknownArray3; + public boolean unnoted; + public int unknownInt1; + public int unknownInt2; + public int unknownInt3; + public int unknownInt4; + public int unknownInt5; + public int unknownInt6; + public int switchNoteItemId; + public int notedItemId; + public int[] stackIds; + public int[] stackAmounts; + public int unknownInt7; + public int unknownInt8; + public int unknownInt9; + public int unknownInt10; + public int unknownInt11; + public int teamId; + public int switchLendItemId; + public int lendedItemId; + public int unknownInt12; + public int unknownInt13; + public int unknownInt14; + public int unknownInt15; + public int unknownInt16; + public int unknownInt17; + public int unknownInt18; + public int unknownInt19; + public int unknownInt20; + public int unknownInt21; + public int unknownInt22; + public int unknownInt23; + public int unknownValue1; + public int unknownValue2; + private int opcode218; + private int opcode219; + public HashMap clientScriptData; + + public static ItemDefinitions getItemDefinition(Store cache, int itemId) { + return getItemDefinition(cache, itemId, true); + } + + public static ItemDefinitions getItemDefinition(Store cache, int itemId, boolean load) { + return new ItemDefinitions(cache, itemId, load); + } + + public ItemDefinitions(Store cache, int id) { + this(cache, id, true); + } + + public ItemDefinitions(Store cache, int id, boolean load) { + this.id = id; + this.setDefaultsVariableValules(); + this.setDefaultOptions(); + if(load) { + this.loadItemDefinition(cache); + } + + } + + public boolean isLoaded() { + return this.loaded; + } + + public int getValue() { + return this.value; + } + + public int getTeamId() { + return this.teamId; + } + + public int getStackable() { + return this.stackable; + } + + public boolean isUnnoted() { + return this.unnoted; + } + + public int getLendedItemId() { + return this.lendedItemId; + } + + public int getModelRotation1() { + return this.modelRotation1; + } + + public void setModelRotation1(int modelRotation1) { + this.modelRotation1 = modelRotation1; + } + + public int getModelRotation2() { + return this.modelRotation2; + } + + public void setModelRotation2(int modelRotation2) { + this.modelRotation2 = modelRotation2; + } + + public int getModelOffset1() { + return this.modelOffset1; + } + + public void setModelOffset1(int modelOffset1) { + this.modelOffset1 = modelOffset1; + } + + public int getModelOffset2() { + return this.modelOffset2; + } + + public void setModelOffset2(int modelOffset2) { + this.modelOffset2 = modelOffset2; + } + + public int getMaleEquipModelId1() { + return this.maleEquip1; + } + + public void setMaleEquipModelId1(int maleEquipModelId1) { + this.maleEquip1 = maleEquipModelId1; + } + + public int getFemaleEquipModelId1() { + return this.femaleEquip1; + } + + public void setFemaleEquipModelId1(int femaleEquipModelId1) { + this.femaleEquip1 = femaleEquipModelId1; + } + + public int getMaleEquipModelId2() { + return this.maleEquip2; + } + + public void setMaleEquipModelId2(int maleEquipModelId2) { + this.maleEquip2 = maleEquipModelId2; + } + + public int getFemaleEquipModelId2() { + return this.femaleEquip2; + } + + public void setFemaleEquipModelId2(int femaleEquipModelId2) { + this.femaleEquip2 = femaleEquipModelId2; + } + + public int getMaleEquipModelId3() { + return this.maleEquipModelId3; + } + + public void setMaleEquipModelId3(int maleEquipModelId3) { + this.maleEquipModelId3 = maleEquipModelId3; + } + + public int getFemaleEquipModelId3() { + return this.femaleEquipModelId3; + } + + public void setFemaleEquipModelId3(int femaleEquipModelId3) { + this.femaleEquipModelId3 = femaleEquipModelId3; + } + + public int[] getOriginalModelColors() { + return this.originalModelColors; + } + + public void setOriginalModelColors(int[] originalModelColors) { + this.originalModelColors = originalModelColors; + } + + public int[] getModifiedModelColors() { + return this.modifiedModelColors; + } + + public void setModifiedModelColors(int[] modifiedModelColors) { + this.modifiedModelColors = modifiedModelColors; + } + + public int[] getStackAmounts() { + return this.stackAmounts; + } + + public void setStackAmounts(int[] stackAmounts) { + this.stackAmounts = stackAmounts; + } + + public int[] getStackIds() { + return this.stackIds; + } + + public void setStackIds(int[] stackIds) { + this.stackIds = stackIds; + } + + public void setStackable(int stackable) { + this.stackable = stackable; + } + + public void setValue(int value) { + this.value = value; + } + + public void setTeamId(int teamId) { + this.teamId = teamId; + } + + public void setMembersOnly(boolean membersOnly) { + this.membersOnly = membersOnly; + } + + public void setUnnoted(boolean unnoted) { + this.unnoted = unnoted; + } + + public void setEquipSlot(int equipSlot) { + this.equipSlot = equipSlot; + } + + public void setEquipType(int equipType) { + this.equipType = equipType; + } + + public int getSwitchLendItemId() { + return this.switchLendItemId; + } + + public void setSwitchLendItemId(int switchLendItemId) { + this.switchLendItemId = switchLendItemId; + } + + public void setLendedItemId(int lendedItemId) { + this.lendedItemId = lendedItemId; + } + + public int getId() { + return this.id; + } + + public void setId(int id) { + this.id = id; + } + + public void write(Store store) { + store.getIndexes()[19].putFile(this.getArchiveId(), this.getFileId(), this.encode()); + } + + private void loadItemDefinition(Store cache) { + byte[] data = cache.getIndexes()[19].getFile(this.getArchiveId(), this.getFileId()); + if(data != null) { + try { + this.readOpcodeValues(new InputStream(data)); + } catch (RuntimeException var4) { + var4.printStackTrace(); + } + + if(this.notedItemId != -1) { + this.toNote(cache); + } + + if(this.lendedItemId != -1) { + this.toLend(cache); + } + + this.loaded = true; + } + } + + private void toNote(Store store) { + ItemDefinitions realItem = getItemDefinition(store, this.switchNoteItemId); + this.membersOnly = realItem.membersOnly; + this.value = realItem.value; + this.name = realItem.name; + this.stackable = 1; + } + + private void toLend(Store store) { + ItemDefinitions realItem = getItemDefinition(store, this.switchLendItemId); + this.originalModelColors = realItem.originalModelColors; + this.modifiedModelColors = realItem.modifiedModelColors; + this.teamId = realItem.teamId; + this.value = 0; + this.membersOnly = realItem.membersOnly; + this.name = realItem.name; + this.inventoryOptions = new String[5]; + this.groundOptions = realItem.groundOptions; + if(realItem.inventoryOptions != null) { + for(int optionIndex = 0; optionIndex < 4; ++optionIndex) { + this.inventoryOptions[optionIndex] = realItem.inventoryOptions[optionIndex]; + } + } + + this.inventoryOptions[4] = "Discard"; + this.maleEquip1 = realItem.maleEquip1; + this.maleEquip2 = realItem.maleEquip2; + this.femaleEquip1 = realItem.femaleEquip1; + this.femaleEquip2 = realItem.femaleEquip2; + this.maleEquipModelId3 = realItem.maleEquipModelId3; + this.femaleEquipModelId3 = realItem.femaleEquipModelId3; + this.equipType = realItem.equipType; + this.equipSlot = realItem.equipSlot; + } + + public int getArchiveId() { + return this.id >>> 8; + } + + public int getFileId() { + return 0xff & this.id; + } + + public boolean hasSpecialBar() { + if(this.clientScriptData == null) { + return false; + } else { + Object specialBar = this.clientScriptData.get(Integer.valueOf(686)); + return specialBar != null && specialBar instanceof Integer && ((Integer)specialBar).intValue() == 1; + } + } + + public int getRenderAnimId() { + if(this.clientScriptData == null) { + return 1426; + } else { + Object animId = this.clientScriptData.get(Integer.valueOf(644)); + return animId != null && animId instanceof Integer?((Integer)animId).intValue():1426; + } + } + + public int getQuestId() { + if(this.clientScriptData == null) { + return -1; + } else { + System.out.println(this.clientScriptData.toString()); + Object questId = this.clientScriptData.get(Integer.valueOf(861)); + return questId != null && questId instanceof Integer?((Integer)questId).intValue():-1; + } + } + + public HashMap getWearingSkillRequiriments() { + if(this.clientScriptData == null) { + return null; + } else { + HashMap skills = new HashMap(); + int nextLevel = -1; + int nextSkill = -1; + Iterator var5 = this.clientScriptData.keySet().iterator(); + + while(var5.hasNext()) { + int key = ((Integer)var5.next()).intValue(); + Object value = this.clientScriptData.get(Integer.valueOf(key)); + if(!(value instanceof String)) { + if(key == 23) { + skills.put(Integer.valueOf(4), (Integer)value); + skills.put(Integer.valueOf(11), Integer.valueOf(61)); + } else if(key >= 749 && key < 797) { + if(key % 2 == 0) { + nextLevel = ((Integer)value).intValue(); + } else { + nextSkill = ((Integer)value).intValue(); + } + + if(nextLevel != -1 && nextSkill != -1) { + skills.put(Integer.valueOf(nextSkill), Integer.valueOf(nextLevel)); + nextLevel = -1; + nextSkill = -1; + } + } + } + } + + return skills; + } + } + + public void printClientScriptData() { + Iterator key2 = this.clientScriptData.keySet().iterator(); + + while(key2.hasNext()) { + int requiriments = ((Integer)key2.next()).intValue(); + Object value = this.clientScriptData.get(Integer.valueOf(requiriments)); + System.out.println("KEY: " + requiriments + ", VALUE: " + value); + } + + HashMap requiriments1 = this.getWearingSkillRequiriments(); + if(requiriments1 == null) { + System.out.println("null."); + } else { + System.out.println(requiriments1.keySet().size()); + Iterator value1 = requiriments1.keySet().iterator(); + + while(value1.hasNext()) { + int key21 = ((Integer)value1.next()).intValue(); + Object value2 = requiriments1.get(Integer.valueOf(key21)); + System.out.println("SKILL: " + key21 + ", LEVEL: " + value2); + } + + } + } + + private void setDefaultOptions() { + this.groundOptions = new String[]{null, null, "take", null, null}; + this.inventoryOptions = new String[]{null, null, null, null, "drop"}; + } + + private void setDefaultsVariableValules() { + this.name = "null"; + this.maleEquip1 = -1; + this.maleEquip2 = -1; + this.femaleEquip1 = -1; + this.femaleEquip2 = -1; + this.modelZoom = 2000; + this.switchLendItemId = -1; + this.lendedItemId = -1; + this.switchNoteItemId = -1; + this.notedItemId = -1; + this.unknownInt9 = 128; + this.value = 1; + this.maleEquipModelId3 = -1; + this.femaleEquipModelId3 = -1; + this.teamId = -1; + this.equipType = -1; + this.equipSlot = -1; + } + + public byte[] encode() { + OutputStream stream = new OutputStream(); + stream.writeByte(1); + stream.writeBigSmart(this.modelId); + if(!this.name.equals("null") && this.notedItemId == -1) { + stream.writeByte(2); + stream.writeString(this.name); + } + + if(this.modelZoom != 2000) { + stream.writeByte(4); + stream.writeShort(this.modelZoom); + } + + if(this.modelRotation1 != 0) { + stream.writeByte(5); + stream.writeShort(this.modelRotation1); + } + + if(this.modelRotation2 != 0) { + stream.writeByte(6); + stream.writeShort(this.modelRotation2); + } + + int data; + int value; + if(this.modelOffset1 != 0) { + stream.writeByte(7); + data = this.modelOffset1 >> 0; + this.modelOffset1 = data; + value = data; + if(data < 0) { + value = data + 65536; + } + + stream.writeShort(value); + } + + if(this.modelOffset2 != 0) { + stream.writeByte(8); + data = this.modelOffset2 >> 0; + this.modelOffset2 = data; + value = data; + if(data < 0) { + value = data + 65536; + } + + stream.writeShort(value); + } + + if(this.stackable >= 1 && this.notedItemId == -1) { + stream.writeByte(11); + } + + if(this.value != 1 && this.lendedItemId == -1) { + stream.writeByte(12); + stream.writeInt(this.value); + } + + if(this.equipSlot != -1) { + stream.writeByte(13); + stream.writeByte(this.equipSlot); + } + + if(this.equipType != -1) { + stream.writeByte(14); + stream.writeByte(this.equipType); + } + + if(this.membersOnly && this.notedItemId == -1) { + stream.writeByte(16); + } + + if(this.maleEquip1 != -1) { + stream.writeByte(23); + stream.writeBigSmart(this.maleEquip1); + } + + if(this.maleEquip2 != -1) { + stream.writeByte(24); + stream.writeBigSmart(this.maleEquip2); + } + + if(this.femaleEquip1 != -1) { + stream.writeByte(25); + stream.writeBigSmart(this.femaleEquip1); + } + + if(this.femaleEquip2 != -1) { + stream.writeByte(26); + stream.writeBigSmart(this.femaleEquip2); + } + + for(data = 0; data < 4; ++data) { + if(this.groundOptions[data] != null && (data != 2 || !this.groundOptions[data].equals("take"))) { + stream.writeByte(30 + data); + stream.writeString(this.groundOptions[data]); + } + } + + for(data = 0; data < 4; ++data) { + if(this.inventoryOptions[data] != null && (data != 4 || !this.inventoryOptions[data].equals("drop"))) { + stream.writeByte(35 + data); + stream.writeString(this.inventoryOptions[data]); + } + } + + if(this.originalModelColors != null && this.modifiedModelColors != null) { + stream.writeByte(40); + stream.writeByte(this.originalModelColors.length); + + for(data = 0; data < this.originalModelColors.length; ++data) { + stream.writeShort(this.originalModelColors[data]); + stream.writeShort(this.modifiedModelColors[data]); + } + } + + if(this.originalTextureColors != null && this.modifiedTextureColors != null) { + stream.writeByte(41); + stream.writeByte(this.originalTextureColors.length); + + for(data = 0; data < this.originalTextureColors.length; ++data) { + stream.writeShort(this.originalTextureColors[data]); + stream.writeShort(this.modifiedTextureColors[data]); + } + } + + if(this.unknownArray1 != null) { + stream.writeByte(42); + stream.writeByte(this.unknownArray1.length); + + for(data = 0; data < this.unknownArray1.length; ++data) { + stream.writeByte(this.unknownArray1[data]); + } + } + + if(this.unnoted) { + stream.writeByte(65); + } + + if(this.maleEquipModelId3 != -1) { + stream.writeByte(78); + stream.writeBigSmart(this.maleEquipModelId3); + } + + if(this.femaleEquipModelId3 != -1) { + stream.writeByte(79); + stream.writeBigSmart(this.femaleEquipModelId3); + } + + if(this.switchNoteItemId != -1) { + stream.writeByte(97); + stream.writeShort(this.switchNoteItemId); + } + + if(this.notedItemId != -1) { + stream.writeByte(98); + stream.writeShort(this.notedItemId); + } + + if(this.stackIds != null && this.stackAmounts != null) { + for(data = 0; data < this.stackIds.length; ++data) { + if(this.stackIds[data] != 0 || this.stackAmounts[data] != 0) { + stream.writeByte(100 + data); + stream.writeShort(this.stackIds[data]); + stream.writeShort(this.stackAmounts[data]); + } + } + } + + if(this.teamId != 0) { + stream.writeByte(115); + stream.writeByte(this.teamId); + } + + if(this.switchLendItemId != -1) { + stream.writeByte(121); + stream.writeShort(this.switchLendItemId); + } + + if(this.lendedItemId != -1) { + stream.writeByte(122); + stream.writeShort(this.lendedItemId); + } + + if(this.unknownArray2 != null) { + stream.writeByte(132); + stream.writeByte(this.unknownArray2.length); + + for(data = 0; data < this.unknownArray2.length; ++data) { + stream.writeShort(this.unknownArray2[data]); + } + } + + if(this.clientScriptData != null) { + stream.writeByte(249); + stream.writeByte(this.clientScriptData.size()); + Iterator var5 = this.clientScriptData.keySet().iterator(); + + while(var5.hasNext()) { + data = ((Integer)var5.next()).intValue(); + Object value2 = this.clientScriptData.get(Integer.valueOf(data)); + stream.writeByte(value2 instanceof String?1:0); + stream.write24BitInt(data); + if(value2 instanceof String) { + stream.writeString((String)value2); + } else { + stream.writeInt(((Integer)value2).intValue()); + } + } + } + + stream.writeByte(0); + byte[] var6 = new byte[stream.getOffset()]; + stream.setOffset(0); + stream.getBytes(var6, 0, var6.length); + return var6; + } + + public int getInvModelId() { + return this.modelId; + } + + public void setInvModelId(int modelId) { + this.modelId = modelId; + } + + public int getInvModelZoom() { + return this.modelZoom; + } + + public void setInvModelZoom(int modelZoom) { + this.modelZoom = modelZoom; + } + + private final void readValues(InputStream stream, int opcode) { + if(opcode == 1) { + this.modelId = stream.readUnsignedShort();//stream.readBigSmart(); + } else if(opcode == 2) { + this.name = stream.readString(); + } else if(opcode == 4) { + this.modelZoom = stream.readUnsignedShort(); + } else if(opcode == 5) { + this.modelRotation1 = stream.readUnsignedShort(); + } else if(opcode == 6) { + this.modelRotation2 = stream.readUnsignedShort(); + } else if(opcode == 7) { + this.modelOffset1 = stream.readUnsignedShort(); + if(this.modelOffset1 > 52767) { + //if(this.modelOffset1 > 32767) { + this.modelOffset1 -= 65536; + } + + this.modelOffset1 <<= 0; + } else if(opcode == 8) { + this.modelOffset2 = stream.readUnsignedShort(); + if(this.modelOffset2 > 52767) { + //if(this.modelOffset2 > 32767) { + this.modelOffset2 -= 65536; + } + + this.modelOffset2 <<= 0; + } else if(opcode == 11) { + this.stackable = 1; + } else if(opcode == 12) { + this.value = stream.readInt(); + } else if(opcode == 13) { + this.equipSlot = stream.readUnsignedByte(); + } else if(opcode == 14) { + this.equipType = stream.readUnsignedByte(); + } else if(opcode == 16) { + this.membersOnly = true; + } else if(opcode == 18) { + stream.readUnsignedShortLE(); + } else if(opcode == 23) { + this.maleEquip1 = stream.readUnsignedShort();//stream.readBigSmart(); + } else if(opcode == 24) { + this.maleEquip2 = stream.readUnsignedShort();//stream.readBigSmart(); + } else if(opcode == 25) { + this.femaleEquip1 = stream.readUnsignedShort();//stream.readBigSmart(); + } else if(opcode == 26) { + this.femaleEquip2 = stream.readUnsignedShort();//stream.readBigSmart(); + } else if(opcode == 27) { + stream.readUnsignedByte(); + } else if(opcode >= 30 && opcode < 35) { + this.groundOptions[opcode - 30] = stream.readString(); + } else if(opcode >= 35 && opcode < 40) { + this.inventoryOptions[opcode - 35] = stream.readString(); + } else { + int length; + int index; + if(opcode == 40) { + length = stream.readUnsignedByte(); + this.originalModelColors = new int[length]; + this.modifiedModelColors = new int[length]; + + for(index = 0; index < length; ++index) { + this.originalModelColors[index] = stream.readUnsignedShort(); + this.modifiedModelColors[index] = stream.readUnsignedShort(); + } + } else if(opcode == 41) { + length = stream.readUnsignedByte(); + this.originalTextureColors = new short[length]; + this.modifiedTextureColors = new short[length]; + + for(index = 0; index < length; ++index) { + this.originalTextureColors[index] = (short)stream.readUnsignedShort(); + this.modifiedTextureColors[index] = (short)stream.readUnsignedShort(); + } + } else if(opcode == 42) { + length = stream.readUnsignedByte(); + this.unknownArray1 = new byte[length]; + + for(index = 0; index < length; ++index) { + this.unknownArray1[index] = (byte)stream.readByte(); + } + } else if(opcode == 65) { + this.unnoted = true; + } else if(opcode == 78) { + this.maleEquipModelId3 = stream.readUnsignedShort();//stream.readBigSmart(); + } else if(opcode == 79) { + this.femaleEquipModelId3 = stream.readUnsignedShort();//stream.readBigSmart(); + } else if(opcode == 90) { + this.unknownInt1 = stream.readUnsignedShort();//stream.readBigSmart(); + } else if(opcode == 91) { + this.unknownInt2 = stream.readUnsignedShort();//stream.readBigSmart(); + } else if(opcode == 92) { + this.unknownInt3 = stream.readUnsignedShort();//stream.readBigSmart(); + } else if(opcode == 93) { + this.unknownInt4 = stream.readUnsignedShort();//stream.readBigSmart(); + } else if(opcode == 95) { + this.unknownInt5 = stream.readUnsignedShort(); + } else if(opcode == 96) { + this.unknownInt6 = stream.readUnsignedByte(); + } else if(opcode == 97) { + this.switchNoteItemId = stream.readUnsignedShort(); + } else if(opcode == 98) { + this.notedItemId = stream.readUnsignedShort(); + } else if(opcode >= 100 && opcode < 110) { + if(this.stackIds == null) { + this.stackIds = new int[10]; + this.stackAmounts = new int[10]; + } + + this.stackIds[opcode - 100] = stream.readUnsignedShort(); + this.stackAmounts[opcode - 100] = stream.readUnsignedShort(); + } else if(opcode == 110) { + this.unknownInt7 = stream.readUnsignedShort(); + } else if(opcode == 111) { + this.unknownInt8 = stream.readUnsignedShort(); + } else if(opcode == 112) { + this.unknownInt9 = stream.readUnsignedShort(); + } else if(opcode == 113) { + this.unknownInt10 = stream.readByte(); + } else if(opcode == 114) { + this.unknownInt11 = stream.readByte() * 5; + } else if(opcode == 115) { + this.teamId = stream.readUnsignedByte(); + } else if(opcode == 121) { + this.switchLendItemId = stream.readUnsignedShort(); + } else if(opcode == 122) { + this.lendedItemId = stream.readUnsignedShort(); + } else if(opcode == 125) { + this.unknownInt12 = stream.readByte() << 0; + this.unknownInt13 = stream.readByte() << 0; + this.unknownInt14 = stream.readByte() << 0; + } else if(opcode == 126) { + this.unknownInt15 = stream.readByte() << 0; + this.unknownInt16 = stream.readByte() << 0; + this.unknownInt17 = stream.readByte() << 0; + } else if(opcode == 127) { + this.unknownInt18 = stream.readUnsignedByte(); + this.unknownInt19 = stream.readUnsignedShort(); + } else if(opcode == 128) { + this.unknownInt20 = stream.readUnsignedByte(); + this.unknownInt21 = stream.readUnsignedShort(); + } else if(opcode == 129) { + this.unknownInt20 = stream.readUnsignedByte(); + this.unknownInt21 = stream.readUnsignedShort(); + } else if(opcode == 130) { + this.unknownInt22 = stream.readUnsignedByte(); + this.unknownInt23 = stream.readUnsignedShort(); + } else if(opcode == 132) { + length = stream.readUnsignedByte(); + this.unknownArray2 = new int[length]; + + for(index = 0; index < length; ++index) { + this.unknownArray2[index] = stream.readUnsignedShort(); + } + } else if(opcode == 134) { + stream.readUnsignedByte(); + } else if(opcode == 139) { + this.unknownValue2 = stream.readUnsignedShort(); + } else if(opcode == 140) { + this.unknownValue1 = stream.readUnsignedShort(); + }else if (opcode == 191) { + return; + //int opcode191 = 0; + }else if (opcode == 218) { + return; + //int opcode218 = 0; + }else if (opcode == 219) { + return; + //int opcode219 = 0; + } else if(opcode == 249) { + length = stream.readUnsignedByte(); + if(this.clientScriptData == null) { + this.clientScriptData = new HashMap(length); + } + + for(index = 0; index < length; ++index) { + boolean stringInstance = stream.readUnsignedByte() == 1; + int key = stream.read24BitInt(); + Object value = stringInstance?stream.readString():Integer.valueOf(stream.readInt()); + this.clientScriptData.put(Integer.valueOf(key), value); + } + //} + } else { + throw new RuntimeException("MISSING OPCODE " + opcode + " FOR ITEM " + this.id); + } + } + + } + + private void readOpcodeValues(InputStream stream) { + while(true) { + int opcode = stream.readUnsignedByte(); + if(opcode == 0) { + return; + } + + this.readValues(stream, opcode); + } + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return this.name; + } + + public void resetTextureColors() { + this.originalTextureColors = null; + this.modifiedTextureColors = null; + } + + public boolean isWearItem() { + return this.equipSlot != -1; + } + + public boolean isMembersOnly() { + return this.membersOnly; + } + + public void changeTextureColor(short originalModelColor, short modifiedModelColor) { + if(this.originalTextureColors != null) { + for(int newOriginalModelColors = 0; newOriginalModelColors < this.originalTextureColors.length; ++newOriginalModelColors) { + if(this.originalTextureColors[newOriginalModelColors] == originalModelColor) { + this.modifiedTextureColors[newOriginalModelColors] = modifiedModelColor; + return; + } + } + + short[] var5 = Arrays.copyOf(this.originalTextureColors, this.originalTextureColors.length + 1); + short[] newModifiedModelColors = Arrays.copyOf(this.modifiedTextureColors, this.modifiedTextureColors.length + 1); + var5[var5.length - 1] = originalModelColor; + newModifiedModelColors[newModifiedModelColors.length - 1] = modifiedModelColor; + this.originalTextureColors = var5; + this.modifiedTextureColors = newModifiedModelColors; + } else { + this.originalTextureColors = new short[]{originalModelColor}; + this.modifiedTextureColors = new short[]{modifiedModelColor}; + } + + } + + public void resetModelColors() { + this.originalModelColors = null; + this.modifiedModelColors = null; + } + + public void changeModelColor(int originalModelColor, int modifiedModelColor) { + if(this.originalModelColors != null) { + for(int newOriginalModelColors = 0; newOriginalModelColors < this.originalModelColors.length; ++newOriginalModelColors) { + if(this.originalModelColors[newOriginalModelColors] == originalModelColor) { + this.modifiedModelColors[newOriginalModelColors] = modifiedModelColor; + return; + } + } + + int[] var5 = Arrays.copyOf(this.originalModelColors, this.originalModelColors.length + 1); + int[] newModifiedModelColors = Arrays.copyOf(this.modifiedModelColors, this.modifiedModelColors.length + 1); + var5[var5.length - 1] = originalModelColor; + newModifiedModelColors[newModifiedModelColors.length - 1] = modifiedModelColor; + this.originalModelColors = var5; + this.modifiedModelColors = newModifiedModelColors; + } else { + this.originalModelColors = new int[]{originalModelColor}; + this.modifiedModelColors = new int[]{modifiedModelColor}; + } + + } + + public String[] getGroundOptions() { + return this.groundOptions; + } + + public String[] getInventoryOptions() { + return this.inventoryOptions; + } + + public int getEquipSlot() { + return this.equipSlot; + } + + public int getEquipType() { + return this.equipType; + } + + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException var2) { + var2.printStackTrace(); + return null; + } + } + + public String toString() { + return String.valueOf(this.id) + " - " + this.name; + } +} diff --git a/Tools/Frostys Cache Editor/src/com/alex/loaders/npcs/NPCDefinitions.java b/Tools/Frostys Cache Editor/src/com/alex/loaders/npcs/NPCDefinitions.java new file mode 100644 index 0000000..3cc5a1b --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/loaders/npcs/NPCDefinitions.java @@ -0,0 +1,1252 @@ +package com.alex.loaders.npcs; + +import com.alex.io.InputStream; +import com.alex.io.OutputStream; +import com.alex.store.Store; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.concurrent.ConcurrentHashMap; + +public final class NPCDefinitions implements Cloneable { + private static final ConcurrentHashMap npcDefinitions = new ConcurrentHashMap(); + public boolean loaded; + public int id; + //public HashMap parameters; + public int unknownInt13; + public int unknownInt6; + public int unknownInt15; + public byte respawnDirection; + public int size = 1; + public int[][] unknownArray3; + public boolean unknownBoolean2; + public int unknownInt9; + public int unknownInt4; + public int[] unknownArray2; + public int unknownInt7; + public int renderEmote; + public boolean unknownBoolean5 = false; + public int unknownInt20; + public byte unknownByte1; + public boolean unknownBoolean3; + public int unknownInt3; + public byte unknownByte2; + public boolean unknownBoolean6; + public boolean unknownBoolean4; + public int[] originalModelColors; + public int combatLevel; + public byte[] unknownArray1; + public short unknownShort1; + public boolean unknownBoolean1; + public int npcHeight; + public String name; + public int[] modifiedTextureColors; + public byte walkMask; + public int[] modelIds; + public int unknownInt1; + public int unknownInt21; + public int unknownInt11; + public int unknownInt17; + public int unknownInt14; + public int unknownInt12; + public int unknownInt8; + public int headIcons; + public int unknownInt19; + public int[] originalTextureColors; + public int[][] anIntArrayArray882; + public int unknownInt10; + public int[] unknownArray4; + public int unknownInt5; + public int unknownInt16; + public boolean isVisibleOnMap; + public int[] npcChatHeads; + public short unknownShort2; + public String[] options; + public int[] modifiedModelColors; + public int unknownInt2; + public int npcWidth; + public int npcId; + public int unknownInt18; + public boolean unknownBoolean7; + public int[] unknownArray5; + public HashMap clientScriptData; + public int anInt833; + public int anInt836; + public int anInt837; + public int[][] anIntArrayArray840; + public boolean aBoolean841; + public int anInt842; + public int bConfig; + public int[] transformTo; + public int anInt846; + public boolean aBoolean849 = false; + public int anInt850; + public byte aByte851; + public boolean aBoolean852; + public int anInt853; + public byte aByte854; + public boolean aBoolean856; + public boolean aBoolean857; + public short[] aShortArray859; + public byte[] aByteArray861; + public short aShort862; + public boolean aBoolean863; + public int anInt864; + public short[] aShortArray866; + public int anInt869; + public int anInt870; + public int anInt871; + public int anInt872; + public int anInt874; + public int anInt875; + public int anInt876; + public int anInt879; + public short[] aShortArray880; + public int anInt884; + public int[] anIntArray885; + public int config; + public int anInt889; + public int[] anIntArray892; + public short aShort894; + public short[] aShortArray896; + public int anInt897; + public int anInt899; + public int anInt901; + public boolean aBoolean3190; + private byte[] aByteArray1293; + private byte[] aByteArray12930; + private int[] anIntArray2930; + + public static final NPCDefinitions getNPCDefinitions(int id, Store store) { + NPCDefinitions def = (NPCDefinitions)npcDefinitions.get(Integer.valueOf(id)); + if(def == null) { + def = new NPCDefinitions(id); + def.method694(); + byte[] data = store.getIndexes()[18].getFile(id >>> 134238215, id & 127); + if(data != null) { + def.readValueLoop(new InputStream(data)); + } + + npcDefinitions.put(Integer.valueOf(id), def); + } + + return def; + } + + public static NPCDefinitions getNPCDefinition(Store cache, int npcId) { + return getNPCDefinition(cache, npcId, true); + } + + public static NPCDefinitions getNPCDefinition(Store cache, int npcId, boolean load) { + return new NPCDefinitions(cache, npcId, load); + } + + public NPCDefinitions(Store cache, int id, boolean load) { + this.id = id; + this.setDefaultVariableValues(); + this.setDefaultOptions(); + if(load) { + this.loadNPCDefinition(cache); + } + + } + + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException var2) { + var2.printStackTrace(); + return null; + } + } + + private void setDefaultOptions() { + this.options = new String[]{"Talk-to", null, null, null, null}; + } + + private void setDefaultVariableValues() { + this.name = "null"; + this.combatLevel = 0; + this.isVisibleOnMap = true; + this.renderEmote = -1; + this.respawnDirection = 7; + //this.size = 1; + this.unknownInt9 = -1; + this.unknownInt4 = -1; + this.unknownInt15 = -1; + this.unknownInt7 = -1; + this.unknownInt3 = 32; + this.unknownInt6 = -1; + this.unknownInt1 = 0; + this.walkMask = 0; + this.unknownInt20 = 255; + this.unknownInt11 = -1; + this.unknownBoolean3 = true; + this.unknownShort1 = 0; + this.unknownInt8 = -1; + this.unknownByte1 = -96; + this.unknownInt12 = 0; + this.unknownInt17 = -1; + this.unknownBoolean4 = true; + this.unknownInt21 = -1; + this.unknownInt14 = -1; + this.unknownInt13 = -1; + this.npcHeight = 128; + this.headIcons = -1; + this.unknownBoolean6 = false; + this.unknownInt5 = -1; + this.unknownByte2 = -16; + this.unknownBoolean1 = false; + this.unknownInt16 = -1; + this.unknownInt10 = -1; + this.unknownBoolean2 = true; + this.unknownInt19 = -1; + this.npcWidth = 128; + this.unknownShort2 = 0; + this.unknownInt2 = 0; + this.unknownInt18 = -1; + } + + private void loadNPCDefinition(Store cache) { + byte[] data = cache.getIndexes()[18].getFile(this.getArchiveId(), this.getFileId()); + if(data != null) { + try { + this.readOpcodeValues(new InputStream(data)); + } catch (RuntimeException var4) { + var4.printStackTrace(); + } + + this.loaded = true; + } + + } + + private void readOpcodeValues(InputStream stream) { + while(true) { + int opcode = stream.readUnsignedByte(); + if(opcode == 0) { + return; + } + + this.readValues(stream, opcode); + } + } + + public int getArchiveId() { + return this.id >>> 134238215; + } + + public int getFileId() { + return 127 & this.id; + } + + public void write(Store store) { + store.getIndexes()[18].putFile(this.getArchiveId(), this.getFileId(), this.encode()); + } + + public void method694() { + if(this.modelIds == null) { + this.modelIds = new int[0]; + } + + } + + private void readValueLoop(InputStream stream) { + while(true) { + int opcode = stream.readUnsignedByte(); + if(opcode == 0) { + return; + } + + this.readValues2(stream, opcode); + } + } + + private void readValues2(InputStream stream, int opcode) { + if (opcode != 1) { + if (opcode == 2) + name = stream.readString(); + else if ((opcode ^ 0xffffffff) != -13) { + if (opcode >= 30 && (opcode ^ 0xffffffff) > -36) { + options[opcode - 30] = stream.readString(); + if (options[-30 + opcode].equalsIgnoreCase("Hidden")) + options[-30 + opcode] = null; + } else if ((opcode ^ 0xffffffff) != -41) { + if (opcode == 41) { + int i = stream.readUnsignedByte(); + aShortArray880 = new short[i]; + aShortArray866 = new short[i]; + for (int i_54_ = 0; (i_54_ ^ 0xffffffff) > (i ^ 0xffffffff); i_54_++) { + aShortArray880[i_54_] = (short) stream.readUnsignedShort(); + aShortArray866[i_54_] = (short) stream.readUnsignedShort(); + } + } else if (opcode == 44) { + int i_24_ = (short) stream.readUnsignedShort(); + int i_25_ = 0; + for (int i_26_ = i_24_; i_26_ > 0; i_26_ >>= 1) + i_25_++; + // aByteArray12930 = new byte[i_25_]; + byte i_27_ = 0; + for (int i_28_ = 0; i_28_ < i_25_; i_28_++) { + if ((i_24_ & 1 << i_28_) > 0) { + // aByteArray12930[i_28_] = i_27_; + i_27_++; + } + // aByteArray12930[i_28_] = (byte) -1; + } + } else if (45 == opcode) { + int i_29_ = (short) stream.readUnsignedShort(); + int i_30_ = 0; + for (int i_31_ = i_29_; i_31_ > 0; i_31_ >>= 1) + i_30_++; + // aByteArray1293 = new byte[i_30_]; + byte i_32_ = 0; + for (int i_33_ = 0; i_33_ < i_30_; i_33_++) { + if ((i_29_ & 1 << i_33_) > 0) { + // aByteArray1293[i_33_] = i_32_; + i_32_++; + } + // aByteArray1293[i_33_] = (byte) -1; + } + } else if ((opcode ^ 0xffffffff) == -43) { + int i = stream.readUnsignedByte(); + aByteArray861 = new byte[i]; + for (int i_55_ = 0; i > i_55_; i_55_++) + aByteArray861[i_55_] = (byte) stream.readByte(); + } else if ((opcode ^ 0xffffffff) != -61) { + if (opcode == 93) + isVisibleOnMap = false; + else if ((opcode ^ 0xffffffff) == -96) + combatLevel = stream.readUnsignedShort(); + else if (opcode != 97) { + if ((opcode ^ 0xffffffff) == -99) + anInt899 = stream.readUnsignedShort(); + else if ((opcode ^ 0xffffffff) == -100) + aBoolean863 = true; + else if (opcode == 100) + anInt869 = stream.readByte(); + else if ((opcode ^ 0xffffffff) == -102) + anInt897 = stream.readByte() * 5; + else if ((opcode ^ 0xffffffff) == -103) + headIcons = stream.readUnsignedShort(); + else if (opcode != 103) { + if (opcode == 106 || opcode == 118) { + bConfig = stream.readUnsignedShort(); + if (bConfig == 65535) + bConfig = -1; + config = stream.readUnsignedShort(); + if (config == 65535) + config = -1; + int i = -1; + if ((opcode ^ 0xffffffff) == -119) { + i = stream.readUnsignedShort(); + if ((i ^ 0xffffffff) == -65536) + i = -1; + } + int i_56_ = stream.readUnsignedByte(); + transformTo = new int[2 + i_56_]; + for (int i_57_ = 0; i_56_ >= i_57_; i_57_++) { + transformTo[i_57_] = stream.readUnsignedShort(); + if (transformTo[i_57_] == 65535) + transformTo[i_57_] = -1; + } + transformTo[i_56_ - -1] = i; + } else if ((opcode ^ 0xffffffff) != -108) { + if ((opcode ^ 0xffffffff) == -110) + aBoolean852 = false; + else if ((opcode ^ 0xffffffff) != -112) { + if (opcode != 113) { + if (opcode == 114) { + aByte851 = (byte) (stream.readByte()); + aByte854 = (byte) (stream.readByte()); + } else if (opcode == 115) { + stream.readUnsignedByte(); + stream.readUnsignedByte(); + } else if ((opcode ^ 0xffffffff) != -120) { + if (opcode != 121) { + if ((opcode ^ 0xffffffff) != -123) { + if (opcode == 123) + anInt846 = (stream.readUnsignedShort()); + else if (opcode != 125) { + if (opcode == 127) + renderEmote = (stream.readUnsignedShort()); + else if ((opcode ^ 0xffffffff) == -129) + stream.readUnsignedByte(); + else if (opcode != 134) { + if (opcode == 135) { + anInt833 = stream.readUnsignedByte(); + anInt874 = stream.readUnsignedShort(); + } else if (opcode != 136) { + if (opcode != 137) { + if (opcode != 138) { + if ((opcode ^ 0xffffffff) != -140) { + if (opcode == 140) + anInt850 = stream.readUnsignedByte(); + else if (opcode == 141) + aBoolean849 = true; + else if ((opcode ^ 0xffffffff) != -143) { + if (opcode == 143) + aBoolean856 = true; + else if ((opcode ^ 0xffffffff) <= -151 && opcode < 155) { + options[opcode - 150] = stream.readString(); + if (options[opcode - 150].equalsIgnoreCase("Hidden")) + options[opcode + -150] = null; + } else if ((opcode ^ 0xffffffff) == -161) { + int i = stream.readUnsignedByte(); + anIntArray885 = new int[i]; + for (int i_58_ = 0; i > i_58_; i_58_++) + anIntArray885[i_58_] = stream.readUnsignedShort(); + + // all + // added + // after + // here + } else if (opcode == 155) { + int aByte821 = stream.readByte(); + int aByte824 = stream.readByte(); + int aByte843 = stream.readByte(); + int aByte855 = stream.readByte(); + } else if (opcode == 158) { + byte aByte833 = (byte) 1; + } else if (opcode == 159) { + byte aByte833 = (byte) 0; + } else if (opcode == 162) { // added + // opcode + // aBoolean3190 + // = + // true; + } else if (opcode == 163) { // added + // opcode + int anInt864 = stream.readUnsignedByte(); + } else if (opcode == 164) { + int anInt848 = stream.readUnsignedShort(); + int anInt837 = stream.readUnsignedShort(); + } else if (opcode == 165) { + int anInt847 = stream.readUnsignedByte(); + } else if (opcode == 168) { + int anInt828 = stream.readUnsignedByte(); + } else if (opcode >= 170 && opcode < 176) { + // if + // (null + // == + // anIntArray2930) + // { + // anIntArray2930 + // = + // new + // int[6]; + // Arrays.fill(anIntArray2930, + // -1); + // } + int i_44_ = (short) stream.readUnsignedShort(); + if (i_44_ == 65535) + i_44_ = -1; + // anIntArray2930[opcode + // - + // 170] + // = + // i_44_; + } else if (opcode == 12) { + size = stream.readUnsignedByte(); + } else if (opcode == 249) { + int i = stream.readUnsignedByte(); + if (clientScriptData == null) { + clientScriptData = new HashMap(i); + } + for (int i_60_ = 0; i > i_60_; i_60_++) { + boolean stringInstance = stream.readUnsignedByte() == 1; + int key = stream.read24BitInt(); + Object value; + if (stringInstance) + value = stream.readString(); + else + value = stream.readInt(); + clientScriptData.put(key, value); + } + } + } else + anInt870 = stream.readUnsignedShort(); + } else + anInt879 = stream.readBigSmart(); + } else + anInt901 = stream.readBigSmart(); + } else + anInt872 = stream.readUnsignedShort(); + } else { + anInt837 = stream.readUnsignedByte(); + anInt889 = stream.readUnsignedShort(); + } + } else { + anInt876 = (stream.readUnsignedShort()); + if (anInt876 == 65535) + anInt876 = -1; + anInt842 = (stream.readUnsignedShort()); + if (anInt842 == 65535) + anInt842 = -1; + anInt884 = (stream.readUnsignedShort()); + if ((anInt884 ^ 0xffffffff) == -65536) + anInt884 = -1; + anInt871 = (stream.readUnsignedShort()); + if ((anInt871 ^ 0xffffffff) == -65536) + anInt871 = -1; + anInt875 = (stream.readUnsignedByte()); + } + } else + respawnDirection = (byte) (stream.readByte()); + } else + anInt836 = (stream.readBigSmart()); + } else { + anIntArrayArray840 = (new int[modelIds.length][]); + int i = (stream.readUnsignedByte()); + for (int i_62_ = 0; ((i_62_ ^ 0xffffffff) > (i ^ 0xffffffff)); i_62_++) { + int i_63_ = (stream.readUnsignedByte()); + int[] is = (anIntArrayArray840[i_63_] = (new int[3])); + is[0] = (stream.readByte()); + is[1] = (stream.readByte()); + is[2] = (stream.readByte()); + } + } + } else + walkMask = (byte) (stream.readByte()); + } else { + aShort862 = (short) (stream.readUnsignedShort()); + aShort894 = (short) (stream.readUnsignedShort()); + } + } else + aBoolean857 = false; + } else + aBoolean841 = false; + } else + anInt853 = stream.readUnsignedShort(); + } else + anInt864 = stream.readUnsignedShort(); + } else { + int i = stream.readUnsignedByte(); + anIntArray892 = new int[i]; + for (int i_64_ = 0; (i_64_ ^ 0xffffffff) > (i ^ 0xffffffff); i_64_++) + anIntArray892[i_64_] = stream.readBigSmart(); + } + } else { + int i = stream.readUnsignedByte(); + aShortArray859 = new short[i]; + aShortArray896 = new short[i]; + for (int i_65_ = 0; (i ^ 0xffffffff) < (i_65_ ^ 0xffffffff); i_65_++) { + aShortArray896[i_65_] = (short) stream.readUnsignedShort(); + aShortArray859[i_65_] = (short) stream.readUnsignedShort(); + } + } + //} else + //size = stream.readUnsignedByte(); + } else { + int i = stream.readUnsignedByte(); + modelIds = new int[i]; + for (int i_66_ = 0; i_66_ < i; i_66_++) { + modelIds[i_66_] = stream.readBigSmart(); + if ((modelIds[i_66_] ^ 0xffffffff) == -65536) + modelIds[i_66_] = -1; + } + } + } + } + + private void readValues(InputStream stream, int opcode) { + int i; + int i_66_; + if(opcode != 1) { + if(opcode == 2) { + this.name = stream.readString(); + } else if(~opcode != -13) { + if(opcode >= 30 && ~opcode > -36) { + this.options[opcode - 30] = stream.readString(); + if(this.options[-30 + opcode].equalsIgnoreCase("Hidden")) { + this.options[-30 + opcode] = null; + } + } else if(~opcode != -41) { + if(opcode == 41) { + i = stream.readUnsignedByte(); + this.aShortArray880 = new short[i]; + this.aShortArray866 = new short[i]; + + for(i_66_ = 0; ~i_66_ > ~i; ++i_66_) { + this.aShortArray880[i_66_] = (short)stream.readUnsignedShort(); + this.aShortArray866[i_66_] = (short)stream.readUnsignedShort(); + } + } else { + int i_63_; + int is; + short var8; + byte var9; + if(opcode == 44) { + var8 = (short)stream.readUnsignedShort(); + i_66_ = 0; + + for(i_63_ = var8; i_63_ > 0; i_63_ >>= 1) { + ++i_66_; + } + + this.aByteArray12930 = new byte[i_66_]; + var9 = 0; + + for(is = 0; is < i_66_; ++is) { + if((var8 & 1 << is) > 0) { + this.aByteArray12930[is] = var9++; + } else { + this.aByteArray12930[is] = -1; + } + } + } else if(45 == opcode) { + var8 = (short)stream.readUnsignedShort(); + i_66_ = 0; + + for(i_63_ = var8; i_63_ > 0; i_63_ >>= 1) { + ++i_66_; + } + + this.aByteArray1293 = new byte[i_66_]; + var9 = 0; + + for(is = 0; is < i_66_; ++is) { + if((var8 & 1 << is) > 0) { + this.aByteArray1293[is] = var9++; + } else { + this.aByteArray1293[is] = -1; + } + } + } else if(~opcode == -43) { + i = stream.readUnsignedByte(); + this.aByteArray861 = new byte[i]; + + for(i_66_ = 0; i > i_66_; ++i_66_) { + this.aByteArray861[i_66_] = (byte)stream.readByte(); + } + } else if(~opcode != -61) { + if(opcode == 93) { + this.isVisibleOnMap = false; + } else if(~opcode == -96) { + this.combatLevel = stream.readUnsignedShort(); + } else if(opcode != 97) { + if(~opcode == -99) { + this.anInt899 = stream.readUnsignedShort(); + } else if(~opcode == -100) { + this.aBoolean863 = true; + } else if(opcode == 100) { + this.anInt869 = stream.readByte(); + } else if(~opcode == -102) { + this.anInt897 = stream.readByte() * 5; + } else if(~opcode == -103) { + this.headIcons = stream.readUnsignedShort(); + } else if(opcode != 103) { + if(opcode != 106 && opcode != 118) { + if(~opcode != -108) { + if(~opcode == -110) { + this.aBoolean852 = false; + } else if(~opcode != -112) { + if(opcode != 113) { + if(opcode == 114) { + this.aByte851 = (byte)stream.readByte(); + this.aByte854 = (byte)stream.readByte(); + } else if(opcode == 115) { + stream.readUnsignedByte(); + stream.readUnsignedByte(); + } else if(~opcode != -120) { + if(opcode != 121) { + if(~opcode != -123) { + if(opcode == 123) { + this.anInt846 = stream.readUnsignedShort(); + } else if(opcode != 125) { + if(opcode == 127) { + this.renderEmote = stream.readUnsignedShort(); + } else if(~opcode == -129) { + stream.readUnsignedByte(); + } else if(opcode != 134) { + if(opcode == 135) { + this.anInt833 = stream.readUnsignedByte(); + this.anInt874 = stream.readUnsignedShort(); + } else if(opcode != 136) { + if(opcode != 137) { + if(opcode != 138) { + if(~opcode != -140) { + if(opcode == 140) { + this.anInt850 = stream.readUnsignedByte(); + } else if(opcode == 141) { + this.aBoolean849 = true; + } else if(~opcode != -143) { + if(opcode == 143) { + this.aBoolean856 = true; + } else if(~opcode <= -151 && opcode < 155) { + this.options[opcode - 150] = stream.readString(); + if(this.options[opcode - 150].equalsIgnoreCase("Hidden")) { + this.options[opcode + -150] = null; + } + } else if(~opcode == -161) { + i = stream.readUnsignedByte(); + this.anIntArray885 = new int[i]; + + for(i_66_ = 0; i > i_66_; ++i_66_) { + this.anIntArray885[i_66_] = stream.readUnsignedShort(); + } + } else if(opcode == 155) { + i = stream.readByte(); + i_66_ = stream.readByte(); + i_63_ = stream.readByte(); + is = stream.readByte(); + } else { + boolean var10; + if(opcode == 158) { + var10 = true; + } else if(opcode == 159) { + var10 = false; + } else if(opcode == 162) { + this.aBoolean3190 = true; + } else if(opcode == 163) { + i = stream.readUnsignedByte(); + } else if(opcode == 164) { + i = stream.readUnsignedShort(); + i_66_ = stream.readUnsignedShort(); + } else if(opcode == 165) { + i = stream.readUnsignedByte(); + } else if(opcode == 168) { + i = stream.readUnsignedByte(); + } else if(opcode >= 170 && opcode < 176) { + if(this.anIntArray2930 == null) { + this.anIntArray2930 = new int[6]; + Arrays.fill(this.anIntArray2930, -1); + } + + var8 = (short)stream.readUnsignedShort(); + if(var8 == '\uffff') { + var8 = -1; + } + + this.anIntArray2930[opcode - 170] = var8; + } else if(opcode == 249) { + i = stream.readUnsignedByte(); + if(this.clientScriptData == null) { + this.clientScriptData = new HashMap(i); + } + + for(i_66_ = 0; i > i_66_; ++i_66_) { + boolean var12 = stream.readUnsignedByte() == 1; + is = stream.read24BitInt(); + Object value; + if(var12) { + value = stream.readString(); + } else { + value = Integer.valueOf(stream.readInt()); + } + + this.clientScriptData.put(Integer.valueOf(is), value); + } + } + } + } else { + this.anInt870 = stream.readUnsignedShort(); + } + } else { + this.anInt879 = stream.readBigSmart(); + } + } else { + this.anInt901 = stream.readBigSmart(); + } + } else { + this.anInt872 = stream.readUnsignedShort(); + } + } else { + this.anInt837 = stream.readUnsignedByte(); + this.anInt889 = stream.readUnsignedShort(); + } + } else { + this.anInt876 = stream.readUnsignedShort(); + if(this.anInt876 == '\uffff') { + this.anInt876 = -1; + } + + this.anInt842 = stream.readUnsignedShort(); + if(this.anInt842 == '\uffff') { + this.anInt842 = -1; + } + + this.anInt884 = stream.readUnsignedShort(); + if(~this.anInt884 == -65536) { + this.anInt884 = -1; + } + + this.anInt871 = stream.readUnsignedShort(); + if(~this.anInt871 == -65536) { + this.anInt871 = -1; + } + + this.anInt875 = stream.readUnsignedByte(); + } + } else { + this.respawnDirection = (byte)stream.readByte(); + } + } else { + this.anInt836 = stream.readBigSmart(); + } + } else { + this.anIntArrayArray840 = new int[this.modelIds.length][]; + i = stream.readUnsignedByte(); + + for(i_66_ = 0; ~i_66_ > ~i; ++i_66_) { + i_63_ = stream.readUnsignedByte(); + int[] var11 = this.anIntArrayArray840[i_63_] = new int[3]; + var11[0] = stream.readByte(); + var11[1] = stream.readByte(); + var11[2] = stream.readByte(); + } + } + } else { + this.walkMask = (byte)stream.readByte(); + } + } else { + this.aShort862 = (short)stream.readUnsignedShort(); + this.aShort894 = (short)stream.readUnsignedShort(); + } + } else { + this.aBoolean857 = false; + } + } else { + this.aBoolean841 = false; + } + } else { + this.bConfig = stream.readUnsignedShort(); + if(this.bConfig == '\uffff') { + this.bConfig = -1; + } + + this.config = stream.readUnsignedShort(); + if(this.config == '\uffff') { + this.config = -1; + } + + i = -1; + if(~opcode == -119) { + i = stream.readUnsignedShort(); + if(~i == -65536) { + i = -1; + } + } + + i_66_ = stream.readUnsignedByte(); + this.transformTo = new int[2 + i_66_]; + + for(i_63_ = 0; i_66_ >= i_63_; ++i_63_) { + this.transformTo[i_63_] = stream.readUnsignedShort(); + if(this.transformTo[i_63_] == '\uffff') { + this.transformTo[i_63_] = -1; + } + } + + this.transformTo[i_66_ - -1] = i; + } + } else { + this.anInt853 = stream.readUnsignedShort(); + } + } else { + this.anInt864 = stream.readUnsignedShort(); + } + } else { + i = stream.readUnsignedByte(); + this.anIntArray892 = new int[i]; + + for(i_66_ = 0; ~i_66_ > ~i; ++i_66_) { + this.anIntArray892[i_66_] = stream.readBigSmart(); + } + } + } + } else { + i = stream.readUnsignedByte(); + this.aShortArray859 = new short[i]; + this.aShortArray896 = new short[i]; + + for(i_66_ = 0; ~i < ~i_66_; ++i_66_) { + this.aShortArray896[i_66_] = (short)stream.readUnsignedShort(); + this.aShortArray859[i_66_] = (short)stream.readUnsignedShort(); + } + } + } else { + this.size = stream.readUnsignedByte(); + } + } else { + int i1 = stream.readUnsignedByte(); + modelIds = new int[i1]; + for (int i_69_ = 0; i_69_ < i1; i_69_++) { + modelIds[i_69_] = stream.readUnsignedShort(); + if ((modelIds[i_69_] ^ 0xffffffff) == -65536) + modelIds[i_69_] = -1; + } + } + + } + + public static final void clearNPCDefinitions() { + npcDefinitions.clear(); + } + + public NPCDefinitions(int id) { + this.id = id; + this.anInt842 = -1; + this.bConfig = -1; + this.anInt837 = -1; + this.anInt846 = -1; + this.anInt853 = 32; + this.combatLevel = -1; + this.anInt836 = -1; + this.name = "null"; + this.anInt869 = 0; + this.walkMask = 0; + this.anInt850 = 255; + this.anInt871 = -1; + this.aBoolean852 = true; + this.aShort862 = 0; + this.anInt876 = -1; + this.aByte851 = -96; + this.anInt875 = 0; + this.anInt872 = -1; + this.renderEmote = -1; + this.respawnDirection = 7; + this.aBoolean857 = true; + this.anInt870 = -1; + this.anInt874 = -1; + this.anInt833 = -1; + this.anInt864 = 128; + this.headIcons = -1; + this.aBoolean856 = false; + this.config = -1; + this.aByte854 = -16; + this.aBoolean863 = false; + this.isVisibleOnMap = true; + this.anInt889 = -1; + this.anInt884 = -1; + this.aBoolean841 = true; + this.anInt879 = -1; + this.anInt899 = 128; + this.aShort894 = 0; + this.options = new String[5]; + this.anInt897 = 0; + this.anInt901 = -1; + } + + public String toString() { + return this.id + " - " + this.name; + } + + public boolean hasMarkOption() { + String[] var4 = this.options; + int var3 = this.options.length; + + for(int var2 = 0; var2 < var3; ++var2) { + String option = var4[var2]; + if(option != null && option.equalsIgnoreCase("mark")) { + return true; + } + } + + return false; + } + + public boolean hasOption(String op) { + String[] var5 = this.options; + int var4 = this.options.length; + + for(int var3 = 0; var3 < var4; ++var3) { + String option = var5[var3]; + if(option != null && option.equalsIgnoreCase(op)) { + return true; + } + } + + return false; + } + + public byte getRespawnDirection() { + return this.respawnDirection; + } + + public void setRespawnDirection(byte respawnDirection) { + this.respawnDirection = respawnDirection; + } + + public int getSize() { + return this.size; + } + + public void setSize(int size) { + this.size = size; + } + + public int getRenderEmote() { + return this.renderEmote; + } + + public void setRenderEmote(int renderEmote) { + this.renderEmote = renderEmote; + } + + public boolean isVisibleOnMap() { + return this.isVisibleOnMap; + } + + public void setVisibleOnMap(boolean isVisibleOnMap) { + this.isVisibleOnMap = isVisibleOnMap; + } + + public String[] getOptions() { + return this.options; + } + + public void setOptions(String[] options) { + this.options = options; + } + + public int getNpcId() { + return this.npcId; + } + + public void setNpcId(int npcId) { + this.npcId = npcId; + } + + public boolean hasAttackOption() { + if(this.id == 14899) { + return true; + } else { + String[] var4 = this.options; + int var3 = this.options.length; + + for(int var2 = 0; var2 < var3; ++var2) { + String option = var4[var2]; + if(option != null && option.equalsIgnoreCase("attack")) { + return true; + } + } + + return false; + } + } + + public byte[] encode() { + OutputStream stream = new OutputStream(); + stream.writeByte(1); + stream.writeByte(this.modelIds.length); + + int data; + for(data = 0; data < this.modelIds.length; ++data) { + stream.writeBigSmart(this.modelIds[data]); + } + + if(!this.name.equals("null")) { + stream.writeByte(2); + stream.writeString(this.name); + } + + //if(this.size != 1) { + if(this.size > 1) { + stream.writeByte(12); + stream.writeByte(this.size); + } + + for(data = 0; data < this.options.length; ++data) { + if(this.options[data] != null && this.options[data] != "Hidden") { + stream.writeByte(30 + data); + stream.writeString(this.options[data]); + } + } + + if(this.originalModelColors != null && this.modifiedModelColors != null) { + stream.writeByte(40); + stream.writeByte(this.originalModelColors.length); + + for(data = 0; data < this.originalModelColors.length; ++data) { + stream.writeShort(this.originalModelColors[data]); + stream.writeShort(this.modifiedModelColors[data]); + } + } + + if(this.originalTextureColors != null && this.modifiedTextureColors != null) { + stream.writeByte(41); + stream.writeByte(this.originalTextureColors.length); + + for(data = 0; data < this.originalTextureColors.length; ++data) { + stream.writeShort(this.originalTextureColors[data]); + stream.writeShort(this.modifiedTextureColors[data]); + } + } + + if(this.unknownArray1 != null) { + stream.writeByte(42); + stream.writeByte(this.unknownArray1.length); + + for(data = 0; data < this.unknownArray1.length; ++data) { + stream.writeByte(this.unknownArray1[data]); + } + } + + if(this.npcChatHeads != null) { + stream.writeByte(60); + stream.writeByte(this.npcChatHeads.length); + + for(data = 0; data < this.npcChatHeads.length; ++data) { + stream.writeBigSmart(this.npcChatHeads[data]); + } + } + + if(!this.isVisibleOnMap) { + stream.writeByte(93); + } + + //if(this.combatLevel != 0) { + if(this.combatLevel > -1) { + stream.writeByte(95); + stream.writeShort(this.combatLevel); + } + + if(this.npcHeight != 0) { + stream.writeByte(97); + stream.writeShort(this.npcHeight); + } + + if(this.npcWidth != 0) { + stream.writeByte(98); + stream.writeShort(this.npcWidth); + } + + if(this.unknownBoolean1) { + stream.writeByte(99); + } + + if(this.unknownInt1 != 0) { + stream.writeByte(100); + stream.writeByte(this.unknownInt1); + } + + if(this.unknownInt2 != 0) { + stream.writeByte(101); + stream.writeByte(this.unknownInt2 / 5); + } + + if(this.headIcons != 0) { + stream.writeByte(102); + stream.writeShort(this.headIcons); + } + + if(this.walkMask != -1) { + stream.writeByte(119); + stream.writeByte(this.walkMask); + } + + if(this.respawnDirection != 7) { + stream.writeByte(125); + stream.writeByte(this.respawnDirection); + } + + if(this.renderEmote != -1) { + stream.writeByte(127); + stream.writeShort(this.renderEmote); + } + + if(this.clientScriptData != null) { + stream.writeByte(249); + stream.writeByte(this.clientScriptData.size()); + Iterator var6 = this.clientScriptData.keySet().iterator(); + + while(var6.hasNext()) { + int key = ((Integer)var6.next()).intValue(); + Object value = this.clientScriptData.get(Integer.valueOf(key)); + stream.writeByte(value instanceof String?1:0); + stream.write24BitInt(key); + if(value instanceof String) { + stream.writeString((String)value); + } else { + stream.writeInt(((Integer)value).intValue()); + } + } + } + + stream.writeByte(0); + byte[] var61 = new byte[stream.getOffset()]; + stream.setOffset(0); + stream.getBytes(var61, 0, var61.length); + return var61; + } + + public int getCombatLevel() { + return this.combatLevel; + } + + public void setCombatLevel(int combatLevel) { + this.combatLevel = combatLevel; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public int getId() { + return this.id; + } + + public void setId(int id) { + this.id = id; + } + + public void resetTextureColors() { + this.originalTextureColors = null; + this.modifiedTextureColors = null; + } + + public void changeTextureColor(int originalModelColor, int modifiedModelColor) { + if(this.originalTextureColors != null) { + for(int var5 = 0; var5 < this.originalTextureColors.length; ++var5) { + if(this.originalTextureColors[var5] == originalModelColor) { + this.modifiedTextureColors[var5] = modifiedModelColor; + return; + } + } + + int[] var51 = Arrays.copyOf(this.originalTextureColors, this.originalTextureColors.length + 1); + int[] newModifiedModelColors = Arrays.copyOf(this.modifiedTextureColors, this.modifiedTextureColors.length + 1); + var51[var51.length - 1] = originalModelColor; + newModifiedModelColors[newModifiedModelColors.length - 1] = modifiedModelColor; + this.originalTextureColors = var51; + this.modifiedTextureColors = newModifiedModelColors; + } else { + this.originalTextureColors = new int[]{originalModelColor}; + this.modifiedTextureColors = new int[]{modifiedModelColor}; + } + + } + + public void resetModelColors() { + this.originalModelColors = null; + this.modifiedModelColors = null; + } + + public void changeModelColor(int originalModelColor, int modifiedModelColor) { + if(this.originalModelColors != null) { + for(int var5 = 0; var5 < this.originalModelColors.length; ++var5) { + if(this.originalModelColors[var5] == originalModelColor) { + this.modifiedModelColors[var5] = modifiedModelColor; + return; + } + } + + int[] var51 = Arrays.copyOf(this.originalModelColors, this.originalModelColors.length + 1); + int[] newModifiedModelColors = Arrays.copyOf(this.modifiedModelColors, this.modifiedModelColors.length + 1); + var51[var51.length - 1] = originalModelColor; + newModifiedModelColors[newModifiedModelColors.length - 1] = modifiedModelColor; + this.originalModelColors = var51; + this.modifiedModelColors = newModifiedModelColors; + } else { + this.originalModelColors = new int[]{originalModelColor}; + this.modifiedModelColors = new int[]{modifiedModelColor}; + } + + } +} diff --git a/Tools/Frostys Cache Editor/src/com/alex/loaders/objects/ObjectDefinitions.java b/Tools/Frostys Cache Editor/src/com/alex/loaders/objects/ObjectDefinitions.java new file mode 100644 index 0000000..00803ed --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/loaders/objects/ObjectDefinitions.java @@ -0,0 +1,908 @@ +package com.alex.loaders.objects; + +import com.alex.io.InputStream; +import com.alex.io.OutputStream; +import com.alex.store.Store; + +import java.lang.reflect.Field; +import java.util.Arrays; +import java.util.HashMap; +import java.util.concurrent.ConcurrentHashMap; + +public class ObjectDefinitions { + private static final ConcurrentHashMap objectDefinitions = new ConcurrentHashMap(); + private short[] originalColors; + int[] toObjectIds; + static int anInt3832; + int[] anIntArray3833 = null; + public int anInt3834; + int anInt3835; + static int anInt3836; + public byte aByte3837; + int anInt3838 = -1; + boolean aBoolean3839; + public int anInt3840; + public int anInt3841; + static int anInt3842; + static int anInt3843; + int anInt3844; + boolean aBoolean3845; + public byte aByte3847; + public boolean ignoreClipOnAlternativeRoute; + int[] animations = null; + private byte[] possibleTypes; + private int[] anIntArray4534; + private byte[] unknownArray4; + private byte[] unknownArray3; + private int cflag; + public byte aByte3849; + int anInt3850; + int anInt3851; + public boolean secondBool; + public boolean aBoolean3853; + int anInt3855; + public boolean notCliped; + int anInt3857; + private byte[] aByteArray3858; + int[] anIntArray3859; + int anInt3860; + public String[] options; + int configFileId; + private short[] modifiedColors; + int anInt3865; + boolean aBoolean3866; + boolean aBoolean3867; + private int[] anIntArray3869; + boolean aBoolean3870; + public int sizeY; + boolean aBoolean3872; + boolean aBoolean3873; + public int thirdInt; + public int anInt3875; + public int objectAnimation; + public int anInt3877; + public int anInt3878; + public int clipType; + public int anInt3881; + public int anInt3882; + public int anInt3883; + Object loader; + public int anInt3889; + public int sizeX; + public boolean aBoolean3891; + int anInt3892; + public int secondInt; + boolean aBoolean3894; + boolean aBoolean3895; + int anInt3896; + int configId; + private byte[] aByteArray3899; + int anInt3900; + public String name; + public int anInt3902; + int anInt3904; + int anInt3905; + boolean aBoolean3906; + int[] anIntArray3908; + public byte aByte3912; + int anInt3913; + public byte aByte3914; + public int anInt3915; + public int[][] modelIds; + public int anInt3917; + public boolean loaded; + private short[] aShortArray3919; + private short[] aShortArray3920; + int anInt3921; + private HashMap parameters; + boolean aBoolean3923; + boolean aBoolean3924; + int anInt3925; + public int id; + public boolean aBool6886; + static int anInt3846; + public boolean projectileCliped; + + public ObjectDefinitions() { + this.anInt3835 = -1; + this.anInt3860 = -1; + this.configFileId = -1; + this.aBoolean3866 = false; + this.anInt3851 = -1; + this.anInt3865 = 255; + this.aBoolean3845 = false; + this.aBoolean3867 = false; + this.anInt3850 = 0; + this.anInt3844 = -1; + this.anInt3881 = 0; + this.anInt3857 = -1; + this.aBoolean3872 = true; + this.anInt3882 = -1; + this.anInt3834 = 0; + this.options = new String[5]; + this.anInt3875 = 0; + this.aBoolean3839 = false; + this.anIntArray3869 = null; + this.sizeY = 1; + this.thirdInt = -1; + this.anInt3883 = 0; + this.aBoolean3895 = true; + this.anInt3840 = 0; + this.aBoolean3870 = false; + this.anInt3889 = 0; + this.aBoolean3853 = true; + this.secondBool = false; + this.clipType = 2; + this.projectileCliped = true; + this.ignoreClipOnAlternativeRoute = false; + this.anInt3855 = -1; + this.anInt3878 = 0; + this.anInt3904 = 0; + this.sizeX = 1; + this.objectAnimation = -1; + this.aBoolean3891 = false; + this.anInt3905 = 0; + this.name = "null"; + this.anInt3913 = -1; + this.aBoolean3906 = false; + this.aBoolean3873 = false; + this.aByte3914 = 0; + this.anInt3915 = 0; + this.anInt3900 = 0; + this.secondInt = -1; + this.aBoolean3894 = false; + this.aByte3912 = 0; + this.anInt3921 = 0; + this.anInt3902 = 128; + this.configId = -1; + this.anInt3877 = 0; + this.anInt3925 = 0; + this.anInt3892 = 64; + this.aBoolean3923 = false; + this.aBoolean3924 = false; + this.anInt3841 = 128; + this.anInt3917 = 128; + } + + public String getFirstOption() { + return this.options != null && this.options.length >= 1?this.options[0]:""; + } + + public String getSecondOption() { + return this.options != null && this.options.length >= 2?this.options[1]:""; + } + + public String getOption(int option) { + return this.options != null && this.options.length >= option && option != 0?this.options[option - 1]:""; + } + + public String getThirdOption() { + return this.options != null && this.options.length >= 3?this.options[2]:""; + } + + private static int getArchiveId(int i_0_) { + return i_0_ >>> -1135990488; + } + + public int getSizeX() { + return this.sizeX; + } + + public int getSizeY() { + return this.sizeY; + } + + private Object getValue(Field field) throws Throwable { + field.setAccessible(true); + Class type = field.getType(); + return type == int[][].class?Arrays.toString((int[][])field.get(this)):(type == int[].class?Arrays.toString((int[])field.get(this)):(type == byte[].class?Arrays.toString((byte[])field.get(this)):(type == short[].class?Arrays.toString((short[])field.get(this)):(type == double[].class?Arrays.toString((double[])field.get(this)):(type == float[].class?Arrays.toString((float[])field.get(this)):(type == Object[].class?Arrays.toString((Object[])field.get(this)):field.get(this))))))); + } + + public boolean isProjectileCliped() { + return this.projectileCliped; + } + + public boolean containsOption(int i, String option) { + return this.options != null && this.options[i] != null && this.options.length > i?this.options[i].equals(option):false; + } + + public boolean containsOption(String o) { + if(this.options == null) { + return false; + } else { + String[] var5 = this.options; + int var4 = this.options.length; + + for(int var3 = 0; var3 < var4; ++var3) { + String option = var5[var3]; + if(option != null && option.equalsIgnoreCase(o)) { + return true; + } + } + + return false; + } + } + + final void method3287() { + if(this.secondInt == -1) { + this.secondInt = 0; + if(this.possibleTypes != null && this.possibleTypes.length == 1 && this.possibleTypes[0] == 10) { + this.secondInt = 1; + } + + for(int i_13_ = 0; i_13_ < 5; ++i_13_) { + if(this.options[i_13_] != null) { + this.secondInt = 1; + break; + } + } + } + + if(this.anInt3855 == -1) { + this.anInt3855 = this.clipType != 0?1:0; + } + + } + + public int getAccessBlockFlag() { + return this.cflag; + } + + private void readValues(InputStream stream, int opcode) { + boolean aBoolean1162; + int i_73_; + int i_74_; + int i_75_; + if(opcode != 1 && opcode != 5) { + if(opcode != 2) { + if(opcode != 14) { + if(opcode != 15) { + if(opcode == 17) { + this.projectileCliped = false; + this.clipType = 0; + } else if(opcode != 18) { + if(opcode == 19) { + this.secondInt = stream.readUnsignedByte(); + } else if(opcode == 21) { + this.aByte3912 = 1; + } else if(opcode != 22) { + if(opcode != 23) { + if(opcode != 24) { + if(opcode == 27) { + this.clipType = 1; + } else if(opcode == 28) { + this.anInt3892 = stream.readUnsignedByte() << 2; + } else if(opcode != 29) { + if(opcode != 39) { + if(opcode >= 30 && opcode < 35) { + this.options[-30 + opcode] = stream.readString(); + } else { + int var8; + if(opcode == 40) { + var8 = stream.readUnsignedByte(); + this.originalColors = new short[var8]; + this.modifiedColors = new short[var8]; + + for(i_73_ = 0; var8 > i_73_; ++i_73_) { + this.originalColors[i_73_] = (short)stream.readUnsignedShort(); + this.modifiedColors[i_73_] = (short)stream.readUnsignedShort(); + } + } else { + short var9; + byte var10; + if(44 == opcode) { + var9 = (short)stream.readUnsignedShort(); + i_73_ = 0; + + for(i_74_ = var9; i_74_ > 0; i_74_ >>= 1) { + ++i_73_; + } + + this.unknownArray3 = new byte[i_73_]; + var10 = 0; + + for(i_75_ = 0; i_75_ < i_73_; ++i_75_) { + if((var9 & 1 << i_75_) > 0) { + this.unknownArray3[i_75_] = var10++; + } else { + this.unknownArray3[i_75_] = -1; + } + } + } else if(opcode == 45) { + var9 = (short)stream.readUnsignedShort(); + i_73_ = 0; + + for(i_74_ = var9; i_74_ > 0; i_74_ >>= 1) { + ++i_73_; + } + + this.unknownArray4 = new byte[i_73_]; + var10 = 0; + + for(i_75_ = 0; i_75_ < i_73_; ++i_75_) { + if((var9 & 1 << i_75_) > 0) { + this.unknownArray4[i_75_] = var10++; + } else { + this.unknownArray4[i_75_] = -1; + } + } + } else if(opcode != 41) { + if(opcode != 42) { + if(opcode != 62) { + if(opcode != 64) { + if(opcode == 65) { + this.anInt3902 = stream.readUnsignedShort(); + } else if(opcode != 66) { + if(opcode != 67) { + if(opcode == 69) { + this.cflag = stream.readUnsignedByte(); + } else if(opcode != 70) { + if(opcode == 71) { + this.anInt3889 = stream.readShort() << 2; + } else if(opcode != 72) { + if(opcode == 73) { + this.secondBool = true; + } else if(opcode == 74) { + this.ignoreClipOnAlternativeRoute = true; + } else if(opcode != 75) { + if(opcode != 77 && opcode != 92) { + if(opcode == 78) { + this.anInt3860 = stream.readUnsignedShort(); + this.anInt3904 = stream.readUnsignedByte(); + } else if(opcode != 79) { + if(opcode == 81) { + this.aByte3912 = 2; + this.anInt3882 = 256 * stream.readUnsignedByte(); + } else if(opcode != 82) { + if(opcode == 88) { + this.aBoolean3853 = false; + } else if(opcode != 89) { + if(opcode == 90) { + this.aBoolean3870 = true; + } else if(opcode != 91) { + if(opcode != 93) { + if(opcode == 94) { + this.aByte3912 = 4; + } else if(opcode != 95) { + if(opcode != 96) { + if(opcode == 97) { + this.aBoolean3866 = true; + } else if(opcode == 98) { + this.aBoolean3923 = true; + } else if(opcode == 99) { + this.anInt3857 = stream.readUnsignedByte(); + this.anInt3835 = stream.readUnsignedShort(); + } else if(opcode == 100) { + this.anInt3844 = stream.readUnsignedByte(); + this.anInt3913 = stream.readUnsignedShort(); + } else if(opcode != 101) { + if(opcode == 102) { + this.anInt3838 = stream.readUnsignedShort(); + } else if(opcode == 103) { + this.thirdInt = 0; + } else if(opcode != 104) { + if(opcode == 105) { + this.aBoolean3906 = true; + } else if(opcode == 106) { + var8 = stream.readUnsignedByte(); + this.anIntArray3869 = new int[var8]; + this.animations = new int[var8]; + + for(i_73_ = 0; i_73_ < var8; ++i_73_) { + this.animations[i_73_] = stream.readBigSmart(); + i_74_ = stream.readUnsignedByte(); + this.anIntArray3869[i_73_] = i_74_; + this.anInt3881 += i_74_; + } + } else if(opcode == 107) { + this.anInt3851 = stream.readUnsignedShort(); + } else if(opcode >= 150 && opcode < 155) { + this.options[opcode + -150] = stream.readString(); + } else if(opcode != 160) { + if(opcode == 162) { + this.aByte3912 = 3; + this.anInt3882 = stream.readInt(); + } else if(opcode == 163) { + this.aByte3847 = (byte)stream.readByte(); + this.aByte3849 = (byte)stream.readByte(); + this.aByte3837 = (byte)stream.readByte(); + this.aByte3914 = (byte)stream.readByte(); + } else if(opcode != 164) { + if(opcode != 165) { + if(opcode != 166) { + if(opcode == 167) { + this.anInt3921 = stream.readUnsignedShort(); + } else if(opcode != 168) { + if(opcode == 169) { + this.aBoolean3845 = true; + } else if(opcode == 170) { + var8 = stream.readUnsignedSmart(); + } else if(opcode == 171) { + var8 = stream.readUnsignedSmart(); + } else if(opcode == 173) { + var8 = stream.readUnsignedShort(); + i_73_ = stream.readUnsignedShort(); + } else if(opcode == 177) { + aBoolean1162 = true; + } else if(opcode == 178) { + var8 = stream.readUnsignedByte(); + } else if(opcode == 189) { + aBoolean1162 = true; + } else if(opcode >= 190 && opcode < 196) { + if(this.anIntArray4534 == null) { + this.anIntArray4534 = new int[6]; + Arrays.fill(this.anIntArray4534, -1); + } + + this.anIntArray4534[opcode - 190] = stream.readUnsignedShort(); + } else if(opcode == 249) { + var8 = stream.readUnsignedByte(); + if(this.parameters == null) { + this.parameters = new HashMap(var8); + } + + for(i_73_ = 0; i_73_ < var8; ++i_73_) { + boolean var11 = stream.readUnsignedByte() == 1; + i_75_ = stream.read24BitInt(); + if(!var11) { + this.parameters.put(Integer.valueOf(i_75_), Integer.valueOf(stream.readInt())); + } else { + this.parameters.put(Integer.valueOf(i_75_), stream.readString()); + } + } + } + } else { + this.aBoolean3894 = true; + } + } else { + this.anInt3877 = stream.readShort(); + } + } else { + this.anInt3875 = stream.readShort(); + } + } else { + this.anInt3834 = stream.readShort(); + } + } else { + var8 = stream.readUnsignedByte(); + this.anIntArray3908 = new int[var8]; + + for(i_73_ = 0; var8 > i_73_; ++i_73_) { + this.anIntArray3908[i_73_] = stream.readUnsignedShort(); + } + } + } else { + this.anInt3865 = stream.readUnsignedByte(); + } + } else { + this.anInt3850 = stream.readUnsignedByte(); + } + } else { + this.aBoolean3924 = true; + } + } else { + this.aByte3912 = 5; + this.anInt3882 = stream.readShort(); + } + } else { + this.aByte3912 = 3; + this.anInt3882 = stream.readUnsignedShort(); + } + } else { + this.aBoolean3873 = true; + } + } else { + this.aBoolean3895 = false; + } + } else { + this.aBoolean3891 = true; + } + } else { + this.anInt3900 = stream.readUnsignedShort(); + this.anInt3905 = stream.readUnsignedShort(); + this.anInt3904 = stream.readUnsignedByte(); + var8 = stream.readUnsignedByte(); + this.anIntArray3859 = new int[var8]; + + for(i_73_ = 0; i_73_ < var8; ++i_73_) { + this.anIntArray3859[i_73_] = stream.readUnsignedShort(); + } + } + } else { + this.configFileId = stream.readUnsignedShort(); + if(this.configFileId == '\uffff') { + this.configFileId = -1; + } + + this.configId = stream.readUnsignedShort(); + if(this.configId == '\uffff') { + this.configId = -1; + } + + var8 = -1; + if(opcode == 92) { + var8 = stream.readBigSmart(); + } + + i_73_ = stream.readUnsignedByte(); + this.toObjectIds = new int[i_73_ - -2]; + + for(i_74_ = 0; i_73_ >= i_74_; ++i_74_) { + this.toObjectIds[i_74_] = stream.readBigSmart(); + } + + this.toObjectIds[i_73_ + 1] = var8; + } + } else { + this.anInt3855 = stream.readUnsignedByte(); + } + } else { + this.anInt3915 = stream.readShort() << 2; + } + } else { + this.anInt3883 = stream.readShort() << 2; + } + } else { + this.anInt3917 = stream.readUnsignedShort(); + } + } else { + this.anInt3841 = stream.readUnsignedShort(); + } + } else { + this.aBoolean3872 = false; + } + } else { + this.aBoolean3839 = true; + } + } else { + var8 = stream.readUnsignedByte(); + this.aByteArray3858 = new byte[var8]; + + for(i_73_ = 0; i_73_ < var8; ++i_73_) { + this.aByteArray3858[i_73_] = (byte)stream.readByte(); + } + } + } else { + var8 = stream.readUnsignedByte(); + this.aShortArray3920 = new short[var8]; + this.aShortArray3919 = new short[var8]; + + for(i_73_ = 0; var8 > i_73_; ++i_73_) { + this.aShortArray3920[i_73_] = (short)stream.readUnsignedShort(); + this.aShortArray3919[i_73_] = (short)stream.readUnsignedShort(); + } + } + } + } + } else { + this.anInt3840 = stream.readByte() * 5; + } + } else { + this.anInt3878 = stream.readByte(); + } + } else { + this.objectAnimation = stream.readBigSmart(); + } + } else { + this.thirdInt = 1; + } + } else { + this.aBoolean3867 = true; + } + } else { + this.projectileCliped = false; + } + } else { + this.sizeY = stream.readUnsignedByte(); + } + } else { + this.sizeX = stream.readUnsignedByte(); + } + } else { + this.name = stream.readString(); + } + } else { + aBoolean1162 = false; + if(opcode == 5 && aBoolean1162) { + this.skipReadModelIds(stream); + } + + i_73_ = stream.readUnsignedByte(); + this.modelIds = new int[i_73_][]; + this.possibleTypes = new byte[i_73_]; + + for(i_74_ = 0; i_74_ < i_73_; ++i_74_) { + this.possibleTypes[i_74_] = (byte)stream.readByte(); + i_75_ = stream.readUnsignedByte(); + this.modelIds[i_74_] = new int[i_75_]; + + for(int i_76_ = 0; i_75_ > i_76_; ++i_76_) { + this.modelIds[i_74_][i_76_] = stream.readIntLE(); //fix + } + } + + if(opcode == 5 && !aBoolean1162) { + this.skipReadModelIds(stream); + } + } + + } + + private void skipReadModelIds(InputStream stream) { + int length = stream.readUnsignedByte(); + + for(int index = 0; index < length; ++index) { + stream.skip(1); + int length2 = stream.readUnsignedByte(); + + for(int i = 0; i < length2; ++i) { + stream.readBigSmart(); + } + } + + } + + private void readValueLoop(InputStream stream) { + while(true) { + int opcode = stream.readUnsignedByte(); + if(opcode == 0) { + return; + } + + this.readValues(stream, opcode); + } + } + + public ObjectDefinitions(Store cache, int i) { + this.anInt3835 = -1; + this.anInt3860 = -1; + this.configFileId = -1; + this.aBoolean3866 = false; + this.anInt3851 = -1; + this.anInt3865 = 255; + this.aBoolean3845 = false; + this.aBoolean3867 = false; + this.anInt3850 = 0; + this.anInt3844 = -1; + this.anInt3881 = 0; + this.anInt3857 = -1; + this.aBoolean3872 = true; + this.anInt3882 = -1; + this.anInt3834 = 0; + this.options = new String[5]; + this.anInt3875 = 0; + this.aBoolean3839 = false; + this.anIntArray3869 = null; + this.sizeY = 1; + this.thirdInt = -1; + this.anInt3883 = 0; + this.aBoolean3895 = true; + this.anInt3840 = 0; + this.aBoolean3870 = false; + this.anInt3889 = 0; + this.aBoolean3853 = true; + this.secondBool = false; + this.clipType = 2; + this.projectileCliped = true; + this.notCliped = false; + this.anInt3855 = -1; + this.anInt3878 = 0; + this.anInt3904 = 0; + this.sizeX = 1; + this.objectAnimation = -1; + this.aBoolean3891 = false; + this.anInt3905 = 0; + this.name = "null"; + this.anInt3913 = -1; + this.aBoolean3906 = false; + this.aBoolean3873 = false; + this.aByte3914 = 0; + this.anInt3915 = 0; + this.anInt3900 = 0; + this.secondInt = -1; + this.aBoolean3894 = false; + this.aByte3912 = 0; + this.anInt3921 = 0; + this.anInt3902 = 128; + this.configId = -1; + this.anInt3877 = 0; + this.anInt3925 = 0; + this.anInt3892 = 64; + this.aBoolean3923 = false; + this.aBoolean3924 = false; + this.anInt3841 = 128; + this.anInt3917 = 128; + } + + public int getArchiveId() { + return this.id >>> -1135990488; + } + + public int getFileId() { + return 0xff & this.id; + } + + public static ObjectDefinitions getObjectDefinitions(int id, Store store) { + ObjectDefinitions def = (ObjectDefinitions)objectDefinitions.get(Integer.valueOf(id)); + if(def == null) { + def = new ObjectDefinitions(); + def.id = id; + byte[] data = store.getIndexes()[16].getFile(getArchiveId(id), id & 0xff); + if(data != null) { + def.readValueLoop(new InputStream(data)); + } + + def.method3287(); + objectDefinitions.put(Integer.valueOf(id), def); + } + + return def; + } + + private void loadObjectDefinition(Store store) { + byte[] data = store.getIndexes()[16].getFile(this.id >>> -1135990488, this.id & 0xff); + if(data == null) { + System.out.println("FAILED LOADING OBJECT " + this.id); + } else { + try { + this.readOpcodeValues(new InputStream(data)); + } catch (RuntimeException var4) { + var4.printStackTrace(); + } + + this.loaded = true; + } + + } + + private void readOpcodeValues(InputStream stream) { + while(true) { + int opcode = stream.readUnsignedByte(); + if(opcode == 0) { + return; + } + + this.readValues(stream, opcode); + } + } + + public static ObjectDefinitions getObjectDefinition(Store cache, int itemId) { + return getObjectDefinition(cache, itemId, true); + } + + public static ObjectDefinitions getObjectDefinition(Store cache, int itemId, boolean load) { + return new ObjectDefinitions(cache, itemId, load); + } + + public ObjectDefinitions(Store cache, int id, boolean load) { + this.id = id; + this.setDefaultVariableValues(); + this.setDefaultOptions(); + if(load) { + this.loadObjectDefinition(cache); + } + + } + + private void setDefaultOptions() { + this.options = new String[5]; + } + + private void setDefaultVariableValues() { + this.name = name; + this.sizeX = 1; + this.sizeY = 1; + this.projectileCliped = true; + this.clipType = 2; + this.objectAnimation = -1; + } + + public int getClipType() { + return this.clipType; + } + + public static void clearObjectDefinitions() { + objectDefinitions.clear(); + } + + public void printFields() { + Field[] arr$ = this.getClass().getDeclaredFields(); + int len$ = arr$.length; + + for(int i$ = 0; i$ < len$; ++i$) { + Field field = arr$[i$]; + if((field.getModifiers() & 8) == 0) { + try { + System.out.println(field.getName() + ": " + this.getValue(field)); + } catch (Throwable var6) { + var6.printStackTrace(); + } + } + } + + System.out.println("-- end of " + this.getClass().getSimpleName() + " fields --"); + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return this.name; + } + + public byte[] encode() { + OutputStream stream = new OutputStream(); + stream.writeByte(1); + int i_73_ = this.modelIds.length; + this.modelIds = new int[i_73_][]; + this.aByteArray3899 = new byte[i_73_]; + + int data; + for(data = 0; data < i_73_; ++data) { + stream.write128Byte(this.aByteArray3899[data]); + int var6 = this.modelIds[data].length; + this.modelIds[data] = new int[var6]; + + for(int i_76_ = 0; var6 > i_76_; ++i_76_) { + stream.writeBigSmart(this.modelIds[data][i_76_]); + } + } + + if(!this.name.equals("null")) { + stream.writeByte(2); + stream.writeString(this.name); + } + + if(this.sizeX != 1) { + stream.writeByte(14); + stream.write128Byte(this.sizeX); + } + + if(this.sizeY != 1) { + stream.writeByte(15); + stream.writeByte(this.sizeY); + } + + if(this.objectAnimation != -1) { + stream.writeByte(24); + stream.writeBigSmart(this.objectAnimation); + } + + for(data = 0; data < this.options.length; ++data) { + if(this.options[data] != null && this.options[data] != "Hidden") { + stream.writeByte(30 + data); + stream.writeString(this.options[data]); + } + } + + if(this.originalColors != null && this.modifiedColors != null) { + stream.writeByte(40); + stream.writeByte(this.originalColors.length); + + for(data = 0; data < this.originalColors.length; ++data) { + stream.writeShort(this.originalColors[data]); + stream.writeShort(this.modifiedColors[data]); + } + } + + if(this.clipType == 0 && this.projectileCliped) { + stream.writeByte(17); + } + + if(this.projectileCliped) { + stream.writeByte(18); + } + + if(this.clipType == 1 || this.clipType == 2) { + stream.writeByte(27); + } + + stream.writeByte(0); + byte[] var61 = new byte[stream.getOffset()]; + stream.setOffset(0); + stream.getBytes(var61, 0, var61.length); + return var61; + } +} diff --git a/Tools/Frostys Cache Editor/src/com/alex/store/Archive.java b/Tools/Frostys Cache Editor/src/com/alex/store/Archive.java new file mode 100644 index 0000000..e5ab567 --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/store/Archive.java @@ -0,0 +1,166 @@ +package com.alex.store; + +import com.alex.io.InputStream; +import com.alex.io.OutputStream; +import com.alex.store.MainFile; +import com.alex.util.bzip2.BZip2Compressor; +import com.alex.util.bzip2.BZip2Decompressor; +import com.alex.util.crc32.CRC32HGenerator; +import com.alex.util.gzip.GZipCompressor; +import com.alex.util.gzip.GZipDecompressor; +import com.alex.util.whirlpool.Whirlpool; + +public class Archive { + private int id; + private int revision; + private int compression; + private byte[] data; + private int[] keys; + + protected Archive(int id, byte[] archive, int[] keys) { + this.id = id; + this.keys = keys; + this.decompress(archive); + } + + public Archive(int id, int compression, int revision, byte[] data) { + this.id = id; + this.compression = compression; + this.revision = revision; + this.data = data; + } + + public byte[] compress() { + OutputStream stream = new OutputStream(); + stream.writeByte(this.compression); + byte[] compressedData1; + switch(this.compression) { + case 0: + compressedData1 = this.data; + stream.writeInt(this.data.length); + break; + case 1: + Object compressed = null; + compressedData1 = BZip2Compressor.compress(this.data); + stream.writeInt(compressedData1.length); + stream.writeInt(this.data.length); + default: + compressedData1 = GZipCompressor.compress(this.data); + stream.writeInt(compressedData1.length); + stream.writeInt(this.data.length); + } + + stream.writeBytes(compressedData1); + if(this.keys != null && this.keys.length == 4) { + stream.encodeXTEA(this.keys, 5, stream.getOffset()); + } + + if(this.revision != -1) { + stream.writeShort(this.revision); + } + + byte[] compressed1 = new byte[stream.getOffset()]; + stream.setOffset(0); + stream.getBytes(compressed1, 0, compressed1.length); + return compressed1; + } + + private void decompress(byte[] archive) { + InputStream stream = new InputStream(archive); + if(this.keys != null && this.keys.length == 4) { + stream.decodeXTEA(this.keys); + } + + this.compression = stream.readUnsignedByte(); + int compressedLength = stream.readInt(); + if(compressedLength >= 0 && compressedLength <= 1000000) { + int length; + switch(this.compression) { + case 0: + this.data = new byte[compressedLength]; + this.checkRevision(compressedLength, archive, stream.getOffset()); + stream.readBytes(this.data, 0, compressedLength); + break; + case 1: + length = stream.readInt(); + if(length <= 0) { + this.data = null; + } else { + this.data = new byte[length]; + this.checkRevision(compressedLength, archive, stream.getOffset()); + BZip2Decompressor.decompress(this.data, archive, compressedLength, 9); + } + break; + default: + length = stream.readInt(); + if(length > 0 && length <= 1000000000) { + this.data = new byte[length]; + this.checkRevision(compressedLength, archive, stream.getOffset()); + if(!GZipDecompressor.decompress(stream, this.data)) { + this.data = null; + } + } else { + this.data = null; + } + } + + } else { + throw new RuntimeException("INVALID ARCHIVE HEADER"); + } + } + + private void checkRevision(int compressedLength, byte[] archive, int o) { + InputStream stream = new InputStream(archive); + int offset = stream.getOffset(); + if(stream.getLength() - (compressedLength + o) >= 2) { + stream.setOffset(stream.getLength() - 2); + this.revision = stream.readUnsignedShort(); + stream.setOffset(offset); + } else { + this.revision = -1; + } + + } + + public Object[] editNoRevision(byte[] data, MainFile mainFile) { + this.data = data; + if(this.compression == 1) { + this.compression = 2; + } + + byte[] compressed = this.compress(); + return !mainFile.putArchiveData(this.id, compressed)?null:new Object[]{Integer.valueOf(CRC32HGenerator.getHash(compressed)), Whirlpool.getHash(compressed, 0, compressed.length)}; + } + + public int getId() { + return this.id; + } + + public byte[] getData() { + return this.data; + } + + public int getDecompressedLength() { + return this.data.length; + } + + public int getRevision() { + return this.revision; + } + + public void setRevision(int revision) { + this.revision = revision; + } + + public int getCompression() { + return this.compression; + } + + public int[] getKeys() { + return this.keys; + } + + public void setKeys(int[] keys) { + this.keys = keys; + } +} diff --git a/Tools/Frostys Cache Editor/src/com/alex/store/ArchiveReference.java b/Tools/Frostys Cache Editor/src/com/alex/store/ArchiveReference.java new file mode 100644 index 0000000..aaa59f8 --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/store/ArchiveReference.java @@ -0,0 +1,138 @@ +package com.alex.store; + +import com.alex.store.FileReference; + +import java.util.Arrays; + +public class ArchiveReference { + private int nameHash; + private byte[] whirpool; + private int crc; + private int revision; + private FileReference[] files; + private int[] validFileIds; + private boolean needsFilesSort; + private boolean updatedRevision; + + public void updateRevision() { + if(!this.updatedRevision) { + ++this.revision; + this.updatedRevision = true; + } + + } + + public int getNameHash() { + return this.nameHash; + } + + public void setNameHash(int nameHash) { + this.nameHash = nameHash; + } + + public byte[] getWhirpool() { + return this.whirpool; + } + + public void setWhirpool(byte[] whirpool) { + this.whirpool = whirpool; + } + + public int getCRC() { + return this.crc; + } + + public void setCrc(int crc) { + this.crc = crc; + } + + public int getRevision() { + return this.revision; + } + + public FileReference[] getFiles() { + return this.files; + } + + public void setFiles(FileReference[] files) { + this.files = files; + } + + public void setRevision(int revision) { + this.revision = revision; + } + + public int[] getValidFileIds() { + return this.validFileIds; + } + + public void setValidFileIds(int[] validFileIds) { + this.validFileIds = validFileIds; + } + + public boolean isNeedsFilesSort() { + return this.needsFilesSort; + } + + public void setNeedsFilesSort(boolean needsFilesSort) { + this.needsFilesSort = needsFilesSort; + } + + public void removeFileReference(int fileId) { + int[] newValidFileIds = new int[this.validFileIds.length - 1]; + int count = 0; + int[] arr$ = this.validFileIds; + int len$ = arr$.length; + + for(int i$ = 0; i$ < len$; ++i$) { + int id = arr$[i$]; + if(id != fileId) { + newValidFileIds[count++] = id; + } + } + + this.validFileIds = newValidFileIds; + this.files[fileId] = null; + } + + public void addEmptyFileReference(int fileId) { + this.needsFilesSort = true; + int[] newValidFileIds = Arrays.copyOf(this.validFileIds, this.validFileIds.length + 1); + newValidFileIds[newValidFileIds.length - 1] = fileId; + this.validFileIds = newValidFileIds; + if(this.files.length <= fileId) { + FileReference[] newFiles = (FileReference[])Arrays.copyOf(this.files, fileId + 1); + newFiles[fileId] = new FileReference(); + this.files = newFiles; + } else { + this.files[fileId] = new FileReference(); + } + + } + + public void sortFiles() { + Arrays.sort(this.validFileIds); + this.needsFilesSort = false; + } + + public void reset() { + this.whirpool = null; + this.updatedRevision = true; + this.revision = 0; + this.nameHash = 0; + this.crc = 0; + this.files = new FileReference[0]; + this.validFileIds = new int[0]; + this.needsFilesSort = false; + } + + public void copyHeader(ArchiveReference fromReference) { + this.setCrc(fromReference.getCRC()); + this.setNameHash(fromReference.getNameHash()); + this.setWhirpool(fromReference.getWhirpool()); + int[] validFiles = fromReference.getValidFileIds(); + this.setValidFileIds(Arrays.copyOf(validFiles, validFiles.length)); + FileReference[] files = fromReference.getFiles(); + this.setFiles((FileReference[])Arrays.copyOf(files, files.length)); + } +} diff --git a/Tools/Frostys Cache Editor/src/com/alex/store/FileReference.java b/Tools/Frostys Cache Editor/src/com/alex/store/FileReference.java new file mode 100644 index 0000000..db59680 --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/store/FileReference.java @@ -0,0 +1,13 @@ +package com.alex.store; + +public class FileReference { + private int nameHash; + + public int getNameHash() { + return this.nameHash; + } + + public void setNameHash(int nameHash) { + this.nameHash = nameHash; + } +} diff --git a/Tools/Frostys Cache Editor/src/com/alex/store/Index.java b/Tools/Frostys Cache Editor/src/com/alex/store/Index.java new file mode 100644 index 0000000..f7905e1 --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/store/Index.java @@ -0,0 +1,504 @@ +package com.alex.store; + +import com.alex.io.InputStream; +import com.alex.io.OutputStream; +import com.alex.store.*; +import com.alex.util.crc32.CRC32HGenerator; +import com.alex.util.whirlpool.Whirlpool; +import com.alex.utils.Utils; + +public final class Index { + private MainFile mainFile; + private MainFile index255; + private ReferenceTable table; + private byte[][][] cachedFiles; + private int crc; + private byte[] whirlpool; + + protected Index(MainFile index255, MainFile mainFile, int[] keys) { + this.mainFile = mainFile; + this.index255 = index255; + byte[] archiveData = index255.getArchiveData(this.getId()); + if(archiveData != null) { + this.crc = CRC32HGenerator.getHash(archiveData); + this.whirlpool = Whirlpool.getHash(archiveData, 0, archiveData.length); + Archive archive = new Archive(this.getId(), archiveData, keys); + this.table = new ReferenceTable(archive); + this.resetCachedFiles(); + } + + } + + public void resetCachedFiles() { + this.cachedFiles = new byte[this.getLastArchiveId() + 1][][]; + } + + public int getLastFileId(int archiveId) { + return !this.archiveExists(archiveId)?-1:this.table.getArchives()[archiveId].getFiles().length - 1; + } + + public int getLastArchiveId() { + return this.table.getArchives().length - 1; + } + + public int getValidArchivesCount() { + return this.table.getValidArchiveIds().length; + } + + public int getValidFilesCount(int archiveId) { + return !this.archiveExists(archiveId)?-1:this.table.getArchives()[archiveId].getValidFileIds().length; + } + + public boolean archiveExists(int archiveId) { + if(archiveId < 0) { + return false; + } else { + ArchiveReference[] archives = this.table.getArchives(); + return archives.length > archiveId && archives[archiveId] != null; + } + } + + public boolean fileExists(int archiveId, int fileId) { + if(!this.archiveExists(archiveId)) { + return false; + } else { + FileReference[] files = this.table.getArchives()[archiveId].getFiles(); + return files.length > fileId && files[fileId] != null; + } + } + + public int getArchiveId(String name) { + int nameHash = Utils.getNameHash(name); + ArchiveReference[] archives = this.table.getArchives(); + int[] validArchiveIds = this.table.getValidArchiveIds(); + int[] arr$ = validArchiveIds; + int len$ = validArchiveIds.length; + + for(int i$ = 0; i$ < len$; ++i$) { + int archiveId = arr$[i$]; + if(archives[archiveId].getNameHash() == nameHash) { + return archiveId; + } + } + + return -1; + } + + public int getFileId(int archiveId, String name) { + if(!this.archiveExists(archiveId)) { + return -1; + } else { + int nameHash = Utils.getNameHash(name); + FileReference[] files = this.table.getArchives()[archiveId].getFiles(); + int[] validFileIds = this.table.getArchives()[archiveId].getValidFileIds(); + + for(int index = 0; index < validFileIds.length; ++index) { + int fileId = validFileIds[index]; + if(files[fileId].getNameHash() == nameHash) { + return fileId; + } + } + + return -1; + } + } + + public byte[] getFile(int archiveId) { + return !this.archiveExists(archiveId)?null:this.getFile(archiveId, this.table.getArchives()[archiveId].getValidFileIds()[0]); + } + + public byte[] getFile(int archiveId, int fileId) { + return this.getFile(archiveId, fileId, (int[])null); + } + + public byte[] getFile(int archiveId, int fileId, int[] keys) { + try { + if(!this.fileExists(archiveId, fileId)) { + return null; + } else { + if(this.cachedFiles[archiveId] == null || this.cachedFiles[archiveId][fileId] == null) { + this.cacheArchiveFiles(archiveId, keys); + } + + byte[] var5 = this.cachedFiles[archiveId][fileId]; + this.cachedFiles[archiveId][fileId] = null; + return var5; + } + } catch (Throwable var51) { + var51.printStackTrace(); + return null; + } + } + + public boolean packIndex(Store originalStore) { + return this.packIndex(originalStore, false); + } + + public boolean packIndex(Store originalStore, boolean checkCRC) { + try { + return this.packIndex(this.getId(), originalStore, checkCRC); + } catch (Exception var4) { + return this.packIndex(this.getId(), originalStore, checkCRC); + } + } + + public boolean packIndex(int id, Store originalStore, boolean checkCRC) { + try { + Index var9 = originalStore.getIndexes()[id]; + int[] arr$ = var9.table.getValidArchiveIds(); + int len$ = arr$.length; + + for(int i$ = 0; i$ < len$; ++i$) { + int archiveId = arr$[i$]; + if((!checkCRC || !this.archiveExists(archiveId) || var9.table.getArchives()[archiveId].getCRC() != this.table.getArchives()[archiveId].getCRC()) && !this.putArchive(id, archiveId, originalStore, false, false)) { + return false; + } + } + + if(!this.rewriteTable()) { + return false; + } else { + this.resetCachedFiles(); + return true; + } + } catch (Exception var91) { + return true; + } + } + + public boolean putArchive(int archiveId, Store originalStore) { + return this.putArchive(this.getId(), archiveId, originalStore, true, true); + } + + public boolean putArchive(int archiveId, Store originalStore, boolean rewriteTable, boolean resetCache) { + return this.putArchive(this.getId(), archiveId, originalStore, rewriteTable, resetCache); + } + + public boolean putArchive(int id, int archiveId, Store originalStore, boolean rewriteTable, boolean resetCache) { + try { + Index var11 = originalStore.getIndexes()[id]; + byte[] data = var11.getMainFile().getArchiveData(archiveId); + if(data == null) { + return false; + } else { + if(!this.archiveExists(archiveId)) { + this.table.addEmptyArchiveReference(archiveId); + } + + ArchiveReference reference = this.table.getArchives()[archiveId]; + reference.updateRevision(); + ArchiveReference originalReference = var11.table.getArchives()[archiveId]; + reference.copyHeader(originalReference); + int revision = reference.getRevision(); + data[data.length - 2] = (byte)(revision >> 8); + data[data.length - 1] = (byte)revision; + if(!this.mainFile.putArchiveData(archiveId, data)) { + return false; + } else if(rewriteTable && !this.rewriteTable()) { + return false; + } else { + if(resetCache) { + this.resetCachedFiles(); + } + + return true; + } + } + } catch (Exception var111) { + return true; + } + } + + public boolean putFile(int archiveId, int fileId, byte[] data) { + return this.putFile(archiveId, fileId, 2, data, (int[])null, true, true, -1, -1); + } + + public boolean removeFile(int archiveId, int fileId) { + return this.removeFile(archiveId, fileId, 2, (int[])null); + } + + public boolean removeFile(int archiveId, int fileId, int compression, int[] keys) { + if(!this.fileExists(archiveId, fileId)) { + return false; + } else { + this.cacheArchiveFiles(archiveId, keys); + ArchiveReference reference = this.table.getArchives()[archiveId]; + reference.removeFileReference(fileId); + int filesCount = this.getValidFilesCount(archiveId); + byte[] archiveData; + if(filesCount == 1) { + archiveData = this.getFile(archiveId, reference.getValidFileIds()[0], keys); + } else { + int[] var13 = new int[filesCount]; + OutputStream var14 = new OutputStream(); + + int index; + int offset; + for(index = 0; index < filesCount; ++index) { + offset = reference.getValidFileIds()[index]; + byte[] fileData = this.getFile(archiveId, offset, keys); + var13[index] = fileData.length; + var14.writeBytes(fileData); + } + + for(index = 0; index < var13.length; ++index) { + offset = var13[index]; + if(index != 0) { + offset -= var13[index - 1]; + } + + var14.writeInt(offset); + } + + var14.writeByte(1); + archiveData = new byte[var14.getOffset()]; + var14.setOffset(0); + var14.getBytes(archiveData, 0, archiveData.length); + } + + reference.updateRevision(); + Archive var131 = new Archive(archiveId, compression, reference.getRevision(), archiveData); + byte[] var141 = var131.compress(); + reference.setCrc(CRC32HGenerator.getHash(var141, 0, var141.length - 2)); + reference.setWhirpool(Whirlpool.getHash(var141, 0, var141.length - 2)); + if(!this.mainFile.putArchiveData(archiveId, var141)) { + return false; + } else if(!this.rewriteTable()) { + return false; + } else { + this.resetCachedFiles(); + return true; + } + } + } + + public boolean putFile(int archiveId, int fileId, int compression, byte[] data, int[] keys, boolean rewriteTable, boolean resetCache, int archiveName, int fileName) { + if(!this.archiveExists(archiveId)) { + this.table.addEmptyArchiveReference(archiveId); + this.resetCachedFiles(); + this.cachedFiles[archiveId] = new byte[1][]; + } else { + this.cacheArchiveFiles(archiveId, keys); + } + + ArchiveReference reference = this.table.getArchives()[archiveId]; + if(!this.fileExists(archiveId, fileId)) { + reference.addEmptyFileReference(fileId); + } + + reference.sortFiles(); + int filesCount = this.getValidFilesCount(archiveId); + byte[] archiveData; + if(filesCount == 1) { + archiveData = data; + } else { + int[] var18 = new int[filesCount]; + OutputStream var19 = new OutputStream(); + + int index; + int offset; + for(index = 0; index < filesCount; ++index) { + offset = reference.getValidFileIds()[index]; + byte[] fileData; + if(offset == fileId) { + fileData = data; + } else { + fileData = this.getFile(archiveId, offset, keys); + } + + var18[index] = fileData.length; + var19.writeBytes(fileData); + } + + for(index = 0; index < filesCount; ++index) { + offset = var18[index]; + if(index != 0) { + offset -= var18[index - 1]; + } + + var19.writeInt(offset); + } + + var19.writeByte(1); + archiveData = new byte[var19.getOffset()]; + var19.setOffset(0); + var19.getBytes(archiveData, 0, archiveData.length); + } + + reference.updateRevision(); + Archive var181 = new Archive(archiveId, compression, reference.getRevision(), archiveData); + byte[] var191 = var181.compress(); + reference.setCrc(CRC32HGenerator.getHash(var191, 0, var191.length - 2)); + reference.setWhirpool(Whirlpool.getHash(var191, 0, var191.length - 2)); + if(archiveName != -1) { + reference.setNameHash(archiveName); + } + + if(fileName != -1) { + reference.getFiles()[fileId].setNameHash(fileName); + } + + if(!this.mainFile.putArchiveData(archiveId, var191)) { + return false; + } else if(rewriteTable && !this.rewriteTable()) { + return false; + } else { + if(resetCache) { + this.resetCachedFiles(); + } + + return true; + } + } + + public boolean encryptArchive(int archiveId, int[] keys) { + return this.encryptArchive(archiveId, (int[])null, keys, true, true); + } + + public boolean encryptArchive(int archiveId, int[] oldKeys, int[] keys, boolean rewriteTable, boolean resetCache) { + if(!this.archiveExists(archiveId)) { + return false; + } else { + Archive archive = this.mainFile.getArchive(archiveId, oldKeys); + if(archive == null) { + return false; + } else { + ArchiveReference reference = this.table.getArchives()[archiveId]; + if(reference.getRevision() != archive.getRevision()) { + throw new RuntimeException("ERROR REVISION"); + } else { + reference.updateRevision(); + archive.setRevision(reference.getRevision()); + archive.setKeys(keys); + byte[] closedArchive = archive.compress(); + reference.setCrc(CRC32HGenerator.getHash(closedArchive, 0, closedArchive.length - 2)); + reference.setWhirpool(Whirlpool.getHash(closedArchive, 0, closedArchive.length - 2)); + if(!this.mainFile.putArchiveData(archiveId, closedArchive)) { + return false; + } else if(rewriteTable && !this.rewriteTable()) { + return false; + } else { + if(resetCache) { + this.resetCachedFiles(); + } + + return true; + } + } + } + } + } + + public boolean rewriteTable() { + this.table.updateRevision(); + this.table.sortTable(); + Object[] hashes = this.table.encodeHeader(this.index255); + if(hashes == null) { + return false; + } else { + this.whirlpool = (byte[])hashes[1]; + return true; + } + } + + public void setKeys(int[] keys) { + this.table.setKeys(keys); + } + + public int[] getKeys() { + return this.table.getKeys(); + } + + private void cacheArchiveFiles(int archiveId, int[] keys) { + Archive archive = this.getArchive(archiveId, keys); + int lastFileId = this.getLastFileId(archiveId); + this.cachedFiles[archiveId] = new byte[lastFileId + 1][]; + if(archive != null) { + byte[] data = archive.getData(); + if(data != null) { + int filesCount = this.getValidFilesCount(archiveId); + if(filesCount == 1) { + this.cachedFiles[archiveId][lastFileId] = data; + } else { + int readPosition = data.length; + --readPosition; + int amtOfLoops = data[readPosition] & 255; + readPosition -= amtOfLoops * filesCount * 4; + InputStream stream = new InputStream(data); + stream.setOffset(readPosition); + int[] filesSize = new int[filesCount]; + + int sourceOffset; + int count; + for(int var18 = 0; var18 < amtOfLoops; ++var18) { + sourceOffset = 0; + + for(count = 0; count < filesCount; ++count) { + filesSize[count] += sourceOffset += stream.readInt(); + } + } + + byte[][] var181 = new byte[filesCount][]; + + for(sourceOffset = 0; sourceOffset < filesCount; ++sourceOffset) { + var181[sourceOffset] = new byte[filesSize[sourceOffset]]; + filesSize[sourceOffset] = 0; + } + + stream.setOffset(readPosition); + sourceOffset = 0; + + int len$; + for(count = 0; count < amtOfLoops; ++count) { + int var19 = 0; + + for(len$ = 0; len$ < filesCount; ++len$) { + var19 += stream.readInt(); + System.arraycopy(data, sourceOffset, var181[len$], filesSize[len$], var19); + sourceOffset += var19; + filesSize[len$] += var19; + } + } + + count = 0; + int[] var191 = this.table.getArchives()[archiveId].getValidFileIds(); + len$ = var191.length; + + for(int i$ = 0; i$ < len$; ++i$) { + int fileId = var191[i$]; + this.cachedFiles[archiveId][fileId] = var181[count++]; + } + } + } + } + + } + + public int getId() { + return this.mainFile.getId(); + } + + public ReferenceTable getTable() { + return this.table; + } + + public MainFile getMainFile() { + return this.mainFile; + } + + public Archive getArchive(int id) { + return this.mainFile.getArchive(id, (int[])null); + } + + public Archive getArchive(int id, int[] keys) { + return this.mainFile.getArchive(id, keys); + } + + public int getCRC() { + return this.crc; + } + + public byte[] getWhirlpool() { + return this.whirlpool; + } +} diff --git a/Tools/Frostys Cache Editor/src/com/alex/store/MainFile.java b/Tools/Frostys Cache Editor/src/com/alex/store/MainFile.java new file mode 100644 index 0000000..48bbcb3 --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/store/MainFile.java @@ -0,0 +1,277 @@ +package com.alex.store; + +import com.alex.store.Archive; + +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; + +public final class MainFile { + public static final int IDX_BLOCK_LEN = 6; + public static final int HEADER_LEN = 8; + public static final int EXPANDED_HEADER_LEN = 10; + public static final int BLOCK_LEN = 512; + public static final int EXPANDED_BLOCK_LEN = 510; + public static final int TOTAL_BLOCK_LEN = 520; + private static final ByteBuffer tempBuffer = ByteBuffer.allocateDirect(520); + private int id; + private FileChannel index; + private FileChannel data; + private boolean newProtocol; + + protected MainFile(int id, RandomAccessFile data, RandomAccessFile index, boolean newProtocol) throws IOException { + this.id = id; + this.data = data.getChannel(); + this.index = index.getChannel(); + this.newProtocol = newProtocol; + } + + public Archive getArchive(int id) { + return this.getArchive(id, (int[])null); + } + + public Archive getArchive(int id, int[] keys) { + byte[] data = this.getArchiveData(id); + return data == null?null:new Archive(id, data, keys); + } + + public byte[] getArchiveData(int archiveId) { + FileChannel var2 = this.data; + FileChannel var3 = this.data; + synchronized(this.data) { + try { + tempBuffer.position(0).limit(6); + this.index.read(tempBuffer, (long)(archiveId * 6)); + tempBuffer.flip(); + int var16 = getMediumInt(tempBuffer); + int block = getMediumInt(tempBuffer); + Object var10000; + byte[] var100001; + if(var16 < 0) { + var10000 = null; + var100001 = (byte[])var10000; + return var100001; + } else if(block <= 0 || (long)block > this.data.size() / 520L) { + var10000 = null; + var100001 = (byte[])var10000; + return var100001; + } else { + ByteBuffer fileBuffer = ByteBuffer.allocate(var16); + int remaining = var16; + int chunk = 0; + int blockLen = this.newProtocol && archiveId > '\uffff'?510:512; + int headerLen = this.newProtocol && archiveId > '\uffff'?10:8; + + while(remaining > 0) { + if(block == 0) { + System.out.println(archiveId + ", " + this.newProtocol); + var10000 = null; + var100001 = (byte[])var10000; + return var100001; + } + + int blockSize = remaining > blockLen?blockLen:remaining; + tempBuffer.position(0).limit(blockSize + headerLen); + this.data.read(tempBuffer, (long)(block * 520)); + tempBuffer.flip(); + int currentFile; + int currentChunk; + int nextBlock; + int currentIndex; + if(this.newProtocol && archiveId > '\uffff') { + currentFile = tempBuffer.getInt(); + currentChunk = tempBuffer.getShort() & '\uffff'; + nextBlock = getMediumInt(tempBuffer); + currentIndex = tempBuffer.get() & 255; + } else { + currentFile = tempBuffer.getShort() & '\uffff'; + currentChunk = tempBuffer.getShort() & '\uffff'; + nextBlock = getMediumInt(tempBuffer); + currentIndex = tempBuffer.get() & 255; + } + + if((archiveId == currentFile || archiveId > '\uffff') && chunk == currentChunk && this.id == currentIndex) { + if(nextBlock >= 0 && (long)nextBlock <= this.data.size() / 520L) { + fileBuffer.put(tempBuffer); + remaining -= blockSize; + block = nextBlock; + ++chunk; + continue; + } + + var10000 = null; + var100001 = (byte[])var10000; + return var100001; + } + + var10000 = null; + var100001 = (byte[])var10000; + return var100001; + } + + byte[] var18 = (byte[])fileBuffer.flip().array(); + return var18; + } + } catch (Exception var181) { + return null; + } + } + } + + private static int getMediumInt(ByteBuffer buffer) { + return (buffer.get() & 255) << 16 | (buffer.get() & 255) << 8 | buffer.get() & 255; + } + + private static void putMediumInt(ByteBuffer buffer, int val) { + buffer.put((byte)(val >> 16)); + buffer.put((byte)(val >> 8)); + buffer.put((byte)val); + } + + public boolean putArchive(Archive archive) { + return this.putArchiveData(archive.getId(), archive.getData()); + } + + public boolean putArchiveData(int id, byte[] archive) { + ByteBuffer buffer = ByteBuffer.wrap(archive); + boolean done = this.putArchiveData(id, buffer, archive.length, true); + if(!done) { + done = this.putArchiveData(id, buffer, archive.length, false); + } + + return done; + } + + public boolean putArchiveData(int archiveId, ByteBuffer archive, int size, boolean exists) { + FileChannel var5 = this.data; + FileChannel var6 = this.data; + synchronized(this.data) { + try { + boolean var10000; + int var16; + boolean var100001; + if(exists) { + if((long)(archiveId * 6 + 6) > this.index.size()) { + var10000 = false; + var100001 = var10000; + return var100001; + } + + tempBuffer.position(0).limit(6); + this.index.read(tempBuffer, (long)(archiveId * 6)); + tempBuffer.flip().position(3); + var16 = getMediumInt(tempBuffer); + if(var16 <= 0 || (long)var16 > this.data.size() / 520L) { + var10000 = false; + var100001 = var10000; + return var100001; + } + } else { + var16 = (int)(this.data.size() + 520L - 1L) / 520; + if(var16 == 0) { + var16 = 1; + } + } + + tempBuffer.position(0); + putMediumInt(tempBuffer, size); + putMediumInt(tempBuffer, var16); + tempBuffer.flip(); + this.index.write(tempBuffer, (long)(archiveId * 6)); + int remaining = size; + int chunk = 0; + int blockLen = this.newProtocol && archiveId > '\uffff'?510:512; + + for(int headerLen = this.newProtocol && archiveId > '\uffff'?10:8; remaining > 0; ++chunk) { + int nextBlock = 0; + int blockSize; + if(exists) { + tempBuffer.position(0).limit(headerLen); + this.data.read(tempBuffer, (long)(var16 * 520)); + tempBuffer.flip(); + int currentChunk; + int currentIndex; + if(this.newProtocol && archiveId > '\uffff') { + blockSize = tempBuffer.getInt(); + currentChunk = tempBuffer.getShort() & '\uffff'; + nextBlock = getMediumInt(tempBuffer); + currentIndex = tempBuffer.get() & 255; + } else { + blockSize = tempBuffer.getShort() & '\uffff'; + currentChunk = tempBuffer.getShort() & '\uffff'; + nextBlock = getMediumInt(tempBuffer); + currentIndex = tempBuffer.get() & 255; + } + + if(archiveId != blockSize && archiveId <= '\uffff' || chunk != currentChunk || this.id != currentIndex) { + var10000 = false; + var100001 = var10000; + return var100001; + } + + if(nextBlock < 0 || (long)nextBlock > this.data.size() / 520L) { + var10000 = false; + var100001 = var10000; + return var100001; + } + } + + if(nextBlock == 0) { + exists = false; + nextBlock = (int)((this.data.size() + 520L - 1L) / 520L); + if(nextBlock == 0) { + nextBlock = 1; + } + + if(nextBlock == var16) { + ++nextBlock; + } + } + + if(remaining <= blockLen) { + nextBlock = 0; + } + + tempBuffer.position(0).limit(520); + if(this.newProtocol && archiveId > '\uffff') { + tempBuffer.putInt(archiveId); + tempBuffer.putShort((short)chunk); + putMediumInt(tempBuffer, nextBlock); + tempBuffer.put((byte)this.id); + } else { + tempBuffer.putShort((short)archiveId); + tempBuffer.putShort((short)chunk); + putMediumInt(tempBuffer, nextBlock); + tempBuffer.put((byte)this.id); + } + + blockSize = remaining > blockLen?blockLen:remaining; + archive.limit(archive.position() + blockSize); + tempBuffer.put(archive); + tempBuffer.flip(); + this.data.write(tempBuffer, (long)(var16 * 520)); + remaining -= blockSize; + var16 = nextBlock; + } + + var10000 = true; + return var10000; + } catch (Exception var17) { + return false; + } + } + } + + public int getId() { + return this.id; + } + + public int getArchivesCount() throws IOException { + FileChannel var1 = this.index; + FileChannel var2 = this.index; + synchronized(this.index) { + return (int)(this.index.size() / 6L); + } + } +} diff --git a/Tools/Frostys Cache Editor/src/com/alex/store/ReferenceTable.java b/Tools/Frostys Cache Editor/src/com/alex/store/ReferenceTable.java new file mode 100644 index 0000000..ec351e1 --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/store/ReferenceTable.java @@ -0,0 +1,317 @@ +package com.alex.store; + +import com.alex.io.InputStream; +import com.alex.io.OutputStream; +import com.alex.store.Archive; +import com.alex.store.ArchiveReference; +import com.alex.store.FileReference; +import com.alex.store.MainFile; + +import java.util.Arrays; + +public final class ReferenceTable { + private Archive archive; + private int revision; + private boolean named; + private boolean usesWhirpool; + private ArchiveReference[] archives; + private int[] validArchiveIds; + private boolean updatedRevision; + private boolean needsArchivesSort; + + protected ReferenceTable(Archive archive) { + this.archive = archive; + this.decodeHeader(); + } + + public void setKeys(int[] keys) { + this.archive.setKeys(keys); + } + + public int[] getKeys() { + return this.archive.getKeys(); + } + + public void sortArchives() { + Arrays.sort(this.validArchiveIds); + this.needsArchivesSort = false; + } + + public void addEmptyArchiveReference(int archiveId) { + this.needsArchivesSort = true; + int[] newValidArchiveIds = Arrays.copyOf(this.validArchiveIds, this.validArchiveIds.length + 1); + newValidArchiveIds[newValidArchiveIds.length - 1] = archiveId; + this.validArchiveIds = newValidArchiveIds; + ArchiveReference reference; + if(this.archives.length <= archiveId) { + ArchiveReference[] newArchives = (ArchiveReference[])Arrays.copyOf(this.archives, archiveId + 1); + reference = newArchives[archiveId] = new ArchiveReference(); + this.archives = newArchives; + } else { + reference = this.archives[archiveId] = new ArchiveReference(); + } + + reference.reset(); + } + + public void sortTable() { + if(this.needsArchivesSort) { + this.sortArchives(); + } + + for(int index = 0; index < this.validArchiveIds.length; ++index) { + ArchiveReference archive = this.archives[this.validArchiveIds[index]]; + if(archive.isNeedsFilesSort()) { + archive.sortFiles(); + } + } + + } + + public Object[] encodeHeader(MainFile mainFile) { + OutputStream stream = new OutputStream(); + int protocol = this.getProtocol(); + stream.writeByte(protocol); + if(protocol >= 6) { + stream.writeInt(this.revision); + } + + stream.writeByte((this.named?1:0) | (this.usesWhirpool?2:0)); + if(protocol >= 7) { + stream.writeBigSmart(this.validArchiveIds.length); + } else { + stream.writeShort(this.validArchiveIds.length); + } + + int data; + int archive; + for(data = 0; data < this.validArchiveIds.length; ++data) { + archive = this.validArchiveIds[data]; + if(data != 0) { + archive -= this.validArchiveIds[data - 1]; + } + + if(protocol >= 7) { + stream.writeBigSmart(archive); + } else { + stream.writeShort(archive); + } + } + + if(this.named) { + for(data = 0; data < this.validArchiveIds.length; ++data) { + stream.writeInt(this.archives[this.validArchiveIds[data]].getNameHash()); + } + } + + if(this.usesWhirpool) { + for(data = 0; data < this.validArchiveIds.length; ++data) { + stream.writeBytes(this.archives[this.validArchiveIds[data]].getWhirpool()); + } + } + + for(data = 0; data < this.validArchiveIds.length; ++data) { + stream.writeInt(this.archives[this.validArchiveIds[data]].getCRC()); + } + + for(data = 0; data < this.validArchiveIds.length; ++data) { + stream.writeInt(this.archives[this.validArchiveIds[data]].getRevision()); + } + + for(data = 0; data < this.validArchiveIds.length; ++data) { + archive = this.archives[this.validArchiveIds[data]].getValidFileIds().length; + if(protocol >= 7) { + stream.writeBigSmart(archive); + } else { + stream.writeShort(archive); + } + } + + int index2; + ArchiveReference var8; + for(data = 0; data < this.validArchiveIds.length; ++data) { + var8 = this.archives[this.validArchiveIds[data]]; + + for(index2 = 0; index2 < var8.getValidFileIds().length; ++index2) { + int var9 = var8.getValidFileIds()[index2]; + if(index2 != 0) { + var9 -= var8.getValidFileIds()[index2 - 1]; + } + + if(protocol >= 7) { + stream.writeBigSmart(var9); + } else { + stream.writeShort(var9); + } + } + } + + if(this.named) { + for(data = 0; data < this.validArchiveIds.length; ++data) { + var8 = this.archives[this.validArchiveIds[data]]; + + for(index2 = 0; index2 < var8.getValidFileIds().length; ++index2) { + stream.writeInt(var8.getFiles()[var8.getValidFileIds()[index2]].getNameHash()); + } + } + } + + byte[] var91 = new byte[stream.getOffset()]; + stream.setOffset(0); + stream.getBytes(var91, 0, var91.length); + return this.archive.editNoRevision(var91, mainFile); + } + + public int getProtocol() { + if(this.archives.length > '\uffff') { + return 7; + } else { + for(int index = 0; index < this.validArchiveIds.length; ++index) { + if(index > 0 && this.validArchiveIds[index] - this.validArchiveIds[index - 1] > '\uffff') { + return 7; + } + + if(this.archives[this.validArchiveIds[index]].getValidFileIds().length > '\uffff') { + return 7; + } + } + + return this.revision == 0?5:6; + } + } + + public void setRevision(int revision) { + this.updatedRevision = true; + this.revision = revision; + } + + public void updateRevision() { + if(!this.updatedRevision) { + ++this.revision; + this.updatedRevision = true; + } + + } + + private void decodeHeader() { + InputStream stream = new InputStream(this.archive.getData()); + int protocol = stream.readUnsignedByte(); + if(protocol >= 5 && protocol <= 7) { + if(protocol >= 6) { + this.revision = stream.readInt(); + } + + int hash = stream.readUnsignedByte(); + this.named = (1 & hash) != 0; + this.usesWhirpool = (2 & hash) != 0; + int validArchivesCount = protocol >= 7?stream.readBigSmart():stream.readUnsignedShort(); + this.validArchiveIds = new int[validArchivesCount]; + int lastArchiveId = 0; + int biggestArchiveId = 0; + + int index; + int archive; + for(index = 0; index < validArchivesCount; ++index) { + archive = lastArchiveId += protocol >= 7?stream.readBigSmart():stream.readUnsignedShort(); + if(archive > biggestArchiveId) { + biggestArchiveId = archive; + } + + this.validArchiveIds[index] = archive; + } + + this.archives = new ArchiveReference[biggestArchiveId + 1]; + + for(index = 0; index < validArchivesCount; ++index) { + this.archives[this.validArchiveIds[index]] = new ArchiveReference(); + } + + if(this.named) { + for(index = 0; index < validArchivesCount; ++index) { + this.archives[this.validArchiveIds[index]].setNameHash(stream.readInt()); + } + } + + if(this.usesWhirpool) { + for(index = 0; index < validArchivesCount; ++index) { + byte[] index2 = new byte[64]; + stream.getBytes(index2, 0, 64); + this.archives[this.validArchiveIds[index]].setWhirpool(index2); + } + } + + for(index = 0; index < validArchivesCount; ++index) { + this.archives[this.validArchiveIds[index]].setCrc(stream.readInt()); + } + + for(index = 0; index < validArchivesCount; ++index) { + this.archives[this.validArchiveIds[index]].setRevision(stream.readInt()); + } + + for(index = 0; index < validArchivesCount; ++index) { + this.archives[this.validArchiveIds[index]].setValidFileIds(new int[protocol >= 7?stream.readBigSmart():stream.readUnsignedShort()]); + } + + ArchiveReference var14; + int var13; + for(index = 0; index < validArchivesCount; ++index) { + archive = 0; + var13 = 0; + var14 = this.archives[this.validArchiveIds[index]]; + + int index21; + for(index21 = 0; index21 < var14.getValidFileIds().length; ++index21) { + int fileId = archive += protocol >= 7?stream.readBigSmart():stream.readUnsignedShort(); + if(fileId > var13) { + var13 = fileId; + } + + var14.getValidFileIds()[index21] = fileId; + } + + var14.setFiles(new FileReference[var13 + 1]); + + for(index21 = 0; index21 < var14.getValidFileIds().length; ++index21) { + var14.getFiles()[var14.getValidFileIds()[index21]] = new FileReference(); + } + } + + if(this.named) { + for(index = 0; index < validArchivesCount; ++index) { + var14 = this.archives[this.validArchiveIds[index]]; + + for(var13 = 0; var13 < var14.getValidFileIds().length; ++var13) { + var14.getFiles()[var14.getValidFileIds()[var13]].setNameHash(stream.readInt()); + } + } + } + + } else { + throw new RuntimeException("INVALID PROTOCOL"); + } + } + + public int getRevision() { + return this.revision; + } + + public ArchiveReference[] getArchives() { + return this.archives; + } + + public int[] getValidArchiveIds() { + return this.validArchiveIds; + } + + public boolean isNamed() { + return this.named; + } + + public boolean usesWhirpool() { + return this.usesWhirpool; + } + + public int getCompression() { + return this.archive.getCompression(); + } +} diff --git a/Tools/Frostys Cache Editor/src/com/alex/store/Store.java b/Tools/Frostys Cache Editor/src/com/alex/store/Store.java new file mode 100644 index 0000000..22e8ee1 --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/store/Store.java @@ -0,0 +1,152 @@ +package com.alex.store; + +import com.alex.io.OutputStream; +import com.alex.store.Archive; +import com.alex.store.Index; +import com.alex.store.MainFile; +import com.alex.util.whirlpool.Whirlpool; +import com.alex.utils.Utils; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.math.BigInteger; +import java.util.Arrays; + +public final class Store { + private Index[] indexes; + private MainFile index255; + private String path; + private RandomAccessFile data; + private boolean newProtocol; + + public Store(String path) throws IOException { + this(path, true); + } + + public Store(String path, boolean newProtocol) throws IOException { + this(path, newProtocol, (int[][])null); + } + + public Store(String path, boolean newProtocol, int[][] keys) throws IOException { + this.path = path; + this.newProtocol = newProtocol; + this.data = new RandomAccessFile(path + "main_file_cache.dat2", "rw"); + this.index255 = new MainFile(255, this.data, new RandomAccessFile(path + "main_file_cache.idx255", "rw"), newProtocol); + int idxsCount = this.index255.getArchivesCount(); + this.indexes = new Index[idxsCount]; + + for(int id = 0; id < idxsCount; ++id) { + Index index = new Index(this.index255, new MainFile(id, this.data, new RandomAccessFile(path + "main_file_cache.idx" + id, "rw"), newProtocol), keys == null?null:keys[id]); + if(index.getTable() != null) { + this.indexes[id] = index; + } + } + + } + + public final byte[] generateIndex255Archive255Current(BigInteger grab_server_private_exponent, BigInteger grab_server_modulus) { + OutputStream stream = new OutputStream(); + stream.writeByte(this.getIndexes().length); + + for(int var9 = 0; var9 < this.getIndexes().length; ++var9) { + if(this.getIndexes()[var9] == null) { + stream.writeInt(0); + stream.writeInt(0); + stream.writeBytes(new byte[64]); + } else { + stream.writeInt(this.getIndexes()[var9].getCRC()); + stream.writeInt(this.getIndexes()[var9].getTable().getRevision()); + stream.writeBytes(this.getIndexes()[var9].getWhirlpool()); + if(this.getIndexes()[var9].getKeys() != null) { + int[] var10 = this.getIndexes()[var9].getKeys(); + int var12 = var10.length; + + for(int i$ = 0; i$ < var12; ++i$) { + int key = var10[i$]; + stream.writeInt(key); + } + } else { + for(int var11 = 0; var11 < 4; ++var11) { + stream.writeInt(0); + } + } + } + } + + byte[] var91 = new byte[stream.getOffset()]; + stream.setOffset(0); + stream.getBytes(var91, 0, var91.length); + OutputStream var111 = new OutputStream(65); + var111.writeByte(0); + var111.writeBytes(Whirlpool.getHash(var91, 0, var91.length)); + byte[] var121 = new byte[var111.getOffset()]; + var111.setOffset(0); + var111.getBytes(var121, 0, var121.length); + if(grab_server_private_exponent != null && grab_server_modulus != null) { + var121 = Utils.cryptRSA(var121, grab_server_private_exponent, grab_server_modulus); + } + + stream.writeBytes(var121); + var91 = new byte[stream.getOffset()]; + stream.setOffset(0); + stream.getBytes(var91, 0, var91.length); + return var91; + } + + public byte[] generateIndex255Archive255() { + return this.generateIndex255Archive255Current((BigInteger)null, (BigInteger)null); + } + + public byte[] generateIndex255Archive255Outdated() { + OutputStream stream = new OutputStream(this.indexes.length * 8); + + for(int var3 = 0; var3 < this.indexes.length; ++var3) { + if(this.indexes[var3] == null) { + stream.writeInt(0); + stream.writeInt(0); + } else { + stream.writeInt(this.indexes[var3].getCRC()); + stream.writeInt(this.indexes[var3].getTable().getRevision()); + } + } + + byte[] var31 = new byte[stream.getOffset()]; + stream.setOffset(0); + stream.getBytes(var31, 0, var31.length); + return var31; + } + + public Index[] getIndexes() { + return this.indexes; + } + + public MainFile getIndex255() { + return this.index255; + } + + public int addIndex(boolean named, boolean usesWhirpool, int tableCompression) throws IOException { + int id = this.indexes.length; + Index[] newIndexes = (Index[])Arrays.copyOf(this.indexes, this.indexes.length + 1); + this.resetIndex(id, newIndexes, named, usesWhirpool, tableCompression); + this.indexes = newIndexes; + return id; + } + + public void resetIndex(int id, boolean named, boolean usesWhirpool, int tableCompression) throws FileNotFoundException, IOException { + this.resetIndex(id, this.indexes, named, usesWhirpool, tableCompression); + } + + public void resetIndex(int id, Index[] indexes, boolean named, boolean usesWhirpool, int tableCompression) throws FileNotFoundException, IOException { + OutputStream stream = new OutputStream(4); + stream.writeByte(5); + stream.writeByte((named?1:0) | (usesWhirpool?2:0)); + stream.writeShort(0); + byte[] archiveData = new byte[stream.getOffset()]; + stream.setOffset(0); + stream.getBytes(archiveData, 0, archiveData.length); + Archive archive = new Archive(id, tableCompression, -1, archiveData); + this.index255.putArchiveData(id, archive.compress()); + indexes[id] = new Index(this.index255, new MainFile(id, this.data, new RandomAccessFile(this.path + "main_file_cache.idx" + id, "rw"), this.newProtocol), (int[])null); + } +} diff --git a/Tools/Frostys Cache Editor/src/com/alex/tools/clientCacheUpdater/ArchiveValidation.java b/Tools/Frostys Cache Editor/src/com/alex/tools/clientCacheUpdater/ArchiveValidation.java new file mode 100644 index 0000000..6c99c01 --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/tools/clientCacheUpdater/ArchiveValidation.java @@ -0,0 +1,48 @@ +package com.alex.tools.clientCacheUpdater; + +import com.alex.store.Archive; +import com.alex.store.ArchiveReference; +import com.alex.store.Index; +import com.alex.store.Store; + +import java.io.IOException; +import java.util.Random; + +public class ArchiveValidation { + public static void main(String[] args) throws IOException { + Store rscache = new Store("718/cache/"); + + for(int i = 0; i < rscache.getIndexes().length; ++i) { + if(i != 5) { + Index index = rscache.getIndexes()[i]; + System.out.println("checking index: " + i); + int[] arr$ = index.getTable().getValidArchiveIds(); + int len$ = arr$.length; + + for(int i$ = 0; i$ < len$; ++i$) { + int archiveId = arr$[i$]; + Archive archive = index.getArchive(archiveId); + if(archive == null) { + System.out.println("Missing:: " + i + ", " + archiveId); + } else { + ArchiveReference reference = index.getTable().getArchives()[archiveId]; + if(archive.getRevision() != reference.getRevision()) { + System.out.println("corrupted: " + i + ", " + archiveId); + } + } + } + } + } + + } + + public static int[] generateKeys() { + int[] keys = new int[4]; + + for(int index = 0; index < keys.length; ++index) { + keys[index] = (new Random()).nextInt(); + } + + return keys; + } +} diff --git a/Tools/Frostys Cache Editor/src/com/alex/tools/clientCacheUpdater/CacheEditor.java b/Tools/Frostys Cache Editor/src/com/alex/tools/clientCacheUpdater/CacheEditor.java new file mode 100644 index 0000000..58ae068 --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/tools/clientCacheUpdater/CacheEditor.java @@ -0,0 +1,192 @@ +package com.alex.tools.clientCacheUpdater; + +import com.alex.loaders.items.ItemDefinitions; +import com.alex.store.Index; +import com.alex.store.Store; +import com.alex.tools.clientCacheUpdater.RSXteas; +import com.alex.utils.Utils; + +import javax.imageio.ImageIO; +import javax.imageio.stream.ImageOutputStream; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; + +public class CacheEditor { + public static byte[] getBytesFromFile(File file) throws IOException { + FileInputStream is = new FileInputStream(file); + long length = file.length(); + if(length > 2147483647L) { + ; + } + + byte[] bytes = new byte[(int)length]; + int offset = 0; + + int numRead1; + for(boolean numRead = false; offset < bytes.length && (numRead1 = is.read(bytes, offset, bytes.length - offset)) >= 0; offset += numRead1) { + ; + } + + if(offset < bytes.length) { + throw new IOException("Could not completely read file " + file.getName()); + } else { + is.close(); + return bytes; + } + } + + public static int packCustomModel(Store cache, byte[] data) { + int archiveId = cache.getIndexes()[7].getLastArchiveId() + 1; + if(cache.getIndexes()[7].putFile(archiveId, 0, data)) { + return archiveId; + } else { + System.out.println("Failing packing model " + archiveId); + return -1; + } + } + + public static void packCustomItem(Store cache, int id, ItemDefinitions def) { + cache.getIndexes()[19].putFile(id >>> 8, 255 & id, def.encode()); + } + + public static void divideBackgrounds() throws IOException { + BufferedImage background = ImageIO.read(new File("718/sprites/bg.jpg")); + int id = 4139; + int sx = background.getWidth() / 4; + int sy = background.getHeight() / 2; + + int y; + for(int var8 = 0; var8 < 2; ++var8) { + for(y = 0; y < 4; ++y) { + BufferedImage var9 = background.getSubimage(y * sx, var8 * sy, sx, sy); + ImageIO.write(var9, "gif", new File("718/sprites/bg/" + id++ + ".gif")); + } + } + + BufferedImage var81 = ImageIO.read(new File("718/sprites/load.png")); + id = 3769; + sx = var81.getWidth() / 2; + sy = var81.getHeight() / 2; + + for(y = 0; y < 2; ++y) { + for(int var91 = 0; var91 < 2; ++var91) { + BufferedImage part = var81.getSubimage(var91 * sx, y * sy, sx, sy); + ImageIO.write(part, "png", new File("718/sprites/load/" + id + ".png")); + ImageIO.write(part, "gif", new File("718/sprites/load/" + id++ + ".gif")); + } + } + + } + + public static byte[] getImage(File file) throws IOException { + ImageOutputStream stream = ImageIO.createImageOutputStream(file); + byte[] data = new byte[(int)stream.length()]; + stream.read(data); + return data; + } + + public static void main(String[] args) throws IOException { + boolean beta = false; + boolean addNewItemDefinitions = false; + boolean divideBackgrounds = false; + if(divideBackgrounds) { + divideBackgrounds(); + } + + Store rscache = new Store(beta?"718/rsCacheBeta/":"718/rscache/"); + Store cache = new Store(beta?"718/cacheBeta/":"718/cache/"); + cache.resetIndex(7, false, false, 2); + + boolean result; + int regionId; + for(regionId = 0; regionId < cache.getIndexes().length; ++regionId) { + if(regionId != 3 && regionId != 5 && regionId != 12) { + result = cache.getIndexes()[regionId].packIndex(rscache, true); + System.out.println("Packed index archives: " + regionId + ", " + result); + } + } + + int regionY; + if(addNewItemDefinitions) { + System.out.println("Packing old item definitions..."); + Store var14 = new Store("cache667/", false); + short var15 = 30000; + regionY = Utils.getItemDefinitionsSize(var14); + + for(int data = var15; data < var15 + regionY; ++data) { + int var16 = data - var15; + cache.getIndexes()[19].putFile(data >>> 8, 255 & data, 2, var14.getIndexes()[19].getFile(var16 >>> 8, 255 & var16), (int[])null, false, false, -1, -1); + } + + result = cache.getIndexes()[19].rewriteTable(); + System.out.println("Packed old item definitions: " + result); + } + + System.out.println("Adding new interfaces..."); + + for(regionId = cache.getIndexes()[3].getLastArchiveId() + 1; regionId <= rscache.getIndexes()[3].getLastArchiveId(); ++regionId) { + if(regionId != 548 && regionId != 746 && rscache.getIndexes()[3].archiveExists(regionId)) { + cache.getIndexes()[3].putArchive(regionId, rscache, false, false); + } + } + + result = cache.getIndexes()[3].rewriteTable(); + System.out.println("Packed new interfaces: " + result); + RSXteas.loadUnpackedXteas("old"); + System.out.println("Updating Maps."); + + for(regionId = 0; regionId < 30000; ++regionId) { + int var13 = (regionId >> 8) * 64; + regionY = (regionId & 255) * 64; + String var141 = "m" + (var13 >> 3) / 8 + "_" + (regionY >> 3) / 8; + byte[] var151 = rscache.getIndexes()[5].getFile(rscache.getIndexes()[5].getArchiveId(var141)); + if(var151 != null) { + result = addMapFile(cache.getIndexes()[5], var141, var151); + System.out.println(var141 + ", " + result); + } + + var141 = "um" + (var13 >> 3) / 8 + "_" + (regionY >> 3) / 8; + var151 = rscache.getIndexes()[5].getFile(rscache.getIndexes()[5].getArchiveId(var141)); + if(var151 != null) { + result = addMapFile(cache.getIndexes()[5], var141, var151); + System.out.println(var141 + ", " + result); + } + + int[] var161 = RSXteas.getXteas(regionId); + var141 = "l" + (var13 >> 3) / 8 + "_" + (regionY >> 3) / 8; + var151 = rscache.getIndexes()[5].getFile(rscache.getIndexes()[5].getArchiveId(var141), 0, var161); + if(var151 != null) { + result = addMapFile(cache.getIndexes()[5], var141, var151); + System.out.println(var141 + ", " + result); + } + + var141 = "ul" + (var13 >> 3) / 8 + "_" + (regionY >> 3) / 8; + var151 = rscache.getIndexes()[5].getFile(rscache.getIndexes()[5].getArchiveId(var141), 0, var161); + if(var151 != null) { + result = addMapFile(cache.getIndexes()[5], var141, var151); + System.out.println(var141 + ", " + result); + } + + var141 = "n" + (var13 >> 3) / 8 + "_" + (regionY >> 3) / 8; + var151 = rscache.getIndexes()[5].getFile(rscache.getIndexes()[5].getArchiveId(var141), 0); + if(var151 != null) { + result = addMapFile(cache.getIndexes()[5], var141, var151); + System.out.println(var141 + ", " + result); + } + } + + result = cache.getIndexes()[5].rewriteTable(); + System.out.println("Updated maps: " + result); + } + + public static boolean addMapFile(Index index, String name, byte[] data) { + int archiveId = index.getArchiveId(name); + if(archiveId == -1) { + archiveId = index.getTable().getValidArchiveIds().length; + } + + return index.putFile(archiveId, 0, 2, data, (int[])null, false, false, Utils.getNameHash(name), -1); + } +} diff --git a/Tools/Frostys Cache Editor/src/com/alex/tools/clientCacheUpdater/CacheEditormodels.java b/Tools/Frostys Cache Editor/src/com/alex/tools/clientCacheUpdater/CacheEditormodels.java new file mode 100644 index 0000000..05b516d --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/tools/clientCacheUpdater/CacheEditormodels.java @@ -0,0 +1,135 @@ +package com.alex.tools.clientCacheUpdater; + +import com.alex.loaders.items.ItemDefinitions; +import com.alex.store.Store; +import com.alex.utils.Utils; + +import javax.imageio.ImageIO; +import javax.imageio.stream.ImageOutputStream; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; + +public class CacheEditormodels { + public static byte[] getBytesFromFile(File file) throws IOException { + FileInputStream is = new FileInputStream(file); + long length = file.length(); + if(length > 2147483647L) { + ; + } + + byte[] bytes = new byte[(int)length]; + int offset = 0; + + int numRead1; + for(boolean numRead = false; offset < bytes.length && (numRead1 = is.read(bytes, offset, bytes.length - offset)) >= 0; offset += numRead1) { + ; + } + + if(offset < bytes.length) { + throw new IOException("Could not completely read file " + file.getName()); + } else { + is.close(); + return bytes; + } + } + + public static int packCustomModel(Store cache, byte[] data) { + int archiveId = cache.getIndexes()[7].getLastArchiveId() + 1; + if(cache.getIndexes()[7].putFile(archiveId, 0, data)) { + return archiveId; + } else { + System.out.println("Failing packing model " + archiveId); + return -1; + } + } + + public static void packCustomItems(Store cache) throws IOException { + int modelID = packCustomModel(cache, getBytesFromFile(new File("pkcapefinalb.dat"))); + ItemDefinitions pkCape = ItemDefinitions.getItemDefinition(cache, 9747); + pkCape.setName("PK Cape"); + pkCape.femaleEquip1 = modelID; + pkCape.maleEquip1 = modelID; + pkCape.modelId = modelID; + pkCape.resetModelColors(); + packCustomItem(cache, 30000, pkCape); + } + + public static void packCustomItem(Store cache, int id, ItemDefinitions def) { + cache.getIndexes()[19].putFile(id >>> 8, 255 & id, def.encode()); + } + + public static void divideBackgrounds() throws IOException { + BufferedImage background = ImageIO.read(new File("718/sprites/bg.jpg")); + int id = 4139; + int sx = background.getWidth() / 4; + int sy = background.getHeight() / 2; + + int y; + for(int var8 = 0; var8 < 2; ++var8) { + for(y = 0; y < 4; ++y) { + BufferedImage var9 = background.getSubimage(y * sx, var8 * sy, sx, sy); + ImageIO.write(var9, "gif", new File("718/sprites/bg/" + id++ + ".gif")); + } + } + + BufferedImage var81 = ImageIO.read(new File("718/sprites/load.png")); + id = 3769; + sx = var81.getWidth() / 2; + sy = var81.getHeight() / 2; + + for(y = 0; y < 2; ++y) { + for(int var91 = 0; var91 < 2; ++var91) { + BufferedImage part = var81.getSubimage(var91 * sx, y * sy, sx, sy); + ImageIO.write(part, "png", new File("718/sprites/load/" + id + ".png")); + ImageIO.write(part, "gif", new File("718/sprites/load/" + id++ + ".gif")); + } + } + + } + + public static byte[] getImage(File file) throws IOException { + ImageOutputStream stream = ImageIO.createImageOutputStream(file); + byte[] data = new byte[(int)stream.length()]; + stream.read(data); + return data; + } + + public static void main(String[] args) throws IOException { + boolean beta = false; + boolean addNewItemDefinitions = false; + boolean divideBackgrounds = false; + if(divideBackgrounds) { + divideBackgrounds(); + } + + Store rscache = new Store(beta?"718/rsCacheBeta/":"718/rscache/"); + Store cache = new Store(beta?"718/cacheBeta/":"718/cache/"); + cache.resetIndex(7, false, false, 2); + + boolean result; + for(int var13 = 0; var13 < cache.getIndexes().length; ++var13) { + if(var13 != 3 && var13 != 5 && var13 != 12) { + result = cache.getIndexes()[var13].packIndex(rscache, true); + System.out.println("Packed index archives: " + var13 + ", " + result); + } + } + + if(addNewItemDefinitions) { + System.out.println("Packing old item definitions..."); + Store var12 = new Store("cache667/", false); + short currentSize = 30000; + int oldSize = Utils.getItemDefinitionsSize(var12); + + for(int i = currentSize; i < currentSize + oldSize; ++i) { + int oldItemId = i - currentSize; + cache.getIndexes()[19].putFile(i >>> 8, 255 & i, 2, var12.getIndexes()[19].getFile(oldItemId >>> 8, 255 & oldItemId), (int[])null, false, false, -1, -1); + } + + result = cache.getIndexes()[19].rewriteTable(); + System.out.println("Packed old item definitions: " + result); + } + + } +} diff --git a/Tools/Frostys Cache Editor/src/com/alex/tools/clientCacheUpdater/CheckMap.java b/Tools/Frostys Cache Editor/src/com/alex/tools/clientCacheUpdater/CheckMap.java new file mode 100644 index 0000000..7deec62 --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/tools/clientCacheUpdater/CheckMap.java @@ -0,0 +1,96 @@ +package com.alex.tools.clientCacheUpdater; + +import com.alex.store.Store; +import com.alex.utils.Utils; + +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.IOException; +import java.util.Arrays; +import java.util.Random; + +public class CheckMap { + public static void main(String[] args) throws IOException { + Store cache = new Store("C:/Users/yvonne � christer/Dropbox/Source/data/562cache/", false, (int[][])null); + double land = 0.0D; + double map = 0.0D; + + for(int var11 = 0; var11 < 30000; ++var11) { + int regionX = (var11 >> 8) * 64; + int regionY = (var11 & 255) * 64; + String name1 = "l" + (regionX >> 3) / 8 + "_" + (regionY >> 3) / 8; + String name2 = "m" + (regionX >> 3) / 8 + "_" + (regionY >> 3) / 8; + if(cache.getIndexes()[5].getArchiveId(name1) != -1) { + ++land; + } + + if(cache.getIndexes()[5].getArchiveId(name2) != -1) { + ++map; + } + } + + System.out.println("land: " + land + ", newMaps: " + map); + double var111 = land * 100.0D / map; + System.out.println(var111 + "% complete!"); + } + + public static boolean passArchive(int regionId, Store store1, Store store2, String nameHash, int i, int[] keys1, int[] keys2) { + if(keys2 != null) { + System.out.println(keys2); + } + + int archiveId = store1.getIndexes()[i].getArchiveId(nameHash); + if(archiveId == -1) { + return false; + } else { + int oldArchiveId = store2.getIndexes()[i].getArchiveId(nameHash); + if(oldArchiveId == -1) { + oldArchiveId = store2.getIndexes()[i].getLastArchiveId() + 1; + } + + byte[] data = store1.getIndexes()[i].getFile(archiveId, 0, keys1); + if(data == null) { + return false; + } else { + try { + boolean var13 = store2.getIndexes()[i].putFile(oldArchiveId, 0, 2, data, keys2, false, false, Utils.getNameHash(nameHash), -1); + if(!var13) { + return false; + } else { + int[] keys = writeKeys(regionId); + return store2.getIndexes()[i].encryptArchive(oldArchiveId, keys2, keys, false, false); + } + } catch (Error var12) { + return false; + } catch (Exception var131) { + var131.printStackTrace(); + return false; + } + } + } + } + + public static int[] generateKeys() { + int[] keys = new int[4]; + + for(int index = 0; index < keys.length; ++index) { + keys[index] = (new Random()).nextInt(); + } + + return keys; + } + + public static int[] writeKeys(int regionId) throws IOException { + BufferedWriter writer = new BufferedWriter(new FileWriter("C:/Users/yvonne � christer/Desktop/LS/Xteas/xteas/742/" + regionId + ".txt")); + int[] keys = generateKeys(); + + for(int index = 0; index < keys.length; ++index) { + writer.write("" + keys[index]); + writer.newLine(); + writer.flush(); + } + + System.out.println("Region: " + regionId + ", " + Arrays.toString(keys)); + return keys; + } +} diff --git a/Tools/Frostys Cache Editor/src/com/alex/tools/clientCacheUpdater/CopyCache.java b/Tools/Frostys Cache Editor/src/com/alex/tools/clientCacheUpdater/CopyCache.java new file mode 100644 index 0000000..090d562 --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/tools/clientCacheUpdater/CopyCache.java @@ -0,0 +1,22 @@ +package com.alex.tools.clientCacheUpdater; + +import com.alex.store.Index; +import com.alex.store.Store; + +import java.io.IOException; + +public class CopyCache { + public static void main(String[] args) throws IOException { + Store cache = new Store("718/cache/"); + Store newCache = new Store("718/cacheCleaned/"); + + for(int i = 0; i < cache.getIndexes().length; ++i) { + Index index = cache.getIndexes()[i]; + newCache.addIndex(index.getTable().isNamed(), index.getTable().usesWhirpool(), 2); + newCache.getIndexes()[i].packIndex(cache); + newCache.getIndexes()[i].getTable().setRevision(cache.getIndexes()[i].getTable().getRevision()); + newCache.getIndexes()[i].rewriteTable(); + } + + } +} diff --git a/Tools/Frostys Cache Editor/src/com/alex/tools/clientCacheUpdater/OriginalXteas.java b/Tools/Frostys Cache Editor/src/com/alex/tools/clientCacheUpdater/OriginalXteas.java new file mode 100644 index 0000000..d919dc5 --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/tools/clientCacheUpdater/OriginalXteas.java @@ -0,0 +1,57 @@ +package com.alex.tools.clientCacheUpdater; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.HashMap; + +public final class OriginalXteas { + public static final HashMap mapContainersXteas = new HashMap(); + + public static final int[] getXteas(int regionId) { + return (int[])mapContainersXteas.get(Integer.valueOf(regionId)); + } + + public static void init() { + loadUnpackedXteas(); + } + + public static final void delete() { + } + + public static final void loadUnpackedXteas() { + try { + File var11 = new File("cache667_protected/keys"); + File[] xteasFiles = var11.listFiles(); + File[] arr$ = xteasFiles; + int len$ = xteasFiles.length; + + for(int i$ = 0; i$ < len$; ++i$) { + File region = arr$[i$]; + String name = region.getName(); + if(!name.contains(".txt")) { + region.delete(); + } else { + short regionId = Short.parseShort(name.replace(".txt", "")); + if(regionId <= 0) { + region.delete(); + } else { + BufferedReader in = new BufferedReader(new FileReader(region)); + int[] xteas = new int[4]; + + for(int index = 0; index < 4; ++index) { + xteas[index] = Integer.parseInt(in.readLine()); + } + + mapContainersXteas.put(Integer.valueOf(regionId), xteas); + in.close(); + } + } + } + } catch (IOException var111) { + var111.printStackTrace(); + } + + } +} diff --git a/Tools/Frostys Cache Editor/src/com/alex/tools/clientCacheUpdater/ProtectCache.java b/Tools/Frostys Cache Editor/src/com/alex/tools/clientCacheUpdater/ProtectCache.java new file mode 100644 index 0000000..5b81b93 --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/tools/clientCacheUpdater/ProtectCache.java @@ -0,0 +1,99 @@ +package com.alex.tools.clientCacheUpdater; + +import com.alex.store.Index; +import com.alex.store.Store; + +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.IOException; +import java.util.Arrays; +import java.util.Random; + +public class ProtectCache { + public static void main(String[] args) throws IOException { + boolean encryptMaps = true; + boolean encryptTables = false; + Store cache = new Store("718/cacheEncrypted/"); + if(encryptMaps) { + Store var13 = new Store("718/rscache/"); + Index var14 = cache.getIndexes()[5]; + Index rsIndex = var13.getIndexes()[5]; + + for(int regionId = 0; regionId < 25000; ++regionId) { + int regionX = (regionId >> 8) * 64; + int regionY = (regionId & 255) * 64; + int[] keys1 = null; + String name = "l" + (regionX >> 3) / 8 + "_" + (regionY >> 3) / 8; + int archiveId; + if(rsIndex.getFile(rsIndex.getArchiveId(name), 0) == null) { + archiveId = var14.getArchiveId(name); + if(archiveId != -1) { + keys1 = writeKeys(regionId); + if(!var14.encryptArchive(archiveId, (int[])null, keys1, false, false)) { + throw new RuntimeException("FAIL"); + } + } + } + + name = "ul" + (regionX >> 3) / 8 + "_" + (regionY >> 3) / 8; + if(rsIndex.getFile(rsIndex.getArchiveId(name), 0) == null) { + archiveId = var14.getArchiveId(name); + if(archiveId != -1) { + if(keys1 == null) { + keys1 = writeKeys(regionId); + } + + if(!var14.encryptArchive(archiveId, (int[])null, keys1, false, false)) { + throw new RuntimeException("FAIL"); + } + } + } + } + + var14.rewriteTable(); + } + + if(encryptTables) { + int[][] var131 = new int[cache.getIndexes().length][]; + + int var141; + for(var141 = 0; var141 < var131.length; ++var141) { + var131[var141] = generateKeys(); + if(cache.getIndexes()[var141] != null) { + System.out.println("encrypting idx table: " + var141); + cache.getIndexes()[var141].setKeys(var131[var141]); + cache.getIndexes()[var141].rewriteTable(); + } + } + + for(var141 = 0; var141 < var131.length; ++var141) { + System.out.println(Arrays.toString(var131[var141])); + } + } + + } + + public static int[] generateKeys() { + int[] keys = new int[4]; + + for(int index = 0; index < keys.length; ++index) { + keys[index] = (new Random()).nextInt(); + } + + return keys; + } + + public static int[] writeKeys(int regionId) throws IOException { + BufferedWriter writer = new BufferedWriter(new FileWriter("718/maps/unpacked/" + regionId + ".txt")); + int[] keys = generateKeys(); + + for(int index = 0; index < keys.length; ++index) { + writer.write("" + keys[index]); + writer.newLine(); + writer.flush(); + } + + System.out.println("Region: " + regionId + ", " + Arrays.toString(keys)); + return keys; + } +} diff --git a/Tools/Frostys Cache Editor/src/com/alex/tools/clientCacheUpdater/RSXteas.java b/Tools/Frostys Cache Editor/src/com/alex/tools/clientCacheUpdater/RSXteas.java new file mode 100644 index 0000000..f293f78 --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/tools/clientCacheUpdater/RSXteas.java @@ -0,0 +1,49 @@ +package com.alex.tools.clientCacheUpdater; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.util.HashMap; + +public final class RSXteas { + public static final HashMap mapContainersXteas = new HashMap(); + + public static final int[] getXteas(int regionId) { + return (int[])mapContainersXteas.get(Integer.valueOf(regionId)); + } + + public static final void loadUnpackedXteas(String location) { + try { + File var12 = new File(location); + File[] xteasFiles = var12.listFiles(); + File[] arr$ = xteasFiles; + int len$ = xteasFiles.length; + + for(int i$ = 0; i$ < len$; ++i$) { + File region = arr$[i$]; + String name = region.getName(); + if(!name.contains(".txt")) { + region.delete(); + } else { + short regionId = Short.parseShort(name.replace(".txt", "")); + if(regionId <= 0) { + region.delete(); + } else { + BufferedReader in = new BufferedReader(new FileReader(region)); + int[] xteas = new int[4]; + + for(int index = 0; index < 4; ++index) { + xteas[index] = Integer.parseInt(in.readLine()); + } + + mapContainersXteas.put(Integer.valueOf(regionId), xteas); + in.close(); + } + } + } + } catch (Exception var121) { + var121.printStackTrace(); + } + + } +} diff --git a/Tools/Frostys Cache Editor/src/com/alex/tools/clientCacheUpdater/SpritesDumper.java b/Tools/Frostys Cache Editor/src/com/alex/tools/clientCacheUpdater/SpritesDumper.java new file mode 100644 index 0000000..7e21c02 --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/tools/clientCacheUpdater/SpritesDumper.java @@ -0,0 +1,116 @@ +package com.alex.tools.clientCacheUpdater; + +import com.alex.store.Index; +import com.alex.store.Store; +import com.alex.tools.clientCacheUpdater.UpdateCache; + +import javax.imageio.ImageIO; +import javax.imageio.stream.ImageOutputStream; +import java.awt.image.BufferedImage; +import java.awt.image.ImageObserver; +import java.io.File; +import java.io.IOException; + +public class SpritesDumper { + public static void main2(String[] args) throws IOException { + BufferedImage background = ImageIO.read(new File("bg/matrix.jpg")); + int id = 3769; + int sx = background.getWidth() / 2; + int sy = background.getHeight() / 2; + + for(int y = 0; y < 2; ++y) { + for(int x = 0; x < 2; ++x) { + System.out.println("id " + id); + BufferedImage part = background.getSubimage(x * sx, y * sy, sx, sy); + ImageIO.write(part, "gif", new File("bg/" + id++ + ".gif")); + } + } + + } + + public static void main3(String[] args) throws IOException { + Store cache = new Store("cache667_2/", false); + UpdateCache.packLogo(cache); + System.out.println("Adding donator icon..."); + UpdateCache.packDonatorIcon(cache); + System.out.println("Adding Matrix icon..."); + UpdateCache.packMatrixIcon(cache); + } + + public static byte[] getImage(File file) throws IOException { + ImageOutputStream stream = ImageIO.createImageOutputStream(file); + byte[] data = new byte[(int)stream.length()]; + stream.read(data); + return data; + } + + public static void main(String[] args) throws IOException { + Store cache = new Store("718/rscache/"); + Index sprites = cache.getIndexes()[32]; + int[] arr$ = sprites.getTable().getValidArchiveIds(); + int len$ = arr$.length; + + for(int i$ = 0; i$ < len$; ++i$) { + int archiveId = arr$[i$]; + int[] arr$1 = sprites.getTable().getArchives()[archiveId].getValidFileIds(); + int len$1 = arr$1.length; + + for(int i$1 = 0; i$1 < len$1; ++i$1) { + int fileId = arr$1[i$1]; + byte[] data = sprites.getFile(archiveId, fileId); + Image image = Toolkit.getDefaultToolkit().createImage(data); + String name = "sprites32/" + archiveId + "_" + fileId; + BufferedImage bi = toBufferedImage(image); + if(bi == null) { + System.out.println("failed " + name); + } else { + ImageIO.write(bi, "png", new File(name + ".png")); + } + } + } + + } + + public static BufferedImage toBufferedImage(Image image) { + if(image instanceof BufferedImage) { + return (BufferedImage)image; + } else { + image = (new ImageIcon(image)).getImage(); + boolean hasAlpha = true; + BufferedImage bimage = null; + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + + byte g; + try { + g = 1; + if(hasAlpha) { + g = 2; + } + + GraphicsDevice g1 = ge.getDefaultScreenDevice(); + GraphicsConfiguration gc = g1.getDefaultConfiguration(); + if(image.getWidth((ImageObserver)null) < 0 || image.getHeight((ImageObserver)null) < 0) { + return null; + } + + bimage = gc.createCompatibleImage(image.getWidth((ImageObserver)null), image.getHeight((ImageObserver)null), g); + } catch (HeadlessException var7) { + ; + } + + if(bimage == null) { + g = 1; + if(hasAlpha) { + g = 2; + } + + bimage = new BufferedImage(image.getWidth((ImageObserver)null), image.getHeight((ImageObserver)null), g); + } + + Graphics2D g11 = bimage.createGraphics(); + g11.drawImage(image, 0, 0, (ImageObserver)null); + g11.dispose(); + return bimage; + } + } +} diff --git a/Tools/Frostys Cache Editor/src/com/alex/tools/clientCacheUpdater/UpdateCache.java b/Tools/Frostys Cache Editor/src/com/alex/tools/clientCacheUpdater/UpdateCache.java new file mode 100644 index 0000000..a277ea2 --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/tools/clientCacheUpdater/UpdateCache.java @@ -0,0 +1,357 @@ +package com.alex.tools.clientCacheUpdater; + +import com.alex.loaders.images.IndexedColorImageFile; +import com.alex.loaders.items.ItemDefinitions; +import com.alex.store.Index; +import com.alex.store.Store; +import com.alex.tools.clientCacheUpdater.RSXteas; +import com.alex.tools.clientCacheUpdater.SpritesDumper; +import com.alex.utils.Utils; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; + +public class UpdateCache { + public static byte[] getBytesFromFile(File file) throws IOException { + FileInputStream is = new FileInputStream(file); + long length = file.length(); + if(length > 2147483647L) { + ; + } + + byte[] bytes = new byte[(int)length]; + int offset = 0; + + int numRead1; + for(boolean numRead = false; offset < bytes.length && (numRead1 = is.read(bytes, offset, bytes.length - offset)) >= 0; offset += numRead1) { + ; + } + + if(offset < bytes.length) { + throw new IOException("Could not completely read file " + file.getName()); + } else { + is.close(); + return bytes; + } + } + + public static void main6(String[] args) throws IOException { + Store cache = new Store("cache667_2/", false); + cache.getIndexes()[6].putFile(0, 0, getBytesFromFile(new File("0"))); + } + + public static void main5(String[] args) throws IOException { + Store rscache = new Store("cache697/"); + Store cache = new Store("cache667_2/", false); + boolean result = false; + result = cache.getIndexes()[3].putArchive(320, rscache, false, false); + System.out.println("Packed skill interface: 320, " + result); + result = cache.getIndexes()[3].putArchive(679, rscache, false, false); + System.out.println("Packed skill interface: 679, " + result); + cache.getIndexes()[3].rewriteTable(); + } + + public static void main555(String[] args) throws IOException { + Store cache = new Store("cache667_2/", false); + Store originalCache = new Store("rscache/", false); + cache.addIndex(false, false, 2); + int[] arr$ = originalCache.getIndexes()[19].getTable().getValidArchiveIds(); + int len$ = arr$.length; + + for(int i$ = 0; i$ < len$; ++i$) { + int i = arr$[i$]; + System.out.println(i); + int[] arr$1 = originalCache.getIndexes()[19].getTable().getArchives()[i].getValidFileIds(); + int len$1 = arr$1.length; + + for(int i$1 = 0; i$1 < len$1; ++i$1) { + int i2 = arr$1[i$1]; + + try { + cache.getIndexes()[37].putFile(i, i2, 2, originalCache.getIndexes()[19].getFile(i, i2), (int[])null, false, false, -1, -1); + } catch (Throwable var12) { + var12.printStackTrace(); + } + } + } + + cache.getIndexes()[37].rewriteTable(); + } + + public static void main77(String[] args) throws IOException { + Store originalCache = new Store("cache667/", false); + Store cache = new Store("cache667_2/", false); + + for(int i = 1610; i < 1616; ++i) { + cache.getIndexes()[17].putFile(i >>> 8, i & 255, originalCache.getIndexes()[17].getFile(i >>> 8, i & 255)); + } + + } + + public static void packLogo(Store cache) throws IOException { + short id = 2498; + IndexedColorImageFile f = null; + + try { + f = new IndexedColorImageFile(new BufferedImage[]{ImageIO.read(new File("bg/logo.png"))}); + } catch (IOException var81) { + var81.printStackTrace(); + } + + byte[] data = f.encodeFile(); + cache.getIndexes()[8].putFile(id, 0, data); + + int i; + for(i = 4139; i <= 4146; ++i) { + try { + cache.getIndexes()[8].putFile(i, 0, (new IndexedColorImageFile(new BufferedImage[]{ImageIO.read(new File("bg/" + i + ".gif"))})).encodeFile()); + } catch (IOException var7) { + var7.printStackTrace(); + } + } + + for(i = 0; i < 4; ++i) { + int realid = 3769 + i; + int var8 = 3769 + i; + cache.getIndexes()[8].putFile(var8, 0, (new IndexedColorImageFile(new BufferedImage[]{ImageIO.read(new File("bg/" + realid + ".gif"))})).encodeFile()); + var8 = 3779 + i; + cache.getIndexes()[8].putFile(var8, 0, (new IndexedColorImageFile(new BufferedImage[]{ImageIO.read(new File("bg/" + realid + ".gif"))})).encodeFile()); + var8 = 3783 + (i >= 2?i - 2:i + 2); + cache.getIndexes()[8].putFile(var8, 0, (new IndexedColorImageFile(new BufferedImage[]{ImageIO.read(new File("bg/" + realid + ".gif"))})).encodeFile()); + var8 = 3769 + i; + cache.getIndexes()[34].putFile(var8, 0, (new IndexedColorImageFile(new BufferedImage[]{ImageIO.read(new File("bg/" + realid + ".gif"))})).encodeFile()); + var8 = 3779 + i; + cache.getIndexes()[34].putFile(var8, 0, (new IndexedColorImageFile(new BufferedImage[]{ImageIO.read(new File("bg/" + realid + ".gif"))})).encodeFile()); + var8 = 3783 + (i >= 2?i - 2:i + 2); + cache.getIndexes()[34].putFile(var8, 0, (new IndexedColorImageFile(new BufferedImage[]{ImageIO.read(new File("bg/" + realid + ".gif"))})).encodeFile()); + var8 = 3769 + i; + cache.getIndexes()[32].putFile(var8, 0, SpritesDumper.getImage(new File("bg/" + realid + ".png"))); + var8 = 3779 + i; + cache.getIndexes()[32].putFile(var8, 0, SpritesDumper.getImage(new File("bg/" + realid + ".png"))); + var8 = 3783 + (i >= 2?i - 2:i + 2); + cache.getIndexes()[32].putFile(var8, 0, SpritesDumper.getImage(new File("bg/" + realid + ".png"))); + System.out.println("added file: " + i); + } + + } + + public static void packDonatorIcon(Store cache) { + short id = 1455; + IndexedColorImageFile f = null; + + try { + f = new IndexedColorImageFile(cache, id, 0); + BufferedImage var7 = ImageIO.read(new File("1455.png")); + System.out.println("Added icon: " + f.addImage(var7) + "."); + BufferedImage icon2 = ImageIO.read(new File("1455f.png")); + System.out.println("Added icon2: " + f.addImage(icon2) + "."); + BufferedImage icon3 = ImageIO.read(new File("crown_green.gif")); + System.out.println("Added icon3: " + f.addImage(icon3) + "."); + BufferedImage icon4 = ImageIO.read(new File("1455_11.png")); + System.out.println("Added icon4: " + f.addImage(icon4) + "."); + } catch (IOException var71) { + var71.printStackTrace(); + } + + cache.getIndexes()[8].putFile(id, 0, f.encodeFile()); + } + + public static void packMatrixIcon(Store cache) { + short id = 2173; + IndexedColorImageFile f = null; + + try { + f = new IndexedColorImageFile(new BufferedImage[]{ImageIO.read(new File("2173.png"))}); + } catch (IOException var4) { + var4.printStackTrace(); + } + + byte[] data = f.encodeFile(); + cache.getIndexes()[8].putFile(id, 0, data); + } + + public static int packCustomModel(Store cache, byte[] data) { + int archiveId = cache.getIndexes()[7].getLastArchiveId() + 1; + if(cache.getIndexes()[7].putFile(archiveId, 0, data)) { + return archiveId; + } else { + System.out.println("Failing packing model " + archiveId); + return -1; + } + } + + public static void packCustomItems(Store cache) throws IOException { + int modelID = packCustomModel(cache, getBytesFromFile(new File("donatorCape.dat"))); + System.out.println("model id " + modelID); + ItemDefinitions donatorCape = ItemDefinitions.getItemDefinition(cache, 9747); + donatorCape.setName("Donator cape"); + donatorCape.femaleEquip1 = modelID; + donatorCape.maleEquip1 = modelID; + donatorCape.modelId = modelID; + donatorCape.resetModelColors(); + short newId = 29999; + System.out.println(cache.getIndexes()[19].putFile(newId >>> 8, 255 & newId, donatorCape.encode())); + } + + public static void main(String[] args) throws IOException { + boolean updateJustMaps = false; + boolean addOldItems = true; + Store rscache = new Store("cache697/"); + Store cache = new Store("cache667_2/", false); + Store originalCache = new Store("cache667/", false); + if(addOldItems) { + cache.resetIndex(19, false, false, 2); + } + + cache.resetIndex(7, false, false, 2); + cache.getIndexes()[7].packIndex(originalCache); + int regionId; + int regionX; + int regionY; + boolean var20; + int[] xteas; + if(!updateJustMaps) { + int var19; + for(var19 = 0; var19 < cache.getIndexes().length; ++var19) { + if(var19 != 3 && var19 != 5 && var19 != 12 && var19 != 33 && var19 != 30) { + boolean var21 = cache.getIndexes()[var19].packIndex(rscache, true); + System.out.println("Packed index archives: " + var19 + ", " + var21); + } + } + + System.out.println("Adding logo..."); + packLogo(cache); + System.out.println("Adding donator icon..."); + packDonatorIcon(cache); + System.out.println("Adding Matrix icon..."); + packMatrixIcon(cache); + System.out.println("Adding Custom items..."); + packCustomItems(cache); + int var22; + int var17; + if(addOldItems) { + System.out.println("Adding back old item definitions..."); + short var24 = 30000; + System.out.println(var24); + var22 = Utils.getItemDefinitionsSize(originalCache); + + for(var17 = var24; var17 < var24 + var22; ++var17) { + regionId = var17 - var24; + cache.getIndexes()[19].putFile(var17 >>> 8, 255 & var17, 2, originalCache.getIndexes()[19].getFile(regionId >>> 8, 255 & regionId), (int[])null, false, false, -1, -1); + } + + cache.getIndexes()[19].rewriteTable(); + } + + System.out.println("Recovering Client Script Maps..."); + int[] var211 = originalCache.getIndexes()[17].getTable().getValidArchiveIds(); + var22 = var211.length; + + for(var17 = 0; var17 < var22; ++var17) { + int data = var211[var17]; + xteas = originalCache.getIndexes()[17].getTable().getArchives()[data].getValidFileIds(); + regionX = xteas.length; + + for(regionY = 0; regionY < regionX; ++regionY) { + int name = xteas[regionY]; + if(!cache.getIndexes()[17].fileExists(data, name) || cache.getIndexes()[17].getFile(data, name).length == 1) { + cache.getIndexes()[17].putFile(data, name, originalCache.getIndexes()[17].getFile(data, name)); + } + } + } + + System.out.println("Recovering Bank Client Script Maps..."); + + for(var19 = 1610; var19 < 1616; ++var19) { + cache.getIndexes()[17].putFile(var19 >>> 8, var19 & 255, originalCache.getIndexes()[17].getFile(var19 >>> 8, var19 & 255)); + } + + System.out.println("Adding new interfaces..."); + + for(var19 = cache.getIndexes()[3].getLastArchiveId() + 1; var19 <= rscache.getIndexes()[3].getLastArchiveId(); ++var19) { + if(rscache.getIndexes()[3].archiveExists(var19)) { + cache.getIndexes()[3].putArchive(var19, rscache, false, false); + } + } + + cache.getIndexes()[3].putArchive(320, rscache, false, false); + cache.getIndexes()[3].putArchive(751, rscache, false, false); + cache.getIndexes()[3].putArchive(1092, rscache, false, false); + var20 = cache.getIndexes()[3].rewriteTable(); + cache.getIndexes()[8].rewriteTable(); + System.out.println("Packed new interfaces: " + var20); + } + + Index var18 = cache.getIndexes()[5]; + Index var191 = rscache.getIndexes()[5]; + Index var201 = originalCache.getIndexes()[5]; + RSXteas.loadUnpackedXteas("old"); + System.out.println("Updating Maps."); + + for(regionId = 0; regionId < 30000; ++regionId) { + regionX = (regionId >> 8) * 64; + regionY = (regionId & 255) * 64; + String var221 = "m" + (regionX >> 3) / 8 + "_" + (regionY >> 3) / 8; + byte[] var23 = var191.getFile(var191.getArchiveId(var221)); + if(var23 == null) { + var23 = var201.getFile(var201.getArchiveId(var221)); + } + + if(var23 != null) { + var20 = addMapFile(var18, var221, var23); + System.out.println(var221 + ", " + var20); + } + + var221 = "um" + (regionX >> 3) / 8 + "_" + (regionY >> 3) / 8; + var23 = var191.getFile(var191.getArchiveId(var221)); + if(var23 == null) { + var23 = var201.getFile(var201.getArchiveId(var221)); + } + + if(var23 != null) { + var20 = addMapFile(var18, var221, var23); + System.out.println(var221 + ", " + var20); + } + + xteas = RSXteas.getXteas(regionId); + var221 = "l" + (regionX >> 3) / 8 + "_" + (regionY >> 3) / 8; + var23 = var191.getFile(var191.getArchiveId(var221), 0, xteas); + if(var23 != null) { + var20 = addMapFile(var18, var221, var23); + System.out.println(var221 + ", " + var20); + } + + var221 = "ul" + (regionX >> 3) / 8 + "_" + (regionY >> 3) / 8; + var23 = var191.getFile(var191.getArchiveId(var221), 0, xteas); + if(var23 != null) { + var20 = addMapFile(var18, var221, var23); + System.out.println(var221 + ", " + var20); + } + + var221 = "n" + (regionX >> 3) / 8 + "_" + (regionY >> 3) / 8; + var23 = var191.getFile(var191.getArchiveId(var221), 0); + if(var23 == null) { + var23 = var201.getFile(var201.getArchiveId(var221), 0); + } + + if(var23 != null) { + var20 = addMapFile(var18, var221, var23); + System.out.println(var221 + ", " + var20); + } + } + + var18.rewriteTable(); + } + + public static boolean addMapFile(Index index, String name, byte[] data) { + int archiveId = index.getArchiveId(name); + if(archiveId == -1) { + archiveId = index.getTable().getValidArchiveIds().length; + } + + return index.putFile(archiveId, 0, 2, data, (int[])null, false, false, Utils.getNameHash(name), -1); + } +} diff --git a/Tools/Frostys Cache Editor/src/com/alex/tools/itemsDefsEditor/Application.java b/Tools/Frostys Cache Editor/src/com/alex/tools/itemsDefsEditor/Application.java new file mode 100644 index 0000000..e52a09a --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/tools/itemsDefsEditor/Application.java @@ -0,0 +1,197 @@ +package com.alex.tools.itemsDefsEditor; + +import com.alex.loaders.items.ItemDefinitions; +import com.alex.store.Store; +import com.alex.tools.itemsDefsEditor.GeneratedUkeys; +import com.alex.tools.itemsDefsEditor.ItemDefsEditor; +import com.alex.utils.Utils; + +import javax.swing.UIManager.LookAndFeelInfo; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.IOException; + +public class Application { + public static Store STORE; + private JFrame frmCacheEditorV; + private JList itemsList; + private DefaultListModel itemsListmodel; + + public static void main(String[] args) throws IOException { + STORE = new Store("cache/", false); + EventQueue.invokeLater(new Runnable() { + public void run() { + try { + Application var2 = new Application(); + var2.frmCacheEditorV.setVisible(true); + } catch (Exception var21) { + var21.printStackTrace(); + } + + } + }); + } + + public Application() { + this.initialize(); + } + + private void setLook() { + boolean found = false; + LookAndFeelInfo[] e = UIManager.getInstalledLookAndFeels(); + int len$ = e.length; + + for(int var7 = 0; var7 < len$; ++var7) { + LookAndFeelInfo info = e[var7]; + if(info.getName().equals("Nimbus")) { + try { + UIManager.setLookAndFeel(info.getClassName()); + found = true; + } catch (Exception var8) { + var8.printStackTrace(); + } + } + } + + if(!found) { + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } catch (Exception var71) { + var71.printStackTrace(); + } + } + + } + + private void initialize() { + this.setLook(); + this.frmCacheEditorV = new JFrame(); + this.frmCacheEditorV.setTitle("Cache Editor V0.1"); + this.frmCacheEditorV.setBounds(100, 100, 352, 435); + this.frmCacheEditorV.setDefaultCloseOperation(3); + JTabbedPane tabbedPane = new JTabbedPane(1); + this.frmCacheEditorV.getContentPane().add(tabbedPane, "Center"); + JPanel panel = new JPanel(); + tabbedPane.addTab("Main", (Icon)null, panel, (String)null); + panel.setLayout((LayoutManager)null); + JButton btnGenerateUkeys = new JButton("Generate Ukeys (614- Client Builts)"); + btnGenerateUkeys.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + byte[] ukeys = Utils.getArchivePacketData(255, 255, Application.STORE.generateIndex255Archive255Outdated()); + new GeneratedUkeys(Application.this.getFrame(), ukeys); + } + }); + btnGenerateUkeys.setBounds(33, 64, 257, 28); + panel.add(btnGenerateUkeys); + JLabel lblCreatedByAlexalso = new JLabel("Created By Alex(Also named Dragonkk)"); + lblCreatedByAlexalso.setFont(new Font("Tekton Pro Ext", 0, 15)); + lblCreatedByAlexalso.setBounds(6, 290, 322, 46); + panel.add(lblCreatedByAlexalso); + JPanel panel_1 = new JPanel(); + tabbedPane.addTab("Items", (Icon)null, panel_1, (String)null); + panel_1.setLayout((LayoutManager)null); + this.itemsListmodel = new DefaultListModel(); + this.itemsList = new JList(this.itemsListmodel); + this.itemsList.setSelectionMode(1); + this.itemsList.setLayoutOrientation(0); + this.itemsList.setVisibleRowCount(-1); + JScrollPane itemListscrollPane = new JScrollPane(this.itemsList); + itemListscrollPane.setBounds(34, 49, 155, 254); + panel_1.add(itemListscrollPane); + JButton btnEdit = new JButton("Edit"); + btnEdit.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + ItemDefinitions defs = (ItemDefinitions)Application.this.itemsList.getSelectedValue(); + if(defs != null) { + new ItemDefsEditor(Application.this, defs); + } + + } + }); + btnEdit.setBounds(201, 48, 90, 28); + panel_1.add(btnEdit); + JButton btnAdd = new JButton("Add"); + btnAdd.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + new ItemDefsEditor(Application.this, new ItemDefinitions(Application.STORE, Utils.getItemDefinitionsSize(Application.STORE), false)); + } + }); + btnAdd.setBounds(201, 88, 90, 28); + panel_1.add(btnAdd); + JButton btnRemove = new JButton("Remove"); + btnRemove.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + ItemDefinitions defs = (ItemDefinitions)Application.this.itemsList.getSelectedValue(); + if(defs != null) { + Application.STORE.getIndexes()[19].removeFile(defs.getArchiveId(), defs.getFileId()); + Application.this.removeItemDefs(defs); + } + + } + }); + btnRemove.setBounds(201, 128, 90, 28); + panel_1.add(btnRemove); + JLabel label = new JLabel("Cached Items:"); + label.setFont(new Font("Comic Sans MS", 0, 18)); + label.setBounds(34, 18, 155, 21); + panel_1.add(label); + JButton btnDuplicate = new JButton("Clone"); + btnDuplicate.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + ItemDefinitions defs = (ItemDefinitions)Application.this.itemsList.getSelectedValue(); + if(defs != null) { + defs = (ItemDefinitions)defs.clone(); + if(defs != null) { + defs.id = Utils.getItemDefinitionsSize(Application.STORE); + new ItemDefsEditor(Application.this, defs); + } + } + + } + }); + btnDuplicate.setBounds(201, 168, 90, 28); + panel_1.add(btnDuplicate); + this.addAllItems(); + } + + public void addAllItems() { + for(int id = 0; id < Utils.getItemDefinitionsSize(STORE) - 22314; ++id) { + this.addItemDefs(ItemDefinitions.getItemDefinition(STORE, id)); + } + + } + + public void addItemDefs(final ItemDefinitions defs) { + EventQueue.invokeLater(new Runnable() { + public void run() { + Application.this.itemsListmodel.addElement(defs); + } + }); + } + + public void updateItemDefs(final ItemDefinitions defs) { + EventQueue.invokeLater(new Runnable() { + public void run() { + int index = Application.this.itemsListmodel.indexOf(defs); + if(index == -1) { + Application.this.itemsListmodel.addElement(defs); + } else { + Application.this.itemsListmodel.setElementAt(defs, index); + } + + } + }); + } + + public void removeItemDefs(final ItemDefinitions defs) { + EventQueue.invokeLater(new Runnable() { + public void run() { + Application.this.itemsListmodel.removeElement(defs); + } + }); + } + + public JFrame getFrame() { + return this.frmCacheEditorV; + } +} diff --git a/Tools/Frostys Cache Editor/src/com/alex/tools/itemsDefsEditor/GeneratedUkeys.java b/Tools/Frostys Cache Editor/src/com/alex/tools/itemsDefsEditor/GeneratedUkeys.java new file mode 100644 index 0000000..923d4ef --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/tools/itemsDefsEditor/GeneratedUkeys.java @@ -0,0 +1,39 @@ +package com.alex.tools.itemsDefsEditor; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.Arrays; + +public class GeneratedUkeys extends JDialog { + private static final long serialVersionUID = -4163755150981048484L; + + public GeneratedUkeys(JFrame frame, byte[] ukeys) { + super(frame, "Ukeys", true); + this.setBounds(100, 100, 450, 300); + this.getContentPane().setLayout((LayoutManager)null); + final JEditorPane editorPane = new JEditorPane(); + editorPane.setText(Arrays.toString(ukeys)); + editorPane.setBounds(6, 6, 420, 213); + this.getContentPane().add(editorPane); + JButton btnClose = new JButton("Close"); + btnClose.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + GeneratedUkeys.this.dispose(); + } + }); + btnClose.setBounds(101, 221, 90, 28); + this.getContentPane().add(btnClose); + JButton btnCopy = new JButton("Copy"); + btnCopy.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + ActionEvent nev = new ActionEvent(editorPane, 1001, "copy"); + editorPane.selectAll(); + editorPane.getActionMap().get(nev.getActionCommand()).actionPerformed(nev); + } + }); + btnCopy.setBounds(6, 221, 90, 28); + this.getContentPane().add(btnCopy); + this.setDefaultCloseOperation(2); + this.setVisible(true); + } +} diff --git a/Tools/Frostys Cache Editor/src/com/alex/tools/itemsDefsEditor/ItemDefsEditor.java b/Tools/Frostys Cache Editor/src/com/alex/tools/itemsDefsEditor/ItemDefsEditor.java new file mode 100644 index 0000000..f408c63 --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/tools/itemsDefsEditor/ItemDefsEditor.java @@ -0,0 +1,351 @@ +package com.alex.tools.itemsDefsEditor; + +import com.alex.loaders.items.ItemDefinitions; +import com.alex.tools.itemsDefsEditor.Application; + +import javax.swing.border.EmptyBorder; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class ItemDefsEditor extends JDialog { + private static final long serialVersionUID = 779623426244652906L; + private final JPanel contentPanel = new JPanel(); + private ItemDefinitions defs; + private Application application; + private JTextField modelIDField; + private JTextField nameField; + private JTextField modelZoomField; + private JTextField groundOptionsField; + private JTextField inventoryOptionsField; + private JTextField femaleModelId2Field; + private JTextField maleModelId1Field; + private JTextField maleModelId2Field; + private JTextField maleModelId3Field; + private JTextField femaleModelId1Field; + private JTextField femaleModelId3Field; + private JTextField teamIdField; + private JTextField notedItemIdField; + private JTextField switchNotedItemField; + private JTextField lendedItemIdField; + private JTextField switchLendedItemField; + private JTextField changedModelColorsField; + private JTextField changedTextureColorsField; + private JCheckBox membersOnlyCheck; + private JTextField price; + + public void save() { + this.defs.setInvModelId(Integer.valueOf(this.modelIDField.getText()).intValue()); + this.defs.setName(this.nameField.getText()); + this.defs.setInvModelZoom(Integer.valueOf(this.modelZoomField.getText()).intValue()); + String[] groundOptions = this.groundOptionsField.getText().split(";"); + + for(int var9 = 0; var9 < this.defs.getGroundOptions().length; ++var9) { + this.defs.getGroundOptions()[var9] = groundOptions[var9].equals("null")?null:groundOptions[var9]; + } + + String[] var91 = this.inventoryOptionsField.getText().split(";"); + + for(int t = 0; t < this.defs.getInventoryOptions().length; ++t) { + this.defs.getInventoryOptions()[t] = var91[t].equals("null")?null:var91[t]; + } + + this.defs.maleEquip1 = Integer.valueOf(this.maleModelId1Field.getText()).intValue(); + this.defs.maleEquip2 = Integer.valueOf(this.maleModelId2Field.getText()).intValue(); + this.defs.maleEquipModelId3 = Integer.valueOf(this.maleModelId3Field.getText()).intValue(); + this.defs.femaleEquip1 = Integer.valueOf(this.femaleModelId1Field.getText()).intValue(); + this.defs.femaleEquip2 = Integer.valueOf(this.femaleModelId2Field.getText()).intValue(); + this.defs.femaleEquipModelId3 = Integer.valueOf(this.femaleModelId3Field.getText()).intValue(); + this.defs.teamId = Integer.valueOf(this.teamIdField.getText()).intValue(); + this.defs.notedItemId = Integer.valueOf(this.notedItemIdField.getText()).intValue(); + this.defs.switchNoteItemId = Integer.valueOf(this.switchNotedItemField.getText()).intValue(); + this.defs.lendedItemId = Integer.valueOf(this.lendedItemIdField.getText()).intValue(); + this.defs.switchLendItemId = Integer.valueOf(this.switchLendedItemField.getText()).intValue(); + this.defs.resetModelColors(); + int var5; + int var6; + String[] var7; + String[] editedColor; + String[] var10; + String var101; + if(!this.changedModelColorsField.getText().equals("")) { + var10 = this.changedModelColorsField.getText().split(";"); + var7 = var10; + var6 = var10.length; + + for(var5 = 0; var5 < var6; ++var5) { + var101 = var7[var5]; + editedColor = var101.split("="); + this.defs.changeModelColor(Integer.valueOf(editedColor[0]).intValue(), Integer.valueOf(editedColor[1]).intValue()); + } + } + + this.defs.resetTextureColors(); + if(!this.changedTextureColorsField.getText().equals("")) { + var10 = this.changedTextureColorsField.getText().split(";"); + var7 = var10; + var6 = var10.length; + + for(var5 = 0; var5 < var6; ++var5) { + var101 = var7[var5]; + editedColor = var101.split("="); + this.defs.changeTextureColor(Short.valueOf(editedColor[0]).shortValue(), Short.valueOf(editedColor[1]).shortValue()); + } + } + + this.defs.membersOnly = this.membersOnlyCheck.isSelected(); + this.defs.value = Integer.valueOf(this.price.getText()).intValue(); + this.defs.equipType = Integer.valueOf(this.modelIDField.getText()).intValue(); + this.defs.equipSlot = Integer.valueOf(this.modelIDField.getText()).intValue(); + this.defs.write(Application.STORE); + this.application.updateItemDefs(this.defs); + } + + public ItemDefsEditor(Application application, ItemDefinitions defs) { + super(application.getFrame(), "Item Definitions Editor", true); + this.defs = defs; + this.application = application; + this.setBounds(100, 100, 912, 354); + this.getContentPane().setLayout(new BorderLayout()); + this.contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5)); + this.getContentPane().add(this.contentPanel, "Center"); + this.contentPanel.setLayout((LayoutManager)null); + JLabel lblNewLabel = new JLabel("Model ID:"); + lblNewLabel.setFont(new Font("Comic Sans MS", 0, 14)); + lblNewLabel.setBounds(6, 43, 81, 21); + this.contentPanel.add(lblNewLabel); + this.modelIDField = new JTextField(); + this.modelIDField.setBounds(139, 40, 122, 28); + this.contentPanel.add(this.modelIDField); + this.modelIDField.setColumns(10); + this.modelIDField.setText("" + defs.getInvModelId()); + JLabel label = new JLabel("Name:"); + label.setFont(new Font("Comic Sans MS", 0, 14)); + label.setBounds(6, 76, 81, 21); + this.contentPanel.add(label); + this.nameField = new JTextField(); + this.nameField.setBounds(139, 73, 122, 28); + this.contentPanel.add(this.nameField); + this.nameField.setColumns(10); + this.nameField.setText(defs.getName()); + label = new JLabel("Model Zoom:"); + label.setFont(new Font("Comic Sans MS", 0, 14)); + label.setBounds(6, 109, 95, 21); + this.contentPanel.add(label); + this.modelZoomField = new JTextField(); + this.modelZoomField.setBounds(139, 106, 122, 28); + this.contentPanel.add(this.modelZoomField); + this.modelZoomField.setColumns(10); + this.modelZoomField.setText("" + defs.getInvModelZoom()); + label = new JLabel("Ground Options:"); + label.setFont(new Font("Comic Sans MS", 0, 14)); + label.setBounds(6, 142, 108, 21); + this.contentPanel.add(label); + this.groundOptionsField = new JTextField(); + this.groundOptionsField.setBounds(139, 139, 122, 28); + this.contentPanel.add(this.groundOptionsField); + this.groundOptionsField.setColumns(10); + String var14 = ""; + String[] label_1 = defs.getGroundOptions(); + int label_2 = label_1.length; + + int label_3; + String label_4; + for(label_3 = 0; label_3 < label_2; ++label_3) { + label_4 = label_1[label_3]; + var14 = var14 + (label_4 == null?"null":label_4) + ";"; + } + + this.groundOptionsField.setText(var14); + label = new JLabel("Inventory Options:"); + label.setFont(new Font("Comic Sans MS", 0, 14)); + label.setBounds(6, 175, 139, 21); + this.contentPanel.add(label); + this.inventoryOptionsField = new JTextField(); + this.inventoryOptionsField.setBounds(139, 172, 122, 28); + this.contentPanel.add(this.inventoryOptionsField); + this.inventoryOptionsField.setColumns(10); + var14 = ""; + label_1 = defs.getInventoryOptions(); + label_2 = label_1.length; + + for(label_3 = 0; label_3 < label_2; ++label_3) { + label_4 = label_1[label_3]; + var14 = var14 + (label_4 == null?"null":label_4) + ";"; + } + + this.inventoryOptionsField.setText(var14); + JButton var16 = new JButton("Save"); + var16.setBounds(6, 265, 55, 28); + this.contentPanel.add(var16); + var16.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + ItemDefsEditor.this.save(); + ItemDefsEditor.this.dispose(); + } + }); + this.getRootPane().setDefaultButton(var16); + var16 = new JButton("Cancel"); + var16.setBounds(73, 265, 67, 28); + this.contentPanel.add(var16); + var16.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + ItemDefsEditor.this.dispose(); + } + }); + var16.setActionCommand("Cancel"); + label = new JLabel("Interface / Droped"); + label.setFont(new Font("Comic Sans MS", 0, 18)); + label.setBounds(6, 6, 205, 21); + this.contentPanel.add(label); + JLabel var15 = new JLabel("Wearing"); + var15.setFont(new Font("Comic Sans MS", 0, 18)); + var15.setBounds(273, 6, 205, 21); + this.contentPanel.add(var15); + JLabel var17 = new JLabel("Male Model ID 1:"); + var17.setFont(new Font("Comic Sans MS", 0, 14)); + var17.setBounds(273, 43, 131, 21); + this.contentPanel.add(var17); + JLabel var18 = new JLabel("Male Model ID 2:"); + var18.setFont(new Font("Comic Sans MS", 0, 14)); + var18.setBounds(273, 76, 131, 21); + this.contentPanel.add(var18); + JLabel var19 = new JLabel("Male Model ID 3:"); + var19.setFont(new Font("Comic Sans MS", 0, 14)); + var19.setBounds(273, 112, 131, 21); + this.contentPanel.add(var19); + JLabel label_5 = new JLabel("Female Model ID 1:"); + label_5.setFont(new Font("Comic Sans MS", 0, 14)); + label_5.setBounds(273, 145, 131, 21); + this.contentPanel.add(label_5); + JLabel label_6 = new JLabel("Female Model ID 2:"); + label_6.setFont(new Font("Comic Sans MS", 0, 14)); + label_6.setBounds(273, 175, 131, 21); + this.contentPanel.add(label_6); + JLabel label_7 = new JLabel("Female Model ID 3:"); + label_7.setFont(new Font("Comic Sans MS", 0, 14)); + label_7.setBounds(273, 208, 131, 21); + this.contentPanel.add(label_7); + this.femaleModelId2Field = new JTextField(); + this.femaleModelId2Field.setBounds(411, 172, 122, 28); + this.contentPanel.add(this.femaleModelId2Field); + this.femaleModelId2Field.setColumns(10); + this.femaleModelId2Field.setText("" + defs.femaleEquip2); + this.maleModelId1Field = new JTextField(); + this.maleModelId1Field.setBounds(411, 40, 122, 28); + this.contentPanel.add(this.maleModelId1Field); + this.maleModelId1Field.setColumns(10); + this.maleModelId1Field.setText("" + defs.maleEquip1); + this.maleModelId2Field = new JTextField(); + this.maleModelId2Field.setBounds(411, 73, 122, 28); + this.contentPanel.add(this.maleModelId2Field); + this.maleModelId2Field.setColumns(10); + this.maleModelId2Field.setText("" + defs.maleEquip2); + this.maleModelId3Field = new JTextField(); + this.maleModelId3Field.setBounds(411, 106, 122, 28); + this.contentPanel.add(this.maleModelId3Field); + this.maleModelId3Field.setColumns(10); + this.maleModelId3Field.setText("" + defs.maleEquipModelId3); + this.femaleModelId1Field = new JTextField(); + this.femaleModelId1Field.setBounds(411, 139, 122, 28); + this.contentPanel.add(this.femaleModelId1Field); + this.femaleModelId1Field.setColumns(10); + this.femaleModelId1Field.setText("" + defs.femaleEquip1); + this.femaleModelId3Field = new JTextField(); + this.femaleModelId3Field.setBounds(411, 205, 122, 28); + this.contentPanel.add(this.femaleModelId3Field); + this.femaleModelId3Field.setColumns(10); + this.femaleModelId3Field.setText("" + defs.femaleEquipModelId3); + JLabel buttonPane = new JLabel("Team ID:"); + buttonPane.setFont(new Font("Comic Sans MS", 0, 14)); + buttonPane.setBounds(273, 241, 131, 21); + this.contentPanel.add(buttonPane); + this.teamIdField = new JTextField(); + this.teamIdField.setBounds(411, 238, 122, 28); + this.contentPanel.add(this.teamIdField); + this.teamIdField.setColumns(10); + this.teamIdField.setText("" + defs.teamId); + buttonPane = new JLabel("Others"); + buttonPane.setFont(new Font("Comic Sans MS", 0, 18)); + buttonPane.setBounds(539, 6, 205, 21); + this.contentPanel.add(buttonPane); + buttonPane = new JLabel("Noted Item ID:"); + buttonPane.setFont(new Font("Comic Sans MS", 0, 14)); + buttonPane.setBounds(545, 43, 131, 21); + this.contentPanel.add(buttonPane); + buttonPane = new JLabel("Switch Noted Item Id:"); + buttonPane.setFont(new Font("Comic Sans MS", 0, 14)); + buttonPane.setBounds(545, 76, 160, 21); + this.contentPanel.add(buttonPane); + buttonPane = new JLabel("Lended Item ID:"); + buttonPane.setFont(new Font("Comic Sans MS", 0, 14)); + buttonPane.setBounds(545, 109, 160, 21); + this.contentPanel.add(buttonPane); + buttonPane = new JLabel("Switch Lended Item Id:"); + buttonPane.setFont(new Font("Comic Sans MS", 0, 14)); + buttonPane.setBounds(545, 145, 160, 21); + this.contentPanel.add(buttonPane); + this.notedItemIdField = new JTextField(); + this.notedItemIdField.setBounds(707, 39, 122, 28); + this.contentPanel.add(this.notedItemIdField); + this.notedItemIdField.setColumns(10); + this.notedItemIdField.setText("" + defs.notedItemId); + this.switchNotedItemField = new JTextField(); + this.switchNotedItemField.setBounds(707, 73, 122, 28); + this.contentPanel.add(this.switchNotedItemField); + this.switchNotedItemField.setColumns(10); + this.switchNotedItemField.setText("" + defs.switchNoteItemId); + this.lendedItemIdField = new JTextField(); + this.lendedItemIdField.setBounds(707, 106, 122, 28); + this.contentPanel.add(this.lendedItemIdField); + this.lendedItemIdField.setColumns(10); + this.lendedItemIdField.setText("" + defs.lendedItemId); + this.switchLendedItemField = new JTextField(); + this.switchLendedItemField.setBounds(707, 139, 122, 28); + this.contentPanel.add(this.switchLendedItemField); + this.switchLendedItemField.setColumns(10); + this.switchLendedItemField.setText("" + defs.switchLendItemId); + buttonPane = new JLabel("Changed Model Colors:"); + buttonPane.setFont(new Font("Comic Sans MS", 0, 14)); + buttonPane.setBounds(545, 175, 160, 21); + this.contentPanel.add(buttonPane); + this.changedModelColorsField = new JTextField(); + this.changedModelColorsField.setBounds(707, 172, 122, 28); + this.contentPanel.add(this.changedModelColorsField); + this.changedModelColorsField.setColumns(10); + String var20 = ""; + int i; + if(defs.originalModelColors != null) { + for(i = 0; i < defs.originalModelColors.length; ++i) { + var20 = var20 + defs.originalModelColors[i] + "=" + defs.modifiedModelColors[i] + ";"; + } + } + + this.changedModelColorsField.setText(var20); + buttonPane = new JLabel("Changed Texture Colors:"); + buttonPane.setFont(new Font("Comic Sans MS", 0, 14)); + buttonPane.setBounds(545, 205, 160, 21); + this.contentPanel.add(buttonPane); + this.changedTextureColorsField = new JTextField(); + this.changedTextureColorsField.setBounds(707, 205, 122, 28); + this.contentPanel.add(this.changedTextureColorsField); + this.changedTextureColorsField.setColumns(10); + var20 = ""; + if(defs.originalTextureColors != null) { + for(i = 0; i < defs.originalTextureColors.length; ++i) { + var20 = var20 + defs.originalTextureColors[i] + "=" + defs.modifiedTextureColors[i] + ";"; + } + } + + this.changedTextureColorsField.setText(var20); + this.membersOnlyCheck = new JCheckBox("Members Only"); + this.membersOnlyCheck.setFont(new Font("Comic Sans MS", 0, 14)); + this.membersOnlyCheck.setBounds(545, 243, 131, 18); + this.membersOnlyCheck.setSelected(defs.membersOnly); + this.contentPanel.add(this.membersOnlyCheck); + JPanel var21 = new JPanel(); + var21.setLayout(new FlowLayout(2)); + this.getContentPane().add(var21, "South"); + this.setDefaultCloseOperation(2); + this.setVisible(true); + } +} diff --git a/Tools/Frostys Cache Editor/src/com/alex/util/bzip2/BZip2BlockEntry.java b/Tools/Frostys Cache Editor/src/com/alex/util/bzip2/BZip2BlockEntry.java new file mode 100644 index 0000000..20478b1 --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/util/bzip2/BZip2BlockEntry.java @@ -0,0 +1,36 @@ +package com.alex.util.bzip2; + +public class BZip2BlockEntry { + boolean[] aBooleanArray2205 = new boolean[16]; + boolean[] aBooleanArray2213 = new boolean[256]; + byte aByte2201; + byte[] aByteArray2204 = new byte[4096]; + byte[] aByteArray2211 = new byte[256]; + byte[] aByteArray2212; + byte[] aByteArray2214 = new byte[18002]; + byte[] aByteArray2219 = new byte[18002]; + byte[] aByteArray2224; + byte[][] aByteArrayArray2229 = new byte[6][258]; + int anInt2202; + int anInt2203 = 0; + int anInt2206; + int anInt2207; + int anInt2208; + int anInt2209 = 0; + int anInt2215; + int anInt2216; + int anInt2217; + int anInt2221; + int anInt2222; + int anInt2223; + int anInt2225; + int anInt2227; + int anInt2232; + int[] anIntArray2200 = new int[6]; + int[] anIntArray2220 = new int[257]; + int[] anIntArray2226 = new int[16]; + int[] anIntArray2228 = new int[256]; + int[][] anIntArrayArray2210 = new int[6][258]; + int[][] anIntArrayArray2218 = new int[6][258]; + int[][] anIntArrayArray2230 = new int[6][258]; +} diff --git a/Tools/Frostys Cache Editor/src/com/alex/util/bzip2/BZip2Compressor.java b/Tools/Frostys Cache Editor/src/com/alex/util/bzip2/BZip2Compressor.java new file mode 100644 index 0000000..95dea27 --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/util/bzip2/BZip2Compressor.java @@ -0,0 +1,22 @@ +package com.alex.util.bzip2; + +import org.apache.tools.bzip2.CBZip2OutputStream; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +public class BZip2Compressor { + public static final byte[] compress(byte[] data) { + ByteArrayOutputStream compressedBytes = new ByteArrayOutputStream(); + + try { + CBZip2OutputStream var3 = new CBZip2OutputStream(compressedBytes); + var3.write(data); + var3.close(); + return compressedBytes.toByteArray(); + } catch (IOException var31) { + var31.printStackTrace(); + return null; + } + } +} diff --git a/Tools/Frostys Cache Editor/src/com/alex/util/bzip2/BZip2Decompressor.java b/Tools/Frostys Cache Editor/src/com/alex/util/bzip2/BZip2Decompressor.java new file mode 100644 index 0000000..745ab41 --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/util/bzip2/BZip2Decompressor.java @@ -0,0 +1,584 @@ +package com.alex.util.bzip2; + +import com.alex.util.bzip2.BZip2BlockEntry; + +public class BZip2Decompressor { + private static int[] anIntArray257; + private static BZip2BlockEntry entryInstance = new BZip2BlockEntry(); + + public static final void decompress(byte[] decompressedData, byte[] packedData, int containerSize, int blockSize) { + BZip2BlockEntry var4 = entryInstance; + BZip2BlockEntry var5 = entryInstance; + synchronized(entryInstance) { + entryInstance.aByteArray2224 = packedData; + entryInstance.anInt2209 = blockSize; + entryInstance.aByteArray2212 = decompressedData; + entryInstance.anInt2203 = 0; + entryInstance.anInt2206 = decompressedData.length; + entryInstance.anInt2232 = 0; + entryInstance.anInt2207 = 0; + entryInstance.anInt2217 = 0; + entryInstance.anInt2216 = 0; + method1793(entryInstance); + entryInstance.aByteArray2224 = null; + entryInstance.aByteArray2212 = null; + } + } + + private static final void method1785(BZip2BlockEntry entry) { + entry.anInt2215 = 0; + + for(int i = 0; i < 256; ++i) { + if(entry.aBooleanArray2213[i]) { + entry.aByteArray2211[entry.anInt2215] = (byte)i; + ++entry.anInt2215; + } + } + + } + + private static final void method1786(int[] ai, int[] ai1, int[] ai2, byte[] abyte0, int i, int j, int k) { + int l = 0; + + int i3; + int k2; + for(i3 = i; i3 <= j; ++i3) { + for(k2 = 0; k2 < k; ++k2) { + if(abyte0[k2] == i3) { + ai2[l] = k2; + ++l; + } + } + } + + for(i3 = 0; i3 < 23; ++i3) { + ai1[i3] = 0; + } + + for(i3 = 0; i3 < k; ++i3) { + ++ai1[abyte0[i3] + 1]; + } + + for(i3 = 1; i3 < 23; ++i3) { + ai1[i3] += ai1[i3 - 1]; + } + + for(i3 = 0; i3 < 23; ++i3) { + ai[i3] = 0; + } + + i3 = 0; + + for(k2 = i; k2 <= j; ++k2) { + i3 += ai1[k2 + 1] - ai1[k2]; + ai[k2] = i3 - 1; + i3 <<= 1; + } + + for(k2 = i + 1; k2 <= j; ++k2) { + ai1[k2] = (ai[k2 - 1] + 1 << 1) - ai1[k2]; + } + + } + + private static final void method1787(BZip2BlockEntry entry) { + byte byte4 = entry.aByte2201; + int i = entry.anInt2222; + int j = entry.anInt2227; + int k = entry.anInt2221; + int[] ai = anIntArray257; + int l = entry.anInt2208; + byte[] abyte0 = entry.aByteArray2212; + int i1 = entry.anInt2203; + int j1 = entry.anInt2206; + int l1 = entry.anInt2225 + 1; + + label63: + while(true) { + if(i > 0) { + while(true) { + if(j1 == 0) { + break label63; + } + + if(i == 1) { + if(j1 == 0) { + i = 1; + break label63; + } + + abyte0[i1] = byte4; + ++i1; + --j1; + break; + } + + abyte0[i1] = byte4; + --i; + ++i1; + --j1; + } + } + + boolean flag = true; + + byte byte1; + while(flag) { + flag = false; + if(j == l1) { + i = 0; + break label63; + } + + byte4 = (byte)k; + l = ai[l]; + byte1 = (byte)(l & 255); + l >>= 8; + ++j; + if(byte1 != k) { + k = byte1; + if(j1 == 0) { + i = 1; + break label63; + } + + abyte0[i1] = byte4; + ++i1; + --j1; + flag = true; + } else if(j == l1) { + if(j1 == 0) { + i = 1; + break label63; + } + + abyte0[i1] = byte4; + ++i1; + --j1; + flag = true; + } + } + + i = 2; + l = ai[l]; + byte1 = (byte)(l & 255); + l >>= 8; + ++j; + if(j != l1) { + if(byte1 != k) { + k = byte1; + } else { + i = 3; + l = ai[l]; + byte byte2 = (byte)(l & 255); + l >>= 8; + ++j; + if(j != l1) { + if(byte2 != k) { + k = byte2; + } else { + l = ai[l]; + byte byte3 = (byte)(l & 255); + l >>= 8; + ++j; + i = (byte3 & 255) + 4; + l = ai[l]; + k = (byte)(l & 255); + l >>= 8; + ++j; + } + } + } + } + } + + entry.anInt2216 += j1 - j1; + entry.aByte2201 = byte4; + entry.anInt2222 = i; + entry.anInt2227 = j; + entry.anInt2221 = k; + anIntArray257 = ai; + entry.anInt2208 = l; + entry.aByteArray2212 = abyte0; + entry.anInt2203 = i1; + entry.anInt2206 = j1; + } + + private static final byte method1788(BZip2BlockEntry entry) { + return (byte)method1790(1, entry); + } + + private static final byte method1789(BZip2BlockEntry entry) { + return (byte)method1790(8, entry); + } + + private static final int method1790(int i, BZip2BlockEntry entry) { + while(entry.anInt2232 < i) { + entry.anInt2207 = entry.anInt2207 << 8 | entry.aByteArray2224[entry.anInt2209] & 255; + entry.anInt2232 += 8; + ++entry.anInt2209; + ++entry.anInt2217; + } + + int k = entry.anInt2207 >> entry.anInt2232 - i & (1 << i) - 1; + entry.anInt2232 -= i; + return k; + } + + public static void clearBlockEntryInstance() { + entryInstance = null; + } + + private static final void method1793(BZip2BlockEntry entry) { + int j8 = 0; + int[] ai = null; + int[] ai1 = null; + int[] ai2 = null; + entry.anInt2202 = 1; + if(anIntArray257 == null) { + anIntArray257 = new int[entry.anInt2202 * 100000]; + } + + boolean flag18 = true; + + while(true) { + while(flag18) { + byte byte0 = method1789(entry); + if(byte0 == 23) { + return; + } + + byte0 = method1789(entry); + byte0 = method1789(entry); + byte0 = method1789(entry); + byte0 = method1789(entry); + byte0 = method1789(entry); + byte0 = method1789(entry); + byte0 = method1789(entry); + byte0 = method1789(entry); + byte0 = method1789(entry); + byte0 = method1788(entry); + entry.anInt2223 = 0; + byte0 = method1789(entry); + entry.anInt2223 = entry.anInt2223 << 8 | byte0 & 255; + byte0 = method1789(entry); + entry.anInt2223 = entry.anInt2223 << 8 | byte0 & 255; + byte0 = method1789(entry); + entry.anInt2223 = entry.anInt2223 << 8 | byte0 & 255; + + int i4; + for(i4 = 0; i4 < 16; ++i4) { + byte var28 = method1788(entry); + if(var28 == 1) { + entry.aBooleanArray2205[i4] = true; + } else { + entry.aBooleanArray2205[i4] = false; + } + } + + for(i4 = 0; i4 < 256; ++i4) { + entry.aBooleanArray2213[i4] = false; + } + + int var341; + for(i4 = 0; i4 < 16; ++i4) { + if(entry.aBooleanArray2205[i4]) { + for(var341 = 0; var341 < 16; ++var341) { + byte var29 = method1788(entry); + if(var29 == 1) { + entry.aBooleanArray2213[i4 * 16 + var341] = true; + } + } + } + } + + method1785(entry); + i4 = entry.anInt2215 + 2; + var341 = method1790(3, entry); + int var351 = method1790(15, entry); + + int l4; + byte i5; + for(int abyte0 = 0; abyte0 < var351; ++abyte0) { + l4 = 0; + + while(true) { + i5 = method1788(entry); + if(i5 == 0) { + entry.aByteArray2214[abyte0] = (byte)l4; + break; + } + + ++l4; + } + } + + byte[] var30 = new byte[6]; + + byte j5; + for(j5 = 0; j5 < var341; var30[j5] = j5++) { + ; + } + + for(l4 = 0; l4 < var351; ++l4) { + i5 = entry.aByteArray2214[l4]; + + for(j5 = var30[i5]; i5 > 0; --i5) { + var30[i5] = var30[i5 - 1]; + } + + var30[0] = j5; + entry.aByteArray2219[l4] = j5; + } + + int var32; + int var33; + for(l4 = 0; l4 < var341; ++l4) { + var32 = method1790(5, entry); + + for(var33 = 0; var33 < i4; ++var33) { + while(true) { + byte var35 = method1788(entry); + if(var35 == 0) { + entry.aByteArrayArray2229[l4][var33] = (byte)var32; + break; + } + + var35 = method1788(entry); + if(var35 == 0) { + ++var32; + } else { + --var32; + } + } + } + } + + int var36; + for(l4 = 0; l4 < var341; ++l4) { + i5 = 32; + j5 = 0; + + for(var36 = 0; var36 < i4; ++var36) { + if(entry.aByteArrayArray2229[l4][var36] > j5) { + j5 = entry.aByteArrayArray2229[l4][var36]; + } + + if(entry.aByteArrayArray2229[l4][var36] < i5) { + i5 = entry.aByteArrayArray2229[l4][var36]; + } + } + + method1786(entry.anIntArrayArray2230[l4], entry.anIntArrayArray2218[l4], entry.anIntArrayArray2210[l4], entry.aByteArrayArray2229[l4], i5, j5, i4); + entry.anIntArray2200[l4] = i5; + } + + l4 = entry.anInt2215 + 1; + var32 = -1; + byte var34 = 0; + + for(var36 = 0; var36 <= 255; ++var36) { + entry.anIntArray2228[var36] = 0; + } + + var36 = 4095; + + int l5; + int l6; + for(l5 = 15; l5 >= 0; --l5) { + for(l6 = 15; l6 >= 0; --l6) { + entry.aByteArray2204[var36] = (byte)(l5 * 16 + l6); + --var36; + } + + entry.anIntArray2226[l5] = var36 + 1; + } + + l5 = 0; + if(var34 == 0) { + ++var32; + var34 = 50; + byte k7 = entry.aByteArray2219[var32]; + j8 = entry.anIntArray2200[k7]; + ai = entry.anIntArrayArray2230[k7]; + ai2 = entry.anIntArrayArray2210[k7]; + ai1 = entry.anIntArrayArray2218[k7]; + } + + var33 = var34 - 1; + l6 = j8; + + byte byte9; + int var37; + for(var37 = method1790(j8, entry); var37 > ai[l6]; var37 = var37 << 1 | byte9) { + ++l6; + byte9 = method1788(entry); + } + + int l2 = ai2[var37 - ai1[l6]]; + + while(true) { + while(l2 != l4) { + int var39; + byte j7; + int i8; + byte byte11; + int var38; + if(l2 != 0 && l2 != 1) { + var39 = l2 - 1; + byte var391; + if(var39 < 16) { + var38 = entry.anIntArray2226[0]; + + for(var391 = entry.aByteArray2204[var38 + var39]; var39 > 3; var39 -= 4) { + i8 = var38 + var39; + entry.aByteArray2204[i8] = entry.aByteArray2204[i8 - 1]; + entry.aByteArray2204[i8 - 1] = entry.aByteArray2204[i8 - 2]; + entry.aByteArray2204[i8 - 2] = entry.aByteArray2204[i8 - 3]; + entry.aByteArray2204[i8 - 3] = entry.aByteArray2204[i8 - 4]; + } + + while(var39 > 0) { + entry.aByteArray2204[var38 + var39] = entry.aByteArray2204[var38 + var39 - 1]; + --var39; + } + + entry.aByteArray2204[var38] = var391; + } else { + var38 = var39 / 16; + i8 = var39 % 16; + int var40 = entry.anIntArray2226[var38] + i8; + + for(var391 = entry.aByteArray2204[var40]; var40 > entry.anIntArray2226[var38]; --var40) { + entry.aByteArray2204[var40] = entry.aByteArray2204[var40 - 1]; + } + + ++entry.anIntArray2226[var38]; + + while(var38 > 0) { + --entry.anIntArray2226[var38]; + entry.aByteArray2204[entry.anIntArray2226[var38]] = entry.aByteArray2204[entry.anIntArray2226[var38 - 1] + 16 - 1]; + --var38; + } + + --entry.anIntArray2226[0]; + entry.aByteArray2204[entry.anIntArray2226[0]] = var391; + if(entry.anIntArray2226[0] == 0) { + int l9 = 4095; + + for(int j9 = 15; j9 >= 0; --j9) { + for(int k9 = 15; k9 >= 0; --k9) { + entry.aByteArray2204[l9] = entry.aByteArray2204[entry.anIntArray2226[j9] + k9]; + --l9; + } + + entry.anIntArray2226[j9] = l9 + 1; + } + } + } + + ++entry.anIntArray2228[entry.aByteArray2211[var391 & 255] & 255]; + anIntArray257[l5] = entry.aByteArray2211[var391 & 255] & 255; + ++l5; + if(var33 == 0) { + ++var32; + var33 = 50; + j7 = entry.aByteArray2219[var32]; + j8 = entry.anIntArray2200[j7]; + ai = entry.anIntArrayArray2230[j7]; + ai2 = entry.anIntArrayArray2210[j7]; + ai1 = entry.anIntArrayArray2218[j7]; + } + + --var33; + var38 = j8; + + for(i8 = method1790(j8, entry); i8 > ai[var38]; i8 = i8 << 1 | byte11) { + ++var38; + byte11 = method1788(entry); + } + + l2 = ai2[i8 - ai1[var38]]; + } else { + var39 = -1; + int byte6 = 1; + + do { + if(l2 == 0) { + var39 += byte6; + } else if(l2 == 1) { + var39 += 2 * byte6; + } + + byte6 *= 2; + if(var33 == 0) { + ++var32; + var33 = 50; + j7 = entry.aByteArray2219[var32]; + j8 = entry.anIntArray2200[j7]; + ai = entry.anIntArrayArray2230[j7]; + ai2 = entry.anIntArrayArray2210[j7]; + ai1 = entry.anIntArrayArray2218[j7]; + } + + --var33; + var38 = j8; + + for(i8 = method1790(j8, entry); i8 > ai[var38]; i8 = i8 << 1 | byte11) { + ++var38; + byte11 = method1788(entry); + } + + l2 = ai2[i8 - ai1[var38]]; + } while(l2 == 0 || l2 == 1); + + ++var39; + j7 = entry.aByteArray2211[entry.aByteArray2204[entry.anIntArray2226[0]] & 255]; + + for(entry.anIntArray2228[j7 & 255] += var39; var39 > 0; --var39) { + anIntArray257[l5] = j7 & 255; + ++l5; + } + } + } + + entry.anInt2222 = 0; + entry.aByte2201 = 0; + entry.anIntArray2220[0] = 0; + + for(l2 = 1; l2 <= 256; ++l2) { + entry.anIntArray2220[l2] = entry.anIntArray2228[l2 - 1]; + } + + for(l2 = 1; l2 <= 256; ++l2) { + entry.anIntArray2220[l2] += entry.anIntArray2220[l2 - 1]; + } + + for(l2 = 0; l2 < l5; ++l2) { + byte var381 = (byte)(anIntArray257[l2] & 255); + anIntArray257[entry.anIntArray2220[var381 & 255]] |= l2 << 8; + ++entry.anIntArray2220[var381 & 255]; + } + + entry.anInt2208 = anIntArray257[entry.anInt2223] >> 8; + entry.anInt2227 = 0; + entry.anInt2208 = anIntArray257[entry.anInt2208]; + entry.anInt2221 = (byte)(entry.anInt2208 & 255); + entry.anInt2208 >>= 8; + ++entry.anInt2227; + entry.anInt2225 = l5; + method1787(entry); + if(entry.anInt2227 == entry.anInt2225 + 1 && entry.anInt2222 == 0) { + flag18 = true; + break; + } + + flag18 = false; + break; + } + } + + return; + } + } +} diff --git a/Tools/Frostys Cache Editor/src/com/alex/util/crc32/CRC32HGenerator.java b/Tools/Frostys Cache Editor/src/com/alex/util/crc32/CRC32HGenerator.java new file mode 100644 index 0000000..323d01c --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/util/crc32/CRC32HGenerator.java @@ -0,0 +1,22 @@ +package com.alex.util.crc32; + +import java.util.zip.CRC32; + +public final class CRC32HGenerator { + public static final CRC32 CRC32Instance = new CRC32(); + + public static int getHash(byte[] data) { + return getHash(data, 0, data.length); + } + + public static int getHash(byte[] data, int offset, int length) { + CRC32 var3 = CRC32Instance; + CRC32 var4 = CRC32Instance; + synchronized(CRC32Instance) { + CRC32Instance.update(data, offset, length); + int hash = (int)CRC32Instance.getValue(); + CRC32Instance.reset(); + return hash; + } + } +} diff --git a/Tools/Frostys Cache Editor/src/com/alex/util/gzip/GZipCompressor.java b/Tools/Frostys Cache Editor/src/com/alex/util/gzip/GZipCompressor.java new file mode 100644 index 0000000..5c92949 --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/util/gzip/GZipCompressor.java @@ -0,0 +1,22 @@ +package com.alex.util.gzip; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.zip.GZIPOutputStream; + +public class GZipCompressor { + public static final byte[] compress(byte[] data) { + ByteArrayOutputStream compressedBytes = new ByteArrayOutputStream(); + + try { + GZIPOutputStream var3 = new GZIPOutputStream(compressedBytes); + var3.write(data); + var3.finish(); + var3.close(); + return compressedBytes.toByteArray(); + } catch (IOException var31) { + var31.printStackTrace(); + return null; + } + } +} diff --git a/Tools/Frostys Cache Editor/src/com/alex/util/gzip/GZipDecompressor.java b/Tools/Frostys Cache Editor/src/com/alex/util/gzip/GZipDecompressor.java new file mode 100644 index 0000000..2100504 --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/util/gzip/GZipDecompressor.java @@ -0,0 +1,30 @@ +package com.alex.util.gzip; + +import com.alex.io.Stream; + +import java.util.zip.Inflater; + +public class GZipDecompressor { + private static final Inflater inflaterInstance = new Inflater(true); + + public static final boolean decompress(Stream stream, byte[] data) { + Inflater var2 = inflaterInstance; + Inflater var3 = inflaterInstance; + synchronized(inflaterInstance) { + if(stream.getBuffer()[stream.getOffset()] == 31 && stream.getBuffer()[stream.getOffset() + 1] == -117) { + try { + inflaterInstance.setInput(stream.getBuffer(), stream.getOffset() + 10, -stream.getOffset() - 18 + stream.getBuffer().length); + inflaterInstance.inflate(data); + } catch (Exception var5) { + inflaterInstance.reset(); + return false; + } + + inflaterInstance.reset(); + return true; + } else { + return false; + } + } + } +} diff --git a/Tools/Frostys Cache Editor/src/com/alex/util/whirlpool/Whirlpool.java b/Tools/Frostys Cache Editor/src/com/alex/util/whirlpool/Whirlpool.java new file mode 100644 index 0000000..4cc3d9d --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/util/whirlpool/Whirlpool.java @@ -0,0 +1,250 @@ +package com.alex.util.whirlpool; + +import java.util.Arrays; + +public class Whirlpool { + public static final int DIGESTBITS = 512; + public static final int DIGESTBYTES = 64; + protected static final int R = 10; + private static final String sbox = "ᠣ웨螸Å�㚦틵祯酒悼鮎ꌌ笵ᷠퟂ\u2e4b﹗ᕷ㟥\u9ff0䫚壉⤊놠殅ëµ�ჴ쬾է\ue427䆋ê�½é—˜ï¯®ç±¦\udd17äžžì¨\u00ad뼇굚茳挂ꩱ젙䧙\uf2e3守騦㊰\ue90fí–€ë»�㑈コé�Ÿ\u2068\u1aae둔錢擱猒䀈ì�¬\udba1贽需켫皂혛떯æ©�䗳ワ㽕ꋪ斺⿀\ude1c\ufd4d鉵ڊ닦ฟ拔ꢖ暈╙葲㥌幸㢌톥\ue261댡鰞ä�‡ï°„写æ´�\ufadf縤㮫츑轎럫ã²�铷뤓ⳓ\ue76eì�ƒå™„義⪻셓\udc0b鵬ㅴ\uf646겉ᓡᘺ椉炶íƒ\u00ad챂颤⡜\uf886"; + private static long[][] C = new long[8][256]; + private static long[] rc = new long[11]; + protected byte[] bitLength = new byte[32]; + protected byte[] buffer = new byte[64]; + protected int bufferBits = 0; + protected int bufferPos = 0; + protected long[] hash = new long[8]; + protected long[] K = new long[8]; + protected long[] L = new long[8]; + protected long[] block = new long[8]; + protected long[] state = new long[8]; + + static { + int r; + for(r = 0; r < 256; ++r) { + char var15 = "ᠣ웨螸Å�㚦틵祯酒悼鮎ꌌ笵ᷠퟂ\u2e4b﹗ᕷ㟥\u9ff0䫚壉⤊놠殅ëµ�ჴ쬾է\ue427䆋ê�½é—˜ï¯®ç±¦\udd17äžžì¨\u00ad뼇굚茳挂ꩱ젙䧙\uf2e3守騦㊰\ue90fí–€ë»�㑈コé�Ÿ\u2068\u1aae둔錢擱猒䀈ì�¬\udba1贽需켫皂혛떯æ©�䗳ワ㽕ꋪ斺⿀\ude1c\ufd4d鉵ڊ닦ฟ拔ꢖ暈╙葲㥌幸㢌톥\ue261댡鰞ä�‡ï°„写æ´�\ufadf縤㮫츑轎럫ã²�铷뤓ⳓ\ue76eì�ƒå™„義⪻셓\udc0b鵬ㅴ\uf646겉ᓡᘺ椉炶íƒ\u00ad챂颤⡜\uf886".charAt(r / 2); + long v1 = (r & 1) == 0?(long)(var15 >>> 8):(long)(var15 & 255); + long v2 = v1 << 1; + if(v2 >= 256L) { + v2 ^= 285L; + } + + long v4 = v2 << 1; + if(v4 >= 256L) { + v4 ^= 285L; + } + + long v5 = v4 ^ v1; + long v8 = v4 << 1; + if(v8 >= 256L) { + v8 ^= 285L; + } + + long v9 = v8 ^ v1; + C[0][r] = v1 << 56 | v1 << 48 | v4 << 40 | v1 << 32 | v8 << 24 | v5 << 16 | v2 << 8 | v9; + + for(int t = 1; t < 8; ++t) { + C[t][r] = C[t - 1][r] >>> 8 | C[t - 1][r] << 56; + } + } + + rc[0] = 0L; + + for(r = 1; r <= 10; ++r) { + int var151 = 8 * (r - 1); + rc[r] = C[0][var151] & -72057594037927936L ^ C[1][var151 + 1] & 71776119061217280L ^ C[2][var151 + 2] & 280375465082880L ^ C[3][var151 + 3] & 1095216660480L ^ C[4][var151 + 4] & 4278190080L ^ C[5][var151 + 5] & 16711680L ^ C[6][var151 + 6] & 65280L ^ C[7][var151 + 7] & 255L; + } + + } + + public static byte[] getHash(byte[] data, int off, int len) { + byte[] source; + if(off <= 0) { + source = data; + } else { + source = new byte[len]; + + for(int var6 = 0; var6 < len; ++var6) { + source[var6] = data[off + var6]; + } + } + + Whirlpool var61 = new Whirlpool(); + var61.NESSIEinit(); + var61.NESSIEadd(source, (long)(len * 8)); + byte[] digest = new byte[64]; + var61.NESSIEfinalize(digest); + return digest; + } + + protected void processBuffer() { + int i = 0; + + int i1; + for(i1 = 0; i < 8; i1 += 8) { + this.block[i] = (long)this.buffer[i1] << 56 ^ ((long)this.buffer[i1 + 1] & 255L) << 48 ^ ((long)this.buffer[i1 + 2] & 255L) << 40 ^ ((long)this.buffer[i1 + 3] & 255L) << 32 ^ ((long)this.buffer[i1 + 4] & 255L) << 24 ^ ((long)this.buffer[i1 + 5] & 255L) << 16 ^ ((long)this.buffer[i1 + 6] & 255L) << 8 ^ (long)this.buffer[i1 + 7] & 255L; + ++i; + } + + for(i = 0; i < 8; ++i) { + this.state[i] = this.block[i] ^ (this.K[i] = this.hash[i]); + } + + for(i = 1; i <= 10; ++i) { + int t; + int s; + for(i1 = 0; i1 < 8; ++i1) { + this.L[i1] = 0L; + t = 0; + + for(s = 56; t < 8; s -= 8) { + this.L[i1] ^= C[t][(int)(this.K[i1 - t & 7] >>> s) & 255]; + ++t; + } + } + + for(i1 = 0; i1 < 8; ++i1) { + this.K[i1] = this.L[i1]; + } + + this.K[0] ^= rc[i]; + + for(i1 = 0; i1 < 8; ++i1) { + this.L[i1] = this.K[i1]; + t = 0; + + for(s = 56; t < 8; s -= 8) { + this.L[i1] ^= C[t][(int)(this.state[i1 - t & 7] >>> s) & 255]; + ++t; + } + } + + for(i1 = 0; i1 < 8; ++i1) { + this.state[i1] = this.L[i1]; + } + } + + for(i = 0; i < 8; ++i) { + this.hash[i] ^= this.state[i] ^ this.block[i]; + } + + } + + public void NESSIEinit() { + Arrays.fill(this.bitLength, (byte)0); + this.bufferBits = this.bufferPos = 0; + this.buffer[0] = 0; + Arrays.fill(this.hash, 0L); + } + + public void NESSIEadd(byte[] source, long sourceBits) { + int sourcePos = 0; + int sourceGap = 8 - ((int)sourceBits & 7) & 7; + int bufferRem = this.bufferBits & 7; + long value = sourceBits; + int i = 31; + + int b; + for(b = 0; i >= 0; --i) { + b += (this.bitLength[i] & 255) + ((int)value & 255); + this.bitLength[i] = (byte)b; + b >>>= 8; + value >>>= 8; + } + + while(sourceBits > 8L) { + b = source[sourcePos] << sourceGap & 255 | (source[sourcePos + 1] & 255) >>> 8 - sourceGap; + if(b < 0 || b >= 256) { + throw new RuntimeException("LOGIC ERROR"); + } + + byte[] var10000 = this.buffer; + int var10001 = this.bufferPos++; + var10000[var10001] = (byte)(var10000[var10001] | b >>> bufferRem); + this.bufferBits += 8 - bufferRem; + if(this.bufferBits == 512) { + this.processBuffer(); + this.bufferBits = this.bufferPos = 0; + } + + this.buffer[this.bufferPos] = (byte)(b << 8 - bufferRem & 255); + this.bufferBits += bufferRem; + sourceBits -= 8L; + ++sourcePos; + } + + if(sourceBits > 0L) { + b = source[sourcePos] << sourceGap & 255; + this.buffer[this.bufferPos] = (byte)(this.buffer[this.bufferPos] | b >>> bufferRem); + } else { + b = 0; + } + + if((long)bufferRem + sourceBits < 8L) { + this.bufferBits = (int)((long)this.bufferBits + sourceBits); + } else { + ++this.bufferPos; + this.bufferBits += 8 - bufferRem; + sourceBits -= (long)(8 - bufferRem); + if(this.bufferBits == 512) { + this.processBuffer(); + this.bufferBits = this.bufferPos = 0; + } + + this.buffer[this.bufferPos] = (byte)(b << 8 - bufferRem & 255); + this.bufferBits += (int)sourceBits; + } + + } + + public void NESSIEfinalize(byte[] digest) { + this.buffer[this.bufferPos] = (byte)(this.buffer[this.bufferPos] | 128 >>> (this.bufferBits & 7)); + ++this.bufferPos; + if(this.bufferPos > 32) { + while(true) { + if(this.bufferPos >= 64) { + this.processBuffer(); + this.bufferPos = 0; + break; + } + + this.buffer[this.bufferPos++] = 0; + } + } + + while(this.bufferPos < 32) { + this.buffer[this.bufferPos++] = 0; + } + + System.arraycopy(this.bitLength, 0, this.buffer, 32, 32); + this.processBuffer(); + int i = 0; + + for(int j = 0; i < 8; j += 8) { + long h = this.hash[i]; + digest[j] = (byte)((int)(h >>> 56)); + digest[j + 1] = (byte)((int)(h >>> 48)); + digest[j + 2] = (byte)((int)(h >>> 40)); + digest[j + 3] = (byte)((int)(h >>> 32)); + digest[j + 4] = (byte)((int)(h >>> 24)); + digest[j + 5] = (byte)((int)(h >>> 16)); + digest[j + 6] = (byte)((int)(h >>> 8)); + digest[j + 7] = (byte)((int)h); + ++i; + } + + } + + public void NESSIEadd(String source) { + if(source.length() > 0) { + byte[] data = new byte[source.length()]; + + for(int i = 0; i < source.length(); ++i) { + data[i] = (byte)source.charAt(i); + } + + this.NESSIEadd(data, (long)(8 * data.length)); + } + + } +} diff --git a/Tools/Frostys Cache Editor/src/com/alex/utils/Constants.java b/Tools/Frostys Cache Editor/src/com/alex/utils/Constants.java new file mode 100644 index 0000000..c7b0ddc --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/utils/Constants.java @@ -0,0 +1,20 @@ +package com.alex.utils; + +public final class Constants { + public static final int NO_COMPRESSION = 0; + public static final int BZIP2_COMPRESSION = 1; + public static final int GZIP_COMPRESSION = 2; + public static final int MAX_VALID_ARCHIVE_LENGTH = 1000000; + public static final int INTERFACE_DEFINITIONS_INDEX = 3; + public static final int MAPS_INDEX = 5; + public static final int MODELS_INDEX = 7; + public static final int SPRITES_INDEX = 8; + public static final int INDEXED_IMAGES_INDEX = 8; + public static final int OBJECTS_DEFINITIONS_INDEX = 18; + public static final int ITEM_DEFINITIONS_INDEX = 19; + public static final int LOADER_IMAGES_INDEX = 32; + public static final int LOADER_INDEXED_IMAGES_INDEX = 34; + public static final int CLIENT_BUILD = 562; + public static final boolean ENCRYPTED_CACHE = true; + public static final int NPC_DEFINITIONS_INDEX = 18; +} diff --git a/Tools/Frostys Cache Editor/src/com/alex/utils/Utils.java b/Tools/Frostys Cache Editor/src/com/alex/utils/Utils.java new file mode 100644 index 0000000..5a37d97 --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/alex/utils/Utils.java @@ -0,0 +1,73 @@ +package com.alex.utils; + +import com.alex.io.OutputStream; +import com.alex.store.Store; + +import java.math.BigInteger; + +public final class Utils { + public static byte[] cryptRSA(byte[] data, BigInteger exponent, BigInteger modulus) { + return (new BigInteger(data)).modPow(exponent, modulus).toByteArray(); + } + + public static byte[] getArchivePacketData(int indexId, int archiveId, byte[] archive) { + OutputStream stream = new OutputStream(archive.length + 4); + stream.writeByte(indexId); + stream.writeShort(archiveId); + stream.writeByte(0); + stream.writeInt(archive.length); + int offset = 8; + + for(int var6 = 0; var6 < archive.length; ++var6) { + if(offset == 512) { + stream.writeByte(-1); + offset = 1; + } + + stream.writeByte(archive[var6]); + ++offset; + } + + byte[] var61 = new byte[stream.getOffset()]; + stream.setOffset(0); + stream.getBytes(var61, 0, var61.length); + return var61; + } + + public static int getNameHash(String name) { + return name.toLowerCase().hashCode(); + } + + public static final int getInterfaceDefinitionsSize(Store store) { + return store.getIndexes()[3].getLastArchiveId() + 1; + } + + public static final int getInterfaceDefinitionsComponentsSize(Store store, int interfaceId) { + return store.getIndexes()[3].getLastFileId(interfaceId) + 1; + } + + public static final int getAnimationDefinitionsSize(Store store) { + int lastArchiveId = store.getIndexes()[20].getLastArchiveId(); + return lastArchiveId * 128 + store.getIndexes()[20].getValidFilesCount(lastArchiveId); + } + + public static final int getItemDefinitionsSize(Store store) { + int lastArchiveId = store.getIndexes()[19].getLastArchiveId(); + return lastArchiveId * 256 + store.getIndexes()[19].getValidFilesCount(lastArchiveId); + } + + public static int getNPCDefinitionsSize(Store store) { + int lastArchiveId = store.getIndexes()[18].getLastArchiveId(); + return lastArchiveId * 128 + store.getIndexes()[18].getValidFilesCount(lastArchiveId); + } + + public static final int getObjectDefinitionsSize(Store store) { + int lastArchiveId = store.getIndexes()[16].getLastArchiveId(); + return lastArchiveId * 256 + store.getIndexes()[16].getValidFilesCount(lastArchiveId); + } + + public static final int getGraphicDefinitionsSize(Store store) { + int lastArchiveId = store.getIndexes()[21].getLastArchiveId(); + return lastArchiveId * 256 + store.getIndexes()[21].getValidFilesCount(lastArchiveId); + } +} diff --git a/Tools/Frostys Cache Editor/src/com/editor/Console.java b/Tools/Frostys Cache Editor/src/com/editor/Console.java new file mode 100644 index 0000000..c165abf --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/editor/Console.java @@ -0,0 +1,108 @@ +package com.editor; + +import com.editor.Main; + +import javax.swing.GroupLayout.Alignment; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; + +public class Console extends JFrame { + private static final long serialVersionUID = -4693540915136770583L; + private JMenu jMenu1; + private JMenuBar jMenuBar1; + private JMenuItem jMenuItem1; + private JMenuItem jMenuItem2; + private JScrollPane jScrollPane1; + public static JTextArea output; + + public Console() { + this.setTitle("Console"); + this.setResizable(false); + this.setDefaultCloseOperation(0); + this.setLocationRelativeTo((Component)null); + this.initComponents(); + Main.log("Console", "Console Started."); + } + + private void initComponents() { + this.jScrollPane1 = new JScrollPane(); + output = new JTextArea(); + this.jMenuBar1 = new JMenuBar(); + this.jMenu1 = new JMenu(); + this.jMenuItem1 = new JMenuItem(); + this.jMenuItem2 = new JMenuItem(); + this.setDefaultCloseOperation(3); + output.setEditable(false); + output.setColumns(20); + output.setLineWrap(true); + output.setRows(5); + this.jScrollPane1.setViewportView(output); + this.jMenu1.setText("File"); + this.jMenuItem1.setText("Close Console"); + this.jMenuItem1.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + Console.this.jMenuItem1ActionPerformed(evt); + } + }); + this.jMenu1.add(this.jMenuItem1); + this.jMenuItem2.setText("Exit Program"); + this.jMenuItem2.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + Console.this.jMenuItem2ActionPerformed(evt); + } + }); + this.jMenu1.add(this.jMenuItem2); + this.jMenuBar1.add(this.jMenu1); + this.setJMenuBar(this.jMenuBar1); + GroupLayout layout = new GroupLayout(this.getContentPane()); + this.getContentPane().setLayout(layout); + layout.setHorizontalGroup(layout.createParallelGroup(Alignment.LEADING).addComponent(this.jScrollPane1, -1, 618, 32767)); + layout.setVerticalGroup(layout.createParallelGroup(Alignment.LEADING).addComponent(this.jScrollPane1, -1, 240, 32767)); + this.pack(); + } + + private void jMenuItem2ActionPerformed(ActionEvent evt) { + System.exit(0); + } + + private void jMenuItem1ActionPerformed(ActionEvent evt) { + this.dispose(); + } + + public static void main(String[] args) { + EventQueue.invokeLater(new Runnable() { + public void run() { + (new Console()).setVisible(true); + } + }); + } + + private static void updateTextArea(final String text) { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + Console.output.append(text); + } + }); + } + + public static void redirectSystemStreams() { + OutputStream out = new OutputStream() { + public void write(int b) throws IOException { + Console.updateTextArea(String.valueOf((char)b)); + } + + public void write(byte[] b, int off, int len) throws IOException { + Console.updateTextArea(new String(b, off, len)); + } + + public void write(byte[] b) throws IOException { + this.write(b, 0, b.length); + } + }; + System.setOut(new PrintStream(out, true)); + System.setErr(new PrintStream(out, true)); + } +} diff --git a/Tools/Frostys Cache Editor/src/com/editor/Main.java b/Tools/Frostys Cache Editor/src/com/editor/Main.java new file mode 100644 index 0000000..890c0bc --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/editor/Main.java @@ -0,0 +1,52 @@ +package com.editor; + +import com.editor.Console; +import com.editor.ToolSelection; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Date; + +public class Main { + public static void main(String[] args) { + Console.redirectSystemStreams(); + (new Console()).setVisible(true); + (new ToolSelection()).setVisible(true); + log("Main", "Frosty's Cache Editor"); + log("Main", "Edited to support the #562 revision by Jens."); + } + + public static void log(String className, String message) { + System.out.println("[" + className + "]: " + message); + printDebug(className, message); + } + + private static void printDebug(String className, String message) { + File f = new File(System.getProperty("user.home") + "/FCE/logs/"); + File f1 = new File(System.getProperty("user.home") + "/FCE/logs/" + 2 + 5 + 1 + 11 + ".txt"); + f.mkdirs(); + + try { + f1.createNewFile(); + } catch (IOException var10) { + log("Main", "Could not create log file."); + } + + String strFilePath = System.getProperty("user.home") + "/FCE/logs/" + 2 + 5 + 1 + 11 + ".txt"; + + try { + FileOutputStream var9 = new FileOutputStream(strFilePath, true); + String strContent = new Date() + ": [" + className + "]: " + message; + String lineSep = System.getProperty("line.separator"); + var9.write(strContent.getBytes()); + var9.write(lineSep.getBytes()); + } catch (FileNotFoundException var8) { + log("Main", "FileNotFoundException : " + var8); + } catch (IOException var91) { + log("Main", "IOException : " + var91); + } + + } +} diff --git a/Tools/Frostys Cache Editor/src/com/editor/ToolSelection.java b/Tools/Frostys Cache Editor/src/com/editor/ToolSelection.java new file mode 100644 index 0000000..cee1459 --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/editor/ToolSelection.java @@ -0,0 +1,167 @@ +package com.editor; + +import com.editor.Main; +import com.editor.item.ItemDefDump; +import com.editor.item.ItemSelection; +import com.editor.model.MultiModelPacker; +import com.editor.model.UniModelDumper; +import com.editor.npc.NPCDefDump; +import com.editor.npc.NPCSelection; +import com.editor.object.ObjectSelection; + +import javax.swing.GroupLayout.Alignment; +import javax.swing.LayoutStyle.ComponentPlacement; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; +import java.io.IOException; + +public class ToolSelection extends JFrame { + private static final long serialVersionUID = 2024943190858205332L; + private String cache; + private JLabel jLabel1; + private JMenu jMenu1; + private JMenuBar jMenuBar1; + private JMenuItem loadCacheButton; + private JMenuItem exitButton; + private JComboBox selectionBox; + private JButton submitButton; + + public ToolSelection() { + this.setTitle("Tool Selection"); + this.setResizable(false); + this.setDefaultCloseOperation(3); + this.setLocationRelativeTo((Component)null); + this.initComponents(); + Main.log("Main", "ToolSelection Started"); + } + + private void initComponents() { + this.jLabel1 = new JLabel(); + this.selectionBox = new JComboBox(); + this.submitButton = new JButton(); + this.jMenuBar1 = new JMenuBar(); + this.jMenu1 = new JMenu(); + this.loadCacheButton = new JMenuItem(); + this.exitButton = new JMenuItem(); + this.setDefaultCloseOperation(3); + this.jLabel1.setText("Select Your Editor:"); + this.selectionBox.setModel(new DefaultComboBoxModel(new String[]{"Items", "NPCs", "Objects", "ItemDefDump", "NPCDefDump", "MultiModelPacker", "MultiItemPacker", "MultiNPCPacker", "UniModelDumper"})); + this.submitButton.setText("Submit"); + this.submitButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + ToolSelection.this.submitButtonActionPerformed(evt); + } + }); + this.jMenu1.setText("File"); + this.loadCacheButton.setText("Load Cache"); + this.loadCacheButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + ToolSelection.this.jMenuItem1ActionPerformed(evt); + } + }); + this.jMenu1.add(this.loadCacheButton); + this.exitButton.setText("Exit Program"); + this.exitButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + ToolSelection.this.exitButtonActionPerformed(evt); + } + }); + this.jMenu1.add(this.exitButton); + this.jMenuBar1.add(this.jMenu1); + this.setJMenuBar(this.jMenuBar1); + GroupLayout layout = new GroupLayout(this.getContentPane()); + this.getContentPane().setLayout(layout); + layout.setHorizontalGroup(layout.createParallelGroup(Alignment.LEADING).addGroup(layout.createSequentialGroup().addGap(77, 77, 77).addGroup(layout.createParallelGroup(Alignment.LEADING).addComponent(this.submitButton).addComponent(this.selectionBox, -2, -1, -2)).addContainerGap(-1, 32767)).addGroup(Alignment.TRAILING, layout.createSequentialGroup().addContainerGap(62, 32767).addComponent(this.jLabel1).addGap(58, 58, 58))); + layout.setVerticalGroup(layout.createParallelGroup(Alignment.LEADING).addGroup(layout.createSequentialGroup().addContainerGap(50, 32767).addComponent(this.jLabel1).addPreferredGap(ComponentPlacement.UNRELATED).addComponent(this.selectionBox, -2, -1, -2).addGap(44, 44, 44).addComponent(this.submitButton).addGap(38, 38, 38))); + this.pack(); + } + + private void submitButtonActionPerformed(ActionEvent evt) { + if(this.selectionBox.getSelectedIndex() == 0) { + try { + (new ItemSelection(this.cache)).setVisible(true); + Main.log("ToolSelection", "ItemSelection Started"); + } catch (IOException var4) { + Main.log("ToolSelection", "No Cache Set!"); + } + } else if(this.selectionBox.getSelectedIndex() == 1) { + try { + (new NPCSelection(this.cache)).setVisible(true); + Main.log("ToolSelection", "NPCSelection Started"); + } catch (IOException var3) { + Main.log("ToolSelection", "No Cache Set!"); + } + } else if(this.selectionBox.getSelectedIndex() == 2) { + try { + (new ObjectSelection(this.cache)).setVisible(true); + Main.log("ToolSelection", "ObjectSelection Started"); + } catch (IOException var2) { + Main.log("ToolSelection", "No Cache Set!"); + } + } else if(this.selectionBox.getSelectedIndex() == 3) { + Main.log("ToolSelection", "Item Def Dumping Started"); + EventQueue.invokeLater(new Runnable() { + public void run() { + ItemDefDump.editorDump(ToolSelection.this.cache); + } + }); + } else if(this.selectionBox.getSelectedIndex() == 4) { + Main.log("ToolSelection", "NPC Def Dumping Started"); + EventQueue.invokeLater(new Runnable() { + public void run() { + NPCDefDump.editorDump(ToolSelection.this.cache); + } + }); + } else if(this.selectionBox.getSelectedIndex() == 5) { + Main.log("ToolSelection", "MultiModelPacker Started"); + EventQueue.invokeLater(new Runnable() { + public void run() { + new MultiModelPacker(ToolSelection.this.cache); + } + }); + } else if(this.selectionBox.getSelectedIndex() == 6) { + Main.log("ToolSelection", "MultiNPCPacker is not working at the moment."); + } else if(this.selectionBox.getSelectedIndex() == 8) { + Main.log("ToolSelection", "UniModelDumper Started"); + EventQueue.invokeLater(new Runnable() { + public void run() { + new UniModelDumper(ToolSelection.this.cache); + } + }); + } else { + Main.log("ToolSelection", "No Tool Selected!"); + } + + } + + private void jMenuItem1ActionPerformed(ActionEvent evt) { + JFileChooser fc = new JFileChooser(); + fc.setFileSelectionMode(1); + if(evt.getSource() == this.loadCacheButton) { + int returnVal = fc.showOpenDialog(this); + if(returnVal == 0) { + File file = fc.getSelectedFile(); + this.cache = file.getPath() + "/"; + } + } + + } + + private void exitButtonActionPerformed(ActionEvent evt) { + JDialog.setDefaultLookAndFeelDecorated(true); + int response = JOptionPane.showConfirmDialog((Component)null, "Do you want to continue?", "Confirm", 0, 3); + if(response == 0) { + System.exit(0); + } + + } + + public static void main(String[] args) { + EventQueue.invokeLater(new Runnable() { + public void run() { + (new ToolSelection()).setVisible(true); + } + }); + } +} diff --git a/Tools/Frostys Cache Editor/src/com/editor/Utils.java b/Tools/Frostys Cache Editor/src/com/editor/Utils.java new file mode 100644 index 0000000..e803588 --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/editor/Utils.java @@ -0,0 +1,51 @@ +package com.editor; + +import com.alex.store.Store; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; + +public class Utils { + public static byte[] getBytesFromFile(File file) throws IOException { + FileInputStream is = new FileInputStream(file); + long length = file.length(); + if(length > 2147483647L) { + ; + } + + byte[] bytes = new byte[(int)length]; + int offset = 0; + + int numRead1; + for(boolean numRead = false; offset < bytes.length && (numRead1 = is.read(bytes, offset, bytes.length - offset)) >= 0; offset += numRead1) { + ; + } + + if(offset < bytes.length) { + throw new IOException("Could not completely read file " + file.getName()); + } else { + is.close(); + return bytes; + } + } + + public static int packCustomModel(Store cache, byte[] data) { + int archiveId = cache.getIndexes()[7].getLastArchiveId() + 1; + if(cache.getIndexes()[7].putFile(archiveId, 0, data)) { + return archiveId; + } else { + System.out.println("Failed packing model " + archiveId); + return -1; + } + } + + public static int packCustomModel(Store cache, byte[] data, int modelId) { + if(cache.getIndexes()[7].putFile(modelId, 0, data)) { + return modelId; + } else { + System.out.println("Failed packing model " + modelId); + return -1; + } + } +} diff --git a/Tools/Frostys Cache Editor/src/com/editor/item/ItemDefDump.java b/Tools/Frostys Cache Editor/src/com/editor/item/ItemDefDump.java new file mode 100644 index 0000000..aace0f3 --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/editor/item/ItemDefDump.java @@ -0,0 +1,418 @@ +package com.editor.item; + +import com.alex.loaders.items.ItemDefinitions; +import com.alex.store.Store; +import com.alex.utils.Utils; +import com.editor.Main; + +import java.util.Iterator; + +public class ItemDefDump { + private static ItemDefinitions defs; + private static Store STORE; + + public static void main(String[] args) { + try { + STORE = new Store("C:/Users/yvonne å christer/Dropbox/FCE/ItemDefDump/"); + } catch (IOException var2) { + System.out.println("Cannot find cache location"); + } + + int id; + if(Utils.getItemDefinitionsSize(STORE) > 30000) { + for(id = 0; id < Utils.getItemDefinitionsSize(STORE) - 22314; ++id) { + defs = ItemDefinitions.getItemDefinition(STORE, id); + dump(); + Main.log("ItemDefDump", "Dumping Item " + defs.id); + } + } else { + for(id = 0; id < Utils.getItemDefinitionsSize(STORE); ++id) { + defs = ItemDefinitions.getItemDefinition(STORE, id); + dump(); + Main.log("ItemDefDump", "Dumping Item " + defs.id); + } + } + + } + + public static void editorDump(String cache) { + try { + STORE = new Store(cache); + } catch (IOException var2) { + Main.log("ItemDefDump", "Cannot find cache location"); + } + + int id; + if(Utils.getItemDefinitionsSize(STORE) > 30000) { + for(id = 0; id < Utils.getItemDefinitionsSize(STORE) - 22314; ++id) { + defs = ItemDefinitions.getItemDefinition(STORE, id); + dump(); + Main.log("ItemDefDump", "Dumping Item " + defs.id); + } + } else { + for(id = 0; id < Utils.getItemDefinitionsSize(STORE); ++id) { + defs = ItemDefinitions.getItemDefinition(STORE, id); + dump(); + Main.log("ItemDefDump", "Dumping Item " + defs.id); + } + } + + } + + public static void dump() { + File f = new File(System.getProperty("user.home") + "/FCE/items/"); + f.mkdirs(); + String lineSep = System.getProperty("line.separator"); + BufferedWriter writer = null; + + try { + writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(System.getProperty("user.home") + "/FCE/items/" + defs.id + ".txt"), "utf-8")); + writer.write("name = " + defs.getName()); + writer.write(lineSep); + writer.write("value = " + defs.getValue()); + writer.write(lineSep); + writer.write("team id = " + defs.getTeamId()); + writer.write(lineSep); + writer.write("members only = " + String.valueOf(defs.isMembersOnly())); + writer.write(lineSep); + writer.write("equip slot = " + defs.getEquipSlot()); + writer.write(lineSep); + writer.write("equip type = " + defs.getEquipType()); + writer.write(lineSep); + writer.write("stack ids = " + getStackIDs()); + writer.write(lineSep); + writer.write("stack amounts = " + getStackAmts()); + writer.write(lineSep); + writer.write("stackable = " + defs.getStackable()); + writer.write(lineSep); + writer.write("inv model zoom = " + defs.getInvModelZoom()); + writer.write(lineSep); + writer.write("model rotation 1 = " + defs.getModelRotation1()); + writer.write(lineSep); + writer.write("model rotation 2 = " + defs.getModelRotation2()); + writer.write(lineSep); + writer.write("model offset 1 = " + defs.getModelOffset1()); + writer.write(lineSep); + writer.write("model offset 2 = " + defs.getModelOffset2()); + writer.write(lineSep); + writer.write("inv model id = " + defs.getInvModelId()); + writer.write(lineSep); + writer.write("male equip model id 1 = " + defs.getMaleEquipModelId1()); + writer.write(lineSep); + writer.write("female equip model id 1 = " + defs.getFemaleEquipModelId1()); + writer.write(lineSep); + writer.write("male equip model id 2 = " + defs.getMaleEquipModelId2()); + writer.write(lineSep); + writer.write("female equip model id 2 = " + defs.getFemaleEquipModelId2()); + writer.write(lineSep); + writer.write("male equip model id 3 = " + defs.getMaleEquipModelId3()); + writer.write(lineSep); + writer.write("female equip model id 3 = " + defs.getFemaleEquipModelId3()); + writer.write(lineSep); + writer.write("inventory options = " + getInventoryOpts()); + writer.write(lineSep); + writer.write("ground options = " + getGroundOpts()); + writer.write(lineSep); + writer.write("changed model colors = " + getChangedModelColors()); + writer.write(lineSep); + writer.write("changed texture colors = " + getChangedTextureColors()); + writer.write(lineSep); + writer.write("switch note item id = " + defs.switchNoteItemId); + writer.write(lineSep); + writer.write("noted item id = " + defs.notedItemId); + writer.write(lineSep); + writer.write("unnoted = " + String.valueOf(defs.isUnnoted())); + writer.write(lineSep); + writer.write("switch lend item id = " + defs.getSwitchLendItemId()); + writer.write(lineSep); + writer.write("lended item id = " + defs.getLendedItemId()); + writer.write(lineSep); + writer.write("unknownArray1 = " + getUnknownArray1()); + writer.write(lineSep); + writer.write("unknownArray2 = " + getUnknownArray2()); + writer.write(lineSep); + writer.write("unknownArray3 = " + getUnknownArray3()); + writer.write(lineSep); + writer.write("unknownArray4 = " + getUnknownArray4()); + writer.write(lineSep); + writer.write("unknownArray5 = " + getUnknownArray5()); + writer.write(lineSep); + writer.write("unknownArray6 = " + getUnknownArray6()); + writer.write(lineSep); + writer.write("unknownInt1 = " + defs.unknownInt1); + writer.write(lineSep); + writer.write("unknownInt2 = " + defs.unknownInt2); + writer.write(lineSep); + writer.write("unknownInt3 = " + defs.unknownInt3); + writer.write(lineSep); + writer.write("unknownInt4 = " + defs.unknownInt4); + writer.write(lineSep); + writer.write("unknownInt5 = " + defs.unknownInt5); + writer.write(lineSep); + writer.write("unknownInt6 = " + defs.unknownInt6); + writer.write(lineSep); + writer.write("unknownInt7 = " + defs.unknownInt7); + writer.write(lineSep); + writer.write("unknownInt8 = " + defs.unknownInt8); + writer.write(lineSep); + writer.write("unknownInt9 = " + defs.unknownInt9); + writer.write(lineSep); + writer.write("unknownInt10 = " + defs.unknownInt10); + writer.write(lineSep); + writer.write("unknownInt11 = " + defs.unknownInt11); + writer.write(lineSep); + writer.write("unknownInt12 = " + defs.unknownInt12); + writer.write(lineSep); + writer.write("unknownInt13 = " + defs.unknownInt13); + writer.write(lineSep); + writer.write("unknownInt14 = " + defs.unknownInt14); + writer.write(lineSep); + writer.write("unknownInt15 = " + defs.unknownInt15); + writer.write(lineSep); + writer.write("unknownInt16 = " + defs.unknownInt16); + writer.write(lineSep); + writer.write("unknownInt17 = " + defs.unknownInt17); + writer.write(lineSep); + writer.write("unknownInt18 = " + defs.unknownInt18); + writer.write(lineSep); + writer.write("unknownInt19 = " + defs.unknownInt19); + writer.write(lineSep); + writer.write("unknownInt20 = " + defs.unknownInt20); + writer.write(lineSep); + writer.write("unknownInt21 = " + defs.unknownInt21); + writer.write(lineSep); + writer.write("unknownInt22 = " + defs.unknownInt22); + writer.write(lineSep); + writer.write("unknownInt23 = " + defs.unknownInt23); + writer.write(lineSep); + writer.write("Clientscripts"); + writer.write(lineSep); + if(defs.clientScriptData != null) { + Iterator var14 = defs.clientScriptData.keySet().iterator(); + + while(var14.hasNext()) { + int key = ((Integer)var14.next()).intValue(); + Object value = defs.clientScriptData.get(Integer.valueOf(key)); + writer.write("KEY: " + key + ", VALUE: " + value); + writer.write(lineSep); + } + } + } catch (IOException var141) { + Main.log("ItemEditor", "Failed to export Item Defs to .txt"); + } finally { + try { + writer.close(); + } catch (Exception var13) { + ; + } + + } + + } + + public static String getInventoryOpts() { + String text = ""; + String[] arr$ = defs.getInventoryOptions(); + int len$ = arr$.length; + + for(int i$ = 0; i$ < len$; ++i$) { + String option = arr$[i$]; + text = text + (option == null?"null":option) + ";"; + } + + return text; + } + + public static String getGroundOpts() { + String text = ""; + String[] arr$ = defs.getGroundOptions(); + int len$ = arr$.length; + + for(int i$ = 0; i$ < len$; ++i$) { + String option = arr$[i$]; + text = text + (option == null?"null":option) + ";"; + } + + return text; + } + + public static String getChangedModelColors() { + String text = ""; + if(defs.originalModelColors != null) { + for(int i = 0; i < defs.originalModelColors.length; ++i) { + text = text + defs.originalModelColors[i] + "=" + defs.modifiedModelColors[i] + ";"; + } + } + + return text; + } + + public static String getChangedTextureColors() { + String text = ""; + if(defs.originalTextureColors != null) { + for(int i = 0; i < defs.originalTextureColors.length; ++i) { + text = text + defs.originalTextureColors[i] + "=" + defs.modifiedTextureColors[i] + ";"; + } + } + + return text; + } + + public static String getStackIDs() { + String text = ""; + + try { + int[] e = defs.getStackIds(); + int len$ = e.length; + + for(int i$ = 0; i$ < len$; ++i$) { + int index = e[i$]; + text = text + index + ";"; + } + } catch (Exception var5) { + ; + } + + return text; + } + + public static String getClientScripts() { + String text = ""; + String lineSep = System.getProperty("line.separator"); + if(defs.clientScriptData != null) { + for(Iterator i$ = defs.clientScriptData.keySet().iterator(); i$.hasNext(); text = text + lineSep) { + int key = ((Integer)i$.next()).intValue(); + Object value = defs.clientScriptData.get(Integer.valueOf(key)); + text = text + "KEY: " + key + ", VALUE: " + value; + } + } + + return text; + } + + public static String getStackAmts() { + String text = ""; + + try { + int[] e = defs.getStackAmounts(); + int len$ = e.length; + + for(int i$ = 0; i$ < len$; ++i$) { + int index = e[i$]; + text = text + index + ";"; + } + } catch (Exception var5) { + ; + } + + return text; + } + + public static String getUnknownArray1() { + String text = ""; + + try { + byte[] e = defs.unknownArray1; + int len$ = e.length; + + for(int i$ = 0; i$ < len$; ++i$) { + byte index = e[i$]; + text = text + index + ";"; + } + } catch (Exception var5) { + ; + } + + return text; + } + + public static String getUnknownArray2() { + String text = ""; + + try { + int[] e = defs.unknownArray2; + int len$ = e.length; + + for(int i$ = 0; i$ < len$; ++i$) { + int index = e[i$]; + text = text + index + ";"; + } + } catch (Exception var5) { + ; + } + + return text; + } + + public static String getUnknownArray3() { + String text = ""; + + try { + byte[] e = defs.unknownArray3; + int len$ = e.length; + + for(int i$ = 0; i$ < len$; ++i$) { + byte index = e[i$]; + text = text + index + ";"; + } + } catch (Exception var5) { + ; + } + + return text; + } + + public static String getUnknownArray4() { + String text = ""; + + try { + int[] e = defs.unknownArray4; + int len$ = e.length; + + for(int i$ = 0; i$ < len$; ++i$) { + int index = e[i$]; + text = text + index + ";"; + } + } catch (Exception var5) { + ; + } + + return text; + } + + public static String getUnknownArray5() { + String text = ""; + + try { + int[] e = defs.unknownArray5; + int len$ = e.length; + + for(int i$ = 0; i$ < len$; ++i$) { + int index = e[i$]; + text = text + index + ";"; + } + } catch (Exception var5) { + ; + } + + return text; + } + + public static String getUnknownArray6() { + String text = ""; + + try { + byte[] e = defs.unknownArray6; + int len$ = e.length; + + for(int i$ = 0; i$ < len$; ++i$) { + byte index = e[i$]; + text = text + index + ";"; + } + } catch (Exception var5) { + ; + } + + return text; + } +} diff --git a/Tools/Frostys Cache Editor/src/com/editor/item/ItemEditor.java b/Tools/Frostys Cache Editor/src/com/editor/item/ItemEditor.java new file mode 100644 index 0000000..e0014d4 --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/editor/item/ItemEditor.java @@ -0,0 +1,1259 @@ +package com.editor.item; + +import com.alex.loaders.items.ItemDefinitions; +import com.editor.Main; +import com.editor.Utils; +import com.editor.item.ItemSelection; + +import javax.swing.GroupLayout.Alignment; +import javax.swing.LayoutStyle.ComponentPlacement; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.HashMap; +import java.util.Iterator; + +public class ItemEditor extends JFrame { + private static final long serialVersionUID = -3870086097297420720L; + private ItemDefinitions defs; + private ItemSelection is; + private JTextField ModelOffset1; + private JTextField ModelRot2; + private JMenuItem addModelMenuBtn; + private JTextField array1; + private JTextField array2; + private JTextField array3; + private JTextField array4; + private JTextField array5; + private JTextField array6; + private JTextArea clientScriptOutput; + private JTextField csk1; + private JTextField csk2; + private JTextField csk3; + private JTextField csk4; + private JTextField csk5; + private JTextField csk6; + private JTextField csk7; + private JTextField csv1; + private JTextField csv2; + private JTextField csv3; + private JTextField csv4; + private JTextField csv5; + private JTextField csv6; + private JTextField csv7; + private JLabel currentViewLabel; + private JTextField equipSlot; + private JTextField equipType; + private JMenuItem exitMenuBtn; + private JMenuItem exportMenuBtn; + private JTextField femaleEquip1; + private JTextField femaleEquip2; + private JTextField femaleEquip3; + private JTextField groundOptions; + private JTextField int1; + private JTextField int10; + private JTextField int11; + private JTextField int12; + private JTextField int13; + private JTextField int14; + private JTextField int15; + private JTextField int16; + private JTextField int17; + private JTextField int18; + private JTextField int19; + private JTextField int2; + private JTextField int20; + private JTextField int21; + private JTextField int22; + private JTextField int23; + private JTextField int3; + private JTextField int4; + private JTextField int5; + private JTextField int6; + private JTextField int7; + private JTextField int8; + private JTextField int9; + private JTextField invModel; + private JTextField invModelZoom; + private JTextField invOptions; + private JTextField itemName; + private JLabel jLabel1; + private JLabel jLabel10; + private JLabel jLabel11; + private JLabel jLabel12; + private JLabel jLabel13; + private JLabel jLabel14; + private JLabel jLabel15; + private JLabel jLabel16; + private JLabel jLabel17; + private JLabel jLabel18; + private JLabel jLabel19; + private JLabel jLabel2; + private JLabel jLabel20; + private JLabel jLabel21; + private JLabel jLabel22; + private JLabel jLabel23; + private JLabel jLabel24; + private JLabel jLabel25; + private JLabel jLabel26; + private JLabel jLabel27; + private JLabel jLabel28; + private JLabel jLabel29; + private JLabel jLabel3; + private JLabel jLabel30; + private JLabel jLabel31; + private JLabel jLabel32; + private JLabel jLabel33; + private JLabel jLabel34; + private JLabel jLabel35; + private JLabel jLabel36; + private JLabel jLabel37; + private JLabel jLabel38; + private JLabel jLabel39; + private JLabel jLabel4; + private JLabel jLabel40; + private JLabel jLabel41; + private JLabel jLabel42; + private JLabel jLabel43; + private JLabel jLabel44; + private JLabel jLabel45; + private JLabel jLabel46; + private JLabel jLabel47; + private JLabel jLabel48; + private JLabel jLabel49; + private JLabel jLabel5; + private JLabel jLabel50; + private JLabel jLabel51; + private JLabel jLabel52; + private JLabel jLabel53; + private JLabel jLabel54; + private JLabel jLabel55; + private JLabel jLabel56; + private JLabel jLabel57; + private JLabel jLabel58; + private JLabel jLabel59; + private JLabel jLabel6; + private JLabel jLabel60; + private JLabel jLabel61; + private JLabel jLabel7; + private JLabel jLabel8; + private JLabel jLabel9; + private JMenu jMenu1; + private JMenuBar jMenuBar1; + private JPanel jPanel1; + private JPanel jPanel2; + private JPanel jPanel3; + private JPanel jPanel5; + private JPanel jPanel6; + private JPanel jPanel7; + private JScrollPane jScrollPane1; + private JTabbedPane jTabbedPane1; + private JTextField lend; + private JTextField maleEquip1; + private JTextField maleEquip2; + private JTextField maleEquip3; + private JCheckBox membersOnly; + private JTextField modelColors; + private JTextField modelOffset2; + private JTextField modelRot1; + private JTextField note; + private JMenuItem reloadMenuBtn; + private JMenuItem saveMenuBtn; + private JTextField stackAmts; + private JTextField stackIDs; + private JTextField stackable; + public JTextField switchLend; + public JTextField switchNote; + public JTextField teamId; + public JTextField textureColors; + public JCheckBox unnoted; + public JTextField value; + + public ItemEditor(ItemSelection is, ItemDefinitions defs) { + this.defs = defs; + this.is = is; + this.initComponents(); + this.setResizable(false); + this.setTitle("Item Editor"); + this.setDefaultCloseOperation(1); + this.setLocationRelativeTo((Component)null); + this.setVisible(true); + } + + private void initComponents() { + this.jTabbedPane1 = new JTabbedPane(); + this.jPanel1 = new JPanel(); + this.jLabel1 = new JLabel(); + this.itemName = new JTextField(); + this.jLabel2 = new JLabel(); + this.value = new JTextField(); + this.teamId = new JTextField(); + this.jLabel3 = new JLabel(); + this.membersOnly = new JCheckBox(); + this.jLabel20 = new JLabel(); + this.equipSlot = new JTextField(); + this.jLabel21 = new JLabel(); + this.equipType = new JTextField(); + this.jLabel22 = new JLabel(); + this.stackIDs = new JTextField(); + this.jLabel23 = new JLabel(); + this.stackAmts = new JTextField(); + this.jLabel24 = new JLabel(); + this.stackable = new JTextField(); + this.jLabel58 = new JLabel(); + this.switchNote = new JTextField(); + this.jLabel59 = new JLabel(); + this.note = new JTextField(); + this.unnoted = new JCheckBox(); + this.jLabel60 = new JLabel(); + this.jLabel61 = new JLabel(); + this.switchLend = new JTextField(); + this.lend = new JTextField(); + this.jPanel2 = new JPanel(); + this.jLabel4 = new JLabel(); + this.invModelZoom = new JTextField(); + this.jLabel5 = new JLabel(); + this.modelRot1 = new JTextField(); + this.jLabel6 = new JLabel(); + this.ModelRot2 = new JTextField(); + this.jLabel7 = new JLabel(); + this.ModelOffset1 = new JTextField(); + this.jLabel8 = new JLabel(); + this.modelOffset2 = new JTextField(); + this.jLabel9 = new JLabel(); + this.invModel = new JTextField(); + this.jLabel10 = new JLabel(); + this.maleEquip1 = new JTextField(); + this.jLabel11 = new JLabel(); + this.femaleEquip1 = new JTextField(); + this.jLabel12 = new JLabel(); + this.maleEquip2 = new JTextField(); + this.jLabel13 = new JLabel(); + this.femaleEquip2 = new JTextField(); + this.jLabel14 = new JLabel(); + this.maleEquip3 = new JTextField(); + this.jLabel15 = new JLabel(); + this.femaleEquip3 = new JTextField(); + this.jPanel3 = new JPanel(); + this.jLabel16 = new JLabel(); + this.invOptions = new JTextField(); + this.jLabel17 = new JLabel(); + this.groundOptions = new JTextField(); + this.jLabel18 = new JLabel(); + this.modelColors = new JTextField(); + this.jLabel19 = new JLabel(); + this.textureColors = new JTextField(); + this.jPanel5 = new JPanel(); + this.jLabel25 = new JLabel(); + this.array1 = new JTextField(); + this.jLabel27 = new JLabel(); + this.jLabel28 = new JLabel(); + this.jLabel29 = new JLabel(); + this.jLabel30 = new JLabel(); + this.jLabel31 = new JLabel(); + this.array2 = new JTextField(); + this.array3 = new JTextField(); + this.array4 = new JTextField(); + this.array5 = new JTextField(); + this.array6 = new JTextField(); + this.jLabel32 = new JLabel(); + this.int1 = new JTextField(); + this.int2 = new JTextField(); + this.jLabel33 = new JLabel(); + this.jLabel34 = new JLabel(); + this.int3 = new JTextField(); + this.jLabel35 = new JLabel(); + this.int4 = new JTextField(); + this.jLabel36 = new JLabel(); + this.int5 = new JTextField(); + this.jLabel37 = new JLabel(); + this.int6 = new JTextField(); + this.jLabel38 = new JLabel(); + this.int7 = new JTextField(); + this.jLabel39 = new JLabel(); + this.int8 = new JTextField(); + this.jLabel40 = new JLabel(); + this.int9 = new JTextField(); + this.jLabel41 = new JLabel(); + this.int10 = new JTextField(); + this.jLabel42 = new JLabel(); + this.int11 = new JTextField(); + this.jLabel43 = new JLabel(); + this.int12 = new JTextField(); + this.jLabel44 = new JLabel(); + this.int13 = new JTextField(); + this.jLabel45 = new JLabel(); + this.int14 = new JTextField(); + this.jPanel6 = new JPanel(); + this.jLabel46 = new JLabel(); + this.int15 = new JTextField(); + this.jLabel47 = new JLabel(); + this.int16 = new JTextField(); + this.jLabel48 = new JLabel(); + this.int17 = new JTextField(); + this.jLabel49 = new JLabel(); + this.int18 = new JTextField(); + this.jLabel50 = new JLabel(); + this.int19 = new JTextField(); + this.jLabel51 = new JLabel(); + this.int20 = new JTextField(); + this.jLabel52 = new JLabel(); + this.int21 = new JTextField(); + this.jLabel53 = new JLabel(); + this.int22 = new JTextField(); + this.jLabel54 = new JLabel(); + this.int23 = new JTextField(); + this.jPanel7 = new JPanel(); + this.jScrollPane1 = new JScrollPane(); + this.clientScriptOutput = new JTextArea(); + this.jLabel26 = new JLabel(); + this.jLabel55 = new JLabel(); + this.jLabel56 = new JLabel(); + this.jLabel57 = new JLabel(); + this.csk1 = new JTextField(); + this.csk2 = new JTextField(); + this.csk3 = new JTextField(); + this.csk4 = new JTextField(); + this.csk5 = new JTextField(); + this.csk6 = new JTextField(); + this.csk7 = new JTextField(); + this.csv1 = new JTextField(); + this.csv2 = new JTextField(); + this.csv3 = new JTextField(); + this.csv4 = new JTextField(); + this.csv5 = new JTextField(); + this.csv6 = new JTextField(); + this.csv7 = new JTextField(); + this.currentViewLabel = new JLabel(); + this.jMenuBar1 = new JMenuBar(); + this.jMenu1 = new JMenu(); + this.reloadMenuBtn = new JMenuItem(); + this.saveMenuBtn = new JMenuItem(); + this.addModelMenuBtn = new JMenuItem(); + this.exportMenuBtn = new JMenuItem(); + this.exitMenuBtn = new JMenuItem(); + this.setDefaultCloseOperation(3); + this.jLabel1.setText("Name"); + this.itemName.setText(this.defs.getName()); + this.jLabel2.setText("Value"); + this.value.setText("" + this.defs.getValue()); + this.teamId.setText("" + this.defs.getTeamId()); + this.jLabel3.setText("Team"); + this.membersOnly.setSelected(this.defs.isMembersOnly()); + this.membersOnly.setText("Members Only"); + this.jLabel20.setText("Equip Slot"); + this.equipSlot.setText("" + this.defs.getEquipSlot()); + this.jLabel21.setText("Equip Type"); + this.equipType.setText("" + this.defs.getEquipType()); + this.jLabel22.setText("Stack IDs"); + this.stackIDs.setText(this.getStackIDs()); + this.jLabel23.setText("Stack Amounts"); + this.stackAmts.setText(this.getStackAmts()); + this.jLabel24.setText("Stackable"); + this.stackable.setText("" + this.defs.getStackable()); + this.jLabel58.setText("Switch Note Item ID"); + this.switchNote.setText("" + this.defs.switchNoteItemId); + this.jLabel59.setText("Noted Item ID"); + this.note.setText("" + this.defs.notedItemId); + this.unnoted.setSelected(this.defs.isUnnoted()); + this.unnoted.setText("Unnoted"); + this.jLabel60.setText("Switch Lend Item ID"); + this.jLabel61.setText("Lent Item ID"); + this.switchLend.setText("" + this.defs.getSwitchLendItemId()); + this.lend.setText("" + this.defs.getLendedItemId()); + GroupLayout jPanel1Layout = new GroupLayout(this.jPanel1); + this.jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup(jPanel1Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel1Layout.createSequentialGroup().addContainerGap().addGroup(jPanel1Layout.createParallelGroup(Alignment.LEADING).addComponent(this.unnoted).addComponent(this.membersOnly).addGroup(jPanel1Layout.createSequentialGroup().addComponent(this.jLabel20).addPreferredGap(ComponentPlacement.UNRELATED).addComponent(this.equipSlot, -2, 100, -2)).addGroup(jPanel1Layout.createSequentialGroup().addGroup(jPanel1Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel1Layout.createSequentialGroup().addComponent(this.jLabel1).addGap(18, 18, 18).addComponent(this.itemName, -2, 100, -2)).addGroup(jPanel1Layout.createSequentialGroup().addGroup(jPanel1Layout.createParallelGroup(Alignment.LEADING).addComponent(this.jLabel2).addComponent(this.jLabel3)).addGap(18, 18, 18).addGroup(jPanel1Layout.createParallelGroup(Alignment.LEADING).addComponent(this.teamId, -2, 100, -2).addComponent(this.value, -2, 100, -2))).addGroup(jPanel1Layout.createSequentialGroup().addComponent(this.jLabel24).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.stackable, -2, 100, -2))).addGap(126, 126, 126).addGroup(jPanel1Layout.createParallelGroup(Alignment.LEADING).addComponent(this.stackAmts, -2, 300, -2).addComponent(this.stackIDs, -2, 300, -2).addComponent(this.jLabel22).addComponent(this.jLabel23))).addGroup(jPanel1Layout.createSequentialGroup().addComponent(this.jLabel21).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.equipType, -2, 100, -2)).addGroup(jPanel1Layout.createSequentialGroup().addGroup(jPanel1Layout.createParallelGroup(Alignment.LEADING).addComponent(this.jLabel58).addComponent(this.jLabel59)).addPreferredGap(ComponentPlacement.UNRELATED).addGroup(jPanel1Layout.createParallelGroup(Alignment.LEADING, false).addComponent(this.switchNote, -1, 100, 32767).addComponent(this.note)).addGap(18, 18, 18).addGroup(jPanel1Layout.createParallelGroup(Alignment.LEADING).addComponent(this.jLabel60).addComponent(this.jLabel61)).addPreferredGap(ComponentPlacement.UNRELATED).addGroup(jPanel1Layout.createParallelGroup(Alignment.LEADING, false).addComponent(this.switchLend, -1, 100, 32767).addComponent(this.lend)))).addContainerGap(36, 32767))); + jPanel1Layout.setVerticalGroup(jPanel1Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel1Layout.createSequentialGroup().addContainerGap().addGroup(jPanel1Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel1).addComponent(this.itemName, -2, -1, -2).addComponent(this.jLabel22)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel1Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel1Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.value, -2, -1, -2).addComponent(this.jLabel2)).addComponent(this.stackIDs, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel1Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.teamId, -2, -1, -2).addComponent(this.jLabel3).addComponent(this.jLabel23)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel1Layout.createParallelGroup(Alignment.LEADING).addComponent(this.stackAmts, -2, -1, -2).addGroup(jPanel1Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel24).addComponent(this.stackable, -2, -1, -2))).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.membersOnly).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel1Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel20).addComponent(this.equipSlot, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel1Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel21).addComponent(this.equipType, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel1Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel58).addComponent(this.switchNote, -2, -1, -2).addComponent(this.jLabel60).addComponent(this.switchLend, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel1Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel59).addComponent(this.note, -2, -1, -2).addComponent(this.jLabel61).addComponent(this.lend, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.unnoted).addContainerGap(13, 32767))); + this.jTabbedPane1.addTab("General", this.jPanel1); + this.jLabel4.setText("Inventory Model Zoom"); + this.invModelZoom.setText("" + this.defs.getInvModelZoom()); + this.jLabel5.setText("Model Rotation 1"); + this.modelRot1.setText("" + this.defs.getModelRotation1()); + this.jLabel6.setText("Model Rotation 2"); + this.ModelRot2.setText("" + this.defs.getModelRotation2()); + this.jLabel7.setText("Model Offset 1"); + this.ModelOffset1.setText("" + this.defs.getModelOffset1()); + this.jLabel8.setText("Model Offset 2"); + this.modelOffset2.setText("" + this.defs.getModelOffset2()); + this.jLabel9.setText("Inventory Model"); + this.invModel.setText("" + this.defs.getInvModelId()); + this.jLabel10.setText("Male Equip 1"); + this.maleEquip1.setText("" + this.defs.getMaleEquipModelId1()); + this.jLabel11.setText("Female Equip 1"); + this.femaleEquip1.setText("" + this.defs.getFemaleEquipModelId1()); + this.jLabel12.setText("Male Equip 2"); + this.maleEquip2.setText("" + this.defs.getMaleEquipModelId2()); + this.jLabel13.setText("Female Equip 2"); + this.femaleEquip2.setText("" + this.defs.getFemaleEquipModelId2()); + this.jLabel14.setText("Male Equip 3"); + this.maleEquip3.setText("" + this.defs.getMaleEquipModelId3()); + this.jLabel15.setText("Female Equip 3"); + this.femaleEquip3.setText("" + this.defs.getFemaleEquipModelId3()); + GroupLayout jPanel2Layout = new GroupLayout(this.jPanel2); + this.jPanel2.setLayout(jPanel2Layout); + jPanel2Layout.setHorizontalGroup(jPanel2Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel2Layout.createSequentialGroup().addContainerGap().addGroup(jPanel2Layout.createParallelGroup(Alignment.LEADING, false).addGroup(jPanel2Layout.createSequentialGroup().addComponent(this.jLabel7).addPreferredGap(ComponentPlacement.RELATED, -1, 32767).addComponent(this.ModelOffset1, -2, 100, -2)).addGroup(jPanel2Layout.createSequentialGroup().addGroup(jPanel2Layout.createParallelGroup(Alignment.LEADING).addComponent(this.jLabel4).addComponent(this.jLabel5).addComponent(this.jLabel6)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel2Layout.createParallelGroup(Alignment.LEADING).addComponent(this.ModelRot2, -2, 100, -2).addComponent(this.modelRot1, -2, 100, -2).addComponent(this.invModelZoom, -2, 100, -2))).addGroup(Alignment.TRAILING, jPanel2Layout.createSequentialGroup().addComponent(this.jLabel8).addPreferredGap(ComponentPlacement.RELATED, -1, 32767).addComponent(this.modelOffset2, -2, 100, -2))).addGap(114, 114, 114).addGroup(jPanel2Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel2Layout.createSequentialGroup().addComponent(this.jLabel15).addPreferredGap(ComponentPlacement.UNRELATED).addComponent(this.femaleEquip3, -2, 100, -2)).addGroup(jPanel2Layout.createSequentialGroup().addGroup(jPanel2Layout.createParallelGroup(Alignment.LEADING).addComponent(this.jLabel9).addComponent(this.jLabel10)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel2Layout.createParallelGroup(Alignment.LEADING).addComponent(this.maleEquip1, -2, 100, -2).addComponent(this.invModel, -2, 100, -2))).addGroup(jPanel2Layout.createSequentialGroup().addGroup(jPanel2Layout.createParallelGroup(Alignment.LEADING).addComponent(this.jLabel11).addComponent(this.jLabel12)).addPreferredGap(ComponentPlacement.UNRELATED).addGroup(jPanel2Layout.createParallelGroup(Alignment.LEADING).addComponent(this.maleEquip2, -2, 100, -2).addComponent(this.femaleEquip1, -2, 100, -2))).addGroup(jPanel2Layout.createParallelGroup(Alignment.TRAILING, false).addGroup(jPanel2Layout.createSequentialGroup().addComponent(this.jLabel14).addPreferredGap(ComponentPlacement.RELATED, -1, 32767).addComponent(this.maleEquip3, -2, 100, -2)).addGroup(jPanel2Layout.createSequentialGroup().addComponent(this.jLabel13).addPreferredGap(ComponentPlacement.UNRELATED).addComponent(this.femaleEquip2, -2, 100, -2)))).addContainerGap(103, 32767))); + jPanel2Layout.setVerticalGroup(jPanel2Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel2Layout.createSequentialGroup().addContainerGap().addGroup(jPanel2Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel4).addComponent(this.invModelZoom, -2, -1, -2).addComponent(this.jLabel9).addComponent(this.invModel, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel2Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel5).addComponent(this.modelRot1, -2, -1, -2).addComponent(this.jLabel10).addComponent(this.maleEquip1, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel2Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel6).addComponent(this.ModelRot2, -2, -1, -2).addComponent(this.jLabel11).addComponent(this.femaleEquip1, -2, -1, -2)).addGroup(jPanel2Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel2Layout.createSequentialGroup().addGap(9, 9, 9).addGroup(jPanel2Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel7).addComponent(this.ModelOffset1, -2, -1, -2).addComponent(this.jLabel12)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel2Layout.createParallelGroup(Alignment.TRAILING).addComponent(this.jLabel8).addComponent(this.modelOffset2, -2, -1, -2).addGroup(Alignment.LEADING, jPanel2Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel13).addComponent(this.femaleEquip2, -2, -1, -2)))).addGroup(jPanel2Layout.createSequentialGroup().addPreferredGap(ComponentPlacement.RELATED).addComponent(this.maleEquip2, -2, -1, -2))).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel2Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel14).addComponent(this.maleEquip3, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel2Layout.createParallelGroup(Alignment.LEADING).addComponent(this.jLabel15).addComponent(this.femaleEquip3, -2, -1, -2)).addContainerGap(82, 32767))); + this.jTabbedPane1.addTab("Model", this.jPanel2); + this.jLabel16.setText("Inventory Options"); + this.invOptions.setText(this.getInventoryOpts()); + this.jLabel17.setText("Ground Options"); + this.groundOptions.setText(this.getGroundOpts()); + this.jLabel18.setText("Model Colors"); + this.modelColors.setText(this.getChangedModelColors()); + this.jLabel19.setText("Texture Colors"); + this.textureColors.setText(this.getChangedTextureColors()); + GroupLayout jPanel3Layout = new GroupLayout(this.jPanel3); + this.jPanel3.setLayout(jPanel3Layout); + jPanel3Layout.setHorizontalGroup(jPanel3Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel3Layout.createSequentialGroup().addContainerGap().addGroup(jPanel3Layout.createParallelGroup(Alignment.LEADING).addComponent(this.jLabel16).addComponent(this.invOptions, -2, 300, -2).addComponent(this.jLabel17).addComponent(this.groundOptions, -2, 300, -2).addComponent(this.jLabel18).addComponent(this.modelColors, -2, 300, -2).addComponent(this.jLabel19).addComponent(this.textureColors, -2, 300, -2)).addContainerGap(312, 32767))); + jPanel3Layout.setVerticalGroup(jPanel3Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel3Layout.createSequentialGroup().addContainerGap().addComponent(this.jLabel16).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.invOptions, -2, -1, -2).addGap(18, 18, 18).addComponent(this.jLabel17).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.groundOptions, -2, -1, -2).addGap(18, 18, 18).addComponent(this.jLabel18).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.modelColors, -2, -1, -2).addGap(18, 18, 18).addComponent(this.jLabel19).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.textureColors, -2, -1, -2).addContainerGap(47, 32767))); + this.jTabbedPane1.addTab("Options", this.jPanel3); + this.jLabel25.setText("unknownArray1"); + this.array1.setText(this.getUnknownArray1()); + this.jLabel27.setText("unknownArray2"); + this.jLabel28.setText("unknownArray3"); + this.jLabel29.setText("unknownArray4"); + this.jLabel30.setText("unknownArray5"); + this.jLabel31.setText("unknownArray6"); + this.array2.setText(this.getUnknownArray2()); + this.array3.setText(this.getUnknownArray3()); + this.array4.setText(this.getUnknownArray4()); + this.array5.setText(this.getUnknownArray5()); + this.array6.setText(this.getUnknownArray6()); + this.jLabel32.setText("unknownInt1"); + this.int1.setText("" + this.defs.unknownInt1); + this.int2.setText("" + this.defs.unknownInt2); + this.jLabel33.setText("unknownInt2"); + this.jLabel34.setText("unknownInt3"); + this.int3.setText("" + this.defs.unknownInt3); + this.jLabel35.setText("unknownInt4"); + this.int4.setText("" + this.defs.unknownInt4); + this.jLabel36.setText("unknownInt5"); + this.int5.setText("" + this.defs.unknownInt5); + this.jLabel37.setText("unknownInt6"); + this.int6.setText("" + this.defs.unknownInt6); + this.jLabel38.setText("unknownInt7"); + this.int7.setText("" + this.defs.unknownInt7); + this.jLabel39.setText("unknownInt8"); + this.int8.setText("" + this.defs.unknownInt8); + this.jLabel40.setText("unknownInt9"); + this.int9.setText("" + this.defs.unknownInt9); + this.jLabel41.setText("unknownInt10"); + this.int10.setText("" + this.defs.unknownInt10); + this.jLabel42.setText("unknownInt11"); + this.int11.setText("" + this.defs.unknownInt11); + this.jLabel43.setText("unknownInt12"); + this.int12.setText("" + this.defs.unknownInt12); + this.jLabel44.setText("unknownInt13"); + this.int13.setText("" + this.defs.unknownInt13); + this.jLabel45.setText("unknownInt14"); + this.int14.setText("" + this.defs.unknownInt14); + GroupLayout jPanel5Layout = new GroupLayout(this.jPanel5); + this.jPanel5.setLayout(jPanel5Layout); + jPanel5Layout.setHorizontalGroup(jPanel5Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel5Layout.createSequentialGroup().addContainerGap().addGroup(jPanel5Layout.createParallelGroup(Alignment.LEADING, false).addGroup(jPanel5Layout.createSequentialGroup().addGroup(jPanel5Layout.createParallelGroup(Alignment.LEADING).addComponent(this.jLabel31).addComponent(this.jLabel32).addComponent(this.jLabel33).addComponent(this.jLabel34).addComponent(this.jLabel35)).addGap(18, 18, 18).addGroup(jPanel5Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel5Layout.createSequentialGroup().addComponent(this.array6, -2, 200, -2).addPreferredGap(ComponentPlacement.RELATED, -1, 32767).addComponent(this.jLabel41).addGap(18, 18, 18).addComponent(this.int10, -2, 100, -2)).addGroup(jPanel5Layout.createSequentialGroup().addComponent(this.int1, -2, 100, -2).addPreferredGap(ComponentPlacement.RELATED, -1, 32767).addComponent(this.jLabel42).addGap(18, 18, 18).addComponent(this.int11, -2, 100, -2)).addGroup(jPanel5Layout.createSequentialGroup().addComponent(this.int4, -2, 100, -2).addPreferredGap(ComponentPlacement.RELATED, -1, 32767).addComponent(this.jLabel45).addGap(18, 18, 18).addComponent(this.int14, -2, 100, -2)).addGroup(jPanel5Layout.createSequentialGroup().addComponent(this.int2, -2, 100, -2).addPreferredGap(ComponentPlacement.RELATED, -1, 32767).addComponent(this.jLabel43).addGap(18, 18, 18).addComponent(this.int12, -2, 100, -2)).addGroup(jPanel5Layout.createSequentialGroup().addComponent(this.int3, -2, 100, -2).addPreferredGap(ComponentPlacement.RELATED, -1, 32767).addComponent(this.jLabel44).addGap(18, 18, 18).addComponent(this.int13, -2, 100, -2)))).addGroup(jPanel5Layout.createSequentialGroup().addComponent(this.jLabel30).addGap(18, 18, 18).addComponent(this.array5, -2, 200, -2).addPreferredGap(ComponentPlacement.RELATED, -1, 32767).addComponent(this.jLabel40).addGap(18, 18, 18).addComponent(this.int9, -2, 100, -2)).addGroup(jPanel5Layout.createSequentialGroup().addComponent(this.jLabel29).addGap(18, 18, 18).addComponent(this.array4, -2, 200, -2).addPreferredGap(ComponentPlacement.RELATED, -1, 32767).addComponent(this.jLabel39).addGap(18, 18, 18).addComponent(this.int8, -2, 100, -2)).addGroup(jPanel5Layout.createSequentialGroup().addComponent(this.jLabel28).addGap(18, 18, 18).addComponent(this.array3, -2, 200, -2).addPreferredGap(ComponentPlacement.RELATED, -1, 32767).addComponent(this.jLabel38).addGap(18, 18, 18).addComponent(this.int7, -2, 100, -2)).addGroup(jPanel5Layout.createSequentialGroup().addComponent(this.jLabel27).addGap(18, 18, 18).addComponent(this.array2, -2, 200, -2).addPreferredGap(ComponentPlacement.RELATED, -1, 32767).addComponent(this.jLabel37).addGap(18, 18, 18).addComponent(this.int6, -2, 100, -2)).addGroup(jPanel5Layout.createSequentialGroup().addComponent(this.jLabel25).addGap(18, 18, 18).addComponent(this.array1, -2, 200, -2).addGap(73, 73, 73).addComponent(this.jLabel36).addGap(18, 18, 18).addComponent(this.int5, -2, 100, -2))).addContainerGap(64, 32767))); + jPanel5Layout.setVerticalGroup(jPanel5Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel5Layout.createSequentialGroup().addContainerGap().addGroup(jPanel5Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel25).addComponent(this.array1, -2, -1, -2).addComponent(this.jLabel36).addComponent(this.int5, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel5Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel27).addComponent(this.array2, -2, -1, -2).addComponent(this.jLabel37).addComponent(this.int6, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel5Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel28).addComponent(this.array3, -2, -1, -2).addComponent(this.jLabel38).addComponent(this.int7, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel5Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel29).addComponent(this.array4, -2, -1, -2).addComponent(this.jLabel39).addComponent(this.int8, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel5Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel30).addComponent(this.array5, -2, -1, -2).addComponent(this.jLabel40).addComponent(this.int9, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel5Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel31).addComponent(this.array6, -2, -1, -2).addComponent(this.jLabel41).addComponent(this.int10, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel5Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel32).addComponent(this.int1, -2, -1, -2).addComponent(this.jLabel42).addComponent(this.int11, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel5Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel33).addComponent(this.int2, -2, -1, -2).addComponent(this.jLabel43).addComponent(this.int12, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel5Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel34).addComponent(this.int3, -2, -1, -2).addComponent(this.jLabel44).addComponent(this.int13, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel5Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel5Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel45).addComponent(this.int14, -2, -1, -2)).addGroup(jPanel5Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel35).addComponent(this.int4, -2, -1, -2))).addContainerGap(-1, 32767))); + this.jTabbedPane1.addTab("Unknown Definitions", this.jPanel5); + this.jLabel46.setText("unknownInt15"); + this.int15.setText("" + this.defs.unknownInt15); + this.jLabel47.setText("unknownInt16"); + this.int16.setText("" + this.defs.unknownInt16); + this.jLabel48.setText("unknownInt17"); + this.int17.setText("" + this.defs.unknownInt17); + this.jLabel49.setText("unknownInt18"); + this.int18.setText("" + this.defs.unknownInt18); + this.jLabel50.setText("unknownInt19"); + this.int19.setText("" + this.defs.unknownInt19); + this.jLabel51.setText("unknownInt20"); + this.int20.setText("" + this.defs.unknownInt20); + this.jLabel52.setText("unknownInt21"); + this.int21.setText("" + this.defs.unknownInt21); + this.jLabel53.setText("unknownInt22"); + this.int22.setText("" + this.defs.unknownInt22); + this.jLabel54.setText("unknownInt23"); + this.int23.setText("" + this.defs.unknownInt23); + GroupLayout jPanel6Layout = new GroupLayout(this.jPanel6); + this.jPanel6.setLayout(jPanel6Layout); + jPanel6Layout.setHorizontalGroup(jPanel6Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel6Layout.createSequentialGroup().addContainerGap().addGroup(jPanel6Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel6Layout.createSequentialGroup().addComponent(this.jLabel46).addGap(18, 18, 18).addComponent(this.int15, -2, 100, -2)).addGroup(jPanel6Layout.createSequentialGroup().addComponent(this.jLabel47).addGap(18, 18, 18).addComponent(this.int16, -2, 100, -2)).addGroup(jPanel6Layout.createSequentialGroup().addComponent(this.jLabel48).addGap(18, 18, 18).addComponent(this.int17, -2, 100, -2)).addGroup(jPanel6Layout.createSequentialGroup().addComponent(this.jLabel49).addGap(18, 18, 18).addComponent(this.int18, -2, 100, -2)).addGroup(jPanel6Layout.createSequentialGroup().addComponent(this.jLabel50).addGap(18, 18, 18).addComponent(this.int19, -2, 100, -2)).addGroup(jPanel6Layout.createSequentialGroup().addComponent(this.jLabel51).addGap(18, 18, 18).addComponent(this.int20, -2, 100, -2)).addGroup(jPanel6Layout.createSequentialGroup().addComponent(this.jLabel52).addGap(18, 18, 18).addComponent(this.int21, -2, 100, -2)).addGroup(jPanel6Layout.createSequentialGroup().addComponent(this.jLabel53).addGap(18, 18, 18).addComponent(this.int22, -2, 100, -2)).addGroup(jPanel6Layout.createSequentialGroup().addComponent(this.jLabel54).addGap(18, 18, 18).addComponent(this.int23, -2, 100, -2))).addContainerGap(425, 32767))); + jPanel6Layout.setVerticalGroup(jPanel6Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel6Layout.createSequentialGroup().addContainerGap().addGroup(jPanel6Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel46).addComponent(this.int15, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel6Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel47).addComponent(this.int16, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel6Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel48).addComponent(this.int17, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel6Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel49).addComponent(this.int18, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel6Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel50).addComponent(this.int19, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel6Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel51).addComponent(this.int20, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel6Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel52).addComponent(this.int21, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel6Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel53).addComponent(this.int22, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel6Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel54).addComponent(this.int23, -2, -1, -2)).addContainerGap(33, 32767))); + this.jTabbedPane1.addTab("Unknown Definitions(2)", this.jPanel6); + this.clientScriptOutput.setColumns(20); + this.clientScriptOutput.setRows(5); + this.clientScriptOutput.setText(this.getClientScripts()); + this.jScrollPane1.setViewportView(this.clientScriptOutput); + this.jLabel26.setText("KEY"); + this.jLabel55.setText("VALUE"); + this.jLabel56.setText("Add the keys to the left to the boxes to edit them."); + this.jLabel57.setText("Add new keys in the boxes to give the item new clientscripts."); + GroupLayout jPanel7Layout = new GroupLayout(this.jPanel7); + this.jPanel7.setLayout(jPanel7Layout); + jPanel7Layout.setHorizontalGroup(jPanel7Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel7Layout.createSequentialGroup().addContainerGap().addComponent(this.jScrollPane1, -2, 305, -2).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel7Layout.createParallelGroup(Alignment.LEADING).addComponent(this.jLabel57).addGroup(jPanel7Layout.createParallelGroup(Alignment.TRAILING).addGroup(jPanel7Layout.createSequentialGroup().addGroup(jPanel7Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel7Layout.createParallelGroup(Alignment.TRAILING).addComponent(this.csk2, -2, 75, -2).addComponent(this.csk1, -2, 75, -2).addComponent(this.csk3, -2, 75, -2).addComponent(this.csk4, -2, 75, -2).addComponent(this.csk5, -2, 75, -2).addComponent(this.csk6, -2, 75, -2).addComponent(this.csk7, -2, 75, -2)).addComponent(this.jLabel26)).addGap(58, 58, 58).addGroup(jPanel7Layout.createParallelGroup(Alignment.LEADING).addComponent(this.csv1, -2, 75, -2).addComponent(this.csv2, -2, 75, -2).addComponent(this.csv3, -2, 75, -2).addComponent(this.csv4, -2, 75, -2).addComponent(this.csv5, -2, 75, -2).addComponent(this.csv6, -2, 75, -2).addComponent(this.csv7, -2, 75, -2).addComponent(this.jLabel55))).addComponent(this.jLabel56))).addContainerGap(-1, 32767))); + jPanel7Layout.setVerticalGroup(jPanel7Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel7Layout.createSequentialGroup().addContainerGap().addGroup(jPanel7Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel7Layout.createSequentialGroup().addGroup(jPanel7Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel26).addComponent(this.jLabel55)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel7Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.csk1, -2, -1, -2).addComponent(this.csv1, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel7Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.csk2, -2, -1, -2).addComponent(this.csv2, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel7Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.csk3, -2, -1, -2).addComponent(this.csv3, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel7Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.csk4, -2, -1, -2).addComponent(this.csv4, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel7Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.csk5, -2, -1, -2).addComponent(this.csv5, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel7Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.csk6, -2, -1, -2).addComponent(this.csv6, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel7Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.csk7, -2, -1, -2).addComponent(this.csv7, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED, 20, 32767).addComponent(this.jLabel56).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.jLabel57)).addComponent(this.jScrollPane1)).addContainerGap())); + this.jTabbedPane1.addTab("Clientscripts", this.jPanel7); + this.currentViewLabel.setText("Currently Viewing Definitions of Item: " + this.defs.getId() + " - " + this.defs.getName()); + this.jMenu1.setText("File"); + this.reloadMenuBtn.setText("Reload"); + this.reloadMenuBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + ItemEditor.this.reloadMenuBtnActionPerformed(evt); + } + }); + this.jMenu1.add(this.reloadMenuBtn); + this.saveMenuBtn.setText("Save"); + this.saveMenuBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + ItemEditor.this.saveMenuBtnActionPerformed(evt); + } + }); + this.jMenu1.add(this.saveMenuBtn); + this.addModelMenuBtn.setText("Add Model"); + this.addModelMenuBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + ItemEditor.this.addModelMenuBtnActionPerformed(evt); + } + }); + this.jMenu1.add(this.addModelMenuBtn); + this.exportMenuBtn.setText("Export to .txt"); + this.exportMenuBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + ItemEditor.this.exportMenuBtnActionPerformed(evt); + } + }); + this.jMenu1.add(this.exportMenuBtn); + this.exitMenuBtn.setText("Exit"); + this.exitMenuBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + ItemEditor.this.exitMenuBtnActionPerformed(evt); + } + }); + this.jMenu1.add(this.exitMenuBtn); + this.jMenuBar1.add(this.jMenu1); + this.setJMenuBar(this.jMenuBar1); + GroupLayout layout = new GroupLayout(this.getContentPane()); + this.getContentPane().setLayout(layout); + layout.setHorizontalGroup(layout.createParallelGroup(Alignment.LEADING).addComponent(this.jTabbedPane1).addGroup(layout.createSequentialGroup().addContainerGap().addComponent(this.currentViewLabel).addContainerGap(-1, 32767))); + layout.setVerticalGroup(layout.createParallelGroup(Alignment.LEADING).addGroup(Alignment.TRAILING, layout.createSequentialGroup().addGap(0, 11, 32767).addComponent(this.currentViewLabel).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.jTabbedPane1, -2, 300, -2))); + this.pack(); + } + + private void exitMenuBtnActionPerformed(ActionEvent evt) { + this.dispose(); + } + + private void exportMenuBtnActionPerformed(ActionEvent evt) { + this.export(); + } + + private void addModelMenuBtnActionPerformed(ActionEvent evt) { + this.addModel(); + } + + private void saveMenuBtnActionPerformed(ActionEvent evt) { + this.save(); + } + + private void reloadMenuBtnActionPerformed(ActionEvent evt) { + this.itemName.setText(this.defs.getName()); + this.value.setText("" + this.defs.getValue()); + this.teamId.setText("" + this.defs.getTeamId()); + this.membersOnly.setSelected(this.defs.isMembersOnly()); + this.equipSlot.setText("" + this.defs.getEquipSlot()); + this.equipType.setText("" + this.defs.getEquipType()); + this.stackIDs.setText(this.getStackIDs()); + this.stackAmts.setText(this.getStackAmts()); + this.stackable.setText("" + this.defs.getStackable()); + this.invModelZoom.setText("" + this.defs.getInvModelZoom()); + this.modelRot1.setText("" + this.defs.getModelRotation1()); + this.ModelRot2.setText("" + this.defs.getModelRotation2()); + this.ModelOffset1.setText("" + this.defs.getModelOffset1()); + this.modelOffset2.setText("" + this.defs.getModelOffset2()); + this.invModel.setText("" + this.defs.getInvModelId()); + this.maleEquip1.setText("" + this.defs.getMaleEquipModelId1()); + this.femaleEquip1.setText("" + this.defs.getFemaleEquipModelId1()); + this.maleEquip2.setText("" + this.defs.getMaleEquipModelId2()); + this.femaleEquip2.setText("" + this.defs.getFemaleEquipModelId2()); + this.maleEquip3.setText("" + this.defs.getMaleEquipModelId3()); + this.femaleEquip3.setText("" + this.defs.getFemaleEquipModelId3()); + this.invOptions.setText(this.getInventoryOpts()); + this.groundOptions.setText(this.getGroundOpts()); + this.modelColors.setText(this.getChangedModelColors()); + this.textureColors.setText(this.getChangedTextureColors()); + this.switchNote.setText("" + this.defs.switchNoteItemId); + this.note.setText("" + this.defs.notedItemId); + this.unnoted.setSelected(this.defs.isUnnoted()); + this.switchLend.setText("" + this.defs.getSwitchLendItemId()); + this.lend.setText("" + this.defs.getLendedItemId()); + this.array1.setText(this.getUnknownArray1()); + this.array2.setText(this.getUnknownArray2()); + this.array3.setText(this.getUnknownArray3()); + this.array4.setText(this.getUnknownArray4()); + this.array5.setText(this.getUnknownArray5()); + this.array6.setText(this.getUnknownArray6()); + this.int1.setText("" + this.defs.unknownInt1); + this.int2.setText("" + this.defs.unknownInt2); + this.int3.setText("" + this.defs.unknownInt3); + this.int4.setText("" + this.defs.unknownInt4); + this.int5.setText("" + this.defs.unknownInt5); + this.int6.setText("" + this.defs.unknownInt6); + this.int7.setText("" + this.defs.unknownInt7); + this.int8.setText("" + this.defs.unknownInt8); + this.int9.setText("" + this.defs.unknownInt9); + this.int10.setText("" + this.defs.unknownInt10); + this.int11.setText("" + this.defs.unknownInt11); + this.int12.setText("" + this.defs.unknownInt12); + this.int13.setText("" + this.defs.unknownInt13); + this.int14.setText("" + this.defs.unknownInt14); + this.int15.setText("" + this.defs.unknownInt15); + this.int16.setText("" + this.defs.unknownInt16); + this.int17.setText("" + this.defs.unknownInt17); + this.int18.setText("" + this.defs.unknownInt18); + this.int19.setText("" + this.defs.unknownInt19); + this.int20.setText("" + this.defs.unknownInt20); + this.int21.setText("" + this.defs.unknownInt21); + this.int22.setText("" + this.defs.unknownInt22); + this.int23.setText("" + this.defs.unknownInt23); + this.clientScriptOutput.setText(this.getClientScripts()); + } + + private void export() { + File f = new File(System.getProperty("user.home") + "/FCE/items/"); + f.mkdirs(); + String lineSep = System.getProperty("line.separator"); + BufferedWriter writer = null; + + try { + writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(System.getProperty("user.home") + "/FCE/items/" + this.defs.id + ".txt"), "utf-8")); + writer.write("name = " + this.defs.getName()); + writer.write(lineSep); + writer.write("value = " + this.defs.getValue()); + writer.write(lineSep); + writer.write("team id = " + this.defs.getTeamId()); + writer.write(lineSep); + writer.write("members only = " + String.valueOf(this.defs.isMembersOnly())); + writer.write(lineSep); + writer.write("equip slot = " + this.defs.getEquipSlot()); + writer.write(lineSep); + writer.write("equip type = " + this.defs.getEquipType()); + writer.write(lineSep); + writer.write("stack ids = " + this.getStackIDs()); + writer.write(lineSep); + writer.write("stack amounts = " + this.getStackAmts()); + writer.write(lineSep); + writer.write("stackable = " + this.defs.getStackable()); + writer.write(lineSep); + writer.write("inv model zoom = " + this.defs.getInvModelZoom()); + writer.write(lineSep); + writer.write("model rotation 1 = " + this.defs.getModelRotation1()); + writer.write(lineSep); + writer.write("model rotation 2 = " + this.defs.getModelRotation2()); + writer.write(lineSep); + writer.write("model offset 1 = " + this.defs.getModelOffset1()); + writer.write(lineSep); + writer.write("model offset 2 = " + this.defs.getModelOffset2()); + writer.write(lineSep); + writer.write("inv model id = " + this.defs.getInvModelId()); + writer.write(lineSep); + writer.write("male equip model id 1 = " + this.defs.getMaleEquipModelId1()); + writer.write(lineSep); + writer.write("female equip model id 1 = " + this.defs.getFemaleEquipModelId1()); + writer.write(lineSep); + writer.write("male equip model id 2 = " + this.defs.getMaleEquipModelId2()); + writer.write(lineSep); + writer.write("female equip model id 2 = " + this.defs.getFemaleEquipModelId2()); + writer.write(lineSep); + writer.write("male equip model id 3 = " + this.defs.getMaleEquipModelId3()); + writer.write(lineSep); + writer.write("female equip model id 3 = " + this.defs.getFemaleEquipModelId3()); + writer.write(lineSep); + writer.write("inventory options = " + this.getInventoryOpts()); + writer.write(lineSep); + writer.write("ground options = " + this.getGroundOpts()); + writer.write(lineSep); + writer.write("changed model colors = " + this.getChangedModelColors()); + writer.write(lineSep); + writer.write("changed texture colors = " + this.getChangedTextureColors()); + writer.write(lineSep); + writer.write("switch note item id = " + this.defs.switchNoteItemId); + writer.write(lineSep); + writer.write("noted item id = " + this.defs.notedItemId); + writer.write(lineSep); + writer.write("unnoted = " + String.valueOf(this.defs.isUnnoted())); + writer.write(lineSep); + writer.write("switch lend item id = " + this.defs.getSwitchLendItemId()); + writer.write(lineSep); + writer.write("lended item id = " + this.defs.getLendedItemId()); + writer.write(lineSep); + writer.write("unknownArray1 = " + this.getUnknownArray1()); + writer.write(lineSep); + writer.write("unknownArray2 = " + this.getUnknownArray2()); + writer.write(lineSep); + writer.write("unknownArray3 = " + this.getUnknownArray3()); + writer.write(lineSep); + writer.write("unknownArray4 = " + this.getUnknownArray4()); + writer.write(lineSep); + writer.write("unknownArray5 = " + this.getUnknownArray5()); + writer.write(lineSep); + writer.write("unknownArray6 = " + this.getUnknownArray6()); + writer.write(lineSep); + writer.write("unknownInt1 = " + this.defs.unknownInt1); + writer.write(lineSep); + writer.write("unknownInt2 = " + this.defs.unknownInt2); + writer.write(lineSep); + writer.write("unknownInt3 = " + this.defs.unknownInt3); + writer.write(lineSep); + writer.write("unknownInt4 = " + this.defs.unknownInt4); + writer.write(lineSep); + writer.write("unknownInt5 = " + this.defs.unknownInt5); + writer.write(lineSep); + writer.write("unknownInt6 = " + this.defs.unknownInt6); + writer.write(lineSep); + writer.write("unknownInt7 = " + this.defs.unknownInt7); + writer.write(lineSep); + writer.write("unknownInt8 = " + this.defs.unknownInt8); + writer.write(lineSep); + writer.write("unknownInt9 = " + this.defs.unknownInt9); + writer.write(lineSep); + writer.write("unknownInt10 = " + this.defs.unknownInt10); + writer.write(lineSep); + writer.write("unknownInt11 = " + this.defs.unknownInt11); + writer.write(lineSep); + writer.write("unknownInt12 = " + this.defs.unknownInt12); + writer.write(lineSep); + writer.write("unknownInt13 = " + this.defs.unknownInt13); + writer.write(lineSep); + writer.write("unknownInt14 = " + this.defs.unknownInt14); + writer.write(lineSep); + writer.write("unknownInt15 = " + this.defs.unknownInt15); + writer.write(lineSep); + writer.write("unknownInt16 = " + this.defs.unknownInt16); + writer.write(lineSep); + writer.write("unknownInt17 = " + this.defs.unknownInt17); + writer.write(lineSep); + writer.write("unknownInt18 = " + this.defs.unknownInt18); + writer.write(lineSep); + writer.write("unknownInt19 = " + this.defs.unknownInt19); + writer.write(lineSep); + writer.write("unknownInt20 = " + this.defs.unknownInt20); + writer.write(lineSep); + writer.write("unknownInt21 = " + this.defs.unknownInt21); + writer.write(lineSep); + writer.write("unknownInt22 = " + this.defs.unknownInt22); + writer.write(lineSep); + writer.write("unknownInt23 = " + this.defs.unknownInt23); + writer.write(lineSep); + writer.write("Clientscripts"); + writer.write(lineSep); + if(this.defs.clientScriptData != null) { + Iterator var15 = this.defs.clientScriptData.keySet().iterator(); + + while(var15.hasNext()) { + int key = ((Integer)var15.next()).intValue(); + Object value = this.defs.clientScriptData.get(Integer.valueOf(key)); + writer.write("KEY: " + key + ", VALUE: " + value); + writer.write(lineSep); + } + } + } catch (IOException var151) { + Main.log("ItemEditor", "Failed to export Item Defs to .txt"); + } finally { + try { + writer.close(); + } catch (Exception var14) { + ; + } + + } + + } + + private void save() { + try { + this.defs.setName(this.itemName.getText().toString()); + this.defs.setValue(Integer.parseInt(this.value.getText().toString())); + this.defs.setTeamId(Integer.parseInt(this.teamId.getText().toString())); + this.defs.setMembersOnly(this.membersOnly.isSelected()); + this.defs.setEquipSlot(Integer.parseInt(this.equipSlot.getText().toString())); + this.defs.setEquipType(Integer.parseInt(this.equipType.getText().toString())); + String[] var17; + int invOpts; + if(!this.stackIDs.getText().equals("")) { + var17 = this.stackIDs.getText().split(";"); + + for(invOpts = 0; invOpts < this.defs.getStackIds().length; ++invOpts) { + this.defs.getStackIds()[invOpts] = Integer.parseInt(var17[invOpts]); + } + } + + if(!this.stackAmts.getText().equals("")) { + var17 = this.stackAmts.getText().split(";"); + + for(invOpts = 0; invOpts < this.defs.getStackAmounts().length; ++invOpts) { + this.defs.getStackAmounts()[invOpts] = Integer.parseInt(var17[invOpts]); + } + } + + this.defs.setStackable(Integer.parseInt(this.stackable.getText().toString())); + this.defs.setInvModelZoom(Integer.parseInt(this.invModelZoom.getText().toString())); + this.defs.setModelRotation1(Integer.parseInt(this.modelRot1.getText().toString())); + this.defs.setModelRotation2(Integer.parseInt(this.ModelRot2.getText().toString())); + this.defs.setModelOffset1(Integer.parseInt(this.ModelOffset1.getText().toString())); + this.defs.setModelOffset2(Integer.parseInt(this.modelOffset2.getText().toString())); + this.defs.setInvModelId(Integer.parseInt(this.invModel.getText().toString())); + this.defs.maleEquip1 = Integer.parseInt(this.maleEquip1.getText().toString()); + this.defs.maleEquip2 = Integer.parseInt(this.maleEquip2.getText().toString()); + this.defs.maleEquipModelId3 = Integer.parseInt(this.maleEquip3.getText().toString()); + this.defs.femaleEquip1 = Integer.parseInt(this.femaleEquip1.getText().toString()); + this.defs.femaleEquip2 = Integer.parseInt(this.femaleEquip2.getText().toString()); + this.defs.femaleEquipModelId3 = Integer.parseInt(this.femaleEquip3.getText().toString()); + var17 = this.groundOptions.getText().split(";"); + + for(invOpts = 0; invOpts < this.defs.getGroundOptions().length; ++invOpts) { + this.defs.getGroundOptions()[invOpts] = var17[invOpts].equals("null")?null:var17[invOpts]; + } + + String[] var19 = this.invOptions.getText().split(";"); + + for(int i = 0; i < this.defs.getInventoryOptions().length; ++i) { + this.defs.getInventoryOptions()[i] = var19[i].equals("null")?null:var19[i]; + } + + this.defs.resetModelColors(); + int len$; + int i$; + String t; + String[] editedColor; + String[] var18; + String[] var21; + if(!this.modelColors.getText().equals("")) { + var18 = this.modelColors.getText().split(";"); + var21 = var18; + len$ = var18.length; + + for(i$ = 0; i$ < len$; ++i$) { + t = var21[i$]; + editedColor = t.split("="); + this.defs.changeModelColor(Integer.valueOf(editedColor[0]).intValue(), Integer.valueOf(editedColor[1]).intValue()); + } + } + + this.defs.resetTextureColors(); + if(!this.textureColors.getText().equals("")) { + var18 = this.textureColors.getText().split(";"); + var21 = var18; + len$ = var18.length; + + for(i$ = 0; i$ < len$; ++i$) { + t = var21[i$]; + editedColor = t.split("="); + this.defs.changeTextureColor(Short.valueOf(editedColor[0]).shortValue(), Short.valueOf(editedColor[1]).shortValue()); + } + } + + this.defs.notedItemId = Integer.valueOf(this.note.getText()).intValue(); + this.defs.switchNoteItemId = Integer.valueOf(this.switchNote.getText()).intValue(); + this.defs.lendedItemId = Integer.valueOf(this.lend.getText()).intValue(); + this.defs.switchLendItemId = Integer.valueOf(this.switchLend.getText()).intValue(); + this.defs.setUnnoted(this.unnoted.isSelected()); + int var20; + if(!this.array1.getText().equals("")) { + var18 = this.array1.getText().split(";"); + + for(var20 = 0; var20 < this.defs.unknownArray1.length; ++var20) { + this.defs.unknownArray1[var20] = (byte)Integer.parseInt(var18[var20]); + } + } + + if(!this.array2.getText().equals("")) { + var18 = this.array2.getText().split(";"); + + for(var20 = 0; var20 < this.defs.unknownArray2.length; ++var20) { + this.defs.unknownArray2[var20] = Integer.parseInt(var18[var20]); + } + } + + if(!this.array3.getText().equals("")) { + var18 = this.array3.getText().split(";"); + + for(var20 = 0; var20 < this.defs.unknownArray3.length; ++var20) { + this.defs.unknownArray3[var20] = (byte)Integer.parseInt(var18[var20]); + } + } + + if(!this.array4.getText().equals("")) { + var18 = this.array4.getText().split(";"); + + for(var20 = 0; var20 < this.defs.unknownArray4.length; ++var20) { + this.defs.unknownArray4[var20] = Integer.parseInt(var18[var20]); + } + } + + if(!this.array5.getText().equals("")) { + var18 = this.array5.getText().split(";"); + + for(var20 = 0; var20 < this.defs.unknownArray5.length; ++var20) { + this.defs.unknownArray5[var20] = Integer.parseInt(var18[var20]); + } + } + + if(!this.array6.getText().equals("")) { + var18 = this.array6.getText().split(";"); + + for(var20 = 0; var20 < this.defs.unknownArray6.length; ++var20) { + this.defs.unknownArray6[var20] = (byte)Integer.parseInt(var18[var20]); + } + } + + this.defs.unknownInt1 = Integer.parseInt(this.int1.getText()); + this.defs.unknownInt2 = Integer.parseInt(this.int2.getText()); + this.defs.unknownInt3 = Integer.parseInt(this.int3.getText()); + this.defs.unknownInt4 = Integer.parseInt(this.int4.getText()); + this.defs.unknownInt5 = Integer.parseInt(this.int5.getText()); + this.defs.unknownInt6 = Integer.parseInt(this.int6.getText()); + this.defs.unknownInt7 = Integer.parseInt(this.int7.getText()); + this.defs.unknownInt8 = Integer.parseInt(this.int8.getText()); + this.defs.unknownInt9 = Integer.parseInt(this.int9.getText()); + this.defs.unknownInt10 = Integer.parseInt(this.int10.getText()); + this.defs.unknownInt11 = Integer.parseInt(this.int11.getText()); + this.defs.unknownInt12 = Integer.parseInt(this.int12.getText()); + this.defs.unknownInt13 = Integer.parseInt(this.int13.getText()); + this.defs.unknownInt14 = Integer.parseInt(this.int14.getText()); + this.defs.unknownInt15 = Integer.parseInt(this.int15.getText()); + this.defs.unknownInt16 = Integer.parseInt(this.int16.getText()); + this.defs.unknownInt17 = Integer.parseInt(this.int17.getText()); + this.defs.unknownInt18 = Integer.parseInt(this.int18.getText()); + this.defs.unknownInt19 = Integer.parseInt(this.int19.getText()); + this.defs.unknownInt20 = Integer.parseInt(this.int20.getText()); + this.defs.unknownInt21 = Integer.parseInt(this.int21.getText()); + this.defs.unknownInt22 = Integer.parseInt(this.int22.getText()); + this.defs.unknownInt23 = Integer.parseInt(this.int23.getText()); + + try { + if(!this.csk1.getText().equals("") && !this.csv1.getText().equals("")) { + try { + this.defs.clientScriptData.remove(this.csk1); + this.defs.clientScriptData.put(Integer.valueOf(Integer.parseInt(this.csk1.getText())), Integer.valueOf(Integer.parseInt(this.csv1.getText()))); + } catch (Exception var181) { + this.defs.clientScriptData.remove(this.csk1); + this.defs.clientScriptData.put(Integer.valueOf(Integer.parseInt(this.csk1.getText())), this.csv1.getText().toString()); + } + } + + if(!this.csk2.getText().equals("") && !this.csv2.getText().equals("")) { + try { + this.defs.clientScriptData.remove(this.csk2); + this.defs.clientScriptData.put(Integer.valueOf(Integer.parseInt(this.csk2.getText())), Integer.valueOf(Integer.parseInt(this.csv2.getText()))); + } catch (Exception var171) { + this.defs.clientScriptData.remove(this.csk2); + this.defs.clientScriptData.put(Integer.valueOf(Integer.parseInt(this.csk2.getText())), this.csv2.getText().toString()); + } + } + + if(!this.csk3.getText().equals("") && !this.csv3.getText().equals("")) { + try { + this.defs.clientScriptData.remove(this.csk3); + this.defs.clientScriptData.put(Integer.valueOf(Integer.parseInt(this.csk3.getText())), Integer.valueOf(Integer.parseInt(this.csv3.getText()))); + } catch (Exception var16) { + this.defs.clientScriptData.remove(this.csk3); + this.defs.clientScriptData.put(Integer.valueOf(Integer.parseInt(this.csk3.getText())), this.csv3.getText().toString()); + } + } + + if(!this.csk4.getText().equals("") && !this.csv4.getText().equals("")) { + try { + this.defs.clientScriptData.remove(this.csk4); + this.defs.clientScriptData.put(Integer.valueOf(Integer.parseInt(this.csk4.getText())), Integer.valueOf(Integer.parseInt(this.csv4.getText()))); + } catch (Exception var15) { + this.defs.clientScriptData.remove(this.csk4); + this.defs.clientScriptData.put(Integer.valueOf(Integer.parseInt(this.csk4.getText())), this.csv4.getText().toString()); + } + } + + if(!this.csk5.getText().equals("") && !this.csv5.getText().equals("")) { + try { + this.defs.clientScriptData.remove(this.csk5); + this.defs.clientScriptData.put(Integer.valueOf(Integer.parseInt(this.csk5.getText())), Integer.valueOf(Integer.parseInt(this.csv5.getText()))); + } catch (Exception var14) { + this.defs.clientScriptData.remove(this.csk5); + this.defs.clientScriptData.put(Integer.valueOf(Integer.parseInt(this.csk5.getText())), this.csv5.getText().toString()); + } + } + + if(!this.csk6.getText().equals("") && !this.csv6.getText().equals("")) { + try { + this.defs.clientScriptData.remove(this.csk6); + this.defs.clientScriptData.put(Integer.valueOf(Integer.parseInt(this.csk6.getText())), Integer.valueOf(Integer.parseInt(this.csv6.getText()))); + } catch (Exception var13) { + this.defs.clientScriptData.remove(this.csk6); + this.defs.clientScriptData.put(Integer.valueOf(Integer.parseInt(this.csk6.getText())), this.csv6.getText().toString()); + } + } + + if(!this.csk7.getText().equals("") && !this.csv7.getText().equals("")) { + try { + this.defs.clientScriptData.remove(this.csk7); + this.defs.clientScriptData.put(Integer.valueOf(Integer.parseInt(this.csk7.getText())), Integer.valueOf(Integer.parseInt(this.csv7.getText()))); + } catch (Exception var12) { + this.defs.clientScriptData.remove(this.csk7); + this.defs.clientScriptData.put(Integer.valueOf(Integer.parseInt(this.csk7.getText())), this.csv7.getText().toString()); + } + } + } catch (Exception var191) { + this.defs.clientScriptData = new HashMap(1); + } + + ItemSelection var10001 = this.is; + this.defs.write(ItemSelection.STORE); + this.is.updateItemDefs(this.defs); + } catch (Exception var201) { + Main.log("ItemEditor", "Cannot save. Please check for mistypes."); + } + + } + + private void addModel() { + JFrame frame = new JFrame(); + int result = JOptionPane.showConfirmDialog(frame, "Do you want to specify a model ID?"); + StringBuilder var10001; + ItemSelection var10002; + if(result == 0) { + JFrame fc1 = new JFrame(); + String returnVal1 = JOptionPane.showInputDialog(fc1, "Enter new model ID:"); + if(Integer.parseInt(returnVal1.toString()) != -1) { + JFileChooser file2 = new JFileChooser(); + file2.setFileSelectionMode(0); + int var9 = file2.showOpenDialog(this); + if(var9 == 0) { + File file1 = file2.getSelectedFile(); + + try { + var10001 = (new StringBuilder()).append("The model ID of the recently packed model is: "); + var10002 = this.is; + Main.log("ItemEditor", var10001.append(Utils.packCustomModel(ItemSelection.STORE, Utils.getBytesFromFile(new File(file1.getPath().toString())), Integer.parseInt(returnVal1.toString()))).toString()); + } catch (IOException var12) { + Main.log("ItemEditor", "There was an error packing the model."); + } + } + } + } else if(result == 1) { + JFileChooser fc11 = new JFileChooser(); + fc11.setFileSelectionMode(0); + int returnVal11 = fc11.showOpenDialog(this); + if(returnVal11 == 0) { + File file21 = fc11.getSelectedFile(); + + try { + var10001 = (new StringBuilder()).append("The model ID of the recently packed model is: "); + var10002 = this.is; + Main.log("ItemEditor", var10001.append(Utils.packCustomModel(ItemSelection.STORE, Utils.getBytesFromFile(new File(file21.getPath().toString())))).toString()); + } catch (IOException var11) { + Main.log("ItemEditor", "There was an error packing the model."); + } + } + } + + } + + public String getInventoryOpts() { + String text = ""; + String[] arr$ = this.defs.getInventoryOptions(); + int len$ = arr$.length; + + for(int i$ = 0; i$ < len$; ++i$) { + String option = arr$[i$]; + text = text + (option == null?"null":option) + ";"; + } + + return text; + } + + public String getGroundOpts() { + String text = ""; + String[] arr$ = this.defs.getGroundOptions(); + int len$ = arr$.length; + + for(int i$ = 0; i$ < len$; ++i$) { + String option = arr$[i$]; + text = text + (option == null?"null":option) + ";"; + } + + return text; + } + + public String getChangedModelColors() { + String text = ""; + if(this.defs.originalModelColors != null) { + for(int i = 0; i < this.defs.originalModelColors.length; ++i) { + text = text + this.defs.originalModelColors[i] + "=" + this.defs.modifiedModelColors[i] + ";"; + } + } + + return text; + } + + public String getChangedTextureColors() { + String text = ""; + if(this.defs.originalTextureColors != null) { + for(int i = 0; i < this.defs.originalTextureColors.length; ++i) { + text = text + this.defs.originalTextureColors[i] + "=" + this.defs.modifiedTextureColors[i] + ";"; + } + } + + return text; + } + + public String getStackIDs() { + String text = ""; + + try { + int[] e = this.defs.getStackIds(); + int len$ = e.length; + + for(int i$ = 0; i$ < len$; ++i$) { + int index = e[i$]; + text = text + index + ";"; + } + } catch (Exception var6) { + ; + } + + return text; + } + + public String getClientScripts() { + String text = ""; + String lineSep = System.getProperty("line.separator"); + if(this.defs.clientScriptData != null) { + for(Iterator i$ = this.defs.clientScriptData.keySet().iterator(); i$.hasNext(); text = text + lineSep) { + int key = ((Integer)i$.next()).intValue(); + Object value = this.defs.clientScriptData.get(Integer.valueOf(key)); + text = text + "KEY: " + key + ", VALUE: " + value; + } + } + + return text; + } + + public String getStackAmts() { + String text = ""; + + try { + int[] e = this.defs.getStackAmounts(); + int len$ = e.length; + + for(int i$ = 0; i$ < len$; ++i$) { + int index = e[i$]; + text = text + index + ";"; + } + } catch (Exception var6) { + ; + } + + return text; + } + + public String getUnknownArray1() { + String text = ""; + + try { + byte[] e = this.defs.unknownArray1; + int len$ = e.length; + + for(int i$ = 0; i$ < len$; ++i$) { + byte index = e[i$]; + text = text + index + ";"; + } + } catch (Exception var6) { + ; + } + + return text; + } + + public String getUnknownArray2() { + String text = ""; + + try { + int[] e = this.defs.unknownArray2; + int len$ = e.length; + + for(int i$ = 0; i$ < len$; ++i$) { + int index = e[i$]; + text = text + index + ";"; + } + } catch (Exception var6) { + ; + } + + return text; + } + + public String getUnknownArray3() { + String text = ""; + + try { + byte[] e = this.defs.unknownArray3; + int len$ = e.length; + + for(int i$ = 0; i$ < len$; ++i$) { + byte index = e[i$]; + text = text + index + ";"; + } + } catch (Exception var6) { + ; + } + + return text; + } + + public String getUnknownArray4() { + String text = ""; + + try { + int[] e = this.defs.unknownArray4; + int len$ = e.length; + + for(int i$ = 0; i$ < len$; ++i$) { + int index = e[i$]; + text = text + index + ";"; + } + } catch (Exception var6) { + ; + } + + return text; + } + + public String getUnknownArray5() { + String text = ""; + + try { + int[] e = this.defs.unknownArray5; + int len$ = e.length; + + for(int i$ = 0; i$ < len$; ++i$) { + int index = e[i$]; + text = text + index + ";"; + } + } catch (Exception var6) { + ; + } + + return text; + } + + public String getUnknownArray6() { + String text = ""; + + try { + byte[] e = this.defs.unknownArray6; + int len$ = e.length; + + for(int i$ = 0; i$ < len$; ++i$) { + byte index = e[i$]; + text = text + index + ";"; + } + } catch (Exception var6) { + ; + } + + return text; + } +} diff --git a/Tools/Frostys Cache Editor/src/com/editor/item/ItemListDumper.java b/Tools/Frostys Cache Editor/src/com/editor/item/ItemListDumper.java new file mode 100644 index 0000000..fef7b59 --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/editor/item/ItemListDumper.java @@ -0,0 +1,57 @@ +package com.editor.item; + +import com.alex.loaders.items.ItemDefinitions; +import com.alex.store.Store; +import com.alex.utils.Utils; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; + +public class ItemListDumper { + private static Store STORE; + + public static void main(String[] args) { + try { + STORE = new Store("C:/Users/Travis/Documents/rscd/data/"); + new ItemListDumper(); + } catch (IOException var2) { + var2.printStackTrace(); + } + + } + + public ItemListDumper() throws IOException { + File file = new File("C:/Users/Travis/Documents/781 ItemList.txt"); + if(file.exists()) { + file.delete(); + } else { + file.createNewFile(); + } + + BufferedWriter writer = new BufferedWriter(new FileWriter(file)); + writer.append("//Version = 781\n"); + writer.flush(); + + for(int id = 0; id < Utils.getItemDefinitionsSize(STORE); ++id) { + ItemDefinitions def = ItemDefinitions.getItemDefinition(STORE, id); + if(!def.getName().equals("null")) { + writer.append(id + " - " + def.getName()); + writer.newLine(); + writer.flush(); + } + } + + writer.close(); + } + + public static int convertInt(String str) { + try { + int var2 = Integer.parseInt(str); + return var2; + } catch (NumberFormatException var21) { + return 0; + } + } +} diff --git a/Tools/Frostys Cache Editor/src/com/editor/item/ItemSelection.java b/Tools/Frostys Cache Editor/src/com/editor/item/ItemSelection.java new file mode 100644 index 0000000..df50c82 --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/editor/item/ItemSelection.java @@ -0,0 +1,198 @@ +package com.editor.item; + +import com.alex.loaders.items.ItemDefinitions; +import com.alex.store.Store; +import com.alex.utils.Utils; +import com.editor.Main; +import com.editor.item.ItemEditor; + +import javax.swing.GroupLayout.Alignment; +import javax.swing.LayoutStyle.ComponentPlacement; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.IOException; + +public class ItemSelection extends JFrame { + private static final long serialVersionUID = -3059309913196024742L; + public static Store STORE; + private JButton addButton; + private JButton duplicateButton; + private JButton editButton; + private DefaultListModel itemsListmodel; + private JList itemsList; + private JMenu jMenu1; + private JMenuBar jMenuBar1; + private JMenuItem exitButton; + private JButton deleteButton; + + public ItemSelection(String cache) throws IOException { + STORE = new Store(cache); + this.setTitle("Item Selection"); + this.setResizable(false); + this.setDefaultCloseOperation(1); + this.setLocationRelativeTo((Component)null); + this.initComponents(); + } + + public ItemSelection() { + this.initComponents(); + } + + private void initComponents() { + this.editButton = new JButton(); + this.addButton = new JButton(); + this.duplicateButton = new JButton(); + this.deleteButton = new JButton(); + this.jMenuBar1 = new JMenuBar(); + this.jMenu1 = new JMenu(); + this.exitButton = new JMenuItem(); + this.setDefaultCloseOperation(1); + this.itemsListmodel = new DefaultListModel(); + this.itemsList = new JList(this.itemsListmodel); + this.itemsList.setSelectionMode(1); + this.itemsList.setLayoutOrientation(0); + this.itemsList.setVisibleRowCount(-1); + JScrollPane jScrollPane1 = new JScrollPane(this.itemsList); + this.editButton.setText("Edit"); + this.editButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + ItemDefinitions defs = (ItemDefinitions)ItemSelection.this.itemsList.getSelectedValue(); + if(defs != null) { + new ItemEditor(ItemSelection.this, defs); + } + + } + }); + this.addButton.setText("Add New"); + this.addButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + ItemDefinitions defs = new ItemDefinitions(ItemSelection.STORE, ItemSelection.this.getNewItemID(), false); + if(defs != null && defs.id != -1) { + new ItemEditor(ItemSelection.this, defs); + } + + } + }); + this.duplicateButton.setText("Duplicate"); + this.duplicateButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + ItemDefinitions defs = (ItemDefinitions)ItemSelection.this.itemsList.getSelectedValue(); + if(defs != null) { + defs = (ItemDefinitions)defs.clone(); + if(defs != null) { + defs.id = ItemSelection.this.getNewItemID(); + if(defs.id != -1) { + new ItemEditor(ItemSelection.this, defs); + } + } + } + + } + }); + this.deleteButton.setText("Delete"); + this.deleteButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + ItemDefinitions defs = (ItemDefinitions)ItemSelection.this.itemsList.getSelectedValue(); + JFrame frame = new JFrame(); + int result = JOptionPane.showConfirmDialog(frame, "Do you really want to delete item " + defs.id); + if(result == 0) { + if(defs == null) { + return; + } + + ItemSelection.STORE.getIndexes()[19].removeFile(defs.getArchiveId(), defs.getFileId()); + ItemSelection.this.removeItemDefs(defs); + Main.log("ItemSelection", "Item " + defs.id + " removed."); + } + + } + }); + this.jMenu1.setText("File"); + this.exitButton.setText("Close"); + this.exitButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + ItemSelection.this.exitButtonActionPerformed(evt); + } + }); + this.jMenu1.add(this.exitButton); + this.jMenuBar1.add(this.jMenu1); + this.setJMenuBar(this.jMenuBar1); + GroupLayout layout = new GroupLayout(this.getContentPane()); + this.getContentPane().setLayout(layout); + layout.setHorizontalGroup(layout.createParallelGroup(Alignment.LEADING).addGroup(layout.createSequentialGroup().addContainerGap().addGroup(layout.createParallelGroup(Alignment.LEADING).addGroup(layout.createSequentialGroup().addGroup(layout.createParallelGroup(Alignment.LEADING, false).addComponent(jScrollPane1, -2, 200, -2).addGroup(layout.createSequentialGroup().addComponent(this.editButton).addPreferredGap(ComponentPlacement.RELATED, -1, 32767).addComponent(this.addButton))).addGap(0, 0, 32767)).addGroup(layout.createSequentialGroup().addComponent(this.duplicateButton).addPreferredGap(ComponentPlacement.RELATED, -1, 32767).addComponent(this.deleteButton))).addContainerGap(-1, 32767))); + layout.setVerticalGroup(layout.createParallelGroup(Alignment.LEADING).addGroup(layout.createSequentialGroup().addContainerGap().addComponent(jScrollPane1, -2, 279, -2).addPreferredGap(ComponentPlacement.RELATED).addGroup(layout.createParallelGroup(Alignment.BASELINE).addComponent(this.editButton).addComponent(this.addButton)).addPreferredGap(ComponentPlacement.RELATED).addGroup(layout.createParallelGroup(Alignment.BASELINE).addComponent(this.duplicateButton).addComponent(this.deleteButton)).addContainerGap(-1, 32767))); + this.pack(); + this.addAllItems(); + } + + public static void main(String[] args) throws IOException { + STORE = new Store("cache/", false); + EventQueue.invokeLater(new Runnable() { + public void run() { + (new ItemSelection()).setVisible(true); + } + }); + } + + private void exitButtonActionPerformed(ActionEvent evt) { + this.dispose(); + } + + public int getNewItemID() { + try { + JFrame var3 = new JFrame(); + String parent1 = JOptionPane.showInputDialog(var3, "Enter new Item ID:"); + return Integer.parseInt(parent1.toString()); + } catch (Exception var31) { + JFrame parent = new JFrame(); + JOptionPane.showMessageDialog(parent, "Please enter a valid integer!"); + Main.log("ItemSelection", "Non-valid character entered for new Item ID"); + return -1; + } + } + + public void addAllItems() { + int id; + if(Utils.getItemDefinitionsSize(STORE) > 30000) { + for(id = 0; id < Utils.getItemDefinitionsSize(STORE) - 22314; ++id) { + this.addItemDefs(ItemDefinitions.getItemDefinition(STORE, id)); + } + } else { + for(id = 0; id < Utils.getItemDefinitionsSize(STORE); ++id) { + this.addItemDefs(ItemDefinitions.getItemDefinition(STORE, id)); + } + } + + Main.log("ItemSelection", "All Items Loaded"); + } + + public void addItemDefs(final ItemDefinitions defs) { + EventQueue.invokeLater(new Runnable() { + public void run() { + ItemSelection.this.itemsListmodel.addElement(defs); + } + }); + } + + public void updateItemDefs(final ItemDefinitions defs) { + EventQueue.invokeLater(new Runnable() { + public void run() { + int index = ItemSelection.this.itemsListmodel.indexOf(defs); + if(index == -1) { + ItemSelection.this.itemsListmodel.addElement(defs); + } else { + ItemSelection.this.itemsListmodel.setElementAt(defs, index); + } + + } + }); + } + + public void removeItemDefs(final ItemDefinitions defs) { + EventQueue.invokeLater(new Runnable() { + public void run() { + ItemSelection.this.itemsListmodel.removeElement(defs); + } + }); + } +} diff --git a/Tools/Frostys Cache Editor/src/com/editor/model/ModelDumper.java b/Tools/Frostys Cache Editor/src/com/editor/model/ModelDumper.java new file mode 100644 index 0000000..8232c05 --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/editor/model/ModelDumper.java @@ -0,0 +1,36 @@ +package com.editor.model; + +import com.alex.store.Index; +import com.alex.store.Store; + +import java.io.FileOutputStream; +import java.io.IOException; + +public class ModelDumper { + private static Store STORE; + + public static void main(String[] args) throws IOException { + try { + STORE = new Store("C:/Users/Travis/Documents/rscd/data/"); + } catch (Exception var4) { + ; + } + + Index index = STORE.getIndexes()[7]; + System.out.println(index.getLastArchiveId()); + + for(int i = 0; i < index.getLastArchiveId(); ++i) { + byte[] data = index.getFile(i); + if(data != null) { + writeFile(data, "C:/Users/Travis/Documents/781 Models/" + i + ".dat"); + } + } + + } + + public static void writeFile(byte[] data, String fileName) throws IOException { + FileOutputStream out = new FileOutputStream(fileName); + out.write(data); + out.close(); + } +} diff --git a/Tools/Frostys Cache Editor/src/com/editor/model/MultiModelPacker.java b/Tools/Frostys Cache Editor/src/com/editor/model/MultiModelPacker.java new file mode 100644 index 0000000..85eda8c --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/editor/model/MultiModelPacker.java @@ -0,0 +1,182 @@ +package com.editor.model; + +import com.alex.store.Store; +import com.editor.Main; +import com.editor.Utils; + +import javax.swing.GroupLayout.Alignment; +import javax.swing.LayoutStyle.ComponentPlacement; +import javax.swing.UIManager.LookAndFeelInfo; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class MultiModelPacker extends JFrame { + private static final long serialVersionUID = -1984870962939167633L; + private static Store STORE; + private JMenuItem exit; + private JLabel jLabel1; + private JLabel jLabel2; + private JMenu jMenu1; + private JMenuBar jMenuBar1; + private JMenuItem modelDir; + private JTextField modelDirField; + private JCheckBox sameId; + private JButton submit; + + public MultiModelPacker() { + this.initComponents(); + } + + public MultiModelPacker(String cache) { + try { + STORE = new Store(cache); + } catch (Exception var3) { + Main.log("MultiModelPacker", "Cannot find cache directory"); + } + + this.initComponents(); + this.setResizable(false); + this.setTitle("MultiModelPacker"); + this.setDefaultCloseOperation(1); + this.setLocationRelativeTo((Component)null); + this.setVisible(true); + } + + private void initComponents() { + this.jLabel1 = new JLabel(); + this.jLabel2 = new JLabel(); + this.modelDirField = new JTextField(); + this.sameId = new JCheckBox(); + this.submit = new JButton(); + this.jMenuBar1 = new JMenuBar(); + this.jMenu1 = new JMenu(); + this.modelDir = new JMenuItem(); + this.exit = new JMenuItem(); + this.setDefaultCloseOperation(3); + this.jLabel1.setText("Multiple Model Packer"); + this.jLabel2.setText("Models Directory"); + this.sameId.setText("Keep Same ID"); + this.sameId.setToolTipText("Keeps same ID as named"); + this.submit.setText("Submit"); + this.submit.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + MultiModelPacker.this.submitActionPerformed(evt); + } + }); + this.jMenu1.setText("File"); + this.modelDir.setText("Choose Model Dir"); + this.modelDir.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + MultiModelPacker.this.modelDirActionPerformed(evt); + } + }); + this.jMenu1.add(this.modelDir); + this.exit.setText("Exit"); + this.exit.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + MultiModelPacker.this.exitActionPerformed(evt); + } + }); + this.jMenu1.add(this.exit); + this.jMenuBar1.add(this.jMenu1); + this.setJMenuBar(this.jMenuBar1); + GroupLayout layout = new GroupLayout(this.getContentPane()); + this.getContentPane().setLayout(layout); + layout.setHorizontalGroup(layout.createParallelGroup(Alignment.LEADING).addGroup(layout.createSequentialGroup().addContainerGap().addComponent(this.modelDirField).addContainerGap()).addGroup(layout.createSequentialGroup().addGroup(layout.createParallelGroup(Alignment.LEADING).addGroup(layout.createSequentialGroup().addContainerGap().addGroup(layout.createParallelGroup(Alignment.LEADING).addGroup(layout.createSequentialGroup().addPreferredGap(ComponentPlacement.RELATED, 4, -2).addComponent(this.jLabel2)).addComponent(this.sameId))).addGroup(layout.createSequentialGroup().addGap(77, 77, 77).addComponent(this.jLabel1)).addGroup(layout.createSequentialGroup().addGap(101, 101, 101).addComponent(this.submit))).addGap(0, 76, 32767))); + layout.setVerticalGroup(layout.createParallelGroup(Alignment.LEADING).addGroup(layout.createSequentialGroup().addContainerGap().addComponent(this.jLabel1).addPreferredGap(ComponentPlacement.UNRELATED).addComponent(this.jLabel2).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.modelDirField, -2, -1, -2).addGap(18, 18, 18).addComponent(this.sameId).addPreferredGap(ComponentPlacement.UNRELATED).addComponent(this.submit).addContainerGap(20, 32767))); + this.pack(); + } + + private void submitActionPerformed(ActionEvent evt) { + String directory = this.modelDirField.getText(); + boolean keepID = this.sameId.isSelected(); + String fileName; + if(keepID) { + fileName = ""; + String var12 = ""; + File var13 = new File(directory); + File[] var14 = var13.listFiles(); + + for(int var10 = 0; var10 < var14.length; ++var10) { + if(var14[var10].isFile()) { + System.out.println(var14[var10]); + fileName = var14[var10].getName(); + var12 = var14[var10].getName().replace(".dat", ""); + + try { + Main.log("MultiModelPacker", "The model ID of " + fileName + " is: " + Utils.packCustomModel(STORE, Utils.getBytesFromFile(var14[var10]), Integer.parseInt(var12))); + } catch (IOException var11) { + Main.log("MultiModelPacker", "There was an error packing the model."); + } + } + } + } else { + fileName = ""; + File var121 = new File(directory); + File[] var131 = var121.listFiles(); + + for(int var141 = 0; var141 < var131.length; ++var141) { + if(var131[var141].isFile()) { + fileName = var131[var141].getName(); + + try { + Main.log("MultiModelPacker", "The model ID of " + fileName + " is: " + Utils.packCustomModel(STORE, Utils.getBytesFromFile(var131[var141]))); + } catch (IOException var101) { + Main.log("MultiModelPacker", "There was an error packing the model."); + } + } + } + } + + } + + private void modelDirActionPerformed(ActionEvent evt) { + JFileChooser fc = new JFileChooser(); + fc.setFileSelectionMode(1); + if(evt.getSource() == this.modelDir) { + int returnVal = fc.showOpenDialog(this); + if(returnVal == 0) { + File file = fc.getSelectedFile(); + this.modelDirField.setText(file.getPath() + "/"); + } + } + + } + + private void exitActionPerformed(ActionEvent evt) { + this.dispose(); + } + + public static void main(String[] args) { + try { + LookAndFeelInfo[] var8 = UIManager.getInstalledLookAndFeels(); + int len$ = var8.length; + + for(int i$ = 0; i$ < len$; ++i$) { + LookAndFeelInfo info = var8[i$]; + if("Nimbus".equals(info.getName())) { + UIManager.setLookAndFeel(info.getClassName()); + break; + } + } + } catch (ClassNotFoundException var5) { + Logger.getLogger(MultiModelPacker.class.getName()).log(Level.SEVERE, (String)null, var5); + } catch (InstantiationException var6) { + Logger.getLogger(MultiModelPacker.class.getName()).log(Level.SEVERE, (String)null, var6); + } catch (IllegalAccessException var7) { + Logger.getLogger(MultiModelPacker.class.getName()).log(Level.SEVERE, (String)null, var7); + } catch (UnsupportedLookAndFeelException var81) { + Logger.getLogger(MultiModelPacker.class.getName()).log(Level.SEVERE, (String)null, var81); + } + + EventQueue.invokeLater(new Runnable() { + public void run() { + (new MultiModelPacker()).setVisible(true); + } + }); + } +} diff --git a/Tools/Frostys Cache Editor/src/com/editor/model/UniModelDumper.java b/Tools/Frostys Cache Editor/src/com/editor/model/UniModelDumper.java new file mode 100644 index 0000000..ce4b96b --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/editor/model/UniModelDumper.java @@ -0,0 +1,133 @@ +package com.editor.model; + +import com.alex.store.Index; +import com.alex.store.Store; +import com.editor.Main; + +import javax.swing.GroupLayout.Alignment; +import javax.swing.LayoutStyle.ComponentPlacement; +import javax.swing.UIManager.LookAndFeelInfo; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class UniModelDumper extends JFrame { + private static final long serialVersionUID = 433437706015594462L; + private static Store STORE; + private JMenu exit; + private JLabel jLabel1; + private JMenuBar jMenuBar1; + private JMenuItem jMenuItem1; + private JTextField modelID; + private JButton submit; + + public UniModelDumper() { + this.initComponents(); + } + + public UniModelDumper(String cache) { + try { + STORE = new Store(cache); + } catch (Exception var3) { + Main.log("UniModelDumper", "Cannot find cache directory"); + } + + this.initComponents(); + this.setResizable(false); + this.setTitle("UniModelDumper"); + this.setDefaultCloseOperation(1); + this.setLocationRelativeTo((Component)null); + this.setVisible(true); + } + + private void initComponents() { + this.jLabel1 = new JLabel(); + this.modelID = new JTextField(); + this.submit = new JButton(); + this.jMenuBar1 = new JMenuBar(); + this.exit = new JMenu(); + this.jMenuItem1 = new JMenuItem(); + this.setDefaultCloseOperation(3); + this.jLabel1.setText("Model ID To Dump:"); + this.submit.setText("Submit"); + this.submit.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + UniModelDumper.this.submitActionPerformed(evt); + } + }); + this.exit.setText("File"); + this.exit.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + UniModelDumper.this.exitActionPerformed(evt); + } + }); + this.jMenuItem1.setText("Exit"); + this.exit.add(this.jMenuItem1); + this.jMenuBar1.add(this.exit); + this.setJMenuBar(this.jMenuBar1); + GroupLayout layout = new GroupLayout(this.getContentPane()); + this.getContentPane().setLayout(layout); + layout.setHorizontalGroup(layout.createParallelGroup(Alignment.LEADING).addGroup(layout.createSequentialGroup().addGroup(layout.createParallelGroup(Alignment.LEADING).addGroup(layout.createSequentialGroup().addContainerGap().addGroup(layout.createParallelGroup(Alignment.LEADING).addGroup(layout.createSequentialGroup().addGap(10, 10, 10).addComponent(this.modelID, -2, 100, -2)).addComponent(this.jLabel1))).addGroup(layout.createSequentialGroup().addGap(32, 32, 32).addComponent(this.submit))).addContainerGap(22, 32767))); + layout.setVerticalGroup(layout.createParallelGroup(Alignment.LEADING).addGroup(layout.createSequentialGroup().addContainerGap().addComponent(this.jLabel1).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.modelID, -2, -1, -2).addGap(33, 33, 33).addComponent(this.submit).addContainerGap(20, 32767))); + this.pack(); + } + + private void exitActionPerformed(ActionEvent evt) { + this.dispose(); + } + + private void submitActionPerformed(ActionEvent evt) { + File f = new File(System.getProperty("user.home") + "/FCE/models/"); + f.mkdirs(); + Index index = STORE.getIndexes()[7]; + int modelId = Integer.parseInt(this.modelID.getText()); + + try { + byte[] var6 = index.getFile(modelId); + writeFile(var6, System.getProperty("user.home") + "/FCE/models/" + modelId + ".dat"); + Main.log("UniModelDumper", "Dumped Model ID: " + modelId + " to: " + System.getProperty("user.home") + "/FCE/models/" + modelId + ".dat"); + } catch (IOException var61) { + Main.log("UniModelDumper", "Cannot Dump Model"); + } + + } + + public static void writeFile(byte[] data, String fileName) throws IOException { + FileOutputStream out = new FileOutputStream(fileName); + out.write(data); + out.close(); + } + + public static void main(String[] args) { + try { + LookAndFeelInfo[] var8 = UIManager.getInstalledLookAndFeels(); + int len$ = var8.length; + + for(int i$ = 0; i$ < len$; ++i$) { + LookAndFeelInfo info = var8[i$]; + if("Nimbus".equals(info.getName())) { + UIManager.setLookAndFeel(info.getClassName()); + break; + } + } + } catch (ClassNotFoundException var5) { + Logger.getLogger(UniModelDumper.class.getName()).log(Level.SEVERE, (String)null, var5); + } catch (InstantiationException var6) { + Logger.getLogger(UniModelDumper.class.getName()).log(Level.SEVERE, (String)null, var6); + } catch (IllegalAccessException var7) { + Logger.getLogger(UniModelDumper.class.getName()).log(Level.SEVERE, (String)null, var7); + } catch (UnsupportedLookAndFeelException var81) { + Logger.getLogger(UniModelDumper.class.getName()).log(Level.SEVERE, (String)null, var81); + } + + EventQueue.invokeLater(new Runnable() { + public void run() { + (new UniModelDumper()).setVisible(true); + } + }); + } +} diff --git a/Tools/Frostys Cache Editor/src/com/editor/npc/NPCDefDump.java b/Tools/Frostys Cache Editor/src/com/editor/npc/NPCDefDump.java new file mode 100644 index 0000000..7e868a7 --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/editor/npc/NPCDefDump.java @@ -0,0 +1,361 @@ +package com.editor.npc; + +import com.alex.loaders.npcs.NPCDefinitions; +import com.alex.store.Store; +import com.alex.utils.Utils; +import com.editor.Main; + +import java.util.Iterator; + +public class NPCDefDump { + private static NPCDefinitions defs; + private static Store STORE; + + public static void main(String[] args) { + try { + STORE = new Store("C:/Users/Travis/Documents/rscd/data/"); + } catch (IOException var2) { + System.out.println("Cannot find cache location"); + } + + int id; + if(Utils.getNPCDefinitionsSize(STORE) > 30000) { + for(id = 0; id < Utils.getNPCDefinitionsSize(STORE) - 18433; ++id) { + defs = NPCDefinitions.getNPCDefinition(STORE, id); + dump(); + Main.log("NPCDefDump", "Dumping NPC " + defs.id); + } + } else { + for(id = 0; id < Utils.getNPCDefinitionsSize(STORE); ++id) { + defs = NPCDefinitions.getNPCDefinition(STORE, id); + dump(); + Main.log("NPCDefDump", "Dumping NPC " + defs.id); + } + } + + } + + public static void editorDump(String cache) { + try { + STORE = new Store(cache); + } catch (IOException var2) { + Main.log("NPCDefDump", "Cannot find cache location"); + } + + int id; + if(Utils.getNPCDefinitionsSize(STORE) > 30000) { + for(id = 0; id < Utils.getNPCDefinitionsSize(STORE) - 15615; ++id) { + defs = NPCDefinitions.getNPCDefinition(STORE, id); + dump(); + Main.log("NPCDefDump", "Dumping NPC " + defs.id); + } + } else { + for(id = 0; id < Utils.getNPCDefinitionsSize(STORE); ++id) { + defs = NPCDefinitions.getNPCDefinition(STORE, id); + dump(); + Main.log("NPCDefDump", "Dumping NPC " + defs.id); + } + } + + } + + private static void dump() { + File f = new File(System.getProperty("user.home") + "/FCE/npcs/"); + f.mkdirs(); + String lineSep = System.getProperty("line.separator"); + BufferedWriter writer = null; + + try { + writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(System.getProperty("user.home") + "/FCE/npcs/" + defs.id + ".txt"), "utf-8")); + writer.write("name = " + defs.getName()); + writer.write(lineSep); + writer.write("combat level = " + defs.getCombatLevel()); + writer.write(lineSep); + writer.write("isVisibleOnMap = " + defs.isVisibleOnMap); + writer.write(lineSep); + writer.write("height = " + defs.npcHeight); + writer.write(lineSep); + writer.write("width = " + defs.npcWidth); + writer.write(lineSep); + writer.write("walk mask = " + defs.walkMask); + writer.write(lineSep); + writer.write("respawn direction = " + defs.respawnDirection); + writer.write(lineSep); + writer.write("render emote = " + defs.renderEmote); + writer.write(lineSep); + writer.write("model ids = " + getModelIds()); + writer.write(lineSep); + writer.write("chat head model ids = " + getChatHeads()); + writer.write(lineSep); + writer.write("options = " + getOpts()); + writer.write(lineSep); + writer.write("model colors = " + getChangedModelColors()); + writer.write(lineSep); + writer.write("texture colors = " + getChangedTextureColors()); + writer.write(lineSep); + writer.write("unknown array1 = " + getUnknownArray1()); + writer.write(lineSep); + writer.write("unknown array2 = " + getUnknownArray2()); + writer.write(lineSep); + writer.write("unknown array3 = " + getUnknownArray3()); + writer.write(lineSep); + writer.write("unknown array4 = " + getUnknownArray4()); + writer.write(lineSep); + writer.write("unknown array5 = " + getUnknownArray5()); + writer.write(lineSep); + writer.write("unknownBoolean1 = " + defs.unknownBoolean1); + writer.write(lineSep); + writer.write("unknwonBoolean2 = " + defs.unknownBoolean2); + writer.write(lineSep); + writer.write("unknownBoolean3 = " + defs.unknownBoolean3); + writer.write(lineSep); + writer.write("unknownBoolean4 = " + defs.unknownBoolean5); + writer.write(lineSep); + writer.write("unknownBoolean5 = " + defs.unknownBoolean4); + writer.write(lineSep); + writer.write("unknownBoolean6 = " + defs.unknownBoolean6); + writer.write(lineSep); + writer.write("unknownBoolean7 = " + defs.unknownBoolean7); + writer.write(lineSep); + writer.write("unknown int1 = " + defs.unknownInt1); + writer.write(lineSep); + writer.write("unknown int2 = " + defs.unknownInt2); + writer.write(lineSep); + writer.write("unknown int3 = " + defs.unknownInt3); + writer.write(lineSep); + writer.write("unknown int4 = " + defs.unknownInt4); + writer.write(lineSep); + writer.write("unknown int5 = " + defs.unknownInt5); + writer.write(lineSep); + writer.write("unknown int6 = " + defs.unknownInt6); + writer.write(lineSep); + writer.write("unknown int7 = " + defs.unknownInt7); + writer.write(lineSep); + writer.write("unknown int8 = " + defs.unknownInt8); + writer.write(lineSep); + writer.write("unknown int9 = " + defs.unknownInt9); + writer.write(lineSep); + writer.write("unknown int10 = " + defs.unknownInt10); + writer.write(lineSep); + writer.write("unknown int11 = " + defs.unknownInt11); + writer.write(lineSep); + writer.write("unknown int12 = " + defs.unknownInt12); + writer.write(lineSep); + writer.write("unknown int13 = " + defs.unknownInt13); + writer.write(lineSep); + writer.write("unknown int14 = " + defs.unknownInt14); + writer.write(lineSep); + writer.write("unknown int15 = " + defs.unknownInt15); + writer.write(lineSep); + writer.write("unknown int16 = " + defs.unknownInt16); + writer.write(lineSep); + writer.write("unknown int17 = " + defs.unknownInt17); + writer.write(lineSep); + writer.write("unknown int18 = " + defs.unknownInt18); + writer.write(lineSep); + writer.write("unknown int19 = " + defs.unknownInt19); + writer.write(lineSep); + writer.write("unknown int20 = " + defs.unknownInt20); + writer.write(lineSep); + writer.write("unknown int21 = " + defs.unknownInt21); + writer.write(lineSep); + writer.write("Clientscripts"); + writer.write(lineSep); + if(defs.clientScriptData != null) { + Iterator var14 = defs.clientScriptData.keySet().iterator(); + + while(var14.hasNext()) { + int key = ((Integer)var14.next()).intValue(); + Object value = defs.clientScriptData.get(Integer.valueOf(key)); + writer.write("KEY: " + key + ", VALUE: " + value); + writer.write(lineSep); + } + } + } catch (IOException var141) { + Main.log("NPCDefDump", "Failed to export NPC Defs to .txt"); + } finally { + try { + writer.close(); + } catch (Exception var13) { + ; + } + + } + + } + + public static String getClientScripts() { + String text = ""; + String lineSep = System.getProperty("line.separator"); + if(defs.clientScriptData != null) { + for(Iterator i$ = defs.clientScriptData.keySet().iterator(); i$.hasNext(); text = text + lineSep) { + int key = ((Integer)i$.next()).intValue(); + Object value = defs.clientScriptData.get(Integer.valueOf(key)); + text = text + "KEY: " + key + ", VALUE: " + value; + } + } + + return text; + } + + public static String getModelIds() { + String text = ""; + + try { + int[] e = defs.modelIds; + int len$ = e.length; + + for(int i$ = 0; i$ < len$; ++i$) { + int index = e[i$]; + text = text + index + ";"; + } + } catch (Exception var5) { + ; + } + + return text; + } + + public static String getOpts() { + String text = ""; + String[] arr$ = defs.getOptions(); + int len$ = arr$.length; + + for(int i$ = 0; i$ < len$; ++i$) { + String option = arr$[i$]; + text = text + (option == null?"null":option) + ";"; + } + + return text; + } + + public static String getChangedModelColors() { + String text = ""; + if(defs.originalModelColors != null) { + for(int i = 0; i < defs.originalModelColors.length; ++i) { + text = text + defs.originalModelColors[i] + "=" + defs.modifiedModelColors[i] + ";"; + } + } + + return text; + } + + public static String getChangedTextureColors() { + String text = ""; + if(defs.originalTextureColors != null) { + for(int i = 0; i < defs.originalTextureColors.length; ++i) { + text = text + defs.originalTextureColors[i] + "=" + defs.modifiedTextureColors[i] + ";"; + } + } + + return text; + } + + public static String getChatHeads() { + String text = ""; + + try { + int[] e = defs.npcChatHeads; + int len$ = e.length; + + for(int i$ = 0; i$ < len$; ++i$) { + int id = e[i$]; + text = text + id + ";"; + } + } catch (Exception var5) { + ; + } + + return text; + } + + public static String getUnknownArray1() { + String text = ""; + + try { + byte[] e = defs.unknownArray1; + int len$ = e.length; + + for(int i$ = 0; i$ < len$; ++i$) { + byte index = e[i$]; + text = text + index + ";"; + } + } catch (Exception var5) { + ; + } + + return text; + } + + public static String getUnknownArray2() { + String text = ""; + + try { + int[] e = defs.unknownArray2; + int len$ = e.length; + + for(int i$ = 0; i$ < len$; ++i$) { + int index = e[i$]; + text = text + index + ";"; + } + } catch (Exception var5) { + ; + } + + return text; + } + + public static String getUnknownArray3() { + String text = ""; + + try { + int[] e = defs.unknownArray3[0]; + int len$ = e.length; + + for(int i$ = 0; i$ < len$; ++i$) { + int index = e[i$]; + text = text + index + ";"; + } + } catch (Exception var5) { + ; + } + + return text; + } + + public static String getUnknownArray4() { + String text = ""; + + try { + int[] e = defs.unknownArray4; + int len$ = e.length; + + for(int i$ = 0; i$ < len$; ++i$) { + int index = e[i$]; + text = text + index + ";"; + } + } catch (Exception var5) { + ; + } + + return text; + } + + public static String getUnknownArray5() { + String text = ""; + + try { + int[] e = defs.unknownArray5; + int len$ = e.length; + + for(int i$ = 0; i$ < len$; ++i$) { + int index = e[i$]; + text = text + index + ";"; + } + } catch (Exception var5) { + ; + } + + return text; + } +} diff --git a/Tools/Frostys Cache Editor/src/com/editor/npc/NPCEditor.java b/Tools/Frostys Cache Editor/src/com/editor/npc/NPCEditor.java new file mode 100644 index 0000000..e5b443c --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/editor/npc/NPCEditor.java @@ -0,0 +1,1138 @@ +package com.editor.npc; + +import com.alex.loaders.npcs.NPCDefinitions; +import com.editor.Main; +import com.editor.Utils; +import com.editor.npc.NPCSelection; + +import javax.swing.GroupLayout.Alignment; +import javax.swing.LayoutStyle.ComponentPlacement; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.HashMap; +import java.util.Iterator; + +public class NPCEditor extends JFrame { + private static final long serialVersionUID = -8143046599523114860L; + private NPCDefinitions defs; + private NPCSelection ns; + private JMenuItem addModelButton; + private JTextArea clientScriptOutput; + private JTextField combatLevel; + private JTextField csk1; + private JTextField csk2; + private JTextField csk3; + private JTextField csk4; + private JTextField csk5; + private JTextField csk6; + private JTextField csv1; + private JTextField csv2; + private JTextField csv3; + private JTextField csv4; + private JTextField csv5; + private JTextField csv6; + private JMenuItem exitButton; + private JMenuItem exportButton; + private JLabel jLabel1; + private JLabel jLabel10; + private JLabel jLabel11; + private JLabel jLabel12; + private JLabel jLabel13; + private JLabel jLabel14; + private JLabel jLabel15; + private JLabel jLabel16; + private JLabel jLabel17; + private JLabel jLabel18; + private JLabel jLabel19; + private JLabel jLabel2; + private JLabel jLabel20; + private JLabel jLabel21; + private JLabel jLabel22; + private JLabel jLabel23; + private JLabel jLabel24; + private JLabel jLabel25; + private JLabel jLabel26; + private JLabel jLabel27; + private JLabel jLabel28; + private JLabel jLabel29; + private JLabel jLabel3; + private JLabel jLabel30; + private JLabel jLabel31; + private JLabel jLabel32; + private JLabel jLabel33; + private JLabel jLabel34; + private JLabel jLabel35; + private JLabel jLabel36; + private JLabel jLabel37; + private JLabel jLabel38; + private JLabel jLabel39; + private JLabel jLabel4; + private JLabel jLabel40; + private JLabel jLabel41; + private JLabel jLabel42; + private JLabel jLabel43; + private JLabel jLabel44; + private JLabel jLabel5; + private JLabel jLabel6; + private JLabel jLabel7; + private JLabel jLabel8; + private JLabel jLabel9; + private JMenu jMenu1; + private JMenuBar jMenuBar1; + private JPanel jPanel1; + private JPanel jPanel2; + private JPanel jPanel3; + private JPanel jPanel4; + private JPanel jPanel5; + private JScrollPane jScrollPane1; + private JTabbedPane jTabbedPane1; + private JTextField jTextField2; + private JTextField modelColorField; + private JTextField modelIds; + private JTextField name; + private JTextField npcHeight; + private JTextField npcSize; + private JTextField npcWidth; + private JTextField optionsField; + private JMenuItem reloadButton; + private JTextField renderEmote; + private JTextField respawnDirection; + private JMenuItem saveButton; + private JTextField textureColorField; + private JTextField unknownArray1; + private JTextField unknownArray2; + private JTextField unknownArray3; + private JTextField unknownArray4; + private JTextField unknownArray5; + private JCheckBox unknownBoolean1; + private JCheckBox unknownBoolean2; + private JCheckBox unknownBoolean3; + private JCheckBox unknownBoolean4; + private JCheckBox unknownBoolean5; + private JCheckBox unknownBoolean6; + private JCheckBox unknownBoolean7; + private JTextField unknownInt1; + private JTextField unknownInt10; + private JTextField unknownInt11; + private JTextField unknownInt12; + private JTextField unknownInt13; + private JTextField unknownInt14; + private JTextField unknownInt15; + private JTextField unknownInt16; + private JTextField unknownInt17; + private JTextField unknownInt18; + private JTextField unknownInt19; + private JTextField unknownInt2; + private JTextField unknownInt20; + private JTextField unknownInt21; + private JTextField unknownInt3; + private JTextField unknownInt4; + private JTextField unknownInt5; + private JTextField unknownInt6; + private JTextField unknownInt7; + private JTextField unknownInt8; + private JTextField unknownInt9; + private JCheckBox visibleOnMap; + private JTextField walkMask; + + public NPCEditor(NPCSelection ns, NPCDefinitions defs) { + this.defs = defs; + this.ns = ns; + this.initComponents(); + this.setResizable(false); + this.setTitle("NPC Editor"); + this.setDefaultCloseOperation(1); + this.setLocationRelativeTo((Component)null); + this.setVisible(true); + } + + public NPCEditor() { + this.initComponents(); + } + + private void initComponents() { + this.jTabbedPane1 = new JTabbedPane(); + this.jPanel1 = new JPanel(); + this.jLabel1 = new JLabel(); + this.name = new JTextField(); + this.jLabel4 = new JLabel(); + this.combatLevel = new JTextField(); + this.jLabel5 = new JLabel(); + this.npcSize = new JTextField(); + this.visibleOnMap = new JCheckBox(); + this.jLabel10 = new JLabel(); + this.npcHeight = new JTextField(); + this.jLabel11 = new JLabel(); + this.npcWidth = new JTextField(); + this.jLabel12 = new JLabel(); + this.walkMask = new JTextField(); + this.jLabel13 = new JLabel(); + this.respawnDirection = new JTextField(); + this.jLabel14 = new JLabel(); + this.renderEmote = new JTextField(); + this.jPanel2 = new JPanel(); + this.jLabel3 = new JLabel(); + this.modelIds = new JTextField(); + this.jLabel6 = new JLabel(); + this.jTextField2 = new JTextField(); + this.jPanel3 = new JPanel(); + this.jLabel7 = new JLabel(); + this.optionsField = new JTextField(); + this.jLabel8 = new JLabel(); + this.modelColorField = new JTextField(); + this.jLabel9 = new JLabel(); + this.textureColorField = new JTextField(); + this.jPanel4 = new JPanel(); + this.jLabel15 = new JLabel(); + this.unknownArray1 = new JTextField(); + this.jLabel16 = new JLabel(); + this.unknownArray2 = new JTextField(); + this.jLabel17 = new JLabel(); + this.unknownArray3 = new JTextField(); + this.jLabel18 = new JLabel(); + this.unknownArray4 = new JTextField(); + this.jLabel19 = new JLabel(); + this.unknownArray5 = new JTextField(); + this.unknownBoolean1 = new JCheckBox(); + this.unknownBoolean2 = new JCheckBox(); + this.unknownBoolean3 = new JCheckBox(); + this.unknownBoolean5 = new JCheckBox(); + this.unknownBoolean4 = new JCheckBox(); + this.unknownBoolean6 = new JCheckBox(); + this.unknownBoolean7 = new JCheckBox(); + this.jLabel20 = new JLabel(); + this.unknownInt1 = new JTextField(); + this.jLabel21 = new JLabel(); + this.unknownInt2 = new JTextField(); + this.jLabel22 = new JLabel(); + this.unknownInt3 = new JTextField(); + this.jLabel23 = new JLabel(); + this.unknownInt4 = new JTextField(); + this.jLabel24 = new JLabel(); + this.unknownInt5 = new JTextField(); + this.jLabel25 = new JLabel(); + this.unknownInt6 = new JTextField(); + this.jLabel26 = new JLabel(); + this.unknownInt7 = new JTextField(); + this.jLabel27 = new JLabel(); + this.unknownInt8 = new JTextField(); + this.jLabel28 = new JLabel(); + this.unknownInt9 = new JTextField(); + this.jLabel29 = new JLabel(); + this.unknownInt10 = new JTextField(); + this.jLabel30 = new JLabel(); + this.unknownInt11 = new JTextField(); + this.jLabel31 = new JLabel(); + this.unknownInt12 = new JTextField(); + this.jLabel32 = new JLabel(); + this.unknownInt13 = new JTextField(); + this.jLabel33 = new JLabel(); + this.unknownInt14 = new JTextField(); + this.jLabel34 = new JLabel(); + this.unknownInt15 = new JTextField(); + this.jLabel35 = new JLabel(); + this.unknownInt16 = new JTextField(); + this.jLabel36 = new JLabel(); + this.unknownInt17 = new JTextField(); + this.jLabel37 = new JLabel(); + this.unknownInt18 = new JTextField(); + this.jLabel38 = new JLabel(); + this.unknownInt19 = new JTextField(); + this.jLabel39 = new JLabel(); + this.unknownInt20 = new JTextField(); + this.jLabel40 = new JLabel(); + this.unknownInt21 = new JTextField(); + this.jPanel5 = new JPanel(); + this.jScrollPane1 = new JScrollPane(); + this.clientScriptOutput = new JTextArea(); + this.jLabel41 = new JLabel(); + this.jLabel42 = new JLabel(); + this.csk1 = new JTextField(); + this.csk2 = new JTextField(); + this.csk3 = new JTextField(); + this.csk4 = new JTextField(); + this.csk5 = new JTextField(); + this.csk6 = new JTextField(); + this.csv1 = new JTextField(); + this.csv2 = new JTextField(); + this.csv3 = new JTextField(); + this.csv4 = new JTextField(); + this.csv5 = new JTextField(); + this.csv6 = new JTextField(); + this.jLabel43 = new JLabel(); + this.jLabel44 = new JLabel(); + this.jLabel2 = new JLabel(); + this.jMenuBar1 = new JMenuBar(); + this.jMenu1 = new JMenu(); + this.reloadButton = new JMenuItem(); + this.saveButton = new JMenuItem(); + this.addModelButton = new JMenuItem(); + this.exportButton = new JMenuItem(); + this.exitButton = new JMenuItem(); + this.setDefaultCloseOperation(3); + this.jLabel1.setText("Name"); + this.name.setText(this.defs.getName()); + this.jLabel4.setText("Combat Level"); + this.combatLevel.setText("" + this.defs.getCombatLevel()); + this.jLabel5.setText("NPC Size"); + this.npcSize.setText("" + this.defs.getSize()); + this.visibleOnMap.setSelected(this.defs.isVisibleOnMap); + this.visibleOnMap.setText("Visible On Map"); + this.jLabel10.setText("NPC Height"); + this.npcHeight.setText("" + this.defs.npcHeight); + this.jLabel11.setText("NPC Width"); + this.npcWidth.setText("" + this.defs.npcWidth); + this.jLabel12.setText("Walk Mask"); + this.walkMask.setText("" + this.defs.walkMask); + this.jLabel13.setText("Respawn Direction"); + this.respawnDirection.setText("" + this.defs.respawnDirection); + this.jLabel14.setText("Render Animation"); + this.renderEmote.setText("" + this.defs.renderEmote); + GroupLayout jPanel1Layout = new GroupLayout(this.jPanel1); + this.jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup(jPanel1Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel1Layout.createSequentialGroup().addContainerGap().addGroup(jPanel1Layout.createParallelGroup(Alignment.LEADING).addComponent(this.visibleOnMap).addGroup(jPanel1Layout.createParallelGroup(Alignment.TRAILING, false).addGroup(Alignment.LEADING, jPanel1Layout.createSequentialGroup().addComponent(this.jLabel1).addPreferredGap(ComponentPlacement.RELATED, -1, 32767).addComponent(this.name, -2, 100, -2)).addGroup(Alignment.LEADING, jPanel1Layout.createSequentialGroup().addGroup(jPanel1Layout.createParallelGroup(Alignment.LEADING).addComponent(this.jLabel4).addComponent(this.jLabel5)).addGap(18, 18, 18).addGroup(jPanel1Layout.createParallelGroup(Alignment.LEADING).addComponent(this.npcSize, -2, 100, -2).addComponent(this.combatLevel, -2, 100, -2))).addGroup(jPanel1Layout.createSequentialGroup().addGroup(jPanel1Layout.createParallelGroup(Alignment.LEADING).addComponent(this.jLabel10).addComponent(this.jLabel11).addComponent(this.jLabel12)).addPreferredGap(ComponentPlacement.RELATED, -1, 32767).addGroup(jPanel1Layout.createParallelGroup(Alignment.LEADING, false).addComponent(this.npcHeight, -1, 100, 32767).addComponent(this.npcWidth).addComponent(this.walkMask)))).addGroup(jPanel1Layout.createSequentialGroup().addGroup(jPanel1Layout.createParallelGroup(Alignment.LEADING).addComponent(this.jLabel13).addComponent(this.jLabel14)).addPreferredGap(ComponentPlacement.UNRELATED).addGroup(jPanel1Layout.createParallelGroup(Alignment.LEADING, false).addComponent(this.respawnDirection, -1, 100, 32767).addComponent(this.renderEmote)))).addContainerGap(455, 32767))); + jPanel1Layout.setVerticalGroup(jPanel1Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel1Layout.createSequentialGroup().addContainerGap().addGroup(jPanel1Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel1).addComponent(this.name, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel1Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel4).addComponent(this.combatLevel, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel1Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel5).addComponent(this.npcSize, -2, 20, -2)).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.visibleOnMap).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel1Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel10).addComponent(this.npcHeight, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel1Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel11).addComponent(this.npcWidth, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel1Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel12).addComponent(this.walkMask, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel1Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel13).addComponent(this.respawnDirection, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel1Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel14).addComponent(this.renderEmote, -2, -1, -2)).addContainerGap(134, 32767))); + this.jTabbedPane1.addTab("General", this.jPanel1); + this.jLabel3.setText("Model IDs"); + this.modelIds.setText(this.getModelIds()); + this.jLabel6.setText("Chat Heads"); + this.jTextField2.setText(this.getChatHeads()); + GroupLayout jPanel2Layout = new GroupLayout(this.jPanel2); + this.jPanel2.setLayout(jPanel2Layout); + jPanel2Layout.setHorizontalGroup(jPanel2Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel2Layout.createSequentialGroup().addContainerGap().addGroup(jPanel2Layout.createParallelGroup(Alignment.LEADING, false).addComponent(this.jLabel3).addComponent(this.modelIds, -1, 275, 32767).addComponent(this.jLabel6).addComponent(this.jTextField2)).addContainerGap(379, 32767))); + jPanel2Layout.setVerticalGroup(jPanel2Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel2Layout.createSequentialGroup().addContainerGap().addComponent(this.jLabel3).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.modelIds, -2, -1, -2).addGap(18, 18, 18).addComponent(this.jLabel6).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.jTextField2, -2, -1, -2).addContainerGap(259, 32767))); + this.jTabbedPane1.addTab("Model", this.jPanel2); + this.jLabel7.setText("Options"); + this.optionsField.setText(this.getOpts()); + this.jLabel8.setText("Model Colors"); + this.modelColorField.setText(this.getChangedModelColors()); + this.jLabel9.setText("Texture Colors"); + this.textureColorField.setText(this.getChangedTextureColors()); + GroupLayout jPanel3Layout = new GroupLayout(this.jPanel3); + this.jPanel3.setLayout(jPanel3Layout); + jPanel3Layout.setHorizontalGroup(jPanel3Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel3Layout.createSequentialGroup().addContainerGap().addGroup(jPanel3Layout.createParallelGroup(Alignment.LEADING, false).addComponent(this.jLabel7).addComponent(this.optionsField, -1, 275, 32767).addComponent(this.jLabel8).addComponent(this.modelColorField).addComponent(this.jLabel9).addComponent(this.textureColorField)).addContainerGap(379, 32767))); + jPanel3Layout.setVerticalGroup(jPanel3Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel3Layout.createSequentialGroup().addContainerGap().addComponent(this.jLabel7).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.optionsField, -2, -1, -2).addGap(18, 18, 18).addComponent(this.jLabel8).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.modelColorField, -2, -1, -2).addGap(18, 18, 18).addComponent(this.jLabel9).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.textureColorField, -2, -1, -2).addContainerGap(201, 32767))); + this.jTabbedPane1.addTab("Options", this.jPanel3); + this.jLabel15.setText("unknownArray1"); + this.unknownArray1.setText(this.getUnknownArray1()); + this.jLabel16.setText("unknownArray2"); + this.unknownArray2.setText(this.getUnknownArray2()); + this.jLabel17.setText("unknownArray3"); + this.unknownArray3.setText(this.getUnknownArray3()); + this.jLabel18.setText("unknownArray4"); + this.unknownArray4.setText(this.getUnknownArray4()); + this.jLabel19.setText("unknownArray5"); + this.unknownArray5.setText(this.getUnknownArray5()); + this.unknownBoolean1.setSelected(this.defs.unknownBoolean1); + this.unknownBoolean1.setText("unknownBoolean1"); + this.unknownBoolean2.setSelected(this.defs.unknownBoolean2); + this.unknownBoolean2.setText("unknownBoolean2"); + this.unknownBoolean3.setSelected(this.defs.unknownBoolean3); + this.unknownBoolean3.setText("unknownBoolean3"); + this.unknownBoolean5.setSelected(this.defs.unknownBoolean5); + this.unknownBoolean5.setText("unknownBoolean5"); + this.unknownBoolean4.setSelected(this.defs.unknownBoolean4); + this.unknownBoolean4.setText("unknownBoolean4"); + this.unknownBoolean6.setSelected(this.defs.unknownBoolean6); + this.unknownBoolean6.setText("unknownBoolean6"); + this.unknownBoolean7.setSelected(this.defs.unknownBoolean7); + this.unknownBoolean7.setText("unknownBoolean7"); + this.jLabel20.setText("unknownInt1"); + this.unknownInt1.setText("" + this.defs.unknownInt1); + this.jLabel21.setText("unknownInt2"); + this.unknownInt2.setText("" + this.defs.unknownInt2); + this.jLabel22.setText("unknownInt3"); + this.unknownInt3.setText("" + this.defs.unknownInt3); + this.jLabel23.setText("unknownInt4"); + this.unknownInt4.setText("" + this.defs.unknownInt4); + this.jLabel24.setText("unknownInt5"); + this.unknownInt5.setText("" + this.defs.unknownInt5); + this.jLabel25.setText("unknownInt6"); + this.unknownInt6.setText("" + this.defs.unknownInt6); + this.jLabel26.setText("unknownInt7"); + this.unknownInt7.setText("" + this.defs.unknownInt7); + this.jLabel27.setText("unknownInt8"); + this.unknownInt8.setText("" + this.defs.unknownInt8); + this.jLabel28.setText("unknownInt9"); + this.unknownInt9.setText("" + this.defs.unknownInt9); + this.jLabel29.setText("unknownInt10"); + this.unknownInt10.setText("" + this.defs.unknownInt10); + this.jLabel30.setText("unknownInt11"); + this.unknownInt11.setText("" + this.defs.unknownInt11); + this.jLabel31.setText("unknownInt12"); + this.unknownInt12.setText("" + this.defs.unknownInt12); + this.jLabel32.setText("unknownInt13"); + this.unknownInt13.setText("" + this.defs.unknownInt13); + this.jLabel33.setText("unknownInt14"); + this.unknownInt14.setText("" + this.defs.unknownInt14); + this.jLabel34.setText("unknownInt15"); + this.unknownInt15.setText("" + this.defs.unknownInt15); + this.jLabel35.setText("unknownInt16"); + this.unknownInt16.setText("" + this.defs.unknownInt16); + this.jLabel36.setText("unknownInt17"); + this.unknownInt17.setText("" + this.defs.unknownInt17); + this.jLabel37.setText("unknownInt18"); + this.unknownInt18.setText("" + this.defs.unknownInt18); + this.jLabel38.setText("unknownInt19"); + this.unknownInt19.setText("" + this.defs.unknownInt19); + this.jLabel39.setText("unknownInt20"); + this.unknownInt20.setText("" + this.defs.unknownInt20); + this.jLabel40.setText("unknownInt21"); + this.unknownInt21.setText("" + this.defs.unknownInt21); + GroupLayout jPanel4Layout = new GroupLayout(this.jPanel4); + this.jPanel4.setLayout(jPanel4Layout); + jPanel4Layout.setHorizontalGroup(jPanel4Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel4Layout.createSequentialGroup().addContainerGap().addGroup(jPanel4Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel4Layout.createSequentialGroup().addGroup(jPanel4Layout.createParallelGroup(Alignment.LEADING).addComponent(this.unknownArray2, -2, 175, -2).addComponent(this.jLabel15).addComponent(this.unknownArray1, -2, 175, -2).addComponent(this.jLabel16).addComponent(this.jLabel17)).addGap(18, 18, 18).addGroup(jPanel4Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel4Layout.createSequentialGroup().addComponent(this.jLabel20).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.unknownInt1, -2, 100, -2).addPreferredGap(ComponentPlacement.RELATED, 33, 32767).addComponent(this.jLabel32).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.unknownInt13, -2, 100, -2)).addGroup(jPanel4Layout.createSequentialGroup().addComponent(this.jLabel21).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.unknownInt2, -2, 100, -2).addPreferredGap(ComponentPlacement.RELATED, -1, 32767).addComponent(this.jLabel33).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.unknownInt14, -2, 100, -2)).addGroup(Alignment.TRAILING, jPanel4Layout.createSequentialGroup().addGroup(jPanel4Layout.createParallelGroup(Alignment.LEADING).addComponent(this.unknownBoolean5).addComponent(this.unknownBoolean6).addComponent(this.unknownBoolean7)).addPreferredGap(ComponentPlacement.RELATED, -1, 32767).addGroup(jPanel4Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel4Layout.createSequentialGroup().addComponent(this.jLabel31).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.unknownInt12, -2, 100, -2)).addGroup(jPanel4Layout.createSequentialGroup().addComponent(this.jLabel30).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.unknownInt11, -2, 100, -2)).addGroup(jPanel4Layout.createSequentialGroup().addComponent(this.jLabel29).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.unknownInt10, -2, 100, -2)))))).addGroup(jPanel4Layout.createSequentialGroup().addGroup(jPanel4Layout.createParallelGroup(Alignment.LEADING).addComponent(this.unknownArray3, -2, 175, -2).addComponent(this.jLabel18)).addGap(18, 18, 18).addGroup(jPanel4Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel4Layout.createSequentialGroup().addComponent(this.jLabel23).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.unknownInt4, -2, 100, -2).addPreferredGap(ComponentPlacement.RELATED, -1, 32767).addComponent(this.jLabel35).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.unknownInt16, -2, 100, -2)).addGroup(jPanel4Layout.createSequentialGroup().addComponent(this.jLabel22).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.unknownInt3, -2, 100, -2).addPreferredGap(ComponentPlacement.RELATED, -1, 32767).addComponent(this.jLabel34).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.unknownInt15, -2, 100, -2)))).addGroup(jPanel4Layout.createSequentialGroup().addGroup(jPanel4Layout.createParallelGroup(Alignment.LEADING).addComponent(this.unknownBoolean4).addComponent(this.unknownBoolean3)).addGap(0, 0, 32767)).addGroup(jPanel4Layout.createSequentialGroup().addGroup(jPanel4Layout.createParallelGroup(Alignment.LEADING).addComponent(this.unknownArray4, -2, 175, -2).addComponent(this.jLabel19)).addGap(18, 18, 18).addGroup(jPanel4Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel4Layout.createSequentialGroup().addComponent(this.jLabel25).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.unknownInt6, -2, 100, -2).addPreferredGap(ComponentPlacement.RELATED, -1, 32767).addComponent(this.jLabel37).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.unknownInt18, -2, 100, -2)).addGroup(jPanel4Layout.createSequentialGroup().addComponent(this.jLabel24).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.unknownInt5, -2, 100, -2).addPreferredGap(ComponentPlacement.RELATED, -1, 32767).addComponent(this.jLabel36).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.unknownInt17, -2, 100, -2)))).addGroup(jPanel4Layout.createSequentialGroup().addGroup(jPanel4Layout.createParallelGroup(Alignment.TRAILING, false).addGroup(Alignment.LEADING, jPanel4Layout.createSequentialGroup().addComponent(this.unknownArray5, -2, 175, -2).addGap(18, 18, 18).addComponent(this.jLabel26).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.unknownInt7, -2, 100, -2)).addGroup(jPanel4Layout.createSequentialGroup().addGroup(jPanel4Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel4Layout.createSequentialGroup().addComponent(this.unknownBoolean1).addPreferredGap(ComponentPlacement.RELATED, -1, 32767)).addGroup(Alignment.TRAILING, jPanel4Layout.createSequentialGroup().addComponent(this.unknownBoolean2).addGap(80, 80, 80))).addGroup(jPanel4Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel4Layout.createSequentialGroup().addComponent(this.jLabel28).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.unknownInt9, -2, 100, -2)).addGroup(jPanel4Layout.createSequentialGroup().addComponent(this.jLabel27).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.unknownInt8, -2, 100, -2))))).addPreferredGap(ComponentPlacement.RELATED, -1, 32767).addGroup(jPanel4Layout.createParallelGroup(Alignment.LEADING).addGroup(Alignment.TRAILING, jPanel4Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel4Layout.createSequentialGroup().addComponent(this.jLabel38).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.unknownInt19, -2, 100, -2)).addGroup(jPanel4Layout.createSequentialGroup().addComponent(this.jLabel39).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.unknownInt20, -2, 100, -2))).addGroup(Alignment.TRAILING, jPanel4Layout.createSequentialGroup().addComponent(this.jLabel40).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.unknownInt21, -2, 100, -2))))).addGap(88, 88, 88))); + jPanel4Layout.setVerticalGroup(jPanel4Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel4Layout.createSequentialGroup().addContainerGap().addGroup(jPanel4Layout.createParallelGroup(Alignment.LEADING, false).addGroup(jPanel4Layout.createSequentialGroup().addComponent(this.jLabel15).addGap(4, 4, 4).addComponent(this.unknownArray1, -2, -1, -2).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.jLabel16).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.unknownArray2, -2, -1, -2)).addGroup(jPanel4Layout.createSequentialGroup().addGroup(jPanel4Layout.createParallelGroup(Alignment.TRAILING).addGroup(jPanel4Layout.createSequentialGroup().addGroup(jPanel4Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.unknownBoolean5).addComponent(this.jLabel29).addComponent(this.unknownInt10, -2, -1, -2)).addGap(22, 22, 22)).addGroup(jPanel4Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.unknownBoolean6).addComponent(this.jLabel30).addComponent(this.unknownInt11, -2, -1, -2))).addGroup(jPanel4Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.unknownBoolean7).addComponent(this.jLabel31).addComponent(this.unknownInt12, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED, -1, 32767).addGroup(jPanel4Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel20).addComponent(this.unknownInt1, -2, -1, -2).addComponent(this.jLabel32).addComponent(this.unknownInt13, -2, -1, -2)))).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel4Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel17).addComponent(this.jLabel21).addComponent(this.unknownInt2, -2, -1, -2).addComponent(this.jLabel33).addComponent(this.unknownInt14, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel4Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.unknownArray3, -2, -1, -2).addComponent(this.jLabel22).addComponent(this.unknownInt3, -2, -1, -2).addComponent(this.jLabel34).addComponent(this.unknownInt15, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel4Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel18).addComponent(this.jLabel23).addComponent(this.unknownInt4, -2, -1, -2).addComponent(this.jLabel35).addComponent(this.unknownInt16, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel4Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.unknownArray4, -2, -1, -2).addComponent(this.jLabel24).addComponent(this.unknownInt5, -2, -1, -2).addComponent(this.jLabel36).addComponent(this.unknownInt17, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel4Layout.createParallelGroup(Alignment.LEADING).addComponent(this.unknownInt6, -2, 20, -2).addGroup(jPanel4Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel19).addComponent(this.jLabel25).addComponent(this.jLabel37).addComponent(this.unknownInt18, -2, -1, -2))).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel4Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.unknownArray5, -2, -1, -2).addComponent(this.jLabel26).addComponent(this.unknownInt7, -2, -1, -2).addComponent(this.jLabel38).addComponent(this.unknownInt19, -2, -1, -2)).addPreferredGap(ComponentPlacement.UNRELATED).addGroup(jPanel4Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.unknownBoolean1).addComponent(this.jLabel27).addComponent(this.unknownInt8, -2, -1, -2).addComponent(this.jLabel39).addComponent(this.unknownInt20, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel4Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.unknownBoolean2).addComponent(this.jLabel28).addComponent(this.unknownInt9, -2, -1, -2).addComponent(this.jLabel40).addComponent(this.unknownInt21, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.unknownBoolean3).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.unknownBoolean4).addContainerGap(-1, 32767))); + this.jTabbedPane1.addTab("Unknown Definitions", this.jPanel4); + this.clientScriptOutput.setColumns(20); + this.clientScriptOutput.setRows(5); + this.clientScriptOutput.setText(this.getClientScripts()); + this.jScrollPane1.setViewportView(this.clientScriptOutput); + this.jLabel41.setText("KEY"); + this.jLabel42.setText("VALUE"); + this.jLabel43.setText("Add keys into the boxes on the left to edit or add them."); + this.jLabel44.setText("Add values on the right to match the keys."); + GroupLayout jPanel5Layout = new GroupLayout(this.jPanel5); + this.jPanel5.setLayout(jPanel5Layout); + jPanel5Layout.setHorizontalGroup(jPanel5Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel5Layout.createSequentialGroup().addContainerGap().addComponent(this.jScrollPane1, -2, 325, -2).addGroup(jPanel5Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel5Layout.createSequentialGroup().addGap(72, 72, 72).addComponent(this.jLabel41).addPreferredGap(ComponentPlacement.RELATED, -1, 32767).addComponent(this.jLabel42).addGap(81, 81, 81)).addGroup(jPanel5Layout.createSequentialGroup().addGap(18, 18, 18).addGroup(jPanel5Layout.createParallelGroup(Alignment.LEADING).addComponent(this.jLabel44).addComponent(this.jLabel43)).addContainerGap(43, 32767)).addGroup(jPanel5Layout.createSequentialGroup().addGap(53, 53, 53).addGroup(jPanel5Layout.createParallelGroup(Alignment.LEADING, false).addComponent(this.csk4, Alignment.TRAILING).addComponent(this.csk5, Alignment.TRAILING).addComponent(this.csk6, Alignment.TRAILING).addComponent(this.csk1, -1, 80, 32767).addComponent(this.csk2).addComponent(this.csk3)).addPreferredGap(ComponentPlacement.RELATED, -1, 32767).addGroup(jPanel5Layout.createParallelGroup(Alignment.LEADING, false).addComponent(this.csv1, -2, 80, -2).addComponent(this.csv2, -1, 81, 32767).addComponent(this.csv3).addComponent(this.csv4).addComponent(this.csv5).addComponent(this.csv6)).addGap(0, 0, 32767))))); + jPanel5Layout.setVerticalGroup(jPanel5Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel5Layout.createSequentialGroup().addContainerGap().addGroup(jPanel5Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel5Layout.createSequentialGroup().addComponent(this.jScrollPane1, -1, 346, 32767).addContainerGap()).addGroup(jPanel5Layout.createSequentialGroup().addGroup(jPanel5Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel41).addComponent(this.jLabel42)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel5Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.csk1, -2, -1, -2).addComponent(this.csv1, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel5Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.csk2, -2, -1, -2).addComponent(this.csv2, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel5Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.csk3, -2, -1, -2).addComponent(this.csv3, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel5Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.csk4, -2, -1, -2).addComponent(this.csv4, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel5Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.csk5, -2, -1, -2).addComponent(this.csv5, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel5Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.csk6, -2, -1, -2).addComponent(this.csv6, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED, -1, 32767).addComponent(this.jLabel43).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.jLabel44).addGap(45, 45, 45))))); + this.jTabbedPane1.addTab("Clientscripts", this.jPanel5); + this.jLabel2.setText("Currently Viewing Definitions of NPC: " + this.defs.getId() + " - " + this.defs.getName()); + this.jMenu1.setText("File"); + this.reloadButton.setText("Reload"); + this.reloadButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + NPCEditor.this.reloadButtonActionPerformed(evt); + } + }); + this.jMenu1.add(this.reloadButton); + this.saveButton.setText("Save"); + this.saveButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + NPCEditor.this.saveButtonActionPerformed(evt); + } + }); + this.jMenu1.add(this.saveButton); + this.addModelButton.setText("Add Model"); + this.addModelButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + NPCEditor.this.addModelButtonActionPerformed(evt); + } + }); + this.jMenu1.add(this.addModelButton); + this.exportButton.setText("Export to .txt"); + this.exportButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + NPCEditor.this.exportButtonActionPerformed(evt); + } + }); + this.jMenu1.add(this.exportButton); + this.exitButton.setText("Exit"); + this.exitButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + NPCEditor.this.exitButtonActionPerformed(evt); + } + }); + this.jMenu1.add(this.exitButton); + this.jMenuBar1.add(this.jMenu1); + this.setJMenuBar(this.jMenuBar1); + GroupLayout layout = new GroupLayout(this.getContentPane()); + this.getContentPane().setLayout(layout); + layout.setHorizontalGroup(layout.createParallelGroup(Alignment.LEADING).addComponent(this.jTabbedPane1).addGroup(layout.createSequentialGroup().addContainerGap().addComponent(this.jLabel2).addContainerGap(-1, 32767))); + layout.setVerticalGroup(layout.createParallelGroup(Alignment.LEADING).addGroup(Alignment.TRAILING, layout.createSequentialGroup().addGap(0, 16, 32767).addComponent(this.jLabel2).addPreferredGap(ComponentPlacement.UNRELATED).addComponent(this.jTabbedPane1, -2, 396, -2))); + this.pack(); + } + + private void reloadButtonActionPerformed(ActionEvent evt) { + this.reload(); + } + + private void saveButtonActionPerformed(ActionEvent evt) { + this.save(); + } + + private void addModelButtonActionPerformed(ActionEvent evt) { + this.addModel(); + } + + private void exportButtonActionPerformed(ActionEvent evt) { + this.export(); + } + + private void exitButtonActionPerformed(ActionEvent evt) { + this.dispose(); + } + + public static void main(String[] args) { + EventQueue.invokeLater(new Runnable() { + public void run() { + (new NPCEditor()).setVisible(true); + } + }); + } + + private void reload() { + this.name.setText(this.defs.getName()); + this.combatLevel.setText("" + this.defs.getCombatLevel()); + this.visibleOnMap.setSelected(this.defs.isVisibleOnMap); + this.npcHeight.setText("" + this.defs.npcHeight); + this.npcWidth.setText("" + this.defs.npcWidth); + this.walkMask.setText("" + this.defs.walkMask); + this.respawnDirection.setText("" + this.defs.respawnDirection); + this.renderEmote.setText("" + this.defs.renderEmote); + this.modelIds.setText(this.getModelIds()); + this.jTextField2.setText(this.getChatHeads()); + this.optionsField.setText(this.getOpts()); + this.modelColorField.setText(this.getChangedModelColors()); + this.textureColorField.setText(this.getChangedTextureColors()); + this.unknownArray1.setText(this.getUnknownArray1()); + this.unknownArray2.setText(this.getUnknownArray2()); + this.unknownArray3.setText(this.getUnknownArray3()); + this.unknownArray4.setText(this.getUnknownArray4()); + this.unknownArray5.setText(this.getUnknownArray5()); + this.unknownBoolean1.setSelected(this.defs.unknownBoolean1); + this.unknownBoolean2.setSelected(this.defs.unknownBoolean2); + this.unknownBoolean3.setSelected(this.defs.unknownBoolean3); + this.unknownBoolean5.setSelected(this.defs.unknownBoolean5); + this.unknownBoolean4.setSelected(this.defs.unknownBoolean4); + this.unknownBoolean6.setSelected(this.defs.unknownBoolean6); + this.unknownBoolean7.setSelected(this.defs.unknownBoolean7); + this.unknownInt1.setText("" + this.defs.unknownInt1); + this.unknownInt2.setText("" + this.defs.unknownInt2); + this.unknownInt3.setText("" + this.defs.unknownInt3); + this.unknownInt4.setText("" + this.defs.unknownInt4); + this.unknownInt5.setText("" + this.defs.unknownInt5); + this.unknownInt6.setText("" + this.defs.unknownInt6); + this.unknownInt7.setText("" + this.defs.unknownInt7); + this.unknownInt8.setText("" + this.defs.unknownInt8); + this.unknownInt9.setText("" + this.defs.unknownInt9); + this.unknownInt10.setText("" + this.defs.unknownInt10); + this.unknownInt11.setText("" + this.defs.unknownInt11); + this.unknownInt12.setText("" + this.defs.unknownInt12); + this.unknownInt13.setText("" + this.defs.unknownInt13); + this.unknownInt14.setText("" + this.defs.unknownInt14); + this.unknownInt15.setText("" + this.defs.unknownInt15); + this.unknownInt16.setText("" + this.defs.unknownInt16); + this.unknownInt17.setText("" + this.defs.unknownInt17); + this.unknownInt18.setText("" + this.defs.unknownInt18); + this.unknownInt19.setText("" + this.defs.unknownInt19); + this.unknownInt20.setText("" + this.defs.unknownInt20); + this.unknownInt21.setText("" + this.defs.unknownInt21); + this.clientScriptOutput.setText(this.getClientScripts()); + } + + private void save() { + try { + this.defs.name = this.name.getText(); + this.defs.combatLevel = Integer.parseInt(this.combatLevel.getText()); + this.defs.isVisibleOnMap = this.visibleOnMap.isSelected(); + this.defs.npcHeight = Integer.parseInt(this.npcHeight.getText()); + this.defs.npcWidth = Integer.parseInt(this.npcWidth.getText()); + this.defs.walkMask = (byte)Integer.parseInt(this.walkMask.getText()); + this.defs.respawnDirection = (byte)Integer.parseInt(this.respawnDirection.getText()); + this.defs.renderEmote = Integer.parseInt(this.renderEmote.getText()); + String[] var15; + int e1; + if(!this.modelIds.getText().equals("")) { + var15 = this.modelIds.getText().split(";"); + + for(e1 = 0; e1 < this.defs.modelIds.length; ++e1) { + this.defs.modelIds[e1] = Integer.parseInt(var15[e1]); + } + } + + if(!this.jTextField2.getText().equals("")) { + var15 = this.jTextField2.getText().split(";"); + + for(e1 = 0; e1 < this.defs.npcChatHeads.length; ++e1) { + this.defs.npcChatHeads[e1] = Integer.parseInt(var15[e1]); + } + } + + var15 = this.optionsField.getText().split(";"); + + for(e1 = 0; e1 < this.defs.options.length; ++e1) { + this.defs.options[e1] = var15[e1].equals("null")?null:var15[e1]; + } + + this.defs.resetModelColors(); + String[] var17; + String[] i; + int len$; + int i$; + String t; + String[] editedColor; + if(!this.modelColorField.getText().equals("")) { + var17 = this.modelColorField.getText().split(";"); + i = var17; + len$ = var17.length; + + for(i$ = 0; i$ < len$; ++i$) { + t = i[i$]; + editedColor = t.split("="); + this.defs.changeModelColor(Integer.valueOf(editedColor[0]).intValue(), Integer.valueOf(editedColor[1]).intValue()); + } + } + + this.defs.resetTextureColors(); + if(!this.textureColorField.getText().equals("")) { + var17 = this.textureColorField.getText().split(";"); + i = var17; + len$ = var17.length; + + for(i$ = 0; i$ < len$; ++i$) { + t = i[i$]; + editedColor = t.split("="); + this.defs.changeTextureColor(Integer.valueOf(editedColor[0]).intValue(), Integer.valueOf(editedColor[1]).intValue()); + } + } + + int var16; + if(!this.unknownArray1.getText().equals("")) { + var17 = this.unknownArray1.getText().split(";"); + + for(var16 = 0; var16 < this.defs.unknownArray1.length; ++var16) { + this.defs.unknownArray1[var16] = (byte)Integer.parseInt(var17[var16]); + } + } + + if(!this.unknownArray2.getText().equals("")) { + var17 = this.unknownArray2.getText().split(";"); + + for(var16 = 0; var16 < this.defs.unknownArray2.length; ++var16) { + this.defs.unknownArray2[var16] = Integer.parseInt(var17[var16]); + } + } + + if(!this.unknownArray3.getText().equals("")) { + var17 = this.unknownArray3.getText().split(";"); + + for(var16 = 0; var16 < this.defs.unknownArray3.length; ++var16) { + this.defs.unknownArray3[0][var16] = Integer.parseInt(var17[var16]); + } + } + + if(!this.unknownArray4.getText().equals("")) { + var17 = this.unknownArray4.getText().split(";"); + + for(var16 = 0; var16 < this.defs.unknownArray4.length; ++var16) { + this.defs.unknownArray4[var16] = Integer.parseInt(var17[var16]); + } + } + + if(!this.unknownArray5.getText().equals("")) { + var17 = this.unknownArray5.getText().split(";"); + + for(var16 = 0; var16 < this.defs.unknownArray5.length; ++var16) { + this.defs.unknownArray5[var16] = Integer.parseInt(var17[var16]); + } + } + + this.defs.unknownBoolean1 = this.unknownBoolean1.isSelected(); + this.defs.unknownBoolean2 = this.unknownBoolean2.isSelected(); + this.defs.unknownBoolean3 = this.unknownBoolean3.isSelected(); + this.defs.unknownBoolean4 = this.unknownBoolean4.isSelected(); + this.defs.unknownBoolean5 = this.unknownBoolean5.isSelected(); + this.defs.unknownBoolean6 = this.unknownBoolean6.isSelected(); + this.defs.unknownBoolean7 = this.unknownBoolean7.isSelected(); + if(!this.unknownInt1.getText().equals("")) { + this.defs.unknownInt1 = Integer.parseInt(this.unknownInt1.getText()); + } + + if(!this.unknownInt2.getText().equals("")) { + this.defs.unknownInt2 = Integer.parseInt(this.unknownInt2.getText()); + } + + if(!this.unknownInt3.getText().equals("")) { + this.defs.unknownInt3 = Integer.parseInt(this.unknownInt3.getText()); + } + + if(!this.unknownInt4.getText().equals("")) { + this.defs.unknownInt4 = Integer.parseInt(this.unknownInt4.getText()); + } + + if(!this.unknownInt5.getText().equals("")) { + this.defs.unknownInt5 = Integer.parseInt(this.unknownInt5.getText()); + } + + if(!this.unknownInt6.getText().equals("")) { + this.defs.unknownInt6 = Integer.parseInt(this.unknownInt6.getText()); + } + + if(!this.unknownInt7.getText().equals("")) { + this.defs.unknownInt7 = Integer.parseInt(this.unknownInt7.getText()); + } + + if(!this.unknownInt8.getText().equals("")) { + this.defs.unknownInt8 = Integer.parseInt(this.unknownInt8.getText()); + } + + if(!this.unknownInt9.getText().equals("")) { + this.defs.unknownInt9 = Integer.parseInt(this.unknownInt9.getText()); + } + + if(!this.unknownInt10.getText().equals("")) { + this.defs.unknownInt10 = Integer.parseInt(this.unknownInt10.getText()); + } + + if(!this.unknownInt11.getText().equals("")) { + this.defs.unknownInt11 = Integer.parseInt(this.unknownInt11.getText()); + } + + if(!this.unknownInt12.getText().equals("")) { + this.defs.unknownInt12 = Integer.parseInt(this.unknownInt12.getText()); + } + + if(!this.unknownInt13.getText().equals("")) { + this.defs.unknownInt13 = Integer.parseInt(this.unknownInt13.getText()); + } + + if(!this.unknownInt14.getText().equals("")) { + this.defs.unknownInt14 = Integer.parseInt(this.unknownInt14.getText()); + } + + if(!this.unknownInt15.getText().equals("")) { + this.defs.unknownInt15 = Integer.parseInt(this.unknownInt15.getText()); + } + + if(!this.unknownInt16.getText().equals("")) { + this.defs.unknownInt16 = Integer.parseInt(this.unknownInt16.getText()); + } + + if(!this.unknownInt17.getText().equals("")) { + this.defs.unknownInt17 = Integer.parseInt(this.unknownInt17.getText()); + } + + if(!this.unknownInt18.getText().equals("")) { + this.defs.unknownInt18 = Integer.parseInt(this.unknownInt18.getText()); + } + + if(!this.unknownInt19.getText().equals("")) { + this.defs.unknownInt19 = Integer.parseInt(this.unknownInt19.getText()); + } + + if(!this.unknownInt20.getText().equals("")) { + this.defs.unknownInt20 = Integer.parseInt(this.unknownInt20.getText()); + } + + if(!this.unknownInt21.getText().equals("")) { + this.defs.unknownInt21 = Integer.parseInt(this.unknownInt21.getText()); + } + + try { + if(!this.csk1.getText().equals("") && !this.csv1.getText().equals("")) { + try { + this.defs.clientScriptData.remove(this.csk1); + this.defs.clientScriptData.put(Integer.valueOf(Integer.parseInt(this.csk1.getText())), Integer.valueOf(Integer.parseInt(this.csv1.getText()))); + } catch (Exception var161) { + this.defs.clientScriptData.remove(this.csk1); + this.defs.clientScriptData.put(Integer.valueOf(Integer.parseInt(this.csk1.getText())), this.csv1.getText().toString()); + } + } + + if(!this.csk2.getText().equals("") && !this.csv2.getText().equals("")) { + try { + this.defs.clientScriptData.remove(this.csk2); + this.defs.clientScriptData.put(Integer.valueOf(Integer.parseInt(this.csk2.getText())), Integer.valueOf(Integer.parseInt(this.csv2.getText()))); + } catch (Exception var151) { + this.defs.clientScriptData.remove(this.csk2); + this.defs.clientScriptData.put(Integer.valueOf(Integer.parseInt(this.csk2.getText())), this.csv2.getText().toString()); + } + } + + if(!this.csk3.getText().equals("") && !this.csv3.getText().equals("")) { + try { + this.defs.clientScriptData.remove(this.csk3); + this.defs.clientScriptData.put(Integer.valueOf(Integer.parseInt(this.csk3.getText())), Integer.valueOf(Integer.parseInt(this.csv3.getText()))); + } catch (Exception var14) { + this.defs.clientScriptData.remove(this.csk3); + this.defs.clientScriptData.put(Integer.valueOf(Integer.parseInt(this.csk3.getText())), this.csv3.getText().toString()); + } + } + + if(!this.csk4.getText().equals("") && !this.csv4.getText().equals("")) { + try { + this.defs.clientScriptData.remove(this.csk4); + this.defs.clientScriptData.put(Integer.valueOf(Integer.parseInt(this.csk4.getText())), Integer.valueOf(Integer.parseInt(this.csv4.getText()))); + } catch (Exception var13) { + this.defs.clientScriptData.remove(this.csk4); + this.defs.clientScriptData.put(Integer.valueOf(Integer.parseInt(this.csk4.getText())), this.csv4.getText().toString()); + } + } + + if(!this.csk5.getText().equals("") && !this.csv5.getText().equals("")) { + try { + this.defs.clientScriptData.remove(this.csk5); + this.defs.clientScriptData.put(Integer.valueOf(Integer.parseInt(this.csk5.getText())), Integer.valueOf(Integer.parseInt(this.csv5.getText()))); + } catch (Exception var12) { + this.defs.clientScriptData.remove(this.csk5); + this.defs.clientScriptData.put(Integer.valueOf(Integer.parseInt(this.csk5.getText())), this.csv5.getText().toString()); + } + } + + if(!this.csk6.getText().equals("") && !this.csv6.getText().equals("")) { + try { + this.defs.clientScriptData.remove(this.csk6); + this.defs.clientScriptData.put(Integer.valueOf(Integer.parseInt(this.csk6.getText())), Integer.valueOf(Integer.parseInt(this.csv6.getText()))); + } catch (Exception var11) { + this.defs.clientScriptData.remove(this.csk6); + this.defs.clientScriptData.put(Integer.valueOf(Integer.parseInt(this.csk6.getText())), this.csv6.getText().toString()); + } + } + } catch (Exception var171) { + this.defs.clientScriptData = new HashMap(1); + } + + NPCSelection var10001 = this.ns; + this.defs.write(NPCSelection.STORE); + this.ns.updateNPCDefs(this.defs); + } catch (Exception var18) { + Main.log("NPCEditor", "Cannot save. Please check for mistypes."); + System.out.println(var18); + } + + } + + private void addModel() { + JFrame frame = new JFrame(); + int result = JOptionPane.showConfirmDialog(frame, "Do you want to specify a model ID?"); + StringBuilder var10001; + NPCSelection var10002; + if(result == 0) { + JFrame fc1 = new JFrame(); + String returnVal1 = JOptionPane.showInputDialog(fc1, "Enter new model ID:"); + if(Integer.parseInt(returnVal1.toString()) != -1) { + JFileChooser file2 = new JFileChooser(); + file2.setFileSelectionMode(0); + int var9 = file2.showOpenDialog(this); + if(var9 == 0) { + File file1 = file2.getSelectedFile(); + + try { + var10001 = (new StringBuilder()).append("The model ID of the recently packed model is: "); + var10002 = this.ns; + Main.log("NPCEditor", var10001.append(Utils.packCustomModel(NPCSelection.STORE, Utils.getBytesFromFile(new File(file1.getPath().toString())), Integer.parseInt(returnVal1.toString()))).toString()); + } catch (IOException var12) { + Main.log("NPCEditor", "There was an error packing the model."); + } + } + } + } else if(result == 1) { + JFileChooser fc11 = new JFileChooser(); + fc11.setFileSelectionMode(0); + int returnVal11 = fc11.showOpenDialog(this); + if(returnVal11 == 0) { + File file21 = fc11.getSelectedFile(); + + try { + var10001 = (new StringBuilder()).append("The model ID of the recently packed model is: "); + var10002 = this.ns; + Main.log("NPCEditor", var10001.append(Utils.packCustomModel(NPCSelection.STORE, Utils.getBytesFromFile(new File(file21.getPath().toString())))).toString()); + } catch (IOException var11) { + Main.log("NPCEditor", "There was an error packing the model."); + } + } + } + + } + + private void export() { + File f = new File(System.getProperty("user.home") + "/FCE/npcs/"); + f.mkdirs(); + String lineSep = System.getProperty("line.separator"); + BufferedWriter writer = null; + + try { + writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(System.getProperty("user.home") + "/FCE/npcs/" + this.defs.id + ".txt"), "utf-8")); + writer.write("name = " + this.defs.getName()); + writer.write(lineSep); + writer.write("combat level = " + this.defs.getCombatLevel()); + writer.write(lineSep); + writer.write("isVisibleOnMap = " + this.defs.isVisibleOnMap); + writer.write(lineSep); + writer.write("height = " + this.defs.npcHeight); + writer.write(lineSep); + writer.write("width = " + this.defs.npcWidth); + writer.write(lineSep); + writer.write("walk mask = " + this.defs.walkMask); + writer.write(lineSep); + writer.write("respawn direction = " + this.defs.respawnDirection); + writer.write(lineSep); + writer.write("render emote = " + this.defs.renderEmote); + writer.write(lineSep); + writer.write("model ids = " + this.getModelIds()); + writer.write(lineSep); + writer.write("chat head model ids = " + this.getChatHeads()); + writer.write(lineSep); + writer.write("options = " + this.getOpts()); + writer.write(lineSep); + writer.write("model colors = " + this.getChangedModelColors()); + writer.write(lineSep); + writer.write("texture colors = " + this.getChangedTextureColors()); + writer.write(lineSep); + writer.write("unknown array1 = " + this.getUnknownArray1()); + writer.write(lineSep); + writer.write("unknown array2 = " + this.getUnknownArray2()); + writer.write(lineSep); + writer.write("unknown array3 = " + this.getUnknownArray3()); + writer.write(lineSep); + writer.write("unknown array4 = " + this.getUnknownArray4()); + writer.write(lineSep); + writer.write("unknown array5 = " + this.getUnknownArray5()); + writer.write(lineSep); + writer.write("unknownBoolean1 = " + this.defs.unknownBoolean1); + writer.write(lineSep); + writer.write("unknwonBoolean2 = " + this.defs.unknownBoolean2); + writer.write(lineSep); + writer.write("unknownBoolean3 = " + this.defs.unknownBoolean3); + writer.write(lineSep); + writer.write("unknownBoolean4 = " + this.defs.unknownBoolean5); + writer.write(lineSep); + writer.write("unknownBoolean5 = " + this.defs.unknownBoolean4); + writer.write(lineSep); + writer.write("unknownBoolean6 = " + this.defs.unknownBoolean6); + writer.write(lineSep); + writer.write("unknownBoolean7 = " + this.defs.unknownBoolean7); + writer.write(lineSep); + writer.write("unknown int1 = " + this.defs.unknownInt1); + writer.write(lineSep); + writer.write("unknown int2 = " + this.defs.unknownInt2); + writer.write(lineSep); + writer.write("unknown int3 = " + this.defs.unknownInt3); + writer.write(lineSep); + writer.write("unknown int4 = " + this.defs.unknownInt4); + writer.write(lineSep); + writer.write("unknown int5 = " + this.defs.unknownInt5); + writer.write(lineSep); + writer.write("unknown int6 = " + this.defs.unknownInt6); + writer.write(lineSep); + writer.write("unknown int7 = " + this.defs.unknownInt7); + writer.write(lineSep); + writer.write("unknown int8 = " + this.defs.unknownInt8); + writer.write(lineSep); + writer.write("unknown int9 = " + this.defs.unknownInt9); + writer.write(lineSep); + writer.write("unknown int10 = " + this.defs.unknownInt10); + writer.write(lineSep); + writer.write("unknown int11 = " + this.defs.unknownInt11); + writer.write(lineSep); + writer.write("unknown int12 = " + this.defs.unknownInt12); + writer.write(lineSep); + writer.write("unknown int13 = " + this.defs.unknownInt13); + writer.write(lineSep); + writer.write("unknown int14 = " + this.defs.unknownInt14); + writer.write(lineSep); + writer.write("unknown int15 = " + this.defs.unknownInt15); + writer.write(lineSep); + writer.write("unknown int16 = " + this.defs.unknownInt16); + writer.write(lineSep); + writer.write("unknown int17 = " + this.defs.unknownInt17); + writer.write(lineSep); + writer.write("unknown int18 = " + this.defs.unknownInt18); + writer.write(lineSep); + writer.write("unknown int19 = " + this.defs.unknownInt19); + writer.write(lineSep); + writer.write("unknown int20 = " + this.defs.unknownInt20); + writer.write(lineSep); + writer.write("unknown int21 = " + this.defs.unknownInt21); + writer.write(lineSep); + writer.write("Clientscripts"); + writer.write(lineSep); + if(this.defs.clientScriptData != null) { + Iterator var15 = this.defs.clientScriptData.keySet().iterator(); + + while(var15.hasNext()) { + int key = ((Integer)var15.next()).intValue(); + Object value = this.defs.clientScriptData.get(Integer.valueOf(key)); + writer.write("KEY: " + key + ", VALUE: " + value); + writer.write(lineSep); + } + } + } catch (IOException var151) { + Main.log("NPCEditor", "Failed to export NPC Defs to .txt"); + } finally { + try { + writer.close(); + } catch (Exception var14) { + ; + } + + } + + } + + public String getClientScripts() { + String text = ""; + String lineSep = System.getProperty("line.separator"); + if(this.defs.clientScriptData != null) { + for(Iterator i$ = this.defs.clientScriptData.keySet().iterator(); i$.hasNext(); text = text + lineSep) { + int key = ((Integer)i$.next()).intValue(); + Object value = this.defs.clientScriptData.get(Integer.valueOf(key)); + text = text + "KEY: " + key + ", VALUE: " + value; + } + } + + return text; + } + + public String getModelIds() { + String text = ""; + + try { + int[] e = this.defs.modelIds; + int len$ = e.length; + + for(int i$ = 0; i$ < len$; ++i$) { + int index = e[i$]; + text = text + index + ";"; + } + } catch (Exception var6) { + ; + } + + return text; + } + + public String getOpts() { + String text = ""; + String[] arr$ = this.defs.getOptions(); + int len$ = arr$.length; + + for(int i$ = 0; i$ < len$; ++i$) { + String option = arr$[i$]; + text = text + (option == null?"null":option) + ";"; + } + + return text; + } + + public String getChangedModelColors() { + String text = ""; + if(this.defs.originalModelColors != null) { + for(int i = 0; i < this.defs.originalModelColors.length; ++i) { + text = text + this.defs.originalModelColors[i] + "=" + this.defs.modifiedModelColors[i] + ";"; + } + } + + return text; + } + + public String getChangedTextureColors() { + String text = ""; + if(this.defs.originalTextureColors != null) { + for(int i = 0; i < this.defs.originalTextureColors.length; ++i) { + text = text + this.defs.originalTextureColors[i] + "=" + this.defs.modifiedTextureColors[i] + ";"; + } + } + + return text; + } + + public String getChatHeads() { + String text = ""; + + try { + int[] e = this.defs.npcChatHeads; + int len$ = e.length; + + for(int i$ = 0; i$ < len$; ++i$) { + int id = e[i$]; + text = text + id + ";"; + } + } catch (Exception var6) { + ; + } + + return text; + } + + public String getUnknownArray1() { + String text = ""; + + try { + byte[] e = this.defs.unknownArray1; + int len$ = e.length; + + for(int i$ = 0; i$ < len$; ++i$) { + byte index = e[i$]; + text = text + index + ";"; + } + } catch (Exception var6) { + ; + } + + return text; + } + + public String getUnknownArray2() { + String text = ""; + + try { + int[] e = this.defs.unknownArray2; + int len$ = e.length; + + for(int i$ = 0; i$ < len$; ++i$) { + int index = e[i$]; + text = text + index + ";"; + } + } catch (Exception var6) { + ; + } + + return text; + } + + public String getUnknownArray3() { + String text = ""; + + try { + int[] e = this.defs.unknownArray3[0]; + int len$ = e.length; + + for(int i$ = 0; i$ < len$; ++i$) { + int index = e[i$]; + text = text + index + ";"; + } + } catch (Exception var6) { + ; + } + + return text; + } + + public String getUnknownArray4() { + String text = ""; + + try { + int[] e = this.defs.unknownArray4; + int len$ = e.length; + + for(int i$ = 0; i$ < len$; ++i$) { + int index = e[i$]; + text = text + index + ";"; + } + } catch (Exception var6) { + ; + } + + return text; + } + + public String getUnknownArray5() { + String text = ""; + + try { + int[] e = this.defs.unknownArray5; + int len$ = e.length; + + for(int i$ = 0; i$ < len$; ++i$) { + int index = e[i$]; + text = text + index + ";"; + } + } catch (Exception var6) { + ; + } + + return text; + } +} diff --git a/Tools/Frostys Cache Editor/src/com/editor/npc/NPCListDumper.java b/Tools/Frostys Cache Editor/src/com/editor/npc/NPCListDumper.java new file mode 100644 index 0000000..f1dbc3a --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/editor/npc/NPCListDumper.java @@ -0,0 +1,38 @@ +package com.editor.npc; + +import com.alex.loaders.npcs.NPCDefinitions; +import com.alex.store.Store; +import com.alex.utils.Utils; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; + +public class NPCListDumper { + private static Store STORE; + + public static void main(String[] args) throws IOException { + STORE = new Store("C:/Users/Travis/Documents/rscd/data/"); + File file = new File("C:/Users/Travis/Documents/781 NPCList.txt"); + if(file.exists()) { + file.delete(); + } else { + file.createNewFile(); + } + + BufferedWriter writer = new BufferedWriter(new FileWriter(file)); + writer.append("//Version = 781\n"); + writer.flush(); + + for(int id = 0; id < Utils.getNPCDefinitionsSize(STORE) - 18433; ++id) { + NPCDefinitions def = NPCDefinitions.getNPCDefinition(STORE, id); + writer.append(id + " - " + def.name); + writer.newLine(); + System.out.println(id + " - " + def.name); + writer.flush(); + } + + writer.close(); + } +} diff --git a/Tools/Frostys Cache Editor/src/com/editor/npc/NPCSelection.java b/Tools/Frostys Cache Editor/src/com/editor/npc/NPCSelection.java new file mode 100644 index 0000000..891cf0b --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/editor/npc/NPCSelection.java @@ -0,0 +1,191 @@ +package com.editor.npc; + +import com.alex.loaders.npcs.NPCDefinitions; +import com.alex.store.Store; +import com.alex.utils.Utils; +import com.editor.Main; +import com.editor.npc.NPCEditor; + +import javax.swing.GroupLayout.Alignment; +import javax.swing.LayoutStyle.ComponentPlacement; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.IOException; + +public class NPCSelection extends JFrame { + private static final long serialVersionUID = -3068337441331467664L; + public static Store STORE; + private JButton addButton; + private JButton duplicateButton; + private JButton editButton; + private DefaultListModel npcsListmodel; + private JList npcsList; + private JMenu jMenu1; + private JMenuBar jMenuBar1; + private JMenuItem exitButton; + private JButton deleteButton; + + public NPCSelection(String cache) throws IOException { + STORE = new Store(cache); + this.setTitle("NPC Selection"); + this.setResizable(false); + this.setDefaultCloseOperation(1); + this.setLocationRelativeTo((Component)null); + this.initComponents(); + } + + public NPCSelection() { + this.initComponents(); + } + + private void initComponents() { + this.editButton = new JButton(); + this.addButton = new JButton(); + this.duplicateButton = new JButton(); + this.deleteButton = new JButton(); + this.jMenuBar1 = new JMenuBar(); + this.jMenu1 = new JMenu(); + this.exitButton = new JMenuItem(); + this.setDefaultCloseOperation(1); + this.npcsListmodel = new DefaultListModel(); + this.npcsList = new JList(this.npcsListmodel); + this.npcsList.setSelectionMode(1); + this.npcsList.setLayoutOrientation(0); + this.npcsList.setVisibleRowCount(-1); + JScrollPane jScrollPane1 = new JScrollPane(this.npcsList); + this.editButton.setText("Edit"); + this.editButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + NPCDefinitions defs = (NPCDefinitions)NPCSelection.this.npcsList.getSelectedValue(); + if(defs != null) { + new NPCEditor(NPCSelection.this, defs); + } + + } + }); + this.addButton.setText("Add New"); + this.addButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + NPCDefinitions defs = new NPCDefinitions(NPCSelection.STORE, NPCSelection.this.getNewNPCID(), false); + if(defs != null && defs.id != -1) { + new NPCEditor(NPCSelection.this, defs); + } + + } + }); + this.duplicateButton.setText("Duplicate"); + this.duplicateButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + NPCDefinitions defs = (NPCDefinitions)NPCSelection.this.npcsList.getSelectedValue(); + if(defs != null) { + defs = (NPCDefinitions)defs.clone(); + if(defs != null) { + defs.id = NPCSelection.this.getNewNPCID(); + if(defs.id != -1) { + new NPCEditor(NPCSelection.this, defs); + } + } + } + + } + }); + this.deleteButton.setText("Delete"); + this.deleteButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + NPCDefinitions defs = (NPCDefinitions)NPCSelection.this.npcsList.getSelectedValue(); + JFrame frame = new JFrame(); + int result = JOptionPane.showConfirmDialog(frame, "Do you really want to delete item " + defs.id); + if(result == 0) { + if(defs == null) { + return; + } + + NPCSelection.STORE.getIndexes()[19].removeFile(defs.getArchiveId(), defs.getFileId()); + NPCSelection.this.removeNPCDefs(defs); + Main.log("ItemSelection", "Item " + defs.id + " removed."); + } + + } + }); + this.jMenu1.setText("File"); + this.exitButton.setText("Close"); + this.exitButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + NPCSelection.this.exitButtonActionPerformed(evt); + } + }); + this.jMenu1.add(this.exitButton); + this.jMenuBar1.add(this.jMenu1); + this.setJMenuBar(this.jMenuBar1); + GroupLayout layout = new GroupLayout(this.getContentPane()); + this.getContentPane().setLayout(layout); + layout.setHorizontalGroup(layout.createParallelGroup(Alignment.LEADING).addGroup(layout.createSequentialGroup().addContainerGap().addGroup(layout.createParallelGroup(Alignment.LEADING).addGroup(layout.createSequentialGroup().addGroup(layout.createParallelGroup(Alignment.LEADING, false).addComponent(jScrollPane1, -2, 200, -2).addGroup(layout.createSequentialGroup().addComponent(this.editButton).addPreferredGap(ComponentPlacement.RELATED, -1, 32767).addComponent(this.addButton))).addGap(0, 0, 32767)).addGroup(layout.createSequentialGroup().addComponent(this.duplicateButton).addPreferredGap(ComponentPlacement.RELATED, -1, 32767).addComponent(this.deleteButton))).addContainerGap(-1, 32767))); + layout.setVerticalGroup(layout.createParallelGroup(Alignment.LEADING).addGroup(layout.createSequentialGroup().addContainerGap().addComponent(jScrollPane1, -2, 279, -2).addPreferredGap(ComponentPlacement.RELATED).addGroup(layout.createParallelGroup(Alignment.BASELINE).addComponent(this.editButton).addComponent(this.addButton)).addPreferredGap(ComponentPlacement.RELATED).addGroup(layout.createParallelGroup(Alignment.BASELINE).addComponent(this.duplicateButton).addComponent(this.deleteButton)).addContainerGap(-1, 32767))); + this.pack(); + this.addAllNPCs(); + } + + public static void main(String[] args) throws IOException { + STORE = new Store("cache/", false); + EventQueue.invokeLater(new Runnable() { + public void run() { + (new NPCSelection()).setVisible(true); + } + }); + } + + private void exitButtonActionPerformed(ActionEvent evt) { + this.dispose(); + } + + public int getNewNPCID() { + try { + JFrame var3 = new JFrame(); + String parent1 = JOptionPane.showInputDialog(var3, "Enter new NPC ID:"); + return Integer.parseInt(parent1.toString()); + } catch (Exception var31) { + JFrame parent = new JFrame(); + JOptionPane.showMessageDialog(parent, "Please enter a valid integer!"); + Main.log("NPCSelection", "Non-valid character entered for new NPC ID"); + return -1; + } + } + + public void addAllNPCs() { + for(int id = 0; id < Utils.getNPCDefinitionsSize(STORE)/* - 15615*/; ++id) { + this.addNPCDefs(NPCDefinitions.getNPCDefinition(STORE, id)); + } + + Main.log("NPCSelection", "All NPCs Loaded"); + } + + public void addNPCDefs(final NPCDefinitions defs) { + EventQueue.invokeLater(new Runnable() { + public void run() { + NPCSelection.this.npcsListmodel.addElement(defs); + } + }); + } + + public void updateNPCDefs(final NPCDefinitions defs) { + EventQueue.invokeLater(new Runnable() { + public void run() { + int index = NPCSelection.this.npcsListmodel.indexOf(defs); + if(index == -1) { + NPCSelection.this.npcsListmodel.addElement(defs); + } else { + NPCSelection.this.npcsListmodel.setElementAt(defs, index); + } + + } + }); + } + + public void removeNPCDefs(final NPCDefinitions defs) { + EventQueue.invokeLater(new Runnable() { + public void run() { + NPCSelection.this.npcsListmodel.removeElement(defs); + } + }); + } +} diff --git a/Tools/Frostys Cache Editor/src/com/editor/object/ObjectEditor.java b/Tools/Frostys Cache Editor/src/com/editor/object/ObjectEditor.java new file mode 100644 index 0000000..e36524c --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/editor/object/ObjectEditor.java @@ -0,0 +1,457 @@ +package com.editor.object; + +import com.alex.loaders.objects.ObjectDefinitions; +import com.editor.Main; +import com.editor.object.ObjectSelection; + +import javax.swing.GroupLayout.Alignment; +import javax.swing.LayoutStyle.ComponentPlacement; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class ObjectEditor extends JFrame { + private ObjectDefinitions defs; + private ObjectSelection os; + private JTextField ModelOffset1; + private JTextField ModelRot2; + private JMenuItem addModelMenuBtn; + private JTextField array1; + private JTextField array2; + private JTextField array3; + private JTextField array4; + private JTextField array5; + private JTextField array6; + private JTextField csk1; + private JTextField csk2; + private JTextField csk3; + private JTextField csk4; + private JTextField csk5; + private JTextField csk6; + private JTextField csk7; + private JTextField csv1; + private JTextField csv2; + private JTextField csv3; + private JTextField csv4; + private JTextField csv5; + private JTextField csv6; + private JTextField csv7; + private JLabel currentViewLabel; + private JTextField equipSlot; + private JTextField equipType; + private JMenuItem exitMenuBtn; + private JMenuItem exportMenuBtn; + private JTextField femaleEquip1; + private JTextField femaleEquip2; + private JTextField femaleEquip3; + private JTextField groundOptions; + private JTextField int1; + private JTextField int10; + private JTextField int11; + private JTextField int12; + private JTextField int13; + private JTextField int14; + private JTextField int15; + private JTextField int16; + private JTextField int17; + private JTextField int18; + private JTextField int19; + private JTextField int2; + private JTextField int20; + private JTextField int21; + private JTextField int22; + private JTextField int23; + private JTextField int3; + private JTextField int4; + private JTextField int5; + private JTextField int6; + private JTextField int7; + private JTextField int8; + private JTextField int9; + private JTextField invModel; + private JTextField invModelZoom; + private JTextField invOptions; + private JTextField objectName; + private JLabel jLabel1; + private JLabel jLabel10; + private JLabel jLabel11; + private JLabel jLabel12; + private JLabel jLabel13; + private JLabel jLabel14; + private JLabel jLabel15; + private JLabel jLabel16; + private JLabel jLabel17; + private JLabel jLabel18; + private JLabel jLabel19; + private JLabel jLabel2; + private JLabel jLabel20; + private JLabel jLabel21; + private JLabel jLabel22; + private JLabel jLabel23; + private JLabel jLabel24; + private JLabel jLabel25; + private JLabel jLabel26; + private JLabel jLabel27; + private JLabel jLabel28; + private JLabel jLabel29; + private JLabel jLabel3; + private JLabel jLabel30; + private JLabel jLabel31; + private JLabel jLabel32; + private JLabel jLabel33; + private JLabel jLabel34; + private JLabel jLabel35; + private JLabel jLabel36; + private JLabel jLabel37; + private JLabel jLabel38; + private JLabel jLabel39; + private JLabel jLabel4; + private JLabel jLabel40; + private JLabel jLabel41; + private JLabel jLabel42; + private JLabel jLabel43; + private JLabel jLabel44; + private JLabel jLabel45; + private JLabel jLabel46; + private JLabel jLabel47; + private JLabel jLabel48; + private JLabel jLabel49; + private JLabel jLabel5; + private JLabel jLabel50; + private JLabel jLabel51; + private JLabel jLabel52; + private JLabel jLabel53; + private JLabel jLabel54; + private JLabel jLabel55; + private JLabel jLabel56; + private JLabel jLabel57; + private JLabel jLabel58; + private JLabel jLabel59; + private JLabel jLabel6; + private JLabel jLabel60; + private JLabel jLabel61; + private JLabel jLabel7; + private JLabel jLabel8; + private JLabel jLabel9; + private JMenu jMenu1; + private JMenuBar jMenuBar1; + private JPanel jPanel1; + private JPanel jPanel2; + private JPanel jPanel3; + private JPanel jPanel5; + private JPanel jPanel6; + private JPanel jPanel7; + private JScrollPane jScrollPane1; + private JTabbedPane jTabbedPane1; + private JTextField lend; + private JTextField maleEquip1; + private JTextField maleEquip2; + private JTextField maleEquip3; + private JCheckBox membersOnly; + private JTextField modelColors; + private JTextField modelOffset2; + private JTextField modelRot1; + private JTextField note; + private JMenuItem reloadMenuBtn; + private JMenuItem saveMenuBtn; + private JTextField stackAmts; + private JTextField stackIDs; + private JTextField stackable; + public JTextField switchLend; + public JTextField switchNote; + public JTextField sizeY; + public JTextField textureColors; + public JCheckBox unnoted; + public JTextField sizeX; + + + public ObjectEditor(ObjectSelection os, ObjectDefinitions defs) { + this.defs = defs; + this.os = os; + this.initComponents(); + this.setResizable(false); + this.setTitle("Object Editor"); + this.setDefaultCloseOperation(1); + this.setLocationRelativeTo((Component)null); + this.setVisible(true); + } + + private void initComponents() { + this.jTabbedPane1 = new JTabbedPane(); + this.jPanel1 = new JPanel(); + this.jLabel1 = new JLabel(); + this.objectName = new JTextField(); + this.jLabel2 = new JLabel(); + this.sizeX = new JTextField(); + this.sizeY = new JTextField(); + this.jLabel3 = new JLabel(); + this.membersOnly = new JCheckBox(); + this.jLabel20 = new JLabel(); + this.equipSlot = new JTextField(); + this.jLabel21 = new JLabel(); + this.equipType = new JTextField(); + this.jLabel22 = new JLabel(); + this.stackIDs = new JTextField(); + this.jLabel23 = new JLabel(); + this.stackAmts = new JTextField(); + this.jLabel24 = new JLabel(); + this.stackable = new JTextField(); + this.jLabel58 = new JLabel(); + this.switchNote = new JTextField(); + this.jLabel59 = new JLabel(); + this.note = new JTextField(); + this.unnoted = new JCheckBox(); + this.jLabel60 = new JLabel(); + this.jLabel61 = new JLabel(); + this.switchLend = new JTextField(); + this.lend = new JTextField(); + this.jPanel2 = new JPanel(); + this.jLabel4 = new JLabel(); + this.invModelZoom = new JTextField(); + this.jLabel5 = new JLabel(); + this.modelRot1 = new JTextField(); + this.jLabel6 = new JLabel(); + this.ModelRot2 = new JTextField(); + this.jLabel7 = new JLabel(); + this.ModelOffset1 = new JTextField(); + this.jLabel8 = new JLabel(); + this.modelOffset2 = new JTextField(); + this.jLabel9 = new JLabel(); + this.invModel = new JTextField(); + this.jLabel10 = new JLabel(); + this.maleEquip1 = new JTextField(); + this.jLabel11 = new JLabel(); + this.femaleEquip1 = new JTextField(); + this.jLabel12 = new JLabel(); + this.maleEquip2 = new JTextField(); + this.jLabel13 = new JLabel(); + this.femaleEquip2 = new JTextField(); + this.jLabel14 = new JLabel(); + this.maleEquip3 = new JTextField(); + this.jLabel15 = new JLabel(); + this.femaleEquip3 = new JTextField(); + this.jPanel3 = new JPanel(); + this.jLabel16 = new JLabel(); + this.invOptions = new JTextField(); + this.jLabel17 = new JLabel(); + this.groundOptions = new JTextField(); + this.jLabel18 = new JLabel(); + this.modelColors = new JTextField(); + this.jLabel19 = new JLabel(); + this.textureColors = new JTextField(); + this.jPanel5 = new JPanel(); + this.jLabel25 = new JLabel(); + this.array1 = new JTextField(); + this.jLabel27 = new JLabel(); + this.jLabel28 = new JLabel(); + this.jLabel29 = new JLabel(); + this.jLabel30 = new JLabel(); + this.jLabel31 = new JLabel(); + this.array2 = new JTextField(); + this.array3 = new JTextField(); + this.array4 = new JTextField(); + this.array5 = new JTextField(); + this.array6 = new JTextField(); + this.jLabel32 = new JLabel(); + this.int1 = new JTextField(); + this.int2 = new JTextField(); + this.jLabel33 = new JLabel(); + this.jLabel34 = new JLabel(); + this.int3 = new JTextField(); + this.jLabel35 = new JLabel(); + this.int4 = new JTextField(); + this.jLabel36 = new JLabel(); + this.int5 = new JTextField(); + this.jLabel37 = new JLabel(); + this.int6 = new JTextField(); + this.jLabel38 = new JLabel(); + this.int7 = new JTextField(); + this.jLabel39 = new JLabel(); + this.int8 = new JTextField(); + this.jLabel40 = new JLabel(); + this.int9 = new JTextField(); + this.jLabel41 = new JLabel(); + this.int10 = new JTextField(); + this.jLabel42 = new JLabel(); + this.int11 = new JTextField(); + this.jLabel43 = new JLabel(); + this.int12 = new JTextField(); + this.jLabel44 = new JLabel(); + this.int13 = new JTextField(); + this.jLabel45 = new JLabel(); + this.int14 = new JTextField(); + this.jPanel6 = new JPanel(); + this.jLabel46 = new JLabel(); + this.int15 = new JTextField(); + this.jLabel47 = new JLabel(); + this.int16 = new JTextField(); + this.jLabel48 = new JLabel(); + this.int17 = new JTextField(); + this.jLabel49 = new JLabel(); + this.int18 = new JTextField(); + this.jLabel50 = new JLabel(); + this.int19 = new JTextField(); + this.jLabel51 = new JLabel(); + this.int20 = new JTextField(); + this.jLabel52 = new JLabel(); + this.int21 = new JTextField(); + this.jLabel53 = new JLabel(); + this.int22 = new JTextField(); + this.jLabel54 = new JLabel(); + this.int23 = new JTextField(); + this.jPanel7 = new JPanel(); + this.jScrollPane1 = new JScrollPane(); + this.jLabel26 = new JLabel(); + this.jLabel55 = new JLabel(); + this.jLabel56 = new JLabel(); + this.jLabel57 = new JLabel(); + this.csk1 = new JTextField(); + this.csk2 = new JTextField(); + this.csk3 = new JTextField(); + this.csk4 = new JTextField(); + this.csk5 = new JTextField(); + this.csk6 = new JTextField(); + this.csk7 = new JTextField(); + this.csv1 = new JTextField(); + this.csv2 = new JTextField(); + this.csv3 = new JTextField(); + this.csv4 = new JTextField(); + this.csv5 = new JTextField(); + this.csv6 = new JTextField(); + this.csv7 = new JTextField(); + this.currentViewLabel = new JLabel(); + this.jMenuBar1 = new JMenuBar(); + this.jMenu1 = new JMenu(); + this.reloadMenuBtn = new JMenuItem(); + this.saveMenuBtn = new JMenuItem(); + this.addModelMenuBtn = new JMenuItem(); + this.exportMenuBtn = new JMenuItem(); + this.exitMenuBtn = new JMenuItem(); + this.setDefaultCloseOperation(3); + this.jLabel1.setText("Name"); + this.objectName.setText("" + this.defs.name); + this.jLabel2.setText("Size X"); + this.sizeX.setText("" + this.defs.sizeX); + this.sizeY.setText("" + this.defs.sizeY); + this.jLabel3.setText("Size Y"); + this.membersOnly.setSelected(true); + this.membersOnly.setText("Projectile Clipped"); + this.jLabel20.setText("Animation"); + this.equipSlot.setText(""); + this.jLabel21.setText("Equip Type"); + this.equipType.setText(""); + this.jLabel22.setText("ConfigFileID"); + this.stackIDs.setText(""); + this.jLabel23.setText("ConfigID"); + this.stackAmts.setText(""); + this.jLabel24.setText("Clip Type"); + this.stackable.setText(""); + this.jLabel58.setText("Switch Note Item ID"); + this.switchNote.setText(""); + this.jLabel59.setText("Noted Item ID"); + this.note.setText(""); + this.unnoted.setSelected(true); + this.unnoted.setText("Unnoted"); + this.jLabel60.setText("Switch Lend Item ID"); + this.jLabel61.setText("Lent Item ID"); + this.switchLend.setText(""); + this.lend.setText(""); + GroupLayout jPanel1Layout = new GroupLayout(this.jPanel1); + this.jPanel1.setLayout(jPanel1Layout); + jPanel1Layout.setHorizontalGroup(jPanel1Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel1Layout.createSequentialGroup().addContainerGap().addGroup(jPanel1Layout.createParallelGroup(Alignment.LEADING).addComponent(this.unnoted).addComponent(this.membersOnly).addGroup(jPanel1Layout.createSequentialGroup().addComponent(this.jLabel20).addPreferredGap(ComponentPlacement.UNRELATED).addComponent(this.equipSlot, -2, 100, -2)).addGroup(jPanel1Layout.createSequentialGroup().addGroup(jPanel1Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel1Layout.createSequentialGroup().addComponent(this.jLabel1).addGap(18, 18, 18).addComponent(this.objectName, -2, 100, -2)).addGroup(jPanel1Layout.createSequentialGroup().addGroup(jPanel1Layout.createParallelGroup(Alignment.LEADING).addComponent(this.jLabel2).addComponent(this.jLabel3)).addGap(18, 18, 18).addGroup(jPanel1Layout.createParallelGroup(Alignment.LEADING).addComponent(this.sizeY, -2, 100, -2).addComponent(this.sizeX, -2, 100, -2))).addGroup(jPanel1Layout.createSequentialGroup().addComponent(this.jLabel24).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.stackable, -2, 100, -2))).addGap(126, 126, 126).addGroup(jPanel1Layout.createParallelGroup(Alignment.LEADING).addComponent(this.stackAmts, -2, 300, -2).addComponent(this.stackIDs, -2, 300, -2).addComponent(this.jLabel22).addComponent(this.jLabel23))).addGroup(jPanel1Layout.createSequentialGroup().addComponent(this.jLabel21).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.equipType, -2, 100, -2)).addGroup(jPanel1Layout.createSequentialGroup().addGroup(jPanel1Layout.createParallelGroup(Alignment.LEADING).addComponent(this.jLabel58).addComponent(this.jLabel59)).addPreferredGap(ComponentPlacement.UNRELATED).addGroup(jPanel1Layout.createParallelGroup(Alignment.LEADING, false).addComponent(this.switchNote, -1, 100, 32767).addComponent(this.note)).addGap(18, 18, 18).addGroup(jPanel1Layout.createParallelGroup(Alignment.LEADING).addComponent(this.jLabel60).addComponent(this.jLabel61)).addPreferredGap(ComponentPlacement.UNRELATED).addGroup(jPanel1Layout.createParallelGroup(Alignment.LEADING, false).addComponent(this.switchLend, -1, 100, 32767).addComponent(this.lend)))).addContainerGap(36, 32767))); + jPanel1Layout.setVerticalGroup(jPanel1Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel1Layout.createSequentialGroup().addContainerGap().addGroup(jPanel1Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel1).addComponent(this.objectName, -2, -1, -2).addComponent(this.jLabel22)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel1Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel1Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.sizeX, -2, -1, -2).addComponent(this.jLabel2)).addComponent(this.stackIDs, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel1Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.sizeY, -2, -1, -2).addComponent(this.jLabel3).addComponent(this.jLabel23)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel1Layout.createParallelGroup(Alignment.LEADING).addComponent(this.stackAmts, -2, -1, -2).addGroup(jPanel1Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel24).addComponent(this.stackable, -2, -1, -2))).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.membersOnly).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel1Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel20).addComponent(this.equipSlot, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel1Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel21).addComponent(this.equipType, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel1Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel58).addComponent(this.switchNote, -2, -1, -2).addComponent(this.jLabel60).addComponent(this.switchLend, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel1Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel59).addComponent(this.note, -2, -1, -2).addComponent(this.jLabel61).addComponent(this.lend, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.unnoted).addContainerGap(13, 32767))); + this.jTabbedPane1.addTab("General", this.jPanel1); + this.jLabel4.setText("Inventory Model Zoom"); + this.invModelZoom.setText(""); + this.jLabel5.setText("Model Rotation 1"); + this.modelRot1.setText(""); + this.jLabel6.setText("Model Rotation 2"); + this.ModelRot2.setText(""); + this.jLabel7.setText("Model Offset 1"); + this.ModelOffset1.setText(""); + this.jLabel8.setText("Model Offset 2"); + this.modelOffset2.setText(""); + this.jLabel9.setText("Inventory Model"); + this.invModel.setText(""); + this.jLabel10.setText("Male Equip 1"); + this.maleEquip1.setText(""); + this.jLabel11.setText("Female Equip 1"); + this.femaleEquip1.setText(""); + this.jLabel12.setText("Male Equip 2"); + this.maleEquip2.setText(""); + this.jLabel13.setText("Female Equip 2"); + this.femaleEquip2.setText(""); + this.jLabel14.setText("Male Equip 3"); + this.maleEquip3.setText(""); + this.jLabel15.setText("Female Equip 3"); + this.femaleEquip3.setText(""); + GroupLayout jPanel2Layout = new GroupLayout(this.jPanel2); + this.jPanel2.setLayout(jPanel2Layout); + jPanel2Layout.setHorizontalGroup(jPanel2Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel2Layout.createSequentialGroup().addContainerGap().addGroup(jPanel2Layout.createParallelGroup(Alignment.LEADING, false).addGroup(jPanel2Layout.createSequentialGroup().addComponent(this.jLabel7).addPreferredGap(ComponentPlacement.RELATED, -1, 32767).addComponent(this.ModelOffset1, -2, 100, -2)).addGroup(jPanel2Layout.createSequentialGroup().addGroup(jPanel2Layout.createParallelGroup(Alignment.LEADING).addComponent(this.jLabel4).addComponent(this.jLabel5).addComponent(this.jLabel6)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel2Layout.createParallelGroup(Alignment.LEADING).addComponent(this.ModelRot2, -2, 100, -2).addComponent(this.modelRot1, -2, 100, -2).addComponent(this.invModelZoom, -2, 100, -2))).addGroup(Alignment.TRAILING, jPanel2Layout.createSequentialGroup().addComponent(this.jLabel8).addPreferredGap(ComponentPlacement.RELATED, -1, 32767).addComponent(this.modelOffset2, -2, 100, -2))).addGap(114, 114, 114).addGroup(jPanel2Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel2Layout.createSequentialGroup().addComponent(this.jLabel15).addPreferredGap(ComponentPlacement.UNRELATED).addComponent(this.femaleEquip3, -2, 100, -2)).addGroup(jPanel2Layout.createSequentialGroup().addGroup(jPanel2Layout.createParallelGroup(Alignment.LEADING).addComponent(this.jLabel9).addComponent(this.jLabel10)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel2Layout.createParallelGroup(Alignment.LEADING).addComponent(this.maleEquip1, -2, 100, -2).addComponent(this.invModel, -2, 100, -2))).addGroup(jPanel2Layout.createSequentialGroup().addGroup(jPanel2Layout.createParallelGroup(Alignment.LEADING).addComponent(this.jLabel11).addComponent(this.jLabel12)).addPreferredGap(ComponentPlacement.UNRELATED).addGroup(jPanel2Layout.createParallelGroup(Alignment.LEADING).addComponent(this.maleEquip2, -2, 100, -2).addComponent(this.femaleEquip1, -2, 100, -2))).addGroup(jPanel2Layout.createParallelGroup(Alignment.TRAILING, false).addGroup(jPanel2Layout.createSequentialGroup().addComponent(this.jLabel14).addPreferredGap(ComponentPlacement.RELATED, -1, 32767).addComponent(this.maleEquip3, -2, 100, -2)).addGroup(jPanel2Layout.createSequentialGroup().addComponent(this.jLabel13).addPreferredGap(ComponentPlacement.UNRELATED).addComponent(this.femaleEquip2, -2, 100, -2)))).addContainerGap(103, 32767))); + jPanel2Layout.setVerticalGroup(jPanel2Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel2Layout.createSequentialGroup().addContainerGap().addGroup(jPanel2Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel4).addComponent(this.invModelZoom, -2, -1, -2).addComponent(this.jLabel9).addComponent(this.invModel, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel2Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel5).addComponent(this.modelRot1, -2, -1, -2).addComponent(this.jLabel10).addComponent(this.maleEquip1, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel2Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel6).addComponent(this.ModelRot2, -2, -1, -2).addComponent(this.jLabel11).addComponent(this.femaleEquip1, -2, -1, -2)).addGroup(jPanel2Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel2Layout.createSequentialGroup().addGap(9, 9, 9).addGroup(jPanel2Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel7).addComponent(this.ModelOffset1, -2, -1, -2).addComponent(this.jLabel12)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel2Layout.createParallelGroup(Alignment.TRAILING).addComponent(this.jLabel8).addComponent(this.modelOffset2, -2, -1, -2).addGroup(Alignment.LEADING, jPanel2Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel13).addComponent(this.femaleEquip2, -2, -1, -2)))).addGroup(jPanel2Layout.createSequentialGroup().addPreferredGap(ComponentPlacement.RELATED).addComponent(this.maleEquip2, -2, -1, -2))).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel2Layout.createParallelGroup(Alignment.BASELINE).addComponent(this.jLabel14).addComponent(this.maleEquip3, -2, -1, -2)).addPreferredGap(ComponentPlacement.RELATED).addGroup(jPanel2Layout.createParallelGroup(Alignment.LEADING).addComponent(this.jLabel15).addComponent(this.femaleEquip3, -2, -1, -2)).addContainerGap(82, 32767))); + this.jTabbedPane1.addTab("Model", this.jPanel2); + this.jLabel16.setText("Inventory Options"); + this.invOptions.setText("riggg"); + this.jLabel17.setText("Ground Options"); + this.groundOptions.setText("44"); + this.jLabel18.setText("Model Colors"); + this.modelColors.setText("1"); + this.jLabel19.setText("Texture Colors"); + this.textureColors.setText("2"); + GroupLayout jPanel3Layout = new GroupLayout(this.jPanel3); + this.jPanel3.setLayout(jPanel3Layout); + jPanel3Layout.setHorizontalGroup(jPanel3Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel3Layout.createSequentialGroup().addContainerGap().addGroup(jPanel3Layout.createParallelGroup(Alignment.LEADING).addComponent(this.jLabel16).addComponent(this.invOptions, -2, 300, -2).addComponent(this.jLabel17).addComponent(this.groundOptions, -2, 300, -2).addComponent(this.jLabel18).addComponent(this.modelColors, -2, 300, -2).addComponent(this.jLabel19).addComponent(this.textureColors, -2, 300, -2)).addContainerGap(312, 32767))); + jPanel3Layout.setVerticalGroup(jPanel3Layout.createParallelGroup(Alignment.LEADING).addGroup(jPanel3Layout.createSequentialGroup().addContainerGap().addComponent(this.jLabel16).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.invOptions, -2, -1, -2).addGap(18, 18, 18).addComponent(this.jLabel17).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.groundOptions, -2, -1, -2).addGap(18, 18, 18).addComponent(this.jLabel18).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.modelColors, -2, -1, -2).addGap(18, 18, 18).addComponent(this.jLabel19).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.textureColors, -2, -1, -2).addContainerGap(47, 32767))); + this.jTabbedPane1.addTab("Options", this.jPanel3); + this.currentViewLabel.setText("Currently Viewing Definitions of Object: " + this.defs.id + " - " + defs.name); + this.jMenu1.setText("File"); + this.reloadMenuBtn.setText("Reload"); + this.reloadMenuBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + ObjectEditor.this.reloadMenuBtnActionPerformed(evt); + } + }); + this.jMenu1.add(this.reloadMenuBtn); + this.saveMenuBtn.setText("Save"); + this.saveMenuBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + ObjectEditor.this.saveMenuBtnActionPerformed(evt); + } + }); + this.jMenu1.add(this.saveMenuBtn); + this.exitMenuBtn.setText("Exit"); + this.exitMenuBtn.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + ObjectEditor.this.exitMenuBtnActionPerformed(evt); + } + }); + this.jMenu1.add(this.exitMenuBtn); + this.jMenuBar1.add(this.jMenu1); + this.setJMenuBar(this.jMenuBar1); + GroupLayout layout = new GroupLayout(this.getContentPane()); + this.getContentPane().setLayout(layout); + layout.setHorizontalGroup(layout.createParallelGroup(Alignment.LEADING).addComponent(this.jTabbedPane1).addGroup(layout.createSequentialGroup().addContainerGap().addComponent(this.currentViewLabel).addContainerGap(-1, 32767))); + layout.setVerticalGroup(layout.createParallelGroup(Alignment.LEADING).addGroup(Alignment.TRAILING, layout.createSequentialGroup().addGap(0, 11, 32767).addComponent(this.currentViewLabel).addPreferredGap(ComponentPlacement.RELATED).addComponent(this.jTabbedPane1, -2, 300, -2))); + this.pack(); + } + + private void save() { + try { + this.defs.setName(this.objectName.getText().toString()); + } catch (Exception var201) { + Main.log("ObjectEditor", "Cannot save. Please check for mistypes."); + } + } + + private void saveMenuBtnActionPerformed(ActionEvent evt) { + this.save(); + } + + private void reloadMenuBtnActionPerformed(ActionEvent evt) { + this.objectName.setText(this.defs.getName()); + this.sizeX.setText("" + this.defs.sizeX); + } + + private void exitMenuBtnActionPerformed(ActionEvent evt) { + this.dispose(); + } + } diff --git a/Tools/Frostys Cache Editor/src/com/editor/object/ObjectSelection.java b/Tools/Frostys Cache Editor/src/com/editor/object/ObjectSelection.java new file mode 100644 index 0000000..fa6e92e --- /dev/null +++ b/Tools/Frostys Cache Editor/src/com/editor/object/ObjectSelection.java @@ -0,0 +1,205 @@ +package com.editor.object; + +import com.alex.loaders.objects.ObjectDefinitions; +import com.alex.store.Store; +import com.editor.Main; +import com.editor.object.ObjectEditor; + +import javax.swing.GroupLayout.Alignment; +import javax.swing.LayoutStyle.ComponentPlacement; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.IOException; + +public class ObjectSelection extends JFrame { + private static final long serialVersionUID = -3068337441331467664L; + public static Store STORE; + private JButton addButton; + private JButton duplicateButton; + private JButton editButton; + private DefaultListModel objectsListmodel; + private JList objectsList; + private JMenu jMenu1; + private JMenuBar jMenuBar1; + private JMenuItem exitButton; + private JButton deleteButton; + + public ObjectSelection(String cache) throws IOException { + STORE = new Store(cache); + this.setTitle("Object Selection"); + this.setResizable(false); + this.setDefaultCloseOperation(1); + this.setLocationRelativeTo((Component)null); + this.initComponents(); + } + + public ObjectSelection() { + this.initComponents(); + } + + private void initComponents() { + this.editButton = new JButton(); + this.addButton = new JButton(); + this.duplicateButton = new JButton(); + this.deleteButton = new JButton(); + this.jMenuBar1 = new JMenuBar(); + this.jMenu1 = new JMenu(); + this.exitButton = new JMenuItem(); + this.setDefaultCloseOperation(1); + this.objectsListmodel = new DefaultListModel(); + this.objectsList = new JList(this.objectsListmodel); + this.objectsList.setSelectionMode(1); + this.objectsList.setLayoutOrientation(0); + this.objectsList.setVisibleRowCount(-1); + JScrollPane jScrollPane1 = new JScrollPane(this.objectsList); + this.editButton.setText("Edit"); + this.editButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + ObjectDefinitions defs = (ObjectDefinitions)ObjectSelection.this.objectsList.getSelectedValue(); + if(defs != null) { + new ObjectEditor(ObjectSelection.this, defs); + } + + } + }); + this.addButton.setText("Add New"); + this.addButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + ObjectDefinitions defs = new ObjectDefinitions(ObjectSelection.STORE, ObjectSelection.this.getNewObjectID(), false); + if(defs != null && defs.id != -1) { + new ObjectEditor(ObjectSelection.this, defs); + } + + } + }); + this.duplicateButton.setText("Duplicate"); + this.duplicateButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + ObjectDefinitions defs = (ObjectDefinitions)ObjectSelection.this.objectsList.getSelectedValue(); + if(defs != null) { + // defs = (ObjectDefinitions)defs.clone(); + if(defs != null) { + defs.id = ObjectSelection.this.getNewObjectID(); + if(defs.id != -1) { + new ObjectEditor(ObjectSelection.this, defs); + } + } + } + + } + }); + this.deleteButton.setText("Delete"); + this.deleteButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + ObjectDefinitions defs = (ObjectDefinitions)ObjectSelection.this.objectsList.getSelectedValue(); + JFrame frame = new JFrame(); + int result = JOptionPane.showConfirmDialog(frame, "Do you really want to delete Object " + defs.id); + if(result == 0) { + if(defs == null) { + return; + } + + ObjectSelection.STORE.getIndexes()[19].removeFile(defs.getArchiveId(), defs.getFileId()); + ObjectSelection.this.removeObjectDefs(defs); + Main.log("ObjectSelection", "Object " + defs.id + " removed."); + } + + } + }); + this.jMenu1.setText("File"); + this.exitButton.setText("Close"); + this.exitButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + ObjectSelection.this.exitButtonActionPerformed(evt); + } + }); + this.jMenu1.add(this.exitButton); + this.jMenuBar1.add(this.jMenu1); + this.setJMenuBar(this.jMenuBar1); + GroupLayout layout = new GroupLayout(this.getContentPane()); + this.getContentPane().setLayout(layout); + layout.setHorizontalGroup(layout.createParallelGroup(Alignment.LEADING).addGroup(layout.createSequentialGroup().addContainerGap().addGroup(layout.createParallelGroup(Alignment.LEADING).addGroup(layout.createSequentialGroup().addGroup(layout.createParallelGroup(Alignment.LEADING, false).addComponent(jScrollPane1, -2, 200, -2).addGroup(layout.createSequentialGroup().addComponent(this.editButton).addPreferredGap(ComponentPlacement.RELATED, -1, 32767).addComponent(this.addButton))).addGap(0, 0, 32767)).addGroup(layout.createSequentialGroup().addComponent(this.duplicateButton).addPreferredGap(ComponentPlacement.RELATED, -1, 32767).addComponent(this.deleteButton))).addContainerGap(-1, 32767))); + layout.setVerticalGroup(layout.createParallelGroup(Alignment.LEADING).addGroup(layout.createSequentialGroup().addContainerGap().addComponent(jScrollPane1, -2, 279, -2).addPreferredGap(ComponentPlacement.RELATED).addGroup(layout.createParallelGroup(Alignment.BASELINE).addComponent(this.editButton).addComponent(this.addButton)).addPreferredGap(ComponentPlacement.RELATED).addGroup(layout.createParallelGroup(Alignment.BASELINE).addComponent(this.duplicateButton).addComponent(this.deleteButton)).addContainerGap(-1, 32767))); + this.pack(); + this.addAllObjects(); + } + + public static void main(String[] args) throws IOException { + STORE = new Store("cache/", false); + EventQueue.invokeLater(new Runnable() { + public void run() { + (new ObjectSelection()).setVisible(true); + } + }); + } + + private void exitButtonActionPerformed(ActionEvent evt) { + this.dispose(); + } + + public int getNewObjectID() { + try { + JFrame var3 = new JFrame(); + String parent1 = JOptionPane.showInputDialog(var3, "Enter new Object ID:"); + return Integer.parseInt(parent1.toString()); + } catch (Exception var31) { + JFrame parent = new JFrame(); + JOptionPane.showMessageDialog(parent, "Please enter a valid integer!"); + Main.log("ObjectSelection", "Non-valid character entered for new Object ID"); + return -1; + } + } + + public void addAllObjects() { + for(int id = 36770; id < /*Utils.getObjectDefinitionsSize(STORE)*/36773; ++id) { + addObjectDefs(ObjectDefinitions.getObjectDefinition(STORE, id)); + } + + Main.log("ObjectSelection", "All Objects Loaded"); + } + + /*public void addAllObjects() { + int id; + if(Utils.getObjectDefinitionsSize(STORE) > 30000) { + for(id = 0; id < Utils.getObjectDefinitionsSize(STORE) - 22314; ++id) { + this.addObjectDefs(ObjectDefinitions.getObjectDefinition(STORE, id)); + } + } else { + for(id = 0; id < Utils.getObjectDefinitionsSize(STORE); ++id) { + this.addObjectDefs(ObjectDefinitions.getObjectDefinition(STORE, id)); + } + } + + Main.log("ObjectSelection", "All Objects Loaded"); + }*/ + + public void addObjectDefs(final ObjectDefinitions defs) { + EventQueue.invokeLater(new Runnable() { + public void run() { + ObjectSelection.this.objectsListmodel.addElement(defs); + } + }); + } + + public void updateObjectDefs(final ObjectDefinitions defs) { + EventQueue.invokeLater(new Runnable() { + public void run() { + int index = ObjectSelection.this.objectsListmodel.indexOf(defs); + if(index == -1) { + ObjectSelection.this.objectsListmodel.addElement(defs); + } else { + ObjectSelection.this.objectsListmodel.setElementAt(defs, index); + } + + } + }); + } + + public void removeObjectDefs(final ObjectDefinitions defs) { + EventQueue.invokeLater(new Runnable() { + public void run() { + ObjectSelection.this.objectsListmodel.removeElement(defs); + } + }); + } +} diff --git a/Tools/Frostys Cache Editor/src/org/apache/tools/bzip2/BZip2Constants.java b/Tools/Frostys Cache Editor/src/org/apache/tools/bzip2/BZip2Constants.java new file mode 100644 index 0000000..56f0e60 --- /dev/null +++ b/Tools/Frostys Cache Editor/src/org/apache/tools/bzip2/BZip2Constants.java @@ -0,0 +1,15 @@ +package org.apache.tools.bzip2; + +public interface BZip2Constants { + int baseBlockSize = 100000; + int MAX_ALPHA_SIZE = 258; + int MAX_CODE_LEN = 23; + int RUNA = 0; + int RUNB = 1; + int N_GROUPS = 6; + int G_SIZE = 50; + int N_ITERS = 4; + int MAX_SELECTORS = 18002; + int NUM_OVERSHOOT_BYTES = 20; + int[] rNums = new int[]{619, 720, 127, 481, 931, 816, 813, 233, 566, 247, 985, 724, 205, 454, 863, 491, 741, 242, 949, 214, 733, 859, 335, 708, 621, 574, 73, 654, 730, 472, 419, 436, 278, 496, 867, 210, 399, 680, 480, 51, 878, 465, 811, 169, 869, 675, 611, 697, 867, 561, 862, 687, 507, 283, 482, 129, 807, 591, 733, 623, 150, 238, 59, 379, 684, 877, 625, 169, 643, 105, 170, 607, 520, 932, 727, 476, 693, 425, 174, 647, 73, 122, 335, 530, 442, 853, 695, 249, 445, 515, 909, 545, 703, 919, 874, 474, 882, 500, 594, 612, 641, 801, 220, 162, 819, 984, 589, 513, 495, 799, 161, 604, 958, 533, 221, 400, 386, 867, 600, 782, 382, 596, 414, 171, 516, 375, 682, 485, 911, 276, 98, 553, 163, 354, 666, 933, 424, 341, 533, 870, 227, 730, 475, 186, 263, 647, 537, 686, 600, 224, 469, 68, 770, 919, 190, 373, 294, 822, 808, 206, 184, 943, 795, 384, 383, 461, 404, 758, 839, 887, 715, 67, 618, 276, 204, 918, 873, 777, 604, 560, 951, 160, 578, 722, 79, 804, 96, 409, 713, 940, 652, 934, 970, 447, 318, 353, 859, 672, 112, 785, 645, 863, 803, 350, 139, 93, 354, 99, 820, 908, 609, 772, 154, 274, 580, 184, 79, 626, 630, 742, 653, 282, 762, 623, 680, 81, 927, 626, 789, 125, 411, 521, 938, 300, 821, 78, 343, 175, 128, 250, 170, 774, 972, 275, 999, 639, 495, 78, 352, 126, 857, 956, 358, 619, 580, 124, 737, 594, 701, 612, 669, 112, 134, 694, 363, 992, 809, 743, 168, 974, 944, 375, 748, 52, 600, 747, 642, 182, 862, 81, 344, 805, 988, 739, 511, 655, 814, 334, 249, 515, 897, 955, 664, 981, 649, 113, 974, 459, 893, 228, 433, 837, 553, 268, 926, 240, 102, 654, 459, 51, 686, 754, 806, 760, 493, 403, 415, 394, 687, 700, 946, 670, 656, 610, 738, 392, 760, 799, 887, 653, 978, 321, 576, 617, 626, 502, 894, 679, 243, 440, 680, 879, 194, 572, 640, 724, 926, 56, 204, 700, 707, 151, 457, 449, 797, 195, 791, 558, 945, 679, 297, 59, 87, 824, 713, 663, 412, 693, 342, 606, 134, 108, 571, 364, 631, 212, 174, 643, 304, 329, 343, 97, 430, 751, 497, 314, 983, 374, 822, 928, 140, 206, 73, 263, 980, 736, 876, 478, 430, 305, 170, 514, 364, 692, 829, 82, 855, 953, 676, 246, 369, 970, 294, 750, 807, 827, 150, 790, 288, 923, 804, 378, 215, 828, 592, 281, 565, 555, 710, 82, 896, 831, 547, 261, 524, 462, 293, 465, 502, 56, 661, 821, 976, 991, 658, 869, 905, 758, 745, 193, 768, 550, 608, 933, 378, 286, 215, 979, 792, 961, 61, 688, 793, 644, 986, 403, 106, 366, 905, 644, 372, 567, 466, 434, 645, 210, 389, 550, 919, 135, 780, 773, 635, 389, 707, 100, 626, 958, 165, 504, 920, 176, 193, 713, 857, 265, 203, 50, 668, 108, 645, 990, 626, 197, 510, 357, 358, 850, 858, 364, 936, 638}; +} diff --git a/Tools/Frostys Cache Editor/src/org/apache/tools/bzip2/CBZip2OutputStream.java b/Tools/Frostys Cache Editor/src/org/apache/tools/bzip2/CBZip2OutputStream.java new file mode 100644 index 0000000..b56924d --- /dev/null +++ b/Tools/Frostys Cache Editor/src/org/apache/tools/bzip2/CBZip2OutputStream.java @@ -0,0 +1,1494 @@ +package org.apache.tools.bzip2; + +import org.apache.tools.bzip2.BZip2Constants; +import org.apache.tools.bzip2.CRC; + +import java.io.IOException; +import java.io.OutputStream; + +public class CBZip2OutputStream extends OutputStream implements BZip2Constants { + protected static final int SETMASK = 2097152; + protected static final int CLEARMASK = -2097153; + protected static final int GREATER_ICOST = 15; + protected static final int LESSER_ICOST = 0; + protected static final int SMALL_THRESH = 20; + protected static final int DEPTH_THRESH = 10; + protected static final int QSORT_STACK_SIZE = 1000; + int last; + int origPtr; + int blockSize100k; + boolean blockRandomised; + int bytesOut; + int bsBuff; + int bsLive; + CRC mCrc; + private boolean[] inUse; + private int nInUse; + private char[] seqToUnseq; + private char[] unseqToSeq; + private char[] selector; + private char[] selectorMtf; + private char[] block; + private int[] quadrant; + private int[] zptr; + private short[] szptr; + private int[] ftab; + private int nMTF; + private int[] mtfFreq; + private int workFactor; + private int workDone; + private int workLimit; + private boolean firstAttempt; + private int nBlocksRandomised; + private int currentChar; + private int runLength; + boolean closed; + private int blockCRC; + private int combinedCRC; + private int allowableBlockSize; + private OutputStream bsStream; + private int[] incs; + + private static void panic() { + System.out.println("panic"); + } + + private void makeMaps() { + this.nInUse = 0; + + for(int i = 0; i < 256; ++i) { + if(this.inUse[i]) { + this.seqToUnseq[this.nInUse] = (char)i; + this.unseqToSeq[i] = (char)this.nInUse; + ++this.nInUse; + } + } + + } + + protected static void hbMakeCodeLengths(char[] len, int[] freq, int alphaSize, int maxLen) { + int[] heap = new int[260]; + int[] weight = new int[516]; + int[] parent = new int[516]; + + int i; + for(i = 0; i < alphaSize; ++i) { + weight[i + 1] = (freq[i] == 0?1:freq[i]) << 8; + } + + while(true) { + int nNodes = alphaSize; + int nHeap = 0; + heap[0] = 0; + weight[0] = 0; + parent[0] = -2; + + int zz; + int tmp; + for(i = 1; i <= alphaSize; ++i) { + parent[i] = -1; + ++nHeap; + heap[nHeap] = i; + zz = nHeap; + + for(tmp = heap[nHeap]; weight[tmp] < weight[heap[zz >> 1]]; zz >>= 1) { + heap[zz] = heap[zz >> 1]; + } + + heap[zz] = tmp; + } + + if(nHeap >= 260) { + panic(); + } + + while(nHeap > 1) { + int tooLong = heap[1]; + heap[1] = heap[nHeap]; + --nHeap; + boolean j = false; + boolean k = false; + boolean tmp1 = false; + zz = 1; + int var20 = heap[zz]; + + while(true) { + tmp = zz << 1; + if(tmp > nHeap) { + break; + } + + if(tmp < nHeap && weight[heap[tmp + 1]] < weight[heap[tmp]]) { + ++tmp; + } + + if(weight[var20] < weight[heap[tmp]]) { + break; + } + + heap[zz] = heap[tmp]; + zz = tmp; + } + + heap[zz] = var20; + int n2 = heap[1]; + heap[1] = heap[nHeap]; + --nHeap; + j = false; + k = false; + tmp1 = false; + zz = 1; + var20 = heap[zz]; + + while(true) { + tmp = zz << 1; + if(tmp > nHeap) { + break; + } + + if(tmp < nHeap && weight[heap[tmp + 1]] < weight[heap[tmp]]) { + ++tmp; + } + + if(weight[var20] < weight[heap[tmp]]) { + break; + } + + heap[zz] = heap[tmp]; + zz = tmp; + } + + heap[zz] = var20; + ++nNodes; + parent[tooLong] = parent[n2] = nNodes; + weight[nNodes] = (weight[tooLong] & -256) + (weight[n2] & -256) | 1 + ((weight[tooLong] & 255) > (weight[n2] & 255)?weight[tooLong] & 255:weight[n2] & 255); + parent[nNodes] = -1; + ++nHeap; + heap[nHeap] = nNodes; + j = false; + k = false; + zz = nHeap; + + for(tmp = heap[nHeap]; weight[tmp] < weight[heap[zz >> 1]]; zz >>= 1) { + heap[zz] = heap[zz >> 1]; + } + + heap[zz] = tmp; + } + + if(nNodes >= 516) { + panic(); + } + + boolean var18 = false; + + int var19; + for(i = 1; i <= alphaSize; ++i) { + var19 = 0; + + for(int var201 = i; parent[var201] >= 0; ++var19) { + var201 = parent[var201]; + } + + len[i - 1] = (char)var19; + if(var19 > maxLen) { + var18 = true; + } + } + + if(!var18) { + return; + } + + for(i = 1; i < alphaSize; ++i) { + var19 = weight[i] >> 8; + var19 = 1 + var19 / 2; + weight[i] = var19 << 8; + } + } + } + + public CBZip2OutputStream(OutputStream inStream) throws IOException { + this(inStream, 9); + } + + public CBZip2OutputStream(OutputStream inStream, int inBlockSize) throws IOException { + this.mCrc = new CRC(); + this.inUse = new boolean[256]; + this.seqToUnseq = new char[256]; + this.unseqToSeq = new char[256]; + this.selector = new char[18002]; + this.selectorMtf = new char[18002]; + this.mtfFreq = new int[258]; + this.currentChar = -1; + this.runLength = 0; + this.closed = false; + this.incs = new int[]{1, 4, 13, 40, 121, 364, 1093, 3280, 9841, 29524, 88573, 265720, 797161, 2391484}; + this.block = null; + this.quadrant = null; + this.zptr = null; + this.ftab = null; + this.bsSetStream(inStream); + this.workFactor = 50; + if(inBlockSize > 9) { + inBlockSize = 9; + } + + if(inBlockSize < 1) { + inBlockSize = 1; + } + + this.blockSize100k = inBlockSize; + this.allocateCompressStructures(); + this.initialize(); + this.initBlock(); + } + + public void write(int bv) throws IOException { + int b = (256 + bv) % 256; + if(this.currentChar != -1) { + if(this.currentChar == b) { + ++this.runLength; + if(this.runLength > 254) { + this.writeRun(); + this.currentChar = -1; + this.runLength = 0; + } + } else { + this.writeRun(); + this.runLength = 1; + this.currentChar = b; + } + } else { + this.currentChar = b; + ++this.runLength; + } + + } + + private void writeRun() throws IOException { + if(this.last < this.allowableBlockSize) { + this.inUse[this.currentChar] = true; + + for(int i = 0; i < this.runLength; ++i) { + this.mCrc.updateCRC((char)this.currentChar); + } + + switch(this.runLength) { + case 1: + ++this.last; + this.block[this.last + 1] = (char)this.currentChar; + break; + case 2: + ++this.last; + this.block[this.last + 1] = (char)this.currentChar; + ++this.last; + this.block[this.last + 1] = (char)this.currentChar; + break; + case 3: + ++this.last; + this.block[this.last + 1] = (char)this.currentChar; + ++this.last; + this.block[this.last + 1] = (char)this.currentChar; + ++this.last; + this.block[this.last + 1] = (char)this.currentChar; + break; + default: + this.inUse[this.runLength - 4] = true; + ++this.last; + this.block[this.last + 1] = (char)this.currentChar; + ++this.last; + this.block[this.last + 1] = (char)this.currentChar; + ++this.last; + this.block[this.last + 1] = (char)this.currentChar; + ++this.last; + this.block[this.last + 1] = (char)this.currentChar; + ++this.last; + this.block[this.last + 1] = (char)(this.runLength - 4); + } + } else { + this.endBlock(); + this.initBlock(); + this.writeRun(); + } + + } + + protected void finalize() throws Throwable { + this.close(); + super.finalize(); + } + + public void close() throws IOException { + if(!this.closed) { + if(this.runLength > 0) { + this.writeRun(); + } + + this.currentChar = -1; + this.endBlock(); + this.endCompression(); + this.closed = true; + super.close(); + this.bsStream.close(); + } + + } + + public void flush() throws IOException { + super.flush(); + this.bsStream.flush(); + } + + private void initialize() throws IOException { + this.bytesOut = 0; + this.setnBlocksRandomised(0); + this.bsPutUChar(104); + this.bsPutUChar(48 + this.blockSize100k); + this.combinedCRC = 0; + } + + private void initBlock() { + this.mCrc.initialiseCRC(); + this.last = -1; + + for(int i = 0; i < 256; ++i) { + this.inUse[i] = false; + } + + this.allowableBlockSize = 100000 * this.blockSize100k - 20; + } + + private void endBlock() throws IOException { + this.blockCRC = this.mCrc.getFinalCRC(); + this.combinedCRC = this.combinedCRC << 1 | this.combinedCRC >>> 31; + this.combinedCRC ^= this.blockCRC; + this.doReversibleTransformation(); + this.bsPutUChar(49); + this.bsPutUChar(65); + this.bsPutUChar(89); + this.bsPutUChar(38); + this.bsPutUChar(83); + this.bsPutUChar(89); + this.bsPutint(this.blockCRC); + if(this.blockRandomised) { + this.bsW(1, 1); + this.setnBlocksRandomised(this.getnBlocksRandomised() + 1); + } else { + this.bsW(1, 0); + } + + this.moveToFrontCodeAndSend(); + } + + private void endCompression() throws IOException { + this.bsPutUChar(23); + this.bsPutUChar(114); + this.bsPutUChar(69); + this.bsPutUChar(56); + this.bsPutUChar(80); + this.bsPutUChar(144); + this.bsPutint(this.combinedCRC); + this.bsFinishedWithStream(); + } + + private void hbAssignCodes(int[] code, char[] length, int minLen, int maxLen, int alphaSize) { + int vec = 0; + + for(int n = minLen; n <= maxLen; ++n) { + for(int i = 0; i < alphaSize; ++i) { + if(length[i] == n) { + code[i] = vec++; + } + } + + vec <<= 1; + } + + } + + private void bsSetStream(OutputStream f) { + this.bsStream = f; + this.bsLive = 0; + this.bsBuff = 0; + this.bytesOut = 0; + } + + private void bsFinishedWithStream() throws IOException { + while(this.bsLive > 0) { + int ch = this.bsBuff >> 24; + + try { + this.bsStream.write(ch); + } catch (IOException var3) { + throw var3; + } + + this.bsBuff <<= 8; + this.bsLive -= 8; + ++this.bytesOut; + } + + } + + private void bsW(int n, int v) throws IOException { + while(this.bsLive >= 8) { + int ch = this.bsBuff >> 24; + + try { + this.bsStream.write(ch); + } catch (IOException var5) { + throw var5; + } + + this.bsBuff <<= 8; + this.bsLive -= 8; + ++this.bytesOut; + } + + this.bsBuff |= v << 32 - this.bsLive - n; + this.bsLive += n; + } + + private void bsPutUChar(int c) throws IOException { + this.bsW(8, c); + } + + private void bsPutint(int u) throws IOException { + this.bsW(8, u >> 24 & 255); + this.bsW(8, u >> 16 & 255); + this.bsW(8, u >> 8 & 255); + this.bsW(8, u & 255); + } + + private void bsPutIntVS(int numBits, int c) throws IOException { + this.bsW(numBits, c); + } + + private void sendMTFValues() throws IOException { + char[][] len = new char[6][258]; + int nSelectors = 0; + int alphaSize = this.nInUse + 2; + + int v; + int t; + for(t = 0; t < 6; ++t) { + for(v = 0; v < alphaSize; ++v) { + len[t][v] = 15; + } + } + + if(this.nMTF <= 0) { + panic(); + } + + byte nGroups; + if(this.nMTF < 200) { + nGroups = 2; + } else if(this.nMTF < 600) { + nGroups = 3; + } else if(this.nMTF < 1200) { + nGroups = 4; + } else if(this.nMTF < 2400) { + nGroups = 5; + } else { + nGroups = 6; + } + + int rfreq = nGroups; + int fave = this.nMTF; + + int gs; + int ge; + int code; + for(gs = 0; rfreq > 0; fave -= code) { + int var29 = fave / rfreq; + ge = gs - 1; + + for(code = 0; code < var29 && ge < alphaSize - 1; code += this.mtfFreq[ge]) { + ++ge; + } + + if(ge > gs && rfreq != nGroups && rfreq != 1 && (nGroups - rfreq) % 2 == 1) { + code -= this.mtfFreq[ge]; + --ge; + } + + for(v = 0; v < alphaSize; ++v) { + if(v >= gs && v <= ge) { + len[rfreq - 1][v] = 0; + } else { + len[rfreq - 1][v] = 15; + } + } + + --rfreq; + gs = ge + 1; + } + + int[][] var25 = new int[6][258]; + int[] var30 = new int[6]; + short[] var32 = new short[6]; + + int i; + int var291; + for(int var31 = 0; var31 < 4; ++var31) { + for(t = 0; t < nGroups; ++t) { + var30[t] = 0; + } + + for(t = 0; t < nGroups; ++t) { + for(v = 0; v < alphaSize; ++v) { + var25[t][v] = 0; + } + } + + nSelectors = 0; + int var33 = 0; + + for(gs = 0; gs < this.nMTF; gs = ge + 1) { + ge = gs + 50 - 1; + if(ge >= this.nMTF) { + ge = this.nMTF - 1; + } + + for(t = 0; t < nGroups; ++t) { + var32[t] = 0; + } + + short var37; + if(nGroups == 6) { + short j = 0; + short var39 = 0; + short var36 = 0; + short nBytes = 0; + short selCtr = 0; + var37 = 0; + + for(i = gs; i <= ge; ++i) { + short icv = this.szptr[i]; + var37 = (short)(var37 + len[0][icv]); + selCtr = (short)(selCtr + len[1][icv]); + nBytes = (short)(nBytes + len[2][icv]); + var36 = (short)(var36 + len[3][icv]); + var39 = (short)(var39 + len[4][icv]); + j = (short)(j + len[5][icv]); + } + + var32[0] = var37; + var32[1] = selCtr; + var32[2] = nBytes; + var32[3] = var36; + var32[4] = var39; + var32[5] = j; + } else { + for(i = gs; i <= ge; ++i) { + var37 = this.szptr[i]; + + for(t = 0; t < nGroups; ++t) { + var32[t] = (short)(var32[t] + len[t][var37]); + } + } + } + + var291 = 999999999; + int var301 = -1; + + for(t = 0; t < nGroups; ++t) { + if(var32[t] < var291) { + var291 = var32[t]; + var301 = t; + } + } + + var33 += var291; + ++var30[var301]; + this.selector[nSelectors] = (char)var301; + ++nSelectors; + + for(i = gs; i <= ge; ++i) { + ++var25[var301][this.szptr[i]]; + } + } + + for(t = 0; t < nGroups; ++t) { + hbMakeCodeLengths(len[t], var25[t], alphaSize, 20); + } + } + + var25 = (int[][])null; + Object var26 = null; + Object var27 = null; + if(nGroups >= 8) { + panic(); + } + + if(nSelectors >= 32768 || nSelectors > 18002) { + panic(); + } + + char[] var28 = new char[6]; + + for(i = 0; i < nGroups; ++i) { + var28[i] = (char)i; + } + + char var331; + char var34; + for(i = 0; i < nSelectors; ++i) { + char var311 = this.selector[i]; + var291 = 0; + + for(var34 = var28[var291]; var311 != var34; var28[var291] = var331) { + ++var291; + var331 = var34; + var34 = var28[var291]; + } + + var28[0] = var34; + this.selectorMtf[i] = (char)var291; + } + + int[][] var321 = new int[6][258]; + + for(t = 0; t < nGroups; ++t) { + var331 = 32; + var34 = 0; + + for(i = 0; i < alphaSize; ++i) { + if(len[t][i] > var34) { + var34 = len[t][i]; + } + + if(len[t][i] < var331) { + var331 = len[t][i]; + } + } + + if(var34 > 20) { + panic(); + } + + if(var331 < 1) { + panic(); + } + + this.hbAssignCodes(var321[t], len[t], var331, var34, alphaSize); + } + + boolean[] var35 = new boolean[16]; + + for(i = 0; i < 16; ++i) { + var35[i] = false; + + for(var291 = 0; var291 < 16; ++var291) { + if(this.inUse[i * 16 + var291]) { + var35[i] = true; + } + } + } + + int var371 = this.bytesOut; + + for(i = 0; i < 16; ++i) { + if(var35[i]) { + this.bsW(1, 1); + } else { + this.bsW(1, 0); + } + } + + for(i = 0; i < 16; ++i) { + if(var35[i]) { + for(var291 = 0; var291 < 16; ++var291) { + if(this.inUse[i * 16 + var291]) { + this.bsW(1, 1); + } else { + this.bsW(1, 0); + } + } + } + } + + var371 = this.bytesOut; + this.bsW(3, nGroups); + this.bsW(15, nSelectors); + + for(i = 0; i < nSelectors; ++i) { + for(var291 = 0; var291 < this.selectorMtf[i]; ++var291) { + this.bsW(1, 1); + } + + this.bsW(1, 0); + } + + var371 = this.bytesOut; + + int var361; + for(t = 0; t < nGroups; ++t) { + var361 = len[t][0]; + this.bsW(5, var361); + + for(i = 0; i < alphaSize; ++i) { + while(var361 < len[t][i]) { + this.bsW(2, 2); + ++var361; + } + + while(var361 > len[t][i]) { + this.bsW(2, 3); + --var361; + } + + this.bsW(1, 0); + } + } + + var371 = this.bytesOut; + var361 = 0; + + for(gs = 0; gs < this.nMTF; ++var361) { + ge = gs + 50 - 1; + if(ge >= this.nMTF) { + ge = this.nMTF - 1; + } + + for(i = gs; i <= ge; ++i) { + this.bsW(len[this.selector[var361]][this.szptr[i]], var321[this.selector[var361]][this.szptr[i]]); + } + + gs = ge + 1; + } + + if(var361 != nSelectors) { + panic(); + } + + } + + private void moveToFrontCodeAndSend() throws IOException { + this.bsPutIntVS(24, this.origPtr); + this.generateMTFValues(); + this.sendMTFValues(); + } + + private void simpleSort(int lo, int hi, int d) { + int bigN = hi - lo + 1; + if(bigN >= 2) { + int hp; + for(hp = 0; this.incs[hp] < bigN; ++hp) { + ; + } + + --hp; + + for(; hp >= 0; --hp) { + int h = this.incs[hp]; + int i = lo + h; + + while(i <= hi) { + int v = this.zptr[i]; + int j = i; + + while(this.fullGtU(this.zptr[j - h] + d, v + d)) { + this.zptr[j] = this.zptr[j - h]; + j -= h; + if(j <= lo + h - 1) { + break; + } + } + + this.zptr[j] = v; + ++i; + if(i > hi) { + break; + } + + v = this.zptr[i]; + j = i; + + while(this.fullGtU(this.zptr[j - h] + d, v + d)) { + this.zptr[j] = this.zptr[j - h]; + j -= h; + if(j <= lo + h - 1) { + break; + } + } + + this.zptr[j] = v; + ++i; + if(i > hi) { + break; + } + + v = this.zptr[i]; + j = i; + + while(this.fullGtU(this.zptr[j - h] + d, v + d)) { + this.zptr[j] = this.zptr[j - h]; + j -= h; + if(j <= lo + h - 1) { + break; + } + } + + this.zptr[j] = v; + ++i; + if(this.workDone > this.workLimit && this.firstAttempt) { + return; + } + } + } + } + + } + + private void vswap(int p1, int p2, int n) { + for(boolean temp = false; n > 0; --n) { + int var5 = this.zptr[p1]; + this.zptr[p1] = this.zptr[p2]; + this.zptr[p2] = var5; + ++p1; + ++p2; + } + + } + + private char med3(char a, char b, char c) { + if(a > b) { + char t = a; + a = b; + b = t; + } + + if(b > c) { + b = c; + } + + if(a > b) { + b = a; + } + + return b; + } + + private void qSort3(int loSt, int hiSt, int dSt) { + CBZip2OutputStream.StackElem[] stack = new CBZip2OutputStream.StackElem[1000]; + + int temp; + for(temp = 0; temp < 1000; ++temp) { + stack[temp] = new CBZip2OutputStream.StackElem((CBZip2OutputStream.StackElem)null); + } + + byte sp = 0; + stack[sp].ll = loSt; + stack[sp].hh = hiSt; + stack[sp].dd = dSt; + int var17 = sp + 1; + + while(true) { + label55: + while(var17 > 0) { + if(var17 >= 1000) { + panic(); + } + + --var17; + int lo = stack[var17].ll; + int hi = stack[var17].hh; + int d = stack[var17].dd; + if(hi - lo >= 20 && d <= 10) { + char med = this.med3(this.block[this.zptr[lo] + d + 1], this.block[this.zptr[hi] + d + 1], this.block[this.zptr[lo + hi >> 1] + d + 1]); + int ltLo = lo; + int unLo = lo; + int gtHi = hi; + int unHi = hi; + + while(true) { + while(true) { + int n; + boolean var18; + if(unLo <= unHi) { + n = this.block[this.zptr[unLo] + d + 1] - med; + if(n == 0) { + var18 = false; + temp = this.zptr[unLo]; + this.zptr[unLo] = this.zptr[ltLo]; + this.zptr[ltLo] = temp; + ++ltLo; + ++unLo; + continue; + } + + if(n <= 0) { + ++unLo; + continue; + } + } + + while(unLo <= unHi) { + n = this.block[this.zptr[unHi] + d + 1] - med; + if(n == 0) { + var18 = false; + temp = this.zptr[unHi]; + this.zptr[unHi] = this.zptr[gtHi]; + this.zptr[gtHi] = temp; + --gtHi; + --unHi; + } else { + if(n < 0) { + break; + } + + --unHi; + } + } + + if(unLo > unHi) { + if(gtHi < ltLo) { + stack[var17].ll = lo; + stack[var17].hh = hi; + stack[var17].dd = d + 1; + ++var17; + } else { + n = ltLo - lo < unLo - ltLo?ltLo - lo:unLo - ltLo; + this.vswap(lo, unLo - n, n); + int m = hi - gtHi < gtHi - unHi?hi - gtHi:gtHi - unHi; + this.vswap(unLo, hi - m + 1, m); + n = lo + unLo - ltLo - 1; + m = hi - (gtHi - unHi) + 1; + stack[var17].ll = lo; + stack[var17].hh = n; + stack[var17].dd = d; + ++var17; + stack[var17].ll = n + 1; + stack[var17].hh = m - 1; + stack[var17].dd = d + 1; + ++var17; + stack[var17].ll = m; + stack[var17].hh = hi; + stack[var17].dd = d; + ++var17; + } + continue label55; + } + + var18 = false; + temp = this.zptr[unLo]; + this.zptr[unLo] = this.zptr[unHi]; + this.zptr[unHi] = temp; + ++unLo; + --unHi; + } + } + } else { + this.simpleSort(lo, hi, d); + if(this.workDone > this.workLimit && this.firstAttempt) { + return; + } + } + } + + return; + } + } + + private void mainSort() { + int[] runningOrder = new int[256]; + int[] copy = new int[256]; + boolean[] bigDone = new boolean[256]; + + int i; + for(i = 0; i < 20; ++i) { + this.block[this.last + i + 2] = this.block[i % (this.last + 1) + 1]; + } + + for(i = 0; i <= this.last + 20; ++i) { + this.quadrant[i] = 0; + } + + this.block[0] = this.block[this.last + 1]; + if(this.last < 4000) { + for(i = 0; i <= this.last; this.zptr[i] = i++) { + ; + } + + this.firstAttempt = false; + this.workDone = this.workLimit = 0; + this.simpleSort(0, this.last, 0); + } else { + int numQSorted = 0; + + for(i = 0; i <= 255; ++i) { + bigDone[i] = false; + } + + for(i = 0; i <= 65536; ++i) { + this.ftab[i] = 0; + } + + char c1 = this.block[0]; + + char c2; + for(i = 0; i <= this.last; ++i) { + c2 = this.block[i + 1]; + ++this.ftab[(c1 << 8) + c2]; + c1 = c2; + } + + for(i = 1; i <= 65536; ++i) { + this.ftab[i] += this.ftab[i - 1]; + } + + c1 = this.block[1]; + + int j; + for(i = 0; i < this.last; this.zptr[this.ftab[j]] = i++) { + c2 = this.block[i + 2]; + j = (c1 << 8) + c2; + c1 = c2; + --this.ftab[j]; + } + + j = (this.block[this.last + 1] << 8) + this.block[1]; + --this.ftab[j]; + this.zptr[this.ftab[j]] = this.last; + + for(i = 0; i <= 255; runningOrder[i] = i++) { + ; + } + + int bbSize = 1; + + do { + bbSize = 3 * bbSize + 1; + } while(bbSize <= 256); + + int bbStart; + do { + bbSize /= 3; + + for(i = bbSize; i <= 255; ++i) { + bbStart = runningOrder[i]; + j = i; + + while(this.ftab[runningOrder[j - bbSize] + 1 << 8] - this.ftab[runningOrder[j - bbSize] << 8] > this.ftab[bbStart + 1 << 8] - this.ftab[bbStart << 8]) { + runningOrder[j] = runningOrder[j - bbSize]; + j -= bbSize; + if(j <= bbSize - 1) { + break; + } + } + + runningOrder[j] = bbStart; + } + } while(bbSize != 1); + + for(i = 0; i <= 255; ++i) { + int ss = runningOrder[i]; + + int shifts; + for(j = 0; j <= 255; ++j) { + shifts = (ss << 8) + j; + if((this.ftab[shifts] & 2097152) != 2097152) { + bbStart = this.ftab[shifts] & -2097153; + bbSize = (this.ftab[shifts + 1] & -2097153) - 1; + if(bbSize > bbStart) { + this.qSort3(bbStart, bbSize, 2); + numQSorted += bbSize - bbStart + 1; + if(this.workDone > this.workLimit && this.firstAttempt) { + return; + } + } + + this.ftab[shifts] |= 2097152; + } + } + + bigDone[ss] = true; + if(i < 255) { + bbStart = this.ftab[ss << 8] & -2097153; + bbSize = (this.ftab[ss + 1 << 8] & -2097153) - bbStart; + + for(shifts = 0; bbSize >> shifts > '\ufffe'; ++shifts) { + ; + } + + for(j = 0; j < bbSize; ++j) { + int a2update = this.zptr[bbStart + j]; + int qVal = j >> shifts; + this.quadrant[a2update] = qVal; + if(a2update < 20) { + this.quadrant[a2update + this.last + 1] = qVal; + } + } + + if(bbSize - 1 >> shifts > '\uffff') { + panic(); + } + } + + for(j = 0; j <= 255; ++j) { + copy[j] = this.ftab[(j << 8) + ss] & -2097153; + } + + for(j = this.ftab[ss << 8] & -2097153; j < (this.ftab[ss + 1 << 8] & -2097153); ++j) { + c1 = this.block[this.zptr[j]]; + if(!bigDone[c1]) { + this.zptr[copy[c1]] = this.zptr[j] == 0?this.last:this.zptr[j] - 1; + ++copy[c1]; + } + } + + for(j = 0; j <= 255; ++j) { + this.ftab[(j << 8) + ss] |= 2097152; + } + } + } + + } + + private void randomiseBlock() { + int rNToGo = 0; + int rTPos = 0; + + int i; + for(i = 0; i < 256; ++i) { + this.inUse[i] = false; + } + + for(i = 0; i <= this.last; ++i) { + if(rNToGo == 0) { + rNToGo = (char)rNums[rTPos]; + ++rTPos; + if(rTPos == 512) { + rTPos = 0; + } + } + + --rNToGo; + this.block[i + 1] = (char)(this.block[i + 1] ^ (rNToGo == 1?1:0)); + this.block[i + 1] = (char)(this.block[i + 1] & 255); + this.inUse[this.block[i + 1]] = true; + } + + } + + private void doReversibleTransformation() { + this.workLimit = this.workFactor * this.last; + this.workDone = 0; + this.blockRandomised = false; + this.firstAttempt = true; + this.mainSort(); + if(this.workDone > this.workLimit && this.firstAttempt) { + this.randomiseBlock(); + this.workLimit = this.workDone = 0; + this.blockRandomised = true; + this.firstAttempt = false; + this.mainSort(); + } + + this.origPtr = -1; + + for(int i = 0; i <= this.last; ++i) { + if(this.zptr[i] == 0) { + this.origPtr = i; + break; + } + } + + if(this.origPtr == -1) { + panic(); + } + + } + + private boolean fullGtU(int i1, int i2) { + char c1 = this.block[i1 + 1]; + char c2 = this.block[i2 + 1]; + if(c1 != c2) { + return c1 > c2; + } else { + ++i1; + ++i2; + c1 = this.block[i1 + 1]; + c2 = this.block[i2 + 1]; + if(c1 != c2) { + return c1 > c2; + } else { + ++i1; + ++i2; + c1 = this.block[i1 + 1]; + c2 = this.block[i2 + 1]; + if(c1 != c2) { + return c1 > c2; + } else { + ++i1; + ++i2; + c1 = this.block[i1 + 1]; + c2 = this.block[i2 + 1]; + if(c1 != c2) { + return c1 > c2; + } else { + ++i1; + ++i2; + c1 = this.block[i1 + 1]; + c2 = this.block[i2 + 1]; + if(c1 != c2) { + return c1 > c2; + } else { + ++i1; + ++i2; + c1 = this.block[i1 + 1]; + c2 = this.block[i2 + 1]; + if(c1 != c2) { + return c1 > c2; + } else { + ++i1; + ++i2; + int k = this.last + 1; + + do { + c1 = this.block[i1 + 1]; + c2 = this.block[i2 + 1]; + if(c1 != c2) { + return c1 > c2; + } + + int s1 = this.quadrant[i1]; + int s2 = this.quadrant[i2]; + if(s1 != s2) { + if(s1 > s2) { + return true; + } + + return false; + } + + ++i1; + ++i2; + c1 = this.block[i1 + 1]; + c2 = this.block[i2 + 1]; + if(c1 != c2) { + if(c1 > c2) { + return true; + } + + return false; + } + + s1 = this.quadrant[i1]; + s2 = this.quadrant[i2]; + if(s1 != s2) { + if(s1 > s2) { + return true; + } + + return false; + } + + ++i1; + ++i2; + c1 = this.block[i1 + 1]; + c2 = this.block[i2 + 1]; + if(c1 != c2) { + if(c1 > c2) { + return true; + } + + return false; + } + + s1 = this.quadrant[i1]; + s2 = this.quadrant[i2]; + if(s1 != s2) { + if(s1 > s2) { + return true; + } + + return false; + } + + ++i1; + ++i2; + c1 = this.block[i1 + 1]; + c2 = this.block[i2 + 1]; + if(c1 != c2) { + if(c1 > c2) { + return true; + } + + return false; + } + + s1 = this.quadrant[i1]; + s2 = this.quadrant[i2]; + if(s1 != s2) { + if(s1 > s2) { + return true; + } + + return false; + } + + ++i1; + ++i2; + if(i1 > this.last) { + i1 -= this.last; + --i1; + } + + if(i2 > this.last) { + i2 -= this.last; + --i2; + } + + k -= 4; + ++this.workDone; + } while(k >= 0); + + return false; + } + } + } + } + } + } + } + + private void allocateCompressStructures() { + int n = 100000 * this.blockSize100k; + this.block = new char[n + 1 + 20]; + this.quadrant = new int[n + 20]; + this.zptr = new int[n]; + this.ftab = new int[65537]; + if(this.block != null && this.quadrant != null && this.zptr != null && this.ftab == null) { + ; + } + + this.szptr = new short[2 * n]; + } + + private void generateMTFValues() { + char[] yy = new char[256]; + this.makeMaps(); + int EOB = this.nInUse + 1; + + int i; + for(i = 0; i <= EOB; ++i) { + this.mtfFreq[i] = 0; + } + + int wr = 0; + int zPend = 0; + + for(i = 0; i < this.nInUse; ++i) { + yy[i] = (char)i; + } + + for(i = 0; i <= this.last; ++i) { + char ll_i = this.unseqToSeq[this.block[this.zptr[i]]]; + int j = 0; + + char tmp; + char tmp2; + for(tmp = yy[j]; ll_i != tmp; yy[j] = tmp2) { + ++j; + tmp2 = tmp; + tmp = yy[j]; + } + + yy[0] = tmp; + if(j == 0) { + ++zPend; + } else { + if(zPend > 0) { + --zPend; + + while(true) { + switch(zPend % 2) { + case 0: + this.szptr[wr] = 0; + ++wr; + ++this.mtfFreq[0]; + break; + case 1: + this.szptr[wr] = 1; + ++wr; + ++this.mtfFreq[1]; + } + + if(zPend < 2) { + zPend = 0; + break; + } + + zPend = (zPend - 2) / 2; + } + } + + this.szptr[wr] = (short)(j + 1); + ++wr; + ++this.mtfFreq[j + 1]; + } + } + + if(zPend > 0) { + --zPend; + + while(true) { + switch(zPend % 2) { + case 0: + this.szptr[wr] = 0; + ++wr; + ++this.mtfFreq[0]; + break; + case 1: + this.szptr[wr] = 1; + ++wr; + ++this.mtfFreq[1]; + } + + if(zPend < 2) { + break; + } + + zPend = (zPend - 2) / 2; + } + } + + this.szptr[wr] = (short)EOB; + ++wr; + ++this.mtfFreq[EOB]; + this.nMTF = wr; + } + + public int getnBlocksRandomised() { + return this.nBlocksRandomised; + } + + public void setnBlocksRandomised(int nBlocksRandomised) { + this.nBlocksRandomised = nBlocksRandomised; + } + + private static class StackElem { + int ll; + int hh; + int dd; + + private StackElem() { + } + + StackElem(CBZip2OutputStream.SyntheticClass_1 x0) { + this(); + } + + // $FF: synthetic method + StackElem(CBZip2OutputStream.StackElem var1) { + this(); + } + } + + static class SyntheticClass_1 { + } +} diff --git a/Tools/Frostys Cache Editor/src/org/apache/tools/bzip2/CRC.java b/Tools/Frostys Cache Editor/src/org/apache/tools/bzip2/CRC.java new file mode 100644 index 0000000..d00698e --- /dev/null +++ b/Tools/Frostys Cache Editor/src/org/apache/tools/bzip2/CRC.java @@ -0,0 +1,35 @@ +package org.apache.tools.bzip2; + +class CRC { + public static int[] crc32Table = new int[]{0, 79764919, 159529838, 222504665, 319059676, 398814059, 445009330, 507990021, 638119352, 583659535, 797628118, 726387553, 890018660, 835552979, 1015980042, 944750013, 1276238704, 1221641927, 1167319070, 1095957929, 1595256236, 1540665371, 1452775106, 1381403509, 1780037320, 1859660671, 1671105958, 1733955601, 2031960084, 2111593891, 1889500026, 1952343757, -1742489888, -1662866601, -1851683442, -1788833735, -1960329156, -1880695413, -2103051438, -2040207643, -1104454824, -1159051537, -1213636554, -1284997759, -1389417084, -1444007885, -1532160278, -1603531939, -734892656, -789352409, -575645954, -646886583, -952755380, -1007220997, -827056094, -898286187, -231047128, -151282273, -71779514, -8804623, -515967244, -436212925, -390279782, -327299027, 881225847, 809987520, 1023691545, 969234094, 662832811, 591600412, 771767749, 717299826, 311336399, 374308984, 453813921, 533576470, 25881363, 88864420, 134795389, 214552010, 2023205639, 2086057648, 1897238633, 1976864222, 1804852699, 1867694188, 1645340341, 1724971778, 1587496639, 1516133128, 1461550545, 1406951526, 1302016099, 1230646740, 1142491917, 1087903418, -1398421865, -1469785312, -1524105735, -1578704818, -1079922613, -1151291908, -1239184603, -1293773166, -1968362705, -1905510760, -2094067647, -2014441994, -1716953613, -1654112188, -1876203875, -1796572374, -525066777, -462094256, -382327159, -302564546, -206542021, -143559028, -97365931, -17609246, -960696225, -1031934488, -817968335, -872425850, -709327229, -780559564, -600130067, -654598054, 1762451694, 1842216281, 1619975040, 1682949687, 2047383090, 2127137669, 1938468188, 2001449195, 1325665622, 1271206113, 1183200824, 1111960463, 1543535498, 1489069629, 1434599652, 1363369299, 622672798, 568075817, 748617968, 677256519, 907627842, 853037301, 1067152940, 995781531, 51762726, 131386257, 177728840, 240578815, 269590778, 349224269, 429104020, 491947555, -248556018, -168932423, -122852000, -60002089, -500490030, -420856475, -341238852, -278395381, -685261898, -739858943, -559578920, -630940305, -1004286614, -1058877219, -845023740, -916395085, -1119974018, -1174433591, -1262701040, -1333941337, -1371866206, -1426332139, -1481064244, -1552294533, -1690935098, -1611170447, -1833673816, -1770699233, -2009983462, -1930228819, -2119160460, -2056179517, 1569362073, 1498123566, 1409854455, 1355396672, 1317987909, 1246755826, 1192025387, 1137557660, 2072149281, 2135122070, 1912620623, 1992383480, 1753615357, 1816598090, 1627664531, 1707420964, 295390185, 358241886, 404320391, 483945776, 43990325, 106832002, 186451547, 266083308, 932423249, 861060070, 1041341759, 986742920, 613929101, 542559546, 756411363, 701822548, -978770311, -1050133554, -869589737, -924188512, -693284699, -764654318, -550540341, -605129092, -475935807, -413084042, -366743377, -287118056, -257573603, -194731862, -114850189, -35218492, -1984365303, -1921392450, -2143631769, -2063868976, -1698919467, -1635936670, -1824608069, -1744851700, -1347415887, -1418654458, -1506661409, -1561119128, -1129027987, -1200260134, -1254728445, -1309196108}; + int globalCrc; + + public CRC() { + this.initialiseCRC(); + } + + void initialiseCRC() { + this.globalCrc = -1; + } + + int getFinalCRC() { + return ~this.globalCrc; + } + + int getGlobalCRC() { + return this.globalCrc; + } + + void setGlobalCRC(int newCrc) { + this.globalCrc = newCrc; + } + + void updateCRC(int inCh) { + int temp = this.globalCrc >> 24 ^ inCh; + if(temp < 0) { + temp += 256; + } + + this.globalCrc = this.globalCrc << 8 ^ crc32Table[temp]; + } +} diff --git a/Tools/RSDataSuite v1.2.2.jar b/Tools/RSDataSuite v1.2.2.jar new file mode 100644 index 0000000..3d9cbff Binary files /dev/null and b/Tools/RSDataSuite v1.2.2.jar differ diff --git a/Tools/diff_json_simple.py b/Tools/diff_json_simple.py new file mode 100644 index 0000000..6d012e3 --- /dev/null +++ b/Tools/diff_json_simple.py @@ -0,0 +1,137 @@ +import json +import code +from pprint import pprint +import argparse +import collections +from weakref import proxy +#code.interact(local=dict(globals(), **locals())) + +class Link(object): + __slots__ = 'prev', 'next', 'key', '__weakref__' + +class OrderedSet(collections.MutableSet): + 'Set the remembers the order elements were added' + # Big-O running times for all methods are the same as for regular sets. + # The internal self.__map dictionary maps keys to links in a doubly linked list. + # The circular doubly linked list starts and ends with a sentinel element. + # The sentinel element never gets deleted (this simplifies the algorithm). + # The prev/next links are weakref proxies (to prevent circular references). + # Individual links are kept alive by the hard reference in self.__map. + # Those hard references disappear when a key is deleted from an OrderedSet. + + def __init__(self, iterable=None): + self.__root = root = Link() # sentinel node for doubly linked list + root.prev = root.next = root + self.__map = {} # key --> link + if iterable is not None: + self |= iterable + + def __len__(self): + return len(self.__map) + + def __contains__(self, key): + return key in self.__map + + def add(self, key): + # Store new key in a new link at the end of the linked list + if key not in self.__map: + self.__map[key] = link = Link() + root = self.__root + last = root.prev + link.prev, link.next, link.key = last, root, key + last.next = root.prev = proxy(link) + + def discard(self, key): + # Remove an existing item using self.__map to find the link which is + # then removed by updating the links in the predecessor and successors. + if key in self.__map: + link = self.__map.pop(key) + link.prev.next = link.next + link.next.prev = link.prev + + def __iter__(self): + # Traverse the linked list in order. + root = self.__root + curr = root.next + while curr is not root: + yield curr.key + curr = curr.next + + def __reversed__(self): + # Traverse the linked list in reverse order. + root = self.__root + curr = root.prev + while curr is not root: + yield curr.key + curr = curr.prev + + def pop(self, last=True): + if not self: + raise KeyError('set is empty') + key = next(reversed(self)) if last else next(iter(self)) + self.discard(key) + return key + + def __repr__(self): + if not self: + return '%s()' % (self.__class__.__name__,) + return '%s(%r)' % (self.__class__.__name__, list(self)) + + def __eq__(self, other): + if isinstance(other, OrderedSet): + return len(self) == len(other) and list(self) == list(other) + return not self.isdisjoint(other) + + +def datalist(f): + with open(f) as jsonFile: + d = json.load(jsonFile) + if (isinstance(d, dict) and len(d.keys()) == 1): + d = d[list(d.keys())[0]] + return d + +def compareby(l1, l2, field): + idx1 = [record[field] for record in l1] + idx2 = [record[field] for record in l2] + + idx1Uniques = OrderedSet(idx1) - idx2 + idx2Uniques = OrderedSet(idx2) - idx1 + + print('') + print('[%s] not in LEFT:' % field) + pprint(idx2Uniques) + print('') + print('[%s] not in RIGHT:' % field) + pprint(idx1Uniques) + print('') + + idxCommon = (OrderedSet(idx1) | OrderedSet(idx2)) - idx1Uniques - idx2Uniques + idxCommonList = list(idxCommon) + + dict1 = {record[field] : {i:record[i] for i in record if i!=field} for record in l1} + dict2 = {record[field] : {i:record[i] for i in record if i!=field} for record in l2} + + for idx in idxCommonList: + if (dict1[idx] != dict2[idx]): + print('records do not match for [%s]=%s' % (field, idx)) + print(' LEFT: ' + str(dict1[idx])) + print(' RIGHT: ' + str(dict2[idx])) + print('') + + #code.interact(local=dict(globals(), **locals())) + + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description='Show delta to get from LEFT file to RIGHT file') + parser.add_argument('f1', type=str, help='LEFT file') + parser.add_argument('f2', type=str, help='RIGHT file') + parser.add_argument('field', type=str, help='FIELD to compare by') + args = parser.parse_args() + + d1 = datalist(args.f1) + d2 = datalist(args.f2) + compareby(d1, d2, args.field) + + #code.interact(local=dict(globals(), **locals())) + \ No newline at end of file diff --git a/build b/build new file mode 100755 index 0000000..86471b2 --- /dev/null +++ b/build @@ -0,0 +1,140 @@ +#!/usr/bin/env bash + +SCRIPT_DIR=$(cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P) + +BUILD_MS=0 +BUILD_GS=0 +CLEAN_MS=0 +CLEAN_GS=0 +SKIPTEST="" + +GS_SRC=$SCRIPT_DIR/Server +MS_SRC=$SCRIPT_DIR/Management-Server + +CLEANOPT="" +_JAR_DIR="$SCRIPT_DIR/builddir" + +help() +{ + echo "Usage: $0 [-h] <-m | -g> [-c ] [-o ]"; + echo " -h: Display this message."; + echo " -m: Build the management server."; + echo " -g: Build the game server."; + echo " -c: Clean: m: management, g: gameserver. " + echo " Can specify both. Need at least one if present."; + echo " -o: Specify jar-file directory." + echo " -q: Quick build - will skip tests."; +} + +error() +{ + echo $1; + exit -1; +} + +clean_ms() +{ + cd $MS_SRC + + if [[ "$CLEANOPT" == *"m"* ]]; then + echo "Cleaning the management server." + sh mvnw clean || error "Failed to clean the MS." + fi +} + +clean_gs() +{ + cd $GS_SRC; + if [[ "$CLEANOPT" == *"g"* ]]; then + echo "Cleaning the game server." + sh mvnw clean || error "Failed to clean the game server. Giving up." + fi +} + +build_ms() +{ + cd $MS_SRC + + sh mvnw package $SKIPTEST || \ + error "Failed to build the management server. Giving up"; +} + +build_gs() +{ + cd $GS_SRC; + + sh mvnw package $SKIPTEST || \ + error "Failed to build the game server. Giving up." +} + +while getopts "hqmgc:o:d" arg; do + case $arg in + h) + help + exit 0 + ;; + m) + BUILD_MS=1 + ;; + g) + BUILD_GS=1 + ;; + c) + CLEANOPT=${OPTARG} + ;; + o) + _JAR_DIR=${OPTARG} + ;; + d) + echo "BUILD_MS=$BUILD_MS" + echo "BUILD_GS=$BUILD_GS" + echo "CLEANOPT=$CLEANOPT" + echo "_JAR_DIR=$_JAR_DIR" + ;; + q) + SKIPTEST="-DskipTests" + ;; + esac +done + +if [[ $CLEANOPT != "m" ]] \ + && [[ $CLEANOPT != "g" ]] \ + && [[ $CLEANOPT != "mg" ]] \ + && [[ $CLEANOPT != "" ]]; +then + error "Invalid cleaning option '$CLEANOPT'. Valid options are 'm', 'g', 'mg' or none." +fi + +if [ $BUILD_MS -eq 0 ] && [ $BUILD_GS -eq 0 ] && [[ $CLEANOPT == "" ]]; then + error "Need to build or clean at least one of the modules. See -h for details." +fi + +# Conditionals inside the functions. +clean_gs +clean_ms +# ----------- + +if [ -d $_JAR_DIR ]; then + rm -r $_JAR_DIR +fi + +if [ $BUILD_MS -ne 1 ] && [ $BUILD_GS -ne 1 ]; then + echo "No build options specified. Stop." + exit 0 +fi + +mkdir -p $_JAR_DIR || error "Failed to create build directory."; + +if [ $BUILD_MS -eq 1 ]; then + build_ms + + # Will never execute if build_ms fails because it quits upon failure. + mv -v $MS_SRC/target/*-with-dependencies.jar $_JAR_DIR/ms.jar +fi + +if [ $BUILD_GS -eq 1 ]; then + build_gs + + # Will never execute if build_gs fails because it quits upon failure. + mv -v $GS_SRC/target/*-with-dependencies.jar $_JAR_DIR/server.jar +fi diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..02614f3 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,29 @@ +version: '3.3' +services: + app: + build: . + container_name: "2009scape_app" + depends_on: + - database + restart: unless-stopped + volumes: + - "2009scape_app:/app" + ports: + - "43595:43595" + + database: + image: mysql:5.7 + container_name: "2009scape_db" + restart: always + ports: + - "3306:3306" + volumes: + - "2009scape_db:/var/lib/mysql" + - "./Server/db_exports/global.sql:/docker-entrypoint-initdb.d/global.sql" + environment: + MYSQL_ALLOW_EMPTY_PASSWORD: "yes" + MYSQL_ROOT_PASSWORD: "" + MYSQL_ROOT_USER: "root" +volumes: + 2009scape_app: + 2009scape_db: diff --git a/dumps/498/498_clothing_dump.txt b/dumps/498/498_clothing_dump.txt new file mode 100644 index 0000000..6a6c973 --- /dev/null +++ b/dumps/498/498_clothing_dump.txt @@ -0,0 +1,171 @@ +[2014-04-26 04:20:29][Arios]: Initializing cache... +Definition size: 169. +Clothing 0: 0, false, [230], [63, -1, -1, -1, -1] +Clothing 1: 0, false, [210], [49, -1, -1, -1, -1] +Clothing 2: 0, false, [214], [52, -1, -1, -1, -1] +Clothing 3: 0, false, [217], [55, -1, -1, -1, -1] +Clothing 4: 0, false, [223], [59, -1, -1, -1, -1] +Clothing 5: 0, false, [215], [53, -1, -1, -1, -1] +Clothing 6: 0, false, [235], [67, -1, -1, -1, -1] +Clothing 7: 0, false, [206], [46, -1, -1, -1, -1] +Clothing 8: 0, false, [203], [45, -1, -1, -1, -1] +Clothing 9: 0, true, [203], [45, -1, -1, -1, -1] +Clothing 10: 1, false, [249], [81, -1, -1, -1, -1] +Clothing 11: 1, false, [250], [82, -1, -1, -1, -1] +Clothing 12: 1, false, [251], [83, -1, -1, -1, -1] +Clothing 13: 1, false, [247], [79, -1, -1, -1, -1] +Clothing 14: 1, false, [246], [-1, -1, -1, -1, -1] +Clothing 15: 1, false, [248], [80, -1, -1, -1, -1] +Clothing 16: 1, false, [253], [85, -1, -1, -1, -1] +Clothing 17: 1, false, [252], [84, -1, -1, -1, -1] +Clothing 18: 2, false, [292], [-1, -1, -1, -1, -1] +Clothing 19: 2, false, [292, 322], [-1, -1, -1, -1, -1] +Clothing 20: 2, false, [292, 326], [-1, -1, -1, -1, -1] +Clothing 21: 2, false, [292, 320], [-1, -1, -1, -1, -1] +Clothing 22: 2, false, [292, 327], [-1, -1, -1, -1, -1] +Clothing 23: 2, false, [292, 324], [-1, -1, -1, -1, -1] +Clothing 24: 2, false, [310], [-1, -1, -1, -1, -1] +Clothing 25: 2, false, [297], [-1, -1, -1, -1, -1] +Clothing 26: 3, false, [151], [-1, -1, -1, -1, -1] +Clothing 27: 3, false, [167], [-1, -1, -1, -1, -1] +Clothing 28: 3, false, [170], [-1, -1, -1, -1, -1] +Clothing 29: 3, false, [162], [-1, -1, -1, -1, -1] +Clothing 30: 3, false, [163], [-1, -1, -1, -1, -1] +Clothing 31: 3, false, [158], [-1, -1, -1, -1, -1] +Clothing 32: 3, true, [158], [-1, -1, -1, -1, -1] +Clothing 33: 4, false, [176], [-1, -1, -1, -1, -1] +Clothing 34: 4, false, [176], [-1, -1, -1, -1, -1] +Clothing 35: 4, true, [176], [-1, -1, -1, -1, -1] +Clothing 36: 5, false, [254], [-1, -1, -1, -1, -1] +Clothing 37: 5, false, [271], [-1, -1, -1, -1, -1] +Clothing 38: 5, false, [267], [-1, -1, -1, -1, -1] +Clothing 39: 5, false, [274], [-1, -1, -1, -1, -1] +Clothing 40: 5, false, [275], [-1, -1, -1, -1, -1] +Clothing 41: 5, true, [275], [-1, -1, -1, -1, -1] +Clothing 42: 6, false, [181], [-1, -1, -1, -1, -1] +Clothing 43: 6, false, [183], [-1, -1, -1, -1, -1] +Clothing 44: 6, true, [183], [-1, -1, -1, -1, -1] +Clothing 45: 7, false, [403], [120, -1, -1, -1, -1] +Clothing 46: 7, false, [378], [103, -1, -1, -1, -1] +Clothing 47: 7, false, [387], [110, -1, -1, -1, -1] +Clothing 48: 7, false, [390], [113, -1, -1, -1, -1] +Clothing 49: 7, false, [393], [115, -1, -1, -1, -1] +Clothing 50: 7, false, [399], [118, -1, -1, -1, -1] +Clothing 51: 7, false, [391], [114, -1, -1, -1, -1] +Clothing 52: 7, false, [408], [125, -1, -1, -1, -1] +Clothing 53: 7, false, [382], [105, -1, -1, -1, -1] +Clothing 54: 7, false, [379], [104, -1, -1, -1, -1] +Clothing 55: 7, true, [379], [104, -1, -1, -1, -1] +Clothing 56: 9, false, [456], [-1, -1, -1, -1, -1] +Clothing 57: 9, false, [469], [-1, -1, -1, -1, -1] +Clothing 58: 9, false, [470], [-1, -1, -1, -1, -1] +Clothing 59: 9, false, [471], [-1, -1, -1, -1, -1] +Clothing 60: 9, false, [474], [-1, -1, -1, -1, -1] +Clothing 61: 10, false, [332], [-1, -1, -1, -1, -1] +Clothing 62: 10, false, [351], [-1, -1, -1, -1, -1] +Clothing 63: 10, false, [346], [-1, -1, -1, -1, -1] +Clothing 64: 10, false, [348], [-1, -1, -1, -1, -1] +Clothing 65: 10, false, [343], [-1, -1, -1, -1, -1] +Clothing 66: 10, true, [343], [-1, -1, -1, -1, -1] +Clothing 67: 11, false, [353], [-1, -1, -1, -1, -1] +Clothing 68: 11, false, [353], [-1, -1, -1, -1, -1] +Clothing 69: 11, true, [353], [-1, -1, -1, -1, -1] +Clothing 70: 12, false, [419], [-1, -1, -1, -1, -1] +Clothing 71: 12, false, [433], [-1, -1, -1, -1, -1] +Clothing 72: 12, false, [431], [-1, -1, -1, -1, -1] +Clothing 73: 12, false, [428], [-1, -1, -1, -1, -1] +Clothing 74: 12, false, [421], [-1, -1, -1, -1, -1] +Clothing 75: 12, false, [438], [-1, -1, -1, -1, -1] +Clothing 76: 12, false, [437], [-1, -1, -1, -1, -1] +Clothing 77: 12, false, [429], [-1, -1, -1, -1, -1] +Clothing 78: 12, true, [429], [-1, -1, -1, -1, -1] +Clothing 79: 13, false, [358], [-1, -1, -1, -1, -1] +Clothing 80: 13, false, [360], [-1, -1, -1, -1, -1] +Clothing 81: 13, true, [360], [-1, -1, -1, -1, -1] +Clothing 82: 6, true, [7117], [-1, -1, -1, -1, -1] +Clothing 83: 13, true, [7118], [-1, -1, -1, -1, -1] +Clothing 84: 4, false, [176], [-1, -1, -1, -1, -1] +Clothing 85: 5, false, [27626], [-1, -1, -1, -1, -1] +Clothing 86: 5, false, [27623], [-1, -1, -1, -1, -1] +Clothing 87: 5, false, [27624], [-1, -1, -1, -1, -1] +Clothing 88: 5, false, [27621], [-1, -1, -1, -1, -1] +Clothing 89: 5, false, [27622], [-1, -1, -1, -1, -1] +Clothing 90: 5, false, [27625], [-1, -1, -1, -1, -1] +Clothing 91: 0, false, [27633], [27680, -1, -1, -1, -1] +Clothing 92: 0, false, [27627], [27677, -1, -1, -1, -1] +Clothing 93: 0, false, [27630], [27679, -1, -1, -1, -1] +Clothing 94: 0, false, [27628], [27682, -1, -1, -1, -1] +Clothing 95: 0, false, [27631], [27683, -1, -1, -1, -1] +Clothing 96: 0, false, [27629], [27681, -1, -1, -1, -1] +Clothing 97: 0, false, [27632], [27678, -1, -1, -1, -1] +Clothing 98: 1, false, [27645], [27685, -1, -1, -1, -1] +Clothing 99: 1, false, [27644], [27688, -1, -1, -1, -1] +Clothing 100: 1, false, [27646], [27687, -1, -1, -1, -1] +Clothing 101: 1, false, [27642], [27689, -1, -1, -1, -1] +Clothing 102: 1, false, [27640], [27684, -1, -1, -1, -1] +Clothing 103: 1, false, [27643], [27690, -1, -1, -1, -1] +Clothing 104: 1, false, [27641], [27686, -1, -1, -1, -1] +Clothing 105: 3, false, [27634], [-1, -1, -1, -1, -1] +Clothing 106: 3, false, [27635], [-1, -1, -1, -1, -1] +Clothing 107: 3, false, [27638], [-1, -1, -1, -1, -1] +Clothing 108: 3, false, [27639], [-1, -1, -1, -1, -1] +Clothing 109: 3, false, [27636], [-1, -1, -1, -1, -1] +Clothing 110: 3, false, [27637], [-1, -1, -1, -1, -1] +Clothing 111: 2, false, [27648], [-1, -1, -1, -1, -1] +Clothing 112: 2, false, [27563], [-1, -1, -1, -1, -1] +Clothing 113: 2, false, [27647], [-1, -1, -1, -1, -1] +Clothing 114: 2, false, [25864], [-1, -1, -1, -1, -1] +Clothing 115: 2, false, [27650], [-1, -1, -1, -1, -1] +Clothing 116: 2, false, [27649], [-1, -1, -1, -1, -1] +Clothing 117: 4, false, [24553], [-1, -1, -1, -1, -1] +Clothing 118: 4, false, [24553], [-1, -1, -1, -1, -1] +Clothing 119: 4, false, [24554], [-1, -1, -1, -1, -1] +Clothing 120: 4, false, [24554], [-1, -1, -1, -1, -1] +Clothing 121: 4, false, [24555], [-1, -1, -1, -1, -1] +Clothing 122: 4, false, [24555], [-1, -1, -1, -1, -1] +Clothing 123: 4, false, [24556], [-1, -1, -1, -1, -1] +Clothing 124: 4, false, [24556], [-1, -1, -1, -1, -1] +Clothing 125: 4, false, [24557], [-1, -1, -1, -1, -1] +Clothing 126: 4, false, [24557], [-1, -1, -1, -1, -1] +Clothing 127: 11, false, [353], [-1, -1, -1, -1, -1] +Clothing 128: 12, false, [27655], [-1, -1, -1, -1, -1] +Clothing 129: 12, false, [27657], [-1, -1, -1, -1, -1] +Clothing 130: 12, false, [27654], [-1, -1, -1, -1, -1] +Clothing 131: 12, false, [27653], [-1, -1, -1, -1, -1] +Clothing 132: 12, false, [27656], [-1, -1, -1, -1, -1] +Clothing 133: 12, false, [27651], [-1, -1, -1, -1, -1] +Clothing 134: 12, false, [27652], [-1, -1, -1, -1, -1] +Clothing 135: 7, false, [16458], [16446, -1, -1, -1, -1] +Clothing 136: 7, false, [16453], [16441, -1, -1, -1, -1] +Clothing 137: 7, false, [16460], [16448, -1, -1, -1, -1] +Clothing 138: 7, false, [16457], [16470, -1, -1, -1, -1] +Clothing 139: 7, false, [27664], [27695, -1, -1, -1, -1] +Clothing 140: 7, false, [27660], [16439, -1, -1, -1, -1] +Clothing 141: 7, false, [27662], [27692, -1, -1, -1, -1] +Clothing 142: 7, false, [16454], [16442, -1, -1, -1, -1] +Clothing 143: 7, false, [27663], [27696, -1, -1, -1, -1] +Clothing 144: 7, false, [27661], [27694, -1, -1, -1, -1] +Clothing 145: 7, false, [27658], [27693, -1, -1, -1, -1] +Clothing 146: 7, false, [27659], [27691, -1, -1, -1, -1] +Clothing 147: 10, false, [27670], [-1, -1, -1, -1, -1] +Clothing 148: 10, false, [27666], [-1, -1, -1, -1, -1] +Clothing 149: 10, false, [27665], [-1, -1, -1, -1, -1] +Clothing 150: 10, false, [27668], [-1, -1, -1, -1, -1] +Clothing 151: 10, false, [27669], [-1, -1, -1, -1, -1] +Clothing 152: 10, false, [27667], [-1, -1, -1, -1, -1] +Clothing 153: 9, false, [27673], [-1, -1, -1, -1, -1] +Clothing 154: 9, false, [27675], [-1, -1, -1, -1, -1] +Clothing 155: 9, false, [27672], [-1, -1, -1, -1, -1] +Clothing 156: 9, false, [27674], [-1, -1, -1, -1, -1] +Clothing 157: 9, false, [27671], [-1, -1, -1, -1, -1] +Clothing 158: 9, false, [27676], [-1, -1, -1, -1, -1] +Clothing 159: 11, false, [24559], [-1, -1, -1, -1, -1] +Clothing 160: 11, false, [24559], [-1, -1, -1, -1, -1] +Clothing 161: 11, false, [24560], [-1, -1, -1, -1, -1] +Clothing 162: 11, false, [24560], [-1, -1, -1, -1, -1] +Clothing 163: 11, false, [24561], [-1, -1, -1, -1, -1] +Clothing 164: 11, false, [24561], [-1, -1, -1, -1, -1] +Clothing 165: 11, false, [24562], [-1, -1, -1, -1, -1] +Clothing 166: 11, false, [24562], [-1, -1, -1, -1, -1] +Clothing 167: 11, false, [24563], [-1, -1, -1, -1, -1] +Clothing 168: 11, false, [24563], [-1, -1, -1, -1, -1] diff --git a/dumps/498/498_hidden_child_dump.txt b/dumps/498/498_hidden_child_dump.txt new file mode 100644 index 0000000..e6a3a4e --- /dev/null +++ b/dumps/498/498_hidden_child_dump.txt @@ -0,0 +1,1116 @@ +RSInterface 0 has hidden child 10 +RSInterface 0 has hidden child 12 +RSInterface 0 has hidden child 14 +RSInterface 0 has hidden child 16 +RSInterface 0 has hidden child 18 +RSInterface 1 has hidden child 7 +RSInterface 1 has hidden child 8 +RSInterface 1 has hidden child 9 +RSInterface 1 has hidden child 10 +RSInterface 1 has hidden child 11 +RSInterface 1 has hidden child 12 +RSInterface 3 has hidden child 7 +RSInterface 3 has hidden child 8 +RSInterface 3 has hidden child 9 +RSInterface 3 has hidden child 10 +RSInterface 3 has hidden child 11 +RSInterface 3 has hidden child 12 +RSInterface 11 has hidden child 64 +RSInterface 12 has hidden child 103 +RSInterface 14 has hidden child 87 +RSInterface 26 has hidden child 4 +RSInterface 26 has hidden child 6 +RSInterface 26 has hidden child 8 +RSInterface 26 has hidden child 10 +RSInterface 26 has hidden child 12 +RSInterface 26 has hidden child 14 +RSInterface 26 has hidden child 16 +RSInterface 26 has hidden child 18 +RSInterface 26 has hidden child 20 +RSInterface 26 has hidden child 22 +RSInterface 26 has hidden child 24 +RSInterface 26 has hidden child 26 +RSInterface 26 has hidden child 28 +RSInterface 26 has hidden child 30 +RSInterface 26 has hidden child 32 +RSInterface 26 has hidden child 34 +RSInterface 26 has hidden child 36 +RSInterface 26 has hidden child 38 +RSInterface 26 has hidden child 40 +RSInterface 26 has hidden child 42 +RSInterface 26 has hidden child 44 +RSInterface 26 has hidden child 46 +RSInterface 26 has hidden child 48 +RSInterface 26 has hidden child 50 +RSInterface 26 has hidden child 52 +RSInterface 26 has hidden child 54 +RSInterface 26 has hidden child 56 +RSInterface 26 has hidden child 58 +RSInterface 26 has hidden child 60 +RSInterface 26 has hidden child 62 +RSInterface 26 has hidden child 72 +RSInterface 27 has hidden child 10 +RSInterface 27 has hidden child 12 +RSInterface 27 has hidden child 14 +RSInterface 27 has hidden child 16 +RSInterface 27 has hidden child 18 +RSInterface 27 has hidden child 20 +RSInterface 27 has hidden child 22 +RSInterface 27 has hidden child 24 +RSInterface 27 has hidden child 26 +RSInterface 27 has hidden child 28 +RSInterface 27 has hidden child 30 +RSInterface 27 has hidden child 32 +RSInterface 27 has hidden child 34 +RSInterface 27 has hidden child 36 +RSInterface 27 has hidden child 38 +RSInterface 27 has hidden child 70 +RSInterface 27 has hidden child 72 +RSInterface 27 has hidden child 74 +RSInterface 27 has hidden child 76 +RSInterface 27 has hidden child 78 +RSInterface 27 has hidden child 80 +RSInterface 27 has hidden child 82 +RSInterface 27 has hidden child 84 +RSInterface 27 has hidden child 86 +RSInterface 27 has hidden child 88 +RSInterface 27 has hidden child 90 +RSInterface 27 has hidden child 92 +RSInterface 27 has hidden child 94 +RSInterface 27 has hidden child 96 +RSInterface 27 has hidden child 98 +RSInterface 28 has hidden child 117 +RSInterface 33 has hidden child 115 +RSInterface 36 has hidden child 124 +RSInterface 37 has hidden child 115 +RSInterface 40 has hidden child 116 +RSInterface 41 has hidden child 115 +RSInterface 44 has hidden child 150 +RSInterface 45 has hidden child 115 +RSInterface 49 has hidden child 39 +RSInterface 49 has hidden child 41 +RSInterface 49 has hidden child 43 +RSInterface 49 has hidden child 45 +RSInterface 49 has hidden child 47 +RSInterface 49 has hidden child 49 +RSInterface 49 has hidden child 51 +RSInterface 49 has hidden child 53 +RSInterface 49 has hidden child 55 +RSInterface 49 has hidden child 57 +RSInterface 49 has hidden child 59 +RSInterface 49 has hidden child 61 +RSInterface 49 has hidden child 63 +RSInterface 49 has hidden child 65 +RSInterface 49 has hidden child 67 +RSInterface 49 has hidden child 69 +RSInterface 49 has hidden child 71 +RSInterface 49 has hidden child 73 +RSInterface 49 has hidden child 75 +RSInterface 49 has hidden child 77 +RSInterface 49 has hidden child 79 +RSInterface 49 has hidden child 81 +RSInterface 51 has hidden child 28 +RSInterface 51 has hidden child 29 +RSInterface 52 has hidden child 3 +RSInterface 52 has hidden child 6 +RSInterface 52 has hidden child 13 +RSInterface 53 has hidden child 22 +RSInterface 53 has hidden child 23 +RSInterface 53 has hidden child 24 +RSInterface 53 has hidden child 36 +RSInterface 53 has hidden child 40 +RSInterface 53 has hidden child 41 +RSInterface 53 has hidden child 44 +RSInterface 53 has hidden child 47 +RSInterface 53 has hidden child 50 +RSInterface 75 has hidden child 12 +RSInterface 76 has hidden child 10 +RSInterface 77 has hidden child 10 +RSInterface 78 has hidden child 12 +RSInterface 79 has hidden child 10 +RSInterface 81 has hidden child 12 +RSInterface 82 has hidden child 12 +RSInterface 83 has hidden child 12 +RSInterface 84 has hidden child 10 +RSInterface 85 has hidden child 10 +RSInterface 87 has hidden child 12 +RSInterface 88 has hidden child 12 +RSInterface 89 has hidden child 12 +RSInterface 90 has hidden child 13 +RSInterface 90 has hidden child 15 +RSInterface 90 has hidden child 17 +RSInterface 90 has hidden child 19 +RSInterface 90 has hidden child 21 +RSInterface 90 has hidden child 23 +RSInterface 90 has hidden child 25 +RSInterface 90 has hidden child 27 +RSInterface 90 has hidden child 29 +RSInterface 90 has hidden child 31 +RSInterface 90 has hidden child 33 +RSInterface 90 has hidden child 35 +RSInterface 90 has hidden child 37 +RSInterface 90 has hidden child 39 +RSInterface 90 has hidden child 41 +RSInterface 90 has hidden child 43 +RSInterface 90 has hidden child 45 +RSInterface 90 has hidden child 47 +RSInterface 90 has hidden child 49 +RSInterface 90 has hidden child 51 +RSInterface 90 has hidden child 53 +RSInterface 90 has hidden child 55 +RSInterface 90 has hidden child 57 +RSInterface 90 has hidden child 59 +RSInterface 90 has hidden child 61 +RSInterface 90 has hidden child 63 +RSInterface 90 has hidden child 65 +RSInterface 90 has hidden child 67 +RSInterface 90 has hidden child 69 +RSInterface 90 has hidden child 71 +RSInterface 90 has hidden child 73 +RSInterface 90 has hidden child 75 +RSInterface 90 has hidden child 77 +RSInterface 90 has hidden child 79 +RSInterface 90 has hidden child 81 +RSInterface 90 has hidden child 87 +RSInterface 90 has hidden child 113 +RSInterface 90 has hidden child 115 +RSInterface 90 has hidden child 117 +RSInterface 90 has hidden child 119 +RSInterface 90 has hidden child 121 +RSInterface 90 has hidden child 123 +RSInterface 90 has hidden child 125 +RSInterface 90 has hidden child 127 +RSInterface 90 has hidden child 129 +RSInterface 90 has hidden child 131 +RSInterface 90 has hidden child 133 +RSInterface 90 has hidden child 135 +RSInterface 90 has hidden child 137 +RSInterface 90 has hidden child 139 +RSInterface 90 has hidden child 141 +RSInterface 90 has hidden child 143 +RSInterface 90 has hidden child 145 +RSInterface 90 has hidden child 147 +RSInterface 90 has hidden child 149 +RSInterface 90 has hidden child 151 +RSInterface 90 has hidden child 153 +RSInterface 90 has hidden child 155 +RSInterface 90 has hidden child 157 +RSInterface 90 has hidden child 159 +RSInterface 90 has hidden child 161 +RSInterface 90 has hidden child 163 +RSInterface 90 has hidden child 165 +RSInterface 90 has hidden child 167 +RSInterface 90 has hidden child 169 +RSInterface 90 has hidden child 171 +RSInterface 90 has hidden child 173 +RSInterface 90 has hidden child 175 +RSInterface 90 has hidden child 177 +RSInterface 90 has hidden child 179 +RSInterface 90 has hidden child 181 +RSInterface 91 has hidden child 10 +RSInterface 92 has hidden child 10 +RSInterface 93 has hidden child 10 +RSInterface 99 has hidden child 27 +RSInterface 99 has hidden child 29 +RSInterface 102 has hidden child 29 +RSInterface 103 has hidden child 7 +RSInterface 105 has hidden child 19 +RSInterface 105 has hidden child 35 +RSInterface 105 has hidden child 51 +RSInterface 105 has hidden child 66 +RSInterface 105 has hidden child 70 +RSInterface 105 has hidden child 85 +RSInterface 105 has hidden child 89 +RSInterface 105 has hidden child 104 +RSInterface 105 has hidden child 108 +RSInterface 105 has hidden child 123 +RSInterface 105 has hidden child 126 +RSInterface 105 has hidden child 156 +RSInterface 105 has hidden child 192 +RSInterface 105 has hidden child 197 +RSInterface 105 has hidden child 200 +RSInterface 106 has hidden child 19 +RSInterface 106 has hidden child 33 +RSInterface 106 has hidden child 47 +RSInterface 106 has hidden child 60 +RSInterface 106 has hidden child 64 +RSInterface 106 has hidden child 77 +RSInterface 106 has hidden child 81 +RSInterface 106 has hidden child 94 +RSInterface 106 has hidden child 98 +RSInterface 106 has hidden child 111 +RSInterface 106 has hidden child 126 +RSInterface 106 has hidden child 131 +RSInterface 106 has hidden child 140 +RSInterface 111 has hidden child 1 +RSInterface 111 has hidden child 41 +RSInterface 111 has hidden child 43 +RSInterface 111 has hidden child 45 +RSInterface 111 has hidden child 47 +RSInterface 111 has hidden child 49 +RSInterface 111 has hidden child 51 +RSInterface 111 has hidden child 53 +RSInterface 111 has hidden child 55 +RSInterface 111 has hidden child 57 +RSInterface 111 has hidden child 59 +RSInterface 111 has hidden child 61 +RSInterface 111 has hidden child 63 +RSInterface 111 has hidden child 65 +RSInterface 111 has hidden child 67 +RSInterface 111 has hidden child 69 +RSInterface 111 has hidden child 71 +RSInterface 111 has hidden child 73 +RSInterface 111 has hidden child 75 +RSInterface 111 has hidden child 77 +RSInterface 111 has hidden child 79 +RSInterface 111 has hidden child 81 +RSInterface 111 has hidden child 83 +RSInterface 112 has hidden child 10 +RSInterface 113 has hidden child 16 +RSInterface 127 has hidden child 21 +RSInterface 127 has hidden child 23 +RSInterface 127 has hidden child 25 +RSInterface 127 has hidden child 27 +RSInterface 128 has hidden child 18 +RSInterface 128 has hidden child 20 +RSInterface 128 has hidden child 22 +RSInterface 128 has hidden child 24 +RSInterface 128 has hidden child 26 +RSInterface 128 has hidden child 28 +RSInterface 128 has hidden child 30 +RSInterface 128 has hidden child 32 +RSInterface 129 has hidden child 26 +RSInterface 129 has hidden child 28 +RSInterface 129 has hidden child 30 +RSInterface 129 has hidden child 32 +RSInterface 129 has hidden child 34 +RSInterface 129 has hidden child 36 +RSInterface 129 has hidden child 38 +RSInterface 129 has hidden child 40 +RSInterface 129 has hidden child 42 +RSInterface 129 has hidden child 44 +RSInterface 129 has hidden child 46 +RSInterface 129 has hidden child 48 +RSInterface 130 has hidden child 40 +RSInterface 130 has hidden child 42 +RSInterface 130 has hidden child 44 +RSInterface 130 has hidden child 46 +RSInterface 130 has hidden child 48 +RSInterface 130 has hidden child 50 +RSInterface 130 has hidden child 52 +RSInterface 130 has hidden child 54 +RSInterface 130 has hidden child 56 +RSInterface 130 has hidden child 58 +RSInterface 130 has hidden child 60 +RSInterface 130 has hidden child 62 +RSInterface 130 has hidden child 64 +RSInterface 130 has hidden child 66 +RSInterface 130 has hidden child 68 +RSInterface 130 has hidden child 70 +RSInterface 130 has hidden child 72 +RSInterface 130 has hidden child 74 +RSInterface 130 has hidden child 76 +RSInterface 138 has hidden child 20 +RSInterface 138 has hidden child 21 +RSInterface 138 has hidden child 22 +RSInterface 138 has hidden child 23 +RSInterface 138 has hidden child 24 +RSInterface 138 has hidden child 25 +RSInterface 144 has hidden child 245 +RSInterface 144 has hidden child 259 +RSInterface 144 has hidden child 278 +RSInterface 144 has hidden child 298 +RSInterface 144 has hidden child 309 +RSInterface 144 has hidden child 321 +RSInterface 144 has hidden child 341 +RSInterface 144 has hidden child 355 +RSInterface 151 has hidden child 0 +RSInterface 151 has hidden child 1 +RSInterface 151 has hidden child 2 +RSInterface 151 has hidden child 3 +RSInterface 151 has hidden child 4 +RSInterface 151 has hidden child 5 +RSInterface 151 has hidden child 6 +RSInterface 151 has hidden child 7 +RSInterface 151 has hidden child 8 +RSInterface 152 has hidden child 0 +RSInterface 152 has hidden child 1 +RSInterface 152 has hidden child 2 +RSInterface 152 has hidden child 3 +RSInterface 152 has hidden child 4 +RSInterface 152 has hidden child 5 +RSInterface 152 has hidden child 6 +RSInterface 181 has hidden child 7 +RSInterface 181 has hidden child 8 +RSInterface 181 has hidden child 9 +RSInterface 181 has hidden child 10 +RSInterface 181 has hidden child 11 +RSInterface 181 has hidden child 12 +RSInterface 183 has hidden child 15 +RSInterface 183 has hidden child 16 +RSInterface 183 has hidden child 39 +RSInterface 183 has hidden child 43 +RSInterface 183 has hidden child 47 +RSInterface 183 has hidden child 50 +RSInterface 194 has hidden child 14 +RSInterface 194 has hidden child 15 +RSInterface 194 has hidden child 16 +RSInterface 194 has hidden child 17 +RSInterface 194 has hidden child 18 +RSInterface 195 has hidden child 4 +RSInterface 195 has hidden child 5 +RSInterface 195 has hidden child 6 +RSInterface 195 has hidden child 7 +RSInterface 208 has hidden child 0 +RSInterface 221 has hidden child 1 +RSInterface 232 has hidden child 8 +RSInterface 233 has hidden child 8 +RSInterface 234 has hidden child 9 +RSInterface 235 has hidden child 9 +RSInterface 236 has hidden child 6 +RSInterface 237 has hidden child 8 +RSInterface 238 has hidden child 9 +RSInterface 240 has hidden child 7 +RSInterface 240 has hidden child 12 +RSInterface 240 has hidden child 17 +RSInterface 240 has hidden child 22 +RSInterface 240 has hidden child 26 +RSInterface 252 has hidden child 2 +RSInterface 253 has hidden child 2 +RSInterface 255 has hidden child 2 +RSInterface 261 has hidden child 52 +RSInterface 261 has hidden child 54 +RSInterface 261 has hidden child 56 +RSInterface 261 has hidden child 58 +RSInterface 262 has hidden child 8 +RSInterface 262 has hidden child 10 +RSInterface 262 has hidden child 12 +RSInterface 262 has hidden child 14 +RSInterface 262 has hidden child 16 +RSInterface 262 has hidden child 18 +RSInterface 262 has hidden child 20 +RSInterface 262 has hidden child 22 +RSInterface 262 has hidden child 24 +RSInterface 262 has hidden child 26 +RSInterface 262 has hidden child 28 +RSInterface 262 has hidden child 30 +RSInterface 262 has hidden child 32 +RSInterface 262 has hidden child 34 +RSInterface 262 has hidden child 36 +RSInterface 267 has hidden child 4 +RSInterface 270 has hidden child 60 +RSInterface 275 has hidden child 176 +RSInterface 281 has hidden child 7 +RSInterface 287 has hidden child 0 +RSInterface 292 has hidden child 31 +RSInterface 292 has hidden child 32 +RSInterface 292 has hidden child 33 +RSInterface 292 has hidden child 34 +RSInterface 292 has hidden child 35 +RSInterface 292 has hidden child 36 +RSInterface 292 has hidden child 37 +RSInterface 292 has hidden child 38 +RSInterface 292 has hidden child 39 +RSInterface 292 has hidden child 40 +RSInterface 292 has hidden child 41 +RSInterface 292 has hidden child 42 +RSInterface 292 has hidden child 43 +RSInterface 292 has hidden child 44 +RSInterface 292 has hidden child 45 +RSInterface 292 has hidden child 46 +RSInterface 292 has hidden child 47 +RSInterface 292 has hidden child 48 +RSInterface 297 has hidden child 11 +RSInterface 297 has hidden child 13 +RSInterface 299 has hidden child 51 +RSInterface 300 has hidden child 66 +RSInterface 300 has hidden child 82 +RSInterface 300 has hidden child 90 +RSInterface 300 has hidden child 98 +RSInterface 300 has hidden child 162 +RSInterface 300 has hidden child 170 +RSInterface 300 has hidden child 210 +RSInterface 300 has hidden child 250 +RSInterface 300 has hidden child 267 +RSInterface 301 has hidden child 13 +RSInterface 301 has hidden child 18 +RSInterface 301 has hidden child 23 +RSInterface 301 has hidden child 28 +RSInterface 301 has hidden child 33 +RSInterface 301 has hidden child 38 +RSInterface 301 has hidden child 43 +RSInterface 301 has hidden child 48 +RSInterface 301 has hidden child 53 +RSInterface 316 has hidden child 0 +RSInterface 324 has hidden child 91 +RSInterface 325 has hidden child 90 +RSInterface 329 has hidden child 4 +RSInterface 329 has hidden child 23 +RSInterface 329 has hidden child 27 +RSInterface 329 has hidden child 31 +RSInterface 332 has hidden child 90 +RSInterface 334 has hidden child 17 +RSInterface 334 has hidden child 19 +RSInterface 334 has hidden child 37 +RSInterface 334 has hidden child 38 +RSInterface 334 has hidden child 39 +RSInterface 334 has hidden child 40 +RSInterface 334 has hidden child 41 +RSInterface 334 has hidden child 42 +RSInterface 334 has hidden child 43 +RSInterface 334 has hidden child 45 +RSInterface 335 has hidden child 13 +RSInterface 335 has hidden child 14 +RSInterface 335 has hidden child 39 +RSInterface 335 has hidden child 40 +RSInterface 335 has hidden child 41 +RSInterface 337 has hidden child 3 +RSInterface 339 has hidden child 2 +RSInterface 340 has hidden child 2 +RSInterface 341 has hidden child 2 +RSInterface 342 has hidden child 2 +RSInterface 358 has hidden child 52 +RSInterface 360 has hidden child 77 +RSInterface 363 has hidden child 5 +RSInterface 369 has hidden child 59 +RSInterface 383 has hidden child 6 +RSInterface 383 has hidden child 9 +RSInterface 383 has hidden child 12 +RSInterface 383 has hidden child 15 +RSInterface 383 has hidden child 18 +RSInterface 389 has hidden child 0 +RSInterface 390 has hidden child 2 +RSInterface 391 has hidden child 139 +RSInterface 391 has hidden child 141 +RSInterface 415 has hidden child 7 +RSInterface 415 has hidden child 9 +RSInterface 415 has hidden child 11 +RSInterface 415 has hidden child 22 +RSInterface 415 has hidden child 24 +RSInterface 415 has hidden child 26 +RSInterface 415 has hidden child 28 +RSInterface 415 has hidden child 30 +RSInterface 415 has hidden child 32 +RSInterface 415 has hidden child 34 +RSInterface 415 has hidden child 36 +RSInterface 415 has hidden child 38 +RSInterface 415 has hidden child 40 +RSInterface 415 has hidden child 48 +RSInterface 415 has hidden child 50 +RSInterface 415 has hidden child 52 +RSInterface 415 has hidden child 54 +RSInterface 415 has hidden child 56 +RSInterface 416 has hidden child 9 +RSInterface 416 has hidden child 12 +RSInterface 416 has hidden child 15 +RSInterface 424 has hidden child 3 +RSInterface 429 has hidden child 98 +RSInterface 429 has hidden child 99 +RSInterface 429 has hidden child 100 +RSInterface 429 has hidden child 101 +RSInterface 429 has hidden child 102 +RSInterface 429 has hidden child 103 +RSInterface 429 has hidden child 104 +RSInterface 429 has hidden child 105 +RSInterface 429 has hidden child 106 +RSInterface 429 has hidden child 107 +RSInterface 429 has hidden child 108 +RSInterface 429 has hidden child 109 +RSInterface 429 has hidden child 111 +RSInterface 434 has hidden child 101 +RSInterface 434 has hidden child 112 +RSInterface 434 has hidden child 121 +RSInterface 434 has hidden child 134 +RSInterface 434 has hidden child 141 +RSInterface 435 has hidden child 99 +RSInterface 435 has hidden child 108 +RSInterface 435 has hidden child 121 +RSInterface 435 has hidden child 128 +RSInterface 436 has hidden child 103 +RSInterface 436 has hidden child 110 +RSInterface 436 has hidden child 119 +RSInterface 436 has hidden child 128 +RSInterface 436 has hidden child 137 +RSInterface 436 has hidden child 148 +RSInterface 436 has hidden child 161 +RSInterface 437 has hidden child 97 +RSInterface 437 has hidden child 104 +RSInterface 437 has hidden child 113 +RSInterface 437 has hidden child 120 +RSInterface 443 has hidden child 6 +RSInterface 445 has hidden child 35 +RSInterface 447 has hidden child 96 +RSInterface 451 has hidden child 7 +RSInterface 460 has hidden child 1 +RSInterface 460 has hidden child 3 +RSInterface 460 has hidden child 5 +RSInterface 460 has hidden child 7 +RSInterface 460 has hidden child 11 +RSInterface 460 has hidden child 12 +RSInterface 460 has hidden child 14 +RSInterface 460 has hidden child 16 +RSInterface 460 has hidden child 18 +RSInterface 461 has hidden child 10 +RSInterface 461 has hidden child 11 +RSInterface 461 has hidden child 12 +RSInterface 461 has hidden child 13 +RSInterface 463 has hidden child 5 +RSInterface 467 has hidden child 163 +RSInterface 467 has hidden child 166 +RSInterface 467 has hidden child 168 +RSInterface 467 has hidden child 170 +RSInterface 467 has hidden child 172 +RSInterface 467 has hidden child 174 +RSInterface 467 has hidden child 176 +RSInterface 467 has hidden child 178 +RSInterface 467 has hidden child 180 +RSInterface 467 has hidden child 182 +RSInterface 467 has hidden child 184 +RSInterface 467 has hidden child 186 +RSInterface 467 has hidden child 188 +RSInterface 467 has hidden child 190 +RSInterface 467 has hidden child 192 +RSInterface 467 has hidden child 194 +RSInterface 467 has hidden child 196 +RSInterface 467 has hidden child 198 +RSInterface 467 has hidden child 200 +RSInterface 467 has hidden child 202 +RSInterface 467 has hidden child 204 +RSInterface 467 has hidden child 206 +RSInterface 467 has hidden child 208 +RSInterface 467 has hidden child 210 +RSInterface 467 has hidden child 212 +RSInterface 467 has hidden child 214 +RSInterface 467 has hidden child 216 +RSInterface 467 has hidden child 218 +RSInterface 467 has hidden child 220 +RSInterface 467 has hidden child 222 +RSInterface 467 has hidden child 224 +RSInterface 468 has hidden child 6 +RSInterface 469 has hidden child 15 +RSInterface 469 has hidden child 24 +RSInterface 469 has hidden child 26 +RSInterface 469 has hidden child 27 +RSInterface 469 has hidden child 29 +RSInterface 469 has hidden child 31 +RSInterface 469 has hidden child 34 +RSInterface 473 has hidden child 10 +RSInterface 474 has hidden child 10 +RSInterface 475 has hidden child 10 +RSInterface 476 has hidden child 10 +RSInterface 480 has hidden child 4 +RSInterface 480 has hidden child 50 +RSInterface 480 has hidden child 51 +RSInterface 480 has hidden child 52 +RSInterface 480 has hidden child 53 +RSInterface 480 has hidden child 54 +RSInterface 480 has hidden child 55 +RSInterface 480 has hidden child 56 +RSInterface 480 has hidden child 57 +RSInterface 484 has hidden child 29 +RSInterface 488 has hidden child 12 +RSInterface 488 has hidden child 16 +RSInterface 488 has hidden child 22 +RSInterface 488 has hidden child 28 +RSInterface 489 has hidden child 16 +RSInterface 489 has hidden child 17 +RSInterface 489 has hidden child 18 +RSInterface 489 has hidden child 19 +RSInterface 491 has hidden child 209 +RSInterface 492 has hidden child 49 +RSInterface 492 has hidden child 51 +RSInterface 493 has hidden child 17 +RSInterface 493 has hidden child 40 +RSInterface 493 has hidden child 42 +RSInterface 493 has hidden child 44 +RSInterface 493 has hidden child 46 +RSInterface 493 has hidden child 48 +RSInterface 493 has hidden child 50 +RSInterface 496 has hidden child 15 +RSInterface 497 has hidden child 60 +RSInterface 497 has hidden child 61 +RSInterface 497 has hidden child 75 +RSInterface 501 has hidden child 13 +RSInterface 501 has hidden child 16 +RSInterface 501 has hidden child 19 +RSInterface 501 has hidden child 22 +RSInterface 501 has hidden child 25 +RSInterface 502 has hidden child 13 +RSInterface 502 has hidden child 16 +RSInterface 502 has hidden child 19 +RSInterface 502 has hidden child 22 +RSInterface 502 has hidden child 25 +RSInterface 503 has hidden child 6 +RSInterface 508 has hidden child 9 +RSInterface 508 has hidden child 11 +RSInterface 508 has hidden child 13 +RSInterface 508 has hidden child 15 +RSInterface 508 has hidden child 17 +RSInterface 508 has hidden child 19 +RSInterface 508 has hidden child 21 +RSInterface 508 has hidden child 23 +RSInterface 508 has hidden child 25 +RSInterface 508 has hidden child 27 +RSInterface 508 has hidden child 29 +RSInterface 508 has hidden child 31 +RSInterface 508 has hidden child 33 +RSInterface 508 has hidden child 35 +RSInterface 509 has hidden child 3 +RSInterface 509 has hidden child 5 +RSInterface 509 has hidden child 15 +RSInterface 509 has hidden child 20 +RSInterface 509 has hidden child 27 +RSInterface 509 has hidden child 30 +RSInterface 509 has hidden child 33 +RSInterface 509 has hidden child 42 +RSInterface 509 has hidden child 45 +RSInterface 509 has hidden child 50 +RSInterface 509 has hidden child 53 +RSInterface 510 has hidden child 7 +RSInterface 510 has hidden child 13 +RSInterface 510 has hidden child 41 +RSInterface 510 has hidden child 44 +RSInterface 510 has hidden child 47 +RSInterface 510 has hidden child 50 +RSInterface 510 has hidden child 53 +RSInterface 510 has hidden child 56 +RSInterface 510 has hidden child 58 +RSInterface 510 has hidden child 61 +RSInterface 510 has hidden child 63 +RSInterface 510 has hidden child 66 +RSInterface 510 has hidden child 68 +RSInterface 510 has hidden child 71 +RSInterface 510 has hidden child 73 +RSInterface 510 has hidden child 78 +RSInterface 510 has hidden child 81 +RSInterface 510 has hidden child 83 +RSInterface 510 has hidden child 86 +RSInterface 510 has hidden child 89 +RSInterface 510 has hidden child 94 +RSInterface 510 has hidden child 101 +RSInterface 510 has hidden child 104 +RSInterface 510 has hidden child 108 +RSInterface 510 has hidden child 111 +RSInterface 510 has hidden child 118 +RSInterface 510 has hidden child 120 +RSInterface 510 has hidden child 122 +RSInterface 510 has hidden child 124 +RSInterface 510 has hidden child 126 +RSInterface 510 has hidden child 130 +RSInterface 510 has hidden child 139 +RSInterface 510 has hidden child 141 +RSInterface 510 has hidden child 147 +RSInterface 510 has hidden child 149 +RSInterface 511 has hidden child 16 +RSInterface 511 has hidden child 19 +RSInterface 511 has hidden child 23 +RSInterface 511 has hidden child 27 +RSInterface 511 has hidden child 31 +RSInterface 520 has hidden child 0 +RSInterface 520 has hidden child 2 +RSInterface 520 has hidden child 4 +RSInterface 520 has hidden child 6 +RSInterface 520 has hidden child 8 +RSInterface 520 has hidden child 10 +RSInterface 520 has hidden child 12 +RSInterface 520 has hidden child 14 +RSInterface 520 has hidden child 16 +RSInterface 520 has hidden child 18 +RSInterface 521 has hidden child 15 +RSInterface 521 has hidden child 72 +RSInterface 521 has hidden child 74 +RSInterface 521 has hidden child 76 +RSInterface 523 has hidden child 101 +RSInterface 527 has hidden child 3 +RSInterface 527 has hidden child 6 +RSInterface 527 has hidden child 9 +RSInterface 527 has hidden child 12 +RSInterface 527 has hidden child 15 +RSInterface 527 has hidden child 18 +RSInterface 527 has hidden child 21 +RSInterface 527 has hidden child 24 +RSInterface 527 has hidden child 27 +RSInterface 527 has hidden child 30 +RSInterface 527 has hidden child 33 +RSInterface 527 has hidden child 39 +RSInterface 527 has hidden child 64 +RSInterface 527 has hidden child 66 +RSInterface 527 has hidden child 68 +RSInterface 527 has hidden child 70 +RSInterface 527 has hidden child 72 +RSInterface 527 has hidden child 74 +RSInterface 527 has hidden child 76 +RSInterface 527 has hidden child 78 +RSInterface 527 has hidden child 80 +RSInterface 527 has hidden child 82 +RSInterface 527 has hidden child 84 +RSInterface 527 has hidden child 86 +RSInterface 527 has hidden child 88 +RSInterface 527 has hidden child 90 +RSInterface 527 has hidden child 92 +RSInterface 527 has hidden child 94 +RSInterface 527 has hidden child 96 +RSInterface 527 has hidden child 98 +RSInterface 527 has hidden child 100 +RSInterface 527 has hidden child 102 +RSInterface 527 has hidden child 104 +RSInterface 527 has hidden child 106 +RSInterface 527 has hidden child 107 +RSInterface 527 has hidden child 114 +RSInterface 527 has hidden child 117 +RSInterface 527 has hidden child 120 +RSInterface 527 has hidden child 123 +RSInterface 527 has hidden child 126 +RSInterface 527 has hidden child 129 +RSInterface 527 has hidden child 132 +RSInterface 527 has hidden child 135 +RSInterface 527 has hidden child 138 +RSInterface 527 has hidden child 141 +RSInterface 527 has hidden child 144 +RSInterface 527 has hidden child 149 +RSInterface 527 has hidden child 151 +RSInterface 527 has hidden child 155 +RSInterface 527 has hidden child 158 +RSInterface 527 has hidden child 161 +RSInterface 527 has hidden child 164 +RSInterface 527 has hidden child 167 +RSInterface 527 has hidden child 170 +RSInterface 527 has hidden child 173 +RSInterface 527 has hidden child 176 +RSInterface 527 has hidden child 179 +RSInterface 527 has hidden child 182 +RSInterface 527 has hidden child 185 +RSInterface 527 has hidden child 188 +RSInterface 527 has hidden child 191 +RSInterface 527 has hidden child 194 +RSInterface 527 has hidden child 196 +RSInterface 530 has hidden child 5 +RSInterface 533 has hidden child 26 +RSInterface 533 has hidden child 27 +RSInterface 534 has hidden child 64 +RSInterface 535 has hidden child 2 +RSInterface 535 has hidden child 22 +RSInterface 535 has hidden child 24 +RSInterface 540 has hidden child 92 +RSInterface 540 has hidden child 127 +RSInterface 553 has hidden child 16 +RSInterface 559 has hidden child 7 +RSInterface 559 has hidden child 71 +RSInterface 591 has hidden child 64 +RSInterface 591 has hidden child 67 +RSInterface 591 has hidden child 70 +RSInterface 591 has hidden child 73 +RSInterface 591 has hidden child 76 +RSInterface 591 has hidden child 79 +RSInterface 591 has hidden child 82 +RSInterface 591 has hidden child 85 +RSInterface 591 has hidden child 88 +RSInterface 591 has hidden child 91 +RSInterface 591 has hidden child 94 +RSInterface 591 has hidden child 97 +RSInterface 591 has hidden child 100 +RSInterface 591 has hidden child 103 +RSInterface 591 has hidden child 106 +RSInterface 591 has hidden child 109 +RSInterface 591 has hidden child 112 +RSInterface 591 has hidden child 115 +RSInterface 591 has hidden child 118 +RSInterface 591 has hidden child 121 +RSInterface 591 has hidden child 124 +RSInterface 591 has hidden child 127 +RSInterface 591 has hidden child 130 +RSInterface 591 has hidden child 133 +RSInterface 591 has hidden child 136 +RSInterface 591 has hidden child 139 +RSInterface 591 has hidden child 142 +RSInterface 591 has hidden child 145 +RSInterface 591 has hidden child 148 +RSInterface 591 has hidden child 151 +RSInterface 591 has hidden child 154 +RSInterface 591 has hidden child 157 +RSInterface 591 has hidden child 160 +RSInterface 591 has hidden child 163 +RSInterface 591 has hidden child 166 +RSInterface 591 has hidden child 169 +RSInterface 591 has hidden child 172 +RSInterface 591 has hidden child 175 +RSInterface 591 has hidden child 176 +RSInterface 591 has hidden child 177 +RSInterface 591 has hidden child 178 +RSInterface 592 has hidden child 67 +RSInterface 592 has hidden child 70 +RSInterface 592 has hidden child 73 +RSInterface 592 has hidden child 76 +RSInterface 592 has hidden child 79 +RSInterface 592 has hidden child 82 +RSInterface 592 has hidden child 85 +RSInterface 592 has hidden child 88 +RSInterface 592 has hidden child 91 +RSInterface 592 has hidden child 94 +RSInterface 592 has hidden child 97 +RSInterface 592 has hidden child 100 +RSInterface 592 has hidden child 103 +RSInterface 592 has hidden child 106 +RSInterface 592 has hidden child 109 +RSInterface 592 has hidden child 112 +RSInterface 592 has hidden child 115 +RSInterface 592 has hidden child 118 +RSInterface 592 has hidden child 121 +RSInterface 592 has hidden child 124 +RSInterface 592 has hidden child 127 +RSInterface 592 has hidden child 130 +RSInterface 593 has hidden child 75 +RSInterface 593 has hidden child 78 +RSInterface 593 has hidden child 81 +RSInterface 593 has hidden child 84 +RSInterface 593 has hidden child 87 +RSInterface 593 has hidden child 90 +RSInterface 593 has hidden child 93 +RSInterface 593 has hidden child 96 +RSInterface 593 has hidden child 99 +RSInterface 593 has hidden child 102 +RSInterface 593 has hidden child 105 +RSInterface 593 has hidden child 108 +RSInterface 593 has hidden child 111 +RSInterface 593 has hidden child 114 +RSInterface 593 has hidden child 116 +RSInterface 594 has hidden child 64 +RSInterface 594 has hidden child 66 +RSInterface 594 has hidden child 70 +RSInterface 594 has hidden child 73 +RSInterface 594 has hidden child 76 +RSInterface 594 has hidden child 79 +RSInterface 594 has hidden child 82 +RSInterface 594 has hidden child 85 +RSInterface 594 has hidden child 88 +RSInterface 594 has hidden child 91 +RSInterface 594 has hidden child 94 +RSInterface 594 has hidden child 97 +RSInterface 594 has hidden child 100 +RSInterface 594 has hidden child 103 +RSInterface 594 has hidden child 106 +RSInterface 594 has hidden child 109 +RSInterface 594 has hidden child 112 +RSInterface 594 has hidden child 115 +RSInterface 594 has hidden child 118 +RSInterface 594 has hidden child 121 +RSInterface 594 has hidden child 124 +RSInterface 594 has hidden child 127 +RSInterface 594 has hidden child 130 +RSInterface 594 has hidden child 133 +RSInterface 594 has hidden child 136 +RSInterface 594 has hidden child 139 +RSInterface 594 has hidden child 142 +RSInterface 594 has hidden child 145 +RSInterface 594 has hidden child 148 +RSInterface 594 has hidden child 151 +RSInterface 594 has hidden child 154 +RSInterface 594 has hidden child 157 +RSInterface 594 has hidden child 160 +RSInterface 594 has hidden child 163 +RSInterface 594 has hidden child 166 +RSInterface 594 has hidden child 169 +RSInterface 594 has hidden child 172 +RSInterface 594 has hidden child 175 +RSInterface 594 has hidden child 176 +RSInterface 594 has hidden child 177 +RSInterface 594 has hidden child 178 +RSInterface 595 has hidden child 75 +RSInterface 595 has hidden child 78 +RSInterface 595 has hidden child 81 +RSInterface 595 has hidden child 84 +RSInterface 595 has hidden child 87 +RSInterface 595 has hidden child 90 +RSInterface 595 has hidden child 93 +RSInterface 595 has hidden child 96 +RSInterface 595 has hidden child 99 +RSInterface 595 has hidden child 102 +RSInterface 595 has hidden child 105 +RSInterface 595 has hidden child 108 +RSInterface 595 has hidden child 111 +RSInterface 595 has hidden child 114 +RSInterface 595 has hidden child 116 +RSInterface 596 has hidden child 67 +RSInterface 596 has hidden child 70 +RSInterface 596 has hidden child 73 +RSInterface 596 has hidden child 76 +RSInterface 596 has hidden child 79 +RSInterface 596 has hidden child 82 +RSInterface 596 has hidden child 85 +RSInterface 596 has hidden child 88 +RSInterface 596 has hidden child 91 +RSInterface 596 has hidden child 94 +RSInterface 596 has hidden child 97 +RSInterface 596 has hidden child 100 +RSInterface 596 has hidden child 103 +RSInterface 596 has hidden child 106 +RSInterface 596 has hidden child 109 +RSInterface 596 has hidden child 112 +RSInterface 596 has hidden child 115 +RSInterface 596 has hidden child 118 +RSInterface 596 has hidden child 121 +RSInterface 596 has hidden child 124 +RSInterface 596 has hidden child 127 +RSInterface 596 has hidden child 130 +RSInterface 596 has hidden child 133 +RSInterface 596 has hidden child 136 +RSInterface 596 has hidden child 139 +RSInterface 596 has hidden child 142 +RSInterface 596 has hidden child 145 +RSInterface 596 has hidden child 148 +RSInterface 596 has hidden child 151 +RSInterface 596 has hidden child 154 +RSInterface 596 has hidden child 157 +RSInterface 596 has hidden child 159 +RSInterface 596 has hidden child 166 +RSInterface 613 has hidden child 16 +RSInterface 619 has hidden child 45 +RSInterface 619 has hidden child 46 +RSInterface 619 has hidden child 47 +RSInterface 619 has hidden child 48 +RSInterface 619 has hidden child 49 +RSInterface 619 has hidden child 50 +RSInterface 619 has hidden child 51 +RSInterface 619 has hidden child 52 +RSInterface 619 has hidden child 53 +RSInterface 619 has hidden child 54 +RSInterface 619 has hidden child 55 +RSInterface 619 has hidden child 56 +RSInterface 619 has hidden child 57 +RSInterface 619 has hidden child 58 +RSInterface 620 has hidden child 25 +RSInterface 620 has hidden child 27 +RSInterface 624 has hidden child 35 +RSInterface 624 has hidden child 37 +RSInterface 624 has hidden child 39 +RSInterface 624 has hidden child 48 +RSInterface 624 has hidden child 50 +RSInterface 624 has hidden child 52 +RSInterface 624 has hidden child 54 +RSInterface 624 has hidden child 56 +RSInterface 624 has hidden child 58 +RSInterface 633 has hidden child 31 +RSInterface 634 has hidden child 32 +RSInterface 635 has hidden child 1 +RSInterface 635 has hidden child 2 +RSInterface 635 has hidden child 3 +RSInterface 635 has hidden child 4 +RSInterface 635 has hidden child 5 +RSInterface 635 has hidden child 6 +RSInterface 635 has hidden child 7 +RSInterface 635 has hidden child 8 +RSInterface 635 has hidden child 9 +RSInterface 635 has hidden child 10 +RSInterface 641 has hidden child 2 +RSInterface 641 has hidden child 3 +RSInterface 641 has hidden child 4 +RSInterface 641 has hidden child 5 +RSInterface 641 has hidden child 6 +RSInterface 641 has hidden child 7 +RSInterface 641 has hidden child 8 +RSInterface 641 has hidden child 9 +RSInterface 641 has hidden child 10 +RSInterface 641 has hidden child 11 +RSInterface 641 has hidden child 26 +RSInterface 653 has hidden child 8 +RSInterface 653 has hidden child 11 +RSInterface 656 has hidden child 8 +RSInterface 664 has hidden child 14 +RSInterface 680 has hidden child 10 +RSInterface 681 has hidden child 11 +RSInterface 681 has hidden child 18 +RSInterface 681 has hidden child 19 +RSInterface 681 has hidden child 20 +RSInterface 681 has hidden child 21 +RSInterface 681 has hidden child 22 +RSInterface 681 has hidden child 23 +RSInterface 681 has hidden child 24 +RSInterface 681 has hidden child 25 +RSInterface 681 has hidden child 26 +RSInterface 681 has hidden child 27 +RSInterface 681 has hidden child 28 +RSInterface 681 has hidden child 29 +RSInterface 681 has hidden child 30 +RSInterface 681 has hidden child 31 +RSInterface 681 has hidden child 32 +RSInterface 681 has hidden child 33 +RSInterface 681 has hidden child 34 +RSInterface 681 has hidden child 35 +RSInterface 681 has hidden child 36 +RSInterface 681 has hidden child 37 +RSInterface 681 has hidden child 39 +RSInterface 681 has hidden child 40 +RSInterface 681 has hidden child 41 +RSInterface 681 has hidden child 42 +RSInterface 681 has hidden child 43 +RSInterface 681 has hidden child 44 +RSInterface 681 has hidden child 45 +RSInterface 681 has hidden child 46 +RSInterface 681 has hidden child 47 +RSInterface 681 has hidden child 48 +RSInterface 681 has hidden child 49 +RSInterface 681 has hidden child 50 +RSInterface 681 has hidden child 51 +RSInterface 681 has hidden child 52 +RSInterface 681 has hidden child 53 +RSInterface 681 has hidden child 54 +RSInterface 681 has hidden child 55 +RSInterface 681 has hidden child 56 +RSInterface 681 has hidden child 57 +RSInterface 681 has hidden child 110 +RSInterface 681 has hidden child 111 +RSInterface 681 has hidden child 112 +RSInterface 682 has hidden child 29 +RSInterface 682 has hidden child 31 +RSInterface 683 has hidden child 24 +RSInterface 683 has hidden child 25 +RSInterface 683 has hidden child 26 +RSInterface 683 has hidden child 27 +RSInterface 683 has hidden child 28 +RSInterface 683 has hidden child 29 +RSInterface 683 has hidden child 30 +RSInterface 683 has hidden child 31 +RSInterface 683 has hidden child 32 +RSInterface 683 has hidden child 33 +RSInterface 683 has hidden child 43 +RSInterface 693 has hidden child 3 +RSInterface 694 has hidden child 20 +RSInterface 694 has hidden child 31 +RSInterface 694 has hidden child 34 +RSInterface 696 has hidden child 20 +RSInterface 696 has hidden child 31 +RSInterface 696 has hidden child 34 +RSInterface 697 has hidden child 26 +RSInterface 697 has hidden child 37 +RSInterface 697 has hidden child 40 +RSInterface 697 has hidden child 43 +RSInterface 699 has hidden child 20 +RSInterface 699 has hidden child 31 +RSInterface 699 has hidden child 34 +RSInterface 704 has hidden child 26 +RSInterface 704 has hidden child 37 +RSInterface 704 has hidden child 40 +RSInterface 704 has hidden child 43 +RSInterface 705 has hidden child 26 +RSInterface 705 has hidden child 37 +RSInterface 705 has hidden child 40 +RSInterface 705 has hidden child 43 +RSInterface 707 has hidden child 20 +RSInterface 707 has hidden child 31 +RSInterface 707 has hidden child 35 +RSInterface 708 has hidden child 20 +RSInterface 708 has hidden child 31 +RSInterface 708 has hidden child 34 +RSInterface 710 has hidden child 20 +RSInterface 710 has hidden child 31 +RSInterface 710 has hidden child 34 +RSInterface 714 has hidden child 0 +RSInterface 714 has hidden child 2 +RSInterface 714 has hidden child 4 +RSInterface 714 has hidden child 6 +RSInterface 716 has hidden child 39 +RSInterface 717 has hidden child 21 +RSInterface 717 has hidden child 33 +RSInterface 717 has hidden child 35 +RSInterface 730 has hidden child 23 +RSInterface 734 has hidden child 22 diff --git a/dumps/498/498_interface_configs.txt b/dumps/498/498_interface_configs.txt new file mode 100644 index 0000000..0497d92 --- /dev/null +++ b/dumps/498/498_interface_configs.txt @@ -0,0 +1,2017 @@ +s suppInterface 4 child 1 config: [449, 7] +Interface 4 child 2 config: [449, 7] +Interface 4 child 3 config: [449, 7] +Interface 4 child 4 config: [449, 7] +Interface 4 child 5 config: [449, 7] +Interface 4 child 6 config: [449, 7] +Interface 4 child 7 config: [449, 7] +Interface 4 child 8 config: [449, 7] +Interface 4 child 9 config: [449, 7] +Interface 4 child 10 config: [449, 7] +Interface 4 child 12 config: [449, 12] +Interface 4 child 13 config: [449, 12] +Interface 4 child 14 config: [449, 12] +Interface 4 child 15 config: [449, 12] +Interface 4 child 17 config: [449, 12] +Interface 4 child 16 config: [449, 12] +Interface 4 child 19 config: [449, 12] +Interface 4 child 18 config: [449, 12] +Interface 4 child 21 config: [449, 12] +Interface 4 child 20 config: [449, 12] +Interface 4 child 25 config: [449, 12] +Interface 5 child 0 config: [309, 2] +Interface 5 child 1 config: [309, 2] +Interface 9 child 27 config: [0, 0] +Interface 9 child 29 config: [0, 0] +Interface 12 child 93 config: [115, 0] +Interface 12 child 92 config: [115, 0] +Interface 12 child 98 config: [304, 0] +Interface 12 child 99 config: [304, 0] +Interface 24 child 0 config: [453, 17] +Interface 28 child 77 config: [545, 0] +Interface 28 child 75 config: [545, 8] +Interface 28 child 102 config: [546, 0] +Interface 28 child 103 config: [546, 8] +Interface 28 child 100 config: [545, 16] +Interface 28 child 101 config: [545, 24] +Interface 28 child 110 config: [545, 16] +Interface 28 child 111 config: [545, 24] +Interface 28 child 108 config: [545, 0] +Interface 28 child 109 config: [545, 8] +Interface 28 child 106 config: [549, 8] +Interface 28 child 107 config: [547, 0], [543, 12] +Interface 28 child 104 config: [546, 24] +Interface 28 child 105 config: [546, 16] +Interface 28 child 116 config: [549, 8] +Interface 28 child 115 config: [546, 16] +Interface 28 child 114 config: [546, 24] +Interface 28 child 113 config: [546, 8] +Interface 28 child 112 config: [546, 0] +Interface 31 child 76 config: [261, 0] +Interface 31 child 77 config: [261, 0] +Interface 31 child 84 config: [261, 0] +Interface 31 child 87 config: [261, 0] +Interface 33 child 76 config: [355, 0] +Interface 33 child 78 config: [355, 0] +Interface 33 child 79 config: [355, 0] +Interface 33 child 86 config: [355, 2] +Interface 33 child 80 config: [355, 0] +Interface 33 child 102 config: [355, 2] +Interface 33 child 103 config: [355, 2] +Interface 33 child 100 config: [355, 2] +Interface 33 child 101 config: [355, 2] +Interface 33 child 110 config: [355, 2] +Interface 33 child 108 config: [355, 2] +Interface 33 child 109 config: [355, 2] +Interface 33 child 106 config: [355, 2] +Interface 33 child 107 config: [355, 2] +Interface 33 child 104 config: [355, 2] +Interface 33 child 105 config: [355, 2] +Interface 33 child 112 config: [356, 15] +Interface 37 child 76 config: [355, 0] +Interface 37 child 78 config: [355, 0] +Interface 37 child 79 config: [355, 0] +Interface 37 child 86 config: [355, 2] +Interface 37 child 80 config: [355, 0] +Interface 37 child 102 config: [355, 2] +Interface 37 child 103 config: [355, 2] +Interface 37 child 100 config: [355, 2] +Interface 37 child 101 config: [355, 2] +Interface 37 child 110 config: [355, 2] +Interface 37 child 108 config: [355, 2] +Interface 37 child 109 config: [355, 2] +Interface 37 child 106 config: [355, 2] +Interface 37 child 107 config: [355, 2] +Interface 37 child 104 config: [355, 2] +Interface 37 child 105 config: [355, 2] +Interface 37 child 112 config: [356, 15] +Interface 40 child 137 config: [644, 9] +Interface 40 child 136 config: [644, 8] +Interface 40 child 139 config: [644, 11] +Interface 40 child 138 config: [644, 10] +Interface 40 child 141 config: [644, 13] +Interface 40 child 140 config: [644, 12] +Interface 40 child 143 config: [644, 15] +Interface 40 child 142 config: [644, 14] +Interface 40 child 129 config: [644, 1] +Interface 40 child 128 config: [644, 0] +Interface 40 child 131 config: [644, 3] +Interface 40 child 130 config: [644, 2] +Interface 40 child 133 config: [644, 5] +Interface 40 child 132 config: [644, 4] +Interface 40 child 135 config: [644, 7] +Interface 40 child 134 config: [644, 6] +Interface 40 child 152 config: [644, 24] +Interface 40 child 153 config: [644, 25] +Interface 40 child 154 config: [644, 26] +Interface 40 child 155 config: [644, 27] +Interface 40 child 156 config: [644, 28] +Interface 40 child 157 config: [644, 29] +Interface 40 child 158 config: [644, 30] +Interface 40 child 159 config: [644, 31] +Interface 40 child 144 config: [644, 16] +Interface 40 child 145 config: [644, 17] +Interface 40 child 146 config: [644, 18] +Interface 40 child 147 config: [644, 19] +Interface 40 child 148 config: [644, 20] +Interface 40 child 149 config: [644, 21] +Interface 40 child 150 config: [644, 22] +Interface 40 child 151 config: [644, 23] +Interface 40 child 171 config: [645, 11] +Interface 40 child 170 config: [645, 10] +Interface 40 child 169 config: [645, 9] +Interface 40 child 168 config: [645, 8] +Interface 40 child 175 config: [645, 15] +Interface 40 child 174 config: [645, 14] +Interface 40 child 173 config: [645, 13] +Interface 40 child 172 config: [645, 12] +Interface 40 child 163 config: [645, 3] +Interface 40 child 162 config: [645, 2] +Interface 40 child 161 config: [645, 1] +Interface 40 child 160 config: [645, 0] +Interface 40 child 167 config: [645, 7] +Interface 40 child 166 config: [645, 6] +Interface 40 child 165 config: [645, 5] +Interface 40 child 164 config: [645, 4] +Interface 40 child 186 config: [646, 2] +Interface 40 child 187 config: [646, 3] +Interface 40 child 184 config: [646, 0] +Interface 40 child 185 config: [646, 1] +Interface 40 child 190 config: [646, 6] +Interface 40 child 191 config: [646, 7] +Interface 40 child 188 config: [646, 4] +Interface 40 child 189 config: [646, 5] +Interface 40 child 178 config: [645, 18] +Interface 40 child 179 config: [645, 19] +Interface 40 child 176 config: [645, 16] +Interface 40 child 177 config: [645, 17] +Interface 40 child 182 config: [645, 22] +Interface 40 child 183 config: [645, 23] +Interface 40 child 180 config: [645, 20] +Interface 40 child 181 config: [645, 21] +Interface 40 child 205 config: [646, 21] +Interface 40 child 204 config: [646, 20] +Interface 40 child 207 config: [646, 23] +Interface 40 child 206 config: [646, 22] +Interface 40 child 201 config: [646, 17] +Interface 40 child 200 config: [646, 16] +Interface 40 child 203 config: [646, 19] +Interface 40 child 202 config: [646, 18] +Interface 40 child 197 config: [646, 13] +Interface 40 child 196 config: [646, 12] +Interface 40 child 199 config: [646, 15] +Interface 40 child 198 config: [646, 14] +Interface 40 child 193 config: [646, 9] +Interface 40 child 192 config: [646, 8] +Interface 40 child 195 config: [646, 11] +Interface 40 child 194 config: [646, 10] +Interface 40 child 220 config: [647, 4] +Interface 40 child 221 config: [647, 5] +Interface 40 child 222 config: [647, 6] +Interface 40 child 223 config: [647, 7] +Interface 40 child 216 config: [647, 0] +Interface 40 child 217 config: [647, 1] +Interface 40 child 218 config: [647, 2] +Interface 40 child 219 config: [647, 3] +Interface 40 child 212 config: [646, 28] +Interface 40 child 213 config: [646, 29] +Interface 40 child 214 config: [646, 30] +Interface 40 child 215 config: [646, 31] +Interface 40 child 208 config: [646, 24] +Interface 40 child 209 config: [646, 25] +Interface 40 child 210 config: [646, 26] +Interface 40 child 211 config: [646, 27] +Interface 40 child 239 config: [647, 23] +Interface 40 child 238 config: [647, 22] +Interface 40 child 237 config: [647, 21] +Interface 40 child 236 config: [647, 20] +Interface 40 child 235 config: [647, 19] +Interface 40 child 234 config: [647, 18] +Interface 40 child 233 config: [647, 17] +Interface 40 child 232 config: [647, 16] +Interface 40 child 231 config: [647, 15] +Interface 40 child 230 config: [647, 14] +Interface 40 child 229 config: [647, 13] +Interface 40 child 228 config: [647, 12] +Interface 40 child 227 config: [647, 11] +Interface 40 child 226 config: [647, 10] +Interface 40 child 225 config: [647, 9] +Interface 40 child 224 config: [647, 8] +Interface 40 child 305 config: [644, 12] +Interface 40 child 304 config: [644, 11] +Interface 40 child 307 config: [644, 14] +Interface 40 child 306 config: [644, 13] +Interface 40 child 309 config: [644, 16] +Interface 40 child 308 config: [644, 15] +Interface 40 child 311 config: [644, 18] +Interface 40 child 310 config: [644, 17] +Interface 40 child 313 config: [644, 20] +Interface 40 child 312 config: [644, 19] +Interface 40 child 315 config: [644, 22] +Interface 40 child 314 config: [644, 21] +Interface 40 child 317 config: [644, 24] +Interface 40 child 316 config: [644, 23] +Interface 40 child 319 config: [644, 26] +Interface 40 child 318 config: [644, 25] +Interface 40 child 293 config: [644, 0] +Interface 40 child 294 config: [644, 1] +Interface 40 child 295 config: [644, 2] +Interface 40 child 296 config: [644, 3] +Interface 40 child 297 config: [644, 4] +Interface 40 child 298 config: [644, 5] +Interface 40 child 299 config: [644, 6] +Interface 40 child 300 config: [644, 7] +Interface 40 child 301 config: [644, 8] +Interface 40 child 302 config: [644, 9] +Interface 40 child 303 config: [644, 10] +Interface 40 child 343 config: [645, 18] +Interface 40 child 342 config: [645, 17] +Interface 40 child 341 config: [645, 16] +Interface 40 child 340 config: [645, 15] +Interface 40 child 339 config: [645, 14] +Interface 40 child 338 config: [645, 13] +Interface 40 child 337 config: [645, 12] +Interface 40 child 336 config: [645, 11] +Interface 40 child 351 config: [646, 2] +Interface 40 child 350 config: [646, 1] +Interface 40 child 349 config: [646, 0] +Interface 40 child 348 config: [645, 23] +Interface 40 child 347 config: [645, 22] +Interface 40 child 346 config: [645, 21] +Interface 40 child 345 config: [645, 20] +Interface 40 child 344 config: [645, 19] +Interface 40 child 326 config: [645, 1] +Interface 40 child 327 config: [645, 2] +Interface 40 child 324 config: [644, 31] +Interface 40 child 325 config: [645, 0] +Interface 40 child 322 config: [644, 29] +Interface 40 child 323 config: [644, 30] +Interface 40 child 320 config: [644, 27] +Interface 40 child 321 config: [644, 28] +Interface 40 child 334 config: [645, 9] +Interface 40 child 335 config: [645, 10] +Interface 40 child 332 config: [645, 7] +Interface 40 child 333 config: [645, 8] +Interface 40 child 330 config: [645, 5] +Interface 40 child 331 config: [645, 6] +Interface 40 child 328 config: [645, 3] +Interface 40 child 329 config: [645, 4] +Interface 40 child 373 config: [646, 24] +Interface 40 child 372 config: [646, 23] +Interface 40 child 375 config: [646, 26] +Interface 40 child 374 config: [646, 25] +Interface 40 child 369 config: [646, 20] +Interface 40 child 368 config: [646, 19] +Interface 40 child 371 config: [646, 22] +Interface 40 child 370 config: [646, 21] +Interface 40 child 381 config: [647, 0] +Interface 40 child 380 config: [646, 31] +Interface 40 child 383 config: [647, 2] +Interface 40 child 382 config: [647, 1] +Interface 40 child 377 config: [646, 28] +Interface 40 child 376 config: [646, 27] +Interface 40 child 379 config: [646, 30] +Interface 40 child 378 config: [646, 29] +Interface 40 child 356 config: [646, 7] +Interface 40 child 357 config: [646, 8] +Interface 40 child 358 config: [646, 9] +Interface 40 child 359 config: [646, 10] +Interface 40 child 352 config: [646, 3] +Interface 40 child 353 config: [646, 4] +Interface 40 child 354 config: [646, 5] +Interface 40 child 355 config: [646, 6] +Interface 40 child 364 config: [646, 15] +Interface 40 child 365 config: [646, 16] +Interface 40 child 366 config: [646, 17] +Interface 40 child 367 config: [646, 18] +Interface 40 child 360 config: [646, 11] +Interface 40 child 361 config: [646, 12] +Interface 40 child 362 config: [646, 13] +Interface 40 child 363 config: [646, 14] +Interface 40 child 402 config: [647, 21] +Interface 40 child 403 config: [647, 22] +Interface 40 child 400 config: [647, 19] +Interface 40 child 401 config: [647, 20] +Interface 40 child 404 config: [647, 23] +Interface 40 child 395 config: [647, 14] +Interface 40 child 394 config: [647, 13] +Interface 40 child 393 config: [647, 12] +Interface 40 child 392 config: [647, 11] +Interface 40 child 399 config: [647, 18] +Interface 40 child 398 config: [647, 17] +Interface 40 child 397 config: [647, 16] +Interface 40 child 396 config: [647, 15] +Interface 40 child 387 config: [647, 6] +Interface 40 child 386 config: [647, 5] +Interface 40 child 385 config: [647, 4] +Interface 40 child 384 config: [647, 3] +Interface 40 child 391 config: [647, 10] +Interface 40 child 390 config: [647, 9] +Interface 40 child 389 config: [647, 8] +Interface 40 child 388 config: [647, 7] +Interface 41 child 76 config: [355, 0] +Interface 41 child 78 config: [355, 0] +Interface 41 child 79 config: [355, 0] +Interface 41 child 86 config: [355, 2] +Interface 41 child 80 config: [355, 0] +Interface 41 child 102 config: [355, 2] +Interface 41 child 103 config: [355, 2] +Interface 41 child 100 config: [355, 2] +Interface 41 child 101 config: [355, 2] +Interface 41 child 110 config: [355, 2] +Interface 41 child 108 config: [355, 2] +Interface 41 child 109 config: [355, 2] +Interface 41 child 106 config: [355, 2] +Interface 41 child 107 config: [355, 2] +Interface 41 child 104 config: [355, 2] +Interface 41 child 105 config: [355, 2] +Interface 41 child 112 config: [356, 15] +Interface 43 child 110 config: [644, 4] +Interface 43 child 111 config: [644, 5] +Interface 43 child 108 config: [644, 2] +Interface 43 child 109 config: [644, 3] +Interface 43 child 106 config: [644, 0] +Interface 43 child 107 config: [644, 1] +Interface 43 child 119 config: [644, 13] +Interface 43 child 118 config: [644, 12] +Interface 43 child 117 config: [644, 11] +Interface 43 child 116 config: [644, 10] +Interface 43 child 115 config: [644, 9] +Interface 43 child 114 config: [644, 8] +Interface 43 child 113 config: [644, 7] +Interface 43 child 112 config: [644, 6] +Interface 43 child 127 config: [644, 21] +Interface 43 child 126 config: [644, 20] +Interface 43 child 125 config: [644, 19] +Interface 43 child 124 config: [644, 18] +Interface 43 child 123 config: [644, 17] +Interface 43 child 122 config: [644, 16] +Interface 43 child 121 config: [644, 15] +Interface 43 child 120 config: [644, 14] +Interface 43 child 137 config: [644, 31] +Interface 43 child 136 config: [644, 30] +Interface 43 child 139 config: [645, 1] +Interface 43 child 138 config: [645, 0] +Interface 43 child 141 config: [645, 3] +Interface 43 child 140 config: [645, 2] +Interface 43 child 143 config: [645, 5] +Interface 43 child 142 config: [645, 4] +Interface 43 child 129 config: [644, 23] +Interface 43 child 128 config: [644, 22] +Interface 43 child 131 config: [644, 25] +Interface 43 child 130 config: [644, 24] +Interface 43 child 133 config: [644, 27] +Interface 43 child 132 config: [644, 26] +Interface 43 child 135 config: [644, 29] +Interface 43 child 134 config: [644, 28] +Interface 43 child 152 config: [645, 14] +Interface 43 child 153 config: [645, 15] +Interface 43 child 154 config: [645, 16] +Interface 43 child 155 config: [645, 17] +Interface 43 child 156 config: [645, 18] +Interface 43 child 157 config: [645, 19] +Interface 43 child 158 config: [645, 20] +Interface 43 child 159 config: [645, 21] +Interface 43 child 144 config: [645, 6] +Interface 43 child 145 config: [645, 7] +Interface 43 child 146 config: [645, 8] +Interface 43 child 147 config: [645, 9] +Interface 43 child 148 config: [645, 10] +Interface 43 child 149 config: [645, 11] +Interface 43 child 150 config: [645, 12] +Interface 43 child 151 config: [645, 13] +Interface 43 child 171 config: [646, 9] +Interface 43 child 170 config: [646, 8] +Interface 43 child 169 config: [646, 7] +Interface 43 child 168 config: [646, 6] +Interface 43 child 175 config: [646, 13] +Interface 43 child 174 config: [646, 12] +Interface 43 child 173 config: [646, 11] +Interface 43 child 172 config: [646, 10] +Interface 43 child 163 config: [646, 1] +Interface 43 child 162 config: [646, 0] +Interface 43 child 161 config: [645, 23] +Interface 43 child 160 config: [645, 22] +Interface 43 child 167 config: [646, 5] +Interface 43 child 166 config: [646, 4] +Interface 43 child 165 config: [646, 3] +Interface 43 child 164 config: [646, 2] +Interface 43 child 186 config: [646, 24] +Interface 43 child 187 config: [646, 25] +Interface 43 child 184 config: [646, 22] +Interface 43 child 185 config: [646, 23] +Interface 43 child 190 config: [646, 28] +Interface 43 child 191 config: [646, 29] +Interface 43 child 188 config: [646, 26] +Interface 43 child 189 config: [646, 27] +Interface 43 child 178 config: [646, 16] +Interface 43 child 179 config: [646, 17] +Interface 43 child 176 config: [646, 14] +Interface 43 child 177 config: [646, 15] +Interface 43 child 182 config: [646, 20] +Interface 43 child 183 config: [646, 21] +Interface 43 child 180 config: [646, 18] +Interface 43 child 181 config: [646, 19] +Interface 43 child 205 config: [647, 11] +Interface 43 child 204 config: [647, 10] +Interface 43 child 207 config: [647, 13] +Interface 43 child 206 config: [647, 12] +Interface 43 child 201 config: [647, 7] +Interface 43 child 200 config: [647, 6] +Interface 43 child 203 config: [647, 9] +Interface 43 child 202 config: [647, 8] +Interface 43 child 197 config: [647, 3] +Interface 43 child 196 config: [647, 2] +Interface 43 child 199 config: [647, 5] +Interface 43 child 198 config: [647, 4] +Interface 43 child 193 config: [646, 31] +Interface 43 child 192 config: [646, 30] +Interface 43 child 195 config: [647, 1] +Interface 43 child 194 config: [647, 0] +Interface 43 child 216 config: [647, 22] +Interface 43 child 217 config: [647, 23] +Interface 43 child 212 config: [647, 18] +Interface 43 child 213 config: [647, 19] +Interface 43 child 214 config: [647, 20] +Interface 43 child 215 config: [647, 21] +Interface 43 child 208 config: [647, 14] +Interface 43 child 209 config: [647, 15] +Interface 43 child 210 config: [647, 16] +Interface 43 child 211 config: [647, 17] +Interface 45 child 76 config: [355, 0] +Interface 45 child 78 config: [355, 0] +Interface 45 child 79 config: [355, 0] +Interface 45 child 86 config: [355, 2] +Interface 45 child 80 config: [355, 0] +Interface 45 child 102 config: [355, 2] +Interface 45 child 103 config: [355, 2] +Interface 45 child 100 config: [355, 2] +Interface 45 child 101 config: [355, 2] +Interface 45 child 110 config: [355, 2] +Interface 45 child 108 config: [355, 2] +Interface 45 child 109 config: [355, 2] +Interface 45 child 106 config: [355, 2] +Interface 45 child 107 config: [355, 2] +Interface 45 child 104 config: [355, 2] +Interface 45 child 105 config: [355, 2] +Interface 45 child 112 config: [356, 15] +Interface 48 child 7 config: [261, 0] +Interface 48 child 8 config: [261, 0] +Interface 58 child 0 config: [377, 24] +Interface 58 child 1 config: [378, 24] +Interface 58 child 4 config: [378, 21] +Interface 58 child 5 config: [377, 21] +Interface 58 child 7 config: [378, 0] +Interface 58 child 8 config: [380, 0] +Interface 58 child 11 config: [378, 7] +Interface 58 child 13 config: [378, 8] +Interface 58 child 15 config: [378, 9] +Interface 58 child 17 config: [378, 10] +Interface 58 child 19 config: [378, 21] +Interface 58 child 18 config: [378, 21] +Interface 58 child 21 config: [377, 21] +Interface 58 child 20 config: [377, 21] +Interface 59 child 0 config: [377, 24] +Interface 59 child 1 config: [378, 24] +Interface 59 child 4 config: [378, 21] +Interface 59 child 5 config: [377, 21] +Interface 59 child 7 config: [377, 0] +Interface 59 child 8 config: [380, 0] +Interface 59 child 11 config: [377, 7] +Interface 59 child 13 config: [377, 8] +Interface 59 child 15 config: [377, 9] +Interface 59 child 17 config: [377, 10] +Interface 59 child 19 config: [378, 21] +Interface 59 child 18 config: [378, 21] +Interface 59 child 21 config: [377, 21] +Interface 59 child 20 config: [377, 21] +Interface 63 child 6 config: [621, 0] +Interface 63 child 7 config: [620, 0] +Interface 75 child 2 config: [43, 0] +Interface 75 child 3 config: [43, 0] +Interface 75 child 4 config: [43, 0] +Interface 75 child 5 config: [43, 0] +Interface 75 child 14 config: [300, 0] +Interface 75 child 15 config: [300, 0] +Interface 75 child 17 config: [300, 0] +Interface 75 child 16 config: [300, 0] +Interface 75 child 19 config: [300, 0] +Interface 75 child 18 config: [300, 0] +Interface 75 child 21 config: [300, 0] +Interface 75 child 20 config: [300, 0] +Interface 75 child 23 config: [300, 0] +Interface 75 child 22 config: [300, 0] +Interface 75 child 24 config: [301, 0] +Interface 75 child 26 config: [172, 0] +Interface 75 child 30 config: [172, 0] +Interface 76 child 2 config: [43, 0] +Interface 76 child 3 config: [43, 0] +Interface 76 child 4 config: [43, 0] +Interface 76 child 12 config: [300, 0] +Interface 76 child 13 config: [300, 0] +Interface 76 child 14 config: [300, 0] +Interface 76 child 15 config: [300, 0] +Interface 76 child 17 config: [300, 0] +Interface 76 child 16 config: [300, 0] +Interface 76 child 19 config: [300, 0] +Interface 76 child 18 config: [300, 0] +Interface 76 child 21 config: [300, 0] +Interface 76 child 20 config: [300, 0] +Interface 76 child 22 config: [301, 0] +Interface 76 child 24 config: [172, 0] +Interface 76 child 28 config: [172, 0] +Interface 77 child 2 config: [43, 0] +Interface 77 child 3 config: [43, 0] +Interface 77 child 4 config: [43, 0] +Interface 77 child 12 config: [300, 0] +Interface 77 child 13 config: [300, 0] +Interface 77 child 14 config: [300, 0] +Interface 77 child 15 config: [300, 0] +Interface 77 child 17 config: [300, 0] +Interface 77 child 16 config: [300, 0] +Interface 77 child 19 config: [300, 0] +Interface 77 child 18 config: [300, 0] +Interface 77 child 21 config: [300, 0] +Interface 77 child 20 config: [300, 0] +Interface 77 child 22 config: [301, 0] +Interface 77 child 24 config: [172, 0] +Interface 77 child 28 config: [172, 0] +Interface 78 child 2 config: [43, 0] +Interface 78 child 3 config: [43, 0] +Interface 78 child 4 config: [43, 0] +Interface 78 child 5 config: [43, 0] +Interface 78 child 14 config: [300, 0] +Interface 78 child 15 config: [300, 0] +Interface 78 child 17 config: [300, 0] +Interface 78 child 16 config: [300, 0] +Interface 78 child 19 config: [300, 0] +Interface 78 child 18 config: [300, 0] +Interface 78 child 21 config: [300, 0] +Interface 78 child 20 config: [300, 0] +Interface 78 child 23 config: [300, 0] +Interface 78 child 22 config: [300, 0] +Interface 78 child 24 config: [301, 0] +Interface 78 child 26 config: [172, 0] +Interface 78 child 31 config: [172, 0] +Interface 79 child 2 config: [43, 0] +Interface 79 child 3 config: [43, 0] +Interface 79 child 4 config: [43, 0] +Interface 79 child 12 config: [300, 0] +Interface 79 child 13 config: [300, 0] +Interface 79 child 14 config: [300, 0] +Interface 79 child 15 config: [300, 0] +Interface 79 child 17 config: [300, 0] +Interface 79 child 16 config: [300, 0] +Interface 79 child 19 config: [300, 0] +Interface 79 child 18 config: [300, 0] +Interface 79 child 21 config: [300, 0] +Interface 79 child 20 config: [300, 0] +Interface 79 child 22 config: [301, 0] +Interface 79 child 24 config: [172, 0] +Interface 79 child 28 config: [172, 0] +Interface 80 child 2 config: [43, 0] +Interface 80 child 3 config: [43, 0] +Interface 80 child 7 config: [172, 0] +Interface 80 child 10 config: [172, 0] +Interface 81 child 2 config: [43, 0] +Interface 81 child 3 config: [43, 0] +Interface 81 child 4 config: [43, 0] +Interface 81 child 5 config: [43, 0] +Interface 81 child 14 config: [300, 0] +Interface 81 child 15 config: [300, 0] +Interface 81 child 17 config: [300, 0] +Interface 81 child 16 config: [300, 0] +Interface 81 child 19 config: [300, 0] +Interface 81 child 18 config: [300, 0] +Interface 81 child 21 config: [300, 0] +Interface 81 child 20 config: [300, 0] +Interface 81 child 23 config: [300, 0] +Interface 81 child 22 config: [300, 0] +Interface 81 child 24 config: [301, 0] +Interface 81 child 26 config: [172, 0] +Interface 81 child 31 config: [172, 0] +Interface 82 child 2 config: [43, 0] +Interface 82 child 3 config: [43, 0] +Interface 82 child 4 config: [43, 0] +Interface 82 child 5 config: [43, 0] +Interface 82 child 14 config: [300, 0] +Interface 82 child 15 config: [300, 0] +Interface 82 child 17 config: [300, 0] +Interface 82 child 16 config: [300, 0] +Interface 82 child 19 config: [300, 0] +Interface 82 child 18 config: [300, 0] +Interface 82 child 21 config: [300, 0] +Interface 82 child 20 config: [300, 0] +Interface 82 child 23 config: [300, 0] +Interface 82 child 22 config: [300, 0] +Interface 82 child 24 config: [301, 0] +Interface 82 child 26 config: [172, 0] +Interface 82 child 31 config: [172, 0] +Interface 83 child 2 config: [43, 0] +Interface 83 child 3 config: [43, 0] +Interface 83 child 4 config: [43, 0] +Interface 83 child 5 config: [43, 0] +Interface 83 child 14 config: [300, 0] +Interface 83 child 15 config: [300, 0] +Interface 83 child 17 config: [300, 0] +Interface 83 child 16 config: [300, 0] +Interface 83 child 19 config: [300, 0] +Interface 83 child 18 config: [300, 0] +Interface 83 child 21 config: [300, 0] +Interface 83 child 20 config: [300, 0] +Interface 83 child 23 config: [300, 0] +Interface 83 child 22 config: [300, 0] +Interface 83 child 24 config: [301, 0] +Interface 83 child 26 config: [172, 0] +Interface 83 child 31 config: [172, 0] +Interface 84 child 2 config: [43, 0] +Interface 84 child 3 config: [43, 0] +Interface 84 child 4 config: [43, 0] +Interface 84 child 12 config: [300, 0] +Interface 84 child 13 config: [300, 0] +Interface 84 child 14 config: [300, 0] +Interface 84 child 15 config: [300, 0] +Interface 84 child 17 config: [300, 0] +Interface 84 child 16 config: [300, 0] +Interface 84 child 19 config: [300, 0] +Interface 84 child 18 config: [300, 0] +Interface 84 child 21 config: [300, 0] +Interface 84 child 20 config: [300, 0] +Interface 84 child 22 config: [301, 0] +Interface 84 child 24 config: [172, 0] +Interface 84 child 28 config: [172, 0] +Interface 85 child 2 config: [43, 0] +Interface 85 child 3 config: [43, 0] +Interface 85 child 4 config: [43, 0] +Interface 85 child 12 config: [300, 0] +Interface 85 child 13 config: [300, 0] +Interface 85 child 14 config: [300, 0] +Interface 85 child 15 config: [300, 0] +Interface 85 child 17 config: [300, 0] +Interface 85 child 16 config: [300, 0] +Interface 85 child 19 config: [300, 0] +Interface 85 child 18 config: [300, 0] +Interface 85 child 21 config: [300, 0] +Interface 85 child 20 config: [300, 0] +Interface 85 child 22 config: [301, 0] +Interface 85 child 24 config: [172, 0] +Interface 85 child 28 config: [172, 0] +Interface 86 child 2 config: [43, 0] +Interface 86 child 3 config: [43, 0] +Interface 86 child 4 config: [43, 0] +Interface 86 child 5 config: [43, 0] +Interface 86 child 11 config: [172, 0] +Interface 86 child 16 config: [172, 0] +Interface 87 child 2 config: [43, 0] +Interface 87 child 3 config: [43, 0] +Interface 87 child 4 config: [43, 0] +Interface 87 child 5 config: [43, 0] +Interface 87 child 14 config: [300, 0] +Interface 87 child 15 config: [300, 0] +Interface 87 child 17 config: [300, 0] +Interface 87 child 16 config: [300, 0] +Interface 87 child 19 config: [300, 0] +Interface 87 child 18 config: [300, 0] +Interface 87 child 21 config: [300, 0] +Interface 87 child 20 config: [300, 0] +Interface 87 child 23 config: [300, 0] +Interface 87 child 22 config: [300, 0] +Interface 87 child 24 config: [301, 0] +Interface 87 child 26 config: [172, 0] +Interface 87 child 31 config: [172, 0] +Interface 88 child 2 config: [43, 0] +Interface 88 child 3 config: [43, 0] +Interface 88 child 4 config: [43, 0] +Interface 88 child 5 config: [43, 0] +Interface 88 child 14 config: [300, 0] +Interface 88 child 15 config: [300, 0] +Interface 88 child 17 config: [300, 0] +Interface 88 child 16 config: [300, 0] +Interface 88 child 19 config: [300, 0] +Interface 88 child 18 config: [300, 0] +Interface 88 child 21 config: [300, 0] +Interface 88 child 20 config: [300, 0] +Interface 88 child 23 config: [300, 0] +Interface 88 child 22 config: [300, 0] +Interface 88 child 24 config: [301, 0] +Interface 88 child 26 config: [172, 0] +Interface 88 child 31 config: [172, 0] +Interface 89 child 2 config: [43, 0] +Interface 89 child 3 config: [43, 0] +Interface 89 child 4 config: [43, 0] +Interface 89 child 5 config: [43, 0] +Interface 89 child 14 config: [300, 0] +Interface 89 child 15 config: [300, 0] +Interface 89 child 17 config: [300, 0] +Interface 89 child 16 config: [300, 0] +Interface 89 child 19 config: [300, 0] +Interface 89 child 18 config: [300, 0] +Interface 89 child 21 config: [300, 0] +Interface 89 child 20 config: [300, 0] +Interface 89 child 23 config: [300, 0] +Interface 89 child 22 config: [300, 0] +Interface 89 child 24 config: [301, 0] +Interface 89 child 26 config: [172, 0] +Interface 89 child 31 config: [172, 0] +Interface 90 child 1 config: [43, 0] +Interface 90 child 2 config: [43, 0] +Interface 90 child 3 config: [43, 0] +Interface 90 child 4 config: [439, 8] +Interface 90 child 5 config: [43, 0], [439, 8] +Interface 90 child 9 config: [172, 0] +Interface 90 child 10 config: [172, 0] +Interface 90 child 93 config: [300, 0] +Interface 90 child 92 config: [300, 0] +Interface 90 child 95 config: [300, 0] +Interface 90 child 94 config: [300, 0] +Interface 90 child 89 config: [300, 0] +Interface 90 child 91 config: [300, 0] +Interface 90 child 90 config: [300, 0] +Interface 90 child 98 config: [300, 0] +Interface 90 child 99 config: [301, 0] +Interface 90 child 96 config: [300, 0] +Interface 90 child 97 config: [300, 0] +Interface 91 child 2 config: [43, 0] +Interface 91 child 3 config: [43, 0] +Interface 91 child 4 config: [43, 0] +Interface 91 child 12 config: [300, 0] +Interface 91 child 13 config: [300, 0] +Interface 91 child 14 config: [300, 0] +Interface 91 child 15 config: [300, 0] +Interface 91 child 17 config: [300, 0] +Interface 91 child 16 config: [300, 0] +Interface 91 child 19 config: [300, 0] +Interface 91 child 18 config: [300, 0] +Interface 91 child 21 config: [300, 0] +Interface 91 child 20 config: [300, 0] +Interface 91 child 22 config: [301, 0] +Interface 91 child 24 config: [172, 0] +Interface 91 child 28 config: [172, 0] +Interface 92 child 2 config: [43, 0] +Interface 92 child 3 config: [43, 0] +Interface 92 child 4 config: [43, 0] +Interface 92 child 12 config: [300, 0] +Interface 92 child 13 config: [300, 0] +Interface 92 child 14 config: [300, 0] +Interface 92 child 15 config: [300, 0] +Interface 92 child 17 config: [300, 0] +Interface 92 child 16 config: [300, 0] +Interface 92 child 19 config: [300, 0] +Interface 92 child 18 config: [300, 0] +Interface 92 child 21 config: [300, 0] +Interface 92 child 20 config: [300, 0] +Interface 92 child 22 config: [301, 0] +Interface 92 child 24 config: [172, 0] +Interface 92 child 28 config: [172, 0] +Interface 93 child 2 config: [43, 0] +Interface 93 child 3 config: [43, 0] +Interface 93 child 4 config: [43, 0] +Interface 93 child 12 config: [300, 0] +Interface 93 child 13 config: [300, 0] +Interface 93 child 14 config: [300, 0] +Interface 93 child 15 config: [300, 0] +Interface 93 child 17 config: [300, 0] +Interface 93 child 16 config: [300, 0] +Interface 93 child 19 config: [300, 0] +Interface 93 child 18 config: [300, 0] +Interface 93 child 21 config: [300, 0] +Interface 93 child 20 config: [300, 0] +Interface 93 child 22 config: [301, 0] +Interface 93 child 24 config: [172, 0] +Interface 93 child 28 config: [172, 0] +Interface 99 child 7 config: [261, 0] +Interface 99 child 8 config: [261, 0] +Interface 99 child 9 config: [261, 0] +Interface 99 child 10 config: [261, 0] +Interface 99 child 11 config: [261, 0] +Interface 99 child 12 config: [261, 0] +Interface 99 child 13 config: [261, 0] +Interface 99 child 14 config: [261, 0] +Interface 99 child 15 config: [261, 0] +Interface 99 child 17 config: [262, 0] +Interface 99 child 16 config: [261, 0] +Interface 99 child 19 config: [262, 0] +Interface 99 child 18 config: [262, 0] +Interface 99 child 21 config: [262, 0] +Interface 99 child 20 config: [262, 0] +Interface 99 child 23 config: [262, 0] +Interface 99 child 22 config: [262, 0] +Interface 99 child 25 config: [262, 0] +Interface 99 child 24 config: [262, 0] +Interface 99 child 26 config: [262, 0] +Interface 114 child 25 config: [262, 0] +Interface 114 child 24 config: [261, 0] +Interface 114 child 27 config: [264, 0] +Interface 114 child 26 config: [263, 0] +Interface 114 child 29 config: [266, 0] +Interface 114 child 28 config: [265, 0] +Interface 125 child 70 config: [615, 0] +Interface 125 child 71 config: [615, 0] +Interface 125 child 76 config: [615, 3] +Interface 125 child 77 config: [615, 3] +Interface 125 child 78 config: [615, 4] +Interface 125 child 79 config: [615, 4] +Interface 125 child 72 config: [615, 1] +Interface 125 child 73 config: [615, 1] +Interface 125 child 74 config: [615, 2] +Interface 125 child 75 config: [615, 2] +Interface 125 child 85 config: [615, 14] +Interface 125 child 84 config: [615, 14] +Interface 125 child 87 config: [615, 22] +Interface 125 child 86 config: [615, 22] +Interface 125 child 81 config: [615, 8] +Interface 125 child 80 config: [615, 8] +Interface 125 child 83 config: [615, 9] +Interface 125 child 82 config: [615, 9] +Interface 128 child 0 config: [524, 0] +Interface 128 child 1 config: [524, 0] +Interface 128 child 2 config: [524, 2] +Interface 128 child 3 config: [524, 2] +Interface 128 child 4 config: [524, 4] +Interface 128 child 5 config: [524, 4] +Interface 128 child 6 config: [524, 6] +Interface 128 child 7 config: [524, 6] +Interface 128 child 8 config: [524, 8] +Interface 128 child 9 config: [524, 8] +Interface 128 child 10 config: [524, 10] +Interface 128 child 11 config: [524, 10] +Interface 128 child 12 config: [524, 12] +Interface 128 child 13 config: [524, 12] +Interface 128 child 14 config: [524, 14] +Interface 128 child 15 config: [524, 14] +Interface 128 child 19 config: [524, 0] +Interface 128 child 21 config: [524, 2] +Interface 128 child 23 config: [524, 4] +Interface 128 child 25 config: [524, 6] +Interface 128 child 27 config: [524, 8] +Interface 128 child 29 config: [524, 10] +Interface 128 child 31 config: [524, 12] +Interface 128 child 33 config: [524, 14] +Interface 128 child 44 config: [525, 6] +Interface 128 child 45 config: [525, 14] +Interface 129 child 0 config: [524, 0] +Interface 129 child 1 config: [524, 0] +Interface 129 child 2 config: [524, 2] +Interface 129 child 3 config: [524, 2] +Interface 129 child 4 config: [524, 4] +Interface 129 child 5 config: [524, 4] +Interface 129 child 6 config: [524, 6] +Interface 129 child 7 config: [524, 6] +Interface 129 child 8 config: [524, 8] +Interface 129 child 9 config: [524, 8] +Interface 129 child 10 config: [524, 10] +Interface 129 child 11 config: [524, 10] +Interface 129 child 12 config: [524, 12] +Interface 129 child 13 config: [524, 12] +Interface 129 child 14 config: [524, 14] +Interface 129 child 15 config: [524, 14] +Interface 129 child 17 config: [524, 16] +Interface 129 child 16 config: [524, 16] +Interface 129 child 19 config: [524, 18] +Interface 129 child 18 config: [524, 18] +Interface 129 child 21 config: [524, 20] +Interface 129 child 20 config: [524, 20] +Interface 129 child 23 config: [524, 22] +Interface 129 child 22 config: [524, 22] +Interface 129 child 27 config: [524, 0] +Interface 129 child 29 config: [524, 2] +Interface 129 child 31 config: [524, 4] +Interface 129 child 35 config: [524, 8] +Interface 129 child 33 config: [524, 6] +Interface 129 child 39 config: [524, 12] +Interface 129 child 37 config: [524, 10] +Interface 129 child 43 config: [524, 16] +Interface 129 child 41 config: [524, 14] +Interface 129 child 47 config: [524, 20] +Interface 129 child 45 config: [524, 18] +Interface 129 child 49 config: [524, 22] +Interface 129 child 64 config: [525, 6] +Interface 129 child 65 config: [525, 14] +Interface 130 child 0 config: [524, 0] +Interface 130 child 1 config: [524, 0] +Interface 130 child 2 config: [524, 2] +Interface 130 child 3 config: [524, 2] +Interface 130 child 4 config: [524, 4] +Interface 130 child 5 config: [524, 4] +Interface 130 child 6 config: [524, 6] +Interface 130 child 7 config: [524, 6] +Interface 130 child 8 config: [524, 8] +Interface 130 child 9 config: [524, 8] +Interface 130 child 10 config: [524, 10] +Interface 130 child 11 config: [524, 10] +Interface 130 child 12 config: [524, 12] +Interface 130 child 13 config: [524, 12] +Interface 130 child 14 config: [524, 14] +Interface 130 child 15 config: [524, 14] +Interface 130 child 17 config: [524, 16] +Interface 130 child 16 config: [524, 16] +Interface 130 child 19 config: [524, 18] +Interface 130 child 18 config: [524, 18] +Interface 130 child 21 config: [524, 20] +Interface 130 child 20 config: [524, 20] +Interface 130 child 23 config: [524, 22] +Interface 130 child 22 config: [524, 22] +Interface 130 child 25 config: [524, 24] +Interface 130 child 24 config: [524, 24] +Interface 130 child 27 config: [524, 26] +Interface 130 child 26 config: [524, 26] +Interface 130 child 29 config: [524, 28] +Interface 130 child 28 config: [524, 28] +Interface 130 child 31 config: [524, 30] +Interface 130 child 30 config: [524, 30] +Interface 130 child 34 config: [525, 2] +Interface 130 child 35 config: [525, 2] +Interface 130 child 32 config: [525, 0] +Interface 130 child 33 config: [525, 0] +Interface 130 child 36 config: [525, 4] +Interface 130 child 37 config: [525, 4] +Interface 130 child 43 config: [524, 2] +Interface 130 child 41 config: [524, 0] +Interface 130 child 47 config: [524, 6] +Interface 130 child 45 config: [524, 4] +Interface 130 child 51 config: [524, 10] +Interface 130 child 49 config: [524, 8] +Interface 130 child 55 config: [524, 14] +Interface 130 child 53 config: [524, 12] +Interface 130 child 59 config: [524, 18] +Interface 130 child 57 config: [524, 16] +Interface 130 child 63 config: [524, 22] +Interface 130 child 61 config: [524, 20] +Interface 130 child 69 config: [524, 28] +Interface 130 child 71 config: [524, 30] +Interface 130 child 65 config: [524, 24] +Interface 130 child 67 config: [524, 26] +Interface 130 child 77 config: [525, 4] +Interface 130 child 73 config: [525, 0] +Interface 130 child 75 config: [525, 2] +Interface 130 child 100 config: [525, 6] +Interface 130 child 99 config: [525, 14] +Interface 138 child 34 config: [153, 0] +Interface 138 child 35 config: [153, 0] +Interface 138 child 32 config: [153, 0] +Interface 138 child 33 config: [153, 0] +Interface 138 child 38 config: [153, 0] +Interface 138 child 39 config: [153, 0] +Interface 138 child 36 config: [153, 0] +Interface 138 child 37 config: [153, 0] +Interface 138 child 42 config: [153, 0] +Interface 138 child 40 config: [153, 0] +Interface 138 child 41 config: [153, 0] +Interface 144 child 220 config: [383, 0] +Interface 144 child 221 config: [383, 13] +Interface 144 child 212 config: [383, 5] +Interface 144 child 213 config: [383, 6] +Interface 144 child 214 config: [383, 7] +Interface 144 child 215 config: [383, 8] +Interface 144 child 208 config: [383, 1] +Interface 144 child 209 config: [383, 2] +Interface 144 child 210 config: [383, 3] +Interface 144 child 211 config: [383, 4] +Interface 144 child 277 config: [383, 14] +Interface 144 child 258 config: [383, 15] +Interface 144 child 308 config: [383, 17] +Interface 144 child 297 config: [383, 16] +Interface 144 child 320 config: [383, 18] +Interface 144 child 369 config: [383, 13] +Interface 144 child 368 config: [383, 13] +Interface 144 child 354 config: [383, 19] +Interface 144 child 367 config: [383, 20] +Interface 189 child 9 config: [531, 0] +Interface 189 child 10 config: [531, 0] +Interface 189 child 11 config: [531, 0] +Interface 189 child 12 config: [531, 0] +Interface 189 child 13 config: [531, 0] +Interface 189 child 14 config: [531, 0] +Interface 199 child 119 config: [261, 0] +Interface 199 child 127 config: [262, 0] +Interface 199 child 126 config: [261, 0] +Interface 199 child 125 config: [261, 0] +Interface 199 child 124 config: [261, 0] +Interface 199 child 123 config: [261, 0] +Interface 199 child 122 config: [261, 0] +Interface 199 child 121 config: [261, 0] +Interface 199 child 120 config: [261, 0] +Interface 199 child 137 config: [262, 0] +Interface 199 child 136 config: [262, 0] +Interface 199 child 139 config: [261, 0] +Interface 199 child 138 config: [262, 0] +Interface 199 child 141 config: [261, 0] +Interface 199 child 140 config: [261, 0] +Interface 199 child 143 config: [261, 0] +Interface 199 child 142 config: [261, 0] +Interface 199 child 129 config: [262, 0] +Interface 199 child 128 config: [262, 0] +Interface 199 child 131 config: [262, 0] +Interface 199 child 130 config: [262, 0] +Interface 199 child 133 config: [262, 0] +Interface 199 child 132 config: [262, 0] +Interface 199 child 135 config: [262, 0] +Interface 199 child 134 config: [262, 0] +Interface 199 child 144 config: [261, 0] +Interface 199 child 145 config: [261, 0] +Interface 199 child 146 config: [261, 0] +Interface 200 child 100 config: [261, 0] +Interface 200 child 101 config: [261, 0] +Interface 200 child 98 config: [261, 0] +Interface 200 child 99 config: [261, 0] +Interface 200 child 96 config: [261, 0] +Interface 200 child 97 config: [261, 0] +Interface 201 child 93 config: [263, 0] +Interface 201 child 92 config: [263, 0] +Interface 201 child 95 config: [263, 0] +Interface 201 child 94 config: [263, 0] +Interface 201 child 91 config: [263, 0] +Interface 201 child 90 config: [263, 0] +Interface 201 child 102 config: [263, 0] +Interface 201 child 103 config: [263, 0] +Interface 201 child 100 config: [263, 0] +Interface 201 child 101 config: [263, 0] +Interface 201 child 98 config: [263, 0] +Interface 201 child 99 config: [263, 0] +Interface 201 child 96 config: [263, 0] +Interface 201 child 97 config: [263, 0] +Interface 201 child 110 config: [263, 0] +Interface 201 child 111 config: [263, 0] +Interface 201 child 108 config: [263, 0] +Interface 201 child 109 config: [263, 0] +Interface 201 child 107 config: [263, 0] +Interface 201 child 104 config: [263, 0] +Interface 201 child 105 config: [263, 0] +Interface 201 child 119 config: [263, 0] +Interface 201 child 118 config: [263, 0] +Interface 201 child 117 config: [263, 0] +Interface 201 child 116 config: [263, 0] +Interface 201 child 115 config: [263, 0] +Interface 201 child 114 config: [263, 0] +Interface 201 child 113 config: [263, 0] +Interface 201 child 112 config: [263, 0] +Interface 201 child 122 config: [263, 0] +Interface 201 child 121 config: [263, 0] +Interface 201 child 120 config: [263, 0] +Interface 201 child 137 config: [261, 0] +Interface 201 child 136 config: [261, 0] +Interface 201 child 139 config: [261, 0] +Interface 201 child 138 config: [261, 0] +Interface 201 child 141 config: [261, 0] +Interface 201 child 140 config: [261, 0] +Interface 201 child 143 config: [261, 0] +Interface 201 child 142 config: [261, 0] +Interface 201 child 131 config: [261, 0] +Interface 201 child 133 config: [261, 0] +Interface 201 child 132 config: [261, 0] +Interface 201 child 135 config: [261, 0] +Interface 201 child 134 config: [261, 0] +Interface 201 child 144 config: [261, 0] +Interface 202 child 93 config: [263, 0] +Interface 202 child 92 config: [263, 0] +Interface 202 child 95 config: [263, 0] +Interface 202 child 94 config: [263, 0] +Interface 202 child 91 config: [263, 0] +Interface 202 child 90 config: [263, 0] +Interface 202 child 102 config: [263, 0] +Interface 202 child 103 config: [263, 0] +Interface 202 child 100 config: [263, 0] +Interface 202 child 101 config: [263, 0] +Interface 202 child 98 config: [263, 0] +Interface 202 child 99 config: [263, 0] +Interface 202 child 96 config: [263, 0] +Interface 202 child 97 config: [263, 0] +Interface 202 child 110 config: [263, 0] +Interface 202 child 111 config: [263, 0] +Interface 202 child 108 config: [263, 0] +Interface 202 child 109 config: [263, 0] +Interface 202 child 107 config: [263, 0] +Interface 202 child 104 config: [263, 0] +Interface 202 child 105 config: [263, 0] +Interface 202 child 119 config: [263, 0] +Interface 202 child 118 config: [263, 0] +Interface 202 child 117 config: [263, 0] +Interface 202 child 116 config: [263, 0] +Interface 202 child 115 config: [263, 0] +Interface 202 child 114 config: [263, 0] +Interface 202 child 113 config: [263, 0] +Interface 202 child 112 config: [263, 0] +Interface 202 child 122 config: [263, 0] +Interface 202 child 121 config: [263, 0] +Interface 202 child 120 config: [263, 0] +Interface 202 child 152 config: [262, 0] +Interface 202 child 153 config: [262, 0] +Interface 202 child 154 config: [262, 0] +Interface 202 child 155 config: [262, 0] +Interface 202 child 146 config: [261, 0] +Interface 202 child 147 config: [261, 0] +Interface 202 child 148 config: [261, 0] +Interface 202 child 149 config: [261, 0] +Interface 202 child 150 config: [261, 0] +Interface 202 child 151 config: [262, 0] +Interface 203 child 119 config: [261, 0] +Interface 203 child 118 config: [261, 0] +Interface 203 child 117 config: [261, 0] +Interface 203 child 116 config: [261, 0] +Interface 203 child 115 config: [261, 0] +Interface 203 child 114 config: [261, 0] +Interface 203 child 127 config: [262, 0] +Interface 203 child 126 config: [262, 0] +Interface 203 child 125 config: [262, 0] +Interface 203 child 124 config: [262, 0] +Interface 203 child 123 config: [261, 0] +Interface 203 child 122 config: [261, 0] +Interface 203 child 121 config: [261, 0] +Interface 203 child 120 config: [261, 0] +Interface 203 child 137 config: [261, 0] +Interface 203 child 136 config: [261, 0] +Interface 203 child 139 config: [261, 0] +Interface 203 child 138 config: [261, 0] +Interface 203 child 141 config: [261, 0] +Interface 203 child 140 config: [261, 0] +Interface 203 child 143 config: [261, 0] +Interface 203 child 142 config: [261, 0] +Interface 203 child 129 config: [262, 0] +Interface 203 child 128 config: [262, 0] +Interface 203 child 131 config: [262, 0] +Interface 203 child 130 config: [262, 0] +Interface 203 child 133 config: [262, 0] +Interface 203 child 132 config: [262, 0] +Interface 203 child 135 config: [262, 0] +Interface 203 child 134 config: [262, 0] +Interface 203 child 144 config: [261, 0] +Interface 203 child 145 config: [261, 0] +Interface 204 child 119 config: [261, 0] +Interface 204 child 118 config: [261, 0] +Interface 204 child 117 config: [261, 0] +Interface 204 child 116 config: [261, 0] +Interface 204 child 115 config: [261, 0] +Interface 204 child 114 config: [261, 0] +Interface 204 child 113 config: [261, 0] +Interface 204 child 127 config: [262, 0] +Interface 204 child 126 config: [262, 0] +Interface 204 child 125 config: [262, 0] +Interface 204 child 124 config: [262, 0] +Interface 204 child 123 config: [262, 0] +Interface 204 child 122 config: [262, 0] +Interface 204 child 121 config: [261, 0] +Interface 204 child 120 config: [261, 0] +Interface 204 child 137 config: [261, 0] +Interface 204 child 136 config: [261, 0] +Interface 204 child 139 config: [261, 0] +Interface 204 child 138 config: [261, 0] +Interface 204 child 141 config: [261, 0] +Interface 204 child 140 config: [261, 0] +Interface 204 child 142 config: [261, 0] +Interface 204 child 129 config: [262, 0] +Interface 204 child 128 config: [262, 0] +Interface 204 child 131 config: [262, 0] +Interface 204 child 130 config: [262, 0] +Interface 204 child 133 config: [262, 0] +Interface 204 child 132 config: [262, 0] +Interface 204 child 135 config: [261, 0] +Interface 204 child 134 config: [261, 0] +Interface 205 child 93 config: [262, 0] +Interface 205 child 95 config: [262, 0] +Interface 205 child 94 config: [262, 0] +Interface 205 child 103 config: [261, 0] +Interface 205 child 100 config: [262, 0] +Interface 205 child 101 config: [261, 0] +Interface 205 child 98 config: [262, 0] +Interface 205 child 99 config: [262, 0] +Interface 205 child 96 config: [262, 0] +Interface 205 child 97 config: [262, 0] +Interface 205 child 110 config: [262, 0] +Interface 205 child 111 config: [262, 0] +Interface 205 child 108 config: [262, 0] +Interface 205 child 109 config: [262, 0] +Interface 205 child 106 config: [262, 0] +Interface 205 child 107 config: [262, 0] +Interface 205 child 104 config: [262, 0] +Interface 205 child 105 config: [262, 0] +Interface 205 child 113 config: [261, 0] +Interface 205 child 112 config: [261, 0] +Interface 206 child 93 config: [263, 0] +Interface 206 child 92 config: [263, 0] +Interface 206 child 95 config: [263, 0] +Interface 206 child 94 config: [263, 0] +Interface 206 child 91 config: [263, 0] +Interface 206 child 90 config: [263, 0] +Interface 206 child 102 config: [263, 0] +Interface 206 child 103 config: [263, 0] +Interface 206 child 100 config: [263, 0] +Interface 206 child 101 config: [263, 0] +Interface 206 child 98 config: [263, 0] +Interface 206 child 99 config: [263, 0] +Interface 206 child 96 config: [263, 0] +Interface 206 child 97 config: [263, 0] +Interface 206 child 110 config: [263, 0] +Interface 206 child 111 config: [263, 0] +Interface 206 child 108 config: [263, 0] +Interface 206 child 109 config: [263, 0] +Interface 206 child 107 config: [263, 0] +Interface 206 child 104 config: [263, 0] +Interface 206 child 105 config: [263, 0] +Interface 206 child 119 config: [263, 0] +Interface 206 child 118 config: [263, 0] +Interface 206 child 117 config: [263, 0] +Interface 206 child 116 config: [263, 0] +Interface 206 child 115 config: [263, 0] +Interface 206 child 114 config: [263, 0] +Interface 206 child 113 config: [263, 0] +Interface 206 child 112 config: [263, 0] +Interface 206 child 122 config: [263, 0] +Interface 206 child 121 config: [263, 0] +Interface 206 child 120 config: [263, 0] +Interface 206 child 129 config: [261, 0] +Interface 206 child 128 config: [261, 0] +Interface 206 child 131 config: [261, 0] +Interface 206 child 130 config: [261, 0] +Interface 206 child 133 config: [261, 0] +Interface 206 child 132 config: [261, 0] +Interface 206 child 135 config: [261, 0] +Interface 206 child 134 config: [261, 0] +Interface 207 child 93 config: [263, 0] +Interface 207 child 92 config: [263, 0] +Interface 207 child 95 config: [263, 0] +Interface 207 child 94 config: [263, 0] +Interface 207 child 91 config: [263, 0] +Interface 207 child 90 config: [263, 0] +Interface 207 child 102 config: [263, 0] +Interface 207 child 103 config: [263, 0] +Interface 207 child 100 config: [263, 0] +Interface 207 child 101 config: [263, 0] +Interface 207 child 98 config: [263, 0] +Interface 207 child 99 config: [263, 0] +Interface 207 child 96 config: [263, 0] +Interface 207 child 97 config: [263, 0] +Interface 207 child 110 config: [263, 0] +Interface 207 child 111 config: [263, 0] +Interface 207 child 108 config: [263, 0] +Interface 207 child 109 config: [263, 0] +Interface 207 child 107 config: [263, 0] +Interface 207 child 104 config: [263, 0] +Interface 207 child 105 config: [263, 0] +Interface 207 child 119 config: [263, 0] +Interface 207 child 118 config: [263, 0] +Interface 207 child 117 config: [263, 0] +Interface 207 child 116 config: [263, 0] +Interface 207 child 115 config: [263, 0] +Interface 207 child 114 config: [263, 0] +Interface 207 child 113 config: [263, 0] +Interface 207 child 112 config: [263, 0] +Interface 207 child 122 config: [263, 0] +Interface 207 child 121 config: [263, 0] +Interface 207 child 120 config: [263, 0] +Interface 207 child 157 config: [261, 0] +Interface 207 child 158 config: [261, 0] +Interface 207 child 159 config: [261, 0] +Interface 207 child 169 config: [262, 0] +Interface 207 child 168 config: [262, 0] +Interface 207 child 163 config: [261, 0] +Interface 207 child 162 config: [261, 0] +Interface 207 child 161 config: [261, 0] +Interface 207 child 160 config: [261, 0] +Interface 207 child 167 config: [262, 0] +Interface 207 child 166 config: [262, 0] +Interface 207 child 165 config: [262, 0] +Interface 207 child 164 config: [262, 0] +Interface 209 child 2 config: [531, 0] +Interface 261 child 0 config: [173, 0] +Interface 261 child 1 config: [171, 0] +Interface 261 child 2 config: [287, 0] +Interface 261 child 3 config: [170, 0] +Interface 261 child 4 config: [427, 0] +Interface 261 child 7 config: [166, 0] +Interface 261 child 8 config: [166, 0] +Interface 261 child 9 config: [166, 0] +Interface 261 child 10 config: [166, 0] +Interface 261 child 11 config: [168, 0] +Interface 261 child 12 config: [168, 0] +Interface 261 child 13 config: [168, 0] +Interface 261 child 14 config: [168, 0] +Interface 261 child 15 config: [168, 0] +Interface 261 child 17 config: [169, 0] +Interface 261 child 16 config: [169, 0] +Interface 261 child 19 config: [169, 0] +Interface 261 child 18 config: [169, 0] +Interface 261 child 20 config: [169, 0] +Interface 261 child 25 config: [168, 0] +Interface 261 child 26 config: [169, 0] +Interface 261 child 29 config: [872, 0] +Interface 261 child 31 config: [872, 0] +Interface 261 child 30 config: [872, 0] +Interface 261 child 34 config: [872, 0] +Interface 261 child 32 config: [872, 0] +Interface 261 child 33 config: [872, 0] +Interface 262 child 1 config: [262, 0] +Interface 262 child 2 config: [262, 0] +Interface 262 child 3 config: [262, 0] +Interface 262 child 13 config: [896, 16], [896, 20], [896, 24] +Interface 262 child 15 config: [896, 16], [896, 20], [896, 24] +Interface 262 child 38 config: [261, 0] +Interface 262 child 39 config: [261, 0] +Interface 262 child 37 config: [261, 0] +Interface 262 child 42 config: [261, 0] +Interface 262 child 40 config: [261, 0] +Interface 262 child 41 config: [261, 0] +Interface 270 child 5 config: [106, 0] +Interface 270 child 6 config: [106, 0] +Interface 270 child 7 config: [106, 0] +Interface 270 child 8 config: [106, 0] +Interface 270 child 9 config: [106, 0] +Interface 270 child 10 config: [106, 0] +Interface 270 child 11 config: [106, 0] +Interface 270 child 12 config: [106, 0] +Interface 270 child 13 config: [106, 0] +Interface 270 child 14 config: [106, 0] +Interface 270 child 15 config: [106, 0] +Interface 270 child 17 config: [106, 0] +Interface 270 child 16 config: [106, 0] +Interface 270 child 19 config: [106, 0] +Interface 270 child 18 config: [106, 0] +Interface 270 child 21 config: [106, 0] +Interface 270 child 20 config: [106, 0] +Interface 270 child 23 config: [106, 0] +Interface 270 child 22 config: [106, 0] +Interface 270 child 25 config: [106, 0] +Interface 270 child 24 config: [106, 0] +Interface 270 child 27 config: [106, 0] +Interface 270 child 26 config: [106, 0] +Interface 270 child 29 config: [106, 0] +Interface 270 child 28 config: [106, 0] +Interface 270 child 31 config: [106, 0] +Interface 270 child 30 config: [106, 0] +Interface 270 child 34 config: [106, 0] +Interface 270 child 35 config: [106, 0] +Interface 270 child 32 config: [106, 0] +Interface 270 child 33 config: [106, 0] +Interface 270 child 38 config: [106, 0] +Interface 270 child 39 config: [106, 0] +Interface 270 child 36 config: [106, 0] +Interface 270 child 37 config: [106, 0] +Interface 270 child 42 config: [106, 0] +Interface 270 child 43 config: [106, 0] +Interface 270 child 40 config: [106, 0] +Interface 270 child 41 config: [106, 0] +Interface 270 child 46 config: [106, 0] +Interface 270 child 44 config: [106, 0] +Interface 270 child 45 config: [106, 0] +Interface 276 child 5 config: [101, 0] +Interface 277 child 5 config: [101, 0] +Interface 282 child 11 config: [607, 19] +Interface 282 child 12 config: [607, 13] +Interface 282 child 13 config: [607, 13] +Interface 282 child 14 config: [607, 13] +Interface 282 child 15 config: [607, 13] +Interface 282 child 17 config: [607, 13] +Interface 282 child 16 config: [607, 13] +Interface 282 child 19 config: [607, 13] +Interface 282 child 18 config: [607, 13] +Interface 286 child 93 config: [331, 0] +Interface 286 child 95 config: [331, 2] +Interface 286 child 94 config: [331, 1] +Interface 286 child 102 config: [331, 9] +Interface 286 child 103 config: [331, 10] +Interface 286 child 100 config: [331, 7] +Interface 286 child 101 config: [331, 8] +Interface 286 child 98 config: [331, 5] +Interface 286 child 99 config: [331, 6] +Interface 286 child 96 config: [331, 3] +Interface 286 child 97 config: [331, 4] +Interface 286 child 110 config: [331, 17] +Interface 286 child 111 config: [331, 18] +Interface 286 child 108 config: [331, 15] +Interface 286 child 109 config: [331, 16] +Interface 286 child 106 config: [331, 13] +Interface 286 child 107 config: [331, 14] +Interface 286 child 104 config: [331, 11] +Interface 286 child 105 config: [331, 12] +Interface 286 child 118 config: [331, 25] +Interface 286 child 117 config: [331, 24] +Interface 286 child 116 config: [331, 23] +Interface 286 child 115 config: [331, 22] +Interface 286 child 114 config: [331, 21] +Interface 286 child 113 config: [331, 20] +Interface 286 child 112 config: [331, 19] +Interface 286 child 126 config: [331, 31] +Interface 286 child 125 config: [331, 30] +Interface 286 child 124 config: [331, 29] +Interface 286 child 123 config: [331, 28] +Interface 286 child 122 config: [331, 27] +Interface 286 child 121 config: [331, 26] +Interface 286 child 137 config: [330, 0] +Interface 286 child 136 config: [330, 0] +Interface 286 child 139 config: [330, 0] +Interface 286 child 138 config: [330, 0] +Interface 286 child 141 config: [330, 0] +Interface 286 child 140 config: [330, 0] +Interface 286 child 143 config: [330, 0] +Interface 286 child 142 config: [330, 0] +Interface 286 child 133 config: [330, 0] +Interface 286 child 132 config: [330, 0] +Interface 286 child 135 config: [330, 0] +Interface 286 child 134 config: [330, 0] +Interface 286 child 152 config: [330, 0] +Interface 286 child 153 config: [330, 0] +Interface 286 child 154 config: [330, 0] +Interface 286 child 155 config: [330, 0] +Interface 286 child 156 config: [330, 0] +Interface 286 child 144 config: [330, 0] +Interface 286 child 145 config: [330, 0] +Interface 286 child 146 config: [330, 0] +Interface 286 child 147 config: [330, 0] +Interface 286 child 148 config: [330, 0] +Interface 286 child 149 config: [330, 0] +Interface 286 child 150 config: [330, 0] +Interface 286 child 151 config: [330, 0] +Interface 287 child 0 config: [261, 0] +Interface 289 child 43 config: [261, 0] +Interface 289 child 46 config: [261, 0] +Interface 289 child 47 config: [261, 0] +Interface 289 child 44 config: [261, 0] +Interface 289 child 50 config: [261, 0] +Interface 289 child 49 config: [261, 0] +Interface 289 child 55 config: [261, 0] +Interface 289 child 53 config: [261, 0] +Interface 289 child 52 config: [261, 0] +Interface 289 child 56 config: [261, 0] +Interface 291 child 6 config: [493, 18] +Interface 291 child 7 config: [493, 18] +Interface 291 child 8 config: [493, 18] +Interface 291 child 9 config: [493, 18] +Interface 291 child 10 config: [493, 18] +Interface 299 child 27 config: [75, 0] +Interface 299 child 26 config: [75, 0] +Interface 299 child 29 config: [75, 0] +Interface 299 child 28 config: [75, 0] +Interface 299 child 31 config: [75, 0] +Interface 299 child 30 config: [75, 0] +Interface 299 child 34 config: [75, 0] +Interface 299 child 35 config: [75, 0] +Interface 299 child 32 config: [75, 0] +Interface 299 child 33 config: [75, 0] +Interface 299 child 38 config: [75, 0] +Interface 299 child 39 config: [75, 0] +Interface 299 child 36 config: [75, 0] +Interface 299 child 37 config: [75, 0] +Interface 299 child 42 config: [75, 0] +Interface 299 child 40 config: [75, 0] +Interface 299 child 41 config: [75, 0] +Interface 325 child 92 config: [158, 0] +Interface 325 child 95 config: [158, 0] +Interface 325 child 94 config: [156, 0] +Interface 325 child 102 config: [158, 0] +Interface 325 child 103 config: [158, 0] +Interface 325 child 100 config: [158, 0] +Interface 325 child 101 config: [158, 0] +Interface 325 child 98 config: [158, 0] +Interface 325 child 99 config: [158, 0] +Interface 325 child 96 config: [158, 0] +Interface 325 child 97 config: [158, 0] +Interface 325 child 107 config: [157, 0] +Interface 325 child 104 config: [158, 0] +Interface 325 child 119 config: [156, 0] +Interface 325 child 118 config: [156, 0] +Interface 325 child 117 config: [156, 0] +Interface 325 child 116 config: [156, 0] +Interface 325 child 115 config: [156, 0] +Interface 325 child 113 config: [156, 0] +Interface 325 child 122 config: [156, 0] +Interface 325 child 121 config: [156, 0] +Interface 325 child 120 config: [156, 0] +Interface 328 child 1 config: [343, 0] +Interface 328 child 3 config: [344, 0] +Interface 328 child 5 config: [345, 0] +Interface 329 child 34 config: [700, 19] +Interface 329 child 35 config: [700, 19] +Interface 329 child 38 config: [700, 19] +Interface 329 child 39 config: [700, 19] +Interface 329 child 36 config: [700, 19] +Interface 329 child 37 config: [700, 19] +Interface 329 child 42 config: [700, 19] +Interface 329 child 43 config: [700, 19] +Interface 329 child 40 config: [700, 19] +Interface 329 child 41 config: [700, 19] +Interface 329 child 46 config: [700, 19] +Interface 329 child 47 config: [700, 19] +Interface 329 child 44 config: [700, 19] +Interface 329 child 45 config: [700, 19] +Interface 329 child 51 config: [700, 19] +Interface 329 child 50 config: [700, 19] +Interface 329 child 49 config: [700, 19] +Interface 329 child 48 config: [700, 19] +Interface 329 child 55 config: [700, 19] +Interface 329 child 54 config: [700, 19] +Interface 329 child 53 config: [700, 19] +Interface 329 child 52 config: [700, 19] +Interface 329 child 58 config: [700, 19] +Interface 329 child 57 config: [700, 19] +Interface 329 child 56 config: [700, 19] +Interface 330 child 3 config: [261, 0] +Interface 330 child 4 config: [261, 0] +Interface 330 child 5 config: [261, 0] +Interface 330 child 6 config: [261, 0] +Interface 330 child 7 config: [261, 0] +Interface 330 child 8 config: [261, 0] +Interface 330 child 9 config: [261, 0] +Interface 330 child 10 config: [261, 0] +Interface 330 child 11 config: [261, 0] +Interface 363 child 5 config: [261, 0] +Interface 366 child 0 config: [391, 0] +Interface 366 child 1 config: [391, 0] +Interface 366 child 2 config: [391, 0] +Interface 366 child 3 config: [391, 0] +Interface 366 child 4 config: [391, 0] +Interface 366 child 5 config: [391, 0] +Interface 366 child 6 config: [391, 0] +Interface 366 child 7 config: [391, 0] +Interface 366 child 8 config: [391, 0] +Interface 366 child 9 config: [391, 0] +Interface 366 child 10 config: [391, 0] +Interface 366 child 11 config: [391, 0] +Interface 366 child 12 config: [391, 0] +Interface 366 child 13 config: [391, 0] +Interface 366 child 14 config: [391, 0] +Interface 366 child 15 config: [391, 0] +Interface 366 child 17 config: [391, 0] +Interface 366 child 16 config: [391, 0] +Interface 366 child 19 config: [391, 0] +Interface 366 child 18 config: [391, 0] +Interface 371 child 0 config: [406, 0] +Interface 371 child 1 config: [406, 0] +Interface 371 child 2 config: [406, 0] +Interface 371 child 3 config: [406, 0] +Interface 371 child 4 config: [406, 0] +Interface 371 child 5 config: [406, 0] +Interface 371 child 6 config: [406, 0] +Interface 371 child 7 config: [406, 0] +Interface 371 child 8 config: [406, 0] +Interface 371 child 9 config: [406, 0] +Interface 371 child 10 config: [406, 0] +Interface 371 child 11 config: [406, 0] +Interface 371 child 12 config: [406, 0] +Interface 371 child 13 config: [406, 0] +Interface 371 child 14 config: [406, 0] +Interface 371 child 15 config: [406, 0] +Interface 371 child 17 config: [406, 0] +Interface 371 child 16 config: [406, 0] +Interface 371 child 19 config: [406, 0] +Interface 371 child 18 config: [406, 0] +Interface 377 child 2 config: [535, 2] +Interface 391 child 12 config: [363, 12] +Interface 391 child 13 config: [363, 12] +Interface 391 child 14 config: [363, 12] +Interface 391 child 15 config: [363, 12] +Interface 391 child 17 config: [363, 12] +Interface 391 child 16 config: [363, 12] +Interface 391 child 19 config: [363, 12] +Interface 391 child 18 config: [363, 12] +Interface 391 child 21 config: [363, 12] +Interface 391 child 20 config: [363, 12] +Interface 391 child 29 config: [363, 0] +Interface 391 child 31 config: [363, 0] +Interface 391 child 30 config: [363, 0] +Interface 391 child 34 config: [363, 0] +Interface 391 child 35 config: [363, 0] +Interface 391 child 32 config: [363, 0] +Interface 391 child 33 config: [363, 0] +Interface 391 child 38 config: [363, 0] +Interface 391 child 36 config: [363, 0] +Interface 391 child 45 config: [363, 0] +Interface 391 child 51 config: [363, 4] +Interface 391 child 50 config: [363, 4] +Interface 391 child 49 config: [363, 4] +Interface 391 child 55 config: [363, 4] +Interface 391 child 54 config: [363, 4] +Interface 391 child 53 config: [363, 4] +Interface 391 child 52 config: [363, 4] +Interface 391 child 58 config: [363, 4] +Interface 391 child 57 config: [363, 4] +Interface 391 child 56 config: [363, 4] +Interface 391 child 68 config: [363, 8] +Interface 391 child 69 config: [363, 8] +Interface 391 child 70 config: [363, 8] +Interface 391 child 71 config: [363, 8] +Interface 391 child 64 config: [363, 8] +Interface 391 child 65 config: [363, 8] +Interface 391 child 66 config: [363, 8] +Interface 391 child 76 config: [261, 0] +Interface 391 child 77 config: [261, 0] +Interface 391 child 78 config: [261, 0] +Interface 391 child 72 config: [363, 8] +Interface 391 child 73 config: [363, 8] +Interface 391 child 74 config: [363, 8] +Interface 391 child 75 config: [261, 0] +Interface 391 child 85 config: [261, 0] +Interface 391 child 84 config: [261, 0] +Interface 391 child 87 config: [261, 0] +Interface 391 child 86 config: [261, 0] +Interface 391 child 83 config: [261, 0] +Interface 391 child 82 config: [261, 0] +Interface 391 child 92 config: [261, 0] +Interface 391 child 89 config: [261, 0] +Interface 391 child 88 config: [261, 0] +Interface 391 child 91 config: [261, 0] +Interface 391 child 90 config: [261, 0] +Interface 391 child 102 config: [262, 0] +Interface 391 child 103 config: [262, 0] +Interface 391 child 101 config: [262, 0] +Interface 391 child 110 config: [262, 0] +Interface 391 child 108 config: [262, 0] +Interface 391 child 109 config: [262, 0] +Interface 391 child 106 config: [262, 0] +Interface 391 child 107 config: [262, 0] +Interface 391 child 104 config: [262, 0] +Interface 391 child 105 config: [262, 0] +Interface 391 child 119 config: [729, 0] +Interface 391 child 118 config: [729, 0] +Interface 391 child 112 config: [362, 27] +Interface 391 child 127 config: [729, 0] +Interface 391 child 126 config: [729, 0] +Interface 391 child 125 config: [729, 0] +Interface 391 child 124 config: [729, 0] +Interface 391 child 123 config: [729, 0] +Interface 391 child 122 config: [729, 0] +Interface 391 child 121 config: [729, 0] +Interface 391 child 120 config: [729, 0] +Interface 391 child 129 config: [729, 8] +Interface 391 child 128 config: [729, 8] +Interface 391 child 130 config: [729, 8] +Interface 391 child 152 config: [729, 4] +Interface 391 child 153 config: [729, 4] +Interface 391 child 154 config: [729, 4] +Interface 391 child 155 config: [729, 10] +Interface 391 child 157 config: [729, 10] +Interface 391 child 145 config: [729, 4] +Interface 391 child 146 config: [729, 4] +Interface 391 child 147 config: [729, 4] +Interface 391 child 148 config: [729, 4] +Interface 391 child 149 config: [729, 4] +Interface 391 child 150 config: [729, 4] +Interface 391 child 151 config: [729, 4] +Interface 394 child 108 config: [262, 0] +Interface 394 child 109 config: [263, 0] +Interface 394 child 107 config: [261, 0] +Interface 396 child 137 config: [261, 5] +Interface 396 child 136 config: [261, 4] +Interface 396 child 139 config: [261, 7] +Interface 396 child 138 config: [261, 6] +Interface 396 child 133 config: [261, 1] +Interface 396 child 135 config: [261, 3] +Interface 396 child 134 config: [261, 2] +Interface 398 child 1 config: [261, 0] +Interface 398 child 14 config: [261, 0] +Interface 398 child 20 config: [262, 0] +Interface 400 child 2 config: [261, 0] +Interface 400 child 3 config: [262, 0] +Interface 400 child 4 config: [262, 0] +Interface 400 child 5 config: [261, 0] +Interface 400 child 6 config: [262, 0] +Interface 400 child 7 config: [262, 0] +Interface 400 child 8 config: [262, 0] +Interface 400 child 9 config: [262, 0] +Interface 400 child 10 config: [262, 0] +Interface 400 child 12 config: [261, 0] +Interface 400 child 13 config: [261, 0] +Interface 400 child 14 config: [261, 0] +Interface 400 child 16 config: [261, 0] +Interface 402 child 139 config: [261, 0] +Interface 402 child 138 config: [261, 0] +Interface 402 child 141 config: [261, 0] +Interface 402 child 140 config: [261, 0] +Interface 402 child 143 config: [261, 0] +Interface 402 child 142 config: [261, 0] +Interface 402 child 152 config: [261, 0] +Interface 402 child 153 config: [261, 0] +Interface 402 child 154 config: [261, 0] +Interface 402 child 155 config: [261, 0] +Interface 402 child 156 config: [261, 0] +Interface 402 child 157 config: [261, 0] +Interface 402 child 159 config: [261, 0] +Interface 402 child 144 config: [261, 0] +Interface 402 child 145 config: [261, 0] +Interface 402 child 146 config: [261, 0] +Interface 402 child 147 config: [261, 0] +Interface 402 child 148 config: [261, 0] +Interface 402 child 149 config: [261, 0] +Interface 402 child 150 config: [261, 0] +Interface 402 child 151 config: [261, 0] +Interface 408 child 7 config: [719, 28] +Interface 408 child 8 config: [719, 29] +Interface 408 child 9 config: [719, 30] +Interface 408 child 10 config: [719, 31] +Interface 409 child 1 config: [1, 0] +Interface 409 child 2 config: [1, 1] +Interface 409 child 3 config: [1, 2] +Interface 411 child 9 config: [788, 0] +Interface 411 child 10 config: [788, 0] +Interface 411 child 11 config: [788, 0] +Interface 411 child 12 config: [788, 0] +Interface 422 child 0 config: [425, 1] +Interface 428 child 1 config: [822, 9], [822, 0] +Interface 428 child 2 config: [821, 22] +Interface 428 child 3 config: [821, 22] +Interface 428 child 4 config: [821, 22] +Interface 428 child 5 config: [821, 22] +Interface 428 child 6 config: [821, 22] +Interface 428 child 7 config: [821, 22] +Interface 428 child 8 config: [821, 22] +Interface 428 child 9 config: [821, 22] +Interface 428 child 10 config: [821, 22] +Interface 428 child 11 config: [821, 22] +Interface 428 child 12 config: [821, 22] +Interface 428 child 13 config: [821, 22] +Interface 428 child 14 config: [821, 22] +Interface 428 child 15 config: [821, 22] +Interface 428 child 17 config: [821, 22] +Interface 428 child 16 config: [821, 22] +Interface 428 child 19 config: [821, 22] +Interface 428 child 18 config: [821, 22] +Interface 428 child 21 config: [821, 22] +Interface 428 child 20 config: [821, 22] +Interface 428 child 23 config: [821, 22] +Interface 428 child 22 config: [821, 22] +Interface 428 child 25 config: [821, 22] +Interface 428 child 24 config: [821, 22] +Interface 428 child 27 config: [821, 22] +Interface 428 child 26 config: [821, 22] +Interface 428 child 29 config: [821, 22] +Interface 428 child 31 config: [821, 22] +Interface 428 child 30 config: [821, 22] +Interface 428 child 34 config: [821, 22] +Interface 428 child 35 config: [821, 22] +Interface 428 child 32 config: [821, 22] +Interface 428 child 33 config: [821, 22] +Interface 428 child 38 config: [821, 22] +Interface 428 child 39 config: [821, 22] +Interface 428 child 36 config: [821, 22] +Interface 428 child 37 config: [821, 22] +Interface 428 child 42 config: [821, 22] +Interface 428 child 43 config: [821, 22] +Interface 428 child 40 config: [821, 22] +Interface 428 child 41 config: [821, 22] +Interface 428 child 46 config: [821, 22] +Interface 428 child 47 config: [821, 22] +Interface 428 child 44 config: [821, 22] +Interface 428 child 45 config: [821, 22] +Interface 428 child 51 config: [821, 22] +Interface 428 child 50 config: [821, 22] +Interface 428 child 49 config: [821, 22] +Interface 428 child 48 config: [821, 22] +Interface 428 child 54 config: [821, 22] +Interface 428 child 53 config: [821, 22] +Interface 428 child 52 config: [821, 22] +Interface 433 child 21 config: [834, 8] +Interface 433 child 20 config: [834, 0] +Interface 433 child 23 config: [835, 8] +Interface 433 child 22 config: [835, 0] +Interface 445 child 3 config: [846, 0] +Interface 445 child 4 config: [846, 0] +Interface 445 child 5 config: [846, 0] +Interface 445 child 6 config: [846, 0] +Interface 445 child 7 config: [846, 0] +Interface 445 child 8 config: [846, 0] +Interface 445 child 9 config: [846, 0] +Interface 445 child 10 config: [846, 0] +Interface 445 child 11 config: [846, 0] +Interface 445 child 12 config: [846, 0] +Interface 445 child 13 config: [846, 4] +Interface 445 child 14 config: [846, 4] +Interface 445 child 15 config: [846, 4] +Interface 445 child 17 config: [846, 4] +Interface 445 child 16 config: [846, 4] +Interface 445 child 19 config: [846, 4] +Interface 445 child 18 config: [846, 4] +Interface 445 child 21 config: [846, 4] +Interface 445 child 20 config: [846, 4] +Interface 445 child 23 config: [847, 10] +Interface 445 child 22 config: [846, 4] +Interface 445 child 25 config: [847, 12] +Interface 445 child 24 config: [847, 8] +Interface 445 child 27 config: [847, 8] +Interface 445 child 26 config: [847, 12] +Interface 445 child 28 config: [847, 10] +Interface 447 child 2 config: [846, 12] +Interface 447 child 3 config: [846, 12] +Interface 447 child 4 config: [846, 12] +Interface 447 child 5 config: [846, 12] +Interface 447 child 6 config: [846, 12] +Interface 447 child 7 config: [846, 12] +Interface 447 child 8 config: [846, 12] +Interface 447 child 9 config: [846, 12] +Interface 447 child 10 config: [846, 12] +Interface 447 child 11 config: [846, 12] +Interface 447 child 12 config: [846, 8] +Interface 447 child 13 config: [846, 8] +Interface 447 child 14 config: [846, 8] +Interface 447 child 15 config: [846, 8] +Interface 447 child 17 config: [846, 8] +Interface 447 child 16 config: [846, 8] +Interface 447 child 19 config: [846, 8] +Interface 447 child 18 config: [846, 8] +Interface 447 child 21 config: [846, 8] +Interface 447 child 20 config: [846, 8] +Interface 447 child 23 config: [846, 20] +Interface 447 child 22 config: [846, 20] +Interface 447 child 25 config: [846, 20] +Interface 447 child 24 config: [846, 20] +Interface 447 child 27 config: [846, 20] +Interface 447 child 26 config: [846, 20] +Interface 447 child 29 config: [846, 20] +Interface 447 child 28 config: [846, 20] +Interface 447 child 31 config: [846, 20] +Interface 447 child 30 config: [846, 20] +Interface 447 child 34 config: [846, 16] +Interface 447 child 35 config: [846, 16] +Interface 447 child 32 config: [846, 16] +Interface 447 child 33 config: [846, 16] +Interface 447 child 38 config: [846, 16] +Interface 447 child 39 config: [846, 16] +Interface 447 child 36 config: [846, 16] +Interface 447 child 37 config: [846, 16] +Interface 447 child 42 config: [846, 28] +Interface 447 child 43 config: [846, 28] +Interface 447 child 40 config: [846, 16] +Interface 447 child 41 config: [846, 16] +Interface 447 child 46 config: [846, 28] +Interface 447 child 47 config: [846, 28] +Interface 447 child 44 config: [846, 28] +Interface 447 child 45 config: [846, 28] +Interface 447 child 51 config: [846, 28] +Interface 447 child 50 config: [846, 28] +Interface 447 child 49 config: [846, 28] +Interface 447 child 48 config: [846, 28] +Interface 447 child 55 config: [846, 24] +Interface 447 child 54 config: [846, 24] +Interface 447 child 53 config: [846, 24] +Interface 447 child 52 config: [846, 24] +Interface 447 child 59 config: [846, 24] +Interface 447 child 58 config: [846, 24] +Interface 447 child 57 config: [846, 24] +Interface 447 child 56 config: [846, 24] +Interface 447 child 63 config: [847, 14] +Interface 447 child 62 config: [847, 16] +Interface 447 child 61 config: [846, 24] +Interface 447 child 60 config: [846, 24] +Interface 447 child 68 config: [847, 22] +Interface 447 child 69 config: [847, 20] +Interface 447 child 70 config: [847, 24] +Interface 447 child 71 config: [847, 24] +Interface 447 child 64 config: [847, 18] +Interface 447 child 65 config: [847, 18] +Interface 447 child 66 config: [847, 14] +Interface 447 child 67 config: [847, 16] +Interface 447 child 76 config: [847, 30] +Interface 447 child 77 config: [847, 30] +Interface 447 child 78 config: [847, 26] +Interface 447 child 79 config: [847, 28] +Interface 447 child 72 config: [847, 20] +Interface 447 child 73 config: [847, 22] +Interface 447 child 74 config: [847, 28] +Interface 447 child 75 config: [847, 26] +Interface 462 child 23 config: [262, 0] +Interface 462 child 22 config: [261, 0] +Interface 462 child 25 config: [264, 0] +Interface 462 child 24 config: [263, 0] +Interface 462 child 27 config: [266, 0] +Interface 462 child 26 config: [265, 0] +Interface 471 child 7 config: [913, 0] +Interface 471 child 8 config: [913, 4] +Interface 473 child 2 config: [43, 0] +Interface 473 child 3 config: [43, 0] +Interface 473 child 4 config: [43, 0] +Interface 473 child 12 config: [300, 0] +Interface 473 child 13 config: [300, 0] +Interface 473 child 14 config: [300, 0] +Interface 473 child 15 config: [300, 0] +Interface 473 child 17 config: [300, 0] +Interface 473 child 16 config: [300, 0] +Interface 473 child 19 config: [300, 0] +Interface 473 child 18 config: [300, 0] +Interface 473 child 21 config: [300, 0] +Interface 473 child 20 config: [300, 0] +Interface 473 child 22 config: [301, 0] +Interface 473 child 25 config: [172, 0] +Interface 473 child 24 config: [172, 0] +Interface 474 child 2 config: [43, 0] +Interface 474 child 3 config: [43, 0] +Interface 474 child 4 config: [43, 0] +Interface 474 child 12 config: [300, 0] +Interface 474 child 13 config: [300, 0] +Interface 474 child 14 config: [300, 0] +Interface 474 child 15 config: [300, 0] +Interface 474 child 17 config: [300, 0] +Interface 474 child 16 config: [300, 0] +Interface 474 child 19 config: [300, 0] +Interface 474 child 18 config: [300, 0] +Interface 474 child 21 config: [300, 0] +Interface 474 child 20 config: [300, 0] +Interface 474 child 22 config: [301, 0] +Interface 474 child 24 config: [172, 0] +Interface 474 child 28 config: [172, 0] +Interface 475 child 2 config: [43, 0] +Interface 475 child 3 config: [43, 0] +Interface 475 child 4 config: [43, 0] +Interface 475 child 12 config: [300, 0] +Interface 475 child 13 config: [300, 0] +Interface 475 child 14 config: [300, 0] +Interface 475 child 15 config: [300, 0] +Interface 475 child 17 config: [300, 0] +Interface 475 child 16 config: [300, 0] +Interface 475 child 19 config: [300, 0] +Interface 475 child 18 config: [300, 0] +Interface 475 child 21 config: [300, 0] +Interface 475 child 20 config: [300, 0] +Interface 475 child 22 config: [301, 0] +Interface 475 child 24 config: [172, 0] +Interface 475 child 28 config: [172, 0] +Interface 476 child 2 config: [43, 0] +Interface 476 child 3 config: [43, 0] +Interface 476 child 4 config: [43, 0] +Interface 476 child 12 config: [300, 0] +Interface 476 child 13 config: [300, 0] +Interface 476 child 14 config: [300, 0] +Interface 476 child 15 config: [300, 0] +Interface 476 child 17 config: [300, 0] +Interface 476 child 16 config: [300, 0] +Interface 476 child 19 config: [300, 0] +Interface 476 child 18 config: [300, 0] +Interface 476 child 21 config: [300, 0] +Interface 476 child 20 config: [300, 0] +Interface 476 child 22 config: [301, 0] +Interface 476 child 24 config: [172, 0] +Interface 476 child 28 config: [172, 0] +Interface 491 child 85 config: [261, 0] +Interface 491 child 83 config: [261, 0] +Interface 491 child 92 config: [261, 0] +Interface 491 child 94 config: [261, 0] +Interface 491 child 101 config: [261, 0] +Interface 491 child 99 config: [261, 0] +Interface 491 child 108 config: [261, 0] +Interface 491 child 106 config: [261, 0] +Interface 491 child 115 config: [261, 0] +Interface 491 child 113 config: [261, 0] +Interface 491 child 127 config: [261, 0] +Interface 491 child 122 config: [261, 0] +Interface 491 child 120 config: [261, 0] +Interface 491 child 136 config: [261, 0] +Interface 491 child 141 config: [261, 0] +Interface 491 child 143 config: [261, 0] +Interface 491 child 129 config: [261, 0] +Interface 491 child 134 config: [261, 0] +Interface 491 child 155 config: [261, 0] +Interface 491 child 157 config: [261, 0] +Interface 491 child 148 config: [261, 0] +Interface 491 child 150 config: [261, 0] +Interface 491 child 171 config: [261, 0] +Interface 491 child 169 config: [261, 0] +Interface 491 child 162 config: [261, 0] +Interface 491 child 164 config: [261, 0] +Interface 491 child 185 config: [261, 0] +Interface 491 child 190 config: [261, 0] +Interface 491 child 178 config: [261, 0] +Interface 491 child 176 config: [261, 0] +Interface 491 child 183 config: [261, 0] +Interface 491 child 192 config: [261, 0] +Interface 491 child 223 config: [261, 0] +Interface 491 child 229 config: [261, 0] +Interface 491 child 228 config: [261, 0] +Interface 491 child 227 config: [261, 0] +Interface 491 child 226 config: [261, 0] +Interface 491 child 225 config: [261, 0] +Interface 491 child 224 config: [261, 0] +Interface 518 child 84 config: [984, 8] +Interface 518 child 87 config: [984, 12] +Interface 518 child 80 config: [986, 28] +Interface 518 child 83 config: [984, 4] +Interface 518 child 82 config: [984, 0] +Interface 518 child 93 config: [985, 4] +Interface 518 child 92 config: [985, 0] +Interface 518 child 95 config: [985, 12] +Interface 518 child 94 config: [985, 8] +Interface 518 child 89 config: [984, 20] +Interface 518 child 88 config: [984, 16] +Interface 518 child 91 config: [984, 28] +Interface 518 child 90 config: [984, 24] +Interface 518 child 102 config: [986, 8] +Interface 518 child 100 config: [986, 0] +Interface 518 child 101 config: [986, 4] +Interface 518 child 98 config: [985, 24] +Interface 518 child 99 config: [985, 28] +Interface 518 child 96 config: [985, 16] +Interface 518 child 97 config: [985, 20] +Interface 540 child 117 config: [1018, 18] +Interface 540 child 114 config: [1018, 18] +Interface 540 child 123 config: [1018, 18] +Interface 540 child 120 config: [1018, 18] +Interface 559 child 55 config: [1037, 1] +Interface 559 child 59 config: [1037, 5] +Interface 559 child 58 config: [1037, 4] +Interface 559 child 57 config: [1037, 3] +Interface 559 child 56 config: [1037, 2] +Interface 559 child 63 config: [1037, 9] +Interface 559 child 62 config: [1037, 8] +Interface 559 child 61 config: [1037, 7] +Interface 559 child 60 config: [1037, 6] +Interface 559 child 68 config: [1037, 14] +Interface 559 child 69 config: [1037, 0] +Interface 559 child 64 config: [1037, 10] +Interface 559 child 65 config: [1037, 11] +Interface 559 child 66 config: [1037, 12] +Interface 559 child 67 config: [1037, 13] diff --git a/dumps/498/498_interface_containers.txt b/dumps/498/498_interface_containers.txt new file mode 100644 index 0000000..f29e472 --- /dev/null +++ b/dumps/498/498_interface_containers.txt @@ -0,0 +1,80 @@ +Interface 2 has container childs: [48] +Interface 11 has container childs: [61] +Interface 12 has container childs: [89] +Interface 15 has container childs: [0] (no components) +Interface 32 has container childs: [113] +Interface 35 has container childs: [92] +Interface 36 has container childs: [110] +Interface 39 has container childs: [90] +Interface 40 has container childs: [127] +Interface 43 has container childs: [105] +Interface 44 has container childs: [161] +Interface 47 has container childs: [138] +Interface 56 has container childs: [0] (no components) +Interface 57 has container childs: [0] (no components) +Interface 60 has container childs: [89, 90] +Interface 94 has container childs: [0] +Interface 96 has container childs: [0] (no components) +Interface 97 has container childs: [0] (no components) +Interface 98 has container childs: [0] (no components) +Interface 100 has container childs: [0] (no components) +Interface 115 has container childs: [0] (no components) +Interface 117 has container childs: [0] (no components) +Interface 118 has container childs: [0] (no components) +Interface 125 has container childs: [68, 69] +Interface 126 has container childs: [0, 1] +Interface 145 has container childs: [10] +Interface 146 has container childs: [0] (no components) +Interface 149 has container childs: [0] (no components) +Interface 155 has container childs: [0] (no components) +Interface 179 has container childs: [0] (no components) +Interface 180 has container childs: [0] (no components) +Interface 215 has container childs: [0] (no components) +Interface 226 has container childs: [0] (no components) +Interface 257 has container childs: [0] (no components) +Interface 278 has container childs: [89] +Interface 284 has container childs: [0] (no components) +Interface 287 has container childs: [2] +Interface 288 has container childs: [131] +Interface 289 has container childs: [62] +Interface 290 has container childs: [8] +Interface 296 has container childs: [0] (no components) +Interface 311 has container childs: [3] +Interface 317 has container childs: [0] (no components) +Interface 323 has container childs: [2] +Interface 333 has container childs: [0] (no components) +Interface 336 has container childs: [0] (no components) +Interface 363 has container childs: [1, 7] +Interface 364 has container childs: [1] +Interface 367 has container childs: [75] +Interface 385 has container childs: [0] (no components) +Interface 386 has container childs: [0] (no components) +Interface 387 has container childs: [28] +Interface 392 has container childs: [3] +Interface 394 has container childs: [106] +Interface 396 has container childs: [132] +Interface 404 has container childs: [0] (no components) +Interface 413 has container childs: [0] (no components) +Interface 442 has container childs: [2, 4] +Interface 449 has container childs: [0] (no components) +Interface 467 has container childs: [164] +Interface 477 has container childs: [75] +Interface 478 has container childs: [61] +Interface 483 has container childs: [0] (no components) +Interface 504 has container childs: [0] (no components) +Interface 512 has container childs: [0] (no components) +Interface 513 has container childs: [0] (no components) +Interface 516 has container childs: [0] (no components) +Interface 517 has container childs: [0] (no components) +Interface 518 has container childs: [78] +Interface 539 has container childs: [0] (no components) +Interface 545 has container childs: [0] (no components) +Interface 602 has container childs: [0] (no components) +Interface 610 has container childs: [0] (no components) +Interface 621 has container childs: [0] (no components) +Interface 628 has container childs: [0] (no components) +Interface 644 has container childs: [0] (no components) +Interface 648 has container childs: [0] (no components) +Interface 665 has container childs: [0] (no components) +Interface 670 has container childs: [0] (no components) +Interface 713 has container childs: [0] (no components) diff --git a/dumps/498/498_interface_dump.txt b/dumps/498/498_interface_dump.txt new file mode 100644 index 0000000..bce0ff3 --- /dev/null +++ b/dumps/498/498_interface_dump.txt @@ -0,0 +1,4769 @@ +RSInterface 4 - [22: Water Collected] +RSInterface 4 - [23: Time Left] +RSInterface 4 - [25: %1] +RSInterface 6 - [90: Brimhaven Agility Arena Ticket Exchange] +RSInterface 6 - [91: Toadflax] +RSInterface 6 - [92: Pirate's hook] +RSInterface 6 - [94: Experience (1)] +RSInterface 6 - [100: Snapdragon] +RSInterface 6 - [101: Experience (10)] +RSInterface 6 - [102: Experience (25)] +RSInterface 6 - [103: Experience (100)] +RSInterface 6 - [104: Experience (1000)] +RSInterface 8 - [3: 8-East] +RSInterface 8 - [4: 6-South] +RSInterface 8 - [5: 2-North] +RSInterface 8 - [6: 4-East] +RSInterface 8 - [7: 22-South] +RSInterface 8 - [8: X marks the start!] +RSInterface 8 - [9: Dragontooth Island] +RSInterface 9 - [2: Rune-Draw] +RSInterface 9 - [3: Your Score] +RSInterface 9 - [4: Opponent's Score] +RSInterface 9 - [5: Draw] +RSInterface 9 - [6: Hold] +RSInterface 9 - [27: DEATH] +RSInterface 9 - [28: Text] +RSInterface 9 - [29: DEATH] +RSInterface 9 - [30: Text] +RSInterface 10 - [1: Windspeed:] +RSInterface 11 - [60: The Bank of RuneScape - Deposit Box] +RSInterface 12 - [90: The Bank of RuneScape] +RSInterface 12 - [94: Withdraw as:] +RSInterface 12 - [95: Item] +RSInterface 12 - [96: Rearrange mode:] +RSInterface 12 - [97: Note] +RSInterface 12 - [100: Insert] +RSInterface 12 - [101: Swap] +RSInterface 13 - [11: 0] +RSInterface 13 - [12: 0] +RSInterface 13 - [13: 0] +RSInterface 13 - [14: 0] +RSInterface 13 - [15: 0] +RSInterface 13 - [16: 0] +RSInterface 13 - [17: 0] +RSInterface 13 - [18: 0] +RSInterface 13 - [19: 0] +RSInterface 13 - [20: 0] +RSInterface 13 - [28: Please enter your FOUR DIGIT PIN using the buttons below.] +RSInterface 13 - [30: Exit] +RSInterface 13 - [31: YOUR PIN WILL BE DELETED IN X DAYS] +RSInterface 14 - [40: Bank PIN Settings] +RSInterface 14 - [41: Messages] +RSInterface 14 - [60: Set a PIN] +RSInterface 14 - [61: Change your recovery delay] +RSInterface 14 - [62: Change your PIN] +RSInterface 14 - [63: Delete your PIN] +RSInterface 14 - [64: Change your recovery delay] +RSInterface 14 - [65: Cancel the PIN that's pending] +RSInterface 14 - [68: Your Bank PIN status:] +RSInterface 14 - [69: Unknown] +RSInterface 14 - [70: Recovery delay:] +RSInterface 14 - [71: X days] +RSInterface 14 - [73: Do you really wish to do that?] +RSInterface 14 - [86: Use the buttons below to change your PIN settings] +RSInterface 14 - [89: Yes, I really want to do that.] +RSInterface 17 - [2: Message of the week] +RSInterface 18 - [2: Message of the week] +RSInterface 19 - [2: Message of the week] +RSInterface 20 - [2: Message of the week] +RSInterface 21 - [2: Message of the week] +RSInterface 22 - [2: Message of the week] +RSInterface 23 - [2: Message of the week] +RSInterface 24 - [0: Kill Count: %1] +RSInterface 25 - [5: Which is the next shape in the above sequence?] +RSInterface 25 - [9: 1.] +RSInterface 25 - [10: 2.] +RSInterface 25 - [11: 3.] +RSInterface 25 - [12: 4.] +RSInterface 26 - [3: title] +RSInterface 26 - [68: page%1] +RSInterface 26 - [69: page%2] +RSInterface 26 - [73: line2] +RSInterface 26 - [74: line3] +RSInterface 26 - [75: line4] +RSInterface 26 - [76: line5] +RSInterface 26 - [77: line6] +RSInterface 26 - [78: line7] +RSInterface 26 - [79: line8] +RSInterface 26 - [80: line9] +RSInterface 26 - [81: line10] +RSInterface 26 - [82: line11] +RSInterface 26 - [83: line12] +RSInterface 26 - [84: line13] +RSInterface 26 - [85: line14] +RSInterface 26 - [86: line15] +RSInterface 26 - [87: line16] +RSInterface 26 - [88: line17] +RSInterface 26 - [89: line18] +RSInterface 26 - [90: line19] +RSInterface 26 - [91: line20] +RSInterface 26 - [92: line21] +RSInterface 26 - [93: line22] +RSInterface 26 - [94: line23] +RSInterface 26 - [95: line24] +RSInterface 26 - [96: line25] +RSInterface 26 - [97: line26] +RSInterface 26 - [98: line27] +RSInterface 26 - [99: line28] +RSInterface 26 - [100: line28] +RSInterface 26 - [101: line29] +RSInterface 27 - [6: page%1] +RSInterface 27 - [7: page%2] +RSInterface 27 - [39: line1] +RSInterface 27 - [40: line2] +RSInterface 27 - [41: line3] +RSInterface 27 - [42: line4] +RSInterface 27 - [43: line5] +RSInterface 27 - [44: line6] +RSInterface 27 - [45: line7] +RSInterface 27 - [46: line8] +RSInterface 27 - [47: line9] +RSInterface 27 - [48: line10] +RSInterface 27 - [49: line11] +RSInterface 27 - [50: line12] +RSInterface 27 - [51: line13] +RSInterface 27 - [52: line14] +RSInterface 27 - [53: line15] +RSInterface 27 - [54: line16] +RSInterface 27 - [55: line17] +RSInterface 27 - [56: line18] +RSInterface 27 - [57: line19] +RSInterface 27 - [58: line20] +RSInterface 27 - [59: line21] +RSInterface 27 - [60: line22] +RSInterface 27 - [61: line23] +RSInterface 27 - [62: line24] +RSInterface 27 - [63: line25] +RSInterface 27 - [64: line26] +RSInterface 27 - [65: line27] +RSInterface 27 - [66: line28] +RSInterface 27 - [67: line28] +RSInterface 27 - [68: line29] +RSInterface 27 - [160: Index] +RSInterface 28 - [75: Iron: %1] +RSInterface 28 - [76: Blast Furnace Bar Stock] +RSInterface 28 - [77: Bronze: %1] +RSInterface 28 - [100: Steel: %1] +RSInterface 28 - [101: Mithril: %1] +RSInterface 28 - [102: Adamantite: %1] +RSInterface 28 - [103: Runite: %1] +RSInterface 28 - [104: Silver: %1] +RSInterface 28 - [105: Gold: %1] +RSInterface 28 - [106: Perfect gold: %1] +RSInterface 28 - [107: Coal to add: %2] +RSInterface 28 - [108: (All)] +RSInterface 28 - [109: (All)] +RSInterface 28 - [110: (All)] +RSInterface 28 - [111: (All)] +RSInterface 28 - [112: (All)] +RSInterface 28 - [113: (All)] +RSInterface 28 - [114: (All)] +RSInterface 28 - [115: (All)] +RSInterface 28 - [116: (All)] +RSInterface 29 - [2: Blast Furnace Plan] +RSInterface 29 - [3: Stove] +RSInterface 29 - [4: Air Pump] +RSInterface 29 - [5: Temp Gauge] +RSInterface 29 - [6: Furnace] +RSInterface 29 - [7: Dispenser] +RSInterface 29 - [8: Conveyor
Belt] +RSInterface 29 - [9: Cogs] +RSInterface 29 - [10: Pipes] +RSInterface 29 - [11: Coke] +RSInterface 30 - [0: Blast Furnace Temp Gauge] +RSInterface 31 - [66: Challenge: Select Game] +RSInterface 31 - [68: Select] +RSInterface 31 - [78: Draughts] +RSInterface 31 - [79: Runelink] +RSInterface 31 - [80: 100 vs 100] +RSInterface 31 - [81: 100 vs 100] +RSInterface 31 - [82: Game:] +RSInterface 31 - [83: Ranks (mine vs opponents):] +RSInterface 31 - [85: Runesquares] +RSInterface 31 - [86: 100 vs 100] +RSInterface 31 - [88: Runeversi] +RSInterface 31 - [89: 100 vs 100] +RSInterface 32 - [67: Insert a very long name here!] +RSInterface 32 - [75: vs] +RSInterface 32 - [76: Insert a very long name here!] +RSInterface 32 - [88: Turn:] +RSInterface 32 - [91: Draughts] +RSInterface 32 - [93: Resign] +RSInterface 32 - [95: Offer draw] +RSInterface 32 - [98: A very long name] +RSInterface 32 - [111: Blah blah blah blah blah blah blah!] +RSInterface 32 - [118: Blah blah blah blah blah blah blah!] +RSInterface 32 - [119: Blah blah blah blah blah!] +RSInterface 33 - [66: Draughts: Options] +RSInterface 33 - [68: Challenge] +RSInterface 33 - [75: 30 seconds] +RSInterface 33 - [81: 1 minute] +RSInterface 33 - [82: 2 minutes] +RSInterface 33 - [83: 15 seconds] +RSInterface 33 - [84: Time per move:] +RSInterface 33 - [88: Choose piece:] +RSInterface 33 - [111: Ranked] +RSInterface 34 - [1: Draughts] +RSInterface 35 - [67: Insert a very long name here!] +RSInterface 35 - [75: vs] +RSInterface 35 - [76: Insert a very long name here!] +RSInterface 35 - [88: Draughts] +RSInterface 35 - [96: Blah blah blah blah blah!] +RSInterface 35 - [98: Close] +RSInterface 35 - [107: Blah blah blah blah blah blah blah!] +RSInterface 36 - [66: Insert a very long name here!] +RSInterface 36 - [73: vs] +RSInterface 36 - [74: Insert a very long name here!] +RSInterface 36 - [86: Turn:] +RSInterface 36 - [90: Runelink] +RSInterface 36 - [92: Resign] +RSInterface 36 - [94: Offer draw] +RSInterface 36 - [97: A very long name] +RSInterface 36 - [111: Blah blah blah blah blah blah blah!] +RSInterface 36 - [115: Blah blah blah blah blah blah blah!] +RSInterface 36 - [123: Blah blah blah blah blah!] +RSInterface 36 - [126: Close] +RSInterface 37 - [66: Runelink: Options] +RSInterface 37 - [68: Challenge] +RSInterface 37 - [75: 30 seconds] +RSInterface 37 - [81: 1 minute] +RSInterface 37 - [82: 2 minutes] +RSInterface 37 - [83: 15 seconds] +RSInterface 37 - [84: Time per move:] +RSInterface 37 - [88: Choose piece:] +RSInterface 37 - [111: Ranked] +RSInterface 38 - [1: Runelink] +RSInterface 39 - [67: Insert a very long name here!] +RSInterface 39 - [75: vs] +RSInterface 39 - [76: Insert a very long name here!] +RSInterface 39 - [88: Runelink] +RSInterface 39 - [95: Blah blah blah blah blah!] +RSInterface 39 - [97: Close] +RSInterface 39 - [106: Blah blah blah blah blah blah blah!] +RSInterface 40 - [67: Insert a very long name here!] +RSInterface 40 - [75: vs] +RSInterface 40 - [76: Insert a very long name here!] +RSInterface 40 - [88: Turn:] +RSInterface 40 - [92: Runesquares] +RSInterface 40 - [94: Resign] +RSInterface 40 - [96: Offer draw] +RSInterface 40 - [99: A very long name] +RSInterface 40 - [110: Blah blah blah blah blah blah blah!] +RSInterface 40 - [114: Blah blah blah blah blah blah blah!] +RSInterface 40 - [115: Blah blah blah blah blah!] +RSInterface 40 - [118: Close] +RSInterface 41 - [66: Runesquares: Options] +RSInterface 41 - [68: Challenge] +RSInterface 41 - [75: 30 seconds] +RSInterface 41 - [81: 1 minute] +RSInterface 41 - [82: 2 minutes] +RSInterface 41 - [83: 15 seconds] +RSInterface 41 - [84: Time per move:] +RSInterface 41 - [88: Choose piece:] +RSInterface 41 - [111: Ranked] +RSInterface 42 - [1: Runesquares] +RSInterface 43 - [67: Insert a very long name here!] +RSInterface 43 - [75: vs] +RSInterface 43 - [76: Insert a very long name here!] +RSInterface 43 - [88: Blah blah blah blah blah blah blah!] +RSInterface 43 - [92: Blah blah blah blah blah blah blah!] +RSInterface 43 - [93: Blah blah blah blah blah!] +RSInterface 43 - [96: Close] +RSInterface 44 - [67: Insert a very long name here!] +RSInterface 44 - [75: vs] +RSInterface 44 - [76: Insert a very long name here!] +RSInterface 44 - [88: Turn:] +RSInterface 44 - [92: Runeversi] +RSInterface 44 - [94: Resign] +RSInterface 44 - [96: Offer draw] +RSInterface 44 - [100: A very long name] +RSInterface 44 - [142: Blah blah blah blah blah blah blah!] +RSInterface 44 - [148: Blah blah blah blah blah blah blah!] +RSInterface 44 - [149: Blah blah blah blah blah!] +RSInterface 44 - [152: Close] +RSInterface 45 - [66: Runeversi: Options] +RSInterface 45 - [68: Challenge] +RSInterface 45 - [75: 30 seconds] +RSInterface 45 - [81: 1 minute] +RSInterface 45 - [82: 2 minutes] +RSInterface 45 - [83: 15 seconds] +RSInterface 45 - [84: Time per move:] +RSInterface 45 - [88: Choose piece:] +RSInterface 45 - [111: Ranked] +RSInterface 46 - [1: Runeversi] +RSInterface 47 - [67: Insert a very long name here!] +RSInterface 47 - [75: vs] +RSInterface 47 - [76: Insert a very long name here!] +RSInterface 47 - [88: Runeversi] +RSInterface 47 - [89: Blah blah blah blah blah blah blah!] +RSInterface 47 - [93: Blah blah blah blah blah blah blah!] +RSInterface 47 - [94: Blah blah blah blah blah!] +RSInterface 47 - [129: Close] +RSInterface 49 - [38: book title] +RSInterface 49 - [87: line1] +RSInterface 49 - [88: line2] +RSInterface 49 - [89: line3] +RSInterface 49 - [90: line4] +RSInterface 49 - [91: line5] +RSInterface 49 - [92: line6] +RSInterface 49 - [93: line7] +RSInterface 49 - [94: line8] +RSInterface 49 - [95: line9] +RSInterface 49 - [96: line10] +RSInterface 49 - [97: line11] +RSInterface 49 - [98: line12] +RSInterface 49 - [99: line13] +RSInterface 49 - [100: line14] +RSInterface 49 - [101: line15] +RSInterface 49 - [102: line16] +RSInterface 49 - [103: line17] +RSInterface 49 - [104: line18] +RSInterface 49 - [105: line19] +RSInterface 49 - [106: line20] +RSInterface 49 - [107: line21] +RSInterface 49 - [108: line22] +RSInterface 49 - [109: Page%1] +RSInterface 49 - [110: Page%2] +RSInterface 50 - [76: Brooch] +RSInterface 51 - [11: Canifis] +RSInterface 51 - [12: Mort Myre
Swamp] +RSInterface 51 - [13: Hollows] +RSInterface 51 - [14: Mort'ton] +RSInterface 51 - [15: Graveyard] +RSInterface 51 - [16: Temple] +RSInterface 51 - [20: Route 1] +RSInterface 51 - [21: Route 1] +RSInterface 51 - [23: Route 2] +RSInterface 51 - [24: Route 2] +RSInterface 51 - [26: Route 1:

Take the route through
Canifis.

Shorter but potentially
more dangerous.] +RSInterface 51 - [27: Route 2:

Take the route through
Mort Myre Swamp.

Longer but less likely
to be attacked.] +RSInterface 51 - [31: Burgh de
Rott] +RSInterface 51 - [32: Choose your path] +RSInterface 52 - [16: A Stable Dugout.] +RSInterface 52 - [17: A Waka.] +RSInterface 52 - [18: A Dugout.] +RSInterface 52 - [19: A Log.] +RSInterface 52 - [20: WHAT SORT OF CANOE WOULD YOU LIKE TO MAKE ?] +RSInterface 53 - [25: Lumbridge] +RSInterface 53 - [26: Champions
Guild] +RSInterface 53 - [27: Barbarian
Village] +RSInterface 53 - [28: Edgeville] +RSInterface 53 - [29: Wilderness Pond -
No canoe trees here.] +RSInterface 53 - [37: You are here] +RSInterface 53 - [42: Wilderness Pond -
No canoe trees here.] +RSInterface 53 - [46: You are here] +RSInterface 53 - [49: You are here] +RSInterface 53 - [52: You are here] +RSInterface 53 - [55: Please Select
Your Destination] +RSInterface 54 - [88: Catapult Controls] +RSInterface 54 - [157: Fire Catapult] +RSInterface 55 - [0: Total Wins This Season!] +RSInterface 55 - [1: Saradomin: 0] +RSInterface 55 - [2: Zamorak: 0] +RSInterface 58 - [0: Zamorak = %1] +RSInterface 58 - [1: %1 = Saradomin] +RSInterface 58 - [7: Health %1%] +RSInterface 58 - [8: %1 Min] +RSInterface 58 - [11: Locked] +RSInterface 58 - [13: Collapsed] +RSInterface 58 - [15: Collapsed] +RSInterface 58 - [17: Operational] +RSInterface 59 - [0: Zamorak = %1] +RSInterface 59 - [1: %1 = Saradomin] +RSInterface 59 - [7: Health %1%] +RSInterface 59 - [8: %1 Min] +RSInterface 59 - [11: Locked] +RSInterface 59 - [13: Collapsed] +RSInterface 59 - [15: Collapsed] +RSInterface 59 - [17: Operational] +RSInterface 60 - [88: Castle Wars Ticket Exchange] +RSInterface 61 - [10: A] +RSInterface 61 - [11: A] +RSInterface 61 - [12: A] +RSInterface 61 - [13: A] +RSInterface 61 - [14: A] +RSInterface 61 - [15: A] +RSInterface 61 - [30: Name Your Cat] +RSInterface 61 - [32: E N T E R] +RSInterface 63 - [1: Congratulations!] +RSInterface 63 - [2: Well done, you defeated the Champion!] +RSInterface 63 - [5: You are awarded:] +RSInterface 63 - [6: %1 Slayer Xp] +RSInterface 63 - [7: %1 Hitpoint Xp] +RSInterface 64 - [1: Name] +RSInterface 64 - [2: Line1] +RSInterface 65 - [1: Name] +RSInterface 65 - [2: Line1] +RSInterface 65 - [3: Line2] +RSInterface 66 - [1: Name] +RSInterface 66 - [2: Line1] +RSInterface 66 - [3: Line2] +RSInterface 66 - [4: Line3] +RSInterface 67 - [1: Name] +RSInterface 67 - [2: Line1] +RSInterface 67 - [3: Line2] +RSInterface 67 - [4: Line3] +RSInterface 67 - [5: Line4] +RSInterface 68 - [1: Name] +RSInterface 69 - [1: Name] +RSInterface 69 - [2: Line1] +RSInterface 70 - [1: Name] +RSInterface 70 - [2: Line1] +RSInterface 70 - [3: Line2] +RSInterface 71 - [1: Name] +RSInterface 71 - [2: Line1] +RSInterface 71 - [3: Line2] +RSInterface 71 - [4: Line3] +RSInterface 72 - [6: What would you like to make in the churn?] +RSInterface 73 - [10: What would you like to make in the churn?] +RSInterface 73 - [11: Churn Butter] +RSInterface 74 - [14: What would you like to make?] +RSInterface 74 - [15: Churn Cream] +RSInterface 74 - [16: Churn Butter] +RSInterface 75 - [0: %1] +RSInterface 75 - [24: S P E C I A L A T T A C K] +RSInterface 75 - [25: Combat Lvl: %1] +RSInterface 75 - [27: Chop] +RSInterface 75 - [28: Hack] +RSInterface 75 - [29: Smash] +RSInterface 75 - [30: Auto Retaliate
(Off)] +RSInterface 75 - [31: Block] +RSInterface 75 - [32: (Aggressive)
(Slash)
(Strength XP)] +RSInterface 75 - [33: (Aggressive)
(Crush)
(Strength XP)] +RSInterface 75 - [34: (Defensive)
(Slash)
(Defence XP)] +RSInterface 75 - [35: (Accurate)
(Slash)
(Attack XP)] +RSInterface 75 - [36: When active your player
will automatically fight
back if attacked] +RSInterface 76 - [0: %1] +RSInterface 76 - [22: S P E C I A L A T T A C K] +RSInterface 76 - [23: Combat Lvl: %1] +RSInterface 76 - [25: Block] +RSInterface 76 - [26: Pound] +RSInterface 76 - [27: Pummel] +RSInterface 76 - [28: Auto Retaliate
(Off)] +RSInterface 76 - [29: (Accurate)
(Crush)
(Attack XP)] +RSInterface 76 - [30: (Aggressive)
(Crush)
(Strength XP)] +RSInterface 76 - [31: (Defensive)
(Crush)
(Defence XP)] +RSInterface 76 - [32: When active your player
will automatically fight
back if attacked] +RSInterface 77 - [0: %1] +RSInterface 77 - [22: S P E C I A L A T T A C K] +RSInterface 77 - [23: Combat Lvl: %1] +RSInterface 77 - [25: Longrange] +RSInterface 77 - [26: Accurate] +RSInterface 77 - [27: Rapid] +RSInterface 77 - [28: Auto Retaliate
(Off)] +RSInterface 77 - [29: (Accurate)
(Ranged XP)] +RSInterface 77 - [30: (Rapid)
(Ranged XP)] +RSInterface 77 - [31: (Longrange)
(Ranged XP)
(Defence XP)] +RSInterface 77 - [32: When active your player
will automatically fight
back if attacked] +RSInterface 78 - [0: %1] +RSInterface 78 - [24: S P E C I A L A T T A C K] +RSInterface 78 - [25: Combat Lvl: %1] +RSInterface 78 - [27: Chop] +RSInterface 78 - [28: Slash] +RSInterface 78 - [29: Lunge] +RSInterface 78 - [30: Block] +RSInterface 78 - [31: Auto Retaliate
(Off)] +RSInterface 78 - [32: (Accurate)
(Slash)
(Attack XP)] +RSInterface 78 - [33: (Aggressive)
(Slash)
(Strength XP)] +RSInterface 78 - [34: (Controlled)
(Stab)
(Shared XP)] +RSInterface 78 - [35: (Defensive)
(Slash)
(Defence XP)] +RSInterface 78 - [36: When active your player
will automatically fight
back if attacked] +RSInterface 79 - [0: %1] +RSInterface 79 - [22: S P E C I A L A T T A C K] +RSInterface 79 - [23: Combat Lvl: %1] +RSInterface 79 - [25: Accurate] +RSInterface 79 - [26: Rapid] +RSInterface 79 - [27: Longrange] +RSInterface 79 - [28: Auto Retaliate
(Off)] +RSInterface 79 - [29: (Accurate)
(Ranged XP)] +RSInterface 79 - [30: (Rapid)
(Ranged XP)] +RSInterface 79 - [31: (Longrange)
(Ranged XP)
(Defence XP)] +RSInterface 79 - [32: When active your player
will automatically fight
back if attacked] +RSInterface 80 - [0: %1] +RSInterface 80 - [6: Combat Lvl: %1] +RSInterface 80 - [8: Aim and Fire] +RSInterface 80 - [9: Kick] +RSInterface 80 - [10: Auto Retaliate
(Off)] +RSInterface 80 - [11: Aim and Fire] +RSInterface 80 - [12: (Aggressive)
(Crush)
(Strength XP)] +RSInterface 81 - [0: %1] +RSInterface 81 - [24: S P E C I A L A T T A C K] +RSInterface 81 - [25: Combat Lvl: %1] +RSInterface 81 - [27: Chop] +RSInterface 81 - [28: Slash] +RSInterface 81 - [29: Lunge] +RSInterface 81 - [30: Block] +RSInterface 81 - [31: Auto Retaliate
(Off)] +RSInterface 81 - [32: (Accurate)
(Slash)
(Attack XP)] +RSInterface 81 - [33: (Aggressive)
(Slash)
(Strength XP)] +RSInterface 81 - [34: (Controlled)
(Stab)
(Shared XP)] +RSInterface 81 - [35: (Defensive)
(Slash)
(Defence XP)] +RSInterface 81 - [36: When active your player
will automatically fight
back if attacked] +RSInterface 82 - [0: %1] +RSInterface 82 - [24: S P E C I A L A T T A C K] +RSInterface 82 - [25: Combat Lvl: %1] +RSInterface 82 - [27: Chop] +RSInterface 82 - [28: Slash] +RSInterface 82 - [29: Smash] +RSInterface 82 - [30: Block] +RSInterface 82 - [31: Auto Retaliate
(Off)] +RSInterface 82 - [32: (Accurate)
(Slash)
(Attack XP)] +RSInterface 82 - [33: (Aggressive)
(Slash)
(Strength XP)] +RSInterface 82 - [34: (Aggressive)
(Crush)
(Strength XP)] +RSInterface 82 - [35: (Defensive)
(Slash)
(Defence XP)] +RSInterface 82 - [36: When active your player
will automatically fight
back if attacked] +RSInterface 83 - [0: %1] +RSInterface 83 - [24: S P E C I A L A T T A C K] +RSInterface 83 - [25: Combat Lvl: %1] +RSInterface 83 - [27: Spike] +RSInterface 83 - [28: Impale] +RSInterface 83 - [29: Smash] +RSInterface 83 - [30: Block] +RSInterface 83 - [31: Auto Retaliate
(Off)] +RSInterface 83 - [32: (Accurate)
(Stab)
(Attack XP)] +RSInterface 83 - [33: (Aggressive)
(Stab)
(Strength XP)] +RSInterface 83 - [34: (Aggressive)
(Crush)
(Strength XP)] +RSInterface 83 - [35: (Defensive)
(Stab)
(Defence XP)] +RSInterface 83 - [36: When active your player
will automatically fight
back if attacked] +RSInterface 84 - [0: %1] +RSInterface 84 - [22: S P E C I A L A T T A C K] +RSInterface 84 - [23: Combat Lvl: %1] +RSInterface 84 - [25: Jab] +RSInterface 84 - [26: Swipe] +RSInterface 84 - [27: Fend] +RSInterface 84 - [28: Auto Retaliate
(Off)] +RSInterface 84 - [29: (Controlled)
(Stab)
(Shared XP)] +RSInterface 84 - [30: (Aggressive)
(Slash)
(Strength XP)] +RSInterface 84 - [31: (Defensive)
(Stab)
(Defence XP)] +RSInterface 84 - [32: When active your player
will automatically fight
back if attacked] +RSInterface 85 - [0: %1] +RSInterface 85 - [22: S P E C I A L A T T A C K] +RSInterface 85 - [23: Combat Lvl: %1] +RSInterface 85 - [25: Bash] +RSInterface 85 - [26: Pound] +RSInterface 85 - [27: Block] +RSInterface 85 - [28: Auto Retaliate
(Off)] +RSInterface 85 - [29: (Accurate)
(Crush)
(Attack XP)] +RSInterface 85 - [30: (Aggressive)
(Crush)
(Strength XP)] +RSInterface 85 - [31: (Defensive)
(Crush)
(Defence XP)] +RSInterface 85 - [32: When active your player
will automatically fight
back if attacked] +RSInterface 86 - [0: %1] +RSInterface 86 - [10: Combat Lvl: %1] +RSInterface 86 - [12: Reap] +RSInterface 86 - [13: Chop] +RSInterface 86 - [14: Jab] +RSInterface 86 - [15: Block] +RSInterface 86 - [16: Auto Retaliate
(Off)] +RSInterface 86 - [17: (Accurate)
(Slash)
(Attack XP)] +RSInterface 86 - [18: (Aggressive)
(Stab)
(Strength XP)] +RSInterface 86 - [19: (Aggressive)
(Crush)
(Strength XP)] +RSInterface 86 - [20: (Defensive)
(Slash)
(Defence XP)] +RSInterface 87 - [0: %1] +RSInterface 87 - [24: S P E C I A L A T T A C K] +RSInterface 87 - [25: Combat Lvl: %1] +RSInterface 87 - [27: Lunge] +RSInterface 87 - [28: Swipe] +RSInterface 87 - [29: Pound] +RSInterface 87 - [30: Block] +RSInterface 87 - [31: Auto Retaliate
(Off)] +RSInterface 87 - [32: (Controlled)
(Stab)
(Shared XP)] +RSInterface 87 - [33: (Controlled)
(Slash)
(Shared XP)] +RSInterface 87 - [34: (Controlled)
(Crush)
(Shared XP)] +RSInterface 87 - [35: (Defensive)
(Stab)
(Defence XP)] +RSInterface 87 - [36: When active your player
will automatically fight
back if attacked] +RSInterface 88 - [0: %1] +RSInterface 88 - [24: S P E C I A L A T T A C K] +RSInterface 88 - [25: Combat Lvl: %1] +RSInterface 88 - [27: Pound] +RSInterface 88 - [28: Pummel] +RSInterface 88 - [29: Spike] +RSInterface 88 - [30: Block] +RSInterface 88 - [31: Auto Retaliate
(Off)] +RSInterface 88 - [32: (Accurate)
(Crush)
(Attack XP)] +RSInterface 88 - [33: (Aggressive)
(Crush)
(Strength XP)] +RSInterface 88 - [34: (Controlled)
(Stab)
(Shared XP)] +RSInterface 88 - [35: (Defensive)
(Crush)
(Defence XP)] +RSInterface 88 - [36: When active your player
will automatically fight
back if attacked] +RSInterface 89 - [0: %1] +RSInterface 89 - [24: S P E C I A L A T T A C K] +RSInterface 89 - [25: Combat Lvl: %1] +RSInterface 89 - [27: Stab] +RSInterface 89 - [28: Lunge] +RSInterface 89 - [29: Slash] +RSInterface 89 - [30: Block] +RSInterface 89 - [31: Auto Retaliate
(Off)] +RSInterface 89 - [32: (Accurate)
(Stab)
(Attack XP)] +RSInterface 89 - [33: (Aggressive)
(Stab)
(Strength XP)] +RSInterface 89 - [34: (Aggressive)
(Slash)
(Strength XP)] +RSInterface 89 - [35: (Defensive)
(Stab)
(Defence XP)] +RSInterface 89 - [36: When active your player
will automatically fight
back if attacked] +RSInterface 90 - [0: %1] +RSInterface 90 - [10: Auto Retaliate
(Off)] +RSInterface 90 - [11: Spell] +RSInterface 90 - [99: S P E C I A L A T T A C K] +RSInterface 90 - [100: Combat Lvl: %1] +RSInterface 90 - [101: Bash] +RSInterface 90 - [102: Pound] +RSInterface 90 - [103: Focus] +RSInterface 90 - [105: (Accurate)
(Crush)
(Attack XP)] +RSInterface 90 - [106: (Aggressive)
(Crush)
(Strength XP)] +RSInterface 90 - [107: (Defensive)
(Crush)
(Defence XP)] +RSInterface 90 - [108: (Attack with
a spell)
(Magic XP)
(Defence XP)] +RSInterface 90 - [109: (Attack with
a spell)
(Magic XP)] +RSInterface 90 - [110: Select to perform
a special attack] +RSInterface 90 - [111: When active your player
will automatically fight
back if attacked] +RSInterface 90 - [112: Spell] +RSInterface 90 - [185: Smoke rush
(Magic XP)] +RSInterface 90 - [186: Shadow rush
(Magic XP)] +RSInterface 90 - [187: Blood rush
(Magic XP)] +RSInterface 90 - [188: Ice rush
(Magic XP)] +RSInterface 90 - [189: Smoke burst
(Magic XP)] +RSInterface 90 - [190: Shadow burst
(Magic XP)] +RSInterface 90 - [191: Blood Burst
(Magic XP)] +RSInterface 90 - [192: Ice burst
(Magic XP)] +RSInterface 90 - [193: Smoke blitz
(Magic XP)] +RSInterface 90 - [194: Blood blitz
(Magic XP)] +RSInterface 90 - [195: Ice blitz
(Magic XP)] +RSInterface 90 - [196: Smoke barrage
(Magic XP)] +RSInterface 90 - [197: Shadow
barrage
(Magic XP)] +RSInterface 90 - [198: Blood barrage
(Magic XP)] +RSInterface 90 - [199: Ice barrage
(Magic XP)] +RSInterface 90 - [200: Wind strike
(Magic XP)] +RSInterface 90 - [201: Water strike
(Magic XP)] +RSInterface 90 - [202: Earth strike
(Magic XP)] +RSInterface 90 - [203: Fire strike
(Magic XP)] +RSInterface 90 - [204: Wind bolt
(Magic XP)] +RSInterface 90 - [205: Water bolt
(Magic XP)] +RSInterface 90 - [206: Earth bolt
(Magic XP)] +RSInterface 90 - [207: Fire bolt
(Magic XP)] +RSInterface 90 - [208: Wind blast
(Magic XP)] +RSInterface 90 - [209: Water blast
(Magic XP)] +RSInterface 90 - [210: Earth blast
(Magic XP)] +RSInterface 90 - [211: Fire blast
(Magic XP)] +RSInterface 90 - [212: Wind wave
(Magic XP)] +RSInterface 90 - [213: Water wave
(Magic XP)] +RSInterface 90 - [214: Earth wave
(Magic XP)] +RSInterface 90 - [215: Fire wave
(Magic XP)] +RSInterface 90 - [216: Crumble undead
(Magic XP)] +RSInterface 90 - [217: Magic dart
(Magic XP)] +RSInterface 90 - [218: Claws of Guthix
(Magic XP)] +RSInterface 90 - [219: Earth wave
(Magic XP)
(Defence XP)] +RSInterface 90 - [220: Smoke barrage
(Magic XP)
(Defence XP)] +RSInterface 90 - [221: Shadow rush
(Magic XP)
(Defence XP)] +RSInterface 90 - [222: Wind wave
(Magic XP)
(Defence XP)] +RSInterface 90 - [223: Wind bolt
(Magic XP)
(Defence XP)] +RSInterface 90 - [224: Blood rush
(Magic XP)
(Defence XP)] +RSInterface 90 - [225: Shadow
barrage
(Magic XP)
(Defence XP)] +RSInterface 90 - [226: Water blast
(Magic XP)
(Defence XP)] +RSInterface 90 - [227: Ice rush
(Magic XP)
(Defence XP)] +RSInterface 90 - [228: Claws of Guthix
(Magic XP)
(Defence XP)] +RSInterface 90 - [229: Blood barrage
(Magic XP)
(Defence XP)] +RSInterface 90 - [230: Smoke burst
(Magic XP)
(Defence XP)] +RSInterface 90 - [231: Water bolt
(Magic XP)
(Defence XP)] +RSInterface 90 - [232: Crumble undead
(Magic XP)
(Defence XP)] +RSInterface 90 - [233: Shadow burst
(Magic XP)
(Defence XP)] +RSInterface 90 - [234: Ice barrage
(Magic XP)
(Defence XP)] +RSInterface 90 - [235: Earth blast
(Magic XP)
(Defence XP)] +RSInterface 90 - [236: Blood Burst
(Magic XP)
(Defence XP)] +RSInterface 90 - [237: Earth bolt
(Magic XP)
(Defence XP)] +RSInterface 90 - [238: Wind strike
(Magic XP)
(Defence XP)] +RSInterface 90 - [239: Ice burst
(Magic XP)
(Defence XP)] +RSInterface 90 - [240: Water wave
(Magic XP)
(Defence XP)] +RSInterface 90 - [241: Fire wave
(Magic XP)
(Defence XP)] +RSInterface 90 - [242: Water strike
(Magic XP)
(Defence XP)] +RSInterface 90 - [243: Fire bolt
(Magic XP)
(Defence XP)] +RSInterface 90 - [244: Smoke blitz
(Magic XP)
(Defence XP)] +RSInterface 90 - [245: Fire blast
(Magic XP)
(Defence XP)] +RSInterface 90 - [246: Earth strike
(Magic XP)
(Defence XP)] +RSInterface 90 - [247: Blood blitz
(Magic XP)
(Defence XP)] +RSInterface 90 - [248: Magic dart
(Magic XP)
(Defence XP)] +RSInterface 90 - [249: Wind blast
(Magic XP)
(Defence XP)] +RSInterface 90 - [250: Ice blitz
(Magic XP)
(Defence XP)] +RSInterface 90 - [251: Fire strike
(Magic XP)
(Defence XP)] +RSInterface 91 - [0: %1] +RSInterface 91 - [22: S P E C I A L A T T A C K] +RSInterface 91 - [23: Combat Lvl: %1] +RSInterface 91 - [25: Accurate] +RSInterface 91 - [26: Rapid] +RSInterface 91 - [27: Longrange] +RSInterface 91 - [28: Auto Retaliate
(Off)] +RSInterface 91 - [29: (Accurate)
(Ranged XP)] +RSInterface 91 - [30: (Rapid)
(Ranged XP)] +RSInterface 91 - [31: (Longrange)
(Ranged XP)
(Defence XP)] +RSInterface 91 - [32: When active your player
will automatically fight
back if attacked] +RSInterface 92 - [0: %1] +RSInterface 92 - [22: S P E C I A L A T T A C K] +RSInterface 92 - [23: Combat Lvl: %1] +RSInterface 92 - [25: Punch] +RSInterface 92 - [26: Kick] +RSInterface 92 - [27: Block] +RSInterface 92 - [28: Auto Retaliate
(Off)] +RSInterface 92 - [29: (Accurate)
(Crush)
(Attack XP)] +RSInterface 92 - [30: (Aggressive)
(Crush)
(Strength XP)] +RSInterface 92 - [31: (Defensive)
(Crush)
(Defence XP)] +RSInterface 92 - [32: When active your player
will automatically fight
back if attacked] +RSInterface 93 - [0: %1] +RSInterface 93 - [22: S P E C I A L A T T A C K] +RSInterface 93 - [23: Combat Lvl: %1] +RSInterface 93 - [25: Flick] +RSInterface 93 - [26: Lash] +RSInterface 93 - [27: Deflect] +RSInterface 93 - [28: Auto Retaliate
(Off)] +RSInterface 93 - [29: (Accurate)
(Slash)
(Attack XP)] +RSInterface 93 - [30: (Controlled)
(Slash)
(Shared XP)] +RSInterface 93 - [31: (Defensive)
(Slash)
(Defence XP)] +RSInterface 93 - [32: When active your player
will automatically fight
back if attacked] +RSInterface 94 - [3: Are you sure you want to destroy this object?] +RSInterface 94 - [4: Yes.] +RSInterface 94 - [5: No.] +RSInterface 94 - [10: Single_Line_Text] +RSInterface 94 - [11: Multi_line_text_1] +RSInterface 94 - [12: Multi_line_text_2] +RSInterface 95 - [12: Port Tyras] +RSInterface 95 - [13: Port Phasmatys] +RSInterface 95 - [14: Catherby] +RSInterface 95 - [15: Shipyard] +RSInterface 95 - [16: Karamja] +RSInterface 95 - [17: Brimhaven] +RSInterface 95 - [18: Port Khazard] +RSInterface 95 - [19: Port Sarim] +RSInterface 95 - [20: Mos Le'Harmless] +RSInterface 95 - [21: Crandor] +RSInterface 95 - [22: Oo'glog] +RSInterface 99 - [5: Harold] +RSInterface 99 - [6: Player] +RSInterface 99 - [28: Roll Dice!] +RSInterface 99 - [30: Continue...] +RSInterface 99 - [31: 0] +RSInterface 99 - [32: 0] +RSInterface 99 - [33: You win!] +RSInterface 102 - [15: Items Kept on Death] +RSInterface 102 - [17: Items you will keep on death if not skulled:] +RSInterface 102 - [20: Items you will lose on death if not skulled:] +RSInterface 102 - [25: Information:] +RSInterface 102 - [27: This is where the information goes, This is where the information goes, This is where the information goes, This is where the information goes, This is where the information goes, This is where the information goes] +RSInterface 102 - [28: put information in here,put information in here,put information in] +RSInterface 103 - [11: What comes next?] +RSInterface 104 - [19: Aquarius] +RSInterface 104 - [20: Aries] +RSInterface 104 - [21: Cancer] +RSInterface 104 - [22: Capricorn] +RSInterface 104 - [23: Gemini] +RSInterface 104 - [24: Leo] +RSInterface 104 - [25: Libra] +RSInterface 104 - [26: Pisces] +RSInterface 104 - [27: Sagittarius] +RSInterface 104 - [28: Scorpio] +RSInterface 104 - [29: Taurus] +RSInterface 104 - [30: Virgo] +RSInterface 104 - [31: Star Chart Viewer] +RSInterface 105 - [14: Grand Exchange] +RSInterface 105 - [17: Shown below is a summary of all your current offers.] +RSInterface 105 - [133: Buy Offer] +RSInterface 105 - [141: Choose an item to exchange] +RSInterface 105 - [146: Quantity:] +RSInterface 105 - [150: 1] +RSInterface 105 - [151: Price per item:] +RSInterface 105 - [155: 1 gp] +RSInterface 105 - [162: 1] +RSInterface 105 - [164: 10] +RSInterface 105 - [166: 100] +RSInterface 105 - [168: 1000] +RSInterface 105 - [170: ...] +RSInterface 105 - [185: ...] +RSInterface 105 - [191: Confirm Offer] +RSInterface 105 - [196: Click the icon to the left to search for items.] +RSInterface 105 - [199: Select an item in your inventory to sell.] +RSInterface 106 - [14: Grand Exchange] +RSInterface 106 - [17: Shown below is a summary of all your current offers.] +RSInterface 106 - [124: Jetzt ist Ihr Angebot eingegangen! Sie k?nnen jederzeit darauf klicken, um sich die Einzelheiten anzuschauen. Unten wird der Fortschritt mit einem Balken angezeigt. ] +RSInterface 108 - [14: Grand Exchange] +RSInterface 108 - [22: Buy Offer] +RSInterface 108 - [28: 1,281 gp] +RSInterface 108 - [29: Choose an item to exchange] +RSInterface 108 - [30: Quantity:] +RSInterface 108 - [34: 2] +RSInterface 108 - [35: Price per item:] +RSInterface 108 - [39: 1,281 gp] +RSInterface 108 - [43: 1] +RSInterface 108 - [45: 10] +RSInterface 108 - [47: 100] +RSInterface 108 - [49: 500] +RSInterface 108 - [51: ...] +RSInterface 108 - [64: ...] +RSInterface 108 - [68: 2,562 gp] +RSInterface 108 - [71: Confirm Offer] +RSInterface 108 - [94: Jetzt ist Ihr Angebot eingegangen! Sie k?nnen jederzeit darauf klicken, um sich die Einzelheiten anzuschauen. Unten wird der Fortschritt mit einem Balken angezeigt. ] +RSInterface 109 - [15: Grand Exchange - Collection Box] +RSInterface 110 - [14: Grand Exchange] +RSInterface 110 - [22: Buy Offer] +RSInterface 110 - [27: N/A] +RSInterface 110 - [28: Choose an item to exchange] +RSInterface 110 - [29: Quantity:] +RSInterface 110 - [33: 1] +RSInterface 110 - [34: Price per item:] +RSInterface 110 - [38: 1 gp] +RSInterface 110 - [42: 1] +RSInterface 110 - [44: 10] +RSInterface 110 - [46: 100] +RSInterface 110 - [48: 500] +RSInterface 110 - [50: ...] +RSInterface 110 - [63: ...] +RSInterface 110 - [69: Confirm Offer] +RSInterface 110 - [70: 1 gp] +RSInterface 110 - [89: Jetzt ist Ihr Angebot eingegangen! Sie k?nnen jederzeit darauf klicken, um sich die Einzelheiten anzuschauen. Unten wird der Fortschritt mit einem Balken angezeigt. ] +RSInterface 111 - [40: %1] +RSInterface 111 - [89: line1] +RSInterface 111 - [90: line2] +RSInterface 111 - [91: line3] +RSInterface 111 - [92: line4] +RSInterface 111 - [93: line5] +RSInterface 111 - [94: line6] +RSInterface 111 - [95: line7] +RSInterface 111 - [96: line8] +RSInterface 111 - [97: line9] +RSInterface 111 - [98: line10] +RSInterface 111 - [99: line11] +RSInterface 111 - [100: line12] +RSInterface 111 - [101: line13] +RSInterface 111 - [102: line14] +RSInterface 111 - [103: line15] +RSInterface 111 - [104: line16] +RSInterface 111 - [105: line17] +RSInterface 111 - [106: line18] +RSInterface 111 - [107: line19] +RSInterface 111 - [108: line20] +RSInterface 111 - [109: line21] +RSInterface 111 - [110: line22] +RSInterface 112 - [4: Name] +RSInterface 112 - [5: Line1] +RSInterface 112 - [7: Line1] +RSInterface 113 - [17: That's it, it all makes sense now! If you were a dwarf, that is...] +RSInterface 114 - [20: Schematic 1] +RSInterface 114 - [21: Schematic 2] +RSInterface 114 - [22: Schematic 3] +RSInterface 114 - [23: Show/Select] +RSInterface 116 - [4: Title] +RSInterface 123 - [2: Certificate of Advanced Healing] +RSInterface 123 - [3: From PoxStead College.] +RSInterface 123 - [4: Signed Dr Foster-MMD, PRD
Head Of
Magical Healing.] +RSInterface 124 - [1: List of Fairy Queen's Symptoms.] +RSInterface 124 - [3: Extremely weak
Slow discorporation of ethereal body
Drifting in and out of coma
Shallow breath
Fading magical energy
High fever] +RSInterface 125 - [67: Amazing Farming Equipment Store] +RSInterface 125 - [70: Farming rake] +RSInterface 125 - [71: %1/1] +RSInterface 125 - [72: Seed dibber] +RSInterface 125 - [73: %1/1] +RSInterface 125 - [74: All-purpose spade] +RSInterface 125 - [75: %1/1] +RSInterface 125 - [76: Secateurs] +RSInterface 125 - [77: %1/1] +RSInterface 125 - [78: Watering Can] +RSInterface 125 - [79: 0/1] +RSInterface 125 - [80: Gardening trowel] +RSInterface 125 - [81: %1/1] +RSInterface 125 - [82: Empty buckets] +RSInterface 125 - [83: %1/31] +RSInterface 125 - [84: Normal Compost] +RSInterface 125 - [85: %1/255] +RSInterface 125 - [86: Super Compost] +RSInterface 125 - [87: %1/255] +RSInterface 126 - [2: Rake] +RSInterface 126 - [3: %1] +RSInterface 126 - [4: Dibber] +RSInterface 126 - [5: %1] +RSInterface 126 - [6: Spade] +RSInterface 126 - [7: %1] +RSInterface 126 - [8: Secateurs] +RSInterface 126 - [9: %1] +RSInterface 126 - [10: Watering Can] +RSInterface 126 - [11: %1] +RSInterface 126 - [12: Trowel] +RSInterface 126 - [13: %1] +RSInterface 126 - [14: Buckets] +RSInterface 126 - [15: %1] +RSInterface 126 - [16: Compost] +RSInterface 126 - [17: %1] +RSInterface 126 - [18: Super Compost] +RSInterface 127 - [11: **********] +RSInterface 127 - [12: ************************] +RSInterface 127 - [17: Remove this key] +RSInterface 127 - [18: ***************] +RSInterface 127 - [20: Remove this key] +RSInterface 128 - [44: x%1] +RSInterface 128 - [45: x%1] +RSInterface 129 - [64: x%1] +RSInterface 129 - [65: x%1] +RSInterface 130 - [99: x%1] +RSInterface 130 - [100: x%1] +RSInterface 131 - [1: Line1] +RSInterface 132 - [1: lj1] +RSInterface 132 - [2: lj2] +RSInterface 132 - [3: lj3] +RSInterface 132 - [4: lj4] +RSInterface 132 - [5: lj5] +RSInterface 132 - [6: lj6] +RSInterface 132 - [7: lj7] +RSInterface 132 - [8: lj8] +RSInterface 132 - [9: lj9] +RSInterface 132 - [10: lj10] +RSInterface 132 - [11: lj11] +RSInterface 132 - [13: >>>] +RSInterface 132 - [14: <<<] +RSInterface 132 - [16: >>>] +RSInterface 132 - [17: <<<] +RSInterface 132 - [19: >>>] +RSInterface 132 - [20: <<<] +RSInterface 132 - [22: >>>] +RSInterface 132 - [23: <<<] +RSInterface 132 - [25: >>>] +RSInterface 132 - [26: <<<] +RSInterface 132 - [28: >>>] +RSInterface 132 - [29: <<<] +RSInterface 132 - [31: >>>] +RSInterface 132 - [32: <<<] +RSInterface 132 - [34: >>>] +RSInterface 132 - [35: <<<] +RSInterface 132 - [37: >>>] +RSInterface 132 - [38: <<<] +RSInterface 132 - [40: >>>] +RSInterface 132 - [41: <<<] +RSInterface 132 - [43: >>>] +RSInterface 132 - [44: <<<] +RSInterface 132 - [45: Items I need to get for King Roald's garden:] +RSInterface 133 - [0: option1] +RSInterface 133 - [1: option1] +RSInterface 133 - [2: option3] +RSInterface 133 - [3: [A]] +RSInterface 133 - [4: [B]] +RSInterface 133 - [5: [C]] +RSInterface 134 - [2: Choose the stat you wish to be advanced!] +RSInterface 134 - [27: Confirm] +RSInterface 135 - [2: To the NORTH] +RSInterface 135 - [3: To the NORTH] +RSInterface 135 - [6: To the EAST] +RSInterface 135 - [7: To the SOUTH] +RSInterface 135 - [8: To the EAST] +RSInterface 135 - [9: To the SOUTH] +RSInterface 135 - [11: To the WEST] +RSInterface 135 - [12: To the WEST] +RSInterface 136 - [1: Both] +RSInterface 136 - [2: Argh!] +RSInterface 138 - [7: Ta Quir Priw] +RSInterface 138 - [8: Lemanto Andra] +RSInterface 138 - [9: Sindarpos] +RSInterface 138 - [10: Gandius] +RSInterface 138 - [11: Kar-Hewo] +RSInterface 138 - [12: Lemantolly] +RSInterface 138 - [13: Undri] +RSInterface 139 - [1: Gnomeball] +RSInterface 139 - [2: Score] +RSInterface 140 - [4: Select an Option] +RSInterface 144 - [88: Points Settings] +RSInterface 144 - [205: < To Lift] +RSInterface 144 - [207: Controls] +RSInterface 144 - [221: START] +RSInterface 144 - [223: Controls] +RSInterface 144 - [224: You are
here] +RSInterface 144 - [233: A] +RSInterface 144 - [234: B] +RSInterface 144 - [235: C] +RSInterface 144 - [236: D] +RSInterface 144 - [237: E] +RSInterface 144 - [238: F] +RSInterface 144 - [239: G] +RSInterface 144 - [240: H] +RSInterface 144 - [241: I] +RSInterface 144 - [242: J] +RSInterface 144 - [243: K] +RSInterface 145 - [2: Dwarf] +RSInterface 145 - [3: Wartface & Bentnoze] +RSInterface 145 - [4: Pirate Pete] +RSInterface 145 - [5: Lumbridge Guide] +RSInterface 145 - [6: Evil Dave] +RSInterface 145 - [7: Sir Amik Varze] +RSInterface 145 - [8: Skrach 'Bone Cruncher' Uglogwee] +RSInterface 145 - [9: Monkey Ambassador] +RSInterface 145 - [12: Recipe for Disaster] +RSInterface 145 - [13: This quest is comprised of the 8 mini quests highlighted below] +RSInterface 148 - [7: Select an Option] +RSInterface 151 - [9: Five hundred years have passed since the rule of King Alvis,] +RSInterface 151 - [10: saviour of Keldagrim, victim of his own inventions.] +RSInterface 151 - [11: Founder of the Consortium, the gathering of mining companies] +RSInterface 151 - [12: that were to serve the monarchy, eventually the monarchy came] +RSInterface 151 - [13: to serve the Consortium.] +RSInterface 151 - [14: By the time of his death, the monarchy was all but abolished.] +RSInterface 151 - [15: By now, the Kings of Keldagrim are but a distant memory...] +RSInterface 151 - [16: with only the statue of King Alvis to remind the people of the] +RSInterface 152 - [7: The Giant
Dwarf] +RSInterface 152 - [8: Keldagrim] +RSInterface 152 - [9: Grand Capital
of the Dwarven realm] +RSInterface 152 - [10: Rise of the
Red Axe] +RSInterface 152 - [11: Part 1] +RSInterface 152 - [12: Keldagrim
Palace] +RSInterface 152 - [13: Consortium
Meeting] +RSInterface 152 - [14: A little while later] +RSInterface 152 - [15: Rise of the
Red Axe] +RSInterface 152 - [16: Part II] +RSInterface 153 - [88: Oh dear, you're dead, but don't despair!] +RSInterface 153 - [89: Never show me this again] +RSInterface 153 - [98: You can buy a new tinderbox from the general store.] +RSInterface 153 - [99: You can buy a new axe from Bob's Axe shop in south Lumbridge.] +RSInterface 153 - [100: You can pick up a pickaxe above the gates of Lumbridge Castle or buy one from Bob's Axe shop in south Lumbridge.] +RSInterface 153 - [101: You can get a new net from the Fishing Tutor in Lumbridge Swamps.] +RSInterface 153 - [102: You can get new combat equipment from the combat tutors north of Lumbridge Castle.] +RSInterface 153 - [103: You can buy a new hammer from the general store.] +RSInterface 153 - [104: If you need more gold, kill goblins for a short while or try a quest.] +RSInterface 153 - [105: Tutors can help you with skills and give you basic equipment. Look for this icon on your mini map.] +RSInterface 153 - [106: More information is available in the manual on our website.] +RSInterface 154 - [13: What would you like to make?] +RSInterface 154 - [15: Armour] +RSInterface 154 - [17: Gloves] +RSInterface 154 - [19: Boots] +RSInterface 154 - [21: Vambraces] +RSInterface 154 - [23: Chaps] +RSInterface 154 - [25: Coif] +RSInterface 154 - [27: Cowl] +RSInterface 156 - [2: lj_title] +RSInterface 156 - [4: lj1] +RSInterface 156 - [5: lj2] +RSInterface 156 - [6: lj3] +RSInterface 156 - [7: lj4] +RSInterface 156 - [8: lj5] +RSInterface 156 - [9: lj6] +RSInterface 156 - [10: lj7] +RSInterface 156 - [11: lj8] +RSInterface 156 - [12: lj9] +RSInterface 156 - [13: lj10] +RSInterface 156 - [14: lj11] +RSInterface 156 - [15: lj12] +RSInterface 156 - [16: lj13] +RSInterface 156 - [17: lj14] +RSInterface 156 - [18: lj15] +RSInterface 156 - [19: lj16] +RSInterface 156 - [20: lj17] +RSInterface 156 - [21: lj18] +RSInterface 156 - [22: lj19] +RSInterface 156 - [23: lj20] +RSInterface 156 - [24: lj21] +RSInterface 156 - [25: lj22] +RSInterface 156 - [26: lj23] +RSInterface 156 - [27: lj24] +RSInterface 156 - [28: lj25] +RSInterface 156 - [29: lj26] +RSInterface 156 - [30: lj27] +RSInterface 156 - [31: lj28] +RSInterface 156 - [32: lj29] +RSInterface 156 - [33: lj30] +RSInterface 156 - [34: lj31] +RSInterface 156 - [35: lj32] +RSInterface 156 - [36: lj33] +RSInterface 156 - [37: lj34] +RSInterface 156 - [38: lj35] +RSInterface 156 - [39: lj36] +RSInterface 156 - [40: lj37] +RSInterface 156 - [41: lj38] +RSInterface 156 - [42: lj39] +RSInterface 156 - [43: lj40] +RSInterface 156 - [44: lj41] +RSInterface 156 - [45: lj42] +RSInterface 156 - [46: lj43] +RSInterface 156 - [47: lj44] +RSInterface 156 - [48: lj45] +RSInterface 156 - [49: lj46] +RSInterface 156 - [50: lj47] +RSInterface 156 - [51: lj48] +RSInterface 156 - [52: lj49] +RSInterface 156 - [53: lj50] +RSInterface 156 - [54: lj51] +RSInterface 156 - [55: lj52] +RSInterface 156 - [56: lj53] +RSInterface 156 - [57: lj54] +RSInterface 156 - [58: lj55] +RSInterface 156 - [59: lj56] +RSInterface 156 - [60: lj57] +RSInterface 156 - [61: lj58] +RSInterface 156 - [62: lj59] +RSInterface 156 - [63: lj60] +RSInterface 156 - [64: lj61] +RSInterface 156 - [65: lj62] +RSInterface 156 - [66: lj63] +RSInterface 156 - [67: lj64] +RSInterface 156 - [68: lj65] +RSInterface 156 - [69: lj66] +RSInterface 156 - [70: lj67] +RSInterface 156 - [71: lj68] +RSInterface 156 - [72: lj69] +RSInterface 156 - [73: lj70] +RSInterface 156 - [74: lj71] +RSInterface 156 - [75: lj72] +RSInterface 156 - [76: lj73] +RSInterface 156 - [77: lj74] +RSInterface 156 - [78: lj75] +RSInterface 156 - [79: lj76] +RSInterface 156 - [80: lj77] +RSInterface 156 - [81: lj78] +RSInterface 156 - [82: lj79] +RSInterface 156 - [83: lj80] +RSInterface 156 - [84: lj81] +RSInterface 156 - [85: lj82] +RSInterface 156 - [86: lj83] +RSInterface 156 - [87: lj84] +RSInterface 156 - [88: lj85] +RSInterface 156 - [89: lj86] +RSInterface 156 - [90: lj87] +RSInterface 156 - [91: lj88] +RSInterface 156 - [92: lj89] +RSInterface 156 - [93: lj90] +RSInterface 156 - [94: lj91] +RSInterface 156 - [95: lj92] +RSInterface 156 - [96: lj93] +RSInterface 156 - [97: lj94] +RSInterface 156 - [98: lj95] +RSInterface 156 - [99: lj96] +RSInterface 156 - [100: lj97] +RSInterface 156 - [101: lj98] +RSInterface 156 - [102: lj99] +RSInterface 156 - [103: lj100] +RSInterface 157 - [0: Line1] +RSInterface 157 - [1: Line2] +RSInterface 157 - [2: Click here to continue] +RSInterface 158 - [0: Line1] +RSInterface 158 - [1: Line2] +RSInterface 158 - [2: Click here to continue] +RSInterface 159 - [0: Line1] +RSInterface 159 - [1: Line2] +RSInterface 159 - [2: Click here to continue] +RSInterface 160 - [0: Line1] +RSInterface 160 - [1: Line2] +RSInterface 160 - [2: Click here to continue] +RSInterface 161 - [0: Line1] +RSInterface 161 - [1: Line2] +RSInterface 161 - [2: Click here to continue] +RSInterface 162 - [0: Line1] +RSInterface 162 - [1: Line2] +RSInterface 162 - [2: Click here to continue] +RSInterface 163 - [0: Line1] +RSInterface 163 - [1: Line2] +RSInterface 163 - [2: Click here to continue] +RSInterface 164 - [0: Line1] +RSInterface 164 - [1: Line2] +RSInterface 164 - [2: Click here to continue] +RSInterface 165 - [0: Line1] +RSInterface 165 - [1: Line2] +RSInterface 165 - [2: Click here to continue] +RSInterface 166 - [0: Line1] +RSInterface 166 - [1: Line2] +RSInterface 166 - [2: Click here to continue] +RSInterface 167 - [0: Line1] +RSInterface 167 - [1: Line2] +RSInterface 167 - [2: Click here to continue] +RSInterface 168 - [0: Line1] +RSInterface 168 - [1: Line2] +RSInterface 168 - [2: Click here to continue] +RSInterface 169 - [0: Line1] +RSInterface 169 - [1: Line2] +RSInterface 169 - [2: Click here to continue] +RSInterface 170 - [0: Line1] +RSInterface 170 - [1: Line2] +RSInterface 170 - [2: Click here to continue] +RSInterface 171 - [0: Line1] +RSInterface 171 - [1: Line2] +RSInterface 171 - [2: Click here to continue] +RSInterface 172 - [0: Line1] +RSInterface 172 - [1: Line2] +RSInterface 172 - [2: Click here to continue] +RSInterface 173 - [0: Line1] +RSInterface 173 - [1: Line2] +RSInterface 173 - [2: Click here to continue] +RSInterface 174 - [0: Line1] +RSInterface 174 - [1: Line2] +RSInterface 174 - [2: Click here to continue] +RSInterface 175 - [0: Line1] +RSInterface 175 - [1: Line2] +RSInterface 175 - [2: Click here to continue] +RSInterface 176 - [0: Line1] +RSInterface 176 - [1: Line2] +RSInterface 176 - [2: Click here to continue] +RSInterface 177 - [0: Line1] +RSInterface 177 - [1: Line2] +RSInterface 177 - [2: Click here to continue] +RSInterface 178 - [6: Click arrow buttons to move taper.] +RSInterface 178 - [7: Press the Light button to light the candles.] +RSInterface 181 - [16: Rotate mirror.] +RSInterface 182 - [0: When you have finished playing
RuneScape, always use the
button below to logout safely.] +RSInterface 183 - [21: -Drogokishuun-
Goblins of the
Fierce Blades] +RSInterface 183 - [22: -Huzamogaarb-
Live-Flesh Eaters
of the Chaos God] +RSInterface 183 - [23: -Saragorgak-
Footsoldiers of
Holy Wrath] +RSInterface 183 - [24: -Dorgeshuun-
Goblins of the
Strong Spears] +RSInterface 183 - [25: -Horogothgar-
Eaters of
Manflesh] +RSInterface 183 - [26: -Yurkolgokh-
The Flatulent] +RSInterface 183 - [27: -Thorobshuun-
Goblins of the
Hills] +RSInterface 183 - [28: -Garagorshuun-
Goblins of the
Sea] +RSInterface 183 - [29: -Rekeshuun-
Goblins of the
North] +RSInterface 183 - [30: -Ekeleshuun-
Goblins of the
East] +RSInterface 183 - [31: -Idithuun-
Goblins of the
South] +RSInterface 183 - [32: -Narogoshuun-
Goblins of the
West] +RSInterface 183 - [33: A History of the Goblin Race] +RSInterface 183 - [35: Goblin tradition holds that
their race was created by
a war-god in order to
fight a war against other
gods.] +RSInterface 183 - [36: (They never name their
god, so whether it is the
same as any of the gods
worshipped by the other
races is unknown.)] +RSInterface 183 - [37: The legends also speak
of goblins fighting
against goblins during
the wars, so it is likely
that gods other than
their creators used
them as footsoldiers.] +RSInterface 183 - [38: Although goblins are still
warlike, it is probable
that in earlier ages
they were more
organised than they
are now,] +RSInterface 183 - [40: especially if they were
under the direct
command of one or
more gods.] +RSInterface 183 - [41: This is corroborated
by finds unearthed
at various
archaeological sites,
including the large
excavation east of
Varrock.] +RSInterface 183 - [42: Armour and weapons
have been found,
obviously made to fit
goblins but far more
well-made than their
current equipment.] +RSInterface 183 - [44: Almost every piece of
ancient goblin equipment
has one of a number
of symbols on it,
and by correlating these
symbols with the
sketchy records that
survive from the
Third Age it has been
possible to identify
twelve distinct goblin tribes
or regiments.] +RSInterface 183 - [45: The separate identities of
the tribes have long
since dissolved and
no goblins remember the
symbols, although their
generals may still
recognize the ancient
tribal names.] +RSInterface 183 - [46: In the following pages
I present a list of
the tribes and their
symbols.] +RSInterface 184 - [1: A....a lemming] +RSInterface 184 - [2: B....a fryingpan] +RSInterface 184 - [3: C....the disenfrachaised youth of 1940's Columbia] +RSInterface 184 - [4: Is this:] +RSInterface 185 - [15: DIAMOND] +RSInterface 185 - [16: COINS] +RSInterface 185 - [17: RING] +RSInterface 185 - [18: U N L O C K] +RSInterface 186 - [0: Watch the statue! Fish here!] +RSInterface 187 - [14: Playing.............................] +RSInterface 188 - [2: Think] +RSInterface 188 - [3: Cry] +RSInterface 188 - [4: Laugh] +RSInterface 188 - [5: Dance] +RSInterface 188 - [6: Climb Rope] +RSInterface 188 - [7: Lean on air] +RSInterface 188 - [8: Glass Box] +RSInterface 190 - [6: Which shape is blue?] +RSInterface 190 - [10: Shape1] +RSInterface 190 - [11: Shape2] +RSInterface 190 - [12: Shape3] +RSInterface 194 - [1: Alchemy] +RSInterface 194 - [2: Pizazz Points:] +RSInterface 194 - [3: 9999] +RSInterface 194 - [4: Leather Boots:] +RSInterface 194 - [5: Adamant Kiteshield:] +RSInterface 194 - [6: Adamant Helm:] +RSInterface 194 - [7: Emerald:] +RSInterface 194 - [8: Rune Longsword:] +RSInterface 194 - [9: 999] +RSInterface 194 - [10: 999] +RSInterface 194 - [11: 999] +RSInterface 194 - [12: 999] +RSInterface 194 - [13: 999] +RSInterface 195 - [1: Enchantment] +RSInterface 195 - [2: Pizazz Points:] +RSInterface 195 - [3: 9999] +RSInterface 196 - [1: Graveyard] +RSInterface 196 - [2: Pizazz Points:] +RSInterface 196 - [3: 9999] +RSInterface 196 - [8: 4] +RSInterface 196 - [9: 3] +RSInterface 196 - [10: 2] +RSInterface 197 - [3: Magic Training Arena Shop] +RSInterface 197 - [4: Telekinetic Pizazz Points] +RSInterface 197 - [5: Enchantment Pizazz Points] +RSInterface 197 - [6: Graveyard Pizazz Points] +RSInterface 197 - [7: Alchemist Pizazz Points] +RSInterface 197 - [8: 99999] +RSInterface 197 - [9: 99999] +RSInterface 197 - [10: 99999] +RSInterface 197 - [11: 99999] +RSInterface 197 - [12: (Upgrade)] +RSInterface 197 - [13: (Upgrade)] +RSInterface 197 - [14: (Upgrade)] +RSInterface 198 - [1: Telekinetic] +RSInterface 198 - [2: Pizazz Points:] +RSInterface 198 - [3: 999999] +RSInterface 198 - [5: 999] +RSInterface 199 - [75: Hairdresser's Salon] +RSInterface 199 - [104: CONFIRM] +RSInterface 199 - [118: Please select colour] +RSInterface 200 - [88: Yrsa's Shoe Store] +RSInterface 200 - [89: CONFIRM (500 GOLD)] +RSInterface 201 - [88: Thessalia's Makeovers (Legs)] +RSInterface 201 - [106: CONFIRM (500 gold)] +RSInterface 201 - [123: Select colour] +RSInterface 201 - [145: Select leg style] +RSInterface 202 - [88: Thessalia's Makeovers (Torso)] +RSInterface 202 - [106: CONFIRM (500 gold)] +RSInterface 202 - [123: Select body style] +RSInterface 202 - [124: Select arms style] +RSInterface 202 - [125: Select colour] +RSInterface 203 - [76: Hairdresser's Salon] +RSInterface 203 - [99: CONFIRM] +RSInterface 203 - [113: Please select colour] +RSInterface 204 - [75: Hairdresser's Salon] +RSInterface 204 - [98: CONFIRM] +RSInterface 204 - [112: Please select colour] +RSInterface 205 - [88: CONFIRM (3000 Gold)] +RSInterface 205 - [101: MALE] +RSInterface 205 - [102: Select skin colour and gender] +RSInterface 205 - [103: FEMALE] +RSInterface 206 - [88: Thessalia's Makeovers (Legs)] +RSInterface 206 - [106: CONFIRM (500 gold)] +RSInterface 206 - [123: Select colour] +RSInterface 206 - [136: Select leg style] +RSInterface 207 - [88: Thessalia's Makeovers (Torso)] +RSInterface 207 - [106: CONFIRM (500 gold)] +RSInterface 207 - [123: Select body style] +RSInterface 207 - [124: Select arms style] +RSInterface 207 - [125: Select colour] +RSInterface 209 - [0: Complete the Maze as fast as possible!] +RSInterface 209 - [1: There is...] +RSInterface 209 - [2: %1%] +RSInterface 209 - [3: ... of the Reward left!] +RSInterface 210 - [0: Line1] +RSInterface 211 - [0: Line1] +RSInterface 211 - [1: Line2] +RSInterface 212 - [0: Line1] +RSInterface 212 - [1: Line2] +RSInterface 212 - [2: Line3] +RSInterface 213 - [0: Line1] +RSInterface 213 - [1: Line2] +RSInterface 213 - [2: Line3] +RSInterface 213 - [3: Line4] +RSInterface 214 - [0: Line1] +RSInterface 214 - [1: Line2] +RSInterface 214 - [2: Line3] +RSInterface 214 - [3: Line4] +RSInterface 214 - [4: Line5] +RSInterface 216 - [0: Line1] +RSInterface 217 - [0: Line1] +RSInterface 217 - [1: Line2] +RSInterface 218 - [0: Line1] +RSInterface 218 - [1: Line2] +RSInterface 218 - [2: Line3] +RSInterface 219 - [0: Line1] +RSInterface 219 - [1: Line2] +RSInterface 219 - [2: Line3] +RSInterface 219 - [3: Line4] +RSInterface 223 - [9: Shiver] +RSInterface 223 - [10: Spin] +RSInterface 223 - [11: Clap] +RSInterface 223 - [12: Bow] +RSInterface 223 - [13: Cheer] +RSInterface 223 - [14: Wave] +RSInterface 223 - [15: Preen] +RSInterface 224 - [2: Waterbirth Island] +RSInterface 224 - [3: Miscellania] +RSInterface 224 - [4: Etceteria] +RSInterface 224 - [5: Rellekka] +RSInterface 224 - [6: Neitiznot & Jatizso] +RSInterface 227 - [2: List of needed items:] +RSInterface 227 - [3: mourning_deathalter_item1] +RSInterface 227 - [5: mourning_deathalter_item2] +RSInterface 227 - [6: mourning_deathalter_item3] +RSInterface 227 - [7: mourning_deathalter_item4] +RSInterface 227 - [8: mourning_deathalter_item5] +RSInterface 227 - [9: mourning_deathalter_item6] +RSInterface 227 - [10: mourning_deathalter_item7] +RSInterface 227 - [11: mourning_deathalter_item8] +RSInterface 227 - [12: mourning_deathalter_item9] +RSInterface 227 - [13: mourning_deathalter_item10] +RSInterface 227 - [14: mourning_deathalter_item11] +RSInterface 227 - [15: mourning_deathalter_item12] +RSInterface 227 - [16: mourning_deathalter_item13] +RSInterface 227 - [17: mourning_deathalter_item14] +RSInterface 227 - [18: mourning_deathalter_item15] +RSInterface 227 - [19: mourning_deathalter_item16] +RSInterface 227 - [20: mourning_deathalter_item17] +RSInterface 227 - [21: mourning_deathalter_item18] +RSInterface 227 - [22: mourning_deathalter_item19] +RSInterface 227 - [23: mourning_deathalter_item20] +RSInterface 227 - [24: mourning_deathalter_item21] +RSInterface 227 - [25: mourning_deathalter_item22] +RSInterface 227 - [26: mourning_deathalter_item23] +RSInterface 227 - [27: mourning_deathalter_item24] +RSInterface 227 - [28: mourning_deathalter_item25] +RSInterface 227 - [29: mourning_deathalter_item26] +RSInterface 227 - [30: mourning_deathalter_item27] +RSInterface 227 - [31: mourning_deathalter_item28] +RSInterface 227 - [32: mourning_deathalter_item29] +RSInterface 227 - [33: mourning_deathalter_item30] +RSInterface 227 - [34: mourning_deathalter_item31] +RSInterface 227 - [35: mourning_deathalter_item32] +RSInterface 227 - [36: mourning_deathalter_item33] +RSInterface 227 - [37: mourning_deathalter_item34] +RSInterface 227 - [38: mourning_deathalter_item35] +RSInterface 227 - [39: mourning_deathalter_item36] +RSInterface 227 - [40: mourning_deathalter_item37] +RSInterface 227 - [41: mourning_deathalter_item38] +RSInterface 227 - [42: mourning_deathalter_item39] +RSInterface 227 - [43: mourning_deathalter_item40] +RSInterface 227 - [44: mourning_deathalter_item41] +RSInterface 227 - [45: mourning_deathalter_item42] +RSInterface 227 - [46: mourning_deathalter_item43] +RSInterface 227 - [47: mourning_deathalter_item44] +RSInterface 227 - [48: mourning_deathalter_item45] +RSInterface 227 - [49: mourning_deathalter_item46] +RSInterface 227 - [50: mourning_deathalter_item47] +RSInterface 227 - [51: mourning_deathalter_item48] +RSInterface 227 - [52: mourning_deathalter_item49] +RSInterface 227 - [53: mourning_deathalter_item50] +RSInterface 228 - [0: Select an Option] +RSInterface 228 - [1: option1] +RSInterface 228 - [2: option2] +RSInterface 229 - [0: Select an Option] +RSInterface 229 - [1: option1] +RSInterface 229 - [2: option2] +RSInterface 230 - [0: Select an Option] +RSInterface 230 - [1: option1] +RSInterface 230 - [2: option2] +RSInterface 230 - [3: option3] +RSInterface 231 - [0: Select an Option] +RSInterface 231 - [1: option1] +RSInterface 231 - [2: option2] +RSInterface 231 - [3: option3] +RSInterface 232 - [0: Select an Option] +RSInterface 232 - [1: option1] +RSInterface 232 - [2: option2] +RSInterface 232 - [3: option3] +RSInterface 232 - [4: option4] +RSInterface 233 - [0: Select an Option] +RSInterface 233 - [1: option1] +RSInterface 233 - [2: option2] +RSInterface 233 - [3: option3] +RSInterface 233 - [4: option4] +RSInterface 234 - [0: Select an Option] +RSInterface 234 - [1: option1] +RSInterface 234 - [2: option2] +RSInterface 234 - [3: option3] +RSInterface 234 - [4: option4] +RSInterface 234 - [5: option5] +RSInterface 235 - [0: Select an Option] +RSInterface 235 - [1: option1] +RSInterface 235 - [2: option2] +RSInterface 235 - [3: option3] +RSInterface 235 - [4: option4] +RSInterface 235 - [5: option5] +RSInterface 236 - [0: Select an Option] +RSInterface 236 - [1: option1] +RSInterface 236 - [2: option2] +RSInterface 237 - [0: Select an Option] +RSInterface 237 - [1: option1] +RSInterface 237 - [2: option2] +RSInterface 237 - [3: option3] +RSInterface 237 - [4: option4] +RSInterface 238 - [0: Select an Option] +RSInterface 238 - [1: option1] +RSInterface 238 - [2: option2] +RSInterface 238 - [3: option3] +RSInterface 238 - [4: option4] +RSInterface 238 - [5: option5] +RSInterface 239 - [1: To: Engineer Claus Mousetrap] +RSInterface 239 - [2: This morning I received a complaint about your inability to repair the Camp Tyras catapult, arriving without the tools and materials required. To avoid further delay, I'll repeat your instructions:] +RSInterface 239 - [3: *The replacement wooden parts must be made from MAHOGANY planks and at least MITHRIL nails.
*You will need METAL PARTS, which have been ordered from Rolad, the dwarf scholar.
The pride of the King's Engineers is at stake, Claus.] +RSInterface 239 - [4: SORT THIS MESS OUT!] +RSInterface 239 - [5: Chief Engineer, Commander Measures] +RSInterface 240 - [27: Tries = 3] +RSInterface 241 - [1: Name] +RSInterface 241 - [2: Line1] +RSInterface 242 - [1: Name] +RSInterface 242 - [2: Line1] +RSInterface 242 - [3: Line2] +RSInterface 243 - [1: Name] +RSInterface 243 - [2: Line1] +RSInterface 243 - [3: Line2] +RSInterface 243 - [4: Line3] +RSInterface 244 - [1: Name] +RSInterface 244 - [2: Line1] +RSInterface 244 - [3: Line2] +RSInterface 244 - [4: Line3] +RSInterface 244 - [5: Line4] +RSInterface 245 - [1: Name] +RSInterface 246 - [1: Name] +RSInterface 246 - [2: Line1] +RSInterface 247 - [1: Name] +RSInterface 247 - [2: Line1] +RSInterface 247 - [3: Line2] +RSInterface 248 - [1: Name] +RSInterface 248 - [2: Line1] +RSInterface 248 - [3: Line2] +RSInterface 248 - [4: Line3] +RSInterface 249 - [2: Surok Magis,] +RSInterface 249 - [4: Your actions are being watched. We know what you are trying to do and the VPSG will stop you! Do not attempt to leave the palace or you will be arrested on sight. We will not hesitate to kill you if you disobey King Roald's orders. Rat Burgiss] +RSInterface 250 - [2: To My Business Partner,] +RSInterface 250 - [4: All is well here, my friend. I will continue with my work. You do not need worry. They suspect nothing, the fools! In three days there will be a new King in Varrock! Surok Magis] +RSInterface 251 - [2: Instructions for Beacon Ring] +RSInterface 251 - [4: Use this ring when you are ready to summon me to your aid. It is a daunting task, yet you must battle the king to allow me to remove the spell from him. When the king is almost dead, use this ring and I will teleport to your aid. Be warned - Though I am skilled with magic, I am no fighter! Should you summon me too early I will have to teleport us out of danger! When our mission is completed, I will remove the summon ability from this ring, but you may keep it for protection. Zaff] +RSInterface 256 - [4: Current team] +RSInterface 256 - [5: -----] +RSInterface 256 - [6: -----] +RSInterface 256 - [7: -----] +RSInterface 256 - [8: -----] +RSInterface 256 - [9: -----] +RSInterface 256 - [10: Leader:] +RSInterface 256 - [11: Player 1:] +RSInterface 256 - [12: Player 2:] +RSInterface 256 - [13: Player 3:] +RSInterface 256 - [14: Player 4:] +RSInterface 259 - [11: Achievement Diary] +RSInterface 259 - [13: Karamja] +RSInterface 259 - [14: Varrock] +RSInterface 260 - [41: Cyrisus's Bank] +RSInterface 260 - [43: Chest] +RSInterface 261 - [27: %1%] +RSInterface 261 - [36: Adjust Screen Brightness] +RSInterface 261 - [37: Adjust Music Volume] +RSInterface 261 - [38: Adjust Sound Effect Volume] +RSInterface 261 - [39: Adjust Area Sound Volume] +RSInterface 261 - [40: Run (on) Energy %1%] +RSInterface 261 - [41: Chat Effects
(currently on)] +RSInterface 261 - [42: Split Private Chat
(currently on)] +RSInterface 261 - [43: Mouse buttons
(currently 2)] +RSInterface 261 - [44: Accept Aid (currently on)] +RSInterface 261 - [45: House Options] +RSInterface 261 - [46: Run (off) Energy %1%] +RSInterface 261 - [47: Chat Effects
(currently off)] +RSInterface 261 - [48: Split Private Chat
(currently off)] +RSInterface 261 - [49: Mouse buttons
(currently 1)] +RSInterface 261 - [50: Accept Aid (currently off)] +RSInterface 265 - [2: Clan A's name] +RSInterface 265 - [3: Players remaining:] +RSInterface 265 - [4: Opposing clan] +RSInterface 265 - [5: Players remaining:] +RSInterface 265 - [6: 0] +RSInterface 265 - [7: 0] +RSInterface 265 - [8: Time till start] +RSInterface 267 - [12: Attack] +RSInterface 267 - [13: Strength] +RSInterface 267 - [14: Defence] +RSInterface 267 - [15: Ranged] +RSInterface 267 - [16: Magic] +RSInterface 267 - [17: Hitpoints] +RSInterface 267 - [18: Prayer] +RSInterface 267 - [30: Void Knight Mace] +RSInterface 267 - [31: Void Knight Top] +RSInterface 267 - [32: Void Knight Robes] +RSInterface 267 - [33: Void Knight Gloves] +RSInterface 267 - [34: Herb Pack] +RSInterface 267 - [35: Seed Pack] +RSInterface 267 - [36: (1 Pt)] +RSInterface 267 - [37: (1 Pt)] +RSInterface 267 - [38: (1 Pt)] +RSInterface 267 - [39: (1 Pt)] +RSInterface 267 - [40: (1 Pt)] +RSInterface 267 - [41: (1 Pt)] +RSInterface 267 - [42: (1 Pt)] +RSInterface 267 - [43: (250 Pts)] +RSInterface 267 - [44: (250 Pts)] +RSInterface 267 - [45: (250 Pts)] +RSInterface 267 - [46: (150 Pts)] +RSInterface 267 - [47: (30 Pts)] +RSInterface 267 - [48: (15 Pts)] +RSInterface 267 - [49: Mineral Pack] +RSInterface 267 - [50: (15 Pts)] +RSInterface 267 - [51: (10 Pts)] +RSInterface 267 - [52: (10 Pts)] +RSInterface 267 - [53: (10 Pts)] +RSInterface 267 - [54: (10 Pts)] +RSInterface 267 - [55: (10 Pts)] +RSInterface 267 - [56: (10 Pts)] +RSInterface 267 - [57: (10 Pts)] +RSInterface 267 - [58: (100 Pts)] +RSInterface 267 - [59: (100 Pts)] +RSInterface 267 - [60: (100 Pts)] +RSInterface 267 - [61: (100 Pts)] +RSInterface 267 - [62: (100 Pts)] +RSInterface 267 - [63: (100 Pts)] +RSInterface 267 - [64: (100 Pts)] +RSInterface 267 - [65: Void Knight Mage Helm] +RSInterface 267 - [66: Void Knight Ranger Helm] +RSInterface 267 - [67: Void Knight Melee Helm] +RSInterface 267 - [68: Void Knight Seal] +RSInterface 267 - [69: (200 Pts)] +RSInterface 267 - [70: (200 Pts)] +RSInterface 267 - [71: (200 Pts)] +RSInterface 267 - [72: (10 Pts)] +RSInterface 267 - [73: Spinner Charm] +RSInterface 267 - [74: Ravager Charm] +RSInterface 267 - [75: Shifter Charm] +RSInterface 267 - [76: Torcher Charm] +RSInterface 267 - [77: (2 Pts)] +RSInterface 267 - [78: (28 Pts)] +RSInterface 267 - [79: (56 Pts)] +RSInterface 267 - [80: (28 Pts)] +RSInterface 267 - [81: (56 Pts)] +RSInterface 267 - [82: (28 Pts)] +RSInterface 267 - [83: (56 Pts)] +RSInterface 267 - [84: (28 Pts)] +RSInterface 267 - [85: (56 Pts)] +RSInterface 267 - [86: (2 Pts)] +RSInterface 267 - [87: (2 Pts)] +RSInterface 267 - [88: (2 Pts)] +RSInterface 267 - [96: Void Knights' Reward Options] +RSInterface 267 - [106: Confirm:] +RSInterface 270 - [3: Misthalin & Asgarnia] +RSInterface 270 - [47: Lumbridge] +RSInterface 270 - [48: Draynor] +RSInterface 270 - [49: Varrock] +RSInterface 270 - [50: Falador] +RSInterface 270 - [51: Port] +RSInterface 270 - [52: Sarim] +RSInterface 270 - [53: Rimmington] +RSInterface 270 - [54: Edgeville] +RSInterface 270 - [55: Al Kharid] +RSInterface 270 - [62: Show Tutors] +RSInterface 272 - [16: Grave Monument] +RSInterface 272 - [17: Saradomin

lights my way

through

the darkness of life] +RSInterface 273 - [1: Pop the correct balloon animal to find a key] +RSInterface 274 - [10: Quest Points: 0] +RSInterface 274 - [13: Free Quests] +RSInterface 274 - [14: Black Knights' Fortress] +RSInterface 274 - [15: Cook's Assistant] +RSInterface 274 - [16: Demon Slayer] +RSInterface 274 - [17: Doric's Quest] +RSInterface 274 - [18: Dragon Slayer] +RSInterface 274 - [19: Ernest the Chicken] +RSInterface 274 - [20: Goblin Diplomacy] +RSInterface 274 - [21: Imp Catcher] +RSInterface 274 - [22: The Knight's Sword] +RSInterface 274 - [23: Pirate's Treasure] +RSInterface 274 - [24: Prince Ali Rescue] +RSInterface 274 - [25: The Restless Ghost] +RSInterface 274 - [26: Romeo & Juliet] +RSInterface 274 - [27: Rune Mysteries] +RSInterface 274 - [28: Sheep Shearer] +RSInterface 274 - [29: Shield of Arrav] +RSInterface 274 - [30: Vampire Slayer] +RSInterface 274 - [31: Witch's Potion] +RSInterface 274 - [32: Members' Quests] +RSInterface 274 - [33: Animal Magnetism] +RSInterface 274 - [34: Between a Rock...] +RSInterface 274 - [35: Big Chompy Bird Hunting] +RSInterface 274 - [36: Biohazard] +RSInterface 274 - [37: Cabin Fever] +RSInterface 274 - [38: Clock Tower] +RSInterface 274 - [39: Contact!] +RSInterface 274 - [40: Zogre Flesh Eaters] +RSInterface 274 - [41: Creature of Fenkenstrain] +RSInterface 274 - [42: Darkness of Hallowvale] +RSInterface 274 - [43: Death to the Dorgeshuun] +RSInterface 274 - [44: Death Plateau] +RSInterface 274 - [45: Desert Treasure] +RSInterface 274 - [46: Devious Minds] +RSInterface 274 - [47: The Dig Site] +RSInterface 274 - [48: Druidic Ritual] +RSInterface 274 - [49: Dwarf Cannon] +RSInterface 274 - [50: Eadgar's Ruse] +RSInterface 274 - [51: Eagles' Peak] +RSInterface 274 - [52: Elemental Workshop I] +RSInterface 274 - [53: Elemental Workshop II] +RSInterface 274 - [54: Enakhra's Lament] +RSInterface 274 - [55: Enlightened Journey] +RSInterface 274 - [56: The Eyes of Glouphrie] +RSInterface 274 - [57: Fairytale I - Growing Pains] +RSInterface 274 - [58: Fairytale II - Cure a Queen] +RSInterface 274 - [59: Family Crest] +RSInterface 274 - [60: The Feud] +RSInterface 274 - [61: Fight Arena] +RSInterface 274 - [62: Fishing Contest] +RSInterface 274 - [63: Forgettable Tale...] +RSInterface 274 - [64: The Fremennik Trials] +RSInterface 274 - [65: Waterfall Quest] +RSInterface 274 - [66: Garden of Tranquillity] +RSInterface 274 - [67: Gertrude's Cat] +RSInterface 274 - [68: Ghosts Ahoy] +RSInterface 274 - [69: The Giant Dwarf] +RSInterface 274 - [70: The Golem] +RSInterface 274 - [71: The Grand Tree] +RSInterface 274 - [72: The Hand in the Sand] +RSInterface 274 - [73: Haunted Mine] +RSInterface 274 - [74: Hazeel Cult] +RSInterface 274 - [75: Heroes' Quest] +RSInterface 274 - [76: Holy Grail] +RSInterface 274 - [77: Horror from the Deep] +RSInterface 274 - [78: Icthlarin's Little Helper] +RSInterface 274 - [79: In Aid of the Myreque] +RSInterface 274 - [80: In Search of the Myreque] +RSInterface 274 - [81: Jungle Potion] +RSInterface 274 - [82: Legends' Quest] +RSInterface 274 - [83: Lost City] +RSInterface 274 - [84: The Lost Tribe] +RSInterface 274 - [85: Lunar Diplomacy] +RSInterface 274 - [86: Making History] +RSInterface 274 - [87: Merlin's Crystal] +RSInterface 274 - [88: Monkey Madness] +RSInterface 274 - [89: Monk's Friend] +RSInterface 274 - [90: Mountain Daughter] +RSInterface 274 - [91: Mourning's Ends Part I] +RSInterface 274 - [92: Mourning's Ends Part II] +RSInterface 274 - [93: Murder Mystery] +RSInterface 274 - [94: My Arm's Big Adventure] +RSInterface 274 - [95: Nature Spirit] +RSInterface 274 - [96: Observatory Quest] +RSInterface 274 - [97: One Small Favour] +RSInterface 274 - [98: Plague City] +RSInterface 274 - [99: Priest in Peril] +RSInterface 274 - [100: Rag and Bone Man] +RSInterface 274 - [101: Ratcatchers] +RSInterface 274 - [102: Recipe for Disaster] +RSInterface 274 - [103: Recruitment Drive] +RSInterface 274 - [104: Regicide] +RSInterface 274 - [105: Roving Elves] +RSInterface 274 - [106: Royal Trouble] +RSInterface 274 - [107: Rum Deal] +RSInterface 274 - [108: Scorpion Catcher] +RSInterface 274 - [109: Sea Slug] +RSInterface 274 - [110: The Slug Menace] +RSInterface 274 - [111: Shades of Mort'ton] +RSInterface 274 - [112: Shadow of the Storm] +RSInterface 274 - [113: Sheep Herder] +RSInterface 274 - [114: Shilo Village] +RSInterface 274 - [115: A Soul's Bane] +RSInterface 274 - [116: Spirits of the Elid] +RSInterface 274 - [117: Swan Song] +RSInterface 274 - [118: Tai Bwo Wannai Trio] +RSInterface 274 - [119: A Tail of Two Cats] +RSInterface 274 - [120: Tears of Guthix] +RSInterface 274 - [121: Temple of Ikov] +RSInterface 274 - [122: Throne of Miscellania] +RSInterface 274 - [123: The Tourist Trap] +RSInterface 274 - [124: Witch's House] +RSInterface 274 - [125: Tree Gnome Village] +RSInterface 274 - [126: Tribal Totem] +RSInterface 274 - [127: Troll Romance] +RSInterface 274 - [128: Troll Stronghold] +RSInterface 274 - [129: Underground Pass] +RSInterface 274 - [130: Wanted!] +RSInterface 274 - [131: Watchtower] +RSInterface 274 - [132: Cold War] +RSInterface 274 - [133: The Fremennik Isles] +RSInterface 274 - [134: Tower of Life] +RSInterface 274 - [135: The Great Brain Robbery] +RSInterface 274 - [136: What Lies Below] +RSInterface 274 - [137: Olaf's Quest] +RSInterface 274 - [138: Another Slice of H.A.M.] +RSInterface 274 - [139: Dream Mentor] +RSInterface 274 - [140: Grim Tales] +RSInterface 274 - [141: King's Ransom] +RSInterface 274 - [142: The Path of Glouphrie] +RSInterface 274 - [143: Back to my Roots] +RSInterface 274 - [144: Land of the Goblins] +RSInterface 274 - [145: Dealing with Scabaras] +RSInterface 274 - [146: Wolf Whistle] +RSInterface 274 - [147: As a First Resort...] +RSInterface 274 - [148: Catapult Construction] +RSInterface 274 - [149: Kennith's Concerns] +RSInterface 274 - [150: Legacy of Seergaze] +RSInterface 274 - [151: Perils of Ice Mountain] +RSInterface 275 - [2: ifquestname] +RSInterface 275 - [4: qj1] +RSInterface 275 - [5: qj2] +RSInterface 275 - [6: qj3] +RSInterface 275 - [7: qj4] +RSInterface 275 - [8: qj5] +RSInterface 275 - [9: qj6] +RSInterface 275 - [10: qj7] +RSInterface 275 - [11: qj8] +RSInterface 275 - [12: qj9] +RSInterface 275 - [13: qj10] +RSInterface 275 - [14: qj11] +RSInterface 275 - [15: qj12] +RSInterface 275 - [16: qj13] +RSInterface 275 - [17: qj14] +RSInterface 275 - [18: qj15] +RSInterface 275 - [19: qj16] +RSInterface 275 - [20: qj17] +RSInterface 275 - [21: qj18] +RSInterface 275 - [22: qj19] +RSInterface 275 - [23: qj20] +RSInterface 275 - [24: qj21] +RSInterface 275 - [25: qj22] +RSInterface 275 - [26: qj23] +RSInterface 275 - [27: qj24] +RSInterface 275 - [28: qj25] +RSInterface 275 - [29: qj26] +RSInterface 275 - [30: qj27] +RSInterface 275 - [31: qj28] +RSInterface 275 - [32: qj29] +RSInterface 275 - [33: qj30] +RSInterface 275 - [34: qj31] +RSInterface 275 - [35: qj32] +RSInterface 275 - [36: qj33] +RSInterface 275 - [37: qj34] +RSInterface 275 - [38: qj35] +RSInterface 275 - [39: qj36] +RSInterface 275 - [40: qj37] +RSInterface 275 - [41: qj38] +RSInterface 275 - [42: qj39] +RSInterface 275 - [43: qj40] +RSInterface 275 - [44: qj41] +RSInterface 275 - [45: qj42] +RSInterface 275 - [46: qj43] +RSInterface 275 - [47: qj44] +RSInterface 275 - [48: qj45] +RSInterface 275 - [49: qj46] +RSInterface 275 - [50: qj47] +RSInterface 275 - [51: qj48] +RSInterface 275 - [52: qj49] +RSInterface 275 - [53: qj50] +RSInterface 275 - [54: qj51] +RSInterface 275 - [55: qj52] +RSInterface 275 - [56: qj53] +RSInterface 275 - [57: qj54] +RSInterface 275 - [58: qj55] +RSInterface 275 - [59: qj56] +RSInterface 275 - [60: qj57] +RSInterface 275 - [61: qj58] +RSInterface 275 - [62: qj59] +RSInterface 275 - [63: qj60] +RSInterface 275 - [64: qj61] +RSInterface 275 - [65: qj62] +RSInterface 275 - [66: qj63] +RSInterface 275 - [67: qj64] +RSInterface 275 - [68: qj65] +RSInterface 275 - [69: qj66] +RSInterface 275 - [70: qj67] +RSInterface 275 - [71: qj68] +RSInterface 275 - [72: qj69] +RSInterface 275 - [73: qj70] +RSInterface 275 - [74: qj71] +RSInterface 275 - [75: qj72] +RSInterface 275 - [76: qj73] +RSInterface 275 - [77: qj74] +RSInterface 275 - [78: qj75] +RSInterface 275 - [79: qj76] +RSInterface 275 - [80: qj77] +RSInterface 275 - [81: qj78] +RSInterface 275 - [82: qj79] +RSInterface 275 - [83: qj80] +RSInterface 275 - [84: qj81] +RSInterface 275 - [85: qj82] +RSInterface 275 - [86: qj83] +RSInterface 275 - [87: qj84] +RSInterface 275 - [88: qj85] +RSInterface 275 - [89: qj86] +RSInterface 275 - [90: qj87] +RSInterface 275 - [91: qj88] +RSInterface 275 - [92: qj89] +RSInterface 275 - [93: qj90] +RSInterface 275 - [94: qj91] +RSInterface 275 - [95: qj92] +RSInterface 275 - [96: qj93] +RSInterface 275 - [97: qj94] +RSInterface 275 - [98: qj95] +RSInterface 275 - [99: qj96] +RSInterface 275 - [100: qj97] +RSInterface 275 - [101: qj98] +RSInterface 275 - [102: qj99] +RSInterface 275 - [103: qj100] +RSInterface 275 - [104: qj101] +RSInterface 275 - [105: qj102] +RSInterface 275 - [106: qj103] +RSInterface 275 - [107: qj104] +RSInterface 275 - [108: qj105] +RSInterface 275 - [109: qj106] +RSInterface 275 - [110: qj107] +RSInterface 275 - [111: qj108] +RSInterface 275 - [112: qj109] +RSInterface 275 - [113: qj110] +RSInterface 275 - [114: qj111] +RSInterface 275 - [115: qj112] +RSInterface 275 - [116: qj113] +RSInterface 275 - [117: qj114] +RSInterface 275 - [118: qj115] +RSInterface 275 - [119: qj116] +RSInterface 275 - [120: qj117] +RSInterface 275 - [121: qj118] +RSInterface 275 - [122: qj119] +RSInterface 275 - [123: qj120] +RSInterface 275 - [124: qj121] +RSInterface 275 - [125: qj122] +RSInterface 275 - [126: qj123] +RSInterface 275 - [127: qj124] +RSInterface 275 - [128: qj125] +RSInterface 275 - [129: qj126] +RSInterface 275 - [130: qj127] +RSInterface 275 - [131: qj128] +RSInterface 275 - [132: qj129] +RSInterface 275 - [133: qj130] +RSInterface 275 - [134: qj131] +RSInterface 275 - [135: qj132] +RSInterface 275 - [136: qj133] +RSInterface 275 - [137: qj134] +RSInterface 275 - [138: qj135] +RSInterface 275 - [139: qj136] +RSInterface 275 - [140: qj137] +RSInterface 275 - [141: qj138] +RSInterface 275 - [142: qj139] +RSInterface 275 - [143: qj140] +RSInterface 275 - [144: qj141] +RSInterface 275 - [145: qj142] +RSInterface 275 - [146: qj143] +RSInterface 275 - [147: qj144] +RSInterface 275 - [148: qj145] +RSInterface 275 - [149: qj146] +RSInterface 275 - [150: qj147] +RSInterface 275 - [151: qj148] +RSInterface 275 - [152: qj149] +RSInterface 275 - [153: qj150] +RSInterface 275 - [154: qj151] +RSInterface 275 - [155: qj152] +RSInterface 275 - [156: qj153] +RSInterface 275 - [157: qj154] +RSInterface 275 - [158: qj155] +RSInterface 275 - [159: qj156] +RSInterface 275 - [160: qj157] +RSInterface 275 - [161: qj158] +RSInterface 275 - [162: qj159] +RSInterface 275 - [163: qj160] +RSInterface 275 - [164: qj161] +RSInterface 275 - [165: qj162] +RSInterface 275 - [166: qj163] +RSInterface 275 - [167: qj164] +RSInterface 275 - [168: qj165] +RSInterface 275 - [169: qj166] +RSInterface 275 - [170: qj167] +RSInterface 275 - [171: qj168] +RSInterface 275 - [172: qj169] +RSInterface 275 - [173: qj170] +RSInterface 275 - [177: qj171] +RSInterface 275 - [178: qj172] +RSInterface 275 - [179: qj173] +RSInterface 275 - [180: qj174] +RSInterface 275 - [181: qj175] +RSInterface 275 - [182: qj176] +RSInterface 275 - [183: qj177] +RSInterface 275 - [184: qj178] +RSInterface 275 - [185: qj179] +RSInterface 275 - [186: qj180] +RSInterface 275 - [187: qj181] +RSInterface 275 - [188: qj182] +RSInterface 275 - [189: qj183] +RSInterface 275 - [190: qj184] +RSInterface 275 - [191: qj185] +RSInterface 275 - [192: qj186] +RSInterface 275 - [193: qj187] +RSInterface 275 - [194: qj188] +RSInterface 275 - [195: qj189] +RSInterface 275 - [196: qj190] +RSInterface 275 - [197: qj191] +RSInterface 275 - [198: qj192] +RSInterface 275 - [199: qj193] +RSInterface 275 - [200: qj194] +RSInterface 275 - [201: qj195] +RSInterface 275 - [202: qj196] +RSInterface 275 - [203: qj197] +RSInterface 275 - [204: qj198] +RSInterface 275 - [205: qj199] +RSInterface 275 - [206: qj200] +RSInterface 275 - [207: qj201] +RSInterface 275 - [208: qj202] +RSInterface 275 - [209: qj203] +RSInterface 275 - [210: qj204] +RSInterface 275 - [211: qj205] +RSInterface 275 - [212: qj206] +RSInterface 275 - [213: qj207] +RSInterface 275 - [214: qj208] +RSInterface 275 - [215: qj209] +RSInterface 275 - [216: qj210] +RSInterface 275 - [217: qj211] +RSInterface 275 - [218: qj212] +RSInterface 275 - [219: qj213] +RSInterface 275 - [220: qj214] +RSInterface 275 - [221: qj215] +RSInterface 275 - [222: qj216] +RSInterface 275 - [223: qj217] +RSInterface 275 - [224: qj218] +RSInterface 275 - [225: qj219] +RSInterface 275 - [226: qj220] +RSInterface 275 - [227: qj221] +RSInterface 275 - [228: qj222] +RSInterface 275 - [229: qj223] +RSInterface 275 - [230: qj224] +RSInterface 275 - [231: qj225] +RSInterface 275 - [232: qj226] +RSInterface 275 - [233: qj227] +RSInterface 275 - [234: qj228] +RSInterface 275 - [235: qj229] +RSInterface 275 - [236: qj230] +RSInterface 275 - [237: qj231] +RSInterface 275 - [238: qj232] +RSInterface 275 - [239: qj233] +RSInterface 275 - [240: qj234] +RSInterface 275 - [241: qj235] +RSInterface 275 - [242: qj236] +RSInterface 275 - [243: qj237] +RSInterface 275 - [244: qj238] +RSInterface 275 - [245: qj239] +RSInterface 275 - [246: qj240] +RSInterface 275 - [247: qj241] +RSInterface 275 - [248: qj242] +RSInterface 275 - [249: qj243] +RSInterface 275 - [250: qj244] +RSInterface 275 - [251: qj215] +RSInterface 275 - [252: qj246] +RSInterface 275 - [253: qj247] +RSInterface 275 - [254: qj248] +RSInterface 275 - [255: qj249] +RSInterface 276 - [1: Congratulations!] +RSInterface 276 - [4: Total Points:] +RSInterface 276 - [5: %1] +RSInterface 276 - [7: You are awarded] +RSInterface 276 - [8: 0] +RSInterface 276 - [9: Quest points.] +RSInterface 277 - [1: Congratulations!] +RSInterface 277 - [2: You have completed Death Plateau!] +RSInterface 277 - [4: Quest Points:] +RSInterface 277 - [5: %1] +RSInterface 277 - [7: You are awarded:] +RSInterface 277 - [8: Line 1] +RSInterface 277 - [9: Line 2] +RSInterface 277 - [10: Line 3 ] +RSInterface 277 - [11: Line 4] +RSInterface 277 - [12: Line 5] +RSInterface 277 - [13: Line 6] +RSInterface 277 - [14: Line 7] +RSInterface 278 - [88: Ranging Guild Ticket Exchange] +RSInterface 279 - [8: Player's Cat] +RSInterface 279 - [9: Opponent's Cat] +RSInterface 279 - [10: Vs] +RSInterface 279 - [11: ACCEPT] +RSInterface 279 - [12: DECLINE] +RSInterface 279 - [13: Amount] +RSInterface 279 - [14: Amount] +RSInterface 279 - [15: 0] +RSInterface 279 - [16: 0] +RSInterface 279 - [23: Your Limit:] +RSInterface 279 - [24: Their Limit:] +RSInterface 279 - [25: 1000] +RSInterface 280 - [3: YES] +RSInterface 280 - [4: NO] +RSInterface 281 - [0: Text] +RSInterface 281 - [1: Text] +RSInterface 281 - [4: 10] +RSInterface 281 - [5: 10] +RSInterface 281 - [9: Your cat has been] +RSInterface 282 - [10: Page 1 of 8] +RSInterface 282 - [20: PLAY] +RSInterface 285 - [43: A] +RSInterface 285 - [44: A] +RSInterface 285 - [45: A] +RSInterface 285 - [46: A] +RSInterface 285 - [55: Combination Lock Door] +RSInterface 285 - [57: E N T E R] +RSInterface 286 - [88: Fractional still] +RSInterface 286 - [90: Heat] +RSInterface 286 - [92: Pressure] +RSInterface 286 - [120: Add Coal] +RSInterface 286 - [157: Tar regulator] +RSInterface 286 - [158: Pressure valve] +RSInterface 286 - [160: Total distilled] +RSInterface 288 - [9: open casket] +RSInterface 289 - [41: open casket] +RSInterface 294 - [4: Rum] +RSInterface 295 - [1: Rum] +RSInterface 297 - [8: Choose your refreshment from the sandwich tray] +RSInterface 297 - [12: Key] +RSInterface 297 - [23: Meat Pie] +RSInterface 297 - [24: Kebab] +RSInterface 297 - [25: Chocolate Bar] +RSInterface 297 - [26: Baguette] +RSInterface 297 - [27: Triangle Sandwich] +RSInterface 297 - [28: Square Sandwich] +RSInterface 297 - [29: back] +RSInterface 297 - [30: Roll] +RSInterface 298 - [43: A] +RSInterface 298 - [44: A] +RSInterface 298 - [45: A] +RSInterface 298 - [46: A] +RSInterface 298 - [55: Combination Lock Door] +RSInterface 298 - [57: E N T E R] +RSInterface 299 - [2: Ape] +RSInterface 299 - [3: Asgarnia] +RSInterface 299 - [4: Karamja] +RSInterface 299 - [5: Crandor] +RSInterface 299 - [6: Entrana] +RSInterface 299 - [7: Port] +RSInterface 299 - [8: Sarim] +RSInterface 299 - [13: Port] +RSInterface 299 - [14: Khazard] +RSInterface 299 - [15: Ship] +RSInterface 299 - [16: Yard] +RSInterface 299 - [19: Cairn] +RSInterface 299 - [20: Isle] +RSInterface 299 - [22: Brimhaven] +RSInterface 299 - [23: Ardougne] +RSInterface 299 - [25: You Journey on the ship....] +RSInterface 299 - [44: Atoll] +RSInterface 299 - [47: Feldip] +RSInterface 299 - [48: Hills] +RSInterface 299 - [49: The ogres follow the scent of the chompy.... ] +RSInterface 299 - [50: The ogres travel back with the goods] +RSInterface 300 - [15: Smithing] +RSInterface 300 - [20: Dagger] +RSInterface 300 - [21: 1 Bar] +RSInterface 300 - [28: Axe] +RSInterface 300 - [29: 1 Bar] +RSInterface 300 - [36: Mace] +RSInterface 300 - [37: 1 Bar] +RSInterface 300 - [44: Medium helm] +RSInterface 300 - [45: 1 Bar] +RSInterface 300 - [52: Crossbow bolts] +RSInterface 300 - [53: 1 Bar] +RSInterface 300 - [60: Sword] +RSInterface 300 - [61: 1 Bar] +RSInterface 300 - [68: Dart tips] +RSInterface 300 - [69: 1 Bar] +RSInterface 300 - [76: Nails] +RSInterface 300 - [77: 1 Bar] +RSInterface 300 - [84: Bronze wire] +RSInterface 300 - [85: 1 Bar] +RSInterface 300 - [92: Spit iron] +RSInterface 300 - [93: 1 Bar] +RSInterface 300 - [100: Studs] +RSInterface 300 - [101: 1 Bar] +RSInterface 300 - [108: Arrow tips] +RSInterface 300 - [109: 1 Bar] +RSInterface 300 - [116: Scimitar] +RSInterface 300 - [117: 2 Bars] +RSInterface 300 - [124: Crossbow limbs] +RSInterface 300 - [125: 1 Bar] +RSInterface 300 - [132: Longsword] +RSInterface 300 - [133: 2 Bars] +RSInterface 300 - [140: Throwing knife] +RSInterface 300 - [141: 1 Bar] +RSInterface 300 - [148: Full helm] +RSInterface 300 - [149: 2 Bars] +RSInterface 300 - [156: Square shield] +RSInterface 300 - [157: 2 Bars] +RSInterface 300 - [164: Bullseye lantern] +RSInterface 300 - [165: 1 Bar] +RSInterface 300 - [172: Grapple tip] +RSInterface 300 - [173: 1 Bar] +RSInterface 300 - [180: Warhammer] +RSInterface 300 - [181: 3 Bars] +RSInterface 300 - [188: Battleaxe] +RSInterface 300 - [189: 3 Bars] +RSInterface 300 - [196: Chainbody] +RSInterface 300 - [197: 3 Bars] +RSInterface 300 - [204: Kiteshield] +RSInterface 300 - [205: 3 Bars] +RSInterface 300 - [212: Claws] +RSInterface 300 - [213: 2 Bars] +RSInterface 300 - [220: 2-h sword] +RSInterface 300 - [221: 3 Bars] +RSInterface 300 - [228: Plateskirt] +RSInterface 300 - [229: 3 Bars] +RSInterface 300 - [236: Platelegs] +RSInterface 300 - [237: 3 Bars] +RSInterface 300 - [244: Platebody] +RSInterface 300 - [245: 5 Bars] +RSInterface 300 - [253: Crossbow bolts] +RSInterface 300 - [254: 1 Bar] +RSInterface 300 - [261: Crossbow limbs] +RSInterface 300 - [262: 1 Bar] +RSInterface 300 - [269: Pickaxe] +RSInterface 300 - [270: 2 Bars] +RSInterface 301 - [10: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX] +RSInterface 301 - [70: Runecrafting XP] +RSInterface 301 - [71: XP] +RSInterface 301 - [72: Crafting XP] +RSInterface 301 - [73: XP] +RSInterface 301 - [74: Fletching XP] +RSInterface 301 - [75: XP] +RSInterface 301 - [76: Construction XP] +RSInterface 301 - [77: XP] +RSInterface 301 - [78: Farming XP] +RSInterface 301 - [79: XP] +RSInterface 301 - [80: Magic XP] +RSInterface 301 - [81: XP ] +RSInterface 301 - [82: Smithing XP] +RSInterface 301 - [83: XP ] +RSInterface 301 - [84: Cooking XP] +RSInterface 301 - [85: XP ] +RSInterface 301 - [86: Herblore XP] +RSInterface 301 - [87: XP ] +RSInterface 301 - [98: Total XP earned] +RSInterface 301 - [99: XP ] +RSInterface 310 - [6: Cancel] +RSInterface 311 - [2: What would you like to smelt?] +RSInterface 311 - [16:



Bronze] +RSInterface 311 - [20:



Blurite] +RSInterface 311 - [24:



Iron] +RSInterface 311 - [28:



Silver] +RSInterface 311 - [32:



Steel] +RSInterface 311 - [36:



Gold] +RSInterface 311 - [40:



Mithril] +RSInterface 311 - [44:



Adamant] +RSInterface 312 - [1: This sneaky gublinch wanted to set up a webcam conversation with a player! The player refused and sensibly used the Report Abuse button to enable us to catch him.] +RSInterface 319 - [16: Cancel] +RSInterface 323 - [3: Tai Bwo Wannai Parcel Service] +RSInterface 324 - [88: What hides would you like tanning?] +RSInterface 324 - [108: Hide] +RSInterface 324 - [109: Hide] +RSInterface 324 - [110: Hide] +RSInterface 324 - [111: Hide] +RSInterface 324 - [112: Hide] +RSInterface 324 - [113: Hide] +RSInterface 324 - [114: Hide] +RSInterface 324 - [115: Hide] +RSInterface 324 - [116: Cost] +RSInterface 324 - [117: Cost] +RSInterface 324 - [118: Cost] +RSInterface 324 - [119: Cost] +RSInterface 324 - [120: Cost] +RSInterface 324 - [121: Cost] +RSInterface 324 - [122: Cost] +RSInterface 324 - [123: Cost] +RSInterface 325 - [93: Target View] +RSInterface 325 - [105: Shots] +RSInterface 325 - [106: Score:] +RSInterface 325 - [107: %1] +RSInterface 325 - [108: Left:] +RSInterface 325 - [109: 10] +RSInterface 325 - [110: 20] +RSInterface 325 - [111: 30] +RSInterface 325 - [112: 50] +RSInterface 325 - [114: 100] +RSInterface 326 - [88: Teleport Option] +RSInterface 326 - [89: %1] +RSInterface 326 - [90: ...wants to teleport you to...] +RSInterface 326 - [91: %2] +RSInterface 326 - [92: Do you accept?] +RSInterface 326 - [98: Accept] +RSInterface 326 - [100: Decline] +RSInterface 327 - [13: Warning!] +RSInterface 327 - [14: This area is so cold that you will experience
a constant, slow drain of your stats while
you remain within it.] +RSInterface 327 - [17: Don't show me this again] +RSInterface 328 - [0: Repair State :] +RSInterface 328 - [1: %1%] +RSInterface 328 - [2: Resources :] +RSInterface 328 - [3: %1%] +RSInterface 328 - [4: Sanctity:] +RSInterface 328 - [5: %1%] +RSInterface 328 - [6: * Temple Repair *] +RSInterface 329 - [5: Burgh DeRott] +RSInterface 329 - [6: Mort'ton] +RSInterface 329 - [7: Canifis] +RSInterface 329 - [8: Mort] +RSInterface 329 - [9: Myre] +RSInterface 329 - [10: Swamp] +RSInterface 329 - [11: The Hollows] +RSInterface 329 - [19: Choose a route] +RSInterface 329 - [21: Route One] +RSInterface 329 - [22: Route One] +RSInterface 329 - [25: Route Two] +RSInterface 329 - [26: Route Two] +RSInterface 329 - [29: Route Three] +RSInterface 329 - [30: Route Three] +RSInterface 329 - [33: Temple] +RSInterface 329 - [59: Slow plod,
can evade
encounters.] +RSInterface 329 - [60: Leisurely walk,
harder to evade
encounters.] +RSInterface 331 - [2: Whatever text you need goes here!] +RSInterface 331 - [3: Combi for lock] +RSInterface 331 - [4: Text] +RSInterface 331 - [5: Text] +RSInterface 331 - [6: Text] +RSInterface 332 - [91: Water Battlestaff] +RSInterface 332 - [92: Air Battlestaff] +RSInterface 332 - [93: Earth Battlestaff] +RSInterface 332 - [94: Fire Battlestaff] +RSInterface 332 - [95: What would you like to enchant?] +RSInterface 332 - [96: Lava Battlestaff] +RSInterface 332 - [97: Mud Battlestaff] +RSInterface 332 - [98: Steam Battlestaff] +RSInterface 334 - [31: You are about to give:] +RSInterface 334 - [32: In return you will receive:] +RSInterface 334 - [33: Are you sure you want to make this trade?] +RSInterface 334 - [34: There is NO WAY to reverse a trade if you change your mind.] +RSInterface 334 - [35: Accept] +RSInterface 334 - [36: Decline] +RSInterface 334 - [37: Item] +RSInterface 334 - [38: Item] +RSInterface 334 - [39: Item] +RSInterface 334 - [40: Item] +RSInterface 334 - [41: Item] +RSInterface 334 - [42: Item] +RSInterface 334 - [44: Trading with:
Unknown] +RSInterface 334 - [45: Trade modified] +RSInterface 335 - [17: Trading With: Unknown] +RSInterface 335 - [19: Accept] +RSInterface 335 - [21: Decline] +RSInterface 335 - [23: Name] +RSInterface 335 - [36: Trader's Offer] +RSInterface 335 - [37: Your Offer] +RSInterface 335 - [38: Waiting for other player] +RSInterface 335 - [40: Trade modified] +RSInterface 335 - [41: Trade modified] +RSInterface 335 - [42: Limit: 3000] +RSInterface 335 - [43: Wealth transfer] +RSInterface 335 - [44: Limit: 3000] +RSInterface 337 - [82: 1S] +RSInterface 339 - [27: 3N] +RSInterface 339 - [28: 2E] +RSInterface 340 - [27: 2N] +RSInterface 340 - [28: 3W] +RSInterface 340 - [29: 3N] +RSInterface 340 - [30: 2W] +RSInterface 340 - [31: 3N] +RSInterface 341 - [112: 8N] +RSInterface 341 - [113: 6W] +RSInterface 345 - [1: The quick brown fox jumped over the ] +RSInterface 345 - [2: The quick brown fox jumped over the ] +RSInterface 345 - [3: The quick brown fox jumped over the ] +RSInterface 345 - [4: The quick brown fox jumped over the ] +RSInterface 345 - [5: The quick brown fox jumped over the ] +RSInterface 345 - [6: The quick brown fox jumped over the ] +RSInterface 345 - [7: The quick brown fox jumped over the ] +RSInterface 345 - [8: The quick brown fox jumped over the ] +RSInterface 346 - [32: 2E] +RSInterface 347 - [21: 1N] +RSInterface 347 - [22: 6E] +RSInterface 347 - [23: 2W] +RSInterface 347 - [24: 6N] +RSInterface 348 - [36: 2W] +RSInterface 348 - [37: 4S] +RSInterface 348 - [38: 3E] +RSInterface 348 - [39: 3S] +RSInterface 349 - [37: 3E] +RSInterface 349 - [38: 3N] +RSInterface 349 - [39: 1E] +RSInterface 349 - [40: 2N] +RSInterface 363 - [3: Hint] +RSInterface 365 - [11: Get Location] +RSInterface 366 - [21: Water:] +RSInterface 366 - [22: Net:] +RSInterface 366 - [23: Catch:] +RSInterface 366 - [24: Time left:] +RSInterface 366 - [26: Okay] +RSInterface 366 - [27: Ripped!] +RSInterface 366 - [28: Nothing] +RSInterface 367 - [76: Trawler Catch] +RSInterface 367 - [77: Dump Items] +RSInterface 367 - [78: Click Dump Items to close the window and discard remaining items.] +RSInterface 368 - [4: Use rope to repair the Trawler's nets.] +RSInterface 368 - [5: Use Swamp Paste to repair leaks in the Ship's hull.] +RSInterface 368 - [6: If all else fails you can always try and bail the water out as well!] +RSInterface 368 - [7: How to play:] +RSInterface 369 - [42: A] +RSInterface 369 - [43: A] +RSInterface 369 - [44: A] +RSInterface 369 - [45: A] +RSInterface 369 - [54: Combination Lock Door] +RSInterface 369 - [56: Enter] +RSInterface 371 - [21: % Done] +RSInterface 371 - [22: Tutorial Island Progress] +RSInterface 372 - [0: Title] +RSInterface 372 - [1: Line1] +RSInterface 372 - [2: Line2] +RSInterface 372 - [3: Line3] +RSInterface 373 - [0: Current Champion: TzHaar-Xil-Huz] +RSInterface 373 - [1: Foes Remaining:] +RSInterface 374 - [5: Stop Viewing] +RSInterface 374 - [11: Centre] +RSInterface 374 - [12: North-West] +RSInterface 374 - [13: North-East] +RSInterface 374 - [14: South-East] +RSInterface 377 - [2: %1 %] +RSInterface 378 - [12: Welcome to RuneScape] +RSInterface 378 - [15: Jagex Staff will NEVER email you. We use the message centre on this website instead.] +RSInterface 378 - [18: CLICK HERE TO PLAY] +RSInterface 378 - [20: To view your messages:
1) Logout and return to the frontpage of this website.
2) Choose 'Read your messages from Jagex'.] +RSInterface 379 - [3: Time] +RSInterface 379 - [4: 4:17] +RSInterface 379 - [5: 300] +RSInterface 379 - [6: XP score] +RSInterface 380 - [1: Level: %1] +RSInterface 382 - [22: WARNING!] +RSInterface 382 - [23: If you go any further you will enter the Wilderness. This is a very dangerous area, haunted by ghosts! The further north you go, the more dangerous it becomes.] +RSInterface 382 - [24: Enter Wilderness] +RSInterface 382 - [25: Don't go] +RSInterface 382 - [26: Don't ask me this again] +RSInterface 383 - [26: Pick a colour] +RSInterface 384 - [1: wom1] +RSInterface 384 - [2: wom2] +RSInterface 384 - [3: wom3] +RSInterface 384 - [4: wom4] +RSInterface 384 - [5: wom5] +RSInterface 384 - [6: wom6] +RSInterface 384 - [7: wom7] +RSInterface 384 - [8: wom8] +RSInterface 384 - [9: wom9] +RSInterface 384 - [10: wom10] +RSInterface 384 - [11: wom11] +RSInterface 384 - [12: wom12] +RSInterface 384 - [13: wom13] +RSInterface 384 - [14: wom14] +RSInterface 384 - [15: wom15] +RSInterface 384 - [16: wom16] +RSInterface 387 - [58: Show Equipment Stats] +RSInterface 388 - [16: Cancel] +RSInterface 389 - [7: To search for an item, start by typing part of its name.
Then, simply select the item you want from the results on display.] +RSInterface 390 - [8: Show riddle] +RSInterface 391 - [1: Kingdom of Miscellania] +RSInterface 391 - [4: Mining] +RSInterface 391 - [10: Herbs] +RSInterface 391 - [25: Coffers:] +RSInterface 391 - [41: Wood] +RSInterface 391 - [60: Fishing] +RSInterface 391 - [80: Idle] +RSInterface 391 - [93: 500,000] +RSInterface 391 - [94: Deposit] +RSInterface 391 - [95: Withdraw] +RSInterface 391 - [100: Help] +RSInterface 391 - [111: Cooked] +RSInterface 391 - [131: Mahogany] +RSInterface 391 - [132: Teak] +RSInterface 391 - [133: Both] +RSInterface 391 - [134: Hardwood] +RSInterface 391 - [142: Farm] +RSInterface 391 - [156: Herbs] +RSInterface 391 - [158: Flax] +RSInterface 392 - [2: Resources Collected] +RSInterface 393 - [0: A] +RSInterface 393 - [1: B] +RSInterface 393 - [2: C] +RSInterface 393 - [3: D] +RSInterface 393 - [4: E] +RSInterface 393 - [5: F] +RSInterface 393 - [6: G] +RSInterface 393 - [7: H] +RSInterface 393 - [8: I] +RSInterface 393 - [9: J] +RSInterface 393 - [10: K] +RSInterface 393 - [11: L] +RSInterface 393 - [12: M] +RSInterface 393 - [13: N] +RSInterface 393 - [14: O] +RSInterface 393 - [15: P] +RSInterface 393 - [16: Q] +RSInterface 393 - [17: R] +RSInterface 393 - [18: S] +RSInterface 393 - [19: T] +RSInterface 393 - [20: U] +RSInterface 393 - [21: V] +RSInterface 393 - [22: W] +RSInterface 393 - [23: X] +RSInterface 393 - [24: Y] +RSInterface 393 - [25: Z] +RSInterface 393 - [27: GUESS] +RSInterface 393 - [29: __________] +RSInterface 393 - [30: Enter up to five letters in any order then click 'guess' again.] +RSInterface 394 - [89: Furniture Creation Menu] +RSInterface 394 - [90: Select a piece of furniture to build.] +RSInterface 394 - [91: Wooden Chair] +RSInterface 394 - [92: 5 Wood] +RSInterface 394 - [93: 2 Oak] +RSInterface 394 - [94: 2 Oak] +RSInterface 394 - [95: 2 Oak] +RSInterface 394 - [96: Wooden Chair] +RSInterface 394 - [97: 5 Wood] +RSInterface 394 - [98: 2 Oak] +RSInterface 394 - [99: 2 Oak] +RSInterface 394 - [100: 2 Oak] +RSInterface 394 - [101: Wooden Chair] +RSInterface 394 - [102: 5 Wood] +RSInterface 394 - [103: 2 Oak] +RSInterface 394 - [104: 2 Oak] +RSInterface 394 - [105: 2 Oak] +RSInterface 394 - [110: Level] +RSInterface 394 - [111: Level] +RSInterface 394 - [112: Level] +RSInterface 395 - [0: Line1] +RSInterface 395 - [1: Line2] +RSInterface 395 - [2: Click here to continue] +RSInterface 396 - [95: Select a piece of furniture to build. ] +RSInterface 396 - [97: Wooden Chair] +RSInterface 396 - [98: 5 Wood] +RSInterface 396 - [99: 2 Oak] +RSInterface 396 - [100: 2 Oak] +RSInterface 396 - [101: 2 Oak] +RSInterface 396 - [102: Wooden Chair] +RSInterface 396 - [103: 5 Wood] +RSInterface 396 - [104: 2 Oak] +RSInterface 396 - [105: 2 Oak] +RSInterface 396 - [106: 2 Oak] +RSInterface 396 - [107: Wooden Chair] +RSInterface 396 - [108: 5 Wood] +RSInterface 396 - [109: 2 Oak] +RSInterface 396 - [110: 2 Oak] +RSInterface 396 - [111: 2 Oak] +RSInterface 396 - [112: Wooden Chair] +RSInterface 396 - [113: 5 Wood] +RSInterface 396 - [114: 2 Oak] +RSInterface 396 - [115: 2 Oak] +RSInterface 396 - [116: 2 Oak] +RSInterface 396 - [117: Wooden Chair] +RSInterface 396 - [118: 5 Wood] +RSInterface 396 - [119: 2 Oak] +RSInterface 396 - [120: 2 Oak] +RSInterface 396 - [121: 2 Oak] +RSInterface 396 - [122: Wooden Chair] +RSInterface 396 - [123: 5 Wood] +RSInterface 396 - [124: 2 Oak] +RSInterface 396 - [125: 2 Oak] +RSInterface 396 - [126: 2 Oak] +RSInterface 396 - [127: Wooden Chair] +RSInterface 396 - [128: 5 Wood] +RSInterface 396 - [129: 2 Oak] +RSInterface 396 - [130: 2 Oak] +RSInterface 396 - [131: 2 Oak] +RSInterface 396 - [140: Level] +RSInterface 396 - [141: Level] +RSInterface 396 - [142: Level] +RSInterface 396 - [143: Level] +RSInterface 396 - [144: Level] +RSInterface 396 - [145: Level] +RSInterface 396 - [146: Level] +RSInterface 397 - [88: Armchairs] +RSInterface 397 - [89: Bookcases] +RSInterface 397 - [90: Beer Barrels] +RSInterface 397 - [91: Kitchen Tables] +RSInterface 397 - [92: Dining Tables] +RSInterface 397 - [93: Dining Benches] +RSInterface 397 - [94: Beds] +RSInterface 397 - [95: Dressers] +RSInterface 397 - [96: Wardrobes] +RSInterface 397 - [97: Clocks] +RSInterface 397 - [98: Cape Racks] +RSInterface 397 - [99: Magic Wardrobes] +RSInterface 397 - [100: Armour cases ] +RSInterface 397 - [101: Treasure trail chests] +RSInterface 397 - [102: Fancy dress boxes ] +RSInterface 397 - [103: Toy boxes ] +RSInterface 397 - [128: Select a piece of furniture to build] +RSInterface 397 - [133: Furniture Creation Menu] +RSInterface 398 - [2: Off] +RSInterface 398 - [7: House Options] +RSInterface 398 - [16: Leave House] +RSInterface 398 - [17: Building Mode] +RSInterface 398 - [18: Expel Guests] +RSInterface 398 - [19: On] +RSInterface 398 - [20: Number Of Rooms: %1] +RSInterface 399 - [1: There's no place like home...] +RSInterface 401 - [3: PLAYER ] +RSInterface 401 - [4: SHOTS] +RSInterface 401 - [5: SCORE] +RSInterface 401 - [6: -] +RSInterface 401 - [7: -] +RSInterface 401 - [8: -] +RSInterface 401 - [9: -] +RSInterface 401 - [10: -] +RSInterface 401 - [11: -] +RSInterface 401 - [12: -] +RSInterface 401 - [13: -] +RSInterface 401 - [14: -] +RSInterface 401 - [15: -] +RSInterface 401 - [16: -] +RSInterface 401 - [17: -] +RSInterface 402 - [67: Room Creation Menu] +RSInterface 402 - [108: Parlour: Lvl 1] +RSInterface 402 - [109: Garden: Lvl 1] +RSInterface 402 - [110: Kitchen: Lvl 5] +RSInterface 402 - [111: Dining room: Lvl 10] +RSInterface 402 - [112: Workshop: Lvl 15] +RSInterface 402 - [113: Bedroom: Lvl 20] +RSInterface 402 - [114: Hall - Skill trophies: Lvl 25] +RSInterface 402 - [115: Games room: Lvl 30] +RSInterface 402 - [116: Combat room: Lvl 32] +RSInterface 402 - [117: Hall - Quest trophies: Lvl 35] +RSInterface 402 - [118: Study: Lvl 40] +RSInterface 402 - [119: Costume room: Lvl 42] +RSInterface 402 - [120: Chapel: Lvl 45] +RSInterface 402 - [121: Portal chamber: Lvl 50] +RSInterface 402 - [122: Formal garden: Lvl 55] +RSInterface 402 - [123: Throne room: Lvl 60] +RSInterface 402 - [124: Oubliette: Lvl 65] +RSInterface 402 - [125: Dungeon - Corridor: Lvl 70] +RSInterface 402 - [126: Dungeon - Junction: Lvl 70] +RSInterface 402 - [127: Dungeon - Stairs: Lvl 70] +RSInterface 402 - [137: Select a room to build] +RSInterface 402 - [138: 1000 coins] +RSInterface 402 - [139: 1000 coins] +RSInterface 402 - [140: 5000 coins] +RSInterface 402 - [141: 5000 coins] +RSInterface 402 - [142: 10000 coins] +RSInterface 402 - [143: 10000 coins] +RSInterface 402 - [144: 15000 coins] +RSInterface 402 - [145: 25000 coins] +RSInterface 402 - [146: 25000 coins] +RSInterface 402 - [147: 25000 coins] +RSInterface 402 - [148: 50000 coins] +RSInterface 402 - [149: 50000 coins] +RSInterface 402 - [150: 50000 coins] +RSInterface 402 - [151: 100000 coins] +RSInterface 402 - [152: 75000 coins] +RSInterface 402 - [153: 150000 coins] +RSInterface 402 - [154: 150000 coins] +RSInterface 402 - [155: 7500 coins] +RSInterface 402 - [156: 7500 coins] +RSInterface 402 - [157: 7500 coins] +RSInterface 402 - [158: Treasure room: Lvl 75] +RSInterface 402 - [159: 250000 coins] +RSInterface 403 - [88: What wood do you want converting to planks?] +RSInterface 403 - [97: Wood
Cost = 100] +RSInterface 403 - [98: Oak
Cost = 250 ] +RSInterface 403 - [99: Teak
Cost = 500] +RSInterface 403 - [100: Mahogany
Cost = 1500] +RSInterface 405 - [2: Message of the week] +RSInterface 406 - [6: Cancel] +RSInterface 407 - [11: Next Departure: 5 min] +RSInterface 407 - [12: Players Ready: 5] +RSInterface 407 - [13: (Need 5 to 25 players)] +RSInterface 407 - [14: Points:pest_points] +RSInterface 408 - [0: %1 Min] +RSInterface 408 - [1: %100] +RSInterface 408 - [11: 0] +RSInterface 408 - [13: 100] +RSInterface 408 - [14: 100] +RSInterface 408 - [15: 100] +RSInterface 408 - [16: 100] +RSInterface 408 - [25: W] +RSInterface 408 - [26: E] +RSInterface 408 - [27: SE] +RSInterface 409 - [6: Choose a tool to use on each of the moving parts.] +RSInterface 410 - [5: Spiky ball. Use stab defence.] +RSInterface 410 - [6: Anvil. Use blunt defence.] +RSInterface 410 - [7: Slashing blades. Use slash defence.] +RSInterface 410 - [8: Magic missile. Use magic defence.] +RSInterface 410 - [9: Catapult Defence Game Key] +RSInterface 411 - [9: Use stab defence] +RSInterface 411 - [10: Use blunt defence] +RSInterface 411 - [11: Use slash defence] +RSInterface 411 - [12: Use magic defence] +RSInterface 412 - [1: Attack Dummy Key] +RSInterface 412 - [9: Accurate] +RSInterface 412 - [10: Slash] +RSInterface 412 - [11: Aggressive] +RSInterface 412 - [12: Controlled] +RSInterface 412 - [13: Crush] +RSInterface 412 - [14: Stab] +RSInterface 412 - [15: Defensive ] +RSInterface 412 - [16:

These are the types
of attack to use on
each of the dummies
that pop up from
the floor.

You will find that you
need more than one
weapon to be
successful.] +RSInterface 414 - [19: Congratulations! Your team won!] +RSInterface 414 - [20: The final score was:] +RSInterface 414 - [21: You were awarded 999 Pieces of Eight!] +RSInterface 414 - [22: 99] +RSInterface 414 - [23: 99] +RSInterface 414 - [24: :] +RSInterface 415 - [4: 0] +RSInterface 415 - [5: 0] +RSInterface 415 - [6: 0] +RSInterface 415 - [44: 0] +RSInterface 415 - [45: 0] +RSInterface 415 - [58: 0] +RSInterface 415 - [59: 0] +RSInterface 415 - [60: 0] +RSInterface 415 - [61: 0] +RSInterface 415 - [62: 0] +RSInterface 415 - [63: 0] +RSInterface 415 - [64: 0] +RSInterface 415 - [65: 0] +RSInterface 415 - [66: Current Score] +RSInterface 416 - [11: Bridge Section] +RSInterface 416 - [14: Pipe Section] +RSInterface 416 - [17: Wooden Planks] +RSInterface 417 - [12: Bamboo pipe] +RSInterface 417 - [13: Bridge section] +RSInterface 417 - [14: Bucket] +RSInterface 417 - [15: Torch] +RSInterface 417 - [16: Lumber patch] +RSInterface 417 - [17: Bowl] +RSInterface 417 - [18: Tinderbox] +RSInterface 417 - [19: Meat] +RSInterface 417 - [20: Knife] +RSInterface 417 - [21: Axe] +RSInterface 417 - [22: 0] +RSInterface 417 - [23: 0] +RSInterface 417 - [24: 0] +RSInterface 418 - [2: 0] +RSInterface 418 - [3: 0] +RSInterface 418 - [4: Next Game In :] +RSInterface 419 - [1: Ahoy, what would ye like to be sewn together matey?] +RSInterface 419 - [18: Blue
Bandana] +RSInterface 419 - [19: Brown
Bandana] +RSInterface 419 - [20: Hat & Patch] +RSInterface 419 - [21: Hook & Claw] +RSInterface 419 - [22: Red
Bandana] +RSInterface 419 - [23: White
Bandana] +RSInterface 419 - [24: Cavalier & Highwayman Mask] +RSInterface 419 - [25: Beret & Mime Mask] +RSInterface 420 - [23: EXAMPLE] +RSInterface 421 - [1: Line1] +RSInterface 421 - [2: Line2] +RSInterface 421 - [3: Line3] +RSInterface 421 - [4: Line4] +RSInterface 421 - [5: Line5] +RSInterface 421 - [6: Line6] +RSInterface 421 - [7: Line7] +RSInterface 421 - [8: Line8] +RSInterface 421 - [9: Line9] +RSInterface 421 - [10: Line10] +RSInterface 421 - [11: Line11] +RSInterface 423 - [1: Certificate of Advanced Healing] +RSInterface 423 - [2: From PoxStead College.] +RSInterface 423 - [3: Signed Dr Foster-MMD, PRD
Head of
Magical Healing.] +RSInterface 425 - [1: COSMIC
RUNEe
ALTAR] +RSInterface 427 - [1: I (insert full name here) do hereby swear fealty ] +RSInterface 427 - [2: and indebtedness to the Fairy Godfather until] +RSInterface 427 - [3: such time as he releases me from my bond.] +RSInterface 427 - [5: Signed] +RSInterface 427 - [7: (insert full name and date here)] +RSInterface 428 - [1: Room %1 of 8
Thieving level required: %2] +RSInterface 429 - [86: Honest
Jimmy] +RSInterface 429 - [87: Bert the
Sandman] +RSInterface 429 - [88: Advisor
Ghrim] +RSInterface 429 - [89: Turael] +RSInterface 429 - [90: Lanthus] +RSInterface 429 - [91: Mazchna] +RSInterface 429 - [92: Duradel] +RSInterface 429 - [93: Vannaka] +RSInterface 429 - [94: Murphy] +RSInterface 429 - [95: Chaeldar] +RSInterface 429 - [96: Cyrisus] +RSInterface 429 - [97: Random] +RSInterface 431 - [2: Pirates'
Cove] +RSInterface 431 - [3: Moonclan
Island] +RSInterface 432 - [13: Enchant Crossbow Bolt] +RSInterface 432 - [15: Magic 4] +RSInterface 432 - [16: Opal] +RSInterface 432 - [19: Jade] +RSInterface 432 - [20: Magic 14] +RSInterface 432 - [23: Pearl] +RSInterface 432 - [24: Magic 24] +RSInterface 432 - [27: Magic 29] +RSInterface 432 - [30: Magic 7] +RSInterface 432 - [33: Magic 27] +RSInterface 432 - [36: Magic 49] +RSInterface 432 - [39: Magic 57] +RSInterface 432 - [42: Magic 68] +RSInterface 432 - [45: Magic 87] +RSInterface 432 - [47: %1/1] +RSInterface 432 - [49: %1/1] +RSInterface 432 - [51: %1/1] +RSInterface 432 - [53: %1/1] +RSInterface 432 - [55: %1/1] +RSInterface 432 - [57: %1/1] +RSInterface 432 - [59: %1/1] +RSInterface 432 - [61: %1/1] +RSInterface 432 - [63: %1/1] +RSInterface 432 - [65: %1/1] +RSInterface 432 - [68: %1/2] +RSInterface 432 - [70: %1/15] +RSInterface 432 - [72: %1/2] +RSInterface 432 - [74: %1/2] +RSInterface 432 - [76: %1/2] +RSInterface 432 - [78: %1/1] +RSInterface 432 - [80: %1/1] +RSInterface 432 - [82: %1/1] +RSInterface 432 - [84: %1/5] +RSInterface 432 - [86: %1/3] +RSInterface 432 - [88: %1/2] +RSInterface 432 - [90: %1/1] +RSInterface 432 - [92: %1/1] +RSInterface 432 - [94: %1/1] +RSInterface 432 - [95: Click on the bolts to enchant a maximum of 10.] +RSInterface 432 - [96: Red Topaz] +RSInterface 432 - [97: Sapphire] +RSInterface 432 - [98: Emerald] +RSInterface 432 - [99: Ruby] +RSInterface 432 - [100: Diamond] +RSInterface 432 - [101: Dragonstone] +RSInterface 432 - [102: Onyx] +RSInterface 432 - [104: %1/10] +RSInterface 433 - [20: %1] +RSInterface 433 - [21: %1] +RSInterface 433 - [22: %1] +RSInterface 433 - [23: %1] +RSInterface 433 - [24: 0] +RSInterface 433 - [25: Text] +RSInterface 433 - [26: Text] +RSInterface 433 - [27: Text] +RSInterface 433 - [28: Text] +RSInterface 433 - [29: Text] +RSInterface 433 - [30: Crossbow Bolt Pouch] +RSInterface 433 - [31: Current Ammo] +RSInterface 434 - [90: Gnome Battas] +RSInterface 434 - [96: %1/4] +RSInterface 434 - [97: %1/1] +RSInterface 434 - [98: %1/1] +RSInterface 434 - [99: %1/1] +RSInterface 434 - [100: Fruit Batta] +RSInterface 434 - [107: %1/1] +RSInterface 434 - [108: %1/1] +RSInterface 434 - [109: %1/1] +RSInterface 434 - [110: %1/1] +RSInterface 434 - [111: Toad Batta] +RSInterface 434 - [117: %1/1] +RSInterface 434 - [118: %1/1] +RSInterface 434 - [119: %1/1] +RSInterface 434 - [120: Worm Batta] +RSInterface 434 - [128: %1/2] +RSInterface 434 - [129: %1/1] +RSInterface 434 - [130: %1/1] +RSInterface 434 - [131: %1/1] +RSInterface 434 - [132: %1/1] +RSInterface 434 - [133: Vegetable Batta] +RSInterface 434 - [138: %1/1] +RSInterface 434 - [139: %1/1] +RSInterface 434 - [140: Cheese And Tomato Batta] +RSInterface 434 - [142: level 25] +RSInterface 434 - [143: level 26] +RSInterface 434 - [144: level 27] +RSInterface 434 - [145: level 29] +RSInterface 434 - [146: level 28] +RSInterface 434 - [147: Fruit Batta] +RSInterface 434 - [148: Toad Batta] +RSInterface 434 - [149: Worm Batta] +RSInterface 434 - [150: Vegetable Batta] +RSInterface 434 - [151: Cheese & tomato Batta] +RSInterface 435 - [90: Gnome Bowls] +RSInterface 435 - [95: %1/4] +RSInterface 435 - [96: %1/2] +RSInterface 435 - [97: %1/1] +RSInterface 435 - [98: Worm Hole] +RSInterface 435 - [104: %1/2] +RSInterface 435 - [105: %1/2] +RSInterface 435 - [106: %1/1] +RSInterface 435 - [107: Vegetable Ball] +RSInterface 435 - [115: %1/4] +RSInterface 435 - [116: %1/2] +RSInterface 435 - [117: %1/2] +RSInterface 435 - [118: %1/1] +RSInterface 435 - [119: %1/1] +RSInterface 435 - [120: Tangled Toads Legs] +RSInterface 435 - [125: %1/4] +RSInterface 435 - [126: %1/1] +RSInterface 435 - [127: Chocolate Bomb] +RSInterface 435 - [129: level 30] +RSInterface 435 - [130: level 35] +RSInterface 435 - [131: level 40] +RSInterface 435 - [132: level 42] +RSInterface 435 - [133: Worm hole] +RSInterface 435 - [134: Vegetable ball] +RSInterface 435 - [135: Tangled Toads Legs] +RSInterface 435 - [136: Chocolate Bomb] +RSInterface 436 - [90: Gnome Cocktails] +RSInterface 436 - [97: %1/2] +RSInterface 436 - [98: %1/1] +RSInterface 436 - [99: %1/1] +RSInterface 436 - [100: %1/1] +RSInterface 436 - [101: %1/1] +RSInterface 436 - [102: Wizard Blizzard] +RSInterface 436 - [107: %1/1] +RSInterface 436 - [108: %1/3] +RSInterface 436 - [109: Short Green Guy] +RSInterface 436 - [115: %1/1] +RSInterface 436 - [116: %1/1] +RSInterface 436 - [117: %1/1] +RSInterface 436 - [118: Fruit Blast] +RSInterface 436 - [124: %1/2] +RSInterface 436 - [125: %1/1] +RSInterface 436 - [126: %1/1] +RSInterface 436 - [127: Pineapple Punch] +RSInterface 436 - [133: %1/1] +RSInterface 436 - [134: %1/1] +RSInterface 436 - [135: %1/1] +RSInterface 436 - [136: Drunk Dragon] +RSInterface 436 - [143: %1/1] +RSInterface 436 - [144: %1/1] +RSInterface 436 - [145: %1/1] +RSInterface 436 - [146: %1/1] +RSInterface 436 - [147: Chocolate Saturday] +RSInterface 436 - [155: %1/1] +RSInterface 436 - [156: %1/1] +RSInterface 436 - [157: %1/1] +RSInterface 436 - [158: %1/1] +RSInterface 436 - [159: Blurberry Special] +RSInterface 436 - [160: %1/2] +RSInterface 436 - [162: level 6] +RSInterface 436 - [163: level 8] +RSInterface 436 - [164: level 18] +RSInterface 436 - [165: level 20] +RSInterface 436 - [166: level 33] +RSInterface 436 - [167: level 37] +RSInterface 436 - [168: level 32] +RSInterface 436 - [169: Wizard Blizzard] +RSInterface 436 - [170: Short Green Guy] +RSInterface 436 - [171: Fruit Blast] +RSInterface 436 - [172: Pineapple Punch] +RSInterface 436 - [173: Drunk Dragon] +RSInterface 436 - [174: Chocolate Saturday] +RSInterface 436 - [175: Blurberry Special] +RSInterface 437 - [90: Gnome Crunchies] +RSInterface 437 - [94: %1/2] +RSInterface 437 - [95: %1/1] +RSInterface 437 - [96: Toad Crunchies] +RSInterface 437 - [101: %1/1] +RSInterface 437 - [102: %1/2] +RSInterface 437 - [103: Spice Crunchies] +RSInterface 437 - [109: %1/1] +RSInterface 437 - [110: %1/2] +RSInterface 437 - [111: %1/1] +RSInterface 437 - [112: Worm Crunchies] +RSInterface 437 - [117: %1/2] +RSInterface 437 - [118: %1/1] +RSInterface 437 - [119: Chocolate Chip Crunchies] +RSInterface 437 - [121: level 10] +RSInterface 437 - [122: level 12] +RSInterface 437 - [123: level 14] +RSInterface 437 - [124: level 16] +RSInterface 437 - [125: Toad crunchies] +RSInterface 437 - [126: Spice crunchies] +RSInterface 437 - [127: Worm crunchies] +RSInterface 437 - [128: Choc chip crunchies] +RSInterface 440 - [3: Certificate of Qualification] +RSInterface 440 - [4: Earth Sciences Level 1
This is to certify that] +RSInterface 440 - [5: ] +RSInterface 440 - [6: has passed the Level 1
Earth Sciences exam.] +RSInterface 441 - [3: Certificate of Qualification] +RSInterface 441 - [4: Earth Sciences Level 2
This is to certify that] +RSInterface 441 - [5: ] +RSInterface 441 - [6: has passed the Level 2
Earth Sciences exam.] +RSInterface 444 - [3: Certificate of Qualification] +RSInterface 444 - [4: Earth Sciences Level 3
This is to certify that] +RSInterface 444 - [5: ] +RSInterface 444 - [6: has passed the Level 3
Earth Sciences exam.] +RSInterface 451 - [0: Select an Option] +RSInterface 451 - [1: option1] +RSInterface 451 - [2: option2] +RSInterface 451 - [3: option3] +RSInterface 458 - [0: Select an Option] +RSInterface 458 - [1: option1] +RSInterface 458 - [2: option2] +RSInterface 458 - [3: option3] +RSInterface 461 - [7: Island] +RSInterface 461 - [8: Witchaven] +RSInterface 461 - [9: Fishing Platform] +RSInterface 462 - [18: Piece 1] +RSInterface 462 - [19: Piece 2] +RSInterface 462 - [20: Piece 3] +RSInterface 462 - [21: Show/Select] +RSInterface 465 - [2: Varrock Herald] +RSInterface 465 - [3: Covering all of Misthalin and beyond.] +RSInterface 465 - [4: 1 gp] +RSInterface 465 - [5: Oo'glog Ogresses Open Health Spa!] +RSInterface 468 - [7: Diango Item Return] +RSInterface 469 - [3: Castle] +RSInterface 469 - [4: Wars] +RSInterface 469 - [5: Grand] +RSInterface 469 - [6: Tree] +RSInterface 469 - [7: Varrock] +RSInterface 469 - [8: Entrana] +RSInterface 469 - [9: Taverley] +RSInterface 469 - [10: Crafting] +RSInterface 469 - [11: Guild] +RSInterface 469 - [22: Crafting] +RSInterface 469 - [23: Guild] +RSInterface 469 - [25: Varrock] +RSInterface 469 - [28: Taverley] +RSInterface 469 - [30: Entrana] +RSInterface 469 - [32: Grand] +RSInterface 469 - [33: Tree] +RSInterface 469 - [35: Castle] +RSInterface 469 - [36: Wars] +RSInterface 471 - [5: X] +RSInterface 471 - [6: X] +RSInterface 471 - [7: %1] +RSInterface 471 - [8: %1] +RSInterface 471 - [10: Relax] +RSInterface 471 - [24: Balloon Controls] +RSInterface 471 - [25: Bail ] +RSInterface 471 - [27: Move down.] +RSInterface 471 - [28: Move down more.] +RSInterface 471 - [29: Sandbags left.] +RSInterface 471 - [30: Logs left.] +RSInterface 471 - [31: Move up.] +RSInterface 471 - [32: Move up more.] +RSInterface 471 - [33: We're doomed.] +RSInterface 473 - [0: %1] +RSInterface 473 - [22: S P E C I A L A T T A C K] +RSInterface 473 - [23: Combat Lvl: %1] +RSInterface 473 - [25: Auto Retaliate
(Off)] +RSInterface 473 - [26: Short fuse] +RSInterface 473 - [27: Medium fuse] +RSInterface 473 - [28: Long fuse] +RSInterface 473 - [29: (Short fuse)
(Ranged XP)] +RSInterface 473 - [30: (Medium fuse)
(Ranged XP)] +RSInterface 473 - [31: (Long fuse)
(Ranged XP)
(Defence XP)] +RSInterface 473 - [32: When active your player
will automatically fight
back if attacked] +RSInterface 474 - [0: %1] +RSInterface 474 - [22: S P E C I A L A T T A C K] +RSInterface 474 - [23: Combat Lvl: %1] +RSInterface 474 - [25: Scorch] +RSInterface 474 - [26: Flare] +RSInterface 474 - [27: Blaze] +RSInterface 474 - [28: Auto Retaliate
(Off)] +RSInterface 474 - [29: (Aggressive)
(Slash)
(Strength XP)] +RSInterface 474 - [30: (Accurate)
(Ranged)
(Ranged XP)] +RSInterface 474 - [31: (Defensive)
(Magic)
(Magic XP)] +RSInterface 474 - [32: When active your player
will automatically fight
back if attacked] +RSInterface 475 - [0: %1] +RSInterface 475 - [22: S P E C I A L A T T A C K] +RSInterface 475 - [23: Combat Lvl: %1] +RSInterface 475 - [25: Short fuse] +RSInterface 475 - [26: Medium fuse] +RSInterface 475 - [27: Long fuse] +RSInterface 475 - [28: Auto Retaliate
(Off)] +RSInterface 475 - [29: (Short fuse)
(Ranged XP)] +RSInterface 475 - [30: (Medium fuse)
(Ranged XP)] +RSInterface 475 - [31: (Long fuse)
(Ranged XP)
(Defence XP)] +RSInterface 475 - [32: When active your player
will automatically fight
back if attacked] +RSInterface 476 - [0: %1] +RSInterface 476 - [22: S P E C I A L A T T A C K] +RSInterface 476 - [23: Combat Lvl: %1] +RSInterface 476 - [25: Melee] +RSInterface 476 - [26: Ranged] +RSInterface 476 - [27: Magic] +RSInterface 476 - [28: Auto Retaliate
(Off)] +RSInterface 476 - [29: (Melee)
(Attack XP)] +RSInterface 476 - [30: (Ranged)
(Attack XP)] +RSInterface 476 - [31: (Magic)
(Defence XP)] +RSInterface 476 - [32: When active your player
will automatically fight
back if attacked] +RSInterface 477 - [76: Custom Fur Clothing] +RSInterface 477 - [77: Right-click an item in the shop to have it made for you.] +RSInterface 477 - [91: Larupia] +RSInterface 477 - [92: Graahk] +RSInterface 477 - [93: Kyatt ] +RSInterface 477 - [94: Polar kebbit] +RSInterface 477 - [95: Common kebbit] +RSInterface 477 - [96: Feldip weasel] +RSInterface 477 - [97: Desert devil] +RSInterface 477 - [98: Dark kebbit] +RSInterface 477 - [99: Spotted kebbit] +RSInterface 477 - [100: Dashing kebbit] +RSInterface 478 - [60: Imp Release Negotiation Form] +RSInterface 478 - [62: Select an item or stack of items to deposit.
You can deposit up to 2 items or stacks.] +RSInterface 484 - [1: Attacker :] +RSInterface 484 - [2: Defender :] +RSInterface 484 - [3: Collector :] +RSInterface 484 - [4: Healer :] +RSInterface 484 - [5: ----------------------] +RSInterface 484 - [6: ----------------------] +RSInterface 484 - [7: ----------------------] +RSInterface 484 - [8: ----------------------] +RSInterface 484 - [13: Red] +RSInterface 484 - [14: Green] +RSInterface 484 - [15: Blue] +RSInterface 484 - [16: Controlled/Bronze/Wind] +RSInterface 484 - [17: Accurate/Iron/Water] +RSInterface 484 - [18: Aggressive/Steel/Earth] +RSInterface 484 - [19: Defensive/Mithril/Fire] +RSInterface 484 - [20: Tofu] +RSInterface 484 - [21: Worms] +RSInterface 484 - [22: Crackers] +RSInterface 484 - [23: Poison tofu] +RSInterface 484 - [24: Poison worms] +RSInterface 484 - [25: Poison meat] +RSInterface 484 - [26: Horn of Glory] +RSInterface 485 - [1: Wave 1] +RSInterface 485 - [3: Controlled/] +RSInterface 485 - [4: Bronze/Wind] +RSInterface 485 - [6: Green eggs] +RSInterface 486 - [1: Wave 1] +RSInterface 486 - [3: Red eggs] +RSInterface 486 - [5: Style 1] +RSInterface 487 - [1: Wave 1] +RSInterface 487 - [3: Tofu] +RSInterface 487 - [5: Poison meat] +RSInterface 488 - [1: Wave 1] +RSInterface 488 - [3: Poison tofu] +RSInterface 488 - [5: Tofu] +RSInterface 488 - [7: Defender] +RSInterface 488 - [10: Alex] +RSInterface 488 - [11: HP 50/78] +RSInterface 488 - [18: Tim] +RSInterface 488 - [19: HP 88/88] +RSInterface 488 - [24: Matt] +RSInterface 488 - [25: HP 24/54] +RSInterface 488 - [30: Martin] +RSInterface 488 - [31: HP 61/62] +RSInterface 489 - [0: # Players in room:] +RSInterface 489 - [1: Attackers:] +RSInterface 489 - [2: Defenders:] +RSInterface 489 - [3: Collectors:] +RSInterface 489 - [4: Healers:] +RSInterface 489 - [5: Any:] +RSInterface 489 - [6: 0] +RSInterface 489 - [7: 0] +RSInterface 489 - [8: 0] +RSInterface 489 - [9: 0] +RSInterface 489 - [10: 0] +RSInterface 490 - [2: Player status for:] +RSInterface 490 - [3: Role] +RSInterface 490 - [4: Current honour points] +RSInterface 490 - [5: Attacker] +RSInterface 490 - [6: Healer] +RSInterface 490 - [7: Defender] +RSInterface 490 - [8: Collector] +RSInterface 490 - [9: Points for next level] +RSInterface 490 - [10: 0] +RSInterface 490 - [11: 0] +RSInterface 490 - [12: 0] +RSInterface 490 - [13: 0] +RSInterface 490 - [14: Level] +RSInterface 490 - [15: 0] +RSInterface 490 - [16: 0] +RSInterface 490 - [17: 0] +RSInterface 490 - [18: 0] +RSInterface 490 - [19: null] +RSInterface 490 - [20: 0] +RSInterface 490 - [21: 0] +RSInterface 490 - [22: 0] +RSInterface 490 - [23: 0] +RSInterface 490 - [24: Current wave :] +RSInterface 490 - [25: 0] +RSInterface 490 - [26: Reward next level] +RSInterface 490 - [27: -----------] +RSInterface 490 - [28: -----------] +RSInterface 490 - [29: -----------] +RSInterface 490 - [30: -----------] +RSInterface 491 - [78: Barbarian Assault Reward Shop] +RSInterface 491 - [82: Attacker level up to 2] +RSInterface 491 - [83: 100 Attacker points] +RSInterface 491 - [85: +2 bonus damage] +RSInterface 491 - [91: Collector level up to 2] +RSInterface 491 - [92: 100 Collector points] +RSInterface 491 - [94: Bag stores 4] +RSInterface 491 - [98: Defender level up to 2] +RSInterface 491 - [99: 100 Defender points] +RSInterface 491 - [101: Lure range 5] +RSInterface 491 - [105: Defender level up to 2] +RSInterface 491 - [106: 100 Healer points] +RSInterface 491 - [108: Class 2 healing] +RSInterface 491 - [112: Penance Fighter hat] +RSInterface 491 - [113: 275 points in each role] +RSInterface 491 - [115: Requires Defence 45] +RSInterface 491 - [119: Penance Ranger hat] +RSInterface 491 - [120: 275 points in each role] +RSInterface 491 - [122: Requires Defence 45] +RSInterface 491 - [126: Penance Runner hat] +RSInterface 491 - [127: 275 points in each role] +RSInterface 491 - [129: Requires Defence 45] +RSInterface 491 - [133: Penance Healer hat] +RSInterface 491 - [134: 275 points in each role] +RSInterface 491 - [136: Requires Defence 45] +RSInterface 491 - [140: Penance torso] +RSInterface 491 - [141: 375 points in each role] +RSInterface 491 - [143: Requires Defence 40] +RSInterface 491 - [147: Penance skirt] +RSInterface 491 - [148: 375 points in each role] +RSInterface 491 - [150: Requires Defence 40] +RSInterface 491 - [154: Penance boots] +RSInterface 491 - [155: 100 points in each role] +RSInterface 491 - [157: Requires Defence 40] +RSInterface 491 - [161: Penance gloves] +RSInterface 491 - [162: 150 points in each role] +RSInterface 491 - [164: Requires Defence 40] +RSInterface 491 - [168: Granite body] +RSInterface 491 - [169: 95,000 coins] +RSInterface 491 - [171: Requires Defence 50] +RSInterface 491 - [175: Gamble points - low items] +RSInterface 491 - [176: 200 points (any role)] +RSInterface 491 - [178: Receive a random item] +RSInterface 491 - [182: Gamble points - medium items] +RSInterface 491 - [183: 400 points (any role)] +RSInterface 491 - [185: Receive a random item] +RSInterface 491 - [189: Gamble points - high items] +RSInterface 491 - [190: 500 points (any role)] +RSInterface 491 - [192: Receive a random item] +RSInterface 491 - [210: Select your reward] +RSInterface 491 - [213: Accept] +RSInterface 491 - [215: Attacker Honour Points:] +RSInterface 491 - [216: Defender Honour Points:] +RSInterface 491 - [217: Collector Honour Points:] +RSInterface 491 - [218: Healer Honour Points:] +RSInterface 491 - [219: 999] +RSInterface 491 - [220: 999] +RSInterface 491 - [221: 999] +RSInterface 491 - [222: 999] +RSInterface 491 - [223: Kill Queen] +RSInterface 491 - [224: Kill Queen] +RSInterface 491 - [225: Kill Queen] +RSInterface 491 - [226: Kill Queen] +RSInterface 491 - [227: Kill Queen] +RSInterface 491 - [228: Kill Queen] +RSInterface 491 - [229: Kill Queen] +RSInterface 492 - [2: Player 1 Interface Screen] +RSInterface 492 - [3: Decline] +RSInterface 492 - [5: Accept] +RSInterface 492 - [6: Player 2 selected role:] +RSInterface 492 - [7: Waiting ...] +RSInterface 492 - [8: The team:] +RSInterface 492 - [9: Name] +RSInterface 492 - [10: Role] +RSInterface 492 - [11: 1] +RSInterface 492 - [12: 2] +RSInterface 492 - [13: 3] +RSInterface 492 - [14: 4] +RSInterface 492 - [15: 5] +RSInterface 492 - [16: none set] +RSInterface 492 - [17: none set] +RSInterface 492 - [18: none set] +RSInterface 492 - [19: none set] +RSInterface 492 - [20: none set] +RSInterface 492 - [21: none set] +RSInterface 492 - [22: none set] +RSInterface 492 - [23: none set] +RSInterface 492 - [24: none set] +RSInterface 492 - [25: none set] +RSInterface 492 - [26: Wave] +RSInterface 492 - [27: 0] +RSInterface 492 - [31: Remove?] +RSInterface 492 - [32: 0] +RSInterface 492 - [33: 0] +RSInterface 492 - [34: 0] +RSInterface 492 - [35: 0] +RSInterface 492 - [46: Level in role:] +RSInterface 492 - [47: Waiting ...] +RSInterface 493 - [2: Player 2 Interface Screen] +RSInterface 493 - [3: Decline] +RSInterface 493 - [5: Attacker] +RSInterface 493 - [7: Defender] +RSInterface 493 - [8: Collector] +RSInterface 493 - [11: Healer] +RSInterface 493 - [13: Accept] +RSInterface 493 - [15: None] +RSInterface 493 - [16: Waiting for player 1 to accept...] +RSInterface 493 - [18: The team:] +RSInterface 493 - [19: Name] +RSInterface 493 - [20: Role] +RSInterface 493 - [21: --- Leader ---] +RSInterface 493 - [22: --- Followers ---] +RSInterface 493 - [23: none set] +RSInterface 493 - [24: none set] +RSInterface 493 - [25: none set] +RSInterface 493 - [26: none set] +RSInterface 493 - [27: none set] +RSInterface 493 - [28: none set] +RSInterface 493 - [29: none set] +RSInterface 493 - [30: none set] +RSInterface 493 - [31: none set] +RSInterface 493 - [32: none set] +RSInterface 493 - [33: Wave] +RSInterface 493 - [34: 0] +RSInterface 493 - [35: 0] +RSInterface 493 - [36: 0] +RSInterface 493 - [37: 0] +RSInterface 493 - [38: 0] +RSInterface 493 - [39: Please select a role!
Current Role:] +RSInterface 493 - [52: Name] +RSInterface 493 - [53: Role] +RSInterface 493 - [54: Name] +RSInterface 493 - [55: Role] +RSInterface 493 - [56: Name] +RSInterface 493 - [57: Role] +RSInterface 493 - [58: Name] +RSInterface 494 - [0: XX] +RSInterface 494 - [1: Time until next wave:] +RSInterface 495 - [4: Poison] +RSInterface 495 - [5: Explosive] +RSInterface 495 - [6: Stun] +RSInterface 495 - [11: Poison] +RSInterface 495 - [12: Explosive] +RSInterface 495 - [13: Stun] +RSInterface 495 - [18: Poison] +RSInterface 495 - [19: Explosive] +RSInterface 495 - [20: Stun] +RSInterface 495 - [25: Poison] +RSInterface 495 - [26: Explosive] +RSInterface 495 - [27: Stun] +RSInterface 495 - [30: Omega] +RSInterface 495 - [31: ##] +RSInterface 495 - [32: ##] +RSInterface 495 - [33: ##] +RSInterface 495 - [34: ##] +RSInterface 495 - [35: ##] +RSInterface 495 - [36: ##] +RSInterface 495 - [37: ##] +RSInterface 495 - [38: ##] +RSInterface 495 - [39: ##] +RSInterface 495 - [40: ##] +RSInterface 495 - [41: ##] +RSInterface 495 - [42: ##] +RSInterface 496 - [2: Tutorial Progress] +RSInterface 496 - [3: Introduction to the Arena] +RSInterface 496 - [4: Getting Started] +RSInterface 496 - [5: Playing the Game] +RSInterface 496 - [6: The Attacker Role] +RSInterface 496 - [7: The Defender Role] +RSInterface 496 - [8: The Collector Role] +RSInterface 496 - [9: The Healer Role] +RSInterface 496 - [10: Extra Information] +RSInterface 496 - [11: The Final Battle] +RSInterface 496 - [12: Rewards] +RSInterface 497 - [4: Wave Complete!] +RSInterface 497 - [5: Reward: ] +RSInterface 497 - [6: Runners that got past] +RSInterface 497 - [7: Rangers killed] +RSInterface 497 - [8: Fighters killed] +RSInterface 497 - [9: Healers killed] +RSInterface 497 - [10: Runners killed] +RSInterface 497 - [11: Player hitpoints replenished] +RSInterface 497 - [12: Wrong poison packs used] +RSInterface 497 - [13: Eggs collected (min. exploded)] +RSInterface 497 - [14: Failed Attacker attacks] +RSInterface 497 - [15: 0] +RSInterface 497 - [16: 0] +RSInterface 497 - [17: 0] +RSInterface 497 - [18: 0] +RSInterface 497 - [19: 0] +RSInterface 497 - [20: 0] +RSInterface 497 - [21: 0] +RSInterface 497 - [22: 0] +RSInterface 497 - [23: 0] +RSInterface 497 - [24: Total] +RSInterface 497 - [25: 0] +RSInterface 497 - [26: 0] +RSInterface 497 - [27: 0] +RSInterface 497 - [28: 0] +RSInterface 497 - [29: 0] +RSInterface 497 - [30: 0] +RSInterface 497 - [31: 0] +RSInterface 497 - [32: 0] +RSInterface 497 - [33: 0] +RSInterface 497 - [34: 0] +RSInterface 497 - [35: #] +RSInterface 497 - [36: Team Honour Points] +RSInterface 497 - [37: Role:] +RSInterface 497 - [38: None] +RSInterface 497 - [39: 0] +RSInterface 497 - [40: 0] +RSInterface 497 - [41: 0] +RSInterface 497 - [42: 0] +RSInterface 497 - [43: 0] +RSInterface 497 - [44: 0] +RSInterface 497 - [45: 0] +RSInterface 497 - [46: 0] +RSInterface 497 - [47: 0] +RSInterface 497 - [48: 0] +RSInterface 497 - [49: Honour Points reward :] +RSInterface 497 - [50: 0] +RSInterface 497 - [51: -] +RSInterface 497 - [52: -] +RSInterface 497 - [53: -] +RSInterface 497 - [54: -] +RSInterface 497 - [55: -] +RSInterface 497 - [56: -] +RSInterface 497 - [57: Total Honour Points in role:] +RSInterface 497 - [58: 0] +RSInterface 497 - [59: Individual Honour Points] +RSInterface 497 - [62: The Queen is dead!] +RSInterface 497 - [63: Reward:] +RSInterface 497 - [64: --Points output--] +RSInterface 497 - [65: -Role-] +RSInterface 497 - [66: Simple breakdown] +RSInterface 497 - [67: Honour Points Reward:] +RSInterface 497 - [68: 0] +RSInterface 497 - [69: 0] +RSInterface 497 - [71: Advanced Breakdown] +RSInterface 497 - [72: Total Honour Points in role:] +RSInterface 497 - [77: Level
up] +RSInterface 497 - [80: Level
up] +RSInterface 498 - [1: Kaleef

Your mission is to contact our agent inside Menaphos.
Use the tunnels beneath the temple of lesser gods.
Be vigilant of traps and the hostile natives.
They're about as welcoming as the Menaphites only slightly better looking.

Os] +RSInterface 499 - [6: Skill] +RSInterface 499 - [9: Description] +RSInterface 501 - [15: Cannon barrel] +RSInterface 501 - [18: Fuse] +RSInterface 501 - [21: Ramrod] +RSInterface 501 - [24: Cannonball] +RSInterface 501 - [27: Cannon cannister] +RSInterface 502 - [15: Rope] +RSInterface 502 - [18: Hammer] +RSInterface 502 - [21: Tack] +RSInterface 502 - [24: Plank] +RSInterface 502 - [27: Swamp paste] +RSInterface 503 - [3: Clockwork Toys - A Clockwork Mechanism, Chapter 1.0] +RSInterface 503 - [7: Making a clockwork toy is very simple and a good place to start for new crafters. Simply create a clockwork mechanism on your Crafting table, then use it and a wood plank to make a toy soldier or a doll. Wind them up and watch them go!] +RSInterface 503 - [8: Multi-rotation head for lifelike simulation] +RSInterface 503 - [9: A well-hidden clockwork system] +RSInterface 503 - [11: The clockwork mechanism.] +RSInterface 503 - [13: It would be simple to alter the design by adding a piece of silk to the wooden frame and clockwork mechanism. You could make a suit that could be controlled from the inside.] +RSInterface 505 - [3: Waterbirth
Island] +RSInterface 505 - [4: Miscellania] +RSInterface 505 - [5: Etceteria] +RSInterface 505 - [6: Rellekka] +RSInterface 505 - [7: Neitiznot & Jatizso] +RSInterface 506 - [5: Talk to puppet] +RSInterface 506 - [6: Jester Controls] +RSInterface 506 - [9: Dance] +RSInterface 506 - [12: Juggle] +RSInterface 506 - [15: Skip] +RSInterface 506 - [18: Pie] +RSInterface 506 - [21: Jig] +RSInterface 507 - [0: A] +RSInterface 507 - [1: B] +RSInterface 507 - [2: C] +RSInterface 507 - [3: D] +RSInterface 507 - [4: E] +RSInterface 507 - [5: F] +RSInterface 507 - [6: G] +RSInterface 507 - [7: H] +RSInterface 507 - [8: I] +RSInterface 507 - [9: J] +RSInterface 507 - [10: K] +RSInterface 507 - [11: L] +RSInterface 507 - [12: M] +RSInterface 507 - [13: N] +RSInterface 507 - [14: O] +RSInterface 507 - [15: P] +RSInterface 507 - [16: Q] +RSInterface 507 - [17: R] +RSInterface 507 - [18: S] +RSInterface 507 - [19: T] +RSInterface 507 - [20: U] +RSInterface 507 - [21: V] +RSInterface 507 - [22: W] +RSInterface 507 - [23: X] +RSInterface 507 - [24: Y] +RSInterface 507 - [25: Z] +RSInterface 507 - [26: ?] +RSInterface 507 - [27: ?] +RSInterface 507 - [28: ?] +RSInterface 507 - [29: ?] +RSInterface 507 - [31: GUESS] +RSInterface 507 - [33: __________] +RSInterface 507 - [34: Enter up to five letters in any order then click 'guess' again.] +RSInterface 508 - [7: The World of Magic] +RSInterface 508 - [8: The World of Logic] +RSInterface 509 - [36: Place bar] +RSInterface 509 - [47: Horizontal] +RSInterface 509 - [48: Vertical] +RSInterface 509 - [56: 1] +RSInterface 510 - [151: 1] +RSInterface 510 - [152: 2] +RSInterface 510 - [153: 3] +RSInterface 510 - [154: 4] +RSInterface 510 - [155: Use the valves] +RSInterface 510 - [156: and the levers to] +RSInterface 510 - [157: get the balls in] +RSInterface 510 - [158: the holes, and ] +RSInterface 510 - [159: then increase the] +RSInterface 510 - [160: pressure to fill] +RSInterface 518 - [79: Follower Inv] +RSInterface 518 - [80: %1] +RSInterface 518 - [81: Npc spaces left.] +RSInterface 518 - [82: %1] +RSInterface 518 - [83: %1] +RSInterface 518 - [84: %1] +RSInterface 518 - [87: %1] +RSInterface 518 - [88: %1] +RSInterface 518 - [89: %1] +RSInterface 518 - [90: %1] +RSInterface 518 - [91: %1] +RSInterface 518 - [92: %1] +RSInterface 518 - [93: %1] +RSInterface 518 - [94: %1] +RSInterface 518 - [95: %1] +RSInterface 518 - [96: %1] +RSInterface 518 - [97: %1] +RSInterface 518 - [98: %1] +RSInterface 518 - [99: %1] +RSInterface 518 - [100: %1] +RSInterface 518 - [101: %1] +RSInterface 518 - [102: %1] +RSInterface 518 - [118: Right click on items in your inventory to add them here, then click close.] +RSInterface 521 - [14: Guidance System] +RSInterface 521 - [31: 100%] +RSInterface 521 - [32: Health - ] +RSInterface 521 - [46: 100%] +RSInterface 521 - [47: Spirit - ] +RSInterface 521 - [57: 100%] +RSInterface 521 - [58: Armament - ] +RSInterface 521 - [79: --- Stat ---] +RSInterface 521 - [80: Information...] +RSInterface 522 - [0: Monster name] +RSInterface 522 - [1: Line1] +RSInterface 522 - [2: Line2] +RSInterface 522 - [3: Line3] +RSInterface 522 - [4: Line4] +RSInterface 523 - [1: 00] +RSInterface 523 - [2: 00] +RSInterface 523 - [3: /] +RSInterface 523 - [5: 00] +RSInterface 523 - [6: 00] +RSInterface 523 - [7: /] +RSInterface 523 - [9: 00] +RSInterface 523 - [10: 00] +RSInterface 523 - [11: /] +RSInterface 523 - [13: 00] +RSInterface 523 - [14: 00] +RSInterface 523 - [15: /] +RSInterface 523 - [17: 00] +RSInterface 523 - [18: 00] +RSInterface 523 - [19: /] +RSInterface 523 - [21: 00] +RSInterface 523 - [22: 00] +RSInterface 523 - [23: /] +RSInterface 523 - [25: 00] +RSInterface 523 - [26: 00] +RSInterface 523 - [27: /] +RSInterface 523 - [29: 00] +RSInterface 523 - [30: 00] +RSInterface 523 - [31: /] +RSInterface 523 - [33: 00] +RSInterface 523 - [34: 00] +RSInterface 523 - [35: /] +RSInterface 523 - [37: 00] +RSInterface 523 - [38: 00] +RSInterface 523 - [39: /] +RSInterface 523 - [41: 00] +RSInterface 523 - [42: 00] +RSInterface 523 - [43: /] +RSInterface 523 - [45: 00] +RSInterface 523 - [46: 00] +RSInterface 523 - [47: /] +RSInterface 523 - [49: 00] +RSInterface 523 - [50: 00] +RSInterface 523 - [51: /] +RSInterface 523 - [53: 00] +RSInterface 523 - [54: 00] +RSInterface 523 - [55: /] +RSInterface 523 - [57: 00] +RSInterface 523 - [58: 00] +RSInterface 523 - [59: /] +RSInterface 523 - [61: 00] +RSInterface 523 - [62: 00] +RSInterface 523 - [63: /] +RSInterface 523 - [65: 00] +RSInterface 523 - [66: 00] +RSInterface 523 - [67: /] +RSInterface 523 - [69: 00] +RSInterface 523 - [70: 00] +RSInterface 523 - [71: /] +RSInterface 523 - [73: 00] +RSInterface 523 - [74: 00] +RSInterface 523 - [75: /] +RSInterface 523 - [77: 00] +RSInterface 523 - [78: 00] +RSInterface 523 - [79: /] +RSInterface 523 - [81: 00] +RSInterface 523 - [82: 00] +RSInterface 523 - [83: /] +RSInterface 523 - [85: 00] +RSInterface 523 - [86: 00] +RSInterface 523 - [87: /] +RSInterface 523 - [89: 00] +RSInterface 523 - [90: 00] +RSInterface 523 - [91: /] +RSInterface 523 - [93: 00] +RSInterface 523 - [94: 00] +RSInterface 523 - [95: /] +RSInterface 523 - [98: Player :] +RSInterface 523 - [99: Player ~ Name] +RSInterface 524 - [1: Text] +RSInterface 525 - [2: This is an interface type test.] +RSInterface 526 - [2: This is an interface type test.] +RSInterface 527 - [4: Arrowheads display] +RSInterface 527 - [7: Saranthium coin display] +RSInterface 527 - [10: Senntisten coin display] +RSInterface 527 - [13: Jewellery display] +RSInterface 527 - [16: Pottery display] +RSInterface 527 - [19: Ancient Saradomin symbol display] +RSInterface 527 - [22: Old Saradomin symbol display] +RSInterface 527 - [25: Zaros tablet display] +RSInterface 527 - [28: Ancient talisman display] +RSInterface 527 - [31: Vase display] +RSInterface 527 - [34: Soil layers display] +RSInterface 527 - [35: Stairs to
Natural History
exhibit] +RSInterface 527 - [36: Stairs to
Timeline
exhibit] +RSInterface 527 - [37: Dig Site cleaning area] +RSInterface 527 - [38: Level up] +RSInterface 527 - [65: 1st-2nd Ages] +RSInterface 527 - [67: End of
2nd Age] +RSInterface 527 - [69: 3rd Age
4000 years long] +RSInterface 527 - [71: 3rd Age
yr 3000-4000] +RSInterface 527 - [73: 4th Age
2000 yrs long] +RSInterface 527 - [75: 4th Age
yr 1-200] +RSInterface 527 - [77: 4th Age
yr 500-900] +RSInterface 527 - [79: 4th Age
yr 1-100] +RSInterface 527 - [81: 4th Age
yr 31-60] +RSInterface 527 - [83: 4th Age
yr 1100-1200] +RSInterface 527 - [85: 4th Age
yr 700-800] +RSInterface 527 - [87: 4th Age
yr 1777] +RSInterface 527 - [89: 4th Age
yr 1937] +RSInterface 527 - [91: 5th Age
currently 169 years old] +RSInterface 527 - [93: 5th Age
yr 8] +RSInterface 527 - [95: 5th Age
yr 9] +RSInterface 527 - [97: 5th Age
yr 12] +RSInterface 527 - [99: 5th Age
yr 20] +RSInterface 527 - [101: 5th Age
yr 23] +RSInterface 527 - [103: 5th Age
yr 42-62] +RSInterface 527 - [105: 5th Age
yr 47] +RSInterface 527 - [108: 5th Age
yr 7] +RSInterface 527 - [109: 5th Age
yr 62] +RSInterface 527 - [110: Stairs to
Dig Site
exhibit] +RSInterface 527 - [111: Stairs to
Timeline
exhibit] +RSInterface 527 - [112: Level up] +RSInterface 527 - [113: Level down] +RSInterface 527 - [118: 5th Age
yr 136] +RSInterface 527 - [121: 5th Age
yr 70] +RSInterface 527 - [124: 5th Age
yr 132] +RSInterface 527 - [127: 5th Age
yr 154] +RSInterface 527 - [130: 5th Age
yr 169] +RSInterface 527 - [133: 5th Age
yr 169] +RSInterface 527 - [136: 5th Age
yr 143] +RSInterface 527 - [139: 5th Age
yr 162-163] +RSInterface 527 - [142: 5th Age
yr 20] +RSInterface 527 - [145: 5th Age
yr 98] +RSInterface 527 - [146: Level down] +RSInterface 527 - [147: Stairs to
Timeline
exhibit] +RSInterface 527 - [150: 5th Age
yr 70] +RSInterface 527 - [156: Terrorbird display] +RSInterface 527 - [159: Kalphite Queen
display] +RSInterface 527 - [162: Mole
display] +RSInterface 527 - [165: Penguin
display] +RSInterface 527 - [168: Camel
display] +RSInterface 527 - [171: Leech
display] +RSInterface 527 - [174: Monkey
display] +RSInterface 527 - [177: Sea slug
display] +RSInterface 527 - [180: Snail
display] +RSInterface 527 - [183: Snake
display] +RSInterface 527 - [186: Lizard
display] +RSInterface 527 - [189: Battle tortoise
display] +RSInterface 527 - [192: Dragon
display] +RSInterface 527 - [195: Wyvern
display] +RSInterface 527 - [197: Level down] +RSInterface 527 - [198: Level up] +RSInterface 528 - [2: Text] +RSInterface 528 - [15: Display number] +RSInterface 529 - [2: This is an interface type test.] +RSInterface 530 - [2: Text] +RSInterface 530 - [4: Text] +RSInterface 530 - [6: This is an interface type test.] +RSInterface 530 - [7: This is an interface type test.] +RSInterface 532 - [0: Museum Kudos:] +RSInterface 533 - [1: Text] +RSInterface 533 - [24: Display number] +RSInterface 533 - [25: 03] +RSInterface 533 - [28: Text] +RSInterface 533 - [29: Text] +RSInterface 533 - [30: Text] +RSInterface 533 - [31: Text] +RSInterface 534 - [2: Text] +RSInterface 534 - [58: Asgarnia] +RSInterface 534 - [59: Misthalin] +RSInterface 534 - [60: Avarrocka] +RSInterface 534 - [61: Ghost Town] +RSInterface 534 - [62: Karamja] +RSInterface 534 - [63: Entrana] +RSInterface 534 - [83: Display number] +RSInterface 536 - [4: Shrink-Me-Quick Recipe] +RSInterface 536 - [5: 1x leaf of tarromin, 1x shrunken ogleroot. Mix the tarromin in a vial of water, then add the shrunken ogleroot. Drink when standing within an area prepared with glyphs for this potion to have full effect. Take one dose only, for a new perspective on the world...] +RSInterface 537 - [14: E] +RSInterface 537 - [15: F] +RSInterface 537 - [16: E] +RSInterface 537 - [17: D] +RSInterface 537 - [18: C] +RSInterface 537 - [19: A] +RSInterface 537 - [20: E] +RSInterface 537 - [21: G] +RSInterface 537 - [22: A] +RSInterface 537 - [24: C] +RSInterface 537 - [25: D] +RSInterface 537 - [26: E] +RSInterface 537 - [27: F] +RSInterface 537 - [28: G] +RSInterface 537 - [29: A] +RSInterface 537 - [30: B] +RSInterface 537 - [31: D] +RSInterface 537 - [32: C] +RSInterface 537 - [33: E] +RSInterface 537 - [34: F] +RSInterface 537 - [35: G] +RSInterface 537 - [36: A] +RSInterface 537 - [37: B] +RSInterface 537 - [38: UPPER] +RSInterface 537 - [39: LOWER] +RSInterface 538 - [4: Things to do:] +RSInterface 538 - [5: Take out the rubbish
Buy a new record for the gramophone
Check shrunken ogleroot supply
Feed ogleroots to my darlings
Wash the bedsheets
Hang out the washing
Practise the piano
Terrorise the little brat with the ball again
Trim hedges in the garden
Floss warts
Plot revenge on Fritz's murderer] +RSInterface 540 - [75: Elnock's Exchange] +RSInterface 540 - [76: Make your selection and press confirm] +RSInterface 540 - [94: x3] +RSInterface 540 - [96: x2] +RSInterface 540 - [98: x1] +RSInterface 540 - [100: x3] +RSInterface 540 - [102: x2] +RSInterface 540 - [104: x1] +RSInterface 540 - [106: x3] +RSInterface 540 - [108: x2] +RSInterface 540 - [110: x1] +RSInterface 540 - [112: x1 of any impling type] +RSInterface 540 - [115: x1] +RSInterface 540 - [118: x1] +RSInterface 540 - [121: x1] +RSInterface 540 - [124: x3] +RSInterface 540 - [128: Text] +RSInterface 540 - [129: Baby impling] +RSInterface 540 - [130: Young impling] +RSInterface 540 - [131: Gourmet impling] +RSInterface 540 - [132: Gourmet impling] +RSInterface 540 - [133: Essence impling] +RSInterface 540 - [134: Essence impling] +RSInterface 540 - [135: Earth impling] +RSInterface 540 - [136: Eclectic impling] +RSInterface 540 - [137: Nature impling] +RSInterface 540 - [138: Imp repellant] +RSInterface 540 - [139: Magic butterfly net] +RSInterface 540 - [140: Jar generator] +RSInterface 541 - [11: %1] +RSInterface 541 - [12: %1] +RSInterface 541 - [13: %1] +RSInterface 541 - [14: %1] +RSInterface 541 - [15: %1] +RSInterface 541 - [16: %1] +RSInterface 541 - [17: %1] +RSInterface 541 - [18: %1] +RSInterface 541 - [19: %1] +RSInterface 541 - [20: %1] +RSInterface 550 - [3: Friends List - RuneScape XXX] +RSInterface 550 - [6: Add Friend] +RSInterface 550 - [7: Del Friend] +RSInterface 551 - [3: Ignore List] +RSInterface 551 - [6: Add Name] +RSInterface 551 - [7: Del Name] +RSInterface 553 - [11: Report abuse] +RSInterface 553 - [12: This form is for reporting players who are breaking our rules.
Using it sends a snapshot of the last 60 secs of activity to us.] +RSInterface 553 - [13: If you misuse this form, you will be banned.] +RSInterface 553 - [14: First please enter the name of the offending player below:] +RSInterface 553 - [15: *] +RSInterface 553 - [16: Moderator option: Mute player for 48 hours: OFF] +RSInterface 553 - [17: Then click below to indicate which of our 13 rules is being broken.
For a detailed explanation of each rule please read the manual on our website.] +RSInterface 553 - [18: 1: Offensive language] +RSInterface 553 - [19: 2: Item scamming] +RSInterface 553 - [20: 3: Password scamming] +RSInterface 553 - [21: 4: Bug abuse] +RSInterface 553 - [22: 5: Jagex staff impersonation] +RSInterface 553 - [23: 6: Account sharing/trading] +RSInterface 553 - [24: 7: Macroing] +RSInterface 553 - [25: 8: Multiple logging in] +RSInterface 553 - [26: 9: Encouraging others to break rules] +RSInterface 553 - [27: 10: Misuse of customer support] +RSInterface 553 - [28: 11: Advertising / website] +RSInterface 553 - [29: 12: Real world item trading] +RSInterface 553 - [30: 13: Asking for personal details] +RSInterface 557 - [0: Select an Option] +RSInterface 557 - [1: option1] +RSInterface 557 - [2: option2] +RSInterface 558 - [28: What would you like to make?] +RSInterface 559 - [72: Text for testing, remove at will. Text for testing, remove at will. Text for testing, remove at will. Text for testing, remove at will. Text for testing, remove at will. Text for testing, remove at will. ] +RSInterface 560 - [13: Warning!] +RSInterface 560 - [14: Warning! Low level players beware. Goblins have taken over and there are poisonous spiders!] +RSInterface 560 - [17: Proceed regardless] +RSInterface 560 - [18: Stay out] +RSInterface 560 - [19: Don't ask me this again] +RSInterface 561 - [13: Warning!] +RSInterface 561 - [14: If you climb down this rope you will be attacked by
the Kalphite Queen, one of the most deadly creatures in RuneScape.] +RSInterface 561 - [17: That's what I came here for] +RSInterface 561 - [18: I think I'll stay out] +RSInterface 561 - [19: Don't ask me this again] +RSInterface 562 - [13: Warning!] +RSInterface 562 - [14: This area is very dark. Do not extinguish your light source!] +RSInterface 562 - [17: Proceed] +RSInterface 562 - [18: Stay out] +RSInterface 562 - [19: Don't ask me this again] +RSInterface 563 - [13: Warning!] +RSInterface 563 - [14: Entering building mode will destroy
any items that are on the ground. Do you want to continue?] +RSInterface 563 - [17: Yes, I do not mind losing any items that are on the ground.] +RSInterface 563 - [18: No, I want to look around and pick things up first.] +RSInterface 563 - [19: Don't ask me this again] +RSInterface 564 - [13: Warning!] +RSInterface 564 - [14: Warning! At the top of this tower you will be attacked
by archers, who will shoot you without mercy!] +RSInterface 564 - [17: I'll be okay - they can't hurt me] +RSInterface 564 - [18: I'll stay down here] +RSInterface 564 - [19: Don't ask me this again] +RSInterface 565 - [13: Warning!] +RSInterface 565 - [14: The desert is a VERY dangerous place. Do not
enter if you are afraid of dying. Beware of high temperatures, sandstorms, robbers and slavers.
No responsibility is taken by Shantay if anything
bad should happen to you, in any circumstances whatsoever.] +RSInterface 565 - [17: Proceed regardless] +RSInterface 565 - [18: Stay out] +RSInterface 565 - [19: Don't ask me this again] +RSInterface 566 - [13: Warning!] +RSInterface 566 - [14: Do you need to collect any dropped
items?] +RSInterface 566 - [17: Yes - I need to collect some stuff
before I leave] +RSInterface 566 - [18: No - I haven't left any valuables on the floor] +RSInterface 566 - [19: Don't ask me this again] +RSInterface 567 - [13: Warning!] +RSInterface 567 - [14: It's very dark in there. Are you sure you want to
go in without a light source?] +RSInterface 567 - [17: Yes I am sure.] +RSInterface 567 - [18: No, I am not properly equipped.] +RSInterface 567 - [19: Don't ask me this again] +RSInterface 568 - [13: Warning!] +RSInterface 568 - [14: This area is very dark. Do not extinquish your light source!] +RSInterface 568 - [17: Proceed regardless] +RSInterface 568 - [18: Stay out] +RSInterface 568 - [19: Don't ask me this again] +RSInterface 569 - [13: Warning!] +RSInterface 569 - [14: It's very dark in there. Are you sure you want to go in without a light source?] +RSInterface 569 - [17: Yes I am sure.] +RSInterface 569 - [18: No, I am not properly equipped..] +RSInterface 569 - [19: Don't ask me this again] +RSInterface 570 - [13: Warning!] +RSInterface 570 - [14: The cave is very dark and you don't have a light
source. Are you sure you want to go down?] +RSInterface 570 - [17: I'm NOT scared of the dark] +RSInterface 570 - [18: I AM scared of the dark] +RSInterface 570 - [19: Don't ask me this again] +RSInterface 571 - [13: Warning!] +RSInterface 571 - [14: The tunnel is very dark. Are you sure you want
to go down without a light source?] +RSInterface 571 - [17: Yes I am sure.] +RSInterface 571 - [18: No, I am not properly equipped.] +RSInterface 571 - [19: Don't ask me this again] +RSInterface 572 - [13: Warning!] +RSInterface 572 - [14: If your light source goes out down there you'll
be in trouble! Are you sure you want to go in without
a tinderbox?] +RSInterface 572 - [17: I'm NOT scared of the dark] +RSInterface 572 - [18: I AM scared of the dark] +RSInterface 572 - [19: Don't ask me this again] +RSInterface 573 - [13: Warning!] +RSInterface 573 - [14: You can run past, but keep in mind that a
dangerous area follows!] +RSInterface 573 - [17: I'm not scared] +RSInterface 573 - [18: I think I'll stay here] +RSInterface 573 - [19: Don't ask me this again] +RSInterface 574 - [13: Warning!] +RSInterface 574 - [14: This area is very dangerous, are you sure you want to continue?] +RSInterface 574 - [17: Go in - I don't mind dying] +RSInterface 574 - [18: No - I'm holding too much stuff] +RSInterface 574 - [19: Don't ask me this again] +RSInterface 575 - [13: Warning!] +RSInterface 575 - [14: If you pull this lever you will be attacked by the King Black Dragon, one of the most deadly creatures in RuneScape.] +RSInterface 575 - [17: That's what I came here for] +RSInterface 575 - [18: I think I'll stay out] +RSInterface 575 - [19: Don't ask me this again] +RSInterface 576 - [13: Warning!] +RSInterface 576 - [14: This way leads into the Wilderness and is only
one way! Are you sure you want to go down here?] +RSInterface 576 - [17: Yes - I'm fearless] +RSInterface 576 - [18: No - That doesn't seem like a sensible
thing to do] +RSInterface 576 - [19: Don't ask me this again] +RSInterface 577 - [13: Warning!] +RSInterface 577 - [14: The tunnel is very dark. Are you sure you want to
go down without a light source?] +RSInterface 577 - [17: Yes I am sure.] +RSInterface 577 - [18: No, I am not properly equipped.] +RSInterface 577 - [19: Don't ask me this again] +RSInterface 578 - [13: Warning!] +RSInterface 578 - [14: This fairy ring code leads to a dark area. Are you
sure you want to go there without a light source?] +RSInterface 578 - [17: Yes I am sure.] +RSInterface 578 - [18: No, I am not properly equipped.] +RSInterface 578 - [19: Don't ask me this again] +RSInterface 579 - [13: Warning!] +RSInterface 579 - [14: Are you sure you want to climb down?] +RSInterface 579 - [17: Yes - I know that it may be
dangerous down there] +RSInterface 579 - [18: No thanks - I don't want to die] +RSInterface 579 - [19: Don't ask me this again] +RSInterface 580 - [13: Warning!] +RSInterface 580 - [14: Mort Myre is a dangerous ghast-infested swamp.
Do not enter if you value your life.] +RSInterface 580 - [17: Enter the swamp.] +RSInterface 580 - [18: Stay out] +RSInterface 580 - [19: Don't ask me this again] +RSInterface 581 - [13: Warning!] +RSInterface 581 - [14: Danger! Death Plateau is not named that for
a joke! If you continue down this path you will
be assailed by trolls! If you are not prepared
for that you should turn back now!] +RSInterface 581 - [17: Don't show me this again] +RSInterface 583 - [14: Reset Warning Messages] +RSInterface 583 - [15: Body Text] +RSInterface 583 - [46: Dagannoth Kings' Ladder] +RSInterface 583 - [47: Lumbridge Swamp Cave Rope] +RSInterface 583 - [48: Stronghold of Security Ladders] +RSInterface 583 - [49: Falador Mole Lair] +RSInterface 583 - [50: Dropped Items in Random Events] +RSInterface 583 - [51: Player-Owned Houses] +RSInterface 583 - [52: Contact Dungeon Ladder] +RSInterface 583 - [53: Icy Path Area] +RSInterface 583 - [54: H.A.M. Tunnel from Mill] +RSInterface 583 - [55: Fairy Ring to Dorgesh-Kaan] +RSInterface 583 - [56: Lumbridge Cellar] +RSInterface 583 - [57: Mort Myre] +RSInterface 583 - [58: Observatory Stairs] +RSInterface 583 - [59: Shantay Pass] +RSInterface 583 - [60: Elid Genie Cave] +RSInterface 583 - [61: Watchtower Shaman Cave] +RSInterface 583 - [62: Trollheim Wilderness Entrance] +RSInterface 583 - [63: Wilderness Ditch] +RSInterface 583 - [64: Dorgesh-Kaan City Exit] +RSInterface 583 - [65: Dorgesh-Kaan Tunnel to Kalphites] +RSInterface 583 - [66: Ranging Guild Tower] +RSInterface 583 - [67: Death Plateau] +RSInterface 583 - [68: God Wars Wilderness Agility Route] +RSInterface 583 - [69: Duel Arena] +RSInterface 583 - [70: Bounty Hunter] +RSInterface 583 - [71: Chaos Tunnels (East)] +RSInterface 583 - [72: Chaos Tunnels (Central)] +RSInterface 586 - [2: Change of address form for the citizens of Seers' Village.] +RSInterface 587 - [2: Meet at Camel We'll storm She'll ensure w The servants silence.] +RSInterface 588 - [3: Correct tumbler and height] +RSInterface 588 - [4: Correct height, wrong tumbler] +RSInterface 588 - [5: Wrong height, wrong tumbler] +RSInterface 588 - [6: Selected tumbler height] +RSInterface 588 - [7: 0/5] +RSInterface 588 - [8: Tumbler] +RSInterface 588 - [9: Guess] +RSInterface 588 - [14: Try Lock] +RSInterface 588 - [15: 1] +RSInterface 588 - [16: 2] +RSInterface 588 - [17: 3] +RSInterface 588 - [18: 4] +RSInterface 588 - [19: Select a tumbler] +RSInterface 588 - [20: 1] +RSInterface 588 - [21: 2] +RSInterface 588 - [22: 3] +RSInterface 588 - [23: 4] +RSInterface 589 - [0: Talking in: Not in chat] +RSInterface 589 - [1: Owner: None] +RSInterface 589 - [7: Clan Chat] +RSInterface 589 - [8: Join Chat] +RSInterface 589 - [9: Clan Setup] +RSInterface 591 - [61: Thessalia's Makeovers] +RSInterface 591 - [62: Striped sweater] +RSInterface 591 - [65: Woollen vest] +RSInterface 591 - [68: Princely vest] +RSInterface 591 - [71: Tattered waistcoat] +RSInterface 591 - [74: Fine shirt] +RSInterface 591 - [77: Waistcoat] +RSInterface 591 - [80: Plain top] +RSInterface 591 - [83: Light buttons] +RSInterface 591 - [86: Dark buttons] +RSInterface 591 - [89: Jacket] +RSInterface 591 - [92: Shirt] +RSInterface 591 - [95: Stitching] +RSInterface 591 - [98: Ragged top] +RSInterface 591 - [101: Two-toned] +RSInterface 591 - [104: Striped arms] +RSInterface 591 - [107: Princely sleeves] +RSInterface 591 - [110: Fine cuffs] +RSInterface 591 - [113: Woollen sleeves] +RSInterface 591 - [116: Ragged arms] +RSInterface 591 - [119: Tattered sleeves] +RSInterface 591 - [122: Loose sleeved] +RSInterface 591 - [125: Regular] +RSInterface 591 - [128: Musclebound] +RSInterface 591 - [131: Large cuffed] +RSInterface 591 - [134: Thin sleeved] +RSInterface 591 - [137: Shoulder pads] +RSInterface 591 - [140: Plain trousers] +RSInterface 591 - [143: Princely breeches] +RSInterface 591 - [146: Shorts] +RSInterface 591 - [149: Ragged breeches] +RSInterface 591 - [152: Tattered breeches] +RSInterface 591 - [155: Torn trousers] +RSInterface 591 - [158: Breeches] +RSInterface 591 - [161: Striped trousers] +RSInterface 591 - [164: Turn-ups] +RSInterface 591 - [167: Flares] +RSInterface 591 - [170: Fine breeches] +RSInterface 591 - [179: 1,000 Coins] +RSInterface 592 - [64: Hairdresser's Salon] +RSInterface 592 - [65: Bald] +RSInterface 592 - [68: Bun] +RSInterface 592 - [71: Dreadlocks] +RSInterface 592 - [74: Long] +RSInterface 592 - [77: Short] +RSInterface 592 - [80: Pigtails] +RSInterface 592 - [83: Crew cut] +RSInterface 592 - [86: Close-cropped] +RSInterface 592 - [89: Wild spikes] +RSInterface 592 - [92: Spikes] +RSInterface 592 - [95: Side ponytail] +RSInterface 592 - [98: Curls] +RSInterface 592 - [101: Wind braids] +RSInterface 592 - [104: Ponytail] +RSInterface 592 - [107: Braids] +RSInterface 592 - [110: Four ponies] +RSInterface 592 - [113: Bob] +RSInterface 592 - [116: Layered] +RSInterface 592 - [119: Straight] +RSInterface 592 - [122: Long braids] +RSInterface 592 - [125: Curtains] +RSInterface 592 - [128: Earmuffs] +RSInterface 592 - [133: 2,000 Coins] +RSInterface 593 - [72: Reinald's Smithing Emporium] +RSInterface 593 - [73: Bare arms] +RSInterface 593 - [76: Silver wristguards] +RSInterface 593 - [79: Silver clasps] +RSInterface 593 - [82: Silver bangles] +RSInterface 593 - [85: Silver banding] +RSInterface 593 - [88: Silver bands] +RSInterface 593 - [91: Silver armguards] +RSInterface 593 - [94: Bare arms] +RSInterface 593 - [97: Gold wristguards] +RSInterface 593 - [100: Gold clasps] +RSInterface 593 - [103: Gold bangles] +RSInterface 593 - [106: Gold banding] +RSInterface 593 - [109: Gold bands] +RSInterface 593 - [112: Gold armguards] +RSInterface 593 - [118: 500 Coins] +RSInterface 594 - [61: Thessalia's Makeovers] +RSInterface 594 - [62: Striped sweater] +RSInterface 594 - [67: Woollen vest] +RSInterface 594 - [68: Frilled blouse] +RSInterface 594 - [71: Bodice] +RSInterface 594 - [74: Fine shirt] +RSInterface 594 - [77: Ragged top] +RSInterface 594 - [80: Plain top] +RSInterface 594 - [83: Crop-top] +RSInterface 594 - [86: Simple] +RSInterface 594 - [89: Polo neck] +RSInterface 594 - [92: Torn] +RSInterface 594 - [95: Striped arms] +RSInterface 594 - [98: Frilled sleeves] +RSInterface 594 - [101: Fine cuffs] +RSInterface 594 - [104: Woollen arms] +RSInterface 594 - [107: Ragged sleeves] +RSInterface 594 - [110: Tattered sleeves] +RSInterface 594 - [113: Long sleeves] +RSInterface 594 - [116: Short sleeves] +RSInterface 594 - [119: Muscly] +RSInterface 594 - [122: Large cuffs] +RSInterface 594 - [125: Bare arms] +RSInterface 594 - [128: Fine skirt] +RSInterface 594 - [131: Frilled skirt] +RSInterface 594 - [134: Layered skirt] +RSInterface 594 - [137: Long, narrow skirt] +RSInterface 594 - [140: Ragged skirt] +RSInterface 594 - [143: Tattered skirt] +RSInterface 594 - [146: Short skirt] +RSInterface 594 - [149: Sashed skirt] +RSInterface 594 - [152: Fitted skirt] +RSInterface 594 - [155: Torn trousers] +RSInterface 594 - [158: Long skirt] +RSInterface 594 - [161: Turn-ups] +RSInterface 594 - [164: Flares] +RSInterface 594 - [167: Plain trousers] +RSInterface 594 - [170: Shorts] +RSInterface 594 - [180: 1,000 Coins] +RSInterface 595 - [72: Reinald's Smithing Emporium] +RSInterface 595 - [73: Bare arms] +RSInterface 595 - [76: Silver wristguards] +RSInterface 595 - [79: Silver clasps] +RSInterface 595 - [82: Silver bangles] +RSInterface 595 - [85: Silver banding] +RSInterface 595 - [88: Silver bands] +RSInterface 595 - [91: Silver armguards] +RSInterface 595 - [94: Bare arms] +RSInterface 595 - [97: Gold wristguards] +RSInterface 595 - [100: Gold clasps] +RSInterface 595 - [103: Gold bangles] +RSInterface 595 - [106: Gold banding] +RSInterface 595 - [109: Gold bands] +RSInterface 595 - [112: Gold armguards] +RSInterface 595 - [118: 500 Coins] +RSInterface 596 - [64: Hairdresser's Salon] +RSInterface 596 - [65: Bald] +RSInterface 596 - [68: Dreadlocks] +RSInterface 596 - [71: Long hair] +RSInterface 596 - [74: Medium hair] +RSInterface 596 - [77: Monk] +RSInterface 596 - [80: Short] +RSInterface 596 - [83: Close-cropped] +RSInterface 596 - [86: Wild spikes] +RSInterface 596 - [89: Spikes] +RSInterface 596 - [92: Mohawk] +RSInterface 596 - [95: Wind braids] +RSInterface 596 - [98: Quiff] +RSInterface 596 - [101: Samurai] +RSInterface 596 - [104: Prince] +RSInterface 596 - [107: Curtains] +RSInterface 596 - [110: Long curtains] +RSInterface 596 - [113: Goatee] +RSInterface 596 - [116: Long beard] +RSInterface 596 - [119: Medium beard] +RSInterface 596 - [122: Moustache] +RSInterface 596 - [125: Clean shaven] +RSInterface 596 - [128: Short beard] +RSInterface 596 - [131: Short full] +RSInterface 596 - [134: Split] +RSInterface 596 - [137: Handlebar] +RSInterface 596 - [140: Mutton] +RSInterface 596 - [143: Full mutton] +RSInterface 596 - [146: Full moustache] +RSInterface 596 - [149: Waxed] +RSInterface 596 - [152: Dali] +RSInterface 596 - [155: Vizier] +RSInterface 596 - [161: 2,000 Coins] +RSInterface 597 - [2: NPC Killcount] +RSInterface 597 - [3: Armadyl kills] +RSInterface 597 - [4: Bandos kills] +RSInterface 597 - [5: Saradomin kills] +RSInterface 597 - [6: Zamorak kills] +RSInterface 597 - [7: 0] +RSInterface 597 - [8: 0] +RSInterface 597 - [9: 0] +RSInterface 598 - [2: NPC Killcount] +RSInterface 598 - [3: Armadyl kills] +RSInterface 598 - [4: Bandos kills] +RSInterface 598 - [5: Saradomin kills] +RSInterface 598 - [6: Zamorak kills] +RSInterface 598 - [7: 0] +RSInterface 598 - [8: 0] +RSInterface 598 - [9: 0] +RSInterface 599 - [2: NPC Killcount] +RSInterface 599 - [3: Armadyl kills] +RSInterface 599 - [4: Bandos kills] +RSInterface 599 - [5: Saradomin kills] +RSInterface 599 - [6: Zamorak kills] +RSInterface 599 - [7: 0] +RSInterface 599 - [8: 0] +RSInterface 599 - [9: 0] +RSInterface 600 - [13: Warning!] +RSInterface 600 - [14: This way leads into the Wilderness and is only
one way! Are you sure you want to go down here?] +RSInterface 600 - [17: Yes, I'm fearless] +RSInterface 600 - [18: Nope, that doesn't seem like a sensible
thing to do] +RSInterface 600 - [19: Don't ask me this again] +RSInterface 601 - [1: NPC Killcount] +RSInterface 601 - [2: Armadyl kills] +RSInterface 601 - [3: Bandos kills] +RSInterface 601 - [4: Saradomin kills] +RSInterface 601 - [5: Zamorak kills] +RSInterface 601 - [6: 0] +RSInterface 601 - [7: 0] +RSInterface 601 - [8: 0] +RSInterface 617 - [7: Bolrie's Diary] +RSInterface 617 - [8: Chapter 1. Bad advice] +RSInterface 617 - [9: In which Bolrie is advised by] +RSInterface 617 - [10: a mysterious stranger, and] +RSInterface 617 - [11: ambition is fed.] +RSInterface 617 - [13: Chapter 2. The King is dead] +RSInterface 617 - [14: In which a great king dies] +RSInterface 617 - [15: and the search for a new] +RSInterface 617 - [16: one begins.] +RSInterface 617 - [19: Chapter 3. Eyes opened] +RSInterface 617 - [20: In which a secret is revealed,] +RSInterface 617 - [21: an old foe reappears and] +RSInterface 617 - [22: ambitions end.] +RSInterface 617 - [24: Finally, I understand my] +RSInterface 617 - [25: failings and my true enemies.] +RSInterface 617 - [26: I dedicate the rest of my] +RSInterface 617 - [27: shattered life to the task of] +RSInterface 617 - [28: eradicating them both.] +RSInterface 619 - [43: Pay Bank Charge With...] +RSInterface 620 - [19: Player Stock] +RSInterface 620 - [21: Main Stock] +RSInterface 620 - [22: Lowe's Archery Emporium] +RSInterface 620 - [28: Right-click on an item in the shop or your inventory to see the available options.
Compare the prices between the Main and Player Stock to find the best deals!] +RSInterface 620 - [31: Player Stock] +RSInterface 620 - [32: Main Stock] +RSInterface 623 - [4: Message of the week] +RSInterface 624 - [46: Fairy Ring Power Relay] +RSInterface 624 - [47: Assign power to each ring in proportion to its area:] +RSInterface 624 - [68: Confirm] +RSInterface 624 - [70: 0] +RSInterface 624 - [71: 0] +RSInterface 625 - [45: Please select your goblin from the options below:] +RSInterface 625 - [67: Select your Goblin] +RSInterface 625 - [68: Goblin 1] +RSInterface 625 - [71: Goblin 2] +RSInterface 625 - [74: Goblin 3] +RSInterface 625 - [77: Goblin 4] +RSInterface 625 - [80: Goblin 5] +RSInterface 625 - [83: Goblin 6] +RSInterface 625 - [105: Confirm] +RSInterface 626 - [20: Are you sure you want to fight this duel?] +RSInterface 626 - [23: You are about to stake:] +RSInterface 626 - [24: Your opponent will stake:] +RSInterface 626 - [25: Absolutely nothing!] +RSInterface 626 - [26: Absolutely nothing!] +RSInterface 626 - [27: Before the duel starts:] +RSInterface 626 - [28: There will be obstacles in the arena.] +RSInterface 626 - [29: There will be obstacles in the arena.] +RSInterface 626 - [30: There will be obstacles in the arena.] +RSInterface 626 - [31: There will be obstacles in the arena.] +RSInterface 626 - [32: During the duel:] +RSInterface 626 - [33: There will be obstacles in the arena.] +RSInterface 626 - [34: There will be obstacles in the arena.] +RSInterface 626 - [35: There will be obstacles in the arena.] +RSInterface 626 - [36: There will be obstacles in the arena.] +RSInterface 626 - [37: There will be obstacles in the arena.] +RSInterface 626 - [38: There will be obstacles in the arena.] +RSInterface 626 - [39: There will be obstacles in the arena.] +RSInterface 626 - [40: There will be obstacles in the arena.] +RSInterface 626 - [41: Lots of y's and g's] +RSInterface 626 - [42: There will be obstacles in the arena.] +RSInterface 626 - [43: There will be obstacles in the arena.] +RSInterface 626 - [44: There will be obstacles in the arena.] +RSInterface 626 - [45: Waiting for other player...] +RSInterface 626 - [53: Accept] +RSInterface 627 - [13: Warning!] +RSInterface 627 - [14: Duelling is an honourable pastime. Anyone leaving a duel or tournament by ANY means, accidentally or deliberately, will lose their duel and their stake. No exceptions.] +RSInterface 627 - [17: Don't show me this again] +RSInterface 629 - [11: Tournament Value:] +RSInterface 629 - [12: 0] +RSInterface 629 - [40: Rank Required:] +RSInterface 629 - [41: Entry Fee:] +RSInterface 629 - [42: Potions:] +RSInterface 629 - [43: Food:] +RSInterface 629 - [44: Prayer:] +RSInterface 629 - [45: Special Attacks:] +RSInterface 629 - [46: Obstacles:] +RSInterface 629 - [47: Ranged:] +RSInterface 629 - [48: Melee:] +RSInterface 629 - [49: Magic:] +RSInterface 629 - [50: Heal Between Rounds:] +RSInterface 629 - [51: Weapon Slots Only:] +RSInterface 629 - [52: Summoning:] +RSInterface 629 - [53: rank] +RSInterface 629 - [54: fee] +RSInterface 629 - [55: fee] +RSInterface 629 - [56: fee] +RSInterface 629 - [57: fee] +RSInterface 629 - [58: spec] +RSInterface 629 - [59: obstacles] +RSInterface 629 - [60: ranged] +RSInterface 629 - [61: melee] +RSInterface 629 - [62: magic] +RSInterface 629 - [63: heal] +RSInterface 629 - [64: weapon] +RSInterface 629 - [65: summon] +RSInterface 629 - [67: Join] +RSInterface 629 - [68: Join] +RSInterface 629 - [69: Join] +RSInterface 629 - [70: Join] +RSInterface 629 - [71: Join] +RSInterface 629 - [72: Resign] +RSInterface 630 - [0: Line1] +RSInterface 630 - [1: Line2] +RSInterface 630 - [2: Click here to continue] +RSInterface 631 - [24: Opponent:] +RSInterface 631 - [25: namehhhhhhhh] +RSInterface 631 - [26: Opponent's Level:] +RSInterface 631 - [27: 126] +RSInterface 631 - [28: AAAAAAAAAAAAAAAA] +RSInterface 631 - [29: No Ranged] +RSInterface 631 - [31: No Melee] +RSInterface 631 - [33: No Magic] +RSInterface 631 - [35: Fun Weapons] +RSInterface 631 - [37: No Forfeit] +RSInterface 631 - [39: No Drinks] +RSInterface 631 - [41: No Food] +RSInterface 631 - [43: No Prayer] +RSInterface 631 - [45: No Movement] +RSInterface 631 - [47: Obstacles] +RSInterface 631 - [50: No Special Attacks] +RSInterface 631 - [52: Enable Summoning] +RSInterface 631 - [92: 0] +RSInterface 631 - [93: 0] +RSInterface 631 - [94: Max Stake:] +RSInterface 631 - [95: Max Stake:] +RSInterface 631 - [96: Your stake:] +RSInterface 631 - [97: Opponent's stake:] +RSInterface 631 - [101: Accept] +RSInterface 631 - [106: VS] +RSInterface 632 - [13: Last fifty duels on this world:] +RSInterface 632 - [14: Duel Scoreboard] +RSInterface 632 - [16: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [17: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [18: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [19: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [20: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [21: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [22: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [23: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [24: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [25: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [26: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [27: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [28: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [29: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [30: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [31: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [32: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [33: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [34: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [35: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [36: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [37: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [38: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [39: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [40: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [41: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [42: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [43: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [44: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [45: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [46: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [47: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [48: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [49: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [50: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [51: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [52: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [53: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [54: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [55: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [56: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [57: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [58: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [59: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [60: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [61: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [62: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [63: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [64: Crunchy (126) beat Crunchy2 (126)] +RSInterface 632 - [65: Crunchy (126) beat Crunchy2 (126)] +RSInterface 633 - [15: You are Victorious!] +RSInterface 633 - [17: Close] +RSInterface 633 - [18: The Defeated:] +RSInterface 633 - [19: Name:] +RSInterface 633 - [20: Combat Level:] +RSInterface 633 - [21: 126] +RSInterface 633 - [22: Crunchy] +RSInterface 634 - [15: You are Victorious!] +RSInterface 634 - [17: Claim!] +RSInterface 634 - [18: The Spoils:] +RSInterface 634 - [19: The Defeated:] +RSInterface 634 - [20: Name:] +RSInterface 634 - [21: Combat Level:] +RSInterface 634 - [22: 126] +RSInterface 634 - [23: Crunchy] +RSInterface 635 - [12: Style:] +RSInterface 635 - [13: Options:] +RSInterface 635 - [28: Registrar:] +RSInterface 635 - [30: Tourn. Rank:] +RSInterface 635 - [32: Tourn. Value:] +RSInterface 635 - [34: Entry Fee:] +RSInterface 635 - [36: Time left:] +RSInterface 636 - [11: Upcoming Tournament Rules: Registrar #] +RSInterface 636 - [41: Tournament Value:] +RSInterface 636 - [42: Rank Required:] +RSInterface 636 - [43: Entry Fee:] +RSInterface 636 - [44: Potions:] +RSInterface 636 - [45: Food:] +RSInterface 636 - [46: Prayer:] +RSInterface 636 - [47: Special Attacks:] +RSInterface 636 - [48: Obstacles:] +RSInterface 636 - [49: Ranged:] +RSInterface 636 - [50: Melee:] +RSInterface 636 - [51: Magic:] +RSInterface 636 - [52: Heal Between Rounds:] +RSInterface 636 - [53: Weapon Slots Only:] +RSInterface 636 - [54: Summoning:] +RSInterface 636 - [55: 0] +RSInterface 636 - [56: rank] +RSInterface 636 - [57: fee] +RSInterface 636 - [58: fee] +RSInterface 636 - [59: fee] +RSInterface 636 - [60: fee] +RSInterface 636 - [61: spec] +RSInterface 636 - [62: obstacles] +RSInterface 636 - [63: ranged] +RSInterface 636 - [64: melee] +RSInterface 636 - [65: magic] +RSInterface 636 - [66: heal] +RSInterface 636 - [67: weapon] +RSInterface 637 - [15: Duelling with:] +RSInterface 637 - [16: name] +RSInterface 637 - [17: Their Combat Level:] +RSInterface 637 - [18: 126] +RSInterface 637 - [19: No Ranged] +RSInterface 637 - [21: No Melee] +RSInterface 637 - [23: No Magic] +RSInterface 637 - [25: Fun Weapons] +RSInterface 637 - [27: No Forfeit] +RSInterface 637 - [29: No Drinks] +RSInterface 637 - [31: No Food] +RSInterface 637 - [33: No Prayer] +RSInterface 637 - [35: No Movement] +RSInterface 637 - [37: Obstacles] +RSInterface 637 - [39: Enable Summoning] +RSInterface 637 - [41: No Special Attacks] +RSInterface 637 - [45: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA] +RSInterface 637 - [82: Accept] +RSInterface 637 - [85: Decline] +RSInterface 639 - [14: Are you sure you want to fight this duel?] +RSInterface 639 - [15: Before the duel starts:] +RSInterface 639 - [16: Lots of y's and g's] +RSInterface 639 - [17: There will be obstacles in the arena.] +RSInterface 639 - [18: There will be obstacles in the arena.] +RSInterface 639 - [19: There will be obstacles in the arena.] +RSInterface 639 - [20: There will be obstacles in the arena.] +RSInterface 639 - [21: During the duel:] +RSInterface 639 - [22: There will be obstacles in the arena.] +RSInterface 639 - [23: There will be obstacles in the arena.] +RSInterface 639 - [24: There will be obstacles in the arena.] +RSInterface 639 - [25: There will be obstacles in the arena.] +RSInterface 639 - [26: There will be obstacles in the arena.] +RSInterface 639 - [27: There will be obstacles in the arena.] +RSInterface 639 - [28: There will be obstacles in the arena.] +RSInterface 639 - [29: There will be obstacles in the arena.] +RSInterface 639 - [30: There will be obstacles in the arena.] +RSInterface 639 - [31: There will be obstacles in the arena.] +RSInterface 639 - [32: There will be obstacles in the arena.] +RSInterface 639 - [33: Waiting for other player...] +RSInterface 639 - [35: Accept] +RSInterface 640 - [18: Friendly Duel] +RSInterface 640 - [19: Staked Duel] +RSInterface 640 - [20: Challenge!] +RSInterface 641 - [13: Style:] +RSInterface 641 - [14: Options:] +RSInterface 641 - [28: Tourn. Size:] +RSInterface 641 - [29: 0] +RSInterface 641 - [30: Round Time:] +RSInterface 641 - [32: Tourn. Value:] +RSInterface 641 - [34: Opponent:] +RSInterface 641 - [36: Tourn. Rank:] +RSInterface 641 - [37: 0] +RSInterface 643 - [19: Item Back History] +RSInterface 643 - [21: Offer type] +RSInterface 643 - [22: Item name] +RSInterface 643 - [23: Quantity] +RSInterface 643 - [24: Price] +RSInterface 643 - [25: xxxxxxxxxxxxx] +RSInterface 643 - [26: xxxxxxxxxxxxx] +RSInterface 643 - [27: xxxxxxxxxxxxx] +RSInterface 643 - [28: xxxxxxxxxxxxx] +RSInterface 643 - [29: xxxxxxxxxxxxx] +RSInterface 643 - [30: 2,000,000,000] +RSInterface 643 - [31: 2,000,000,000] +RSInterface 643 - [32: 2,000,000,000] +RSInterface 643 - [33: 2,000,000,000] +RSInterface 643 - [34: 2,000,000,000] +RSInterface 643 - [35: name name name name name] +RSInterface 643 - [36: name name name name name] +RSInterface 643 - [37: name name name name name] +RSInterface 643 - [38: name name name name name] +RSInterface 643 - [39: name name name name name] +RSInterface 643 - [40: 2,000,000,000 gp] +RSInterface 643 - [41: 2,000,000,000 gp] +RSInterface 643 - [42: 2,000,000,000 gp] +RSInterface 643 - [43: 2,000,000,000 gp] +RSInterface 643 - [44: 2,000,000,000 gp] +RSInterface 645 - [15: Grand Exchange Item Sets] +RSInterface 645 - [17: Click on a set you wish to purchase here
or click on a set in your inventory that you wish to sell.] +RSInterface 646 - [11: Step 4 : With your items placed on the Grand Exchange system, just wait a while and we will let you know when your items are traded.] +RSInterface 647 - [19: Items being dropped] +RSInterface 647 - [20: Items ready to be dropped] +RSInterface 647 - [24: 00] +RSInterface 647 - [26: Accept] +RSInterface 649 - [5: Stop viewing] +RSInterface 649 - [11: Centre] +RSInterface 649 - [12: North-west] +RSInterface 649 - [13: North-east] +RSInterface 649 - [14: South-east] +RSInterface 650 - [3: Defeat!] +RSInterface 650 - [4: Your clan has been defeated.] +RSInterface 651 - [3: Victory!] +RSInterface 651 - [4: Your clan is victorious!] +RSInterface 652 - [28: Gravestones] +RSInterface 653 - [6: Target:] +RSInterface 653 - [7: None] +RSInterface 653 - [9: Pickup penalty:] +RSInterface 653 - [10: 100 Sec] +RSInterface 653 - [12: Can't leave for:] +RSInterface 654 - [3: Bounty Hunters] +RSInterface 654 - [4: Players who hunt and kill assigned targets] +RSInterface 654 - [5: 1)] +RSInterface 654 - [6: 2)] +RSInterface 654 - [7: 3)] +RSInterface 654 - [8: 4)] +RSInterface 654 - [9: 5)] +RSInterface 654 - [10: 6)] +RSInterface 654 - [11: 7)] +RSInterface 654 - [12: 8)] +RSInterface 654 - [13: 9)] +RSInterface 654 - [14: 10)] +RSInterface 654 - [15: Nobody yet] +RSInterface 654 - [16: Nobody yet] +RSInterface 654 - [17: Nobody yet] +RSInterface 654 - [18: Nobody yet] +RSInterface 654 - [19: Nobody yet] +RSInterface 654 - [20: Nobody yet] +RSInterface 654 - [21: Nobody yet] +RSInterface 654 - [22: Nobody yet] +RSInterface 654 - [23: Nobody yet] +RSInterface 654 - [24: Nobody yet] +RSInterface 654 - [25: 0] +RSInterface 654 - [26: 0] +RSInterface 654 - [27: 0] +RSInterface 654 - [28: 0] +RSInterface 654 - [29: 0] +RSInterface 654 - [30: 0] +RSInterface 654 - [31: 0] +RSInterface 654 - [32: 0] +RSInterface 654 - [33: 0] +RSInterface 654 - [34: 0] +RSInterface 655 - [3: Rogues] +RSInterface 655 - [4: Players who hunt and kill anyone] +RSInterface 655 - [5: 1)] +RSInterface 655 - [6: 2)] +RSInterface 655 - [7: 3)] +RSInterface 655 - [8: 4)] +RSInterface 655 - [9: 5)] +RSInterface 655 - [10: 6)] +RSInterface 655 - [11: 7)] +RSInterface 655 - [12: 8)] +RSInterface 655 - [13: 9)] +RSInterface 655 - [14: 10)] +RSInterface 655 - [15: Nobody yet] +RSInterface 655 - [16: Nobody yet] +RSInterface 655 - [17: Nobody yet] +RSInterface 655 - [18: Nobody yet] +RSInterface 655 - [19: Nobody yet] +RSInterface 655 - [20: Nobody yet] +RSInterface 655 - [21: Nobody yet] +RSInterface 655 - [22: Nobody yet] +RSInterface 655 - [23: Nobody yet] +RSInterface 655 - [24: Nobody yet] +RSInterface 655 - [25: 0] +RSInterface 655 - [26: 0] +RSInterface 655 - [27: 0] +RSInterface 655 - [28: 0] +RSInterface 655 - [29: 0] +RSInterface 655 - [30: 0] +RSInterface 655 - [31: 0] +RSInterface 655 - [32: 0] +RSInterface 655 - [33: 0] +RSInterface 655 - [34: 0] +RSInterface 656 - [6: Players waiting (need X):] +RSInterface 656 - [7: 0] +RSInterface 656 - [9: Game starting in:] +RSInterface 657 - [22: WARNING!] +RSInterface 657 - [23: You are about to enter the Bounty Hunter minigame.

This is not a safe area - it involves player versus player combat and, if you die, you will lose all the items you are carrying!

If you kill players that are not your target, you will not be able to use the Protect Item prayer. Also you cannot drop items on the floor worth over 1000 gp.] +RSInterface 657 - [24: Enter
Crater] +RSInterface 657 - [25: Don't go] +RSInterface 657 - [26: Don't ask me this again] +RSInterface 660 - [98: Welcome to RuneScape
Use the buttons below to design your player] +RSInterface 660 - [101: Accept] +RSInterface 660 - [106: Design] +RSInterface 660 - [121: Head
Jaw
Torso
Arms
Hands
Legs
Feet] +RSInterface 660 - [122: Colour] +RSInterface 660 - [133: Hair
Torso
Legs
Feet
Skin] +RSInterface 660 - [136: Gender] +RSInterface 660 - [139: Male] +RSInterface 661 - [1: The runes must be in sets of three, I think, but I have had no luck in completing this conundrum. Perhaps, if my Thieving skills were greater, I could in some way interfere with the mechanism. May those who follow have more luck in this accursed place.
-Toralis of Menaphos] +RSInterface 663 - [17: 100%] +RSInterface 663 - [19: 9999] +RSInterface 664 - [0: %1] +RSInterface 664 - [8: Summon] +RSInterface 664 - [10: Auto-retaliate
(Off)] +RSInterface 664 - [26: S P E C I A L A T T A C K] +RSInterface 664 - [27: Combat Lvl: %1] +RSInterface 664 - [28: Bash] +RSInterface 664 - [29: Pound] +RSInterface 664 - [30: Focus] +RSInterface 666 - [14: Scroll Creation ] +RSInterface 667 - [1: Equip Your Character...] +RSInterface 667 - [22: Attack bonus] +RSInterface 667 - [23: Defence bonus] +RSInterface 667 - [24: Stab: +120] +RSInterface 667 - [25: Slash:+120] +RSInterface 667 - [26: Crush:+120] +RSInterface 667 - [27: Magic: +120] +RSInterface 667 - [28: Range: +120] +RSInterface 667 - [29: Stab: +120] +RSInterface 667 - [30: Slash: +120] +RSInterface 667 - [31: Crush: +120] +RSInterface 667 - [32: Magic: +120] +RSInterface 667 - [33: Range: +120] +RSInterface 667 - [34: Summoning: +120] +RSInterface 667 - [35: Other bonuses] +RSInterface 667 - [36: Strength: +120] +RSInterface 667 - [37: Prayer: +120] +RSInterface 667 - [38: %1kg] +RSInterface 668 - [0: Pick a Puppy] +RSInterface 669 - [14: Summoning Pouch Creation ] +RSInterface 671 - [14: Familiar Inventory] +RSInterface 672 - [14: Summoning Pouch Creation ] +RSInterface 673 - [14: Scroll Creation ] +RSInterface 676 - [13: Warning!] +RSInterface 676 - [14: This area is dangerous and death is more than a possibility! Are you sure you want to go down there?] +RSInterface 676 - [17: Proceed regardless] +RSInterface 676 - [18: Stay out] +RSInterface 676 - [19: Don't ask me this again] +RSInterface 677 - [13: Warning!] +RSInterface 677 - [14: This area is dangerous and death is more than a possibility! Are you sure you want to go down there?] +RSInterface 677 - [17: Proceed regardless] +RSInterface 677 - [18: Stay out] +RSInterface 677 - [19: Don't ask me this again] +RSInterface 678 - [13: Warning!] +RSInterface 678 - [14: This area is dangerous and death is more than a possibility! Are you sure you want to go down there?] +RSInterface 678 - [17: Proceed regardless] +RSInterface 678 - [18: Stay out] +RSInterface 678 - [19: Don't ask me this again] +RSInterface 679 - [2: Message of the week] +RSInterface 681 - [115: Close] +RSInterface 681 - [116: Repairs Complete] +RSInterface 681 - [117: You finish repairing the catapult. The Guard looks rather impressed.] +RSInterface 682 - [36: COUNTERWEIGHT] +RSInterface 682 - [37: DIRECTION] +RSInterface 683 - [46: Yes, Restart] +RSInterface 683 - [47: No, Cancel] +RSInterface 683 - [48: Are you sure you want to restart the puzzle?] +RSInterface 684 - [3: Watch out for rabbits wandering around the farmyard. They are hungry and will look for flags, as they often mean hidden food! If a rabbit eats the seed under a flag, you will not get any points for it and will lose the flag. ] +RSInterface 684 - [4: You can improve your Hunter skill by finding ogleroots in the farmyard and feeding them to the rabbits. Ogleroots are magical vegetables and will cause the rabbit to disappear for a short amount of time.] +RSInterface 685 - [14: Farmer Blinkin's Vinesweeper Instructions] +RSInterface 685 - [15: 1. Speak to either Mrs. Winkin in the barn or Farmer Blinkin outside to buy some flags.] +RSInterface 685 - [16: 2. When you have some flags, head out into the farmyard area over any of the 4 stiles.] +RSInterface 685 - [17: 3. Use your spade to dig up any of the holes around the farmyard. This will uncover what was in that hole. The aim is to place your flags in holes where you believe seeds are planted.] +RSInterface 685 - [18: 4. If the hole has nothing in it, then it will uncover a radius of 2 holes in all directions] +RSInterface 685 - [19: 5. If you uncover a number from 1-8, this means that there are that many seeds planted in the 8 holes surrounding the one that you have dug up.] +RSInterface 685 - [20: 6. When you have a square that you are certain contains a seed, either right-click and select the 'Flag' option or use a flag on the hole.] +RSInterface 685 - [21: 7. When a farmer sees a flag, he will come over to check beneath it. He will collect the flag and give points out if there was a seed there. If you have successfully found a seed, you will be able to get the flag back for free from either Mrs. Winkin or Farmer Blinkin.] +RSInterface 687 - [3: Use a spade to dig in the farmer's field and try to work out where the seeds have been planted. Try not to dig up the seeds, as this will lose you points! Usually, when you dig a square, you will uncover a number, which shows how many seeds are in the holes next to it.] +RSInterface 687 - [4: Plant your flags in holes where you think that seeds may be found. If you are correct, you will get lots of points, but if you are wrong, you will lose the flag. If you are close to other players, you might get some points if they find seeds, too!"] +RSInterface 688 - [3: While you are in the area, you will be able to see your points total in the top-right corner of your screen. Your points are saved, so you can leave if you wish and return another time to pick up from where you left off.] +RSInterface 688 - [4: You can trade your points in for prizes or Farming experience by speaking to Mrs. Winkin in the Winkin shop.] +RSInterface 688 - [8: Points] +RSInterface 688 - [9: 234,567] +RSInterface 688 - [11: XP] +RSInterface 689 - [7: Points] +RSInterface 689 - [8: None] +RSInterface 690 - [3: Farmers wander the area looking for seeds that have been dug up by mistake. They will also collect any flags you have placed, resetting the nearby area and giving you points if the flag is in the right place.] +RSInterface 690 - [4: If you place a flag over a seed, you will be able to get the flag back from Mrs. Winkin or Farmer Blinkin. If you placed a flag wrongly, you will have to pay 500gp for a new one.] +RSInterface 693 - [4: Congratulations] +RSInterface 693 - [5: Congratulations] +RSInterface 693 - [6: you have] +RSInterface 693 - [7: you have] +RSInterface 693 - [8: slain bork!] +RSInterface 694 - [5: Question:] +RSInterface 694 - [6: Player Safety Test] +RSInterface 694 - [8: A friend you met playing RuneScape has asked to meet you in real life. What should you do?] +RSInterface 694 - [9: Meet them. They've been a friend in-game for a while now and they're really nice] +RSInterface 694 - [10: Say no and do not meet them] +RSInterface 694 - [32: Correct!] +RSInterface 694 - [33: Be polite and say no, but if the other player is persistent you can use the report abuse button and ignore functions, which can both be found at the bottom of your game window. If you are at all concerned, speak to a parent, friend or adult that you trust.] +RSInterface 694 - [35: Incorrect!] +RSInterface 694 - [36: However nice your friend is in RuneScape, they are still a stranger to you in real life. We would suggest that you have fun and enjoy the player's company in-game, but leave it there. If you are at all concerned, speak to a parent, friend or adult that you trust.] +RSInterface 695 - [1: This naughty gublinchette gave a player her email address. The wise player hit the Report Abuse button straight away, allowing us to catch her!] +RSInterface 696 - [5: Question:] +RSInterface 696 - [6: Player Safety Test] +RSInterface 696 - [8: A player has started to ask you personal questions that make you feel uncomfortable and you'd rather not answer. What should you do? ] +RSInterface 696 - [9: Answer them anyway] +RSInterface 696 - [10: Do not answer any questions and report the player using the Report Abuse button at the bottom of the game screen.] +RSInterface 696 - [32: Correct!] +RSInterface 696 - [33: If you are at all concerned, speak to a parent, friend or adult that you trust.] +RSInterface 696 - [35: Incorrect!] +RSInterface 696 - [36: If another player makes you feel uncomfortable by asking lots of personal questions, you can report them using the Report Abuse button. You can also use the ignore function, which can be found at the bottom of your game window.] +RSInterface 697 - [6: Question:] +RSInterface 697 - [7: Player Safety Test] +RSInterface 697 - [9: A player has just asked you for your personal details, including your phone number, home address and email address. What should you do?] +RSInterface 697 - [10: Give them my personal details] +RSInterface 697 - [11: Say "No" or ignore them] +RSInterface 697 - [12: Say "No" and ask for their details instead] +RSInterface 697 - [38: Correct!] +RSInterface 697 - [39: Be polite and say no, but if the other player is persistent you can also use the report abuse button and ignore functions, which can both be found at the bottom of your game window. If you are at all concerned, speak to a parent, friend or adult that you trust.] +RSInterface 697 - [41: Incorrect!] +RSInterface 697 - [42: Giving out personal information to another player is dangerous, as you can never be sure who you are talking to. It's best to keep your personal details to yourself.] +RSInterface 697 - [44: Incorrect!] +RSInterface 697 - [45: Asking for another player's personal details is against the RuneScape Rules of Conduct. Doing so would put your account at risk of being banned.] +RSInterface 698 - [1: This cheeky gublinch claimed to be a Jagex Moderator! He was reported straight away and dealt with.] +RSInterface 699 - [5: Question:] +RSInterface 699 - [6: Player Safety Test] +RSInterface 699 - [8: Where should you go in order to read about playing RuneScape safely?] +RSInterface 699 - [9: There is nowhere to go] +RSInterface 699 - [10: To the 'Safety & Security' section of the RuneScape homepage] +RSInterface 699 - [32: Correct!] +RSInterface 699 - [33: Head to the 'Safety & Security' section of the RuneScape Knowledge Base for more information.] +RSInterface 699 - [35: Incorrect!] +RSInterface 699 - [36: Actually, there is! A "Play Safely" article can be found in the Safety & Security Guidelines section of the Knowledge Base! We also have pages on player safety, keeping healthy, responsible gaming and account security. If you would like more information, please go to the RuneScape Knowledge Base.] +RSInterface 700 - [11: Report abuse] +RSInterface 700 - [12: This form is for reporting players who are breaking our rules.
Using it sends a snapshot of the last 60 secs of activity to us.] +RSInterface 700 - [13: If you misuse this form, you will be banned.] +RSInterface 700 - [14: First please enter the name of the offending player below:] +RSInterface 700 - [15: **************] +RSInterface 700 - [16: Then click below to indicate which of our 13 rules is being broken.
For a detailed explanation of each rule please read the manual on our website.] +RSInterface 700 - [17: 1: Offensive language] +RSInterface 700 - [18: 2: Item scamming] +RSInterface 700 - [19: 3: Password scamming] +RSInterface 700 - [20: 4: Bug abuse] +RSInterface 700 - [21: 5: Jagex staff impersonation] +RSInterface 700 - [22: 6: Account sharing/trading] +RSInterface 700 - [23: 7: Macroing] +RSInterface 700 - [24: 8: Multiple logging in] +RSInterface 700 - [25: 9: Encouraging others to break rules] +RSInterface 700 - [26: 10: Misuse of customer support] +RSInterface 700 - [27: 11: Advertising / website] +RSInterface 700 - [28: 12: Real world item trading] +RSInterface 700 - [29: 13: Asking for personal details] +RSInterface 701 - [1: This wretched gublinch was asking a player for his telephone number. The player helped us catch him by refusing to give their information away and reporting the gublinch straight away!] +RSInterface 702 - [1: This foul-mouthed gublinch was flaming and insulting other players. They used the Report Abuse button and he was instantly apprehended.] +RSInterface 703 - [1: This vile gublinchette was asking a player for his home address. The clever player didn't give her their address, but used the Report Abuse button to report her instead.] +RSInterface 704 - [3: Question:] +RSInterface 704 - [4: Player Safety Test] +RSInterface 704 - [6: How do you report a player for breaking the Rules?] +RSInterface 704 - [7: By using the Report Abuse button at the bottom of my gaming screen] +RSInterface 704 - [8: I'm not a tell-tale, so I don't report players] +RSInterface 704 - [9: Find a Moderator and get them to report the player] +RSInterface 704 - [38: Correct!] +RSInterface 704 - [39: You can use the Report Abuse button at the bottom of the game screen, but make sure you only report players who break the rules.] +RSInterface 704 - [41: Incorrect!] +RSInterface 704 - [42: Reporting players who break the Rules allows us to ensure that RuneScape remains a positive and enjoyable environment for everyone. To find out everything you need to know about reporting rulebreakers in RuneScape, please take some time to read the Rules of Conduct and then see our guides on reporting abuse. This can be accessed by clicking on the link: 'Customer Support' on our homepage and then 'Reporting Abuse'. ] +RSInterface 704 - [44: Incorrect!] +RSInterface 704 - [45: Incorrect. By waiting to find a Moderator, you run the risk of losing the ability to report the player.] +RSInterface 705 - [3: Question:] +RSInterface 705 - [4: Player Safety Test] +RSInterface 705 - [6: A player that you do not know sends you a private message that is offensive. What should you do?] +RSInterface 705 - [7: Nothing. I can't report anything that is said in private chat] +RSInterface 705 - [8: Send the player an offensive message back] +RSInterface 705 - [9: Use the Report Abuse button to report the player and then add them to my Ignore List] +RSInterface 705 - [38: Correct!] +RSInterface 705 - [39: Correct! You can use the Report Abuse button to report any chat that you find offensive, whether it is said in Public or Private Chat. Adding a player to your Ignore List will prevent them from sending you any further messages.] +RSInterface 705 - [41: Incorrect!] +RSInterface 705 - [42: Wrong. You can use the Report Abuse button to report any chat that you find offensive, whether it is said in Public or Private Chat.] +RSInterface 705 - [44: Incorrect!] +RSInterface 705 - [45: Wrong. Retaliating may cause you to get in trouble and be reported yourself!] +RSInterface 706 - [1: This sly gublinch wanted to meet one of his player friends in the real world. The player obviously refused and reported him straight away.] +RSInterface 707 - [5: Question:] +RSInterface 707 - [6: Player Safety Test] +RSInterface 707 - [8: You are approached in the game by a player named JagMod999. This player claims to be a member of Jagex and asks for your personal details. What should you do?] +RSInterface 707 - [9: Do not answer any questions and report the player using the Report Abuse button at the bottom of the game screen] +RSInterface 707 - [10: Give them my details; they are a member of Jagex after all] +RSInterface 707 - [32: Correct!] +RSInterface 707 - [33: Correct! A real Jagex Moderator would never ask for a player's personal details. You can always tell who an official moderator is as a gold crown will appear before anything they say in the chat window. You can report any player who claims to be a member of Jagex Staff by using the Report Abuse button. You can also use the ignore function, which can be found at the bottom of your game window. If you are at all ] +RSInterface 707 - [34: concerned about the incident, speak to a parent, friend or adult that you trust.] +RSInterface 707 - [36: Incorrect!] +RSInterface 707 - [37: A real Jagex Moderator would never ask for any of your personal details, so we would advise you keep them to yourself. You can report any player who claims to be a Jagex Moderator by using the Report Abuse button.] +RSInterface 708 - [5: Question:] +RSInterface 708 - [6: Player Safety Test] +RSInterface 708 - [8: How long should you play RuneScape for at any one time?] +RSInterface 708 - [9: As long as I like. I'm having fun and don't want to stop] +RSInterface 708 - [10: I should take regular breaks in order to stay healthy] +RSInterface 708 - [32: Correct!] +RSInterface 708 - [33: It's very important to remain healthy by taking regular breaks and spending time doing other activities. ] +RSInterface 708 - [35: Incorrect!] +RSInterface 708 - [36: Spending too much time on the computer can be harmful to your health. It's very important to take breaks, exercise and eat properly in order to stay healthy. While it's great to play RuneScape, it's also important to maintain a balanced lifestyle by socialising and spending time away from your computer. For more information, please look at our Responsible Gaming Policy on the RuneScape Knowledge Base.] +RSInterface 709 - [14: End of Exam] +RSInterface 709 - [15: Player Safety Exam 101] +RSInterface 709 - [17: Congratulations! You have completed the Player Safety exam!] +RSInterface 710 - [3: Question:] +RSInterface 710 - [4: Player Safety Test] +RSInterface 710 - [6: You are asked for your full name and date of birth by a player that you have been chatting with for a short while. Should you give them these details?] +RSInterface 710 - [7: No. The player could use my information to steal my identity. I don't want anyone pretending to be me] +RSInterface 710 - [8: Yes. There's no harm in telling someone my full name and my birthday. Maybe they want to buy me a birthday present!] +RSInterface 710 - [32: Correct!] +RSInterface 710 - [33: Correct! Personal details given out while chatting could be used by someone who wishes to pretend to be you. Use the Report Abuse button to report anyone asking for your personal details.] +RSInterface 710 - [35: Incorrect!] +RSInterface 710 - [36: Wrong. Never give out personal details, such as your full name and date of birth, to other players. Personal details that you give out while chatting could be used by someone so that they can pretend to be you. Use the Report Abuse button to report anyone asking for your personal details.] +RSInterface 711 - [1: This evil gublinch asked a younger player where she went to school. The player was smart enough to not tell the gublinch and report him instead.] +RSInterface 712 - [1: Dear friend,] +RSInterface 712 - [2: Come and meet me at the entrance to the Legends' Guild as soon as possible. There are things I would like to discuss with you, but it is difficult to talk in Witchaven...] +RSInterface 712 - [3: ~Kent] +RSInterface 715 - [4: Message of the week] +RSInterface 716 - [33: Chocatrice] +RSInterface 716 - [34: Waiting] +RSInterface 717 - [20: Temperature reached!

New target
temperature set.] +RSInterface 718 - [0: Select an Option] +RSInterface 718 - [1: option1] +RSInterface 718 - [2: option2] +RSInterface 719 - [3: COAL AND WATER SUPPLIES:
For your convenience, the incubator has a coal scuttle and water tank, which can hold up to twelve buckets of coal or water respectively. Simply use a bucket of coal or water on the coal scuttle or water tank to add to the supplies.

ADJUSTING THE INCUBATOR TEMPERATURE:
The control panel to the left of the incubator allows you to use the coal and water supplies you have added to the incubator to heat or cool it.

INCUBATING AN EGG:
> Place a suitable egg inside the incubation chamber.
> Add supplies to the water tank and coal scuttle
> Using the incubator controls, adjust the temperature. The temperature gauge has a needle which shows the current temperature. The top of the temperature gauge also has an arrow showing the temperature needed to reach the next phase of incubation.
> Some eggs may require you to reach several different temperatures before they hatch.

The very best of luck with hatching your eggs!] +RSInterface 723 - [5: ~ What is this? ~] +RSInterface 724 - [18: Runesquares] +RSInterface 724 - [20: vs] +RSInterface 724 - [22: Close] +RSInterface 725 - [18: Runelink] +RSInterface 725 - [21: vs] +RSInterface 725 - [23: Close] +RSInterface 726 - [114: Runeversi] +RSInterface 726 - [116: vs] +RSInterface 726 - [118: Close] +RSInterface 727 - [18: Draughts] +RSInterface 727 - [22: vs] +RSInterface 727 - [24: Close] +RSInterface 730 - [15: Please pick up a stone!] +RSInterface 730 - [17: Charge:] +RSInterface 730 - [18: Name] +RSInterface 730 - [20: Hunting:] +RSInterface 730 - [22: Hunted by:] +RSInterface 730 - [24: Time left:] +RSInterface 731 - [7: Rating] +RSInterface 731 - [16: Text] +RSInterface 731 - [25: The following item is not allowed in the arena:] +RSInterface 733 - [2: Ivandis Flail] +RSInterface 733 - [3: Ivandis flail requires silvthril chain to connect blessed silver sickle to. However, to increase charges for the flail, need to add an emerald to the sickle before chain is attached. ] +RSInterface 733 - [4: Find it difficult to make big hole for emerald to fit in sickle and am just frustrated. More effort to make this work is just crazy, why won't it just work?? ] +RSInterface 734 - [20: Choose a combination] +RSInterface 734 - [21: Teleport to this location] +RSInterface 734 - [22: Teleport to this location] +RSInterface 735 - [11: Travel Log] +RSInterface 737 - [0: Pick a Kitten] +RSInterface 738 - [1: Tok-Xil-Im] +RSInterface 738 - [2: Tok-Ket-Hurt] +RSInterface 738 - [3: TokJal-Hurt] +RSInterface 738 - [4: a] +RSInterface 738 - [5: ah] +RSInterface 738 - [6: ac] diff --git a/dumps/498/498_interface_scripts.txt b/dumps/498/498_interface_scripts.txt new file mode 100644 index 0000000..ff52725 --- /dev/null +++ b/dumps/498/498_interface_scripts.txt @@ -0,0 +1,4357 @@ +Interface 13 child 1 (script default): [184745984, 4521984, 0, null, 184549376, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 13 child 2 (script default): [201523200, 4521984, 0, null, 201326592, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 13 child 3 (script default): [218300416, 4521984, 0, null, 218103808, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 13 child 4 (script default): [235077632, 4521984, 0, null, 234881024, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 13 child 5 (script default): [251854848, 4521984, 0, null, 251658240, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 13 child 6 (script default): [268632064, 4521984, 0, null, 268435456, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 13 child 7 (script default): [285409280, 4521984, 0, null, 285212672, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 13 child 8 (script default): [302186496, 4521984, 0, null, 301989888, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 13 child 9 (script default): [318963712, 4521984, 0, null, 318767104, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 13 child 10 (script default): [335740928, 4521984, 0, null, 335544320, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 13 child 11 (script 2): [null, -2147483645] +Interface 13 child 11 (script 7): [700, -2147483645] +Interface 13 child 12 (script 2): [null, -2147483645] +Interface 13 child 12 (script 7): [700, -2147483645] +Interface 13 child 13 (script 2): [null, -2147483645] +Interface 13 child 13 (script 7): [700, -2147483645] +Interface 13 child 14 (script 2): [null, -2147483645] +Interface 13 child 14 (script 7): [700, -2147483645] +Interface 13 child 15 (script 2): [null, -2147483645] +Interface 13 child 15 (script 7): [700, -2147483645] +Interface 13 child 16 (script 2): [null, -2147483645] +Interface 13 child 16 (script 7): [700, -2147483645] +Interface 13 child 17 (script 2): [null, -2147483645] +Interface 13 child 17 (script 7): [700, -2147483645] +Interface 13 child 18 (script 2): [null, -2147483645] +Interface 13 child 18 (script 7): [700, -2147483645] +Interface 13 child 19 (script 2): [null, -2147483645] +Interface 13 child 19 (script 7): [700, -2147483645] +Interface 13 child 20 (script 2): [null, -2147483645] +Interface 13 child 20 (script 7): [700, -2147483645] +Interface 13 child 21 (script 2): [null, -2147483645] +Interface 13 child 21 (script 7): [3] +Interface 13 child 21 (script 11): [null, -2147483645] +Interface 13 child 21 (script 16): [0] +Interface 13 child 22 (script 2): [null, -2147483645] +Interface 13 child 22 (script 7): [3, 697] +Interface 13 child 22 (script 9): [196608, 131072, 0, 0, , 36896768, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 13 child 23 (script 2): [null, -2147483645] +Interface 13 child 23 (script 7): [3, 697, -2147483645] +Interface 13 child 23 (script 12): [0, 0, 65536] +Interface 13 child 23 (script 13): [null, 0] +Interface 13 child 24 (script 2): [null, -2147483645] +Interface 13 child 24 (script 7): [3, 697, -2147483645, 4] +Interface 13 child 29 (script 2): [null, -2147483645] +Interface 13 child 29 (script 3): [45, -2147483645, 14784543] +Interface 13 child 29 (script 4): [45, -2147483645, 12547357] +Interface 13 child 29 (script 7): [699, -2147483645] +Interface 13 child 30 (script 3): [-2147483645, 14784543, null, 45, -2147483645, 12547357, 0, 16777216, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 13 child 32 (script 3): [698, -2147483645] +Interface 13 child 32 (script 16): [144128] +Interface 14 child 3 (script 1): [536, null, 44] +Interface 14 child 3 (script 3): [196608, 35061760, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 14 child 60 (script 3): [-2147483645, 14784543, null, 45, -2147483645, 12547357, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 14 child 61 (script 3): [-2147483645, 14784543, null, 45, -2147483645, 12547357, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 14 child 62 (script 3): [-2147483645, 14784543, null, 45, -2147483645, 12547357, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 14 child 63 (script 3): [-2147483645, 14784543, null, 45, -2147483645, 12547357, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 14 child 64 (script 3): [-2147483645, 14784543, null, 45, -2147483645, 12547357, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 14 child 65 (script 3): [-2147483645, 14784543, null, 45, -2147483645, 12547357, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 14 child 89 (script 3): [-2147483645, 14784543, null, 45, -2147483645, 12547357, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 27 child 8 (script 1): [1065, null, 44] +Interface 27 child 8 (script 3): [196608, 69730304, 1, 517, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 27 child 101 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 27 child 103 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 27 child 105 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 27 child 107 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 27 child 109 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 27 child 111 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 27 child 113 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 27 child 115 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 27 child 117 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 27 child 119 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 27 child 121 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 27 child 123 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 27 child 125 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 27 child 127 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 27 child 129 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 27 child 131 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 27 child 133 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 27 child 135 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 27 child 137 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 27 child 139 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 27 child 141 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 27 child 143 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 27 child 145 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 27 child 147 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 27 child 149 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 27 child 151 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 27 child 153 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 27 child 155 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 27 child 157 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 27 child 159 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 61 child 29 (script 1): [486539264, null, null, null, 44, 3997725, 539, 0, 256, 7424, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 95 child 23 (script 3): [6225921, 17359, null, 67, 6225921, 17360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 95 child 24 (script 3): [6225922, 17359, null, 67, 6225922, 17360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 95 child 25 (script 3): [6225923, 17359, null, 67, 6225923, 17360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 95 child 26 (script 3): [6225924, 17359, null, 67, 6225924, 17360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 95 child 27 (script 3): [6225925, 17359, null, 67, 6225925, 17360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 95 child 28 (script 3): [6225926, 17359, null, 67, 6225926, 17360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 95 child 29 (script 3): [6225927, 17359, null, 67, 6225927, 17360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 95 child 30 (script 3): [6225928, 17359, null, 67, 6225928, 17360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 95 child 31 (script 3): [6225929, 17359, null, 67, 6225929, 17360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 95 child 32 (script 3): [6225930, 17359, null, 67, 6225930, 17360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 95 child 33 (script 3): [6225931, 17359, null, 67, 6225931, 17360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 102 child 13 (script 1): [832, null, 44] +Interface 102 child 13 (script 3): [196608, 54460416, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 104 child 19 (script 3): [-2147483645, 16696461, null, 45, -2147483645, 16750623, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 104 child 20 (script 3): [-2147483645, 16696461, null, 45, -2147483645, 16750623, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 104 child 21 (script 3): [-2147483645, 16696461, null, 45, -2147483645, 16750623, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 104 child 22 (script 3): [-2147483645, 16696461, null, 45, -2147483645, 16750623, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 104 child 23 (script 3): [-2147483645, 16696461, null, 45, -2147483645, 16750623, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 104 child 24 (script 3): [-2147483645, 16696461, null, 45, -2147483645, 16750623, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 104 child 25 (script 3): [-2147483645, 16696461, null, 45, -2147483645, 16750623, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 104 child 26 (script 3): [-2147483645, 16696461, null, 45, -2147483645, 16750623, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 104 child 27 (script 3): [-2147483645, 16696461, null, 45, -2147483645, 16750623, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 104 child 28 (script 3): [-2147483645, 16696461, null, 45, -2147483645, 16750623, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 104 child 29 (script 3): [-2147483645, 16696461, null, 45, -2147483645, 16750623, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 104 child 30 (script 3): [-2147483645, 16696461, null, 45, -2147483645, 16750623, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 104 child 38 (script 1): [832, null, 44] +Interface 104 child 38 (script 3): [196608, 54460416, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 105 child 13 (script 1): [832, null, 44] +Interface 105 child 13 (script 3): [196608, 54460416, 1, 29, 16777216, 486539264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 105 child 14 (script 2): [null, 1] +Interface 105 child 14 (script 6): [null, 0] +Interface 105 child 14 (script 14): [283904, 72876032, null, null, 284160] +Interface 105 child 14 (script 16): [null, 0, 0, 0] +Interface 105 child 30 (script 2): [null, 6881309] +Interface 105 child 30 (script 3): [637, 6881309] +Interface 105 child 30 (script 11): [647, -2147483645, 6881313, Buy, 25, 100] +Interface 105 child 30 (script 12): [40, 6881313] +Interface 105 child 31 (script 2): [null, 6881308] +Interface 105 child 31 (script 3): [641, 6881308] +Interface 105 child 31 (script 11): [647, -2147483645, 6881313, Sell, 25, 100] +Interface 105 child 31 (script 12): [40, 6881313] +Interface 105 child 46 (script 2): [null, 6881325] +Interface 105 child 46 (script 3): [637, 6881325] +Interface 105 child 46 (script 11): [647, -2147483645, 6881329, Buy, 25, 100] +Interface 105 child 46 (script 12): [40, 6881329] +Interface 105 child 47 (script 2): [null, 6881324] +Interface 105 child 47 (script 3): [641, 6881324] +Interface 105 child 47 (script 11): [647, -2147483645, 6881329, Sell, 25, 100] +Interface 105 child 47 (script 12): [40, 6881329] +Interface 105 child 62 (script 2): [null, 6881341] +Interface 105 child 62 (script 3): [637, 6881341] +Interface 105 child 62 (script 11): [647, -2147483645, 6881345, Buy, 25, 100] +Interface 105 child 62 (script 12): [40, 6881345] +Interface 105 child 63 (script 2): [null, 6881340] +Interface 105 child 63 (script 3): [641, 6881340] +Interface 105 child 63 (script 11): [647, -2147483645, 6881345, Sell, 25, 100] +Interface 105 child 63 (script 12): [40, 6881345] +Interface 105 child 81 (script 2): [null, 6881360] +Interface 105 child 81 (script 3): [637, 6881360] +Interface 105 child 81 (script 11): [647, -2147483645, 6881364, Buy, 25, 100] +Interface 105 child 81 (script 12): [40, 6881364] +Interface 105 child 82 (script 2): [null, 6881359] +Interface 105 child 82 (script 3): [641, 6881359] +Interface 105 child 82 (script 11): [647, -2147483645, 6881364, Sell, 25, 100] +Interface 105 child 82 (script 12): [40, 6881364] +Interface 105 child 100 (script 2): [null, 6881379] +Interface 105 child 100 (script 3): [637, 6881379] +Interface 105 child 100 (script 11): [647, -2147483645, 6881383, Buy, 25, 100] +Interface 105 child 100 (script 12): [40, 6881383] +Interface 105 child 101 (script 2): [null, 6881378] +Interface 105 child 101 (script 3): [641, 6881378] +Interface 105 child 101 (script 11): [647, -2147483645, 6881383, Sell, 25, 100] +Interface 105 child 101 (script 12): [40, 6881383] +Interface 105 child 119 (script 2): [null, 6881398] +Interface 105 child 119 (script 3): [637, 6881398] +Interface 105 child 119 (script 11): [647, -2147483645, 6881402, Buy, 25, 100] +Interface 105 child 119 (script 12): [40, 6881402] +Interface 105 child 120 (script 2): [null, 6881397] +Interface 105 child 120 (script 3): [641, 6881397] +Interface 105 child 120 (script 11): [647, -2147483645, 6881402, Sell, 25, 100] +Interface 105 child 120 (script 12): [40, 6881402] +Interface 105 child 127 (script default): [null, 616, -2147483645] +Interface 105 child 127 (script 7): [591] +Interface 105 child 127 (script 8): [649, -2147483645, 6881493, Back to offer summary, 25, 300] +Interface 105 child 129 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 105 child 131 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 105 child 140 (script default): [40, 6881493] +Interface 105 child 140 (script 8): [38, -2147483645, 6881493, Current item Market Price, 25, 300] +Interface 105 child 145 (script default): [40, 6881493] +Interface 105 child 145 (script 8): [38, -2147483645, 6881493, Current item price range (Minimum/Maximum Price), 25, 300] +Interface 105 child 157 (script default): [40, 6881493] +Interface 105 child 157 (script 7): [596] +Interface 105 child 157 (script 8): [649, -2147483645, 6881493, Decrease quantity by 1, 25, 300] +Interface 105 child 158 (script default): [197120, 157184, null, 196608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 105 child 159 (script 3): [6881493, 0, 16777216, null, null, null, 649, -2147483645, 6881493, Increase quantity by 1, 25, 300, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 105 child 160 (script default): [197120, 156672, null, 196608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 105 child 161 (script default): [197120, 165120, null, 196608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 105 child 162 (script default): [40, 6881493] +Interface 105 child 162 (script 7): [598] +Interface 105 child 163 (script default): [197120, 165120, null, 196608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 105 child 164 (script default): [40, 6881493] +Interface 105 child 164 (script 7): [599] +Interface 105 child 165 (script default): [197120, 165120, null, 196608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 105 child 166 (script default): [40, 6881493] +Interface 105 child 166 (script 7): [600] +Interface 105 child 167 (script default): [197120, 165120, null, 196608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 105 child 168 (script default): [40, 6881493] +Interface 105 child 168 (script 7): [865] +Interface 105 child 169 (script default): [197120, 165120, null, 196608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 105 child 170 (script default): [40, 6881493] +Interface 105 child 170 (script 8): [649, -2147483645, 6881493, Enter custom quantity, 25, 300] +Interface 105 child 171 (script default): [40, 6881493] +Interface 105 child 171 (script 7): [604] +Interface 105 child 171 (script 8): [649, -2147483645, 6881493, Decrease price by 1, 25, 300] +Interface 105 child 172 (script default): [197120, 157184, null, 196608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 105 child 173 (script default): [40, 6881493] +Interface 105 child 173 (script 7): [605] +Interface 105 child 173 (script 8): [649, -2147483645, 6881493, Increase price by 1, 25, 300] +Interface 105 child 174 (script default): [197120, 156672, null, 196608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 105 child 175 (script default): [197120, 165120, null, 196608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 105 child 177 (script default): [40, 6881493] +Interface 105 child 177 (script 7): [606] +Interface 105 child 177 (script 8): [649, -2147483645, 6881493, Set price to item's Minimum Price, 25, 300] +Interface 105 child 178 (script default): [197120, 165120, null, 196608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 105 child 180 (script default): [40, 6881493] +Interface 105 child 180 (script 7): [607] +Interface 105 child 180 (script 8): [649, -2147483645, 6881493, Set price to item's Market Price, 25, 300] +Interface 105 child 181 (script default): [197120, 165120, null, 196608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 105 child 183 (script default): [40, 6881493] +Interface 105 child 183 (script 7): [608] +Interface 105 child 183 (script 8): [649, -2147483645, 6881493, Set price to item's Maximum Price, 25, 300] +Interface 105 child 184 (script default): [197120, 165120, null, 196608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 105 child 185 (script default): [40, 6881493] +Interface 105 child 185 (script 8): [649, -2147483645, 6881493, Enter custom price, 25, 300] +Interface 105 child 189 (script default): [40, 6881493] +Interface 105 child 190 (script 3): [-2147483645, null, 97, -2147483645, null, 653, -2147483645, 0, 393216, 42532992, 196608, null, -721337489, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, null, 300, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 105 child 193 (script default): [40, 6881493] +Interface 105 child 193 (script 8): [649, -2147483645, 6881493, Click here to search for an item to buy, 25, 300] +Interface 105 child 194 (script 2): [null, 6881416] +Interface 105 child 194 (script 4): [null, null, null, null, 665, 6881416, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 105 child 198 (script default): [40, 6881493] +Interface 105 child 198 (script 8): [649, -2147483645, 6881493, Use your inventory to select an item to sell here, 25, 300] +Interface 105 child 203 (script 2): [null, -2147483645] +Interface 105 child 203 (script 10): [649, -2147483645, 6881493, Abort offer, 25, 100] +Interface 105 child 203 (script 11): [618, -2147483645] +Interface 105 child 208 (script default): [196863, null, null, null, null, 665, -2147483645, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 105 child 210 (script default): [196863, null, null, null, null, 665, -2147483645, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 106 child 13 (script 1): [832, null, 44] +Interface 106 child 13 (script 3): [196608, 54460416, 1, 29, 16777216, 486539264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 106 child 14 (script 2): [null, 0] +Interface 106 child 125 (script default): [1175, null, 44] +Interface 106 child 125 (script 2): [196608, 76939264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 108 child 13 (script 1): [832, null, 44] +Interface 108 child 13 (script 3): [196608, 54460416, 1, 29, 16777216, 486539264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 108 child 18 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 108 child 20 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 108 child 70 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 108 child 95 (script 1): [1175, null, 44] +Interface 108 child 95 (script 3): [196608, 76939264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 109 child 13 (script 1): [832, null, 44] +Interface 109 child 13 (script 3): [196608, 54460416, 1, 29, 16777216, 486539264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 109 child 15 (script 2): [null, 0] +Interface 109 child 15 (script 3): [656] +Interface 109 child 15 (script 16): [133888, 34340864, null, null, 134656, 34537472] +Interface 109 child 15 (script 17): [null, 0] +Interface 109 child 17 (script 2): [null, -2147483645] +Interface 109 child 22 (script 2): [null, -2147483645] +Interface 109 child 27 (script 2): [null, -2147483645] +Interface 109 child 35 (script 2): [null, -2147483645] +Interface 109 child 43 (script 2): [null, -2147483645] +Interface 109 child 51 (script 2): [null, -2147483645] +Interface 110 child 13 (script 1): [832, null, 44] +Interface 110 child 13 (script 3): [196608, 54460416, 1, 29, 16777216, 486539264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 110 child 18 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 110 child 20 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 110 child 68 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 110 child 90 (script default): [1175, null, 44] +Interface 110 child 90 (script 2): [196608, 76939264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 134 child 3 (script 2): [789, -2147483645] +Interface 134 child 4 (script default): [789, -2147483645] +Interface 134 child 5 (script 2): [789, -2147483645] +Interface 134 child 6 (script 1): [789, -2147483645] +Interface 134 child 7 (script 3): [null, -2147483645, 0] +Interface 134 child 8 (script 1): [789, -2147483645] +Interface 134 child 9 (script 2): [789, -2147483645] +Interface 134 child 10 (script 3): [null, -2147483645, 0] +Interface 134 child 11 (script default): [789, -2147483645] +Interface 134 child 12 (script default): [789, -2147483645] +Interface 134 child 13 (script default): [789, -2147483645] +Interface 134 child 14 (script default): [789, -2147483645] +Interface 134 child 15 (script 2): [789, -2147483645] +Interface 134 child 16 (script default): [789, -2147483645] +Interface 134 child 17 (script 3): [null, -2147483645, 0] +Interface 134 child 18 (script 3): [null, -2147483645, 0] +Interface 134 child 19 (script 2): [789, -2147483645] +Interface 134 child 20 (script 3): [null, -2147483645, 0] +Interface 134 child 21 (script 1): [789, -2147483645] +Interface 134 child 22 (script 2): [789, -2147483645] +Interface 134 child 23 (script 3): [null, -2147483645, 0] +Interface 134 child 24 (script default): [789, -2147483645] +Interface 134 child 25 (script 2): [789, -2147483645] +Interface 134 child 26 (script 1): [789, -2147483645] +Interface 134 child 27 (script 3): [8781851, 16777215, null, 45, 8781851, 6710886, 65536, 51773440, 0, 0, , 17104896, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 1 (script 3): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 3 (script 3): [-2147483645, 8978434, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 4 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 5 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 6 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 7 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 8 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 9 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 10 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 11 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 12 (script 13): [86, -2147483644, event_opbase] +Interface 137 child 13 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 14 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 15 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 16 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 17 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 18 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 19 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 20 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 21 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 22 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 23 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 24 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 25 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 26 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 27 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 28 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 29 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 30 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 31 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 32 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 33 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 34 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 35 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 36 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 37 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 38 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 39 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 40 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 41 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 42 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 43 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 44 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 45 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 46 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 47 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 48 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 49 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 50 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 51 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 52 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 53 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 54 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 55 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 56 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 57 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 58 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 59 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 60 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 61 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 62 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 63 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 64 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 65 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 66 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 67 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 68 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 69 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 70 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 71 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 72 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 73 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 74 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 75 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 76 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 77 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 78 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 79 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 80 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 81 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 82 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 83 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 84 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 85 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 86 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 87 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 88 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 89 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 90 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 91 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 92 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 93 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 94 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 95 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 96 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 97 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 98 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 99 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 100 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 101 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 137 child 102 (script default): [0, 0, 3, 86, -2147483644, event_opbase, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 140 child 2 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 140 child 3 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 154 child 12 (script 1): [832, null, 44] +Interface 154 child 12 (script 3): [196608, 54460416, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 154 child 15 (script 2): [null, -2147483645] +Interface 154 child 15 (script 7): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 154 child 17 (script 2): [null, -2147483645] +Interface 154 child 17 (script 7): [0] +Interface 154 child 19 (script 2): [null, -2147483645] +Interface 154 child 19 (script 7): [0, 0, 0, 0, 0, 0, 0] +Interface 154 child 21 (script 2): [null, -2147483645] +Interface 154 child 21 (script 7): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 154 child 23 (script 2): [null, -2147483645] +Interface 154 child 23 (script 7): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 154 child 25 (script 2): [null, -2147483645] +Interface 154 child 25 (script 7): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 154 child 27 (script 2): [null, -2147483645] +Interface 154 child 27 (script 7): [0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 154 child 28 (script 3): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 154 child 29 (script 3): [0] +Interface 157 child 2 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 158 child 2 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 159 child 2 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 160 child 2 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 161 child 2 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 162 child 2 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 163 child 2 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 164 child 2 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 165 child 2 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 166 child 2 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 167 child 2 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 168 child 2 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 169 child 2 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 170 child 2 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 171 child 2 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 172 child 2 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 173 child 2 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 174 child 2 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 175 child 2 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 176 child 2 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 177 child 2 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 187 child 1 (script 3): [832] +Interface 187 child 1 (script 16): [5120, 1376256, 369098752, null, 6144, 1638400, *, 20381696, Z, 27131904, ?, 39190528, null, null, 184576, 59375616, null, null, 282624, 74448896] +Interface 187 child 1 (script 17): [null, 307712, 0, 0] +Interface 187 child 11 (script 1): [65536, 54722560, 65536, 54788352, 213504, 0, null, 4864, 30539776, ), 0, 0, 0, 0, 0] +Interface 188 child 2 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 8816303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 188 child 3 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 8816303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 188 child 4 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 8816303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 188 child 5 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 8816303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 188 child 6 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 8816303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 188 child 7 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 8816303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 188 child 8 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 8816303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 0 (script default): [1056964608, d, 103936, 1, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 22177137, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 16777215, null, 0, -1, 0, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 1 (script 1): [12582975, 15, 65] +Interface 192 child 1 (script 6): [Wind Strike] +Interface 192 child 1 (script 7): [null] +Interface 192 child 1 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 1, 558, 1, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 2 (script 1): [12582975, 16, 66] +Interface 192 child 2 (script 6): [Confuse, Reduces your opponent's attack by 5%, 555] +Interface 192 child 2 (script 11): [557, 2, 559] +Interface 192 child 2 (script 16): [-1] +Interface 192 child 3 (script default): [1056964608, f, 104448, 1025, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 21850478, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 16777215, null, 0, -1, 0, -1, 0, -1, 0, 16, 6, -2147483645, 12582975, 358, 408, 4, Enchant Crossbow Bolt, Minimum level 4 Magic Multiple other requirements, -1, 0, -1, 0, -1, 0, -1, 0, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 4 (script 1): [12582975, 17, 67] +Interface 192 child 4 (script 6): [Water Strike, A basic Water missile, 555, 1, 556] +Interface 192 child 4 (script 11): [558] +Interface 192 child 4 (script 16): [-1] +Interface 192 child 5 (script 1): [12582975, 18, 68] +Interface 192 child 5 (script 6): [Lvl-1 Enchant, For use on sapphire jewellery, 555, 1, 564, 1, -1] +Interface 192 child 5 (script 13): [null, null, null, 0, 16, 6, -2147483645, 12582975, 18, 68, 7, Lvl-1 Enchant, For use on sapphire jewellery, 555, 1, 564, 1, -1, 0, -1, 0, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 6 (script 1): [12582975, 19, 69] +Interface 192 child 6 (script 6): [Earth Strike, A basic Earth missile, 557, 2, 556, 1, 558, 1, -1] +Interface 192 child 7 (script 1): [12582975, 20, 70] +Interface 192 child 7 (script 6): [Weaken, Reduces your opponent's
strength by 5%, 555, 3, 557, 2, 559, 1, -1, 0, 0] +Interface 192 child 8 (script 1): [12582975, 21, 71] +Interface 192 child 8 (script 6): [Fire Strike, A basic Fire missile, 554, 3, 556, 2, 558, 1, -1, 0, 0, 0, 0] +Interface 192 child 9 (script default): [1056964608, 369098752, 1207959552, 251740783, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 21194849, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 2, 555, 2, 561, 1, -1, 0, 16, 6, -2147483645, 12582975, 22, 72, 15, Bones to Bananas, Changes all held bones into bananas, 557, 2, 555, 2, 561, 1, -1, 0, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 10 (script 1): [12582975, 23, 73] +Interface 192 child 10 (script 6): [Wind Bolt, A low level Air missile, 556, 2, 562, 1, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 11 (script 1): [12582975, 24, 74] +Interface 192 child 11 (script 6): [Curse, Reduces your opponent's
defence by 5%, 555, 2, 557, 3, 559, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 12 (script 1): [12582975, 319, 369] +Interface 192 child 12 (script 6): [Bind, Holds your opponent for 5 seconds, 557, 3, 555, 3, 561, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 13 (script 1): [12582975, 25, 75] +Interface 192 child 13 (script 6): [Low Level Alchemy, Converts an item into gold, 554, 3, 561, 1, -1, 0, -1, 0, 16, 6, -2147483645, 12582975, 25, 75, 21, Low Level Alchemy, Converts an item into gold, 554, 3] +Interface 192 child 13 (script 10): [null, 1] +Interface 192 child 13 (script 12): [null, null, null, 0, -1, 0, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 14 (script 1): [12582975, 26, 76] +Interface 192 child 14 (script 6): [Water Bolt, A low level Water missile, 555, 2, 556, 2, 562, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 15 (script default): [1056964608, 452984832, 1291845632, 419518049, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 22308204, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 1, 556, 3, 563, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 16 (script 1): [12582975, 28, 78] +Interface 192 child 16 (script 6): [Lvl-2 Enchant, For use on emerald jewellery, 556, 3, 564, 1, -1, 0, -1, 0, 16, 6, -2147483645, 12582975, 28, 78, 27, Lvl-2 Enchant, For use on emerald jewellery, 556, 3, 564, 1, -1, 0, -1, 0] +Interface 192 child 16 (script 19): [279552] +Interface 192 child 17 (script 1): [12582975, 29, 79] +Interface 192 child 17 (script 6): [Earth Bolt, A low level Earth missile, 557, 3, 556, 2, 562, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 18 (script default): [1056964608, 503316480, 1342177280, 520178805, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 22308204, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 1, 556, 3, 563, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 19 (script 1): [12582975, 31, 81] +Interface 192 child 19 (script 6): [Telekinetic Grab, Take an item you can see but can't reach, 556, 1, 563, 1, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 20 (script 1): [12582975, 32, 82] +Interface 192 child 20 (script 6): [Fire Bolt, A low level Fire missile, 554, 4, 556, 3, 562, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 21 (script default): [1056964608, 553648128, 1392508928, 620840545, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 22308204, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 1, 556, 3, 563, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 22 (script 1): [12582975, 34, 84] +Interface 192 child 22 (script 6): [Crumble Undead, Hits skeletons, ghosts, shades & zombies hard, 557, 2, 556, 2, 562, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 23 (script default): [1056964608, c, 103680, 10241, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 22308204, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 1, 556, 1, 557, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 24 (script 1): [12582975, 35, 85] +Interface 192 child 24 (script 6): [Wind Blast, A medium level Air missile, 556, 3, 560, 1, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 25 (script 1): [12582975, 36, 86] +Interface 192 child 25 (script 6): [Superheat Item, Smelt ore without a furnace, 554, 4, 561, 1, -1, 0, -1, 0, 16, 6, -2147483645, 12582975, 36, 86, 43, Superheat Item, Smelt ore without a furnace, 554, 4, 561, 1, -1, 0, -1, 0, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 26 (script default): [1056964608, 620756992, 1459617792, 755057505, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 22308204, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 5, 563, 1, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 27 (script 1): [12582975, 38, 88] +Interface 192 child 27 (script 6): [Water Blast, A medium level Water missile, 555, 3, 556, 3, 560, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 28 (script 1): [12582975, 39, 89] +Interface 192 child 28 (script 6): [Lvl-3 Enchant, For use on ruby jewellery, 554, 5, 564, 1, -1, 0, -1, 0, 16, 6, -2147483645, 12582975, 39, 89, 49, Lvl-3 Enchant, For use on ruby jewellery, 554, 5, 564, 1, -1, 0, -1, 0, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 29 (script 1): [12582975, 53, 103] +Interface 192 child 29 (script 6): [Iban Blast, Summons the wrath of Iban, 554, 5, 560, 1, 1409, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 30 (script 1): [12582975, 320, 370] +Interface 192 child 30 (script 6): [Snare, Holds your opponent for 10 seconds, 557, 4, 555, 4, 561, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 31 (script 1): [12582975, 324, 374] +Interface 192 child 31 (script 6): [Magic Dart, A magic dart of slaying, 4170, 1, 560, 1, 558, 4, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 32 (script default): [1056964608, 905969664, 1744830464, 855720306, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 22308204, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 2, 563, 2, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 33 (script 1): [12582975, 40, 90] +Interface 192 child 33 (script 6): [Earth Blast, A medium level Earth missile, 557, 4, 556, 3, 560, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 34 (script 1): [12582975, 41, 91] +Interface 192 child 34 (script 6): [High Level Alchemy, Converts an item into more gold, 554, 5, 561, 1, -1, 0, -1, 0, 16, 6, -2147483645, 12582975, 41, 91, 55, High Level Alchemy, Converts an item into more gold, 554, 5, 561, 1, -1, 0, -1, 0, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 35 (script 1): [12582975, 42, 92] +Interface 192 child 35 (script 6): [Charge Water Orb, Needs to be cast on a water obelisk, 555, 30, 564, 3, 567, 1, -1, 0, 16, 6, -2147483645, 12582975, 42, 92, 56, Charge Water Orb, Needs to be cast on a water obelisk, 555, 30, 564, 3, 567, 1, -1, 0, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 36 (script 1): [12582975, 43, 93] +Interface 192 child 36 (script 6): [Lvl-4 Enchant, For use on diamond jewellery, 557, 10, 564, 1, -1, 0, -1, 0, 16, 6, -2147483645, 12582975, 43, 93, 57, Lvl-4 Enchant, For use on diamond jewellery, 557, 10, 564, 1, -1, 0, -1, 0, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 37 (script default): [1056964608, 922746880, 1761607680, 973166433, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 22308204, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 2, 563, 2, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 38 (script 1): [12582975, 44, 94] +Interface 192 child 38 (script 6): [Fire Blast, A medium level Fire missile, 554, 5, 556, 4, 560, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 39 (script 1): [12582975, 45, 95] +Interface 192 child 39 (script 6): [Charge Earth Orb, Needs to be cast on an earth obelisk, 557, 30, 564, 3, 567, 1, -1, 0, 16, 6, -2147483645, 12582975, 45, 95, 60, Charge Earth Orb, Needs to be cast on an earth obelisk, 557, 30, 564, 3, 567, 1, -1, 0, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 40 (script default): [1056964608, b, 103424, 15361, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 22312306, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 2, 555, 4, 557, 4, -1, 0, 16, 6, -2147483645, 12582975, 354, 404, 60, Bones to Peaches, Turns Bones into Peaches, 561, 2, 555, 4, 557, 4, -1, 0, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 41 (script 1): [12582975, 61, 111] +Interface 192 child 41 (script 6): [Saradomin strike, Summons the power of Saradomin, 554, 2, 565, 2, 556, 4, 2415, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 42 (script 1): [12582975, 60, 110] +Interface 192 child 42 (script 6): [Claws of Guthix, Summons the power of Guthix, 554, 1, 565, 2, 556, 4, 8843, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 43 (script 1): [12582975, 59, 109] +Interface 192 child 43 (script 6): [Flames of Zamorak, Summons the power of Zamorak, 554, 4, 565, 2, 556, 1, 2417, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 44 (script default): [1056964608, C, 95488, 15617, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 22308204, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 2, 563, 2, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 45 (script 1): [12582975, 46, 96] +Interface 192 child 45 (script 6): [Wind Wave, A high level Air missile, 556, 5, 565, 1, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 46 (script 1): [12582975, 47, 97] +Interface 192 child 46 (script 6): [Charge Fire Orb, Needs to be cast on a fire obelisk, 554, 30, 564, 3, 567, 1, -1, 0, 16, 6, -2147483645, 12582975, 47, 97, 63, Charge Fire Orb, Needs to be cast on a fire obelisk, 554, 30, 564, 3, 567, 1, -1, 0, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 47 (script default): [1056964608, e, 104192, 16385, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 22308204, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 2, 555, 2, 563, 2, 1963, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 48 (script 1): [12582975, 48, 98] +Interface 192 child 48 (script 6): [Water Wave, A high level Water missile, 555, 7, 556, 5, 565, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 49 (script 1): [12582975, 49, 99] +Interface 192 child 49 (script 6): [Charge Air Orb, Needs to be cast on an air obelisk, 556, 30, 564, 3, 567, 1, -1, 0, 16, 6, -2147483645, 12582975, 49, 99, 66, Charge Air Orb, Needs to be cast on an air obelisk, 556, 30, 564, 3, 567, 1, -1, 0, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 50 (script 1): [12582975, 56, 106] +Interface 192 child 50 (script 6): [Vulnerability, Reduces your opponent's defence by 10%, 557, 5, 555, 5, 566, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 51 (script 1): [12582975, 50, 100] +Interface 192 child 51 (script 6): [Lvl-5 Enchant, For use on dragonstone jewellery, 555, 15, 557, 15, 564, 1, -1, 0, 16, 6, -2147483645, 12582975, 50, 100, 68, Lvl-5 Enchant, For use on dragonstone jewellery, 555, 15, 557, 15, 564, 1, -1, 0, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 52 (script 1): [12582975, 51, 101] +Interface 192 child 52 (script 6): [Earth Wave, A high level Earth missile, 557, 7, 556, 5, 565, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 53 (script 1): [12582975, 57, 107] +Interface 192 child 53 (script 6): [Enfeeble, Reduces your opponent's strength by 10%, 557, 8, 555, 8, 566, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 54 (script 1): [12582975, 349, 399] +Interface 192 child 54 (script 6): [Teleother Lumbridge, Teleports target to Lumbridge, 566, 1, 563, 1, 557, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 55 (script 1): [12582975, 52, 102] +Interface 192 child 55 (script 6): [Fire Wave, A high level Fire missile, 554, 7, 556, 5, 565, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 56 (script 1): [12582975, 321, 371] +Interface 192 child 56 (script 6): [Entangle, Holds your opponent for 15 seconds, 557, 5, 555, 5, 561, 4, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 57 (script 1): [12582975, 58, 108] +Interface 192 child 57 (script 6): [Stun, Reduces your opponent's attack by 10%, 557, 12, 555, 12, 566, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 58 (script default): [1056964608, B, 95232, 20481, null, null, null, null, null, null, 22308205, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 3, 565, 3, 556, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 59 (script 1): [12582975, 350, 400] +Interface 192 child 59 (script 6): [Teleother Falador, Teleports target to Falador, 566, 1, 555, 1, 563, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 60 (script default): [1056964608, `, 102912, 8193, null, null, null, null, null, null, null, null, null, null, null, null, null, 22308204, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 1, 554, 1, 563, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 61 (script 1): [12582975, 353, 403] +Interface 192 child 61 (script 6): [Lvl-6 Enchant, For use on onyx jewellery, 557, 20, 554, 20, 564, 1, -1, 0, 16, 6, -2147483645, 12582975, 353, 403, 87, Lvl-6 Enchant, For use on onyx jewellery, 557, 20, 554, 20, 564, 1, -1, 0, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 192 child 62 (script 1): [12582975, 351, 401] +Interface 192 child 62 (script 6): [Teleother Camelot, Teleports target to Camelot, 566, 2, 563, 1, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 193 child 0 (script 1): [12648473, 325, 375] +Interface 193 child 0 (script 6): [Ice Rush, A single target ice attack, 562, 2, 560, 2, 555, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 193 child 1 (script 1): [12648473, 327, 377] +Interface 193 child 1 (script 6): [Ice Blitz, A single target strong ice attack, 560, 2, 565, 2, 555, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 193 child 2 (script 1): [12648473, 326, 376] +Interface 193 child 2 (script 6): [Ice Burst, A multi-target ice attack, 562, 4, 560, 2, 555, 4, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 193 child 3 (script 1): [12648473, 328, 378] +Interface 193 child 3 (script 6): [Ice Barrage, A multi-target strong ice attack, 560, 4, 565, 2, 555, 6, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 193 child 4 (script 1): [12648473, 333, 383] +Interface 193 child 4 (script 6): [Blood Rush, A single target blood attack, 562, 2, 560, 2, 565, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 193 child 5 (script 1): [12648473, 335, 385] +Interface 193 child 5 (script 6): [Blood Blitz, A single target strong blood attack, 560, 2, 565, 4, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 193 child 6 (script 1): [12648473, 334, 384] +Interface 193 child 6 (script 6): [Blood Burst, A multi-target blood attack, 562, 4, 560, 2, 565, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 193 child 7 (script 1): [12648473, 336, 386] +Interface 193 child 7 (script 6): [Blood Barrage, A multi-target strong blood attack, 560, 4, 565, 4, 566, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 193 child 8 (script 1): [12648473, 329, 379] +Interface 193 child 8 (script 6): [Smoke Rush, A single target smoke attack, 562, 2, 560, 2, 554, 1, 556, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 193 child 9 (script 1): [12648473, 331, 381] +Interface 193 child 9 (script 6): [Smoke Blitz, A single target strong smoke attack, 560, 2, 565, 2, 554, 2, 556, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 193 child 10 (script 1): [12648473, 330, 380] +Interface 193 child 10 (script 6): [Smoke Burst, A multi-target smoke attack, 562, 4, 560, 2, 554, 2, 556, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 193 child 11 (script 1): [12648473, 332, 382] +Interface 193 child 11 (script 6): [Smoke Barrage, A multi-target strong smoke attack, 560, 4, 565, 2, 554, 4, 556, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 193 child 12 (script 1): [12648473, 337, 387] +Interface 193 child 12 (script 6): [Shadow Rush, A single target shadow attack, 562, 2, 560, 2, 556, 1, 566, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 193 child 13 (script 1): [12648473, 339, 389] +Interface 193 child 13 (script 6): [Shadow Blitz, A single target strong shadow attack, 560, 2, 565, 2, 556, 2, 566, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 193 child 14 (script 1): [12648473, 338, 388] +Interface 193 child 14 (script 6): [Shadow Burst, A multi-target shadow attack, 562, 4, 560, 2, 556, 1, 566, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 193 child 15 (script 1): [12648473, 340, 390] +Interface 193 child 15 (script 6): [Shadow Barrage, A multi-target strong shadow attack, 560, 4, 565, 2, 556, 4, 566, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 193 child 16 (script default): [419430400, U, 100096, 13825, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 21045364, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 2, 554, 1, 556, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 193 child 17 (script default): [419430400, V, 100352, 15361, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 21045364, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 2, 566, 1, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 193 child 18 (script default): [419430400, W, 100608, 16897, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 21045364, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 2, 565, 1, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 193 child 19 (script default): [419430400, X, 100864, 18433, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 21045364, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 2, 555, 4, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 193 child 20 (script default): [419430400, Y, 101120, 19969, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 21045364, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 2, 554, 3, 556, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 193 child 21 (script default): [419430400, Z, 101376, 21505, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 21045364, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 2, 566, 2, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 193 child 22 (script default): [419430400, [, 101632, 23041, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 21045364, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 2, 565, 2, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 193 child 23 (script default): [419430400, \, 101888, 24577, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 21045364, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 2, 555, 8, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 193 child 24 (script default): [419430400, d, 103936, 1, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 22177137, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 16777215, null, 0, -1, 0, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 197 child 15 (script 1): [540, null, 44] +Interface 197 child 15 (script 3): [196608, 35323904, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 239 child 6 (script 1): [538, null, 44] +Interface 239 child 6 (script 3): [196608, 35192832, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 252 child 1 (script 1): [538] +Interface 252 child 1 (script 2): [44, 16515073, 537] +Interface 252 child 1 (script 11): [29] +Interface 253 child 1 (script 1): [16777216, null, null, null, 44, 16580609, 537, 0, 256, 7424, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 254 child 2 (script 1): [33554432, null, null, null, 44, 16646146, 537, 0, 256, 7424, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 255 child 1 (script 1): [16777216, null, null, null, 44, 16711681, 537, 0, 256, 7424, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 259 child 0 (script 3): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 259 child 13 (script 3): [16973837, 16777215, null, 59, 0, 65536, 3801088, 0, 0, null, 256000, 65601536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 259 child 14 (script 3): [16973838, 16777215, null, 59, 1, 65536, 3801088, 0, 0, null, 274176, 70254592, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 260 child 42 (script 4): [60] +Interface 260 child 42 (script 17): [131584] +Interface 260 child 45 (script 4): [61] +Interface 260 child 45 (script 17): [131840] +Interface 260 child 46 (script 1): [832, null, 44] +Interface 260 child 46 (script 3): [196608, 54460416, 0, 16777216, 486539264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 265 child 0 (script default): [null, 1] +Interface 265 child 0 (script 4): [null, 0] +Interface 265 child 0 (script 12): [293632] +Interface 266 child 0 (script 2): [null, 17432577] +Interface 266 child 0 (script 4): [null] +Interface 266 child 0 (script 6): [3, 663] +Interface 266 child 0 (script 8): [null] +Interface 266 child 0 (script 10): [17432578] +Interface 267 child 100 (script 1): [832, null, 44, 17498212, 831, 0, 16777216, 486539264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 269 child 0 (script 2): [null, 1] +Interface 269 child 0 (script 6): [null, 0] +Interface 269 child 0 (script 14): [297728] +Interface 269 child 1 (script default): [742] +Interface 269 child 1 (script 13): [297984] +Interface 269 child 44 (script 1): [542, null, 44] +Interface 269 child 44 (script 3): [196608, 35454976, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 0 (script 3): [1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 14 (script 3): [17956878, 16777215, null, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 15 (script default): [null, null, 538976256, null, null, null, 538976256, null, null, null, 538976256, 0, null, 45, 17956879, 16777215, null, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 16 (script default): [null, null, null, 538976288, 538976288, 538976288, 538976288, 538976288, 0, 50331648, 754974994, 268435711, null, null, null, 8, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 17 (script default): [null, null, null, null, 538976288, null, 538976288, null, 538976288, null, 538976288, null, 538976288, null, 0, 50331648, 754974994, 285212927, null, null, null, 8, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 18 (script default): [null, null, null, null, null, 538976288, null, null, 538976288, null, null, 538976288, null, null, 538976288, null, null, 538976288, null, null, 0, 50331648, 754974994, 301990143, null, null, null, 8, 4, 0, 0, 0] +Interface 274 child 19 (script default): [null, null, null, null, null, null, 538976288, null, null, null, 538976288, null, null, null, 538976288, null, null, null, 538976288, null, null, null, 538976288, null, null, null, 538976288, null, null, null, 0, 50331648] +Interface 274 child 19 (script 2): [17956883, 16777215, null, 8, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 20 (script default): [null, null, null, null, null, null, null, 538976288, null, null, null, null, 538976288, null, null, null, null, 538976288, null, null, null, null, 538976288, null, null, null, null, 538976288, null, null, null, null] +Interface 274 child 20 (script 2): [null, null, null, null, null, null, null, 0, 50331648, 754974994, 335544575, null, null, null, 8, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 21 (script default): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, 538976288, null, null, null, null, null, 538976288, null, null, null, null, null, 538976288, null, null, null, null, null] +Interface 274 child 21 (script 2): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, 0, 50331648, 754974994, 352321791, null, null, null, 8, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 22 (script default): [null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, 538976288, null] +Interface 274 child 22 (script 1): [null, null, null, null, 538976288, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, 0, 50331648, 754974994, 369099007, null, null, null, 8, 8, 0, 0, 0, 0, 0] +Interface 274 child 23 (script default): [null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, 538976288, null, null, null, null, null] +Interface 274 child 23 (script 1): [null, 538976288, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, 0, 50331648, 754974994, 385876223, null, null, null] +Interface 274 child 23 (script 6): [9, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 24 (script default): [null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, 538976288, null, null] +Interface 274 child 24 (script 1): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null] +Interface 274 child 24 (script 8): [45, 17956888, 16777215] +Interface 274 child 24 (script 9): [8, 10] +Interface 274 child 25 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null] +Interface 274 child 25 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null] +Interface 274 child 25 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 419430655, null, null, null, 8, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 26 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null] +Interface 274 child 26 (script 1): [null, null, 538976288, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null] +Interface 274 child 26 (script 2): [null, null, 538976288, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 436207871, null, null, null, 8, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 27 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null] +Interface 274 child 27 (script 1): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null] +Interface 274 child 27 (script 2): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 452985087, null, null, null, 8, 13, 0, 0, 0] +Interface 274 child 28 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null] +Interface 274 child 28 (script 1): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 28 (script 2): [null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 469762303, null] +Interface 274 child 28 (script 3): [null, 8, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 29 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null] +Interface 274 child 29 (script 1): [null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null] +Interface 274 child 29 (script 2): [null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 29 (script 3): [null, 0, 50331648, 754974994, 486539519, null, null, null, 8, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 30 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 30 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 30 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 30 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 503316735, null, null, null, 8, 16, 0, 0, 0, 0, 0, 0] +Interface 274 child 31 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 31 (script 1): [null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 31 (script 2): [538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 31 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 520093951, null, null, null, 8, 17, 0, 0, 0, 0, 0] +Interface 274 child 32 (script default): [null, null, null, 538976288, 538976288, 538976288, 538976288, 538976288, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 33 (script 3): [17956897, 16777215, null, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 34 (script default): [null, null, null, null, null, null, 538976288, null, null, null, 538976288, null, null, null, 538976288, null, null, null, 538976288, null, null, null, 538976288, null, null, null, 538976288, null, null, null, 0, 50331648] +Interface 274 child 34 (script 2): [17956898, 16777215, null, 9, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 35 (script default): [null, null, null, null, null, null, null, 538976288, null, null, null, null, 538976288, null, null, null, null, 538976288, null, null, null, null, 538976288, null, null, null, null, 538976288, null, null, null, null] +Interface 274 child 35 (script 2): [null, null, null, null, null, null, null, 0, 50331648, 754974994, 587202815, null, null, null, 9, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 36 (script default): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, 538976288, null, null, null, null, null, 538976288, null, null, null, null, null, 538976288, null, null, null, null, null] +Interface 274 child 36 (script 2): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, 0, 50331648, 754974994, 603980031, null, null, null, 9, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 37 (script default): [null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, 538976288, null] +Interface 274 child 37 (script 1): [null, null, null, null, 538976288, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, 0, 50331648, 754974994, 620757247, null, null, null, 9, 4, 0, 0, 0, 0, 0] +Interface 274 child 38 (script default): [null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, 538976288, null, null, null, null, null] +Interface 274 child 38 (script 1): [null, 538976288, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, 0, 50331648, 754974994, 637534463, null, null, null] +Interface 274 child 38 (script 6): [5, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 39 (script default): [null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, 538976288, null, null] +Interface 274 child 39 (script 1): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null] +Interface 274 child 39 (script 8): [45, 17956903, 16777215] +Interface 274 child 39 (script 9): [9, 6] +Interface 274 child 40 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null] +Interface 274 child 40 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null] +Interface 274 child 40 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 671088895, null, null, null, 9, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 41 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null] +Interface 274 child 41 (script 1): [null, null, 538976288, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null] +Interface 274 child 41 (script 2): [null, null, 538976288, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 687866111, null, null, null, 9, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 42 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null] +Interface 274 child 42 (script 1): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null] +Interface 274 child 42 (script 2): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 704643327, null, null, null, 9, 9, 0, 0, 0] +Interface 274 child 43 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null] +Interface 274 child 43 (script 1): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 43 (script 2): [null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 721420543, null] +Interface 274 child 43 (script 3): [null, 9, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 44 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null] +Interface 274 child 44 (script 1): [null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null] +Interface 274 child 44 (script 2): [null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 44 (script 3): [null, 0, 50331648, 754974994, 738197759, null, null, null, 9, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 45 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 45 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 45 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 45 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 754974975, null, null, null, 9, 12, 0, 0, 0, 0, 0, 0] +Interface 274 child 46 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 46 (script 1): [null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 46 (script 2): [538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 46 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 771752191, null, null, null, 9, 13, 0, 0, 0, 0, 0] +Interface 274 child 47 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 47 (script 1): [null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 47 (script 2): [null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 47 (script 3): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 788529407, null, null, null, 9, 14, 0] +Interface 274 child 48 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 48 (script 1): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null] +Interface 274 child 48 (script 2): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null] +Interface 274 child 48 (script 3): [null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994] +Interface 274 child 48 (script 5): [16777215, null, 9, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 49 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 49 (script 1): [null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null] +Interface 274 child 49 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288] +Interface 274 child 49 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 49 (script 4): [null, null, null, 0, 50331648, 754974994, 822083839, null, null, null, 9, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 50 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null] +Interface 274 child 50 (script 1): [null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null] +Interface 274 child 50 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 50 (script 3): [null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null] +Interface 274 child 50 (script 4): [null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 838861055, null, null, null, 9, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 51 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null] +Interface 274 child 51 (script 1): [null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 51 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null] +Interface 274 child 51 (script 4): [null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 51 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 855638271, null, null, null, 9, 18] +Interface 274 child 52 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null] +Interface 274 child 52 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 52 (script 2): [null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null] +Interface 274 child 52 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 52 (script 4): [null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 872415487, null, null, null, 9] +Interface 274 child 52 (script 9): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 53 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null] +Interface 274 child 53 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 53 (script 2): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null] +Interface 274 child 53 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 53 (script 4): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0] +Interface 274 child 53 (script 6): [45, 17956917, 16777215] +Interface 274 child 53 (script 7): [9, 20] +Interface 274 child 54 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null] +Interface 274 child 54 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 54 (script 2): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 54 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null] +Interface 274 child 54 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 54 (script 6): [null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 905969919, null, null, null, 9, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 55 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null] +Interface 274 child 55 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 55 (script 2): [null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 55 (script 3): [null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null] +Interface 274 child 55 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 55 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 922747135, null, null, null, 9, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 56 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null] +Interface 274 child 56 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 56 (script 2): [null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 56 (script 3): [null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null] +Interface 274 child 56 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 56 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 939524351, null, null, null, 9, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 57 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null] +Interface 274 child 57 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 57 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 57 (script 3): [null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 57 (script 4): [538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null] +Interface 274 child 57 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 956301567, null, null, null, 9, 24, 0, 0, 0, 0] +Interface 274 child 58 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null] +Interface 274 child 58 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null] +Interface 274 child 58 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 58 (script 3): [null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 58 (script 4): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 58 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994] +Interface 274 child 58 (script 8): [16777215, null, 9, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 59 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null] +Interface 274 child 59 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null] +Interface 274 child 59 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 59 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 59 (script 4): [null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 59 (script 5): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 59 (script 6): [0, 50331648, 754974994, 989855999, null, null, null, 9, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 60 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288] +Interface 274 child 60 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null] +Interface 274 child 60 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null] +Interface 274 child 60 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 60 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 60 (script 5): [null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 60 (script 6): [null, null, null, null, null, null, null, 0, 50331648, 754974994, 1006633215, null, null, null, 9, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 61 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 61 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 61 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 61 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 61 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 61 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 61 (script 12): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 61 (script 19): [45, 17956925, 16777215] +Interface 274 child 62 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 62 (script 1): [538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288] +Interface 274 child 62 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null] +Interface 274 child 62 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null] +Interface 274 child 62 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null] +Interface 274 child 62 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null] +Interface 274 child 62 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 1040187647, null, null, null, 9, 29, 0, 0] +Interface 274 child 63 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 63 (script 1): [null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 63 (script 2): [538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 63 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 63 (script 5): [null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 63 (script 6): [538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 63 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 63 (script 9): [null, 0, 50331648, 754974994, 1056964863, null, null, null, 9, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 64 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 64 (script 1): [null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 64 (script 2): [null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 64 (script 3): [null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 64 (script 4): [null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 64 (script 5): [null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 64 (script 6): [null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 64 (script 7): [null, null, 0, 50331648, 754974994, 1073742079, null, null, null, 9, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 65 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 65 (script 1): [null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 65 (script 2): [null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 65 (script 3): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 65 (script 4): [null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 65 (script 5): [null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 65 (script 6): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 65 (script 7): [null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 1090519295, null, null, null, 9, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 66 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 66 (script 1): [null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 66 (script 2): [null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 66 (script 3): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 66 (script 4): [null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 66 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 66 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 66 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 1107296511, null, null, null, 9, 33, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 67 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 67 (script 1): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 67 (script 2): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 67 (script 3): [null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 67 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 67 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 67 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 67 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 1124073727, null, null, null, 9, 34] +Interface 274 child 68 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 68 (script 1): [null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 68 (script 2): [null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 68 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 68 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 68 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null] +Interface 274 child 68 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null] +Interface 274 child 68 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648] +Interface 274 child 68 (script 9): [17956932, 16777215, null, 9, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 69 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 69 (script 1): [null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 69 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 69 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 69 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null] +Interface 274 child 69 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null] +Interface 274 child 69 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 69 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 69 (script 9): [null, null, null, null, null, null, null, 0, 50331648, 754974994, 1157628159, null, null, null, 9, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 70 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 70 (script 1): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 70 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 70 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 70 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null] +Interface 274 child 70 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 70 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 70 (script 8): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 70 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 1174405375, null, null, null, 9, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 71 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 71 (script 1): [null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 71 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 71 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null] +Interface 274 child 71 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null] +Interface 274 child 71 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 71 (script 6): [null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 71 (script 7): [null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 71 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 1191182591, null, null, null, 9, 38, 0, 0, 0, 0, 0] +Interface 274 child 72 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 72 (script 1): [null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 72 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 72 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null] +Interface 274 child 72 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 72 (script 5): [null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 72 (script 6): [null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 72 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 72 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 1207959807, null, null, null] +Interface 274 child 72 (script 13): [39, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 73 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 73 (script 1): [null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 73 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 73 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null] +Interface 274 child 73 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 73 (script 5): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 73 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 73 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null] +Interface 274 child 73 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 73 (script 15): [45, 17956937, 16777215] +Interface 274 child 73 (script 16): [9, 40] +Interface 274 child 74 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 74 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 74 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null] +Interface 274 child 74 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 74 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 74 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 74 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null] +Interface 274 child 74 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 74 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 74 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 1241514239, null, null, null, 9, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 75 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 75 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 75 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null] +Interface 274 child 75 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 75 (script 4): [null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 75 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 75 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null] +Interface 274 child 75 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 75 (script 8): [null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 75 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 1258291455, null, null, null, 9, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 76 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 76 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 76 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null] +Interface 274 child 76 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 76 (script 4): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 76 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 76 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null] +Interface 274 child 76 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 76 (script 8): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 76 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 1275068671, null, null, null, 9, 43, 0, 0, 0] +Interface 274 child 77 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 77 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 77 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null] +Interface 274 child 77 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 77 (script 4): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 77 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 77 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 77 (script 7): [null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 77 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 77 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 1291845887, null] +Interface 274 child 77 (script 10): [null, 9, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 78 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 78 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 78 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null] +Interface 274 child 78 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 78 (script 4): [null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 78 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null] +Interface 274 child 78 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 78 (script 7): [null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 78 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 78 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 78 (script 10): [null, 0, 50331648, 754974994, 1308623103, null, null, null, 9, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 79 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 79 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 79 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 79 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 79 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 79 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 79 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 79 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 79 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 79 (script 12): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 79 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 1325400319, null, null, null, 9, 46, 0, 0, 0, 0, 0, 0] +Interface 274 child 80 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 80 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 80 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 80 (script 3): [null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 80 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 80 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 80 (script 6): [538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 80 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 80 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 80 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 80 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 1342177535, null, null, null, 9, 47, 0, 0, 0, 0, 0] +Interface 274 child 81 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 81 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 81 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 81 (script 3): [null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 81 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 81 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 81 (script 6): [null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 81 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 81 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 81 (script 9): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 81 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 1358954751, null, null, null, 9, 48, 0] +Interface 274 child 82 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 82 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 82 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 82 (script 3): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 82 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null] +Interface 274 child 82 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 82 (script 6): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 82 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null] +Interface 274 child 82 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 82 (script 9): [null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 82 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994] +Interface 274 child 82 (script 12): [16777215, null, 9, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 83 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 83 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 83 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 83 (script 3): [null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 83 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null] +Interface 274 child 83 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 83 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 83 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288] +Interface 274 child 83 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 83 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 83 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 83 (script 11): [null, null, null, 0, 50331648, 754974994, 1392509183, null, null, null, 9, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 84 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 84 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null] +Interface 274 child 84 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 84 (script 3): [null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 84 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null] +Interface 274 child 84 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 84 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 84 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 84 (script 8): [null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 84 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null] +Interface 274 child 84 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 84 (script 11): [null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 1409286399, null, null, null, 9, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 85 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 85 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null] +Interface 274 child 85 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 85 (script 3): [null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 85 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 85 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 85 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null] +Interface 274 child 85 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 85 (script 9): [null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 85 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 85 (script 12): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 85 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 1426063615, null, null, null, 9, 52] +Interface 274 child 86 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 86 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null] +Interface 274 child 86 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 86 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 86 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 86 (script 5): [null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 86 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null] +Interface 274 child 86 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 86 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 86 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 86 (script 10): [null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 86 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 1442840831, null, null, null, 9] +Interface 274 child 86 (script 16): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 87 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 87 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null] +Interface 274 child 87 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 87 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 87 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 87 (script 5): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 87 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null] +Interface 274 child 87 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 87 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 87 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 87 (script 10): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 87 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0] +Interface 274 child 87 (script 13): [45, 17956951, 16777215] +Interface 274 child 87 (script 14): [9, 54] +Interface 274 child 88 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 88 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null] +Interface 274 child 88 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 88 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 88 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 88 (script 5): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 88 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 88 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 88 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null] +Interface 274 child 88 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 88 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 88 (script 12): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 88 (script 13): [null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 1476395263, null, null, null, 9, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 89 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 89 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null] +Interface 274 child 89 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 89 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 89 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 89 (script 5): [null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 89 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 89 (script 7): [null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 89 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null] +Interface 274 child 89 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 89 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 89 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 89 (script 12): [null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 1493172479, null, null, null, 9, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 90 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 90 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null] +Interface 274 child 90 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 90 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 90 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 90 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 90 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 90 (script 7): [null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 90 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 90 (script 9): [538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 90 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null] +Interface 274 child 90 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 90 (script 12): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 1509949695, null, null, null, 9, 57, 0, 0, 0, 0] +Interface 274 child 91 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 91 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null] +Interface 274 child 91 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 91 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null] +Interface 274 child 91 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 91 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 91 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 91 (script 7): [null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 91 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 91 (script 9): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 91 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 91 (script 12): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 91 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994] +Interface 274 child 91 (script 15): [16777215, null, 9, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 92 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 92 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null] +Interface 274 child 92 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 92 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null] +Interface 274 child 92 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 92 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 92 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 92 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 92 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 92 (script 9): [null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 92 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 92 (script 11): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 92 (script 12): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 92 (script 13): [0, 50331648, 754974994, 1543504127, null, null, null, 9, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 93 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 93 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288] +Interface 274 child 93 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 93 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null] +Interface 274 child 93 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 93 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null] +Interface 274 child 93 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 93 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 93 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 93 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 93 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 93 (script 11): [null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 93 (script 12): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 93 (script 13): [null, null, null, null, null, null, null, 0, 50331648, 754974994, 1560281343, null, null, null, 9, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 94 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 94 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 94 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 94 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 94 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 94 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 94 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 94 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 94 (script 12): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 94 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 94 (script 15): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 94 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 94 (script 18): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 94 (script 19): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 95 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 95 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 95 (script 2): [538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 95 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288] +Interface 274 child 95 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 95 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null] +Interface 274 child 95 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 95 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null] +Interface 274 child 95 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 95 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null] +Interface 274 child 95 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 95 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null] +Interface 274 child 95 (script 12): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 95 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 1593835775, null, null, null, 9, 62, 0, 0] +Interface 274 child 96 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 96 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 96 (script 2): [null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 96 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 96 (script 4): [538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 96 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 96 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 96 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 96 (script 9): [null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 96 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 96 (script 11): [538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 96 (script 12): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 96 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 96 (script 15): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 96 (script 16): [null, 0, 50331648, 754974994, 1610612991, null, null, null, 9, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 97 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 97 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 97 (script 2): [null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 97 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 97 (script 4): [null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 97 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 97 (script 6): [null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 97 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 97 (script 8): [null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 97 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 97 (script 10): [null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 97 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 97 (script 12): [null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 97 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 97 (script 14): [null, null, 0, 50331648, 754974994, 1627390207, null, null, null, 9, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 98 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 98 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 98 (script 2): [null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 98 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 98 (script 4): [null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 98 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 98 (script 6): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 98 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 98 (script 8): [null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 98 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 98 (script 10): [null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 98 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 98 (script 12): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 98 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 98 (script 14): [null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 1644167423, null, null, null, 9, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 99 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 99 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 99 (script 2): [null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 99 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 99 (script 4): [null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 99 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 99 (script 6): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 99 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 99 (script 8): [null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 99 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 99 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 99 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 99 (script 12): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 99 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 99 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 1660944639, null, null, null, 9, 66, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 100 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 100 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 100 (script 2): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 100 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 100 (script 4): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 100 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 100 (script 6): [null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 100 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 100 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 100 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 100 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 100 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 100 (script 12): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 100 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 100 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 1677721855, null, null, null, 9, 67] +Interface 274 child 101 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 101 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 101 (script 2): [null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 101 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 101 (script 4): [null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 101 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 101 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 101 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 101 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 101 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 101 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null] +Interface 274 child 101 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 101 (script 12): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null] +Interface 274 child 101 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 101 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648] +Interface 274 child 101 (script 16): [17956965, 16777215, null, 9, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 102 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 102 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 102 (script 2): [null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 102 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 102 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 102 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 102 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 102 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 102 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null] +Interface 274 child 102 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 102 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null] +Interface 274 child 102 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 102 (script 12): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 102 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 102 (script 15): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 102 (script 16): [null, null, null, null, null, null, null, 0, 50331648, 754974994, 1711276287, null, null, null, 9, 69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 103 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 103 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 103 (script 2): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 103 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 103 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 103 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 103 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 103 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 103 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null] +Interface 274 child 103 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 103 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 103 (script 12): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 103 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 103 (script 14): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 103 (script 15): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 103 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 1728053503, null, null, null, 9, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 104 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 104 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 104 (script 2): [null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 104 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 104 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 104 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 104 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null] +Interface 274 child 104 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 104 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null] +Interface 274 child 104 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 104 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 104 (script 11): [null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 104 (script 12): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 104 (script 13): [null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 104 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 104 (script 15): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 1744830719, null, null, null, 9, 71, 0, 0, 0, 0, 0] +Interface 274 child 105 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 105 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 105 (script 2): [null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 105 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 105 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 105 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 105 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null] +Interface 274 child 105 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 105 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 105 (script 9): [null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 105 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 105 (script 11): [null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 105 (script 12): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 105 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 105 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 105 (script 15): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 1761607935, null, null, null] +Interface 274 child 106 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 106 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 106 (script 2): [null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 106 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 106 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 106 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 106 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null] +Interface 274 child 106 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 106 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 106 (script 9): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 106 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 106 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 106 (script 12): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 106 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null] +Interface 274 child 106 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 106 (script 15): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 107 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 107 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 107 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 107 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 107 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null] +Interface 274 child 107 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 107 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 107 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 107 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 107 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 107 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 107 (script 12): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null] +Interface 274 child 107 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 107 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 107 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 107 (script 17): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 107 (script 18): [null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 1795162367, null, null, null, 9, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 108 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 108 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 108 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 108 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 108 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null] +Interface 274 child 108 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 108 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 108 (script 7): [null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 108 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 108 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 108 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 108 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null] +Interface 274 child 108 (script 12): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 108 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 108 (script 14): [null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 108 (script 15): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 108 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 1811939583, null, null, null, 9, 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 109 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 109 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 109 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 109 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 109 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null] +Interface 274 child 109 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 109 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 109 (script 7): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 109 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 109 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 109 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 109 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null] +Interface 274 child 109 (script 12): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 109 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 109 (script 14): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 109 (script 15): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 109 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 1828716799, null, null, null, 9, 76, 0, 0, 0] +Interface 274 child 110 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 110 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 110 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 110 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 110 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null] +Interface 274 child 110 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 110 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 110 (script 7): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 110 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 110 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 110 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 110 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 110 (script 12): [null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 110 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 110 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 110 (script 15): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 110 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 1845494015, null] +Interface 274 child 110 (script 17): [null, 9, 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 111 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 111 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 111 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 111 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 111 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null] +Interface 274 child 111 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 111 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 111 (script 7): [null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 111 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 111 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null] +Interface 274 child 111 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 111 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 111 (script 12): [null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 111 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 111 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 111 (script 15): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 111 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 111 (script 17): [null, 0, 50331648, 754974994, 1862271231, null, null, null, 9, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 112 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 112 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 112 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 112 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 112 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 112 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 112 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 112 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 112 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 112 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 112 (script 12): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 112 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 112 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 112 (script 15): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 112 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 112 (script 18): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 112 (script 19): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 113 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 113 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 113 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 113 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 113 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 113 (script 5): [null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 113 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 113 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 113 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 113 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 113 (script 10): [538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 113 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 113 (script 12): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 113 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 113 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 113 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 113 (script 17): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 113 (script 18): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 1895825663, null, null, null, 9, 80, 0, 0, 0, 0, 0] +Interface 274 child 114 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 114 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 114 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 114 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 114 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 114 (script 5): [null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 114 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 114 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 114 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 114 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 114 (script 10): [null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 114 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 114 (script 12): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 114 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 114 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 114 (script 15): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 114 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 114 (script 17): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 1912602879, null, null, null, 9, 81, 0] +Interface 274 child 115 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 115 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 115 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 115 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 115 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 115 (script 5): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 115 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 115 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null] +Interface 274 child 115 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 115 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 115 (script 10): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 115 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 115 (script 12): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null] +Interface 274 child 115 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 115 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 115 (script 15): [null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 115 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 115 (script 17): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994] +Interface 274 child 115 (script 19): [16777215, null, 9, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 116 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 116 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 116 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 116 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 116 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 116 (script 5): [null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 116 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 116 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null] +Interface 274 child 116 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 116 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 116 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 116 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 116 (script 12): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288] +Interface 274 child 116 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 116 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 116 (script 15): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 116 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 116 (script 17): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 116 (script 18): [null, null, null, 0, 50331648, 754974994, 1946157311, null, null, null, 9, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 117 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 117 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 117 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null] +Interface 274 child 117 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 117 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 117 (script 5): [null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 117 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 117 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null] +Interface 274 child 117 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 117 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 117 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 117 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 117 (script 12): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 117 (script 13): [null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 117 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 117 (script 15): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null] +Interface 274 child 117 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 117 (script 17): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 117 (script 18): [null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 1962934527, null, null, null, 9, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 118 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 118 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 118 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null] +Interface 274 child 118 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 118 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 118 (script 5): [null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 118 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 118 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 118 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 118 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 118 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null] +Interface 274 child 118 (script 12): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 118 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 118 (script 14): [null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 118 (script 15): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 118 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 118 (script 18): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 118 (script 19): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 119 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 119 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 119 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null] +Interface 274 child 119 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 119 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 119 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 119 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 119 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 119 (script 8): [null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 119 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 119 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null] +Interface 274 child 119 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 119 (script 12): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 119 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 119 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 119 (script 15): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 119 (script 16): [null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 119 (script 17): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 119 (script 18): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 1996488959, null, null, null, 9] +Interface 274 child 120 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 120 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 120 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null] +Interface 274 child 120 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 120 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 120 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 120 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 120 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 120 (script 8): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 120 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 120 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null] +Interface 274 child 120 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 120 (script 12): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 120 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 120 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 120 (script 15): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 120 (script 16): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 120 (script 17): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 120 (script 18): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0] +Interface 274 child 121 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 121 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 121 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null] +Interface 274 child 121 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 121 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 121 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 121 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 121 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 121 (script 8): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 121 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 121 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 121 (script 12): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 121 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 121 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null] +Interface 274 child 121 (script 15): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 121 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 121 (script 17): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 121 (script 18): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 121 (script 19): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 122 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 122 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 122 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null] +Interface 274 child 122 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 122 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 122 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 122 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 122 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 122 (script 8): [null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 122 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 122 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 122 (script 11): [null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 122 (script 12): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 122 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null] +Interface 274 child 122 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 122 (script 15): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 122 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 122 (script 17): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 122 (script 18): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 122 (script 19): [null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 2046820607, null, null, null, 9, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 274 child 123 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 123 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 123 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null] +Interface 274 child 123 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 123 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 123 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 123 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 123 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 123 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 123 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 123 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 123 (script 11): [null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 123 (script 12): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 123 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 123 (script 14): [538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 123 (script 15): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 123 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null] +Interface 274 child 123 (script 17): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 123 (script 18): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 123 (script 19): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, 50331648, 754974994, 2063597823, null, null, null, 9, 90, 0, 0, 0, 0] +Interface 274 child 124 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 124 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 124 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null] +Interface 274 child 124 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 124 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 124 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null] +Interface 274 child 124 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 124 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 124 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 124 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 124 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 124 (script 11): [null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 124 (script 12): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 124 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 124 (script 14): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 124 (script 15): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 124 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 124 (script 18): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 124 (script 19): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 125 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 125 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 125 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null] +Interface 274 child 125 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 125 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 125 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null] +Interface 274 child 125 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 125 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 125 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 125 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 125 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 125 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 125 (script 12): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 125 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 125 (script 14): [null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 125 (script 15): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 125 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 125 (script 17): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 125 (script 18): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 125 (script 19): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 126 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 126 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 126 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288] +Interface 274 child 126 (script 3): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 126 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 126 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null] +Interface 274 child 126 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 126 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 126 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null] +Interface 274 child 126 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 126 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 126 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 126 (script 12): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 126 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 126 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 126 (script 15): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 126 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 126 (script 17): [null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 126 (script 18): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 126 (script 19): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 127 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 127 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 127 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 127 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 127 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 127 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 127 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 127 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 127 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 127 (script 12): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 127 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 127 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 127 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 127 (script 17): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 127 (script 18): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 128 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 128 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 128 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 128 (script 3): [538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 128 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 128 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288] +Interface 274 child 128 (script 6): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 128 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 128 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null] +Interface 274 child 128 (script 9): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 128 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 128 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null] +Interface 274 child 128 (script 12): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 128 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 128 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null] +Interface 274 child 128 (script 15): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 128 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 128 (script 17): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null] +Interface 274 child 128 (script 18): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 128 (script 19): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 129 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 129 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 129 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 129 (script 3): [null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 129 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 129 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 129 (script 6): [538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 129 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 129 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 129 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 129 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 129 (script 12): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 129 (script 13): [null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 129 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 129 (script 15): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 129 (script 16): [538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 129 (script 17): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 129 (script 18): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 130 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 130 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 130 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 130 (script 3): [null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 130 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 130 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 130 (script 6): [null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 130 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 130 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 130 (script 9): [null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 130 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 130 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 130 (script 12): [null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 130 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 130 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 130 (script 15): [null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 130 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 130 (script 17): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 130 (script 18): [null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 130 (script 19): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 131 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 131 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 131 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 131 (script 3): [null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 131 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 131 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 131 (script 6): [null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 131 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 131 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 131 (script 9): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 131 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 131 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 131 (script 12): [null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 131 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 131 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 131 (script 15): [null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 131 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 131 (script 17): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 131 (script 18): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 131 (script 19): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 132 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 132 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 132 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 132 (script 3): [null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 132 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 132 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 132 (script 6): [null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 132 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 132 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 132 (script 9): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 132 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 132 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 132 (script 12): [null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 132 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 132 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 132 (script 15): [null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 132 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 132 (script 17): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 132 (script 18): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 132 (script 19): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 133 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 133 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 133 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 133 (script 3): [null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 133 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 133 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 133 (script 6): [null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 133 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 133 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 133 (script 9): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 133 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 133 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 133 (script 12): [null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 133 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 133 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 133 (script 15): [null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 133 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 133 (script 17): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 133 (script 18): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 133 (script 19): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 134 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 134 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 134 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 134 (script 3): [null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 134 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 134 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 134 (script 6): [null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 134 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 134 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 134 (script 9): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 134 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 134 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 134 (script 12): [null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 134 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 134 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 134 (script 15): [null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 134 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 134 (script 17): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 134 (script 18): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 134 (script 19): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 135 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 135 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 135 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 135 (script 3): [null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 135 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 135 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 135 (script 6): [null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 135 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 135 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 135 (script 9): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 135 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 135 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 135 (script 12): [null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 135 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 135 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 135 (script 15): [null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 135 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 135 (script 17): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 135 (script 18): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 135 (script 19): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 136 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 136 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 136 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 136 (script 3): [null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 136 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 136 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 136 (script 6): [null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 136 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 136 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 136 (script 9): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 136 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 136 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 136 (script 12): [null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 136 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 136 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 136 (script 15): [null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 136 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 136 (script 17): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 136 (script 18): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 136 (script 19): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 137 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 137 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 137 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 137 (script 3): [null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 137 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 137 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 137 (script 6): [null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 137 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 137 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 137 (script 9): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 137 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 137 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 137 (script 12): [null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 137 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 137 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 137 (script 15): [null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 137 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 137 (script 17): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 137 (script 18): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 137 (script 19): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 138 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 138 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 138 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 138 (script 3): [null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 138 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 138 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 138 (script 6): [null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 138 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 138 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 138 (script 9): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 138 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 138 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 138 (script 12): [null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 138 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 138 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 138 (script 15): [null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 138 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 138 (script 17): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 138 (script 18): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 138 (script 19): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 139 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 139 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 139 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 139 (script 3): [null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 139 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 139 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 139 (script 6): [null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 139 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 139 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 139 (script 9): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 139 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 139 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 139 (script 12): [null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 139 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 139 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 139 (script 15): [null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 139 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 139 (script 17): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 139 (script 18): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 139 (script 19): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 140 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 140 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 140 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 140 (script 3): [null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 140 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 140 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 140 (script 6): [null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 140 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 140 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 140 (script 9): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 140 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 140 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 140 (script 12): [null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 140 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 140 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 140 (script 15): [null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 140 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 140 (script 17): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 140 (script 18): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 140 (script 19): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 141 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 141 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 141 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 141 (script 3): [null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 141 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 141 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 141 (script 6): [null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 141 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 141 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 141 (script 9): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 141 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 141 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 141 (script 12): [null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 141 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 141 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 141 (script 15): [null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 141 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 141 (script 17): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 141 (script 18): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 141 (script 19): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 142 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 142 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 142 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 142 (script 3): [null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 142 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 142 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 142 (script 6): [null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 142 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 142 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 142 (script 9): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 142 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 142 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 142 (script 12): [null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 142 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 142 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 142 (script 15): [null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 142 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 142 (script 17): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 142 (script 18): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 142 (script 19): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 143 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 143 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 143 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 143 (script 3): [null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 143 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 143 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 143 (script 6): [null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 143 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 143 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 143 (script 9): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 143 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 143 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 143 (script 12): [null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 143 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 143 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 143 (script 15): [null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 143 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 143 (script 17): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 143 (script 18): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 143 (script 19): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 144 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 144 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 144 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 144 (script 3): [null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 144 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 144 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 144 (script 6): [null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 144 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 144 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 144 (script 9): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 144 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 144 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 144 (script 12): [null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 144 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 144 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 144 (script 15): [null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 144 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 144 (script 17): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 144 (script 18): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 144 (script 19): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 145 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 145 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 145 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 145 (script 3): [null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 145 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 145 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 145 (script 6): [null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 145 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 145 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 145 (script 9): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 145 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 145 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 145 (script 12): [null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 145 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 145 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 145 (script 15): [null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 145 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 145 (script 17): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 145 (script 18): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 145 (script 19): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 146 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 146 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 146 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 146 (script 3): [null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 146 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 146 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 146 (script 6): [null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 146 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 146 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 146 (script 9): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 146 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 146 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 146 (script 12): [null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 146 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 146 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 146 (script 15): [null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 146 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 146 (script 17): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 146 (script 18): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 146 (script 19): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 147 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 147 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 147 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 147 (script 3): [null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 147 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 147 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 147 (script 6): [null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 147 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 147 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 147 (script 9): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 147 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 147 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 147 (script 12): [null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 147 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 147 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 147 (script 15): [null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 147 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 147 (script 17): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 147 (script 18): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 147 (script 19): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 148 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 148 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 148 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 148 (script 3): [null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 148 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 148 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 148 (script 6): [null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 148 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 148 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 148 (script 9): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 148 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 148 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 148 (script 12): [null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 148 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 148 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 148 (script 15): [null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 148 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 148 (script 17): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 148 (script 18): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 148 (script 19): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 149 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 149 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 149 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 149 (script 3): [null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 149 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 149 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 149 (script 6): [null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 149 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 149 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 149 (script 9): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 149 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 149 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 149 (script 12): [null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 149 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 149 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 149 (script 15): [null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 149 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 149 (script 17): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 149 (script 18): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 149 (script 19): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 150 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 150 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 150 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 150 (script 3): [null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 150 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 150 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 150 (script 6): [null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 150 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 150 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 150 (script 9): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 150 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 150 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 150 (script 12): [null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 150 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 150 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 150 (script 15): [null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 150 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 150 (script 17): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 150 (script 18): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 150 (script 19): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 151 (script default): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 151 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 151 (script 2): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 151 (script 3): [null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 151 (script 4): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 151 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 151 (script 6): [null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 151 (script 7): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 151 (script 8): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 151 (script 9): [null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 151 (script 10): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 151 (script 11): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 151 (script 12): [null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 151 (script 13): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 151 (script 14): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 151 (script 15): [null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 151 (script 16): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 151 (script 17): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 151 (script 18): [null, null, null, null, null, null, null, null, 538976288, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 274 child 151 (script 19): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 300 child 14 (script 1): [832, null, 44] +Interface 300 child 14 (script 3): [196608, 54460416, 0, 16777216, 486539264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 300 child 17 (script default): [196609, null, 268435456, null, null, 789, 790, 791, 773, 788, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 301 child 11 (script 5): [529, -2147483645] +Interface 301 child 12 (script 5): [529, -2147483645] +Interface 301 child 15 (script 2): [null, 0] +Interface 301 child 15 (script 4): [null] +Interface 301 child 15 (script 6): [-1, null, 526, 1, 19726349, 19726353, 0, 131072, 34668672, 197888, 135936, -, null] +Interface 301 child 15 (script 11): [1103, 19726350, 33554432, null, null, 19726353, null, 533, 19726353, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 301 child 20 (script 2): [null, 0] +Interface 301 child 20 (script 4): [null] +Interface 301 child 20 (script 6): [-1, null, 526, 1, 19726354, 19726358, 0, 131072, 34668672, 197888, 135936, -, null, 207, 1095, 19726355, 33554432, null] +Interface 301 child 20 (script 7): [19726358, null, 533, 19726358, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 301 child 25 (script 2): [null, 0] +Interface 301 child 25 (script 4): [null] +Interface 301 child 25 (script 6): [-1, null, 526, 1, 19726359, 19726363, 0, 131072, 34668672, 197888, 135936, -, null, 208, 1096, 19726360, 33554432, null, null, 19726363, null, 533, 19726363] +Interface 301 child 30 (script 2): [null, 0] +Interface 301 child 30 (script 4): [null] +Interface 301 child 30 (script 6): [-1, null, 526, 1, 19726364, 19726368, 0, 131072, 34668672, 197888, 135936, -, null, 221, 1109, 19726365, 33554432, null, null, 19726368, null, 533, 19726368, 0, 0, 0, 0, 0] +Interface 301 child 35 (script 2): [null, 0] +Interface 301 child 35 (script 4): [null] +Interface 301 child 35 (script 6): [-1, null, 526, 1, 19726369, 19726373, 0, 131072, 34668672, 197888, 135936, -, null, 217, 1105, 19726370, 33554432, null, null, 19726373, null, 533, 19726373, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 301 child 40 (script 2): [null, 0] +Interface 301 child 40 (script 4): [null] +Interface 301 child 40 (script 6): [-1, null, 526, 1, 19726374, 19726378, 0, 131072, 34668672, 197888, 135936, -, null, 202, 1090, 19726375, 33554432, null, null, 19726378, null, 533, 19726378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 301 child 45 (script 2): [null, 0] +Interface 301 child 45 (script 4): [null] +Interface 301 child 45 (script 6): [-1, null, 526, 1, 19726379, 19726383, 0, 131072, 34668672, 197888, 135936, -, null, 210, 1098, 19726380, 33554432, null, null, 19726383, null, 533, 19726383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 301 child 50 (script 2): [null, 0] +Interface 301 child 50 (script 4): [null] +Interface 301 child 50 (script 6): [-1, null, 526, 1, 19726384, 19726388, 0, 131072, 34668672, 197888, 135936, -, null, 212, 1100, 19726385, 33554432, null, null, 19726388, null, 533, 19726388, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 301 child 55 (script 2): [null, 0] +Interface 301 child 55 (script 4): [null] +Interface 301 child 55 (script 6): [-1, null, 526, 1, 19726389, 19726393, 0, 131072, 34668672, 197888, 135936, -, null, 205, 1093, 19726390, 33554432, null, null, 19726393, null, 533, 19726393, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 301 child 58 (script 1): [832, null, 44] +Interface 301 child 58 (script 3): [196608, 54460416, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 301 child 70 (script 3): [524, -2147483645, 19726407] +Interface 301 child 70 (script 16): [278528, 71237632] +Interface 301 child 71 (script 2): [null, 0] +Interface 301 child 71 (script 4): [522, -2147483645, 20] +Interface 301 child 71 (script 17): [5120] +Interface 301 child 72 (script 3): [524, -2147483645, 19726409] +Interface 301 child 72 (script 16): [278528, 71237632] +Interface 301 child 73 (script 5): [522, -2147483645, 12] +Interface 301 child 73 (script 18): [3072] +Interface 301 child 74 (script 3): [524, -2147483645, 19726411] +Interface 301 child 74 (script 16): [278528, 71237632] +Interface 301 child 75 (script 2): [522, -2147483645, 9] +Interface 301 child 75 (script 15): [2304] +Interface 301 child 76 (script 3): [524, -2147483645, 19726413] +Interface 301 child 76 (script 16): [278528, 71237632] +Interface 301 child 77 (script 5): [522, -2147483645, 22] +Interface 301 child 77 (script 18): [5632] +Interface 301 child 78 (script 3): [524, -2147483645, 19726415] +Interface 301 child 78 (script 16): [278528, 71237632] +Interface 301 child 79 (script 2): [522, -2147483645, 19] +Interface 301 child 79 (script 15): [4864] +Interface 301 child 80 (script 3): [524, -2147483645, 19726417] +Interface 301 child 80 (script 16): [278528, 71237632] +Interface 301 child 81 (script 2): [null, 0] +Interface 301 child 81 (script 4): [522, -2147483645, 6] +Interface 301 child 81 (script 17): [1536] +Interface 301 child 82 (script 3): [524, -2147483645, 19726419] +Interface 301 child 82 (script 16): [278528, 71237632] +Interface 301 child 83 (script 2): [null, 0] +Interface 301 child 83 (script 4): [522, -2147483645, 13] +Interface 301 child 83 (script 17): [3328] +Interface 301 child 84 (script 3): [524, -2147483645, 19726421] +Interface 301 child 84 (script 16): [278528, 71237632] +Interface 301 child 85 (script 2): [null, 0] +Interface 301 child 85 (script 4): [522, -2147483645, 7] +Interface 301 child 85 (script 17): [1792] +Interface 301 child 86 (script 3): [524, -2147483645, 19726423] +Interface 301 child 86 (script 16): [278528, 71237632] +Interface 301 child 87 (script 2): [522, -2147483645, 15] +Interface 301 child 87 (script 15): [3840] +Interface 301 child 88 (script 3): [527] +Interface 301 child 88 (script 16): [278272] +Interface 301 child 98 (script 3): [524, -2147483645, 19726435] +Interface 301 child 98 (script 16): [278528] +Interface 301 child 99 (script 3): [535, -2147483645] +Interface 301 child 99 (script 16): [278528] +Interface 301 child 100 (script default): [40, 19726436] +Interface 310 child 0 (script default): [117440512, 570425344, 1409286144, 654394226, null, null, null, null, null, null, null, null, null, null, null, null, 21522804, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 310 child 0 (script 1): [null, null, null, null, 2, null, 2, 556, 2, 562, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 310 child 1 (script default): [117440512, D, 95744, 12801, null, null, null, null, null, null, null, null, null, null, 21045357, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 16, null, 1, 560, 1, 558, 4, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 310 child 2 (script default): [117440512, 771751936, 1610612736, 1040275305, null, null, null, null, null, null, null, 21045352, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 5, 565, 1, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 310 child 3 (script default): [117440512, 805306368, 1644167168, 1090606945, null, null, null, null, null, null, null, null, 21045352, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 7, 556, 5, 565, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 310 child 4 (script default): [117440512, 855638016, 1694498816, 1174488417, null, null, null, null, null, null, null, null, 21045352, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 7, 556, 5, 565, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 310 child 5 (script default): [117440512, 872415232, 1711276032, 1258374761, null, null, null, null, null, null, null, 21045352, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 7, 556, 5, 565, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 310 child 6 (script 3): [-2147483645, 13158600, null, 45, -2147483645, 8421504, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 314 child 5 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 314 child 6 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 314 child 7 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 319 child 0 (script default): [285212672, 251658240, 1090519040, 16865129, null, null, null, null, null, null, null, null, null, 21045346, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 1, 558, 1, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 319 child 1 (script default): [285212672, 285212672, 1124073472, 83973985, null, null, null, null, null, null, null, null, null, null, 21045346, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 1, 556, 1, 558, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 319 child 2 (script default): [285212672, 318767104, 1157627904, 151078241, null, null, null, null, null, null, null, null, null, null, 21045346, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 2, 556, 1, 558, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 319 child 3 (script default): [285212672, 352321536, 1191182336, 218187369, null, null, null, null, null, null, null, null, null, 21045346, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 3, 556, 2, 558, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 319 child 4 (script default): [285212672, 385875968, 1224736768, 285300585, null, null, null, null, null, null, null, 21045356, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 2, 562, 1, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 319 child 5 (script default): [285212672, 436207616, 1275068416, 385963873, null, null, null, null, null, null, null, null, 21045356, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 2, 556, 2, 562, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 319 child 6 (script default): [285212672, 486539264, 1325400064, 486622561, null, null, null, null, null, null, null, null, 21045356, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 3, 556, 2, 562, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 319 child 7 (script default): [285212672, 536870912, 1375731712, 587286121, null, null, null, null, null, null, null, 21045356, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 4, 556, 3, 562, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 319 child 8 (script default): [285212672, 587202560, 1426063360, 687953769, null, null, null, null, null, null, null, null, 21045357, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 3, 560, 1, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 319 child 9 (script default): [285212672, 637534208, 1476395008, 788617057, null, null, null, null, null, null, null, null, null, 21045357, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 3, 556, 3, 560, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 319 child 10 (script default): [285212672, 671088640, 1509949440, 889275745, null, null, null, null, null, null, null, null, null, 21045357, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 4, 556, 3, 560, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 319 child 11 (script default): [285212672, 738197504, 1577058304, 989939305, null, null, null, null, null, null, null, null, 21045357, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 5, 556, 4, 560, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 319 child 12 (script default): [285212672, 771751936, 1610612736, 1040275305, null, null, null, null, null, null, null, 21045352, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 5, 565, 1, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 319 child 13 (script default): [285212672, 805306368, 1644167168, 1090606945, null, null, null, null, null, null, null, null, 21045352, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 7, 556, 5, 565, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 319 child 14 (script default): [285212672, 855638016, 1694498816, 1174488417, null, null, null, null, null, null, null, null, 21045352, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 7, 556, 5, 565, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 319 child 15 (script default): [285212672, 872415232, 1711276032, 1258374761, null, null, null, null, null, null, null, 21045352, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 7, 556, 5, 565, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 319 child 16 (script 3): [-2147483645, 13158600, null, 45, -2147483645, 8421504, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 320 child 4 (script 5): [544, -2147483645] +Interface 320 child 77 (script 5): [525, -2147483645, 0] +Interface 320 child 77 (script 18): [0] +Interface 320 child 78 (script 5): [532, -2147483645, 0] +Interface 320 child 78 (script 18): [0] +Interface 320 child 79 (script 5): [525, -2147483645, 2] +Interface 320 child 79 (script 18): [512] +Interface 320 child 80 (script 5): [532, -2147483645, 2] +Interface 320 child 80 (script 18): [512] +Interface 320 child 81 (script 5): [525, -2147483645, 1] +Interface 320 child 81 (script 18): [256] +Interface 320 child 82 (script 5): [532, -2147483645, 1] +Interface 320 child 82 (script 18): [256] +Interface 320 child 83 (script 5): [525, -2147483645, 4] +Interface 320 child 83 (script 18): [1024] +Interface 320 child 84 (script 5): [532, -2147483645, 4] +Interface 320 child 84 (script 18): [1024] +Interface 320 child 85 (script 5): [525, -2147483645, 5] +Interface 320 child 85 (script 18): [1280] +Interface 320 child 86 (script 5): [532, -2147483645, 5] +Interface 320 child 86 (script 18): [1280] +Interface 320 child 87 (script 5): [525, -2147483645, 6] +Interface 320 child 87 (script 18): [1536] +Interface 320 child 88 (script 5): [532, -2147483645, 6] +Interface 320 child 88 (script 18): [1536] +Interface 320 child 89 (script 5): [525, -2147483645, 20] +Interface 320 child 89 (script 18): [5120] +Interface 320 child 90 (script 5): [532, -2147483645, 20] +Interface 320 child 90 (script 18): [5120] +Interface 320 child 91 (script 5): [525, -2147483645, 22] +Interface 320 child 91 (script 18): [5632] +Interface 320 child 92 (script 5): [532, -2147483645, 22] +Interface 320 child 92 (script 18): [5632] +Interface 320 child 93 (script 5): [525, -2147483645, 3] +Interface 320 child 93 (script 18): [768] +Interface 320 child 94 (script 5): [532, -2147483645, 3] +Interface 320 child 94 (script 18): [768] +Interface 320 child 95 (script 5): [525, -2147483645, 16] +Interface 320 child 95 (script 18): [4096] +Interface 320 child 96 (script 5): [532, -2147483645, 16] +Interface 320 child 96 (script 18): [4096] +Interface 320 child 97 (script 5): [525, -2147483645, 15] +Interface 320 child 97 (script 18): [3840] +Interface 320 child 98 (script 5): [532, -2147483645, 15] +Interface 320 child 98 (script 18): [3840] +Interface 320 child 99 (script 5): [525, -2147483645, 17] +Interface 320 child 99 (script 18): [4352] +Interface 320 child 100 (script 5): [532, -2147483645, 17] +Interface 320 child 100 (script 18): [4352] +Interface 320 child 101 (script 5): [525, -2147483645, 12] +Interface 320 child 101 (script 18): [3072] +Interface 320 child 102 (script 5): [532, -2147483645, 12] +Interface 320 child 102 (script 18): [3072] +Interface 320 child 103 (script 5): [525, -2147483645, 9] +Interface 320 child 103 (script 18): [2304] +Interface 320 child 104 (script 5): [532, -2147483645, 9] +Interface 320 child 104 (script 18): [2304] +Interface 320 child 105 (script 5): [525, -2147483645, 18] +Interface 320 child 105 (script 18): [4608] +Interface 320 child 106 (script 2): [532, -2147483645, 18] +Interface 320 child 106 (script 15): [4608] +Interface 320 child 107 (script 5): [525, -2147483645, 21] +Interface 320 child 107 (script 18): [5376] +Interface 320 child 108 (script 5): [532, -2147483645, 21] +Interface 320 child 108 (script 18): [5376] +Interface 320 child 109 (script 5): [525, -2147483645, 14] +Interface 320 child 109 (script 18): [3584] +Interface 320 child 110 (script 5): [532, -2147483645, 14] +Interface 320 child 110 (script 18): [3584] +Interface 320 child 111 (script 5): [525, -2147483645, 13] +Interface 320 child 111 (script 18): [3328] +Interface 320 child 112 (script 5): [532, -2147483645, 13] +Interface 320 child 112 (script 18): [3328] +Interface 320 child 113 (script 5): [525, -2147483645, 10] +Interface 320 child 113 (script 18): [2560] +Interface 320 child 114 (script 5): [532, -2147483645, 10] +Interface 320 child 114 (script 18): [2560] +Interface 320 child 115 (script 5): [525, -2147483645, 7] +Interface 320 child 115 (script 18): [1792] +Interface 320 child 116 (script 5): [532, -2147483645, 7] +Interface 320 child 116 (script 18): [1792] +Interface 320 child 117 (script 5): [525, -2147483645, 11] +Interface 320 child 117 (script 18): [2816] +Interface 320 child 118 (script 5): [532, -2147483645, 11] +Interface 320 child 118 (script 18): [2816] +Interface 320 child 119 (script 5): [525, -2147483645, 8] +Interface 320 child 119 (script 18): [2048] +Interface 320 child 120 (script 5): [532, -2147483645, 8] +Interface 320 child 120 (script 18): [2048] +Interface 320 child 121 (script 5): [525, -2147483645, 19] +Interface 320 child 121 (script 18): [4864] +Interface 320 child 122 (script 5): [532, -2147483645, 19] +Interface 320 child 122 (script 18): [4864] +Interface 320 child 123 (script 5): [525, -2147483645, 23] +Interface 320 child 123 (script 18): [5888] +Interface 320 child 124 (script 5): [532, -2147483645, 23] +Interface 320 child 124 (script 18): [5888] +Interface 320 child 125 (script 1): [null, -2147483645] +Interface 320 child 125 (script 8): [null] +Interface 320 child 125 (script 10): [null, 546, 20971671, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 320 child 126 (script 2): [null, -2147483645] +Interface 320 child 126 (script 7): [20971671, null] +Interface 320 child 126 (script 11): [null, 20971671] +Interface 320 child 127 (script 2): [null, -2147483645] +Interface 320 child 127 (script 7): [20971671] +Interface 320 child 127 (script 8): [546, 20971671] +Interface 320 child 128 (script 2): [null, -2147483645] +Interface 320 child 128 (script 7): [20971671, null, 546, 20971671] +Interface 320 child 129 (script 2): [null, -2147483645] +Interface 320 child 129 (script 7): [20971671, null, 546, 20971671, 0] +Interface 320 child 130 (script 2): [null, -2147483645] +Interface 320 child 130 (script 7): [20971671, null, 546, 20971671, 0, 0] +Interface 320 child 131 (script 2): [null, -2147483645] +Interface 320 child 131 (script 7): [20971671, null, 546, 20971671, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 320 child 132 (script 2): [null, -2147483645] +Interface 320 child 132 (script 7): [20971671, null, 546, 20971671, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 320 child 133 (script 2): [null, -2147483645] +Interface 320 child 133 (script 7): [20971671, null, 546] +Interface 320 child 133 (script 9): [null] +Interface 320 child 133 (script 11): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 320 child 134 (script 2): [null, -2147483645] +Interface 320 child 134 (script 7): [20971671, null, 546, 20971671, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 320 child 135 (script 2): [null, -2147483645] +Interface 320 child 135 (script 7): [20971671, null, 546, 20971671, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 320 child 136 (script 2): [null, -2147483645] +Interface 320 child 136 (script 7): [20971671, null, 546, 20971671, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 320 child 137 (script 2): [null, -2147483645] +Interface 320 child 137 (script 7): [20971671, null, 546, 20971671, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 320 child 138 (script 2): [null, -2147483645] +Interface 320 child 138 (script 7): [20971671, null, 546, 20971671, 0, 0, 0, 0, 0] +Interface 320 child 139 (script 2): [null, -2147483645] +Interface 320 child 139 (script 7): [20971671, null, 546, 20971671, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 320 child 140 (script 2): [null, -2147483645] +Interface 320 child 140 (script 7): [20971671, null, 546, 20971671, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 320 child 141 (script 2): [null, -2147483645] +Interface 320 child 141 (script 7): [20971671, null, 546, 20971671, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 320 child 142 (script 2): [null, -2147483645] +Interface 320 child 142 (script 7): [20971671, null, 546, 20971671, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 320 child 143 (script 2): [null, -2147483645] +Interface 320 child 143 (script 7): [20971671, null, 546, 20971671, 0, 0, 0, 0, 0, 0] +Interface 320 child 144 (script 2): [null, -2147483645] +Interface 320 child 144 (script 7): [20971671, null, 546, 20971671, 0, 0, 0] +Interface 320 child 145 (script 2): [null, -2147483645] +Interface 320 child 145 (script 7): [20971671, null, 546, 20971671, 0, 0, 0, 0, 0, 0, 0] +Interface 320 child 146 (script 2): [null, -2147483645] +Interface 320 child 146 (script 7): [20971671, null, 546, 20971671, 0, 0, 0, 0] +Interface 320 child 147 (script 2): [null, -2147483645] +Interface 320 child 147 (script 7): [20971671, null, 546, 20971671, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 320 child 148 (script 2): [null, -2147483645] +Interface 320 child 148 (script 7): [20971671, null, 546, 20971671, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 320 child 150 (script default): [null, -2147483645, 20971669] +Interface 320 child 150 (script 4): [null, 789, 790] +Interface 320 child 150 (script 8): [null, 773, 788] +Interface 327 child 12 (script 1): [832, null, 44, 21430284, 831, 0, 16777216, 486539264, 0, 0, 0, 0] +Interface 327 child 18 (script 1): [21430290, 11, 0, null, 163, 21430290, 0, 16777220, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 334 child 6 (script 1): [832, null, 44] +Interface 334 child 6 (script 3): [196608, 54460416, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 334 child 44 (script 3): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 335 child 12 (script 1): [832, null, 44] +Interface 335 child 12 (script 3): [196608, 54460416, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 335 child 17 (script 3): [141] +Interface 335 child 17 (script 16): [266752, 68354048] +Interface 335 child 18 (script 3): [-2147483645, null, 97, -2147483645, null, 93, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 335 child 20 (script 3): [-2147483645, null, 97, -2147483645, null, 93, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 335 child 31 (script 3): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 335 child 42 (script default): [40, 21954639] +Interface 335 child 43 (script default): [40, 21954639] +Interface 335 child 44 (script default): [40, 21954639] +Interface 335 child 75 (script 1): [21954639, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 335 child 76 (script 1): [21954639, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 335 child 77 (script 1): [21954639, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 335 child 78 (script 1): [21954639, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 373 child 1 (script 3): [70] +Interface 373 child 1 (script 16): [143360] +Interface 374 child 5 (script 1): [45, -2147483645, 16776960] +Interface 374 child 5 (script 2): [45, -2147483645, 16777215] +Interface 374 child 11 (script 1): [45, -2147483645, 16777215] +Interface 374 child 11 (script 2): [45, -2147483645, 16750623] +Interface 374 child 12 (script 1): [45, -2147483645, 16777215] +Interface 374 child 12 (script 2): [45, -2147483645, 16750623] +Interface 374 child 13 (script 1): [45, -2147483645, 16777215] +Interface 374 child 13 (script 2): [45, -2147483645, 16750623] +Interface 374 child 14 (script 1): [45, -2147483645, 16777215] +Interface 374 child 14 (script 2): [45, -2147483645, 16750623] +Interface 380 child 1 (script 6): [54] +Interface 381 child 1 (script 6): [54] +Interface 382 child 13 (script 1): [832, null, 44] +Interface 382 child 13 (script 3): [196608, 54460416, 0, 16777216, 486539264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 382 child 18 (script 2): [834, null, 44] +Interface 382 child 18 (script 4): [196608, 54591488, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 382 child 19 (script 1): [834, null, 44] +Interface 382 child 19 (script 3): [196608, 54591488, 0, 16777216, 486539264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 382 child 27 (script 1): [25034779, 7, 0, null, 163, 25034779, 0, 16777220, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 388 child 0 (script default): [285212672, I, 97024, 12801, null, null, null, null, null, null, null, null, null, null, 21045363, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 2, 560, 2, 554, 1, 556, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 388 child 1 (script default): [285212672, Q, 99072, 13313, null, null, null, null, null, null, null, null, null, null, null, 21045363, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 2, 560, 2, 556, 1, 566, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 388 child 2 (script default): [285212672, M, 98048, 14337, null, null, null, null, null, null, null, null, null, null, 21045363, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 2, 560, 2, 565, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 388 child 3 (script default): [285212672, E, 96000, 14849, null, null, null, null, null, null, null, null, 21045363, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 2, 560, 2, 555, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 388 child 4 (script default): [285212672, J, 97280, 15873, null, null, null, null, null, null, null, null, null, null, null, 21045357, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 4, 560, 2, 554, 2, 556, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 388 child 5 (script default): [285212672, R, 99328, 16385, null, null, null, null, null, null, null, null, null, null, null, null, 21045357, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 4, 560, 2, 556, 1, 566, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 388 child 6 (script default): [285212672, N, 98304, 17409, null, null, null, null, null, null, null, null, null, null, null, 21045357, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 4, 560, 2, 565, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 388 child 7 (script default): [285212672, F, 96256, 17921, null, null, null, null, null, null, null, null, null, 21045357, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 4, 560, 2, 555, 4, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 388 child 8 (script default): [285212672, K, 97536, 18945, null, null, null, null, null, null, null, null, null, null, null, 21045363, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 2, 565, 2, 554, 2, 556, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 388 child 9 (script default): [285212672, S, 99584, 19457, null, null, null, null, null, null, null, null, null, null, null, null, 21045363, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 2, 565, 2, 556, 2, 566, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 388 child 10 (script default): [285212672, O, 98560, 20481, null, null, null, null, null, null, null, null, null, null, null, 21045363, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 2, 565, 4, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 388 child 11 (script default): [285212672, G, 96512, 20993, null, null, null, null, null, null, null, null, null, 21045363, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 2, 565, 2, 555, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 388 child 12 (script default): [285212672, L, 97792, 22017, null, null, null, null, null, null, null, null, null, null, null, null, null, 21045357, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 4, 565, 2, 554, 4, 556, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 388 child 13 (script default): [285212672, T, 99840, 22529, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 21045357, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 4, 565, 2, 556, 4, 566, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 388 child 14 (script default): [285212672, P, 98816, 23553, null, null, null, null, null, null, null, null, null, null, null, null, null, 21045357, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 4, 565, 4, 566, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 388 child 15 (script default): [285212672, H, 96768, 24065, null, null, null, null, null, null, null, null, null, null, null, 21045357, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 4, 565, 2, 555, 6, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 388 child 16 (script 3): [-2147483645, 13158600, null, 45, -2147483645, 8421504, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 389 child 10 (script 1): [832, null, 44] +Interface 389 child 10 (script 3): [196608, 54460416, 1, 571, 16777216, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 390 child 8 (script default): [45, -2147483645, 13811300] +Interface 390 child 8 (script 8): [45, -2147483645, 14784543] +Interface 390 child 16 (script 9): [67, 25559041, 27494] +Interface 395 child 2 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 406 child 0 (script default): [117440512, 570425344, 1409286144, 654394226, null, null, null, null, null, null, null, null, null, null, null, null, 21522804, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 2, 556, 2, 562, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 406 child 1 (script default): [117440512, 1006632960, 1845493760, 1006715756, null, null, null, null, null, null, null, null, null, null, null, null, null, 22246765, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 1, 565, 2, 556, 4, 8843, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 406 child 2 (script default): [117440512, 771751936, 1610612736, 1040275305, null, null, null, null, null, null, null, 21045352, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 5, 565, 1, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 406 child 3 (script default): [117440512, 805306368, 1644167168, 1090606945, null, null, null, null, null, null, null, null, 21045352, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 7, 556, 5, 565, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 406 child 4 (script default): [117440512, 855638016, 1694498816, 1174488417, null, null, null, null, null, null, null, null, 21045352, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 7, 556, 5, 565, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 406 child 5 (script default): [117440512, 872415232, 1711276032, 1258374761, null, null, null, null, null, null, null, 21045352, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 2, null, 7, 556, 5, 565, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 406 child 6 (script 3): [-2147483645, 13158600, null, 45, -2147483645, 8421504, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 419 child 10 (script 1): [27459606, 16777215, null, 45, 27459606, 13421772, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 419 child 11 (script 1): [27459607, 16777215, null, 45, 27459607, 13421772, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 419 child 12 (script 1): [27459602, 16777215, null, 45, 27459602, 13421772, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 419 child 13 (script 1): [27459603, 16777215, null, 45, 27459603, 13421772, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 419 child 14 (script 1): [27459604, 16777215, null, 45, 27459604, 13421772, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 419 child 15 (script 1): [27459605, 16777215, null, 45, 27459605, 13421772, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 419 child 16 (script 1): [27459608, 16777215, null, 45, 27459608, 13421772, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 419 child 17 (script 1): [27459609, 16777215, null, 45, 27459609, 13421772, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 419 child 18 (script 3): [27459602, 16777215, null, 45, 27459602, 13421772, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 419 child 19 (script 3): [27459603, 16777215, null, 45, 27459603, 13421772, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 419 child 20 (script 3): [27459604, 16777215, null, 45, 27459604, 13421772, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 419 child 21 (script 3): [27459605, 16777215, null, 45, 27459605, 13421772, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 419 child 22 (script 3): [27459606, 16777215, null, 45, 27459606, 13421772, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 419 child 23 (script 3): [27459607, 16777215, null, 45, 27459607, 13421772, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 419 child 24 (script 3): [27459608, 16777215, null, 45, 27459608, 13421772, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 419 child 25 (script 3): [27459609, 16777215, null, 45, 27459609, 13421772, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 429 child 86 (script 3): [-2147483645, 15840880, null, 45, -2147483645, 16750623, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 429 child 87 (script 3): [-2147483645, 15840880, null, 45, -2147483645, 16750623, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 429 child 88 (script 3): [-2147483645, 15840880, null, 45, -2147483645, 16750623, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 429 child 89 (script 3): [-2147483645, 15840880, null, 45, -2147483645, 16750623, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 429 child 90 (script 3): [-2147483645, 15840880, null, 45, -2147483645, 16750623, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 429 child 91 (script 3): [-2147483645, 15840880, null, 45, -2147483645, 16750623, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 429 child 92 (script 3): [-2147483645, 15840880, null, 45, -2147483645, 16750623, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 429 child 93 (script 3): [-2147483645, 15840880, null, 45, -2147483645, 16750623, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 429 child 94 (script 3): [-2147483645, 15840880, null, 45, -2147483645, 16750623, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 429 child 95 (script 3): [-2147483645, 15840880, null, 45, -2147483645, 16750623, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 429 child 96 (script 3): [-2147483645, 15840880, null, 45, -2147483645, 16750623, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 429 child 97 (script 3): [-2147483645, 15840880, null, 45, -2147483645, 16750623, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 429 child 110 (script 1): [536, null, 44] +Interface 429 child 110 (script 3): [196608, 35061760, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 430 child 0 (script default): [671088640, null, null, 597, 75, Barbarian Teleport, Teleports you to the Barbarian Outpost, 9075, 2, 563, 2, 554, 3, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 430 child 1 (script 1): [28180520, 559, 609] +Interface 430 child 1 (script 6): [Cure Other, Cure poisoned players, 9075, 1, 563, 1, 557, 10, -1, 0, 16, 6, -2147483645, 28180520, 559, 609, 68, Cure Other, Cure poisoned players, 9075, 1, 563, 1, 557, 10, -1, 0, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 430 child 2 (script 1): [28180520, 553, 603] +Interface 430 child 2 (script 6): [Fertile Soil, Fertilise a farming patch with super compost, 9075, 3, 561, 2, 557, 15, -1, 0, 16, 6, -2147483645, 28180520, 553, 603, 83, Fertile Soil, Fertilise a farming patch with super compost, 9075, 3, 561, 2, 557, 15, -1, 0, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 430 child 3 (script default): [671088640, null, null, 615, 74, Cure Group, Cure poison on players, 9075, 2, 564, 2, 563, 2, -1, 0, 16, 6, -2147483645, 28180520, 565, 615, 74, Cure Group, Cure poison on players, 9075, 2, 564, 2, 563, 2, -1, 0, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 430 child 4 (script default): [671088640, null, null, 618, 67, NPC Contact, Speak with varied NPCs, 9075, 1, 564, 1, 556, 2, -1, 0, 16, 6, -2147483645, 28180520, 568, 618, 67, NPC Contact, Speak with varied NPCs, 9075, 1, 564, 1, 556, 2, -1, 0, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 430 child 5 (script 1): [28180520, 558, 608] +Interface 430 child 5 (script 6): [Energy Transfer, Spend hitpoints and SA energy to give another SA and run energy, 9075, 3, 563, 2, 561, 1, -1, 0, 16, 6, -2147483645, 28180520, 558, 608, 91, Energy Transfer, Spend hitpoints and SA energy to give another SA and run energy, 9075, 3, 563, 2, 561, 1, -1, 0, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 430 child 6 (script 1): [28180520, 577, 627] +Interface 430 child 6 (script 6): [Monster Examine, Detect the combat statistics of a monster, 9075, 1, 564, 1, 558, 1, -1, 0, 16, 6, -2147483645, 28180520, 577, 627, 66, Monster Examine, Detect the combat statistics of a monster, 9075, 1, 564, 1, 558, 1, -1, 0, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 430 child 7 (script default): [671088640, null, null, 628, 68, Humidify, Fills certain vessels with water, 9075, 1, 555, 3, 554, 1, -1, 0, 16, 6, -2147483645, 28180520, 578, 628, 68, Humidify, Fills certain vessels with water, 9075, 1, 555, 3, 554, 1, -1, 0, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 430 child 8 (script 3): [null, 71] +Interface 430 child 8 (script 4): [null] +Interface 430 child 8 (script 5): [null, null, null, null, null, null, null, null, 21456244, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 35, null, 2, 557, 2, -1, 0, -1, 0, 16, 6, -2147483645, 28180520, 579, 629, 71, Hunter Kit, Get a kit of hunter gear, 9075, 2, 557, 2, -1, 0, -1, 0, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 430 child 9 (script 1): [28180520, 576, 626] +Interface 430 child 9 (script 6): [Stat Spy, Cast on another player to see their skill levels, 9075, 2, 564, 2, 559, 5, -1, 0, 16, 6, -2147483645, 28180520, 576, 626, 75, Stat Spy, Cast on another player to see their skill levels, 9075, 2, 564, 2, 559, 5, -1, 0, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 430 child 10 (script 3): [null, 79] +Interface 430 child 10 (script 4): [null] +Interface 430 child 10 (script 5): [null, null, null, 22307179, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 35, null, 2, 564, 1, 559, 5, -1, 0, 16, 6, -2147483645, 28180520, 580, 630, 79, Dream, Take a rest and restore hitpoints 3 times faster, 9075, 2, 564, 1, 559, 5, -1, 0, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 430 child 11 (script 1): [28180520, 581, 631] +Interface 430 child 11 (script 6): [Plank Make, Turn logs into planks, 9075, 2, 557, 15, 561, 1, -1, 0, 16, 6, -2147483645, 28180520, 581, 631, 86, Plank Make, Turn logs into planks, 9075, 2, 557, 15, 561, 1, -1, 0, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 430 child 12 (script 3): [null, 96] +Interface 430 child 12 (script 4): [null] +Interface 430 child 12 (script 5): [null, null, null, null, null, null, null, null, null, null, null, null, 21194849, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 35, null, 3, 564, 2, 563, 1, -1, 0, 16, 6, -2147483645, 28180520, 582, 632, 96, Spellbook Swap, Change to another spellbook for 1 spell cast, 9075, 3, 564, 2, 563, 1, -1, 0, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 430 child 13 (script default): [671088640, null, null, 602, 82, Magic Imbue, Combine runes without a talisman, 9075, 2, 554, 7, 555, 7, -1, 0, 16, 6, -2147483645, 28180520, 552, 602, 82, Magic Imbue, Combine runes without a talisman, 9075, 2, 554, 7, 555, 7, -1, 0, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 430 child 14 (script default): [671088640, null, null, 614, 94, Vengeance, Rebound damage to an opponent, 9075, 4, 560, 2, 557, 10, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 430 child 15 (script default): [671088640, null, null, 593, 65, Bake Pie, Bake pies without a stove, 9075, 1, 554, 5, 555, 4, -1, 0, 16, 6, -2147483645, 28180520, 543, 593, 65, Bake Pie, Bake pies without a stove, 9075, 1, 554, 5, 555, 4, -1, 0, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 430 child 16 (script default): [671088640, d, 103936, 1, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 22177137, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 16777215, null, 0, -1, 0, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 430 child 17 (script default): [671088640, null, null, 605, 85, Fishing Guild Teleport, Teleports you to the Fishing Guild, 9075, 3, 563, 3, 555, 10, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 430 child 18 (script default): [671088640, null, null, 599, 78, Khazard Teleport, Teleports you to Port Khazard, 9075, 2, 563, 2, 555, 4, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 430 child 19 (script default): [28180520, 561, 611] +Interface 430 child 19 (script 5): [Vengeance Other, Allows another player to rebound damage to an opponent, 9075, 3, 560, 2, 557, 10, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 430 child 20 (script default): [671088640, null, null, 594, 69, Moonclan Teleport, Teleports you to Moonclan Island, 9075, 2, 563, 1, 557, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 430 child 21 (script default): [671088640, null, null, 606, 87, Catherby Teleport, Teleports you to Catherby, 9075, 3, 563, 3, 555, 10, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 430 child 22 (script default): [671088640, null, null, 600, 80, String Jewellery, String amulets without wool, 9075, 2, 557, 10, 555, 5, -1, 0, 16, 6, -2147483645, 28180520, 550, 600, 80, String Jewellery, String amulets without wool, 9075, 2, 557, 10, 555, 5, -1, 0, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 430 child 23 (script default): [671088640, null, null, 612, 71, Cure Me, Cure Poison, 9075, 2, 564, 2, 563, 1, -1, 0, 16, 6, -2147483645, 28180520, 562, 612, 71, Cure Me, Cure Poison, 9075, 2, 564, 2, 563, 1, -1, 0, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 430 child 24 (script default): [671088640, null, null, 595, 72, Waterbirth Teleport, Teleports you to Waterbirth Island, 9075, 2, 563, 1, 555, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 430 child 25 (script default): [671088640, null, null, 598, 77, Superglass Make, Make glass without a furnace, 9075, 2, 554, 6, 556, 10, -1, 0, 16, 6, -2147483645, 28180520, 548, 598, 77, Superglass Make, Make glass without a furnace, 9075, 2, 554, 6, 556, 10, -1, 0, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 430 child 26 (script 1): [28180520, 551, 601] +Interface 430 child 26 (script 6): [Boost Potion Share, Shares a potion with up to 4 nearby players, 9075, 3, 557, 12, 555, 10, -1, 0, 16, 6, -2147483645, 28180520, 551, 601, 84, Boost Potion Share, Shares a potion with up to 4 nearby players, 9075, 3, 557, 12, 555, 10, -1, 0, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 430 child 27 (script 1): [28180520, 554, 604] +Interface 430 child 27 (script 6): [Stat Restore Pot Share, Shares a potion with up to 4 nearby players, 9075, 2, 557, 10, 555, 10, -1, 0, 16, 6, -2147483645, 28180520, 554, 604, 81, Stat Restore Pot Share, Shares a potion with up to 4 nearby players, 9075, 2, 557, 10, 555, 10, -1, 0, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 430 child 28 (script default): [671088640, null, null, 607, 89, Ice Plateau Teleport, Teleports you to Ice Plateau, 9075, 3, 563, 3, 555, 8, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 430 child 29 (script 1): [28180520, 560, 610] +Interface 430 child 29 (script 6): [Heal Other, Transfers up to 75% of hitpoints to another player, 9075, 3, 563, 3, 565, 1, -1, 0, 16, 6, -2147483645, 28180520, 560, 610, 92, Heal Other, Transfers up to 75% of hitpoints to another player, 9075, 3, 563, 3, 565, 1, -1, 0, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 430 child 30 (script default): [671088640, null, null, 616, 95, Heal Group, Transfers up to 75% of hitpoints to a group, 9075, 4, 565, 3, 563, 6, -1, 0, 16, 6, -2147483645, 28180520, 566, 616, 95, Heal Group, Transfers up to 75% of hitpoints to a group, 9075, 4, 565, 3, 563, 6, -1, 0, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 430 child 31 (script default): [671088640, null, null, 633, 71, Ourania Teleport, Teleports you to Ourania rune altar, 9075, 2, 563, 1, 557, 6, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 430 child 32 (script 1): [28180520, 567, 617] +Interface 430 child 32 (script 6): [Cure Plant, Cures disease on farming patch, 9075, 1, 557, 8, -1, 0, -1, 0, 16, 6, -2147483645, 28180520, 567, 617, 66, Cure Plant, Cures disease on farming patch, 9075, 1, 557, 8, -1, 0, -1, 0, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 430 child 33 (script default): [671088640, null, null, 619, 70, Tele Group Moonclan, Teleports players to Moonclan Island, 9075, 2, 563, 1, 557, 4, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 430 child 34 (script default): [671088640, null, null, 620, 73, Tele Group Waterbirth, Teleports players to Waterbirth Island, 9075, 2, 563, 1, 555, 5, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 430 child 35 (script default): [671088640, null, null, 621, 76, Tele Group Barbarian, Teleports players to the Barbarian Outpost, 9075, 2, 563, 2, 554, 6, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 430 child 36 (script default): [671088640, null, null, 622, 79, Tele Group Khazard, Teleports players to Port Khazard, 9075, 2, 563, 2, 555, 8, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 430 child 37 (script default): [671088640, null, null, 623, 86, Tele Group Fishing Guild, Teleports players to the Fishing Guild, 9075, 3, 563, 3, 555, 14, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 430 child 38 (script default): [671088640, null, null, 624, 88, Tele Group Catherby, Teleports players to Catherby, 9075, 3, 563, 3, 555, 15, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 430 child 39 (script default): [671088640, null, null, 625, 90, Tele Group Ice Plateau, Teleports players to Ice Plateau, 9075, 3, 563, 3, 555, 16, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 432 child 12 (script 1): [832, null, 44] +Interface 432 child 12 (script 3): [196608, 54460416, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 432 child 15 (script 2): [null, -2147483645] +Interface 432 child 15 (script 7): [3, 540, -2147483645, 4] +Interface 432 child 16 (script 2): [null, -2147483645] +Interface 432 child 16 (script 6): [null, 0, 0] +Interface 432 child 19 (script 2): [null, -2147483645] +Interface 432 child 19 (script 6): [null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 432 child 20 (script 2): [null, -2147483645] +Interface 432 child 20 (script 7): [3, 540, -2147483645, 14, 0, 0, 65536, null, null, 0, 0, 0, 0, 0] +Interface 432 child 23 (script 2): [null, -2147483645] +Interface 432 child 23 (script 6): [null, 0, 0] +Interface 432 child 24 (script 2): [null, -2147483645] +Interface 432 child 24 (script 7): [3, 540, -2147483645, 24, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 432 child 27 (script 2): [null, -2147483645] +Interface 432 child 27 (script 7): [3, 540, -2147483645, 29, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 432 child 30 (script 2): [null, -2147483645] +Interface 432 child 30 (script 7): [3, 540, -2147483645, 7, 0, 0, 65536] +Interface 432 child 30 (script 8): [null, 0, 0, 0] +Interface 432 child 33 (script 2): [null, -2147483645] +Interface 432 child 33 (script 7): [3, 540, -2147483645, 27, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 432 child 36 (script 2): [null, -2147483645] +Interface 432 child 36 (script 7): [3, 540, -2147483645, 49, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 432 child 39 (script 2): [null, -2147483645] +Interface 432 child 39 (script 7): [3, 540, -2147483645, 57, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 432 child 42 (script 2): [null, -2147483645] +Interface 432 child 42 (script 7): [3, 540, -2147483645, 68, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 432 child 45 (script 2): [null, -2147483645] +Interface 432 child 45 (script 7): [3, 540, -2147483645, 87, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 432 child 47 (script 2): [null, -2147483645] +Interface 432 child 47 (script 6): [null, 1] +Interface 432 child 49 (script 2): [null, -2147483645] +Interface 432 child 49 (script 6): [null, 1] +Interface 432 child 51 (script 2): [null, -2147483645] +Interface 432 child 51 (script 6): [null, 1] +Interface 432 child 53 (script 2): [null, -2147483645] +Interface 432 child 53 (script 6): [null, 1] +Interface 432 child 55 (script 2): [null, -2147483645] +Interface 432 child 55 (script 6): [null, 1] +Interface 432 child 57 (script 2): [null, -2147483645] +Interface 432 child 57 (script 6): [null, 1] +Interface 432 child 59 (script 2): [null, -2147483645] +Interface 432 child 59 (script 6): [null, 1] +Interface 432 child 61 (script 2): [null, -2147483645] +Interface 432 child 61 (script 6): [null, 1] +Interface 432 child 63 (script 2): [null, -2147483645] +Interface 432 child 63 (script 6): [null, 1] +Interface 432 child 65 (script 2): [null, -2147483645] +Interface 432 child 65 (script 6): [null, 1] +Interface 432 child 68 (script 2): [null, -2147483645] +Interface 432 child 68 (script 6): [null, 2] +Interface 432 child 70 (script 2): [null, -2147483645] +Interface 432 child 70 (script 6): [null, 15] +Interface 432 child 72 (script 2): [null, -2147483645] +Interface 432 child 72 (script 6): [null, 2] +Interface 432 child 74 (script 2): [null, -2147483645] +Interface 432 child 74 (script 6): [null, 2] +Interface 432 child 76 (script 2): [null, -2147483645] +Interface 432 child 76 (script 6): [null, 2] +Interface 432 child 78 (script 2): [null, -2147483645] +Interface 432 child 78 (script 6): [null, 1] +Interface 432 child 80 (script 2): [null, -2147483645] +Interface 432 child 80 (script 6): [null, 1] +Interface 432 child 82 (script 2): [null, -2147483645] +Interface 432 child 82 (script 6): [null, 1] +Interface 432 child 84 (script 2): [null, -2147483645] +Interface 432 child 84 (script 6): [null, 5] +Interface 432 child 86 (script 2): [null, -2147483645] +Interface 432 child 86 (script 6): [null, 3] +Interface 432 child 88 (script 2): [null, -2147483645] +Interface 432 child 88 (script 6): [null, 2] +Interface 432 child 90 (script 2): [null, -2147483645] +Interface 432 child 90 (script 6): [null, 1] +Interface 432 child 92 (script 2): [null, -2147483645] +Interface 432 child 92 (script 6): [null, 1] +Interface 432 child 94 (script 2): [null, -2147483645] +Interface 432 child 94 (script 6): [null, 1] +Interface 432 child 96 (script 2): [null, -2147483645] +Interface 432 child 96 (script 6): [null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 432 child 97 (script 2): [null, -2147483645] +Interface 432 child 97 (script 6): [null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 432 child 98 (script 2): [null, -2147483645] +Interface 432 child 98 (script 6): [null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 432 child 99 (script 2): [null, -2147483645] +Interface 432 child 99 (script 6): [null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 432 child 100 (script 2): [null, -2147483645] +Interface 432 child 100 (script 6): [null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 432 child 101 (script 2): [null, -2147483645] +Interface 432 child 101 (script 6): [null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 432 child 102 (script 2): [null, -2147483645] +Interface 432 child 102 (script 6): [null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 432 child 104 (script 2): [null, -2147483645] +Interface 432 child 104 (script 6): [null, 10] +Interface 464 child 1 (script 3): [30408704, 30408705, 1, 838, 0, 0, 262144, 9, 30474240, null, null, 277760, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 464 child 2 (script default): [0, 393216, 2490496, 196609, null, 721508709, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 464 child 3 (script default): [721420288, 6, 38, -2147483645, 30408747, No, 50, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 464 child 4 (script default): [0, 393216, 2490496, 196609, null, 721502831, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 464 child 5 (script default): [721420288, 6, 38, -2147483645, 30408747, Angry, 50, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 464 child 6 (script default): [721420288, 6, 38, -2147483645, 30408747, Think, 50, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 464 child 7 (script 1): [0, 393216, 2490496, 196609, null, 721508193, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 464 child 8 (script default): [721420288, 6, 38, -2147483645, 30408747, Shrug, 50, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 464 child 9 (script default): [721420288, 6, 38, -2147483645, 30408747, Cheer, 50, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 464 child 10 (script default): [721420288, 6, 38, -2147483645, 30408747, Beckon, 50, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 464 child 11 (script default): [721420288, 6, 38, -2147483645, 30408747, Laugh, 50, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 464 child 12 (script 1): [0, 393216, 2490496, 196609, null, 721504885, null, null, null, null, null, null, null, null, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 464 child 13 (script 1): [0, 393216, 2490496, 196609, null, 721508705, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 464 child 14 (script default): [721420288, 6, 38, -2147483645, 30408747, Dance, 50, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 464 child 15 (script default): [0, 393216, 2490496, 196609, null, 721504873, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 464 child 16 (script 1): [0, 393216, 2490496, 196609, null, 721507184, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 464 child 17 (script 1): [0, 393216, 2490496, 196609, null, 721504357, null, null, null, null, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 464 child 18 (script default): [0, 393216, 2490496, 196609, null, 721503090, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 464 child 19 (script default): [721420288, 6, 38, -2147483645, 30408747, Blow Kiss, 50, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 464 child 20 (script default): [721420288, 6, 38, -2147483645, 30408747, Panic, 50, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 464 child 21 (script default): [721420288, 6, 38, -2147483645, 30408747, Raspberry, 50, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 464 child 22 (script 1): [0, 393216, 2490496, 196609, null, 721503084, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 464 child 23 (script default): [721420288, 6, 38, -2147483645, 30408747, Salute, 50, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 464 child 24 (script default): [721420288, 6, 38, -2147483645, 30408747, Goblin Bow, 50, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 464 child 25 (script default): [721420288, 6, 38, -2147483645, 30408747, Goblin Salute, 50, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 464 child 26 (script default): [721420288, 6, 38, -2147483645, 30408747, Glass Box, 50, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 464 child 27 (script 1): [30408747, 0, 393216, 2490496, 196609, null, 721503084, null, null, null, null, null, null, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 464 child 28 (script 1): [0, 393216, 2490496, 196609, null, 721505381, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 464 child 29 (script default): [721420288, 6, 38, -2147483645, 30408747, Glass Wall, 50, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 464 child 30 (script default): [721420288, 6, 38, -2147483645, 30408747, Slap Head, 50, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 464 child 31 (script default): [721420288, 6, 38, -2147483645, 30408747, Stomp, 50, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 464 child 32 (script 1): [0, 393216, 2490496, 196609, null, 721503852, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 464 child 33 (script 1): [0, 393216, 2490496, 196609, null, 721504612, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 464 child 34 (script default): [0, 393216, 2490496, 196609, null, 721508975, null, null, null, null, null, null, null, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 464 child 35 (script 1): [0, 393216, 2490496, 196609, null, 721508975, null, null, null, null, null, null, null, null, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 464 child 36 (script default): [0, 393216, 2490496, 196609, null, 721508975, null, null, null, null, null, null, null, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 464 child 37 (script default): [721420288, 6, 38, -2147483645, 30408747, Scared, 50, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 464 child 38 (script default): [721420288, 6, 38, -2147483645, 30408747, Bunny-hop, 50, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 464 child 39 (script default): [721420288, 6, 38, -2147483645, 30408747, Skillcape, 50, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 464 child 40 (script default): [721420288, 6, 38, -2147483645, 30408747, Snowman Dance, 50, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 464 child 41 (script default): [721420288, 6, 38, -2147483645, 30408747, Air Guitar, 50, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 464 child 42 (script 1): [0, 393216, 2490496, 196609, null, 721507169, null, null, null, null, null, null, null, null, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 465 child 2 (script 2): [null, 0, 0] +Interface 465 child 3 (script 2): [null, 0, 0] +Interface 465 child 4 (script 2): [null, 0, 0] +Interface 465 child 5 (script 2): [null, 0, 0] +Interface 499 child 7 (script 3): [1, 23, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 499 child 10 (script 3): [32702474, 6574120, null, 45, 32702474, 4600330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 499 child 11 (script 3): [32702475, 6574120, null, 45, 32702475, 4600330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 499 child 12 (script 3): [32702476, 6574120, null, 45, 32702476, 4600330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 499 child 13 (script 3): [32702477, 6574120, null, 45, 32702477, 4600330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 499 child 14 (script 3): [32702478, 6574120, null, 45, 32702478, 4600330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 499 child 15 (script 3): [32702479, 6574120, null, 45, 32702479, 4600330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 499 child 16 (script 3): [32702480, 6574120, null, 45, 32702480, 4600330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 499 child 17 (script 3): [32702481, 6574120, null, 45, 32702481, 4600330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 499 child 18 (script 3): [32702482, 6574120, null, 45, 32702482, 4600330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 499 child 19 (script 3): [32702483, 6574120, null, 45, 32702483, 4600330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 499 child 20 (script 3): [32702484, 6574120, null, 45, 32702484, 4600330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 499 child 21 (script 3): [32702485, 6574120, null, 45, 32702485, 4600330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 499 child 22 (script 3): [32702486, 6574120, null, 45, 32702486, 4600330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 499 child 23 (script 3): [32702487, 6574120, null, 45, 32702487, 4600330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 510 child 128 (script 1): [542, null, 44] +Interface 510 child 128 (script 3): [196608, 35454976, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 521 child 13 (script 1): [832, null, 44] +Interface 521 child 13 (script 3): [196608, 54460416, 0, 16777216, 486539264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 521 child 32 (script 3): [-2147483645, 16168038, null, 45, -2147483645, 16750623, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 521 child 47 (script 3): [-2147483645, 16168038, null, 45, -2147483645, 16750623, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 521 child 58 (script 3): [-2147483645, 16168038, null, 45, -2147483645, 16750623, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 522 child 6 (script 1): [832, null, 44] +Interface 522 child 6 (script 3): [196608, 54460416, 0, 16777216, 486539264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 523 child 97 (script 3): [-2147483645, 34275424, 792, 789, 790, 791, 773, 788, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 523 child 100 (script 1): [832, null, 44] +Interface 523 child 100 (script 3): [196608, 54460416, 0, 16777216, 486539264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 2 (script 1): [0, 34537475, null, 69, 1, 34537475, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 5 (script 1): [0, 34537478, null, 69, 1, 34537478, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 8 (script 1): [0, 34537481, null, 69, 1, 34537481, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 11 (script 1): [0, 34537484, null, 69, 1, 34537484, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 14 (script 1): [0, 34537487, null, 69, 1, 34537487, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 17 (script 1): [0, 34537490, null, 69, 1, 34537490, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 20 (script 1): [0, 34537493, null, 69, 1, 34537493, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 23 (script 1): [0, 34537496, null, 69, 1, 34537496, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 26 (script 1): [0, 34537499, null, 69, 1, 34537499, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 29 (script 1): [0, 34537502, null, 69, 1, 34537502, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 32 (script 1): [0, 34537505, null, 69, 1, 34537505, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 35 (script 3): [-2147483645, 14784543, null, 45, -2147483645, 12547357, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 36 (script 3): [-2147483645, 14784543, null, 45, -2147483645, 12547357, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 38 (script 3): [-2147483645, 14784543, null, 45, -2147483645, 12547357, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 40 (script 2): [1, 34537475, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 41 (script 1): [0, 34537536, null, 69, 1, 34537536, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 42 (script 1): [0, 34537538, null, 69, 1, 34537538, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 43 (script 1): [0, 34537540, null, 69, 1, 34537540, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 44 (script 1): [0, 34537542, null, 69, 1, 34537542, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 45 (script 1): [0, 34537544, null, 69, 1, 34537544, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 46 (script 1): [0, 34537546, null, 69, 1, 34537546, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 47 (script 1): [0, 34537548, null, 69, 1, 34537548, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 48 (script 1): [0, 34537550, null, 69, 1, 34537550, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 49 (script 1): [0, 34537552, null, 69, 1, 34537552, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 50 (script 1): [0, 34537554, null, 69, 1, 34537554, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 51 (script 1): [0, 34537556, null, 69, 1, 34537556, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 52 (script 1): [0, 34537558, null, 69, 1, 34537558, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 53 (script 1): [0, 34537560, null, 69, 1, 34537560, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 54 (script 1): [0, 34537562, null, 69, 1, 34537562, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 55 (script 1): [0, 34537564, null, 69, 1, 34537564, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 56 (script 1): [0, 34537566, null, 69, 1, 34537566, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 57 (script 1): [0, 34537568, null, 69, 1, 34537568, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 58 (script 1): [0, 34537570, null, 69, 1, 34537570, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 59 (script 1): [0, 34537572, null, 69, 1, 34537572, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 60 (script 1): [0, 34537574, null, 69, 1, 34537574, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 61 (script 1): [0, 34537576, null, 69, 1, 34537576, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 62 (script 1): [0, 34537578, null, 69, 1, 34537578, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 63 (script 1): [0, 34537579, null, 69, 1, 34537579, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 110 (script 3): [-2147483645, 14784543, null, 45, -2147483645, 12547357, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 111 (script 3): [-2147483645, 14784543, null, 45, -2147483645, 12547357, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 112 (script 3): [-2147483645, 14784543, null, 45, -2147483645, 12547357, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 113 (script 3): [-2147483645, 14784543, null, 45, -2147483645, 12547357, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 116 (script 1): [0, 34537589, null, 69, 1, 34537589, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 119 (script 1): [0, 34537592, null, 69, 1, 34537592, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 122 (script 1): [0, 34537595, null, 69, 1, 34537595, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 125 (script 1): [0, 34537598, null, 69, 1, 34537598, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 128 (script 1): [0, 34537601, null, 69, 1, 34537601, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 131 (script 1): [0, 34537604, null, 69, 1, 34537604, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 134 (script 1): [0, 34537607, null, 69, 1, 34537607, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 137 (script 1): [0, 34537610, null, 69, 1, 34537610, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 140 (script 1): [0, 34537613, null, 69, 1, 34537613, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 143 (script 1): [0, 34537616, null, 69, 1, 34537616, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 146 (script 3): [-2147483645, 14784543, null, 45, -2147483645, 12547357, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 147 (script 3): [-2147483645, 14784543, null, 45, -2147483645, 12547357, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 148 (script 1): [0, 34537621, null, 69, 1, 34537621, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 152 (script 1): [538, null, 44] +Interface 527 child 152 (script 3): [196608, 35192832, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 154 (script 1): [0, 34537627, null, 69, 1, 34537627, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 157 (script 1): [0, 34537630, null, 69, 1, 34537630, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 160 (script 1): [0, 34537633, null, 69, 1, 34537633, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 163 (script 1): [0, 34537636, null, 69, 1, 34537636, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 166 (script 1): [0, 34537639, null, 69, 1, 34537639, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 169 (script 1): [0, 34537642, null, 69, 1, 34537642, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 172 (script 1): [0, 34537645, null, 69, 1, 34537645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 175 (script 1): [0, 34537648, null, 69, 1, 34537648, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 178 (script 1): [0, 34537651, null, 69, 1, 34537651, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 181 (script 1): [0, 34537654, null, 69, 1, 34537654, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 184 (script 1): [0, 34537657, null, 69, 1, 34537657, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 187 (script 1): [0, 34537660, null, 69, 1, 34537660, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 190 (script 1): [0, 34537663, null, 69, 1, 34537663, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 193 (script 1): [0, 34537666, null, 69, 1, 34537666, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 197 (script 3): [-2147483645, 14784543, null, 45, -2147483645, 12547357, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 527 child 198 (script 3): [-2147483645, 14784543, null, 45, -2147483645, 12547357, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 528 child 1 (script 1): [540, null, 44] +Interface 528 child 1 (script 3): [196608, 35323904, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 534 child 1 (script 1): [540, null, 44] +Interface 534 child 1 (script 3): [196608, 35323904, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 535 child 20 (script 1): [540, null, 44] +Interface 535 child 20 (script 3): [196608, 35323904, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 535 child 26 (script 3): [35061765, 25902, null, 67, 35061765, 25892, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 535 child 27 (script 3): [35061766, 25904, null, 67, 35061766, 25903, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 535 child 28 (script 3): [35061767, 25906, null, 67, 35061767, 25905, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 535 child 29 (script 3): [35061769, 25908, null, 67, 35061769, 25907, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 535 child 30 (script 3): [35061768, 25910, null, 67, 35061768, 25909, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 535 child 31 (script 3): [35061770, 25912, null, 67, 35061770, 25911, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 535 child 32 (script 3): [35061773, 25914, null, 67, 35061773, 25913, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 535 child 33 (script 3): [35061772, 25916, null, 67, 35061772, 25915, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 535 child 34 (script 3): [35061771, 25918, null, 67, 35061771, 25917, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 535 child 35 (script 3): [35061778, 25891, null, 67, 35061778, 25893, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 535 child 36 (script 3): [35061777, 25894, null, 67, 35061777, 25895, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 535 child 37 (script 3): [35061776, 25896, null, 67, 35061776, 25897, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 535 child 38 (script 3): [35061775, 25898, null, 67, 35061775, 25899, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 536 child 6 (script 1): [541, null, 44, 35127302, 542, 0] +Interface 536 child 6 (script 5): [29] +Interface 550 child 1 (script 3): [36044801, 36044802, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 550 child 4 (script default): [103] +Interface 550 child 5 (script 4): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 551 child 2 (script 3): [36110338, 36110337, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 551 child 4 (script 3): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 551 child 5 (script 2): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 553 child 10 (script default): [196608, 35128064, 11264, null, 196608, 35061760, 0, 16777216, 486539264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 553 child 16 (script 9): [134] +Interface 553 child 18 (script 3): [-2147483645, 16711680, null, 45, -2147483645, 16777215, 0, 512, 34560, 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 553 child 19 (script 3): [-2147483645, 16711680, null, 45, -2147483645, 16777215, 0, 512, 34560, 512, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 553 child 20 (script 3): [-2147483645, 16711680, null, 45, -2147483645, 16777215, 0, 512, 34560, 768, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 553 child 21 (script 3): [-2147483645, 16711680, null, 45, -2147483645, 16777215, 0, 512, 34560, 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 553 child 22 (script 3): [-2147483645, 16711680, null, 45, -2147483645, 16777215, 0, 512, 34560, 1280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 553 child 23 (script 3): [-2147483645, 16711680, null, 45, -2147483645, 16777215, 0, 512, 34560, 1536, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 553 child 24 (script 3): [-2147483645, 16711680, null, 45, -2147483645, 16777215, 0, 512, 34560, 1792, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 553 child 25 (script 3): [-2147483645, 16711680, null, 45, -2147483645, 16777215, 0, 512, 34560, 2048, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 553 child 26 (script 3): [-2147483645, 16711680, null, 45, -2147483645, 16777215, 0, 512, 34560, 2304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 553 child 27 (script 3): [-2147483645, 16711680, null, 45, -2147483645, 16777215, 0, 512, 34560, 2560, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 553 child 28 (script 3): [-2147483645, 16711680, null, 45, -2147483645, 16777215, 0, 512, 34560, 2816, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 553 child 29 (script 3): [-2147483645, 16711680, null, 45, -2147483645, 16777215, 0, 512, 34560, 3072, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 553 child 30 (script 3): [-2147483645, 16711680, null, 45, -2147483645, 16777215, 0, 512, 34560, 3328, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 554 child 6 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 554 child 7 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 554 child 8 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 554 child 9 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 555 child 8 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 555 child 9 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 555 child 10 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 555 child 11 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 555 child 12 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 555 child 13 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 556 child 9 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 556 child 10 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 556 child 11 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 556 child 12 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 556 child 13 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 556 child 14 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 556 child 15 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 560 child 12 (script 1): [832, null, 44, 36700172, 831, 0, 16777216, 486539264, 0, 0, 0, 0] +Interface 560 child 17 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 560 child 18 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 560 child 20 (script 1): [36700180, 9, 0, null, 163, 36700180, 0, 16777220, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 561 child 12 (script 1): [832, null, 44, 36765708, 831, 0, 16777216, 486539264, 0, 0, 0, 0] +Interface 561 child 17 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 561 child 18 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 561 child 20 (script 1): [36765716, 21, 0, null, 163, 36765716, 0, 16777220, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 562 child 12 (script 1): [832, null, 44, 36831244, 831, 0, 16777216, 486539264, 0, 0, 0, 0] +Interface 562 child 17 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 562 child 18 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 562 child 20 (script 1): [36831252, 2, 0, null, 163, 36831252, 0, 16777220, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 563 child 12 (script 1): [832, null, 44, 36896780, 831, 0, 16777216, 486539264, 0, 0, 0, 0] +Interface 563 child 17 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 563 child 18 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 563 child 20 (script 1): [36896788, 5, 0, null, 163, 36896788, 0, 16777220, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 564 child 12 (script 1): [832, null, 44, 36962316, 831, 0, 16777216, 486539264, 0, 0, 0, 0] +Interface 564 child 17 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 564 child 18 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 564 child 20 (script 1): [36962324, 23, 0, null, 163, 36962324, 0, 16777220, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 565 child 12 (script 1): [832, null, 44, 37027852, 831, 0, 16777216, 486539264, 0, 0, 0, 0] +Interface 565 child 17 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 565 child 18 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 565 child 20 (script 1): [37027860, 10, 0, null, 163, 37027860, 0, 16777220, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 566 child 12 (script 1): [832, null, 44, 37093388, 831, 0, 16777216, 486539264, 0, 0, 0, 0] +Interface 566 child 17 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 566 child 18 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 566 child 20 (script 1): [37093396, 6, 0, null, 163, 37093396, 0, 16777220, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 567 child 12 (script 1): [832, null, 44, 37158924, 831, 0, 16777216, 486539264, 0, 0, 0, 0] +Interface 567 child 17 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 567 child 18 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 567 child 20 (script 1): [37158932, 14, 0, null, 163, 37158932, 0, 16777220, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 568 child 12 (script 1): [832, null, 44, 37224460, 831, 0, 16777216, 486539264, 0, 0, 0, 0] +Interface 568 child 17 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 568 child 18 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 568 child 20 (script 1): [37224468, 3, 0, null, 163, 37224468, 0, 16777220, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 569 child 12 (script 1): [832, null, 44, 37289996, 831, 0, 16777216, 486539264, 0, 0, 0, 0] +Interface 569 child 17 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 569 child 18 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 569 child 20 (script 1): [37290004, 16, 0, null, 163, 37290004, 0, 16777220, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 570 child 12 (script 1): [832, null, 44, 37355532, 831, 0, 16777216, 486539264, 0, 0, 0, 0] +Interface 570 child 17 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 570 child 18 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 570 child 20 (script 1): [37355540, 17, 0, null, 163, 37355540, 0, 16777220, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 571 child 12 (script 1): [832, null, 44, 37421068, 831, 0, 16777216, 486539264, 0, 0, 0, 0] +Interface 571 child 17 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 571 child 18 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 571 child 20 (script 1): [37421076, 19, 0, null, 163, 37421076, 0, 16777220, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 572 child 12 (script 1): [832, null, 44, 37486604, 831, 0, 16777216, 486539264, 0, 0, 0, 0] +Interface 572 child 17 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 572 child 18 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 572 child 20 (script 1): [37486612, 13, 0, null, 163, 37486612, 0, 16777220, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 573 child 12 (script 1): [832, null, 44, 37552140, 831, 0, 16777216, 486539264, 0, 0, 0, 0] +Interface 573 child 17 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 573 child 18 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 573 child 20 (script 1): [37552148, 12, 0, null, 163, 37552148, 0, 16777220, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 574 child 12 (script 1): [832, null, 44, 37617676, 831, 0, 16777216, 486539264, 0, 0, 0, 0] +Interface 574 child 17 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 574 child 18 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 574 child 20 (script 1): [37617684, 1, 0, null, 163, 37617684, 0, 16777220, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 575 child 12 (script 1): [832, null, 44, 37683212, 831, 0, 16777216, 486539264, 0, 0, 0, 0] +Interface 575 child 17 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 575 child 18 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 575 child 20 (script 1): [37683220, 22, 0, null, 163, 37683220, 0, 16777220, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 576 child 12 (script 1): [832, null, 44, 37748748, 831, 0, 16777216, 486539264, 0, 0, 0, 0] +Interface 576 child 17 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 576 child 18 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 576 child 20 (script 1): [37748756, 8, 0, null, 163, 37748756, 0, 16777220, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 577 child 12 (script 1): [832, null, 44, 37814284, 831, 0, 16777216, 486539264, 0, 0, 0, 0] +Interface 577 child 17 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 577 child 18 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 577 child 20 (script 1): [37814292, 18, 0, null, 163, 37814292, 0, 16777220, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 578 child 12 (script 1): [832, null, 44, 37879820, 831, 0, 16777216, 486539264, 0, 0, 0, 0] +Interface 578 child 17 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 578 child 18 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 578 child 20 (script 1): [37879828, 15, 0, null, 163, 37879828, 0, 16777220, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 579 child 12 (script 1): [832, null, 44, 37945356, 831, 0, 16777216, 486539264, 0, 0, 0, 0] +Interface 579 child 17 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 579 child 18 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 579 child 20 (script 1): [37945364, 4, 0, null, 163, 37945364, 0, 16777220, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 580 child 12 (script 1): [832, null, 44, 38010892, 831, 0, 16777216, 486539264, 0, 0, 0, 0] +Interface 580 child 17 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 580 child 18 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 580 child 20 (script 1): [38010900, 20, 0, null, 163, 38010900, 0, 16777220, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 581 child 12 (script 1): [832, null, 44, 38076428, 831, 0, 16777216, 486539264, 0, 0, 0, 0] +Interface 581 child 18 (script 1): [38076434, 24, 0, null, 163, 38076434, 0, 16777220, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 583 child 13 (script 1): [832, null, 44, 38207501, 831, 0, 16777216, 486539264, 0, 0, 0, 0, 0] +Interface 583 child 17 (script default): [196610, null, 268435456, null, null, 789, 790, 791, 773, 788, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 583 child 18 (script 3): [-2147483645, 1, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 583 child 19 (script 3): [-2147483645, 13, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 583 child 20 (script 3): [-2147483645, 4, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 583 child 21 (script 3): [-2147483645, 3, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 583 child 22 (script 3): [-2147483645, 6, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 583 child 23 (script 3): [-2147483645, 5, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 583 child 24 (script 3): [-2147483645, 2, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 583 child 25 (script 3): [-2147483645, 11, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 583 child 26 (script 3): [-2147483645, 14, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 583 child 27 (script 3): [-2147483645, 15, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 583 child 28 (script 3): [-2147483645, 16, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 583 child 29 (script 3): [-2147483645, 20, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 583 child 30 (script 3): [-2147483645, 9, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 583 child 31 (script 3): [-2147483645, 17, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 583 child 32 (script 3): [-2147483645, 10, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 583 child 33 (script 3): [-2147483645, 12, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 583 child 34 (script 1): [-2147483645, 8, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 583 child 35 (script 3): [-2147483645, 7, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 583 child 36 (script 3): [-2147483645, 19, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 583 child 37 (script 3): [-2147483645, 18, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 583 child 38 (script 3): [-2147483645, 23, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 583 child 39 (script 3): [-2147483645, 24, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 583 child 40 (script 3): [-2147483645, 25, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 583 child 41 (script 3): [-2147483645, 26, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 583 child 42 (script 3): [-2147483645, 21, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 583 child 43 (script 3): [-2147483645, 27, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 583 child 44 (script 3): [-2147483645, 28, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 583 child 45 (script 3): [-2147483645, 29, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 588 child 2 (script 1): [542, null, 44] +Interface 588 child 2 (script 3): [196608, 35454976, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 588 child 7 (script 3): [170] +Interface 588 child 7 (script 16): [269056] +Interface 588 child 14 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 6574110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 588 child 20 (script 3): [-2147483645, 16777215, null, 169, 1, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 588 child 21 (script 3): [-2147483645, 16777215, null, 169, 2, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 588 child 22 (script 3): [-2147483645, 16777215, null, 169, 3, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 588 child 23 (script 3): [-2147483645, 16777215, null, 169, 4, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 589 child 2 (script 3): [-2147483645, null, 94, -2147483645, null, 92, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 589 child 3 (script 3): [-2147483645, null, 94, -2147483645, null, 92, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 589 child 5 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 589 child 8 (script 7): [194, -2147483644] +Interface 591 child 174 (script 2): [null] +Interface 591 child 176 (script 2): [null] +Interface 591 child 178 (script 2): [null] +Interface 591 child 180 (script default): [1050, null, 299] +Interface 591 child 180 (script 2): [null, +] +Interface 591 child 180 (script 3): [196608, 69337088, 0, null, 38, -2147483645, 38732075, Confirm Purchase, 25, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 591 child 182 (script default): [+, 0, 100663296, 637566976, 50332239, +Show Torso Selections, 25, 80, , 110848, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 591 child 183 (script default): [+, 0, 100663296, 637566976, 50332239, +Show Arms Selections, 25, 80, , 111104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 591 child 184 (script default): [+, 0, 100663296, 637566976, 50332239, +Show Legs Selections, 25, 80, , 111360, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 591 child 185 (script 9): [436] +Interface 591 child 186 (script 9): [437] +Interface 591 child 187 (script 9): [438] +Interface 591 child 188 (script 9): [439] +Interface 591 child 189 (script 9): [440] +Interface 591 child 190 (script 9): [441] +Interface 591 child 191 (script 9): [442] +Interface 591 child 192 (script 9): [443] +Interface 591 child 193 (script 9): [444] +Interface 591 child 194 (script 9): [445] +Interface 591 child 195 (script 9): [446] +Interface 591 child 196 (script 9): [447] +Interface 591 child 197 (script 9): [448] +Interface 591 child 198 (script 9): [449] +Interface 591 child 199 (script 9): [450] +Interface 591 child 200 (script 9): [451] +Interface 591 child 201 (script 9): [452] +Interface 591 child 202 (script 9): [453] +Interface 591 child 203 (script 9): [454] +Interface 591 child 204 (script 9): [455] +Interface 591 child 205 (script 9): [456] +Interface 591 child 206 (script 9): [457] +Interface 591 child 207 (script 9): [458] +Interface 591 child 208 (script 9): [459] +Interface 591 child 209 (script 9): [460] +Interface 591 child 210 (script 9): [461] +Interface 591 child 211 (script 9): [462] +Interface 591 child 212 (script 9): [463] +Interface 591 child 213 (script 9): [464] +Interface 591 child 214 (script 9): [465] +Interface 591 child 215 (script 9): [466] +Interface 591 child 216 (script 9): [467] +Interface 591 child 217 (script 9): [468] +Interface 591 child 218 (script 9): [469] +Interface 591 child 219 (script 9): [470] +Interface 591 child 220 (script 9): [471] +Interface 591 child 221 (script 9): [472] +Interface 591 child 252 (script 2): [1042, null, 299] +Interface 591 child 252 (script 4): [null, +] +Interface 591 child 252 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38732075, Burgundy, 25, 40, , 121088, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 591 child 253 (script 2): [1042, null, 299] +Interface 591 child 253 (script 4): [null, +] +Interface 591 child 253 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38732075, Red, 25, 40, , 121344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 591 child 254 (script 2): [1042, null, 299] +Interface 591 child 254 (script 4): [null, +] +Interface 591 child 254 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38732075, Dark Red, 25, 40, , 121600, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 591 child 255 (script 2): [1042, null, 299] +Interface 591 child 255 (script 4): [null, +] +Interface 591 child 255 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38732075, Pink, 25, 40, , 121856, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 591 child 256 (script 2): [1042, null, 299] +Interface 591 child 256 (script 4): [null, +] +Interface 591 child 256 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38732075, Dark Pink, 25, 40, , 122112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 591 child 257 (script 2): [1042, null, 299] +Interface 591 child 257 (script 4): [null, +] +Interface 591 child 257 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38732075, Orange, 25, 40, , 122368, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 591 child 258 (script 2): [1042, null, 299] +Interface 591 child 258 (script 4): [null, +] +Interface 591 child 258 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38732075, Burnt Orange, 25, 40, , 122624, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 591 child 259 (script 2): [1042, null, 299] +Interface 591 child 259 (script 4): [null, +] +Interface 591 child 259 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38732075, Peach, 25, 40, , 122880, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 591 child 260 (script 2): [1042, null, 299] +Interface 591 child 260 (script 4): [null, +] +Interface 591 child 260 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38732075, Light Khaki, 25, 40, , 123136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 591 child 261 (script 2): [1042, null, 299] +Interface 591 child 261 (script 4): [null, +] +Interface 591 child 261 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38732075, Khaki, 25, 40, , 123392, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 591 child 262 (script 2): [1042, null, 299] +Interface 591 child 262 (script 4): [null, +] +Interface 591 child 262 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38732075, Gold, 25, 40, , 123648, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 591 child 263 (script 2): [1042, null, 299] +Interface 591 child 263 (script 4): [null, +] +Interface 591 child 263 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38732075, Moss Green, 25, 40, , 123904, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 591 child 264 (script 2): [1042, null, 299] +Interface 591 child 264 (script 4): [null, +] +Interface 591 child 264 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38732075, Mint Green, 25, 40, , 124160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 591 child 265 (script 2): [1042, null, 299] +Interface 591 child 265 (script 4): [null, +] +Interface 591 child 265 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38732075, Sea Green, 25, 40, , 124416, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 591 child 266 (script 2): [1042, null, 299] +Interface 591 child 266 (script 4): [null, +] +Interface 591 child 266 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38732075, Forest Green, 25, 40, , 124672, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 591 child 267 (script 2): [1042, null, 299] +Interface 591 child 267 (script 4): [null, +] +Interface 591 child 267 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38732075, Dark Green, 25, 40, , 124928, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 591 child 268 (script 2): [1042, null, 299] +Interface 591 child 268 (script 4): [null, +] +Interface 591 child 268 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38732075, Royal Blue, 25, 40, , 125184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 591 child 269 (script 2): [1042, null, 299] +Interface 591 child 269 (script 4): [null, +] +Interface 591 child 269 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38732075, Dark Blue, 25, 40, , 125440, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 591 child 270 (script 2): [1042, null, 299] +Interface 591 child 270 (script 4): [null, +] +Interface 591 child 270 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38732075, Light Blue, 25, 40, , 125696, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 591 child 271 (script 2): [1042, null, 299] +Interface 591 child 271 (script 4): [null, +] +Interface 591 child 271 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38732075, Pale Blue, 25, 40, , 125952, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 591 child 272 (script 2): [1042, null, 299] +Interface 591 child 272 (script 4): [null, +] +Interface 591 child 272 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38732075, Mauve, 25, 40, , 126208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 591 child 273 (script 2): [1042, null, 299] +Interface 591 child 273 (script 4): [null, +] +Interface 591 child 273 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38732075, Violet, 25, 40, , 126464, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 591 child 274 (script 2): [1042, null, 299] +Interface 591 child 274 (script 4): [null, +] +Interface 591 child 274 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38732075, Indigo, 25, 40, , 126720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 591 child 275 (script 2): [1042, null, 299] +Interface 591 child 275 (script 4): [null, +] +Interface 591 child 275 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38732075, Navy Blue, 25, 40, , 126976, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 591 child 276 (script 2): [1042, null, 299] +Interface 591 child 276 (script 4): [null, +] +Interface 591 child 276 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38732075, Beige, 25, 40, , 127232, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 591 child 277 (script 2): [1042, null, 299] +Interface 591 child 277 (script 4): [null, +] +Interface 591 child 277 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38732075, Light Grey, 25, 40, , 127488, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 591 child 278 (script 2): [1042, null, 299] +Interface 591 child 278 (script 4): [null, +] +Interface 591 child 278 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38732075, Taupe, 25, 40, , 127744, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 591 child 279 (script 2): [1042, null, 299] +Interface 591 child 279 (script 4): [null, +] +Interface 591 child 279 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38732075, Dark Grey, 25, 40, , 128000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 591 child 280 (script 2): [1042, null, 299] +Interface 591 child 280 (script 4): [null, +] +Interface 591 child 280 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38732075, Black, 25, 40, , 128256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 591 child 281 (script 1): [832, null, 44] +Interface 591 child 281 (script 3): [196608, 54460416, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 591 child 297 (script 3): [38731956, 1050, null, 299, 38732075, 38731956, 1058, 0, 393216, 2490496, 196610, null, +Confirm Purchase, 25, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 592 child 132 (script default): [1050, null, 299] +Interface 592 child 132 (script 2): [null, -402620416] +Interface 592 child 132 (script 4): [1058, 0, 393216] +Interface 592 child 132 (script 7): [-2147483645, 38797544, Confirm Purchase, 25, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 592 child 135 (script 1): [0, 393216, 2490496, 196610, null, -402566296, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, null, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 592 child 136 (script 2): [null] +Interface 592 child 137 (script 9): [318] +Interface 592 child 138 (script 9): [319] +Interface 592 child 139 (script 9): [320] +Interface 592 child 140 (script 9): [321] +Interface 592 child 141 (script 9): [322] +Interface 592 child 142 (script 9): [323] +Interface 592 child 143 (script 9): [324] +Interface 592 child 144 (script 9): [325] +Interface 592 child 145 (script 9): [326] +Interface 592 child 146 (script 9): [327] +Interface 592 child 147 (script 9): [328] +Interface 592 child 148 (script 9): [329] +Interface 592 child 149 (script 9): [330] +Interface 592 child 150 (script 9): [331] +Interface 592 child 151 (script 9): [332] +Interface 592 child 152 (script 9): [333] +Interface 592 child 153 (script 9): [334] +Interface 592 child 154 (script 9): [335] +Interface 592 child 155 (script 9): [336] +Interface 592 child 156 (script 9): [337] +Interface 592 child 157 (script 9): [338] +Interface 592 child 158 (script 9): [339] +Interface 592 child 185 (script 2): [1042, null, 299] +Interface 592 child 185 (script 4): [null, -402620416] +Interface 592 child 185 (script 6): [1041, 0, 393216] +Interface 592 child 185 (script 9): [-2147483645, 38797544, Burgundy, 25, 40, , 87040, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 592 child 186 (script 2): [1042, null, 299] +Interface 592 child 186 (script 4): [null, -402620416] +Interface 592 child 186 (script 6): [1041, 0, 393216] +Interface 592 child 186 (script 9): [-2147483645, 38797544, Red, 25, 40, , 87296, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 592 child 187 (script 2): [1042, null, 299] +Interface 592 child 187 (script 4): [null, -402620416] +Interface 592 child 187 (script 6): [1041, 0, 393216] +Interface 592 child 187 (script 9): [-2147483645, 38797544, Vermillion, 25, 40, , 87552, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 592 child 188 (script 2): [1042, null, 299] +Interface 592 child 188 (script 4): [null, -402620416] +Interface 592 child 188 (script 6): [1041, 0, 393216] +Interface 592 child 188 (script 9): [-2147483645, 38797544, Pink, 25, 40, , 87808, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 592 child 189 (script 2): [1042, null, 299] +Interface 592 child 189 (script 4): [null, -402620416] +Interface 592 child 189 (script 6): [1041, 0, 393216] +Interface 592 child 189 (script 9): [-2147483645, 38797544, Orange, 25, 40, , 88064, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 592 child 190 (script 2): [1042, null, 299] +Interface 592 child 190 (script 4): [null, -402620416] +Interface 592 child 190 (script 6): [1041, 0, 393216] +Interface 592 child 190 (script 9): [-2147483645, 38797544, Yellow, 25, 40, , 88320, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 592 child 191 (script 2): [1042, null, 299] +Interface 592 child 191 (script 4): [null, -402620416] +Interface 592 child 191 (script 6): [1041, 0, 393216] +Interface 592 child 191 (script 9): [-2147483645, 38797544, Peach, 25, 40, , 88576, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 592 child 192 (script 2): [1042, null, 299] +Interface 592 child 192 (script 4): [null, -402620416] +Interface 592 child 192 (script 6): [1041, 0, 393216] +Interface 592 child 192 (script 9): [-2147483645, 38797544, Brown, 25, 40, , 88832, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 592 child 193 (script 2): [1042, null, 299] +Interface 592 child 193 (script 4): [null, -402620416] +Interface 592 child 193 (script 6): [1041, 0, 393216] +Interface 592 child 193 (script 9): [-2147483645, 38797544, Dark Brown, 25, 40, , 89088, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 592 child 194 (script 2): [1042, null, 299] +Interface 592 child 194 (script 4): [null, -402620416] +Interface 592 child 194 (script 6): [1041, 0, 393216] +Interface 592 child 194 (script 9): [-2147483645, 38797544, Light Brown, 25, 40, , 89344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 592 child 195 (script 2): [1042, null, 299] +Interface 592 child 195 (script 4): [null, -402620416] +Interface 592 child 195 (script 6): [1041, 0, 393216] +Interface 592 child 195 (script 9): [-2147483645, 38797544, Mint Green, 25, 40, , 89600, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 592 child 196 (script 2): [1042, null, 299] +Interface 592 child 196 (script 4): [null, -402620416] +Interface 592 child 196 (script 6): [1041, 0, 393216] +Interface 592 child 196 (script 9): [-2147483645, 38797544, Green, 25, 40, , 89856, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 592 child 197 (script 2): [1042, null, 299] +Interface 592 child 197 (script 4): [null, -402620416] +Interface 592 child 197 (script 6): [1041, 0, 393216] +Interface 592 child 197 (script 9): [-2147483645, 38797544, Dark Green, 25, 40, , 90112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 592 child 198 (script 2): [1042, null, 299] +Interface 592 child 198 (script 4): [null, -402620416] +Interface 592 child 198 (script 6): [1041, 0, 393216] +Interface 592 child 198 (script 9): [-2147483645, 38797544, Dark Blue, 25, 40, , 90368, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 592 child 199 (script 2): [1042, null, 299] +Interface 592 child 199 (script 4): [null, -402620416] +Interface 592 child 199 (script 6): [1041, 0, 393216] +Interface 592 child 199 (script 9): [-2147483645, 38797544, Turquoise, 25, 40, , 90624, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 592 child 200 (script 2): [1042, null, 299] +Interface 592 child 200 (script 4): [null, -402620416] +Interface 592 child 200 (script 6): [1041, 0, 393216] +Interface 592 child 200 (script 9): [-2147483645, 38797544, Cyan, 25, 40, , 90880, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 592 child 201 (script 2): [1042, null, 299] +Interface 592 child 201 (script 4): [null, -402620416] +Interface 592 child 201 (script 6): [1041, 0, 393216] +Interface 592 child 201 (script 9): [-2147483645, 38797544, Purple, 25, 40, , 91136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 592 child 202 (script 2): [1042, null, 299] +Interface 592 child 202 (script 4): [null, -402620416] +Interface 592 child 202 (script 6): [1041, 0, 393216] +Interface 592 child 202 (script 9): [-2147483645, 38797544, Violet, 25, 40, , 91392, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 592 child 203 (script 2): [1042, null, 299] +Interface 592 child 203 (script 4): [null, -402620416] +Interface 592 child 203 (script 6): [1041, 0, 393216] +Interface 592 child 203 (script 9): [-2147483645, 38797544, Indigo, 25, 40, , 91648, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 592 child 204 (script 2): [1042, null, 299] +Interface 592 child 204 (script 4): [null, -402620416] +Interface 592 child 204 (script 6): [1041, 0, 393216] +Interface 592 child 204 (script 9): [-2147483645, 38797544, Dark Grey, 25, 40, , 91904, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 592 child 205 (script 2): [1042, null, 299] +Interface 592 child 205 (script 4): [null, -402620416] +Interface 592 child 205 (script 6): [1041, 0, 393216] +Interface 592 child 205 (script 9): [-2147483645, 38797544, Military Grey, 25, 40, , 92160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 592 child 206 (script 2): [1042, null, 299] +Interface 592 child 206 (script 4): [null, -402620416] +Interface 592 child 206 (script 6): [1041, 0, 393216] +Interface 592 child 206 (script 9): [-2147483645, 38797544, White, 25, 40, , 92416, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 592 child 207 (script 2): [1042, null, 299] +Interface 592 child 207 (script 4): [null, -402620416] +Interface 592 child 207 (script 6): [1041, 0, 393216] +Interface 592 child 207 (script 9): [-2147483645, 38797544, Light Grey, 25, 40, , 92672, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 592 child 208 (script 2): [1042, null, 299] +Interface 592 child 208 (script 4): [null, -402620416] +Interface 592 child 208 (script 6): [1041, 0, 393216] +Interface 592 child 208 (script 9): [-2147483645, 38797544, Taupe, 25, 40, , 92928, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 592 child 209 (script 2): [1042, null, 299] +Interface 592 child 209 (script 4): [null, -402620416] +Interface 592 child 209 (script 6): [1041, 0, 393216] +Interface 592 child 209 (script 9): [-2147483645, 38797544, Black, 25, 40, , 93184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 592 child 210 (script 1): [832, null, 44] +Interface 592 child 210 (script 3): [196608, 54460416, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 592 child 230 (script 3): [38797444, 1050, null, 299, 38797544, 38797444, 1058, 0, 393216, 2490496, 196610, null, -402570385, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, null, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 593 child 117 (script default): [1050, null, 299] +Interface 593 child 117 (script 2): [null, -1744797696] +Interface 593 child 117 (script 4): [1058, 0, 393216] +Interface 593 child 117 (script 7): [-2147483645, 38863000, Confirm Purchase, 25, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 593 child 120 (script default): [-1744830464, 6, 38, -2147483645, 38863000, Show Silver Selections, 25, 80, , 76800, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 593 child 121 (script default): [-1744830464, 6, 38, -2147483645, 38863000, Show Gold Selections, 25, 80, , 77056, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 593 child 122 (script 9): [302] +Interface 593 child 123 (script 9): [303] +Interface 593 child 124 (script 9): [304] +Interface 593 child 125 (script 9): [305] +Interface 593 child 126 (script 9): [306] +Interface 593 child 127 (script 9): [307] +Interface 593 child 128 (script 9): [308] +Interface 593 child 129 (script 9): [309] +Interface 593 child 130 (script 9): [310] +Interface 593 child 131 (script 9): [311] +Interface 593 child 132 (script 9): [312] +Interface 593 child 133 (script 9): [313] +Interface 593 child 134 (script 9): [314] +Interface 593 child 135 (script 9): [315] +Interface 593 child 136 (script 1): [832, null, 44] +Interface 593 child 136 (script 3): [196608, 54460416, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 593 child 150 (script 3): [38862965, 1050, null, 299, 38863000, 38862965, 1058, 0, 393216, 2490496, 196610, null, -1744747665, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, null, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 594 child 174 (script 3): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 594 child 176 (script 3): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 594 child 178 (script 3): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 594 child 181 (script default): [1050, null, 299] +Interface 594 child 181 (script 2): [null, ,] +Interface 594 child 181 (script 3): [196608, 69337088, 0, null, 38, -2147483645, 38928684, Confirm Purchase, 25, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 594 child 183 (script default): [,, 0, 100663296, 637566976, 50332242, ,Show Torso Selections, 25, 80, , 58368, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 594 child 184 (script default): [,, 0, 100663296, 637566976, 50332242, ,Show Arms Selections, 25, 80, , 58624, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 594 child 185 (script default): [,, 0, 100663296, 637566976, 50332242, ,Show Legs Selections, 25, 80, , 58880, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 594 child 186 (script 9): [231] +Interface 594 child 187 (script 9): [232] +Interface 594 child 188 (script 9): [233] +Interface 594 child 189 (script 9): [234] +Interface 594 child 190 (script 9): [235] +Interface 594 child 191 (script 9): [236] +Interface 594 child 192 (script 9): [237] +Interface 594 child 193 (script 9): [238] +Interface 594 child 194 (script 9): [239] +Interface 594 child 195 (script 9): [240] +Interface 594 child 196 (script 9): [241] +Interface 594 child 197 (script 9): [242] +Interface 594 child 198 (script 9): [243] +Interface 594 child 199 (script 9): [245] +Interface 594 child 200 (script 9): [244] +Interface 594 child 201 (script 9): [246] +Interface 594 child 202 (script 9): [247] +Interface 594 child 203 (script 9): [248] +Interface 594 child 204 (script 9): [249] +Interface 594 child 205 (script 9): [250] +Interface 594 child 206 (script 9): [251] +Interface 594 child 207 (script 9): [252] +Interface 594 child 208 (script 9): [253] +Interface 594 child 209 (script 9): [254] +Interface 594 child 210 (script 9): [255] +Interface 594 child 211 (script 9): [256] +Interface 594 child 212 (script 9): [257] +Interface 594 child 213 (script 9): [258] +Interface 594 child 214 (script 9): [259] +Interface 594 child 215 (script 9): [260] +Interface 594 child 216 (script 9): [261] +Interface 594 child 217 (script 9): [262] +Interface 594 child 218 (script 9): [263] +Interface 594 child 219 (script 9): [264] +Interface 594 child 220 (script 9): [265] +Interface 594 child 221 (script 9): [266] +Interface 594 child 222 (script 9): [267] +Interface 594 child 253 (script 2): [1042, null, 299] +Interface 594 child 253 (script 4): [null, ,] +Interface 594 child 253 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38928684, Burgundy, 25, 40, , 68608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 594 child 254 (script 2): [1042, null, 299] +Interface 594 child 254 (script 4): [null, ,] +Interface 594 child 254 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38928684, Red, 25, 40, , 68864, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 594 child 255 (script 2): [1042, null, 299] +Interface 594 child 255 (script 4): [null, ,] +Interface 594 child 255 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38928684, Dark Red, 25, 40, , 69120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 594 child 256 (script 2): [1042, null, 299] +Interface 594 child 256 (script 4): [null, ,] +Interface 594 child 256 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38928684, Pink, 25, 40, , 69376, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 594 child 257 (script 2): [1042, null, 299] +Interface 594 child 257 (script 4): [null, ,] +Interface 594 child 257 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38928684, Dark Pink, 25, 40, , 69632, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 594 child 258 (script 2): [1042, null, 299] +Interface 594 child 258 (script 4): [null, ,] +Interface 594 child 258 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38928684, Orange, 25, 40, , 69888, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 594 child 259 (script 2): [1042, null, 299] +Interface 594 child 259 (script 4): [null, ,] +Interface 594 child 259 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38928684, Burnt Orange, 25, 40, , 70144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 594 child 260 (script 2): [1042, null, 299] +Interface 594 child 260 (script 4): [null, ,] +Interface 594 child 260 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38928684, Peach, 25, 40, , 70400, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 594 child 261 (script 2): [1042, null, 299] +Interface 594 child 261 (script 4): [null, ,] +Interface 594 child 261 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38928684, Light Khaki, 25, 40, , 70656, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 594 child 262 (script 2): [1042, null, 299] +Interface 594 child 262 (script 4): [null, ,] +Interface 594 child 262 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38928684, Khaki, 25, 40, , 70912, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 594 child 263 (script 2): [1042, null, 299] +Interface 594 child 263 (script 4): [null, ,] +Interface 594 child 263 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38928684, Gold, 25, 40, , 71168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 594 child 264 (script 2): [1042, null, 299] +Interface 594 child 264 (script 4): [null, ,] +Interface 594 child 264 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38928684, Moss Green, 25, 40, , 71424, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 594 child 265 (script 2): [1042, null, 299] +Interface 594 child 265 (script 4): [null, ,] +Interface 594 child 265 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38928684, Mint Green, 25, 40, , 71680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 594 child 266 (script 2): [1042, null, 299] +Interface 594 child 266 (script 4): [null, ,] +Interface 594 child 266 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38928684, Sea Green, 25, 40, , 71936, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 594 child 267 (script 2): [1042, null, 299] +Interface 594 child 267 (script 4): [null, ,] +Interface 594 child 267 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38928684, Forest Green, 25, 40, , 72192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 594 child 268 (script 2): [1042, null, 299] +Interface 594 child 268 (script 4): [null, ,] +Interface 594 child 268 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38928684, Dark Green, 25, 40, , 72448, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 594 child 269 (script 2): [1042, null, 299] +Interface 594 child 269 (script 4): [null, ,] +Interface 594 child 269 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38928684, Royal Blue, 25, 40, , 72704, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 594 child 270 (script 2): [1042, null, 299] +Interface 594 child 270 (script 4): [null, ,] +Interface 594 child 270 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38928684, Dark Blue, 25, 40, , 72960, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 594 child 271 (script 2): [1042, null, 299] +Interface 594 child 271 (script 4): [null, ,] +Interface 594 child 271 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38928684, Light Blue, 25, 40, , 73216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 594 child 272 (script 2): [1042, null, 299] +Interface 594 child 272 (script 4): [null, ,] +Interface 594 child 272 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38928684, Pale Blue, 25, 40, , 73472, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 594 child 273 (script 2): [1042, null, 299] +Interface 594 child 273 (script 4): [null, ,] +Interface 594 child 273 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38928684, Mauve, 25, 40, , 73728, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 594 child 274 (script 2): [1042, null, 299] +Interface 594 child 274 (script 4): [null, ,] +Interface 594 child 274 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38928684, Violet, 25, 40, , 73984, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 594 child 275 (script 2): [1042, null, 299] +Interface 594 child 275 (script 4): [null, ,] +Interface 594 child 275 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38928684, Indigo, 25, 40, , 74240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 594 child 276 (script 2): [1042, null, 299] +Interface 594 child 276 (script 4): [null, ,] +Interface 594 child 276 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38928684, Navy Blue, 25, 40, , 74496, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 594 child 277 (script 2): [1042, null, 299] +Interface 594 child 277 (script 4): [null, ,] +Interface 594 child 277 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38928684, Beige, 25, 40, , 74752, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 594 child 278 (script 2): [1042, null, 299] +Interface 594 child 278 (script 4): [null, ,] +Interface 594 child 278 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38928684, Light Grey, 25, 40, , 75008, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 594 child 279 (script 2): [1042, null, 299] +Interface 594 child 279 (script 4): [null, ,] +Interface 594 child 279 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38928684, Taupe, 25, 40, , 75264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 594 child 280 (script 2): [1042, null, 299] +Interface 594 child 280 (script 4): [null, ,] +Interface 594 child 280 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38928684, Dark Grey, 25, 40, , 75520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 594 child 281 (script 2): [1042, null, 299] +Interface 594 child 281 (script 4): [null, ,] +Interface 594 child 281 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 38928684, Black, 25, 40, , 75776, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 594 child 282 (script 1): [832, null, 44] +Interface 594 child 282 (script 3): [196608, 54460416, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 594 child 298 (script 3): [38928565, 1050, null, 299, 38928684, 38928565, 1058, 0, 393216, 2490496, 196610, null, ,Confirm Purchase, 25, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 595 child 117 (script default): [1050, null, 299] +Interface 595 child 117 (script 2): [null, -1744797696] +Interface 595 child 117 (script 4): [1058, 0, 393216] +Interface 595 child 117 (script 7): [-2147483645, 38994072, Confirm Purchase, 25, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 595 child 120 (script default): [-1744830464, 6, 38, -2147483645, 38994072, Show Silver Selections, 25, 80, , 53248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 595 child 121 (script default): [-1744830464, 6, 38, -2147483645, 38994072, Show Gold Selections, 25, 80, , 53504, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 595 child 122 (script 9): [210] +Interface 595 child 123 (script 9): [211] +Interface 595 child 124 (script 9): [212] +Interface 595 child 125 (script 9): [213] +Interface 595 child 126 (script 9): [214] +Interface 595 child 127 (script 9): [215] +Interface 595 child 128 (script 9): [216] +Interface 595 child 129 (script 9): [217] +Interface 595 child 130 (script 9): [218] +Interface 595 child 131 (script 9): [219] +Interface 595 child 132 (script 9): [220] +Interface 595 child 133 (script 9): [221] +Interface 595 child 134 (script 9): [222] +Interface 595 child 135 (script 9): [223] +Interface 595 child 136 (script 1): [832, null, 44] +Interface 595 child 136 (script 3): [196608, 54460416, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 595 child 150 (script 3): [38994037, 1050, null, 299, 38994072, 38994037, 1058, 0, 393216, 2490496, 196610, null, -1744747665, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, null, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 596 child 160 (script default): [1050, null, 299] +Interface 596 child 160 (script 2): [null, ] +Interface 596 child 160 (script 3): [196608, 69337088, 0, null, 38, -2147483645, 39059727, Confirm Purchase, 25, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 596 child 163 (script default): [null] +Interface 596 child 163 (script 8): [38, -2147483645, 39059727, Show Hair Selections, 25, 80] +Interface 596 child 163 (script 9): [369] +Interface 596 child 164 (script default): [, 0, 100663296, 637566976, 50332244, Show Beard Selections, 25, 80, , 94720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 596 child 165 (script 2): [null] +Interface 596 child 166 (script 2): [null] +Interface 596 child 167 (script 9): [371] +Interface 596 child 168 (script 9): [372] +Interface 596 child 169 (script 9): [373] +Interface 596 child 170 (script 9): [374] +Interface 596 child 171 (script 9): [375] +Interface 596 child 172 (script 9): [376] +Interface 596 child 173 (script 9): [377] +Interface 596 child 174 (script 9): [378] +Interface 596 child 175 (script 9): [379] +Interface 596 child 176 (script 9): [380] +Interface 596 child 177 (script 9): [381] +Interface 596 child 178 (script 9): [382] +Interface 596 child 179 (script 9): [383] +Interface 596 child 180 (script 9): [384] +Interface 596 child 181 (script 9): [385] +Interface 596 child 182 (script 9): [386] +Interface 596 child 183 (script 9): [387] +Interface 596 child 184 (script 9): [388] +Interface 596 child 185 (script 9): [389] +Interface 596 child 186 (script 9): [390] +Interface 596 child 187 (script 9): [391] +Interface 596 child 188 (script 9): [392] +Interface 596 child 189 (script 9): [393] +Interface 596 child 190 (script 9): [394] +Interface 596 child 191 (script 9): [395] +Interface 596 child 192 (script 9): [396] +Interface 596 child 193 (script 9): [397] +Interface 596 child 194 (script 9): [398] +Interface 596 child 195 (script 9): [399] +Interface 596 child 196 (script 9): [400] +Interface 596 child 197 (script 9): [401] +Interface 596 child 224 (script 2): [1042, null, 299] +Interface 596 child 224 (script 4): [null, ] +Interface 596 child 224 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 39059727, Burgundy, 25, 40, , 102912, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 596 child 225 (script 2): [1042, null, 299] +Interface 596 child 225 (script 4): [null, ] +Interface 596 child 225 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 39059727, Red, 25, 40, , 103168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 596 child 226 (script 2): [1042, null, 299] +Interface 596 child 226 (script 4): [null, ] +Interface 596 child 226 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 39059727, Vermillion, 25, 40, , 103424, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 596 child 227 (script 2): [1042, null, 299] +Interface 596 child 227 (script 4): [null, ] +Interface 596 child 227 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 39059727, Pink, 25, 40, , 103680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 596 child 228 (script 2): [1042, null, 299] +Interface 596 child 228 (script 4): [null, ] +Interface 596 child 228 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 39059727, Orange, 25, 40, , 103936, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 596 child 229 (script 2): [1042, null, 299] +Interface 596 child 229 (script 4): [null, ] +Interface 596 child 229 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 39059727, Yellow, 25, 40, , 104192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 596 child 230 (script 2): [1042, null, 299] +Interface 596 child 230 (script 4): [null, ] +Interface 596 child 230 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 39059727, Peach, 25, 40, , 104448, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 596 child 231 (script 2): [1042, null, 299] +Interface 596 child 231 (script 4): [null, ] +Interface 596 child 231 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 39059727, Brown, 25, 40, , 104704, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 596 child 232 (script 2): [1042, null, 299] +Interface 596 child 232 (script 4): [null, ] +Interface 596 child 232 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 39059727, Dark Brown, 25, 40, , 104960, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 596 child 233 (script 2): [1042, null, 299] +Interface 596 child 233 (script 4): [null, ] +Interface 596 child 233 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 39059727, Light Brown, 25, 40, , 105216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 596 child 234 (script 2): [1042, null, 299] +Interface 596 child 234 (script 4): [null, ] +Interface 596 child 234 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 39059727, Mint Green, 25, 40, , 105472, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 596 child 235 (script 2): [1042, null, 299] +Interface 596 child 235 (script 4): [null, ] +Interface 596 child 235 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 39059727, Green, 25, 40, , 105728, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 596 child 236 (script 2): [1042, null, 299] +Interface 596 child 236 (script 4): [null, ] +Interface 596 child 236 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 39059727, Dark Green, 25, 40, , 105984, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 596 child 237 (script 2): [1042, null, 299] +Interface 596 child 237 (script 4): [null, ] +Interface 596 child 237 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 39059727, Dark Blue, 25, 40, , 106240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 596 child 238 (script 2): [1042, null, 299] +Interface 596 child 238 (script 4): [null, ] +Interface 596 child 238 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 39059727, Turquoise, 25, 40, , 106496, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 596 child 239 (script 2): [1042, null, 299] +Interface 596 child 239 (script 4): [null, ] +Interface 596 child 239 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 39059727, Cyan, 25, 40, , 106752, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 596 child 240 (script 2): [1042, null, 299] +Interface 596 child 240 (script 4): [null, ] +Interface 596 child 240 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 39059727, Purple, 25, 40, , 107008, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 596 child 241 (script 2): [1042, null, 299] +Interface 596 child 241 (script 4): [null, ] +Interface 596 child 241 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 39059727, Violet, 25, 40, , 107264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 596 child 242 (script 2): [1042, null, 299] +Interface 596 child 242 (script 4): [null, ] +Interface 596 child 242 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 39059727, Indigo, 25, 40, , 107520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 596 child 243 (script 2): [1042, null, 299] +Interface 596 child 243 (script 4): [null, ] +Interface 596 child 243 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 39059727, Dark Grey, 25, 40, , 107776, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 596 child 244 (script 2): [1042, null, 299] +Interface 596 child 244 (script 4): [null, ] +Interface 596 child 244 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 39059727, Military Grey, 25, 40, , 108032, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 596 child 245 (script 2): [1042, null, 299] +Interface 596 child 245 (script 4): [null, ] +Interface 596 child 245 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 39059727, White, 25, 40, , 108288, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 596 child 246 (script 2): [1042, null, 299] +Interface 596 child 246 (script 4): [null, ] +Interface 596 child 246 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 39059727, Light Grey, 25, 40, , 108544, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 596 child 247 (script 2): [1042, null, 299] +Interface 596 child 247 (script 4): [null, ] +Interface 596 child 247 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 39059727, Taupe, 25, 40, , 108800, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 596 child 248 (script 2): [1042, null, 299] +Interface 596 child 248 (script 4): [null, ] +Interface 596 child 248 (script 5): [196608, 68222976, 0, null, 38, -2147483645, 39059727, Black, 25, 40, , 109056, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 596 child 249 (script 1): [832, null, 44] +Interface 596 child 249 (script 3): [196608, 54460416, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 596 child 269 (script 3): [39059616, 1050, null, 299, 39059727, 39059616, 1058, 0, 393216, 2490496, 196610, null, Confirm Purchase, 25, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 600 child 12 (script 1): [832, null, 44, 39321612, 831, 0, 16777216, 486539264, 0, 0, 0, 0] +Interface 600 child 17 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 600 child 18 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 600 child 20 (script 1): [39321620, 25, 0, null, 163, 39321620, 0, 16777220, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 605 child 0 (script 6): [511] +Interface 608 child 2 (script 3): [66, 0, 1, 0, -2147483645] +Interface 613 child 11 (script default): [null, 352321536] +Interface 613 child 11 (script 5): [509, -2147483645] +Interface 613 child 12 (script default): [null, 352321536] +Interface 613 child 12 (script 5): [509, -2147483645] +Interface 613 child 13 (script default): [null, 352321536] +Interface 613 child 13 (script 5): [509, -2147483645] +Interface 613 child 15 (script 1): [540, null, 44] +Interface 613 child 15 (script 3): [196608, 35323904, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 613 child 17 (script default): [null, 335544320] +Interface 613 child 17 (script 5): [136, -2147483645] +Interface 613 child 18 (script default): [null, 335544320] +Interface 613 child 18 (script 5): [136, -2147483645] +Interface 613 child 19 (script 1): [40173588, 0, 131072, 8913024, 196608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 615 child 2 (script 6): [516] +Interface 617 child 6 (script 1): [1065, null, 44] +Interface 617 child 6 (script 3): [196608, 69730304, 1, 517, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 617 child 8 (script 2): [-2147483645, 9200660, null, 45, -2147483645, 4600330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 617 child 13 (script 2): [-2147483645, 9200660, null, 45, -2147483645, 4600330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 617 child 19 (script 2): [-2147483645, 9200660, null, 45, -2147483645, 4600330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 619 child 7 (script 1): [832, null, 44] +Interface 619 child 7 (script 3): [196608, 54460416, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 619 child 28 (script 1): [40566843, 0, 393216, 2490496, 196610, null, 989938025, null, null, null, null, null, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 619 child 29 (script 1): [40566843, 0, 393216, 2490496, 196610, null, 989941097, null, null, null, null, null, null, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 619 child 30 (script 1): [40566843, 0, 393216, 2490496, 196610, null, 989943649, null, null, null, null, null, null, null, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 619 child 31 (script 1): [40566843, 0, 393216, 2490496, 196610, null, 989939041, null, null, null, null, null, null, null, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 619 child 32 (script 1): [40566843, 0, 393216, 2490496, 196610, null, 989939305, null, null, null, null, null, null, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 619 child 33 (script 1): [40566843, 0, 393216, 2490496, 196610, null, 989938287, null, null, null, null, null, null, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 619 child 34 (script 1): [40566843, 0, 393216, 2490496, 196610, null, 989938543, null, null, null, null, null, null, null, null, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 619 child 35 (script 1): [40566843, 0, 393216, 2490496, 196610, null, 989938536, null, null, null, null, null, null, null, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 619 child 36 (script 1): [40566843, 0, 393216, 2490496, 196610, null, 989938035, null, null, null, null, null, null, null, null, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 619 child 37 (script 1): [40566843, 0, 393216, 2490496, 196610, null, 989940833, null, null, null, null, null, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 619 child 38 (script 1): [40566843, 0, 393216, 2490496, 196610, null, 989938789, null, null, null, null, null, null, null, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 619 child 39 (script 1): [40566843, 0, 393216, 2490496, 196610, null, 989938284, null, null, null, null, null, null, null, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 619 child 40 (script 1): [40566843, 0, 393216, 2490496, 196610, null, 989941345, null, null, null, null, null, null, null, null, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 619 child 41 (script 1): [40566843, 0, 393216, 2490496, 196610, null, 989942639, null, null, null, null, null, null, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 620 child 7 (script 1): [832, null, 44] +Interface 620 child 7 (script 3): [196608, 54460416, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 624 child 7 (script 1): [832, null, 44] +Interface 624 child 7 (script 3): [196608, 54460416, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 624 child 21 (script 3): [0, 40894499, null, 69, 1, 40894499, 65536, 36372480, 16777216, null, null, 0, 256, 71696384, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 624 child 22 (script 3): [0, 40894499, null, 69, 1, 40894499, 0, 16777216, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 624 child 23 (script 3): [0, 40894501, null, 69, 1, 40894501, 0, 16777216, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 624 child 24 (script 3): [0, 40894501, null, 69, 1, 40894501, 0, 16777216, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 624 child 25 (script 3): [0, 40894503, null, 69, 1, 40894503, 0, 16777216, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 624 child 26 (script 3): [0, 40894503, null, 69, 1, 40894503, 0, 16777216, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 625 child 39 (script default): [557] +Interface 625 child 39 (script 13): [280320] +Interface 625 child 70 (script 7): [556, 1] +Interface 625 child 73 (script 7): [556, 2] +Interface 625 child 76 (script 7): [556, 3] +Interface 625 child 79 (script 7): [556, 4] +Interface 625 child 82 (script 7): [556, 5] +Interface 625 child 85 (script 7): [556, 6] +Interface 625 child 87 (script 2): [null] +Interface 625 child 88 (script 1): [832, null, 44] +Interface 625 child 88 (script 3): [196608, 54460416, 1, 29, 16777216, 486539264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 626 child 7 (script 1): [832, null, 44] +Interface 626 child 7 (script 3): [196608, 54460416, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 626 child 48 (script 4): [206] +Interface 626 child 48 (script 17): [34304] +Interface 626 child 49 (script 4): [206] +Interface 626 child 49 (script 17): [34304] +Interface 626 child 50 (script 3): [-2147483645, 41025584, 792, 789, 790, 791, 773, 788, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 626 child 51 (script 3): [-2147483645, 41025585, 792, 789, 790, 791, 773, 788, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 626 child 52 (script default): [197120, 24064, null, 197120, 23552, null, 196608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 626 child 53 (script 1): [null, 45, -2147483645] +Interface 626 child 53 (script 5): [50331648, 755007488, 50331648, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 626 child 54 (script default): [197120, 24064, null, 197120, 23552, null, 196608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 627 child 12 (script 1): [832, null, 44, 41091084, 831, 0, 16777216, 486539264, 0, 0, 0, 0] +Interface 627 child 18 (script 1): [41091090, 26, 0, null, 163, 41091090, 0, 16777220, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 629 child 13 (script 1): [832, null, 44] +Interface 629 child 13 (script 3): [196608, 54460416, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 629 child 14 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 629 child 15 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 629 child 16 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 629 child 17 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 629 child 18 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 629 child 19 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 629 child 20 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 629 child 21 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 629 child 22 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 629 child 23 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 629 child 24 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 629 child 25 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 629 child 26 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 629 child 27 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 629 child 28 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 629 child 29 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 629 child 30 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 629 child 31 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 629 child 32 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 629 child 33 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 629 child 34 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 629 child 35 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 629 child 36 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 629 child 37 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 629 child 38 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 629 child 39 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 629 child 66 (script 3): [-2147483645, null, 94, -2147483645, null, 92, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 629 child 67 (script 2): [-2147483645, 16777215, null, 45, -2147483645, 39168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 629 child 68 (script 2): [-2147483645, 16777215, null, 45, -2147483645, 39168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 629 child 69 (script 2): [-2147483645, 16777215, null, 45, -2147483645, 39168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 629 child 70 (script 2): [-2147483645, 16777215, null, 45, -2147483645, 39168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 629 child 71 (script 2): [-2147483645, 16777215, null, 45, -2147483645, 39168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 629 child 72 (script default): [196608, null, 196608, 2949248, 196608, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 630 child 2 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 23 (script 1): [832, null, 44] +Interface 631 child 23 (script 3): [196608, 54460416, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 29 (script 3): [41353244, Neither player is allowed to use ranged attacks., null, 68, 41353244, , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 30 (script default): [469847653, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851319, 469827584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 31 (script 3): [41353244, Neither player is allowed to use melee attacks., null, 68, 41353244, , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 32 (script default): [469847653, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851319, 469827584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 33 (script 3): [41353244, Neither player is allowed to use Magic attacks., null, 68, 41353244, , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 34 (script default): [469847653, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851319, 469827584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 35 (script 3): [41353244, Both players will use a 'fun weapon', such as: rubber chicken., null, 68, 41353244, , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 36 (script default): [469844591, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851319, 469827584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 37 (script 3): [41353244, Neither player is allowed to forfeit the duel., null, 68, 41353244, , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 38 (script default): [469847653, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851319, 469827584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 39 (script 3): [41353244, Neither player will be allowed to use drinks, such as: Strength potion., null, 68, 41353244, , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 40 (script default): [469847653, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851319, 469827584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 41 (script 3): [41353244, Neither player will be allowed to use food., null, 68, 41353244, , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 42 (script default): [469847653, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851319, 469827584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 43 (script 3): [41353244, Neither player will be allowed to use prayers., null, 68, 41353244, , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 44 (script default): [469847653, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851319, 469827584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 45 (script 3): [41353244, Players stand next to each other and aren't allowed to move or use holding spells., null, 68, 41353244, , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 46 (script default): [469848172, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851319, 469827584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 47 (script 3): [41353244, The duel will be in an arena with obstacles., null, 68, 41353244, , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 48 (script default): [469849192, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851319, 469827584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 50 (script 3): [41353244, Neither player will be allowed to use special attacks., null, 68, 41353244, , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 51 (script default): [469847653, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851319, 469827584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 52 (script 3): [41353244, Players can summon animals during the duel., null, 68, 41353244, , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 53 (script default): [469848172, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851319, 469827584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 56 (script 3): [567] +Interface 631 child 56 (script 16): [73216] +Interface 631 child 57 (script default): [469847653, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851319, 469827584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 58 (script default): [469847653, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851319, 469827584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 59 (script default): [469847653, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851319, 469827584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 60 (script default): [469847653, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851319, 469827584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 61 (script default): [469847653, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851319, 469827584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 62 (script default): [469847653, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851319, 469827584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 63 (script default): [469847653, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851319, 469827584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 64 (script default): [469847653, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851319, 469827584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 65 (script default): [469847653, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851319, 469827584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 66 (script default): [469847653, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851319, 469827584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 67 (script default): [469847653, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851319, 469827584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 79 (script default): [null, 469847653] +Interface 631 child 79 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851319, 469827584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 80 (script default): [null, 469847653] +Interface 631 child 80 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851319, 469827584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 81 (script default): [null, 469847653] +Interface 631 child 81 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851319, 469827584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 82 (script default): [null, 469847653] +Interface 631 child 82 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851319, 469827584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 83 (script default): [null, 469847653] +Interface 631 child 83 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851319, 469827584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 84 (script default): [null, 469847653] +Interface 631 child 84 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851319, 469827584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 85 (script default): [null, 469847653] +Interface 631 child 85 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851319, 469827584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 86 (script default): [null, 469847653] +Interface 631 child 86 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851319, 469827584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 87 (script default): [null, 469847653] +Interface 631 child 87 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851319, 469827584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 88 (script default): [null, 469847653] +Interface 631 child 88 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851319, 469827584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 89 (script default): [null, 469847653] +Interface 631 child 89 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851319, 469827584, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 90 (script 3): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 100 (script 3): [-2147483645, null, 94, -2147483645, null, 92, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 101 (script 3): [-2147483645, 43776, null, 45, -2147483645, 52224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 631 child 103 (script 2): [null, 0] +Interface 631 child 103 (script 3): [99] +Interface 631 child 103 (script 16): [34304] +Interface 631 child 108 (script 3): [-2147483645, null, 94, -2147483645, null, 92, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 632 child 66 (script 3): [-2147483645, 41418767, 792, 789, 790, 791, 773, 788, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 633 child 17 (script 3): [-2147483645, 43776, null, 45, -2147483645, 32768, 0, 16777216, 486539264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 633 child 30 (script 1): [832, null, 44] +Interface 633 child 30 (script 3): [196608, 54460416, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 634 child 17 (script 3): [-2147483645, 43776, null, 45, -2147483645, 32768, 0, 16777216, 486539264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 634 child 31 (script 1): [832, null, 44] +Interface 634 child 31 (script 3): [196608, 54460416, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 635 child 14 (script 1): [41615384, 0, 393216, 2490496, 196610, null, 402739311, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 635 child 15 (script 1): [41615384, 0, 393216, 2490496, 196610, null, 402736751, null, null, null, null, null, null, null, null, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 635 child 16 (script 1): [41615384, 0, 393216, 2490496, 196610, null, 402739314, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 635 child 17 (script 1): [41615384, 0, 393216, 2490496, 196610, null, 402740080, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 635 child 18 (script 1): [41615384, 0, 393216, 2490496, 196610, null, 402740085, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 635 child 19 (script 1): [41615384, 0, 393216, 2490496, 196610, null, 402737253, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 635 child 20 (script 1): [41615384, 0, 393216, 2490496, 196610, null, 402741093, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 635 child 21 (script 1): [41615384, 0, 393216, 2490496, 196610, null, 402739809, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 635 child 22 (script 1): [41615384, 0, 393216, 2490496, 196610, null, 402738533, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 635 child 23 (script 1): [41615384, 0, 393216, 2490496, 196610, null, 402738529, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 635 child 24 (script 2): [null, 1] +Interface 635 child 24 (script 6): [null, 0] +Interface 635 child 24 (script 14): [73216] +Interface 635 child 31 (script 3): [564, -2147483645] +Interface 635 child 31 (script 16): [282880] +Interface 636 child 12 (script 1): [832, null, 44] +Interface 636 child 12 (script 3): [196608, 54460416, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 636 child 13 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 636 child 14 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 636 child 15 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 636 child 16 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 636 child 17 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 636 child 18 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 636 child 19 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 636 child 20 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 636 child 21 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 636 child 22 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 636 child 23 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 636 child 24 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 636 child 25 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 636 child 26 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 636 child 27 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 636 child 28 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 636 child 29 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 636 child 30 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 636 child 31 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 636 child 32 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 636 child 33 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 636 child 34 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 636 child 35 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 636 child 36 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 636 child 37 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 636 child 38 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 636 child 39 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 636 child 40 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 14 (script 1): [832, null, 44] +Interface 637 child 14 (script 3): [196608, 54460416, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 19 (script 3): [41746477, Neither player is allowed to use Ranged attacks., null, 68, 41746477, , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 20 (script default): [755060325, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851325, 755040256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 21 (script 3): [41746477, Neither player is allowed to use melee attacks., null, 68, 41746477, , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 22 (script default): [755060325, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851325, 755040256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 23 (script 3): [41746477, Neither player is allowed to use Magic attacks., null, 68, 41746477, , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 24 (script default): [755060325, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851325, 755040256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 25 (script 3): [41746477, Both players will use a 'fun weapon', such as: rubber chicken., null, 68, 41746477, , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 26 (script default): [755057263, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851325, 755040256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 27 (script 3): [41746477, Neither player is allowed to forfeit the duel., null, 68, 41746477, , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 28 (script default): [755060325, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851325, 755040256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 29 (script 3): [41746477, Neither player will be allowed to use drinks, such as: strength potion., null, 68, 41746477, , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 30 (script default): [755060325, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851325, 755040256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 31 (script 3): [41746477, Neither player will be allowed to use food., null, 68, 41746477, , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 32 (script default): [755060325, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851325, 755040256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 33 (script 3): [41746477, Neither player will be allowed to use prayer., null, 68, 41746477, , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 34 (script default): [755060325, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851325, 755040256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 35 (script 3): [41746477, Players stand next to each other and aren't allowed to move or use holding spells., null, 68, 41746477, , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 36 (script default): [755060844, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851325, 755040256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 37 (script 3): [41746477, The duel will be in an arena with obstacles., null, 68, 41746477, , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 38 (script default): [755061864, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851325, 755040256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 39 (script 3): [41746477, Players can summon animals during the duel., null, 68, 41746477, , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 40 (script default): [755060844, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851325, 755040256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 41 (script 3): [41746477, Neither player will be allowed to use special attacks., null, 68, 41746477, , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 42 (script default): [755060325, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851325, 755040256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 44 (script 2): [null, 1, 566] +Interface 637 child 44 (script 15): [73216] +Interface 637 child 46 (script default): [755060325, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851325, 755040256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 47 (script default): [755060325, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851325, 755040256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 48 (script default): [755060325, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851325, 755040256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 49 (script default): [755060325, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851325, 755040256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 50 (script default): [755060325, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851325, 755040256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 51 (script default): [755060325, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851325, 755040256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 52 (script default): [755060325, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851325, 755040256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 53 (script default): [755060325, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851325, 755040256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 54 (script default): [755060325, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851325, 755040256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 55 (script default): [755060325, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851325, 755040256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 56 (script default): [755060325, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851325, 755040256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 68 (script default): [null, 755060325] +Interface 637 child 68 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851325, 755040256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 69 (script default): [null, 755060325] +Interface 637 child 69 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851325, 755040256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 70 (script default): [null, 755060325] +Interface 637 child 70 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851325, 755040256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 71 (script default): [null, 755060325] +Interface 637 child 71 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851325, 755040256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 72 (script default): [null, 755060325] +Interface 637 child 72 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851325, 755040256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 73 (script default): [null, 755060325] +Interface 637 child 73 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851325, 755040256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 74 (script default): [null, 755060325] +Interface 637 child 74 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851325, 755040256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 75 (script default): [null, 755060325] +Interface 637 child 75 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851325, 755040256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 76 (script default): [null, 755060325] +Interface 637 child 76 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851325, 755040256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 77 (script default): [null, 755060325] +Interface 637 child 77 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851325, 755040256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 78 (script default): [null, 755060325] +Interface 637 child 78 (script 1): [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 50331648, 1140851325, 755040256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 79 (script 2): [null, 0] +Interface 637 child 81 (script 3): [-2147483645, null, 94, -2147483645, null, 92, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 82 (script 3): [-2147483645, 43776, null, 45, -2147483645, 52224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 84 (script 3): [-2147483645, null, 94, -2147483645, null, 92, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 637 child 85 (script 3): [-2147483645, 11206656, null, 45, -2147483645, 13369344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 639 child 10 (script 1): [832, null, 44] +Interface 639 child 10 (script 3): [196608, 54460416, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 639 child 34 (script 3): [-2147483645, null, 94, -2147483645, null, 92, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 639 child 35 (script 3): [-2147483645, null, 45, -2147483645, 43776, null, 45, -2147483645, 52224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 639 child 36 (script 3): [-2147483645, null, 94, -2147483645, null, 92, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 640 child 18 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 16750623, 65536, 36765696, 0, 0, , 18546688, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 640 child 19 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 16750623, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 640 child 20 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 16750623, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 640 child 23 (script 3): [-2147483645, null, 94, -2147483645, null, 92, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 641 child 16 (script 1): [42008615, 0, 393216, 2490496, 196610, null, 654397551, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 641 child 17 (script 1): [42008615, 0, 393216, 2490496, 196610, null, 654394991, null, null, null, null, null, null, null, null, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 641 child 18 (script 1): [42008615, 0, 393216, 2490496, 196610, null, 654397554, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 641 child 19 (script 1): [42008615, 0, 393216, 2490496, 196610, null, 654398320, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 641 child 20 (script 1): [42008615, 0, 393216, 2490496, 196610, null, 654398325, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 641 child 21 (script 1): [42008615, 0, 393216, 2490496, 196610, null, 654395493, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 641 child 22 (script 1): [42008615, 0, 393216, 2490496, 196610, null, 654399333, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 641 child 23 (script 1): [42008615, 0, 393216, 2490496, 196610, null, 654398049, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 641 child 24 (script 1): [42008615, 0, 393216, 2490496, 196610, null, 654396773, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 641 child 25 (script 1): [42008615, 0, 393216, 2490496, 196610, null, 654396769, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, null, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 641 child 37 (script 3): [564, -2147483645] +Interface 641 child 37 (script 16): [282880] +Interface 643 child 7 (script 1): [832, null, 44] +Interface 643 child 7 (script 3): [196608, 54460416, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 645 child 7 (script 1): [832, null, 44] +Interface 645 child 7 (script 3): [196608, 54460416, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 645 child 18 (script 3): [-2147483645, 42270736, 792, 789, 790, 791, 773, 788, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 646 child 12 (script default): [1175, null, 44] +Interface 646 child 12 (script 2): [196608, 76939264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 647 child 7 (script 1): [832, null, 44] +Interface 647 child 7 (script 3): [196608, 54460416, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 647 child 21 (script 2): [null, 0] +Interface 647 child 24 (script 3): [677] +Interface 647 child 24 (script 16): [290560] +Interface 647 child 25 (script 3): [-2147483645, null, 97, -2147483645, null, 93, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 649 child 5 (script 1): [45, -2147483645, 16776960] +Interface 649 child 5 (script 2): [45, -2147483645, 16777215] +Interface 649 child 11 (script 1): [45, -2147483645, 16777215] +Interface 649 child 11 (script 2): [45, -2147483645, 16750623] +Interface 649 child 12 (script 1): [45, -2147483645, 16777215] +Interface 649 child 12 (script 2): [45, -2147483645, 16750623] +Interface 649 child 13 (script 1): [45, -2147483645, 16777215] +Interface 649 child 13 (script 2): [45, -2147483645, 16750623] +Interface 649 child 14 (script 1): [45, -2147483645, 16777215] +Interface 649 child 14 (script 2): [45, -2147483645, 16750623] +Interface 652 child 31 (script 2): [null, -2147483645] +Interface 652 child 31 (script 4): [null, 536871564] +Interface 652 child 31 (script 6): [42729507, 42729501, 42729502, 7, 681, -2147483645, 42729504, 42729506, 42729507, 42729501, 42729502, 0, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 652 child 35 (script 3): [42729507, 14784543, null, 45, 42729507, 12547357, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 657 child 13 (script 1): [832, null, 44] +Interface 657 child 13 (script 3): [196608, 54460416, 0, 16777216, 486539264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 657 child 18 (script 1): [834, null, 44] +Interface 657 child 18 (script 3): [196608, 54591488, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 657 child 19 (script 1): [834, null, 44] +Interface 657 child 19 (script 3): [196608, 54591488, 0, 16777216, 486539264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 657 child 27 (script 1): [43057179, 21, 0, null, 163, 43057179, 0, 16777220, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 659 child 1 (script 1): [542, null, 44] +Interface 659 child 1 (script 3): [196608, 35454976, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 660 child 97 (script 2): [null, 0] +Interface 660 child 107 (script 3): [null, 0] +Interface 660 child 108 (script 2): [null, 0] +Interface 660 child 109 (script default): [712] +Interface 660 child 110 (script 3): [null, 0] +Interface 660 child 111 (script default): [716] +Interface 660 child 112 (script 3): [null, 0] +Interface 660 child 113 (script 3): [null, 0] +Interface 660 child 114 (script 3): [null, 0] +Interface 660 child 115 (script 2): [null, 0] +Interface 660 child 116 (script default): [711] +Interface 660 child 117 (script 3): [null, 0] +Interface 660 child 118 (script default): [715] +Interface 660 child 119 (script 3): [null, 0] +Interface 660 child 120 (script 3): [null, 0] +Interface 660 child 123 (script 2): [null, 0] +Interface 660 child 124 (script 3): [null, 0] +Interface 660 child 125 (script 2): [null, 0] +Interface 660 child 126 (script 2): [null, 0] +Interface 660 child 127 (script 2): [null, 0] +Interface 660 child 128 (script 2): [null, 0] +Interface 660 child 129 (script 3): [null, 0] +Interface 660 child 130 (script 2): [null, 0] +Interface 660 child 131 (script 2): [null, 0] +Interface 660 child 132 (script 2): [null, 0] +Interface 660 child 137 (script 2): [null, 0] +Interface 660 child 138 (script default): [732] +Interface 663 child 3 (script 2): [null, 0, 0] +Interface 663 child 3 (script 5): [300544] +Interface 663 child 16 (script 1): [43450394, 0, 393216, 2490496, 196610, null, 436293733, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, null, 300, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 663 child 17 (script default): [40, 43450394] +Interface 663 child 17 (script 3): [820] +Interface 663 child 17 (script 8): [38, -2147483645, 43450394, Pet Size Percentage, 25, 300] +Interface 663 child 17 (script 16): [300800] +Interface 663 child 18 (script 1): [43450394, 0, 393216, 2490496, 196610, null, 436293733, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, 0, null, 300, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 663 child 19 (script default): [40, 43450394] +Interface 663 child 19 (script 8): [38, -2147483645, 43450394, Pet Hunger Percentage, 25, 300] +Interface 663 child 20 (script 3): [-2147483645, null, 94, -2147483645, null, 92, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 663 child 21 (script 1): [0, 393216, 2490496, 196610, null, 436290401, null, null, null, null, null, null, null, null, null, 0, null, 300, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 663 child 22 (script 3): [-2147483645, null, 94, -2147483645, null, 92, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 663 child 23 (script default): [0, 393216, 2490496, 196610, null, 436290665, null, null, null, null, null, null, null, null, null, null, null, null, 0, null, 300, 0, 0, 0, 0, 0] +Interface 664 child 1 (script default): [745] +Interface 664 child 3 (script 1): [746] +Interface 664 child 5 (script 1): [747] +Interface 664 child 9 (script 2): [748, 43515913, 43515916] +Interface 664 child 27 (script 3): [749] +Interface 664 child 27 (script 6): [743] +Interface 664 child 27 (script 16): [11008, 11272192] +Interface 666 child 7 (script 1): [832, null, 44, 43646983, 831, 0, 16777216] +Interface 666 child 7 (script 3): [16777216, 486539264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 666 child 16 (script 3): [-2147483645, 43646991, 792, 789, 790, 791, 773, 788, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 666 child 17 (script default): [369098752, 6, 779, -2147483645, 43646998, 43646998, 1, Swap between creating animal pouches and scrolls, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 667 child 3 (script 1): [536, null, 44] +Interface 667 child 3 (script 3): [196608, 35061760, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 667 child 20 (script 4): [787] +Interface 667 child 20 (script 17): [24064] +Interface 668 child 3 (script 2): [43778058, 0, 393216, 2490496, 196610, null, 167854709, null, null, null, null, null, 0, null, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 668 child 4 (script 2): [43778058, 0, 393216, 2490496, 196610, null, 167855201, null, null, null, null, null, null, null, 0, null, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 668 child 5 (script 2): [43778058, 0, 393216, 2490496, 196610, null, 167855986, null, null, null, null, null, null, null, 0, null, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 668 child 6 (script 2): [43778058, 0, 393216, 2490496, 196610, null, 167859301, null, null, null, null, null, 0, null, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 668 child 7 (script 2): [43778058, 0, 393216, 2490496, 196610, null, 167859048, null, null, null, null, null, null, 0, null, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 668 child 8 (script 2): [43778058, 0, 393216, 2490496, 196610, null, 167857249, null, null, null, null, null, null, 0, null, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 669 child 7 (script 1): [832, null, 44, 43843591, 831, 0, 16777216] +Interface 669 child 7 (script 3): [16777216, 486539264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 669 child 17 (script 3): [-2147483645, 43843599, 792, 789, 790, 791, 773, 788, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 669 child 18 (script default): [385875968, 6, 779, -2147483645, 43843607, 43843607, 1, Swap between creating pouches and scrolls, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 671 child 13 (script 1): [832, null, 44] +Interface 671 child 13 (script 3): [196608, 54460416, 1, 29, 16777216, 486539264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 671 child 29 (script 1): [0, 393216, 2490496, 196610, null, 503403617, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null] +Interface 671 child 29 (script 2): [0, null, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 672 child 7 (script 1): [832, null, 44, 44040199, 831, 0, 16777216] +Interface 672 child 7 (script 3): [16777216, 486539264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 672 child 17 (script 3): [-2147483645, 44040207, 792, 789, 790, 791, 773, 788, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 672 child 18 (script default): [385875968, 6, 779, -2147483645, 44040215, 44040215, 1, Swap between creating animal pouches and scrolls, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 673 child 7 (script 1): [832, null, 44, 44105735, 831, 0, 16777216] +Interface 673 child 7 (script 3): [16777216, 486539264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 673 child 16 (script 3): [-2147483645, 44105743, 792, 789, 790, 791, 773, 788, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 673 child 17 (script default): [369098752, 6, 779, -2147483645, 44105750, 44105750, 1, Swap between creating pouches and scrolls, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 676 child 12 (script 1): [832, null, 44, 44302348, 831, 0, 16777216, 486539264, 0, 0, 0, 0] +Interface 676 child 17 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 676 child 18 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 676 child 20 (script 1): [44302356, 27, 0, null, 163, 44302356, 0, 16777220, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 677 child 12 (script 1): [832, null, 44, 44367884, 831, 0, 16777216, 486539264, 0, 0, 0, 0] +Interface 677 child 17 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 677 child 18 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 677 child 20 (script 1): [44367892, 28, 0, null, 163, 44367892, 0, 16777220, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 678 child 12 (script 1): [832, null, 44, 44433420, 831, 0, 16777216, 486539264, 0, 0, 0, 0] +Interface 678 child 17 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 678 child 18 (script 3): [-2147483645, 65280, null, 167, -2147483645, 16711680, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 678 child 20 (script 1): [44433428, 29, 0, null, 163, 44433428, 0, 16777220, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 681 child 115 (script 7): [29] +Interface 681 child 120 (script 3): [-2147483645, null, 97, -2147483645, null, 93, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 681 child 121 (script default): [40, 44630145] +Interface 681 child 121 (script 7): [840] +Interface 681 child 121 (script 8): [38, -2147483645, 44630145, View right side of the catapult., 50, 180] +Interface 681 child 124 (script 3): [-2147483645, null, 97, -2147483645, null, 93, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 681 child 125 (script default): [40, 44630145] +Interface 681 child 125 (script 7): [840] +Interface 681 child 125 (script 8): [38, -2147483645, 44630145, View left side of the catapult., 50, 180] +Interface 681 child 126 (script 1): [832, null, 44] +Interface 681 child 126 (script 3): [196608, 54460416, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 682 child 3 (script 3): [-2147483645, 14936, null, 67, -2147483645, 14938, 0, 16777216, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 682 child 4 (script default): [40, 44695590] +Interface 682 child 4 (script 8): [38, -2147483645, 44695590, Fire the catapult., 25, 180] +Interface 682 child 9 (script default): [196608, 2107638528, 17152, null, 196608, 2109997056, 1, 858, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 682 child 10 (script default): [40, 44695590] +Interface 682 child 10 (script 8): [38, -2147483645, 44695590, Aim the catapult left., 25, 180] +Interface 682 child 11 (script 1): [-2147483645, 32160, null, 67, -2147483645, 32196, 0, 16777216, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 682 child 12 (script default): [40, 44695590] +Interface 682 child 12 (script 8): [38, -2147483645, 44695590, Aim the catapult right., 25, 180] +Interface 682 child 13 (script default): [40, 44695590] +Interface 682 child 13 (script 8): [38, -2147483645, 44695590, Increase counterweight., 25, 180] +Interface 682 child 14 (script default): [40, 44695590] +Interface 682 child 14 (script 8): [38, -2147483645, 44695590, Decrease counterweight., 25, 180] +Interface 682 child 24 (script 1): [null, null, 44, -2147483645] +Interface 682 child 24 (script 5): [null, 0, 0, 0] +Interface 682 child 25 (script 1): [null, null, 44, -2147483645] +Interface 682 child 25 (script 5): [null, 0, 0, 0] +Interface 683 child 34 (script 1): [null, null, 44, -2147483645] +Interface 683 child 34 (script 5): [null, 0, 16777216, null] +Interface 683 child 34 (script 6): [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 683 child 35 (script default): [1231, null, 44] +Interface 683 child 35 (script 2): [196608, 80609280, 1, 848, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 683 child 36 (script 1): [1225, null, 44, 44761124, 1224, 0, 16777216, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 683 child 37 (script 1): [null, null, 44, -2147483645] +Interface 683 child 37 (script 5): [null, 0, 0, 0] +Interface 683 child 38 (script 2): [-2147483645, 32160, null, 67, -2147483645, 32196, 0, 16777216, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 683 child 39 (script 1): [-2147483645, 32160, null, 67, -2147483645, 32196, 0, 16777216, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 683 child 40 (script default): [196608, 2107638528, 17152, null, 196608, 2109997056, 1, 844, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 683 child 41 (script default): [196608, 2107638528, 17152, null, 196608, 2109997056, 1, 843, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 683 child 44 (script 3): [-2147483645, null, 97, -2147483645, null, 93, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 683 child 45 (script 3): [-2147483645, null, 97, -2147483645, null, 93, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 683 child 50 (script default): [40, 44761137] +Interface 683 child 50 (script 8): [38, -2147483645, 44761137, Move piece right., 50, 180] +Interface 683 child 52 (script default): [40, 44761137] +Interface 683 child 52 (script 8): [38, -2147483645, 44761137, Move piece up., 50, 180] +Interface 683 child 53 (script default): [40, 44761137] +Interface 683 child 53 (script 8): [38, -2147483645, 44761137, Move piece down., 50, 180] +Interface 683 child 54 (script default): [40, 44761137] +Interface 683 child 54 (script 8): [38, -2147483645, 44761137, Move piece left., 50, 180] +Interface 683 child 55 (script default): [40, 44761137] +Interface 683 child 55 (script 8): [38, -2147483645, 44761137, Rotate piece counter-clockwise., 25, 180] +Interface 683 child 56 (script default): [40, 44761137] +Interface 683 child 56 (script 8): [38, -2147483645, 44761137, Rotate piece clockwise., 25, 180] +Interface 683 child 57 (script default): [40, 44761137] +Interface 683 child 57 (script 8): [38, -2147483645, 44761137, View the other side of the catapult., 25, 180] +Interface 685 child 7 (script 1): [832, null, 44] +Interface 685 child 7 (script 3): [196608, 54460416, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 688 child 9 (script 2): [null, 1, 862] +Interface 688 child 9 (script 15): [305920] +Interface 689 child 8 (script 2): [null, 1, 862] +Interface 689 child 8 (script 15): [305920] +Interface 694 child 3 (script 1): [32408, null, 67] +Interface 694 child 3 (script 3): [196863, null, null, null, 0, 512, 224000, null, 196608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 694 child 4 (script 1): [32408, null, 67] +Interface 694 child 4 (script 3): [196863, null, null, null, 0, 512, 224256, null, 196608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 694 child 7 (script 1): [537, null, 44] +Interface 694 child 7 (script 3): [196608, 35258368, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 694 child 38 (script 3): [-2147483645, null, 97, -2147483645, null, 93, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 696 child 3 (script 1): [32408, null, 67] +Interface 696 child 3 (script 3): [196863, null, null, null, 0, 512, 224512, null, 196608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 696 child 4 (script 1): [32408, null, 67] +Interface 696 child 4 (script 3): [196863, null, null, null, 0, 512, 224768, null, 196608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 696 child 7 (script 1): [537, null, 44] +Interface 696 child 7 (script 3): [196608, 35258368, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 696 child 38 (script 3): [-2147483645, null, 97, -2147483645, null, 93, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 697 child 3 (script 1): [32408, null, 67] +Interface 697 child 3 (script 3): [196863, null, null, null, 0, 512, 223232, null, 196608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 697 child 4 (script 1): [32408, null, 67] +Interface 697 child 4 (script 3): [196863, null, null, null, 0, 512, 223488, null, 196608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 697 child 5 (script 1): [32408, null, 67] +Interface 697 child 5 (script 3): [196863, null, null, null, 0, 512, 223744, null, 196608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 697 child 8 (script 1): [537, null, 44] +Interface 697 child 8 (script 3): [196608, 35258368, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 697 child 47 (script 3): [-2147483645, null, 97, -2147483645, null, 93, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 699 child 3 (script 1): [32408, null, 67] +Interface 699 child 3 (script 3): [196863, null, null, null, 0, 512, 225536, null, 196608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 699 child 4 (script 1): [32408, null, 67] +Interface 699 child 4 (script 3): [196863, null, null, null, 0, 512, 225792, null, 196608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 699 child 7 (script 1): [537, null, 44] +Interface 699 child 7 (script 3): [196608, 35258368, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 699 child 38 (script 3): [-2147483645, null, 97, -2147483645, null, 93, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 704 child 5 (script 1): [537, null, 44] +Interface 704 child 5 (script 3): [196608, 35258368, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 704 child 10 (script 1): [32408, null, 67] +Interface 704 child 10 (script 3): [196863, null, null, null, 0, 512, 226560, null, 196608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 704 child 11 (script 1): [32408, null, 67] +Interface 704 child 11 (script 3): [196863, null, null, null, 0, 512, 226816, null, 196608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 704 child 12 (script 1): [32408, null, 67] +Interface 704 child 12 (script 3): [196863, null, null, null, 0, 512, 227072, null, 196608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 704 child 47 (script 3): [-2147483645, null, 97, -2147483645, null, 93, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 705 child 5 (script 1): [537, null, 44] +Interface 705 child 5 (script 3): [196608, 35258368, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 705 child 10 (script 1): [32408, null, 67] +Interface 705 child 10 (script 3): [196863, null, null, null, 0, 512, 227328, null, 196608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 705 child 11 (script 1): [32408, null, 67] +Interface 705 child 11 (script 3): [196863, null, null, null, 0, 512, 227584, null, 196608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 705 child 12 (script 1): [32408, null, 67] +Interface 705 child 12 (script 3): [196863, null, null, null, 0, 512, 227840, null, 196608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 705 child 47 (script 3): [-2147483645, null, 97, -2147483645, null, 93, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 707 child 3 (script 1): [32408, null, 67] +Interface 707 child 3 (script 3): [196863, null, null, null, 0, 512, 225024, null, 196608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 707 child 4 (script 1): [32408, null, 67] +Interface 707 child 4 (script 3): [196863, null, null, null, 0, 512, 225280, null, 196608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 707 child 7 (script 1): [537, null, 44] +Interface 707 child 7 (script 3): [196608, 35258368, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 707 child 39 (script 3): [-2147483645, null, 97, -2147483645, null, 93, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 708 child 3 (script 1): [32408, null, 67] +Interface 708 child 3 (script 3): [196863, null, null, null, 0, 512, 226048, null, 196608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 708 child 4 (script 1): [32408, null, 67] +Interface 708 child 4 (script 3): [196863, null, null, null, 0, 512, 226304, null, 196608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 708 child 7 (script 1): [537, null, 44] +Interface 708 child 7 (script 3): [196608, 35258368, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 708 child 38 (script 3): [-2147483645, null, 97, -2147483645, null, 93, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 709 child 16 (script 1): [832, null, 44] +Interface 709 child 16 (script 3): [196608, 54460416, 0, 16777216, 486539264, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 710 child 5 (script 1): [537, null, 44] +Interface 710 child 5 (script 3): [196608, 35258368, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 710 child 9 (script 1): [32408, null, 67] +Interface 710 child 9 (script 3): [196863, null, null, null, 0, 512, 228096, null, 196608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 710 child 10 (script 1): [32408, null, 67] +Interface 710 child 10 (script 3): [196863, null, null, null, 0, 512, 228352, null, 196608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 710 child 38 (script 3): [-2147483645, null, 97, -2147483645, null, 93, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 712 child 4 (script 1): [538, null, 44] +Interface 712 child 4 (script 3): [196608, 35192832, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 716 child 17 (script 3): [-2147483645, null, 94, -2147483645, null, 92, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 716 child 32 (script default): [908] +Interface 716 child 32 (script 1): [909] +Interface 716 child 32 (script 2): [907] +Interface 716 child 32 (script 3): [906] +Interface 716 child 32 (script 7): [910] +Interface 716 child 35 (script default): [40, 46923813] +Interface 716 child 35 (script 8): [38, -2147483645, 46923813, Target the chocatrice on a creature., 25, 180] +Interface 716 child 36 (script default): [40, 46923813] +Interface 716 child 36 (script 8): [38, -2147483645, 46923813, Calls the chocatrice to you if you get separated., 25, 180] +Interface 717 child 1 (script 2): [null, 0, 0] +Interface 717 child 3 (script 3): [893] +Interface 717 child 4 (script 3): [893] +Interface 717 child 7 (script 3): [895] +Interface 717 child 7 (script 16): [308480] +Interface 717 child 8 (script 3): [894] +Interface 717 child 8 (script 16): [308480] +Interface 717 child 13 (script default): [null, , 230400] +Interface 717 child 13 (script 8): [903] +Interface 717 child 13 (script 10): [904] +Interface 717 child 14 (script default): [null, , 229888] +Interface 717 child 14 (script 8): [901] +Interface 717 child 14 (script 10): [902] +Interface 717 child 16 (script default): [40, 46989342] +Interface 717 child 16 (script 8): [38, -2147483645, 46989342, Add water to cool the incubator., 50, 180] +Interface 717 child 18 (script default): [40, 46989342] +Interface 717 child 18 (script 8): [38, -2147483645, 46989342, Add coal to heat the incubator., 50, 180] +Interface 717 child 26 (script 1): [832, null, 44] +Interface 717 child 26 (script 3): [196608, 54460416, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 717 child 27 (script default): [40, 46989342] +Interface 717 child 27 (script 8): [38, -2147483645, 46989342, Add water to cool the incubator., 25, 180] +Interface 717 child 28 (script default): [40, 46989342] +Interface 717 child 28 (script 8): [38, -2147483645, 46989342, Add coal to heat the incubator., 25, 180] +Interface 718 child 1 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 718 child 2 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 719 child 2 (script 1): [542, null, 44] +Interface 719 child 2 (script 3): [196608, 35454976, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 719 child 5 (script 3): [47120388, 47120389, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 720 child 1 (script 1): [832, null, 44] +Interface 720 child 1 (script 3): [196608, 54460416, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 723 child 6 (script 2): [null, -2147483645, 47382535] +Interface 723 child 6 (script 4): [null, 167772883] +Interface 723 child 6 (script 6): [47382537, 0, 0, 0, 0, 0, 0, 0] +Interface 724 child 17 (script 7): [29] +Interface 724 child 22 (script 3): [-2147483645, 16711680, null, 45, -2147483645, 8388608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 724 child 27 (script 2): [null, 1, 930] +Interface 724 child 27 (script 15): [308992] +Interface 725 child 17 (script 7): [29] +Interface 725 child 19 (script 3): [926] +Interface 725 child 19 (script 16): [308992] +Interface 725 child 23 (script 3): [-2147483645, 16711680, null, 45, -2147483645, 8388608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 726 child 17 (script 7): [29] +Interface 726 child 116 (script 2): [null, 1, 948] +Interface 726 child 116 (script 15): [308992] +Interface 726 child 118 (script 3): [-2147483645, 16711680, null, 45, -2147483645, 8388608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 727 child 17 (script 7): [29] +Interface 727 child 24 (script 3): [-2147483645, 16711680, null, 45, -2147483645, 8388608, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 728 child 1 (script default): [null, -2147483645, 47710235] +Interface 728 child 1 (script 2): [null, 335545048] +Interface 728 child 1 (script 4): [47710230, 47710231, 0, 524288, 60162176, 196610, null, 452984832, 728, 335545048, 352322264, 369099480, 385875968, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 728 child 4 (script 3): [776, -2147483645] +Interface 728 child 4 (script 16): [308992] +Interface 728 child 5 (script 3): [776, -2147483645] +Interface 728 child 5 (script 16): [308992] +Interface 728 child 6 (script 3): [776, -2147483645] +Interface 728 child 6 (script 16): [308992] +Interface 728 child 7 (script 3): [776, -2147483645] +Interface 728 child 7 (script 16): [308992] +Interface 728 child 8 (script 3): [776, -2147483645] +Interface 728 child 8 (script 16): [308992] +Interface 728 child 9 (script 3): [776, -2147483645] +Interface 728 child 9 (script 16): [308992] +Interface 728 child 10 (script 3): [776, -2147483645] +Interface 728 child 10 (script 16): [308992] +Interface 728 child 11 (script 3): [776, -2147483645] +Interface 728 child 11 (script 16): [308992] +Interface 728 child 12 (script 3): [776, -2147483645] +Interface 728 child 12 (script 16): [308992] +Interface 728 child 13 (script 3): [776, -2147483645] +Interface 728 child 13 (script 16): [308992] +Interface 728 child 14 (script 3): [912, -2147483645] +Interface 728 child 14 (script 16): [308992] +Interface 728 child 17 (script 2): [47710233, 131072, 60489856, 196608, 33554432, null, null, -2147483645, null, 917, -2147483645, 47710233, 0, 65536, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 728 child 18 (script 1): [null, null, 299] +Interface 728 child 18 (script 3): [null, 419463168] +Interface 728 child 18 (script 5): [783, 0, 33554432] +Interface 728 child 18 (script 6): [null, -2147483645, null] +Interface 728 child 18 (script 10): [null, -2147483645, 47710233] +Interface 728 child 19 (script 3): [-2147483645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 728 child 20 (script 2): [786, null, 299] +Interface 728 child 20 (script 4): [null, 419463168] +Interface 728 child 20 (script 6): [785, 0, 16777216] +Interface 728 child 20 (script 7): [null, null, 917] +Interface 728 child 20 (script 9): [196610, null, 419430400, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 728 child 21 (script 1): [1173, null, 299] +Interface 728 child 21 (script 3): [null, 419463168] +Interface 728 child 21 (script 5): [1172, 0, 16777216] +Interface 728 child 21 (script 6): [null, null, 917] +Interface 728 child 21 (script 8): [196610, null, 419430400, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 728 child 22 (script 1): [1175, null, 299] +Interface 728 child 22 (script 3): [null, 419463168] +Interface 728 child 22 (script 5): [1174, 0, 16777216] +Interface 728 child 22 (script 6): [null, null, 917] +Interface 728 child 22 (script 8): [196610, null, 419430400, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 728 child 23 (script 1): [801, null, 299] +Interface 728 child 23 (script 3): [null, 419463168] +Interface 728 child 23 (script 5): [787, 0, 16777216] +Interface 728 child 23 (script 6): [null, null, 917] +Interface 728 child 23 (script 8): [196610, null, 419430400, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 730 child 19 (script 1): [955] +Interface 730 child 19 (script 14): [23808] +Interface 730 child 25 (script 3): [954] +Interface 730 child 25 (script 16): [311040] +Interface 734 child 0 (script 3): [964] +Interface 734 child 0 (script 6): [965, 48103425, 48103426, 48103427, 48103428, 48103429, 48103430, 48103431, 48103432, 48103433, 48103434, 48103435, 48103436, 48103437, 48103438, 48103439, 48103445, 48103446] +Interface 734 child 0 (script 16): [208896] +Interface 734 child 19 (script 1): [540, null, 44] +Interface 734 child 19 (script 3): [196608, 35323904, 1, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 734 child 21 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 4202496, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 734 child 22 (script 3): [-2147483645, 16777215, null, 45, -2147483645, 4202496, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +Interface 734 child 23 (script 7): [962, 48103425] +Interface 734 child 24 (script 7): [963, 48103425] +Interface 734 child 25 (script 7): [962, 48103430] +Interface 734 child 26 (script 7): [963, 48103430] +Interface 734 child 27 (script 7): [962, 48103435] +Interface 735 child 12 (script default): [null, 961, -2147483645] +Interface 735 child 12 (script 7): [958, 48168973, 48169039, 48168972] +Interface 735 child 13 (script 2): [null, -2147483645, 48169039] +Interface 735 child 13 (script 4): [null, 201326592] +Interface 735 child 13 (script 6): [957, -2147483645, 48169039, 48168972] +Interface 735 child 13 (script 19): [208896] diff --git a/dumps/498/498_item_dump.txt b/dumps/498/498_item_dump.txt new file mode 100644 index 0000000..efff5ef --- /dev/null +++ b/dumps/498/498_item_dump.txt @@ -0,0 +1,13248 @@ + +item=Dwarf remains, id=0, option=[null, null, null, null, Destroy] +item=Toolkit, id=1, option=[null, null, null, null, Destroy] +item=Cannonball, id=2, option=[null, null, null, null, drop] +item=Nulodion's notes, id=3, option=[Read, null, null, null, Destroy] +item=Ammo mould, id=4, option=[null, null, null, null, drop] +item=Instruction manual, id=5, option=[Read, null, null, null, drop] +item=Cannon base, id=6, option=[Set-up, null, null, null, drop] +item=Cannon base, id=7, option=[null, null, null, null, drop] +item=Cannon stand, id=8, option=[null, null, null, null, drop] +item=Cannon stand, id=9, option=[null, null, null, null, drop] +item=Cannon barrels, id=10, option=[null, null, null, null, drop] +item=Cannon barrels, id=11, option=[null, null, null, null, drop] +item=Cannon furnace, id=12, option=[null, null, null, null, drop] +item=Cannon furnace, id=13, option=[null, null, null, null, drop] +item=Railing, id=14, option=[null, null, null, null, drop] +item=Holy table napkin, id=15, option=[null, null, null, null, drop] +item=Magic whistle, id=16, option=[Blow, null, null, null, drop] +item=Grail bell, id=17, option=[Ring, null, null, null, drop] +item=Magic gold feather, id=18, option=[Blow-on, null, null, null, drop] +item=Holy grail, id=19, option=[null, null, null, null, Destroy] +item=White cog, id=20, option=[null, null, null, null, drop] +item=Black cog, id=21, option=[null, null, null, null, drop] +item=Blue cog, id=22, option=[null, null, null, null, drop] +item=Red cog, id=23, option=[null, null, null, null, drop] +item=Rat poison, id=24, option=[null, null, null, null, drop] +item=Red vine worm, id=25, option=[null, null, null, null, drop] +item=Fishing trophy, id=26, option=[null, null, null, null, drop] +item=Fishing pass, id=27, option=[null, null, null, null, drop] +item=Insect repellent, id=28, option=[null, null, null, null, drop] +item=Whoopsie, id=29, option=[null, null, null, null, drop] +item=Bucket of wax, id=30, option=[null, null, null, null, drop] +item=Whoopsie, id=31, option=[null, null, null, null, drop] +item=Lit black candle, id=32, option=[Extinguish, null, null, null, drop] +item=Lit candle, id=33, option=[Extinguish, null, null, null, drop] +item=Lit candle, id=34, option=[Extinguish, null, null, null, drop] +item=Excalibur, id=35, option=[null, Wield, null, null, drop] +item=Candle, id=36, option=[null, null, null, null, drop] +item=Candle, id=37, option=[null, null, null, null, drop] +item=Black candle, id=38, option=[null, null, null, null, drop] +item=Bronze arrowtips, id=39, option=[null, null, null, null, drop] +item=Iron arrowtips, id=40, option=[null, null, null, null, drop] +item=Steel arrowtips, id=41, option=[null, null, null, null, drop] +item=Mithril arrowtips, id=42, option=[null, null, null, null, drop] +item=Adamant arrowtips, id=43, option=[null, null, null, null, drop] +item=Rune arrowtips, id=44, option=[null, null, null, null, drop] +item=Opal bolt tips, id=45, option=[null, null, null, null, drop] +item=Pearl bolt tips, id=46, option=[null, null, null, null, drop] +item=Barb bolttips, id=47, option=[null, null, null, null, drop] +item=Longbow (u), id=48, option=[null, null, null, null, drop] +item=Longbow (u), id=49, option=[null, null, null, null, drop] +item=Shortbow (u), id=50, option=[null, null, null, null, drop] +item=Shortbow (u), id=51, option=[null, null, null, null, drop] +item=Arrow shaft, id=52, option=[null, null, null, null, drop] +item=Headless arrow, id=53, option=[null, null, null, null, drop] +item=Oak shortbow (u), id=54, option=[null, null, null, null, drop] +item=Oak shortbow (u), id=55, option=[null, null, null, null, drop] +item=Oak longbow (u), id=56, option=[null, null, null, null, drop] +item=Oak longbow (u), id=57, option=[null, null, null, null, drop] +item=Willow longbow (u), id=58, option=[null, null, null, null, drop] +item=Willow longbow (u), id=59, option=[null, null, null, null, drop] +item=Willow shortbow (u), id=60, option=[null, null, null, null, drop] +item=Willow shortbow (u), id=61, option=[null, null, null, null, drop] +item=Maple longbow (u), id=62, option=[null, null, null, null, drop] +item=Maple longbow (u), id=63, option=[null, null, null, null, drop] +item=Maple shortbow (u), id=64, option=[null, null, null, null, drop] +item=Maple shortbow (u), id=65, option=[null, null, null, null, drop] +item=Yew longbow (u), id=66, option=[null, null, null, null, drop] +item=Yew longbow (u), id=67, option=[null, null, null, null, drop] +item=Yew shortbow (u), id=68, option=[null, null, null, null, drop] +item=Yew shortbow (u), id=69, option=[null, null, null, null, drop] +item=Magic longbow (u), id=70, option=[null, null, null, null, drop] +item=Magic longbow (u), id=71, option=[null, null, null, null, drop] +item=Magic shortbow (u), id=72, option=[null, null, null, null, drop] +item=Magic shortbow (u), id=73, option=[null, null, null, null, drop] +item=Khazard helmet, id=74, option=[null, Wear, null, null, drop] +item=Khazard armour, id=75, option=[null, Wear, null, null, drop] +item=Khazard cell keys, id=76, option=[null, null, null, null, drop] +item=Khali brew, id=77, option=[null, null, null, null, drop] +item=Ice arrows, id=78, option=[null, Wield, null, null, drop] +item=null, id=79, option=[null, null, null, null, drop] +item=null, id=80, option=[null, null, null, null, drop] +item=null, id=81, option=[null, null, null, null, drop] +item=null, id=82, option=[null, null, null, null, drop] +item=Lever, id=83, option=[null, null, null, null, drop] +item=Staff of armadyl, id=84, option=[null, null, null, null, drop] +item=Shiny key, id=85, option=[null, null, null, null, drop] +item=Pendant of lucien, id=86, option=[null, Wear, null, null, drop] +item=Armadyl pendant, id=87, option=[null, Wear, null, null, drop] +item=Boots of lightness, id=88, option=[null, Wear, null, null, drop] +item=Boots of lightness, id=89, option=[null, Wear, null, null, drop] +item=Child's blanket, id=90, option=[null, null, null, null, drop] +item=Guam potion(unf), id=91, option=[null, null, null, Empty, drop] +item=Guam potion(unf), id=92, option=[null, null, null, null, drop] +item=Marrentill potion(unf), id=93, option=[null, null, null, Empty, drop] +item=Marrentill potion(unf), id=94, option=[null, null, null, null, drop] +item=Tarromin potion(unf), id=95, option=[null, null, null, Empty, drop] +item=Tarromin potion(unf), id=96, option=[null, null, null, null, drop] +item=Harralander potion(unf), id=97, option=[null, null, null, Empty, drop] +item=Harralander potion(unf), id=98, option=[null, null, null, null, drop] +item=Ranarr potion(unf), id=99, option=[null, null, null, Empty, drop] +item=Ranarr potion(unf), id=100, option=[null, null, null, null, drop] +item=Irit potion(unf), id=101, option=[null, null, null, Empty, drop] +item=Irit potion(unf), id=102, option=[null, null, null, null, drop] +item=Avantoe potion(unf), id=103, option=[null, null, null, Empty, drop] +item=Avantoe potion(unf), id=104, option=[null, null, null, null, drop] +item=Kwuarm potion(unf), id=105, option=[null, null, null, Empty, drop] +item=Kwuarm potion(unf), id=106, option=[null, null, null, null, drop] +item=Cadantine potion(unf), id=107, option=[null, null, null, Empty, drop] +item=Cadantine potion(unf), id=108, option=[null, null, null, null, drop] +item=Dwarf weed potion(unf), id=109, option=[null, null, null, Empty, drop] +item=Dwarf weed potion(unf), id=110, option=[null, null, null, null, drop] +item=Torstol potion(unf), id=111, option=[null, null, null, Empty, drop] +item=Torstol potion(unf), id=112, option=[null, null, null, null, drop] +item=Strength potion(4), id=113, option=[Drink, null, null, Empty, drop] +item=Strength potion(4), id=114, option=[null, null, null, null, drop] +item=Strength potion(3), id=115, option=[Drink, null, null, Empty, drop] +item=Strength potion(3), id=116, option=[null, null, null, null, drop] +item=Strength potion(2), id=117, option=[Drink, null, null, Empty, drop] +item=Strength potion(2), id=118, option=[null, null, null, null, drop] +item=Strength potion(1), id=119, option=[Drink, null, null, Empty, drop] +item=Strength potion(1), id=120, option=[null, null, null, null, drop] +item=Attack potion(3), id=121, option=[Drink, null, null, Empty, drop] +item=Attack potion(3), id=122, option=[null, null, null, null, drop] +item=Attack potion(2), id=123, option=[Drink, null, null, Empty, drop] +item=Attack potion(2), id=124, option=[null, null, null, null, drop] +item=Attack potion(1), id=125, option=[Drink, null, null, Empty, drop] +item=Attack potion(1), id=126, option=[null, null, null, null, drop] +item=Restore potion(3), id=127, option=[Drink, null, null, Empty, drop] +item=Restore potion(3), id=128, option=[null, null, null, null, drop] +item=Restore potion(2), id=129, option=[Drink, null, null, Empty, drop] +item=Restore potion(2), id=130, option=[null, null, null, null, drop] +item=Restore potion(1), id=131, option=[Drink, null, null, Empty, drop] +item=Restore potion(1), id=132, option=[null, null, null, null, drop] +item=Defence potion(3), id=133, option=[Drink, null, null, Empty, drop] +item=Defence potion(3), id=134, option=[null, null, null, null, drop] +item=Defence potion(2), id=135, option=[Drink, null, null, Empty, drop] +item=Defence potion(2), id=136, option=[null, null, null, null, drop] +item=Defence potion(1), id=137, option=[Drink, null, null, Empty, drop] +item=Defence potion(1), id=138, option=[null, null, null, null, drop] +item=Prayer potion(3), id=139, option=[Drink, null, null, Empty, drop] +item=Prayer potion(3), id=140, option=[null, null, null, null, drop] +item=Prayer potion(2), id=141, option=[Drink, null, null, Empty, drop] +item=Prayer potion(2), id=142, option=[null, null, null, null, drop] +item=Prayer potion(1), id=143, option=[Drink, null, null, Empty, drop] +item=Prayer potion(1), id=144, option=[null, null, null, null, drop] +item=Super attack(3), id=145, option=[Drink, null, null, Empty, drop] +item=Super attack(3), id=146, option=[null, null, null, null, drop] +item=Super attack(2), id=147, option=[Drink, null, null, Empty, drop] +item=Super attack(2), id=148, option=[null, null, null, null, drop] +item=Super attack(1), id=149, option=[Drink, null, null, Empty, drop] +item=Super attack(1), id=150, option=[null, null, null, null, drop] +item=Fishing potion(3), id=151, option=[Drink, null, null, Empty, drop] +item=Fishing potion(3), id=152, option=[null, null, null, null, drop] +item=Fishing potion(2), id=153, option=[Drink, null, null, Empty, drop] +item=Fishing potion(2), id=154, option=[null, null, null, null, drop] +item=Fishing potion(1), id=155, option=[Drink, null, null, Empty, drop] +item=Fishing potion(1), id=156, option=[null, null, null, null, drop] +item=Super strength(3), id=157, option=[Drink, null, null, Empty, drop] +item=Super strength(3), id=158, option=[null, null, null, null, drop] +item=Super strength(2), id=159, option=[Drink, null, null, Empty, drop] +item=Super strength(2), id=160, option=[null, null, null, null, drop] +item=Super strength(1), id=161, option=[Drink, null, null, Empty, drop] +item=Super strength(1), id=162, option=[null, null, null, null, drop] +item=Super defence(3), id=163, option=[Drink, null, null, Empty, drop] +item=Super defence(3), id=164, option=[null, null, null, null, drop] +item=Super defence(2), id=165, option=[Drink, null, null, Empty, drop] +item=Super defence(2), id=166, option=[null, null, null, null, drop] +item=Super defence(1), id=167, option=[Drink, null, null, Empty, drop] +item=Super defence(1), id=168, option=[null, null, null, null, drop] +item=Ranging potion(3), id=169, option=[Drink, null, null, Empty, drop] +item=Ranging potion(3), id=170, option=[null, null, null, null, drop] +item=Ranging potion(2), id=171, option=[Drink, null, null, Empty, drop] +item=Ranging potion(2), id=172, option=[null, null, null, null, drop] +item=Ranging potion(1), id=173, option=[Drink, null, null, Empty, drop] +item=Ranging potion(1), id=174, option=[null, null, null, null, drop] +item=Antipoison(3), id=175, option=[Drink, null, null, Empty, drop] +item=Antipoison(3), id=176, option=[null, null, null, null, drop] +item=Antipoison(2), id=177, option=[Drink, null, null, Empty, drop] +item=Antipoison(2), id=178, option=[null, null, null, null, drop] +item=Antipoison(1), id=179, option=[Drink, null, null, Empty, drop] +item=Antipoison(1), id=180, option=[null, null, null, null, drop] +item=Super antipoison(3), id=181, option=[Drink, null, null, Empty, drop] +item=Super antipoison(3), id=182, option=[null, null, null, null, drop] +item=Super antipoison(2), id=183, option=[Drink, null, null, Empty, drop] +item=Super antipoison(2), id=184, option=[null, null, null, null, drop] +item=Super antipoison(1), id=185, option=[Drink, null, null, Empty, drop] +item=Super antipoison(1), id=186, option=[null, null, null, null, drop] +item=Weapon poison, id=187, option=[null, null, null, Empty, drop] +item=Weapon poison, id=188, option=[null, null, null, null, drop] +item=Zamorak brew(3), id=189, option=[Drink, null, null, Empty, drop] +item=Zamorak brew(3), id=190, option=[null, null, null, null, drop] +item=Zamorak brew(2), id=191, option=[Drink, null, null, Empty, drop] +item=Zamorak brew(2), id=192, option=[null, null, null, null, drop] +item=Zamorak brew(1), id=193, option=[Drink, null, null, Empty, drop] +item=Zamorak brew(1), id=194, option=[null, null, null, null, drop] +item=Potion, id=195, option=[null, null, null, null, drop] +item=Potion, id=196, option=[null, null, null, null, drop] +item=Poison chalice, id=197, option=[Drink, null, null, null, drop] +item=Poison chalice, id=198, option=[null, null, null, null, drop] +item=Grimy guam, id=199, option=[Clean, null, null, null, drop] +item=Grimy guam, id=200, option=[null, null, null, null, drop] +item=Grimy marrentill, id=201, option=[Clean, null, null, null, drop] +item=Grimy marrentill, id=202, option=[null, null, null, null, drop] +item=Grimy tarromin, id=203, option=[Clean, null, null, null, drop] +item=Grimy tarromin, id=204, option=[null, null, null, null, drop] +item=Grimy harralander, id=205, option=[Clean, null, null, null, drop] +item=Grimy harralander, id=206, option=[null, null, null, null, drop] +item=Grimy ranarr, id=207, option=[Clean, null, null, null, drop] +item=Grimy ranarr, id=208, option=[null, null, null, null, drop] +item=Grimy irit, id=209, option=[Clean, null, null, null, drop] +item=Grimy irit, id=210, option=[null, null, null, null, drop] +item=Grimy avantoe, id=211, option=[Clean, null, null, null, drop] +item=Grimy avantoe, id=212, option=[null, null, null, null, drop] +item=Grimy kwuarm, id=213, option=[Clean, null, null, null, drop] +item=Grimy kwuarm, id=214, option=[null, null, null, null, drop] +item=Grimy cadantine, id=215, option=[Clean, null, null, null, drop] +item=Grimy cadantine, id=216, option=[null, null, null, null, drop] +item=Grimy dwarf weed, id=217, option=[Clean, null, null, null, drop] +item=Grimy dwarf weed, id=218, option=[null, null, null, null, drop] +item=Grimy torstol, id=219, option=[Clean, null, null, null, drop] +item=Grimy torstol, id=220, option=[null, null, null, null, drop] +item=Eye of newt, id=221, option=[null, null, null, null, drop] +item=Eye of newt, id=222, option=[null, null, null, null, drop] +item=Red spiders' eggs, id=223, option=[null, null, null, null, drop] +item=Red spiders' eggs, id=224, option=[null, null, null, null, drop] +item=Limpwurt root, id=225, option=[null, null, null, null, drop] +item=Limpwurt root, id=226, option=[null, null, null, null, drop] +item=Vial of water, id=227, option=[null, null, null, Empty, drop] +item=Vial of water, id=228, option=[null, null, null, null, drop] +item=Vial, id=229, option=[null, null, null, null, drop] +item=Vial, id=230, option=[null, null, null, null, drop] +item=Snape grass, id=231, option=[null, null, null, null, drop] +item=Snape grass, id=232, option=[null, null, null, null, drop] +item=Pestle and mortar, id=233, option=[null, null, null, null, drop] +item=Pestle and mortar, id=234, option=[null, null, null, null, drop] +item=Unicorn horn dust, id=235, option=[null, null, null, null, drop] +item=Unicorn horn dust, id=236, option=[null, null, null, null, drop] +item=Unicorn horn, id=237, option=[null, null, null, null, drop] +item=Unicorn horn, id=238, option=[null, null, null, null, drop] +item=White berries, id=239, option=[null, null, null, null, drop] +item=White berries, id=240, option=[null, null, null, null, drop] +item=Dragon scale dust, id=241, option=[null, null, null, null, drop] +item=Dragon scale dust, id=242, option=[null, null, null, null, drop] +item=Blue dragon scale, id=243, option=[null, null, null, null, drop] +item=Blue dragon scale, id=244, option=[null, null, null, null, drop] +item=Wine of zamorak, id=245, option=[null, null, null, null, drop] +item=Wine of zamorak, id=246, option=[null, null, null, null, drop] +item=Jangerberries, id=247, option=[Eat, null, null, null, drop] +item=Jangerberries, id=248, option=[null, null, null, null, drop] +item=Clean guam, id=249, option=[null, null, null, null, drop] +item=Clean guam, id=250, option=[null, null, null, null, drop] +item=Clean marrentill, id=251, option=[null, null, null, null, drop] +item=Clean marrentill, id=252, option=[null, null, null, null, drop] +item=Clean tarromin, id=253, option=[null, null, null, null, drop] +item=Clean tarromin, id=254, option=[null, null, null, null, drop] +item=Clean harralander, id=255, option=[null, null, null, null, drop] +item=Clean harralander, id=256, option=[null, null, null, null, drop] +item=Clean ranarr, id=257, option=[null, null, null, null, drop] +item=Clean ranarr, id=258, option=[null, null, null, null, drop] +item=Clean irit, id=259, option=[null, null, null, null, drop] +item=Clean irit, id=260, option=[null, null, null, null, drop] +item=Clean avantoe, id=261, option=[null, null, null, null, drop] +item=Clean avantoe, id=262, option=[null, null, null, null, drop] +item=Clean kwuarm, id=263, option=[null, null, null, null, drop] +item=Clean kwuarm, id=264, option=[null, null, null, null, drop] +item=Clean cadantine, id=265, option=[null, null, null, null, drop] +item=Clean cadantine, id=266, option=[null, null, null, null, drop] +item=Clean dwarf weed, id=267, option=[null, null, null, null, drop] +item=Clean dwarf weed, id=268, option=[null, null, null, null, drop] +item=Clean torstol, id=269, option=[null, null, null, null, drop] +item=Clean torstol, id=270, option=[null, null, null, null, drop] +item=Pressure gauge, id=271, option=[null, null, null, null, drop] +item=Fish food, id=272, option=[null, null, null, null, drop] +item=Poison, id=273, option=[null, null, null, null, drop] +item=Poisoned fish food, id=274, option=[null, null, null, null, drop] +item=Key, id=275, option=[null, null, null, null, drop] +item=Rubber tube, id=276, option=[null, null, null, null, drop] +item=Oil can, id=277, option=[null, null, null, null, drop] +item=Cattleprod, id=278, option=[null, Equip, null, null, drop] +item=Sheep feed, id=279, option=[null, null, null, null, drop] +item=Sheep bones (1), id=280, option=[null, null, null, null, drop] +item=Sheep bones (2), id=281, option=[null, null, null, null, drop] +item=Sheep bones (3), id=282, option=[null, null, null, null, drop] +item=Sheep bones (4), id=283, option=[null, null, null, null, drop] +item=Plague jacket, id=284, option=[null, Wear, null, null, drop] +item=Plague trousers, id=285, option=[null, Wear, null, null, drop] +item=Orange goblin mail, id=286, option=[null, Wear, null, null, drop] +item=Blue goblin mail, id=287, option=[null, Wear, null, null, drop] +item=Goblin mail, id=288, option=[null, Wear, null, null, drop] +item=Goblin mail, id=289, option=[null, null, null, null, drop] +item=Research package, id=290, option=[null, null, null, null, drop] +item=Notes, id=291, option=[null, null, null, null, drop] +item=Book on baxtorian, id=292, option=[Read, null, null, null, drop] +item=A key, id=293, option=[null, null, null, null, drop] +item=Glarial's pebble, id=294, option=[null, null, null, null, drop] +item=Glarial's amulet, id=295, option=[null, Wear, null, null, drop] +item=Glarial's urn, id=296, option=[null, null, null, null, drop] +item=Glarial's urn, id=297, option=[null, null, null, null, drop] +item=A key, id=298, option=[null, null, null, null, drop] +item=Mithril seeds, id=299, option=[Plant, null, null, null, drop] +item=Rat's tail, id=300, option=[null, null, null, null, drop] +item=Lobster pot, id=301, option=[null, null, null, null, drop] +item=Lobster pot, id=302, option=[null, null, null, null, drop] +item=Small fishing net, id=303, option=[null, null, null, null, drop] +item=Small fishing net, id=304, option=[null, null, null, null, drop] +item=Big fishing net, id=305, option=[null, null, null, null, drop] +item=Big fishing net, id=306, option=[null, null, null, null, drop] +item=Fishing rod, id=307, option=[null, null, null, null, drop] +item=Fishing rod, id=308, option=[null, null, null, null, drop] +item=Fly fishing rod, id=309, option=[null, null, null, null, drop] +item=Fly fishing rod, id=310, option=[null, null, null, null, drop] +item=Harpoon, id=311, option=[null, null, null, null, drop] +item=Harpoon, id=312, option=[null, null, null, null, drop] +item=Fishing bait, id=313, option=[null, null, null, null, drop] +item=Feather, id=314, option=[null, null, null, null, drop] +item=Shrimps, id=315, option=[Eat, null, null, null, drop] +item=Shrimps, id=316, option=[null, null, null, null, drop] +item=Raw shrimps, id=317, option=[null, null, null, null, drop] +item=Raw shrimps, id=318, option=[null, null, null, null, drop] +item=Anchovies, id=319, option=[Eat, null, null, null, drop] +item=Anchovies, id=320, option=[null, null, null, null, drop] +item=Raw anchovies, id=321, option=[null, null, null, null, drop] +item=Raw anchovies, id=322, option=[null, null, null, null, drop] +item=Burnt fish, id=323, option=[null, null, null, null, drop] +item=Burnt fish, id=324, option=[null, null, null, null, drop] +item=Sardine, id=325, option=[Eat, null, null, null, drop] +item=Sardine, id=326, option=[null, null, null, null, drop] +item=Raw sardine, id=327, option=[null, null, null, null, drop] +item=Raw sardine, id=328, option=[null, null, null, null, drop] +item=Salmon, id=329, option=[Eat, null, null, null, drop] +item=Salmon, id=330, option=[null, null, null, null, drop] +item=Raw salmon, id=331, option=[null, null, null, null, drop] +item=Raw salmon, id=332, option=[null, null, null, null, drop] +item=Trout, id=333, option=[Eat, null, null, null, drop] +item=Trout, id=334, option=[null, null, null, null, drop] +item=Raw trout, id=335, option=[null, null, null, null, drop] +item=Raw trout, id=336, option=[null, null, null, null, drop] +item=Giant carp, id=337, option=[Eat, null, null, null, drop] +item=Raw giant carp, id=338, option=[null, null, null, null, drop] +item=Cod, id=339, option=[Eat, null, null, null, drop] +item=Cod, id=340, option=[null, null, null, null, drop] +item=Raw cod, id=341, option=[null, null, null, null, drop] +item=Raw cod, id=342, option=[null, null, null, null, drop] +item=Burnt fish, id=343, option=[null, null, null, null, drop] +item=Burnt fish, id=344, option=[null, null, null, null, drop] +item=Raw herring, id=345, option=[null, null, null, null, drop] +item=Raw herring, id=346, option=[null, null, null, null, drop] +item=Herring, id=347, option=[Eat, null, null, null, drop] +item=Herring, id=348, option=[null, null, null, null, drop] +item=Raw pike, id=349, option=[null, null, null, null, drop] +item=Raw pike, id=350, option=[null, null, null, null, drop] +item=Pike, id=351, option=[Eat, null, null, null, drop] +item=Pike, id=352, option=[null, null, null, null, drop] +item=Raw mackerel, id=353, option=[null, null, null, null, drop] +item=Raw mackerel, id=354, option=[null, null, null, null, drop] +item=Mackerel, id=355, option=[Eat, null, null, null, drop] +item=Mackerel, id=356, option=[null, null, null, null, drop] +item=Burnt fish, id=357, option=[null, null, null, null, drop] +item=Burnt fish, id=358, option=[null, null, null, null, drop] +item=Raw tuna, id=359, option=[null, null, null, null, drop] +item=Raw tuna, id=360, option=[null, null, null, null, drop] +item=Tuna, id=361, option=[Eat, null, null, null, drop] +item=Tuna, id=362, option=[null, null, null, null, drop] +item=Raw bass, id=363, option=[null, null, null, null, drop] +item=Raw bass, id=364, option=[null, null, null, null, drop] +item=Bass, id=365, option=[Eat, null, null, null, drop] +item=Bass, id=366, option=[null, null, null, null, drop] +item=Burnt fish, id=367, option=[null, null, null, null, drop] +item=Burnt fish, id=368, option=[null, null, null, null, drop] +item=Burnt fish, id=369, option=[null, null, null, null, drop] +item=Burnt fish, id=370, option=[null, null, null, null, drop] +item=Raw swordfish, id=371, option=[null, null, null, null, drop] +item=Raw swordfish, id=372, option=[null, null, null, null, drop] +item=Swordfish, id=373, option=[Eat, null, null, null, drop] +item=Swordfish, id=374, option=[null, null, null, null, drop] +item=Burnt swordfish, id=375, option=[null, null, null, null, drop] +item=Burnt swordfish, id=376, option=[null, null, null, null, drop] +item=Raw lobster, id=377, option=[null, null, null, null, drop] +item=Raw lobster, id=378, option=[null, null, null, null, drop] +item=Lobster, id=379, option=[Eat, null, null, null, drop] +item=Lobster, id=380, option=[null, null, null, null, drop] +item=Burnt lobster, id=381, option=[null, null, null, null, drop] +item=Burnt lobster, id=382, option=[null, null, null, null, drop] +item=Raw shark, id=383, option=[null, null, null, null, drop] +item=Raw shark, id=384, option=[null, null, null, null, drop] +item=Shark, id=385, option=[Eat, null, null, null, drop] +item=Shark, id=386, option=[null, null, null, null, drop] +item=Burnt shark, id=387, option=[null, null, null, null, drop] +item=Burnt shark, id=388, option=[null, null, null, null, drop] +item=Raw manta ray, id=389, option=[null, null, null, null, drop] +item=Raw manta ray, id=390, option=[null, null, null, null, drop] +item=Manta ray, id=391, option=[Eat, null, null, null, drop] +item=Manta ray, id=392, option=[null, null, null, null, drop] +item=Burnt manta ray, id=393, option=[null, null, null, null, drop] +item=Burnt manta ray, id=394, option=[null, null, null, null, drop] +item=Raw sea turtle, id=395, option=[null, null, null, null, drop] +item=Raw sea turtle, id=396, option=[null, null, null, null, drop] +item=Sea turtle, id=397, option=[Eat, null, null, null, drop] +item=Sea turtle, id=398, option=[null, null, null, null, drop] +item=Burnt sea turtle, id=399, option=[null, null, null, null, drop] +item=Burnt sea turtle, id=400, option=[null, null, null, null, drop] +item=Seaweed, id=401, option=[null, null, null, null, drop] +item=Seaweed, id=402, option=[null, null, null, null, drop] +item=Edible seaweed, id=403, option=[Eat, null, null, null, drop] +item=Edible seaweed, id=404, option=[null, null, null, null, drop] +item=Casket, id=405, option=[Open, null, null, null, drop] +item=Casket, id=406, option=[null, null, null, null, drop] +item=Oyster, id=407, option=[Open, null, null, null, drop] +item=Oyster, id=408, option=[null, null, null, null, drop] +item=Empty oyster, id=409, option=[null, null, null, null, drop] +item=Empty oyster, id=410, option=[null, null, null, null, drop] +item=Oyster pearl, id=411, option=[null, null, null, null, drop] +item=Oyster pearl, id=412, option=[null, null, null, null, drop] +item=Oyster pearls, id=413, option=[null, null, null, null, drop] +item=Oyster pearls, id=414, option=[null, null, null, null, drop] +item=Ethenea, id=415, option=[null, null, null, null, drop] +item=Liquid honey, id=416, option=[null, null, null, null, drop] +item=Sulphuric broline, id=417, option=[null, null, null, null, drop] +item=Plague sample, id=418, option=[null, null, null, null, drop] +item=Touch paper, id=419, option=[null, null, null, null, drop] +item=Distillator, id=420, option=[null, null, null, null, drop] +item=Lathas' amulet, id=421, option=[null, Wear, null, null, drop] +item=Bird feed, id=422, option=[null, null, null, null, drop] +item=Key, id=423, option=[null, null, null, null, drop] +item=Pigeon cage, id=424, option=[Open, null, null, null, drop] +item=Pigeon cage, id=425, option=[null, null, null, null, drop] +item=Priest gown, id=426, option=[null, Wear, null, null, drop] +item=Priest gown, id=427, option=[null, null, null, null, drop] +item=Priest gown, id=428, option=[null, Wear, null, null, drop] +item=Priest gown, id=429, option=[null, null, null, null, drop] +item=Doctors' gown, id=430, option=[null, Wear, null, null, drop] +item=Karamjan rum, id=431, option=[null, null, null, Drink, drop] +item=Chest key, id=432, option=[null, null, null, null, drop] +item=Pirate message, id=433, option=[Read, null, null, null, drop] +item=Clay, id=434, option=[null, null, null, null, drop] +item=Clay, id=435, option=[null, null, null, null, drop] +item=Copper ore, id=436, option=[null, null, null, null, drop] +item=Copper ore, id=437, option=[null, null, null, null, drop] +item=Tin ore, id=438, option=[null, null, null, null, drop] +item=Tin ore, id=439, option=[null, null, null, null, drop] +item=Iron ore, id=440, option=[null, null, null, null, drop] +item=Iron ore, id=441, option=[null, null, null, null, drop] +item=Silver ore, id=442, option=[null, null, null, null, drop] +item=Silver ore, id=443, option=[null, null, null, null, drop] +item=Gold ore, id=444, option=[null, null, null, null, drop] +item=Gold ore, id=445, option=[null, null, null, null, drop] +item='perfect' gold ore, id=446, option=[null, null, null, null, drop] +item=Mithril ore, id=447, option=[null, null, null, null, drop] +item=Mithril ore, id=448, option=[null, null, null, null, drop] +item=Adamantite ore, id=449, option=[null, null, null, null, drop] +item=Adamantite ore, id=450, option=[null, null, null, null, drop] +item=Runite ore, id=451, option=[null, null, null, null, drop] +item=Runite ore, id=452, option=[null, null, null, null, drop] +item=Coal, id=453, option=[null, null, null, null, drop] +item=Coal, id=454, option=[null, null, null, null, drop] +item=Barcrawl card, id=455, option=[Read, null, null, null, drop] +item=Scorpion cage, id=456, option=[null, null, null, null, Destroy] +item=Scorpion cage, id=457, option=[null, null, null, null, Destroy] +item=Scorpion cage, id=458, option=[null, null, null, null, Destroy] +item=Scorpion cage, id=459, option=[null, null, null, null, Destroy] +item=Scorpion cage, id=460, option=[null, null, null, null, Destroy] +item=Scorpion cage, id=461, option=[null, null, null, null, Destroy] +item=Scorpion cage, id=462, option=[null, null, null, null, Destroy] +item=Scorpion cage, id=463, option=[null, null, null, null, Destroy] +item=Strange fruit, id=464, option=[Eat, null, null, null, drop] +item=Strange fruit, id=465, option=[null, null, null, null, drop] +item=Pickaxe handle, id=466, option=[null, Wield, null, null, drop] +item=Pickaxe handle, id=467, option=[null, null, null, null, drop] +item=Broken pickaxe, id=468, option=[null, null, null, null, drop] +item=Broken pickaxe, id=469, option=[null, null, null, null, drop] +item=Broken pickaxe, id=470, option=[null, null, null, null, drop] +item=Broken pickaxe, id=471, option=[null, null, null, null, drop] +item=Broken pickaxe, id=472, option=[null, null, null, null, drop] +item=Broken pickaxe, id=473, option=[null, null, null, null, drop] +item=Broken pickaxe, id=474, option=[null, null, null, null, drop] +item=Broken pickaxe, id=475, option=[null, null, null, null, drop] +item=Broken pickaxe, id=476, option=[null, null, null, null, drop] +item=Broken pickaxe, id=477, option=[null, null, null, null, drop] +item=Broken pickaxe, id=478, option=[null, null, null, null, drop] +item=Broken pickaxe, id=479, option=[null, null, null, null, drop] +item=Bronze pick head, id=480, option=[null, null, null, null, drop] +item=Bronze pick head, id=481, option=[null, null, null, null, drop] +item=Iron pick head, id=482, option=[null, null, null, null, drop] +item=Iron pick head, id=483, option=[null, null, null, null, drop] +item=Steel pick head, id=484, option=[null, null, null, null, drop] +item=Steel pick head, id=485, option=[null, null, null, null, drop] +item=Mithril pick head, id=486, option=[null, null, null, null, drop] +item=Mithril pick head, id=487, option=[null, null, null, null, drop] +item=Adamant pick head, id=488, option=[null, null, null, null, drop] +item=Adamant pick head, id=489, option=[null, null, null, null, drop] +item=Rune pick head, id=490, option=[null, null, null, null, drop] +item=Rune pick head, id=491, option=[null, null, null, null, drop] +item=Axe handle, id=492, option=[null, Wield, null, null, drop] +item=Axe handle, id=493, option=[null, null, null, null, drop] +item=Broken axe, id=494, option=[null, null, null, null, drop] +item=Broken axe, id=495, option=[null, null, null, null, drop] +item=Broken axe, id=496, option=[null, null, null, null, drop] +item=Broken axe, id=497, option=[null, null, null, null, drop] +item=Broken axe, id=498, option=[null, null, null, null, drop] +item=Broken axe, id=499, option=[null, null, null, null, drop] +item=Broken axe, id=500, option=[null, null, null, null, drop] +item=Broken axe, id=501, option=[null, null, null, null, drop] +item=Broken axe, id=502, option=[null, null, null, null, drop] +item=Broken axe, id=503, option=[null, null, null, null, drop] +item=Broken axe, id=504, option=[null, null, null, null, drop] +item=Broken axe, id=505, option=[null, null, null, null, drop] +item=Broken axe, id=506, option=[null, null, null, null, drop] +item=Broken axe, id=507, option=[null, null, null, null, drop] +item=Bronze axe head, id=508, option=[null, null, null, null, drop] +item=Bronze axe head, id=509, option=[null, null, null, null, drop] +item=Iron axe head, id=510, option=[null, null, null, null, drop] +item=Iron axe head, id=511, option=[null, null, null, null, drop] +item=Steel axe head, id=512, option=[null, null, null, null, drop] +item=Steel axe head, id=513, option=[null, null, null, null, drop] +item=Black axe head, id=514, option=[null, null, null, null, drop] +item=Black axe head, id=515, option=[null, null, null, null, drop] +item=Mithril axe head, id=516, option=[null, null, null, null, drop] +item=Mithril axe head, id=517, option=[null, null, null, null, drop] +item=Adamant axe head, id=518, option=[null, null, null, null, drop] +item=Adamant axe head, id=519, option=[null, null, null, null, drop] +item=Rune axe head, id=520, option=[null, null, null, null, drop] +item=Rune axe head, id=521, option=[null, null, null, null, drop] +item=Enchanted beef, id=522, option=[null, null, null, null, drop] +item=Enchanted rat meat, id=523, option=[null, null, null, null, drop] +item=Enchanted bear meat, id=524, option=[null, null, null, null, drop] +item=Enchanted chicken, id=525, option=[null, null, null, null, drop] +item=Bones, id=526, option=[Bury, null, null, null, drop] +item=Bones, id=527, option=[null, null, null, null, drop] +item=Burnt bones, id=528, option=[Bury, null, null, null, drop] +item=Burnt bones, id=529, option=[null, null, null, null, drop] +item=Bat bones, id=530, option=[Bury, null, null, null, drop] +item=Bat bones, id=531, option=[null, null, null, null, drop] +item=Big bones, id=532, option=[Bury, null, null, null, drop] +item=Big bones, id=533, option=[null, null, null, null, drop] +item=Babydragon bones, id=534, option=[Bury, null, null, null, drop] +item=Babydragon bones, id=535, option=[null, null, null, null, drop] +item=Dragon bones, id=536, option=[Bury, null, null, null, drop] +item=Dragon bones, id=537, option=[null, null, null, null, drop] +item=Druid's robe, id=538, option=[null, Wear, null, null, drop] +item=Druid's robe, id=539, option=[null, null, null, null, drop] +item=Druid's robe, id=540, option=[null, Wear, null, null, drop] +item=Druid's robe, id=541, option=[null, null, null, null, drop] +item=Monk's robe, id=542, option=[null, Wear, null, null, drop] +item=Monk's robe, id=543, option=[null, null, null, null, drop] +item=Monk's robe, id=544, option=[null, Wear, null, null, drop] +item=Monk's robe, id=545, option=[null, null, null, null, drop] +item=Shade robe, id=546, option=[null, Wear, null, null, drop] +item=Whoopsie, id=547, option=[null, null, null, null, drop] +item=Shade robe, id=548, option=[null, Wear, null, null, drop] +item=Whoopsie, id=549, option=[null, null, null, null, drop] +item=Newcomer map, id=550, option=[Read, null, null, null, drop] +item=Newcomer map, id=551, option=[null, null, null, null, drop] +item=Ghostspeak amulet, id=552, option=[null, Wear, null, null, drop] +item=Ghost's skull, id=553, option=[null, null, null, null, drop] +item=Fire rune, id=554, option=[null, null, null, null, drop] +item=Water rune, id=555, option=[null, null, null, null, drop] +item=Air rune, id=556, option=[null, null, null, null, drop] +item=Earth rune, id=557, option=[null, null, null, null, drop] +item=Mind rune, id=558, option=[null, null, null, null, drop] +item=Body rune, id=559, option=[null, null, null, null, drop] +item=Death rune, id=560, option=[null, null, null, null, drop] +item=Nature rune, id=561, option=[null, null, null, null, drop] +item=Chaos rune, id=562, option=[null, null, null, null, drop] +item=Law rune, id=563, option=[null, null, null, null, drop] +item=Cosmic rune, id=564, option=[null, null, null, null, drop] +item=Blood rune, id=565, option=[null, null, null, null, drop] +item=Soul rune, id=566, option=[null, null, null, null, drop] +item=Unpowered orb, id=567, option=[null, null, null, null, drop] +item=Unpowered orb, id=568, option=[null, null, null, null, drop] +item=Fire orb, id=569, option=[null, null, null, null, drop] +item=Fire orb, id=570, option=[null, null, null, null, drop] +item=Water orb, id=571, option=[null, null, null, null, drop] +item=Water orb, id=572, option=[null, null, null, null, drop] +item=Air orb, id=573, option=[null, null, null, null, drop] +item=Air orb, id=574, option=[null, null, null, null, drop] +item=Earth orb, id=575, option=[null, null, null, null, drop] +item=Earth orb, id=576, option=[null, null, null, null, drop] +item=Wizard robe, id=577, option=[null, Wear, null, null, drop] +item=Wizard robe, id=578, option=[null, null, null, null, drop] +item=Wizard hat, id=579, option=[null, Wear, null, null, drop] +item=Wizard hat, id=580, option=[null, null, null, null, drop] +item=Black robe, id=581, option=[null, Wear, null, null, drop] +item=Black robe, id=582, option=[null, null, null, null, drop] +item=Bailing bucket, id=583, option=[Bail-with, null, null, null, drop] +item=Bailing bucket, id=584, option=[null, null, null, null, drop] +item=Bailing bucket, id=585, option=[Empty, null, null, null, drop] +item=Bailing bucket, id=586, option=[null, null, null, null, drop] +item=Orb of protection, id=587, option=[null, null, null, null, drop] +item=Orbs of protection, id=588, option=[null, null, null, null, drop] +item=Gnome amulet, id=589, option=[null, Wear, null, null, drop] +item=Tinderbox, id=590, option=[null, null, null, null, drop] +item=Tinderbox, id=591, option=[null, null, null, null, drop] +item=Ashes, id=592, option=[null, null, null, null, drop] +item=Ashes, id=593, option=[null, null, null, null, drop] +item=Lit torch, id=594, option=[Extinguish, null, null, null, drop] +item=Torch, id=595, option=[Extinguish, null, null, null, drop] +item=Unlit torch, id=596, option=[null, null, null, null, drop] +item=Unlit torch, id=597, option=[null, null, null, null, drop] +item=Bronze fire arrows, id=598, option=[null, Wield, null, null, drop] +item=Double helix, id=599, option=[Wear, null, null, null, drop] +item=Astronomy book, id=600, option=[Read, null, null, null, drop] +item=Goblin kitchen key, id=601, option=[null, null, null, null, Destroy] +item=Lens mould, id=602, option=[null, null, null, null, Destroy] +item=Observatory lens, id=603, option=[null, null, null, null, Destroy] +item=Bone shard, id=604, option=[Inspect, null, null, null, drop] +item=Bone key, id=605, option=[null, null, null, null, drop] +item=Stone-plaque, id=606, option=[Read, null, null, null, drop] +item=Tattered scroll, id=607, option=[Read, null, null, null, drop] +item=Crumpled scroll, id=608, option=[Read, null, null, null, drop] +item=Rashiliyia corpse, id=609, option=[null, null, null, null, drop] +item=Zadimus corpse, id=610, option=[Bury, null, null, null, drop] +item=Locating crystal, id=611, option=[Activate, null, null, null, drop] +item=Locating crystal, id=612, option=[null, null, null, null, drop] +item=Locating crystal, id=613, option=[null, null, null, null, drop] +item=Locating crystal, id=614, option=[null, null, null, null, drop] +item=Locating crystal, id=615, option=[null, null, null, null, drop] +item=Beads of the dead, id=616, option=[null, Wear, null, null, Destroy] +item=Coins, id=617, option=[null, null, null, null, drop] +item=Bone beads, id=618, option=[null, null, null, null, drop] +item=Paramaya ticket, id=619, option=[null, null, null, null, drop] +item=Paramaya ticket, id=620, option=[null, null, null, null, drop] +item=Ship ticket, id=621, option=[null, null, null, null, drop] +item=Whoopsie, id=622, option=[null, null, null, null, drop] +item=Sword pommel, id=623, option=[null, null, null, null, drop] +item=Bervirius notes, id=624, option=[Read, null, null, null, drop] +item=Wampum belt, id=625, option=[null, null, null, null, drop] +item=Boots, id=626, option=[null, Wear, null, null, drop] +item=Boots, id=627, option=[null, null, null, null, drop] +item=Boots, id=628, option=[null, Wear, null, null, drop] +item=Boots, id=629, option=[null, null, null, null, drop] +item=Boots, id=630, option=[null, Wear, null, null, drop] +item=Boots, id=631, option=[null, null, null, null, drop] +item=Boots, id=632, option=[null, Wear, null, null, drop] +item=Boots, id=633, option=[null, null, null, null, drop] +item=Boots, id=634, option=[null, Wear, null, null, drop] +item=Boots, id=635, option=[null, null, null, null, drop] +item=Robe top, id=636, option=[null, Wear, null, null, drop] +item=Robe top, id=637, option=[null, null, null, null, drop] +item=Robe top, id=638, option=[null, Wear, null, null, drop] +item=Robe top, id=639, option=[null, null, null, null, drop] +item=Robe top, id=640, option=[null, Wear, null, null, drop] +item=Robe top, id=641, option=[null, null, null, null, drop] +item=Robe top, id=642, option=[null, Wear, null, null, drop] +item=Robe top, id=643, option=[null, null, null, null, drop] +item=Robe top, id=644, option=[null, Wear, null, null, drop] +item=Robe top, id=645, option=[null, null, null, null, drop] +item=Robe bottoms, id=646, option=[null, Wear, null, null, drop] +item=Robe bottoms, id=647, option=[null, null, null, null, drop] +item=Robe bottoms, id=648, option=[null, Wear, null, null, drop] +item=Robe bottoms, id=649, option=[null, null, null, null, drop] +item=Robe bottoms, id=650, option=[null, Wear, null, null, drop] +item=Robe bottoms, id=651, option=[null, null, null, null, drop] +item=Robe bottoms, id=652, option=[null, Wear, null, null, drop] +item=Robe bottoms, id=653, option=[null, null, null, null, drop] +item=Robe bottoms, id=654, option=[null, Wear, null, null, drop] +item=Robe bottoms, id=655, option=[null, null, null, null, drop] +item=Hat, id=656, option=[null, Wear, null, null, drop] +item=Hat, id=657, option=[null, null, null, null, drop] +item=Hat, id=658, option=[null, Wear, null, null, drop] +item=Hat, id=659, option=[null, null, null, null, drop] +item=Hat, id=660, option=[null, Wear, null, null, drop] +item=Hat, id=661, option=[null, null, null, null, drop] +item=Hat, id=662, option=[null, Wear, null, null, drop] +item=Hat, id=663, option=[null, null, null, null, drop] +item=Hat, id=664, option=[null, Wear, null, null, drop] +item=Hat, id=665, option=[null, null, null, null, drop] +item=Portrait, id=666, option=[null, null, null, null, drop] +item=Blurite sword, id=667, option=[null, Wield, null, null, drop] +item=Blurite ore, id=668, option=[null, null, null, null, drop] +item=Specimen jar, id=669, option=[null, null, null, null, drop] +item=Specimen brush, id=670, option=[null, null, null, null, drop] +item=Animal skull, id=671, option=[null, null, null, null, Destroy] +item=Special cup, id=672, option=[null, null, null, null, Destroy] +item=Teddy, id=673, option=[null, null, null, null, Destroy] +item=Cracked sample, id=674, option=[null, null, null, null, drop] +item=Rock pick, id=675, option=[null, null, null, null, drop] +item=Trowel, id=676, option=[null, null, null, null, drop] +item=Panning tray, id=677, option=[null, null, null, Search, drop] +item=Panning tray, id=678, option=[null, Search, null, null, drop] +item=Panning tray, id=679, option=[null, Search, null, null, drop] +item=Nuggets, id=680, option=[null, null, null, null, drop] +item=Ancient talisman, id=681, option=[null, null, null, null, drop] +item=Unstamped letter, id=682, option=[null, null, null, null, drop] +item=Sealed letter, id=683, option=[null, null, null, null, drop] +item=Belt buckle, id=684, option=[null, null, null, null, drop] +item=Old boot, id=685, option=[null, null, null, null, drop] +item=Rusty sword, id=686, option=[null, null, null, null, drop] +item=Broken arrow, id=687, option=[null, null, null, null, drop] +item=Buttons, id=688, option=[null, Polish, null, null, drop] +item=Broken staff, id=689, option=[null, null, null, null, drop] +item=Broken glass, id=690, option=[null, null, null, null, drop] +item=Level 1 certificate, id=691, option=[Look-at, null, null, null, drop] +item=Level 2 certificate, id=692, option=[Look-at, null, null, null, drop] +item=Level 3 certificate, id=693, option=[Look-at, null, null, null, drop] +item=Ceramic remains, id=694, option=[null, null, null, null, drop] +item=Old tooth, id=695, option=[null, null, null, null, drop] +item=Invitation letter, id=696, option=[null, Read, null, null, drop] +item=Damaged armour, id=697, option=[null, null, null, null, drop] +item=Broken armour, id=698, option=[null, null, null, null, drop] +item=Stone tablet, id=699, option=[null, Read, null, null, drop] +item=Chemical powder, id=700, option=[null, null, null, null, drop] +item=Ammonium nitrate, id=701, option=[null, null, null, null, drop] +item=Unidentified liquid, id=702, option=[null, Empty, null, null, drop] +item=Nitroglycerin, id=703, option=[null, null, null, null, drop] +item=Ground charcoal, id=704, option=[null, null, null, null, drop] +item=Mixed chemicals, id=705, option=[null, null, null, null, drop] +item=Mixed chemicals, id=706, option=[null, null, null, null, drop] +item=Chemical compound, id=707, option=[null, null, null, null, drop] +item=Arcenia root, id=708, option=[null, null, null, null, drop] +item=Chest key, id=709, option=[null, null, null, null, drop] +item=Vase, id=710, option=[null, null, null, null, drop] +item=Book on chemicals, id=711, option=[null, Read, null, null, drop] +item=Cup of tea, id=712, option=[Drink, null, null, null, drop] +item=Enjifern, id=713, option=[Wear, null, null, null, drop] +item=Radimus notes, id=714, option=[Read, Complete, null, null, drop] +item=Radimus notes, id=715, option=[Read, null, null, null, drop] +item=Bull roarer, id=716, option=[Swing, null, null, null, drop] +item=Scrawled note, id=717, option=[Read, null, null, null, drop] +item=A scribbled note, id=718, option=[Read, null, null, null, drop] +item=Scrumpled note, id=719, option=[Read, null, null, null, drop] +item=Sketch, id=720, option=[Look, null, null, null, drop] +item=Gold bowl, id=721, option=[null, null, null, null, drop] +item=Blessed gold bowl, id=722, option=[null, null, null, null, drop] +item=Golden bowl, id=723, option=[null, null, null, Empty, drop] +item=Golden bowl, id=724, option=[null, null, null, Empty, drop] +item=Golden bowl, id=725, option=[null, null, null, Empty, drop] +item=Golden bowl, id=726, option=[null, null, null, Empty, drop] +item=Hollow reed, id=727, option=[null, null, null, null, drop] +item=Hollow reed, id=728, option=[null, null, null, null, drop] +item=Shamans tome, id=729, option=[Read, null, null, null, drop] +item=Binding book, id=730, option=[Read, Enchant-Vials, null, null, drop] +item=Enchanted vial, id=731, option=[null, null, null, null, drop] +item=Holy water, id=732, option=[null, Wield, null, null, drop] +item=Smashed glass, id=733, option=[null, null, null, null, drop] +item=Whoopsie, id=734, option=[null, null, null, null, drop] +item=Yommi tree seeds, id=735, option=[Look, null, null, null, drop] +item=Yommi tree seeds, id=736, option=[Look, null, null, null, drop] +item=Snakeweed mixture, id=737, option=[null, null, null, null, drop] +item=Ardrigal mixture, id=738, option=[null, null, null, null, drop] +item=Bravery potion, id=739, option=[Drink, null, null, null, drop] +item=Blue hat, id=740, option=[null, Wear, null, null, drop] +item=Chunk of crystal, id=741, option=[null, null, null, null, drop] +item=Hunk of crystal, id=742, option=[null, null, null, null, drop] +item=Lump of crystal, id=743, option=[null, null, null, null, drop] +item=Heart crystal, id=744, option=[Look-at, null, null, null, drop] +item=Heart crystal, id=745, option=[Look-at, null, null, null, drop] +item=Dark dagger, id=746, option=[null, Wield, null, null, drop] +item=Glowing dagger, id=747, option=[null, Wield, null, null, drop] +item=Holy force, id=748, option=[Cast Spell, null, null, null, drop] +item=Yommi totem, id=749, option=[null, null, null, null, drop] +item=Gilded totem, id=750, option=[Look-at, null, null, null, drop] +item=Gnomeball, id=751, option=[null, Hold, null, null, drop] +item=Gnomeball, id=752, option=[null, null, null, null, drop] +item=Cadava berries, id=753, option=[null, null, null, null, drop] +item=Cadava berries, id=754, option=[null, null, null, null, drop] +item=Message, id=755, option=[null, null, null, null, drop] +item=Cadava potion, id=756, option=[Look-at, Drink, null, null, drop] +item=Book, id=757, option=[Read, null, null, null, drop] +item=Phoenix hq key, id=758, option=[null, null, null, null, drop] +item=Weapon store key, id=759, option=[null, null, null, null, drop] +item=Weapon store key, id=760, option=[null, null, null, null, drop] +item=Intel report, id=761, option=[Read, null, null, null, Destroy] +item=Whoopsie, id=762, option=[Wear, null, null, null, drop] +item=Broken shield, id=763, option=[null, null, null, null, Destroy] +item=Whoopsie, id=764, option=[Wear, null, null, null, drop] +item=Broken shield, id=765, option=[null, null, null, null, Destroy] +item=Whoopsie, id=766, option=[Wear, null, null, null, drop] +item=Phoenix crossbow, id=767, option=[null, Wield, null, null, drop] +item=Phoenix crossbow, id=768, option=[null, null, null, null, drop] +item=Certificate, id=769, option=[Read, null, null, null, Destroy] +item=Whoopsie, id=770, option=[Wear, null, null, null, drop] +item=Dramen branch, id=771, option=[null, null, null, null, drop] +item=Dramen staff, id=772, option=[null, Wield, null, null, drop] +item='perfect' ring, id=773, option=[null, Wear, null, null, drop] +item='perfect' necklace, id=774, option=[null, Wear, null, null, drop] +item=Cooking gauntlets, id=775, option=[null, Wear, null, null, Destroy] +item=Goldsmith gauntlets, id=776, option=[null, Wear, null, null, Destroy] +item=Chaos gauntlets, id=777, option=[null, Wear, null, null, Destroy] +item=Family gauntlets, id=778, option=[null, Wear, null, null, Destroy] +item=Crest part, id=779, option=[null, null, null, null, drop] +item=Crest part, id=780, option=[null, null, null, null, drop] +item=Crest part, id=781, option=[null, null, null, null, drop] +item=Family crest, id=782, option=[null, null, null, null, drop] +item=Bark sample, id=783, option=[null, null, null, null, drop] +item=Translation book, id=784, option=[Read, null, null, null, drop] +item=Glough's journal, id=785, option=[Read, null, null, null, drop] +item=Hazelmere's scroll, id=786, option=[Read, null, null, null, drop] +item=Lumber order, id=787, option=[Read, null, null, null, drop] +item=Glough's key, id=788, option=[null, null, null, null, drop] +item=Twigs, id=789, option=[null, null, null, null, drop] +item=Twigs, id=790, option=[null, null, null, null, drop] +item=Twigs, id=791, option=[null, null, null, null, drop] +item=Twigs, id=792, option=[null, null, null, null, drop] +item=Daconia rock, id=793, option=[null, null, null, null, drop] +item=Invasion plans, id=794, option=[Read, null, null, null, drop] +item=War ship, id=795, option=[null, null, null, null, drop] +item=Exploding vial, id=796, option=[null, null, null, null, drop] +item=Herb bowl, id=797, option=[null, null, null, null, drop] +item=Grinder, id=798, option=[null, null, null, null, drop] +item=null, id=799, option=[null, null, null, null, drop] +item=Bronze thrownaxe, id=800, option=[null, Wield, null, null, drop] +item=Iron thrownaxe, id=801, option=[null, Wield, null, null, drop] +item=Steel thrownaxe, id=802, option=[null, Wield, null, null, drop] +item=Mithril thrownaxe, id=803, option=[null, Wield, null, null, drop] +item=Addy thrownaxe, id=804, option=[null, Wield, null, null, drop] +item=Rune thrownaxe, id=805, option=[null, Wield, null, null, drop] +item=Bronze dart, id=806, option=[null, Wield, null, null, drop] +item=Iron dart, id=807, option=[null, Wield, null, null, drop] +item=Steel dart, id=808, option=[null, Wield, null, null, drop] +item=Mithril dart, id=809, option=[null, Wield, null, null, drop] +item=Adamant dart, id=810, option=[null, Wield, null, null, drop] +item=Rune dart, id=811, option=[null, Wield, null, null, drop] +item=Bronze dart(p), id=812, option=[null, Wield, null, null, drop] +item=Iron dart(p), id=813, option=[null, Wield, null, null, drop] +item=Steel dart(p), id=814, option=[null, Wield, null, null, drop] +item=Mithril dart(p), id=815, option=[null, Wield, null, null, drop] +item=Adamant dart(p), id=816, option=[null, Wield, null, null, drop] +item=Rune dart(p), id=817, option=[null, Wield, null, null, drop] +item=Poisoned dart(p), id=818, option=[null, Wield, null, null, drop] +item=Bronze dart tip, id=819, option=[null, null, null, null, drop] +item=Iron dart tip, id=820, option=[null, null, null, null, drop] +item=Steel dart tip, id=821, option=[null, null, null, null, drop] +item=Mithril dart tip, id=822, option=[null, null, null, null, drop] +item=Adamant dart tip, id=823, option=[null, null, null, null, drop] +item=Rune dart tip, id=824, option=[null, null, null, null, drop] +item=Bronze javelin, id=825, option=[null, Wield, null, null, drop] +item=Iron javelin, id=826, option=[null, Wield, null, null, drop] +item=Steel javelin, id=827, option=[null, Wield, null, null, drop] +item=Mithril javelin, id=828, option=[null, Wield, null, null, drop] +item=Adamant javelin, id=829, option=[null, Wield, null, null, drop] +item=Rune javelin, id=830, option=[null, Wield, null, null, drop] +item=Bronze javelin(p), id=831, option=[null, Wield, null, null, drop] +item=Iron javelin(p), id=832, option=[null, Wield, null, null, drop] +item=Steel javelin(p), id=833, option=[null, Wield, null, null, drop] +item=Mithril javelin(p), id=834, option=[null, Wield, null, null, drop] +item=Adamant javelin(p), id=835, option=[null, Wield, null, null, drop] +item=Rune javelin(p), id=836, option=[null, Wield, null, null, drop] +item=Crossbow, id=837, option=[null, Wield, null, null, drop] +item=Crossbow, id=838, option=[null, null, null, null, drop] +item=Longbow, id=839, option=[null, Wield, null, null, drop] +item=Longbow, id=840, option=[null, null, null, null, drop] +item=Shortbow, id=841, option=[null, Wield, null, null, drop] +item=Shortbow, id=842, option=[null, null, null, null, drop] +item=Oak shortbow, id=843, option=[null, Wield, null, null, drop] +item=Oak shortbow, id=844, option=[null, null, null, null, drop] +item=Oak longbow, id=845, option=[null, Wield, null, null, drop] +item=Oak longbow, id=846, option=[null, null, null, null, drop] +item=Willow longbow, id=847, option=[null, Wield, null, null, drop] +item=Willow longbow, id=848, option=[null, null, null, null, drop] +item=Willow shortbow, id=849, option=[null, Wield, null, null, drop] +item=Willow shortbow, id=850, option=[null, null, null, null, drop] +item=Maple longbow, id=851, option=[null, Wield, null, null, drop] +item=Maple longbow, id=852, option=[null, null, null, null, drop] +item=Maple shortbow, id=853, option=[null, Wield, null, null, drop] +item=Maple shortbow, id=854, option=[null, null, null, null, drop] +item=Yew longbow, id=855, option=[null, Wield, null, null, drop] +item=Yew longbow, id=856, option=[null, null, null, null, drop] +item=Yew shortbow, id=857, option=[null, Wield, null, null, drop] +item=Yew shortbow, id=858, option=[null, null, null, null, drop] +item=Magic longbow, id=859, option=[null, Wield, null, null, drop] +item=Magic longbow, id=860, option=[null, null, null, null, drop] +item=Magic shortbow, id=861, option=[null, Wield, null, null, drop] +item=Magic shortbow, id=862, option=[null, null, null, null, drop] +item=Iron knife, id=863, option=[null, Wield, null, null, drop] +item=Bronze knife, id=864, option=[null, Wield, null, null, drop] +item=Steel knife, id=865, option=[null, Wield, null, null, drop] +item=Mithril knife, id=866, option=[null, Wield, null, null, drop] +item=Adamant knife, id=867, option=[null, Wield, null, null, drop] +item=Rune knife, id=868, option=[null, Wield, null, null, drop] +item=Black knife, id=869, option=[null, Wield, null, null, drop] +item=Bronze knife(p), id=870, option=[null, Wield, null, null, drop] +item=Iron knife(p), id=871, option=[null, Wield, null, null, drop] +item=Steel knife(p), id=872, option=[null, Wield, null, null, drop] +item=Mithril knife(p), id=873, option=[null, Wield, null, null, drop] +item=Black knife(p), id=874, option=[null, Wield, null, null, drop] +item=Adamant knife(p), id=875, option=[null, Wield, null, null, drop] +item=Rune knife(p), id=876, option=[null, Wield, null, null, drop] +item=Bronze bolts, id=877, option=[null, Wield, null, null, drop] +item=Bronze bolts(p), id=878, option=[null, Wield, null, null, drop] +item=Opal bolts, id=879, option=[null, Wield, null, null, drop] +item=Pearl bolts, id=880, option=[null, Wield, null, null, drop] +item=Barbed bolts, id=881, option=[null, Wield, null, null, drop] +item=Bronze arrow, id=882, option=[null, Wield, null, null, drop] +item=Bronze arrow(p), id=883, option=[null, Wield, null, null, drop] +item=Iron arrow, id=884, option=[null, Wield, null, null, drop] +item=Iron arrow(p), id=885, option=[null, Wield, null, null, drop] +item=Steel arrow, id=886, option=[null, Wield, null, null, drop] +item=Steel arrow(p), id=887, option=[null, Wield, null, null, drop] +item=Mithril arrow, id=888, option=[null, Wield, null, null, drop] +item=Mithril arrow(p), id=889, option=[null, Wield, null, null, drop] +item=Adamant arrow, id=890, option=[null, Wield, null, null, drop] +item=Adamant arrow(p), id=891, option=[null, Wield, null, null, drop] +item=Rune arrow, id=892, option=[null, Wield, null, null, drop] +item=Rune arrow(p), id=893, option=[null, Wield, null, null, drop] +item=null, id=894, option=[null, null, null, null, drop] +item=null, id=895, option=[null, null, null, null, drop] +item=null, id=896, option=[null, null, null, null, drop] +item=null, id=897, option=[null, null, null, null, drop] +item=null, id=898, option=[null, null, null, null, drop] +item=null, id=899, option=[null, null, null, null, drop] +item=null, id=900, option=[null, null, null, null, drop] +item=null, id=901, option=[null, null, null, null, drop] +item=null, id=902, option=[null, null, null, null, drop] +item=null, id=903, option=[null, null, null, null, drop] +item=null, id=904, option=[null, null, null, null, drop] +item=null, id=905, option=[null, null, null, null, drop] +item=null, id=906, option=[null, null, null, null, drop] +item=null, id=907, option=[null, null, null, null, drop] +item=null, id=908, option=[null, null, null, null, drop] +item=null, id=909, option=[null, null, null, null, drop] +item=null, id=910, option=[null, null, null, null, drop] +item=null, id=911, option=[null, null, null, null, drop] +item=null, id=912, option=[null, null, null, null, drop] +item=null, id=913, option=[null, null, null, null, drop] +item=null, id=914, option=[null, null, null, null, drop] +item=null, id=915, option=[null, null, null, null, drop] +item=null, id=916, option=[null, null, null, null, drop] +item=null, id=917, option=[null, null, null, null, drop] +item=null, id=918, option=[null, null, null, null, drop] +item=null, id=919, option=[null, null, null, null, drop] +item=null, id=920, option=[null, null, null, null, drop] +item=null, id=921, option=[null, null, null, null, drop] +item=null, id=922, option=[null, null, null, null, drop] +item=null, id=923, option=[null, null, null, null, drop] +item=null, id=924, option=[null, null, null, null, drop] +item=null, id=925, option=[null, null, null, null, drop] +item=null, id=926, option=[null, null, null, null, drop] +item=null, id=927, option=[null, null, null, null, drop] +item=null, id=928, option=[null, null, null, null, drop] +item=null, id=929, option=[null, null, null, null, drop] +item=null, id=930, option=[null, null, null, null, drop] +item=null, id=931, option=[null, null, null, null, drop] +item=null, id=932, option=[null, null, null, null, drop] +item=null, id=933, option=[null, null, null, null, drop] +item=null, id=934, option=[null, null, null, null, drop] +item=null, id=935, option=[null, null, null, null, drop] +item=null, id=936, option=[null, null, null, null, drop] +item=null, id=937, option=[null, null, null, null, drop] +item=null, id=938, option=[null, null, null, null, drop] +item=null, id=939, option=[null, null, null, null, drop] +item=null, id=940, option=[null, null, null, null, drop] +item=null, id=941, option=[null, null, null, null, drop] +item=Bronze fire arrows, id=942, option=[null, Wield, null, null, drop] +item=Worm, id=943, option=[null, null, null, null, drop] +item=Worm, id=944, option=[null, null, null, null, drop] +item=Throwing rope, id=945, option=[null, null, null, null, drop] +item=Knife, id=946, option=[null, null, null, null, drop] +item=Knife, id=947, option=[null, null, null, null, drop] +item=Bear fur, id=948, option=[null, null, null, null, drop] +item=Bear fur, id=949, option=[null, null, null, null, drop] +item=Silk, id=950, option=[null, null, null, null, drop] +item=Silk, id=951, option=[null, null, null, null, drop] +item=Spade, id=952, option=[Dig, null, null, null, drop] +item=Spade, id=953, option=[null, null, null, null, drop] +item=Rope, id=954, option=[null, null, null, null, drop] +item=Rope, id=955, option=[null, null, null, null, drop] +item=Flier, id=956, option=[null, null, null, null, drop] +item=Whoopsie, id=957, option=[null, null, null, null, drop] +item=Grey wolf fur, id=958, option=[null, null, null, null, drop] +item=Grey wolf fur, id=959, option=[null, null, null, null, drop] +item=Plank, id=960, option=[null, null, null, null, drop] +item=Plank, id=961, option=[null, null, null, null, drop] +item=Christmas cracker, id=962, option=[null, null, null, null, drop] +item=Christmas cracker, id=963, option=[null, null, null, null, drop] +item=Skull, id=964, option=[null, null, null, null, drop] +item=Skull, id=965, option=[null, null, null, null, drop] +item=Tile, id=966, option=[null, null, null, null, drop] +item=Whoopsie, id=967, option=[null, null, null, null, drop] +item=Rock, id=968, option=[null, null, null, null, drop] +item=Whoopsie, id=969, option=[null, null, null, null, drop] +item=Papyrus, id=970, option=[null, null, null, null, drop] +item=Papyrus, id=971, option=[null, null, null, null, drop] +item=Papyrus, id=972, option=[null, null, null, null, drop] +item=Charcoal, id=973, option=[null, null, null, null, drop] +item=Charcoal, id=974, option=[null, null, null, null, drop] +item=Machete, id=975, option=[null, Wield, null, null, drop] +item=Machete, id=976, option=[null, null, null, null, drop] +item=Cooking pot, id=977, option=[null, null, null, null, drop] +item=Cooking pot, id=978, option=[null, null, null, null, drop] +item=null, id=979, option=[null, null, null, null, drop] +item=Whoopsie, id=980, option=[Wear, null, null, null, drop] +item=Disk of returning, id=981, option=[null, null, null, null, drop] +item=Disk of returning, id=982, option=[null, null, null, null, drop] +item=Brass key, id=983, option=[null, null, null, null, drop] +item=Brass key, id=984, option=[null, null, null, null, drop] +item=Tooth half of a key, id=985, option=[null, null, null, null, drop] +item=Tooth half of a key, id=986, option=[null, null, null, null, drop] +item=Loop half of a key, id=987, option=[null, null, null, null, drop] +item=Loop half of a key, id=988, option=[null, null, null, null, drop] +item=Crystal key, id=989, option=[null, null, null, null, drop] +item=Crystal key, id=990, option=[null, null, null, null, drop] +item=Muddy key, id=991, option=[null, null, null, null, drop] +item=Muddy key, id=992, option=[null, null, null, null, drop] +item=Sinister key, id=993, option=[null, null, null, null, drop] +item=Sinister key, id=994, option=[null, null, null, null, drop] +item=Coins, id=995, option=[null, null, null, null, drop] +item=null, id=996, option=[null, null, null, null, drop] +item=null, id=997, option=[null, null, null, null, drop] +item=null, id=998, option=[null, null, null, null, drop] +item=null, id=999, option=[null, null, null, null, drop] +item=null, id=1000, option=[null, null, null, null, drop] +item=null, id=1001, option=[null, null, null, null, drop] +item=null, id=1002, option=[null, null, null, null, drop] +item=null, id=1003, option=[null, null, null, null, drop] +item=null, id=1004, option=[null, null, null, null, drop] +item=White apron, id=1005, option=[null, Wear, null, null, drop] +item=White apron, id=1006, option=[null, null, null, null, drop] +item=Cape, id=1007, option=[null, Wear, null, null, drop] +item=Cape, id=1008, option=[null, null, null, null, drop] +item=Brass necklace, id=1009, option=[null, Wear, null, null, drop] +item=Brass necklace, id=1010, option=[null, null, null, null, drop] +item=Blue skirt, id=1011, option=[null, Wear, null, null, drop] +item=Blue skirt, id=1012, option=[null, null, null, null, drop] +item=Pink skirt, id=1013, option=[null, Wear, null, null, drop] +item=Pink skirt, id=1014, option=[null, null, null, null, drop] +item=Black skirt, id=1015, option=[null, Wear, null, null, drop] +item=Black skirt, id=1016, option=[null, null, null, null, drop] +item=Wizard hat, id=1017, option=[null, Wear, null, null, drop] +item=Wizard hat, id=1018, option=[null, null, null, null, drop] +item=Cape, id=1019, option=[null, Wear, null, null, drop] +item=Cape, id=1020, option=[null, null, null, null, drop] +item=Cape, id=1021, option=[null, Wear, null, null, drop] +item=Cape, id=1022, option=[null, null, null, null, drop] +item=Cape, id=1023, option=[null, Wear, null, null, drop] +item=Cape, id=1024, option=[null, null, null, null, drop] +item=Eye patch, id=1025, option=[null, Wear, null, null, drop] +item=Eye patch, id=1026, option=[null, null, null, null, drop] +item=Cape, id=1027, option=[null, Wear, null, null, drop] +item=Cape, id=1028, option=[null, null, null, null, drop] +item=Cape, id=1029, option=[null, Wear, null, null, drop] +item=Cape, id=1030, option=[null, null, null, null, drop] +item=Cape, id=1031, option=[null, Wear, null, null, drop] +item=Cape, id=1032, option=[null, null, null, null, drop] +item=Zamorak robe, id=1033, option=[null, Wear, null, null, drop] +item=Zamorak robe, id=1034, option=[null, null, null, null, drop] +item=Zamorak robe, id=1035, option=[null, Wear, null, null, drop] +item=Zamorak robe, id=1036, option=[null, null, null, null, drop] +item=Bunny ears, id=1037, option=[null, Wear, null, null, drop] +item=Red partyhat, id=1038, option=[null, Wear, null, null, drop] +item=Red partyhat, id=1039, option=[null, null, null, null, drop] +item=Yellow partyhat, id=1040, option=[null, Wear, null, null, drop] +item=Yellow partyhat, id=1041, option=[null, null, null, null, drop] +item=Blue partyhat, id=1042, option=[null, Wear, null, null, drop] +item=Blue partyhat, id=1043, option=[null, null, null, null, drop] +item=Green partyhat, id=1044, option=[null, Wear, null, null, drop] +item=Green partyhat, id=1045, option=[null, null, null, null, drop] +item=Purple partyhat, id=1046, option=[null, Wear, null, null, drop] +item=Purple partyhat, id=1047, option=[null, null, null, null, drop] +item=White partyhat, id=1048, option=[null, Wear, null, null, drop] +item=White partyhat, id=1049, option=[null, null, null, null, drop] +item=Santa hat, id=1050, option=[null, Wear, null, null, drop] +item=Santa hat, id=1051, option=[null, null, null, null, drop] +item=Cape of legends, id=1052, option=[null, Wear, null, null, drop] +item=Green h'ween mask, id=1053, option=[null, Wear, null, null, drop] +item=Green h'ween mask, id=1054, option=[null, null, null, null, drop] +item=Blue h'ween mask, id=1055, option=[null, Wear, null, null, drop] +item=Blue h'ween mask, id=1056, option=[null, null, null, null, drop] +item=Red h'ween mask, id=1057, option=[null, Wear, null, null, drop] +item=Red h'ween mask, id=1058, option=[null, null, null, null, drop] +item=Leather gloves, id=1059, option=[null, Wear, null, null, drop] +item=Leather gloves, id=1060, option=[null, null, null, null, drop] +item=Leather boots, id=1061, option=[null, Wear, null, null, drop] +item=Leather boots, id=1062, option=[null, null, null, null, drop] +item=Leather vambraces, id=1063, option=[null, Wear, null, null, drop] +item=Leather vambraces, id=1064, option=[null, null, null, null, drop] +item=Green d'hide vamb, id=1065, option=[null, Wear, null, null, drop] +item=Green d'hide vamb, id=1066, option=[null, null, null, null, drop] +item=Iron platelegs, id=1067, option=[null, Wear, null, null, drop] +item=Iron platelegs, id=1068, option=[null, null, null, null, drop] +item=Steel platelegs, id=1069, option=[null, Wear, null, null, drop] +item=Steel platelegs, id=1070, option=[null, null, null, null, drop] +item=Mithril platelegs, id=1071, option=[null, Wear, null, null, drop] +item=Mithril platelegs, id=1072, option=[null, null, null, null, drop] +item=Adamant platelegs, id=1073, option=[null, Wear, null, null, drop] +item=Adamant platelegs, id=1074, option=[null, null, null, null, drop] +item=Bronze platelegs, id=1075, option=[null, Wear, null, null, drop] +item=Bronze platelegs, id=1076, option=[null, null, null, null, drop] +item=Black platelegs, id=1077, option=[null, Wear, null, null, drop] +item=Black platelegs, id=1078, option=[null, null, null, null, drop] +item=Rune platelegs, id=1079, option=[null, Wear, null, null, drop] +item=Rune platelegs, id=1080, option=[null, null, null, null, drop] +item=Iron plateskirt, id=1081, option=[null, Wear, null, null, drop] +item=Iron plateskirt, id=1082, option=[null, null, null, null, drop] +item=Steel plateskirt, id=1083, option=[null, Wear, null, null, drop] +item=Steel plateskirt, id=1084, option=[null, null, null, null, drop] +item=Mithril plateskirt, id=1085, option=[null, Wear, null, null, drop] +item=Mithril plateskirt, id=1086, option=[null, null, null, null, drop] +item=Bronze plateskirt, id=1087, option=[null, Wear, null, null, drop] +item=Bronze plateskirt, id=1088, option=[null, null, null, null, drop] +item=Black plateskirt, id=1089, option=[null, Wear, null, null, drop] +item=Black plateskirt, id=1090, option=[null, null, null, null, drop] +item=Adamant plateskirt, id=1091, option=[null, Wear, null, null, drop] +item=Adamant plateskirt, id=1092, option=[null, null, null, null, drop] +item=Rune plateskirt, id=1093, option=[null, Wear, null, null, drop] +item=Rune plateskirt, id=1094, option=[null, null, null, null, drop] +item=Leather chaps, id=1095, option=[null, Wear, null, null, drop] +item=Leather chaps, id=1096, option=[null, null, null, null, drop] +item=Studded chaps, id=1097, option=[null, Wear, null, null, drop] +item=Studded chaps, id=1098, option=[null, null, null, null, drop] +item=Green d'hide chaps, id=1099, option=[null, Wear, null, null, drop] +item=Green d'hide chaps, id=1100, option=[null, null, null, null, drop] +item=Iron chainbody, id=1101, option=[null, Wear, null, null, drop] +item=Iron chainbody, id=1102, option=[null, null, null, null, drop] +item=Bronze chainbody, id=1103, option=[null, Wear, null, null, drop] +item=Bronze chainbody, id=1104, option=[null, null, null, null, drop] +item=Steel chainbody, id=1105, option=[null, Wear, null, null, drop] +item=Steel chainbody, id=1106, option=[null, null, null, null, drop] +item=Black chainbody, id=1107, option=[null, Wear, null, null, drop] +item=Black chainbody, id=1108, option=[null, null, null, null, drop] +item=Mithril chainbody, id=1109, option=[null, Wear, null, null, drop] +item=Mithril chainbody, id=1110, option=[null, null, null, null, drop] +item=Adamant chainbody, id=1111, option=[null, Wear, null, null, drop] +item=Adamant chainbody, id=1112, option=[null, null, null, null, drop] +item=Rune chainbody, id=1113, option=[null, Wear, null, null, drop] +item=Rune chainbody, id=1114, option=[null, null, null, null, drop] +item=Iron platebody, id=1115, option=[null, Wear, null, null, drop] +item=Iron platebody, id=1116, option=[null, null, null, null, drop] +item=Bronze platebody, id=1117, option=[null, Wear, null, null, drop] +item=Bronze platebody, id=1118, option=[null, null, null, null, drop] +item=Steel platebody, id=1119, option=[null, Wear, null, null, drop] +item=Steel platebody, id=1120, option=[null, null, null, null, drop] +item=Mithril platebody, id=1121, option=[null, Wear, null, null, drop] +item=Mithril platebody, id=1122, option=[null, null, null, null, drop] +item=Adamant platebody, id=1123, option=[null, Wear, null, null, drop] +item=Adamant platebody, id=1124, option=[null, null, null, null, drop] +item=Black platebody, id=1125, option=[null, Wear, null, null, drop] +item=Black platebody, id=1126, option=[null, null, null, null, drop] +item=Rune platebody, id=1127, option=[null, Wear, null, null, drop] +item=Rune platebody, id=1128, option=[null, null, null, null, drop] +item=Leather body, id=1129, option=[null, Wear, null, null, drop] +item=Leather body, id=1130, option=[null, null, null, null, drop] +item=Hardleather body, id=1131, option=[null, Wear, null, null, drop] +item=Hardleather body, id=1132, option=[null, null, null, null, drop] +item=Studded body, id=1133, option=[null, Wear, null, null, drop] +item=Studded body, id=1134, option=[null, null, null, null, drop] +item=Green d'hide body, id=1135, option=[null, Wear, null, null, drop] +item=Green d'hide body, id=1136, option=[null, null, null, null, drop] +item=Iron med helm, id=1137, option=[null, Wear, null, null, drop] +item=Iron med helm, id=1138, option=[null, null, null, null, drop] +item=Bronze med helm, id=1139, option=[null, Wear, null, null, drop] +item=Bronze med helm, id=1140, option=[null, null, null, null, drop] +item=Steel med helm, id=1141, option=[null, Wear, null, null, drop] +item=Steel med helm, id=1142, option=[null, null, null, null, drop] +item=Mithril med helm, id=1143, option=[null, Wear, null, null, drop] +item=Mithril med helm, id=1144, option=[null, null, null, null, drop] +item=Adamant med helm, id=1145, option=[null, Wear, null, null, drop] +item=Adamant med helm, id=1146, option=[null, null, null, null, drop] +item=Rune med helm, id=1147, option=[null, Wear, null, null, drop] +item=Rune med helm, id=1148, option=[null, null, null, null, drop] +item=Dragon med helm, id=1149, option=[null, Wear, null, null, drop] +item=Dragon med helm, id=1150, option=[null, null, null, null, drop] +item=Black med helm, id=1151, option=[null, Wear, null, null, drop] +item=Black med helm, id=1152, option=[null, null, null, null, drop] +item=Iron full helm, id=1153, option=[null, Wear, null, null, drop] +item=Iron full helm, id=1154, option=[null, null, null, null, drop] +item=Bronze full helm, id=1155, option=[null, Wear, null, null, drop] +item=Bronze full helm, id=1156, option=[null, null, null, null, drop] +item=Steel full helm, id=1157, option=[null, Wear, null, null, drop] +item=Steel full helm, id=1158, option=[null, null, null, null, drop] +item=Mithril full helm, id=1159, option=[null, Wear, null, null, drop] +item=Mithril full helm, id=1160, option=[null, null, null, null, drop] +item=Adamant full helm, id=1161, option=[null, Wear, null, null, drop] +item=Adamant full helm, id=1162, option=[null, null, null, null, drop] +item=Rune full helm, id=1163, option=[null, Wear, null, null, drop] +item=Rune full helm, id=1164, option=[null, null, null, null, drop] +item=Black full helm, id=1165, option=[null, Wear, null, null, drop] +item=Black full helm, id=1166, option=[null, null, null, null, drop] +item=Leather cowl, id=1167, option=[null, Wear, null, null, drop] +item=Leather cowl, id=1168, option=[null, null, null, null, drop] +item=Coif, id=1169, option=[null, Wear, null, null, drop] +item=Coif, id=1170, option=[null, null, null, null, drop] +item=Wooden shield, id=1171, option=[null, Wield, null, null, drop] +item=Wooden shield, id=1172, option=[null, null, null, null, drop] +item=Bronze sq shield, id=1173, option=[null, Wield, null, null, drop] +item=Bronze sq shield, id=1174, option=[null, null, null, null, drop] +item=Iron sq shield, id=1175, option=[null, Wield, null, null, drop] +item=Iron sq shield, id=1176, option=[null, null, null, null, drop] +item=Steel sq shield, id=1177, option=[null, Wield, null, null, drop] +item=Steel sq shield, id=1178, option=[null, null, null, null, drop] +item=Black sq shield, id=1179, option=[null, Wield, null, null, drop] +item=Black sq shield, id=1180, option=[null, null, null, null, drop] +item=Mithril sq shield, id=1181, option=[null, Wield, null, null, drop] +item=Mithril sq shield, id=1182, option=[null, null, null, null, drop] +item=Adamant sq shield, id=1183, option=[null, Wield, null, null, drop] +item=Adamant sq shield, id=1184, option=[null, null, null, null, drop] +item=Rune sq shield, id=1185, option=[null, Wield, null, null, drop] +item=Rune sq shield, id=1186, option=[null, null, null, null, drop] +item=Dragon sq shield, id=1187, option=[null, Wield, null, null, drop] +item=Dragon sq shield, id=1188, option=[null, null, null, null, drop] +item=Bronze kiteshield, id=1189, option=[null, Wear, null, null, drop] +item=Bronze kiteshield, id=1190, option=[null, null, null, null, drop] +item=Iron kiteshield, id=1191, option=[null, Wear, null, null, drop] +item=Iron kiteshield, id=1192, option=[null, null, null, null, drop] +item=Steel kiteshield, id=1193, option=[null, Wear, null, null, drop] +item=Steel kiteshield, id=1194, option=[null, null, null, null, drop] +item=Black kiteshield, id=1195, option=[null, Wear, null, null, drop] +item=Black kiteshield, id=1196, option=[null, null, null, null, drop] +item=Mithril kiteshield, id=1197, option=[null, Wear, null, null, drop] +item=Mithril kiteshield, id=1198, option=[null, null, null, null, drop] +item=Adamant kiteshield, id=1199, option=[null, Wear, null, null, drop] +item=Adamant kiteshield, id=1200, option=[null, null, null, null, drop] +item=Rune kiteshield, id=1201, option=[null, Wear, null, null, drop] +item=Rune kiteshield, id=1202, option=[null, null, null, null, drop] +item=Iron dagger, id=1203, option=[null, Wield, null, null, drop] +item=Iron dagger, id=1204, option=[null, null, null, null, drop] +item=Bronze dagger, id=1205, option=[null, Wield, null, null, drop] +item=Bronze dagger, id=1206, option=[null, null, null, null, drop] +item=Steel dagger, id=1207, option=[null, Wield, null, null, drop] +item=Steel dagger, id=1208, option=[null, null, null, null, drop] +item=Mithril dagger, id=1209, option=[null, Wield, null, null, drop] +item=Mithril dagger, id=1210, option=[null, null, null, null, drop] +item=Adamant dagger, id=1211, option=[null, Wield, null, null, drop] +item=Adamant dagger, id=1212, option=[null, null, null, null, drop] +item=Rune dagger, id=1213, option=[null, Wield, null, null, drop] +item=Rune dagger, id=1214, option=[null, null, null, null, drop] +item=Dragon dagger, id=1215, option=[null, Wield, null, null, drop] +item=Dragon dagger, id=1216, option=[null, null, null, null, drop] +item=Black dagger, id=1217, option=[null, Wield, null, null, drop] +item=Black dagger, id=1218, option=[null, null, null, null, drop] +item=Iron dagger(p), id=1219, option=[null, Wield, null, null, drop] +item=Iron dagger(p), id=1220, option=[null, null, null, null, drop] +item=Bronze dagger(p), id=1221, option=[null, Wield, null, null, drop] +item=Bronze dagger(p), id=1222, option=[null, null, null, null, drop] +item=Steel dagger(p), id=1223, option=[null, Wield, null, null, drop] +item=Steel dagger(p), id=1224, option=[null, null, null, null, drop] +item=Mithril dagger(p), id=1225, option=[null, Wield, null, null, drop] +item=Mithril dagger(p), id=1226, option=[null, null, null, null, drop] +item=Adamant dagger(p), id=1227, option=[null, Wield, null, null, drop] +item=Adamant dagger(p), id=1228, option=[null, null, null, null, drop] +item=Rune dagger(p), id=1229, option=[null, Wield, null, null, drop] +item=Rune dagger(p), id=1230, option=[null, null, null, null, drop] +item=Dragon dagger(p), id=1231, option=[null, Wield, null, null, drop] +item=Dragon dagger(p), id=1232, option=[null, null, null, null, drop] +item=Black dagger(p), id=1233, option=[null, Wield, null, null, drop] +item=Black dagger(p), id=1234, option=[null, null, null, null, drop] +item=Poisoned dagger(p), id=1235, option=[null, Wield, null, null, drop] +item=Poisoned dagger(p), id=1236, option=[null, null, null, null, drop] +item=Bronze spear, id=1237, option=[null, Wield, null, null, drop] +item=Bronze spear, id=1238, option=[null, null, null, null, drop] +item=Iron spear, id=1239, option=[null, Wield, null, null, drop] +item=Iron spear, id=1240, option=[null, null, null, null, drop] +item=Steel spear, id=1241, option=[null, Wield, null, null, drop] +item=Steel spear, id=1242, option=[null, null, null, null, drop] +item=Mithril spear, id=1243, option=[null, Wield, null, null, drop] +item=Mithril spear, id=1244, option=[null, null, null, null, drop] +item=Adamant spear, id=1245, option=[null, Wield, null, null, drop] +item=Adamant spear, id=1246, option=[null, null, null, null, drop] +item=Rune spear, id=1247, option=[null, Wield, null, null, drop] +item=Rune spear, id=1248, option=[null, null, null, null, drop] +item=Dragon spear, id=1249, option=[null, Wield, null, null, drop] +item=Dragon spear, id=1250, option=[null, null, null, null, drop] +item=Bronze spear(p), id=1251, option=[null, Wield, null, null, drop] +item=Bronze spear(p), id=1252, option=[null, null, null, null, drop] +item=Iron spear(p), id=1253, option=[null, Wield, null, null, drop] +item=Iron spear(p), id=1254, option=[null, null, null, null, drop] +item=Steel spear(p), id=1255, option=[null, Wield, null, null, drop] +item=Steel spear(p), id=1256, option=[null, null, null, null, drop] +item=Mithril spear(p), id=1257, option=[null, Wield, null, null, drop] +item=Mithril spear(p), id=1258, option=[null, null, null, null, drop] +item=Adamant spear(p), id=1259, option=[null, Wield, null, null, drop] +item=Adamant spear(p), id=1260, option=[null, null, null, null, drop] +item=Rune spear(p), id=1261, option=[null, Wield, null, null, drop] +item=Rune spear(p), id=1262, option=[null, null, null, null, drop] +item=Dragon spear(p), id=1263, option=[null, Wield, null, null, drop] +item=Dragon spear(p), id=1264, option=[null, null, null, null, drop] +item=Bronze pickaxe, id=1265, option=[null, Wield, null, null, drop] +item=Bronze pickaxe, id=1266, option=[null, null, null, null, drop] +item=Iron pickaxe, id=1267, option=[null, Wield, null, null, drop] +item=Iron pickaxe, id=1268, option=[null, null, null, null, drop] +item=Steel pickaxe, id=1269, option=[null, Wield, null, null, drop] +item=Steel pickaxe, id=1270, option=[null, null, null, null, drop] +item=Adamant pickaxe, id=1271, option=[null, Wield, null, null, drop] +item=Adamant pickaxe, id=1272, option=[null, null, null, null, drop] +item=Mithril pickaxe, id=1273, option=[null, Wield, null, null, drop] +item=Mithril pickaxe, id=1274, option=[null, null, null, null, drop] +item=Rune pickaxe, id=1275, option=[null, Wield, null, null, drop] +item=Rune pickaxe, id=1276, option=[null, null, null, null, drop] +item=Bronze sword, id=1277, option=[null, Wield, null, null, drop] +item=Bronze sword, id=1278, option=[null, null, null, null, drop] +item=Iron sword, id=1279, option=[null, Wield, null, null, drop] +item=Iron sword, id=1280, option=[null, null, null, null, drop] +item=Steel sword, id=1281, option=[null, Wield, null, null, drop] +item=Steel sword, id=1282, option=[null, null, null, null, drop] +item=Black sword, id=1283, option=[null, Wield, null, null, drop] +item=Black sword, id=1284, option=[null, null, null, null, drop] +item=Mithril sword, id=1285, option=[null, Wield, null, null, drop] +item=Mithril sword, id=1286, option=[null, null, null, null, drop] +item=Adamant sword, id=1287, option=[null, Wield, null, null, drop] +item=Adamant sword, id=1288, option=[null, null, null, null, drop] +item=Rune sword, id=1289, option=[null, Wield, null, null, drop] +item=Rune sword, id=1290, option=[null, null, null, null, drop] +item=Bronze longsword, id=1291, option=[null, Wield, null, null, drop] +item=Bronze longsword, id=1292, option=[null, null, null, null, drop] +item=Iron longsword, id=1293, option=[null, Wield, null, null, drop] +item=Iron longsword, id=1294, option=[null, null, null, null, drop] +item=Steel longsword, id=1295, option=[null, Wield, null, null, drop] +item=Steel longsword, id=1296, option=[null, null, null, null, drop] +item=Black longsword, id=1297, option=[null, Wield, null, null, drop] +item=Black longsword, id=1298, option=[null, null, null, null, drop] +item=Mithril longsword, id=1299, option=[null, Wield, null, null, drop] +item=Mithril longsword, id=1300, option=[null, null, null, null, drop] +item=Adamant longsword, id=1301, option=[null, Wield, null, null, drop] +item=Adamant longsword, id=1302, option=[null, null, null, null, drop] +item=Rune longsword, id=1303, option=[null, Wield, null, null, drop] +item=Rune longsword, id=1304, option=[null, null, null, null, drop] +item=Dragon longsword, id=1305, option=[null, Wield, null, null, drop] +item=Dragon longsword, id=1306, option=[null, null, null, null, drop] +item=Bronze 2h sword, id=1307, option=[null, Wield, null, null, drop] +item=Bronze 2h sword, id=1308, option=[null, null, null, null, drop] +item=Iron 2h sword, id=1309, option=[null, Wield, null, null, drop] +item=Iron 2h sword, id=1310, option=[null, null, null, null, drop] +item=Steel 2h sword, id=1311, option=[null, Wield, null, null, drop] +item=Steel 2h sword, id=1312, option=[null, null, null, null, drop] +item=Black 2h sword, id=1313, option=[null, Wield, null, null, drop] +item=Black 2h sword, id=1314, option=[null, null, null, null, drop] +item=Mithril 2h sword, id=1315, option=[null, Wield, null, null, drop] +item=Mithril 2h sword, id=1316, option=[null, null, null, null, drop] +item=Adamant 2h sword, id=1317, option=[null, Wield, null, null, drop] +item=Adamant 2h sword, id=1318, option=[null, null, null, null, drop] +item=Rune 2h sword, id=1319, option=[null, Wield, null, null, drop] +item=Rune 2h sword, id=1320, option=[null, null, null, null, drop] +item=Bronze scimitar, id=1321, option=[null, Wield, null, null, drop] +item=Bronze scimitar, id=1322, option=[null, null, null, null, drop] +item=Iron scimitar, id=1323, option=[null, Wield, null, null, drop] +item=Iron scimitar, id=1324, option=[null, null, null, null, drop] +item=Steel scimitar, id=1325, option=[null, Wield, null, null, drop] +item=Steel scimitar, id=1326, option=[null, null, null, null, drop] +item=Black scimitar, id=1327, option=[null, Wield, null, null, drop] +item=Black scimitar, id=1328, option=[null, null, null, null, drop] +item=Mithril scimitar, id=1329, option=[null, Wield, null, null, drop] +item=Mithril scimitar, id=1330, option=[null, null, null, null, drop] +item=Adamant scimitar, id=1331, option=[null, Wield, null, null, drop] +item=Adamant scimitar, id=1332, option=[null, null, null, null, drop] +item=Rune scimitar, id=1333, option=[null, Wield, null, null, drop] +item=Rune scimitar, id=1334, option=[null, null, null, null, drop] +item=Iron warhammer, id=1335, option=[null, Wield, null, null, drop] +item=Iron warhammer, id=1336, option=[null, null, null, null, drop] +item=Bronze warhammer, id=1337, option=[null, Wield, null, null, drop] +item=Bronze warhammer, id=1338, option=[null, null, null, null, drop] +item=Steel warhammer, id=1339, option=[null, Wield, null, null, drop] +item=Steel warhammer, id=1340, option=[null, null, null, null, drop] +item=Black warhammer, id=1341, option=[null, Wield, null, null, drop] +item=Black warhammer, id=1342, option=[null, null, null, null, drop] +item=Mithril warhammer, id=1343, option=[null, Wield, null, null, drop] +item=Mithril warhammer, id=1344, option=[null, null, null, null, drop] +item=Addy warhammer, id=1345, option=[null, Wield, null, null, drop] +item=Addy warhammer, id=1346, option=[null, null, null, null, drop] +item=Rune warhammer, id=1347, option=[null, Wield, null, null, drop] +item=Rune warhammer, id=1348, option=[null, null, null, null, drop] +item=Iron axe, id=1349, option=[null, Wield, null, null, drop] +item=Iron axe, id=1350, option=[null, null, null, null, drop] +item=Bronze axe, id=1351, option=[null, Wield, null, null, drop] +item=Bronze axe, id=1352, option=[null, null, null, null, drop] +item=Steel axe, id=1353, option=[null, Wield, null, null, drop] +item=Steel axe, id=1354, option=[null, null, null, null, drop] +item=Mithril axe, id=1355, option=[null, Wield, null, null, drop] +item=Mithril axe, id=1356, option=[null, null, null, null, drop] +item=Adamant axe, id=1357, option=[null, Wield, null, null, drop] +item=Adamant axe, id=1358, option=[null, null, null, null, drop] +item=Rune axe, id=1359, option=[null, Wield, null, null, drop] +item=Rune axe, id=1360, option=[null, null, null, null, drop] +item=Black axe, id=1361, option=[null, Wield, null, null, drop] +item=Black axe, id=1362, option=[null, null, null, null, drop] +item=Iron battleaxe, id=1363, option=[null, Wield, null, null, drop] +item=Iron battleaxe, id=1364, option=[null, null, null, null, drop] +item=Steel battleaxe, id=1365, option=[null, Wield, null, null, drop] +item=Steel battleaxe, id=1366, option=[null, null, null, null, drop] +item=Black battleaxe, id=1367, option=[null, Wield, null, null, drop] +item=Black battleaxe, id=1368, option=[null, null, null, null, drop] +item=Mithril battleaxe, id=1369, option=[null, Wield, null, null, drop] +item=Mithril battleaxe, id=1370, option=[null, null, null, null, drop] +item=Adamant battleaxe, id=1371, option=[null, Wield, null, null, drop] +item=Adamant battleaxe, id=1372, option=[null, null, null, null, drop] +item=Rune battleaxe, id=1373, option=[null, Wield, null, null, drop] +item=Rune battleaxe, id=1374, option=[null, null, null, null, drop] +item=Bronze battleaxe, id=1375, option=[null, Wield, null, null, drop] +item=Bronze battleaxe, id=1376, option=[null, null, null, null, drop] +item=Dragon battleaxe, id=1377, option=[null, Wield, null, null, drop] +item=Dragon battleaxe, id=1378, option=[null, null, null, null, drop] +item=Staff, id=1379, option=[null, Wield, null, null, drop] +item=Staff, id=1380, option=[null, null, null, null, drop] +item=Staff of air, id=1381, option=[null, Wield, null, null, drop] +item=Staff of air, id=1382, option=[null, null, null, null, drop] +item=Staff of water, id=1383, option=[null, Wield, null, null, drop] +item=Staff of water, id=1384, option=[null, null, null, null, drop] +item=Staff of earth, id=1385, option=[null, Wield, null, null, drop] +item=Staff of earth, id=1386, option=[null, null, null, null, drop] +item=Staff of fire, id=1387, option=[null, Wield, null, null, drop] +item=Staff of fire, id=1388, option=[null, null, null, null, drop] +item=Magic staff, id=1389, option=[null, Wield, null, null, drop] +item=Magic staff, id=1390, option=[null, null, null, null, drop] +item=Battlestaff, id=1391, option=[null, Wield, null, null, drop] +item=Battlestaff, id=1392, option=[null, null, null, null, drop] +item=Fire battlestaff, id=1393, option=[null, Wield, null, null, drop] +item=Fire battlestaff, id=1394, option=[null, null, null, null, drop] +item=Water battlestaff, id=1395, option=[null, Wield, null, null, drop] +item=Water battlestaff, id=1396, option=[null, null, null, null, drop] +item=Air battlestaff, id=1397, option=[null, Wield, null, null, drop] +item=Air battlestaff, id=1398, option=[null, null, null, null, drop] +item=Earth battlestaff, id=1399, option=[null, Wield, null, null, drop] +item=Earth battlestaff, id=1400, option=[null, null, null, null, drop] +item=Mystic fire staff, id=1401, option=[null, Wield, null, null, drop] +item=Mystic fire staff, id=1402, option=[null, null, null, null, drop] +item=Mystic water staff, id=1403, option=[null, Wield, null, null, drop] +item=Mystic water staff, id=1404, option=[null, null, null, null, drop] +item=Mystic air staff, id=1405, option=[null, Wield, null, null, drop] +item=Mystic air staff, id=1406, option=[null, null, null, null, drop] +item=Mystic earth staff, id=1407, option=[null, Wield, null, null, drop] +item=Mystic earth staff, id=1408, option=[null, null, null, null, drop] +item=Iban's staff, id=1409, option=[null, Wield, null, Check, drop] +item=Iban's staff, id=1410, option=[null, null, null, null, drop] +item=Farmer's fork, id=1411, option=[null, null, null, null, drop] +item=Farmer's fork, id=1412, option=[null, null, null, null, drop] +item=Halberd, id=1413, option=[null, null, null, null, drop] +item=Halberd, id=1414, option=[null, null, null, null, drop] +item=Warhammer, id=1415, option=[null, null, null, null, drop] +item=Warhammer, id=1416, option=[null, null, null, null, drop] +item=Javelin, id=1417, option=[null, null, null, null, drop] +item=Javelin, id=1418, option=[null, null, null, null, drop] +item=Scythe, id=1419, option=[null, Wield, null, null, drop] +item=Iron mace, id=1420, option=[null, Wield, null, null, drop] +item=Iron mace, id=1421, option=[null, null, null, null, drop] +item=Bronze mace, id=1422, option=[null, Wield, null, null, drop] +item=Bronze mace, id=1423, option=[null, null, null, null, drop] +item=Steel mace, id=1424, option=[null, Wield, null, null, drop] +item=Steel mace, id=1425, option=[null, null, null, null, drop] +item=Black mace, id=1426, option=[null, Wield, null, null, drop] +item=Black mace, id=1427, option=[null, null, null, null, drop] +item=Mithril mace, id=1428, option=[null, Wield, null, null, drop] +item=Mithril mace, id=1429, option=[null, null, null, null, drop] +item=Adamant mace, id=1430, option=[null, Wield, null, null, drop] +item=Adamant mace, id=1431, option=[null, null, null, null, drop] +item=Rune mace, id=1432, option=[null, Wield, null, null, drop] +item=Rune mace, id=1433, option=[null, null, null, null, drop] +item=Dragon mace, id=1434, option=[null, Wield, null, null, drop] +item=Dragon mace, id=1435, option=[null, null, null, null, drop] +item=Rune essence, id=1436, option=[null, null, null, null, drop] +item=Rune essence, id=1437, option=[null, null, null, null, drop] +item=Air talisman, id=1438, option=[null, null, null, Locate, drop] +item=Air talisman, id=1439, option=[null, null, null, null, drop] +item=Earth talisman, id=1440, option=[null, null, null, Locate, drop] +item=Earth talisman, id=1441, option=[null, null, null, null, drop] +item=Fire talisman, id=1442, option=[null, null, null, Locate, drop] +item=Fire talisman, id=1443, option=[null, null, null, null, drop] +item=Water talisman, id=1444, option=[null, null, null, Locate, drop] +item=Water talisman, id=1445, option=[null, null, null, null, drop] +item=Body talisman, id=1446, option=[null, null, null, Locate, drop] +item=Body talisman, id=1447, option=[null, null, null, null, drop] +item=Mind talisman, id=1448, option=[null, null, null, Locate, drop] +item=Mind talisman, id=1449, option=[null, null, null, null, drop] +item=Blood talisman, id=1450, option=[null, null, null, Locate, drop] +item=Blood talisman, id=1451, option=[null, null, null, null, drop] +item=Chaos talisman, id=1452, option=[null, null, null, Locate, drop] +item=Chaos talisman, id=1453, option=[null, null, null, null, drop] +item=Cosmic talisman, id=1454, option=[null, null, null, Locate, drop] +item=Cosmic talisman, id=1455, option=[null, null, null, null, drop] +item=Death talisman, id=1456, option=[null, null, null, Locate, drop] +item=Death talisman, id=1457, option=[null, null, null, null, drop] +item=Law talisman, id=1458, option=[null, null, null, Locate, drop] +item=Law talisman, id=1459, option=[null, null, null, null, drop] +item=Soul talisman, id=1460, option=[null, null, null, Locate, drop] +item=Soul talisman, id=1461, option=[null, null, null, null, drop] +item=Nature talisman, id=1462, option=[null, null, null, Locate, drop] +item=Nature talisman, id=1463, option=[null, null, null, null, drop] +item=Archery ticket, id=1464, option=[null, null, null, null, drop] +item=Weapon poison, id=1465, option=[null, null, null, null, drop] +item=Sea slug, id=1466, option=[null, null, null, null, drop] +item=Damp sticks, id=1467, option=[null, null, null, null, drop] +item=Dry sticks, id=1468, option=[Rub-together, null, null, null, drop] +item=Broken glass, id=1469, option=[null, null, null, null, drop] +item=Red bead, id=1470, option=[null, null, null, null, drop] +item=Red bead, id=1471, option=[null, null, null, null, drop] +item=Yellow bead, id=1472, option=[null, null, null, null, drop] +item=Yellow bead, id=1473, option=[null, null, null, null, drop] +item=Black bead, id=1474, option=[null, null, null, null, drop] +item=Black bead, id=1475, option=[null, null, null, null, drop] +item=White bead, id=1476, option=[null, null, null, null, drop] +item=White bead, id=1477, option=[null, null, null, null, drop] +item=Amulet of accuracy, id=1478, option=[null, Wear, null, null, drop] +item=Amulet of accuracy, id=1479, option=[null, null, null, null, drop] +item=Rock, id=1480, option=[null, null, null, null, drop] +item=Orb of light, id=1481, option=[null, null, null, null, drop] +item=Orb of light, id=1482, option=[null, null, null, null, drop] +item=Orb of light, id=1483, option=[null, null, null, null, drop] +item=Orb of light, id=1484, option=[null, null, null, null, drop] +item=Damp cloth, id=1485, option=[null, null, null, null, drop] +item=Piece of railing, id=1486, option=[null, null, null, null, drop] +item=Unicorn horn, id=1487, option=[null, null, null, null, drop] +item=Paladin's badge, id=1488, option=[null, null, null, null, drop] +item=Paladin's badge, id=1489, option=[null, null, null, null, drop] +item=Paladin's badge, id=1490, option=[null, null, null, null, drop] +item=Witch's cat, id=1491, option=[null, null, null, null, drop] +item=Doll of iban, id=1492, option=[Search, null, null, null, drop] +item=Old journal, id=1493, option=[Read, null, null, null, drop] +item=History of iban, id=1494, option=[Read, null, null, null, drop] +item=Klank's gauntlets, id=1495, option=[null, Wear, null, null, drop] +item=Iban's dove, id=1496, option=[null, null, null, null, drop] +item=Amulet of othanian, id=1497, option=[null, null, null, null, drop] +item=Amulet of doomion, id=1498, option=[null, null, null, null, drop] +item=Amulet of holthion, id=1499, option=[null, null, null, null, drop] +item=Iban's shadow, id=1500, option=[null, null, null, null, drop] +item=Dwarf brew, id=1501, option=[null, null, null, null, drop] +item=Iban's ashes, id=1502, option=[null, null, null, null, drop] +item=Warrant, id=1503, option=[null, null, null, null, drop] +item=Hangover cure, id=1504, option=[null, null, null, null, drop] +item=A magic scroll, id=1505, option=[Read, null, null, null, drop] +item=Gas mask, id=1506, option=[null, Wear, null, null, drop] +item=A small key, id=1507, option=[null, null, null, null, drop] +item=A scruffy note, id=1508, option=[Read, null, null, null, drop] +item=Book, id=1509, option=[null, null, null, null, drop] +item=Picture, id=1510, option=[null, null, null, null, drop] +item=Logs, id=1511, option=[null, null, null, null, drop] +item=Logs, id=1512, option=[null, null, null, null, drop] +item=Magic logs, id=1513, option=[null, null, null, null, drop] +item=Magic logs, id=1514, option=[null, null, null, null, drop] +item=Yew logs, id=1515, option=[null, null, null, null, drop] +item=Yew logs, id=1516, option=[null, null, null, null, drop] +item=Maple logs, id=1517, option=[null, null, null, null, drop] +item=Maple logs, id=1518, option=[null, null, null, null, drop] +item=Willow logs, id=1519, option=[null, null, null, null, drop] +item=Willow logs, id=1520, option=[null, null, null, null, drop] +item=Oak logs, id=1521, option=[null, null, null, null, drop] +item=Oak logs, id=1522, option=[null, null, null, null, drop] +item=Lockpick, id=1523, option=[null, null, null, null, drop] +item=Lockpick, id=1524, option=[null, null, null, null, drop] +item=Grimy snake weed, id=1525, option=[Clean, null, null, null, drop] +item=Clean snake weed, id=1526, option=[null, null, null, null, drop] +item=Grimy ardrigal, id=1527, option=[Clean, null, null, null, drop] +item=Clean ardrigal, id=1528, option=[null, null, null, null, drop] +item=Grimy sito foil, id=1529, option=[Clean, null, null, null, drop] +item=Clean sito foil, id=1530, option=[null, null, null, null, drop] +item=Grimy volencia moss, id=1531, option=[Clean, null, null, null, drop] +item=Clean volencia moss, id=1532, option=[null, null, null, null, drop] +item=Grimy rogue's purse, id=1533, option=[Clean, null, null, null, drop] +item=Clean rogue's purse, id=1534, option=[null, null, null, null, drop] +item=Map part, id=1535, option=[Study, null, null, null, drop] +item=Map part, id=1536, option=[Study, null, null, null, drop] +item=Map part, id=1537, option=[Study, null, null, null, drop] +item=Crandor map, id=1538, option=[Study, null, null, null, drop] +item=Steel nails, id=1539, option=[null, null, null, null, drop] +item=Anti-dragon shield, id=1540, option=[null, Wear, null, null, drop] +item=Anti-dragon shield, id=1541, option=[null, null, null, null, drop] +item=Maze key, id=1542, option=[null, null, null, null, drop] +item=Key, id=1543, option=[null, null, null, null, drop] +item=Key, id=1544, option=[null, null, null, null, drop] +item=Key, id=1545, option=[null, null, null, null, drop] +item=Key, id=1546, option=[null, null, null, null, drop] +item=Key, id=1547, option=[null, null, null, null, drop] +item=Key, id=1548, option=[null, null, null, null, drop] +item=Stake, id=1549, option=[null, null, null, null, drop] +item=Garlic, id=1550, option=[null, null, null, null, drop] +item=Garlic, id=1551, option=[null, null, null, null, drop] +item=Doogle sardine, id=1552, option=[null, null, null, null, drop] +item=Whoopsie, id=1553, option=[null, null, null, null, drop] +item=null, id=0, option=[null, null, null, null, drop] +item=Pet kitten, id=1555, option=[null, null, null, null, drop] +item=Pet kitten, id=1556, option=[null, null, null, null, drop] +item=Pet kitten, id=1557, option=[null, null, null, null, drop] +item=Pet kitten, id=1558, option=[null, null, null, null, drop] +item=Pet kitten, id=1559, option=[null, null, null, null, drop] +item=Pet kitten, id=1560, option=[null, null, null, null, drop] +item=Pet cat, id=1561, option=[null, null, null, null, drop] +item=Pet cat, id=1562, option=[null, null, null, null, drop] +item=Pet cat, id=1563, option=[null, null, null, null, drop] +item=Pet cat, id=1564, option=[null, null, null, null, drop] +item=Pet cat, id=1565, option=[null, null, null, null, drop] +item=Pet cat, id=1566, option=[null, null, null, null, drop] +item=Overgrown cat, id=1567, option=[null, null, null, null, drop] +item=Overgrown cat, id=1568, option=[null, null, null, null, drop] +item=Overgrown cat, id=1569, option=[null, null, null, null, drop] +item=Overgrown cat, id=1570, option=[null, null, null, null, drop] +item=Overgrown cat, id=1571, option=[null, null, null, null, drop] +item=Overgrown cat, id=1572, option=[null, null, null, null, drop] +item=Doogle leaves, id=1573, option=[null, null, null, null, drop] +item=Whoopsie, id=1574, option=[null, null, null, null, drop] +item=Cat training medal, id=1575, option=[null, Wear, null, null, drop] +item=Whoopsie, id=1576, option=[null, null, null, null, drop] +item=Pete's candlestick, id=1577, option=[null, null, null, null, drop] +item=Pete's candlestick, id=1578, option=[null, null, null, null, drop] +item=Thieves' armband, id=1579, option=[null, null, null, null, drop] +item=Ice gloves, id=1580, option=[null, Wear, null, null, drop] +item=Blamish snail slime, id=1581, option=[null, null, null, null, drop] +item=Blamish oil, id=1582, option=[Drink, null, null, null, drop] +item=Fire feather, id=1583, option=[null, null, null, null, drop] +item=Id papers, id=1584, option=[null, null, null, null, drop] +item=Oily fishing rod, id=1585, option=[null, null, null, null, drop] +item=Miscellaneous key, id=1586, option=[null, null, null, null, drop] +item=Miscellaneous key, id=1587, option=[null, null, null, null, drop] +item=Grips' keyring, id=1588, option=[null, null, null, null, drop] +item=Pretty girl, id=1589, option=[Wear, null, null, null, drop] +item=Dusty key, id=1590, option=[null, null, null, null, drop] +item=Jail key, id=1591, option=[null, null, null, null, drop] +item=Ring mould, id=1592, option=[null, null, null, null, drop] +item=Ring mould, id=1593, option=[null, null, null, null, drop] +item=Unholy mould, id=1594, option=[null, null, null, null, drop] +item=Amulet mould, id=1595, option=[null, null, null, null, drop] +item=Amulet mould, id=1596, option=[null, null, null, null, drop] +item=Necklace mould, id=1597, option=[null, null, null, null, drop] +item=Necklace mould, id=1598, option=[null, null, null, null, drop] +item=Holy mould, id=1599, option=[null, null, null, null, drop] +item=Holy mould, id=1600, option=[null, null, null, null, drop] +item=Diamond, id=1601, option=[null, null, null, null, drop] +item=Diamond, id=1602, option=[null, null, null, null, drop] +item=Ruby, id=1603, option=[null, null, null, null, drop] +item=Ruby, id=1604, option=[null, null, null, null, drop] +item=Emerald, id=1605, option=[null, null, null, null, drop] +item=Emerald, id=1606, option=[null, null, null, null, drop] +item=Sapphire, id=1607, option=[null, null, null, null, drop] +item=Sapphire, id=1608, option=[null, null, null, null, drop] +item=Opal, id=1609, option=[null, null, null, null, drop] +item=Opal, id=1610, option=[null, null, null, null, drop] +item=Jade, id=1611, option=[null, null, null, null, drop] +item=Jade, id=1612, option=[null, null, null, null, drop] +item=Red topaz, id=1613, option=[null, null, null, null, drop] +item=Red topaz, id=1614, option=[null, null, null, null, drop] +item=Dragonstone, id=1615, option=[null, null, null, null, drop] +item=Dragonstone, id=1616, option=[null, null, null, null, drop] +item=Uncut diamond, id=1617, option=[null, null, null, null, drop] +item=Uncut diamond, id=1618, option=[null, null, null, null, drop] +item=Uncut ruby, id=1619, option=[null, null, null, null, drop] +item=Uncut ruby, id=1620, option=[null, null, null, null, drop] +item=Uncut emerald, id=1621, option=[null, null, null, null, drop] +item=Uncut emerald, id=1622, option=[null, null, null, null, drop] +item=Uncut sapphire, id=1623, option=[null, null, null, null, drop] +item=Uncut sapphire, id=1624, option=[null, null, null, null, drop] +item=Uncut opal, id=1625, option=[null, null, null, null, drop] +item=Uncut opal, id=1626, option=[null, null, null, null, drop] +item=Uncut jade, id=1627, option=[null, null, null, null, drop] +item=Uncut jade, id=1628, option=[null, null, null, null, drop] +item=Uncut red topaz, id=1629, option=[null, null, null, null, drop] +item=Uncut red topaz, id=1630, option=[null, null, null, null, drop] +item=Uncut dragonstone, id=1631, option=[null, null, null, null, drop] +item=Uncut dragonstone, id=1632, option=[null, null, null, null, drop] +item=Crushed gem, id=1633, option=[null, null, null, null, drop] +item=Crushed gem, id=1634, option=[null, null, null, null, drop] +item=Gold ring, id=1635, option=[null, Wear, null, null, drop] +item=Gold ring, id=1636, option=[null, null, null, null, drop] +item=Sapphire ring, id=1637, option=[null, Wear, null, null, drop] +item=Sapphire ring, id=1638, option=[null, null, null, null, drop] +item=Emerald ring, id=1639, option=[null, Wear, null, null, drop] +item=Emerald ring, id=1640, option=[null, null, null, null, drop] +item=Ruby ring, id=1641, option=[null, Wear, null, null, drop] +item=Ruby ring, id=1642, option=[null, null, null, null, drop] +item=Diamond ring, id=1643, option=[null, Wear, null, null, drop] +item=Diamond ring, id=1644, option=[null, null, null, null, drop] +item=Dragonstone ring, id=1645, option=[null, Wear, null, null, drop] +item=Dragonstone ring, id=1646, option=[null, null, null, null, drop] +item=null, id=1647, option=[null, null, null, null, drop] +item=Whoopsie, id=1648, option=[Wear, null, null, null, drop] +item=Sapphire ring, id=1649, option=[null, null, null, null, drop] +item=Emerald ring, id=1650, option=[null, null, null, null, drop] +item=Ruby ring, id=1651, option=[null, null, null, null, drop] +item=Diamond ring, id=1652, option=[null, null, null, null, drop] +item=Dragonstone ring, id=1653, option=[null, null, null, null, drop] +item=Gold necklace, id=1654, option=[null, Wear, null, null, drop] +item=Gold necklace, id=1655, option=[null, null, null, null, drop] +item=Sapphire necklace, id=1656, option=[null, Wear, null, null, drop] +item=Sapphire necklace, id=1657, option=[null, null, null, null, drop] +item=Emerald necklace, id=1658, option=[null, Wear, null, null, drop] +item=Emerald necklace, id=1659, option=[null, null, null, null, drop] +item=Ruby necklace, id=1660, option=[null, Wear, null, null, drop] +item=Ruby necklace, id=1661, option=[null, null, null, null, drop] +item=Diamond necklace, id=1662, option=[null, Wear, null, null, drop] +item=Diamond necklace, id=1663, option=[null, null, null, null, drop] +item=Dragon necklace, id=1664, option=[null, Wear, null, null, drop] +item=Dragon necklace, id=1665, option=[null, null, null, null, drop] +item=null, id=1666, option=[null, null, null, null, drop] +item=Whoopsie, id=1667, option=[Wear, null, null, null, drop] +item=Sapphire necklace, id=1668, option=[null, null, null, null, drop] +item=Emerald necklace, id=1669, option=[null, null, null, null, drop] +item=Ruby necklace, id=1670, option=[null, null, null, null, drop] +item=Diamond necklace, id=1671, option=[null, null, null, null, drop] +item=Dragon necklace, id=1672, option=[null, null, null, null, drop] +item=Gold amulet, id=1673, option=[null, null, null, null, drop] +item=Gold amulet, id=1674, option=[null, null, null, null, drop] +item=Sapphire amulet, id=1675, option=[null, null, null, null, drop] +item=Sapphire amulet, id=1676, option=[null, null, null, null, drop] +item=Emerald amulet, id=1677, option=[null, null, null, null, drop] +item=Emerald amulet, id=1678, option=[null, null, null, null, drop] +item=Ruby amulet, id=1679, option=[null, null, null, null, drop] +item=Ruby amulet, id=1680, option=[null, null, null, null, drop] +item=Diamond amulet, id=1681, option=[null, null, null, null, drop] +item=Diamond amulet, id=1682, option=[null, null, null, null, drop] +item=Dragonstone ammy, id=1683, option=[null, null, null, null, drop] +item=Dragonstone ammy, id=1684, option=[null, null, null, null, drop] +item=null, id=1685, option=[null, null, null, null, drop] +item=Whoopsie, id=1686, option=[Wear, null, null, null, drop] +item=Sapphire amulet, id=1687, option=[null, null, null, null, drop] +item=Emerald amulet, id=1688, option=[null, null, null, null, drop] +item=Ruby amulet, id=1689, option=[null, null, null, null, drop] +item=Diamond amulet, id=1690, option=[null, null, null, null, drop] +item=Dragonstone ammy, id=1691, option=[null, null, null, null, drop] +item=Gold amulet, id=1692, option=[null, Wear, null, null, drop] +item=Gold amulet, id=1693, option=[null, null, null, null, drop] +item=Sapphire amulet, id=1694, option=[null, Wear, null, null, drop] +item=Sapphire amulet, id=1695, option=[null, null, null, null, drop] +item=Emerald amulet, id=1696, option=[null, Wear, null, null, drop] +item=Emerald amulet, id=1697, option=[null, null, null, null, drop] +item=Ruby amulet, id=1698, option=[null, Wear, null, null, drop] +item=Ruby amulet, id=1699, option=[null, null, null, null, drop] +item=Diamond amulet, id=1700, option=[null, Wear, null, null, drop] +item=Diamond amulet, id=1701, option=[null, null, null, null, drop] +item=Dragonstone ammy, id=1702, option=[null, Wear, null, null, drop] +item=Dragonstone ammy, id=1703, option=[null, null, null, null, drop] +item=Amulet of glory, id=1704, option=[null, Wear, null, Rub, drop] +item=Amulet of glory, id=1705, option=[null, null, null, null, drop] +item=Amulet of glory(1), id=1706, option=[null, Wear, null, Rub, drop] +item=Amulet of glory(1), id=1707, option=[null, null, null, null, drop] +item=Amulet of glory(2), id=1708, option=[null, Wear, null, Rub, drop] +item=Amulet of glory(2), id=1709, option=[null, null, null, null, drop] +item=Amulet of glory(3), id=1710, option=[null, Wear, null, Rub, drop] +item=Amulet of glory(3), id=1711, option=[null, null, null, null, drop] +item=Amulet of glory(4), id=1712, option=[null, Wear, null, Rub, drop] +item=Amulet of glory(4), id=1713, option=[null, null, null, null, drop] +item=Unstrung symbol, id=1714, option=[null, null, null, null, drop] +item=Unstrung symbol, id=1715, option=[null, null, null, null, drop] +item=Unblessed symbol, id=1716, option=[null, Wear, null, null, drop] +item=Unblessed symbol, id=1717, option=[null, null, null, null, drop] +item=Holy symbol, id=1718, option=[null, Wear, null, null, drop] +item=Holy symbol, id=1719, option=[null, null, null, null, drop] +item=Unstrung emblem, id=1720, option=[null, null, null, null, drop] +item=Unstrung emblem, id=1721, option=[null, null, null, null, drop] +item=Unpowered symbol, id=1722, option=[null, Wear, null, null, drop] +item=Unpowered symbol, id=1723, option=[null, null, null, null, drop] +item=Unholy symbol, id=1724, option=[null, Wear, null, null, drop] +item=Amulet of strength, id=1725, option=[null, Wear, null, null, drop] +item=Amulet of strength, id=1726, option=[null, null, null, null, drop] +item=Amulet of magic, id=1727, option=[null, Wear, null, null, drop] +item=Amulet of magic, id=1728, option=[null, null, null, null, drop] +item=Amulet of defence, id=1729, option=[null, Wear, null, null, drop] +item=Amulet of defence, id=1730, option=[null, null, null, null, drop] +item=Amulet of power, id=1731, option=[null, Wear, null, null, drop] +item=Amulet of power, id=1732, option=[null, null, null, null, drop] +item=Needle, id=1733, option=[null, null, null, null, drop] +item=Thread, id=1734, option=[null, null, null, null, drop] +item=Shears, id=1735, option=[null, null, null, null, drop] +item=Shears, id=1736, option=[null, null, null, null, drop] +item=Wool, id=1737, option=[null, null, null, null, drop] +item=Wool, id=1738, option=[null, null, null, null, drop] +item=Cowhide, id=1739, option=[null, null, null, null, drop] +item=Cowhide, id=1740, option=[null, null, null, null, drop] +item=Leather, id=1741, option=[null, null, null, null, drop] +item=Leather, id=1742, option=[null, null, null, null, drop] +item=Hard leather, id=1743, option=[null, null, null, null, drop] +item=Hard leather, id=1744, option=[null, null, null, null, drop] +item=Green d-leather, id=1745, option=[null, null, null, null, drop] +item=Green d-leather, id=1746, option=[null, null, null, null, drop] +item=Black dragonhide, id=1747, option=[null, null, null, null, drop] +item=Black dragonhide, id=1748, option=[null, null, null, null, drop] +item=Red dragonhide, id=1749, option=[null, null, null, null, drop] +item=Red dragonhide, id=1750, option=[null, null, null, null, drop] +item=Blue dragonhide, id=1751, option=[null, null, null, null, drop] +item=Blue dragonhide, id=1752, option=[null, null, null, null, drop] +item=Green dragonhide, id=1753, option=[null, null, null, null, drop] +item=Green dragonhide, id=1754, option=[null, null, null, null, drop] +item=Chisel, id=1755, option=[null, null, null, null, drop] +item=Chisel, id=1756, option=[null, null, null, null, drop] +item=Brown apron, id=1757, option=[null, Wear, null, null, drop] +item=Brown apron, id=1758, option=[null, null, null, null, drop] +item=Ball of wool, id=1759, option=[null, null, null, null, drop] +item=Ball of wool, id=1760, option=[null, null, null, null, drop] +item=Soft clay, id=1761, option=[null, null, null, null, drop] +item=Soft clay, id=1762, option=[null, null, null, null, drop] +item=Red dye, id=1763, option=[null, null, null, null, drop] +item=Red dye, id=1764, option=[null, null, null, null, drop] +item=Yellow dye, id=1765, option=[null, null, null, null, drop] +item=Yellow dye, id=1766, option=[null, null, null, null, drop] +item=Blue dye, id=1767, option=[null, null, null, null, drop] +item=Blue dye, id=1768, option=[null, null, null, null, drop] +item=Orange dye, id=1769, option=[null, null, null, null, drop] +item=Orange dye, id=1770, option=[null, null, null, null, drop] +item=Green dye, id=1771, option=[null, null, null, null, drop] +item=Green dye, id=1772, option=[null, null, null, null, drop] +item=Purple dye, id=1773, option=[null, null, null, null, drop] +item=Purple dye, id=1774, option=[null, null, null, null, drop] +item=Molten glass, id=1775, option=[null, null, null, null, drop] +item=Molten glass, id=1776, option=[null, null, null, null, drop] +item=Bow string, id=1777, option=[null, null, null, null, drop] +item=Bow string, id=1778, option=[null, null, null, null, drop] +item=Flax, id=1779, option=[null, null, null, null, drop] +item=Flax, id=1780, option=[null, null, null, null, drop] +item=Soda ash, id=1781, option=[null, null, null, null, drop] +item=Soda ash, id=1782, option=[null, null, null, null, drop] +item=Bucket of sand, id=1783, option=[null, null, null, Empty, drop] +item=Bucket of sand, id=1784, option=[null, null, null, null, drop] +item=Glassblowing pipe, id=1785, option=[null, null, null, null, drop] +item=Glassblowing pipe, id=1786, option=[null, null, null, null, drop] +item=Unfired pot, id=1787, option=[null, null, null, null, drop] +item=Unfired pot, id=1788, option=[null, null, null, null, drop] +item=Unfired pie dish, id=1789, option=[null, null, null, null, drop] +item=Unfired pie dish, id=1790, option=[null, null, null, null, drop] +item=Unfired bowl, id=1791, option=[null, null, null, null, drop] +item=Unfired bowl, id=1792, option=[null, null, null, null, drop] +item=Woad leaf, id=1793, option=[null, null, null, null, drop] +item=Bronze wire, id=1794, option=[null, null, null, null, drop] +item=Bronze wire, id=1795, option=[null, null, null, null, drop] +item=Silver necklace, id=1796, option=[null, Wear, null, null, drop] +item=Silver necklace, id=1797, option=[null, Wear, null, null, drop] +item=Silver cup, id=1798, option=[null, null, null, null, drop] +item=Silver cup, id=1799, option=[null, null, null, null, drop] +item=Silver bottle, id=1800, option=[null, null, null, null, drop] +item=Silver bottle, id=1801, option=[null, null, null, null, drop] +item=Silver book, id=1802, option=[null, null, null, null, drop] +item=Silver book, id=1803, option=[null, null, null, null, drop] +item=Silver needle, id=1804, option=[null, null, null, null, drop] +item=Silver needle, id=1805, option=[null, null, null, null, drop] +item=Silver pot, id=1806, option=[null, null, null, null, drop] +item=Silver pot, id=1807, option=[null, null, null, null, drop] +item=Criminal's thread, id=1808, option=[null, null, null, null, drop] +item=Criminal's thread, id=1809, option=[null, null, null, null, drop] +item=Criminal's thread, id=1810, option=[null, null, null, null, drop] +item=Flypaper, id=1811, option=[null, null, null, null, drop] +item=Pungent pot, id=1812, option=[null, null, null, null, drop] +item=Criminal's dagger, id=1813, option=[null, null, null, null, drop] +item=Criminal's dagger, id=1814, option=[null, null, null, null, drop] +item=Killer's print, id=1815, option=[null, null, null, null, drop] +item=Anna's print, id=1816, option=[null, null, null, null, drop] +item=Bob's print, id=1817, option=[null, null, null, null, drop] +item=Carol's print, id=1818, option=[null, null, null, null, drop] +item=David's print, id=1819, option=[null, null, null, null, drop] +item=Elizabeth's print, id=1820, option=[null, null, null, null, drop] +item=Frank's print, id=1821, option=[null, null, null, null, drop] +item=Unknown print, id=1822, option=[null, null, null, null, drop] +item=Waterskin(4), id=1823, option=[null, null, null, null, drop] +item=Waterskin(4), id=1824, option=[null, null, null, null, drop] +item=Waterskin(3), id=1825, option=[null, null, null, null, drop] +item=Waterskin(3), id=1826, option=[null, null, null, null, drop] +item=Waterskin(2), id=1827, option=[null, null, null, null, drop] +item=Waterskin(2), id=1828, option=[null, null, null, null, drop] +item=Waterskin(1), id=1829, option=[null, null, null, null, drop] +item=Waterskin(1), id=1830, option=[null, null, null, null, drop] +item=Waterskin(0), id=1831, option=[null, null, null, null, drop] +item=Waterskin(0), id=1832, option=[null, null, null, null, drop] +item=Desert shirt, id=1833, option=[null, Wear, null, null, drop] +item=Desert shirt, id=1834, option=[null, null, null, null, drop] +item=Desert robe, id=1835, option=[null, Wear, null, null, drop] +item=Desert robe, id=1836, option=[null, null, null, null, drop] +item=Desert boots, id=1837, option=[null, Wear, null, null, drop] +item=Desert boots, id=1838, option=[null, null, null, null, drop] +item=Metal key, id=1839, option=[null, null, null, null, drop] +item=Cell door key, id=1840, option=[null, null, null, null, drop] +item=Barrel, id=1841, option=[null, null, null, null, drop] +item=Ana in a barrel, id=1842, option=[Look, null, null, null, drop] +item=Wrought iron key, id=1843, option=[null, null, null, null, drop] +item=Slave shirt, id=1844, option=[null, Wear, null, null, drop] +item=Slave robe, id=1845, option=[null, Wear, null, null, drop] +item=Slave boots, id=1846, option=[null, Wear, null, null, drop] +item=Scrumpled paper, id=1847, option=[Read, null, null, null, drop] +item=Shantay disclaimer, id=1848, option=[Read, null, null, null, drop] +item=Prototype dart, id=1849, option=[null, null, null, null, drop] +item=Technical plans, id=1850, option=[Read, null, null, null, drop] +item=Tenti pineapple, id=1851, option=[Eat, null, null, null, drop] +item=Bedabin key, id=1852, option=[null, null, null, null, drop] +item=Prototype dart tip, id=1853, option=[null, null, null, null, drop] +item=Shantay pass, id=1854, option=[null, null, null, null, drop] +item=Rock, id=1855, option=[null, null, null, null, drop] +item=Guide book, id=1856, option=[Read, null, null, null, drop] +item=Totem, id=1857, option=[null, null, null, null, drop] +item=Address label, id=1858, option=[null, null, null, null, drop] +item=Raw ugthanki meat, id=1859, option=[null, null, null, null, drop] +item=Raw ugthanki meat, id=1860, option=[null, null, null, null, drop] +item=Ugthanki meat, id=1861, option=[Eat, null, null, null, drop] +item=Ugthanki meat, id=1862, option=[null, null, null, null, drop] +item=Pitta dough, id=1863, option=[null, null, null, null, drop] +item=Pitta dough, id=1864, option=[null, null, null, null, drop] +item=Pitta bread, id=1865, option=[null, null, null, null, drop] +item=Pitta bread, id=1866, option=[null, null, null, null, drop] +item=Burnt pitta bread, id=1867, option=[null, null, null, null, drop] +item=Burnt pitta bread, id=1868, option=[null, null, null, null, drop] +item=Chopped tomato, id=1869, option=[Eat, null, null, null, drop] +item=Chopped tomato, id=1870, option=[null, null, null, null, drop] +item=Chopped onion, id=1871, option=[Eat, null, null, null, drop] +item=Chopped onion, id=1872, option=[null, null, null, null, drop] +item=Chopped ugthanki, id=1873, option=[null, null, null, null, drop] +item=Chopped ugthanki, id=1874, option=[null, null, null, null, drop] +item=Onion & tomato, id=1875, option=[Eat, null, null, null, drop] +item=Onion & tomato, id=1876, option=[null, null, null, null, drop] +item=Ugthanki & onion, id=1877, option=[null, null, null, null, drop] +item=Ugthanki & onion, id=1878, option=[null, null, null, null, drop] +item=Ugthanki & tomato, id=1879, option=[null, null, null, null, drop] +item=Ugthanki & tomato, id=1880, option=[null, null, null, null, drop] +item=Kebab mix, id=1881, option=[null, null, null, null, drop] +item=Kebab mix, id=1882, option=[null, null, null, null, drop] +item=Ugthanki kebab, id=1883, option=[Eat, null, null, null, drop] +item=Ugthanki kebab, id=1884, option=[null, null, null, null, drop] +item=Ugthanki kebab, id=1885, option=[Eat, null, null, null, drop] +item=Ugthanki kebab, id=1886, option=[null, null, null, null, drop] +item=Cake tin, id=1887, option=[null, null, null, null, drop] +item=Cake tin, id=1888, option=[null, null, null, null, drop] +item=Uncooked cake, id=1889, option=[null, null, null, null, drop] +item=Uncooked cake, id=1890, option=[null, null, null, null, drop] +item=Cake, id=1891, option=[Eat, null, null, null, drop] +item=Cake, id=1892, option=[null, null, null, null, drop] +item=2/3 cake, id=1893, option=[Eat, null, null, null, drop] +item=2/3 cake, id=1894, option=[null, null, null, null, drop] +item=Slice of cake, id=1895, option=[Eat, null, null, null, drop] +item=Slice of cake, id=1896, option=[null, null, null, null, drop] +item=Chocolate cake, id=1897, option=[Eat, null, null, null, drop] +item=Chocolate cake, id=1898, option=[null, null, null, null, drop] +item=2/3 chocolate cake, id=1899, option=[Eat, null, null, null, drop] +item=2/3 chocolate cake, id=1900, option=[null, null, null, null, drop] +item=Chocolate slice, id=1901, option=[Eat, null, null, null, drop] +item=Chocolate slice, id=1902, option=[null, null, null, null, drop] +item=Burnt cake, id=1903, option=[null, null, null, null, drop] +item=Burnt cake, id=1904, option=[null, null, null, null, drop] +item=Asgarnian ale, id=1905, option=[Drink, null, null, null, drop] +item=Asgarnian ale, id=1906, option=[null, null, null, null, drop] +item=Wizard's mind bomb, id=1907, option=[Drink, null, null, null, drop] +item=Wizard's mind bomb, id=1908, option=[null, null, null, null, drop] +item=Greenman's ale, id=1909, option=[Drink, null, null, null, drop] +item=Greenman's ale, id=1910, option=[null, null, null, null, drop] +item=Dragon bitter, id=1911, option=[Drink, null, null, null, drop] +item=Dragon bitter, id=1912, option=[null, null, null, null, drop] +item=Dwarven stout, id=1913, option=[Drink, null, null, null, drop] +item=Dwarven stout, id=1914, option=[null, null, null, null, drop] +item=Grog, id=1915, option=[Drink, null, null, null, drop] +item=Grog, id=1916, option=[null, null, null, null, drop] +item=Beer, id=1917, option=[Drink, null, null, null, drop] +item=Beer, id=1918, option=[null, null, null, null, drop] +item=Beer glass, id=1919, option=[null, null, null, null, drop] +item=Beer glass, id=1920, option=[null, null, null, null, drop] +item=Bowl of water, id=1921, option=[null, null, null, Empty, drop] +item=Bowl of water, id=1922, option=[null, null, null, null, drop] +item=Bowl, id=1923, option=[null, null, null, null, drop] +item=Bowl, id=1924, option=[null, null, null, null, drop] +item=Bucket, id=1925, option=[null, null, null, null, drop] +item=Bucket, id=1926, option=[null, null, null, null, drop] +item=Bucket of milk, id=1927, option=[null, null, null, Empty, drop] +item=Bucket of milk, id=1928, option=[null, null, null, null, drop] +item=Bucket of water, id=1929, option=[null, null, null, Empty, drop] +item=Bucket of water, id=1930, option=[null, null, null, null, drop] +item=Empty pot, id=1931, option=[null, null, null, null, drop] +item=Empty pot, id=1932, option=[null, null, null, null, drop] +item=Pot of flour, id=1933, option=[null, null, null, Empty, drop] +item=Pot of flour, id=1934, option=[null, null, null, null, drop] +item=Jug, id=1935, option=[null, null, null, null, drop] +item=Jug, id=1936, option=[null, null, null, null, drop] +item=Jug of water, id=1937, option=[null, null, null, Empty, drop] +item=Jug of water, id=1938, option=[null, null, null, null, drop] +item=Swamp tar, id=1939, option=[null, null, null, null, drop] +item=Raw swamp paste, id=1940, option=[null, null, null, null, drop] +item=Swamp paste, id=1941, option=[null, null, null, null, drop] +item=Potato, id=1942, option=[Eat, null, null, null, drop] +item=Potato, id=1943, option=[null, null, null, null, drop] +item=Egg, id=1944, option=[null, null, null, null, drop] +item=Egg, id=1945, option=[null, null, null, null, drop] +item=Flour, id=1946, option=[null, null, null, null, drop] +item=Grain, id=1947, option=[null, null, null, null, drop] +item=Grain, id=1948, option=[null, null, null, null, drop] +item=Chef's hat, id=1949, option=[null, Wear, null, null, drop] +item=Chef's hat, id=1950, option=[null, null, null, null, drop] +item=Redberries, id=1951, option=[null, null, null, null, drop] +item=Redberries, id=1952, option=[null, null, null, null, drop] +item=Pastry dough, id=1953, option=[null, null, null, null, drop] +item=Pastry dough, id=1954, option=[null, null, null, null, drop] +item=Cooking apple, id=1955, option=[null, null, null, null, drop] +item=Cooking apple, id=1956, option=[null, null, null, null, drop] +item=Onion, id=1957, option=[Eat, null, null, null, drop] +item=Onion, id=1958, option=[null, null, null, null, drop] +item=Pumpkin, id=1959, option=[Eat, null, null, null, drop] +item=Pumpkin, id=1960, option=[null, null, null, null, drop] +item=Easter egg, id=1961, option=[Eat, null, null, null, drop] +item=Easter egg, id=1962, option=[null, null, null, null, drop] +item=Banana, id=1963, option=[Eat, null, null, null, drop] +item=Banana, id=1964, option=[null, null, null, null, drop] +item=Cabbage, id=1965, option=[Eat, null, null, null, drop] +item=Cabbage, id=1966, option=[null, null, null, null, drop] +item=Cabbage, id=1967, option=[Eat, null, null, null, drop] +item=Cabbage, id=1968, option=[null, null, null, null, drop] +item=Spinach roll, id=1969, option=[Eat, null, null, null, drop] +item=Whoopsie, id=1970, option=[null, null, null, null, drop] +item=Kebab, id=1971, option=[Eat, null, null, null, drop] +item=Kebab, id=1972, option=[null, null, null, null, drop] +item=Chocolate bar, id=1973, option=[Eat, null, null, null, drop] +item=Chocolate bar, id=1974, option=[null, null, null, null, drop] +item=Chocolate dust, id=1975, option=[null, null, null, null, drop] +item=Chocolate dust, id=1976, option=[null, null, null, null, drop] +item=Chocolatey milk, id=1977, option=[Drink, null, null, null, drop] +item=Cup of tea, id=1978, option=[Drink, null, null, null, drop] +item=Cup of tea, id=1979, option=[null, null, null, null, drop] +item=Empty cup, id=1980, option=[null, null, null, null, drop] +item=Empty cup, id=1981, option=[null, null, null, null, drop] +item=Tomato, id=1982, option=[Eat, null, null, null, drop] +item=Tomato, id=1983, option=[null, null, null, null, drop] +item=Rotten apple, id=1984, option=[Eat, null, null, null, drop] +item=Cheese, id=1985, option=[Eat, null, null, null, drop] +item=Cheese, id=1986, option=[null, null, null, null, drop] +item=Grapes, id=1987, option=[null, null, null, null, drop] +item=Grapes, id=1988, option=[null, null, null, null, drop] +item=Half full wine jug, id=1989, option=[Drink, null, null, null, drop] +item=Half full wine jug, id=1990, option=[null, null, null, null, drop] +item=Jug of bad wine, id=1991, option=[Drink, null, null, null, drop] +item=Jug of bad wine, id=1992, option=[Drink, null, null, null, drop] +item=Jug of wine, id=1993, option=[Drink, null, null, null, drop] +item=Jug of wine, id=1994, option=[null, null, null, null, drop] +item=Unfermented wine, id=1995, option=[null, null, null, null, drop] +item=Unfermented wine, id=1996, option=[null, null, null, null, drop] +item=Incomplete stew, id=1997, option=[null, null, null, null, drop] +item=Incomplete stew, id=1998, option=[null, null, null, null, drop] +item=Incomplete stew, id=1999, option=[null, null, null, null, drop] +item=Incomplete stew, id=2000, option=[null, null, null, null, drop] +item=Uncooked stew, id=2001, option=[null, null, null, null, drop] +item=Uncooked stew, id=2002, option=[null, null, null, null, drop] +item=Stew, id=2003, option=[Eat, null, null, null, drop] +item=Stew, id=2004, option=[null, null, null, null, drop] +item=Burnt stew, id=2005, option=[Empty Bowl, null, null, null, drop] +item=Burnt stew, id=2006, option=[null, null, null, null, drop] +item=Spice, id=2007, option=[null, null, null, null, drop] +item=Spice, id=2008, option=[null, null, null, null, drop] +item=Uncooked curry, id=2009, option=[null, null, null, null, drop] +item=Uncooked curry, id=2010, option=[null, null, null, null, drop] +item=Curry, id=2011, option=[Eat, null, null, null, drop] +item=Curry, id=2012, option=[null, null, null, null, drop] +item=Burnt curry, id=2013, option=[Empty Bowl, null, null, null, drop] +item=Burnt curry, id=2014, option=[null, null, null, null, drop] +item=Vodka, id=2015, option=[Drink, null, null, null, drop] +item=Vodka, id=2016, option=[null, null, null, null, drop] +item=Whisky, id=2017, option=[Drink, null, null, null, drop] +item=Whisky, id=2018, option=[null, null, null, null, drop] +item=Gin, id=2019, option=[Drink, null, null, null, drop] +item=Gin, id=2020, option=[null, null, null, null, drop] +item=Brandy, id=2021, option=[Drink, null, null, null, drop] +item=Brandy, id=2022, option=[null, null, null, null, drop] +item=Cocktail guide, id=2023, option=[Read, null, null, null, drop] +item=Cocktail guide, id=2024, option=[null, null, null, null, drop] +item=Cocktail shaker, id=2025, option=[Mix-cocktail, null, null, null, drop] +item=Cocktail glass, id=2026, option=[null, null, null, null, drop] +item=Cocktail glass, id=2027, option=[null, null, null, null, drop] +item=Premade blurb' sp., id=2028, option=[Drink, null, null, null, drop] +item=Premade blurb' sp., id=2029, option=[null, null, null, null, drop] +item=Premade choc s'dy, id=2030, option=[Drink, null, null, null, drop] +item=Premade choc s'dy, id=2031, option=[null, null, null, null, drop] +item=Premade dr' dragon, id=2032, option=[Drink, null, null, null, drop] +item=Premade dr' dragon, id=2033, option=[null, null, null, null, drop] +item=Premade fr' blast, id=2034, option=[Drink, null, null, null, drop] +item=Premade fr' blast, id=2035, option=[null, null, null, null, drop] +item=Premade p' punch, id=2036, option=[Drink, null, null, null, drop] +item=Premade p' punch, id=2037, option=[null, null, null, null, drop] +item=Premade sgg, id=2038, option=[Drink, null, null, null, drop] +item=Premade sgg, id=2039, option=[null, null, null, null, drop] +item=Premade wiz blz'd, id=2040, option=[Drink, null, null, null, drop] +item=Premade wiz blz'd, id=2041, option=[null, null, null, null, drop] +item=Unfinished cocktail, id=2042, option=[Drink, null, null, null, drop] +item=Unfinished cocktail, id=2043, option=[null, null, null, null, drop] +item=Unfinished cocktail, id=2044, option=[Drink, null, null, null, drop] +item=Unfinished cocktail, id=2045, option=[null, null, null, null, drop] +item=Unfinished cocktail, id=2046, option=[Drink, null, null, null, drop] +item=Unfinished cocktail, id=2047, option=[null, null, null, null, drop] +item=Pineapple punch, id=2048, option=[Drink, null, null, null, drop] +item=Pineapple punch, id=2049, option=[null, null, null, null, drop] +item=Unfinished cocktail, id=2050, option=[Drink, null, null, null, drop] +item=Unfinished cocktail, id=2051, option=[null, null, null, null, drop] +item=Unfinished cocktail, id=2052, option=[Drink, null, null, null, drop] +item=Unfinished cocktail, id=2053, option=[null, null, null, null, drop] +item=Wizard blizzard, id=2054, option=[Drink, null, null, null, drop] +item=Wizard blizzard, id=2055, option=[null, null, null, null, drop] +item=Unfinished cocktail, id=2056, option=[Drink, null, null, null, drop] +item=Unfinished cocktail, id=2057, option=[null, null, null, null, drop] +item=Unfinished cocktail, id=2058, option=[Drink, null, null, null, drop] +item=Unfinished cocktail, id=2059, option=[null, null, null, null, drop] +item=Unfinished cocktail, id=2060, option=[Drink, null, null, null, drop] +item=Unfinished cocktail, id=2061, option=[null, null, null, null, drop] +item=Unfinished cocktail, id=2062, option=[Drink, null, null, null, drop] +item=Unfinished cocktail, id=2063, option=[null, null, null, null, drop] +item=Blurberry special, id=2064, option=[Drink, null, null, null, drop] +item=Blurberry special, id=2065, option=[null, null, null, null, drop] +item=Unfinished cocktail, id=2066, option=[Drink, null, null, null, drop] +item=Unfinished cocktail, id=2067, option=[null, null, null, null, drop] +item=Unfinished cocktail, id=2068, option=[Drink, null, null, null, drop] +item=Unfinished cocktail, id=2069, option=[null, null, null, null, drop] +item=Unfinished cocktail, id=2070, option=[Drink, null, null, null, drop] +item=Unfinished cocktail, id=2071, option=[null, null, null, null, drop] +item=Unfinished cocktail, id=2072, option=[Drink, null, null, null, drop] +item=Unfinished cocktail, id=2073, option=[null, null, null, null, drop] +item=Choc saturday, id=2074, option=[Drink, null, null, null, drop] +item=Choc saturday, id=2075, option=[null, null, null, null, drop] +item=Unfinished cocktail, id=2076, option=[Drink, null, null, null, drop] +item=Unfinished cocktail, id=2077, option=[null, null, null, null, drop] +item=Unfinished cocktail, id=2078, option=[Drink, null, null, null, drop] +item=Unfinished cocktail, id=2079, option=[null, null, null, null, drop] +item=Short green guy, id=2080, option=[Drink, null, null, null, drop] +item=Short green guy, id=2081, option=[null, null, null, null, drop] +item=Unfinished cocktail, id=2082, option=[Drink, null, null, null, drop] +item=Unfinished cocktail, id=2083, option=[null, null, null, null, drop] +item=Fruit blast, id=2084, option=[Drink, null, null, null, drop] +item=Fruit blast, id=2085, option=[null, null, null, null, drop] +item=Unfinished cocktail, id=2086, option=[Drink, null, null, null, drop] +item=Unfinished cocktail, id=2087, option=[null, null, null, null, drop] +item=Unfinished cocktail, id=2088, option=[Drink, null, null, null, drop] +item=Unfinished cocktail, id=2089, option=[null, null, null, null, drop] +item=Unfinished cocktail, id=2090, option=[Drink, null, null, null, drop] +item=Unfinished cocktail, id=2091, option=[null, null, null, null, drop] +item=Drunk dragon, id=2092, option=[Drink, null, null, null, drop] +item=Drunk dragon, id=2093, option=[null, null, null, null, drop] +item=Odd cocktail, id=2094, option=[Empty, null, Drink, null, drop] +item=Odd cocktail, id=2095, option=[null, null, null, null, drop] +item=Odd cocktail, id=2096, option=[Empty, null, Drink, null, drop] +item=Odd cocktail, id=2097, option=[null, null, null, null, drop] +item=Odd cocktail, id=2098, option=[Empty, null, Drink, null, drop] +item=Odd cocktail, id=2099, option=[null, null, null, null, drop] +item=Odd cocktail, id=2100, option=[Empty, null, Drink, null, drop] +item=Odd cocktail, id=2101, option=[null, null, null, null, drop] +item=Lemon, id=2102, option=[Eat, null, null, null, drop] +item=Lemon, id=2103, option=[null, null, null, null, drop] +item=Lemon chunks, id=2104, option=[Eat, null, null, null, drop] +item=Lemon chunks, id=2105, option=[null, null, null, null, drop] +item=Lemon slices, id=2106, option=[Eat, null, null, null, drop] +item=Lemon slices, id=2107, option=[null, null, null, null, drop] +item=Orange, id=2108, option=[Eat, null, null, null, drop] +item=Orange, id=2109, option=[null, null, null, null, drop] +item=Orange chunks, id=2110, option=[Eat, null, null, null, drop] +item=Orange chunks, id=2111, option=[null, null, null, null, drop] +item=Orange slices, id=2112, option=[Eat, null, null, null, drop] +item=Orange slices, id=2113, option=[null, null, null, null, drop] +item=Pineapple, id=2114, option=[Eat, null, null, null, drop] +item=Pineapple, id=2115, option=[null, null, null, null, drop] +item=Pineapple chunks, id=2116, option=[Eat, null, null, null, drop] +item=Pineapple chunks, id=2117, option=[null, null, null, null, drop] +item=Pineapple ring, id=2118, option=[Eat, null, null, null, drop] +item=Pineapple ring, id=2119, option=[null, null, null, null, drop] +item=Lime, id=2120, option=[Eat, null, null, null, drop] +item=Lime, id=2121, option=[null, null, null, null, drop] +item=Lime chunks, id=2122, option=[Eat, null, null, null, drop] +item=Lime chunks, id=2123, option=[null, null, null, null, drop] +item=Lime slices, id=2124, option=[Eat, null, null, null, drop] +item=Lime slices, id=2125, option=[null, null, null, null, drop] +item=Dwellberries, id=2126, option=[Eat, null, null, null, drop] +item=Dwellberries, id=2127, option=[null, null, null, null, drop] +item=Equa leaves, id=2128, option=[Eat, null, null, null, drop] +item=Equa leaves, id=2129, option=[null, null, null, null, drop] +item=Pot of cream, id=2130, option=[Eat, null, null, null, drop] +item=Pot of cream, id=2131, option=[null, null, null, null, drop] +item=Raw beef, id=2132, option=[null, null, null, null, drop] +item=Raw beef, id=2133, option=[null, null, null, null, drop] +item=Raw rat meat, id=2134, option=[null, null, null, null, drop] +item=Raw rat meat, id=2135, option=[null, null, null, null, drop] +item=Raw bear meat, id=2136, option=[null, null, null, null, drop] +item=Raw bear meat, id=2137, option=[null, null, null, null, drop] +item=Raw chicken, id=2138, option=[null, null, null, null, drop] +item=Raw chicken, id=2139, option=[null, null, null, null, drop] +item=Cooked chicken, id=2140, option=[Eat, null, null, null, drop] +item=Cooked chicken, id=2141, option=[null, null, null, null, drop] +item=Cooked meat, id=2142, option=[Eat, null, null, null, drop] +item=Cooked meat, id=2143, option=[null, null, null, null, drop] +item=Burnt chicken, id=2144, option=[null, null, null, null, drop] +item=Burnt chicken, id=2145, option=[null, null, null, null, drop] +item=Burnt meat, id=2146, option=[null, null, null, null, drop] +item=Burnt meat, id=2147, option=[null, null, null, null, drop] +item=Raw lava eel, id=2148, option=[null, null, null, null, drop] +item=Lava eel, id=2149, option=[Eat, null, null, null, drop] +item=Swamp toad, id=2150, option=[Remove-legs, null, null, null, drop] +item=Swamp toad, id=2151, option=[null, null, null, null, drop] +item=Toad's legs, id=2152, option=[Eat, null, null, null, drop] +item=Toad's legs, id=2153, option=[null, null, null, null, drop] +item=Equa toad's legs, id=2154, option=[Eat, null, null, null, drop] +item=Equa toad's legs, id=2155, option=[null, null, null, null, drop] +item=Spicy toad's legs, id=2156, option=[Eat, null, null, null, drop] +item=Spicy toad's legs, id=2157, option=[null, null, null, null, drop] +item=Seasoned legs, id=2158, option=[Eat, null, null, null, drop] +item=Seasoned legs, id=2159, option=[null, null, null, null, drop] +item=Spicy worm, id=2160, option=[Eat, null, null, null, drop] +item=Spicy worm, id=2161, option=[null, null, null, null, drop] +item=King worm, id=2162, option=[Eat, null, null, null, drop] +item=King worm, id=2163, option=[null, null, null, null, drop] +item=Batta tin, id=2164, option=[null, null, null, null, drop] +item=Crunchy tray, id=2165, option=[null, null, null, null, drop] +item=Gnomebowl mould, id=2166, option=[null, null, null, null, drop] +item=Gianne's cook book, id=2167, option=[Read, null, null, null, drop] +item=Gianne's cook book, id=2168, option=[null, null, null, null, drop] +item=Gnome spice, id=2169, option=[null, null, null, null, drop] +item=Gnome spice, id=2170, option=[null, null, null, null, drop] +item=Gianne dough, id=2171, option=[null, null, null, null, drop] +item=Gianne dough, id=2172, option=[null, null, null, null, drop] +item=Odd gnomebowl, id=2173, option=[Eat, null, null, null, drop] +item=Odd gnomebowl, id=2174, option=[null, null, null, null, drop] +item=Burnt gnomebowl, id=2175, option=[Empty Bowl, null, null, null, drop] +item=Burnt gnomebowl, id=2176, option=[null, null, null, null, drop] +item=Half baked bowl, id=2177, option=[Prepare, null, null, null, drop] +item=Raw gnomebowl, id=2178, option=[null, null, null, null, drop] +item=Unfinished bowl, id=2179, option=[Eat, null, null, null, drop] +item=Unfinished bowl, id=2180, option=[null, null, null, null, drop] +item=Unfinished bowl, id=2181, option=[Eat, null, null, null, drop] +item=Unfinished bowl, id=2182, option=[null, null, null, null, drop] +item=Unfinished bowl, id=2183, option=[Eat, null, null, null, drop] +item=Unfinished bowl, id=2184, option=[null, null, null, null, drop] +item=Chocolate bomb, id=2185, option=[Eat, null, null, null, drop] +item=Chocolate bomb, id=2186, option=[null, null, null, null, drop] +item=Tangled toads' legs, id=2187, option=[Eat, null, null, null, drop] +item=Tangled toads' legs, id=2188, option=[null, null, null, null, drop] +item=Unfinished bowl, id=2189, option=[Eat, null, null, null, drop] +item=Unfinished bowl, id=2190, option=[null, null, null, null, drop] +item=Worm hole, id=2191, option=[Eat, null, null, null, drop] +item=Worm hole, id=2192, option=[null, null, null, null, drop] +item=Unfinished bowl, id=2193, option=[Eat, null, null, null, drop] +item=Unfinished bowl, id=2194, option=[null, null, null, null, drop] +item=Veg ball, id=2195, option=[Eat, null, null, null, drop] +item=Veg ball, id=2196, option=[null, null, null, null, drop] +item=Odd crunchies, id=2197, option=[Eat, null, null, null, drop] +item=Odd crunchies, id=2198, option=[null, null, null, null, drop] +item=Burnt crunchies, id=2199, option=[Empty Tray, null, null, null, drop] +item=Burnt crunchies, id=2200, option=[null, null, null, null, drop] +item=Half baked crunchy, id=2201, option=[Prepare, null, null, null, drop] +item=Raw crunchies, id=2202, option=[null, null, null, null, drop] +item=Unfinished crunchy, id=2203, option=[Eat, null, null, null, drop] +item=Unfinished crunchy, id=2204, option=[null, null, null, null, drop] +item=Worm crunchies, id=2205, option=[Eat, null, null, null, drop] +item=Worm crunchies, id=2206, option=[null, null, null, null, drop] +item=Unfinished crunchy, id=2207, option=[Eat, null, null, null, drop] +item=Unfinished crunchy, id=2208, option=[null, null, null, null, drop] +item=Chocchip crunchies, id=2209, option=[Eat, null, null, null, drop] +item=Chocchip crunchies, id=2210, option=[null, null, null, null, drop] +item=Unfinished crunchy, id=2211, option=[Eat, null, null, null, drop] +item=Unfinished crunchy, id=2212, option=[null, null, null, null, drop] +item=Spicy crunchies, id=2213, option=[Eat, null, null, null, drop] +item=Spicy crunchies, id=2214, option=[null, null, null, null, drop] +item=Unfinished crunchy, id=2215, option=[Eat, null, null, null, drop] +item=Unfinished crunchy, id=2216, option=[null, null, null, null, drop] +item=Toad crunchies, id=2217, option=[Eat, null, null, null, drop] +item=Toad crunchies, id=2218, option=[null, null, null, null, drop] +item=Premade w'm batta, id=2219, option=[Eat, null, null, null, drop] +item=Premade w'm batta, id=2220, option=[null, null, null, null, drop] +item=Premade t'd batta, id=2221, option=[Eat, null, null, null, drop] +item=Premade t'd batta, id=2222, option=[null, null, null, null, drop] +item=Premade c+t batta, id=2223, option=[Eat, null, null, null, drop] +item=Premade c+t batta, id=2224, option=[null, null, null, null, drop] +item=Premade fr't batta, id=2225, option=[Eat, null, null, null, drop] +item=Premade fr't batta, id=2226, option=[null, null, null, null, drop] +item=Premade veg batta, id=2227, option=[Eat, null, null, null, drop] +item=Premade veg batta, id=2228, option=[null, null, null, null, drop] +item=Premade choc bomb, id=2229, option=[Eat, null, null, null, drop] +item=Premade choc bomb, id=2230, option=[null, null, null, null, drop] +item=Premade ttl, id=2231, option=[Eat, null, null, null, drop] +item=Premade ttl, id=2232, option=[null, null, null, null, drop] +item=Premade worm hole, id=2233, option=[Eat, null, null, null, drop] +item=Premade worm hole, id=2234, option=[null, null, null, null, drop] +item=Premade veg ball, id=2235, option=[Eat, null, null, null, drop] +item=Premade veg ball, id=2236, option=[null, null, null, null, drop] +item=Premade w'm crun', id=2237, option=[Eat, null, null, null, drop] +item=Premade w'm crun', id=2238, option=[null, null, null, null, drop] +item=Premade ch' crunch, id=2239, option=[Eat, null, null, null, drop] +item=Premade ch' crunch, id=2240, option=[null, null, null, null, drop] +item=Premade s'y crunch, id=2241, option=[Eat, null, null, null, drop] +item=Premade s'y crunch, id=2242, option=[null, null, null, null, drop] +item=Premade t'd crunch, id=2243, option=[Eat, null, null, null, drop] +item=Premade t'd crunch, id=2244, option=[null, null, null, null, drop] +item=Odd batta, id=2245, option=[Eat, null, null, null, drop] +item=Odd batta, id=2246, option=[null, null, null, null, drop] +item=Burnt batta, id=2247, option=[Empty Tin, null, null, null, drop] +item=Burnt batta, id=2248, option=[null, null, null, null, drop] +item=Half baked batta, id=2249, option=[Prepare, null, null, null, drop] +item=Raw batta, id=2250, option=[null, null, null, null, drop] +item=Unfinished batta, id=2251, option=[Eat, null, null, null, drop] +item=Unfinished batta, id=2252, option=[null, null, null, null, drop] +item=Worm batta, id=2253, option=[Eat, null, null, null, drop] +item=Worm batta, id=2254, option=[null, null, null, null, drop] +item=Toad batta, id=2255, option=[Eat, null, null, null, drop] +item=Toad batta, id=2256, option=[null, null, null, null, drop] +item=Unfinished batta, id=2257, option=[Eat, null, null, null, drop] +item=Unfinished batta, id=2258, option=[null, null, null, null, drop] +item=Cheese+tom batta, id=2259, option=[Eat, null, null, null, drop] +item=Cheese+tom batta, id=2260, option=[null, null, null, null, drop] +item=Unfinished batta, id=2261, option=[Eat, null, null, null, drop] +item=Unfinished batta, id=2262, option=[null, null, null, null, drop] +item=Unfinished batta, id=2263, option=[Eat, null, null, null, drop] +item=Unfinished batta, id=2264, option=[null, null, null, null, drop] +item=Unfinished batta, id=2265, option=[Eat, null, null, null, drop] +item=Unfinished batta, id=2266, option=[null, null, null, null, drop] +item=Unfinished batta, id=2267, option=[Eat, null, null, null, drop] +item=Unfinished batta, id=2268, option=[null, null, null, null, drop] +item=Unfinished batta, id=2269, option=[Eat, null, null, null, drop] +item=Unfinished batta, id=2270, option=[null, null, null, null, drop] +item=Unfinished batta, id=2271, option=[Eat, null, null, null, drop] +item=Unfinished batta, id=2272, option=[null, null, null, null, drop] +item=Unfinished batta, id=2273, option=[Eat, null, null, null, drop] +item=Unfinished batta, id=2274, option=[null, null, null, null, drop] +item=Unfinished batta, id=2275, option=[Eat, null, null, null, drop] +item=Unfinished batta, id=2276, option=[null, null, null, null, drop] +item=Fruit batta, id=2277, option=[Eat, null, null, null, drop] +item=Fruit batta, id=2278, option=[null, null, null, null, drop] +item=Unfinished batta, id=2279, option=[Eat, null, null, null, drop] +item=Unfinished batta, id=2280, option=[null, null, null, null, drop] +item=Vegetable batta, id=2281, option=[Eat, null, null, null, drop] +item=Vegetable batta, id=2282, option=[null, null, null, null, drop] +item=Pizza base, id=2283, option=[null, null, null, null, drop] +item=Pizza base, id=2284, option=[null, null, null, null, drop] +item=Incomplete pizza, id=2285, option=[null, null, null, null, drop] +item=Incomplete pizza, id=2286, option=[null, null, null, null, drop] +item=Uncooked pizza, id=2287, option=[null, null, null, null, drop] +item=Uncooked pizza, id=2288, option=[null, null, null, null, drop] +item=Plain pizza, id=2289, option=[Eat, null, null, null, drop] +item=Plain pizza, id=2290, option=[null, null, null, null, drop] +item=1/2 plain pizza, id=2291, option=[Eat, null, null, null, drop] +item=1/2 plain pizza, id=2292, option=[null, null, null, null, drop] +item=Meat pizza, id=2293, option=[Eat, null, null, null, drop] +item=Meat pizza, id=2294, option=[null, null, null, null, drop] +item=1/2 meat pizza, id=2295, option=[Eat, null, null, null, drop] +item=1/2 meat pizza, id=2296, option=[null, null, null, null, drop] +item=Anchovy pizza, id=2297, option=[Eat, null, null, null, drop] +item=Anchovy pizza, id=2298, option=[null, null, null, null, drop] +item=1/2 anchovy pizza, id=2299, option=[Eat, null, null, null, drop] +item=1/2 anchovy pizza, id=2300, option=[null, null, null, null, drop] +item=Pineapple pizza, id=2301, option=[Eat, null, null, null, drop] +item=Pineapple pizza, id=2302, option=[null, null, null, null, drop] +item=1/2 p'apple pizza, id=2303, option=[Eat, null, null, null, drop] +item=1/2 p'apple pizza, id=2304, option=[null, null, null, null, drop] +item=Burnt pizza, id=2305, option=[null, null, null, null, drop] +item=Burnt pizza, id=2306, option=[null, null, null, null, drop] +item=Bread dough, id=2307, option=[null, null, null, null, drop] +item=Bread dough, id=2308, option=[null, null, null, null, drop] +item=Bread, id=2309, option=[Eat, null, null, null, drop] +item=Bread, id=2310, option=[null, null, null, null, drop] +item=Burnt bread, id=2311, option=[null, null, null, null, drop] +item=Burnt bread, id=2312, option=[null, null, null, null, drop] +item=Pie dish, id=2313, option=[null, null, null, null, drop] +item=Pie dish, id=2314, option=[null, null, null, null, drop] +item=Pie shell, id=2315, option=[null, null, null, null, drop] +item=Pie shell, id=2316, option=[null, null, null, null, drop] +item=Uncooked apple pie, id=2317, option=[null, null, null, null, drop] +item=Uncooked apple pie, id=2318, option=[null, null, null, null, drop] +item=Uncooked meat pie, id=2319, option=[null, null, null, null, drop] +item=Uncooked meat pie, id=2320, option=[null, null, null, null, drop] +item=Uncooked berry pie, id=2321, option=[null, null, null, null, drop] +item=Uncooked berry pie, id=2322, option=[null, null, null, null, drop] +item=Apple pie, id=2323, option=[Eat, null, null, null, drop] +item=Apple pie, id=2324, option=[null, null, null, null, drop] +item=Redberry pie, id=2325, option=[Eat, null, null, null, drop] +item=Redberry pie, id=2326, option=[null, null, null, null, drop] +item=Meat pie, id=2327, option=[Eat, null, null, null, drop] +item=Meat pie, id=2328, option=[null, null, null, null, drop] +item=Burnt pie, id=2329, option=[Empty Dish, null, null, null, drop] +item=Burnt pie, id=2330, option=[null, null, null, null, drop] +item=Half a meat pie, id=2331, option=[Eat, null, null, null, drop] +item=Half a meat pie, id=2332, option=[null, null, null, null, drop] +item=Half a redberry pie, id=2333, option=[Eat, null, null, null, drop] +item=Half a redberry pie, id=2334, option=[null, null, null, null, drop] +item=Half an apple pie, id=2335, option=[Eat, null, null, null, drop] +item=Half an apple pie, id=2336, option=[null, null, null, null, drop] +item=Raw oomlie, id=2337, option=[null, null, null, null, drop] +item=Raw oomlie, id=2338, option=[null, null, null, null, drop] +item=Palm leaf, id=2339, option=[null, null, null, null, drop] +item=Palm leaf, id=2340, option=[null, null, null, null, drop] +item=Wrapped oomlie, id=2341, option=[null, null, null, null, drop] +item=Wrapped oomlie, id=2342, option=[null, null, null, null, drop] +item=Cooked oomlie wrap, id=2343, option=[Eat, null, null, null, drop] +item=Cooked oomlie wrap, id=2344, option=[null, null, null, null, drop] +item=Burnt oomlie wrap, id=2345, option=[null, null, null, null, drop] +item=Burnt oomlie wrap, id=2346, option=[null, null, null, null, drop] +item=Hammer, id=2347, option=[null, null, null, null, drop] +item=Hammer, id=2348, option=[null, null, null, null, drop] +item=Bronze bar, id=2349, option=[null, null, null, null, drop] +item=Bronze bar, id=2350, option=[null, null, null, null, drop] +item=Iron bar, id=2351, option=[null, null, null, null, drop] +item=Iron bar, id=2352, option=[null, null, null, null, drop] +item=Steel bar, id=2353, option=[null, null, null, null, drop] +item=Steel bar, id=2354, option=[null, null, null, null, drop] +item=Silver bar, id=2355, option=[null, null, null, null, drop] +item=Silver bar, id=2356, option=[null, null, null, null, drop] +item=Gold bar, id=2357, option=[null, null, null, null, drop] +item=Gold bar, id=2358, option=[null, null, null, null, drop] +item=Mithril bar, id=2359, option=[null, null, null, null, drop] +item=Mithril bar, id=2360, option=[null, null, null, null, drop] +item=Adamantite bar, id=2361, option=[null, null, null, null, drop] +item=Adamantite bar, id=2362, option=[null, null, null, null, drop] +item=Runite bar, id=2363, option=[null, null, null, null, drop] +item=Runite bar, id=2364, option=[null, null, null, null, drop] +item='perfect' gold bar, id=2365, option=[null, null, null, null, drop] +item=Shield left half, id=2366, option=[null, null, null, null, drop] +item=Shield left half, id=2367, option=[null, null, null, null, drop] +item=Shield right half, id=2368, option=[null, null, null, null, drop] +item=Shield right half, id=2369, option=[null, null, null, null, drop] +item=Steel studs, id=2370, option=[null, null, null, null, drop] +item=Steel studs, id=2371, option=[null, null, null, null, drop] +item=Ogre relic, id=2372, option=[null, null, null, null, Destroy] +item=Relic part 1, id=2373, option=[null, null, null, null, Destroy] +item=Relic part 2, id=2374, option=[null, null, null, null, Destroy] +item=Relic part 3, id=2375, option=[null, null, null, null, Destroy] +item=Skavid map, id=2376, option=[Read, null, null, null, Destroy] +item=Ogre tooth, id=2377, option=[null, null, null, null, Destroy] +item=Toban's key, id=2378, option=[null, null, null, null, Destroy] +item=Rock cake, id=2379, option=[null, Eat, null, null, Destroy] +item=Crystal, id=2380, option=[null, null, null, null, Destroy] +item=Crystal, id=2381, option=[null, null, null, null, Destroy] +item=Crystal, id=2382, option=[null, null, null, null, Destroy] +item=Crystal, id=2383, option=[null, null, null, null, Destroy] +item=Fingernails, id=2384, option=[null, null, null, null, Destroy] +item=Old robe, id=2385, option=[null, null, null, null, drop] +item=Unusual armour, id=2386, option=[null, null, null, null, drop] +item=Damaged dagger, id=2387, option=[null, null, null, null, drop] +item=Tattered eye patch, id=2388, option=[null, null, null, null, drop] +item=Vial, id=2389, option=[null, null, null, null, Destroy] +item=Vial, id=2390, option=[null, null, null, null, Destroy] +item=Ground bat bones, id=2391, option=[null, null, null, null, drop] +item=Ground bat bones, id=2392, option=[null, null, null, null, drop] +item=Toban's gold, id=2393, option=[null, null, null, null, Destroy] +item=Potion, id=2394, option=[null, null, null, null, drop] +item=Magic ogre potion, id=2395, option=[null, null, null, null, drop] +item=Spell scroll, id=2396, option=[Read, null, null, null, drop] +item=Shaman robe, id=2397, option=[Search, null, null, null, drop] +item=Cave nightshade, id=2398, option=[null, null, null, Eat, drop] +item=Silverlight key, id=2399, option=[null, null, null, null, Destroy] +item=Silverlight key, id=2400, option=[null, null, null, null, Destroy] +item=Silverlight key, id=2401, option=[null, null, null, null, Destroy] +item=Silverlight, id=2402, option=[null, Wield, null, null, drop] +item=Hazeel scroll, id=2403, option=[null, null, null, null, drop] +item=Chest key, id=2404, option=[null, null, null, null, drop] +item=Carnillean armour, id=2405, option=[null, Wear, null, null, drop] +item=Hazeel's mark, id=2406, option=[null, Wear, null, null, drop] +item=Ball, id=2407, option=[null, null, null, null, drop] +item=Diary, id=2408, option=[Read, null, null, null, drop] +item=Door key, id=2409, option=[null, null, null, null, drop] +item=Magnet, id=2410, option=[null, null, null, null, drop] +item=Key, id=2411, option=[null, null, null, null, drop] +item=Saradomin cape, id=2412, option=[null, Wear, null, null, drop] +item=Guthix cape, id=2413, option=[null, Wear, null, null, drop] +item=Zamorak cape, id=2414, option=[null, Wear, null, null, drop] +item=Saradomin staff, id=2415, option=[null, Wield, null, null, drop] +item=Guthix staff, id=2416, option=[null, Wield, null, null, drop] +item=Zamorak staff, id=2417, option=[null, Wield, null, null, drop] +item=Bronze key, id=2418, option=[null, null, null, null, drop] +item=Wig, id=2419, option=[null, null, null, null, drop] +item=Brass monkey, id=2420, option=[Wear, null, null, null, drop] +item=Wig, id=2421, option=[null, null, null, null, drop] +item=Blue partyhat, id=2422, option=[null, Wear, null, null, drop] +item=Key print, id=2423, option=[null, null, null, null, drop] +item=Paste, id=2424, option=[null, null, null, null, drop] +item=Orbital knife, id=2425, option=[Wear, null, null, null, drop] +item=Burnt oomlie, id=2426, option=[null, null, null, null, drop] +item=Burnt oomlie, id=2427, option=[null, null, null, null, drop] +item=Attack potion(4), id=2428, option=[Drink, null, null, Empty, drop] +item=Attack potion(4), id=2429, option=[null, null, null, null, drop] +item=Restore potion(4), id=2430, option=[Drink, null, null, Empty, drop] +item=Restore potion(4), id=2431, option=[null, null, null, null, drop] +item=Defence potion(4), id=2432, option=[Drink, null, null, Empty, drop] +item=Defence potion(4), id=2433, option=[null, null, null, null, drop] +item=Prayer potion(4), id=2434, option=[Drink, null, null, Empty, drop] +item=Prayer potion(4), id=2435, option=[null, null, null, null, drop] +item=Super attack(4), id=2436, option=[Drink, null, null, Empty, drop] +item=Super attack(4), id=2437, option=[null, null, null, null, drop] +item=Fishing potion(4), id=2438, option=[Drink, null, null, Empty, drop] +item=Fishing potion(4), id=2439, option=[null, null, null, null, drop] +item=Super strength(4), id=2440, option=[Drink, null, null, Empty, drop] +item=Super strength(4), id=2441, option=[null, null, null, null, drop] +item=Super defence(4), id=2442, option=[Drink, null, null, Empty, drop] +item=Super defence(4), id=2443, option=[null, null, null, null, drop] +item=Ranging potion(4), id=2444, option=[Drink, null, null, Empty, drop] +item=Ranging potion(4), id=2445, option=[null, null, null, null, drop] +item=Antipoison(4), id=2446, option=[Drink, null, null, Empty, drop] +item=Antipoison(4), id=2447, option=[null, null, null, null, drop] +item=Super antipoison(4), id=2448, option=[Drink, null, null, Empty, drop] +item=Super antipoison(4), id=2449, option=[null, null, null, null, drop] +item=Zamorak brew(4), id=2450, option=[Drink, null, null, Empty, drop] +item=Zamorak brew(4), id=2451, option=[null, null, null, null, drop] +item=Antifire potion(4), id=2452, option=[Drink, null, null, Empty, drop] +item=Antifire potion(4), id=2453, option=[null, null, null, null, drop] +item=Antifire potion(3), id=2454, option=[Drink, null, null, Empty, drop] +item=Antifire potion(3), id=2455, option=[null, null, null, null, drop] +item=Antifire potion(2), id=2456, option=[Drink, null, null, Empty, drop] +item=Antifire potion(2), id=2457, option=[null, null, null, null, drop] +item=Antifire potion(1), id=2458, option=[Drink, null, null, Empty, drop] +item=Antifire potion(1), id=2459, option=[null, null, null, null, drop] +item=Flowers, id=2460, option=[null, Wield, null, null, drop] +item=Flowers, id=2461, option=[null, null, null, null, drop] +item=Flowers, id=2462, option=[null, Wield, null, null, drop] +item=Flowers, id=2463, option=[null, null, null, null, drop] +item=Flowers, id=2464, option=[null, Wield, null, null, drop] +item=Flowers, id=2465, option=[null, null, null, null, drop] +item=Flowers, id=2466, option=[null, Wield, null, null, drop] +item=Flowers, id=2467, option=[null, null, null, null, drop] +item=Flowers, id=2468, option=[null, Wield, null, null, drop] +item=Flowers, id=2469, option=[null, null, null, null, drop] +item=Flowers, id=2470, option=[null, Wield, null, null, drop] +item=Flowers, id=2471, option=[null, null, null, null, drop] +item=Flowers, id=2472, option=[null, Wield, null, null, drop] +item=Flowers, id=2473, option=[null, null, null, null, drop] +item=Flowers, id=2474, option=[null, Wield, null, null, drop] +item=Flowers, id=2475, option=[null, null, null, null, drop] +item=Flowers, id=2476, option=[null, Wield, null, null, drop] +item=Flowers, id=2477, option=[null, null, null, null, drop] +item=Whoopsie, id=2478, option=[null, null, null, null, drop] +item=Whoopsie, id=2479, option=[null, null, null, null, drop] +item=Firestarter, id=2480, option=[Wear, null, null, null, drop] +item=Clean lantadyme, id=2481, option=[null, null, null, null, drop] +item=Clean lantadyme, id=2482, option=[null, null, null, null, drop] +item=Lantadyme potion(unf), id=2483, option=[null, null, null, Empty, drop] +item=Lantadyme potion(unf), id=2484, option=[null, null, null, null, drop] +item=Grimy lantadyme, id=2485, option=[Clean, null, null, null, drop] +item=Grimy lantadyme, id=2486, option=[null, null, null, null, drop] +item=Blue d'hide vamb, id=2487, option=[null, Wear, null, null, drop] +item=Blue d'hide vamb, id=2488, option=[null, null, null, null, drop] +item=Red d'hide vamb, id=2489, option=[null, Wear, null, null, drop] +item=Red d'hide vamb, id=2490, option=[null, null, null, null, drop] +item=Black d'hide vamb, id=2491, option=[null, Wear, null, null, drop] +item=Black d'hide vamb, id=2492, option=[null, null, null, null, drop] +item=Blue d'hide chaps, id=2493, option=[null, Wear, null, null, drop] +item=Blue d'hide chaps, id=2494, option=[null, null, null, null, drop] +item=Red d'hide chaps, id=2495, option=[null, Wear, null, null, drop] +item=Red d'hide chaps, id=2496, option=[null, null, null, null, drop] +item=Black d'hide chaps, id=2497, option=[null, Wear, null, null, drop] +item=Black d'hide chaps, id=2498, option=[null, null, null, null, drop] +item=Blue d'hide body, id=2499, option=[null, Wear, null, null, drop] +item=Blue d'hide body, id=2500, option=[null, null, null, null, drop] +item=Red d'hide body, id=2501, option=[null, Wear, null, null, drop] +item=Red d'hide body, id=2502, option=[null, null, null, null, drop] +item=Black d'hide body, id=2503, option=[null, Wear, null, null, drop] +item=Black d'hide body, id=2504, option=[null, null, null, null, drop] +item=Blue d-leather, id=2505, option=[null, null, null, null, drop] +item=Blue d-leather, id=2506, option=[null, null, null, null, drop] +item=Red dragon leather, id=2507, option=[null, null, null, null, drop] +item=Red dragon leather, id=2508, option=[null, null, null, null, drop] +item=Black d-leather, id=2509, option=[null, null, null, null, drop] +item=Black d-leather, id=2510, option=[null, null, null, null, drop] +item=Logs, id=2511, option=[null, null, null, null, drop] +item=Box of delights, id=2512, option=[Wear, null, null, null, drop] +item=Dragon chainbody, id=2513, option=[Wear, null, null, null, drop] +item=Raw shrimps, id=2514, option=[null, null, null, null, drop] +item=Raw shrimps, id=2515, option=[null, null, null, null, drop] +item=Pot of flour, id=2516, option=[null, null, null, null, drop] +item=Pot of flour, id=2517, option=[null, null, null, null, drop] +item=Rotten tomato, id=2518, option=[null, null, null, null, drop] +item=Rotten tomato, id=2519, option=[null, null, null, null, drop] +item=Toy horsey, id=2520, option=[Play-with, null, null, null, drop] +item=Toy horsey, id=2521, option=[null, null, null, null, drop] +item=Toy horsey, id=2522, option=[Play-with, null, null, null, drop] +item=Toy horsey, id=2523, option=[null, null, null, null, drop] +item=Toy horsey, id=2524, option=[Play-with, null, null, null, drop] +item=Toy horsey, id=2525, option=[null, null, null, null, drop] +item=Toy horsey, id=2526, option=[Play-with, null, null, null, drop] +item=Toy horsey, id=2527, option=[null, null, null, null, drop] +item=Lamp, id=2528, option=[Rub, null, null, null, drop] +item=Orb of light, id=2529, option=[null, null, null, null, drop] +item=Bones, id=2530, option=[Bury, null, null, null, drop] +item=Bones, id=2531, option=[null, null, null, null, drop] +item=Iron fire arrows, id=2532, option=[null, Wield, null, null, drop] +item=Iron fire arrows, id=2533, option=[null, Wield, null, null, drop] +item=Steel fire arrows, id=2534, option=[null, Wield, null, null, drop] +item=Steel fire arrows, id=2535, option=[null, Wield, null, null, drop] +item=Mithril fire arrows, id=2536, option=[null, Wield, null, null, drop] +item=Mithril fire arrows, id=2537, option=[null, Wield, null, null, drop] +item=Addy fire arrows, id=2538, option=[null, Wield, null, null, drop] +item=Addy fire arrows, id=2539, option=[null, Wield, null, null, drop] +item=Rune fire arrows, id=2540, option=[null, Wield, null, null, drop] +item=Rune fire arrows, id=2541, option=[null, Wield, null, null, drop] +item=null, id=2542, option=[null, null, null, null, drop] +item=null, id=2543, option=[null, null, null, null, drop] +item=null, id=2544, option=[null, null, null, null, drop] +item=null, id=2545, option=[null, null, null, null, drop] +item=null, id=2546, option=[null, null, null, null, drop] +item=null, id=2547, option=[null, null, null, null, drop] +item=null, id=2548, option=[null, null, null, null, drop] +item=null, id=2549, option=[null, null, null, null, drop] +item=Ring of recoil, id=2550, option=[null, Wear, null, null, drop] +item=Ring of recoil, id=2551, option=[null, null, null, null, drop] +item=Ring of duelling(8), id=2552, option=[null, Wear, null, Rub, drop] +item=Ring of duelling(8), id=2553, option=[null, null, null, null, drop] +item=Ring of duelling(7), id=2554, option=[null, Wear, null, Rub, drop] +item=Ring of duelling(7), id=2555, option=[null, null, null, null, drop] +item=Ring of duelling(6), id=2556, option=[null, Wear, null, Rub, drop] +item=Ring of duelling(6), id=2557, option=[null, null, null, null, drop] +item=Ring of duelling(5), id=2558, option=[null, Wear, null, Rub, drop] +item=Ring of duelling(5), id=2559, option=[null, null, null, null, drop] +item=Ring of duelling(4), id=2560, option=[null, Wear, null, Rub, drop] +item=Ring of duelling(4), id=2561, option=[null, null, null, null, drop] +item=Ring of duelling(3), id=2562, option=[null, Wear, null, Rub, drop] +item=Ring of duelling(3), id=2563, option=[null, null, null, null, drop] +item=Ring of duelling(2), id=2564, option=[null, Wear, null, Rub, drop] +item=Ring of duelling(2), id=2565, option=[null, null, null, null, drop] +item=Ring of duelling(1), id=2566, option=[null, Wear, null, Rub, drop] +item=Ring of duelling(1), id=2567, option=[null, null, null, null, drop] +item=Ring of forging, id=2568, option=[null, Wear, null, null, drop] +item=Ring of forging, id=2569, option=[null, null, null, null, drop] +item=Ring of life, id=2570, option=[null, Wear, null, null, drop] +item=Ring of life, id=2571, option=[null, null, null, null, drop] +item=Ring of wealth, id=2572, option=[null, Wear, null, null, drop] +item=Ring of wealth, id=2573, option=[null, null, null, null, drop] +item=Sextant, id=2574, option=[Look through, null, null, null, drop] +item=Watch, id=2575, option=[null, null, null, null, drop] +item=Chart, id=2576, option=[null, null, null, null, drop] +item=Ranger boots, id=2577, option=[null, Wear, null, null, drop] +item=Ranger boots, id=2578, option=[null, null, null, null, drop] +item=Wizard boots, id=2579, option=[null, Wear, null, null, drop] +item=Wizard boots, id=2580, option=[null, null, null, null, drop] +item=Robin hood hat, id=2581, option=[null, Wear, null, null, drop] +item=Robin hood hat, id=2582, option=[null, null, null, null, drop] +item=Black platebody (t), id=2583, option=[null, Wear, null, null, drop] +item=Black platebody (t), id=2584, option=[null, null, null, null, drop] +item=Black platelegs (t), id=2585, option=[null, Wear, null, null, drop] +item=Black platelegs (t), id=2586, option=[null, null, null, null, drop] +item=Black full helm(t), id=2587, option=[null, Wear, null, null, drop] +item=Black full helm(t), id=2588, option=[null, null, null, null, drop] +item=Black kiteshield (t), id=2589, option=[null, Wear, null, null, drop] +item=Black kiteshield (t), id=2590, option=[null, null, null, null, drop] +item=Black platebody (g), id=2591, option=[null, Wear, null, null, drop] +item=Black platebody (g), id=2592, option=[null, null, null, null, drop] +item=Black platelegs (g), id=2593, option=[null, Wear, null, null, drop] +item=Black platelegs (g), id=2594, option=[null, null, null, null, drop] +item=Black full helm(g), id=2595, option=[null, Wear, null, null, drop] +item=Black full helm(g), id=2596, option=[null, null, null, null, drop] +item=Black kiteshield (g), id=2597, option=[null, Wear, null, null, drop] +item=Black kiteshield (g), id=2598, option=[null, null, null, null, drop] +item=Adam platebody (t), id=2599, option=[null, Wear, null, null, drop] +item=Adam platebody (t), id=2600, option=[null, null, null, null, drop] +item=Adam platelegs (t), id=2601, option=[null, Wear, null, null, drop] +item=Adam platelegs (t), id=2602, option=[null, null, null, null, drop] +item=Adam kiteshield (t), id=2603, option=[null, Wear, null, null, drop] +item=Adam kiteshield (t), id=2604, option=[null, null, null, null, drop] +item=Adam full helm(t), id=2605, option=[null, Wear, null, null, drop] +item=Adam full helm(t), id=2606, option=[null, null, null, null, drop] +item=Adam platebody (g), id=2607, option=[null, Wear, null, null, drop] +item=Adam platebody (g), id=2608, option=[null, null, null, null, drop] +item=Adam platelegs (g), id=2609, option=[null, Wear, null, null, drop] +item=Adam platelegs (g), id=2610, option=[null, null, null, null, drop] +item=Adam kiteshield (g), id=2611, option=[null, Wear, null, null, drop] +item=Adam kiteshield (g), id=2612, option=[null, null, null, null, drop] +item=Adam full helm(g), id=2613, option=[null, Wear, null, null, drop] +item=Adam full helm(g), id=2614, option=[null, null, null, null, drop] +item=Rune platebody (g), id=2615, option=[null, Wear, null, null, drop] +item=Rune platebody (g), id=2616, option=[null, null, null, null, drop] +item=Rune platelegs (g), id=2617, option=[null, Wear, null, null, drop] +item=Rune platelegs (g), id=2618, option=[null, null, null, null, drop] +item=Rune full helm(g), id=2619, option=[null, Wear, null, null, drop] +item=Rune full helm(g), id=2620, option=[null, null, null, null, drop] +item=Rune kiteshield (g), id=2621, option=[null, Wear, null, null, drop] +item=Rune kiteshield (g), id=2622, option=[null, null, null, null, drop] +item=Rune platebody (t), id=2623, option=[null, Wear, null, null, drop] +item=Rune platebody (t), id=2624, option=[null, null, null, null, drop] +item=Rune platelegs (t), id=2625, option=[null, Wear, null, null, drop] +item=Rune platelegs (t), id=2626, option=[null, null, null, null, drop] +item=Rune full helm (t), id=2627, option=[null, Wear, null, null, drop] +item=Rune full helm (t), id=2628, option=[null, null, null, null, drop] +item=Rune kiteshield (t), id=2629, option=[null, Wear, null, null, drop] +item=Rune kiteshield (t), id=2630, option=[null, null, null, null, drop] +item=Highwayman mask, id=2631, option=[null, Wear, null, null, drop] +item=Highwayman mask, id=2632, option=[null, null, null, null, drop] +item=Blue beret, id=2633, option=[null, Wear, null, null, drop] +item=Blue beret, id=2634, option=[null, null, null, null, drop] +item=Black beret, id=2635, option=[null, Wear, null, null, drop] +item=Black beret, id=2636, option=[null, null, null, null, drop] +item=White beret, id=2637, option=[null, Wear, null, null, drop] +item=White beret, id=2638, option=[null, null, null, null, drop] +item=Tan cavalier, id=2639, option=[null, Wear, null, null, drop] +item=Tan cavalier, id=2640, option=[null, null, null, null, drop] +item=Dark cavalier, id=2641, option=[null, Wear, null, null, drop] +item=Dark cavalier, id=2642, option=[null, null, null, null, drop] +item=Black cavalier, id=2643, option=[null, Wear, null, null, drop] +item=Black cavalier, id=2644, option=[null, null, null, null, drop] +item=Red headband, id=2645, option=[null, Wear, null, null, drop] +item=Red headband, id=2646, option=[null, null, null, null, drop] +item=Black headband, id=2647, option=[null, Wear, null, null, drop] +item=Black headband, id=2648, option=[null, null, null, null, drop] +item=Brown headband, id=2649, option=[null, Wear, null, null, drop] +item=Brown headband, id=2650, option=[null, null, null, null, drop] +item=Pirate's hat, id=2651, option=[null, Wear, null, null, drop] +item=Pirate's hat, id=2652, option=[null, null, null, null, drop] +item=Zamorak platebody, id=2653, option=[null, Wear, null, null, drop] +item=Zamorak platebody, id=2654, option=[null, null, null, null, drop] +item=Zamorak platelegs, id=2655, option=[null, Wear, null, null, drop] +item=Zamorak platelegs, id=2656, option=[null, null, null, null, drop] +item=Zamorak full helm, id=2657, option=[null, Wear, null, null, drop] +item=Zamorak full helm, id=2658, option=[null, null, null, null, drop] +item=Zamorak kiteshield, id=2659, option=[null, Wear, null, null, drop] +item=Zamorak kiteshield, id=2660, option=[null, null, null, null, drop] +item=Saradomin plate, id=2661, option=[null, Wear, null, null, drop] +item=Saradomin plate, id=2662, option=[null, null, null, null, drop] +item=Saradomin legs, id=2663, option=[null, Wear, null, null, drop] +item=Saradomin legs, id=2664, option=[null, null, null, null, drop] +item=Saradomin full helm, id=2665, option=[null, Wear, null, null, drop] +item=Saradomin full helm, id=2666, option=[null, null, null, null, drop] +item=Saradomin kite, id=2667, option=[null, Wear, null, null, drop] +item=Saradomin kite, id=2668, option=[null, null, null, null, drop] +item=Guthix platebody, id=2669, option=[null, Wear, null, null, drop] +item=Guthix platebody, id=2670, option=[null, null, null, null, drop] +item=Guthix platelegs, id=2671, option=[null, Wear, null, null, drop] +item=Guthix platelegs, id=2672, option=[null, null, null, null, drop] +item=Guthix full helm, id=2673, option=[null, Wear, null, null, drop] +item=Guthix full helm, id=2674, option=[null, null, null, null, drop] +item=Guthix kiteshield, id=2675, option=[null, Wear, null, null, drop] +item=Guthix kiteshield, id=2676, option=[null, null, null, null, drop] +item=Clue scroll, id=2677, option=[Read, null, null, null, drop] +item=Clue scroll, id=2678, option=[Read, null, null, null, drop] +item=Clue scroll, id=2679, option=[Read, null, null, null, drop] +item=Clue scroll, id=2680, option=[Read, null, null, null, drop] +item=Clue scroll, id=2681, option=[Read, null, null, null, drop] +item=Clue scroll, id=2682, option=[Read, null, null, null, drop] +item=Clue scroll, id=2683, option=[Read, null, null, null, drop] +item=Clue scroll, id=2684, option=[Read, null, null, null, drop] +item=Clue scroll, id=2685, option=[Read, null, null, null, drop] +item=Clue scroll, id=2686, option=[Read, null, null, null, drop] +item=Clue scroll, id=2687, option=[Read, null, null, null, drop] +item=Clue scroll, id=2688, option=[Read, null, null, null, drop] +item=Clue scroll, id=2689, option=[Read, null, null, null, drop] +item=Clue scroll, id=2690, option=[Read, null, null, null, drop] +item=Clue scroll, id=2691, option=[Read, null, null, null, drop] +item=Clue scroll, id=2692, option=[Read, null, null, null, drop] +item=Clue scroll, id=2693, option=[Read, null, null, null, drop] +item=Clue scroll, id=2694, option=[Read, null, null, null, drop] +item=Clue scroll, id=2695, option=[Read, null, null, null, drop] +item=Clue scroll, id=2696, option=[Read, null, null, null, drop] +item=Clue scroll, id=2697, option=[Read, null, null, null, drop] +item=Clue scroll, id=2698, option=[Read, null, null, null, drop] +item=Clue scroll, id=2699, option=[Read, null, null, null, drop] +item=Clue scroll, id=2700, option=[Read, null, null, null, drop] +item=Clue scroll, id=2701, option=[Read, null, null, null, drop] +item=Clue scroll, id=2702, option=[Read, null, null, null, drop] +item=Clue scroll, id=2703, option=[Read, null, null, null, drop] +item=Clue scroll, id=2704, option=[Read, null, null, null, drop] +item=Clue scroll, id=2705, option=[Read, null, null, null, drop] +item=Clue scroll, id=2706, option=[Read, null, null, null, drop] +item=Clue scroll, id=2707, option=[Read, null, null, null, drop] +item=Clue scroll, id=2708, option=[Read, null, null, null, drop] +item=Clue scroll, id=2709, option=[Read, null, null, null, drop] +item=Clue scroll, id=2710, option=[Read, null, null, null, drop] +item=Clue scroll, id=2711, option=[Read, null, null, null, drop] +item=Clue scroll, id=2712, option=[Read, null, null, null, drop] +item=Clue scroll, id=2713, option=[Read, null, null, null, drop] +item=Casket, id=2714, option=[Open, null, null, null, drop] +item=Casket, id=2715, option=[Open, null, null, null, drop] +item=Clue scroll, id=2716, option=[Read, null, null, null, drop] +item=Casket, id=2717, option=[Open, null, null, null, drop] +item=Casket, id=2718, option=[Open, null, null, null, drop] +item=Clue scroll, id=2719, option=[Read, null, null, null, drop] +item=Casket, id=2720, option=[Open, null, null, null, drop] +item=Casket, id=2721, option=[Open, null, null, null, drop] +item=Clue scroll, id=2722, option=[Read, null, null, null, drop] +item=Clue scroll, id=2723, option=[Read, null, null, null, drop] +item=Casket, id=2724, option=[Open, null, null, null, drop] +item=Clue scroll, id=2725, option=[Read, null, null, null, drop] +item=Casket, id=2726, option=[Open, null, null, null, drop] +item=Clue scroll, id=2727, option=[Read, null, null, null, drop] +item=Casket, id=2728, option=[Open, null, null, null, drop] +item=Clue scroll, id=2729, option=[Read, null, null, null, drop] +item=Casket, id=2730, option=[Open, null, null, null, drop] +item=Clue scroll, id=2731, option=[Read, null, null, null, drop] +item=Casket, id=2732, option=[Open, null, null, null, drop] +item=Clue scroll, id=2733, option=[Read, null, null, null, drop] +item=Casket, id=2734, option=[Open, null, null, null, drop] +item=Clue scroll, id=2735, option=[Read, null, null, null, drop] +item=Casket, id=2736, option=[Open, null, null, null, drop] +item=Clue scroll, id=2737, option=[Read, null, null, null, drop] +item=Casket, id=2738, option=[Open, null, null, null, drop] +item=Clue scroll, id=2739, option=[Read, null, null, null, drop] +item=Casket, id=2740, option=[Open, null, null, null, drop] +item=Clue scroll, id=2741, option=[Read, null, null, null, drop] +item=Casket, id=2742, option=[Open, null, null, null, drop] +item=Clue scroll, id=2743, option=[Read, null, null, null, drop] +item=Casket, id=2744, option=[Open, null, null, null, drop] +item=Clue scroll, id=2745, option=[Read, null, null, null, drop] +item=Casket, id=2746, option=[Open, null, null, null, drop] +item=Clue scroll, id=2747, option=[Read, null, null, null, drop] +item=Casket, id=2748, option=[Open, null, null, null, drop] +item=Sliding piece, id=2749, option=[null, null, null, null, Move] +item=Sliding piece, id=2750, option=[null, null, null, null, Move] +item=Sliding piece, id=2751, option=[null, null, null, null, Move] +item=Sliding piece, id=2752, option=[null, null, null, null, Move] +item=Sliding piece, id=2753, option=[null, null, null, null, Move] +item=Sliding piece, id=2754, option=[null, null, null, null, Move] +item=Sliding piece, id=2755, option=[null, null, null, null, Move] +item=Sliding piece, id=2756, option=[null, null, null, null, Move] +item=Sliding piece, id=2757, option=[null, null, null, null, Move] +item=Sliding piece, id=2758, option=[null, null, null, null, Move] +item=Sliding piece, id=2759, option=[null, null, null, null, Move] +item=Sliding piece, id=2760, option=[null, null, null, null, Move] +item=Sliding piece, id=2761, option=[null, null, null, null, Move] +item=Sliding piece, id=2762, option=[null, null, null, null, Move] +item=Sliding piece, id=2763, option=[null, null, null, null, Move] +item=Sliding piece, id=2764, option=[null, null, null, null, Move] +item=Sliding piece, id=2765, option=[null, null, null, null, Move] +item=Sliding piece, id=2766, option=[null, null, null, null, Move] +item=Sliding piece, id=2767, option=[null, null, null, null, Move] +item=Sliding piece, id=2768, option=[null, null, null, null, Move] +item=Sliding piece, id=2769, option=[null, null, null, null, Move] +item=Sliding piece, id=2770, option=[null, null, null, null, Move] +item=Sliding piece, id=2771, option=[null, null, null, null, Move] +item=Sliding piece, id=2772, option=[null, null, null, null, Move] +item=Clue scroll, id=2773, option=[Read, null, null, null, drop] +item=Clue scroll, id=2774, option=[Read, null, null, null, drop] +item=Casket, id=2775, option=[Open, null, null, null, drop] +item=Clue scroll, id=2776, option=[Read, null, null, null, drop] +item=Casket, id=2777, option=[Open, null, null, null, drop] +item=Clue scroll, id=2778, option=[Read, null, null, null, drop] +item=Casket, id=2779, option=[Open, null, null, null, drop] +item=Clue scroll, id=2780, option=[Read, null, null, null, drop] +item=Casket, id=2781, option=[Open, null, null, null, drop] +item=Clue scroll, id=2782, option=[Read, null, null, null, drop] +item=Clue scroll, id=2783, option=[Read, null, null, null, drop] +item=Casket, id=2784, option=[Open, null, null, null, drop] +item=Clue scroll, id=2785, option=[Read, null, null, null, drop] +item=Clue scroll, id=2786, option=[Read, null, null, null, drop] +item=Casket, id=2787, option=[Open, null, null, null, drop] +item=Clue scroll, id=2788, option=[Read, null, null, null, drop] +item=Casket, id=2789, option=[Open, null, null, null, drop] +item=Clue scroll, id=2790, option=[Read, null, null, null, drop] +item=Casket, id=2791, option=[Open, null, null, null, drop] +item=Clue scroll, id=2792, option=[Read, null, null, null, drop] +item=Clue scroll, id=2793, option=[Read, null, null, null, drop] +item=Clue scroll, id=2794, option=[Read, null, null, null, drop] +item=Puzzle box, id=2795, option=[Open, null, null, null, drop] +item=Clue scroll, id=2796, option=[Read, null, null, null, drop] +item=Clue scroll, id=2797, option=[Read, null, null, null, drop] +item=Puzzle box, id=2798, option=[Open, null, null, null, drop] +item=Clue scroll, id=2799, option=[Read, null, null, null, drop] +item=Puzzle box, id=2800, option=[Open, null, null, null, drop] +item=Clue scroll, id=2801, option=[Read, null, null, null, drop] +item=Casket, id=2802, option=[Open, null, null, null, drop] +item=Clue scroll, id=2803, option=[Read, null, null, null, drop] +item=Casket, id=2804, option=[Open, null, null, null, drop] +item=Clue scroll, id=2805, option=[Read, null, null, null, drop] +item=Casket, id=2806, option=[Open, null, null, null, drop] +item=Clue scroll, id=2807, option=[Read, null, null, null, drop] +item=Casket, id=2808, option=[Open, null, null, null, drop] +item=Clue scroll, id=2809, option=[Read, null, null, null, drop] +item=Casket, id=2810, option=[Open, null, null, null, drop] +item=Clue scroll, id=2811, option=[Read, null, null, null, drop] +item=Casket, id=2812, option=[Open, null, null, null, drop] +item=Clue scroll, id=2813, option=[Read, null, null, null, drop] +item=Casket, id=2814, option=[Open, null, null, null, drop] +item=Clue scroll, id=2815, option=[Read, null, null, null, drop] +item=Casket, id=2816, option=[Open, null, null, null, drop] +item=Clue scroll, id=2817, option=[Read, null, null, null, drop] +item=Casket, id=2818, option=[Open, null, null, null, drop] +item=Clue scroll, id=2819, option=[Read, null, null, null, drop] +item=Casket, id=2820, option=[Open, null, null, null, drop] +item=Clue scroll, id=2821, option=[Read, null, null, null, drop] +item=Casket, id=2822, option=[Open, null, null, null, drop] +item=Clue scroll, id=2823, option=[Read, null, null, null, drop] +item=Casket, id=2824, option=[Open, null, null, null, drop] +item=Clue scroll, id=2825, option=[Read, null, null, null, drop] +item=Casket, id=2826, option=[Open, null, null, null, drop] +item=Clue scroll, id=2827, option=[Read, null, null, null, drop] +item=Casket, id=2828, option=[Open, null, null, null, drop] +item=Clue scroll, id=2829, option=[Read, null, null, null, drop] +item=Casket, id=2830, option=[Open, null, null, null, drop] +item=Clue scroll, id=2831, option=[Read, null, null, null, drop] +item=Key, id=2832, option=[null, null, null, null, drop] +item=Clue scroll, id=2833, option=[Read, null, null, null, drop] +item=Key, id=2834, option=[null, null, null, null, drop] +item=Clue scroll, id=2835, option=[Read, null, null, null, drop] +item=Key, id=2836, option=[null, null, null, null, drop] +item=Clue scroll, id=2837, option=[Read, null, null, null, drop] +item=Key, id=2838, option=[null, null, null, null, drop] +item=Clue scroll, id=2839, option=[Read, null, null, null, drop] +item=Key, id=2840, option=[null, null, null, null, drop] +item=Clue scroll, id=2841, option=[Read, null, null, null, drop] +item=Challenge scroll, id=2842, option=[Read, null, null, null, drop] +item=Clue scroll, id=2843, option=[Read, null, null, null, drop] +item=Challenge scroll, id=2844, option=[Read, null, null, null, drop] +item=Clue scroll, id=2845, option=[Read, null, null, null, drop] +item=Challenge scroll, id=2846, option=[Read, null, null, null, drop] +item=Clue scroll, id=2847, option=[Read, null, null, null, drop] +item=Clue scroll, id=2848, option=[Read, null, null, null, drop] +item=Clue scroll, id=2849, option=[Read, null, null, null, drop] +item=Challenge scroll, id=2850, option=[Read, null, null, null, drop] +item=Clue scroll, id=2851, option=[Read, null, null, null, drop] +item=Challenge scroll, id=2852, option=[Read, null, null, null, drop] +item=Clue scroll, id=2853, option=[Read, null, null, null, drop] +item=Challenge scroll, id=2854, option=[Read, null, null, null, drop] +item=Clue scroll, id=2855, option=[Read, null, null, null, drop] +item=Clue scroll, id=2856, option=[Read, null, null, null, drop] +item=Clue scroll, id=2857, option=[Read, null, null, null, drop] +item=Clue scroll, id=2858, option=[Read, null, null, null, drop] +item=Wolf bones, id=2859, option=[Bury, null, null, null, drop] +item=Wolf bones, id=2860, option=[null, null, null, null, drop] +item=Wolfbone arrowtips, id=2861, option=[null, null, null, null, drop] +item=Achey tree logs, id=2862, option=[null, null, null, null, drop] +item=Achey tree logs, id=2863, option=[null, null, null, null, drop] +item=Ogre arrow shaft, id=2864, option=[null, null, null, null, drop] +item=Flighted ogre arrow, id=2865, option=[null, null, null, null, drop] +item=Ogre arrow, id=2866, option=[null, Wield, null, null, drop] +item=null, id=2867, option=[null, null, null, null, drop] +item=null, id=2868, option=[null, null, null, null, drop] +item=null, id=2869, option=[null, null, null, null, drop] +item=null, id=2870, option=[null, null, null, null, drop] +item=Ogre bellows, id=2871, option=[null, null, null, null, drop] +item=Ogre bellows (3), id=2872, option=[null, null, null, null, drop] +item=Ogre bellows (2), id=2873, option=[null, null, null, null, drop] +item=Ogre bellows (1), id=2874, option=[null, null, null, null, drop] +item=Bloated toad, id=2875, option=[Drop, null, null, Release All, Release] +item=Raw chompy, id=2876, option=[null, null, null, null, drop] +item=Raw chompy, id=2877, option=[null, null, null, null, drop] +item=Cooked chompy, id=2878, option=[Eat, null, null, null, drop] +item=Cooked chompy, id=2879, option=[null, null, null, null, drop] +item=Ruined chompy, id=2880, option=[null, null, null, null, drop] +item=Ruined chompy, id=2881, option=[null, null, null, null, drop] +item=Seasoned chompy, id=2882, option=[null, null, null, null, drop] +item=Ogre bow, id=2883, option=[null, Wield, Check kills, null, drop] +item=null, id=2884, option=[null, null, null, null, drop] +item=Whoopsie, id=2885, option=[Wear, null, null, null, drop] +item=Battered book, id=2886, option=[Read, null, null, null, drop] +item=Battered key, id=2887, option=[null, null, null, null, drop] +item=A stone bowl, id=2888, option=[null, null, null, null, drop] +item=A stone bowl, id=2889, option=[null, null, null, null, drop] +item=Elemental shield, id=2890, option=[null, Wield, null, null, drop] +item=Elemental shield, id=2891, option=[null, null, null, null, drop] +item=Elemental ore, id=2892, option=[null, null, null, null, drop] +item=Elemental metal, id=2893, option=[null, null, null, null, drop] +item=Boots, id=2894, option=[null, Wear, null, null, drop] +item=Boots, id=2895, option=[null, null, null, null, drop] +item=Robe top, id=2896, option=[null, Wear, null, null, drop] +item=Robe top, id=2897, option=[null, null, null, null, drop] +item=Robe bottoms, id=2898, option=[null, Wear, null, null, drop] +item=Robe bottoms, id=2899, option=[null, null, null, null, drop] +item=Hat, id=2900, option=[null, Wear, null, null, drop] +item=Hat, id=2901, option=[null, null, null, null, drop] +item=Gloves, id=2902, option=[null, Wear, null, null, drop] +item=Gloves, id=2903, option=[null, null, null, null, drop] +item=Boots, id=2904, option=[null, Wear, null, null, drop] +item=Boots, id=2905, option=[null, null, null, null, drop] +item=Robe top, id=2906, option=[null, Wear, null, null, drop] +item=Robe top, id=2907, option=[null, null, null, null, drop] +item=Robe bottoms, id=2908, option=[null, Wear, null, null, drop] +item=Robe bottoms, id=2909, option=[null, null, null, null, drop] +item=Hat, id=2910, option=[null, Wear, null, null, drop] +item=Hat, id=2911, option=[null, null, null, null, drop] +item=Gloves, id=2912, option=[null, Wear, null, null, drop] +item=Gloves, id=2913, option=[null, null, null, null, drop] +item=Boots, id=2914, option=[null, Wear, null, null, drop] +item=Boots, id=2915, option=[null, null, null, null, drop] +item=Robe top, id=2916, option=[null, Wear, null, null, drop] +item=Robe top, id=2917, option=[null, null, null, null, drop] +item=Robe bottoms, id=2918, option=[null, Wear, null, null, drop] +item=Robe bottoms, id=2919, option=[null, null, null, null, drop] +item=Hat, id=2920, option=[null, Wear, null, null, drop] +item=Hat, id=2921, option=[null, null, null, null, drop] +item=Gloves, id=2922, option=[null, Wear, null, null, drop] +item=Gloves, id=2923, option=[null, null, null, null, drop] +item=Boots, id=2924, option=[null, Wear, null, null, drop] +item=Boots, id=2925, option=[null, null, null, null, drop] +item=Robe top, id=2926, option=[null, Wear, null, null, drop] +item=Robe top, id=2927, option=[null, null, null, null, drop] +item=Robe bottoms, id=2928, option=[null, Wear, null, null, drop] +item=Robe bottoms, id=2929, option=[null, null, null, null, drop] +item=Hat, id=2930, option=[null, Wear, null, null, drop] +item=Hat, id=2931, option=[null, null, null, null, drop] +item=Gloves, id=2932, option=[null, Wear, null, null, drop] +item=Gloves, id=2933, option=[null, null, null, null, drop] +item=Boots, id=2934, option=[null, Wear, null, null, drop] +item=Boots, id=2935, option=[null, null, null, null, drop] +item=Robe top, id=2936, option=[null, Wear, null, null, drop] +item=Robe top, id=2937, option=[null, null, null, null, drop] +item=Robe bottoms, id=2938, option=[null, Wear, null, null, drop] +item=Robe bottoms, id=2939, option=[null, null, null, null, drop] +item=Hat, id=2940, option=[null, Wear, null, null, drop] +item=Hat, id=2941, option=[null, null, null, null, drop] +item=Gloves, id=2942, option=[null, Wear, null, null, drop] +item=Gloves, id=2943, option=[null, null, null, null, drop] +item=Golden key, id=2944, option=[null, null, null, null, drop] +item=Iron key, id=2945, option=[null, null, null, null, drop] +item=Golden tinderbox, id=2946, option=[null, null, null, null, drop] +item=Golden candle, id=2947, option=[null, null, null, null, drop] +item=Golden pot, id=2948, option=[null, null, null, null, drop] +item=Golden hammer, id=2949, option=[null, null, null, null, drop] +item=Golden feather, id=2950, option=[null, null, null, null, drop] +item=Golden needle, id=2951, option=[null, null, null, null, drop] +item=Wolfbane, id=2952, option=[null, Wield, null, null, drop] +item=Bucket of water, id=2953, option=[null, null, null, null, drop] +item=Bucket of water, id=2954, option=[null, null, null, null, drop] +item=Moonlight mead, id=2955, option=[Drink, null, null, null, drop] +item=Moonlight mead, id=2956, option=[null, null, null, null, drop] +item=Druid pouch, id=2957, option=[Fill, null, null, null, drop] +item=Druid pouch, id=2958, option=[Fill, null, null, null, drop] +item=Rotten food, id=2959, option=[null, null, null, null, drop] +item=Rotten food, id=2960, option=[null, null, null, null, drop] +item=Silver sickle, id=2961, option=[null, Wield, null, null, drop] +item=Silver sickle, id=2962, option=[null, null, null, null, drop] +item=Silver sickle(b), id=2963, option=[null, Wield, Cast Bloom, null, drop] +item=Washing bowl, id=2964, option=[null, null, null, null, drop] +item=Whoopsie, id=2965, option=[null, null, null, null, drop] +item=Mirror, id=2966, option=[null, null, null, null, drop] +item=Journal, id=2967, option=[Read, null, null, null, drop] +item=Druidic spell, id=2968, option=[Cast, null, null, null, drop] +item=A used spell, id=2969, option=[null, null, null, null, drop] +item=Mort myre fungus, id=2970, option=[null, null, null, null, drop] +item=Mort myre fungus, id=2971, option=[null, null, null, null, drop] +item=Mort myre stem, id=2972, option=[null, null, null, null, drop] +item=Mort myre stem, id=2973, option=[null, null, null, null, drop] +item=Mort myre pear, id=2974, option=[null, null, null, null, drop] +item=Mort myre pear, id=2975, option=[null, null, null, null, drop] +item=Sickle mould, id=2976, option=[null, null, null, null, drop] +item=Sickle mould, id=2977, option=[null, null, null, null, drop] +item=Chompy bird hat, id=2978, option=[null, Wear, null, null, drop] +item=Chompy bird hat, id=2979, option=[null, Wear, null, null, drop] +item=Chompy bird hat, id=2980, option=[null, Wear, null, null, drop] +item=Chompy bird hat, id=2981, option=[null, Wear, null, null, drop] +item=Chompy bird hat, id=2982, option=[null, Wear, null, null, drop] +item=Chompy bird hat, id=2983, option=[null, Wear, null, null, drop] +item=Chompy bird hat, id=2984, option=[null, Wear, null, null, drop] +item=Chompy bird hat, id=2985, option=[null, Wear, null, null, drop] +item=Chompy bird hat, id=2986, option=[null, Wear, null, null, drop] +item=Chompy bird hat, id=2987, option=[null, Wear, null, null, drop] +item=Chompy bird hat, id=2988, option=[null, Wear, null, null, drop] +item=Chompy bird hat, id=2989, option=[null, Wear, null, null, drop] +item=Chompy bird hat, id=2990, option=[null, Wear, null, null, drop] +item=Chompy bird hat, id=2991, option=[null, Wear, null, null, drop] +item=Chompy bird hat, id=2992, option=[null, Wear, null, null, drop] +item=Chompy bird hat, id=2993, option=[null, Wear, null, null, drop] +item=Chompy bird hat, id=2994, option=[null, Wear, null, null, drop] +item=Chompy bird hat, id=2995, option=[null, Wear, null, null, drop] +item=Agility arena ticket, id=2996, option=[null, null, null, null, drop] +item=Pirate's hook, id=2997, option=[null, Wear, null, null, drop] +item=Clean toadflax, id=2998, option=[null, null, null, null, drop] +item=Clean toadflax, id=2999, option=[null, null, null, null, drop] +item=Clean snapdragon, id=3000, option=[null, null, null, null, drop] +item=Clean snapdragon, id=3001, option=[null, null, null, null, drop] +item=Toadflax potion(unf), id=3002, option=[null, null, null, Empty, drop] +item=Toadflax potion(unf), id=3003, option=[null, null, null, null, drop] +item=Snapdragon potion(unf), id=3004, option=[null, null, null, Empty, drop] +item=Snapdragon potion(unf), id=3005, option=[null, null, null, null, drop] +item=Firework, id=3006, option=[null, null, null, Empty, drop] +item=Firework, id=3007, option=[null, null, null, null, drop] +item=Energy potion(4), id=3008, option=[Drink, null, null, Empty, drop] +item=Energy potion(4), id=3009, option=[null, null, null, null, drop] +item=Energy potion(3), id=3010, option=[Drink, null, null, Empty, drop] +item=Energy potion(3), id=3011, option=[null, null, null, null, drop] +item=Energy potion(2), id=3012, option=[Drink, null, null, Empty, drop] +item=Energy potion(2), id=3013, option=[null, null, null, null, drop] +item=Energy potion(1), id=3014, option=[Drink, null, null, Empty, drop] +item=Energy potion(1), id=3015, option=[null, null, null, null, drop] +item=Super energy(4), id=3016, option=[Drink, null, null, Empty, drop] +item=Super energy(4), id=3017, option=[null, null, null, null, drop] +item=Super energy(3), id=3018, option=[Drink, null, null, Empty, drop] +item=Super energy(3), id=3019, option=[null, null, null, null, drop] +item=Super energy(2), id=3020, option=[Drink, null, null, Empty, drop] +item=Super energy(2), id=3021, option=[null, null, null, null, drop] +item=Super energy(1), id=3022, option=[Drink, null, null, Empty, drop] +item=Super energy(1), id=3023, option=[null, null, null, null, drop] +item=Super restore(4), id=3024, option=[Drink, null, null, Empty, drop] +item=Super restore(4), id=3025, option=[null, null, null, null, drop] +item=Super restore(3), id=3026, option=[Drink, null, null, Empty, drop] +item=Super restore(3), id=3027, option=[null, null, null, null, drop] +item=Super restore(2), id=3028, option=[Drink, null, null, Empty, drop] +item=Super restore(2), id=3029, option=[null, null, null, null, drop] +item=Super restore(1), id=3030, option=[Drink, null, null, Empty, drop] +item=Super restore(1), id=3031, option=[null, null, null, null, drop] +item=Agility potion(4), id=3032, option=[Drink, null, null, Empty, drop] +item=Agility potion(4), id=3033, option=[null, null, null, null, drop] +item=Agility potion(3), id=3034, option=[Drink, null, null, Empty, drop] +item=Agility potion(3), id=3035, option=[null, null, null, null, drop] +item=Agility potion(2), id=3036, option=[Drink, null, null, Empty, drop] +item=Agility potion(2), id=3037, option=[null, null, null, null, drop] +item=Agility potion(1), id=3038, option=[Drink, null, null, Empty, drop] +item=Agility potion(1), id=3039, option=[null, null, null, null, drop] +item=Magic potion(4), id=3040, option=[Drink, null, null, Empty, drop] +item=Magic potion(4), id=3041, option=[null, null, null, null, drop] +item=Magic potion(3), id=3042, option=[Drink, null, null, Empty, drop] +item=Magic potion(3), id=3043, option=[null, null, null, null, drop] +item=Magic potion(2), id=3044, option=[Drink, null, null, Empty, drop] +item=Magic potion(2), id=3045, option=[null, null, null, null, drop] +item=Magic potion(1), id=3046, option=[Drink, null, null, Empty, drop] +item=Magic potion(1), id=3047, option=[null, null, null, null, drop] +item=Pirate's hook, id=3048, option=[null, null, null, null, drop] +item=Grimy toadflax, id=3049, option=[Clean, null, null, null, drop] +item=Grimy toadflax, id=3050, option=[null, null, null, null, drop] +item=Grimy snapdragon, id=3051, option=[Clean, null, null, null, drop] +item=Grimy snapdragon, id=3052, option=[null, null, null, null, drop] +item=Lava battlestaff, id=3053, option=[null, Wield, null, null, drop] +item=Mystic lava staff, id=3054, option=[null, Wield, null, null, drop] +item=Lava battlestaff, id=3055, option=[null, null, null, null, drop] +item=Mystic lava staff, id=3056, option=[null, null, null, null, drop] +item=Mime mask, id=3057, option=[null, Wear, null, null, drop] +item=Mime top, id=3058, option=[null, Wear, null, null, drop] +item=Mime legs, id=3059, option=[null, Wear, null, null, drop] +item=Mime gloves, id=3060, option=[null, Wear, null, null, drop] +item=Mime boots, id=3061, option=[null, Wear, null, null, drop] +item=Strange box, id=3062, option=[Open, null, null, null, drop] +item=null, id=3063, option=[null, null, null, null, drop] +item=Whoopsie, id=3064, option=[Wear, null, null, null, drop] +item=null, id=3065, option=[null, null, null, null, drop] +item=Whoopsie, id=3066, option=[Wear, null, null, null, drop] +item=null, id=3067, option=[null, null, null, null, drop] +item=Whoopsie, id=3068, option=[Wear, null, null, null, drop] +item=null, id=3069, option=[null, null, null, null, drop] +item=Whoopsie, id=3070, option=[Wear, null, null, null, drop] +item=null, id=3071, option=[null, null, null, null, drop] +item=Whoopsie, id=3072, option=[Wear, null, null, null, drop] +item=null, id=3073, option=[null, null, null, null, drop] +item=Whoopsie, id=3074, option=[Wear, null, null, null, drop] +item=null, id=3075, option=[null, null, null, null, drop] +item=Whoopsie, id=3076, option=[Wear, null, null, null, drop] +item=null, id=3077, option=[null, null, null, null, drop] +item=Whoopsie, id=3078, option=[Wear, null, null, null, drop] +item=null, id=3079, option=[null, null, null, null, drop] +item=Whoopsie, id=3080, option=[Wear, null, null, null, drop] +item=null, id=3081, option=[null, null, null, null, drop] +item=Whoopsie, id=3082, option=[Wear, null, null, null, drop] +item=null, id=3083, option=[null, null, null, null, drop] +item=Whoopsie, id=3084, option=[Wear, null, null, null, drop] +item=null, id=3085, option=[null, null, null, null, drop] +item=Whoopsie, id=3086, option=[Wear, null, null, null, drop] +item=null, id=3087, option=[null, null, null, null, drop] +item=Whoopsie, id=3088, option=[Wear, null, null, null, drop] +item=null, id=3089, option=[null, null, null, null, drop] +item=Whoopsie, id=3090, option=[Wear, null, null, null, drop] +item=null, id=3091, option=[null, null, null, null, drop] +item=Whoopsie, id=3092, option=[Wear, null, null, null, drop] +item=Black dart, id=3093, option=[null, Wield, null, null, drop] +item=Black dart(p), id=3094, option=[null, Wield, null, null, drop] +item=Bronze claws, id=3095, option=[null, Wear, null, null, drop] +item=Iron claws, id=3096, option=[null, Wear, null, null, drop] +item=Steel claws, id=3097, option=[null, Wear, null, null, drop] +item=Black claws, id=3098, option=[null, Wear, null, null, drop] +item=Mithril claws, id=3099, option=[null, Wear, null, null, drop] +item=Adamant claws, id=3100, option=[null, Wear, null, null, drop] +item=Rune claws, id=3101, option=[null, Wear, null, null, drop] +item=Combination, id=3102, option=[Read, null, null, null, drop] +item=Iou, id=3103, option=[Read, null, null, null, drop] +item=Secret way map, id=3104, option=[null, null, null, null, drop] +item=Climbing boots, id=3105, option=[null, Wear, null, null, drop] +item=Climbing boots, id=3106, option=[null, null, null, null, drop] +item=Spiked boots, id=3107, option=[null, Wear, null, null, drop] +item=Whoopsie, id=3108, option=[null, null, null, null, drop] +item=Stone ball, id=3109, option=[null, null, null, null, drop] +item=Stone ball, id=3110, option=[null, null, null, null, drop] +item=Stone ball, id=3111, option=[null, null, null, null, drop] +item=Stone ball, id=3112, option=[null, null, null, null, drop] +item=Stone ball, id=3113, option=[null, null, null, null, drop] +item=Certificate, id=3114, option=[null, null, null, null, drop] +item=Bronze claws, id=3115, option=[null, null, null, null, drop] +item=Iron claws, id=3116, option=[null, null, null, null, drop] +item=Steel claws, id=3117, option=[null, null, null, null, drop] +item=Black claws, id=3118, option=[null, null, null, null, drop] +item=Mithril claws, id=3119, option=[null, null, null, null, drop] +item=Adamant claws, id=3120, option=[null, null, null, null, drop] +item=Rune claws, id=3121, option=[null, null, null, null, drop] +item=Granite shield, id=3122, option=[null, Wear, null, null, drop] +item=Shaikahan bones, id=3123, option=[Bury, null, null, null, drop] +item=Shaikahan bones, id=3124, option=[null, null, null, null, drop] +item=Jogre bones, id=3125, option=[Bury, null, null, null, drop] +item=Jogre bones, id=3126, option=[null, null, null, null, drop] +item=Burnt jogre bones, id=3127, option=[Bury, null, null, null, drop] +item=Pasty jogre bones, id=3128, option=[Bury, null, null, null, drop] +item=Pasty jogre bones, id=3129, option=[Bury, null, null, null, drop] +item=Marinated j' bones, id=3130, option=[Bury, null, null, null, drop] +item=Pasty jogre bones, id=3131, option=[Bury, null, null, null, drop] +item=Pasty jogre bones, id=3132, option=[Bury, null, null, null, drop] +item=Marinated j' bones, id=3133, option=[Bury, null, null, null, drop] +item=Granite shield, id=3134, option=[null, null, null, null, drop] +item=Prison key, id=3135, option=[null, null, null, null, drop] +item=Cell key 1, id=3136, option=[null, null, null, null, drop] +item=Cell key 2, id=3137, option=[null, null, null, null, drop] +item=Potato cactus, id=3138, option=[null, null, null, null, drop] +item=Potato cactus, id=3139, option=[null, null, null, null, drop] +item=Dragon chainbody, id=3140, option=[null, Wear, null, null, drop] +item=Dragon chainbody, id=3141, option=[null, null, null, null, drop] +item=Raw karambwan, id=3142, option=[null, null, null, null, drop] +item=Raw karambwan, id=3143, option=[null, null, null, null, drop] +item=Cooked karambwan, id=3144, option=[Eat, null, null, null, drop] +item=Cooked karambwan, id=3145, option=[null, null, null, null, drop] +item=Poison karambwan, id=3146, option=[Eat, null, null, null, drop] +item=Cooked karambwan, id=3147, option=[null, null, null, null, drop] +item=Burnt karambwan, id=3148, option=[null, null, null, null, drop] +item=Burnt karambwan, id=3149, option=[null, null, null, null, drop] +item=Raw karambwanji, id=3150, option=[null, null, null, null, drop] +item=Karambwanji, id=3151, option=[Eat, null, null, null, drop] +item=Karambwan paste, id=3152, option=[null, null, null, null, drop] +item=Karambwan paste, id=3153, option=[null, null, null, null, drop] +item=Karambwan paste, id=3154, option=[null, null, null, null, drop] +item=Karambwanji paste, id=3155, option=[null, null, null, null, drop] +item=Karambwanji paste, id=3156, option=[null, null, null, null, drop] +item=Karambwan vessel, id=3157, option=[null, null, null, null, drop] +item=Karambwan vessel, id=3158, option=[null, null, null, null, drop] +item=Karambwan vessel, id=3159, option=[null, null, null, null, drop] +item=Karambwan vessel, id=3160, option=[null, null, null, null, drop] +item=Crafting manual, id=3161, option=[null, null, null, null, drop] +item=Sliced banana, id=3162, option=[Eat, null, null, null, drop] +item=Sliced banana, id=3163, option=[null, null, null, null, drop] +item=Karamjan rum, id=3164, option=[null, null, null, null, drop] +item=Karamjan rum, id=3165, option=[null, null, null, null, drop] +item=Monkey corpse, id=3166, option=[null, null, null, null, drop] +item=Monkey skin, id=3167, option=[null, null, null, null, drop] +item=Seaweed sandwich, id=3168, option=[Eat, null, null, null, drop] +item=Stuffed monkey, id=3169, option=[null, null, null, null, drop] +item=Bronze spear(kp), id=3170, option=[null, Wield, null, null, drop] +item=Iron spear(kp), id=3171, option=[null, Wield, null, null, drop] +item=Steel spear(kp), id=3172, option=[null, Wield, null, null, drop] +item=Mithril spear(kp), id=3173, option=[null, Wield, null, null, drop] +item=Adamant spear(kp), id=3174, option=[null, Wield, null, null, drop] +item=Rune spear(kp), id=3175, option=[null, Wield, null, null, drop] +item=Dragon spear(kp), id=3176, option=[null, Wield, null, null, drop] +item=Banana left, id=3177, option=[Eat, null, null, null, drop] +item=Banana left, id=3178, option=[null, null, null, null, drop] +item=Monkey bones, id=3179, option=[Bury, null, null, null, drop] +item=Monkey bones, id=3180, option=[Bury, null, null, null, drop] +item=Monkey bones, id=3181, option=[Bury, null, null, null, drop] +item=Monkey bones, id=3182, option=[Bury, null, null, null, drop] +item=Monkey bones, id=3183, option=[Bury, null, null, null, drop] +item=Monkey bones, id=3184, option=[null, null, null, null, drop] +item=Monkey bones, id=3185, option=[Bury, null, null, null, drop] +item=Monkey bones, id=3186, option=[Bury, null, null, null, drop] +item=Bones, id=3187, option=[Bury, null, null, null, drop] +item=Cleaning cloth, id=3188, option=[null, null, null, null, drop] +item=Cleaning cloth, id=3189, option=[null, null, null, null, drop] +item=Bronze halberd, id=3190, option=[null, Wield, null, null, drop] +item=Bronze halberd, id=3191, option=[null, null, null, null, drop] +item=Iron halberd, id=3192, option=[null, Wield, null, null, drop] +item=Iron halberd, id=3193, option=[null, null, null, null, drop] +item=Steel halberd, id=3194, option=[null, Wield, null, null, drop] +item=Steel halberd, id=3195, option=[null, null, null, null, drop] +item=Black halberd, id=3196, option=[null, Wield, null, null, drop] +item=Black halberd, id=3197, option=[null, null, null, null, drop] +item=Mithril halberd, id=3198, option=[null, Wield, null, null, drop] +item=Mithril halberd, id=3199, option=[null, null, null, null, drop] +item=Adamant halberd, id=3200, option=[null, Wield, null, null, drop] +item=Adamant halberd, id=3201, option=[null, null, null, null, drop] +item=Rune halberd, id=3202, option=[null, Wield, null, null, drop] +item=Rune halberd, id=3203, option=[null, null, null, null, drop] +item=Dragon halberd, id=3204, option=[null, Wield, null, null, drop] +item=Dragon halberd, id=3205, option=[null, null, null, null, drop] +item=King's message, id=3206, option=[Read, null, null, null, drop] +item=Iorwerths message, id=3207, option=[Read, null, null, null, drop] +item=Crystal pendant, id=3208, option=[null, Wear, null, null, drop] +item=Sulphur, id=3209, option=[null, null, null, null, drop] +item=Whoopsie, id=3210, option=[null, null, null, null, drop] +item=Limestone, id=3211, option=[null, null, null, null, drop] +item=Limestone, id=3212, option=[null, null, null, null, drop] +item=Quicklime, id=3213, option=[null, null, null, null, drop] +item=Pot of quicklime, id=3214, option=[null, null, null, null, drop] +item=Ground sulphur, id=3215, option=[null, null, null, null, drop] +item=Barrel, id=3216, option=[null, null, null, null, drop] +item=Barrel, id=3217, option=[null, null, null, null, drop] +item=Barrel bomb, id=3218, option=[null, null, null, null, drop] +item=Barrel bomb, id=3219, option=[null, null, null, null, drop] +item=Barrel of coal-tar, id=3220, option=[null, null, null, null, drop] +item=Barrel of naphtha, id=3221, option=[null, null, null, null, drop] +item=Naphtha mix, id=3222, option=[null, null, null, null, drop] +item=Naphtha mix, id=3223, option=[null, null, null, null, drop] +item=Strip of cloth, id=3224, option=[null, null, null, null, drop] +item=Whoopsie, id=3225, option=[null, null, null, null, drop] +item=Raw rabbit, id=3226, option=[null, null, null, null, drop] +item=Raw rabbit, id=3227, option=[null, null, null, null, drop] +item=Cooked rabbit, id=3228, option=[Eat, null, null, null, drop] +item=Cooked rabbit, id=3229, option=[null, null, null, null, drop] +item=Big book of bangs, id=3230, option=[Read, null, null, null, drop] +item=Symbol1, id=3231, option=[null, null, null, null, drop] +item=Symbol1, id=3232, option=[null, null, null, null, drop] +item=Symbol2, id=3233, option=[null, null, null, null, drop] +item=Symbol2, id=3234, option=[null, null, null, null, drop] +item=Symbol3, id=3235, option=[null, null, null, null, drop] +item=Symbol3, id=3236, option=[null, null, null, null, drop] +item=Symbol4, id=3237, option=[null, null, null, null, drop] +item=Symbol4, id=3238, option=[null, null, null, null, drop] +item=Bark, id=3239, option=[null, null, null, null, drop] +item=Bark, id=3240, option=[null, null, null, null, drop] +item=Man, id=3241, option=[null, null, null, null, drop] +item=Whoopsie, id=3242, option=[Wear, null, null, null, drop] +item=Farmer, id=3243, option=[null, null, null, null, drop] +item=Whoopsie, id=3244, option=[Wear, null, null, null, drop] +item=Warrior woman, id=3245, option=[null, null, null, null, drop] +item=Whoopsie, id=3246, option=[Wear, null, null, null, drop] +item=Rogue, id=3247, option=[null, null, null, null, drop] +item=Whoopsie, id=3248, option=[Wear, null, null, null, drop] +item=Guard, id=3249, option=[null, null, null, null, drop] +item=Whoopsie, id=3250, option=[Wear, null, null, null, drop] +item=Knight of ardougne, id=3251, option=[null, null, null, null, drop] +item=Whoopsie, id=3252, option=[Wear, null, null, null, drop] +item=Watchman, id=3253, option=[null, null, null, null, drop] +item=Whoopsie, id=3254, option=[Wear, null, null, null, drop] +item=Paladin, id=3255, option=[null, null, null, null, drop] +item=Whoopsie, id=3256, option=[Wear, null, null, null, drop] +item=Gnome, id=3257, option=[null, null, null, null, drop] +item=Whoopsie, id=3258, option=[Wear, null, null, null, drop] +item=Hero, id=3259, option=[null, null, null, null, drop] +item=Whoopsie, id=3260, option=[Wear, null, null, null, drop] +item=Goutweed, id=3261, option=[null, null, null, null, drop] +item=Troll thistle, id=3262, option=[null, null, null, null, drop] +item=Dried thistle, id=3263, option=[null, null, null, null, drop] +item=Ground thistle, id=3264, option=[null, null, null, null, drop] +item=Troll potion, id=3265, option=[null, null, null, null, drop] +item=Drunk parrot, id=3266, option=[null, null, null, null, drop] +item=Dirty robe, id=3267, option=[null, null, null, null, drop] +item=Fake man, id=3268, option=[null, null, null, null, drop] +item=Storeroom key, id=3269, option=[null, null, null, null, drop] +item=Alco-chunks, id=3270, option=[null, null, null, null, drop] +item=null, id=3271, option=[null, null, null, null, drop] +item=Whoopsie, id=3272, option=[Wear, null, null, null, drop] +item=null, id=3273, option=[null, null, null, null, drop] +item=null, id=3274, option=[null, null, null, null, drop] +item=null, id=3275, option=[null, null, null, null, drop] +item=null, id=3276, option=[null, null, null, null, drop] +item=null, id=3277, option=[null, null, null, null, drop] +item=null, id=3278, option=[null, null, null, null, drop] +item=null, id=3279, option=[null, null, null, null, drop] +item=null, id=3280, option=[null, null, null, null, drop] +item=null, id=3281, option=[null, null, null, null, drop] +item=null, id=3282, option=[null, null, null, null, drop] +item=null, id=3283, option=[null, null, null, null, drop] +item=null, id=3284, option=[null, null, null, null, drop] +item=null, id=3285, option=[null, null, null, null, drop] +item=null, id=3286, option=[null, null, null, null, drop] +item=null, id=3287, option=[null, null, null, null, drop] +item=null, id=3288, option=[null, null, null, null, drop] +item=null, id=3289, option=[null, null, null, null, drop] +item=null, id=3290, option=[null, null, null, null, drop] +item=null, id=3291, option=[null, null, null, null, drop] +item=null, id=3292, option=[null, null, null, null, drop] +item=null, id=3293, option=[null, null, null, null, drop] +item=null, id=3294, option=[null, null, null, null, drop] +item=null, id=3295, option=[null, null, null, null, drop] +item=null, id=3296, option=[null, null, null, null, drop] +item=null, id=3297, option=[null, null, null, null, drop] +item=null, id=3298, option=[null, null, null, null, drop] +item=null, id=3299, option=[null, null, null, null, drop] +item=null, id=3300, option=[null, null, null, null, drop] +item=null, id=3301, option=[null, null, null, null, drop] +item=null, id=3302, option=[null, null, null, null, drop] +item=null, id=3303, option=[null, null, null, null, drop] +item=null, id=3304, option=[null, null, null, null, drop] +item=null, id=3305, option=[null, null, null, null, drop] +item=null, id=3306, option=[null, null, null, null, drop] +item=null, id=3307, option=[null, null, null, null, drop] +item=null, id=3308, option=[null, null, null, null, drop] +item=null, id=3309, option=[null, null, null, null, drop] +item=null, id=3310, option=[null, null, null, null, drop] +item=null, id=3311, option=[null, null, null, null, drop] +item=null, id=3312, option=[null, null, null, null, drop] +item=null, id=3313, option=[null, null, null, null, drop] +item=null, id=3314, option=[null, null, null, null, drop] +item=null, id=3315, option=[null, null, null, null, drop] +item=null, id=3316, option=[null, null, null, null, drop] +item=null, id=3317, option=[null, null, null, null, drop] +item=null, id=3318, option=[null, null, null, null, drop] +item=null, id=3319, option=[null, null, null, null, drop] +item=null, id=3320, option=[null, null, null, null, drop] +item=null, id=3321, option=[null, null, null, null, drop] +item=null, id=3322, option=[null, null, null, null, drop] +item=null, id=3323, option=[null, null, null, null, drop] +item=null, id=3324, option=[null, null, null, null, drop] +item=Vampire dust, id=3325, option=[null, null, null, null, drop] +item=Vampire dust, id=3326, option=[null, null, null, null, drop] +item=Myre snelm, id=3327, option=[null, Wear, null, null, drop] +item=Myre snelm, id=3328, option=[null, null, null, null, drop] +item=Blood'n'tar snelm, id=3329, option=[null, Wear, null, null, drop] +item=Blood'n'tar snelm, id=3330, option=[null, null, null, null, drop] +item=Ochre snelm, id=3331, option=[null, Wear, null, null, drop] +item=Ochre snelm, id=3332, option=[null, null, null, null, drop] +item=Bruise blue snelm, id=3333, option=[null, Wear, null, null, drop] +item=Bruise blue snelm, id=3334, option=[null, null, null, null, drop] +item=Broken bark snelm, id=3335, option=[null, Wear, null, null, drop] +item=Broken bark snelm, id=3336, option=[null, null, null, null, drop] +item=Myre snelm, id=3337, option=[null, Wear, null, null, drop] +item=Myre snelm, id=3338, option=[null, null, null, null, drop] +item=Blood'n'tar snelm, id=3339, option=[null, Wear, null, null, drop] +item=Blood'n'tar snelm, id=3340, option=[null, null, null, null, drop] +item=Ochre snelm, id=3341, option=[null, Wear, null, null, drop] +item=Ochre snelm, id=3342, option=[null, null, null, null, drop] +item=Bruise blue snelm, id=3343, option=[null, Wear, null, null, drop] +item=Bruise blue snelm, id=3344, option=[null, null, null, null, drop] +item=Blamish myre shell, id=3345, option=[null, null, null, null, drop] +item=Blamish myre shell, id=3346, option=[null, null, null, null, drop] +item=Blamish red shell, id=3347, option=[null, null, null, null, drop] +item=Blamish red shell, id=3348, option=[null, null, null, null, drop] +item=Blamish ochre shell, id=3349, option=[null, null, null, null, drop] +item=Blamish ochre shell, id=3350, option=[null, null, null, null, drop] +item=Blamish blue shell, id=3351, option=[null, null, null, null, drop] +item=Blamish blue shell, id=3352, option=[null, null, null, null, drop] +item=Blamish bark shell, id=3353, option=[null, null, null, null, drop] +item=Blamish bark shell, id=3354, option=[null, null, null, null, drop] +item=Blamish myre shell, id=3355, option=[null, null, null, null, drop] +item=Blamish myre shell, id=3356, option=[null, null, null, null, drop] +item=Blamish red shell, id=3357, option=[null, null, null, null, drop] +item=Blamish red shell, id=3358, option=[null, null, null, null, drop] +item=Blamish ochre shell, id=3359, option=[null, null, null, null, drop] +item=Blamish ochre shell, id=3360, option=[null, null, null, null, drop] +item=Blamish blue shell, id=3361, option=[null, null, null, null, drop] +item=Blamish blue shell, id=3362, option=[null, null, null, null, drop] +item=Thin snail, id=3363, option=[null, null, null, null, drop] +item=Thin snail, id=3364, option=[null, null, null, null, drop] +item=Lean snail, id=3365, option=[null, null, null, null, drop] +item=Lean snail, id=3366, option=[null, null, null, null, drop] +item=Fat snail, id=3367, option=[null, null, null, null, drop] +item=Fat snail, id=3368, option=[null, null, null, null, drop] +item=Thin snail meat, id=3369, option=[Eat, null, null, null, drop] +item=Thin snail meat, id=3370, option=[null, null, null, null, drop] +item=Lean snail meat, id=3371, option=[Eat, null, null, null, drop] +item=Lean snail meat, id=3372, option=[null, null, null, null, drop] +item=Fat snail meat, id=3373, option=[Eat, null, null, null, drop] +item=Fat snail meat, id=3374, option=[null, null, null, null, drop] +item=Burnt snail, id=3375, option=[null, null, null, null, drop] +item=Burnt snail, id=3376, option=[null, null, null, null, drop] +item=Sample bottle, id=3377, option=[null, null, null, null, drop] +item=Sample bottle, id=3378, option=[null, null, null, null, drop] +item=Slimy eel, id=3379, option=[null, null, null, null, drop] +item=Slimy eel, id=3380, option=[null, null, null, null, drop] +item=Cooked slimy eel, id=3381, option=[Eat, null, null, null, drop] +item=Cooked slimy eel, id=3382, option=[null, null, null, null, drop] +item=Burnt eel, id=3383, option=[null, null, null, null, drop] +item=Whoopsie, id=3384, option=[null, null, null, null, drop] +item=Splitbark helm, id=3385, option=[null, Wear, null, null, drop] +item=Splitbark helm, id=3386, option=[null, null, null, null, drop] +item=Splitbark body, id=3387, option=[null, Wear, null, null, drop] +item=Splitbark body, id=3388, option=[null, null, null, null, drop] +item=Splitbark legs, id=3389, option=[null, Wear, null, null, drop] +item=Splitbark legs, id=3390, option=[null, null, null, null, drop] +item=Splitbark gauntlets, id=3391, option=[null, Wear, null, null, drop] +item=Splitbark gauntlets, id=3392, option=[null, null, null, null, drop] +item=Splitbark boots, id=3393, option=[null, Wear, null, null, drop] +item=Splitbark boots, id=3394, option=[null, null, null, null, drop] +item=Diary, id=3395, option=[Read, null, null, null, drop] +item=Loar remains, id=3396, option=[null, null, null, null, drop] +item=Loar remains, id=3397, option=[null, null, null, null, drop] +item=Phrin remains, id=3398, option=[null, null, null, null, drop] +item=Phrin remains, id=3399, option=[null, null, null, null, drop] +item=Riyl remains, id=3400, option=[null, null, null, null, drop] +item=Riyl remains, id=3401, option=[null, null, null, null, drop] +item=Asyn remains, id=3402, option=[null, null, null, null, drop] +item=Asyn remains, id=3403, option=[null, null, null, null, drop] +item=Fiyr remains, id=3404, option=[null, null, null, null, drop] +item=Fiyr remains, id=3405, option=[null, null, null, null, drop] +item=Ash potion(unf), id=3406, option=[null, null, null, null, drop] +item=Ash potion(unf), id=3407, option=[null, null, null, null, drop] +item=Serum 207 (4), id=3408, option=[null, null, null, Empty, drop] +item=Whoopsie, id=3409, option=[null, null, null, null, drop] +item=Serum 207 (3), id=3410, option=[null, null, null, Empty, drop] +item=Whoopsie, id=3411, option=[null, null, null, null, drop] +item=Serum 207 (2), id=3412, option=[null, null, null, Empty, drop] +item=Whoopsie, id=3413, option=[null, null, null, null, drop] +item=Serum 207 (1), id=3414, option=[null, null, null, Empty, drop] +item=Whoopsie, id=3415, option=[null, null, null, null, drop] +item=Serum 208 (4), id=3416, option=[null, null, null, Empty, drop] +item=Serum 208 (3), id=3417, option=[null, null, null, Empty, drop] +item=Serum 208 (2), id=3418, option=[null, null, null, Empty, drop] +item=Serum 208 (1), id=3419, option=[null, null, null, Empty, drop] +item=Limestone brick, id=3420, option=[null, null, null, null, drop] +item=Limestone brick, id=3421, option=[null, null, null, null, drop] +item=Olive oil(4), id=3422, option=[null, null, null, Empty, drop] +item=Olive oil(4), id=3423, option=[null, null, null, null, drop] +item=Olive oil(3), id=3424, option=[null, null, null, Empty, drop] +item=Olive oil(3), id=3425, option=[null, null, null, null, drop] +item=Olive oil(2), id=3426, option=[null, null, null, Empty, drop] +item=Olive oil(2), id=3427, option=[null, null, null, null, drop] +item=Olive oil(1), id=3428, option=[null, null, null, Empty, drop] +item=Olive oil(1), id=3429, option=[null, null, null, null, drop] +item=Sacred oil(4), id=3430, option=[null, null, null, Empty, drop] +item=Sacred oil(4), id=3431, option=[null, null, null, null, drop] +item=Sacred oil(3), id=3432, option=[null, null, null, Empty, drop] +item=Sacred oil(3), id=3433, option=[null, null, null, null, drop] +item=Sacred oil(2), id=3434, option=[null, null, null, Empty, drop] +item=Sacred oil(2), id=3435, option=[null, null, null, null, drop] +item=Sacred oil(1), id=3436, option=[null, null, null, Empty, drop] +item=Sacred oil(1), id=3437, option=[null, null, null, null, drop] +item=Pyre logs, id=3438, option=[null, null, null, null, drop] +item=Pyre logs, id=3439, option=[null, null, null, null, drop] +item=Oak pyre logs, id=3440, option=[null, null, null, null, drop] +item=Oak pyre logs, id=3441, option=[null, null, null, null, drop] +item=Willow pyre logs, id=3442, option=[null, null, null, null, drop] +item=Willow pyre logs, id=3443, option=[null, null, null, null, drop] +item=Maple pyre logs, id=3444, option=[null, null, null, null, drop] +item=Maple pyre logs, id=3445, option=[null, null, null, null, drop] +item=Yew pyre logs, id=3446, option=[null, null, null, null, drop] +item=Yew pyre logs, id=3447, option=[null, null, null, null, drop] +item=Magic pyre logs, id=3448, option=[null, null, null, null, drop] +item=Magic pyre logs, id=3449, option=[null, null, null, null, drop] +item=Bronze key red, id=3450, option=[null, null, null, null, drop] +item=Bronze key brown, id=3451, option=[null, null, null, null, drop] +item=Bronze key crimson, id=3452, option=[null, null, null, null, drop] +item=Bronze key black, id=3453, option=[null, null, null, null, drop] +item=Bronze key purple, id=3454, option=[null, null, null, null, drop] +item=Steel key red, id=3455, option=[null, null, null, null, drop] +item=Steel key brown, id=3456, option=[null, null, null, null, drop] +item=Steel key crimson, id=3457, option=[null, null, null, null, drop] +item=Steel key black, id=3458, option=[null, null, null, null, drop] +item=Steel key purple, id=3459, option=[null, null, null, null, drop] +item=Black key red, id=3460, option=[null, null, null, null, drop] +item=Black key brown, id=3461, option=[null, null, null, null, drop] +item=Black key crimson, id=3462, option=[null, null, null, null, drop] +item=Black key black, id=3463, option=[null, null, null, null, drop] +item=Black key purple, id=3464, option=[null, null, null, null, drop] +item=Silver key red, id=3465, option=[null, null, null, null, drop] +item=Silver key brown, id=3466, option=[null, null, null, null, drop] +item=Silver key crimson, id=3467, option=[null, null, null, null, drop] +item=Silver key black, id=3468, option=[null, null, null, null, drop] +item=Silver key purple, id=3469, option=[null, null, null, null, drop] +item=Fine cloth, id=3470, option=[null, null, null, null, drop] +item=Fine cloth, id=3471, option=[null, null, null, null, drop] +item=Black plateskirt (t), id=3472, option=[null, Wear, null, null, drop] +item=Black plateskirt (g), id=3473, option=[null, Wear, null, null, drop] +item=Adam plateskirt (t), id=3474, option=[null, Wear, null, null, drop] +item=Adam plateskirt (g), id=3475, option=[null, Wear, null, null, drop] +item=Rune plateskirt (g), id=3476, option=[null, Wear, null, null, drop] +item=Rune plateskirt (t), id=3477, option=[null, Wear, null, null, drop] +item=Zamorak plateskirt, id=3478, option=[null, Wear, null, null, drop] +item=Saradomin skirt, id=3479, option=[null, Wear, null, null, drop] +item=Guthix plateskirt, id=3480, option=[null, Wear, null, null, drop] +item=Gilded platebody, id=3481, option=[null, Wear, null, null, drop] +item=Gilded platebody, id=3482, option=[null, null, null, null, drop] +item=Gilded platelegs, id=3483, option=[null, Wear, null, null, drop] +item=Gilded platelegs, id=3484, option=[null, null, null, null, drop] +item=Gilded plateskirt, id=3485, option=[null, Wear, null, null, drop] +item=Gilded full helm, id=3486, option=[null, Wear, null, null, drop] +item=Gilded full helm, id=3487, option=[null, null, null, null, drop] +item=Gilded kiteshield, id=3488, option=[null, Wear, null, null, drop] +item=Gilded kiteshield, id=3489, option=[null, null, null, null, drop] +item=Clue scroll, id=3490, option=[Read, null, null, null, drop] +item=Clue scroll, id=3491, option=[Read, null, null, null, drop] +item=Clue scroll, id=3492, option=[Read, null, null, null, drop] +item=Clue scroll, id=3493, option=[Read, null, null, null, drop] +item=Clue scroll, id=3494, option=[Read, null, null, null, drop] +item=Clue scroll, id=3495, option=[Read, null, null, null, drop] +item=Clue scroll, id=3496, option=[Read, null, null, null, drop] +item=Clue scroll, id=3497, option=[Read, null, null, null, drop] +item=Clue scroll, id=3498, option=[Read, null, null, null, drop] +item=Clue scroll, id=3499, option=[Read, null, null, null, drop] +item=Clue scroll, id=3500, option=[Read, null, null, null, drop] +item=Clue scroll, id=3501, option=[Read, null, null, null, drop] +item=Clue scroll, id=3502, option=[Read, null, null, null, drop] +item=Clue scroll, id=3503, option=[Read, null, null, null, drop] +item=Clue scroll, id=3504, option=[Read, null, null, null, drop] +item=Clue scroll, id=3505, option=[Read, null, null, null, drop] +item=Clue scroll, id=3506, option=[Read, null, null, null, drop] +item=Clue scroll, id=3507, option=[Read, null, null, null, drop] +item=Clue scroll, id=3508, option=[Read, null, null, null, drop] +item=Clue scroll, id=3509, option=[Read, null, null, null, drop] +item=Clue scroll, id=3510, option=[Read, null, null, null, drop] +item=Casket, id=3511, option=[Open, null, null, null, drop] +item=Clue scroll, id=3512, option=[Read, null, null, null, drop] +item=Clue scroll, id=3513, option=[Read, null, null, null, drop] +item=Clue scroll, id=3514, option=[Read, null, null, null, drop] +item=Clue scroll, id=3515, option=[Read, null, null, null, drop] +item=Clue scroll, id=3516, option=[Read, null, null, null, drop] +item=Casket, id=3517, option=[Open, null, null, null, drop] +item=Clue scroll, id=3518, option=[Read, null, null, null, drop] +item=Casket, id=3519, option=[Open, null, null, null, drop] +item=Clue scroll, id=3520, option=[Read, null, null, null, drop] +item=Casket, id=3521, option=[Open, null, null, null, drop] +item=Clue scroll, id=3522, option=[Read, null, null, null, drop] +item=Casket, id=3523, option=[Open, null, null, null, drop] +item=Clue scroll, id=3524, option=[Read, null, null, null, drop] +item=Clue scroll, id=3525, option=[Read, null, null, null, drop] +item=Clue scroll, id=3526, option=[Read, null, null, null, drop] +item=Casket, id=3527, option=[Open, null, null, null, drop] +item=Clue scroll, id=3528, option=[Read, null, null, null, drop] +item=Casket, id=3529, option=[Open, null, null, null, drop] +item=Clue scroll, id=3530, option=[Read, null, null, null, drop] +item=Casket, id=3531, option=[Open, null, null, null, drop] +item=Clue scroll, id=3532, option=[Read, null, null, null, drop] +item=Casket, id=3533, option=[Open, null, null, null, drop] +item=Clue scroll, id=3534, option=[Read, null, null, null, drop] +item=Casket, id=3535, option=[Open, null, null, null, drop] +item=Clue scroll, id=3536, option=[Read, null, null, null, drop] +item=Casket, id=3537, option=[Open, null, null, null, drop] +item=Clue scroll, id=3538, option=[Read, null, null, null, drop] +item=Casket, id=3539, option=[Open, null, null, null, drop] +item=Clue scroll, id=3540, option=[Read, null, null, null, drop] +item=Casket, id=3541, option=[Open, null, null, null, drop] +item=Clue scroll, id=3542, option=[Read, null, null, null, drop] +item=Casket, id=3543, option=[Open, null, null, null, drop] +item=Clue scroll, id=3544, option=[Read, null, null, null, drop] +item=Casket, id=3545, option=[Open, null, null, null, drop] +item=Clue scroll, id=3546, option=[Read, null, null, null, drop] +item=Casket, id=3547, option=[Open, null, null, null, drop] +item=Clue scroll, id=3548, option=[Read, null, null, null, drop] +item=Casket, id=3549, option=[Open, null, null, null, drop] +item=Clue scroll, id=3550, option=[Read, null, null, null, drop] +item=Casket, id=3551, option=[Open, null, null, null, drop] +item=Clue scroll, id=3552, option=[Read, null, null, null, drop] +item=Casket, id=3553, option=[Open, null, null, null, drop] +item=Clue scroll, id=3554, option=[Read, null, null, null, drop] +item=Casket, id=3555, option=[Open, null, null, null, drop] +item=Clue scroll, id=3556, option=[Read, null, null, null, drop] +item=Casket, id=3557, option=[Open, null, null, null, drop] +item=Clue scroll, id=3558, option=[Read, null, null, null, drop] +item=Casket, id=3559, option=[Open, null, null, null, drop] +item=Clue scroll, id=3560, option=[Read, null, null, null, drop] +item=Casket, id=3561, option=[Open, null, null, null, drop] +item=Clue scroll, id=3562, option=[Read, null, null, null, drop] +item=Casket, id=3563, option=[Open, null, null, null, drop] +item=Clue scroll, id=3564, option=[Read, null, null, null, drop] +item=Puzzle box, id=3565, option=[Open, null, null, null, drop] +item=Clue scroll, id=3566, option=[Read, null, null, null, drop] +item=Puzzle box, id=3567, option=[Open, null, null, null, drop] +item=Clue scroll, id=3568, option=[Read, null, null, null, drop] +item=Puzzle box, id=3569, option=[Open, null, null, null, drop] +item=Clue scroll, id=3570, option=[Read, null, null, null, drop] +item=Puzzle box, id=3571, option=[Open, null, null, null, drop] +item=Clue scroll, id=3572, option=[Read, null, null, null, drop] +item=Clue scroll, id=3573, option=[Read, null, null, null, drop] +item=Clue scroll, id=3574, option=[Read, null, null, null, drop] +item=Clue scroll, id=3575, option=[Read, null, null, null, drop] +item=Puzzle box, id=3576, option=[Open, null, null, null, drop] +item=Clue scroll, id=3577, option=[Read, null, null, null, drop] +item=Puzzle box, id=3578, option=[Open, null, null, null, drop] +item=Clue scroll, id=3579, option=[Read, null, null, null, drop] +item=Clue scroll, id=3580, option=[Read, null, null, null, drop] +item=Casket, id=3581, option=[Open, null, null, null, drop] +item=Clue scroll, id=3582, option=[Read, null, null, null, drop] +item=Casket, id=3583, option=[Open, null, null, null, drop] +item=Clue scroll, id=3584, option=[Read, null, null, null, drop] +item=Casket, id=3585, option=[Open, null, null, null, drop] +item=Clue scroll, id=3586, option=[Read, null, null, null, drop] +item=Casket, id=3587, option=[Open, null, null, null, drop] +item=Clue scroll, id=3588, option=[Read, null, null, null, drop] +item=Casket, id=3589, option=[Open, null, null, null, drop] +item=Clue scroll, id=3590, option=[Read, null, null, null, drop] +item=Casket, id=3591, option=[Open, null, null, null, drop] +item=Clue scroll, id=3592, option=[Read, null, null, null, drop] +item=Casket, id=3593, option=[Open, null, null, null, drop] +item=Clue scroll, id=3594, option=[Read, null, null, null, drop] +item=Casket, id=3595, option=[Open, null, null, null, drop] +item=Clue scroll, id=3596, option=[Read, null, null, null, drop] +item=Casket, id=3597, option=[Open, null, null, null, drop] +item=Clue scroll, id=3598, option=[Read, null, null, null, drop] +item=Clue scroll, id=3599, option=[Read, null, null, null, drop] +item=Casket, id=3600, option=[Open, null, null, null, drop] +item=Clue scroll, id=3601, option=[Read, null, null, null, drop] +item=Clue scroll, id=3602, option=[Read, null, null, null, drop] +item=Casket, id=3603, option=[Open, null, null, null, drop] +item=Clue scroll, id=3604, option=[Read, null, null, null, drop] +item=Clue scroll, id=3605, option=[Read, null, null, null, drop] +item=Key, id=3606, option=[null, null, null, null, drop] +item=Clue scroll, id=3607, option=[Read, null, null, null, drop] +item=Key, id=3608, option=[null, null, null, null, drop] +item=Clue scroll, id=3609, option=[Read, null, null, null, drop] +item=Clue scroll, id=3610, option=[Read, null, null, null, drop] +item=Clue scroll, id=3611, option=[Read, null, null, null, drop] +item=Clue scroll, id=3612, option=[Read, null, null, null, drop] +item=Clue scroll, id=3613, option=[Read, null, null, null, drop] +item=Clue scroll, id=3614, option=[Read, null, null, null, drop] +item=Clue scroll, id=3615, option=[Read, null, null, null, drop] +item=Clue scroll, id=3616, option=[Read, null, null, null, drop] +item=Clue scroll, id=3617, option=[Read, null, null, null, drop] +item=Clue scroll, id=3618, option=[Read, null, null, null, drop] +item=Sliding piece, id=3619, option=[null, null, null, null, Move] +item=Sliding piece, id=3620, option=[null, null, null, null, Move] +item=Sliding piece, id=3621, option=[null, null, null, null, Move] +item=Sliding piece, id=3622, option=[null, null, null, null, Move] +item=Sliding piece, id=3623, option=[null, null, null, null, Move] +item=Sliding piece, id=3624, option=[null, null, null, null, Move] +item=Sliding piece, id=3625, option=[null, null, null, null, Move] +item=Sliding piece, id=3626, option=[null, null, null, null, Move] +item=Sliding piece, id=3627, option=[null, null, null, null, Move] +item=Sliding piece, id=3628, option=[null, null, null, null, Move] +item=Sliding piece, id=3629, option=[null, null, null, null, Move] +item=Sliding piece, id=3630, option=[null, null, null, null, Move] +item=Sliding piece, id=3631, option=[null, null, null, null, Move] +item=Sliding piece, id=3632, option=[null, null, null, null, Move] +item=Sliding piece, id=3633, option=[null, null, null, null, Move] +item=Sliding piece, id=3634, option=[null, null, null, null, Move] +item=Sliding piece, id=3635, option=[null, null, null, null, Move] +item=Sliding piece, id=3636, option=[null, null, null, null, Move] +item=Sliding piece, id=3637, option=[null, null, null, null, Move] +item=Sliding piece, id=3638, option=[null, null, null, null, Move] +item=Sliding piece, id=3639, option=[null, null, null, null, Move] +item=Sliding piece, id=3640, option=[null, null, null, null, Move] +item=Sliding piece, id=3641, option=[null, null, null, null, Move] +item=Sliding piece, id=3642, option=[null, null, null, null, Move] +item=Sliding piece, id=3643, option=[null, null, null, null, Move] +item=Sliding piece, id=3644, option=[null, null, null, null, Move] +item=Sliding piece, id=3645, option=[null, null, null, null, Move] +item=Sliding piece, id=3646, option=[null, null, null, null, Move] +item=Sliding piece, id=3647, option=[null, null, null, null, Move] +item=Sliding piece, id=3648, option=[null, null, null, null, Move] +item=Sliding piece, id=3649, option=[null, null, null, null, Move] +item=Sliding piece, id=3650, option=[null, null, null, null, Move] +item=Sliding piece, id=3651, option=[null, null, null, null, Move] +item=Sliding piece, id=3652, option=[null, null, null, null, Move] +item=Sliding piece, id=3653, option=[null, null, null, null, Move] +item=Sliding piece, id=3654, option=[null, null, null, null, Move] +item=Sliding piece, id=3655, option=[null, null, null, null, Move] +item=Sliding piece, id=3656, option=[null, null, null, null, Move] +item=Sliding piece, id=3657, option=[null, null, null, null, Move] +item=Sliding piece, id=3658, option=[null, null, null, null, Move] +item=Sliding piece, id=3659, option=[null, null, null, null, Move] +item=Sliding piece, id=3660, option=[null, null, null, null, Move] +item=Sliding piece, id=3661, option=[null, null, null, null, Move] +item=Sliding piece, id=3662, option=[null, null, null, null, Move] +item=Sliding piece, id=3663, option=[null, null, null, null, Move] +item=Sliding piece, id=3664, option=[null, null, null, null, Move] +item=Sliding piece, id=3665, option=[null, null, null, null, Move] +item=Sliding piece, id=3666, option=[null, null, null, null, Move] +item=Lifeboat, id=3667, option=[Wear, null, null, null, drop] +item=Black plateskirt (t), id=3668, option=[null, null, null, null, drop] +item=Black plateskirt (g), id=3669, option=[null, null, null, null, drop] +item=Adam plateskirt (t), id=3670, option=[null, null, null, null, drop] +item=Adam plateskirt (g), id=3671, option=[null, null, null, null, drop] +item=Rune plateskirt (g), id=3672, option=[null, null, null, null, drop] +item=Rune plateskirt (t), id=3673, option=[null, null, null, null, drop] +item=Zamorak plateskirt, id=3674, option=[null, null, null, null, drop] +item=Saradomin skirt, id=3675, option=[null, null, null, null, drop] +item=Guthix plateskirt, id=3676, option=[null, null, null, null, drop] +item=Gilded plateskirt, id=3677, option=[null, null, null, null, drop] +item=Flamtaer hammer, id=3678, option=[null, null, null, null, drop] +item=Whoopsie, id=3679, option=[null, null, null, null, drop] +item=Shoe, id=3680, option=[null, null, null, null, drop] +item=Shoe, id=3681, option=[null, null, null, null, drop] +item=Shoe, id=3682, option=[null, null, null, null, drop] +item=Shoe, id=3683, option=[null, null, null, null, drop] +item=Shoe, id=3684, option=[null, null, null, null, drop] +item=Shoe., id=3685, option=[null, null, null, null, drop] +item=Fremennik, id=3686, option=[null, null, null, null, drop] +item=Whoopsie, id=3687, option=[Wear, null, null, null, drop] +item=Unstrung lyre, id=3688, option=[null, null, null, null, drop] +item=Lyre, id=3689, option=[Play, null, null, null, drop] +item=Enchanted lyre, id=3690, option=[Play, null, null, null, drop] +item=Enchanted lyre(1), id=3691, option=[Play, null, null, null, drop] +item=Branch, id=3692, option=[null, null, null, null, drop] +item=Golden fleece, id=3693, option=[null, null, null, null, drop] +item=Golden wool, id=3694, option=[null, null, null, null, drop] +item=Pet rock, id=3695, option=[Interact, Wield, null, null, drop] +item=Hunters' talisman, id=3696, option=[Locate, null, null, null, drop] +item=Hunters' talisman, id=3697, option=[Locate, null, null, null, drop] +item=Exotic flower, id=3698, option=[null, null, null, null, Destroy] +item=Fremennik ballad, id=3699, option=[null, null, null, null, drop] +item=Sturdy boots, id=3700, option=[null, null, null, null, drop] +item=Tracking map, id=3701, option=[null, null, null, null, drop] +item=Custom bow string, id=3702, option=[null, null, null, null, drop] +item=Unusual fish, id=3703, option=[null, null, null, null, drop] +item=Sea fishing map, id=3704, option=[null, null, null, null, drop] +item=Weather forecast, id=3705, option=[null, null, null, null, drop] +item=Champions token, id=3706, option=[null, null, null, null, drop] +item=Legendary cocktail, id=3707, option=[null, null, null, null, drop] +item=Fiscal statement, id=3708, option=[null, null, null, null, drop] +item=Promissory note, id=3709, option=[null, null, null, null, drop] +item=Warriors' contract, id=3710, option=[null, null, null, null, drop] +item=Keg of beer, id=3711, option=[null, null, null, null, drop] +item=Low alcohol keg, id=3712, option=[null, null, null, null, drop] +item=Strange object, id=3713, option=[null, null, null, null, drop] +item=Lit strange object, id=3714, option=[null, null, null, null, drop] +item=Red disk, id=3715, option=[null, null, null, null, drop] +item=Red disk, id=3716, option=[null, null, null, null, drop] +item=null, id=3717, option=[null, null, null, null, drop] +item=Magnet, id=3718, option=[null, null, null, null, drop] +item=Blue thread, id=3719, option=[null, null, null, null, drop] +item=Small pick, id=3720, option=[null, null, null, null, drop] +item=Toy ship, id=3721, option=[null, null, null, null, drop] +item=Full bucket, id=3722, option=[null, null, null, null, Destroy] +item=4/5ths full bucket, id=3723, option=[null, null, null, null, Destroy] +item=3/5ths full bucket, id=3724, option=[null, null, null, null, Destroy] +item=2/5ths full bucket, id=3725, option=[null, null, null, null, Destroy] +item=1/5ths full bucket, id=3726, option=[null, null, null, null, Destroy] +item=Empty bucket, id=3727, option=[null, null, null, null, Destroy] +item=Frozen bucket, id=3728, option=[null, null, null, null, Destroy] +item=Full jug, id=3729, option=[null, null, null, null, Destroy] +item=2/3rds full jug, id=3730, option=[null, null, null, null, Destroy] +item=1/3rds full jug, id=3731, option=[null, null, null, null, Destroy] +item=Empty jug, id=3732, option=[null, null, null, null, Destroy] +item=Frozen jug, id=3733, option=[null, null, null, null, Destroy] +item=Vase, id=3734, option=[Shake, null, null, null, drop] +item=Vase of water, id=3735, option=[Shake, null, null, null, drop] +item=Frozen vase, id=3736, option=[Shake, null, null, null, drop] +item=Vase lid, id=3737, option=[null, null, null, null, drop] +item=Sealed vase, id=3738, option=[Remove-lid, null, null, null, drop] +item=Sealed vase, id=3739, option=[Remove-lid, null, null, null, drop] +item=Sealed vase, id=3740, option=[Remove-lid, null, null, null, drop] +item=Frozen key, id=3741, option=[null, null, null, null, drop] +item=Red herring, id=3742, option=[null, null, null, null, drop] +item=Red disk, id=3743, option=[null, null, null, null, drop] +item=Wooden disk, id=3744, option=[null, null, null, null, drop] +item=Seer's key, id=3745, option=[null, null, null, null, drop] +item=Sticky red goop, id=3746, option=[null, null, null, null, drop] +item=Sticky red goop, id=3747, option=[null, null, null, null, drop] +item=Fremennik helm, id=3748, option=[null, Wear, null, null, drop] +item=Archer helm, id=3749, option=[null, Wear, null, null, drop] +item=Archer helm, id=3750, option=[null, null, null, null, drop] +item=Berserker helm, id=3751, option=[null, Wear, null, null, drop] +item=Berserker helm, id=3752, option=[null, null, null, null, drop] +item=Warrior helm, id=3753, option=[null, Wear, null, null, drop] +item=Warrior helm, id=3754, option=[null, null, null, null, drop] +item=Farseer helm, id=3755, option=[null, Wear, null, null, drop] +item=Farseer helm, id=3756, option=[null, null, null, null, drop] +item=Fremennik blade, id=3757, option=[null, Wield, null, null, drop] +item=Fremennik shield, id=3758, option=[null, Wield, null, null, drop] +item=Fremennik cloak, id=3759, option=[null, Wear, null, null, drop] +item=Fremennik cloak, id=3760, option=[null, null, null, null, drop] +item=Fremennik cloak, id=3761, option=[null, Wear, null, null, drop] +item=Fremennik cloak, id=3762, option=[null, null, null, null, drop] +item=Fremennik cloak, id=3763, option=[null, Wear, null, null, drop] +item=Fremennik cloak, id=3764, option=[null, null, null, null, drop] +item=Fremennik cloak, id=3765, option=[null, Wear, null, null, drop] +item=Fremennik cloak, id=3766, option=[null, null, null, null, drop] +item=Fremennik shirt, id=3767, option=[null, Wear, null, null, drop] +item=Fremennik shirt, id=3768, option=[null, null, null, null, drop] +item=Fremennik shirt, id=3769, option=[null, Wear, null, null, drop] +item=Fremennik shirt, id=3770, option=[null, null, null, null, drop] +item=Fremennik shirt, id=3771, option=[null, Wear, null, null, drop] +item=Fremennik shirt, id=3772, option=[null, null, null, null, drop] +item=Fremennik shirt, id=3773, option=[null, Wear, null, null, drop] +item=Fremennik shirt, id=3774, option=[null, null, null, null, drop] +item=Fremennik shirt, id=3775, option=[null, Wear, null, null, drop] +item=Fremennik shirt, id=3776, option=[null, null, null, null, drop] +item=Fremennik cloak, id=3777, option=[null, Wear, null, null, drop] +item=Fremennik cloak, id=3778, option=[null, null, null, null, drop] +item=Fremennik cloak, id=3779, option=[null, Wear, null, null, drop] +item=Fremennik cloak, id=3780, option=[null, null, null, null, drop] +item=Fremennik cloak, id=3781, option=[null, Wear, null, null, drop] +item=Fremennik cloak, id=3782, option=[null, null, null, null, drop] +item=Fremennik cloak, id=3783, option=[null, Wear, null, null, drop] +item=Fremennik cloak, id=3784, option=[null, null, null, null, drop] +item=Fremennik cloak, id=3785, option=[null, Wear, null, null, drop] +item=Fremennik cloak, id=3786, option=[null, null, null, null, drop] +item=Fremennik cloak, id=3787, option=[null, Wear, null, null, drop] +item=Fremennik cloak, id=3788, option=[null, null, null, null, drop] +item=Fremennik cloak, id=3789, option=[null, Wear, null, null, drop] +item=Fremennik cloak, id=3790, option=[null, null, null, null, drop] +item=Fremennik boots, id=3791, option=[null, Wear, null, null, drop] +item=Fremennik boots, id=3792, option=[null, null, null, null, drop] +item=Fremennik robe, id=3793, option=[null, Wear, null, null, drop] +item=Fremennik robe, id=3794, option=[null, null, null, null, drop] +item=Fremennik skirt, id=3795, option=[null, Wear, null, null, drop] +item=Fremennik skirt, id=3796, option=[null, null, null, null, drop] +item=Fremennik hat, id=3797, option=[null, Wear, null, null, drop] +item=Fremennik hat, id=3798, option=[null, null, null, null, drop] +item=Gloves, id=3799, option=[null, Wear, null, null, drop] +item=Gloves, id=3800, option=[null, null, null, null, drop] +item=Keg of beer, id=3801, option=[Drink, null, null, null, drop] +item=Keg of beer, id=3802, option=[null, null, null, null, drop] +item=Beer, id=3803, option=[Drink, null, null, null, drop] +item=Beer, id=3804, option=[null, null, null, null, drop] +item=Tankard, id=3805, option=[null, null, null, null, drop] +item=Tankard, id=3806, option=[null, null, null, null, drop] +item=null, id=3807, option=[null, null, null, null, drop] +item=null, id=3808, option=[null, null, null, null, drop] +item=null, id=3809, option=[null, null, null, null, drop] +item=null, id=3810, option=[null, null, null, null, drop] +item=null, id=3811, option=[null, null, null, null, drop] +item=null, id=3812, option=[null, null, null, null, drop] +item=null, id=3813, option=[null, null, null, null, drop] +item=null, id=3814, option=[null, null, null, null, drop] +item=null, id=3815, option=[null, null, null, null, drop] +item=null, id=3816, option=[null, null, null, null, drop] +item=null, id=3817, option=[null, null, null, null, drop] +item=null, id=3818, option=[null, null, null, null, drop] +item=null, id=3819, option=[null, null, null, null, drop] +item=null, id=3820, option=[null, null, null, null, drop] +item=null, id=3821, option=[null, null, null, null, drop] +item=null, id=3822, option=[null, null, null, null, drop] +item=null, id=3823, option=[null, null, null, null, drop] +item=null, id=3824, option=[null, null, null, null, drop] +item=null, id=3825, option=[null, null, null, null, drop] +item=null, id=3826, option=[null, null, null, null, drop] +item=Saradomin page 1, id=3827, option=[null, null, null, null, drop] +item=Saradomin page 2, id=3828, option=[null, null, null, null, drop] +item=Saradomin page 3, id=3829, option=[null, null, null, null, drop] +item=Saradomin page 4, id=3830, option=[null, null, null, null, drop] +item=Zamorak page 1, id=3831, option=[null, null, null, null, drop] +item=Zamorak page 2, id=3832, option=[null, null, null, null, drop] +item=Zamorak page 3, id=3833, option=[null, null, null, null, drop] +item=Zamorak page 4, id=3834, option=[null, null, null, null, drop] +item=Guthix page 1, id=3835, option=[null, null, null, null, drop] +item=Guthix page 2, id=3836, option=[null, null, null, null, drop] +item=Guthix page 3, id=3837, option=[null, null, null, null, drop] +item=Guthix page 4, id=3838, option=[null, null, null, null, drop] +item=Damaged book, id=3839, option=[null, Wield, Check, null, drop] +item=Holy book, id=3840, option=[null, Wield, Preach, null, drop] +item=Damaged book, id=3841, option=[null, Wield, Check, null, drop] +item=Unholy book, id=3842, option=[null, Wield, Preach, null, drop] +item=Damaged book, id=3843, option=[null, Wield, Check, null, drop] +item=Book of balance, id=3844, option=[null, Wield, Preach, null, drop] +item=Journal, id=3845, option=[Read, null, null, null, drop] +item=Diary, id=3846, option=[Read, null, null, null, drop] +item=Manual, id=3847, option=[Read, null, null, null, drop] +item=Lighthouse key, id=3848, option=[null, null, null, null, drop] +item=Rusty casket, id=3849, option=[null, null, null, null, drop] +item=null, id=3850, option=[null, null, null, null, drop] +item=Whoopsie, id=3851, option=[Wear, null, null, null, drop] +item=Unholy symbol, id=3852, option=[null, null, null, null, drop] +item=Games necklace(8), id=3853, option=[null, Wear, null, Rub, drop] +item=Games necklace(8), id=3854, option=[null, null, null, null, drop] +item=Games necklace(7), id=3855, option=[null, Wear, null, Rub, drop] +item=Games necklace(7), id=3856, option=[null, null, null, null, drop] +item=Games necklace(6), id=3857, option=[null, Wear, null, Rub, drop] +item=Games necklace(6), id=3858, option=[null, null, null, null, drop] +item=Games necklace(5), id=3859, option=[null, Wear, null, Rub, drop] +item=Games necklace(5), id=3860, option=[null, null, null, null, drop] +item=Games necklace(4), id=3861, option=[null, Wear, null, Rub, drop] +item=Games necklace(4), id=3862, option=[null, null, null, null, drop] +item=Games necklace(3), id=3863, option=[null, Wear, null, Rub, drop] +item=Games necklace(3), id=3864, option=[null, null, null, null, drop] +item=Games necklace(2), id=3865, option=[null, Wear, null, Rub, drop] +item=Games necklace(2), id=3866, option=[null, null, null, null, drop] +item=Games necklace(1), id=3867, option=[null, Wear, null, Rub, drop] +item=Games necklace(1), id=3868, option=[null, null, null, null, drop] +item=Board game piece, id=3869, option=[null, null, null, null, drop] +item=Board game piece, id=3870, option=[null, null, null, null, drop] +item=Board game piece, id=3871, option=[null, null, null, null, drop] +item=Board game piece, id=3872, option=[null, null, null, null, drop] +item=Board game piece, id=3873, option=[null, null, null, null, drop] +item=Board game piece, id=3874, option=[null, null, null, null, drop] +item=Board game piece, id=3875, option=[null, null, null, null, drop] +item=Board game piece, id=3876, option=[null, null, null, null, drop] +item=Board game piece, id=3877, option=[null, null, null, null, drop] +item=Board game piece, id=3878, option=[null, null, null, null, drop] +item=Board game piece, id=3879, option=[null, null, null, null, drop] +item=Board game piece, id=3880, option=[null, null, null, null, drop] +item=Board game piece, id=3881, option=[null, null, null, null, drop] +item=Board game piece, id=3882, option=[null, null, null, null, drop] +item=Board game piece, id=3883, option=[null, null, null, null, drop] +item=Board game piece, id=3884, option=[null, null, null, null, drop] +item=Board game piece, id=3885, option=[null, null, null, null, drop] +item=Board game piece, id=3886, option=[null, null, null, null, drop] +item=Board game piece, id=3887, option=[null, null, null, null, drop] +item=Board game piece, id=3888, option=[null, null, null, null, drop] +item=Board game piece, id=3889, option=[null, null, null, null, drop] +item=Board game piece, id=3890, option=[null, null, null, null, drop] +item=Board game piece, id=3891, option=[null, null, null, null, drop] +item=Board game piece, id=3892, option=[null, null, null, null, drop] +item=Stool, id=3893, option=[null, null, null, null, drop] +item=Awful anthem, id=3894, option=[null, null, null, null, drop] +item=Good anthem, id=3895, option=[null, null, null, null, drop] +item=Treaty, id=3896, option=[null, null, null, null, drop] +item=Giant nib, id=3897, option=[null, null, null, null, drop] +item=Giant pen, id=3898, option=[null, null, null, null, drop] +item=Iron sickle, id=3899, option=[null, Wield, null, null, drop] +item=Whoopsie, id=3900, option=[null, null, null, null, drop] +item=Ghrim's book, id=3901, option=[Read, null, null, null, drop] +item=Sliding button, id=3902, option=[Open, null, null, null, drop] +item=Whoopsie, id=3903, option=[null, null, null, null, drop] +item=Sliding button, id=3904, option=[null, null, null, null, Move] +item=Whoopsie, id=3905, option=[Wear, null, null, null, drop] +item=Sliding button, id=3906, option=[null, null, null, null, Move] +item=Whoopsie, id=3907, option=[Wear, null, null, null, drop] +item=Sliding button, id=3908, option=[null, null, null, null, Move] +item=Whoopsie, id=3909, option=[Wear, null, null, null, drop] +item=Sliding button, id=3910, option=[null, null, null, null, Move] +item=Whoopsie, id=3911, option=[Wear, null, null, null, drop] +item=Sliding button, id=3912, option=[null, null, null, null, Move] +item=Whoopsie, id=3913, option=[Wear, null, null, null, drop] +item=Sliding button, id=3914, option=[null, null, null, null, Move] +item=Whoopsie, id=3915, option=[Wear, null, null, null, drop] +item=Sliding button, id=3916, option=[null, null, null, null, Move] +item=Whoopsie, id=3917, option=[Wear, null, null, null, drop] +item=Sliding button, id=3918, option=[null, null, null, null, Move] +item=Whoopsie, id=3919, option=[Wear, null, null, null, drop] +item=Sliding button, id=3920, option=[null, null, null, null, Move] +item=Whoopsie, id=3921, option=[Wear, null, null, null, drop] +item=Sliding button, id=3922, option=[null, null, null, null, Move] +item=Whoopsie, id=3923, option=[Wear, null, null, null, drop] +item=Sliding button, id=3924, option=[null, null, null, null, Move] +item=Whoopsie, id=3925, option=[Wear, null, null, null, drop] +item=Sliding button, id=3926, option=[null, null, null, null, Move] +item=Whoopsie, id=3927, option=[Wear, null, null, null, drop] +item=Sliding button, id=3928, option=[null, null, null, null, Move] +item=Whoopsie, id=3929, option=[Wear, null, null, null, drop] +item=Sliding button, id=3930, option=[null, null, null, null, Move] +item=Whoopsie, id=3931, option=[Wear, null, null, null, drop] +item=Sliding button, id=3932, option=[null, null, null, null, Move] +item=Whoopsie, id=3933, option=[Wear, null, null, null, drop] +item=Sliding button, id=3934, option=[null, null, null, null, Move] +item=Whoopsie, id=3935, option=[Wear, null, null, null, drop] +item=Sliding button, id=3936, option=[null, null, null, null, Move] +item=Whoopsie, id=3937, option=[Wear, null, null, null, drop] +item=Sliding button, id=3938, option=[null, null, null, null, Move] +item=Whoopsie, id=3939, option=[Wear, null, null, null, drop] +item=Sliding button, id=3940, option=[null, null, null, null, Move] +item=Whoopsie, id=3941, option=[Wear, null, null, null, drop] +item=Sliding button, id=3942, option=[null, null, null, null, Move] +item=Whoopsie, id=3943, option=[Wear, null, null, null, drop] +item=Sliding button, id=3944, option=[null, null, null, null, Move] +item=Whoopsie, id=3945, option=[Wear, null, null, null, drop] +item=Sliding button, id=3946, option=[null, null, null, null, Move] +item=Whoopsie, id=3947, option=[Wear, null, null, null, drop] +item=Sliding button, id=3948, option=[null, null, null, null, Move] +item=Whoopsie, id=3949, option=[Wear, null, null, null, drop] +item=Sliding button, id=3950, option=[null, null, null, null, Move] +item=Whoopsie, id=3951, option=[Wear, null, null, null, drop] +item=Sliding button, id=3952, option=[null, null, null, null, Move] +item=Whoopsie, id=3953, option=[Wear, null, null, null, drop] +item=Sliding button, id=3954, option=[null, null, null, null, Move] +item=Whoopsie, id=3955, option=[Wear, null, null, null, drop] +item=Sliding button, id=3956, option=[null, null, null, null, Move] +item=Whoopsie, id=3957, option=[Wear, null, null, null, drop] +item=Sliding button, id=3958, option=[null, null, null, null, Move] +item=Whoopsie, id=3959, option=[Wear, null, null, null, drop] +item=Sliding button, id=3960, option=[null, null, null, null, Move] +item=Whoopsie, id=3961, option=[Wear, null, null, null, drop] +item=Sliding button, id=3962, option=[null, null, null, null, Move] +item=Whoopsie, id=3963, option=[Wear, null, null, null, drop] +item=Sliding button, id=3964, option=[null, null, null, null, Move] +item=Whoopsie, id=3965, option=[Wear, null, null, null, drop] +item=Sliding button, id=3966, option=[null, null, null, null, Move] +item=Whoopsie, id=3967, option=[Wear, null, null, null, drop] +item=Sliding button, id=3968, option=[null, null, null, null, Move] +item=Whoopsie, id=3969, option=[Wear, null, null, null, drop] +item=Sliding button, id=3970, option=[null, null, null, null, Move] +item=Whoopsie, id=3971, option=[Wear, null, null, null, drop] +item=Sliding button, id=3972, option=[null, null, null, null, Move] +item=Whoopsie, id=3973, option=[Wear, null, null, null, drop] +item=Sliding button, id=3974, option=[null, null, null, null, Move] +item=Whoopsie, id=3975, option=[Wear, null, null, null, drop] +item=Sliding button, id=3976, option=[null, null, null, null, Move] +item=Whoopsie, id=3977, option=[Wear, null, null, null, drop] +item=Sliding button, id=3978, option=[null, null, null, null, Move] +item=Whoopsie, id=3979, option=[Wear, null, null, null, drop] +item=Sliding button, id=3980, option=[null, null, null, null, Move] +item=Whoopsie, id=3981, option=[Wear, null, null, null, drop] +item=Sliding button, id=3982, option=[null, null, null, null, Move] +item=Whoopsie, id=3983, option=[Wear, null, null, null, drop] +item=Sliding button, id=3984, option=[null, null, null, null, Move] +item=Whoopsie, id=3985, option=[Wear, null, null, null, drop] +item=Sliding button, id=3986, option=[null, null, null, null, Move] +item=Whoopsie, id=3987, option=[Wear, null, null, null, drop] +item=Sliding button, id=3988, option=[null, null, null, null, Move] +item=Whoopsie, id=3989, option=[Wear, null, null, null, drop] +item=Sliding button, id=3990, option=[null, null, null, null, Move] +item=Whoopsie, id=3991, option=[Wear, null, null, null, drop] +item=Sliding button, id=3992, option=[null, null, null, null, Move] +item=Whoopsie, id=3993, option=[Wear, null, null, null, drop] +item=Sliding button, id=3994, option=[null, null, null, null, Move] +item=Whoopsie, id=3995, option=[Wear, null, null, null, drop] +item=Sliding button, id=3996, option=[null, null, null, null, Move] +item=Whoopsie, id=3997, option=[Wear, null, null, null, drop] +item=Sliding button, id=3998, option=[null, null, null, null, Move] +item=Whoopsie, id=3999, option=[Wear, null, null, null, drop] +item=Iodine, id=4000, option=[Wear, null, null, null, drop] +item=Hardy gout tuber, id=4001, option=[null, null, null, null, drop] +item=Spare controls, id=4002, option=[View, null, null, null, drop] +item=Whoopsie, id=4003, option=[null, null, null, null, drop] +item=Gnome royal seal, id=4004, option=[null, null, null, null, drop] +item=Narnode's orders, id=4005, option=[null, null, null, null, drop] +item=Monkey dentures, id=4006, option=[null, null, null, Listen, drop] +item=Enchanted bar, id=4007, option=[null, null, null, Listen, drop] +item=Eye of gnome, id=4008, option=[null, null, null, null, drop] +item=Eye of gnome, id=4009, option=[null, null, null, null, drop] +item=Monkey magic, id=4010, option=[null, null, null, null, drop] +item=Whoopsie, id=4011, option=[null, null, null, null, drop] +item=Monkey nuts, id=4012, option=[Eat, null, null, null, drop] +item=Whoopsie, id=4013, option=[null, null, null, null, drop] +item=Monkey bar, id=4014, option=[Eat, null, null, null, drop] +item=Whoopsie, id=4015, option=[null, null, null, null, drop] +item=Banana stew, id=4016, option=[Eat, null, null, null, drop] +item=Whoopsie, id=4017, option=[null, null, null, null, drop] +item=Monkey wrench, id=4018, option=[null, null, null, null, drop] +item=Whoopsie, id=4019, option=[null, null, null, null, drop] +item=M'amulet mould, id=4020, option=[null, null, null, null, drop] +item=M'speak amulet, id=4021, option=[null, Wear, null, null, drop] +item=M'speak amulet, id=4022, option=[null, null, null, null, drop] +item=Monkey talisman, id=4023, option=[null, Hold, null, null, drop] +item=Monkey greegree, id=4024, option=[null, Hold, null, null, drop] +item=Monkey greegree, id=4025, option=[null, Hold, null, null, drop] +item=Monkey greegree, id=4026, option=[null, Hold, null, null, drop] +item=Monkey greegree, id=4027, option=[null, Hold, null, null, drop] +item=Monkey greegree, id=4028, option=[null, Hold, null, null, drop] +item=Monkey greegree, id=4029, option=[null, Hold, null, null, drop] +item=Monkey greegree, id=4030, option=[null, Hold, null, null, drop] +item=Monkey greegree, id=4031, option=[null, Hold, null, null, drop] +item=Dummy, id=4032, option=[null, null, null, null, drop] +item=Monkey, id=4033, option=[Poke, null, null, null, drop] +item=Monkey skull, id=4034, option=[null, null, null, null, drop] +item=10th squad sigil, id=4035, option=[null, Wear, null, null, drop] +item=Whoopsie, id=4036, option=[Wear, null, null, null, drop] +item=Saradomin banner, id=4037, option=[null, Wield, null, null, drop] +item=Saradomin banner, id=4038, option=[null, null, null, null, drop] +item=Zamorak banner, id=4039, option=[null, Wield, null, null, drop] +item=Zamorak banner, id=4040, option=[null, null, null, null, drop] +item=Hooded cloak, id=4041, option=[null, Wear, null, null, drop] +item=Hooded cloak, id=4042, option=[null, Wear, null, null, drop] +item=Rock, id=4043, option=[null, null, null, null, drop] +item=Rock, id=4044, option=[null, null, null, null, drop] +item=Explosive potion, id=4045, option=[null, null, null, null, drop] +item=Explosive potion, id=4046, option=[null, null, null, null, drop] +item=Climbing rope, id=4047, option=[null, null, null, null, drop] +item=Climbing rope, id=4048, option=[null, null, null, null, drop] +item=Bandages, id=4049, option=[Heal, null, null, null, drop] +item=Bandages, id=4050, option=[null, null, null, null, drop] +item=Toolkit, id=4051, option=[null, null, null, null, drop] +item=Toolkit, id=4052, option=[null, null, null, null, drop] +item=Barricade, id=4053, option=[Set-up, null, null, null, drop] +item=Barricade, id=4054, option=[null, null, null, null, drop] +item=Castlewars manual, id=4055, option=[Read, null, null, null, drop] +item=null, id=4056, option=[null, null, null, null, drop] +item=null, id=4057, option=[null, null, null, null, drop] +item=null, id=4058, option=[null, null, null, null, drop] +item=null, id=4059, option=[null, null, null, null, drop] +item=null, id=4060, option=[null, null, null, null, drop] +item=null, id=4061, option=[null, null, null, null, drop] +item=null, id=4062, option=[null, null, null, null, drop] +item=null, id=4063, option=[null, null, null, null, drop] +item=null, id=4064, option=[null, null, null, null, drop] +item=null, id=4065, option=[null, null, null, null, drop] +item=null, id=4066, option=[null, null, null, null, drop] +item=Castle wars ticket, id=4067, option=[null, null, null, null, drop] +item=Decorative sword, id=4068, option=[null, Wield, null, null, drop] +item=Decorative armour, id=4069, option=[null, Wear, null, null, drop] +item=Decorative armour, id=4070, option=[null, Wear, null, null, drop] +item=Decorative helm, id=4071, option=[null, Wear, null, null, drop] +item=Decorative shield, id=4072, option=[null, Wear, null, null, drop] +item=Damp tinderbox, id=4073, option=[null, null, null, null, drop] +item=Damp tinderbox, id=4074, option=[null, null, null, null, drop] +item=Glowing fungus, id=4075, option=[null, null, null, null, drop] +item=Nezikchened's mum, id=4076, option=[Wear, null, null, null, drop] +item=Crystal-mine key, id=4077, option=[null, null, null, null, drop] +item=Zealot's key, id=4078, option=[null, null, null, null, drop] +item=Yo-yo, id=4079, option=[Play, Loop, Walk, Crazy, drop] +item=null, id=4080, option=[null, null, null, null, drop] +item=Salve amulet, id=4081, option=[null, Wear, null, null, drop] +item=Salve shard, id=4082, option=[null, null, null, null, drop] +item=Sled, id=4083, option=[null, null, null, null, drop] +item=Sled, id=4084, option=[null, Ride, null, null, drop] +item=Wax, id=4085, option=[null, null, null, null, drop] +item=Trollweiss, id=4086, option=[null, Wield, null, null, drop] +item=Dragon platelegs, id=4087, option=[null, Wear, null, null, drop] +item=Dragon platelegs, id=4088, option=[null, null, null, null, drop] +item=Mystic hat, id=4089, option=[null, Wear, null, null, drop] +item=Mystic hat, id=4090, option=[null, null, null, null, drop] +item=Mystic robe top, id=4091, option=[null, Wear, null, null, drop] +item=Mystic robe top, id=4092, option=[null, null, null, null, drop] +item=Mystic robe bottom, id=4093, option=[null, Wear, null, null, drop] +item=Mystic robe bottom, id=4094, option=[null, null, null, null, drop] +item=Mystic gloves, id=4095, option=[null, Wear, null, null, drop] +item=Mystic gloves, id=4096, option=[null, null, null, null, drop] +item=Mystic boots, id=4097, option=[null, Wear, null, null, drop] +item=Mystic boots, id=4098, option=[null, null, null, null, drop] +item=Mystic hat, id=4099, option=[null, Wear, null, null, drop] +item=Mystic hat, id=4100, option=[null, null, null, null, drop] +item=Mystic robe top, id=4101, option=[null, Wear, null, null, drop] +item=Mystic robe top, id=4102, option=[null, null, null, null, drop] +item=Mystic robe bottom, id=4103, option=[null, Wear, null, null, drop] +item=Mystic robe bottom, id=4104, option=[null, null, null, null, drop] +item=Mystic gloves, id=4105, option=[null, Wear, null, null, drop] +item=Mystic gloves, id=4106, option=[null, null, null, null, drop] +item=Mystic boots, id=4107, option=[null, Wear, null, null, drop] +item=Mystic boots, id=4108, option=[null, null, null, null, drop] +item=Mystic hat, id=4109, option=[null, Wear, null, null, drop] +item=Mystic hat, id=4110, option=[null, null, null, null, drop] +item=Mystic robe top, id=4111, option=[null, Wear, null, null, drop] +item=Mystic robe top, id=4112, option=[null, null, null, null, drop] +item=Mystic robe bottom, id=4113, option=[null, Wear, null, null, drop] +item=Mystic robe bottom, id=4114, option=[null, null, null, null, drop] +item=Mystic gloves, id=4115, option=[null, Wear, null, null, drop] +item=Mystic gloves, id=4116, option=[null, null, null, null, drop] +item=Mystic boots, id=4117, option=[null, Wear, null, null, drop] +item=Mystic boots, id=4118, option=[null, null, null, null, drop] +item=Bronze boots, id=4119, option=[null, Wear, null, null, drop] +item=Bronze boots, id=4120, option=[null, null, null, null, drop] +item=Iron boots, id=4121, option=[null, Wear, null, null, drop] +item=Iron boots, id=4122, option=[null, null, null, null, drop] +item=Steel boots, id=4123, option=[null, Wear, null, null, drop] +item=Steel boots, id=4124, option=[null, null, null, null, drop] +item=Black boots, id=4125, option=[null, Wear, null, null, drop] +item=Black boots, id=4126, option=[null, null, null, null, drop] +item=Mithril boots, id=4127, option=[null, Wear, null, null, drop] +item=Mithril boots, id=4128, option=[null, null, null, null, drop] +item=Adamant boots, id=4129, option=[null, Wear, null, null, drop] +item=Adamant boots, id=4130, option=[null, null, null, null, drop] +item=Rune boots, id=4131, option=[null, Wear, null, null, drop] +item=Rune boots, id=4132, option=[null, null, null, null, drop] +item=Crawling hand, id=4133, option=[null, null, null, null, drop] +item=Cave crawler, id=4134, option=[null, null, null, null, drop] +item=Banshee, id=4135, option=[null, null, null, null, drop] +item=Rockslug, id=4136, option=[null, null, null, null, drop] +item=Cockatrice, id=4137, option=[null, null, null, null, drop] +item=Pyrefiend, id=4138, option=[null, null, null, null, drop] +item=Basilisk, id=4139, option=[null, null, null, null, drop] +item=Infernal mage, id=4140, option=[null, null, null, null, drop] +item=Bloodveld, id=4141, option=[null, null, null, null, drop] +item=Jelly, id=4142, option=[null, null, null, null, drop] +item=Turoth, id=4143, option=[null, null, null, null, drop] +item=Aberrant spectre, id=4144, option=[null, null, null, null, drop] +item=Dust devil, id=4145, option=[null, null, null, null, drop] +item=Kurask, id=4146, option=[null, null, null, null, drop] +item=Gargoyle, id=4147, option=[null, null, null, null, drop] +item=Nechryael, id=4148, option=[null, null, null, null, drop] +item=Abyssal demon, id=4149, option=[null, null, null, null, drop] +item=Broad arrows, id=4150, option=[null, null, null, null, drop] +item=Abyssal whip, id=4151, option=[null, Wield, null, null, drop] +item=Abyssal whip, id=4152, option=[null, null, null, null, drop] +item=Granite maul, id=4153, option=[null, Wield, null, null, drop] +item=Granite maul, id=4154, option=[null, null, null, null, drop] +item=Enchanted gem, id=4155, option=[Activate, null, null, null, drop] +item=Mirror shield, id=4156, option=[null, Wield, null, null, drop] +item=Mirror shield, id=4157, option=[null, null, null, null, drop] +item=Leaf-bladed spear, id=4158, option=[null, Wield, null, null, drop] +item=Leaf-bladed spear, id=4159, option=[null, Wield, null, null, drop] +item=Broad arrow, id=4160, option=[null, Wield, null, null, drop] +item=Bag of salt, id=4161, option=[null, null, null, null, drop] +item=Rock hammer, id=4162, option=[null, null, null, null, drop] +item=Rock hammer, id=4163, option=[null, null, null, null, drop] +item=Facemask, id=4164, option=[null, Wear, null, null, drop] +item=Facemask, id=4165, option=[null, null, null, null, drop] +item=Earmuffs, id=4166, option=[null, Wear, null, null, drop] +item=Earmuffs, id=4167, option=[null, null, null, null, drop] +item=Nose peg, id=4168, option=[null, Wear, null, null, drop] +item=Nose peg, id=4169, option=[null, null, null, null, drop] +item=Slayer's staff, id=4170, option=[null, Wield, null, null, drop] +item=Slayer's staff, id=4171, option=[null, null, null, null, drop] +item=Broad arrows, id=4172, option=[null, Wield, null, null, drop] +item=Broad arrows, id=4173, option=[null, Wield, null, null, drop] +item=Broad arrows, id=4174, option=[null, Wield, null, null, drop] +item=Broad arrows, id=4175, option=[null, Wield, null, null, drop] +item=null, id=4176, option=[null, null, null, null, drop] +item=Wolfbane lever, id=4177, option=[Push, Pull, Abuse, Pluck, drop] +item=Abyssal whip, id=4178, option=[null, Wield, null, null, drop] +item=Stick, id=4179, option=[null, null, null, null, drop] +item=Dragon platelegs, id=4180, option=[null, Wear, null, null, drop] +item=Mouth grip, id=4181, option=[null, Wear, null, null, drop] +item=Goutweed, id=4182, option=[null, null, null, null, drop] +item=Star amulet, id=4183, option=[null, null, null, null, drop] +item=Cavern key, id=4184, option=[null, null, null, null, drop] +item=Tower key, id=4185, option=[null, null, null, null, drop] +item=Shed key, id=4186, option=[null, null, null, null, drop] +item=Marble amulet, id=4187, option=[null, null, null, null, drop] +item=Obsidian amulet, id=4188, option=[null, null, null, null, drop] +item=Garden cane, id=4189, option=[null, null, null, null, drop] +item=Garden brush, id=4190, option=[null, null, null, null, drop] +item=Extended brush, id=4191, option=[null, null, null, null, drop] +item=Extended brush, id=4192, option=[null, null, null, null, drop] +item=Extended brush, id=4193, option=[null, null, null, null, drop] +item=Torso, id=4194, option=[null, null, null, null, drop] +item=Arms, id=4195, option=[null, null, null, null, drop] +item=Legs, id=4196, option=[null, null, null, null, drop] +item=Decapitated head, id=4197, option=[null, null, null, null, drop] +item=Decapitated head, id=4198, option=[null, null, null, null, drop] +item=Pickled brain, id=4199, option=[null, null, null, null, drop] +item=Conductor mould, id=4200, option=[null, null, null, null, drop] +item=Conductor, id=4201, option=[null, null, null, null, drop] +item=Ring of charos, id=4202, option=[null, Wear, null, null, drop] +item=Journal, id=4203, option=[null, null, null, null, drop] +item=Letter, id=4204, option=[Read, null, null, null, drop] +item=Consecration seed, id=4205, option=[null, null, null, null, drop] +item=Consecration seed, id=4206, option=[Plant, null, null, null, drop] +item=Crystal seed, id=4207, option=[null, null, null, null, drop] +item=Crystal seed, id=4208, option=[null, null, null, null, drop] +item=Cadarn lineage, id=4209, option=[Read, null, null, null, drop] +item=Whoopsie, id=4210, option=[null, null, null, null, drop] +item=Elf crystal, id=4211, option=[null, null, null, null, drop] +item=New crystal bow, id=4212, option=[null, Wield, null, null, drop] +item=New crystal bow, id=4213, option=[null, null, null, null, drop] +item=Crystal bow full, id=4214, option=[null, Wield, null, null, drop] +item=Crystal bow 9/10, id=4215, option=[null, Wield, null, null, drop] +item=Crystal bow 8/10, id=4216, option=[null, Wield, null, null, drop] +item=Crystal bow 7/10, id=4217, option=[null, Wield, null, null, drop] +item=Crystal bow 6/10, id=4218, option=[null, Wield, null, null, drop] +item=Crystal bow 5/10, id=4219, option=[null, Wield, null, null, drop] +item=Crystal bow 4/10, id=4220, option=[null, Wield, null, null, drop] +item=Crystal bow 3/10, id=4221, option=[null, Wield, null, null, drop] +item=Crystal bow 2/10, id=4222, option=[null, Wield, null, null, drop] +item=Crystal bow 1/10, id=4223, option=[null, Wield, null, null, drop] +item=New crystal shield, id=4224, option=[null, Wield, null, null, drop] +item=Crystal shield full, id=4225, option=[null, Wield, null, null, drop] +item=Crystal shield 9/10, id=4226, option=[null, Wield, null, null, drop] +item=Crystal shield 8/10, id=4227, option=[null, Wield, null, null, drop] +item=Crystal shield 7/10, id=4228, option=[null, Wield, null, null, drop] +item=Crystal shield 6/10, id=4229, option=[null, Wield, null, null, drop] +item=Crystal shield 5/10, id=4230, option=[null, Wield, null, null, drop] +item=Crystal shield 4/10, id=4231, option=[null, Wield, null, null, drop] +item=Crystal shield 3/10, id=4232, option=[null, Wield, null, null, drop] +item=Crystal shield 2/10, id=4233, option=[null, Wield, null, null, drop] +item=Crystal shield 1/10, id=4234, option=[null, Wield, null, null, drop] +item=New crystal shield, id=4235, option=[null, null, null, null, drop] +item=Signed oak bow, id=4236, option=[null, Wield, null, null, drop] +item=Nettle-water, id=4237, option=[null, Drink, Empty, null, drop] +item=Puddle of slime, id=4238, option=[null, null, null, null, drop] +item=Nettle tea, id=4239, option=[null, Drink, Empty, null, drop] +item=Nettle tea, id=4240, option=[null, Drink, Empty, null, drop] +item=Nettles, id=4241, option=[null, null, null, null, drop] +item=Cup of tea, id=4242, option=[null, Drink, Empty, null, drop] +item=Cup of tea, id=4243, option=[null, Drink, Empty, null, drop] +item=Porcelain cup, id=4244, option=[null, null, null, null, drop] +item=Cup of tea, id=4245, option=[null, Drink, Empty, null, drop] +item=Cup of tea, id=4246, option=[null, Drink, Empty, null, drop] +item=Mystical robes, id=4247, option=[null, null, null, null, drop] +item=Book of haricanto, id=4248, option=[null, null, null, null, drop] +item=Translation manual, id=4249, option=[null, null, null, null, drop] +item=Ghostspeak amulet, id=4250, option=[null, Wear, null, null, drop] +item=Ectophial, id=4251, option=[Empty, null, null, null, drop] +item=Ectophial, id=4252, option=[null, null, null, null, drop] +item=Model ship, id=4253, option=[Repair, null, null, null, drop] +item=Model ship, id=4254, option=[Inspect, null, null, null, drop] +item=Bonemeal, id=4255, option=[null, Empty, null, null, drop] +item=Bonemeal, id=4256, option=[null, Empty, null, null, drop] +item=Bonemeal, id=4257, option=[null, Empty, null, null, drop] +item=Bonemeal, id=4258, option=[null, Empty, null, null, drop] +item=Bonemeal, id=4259, option=[null, Empty, null, null, drop] +item=Bonemeal, id=4260, option=[null, Empty, null, null, drop] +item=Bonemeal, id=4261, option=[null, Empty, null, null, drop] +item=Bonemeal, id=4262, option=[null, Empty, null, null, drop] +item=Bonemeal, id=4263, option=[null, Empty, null, null, drop] +item=Bonemeal, id=4264, option=[null, Empty, null, null, drop] +item=Bonemeal, id=4265, option=[null, Empty, null, null, drop] +item=Bonemeal, id=4266, option=[null, Empty, null, null, drop] +item=Bonemeal, id=4267, option=[null, Empty, null, null, drop] +item=Bonemeal, id=4268, option=[null, Empty, null, null, drop] +item=Bonemeal, id=4269, option=[null, Empty, null, null, drop] +item=Bonemeal, id=4270, option=[null, Empty, null, null, drop] +item=Bonemeal, id=4271, option=[null, Empty, null, null, drop] +item=Bone key, id=4272, option=[null, null, null, null, drop] +item=Chest key, id=4273, option=[null, null, null, null, drop] +item=Map scrap, id=4274, option=[null, null, null, null, drop] +item=Map scrap, id=4275, option=[null, null, null, null, drop] +item=Map scrap, id=4276, option=[null, null, null, null, drop] +item=Treasure map, id=4277, option=[Read, Follow, null, null, drop] +item=Ecto-token, id=4278, option=[null, null, null, null, drop] +item=null, id=4279, option=[null, null, null, null, drop] +item=Whoopsie, id=4280, option=[Wear, null, null, null, drop] +item=null, id=4281, option=[null, null, null, null, drop] +item=Whoopsie, id=4282, option=[Wear, null, null, null, drop] +item=Petition form, id=4283, option=[Count, null, null, null, drop] +item=Bedsheet, id=4284, option=[null, Wear, null, null, drop] +item=Bedsheet, id=4285, option=[null, Wear, null, null, drop] +item=Bucket of slime, id=4286, option=[null, null, null, Empty, drop] +item=Raw beef, id=4287, option=[null, null, null, null, drop] +item=Raw beef, id=4288, option=[null, null, null, null, drop] +item=Raw chicken, id=4289, option=[null, null, null, null, drop] +item=Raw chicken, id=4290, option=[null, null, null, null, drop] +item=Cooked chicken, id=4291, option=[Eat, null, null, null, drop] +item=Cooked chicken, id=4292, option=[null, null, null, null, drop] +item=Cooked meat, id=4293, option=[Eat, null, null, null, drop] +item=Cooked meat, id=4294, option=[null, null, null, null, drop] +item=Female h.a.m., id=4295, option=[null, null, null, null, drop] +item=Whoopsie, id=4296, option=[Wear, null, null, null, drop] +item=Male h.a.m., id=4297, option=[null, null, null, null, drop] +item=Ham shirt, id=4298, option=[null, Wear, null, null, drop] +item=Ham shirt, id=4299, option=[null, null, null, null, drop] +item=Ham robe, id=4300, option=[null, Wear, null, null, drop] +item=Ham robe, id=4301, option=[null, null, null, null, drop] +item=Ham hood, id=4302, option=[null, Wear, null, null, drop] +item=Ham hood, id=4303, option=[null, null, null, null, drop] +item=Ham cloak, id=4304, option=[null, Wear, null, null, drop] +item=Ham cloak, id=4305, option=[null, null, null, null, drop] +item=H.a.m logo, id=4306, option=[null, Wear, null, null, drop] +item=H.a.m logo, id=4307, option=[null, null, null, null, drop] +item=Gloves, id=4308, option=[null, Wear, null, null, drop] +item=Gloves, id=4309, option=[null, null, null, null, drop] +item=Boots, id=4310, option=[null, Wear, null, null, drop] +item=Boots, id=4311, option=[null, null, null, null, drop] +item=Whoopsie, id=4312, option=[Wear, null, null, null, drop] +item=Crystal of seren, id=4313, option=[Read, null, null, null, drop] +item=Whoopsie, id=4314, option=[null, null, null, null, drop] +item=Team-1 cape, id=4315, option=[null, Wear, null, null, drop] +item=Team-1 cape, id=4316, option=[null, null, null, null, drop] +item=Team-2 cape, id=4317, option=[null, Wear, null, null, drop] +item=Team-2 cape, id=4318, option=[null, null, null, null, drop] +item=Team-3 cape, id=4319, option=[null, Wear, null, null, drop] +item=Team-3 cape, id=4320, option=[null, null, null, null, drop] +item=Team-4 cape, id=4321, option=[null, Wear, null, null, drop] +item=Team-4 cape, id=4322, option=[null, null, null, null, drop] +item=Team-5 cape, id=4323, option=[null, Wear, null, null, drop] +item=Team-5 cape, id=4324, option=[null, null, null, null, drop] +item=Team-6 cape, id=4325, option=[null, Wear, null, null, drop] +item=Team-6 cape, id=4326, option=[null, null, null, null, drop] +item=Team-7 cape, id=4327, option=[null, Wear, null, null, drop] +item=Team-7 cape, id=4328, option=[null, null, null, null, drop] +item=Team-8 cape, id=4329, option=[null, Wear, null, null, drop] +item=Team-8 cape, id=4330, option=[null, null, null, null, drop] +item=Team-9 cape, id=4331, option=[null, Wear, null, null, drop] +item=Team-9 cape, id=4332, option=[null, null, null, null, drop] +item=Team-10 cape, id=4333, option=[null, Wear, null, null, drop] +item=Team-10 cape, id=4334, option=[null, null, null, null, drop] +item=Team-11 cape, id=4335, option=[null, Wear, null, null, drop] +item=Team-11 cape, id=4336, option=[null, null, null, null, drop] +item=Team-12 cape, id=4337, option=[null, Wear, null, null, drop] +item=Team-12 cape, id=4338, option=[null, null, null, null, drop] +item=Team-13 cape, id=4339, option=[null, Wear, null, null, drop] +item=Team-13 cape, id=4340, option=[null, null, null, null, drop] +item=Team-14 cape, id=4341, option=[null, Wear, null, null, drop] +item=Team-14 cape, id=4342, option=[null, null, null, null, drop] +item=Team-15 cape, id=4343, option=[null, Wear, null, null, drop] +item=Team-15 cape, id=4344, option=[null, null, null, null, drop] +item=Team-16 cape, id=4345, option=[null, Wear, null, null, drop] +item=Team-16 cape, id=4346, option=[null, null, null, null, drop] +item=Team-17 cape, id=4347, option=[null, Wear, null, null, drop] +item=Team-17 cape, id=4348, option=[null, null, null, null, drop] +item=Team-18 cape, id=4349, option=[null, Wear, null, null, drop] +item=Team-18 cape, id=4350, option=[null, null, null, null, drop] +item=Team-19 cape, id=4351, option=[null, Wear, null, null, drop] +item=Team-19 cape, id=4352, option=[null, null, null, null, drop] +item=Team-20 cape, id=4353, option=[null, Wear, null, null, drop] +item=Team-20 cape, id=4354, option=[null, null, null, null, drop] +item=Team-21 cape, id=4355, option=[null, Wear, null, null, drop] +item=Team-21 cape, id=4356, option=[null, null, null, null, drop] +item=Team-22 cape, id=4357, option=[null, Wear, null, null, drop] +item=Team-22 cape, id=4358, option=[null, null, null, null, drop] +item=Team-23 cape, id=4359, option=[null, Wear, null, null, drop] +item=Team-23 cape, id=4360, option=[null, null, null, null, drop] +item=Team-24 cape, id=4361, option=[null, Wear, null, null, drop] +item=Team-24 cape, id=4362, option=[null, null, null, null, drop] +item=Team-25 cape, id=4363, option=[null, Wear, null, null, drop] +item=Team-25 cape, id=4364, option=[null, null, null, null, drop] +item=Team-26 cape, id=4365, option=[null, Wear, null, null, drop] +item=Team-26 cape, id=4366, option=[null, null, null, null, drop] +item=Team-27 cape, id=4367, option=[null, Wear, null, null, drop] +item=Team-27 cape, id=4368, option=[null, null, null, null, drop] +item=Team-28 cape, id=4369, option=[null, Wear, null, null, drop] +item=Team-28 cape, id=4370, option=[null, null, null, null, drop] +item=Team-29 cape, id=4371, option=[null, Wear, null, null, drop] +item=Team-29 cape, id=4372, option=[null, null, null, null, drop] +item=Team-30 cape, id=4373, option=[null, Wear, null, null, drop] +item=Team-30 cape, id=4374, option=[null, null, null, null, drop] +item=Team-31 cape, id=4375, option=[null, Wear, null, null, drop] +item=Team-31 cape, id=4376, option=[null, null, null, null, drop] +item=Team-32 cape, id=4377, option=[null, Wear, null, null, drop] +item=Team-32 cape, id=4378, option=[null, null, null, null, drop] +item=Team-33 cape, id=4379, option=[null, Wear, null, null, drop] +item=Team-33 cape, id=4380, option=[null, null, null, null, drop] +item=Team-34 cape, id=4381, option=[null, Wear, null, null, drop] +item=Team-34 cape, id=4382, option=[null, null, null, null, drop] +item=Team-35 cape, id=4383, option=[null, Wear, null, null, drop] +item=Team-35 cape, id=4384, option=[null, null, null, null, drop] +item=Team-36 cape, id=4385, option=[null, Wear, null, null, drop] +item=Team-36 cape, id=4386, option=[null, null, null, null, drop] +item=Team-37 cape, id=4387, option=[null, Wear, null, null, drop] +item=Team-37 cape, id=4388, option=[null, null, null, null, drop] +item=Team-38 cape, id=4389, option=[null, Wear, null, null, drop] +item=Team-38 cape, id=4390, option=[null, null, null, null, drop] +item=Team-39 cape, id=4391, option=[null, Wear, null, null, drop] +item=Team-39 cape, id=4392, option=[null, null, null, null, drop] +item=Team-40 cape, id=4393, option=[null, Wear, null, null, drop] +item=Team-40 cape, id=4394, option=[null, null, null, null, drop] +item=Team-41 cape, id=4395, option=[null, Wear, null, null, drop] +item=Team-41 cape, id=4396, option=[null, null, null, null, drop] +item=Team-42 cape, id=4397, option=[null, Wear, null, null, drop] +item=Team-42 cape, id=4398, option=[null, null, null, null, drop] +item=Team-43 cape, id=4399, option=[null, Wear, null, null, drop] +item=Team-43 cape, id=4400, option=[null, null, null, null, drop] +item=Team-44 cape, id=4401, option=[null, Wear, null, null, drop] +item=Team-44 cape, id=4402, option=[null, null, null, null, drop] +item=Team-45 cape, id=4403, option=[null, Wear, null, null, drop] +item=Team-45 cape, id=4404, option=[null, null, null, null, drop] +item=Team-46 cape, id=4405, option=[null, Wear, null, null, drop] +item=Team-46 cape, id=4406, option=[null, null, null, null, drop] +item=Team-47 cape, id=4407, option=[null, Wear, null, null, drop] +item=Team-47 cape, id=4408, option=[null, null, null, null, drop] +item=Team-48 cape, id=4409, option=[null, Wear, null, null, drop] +item=Team-48 cape, id=4410, option=[null, null, null, null, drop] +item=Team-49 cape, id=4411, option=[null, Wear, null, null, drop] +item=Team-49 cape, id=4412, option=[null, null, null, null, drop] +item=Team-50 cape, id=4413, option=[null, Wear, null, null, drop] +item=Team-50 cape, id=4414, option=[null, null, null, null, drop] +item=Blunt axe, id=4415, option=[null, null, null, null, drop] +item=Herbal tincture, id=4416, option=[null, null, null, null, drop] +item=Guthix rest(4), id=4417, option=[Drink, null, null, Empty, drop] +item=Guthix rest(4), id=4418, option=[null, null, null, null, drop] +item=Guthix rest(3), id=4419, option=[Drink, null, null, Empty, drop] +item=Guthix rest(3), id=4420, option=[null, null, null, null, drop] +item=Guthix rest(2), id=4421, option=[Drink, null, null, Empty, drop] +item=Guthix rest(2), id=4422, option=[null, null, null, null, drop] +item=Guthix rest(1), id=4423, option=[Drink, null, null, Empty, drop] +item=Guthix rest(1), id=4424, option=[null, null, null, null, drop] +item=Stodgy mattress, id=4425, option=[null, null, null, null, drop] +item=Comfy mattress, id=4426, option=[null, null, null, null, drop] +item=Iron oxide, id=4427, option=[null, null, null, null, drop] +item=Animate rock scroll, id=4428, option=[Read, null, null, null, drop] +item=Broken vane part, id=4429, option=[null, null, null, null, drop] +item=Directionals, id=4430, option=[null, null, null, null, drop] +item=Broken vane part, id=4431, option=[null, null, null, null, drop] +item=Ornament, id=4432, option=[null, null, null, null, drop] +item=Broken vane part, id=4433, option=[null, null, null, null, drop] +item=Weathervane pillar, id=4434, option=[null, null, null, null, drop] +item=Weather report, id=4435, option=[Read, null, null, null, drop] +item=Airtight pot, id=4436, option=[Open, null, null, null, drop] +item=Airtight pot, id=4437, option=[null, null, null, null, drop] +item=Unfired pot lid, id=4438, option=[null, null, null, null, drop] +item=Unfired pot lid, id=4439, option=[null, null, null, null, drop] +item=Pot lid, id=4440, option=[null, null, null, null, drop] +item=Pot lid, id=4441, option=[null, null, null, null, drop] +item=Breathing salts, id=4442, option=[null, null, null, null, drop] +item=Chicken cage, id=4443, option=[null, null, null, null, drop] +item=Sharpened axe, id=4444, option=[null, null, null, null, drop] +item=Red mahogany log, id=4445, option=[null, null, null, null, drop] +item=Steel key ring, id=4446, option=[Check-keys, null, null, null, Destroy] +item=Antique lamp, id=4447, option=[Rub, null, null, null, drop] +item=null, id=4448, option=[null, null, null, null, drop] +item=Whoopsie, id=4449, option=[Wear, null, null, null, drop] +item=null, id=4450, option=[null, null, null, null, drop] +item=Whoopsie, id=4451, option=[Wear, null, null, null, drop] +item=null, id=4452, option=[null, null, null, null, drop] +item=Whoopsie, id=4453, option=[Wear, null, null, null, drop] +item=null, id=4454, option=[null, null, null, null, drop] +item=Whoopsie, id=4455, option=[Wear, null, null, null, drop] +item=Bowl of hot water, id=4456, option=[null, null, null, Empty, drop] +item=Bowl of hot water, id=4457, option=[null, null, null, null, drop] +item=Cup of water, id=4458, option=[null, null, null, Empty, drop] +item=Cup of water, id=4459, option=[null, null, null, null, drop] +item=Cup of hot water, id=4460, option=[null, null, null, Empty, drop] +item=Cup of hot water, id=4461, option=[null, null, null, null, drop] +item=Ruined herb tea, id=4462, option=[null, null, null, Empty, drop] +item=Ruined herb tea, id=4463, option=[null, null, null, null, drop] +item=Herb tea mix, id=4464, option=[null, null, null, Empty, drop] +item=Herb tea mix, id=4465, option=[null, null, null, null, drop] +item=Herb tea mix, id=4466, option=[null, null, null, Empty, drop] +item=Herb tea mix, id=4467, option=[null, null, null, null, drop] +item=Herb tea mix, id=4468, option=[null, null, null, Empty, drop] +item=Herb tea mix, id=4469, option=[null, null, null, null, drop] +item=Herb tea mix, id=4470, option=[null, null, null, Empty, drop] +item=Herb tea mix, id=4471, option=[null, null, null, null, drop] +item=Herb tea mix, id=4472, option=[null, null, null, Empty, drop] +item=Herb tea mix, id=4473, option=[null, null, null, null, drop] +item=Herb tea mix, id=4474, option=[null, null, null, Empty, drop] +item=Herb tea mix, id=4475, option=[null, null, null, null, drop] +item=Herb tea mix, id=4476, option=[null, null, null, Empty, drop] +item=Herb tea mix, id=4477, option=[null, null, null, null, drop] +item=Herb tea mix, id=4478, option=[null, null, null, Empty, drop] +item=Herb tea mix, id=4479, option=[null, null, null, null, drop] +item=Herb tea mix, id=4480, option=[null, null, null, Empty, drop] +item=Herb tea mix, id=4481, option=[null, null, null, null, drop] +item=Herb tea mix, id=4482, option=[null, null, null, Empty, drop] +item=Herb tea mix, id=4483, option=[null, null, null, null, drop] +item=Safety guarantee, id=4484, option=[null, null, null, null, drop] +item=White pearl, id=4485, option=[null, null, Eat, null, drop] +item=White pearl seed, id=4486, option=[null, null, null, null, drop] +item=Half a rock, id=4487, option=[null, null, null, null, drop] +item=Corpse of woman, id=4488, option=[null, null, Bury, null, drop] +item=Asleif's necklace, id=4489, option=[null, null, null, null, drop] +item=Mud, id=4490, option=[null, null, null, null, drop] +item=Whoopsie, id=4491, option=[null, null, null, null, drop] +item=Muddy rock, id=4492, option=[null, null, null, null, drop] +item=Whoopsie, id=4493, option=[null, null, null, null, drop] +item=Pole, id=4494, option=[null, null, null, null, drop] +item=Pole, id=4495, option=[null, null, null, null, drop] +item=Broken pole, id=4496, option=[null, null, null, null, drop] +item=Whoopsie, id=4497, option=[null, null, null, null, drop] +item=Rope, id=4498, option=[null, null, null, null, drop] +item=Rope, id=4499, option=[null, null, null, null, drop] +item=Pole, id=4500, option=[null, null, null, null, drop] +item=Pole, id=4501, option=[null, null, null, null, drop] +item=Bearhead, id=4502, option=[null, Wear, null, null, Destroy] +item=Decorative sword, id=4503, option=[null, Wield, null, null, drop] +item=Decorative armour, id=4504, option=[null, Wear, null, null, drop] +item=Decorative armour, id=4505, option=[null, Wear, null, null, drop] +item=Decorative helm, id=4506, option=[null, Wear, null, null, drop] +item=Decorative shield, id=4507, option=[null, Wear, null, null, drop] +item=Decorative sword, id=4508, option=[null, Wield, null, null, drop] +item=Decorative armour, id=4509, option=[null, Wear, null, null, drop] +item=Decorative armour, id=4510, option=[null, Wear, null, null, drop] +item=Decorative helm, id=4511, option=[null, Wear, null, null, drop] +item=Decorative shield, id=4512, option=[null, Wear, null, null, drop] +item=Castlewars hood, id=4513, option=[null, Wear, null, null, drop] +item=Castlewars cloak, id=4514, option=[null, Wear, null, null, drop] +item=Castlewars hood, id=4515, option=[null, Wear, null, null, drop] +item=Castlewars cloak, id=4516, option=[null, Wear, null, null, drop] +item=Giant frog legs, id=4517, option=[Eat, null, null, null, drop] +item=Giant frog legs, id=4518, option=[null, null, null, null, drop] +item=Swamp wallbeast, id=4519, option=[null, null, null, null, drop] +item=Swamp cave slime, id=4520, option=[null, null, null, null, drop] +item=Swamp cave bug, id=4521, option=[null, null, null, null, drop] +item=Oil lamp, id=4522, option=[null, null, null, null, drop] +item=Oil lamp, id=4523, option=[null, null, null, null, drop] +item=Oil lamp, id=4524, option=[null, Extinguish, null, null, drop] +item=Oil lamp, id=4525, option=[null, null, null, null, drop] +item=Oil lamp, id=4526, option=[null, null, null, null, drop] +item=Candle lantern, id=4527, option=[null, null, null, null, drop] +item=Candle lantern, id=4528, option=[null, null, null, null, drop] +item=Candle lantern, id=4529, option=[null, null, null, null, drop] +item=Candle lantern, id=4530, option=[null, null, null, null, drop] +item=Candle lantern, id=4531, option=[null, Extinguish, null, null, drop] +item=Candle lantern, id=4532, option=[null, null, null, null, drop] +item=Candle lantern, id=4533, option=[null, null, null, null, drop] +item=Candle lantern, id=4534, option=[null, Extinguish, null, null, drop] +item=Oil lantern, id=4535, option=[null, null, null, null, drop] +item=Oil lantern, id=4536, option=[null, null, null, null, drop] +item=Oil lantern, id=4537, option=[null, null, null, null, drop] +item=Oil lantern, id=4538, option=[null, null, null, null, drop] +item=Oil lantern, id=4539, option=[null, Extinguish, null, null, drop] +item=Oil lantern frame, id=4540, option=[null, null, null, null, drop] +item=Oil lantern frame, id=4541, option=[null, null, null, null, drop] +item=Lantern lens, id=4542, option=[null, null, null, null, drop] +item=Lantern lens, id=4543, option=[null, null, null, null, drop] +item=Bullseye lantern, id=4544, option=[null, null, null, null, drop] +item=Bullseye lantern, id=4545, option=[null, null, null, null, drop] +item=Bullseye lantern, id=4546, option=[null, null, null, null, drop] +item=Bullseye lantern, id=4547, option=[null, null, null, null, drop] +item=Bullseye lantern, id=4548, option=[null, null, null, null, drop] +item=Bullseye lantern, id=4549, option=[null, null, null, null, drop] +item=Bullseye lantern, id=4550, option=[null, Extinguish, null, null, drop] +item=Spiny helmet, id=4551, option=[null, Wear, null, null, drop] +item=Spiny helmet, id=4552, option=[null, null, null, null, drop] +item=null, id=4553, option=[null, null, null, null, drop] +item=null, id=4554, option=[null, null, null, null, drop] +item=null, id=4555, option=[null, null, null, null, drop] +item=null, id=4556, option=[null, null, null, null, drop] +item=null, id=4557, option=[null, null, null, null, drop] +item=Blue sweets, id=4558, option=[Eat, null, null, null, drop] +item=Deep blue sweets, id=4559, option=[Eat, null, null, null, drop] +item=White sweets, id=4560, option=[Eat, null, null, null, drop] +item=Purple sweets, id=4561, option=[Eat, null, null, null, drop] +item=Red sweets, id=4562, option=[Eat, null, null, null, drop] +item=Green sweets, id=4563, option=[Eat, null, null, null, drop] +item=Pink sweets, id=4564, option=[Eat, null, null, null, drop] +item=Basket of eggs, id=4565, option=[null, Wield, null, null, drop] +item=Rubber chicken, id=4566, option=[null, Wield, Dance, null, drop] +item=Gold helmet, id=4567, option=[null, Wear, null, null, drop] +item=Dwarven lore, id=4568, option=[Read, null, null, null, drop] +item=Book page 1, id=4569, option=[null, null, null, null, drop] +item=Book page 2, id=4570, option=[null, null, null, null, drop] +item=Book page 3, id=4571, option=[null, null, null, null, drop] +item=Pages, id=4572, option=[null, null, null, null, drop] +item=Pages, id=4573, option=[null, null, null, null, drop] +item=Base schematics, id=4574, option=[Assemble, null, null, null, drop] +item=Schematic, id=4575, option=[Assemble, null, null, null, drop] +item=Schematics, id=4576, option=[Assemble, null, null, null, drop] +item=Schematics, id=4577, option=[Assemble, null, null, null, drop] +item=Schematic, id=4578, option=[null, null, null, null, drop] +item=Cannon ball, id=4579, option=[null, null, null, null, drop] +item=Black spear, id=4580, option=[null, Wield, null, null, drop] +item=Black spear, id=4581, option=[null, null, null, null, drop] +item=Black spear(p), id=4582, option=[null, Wield, null, null, drop] +item=Black spear(p), id=4583, option=[null, null, null, null, drop] +item=Black spear(kp), id=4584, option=[null, Wield, null, null, drop] +item=Dragon plateskirt, id=4585, option=[null, Wear, null, null, drop] +item=Dragon plateskirt, id=4586, option=[null, null, null, null, drop] +item=Dragon scimitar, id=4587, option=[null, Wield, null, null, drop] +item=Dragon scimitar, id=4588, option=[null, null, null, null, drop] +item=Keys, id=4589, option=[null, null, null, null, drop] +item=Jewels, id=4590, option=[null, null, null, null, drop] +item=Karidian headpiece, id=4591, option=[null, null, null, null, drop] +item=Whoopsie, id=4592, option=[null, null, null, null, drop] +item=Fake beard, id=4593, option=[null, null, null, null, drop] +item=Whoopsie, id=4594, option=[null, null, null, null, drop] +item=Karidian disguise, id=4595, option=[null, null, null, null, drop] +item=Whoopsie, id=4596, option=[null, null, null, null, drop] +item=Note, id=4597, option=[Read, null, null, null, drop] +item=Note, id=4598, option=[Read, null, null, null, drop] +item=Oak-blackjack, id=4599, option=[null, Wield, null, null, drop] +item=Willow-blackjack, id=4600, option=[null, Wield, null, null, drop] +item=Ugthanki dung, id=4601, option=[null, null, null, Empty, drop] +item=Ugthanki dung, id=4602, option=[null, null, null, Empty, drop] +item=Receipt, id=4603, option=[null, null, null, null, drop] +item=Hag's poison, id=4604, option=[null, null, null, null, drop] +item=Snake charm, id=4605, option=[Play, null, null, null, drop] +item=Snake basket, id=4606, option=[null, null, null, null, drop] +item=Snake basket full, id=4607, option=[null, null, null, null, drop] +item=Super kebab, id=4608, option=[Eat, null, null, null, drop] +item=Super kebab, id=4609, option=[null, null, null, null, drop] +item=Red hot sauce, id=4610, option=[null, null, null, null, drop] +item=Desert disguise, id=4611, option=[null, Wear, null, null, drop] +item=Willow-blackjack, id=4612, option=[null, null, null, null, drop] +item=Spinning plate, id=4613, option=[Spin, null, null, null, drop] +item=Broken plate, id=4614, option=[null, null, null, null, drop] +item=Letter, id=4615, option=[Read, null, null, null, drop] +item=Varmen's notes, id=4616, option=[Read, null, null, null, drop] +item=Display cabinet key, id=4617, option=[null, null, null, null, drop] +item=Statuette, id=4618, option=[null, null, null, null, drop] +item=Strange implement, id=4619, option=[null, null, null, null, drop] +item=Black mushroom, id=4620, option=[Eat, null, null, null, drop] +item=Phoenix feather, id=4621, option=[null, null, null, null, drop] +item=Black mushroom ink, id=4622, option=[null, null, null, Empty, drop] +item=Phoenix quill pen, id=4623, option=[null, null, null, null, drop] +item=Golem program, id=4624, option=[null, null, null, null, drop] +item=Bandit, id=4625, option=[null, null, null, null, drop] +item=Whoopsie, id=4626, option=[Wear, null, null, null, drop] +item=Bandit's brew, id=4627, option=[Drink, null, null, null, drop] +item=Bandit's brew, id=4628, option=[null, null, null, null, drop] +item=null, id=4629, option=[null, null, null, null, drop] +item=null, id=4630, option=[null, null, null, null, drop] +item=null, id=4631, option=[null, null, null, null, drop] +item=null, id=4632, option=[null, null, null, null, drop] +item=null, id=4633, option=[null, null, null, null, drop] +item=null, id=4634, option=[null, null, null, null, drop] +item=null, id=4635, option=[null, null, null, null, drop] +item=null, id=4636, option=[null, null, null, null, drop] +item=null, id=4637, option=[null, null, null, null, drop] +item=null, id=4638, option=[null, null, null, null, drop] +item=null, id=4639, option=[null, null, null, null, drop] +item=null, id=4640, option=[null, null, null, null, drop] +item=null, id=4641, option=[null, null, null, null, drop] +item=null, id=4642, option=[null, null, null, null, drop] +item=null, id=4643, option=[null, null, null, null, drop] +item=null, id=4644, option=[null, null, null, null, drop] +item=null, id=4645, option=[null, null, null, null, drop] +item=null, id=4646, option=[null, null, null, null, drop] +item=null, id=4647, option=[null, null, null, null, drop] +item=null, id=4648, option=[null, null, null, null, drop] +item=null, id=4649, option=[null, null, null, null, drop] +item=null, id=4650, option=[null, null, null, null, drop] +item=null, id=4651, option=[null, null, null, null, drop] +item=null, id=4652, option=[null, null, null, null, drop] +item=Fire, id=4653, option=[null, null, null, null, drop] +item=Etchings, id=4654, option=[null, null, null, null, drop] +item=Translation, id=4655, option=[Read, null, null, null, drop] +item=Warm key, id=4656, option=[null, null, null, null, drop] +item=Ring of visibility, id=4657, option=[null, Wear, null, null, drop] +item=Silver pot, id=4658, option=[null, null, null, null, drop] +item=Blessed pot, id=4659, option=[null, null, null, null, drop] +item=Silver pot, id=4660, option=[null, null, null, null, drop] +item=Blessed pot, id=4661, option=[null, null, null, null, drop] +item=Silver pot, id=4662, option=[null, null, null, null, drop] +item=Blessed pot, id=4663, option=[null, null, null, null, drop] +item=Silver pot, id=4664, option=[null, null, null, null, drop] +item=Blessed pot, id=4665, option=[null, null, null, null, drop] +item=Silver pot, id=4666, option=[null, null, null, null, drop] +item=Blessed pot, id=4667, option=[null, null, null, null, drop] +item=Garlic powder, id=4668, option=[null, null, null, null, drop] +item=Whoopsie, id=4669, option=[null, null, null, null, drop] +item=Blood diamond, id=4670, option=[null, null, null, null, drop] +item=Ice diamond, id=4671, option=[null, null, null, null, drop] +item=Smoke diamond, id=4672, option=[null, null, null, null, drop] +item=Shadow diamond, id=4673, option=[null, null, null, null, drop] +item=Gilded cross, id=4674, option=[null, null, null, null, drop] +item=Ancient staff, id=4675, option=[null, Wield, null, null, drop] +item=Ancient staff, id=4676, option=[null, null, null, null, drop] +item=Catspeak amulet, id=4677, option=[null, Wear, null, null, drop] +item=Canopic jar, id=4678, option=[null, null, null, null, drop] +item=Canopic jar, id=4679, option=[null, null, null, null, drop] +item=Canopic jar, id=4680, option=[null, null, null, null, drop] +item=Canopic jar, id=4681, option=[null, null, null, null, drop] +item=Holy symbol, id=4682, option=[null, null, null, null, drop] +item=Unholy symbol, id=4683, option=[null, null, null, null, drop] +item=Linen, id=4684, option=[null, null, null, null, drop] +item=Whoopsie, id=4685, option=[null, null, null, null, drop] +item=Embalming manual, id=4686, option=[Read, null, null, null, drop] +item=Bucket of sap, id=4687, option=[null, null, null, Empty, drop] +item=Whoopsie, id=4688, option=[null, null, null, null, drop] +item=Pile of salt, id=4689, option=[null, null, null, null, drop] +item=Whoopsie, id=4690, option=[null, null, null, null, drop] +item=Sphinx's token, id=4691, option=[null, null, null, null, drop] +item=Gold leaf, id=4692, option=[null, null, null, null, drop] +item=Full bucket, id=4693, option=[null, null, null, Empty, drop] +item=Steam rune, id=4694, option=[null, null, null, null, drop] +item=Mist rune, id=4695, option=[null, null, null, null, drop] +item=Dust rune, id=4696, option=[null, null, null, null, drop] +item=Smoke rune, id=4697, option=[null, null, null, null, drop] +item=Mud rune, id=4698, option=[null, null, null, null, drop] +item=Lava rune, id=4699, option=[null, null, null, null, drop] +item=Sapphire lantern, id=4700, option=[null, null, null, null, drop] +item=Sapphire lantern, id=4701, option=[null, null, null, null, drop] +item=Sapphire lantern, id=4702, option=[Extinguish, null, null, null, drop] +item=Magic stone, id=4703, option=[null, null, null, null, drop] +item=Stone bowl, id=4704, option=[null, null, null, null, drop] +item=null, id=4705, option=[null, null, null, null, drop] +item=Whoopsie, id=4706, option=[Wear, null, null, null, drop] +item=Crumbling tome, id=4707, option=[Read, null, null, null, drop] +item=Ahrim's hood, id=4708, option=[null, Wear, null, null, drop] +item=Ahrim's hood, id=4709, option=[null, null, null, null, drop] +item=Ahrim's staff, id=4710, option=[null, Wield, null, null, drop] +item=Ahrim's staff, id=4711, option=[null, null, null, null, drop] +item=Ahrim's robetop, id=4712, option=[null, Wear, null, null, drop] +item=Ahrim's robetop, id=4713, option=[null, null, null, null, drop] +item=Ahrim's robeskirt, id=4714, option=[null, Wear, null, null, drop] +item=Ahrim's robeskirt, id=4715, option=[null, null, null, null, drop] +item=Dharok's helm, id=4716, option=[null, Wear, null, null, drop] +item=Dharok's helm, id=4717, option=[null, null, null, null, drop] +item=Dharok's greataxe, id=4718, option=[null, Wield, null, null, drop] +item=Dharok's greataxe, id=4719, option=[null, null, null, null, drop] +item=Dharok's platebody, id=4720, option=[null, Wear, null, null, drop] +item=Dharok's platebody, id=4721, option=[null, null, null, null, drop] +item=Dharok's platelegs, id=4722, option=[null, Wear, null, null, drop] +item=Dharok's platelegs, id=4723, option=[null, null, null, null, drop] +item=Guthan's helm, id=4724, option=[null, Wear, null, null, drop] +item=Guthan's helm, id=4725, option=[null, null, null, null, drop] +item=Guthan's warspear, id=4726, option=[null, Wield, null, null, drop] +item=Guthan's warspear, id=4727, option=[null, null, null, null, drop] +item=Guthan's platebody, id=4728, option=[null, Wear, null, null, drop] +item=Guthan's platebody, id=4729, option=[null, null, null, null, drop] +item=Guthan's chainskirt, id=4730, option=[null, Wear, null, null, drop] +item=Guthan's chainskirt, id=4731, option=[null, null, null, null, drop] +item=Karil's coif, id=4732, option=[null, Wear, null, null, drop] +item=Karil's coif, id=4733, option=[null, null, null, null, drop] +item=Karil's crossbow, id=4734, option=[null, Wield, null, null, drop] +item=Karil's crossbow, id=4735, option=[null, null, null, null, drop] +item=Karil's leathertop, id=4736, option=[null, Wear, null, null, drop] +item=Karil's leathertop, id=4737, option=[null, null, null, null, drop] +item=Karil's leatherskirt, id=4738, option=[null, Wear, null, null, drop] +item=Karil's leatherskirt, id=4739, option=[null, null, null, null, drop] +item=Bolt rack, id=4740, option=[null, Wield, null, null, drop] +item=null, id=4741, option=[null, null, null, null, drop] +item=null, id=4742, option=[null, null, null, null, drop] +item=null, id=4743, option=[null, null, null, null, drop] +item=null, id=4744, option=[null, null, null, null, drop] +item=Torag's helm, id=4745, option=[null, Wear, null, null, drop] +item=Torag's helm, id=4746, option=[null, null, null, null, drop] +item=Torag's hammers, id=4747, option=[null, Wield, null, null, drop] +item=Torag's hammers, id=4748, option=[null, null, null, null, drop] +item=Torag's platebody, id=4749, option=[null, Wear, null, null, drop] +item=Torag's platebody, id=4750, option=[null, null, null, null, drop] +item=Torag's platelegs, id=4751, option=[null, Wear, null, null, drop] +item=Torag's platelegs, id=4752, option=[null, null, null, null, drop] +item=Verac's helm, id=4753, option=[null, Wear, null, null, drop] +item=Verac's helm, id=4754, option=[null, null, null, null, drop] +item=Verac's flail, id=4755, option=[null, Wield, null, null, drop] +item=Verac's flail, id=4756, option=[null, null, null, null, drop] +item=Verac's brassard, id=4757, option=[null, Wear, null, null, drop] +item=Verac's brassard, id=4758, option=[null, null, null, null, drop] +item=Verac's plateskirt, id=4759, option=[null, Wear, null, null, drop] +item=Verac's plateskirt, id=4760, option=[null, null, null, null, drop] +item=null, id=4761, option=[null, null, null, null, drop] +item=null, id=4762, option=[null, null, null, null, drop] +item=null, id=4763, option=[null, null, null, null, drop] +item=null, id=4764, option=[null, null, null, null, drop] +item=null, id=4765, option=[null, null, null, null, drop] +item=null, id=4766, option=[null, null, null, null, drop] +item=null, id=4767, option=[null, null, null, null, drop] +item=null, id=4768, option=[null, null, null, null, drop] +item=null, id=4769, option=[null, null, null, null, drop] +item=null, id=4770, option=[null, null, null, null, drop] +item=null, id=4771, option=[null, null, null, null, drop] +item=null, id=4772, option=[null, null, null, null, drop] +item=Bronze brutal, id=4773, option=[null, Wield, null, null, drop] +item=null, id=4774, option=[null, null, null, null, drop] +item=null, id=4775, option=[null, null, null, null, drop] +item=null, id=4776, option=[null, null, null, null, drop] +item=null, id=4777, option=[null, null, null, null, drop] +item=Iron brutal, id=4778, option=[null, Wield, null, null, drop] +item=null, id=4779, option=[null, null, null, null, drop] +item=null, id=4780, option=[null, null, null, null, drop] +item=null, id=4781, option=[null, null, null, null, drop] +item=null, id=4782, option=[null, null, null, null, drop] +item=Steel brutal, id=4783, option=[null, Wield, null, null, drop] +item=null, id=4784, option=[null, null, null, null, drop] +item=null, id=4785, option=[null, null, null, null, drop] +item=null, id=4786, option=[null, null, null, null, drop] +item=null, id=4787, option=[null, null, null, null, drop] +item=Black brutal, id=4788, option=[null, Wield, null, null, drop] +item=null, id=4789, option=[null, null, null, null, drop] +item=null, id=4790, option=[null, null, null, null, drop] +item=null, id=4791, option=[null, null, null, null, drop] +item=null, id=4792, option=[null, null, null, null, drop] +item=Mithril brutal, id=4793, option=[null, Wield, null, null, drop] +item=null, id=4794, option=[null, null, null, null, drop] +item=null, id=4795, option=[null, null, null, null, drop] +item=null, id=4796, option=[null, null, null, null, drop] +item=null, id=4797, option=[null, null, null, null, drop] +item=Adamant brutal, id=4798, option=[null, Wield, null, null, drop] +item=null, id=4799, option=[null, null, null, null, drop] +item=null, id=4800, option=[null, null, null, null, drop] +item=null, id=4801, option=[null, null, null, null, drop] +item=null, id=4802, option=[null, null, null, null, drop] +item=Rune brutal, id=4803, option=[null, Wield, null, null, drop] +item=null, id=4804, option=[null, null, null, null, drop] +item=null, id=4805, option=[null, null, null, null, drop] +item=null, id=4806, option=[null, null, null, null, drop] +item=null, id=4807, option=[null, null, null, null, drop] +item=Black prism, id=4808, option=[Look-at, null, null, null, drop] +item=Torn page, id=4809, option=[Read, null, null, null, drop] +item=Ruined backpack, id=4810, option=[Open, null, null, null, drop] +item=Dragon inn tankard, id=4811, option=[Look-at, null, null, null, drop] +item=Zogre bones, id=4812, option=[Bury, null, null, null, drop] +item=Zogre bones, id=4813, option=[null, null, null, null, drop] +item=Sithik portrait, id=4814, option=[null, null, null, null, drop] +item=Sithik portrait, id=4815, option=[null, null, null, null, drop] +item=Signed portrait, id=4816, option=[Look-at, null, null, null, drop] +item=Book of portraiture, id=4817, option=[Read, null, null, null, drop] +item=Ogre artefact, id=4818, option=[null, null, null, null, drop] +item=Bronze nails, id=4819, option=[null, null, null, null, drop] +item=Iron nails, id=4820, option=[null, null, null, null, drop] +item=Black nails, id=4821, option=[null, null, null, null, drop] +item=Mithril nails, id=4822, option=[null, null, null, null, drop] +item=Adamantite nails, id=4823, option=[null, null, null, null, drop] +item=Rune nails, id=4824, option=[null, null, null, null, drop] +item=Unstrung comp bow, id=4825, option=[null, null, null, null, drop] +item=Unstrung comp bow, id=4826, option=[null, null, null, null, drop] +item=Comp ogre bow, id=4827, option=[null, Wield, Check kills, null, drop] +item=Comp ogre bow, id=4828, option=[null, null, null, null, drop] +item=Book of 'h.a.m', id=4829, option=[Read, null, null, null, drop] +item=Fayrg bones, id=4830, option=[Bury, null, null, null, drop] +item=Fayrg bones, id=4831, option=[null, null, null, null, drop] +item=Raurg bones, id=4832, option=[Bury, null, null, null, drop] +item=Raurg bones, id=4833, option=[null, null, null, null, drop] +item=Ourg bones, id=4834, option=[Bury, null, null, null, drop] +item=Ourg bones, id=4835, option=[null, null, null, null, drop] +item=Strange potion, id=4836, option=[null, null, null, null, drop] +item=Necromancy book, id=4837, option=[Read, null, null, null, drop] +item=Cup of tea, id=4838, option=[null, null, null, null, drop] +item=Ogre gate key, id=4839, option=[null, null, null, null, drop] +item=Rogue's purse potion(unf), id=4840, option=[null, null, null, Empty, drop] +item=Rogue's purse potion(unf), id=4841, option=[null, null, null, null, drop] +item=Relicym's balm(4), id=4842, option=[Drink, null, null, Empty, drop] +item=Relicym's balm(4), id=4843, option=[null, null, null, null, drop] +item=Relicym's balm(3), id=4844, option=[Drink, null, null, Empty, drop] +item=Relicym's balm(3), id=4845, option=[null, null, null, null, drop] +item=Relicym's balm(2), id=4846, option=[Drink, null, null, Empty, drop] +item=Relicym's balm(2), id=4847, option=[null, null, null, null, drop] +item=Relicym's balm(1), id=4848, option=[Drink, null, null, Empty, drop] +item=Relicym's balm(1), id=4849, option=[null, null, null, null, drop] +item=Ogre coffin key, id=4850, option=[null, null, null, null, drop] +item=Ogre coffin key, id=4851, option=[null, null, null, null, drop] +item=Bonemeal, id=4852, option=[null, Empty, null, null, drop] +item=Bonemeal, id=4853, option=[null, Empty, null, null, drop] +item=Bonemeal, id=4854, option=[null, Empty, null, null, drop] +item=Bonemeal, id=4855, option=[null, Empty, null, null, drop] +item=Ahrim's hood 100, id=4856, option=[null, Wear, null, null, drop] +item=Ahrim's hood 75, id=4857, option=[null, Wear, null, null, drop] +item=Ahrim's hood 50, id=4858, option=[null, Wear, null, null, drop] +item=Ahrim's hood 25, id=4859, option=[null, Wear, null, null, drop] +item=Ahrim's hood 0, id=4860, option=[null, null, null, null, drop] +item=Ahrim's hood 0, id=4861, option=[null, null, null, null, drop] +item=Ahrim's staff 100, id=4862, option=[null, Wield, null, null, drop] +item=Ahrim's staff 75, id=4863, option=[null, Wield, null, null, drop] +item=Ahrim's staff 50, id=4864, option=[null, Wield, null, null, drop] +item=Ahrim's staff 25, id=4865, option=[null, Wield, null, null, drop] +item=Ahrim's staff 0, id=4866, option=[null, null, null, null, drop] +item=Ahrim's staff 0, id=4867, option=[null, null, null, null, drop] +item=Ahrim's top 100, id=4868, option=[null, Wear, null, null, drop] +item=Ahrim's top 75, id=4869, option=[null, Wear, null, null, drop] +item=Ahrim's top 50, id=4870, option=[null, Wear, null, null, drop] +item=Ahrim's top 25, id=4871, option=[null, Wear, null, null, drop] +item=Ahrim's top 0, id=4872, option=[null, null, null, null, drop] +item=Ahrim's top 0, id=4873, option=[null, null, null, null, drop] +item=Ahrim's skirt 100, id=4874, option=[null, Wear, null, null, drop] +item=Ahrim's skirt 75, id=4875, option=[null, Wear, null, null, drop] +item=Ahrim's skirt 50, id=4876, option=[null, Wear, null, null, drop] +item=Ahrim's skirt 25, id=4877, option=[null, Wear, null, null, drop] +item=Ahrim's skirt 0, id=4878, option=[null, null, null, null, drop] +item=Ahrim's skirt 0, id=4879, option=[null, null, null, null, drop] +item=Dharok's helm 100, id=4880, option=[null, Wear, null, null, drop] +item=Dharok's helm 75, id=4881, option=[null, Wear, null, null, drop] +item=Dharok's helm 50, id=4882, option=[null, Wear, null, null, drop] +item=Dharok's helm 25, id=4883, option=[null, Wear, null, null, drop] +item=Dharok's helm 0, id=4884, option=[null, null, null, null, drop] +item=Dharok's helm 0, id=4885, option=[null, null, null, null, drop] +item=Dharok's axe 100, id=4886, option=[null, Wield, null, null, drop] +item=Dharok's axe 75, id=4887, option=[null, Wield, null, null, drop] +item=Dharok's axe 50, id=4888, option=[null, Wield, null, null, drop] +item=Dharok's axe 25, id=4889, option=[null, Wield, null, null, drop] +item=Dharok's axe 0, id=4890, option=[null, null, null, null, drop] +item=Dharok's axe 0, id=4891, option=[null, null, null, null, drop] +item=Dharok's body 100, id=4892, option=[null, Wear, null, null, drop] +item=Dharok's body 75, id=4893, option=[null, Wear, null, null, drop] +item=Dharok's body 50, id=4894, option=[null, Wear, null, null, drop] +item=Dharok's body 25, id=4895, option=[null, Wear, null, null, drop] +item=Dharok's body 0, id=4896, option=[null, null, null, null, drop] +item=Dharok's body 0, id=4897, option=[null, null, null, null, drop] +item=Dharok's legs 100, id=4898, option=[null, Wear, null, null, drop] +item=Dharok's legs 75, id=4899, option=[null, Wear, null, null, drop] +item=Dharok's legs 50, id=4900, option=[null, Wear, null, null, drop] +item=Dharok's legs 25, id=4901, option=[null, Wear, null, null, drop] +item=Dharok's legs 0, id=4902, option=[null, null, null, null, drop] +item=Dharok's legs 0, id=4903, option=[null, null, null, null, drop] +item=Guthan's helm 100, id=4904, option=[null, Wear, null, null, drop] +item=Guthan's helm 75, id=4905, option=[null, Wear, null, null, drop] +item=Guthan's helm 50, id=4906, option=[null, Wear, null, null, drop] +item=Guthan's helm 25, id=4907, option=[null, Wear, null, null, drop] +item=Guthan's helm 0, id=4908, option=[null, null, null, null, drop] +item=Guthan's helm 0, id=4909, option=[null, null, null, null, drop] +item=Guthan's spear 100, id=4910, option=[null, Wield, null, null, drop] +item=Guthan's spear 75, id=4911, option=[null, Wield, null, null, drop] +item=Guthan's spear 50, id=4912, option=[null, Wield, null, null, drop] +item=Guthan's spear 25, id=4913, option=[null, Wield, null, null, drop] +item=Guthan's spear 0, id=4914, option=[null, null, null, null, drop] +item=Guthan's spear 0, id=4915, option=[null, null, null, null, drop] +item=Guthan's body 100, id=4916, option=[null, Wear, null, null, drop] +item=Guthan's body 75, id=4917, option=[null, Wear, null, null, drop] +item=Guthan's body 50, id=4918, option=[null, Wear, null, null, drop] +item=Guthan's body 25, id=4919, option=[null, Wear, null, null, drop] +item=Guthan's body 0, id=4920, option=[null, null, null, null, drop] +item=Guthan's body 0, id=4921, option=[null, null, null, null, drop] +item=Guthan's skirt 100, id=4922, option=[null, Wear, null, null, drop] +item=Guthan's skirt 75, id=4923, option=[null, Wear, null, null, drop] +item=Guthan's skirt 50, id=4924, option=[null, Wear, null, null, drop] +item=Guthan's skirt 25, id=4925, option=[null, Wear, null, null, drop] +item=Guthan's skirt 0, id=4926, option=[null, null, null, null, drop] +item=Guthan's skirt 0, id=4927, option=[null, null, null, null, drop] +item=Karil's coif 100, id=4928, option=[null, Wear, null, null, drop] +item=Karil's coif 75, id=4929, option=[null, Wear, null, null, drop] +item=Karil's coif 50, id=4930, option=[null, Wear, null, null, drop] +item=Karil's coif 25, id=4931, option=[null, Wear, null, null, drop] +item=Karil's coif 0, id=4932, option=[null, null, null, null, drop] +item=Karil's coif 0, id=4933, option=[null, null, null, null, drop] +item=Karil's x-bow 100, id=4934, option=[null, Wield, null, null, drop] +item=Karil's x-bow 75, id=4935, option=[null, Wield, null, null, drop] +item=Karil's x-bow 50, id=4936, option=[null, Wield, null, null, drop] +item=Karil's x-bow 25, id=4937, option=[null, Wield, null, null, drop] +item=Karil's x-bow 0, id=4938, option=[null, null, null, null, drop] +item=Karil's x-bow 0, id=4939, option=[null, null, null, null, drop] +item=Karil's top 100, id=4940, option=[null, Wear, null, null, drop] +item=Karil's top 75, id=4941, option=[null, Wear, null, null, drop] +item=Karil's top 50, id=4942, option=[null, Wear, null, null, drop] +item=Karil's top 25, id=4943, option=[null, Wear, null, null, drop] +item=Karil's top 0, id=4944, option=[null, null, null, null, drop] +item=Karil's top 0, id=4945, option=[null, null, null, null, drop] +item=Karil's skirt 100, id=4946, option=[null, Wear, null, null, drop] +item=Karil's skirt 75, id=4947, option=[null, Wear, null, null, drop] +item=Karil's skirt 50, id=4948, option=[null, Wear, null, null, drop] +item=Karil's skirt 25, id=4949, option=[null, Wear, null, null, drop] +item=Karil's skirt 0, id=4950, option=[null, null, null, null, drop] +item=Karil's skirt 0, id=4951, option=[null, null, null, null, drop] +item=Torag's helm 100, id=4952, option=[null, Wear, null, null, drop] +item=Torag's helm 75, id=4953, option=[null, Wear, null, null, drop] +item=Torag's helm 50, id=4954, option=[null, Wear, null, null, drop] +item=Torag's helm 25, id=4955, option=[null, Wear, null, null, drop] +item=Torag's helm 0, id=4956, option=[null, null, null, null, drop] +item=Torag's helm 0, id=4957, option=[null, null, null, null, drop] +item=Torag's hammer 100, id=4958, option=[null, Wield, null, null, drop] +item=Torag's hammer 75, id=4959, option=[null, Wield, null, null, drop] +item=Torag's hammer 50, id=4960, option=[null, Wield, null, null, drop] +item=Torag's hammer 25, id=4961, option=[null, Wield, null, null, drop] +item=Torag's hammer 0, id=4962, option=[null, null, null, null, drop] +item=Torag's hammer 0, id=4963, option=[null, null, null, null, drop] +item=Torag's body 100, id=4964, option=[null, Wear, null, null, drop] +item=Torag's body 75, id=4965, option=[null, Wear, null, null, drop] +item=Torag's body 50, id=4966, option=[null, Wear, null, null, drop] +item=Torag's body 25, id=4967, option=[null, Wear, null, null, drop] +item=Torag's body 0, id=4968, option=[null, null, null, null, drop] +item=Torag's body 0, id=4969, option=[null, null, null, null, drop] +item=Torag's legs 100, id=4970, option=[null, Wear, null, null, drop] +item=Torag's legs 75, id=4971, option=[null, Wear, null, null, drop] +item=Torag's legs 50, id=4972, option=[null, Wear, null, null, drop] +item=Torag's legs 25, id=4973, option=[null, Wear, null, null, drop] +item=Torag's legs 0, id=4974, option=[null, null, null, null, drop] +item=Torag's legs 0, id=4975, option=[null, null, null, null, drop] +item=Verac's helm 100, id=4976, option=[null, Wear, null, null, drop] +item=Verac's helm 75, id=4977, option=[null, Wear, null, null, drop] +item=Verac's helm 50, id=4978, option=[null, Wear, null, null, drop] +item=Verac's helm 25, id=4979, option=[null, Wear, null, null, drop] +item=Verac's helm 0, id=4980, option=[null, null, null, null, drop] +item=Verac's helm 0, id=4981, option=[null, null, null, null, drop] +item=Verac's flail 100, id=4982, option=[null, Wield, null, null, drop] +item=Verac's flail 75, id=4983, option=[null, Wield, null, null, drop] +item=Verac's flail 50, id=4984, option=[null, Wield, null, null, drop] +item=Verac's flail 25, id=4985, option=[null, Wield, null, null, drop] +item=Verac's flail 0, id=4986, option=[null, null, null, null, drop] +item=Verac's flail 0, id=4987, option=[null, null, null, null, drop] +item=Verac's top 100, id=4988, option=[null, Wear, null, null, drop] +item=Verac's top 75, id=4989, option=[null, Wear, null, null, drop] +item=Verac's top 50, id=4990, option=[null, Wear, null, null, drop] +item=Verac's top 25, id=4991, option=[null, Wear, null, null, drop] +item=Verac's top 0, id=4992, option=[null, null, null, null, drop] +item=Verac's top 0, id=4993, option=[null, null, null, null, drop] +item=Verac's skirt 100, id=4994, option=[null, Wear, null, null, drop] +item=Verac's skirt 75, id=4995, option=[null, Wear, null, null, drop] +item=Verac's skirt 50, id=4996, option=[null, Wear, null, null, drop] +item=Verac's skirt 25, id=4997, option=[null, Wear, null, null, drop] +item=Verac's skirt 0, id=4998, option=[null, null, null, null, drop] +item=Verac's skirt 0, id=4999, option=[null, null, null, null, drop] +item=null, id=5000, option=[null, null, null, null, drop] +item=Raw cave eel, id=5001, option=[null, null, null, null, drop] +item=Burnt cave eel, id=5002, option=[null, null, null, null, drop] +item=Cave eel, id=5003, option=[Eat, null, null, null, drop] +item=Frog spawn, id=5004, option=[Eat, null, null, null, drop] +item=Raw cave eel, id=5005, option=[null, null, null, null, drop] +item=Burnt cave eel, id=5006, option=[null, null, null, null, drop] +item=Cave eel, id=5007, option=[null, null, null, null, drop] +item=Brooch, id=5008, option=[Look-at, null, null, null, drop] +item=Goblin symbol book, id=5009, option=[Read, null, null, null, drop] +item=Key, id=5010, option=[null, null, null, null, drop] +item=Silverware, id=5011, option=[null, null, null, null, drop] +item=Peace treaty, id=5012, option=[null, null, null, null, drop] +item=Mining helmet, id=5013, option=[null, Wear, Extinguish, null, drop] +item=Mining helmet, id=5014, option=[null, Wear, null, null, drop] +item=Mining helmet, id=5015, option=[null, null, null, null, drop] +item=Bone spear, id=5016, option=[null, Wield, null, null, drop] +item=Bone spear, id=5017, option=[null, null, null, null, drop] +item=Bone club, id=5018, option=[null, Wield, null, null, drop] +item=Bone club, id=5019, option=[null, null, null, null, drop] +item=Minecart ticket, id=5020, option=[null, null, null, null, drop] +item=Minecart ticket, id=5021, option=[null, null, null, null, drop] +item=Minecart ticket, id=5022, option=[null, null, null, null, drop] +item=Minecart ticket, id=5023, option=[null, null, null, null, drop] +item=Woven top, id=5024, option=[null, Wear, null, null, drop] +item=Woven top, id=5025, option=[null, null, null, null, drop] +item=Woven top, id=5026, option=[null, Wear, null, null, drop] +item=Woven top, id=5027, option=[null, null, null, null, drop] +item=Woven top, id=5028, option=[null, Wear, null, null, drop] +item=Woven top, id=5029, option=[null, null, null, null, drop] +item=Shirt, id=5030, option=[null, Wear, null, null, drop] +item=Shirt, id=5031, option=[null, null, null, null, drop] +item=Shirt, id=5032, option=[null, Wear, null, null, drop] +item=Shirt, id=5033, option=[null, null, null, null, drop] +item=Shirt, id=5034, option=[null, Wear, null, null, drop] +item=Shirt, id=5035, option=[null, null, null, null, drop] +item=Trousers, id=5036, option=[null, Wear, null, null, drop] +item=Trousers, id=5037, option=[null, null, null, null, drop] +item=Trousers, id=5038, option=[null, Wear, null, null, drop] +item=Trousers, id=5039, option=[null, null, null, null, drop] +item=Trousers, id=5040, option=[null, Wear, null, null, drop] +item=Trousers, id=5041, option=[null, null, null, null, drop] +item=Shorts, id=5042, option=[null, Wear, null, null, drop] +item=Shorts, id=5043, option=[null, null, null, null, drop] +item=Shorts, id=5044, option=[null, Wear, null, null, drop] +item=Shorts, id=5045, option=[null, null, null, null, drop] +item=Shorts, id=5046, option=[null, Wear, null, null, drop] +item=Shorts, id=5047, option=[null, null, null, null, drop] +item=Skirt, id=5048, option=[null, Wear, null, null, drop] +item=Skirt, id=5049, option=[null, null, null, null, drop] +item=Skirt, id=5050, option=[null, Wear, null, null, drop] +item=Skirt, id=5051, option=[null, null, null, null, drop] +item=Skirt, id=5052, option=[null, Wear, null, null, drop] +item=Skirt, id=5053, option=[null, null, null, null, drop] +item=Dwarf, id=5054, option=[null, null, null, null, drop] +item=Dwarf, id=5055, option=[null, null, null, null, drop] +item=Dwarven battleaxe, id=5056, option=[Wield, null, null, null, drop] +item=Dwarven battleaxe, id=5057, option=[Wield, null, null, null, drop] +item=Dwarven battleaxe, id=5058, option=[Wield, null, null, null, drop] +item=Dwarven battleaxe, id=5059, option=[Wield, null, null, null, drop] +item=Dwarven battleaxe, id=5060, option=[null, null, null, null, drop] +item=Dwarven battleaxe, id=5061, option=[null, null, null, null, drop] +item=Left boot, id=5062, option=[Wear, null, null, null, drop] +item=Right boot, id=5063, option=[Wear, null, null, null, drop] +item=Exquisite boots, id=5064, option=[Wear, null, null, null, drop] +item=Book on costumes, id=5065, option=[null, null, null, null, drop] +item=Meeting notes, id=5066, option=[Read, null, null, null, drop] +item=Exquisite clothes, id=5067, option=[Wear, null, null, null, drop] +item=Master farmer, id=5068, option=[null, null, null, null, drop] +item=Whoopsie, id=5069, option=[Wear, null, null, null, drop] +item=Bird's nest, id=5070, option=[Search, null, null, null, drop] +item=Bird's nest, id=5071, option=[Search, null, null, null, drop] +item=Bird's nest, id=5072, option=[Search, null, null, null, drop] +item=Bird's nest, id=5073, option=[Search, null, null, null, drop] +item=Bird's nest, id=5074, option=[Search, null, null, null, drop] +item=Bird's nest, id=5075, option=[null, null, null, null, drop] +item=Bird's egg, id=5076, option=[null, null, null, null, drop] +item=Bird's egg, id=5077, option=[null, null, null, null, drop] +item=Bird's egg, id=5078, option=[null, null, null, null, drop] +item=null, id=5079, option=[null, null, null, null, drop] +item=null, id=5080, option=[null, null, null, null, drop] +item=Whoopsie, id=5081, option=[Wear, null, null, null, drop] +item=null, id=5082, option=[null, null, null, null, drop] +item=Whoopsie, id=5083, option=[Wear, null, null, null, drop] +item=null, id=5084, option=[null, null, null, null, drop] +item=Whoopsie, id=5085, option=[Wear, null, null, null, drop] +item=null, id=5086, option=[null, null, null, null, drop] +item=Whoopsie, id=5087, option=[Wear, null, null, null, drop] +item=null, id=5088, option=[null, null, null, null, drop] +item=Whoopsie, id=5089, option=[Wear, null, null, null, drop] +item=null, id=5090, option=[null, null, null, null, drop] +item=Whoopsie, id=5091, option=[Wear, null, null, null, drop] +item=null, id=5092, option=[null, null, null, null, drop] +item=Whoopsie, id=5093, option=[Wear, null, null, null, drop] +item=null, id=5094, option=[null, null, null, null, drop] +item=Whoopsie, id=5095, option=[Wear, null, null, null, drop] +item=Marigold seed, id=5096, option=[null, null, null, null, drop] +item=Rosemary seed, id=5097, option=[null, null, null, null, drop] +item=Nasturtium seed, id=5098, option=[null, null, null, null, drop] +item=Woad seed, id=5099, option=[null, null, null, null, drop] +item=Limpwurt seed, id=5100, option=[null, null, null, null, drop] +item=Redberry seed, id=5101, option=[null, null, null, null, drop] +item=Cadavaberry seed, id=5102, option=[null, null, null, null, drop] +item=Dwellberry seed, id=5103, option=[null, null, null, null, drop] +item=Jangerberry seed, id=5104, option=[null, null, null, null, drop] +item=Whiteberry seed, id=5105, option=[null, null, null, null, drop] +item=Poison ivy seed, id=5106, option=[null, null, null, null, drop] +item=null, id=5107, option=[null, null, null, null, drop] +item=null, id=5108, option=[null, null, null, null, drop] +item=null, id=5109, option=[null, null, null, null, drop] +item=null, id=5110, option=[null, null, null, null, drop] +item=null, id=5111, option=[null, null, null, null, drop] +item=null, id=5112, option=[null, null, null, null, drop] +item=null, id=5113, option=[null, null, null, null, drop] +item=null, id=5114, option=[null, null, null, null, drop] +item=null, id=5115, option=[null, null, null, null, drop] +item=null, id=5116, option=[null, null, null, null, drop] +item=null, id=5117, option=[null, null, null, null, drop] +item=null, id=5118, option=[null, null, null, null, drop] +item=null, id=5119, option=[null, null, null, null, drop] +item=null, id=5120, option=[null, null, null, null, drop] +item=null, id=5121, option=[null, null, null, null, drop] +item=null, id=5122, option=[null, null, null, null, drop] +item=null, id=5123, option=[null, null, null, null, drop] +item=null, id=5124, option=[null, null, null, null, drop] +item=null, id=5125, option=[null, null, null, null, drop] +item=null, id=5126, option=[null, null, null, null, drop] +item=null, id=5127, option=[null, null, null, null, drop] +item=null, id=5128, option=[null, null, null, null, drop] +item=null, id=5129, option=[null, null, null, null, drop] +item=null, id=5130, option=[null, null, null, null, drop] +item=null, id=5131, option=[null, null, null, null, drop] +item=null, id=5132, option=[null, null, null, null, drop] +item=null, id=5133, option=[null, null, null, null, drop] +item=null, id=5134, option=[null, null, null, null, drop] +item=null, id=5135, option=[null, null, null, null, drop] +item=null, id=5136, option=[null, null, null, null, drop] +item=null, id=5137, option=[null, null, null, null, drop] +item=null, id=5138, option=[null, null, null, null, drop] +item=null, id=5139, option=[null, null, null, null, drop] +item=null, id=5140, option=[null, null, null, null, drop] +item=null, id=5141, option=[null, null, null, null, drop] +item=null, id=5142, option=[null, null, null, null, drop] +item=null, id=5143, option=[null, null, null, null, drop] +item=null, id=5144, option=[null, null, null, null, drop] +item=null, id=5145, option=[null, null, null, null, drop] +item=null, id=5146, option=[null, null, null, null, drop] +item=null, id=5147, option=[null, null, null, null, drop] +item=null, id=5148, option=[null, null, null, null, drop] +item=null, id=5149, option=[null, null, null, null, drop] +item=null, id=5150, option=[null, null, null, null, drop] +item=null, id=5151, option=[null, null, null, null, drop] +item=null, id=5152, option=[null, null, null, null, drop] +item=null, id=5153, option=[null, null, null, null, drop] +item=null, id=5154, option=[null, null, null, null, drop] +item=null, id=5155, option=[null, null, null, null, drop] +item=null, id=5156, option=[null, null, null, null, drop] +item=null, id=5157, option=[null, null, null, null, drop] +item=null, id=5158, option=[null, null, null, null, drop] +item=null, id=5159, option=[null, null, null, null, drop] +item=null, id=5160, option=[null, null, null, null, drop] +item=null, id=5161, option=[null, null, null, null, drop] +item=null, id=5162, option=[null, null, null, null, drop] +item=null, id=5163, option=[null, null, null, null, drop] +item=null, id=5164, option=[null, null, null, null, drop] +item=null, id=5165, option=[null, null, null, null, drop] +item=null, id=5166, option=[null, null, null, null, drop] +item=null, id=5167, option=[null, null, null, null, drop] +item=null, id=5168, option=[null, null, null, null, drop] +item=null, id=5169, option=[null, null, null, null, drop] +item=null, id=5170, option=[null, null, null, null, drop] +item=Seeds, id=5171, option=[null, null, null, null, drop] +item=null, id=5172, option=[null, null, null, null, drop] +item=null, id=5173, option=[null, null, null, null, drop] +item=null, id=5174, option=[null, null, null, null, drop] +item=null, id=5175, option=[null, null, null, null, drop] +item=null, id=5176, option=[null, null, null, null, drop] +item=null, id=5177, option=[null, null, null, null, drop] +item=null, id=5178, option=[null, null, null, null, drop] +item=null, id=5179, option=[null, null, null, null, drop] +item=null, id=5180, option=[null, null, null, null, drop] +item=null, id=5181, option=[null, null, null, null, drop] +item=null, id=5182, option=[null, null, null, null, drop] +item=null, id=5183, option=[null, null, null, null, drop] +item=null, id=5184, option=[null, null, null, null, drop] +item=null, id=5185, option=[null, null, null, null, drop] +item=null, id=5186, option=[null, null, null, null, drop] +item=null, id=5187, option=[null, null, null, null, drop] +item=null, id=5188, option=[null, null, null, null, drop] +item=null, id=5189, option=[null, null, null, null, drop] +item=null, id=5190, option=[null, null, null, null, drop] +item=null, id=5191, option=[null, null, null, null, drop] +item=null, id=5192, option=[null, null, null, null, drop] +item=null, id=5193, option=[null, null, null, null, drop] +item=null, id=5194, option=[null, null, null, null, drop] +item=null, id=5195, option=[null, null, null, null, drop] +item=null, id=5196, option=[null, null, null, null, drop] +item=null, id=5197, option=[null, null, null, null, drop] +item=null, id=5198, option=[null, null, null, null, drop] +item=null, id=5199, option=[null, null, null, null, drop] +item=null, id=5200, option=[null, null, null, null, drop] +item=null, id=5201, option=[null, null, null, null, drop] +item=null, id=5202, option=[null, null, null, null, drop] +item=null, id=5203, option=[null, null, null, null, drop] +item=null, id=5204, option=[null, null, null, null, drop] +item=null, id=5205, option=[null, null, null, null, drop] +item=null, id=5206, option=[null, null, null, null, drop] +item=null, id=5207, option=[null, null, null, null, drop] +item=null, id=5208, option=[null, null, null, null, drop] +item=null, id=5209, option=[null, null, null, null, drop] +item=null, id=5210, option=[null, null, null, null, drop] +item=null, id=5211, option=[null, null, null, null, drop] +item=null, id=5212, option=[null, null, null, null, drop] +item=null, id=5213, option=[null, null, null, null, drop] +item=null, id=5214, option=[null, null, null, null, drop] +item=null, id=5215, option=[null, null, null, null, drop] +item=null, id=5216, option=[null, null, null, null, drop] +item=null, id=5217, option=[null, null, null, null, drop] +item=null, id=5218, option=[null, null, null, null, drop] +item=null, id=5219, option=[null, null, null, null, drop] +item=null, id=5220, option=[null, null, null, null, drop] +item=null, id=5221, option=[null, null, null, null, drop] +item=null, id=5222, option=[null, null, null, null, drop] +item=null, id=5223, option=[null, null, null, null, drop] +item=null, id=5224, option=[null, null, null, null, drop] +item=null, id=5225, option=[null, null, null, null, drop] +item=null, id=5226, option=[null, null, null, null, drop] +item=null, id=5227, option=[null, null, null, null, drop] +item=null, id=5228, option=[null, null, null, null, drop] +item=null, id=5229, option=[null, null, null, null, drop] +item=null, id=5230, option=[null, null, null, null, drop] +item=null, id=5231, option=[null, null, null, null, drop] +item=null, id=5232, option=[null, null, null, null, drop] +item=null, id=5233, option=[null, null, null, null, drop] +item=null, id=5234, option=[null, null, null, null, drop] +item=null, id=5235, option=[null, null, null, null, drop] +item=null, id=5236, option=[null, null, null, null, drop] +item=null, id=5237, option=[null, null, null, null, drop] +item=null, id=5238, option=[null, null, null, null, drop] +item=null, id=5239, option=[null, null, null, null, drop] +item=null, id=5240, option=[null, null, null, null, drop] +item=null, id=5241, option=[null, null, null, null, drop] +item=null, id=5242, option=[null, null, null, null, drop] +item=null, id=5243, option=[null, null, null, null, drop] +item=null, id=5244, option=[null, null, null, null, drop] +item=null, id=5245, option=[null, null, null, null, drop] +item=null, id=5246, option=[null, null, null, null, drop] +item=null, id=5247, option=[null, null, null, null, drop] +item=null, id=5248, option=[null, null, null, null, drop] +item=null, id=5249, option=[null, null, null, null, drop] +item=null, id=5250, option=[null, null, null, null, drop] +item=null, id=5251, option=[null, null, null, null, drop] +item=null, id=5252, option=[null, null, null, null, drop] +item=null, id=5253, option=[null, null, null, null, drop] +item=null, id=5254, option=[null, null, null, null, drop] +item=null, id=5255, option=[null, null, null, null, drop] +item=null, id=5256, option=[null, null, null, null, drop] +item=null, id=5257, option=[null, null, null, null, drop] +item=null, id=5258, option=[null, null, null, null, drop] +item=null, id=5259, option=[null, null, null, null, drop] +item=null, id=5260, option=[null, null, null, null, drop] +item=null, id=5261, option=[null, null, null, null, drop] +item=null, id=5262, option=[null, null, null, null, drop] +item=null, id=5263, option=[null, null, null, null, drop] +item=null, id=5264, option=[null, null, null, null, drop] +item=null, id=5265, option=[null, null, null, null, drop] +item=null, id=5266, option=[null, null, null, null, drop] +item=null, id=5267, option=[null, null, null, null, drop] +item=null, id=5268, option=[null, null, null, null, drop] +item=null, id=5269, option=[null, null, null, null, drop] +item=null, id=5270, option=[null, null, null, null, drop] +item=null, id=5271, option=[null, null, null, null, drop] +item=null, id=5272, option=[null, null, null, null, drop] +item=null, id=5273, option=[null, null, null, null, drop] +item=null, id=5274, option=[null, null, null, null, drop] +item=null, id=5275, option=[null, null, null, null, drop] +item=null, id=5276, option=[null, null, null, null, drop] +item=null, id=5277, option=[null, null, null, null, drop] +item=null, id=5278, option=[null, null, null, null, drop] +item=null, id=5279, option=[null, null, null, null, drop] +item=Cactus seed, id=5280, option=[null, null, null, null, drop] +item=Belladonna seed, id=5281, option=[null, null, null, null, drop] +item=Mushroom spore, id=5282, option=[null, null, null, null, drop] +item=Apple tree seed, id=5283, option=[null, null, null, null, drop] +item=Banana tree seed, id=5284, option=[null, null, null, null, drop] +item=Orange tree seed, id=5285, option=[null, null, null, null, drop] +item=Curry tree seed, id=5286, option=[null, null, null, null, drop] +item=Pineapple seed, id=5287, option=[null, null, null, null, drop] +item=Papaya tree seed, id=5288, option=[null, null, null, null, drop] +item=Palm tree seed, id=5289, option=[null, null, null, null, drop] +item=Calquat tree seed, id=5290, option=[null, null, null, null, drop] +item=Guam seed, id=5291, option=[null, null, null, null, drop] +item=Marrentill seed, id=5292, option=[null, null, null, null, drop] +item=Tarromin seed, id=5293, option=[null, null, null, null, drop] +item=Harralander seed, id=5294, option=[null, null, null, null, drop] +item=Ranarr seed, id=5295, option=[null, null, null, null, drop] +item=Toadflax seed, id=5296, option=[null, null, null, null, drop] +item=Irit seed, id=5297, option=[null, null, null, null, drop] +item=Avantoe seed, id=5298, option=[null, null, null, null, drop] +item=Kwuarm seed, id=5299, option=[null, null, null, null, drop] +item=Snapdragon seed, id=5300, option=[null, null, null, null, drop] +item=Cadantine seed, id=5301, option=[null, null, null, null, drop] +item=Lantadyme seed, id=5302, option=[null, null, null, null, drop] +item=Dwarf weed seed, id=5303, option=[null, null, null, null, drop] +item=Torstol seed, id=5304, option=[null, null, null, null, drop] +item=Barley seed, id=5305, option=[null, null, null, null, drop] +item=Jute seed, id=5306, option=[null, null, null, null, drop] +item=Hammerstone seed, id=5307, option=[null, null, null, null, drop] +item=Asgarnian seed, id=5308, option=[null, null, null, null, drop] +item=Yanillian seed, id=5309, option=[null, null, null, null, drop] +item=Krandorian seed, id=5310, option=[null, null, null, null, drop] +item=Wildblood seed, id=5311, option=[null, null, null, null, drop] +item=Acorn, id=5312, option=[null, null, null, null, drop] +item=Willow seed, id=5313, option=[null, null, null, null, drop] +item=Maple seed, id=5314, option=[null, null, null, null, drop] +item=Yew seed, id=5315, option=[null, null, null, null, drop] +item=Magic seed, id=5316, option=[null, null, null, null, drop] +item=Spirit seed, id=5317, option=[null, null, null, null, drop] +item=Potato seed, id=5318, option=[null, null, null, null, drop] +item=Onion seed, id=5319, option=[null, null, null, null, drop] +item=Sweetcorn seed, id=5320, option=[null, null, null, null, drop] +item=Watermelon seed, id=5321, option=[null, null, null, null, drop] +item=Tomato seed, id=5322, option=[null, null, null, null, drop] +item=Strawberry seed, id=5323, option=[null, null, null, null, drop] +item=Cabbage seed, id=5324, option=[null, null, null, null, drop] +item=Gardening trowel, id=5325, option=[null, null, null, null, drop] +item=Gardening trowel, id=5326, option=[null, null, null, null, drop] +item=Spade handle, id=5327, option=[null, null, null, null, drop] +item=Spade head, id=5328, option=[null, null, null, null, drop] +item=Secateurs, id=5329, option=[null, null, null, null, drop] +item=Secateurs, id=5330, option=[null, null, null, null, drop] +item=Watering can, id=5331, option=[null, null, null, null, drop] +item=Watering can, id=5332, option=[null, null, null, null, drop] +item=Watering can(1), id=5333, option=[null, null, null, null, drop] +item=Watering can(2), id=5334, option=[null, null, null, null, drop] +item=Watering can(3), id=5335, option=[null, null, null, null, drop] +item=Watering can(4), id=5336, option=[null, null, null, null, drop] +item=Watering can(5), id=5337, option=[null, null, null, null, drop] +item=Watering can(6), id=5338, option=[null, null, null, null, drop] +item=Watering can(7), id=5339, option=[null, null, null, null, drop] +item=Watering can(8), id=5340, option=[null, null, null, null, drop] +item=Rake, id=5341, option=[null, null, null, null, drop] +item=Rake, id=5342, option=[null, null, null, null, drop] +item=Seed dibber, id=5343, option=[null, null, null, null, drop] +item=Seed dibber, id=5344, option=[null, null, null, null, drop] +item=Gardening boots, id=5345, option=[null, Wear, null, null, drop] +item=Gardening boots, id=5346, option=[null, null, null, null, drop] +item=Rake handle, id=5347, option=[null, null, null, null, drop] +item=Rake head, id=5348, option=[null, null, null, null, drop] +item=Whoopsie, id=5349, option=[Wear, null, null, null, drop] +item=Plant pot, id=5350, option=[null, null, null, null, drop] +item=Plant pot, id=5351, option=[null, null, null, null, drop] +item=Unfired plant pot, id=5352, option=[null, null, null, null, drop] +item=Unfired plant pot, id=5353, option=[null, null, null, null, drop] +item=Plant pot, id=5354, option=[null, null, null, null, drop] +item=Plant pot, id=5355, option=[null, null, null, null, drop] +item=Plant pot, id=5356, option=[null, null, null, null, drop] +item=Plant pot, id=5357, option=[null, null, null, null, drop] +item=Oak seedling, id=5358, option=[null, null, null, null, drop] +item=Willow seedling, id=5359, option=[null, null, null, null, drop] +item=Maple seedling, id=5360, option=[null, null, null, null, drop] +item=Yew seedling, id=5361, option=[null, null, null, null, drop] +item=Magic seedling, id=5362, option=[null, null, null, null, drop] +item=Spirit seedling, id=5363, option=[null, null, null, null, drop] +item=Oak seedling, id=5364, option=[null, null, null, null, drop] +item=Willow seedling, id=5365, option=[null, null, null, null, drop] +item=Maple seedling, id=5366, option=[null, null, null, null, drop] +item=Yew seedling, id=5367, option=[null, null, null, null, drop] +item=Magic seedling, id=5368, option=[null, null, null, null, drop] +item=Spirit seedling, id=5369, option=[null, null, null, null, drop] +item=Oak sapling, id=5370, option=[null, null, null, null, drop] +item=Willow sapling, id=5371, option=[null, null, null, null, drop] +item=Maple sapling, id=5372, option=[null, null, null, null, drop] +item=Yew sapling, id=5373, option=[null, null, null, null, drop] +item=Magic sapling, id=5374, option=[null, null, null, null, drop] +item=Spirit sapling, id=5375, option=[null, null, null, null, drop] +item=Basket, id=5376, option=[Fill, null, null, null, drop] +item=Basket, id=5377, option=[null, null, null, null, drop] +item=Apples(1), id=5378, option=[Fill, Remove-one, null, null, drop] +item=Apples(1), id=5379, option=[null, null, null, null, drop] +item=Apples(2), id=5380, option=[Fill, Remove-one, Empty, null, drop] +item=Apples(2), id=5381, option=[null, null, null, null, drop] +item=Apples(3), id=5382, option=[Fill, Remove-one, Empty, null, drop] +item=Apples(3), id=5383, option=[null, null, null, null, drop] +item=Apples(4), id=5384, option=[Fill, Remove-one, Empty, null, drop] +item=Apples(4), id=5385, option=[null, null, null, null, drop] +item=Apples(5), id=5386, option=[Fill, Remove-one, Empty, null, drop] +item=Apples(5), id=5387, option=[null, null, null, null, drop] +item=Oranges(1), id=5388, option=[Fill, Remove-one, null, null, drop] +item=Oranges(1), id=5389, option=[null, null, null, null, drop] +item=Oranges(2), id=5390, option=[Fill, Remove-one, Empty, null, drop] +item=Oranges(2), id=5391, option=[null, null, null, null, drop] +item=Oranges(3), id=5392, option=[Fill, Remove-one, Empty, null, drop] +item=Oranges(3), id=5393, option=[null, null, null, null, drop] +item=Oranges(4), id=5394, option=[Fill, Remove-one, Empty, null, drop] +item=Oranges(4), id=5395, option=[null, null, null, null, drop] +item=Oranges(5), id=5396, option=[Fill, Remove-one, Empty, null, drop] +item=Oranges(5), id=5397, option=[null, null, null, null, drop] +item=Strawberries(1), id=5398, option=[Fill, Remove-one, null, null, drop] +item=Strawberries(1), id=5399, option=[null, null, null, null, drop] +item=Strawberries(2), id=5400, option=[Fill, Remove-one, Empty, null, drop] +item=Strawberries(2), id=5401, option=[null, null, null, null, drop] +item=Strawberries(3), id=5402, option=[Fill, Remove-one, Empty, null, drop] +item=Strawberries(3), id=5403, option=[null, null, null, null, drop] +item=Strawberries(4), id=5404, option=[Fill, Remove-one, Empty, null, drop] +item=Strawberries(4), id=5405, option=[null, null, null, null, drop] +item=Strawberries(5), id=5406, option=[Fill, Remove-one, Empty, null, drop] +item=Strawberries(5), id=5407, option=[null, null, null, null, drop] +item=Bananas(1), id=5408, option=[Fill, Remove-one, null, null, drop] +item=Bananas(1), id=5409, option=[null, null, null, null, drop] +item=Bananas(2), id=5410, option=[Fill, Remove-one, Empty, null, drop] +item=Bananas(2), id=5411, option=[null, null, null, null, drop] +item=Bananas(3), id=5412, option=[Fill, Remove-one, Empty, null, drop] +item=Bananas(3), id=5413, option=[null, null, null, null, drop] +item=Bananas(4), id=5414, option=[Fill, Remove-one, Empty, null, drop] +item=Bananas(4), id=5415, option=[null, null, null, null, drop] +item=Bananas(5), id=5416, option=[Fill, Remove-one, Empty, null, drop] +item=Bananas(5), id=5417, option=[null, null, null, null, drop] +item=Empty sack, id=5418, option=[Fill, null, null, null, drop] +item=Empty sack, id=5419, option=[null, null, null, null, drop] +item=Potatoes(1), id=5420, option=[Fill, Remove-one, null, null, drop] +item=Potatoes(1), id=5421, option=[null, null, null, null, drop] +item=Potatoes(2), id=5422, option=[Fill, Remove-one, Empty, null, drop] +item=Potatoes(2), id=5423, option=[null, null, null, null, drop] +item=Potatoes(3), id=5424, option=[Fill, Remove-one, Empty, null, drop] +item=Potatoes(3), id=5425, option=[null, null, null, null, drop] +item=Potatoes(4), id=5426, option=[Fill, Remove-one, Empty, null, drop] +item=Potatoes(4), id=5427, option=[null, null, null, null, drop] +item=Potatoes(5), id=5428, option=[Fill, Remove-one, Empty, null, drop] +item=Potatoes(5), id=5429, option=[null, null, null, null, drop] +item=Potatoes(6), id=5430, option=[Fill, Remove-one, Empty, null, drop] +item=Potatoes(6), id=5431, option=[null, null, null, null, drop] +item=Potatoes(7), id=5432, option=[Fill, Remove-one, Empty, null, drop] +item=Potatoes(7), id=5433, option=[null, null, null, null, drop] +item=Potatoes(8), id=5434, option=[Fill, Remove-one, Empty, null, drop] +item=Potatoes(8), id=5435, option=[null, null, null, null, drop] +item=Potatoes(9), id=5436, option=[Fill, Remove-one, Empty, null, drop] +item=Potatoes(9), id=5437, option=[null, null, null, null, drop] +item=Potatoes(10), id=5438, option=[Fill, Remove-one, Empty, null, drop] +item=Potatoes(10), id=5439, option=[null, null, null, null, drop] +item=Onions(1), id=5440, option=[Fill, Remove-one, null, null, drop] +item=Onions(1), id=5441, option=[null, null, null, null, drop] +item=Onions(2), id=5442, option=[Fill, Remove-one, Empty, null, drop] +item=Onions(2), id=5443, option=[null, null, null, null, drop] +item=Onions(3), id=5444, option=[Fill, Remove-one, Empty, null, drop] +item=Onions(3), id=5445, option=[null, null, null, null, drop] +item=Onions(4), id=5446, option=[Fill, Remove-one, Empty, null, drop] +item=Onions(4), id=5447, option=[null, null, null, null, drop] +item=Onions(5), id=5448, option=[Fill, Remove-one, Empty, null, drop] +item=Onions(5), id=5449, option=[null, null, null, null, drop] +item=Onions(6), id=5450, option=[Fill, Remove-one, Empty, null, drop] +item=Onions(6), id=5451, option=[null, null, null, null, drop] +item=Onions(7), id=5452, option=[Fill, Remove-one, Empty, null, drop] +item=Onions(7), id=5453, option=[null, null, null, null, drop] +item=Onions(8), id=5454, option=[Fill, Remove-one, Empty, null, drop] +item=Onions(8), id=5455, option=[null, null, null, null, drop] +item=Onions(9), id=5456, option=[Fill, Remove-one, Empty, null, drop] +item=Onions(9), id=5457, option=[null, null, null, null, drop] +item=Onions(10), id=5458, option=[Fill, Remove-one, Empty, null, drop] +item=Onions(10), id=5459, option=[null, null, null, null, drop] +item=Cabbages(1), id=5460, option=[Fill, Remove-one, null, null, drop] +item=Cabbages(1), id=5461, option=[null, null, null, null, drop] +item=Cabbages(2), id=5462, option=[Fill, Remove-one, Empty, null, drop] +item=Cabbages(2), id=5463, option=[null, null, null, null, drop] +item=Cabbages(3), id=5464, option=[Fill, Remove-one, Empty, null, drop] +item=Cabbages(3), id=5465, option=[null, null, null, null, drop] +item=Cabbages(4), id=5466, option=[Fill, Remove-one, Empty, null, drop] +item=Cabbages(4), id=5467, option=[null, null, null, null, drop] +item=Cabbages(5), id=5468, option=[Fill, Remove-one, Empty, null, drop] +item=Cabbages(5), id=5469, option=[null, null, null, null, drop] +item=Cabbages(6), id=5470, option=[Fill, Remove-one, Empty, null, drop] +item=Cabbages(6), id=5471, option=[null, null, null, null, drop] +item=Cabbages(7), id=5472, option=[Fill, Remove-one, Empty, null, drop] +item=Cabbages(7), id=5473, option=[null, null, null, null, drop] +item=Cabbages(8), id=5474, option=[Fill, Remove-one, Empty, null, drop] +item=Cabbages(8), id=5475, option=[null, null, null, null, drop] +item=Cabbages(9), id=5476, option=[Fill, Remove-one, Empty, null, drop] +item=Cabbages(9), id=5477, option=[null, null, null, null, drop] +item=Cabbages(10), id=5478, option=[Fill, Remove-one, Empty, null, drop] +item=Cabbages(10), id=5479, option=[null, null, null, null, drop] +item=Apple seedling, id=5480, option=[null, null, null, null, drop] +item=Banana seedling, id=5481, option=[null, null, null, null, drop] +item=Orange seedling, id=5482, option=[null, null, null, null, drop] +item=Curry seedling, id=5483, option=[null, null, null, null, drop] +item=Pineapple seedling, id=5484, option=[null, null, null, null, drop] +item=Papaya seedling, id=5485, option=[null, null, null, null, drop] +item=Palm seedling, id=5486, option=[null, null, null, null, drop] +item=Calquat seedling, id=5487, option=[null, null, null, null, drop] +item=Apple seedling, id=5488, option=[null, null, null, null, drop] +item=Banana seedling, id=5489, option=[null, null, null, null, drop] +item=Orange seedling, id=5490, option=[null, null, null, null, drop] +item=Curry seedling, id=5491, option=[null, null, null, null, drop] +item=Pineapple seedling, id=5492, option=[null, null, null, null, drop] +item=Papaya seedling, id=5493, option=[null, null, null, null, drop] +item=Palm seedling, id=5494, option=[null, null, null, null, drop] +item=Calquat seedling, id=5495, option=[null, null, null, null, drop] +item=Apple sapling, id=5496, option=[null, null, null, null, drop] +item=Banana sapling, id=5497, option=[null, null, null, null, drop] +item=Orange sapling, id=5498, option=[null, null, null, null, drop] +item=Curry sapling, id=5499, option=[null, null, null, null, drop] +item=Pineapple sapling, id=5500, option=[null, null, null, null, drop] +item=Papaya sapling, id=5501, option=[null, null, null, null, drop] +item=Palm sapling, id=5502, option=[null, null, null, null, drop] +item=Calquat sapling, id=5503, option=[null, null, null, null, drop] +item=Strawberry, id=5504, option=[Eat, null, null, null, drop] +item=Strawberry, id=5505, option=[null, null, null, null, drop] +item=Old man's message, id=5506, option=[Read, null, null, null, drop] +item=Strange book, id=5507, option=[Read, null, null, null, drop] +item=Book of folklore, id=5508, option=[Read, null, null, null, drop] +item=Small pouch, id=5509, option=[Fill, Empty, Check, null, drop] +item=Medium pouch, id=5510, option=[Fill, Empty, Check, null, drop] +item=Medium pouch, id=5511, option=[Fill, Empty, Check, null, drop] +item=Large pouch, id=5512, option=[Fill, Empty, Check, null, drop] +item=Large pouch, id=5513, option=[Fill, Empty, Check, null, drop] +item=Giant pouch, id=5514, option=[Fill, Empty, Check, null, drop] +item=Giant pouch, id=5515, option=[Fill, Empty, Check, null, drop] +item=Elemental talisman, id=5516, option=[null, null, null, Locate, drop] +item=Elemental talisman, id=5517, option=[null, null, null, null, drop] +item=Scrying orb, id=5518, option=[null, null, null, null, drop] +item=Scrying orb, id=5519, option=[null, null, null, null, drop] +item=Abyssal book, id=5520, option=[Read, null, null, null, drop] +item=Binding necklace, id=5521, option=[null, Wear, null, null, drop] +item=Binding necklace, id=5522, option=[null, null, null, null, drop] +item=Tiara mould, id=5523, option=[null, null, null, null, drop] +item=Tiara mould, id=5524, option=[null, null, null, null, drop] +item=Tiara, id=5525, option=[null, Wear, null, null, drop] +item=Tiara, id=5526, option=[null, null, null, null, drop] +item=Air tiara, id=5527, option=[null, Wear, null, null, drop] +item=Air tiara, id=5528, option=[null, null, null, null, drop] +item=Mind tiara, id=5529, option=[null, Wear, null, null, drop] +item=Mind tiara, id=5530, option=[null, null, null, null, drop] +item=Water tiara, id=5531, option=[null, Wear, null, null, drop] +item=Water tiara, id=5532, option=[null, null, null, null, drop] +item=Body tiara, id=5533, option=[null, Wear, null, null, drop] +item=Body tiara, id=5534, option=[null, null, null, null, drop] +item=Earth tiara, id=5535, option=[null, Wear, null, null, drop] +item=Earth tiara, id=5536, option=[null, null, null, null, drop] +item=Fire tiara, id=5537, option=[null, Wear, null, null, drop] +item=Fire tiara, id=5538, option=[null, null, null, null, drop] +item=Cosmic tiara, id=5539, option=[null, Wear, null, null, drop] +item=Cosmic tiara, id=5540, option=[null, null, null, null, drop] +item=Nature tiara, id=5541, option=[null, Wear, null, null, drop] +item=Nature tiara, id=5542, option=[null, null, null, null, drop] +item=Chaos tiara, id=5543, option=[null, Wear, null, null, drop] +item=Chaos tiara, id=5544, option=[null, null, null, null, drop] +item=Law tiara, id=5545, option=[null, Wear, null, null, drop] +item=Law tiara, id=5546, option=[null, null, null, null, drop] +item=Death tiara, id=5547, option=[null, Wear, null, null, drop] +item=Death tiara, id=5548, option=[null, null, null, null, drop] +item=Blood tiara, id=5549, option=[null, Wear, null, null, drop] +item=Blood tiara, id=5550, option=[null, null, null, null, drop] +item=Soul tiara, id=5551, option=[null, Wear, null, null, drop] +item=Soul tiara, id=5552, option=[null, null, null, null, drop] +item=Rogue top, id=5553, option=[null, Wear, null, null, drop] +item=Rogue mask, id=5554, option=[null, Wear, null, null, drop] +item=Rogue trousers, id=5555, option=[null, Wear, null, null, drop] +item=Rogue gloves, id=5556, option=[null, Wear, null, null, drop] +item=Rogue boots, id=5557, option=[null, Wear, null, null, drop] +item=Rogue kit, id=5558, option=[Build, null, null, null, drop] +item=Flash powder, id=5559, option=[null, null, null, null, drop] +item=Stethoscope, id=5560, option=[null, null, null, null, drop] +item=Mystic jewel, id=5561, option=[Activate, null, null, null, drop] +item=Gear, id=5562, option=[null, null, null, null, drop] +item=Gear, id=5563, option=[null, null, null, null, drop] +item=Gear, id=5564, option=[null, null, null, null, drop] +item=Gear, id=5565, option=[null, null, null, null, drop] +item=Gear, id=5566, option=[null, null, null, null, drop] +item=Gear, id=5567, option=[null, null, null, null, drop] +item=Tile, id=5568, option=[null, null, null, null, drop] +item=Tiles, id=5569, option=[null, null, null, null, drop] +item=Tiles, id=5570, option=[null, null, null, null, drop] +item=Tiles, id=5571, option=[null, null, null, null, drop] +item=Dial, id=5572, option=[null, null, null, null, drop] +item=Whoopsie, id=5573, option=[Wear, null, null, null, drop] +item=Initiate sallet, id=5574, option=[null, Wear, null, null, drop] +item=Initiate hauberk, id=5575, option=[null, Wear, null, null, drop] +item=Initiate cuisse, id=5576, option=[null, Wear, null, null, drop] +item=Cupric sulfate, id=5577, option=[null, null, null, null, drop] +item=Acetic acid, id=5578, option=[null, null, null, null, drop] +item=Gypsum, id=5579, option=[null, null, null, null, drop] +item=Sodium chloride, id=5580, option=[null, null, null, null, drop] +item=Nitrous oxide, id=5581, option=[Open, null, null, null, drop] +item=Vial of liquid, id=5582, option=[null, null, null, null, drop] +item=Tin ore powder, id=5583, option=[null, null, null, null, drop] +item=Cupric ore powder, id=5584, option=[null, null, null, null, drop] +item=Bronze key, id=5585, option=[null, null, null, null, drop] +item=Metal spade, id=5586, option=[null, null, null, null, drop] +item=Metal spade, id=5587, option=[null, null, null, null, drop] +item=Alchemical notes, id=5588, option=[Read, null, null, null, drop] +item=??? mixture, id=5589, option=[null, null, null, null, drop] +item=??? mixture, id=5590, option=[null, null, null, null, drop] +item=??? mixture, id=5591, option=[null, null, null, null, drop] +item=Tin, id=5592, option=[null, null, null, null, drop] +item=Tin, id=5593, option=[null, null, null, null, drop] +item=Tin, id=5594, option=[null, null, null, null, drop] +item=Tin, id=5595, option=[null, null, null, null, drop] +item=Tin, id=5596, option=[null, null, null, null, drop] +item=Tin, id=5597, option=[null, null, null, null, drop] +item=Tin, id=5598, option=[null, null, null, null, drop] +item=Tin, id=5599, option=[null, null, null, null, drop] +item=Tin, id=5600, option=[null, null, null, null, drop] +item=Chisel, id=5601, option=[null, null, null, null, drop] +item=Bronze wire, id=5602, option=[null, null, null, null, drop] +item=Shears, id=5603, option=[null, null, null, null, drop] +item=Magnet, id=5604, option=[null, null, null, null, drop] +item=Knife, id=5605, option=[null, null, null, null, drop] +item=Makeover voucher, id=5606, option=[null, null, null, null, drop] +item=Grain, id=5607, option=[null, Wear, null, null, drop] +item=Fox, id=5608, option=[null, Wear, null, null, drop] +item=Chicken, id=5609, option=[null, Wear, null, null, drop] +item=Hourglass, id=5610, option=[null, null, null, null, drop] +item=Initiate sallet, id=5611, option=[null, null, null, null, drop] +item=Initiate hauberk, id=5612, option=[null, null, null, null, drop] +item=Initiate cuisse, id=5613, option=[null, null, null, null, drop] +item=Magic carpet, id=5614, option=[null, null, null, null, drop] +item=Bonemeal, id=5615, option=[null, Empty, null, null, drop] +item=Bronze arrow(p+), id=5616, option=[null, Wield, null, null, drop] +item=Iron arrow(p+), id=5617, option=[null, Wield, null, null, drop] +item=Steel arrow(p+), id=5618, option=[null, Wield, null, null, drop] +item=Mithril arrow(p+), id=5619, option=[null, Wield, null, null, drop] +item=Adamant arrow(p+), id=5620, option=[null, Wield, null, null, drop] +item=Rune arrow(p+), id=5621, option=[null, Wield, null, null, drop] +item=Bronze arrow(p++), id=5622, option=[null, Wield, null, null, drop] +item=Iron arrow(p++), id=5623, option=[null, Wield, null, null, drop] +item=Steel arrow(p++), id=5624, option=[null, Wield, null, null, drop] +item=Mithril arrow(p++), id=5625, option=[null, Wield, null, null, drop] +item=Adam arrow(p++), id=5626, option=[null, Wield, null, null, drop] +item=Rune arrow(p++), id=5627, option=[null, Wield, null, null, drop] +item=Bronze dart(p+), id=5628, option=[null, Wield, null, null, drop] +item=Iron dart(p+), id=5629, option=[null, Wield, null, null, drop] +item=Steel dart(p+), id=5630, option=[null, Wield, null, null, drop] +item=Black dart(p+), id=5631, option=[null, Wield, null, null, drop] +item=Mithril dart(p+), id=5632, option=[null, Wield, null, null, drop] +item=Adamant dart(p+), id=5633, option=[null, Wield, null, null, drop] +item=Rune dart(p+), id=5634, option=[null, Wield, null, null, drop] +item=Bronze dart(p++), id=5635, option=[null, Wield, null, null, drop] +item=Iron dart(p++), id=5636, option=[null, Wield, null, null, drop] +item=Steel dart(p++), id=5637, option=[null, Wield, null, null, drop] +item=Black dart(p++), id=5638, option=[null, Wield, null, null, drop] +item=Mithril dart(p++), id=5639, option=[null, Wield, null, null, drop] +item=Adamant dart(p++), id=5640, option=[null, Wield, null, null, drop] +item=Rune dart(p++), id=5641, option=[null, Wield, null, null, drop] +item=Bronze javelin(p+), id=5642, option=[null, Wield, null, null, drop] +item=Iron javelin(p+), id=5643, option=[null, Wield, null, null, drop] +item=Steel javelin(p+), id=5644, option=[null, Wield, null, null, drop] +item=Mithril javelin(p+), id=5645, option=[null, Wield, null, null, drop] +item=Addy javelin(p+), id=5646, option=[null, Wield, null, null, drop] +item=Rune javelin(p+), id=5647, option=[null, Wield, null, null, drop] +item=Bronze jav'n(p++), id=5648, option=[null, Wield, null, null, drop] +item=Iron javelin(p++), id=5649, option=[null, Wield, null, null, drop] +item=Steel javelin(p++), id=5650, option=[null, Wield, null, null, drop] +item=Mithril javelin(p++), id=5651, option=[null, Wield, null, null, drop] +item=Addy javelin(p++), id=5652, option=[null, Wield, null, null, drop] +item=Rune javelin(p++), id=5653, option=[null, Wield, null, null, drop] +item=Bronze knife(p+), id=5654, option=[null, Wield, null, null, drop] +item=Iron knife(p+), id=5655, option=[null, Wield, null, null, drop] +item=Steel knife(p+), id=5656, option=[null, Wield, null, null, drop] +item=Mithril knife(p+), id=5657, option=[null, Wield, null, null, drop] +item=Black knife(p+), id=5658, option=[null, Wield, null, null, drop] +item=Adamant knife(p+), id=5659, option=[null, Wield, null, null, drop] +item=Rune knife(p+), id=5660, option=[null, Wield, null, null, drop] +item=Bronze knife(p++), id=5661, option=[null, Wield, null, null, drop] +item=Iron knife(p++), id=5662, option=[null, Wield, null, null, drop] +item=Steel knife(p++), id=5663, option=[null, Wield, null, null, drop] +item=Mithril knife(p++), id=5664, option=[null, Wield, null, null, drop] +item=Black knife(p++), id=5665, option=[null, Wield, null, null, drop] +item=Addy knife(p++), id=5666, option=[null, Wield, null, null, drop] +item=Rune knife(p++), id=5667, option=[null, Wield, null, null, drop] +item=Iron dagger(p+), id=5668, option=[null, Wield, null, null, drop] +item=Iron dagger(p+), id=5669, option=[null, null, null, null, drop] +item=Bronze dagger(p+), id=5670, option=[null, Wield, null, null, drop] +item=Bronze dagger(p+), id=5671, option=[null, null, null, null, drop] +item=Steel dagger(p+), id=5672, option=[null, Wield, null, null, drop] +item=Steel dagger(p+), id=5673, option=[null, null, null, null, drop] +item=Mithril dagger(p+), id=5674, option=[null, Wield, null, null, drop] +item=Mithril dagger(p+), id=5675, option=[null, null, null, null, drop] +item=Adam dagger(p+), id=5676, option=[null, Wield, null, null, drop] +item=Adam dagger(p+), id=5677, option=[null, null, null, null, drop] +item=Rune dagger(p+), id=5678, option=[null, Wield, null, null, drop] +item=Rune dagger(p+), id=5679, option=[null, null, null, null, drop] +item=Dragon dagger(p+), id=5680, option=[null, Wield, null, null, drop] +item=Dragon dagger(p+), id=5681, option=[null, null, null, null, drop] +item=Black dagger(p+), id=5682, option=[null, Wield, null, null, drop] +item=Black dagger(p+), id=5683, option=[null, null, null, null, drop] +item=Poison dagger(p+), id=5684, option=[null, Wield, null, null, drop] +item=Poison dagger(p+), id=5685, option=[null, null, null, null, drop] +item=Iron dagger(p++), id=5686, option=[null, Wield, null, null, drop] +item=Iron dagger(p++), id=5687, option=[null, null, null, null, drop] +item=Br'ze dagger(p++), id=5688, option=[null, Wield, null, null, drop] +item=Br'ze dagger(p++), id=5689, option=[null, null, null, null, drop] +item=Steel dagger(p++), id=5690, option=[null, Wield, null, null, drop] +item=Steel dagger(p++), id=5691, option=[null, null, null, null, drop] +item=Mithril dagger(p++), id=5692, option=[null, Wield, null, null, drop] +item=Mithril dagger(p++), id=5693, option=[null, null, null, null, drop] +item=Adam dagger(p++), id=5694, option=[null, Wield, null, null, drop] +item=Adam dagger(p++), id=5695, option=[null, null, null, null, drop] +item=Rune dagger(p++), id=5696, option=[null, Wield, null, null, drop] +item=Rune dagger(p++), id=5697, option=[null, null, null, null, drop] +item=Drag dagger(p++), id=5698, option=[null, Wield, null, null, drop] +item=Drag dagger(p++), id=5699, option=[null, null, null, null, drop] +item=Black dagger(p++), id=5700, option=[null, Wield, null, null, drop] +item=Black dagger(p++), id=5701, option=[null, null, null, null, drop] +item=Poison dagger(p++), id=5702, option=[null, Wield, null, null, drop] +item=Poison dagger(p++), id=5703, option=[null, null, null, null, drop] +item=Bronze spear(p+), id=5704, option=[null, Wield, null, null, drop] +item=Bronze spear(p+), id=5705, option=[null, null, null, null, drop] +item=Iron spear(p+), id=5706, option=[null, Wield, null, null, drop] +item=Iron spear(p+), id=5707, option=[null, null, null, null, drop] +item=Steel spear(p+), id=5708, option=[null, Wield, null, null, drop] +item=Steel spear(p+), id=5709, option=[null, null, null, null, drop] +item=Mithril spear(p+), id=5710, option=[null, Wield, null, null, drop] +item=Mithril spear(p+), id=5711, option=[null, null, null, null, drop] +item=Adamant spear(p+), id=5712, option=[null, Wield, null, null, drop] +item=Adamant spear(p+), id=5713, option=[null, null, null, null, drop] +item=Rune spear(p+), id=5714, option=[null, Wield, null, null, drop] +item=Rune spear(p+), id=5715, option=[null, null, null, null, drop] +item=Dragon spear(p+), id=5716, option=[null, Wield, null, null, drop] +item=Dragon spear(p+), id=5717, option=[null, null, null, null, drop] +item=Bronze spear(p++), id=5718, option=[null, Wield, null, null, drop] +item=Bronze spear(p++), id=5719, option=[null, null, null, null, drop] +item=Iron spear(p++), id=5720, option=[null, Wield, null, null, drop] +item=Iron spear(p++), id=5721, option=[null, null, null, null, drop] +item=Steel spear(p++), id=5722, option=[null, Wield, null, null, drop] +item=Steel spear(p++), id=5723, option=[null, null, null, null, drop] +item=Mithril spear(p++), id=5724, option=[null, Wield, null, null, drop] +item=Mithril spear(p++), id=5725, option=[null, null, null, null, drop] +item=Adam spear(p++), id=5726, option=[null, Wield, null, null, drop] +item=Adam spear(p++), id=5727, option=[null, null, null, null, drop] +item=Rune spear(p++), id=5728, option=[null, Wield, null, null, drop] +item=Rune spear(p++), id=5729, option=[null, null, null, null, drop] +item=Dragon spear(p++), id=5730, option=[null, Wield, null, null, drop] +item=Dragon spear(p++), id=5731, option=[null, null, null, null, drop] +item=Stool, id=5732, option=[null, null, null, null, drop] +item=Rotten potato, id=5733, option=[Eat, Slice, Peel, Mash, drop] +item=Black spear(p+), id=5734, option=[null, Wield, null, null, drop] +item=Black spear(p+), id=5735, option=[null, null, null, null, drop] +item=Black spear(p++), id=5736, option=[null, Wield, null, null, drop] +item=Black spear(p++), id=5737, option=[null, null, null, null, drop] +item=Woad leaf, id=5738, option=[null, null, null, null, drop] +item=Asgarnian ale(m), id=5739, option=[Drink, null, null, null, drop] +item=Asgarnian ale(m), id=5740, option=[null, null, null, null, drop] +item=Mature wmb, id=5741, option=[Drink, null, null, null, drop] +item=Mature wmb, id=5742, option=[null, null, null, null, drop] +item=Greenman's ale(m), id=5743, option=[Drink, null, null, null, drop] +item=Greenman's ale(m), id=5744, option=[null, null, null, null, drop] +item=Dragon bitter(m), id=5745, option=[Drink, null, null, null, drop] +item=Dragon bitter(m), id=5746, option=[null, null, null, null, drop] +item=Dwarven stout(m), id=5747, option=[Drink, null, null, null, drop] +item=Dwarven stout(m), id=5748, option=[null, null, null, null, drop] +item=Moonlight mead(m), id=5749, option=[Drink, null, null, null, drop] +item=Moonlight mead(m), id=5750, option=[null, null, null, null, drop] +item=Axeman's folly, id=5751, option=[Drink, null, null, null, drop] +item=Axeman's folly, id=5752, option=[null, null, null, null, drop] +item=Axeman's folly(m), id=5753, option=[Drink, null, null, null, drop] +item=Axeman's folly(m), id=5754, option=[null, null, null, null, drop] +item=Chef's delight, id=5755, option=[Drink, null, null, null, drop] +item=Chef's delight, id=5756, option=[null, null, null, null, drop] +item=Chef's delight(m), id=5757, option=[Drink, null, null, null, drop] +item=Chef's delight(m), id=5758, option=[null, null, null, null, drop] +item=Slayer's respite, id=5759, option=[Drink, null, null, null, drop] +item=Slayer's respite, id=5760, option=[null, null, null, null, drop] +item=Slayer's respite(m), id=5761, option=[Drink, null, null, null, drop] +item=Slayer's respite(m), id=5762, option=[null, null, null, null, drop] +item=Cider, id=5763, option=[Drink, null, null, null, drop] +item=Cider, id=5764, option=[null, null, null, null, drop] +item=Mature cider, id=5765, option=[Drink, null, null, null, drop] +item=Mature cider, id=5766, option=[null, null, null, null, drop] +item=Ale yeast, id=5767, option=[null, null, null, null, drop] +item=Ale yeast, id=5768, option=[null, null, null, null, drop] +item=Calquat keg, id=5769, option=[null, null, null, null, drop] +item=Calquat keg, id=5770, option=[null, null, null, null, drop] +item=Dwarven stout(1), id=5771, option=[Drink, null, null, null, drop] +item=Dwarven stout(1), id=5772, option=[null, null, null, null, drop] +item=Dwarven stout(2), id=5773, option=[Drink, null, null, null, drop] +item=Dwarven stout(2), id=5774, option=[null, null, null, null, drop] +item=Dwarven stout(3), id=5775, option=[Drink, null, null, null, drop] +item=Dwarven stout(3), id=5776, option=[null, null, null, null, drop] +item=Dwarven stout(4), id=5777, option=[Drink, null, null, null, drop] +item=Dwarven stout(4), id=5778, option=[null, null, null, null, drop] +item=Asgarnian ale(1), id=5779, option=[Drink, null, null, null, drop] +item=Asgarnian ale(1), id=5780, option=[null, null, null, null, drop] +item=Asgarnian ale(2), id=5781, option=[Drink, null, null, null, drop] +item=Asgarnian ale(2), id=5782, option=[null, null, null, null, drop] +item=Asgarnian ale(3), id=5783, option=[Drink, null, null, null, drop] +item=Asgarnian ale(3), id=5784, option=[null, null, null, null, drop] +item=Asgarnian ale(4), id=5785, option=[Drink, null, null, null, drop] +item=Asgarnian ale(4), id=5786, option=[null, null, null, null, drop] +item=Greenmans ale(1), id=5787, option=[Drink, null, null, null, drop] +item=Greenmans ale(1), id=5788, option=[null, null, null, null, drop] +item=Greenmans ale(2), id=5789, option=[Drink, null, null, null, drop] +item=Greenmans ale(2), id=5790, option=[null, null, null, null, drop] +item=Greenmans ale(3), id=5791, option=[Drink, null, null, null, drop] +item=Greenmans ale(3), id=5792, option=[null, null, null, null, drop] +item=Greenmans ale(4), id=5793, option=[Drink, null, null, null, drop] +item=Greenmans ale(4), id=5794, option=[null, null, null, null, drop] +item=Mind bomb(1), id=5795, option=[Drink, null, null, null, drop] +item=Mind bomb(1), id=5796, option=[null, null, null, null, drop] +item=Mind bomb(2), id=5797, option=[Drink, null, null, null, drop] +item=Mind bomb(2), id=5798, option=[null, null, null, null, drop] +item=Mind bomb(3), id=5799, option=[Drink, null, null, null, drop] +item=Mind bomb(3), id=5800, option=[null, null, null, null, drop] +item=Mind bomb(4), id=5801, option=[Drink, null, null, null, drop] +item=Mind bomb(4), id=5802, option=[null, null, null, null, drop] +item=Dragon bitter(1), id=5803, option=[Drink, null, null, null, drop] +item=Dragon bitter(1), id=5804, option=[null, null, null, null, drop] +item=Dragon bitter(2), id=5805, option=[Drink, null, null, null, drop] +item=Dragon bitter(2), id=5806, option=[null, null, null, null, drop] +item=Dragon bitter(3), id=5807, option=[Drink, null, null, null, drop] +item=Dragon bitter(3), id=5808, option=[null, null, null, null, drop] +item=Dragon bitter(4), id=5809, option=[Drink, null, null, null, drop] +item=Dragon bitter(4), id=5810, option=[null, null, null, null, drop] +item=Moonlight mead(1), id=5811, option=[Drink, null, null, null, drop] +item=Moonlight mead(1), id=5812, option=[null, null, null, null, drop] +item=Moonlight mead(2), id=5813, option=[Drink, null, null, null, drop] +item=Moonlight mead(2), id=5814, option=[null, null, null, null, drop] +item=Moonlight mead(3), id=5815, option=[Drink, null, null, null, drop] +item=Moonlight mead(3), id=5816, option=[null, null, null, null, drop] +item=Moonlight mead(4), id=5817, option=[Drink, null, null, null, drop] +item=Moonlight mead(4), id=5818, option=[null, null, null, null, drop] +item=Axeman's folly(1), id=5819, option=[Drink, null, null, null, drop] +item=Axeman's folly(1), id=5820, option=[null, null, null, null, drop] +item=Axeman's folly(2), id=5821, option=[Drink, null, null, null, drop] +item=Axeman's folly(2), id=5822, option=[null, null, null, null, drop] +item=Axeman's folly(3), id=5823, option=[Drink, null, null, null, drop] +item=Axeman's folly(3), id=5824, option=[null, null, null, null, drop] +item=Axeman's folly(4), id=5825, option=[Drink, null, null, null, drop] +item=Axeman's folly(4), id=5826, option=[null, null, null, null, drop] +item=Chef's delight(1), id=5827, option=[Drink, null, null, null, drop] +item=Chef's delight(1), id=5828, option=[null, null, null, null, drop] +item=Chef's delight(2), id=5829, option=[Drink, null, null, null, drop] +item=Chef's delight(2), id=5830, option=[null, null, null, null, drop] +item=Chef's delight(3), id=5831, option=[Drink, null, null, null, drop] +item=Chef's delight(3), id=5832, option=[null, null, null, null, drop] +item=Chef's delight(4), id=5833, option=[Drink, null, null, null, drop] +item=Chef's delight(4), id=5834, option=[null, null, null, null, drop] +item=Slayer's respite(1), id=5835, option=[Drink, null, null, null, drop] +item=Slayer's respite(1), id=5836, option=[null, null, null, null, drop] +item=Slayer's respite(2), id=5837, option=[Drink, null, null, null, drop] +item=Slayer's respite(2), id=5838, option=[null, null, null, null, drop] +item=Slayer's respite(3), id=5839, option=[Drink, null, null, null, drop] +item=Slayer's respite(3), id=5840, option=[null, null, null, null, drop] +item=Slayer's respite(4), id=5841, option=[Drink, null, null, null, drop] +item=Slayer's respite(4), id=5842, option=[null, null, null, null, drop] +item=Cider(1), id=5843, option=[Drink, null, null, null, drop] +item=Cider(1), id=5844, option=[null, null, null, null, drop] +item=Cider(2), id=5845, option=[Drink, null, null, null, drop] +item=Cider(2), id=5846, option=[null, null, null, null, drop] +item=Cider(3), id=5847, option=[Drink, null, null, null, drop] +item=Cider(3), id=5848, option=[null, null, null, null, drop] +item=Cider(4), id=5849, option=[Drink, null, null, null, drop] +item=Cider(4), id=5850, option=[null, null, null, null, drop] +item=Dwarven stout(m1), id=5851, option=[Drink, null, null, null, drop] +item=Dwarven stout(m1), id=5852, option=[null, null, null, null, drop] +item=Dwarven stout(m2), id=5853, option=[Drink, null, null, null, drop] +item=Dwarven stout(m2), id=5854, option=[null, null, null, null, drop] +item=Dwarven stout(m3), id=5855, option=[Drink, null, null, null, drop] +item=Dwarven stout(m3), id=5856, option=[null, null, null, null, drop] +item=Dwarven stout(m4), id=5857, option=[Drink, null, null, null, drop] +item=Dwarven stout(m4), id=5858, option=[null, null, null, null, drop] +item=Asgarnian ale(m1), id=5859, option=[Drink, null, null, null, drop] +item=Asgarnian ale(m1), id=5860, option=[null, null, null, null, drop] +item=Asgarnian ale(m2), id=5861, option=[Drink, null, null, null, drop] +item=Asgarnian ale(m2), id=5862, option=[null, null, null, null, drop] +item=Asgarnian ale(m3), id=5863, option=[Drink, null, null, null, drop] +item=Asgarnian ale(m3), id=5864, option=[null, null, null, null, drop] +item=Asgarnian ale(m4), id=5865, option=[Drink, null, null, null, drop] +item=Asgarnian ale(m4), id=5866, option=[null, null, null, null, drop] +item=Greenmans ale(m1), id=5867, option=[Drink, null, null, null, drop] +item=Greenmans ale(m1), id=5868, option=[null, null, null, null, drop] +item=Greenmans ale(m2), id=5869, option=[Drink, null, null, null, drop] +item=Greenmans ale(m2), id=5870, option=[null, null, null, null, drop] +item=Greenmans ale(m3), id=5871, option=[Drink, null, null, null, drop] +item=Greenmans ale(m3), id=5872, option=[null, null, null, null, drop] +item=Greenmans ale(m4), id=5873, option=[Drink, null, null, null, drop] +item=Greenmans ale(m4), id=5874, option=[null, null, null, null, drop] +item=Mind bomb(m1), id=5875, option=[Drink, null, null, null, drop] +item=Mind bomb(m1), id=5876, option=[null, null, null, null, drop] +item=Mind bomb(m2), id=5877, option=[Drink, null, null, null, drop] +item=Mind bomb(m2), id=5878, option=[null, null, null, null, drop] +item=Mind bomb(m3), id=5879, option=[Drink, null, null, null, drop] +item=Mind bomb(m3), id=5880, option=[null, null, null, null, drop] +item=Mind bomb(m4), id=5881, option=[Drink, null, null, null, drop] +item=Mind bomb(m4), id=5882, option=[null, null, null, null, drop] +item=Dragon bitter(m1), id=5883, option=[Drink, null, null, null, drop] +item=Dragon bitter(m1), id=5884, option=[null, null, null, null, drop] +item=Dragon bitter(m2), id=5885, option=[Drink, null, null, null, drop] +item=Dragon bitter(m2), id=5886, option=[null, null, null, null, drop] +item=Dragon bitter(m3), id=5887, option=[Drink, null, null, null, drop] +item=Dragon bitter(m3), id=5888, option=[null, null, null, null, drop] +item=Dragon bitter(m4), id=5889, option=[Drink, null, null, null, drop] +item=Dragon bitter(m4), id=5890, option=[null, null, null, null, drop] +item=M'light mead(m1), id=5891, option=[Drink, null, null, null, drop] +item=M'light mead(m1), id=5892, option=[null, null, null, null, drop] +item=M'light mead(m2), id=5893, option=[Drink, null, null, null, drop] +item=M'light mead(m2), id=5894, option=[null, null, null, null, drop] +item=M'light mead(m3), id=5895, option=[Drink, null, null, null, drop] +item=M'light mead(m3), id=5896, option=[null, null, null, null, drop] +item=M'light mead(m4), id=5897, option=[Drink, null, null, null, drop] +item=M'light mead(m4), id=5898, option=[null, null, null, null, drop] +item=Axeman's folly(m1), id=5899, option=[Drink, null, null, null, drop] +item=Axeman's folly(m1), id=5900, option=[null, null, null, null, drop] +item=Axeman's folly(m2), id=5901, option=[Drink, null, null, null, drop] +item=Axeman's folly(m2), id=5902, option=[null, null, null, null, drop] +item=Axeman's folly(m3), id=5903, option=[Drink, null, null, null, drop] +item=Axeman's folly(m3), id=5904, option=[null, null, null, null, drop] +item=Axeman's folly(m4), id=5905, option=[Drink, null, null, null, drop] +item=Axeman's folly(m4), id=5906, option=[null, null, null, null, drop] +item=Chef's delight(m1), id=5907, option=[Drink, null, null, null, drop] +item=Chef's delight(m1), id=5908, option=[null, null, null, null, drop] +item=Chef's delight(m2), id=5909, option=[Drink, null, null, null, drop] +item=Chef's delight(m2), id=5910, option=[null, null, null, null, drop] +item=Chef's delight(m3), id=5911, option=[Drink, null, null, null, drop] +item=Chef's delight(m3), id=5912, option=[null, null, null, null, drop] +item=Chef's delight(m4), id=5913, option=[Drink, null, null, null, drop] +item=Chef's delight(m4), id=5914, option=[null, null, null, null, drop] +item=Slayer respite(m1), id=5915, option=[Drink, null, null, null, drop] +item=Slayer respite(m1), id=5916, option=[null, null, null, null, drop] +item=Slayer respite(m2), id=5917, option=[Drink, null, null, null, drop] +item=Slayer respite(m2), id=5918, option=[null, null, null, null, drop] +item=Slayer respite(m3), id=5919, option=[Drink, null, null, null, drop] +item=Slayer respite(m3), id=5920, option=[null, null, null, null, drop] +item=Slayer respite(m4), id=5921, option=[Drink, null, null, null, drop] +item=Slayer respite(m4), id=5922, option=[null, null, null, null, drop] +item=Cider(m1), id=5923, option=[Drink, null, null, null, drop] +item=Cider(m1), id=5924, option=[null, null, null, null, drop] +item=Cider(m2), id=5925, option=[Drink, null, null, null, drop] +item=Cider(m2), id=5926, option=[null, null, null, null, drop] +item=Cider(m3), id=5927, option=[Drink, null, null, null, drop] +item=Cider(m3), id=5928, option=[null, null, null, null, drop] +item=Cider(m4), id=5929, option=[Drink, null, null, null, drop] +item=Cider(m4), id=5930, option=[null, null, null, null, drop] +item=Jute fibre, id=5931, option=[null, null, null, null, drop] +item=Jute fibre, id=5932, option=[null, null, null, null, drop] +item=Willow branch, id=5933, option=[null, null, null, null, drop] +item=Willow branch, id=5934, option=[null, null, null, null, drop] +item=Coconut milk, id=5935, option=[null, null, null, Empty, drop] +item=Weapon poison+(unf), id=5936, option=[null, null, null, Empty, drop] +item=Weapon poison+, id=5937, option=[null, null, null, Empty, drop] +item=Weapon poison+, id=5938, option=[null, null, null, null, drop] +item=Weapon poison++(unf), id=5939, option=[null, null, null, Empty, drop] +item=Weapon poison++, id=5940, option=[null, null, null, Empty, drop] +item=Weapon poison++, id=5941, option=[null, null, null, null, drop] +item=Antipoison+(unf), id=5942, option=[null, null, null, Empty, drop] +item=Antipoison+(4), id=5943, option=[Drink, null, null, Empty, drop] +item=Antipoison+(4), id=5944, option=[null, null, null, null, drop] +item=Antipoison+(3), id=5945, option=[Drink, null, null, Empty, drop] +item=Antipoison+(3), id=5946, option=[null, null, null, null, drop] +item=Antipoison+(2), id=5947, option=[Drink, null, null, Empty, drop] +item=Antipoison+(2), id=5948, option=[null, null, null, null, drop] +item=Antipoison+(1), id=5949, option=[Drink, null, null, Empty, drop] +item=Antipoison+(1), id=5950, option=[null, null, null, null, drop] +item=Antipoison++(unf), id=5951, option=[null, null, null, Empty, drop] +item=Antipoison++(4), id=5952, option=[Drink, null, null, Empty, drop] +item=Antipoison++(4), id=5953, option=[null, null, null, null, drop] +item=Antipoison++(3), id=5954, option=[Drink, null, null, Empty, drop] +item=Antipoison++(3), id=5955, option=[null, null, null, null, drop] +item=Antipoison++(2), id=5956, option=[Drink, null, null, Empty, drop] +item=Antipoison++(2), id=5957, option=[null, null, null, null, drop] +item=Antipoison++(1), id=5958, option=[Drink, null, null, Empty, drop] +item=Antipoison++(1), id=5959, option=[null, null, null, null, drop] +item=Tomatoes(1), id=5960, option=[Fill, Remove-one, null, null, drop] +item=Tomatoes(1), id=5961, option=[null, null, null, null, drop] +item=Tomatoes(2), id=5962, option=[Fill, Remove-one, Empty, null, drop] +item=Tomatoes(2), id=5963, option=[null, null, null, null, drop] +item=Tomatoes(3), id=5964, option=[Fill, Remove-one, Empty, null, drop] +item=Tomatoes(3), id=5965, option=[null, null, null, null, drop] +item=Tomatoes(4), id=5966, option=[Fill, Remove-one, Empty, null, drop] +item=Tomatoes(4), id=5967, option=[null, null, null, null, drop] +item=Tomatoes(5), id=5968, option=[Fill, Remove-one, Empty, null, drop] +item=Tomatoes(5), id=5969, option=[null, null, null, null, drop] +item=Curry leaf, id=5970, option=[null, null, null, null, drop] +item=Curry leaf, id=5971, option=[null, null, null, null, drop] +item=Papaya fruit, id=5972, option=[Eat, null, null, null, drop] +item=Papaya fruit, id=5973, option=[null, null, null, null, drop] +item=Coconut, id=5974, option=[null, null, null, null, drop] +item=Coconut, id=5975, option=[null, null, null, null, drop] +item=Coconut, id=5976, option=[null, null, null, null, drop] +item=Coconut, id=5977, option=[null, null, null, null, drop] +item=Coconut shell, id=5978, option=[null, null, null, null, drop] +item=Coconut shell, id=5979, option=[null, null, null, null, drop] +item=Calquat fruit, id=5980, option=[null, null, null, null, drop] +item=Calquat fruit, id=5981, option=[null, null, null, null, drop] +item=Watermelon, id=5982, option=[Eat, null, null, null, drop] +item=Watermelon, id=5983, option=[null, null, null, null, drop] +item=Watermelon slice, id=5984, option=[Eat, null, null, null, drop] +item=Watermelon slice, id=5985, option=[null, null, null, null, drop] +item=Sweetcorn, id=5986, option=[null, null, null, null, drop] +item=Sweetcorn, id=5987, option=[null, null, null, null, drop] +item=Cooked sweetcorn, id=5988, option=[Eat, null, null, null, drop] +item=Cooked sweetcorn, id=5989, option=[null, null, null, null, drop] +item=Burnt sweetcorn, id=5990, option=[null, null, null, null, drop] +item=Burnt sweetcorn, id=5991, option=[null, null, null, null, drop] +item=Apple mush, id=5992, option=[null, null, null, Empty, drop] +item=Apple mush, id=5993, option=[null, null, null, null, drop] +item=Hammerstone hops, id=5994, option=[null, null, null, null, drop] +item=Hammerstone hops, id=5995, option=[null, null, null, null, drop] +item=Asgarnian hops, id=5996, option=[null, null, null, null, drop] +item=Asgarnian hops, id=5997, option=[null, null, null, null, drop] +item=Yanillian hops, id=5998, option=[null, null, null, null, drop] +item=Yanillian hops, id=5999, option=[null, null, null, null, drop] +item=Krandorian hops, id=6000, option=[null, null, null, null, drop] +item=Krandorian hops, id=6001, option=[null, null, null, null, drop] +item=Wildblood hops, id=6002, option=[null, null, null, null, drop] +item=Wildblood hops, id=6003, option=[null, null, null, null, drop] +item=Mushroom, id=6004, option=[null, null, null, null, drop] +item=Mushroom, id=6005, option=[null, null, null, null, drop] +item=Barley, id=6006, option=[null, null, null, null, drop] +item=Barley, id=6007, option=[null, null, null, null, drop] +item=Barley malt, id=6008, option=[null, null, null, null, drop] +item=Barley malt, id=6009, option=[null, null, null, null, drop] +item=Marigolds, id=6010, option=[null, null, null, null, drop] +item=Marigolds, id=6011, option=[null, null, null, null, drop] +item=Nasturtiums, id=6012, option=[null, null, null, null, drop] +item=Nasturtiums, id=6013, option=[null, null, null, null, drop] +item=Rosemary, id=6014, option=[null, null, null, null, drop] +item=Rosemary, id=6015, option=[null, null, null, null, drop] +item=Cactus spine, id=6016, option=[null, null, null, null, drop] +item=Cactus spine, id=6017, option=[null, null, null, null, drop] +item=Poison ivy berries, id=6018, option=[null, null, null, null, drop] +item=Poison ivy berries, id=6019, option=[null, null, null, null, drop] +item=Leaves, id=6020, option=[null, null, null, null, drop] +item=Leaves, id=6021, option=[null, null, null, null, drop] +item=Leaves, id=6022, option=[null, null, null, null, drop] +item=Leaves, id=6023, option=[null, null, null, null, drop] +item=Leaves, id=6024, option=[null, null, null, null, drop] +item=Leaves, id=6025, option=[null, null, null, null, drop] +item=Leaves, id=6026, option=[null, null, null, null, drop] +item=Leaves, id=6027, option=[null, null, null, null, drop] +item=Leaves, id=6028, option=[null, null, null, null, drop] +item=Leaves, id=6029, option=[null, null, null, null, drop] +item=Leaves, id=6030, option=[null, null, null, null, drop] +item=Leaves, id=6031, option=[null, null, null, null, drop] +item=Compost, id=6032, option=[null, null, null, Empty, drop] +item=Compost, id=6033, option=[null, null, null, null, drop] +item=Supercompost, id=6034, option=[null, null, null, Empty, drop] +item=Supercompost, id=6035, option=[null, null, null, null, drop] +item=Plant cure, id=6036, option=[null, null, null, Empty, drop] +item=Plant cure, id=6037, option=[null, null, null, null, drop] +item=Magic string, id=6038, option=[null, null, null, null, drop] +item=Magic string, id=6039, option=[null, null, null, null, drop] +item=Amulet of nature, id=6040, option=[Rub, Wear, Teleport, Contact-farmer, Destroy] +item=Pre-nature amulet, id=6041, option=[null, Wear, null, null, drop] +item=Pre-nature amulet, id=6042, option=[null, null, null, null, drop] +item=Oak roots, id=6043, option=[null, null, null, null, drop] +item=Oak roots, id=6044, option=[null, null, null, null, drop] +item=Willow roots, id=6045, option=[null, null, null, null, drop] +item=Willow roots, id=6046, option=[null, null, null, null, drop] +item=Maple roots, id=6047, option=[null, null, null, null, drop] +item=Maple roots, id=6048, option=[null, null, null, null, drop] +item=Yew roots, id=6049, option=[null, null, null, null, drop] +item=Yew roots, id=6050, option=[null, null, null, null, drop] +item=Magic roots, id=6051, option=[null, null, null, null, drop] +item=Magic roots, id=6052, option=[null, null, null, null, drop] +item=Spirit roots, id=6053, option=[null, null, null, null, drop] +item=Spirit roots, id=6054, option=[null, null, null, null, drop] +item=Weeds, id=6055, option=[null, null, null, null, drop] +item=Weeds, id=6056, option=[null, null, null, null, drop] +item=Hay sack, id=6057, option=[null, null, null, null, drop] +item=Hay sack, id=6058, option=[null, null, null, null, drop] +item=Scarecrow, id=6059, option=[null, null, null, null, drop] +item=Stool, id=6060, option=[null, null, null, null, drop] +item=Bronze bolts(p+), id=6061, option=[null, Wield, null, null, drop] +item=Bronze bolts(p++), id=6062, option=[null, Wield, null, null, drop] +item=Spirit tree, id=6063, option=[null, null, null, null, drop] +item=Bloody mourner top, id=6064, option=[null, null, null, null, drop] +item=Mourner top, id=6065, option=[null, Wear, null, null, drop] +item=Mourner trousers, id=6066, option=[null, null, null, null, drop] +item=Mourner trousers, id=6067, option=[null, Wear, null, null, drop] +item=Mourner gloves, id=6068, option=[null, Wear, null, null, drop] +item=Mourner boots, id=6069, option=[null, Wear, null, null, drop] +item=Mourner cloak, id=6070, option=[null, Wear, null, null, drop] +item=Mourner letter, id=6071, option=[Read, null, null, null, drop] +item=Tegid's soap, id=6072, option=[null, null, null, null, drop] +item=Prifddinas' history, id=6073, option=[Read, null, null, null, drop] +item=Whoopsie, id=6074, option=[null, null, null, null, drop] +item=Eastern discovery, id=6075, option=[Read, null, null, null, drop] +item=Whoopsie, id=6076, option=[null, null, null, null, drop] +item=Eastern settlement, id=6077, option=[Read, null, null, null, drop] +item=Whoopsie, id=6078, option=[null, null, null, null, drop] +item=The great divide, id=6079, option=[Read, null, null, null, drop] +item=Whoopsie, id=6080, option=[null, null, null, null, drop] +item=Broken device, id=6081, option=[null, null, null, null, drop] +item=Fixed device, id=6082, option=[Empty, Wield, null, null, drop] +item=Tarnished key, id=6083, option=[null, null, null, null, drop] +item=Worn key, id=6084, option=[null, null, null, null, drop] +item=Red dye bellows, id=6085, option=[null, null, null, null, drop] +item=Blue dye bellows, id=6086, option=[null, null, null, null, drop] +item=Yellow dye bellows, id=6087, option=[null, null, null, null, drop] +item=Green dye bellows, id=6088, option=[null, null, null, null, drop] +item=Blue toad, id=6089, option=[null, null, null, null, drop] +item=Red toad, id=6090, option=[null, null, null, null, drop] +item=Yellow toad, id=6091, option=[null, null, null, null, drop] +item=Green toad, id=6092, option=[null, null, null, null, drop] +item=Rotten apples, id=6093, option=[null, null, null, null, drop] +item=Apple barrel, id=6094, option=[null, null, null, null, drop] +item=Naphtha apple mix, id=6095, option=[null, null, null, null, drop] +item=Toxic naphtha, id=6096, option=[null, null, null, null, drop] +item=Sieve, id=6097, option=[null, null, null, null, drop] +item=Toxic powder, id=6098, option=[null, null, null, null, drop] +item=Teleport crystal (4), id=6099, option=[Activate, null, null, null, drop] +item=Teleport crystal (3), id=6100, option=[Activate, null, null, null, drop] +item=Teleport crystal (2), id=6101, option=[Activate, null, null, null, drop] +item=Teleport crystal (1), id=6102, option=[Activate, null, null, null, drop] +item=Tiny elf crystal, id=6103, option=[null, null, null, null, drop] +item=New key, id=6104, option=[null, null, null, null, Drop] +item=Elf, id=6105, option=[null, null, null, null, drop] +item=Ghostly boots, id=6106, option=[null, Wear, null, null, drop] +item=Ghostly robe, id=6107, option=[null, Wear, null, null, drop] +item=Ghostly robe, id=6108, option=[null, Wear, null, null, drop] +item=Ghostly hood, id=6109, option=[null, Wear, null, null, drop] +item=Ghostly gloves, id=6110, option=[null, Wear, null, null, drop] +item=Ghostly cloak, id=6111, option=[null, Wear, null, null, drop] +item=Kelda seed, id=6112, option=[null, null, null, null, Destroy] +item=Kelda hops, id=6113, option=[null, null, null, null, Destroy] +item=null, id=6114, option=[null, null, null, null, drop] +item=null, id=6115, option=[null, null, null, null, drop] +item=null, id=6116, option=[null, null, null, null, drop] +item=null, id=6117, option=[null, null, null, null, drop] +item=Kelda stout, id=6118, option=[Drink, null, null, null, Destroy] +item=Square stone, id=6119, option=[null, null, null, null, drop] +item=Square stone, id=6120, option=[null, null, null, null, drop] +item=Letter, id=6121, option=[Read, null, null, null, drop] +item=A chair, id=6122, option=[null, null, null, null, drop] +item=Beer glass, id=6123, option=[null, null, null, null, drop] +item=Coconut milk, id=6124, option=[null, null, null, null, drop] +item=Enchanted lyre(2), id=6125, option=[Play, null, null, null, drop] +item=Enchanted lyre(3), id=6126, option=[Play, null, null, null, drop] +item=Enchanted lyre(4), id=6127, option=[Play, null, null, null, drop] +item=Rock-shell helm, id=6128, option=[null, Wear, null, null, drop] +item=Rock-shell plate, id=6129, option=[null, Wear, null, null, drop] +item=Rock-shell legs, id=6130, option=[null, Wear, null, null, drop] +item=Spined helm, id=6131, option=[null, Wear, null, null, drop] +item=Spined helm, id=6132, option=[null, null, null, null, drop] +item=Spined body, id=6133, option=[null, Wear, null, null, drop] +item=Spined body, id=6134, option=[null, null, null, null, drop] +item=Spined chaps, id=6135, option=[null, Wear, null, null, drop] +item=Spined chaps, id=6136, option=[null, null, null, null, drop] +item=Skeletal helm, id=6137, option=[null, Wear, null, null, drop] +item=Skeletal helm, id=6138, option=[null, null, null, null, drop] +item=Skeletal top, id=6139, option=[null, Wear, null, null, drop] +item=Skeletal top, id=6140, option=[null, null, null, null, drop] +item=Skeletal bottoms, id=6141, option=[null, Wear, null, null, drop] +item=Skeletal bottoms, id=6142, option=[null, null, null, null, drop] +item=Spined boots, id=6143, option=[null, Wear, null, null, drop] +item=Spined boots, id=6144, option=[null, null, null, null, drop] +item=Rock-shell boots, id=6145, option=[null, Wear, null, null, drop] +item=Rock-shell boots, id=6146, option=[null, null, null, null, drop] +item=Skeletal boots, id=6147, option=[null, Wear, null, null, drop] +item=Skeletal boots, id=6148, option=[null, null, null, null, drop] +item=Spined gloves, id=6149, option=[null, Wear, null, null, drop] +item=Spined gloves, id=6150, option=[null, null, null, null, drop] +item=Rock-shell gloves, id=6151, option=[null, Wear, null, null, drop] +item=Rock-shell gloves, id=6152, option=[null, null, null, null, drop] +item=Skeletal gloves, id=6153, option=[null, Wear, null, null, drop] +item=Skeletal gloves, id=6154, option=[null, null, null, null, drop] +item=Dagannoth hide, id=6155, option=[null, null, null, null, drop] +item=Dagannoth hide, id=6156, option=[null, null, null, null, drop] +item=Rock-shell chunk, id=6157, option=[null, null, null, null, drop] +item=Rock-shell chunk, id=6158, option=[null, null, null, null, drop] +item=Rock-shell shard, id=6159, option=[null, null, null, null, drop] +item=Rock-shell shard, id=6160, option=[null, null, null, null, drop] +item=Rock-shell splinter, id=6161, option=[null, null, null, null, drop] +item=Rock-shell splinter, id=6162, option=[null, null, null, null, drop] +item=Skull piece, id=6163, option=[null, null, null, null, drop] +item=Skull piece, id=6164, option=[null, null, null, null, drop] +item=Ribcage piece, id=6165, option=[null, null, null, null, drop] +item=Ribcage piece, id=6166, option=[null, null, null, null, drop] +item=Fibula piece, id=6167, option=[null, null, null, null, drop] +item=Fibula piece, id=6168, option=[null, null, null, null, drop] +item=Circular hide, id=6169, option=[null, null, null, null, drop] +item=Circular hide, id=6170, option=[null, null, null, null, drop] +item=Flattened hide, id=6171, option=[null, null, null, null, drop] +item=Flattened hide, id=6172, option=[null, null, null, null, drop] +item=Stretched hide, id=6173, option=[null, null, null, null, drop] +item=Stretched hide, id=6174, option=[null, null, null, null, drop] +item=Rock-shell helm, id=6175, option=[null, null, null, null, drop] +item=Rock-shell plate, id=6176, option=[null, null, null, null, drop] +item=Rock-shell legs, id=6177, option=[null, null, null, null, drop] +item=Raw pheasant, id=6178, option=[null, null, null, null, drop] +item=Raw pheasant, id=6179, option=[null, null, null, null, drop] +item=Lederhosen top, id=6180, option=[null, Wear, null, null, drop] +item=Lederhosen shorts, id=6181, option=[null, Wear, null, null, drop] +item=Lederhosen hat, id=6182, option=[null, Wear, null, null, drop] +item=Frog token, id=6183, option=[null, null, null, null, drop] +item=Prince tunic, id=6184, option=[null, Wear, null, null, drop] +item=Prince leggings, id=6185, option=[null, Wear, null, null, drop] +item=Princess blouse, id=6186, option=[null, Wear, null, null, drop] +item=Princess skirt, id=6187, option=[null, Wear, null, null, drop] +item=Frog mask, id=6188, option=[null, Wear, null, null, drop] +item=null, id=6189, option=[null, null, null, null, drop] +item=null, id=6190, option=[null, null, null, null, drop] +item=null, id=6191, option=[null, null, null, null, drop] +item=null, id=6192, option=[null, null, null, null, drop] +item=null, id=6193, option=[null, null, null, null, drop] +item=null, id=6194, option=[null, null, null, null, drop] +item=null, id=6195, option=[null, null, null, null, drop] +item=null, id=6196, option=[null, null, null, null, drop] +item=null, id=6197, option=[null, null, null, null, drop] +item=null, id=6198, option=[null, null, null, null, drop] +item=Mystery box, id=6199, option=[Open, null, null, null, drop] +item=Raw fishlike thing, id=6200, option=[null, null, null, null, drop] +item=Fishmonger, id=6201, option=[Wear, null, null, null, drop] +item=Fishlike thing, id=6202, option=[Eat, null, null, null, drop] +item=Sine wave, id=6203, option=[Wear, null, null, null, drop] +item=Raw fishlike thing, id=6204, option=[null, null, null, null, drop] +item=9mm revolver, id=6205, option=[Wear, null, null, null, drop] +item=Fishlike thing, id=6206, option=[Eat, null, null, null, drop] +item=Mobile phone, id=6207, option=[Wear, null, null, null, drop] +item=Man speak amulet, id=6208, option=[null, Wear, null, null, drop] +item=Small fishing net, id=6209, option=[null, null, null, null, drop] +item=Sphinx baby, id=6210, option=[Wear, null, null, null, drop] +item=Teak pyre logs, id=6211, option=[null, null, null, null, drop] +item=Teak pyre logs, id=6212, option=[null, null, null, null, drop] +item=Mahogany pyre log, id=6213, option=[null, null, null, null, drop] +item=Mahogany pyre log, id=6214, option=[null, null, null, null, drop] +item=Broodoo shield (10), id=6215, option=[null, Wield, null, null, drop] +item=Broodoo shield (10), id=6216, option=[null, null, null, null, drop] +item=Broodoo shield (9), id=6217, option=[null, Wield, null, null, drop] +item=Broodoo shield (9), id=6218, option=[null, null, null, null, drop] +item=Broodoo shield (8), id=6219, option=[null, Wield, null, null, drop] +item=Broodoo shield (8), id=6220, option=[null, null, null, null, drop] +item=Broodoo shield (7), id=6221, option=[null, Wield, null, null, drop] +item=Broodoo shield (7), id=6222, option=[null, null, null, null, drop] +item=Broodoo shield (6), id=6223, option=[null, Wield, null, null, drop] +item=Broodoo shield (6), id=6224, option=[null, null, null, null, drop] +item=Broodoo shield (5), id=6225, option=[null, Wield, null, null, drop] +item=Broodoo shield (5), id=6226, option=[null, null, null, null, drop] +item=Broodoo shield (4), id=6227, option=[null, Wield, null, null, drop] +item=Broodoo shield (4), id=6228, option=[null, null, null, null, drop] +item=Broodoo shield (3), id=6229, option=[null, Wield, null, null, drop] +item=Broodoo shield (3), id=6230, option=[null, null, null, null, drop] +item=Broodoo shield (2), id=6231, option=[null, Wield, null, null, drop] +item=Broodoo shield (2), id=6232, option=[null, null, null, null, drop] +item=Broodoo shield (1), id=6233, option=[null, Wield, null, null, drop] +item=Broodoo shield (1), id=6234, option=[null, null, null, null, drop] +item=Broodoo shield, id=6235, option=[null, Wield, null, null, drop] +item=Broodoo shield, id=6236, option=[null, null, null, null, drop] +item=Broodoo shield (10), id=6237, option=[null, Wield, null, null, drop] +item=Broodoo shield (10), id=6238, option=[null, null, null, null, drop] +item=Broodoo shield (9), id=6239, option=[null, Wield, null, null, drop] +item=Broodoo shield (9), id=6240, option=[null, null, null, null, drop] +item=Broodoo shield (8), id=6241, option=[null, Wield, null, null, drop] +item=Broodoo shield (8), id=6242, option=[null, null, null, null, drop] +item=Broodoo shield (7), id=6243, option=[null, Wield, null, null, drop] +item=Broodoo shield (7), id=6244, option=[null, null, null, null, drop] +item=Broodoo shield (6), id=6245, option=[null, Wield, null, null, drop] +item=Broodoo shield (6), id=6246, option=[null, null, null, null, drop] +item=Broodoo shield (5), id=6247, option=[null, Wield, null, null, drop] +item=Broodoo shield (5), id=6248, option=[null, null, null, null, drop] +item=Broodoo shield (4), id=6249, option=[null, Wield, null, null, drop] +item=Broodoo shield (4), id=6250, option=[null, null, null, null, drop] +item=Broodoo shield (3), id=6251, option=[null, Wield, null, null, drop] +item=Broodoo shield (3), id=6252, option=[null, null, null, null, drop] +item=Broodoo shield (2), id=6253, option=[null, Wield, null, null, drop] +item=Broodoo shield (2), id=6254, option=[null, null, null, null, drop] +item=Broodoo shield (1), id=6255, option=[null, Wield, null, null, drop] +item=Broodoo shield (1), id=6256, option=[null, null, null, null, drop] +item=Broodoo shield, id=6257, option=[null, Wield, null, null, drop] +item=Broodoo shield, id=6258, option=[null, null, null, null, drop] +item=Broodoo shield (10), id=6259, option=[null, Wield, null, null, drop] +item=Broodoo shield (10), id=6260, option=[null, null, null, null, drop] +item=Broodoo shield (9), id=6261, option=[null, Wield, null, null, drop] +item=Broodoo shield (9), id=6262, option=[null, null, null, null, drop] +item=Broodoo shield (8), id=6263, option=[null, Wield, null, null, drop] +item=Broodoo shield (8), id=6264, option=[null, null, null, null, drop] +item=Broodoo shield (7), id=6265, option=[null, Wield, null, null, drop] +item=Broodoo shield (7), id=6266, option=[null, null, null, null, drop] +item=Broodoo shield (6), id=6267, option=[null, Wield, null, null, drop] +item=Broodoo shield (6), id=6268, option=[null, null, null, null, drop] +item=Broodoo shield (5), id=6269, option=[null, Wield, null, null, drop] +item=Broodoo shield (5), id=6270, option=[null, null, null, null, drop] +item=Broodoo shield (4), id=6271, option=[null, Wield, null, null, drop] +item=Broodoo shield (4), id=6272, option=[null, null, null, null, drop] +item=Broodoo shield (3), id=6273, option=[null, Wield, null, null, drop] +item=Broodoo shield (3), id=6274, option=[null, null, null, null, drop] +item=Broodoo shield (2), id=6275, option=[null, Wield, null, null, drop] +item=Broodoo shield (2), id=6276, option=[null, null, null, null, drop] +item=Broodoo shield (1), id=6277, option=[null, Wield, null, null, drop] +item=Broodoo shield (1), id=6278, option=[null, null, null, null, drop] +item=Broodoo shield, id=6279, option=[null, Wield, null, null, drop] +item=Broodoo shield, id=6280, option=[null, null, null, null, drop] +item=Thatch spar light, id=6281, option=[null, null, null, null, drop] +item=Thatch spar light, id=6282, option=[null, null, null, null, drop] +item=Thatch spar med, id=6283, option=[null, null, null, null, drop] +item=Thatch spar med, id=6284, option=[null, null, null, null, drop] +item=Thatch spar dense, id=6285, option=[null, null, null, null, drop] +item=Thatch spar dense, id=6286, option=[null, null, null, null, drop] +item=Snake hide, id=6287, option=[null, null, null, null, drop] +item=Snake hide, id=6288, option=[null, null, null, null, drop] +item=Snakeskin, id=6289, option=[null, null, null, null, drop] +item=Snakeskin, id=6290, option=[null, null, null, null, drop] +item=Spider carcass, id=6291, option=[null, null, null, null, drop] +item=Spider carcass, id=6292, option=[null, null, null, null, drop] +item=Spider on stick, id=6293, option=[null, null, null, null, drop] +item=Spider on stick, id=6294, option=[null, null, null, null, drop] +item=Spider on shaft, id=6295, option=[null, null, null, null, drop] +item=Spider on shaft, id=6296, option=[null, null, null, null, drop] +item=Spider on stick, id=6297, option=[Eat, null, null, null, drop] +item=Spider on stick, id=6298, option=[null, null, null, null, drop] +item=Spider on shaft, id=6299, option=[Eat, null, null, null, drop] +item=Spider on shaft, id=6300, option=[null, null, null, null, drop] +item=Burnt spider, id=6301, option=[null, null, null, null, drop] +item=Burnt spider, id=6302, option=[null, null, null, null, drop] +item=Spider on shaft, id=6303, option=[null, null, null, null, drop] +item=Spider on shaft, id=6304, option=[null, null, null, null, drop] +item=Skewer stick, id=6305, option=[null, null, null, null, drop] +item=Trading sticks, id=6306, option=[null, null, null, null, drop] +item=null, id=6307, option=[null, null, null, null, drop] +item=null, id=6308, option=[null, null, null, null, drop] +item=null, id=6309, option=[null, null, null, null, drop] +item=null, id=6310, option=[null, null, null, null, drop] +item=Gout tuber, id=6311, option=[Eat, null, null, null, drop] +item=Gout tuber, id=6312, option=[null, null, null, null, drop] +item=Opal machete, id=6313, option=[null, Wield, null, null, drop] +item=Opal machete, id=6314, option=[null, null, null, null, drop] +item=Jade machete, id=6315, option=[null, Wield, null, null, drop] +item=Jade machete, id=6316, option=[null, null, null, null, drop] +item=Red topaz machete, id=6317, option=[null, Wield, null, null, drop] +item=Red topaz machete, id=6318, option=[null, null, null, null, drop] +item=Proboscis, id=6319, option=[null, null, null, null, drop] +item=null, id=6320, option=[null, null, null, null, drop] +item=null, id=6321, option=[null, null, null, null, drop] +item=Snakeskin body, id=6322, option=[null, Wear, null, null, drop] +item=Snakeskin body, id=6323, option=[null, null, null, null, drop] +item=Snakeskin chaps, id=6324, option=[null, Wear, null, null, drop] +item=Snakeskin chaps, id=6325, option=[null, null, null, null, drop] +item=Snakeskin bandana, id=6326, option=[null, Wear, null, null, drop] +item=Snakeskin bandana, id=6327, option=[null, null, null, null, drop] +item=Snakeskin boots, id=6328, option=[null, Wear, null, null, drop] +item=Snakeskin boots, id=6329, option=[null, null, null, null, drop] +item=Snakeskin v'brace, id=6330, option=[null, Wear, null, null, drop] +item=Snakeskin v'brace, id=6331, option=[null, null, null, null, drop] +item=Mahogany logs, id=6332, option=[null, null, null, null, drop] +item=Teak logs, id=6333, option=[null, null, null, null, drop] +item=Teak logs, id=6334, option=[null, null, null, null, drop] +item=Tribal mask, id=6335, option=[null, Wear, null, null, drop] +item=Tribal mask, id=6336, option=[null, null, null, null, drop] +item=Tribal mask, id=6337, option=[null, Wear, null, null, drop] +item=Tribal mask, id=6338, option=[null, null, null, null, drop] +item=Tribal mask, id=6339, option=[null, Wear, null, null, drop] +item=Tribal mask, id=6340, option=[null, null, null, null, drop] +item=Tribal top, id=6341, option=[null, Wear, null, null, drop] +item=Tribal top, id=6342, option=[null, null, null, null, drop] +item=Villager robe, id=6343, option=[null, Wear, null, null, drop] +item=Villager robe, id=6344, option=[null, null, null, null, drop] +item=Villager hat, id=6345, option=[null, Wear, null, null, drop] +item=Villager hat, id=6346, option=[null, null, null, null, drop] +item=Villager armband, id=6347, option=[null, Wear, null, null, drop] +item=Villager armband, id=6348, option=[null, null, null, null, drop] +item=Villager sandals, id=6349, option=[null, Wear, null, null, drop] +item=Villager sandals, id=6350, option=[null, null, null, null, drop] +item=Tribal top, id=6351, option=[null, Wear, null, null, drop] +item=Tribal top, id=6352, option=[null, null, null, null, drop] +item=Villager robe, id=6353, option=[null, Wear, null, null, drop] +item=Villager robe, id=6354, option=[null, null, null, null, drop] +item=Villager hat, id=6355, option=[null, Wear, null, null, drop] +item=Villager hat, id=6356, option=[null, null, null, null, drop] +item=Villager sandals, id=6357, option=[null, Wear, null, null, drop] +item=Villager sandals, id=6358, option=[null, null, null, null, drop] +item=Villager armband, id=6359, option=[null, Wear, null, null, drop] +item=Villager armband, id=6360, option=[null, null, null, null, drop] +item=Tribal top, id=6361, option=[null, Wear, null, null, drop] +item=Tribal top, id=6362, option=[null, null, null, null, drop] +item=Villager robe, id=6363, option=[null, Wear, null, null, drop] +item=Villager robe, id=6364, option=[null, null, null, null, drop] +item=Villager hat, id=6365, option=[null, Wear, null, null, drop] +item=Villager hat, id=6366, option=[null, null, null, null, drop] +item=Villager sandals, id=6367, option=[null, Wear, null, null, drop] +item=Villager sandals, id=6368, option=[null, null, null, null, drop] +item=Villager armband, id=6369, option=[null, Wear, null, null, drop] +item=Villager armband, id=6370, option=[null, null, null, null, drop] +item=Tribal top, id=6371, option=[null, Wear, null, null, drop] +item=Tribal top, id=6372, option=[null, null, null, null, drop] +item=Villager robe, id=6373, option=[null, Wear, null, null, drop] +item=Villager robe, id=6374, option=[null, null, null, null, drop] +item=Villager hat, id=6375, option=[null, Wear, null, null, drop] +item=Villager hat, id=6376, option=[null, null, null, null, drop] +item=Villager sandals, id=6377, option=[null, Wear, null, null, drop] +item=Villager sandals, id=6378, option=[null, null, null, null, drop] +item=Villager armband, id=6379, option=[null, Wear, null, null, drop] +item=Villager armband, id=6380, option=[null, null, null, null, drop] +item=Tax relief, id=6381, option=[Wear, null, null, null, drop] +item=Fez, id=6382, option=[null, Wear, null, null, drop] +item=Fez, id=6383, option=[null, null, null, null, drop] +item=Desert top, id=6384, option=[null, Wear, null, null, drop] +item=Desert top, id=6385, option=[null, null, null, null, drop] +item=Desert robes, id=6386, option=[null, Wear, null, null, drop] +item=Desert robes, id=6387, option=[null, null, null, null, drop] +item=Desert top, id=6388, option=[null, Wear, null, null, drop] +item=Desert top, id=6389, option=[null, null, null, null, drop] +item=Desert legs, id=6390, option=[null, Wear, null, null, drop] +item=Desert legs, id=6391, option=[null, null, null, null, drop] +item=Menap headgear, id=6392, option=[null, Wear, null, null, drop] +item=Menap headgear, id=6393, option=[null, null, null, null, drop] +item=Menaphite top, id=6394, option=[null, Wear, null, null, drop] +item=Menaphite top, id=6395, option=[null, null, null, null, drop] +item=Menaphite robe, id=6396, option=[null, Wear, null, null, drop] +item=Menaphite robe, id=6397, option=[null, null, null, null, drop] +item=Menap action kilt, id=6398, option=[null, Wear, null, null, drop] +item=Menap action kilt, id=6399, option=[null, null, null, null, drop] +item=Menap headgear, id=6400, option=[null, Wear, null, null, drop] +item=Menap headgear, id=6401, option=[null, null, null, null, drop] +item=Menaphite top, id=6402, option=[null, Wear, null, null, drop] +item=Menaphite top, id=6403, option=[null, null, null, null, drop] +item=Menaphite robe, id=6404, option=[null, Wear, null, null, drop] +item=Menaphite robe, id=6405, option=[null, null, null, null, drop] +item=Menap action kilt, id=6406, option=[null, Wear, null, null, drop] +item=Menap action kilt, id=6407, option=[null, null, null, null, drop] +item=Oak blackjack(o), id=6408, option=[null, Wield, null, null, drop] +item=Oak blackjack(o), id=6409, option=[null, null, null, null, drop] +item=Oak blackjack(d), id=6410, option=[null, Wield, null, null, drop] +item=Oak blackjack(d), id=6411, option=[null, null, null, null, drop] +item=Willow blackjack(o), id=6412, option=[null, Wield, null, null, drop] +item=Willow blackjack(o), id=6413, option=[null, null, null, null, drop] +item=Willow blackjack(d), id=6414, option=[null, Wield, null, null, drop] +item=Willow blackjack(d), id=6415, option=[null, null, null, null, drop] +item=Maple blackjack, id=6416, option=[null, Wield, null, null, drop] +item=Maple blackjack, id=6417, option=[null, null, null, null, drop] +item=Maple blackjack(o), id=6418, option=[null, Wield, null, null, drop] +item=Maple blackjack(o), id=6419, option=[null, null, null, null, drop] +item=Maple blackjack(d), id=6420, option=[null, Wield, null, null, drop] +item=Maple blackjack(d), id=6421, option=[null, null, null, null, drop] +item=Air rune, id=6422, option=[null, null, null, null, drop] +item=Air rune, id=6423, option=[null, null, null, null, drop] +item=Water rune, id=6424, option=[null, null, null, null, drop] +item=Water rune, id=6425, option=[null, null, null, null, drop] +item=Earth rune, id=6426, option=[null, null, null, null, drop] +item=Earth rune, id=6427, option=[null, null, null, null, drop] +item=Fire rune, id=6428, option=[null, null, null, null, drop] +item=Fire rune, id=6429, option=[null, null, null, null, drop] +item=Chaos rune, id=6430, option=[null, null, null, null, drop] +item=Chaos rune, id=6431, option=[null, null, null, null, drop] +item=Death rune, id=6432, option=[null, null, null, null, drop] +item=Death rune, id=6433, option=[null, null, null, null, drop] +item=Law rune, id=6434, option=[null, null, null, null, drop] +item=Law rune, id=6435, option=[null, null, null, null, drop] +item=Mind rune, id=6436, option=[null, null, null, null, drop] +item=Mind rune, id=6437, option=[null, null, null, null, drop] +item=Body rune, id=6438, option=[null, null, null, null, drop] +item=Body rune, id=6439, option=[null, null, null, null, drop] +item=null, id=6440, option=[null, null, null, null, drop] +item=null, id=6441, option=[null, null, null, null, drop] +item=null, id=6442, option=[null, null, null, null, drop] +item=null, id=6443, option=[null, null, null, null, drop] +item=null, id=6444, option=[null, null, null, null, drop] +item=null, id=6445, option=[null, null, null, null, drop] +item=null, id=6446, option=[null, null, null, null, drop] +item=null, id=6447, option=[null, null, null, null, drop] +item=Spadeful of coke, id=6448, option=[Empty, null, null, null, drop] +item=null, id=6449, option=[null, null, null, null, drop] +item=Whoopsie, id=6450, option=[Wear, null, null, null, drop] +item=null, id=6451, option=[null, null, null, null, drop] +item=Whoopsie, id=6452, option=[Wear, null, null, null, drop] +item=White rose seed, id=6453, option=[null, null, null, null, Destroy] +item=Red rose seed, id=6454, option=[null, null, null, null, Destroy] +item=Pink rose seed, id=6455, option=[null, null, null, null, Destroy] +item=Vine seed, id=6456, option=[null, null, null, null, Destroy] +item=Delphinium seed, id=6457, option=[null, null, null, null, Destroy] +item=Orchid seed, id=6458, option=[null, null, null, null, Destroy] +item=Orchid seed, id=6459, option=[null, null, null, null, Destroy] +item=Snowdrop seed, id=6460, option=[null, null, null, null, Destroy] +item=White tree shoot, id=6461, option=[null, null, null, null, Destroy] +item=White tree shoot, id=6462, option=[null, null, null, null, Destroy] +item=White tree shoot, id=6463, option=[null, null, null, null, Destroy] +item=White tree sapling, id=6464, option=[null, null, null, null, Destroy] +item=Ring of charos(a), id=6465, option=[null, Wear, null, null, Destroy] +item=Rune shards, id=6466, option=[null, null, null, null, drop] +item=Rune dust, id=6467, option=[null, null, null, null, drop] +item=Plant cure, id=6468, option=[null, null, null, null, drop] +item=White tree fruit, id=6469, option=[Eat, null, null, null, drop] +item=Compost potion(4), id=6470, option=[null, null, null, Empty, drop] +item=Compost potion(4), id=6471, option=[null, null, null, null, drop] +item=Compost potion(3), id=6472, option=[null, null, null, Empty, drop] +item=Compost potion(3), id=6473, option=[null, null, null, null, drop] +item=Compost potion(2), id=6474, option=[null, null, null, Empty, drop] +item=Compost potion(2), id=6475, option=[null, null, null, null, drop] +item=Compost potion(1), id=6476, option=[null, null, null, Empty, drop] +item=Compost potion(1), id=6477, option=[null, null, null, null, drop] +item=Trolley, id=6478, option=[null, null, null, null, Destroy] +item=List, id=6479, option=[Read, null, null, null, Destroy] +item=null, id=6480, option=[null, null, null, null, drop] +item=null, id=6481, option=[null, null, null, null, drop] +item=null, id=6482, option=[null, null, null, null, drop] +item=null, id=6483, option=[null, null, null, null, drop] +item=null, id=6484, option=[null, null, null, null, drop] +item=null, id=6485, option=[null, null, null, null, drop] +item=null, id=6486, option=[null, null, null, null, drop] +item=null, id=6487, option=[null, null, null, null, drop] +item=null, id=6488, option=[null, null, null, null, drop] +item=null, id=6489, option=[null, null, null, null, drop] +item=null, id=6490, option=[null, null, null, null, drop] +item=null, id=6491, option=[null, null, null, null, drop] +item=null, id=6492, option=[null, null, null, null, drop] +item=null, id=6493, option=[null, null, null, null, drop] +item=null, id=6494, option=[null, null, null, null, drop] +item=null, id=6495, option=[null, null, null, null, drop] +item=null, id=6496, option=[null, null, null, null, drop] +item=null, id=6497, option=[null, null, null, null, drop] +item=null, id=6498, option=[null, null, null, null, drop] +item=null, id=6499, option=[null, null, null, null, drop] +item=null, id=6500, option=[null, null, null, null, drop] +item=null, id=6501, option=[null, null, null, null, drop] +item=null, id=6502, option=[null, null, null, null, drop] +item=null, id=6503, option=[null, null, null, null, drop] +item=null, id=6504, option=[null, null, null, null, drop] +item=null, id=6505, option=[null, null, null, null, drop] +item=null, id=6506, option=[null, null, null, null, drop] +item=null, id=6507, option=[null, null, null, null, drop] +item=null, id=6508, option=[null, null, null, null, drop] +item=null, id=6509, option=[null, null, null, null, drop] +item=null, id=6510, option=[null, null, null, null, drop] +item=null, id=6511, option=[null, null, null, null, drop] +item=null, id=6512, option=[null, null, null, null, drop] +item=null, id=6513, option=[null, null, null, null, drop] +item=Agility jump, id=6514, option=[null, null, null, null, drop] +item=Agility balance, id=6515, option=[null, null, null, null, drop] +item=Agility contortion, id=6516, option=[null, null, null, null, drop] +item=Agility climb, id=6517, option=[null, null, null, null, drop] +item=Agility jump, id=6518, option=[null, null, null, null, drop] +item=Agility balance, id=6519, option=[null, null, null, null, drop] +item=Agility contortion, id=6520, option=[null, null, null, null, drop] +item=Agility climb, id=6521, option=[null, null, null, null, drop] +item=Toktz-xil-ul, id=6522, option=[null, Wield, null, null, drop] +item=Toktz-xil-ak, id=6523, option=[null, Wield, null, null, drop] +item=Toktz-ket-xil, id=6524, option=[null, Wield, null, null, drop] +item=Toktz-xil-ek, id=6525, option=[null, Wield, null, null, drop] +item=Toktz-mej-tal, id=6526, option=[null, Wield, null, null, drop] +item=Tzhaar-ket-em, id=6527, option=[null, Wield, null, null, drop] +item=Tzhaar-ket-om, id=6528, option=[null, Wield, null, null, drop] +item=Tokkul, id=6529, option=[null, null, null, null, drop] +item=null, id=6530, option=[null, null, null, null, drop] +item=null, id=6531, option=[null, null, null, null, drop] +item=null, id=6532, option=[null, null, null, null, drop] +item=null, id=6533, option=[null, null, null, null, drop] +item=null, id=6534, option=[null, null, null, null, drop] +item=Toktz-xil-ak, id=6535, option=[null, null, null, null, drop] +item=Toktz-ket-xil, id=6536, option=[null, null, null, null, drop] +item=Toktz-xil-ek, id=6537, option=[null, null, null, null, drop] +item=Toktz-mej-tal, id=6538, option=[null, null, null, null, drop] +item=Tzhaar-ket-em, id=6539, option=[null, null, null, null, drop] +item=Tzhaar-ket-om, id=6540, option=[null, null, null, null, drop] +item=Mouse toy, id=6541, option=[null, Wield, null, null, Destroy] +item=Present, id=6542, option=[Open, null, null, null, Destroy] +item=Antique lamp, id=6543, option=[Rub, null, null, null, Destroy] +item=Catspeak amulet(e), id=6544, option=[null, Wear, Open, null, Destroy] +item=Chores, id=6545, option=[Read, null, null, null, Destroy] +item=Recipe, id=6546, option=[Read, null, null, null, Destroy] +item=Doctors hat, id=6547, option=[null, Wear, null, null, Destroy] +item=Nurse hat, id=6548, option=[null, Wear, null, null, Destroy] +item=Lazy cat, id=6549, option=[null, null, null, null, drop] +item=Lazy cat, id=6550, option=[null, null, null, null, drop] +item=Lazy cat, id=6551, option=[null, null, null, null, drop] +item=Lazy cat, id=6552, option=[null, null, null, null, drop] +item=Lazy cat, id=6553, option=[null, null, null, null, drop] +item=Lazy cat, id=6554, option=[null, null, null, null, drop] +item=Wily cat, id=6555, option=[null, null, null, null, drop] +item=Wily cat, id=6556, option=[null, null, null, null, drop] +item=Wily cat, id=6557, option=[null, null, null, null, drop] +item=Wily cat, id=6558, option=[null, null, null, null, drop] +item=Wily cat, id=6559, option=[null, null, null, null, drop] +item=Wily cat, id=6560, option=[null, null, null, null, drop] +item=Ahab's beer, id=6561, option=[null, null, null, null, drop] +item=Mud battlestaff, id=6562, option=[null, Wield, null, null, drop] +item=Mystic mud staff, id=6563, option=[null, Wield, null, null, drop] +item=Onyx ring, id=6564, option=[null, null, null, null, drop] +item=Onyx necklace, id=6565, option=[null, null, null, null, drop] +item=Onyx amulet, id=6566, option=[null, null, null, null, drop] +item=null, id=6567, option=[null, null, null, null, drop] +item=Obsidian cape, id=6568, option=[null, Wear, null, null, drop] +item=Obsidian cape, id=6569, option=[null, null, null, null, drop] +item=Fire cape, id=6570, option=[null, Wear, null, null, drop] +item=Uncut onyx, id=6571, option=[null, null, null, null, drop] +item=Uncut onyx, id=6572, option=[null, null, null, null, drop] +item=Onyx, id=6573, option=[null, null, null, null, drop] +item=Onyx, id=6574, option=[null, null, null, null, drop] +item=Onyx ring, id=6575, option=[null, Wear, null, null, drop] +item=Onyx ring, id=6576, option=[null, null, null, null, drop] +item=Onyx necklace, id=6577, option=[null, Wear, null, null, drop] +item=Onyx necklace, id=6578, option=[null, null, null, null, drop] +item=Onyx amulet, id=6579, option=[null, null, null, null, drop] +item=Onyx amulet, id=6580, option=[null, null, null, null, drop] +item=Onyx amulet, id=6581, option=[null, Wear, null, null, drop] +item=Onyx amulet, id=6582, option=[null, null, null, null, drop] +item=Ring of stone, id=6583, option=[null, Wear, null, null, drop] +item=Ring of stone, id=6584, option=[null, null, null, null, drop] +item=Amulet of fury, id=6585, option=[null, Wear, null, null, drop] +item=Amulet of fury, id=6586, option=[null, null, null, null, drop] +item=White claws, id=6587, option=[null, Wear, null, null, drop] +item=White claws, id=6588, option=[null, null, null, null, drop] +item=White battleaxe, id=6589, option=[null, Wield, null, null, drop] +item=White battleaxe, id=6590, option=[null, null, null, null, drop] +item=White dagger, id=6591, option=[null, Wield, null, null, drop] +item=White dagger, id=6592, option=[null, null, null, null, drop] +item=White dagger(p), id=6593, option=[null, Wield, null, null, drop] +item=White dagger(p), id=6594, option=[null, null, null, null, drop] +item=White dagger(p+), id=6595, option=[null, Wield, null, null, drop] +item=White dagger(p+), id=6596, option=[null, null, null, null, drop] +item=White dagger(p++), id=6597, option=[null, Wield, null, null, drop] +item=White dagger(p++), id=6598, option=[null, null, null, null, drop] +item=White halberd, id=6599, option=[null, Wield, null, null, drop] +item=White halberd, id=6600, option=[null, null, null, null, drop] +item=White mace, id=6601, option=[null, Wield, null, null, drop] +item=White mace, id=6602, option=[null, null, null, null, drop] +item=White magic staff, id=6603, option=[null, Wield, null, null, drop] +item=White magic staff, id=6604, option=[null, null, null, null, drop] +item=White sword, id=6605, option=[null, Wield, null, null, drop] +item=White sword, id=6606, option=[null, null, null, null, drop] +item=White longsword, id=6607, option=[null, Wield, null, null, drop] +item=White longsword, id=6608, option=[null, null, null, null, drop] +item=White 2h sword, id=6609, option=[null, Wield, null, null, drop] +item=White 2h sword, id=6610, option=[null, null, null, null, drop] +item=White scimitar, id=6611, option=[null, Wield, null, null, drop] +item=White scimitar, id=6612, option=[null, null, null, null, drop] +item=White warhammer, id=6613, option=[null, Wield, null, null, drop] +item=White warhammer, id=6614, option=[null, null, null, null, drop] +item=White chainbody, id=6615, option=[null, Wear, null, null, drop] +item=White chainbody, id=6616, option=[null, null, null, null, drop] +item=White platebody, id=6617, option=[null, Wear, null, null, drop] +item=White platebody, id=6618, option=[null, null, null, null, drop] +item=White boots, id=6619, option=[null, Wear, null, null, drop] +item=White boots, id=6620, option=[null, null, null, null, drop] +item=White med helm, id=6621, option=[null, Wear, null, null, drop] +item=White med helm, id=6622, option=[null, null, null, null, drop] +item=White full helm, id=6623, option=[null, Wear, null, null, drop] +item=White full helm, id=6624, option=[null, null, null, null, drop] +item=White platelegs, id=6625, option=[null, Wear, null, null, drop] +item=White platelegs, id=6626, option=[null, null, null, null, drop] +item=White plateskirt, id=6627, option=[null, Wear, null, null, drop] +item=White plateskirt, id=6628, option=[null, null, null, null, drop] +item=White gloves, id=6629, option=[null, Wear, null, null, drop] +item=White gloves, id=6630, option=[null, null, null, null, drop] +item=White sq shield, id=6631, option=[null, Wield, null, null, drop] +item=White sq shield, id=6632, option=[null, null, null, null, drop] +item=White kiteshield, id=6633, option=[null, Wear, null, null, drop] +item=White kiteshield, id=6634, option=[null, null, null, null, drop] +item=Commorb, id=6635, option=[Scan, Contact, null, Playback, Destroy] +item=Solus's hat, id=6636, option=[null, null, null, null, drop] +item=Dark beast, id=6637, option=[null, null, null, null, drop] +item=Colour wheel, id=6638, option=[null, null, null, null, drop] +item=Hand mirror, id=6639, option=[null, null, null, null, Destroy] +item=Red crystal, id=6640, option=[null, null, null, null, Destroy] +item=Yellow crystal, id=6641, option=[null, null, null, null, Destroy] +item=Green crystal, id=6642, option=[null, null, null, null, Destroy] +item=Cyan crystal, id=6643, option=[null, null, null, null, Destroy] +item=Blue crystal, id=6644, option=[null, null, null, null, Destroy] +item=Magenta crystal, id=6645, option=[null, null, null, null, Destroy] +item=Fractured crystal, id=6646, option=[null, null, null, null, Destroy] +item=Fractured crystal, id=6647, option=[null, null, null, null, Destroy] +item=Item list, id=6648, option=[Read, null, null, null, Destroy] +item=Edern's journal, id=6649, option=[Read, null, null, null, drop] +item=Blackened crystal, id=6650, option=[null, null, null, null, drop] +item=Newly made crystal, id=6651, option=[null, null, null, null, drop] +item=Newly made crystal, id=6652, option=[null, null, null, null, drop] +item=Crystal trinket, id=6653, option=[null, null, null, null, Destroy] +item=Camo top, id=6654, option=[null, Wear, null, null, drop] +item=Camo bottoms, id=6655, option=[null, Wear, null, null, drop] +item=Camo helmet, id=6656, option=[null, Wear, null, null, drop] +item=Camo top, id=6657, option=[null, null, null, null, drop] +item=Camo bottoms, id=6658, option=[null, null, null, null, drop] +item=Camo helmet, id=6659, option=[null, null, null, null, drop] +item=Fishing explosive, id=6660, option=[null, null, null, null, drop] +item=Mogre, id=6661, option=[null, null, null, null, drop] +item=Broken fishing rod, id=6662, option=[null, null, null, null, drop] +item=Forlorn boot, id=6663, option=[null, null, null, null, drop] +item=Fishing explosive, id=6664, option=[null, null, null, null, drop] +item=Mudskipper hat, id=6665, option=[null, Wear, null, null, drop] +item=Flippers, id=6666, option=[null, Wear, null, null, drop] +item=Fishbowl, id=6667, option=[null, null, null, null, drop] +item=Fishbowl, id=6668, option=[null, null, Empty, null, drop] +item=Fishbowl, id=6669, option=[null, null, Empty, null, drop] +item=Fishbowl, id=6670, option=[Talk-At, Play-With, Feed, null, drop] +item=Fishbowl, id=6671, option=[Talk-At, Play-With, Feed, null, drop] +item=Fishbowl, id=6672, option=[Talk-At, Play-With, Feed, null, drop] +item=Fishbowl and net, id=6673, option=[null, Untangle, null, null, drop] +item=Tiny net, id=6674, option=[null, null, null, null, drop] +item=An empty box, id=6675, option=[null, null, null, null, drop] +item=Whoopsie, id=6676, option=[null, null, null, null, drop] +item=Guam in a box, id=6677, option=[null, null, null, null, drop] +item=Guam in a box?, id=6678, option=[null, null, null, null, drop] +item=Seaweed in a box, id=6679, option=[null, null, null, null, drop] +item=Seaweed in a box?, id=6680, option=[null, null, null, null, drop] +item=Ground guam, id=6681, option=[null, null, null, null, drop] +item=Ground guam, id=6682, option=[null, null, null, null, drop] +item=Ground seaweed, id=6683, option=[null, null, null, null, drop] +item=Ground seaweed, id=6684, option=[null, null, null, null, drop] +item=Saradomin brew(4), id=6685, option=[Drink, null, null, Empty, drop] +item=Saradomin brew(4), id=6686, option=[null, null, null, null, drop] +item=Saradomin brew(3), id=6687, option=[Drink, null, null, Empty, drop] +item=Saradomin brew(3), id=6688, option=[null, null, null, null, drop] +item=Saradomin brew(2), id=6689, option=[Drink, null, null, Empty, drop] +item=Saradomin brew(2), id=6690, option=[null, null, null, null, drop] +item=Saradomin brew(1), id=6691, option=[Drink, null, null, Empty, drop] +item=Saradomin brew(1), id=6692, option=[null, null, null, null, drop] +item=Crushed nest, id=6693, option=[null, null, null, null, drop] +item=Crushed nest, id=6694, option=[null, null, null, null, drop] +item=Desert lizard, id=6695, option=[null, null, null, null, drop] +item=Ice cooler, id=6696, option=[null, null, null, null, drop] +item=Pat of butter, id=6697, option=[null, null, null, null, drop] +item=Pat of butter, id=6698, option=[null, null, null, null, drop] +item=Burnt potato, id=6699, option=[null, null, null, null, drop] +item=Burnt potato, id=6700, option=[null, null, null, null, drop] +item=Baked potato, id=6701, option=[Eat, null, null, null, drop] +item=Baked potato, id=6702, option=[null, null, null, null, drop] +item=Potato with butter, id=6703, option=[Eat, null, null, null, drop] +item=Potato with butter, id=6704, option=[null, null, null, null, drop] +item=Potato with cheese, id=6705, option=[Eat, null, null, null, drop] +item=Potato with cheese, id=6706, option=[null, null, null, null, drop] +item=Camulet, id=6707, option=[null, Wear, Check-charge, Rub, drop] +item=Slayer gloves, id=6708, option=[null, null, null, null, drop] +item=Fever spider, id=6709, option=[null, null, null, null, drop] +item=Blindweed seed, id=6710, option=[null, null, null, null, drop] +item=Blindweed, id=6711, option=[null, null, null, null, drop] +item=Bucket of water, id=6712, option=[null, null, null, Empty, drop] +item=Wrench, id=6713, option=[null, null, null, null, drop] +item=Holy wrench, id=6714, option=[null, null, null, null, drop] +item=Sluglings, id=6715, option=[null, null, null, null, drop] +item=Karamthulhu, id=6716, option=[null, null, null, null, drop] +item=Karamthulhu, id=6717, option=[null, null, null, null, drop] +item=Fever spider body, id=6718, option=[null, null, null, null, drop] +item=Unsanitary swill, id=6719, option=[null, null, null, null, drop] +item=Slayer gloves, id=6720, option=[null, Wear, null, null, drop] +item=Rusty scimitar, id=6721, option=[null, null, null, null, drop] +item=Zombie head, id=6722, option=[Talk-At, Display, Question, null, drop] +item=Fishbowl, id=6723, option=[null, null, null, null, drop] +item=Seercull, id=6724, option=[null, Wield, null, null, drop] +item=Seercull, id=6725, option=[null, null, null, null, drop] +item=Mud battlestaff, id=6726, option=[null, null, null, null, drop] +item=Mystic mud staff, id=6727, option=[null, null, null, null, drop] +item=Bonemeal, id=6728, option=[null, Empty, null, null, drop] +item=Dagannoth bones, id=6729, option=[Bury, null, null, null, drop] +item=Dagannoth bones, id=6730, option=[null, null, null, null, drop] +item=Seers ring, id=6731, option=[null, Wear, null, null, drop] +item=Seers ring, id=6732, option=[null, null, null, null, drop] +item=Archers ring, id=6733, option=[null, Wear, null, null, drop] +item=Archers ring, id=6734, option=[null, null, null, null, drop] +item=Warrior ring, id=6735, option=[null, Wear, null, null, drop] +item=Warrior ring, id=6736, option=[null, null, null, null, drop] +item=Berserker ring, id=6737, option=[null, Wear, null, null, drop] +item=Berserker ring, id=6738, option=[null, null, null, null, drop] +item=Dragon axe, id=6739, option=[null, Wield, null, null, drop] +item=Dragon axe, id=6740, option=[null, null, null, null, drop] +item=Broken axe, id=6741, option=[null, null, null, null, drop] +item=Broken axe, id=6742, option=[null, null, null, null, drop] +item=Dragon axe head, id=6743, option=[null, null, null, null, drop] +item=Dragon axe head, id=6744, option=[null, null, null, null, drop] +item=Silverlight, id=6745, option=[null, Wield, null, null, drop] +item=Darklight, id=6746, option=[null, Wield, null, null, drop] +item=Demonic sigil mould, id=6747, option=[null, null, null, null, drop] +item=Demonic sigil, id=6748, option=[Chant, null, null, null, drop] +item=Demonic tome, id=6749, option=[Read, null, null, null, drop] +item=Black desert shirt, id=6750, option=[null, Wear, null, null, drop] +item=Whoopsie, id=6751, option=[null, null, null, null, drop] +item=Black desert robe, id=6752, option=[null, Wear, null, null, drop] +item=Whoopsie, id=6753, option=[null, null, null, null, drop] +item=Enchanted key, id=6754, option=[Feel, null, null, null, Destroy] +item=Journal, id=6755, option=[Read, null, null, null, Destroy] +item=Letter, id=6756, option=[null, null, null, null, Destroy] +item=Letter, id=6757, option=[null, null, null, null, Destroy] +item=Scroll, id=6758, option=[Read, null, null, null, Destroy] +item=Chest, id=6759, option=[null, null, null, null, Destroy] +item=Guthix mjolnir, id=6760, option=[null, Wield, null, null, drop] +item=Guthix mjolnir, id=6761, option=[null, null, null, null, drop] +item=Saradomin mjolnir, id=6762, option=[null, Wield, null, null, drop] +item=Saradomin mjolnir, id=6763, option=[null, null, null, null, drop] +item=Zamorak mjolnir, id=6764, option=[null, Wield, null, null, drop] +item=Zamorak mjolnir, id=6765, option=[null, null, null, null, drop] +item=Cat antipoison, id=6766, option=[null, null, null, Empty, drop] +item=Book, id=6767, option=[Read, null, null, null, drop] +item=Poisoned cheese, id=6768, option=[Eat, null, null, null, drop] +item=Music scroll, id=6769, option=[Read, null, null, null, Destroy] +item=Directions, id=6770, option=[Read, null, null, null, Destroy] +item=Pot of weeds, id=6771, option=[null, null, null, null, drop] +item=Smouldering pot, id=6772, option=[null, null, null, null, drop] +item=Rat pole, id=6773, option=[null, Wield, null, null, drop] +item=Rat pole, id=6774, option=[Remove-rat, Wield, null, null, drop] +item=Rat pole, id=6775, option=[Remove-rat, Wield, null, null, drop] +item=Rat pole, id=6776, option=[Remove-rat, Wield, null, null, drop] +item=Rat pole, id=6777, option=[Remove-rat, Wield, null, null, drop] +item=Rat pole, id=6778, option=[Remove-rat, Wield, null, null, drop] +item=Rat pole, id=6779, option=[Remove-rat, Wield, null, null, drop] +item=Menaphite thug, id=6780, option=[null, null, null, null, drop] +item=Bandit, id=6781, option=[null, null, null, null, drop] +item=Bandit, id=6782, option=[null, null, null, null, drop] +item=null, id=6783, option=[null, null, null, null, drop] +item=Whoopsie, id=6784, option=[Wear, null, null, null, drop] +item=Statuette, id=6785, option=[null, null, null, null, drop] +item=Robe of elidinis, id=6786, option=[null, Wear, null, null, drop] +item=Robe of elidinis, id=6787, option=[null, Wear, null, null, drop] +item=Torn robe, id=6788, option=[null, Wear, null, null, drop] +item=Torn robe, id=6789, option=[null, Wear, null, null, drop] +item=Shoes, id=6790, option=[null, Wear, null, null, drop] +item=Sole, id=6791, option=[null, null, null, null, drop] +item=Ancestral key, id=6792, option=[null, null, null, null, drop] +item=Ballad, id=6793, option=[Read, null, null, null, drop] +item=Choc-ice, id=6794, option=[Eat, null, null, null, drop] +item=Choc-ice, id=6795, option=[null, null, null, null, drop] +item=Lamp, id=6796, option=[null, null, null, null, drop] +item=Watering can, id=6797, option=[null, null, null, null, drop] +item=Champion scroll, id=6798, option=[Read, null, null, null, drop] +item=Champion scroll, id=6799, option=[Read, null, null, null, drop] +item=Champion scroll, id=6800, option=[Read, null, null, null, drop] +item=Champion scroll, id=6801, option=[Read, null, null, null, drop] +item=Champion scroll, id=6802, option=[Read, null, null, null, drop] +item=Champion scroll, id=6803, option=[Read, null, null, null, drop] +item=Champion scroll, id=6804, option=[Read, null, null, null, drop] +item=Champion scroll, id=6805, option=[Read, null, null, null, drop] +item=Champion scroll, id=6806, option=[Read, null, null, null, drop] +item=Champion scroll, id=6807, option=[Read, null, null, null, drop] +item=Champion scroll, id=6808, option=[Read, null, null, null, drop] +item=Granite legs, id=6809, option=[null, Wear, null, null, drop] +item=Bonemeal, id=6810, option=[null, Empty, null, null, drop] +item=Skeletal wyvern, id=6811, option=[null, null, null, null, drop] +item=Wyvern bones, id=6812, option=[Bury, null, null, null, drop] +item=Granite legs, id=6813, option=[null, null, null, null, drop] +item=Fur, id=6814, option=[null, null, null, null, drop] +item=Fur, id=6815, option=[null, null, null, null, drop] +item=Wyvern bones, id=6816, option=[null, null, null, null, drop] +item=Slender blade, id=6817, option=[null, null, null, null, Destroy] +item=Bow-sword, id=6818, option=[null, Wield, null, null, Destroy] +item=Large pouch, id=6819, option=[Fill, Empty, Check, null, Destroy] +item=Relic, id=6820, option=[null, null, null, null, Destroy] +item=Orb, id=6821, option=[null, null, null, null, Destroy] +item=Star bauble, id=6822, option=[null, null, null, null, drop] +item=Star bauble, id=6823, option=[null, null, null, null, drop] +item=Star bauble, id=6824, option=[null, null, null, null, drop] +item=Star bauble, id=6825, option=[null, null, null, null, drop] +item=Star bauble, id=6826, option=[null, null, null, null, drop] +item=Star bauble, id=6827, option=[null, null, null, null, drop] +item=Box bauble, id=6828, option=[null, null, null, null, drop] +item=Box bauble, id=6829, option=[null, null, null, null, drop] +item=Box bauble, id=6830, option=[null, null, null, null, drop] +item=Box bauble, id=6831, option=[null, null, null, null, drop] +item=Box bauble, id=6832, option=[null, null, null, null, drop] +item=Box bauble, id=6833, option=[null, null, null, null, drop] +item=Diamond bauble, id=6834, option=[null, null, null, null, drop] +item=Diamond bauble, id=6835, option=[null, null, null, null, drop] +item=Diamond bauble, id=6836, option=[null, null, null, null, drop] +item=Diamond bauble, id=6837, option=[null, null, null, null, drop] +item=Diamond bauble, id=6838, option=[null, null, null, null, drop] +item=Diamond bauble, id=6839, option=[null, null, null, null, drop] +item=Tree bauble, id=6840, option=[null, null, null, null, drop] +item=Tree bauble, id=6841, option=[null, null, null, null, drop] +item=Tree bauble, id=6842, option=[null, null, null, null, drop] +item=Tree bauble, id=6843, option=[null, null, null, null, drop] +item=Tree bauble, id=6844, option=[null, null, null, null, drop] +item=Tree bauble, id=6845, option=[null, null, null, null, drop] +item=Bell bauble, id=6846, option=[null, null, null, null, drop] +item=Bell bauble, id=6847, option=[null, null, null, null, drop] +item=Bell bauble, id=6848, option=[null, null, null, null, drop] +item=Bell bauble, id=6849, option=[null, null, null, null, drop] +item=Bell bauble, id=6850, option=[null, null, null, null, drop] +item=Bell bauble, id=6851, option=[null, null, null, null, drop] +item=Puppet box, id=6852, option=[Examine-closer, null, null, null, drop] +item=Bauble box, id=6853, option=[Examine-closer, null, null, null, drop] +item=Puppet box, id=6854, option=[null, null, null, null, Destroy] +item=Bauble box, id=6855, option=[null, null, null, null, Destroy] +item=Bobble hat, id=6856, option=[null, Wear, null, null, Destroy] +item=Bobble scarf, id=6857, option=[null, Wear, null, null, Destroy] +item=Jester hat, id=6858, option=[null, Wear, null, null, Destroy] +item=Jester scarf, id=6859, option=[null, Wear, null, null, Destroy] +item=Tri-jester hat, id=6860, option=[null, Wear, null, null, Destroy] +item=Tri-jester scarf, id=6861, option=[null, Wear, null, null, Destroy] +item=Woolly hat, id=6862, option=[null, Wear, null, null, Destroy] +item=Woolly scarf, id=6863, option=[null, Wear, null, null, Destroy] +item=Marionette handle, id=6864, option=[null, Wear, null, null, drop] +item=Blue marionette, id=6865, option=[Jump, Walk, Bow, Dance, Destroy] +item=Green marionette, id=6866, option=[Jump, Walk, Bow, Dance, Destroy] +item=Red marionette, id=6867, option=[Jump, Walk, Bow, Dance, Destroy] +item=Blue marionette, id=6868, option=[null, null, null, null, drop] +item=Green marionette, id=6869, option=[null, null, null, null, drop] +item=Red marionette, id=6870, option=[null, null, null, null, drop] +item=Red marionette, id=6871, option=[null, null, null, null, drop] +item=Red marionette, id=6872, option=[null, null, null, null, drop] +item=Red marionette, id=6873, option=[null, null, null, null, drop] +item=Red marionette, id=6874, option=[null, null, null, null, drop] +item=Blue marionette, id=6875, option=[null, null, null, null, drop] +item=Blue marionette, id=6876, option=[null, null, null, null, drop] +item=Blue marionette, id=6877, option=[null, null, null, null, drop] +item=Blue marionette, id=6878, option=[null, null, null, null, drop] +item=Green marionette, id=6879, option=[null, null, null, null, drop] +item=Green marionette, id=6880, option=[null, null, null, null, drop] +item=Green marionette, id=6881, option=[null, null, null, null, drop] +item=Green marionette, id=6882, option=[null, null, null, null, drop] +item=Peach, id=6883, option=[Eat, null, null, null, drop] +item=null, id=6884, option=[null, null, null, null, drop] +item=Progress hat, id=6885, option=[Talk-to, Wear, null, null, Destroy] +item=Progress hat, id=6886, option=[Talk-to, Wear, null, null, Destroy] +item=Progress hat, id=6887, option=[Talk-to, Wear, null, null, Destroy] +item=Guardian statue, id=6888, option=[null, null, null, null, drop] +item=Mage's book, id=6889, option=[null, Wield, null, null, drop] +item=Mage's book, id=6890, option=[null, null, null, null, drop] +item=Arena book, id=6891, option=[Read, null, null, null, drop] +item=Whoopsie, id=6892, option=[null, null, null, null, drop] +item=Leather boots, id=6893, option=[null, Wear, null, null, drop] +item=Adamant kiteshield, id=6894, option=[null, Wear, null, null, drop] +item=Adamant med helm, id=6895, option=[null, Wear, null, null, drop] +item=Emerald, id=6896, option=[null, null, null, null, drop] +item=Rune longsword, id=6897, option=[null, Wield, null, null, drop] +item=Cylinder, id=6898, option=[null, null, null, null, drop] +item=Cube, id=6899, option=[null, null, null, null, drop] +item=Icosahedron, id=6900, option=[null, null, null, null, drop] +item=Pentamid, id=6901, option=[null, null, null, null, drop] +item=Orb, id=6902, option=[null, null, null, null, drop] +item=Dragonstone, id=6903, option=[null, null, null, null, drop] +item=Animals' bones, id=6904, option=[null, null, null, null, drop] +item=Animals' bones, id=6905, option=[null, null, null, null, drop] +item=Animals' bones, id=6906, option=[null, null, null, null, drop] +item=Animals' bones, id=6907, option=[null, null, null, null, drop] +item=Beginner wand, id=6908, option=[null, Wield, null, null, drop] +item=Beginner wand, id=6909, option=[null, null, null, null, drop] +item=Apprentice wand, id=6910, option=[null, Wield, null, null, drop] +item=Apprentice wand, id=6911, option=[null, null, null, null, drop] +item=Teacher wand, id=6912, option=[null, Wield, null, null, drop] +item=Teacher wand, id=6913, option=[null, null, null, null, drop] +item=Master wand, id=6914, option=[null, Wield, null, null, drop] +item=Master wand, id=6915, option=[null, null, null, null, drop] +item=Infinity top, id=6916, option=[null, Wear, null, null, drop] +item=Infinity top, id=6917, option=[null, null, null, null, drop] +item=Infinity hat, id=6918, option=[null, Wear, null, null, drop] +item=Infinity hat, id=6919, option=[null, null, null, null, drop] +item=Infinity boots, id=6920, option=[null, Wear, null, null, drop] +item=Infinity boots, id=6921, option=[null, null, null, null, drop] +item=Infinity gloves, id=6922, option=[null, Wear, null, null, drop] +item=Infinity gloves, id=6923, option=[null, null, null, null, drop] +item=Infinity bottoms, id=6924, option=[null, Wear, null, null, drop] +item=Infinity bottoms, id=6925, option=[null, null, null, null, drop] +item=Bones to peaches, id=6926, option=[null, null, null, null, drop] +item=null, id=6927, option=[null, null, null, null, drop] +item=null, id=6928, option=[null, null, null, null, drop] +item=null, id=6929, option=[null, null, null, null, drop] +item=null, id=6930, option=[null, null, null, null, drop] +item=null, id=6931, option=[null, null, null, null, drop] +item=null, id=6932, option=[null, null, null, null, drop] +item=null, id=6933, option=[null, null, null, null, drop] +item=null, id=6934, option=[null, null, null, null, drop] +item=null, id=6935, option=[null, null, null, null, drop] +item=null, id=6936, option=[null, null, null, null, drop] +item=null, id=6937, option=[null, null, null, null, drop] +item=null, id=6938, option=[null, null, null, null, drop] +item=null, id=6939, option=[null, null, null, null, drop] +item=null, id=6940, option=[null, null, null, null, drop] +item=null, id=6941, option=[null, null, null, null, drop] +item=null, id=6942, option=[null, null, null, null, drop] +item=null, id=6943, option=[null, null, null, null, drop] +item=null, id=6944, option=[null, null, null, null, drop] +item=Sandy hand, id=6945, option=[null, null, null, null, Destroy] +item=Beer-soaked hand, id=6946, option=[null, null, null, null, Destroy] +item=Bert's rota, id=6947, option=[Read, null, null, null, Destroy] +item=Sandy's rota, id=6948, option=[Read, null, null, null, Destroy] +item=A magic scroll, id=6949, option=[null, null, null, null, Destroy] +item=Magical orb, id=6950, option=[Activate, null, null, null, Destroy] +item=Magical orb (a), id=6951, option=[null, null, null, null, Destroy] +item=Truth serum, id=6952, option=[null, null, null, null, Destroy] +item=Bottled water, id=6953, option=[null, null, null, null, Destroy] +item=Redberry juice, id=6954, option=[null, null, null, null, Destroy] +item=Pink dye, id=6955, option=[null, null, null, null, Destroy] +item=Rose-tinted lens, id=6956, option=[null, null, null, null, Destroy] +item=Wizard's head, id=6957, option=[null, null, null, null, Destroy] +item=Sand, id=6958, option=[null, null, null, null, Destroy] +item=Cape, id=6959, option=[null, Wear, null, null, drop] +item=Cape, id=6960, option=[null, null, null, null, drop] +item=Baguette, id=6961, option=[Eat, null, null, null, drop] +item=Triangle sandwich, id=6962, option=[Eat, null, null, null, drop] +item=Roll, id=6963, option=[Eat, null, null, null, drop] +item=Coins, id=6964, option=[null, null, null, null, drop] +item=Square sandwich, id=6965, option=[Eat, null, null, null, drop] +item=Prison key, id=6966, option=[Return, null, null, null, drop] +item=Dragon med helm, id=6967, option=[null, Wear, null, null, drop] +item=Triangle sandwich, id=6968, option=[null, null, null, null, drop] +item=Shark, id=6969, option=[Eat, null, null, null, drop] +item=Pyramid top, id=6970, option=[null, null, null, null, drop] +item=Sandstone (1kg), id=6971, option=[null, null, null, null, drop] +item=Sandstone (1kg), id=6972, option=[null, null, null, null, drop] +item=Sandstone (2kg), id=6973, option=[null, null, null, null, drop] +item=Sandstone (2kg), id=6974, option=[null, null, null, null, drop] +item=Sandstone (5kg), id=6975, option=[null, null, null, null, drop] +item=Sandstone (5kg), id=6976, option=[null, null, null, null, drop] +item=Sandstone (10kg), id=6977, option=[null, null, null, null, drop] +item=Sandstone (10kg), id=6978, option=[null, null, null, null, drop] +item=Granite (500g), id=6979, option=[null, null, null, null, drop] +item=Granite (500g), id=6980, option=[null, null, null, null, drop] +item=Granite (2kg), id=6981, option=[null, null, null, null, drop] +item=Granite (2kg), id=6982, option=[null, null, null, null, drop] +item=Granite (5kg), id=6983, option=[null, null, null, null, drop] +item=Granite (5kg), id=6984, option=[null, null, null, null, drop] +item=Sandstone (20kg), id=6985, option=[null, null, null, null, Destroy] +item=Sandstone (32kg), id=6986, option=[null, null, null, null, Destroy] +item=Sandstone body, id=6987, option=[null, null, null, null, Destroy] +item=Sandstone base, id=6988, option=[null, null, null, null, Destroy] +item=Stone head, id=6989, option=[null, null, null, null, Destroy] +item=Stone head, id=6990, option=[null, null, null, null, Destroy] +item=Stone head, id=6991, option=[null, null, null, null, Destroy] +item=Stone head, id=6992, option=[null, null, null, null, Destroy] +item=Z sigil, id=6993, option=[null, null, null, null, Destroy] +item=M sigil, id=6994, option=[null, null, null, null, Destroy] +item=R sigil, id=6995, option=[null, null, null, null, Destroy] +item=K sigil, id=6996, option=[null, null, null, null, Destroy] +item=Stone left arm, id=6997, option=[null, null, null, null, Destroy] +item=Stone right arm, id=6998, option=[null, null, null, null, Destroy] +item=Stone left leg, id=6999, option=[null, null, null, null, Destroy] +item=Stone right leg, id=7000, option=[null, null, null, null, Destroy] +item=Camel mould (p), id=7001, option=[null, null, null, null, Destroy] +item=Stone head, id=7002, option=[null, null, null, null, Destroy] +item=Camel mask, id=7003, option=[null, Wear, null, null, drop] +item=Chisel, id=7004, option=[null, null, null, null, drop] +item=null, id=7005, option=[null, null, null, null, drop] +item=null, id=7006, option=[null, null, null, null, drop] +item=null, id=7007, option=[null, null, null, null, drop] +item=null, id=7008, option=[null, null, null, null, drop] +item=null, id=7009, option=[null, null, null, null, drop] +item=null, id=7010, option=[null, null, null, null, drop] +item=null, id=7011, option=[null, null, null, null, drop] +item=null, id=7012, option=[null, null, null, null, drop] +item=null, id=7013, option=[null, null, null, null, drop] +item=null, id=7014, option=[null, null, null, null, drop] +item=null, id=7015, option=[null, null, null, null, drop] +item=null, id=7016, option=[null, null, null, null, drop] +item=null, id=7017, option=[null, null, null, null, drop] +item=null, id=7018, option=[null, null, null, null, drop] +item=null, id=7019, option=[null, null, null, null, drop] +item=null, id=7020, option=[null, null, null, null, drop] +item=null, id=7021, option=[null, null, null, null, drop] +item=null, id=7022, option=[null, null, null, null, drop] +item=null, id=7023, option=[null, null, null, null, drop] +item=null, id=7024, option=[null, null, null, null, drop] +item=null, id=7025, option=[null, null, null, null, drop] +item=null, id=7026, option=[null, null, null, null, drop] +item=null, id=7027, option=[null, null, null, null, drop] +item=null, id=7028, option=[null, null, null, null, drop] +item=null, id=7029, option=[null, null, null, null, drop] +item=null, id=7030, option=[null, null, null, null, drop] +item=null, id=7031, option=[null, null, null, null, drop] +item=null, id=7032, option=[null, null, null, null, drop] +item=null, id=7033, option=[null, null, null, null, drop] +item=null, id=7034, option=[null, null, null, null, drop] +item=null, id=7035, option=[null, null, null, null, drop] +item=null, id=7036, option=[null, null, null, null, drop] +item=null, id=7037, option=[null, null, null, null, drop] +item=null, id=7038, option=[null, null, null, null, drop] +item=null, id=7039, option=[null, null, null, null, drop] +item=null, id=7040, option=[null, null, null, null, drop] +item=null, id=7041, option=[null, null, null, null, drop] +item=null, id=7042, option=[null, null, null, null, drop] +item=null, id=7043, option=[null, null, null, null, drop] +item=null, id=7044, option=[null, null, null, null, drop] +item=null, id=7045, option=[null, null, null, null, drop] +item=null, id=7046, option=[null, null, null, null, drop] +item=null, id=7047, option=[null, null, null, null, drop] +item=null, id=7048, option=[null, null, null, null, drop] +item=null, id=7049, option=[null, null, null, null, drop] +item=Swarm, id=7050, option=[null, null, null, null, drop] +item=Unlit bug lantern, id=7051, option=[null, Wield, null, null, drop] +item=Unlit bug lantern, id=7052, option=[null, null, null, null, drop] +item=Lit bug lantern, id=7053, option=[null, Wield, Extinguish, null, drop] +item=Chilli potato, id=7054, option=[Eat, null, null, null, drop] +item=Chilli potato, id=7055, option=[null, null, null, null, drop] +item=Egg potato, id=7056, option=[Eat, null, null, null, drop] +item=Egg potato, id=7057, option=[null, null, null, null, drop] +item=Mushroom potato, id=7058, option=[Eat, null, null, null, drop] +item=Mushroom potato, id=7059, option=[null, null, null, null, drop] +item=Tuna potato, id=7060, option=[Eat, null, null, null, drop] +item=Tuna potato, id=7061, option=[null, null, null, null, drop] +item=Chilli con carne, id=7062, option=[Eat, null, null, null, drop] +item=Chilli con carne, id=7063, option=[null, null, null, null, drop] +item=Egg and tomato, id=7064, option=[Eat, null, null, null, drop] +item=Egg and tomato, id=7065, option=[null, null, null, null, drop] +item=Mushroom & onion, id=7066, option=[Eat, null, null, null, drop] +item=Mushroom & onion, id=7067, option=[null, null, null, null, drop] +item=Tuna and corn, id=7068, option=[Eat, null, null, null, drop] +item=Tuna and corn, id=7069, option=[null, null, null, null, drop] +item=Minced meat, id=7070, option=[Eat, null, null, null, drop] +item=Minced meat, id=7071, option=[null, null, null, null, drop] +item=Spicy sauce, id=7072, option=[Eat, null, null, null, drop] +item=Spicy sauce, id=7073, option=[null, null, null, null, drop] +item=Chopped garlic, id=7074, option=[null, null, null, null, drop] +item=Chopped garlic, id=7075, option=[null, null, null, null, drop] +item=Uncooked egg, id=7076, option=[null, null, null, null, drop] +item=Uncooked egg, id=7077, option=[null, null, null, null, drop] +item=Scrambled egg, id=7078, option=[Eat, null, null, null, drop] +item=Scrambled egg, id=7079, option=[null, null, null, null, drop] +item=Sliced mushrooms, id=7080, option=[null, null, null, null, drop] +item=Sliced mushrooms, id=7081, option=[null, null, null, null, drop] +item=Fried mushrooms, id=7082, option=[Eat, null, null, null, drop] +item=Fried mushrooms, id=7083, option=[null, null, null, null, drop] +item=Fried onions, id=7084, option=[Eat, null, null, null, drop] +item=Fried onions, id=7085, option=[null, null, null, null, drop] +item=Chopped tuna, id=7086, option=[Eat, null, null, null, drop] +item=Chopped tuna, id=7087, option=[null, null, null, null, drop] +item=Sweetcorn, id=7088, option=[Eat, null, null, null, drop] +item=Sweetcorn, id=7089, option=[null, null, null, null, drop] +item=Burnt egg, id=7090, option=[Empty, null, null, null, drop] +item=Burnt egg, id=7091, option=[null, null, null, null, drop] +item=Burnt onion, id=7092, option=[Empty, null, null, null, drop] +item=Burnt onion, id=7093, option=[null, null, null, null, drop] +item=Burnt mushroom, id=7094, option=[Empty, null, null, null, drop] +item=Burnt mushroom, id=7095, option=[null, null, null, null, drop] +item=Board game piece, id=7096, option=[null, null, null, null, drop] +item=Board game piece, id=7097, option=[null, null, null, null, drop] +item=Board game piece, id=7098, option=[null, null, null, null, drop] +item=Board game piece, id=7099, option=[null, null, null, null, drop] +item=Board game piece, id=7100, option=[null, null, null, null, drop] +item=Board game piece, id=7101, option=[null, null, null, null, drop] +item=Board game piece, id=7102, option=[null, null, null, null, drop] +item=Board game piece, id=7103, option=[null, null, null, null, drop] +item=Board game piece, id=7104, option=[null, null, null, null, drop] +item=Board game piece, id=7105, option=[null, null, null, null, drop] +item=Board game piece, id=7106, option=[null, null, null, null, drop] +item=Board game piece, id=7107, option=[null, null, null, null, drop] +item=Gunpowder, id=7108, option=[null, null, null, null, drop] +item=Fuse, id=7109, option=[null, null, null, null, drop] +item=Stripy pirate shirt, id=7110, option=[null, Wear, null, null, drop] +item=Stripy pirate shirt, id=7111, option=[null, null, null, null, drop] +item=Pirate bandana, id=7112, option=[null, Wear, null, null, drop] +item=Pirate bandana, id=7113, option=[null, null, null, null, drop] +item=Pirate boots, id=7114, option=[null, Wear, null, null, drop] +item=Pirate boots, id=7115, option=[null, null, null, null, drop] +item=Pirate leggings, id=7116, option=[null, Wear, null, null, drop] +item=Pirate leggings, id=7117, option=[null, null, null, null, drop] +item=Canister, id=7118, option=[null, null, null, null, drop] +item=Cannon ball, id=7119, option=[null, null, null, null, drop] +item=Ramrod, id=7120, option=[null, null, null, null, drop] +item=Repair plank, id=7121, option=[null, null, null, null, drop] +item=Stripy pirate shirt, id=7122, option=[null, Wear, null, null, drop] +item=Stripy pirate shirt, id=7123, option=[null, null, null, null, drop] +item=Pirate bandana, id=7124, option=[null, Wear, null, null, drop] +item=Pirate bandana, id=7125, option=[null, null, null, null, drop] +item=Pirate leggings, id=7126, option=[null, Wear, null, null, drop] +item=Pirate leggings, id=7127, option=[null, null, null, null, drop] +item=Stripy pirate shirt, id=7128, option=[null, Wear, null, null, drop] +item=Stripy pirate shirt, id=7129, option=[null, null, null, null, drop] +item=Pirate bandana, id=7130, option=[null, Wear, null, null, drop] +item=Pirate bandana, id=7131, option=[null, null, null, null, drop] +item=Pirate leggings, id=7132, option=[null, Wear, null, null, drop] +item=Pirate leggings, id=7133, option=[null, null, null, null, drop] +item=Stripy pirate shirt, id=7134, option=[null, Wear, null, null, drop] +item=Stripy pirate shirt, id=7135, option=[null, null, null, null, drop] +item=Pirate bandana, id=7136, option=[null, Wear, null, null, drop] +item=Pirate bandana, id=7137, option=[null, null, null, null, drop] +item=Pirate leggings, id=7138, option=[null, Wear, null, null, drop] +item=Pirate leggings, id=7139, option=[null, null, null, null, drop] +item=Lucky cutlass, id=7140, option=[null, Wield, null, null, drop] +item=Harry's cutlass, id=7141, option=[null, Wield, null, null, drop] +item=Rapier, id=7142, option=[null, Wield, null, null, drop] +item=Plunder, id=7143, option=[null, null, null, null, drop] +item=Book o' piracy, id=7144, option=[Read, null, null, null, drop] +item=Cannon barrel, id=7145, option=[null, null, null, null, drop] +item=Broken cannon, id=7146, option=[null, null, null, null, drop] +item=Cannon balls, id=7147, option=[null, null, null, null, drop] +item=Repair plank, id=7148, option=[null, null, null, null, drop] +item=Canister, id=7149, option=[null, null, null, null, drop] +item=Tacks, id=7150, option=[null, null, null, null, drop] +item=null, id=7151, option=[null, null, null, null, drop] +item=null, id=7152, option=[null, null, null, null, drop] +item=null, id=7153, option=[null, null, null, null, drop] +item=null, id=7154, option=[null, null, null, null, drop] +item=Rope, id=7155, option=[null, null, null, null, drop] +item=Tinderbox, id=7156, option=[null, null, null, null, drop] +item=Braindeath 'rum', id=7157, option=[Drink, null, null, null, drop] +item=Dragon 2h sword, id=7158, option=[null, Wield, null, null, drop] +item=Insulated boots, id=7159, option=[null, Wear, null, null, drop] +item=Killerwatt, id=7160, option=[null, null, null, null, drop] +item=Insulated boots, id=7161, option=[null, null, null, null, drop] +item=Pie recipe book, id=7162, option=[Read, null, null, null, drop] +item=Pie recipe book, id=7163, option=[null, null, null, null, drop] +item=Part mud pie, id=7164, option=[null, null, null, null, drop] +item=Part mud pie, id=7165, option=[null, null, null, null, drop] +item=Part mud pie, id=7166, option=[null, null, null, null, drop] +item=Part mud pie, id=7167, option=[null, null, null, null, drop] +item=Raw mud pie, id=7168, option=[null, null, null, null, drop] +item=Raw mud pie, id=7169, option=[null, null, null, null, drop] +item=Mud pie, id=7170, option=[null, Wield, null, null, drop] +item=Mud pie, id=7171, option=[null, null, null, null, drop] +item=Part garden pie, id=7172, option=[null, null, null, null, drop] +item=Part garden pie, id=7173, option=[null, null, null, null, drop] +item=Part garden pie, id=7174, option=[null, null, null, null, drop] +item=Part garden pie, id=7175, option=[null, null, null, null, drop] +item=Raw garden pie, id=7176, option=[null, null, null, null, drop] +item=Raw garden pie, id=7177, option=[null, null, null, null, drop] +item=Garden pie, id=7178, option=[Eat, null, null, null, drop] +item=Garden pie, id=7179, option=[null, null, null, null, drop] +item=Half a garden pie, id=7180, option=[Eat, null, null, null, drop] +item=Half a garden pie, id=7181, option=[null, null, null, null, drop] +item=Part fish pie, id=7182, option=[null, null, null, null, drop] +item=Part fish pie, id=7183, option=[null, null, null, null, drop] +item=Part fish pie, id=7184, option=[null, null, null, null, drop] +item=Part fish pie, id=7185, option=[null, null, null, null, drop] +item=Raw fish pie, id=7186, option=[null, null, null, null, drop] +item=Raw fish pie, id=7187, option=[null, null, null, null, drop] +item=Fish pie, id=7188, option=[Eat, null, null, null, drop] +item=Fish pie, id=7189, option=[null, null, null, null, drop] +item=Half a fish pie, id=7190, option=[Eat, null, null, null, drop] +item=Half a fish pie, id=7191, option=[null, null, null, null, drop] +item=Part admiral pie, id=7192, option=[null, null, null, null, drop] +item=Part admiral pie, id=7193, option=[null, null, null, null, drop] +item=Part admiral pie, id=7194, option=[null, null, null, null, drop] +item=Part admiral pie, id=7195, option=[null, null, null, null, drop] +item=Raw admiral pie, id=7196, option=[null, null, null, null, drop] +item=Raw admiral pie, id=7197, option=[null, null, null, null, drop] +item=Admiral pie, id=7198, option=[Eat, null, null, null, drop] +item=Admiral pie, id=7199, option=[null, null, null, null, drop] +item=Half an admiral pie, id=7200, option=[Eat, null, null, null, drop] +item=Half an admiral pie, id=7201, option=[null, null, null, null, drop] +item=Part wild pie, id=7202, option=[null, null, null, null, drop] +item=Part wild pie, id=7203, option=[null, null, null, null, drop] +item=Part wild pie, id=7204, option=[null, null, null, null, drop] +item=Part wild pie, id=7205, option=[null, null, null, null, drop] +item=Raw wild pie, id=7206, option=[null, null, null, null, drop] +item=Raw wild pie, id=7207, option=[null, null, null, null, drop] +item=Wild pie, id=7208, option=[Eat, null, null, null, drop] +item=Wild pie, id=7209, option=[null, null, null, null, drop] +item=Half a wild pie, id=7210, option=[Eat, null, null, null, drop] +item=Half a wild pie, id=7211, option=[null, null, null, null, drop] +item=Part summer pie, id=7212, option=[null, null, null, null, drop] +item=Part summer pie, id=7213, option=[null, null, null, null, drop] +item=Part summer pie, id=7214, option=[null, null, null, null, drop] +item=Part summer pie, id=7215, option=[null, null, null, null, drop] +item=Raw summer pie, id=7216, option=[null, null, null, null, drop] +item=Raw summer pie, id=7217, option=[null, null, null, null, drop] +item=Summer pie, id=7218, option=[Eat, null, null, null, drop] +item=Summer pie, id=7219, option=[null, null, null, null, drop] +item=Half a summer pie, id=7220, option=[Eat, null, null, null, drop] +item=Half a summer pie, id=7221, option=[null, null, null, null, drop] +item=Burnt rabbit, id=7222, option=[null, null, null, null, drop] +item=Roast rabbit, id=7223, option=[Eat, null, null, null, drop] +item=Skewered rabbit, id=7224, option=[null, null, null, null, drop] +item=Iron spit, id=7225, option=[null, null, null, null, drop] +item=Burnt chompy, id=7226, option=[null, null, null, null, drop] +item=Burnt chompy, id=7227, option=[null, null, null, null, drop] +item=Cooked chompy, id=7228, option=[Eat, null, null, null, drop] +item=Cooked chompy, id=7229, option=[null, null, null, null, drop] +item=Skewered chompy, id=7230, option=[null, null, null, null, drop] +item=Burnt rabbit, id=7231, option=[null, null, null, null, drop] +item=Roast rabbit, id=7232, option=[null, null, null, null, drop] +item=Skewered rabbit, id=7233, option=[null, null, null, null, drop] +item=Iron spit, id=7234, option=[null, null, null, null, drop] +item=Skewered chompy, id=7235, option=[null, null, null, null, drop] +item=Clue scroll, id=7236, option=[Read, null, null, null, drop] +item=Casket, id=7237, option=[Open, null, null, null, drop] +item=Clue scroll, id=7238, option=[Read, null, null, null, drop] +item=Clue scroll, id=7239, option=[Read, null, null, null, drop] +item=Casket, id=7240, option=[Open, null, null, null, drop] +item=Clue scroll, id=7241, option=[Read, null, null, null, drop] +item=Casket, id=7242, option=[Open, null, null, null, drop] +item=Clue scroll, id=7243, option=[Read, null, null, null, drop] +item=Casket, id=7244, option=[Open, null, null, null, drop] +item=Clue scroll, id=7245, option=[Read, null, null, null, drop] +item=Casket, id=7246, option=[Open, null, null, null, drop] +item=Clue scroll, id=7247, option=[Read, null, null, null, drop] +item=Clue scroll, id=7248, option=[Read, null, null, null, drop] +item=Clue scroll, id=7249, option=[Read, null, null, null, drop] +item=Clue scroll, id=7250, option=[Read, null, null, null, drop] +item=Clue scroll, id=7251, option=[Read, null, null, null, drop] +item=Clue scroll, id=7252, option=[Read, null, null, null, drop] +item=Clue scroll, id=7253, option=[Read, null, null, null, drop] +item=Clue scroll, id=7254, option=[Read, null, null, null, drop] +item=Clue scroll, id=7255, option=[Read, null, null, null, drop] +item=Clue scroll, id=7256, option=[Read, null, null, null, drop] +item=Casket, id=7257, option=[Open, null, null, null, drop] +item=Clue scroll, id=7258, option=[Read, null, null, null, drop] +item=Casket, id=7259, option=[Open, null, null, null, drop] +item=Clue scroll, id=7260, option=[Read, null, null, null, drop] +item=Casket, id=7261, option=[Open, null, null, null, drop] +item=Clue scroll, id=7262, option=[Read, null, null, null, drop] +item=Casket, id=7263, option=[Open, null, null, null, drop] +item=Clue scroll, id=7264, option=[Read, null, null, null, drop] +item=Casket, id=7265, option=[Open, null, null, null, drop] +item=Clue scroll, id=7266, option=[Read, null, null, null, drop] +item=Casket, id=7267, option=[Open, null, null, null, drop] +item=Clue scroll, id=7268, option=[Read, null, null, null, drop] +item=Challenge scroll, id=7269, option=[Read, null, null, null, drop] +item=Clue scroll, id=7270, option=[Read, null, null, null, drop] +item=Challenge scroll, id=7271, option=[Read, null, null, null, drop] +item=Clue scroll, id=7272, option=[Read, null, null, null, drop] +item=Challenge scroll, id=7273, option=[Read, null, null, null, drop] +item=Clue scroll, id=7274, option=[Read, null, null, null, drop] +item=Challenge scroll, id=7275, option=[Read, null, null, null, drop] +item=Clue scroll, id=7276, option=[Read, null, null, null, drop] +item=Challenge scroll, id=7277, option=[Read, null, null, null, drop] +item=Clue scroll, id=7278, option=[Read, null, null, null, drop] +item=Challenge scroll, id=7279, option=[Read, null, null, null, drop] +item=Clue scroll, id=7280, option=[Read, null, null, null, drop] +item=Challenge scroll, id=7281, option=[Read, null, null, null, drop] +item=Clue scroll, id=7282, option=[Read, null, null, null, drop] +item=Challenge scroll, id=7283, option=[Read, null, null, null, drop] +item=Clue scroll, id=7284, option=[Read, null, null, null, drop] +item=Challenge scroll, id=7285, option=[Read, null, null, null, drop] +item=Clue scroll, id=7286, option=[Read, null, null, null, drop] +item=Casket, id=7287, option=[Open, null, null, null, drop] +item=Clue scroll, id=7288, option=[Read, null, null, null, drop] +item=Casket, id=7289, option=[Open, null, null, null, drop] +item=Clue scroll, id=7290, option=[Read, null, null, null, drop] +item=Casket, id=7291, option=[Open, null, null, null, drop] +item=Clue scroll, id=7292, option=[Read, null, null, null, drop] +item=Casket, id=7293, option=[Open, null, null, null, drop] +item=Clue scroll, id=7294, option=[Read, null, null, null, drop] +item=Casket, id=7295, option=[Open, null, null, null, drop] +item=Clue scroll, id=7296, option=[Read, null, null, null, drop] +item=Key, id=7297, option=[null, null, null, null, drop] +item=Clue scroll, id=7298, option=[Read, null, null, null, drop] +item=Key, id=7299, option=[null, null, null, null, drop] +item=Clue scroll, id=7300, option=[Read, null, null, null, drop] +item=Clue scroll, id=7301, option=[Read, null, null, null, drop] +item=Key, id=7302, option=[null, null, null, null, drop] +item=Clue scroll, id=7303, option=[Read, null, null, null, drop] +item=Clue scroll, id=7304, option=[Read, null, null, null, drop] +item=Clue scroll, id=7305, option=[Read, null, null, null, drop] +item=Casket, id=7306, option=[Open, null, null, null, drop] +item=Clue scroll, id=7307, option=[Read, null, null, null, drop] +item=Casket, id=7308, option=[Open, null, null, null, drop] +item=Clue scroll, id=7309, option=[Read, null, null, null, drop] +item=Casket, id=7310, option=[Open, null, null, null, drop] +item=Clue scroll, id=7311, option=[Read, null, null, null, drop] +item=Casket, id=7312, option=[Open, null, null, null, drop] +item=Clue scroll, id=7313, option=[Read, null, null, null, drop] +item=Casket, id=7314, option=[Open, null, null, null, drop] +item=Clue scroll, id=7315, option=[Read, null, null, null, drop] +item=Casket, id=7316, option=[Open, null, null, null, drop] +item=Clue scroll, id=7317, option=[Read, null, null, null, drop] +item=Casket, id=7318, option=[Open, null, null, null, drop] +item=Red boater, id=7319, option=[null, Wear, null, null, drop] +item=Red boater, id=7320, option=[null, null, null, null, drop] +item=Orange boater, id=7321, option=[null, Wear, null, null, drop] +item=Orange boater, id=7322, option=[null, null, null, null, drop] +item=Green boater, id=7323, option=[null, Wear, null, null, drop] +item=Green boater, id=7324, option=[null, null, null, null, drop] +item=Blue boater, id=7325, option=[null, Wear, null, null, drop] +item=Blue boater, id=7326, option=[null, null, null, null, drop] +item=Black boater, id=7327, option=[null, Wear, null, null, drop] +item=Black boater, id=7328, option=[null, null, null, null, drop] +item=Red firelighter, id=7329, option=[null, null, null, null, drop] +item=Green firelighter, id=7330, option=[null, null, null, null, drop] +item=Blue firelighter, id=7331, option=[null, null, null, null, drop] +item=Black shield(h1), id=7332, option=[null, Wear, null, null, drop] +item=Black shield(h1), id=7333, option=[null, null, null, null, drop] +item=Adamant shield(h1), id=7334, option=[null, Wear, null, null, drop] +item=Adamant shield(h1), id=7335, option=[null, null, null, null, drop] +item=Rune shield(h1), id=7336, option=[null, Wear, null, null, drop] +item=Rune shield(h1), id=7337, option=[null, null, null, null, drop] +item=Black shield(h2), id=7338, option=[null, Wear, null, null, drop] +item=Black shield(h2), id=7339, option=[null, null, null, null, drop] +item=Adamant shield(h2), id=7340, option=[null, Wear, null, null, drop] +item=Adamant shield(h2), id=7341, option=[null, null, null, null, drop] +item=Rune shield(h2), id=7342, option=[null, Wear, null, null, drop] +item=Rune shield(h2), id=7343, option=[null, null, null, null, drop] +item=Black shield(h3), id=7344, option=[null, Wear, null, null, drop] +item=Black shield(h3), id=7345, option=[null, null, null, null, drop] +item=Adamant shield(h3), id=7346, option=[null, Wear, null, null, drop] +item=Adamant shield(h3), id=7347, option=[null, null, null, null, drop] +item=Rune shield(h3), id=7348, option=[null, Wear, null, null, drop] +item=Rune shield(h3), id=7349, option=[null, null, null, null, drop] +item=Black shield(h4), id=7350, option=[null, Wear, null, null, drop] +item=Black shield(h4), id=7351, option=[null, null, null, null, drop] +item=Adamant shield(h4), id=7352, option=[null, Wear, null, null, drop] +item=Adamant shield(h4), id=7353, option=[null, null, null, null, drop] +item=Rune shield(h4), id=7354, option=[null, Wear, null, null, drop] +item=Rune shield(h4), id=7355, option=[null, null, null, null, drop] +item=Black shield(h5), id=7356, option=[null, Wear, null, null, drop] +item=Black shield(h5), id=7357, option=[null, null, null, null, drop] +item=Adamant shield(h5), id=7358, option=[null, Wear, null, null, drop] +item=Adamant shield(h5), id=7359, option=[null, null, null, null, drop] +item=Rune shield(h5), id=7360, option=[null, Wear, null, null, drop] +item=Rune shield(h5), id=7361, option=[null, null, null, null, drop] +item=Studded body (g), id=7362, option=[null, Wear, null, null, drop] +item=Studded body (g), id=7363, option=[null, null, null, null, drop] +item=Studded body (t), id=7364, option=[null, Wear, null, null, drop] +item=Studded body (t), id=7365, option=[null, null, null, null, drop] +item=Studded chaps (g), id=7366, option=[null, Wear, null, null, drop] +item=Studded chaps (g), id=7367, option=[null, null, null, null, drop] +item=Studded chaps (t), id=7368, option=[null, Wear, null, null, drop] +item=Studded chaps (t), id=7369, option=[null, null, null, null, drop] +item=D'hide body(g), id=7370, option=[null, Wear, null, null, drop] +item=D'hide body(g), id=7371, option=[null, null, null, null, drop] +item=D'hide body (t), id=7372, option=[null, Wear, null, null, drop] +item=D'hide body (t), id=7373, option=[null, null, null, null, drop] +item=D'hide body (g), id=7374, option=[null, Wear, null, null, drop] +item=D'hide body (g), id=7375, option=[null, null, null, null, drop] +item=D'hide body (t), id=7376, option=[null, Wear, null, null, drop] +item=D'hide body (t), id=7377, option=[null, null, null, null, drop] +item=D'hide chaps (g), id=7378, option=[null, Wear, null, null, drop] +item=D'hide chaps (g), id=7379, option=[null, null, null, null, drop] +item=D'hide chaps (t), id=7380, option=[null, Wear, null, null, drop] +item=D'hide chaps (t), id=7381, option=[null, null, null, null, drop] +item=D'hide chaps (g), id=7382, option=[null, Wear, null, null, drop] +item=D'hide chaps (g), id=7383, option=[null, null, null, null, drop] +item=D'hide chaps (t), id=7384, option=[null, Wear, null, null, drop] +item=D'hide chaps (t), id=7385, option=[null, null, null, null, drop] +item=Blue skirt (g), id=7386, option=[null, Wear, null, null, drop] +item=Blue skirt (g), id=7387, option=[null, null, null, null, drop] +item=Blue skirt (t), id=7388, option=[null, Wear, null, null, drop] +item=Blue skirt (t), id=7389, option=[null, null, null, null, drop] +item=Wizard robe (g), id=7390, option=[null, Wear, null, null, drop] +item=Wizard robe (g), id=7391, option=[null, null, null, null, drop] +item=Wizard robe (t), id=7392, option=[null, Wear, null, null, drop] +item=Wizard robe (t), id=7393, option=[null, null, null, null, drop] +item=Wizard hat (g), id=7394, option=[null, Wear, null, null, drop] +item=Wizard hat (g), id=7395, option=[null, null, null, null, drop] +item=Wizard hat (t), id=7396, option=[null, Wear, null, null, drop] +item=Wizard hat (t), id=7397, option=[null, null, null, null, drop] +item=Enchanted robe, id=7398, option=[null, Wear, null, null, drop] +item=Enchanted top, id=7399, option=[null, Wear, null, null, drop] +item=Enchanted hat, id=7400, option=[null, Wear, null, null, drop] +item=Enchanted robe, id=7401, option=[null, null, null, null, drop] +item=Enchanted top, id=7402, option=[null, null, null, null, drop] +item=Enchanted hat, id=7403, option=[null, null, null, null, drop] +item=Red logs, id=7404, option=[null, null, null, null, drop] +item=Green logs, id=7405, option=[null, null, null, null, drop] +item=Blue logs, id=7406, option=[null, null, null, null, drop] +item=Dragon 2h sword, id=7407, option=[null, null, null, null, drop] +item=Draynor skull, id=7408, option=[null, null, null, null, Destroy] +item=Magic secateurs, id=7409, option=[null, Wield, null, null, Destroy] +item=Queen's secateurs, id=7410, option=[null, null, null, null, Destroy] +item=Symptoms list, id=7411, option=[Read, null, null, null, Destroy] +item=null, id=7412, option=[null, null, null, null, drop] +item=Bird's nest, id=7413, option=[Search, null, null, null, drop] +item=Paddle, id=7414, option=[null, Wield, null, null, drop] +item=Paddle, id=7415, option=[null, null, null, null, drop] +item=Mole claw, id=7416, option=[null, null, null, null, drop] +item=Mole claw, id=7417, option=[null, null, null, null, drop] +item=Mole skin, id=7418, option=[null, null, null, null, drop] +item=Mole skin, id=7419, option=[null, null, null, null, drop] +item=Mutated zygomite, id=7420, option=[null, null, null, null, drop] +item=Fungicide spray 10, id=7421, option=[null, null, null, null, drop] +item=Fungicide spray 9, id=7422, option=[null, null, null, null, drop] +item=Fungicide spray 8, id=7423, option=[null, null, null, null, drop] +item=Fungicide spray 7, id=7424, option=[null, null, null, null, drop] +item=Fungicide spray 6, id=7425, option=[null, null, null, null, drop] +item=Fungicide spray 5, id=7426, option=[null, null, null, null, drop] +item=Fungicide spray 4, id=7427, option=[null, null, null, null, drop] +item=Fungicide spray 3, id=7428, option=[null, null, null, null, drop] +item=Fungicide spray 2, id=7429, option=[null, null, null, null, drop] +item=Fungicide spray 1, id=7430, option=[null, null, null, null, drop] +item=Fungicide spray 0, id=7431, option=[null, null, null, null, drop] +item=Fungicide, id=7432, option=[null, null, null, null, drop] +item=Wooden spoon, id=7433, option=[null, Wield, null, null, drop] +item=Wooden spoon, id=7434, option=[null, null, null, null, drop] +item=Egg whisk, id=7435, option=[null, Wield, null, null, drop] +item=Egg whisk, id=7436, option=[null, null, null, null, drop] +item=Spork, id=7437, option=[null, Wield, null, null, drop] +item=Spork, id=7438, option=[null, null, null, null, drop] +item=Spatula, id=7439, option=[null, Wield, null, null, drop] +item=Spatula, id=7440, option=[null, null, null, null, drop] +item=Frying pan, id=7441, option=[null, Wield, null, null, drop] +item=Frying pan, id=7442, option=[null, null, null, null, drop] +item=Skewer, id=7443, option=[null, Wield, null, null, drop] +item=Skewer, id=7444, option=[null, null, null, null, drop] +item=Rolling pin, id=7445, option=[null, Wield, null, null, drop] +item=Rolling pin, id=7446, option=[null, null, null, null, drop] +item=Kitchen knife, id=7447, option=[null, Wield, null, null, drop] +item=Kitchen knife, id=7448, option=[null, null, null, null, drop] +item=Meat tenderiser, id=7449, option=[null, Wield, null, null, drop] +item=Meat tenderiser, id=7450, option=[null, null, null, null, drop] +item=Cleaver, id=7451, option=[null, Wield, null, null, drop] +item=Cleaver, id=7452, option=[null, null, null, null, drop] +item=Gloves, id=7453, option=[null, Wear, null, null, drop] +item=Gloves, id=7454, option=[null, Wear, null, null, drop] +item=Gloves, id=7455, option=[null, Wear, null, null, drop] +item=Gloves, id=7456, option=[null, Wear, null, null, drop] +item=Gloves, id=7457, option=[null, Wear, null, null, drop] +item=Gloves, id=7458, option=[null, Wear, null, null, drop] +item=Gloves, id=7459, option=[null, Wear, null, null, drop] +item=Gloves, id=7460, option=[null, Wear, null, null, drop] +item=Gloves, id=7461, option=[null, Wear, null, null, drop] +item=Gloves, id=7462, option=[null, Wear, null, null, drop] +item=Cornflour, id=7463, option=[null, null, null, null, drop] +item=Book on chickens, id=7464, option=[Read, null, null, null, drop] +item=Vanilla pod, id=7465, option=[null, null, null, null, drop] +item=Cornflour, id=7466, option=[null, null, null, null, drop] +item=Whoopsie, id=7467, option=[null, null, null, null, drop] +item=Pot of cornflour, id=7468, option=[null, null, null, Empty, drop] +item=Whoopsie, id=7469, option=[null, null, null, null, drop] +item=Cornflour mixture, id=7470, option=[null, null, null, Empty, Destroy] +item=Milky mixture, id=7471, option=[null, null, null, Empty, Destroy] +item=Cinnamon, id=7472, option=[null, null, null, null, drop] +item=Brulee, id=7473, option=[null, null, null, Empty, Destroy] +item=Brulee, id=7474, option=[null, null, null, Empty, Destroy] +item=Brulee, id=7475, option=[null, null, null, Empty, Destroy] +item=Brulee supreme, id=7476, option=[null, null, null, Empty, Destroy] +item=Evil chicken's egg, id=7477, option=[null, null, null, null, Destroy] +item=Dragon token, id=7478, option=[Rub, null, null, null, Destroy] +item=Spicy stew, id=7479, option=[Eat, Smell, null, null, Destroy] +item=Red spice (4), id=7480, option=[null, null, null, null, drop] +item=Red spice (3), id=7481, option=[null, null, null, null, drop] +item=Red spice (2), id=7482, option=[null, null, null, null, drop] +item=Red spice (1), id=7483, option=[null, null, null, null, drop] +item=Orange spice (4), id=7484, option=[null, null, null, null, drop] +item=Orange spice (3), id=7485, option=[null, null, null, null, drop] +item=Orange spice (2), id=7486, option=[null, null, null, null, drop] +item=Orange spice (1), id=7487, option=[null, null, null, null, drop] +item=Brown spice (4), id=7488, option=[null, null, null, null, drop] +item=Brown spice (3), id=7489, option=[null, null, null, null, drop] +item=Brown spice (2), id=7490, option=[null, null, null, null, drop] +item=Brown spice (1), id=7491, option=[null, null, null, null, drop] +item=Yellow spice (4), id=7492, option=[null, null, null, null, drop] +item=Yellow spice (3), id=7493, option=[null, null, null, null, drop] +item=Yellow spice (2), id=7494, option=[null, null, null, null, drop] +item=Yellow spice (1), id=7495, option=[null, null, null, null, drop] +item=Empty spice shaker, id=7496, option=[null, null, null, null, drop] +item=Dirty blast, id=7497, option=[Drink, null, null, null, drop] +item=Antique lamp, id=7498, option=[Rub, null, null, null, Destroy] +item=Evil dave, id=7499, option=[null, null, null, null, drop] +item=Dwarf, id=7500, option=[null, null, null, null, drop] +item=Goblins, id=7501, option=[null, null, null, null, drop] +item=Lumbridge guide, id=7502, option=[null, null, null, null, drop] +item=Monkey, id=7503, option=[null, null, null, null, drop] +item=Osman, id=7504, option=[null, null, null, null, drop] +item=Pirate pete, id=7505, option=[null, null, null, null, drop] +item=Sir amik varze, id=7506, option=[null, null, null, null, drop] +item=Skrach, id=7507, option=[null, null, null, null, drop] +item=Asgoldian ale, id=7508, option=[Drink, null, null, null, drop] +item=Dwarven rock cake, id=7509, option=[Eat, null, null, null, drop] +item=Dwarven rock cake, id=7510, option=[Eat, null, null, null, drop] +item=Slop of compromise, id=7511, option=[null, null, null, null, drop] +item=Soggy bread, id=7512, option=[null, null, null, null, drop] +item=Spicy maggots, id=7513, option=[null, null, null, null, drop] +item=Dyed orange, id=7514, option=[null, null, null, null, drop] +item=Breadcrumbs, id=7515, option=[null, null, null, null, drop] +item=Kelp, id=7516, option=[null, null, null, null, drop] +item=Ground kelp, id=7517, option=[null, null, null, null, drop] +item=Crab meat, id=7518, option=[null, null, null, null, drop] +item=Crab meat, id=7519, option=[null, null, null, null, drop] +item=Burnt crab meat, id=7520, option=[null, null, null, null, drop] +item=Cooked crab meat, id=7521, option=[Eat, null, null, null, drop] +item=Cooked crab meat, id=7522, option=[null, null, null, null, drop] +item=Cooked crab meat, id=7523, option=[Eat, null, null, null, drop] +item=Cooked crab meat, id=7524, option=[Eat, null, null, null, drop] +item=Cooked crab meat, id=7525, option=[Eat, null, null, null, drop] +item=Cooked crab meat, id=7526, option=[Eat, null, null, null, drop] +item=Ground crab meat, id=7527, option=[null, null, null, null, drop] +item=Ground cod, id=7528, option=[null, null, null, null, drop] +item=Raw fishcake, id=7529, option=[null, null, null, null, drop] +item=Cooked fishcake, id=7530, option=[Eat, null, null, null, drop] +item=Burnt fishcake, id=7531, option=[null, null, null, null, drop] +item=Mudskipper hide, id=7532, option=[null, null, null, null, drop] +item=Rock, id=7533, option=[null, null, null, null, drop] +item=Fishbowl helmet, id=7534, option=[null, Wear, null, null, drop] +item=Diving apparatus, id=7535, option=[null, Wear, null, null, drop] +item=Fresh crab claw, id=7536, option=[null, null, null, null, drop] +item=Crab claw, id=7537, option=[null, Wear, null, null, drop] +item=Fresh crab shell, id=7538, option=[null, null, null, null, drop] +item=Crab helmet, id=7539, option=[null, Wear, null, null, drop] +item=Broken crab claw, id=7540, option=[null, null, null, null, drop] +item=Broken crab shell, id=7541, option=[null, null, null, null, drop] +item=Cake of guidance, id=7542, option=[null, null, null, null, Destroy] +item=Raw guide cake, id=7543, option=[null, null, null, null, Destroy] +item=Enchanted egg, id=7544, option=[null, null, null, null, Destroy] +item=Enchanted milk, id=7545, option=[null, null, null, null, Destroy] +item=Enchanted flour, id=7546, option=[null, null, null, null, Destroy] +item=Druid pouch, id=7547, option=[null, null, null, null, drop] +item=Potato seed, id=7548, option=[null, null, null, null, drop] +item=Potato seed, id=7549, option=[null, null, null, null, drop] +item=Onion seed, id=7550, option=[null, null, null, null, drop] +item=Onion seed, id=7551, option=[null, null, null, null, drop] +item=Mithril arrow, id=7552, option=[null, null, null, null, drop] +item=Mithril arrow, id=7553, option=[null, null, null, null, drop] +item=Fire rune, id=7554, option=[null, null, null, null, drop] +item=Fire rune, id=7555, option=[null, null, null, null, drop] +item=Water rune, id=7556, option=[null, null, null, null, drop] +item=Water rune, id=7557, option=[null, null, null, null, drop] +item=Air rune, id=7558, option=[null, null, null, null, drop] +item=Air rune, id=7559, option=[null, null, null, null, drop] +item=Chaos rune, id=7560, option=[null, null, null, null, drop] +item=Chaos rune, id=7561, option=[null, null, null, null, drop] +item=Tomato seed, id=7562, option=[null, null, null, null, drop] +item=Tomato seed, id=7563, option=[null, null, null, null, drop] +item=Balloon toad, id=7564, option=[Drop, null, null, Release-all, Release] +item=Balloon toad, id=7565, option=[Drop, null, null, Release-all, Release] +item=Raw jubbly, id=7566, option=[null, null, null, null, drop] +item=Raw jubbly, id=7567, option=[null, null, null, null, drop] +item=Cooked jubbly, id=7568, option=[Eat, null, null, null, drop] +item=Cooked jubbly, id=7569, option=[null, null, null, null, drop] +item=Burnt jubbly, id=7570, option=[null, null, null, null, drop] +item=Burnt jubbly, id=7571, option=[null, null, null, null, drop] +item=Red banana, id=7572, option=[Eat, null, null, null, drop] +item=Tchiki monkey nuts, id=7573, option=[Eat, null, null, null, drop] +item=Sliced red banana, id=7574, option=[Eat, null, null, null, drop] +item=Tchiki nut paste, id=7575, option=[Eat, null, null, null, drop] +item=Snake corpse, id=7576, option=[null, null, null, null, drop] +item=Raw stuffed snake, id=7577, option=[null, null, null, null, drop] +item=Odd stuffed snake, id=7578, option=[null, null, null, null, drop] +item=Stuffed snake, id=7579, option=[Eat, null, null, null, drop] +item=Snake over-cooked, id=7580, option=[null, null, null, null, drop] +item=Overgrown hellcat, id=7581, option=[null, null, null, null, drop] +item=Hell cat, id=7582, option=[null, null, null, null, drop] +item=Hell-kitten, id=7583, option=[null, null, null, null, drop] +item=Lazy hell cat, id=7584, option=[null, null, null, null, drop] +item=Wily hellcat, id=7585, option=[null, null, null, null, drop] +item=Dummy, id=7586, option=[null, null, null, null, drop] +item=Coffin, id=7587, option=[Check, null, null, null, drop] +item=Coffin, id=7588, option=[Check, null, null, null, drop] +item=Coffin, id=7589, option=[Check, null, null, null, drop] +item=Coffin, id=7590, option=[Check, null, null, null, drop] +item=Coffin, id=7591, option=[Check, null, null, null, drop] +item=Zombie shirt, id=7592, option=[null, Wear, null, null, drop] +item=Zombie trousers, id=7593, option=[null, Wear, null, null, drop] +item=Zombie mask, id=7594, option=[null, Wear, null, null, drop] +item=Zombie gloves, id=7595, option=[null, Wear, null, null, drop] +item=Zombie boots, id=7596, option=[null, Wear, null, null, drop] +item=Item, id=7597, option=[null, null, null, null, drop] +item=Item, id=7598, option=[null, null, null, null, drop] +item=Item, id=7599, option=[null, null, null, null, drop] +item=Item, id=7600, option=[null, null, null, null, drop] +item=Item, id=7601, option=[null, null, null, null, drop] +item=Item, id=7602, option=[null, null, null, null, drop] +item=Item, id=7603, option=[null, null, null, null, drop] +item=Item, id=7604, option=[null, null, null, null, drop] +item=Item, id=7605, option=[null, null, null, null, drop] +item=Item, id=7606, option=[null, null, null, null, drop] +item=Item, id=7607, option=[null, null, null, null, drop] +item=Item, id=7608, option=[null, null, null, null, drop] +item=Item, id=7609, option=[null, null, null, null, drop] +item=Item, id=7610, option=[null, null, null, null, drop] +item=Item, id=7611, option=[null, null, null, null, drop] +item=Item, id=7612, option=[null, null, null, null, drop] +item=Item, id=7613, option=[null, null, null, null, drop] +item=Item, id=7614, option=[null, null, null, null, drop] +item=Item, id=7615, option=[null, null, null, null, drop] +item=Item, id=7616, option=[null, null, null, null, drop] +item=Item, id=7617, option=[null, null, null, null, drop] +item=Item, id=7618, option=[null, null, null, null, drop] +item=null, id=7619, option=[null, null, null, null, drop] +item=Silvthrill rod, id=7620, option=[null, null, null, null, drop] +item=null, id=7621, option=[null, null, null, null, drop] +item=Bucket of rubble, id=7622, option=[null, null, null, Empty, drop] +item=Whoopsie, id=7623, option=[null, null, null, null, drop] +item=Bucket of rubble, id=7624, option=[null, null, null, Empty, drop] +item=Whoopsie, id=7625, option=[null, null, null, null, drop] +item=Bucket of rubble, id=7626, option=[null, null, null, Empty, drop] +item=Whoopsie, id=7627, option=[null, null, null, null, drop] +item=Plaster fragment, id=7628, option=[Read, null, null, null, Destroy] +item=Dusty scroll, id=7629, option=[Read, null, null, null, Destroy] +item=Crate, id=7630, option=[Search, null, null, null, Destroy] +item=Whoopsie, id=7631, option=[null, null, null, null, drop] +item=Temple library key, id=7632, option=[null, null, null, null, Destroy] +item=Ancient book, id=7633, option=[Read, null, null, null, Destroy] +item=Battered tome, id=7634, option=[Read, null, null, null, Destroy] +item=Leather book, id=7635, option=[Read, null, null, null, Destroy] +item=Rod dust, id=7636, option=[null, null, null, null, drop] +item=Silvthrill rod, id=7637, option=[Look-at, null, null, null, drop] +item=Silvthrill rod, id=7638, option=[Look-at, null, null, null, drop] +item=Rod of ivandis(10), id=7639, option=[null, Wield, null, null, drop] +item=Rod of ivandis(9), id=7640, option=[null, Wield, null, null, drop] +item=Rod of ivandis(8), id=7641, option=[null, Wield, null, null, drop] +item=Rod of ivandis(7), id=7642, option=[null, Wield, null, null, drop] +item=Rod of ivandis(6), id=7643, option=[null, Wield, null, null, drop] +item=Rod of ivandis(5), id=7644, option=[null, Wield, null, null, drop] +item=Rod of ivandis(4), id=7645, option=[null, Wield, null, null, drop] +item=Rod of ivandis(3), id=7646, option=[null, Wield, null, null, drop] +item=Rod of ivandis(2), id=7647, option=[null, Wield, null, null, drop] +item=Rod of ivandis(1), id=7648, option=[null, Wield, null, null, drop] +item=Rod clay mould, id=7649, option=[null, null, null, null, Destroy] +item=Silver dust, id=7650, option=[null, null, null, null, drop] +item=Silver dust, id=7651, option=[null, null, null, null, drop] +item=Guthix balance(unf), id=7652, option=[null, null, null, Empty, drop] +item=Guthix balance(unf), id=7653, option=[null, null, null, null, drop] +item=Guthix balance(unf), id=7654, option=[null, null, null, Empty, drop] +item=Guthix balance(unf), id=7655, option=[null, null, null, null, drop] +item=Guthix balance(unf), id=7656, option=[null, null, null, Empty, drop] +item=Guthix balance(unf), id=7657, option=[null, null, null, null, drop] +item=Guthix balance(unf), id=7658, option=[null, null, null, Empty, drop] +item=Guthix balance(unf), id=7659, option=[null, null, null, null, drop] +item=Guthix balance(4), id=7660, option=[null, null, null, Empty, drop] +item=Guthix balance(4), id=7661, option=[null, null, null, null, drop] +item=Guthix balance(3), id=7662, option=[null, null, null, Empty, drop] +item=Guthix balance(3), id=7663, option=[null, null, null, null, drop] +item=Guthix balance(2), id=7664, option=[null, null, null, Empty, drop] +item=Guthix balance(2), id=7665, option=[null, null, null, null, drop] +item=Guthix balance(1), id=7666, option=[null, null, null, Empty, drop] +item=Guthix balance(1), id=7667, option=[null, null, null, null, drop] +item=Gadderhammer, id=7668, option=[null, Wield, null, null, drop] +item=Gadderhammer, id=7669, option=[null, null, null, null, drop] +item=null, id=7670, option=[null, null, null, null, drop] +item=Boxing gloves, id=7671, option=[null, Wear, null, null, drop] +item=Whoopsie, id=7672, option=[Wear, null, null, null, drop] +item=Boxing gloves, id=7673, option=[null, Wear, null, null, drop] +item=Whoopsie, id=7674, option=[Wear, null, null, null, drop] +item=Wooden sword, id=7675, option=[null, Wield, null, null, drop] +item=Wooden shield, id=7676, option=[null, Wield, null, null, drop] +item=Treasure stone, id=7677, option=[Feel, null, null, null, drop] +item=Prize key, id=7678, option=[null, null, null, null, drop] +item=Pugel, id=7679, option=[null, null, null, null, drop] +item=Pugel, id=7680, option=[null, null, null, null, drop] +item=Game book, id=7681, option=[Read, null, null, null, drop] +item=Hoop, id=7682, option=[null, null, null, null, drop] +item=Hoop, id=7683, option=[null, null, null, null, drop] +item=Dart, id=7684, option=[null, null, null, null, drop] +item=Dart, id=7685, option=[null, null, null, null, drop] +item=Bow and arrow, id=7686, option=[null, null, null, null, drop] +item=Bow and arrow, id=7687, option=[null, null, null, null, drop] +item=Kettle, id=7688, option=[null, null, null, null, drop] +item=Kettle, id=7689, option=[null, null, null, null, drop] +item=Full kettle, id=7690, option=[null, null, null, null, drop] +item=Hot kettle, id=7691, option=[null, null, null, null, drop] +item=Pot of tea (4), id=7692, option=[null, null, null, Empty, drop] +item=Pot of tea (4), id=7693, option=[null, null, null, null, drop] +item=Pot of tea (3), id=7694, option=[null, null, null, Empty, drop] +item=Pot of tea (3), id=7695, option=[null, null, null, null, drop] +item=Pot of tea (2), id=7696, option=[null, null, null, Empty, drop] +item=Pot of tea (2), id=7697, option=[null, null, null, null, drop] +item=Pot of tea (1), id=7698, option=[null, null, null, Empty, drop] +item=Pot of tea (1), id=7699, option=[null, null, null, null, drop] +item=Teapot with leaves, id=7700, option=[null, null, null, null, drop] +item=Teapot with leaves, id=7701, option=[null, null, null, null, drop] +item=Teapot, id=7702, option=[null, null, null, null, drop] +item=Teapot, id=7703, option=[null, null, null, null, drop] +item=Pot of tea (4), id=7704, option=[null, null, null, Empty, drop] +item=Pot of tea (4), id=7705, option=[null, null, null, null, drop] +item=Pot of tea (3), id=7706, option=[null, null, null, Empty, drop] +item=Pot of tea (3), id=7707, option=[null, null, null, null, drop] +item=Pot of tea (2), id=7708, option=[null, null, null, Empty, drop] +item=Pot of tea (2), id=7709, option=[null, null, null, null, drop] +item=Pot of tea (1), id=7710, option=[null, null, null, Empty, drop] +item=Pot of tea (1), id=7711, option=[null, null, null, null, drop] +item=Teapot with leaves, id=7712, option=[null, null, null, null, drop] +item=Teapot with leaves, id=7713, option=[null, null, null, null, drop] +item=Teapot, id=7714, option=[null, null, null, null, drop] +item=Teapot, id=7715, option=[null, null, null, null, drop] +item=Pot of tea (4), id=7716, option=[null, null, null, Empty, drop] +item=Pot of tea (4), id=7717, option=[null, null, null, null, drop] +item=Pot of tea (3), id=7718, option=[null, null, null, Empty, drop] +item=Pot of tea (3), id=7719, option=[null, null, null, null, drop] +item=Pot of tea (2), id=7720, option=[null, null, null, Empty, drop] +item=Pot of tea (2), id=7721, option=[null, null, null, null, drop] +item=Pot of tea (1), id=7722, option=[null, null, null, Empty, drop] +item=Pot of tea (1), id=7723, option=[null, null, null, null, drop] +item=Teapot with leaves, id=7724, option=[null, null, null, null, drop] +item=Teapot with leaves, id=7725, option=[null, null, null, null, drop] +item=Teapot, id=7726, option=[null, null, null, null, drop] +item=Teapot, id=7727, option=[null, null, null, null, drop] +item=Empty cup, id=7728, option=[null, null, null, null, drop] +item=Empty cup, id=7729, option=[null, null, null, null, drop] +item=Cup of tea, id=7730, option=[null, Drink, Empty, null, drop] +item=Cup of tea, id=7731, option=[null, Drink, Empty, null, drop] +item=Porcelain cup, id=7732, option=[null, null, null, null, drop] +item=Cup of tea, id=7733, option=[null, Drink, Empty, null, drop] +item=Cup of tea, id=7734, option=[null, Drink, Empty, null, drop] +item=Porcelain cup, id=7735, option=[null, null, null, null, drop] +item=Cup of tea, id=7736, option=[null, Drink, Empty, null, drop] +item=Cup of tea, id=7737, option=[null, Drink, Empty, null, drop] +item=Tea leaves, id=7738, option=[null, null, null, null, drop] +item=Tea leaves, id=7739, option=[null, null, null, null, drop] +item=Beer, id=7740, option=[Drink, null, null, null, drop] +item=Beer, id=7741, option=[null, null, null, null, drop] +item=Beer glass, id=7742, option=[null, null, null, null, drop] +item=Beer glass, id=7743, option=[null, null, null, null, drop] +item=Asgarnian ale, id=7744, option=[Drink, null, null, null, drop] +item=Asgarnian ale, id=7745, option=[null, null, null, null, drop] +item=Greenman's ale, id=7746, option=[Drink, null, null, null, drop] +item=Greenman's ale, id=7747, option=[null, null, null, null, drop] +item=Dragon bitter, id=7748, option=[Drink, null, null, null, drop] +item=Dragon bitter, id=7749, option=[null, null, null, null, drop] +item=Moonlight mead, id=7750, option=[Drink, null, null, null, drop] +item=Moonlight mead, id=7751, option=[null, null, null, null, drop] +item=Cider, id=7752, option=[Drink, null, null, null, drop] +item=Cider, id=7753, option=[null, null, null, null, drop] +item=Chef's delight, id=7754, option=[Drink, null, null, null, drop] +item=Chef's delight, id=7755, option=[null, null, null, null, drop] +item=Paintbrush, id=7756, option=[null, null, null, null, drop] +item=Paintbrush, id=7757, option=[null, null, null, null, drop] +item=Rusty sword, id=7758, option=[null, null, null, null, drop] +item=Toy soldier, id=7759, option=[Wind, null, null, null, drop] +item=Toy soldier, id=7760, option=[null, null, null, null, drop] +item=Toy soldier (wound), id=7761, option=[null, null, null, null, Release] +item=Toy soldier (wound), id=7762, option=[null, null, null, null, drop] +item=Toy doll, id=7763, option=[Wind, null, null, null, drop] +item=Toy doll, id=7764, option=[null, null, null, null, drop] +item=Toy doll (wound), id=7765, option=[null, null, null, null, Release] +item=Toy doll (wound), id=7766, option=[null, null, null, null, drop] +item=Toy mouse, id=7767, option=[Wind, null, null, null, drop] +item=Toy mouse, id=7768, option=[null, null, null, null, drop] +item=Toy mouse (wound), id=7769, option=[null, null, null, null, Release] +item=Toy mouse (wound), id=7770, option=[null, null, null, null, drop] +item=Clockwork cat, id=7771, option=[null, null, null, null, Release] +item=Clockwork cat, id=7772, option=[null, null, null, null, drop] +item=Branch, id=7773, option=[null, null, null, null, drop] +item=Reward token, id=7774, option=[Look-at, null, null, null, Destroy] +item=Reward token, id=7775, option=[Look-at, null, null, null, Destroy] +item=Reward token, id=7776, option=[Look-at, null, null, null, Destroy] +item=Long vine, id=7777, option=[null, null, null, null, drop] +item=Short vine, id=7778, option=[null, null, null, null, drop] +item=Fishing tome, id=7779, option=[Read, null, null, null, drop] +item=Fishing tome, id=7780, option=[Read, null, null, null, drop] +item=Fishing tome, id=7781, option=[Read, null, null, null, drop] +item=Agility tome, id=7782, option=[Read, null, null, null, drop] +item=Agility tome, id=7783, option=[Read, null, null, null, drop] +item=Agility tome, id=7784, option=[Read, null, null, null, drop] +item=Thieving tome, id=7785, option=[Read, null, null, null, drop] +item=Thieving tome, id=7786, option=[Read, null, null, null, drop] +item=Thieving tome, id=7787, option=[Read, null, null, null, drop] +item=Slayer tome, id=7788, option=[Read, null, null, null, drop] +item=Slayer tome, id=7789, option=[Read, null, null, null, drop] +item=Slayer tome, id=7790, option=[Read, null, null, null, drop] +item=Mining tome, id=7791, option=[Read, null, null, null, drop] +item=Mining tome, id=7792, option=[Read, null, null, null, drop] +item=Mining tome, id=7793, option=[Read, null, null, null, drop] +item=Firemaking tome, id=7794, option=[Read, null, null, null, drop] +item=Firemaking tome, id=7795, option=[Read, null, null, null, drop] +item=Firemaking tome, id=7796, option=[Read, null, null, null, drop] +item=Woodcutting tome, id=7797, option=[Read, null, null, null, drop] +item=Woodcutting tome, id=7798, option=[Read, null, null, null, drop] +item=Woodcutting tome, id=7799, option=[Read, null, null, null, drop] +item=Snail shell, id=7800, option=[null, null, null, null, drop] +item=Snake hide, id=7801, option=[null, null, null, null, drop] +item=Snake hide, id=7802, option=[null, null, null, null, drop] +item=Yin yang amulet, id=7803, option=[null, Wear, null, null, drop] +item=Zaros mjolnir, id=7804, option=[null, Wield, null, null, drop] +item=Zaros mjolnir, id=7805, option=[null, null, null, null, drop] +item=Anger sword, id=7806, option=[null, Wield, null, null, drop] +item=Anger battleaxe, id=7807, option=[null, Wield, null, null, drop] +item=Anger mace, id=7808, option=[null, Wield, null, null, drop] +item=Anger spear, id=7809, option=[null, Wield, null, null, drop] +item=Jug of vinegar, id=7810, option=[null, null, null, Empty, drop] +item=Pot of vinegar, id=7811, option=[null, null, null, Empty, drop] +item=Goblin skull, id=7812, option=[null, null, null, null, drop] +item=Bone in vinegar, id=7813, option=[null, null, null, Empty, drop] +item=Goblin skull, id=7814, option=[null, null, null, null, drop] +item=Bear ribs, id=7815, option=[null, null, null, null, drop] +item=Bone in vinegar, id=7816, option=[null, null, null, Empty, drop] +item=Bear ribs, id=7817, option=[null, null, null, null, drop] +item=Ram skull, id=7818, option=[null, null, null, null, drop] +item=Bone in vinegar, id=7819, option=[null, null, null, Empty, drop] +item=Ram skull, id=7820, option=[null, null, null, null, drop] +item=Unicorn bone, id=7821, option=[null, null, null, null, drop] +item=Bone in vinegar, id=7822, option=[null, null, null, Empty, drop] +item=Unicorn bone, id=7823, option=[null, null, null, null, drop] +item=Giant rat bone, id=7824, option=[null, null, null, null, drop] +item=Bone in vinegar, id=7825, option=[null, null, null, Empty, drop] +item=Giant rat bone, id=7826, option=[null, null, null, null, drop] +item=Giant bat wing, id=7827, option=[null, null, null, null, drop] +item=Bone in vinegar, id=7828, option=[null, null, null, Empty, drop] +item=Giant bat wing, id=7829, option=[null, null, null, null, drop] +item=Wolf bone, id=7830, option=[null, null, null, null, drop] +item=Bone in vinegar, id=7831, option=[null, null, null, Empty, drop] +item=Wolf bone, id=7832, option=[null, null, null, null, drop] +item=Bat wing, id=7833, option=[null, null, null, null, drop] +item=Bone in vinegar, id=7834, option=[null, null, null, Empty, drop] +item=Bat wing, id=7835, option=[null, null, null, null, drop] +item=Rat bone, id=7836, option=[null, null, null, null, drop] +item=Bone in vinegar, id=7837, option=[null, null, null, Empty, drop] +item=Rat bone, id=7838, option=[null, null, null, null, drop] +item=Baby dragon bone, id=7839, option=[null, null, null, null, drop] +item=Bone in vinegar, id=7840, option=[null, null, null, Empty, drop] +item=Baby dragon bone, id=7841, option=[null, null, null, null, drop] +item=Ogre ribs, id=7842, option=[null, null, null, null, drop] +item=Bone in vinegar, id=7843, option=[null, null, null, Empty, drop] +item=Ogre ribs, id=7844, option=[null, null, null, null, drop] +item=Jogre bone, id=7845, option=[null, null, null, null, drop] +item=Bone in vinegar, id=7846, option=[null, null, null, Empty, drop] +item=Jogre bone, id=7847, option=[null, null, null, null, drop] +item=Zogre bone, id=7848, option=[null, null, null, null, drop] +item=Bone in vinegar, id=7849, option=[null, null, null, Empty, drop] +item=Zogre bone, id=7850, option=[null, null, null, null, drop] +item=Mogre bone, id=7851, option=[null, null, null, null, drop] +item=Bone in vinegar, id=7852, option=[null, null, null, Empty, drop] +item=Mogre bone, id=7853, option=[null, null, null, null, drop] +item=Monkey paw, id=7854, option=[null, null, null, null, drop] +item=Bone in vinegar, id=7855, option=[null, null, null, Empty, drop] +item=Monkey paw, id=7856, option=[null, null, null, null, drop] +item=Dagannoth ribs, id=7857, option=[null, null, null, null, drop] +item=Bone in vinegar, id=7858, option=[null, null, null, Empty, drop] +item=Dagannoth ribs, id=7859, option=[null, null, null, null, drop] +item=Snake spine, id=7860, option=[null, null, null, null, drop] +item=Bone in vinegar, id=7861, option=[null, null, null, Empty, drop] +item=Snake spine, id=7862, option=[null, null, null, null, drop] +item=Zombie bone, id=7863, option=[null, null, null, null, drop] +item=Bone in vinegar, id=7864, option=[null, null, null, Empty, drop] +item=Zombie bone, id=7865, option=[null, null, null, null, drop] +item=Werewolf bone, id=7866, option=[null, null, null, null, drop] +item=Bone in vinegar, id=7867, option=[null, null, null, Empty, drop] +item=Werewolf bone, id=7868, option=[null, null, null, null, drop] +item=Moss giant bone, id=7869, option=[null, null, null, null, drop] +item=Bone in vinegar, id=7870, option=[null, null, null, Empty, drop] +item=Moss giant bone, id=7871, option=[null, null, null, null, drop] +item=Fire giant bone, id=7872, option=[null, null, null, null, drop] +item=Bone in vinegar, id=7873, option=[null, null, null, Empty, drop] +item=Fire giant bone, id=7874, option=[null, null, null, null, drop] +item=Ice giant ribs, id=7875, option=[null, null, null, null, drop] +item=Bone in vinegar, id=7876, option=[null, null, null, Empty, drop] +item=Ice giant ribs, id=7877, option=[null, null, null, null, drop] +item=Terrorbird wing, id=7878, option=[null, null, null, null, drop] +item=Bone in vinegar, id=7879, option=[null, null, null, Empty, drop] +item=Terrorbird wing, id=7880, option=[null, null, null, null, drop] +item=Ghoul bone, id=7881, option=[null, null, null, null, drop] +item=Bone in vinegar, id=7882, option=[null, null, null, Empty, drop] +item=Ghoul bone, id=7883, option=[null, null, null, null, drop] +item=Troll bone, id=7884, option=[null, null, null, null, drop] +item=Bone in vinegar, id=7885, option=[null, null, null, Empty, drop] +item=Troll bone, id=7886, option=[null, null, null, null, drop] +item=Seagull wing, id=7887, option=[null, null, null, null, drop] +item=Bone in vinegar, id=7888, option=[null, null, null, Empty, drop] +item=Seagull wing, id=7889, option=[null, null, null, null, drop] +item=Undead cow ribs, id=7890, option=[null, null, null, null, drop] +item=Bone in vinegar, id=7891, option=[null, null, null, Empty, drop] +item=Undead cow ribs, id=7892, option=[null, null, null, null, drop] +item=Experiment bone, id=7893, option=[null, null, null, null, drop] +item=Bone in vinegar, id=7894, option=[null, null, null, Empty, drop] +item=Experiment bone, id=7895, option=[null, null, null, null, drop] +item=Rabbit bone, id=7896, option=[null, null, null, null, drop] +item=Bone in vinegar, id=7897, option=[null, null, null, Empty, drop] +item=Rabbit bone, id=7898, option=[null, null, null, null, drop] +item=Basilisk bone, id=7899, option=[null, null, null, null, drop] +item=Bone in vinegar, id=7900, option=[null, null, null, Empty, drop] +item=Basilisk bone, id=7901, option=[null, null, null, null, drop] +item=Desert lizard bone, id=7902, option=[null, null, null, null, drop] +item=Bone in vinegar, id=7903, option=[null, null, null, Empty, drop] +item=Desert lizard bone, id=7904, option=[null, null, null, null, drop] +item=Cave goblin skull, id=7905, option=[null, null, null, null, drop] +item=Bone in vinegar, id=7906, option=[null, null, null, Empty, drop] +item=Cave goblin skull, id=7907, option=[null, null, null, null, drop] +item=Big frog leg, id=7908, option=[null, null, null, null, drop] +item=Bone in vinegar, id=7909, option=[null, null, null, Empty, drop] +item=Big frog leg, id=7910, option=[null, null, null, null, drop] +item=Vulture wing, id=7911, option=[null, null, null, null, drop] +item=Bone in vinegar, id=7912, option=[null, null, null, Empty, drop] +item=Vulture wing, id=7913, option=[null, null, null, null, drop] +item=Jackal bone, id=7914, option=[null, null, null, null, drop] +item=Bone in vinegar, id=7915, option=[null, null, null, Empty, drop] +item=Jackal bone, id=7916, option=[null, null, null, null, drop] +item=Ram skull helm, id=7917, option=[null, Wear, null, null, drop] +item=Bonesack, id=7918, option=[null, Wear, null, null, drop] +item=Bottle of wine, id=7919, option=[Drink, null, null, null, drop] +item=Bottle of wine, id=7920, option=[null, null, null, null, drop] +item=Empty wine bottle, id=7921, option=[null, null, null, null, drop] +item=Al kharid flyer, id=7922, option=[Read, null, null, null, drop] +item=null, id=7923, option=[null, null, null, null, drop] +item=null, id=7924, option=[null, null, null, null, drop] +item=null, id=7925, option=[null, null, null, null, drop] +item=null, id=7926, option=[null, null, null, null, drop] +item=Easter ring, id=7927, option=[null, Wear, null, null, drop] +item=Easter egg, id=7928, option=[Eat, null, null, null, drop] +item=Easter egg, id=7929, option=[Eat, null, null, null, drop] +item=Easter egg, id=7930, option=[Eat, null, null, null, drop] +item=Easter egg, id=7931, option=[Eat, null, null, null, drop] +item=Easter egg, id=7932, option=[Eat, null, null, null, drop] +item=Easter egg, id=7933, option=[Eat, null, null, null, drop] +item=Field ration, id=7934, option=[Eat, null, null, null, drop] +item=Field ration, id=7935, option=[null, null, null, null, drop] +item=Pure essence, id=7936, option=[null, null, null, null, drop] +item=Pure essence, id=7937, option=[null, null, null, null, drop] +item=Bob, id=7938, option=[null, null, null, null, drop] +item=Tortoise shell, id=7939, option=[null, null, null, null, drop] +item=Tortoise shell, id=7940, option=[null, null, null, null, drop] +item=Iron sheet, id=7941, option=[null, null, null, null, drop] +item=Fresh monkfish, id=7942, option=[null, null, null, null, drop] +item=Fresh monkfish, id=7943, option=[Eat, null, null, null, drop] +item=Raw monkfish, id=7944, option=[null, null, null, null, drop] +item=Raw monkfish, id=7945, option=[null, null, null, null, drop] +item=Monkfish, id=7946, option=[Eat, null, null, null, drop] +item=Monkfish, id=7947, option=[null, null, null, null, drop] +item=Burnt monkfish, id=7948, option=[null, null, null, null, drop] +item=Burnt monkfish, id=7949, option=[null, null, null, null, drop] +item=Bone seeds, id=7950, option=[null, null, null, Open, drop] +item=Herman's book, id=7951, option=[Read, null, null, null, drop] +item=Axe handle, id=7952, option=[null, Wield, null, null, drop] +item=Axe handle, id=7953, option=[null, null, null, null, drop] +item=Burnt shrimp, id=7954, option=[null, null, null, null, drop] +item=Burnt shrimp, id=7955, option=[null, null, null, null, drop] +item=Casket, id=7956, option=[Open, null, null, null, drop] +item=White apron, id=7957, option=[null, null, null, null, drop] +item=Mining prop, id=7958, option=[null, null, null, null, Destroy] +item=Heavy box, id=7959, option=[null, null, null, null, Destroy] +item=Empty box, id=7960, option=[null, null, null, null, drop] +item=Burnt diary, id=7961, option=[Read, null, null, null, drop] +item=Burnt diary, id=7962, option=[Read, null, null, null, drop] +item=Burnt diary, id=7963, option=[Read, null, null, null, drop] +item=Burnt diary, id=7964, option=[Read, null, null, null, drop] +item=Burnt diary, id=7965, option=[Read, null, null, null, drop] +item=Letter, id=7966, option=[Read, null, null, null, Destroy] +item=Engine, id=7967, option=[null, null, null, null, drop] +item=Scroll, id=7968, option=[Read, null, null, null, Destroy] +item=Pulley beam, id=7969, option=[null, null, null, null, drop] +item=Long pulley beam, id=7970, option=[null, null, null, null, drop] +item=Longer pulley beam, id=7971, option=[null, null, null, null, drop] +item=Lift manual, id=7972, option=[Read, null, null, null, drop] +item=Beam, id=7973, option=[null, null, null, null, drop] +item=Servant bell, id=7974, option=[Ring, null, null, null, drop] +item=Crawling hand, id=7975, option=[null, null, null, null, drop] +item=Cockatrice head, id=7976, option=[null, null, null, null, drop] +item=Basilisk head, id=7977, option=[null, null, null, null, drop] +item=Kurask head, id=7978, option=[null, null, null, null, drop] +item=Abyssal head, id=7979, option=[null, null, null, null, drop] +item=Kbd heads, id=7980, option=[null, null, null, null, drop] +item=Kq head, id=7981, option=[null, null, null, null, drop] +item=Crawling hand, id=7982, option=[null, null, null, null, drop] +item=Cockatrice head, id=7983, option=[null, null, null, null, drop] +item=Basilisk head, id=7984, option=[null, null, null, null, drop] +item=Kurask head, id=7985, option=[null, null, null, null, drop] +item=Abyssal head, id=7986, option=[null, null, null, null, drop] +item=Kbd heads, id=7987, option=[null, null, null, null, drop] +item=Kq head, id=7988, option=[null, null, null, null, drop] +item=Big bass, id=7989, option=[null, null, null, null, drop] +item=Big bass, id=7990, option=[null, null, null, null, drop] +item=Big swordfish, id=7991, option=[null, null, null, null, drop] +item=Big swordfish, id=7992, option=[null, null, null, null, drop] +item=Big shark, id=7993, option=[null, null, null, null, drop] +item=Big shark, id=7994, option=[null, null, null, null, drop] +item=Arthur portrait, id=7995, option=[null, null, null, null, drop] +item=Elena portrait, id=7996, option=[null, null, null, null, drop] +item=Keldagrim portrait, id=7997, option=[null, null, null, null, drop] +item=Misc. portrait, id=7998, option=[null, null, null, null, drop] +item=Desert painting, id=7999, option=[null, null, null, null, drop] +item=Isafdar painting, id=8000, option=[null, null, null, null, drop] +item=Karamja painting, id=8001, option=[null, null, null, null, drop] +item=Lumbridge painting, id=8002, option=[null, null, null, null, drop] +item=Morytania painting, id=8003, option=[null, null, null, null, drop] +item=Small map, id=8004, option=[null, null, null, null, drop] +item=Medium map, id=8005, option=[null, null, null, null, drop] +item=Large map, id=8006, option=[null, null, null, null, drop] +item=Varrock teleport, id=8007, option=[Break, null, null, null, drop] +item=Lumbridge teleport, id=8008, option=[Break, null, null, null, drop] +item=Falador teleport, id=8009, option=[Break, null, null, null, drop] +item=Camelot teleport, id=8010, option=[Break, null, null, null, drop] +item=Ardougne teleport, id=8011, option=[Break, null, null, null, drop] +item=Watchtower t'port, id=8012, option=[Break, null, null, null, drop] +item=Teleport to house, id=8013, option=[Break, null, null, null, drop] +item=Bones to bananas, id=8014, option=[Break, null, null, null, drop] +item=Bones to peaches, id=8015, option=[Break, null, null, null, drop] +item=Enchant sapphire, id=8016, option=[Break, null, null, null, drop] +item=Enchant emerald, id=8017, option=[Break, null, null, null, drop] +item=Enchant ruby, id=8018, option=[Break, null, null, null, drop] +item=Enchant diamond, id=8019, option=[Break, null, null, null, drop] +item=Enchant dragonstn., id=8020, option=[Break, null, null, null, drop] +item=Enchant onyx, id=8021, option=[Break, null, null, null, drop] +item=Telekinetic grab, id=8022, option=[Break, null, null, null, drop] +item=Boxing ring, id=8023, option=[null, null, null, null, drop] +item=Fencing ring, id=8024, option=[null, null, null, null, drop] +item=Combat ring, id=8025, option=[null, null, null, null, drop] +item=Ranging pedestals, id=8026, option=[null, null, null, null, drop] +item=Balance beam, id=8027, option=[null, null, null, null, drop] +item=Glove rack, id=8028, option=[null, null, null, null, drop] +item=Weapons rack, id=8029, option=[null, null, null, null, drop] +item=Extra weapons rack, id=8030, option=[null, null, null, null, drop] +item=Wooden bed, id=8031, option=[null, null, null, null, drop] +item=Oak bed, id=8032, option=[null, null, null, null, drop] +item=Large oak bed, id=8033, option=[null, null, null, null, drop] +item=Teak bed, id=8034, option=[null, null, null, null, drop] +item=Large teak bed, id=8035, option=[null, null, null, null, drop] +item=4-poster, id=8036, option=[null, null, null, null, drop] +item=Gilded 4-poster, id=8037, option=[null, null, null, null, drop] +item=Shoe box, id=8038, option=[null, null, null, null, drop] +item=Oak drawers, id=8039, option=[null, null, null, null, drop] +item=Oak wardrobe, id=8040, option=[null, null, null, null, drop] +item=Teak drawers, id=8041, option=[null, null, null, null, drop] +item=Teak wardrobe, id=8042, option=[null, null, null, null, drop] +item=Mahogany 'drobe, id=8043, option=[null, null, null, null, drop] +item=Gilded wardrobe, id=8044, option=[null, null, null, null, drop] +item=Shaving stand, id=8045, option=[null, null, null, null, drop] +item=Oak shaving stand, id=8046, option=[null, null, null, null, drop] +item=Oak dresser, id=8047, option=[null, null, null, null, drop] +item=Teak dresser, id=8048, option=[null, null, null, null, drop] +item=Fancy teak dresser, id=8049, option=[null, null, null, null, drop] +item=Mahogany dresser, id=8050, option=[null, null, null, null, drop] +item=Gilded dresser, id=8051, option=[null, null, null, null, drop] +item=Oak clock, id=8052, option=[null, null, null, null, drop] +item=Teak clock, id=8053, option=[null, null, null, null, drop] +item=Gilded clock, id=8054, option=[null, null, null, null, drop] +item=Saradomin symbol, id=8055, option=[null, null, null, null, drop] +item=Zamorak symbol, id=8056, option=[null, null, null, null, drop] +item=Guthix symbol, id=8057, option=[null, null, null, null, drop] +item=Saradomin icon, id=8058, option=[null, null, null, null, drop] +item=Zamorak icon, id=8059, option=[null, null, null, null, drop] +item=Guthix icon, id=8060, option=[null, null, null, null, drop] +item=Icon of bob, id=8061, option=[null, null, null, null, drop] +item=Oak altar, id=8062, option=[null, null, null, null, drop] +item=Teak altar, id=8063, option=[null, null, null, null, drop] +item=Cloth-cover'd altar, id=8064, option=[null, null, null, null, drop] +item=Mahogany altar, id=8065, option=[null, null, null, null, drop] +item=Limestone altar, id=8066, option=[null, null, null, null, drop] +item=Marble altar, id=8067, option=[null, null, null, null, drop] +item=Gilded altar, id=8068, option=[null, null, null, null, drop] +item=Wooden torches, id=8069, option=[null, null, null, null, drop] +item=Steel torches, id=8070, option=[null, null, null, null, drop] +item=Steel candlesticks, id=8071, option=[null, null, null, null, drop] +item=Gold candlesticks, id=8072, option=[null, null, null, null, drop] +item=Incense burners, id=8073, option=[null, null, null, null, drop] +item=Mahogany burners, id=8074, option=[null, null, null, null, drop] +item=Marble burners, id=8075, option=[null, null, null, null, drop] +item=Shuttered window, id=8076, option=[null, null, null, null, drop] +item=Decorative window, id=8077, option=[null, null, null, null, drop] +item=Stained glass, id=8078, option=[null, null, null, null, drop] +item=Windchimes, id=8079, option=[null, null, null, null, drop] +item=Bells, id=8080, option=[null, null, null, null, drop] +item=Organ, id=8081, option=[null, null, null, null, drop] +item=Small statues, id=8082, option=[null, null, null, null, drop] +item=Medium statues, id=8083, option=[null, null, null, null, drop] +item=Large statues, id=8084, option=[null, null, null, null, drop] +item=Suit of armour, id=8085, option=[null, null, null, null, drop] +item=Small portrait, id=8086, option=[null, null, null, null, drop] +item=Minor head, id=8087, option=[null, null, null, null, drop] +item=Medium head, id=8088, option=[null, null, null, null, drop] +item=Major head, id=8089, option=[null, null, null, null, drop] +item=Mounted sword, id=8090, option=[null, null, null, null, drop] +item=Small landscape, id=8091, option=[null, null, null, null, drop] +item=Guild trophy, id=8092, option=[null, null, null, null, drop] +item=Large portrait, id=8093, option=[null, null, null, null, drop] +item=Large landscape, id=8094, option=[null, null, null, null, drop] +item=Rune display case, id=8095, option=[null, null, null, null, drop] +item=Low-level plants, id=8096, option=[null, null, null, null, drop] +item=Mid-level plants, id=8097, option=[null, null, null, null, drop] +item=High-level plants, id=8098, option=[null, null, null, null, drop] +item=Rope bell-pull, id=8099, option=[null, null, null, null, drop] +item=Bell-pull, id=8100, option=[null, null, null, null, drop] +item=Posh bell-pull, id=8101, option=[null, null, null, null, drop] +item=Oak decoration, id=8102, option=[null, null, null, null, drop] +item=Teak decoration, id=8103, option=[null, null, null, null, drop] +item=Gilded decoration, id=8104, option=[null, null, null, null, drop] +item=Round shield, id=8105, option=[null, null, null, null, drop] +item=Square shield, id=8106, option=[null, null, null, null, drop] +item=Kite shield, id=8107, option=[null, null, null, null, drop] +item=Wooden bench, id=8108, option=[null, null, null, null, drop] +item=Oak bench, id=8109, option=[null, null, null, null, drop] +item=Carved oak bench, id=8110, option=[null, null, null, null, drop] +item=Teak dining bench, id=8111, option=[null, null, null, null, drop] +item=Carved teak bench, id=8112, option=[null, null, null, null, drop] +item=Mahogany bench, id=8113, option=[null, null, null, null, drop] +item=Gilded bench, id=8114, option=[null, null, null, null, drop] +item=Wood dining table, id=8115, option=[null, null, null, null, drop] +item=Oak dining table, id=8116, option=[null, null, null, null, drop] +item=Carved oak table, id=8117, option=[null, null, null, null, drop] +item=Teak table, id=8118, option=[null, null, null, null, drop] +item=Carved teak table, id=8119, option=[null, null, null, null, drop] +item=Mahogany table, id=8120, option=[null, null, null, null, drop] +item=Opulent table, id=8121, option=[null, null, null, null, drop] +item=Oak door, id=8122, option=[null, null, null, null, drop] +item=Steel-plated door, id=8123, option=[null, null, null, null, drop] +item=Marble door, id=8124, option=[null, null, null, null, drop] +item=Decorative blood, id=8125, option=[null, null, null, null, drop] +item=Decorative pipe, id=8126, option=[null, null, null, null, drop] +item=Hanging skeleton, id=8127, option=[null, null, null, null, drop] +item=Candles, id=8128, option=[null, null, null, null, drop] +item=Torches, id=8129, option=[null, null, null, null, drop] +item=Skull torches, id=8130, option=[null, null, null, null, drop] +item=Skeleton guard, id=8131, option=[null, null, null, null, drop] +item=Guard dog, id=8132, option=[null, null, null, null, drop] +item=Hobgoblin guard, id=8133, option=[null, null, null, null, drop] +item=Baby red dragon, id=8134, option=[null, null, null, null, drop] +item=Huge spider, id=8135, option=[null, null, null, null, drop] +item=Troll guard, id=8136, option=[null, null, null, null, drop] +item=Hellhound, id=8137, option=[null, null, null, null, drop] +item=Demon, id=8138, option=[null, null, null, null, drop] +item=Kalphite soldier, id=8139, option=[null, null, null, null, drop] +item=Tok-xil, id=8140, option=[null, null, null, null, drop] +item=Dagannoth, id=8141, option=[null, null, null, null, drop] +item=Steel dragon, id=8142, option=[null, null, null, null, drop] +item=Spike trap, id=8143, option=[null, null, null, null, drop] +item=Man trap, id=8144, option=[null, null, null, null, drop] +item=Tangle vine, id=8145, option=[null, null, null, null, drop] +item=Marble trap, id=8146, option=[null, null, null, null, drop] +item=Teleport trap, id=8147, option=[null, null, null, null, drop] +item=Wooden crate, id=8148, option=[null, null, null, null, drop] +item=Oak chest, id=8149, option=[null, null, null, null, drop] +item=Teak chest, id=8150, option=[null, null, null, null, drop] +item=Mahogany chest, id=8151, option=[null, null, null, null, drop] +item=Magic chest, id=8152, option=[null, null, null, null, drop] +item=Clay attack stone, id=8153, option=[null, null, null, null, drop] +item=Attack stone, id=8154, option=[null, null, null, null, drop] +item=Marble att. stone, id=8155, option=[null, null, null, null, drop] +item=Magical balance 1, id=8156, option=[null, null, null, null, drop] +item=Magical balance 2, id=8157, option=[null, null, null, null, drop] +item=Magical balance 3, id=8158, option=[null, null, null, null, drop] +item=Jester, id=8159, option=[null, null, null, null, drop] +item=Treasure hunt, id=8160, option=[null, null, null, null, drop] +item=Hangman game, id=8161, option=[null, null, null, null, drop] +item=Hoop and stick, id=8162, option=[null, null, null, null, drop] +item=Dartboard, id=8163, option=[null, null, null, null, drop] +item=Archery target, id=8164, option=[null, null, null, null, drop] +item=Oak prize chest, id=8165, option=[null, null, null, null, drop] +item=Teak prize chest, id=8166, option=[null, null, null, null, drop] +item=Mahogany chest, id=8167, option=[null, null, null, null, drop] +item=Exit portal, id=8168, option=[null, null, null, null, drop] +item=Decorative rock, id=8169, option=[null, null, null, null, drop] +item=Pond, id=8170, option=[null, null, null, null, drop] +item=Imp statue, id=8171, option=[null, null, null, null, drop] +item=Dungeon entrance, id=8172, option=[null, null, null, null, drop] +item=Tree, id=8173, option=[null, null, null, null, drop] +item=Nice tree, id=8174, option=[null, null, null, null, drop] +item=Oak tree, id=8175, option=[null, null, null, null, drop] +item=Willow tree, id=8176, option=[null, null, null, null, drop] +item=Maple tree, id=8177, option=[null, null, null, null, drop] +item=Yew tree, id=8178, option=[null, null, null, null, drop] +item=Magic tree, id=8179, option=[null, null, null, null, drop] +item=Plant, id=8180, option=[null, null, null, null, drop] +item=Small fern, id=8181, option=[null, null, null, null, drop] +item=Fern, id=8182, option=[null, null, null, null, drop] +item=Dock leaf, id=8183, option=[null, null, null, null, drop] +item=Thistle, id=8184, option=[null, null, null, null, drop] +item=Reeds, id=8185, option=[null, null, null, null, drop] +item=Fern, id=8186, option=[null, null, null, null, drop] +item=Bush, id=8187, option=[null, null, null, null, drop] +item=Tall plant, id=8188, option=[null, null, null, null, drop] +item=Short plant, id=8189, option=[null, null, null, null, drop] +item=Large-leaf plant, id=8190, option=[null, null, null, null, drop] +item=Huge plant, id=8191, option=[null, null, null, null, drop] +item=Gazebo, id=8192, option=[null, null, null, null, drop] +item=Small fountain, id=8193, option=[null, null, null, null, drop] +item=Large fountain, id=8194, option=[null, null, null, null, drop] +item=Posh fountain, id=8195, option=[null, null, null, null, drop] +item=Boundary stones, id=8196, option=[null, null, null, null, drop] +item=Wooden fence, id=8197, option=[null, null, null, null, drop] +item=Stone wall, id=8198, option=[null, null, null, null, drop] +item=Iron railings, id=8199, option=[null, null, null, null, drop] +item=Picket fence, id=8200, option=[null, null, null, null, drop] +item=Garden fence, id=8201, option=[null, null, null, null, drop] +item=Marble wall, id=8202, option=[null, null, null, null, drop] +item=Thorny hedge, id=8203, option=[null, null, null, null, drop] +item=Nice hedge, id=8204, option=[null, null, null, null, drop] +item=Small box hedge, id=8205, option=[null, null, null, null, drop] +item=Topiary hedge, id=8206, option=[null, null, null, null, drop] +item=Fancy hedge, id=8207, option=[null, null, null, null, drop] +item=Tall fancy hedge, id=8208, option=[null, null, null, null, drop] +item=Tall box hedge, id=8209, option=[null, null, null, null, drop] +item=Rosemary, id=8210, option=[null, null, null, null, drop] +item=Daffodils, id=8211, option=[null, null, null, null, drop] +item=Bluebells, id=8212, option=[null, null, null, null, drop] +item=Sunflower, id=8213, option=[null, null, null, null, drop] +item=Marigolds, id=8214, option=[null, null, null, null, drop] +item=Roses, id=8215, option=[null, null, null, null, drop] +item=Firepit, id=8216, option=[null, null, null, null, drop] +item=Firepit with hook, id=8217, option=[null, null, null, null, drop] +item=Firepit with pot, id=8218, option=[null, null, null, null, drop] +item=Small oven, id=8219, option=[null, null, null, null, drop] +item=Large oven, id=8220, option=[null, null, null, null, drop] +item=Steel range, id=8221, option=[null, null, null, null, drop] +item=Fancy range, id=8222, option=[null, null, null, null, drop] +item=Wooden shelves 1, id=8223, option=[null, null, null, null, drop] +item=Wooden shelves 2, id=8224, option=[null, null, null, null, drop] +item=Wooden shelves 3, id=8225, option=[null, null, null, null, drop] +item=Oak shelves 1, id=8226, option=[null, null, null, null, drop] +item=Oak shelves 2, id=8227, option=[null, null, null, null, drop] +item=Teak shelves 1, id=8228, option=[null, null, null, null, drop] +item=Teak shelves 2, id=8229, option=[null, null, null, null, drop] +item=Pump and drain, id=8230, option=[null, null, null, null, drop] +item=Pump and tub, id=8231, option=[null, null, null, null, drop] +item=Sink, id=8232, option=[null, null, null, null, drop] +item=Wooden larder, id=8233, option=[null, null, null, null, drop] +item=Oak larder, id=8234, option=[null, null, null, null, drop] +item=Teak larder, id=8235, option=[null, null, null, null, drop] +item=Cat blanket, id=8236, option=[null, null, null, null, drop] +item=Cat basket, id=8237, option=[null, null, null, null, drop] +item=Cushioned basket, id=8238, option=[null, null, null, null, drop] +item=Beer barrel, id=8239, option=[null, null, null, null, drop] +item=Cider barrel, id=8240, option=[null, null, null, null, drop] +item=Asgarnian ale, id=8241, option=[null, null, null, null, drop] +item=Greenman's ale, id=8242, option=[null, null, null, null, drop] +item=Dragon bitter, id=8243, option=[null, null, null, null, drop] +item=Chef's delight, id=8244, option=[null, null, null, null, drop] +item=Blank poh entity, id=8245, option=[null, null, null, null, drop] +item=Wood kitchen table, id=8246, option=[null, null, null, null, drop] +item=Oak kitchen table, id=8247, option=[null, null, null, null, drop] +item=Teak kitchen table, id=8248, option=[null, null, null, null, drop] +item=Oak staircase, id=8249, option=[null, null, null, null, drop] +item=Oak staircase, id=8250, option=[null, null, null, null, drop] +item=Oak staircase, id=8251, option=[null, null, null, null, drop] +item=Teak staircase, id=8252, option=[null, null, null, null, drop] +item=Teak staircase, id=8253, option=[null, null, null, null, drop] +item=Teak staircase, id=8254, option=[null, null, null, null, drop] +item=Marble staircase, id=8255, option=[null, null, null, null, drop] +item=Marble staircase, id=8256, option=[null, null, null, null, drop] +item=Marble staircase, id=8257, option=[null, null, null, null, drop] +item=Spiral staircase, id=8258, option=[null, null, null, null, drop] +item=Marble spiral, id=8259, option=[null, null, null, null, drop] +item=Crawling hand, id=8260, option=[null, null, null, null, drop] +item=Cockatrice head, id=8261, option=[null, null, null, null, drop] +item=Basilisk head, id=8262, option=[null, null, null, null, drop] +item=Kurask head, id=8263, option=[null, null, null, null, drop] +item=Abyssal head, id=8264, option=[null, null, null, null, drop] +item=Kbd heads, id=8265, option=[null, null, null, null, drop] +item=Kq head, id=8266, option=[null, null, null, null, drop] +item=Mounted bass, id=8267, option=[null, null, null, null, drop] +item=Mounted swordfish, id=8268, option=[null, null, null, null, drop] +item=Mounted shark, id=8269, option=[null, null, null, null, drop] +item=Mithril armour, id=8270, option=[null, null, null, null, drop] +item=Adamantite armour, id=8271, option=[null, null, null, null, drop] +item=Runite armour, id=8272, option=[null, null, null, null, drop] +item=Cw armour 1, id=8273, option=[null, null, null, null, drop] +item=Cw armour 2, id=8274, option=[null, null, null, null, drop] +item=Cw armour 3, id=8275, option=[null, null, null, null, drop] +item=Rune case 1, id=8276, option=[null, null, null, null, drop] +item=Rune case 2, id=8277, option=[null, null, null, null, drop] +item=Rune case 3, id=8278, option=[null, null, null, null, drop] +item=Silverlight, id=8279, option=[null, null, null, null, drop] +item=Excalibur, id=8280, option=[null, null, null, null, drop] +item=Darklight, id=8281, option=[null, null, null, null, drop] +item=Anti-dragon shield, id=8282, option=[null, null, null, null, drop] +item=Amulet of glory, id=8283, option=[null, null, null, null, drop] +item=Cape of legends, id=8284, option=[null, null, null, null, drop] +item=King arthur, id=8285, option=[null, null, null, null, drop] +item=Elena, id=8286, option=[null, null, null, null, drop] +item=Giant dwarf, id=8287, option=[null, null, null, null, drop] +item=Miscellanians, id=8288, option=[null, null, null, null, drop] +item=Lumbridge, id=8289, option=[null, null, null, null, drop] +item=The desert, id=8290, option=[null, null, null, null, drop] +item=Morytania, id=8291, option=[null, null, null, null, drop] +item=Karamja, id=8292, option=[null, null, null, null, drop] +item=Isafdar, id=8293, option=[null, null, null, null, drop] +item=Small map, id=8294, option=[null, null, null, null, drop] +item=Medium map, id=8295, option=[null, null, null, null, drop] +item=Large map, id=8296, option=[null, null, null, null, drop] +item=Oak cage, id=8297, option=[null, null, null, null, drop] +item=Oak and steel cage, id=8298, option=[null, null, null, null, drop] +item=Steel cage, id=8299, option=[null, null, null, null, drop] +item=Spiked cage, id=8300, option=[null, null, null, null, drop] +item=Bone cage, id=8301, option=[null, null, null, null, drop] +item=Spikes, id=8302, option=[null, null, null, null, drop] +item=Tentacle pool, id=8303, option=[null, null, null, null, drop] +item=Flame pit, id=8304, option=[null, null, null, null, drop] +item=Rocnar, id=8305, option=[null, null, null, null, drop] +item=Oak ladder, id=8306, option=[null, null, null, null, drop] +item=Teak ladder, id=8307, option=[null, null, null, null, drop] +item=Mahogany ladder, id=8308, option=[null, null, null, null, drop] +item=Crude wooden chair, id=8309, option=[null, null, null, null, drop] +item=Wooden chair, id=8310, option=[null, null, null, null, drop] +item=Rocking chair, id=8311, option=[null, null, null, null, drop] +item=Oak chair, id=8312, option=[null, null, null, null, drop] +item=Oak armchair, id=8313, option=[null, null, null, null, drop] +item=Teak armchair, id=8314, option=[null, null, null, null, drop] +item=Mahogany armchair, id=8315, option=[null, null, null, null, drop] +item=Brown rug, id=8316, option=[null, null, null, null, drop] +item=Rug, id=8317, option=[null, null, null, null, drop] +item=Opulent rug, id=8318, option=[null, null, null, null, drop] +item=Wooden bookcase, id=8319, option=[null, null, null, null, drop] +item=Oak bookcase, id=8320, option=[null, null, null, null, drop] +item=Mahogany b'kcase, id=8321, option=[null, null, null, null, drop] +item=Torn curtains, id=8322, option=[null, null, null, null, drop] +item=Curtains, id=8323, option=[null, null, null, null, drop] +item=Opulent curtains, id=8324, option=[null, null, null, null, drop] +item=Clay fireplace, id=8325, option=[null, null, null, null, drop] +item=Stone fireplace, id=8326, option=[null, null, null, null, drop] +item=Marble fireplace, id=8327, option=[null, null, null, null, drop] +item=Teak portal, id=8328, option=[null, null, null, null, drop] +item=Mahogany portal, id=8329, option=[null, null, null, null, drop] +item=Marble portal, id=8330, option=[null, null, null, null, drop] +item=Teleport focus, id=8331, option=[null, null, null, null, drop] +item=Greater focus, id=8332, option=[null, null, null, null, drop] +item=Scrying pool, id=8333, option=[null, null, null, null, drop] +item=Oak lectern, id=8334, option=[null, null, null, null, drop] +item=Eagle lectern, id=8335, option=[null, null, null, null, drop] +item=Demon lectern, id=8336, option=[null, null, null, null, drop] +item=Teak eagle lectern, id=8337, option=[null, null, null, null, drop] +item=Teak demon lectern, id=8338, option=[null, null, null, null, drop] +item=Mahogany eagle, id=8339, option=[null, null, null, null, drop] +item=Mahogany demon, id=8340, option=[null, null, null, null, drop] +item=Globe, id=8341, option=[null, null, null, null, drop] +item=Ornamental globe, id=8342, option=[null, null, null, null, drop] +item=Lunar globe, id=8343, option=[null, null, null, null, drop] +item=Celestial globe, id=8344, option=[null, null, null, null, drop] +item=Armillary sphere, id=8345, option=[null, null, null, null, drop] +item=Small orrery, id=8346, option=[null, null, null, null, drop] +item=Large orrery, id=8347, option=[null, null, null, null, drop] +item=Wooden telescope, id=8348, option=[null, null, null, null, drop] +item=Teak telescope, id=8349, option=[null, null, null, null, drop] +item=Mahogany 'scope, id=8350, option=[null, null, null, null, drop] +item=Crystal ball, id=8351, option=[null, null, null, null, drop] +item=Elemental sphere, id=8352, option=[null, null, null, null, drop] +item=Crystal of power, id=8353, option=[null, null, null, null, drop] +item=Alchemical chart, id=8354, option=[null, null, null, null, drop] +item=Astronomical chart, id=8355, option=[null, null, null, null, drop] +item=Infernal chart, id=8356, option=[null, null, null, null, drop] +item=Oak throne, id=8357, option=[null, null, null, null, drop] +item=Teak throne, id=8358, option=[null, null, null, null, drop] +item=Mahogany throne, id=8359, option=[null, null, null, null, drop] +item=Gilded throne, id=8360, option=[null, null, null, null, drop] +item=Skeleton throne, id=8361, option=[null, null, null, null, drop] +item=Crystal throne, id=8362, option=[null, null, null, null, drop] +item=Demonic throne, id=8363, option=[null, null, null, null, drop] +item=Oak lever, id=8364, option=[null, null, null, null, drop] +item=Teak lever, id=8365, option=[null, null, null, null, drop] +item=Mahogany lever, id=8366, option=[null, null, null, null, drop] +item=Trapdoor, id=8367, option=[null, null, null, null, drop] +item=Trapdoor, id=8368, option=[null, null, null, null, drop] +item=Trapdoor, id=8369, option=[null, null, null, null, drop] +item=Floor decoration, id=8370, option=[null, null, null, null, drop] +item=Steel cage, id=8371, option=[null, null, null, null, drop] +item=Trapdoor, id=8372, option=[null, null, null, null, drop] +item=Lesser magic cage, id=8373, option=[null, null, null, null, drop] +item=Greater magic cage, id=8374, option=[null, null, null, null, drop] +item=Wooden workbench, id=8375, option=[null, null, null, null, drop] +item=Oak workbench, id=8376, option=[null, null, null, null, drop] +item=Steel framed bench, id=8377, option=[null, null, null, null, drop] +item=Bench with vice, id=8378, option=[null, null, null, null, drop] +item=Bench with lathe, id=8379, option=[null, null, null, null, drop] +item=Crafting table 1, id=8380, option=[null, null, null, null, drop] +item=Crafting table 2, id=8381, option=[null, null, null, null, drop] +item=Crafting table 3, id=8382, option=[null, null, null, null, drop] +item=Crafting table 4, id=8383, option=[null, null, null, null, drop] +item=Tool store 1, id=8384, option=[null, null, null, null, drop] +item=Tool store 2, id=8385, option=[null, null, null, null, drop] +item=Tool store 3, id=8386, option=[null, null, null, null, drop] +item=Tool store 4, id=8387, option=[null, null, null, null, drop] +item=Tool store 5, id=8388, option=[null, null, null, null, drop] +item=Repair bench, id=8389, option=[null, null, null, null, drop] +item=Whetstone, id=8390, option=[null, null, null, null, drop] +item=Armour stand, id=8391, option=[null, null, null, null, drop] +item=Pluming stand, id=8392, option=[null, null, null, null, drop] +item=Shield easel, id=8393, option=[null, null, null, null, drop] +item=Banner easel, id=8394, option=[null, null, null, null, drop] +item=Parlour, id=8395, option=[null, null, null, null, drop] +item=Kitchen, id=8396, option=[null, null, null, null, drop] +item=Dining room, id=8397, option=[null, null, null, null, drop] +item=Bedroom, id=8398, option=[null, null, null, null, drop] +item=Games room, id=8399, option=[null, null, null, null, drop] +item=Combat room, id=8400, option=[null, null, null, null, drop] +item=Hall, id=8401, option=[null, null, null, null, drop] +item=Hall, id=8402, option=[null, null, null, null, drop] +item=Hall, id=8403, option=[null, null, null, null, drop] +item=Hall, id=8404, option=[null, null, null, null, drop] +item=Chapel, id=8405, option=[null, null, null, null, drop] +item=Workshop, id=8406, option=[null, null, null, null, drop] +item=Study, id=8407, option=[null, null, null, null, drop] +item=Portal chamber, id=8408, option=[null, null, null, null, drop] +item=Throne room, id=8409, option=[null, null, null, null, drop] +item=Oubliette, id=8410, option=[null, null, null, null, drop] +item=Dungeon corridor, id=8411, option=[null, null, null, null, drop] +item=Dungeon cross, id=8412, option=[null, null, null, null, drop] +item=Dungeon stairs, id=8413, option=[null, null, null, null, drop] +item=Treasure room, id=8414, option=[null, null, null, null, drop] +item=Garden, id=8415, option=[null, null, null, null, drop] +item=Formal garden, id=8416, option=[null, null, null, null, drop] +item=Bagged dead tree, id=8417, option=[null, null, null, null, drop] +item=Bagged dead tree, id=8418, option=[null, null, null, null, drop] +item=Bagged nice tree, id=8419, option=[null, null, null, null, drop] +item=Bagged nice tree, id=8420, option=[null, null, null, null, drop] +item=Bagged oak tree, id=8421, option=[null, null, null, null, drop] +item=Bagged oak tree, id=8422, option=[null, null, null, null, drop] +item=Bagged willow tree, id=8423, option=[null, null, null, null, drop] +item=Bagged willow tree, id=8424, option=[null, null, null, null, drop] +item=Bagged maple tree, id=8425, option=[null, null, null, null, drop] +item=Bagged maple tree, id=8426, option=[null, null, null, null, drop] +item=Bagged yew tree, id=8427, option=[null, null, null, null, drop] +item=Bagged yew tree, id=8428, option=[null, null, null, null, drop] +item=Bagged magic tree, id=8429, option=[null, null, null, null, drop] +item=Bagged magic tree, id=8430, option=[null, null, null, null, drop] +item=Bagged plant 1, id=8431, option=[null, null, null, null, drop] +item=Bagged plant 1, id=8432, option=[null, null, null, null, drop] +item=Bagged plant 2, id=8433, option=[null, null, null, null, drop] +item=Bagged plant 2, id=8434, option=[null, null, null, null, drop] +item=Bagged plant 3, id=8435, option=[null, null, null, null, drop] +item=Bagged plant 3, id=8436, option=[null, null, null, null, drop] +item=Thorny hedge, id=8437, option=[null, null, null, null, drop] +item=Thorny hedge, id=8438, option=[null, null, null, null, drop] +item=Nice hedge, id=8439, option=[null, null, null, null, drop] +item=Nice hedge, id=8440, option=[null, null, null, null, drop] +item=Small box hedge, id=8441, option=[null, null, null, null, drop] +item=Small box hedge, id=8442, option=[null, null, null, null, drop] +item=Topiary hedge, id=8443, option=[null, null, null, null, drop] +item=Topiary hedge, id=8444, option=[null, null, null, null, drop] +item=Fancy hedge, id=8445, option=[null, null, null, null, drop] +item=Fancy hedge, id=8446, option=[null, null, null, null, drop] +item=Tall fancy hedge, id=8447, option=[null, null, null, null, drop] +item=Tall fancy hedge, id=8448, option=[null, null, null, null, drop] +item=Tall box hedge, id=8449, option=[null, null, null, null, drop] +item=Tall box hedge, id=8450, option=[null, null, null, null, drop] +item=Bagged rosemary, id=8451, option=[null, null, null, null, drop] +item=Bagged rosemary, id=8452, option=[null, null, null, null, drop] +item=Bagged daffodils, id=8453, option=[null, null, null, null, drop] +item=Bagged daffodils, id=8454, option=[null, null, null, null, drop] +item=Bagged bluebells, id=8455, option=[null, null, null, null, drop] +item=Bagged bluebells, id=8456, option=[null, null, null, null, drop] +item=Bagged sunflower, id=8457, option=[null, null, null, null, drop] +item=Bagged sunflower, id=8458, option=[null, null, null, null, drop] +item=Bagged marigolds, id=8459, option=[null, null, null, null, drop] +item=Bagged marigolds, id=8460, option=[null, null, null, null, drop] +item=Bagged roses, id=8461, option=[null, null, null, null, drop] +item=Bagged roses, id=8462, option=[null, null, null, null, drop] +item=Construction guide, id=8463, option=[Read, null, null, null, drop] +item=Rune heraldic helm, id=8464, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8465, option=[Wear, null, null, null, drop] +item=Rune heraldic helm, id=8466, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8467, option=[Wear, null, null, null, drop] +item=Rune heraldic helm, id=8468, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8469, option=[Wear, null, null, null, drop] +item=Rune heraldic helm, id=8470, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8471, option=[Wear, null, null, null, drop] +item=Rune heraldic helm, id=8472, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8473, option=[Wear, null, null, null, drop] +item=Rune heraldic helm, id=8474, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8475, option=[Wear, null, null, null, drop] +item=Rune heraldic helm, id=8476, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8477, option=[Wear, null, null, null, drop] +item=Rune heraldic helm, id=8478, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8479, option=[Wear, null, null, null, drop] +item=Rune heraldic helm, id=8480, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8481, option=[Wear, null, null, null, drop] +item=Rune heraldic helm, id=8482, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8483, option=[Wear, null, null, null, drop] +item=Rune heraldic helm, id=8484, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8485, option=[Wear, null, null, null, drop] +item=Rune heraldic helm, id=8486, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8487, option=[Wear, null, null, null, drop] +item=Rune heraldic helm, id=8488, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8489, option=[Wear, null, null, null, drop] +item=Rune heraldic helm, id=8490, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8491, option=[Wear, null, null, null, drop] +item=Rune heraldic helm, id=8492, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8493, option=[Wear, null, null, null, drop] +item=Rune heraldic helm, id=8494, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8495, option=[Wear, null, null, null, drop] +item=Crude wooden chair, id=8496, option=[null, null, null, null, drop] +item=Crude wooden chair, id=8497, option=[null, null, null, null, drop] +item=Wooden chair, id=8498, option=[null, null, null, null, drop] +item=Wooden chair, id=8499, option=[null, null, null, null, drop] +item=Rocking chair, id=8500, option=[null, null, null, null, drop] +item=Rocking chair, id=8501, option=[null, null, null, null, drop] +item=Oak chair, id=8502, option=[null, null, null, null, drop] +item=Oak chair, id=8503, option=[null, null, null, null, drop] +item=Oak armchair, id=8504, option=[null, null, null, null, drop] +item=Oak armchair, id=8505, option=[null, null, null, null, drop] +item=Teak armchair, id=8506, option=[null, null, null, null, drop] +item=Teak armchair, id=8507, option=[null, null, null, null, drop] +item=Mahogany armchair, id=8508, option=[null, null, null, null, drop] +item=Mahogany armchair, id=8509, option=[null, null, null, null, drop] +item=Wooden bookcase, id=8510, option=[null, null, null, null, drop] +item=Wooden bookcase, id=8511, option=[null, null, null, null, drop] +item=Oak bookcase, id=8512, option=[null, null, null, null, drop] +item=Oak bookcase, id=8513, option=[null, null, null, null, drop] +item=Mahogany b'kcase, id=8514, option=[null, null, null, null, drop] +item=Mahogany b'kcase, id=8515, option=[null, null, null, null, drop] +item=Beer barrel, id=8516, option=[null, null, null, null, drop] +item=Beer barrel, id=8517, option=[null, null, null, null, drop] +item=Cider barrel, id=8518, option=[null, null, null, null, drop] +item=Cider barrel, id=8519, option=[null, null, null, null, drop] +item=Asgarnian ale, id=8520, option=[null, null, null, null, drop] +item=Asgarnian ale, id=8521, option=[null, null, null, null, drop] +item=Greenman's ale, id=8522, option=[null, null, null, null, drop] +item=Greenman's ale, id=8523, option=[null, null, null, null, drop] +item=Dragon bitter, id=8524, option=[null, null, null, null, drop] +item=Dragon bitter, id=8525, option=[null, null, null, null, drop] +item=Chef's delight, id=8526, option=[null, null, null, null, drop] +item=Chef's delight, id=8527, option=[null, null, null, null, drop] +item=Wood kitchen table, id=8528, option=[null, null, null, null, drop] +item=Wood kitchen table, id=8529, option=[null, null, null, null, drop] +item=Oak kitchen table, id=8530, option=[null, null, null, null, drop] +item=Oak kitchen table, id=8531, option=[null, null, null, null, drop] +item=Teak kitchen table, id=8532, option=[null, null, null, null, drop] +item=Teak kitchen table, id=8533, option=[null, null, null, null, drop] +item=Oak lectern, id=8534, option=[null, null, null, null, drop] +item=Oak lectern, id=8535, option=[null, null, null, null, drop] +item=Eagle lectern, id=8536, option=[null, null, null, null, drop] +item=Eagle lectern, id=8537, option=[null, null, null, null, drop] +item=Demon lectern, id=8538, option=[null, null, null, null, drop] +item=Demon lectern, id=8539, option=[null, null, null, null, drop] +item=Teak eagle lectern, id=8540, option=[null, null, null, null, drop] +item=Teak eagle lectern, id=8541, option=[null, null, null, null, drop] +item=Teak demon lectern, id=8542, option=[null, null, null, null, drop] +item=Teak demon lectern, id=8543, option=[null, null, null, null, drop] +item=Mahogany eagle, id=8544, option=[null, null, null, null, drop] +item=Mahogany eagle, id=8545, option=[null, null, null, null, drop] +item=Mahogany demon, id=8546, option=[null, null, null, null, drop] +item=Mahogany demon, id=8547, option=[null, null, null, null, drop] +item=Wood dining table, id=8548, option=[null, null, null, null, drop] +item=Wood dining table, id=8549, option=[null, null, null, null, drop] +item=Oak dining table, id=8550, option=[null, null, null, null, drop] +item=Oak dining table, id=8551, option=[null, null, null, null, drop] +item=Carved oak table, id=8552, option=[null, null, null, null, drop] +item=Carved oak table, id=8553, option=[null, null, null, null, drop] +item=Teak table, id=8554, option=[null, null, null, null, drop] +item=Teak table, id=8555, option=[null, null, null, null, drop] +item=Carved teak table, id=8556, option=[null, null, null, null, drop] +item=Carved teak table, id=8557, option=[null, null, null, null, drop] +item=Mahogany table, id=8558, option=[null, null, null, null, drop] +item=Mahogany table, id=8559, option=[null, null, null, null, drop] +item=Opulent table, id=8560, option=[null, null, null, null, drop] +item=Opulent table, id=8561, option=[null, null, null, null, drop] +item=Wooden bench, id=8562, option=[null, null, null, null, drop] +item=Wooden bench, id=8563, option=[null, null, null, null, drop] +item=Oak bench, id=8564, option=[null, null, null, null, drop] +item=Oak bench, id=8565, option=[null, null, null, null, drop] +item=Carved oak bench, id=8566, option=[null, null, null, null, drop] +item=Carved oak bench, id=8567, option=[null, null, null, null, drop] +item=Teak dining bench, id=8568, option=[null, null, null, null, drop] +item=Teak dining bench, id=8569, option=[null, null, null, null, drop] +item=Carved teak bench, id=8570, option=[null, null, null, null, drop] +item=Carved teak bench, id=8571, option=[null, null, null, null, drop] +item=Mahogany bench, id=8572, option=[null, null, null, null, drop] +item=Mahogany bench, id=8573, option=[null, null, null, null, drop] +item=Gilded bench, id=8574, option=[null, null, null, null, drop] +item=Gilded bench, id=8575, option=[null, null, null, null, drop] +item=Wooden bed, id=8576, option=[null, null, null, null, drop] +item=Wooden bed, id=8577, option=[null, null, null, null, drop] +item=Oak bed, id=8578, option=[null, null, null, null, drop] +item=Oak bed, id=8579, option=[null, null, null, null, drop] +item=Large oak bed, id=8580, option=[null, null, null, null, drop] +item=Large oak bed, id=8581, option=[null, null, null, null, drop] +item=Teak bed, id=8582, option=[null, null, null, null, drop] +item=Teak bed, id=8583, option=[null, null, null, null, drop] +item=Large teak bed, id=8584, option=[null, null, null, null, drop] +item=Large teak bed, id=8585, option=[null, null, null, null, drop] +item=4-poster, id=8586, option=[null, null, null, null, drop] +item=4-poster, id=8587, option=[null, null, null, null, drop] +item=Gilded 4-poster, id=8588, option=[null, null, null, null, drop] +item=Gilded 4-poster, id=8589, option=[null, null, null, null, drop] +item=Oak clock, id=8590, option=[null, null, null, null, drop] +item=Oak clock, id=8591, option=[null, null, null, null, drop] +item=Teak clock, id=8592, option=[null, null, null, null, drop] +item=Teak clock, id=8593, option=[null, null, null, null, drop] +item=Gilded clock, id=8594, option=[null, null, null, null, drop] +item=Gilded clock, id=8595, option=[null, null, null, null, drop] +item=Shaving stand, id=8596, option=[null, null, null, null, drop] +item=Shaving stand, id=8597, option=[null, null, null, null, drop] +item=Oak shaving stand, id=8598, option=[null, null, null, null, drop] +item=Oak shaving stand, id=8599, option=[null, null, null, null, drop] +item=Oak dresser, id=8600, option=[null, null, null, null, drop] +item=Oak dresser, id=8601, option=[null, null, null, null, drop] +item=Teak dresser, id=8602, option=[null, null, null, null, drop] +item=Teak dresser, id=8603, option=[null, null, null, null, drop] +item=Fancy teak dresser, id=8604, option=[null, null, null, null, drop] +item=Fancy teak dresser, id=8605, option=[null, null, null, null, drop] +item=Mahogany dresser, id=8606, option=[null, null, null, null, drop] +item=Mahogany dresser, id=8607, option=[null, null, null, null, drop] +item=Gilded dresser, id=8608, option=[null, null, null, null, drop] +item=Gilded dresser, id=8609, option=[null, null, null, null, drop] +item=Shoe box, id=8610, option=[null, null, null, null, drop] +item=Shoe box, id=8611, option=[null, null, null, null, drop] +item=Oak drawers, id=8612, option=[null, null, null, null, drop] +item=Oak drawers, id=8613, option=[null, null, null, null, drop] +item=Oak wardrobe, id=8614, option=[null, null, null, null, drop] +item=Oak wardrobe, id=8615, option=[null, null, null, null, drop] +item=Teak drawers, id=8616, option=[null, null, null, null, drop] +item=Teak drawers, id=8617, option=[null, null, null, null, drop] +item=Teak wardrobe, id=8618, option=[null, null, null, null, drop] +item=Teak wardrobe, id=8619, option=[null, null, null, null, drop] +item=Mahogany 'drobe, id=8620, option=[null, null, null, null, drop] +item=Mahogany 'drobe, id=8621, option=[null, null, null, null, drop] +item=Gilded wardrobe, id=8622, option=[null, null, null, null, drop] +item=Gilded wardrobe, id=8623, option=[null, null, null, null, drop] +item=Crystal ball, id=8624, option=[null, null, null, null, drop] +item=Crystal ball, id=8625, option=[null, null, null, null, drop] +item=Elemental sphere, id=8626, option=[null, null, null, null, drop] +item=Elemental sphere, id=8627, option=[null, null, null, null, drop] +item=Crystal of power, id=8628, option=[null, null, null, null, drop] +item=Crystal of power, id=8629, option=[null, null, null, null, drop] +item=Globe, id=8630, option=[null, null, null, null, drop] +item=Globe, id=8631, option=[null, null, null, null, drop] +item=Ornamental globe, id=8632, option=[null, null, null, null, drop] +item=Ornamental globe, id=8633, option=[null, null, null, null, drop] +item=Lunar globe, id=8634, option=[null, null, null, null, drop] +item=Lunar globe, id=8635, option=[null, null, null, null, drop] +item=Celestial globe, id=8636, option=[null, null, null, null, drop] +item=Celestial globe, id=8637, option=[null, null, null, null, drop] +item=Armillary sphere, id=8638, option=[null, null, null, null, drop] +item=Armillary sphere, id=8639, option=[null, null, null, null, drop] +item=Small orrery, id=8640, option=[null, null, null, null, drop] +item=Small orrery, id=8641, option=[null, null, null, null, drop] +item=Large orrery, id=8642, option=[null, null, null, null, drop] +item=Large orrery, id=8643, option=[null, null, null, null, drop] +item=Wooden telescope, id=8644, option=[null, null, null, null, drop] +item=Wooden telescope, id=8645, option=[null, null, null, null, drop] +item=Teak telescope, id=8646, option=[null, null, null, null, drop] +item=Teak telescope, id=8647, option=[null, null, null, null, drop] +item=Mahogany 'scope, id=8648, option=[null, null, null, null, drop] +item=Mahogany 'scope, id=8649, option=[null, null, null, null, drop] +item=Banner, id=8650, option=[null, Wield, null, null, drop] +item=Whoopsie, id=8651, option=[Wear, null, null, null, drop] +item=Banner, id=8652, option=[null, Wield, null, null, drop] +item=Whoopsie, id=8653, option=[Wear, null, null, null, drop] +item=Banner, id=8654, option=[null, Wield, null, null, drop] +item=Whoopsie, id=8655, option=[Wear, null, null, null, drop] +item=Banner, id=8656, option=[null, Wield, null, null, drop] +item=Whoopsie, id=8657, option=[Wear, null, null, null, drop] +item=Banner, id=8658, option=[null, Wield, null, null, drop] +item=Whoopsie, id=8659, option=[Wear, null, null, null, drop] +item=Banner, id=8660, option=[null, Wield, null, null, drop] +item=Whoopsie, id=8661, option=[Wear, null, null, null, drop] +item=Banner, id=8662, option=[null, Wield, null, null, drop] +item=Whoopsie, id=8663, option=[Wear, null, null, null, drop] +item=Banner, id=8664, option=[null, Wield, null, null, drop] +item=Whoopsie, id=8665, option=[Wear, null, null, null, drop] +item=Banner, id=8666, option=[null, Wield, null, null, drop] +item=Whoopsie, id=8667, option=[Wear, null, null, null, drop] +item=Banner, id=8668, option=[null, Wield, null, null, drop] +item=Whoopsie, id=8669, option=[Wear, null, null, null, drop] +item=Banner, id=8670, option=[null, Wield, null, null, drop] +item=Whoopsie, id=8671, option=[Wear, null, null, null, drop] +item=Banner, id=8672, option=[null, Wield, null, null, drop] +item=Whoopsie, id=8673, option=[Wear, null, null, null, drop] +item=Banner, id=8674, option=[null, Wield, null, null, drop] +item=Whoopsie, id=8675, option=[Wear, null, null, null, drop] +item=Banner, id=8676, option=[null, Wield, null, null, drop] +item=Whoopsie, id=8677, option=[Wear, null, null, null, drop] +item=Banner, id=8678, option=[null, Wield, null, null, drop] +item=Whoopsie, id=8679, option=[Wear, null, null, null, drop] +item=Banner, id=8680, option=[null, Wield, null, null, drop] +item=Whoopsie, id=8681, option=[Wear, null, null, null, drop] +item=Steel heraldic helm, id=8682, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8683, option=[Wear, null, null, null, drop] +item=Steel heraldic helm, id=8684, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8685, option=[Wear, null, null, null, drop] +item=Steel heraldic helm, id=8686, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8687, option=[Wear, null, null, null, drop] +item=Steel heraldic helm, id=8688, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8689, option=[Wear, null, null, null, drop] +item=Steel heraldic helm, id=8690, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8691, option=[Wear, null, null, null, drop] +item=Steel heraldic helm, id=8692, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8693, option=[Wear, null, null, null, drop] +item=Steel heraldic helm, id=8694, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8695, option=[Wear, null, null, null, drop] +item=Steel heraldic helm, id=8696, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8697, option=[Wear, null, null, null, drop] +item=Steel heraldic helm, id=8698, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8699, option=[Wear, null, null, null, drop] +item=Steel heraldic helm, id=8700, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8701, option=[Wear, null, null, null, drop] +item=Steel heraldic helm, id=8702, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8703, option=[Wear, null, null, null, drop] +item=Steel heraldic helm, id=8704, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8705, option=[Wear, null, null, null, drop] +item=Steel heraldic helm, id=8706, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8707, option=[Wear, null, null, null, drop] +item=Steel heraldic helm, id=8708, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8709, option=[Wear, null, null, null, drop] +item=Steel heraldic helm, id=8710, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8711, option=[Wear, null, null, null, drop] +item=Steel heraldic helm, id=8712, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8713, option=[Wear, null, null, null, drop] +item=Rune kiteshield, id=8714, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8715, option=[Wear, null, null, null, drop] +item=Rune kiteshield, id=8716, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8717, option=[Wear, null, null, null, drop] +item=Rune kiteshield, id=8718, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8719, option=[Wear, null, null, null, drop] +item=Rune kiteshield, id=8720, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8721, option=[Wear, null, null, null, drop] +item=Rune kiteshield, id=8722, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8723, option=[Wear, null, null, null, drop] +item=Rune kiteshield, id=8724, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8725, option=[Wear, null, null, null, drop] +item=Rune kiteshield, id=8726, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8727, option=[Wear, null, null, null, drop] +item=Rune kiteshield, id=8728, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8729, option=[Wear, null, null, null, drop] +item=Rune kiteshield, id=8730, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8731, option=[Wear, null, null, null, drop] +item=Rune kiteshield, id=8732, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8733, option=[Wear, null, null, null, drop] +item=Rune kiteshield, id=8734, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8735, option=[Wear, null, null, null, drop] +item=Rune kiteshield, id=8736, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8737, option=[Wear, null, null, null, drop] +item=Rune kiteshield, id=8738, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8739, option=[Wear, null, null, null, drop] +item=Rune kiteshield, id=8740, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8741, option=[Wear, null, null, null, drop] +item=Rune kiteshield, id=8742, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8743, option=[Wear, null, null, null, drop] +item=Rune kiteshield, id=8744, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8745, option=[Wear, null, null, null, drop] +item=Steel kiteshield, id=8746, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8747, option=[Wear, null, null, null, drop] +item=Steel kiteshield, id=8748, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8749, option=[Wear, null, null, null, drop] +item=Steel kiteshield, id=8750, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8751, option=[Wear, null, null, null, drop] +item=Steel kiteshield, id=8752, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8753, option=[Wear, null, null, null, drop] +item=Steel kiteshield, id=8754, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8755, option=[Wear, null, null, null, drop] +item=Steel kiteshield, id=8756, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8757, option=[Wear, null, null, null, drop] +item=Steel kiteshield, id=8758, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8759, option=[Wear, null, null, null, drop] +item=Steel kiteshield, id=8760, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8761, option=[Wear, null, null, null, drop] +item=Steel kiteshield, id=8762, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8763, option=[Wear, null, null, null, drop] +item=Steel kiteshield, id=8764, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8765, option=[Wear, null, null, null, drop] +item=Steel kiteshield, id=8766, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8767, option=[Wear, null, null, null, drop] +item=Steel kiteshield, id=8768, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8769, option=[Wear, null, null, null, drop] +item=Steel kiteshield, id=8770, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8771, option=[Wear, null, null, null, drop] +item=Steel kiteshield, id=8772, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8773, option=[Wear, null, null, null, drop] +item=Steel kiteshield, id=8774, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8775, option=[Wear, null, null, null, drop] +item=Steel kiteshield, id=8776, option=[null, Wear, null, null, drop] +item=Whoopsie, id=8777, option=[Wear, null, null, null, drop] +item=Oak plank, id=8778, option=[null, null, null, null, drop] +item=Oak plank, id=8779, option=[null, null, null, null, drop] +item=Teak plank, id=8780, option=[null, null, null, null, drop] +item=Teak plank, id=8781, option=[null, null, null, null, drop] +item=Mahogany plank, id=8782, option=[null, null, null, null, drop] +item=Mahogany plank, id=8783, option=[null, null, null, null, drop] +item=Gold leaf, id=8784, option=[null, null, null, null, drop] +item=Gold leaf, id=8785, option=[null, null, null, null, drop] +item=Marble block, id=8786, option=[null, null, null, null, drop] +item=Marble block, id=8787, option=[null, null, null, null, drop] +item=Magic stone, id=8788, option=[null, null, null, null, drop] +item=Magic stone, id=8789, option=[null, null, null, null, drop] +item=Bolt of cloth, id=8790, option=[null, null, null, null, drop] +item=Bolt of cloth, id=8791, option=[null, null, null, null, drop] +item=Clockwork, id=8792, option=[null, null, null, null, drop] +item=Clockwork, id=8793, option=[null, null, null, null, drop] +item=Saw, id=8794, option=[null, null, null, null, drop] +item=Saw, id=8795, option=[null, null, null, null, drop] +item=Thing, id=8796, option=[null, null, null, null, drop] +item=Cheat, id=8797, option=[null, null, null, null, drop] +item=null, id=8798, option=[null, null, null, null, drop] +item=null, id=8799, option=[null, null, null, null, drop] +item=null, id=8800, option=[null, null, null, null, drop] +item=null, id=8801, option=[null, null, null, null, drop] +item=null, id=8802, option=[null, null, null, null, drop] +item=null, id=8803, option=[null, null, null, null, drop] +item=null, id=8804, option=[null, null, null, null, drop] +item=null, id=8805, option=[null, null, null, null, drop] +item=null, id=8806, option=[null, null, null, null, drop] +item=null, id=8807, option=[null, null, null, null, drop] +item=null, id=8808, option=[null, null, null, null, drop] +item=null, id=8809, option=[null, null, null, null, drop] +item=null, id=8810, option=[null, null, null, null, drop] +item=null, id=8811, option=[null, null, null, null, drop] +item=null, id=8812, option=[null, null, null, null, drop] +item=null, id=8813, option=[null, null, null, null, drop] +item=null, id=8814, option=[null, null, null, null, drop] +item=null, id=8815, option=[null, null, null, null, drop] +item=null, id=8816, option=[null, null, null, null, drop] +item=null, id=8817, option=[null, null, null, null, drop] +item=null, id=8818, option=[null, null, null, null, drop] +item=null, id=8819, option=[null, null, null, null, drop] +item=null, id=8820, option=[null, null, null, null, drop] +item=null, id=8821, option=[null, null, null, null, drop] +item=null, id=8822, option=[null, null, null, null, drop] +item=null, id=8823, option=[null, null, null, null, drop] +item=null, id=8824, option=[null, null, null, null, drop] +item=null, id=8825, option=[null, null, null, null, drop] +item=null, id=8826, option=[null, null, null, null, drop] +item=null, id=8827, option=[null, null, null, null, drop] +item=null, id=8828, option=[null, null, null, null, drop] +item=null, id=8829, option=[null, null, null, null, drop] +item=null, id=8830, option=[null, null, null, null, drop] +item=null, id=8831, option=[null, null, null, null, drop] +item=null, id=8832, option=[null, null, null, null, drop] +item=null, id=8833, option=[null, null, null, null, drop] +item=null, id=8834, option=[null, null, null, null, drop] +item=null, id=8835, option=[null, null, null, null, drop] +item=Mahogany logs, id=8836, option=[null, null, null, null, drop] +item=Timber beam, id=8837, option=[null, null, null, null, drop] +item=Timber beam, id=8838, option=[null, null, null, null, drop] +item=Void knight top, id=8839, option=[null, Wear, null, null, drop] +item=Void knight robe, id=8840, option=[null, Wear, null, null, drop] +item=Void knight mace, id=8841, option=[null, Wield, null, null, drop] +item=Void knight gloves, id=8842, option=[null, Wear, null, null, drop] +item=null, id=8843, option=[null, null, null, null, drop] +item=Bronze defender, id=8844, option=[null, Wield, null, null, drop] +item=Iron defender, id=8845, option=[null, Wield, null, null, drop] +item=Steel defender, id=8846, option=[null, Wield, null, null, drop] +item=Black defender, id=8847, option=[null, Wield, null, null, drop] +item=Mithril defender, id=8848, option=[null, Wield, null, null, drop] +item=Adamant defender, id=8849, option=[null, Wield, null, null, drop] +item=Rune defender, id=8850, option=[null, Wield, null, null, drop] +item=Warrior guild token, id=8851, option=[null, null, null, null, drop] +item=null, id=8852, option=[null, null, null, null, drop] +item=null, id=8853, option=[null, null, null, null, drop] +item=null, id=8854, option=[null, null, null, null, drop] +item=null, id=8855, option=[null, null, null, null, drop] +item=Defensive shield, id=8856, option=[null, Wield, null, null, drop] +item=Shot, id=8857, option=[null, null, null, null, drop] +item=18lb shot, id=8858, option=[null, null, null, null, drop] +item=22lb shot, id=8859, option=[null, null, null, null, drop] +item=One barrel, id=8860, option=[null, null, null, null, drop] +item=Two barrels, id=8861, option=[null, null, null, null, drop] +item=Three barrels, id=8862, option=[null, null, null, null, drop] +item=Four barrels, id=8863, option=[null, null, null, null, drop] +item=Five barrels, id=8864, option=[null, null, null, null, drop] +item=Ground ashes, id=8865, option=[Dust-hands, null, null, null, drop] +item=Steel key, id=8866, option=[null, null, null, null, drop] +item=Bronze key, id=8867, option=[null, null, null, null, drop] +item=Silver key, id=8868, option=[null, null, null, null, drop] +item=Iron key, id=8869, option=[null, null, null, null, drop] +item=Zanik, id=8870, option=[null, null, null, null, drop] +item=Crate with zanik, id=8871, option=[null, Wield, null, null, drop] +item=Bone dagger, id=8872, option=[null, Wield, null, null, drop] +item=Bone dagger, id=8873, option=[null, null, null, null, drop] +item=Bone dagger (p), id=8874, option=[null, Wield, null, null, drop] +item=Bone dagger (p), id=8875, option=[null, null, null, null, drop] +item=Bone dagger (p+), id=8876, option=[null, Wield, null, null, drop] +item=Bone dagger (p+), id=8877, option=[null, null, null, null, drop] +item=Bone dagger (p++), id=8878, option=[null, Wield, null, null, drop] +item=Bone dagger (p++), id=8879, option=[null, null, null, null, drop] +item=Dorgeshuun c'bow, id=8880, option=[null, Wield, null, null, drop] +item=Dorgeshuun c'bow, id=8881, option=[null, null, null, null, drop] +item=Bone bolts, id=8882, option=[null, Wield, null, null, drop] +item=null, id=8883, option=[null, null, null, null, drop] +item=null, id=8884, option=[null, null, null, null, drop] +item=null, id=8885, option=[null, null, null, null, drop] +item=null, id=8886, option=[null, null, null, null, drop] +item=Zanik, id=8887, option=[null, null, null, null, drop] +item=Zanik (ham), id=8888, option=[null, null, null, null, drop] +item=Zanik (showdown), id=8889, option=[null, null, null, null, drop] +item=Coins, id=8890, option=[null, null, null, null, drop] +item=null, id=8891, option=[null, null, null, null, drop] +item=null, id=8892, option=[null, null, null, null, drop] +item=null, id=8893, option=[null, null, null, null, drop] +item=null, id=8894, option=[null, null, null, null, drop] +item=null, id=8895, option=[null, null, null, null, drop] +item=null, id=8896, option=[null, null, null, null, drop] +item=null, id=8897, option=[null, null, null, null, drop] +item=null, id=8898, option=[null, null, null, null, drop] +item=null, id=8899, option=[null, null, null, null, drop] +item=Cave horror, id=8900, option=[null, null, null, null, drop] +item=Black mask (10), id=8901, option=[null, Wear, null, null, drop] +item=Black mask (10), id=8902, option=[null, null, null, null, drop] +item=Black mask (9), id=8903, option=[null, Wear, null, null, drop] +item=Black mask (9), id=8904, option=[null, null, null, null, drop] +item=Black mask (8), id=8905, option=[null, Wear, null, null, drop] +item=Black mask (8), id=8906, option=[null, null, null, null, drop] +item=Black mask (7), id=8907, option=[null, Wear, null, null, drop] +item=Black mask (7), id=8908, option=[null, null, null, null, drop] +item=Black mask (6), id=8909, option=[null, Wear, null, null, drop] +item=Black mask (6), id=8910, option=[null, null, null, null, drop] +item=Black mask (5), id=8911, option=[null, Wear, null, null, drop] +item=Black mask (5), id=8912, option=[null, null, null, null, drop] +item=Black mask (4), id=8913, option=[null, Wear, null, null, drop] +item=Black mask (4), id=8914, option=[null, null, null, null, drop] +item=Black mask (3), id=8915, option=[null, Wear, null, null, drop] +item=Black mask (3), id=8916, option=[null, null, null, null, drop] +item=Black mask (2), id=8917, option=[null, Wear, null, null, drop] +item=Black mask (2), id=8918, option=[null, null, null, null, drop] +item=Black mask (1), id=8919, option=[null, Wear, null, null, drop] +item=Black mask (1), id=8920, option=[null, null, null, null, drop] +item=Black mask, id=8921, option=[null, Wear, null, null, drop] +item=Black mask, id=8922, option=[null, null, null, null, drop] +item=Witchwood icon, id=8923, option=[null, Wear, null, null, drop] +item=Bandana eyepatch, id=8924, option=[null, Wear, null, null, drop] +item=Bandana eyepatch, id=8925, option=[null, Wear, null, null, drop] +item=Bandana eyepatch, id=8926, option=[null, Wear, null, null, drop] +item=Bandana eyepatch, id=8927, option=[null, Wear, null, null, drop] +item=Hat eyepatch, id=8928, option=[null, Wear, null, null, drop] +item=Crabclaw hook, id=8929, option=[null, Wear, null, null, drop] +item=Pipe section, id=8930, option=[null, null, null, null, drop] +item=Pipe section, id=8931, option=[null, null, null, null, drop] +item=Lumber patch, id=8932, option=[null, null, null, null, drop] +item=Lumber patch, id=8933, option=[null, null, null, null, drop] +item=Scrapey tree logs, id=8934, option=[null, null, null, null, drop] +item=Scrapey tree logs, id=8935, option=[null, null, null, null, drop] +item=Blue flowers, id=8936, option=[null, null, null, null, drop] +item=Blue flowers, id=8937, option=[null, null, null, null, drop] +item=Red flowers, id=8938, option=[null, null, null, null, drop] +item=Red flowers, id=8939, option=[null, null, null, null, drop] +item=Rum, id=8940, option=[Drink, null, null, null, drop] +item=Rum, id=8941, option=[Drink, null, null, null, drop] +item=Monkey, id=8942, option=[null, null, null, Talk-To, drop] +item=Blue monkey, id=8943, option=[null, null, null, Talk-To, drop] +item=Blue monkey, id=8944, option=[null, null, null, Talk-To, drop] +item=Blue monkey, id=8945, option=[null, null, null, Talk-To, drop] +item=Red monkey, id=8946, option=[null, null, null, Talk-To, drop] +item=Red monkey, id=8947, option=[null, null, null, Talk-To, drop] +item=Red monkey, id=8948, option=[null, null, null, Talk-To, drop] +item=Pirate bandana, id=8949, option=[null, Wear, null, null, drop] +item=Pirate hat, id=8950, option=[null, Wear, null, null, drop] +item=Pieces of eight, id=8951, option=[null, null, null, null, drop] +item=Blue naval shirt, id=8952, option=[null, Wear, null, null, drop] +item=Green naval shirt, id=8953, option=[null, Wear, null, null, drop] +item=Red naval shirt, id=8954, option=[null, Wear, null, null, drop] +item=Brown naval shirt, id=8955, option=[null, Wear, null, null, drop] +item=Black naval shirt, id=8956, option=[null, Wear, null, null, drop] +item=Purple naval shirt, id=8957, option=[null, Wear, null, null, drop] +item=Grey naval shirt, id=8958, option=[null, Wear, null, null, drop] +item=Blue tricorn hat, id=8959, option=[null, Wear, null, null, drop] +item=Green tricorn hat, id=8960, option=[null, Wear, null, null, drop] +item=Red tricorn hat, id=8961, option=[null, Wear, null, null, drop] +item=Brown tricorn hat, id=8962, option=[null, Wear, null, null, drop] +item=Black tricorn hat, id=8963, option=[null, Wear, null, null, drop] +item=Purple tricorn hat, id=8964, option=[null, Wear, null, null, drop] +item=Grey tricorn hat, id=8965, option=[null, Wear, null, null, drop] +item=Cutthroat flag, id=8966, option=[null, Wield, null, null, drop] +item=Guilded smile flag, id=8967, option=[null, Wield, null, null, drop] +item=Bronze fist flag, id=8968, option=[null, Wield, null, null, drop] +item=Lucky shot flag, id=8969, option=[null, Wield, null, null, drop] +item=Treasure flag, id=8970, option=[null, Wield, null, null, drop] +item=Phasmatys flag, id=8971, option=[null, Wield, null, null, drop] +item=Bowl of red water, id=8972, option=[null, null, null, null, drop] +item=Bowl of red water, id=8973, option=[null, null, null, null, drop] +item=Bowl of blue water, id=8974, option=[null, null, null, null, drop] +item=Bowl of blue water, id=8975, option=[null, null, null, null, drop] +item=Bitternut, id=8976, option=[null, null, null, null, drop] +item=Scrapey bark, id=8977, option=[null, null, null, null, drop] +item=Scrapey bark, id=8978, option=[null, null, null, null, drop] +item=Bridge section, id=8979, option=[null, null, null, null, drop] +item=Bridge section, id=8980, option=[null, null, null, null, drop] +item=Sweetgrubs, id=8981, option=[null, null, null, null, drop] +item=Sweetgrubs, id=8982, option=[null, null, null, null, drop] +item=null, id=8983, option=[null, null, null, null, drop] +item=null, id=8984, option=[null, null, null, null, drop] +item=null, id=8985, option=[null, null, null, null, drop] +item=Bucket, id=8986, option=[null, null, null, null, drop] +item=Torch, id=8987, option=[null, null, null, null, drop] +item=The stuff, id=8988, option=[null, null, null, null, drop] +item=Brewin' guide, id=8989, option=[Read, null, null, null, drop] +item=Brewin' guide, id=8990, option=[null, null, null, null, drop] +item=Blue navy slacks, id=8991, option=[null, Wear, null, null, drop] +item=Green navy slacks, id=8992, option=[null, Wear, null, null, drop] +item=Red navy slacks, id=8993, option=[null, Wear, null, null, drop] +item=Brown navy slacks, id=8994, option=[null, Wear, null, null, drop] +item=Black navy slacks, id=8995, option=[null, Wear, null, null, drop] +item=Purple navy slacks, id=8996, option=[null, Wear, null, null, drop] +item=Grey navy slacks, id=8997, option=[null, Wear, null, null, drop] +item=Bandana eyepatch, id=8998, option=[null, null, null, null, drop] +item=Bandana eyepatch, id=8999, option=[null, null, null, null, drop] +item=Bandana eyepatch, id=9000, option=[null, null, null, null, drop] +item=Bandana eyepatch, id=9001, option=[null, null, null, null, drop] +item=Hat eyepatch, id=9002, option=[null, null, null, null, drop] +item=Security book, id=9003, option=[Read, null, null, null, drop] +item=Stronghold notes, id=9004, option=[Read, null, null, null, drop] +item=Fancy boots, id=9005, option=[null, Wear, null, null, Destroy] +item=Fighting boots, id=9006, option=[null, Wear, null, null, Destroy] +item=Right skull half, id=9007, option=[null, null, null, null, drop] +item=Left skull half, id=9008, option=[null, null, null, null, drop] +item=Strange skull, id=9009, option=[null, null, null, null, drop] +item=Top of sceptre, id=9010, option=[null, null, null, null, drop] +item=Bottom of sceptre, id=9011, option=[null, null, null, null, drop] +item=Runed sceptre, id=9012, option=[null, null, null, null, drop] +item=Skull sceptre, id=9013, option=[null, Wield, Invoke, Divine, Destroy] +item=Security book, id=9014, option=[null, null, null, null, drop] +item=Stronghold notes, id=9015, option=[null, null, null, null, drop] +item=Gorak claws, id=9016, option=[null, null, null, null, drop] +item=Star flower, id=9017, option=[null, null, null, null, drop] +item=Gorak claw powder, id=9018, option=[null, null, null, null, drop] +item=Magic essence(unf), id=9019, option=[null, null, null, Empty, drop] +item=Queen's secateurs, id=9020, option=[null, null, null, null, drop] +item=Magic essence(4), id=9021, option=[Drink, null, null, Empty, drop] +item=Magic essence(3), id=9022, option=[Drink, null, null, Empty, drop] +item=Magic essence(2), id=9023, option=[Drink, null, null, Empty, drop] +item=Magic essence(1), id=9024, option=[Drink, null, null, Empty, drop] +item=Nuff's certificate, id=9025, option=[Read, Study, null, null, Destroy] +item=Ivory comb, id=9026, option=[null, null, null, null, drop] +item=Ivory comb, id=9027, option=[null, null, null, null, drop] +item=Golden scarab, id=9028, option=[null, null, null, null, drop] +item=Golden scarab, id=9029, option=[null, null, null, null, drop] +item=Stone scarab, id=9030, option=[null, null, null, null, drop] +item=Stone scarab, id=9031, option=[null, null, null, null, drop] +item=Pottery scarab, id=9032, option=[null, null, null, null, drop] +item=Pottery scarab, id=9033, option=[null, null, null, null, drop] +item=Golden statuette, id=9034, option=[null, null, null, null, drop] +item=Golden statuette, id=9035, option=[null, null, null, null, drop] +item=Pottery statuette, id=9036, option=[null, null, null, null, drop] +item=Pottery statuette, id=9037, option=[null, null, null, null, drop] +item=Stone statuette, id=9038, option=[null, null, null, null, drop] +item=Stone statuette, id=9039, option=[null, null, null, null, drop] +item=Gold seal, id=9040, option=[null, null, null, null, drop] +item=Gold seal, id=9041, option=[null, null, null, null, drop] +item=Stone seal, id=9042, option=[null, null, null, null, drop] +item=Stone seal, id=9043, option=[null, null, null, null, drop] +item=Pharaoh's sceptre, id=9044, option=[Teleport, Wield, null, null, drop] +item=Pharaoh's sceptre, id=9045, option=[null, null, null, null, drop] +item=Pharaoh's sceptre, id=9046, option=[Teleport, Wield, null, null, drop] +item=Pharaoh's sceptre, id=9047, option=[null, null, null, null, drop] +item=Pharaoh's sceptre, id=9048, option=[Teleport, Wield, null, null, drop] +item=Pharaoh's sceptre, id=9049, option=[null, null, null, null, drop] +item=Pharaoh's sceptre, id=9050, option=[Teleport, Wield, null, null, drop] +item=Pharaoh's sceptre, id=9051, option=[null, null, null, null, drop] +item=Locust meat, id=9052, option=[Eat, null, null, null, drop] +item=Locust meat, id=9053, option=[null, null, null, null, drop] +item=Red goblin mail, id=9054, option=[null, Wear, null, null, drop] +item=Black goblin mail, id=9055, option=[null, Wear, null, null, drop] +item=Yellow goblin mail, id=9056, option=[null, Wear, null, null, drop] +item=Green goblin mail, id=9057, option=[null, Wear, null, null, drop] +item=Purple goblin mail, id=9058, option=[null, Wear, null, null, drop] +item=Pink goblin mail, id=9059, option=[null, Wear, null, null, drop] +item=null, id=9060, option=[null, null, null, null, drop] +item=null, id=9061, option=[null, null, null, null, drop] +item=null, id=9062, option=[null, null, null, null, drop] +item=null, id=9063, option=[null, null, null, null, drop] +item=Emerald lantern, id=9064, option=[null, null, null, null, drop] +item=Emerald lantern, id=9065, option=[null, null, Extinguish, null, drop] +item=Emerald lens, id=9066, option=[null, null, null, null, drop] +item=Dream log, id=9067, option=[null, null, null, null, drop] +item=Moonclan helm, id=9068, option=[null, Wear, null, null, drop] +item=Moonclan hat, id=9069, option=[null, Wear, null, null, drop] +item=Moonclan armour, id=9070, option=[null, Wear, null, null, drop] +item=Moonclan skirt, id=9071, option=[null, Wear, null, null, drop] +item=Moonclan gloves, id=9072, option=[null, Wear, null, null, drop] +item=Moonclan boots, id=9073, option=[null, Wear, null, null, drop] +item=Moonclan cape, id=9074, option=[null, Wear, null, null, drop] +item=Astral rune, id=9075, option=[null, null, null, null, drop] +item=Lunar ore, id=9076, option=[null, null, null, null, Destroy] +item=Lunar bar, id=9077, option=[null, null, null, null, Destroy] +item=Moonclan manual, id=9078, option=[Read, null, null, null, drop] +item=Suqah tooth, id=9079, option=[null, null, null, null, drop] +item=Suqah hide, id=9080, option=[null, null, null, null, drop] +item=Suqah leather, id=9081, option=[null, null, null, null, drop] +item=Ground tooth, id=9082, option=[null, null, null, null, drop] +item=Seal of passage, id=9083, option=[null, Wear, null, null, Destroy] +item=Lunar staff, id=9084, option=[null, Wield, null, null, Destroy] +item=Empty vial, id=9085, option=[null, null, null, null, Destroy] +item=Vial of water, id=9086, option=[null, null, null, null, Destroy] +item=Waking sleep vial, id=9087, option=[null, null, null, null, Destroy] +item=Guam vial, id=9088, option=[null, null, null, null, Destroy] +item=Marr vial, id=9089, option=[null, null, null, null, Destroy] +item=Guam-marr vial, id=9090, option=[null, null, null, null, Destroy] +item=Lunar staff - pt1, id=9091, option=[null, Wield, null, null, Destroy] +item=Lunar staff - pt2, id=9092, option=[null, Wield, null, null, Destroy] +item=Lunar staff - pt3, id=9093, option=[null, Wield, null, null, Destroy] +item=Kindling, id=9094, option=[null, null, null, null, drop] +item=Soaked kindling, id=9095, option=[null, null, null, null, drop] +item=Lunar helm, id=9096, option=[null, Wear, null, null, Destroy] +item=Lunar torso, id=9097, option=[null, Wear, null, null, Destroy] +item=Lunar legs, id=9098, option=[null, Wear, null, null, Destroy] +item=Lunar gloves, id=9099, option=[null, Wear, null, null, Destroy] +item=Lunar boots, id=9100, option=[null, Wear, null, null, Destroy] +item=Lunar cape, id=9101, option=[null, Wear, null, null, Destroy] +item=Lunar amulet, id=9102, option=[null, Wear, null, null, Destroy] +item=A special tiara, id=9103, option=[null, null, null, null, Destroy] +item=Lunar ring, id=9104, option=[null, Wear, null, null, Destroy] +item=Suqah monster, id=9105, option=[null, null, null, null, drop] +item=Astral tiara, id=9106, option=[null, Wear, null, null, drop] +item=null, id=9107, option=[null, null, null, null, drop] +item=null, id=9108, option=[null, null, null, null, drop] +item=null, id=9109, option=[null, null, null, null, drop] +item=null, id=9110, option=[null, null, null, null, drop] +item=null, id=9111, option=[null, null, null, null, drop] +item=null, id=9112, option=[null, null, null, null, drop] +item=null, id=9113, option=[null, null, null, null, drop] +item=null, id=9114, option=[null, null, null, null, drop] +item=null, id=9115, option=[null, null, null, null, drop] +item=null, id=9116, option=[null, null, null, null, drop] +item=null, id=9117, option=[null, null, null, null, drop] +item=null, id=9118, option=[null, null, null, null, drop] +item=null, id=9119, option=[null, null, null, null, drop] +item=null, id=9120, option=[null, null, null, null, drop] +item=null, id=9121, option=[null, null, null, null, drop] +item=null, id=9122, option=[null, null, null, null, drop] +item=null, id=9123, option=[null, null, null, null, drop] +item=null, id=9124, option=[null, null, null, null, drop] +item=null, id=9125, option=[null, null, null, null, drop] +item=null, id=9126, option=[null, null, null, null, drop] +item=null, id=9127, option=[null, null, null, null, drop] +item=null, id=9128, option=[null, null, null, null, drop] +item=null, id=9129, option=[null, null, null, null, drop] +item=null, id=9130, option=[null, null, null, null, drop] +item=null, id=9131, option=[null, null, null, null, drop] +item=null, id=9132, option=[null, null, null, null, drop] +item=null, id=9133, option=[null, null, null, null, drop] +item=null, id=9134, option=[null, null, null, null, drop] +item=null, id=9135, option=[null, null, null, null, drop] +item=null, id=9136, option=[null, null, null, null, drop] +item=null, id=9137, option=[null, null, null, null, drop] +item=null, id=9138, option=[null, null, null, null, drop] +item=Blurite bolts, id=9139, option=[null, Wield, null, null, drop] +item=Iron bolts, id=9140, option=[null, Wield, null, null, drop] +item=Steel bolts, id=9141, option=[null, Wield, null, null, drop] +item=Mithril bolts, id=9142, option=[null, Wield, null, null, drop] +item=Adamant bolts, id=9143, option=[null, Wield, null, null, drop] +item=Runite bolts, id=9144, option=[null, Wield, null, null, drop] +item=Silver bolts, id=9145, option=[null, Wield, null, null, drop] +item=null, id=9146, option=[null, null, null, null, drop] +item=null, id=9147, option=[null, null, null, null, drop] +item=null, id=9148, option=[null, null, null, null, drop] +item=null, id=9149, option=[null, null, null, null, drop] +item=null, id=9150, option=[null, null, null, null, drop] +item=null, id=9151, option=[null, null, null, null, drop] +item=null, id=9152, option=[null, null, null, null, drop] +item=null, id=9153, option=[null, null, null, null, drop] +item=null, id=9154, option=[null, null, null, null, drop] +item=null, id=9155, option=[null, null, null, null, drop] +item=null, id=9156, option=[null, null, null, null, drop] +item=null, id=9157, option=[null, null, null, null, drop] +item=null, id=9158, option=[null, null, null, null, drop] +item=null, id=9159, option=[null, null, null, null, drop] +item=null, id=9160, option=[null, null, null, null, drop] +item=null, id=9161, option=[null, null, null, null, drop] +item=null, id=9162, option=[null, null, null, null, drop] +item=null, id=9163, option=[null, null, null, null, drop] +item=null, id=9164, option=[null, null, null, null, drop] +item=null, id=9165, option=[null, null, null, null, drop] +item=null, id=9166, option=[null, null, null, null, drop] +item=null, id=9167, option=[null, null, null, null, drop] +item=null, id=9168, option=[null, null, null, null, drop] +item=null, id=9169, option=[null, null, null, null, drop] +item=null, id=9170, option=[null, null, null, null, drop] +item=null, id=9171, option=[null, null, null, null, drop] +item=null, id=9172, option=[null, null, null, null, drop] +item=null, id=9173, option=[null, null, null, null, drop] +item=Bronze c'bow, id=9174, option=[null, Wield, null, null, drop] +item=Bronze c'bow, id=9175, option=[null, null, null, null, drop] +item=Blurite c'bow, id=9176, option=[null, Wield, null, null, drop] +item=Iron c'bow, id=9177, option=[null, Wield, null, null, drop] +item=Iron c'bow, id=9178, option=[null, null, null, null, drop] +item=Steel c'bow, id=9179, option=[null, Wield, null, null, drop] +item=Steel c'bow, id=9180, option=[null, null, null, null, drop] +item=Mith c'bow, id=9181, option=[null, Wield, null, null, drop] +item=Mith c'bow, id=9182, option=[null, null, null, null, drop] +item=Adamant c'bow, id=9183, option=[null, Wield, null, null, drop] +item=Adamant c'bow, id=9184, option=[null, null, null, null, drop] +item=Rune c'bow, id=9185, option=[null, Wield, null, null, drop] +item=Rune c'bow, id=9186, option=[null, null, null, null, drop] +item=Jade bolt tips, id=9187, option=[null, null, null, null, drop] +item=Topaz bolt tips, id=9188, option=[null, null, null, null, drop] +item=Sapphire bolt tips, id=9189, option=[null, null, null, null, drop] +item=Emerald bolt tips, id=9190, option=[null, null, null, null, drop] +item=Ruby bolt tips, id=9191, option=[null, null, null, null, drop] +item=Diamond bolt tips, id=9192, option=[null, null, null, null, drop] +item=Dragon bolt tips, id=9193, option=[null, null, null, null, drop] +item=Onyx bolt tips, id=9194, option=[null, null, null, null, drop] +item=null, id=9195, option=[null, null, null, null, drop] +item=null, id=9196, option=[null, null, null, null, drop] +item=null, id=9197, option=[null, null, null, null, drop] +item=null, id=9198, option=[null, null, null, null, drop] +item=null, id=9199, option=[null, null, null, null, drop] +item=null, id=9200, option=[null, null, null, null, drop] +item=null, id=9201, option=[null, null, null, null, drop] +item=null, id=9202, option=[null, null, null, null, drop] +item=null, id=9203, option=[null, null, null, null, drop] +item=null, id=9204, option=[null, null, null, null, drop] +item=null, id=9205, option=[null, null, null, null, drop] +item=null, id=9206, option=[null, null, null, null, drop] +item=null, id=9207, option=[null, null, null, null, drop] +item=null, id=9208, option=[null, null, null, null, drop] +item=null, id=9209, option=[null, null, null, null, drop] +item=null, id=9210, option=[null, null, null, null, drop] +item=null, id=9211, option=[null, null, null, null, drop] +item=null, id=9212, option=[null, null, null, null, drop] +item=null, id=9213, option=[null, null, null, null, drop] +item=null, id=9214, option=[null, null, null, null, drop] +item=null, id=9215, option=[null, null, null, null, drop] +item=null, id=9216, option=[null, null, null, null, drop] +item=null, id=9217, option=[null, null, null, null, drop] +item=null, id=9218, option=[null, null, null, null, drop] +item=null, id=9219, option=[null, null, null, null, drop] +item=null, id=9220, option=[null, null, null, null, drop] +item=null, id=9221, option=[null, null, null, null, drop] +item=null, id=9222, option=[null, null, null, null, drop] +item=null, id=9223, option=[null, null, null, null, drop] +item=null, id=9224, option=[null, null, null, null, drop] +item=null, id=9225, option=[null, null, null, null, drop] +item=null, id=9226, option=[null, null, null, null, drop] +item=null, id=9227, option=[null, null, null, null, drop] +item=null, id=9228, option=[null, null, null, null, drop] +item=null, id=9229, option=[null, null, null, null, drop] +item=null, id=9230, option=[null, null, null, null, drop] +item=null, id=9231, option=[null, null, null, null, drop] +item=null, id=9232, option=[null, null, null, null, drop] +item=null, id=9233, option=[null, null, null, null, drop] +item=null, id=9234, option=[null, null, null, null, drop] +item=null, id=9235, option=[null, null, null, null, drop] +item=Opal bolts (e), id=9236, option=[null, Wield, null, null, drop] +item=Jade bolts (e), id=9237, option=[null, Wield, null, null, drop] +item=Pearl bolts (e), id=9238, option=[null, Wield, null, null, drop] +item=Topaz bolts (e), id=9239, option=[null, Wield, null, null, drop] +item=Sapphire bolts (e), id=9240, option=[null, Wield, null, null, drop] +item=Emerald bolts (e), id=9241, option=[null, Wield, null, null, drop] +item=Ruby bolts (e), id=9242, option=[null, Wield, null, null, drop] +item=Diamond bolts (e), id=9243, option=[null, Wield, null, null, drop] +item=Dragon bolts (e), id=9244, option=[null, Wield, null, null, drop] +item=Onyx bolts (e), id=9245, option=[null, Wield, null, null, drop] +item=null, id=9246, option=[null, null, null, null, drop] +item=null, id=9247, option=[null, null, null, null, drop] +item=null, id=9248, option=[null, null, null, null, drop] +item=null, id=9249, option=[null, null, null, null, drop] +item=null, id=9250, option=[null, null, null, null, drop] +item=null, id=9251, option=[null, null, null, null, drop] +item=null, id=9252, option=[null, null, null, null, drop] +item=null, id=9253, option=[null, null, null, null, drop] +item=null, id=9254, option=[null, null, null, null, drop] +item=null, id=9255, option=[null, null, null, null, drop] +item=null, id=9256, option=[null, null, null, null, drop] +item=null, id=9257, option=[null, null, null, null, drop] +item=null, id=9258, option=[null, null, null, null, drop] +item=null, id=9259, option=[null, null, null, null, drop] +item=null, id=9260, option=[null, null, null, null, drop] +item=null, id=9261, option=[null, null, null, null, drop] +item=null, id=9262, option=[null, null, null, null, drop] +item=null, id=9263, option=[null, null, null, null, drop] +item=null, id=9264, option=[null, null, null, null, drop] +item=null, id=9265, option=[null, null, null, null, drop] +item=null, id=9266, option=[null, null, null, null, drop] +item=null, id=9267, option=[null, null, null, null, drop] +item=null, id=9268, option=[null, null, null, null, drop] +item=null, id=9269, option=[null, null, null, null, drop] +item=null, id=9270, option=[null, null, null, null, drop] +item=null, id=9271, option=[null, null, null, null, drop] +item=null, id=9272, option=[null, null, null, null, drop] +item=null, id=9273, option=[null, null, null, null, drop] +item=null, id=9274, option=[null, null, null, null, drop] +item=null, id=9275, option=[null, null, null, null, drop] +item=null, id=9276, option=[null, null, null, null, drop] +item=null, id=9277, option=[null, null, null, null, drop] +item=null, id=9278, option=[null, null, null, null, drop] +item=null, id=9279, option=[null, null, null, null, drop] +item=null, id=9280, option=[null, null, null, null, drop] +item=null, id=9281, option=[null, null, null, null, drop] +item=null, id=9282, option=[null, null, null, null, drop] +item=null, id=9283, option=[null, null, null, null, drop] +item=null, id=9284, option=[null, null, null, null, drop] +item=null, id=9285, option=[null, null, null, null, drop] +item=Blurite bolts(p), id=9286, option=[null, Wield, null, null, drop] +item=Iron bolts (p), id=9287, option=[null, Wield, null, null, drop] +item=Steel bolts (p), id=9288, option=[null, Wield, null, null, drop] +item=Mithril bolts (p), id=9289, option=[null, Wield, null, null, drop] +item=Addy bolts (p), id=9290, option=[null, Wield, null, null, drop] +item=Runite bolts (p), id=9291, option=[null, Wield, null, null, drop] +item=Silver bolts (p), id=9292, option=[null, Wield, null, null, drop] +item=Blurite bolts(p+), id=9293, option=[null, Wield, null, null, drop] +item=Iron bolts(p+), id=9294, option=[null, Wield, null, null, drop] +item=Steel bolts(p+), id=9295, option=[null, Wield, null, null, drop] +item=Mithril bolts(p+), id=9296, option=[null, Wield, null, null, drop] +item=Addy bolts(p+), id=9297, option=[null, Wield, null, null, drop] +item=Runite bolts(p+), id=9298, option=[null, Wield, null, null, drop] +item=Silver bolts(p+), id=9299, option=[null, Wield, null, null, drop] +item=Blurite bolts(p++), id=9300, option=[null, Wield, null, null, drop] +item=Iron bolts(p++), id=9301, option=[null, Wield, null, null, drop] +item=Steel bolts(p++), id=9302, option=[null, Wield, null, null, drop] +item=Mithril bolts(p++), id=9303, option=[null, Wield, null, null, drop] +item=Addy bolts(p++), id=9304, option=[null, Wield, null, null, drop] +item=Runite bolts(p++), id=9305, option=[null, Wield, null, null, drop] +item=Silver bolts(p++), id=9306, option=[null, Wield, null, null, drop] +item=null, id=9307, option=[null, null, null, null, drop] +item=null, id=9308, option=[null, null, null, null, drop] +item=null, id=9309, option=[null, null, null, null, drop] +item=null, id=9310, option=[null, null, null, null, drop] +item=null, id=9311, option=[null, null, null, null, drop] +item=null, id=9312, option=[null, null, null, null, drop] +item=null, id=9313, option=[null, null, null, null, drop] +item=null, id=9314, option=[null, null, null, null, drop] +item=null, id=9315, option=[null, null, null, null, drop] +item=null, id=9316, option=[null, null, null, null, drop] +item=null, id=9317, option=[null, null, null, null, drop] +item=null, id=9318, option=[null, null, null, null, drop] +item=null, id=9319, option=[null, null, null, null, drop] +item=null, id=9320, option=[null, null, null, null, drop] +item=null, id=9321, option=[null, null, null, null, drop] +item=null, id=9322, option=[null, null, null, null, drop] +item=null, id=9323, option=[null, null, null, null, drop] +item=null, id=9324, option=[null, null, null, null, drop] +item=null, id=9325, option=[null, null, null, null, drop] +item=null, id=9326, option=[null, null, null, null, drop] +item=null, id=9327, option=[null, null, null, null, drop] +item=null, id=9328, option=[null, null, null, null, drop] +item=null, id=9329, option=[null, null, null, null, drop] +item=null, id=9330, option=[null, null, null, null, drop] +item=null, id=9331, option=[null, null, null, null, drop] +item=null, id=9332, option=[null, null, null, null, drop] +item=null, id=9333, option=[null, null, null, null, drop] +item=null, id=9334, option=[null, null, null, null, drop] +item=Jade bolts, id=9335, option=[null, Wield, null, null, drop] +item=Topaz bolts, id=9336, option=[null, Wield, null, null, drop] +item=Sapphire bolts, id=9337, option=[null, Wield, null, null, drop] +item=Emerald bolts, id=9338, option=[null, Wield, null, null, drop] +item=Ruby bolts, id=9339, option=[null, Wield, null, null, drop] +item=Diamond bolts, id=9340, option=[null, Wield, null, null, drop] +item=Dragon bolts, id=9341, option=[null, Wield, null, null, drop] +item=Onyx bolts, id=9342, option=[null, Wield, null, null, drop] +item=null, id=9343, option=[null, null, null, null, drop] +item=null, id=9344, option=[null, null, null, null, drop] +item=null, id=9345, option=[null, null, null, null, drop] +item=null, id=9346, option=[null, null, null, null, drop] +item=null, id=9347, option=[null, null, null, null, drop] +item=null, id=9348, option=[null, null, null, null, drop] +item=null, id=9349, option=[null, null, null, null, drop] +item=null, id=9350, option=[null, null, null, null, drop] +item=null, id=9351, option=[null, null, null, null, drop] +item=null, id=9352, option=[null, null, null, null, drop] +item=null, id=9353, option=[null, null, null, null, drop] +item=null, id=9354, option=[null, null, null, null, drop] +item=null, id=9355, option=[null, null, null, null, drop] +item=null, id=9356, option=[null, null, null, null, drop] +item=null, id=9357, option=[null, null, null, null, drop] +item=null, id=9358, option=[null, null, null, null, drop] +item=null, id=9359, option=[null, null, null, null, drop] +item=null, id=9360, option=[null, null, null, null, drop] +item=null, id=9361, option=[null, null, null, null, drop] +item=null, id=9362, option=[null, null, null, null, drop] +item=null, id=9363, option=[null, null, null, null, drop] +item=null, id=9364, option=[null, null, null, null, drop] +item=null, id=9365, option=[null, null, null, null, drop] +item=null, id=9366, option=[null, null, null, null, drop] +item=null, id=9367, option=[null, null, null, null, drop] +item=null, id=9368, option=[null, null, null, null, drop] +item=null, id=9369, option=[null, null, null, null, drop] +item=null, id=9370, option=[null, null, null, null, drop] +item=null, id=9371, option=[null, null, null, null, drop] +item=null, id=9372, option=[null, null, null, null, drop] +item=null, id=9373, option=[null, null, null, null, drop] +item=null, id=9374, option=[null, null, null, null, drop] +item=Bronze bolts (unf), id=9375, option=[null, null, null, null, drop] +item=Blurite bolts (unf), id=9376, option=[null, null, null, null, drop] +item=Iron bolts (unf), id=9377, option=[null, null, null, null, drop] +item=Steel bolts (unf), id=9378, option=[null, null, null, null, drop] +item=Mithril bolts (unf), id=9379, option=[null, null, null, null, drop] +item=Adamant bolts(unf), id=9380, option=[null, null, null, null, drop] +item=Runite bolts (unf), id=9381, option=[null, null, null, null, drop] +item=Silver bolts (unf), id=9382, option=[null, null, null, null, drop] +item=null, id=9383, option=[null, null, null, null, drop] +item=null, id=9384, option=[null, null, null, null, drop] +item=null, id=9385, option=[null, null, null, null, drop] +item=null, id=9386, option=[null, null, null, null, drop] +item=null, id=9387, option=[null, null, null, null, drop] +item=null, id=9388, option=[null, null, null, null, drop] +item=null, id=9389, option=[null, null, null, null, drop] +item=null, id=9390, option=[null, null, null, null, drop] +item=null, id=9391, option=[null, null, null, null, drop] +item=null, id=9392, option=[null, null, null, null, drop] +item=null, id=9393, option=[null, null, null, null, drop] +item=null, id=9394, option=[null, null, null, null, drop] +item=null, id=9395, option=[null, null, null, null, drop] +item=null, id=9396, option=[null, null, null, null, drop] +item=null, id=9397, option=[null, null, null, null, drop] +item=null, id=9398, option=[null, null, null, null, drop] +item=null, id=9399, option=[null, null, null, null, drop] +item=null, id=9400, option=[null, null, null, null, drop] +item=null, id=9401, option=[null, null, null, null, drop] +item=null, id=9402, option=[null, null, null, null, drop] +item=null, id=9403, option=[null, null, null, null, drop] +item=null, id=9404, option=[null, null, null, null, drop] +item=null, id=9405, option=[null, null, null, null, drop] +item=null, id=9406, option=[null, null, null, null, drop] +item=null, id=9407, option=[null, null, null, null, drop] +item=null, id=9408, option=[null, null, null, null, drop] +item=null, id=9409, option=[null, null, null, null, drop] +item=null, id=9410, option=[null, null, null, null, drop] +item=null, id=9411, option=[null, null, null, null, drop] +item=null, id=9412, option=[null, null, null, null, drop] +item=null, id=9413, option=[null, null, null, null, drop] +item=null, id=9414, option=[null, null, null, null, drop] +item=Grapple, id=9415, option=[null, null, null, null, drop] +item=Mith grapple tip, id=9416, option=[null, null, null, null, drop] +item=Mith grapple tip, id=9417, option=[null, null, null, null, drop] +item=Mith grapple, id=9418, option=[null, null, null, null, drop] +item=Mith grapple, id=9419, option=[null, Wield, null, null, drop] +item=Bronze limbs, id=9420, option=[null, null, null, null, drop] +item=Bronze limbs, id=9421, option=[null, null, null, null, drop] +item=Blurite limbs, id=9422, option=[null, null, null, null, drop] +item=Iron limbs, id=9423, option=[null, null, null, null, drop] +item=Iron limbs, id=9424, option=[null, null, null, null, drop] +item=Steel limbs, id=9425, option=[null, null, null, null, drop] +item=Steel limbs, id=9426, option=[null, null, null, null, drop] +item=Mithril limbs, id=9427, option=[null, null, null, null, drop] +item=Mithril limbs, id=9428, option=[null, null, null, null, drop] +item=Adamantite limbs, id=9429, option=[null, null, null, null, drop] +item=Adamantite limbs, id=9430, option=[null, null, null, null, drop] +item=Runite limbs, id=9431, option=[null, null, null, null, drop] +item=Runite limbs, id=9432, option=[null, null, null, null, drop] +item=Bolt pouch, id=9433, option=[Open, null, null, null, Destroy] +item=Bolt mould, id=9434, option=[null, null, null, null, drop] +item=Bolt mould, id=9435, option=[null, null, null, null, drop] +item=Sinew, id=9436, option=[null, null, null, null, drop] +item=Sinew, id=9437, option=[null, null, null, null, drop] +item=Crossbow string, id=9438, option=[null, null, null, null, drop] +item=Crossbow string, id=9439, option=[null, null, null, null, drop] +item=Wooden stock, id=9440, option=[null, null, null, null, drop] +item=Wooden stock, id=9441, option=[null, null, null, null, drop] +item=Oak stock, id=9442, option=[null, null, null, null, drop] +item=Oak stock, id=9443, option=[null, null, null, null, drop] +item=Willow stock, id=9444, option=[null, null, null, null, drop] +item=Willow stock, id=9445, option=[null, null, null, null, drop] +item=Teak stock, id=9446, option=[null, null, null, null, drop] +item=Teak stock, id=9447, option=[null, null, null, null, drop] +item=Maple stock, id=9448, option=[null, null, null, null, drop] +item=Maple stock, id=9449, option=[null, null, null, null, drop] +item=Mahogany stock, id=9450, option=[null, null, null, null, drop] +item=Mahogany stock, id=9451, option=[null, null, null, null, drop] +item=Yew stock, id=9452, option=[null, null, null, null, drop] +item=Yew stock, id=9453, option=[null, null, null, null, drop] +item=Bronze c'bow (u), id=9454, option=[null, null, null, null, drop] +item=Bronze c'bow (u), id=9455, option=[null, null, null, null, drop] +item=Blurite c'bow (u), id=9456, option=[null, null, null, null, drop] +item=Iron c'bow (u), id=9457, option=[null, null, null, null, drop] +item=Iron c'bow (u), id=9458, option=[null, null, null, null, drop] +item=Steel c'bow (u), id=9459, option=[null, null, null, null, drop] +item=Steel c'bow (u), id=9460, option=[null, null, null, null, drop] +item=Mithril c'bow (u), id=9461, option=[null, null, null, null, drop] +item=Mithril c'bow (u), id=9462, option=[null, null, null, null, drop] +item=Adamant c'bow (u), id=9463, option=[null, null, null, null, drop] +item=Adamant c'bow (u), id=9464, option=[null, null, null, null, drop] +item=Runite c'bow (u), id=9465, option=[null, null, null, null, drop] +item=Runite c'bow (u), id=9466, option=[null, null, null, null, drop] +item=Blurite bar, id=9467, option=[null, null, null, null, drop] +item=Sawdust, id=9468, option=[null, null, null, null, drop] +item=Grand seed pod, id=9469, option=[Launch, null, Squash, null, drop] +item=Gnome scarf, id=9470, option=[null, Wear, null, null, drop] +item=Gnome scarf, id=9471, option=[null, null, null, null, drop] +item=Gnome goggles, id=9472, option=[null, Wear, null, null, drop] +item=Gnome goggles, id=9473, option=[null, null, null, null, drop] +item=Reward token, id=9474, option=[Check, null, Activate, null, Destroy] +item=Mint cake, id=9475, option=[Eat, null, null, null, drop] +item=Mint cake, id=9476, option=[null, null, null, null, drop] +item=Aluft aloft box, id=9477, option=[Check, null, null, null, drop] +item=Half made batta, id=9478, option=[null, null, null, null, drop] +item=Unfinished batta, id=9479, option=[null, null, null, null, drop] +item=Half made batta, id=9480, option=[null, null, null, null, drop] +item=Unfinished batta, id=9481, option=[null, null, null, null, drop] +item=Half made batta, id=9482, option=[null, null, null, null, drop] +item=Half made batta, id=9483, option=[null, null, null, null, drop] +item=Unfinished batta, id=9484, option=[null, null, null, null, drop] +item=Half made batta, id=9485, option=[null, null, null, null, drop] +item=Unfinished batta, id=9486, option=[null, null, null, null, drop] +item=Wizard blizzard, id=9487, option=[null, null, null, null, drop] +item=Wizard blizzard, id=9488, option=[null, null, null, null, drop] +item=Wizard blizzard, id=9489, option=[null, null, null, null, drop] +item=Cheat, id=9490, option=[null, null, null, null, drop] +item=null, id=9491, option=[null, null, null, null, drop] +item=null, id=9492, option=[null, null, null, null, drop] +item=null, id=9493, option=[null, null, null, null, drop] +item=null, id=9494, option=[null, null, null, null, drop] +item=null, id=9495, option=[null, null, null, null, drop] +item=null, id=9496, option=[null, null, null, null, drop] +item=null, id=9497, option=[null, null, null, null, drop] +item=null, id=9498, option=[null, null, null, null, drop] +item=null, id=9499, option=[null, null, null, null, drop] +item=null, id=9500, option=[null, null, null, null, drop] +item=null, id=9501, option=[null, null, null, null, drop] +item=null, id=9502, option=[null, null, null, null, drop] +item=null, id=9503, option=[null, null, null, null, drop] +item=null, id=9504, option=[null, null, null, null, drop] +item=null, id=9505, option=[null, null, null, null, drop] +item=null, id=9506, option=[null, null, null, null, drop] +item=null, id=9507, option=[null, null, null, null, drop] +item=Wizard blizzard, id=9508, option=[Drink, Empty, null, null, drop] +item=Wizard blizzard, id=9509, option=[null, null, null, null, drop] +item=Short green guy, id=9510, option=[Drink, Empty, null, null, drop] +item=Short green guy, id=9511, option=[null, null, null, null, drop] +item=Pineapple punch, id=9512, option=[Drink, Empty, null, null, drop] +item=Pineapple punch, id=9513, option=[null, null, null, null, drop] +item=Fruit blast, id=9514, option=[Drink, Empty, null, null, drop] +item=Fruit blast, id=9515, option=[null, null, null, null, drop] +item=Drunk dragon, id=9516, option=[Drink, Empty, null, null, drop] +item=Drunk dragon, id=9517, option=[null, null, null, null, drop] +item=Choc saturday, id=9518, option=[Drink, Empty, null, null, drop] +item=Choc saturday, id=9519, option=[null, null, null, null, drop] +item=Blurberry special, id=9520, option=[Drink, Empty, null, null, drop] +item=Blurberry special, id=9521, option=[null, null, null, null, drop] +item=Batta tin, id=9522, option=[null, null, null, null, drop] +item=Batta tin, id=9523, option=[null, null, null, null, drop] +item=Batta tin, id=9524, option=[null, null, null, null, drop] +item=Batta tin, id=9525, option=[null, null, null, null, drop] +item=null, id=9526, option=[null, null, null, null, drop] +item=Fruit batta, id=9527, option=[Eat, null, null, null, drop] +item=Fruit batta, id=9528, option=[null, null, null, null, drop] +item=Toad batta, id=9529, option=[Eat, null, null, null, drop] +item=Toad batta, id=9530, option=[null, null, null, null, drop] +item=Worm batta, id=9531, option=[Eat, null, null, null, drop] +item=Worm batta, id=9532, option=[null, null, null, null, drop] +item=Vegetable batta, id=9533, option=[Eat, null, null, null, drop] +item=Vegetable batta, id=9534, option=[null, null, null, null, drop] +item=Cheese+tom batta, id=9535, option=[Eat, null, null, null, drop] +item=Cheese+tom batta, id=9536, option=[null, null, null, null, drop] +item=null, id=9537, option=[null, null, null, null, drop] +item=Toad crunchies, id=9538, option=[Eat, null, null, null, drop] +item=Toad crunchies, id=9539, option=[null, null, null, null, drop] +item=Spicy crunchies, id=9540, option=[Eat, null, null, null, drop] +item=Spicy crunchies, id=9541, option=[null, null, null, null, drop] +item=Worm crunchies, id=9542, option=[Eat, null, null, null, drop] +item=Worm crunchies, id=9543, option=[null, null, null, null, drop] +item=Chocchip crunchies, id=9544, option=[Eat, null, null, null, drop] +item=Chocchip crunchies, id=9545, option=[null, null, null, null, drop] +item=null, id=9546, option=[null, null, null, null, drop] +item=Worm hole, id=9547, option=[Eat, null, null, null, drop] +item=Worm hole, id=9548, option=[null, null, null, null, drop] +item=Veg ball, id=9549, option=[Eat, null, null, null, drop] +item=Veg ball, id=9550, option=[null, null, null, null, drop] +item=Tangled toads' legs, id=9551, option=[Eat, null, null, null, drop] +item=Tangled toads' legs, id=9552, option=[null, null, null, null, drop] +item=Chocolate bomb, id=9553, option=[Eat, null, null, null, drop] +item=Chocolate bomb, id=9554, option=[null, null, null, null, drop] +item=null, id=9555, option=[null, null, null, null, drop] +item=null, id=9556, option=[null, null, null, null, drop] +item=null, id=9557, option=[null, null, null, null, drop] +item=Half made bowl, id=9558, option=[null, null, null, null, drop] +item=Half made bowl, id=9559, option=[null, null, null, null, drop] +item=Unfinished bowl, id=9560, option=[null, null, null, null, drop] +item=Half made bowl, id=9561, option=[null, null, null, null, drop] +item=Unfinished bowl, id=9562, option=[null, null, null, null, drop] +item=Half made bowl, id=9563, option=[null, null, null, null, drop] +item=Unfinished bowl, id=9564, option=[null, null, null, null, drop] +item=Cocktail shaker, id=9565, option=[null, null, null, null, drop] +item=Mixed blizzard, id=9566, option=[Pour, null, null, null, drop] +item=Mixed sgg, id=9567, option=[Pour, null, null, null, drop] +item=Mixed blast, id=9568, option=[Pour, null, null, null, drop] +item=Mixed punch, id=9569, option=[Pour, null, null, null, drop] +item=Mixed blurberry special, id=9570, option=[Pour, null, null, null, drop] +item=Mixed saturday, id=9571, option=[Pour, null, null, null, drop] +item=Mixed saturday, id=9572, option=[null, null, null, null, drop] +item=Mixed saturday, id=9573, option=[Add-ingreds, null, null, null, drop] +item=Mixed dragon, id=9574, option=[Pour, null, null, null, drop] +item=Mixed dragon, id=9575, option=[Add-ingreds, null, null, null, drop] +item=Mixed dragon, id=9576, option=[null, null, null, null, drop] +item=Half made crunchy, id=9577, option=[null, null, null, null, drop] +item=Unfinished crunchy, id=9578, option=[null, null, null, null, drop] +item=Half made crunchy, id=9579, option=[null, null, null, null, drop] +item=Unfinished crunchy, id=9580, option=[null, null, null, null, drop] +item=Half made crunchy, id=9581, option=[null, null, null, null, drop] +item=Unfinished crunchy, id=9582, option=[null, null, null, null, drop] +item=Half made crunchy, id=9583, option=[null, null, null, null, drop] +item=Unfinished crunchy, id=9584, option=[null, null, null, null, drop] +item=Batta tin, id=9585, option=[null, null, null, null, drop] +item=Crunchy tray, id=9586, option=[null, null, null, null, drop] +item=Gnomebowl mould, id=9587, option=[null, null, null, null, drop] +item=Raw crunchies, id=9588, option=[null, null, null, null, drop] +item=Dossier, id=9589, option=[Read, null, null, null, Destroy] +item=Dossier, id=9590, option=[null, null, null, null, drop] +item=Broken cauldron, id=9591, option=[null, null, null, null, drop] +item=Magic glue, id=9592, option=[null, null, null, Empty, drop] +item=Weird gloop, id=9593, option=[null, null, null, Empty, drop] +item=Ground mud runes, id=9594, option=[null, null, null, null, drop] +item=Hazelmere's book, id=9595, option=[Read, null, null, null, drop] +item=Eyeglo null, id=9596, option=[null, null, null, null, drop] +item=Red circle, id=9597, option=[null, null, null, null, drop] +item=Red triangle, id=9598, option=[null, null, null, null, drop] +item=Red square, id=9599, option=[null, null, null, null, drop] +item=Red pentagon, id=9600, option=[null, null, null, null, drop] +item=Orange circle, id=9601, option=[null, null, null, null, drop] +item=Orange triangle, id=9602, option=[null, null, null, null, drop] +item=Orange square, id=9603, option=[null, null, null, null, drop] +item=Orange pentagon, id=9604, option=[null, null, null, null, drop] +item=Yellow circle, id=9605, option=[null, null, null, null, drop] +item=Yellow triangle, id=9606, option=[null, null, null, null, drop] +item=Yellow square, id=9607, option=[null, null, null, null, drop] +item=Yellow pentagon, id=9608, option=[null, null, null, null, drop] +item=Green circle, id=9609, option=[null, null, null, null, drop] +item=Green triangle, id=9610, option=[null, null, null, null, drop] +item=Green square, id=9611, option=[null, null, null, null, drop] +item=Green pentagon, id=9612, option=[null, null, null, null, drop] +item=Blue circle, id=9613, option=[null, null, null, null, drop] +item=Blue triangle, id=9614, option=[null, null, null, null, drop] +item=Blue square, id=9615, option=[null, null, null, null, drop] +item=Blue pentagon, id=9616, option=[null, null, null, null, drop] +item=Indigo circle, id=9617, option=[null, null, null, null, drop] +item=Indigo triangle, id=9618, option=[null, null, null, null, drop] +item=Indigo square, id=9619, option=[null, null, null, null, drop] +item=Indigo pentagon, id=9620, option=[null, null, null, null, drop] +item=Violet circle, id=9621, option=[null, null, null, null, drop] +item=Violet triangle, id=9622, option=[null, null, null, null, drop] +item=Violet square, id=9623, option=[null, null, null, null, drop] +item=Violet pentagon, id=9624, option=[null, null, null, null, drop] +item=Crystal saw, id=9625, option=[null, null, null, Check-charges, Destroy] +item=Small crystal seed, id=9626, option=[null, null, null, null, Destroy] +item=A handwritten book, id=9627, option=[Read, null, null, null, drop] +item=null, id=9628, option=[null, null, null, null, drop] +item=Tyras helm, id=9629, option=[null, Wear, null, null, drop] +item=Tyras helm, id=9630, option=[null, null, null, null, drop] +item=null, id=9631, option=[null, null, null, null, drop] +item=Daeyalt ore, id=9632, option=[null, null, null, null, drop] +item=Message, id=9633, option=[Read, null, null, null, Destroy] +item=Vyrewatch top, id=9634, option=[null, Wear, null, null, drop] +item=Vyrewatch top, id=9635, option=[null, null, null, null, drop] +item=Vyrewatch legs, id=9636, option=[null, Wear, null, null, drop] +item=Vyrewatch legs, id=9637, option=[null, null, null, null, drop] +item=Vyrewatch shoes, id=9638, option=[null, Wear, null, null, drop] +item=Vyrewatch shoes, id=9639, option=[null, null, null, null, drop] +item=Citizen top, id=9640, option=[null, Wear, null, null, drop] +item=Citizen top, id=9641, option=[null, null, null, null, drop] +item=Citizen trousers, id=9642, option=[null, Wear, null, null, drop] +item=Citizen trousers, id=9643, option=[null, null, null, null, drop] +item=Citizen shoes, id=9644, option=[null, Wear, null, null, drop] +item=Citizen shoes, id=9645, option=[null, null, null, null, drop] +item=Castle sketch 1, id=9646, option=[null, Look-at, null, null, Destroy] +item=Castle sketch 2, id=9647, option=[null, Look-at, null, null, Destroy] +item=Castle sketch 3, id=9648, option=[null, Look-at, null, null, Destroy] +item=Message, id=9649, option=[Read, null, null, null, Destroy] +item=Blood tithe pouch, id=9650, option=[null, null, null, null, drop] +item=Large ornate key, id=9651, option=[null, null, null, null, Destroy] +item=Haemalchemy, id=9652, option=[Read, null, null, null, Destroy] +item=Sealed message, id=9653, option=[Read, null, null, null, Destroy] +item=Door key, id=9654, option=[null, null, null, null, Destroy] +item=Ladder top, id=9655, option=[null, null, null, null, Destroy] +item=Tome of xp (3), id=9656, option=[Read, null, null, null, Destroy] +item=Tome of xp (2), id=9657, option=[Read, null, null, null, Destroy] +item=Tome of xp (1), id=9658, option=[Read, null, null, null, Destroy] +item=Bucket of water, id=9659, option=[null, null, null, Empty, Destroy] +item=Bucket, id=9660, option=[null, null, null, null, Destroy] +item=null, id=9661, option=[null, null, null, null, drop] +item=Shortcut key, id=9662, option=[null, null, null, null, Destroy] +item=null, id=9663, option=[null, null, null, null, drop] +item=null, id=9664, option=[null, null, null, null, drop] +item=Torch, id=9665, option=[null, Wield, null, null, drop] +item=Pros'yte harness m, id=9666, option=[Unpack, null, null, null, drop] +item=Pros'yte harness m, id=9667, option=[null, null, null, null, drop] +item=Initiate harness m, id=9668, option=[Unpack, null, null, null, drop] +item=Initiate harness m, id=9669, option=[null, null, null, null, drop] +item=Pros'yte harness f, id=9670, option=[Unpack, null, null, null, drop] +item=Pros'yte harness f, id=9671, option=[null, null, null, null, drop] +item=Proselyte sallet, id=9672, option=[null, Wear, null, null, drop] +item=Proselyte sallet, id=9673, option=[null, null, null, null, drop] +item=Proselyte hauberk, id=9674, option=[null, Wear, null, null, drop] +item=Proselyte hauberk, id=9675, option=[null, null, null, null, drop] +item=Proselyte cuisse, id=9676, option=[null, Wear, null, null, drop] +item=Proselyte cuisse, id=9677, option=[null, null, null, null, drop] +item=Proselyte tasset, id=9678, option=[null, Wear, null, null, drop] +item=Proselyte tasset, id=9679, option=[null, null, null, null, drop] +item=Sea slug glue, id=9680, option=[null, null, null, null, drop] +item=Commorb v2, id=9681, option=[Scan, Contact, null, Playback, drop] +item=Door transcription, id=9682, option=[null, null, null, null, Destroy] +item=Dead sea slug, id=9683, option=[null, null, null, null, drop] +item=Page 1, id=9684, option=[Read, Shape-Earth, Shape-Air, null, Destroy] +item=Page 2, id=9685, option=[Read, Shape-Fire, Shape-Water, null, Destroy] +item=Page 3, id=9686, option=[Read, Shape-Mind, null, null, Destroy] +item=Fragment 1, id=9687, option=[null, null, null, null, Destroy] +item=Fragment 2, id=9688, option=[null, null, null, null, Destroy] +item=Fragment 3, id=9689, option=[null, null, null, null, Destroy] +item=Blank water rune, id=9690, option=[null, null, null, null, Destroy] +item=Water rune, id=9691, option=[null, null, null, null, Destroy] +item=Blank air rune, id=9692, option=[null, null, null, null, Destroy] +item=Air rune, id=9693, option=[null, null, null, null, Destroy] +item=Blank earth rune, id=9694, option=[null, null, null, null, Destroy] +item=Earth rune, id=9695, option=[null, null, null, null, Destroy] +item=Blank mind rune, id=9696, option=[null, null, null, null, Destroy] +item=Mind rune, id=9697, option=[null, null, null, null, Destroy] +item=Blank fire rune, id=9698, option=[null, null, null, null, Destroy] +item=Fire rune, id=9699, option=[null, null, null, null, Destroy] +item=Qc dummy, id=9700, option=[null, null, null, null, drop] +item=Torch, id=9701, option=[null, null, null, null, drop] +item=Stick, id=9702, option=[null, Wield, null, null, Destroy] +item=Training sword, id=9703, option=[null, Wield, null, null, Destroy] +item=Training shield, id=9704, option=[null, Wear, null, null, Destroy] +item=Training bow, id=9705, option=[null, Wield, null, null, Destroy] +item=Training arrows, id=9706, option=[null, Wield, null, null, Destroy] +item=null, id=9707, option=[null, null, null, null, drop] +item=null, id=9708, option=[null, null, null, null, drop] +item=null, id=9709, option=[null, null, null, null, drop] +item=null, id=9710, option=[null, null, null, null, drop] +item=null, id=9711, option=[null, null, null, null, drop] +item=null, id=9712, option=[null, null, null, null, drop] +item=null, id=9713, option=[null, null, null, null, drop] +item=null, id=9714, option=[null, null, null, null, drop] +item=Slashed book, id=9715, option=[Read, null, null, null, drop] +item=Rock, id=9716, option=[null, null, null, null, drop] +item=Beaten book, id=9717, option=[Read, null, null, null, drop] +item=Crane schematic, id=9718, option=[Read, null, null, null, drop] +item=Lever schematic, id=9719, option=[Read, null, null, null, drop] +item=Crane claw, id=9720, option=[null, null, null, null, drop] +item=Scroll, id=9721, option=[Read, null, null, null, drop] +item=Key, id=9722, option=[null, null, null, null, drop] +item=Pipe, id=9723, option=[null, null, null, null, drop] +item=Large cog, id=9724, option=[null, null, null, null, drop] +item=Medium cog, id=9725, option=[null, null, null, null, drop] +item=Small cog, id=9726, option=[null, null, null, null, drop] +item=Primed bar, id=9727, option=[null, null, null, null, drop] +item=Elemental mind bar, id=9728, option=[null, null, null, null, drop] +item=Elemental helmet, id=9729, option=[null, Equip, null, null, drop] +item=Elemental helmet, id=9730, option=[null, null, null, null, drop] +item=Mind shield, id=9731, option=[null, Wield, null, null, drop] +item=Mind shield, id=9732, option=[null, null, null, null, drop] +item=Mind helmet, id=9733, option=[null, Equip, null, null, drop] +item=Mind helmet, id=9734, option=[null, null, null, null, drop] +item=Desert goat horn, id=9735, option=[null, null, null, null, drop] +item=Goat horn dust, id=9736, option=[null, null, null, null, drop] +item=Goat horn dust, id=9737, option=[null, null, null, null, drop] +item=Desert goat horn, id=9738, option=[null, null, null, null, drop] +item=Combat potion(4), id=9739, option=[Drink, null, null, Empty, drop] +item=Combat potion(4), id=9740, option=[null, null, null, null, drop] +item=Combat potion(3), id=9741, option=[Drink, null, null, Empty, drop] +item=Combat potion(3), id=9742, option=[null, null, null, null, drop] +item=Combat potion(2), id=9743, option=[Drink, null, null, Empty, drop] +item=Combat potion(2), id=9744, option=[null, null, null, null, drop] +item=Combat potion(1), id=9745, option=[Drink, null, null, Empty, drop] +item=Combat potion(1), id=9746, option=[null, null, null, null, drop] +item=Attack cape, id=9747, option=[null, Wear, null, null, drop] +item=Attack cape(t), id=9748, option=[null, Wear, null, null, drop] +item=Attack hood, id=9749, option=[null, Wear, null, null, drop] +item=Strength cape, id=9750, option=[null, Wear, null, null, drop] +item=Strength cape(t), id=9751, option=[null, Wear, null, null, drop] +item=Strength hood, id=9752, option=[null, Wear, null, null, drop] +item=Defence cape, id=9753, option=[null, Wear, null, null, drop] +item=Defence cape(t), id=9754, option=[null, Wear, null, null, drop] +item=Defence hood, id=9755, option=[null, Wear, null, null, drop] +item=Ranging cape, id=9756, option=[null, Wear, null, null, drop] +item=Ranging cape(t), id=9757, option=[null, Wear, null, null, drop] +item=Ranging hood, id=9758, option=[null, Wear, null, null, drop] +item=Prayer cape, id=9759, option=[null, Wear, null, null, drop] +item=Prayer cape(t), id=9760, option=[null, Wear, null, null, drop] +item=Prayer hood, id=9761, option=[null, Wear, null, null, drop] +item=Magic cape, id=9762, option=[null, Wear, null, null, drop] +item=Magic cape(t), id=9763, option=[null, Wear, null, null, drop] +item=Magic hood, id=9764, option=[null, Wear, null, null, drop] +item=Runecraft cape, id=9765, option=[null, Wear, null, null, drop] +item=Runecraft cape(t), id=9766, option=[null, Wear, null, null, drop] +item=Runecrafting hood, id=9767, option=[null, Wear, null, null, drop] +item=Hitpoints cape, id=9768, option=[null, Wear, null, null, drop] +item=Hitpoints cape(t), id=9769, option=[null, Wear, null, null, drop] +item=Hitpoints hood, id=9770, option=[null, Wear, null, null, drop] +item=Agility cape, id=9771, option=[null, Wear, null, null, drop] +item=Agility cape(t), id=9772, option=[null, Wear, null, null, drop] +item=Agility hood, id=9773, option=[null, Wear, null, null, drop] +item=Herblore cape, id=9774, option=[null, Wear, null, null, drop] +item=Herblore cape(t), id=9775, option=[null, Wear, null, null, drop] +item=Herblore hood, id=9776, option=[null, Wear, null, null, drop] +item=Thieving cape, id=9777, option=[null, Wear, null, null, drop] +item=Thieving cape(t), id=9778, option=[null, Wear, null, null, drop] +item=Thieving hood, id=9779, option=[null, Wear, null, null, drop] +item=Crafting cape, id=9780, option=[null, Wear, null, null, drop] +item=Crafting cape(t), id=9781, option=[null, Wear, null, null, drop] +item=Crafting hood, id=9782, option=[null, Wear, null, null, drop] +item=Fletching cape, id=9783, option=[null, Wear, null, null, drop] +item=Fletching cape(t), id=9784, option=[null, Wear, null, null, drop] +item=Fletching hood, id=9785, option=[null, Wear, null, null, drop] +item=Slayer cape, id=9786, option=[null, Wear, null, null, drop] +item=Slayer cape(t), id=9787, option=[null, Wear, null, null, drop] +item=Slayer hood, id=9788, option=[null, Wear, null, null, drop] +item=Construct. cape, id=9789, option=[null, Wear, null, null, drop] +item=Construct. cape(t), id=9790, option=[null, Wear, null, null, drop] +item=Construct. hood, id=9791, option=[null, Wear, null, null, drop] +item=Mining cape, id=9792, option=[null, Wear, null, null, drop] +item=Mining cape(t), id=9793, option=[null, Wear, null, null, drop] +item=Mining hood, id=9794, option=[null, Wear, null, null, drop] +item=Smithing cape, id=9795, option=[null, Wear, null, null, drop] +item=Smithing cape(t), id=9796, option=[null, Wear, null, null, drop] +item=Smithing hood, id=9797, option=[null, Wear, null, null, drop] +item=Fishing cape, id=9798, option=[null, Wear, null, null, drop] +item=Fishing cape(t), id=9799, option=[null, Wear, null, null, drop] +item=Fishing hood, id=9800, option=[null, Wear, null, null, drop] +item=Cooking cape, id=9801, option=[null, Wear, null, null, drop] +item=Cooking cape(t), id=9802, option=[null, Wear, null, null, drop] +item=Cooking hood, id=9803, option=[null, Wear, null, null, drop] +item=Firemaking cape, id=9804, option=[null, Wear, null, null, drop] +item=Firemaking cape(t), id=9805, option=[null, Wear, null, null, drop] +item=Firemaking hood, id=9806, option=[null, Wear, null, null, drop] +item=Woodcutting cape, id=9807, option=[null, Wear, null, null, drop] +item=Woodcut. cape(t), id=9808, option=[null, Wear, null, null, drop] +item=Woodcutting hood, id=9809, option=[null, Wear, null, null, drop] +item=Farming cape, id=9810, option=[null, Wear, null, null, drop] +item=Farming cape(t), id=9811, option=[null, Wear, null, null, drop] +item=Farming hood, id=9812, option=[null, Wear, null, null, drop] +item=Quest point cape, id=9813, option=[null, Wear, null, null, drop] +item=Quest point hood, id=9814, option=[null, Wear, null, null, drop] +item=Bobble hat, id=9815, option=[null, null, null, null, drop] +item=Bobble scarf, id=9816, option=[null, null, null, null, drop] +item=Oak cape rack, id=9817, option=[null, null, null, null, drop] +item=Teak cape rack, id=9818, option=[null, null, null, null, drop] +item=M'gany cape rack, id=9819, option=[null, null, null, null, drop] +item=Gilded cape rack, id=9820, option=[null, null, null, null, drop] +item=Marble cape rack, id=9821, option=[null, null, null, null, drop] +item=Magical cape rack, id=9822, option=[null, null, null, null, drop] +item=Oak costume box, id=9823, option=[null, null, null, null, drop] +item=Teak costume box, id=9824, option=[null, null, null, null, drop] +item=Mahogany cos box, id=9825, option=[null, null, null, null, drop] +item=Oak armour case, id=9826, option=[null, null, null, null, drop] +item=Teak armour case, id=9827, option=[null, null, null, null, drop] +item=M'gany arm'r case, id=9828, option=[null, null, null, null, drop] +item=Oak magic wardrobe, id=9829, option=[null, null, null, null, drop] +item=Carved oak magic wardrobe, id=9830, option=[null, null, null, null, drop] +item=Teak magic wardrobe, id=9831, option=[null, null, null, null, drop] +item=Carved teak magic wardrobe, id=9832, option=[null, null, null, null, drop] +item=Mahogany magic wardrobe, id=9833, option=[null, null, null, null, drop] +item=Gilded magic wardrobe, id=9834, option=[null, null, null, null, drop] +item=Marble magic wardrobe, id=9835, option=[null, null, null, null, drop] +item=Oak toy box, id=9836, option=[null, null, null, null, drop] +item=Teak toy box, id=9837, option=[null, null, null, null, drop] +item=Mahogany toy box, id=9838, option=[null, null, null, null, drop] +item=Oak treasure chest, id=9839, option=[null, null, null, null, drop] +item=Teak treas' chest, id=9840, option=[null, null, null, null, drop] +item=M'gany treas' chest, id=9841, option=[null, null, null, null, drop] +item=Costume room, id=9842, option=[null, null, null, null, drop] +item=Oak cape rack, id=9843, option=[null, null, null, null, drop] +item=Teak cape rack, id=9844, option=[null, null, null, null, drop] +item=M'gany cape rack, id=9845, option=[null, null, null, null, drop] +item=Gilded cape rack, id=9846, option=[null, null, null, null, drop] +item=Marble cape rack, id=9847, option=[null, null, null, null, drop] +item=Magical cape rack, id=9848, option=[null, null, null, null, drop] +item=Oak toy box, id=9849, option=[null, null, null, null, drop] +item=Teak toy box, id=9850, option=[null, null, null, null, drop] +item=Mahogany toy box, id=9851, option=[null, null, null, null, drop] +item=Oak magic wardrobe, id=9852, option=[null, null, null, null, drop] +item=Carved oak magic wardrobe, id=9853, option=[null, null, null, null, drop] +item=Teak magic wardrobe, id=9854, option=[null, null, null, null, drop] +item=Carved teak magic wardrobe, id=9855, option=[null, null, null, null, drop] +item=Mahogany magic wardrobe, id=9856, option=[null, null, null, null, drop] +item=Gilded magic wardrobe, id=9857, option=[null, null, null, null, drop] +item=Marble magic wardrobe, id=9858, option=[null, null, null, null, drop] +item=Oak armour case, id=9859, option=[null, null, null, null, drop] +item=Teak armour case, id=9860, option=[null, null, null, null, drop] +item=M'gany arm'r case, id=9861, option=[null, null, null, null, drop] +item=Oak treasure chest, id=9862, option=[null, null, null, null, drop] +item=Teak treas' chest, id=9863, option=[null, null, null, null, drop] +item=M'gany treas' chest, id=9864, option=[null, null, null, null, drop] +item=Oak costume box, id=9865, option=[null, null, null, null, drop] +item=Teak costume box, id=9866, option=[null, null, null, null, drop] +item=Mahogany cos box, id=9867, option=[null, null, null, null, drop] +item=Oak cape rack, id=9868, option=[null, null, null, null, drop] +item=Teak cape rack, id=9869, option=[null, null, null, null, drop] +item=M'gany cape rack, id=9870, option=[null, null, null, null, drop] +item=Gilded cape rack, id=9871, option=[null, null, null, null, drop] +item=Marble cape rack, id=9872, option=[null, null, null, null, drop] +item=Magical cape rack, id=9873, option=[null, null, null, null, drop] +item=Oak toy box, id=9874, option=[null, null, null, null, drop] +item=Teak toy box, id=9875, option=[null, null, null, null, drop] +item=Mahogany toy box, id=9876, option=[null, null, null, null, drop] +item=Oak magic wardrobe, id=9877, option=[null, null, null, null, drop] +item=Carved oak magic wardrobe, id=9878, option=[null, null, null, null, drop] +item=Teak magic wardrobe, id=9879, option=[null, null, null, null, drop] +item=Carved teak magic wardrobe, id=9880, option=[null, null, null, null, drop] +item=Mahogany magic wardrobe, id=9881, option=[null, null, null, null, drop] +item=Gilded magic wardrobe, id=9882, option=[null, null, null, null, drop] +item=Marble magic wardrobe, id=9883, option=[null, null, null, null, drop] +item=Oak armour case, id=9884, option=[null, null, null, null, drop] +item=Teak armour case, id=9885, option=[null, null, null, null, drop] +item=M'gany arm'r case, id=9886, option=[null, null, null, null, drop] +item=Oak treasure chest, id=9887, option=[null, null, null, null, drop] +item=Teak treas' chest, id=9888, option=[null, null, null, null, drop] +item=M'gany treas' chest, id=9889, option=[null, null, null, null, drop] +item=Oak costume box, id=9890, option=[null, null, null, null, drop] +item=Teak costume box, id=9891, option=[null, null, null, null, drop] +item=Mahogany cos box, id=9892, option=[null, null, null, null, drop] +item=null, id=9893, option=[null, null, null, null, drop] +item=null, id=9894, option=[null, null, null, null, drop] +item=null, id=9895, option=[null, null, null, null, drop] +item=null, id=9896, option=[null, null, null, null, drop] +item=null, id=9897, option=[null, null, null, null, drop] +item=null, id=9898, option=[null, null, null, null, drop] +item=null, id=9899, option=[null, null, null, null, drop] +item=null, id=9900, option=[null, null, null, null, drop] +item=Goutweedy lump, id=9901, option=[null, null, null, null, Destroy] +item=Hardy gout tubers, id=9902, option=[null, null, null, null, Destroy] +item=Farming manual, id=9903, option=[Read, null, null, null, Destroy] +item=Sailing book, id=9904, option=[null, null, null, null, drop] +item=null, id=9905, option=[null, null, null, null, drop] +item=Ghost buster 500, id=9906, option=[null, Wield, Empty, null, Destroy] +item=Ghost buster 500, id=9907, option=[null, Wield, Empty, null, Destroy] +item=Ghost buster 500, id=9908, option=[null, Wield, Empty, null, Destroy] +item=Ghost buster 500, id=9909, option=[null, Wield, Empty, null, Destroy] +item=Ghost buster 500, id=9910, option=[null, Wield, Empty, null, Destroy] +item=Ghost buster 500, id=9911, option=[null, Wield, Empty, null, Destroy] +item=Ghost buster 500, id=9912, option=[null, null, null, null, Destroy] +item=White destabiliser, id=9913, option=[null, null, null, Load, Destroy] +item=Red destabiliser, id=9914, option=[null, null, null, Load, Destroy] +item=Blue destabiliser, id=9915, option=[null, null, null, Load, Destroy] +item=Green destabiliser, id=9916, option=[null, null, null, Load, Destroy] +item=Yellow destabiliser, id=9917, option=[null, null, null, Load, Destroy] +item=Black destabiliser, id=9918, option=[null, null, null, Load, Destroy] +item=Evil root, id=9919, option=[null, null, null, null, Destroy] +item=Jack lantern mask, id=9920, option=[null, Wear, null, null, Destroy] +item=Skeleton boots, id=9921, option=[null, Wear, null, null, Destroy] +item=Skeleton gloves, id=9922, option=[null, Wear, null, null, Destroy] +item=Skeleton leggings, id=9923, option=[null, Wear, null, null, Destroy] +item=Skeleton shirt, id=9924, option=[null, Wear, null, null, Destroy] +item=Skeleton mask, id=9925, option=[null, Wear, null, null, Destroy] +item=null, id=9926, option=[null, null, null, null, drop] +item=null, id=9927, option=[null, null, null, null, drop] +item=null, id=9928, option=[null, null, null, null, drop] +item=null, id=9929, option=[null, null, null, null, drop] +item=null, id=9930, option=[null, null, null, null, drop] +item=null, id=9931, option=[null, null, null, null, drop] +item=Auguste's sapling, id=9932, option=[null, null, null, null, Destroy] +item=Balloon structure, id=9933, option=[null, null, null, null, drop] +item=Origami balloon, id=9934, option=[null, null, null, null, drop] +item=Yellow balloon, id=9935, option=[null, null, null, null, drop] +item=Blue balloon, id=9936, option=[null, null, null, null, drop] +item=Red balloon, id=9937, option=[null, null, null, null, drop] +item=Orange balloon, id=9938, option=[null, null, null, null, drop] +item=Green balloon, id=9939, option=[null, null, null, null, drop] +item=Purple balloon, id=9940, option=[null, null, null, null, drop] +item=Pink balloon, id=9941, option=[null, null, null, null, drop] +item=Black balloon, id=9942, option=[null, null, null, null, drop] +item=Sandbag, id=9943, option=[null, null, null, Empty, drop] +item=Bomber jacket, id=9944, option=[null, Wear, null, null, Destroy] +item=Bomber cap, id=9945, option=[null, Wear, null, null, Destroy] +item=Cap and goggles, id=9946, option=[null, Wear, null, Split, drop] +item=Old red disk, id=9947, option=[null, null, null, null, Destroy] +item=Hunter cape, id=9948, option=[null, Wear, null, null, drop] +item=Hunter cape(t), id=9949, option=[null, Wear, null, null, drop] +item=Hunter hood, id=9950, option=[null, Wear, null, null, drop] +item=Footprint, id=9951, option=[null, null, null, null, drop] +item=Imp, id=9952, option=[null, null, null, null, drop] +item=Kebbit, id=9953, option=[null, null, null, null, drop] +item=Kebbit, id=9954, option=[null, null, null, null, drop] +item=Kebbit, id=9955, option=[null, null, null, null, drop] +item=Kebbit, id=9956, option=[null, null, null, null, drop] +item=Kebbit, id=9957, option=[null, null, null, null, drop] +item=Kebbit, id=9958, option=[null, null, null, null, drop] +item=Kebbit, id=9959, option=[null, null, null, null, drop] +item=Kebbit, id=9960, option=[null, null, null, null, drop] +item=Kebbit, id=9961, option=[null, null, null, null, drop] +item=Kebbit, id=9962, option=[null, null, null, null, drop] +item=Kebbit, id=9963, option=[null, null, null, null, drop] +item=Kebbit, id=9964, option=[null, null, null, null, drop] +item=Crimson swift, id=9965, option=[null, null, null, null, drop] +item=Copper longtail, id=9966, option=[null, null, null, null, drop] +item=Cerulean twitch, id=9967, option=[null, null, null, null, drop] +item=Golden warbler, id=9968, option=[null, null, null, null, drop] +item=Tropical wagtail, id=9969, option=[null, null, null, null, drop] +item=Butterfly, id=9970, option=[null, null, null, null, drop] +item=Butterfly, id=9971, option=[null, null, null, null, drop] +item=Butterfly, id=9972, option=[null, null, null, null, drop] +item=Butterfly, id=9973, option=[null, null, null, null, drop] +item=Giant eagle, id=9974, option=[null, null, null, null, drop] +item=Rabbit, id=9975, option=[null, null, null, null, drop] +item=Chinchompa, id=9976, option=[null, null, null, null, drop] +item=Red chinchompa, id=9977, option=[null, null, null, null, drop] +item=Raw bird meat, id=9978, option=[null, null, null, null, drop] +item=Raw bird meat, id=9979, option=[null, null, null, null, drop] +item=Roast bird meat, id=9980, option=[Eat, null, null, null, drop] +item=Roast bird meat, id=9981, option=[null, null, null, null, drop] +item=Burnt bird meat, id=9982, option=[null, null, null, null, drop] +item=Burnt bird meat, id=9983, option=[null, null, null, null, drop] +item=Skewered bird meat, id=9984, option=[null, null, null, null, drop] +item=Skewered bird meat, id=9985, option=[null, null, null, null, drop] +item=Raw beast meat, id=9986, option=[null, null, null, null, drop] +item=Raw beast meat, id=9987, option=[null, null, null, null, drop] +item=Roast beast meat, id=9988, option=[Eat, null, null, null, drop] +item=Roast beast meat, id=9989, option=[null, null, null, null, drop] +item=Burnt beast meat, id=9990, option=[null, null, null, null, drop] +item=Burnt beast meat, id=9991, option=[null, null, null, null, drop] +item=Skewered beast, id=9992, option=[null, null, null, null, drop] +item=Skewered beast, id=9993, option=[null, null, null, null, drop] +item=Spicy tomato, id=9994, option=[Eat, null, null, null, drop] +item=Spicy tomato, id=9995, option=[null, null, null, null, drop] +item=Spicy minced meat, id=9996, option=[Eat, null, null, null, drop] +item=Spicy minced meat, id=9997, option=[null, null, null, null, drop] +item=Hunter potion(4), id=9998, option=[Drink, null, null, Empty, drop] +item=Hunter potion(4), id=9999, option=[null, null, null, null, drop] +item=Hunter potion(3), id=10000, option=[Drink, null, null, Empty, drop] +item=Hunter potion(3), id=10001, option=[null, null, null, null, drop] +item=Hunter potion(2), id=10002, option=[Drink, null, null, Empty, drop] +item=Hunter potion(2), id=10003, option=[null, null, null, null, drop] +item=Hunter potion(1), id=10004, option=[Drink, null, null, Empty, drop] +item=Hunter potion(1), id=10005, option=[null, null, null, null, drop] +item=Bird snare, id=10006, option=[Lay, null, null, null, drop] +item=Bird snare, id=10007, option=[null, null, null, null, drop] +item=Box trap, id=10008, option=[Lay, null, null, null, drop] +item=Box trap, id=10009, option=[null, null, null, null, drop] +item=Butterfly net, id=10010, option=[null, Wield, null, null, drop] +item=Butterfly net, id=10011, option=[null, null, null, null, drop] +item=Butterfly jar, id=10012, option=[null, null, null, null, drop] +item=Butterfly jar, id=10013, option=[null, null, null, null, drop] +item=Black warlock, id=10014, option=[null, null, null, Release, drop] +item=Black warlock, id=10015, option=[null, null, null, null, drop] +item=Snowy knight, id=10016, option=[null, null, null, Release, drop] +item=Snowy knight, id=10017, option=[null, null, null, null, drop] +item=Sapphire glacialis, id=10018, option=[null, null, null, Release, drop] +item=Sapphire glacialis, id=10019, option=[null, null, null, null, drop] +item=Ruby harvest, id=10020, option=[null, null, null, Release, drop] +item=Ruby harvest, id=10021, option=[null, null, null, null, drop] +item=null, id=10022, option=[null, null, null, null, drop] +item=Falconer's glove, id=10023, option=[null, Wear, null, null, drop] +item=Falconer's glove, id=10024, option=[null, Wear, null, null, drop] +item=Magic box, id=10025, option=[Activate, null, null, null, drop] +item=Magic box, id=10026, option=[null, null, null, null, drop] +item=Imp-in-a-box(2), id=10027, option=[Talk-to, Bank, null, null, drop] +item=Imp-in-a-box(1), id=10028, option=[Talk-to, Bank, null, null, drop] +item=Teasing stick, id=10029, option=[null, null, null, null, drop] +item=Teasing stick, id=10030, option=[null, null, null, null, drop] +item=Rabbit snare, id=10031, option=[Lay, null, null, null, drop] +item=Rabbit snare, id=10032, option=[null, null, null, null, drop] +item=Chinchompa, id=10033, option=[null, Wield, null, null, Release] +item=Red chinchompa, id=10034, option=[null, Wield, null, null, Release] +item=Kyatt legs, id=10035, option=[null, Wear, null, null, drop] +item=Kyatt legs, id=10036, option=[null, null, null, null, drop] +item=Kyatt top, id=10037, option=[null, Wear, null, null, drop] +item=Kyatt top, id=10038, option=[null, null, null, null, drop] +item=Kyatt hat, id=10039, option=[null, Wear, null, null, drop] +item=Kyatt hat, id=10040, option=[null, null, null, null, drop] +item=Larupia legs, id=10041, option=[null, Wear, null, null, drop] +item=Larupia legs, id=10042, option=[null, null, null, null, drop] +item=Larupia top, id=10043, option=[null, Wear, null, null, drop] +item=Larupia top, id=10044, option=[null, null, null, null, drop] +item=Larupia hat, id=10045, option=[null, Wear, null, null, drop] +item=Larupia hat, id=10046, option=[null, null, null, null, drop] +item=Graahk legs, id=10047, option=[null, Wear, null, null, drop] +item=Graahk legs, id=10048, option=[null, null, null, null, drop] +item=Graahk top, id=10049, option=[null, Wear, null, null, drop] +item=Graahk top, id=10050, option=[null, null, null, null, drop] +item=Graahk headdress, id=10051, option=[null, Wear, null, null, drop] +item=Graahk headdress, id=10052, option=[null, null, null, null, drop] +item=Wood camo top, id=10053, option=[null, Wear, null, null, drop] +item=Wood camo top, id=10054, option=[null, null, null, null, drop] +item=Wood camo legs, id=10055, option=[null, Wear, null, null, drop] +item=Wood camo legs, id=10056, option=[null, null, null, null, drop] +item=Jungle camo top, id=10057, option=[null, Wear, null, null, drop] +item=Jungle camo top, id=10058, option=[null, null, null, null, drop] +item=Jungle camo legs, id=10059, option=[null, Wear, null, null, drop] +item=Jungle camo legs, id=10060, option=[null, null, null, null, drop] +item=Desert camo top, id=10061, option=[null, Wear, null, null, drop] +item=Desert camo top, id=10062, option=[null, null, null, null, drop] +item=Desert camo legs, id=10063, option=[null, Wear, null, null, drop] +item=Desert camo legs, id=10064, option=[null, null, null, null, drop] +item=Polar camo top, id=10065, option=[null, Wear, null, null, drop] +item=Polar camo top, id=10066, option=[null, null, null, null, drop] +item=Polar camo legs, id=10067, option=[null, Wear, null, null, drop] +item=Polar camo legs, id=10068, option=[null, null, null, null, drop] +item=Spotted cape, id=10069, option=[null, Wear, null, null, drop] +item=Spotted cape, id=10070, option=[null, null, null, null, drop] +item=Spottier cape, id=10071, option=[null, Wear, null, null, drop] +item=Spottier cape, id=10072, option=[null, null, null, null, drop] +item=Spotted cape, id=10073, option=[null, Wear, null, null, drop] +item=Spottier cape, id=10074, option=[null, Wear, null, null, drop] +item=Gloves of silence, id=10075, option=[null, Wear, Check, null, drop] +item=Gloves of silence, id=10076, option=[null, null, null, null, drop] +item=Spiky vambraces, id=10077, option=[null, Wear, null, null, drop] +item=Spiky vambraces, id=10078, option=[null, null, null, null, drop] +item=Green spiky vambs, id=10079, option=[null, Wear, null, null, drop] +item=Green spiky vambs, id=10080, option=[null, null, null, null, drop] +item=Blue spiky vambs, id=10081, option=[null, Wear, null, null, drop] +item=Blue spiky vambs, id=10082, option=[null, null, null, null, drop] +item=Red spiky vambs, id=10083, option=[null, Wear, null, null, drop] +item=Red spiky vambs, id=10084, option=[null, null, null, null, drop] +item=Black spiky vambs, id=10085, option=[null, Wear, null, null, drop] +item=Black spiky vambs, id=10086, option=[null, null, null, null, drop] +item=Stripy feather, id=10087, option=[null, null, null, null, drop] +item=Red feather, id=10088, option=[null, null, null, null, drop] +item=Blue feather, id=10089, option=[null, null, null, null, drop] +item=Yellow feather, id=10090, option=[null, null, null, null, drop] +item=Orange feather, id=10091, option=[null, null, null, null, drop] +item=Ferret, id=10092, option=[null, null, null, null, Release] +item=Tatty larupia fur, id=10093, option=[null, null, null, null, drop] +item=Tatty larupia fur, id=10094, option=[null, null, null, null, drop] +item=Larupia fur, id=10095, option=[null, null, null, null, drop] +item=Larupia fur, id=10096, option=[null, null, null, null, drop] +item=Tatty graahk fur, id=10097, option=[null, null, null, null, drop] +item=Tatty graahk fur, id=10098, option=[null, null, null, null, drop] +item=Graahk fur, id=10099, option=[null, null, null, null, drop] +item=Graahk fur, id=10100, option=[null, null, null, null, drop] +item=Tatty kyatt fur, id=10101, option=[null, null, null, null, drop] +item=Tatty kyatt fur, id=10102, option=[null, null, null, null, drop] +item=Kyatt fur, id=10103, option=[null, null, null, null, drop] +item=Kyatt fur, id=10104, option=[null, null, null, null, drop] +item=Kebbit spike, id=10105, option=[null, null, null, null, drop] +item=Kebbit spike, id=10106, option=[null, null, null, null, drop] +item=Long kebbit spike, id=10107, option=[null, null, null, null, drop] +item=Long kebbit spike, id=10108, option=[null, null, null, null, drop] +item=Kebbit teeth, id=10109, option=[null, null, null, null, drop] +item=Kebbit teeth, id=10110, option=[null, null, null, null, drop] +item=Kebbit teeth dust, id=10111, option=[null, null, null, null, drop] +item=Kebbit teeth dust, id=10112, option=[null, null, null, null, drop] +item=Kebbit claws, id=10113, option=[null, null, null, null, drop] +item=Kebbit claws, id=10114, option=[null, null, null, null, drop] +item=Dark kebbit fur, id=10115, option=[null, null, null, null, drop] +item=Dark kebbit fur, id=10116, option=[null, null, null, null, drop] +item=Polar kebbit fur, id=10117, option=[null, null, null, null, drop] +item=Polar kebbit fur, id=10118, option=[null, null, null, null, drop] +item=Feldip weasel fur, id=10119, option=[null, null, null, null, drop] +item=Feldip weasel fur, id=10120, option=[null, null, null, null, drop] +item=Common kebbit fur, id=10121, option=[null, null, null, null, drop] +item=Common kebbit fur, id=10122, option=[null, null, null, null, drop] +item=Desert devil fur, id=10123, option=[null, null, null, null, drop] +item=Desert devil fur, id=10124, option=[null, null, null, null, drop] +item=Spotted kebbit fur, id=10125, option=[null, null, null, null, drop] +item=Spotted kebbit fur, id=10126, option=[null, null, null, null, drop] +item=Dashing kebbit fur, id=10127, option=[null, null, null, null, drop] +item=Dashing kebbit fur, id=10128, option=[null, null, null, null, drop] +item=Barb-tail harpoon, id=10129, option=[null, Wield, null, null, drop] +item=Barb-tail harpoon, id=10130, option=[null, null, null, null, drop] +item=null, id=10131, option=[null, null, null, null, drop] +item=Strung rabbit foot, id=10132, option=[null, Wear, null, null, drop] +item=Strung rabbit foot, id=10133, option=[null, null, null, null, drop] +item=Rabbit foot, id=10134, option=[null, null, null, null, drop] +item=Rabbit foot, id=10135, option=[null, null, null, null, drop] +item=Rainbow fish, id=10136, option=[Eat, null, null, null, drop] +item=Rainbow fish, id=10137, option=[null, null, null, null, drop] +item=Raw rainbow fish, id=10138, option=[null, null, null, null, drop] +item=Raw rainbow fish, id=10139, option=[null, null, null, null, drop] +item=Burnt rainbow fish, id=10140, option=[null, null, null, null, drop] +item=Burnt rainbow fish, id=10141, option=[null, null, null, null, drop] +item=Guam tar, id=10142, option=[null, Wield, null, null, drop] +item=Marrentill tar, id=10143, option=[null, Wield, null, null, drop] +item=Tarromin tar, id=10144, option=[null, Wield, null, null, drop] +item=Harralander tar, id=10145, option=[null, Wield, null, null, drop] +item=Orange salamander, id=10146, option=[null, Wield, null, null, Release] +item=Red salamander, id=10147, option=[null, Wield, null, null, Release] +item=Black salamander, id=10148, option=[null, Wield, null, null, Release] +item=Swamp lizard, id=10149, option=[null, Wield, null, null, Release] +item=Noose wand, id=10150, option=[null, Wield, null, null, drop] +item=Noose wand, id=10151, option=[null, null, null, null, drop] +item=null, id=10152, option=[null, null, null, null, drop] +item=null, id=10153, option=[null, null, null, null, drop] +item=null, id=10154, option=[null, null, null, null, drop] +item=null, id=10155, option=[null, null, null, null, drop] +item=Hunters' crossbow, id=10156, option=[null, Wield, null, null, drop] +item=Hunters' crossbow, id=10157, option=[null, null, null, null, drop] +item=Kebbit bolts, id=10158, option=[null, Wield, null, null, drop] +item=Long kebbit bolts, id=10159, option=[null, Wield, null, null, drop] +item=Orange salamander, id=10160, option=[null, null, null, null, drop] +item=Red salamander, id=10161, option=[null, null, null, null, drop] +item=Black salamander, id=10162, option=[null, null, null, null, drop] +item=Swamp lizard, id=10163, option=[null, null, null, null, drop] +item=null, id=10164, option=[null, null, null, null, drop] +item=More..., id=10165, option=[null, null, null, null, drop] +item=Back..., id=10166, option=[null, null, null, null, drop] +item=Eagle feather, id=10167, option=[null, null, null, null, drop] +item=null, id=10168, option=[null, null, null, null, drop] +item=null, id=10169, option=[null, null, null, null, drop] +item=null, id=10170, option=[null, null, null, null, drop] +item=Eagle cape, id=10171, option=[null, Wear, null, null, drop] +item=Fake beak, id=10172, option=[null, Wear, null, null, drop] +item=Bird book, id=10173, option=[Read, null, null, null, drop] +item=Metal feather, id=10174, option=[null, null, null, null, Destroy] +item=Golden feather, id=10175, option=[null, null, null, null, Destroy] +item=Silver feather, id=10176, option=[null, null, null, null, Destroy] +item=Bronze feather, id=10177, option=[null, null, null, null, Destroy] +item=Odd bird seed, id=10178, option=[null, null, null, null, drop] +item=Feathered journal, id=10179, option=[Read, null, null, null, drop] +item=Clue scroll, id=10180, option=[Read, null, null, null, drop] +item=Casket, id=10181, option=[Open, null, null, null, drop] +item=Clue scroll, id=10182, option=[Read, null, null, null, drop] +item=Casket, id=10183, option=[Open, null, null, null, drop] +item=Clue scroll, id=10184, option=[Read, null, null, null, drop] +item=Casket, id=10185, option=[Open, null, null, null, drop] +item=Clue scroll, id=10186, option=[Read, null, null, null, drop] +item=Casket, id=10187, option=[Open, null, null, null, drop] +item=Clue scroll, id=10188, option=[Read, null, null, null, drop] +item=Casket, id=10189, option=[Open, null, null, null, drop] +item=Clue scroll, id=10190, option=[Read, null, null, null, drop] +item=Casket, id=10191, option=[Open, null, null, null, drop] +item=Clue scroll, id=10192, option=[Read, null, null, null, drop] +item=Casket, id=10193, option=[Open, null, null, null, drop] +item=Clue scroll, id=10194, option=[Read, null, null, null, drop] +item=Casket, id=10195, option=[Open, null, null, null, drop] +item=Clue scroll, id=10196, option=[Read, null, null, null, drop] +item=Casket, id=10197, option=[Open, null, null, null, drop] +item=Clue scroll, id=10198, option=[Read, null, null, null, drop] +item=Casket, id=10199, option=[Open, null, null, null, drop] +item=Clue scroll, id=10200, option=[Read, null, null, null, drop] +item=Casket, id=10201, option=[Open, null, null, null, drop] +item=Clue scroll, id=10202, option=[Read, null, null, null, drop] +item=Casket, id=10203, option=[Open, null, null, null, drop] +item=Clue scroll, id=10204, option=[Read, null, null, null, drop] +item=Casket, id=10205, option=[Open, null, null, null, drop] +item=Clue scroll, id=10206, option=[Read, null, null, null, drop] +item=Casket, id=10207, option=[Open, null, null, null, drop] +item=Clue scroll, id=10208, option=[Read, null, null, null, drop] +item=Casket, id=10209, option=[Open, null, null, null, drop] +item=Clue scroll, id=10210, option=[Read, null, null, null, drop] +item=Casket, id=10211, option=[Open, null, null, null, drop] +item=Clue scroll, id=10212, option=[Read, null, null, null, drop] +item=Casket, id=10213, option=[Open, null, null, null, drop] +item=Clue scroll, id=10214, option=[Read, null, null, null, drop] +item=Casket, id=10215, option=[Open, null, null, null, drop] +item=Clue scroll, id=10216, option=[Read, null, null, null, drop] +item=Casket, id=10217, option=[Open, null, null, null, drop] +item=Clue scroll, id=10218, option=[Read, null, null, null, drop] +item=Casket, id=10219, option=[Open, null, null, null, drop] +item=Clue scroll, id=10220, option=[Read, null, null, null, drop] +item=Casket, id=10221, option=[Open, null, null, null, drop] +item=Clue scroll, id=10222, option=[Read, null, null, null, drop] +item=Casket, id=10223, option=[Open, null, null, null, drop] +item=Clue scroll, id=10224, option=[Read, null, null, null, drop] +item=Casket, id=10225, option=[Open, null, null, null, drop] +item=Clue scroll, id=10226, option=[Read, null, null, null, drop] +item=Casket, id=10227, option=[Open, null, null, null, drop] +item=Clue scroll, id=10228, option=[Read, null, null, null, drop] +item=Casket, id=10229, option=[Open, null, null, null, drop] +item=Clue scroll, id=10230, option=[Read, null, null, null, drop] +item=Casket, id=10231, option=[Open, null, null, null, drop] +item=Clue scroll, id=10232, option=[Read, null, null, null, drop] +item=Casket, id=10233, option=[Open, null, null, null, drop] +item=Clue scroll, id=10234, option=[Read, null, null, null, drop] +item=Casket, id=10235, option=[Open, null, null, null, drop] +item=Clue scroll, id=10236, option=[Read, null, null, null, drop] +item=Casket, id=10237, option=[Open, null, null, null, drop] +item=Clue scroll, id=10238, option=[Read, null, null, null, drop] +item=Casket, id=10239, option=[Open, null, null, null, drop] +item=Clue scroll, id=10240, option=[Read, null, null, null, drop] +item=Casket, id=10241, option=[Open, null, null, null, drop] +item=Clue scroll, id=10242, option=[Read, null, null, null, drop] +item=Casket, id=10243, option=[Open, null, null, null, drop] +item=Clue scroll, id=10244, option=[Read, null, null, null, drop] +item=Casket, id=10245, option=[Open, null, null, null, drop] +item=Clue scroll, id=10246, option=[Read, null, null, null, drop] +item=Casket, id=10247, option=[Open, null, null, null, drop] +item=Clue scroll, id=10248, option=[Read, null, null, null, drop] +item=Casket, id=10249, option=[Open, null, null, null, drop] +item=Clue scroll, id=10250, option=[Read, null, null, null, drop] +item=Casket, id=10251, option=[Open, null, null, null, drop] +item=Clue scroll, id=10252, option=[Read, null, null, null, drop] +item=Casket, id=10253, option=[Open, null, null, null, drop] +item=Clue scroll, id=10254, option=[Read, null, null, null, drop] +item=Casket, id=10255, option=[Open, null, null, null, drop] +item=Clue scroll, id=10256, option=[Read, null, null, null, drop] +item=Casket, id=10257, option=[Open, null, null, null, drop] +item=Clue scroll, id=10258, option=[Read, null, null, null, drop] +item=Casket, id=10259, option=[Open, null, null, null, drop] +item=Clue scroll, id=10260, option=[Read, null, null, null, drop] +item=Casket, id=10261, option=[Open, null, null, null, drop] +item=Clue scroll, id=10262, option=[Read, null, null, null, drop] +item=Casket, id=10263, option=[Open, null, null, null, drop] +item=Clue scroll, id=10264, option=[Read, null, null, null, drop] +item=Casket, id=10265, option=[Open, null, null, null, drop] +item=Clue scroll, id=10266, option=[Read, null, null, null, drop] +item=Casket, id=10267, option=[Open, null, null, null, drop] +item=Clue scroll, id=10268, option=[Read, null, null, null, drop] +item=Casket, id=10269, option=[Open, null, null, null, drop] +item=Clue scroll, id=10270, option=[Read, null, null, null, drop] +item=Casket, id=10271, option=[Open, null, null, null, drop] +item=Clue scroll, id=10272, option=[Read, null, null, null, drop] +item=Casket, id=10273, option=[Open, null, null, null, drop] +item=Clue scroll, id=10274, option=[Read, null, null, null, drop] +item=Casket, id=10275, option=[Open, null, null, null, drop] +item=Clue scroll, id=10276, option=[Read, null, null, null, drop] +item=Casket, id=10277, option=[Open, null, null, null, drop] +item=Clue scroll, id=10278, option=[Read, null, null, null, drop] +item=Casket, id=10279, option=[Open, null, null, null, drop] +item=Willow comp bow, id=10280, option=[null, Wield, null, null, drop] +item=Willow comp bow, id=10281, option=[null, null, null, null, drop] +item=Yew comp bow, id=10282, option=[null, Wield, null, null, drop] +item=Yew comp bow, id=10283, option=[null, null, null, null, drop] +item=Magic comp bow, id=10284, option=[null, Wield, null, null, drop] +item=Magic comp bow, id=10285, option=[null, null, null, null, drop] +item=Rune helm (h1), id=10286, option=[null, Wear, null, null, drop] +item=Rune helm (h1), id=10287, option=[null, null, null, null, drop] +item=Rune helm (h2), id=10288, option=[null, Wear, null, null, drop] +item=Rune helm (h2), id=10289, option=[null, null, null, null, drop] +item=Rune helm (h3), id=10290, option=[null, Wear, null, null, drop] +item=Rune helm (h3), id=10291, option=[null, null, null, null, drop] +item=Rune helm (h4), id=10292, option=[null, Wear, null, null, drop] +item=Rune helm (h4), id=10293, option=[null, null, null, null, drop] +item=Rune helm (h5), id=10294, option=[null, Wear, null, null, drop] +item=Rune helm (h5), id=10295, option=[null, null, null, null, drop] +item=Adamant helm (h1), id=10296, option=[null, Wear, null, null, drop] +item=Adamant helm (h1), id=10297, option=[null, null, null, null, drop] +item=Adamant helm (h2), id=10298, option=[null, Wear, null, null, drop] +item=Adamant helm (h2), id=10299, option=[null, null, null, null, drop] +item=Adamant helm (h3), id=10300, option=[null, Wear, null, null, drop] +item=Adamant helm (h3), id=10301, option=[null, null, null, null, drop] +item=Adamant helm (h4), id=10302, option=[null, Wear, null, null, drop] +item=Adamant helm (h4), id=10303, option=[null, null, null, null, drop] +item=Adamant helm (h5), id=10304, option=[null, Wear, null, null, drop] +item=Adamant helm (h5), id=10305, option=[null, null, null, null, drop] +item=Black helm (h1), id=10306, option=[null, Wear, null, null, drop] +item=Black helm (h1), id=10307, option=[null, null, null, null, drop] +item=Black helm (h2), id=10308, option=[null, Wear, null, null, drop] +item=Black helm (h2), id=10309, option=[null, null, null, null, drop] +item=Black helm (h3), id=10310, option=[null, Wear, null, null, drop] +item=Black helm (h3), id=10311, option=[null, null, null, null, drop] +item=Black helm (h4), id=10312, option=[null, Wear, null, null, drop] +item=Black helm (h4), id=10313, option=[null, null, null, null, drop] +item=Black helm (h5), id=10314, option=[null, Wear, null, null, drop] +item=Black helm (h5), id=10315, option=[null, null, null, null, drop] +item=Bob shirt, id=10316, option=[null, Wear, null, null, drop] +item=Bob shirt, id=10317, option=[null, null, null, null, drop] +item=Bob shirt, id=10318, option=[null, Wear, null, null, drop] +item=Bob shirt, id=10319, option=[null, null, null, null, drop] +item=Bob shirt, id=10320, option=[null, Wear, null, null, drop] +item=Bob shirt, id=10321, option=[null, null, null, null, drop] +item=Bob shirt, id=10322, option=[null, Wear, null, null, drop] +item=Bob shirt, id=10323, option=[null, null, null, null, drop] +item=Bob shirt, id=10324, option=[null, Wear, null, null, drop] +item=Bob shirt, id=10325, option=[null, null, null, null, drop] +item=Purple firelighter, id=10326, option=[null, null, null, null, drop] +item=White firelighter, id=10327, option=[null, null, null, null, drop] +item=White logs, id=10328, option=[null, null, null, null, drop] +item=Purple logs, id=10329, option=[null, null, null, null, drop] +item=3rd age range top, id=10330, option=[null, Wear, null, null, drop] +item=3rd age range top, id=10331, option=[null, null, null, null, drop] +item=3rd age range legs, id=10332, option=[null, Wear, null, null, drop] +item=3rd age range legs, id=10333, option=[null, null, null, null, drop] +item=3rd age range coif, id=10334, option=[null, Wear, null, null, drop] +item=3rd age range coif, id=10335, option=[null, null, null, null, drop] +item=3rd age vambraces, id=10336, option=[null, Wear, null, null, drop] +item=3rd age vambraces, id=10337, option=[null, null, null, null, drop] +item=3rd age robe top, id=10338, option=[null, Wear, null, null, drop] +item=3rd age robe top, id=10339, option=[null, null, null, null, drop] +item=3rd age robe, id=10340, option=[null, Wear, null, null, drop] +item=3rd age robe, id=10341, option=[null, null, null, null, drop] +item=3rd age mage hat, id=10342, option=[null, Wear, null, null, drop] +item=3rd age mage hat, id=10343, option=[null, null, null, null, drop] +item=3rd age amulet, id=10344, option=[null, Wear, null, null, drop] +item=3rd age amulet, id=10345, option=[null, null, null, null, drop] +item=3rd age platelegs, id=10346, option=[null, Wear, null, null, drop] +item=3rd age platelegs, id=10347, option=[null, null, null, null, drop] +item=3rd age platebody, id=10348, option=[null, Wear, null, null, drop] +item=3rd age platebody, id=10349, option=[null, null, null, null, drop] +item=3rd age full helmet, id=10350, option=[null, Wear, null, null, drop] +item=3rd age full helmet, id=10351, option=[null, null, null, null, drop] +item=3rd age kiteshield, id=10352, option=[null, Wield, null, null, drop] +item=3rd age kiteshield, id=10353, option=[null, null, null, null, drop] +item=Amulet of glory(t4), id=10354, option=[null, Wear, null, Rub, drop] +item=Amulet of glory(t4), id=10355, option=[null, null, null, null, drop] +item=Amulet of glory(t3), id=10356, option=[null, Wear, null, Rub, drop] +item=Amulet of glory(t3), id=10357, option=[null, null, null, null, drop] +item=Amulet of glory(t2), id=10358, option=[null, Wear, null, Rub, drop] +item=Amulet of glory(t2), id=10359, option=[null, null, null, null, drop] +item=Amulet of glory(t1), id=10360, option=[null, Wear, null, Rub, drop] +item=Amulet of glory(t1), id=10361, option=[null, null, null, null, drop] +item=Amulet of glory(t), id=10362, option=[null, Wear, null, Rub, drop] +item=Amulet of glory(t), id=10363, option=[null, null, null, null, drop] +item=Strength amulet(t), id=10364, option=[null, Wear, null, null, drop] +item=Strength amulet(t), id=10365, option=[null, null, null, null, drop] +item=Amulet of magic(t), id=10366, option=[null, Wear, null, null, drop] +item=Amulet of magic(t), id=10367, option=[null, null, null, null, drop] +item=Zamorak bracers, id=10368, option=[null, Wear, null, null, drop] +item=Zamorak bracers, id=10369, option=[null, null, null, null, drop] +item=Zamorak d'hide, id=10370, option=[null, Wear, null, null, drop] +item=Zamorak d'hide, id=10371, option=[null, null, null, null, drop] +item=Zamorak chaps, id=10372, option=[null, Wear, null, null, drop] +item=Zamorak chaps, id=10373, option=[null, null, null, null, drop] +item=Zamorak coif, id=10374, option=[null, Wear, null, null, drop] +item=Zamorak coif, id=10375, option=[null, null, null, null, drop] +item=Guthix bracers, id=10376, option=[null, Wear, null, null, drop] +item=Guthix bracers, id=10377, option=[null, null, null, null, drop] +item=Guthix dragonhide, id=10378, option=[null, Wear, null, null, drop] +item=Guthix dragonhide, id=10379, option=[null, null, null, null, drop] +item=Guthix chaps, id=10380, option=[null, Wear, null, null, drop] +item=Guthix chaps, id=10381, option=[null, null, null, null, drop] +item=Guthix coif, id=10382, option=[null, Wear, null, null, drop] +item=Guthix coif, id=10383, option=[null, null, null, null, drop] +item=Saradomin bracers, id=10384, option=[null, Wear, null, null, drop] +item=Saradomin bracers, id=10385, option=[null, null, null, null, drop] +item=Saradomin d'hide, id=10386, option=[null, Wear, null, null, drop] +item=Saradomin d'hide, id=10387, option=[null, null, null, null, drop] +item=Saradomin chaps, id=10388, option=[null, Wear, null, null, drop] +item=Saradomin chaps, id=10389, option=[null, null, null, null, drop] +item=Saradomin coif, id=10390, option=[null, Wear, null, null, drop] +item=Saradomin coif, id=10391, option=[null, null, null, null, drop] +item=A powdered wig, id=10392, option=[null, Wear, null, null, drop] +item=A powdered wig, id=10393, option=[null, null, null, null, drop] +item=Flared trousers, id=10394, option=[null, Wear, null, null, drop] +item=Flared trousers, id=10395, option=[null, null, null, null, drop] +item=Pantaloons, id=10396, option=[null, Wear, null, null, drop] +item=Pantaloons, id=10397, option=[null, null, null, null, drop] +item=Sleeping cap, id=10398, option=[null, Wear, null, null, drop] +item=Sleeping cap, id=10399, option=[null, null, null, null, drop] +item=Black ele' shirt, id=10400, option=[null, Wear, null, null, drop] +item=Black ele' shirt, id=10401, option=[null, null, null, null, drop] +item=Black ele' legs, id=10402, option=[null, Wear, null, null, drop] +item=Black ele' legs, id=10403, option=[null, null, null, null, drop] +item=Red ele' shirt, id=10404, option=[null, Wear, null, null, drop] +item=Red ele' shirt, id=10405, option=[null, null, null, null, drop] +item=Red ele' legs, id=10406, option=[null, Wear, null, null, drop] +item=Red ele' legs, id=10407, option=[null, null, null, null, drop] +item=Blue ele' shirt, id=10408, option=[null, Wear, null, null, drop] +item=Blue ele' shirt, id=10409, option=[null, null, null, null, drop] +item=Blue ele' legs, id=10410, option=[null, Wear, null, null, drop] +item=Blue ele' legs, id=10411, option=[null, null, null, null, drop] +item=Green ele' shirt, id=10412, option=[null, Wear, null, null, drop] +item=Green ele' shirt, id=10413, option=[null, null, null, null, drop] +item=Green ele' legs, id=10414, option=[null, Wear, null, null, drop] +item=Green ele' legs, id=10415, option=[null, null, null, null, drop] +item=Purple ele' shirt, id=10416, option=[null, Wear, null, null, drop] +item=Purple ele' shirt, id=10417, option=[null, null, null, null, drop] +item=Purple ele' legs, id=10418, option=[null, Wear, null, null, drop] +item=Purple ele' legs, id=10419, option=[null, null, null, null, drop] +item=White ele' blouse, id=10420, option=[null, Wear, null, null, drop] +item=White ele' blouse, id=10421, option=[null, null, null, null, drop] +item=White ele' skirt, id=10422, option=[null, Wear, null, null, drop] +item=White ele' skirt, id=10423, option=[null, null, null, null, drop] +item=Red ele' blouse, id=10424, option=[null, Wear, null, null, drop] +item=Red ele' blouse, id=10425, option=[null, null, null, null, drop] +item=Red ele' skirt, id=10426, option=[null, Wear, null, null, drop] +item=Red ele' skirt, id=10427, option=[null, null, null, null, drop] +item=Blue ele' blouse, id=10428, option=[null, Wear, null, null, drop] +item=Blue ele' blouse, id=10429, option=[null, null, null, null, drop] +item=Blue ele' skirt, id=10430, option=[null, Wear, null, null, drop] +item=Blue ele' skirt, id=10431, option=[null, null, null, null, drop] +item=Green ele' blouse, id=10432, option=[null, Wear, null, null, drop] +item=Green ele' blouse, id=10433, option=[null, null, null, null, drop] +item=Green ele' skirt, id=10434, option=[null, Wear, null, null, drop] +item=Green ele' skirt, id=10435, option=[null, null, null, null, drop] +item=Purple ele' blouse, id=10436, option=[null, Wear, null, null, drop] +item=Purple ele' blouse, id=10437, option=[null, null, null, null, drop] +item=Purple ele' skirt, id=10438, option=[null, Wear, null, null, drop] +item=Purple ele' skirt, id=10439, option=[null, null, null, null, drop] +item=Saradomin crozier, id=10440, option=[null, Wield, null, null, drop] +item=Saradomin crozier, id=10441, option=[null, null, null, null, drop] +item=Guthix crozier, id=10442, option=[null, Wield, null, null, drop] +item=Guthix crozier, id=10443, option=[null, null, null, null, drop] +item=Zamorak crozier, id=10444, option=[null, Wield, null, null, drop] +item=Zamorak crozier, id=10445, option=[null, null, null, null, drop] +item=Saradomin cloak, id=10446, option=[null, Wear, null, null, drop] +item=Saradomin cloak, id=10447, option=[null, null, null, null, drop] +item=Guthix cloak, id=10448, option=[null, Wear, null, null, drop] +item=Guthix cloak, id=10449, option=[null, null, null, null, drop] +item=Zamorak cloak, id=10450, option=[null, Wear, null, null, drop] +item=Zamorak cloak, id=10451, option=[null, null, null, null, drop] +item=Saradomin mitre, id=10452, option=[null, Wear, null, null, drop] +item=Saradomin mitre, id=10453, option=[null, null, null, null, drop] +item=Guthix mitre, id=10454, option=[null, Wear, null, null, drop] +item=Guthix mitre, id=10455, option=[null, null, null, null, drop] +item=Zamorak mitre, id=10456, option=[null, Wear, null, null, drop] +item=Zamorak mitre, id=10457, option=[null, null, null, null, drop] +item=Saradomin robe top, id=10458, option=[null, Wear, null, null, drop] +item=Saradomin robe top, id=10459, option=[null, null, null, null, drop] +item=Zamorak robe top, id=10460, option=[null, Wear, null, null, drop] +item=Zamorak robe top, id=10461, option=[null, null, null, null, drop] +item=Guthix robe top, id=10462, option=[null, Wear, null, null, drop] +item=Guthix robe top, id=10463, option=[null, null, null, null, drop] +item=Saradomin robe legs, id=10464, option=[null, Wear, null, null, drop] +item=Saradomin robe legs, id=10465, option=[null, null, null, null, drop] +item=Guthix robe legs, id=10466, option=[null, Wear, null, null, drop] +item=Guthix robe legs, id=10467, option=[null, null, null, null, drop] +item=Zamorak robe legs, id=10468, option=[null, Wear, null, null, drop] +item=Zamorak robe legs, id=10469, option=[null, null, null, null, drop] +item=Saradomin stole, id=10470, option=[null, Wear, null, null, drop] +item=Saradomin stole, id=10471, option=[null, null, null, null, drop] +item=Guthix stole, id=10472, option=[null, Wear, null, null, drop] +item=Guthix stole, id=10473, option=[null, null, null, null, drop] +item=Zamorak stole, id=10474, option=[null, Wear, null, null, drop] +item=Zamorak stole, id=10475, option=[null, null, null, null, drop] +item=Purple sweets, id=10476, option=[Eat, null, null, null, drop] +item=null, id=10477, option=[null, null, null, null, drop] +item=null, id=10478, option=[null, null, null, null, drop] +item=null, id=10479, option=[null, null, null, null, drop] +item=null, id=10480, option=[null, null, null, null, drop] +item=null, id=10481, option=[null, null, null, null, drop] +item=null, id=10482, option=[null, null, null, null, drop] +item=null, id=10483, option=[null, null, null, null, drop] +item=null, id=10484, option=[null, null, null, null, drop] +item=Scroll, id=10485, option=[null, null, null, null, drop] +item=Empty sack, id=10486, option=[null, null, null, null, drop] +item=Undead chicken, id=10487, option=[null, Wield, null, null, Destroy] +item=Selected iron, id=10488, option=[null, null, null, null, Destroy] +item=Bar magnet, id=10489, option=[null, null, null, null, Destroy] +item=Undead twigs, id=10490, option=[null, null, null, null, Destroy] +item=Blessed axe, id=10491, option=[null, Wield, null, null, Destroy] +item=Research notes, id=10492, option=[Translate, null, null, null, Destroy] +item=Translated notes, id=10493, option=[null, null, null, null, Destroy] +item=A pattern, id=10494, option=[null, null, null, null, Destroy] +item=A container, id=10495, option=[null, null, null, null, Destroy] +item=Polished buttons, id=10496, option=[null, null, null, null, drop] +item=Whoopsie, id=10497, option=[null, null, null, null, drop] +item=Ava's attractor, id=10498, option=[null, Wear, null, null, Destroy] +item=Ava's accumulator, id=10499, option=[null, Wear, null, null, Destroy] +item=Crone-made amulet, id=10500, option=[null, Wear, null, null, Destroy] +item=Snowball, id=10501, option=[null, Wield, null, null, drop] +item=null, id=10502, option=[null, null, null, null, drop] +item=null, id=10503, option=[null, null, null, null, drop] +item=null, id=10504, option=[null, null, null, null, drop] +item=null, id=10505, option=[null, null, null, null, drop] +item=Gublinch shards, id=10506, option=[null, null, null, null, drop] +item=Reindeer hat, id=10507, option=[null, Wear, null, null, Destroy] +item=Wintumber tree, id=10508, option=[Plant, null, null, null, Destroy] +item=Snowball, id=10509, option=[null, null, null, null, drop] +item=Snowball, id=10510, option=[null, null, null, null, drop] +item=Zanaris choir, id=10511, option=[null, null, null, null, drop] +item=Scroll, id=10512, option=[Read, null, Write-Role, Clear, Destroy] +item=Crackers, id=10513, option=[Drop, null, null, null, Destroy] +item=Tofu, id=10514, option=[Drop, null, null, null, Destroy] +item=Worms, id=10515, option=[Drop, null, null, null, Destroy] +item=Attacker horn, id=10516, option=[Tell-red, Tell-green, Tell-blue, Medic, drop] +item=Attacker horn, id=10517, option=[Tell-red, Tell-green, Tell-blue, Medic, drop] +item=Attacker horn, id=10518, option=[Tell-red, Tell-green, Tell-blue, Medic, drop] +item=Attacker horn, id=10519, option=[Tell-red, Tell-green, Tell-blue, Medic, drop] +item=Attacker horn, id=10520, option=[Tell-red, Tell-green, Tell-blue, Medic, drop] +item=Collection bag, id=10521, option=[Look-in, Empty, null, null, drop] +item=Collection bag, id=10522, option=[Look-in, Empty, null, null, drop] +item=Collection bag, id=10523, option=[Look-in, Empty, null, null, drop] +item=Collection bag, id=10524, option=[Look-in, Empty, null, null, drop] +item=Collection bag, id=10525, option=[Look-in, Empty, null, null, drop] +item=Healer horn, id=10526, option=[Tell-tofu, Tell-crackers, Tell-worms, Medic, drop] +item=Healer horn, id=10527, option=[Tell-tofu, Tell-crackers, Tell-worms, Medic, drop] +item=Healer horn, id=10528, option=[Tell-tofu, Tell-crackers, Tell-worms, Medic, drop] +item=Healer horn, id=10529, option=[Tell-tofu, Tell-crackers, Tell-worms, Medic, drop] +item=Healer horn, id=10530, option=[Tell-tofu, Tell-crackers, Tell-worms, Medic, drop] +item=Green egg, id=10531, option=[null, null, null, null, Destroy] +item=Red egg, id=10532, option=[null, null, null, null, Destroy] +item=Blue egg, id=10533, option=[null, null, null, null, Destroy] +item=Yellow egg, id=10534, option=[null, null, null, null, drop] +item=Poisoned egg, id=10535, option=[null, null, null, null, drop] +item=Spiked/pois. egg, id=10536, option=[null, null, null, null, drop] +item=Omega egg, id=10537, option=[null, null, null, null, drop] +item=Defender horn, id=10538, option=[Tell-tofu, Tell-worms, Tell-meat, Medic, drop] +item=Poisoned tofu, id=10539, option=[null, null, null, null, Destroy] +item=Poisoned worms, id=10540, option=[null, null, null, null, Destroy] +item=Poisoned meat, id=10541, option=[null, null, null, null, Destroy] +item=Healing vial(4), id=10542, option=[null, null, null, null, Destroy] +item=Healing vial(3), id=10543, option=[null, null, null, null, Destroy] +item=Healing vial(2), id=10544, option=[null, null, null, null, Destroy] +item=Healing vial(1), id=10545, option=[null, null, null, null, Destroy] +item=Healing vial, id=10546, option=[null, null, null, null, Destroy] +item=Healer hat, id=10547, option=[null, Wear, null, null, Destroy] +item=Fighter hat, id=10548, option=[null, Wear, null, null, Destroy] +item=Runner hat, id=10549, option=[null, Wear, null, null, Destroy] +item=Ranger hat, id=10550, option=[null, Wear, null, null, Destroy] +item=Fighter torso, id=10551, option=[null, Wear, null, null, Destroy] +item=Runner boots, id=10552, option=[null, Wear, null, null, Destroy] +item=Penance gloves, id=10553, option=[null, Wear, null, null, Destroy] +item=Penance gloves, id=10554, option=[null, Wear, null, null, Destroy] +item=Penance skirt, id=10555, option=[null, Wear, null, null, Destroy] +item=Attacker icon, id=10556, option=[null, Wear, null, null, drop] +item=Collector icon, id=10557, option=[null, Wear, null, null, drop] +item=Defender icon, id=10558, option=[null, Wear, null, null, drop] +item=Healer icon, id=10559, option=[null, Wear, null, null, drop] +item=Collector horn, id=10560, option=[Tell-style1, Tell-style2, Tell-style3, Tell-style4, Medic] +item=Spikes, id=10561, option=[null, null, null, null, drop] +item=Queen help book, id=10562, option=[Read, null, null, null, Destroy] +item=No eggs, id=10563, option=[null, null, null, null, drop] +item=Granite body, id=10564, option=[null, Wear, null, null, drop] +item=Granite body, id=10565, option=[null, null, null, null, drop] +item=Fire cape, id=10566, option=[null, Wear, null, null, drop] +item=Thingy, id=10567, option=[null, Wear, null, null, drop] +item=Thingy, id=10568, option=[null, null, null, null, drop] +item=Thingy, id=10569, option=[null, Wear, null, null, drop] +item=Thingy, id=10570, option=[null, null, null, null, drop] +item=Thingy, id=10571, option=[null, Wear, null, null, drop] +item=Thingy, id=10572, option=[null, null, null, null, drop] +item=Thingy, id=10573, option=[null, Wear, null, null, drop] +item=Thingy, id=10574, option=[null, null, null, null, drop] +item=Thingy, id=10575, option=[null, Wear, null, null, drop] +item=Thingy, id=10576, option=[null, null, null, null, drop] +item=Thingy, id=10577, option=[null, Wear, null, null, drop] +item=Thingy, id=10578, option=[null, null, null, null, drop] +item=Thingy, id=10579, option=[null, Wear, null, null, drop] +item=Thingy, id=10580, option=[null, null, null, null, drop] +item=Keris, id=10581, option=[null, Wield, null, null, Destroy] +item=Keris(p), id=10582, option=[null, Wield, null, null, Destroy] +item=Keris(p+), id=10583, option=[null, Wield, null, null, Destroy] +item=Keris(p++), id=10584, option=[null, Wield, null, null, Destroy] +item=Parchment, id=10585, option=[Read, null, null, null, Destroy] +item=Combat lamp, id=10586, option=[Rub, null, null, null, Destroy] +item=Tarn's diary, id=10587, option=[null, Read, null, null, Destroy] +item=Salve amulet(e), id=10588, option=[null, Wear, null, null, drop] +item=Granite helm, id=10589, option=[null, Wear, null, null, drop] +item=Granite helm, id=10590, option=[null, null, null, null, drop] +item=Terror dog, id=10591, option=[null, null, null, null, drop] +item=Penguin bongos, id=10592, option=[Play, null, null, null, drop] +item=Cowbells, id=10593, option=[Play, null, null, null, drop] +item=Clockwork book, id=10594, option=[Read, null, null, null, drop] +item=Clockwork suit, id=10595, option=[Wind, null, null, null, Destroy] +item=Clockwork suit, id=10596, option=[null, null, null, Release, Destroy] +item=Mission report, id=10597, option=[Read, null, null, null, drop] +item=Mission report, id=10598, option=[Read, null, null, null, drop] +item=Mission report, id=10599, option=[Read, null, null, null, drop] +item=Kgp id card, id=10600, option=[null, null, null, null, drop] +item=Mystic hat, id=10601, option=[null, Wear, null, null, drop] +item=Mystic hat, id=10602, option=[null, Wear, null, null, drop] +item=Mystic hat, id=10603, option=[null, Wear, null, null, drop] +item=Skeletal helm, id=10604, option=[null, Wear, null, null, drop] +item=Infinity top, id=10605, option=[null, Wear, null, null, drop] +item=Splitbark helm, id=10606, option=[null, Wear, null, null, drop] +item=Ghostly boots, id=10607, option=[null, Wear, null, null, drop] +item=Moonclan hat, id=10608, option=[null, Wear, null, null, drop] +item=Lunar helm, id=10609, option=[null, Wear, null, null, Destroy] +item=Decorative armour, id=10610, option=[null, Wear, null, null, drop] +item=Void knight top, id=10611, option=[null, Wear, null, null, drop] +item=Rogue mask, id=10612, option=[null, Wear, null, null, drop] +item=Rock-shell helm, id=10613, option=[null, Wear, null, null, drop] +item=Spined helm, id=10614, option=[null, Wear, null, null, drop] +item=Tribal mask, id=10615, option=[null, Wear, null, null, drop] +item=Tribal mask, id=10616, option=[null, Wear, null, null, drop] +item=Tribal mask, id=10617, option=[null, Wear, null, null, drop] +item=White platebody, id=10618, option=[null, Wear, null, null, drop] +item=Initiate hauberk, id=10619, option=[null, Wear, null, null, drop] +item=Proselyte hauberk, id=10620, option=[null, Wear, null, null, drop] +item=Mourner top, id=10621, option=[null, Wear, null, null, drop] +item=Kyatt top, id=10622, option=[null, Wear, null, null, drop] +item=Larupia top, id=10623, option=[null, Wear, null, null, drop] +item=Graahk top, id=10624, option=[null, Wear, null, null, drop] +item=Wood camo top, id=10625, option=[null, Wear, null, null, drop] +item=Jungle camo top, id=10626, option=[null, Wear, null, null, drop] +item=Desert camo top, id=10627, option=[null, Wear, null, null, drop] +item=Polar camo top, id=10628, option=[null, Wear, null, null, drop] +item=Mime mask, id=10629, option=[null, Wear, null, null, drop] +item=Princess blouse, id=10630, option=[null, Wear, null, null, drop] +item=Zombie shirt, id=10631, option=[null, Wear, null, null, drop] +item=Camo top, id=10632, option=[null, Wear, null, null, drop] +item=Lederhosen top, id=10633, option=[null, Wear, null, null, drop] +item=Shade robe, id=10634, option=[null, Wear, null, null, drop] +item=Cape of legends, id=10635, option=[null, Wear, null, null, drop] +item=Obsidian cape, id=10636, option=[null, Wear, null, null, drop] +item=Fire cape, id=10637, option=[null, Wear, null, null, drop] +item=Team-1 cape, id=10638, option=[null, Wear, null, null, drop] +item=Attack cape, id=10639, option=[null, Wear, null, null, drop] +item=Strength cape, id=10640, option=[null, Wear, null, null, drop] +item=Defence cape, id=10641, option=[null, Wear, null, null, drop] +item=Ranging cape, id=10642, option=[null, Wear, null, null, drop] +item=Prayer cape, id=10643, option=[null, Wear, null, null, drop] +item=Magic cape, id=10644, option=[null, Wear, null, null, drop] +item=Runecraft cape, id=10645, option=[null, Wear, null, null, drop] +item=Hunter cape, id=10646, option=[null, Wear, null, null, drop] +item=Hitpoints cape, id=10647, option=[null, Wear, null, null, drop] +item=Agility cape, id=10648, option=[null, Wear, null, null, drop] +item=Herblore cape, id=10649, option=[null, Wear, null, null, drop] +item=Thieving cape, id=10650, option=[null, Wear, null, null, drop] +item=Crafting cape, id=10651, option=[null, Wear, null, null, drop] +item=Fletching cape, id=10652, option=[null, Wear, null, null, drop] +item=Slayer cape, id=10653, option=[null, Wear, null, null, drop] +item=Construct. cape, id=10654, option=[null, Wear, null, null, drop] +item=Mining cape, id=10655, option=[null, Wear, null, null, drop] +item=Smithing cape, id=10656, option=[null, Wear, null, null, drop] +item=Fishing cape, id=10657, option=[null, Wear, null, null, drop] +item=Cooking cape, id=10658, option=[null, Wear, null, null, drop] +item=Firemaking cape, id=10659, option=[null, Wear, null, null, drop] +item=Woodcutting cape, id=10660, option=[null, Wear, null, null, drop] +item=Farming cape, id=10661, option=[null, Wear, null, null, drop] +item=Quest point cape, id=10662, option=[null, Wear, null, null, drop] +item=Spotted cape, id=10663, option=[null, Wear, null, null, drop] +item=Spottier cape, id=10664, option=[null, Wear, null, null, drop] +item=Black shield(h1), id=10665, option=[null, Wear, null, null, drop] +item=Adamant shield(h1), id=10666, option=[null, Wear, null, null, drop] +item=Rune shield(h1), id=10667, option=[null, Wear, null, null, drop] +item=Black shield(h2), id=10668, option=[null, Wear, null, null, drop] +item=Adamant shield(h2), id=10669, option=[null, Wear, null, null, drop] +item=Rune shield(h2), id=10670, option=[null, Wear, null, null, drop] +item=Black shield(h3), id=10671, option=[null, Wear, null, null, drop] +item=Adamant shield(h3), id=10672, option=[null, Wear, null, null, drop] +item=Rune shield(h3), id=10673, option=[null, Wear, null, null, drop] +item=Black shield(h4), id=10674, option=[null, Wear, null, null, drop] +item=Adamant shield(h4), id=10675, option=[null, Wear, null, null, drop] +item=Rune shield(h4), id=10676, option=[null, Wear, null, null, drop] +item=Black shield(h5), id=10677, option=[null, Wear, null, null, drop] +item=Adamant shield(h5), id=10678, option=[null, Wear, null, null, drop] +item=Rune shield(h5), id=10679, option=[null, Wear, null, null, drop] +item=Studded body (g), id=10680, option=[null, Wear, null, null, drop] +item=Studded body (t), id=10681, option=[null, Wear, null, null, drop] +item=D'hide body(g), id=10682, option=[null, Wear, null, null, drop] +item=D'hide body (t), id=10683, option=[null, Wear, null, null, drop] +item=D'hide body (g), id=10684, option=[null, Wear, null, null, drop] +item=D'hide body (t), id=10685, option=[null, Wear, null, null, drop] +item=Wizard robe (g), id=10686, option=[null, Wear, null, null, drop] +item=Wizard robe (t), id=10687, option=[null, Wear, null, null, drop] +item=Enchanted top, id=10688, option=[null, Wear, null, null, drop] +item=Wizard boots, id=10689, option=[null, Wear, null, null, drop] +item=Black platebody (t), id=10690, option=[null, Wear, null, null, drop] +item=Black platebody (g), id=10691, option=[null, Wear, null, null, drop] +item=Highwayman mask, id=10692, option=[null, Wear, null, null, drop] +item=Blue beret, id=10693, option=[null, Wear, null, null, drop] +item=Black beret, id=10694, option=[null, Wear, null, null, drop] +item=White beret, id=10695, option=[null, Wear, null, null, drop] +item=Ranger boots, id=10696, option=[null, Wear, null, null, drop] +item=Adam platebody (t), id=10697, option=[null, Wear, null, null, drop] +item=Adam platebody (g), id=10698, option=[null, Wear, null, null, drop] +item=Black helm (h1), id=10699, option=[null, Wear, null, null, drop] +item=Black helm (h2), id=10700, option=[null, Wear, null, null, drop] +item=Black helm (h3), id=10701, option=[null, Wear, null, null, drop] +item=Black helm (h4), id=10702, option=[null, Wear, null, null, drop] +item=Black helm (h5), id=10703, option=[null, Wear, null, null, drop] +item=Rune helm (h1), id=10704, option=[null, Wear, null, null, drop] +item=Rune helm (h2), id=10705, option=[null, Wear, null, null, drop] +item=Rune helm (h3), id=10706, option=[null, Wear, null, null, drop] +item=Rune helm (h4), id=10707, option=[null, Wear, null, null, drop] +item=Rune helm (h5), id=10708, option=[null, Wear, null, null, drop] +item=Adamant helm (h1), id=10709, option=[null, Wear, null, null, drop] +item=Adamant helm (h2), id=10710, option=[null, Wear, null, null, drop] +item=Adamant helm (h3), id=10711, option=[null, Wear, null, null, drop] +item=Adamant helm (h4), id=10712, option=[null, Wear, null, null, drop] +item=Adamant helm (h5), id=10713, option=[null, Wear, null, null, drop] +item=Bob shirt, id=10714, option=[null, Wear, null, null, drop] +item=Bob shirt, id=10715, option=[null, Wear, null, null, drop] +item=Bob shirt, id=10716, option=[null, Wear, null, null, drop] +item=Bob shirt, id=10717, option=[null, Wear, null, null, drop] +item=Bob shirt, id=10718, option=[null, Wear, null, null, drop] +item=Amulet of glory(t), id=10719, option=[null, Wear, null, Rub, drop] +item=Guthix cape, id=10720, option=[null, Wear, null, null, drop] +item=Frog mask, id=10721, option=[null, Wear, null, null, drop] +item=Reindeer hat, id=10722, option=[null, Wear, null, null, Destroy] +item=Jack lantern mask, id=10723, option=[null, Wear, null, null, Destroy] +item=Skeleton boots, id=10724, option=[null, Wear, null, null, Destroy] +item=Skeleton gloves, id=10725, option=[null, Wear, null, null, Destroy] +item=Skeleton leggings, id=10726, option=[null, Wear, null, null, Destroy] +item=Skeleton shirt, id=10727, option=[null, Wear, null, null, Destroy] +item=Skeleton mask, id=10728, option=[null, Wear, null, null, Destroy] +item=Easter ring, id=10729, option=[null, Wear, null, null, drop] +item=Blue marionette, id=10730, option=[Jump, Walk, Bow, Dance, Destroy] +item=Zombie head, id=10731, option=[Talk-At, Display, Question, null, drop] +item=Rubber chicken, id=10732, option=[null, Wield, Dance, null, drop] +item=Yo-yo, id=10733, option=[Play, Loop, Walk, Crazy, drop] +item=Bunny ears, id=10734, option=[null, Wear, null, null, drop] +item=Scythe, id=10735, option=[null, Wield, null, null, drop] +item=Strength amulet(t), id=10736, option=[null, Wear, null, null, drop] +item=Cheat, id=10737, option=[null, null, null, null, drop] +item=Amulet of magic(t), id=10738, option=[null, Wear, null, null, drop] +item=Cheat, id=10739, option=[null, null, null, null, drop] +item=A powdered wig, id=10740, option=[null, Wear, null, null, drop] +item=Cheat, id=10741, option=[null, null, null, null, drop] +item=Flared trousers, id=10742, option=[null, Wear, null, null, drop] +item=Cheat, id=10743, option=[null, null, null, null, drop] +item=Pantaloons, id=10744, option=[null, Wear, null, null, drop] +item=Cheat, id=10745, option=[null, null, null, null, drop] +item=Sleeping cap, id=10746, option=[null, Wear, null, null, drop] +item=Cheat, id=10747, option=[null, null, null, null, drop] +item=Elegant shirt, id=10748, option=[null, Wear, null, null, drop] +item=Cheat, id=10749, option=[null, null, null, null, drop] +item=Elegant shirt, id=10750, option=[null, Wear, null, null, drop] +item=Cheat, id=10751, option=[null, null, null, null, drop] +item=Elegant shirt, id=10752, option=[null, Wear, null, null, drop] +item=Cheat, id=10753, option=[null, null, null, null, drop] +item=Elegant shirt, id=10754, option=[null, Wear, null, null, drop] +item=Cheat, id=10755, option=[null, null, null, null, drop] +item=Elegant shirt, id=10756, option=[null, Wear, null, null, drop] +item=Cheat, id=10757, option=[null, null, null, null, drop] +item=Red boater, id=10758, option=[null, Wear, null, null, drop] +item=Cheat, id=10759, option=[null, null, null, null, drop] +item=Orange boater, id=10760, option=[null, Wear, null, null, drop] +item=Cheat, id=10761, option=[null, null, null, null, drop] +item=Green boater, id=10762, option=[null, Wear, null, null, drop] +item=Cheat, id=10763, option=[null, null, null, null, drop] +item=Blue boater, id=10764, option=[null, Wear, null, null, drop] +item=Cheat, id=10765, option=[null, null, null, null, drop] +item=Black boater, id=10766, option=[null, Wear, null, null, drop] +item=Cheat, id=10767, option=[null, null, null, null, drop] +item=Red headband, id=10768, option=[null, Wear, null, null, drop] +item=Cheat, id=10769, option=[null, null, null, null, drop] +item=Black headband, id=10770, option=[null, Wear, null, null, drop] +item=Cheat, id=10771, option=[null, null, null, null, drop] +item=Brown headband, id=10772, option=[null, Wear, null, null, drop] +item=Cheat, id=10773, option=[null, null, null, null, drop] +item=Pirate's hat, id=10774, option=[null, Wear, null, null, drop] +item=Cheat, id=10775, option=[null, null, null, null, drop] +item=Zamorak platebody, id=10776, option=[null, Wear, null, null, drop] +item=Cheat, id=10777, option=[null, null, null, null, drop] +item=Saradomin plate, id=10778, option=[null, Wear, null, null, drop] +item=Cheat, id=10779, option=[null, null, null, null, drop] +item=Guthix platebody, id=10780, option=[null, Wear, null, null, drop] +item=Cheat, id=10781, option=[null, null, null, null, drop] +item=Gilded platebody, id=10782, option=[null, Wear, null, null, drop] +item=Cheat, id=10783, option=[null, null, null, null, drop] +item=Saradomin robe top, id=10784, option=[null, Wear, null, null, drop] +item=Cheat, id=10785, option=[null, null, null, null, drop] +item=Zamorak robe top, id=10786, option=[null, Wear, null, null, drop] +item=Cheat, id=10787, option=[null, null, null, null, drop] +item=Guthix robe top, id=10788, option=[null, Wear, null, null, drop] +item=Cheat, id=10789, option=[null, null, null, null, drop] +item=Zamorak d'hide, id=10790, option=[null, Wear, null, null, drop] +item=Cheat, id=10791, option=[null, null, null, null, drop] +item=Saradomin d'hide, id=10792, option=[null, Wear, null, null, drop] +item=Cheat, id=10793, option=[null, null, null, null, drop] +item=Guthix dragonhide, id=10794, option=[null, Wear, null, null, drop] +item=Cheat, id=10795, option=[null, null, null, null, drop] +item=Robin hood hat, id=10796, option=[null, Wear, null, null, drop] +item=Cheat, id=10797, option=[null, null, null, null, drop] +item=Rune platebody (g), id=10798, option=[null, Wear, null, null, drop] +item=Cheat, id=10799, option=[null, null, null, null, drop] +item=Rune platebody (t), id=10800, option=[null, Wear, null, null, drop] +item=Cheat, id=10801, option=[null, null, null, null, drop] +item=Tan cavalier, id=10802, option=[null, Wear, null, null, drop] +item=Cheat, id=10803, option=[null, null, null, null, drop] +item=Dark cavalier, id=10804, option=[null, Wear, null, null, drop] +item=Cheat, id=10805, option=[null, null, null, null, drop] +item=Black cavalier, id=10806, option=[null, Wear, null, null, drop] +item=Cheat, id=10807, option=[null, null, null, null, drop] +item=Arctic pyre logs, id=10808, option=[null, null, null, null, drop] +item=Arctic pyre logs, id=10809, option=[null, null, null, null, drop] +item=Arctic pine logs, id=10810, option=[null, null, null, null, drop] +item=Arctic pine logs, id=10811, option=[null, null, null, null, drop] +item=Split log, id=10812, option=[null, null, null, null, drop] +item=Split log, id=10813, option=[null, null, null, null, drop] +item=Hair, id=10814, option=[null, null, null, null, drop] +item=Hair, id=10815, option=[null, null, null, null, drop] +item=Raw yak meat, id=10816, option=[null, null, null, null, drop] +item=Raw yak meat, id=10817, option=[null, null, null, null, drop] +item=Yak-hide, id=10818, option=[null, null, null, null, drop] +item=Yak-hide, id=10819, option=[null, null, null, null, drop] +item=Cured yak-hide, id=10820, option=[null, null, null, null, drop] +item=Cured yak-hide, id=10821, option=[null, null, null, null, drop] +item=Yak-hide armour, id=10822, option=[null, Wear, null, null, drop] +item=Yak-hide armour, id=10823, option=[null, null, null, null, drop] +item=Yak-hide armour, id=10824, option=[null, Wear, null, null, drop] +item=Yak-hide armour, id=10825, option=[null, null, null, null, drop] +item=Fremennik shield, id=10826, option=[null, Wield, null, null, drop] +item=Fremennik shield, id=10827, option=[null, null, null, null, drop] +item=Helm of neitiznot, id=10828, option=[null, Wear, null, null, drop] +item=Documents, id=10829, option=[Open note, null, null, null, Destroy] +item=Royal decree, id=10830, option=[null, null, null, null, Destroy] +item=Empty tax bag, id=10831, option=[Check tax, null, null, null, Destroy] +item=Light tax bag, id=10832, option=[Check tax, null, null, null, Destroy] +item=Normal tax bag, id=10833, option=[Check tax, null, null, null, Destroy] +item=Hefty tax bag, id=10834, option=[Check tax, null, null, null, Destroy] +item=Bulging taxbag, id=10835, option=[Check taxes, null, null, null, Destroy] +item=Silly jester hat, id=10836, option=[null, Wear, null, null, Destroy] +item=Silly jester top, id=10837, option=[null, Wear, null, null, Destroy] +item=Silly jester tights, id=10838, option=[null, Wear, null, null, Destroy] +item=Silly jester boots, id=10839, option=[null, Wear, null, null, Destroy] +item=A jester stick, id=10840, option=[null, Wield, null, null, drop] +item=Apricot cream pie, id=10841, option=[null, null, null, null, drop] +item=Decapitated head, id=10842, option=[null, null, null, null, Destroy] +item=Helm of neitiznot, id=10843, option=[null, null, null, null, drop] +item=Spring sq'irk, id=10844, option=[null, null, null, null, drop] +item=Summer sq'irk, id=10845, option=[null, null, null, null, drop] +item=Autumn sq'irk, id=10846, option=[null, null, null, null, drop] +item=Winter sq'irk, id=10847, option=[null, null, null, null, drop] +item=Spring sq'irkjuice, id=10848, option=[Drink, null, null, null, drop] +item=Summer sq'irkjuice, id=10849, option=[Drink, null, null, null, drop] +item=Autumn sq'irkjuice, id=10850, option=[Drink, null, null, null, drop] +item=Winter sq'irkjuice, id=10851, option=[Drink, null, null, null, drop] +item=Summer garden, id=10852, option=[null, null, null, null, drop] +item=Spring garden, id=10853, option=[null, null, null, null, drop] +item=Autumn garden, id=10854, option=[null, null, null, null, drop] +item=Winter garden, id=10855, option=[null, null, null, null, drop] +item=Sin seer's note, id=10856, option=[null, null, null, null, Destroy] +item=Severed leg, id=10857, option=[null, null, null, null, Destroy] +item=Shadow sword, id=10858, option=[null, Wield, null, null, Destroy] +item=Tea flask, id=10859, option=[Drink, Look-in, null, null, drop] +item=Tea flask, id=10860, option=[null, Use, null, null, drop] +item=Tea flask, id=10861, option=[null, Use, null, null, drop] +item=Hard hat, id=10862, option=[null, Wear, null, null, Destroy] +item=Builder's shirt, id=10863, option=[null, Wear, null, null, Destroy] +item=Builder's trousers, id=10864, option=[null, Wear, null, null, Destroy] +item=Builder's boots, id=10865, option=[null, Wear, null, null, Destroy] +item=Rivets, id=10866, option=[null, null, null, null, drop] +item=null, id=10867, option=[null, null, null, null, drop] +item=null, id=10868, option=[null, null, null, null, drop] +item=null, id=10869, option=[null, null, null, null, drop] +item=Binding fluid, id=10870, option=[null, null, null, null, drop] +item=Pipe, id=10871, option=[null, null, null, null, drop] +item=Pipe ring, id=10872, option=[null, null, null, null, drop] +item=Metal sheet, id=10873, option=[null, null, null, null, drop] +item=Coloured ball, id=10874, option=[null, null, null, null, drop] +item=Valve wheel, id=10875, option=[null, null, null, null, drop] +item=Metal bar, id=10876, option=[null, null, null, null, drop] +item=Plain satchel, id=10877, option=[Inspect, Wear, null, Empty, drop] +item=Green satchel, id=10878, option=[Inspect, Wear, null, Empty, drop] +item=Red satchel, id=10879, option=[Inspect, Wear, null, Empty, drop] +item=Black satchel, id=10880, option=[Inspect, Wear, null, Empty, drop] +item=Gold satchel, id=10881, option=[Inspect, Wear, null, Empty, drop] +item=Rune satchel, id=10882, option=[Inspect, Wear, null, Empty, drop] +item=Hard hat, id=10883, option=[null, Wear, null, null, Destroy] +item=Fuse, id=10884, option=[null, null, null, null, drop] +item=Keg, id=10885, option=[null, null, null, null, drop] +item=Prayer book, id=10886, option=[null, null, null, null, drop] +item=Barrelchest anchor, id=10887, option=[null, Wield, null, null, Destroy] +item=Barrelchest anchor, id=10888, option=[null, null, null, null, drop] +item=Blessed lamp, id=10889, option=[Pray-over, null, null, null, Destroy] +item=Prayer book, id=10890, option=[Read, Recite-prayer, null, null, Destroy] +item=Wooden cat, id=10891, option=[null, null, null, null, drop] +item=Wooden cat, id=10892, option=[null, null, null, null, drop] +item=Cranial clamp, id=10893, option=[null, null, null, null, drop] +item=Brain tongs, id=10894, option=[null, null, null, null, drop] +item=Bell jar, id=10895, option=[null, null, null, null, drop] +item=Wolf whistle, id=10896, option=[Blow, null, null, null, drop] +item=Shipping order, id=10897, option=[null, null, null, null, drop] +item=Keg, id=10898, option=[null, null, null, null, drop] +item=Crate part, id=10899, option=[null, null, null, null, drop] +item=null, id=10900, option=[null, null, null, null, drop] +item=null, id=10901, option=[null, null, null, null, drop] +item=null, id=10902, option=[null, null, null, null, drop] +item=null, id=10903, option=[null, null, null, null, drop] +item=Skull staple, id=10904, option=[null, null, null, null, drop] +item=null, id=10905, option=[null, null, null, null, drop] +item=null, id=10906, option=[null, null, null, null, drop] +item=null, id=10907, option=[null, null, null, null, drop] +item=null, id=10908, option=[null, null, null, null, drop] +item=Mixture - step 1(4), id=10909, option=[null, null, null, Empty, drop] +item=Mixture - step 1(4), id=10910, option=[null, null, null, null, drop] +item=Mixture - step 1(3), id=10911, option=[null, null, null, Empty, drop] +item=Mixture - step 1(3), id=10912, option=[null, null, null, null, drop] +item=Mixture - step 1(2), id=10913, option=[null, null, null, Empty, drop] +item=Mixture - step 1(2), id=10914, option=[null, null, null, null, drop] +item=Mixture - step 1(1), id=10915, option=[null, null, null, Empty, drop] +item=Mixture - step 1(1), id=10916, option=[null, null, null, null, drop] +item=Mixture - step 2(4), id=10917, option=[null, null, null, Empty, drop] +item=Mixture - step 2(4), id=10918, option=[null, null, null, null, drop] +item=Mixture - step 2(3), id=10919, option=[null, null, null, Empty, drop] +item=Mixture - step 2(3), id=10920, option=[null, null, null, null, drop] +item=Mixture - step 2(2), id=10921, option=[null, null, null, Empty, drop] +item=Mixture - step 2(2), id=10922, option=[null, null, null, null, drop] +item=Mixture - step 2(1), id=10923, option=[null, null, null, Empty, drop] +item=Mixture - step 2(1), id=10924, option=[null, null, null, null, drop] +item=Sanfew serum(4), id=10925, option=[Drink, null, null, Empty, drop] +item=Sanfew serum(4), id=10926, option=[null, null, null, null, drop] +item=Sanfew serum(3), id=10927, option=[Drink, null, null, Empty, drop] +item=Sanfew serum(3), id=10928, option=[null, null, null, null, drop] +item=Sanfew serum(2), id=10929, option=[Drink, null, null, Empty, drop] +item=Sanfew serum(2), id=10930, option=[null, null, null, null, drop] +item=Sanfew serum(1), id=10931, option=[Drink, null, null, Empty, drop] +item=Sanfew serum(1), id=10932, option=[null, null, null, null, drop] +item=Lumberjack boots, id=10933, option=[null, Wear, null, null, drop] +item=Reward token, id=10934, option=[Look-at, null, null, null, Destroy] +item=Reward token, id=10935, option=[Look-at, null, null, null, Destroy] +item=Reward token, id=10936, option=[Look-at, null, null, null, Destroy] +item=Nail beast nails, id=10937, option=[null, null, null, null, drop] +item=Nail beast nails, id=10938, option=[null, null, null, null, drop] +item=Lumberjack top, id=10939, option=[null, Wear, null, null, drop] +item=Lumberjack legs, id=10940, option=[null, Wear, null, null, drop] +item=Lumberjack hat, id=10941, option=[null, Wear, null, null, drop] +item=Reward token, id=10942, option=[Look-at, null, null, null, Destroy] +item=Reward token, id=10943, option=[Look-at, null, null, null, Destroy] +item=Reward token, id=10944, option=[Look-at, null, null, null, Destroy] +item=Lumberjack top, id=10945, option=[null, Wear, null, null, drop] +item=Pushup, id=10946, option=[null, null, null, null, drop] +item=Run, id=10947, option=[null, null, null, null, drop] +item=Situp, id=10948, option=[null, null, null, null, drop] +item=Starjump, id=10949, option=[null, null, null, null, drop] +item=Skull staples, id=10950, option=[null, null, null, null, drop] +item=Skull staples, id=10951, option=[null, null, null, null, drop] +item=Slayer bell, id=10952, option=[Ring, null, null, null, drop] +item=Slayer bell, id=10953, option=[null, null, null, null, drop] +item=Frog-leather body, id=10954, option=[null, Wear, null, null, drop] +item=Frog-leather body, id=10955, option=[null, null, null, null, drop] +item=Frog-leather chaps, id=10956, option=[null, Wear, null, null, drop] +item=Frog-leather chaps, id=10957, option=[null, null, null, null, drop] +item=Frog-leather boots, id=10958, option=[null, Wear, null, null, drop] +item=Frog-leather boots, id=10959, option=[null, null, null, null, drop] +item=Green gloop soup, id=10960, option=[Eat, null, null, null, drop] +item=Frogspawn gumbo, id=10961, option=[Eat, null, null, null, drop] +item=Frogburger, id=10962, option=[Eat, null, null, null, drop] +item=Coated frogs' legs, id=10963, option=[Eat, null, null, null, drop] +item=Bat shish, id=10964, option=[Eat, null, null, null, drop] +item=Fingers, id=10965, option=[Eat, null, null, null, drop] +item=Grubs ? la mode, id=10966, option=[Eat, null, null, null, drop] +item=Roast frog, id=10967, option=[Eat, null, null, null, drop] +item=Mushrooms, id=10968, option=[Eat, null, null, null, drop] +item=Fillets, id=10969, option=[Eat, null, null, null, drop] +item=Loach, id=10970, option=[Eat, null, null, null, drop] +item=Eel sushi, id=10971, option=[Eat, null, null, null, drop] +item=Dorgesh-kaan sphere, id=10972, option=[Break, null, null, null, drop] +item=Light orb, id=10973, option=[null, null, null, null, drop] +item=Light orb, id=10974, option=[null, null, null, null, drop] +item=Spanner, id=10975, option=[null, null, null, null, drop] +item=Long bone, id=10976, option=[Bury, null, null, null, drop] +item=Curved bone, id=10977, option=[Bury, null, null, null, drop] +item=Swamp weed, id=10978, option=[null, null, null, null, drop] +item=Swamp weed, id=10979, option=[null, null, null, null, drop] +item=Empty light orb, id=10980, option=[null, null, null, null, drop] +item=Cave goblin wire, id=10981, option=[null, null, null, null, drop] +item=Cave goblin wire, id=10982, option=[null, null, null, null, drop] +item=Cog, id=10983, option=[null, null, null, null, Destroy] +item=Cog, id=10984, option=[null, null, null, null, Destroy] +item=Fuse, id=10985, option=[null, null, null, null, Destroy] +item=Fuse, id=10986, option=[null, null, null, null, Destroy] +item=Meter, id=10987, option=[null, null, null, null, Destroy] +item=Meter, id=10988, option=[null, null, null, null, Destroy] +item=Capacitor, id=10989, option=[null, null, null, null, Destroy] +item=Capacitor, id=10990, option=[null, null, null, null, Destroy] +item=Lever, id=10991, option=[null, null, null, null, Destroy] +item=Lever, id=10992, option=[null, null, null, null, Destroy] +item=Powerbox, id=10993, option=[null, null, null, null, Destroy] +item=Powerbox, id=10994, option=[null, null, null, null, Destroy] +item=Perfect shell, id=10995, option=[null, null, null, null, drop] +item=Perfect snail shell, id=10996, option=[null, null, null, null, drop] +item=Molanisk, id=10997, option=[null, null, null, null, drop] +item=Cave goblin, id=10998, option=[null, null, null, null, drop] +item=Goblin book, id=10999, option=[Read, null, null, null, drop] +item=Whoopsie, id=11000, option=[null, null, null, null, drop] +item=Dagon'hai history, id=11001, option=[Read, null, null, null, Destroy] +item=Sin'keth's diary, id=11002, option=[Read, null, null, null, Destroy] +item=An empty folder, id=11003, option=[Read, null, null, null, Destroy] +item=null, id=11004, option=[null, null, null, null, drop] +item=null, id=11005, option=[null, null, null, null, drop] +item=Used folder, id=11006, option=[Read, null, null, null, Destroy] +item=Full folder, id=11007, option=[Read, null, null, null, Destroy] +item=Rat's paper, id=11008, option=[Read, null, null, null, Destroy] +item=Rat's letter, id=11009, option=[Read, null, null, null, Destroy] +item=Surok's letter, id=11010, option=[Read, null, null, null, Destroy] +item=Zaff's instructions, id=11011, option=[Read, null, null, null, drop] +item=Wand, id=11012, option=[null, null, null, null, Destroy] +item=Infused wand, id=11013, option=[null, null, null, null, Destroy] +item=Beacon ring, id=11014, option=[null, Wear, Operate, null, Destroy] +item=Chicken head, id=11015, option=[null, null, null, null, drop] +item=Chicken feet, id=11016, option=[null, null, null, null, drop] +item=Chicken wings, id=11017, option=[null, null, null, null, drop] +item=Chicken legs, id=11018, option=[null, null, null, null, drop] +item=Chicken feet, id=11019, option=[null, Wear, null, null, Destroy] +item=Chicken wings, id=11020, option=[null, Wear, null, null, Destroy] +item=Chicken head, id=11021, option=[null, Wear, null, null, Destroy] +item=Chicken legs, id=11022, option=[null, Wear, null, null, Destroy] +item=Magic egg, id=11023, option=[Eat, null, null, null, Destroy] +item=Rabbit mould, id=11024, option=[null, null, null, null, Destroy] +item=Chocolate chunks, id=11025, option=[null, null, null, null, drop] +item=Chocolate kebbit, id=11026, option=[Eat, null, null, null, Drop] +item=Easter egg, id=11027, option=[Release, null, null, null, Destroy] +item=Easter egg, id=11028, option=[Release, null, null, null, Destroy] +item=Easter egg, id=11029, option=[Release, null, null, null, Destroy] +item=Easter egg, id=11030, option=[Release, null, null, null, Destroy] +item=Damp planks, id=11031, option=[null, null, null, null, Destroy] +item=Crude carving, id=11032, option=[null, null, null, null, Destroy] +item=Cruder carving, id=11033, option=[null, null, null, null, Destroy] +item=Sven's last map, id=11034, option=[Read, null, null, null, Destroy] +item=Windswept logs, id=11035, option=[null, null, null, null, Destroy] +item=Parchment, id=11036, option=[Read, null, null, null, Destroy] +item=Brine sabre, id=11037, option=[null, Wield, null, null, drop] +item=Brine sabre, id=11038, option=[null, null, null, null, drop] +item=Key, id=11039, option=[null, null, null, null, Destroy] +item=Key, id=11040, option=[null, null, null, null, Destroy] +item=Key, id=11041, option=[null, null, null, null, Destroy] +item=Key, id=11042, option=[null, null, null, null, Destroy] +item=Key, id=11043, option=[null, null, null, null, Destroy] +item=Rotten barrel, id=11044, option=[null, null, null, null, drop] +item=Rotten barrel, id=11045, option=[null, null, null, null, Destroy] +item=Rope, id=11046, option=[null, null, null, null, drop] +item=Brine rat, id=11047, option=[null, null, null, null, drop] +item=Armour shard, id=11048, option=[null, null, null, null, drop] +item=Artefact, id=11049, option=[null, null, null, null, drop] +item=Axe head, id=11050, option=[null, null, null, null, drop] +item=Artefact, id=11051, option=[null, null, null, null, drop] +item=Helmet fragment, id=11052, option=[null, null, null, null, drop] +item=Artefact, id=11053, option=[null, null, null, null, drop] +item=Shield fragment, id=11054, option=[null, null, null, null, drop] +item=Artefact, id=11055, option=[null, null, null, null, drop] +item=Sword fragment, id=11056, option=[null, null, null, null, drop] +item=Artefact, id=11057, option=[null, null, null, null, drop] +item=Mace, id=11058, option=[null, null, null, null, drop] +item=Artefact, id=11059, option=[null, null, null, null, drop] +item=Goblin village sphere, id=11060, option=[Break, null, null, null, drop] +item=Ancient mace, id=11061, option=[null, Wield, null, null, drop] +item=Zanik (slice), id=11062, option=[null, null, null, null, drop] +item=null, id=11063, option=[null, null, null, null, drop] +item=Ancient mace, id=11064, option=[null, null, null, null, drop] +item=Bracelet mould, id=11065, option=[null, null, null, null, drop] +item=Bracelet mould, id=11066, option=[null, null, null, null, drop] +item=null, id=11067, option=[null, null, null, null, drop] +item=null, id=11068, option=[null, Wear, null, null, drop] +item=Gold bracelet, id=11069, option=[null, Wear, null, null, drop] +item=Gold bracelet, id=11070, option=[null, null, null, null, drop] +item=null, id=11071, option=[null, Wear, null, null, drop] +item=Sapphire bracelet, id=11072, option=[null, Wear, null, null, drop] +item=Sapphire bracelet, id=11073, option=[null, null, null, null, drop] +item=Bracelet of clay, id=11074, option=[null, Wear, null, null, drop] +item=Bracelet of clay, id=11075, option=[null, null, null, null, drop] +item=Emerald bracelet, id=11076, option=[null, Wear, null, null, drop] +item=Emerald bracelet, id=11077, option=[null, null, null, null, drop] +item=null, id=11078, option=[null, Wear, null, null, drop] +item=Castlewar brace(3), id=11079, option=[null, Wear, null, null, drop] +item=Castlewar brace(3), id=11080, option=[null, null, null, null, drop] +item=Castlewar brace(2), id=11081, option=[null, Wear, null, null, drop] +item=Castlewar brace(2), id=11082, option=[null, null, null, null, drop] +item=Castlewar brace(1), id=11083, option=[null, Wear, null, null, drop] +item=Castlewar brace(1), id=11084, option=[null, null, null, null, drop] +item=Ruby bracelet, id=11085, option=[null, Wear, null, null, drop] +item=Ruby bracelet, id=11086, option=[null, null, null, null, drop] +item=null, id=11087, option=[null, Wear, null, null, drop] +item=Inoculation brace, id=11088, option=[null, Wear, null, null, drop] +item=Inoculation brace, id=11089, option=[null, null, null, null, drop] +item=Phoenix necklace, id=11090, option=[null, Wear, null, null, drop] +item=Phoenix necklace, id=11091, option=[null, null, null, null, drop] +item=Diamond bracelet, id=11092, option=[null, Wear, null, null, drop] +item=Diamond bracelet, id=11093, option=[null, null, null, null, drop] +item=null, id=11094, option=[null, Wear, null, null, drop] +item=Forinthry brace(5), id=11095, option=[null, Wear, null, null, drop] +item=Forinthry brace(5), id=11096, option=[null, null, null, null, drop] +item=Forinthry brace(4), id=11097, option=[null, Wear, null, null, drop] +item=Forinthry brace(4), id=11098, option=[null, null, null, null, drop] +item=Forinthry brace(3), id=11099, option=[null, Wear, null, null, drop] +item=Forinthry brace(3), id=11100, option=[null, null, null, null, drop] +item=Forinthry brace(2), id=11101, option=[null, Wear, null, null, drop] +item=Forinthry brace(2), id=11102, option=[null, null, null, null, drop] +item=Forinthry brace(1), id=11103, option=[null, Wear, null, null, drop] +item=Forinthry brace(1), id=11104, option=[null, null, null, null, drop] +item=Skills necklace(4), id=11105, option=[null, Wear, null, Rub, drop] +item=Skills necklace(4), id=11106, option=[null, null, null, null, drop] +item=Skills necklace(3), id=11107, option=[null, Wear, null, Rub, drop] +item=Skills necklace(3), id=11108, option=[null, null, null, null, drop] +item=Skills necklace(2), id=11109, option=[null, Wear, null, Rub, drop] +item=Skills necklace(2), id=11110, option=[null, null, null, null, drop] +item=Skills necklace(1), id=11111, option=[null, Wear, null, Rub, drop] +item=Skills necklace(1), id=11112, option=[null, null, null, null, drop] +item=Skills necklace, id=11113, option=[null, Wear, null, Rub, drop] +item=Skills necklace, id=11114, option=[null, null, null, null, drop] +item=Dragon bracelet, id=11115, option=[null, Wear, null, null, drop] +item=Dragon bracelet, id=11116, option=[null, null, null, null, drop] +item=null, id=11117, option=[null, Wear, null, null, drop] +item=Combat bracelet(4), id=11118, option=[null, Wear, null, Rub, drop] +item=Combat bracelet(4), id=11119, option=[null, null, null, null, drop] +item=Combat bracelet(3), id=11120, option=[null, Wear, null, Rub, drop] +item=Combat bracelet(3), id=11121, option=[null, null, null, null, drop] +item=Combat bracelet(2), id=11122, option=[null, Wear, null, Rub, drop] +item=Combat bracelet(2), id=11123, option=[null, null, null, null, drop] +item=Combat bracelet(1), id=11124, option=[null, Wear, null, Rub, drop] +item=Combat bracelet(1), id=11125, option=[null, null, null, null, drop] +item=Combat bracelet, id=11126, option=[null, Wear, null, Rub, drop] +item=Combat bracelet, id=11127, option=[null, null, null, null, drop] +item=Berserker necklace, id=11128, option=[null, Wear, null, null, drop] +item=Berserker necklace, id=11129, option=[null, null, null, null, drop] +item=Onyx bracelet, id=11130, option=[null, Wear, null, null, drop] +item=Onyx bracelet, id=11131, option=[null, null, null, null, drop] +item=null, id=11132, option=[null, Wear, null, null, drop] +item=Regen bracelet, id=11133, option=[null, Wear, null, null, drop] +item=Regen bracelet, id=11134, option=[null, null, null, null, drop] +item=Bomber jacket, id=11135, option=[null, null, null, null, drop] +item=Karamja gloves 1, id=11136, option=[null, Wear, null, null, Destroy] +item=Antique lamp, id=11137, option=[Rub, null, null, null, Destroy] +item=Karamja gloves 2, id=11138, option=[null, Wear, null, null, Destroy] +item=Antique lamp, id=11139, option=[Rub, null, null, null, Destroy] +item=Karamja gloves 3, id=11140, option=[null, Wear, Activate, null, Destroy] +item=Antique lamp, id=11141, option=[Rub, null, null, null, Destroy] +item=null, id=11142, option=[null, null, null, null, drop] +item=null, id=11143, option=[null, null, null, null, drop] +item=null, id=11144, option=[null, null, null, null, drop] +item=null, id=11145, option=[null, null, null, null, drop] +item=null, id=11146, option=[null, null, null, null, drop] +item=null, id=11147, option=[null, null, null, null, drop] +item=null, id=11148, option=[null, null, null, null, drop] +item=null, id=11149, option=[null, null, null, null, drop] +item=null, id=11150, option=[null, null, null, null, drop] +item=Dream vial (empty), id=11151, option=[null, null, null, null, Destroy] +item=Dream vial (water), id=11152, option=[null, null, null, null, Destroy] +item=Dream vial (herb), id=11153, option=[null, null, null, null, Destroy] +item=Dream potion, id=11154, option=[null, null, null, null, Destroy] +item=Ground astral rune, id=11155, option=[null, null, null, null, Destroy] +item=Astral rune shards, id=11156, option=[null, null, null, null, Destroy] +item=Dreamy lamp, id=11157, option=[Rub, null, null, null, Destroy] +item=Cyrisus's chest, id=11158, option=[Look-in, null, null, null, Destroy] +item=Hunter kit, id=11159, option=[Open, null, null, null, Destroy] +item=null, id=11160, option=[null, null, null, null, drop] +item=null, id=11161, option=[null, null, null, null, drop] +item=null, id=11162, option=[null, null, null, null, drop] +item=null, id=11163, option=[null, null, null, null, drop] +item=Restored shield, id=11164, option=[null, null, null, null, drop] +item=Phoenix crossbow, id=11165, option=[null, Wield, null, null, drop] +item=Phoenix crossbow, id=11166, option=[null, null, null, null, drop] +item=Phoenix crossbow, id=11167, option=[null, Wield, null, null, drop] +item=Phoenix crossbow, id=11168, option=[null, null, null, null, drop] +item=Newspaper, id=11169, option=[Read, null, null, null, drop] +item=Newspaper, id=11170, option=[null, null, null, null, drop] +item=Newspaper, id=11171, option=[Read, null, null, null, drop] +item=Newspaper, id=11172, option=[null, null, null, null, drop] +item=Half certificate, id=11173, option=[Read, null, null, null, Destroy] +item=Half certificate, id=11174, option=[Read, null, null, null, Destroy] +item=Uncleaned find, id=11175, option=[null, null, null, null, Destroy] +item=Arrowheads, id=11176, option=[null, null, null, null, drop] +item=Jewellery, id=11177, option=[null, null, null, null, drop] +item=Pottery, id=11178, option=[null, null, null, null, drop] +item=Old coin, id=11179, option=[null, null, null, null, drop] +item=Ancient coin, id=11180, option=[null, null, null, null, drop] +item=Ancient symbol, id=11181, option=[null, null, null, null, drop] +item=Old symbol, id=11182, option=[null, null, null, null, drop] +item=Old chipped vase, id=11183, option=[null, null, null, null, drop] +item=Museum map, id=11184, option=[Look-at, null, null, null, drop] +item=Antique lamp, id=11185, option=[Rub, null, null, null, Destroy] +item=Antique lamp, id=11186, option=[Rub, null, null, null, Destroy] +item=Antique lamp, id=11187, option=[Rub, null, null, null, Destroy] +item=Antique lamp, id=11188, option=[Rub, null, null, null, Destroy] +item=Antique lamp, id=11189, option=[Rub, null, null, null, Destroy] +item=Digsite pendant (1), id=11190, option=[null, Wear, null, Rub, drop] +item=Digsite pendant (2), id=11191, option=[null, Wear, null, Rub, drop] +item=Digsite pendant (3), id=11192, option=[null, Wear, null, Rub, drop] +item=Digsite pendant (4), id=11193, option=[null, Wear, null, Rub, drop] +item=Digsite pendant (5), id=11194, option=[null, Wear, null, Rub, drop] +item=Clean necklace, id=11195, option=[null, Wear, null, null, drop] +item=Griffin feather, id=11196, option=[null, null, null, null, Destroy] +item=Miazrqa's pendant, id=11197, option=[null, null, null, null, Destroy] +item=Music sheet, id=11198, option=[Read, null, null, null, Destroy] +item=Rupert's helmet, id=11199, option=[null, null, null, null, Destroy] +item=Dwarven helmet, id=11200, option=[null, Wear, null, null, Drop] +item=Dwarven helmet, id=11201, option=[null, null, null, null, drop] +item=Shrinking recipe, id=11202, option=[Read, null, null, null, Destroy] +item=To-do list, id=11203, option=[Read, null, null, null, Destroy] +item=Shrink-me-quick, id=11204, option=[Drink, null, null, Empty, Destroy] +item=Shrunk ogleroot, id=11205, option=[null, null, null, Eat, drop] +item=null, id=11206, option=[null, null, null, null, drop] +item=null, id=11207, option=[null, null, null, null, drop] +item=null, id=11208, option=[null, null, null, null, drop] +item=null, id=11209, option=[null, null, null, null, drop] +item=Golden goblin, id=11210, option=[null, null, null, null, Destroy] +item=Magic beans, id=11211, option=[null, null, null, null, Destroy] +item=Dragon arrow, id=11212, option=[null, Wield, null, null, drop] +item=null, id=11213, option=[null, null, null, null, drop] +item=null, id=11214, option=[null, null, null, null, drop] +item=null, id=11215, option=[null, null, null, null, drop] +item=null, id=11216, option=[null, null, null, null, drop] +item=Dragon fire arrows, id=11217, option=[null, Wield, null, null, drop] +item=null, id=11218, option=[null, null, null, null, drop] +item=null, id=11219, option=[null, null, null, null, drop] +item=null, id=11220, option=[null, null, null, null, drop] +item=null, id=11221, option=[null, null, null, null, drop] +item=Dragon fire arrows, id=11222, option=[null, Wield, null, null, drop] +item=null, id=11223, option=[null, null, null, null, drop] +item=null, id=11224, option=[null, null, null, null, drop] +item=null, id=11225, option=[null, null, null, null, drop] +item=null, id=11226, option=[null, null, null, null, drop] +item=Dragon arrow(p), id=11227, option=[null, Wield, null, null, drop] +item=Dragon arrow(p+), id=11228, option=[null, Wield, null, null, drop] +item=Dragon arrow(p++), id=11229, option=[null, Wield, null, null, drop] +item=Dragon dart, id=11230, option=[null, Wield, null, null, drop] +item=Dragon dart(p), id=11231, option=[null, Wield, null, null, drop] +item=Dragon dart tip, id=11232, option=[null, null, null, null, drop] +item=Dragon dart(p+), id=11233, option=[null, Wield, null, null, drop] +item=Dragon dart(p++), id=11234, option=[null, Wield, null, null, drop] +item=Dark bow, id=11235, option=[null, Wield, null, null, drop] +item=Dark bow, id=11236, option=[null, null, null, null, drop] +item=Dragon arrowtips, id=11237, option=[null, null, null, null, drop] +item=Baby impling jar, id=11238, option=[null, null, Loot, null, Destroy] +item=Baby impling jar, id=11239, option=[null, null, null, null, drop] +item=Young impling jar, id=11240, option=[null, null, Loot, null, Destroy] +item=Young impling jar, id=11241, option=[null, null, null, null, drop] +item=Gourm' impling jar, id=11242, option=[null, null, Loot, null, Destroy] +item=Gourm' impling jar, id=11243, option=[null, null, null, null, drop] +item=Earth impling jar, id=11244, option=[null, null, Loot, null, Destroy] +item=Earth impling jar, id=11245, option=[null, null, null, null, drop] +item=Ess' impling jar, id=11246, option=[null, null, Loot, null, Destroy] +item=Ess' impling jar, id=11247, option=[null, null, null, null, drop] +item=Eclectic impling jar, id=11248, option=[null, null, Loot, null, Destroy] +item=Eclectic impling jar, id=11249, option=[null, null, null, null, drop] +item=Nature impling jar, id=11250, option=[null, null, Loot, null, Destroy] +item=Nature impling jar, id=11251, option=[null, null, null, null, drop] +item=Magpie impling jar, id=11252, option=[null, null, Loot, null, Destroy] +item=Magpie impling jar, id=11253, option=[null, null, null, null, drop] +item=Ninja impling jar, id=11254, option=[null, null, Loot, null, Destroy] +item=Ninja impling jar, id=11255, option=[null, null, null, null, drop] +item=Dragon impling jar, id=11256, option=[null, null, Loot, null, Destroy] +item=Dragon impling jar, id=11257, option=[null, null, null, null, drop] +item=Jar generator, id=11258, option=[Butterfly-jar, null, Impling-jar, Check, Destroy] +item=Magic butterfly net, id=11259, option=[null, Wield, null, null, Destroy] +item=Impling jar, id=11260, option=[null, null, null, null, drop] +item=Impling jar, id=11261, option=[null, null, null, null, drop] +item=Imp repellent, id=11262, option=[null, null, null, Empty, drop] +item=Imp repellent, id=11263, option=[null, null, null, null, drop] +item=Anchovy oil, id=11264, option=[null, null, null, Empty, drop] +item=Anchovy oil, id=11265, option=[null, null, null, null, drop] +item=Anchovy paste, id=11266, option=[null, null, null, null, drop] +item=Dummy, id=11267, option=[null, null, null, null, drop] +item=Dummy, id=11268, option=[null, null, null, null, drop] +item=Dummy, id=11269, option=[null, null, null, null, drop] +item=Dummy, id=11270, option=[null, null, null, null, drop] +item=Dummy, id=11271, option=[null, null, null, Empty, drop] +item=Dummy, id=11272, option=[null, null, null, null, drop] +item=Impling scroll, id=11273, option=[Toggle-view, null, null, null, Destroy] +item=Ham shirt, id=11274, option=[null, Wear, null, null, drop] +item=Mith grapple, id=11275, option=[null, null, null, null, drop] +item=Mith grapple, id=11276, option=[null, null, null, null, drop] +item=Cavalier mask, id=11277, option=[null, Wear, null, null, drop] +item=Beret mask, id=11278, option=[null, Wear, null, null, drop] +item=Elvarg's head, id=11279, option=[null, null, null, null, Destroy] +item=Cavalier mask, id=11280, option=[null, Wear, null, null, drop] +item=Cavalier mask, id=11281, option=[null, null, null, null, drop] +item=Beret mask, id=11282, option=[null, Wear, null, null, drop] +item=Dragonfire shield, id=11283, option=[null, Wield, Inspect, Empty, drop] +item=Dragonfire shield, id=11284, option=[null, Wield, Inspect, null, drop] +item=Dragonfire shield, id=11285, option=[null, null, null, null, drop] +item=Draconic visage, id=11286, option=[null, null, null, null, drop] +item=Draconic visage, id=11287, option=[null, null, null, null, drop] +item=null, id=11288, option=[null, null, null, Empty, drop] +item=null, id=11289, option=[null, null, null, Empty, drop] +item=null, id=11290, option=[null, null, null, Empty, drop] +item=null, id=11291, option=[null, null, null, Empty, drop] +item=null, id=11292, option=[null, null, null, Empty, drop] +item=null, id=11293, option=[null, null, null, Empty, drop] +item=null, id=11294, option=[null, null, null, Empty, drop] +item=null, id=11295, option=[null, null, null, Empty, drop] +item=null, id=11296, option=[null, null, null, Empty, drop] +item=null, id=11297, option=[null, null, null, Empty, drop] +item=null, id=11298, option=[null, null, null, Empty, drop] +item=null, id=11299, option=[null, null, null, Empty, drop] +item=null, id=11300, option=[null, null, null, Empty, drop] +item=null, id=11301, option=[null, null, null, Empty, drop] +item=null, id=11302, option=[null, null, null, Empty, drop] +item=null, id=11303, option=[null, null, null, Empty, drop] +item=null, id=11304, option=[null, null, null, Empty, drop] +item=null, id=11305, option=[null, null, null, Empty, drop] +item=null, id=11306, option=[null, null, null, null, drop] +item=null, id=11307, option=[null, null, null, null, drop] +item=null, id=11308, option=[null, null, null, null, drop] +item=null, id=11309, option=[null, null, null, null, drop] +item=null, id=11310, option=[null, null, null, null, drop] +item=null, id=11311, option=[null, null, null, null, drop] +item=null, id=11312, option=[null, null, null, null, drop] +item=null, id=11313, option=[null, null, null, null, drop] +item=null, id=11314, option=[null, null, null, null, drop] +item=null, id=11315, option=[null, null, null, null, drop] +item=null, id=11316, option=[null, null, null, null, drop] +item=null, id=11317, option=[null, null, null, null, drop] +item=null, id=11318, option=[null, null, null, null, drop] +item=null, id=11319, option=[null, null, null, null, drop] +item=null, id=11320, option=[null, null, null, null, drop] +item=null, id=11321, option=[null, null, null, null, drop] +item=null, id=11322, option=[null, null, null, null, drop] +item=Barbarian rod, id=11323, option=[null, null, null, null, drop] +item=Roe, id=11324, option=[Eat, null, null, null, drop] +item=Roe, id=11325, option=[null, null, null, null, drop] +item=Caviar, id=11326, option=[Eat, null, null, null, drop] +item=Caviar, id=11327, option=[null, null, null, null, drop] +item=Leaping trout, id=11328, option=[null, null, null, null, drop] +item=Leaping trout, id=11329, option=[null, null, null, null, drop] +item=Leaping salmon, id=11330, option=[null, null, null, null, drop] +item=Leaping salmon, id=11331, option=[null, null, null, null, drop] +item=Leaping sturgeon, id=11332, option=[null, null, null, null, drop] +item=Leaping sturgeon, id=11333, option=[null, null, null, null, drop] +item=Fish offcuts, id=11334, option=[null, null, null, null, drop] +item=Dragon full helm, id=11335, option=[null, Wear, null, null, drop] +item=Dragon full helm, id=11336, option=[null, null, null, null, drop] +item=Mangled bones, id=11337, option=[null, null, null, null, Destroy] +item=Chewed bones, id=11338, option=[null, null, null, null, Destroy] +item=My notes, id=11339, option=[Read, null, null, null, Destroy] +item=Barbarian skills, id=11340, option=[Read, null, null, null, Destroy] +item=Ancient page, id=11341, option=[Copy to log, null, null, null, Destroy] +item=Ancient page, id=11342, option=[Copy to log, null, null, null, Destroy] +item=Ancient page, id=11343, option=[Copy to log, null, null, null, Destroy] +item=Ancient page, id=11344, option=[Copy to log, null, null, null, Destroy] +item=Ancient page, id=11345, option=[Copy to log, null, null, null, Destroy] +item=Ancient page, id=11346, option=[Copy to log, null, null, null, Destroy] +item=Ancient page, id=11347, option=[Copy to log, null, null, null, Destroy] +item=Ancient page, id=11348, option=[Copy to log, null, null, null, Destroy] +item=Ancient page, id=11349, option=[Copy to log, null, null, null, Destroy] +item=Ancient page, id=11350, option=[Copy to log, null, null, null, Destroy] +item=Ancient page, id=11351, option=[Copy to log, null, null, null, Destroy] +item=Ancient page, id=11352, option=[Copy to log, null, null, null, Destroy] +item=Ancient page, id=11353, option=[Copy to log, null, null, null, Destroy] +item=Ancient page, id=11354, option=[Copy to log, null, null, null, Destroy] +item=Ancient page, id=11355, option=[Copy to log, null, null, null, Destroy] +item=Ancient page, id=11356, option=[Copy to log, null, null, null, Destroy] +item=Ancient page, id=11357, option=[Copy to log, null, null, null, Destroy] +item=Ancient page, id=11358, option=[Copy to log, null, null, null, Destroy] +item=Ancient page, id=11359, option=[Copy to log, null, null, null, Destroy] +item=Ancient page, id=11360, option=[Copy to log, null, null, null, Destroy] +item=Ancient page, id=11361, option=[Copy to log, null, null, null, Destroy] +item=Ancient page, id=11362, option=[Copy to log, null, null, null, Destroy] +item=Ancient page, id=11363, option=[Copy to log, null, null, null, Destroy] +item=Ancient page, id=11364, option=[Copy to log, null, null, null, Destroy] +item=Ancient page, id=11365, option=[Copy to log, null, null, null, Destroy] +item=Ancient page, id=11366, option=[Copy to log, null, null, null, Destroy] +item=Bronze hasta, id=11367, option=[null, Wield, null, null, drop] +item=Bronze hasta, id=11368, option=[null, null, null, null, drop] +item=Iron hasta, id=11369, option=[null, Wield, null, null, drop] +item=Iron hasta, id=11370, option=[null, null, null, null, drop] +item=Steel hasta, id=11371, option=[null, Wield, null, null, drop] +item=Steel hasta, id=11372, option=[null, null, null, null, drop] +item=Mithril hasta, id=11373, option=[null, Wield, null, null, drop] +item=Mithril hasta, id=11374, option=[null, null, null, null, drop] +item=Adamant hasta, id=11375, option=[null, Wield, null, null, drop] +item=Adamant hasta, id=11376, option=[null, null, null, null, drop] +item=Rune hasta, id=11377, option=[null, Wield, null, null, drop] +item=Rune hasta, id=11378, option=[null, null, null, null, drop] +item=Bronze hasta(p), id=11379, option=[null, Wield, null, null, drop] +item=Bronze hasta(p), id=11380, option=[null, null, null, null, drop] +item=Bronze hasta(kp), id=11381, option=[null, Wield, null, null, drop] +item=Bronze hasta(p+), id=11382, option=[null, Wield, null, null, drop] +item=Bronze hasta(p+), id=11383, option=[null, null, null, null, drop] +item=Bronze hasta(p++), id=11384, option=[null, Wield, null, null, drop] +item=Bronze hasta(p++), id=11385, option=[null, null, null, null, drop] +item=Iron hasta(p), id=11386, option=[null, Wield, null, null, drop] +item=Iron hasta(p), id=11387, option=[null, null, null, null, drop] +item=Iron hasta(kp), id=11388, option=[null, Wield, null, null, drop] +item=Iron hasta(p+), id=11389, option=[null, Wield, null, null, drop] +item=Iron hasta(p+), id=11390, option=[null, null, null, null, drop] +item=Iron hasta(p++), id=11391, option=[null, Wield, null, null, drop] +item=Iron hasta(p++), id=11392, option=[null, null, null, null, drop] +item=Steel hasta(p), id=11393, option=[null, Wield, null, null, drop] +item=Steel hasta(p), id=11394, option=[null, null, null, null, drop] +item=Steel hasta(kp), id=11395, option=[null, Wield, null, null, drop] +item=Steel hasta(p+), id=11396, option=[null, Wield, null, null, drop] +item=Steel hasta(p+), id=11397, option=[null, null, null, null, drop] +item=Steel hasta(p++), id=11398, option=[null, Wield, null, null, drop] +item=Steel hasta(p++), id=11399, option=[null, null, null, null, drop] +item=Mithril hasta(p), id=11400, option=[null, Wield, null, null, drop] +item=Mithril hasta(p), id=11401, option=[null, null, null, null, drop] +item=Mithril hasta(kp), id=11402, option=[null, Wield, null, null, drop] +item=Mithril hasta(p+), id=11403, option=[null, Wield, null, null, drop] +item=Mithril hasta(p+), id=11404, option=[null, null, null, null, drop] +item=Mithril hasta(p++), id=11405, option=[null, Wield, null, null, drop] +item=Mithril hasta(p++), id=11406, option=[null, null, null, null, drop] +item=Adamant hasta(p), id=11407, option=[null, Wield, null, null, drop] +item=Adamant hasta(p), id=11408, option=[null, null, null, null, drop] +item=Adamant hasta(kp), id=11409, option=[null, Wield, null, null, drop] +item=Adamant hasta(p+), id=11410, option=[null, Wield, null, null, drop] +item=Adamant hasta(p+), id=11411, option=[null, null, null, null, drop] +item=Addy hasta(p++), id=11412, option=[null, Wield, null, null, drop] +item=Addy hasta(p++), id=11413, option=[null, null, null, null, drop] +item=Rune hasta(p), id=11414, option=[null, Wield, null, null, drop] +item=Rune hasta(p), id=11415, option=[null, null, null, null, drop] +item=Rune hasta(kp), id=11416, option=[null, Wield, null, null, drop] +item=Rune hasta(p+), id=11417, option=[null, Wield, null, null, drop] +item=Rune hasta(p+), id=11418, option=[null, null, null, null, drop] +item=Rune hasta(p++), id=11419, option=[null, Wield, null, null, drop] +item=Rune hasta(p++), id=11420, option=[null, null, null, null, drop] +item=null, id=11421, option=[null, null, null, null, drop] +item=null, id=11422, option=[null, null, null, null, drop] +item=null, id=11423, option=[null, null, null, null, drop] +item=null, id=11424, option=[null, null, null, null, drop] +item=null, id=11425, option=[null, null, null, null, drop] +item=null, id=11426, option=[null, null, null, null, drop] +item=Fish vial, id=11427, option=[null, null, null, null, drop] +item=Fish vial, id=11428, option=[null, null, null, null, drop] +item=Attack mix(2), id=11429, option=[Drink, null, null, Empty, drop] +item=Attack mix(2), id=11430, option=[null, null, null, null, drop] +item=Attack mix(1), id=11431, option=[Drink, null, null, Empty, drop] +item=Attack mix(1), id=11432, option=[null, null, null, null, drop] +item=Antipoison mix(2), id=11433, option=[Drink, null, null, Empty, drop] +item=Antipoison mix(2), id=11434, option=[null, null, null, null, drop] +item=Antipoison mix(1), id=11435, option=[Drink, null, null, Empty, drop] +item=Antipoison mix(1), id=11436, option=[null, null, null, null, drop] +item=Relicym's mix(2), id=11437, option=[Drink, null, null, Empty, drop] +item=Relicym's mix(2), id=11438, option=[null, null, null, null, drop] +item=Relicym's mix(1), id=11439, option=[Drink, null, null, Empty, drop] +item=Relicym's mix(1), id=11440, option=[null, null, null, null, drop] +item=Strength mix(1), id=11441, option=[Drink, null, null, Empty, drop] +item=Strength mix(1), id=11442, option=[null, null, null, null, drop] +item=Strength mix(2), id=11443, option=[Drink, null, null, Empty, drop] +item=Strength mix(2), id=11444, option=[null, null, null, null, drop] +item=Combat mix(2), id=11445, option=[Drink, null, null, Empty, drop] +item=Combat mix(2), id=11446, option=[null, null, null, null, drop] +item=Combat mix(1), id=11447, option=[Drink, null, null, Empty, drop] +item=Combat mix(1), id=11448, option=[null, null, null, null, drop] +item=Restore mix(2), id=11449, option=[Drink, null, null, Empty, drop] +item=Restore mix(2), id=11450, option=[null, null, null, null, drop] +item=Restore mix(1), id=11451, option=[Drink, null, null, Empty, drop] +item=Restore mix(1), id=11452, option=[null, null, null, null, drop] +item=Energy mix(2), id=11453, option=[Drink, null, null, Empty, drop] +item=Energy mix(2), id=11454, option=[null, null, null, null, drop] +item=Energy mix(1), id=11455, option=[Drink, null, null, Empty, drop] +item=Energy mix(1), id=11456, option=[null, null, null, null, drop] +item=Defence mix(2), id=11457, option=[Drink, null, null, Empty, drop] +item=Defence mix(2), id=11458, option=[null, null, null, null, drop] +item=Defence mix(1), id=11459, option=[Drink, null, null, Empty, drop] +item=Defence mix(1), id=11460, option=[null, null, null, null, drop] +item=Agility mix(2), id=11461, option=[Drink, null, null, Empty, drop] +item=Agility mix(2), id=11462, option=[null, null, null, null, drop] +item=Agility mix(1), id=11463, option=[Drink, null, null, Empty, drop] +item=Agility mix(1), id=11464, option=[null, null, null, null, drop] +item=Prayer mix(2), id=11465, option=[Drink, null, null, Empty, drop] +item=Prayer mix(2), id=11466, option=[null, null, null, null, drop] +item=Prayer mix(1), id=11467, option=[Drink, null, null, Empty, drop] +item=Prayer mix(1), id=11468, option=[null, null, null, null, drop] +item=Superattack mix(2), id=11469, option=[Drink, null, null, Empty, drop] +item=Superattack mix(2), id=11470, option=[null, null, null, null, drop] +item=Superattack mix(1), id=11471, option=[Drink, null, null, Empty, drop] +item=Superattack mix(1), id=11472, option=[null, null, null, null, drop] +item=Anti-p supermix(2), id=11473, option=[Drink, null, null, Empty, drop] +item=Anti-p supermix(2), id=11474, option=[null, null, null, null, drop] +item=Anti-p supermix(1), id=11475, option=[Drink, null, null, Empty, drop] +item=Anti-p supermix(1), id=11476, option=[null, null, null, null, drop] +item=Fishing mix(2), id=11477, option=[Drink, null, null, Empty, drop] +item=Fishing mix(2), id=11478, option=[null, null, null, null, drop] +item=Fishing mix(1), id=11479, option=[Drink, null, null, Empty, drop] +item=Fishing mix(1), id=11480, option=[null, null, null, null, drop] +item=Sup. energy mix(2), id=11481, option=[Drink, null, null, Empty, drop] +item=Sup. energy mix(2), id=11482, option=[null, null, null, null, drop] +item=Sup. energy mix(1), id=11483, option=[Drink, null, null, Empty, drop] +item=Sup. energy mix(1), id=11484, option=[null, null, null, null, drop] +item=Sup. str. mix(2), id=11485, option=[Drink, null, null, Empty, drop] +item=Sup. str. mix(2), id=11486, option=[null, null, null, null, drop] +item=Sup. str. mix(1), id=11487, option=[Drink, null, null, Empty, drop] +item=Sup. str. mix(1), id=11488, option=[null, null, null, null, drop] +item=Magic ess. mix(2), id=11489, option=[Drink, null, null, Empty, drop] +item=Magic ess. mix(2), id=11490, option=[null, null, null, null, drop] +item=Magic ess. mix(1), id=11491, option=[Drink, null, null, Empty, drop] +item=Magic ess. mix(1), id=11492, option=[null, null, null, null, drop] +item=Sup. restore mix(2), id=11493, option=[Drink, null, null, Empty, drop] +item=Sup. restore mix(2), id=11494, option=[null, null, null, null, drop] +item=Sup. restore mix(1), id=11495, option=[Drink, null, null, Empty, drop] +item=Sup. restore mix(1), id=11496, option=[null, null, null, null, drop] +item=Sup. def. mix(2), id=11497, option=[Drink, null, null, Empty, drop] +item=Sup. def. mix(2), id=11498, option=[null, null, null, null, drop] +item=Sup. def. mix(1), id=11499, option=[Drink, null, null, Empty, drop] +item=Sup. def. mix(1), id=11500, option=[null, null, null, null, drop] +item=Antidote+ mix(2), id=11501, option=[Drink, null, null, Empty, drop] +item=Antidote+ mix(2), id=11502, option=[null, null, null, null, drop] +item=Antidote+ mix(1), id=11503, option=[Drink, null, null, Empty, drop] +item=Antidote+ mix(1), id=11504, option=[null, null, null, null, drop] +item=Antifire mix(2), id=11505, option=[Drink, null, null, Empty, drop] +item=Antifire mix(2), id=11506, option=[null, null, null, null, drop] +item=Antifire mix(1), id=11507, option=[Drink, null, null, Empty, drop] +item=Antifire mix(1), id=11508, option=[null, null, null, null, drop] +item=Ranging mix(2), id=11509, option=[Drink, null, null, Empty, drop] +item=Ranging mix(2), id=11510, option=[null, null, null, null, drop] +item=Ranging mix(1), id=11511, option=[Drink, null, null, Empty, drop] +item=Ranging mix(1), id=11512, option=[null, null, null, null, drop] +item=Magic mix(2), id=11513, option=[Drink, null, null, Empty, drop] +item=Magic mix(2), id=11514, option=[null, null, null, null, drop] +item=Magic mix(1), id=11515, option=[Drink, null, null, Empty, drop] +item=Magic mix(1), id=11516, option=[null, null, null, null, drop] +item=Hunting mix(2), id=11517, option=[Drink, null, null, Empty, drop] +item=Hunting mix(2), id=11518, option=[null, null, null, null, drop] +item=Hunting mix(1), id=11519, option=[Drink, null, null, Empty, drop] +item=Hunting mix(1), id=11520, option=[null, null, null, null, drop] +item=Zamorak mix(2), id=11521, option=[Drink, null, null, Empty, drop] +item=Zamorak mix(2), id=11522, option=[null, null, null, null, drop] +item=Zamorak mix(1), id=11523, option=[Drink, null, null, Empty, drop] +item=Zamorak mix(1), id=11524, option=[null, null, null, null, drop] +item=Wimpy feather, id=11525, option=[null, null, null, null, drop] +item=null, id=11526, option=[null, null, null, null, drop] +item=null, id=11527, option=[null, null, null, null, drop] +item=null, id=11528, option=[null, null, null, null, drop] +item=null, id=11529, option=[null, null, null, null, drop] +item=null, id=11530, option=[null, null, null, null, drop] +item=null, id=11531, option=[null, null, null, null, drop] +item=null, id=11532, option=[null, null, null, null, drop] +item=null, id=11533, option=[null, null, null, null, drop] +item=null, id=11534, option=[null, null, null, null, drop] +item=null, id=11535, option=[null, null, null, null, drop] +item=null, id=11536, option=[null, null, null, null, drop] +item=null, id=11537, option=[null, null, null, null, drop] +item=null, id=11538, option=[null, null, null, null, drop] +item=null, id=11539, option=[null, null, null, null, drop] +item=null, id=11540, option=[null, null, null, null, drop] +item=null, id=11541, option=[null, null, null, null, drop] +item=null, id=11542, option=[null, null, null, null, drop] +item=null, id=11543, option=[null, null, null, null, drop] +item=null, id=11544, option=[null, null, null, null, drop] +item=null, id=11545, option=[null, null, null, null, drop] +item=null, id=11546, option=[null, null, null, null, drop] +item=null, id=11547, option=[null, null, null, null, drop] +item=null, id=11548, option=[null, null, null, null, drop] +item=null, id=11549, option=[null, null, null, null, drop] +item=null, id=11550, option=[null, null, null, null, drop] +item=null, id=11551, option=[null, null, null, null, drop] +item=null, id=11552, option=[null, null, null, null, drop] +item=null, id=11553, option=[null, null, null, null, drop] +item=null, id=11554, option=[null, null, null, null, drop] +item=null, id=11555, option=[null, null, null, null, drop] +item=null, id=11556, option=[null, null, null, null, drop] +item=null, id=11557, option=[null, null, null, null, drop] +item=null, id=11558, option=[null, null, null, null, drop] +item=null, id=11559, option=[null, null, null, null, drop] +item=null, id=11560, option=[null, null, null, null, drop] +item=null, id=11561, option=[null, null, null, null, drop] +item=null, id=11562, option=[null, null, null, null, drop] +item=null, id=11563, option=[null, null, null, null, drop] +item=null, id=11564, option=[null, null, null, null, drop] +item=null, id=11565, option=[null, null, null, null, drop] +item=null, id=11566, option=[null, null, null, null, drop] +item=null, id=11567, option=[null, null, null, null, drop] +item=null, id=11568, option=[null, null, null, null, drop] +item=null, id=11569, option=[null, null, null, null, drop] +item=null, id=11570, option=[null, null, null, null, drop] +item=null, id=11571, option=[null, null, null, null, drop] +item=null, id=11572, option=[null, null, null, null, drop] +item=null, id=11573, option=[null, null, null, null, drop] +item=null, id=11574, option=[null, null, null, null, drop] +item=null, id=11575, option=[null, null, null, null, drop] +item=null, id=11576, option=[null, null, null, null, drop] +item=null, id=11577, option=[null, null, null, null, drop] +item=null, id=11578, option=[null, null, null, null, drop] +item=null, id=11579, option=[null, null, null, null, drop] +item=null, id=11580, option=[null, null, null, null, drop] +item=null, id=11581, option=[null, null, null, null, drop] +item=null, id=11582, option=[null, null, null, null, drop] +item=null, id=11583, option=[null, null, null, null, drop] +item=null, id=11584, option=[null, null, null, null, drop] +item=null, id=11585, option=[null, null, null, null, drop] +item=null, id=11586, option=[null, null, null, null, drop] +item=null, id=11587, option=[null, null, null, null, drop] +item=null, id=11588, option=[null, null, null, null, drop] +item=null, id=11589, option=[null, null, null, null, drop] +item=null, id=11590, option=[null, null, null, null, drop] +item=null, id=11591, option=[null, null, null, null, drop] +item=null, id=11592, option=[null, null, null, null, drop] +item=null, id=11593, option=[null, null, null, null, drop] +item=null, id=11594, option=[null, null, null, null, drop] +item=null, id=11595, option=[null, null, null, null, drop] +item=null, id=11596, option=[null, null, null, null, drop] +item=null, id=11597, option=[null, null, null, null, drop] +item=null, id=11598, option=[null, null, null, null, drop] +item=null, id=11599, option=[null, null, null, null, drop] +item=null, id=11600, option=[null, null, null, null, drop] +item=null, id=11601, option=[null, null, null, null, drop] +item=null, id=11602, option=[null, null, null, null, drop] +item=null, id=11603, option=[null, null, null, null, drop] +item=null, id=11604, option=[null, null, null, null, drop] +item=null, id=11605, option=[null, null, null, null, drop] +item=null, id=11606, option=[null, null, null, null, drop] +item=null, id=11607, option=[null, null, null, null, drop] +item=null, id=11608, option=[null, null, null, null, drop] +item=null, id=11609, option=[null, null, null, null, drop] +item=null, id=11610, option=[null, null, null, null, drop] +item=null, id=11611, option=[null, null, null, null, drop] +item=null, id=11612, option=[null, null, null, null, drop] +item=null, id=11613, option=[null, null, null, null, drop] +item=null, id=11614, option=[null, null, null, null, drop] +item=null, id=11615, option=[null, null, null, null, drop] +item=null, id=11616, option=[null, null, null, null, drop] +item=null, id=11617, option=[null, null, null, null, drop] +item=null, id=11618, option=[null, null, null, null, drop] +item=null, id=11619, option=[null, null, null, null, drop] +item=null, id=11620, option=[null, null, null, null, drop] +item=null, id=11621, option=[null, null, null, null, drop] +item=null, id=11622, option=[null, null, null, null, drop] +item=null, id=11623, option=[null, null, null, null, drop] +item=null, id=11624, option=[null, null, null, null, drop] +item=null, id=11625, option=[null, null, null, null, drop] +item=null, id=11626, option=[null, null, null, null, drop] +item=null, id=11627, option=[null, null, null, null, drop] +item=null, id=11628, option=[null, null, null, null, drop] +item=null, id=11629, option=[null, null, null, null, drop] +item=null, id=11630, option=[null, null, null, null, drop] +item=null, id=11631, option=[null, null, null, null, drop] +item=null, id=11632, option=[null, null, null, null, drop] +item=null, id=11633, option=[null, null, null, null, drop] +item=null, id=11634, option=[null, null, null, null, drop] +item=null, id=11635, option=[null, null, null, null, drop] +item=null, id=11636, option=[null, null, null, null, drop] +item=null, id=11637, option=[null, null, null, null, drop] +item=null, id=11638, option=[null, null, null, null, drop] +item=null, id=11639, option=[null, null, null, null, drop] +item=Book of knowledge, id=11640, option=[Read, null, null, null, Destroy] +item=null, id=11641, option=[null, null, null, null, drop] +item=null, id=11642, option=[null, null, null, null, drop] +item=null, id=11643, option=[null, null, null, null, drop] +item=null, id=11644, option=[null, null, null, null, drop] +item=null, id=11645, option=[null, null, null, null, drop] +item=null, id=11646, option=[null, null, null, null, drop] +item=null, id=11647, option=[null, null, null, null, drop] +item=null, id=11648, option=[null, null, null, null, drop] +item=null, id=11649, option=[null, null, null, null, drop] +item=null, id=11650, option=[null, null, null, null, drop] +item=null, id=11651, option=[null, null, null, null, drop] +item=null, id=11652, option=[null, null, null, null, drop] +item=null, id=11653, option=[null, null, null, null, drop] +item=null, id=11654, option=[null, null, null, null, drop] +item=Astronomy book, id=11655, option=[null, null, null, null, drop] +item=Glassblowing book, id=11656, option=[Read, null, null, null, drop] +item=Glassblowing book, id=11657, option=[null, null, null, null, drop] +item=null, id=11658, option=[null, null, null, null, drop] +item=null, id=11659, option=[null, null, null, null, drop] +item=null, id=11660, option=[null, null, null, null, drop] +item=null, id=11661, option=[null, null, null, null, drop] +item=null, id=11662, option=[null, null, null, null, drop] +item=Void mage helm, id=11663, option=[null, Wear, null, null, drop] +item=Void ranger helm, id=11664, option=[null, Wear, null, null, drop] +item=Void melee helm, id=11665, option=[null, Wear, null, null, drop] +item=Void seal(8), id=11666, option=[null, Wear, null, Rub, drop] +item=Void seal(7), id=11667, option=[null, Wear, null, Rub, drop] +item=Void seal(6), id=11668, option=[null, Wear, null, Rub, drop] +item=Void seal(5), id=11669, option=[null, Wear, null, Rub, drop] +item=Void seal(4), id=11670, option=[null, Wear, null, Rub, drop] +item=Void seal(3), id=11671, option=[null, Wear, null, Rub, drop] +item=Void seal(2), id=11672, option=[null, Wear, null, Rub, drop] +item=Void seal(1), id=11673, option=[null, Wear, null, Rub, drop] +item=Void mage helm, id=11674, option=[null, Wear, null, null, drop] +item=Void ranger helm, id=11675, option=[null, Wear, null, null, drop] +item=Void melee helm, id=11676, option=[null, Wear, null, null, drop] +item=Explorer's notes, id=11677, option=[Read, null, null, null, Destroy] +item=Black knight helm, id=11678, option=[null, null, null, null, Destroy] +item=Antique lamp, id=11679, option=[Rub, null, null, null, Destroy] +item=Address form, id=11680, option=[Read, null, null, null, Destroy] +item=Scrap paper, id=11681, option=[Read, null, null, null, Destroy] +item=Hair clip, id=11682, option=[null, null, null, null, drop] +item=null, id=11683, option=[null, null, null, null, drop] +item=null, id=11684, option=[null, null, null, null, drop] +item=null, id=11685, option=[null, null, null, null, drop] +item=Godsword shards, id=11686, option=[null, null, null, null, drop] +item=Godsword shards, id=11687, option=[null, null, null, null, drop] +item=Godsword shards, id=11688, option=[null, null, null, null, drop] +item=Godsword shards, id=11689, option=[null, null, null, null, drop] +item=Godsword blade, id=11690, option=[null, null, null, null, drop] +item=Godsword blade, id=11691, option=[null, null, null, null, drop] +item=Godsword shards, id=11692, option=[null, null, null, null, drop] +item=Godsword shards, id=11693, option=[null, null, null, null, drop] +item=Armadyl godsword, id=11694, option=[null, Wield, Dismantle, null, drop] +item=Armadyl godsword, id=11695, option=[null, null, null, null, drop] +item=Bandos godsword, id=11696, option=[null, Wield, Dismantle, null, drop] +item=Bandos godsword, id=11697, option=[null, null, null, null, drop] +item=Saradomin godsword, id=11698, option=[null, Wield, Dismantle, null, drop] +item=Saradomin godsword, id=11699, option=[null, null, null, null, drop] +item=Zamorak godsword, id=11700, option=[null, Wield, Dismantle, null, drop] +item=Zamorak godsword, id=11701, option=[null, null, null, null, drop] +item=Armadyl hilt, id=11702, option=[null, null, null, null, drop] +item=Armadyl hilt, id=11703, option=[null, null, null, null, drop] +item=Bandos hilt, id=11704, option=[null, null, null, null, drop] +item=Bandos hilt, id=11705, option=[null, null, null, null, drop] +item=Saradomin hilt, id=11706, option=[null, null, null, null, drop] +item=Saradomin hilt, id=11707, option=[null, null, null, null, drop] +item=Zamorak hilt, id=11708, option=[null, null, null, null, drop] +item=Zamorak hilt, id=11709, option=[null, null, null, null, drop] +item=Godsword shard 1, id=11710, option=[null, null, null, null, drop] +item=Godsword shard 1, id=11711, option=[null, null, null, null, drop] +item=Godsword shard 2, id=11712, option=[null, null, null, null, drop] +item=Godsword shard 2, id=11713, option=[null, null, null, null, drop] +item=Godsword shard 3, id=11714, option=[null, null, null, null, drop] +item=Godsword shard 3, id=11715, option=[null, null, null, null, drop] +item=Zamorakian spear, id=11716, option=[null, Wield, null, null, drop] +item=Zamorakian spear, id=11717, option=[null, null, null, null, drop] +item=Armadyl helmet, id=11718, option=[null, Wear, null, null, drop] +item=Armadyl helmet, id=11719, option=[null, null, null, null, drop] +item=Armadyl chestplate, id=11720, option=[null, Wear, null, null, drop] +item=Armadyl chestplate, id=11721, option=[null, null, null, null, drop] +item=Armadyl plateskirt, id=11722, option=[null, Wear, null, null, drop] +item=Armadyl plateskirt, id=11723, option=[null, null, null, null, drop] +item=Bandos chestplate, id=11724, option=[null, Wear, null, null, drop] +item=Bandos chestplate, id=11725, option=[null, null, null, null, drop] +item=Bandos tassets, id=11726, option=[null, Wear, null, null, drop] +item=Bandos tassets, id=11727, option=[null, null, null, null, drop] +item=Bandos boots, id=11728, option=[null, Wear, null, null, drop] +item=Bandos boots, id=11729, option=[null, null, null, null, drop] +item=Saradomin sword, id=11730, option=[null, Wield, null, null, drop] +item=Saradomin sword, id=11731, option=[null, null, null, null, drop] +item=Dragon boots, id=11732, option=[null, Wear, null, null, drop] +item=Dragon boots, id=11733, option=[null, null, null, null, drop] +item=Knight's notes, id=11734, option=[Read, null, null, null, Destroy] +item=Knight's notes, id=11735, option=[Read, null, null, null, Destroy] +item=Steam battlestaff, id=11736, option=[null, Wield, null, null, drop] +item=Steam battlestaff, id=11737, option=[null, null, null, null, drop] +item=Mystic steam staff, id=11738, option=[null, Wield, null, null, drop] +item=Mystic steam staff, id=11739, option=[null, null, null, null, drop] +item=God wars mage, id=11740, option=[null, null, null, null, drop] +item=God wars mage, id=11741, option=[null, null, null, null, drop] +item=God wars ranger, id=11742, option=[null, null, null, null, drop] +item=God wars ranger, id=11743, option=[null, null, null, null, drop] +item=God wars warrior, id=11744, option=[null, null, null, null, drop] +item=God wars warrior, id=11745, option=[null, null, null, null, drop] +item=Agility jump, id=11746, option=[null, null, null, null, drop] +item=A key to a chest, id=11747, option=[null, null, null, null, Destroy] +item=Strongroom key, id=11748, option=[null, null, null, null, Destroy] +item=Crystal chime, id=11749, option=[null, null, null, Ring, Destroy] +item=Yewnock's notes, id=11750, option=[Read, null, null, null, Destroy] +item=null, id=11751, option=[null, null, null, null, drop] +item=null, id=11752, option=[null, null, null, null, drop] +item=Antique lamp, id=11753, option=[Rub, null, null, null, Destroy] +item=Antique lamp, id=11754, option=[Rub, null, null, null, Destroy] +item=Antique lamp, id=11755, option=[Rub, null, null, null, Destroy] +item=Varrock armour 1, id=11756, option=[null, Wear, null, null, Destroy] +item=Varrock armour 2, id=11757, option=[null, Wear, null, null, Destroy] +item=Varrock armour 3, id=11758, option=[null, Wear, null, null, Destroy] +item=null, id=11759, option=[null, null, null, null, drop] +item=Logs, id=11760, option=[null, null, null, null, drop] +item=Locked diary, id=11761, option=[Unlock, null, null, null, Destroy] +item=Unlocked diary, id=11762, option=[Read, null, null, null, Destroy] +item=Hand, id=11763, option=[null, null, null, null, Destroy] +item=Foot, id=11764, option=[null, null, null, null, Destroy] +item=Torso, id=11765, option=[null, null, null, null, Destroy] +item=Left arm, id=11766, option=[null, null, null, null, Destroy] +item=Right arm, id=11767, option=[null, null, null, null, Destroy] +item=Left leg, id=11768, option=[null, null, null, null, Destroy] +item=Right leg, id=11769, option=[null, null, null, null, Destroy] +item=Root cutting, id=11770, option=[null, null, null, null, drop] +item=Root cutting, id=11771, option=[null, null, null, null, drop] +item=Root cutting, id=11772, option=[null, null, null, null, drop] +item=Root cutting, id=11773, option=[null, null, null, null, drop] +item=Root cutting, id=11774, option=[null, null, null, null, drop] +item=Wilted cutting, id=11775, option=[null, null, null, null, drop] +item=Potted root, id=11776, option=[null, null, null, null, drop] +item=Sealed pot, id=11777, option=[null, null, null, null, Destroy] +item=Jade vine seed, id=11778, option=[null, null, null, null, Destroy] +item=null, id=11779, option=[null, null, null, null, drop] +item=The grim reaper's diary, id=11780, option=[Read, null, null, null, Destroy] +item=Grim's robe, id=11781, option=[null, null, null, null, Destroy] +item=Last will and testament, id=11782, option=[null, null, null, null, Destroy] +item=Human bones, id=11783, option=[null, null, null, null, Destroy] +item=Servant's skull, id=11784, option=[null, null, null, null, Destroy] +item=Hourglass, id=11785, option=[null, null, null, null, Destroy] +item=Scythe sharpener, id=11786, option=[null, null, null, null, Destroy] +item=Human eye, id=11787, option=[null, null, null, null, Destroy] +item='voice of doom' potion, id=11788, option=[null, null, null, null, Destroy] +item=Grim reaper hood, id=11789, option=[null, Wear, null, null, Destroy] +item=Grim reaper hood, id=11790, option=[null, Wear, null, null, Destroy] +item=White goblin mail, id=11791, option=[null, Wear, null, null, drop] +item=Grubfoot, id=11792, option=[null, null, null, null, drop] +item=Zanik, id=11793, option=[null, null, null, null, drop] +item=Plain of mud sphere, id=11794, option=[Break, null, null, null, drop] +item=Ekeleshuun key, id=11795, option=[null, null, null, null, Destroy] +item=Narogoshuun key, id=11796, option=[null, null, null, null, Destroy] +item=Huzamogaarb key, id=11797, option=[null, null, null, null, Destroy] +item=Saragorgak key, id=11798, option=[null, null, null, null, Destroy] +item=Horogothgar key, id=11799, option=[null, null, null, null, Destroy] +item=Yurkolgokh key, id=11800, option=[null, null, null, null, Destroy] +item=null, id=11801, option=[null, null, null, null, drop] +item=Snothead's bone, id=11802, option=[Bury, null, null, null, drop] +item=Snailfeet's bone, id=11803, option=[Bury, null, null, null, drop] +item=Mosschin's bone, id=11804, option=[Bury, null, null, null, drop] +item=Redeyes's bone, id=11805, option=[Bury, null, null, null, drop] +item=Strongbones's bone, id=11806, option=[Bury, null, null, null, drop] +item=Pharmakos berries, id=11807, option=[null, null, null, null, drop] +item=Whitefish, id=11808, option=[null, null, null, null, drop] +item=Goblin potion (4), id=11809, option=[Drink, null, null, Empty, drop] +item=Goblin potion (3), id=11810, option=[Drink, null, null, Empty, drop] +item=Goblin potion (2), id=11811, option=[Drink, null, null, Empty, drop] +item=Goblin potion (1), id=11812, option=[Drink, null, null, Empty, drop] +item=Whoopsie, id=11813, option=[null, null, null, null, drop] +item=Bronze armour set (l), id=11814, option=[null, null, null, null, drop] +item=Bronze armour set (l), id=11815, option=[null, null, null, null, drop] +item=Bronze armour set (sk), id=11816, option=[null, null, null, null, drop] +item=Bronze armour set (sk), id=11817, option=[null, null, null, null, drop] +item=Iron armour set (l), id=11818, option=[null, null, null, null, drop] +item=Iron armour set (l), id=11819, option=[null, null, null, null, drop] +item=Iron armour set (sk), id=11820, option=[null, null, null, null, drop] +item=Iron armour set (sk), id=11821, option=[null, null, null, null, drop] +item=Steel armour set (l), id=11822, option=[null, null, null, null, drop] +item=Steel armour set (l), id=11823, option=[null, null, null, null, drop] +item=Steel armour set (sk), id=11824, option=[null, null, null, null, drop] +item=Steel armour set (sk), id=11825, option=[null, null, null, null, drop] +item=Black armour set (l), id=11826, option=[null, null, null, null, drop] +item=Black armour set (l), id=11827, option=[null, null, null, null, drop] +item=Black armour set (sk), id=11828, option=[null, null, null, null, drop] +item=Black armour set (sk), id=11829, option=[null, null, null, null, drop] +item=Mithril armour set (l), id=11830, option=[null, null, null, null, drop] +item=Mithril armour set (l), id=11831, option=[null, null, null, null, drop] +item=Mithril armour set (sk), id=11832, option=[null, null, null, null, drop] +item=Mithril armour set (sk), id=11833, option=[null, null, null, null, drop] +item=Adamant armour set (l), id=11834, option=[null, null, null, null, drop] +item=Adamant armour set (l), id=11835, option=[null, null, null, null, drop] +item=Adamant armour set (sk), id=11836, option=[null, null, null, null, drop] +item=Adamant armour set (sk), id=11837, option=[null, null, null, null, drop] +item=Rune armour set (l), id=11838, option=[null, null, null, null, drop] +item=Rune armour set (l), id=11839, option=[null, null, null, null, drop] +item=Rune armour set (sk), id=11840, option=[null, null, null, null, drop] +item=Rune armour set (sk), id=11841, option=[null, null, null, null, drop] +item=Dragon armour set (l), id=11842, option=[null, null, null, null, drop] +item=Dragon armour set (l), id=11843, option=[null, null, null, null, drop] +item=Dragon armour set (sk), id=11844, option=[null, null, null, null, drop] +item=Dragon armour set (sk), id=11845, option=[null, null, null, null, drop] +item=Barrows - ahrim's set, id=11846, option=[null, null, null, null, drop] +item=Barrows - ahrim's set, id=11847, option=[null, null, null, null, drop] +item=Barrows - dharok's set, id=11848, option=[null, null, null, null, drop] +item=Barrows - dharok's set, id=11849, option=[null, null, null, null, drop] +item=Barrows - guthan's set, id=11850, option=[null, null, null, null, drop] +item=Barrows - guthan's set, id=11851, option=[null, null, null, null, drop] +item=Barrows - karil's set, id=11852, option=[null, null, null, null, drop] +item=Barrows - karil's set, id=11853, option=[null, null, null, null, drop] +item=Barrows - torag's set, id=11854, option=[null, null, null, null, drop] +item=Barrows - torag's set, id=11855, option=[null, null, null, null, drop] +item=Barrows - verac's set, id=11856, option=[null, null, null, null, drop] +item=Barrows - verac's set, id=11857, option=[null, null, null, null, drop] +item=Third age melee set, id=11858, option=[null, null, null, null, drop] +item=Third age melee set, id=11859, option=[null, null, null, null, drop] +item=Third age ranger set, id=11860, option=[null, null, null, null, drop] +item=Third age ranger set, id=11861, option=[null, null, null, null, drop] +item=Third age mage set, id=11862, option=[null, null, null, null, drop] +item=Third age mage set, id=11863, option=[null, null, null, null, drop] +item=Green dragonhide set, id=11864, option=[null, null, null, null, drop] +item=Green dragonhide set, id=11865, option=[null, null, null, null, drop] +item=Blue dragonhide set, id=11866, option=[null, null, null, null, drop] +item=Blue dragonhide set, id=11867, option=[null, null, null, null, drop] +item=Red dragonhide set, id=11868, option=[null, null, null, null, drop] +item=Red dragonhide set, id=11869, option=[null, null, null, null, drop] +item=Black dragonhide set, id=11870, option=[null, null, null, null, drop] +item=Black dragonhide set, id=11871, option=[null, null, null, null, drop] +item=Mystic robes set, id=11872, option=[null, null, null, null, drop] +item=Mystic robes set, id=11873, option=[null, null, null, null, drop] +item=Infinity robes set, id=11874, option=[null, null, null, null, drop] +item=Infinity robes set, id=11875, option=[null, null, null, null, drop] +item=Splitbark armour set, id=11876, option=[null, null, null, null, drop] +item=Splitbark armour set, id=11877, option=[null, null, null, null, drop] +item=Black trimmed armour set (l), id=11878, option=[null, null, null, null, drop] +item=Black trimmed armour set (l), id=11879, option=[null, null, null, null, drop] +item=Black trimmed armour set (sk), id=11880, option=[null, null, null, null, drop] +item=Black trimmed armour set (sk), id=11881, option=[null, null, null, null, drop] +item=Black gold-trimmed armour set (l), id=11882, option=[null, null, null, null, drop] +item=Black gold-trimmed armour set (l), id=11883, option=[null, null, null, null, drop] +item=Black gold-trimmed armour set (sk), id=11884, option=[null, null, null, null, drop] +item=Black gold-trimmed armour set (sk), id=11885, option=[null, null, null, null, drop] +item=Adamant trimmed armour set (l), id=11886, option=[null, null, null, null, drop] +item=Adamant trimmed armour set (l), id=11887, option=[null, null, null, null, drop] +item=Adamant trimmed armour set (sk), id=11888, option=[null, null, null, null, drop] +item=Adamant trimmed armour set (sk), id=11889, option=[null, null, null, null, drop] +item=Adamant gold-trimmed armour set (l), id=11890, option=[null, null, null, null, drop] +item=Adamant gold-trimmed armour set (l), id=11891, option=[null, null, null, null, drop] +item=Adamant gold-trimmed armour set (sk), id=11892, option=[null, null, null, null, drop] +item=Adamant gold-trimmed armour set (sk), id=11893, option=[null, null, null, null, drop] +item=Rune trimmed armour set (l), id=11894, option=[null, null, null, null, drop] +item=Rune trimmed armour set (l), id=11895, option=[null, null, null, null, drop] +item=Rune trimmed armour set (sk), id=11896, option=[null, null, null, null, drop] +item=Rune trimmed armour set (sk), id=11897, option=[null, null, null, null, drop] +item=Rune gold-trimmed armour set (l), id=11898, option=[null, null, null, null, drop] +item=Rune gold-trimmed armour set (l), id=11899, option=[null, null, null, null, drop] +item=Rune gold-trimmed armour set (sk), id=11900, option=[null, null, null, null, drop] +item=Rune gold-trimmed armour set (sk), id=11901, option=[null, null, null, null, drop] +item=Enchanted set, id=11902, option=[null, null, null, null, drop] +item=Enchanted set, id=11903, option=[null, null, null, null, drop] +item=Trimmed blue wizard set, id=11904, option=[null, null, null, null, drop] +item=Trimmed blue wizard set, id=11905, option=[null, null, null, null, drop] +item=Gold-trimmed blue wizard set, id=11906, option=[null, null, null, null, drop] +item=Gold-trimmed blue wizard set, id=11907, option=[null, null, null, null, drop] +item=Trimmed leather armour set, id=11908, option=[null, null, null, null, drop] +item=Trimmed leather armour set, id=11909, option=[null, null, null, null, drop] +item=Gold-trimmed leather armour set, id=11910, option=[null, null, null, null, drop] +item=Gold-trimmed leather armour set, id=11911, option=[null, null, null, null, drop] +item=Green d'hide trimmed set, id=11912, option=[null, null, null, null, drop] +item=Green d'hide trimmed set, id=11913, option=[null, null, null, null, drop] +item=Green d'hide gold-trimmed set, id=11914, option=[null, null, null, null, drop] +item=Green d'hide gold-trimmed set, id=11915, option=[null, null, null, null, drop] +item=Blue d'hide trimmed set, id=11916, option=[null, null, null, null, drop] +item=Blue d'hide trimmed set, id=11917, option=[null, null, null, null, drop] +item=Blue d'hide gold-trimmed set, id=11918, option=[null, null, null, null, drop] +item=Blue d'hide gold-trimmed set, id=11919, option=[null, null, null, null, drop] +item=Green d'hide blessed set, id=11920, option=[null, null, null, null, drop] +item=Green d'hide blessed set, id=11921, option=[null, null, null, null, drop] +item=Blue d'hide blessed set, id=11922, option=[null, null, null, null, drop] +item=Blue d'hide blessed set, id=11923, option=[null, null, null, null, drop] +item=Red d'hide blessed set, id=11924, option=[null, null, null, null, drop] +item=Red d'hide blessed set, id=11925, option=[null, null, null, null, drop] +item=Guthix armour set (l), id=11926, option=[null, null, null, null, drop] +item=Guthix armour set (l), id=11927, option=[null, null, null, null, drop] +item=Saradomin armour set (l), id=11928, option=[null, null, null, null, drop] +item=Saradomin armour set (l), id=11929, option=[null, null, null, null, drop] +item=Zamorak armour set (l), id=11930, option=[null, null, null, null, drop] +item=Zamorak armour set (l), id=11931, option=[null, null, null, null, drop] +item=Guthix armour set (sk), id=11932, option=[null, null, null, null, drop] +item=Guthix armour set (sk), id=11933, option=[null, null, null, null, drop] +item=Saradomin armour set (sk), id=11934, option=[null, null, null, null, drop] +item=Saradomin armour set (sk), id=11935, option=[null, null, null, null, drop] +item=Zamorak armour set (sk), id=11936, option=[null, null, null, null, drop] +item=Zamorak armour set (sk), id=11937, option=[null, null, null, null, drop] +item=Gilded armour set (l), id=11938, option=[null, null, null, null, drop] +item=Gilded armour set (l), id=11939, option=[null, null, null, null, drop] +item=Gilded armour set (sk), id=11940, option=[null, null, null, null, drop] +item=Gilded armour set (sk), id=11941, option=[null, null, null, null, drop] +item=Rockshell armour set, id=11942, option=[null, null, null, null, drop] +item=Rockshell armour set, id=11943, option=[null, null, null, null, drop] +item=Spined armour set, id=11944, option=[null, null, null, null, drop] +item=Spined armour set, id=11945, option=[null, null, null, null, drop] +item=Skeletal armour set, id=11946, option=[null, null, null, null, drop] +item=Skeletal armour set, id=11947, option=[null, null, null, null, drop] +item=null, id=11948, option=[null, null, null, null, drop] +item=Snow globe, id=11949, option=[Shake, null, null, null, Destroy] +item=Snow globe, id=11950, option=[Shake, null, null, null, Destroy] +item=Snowball, id=11951, option=[null, Wield, null, null, drop] +item=Ice sword, id=11952, option=[null, null, null, null, Destroy] +item=Winter staff, id=11953, option=[null, null, null, null, Destroy] +item=Holly bow, id=11954, option=[null, null, null, null, Destroy] +item=Barbarian snowman hat, id=11955, option=[null, null, null, null, Destroy] +item=Dragon snowman hat, id=11956, option=[null, null, null, null, Destroy] +item=Dwarf snowman hat, id=11957, option=[null, null, null, null, Destroy] +item=Pirate snowman hat, id=11958, option=[null, null, null, null, Destroy] +item=Snowman top hat, id=11959, option=[null, null, null, null, Destroy] +item=Light mystic robes set, id=11960, option=[null, null, null, null, drop] +item=Light mystic robes set, id=11961, option=[null, null, null, null, drop] +item=Dark mystic robes set, id=11962, option=[null, null, null, null, drop] +item=Dark mystic robes set, id=11963, option=[null, null, null, null, drop] +item=Raven egg, id=11964, option=[null, null, null, null, drop] +item=Vulture egg, id=11965, option=[null, null, null, null, drop] +item=Bird's nest, id=11966, option=[Search, null, null, null, drop] +item=Dwarf cannon set, id=11967, option=[null, null, null, null, drop] +item=Dwarf cannon set, id=11968, option=[null, null, null, null, drop] +item=Enchanted water tiara, id=11969, option=[null, Wear, null, Check-charges, Destroy] +item=Smelly crate, id=11970, option=[null, null, null, null, Destroy] +item=Full crate, id=11971, option=[Empty, null, null, null, Destroy] +item=Empty crate, id=11972, option=[null, null, null, null, Destroy] +item=Scabaras research, id=11973, option=[Read, null, null, null, Destroy] +item=Artefact receipt, id=11974, option=[null, null, null, null, Destroy] +item=Scabarite notes, id=11975, option=[Copy to log, null, null, null, Destroy] +item=Scabarite notes, id=11976, option=[Copy to log, null, null, null, Destroy] +item=Scabarite notes, id=11977, option=[Copy to log, null, null, null, Destroy] +item=Scabarite notes, id=11978, option=[Copy to log, null, null, null, Destroy] +item=Scabarite notes, id=11979, option=[Copy to log, null, null, null, Destroy] +item=Scabarite notes, id=11980, option=[Copy to log, null, null, null, Destroy] +item=Scabarite notes, id=11981, option=[Copy to log, null, null, null, Destroy] +item=Scabarite notes, id=11982, option=[Copy to log, null, null, null, Destroy] +item=Scabarite notes, id=11983, option=[Copy to log, null, null, null, Destroy] +item=Scabarite notes, id=11984, option=[Copy to log, null, null, null, Destroy] +item=Scabarite notes, id=11985, option=[Copy to log, null, null, null, Destroy] +item=Scabarite notes, id=11986, option=[Copy to log, null, null, null, Destroy] +item=Scabarite notes, id=11987, option=[Copy to log, null, null, null, Destroy] +item=Scabarite notes, id=11988, option=[Copy to log, null, null, null, Destroy] +item=Scabarite notes, id=11989, option=[Copy to log, null, null, null, Destroy] +item=Scabarite notes, id=11990, option=[Copy to log, null, null, null, Destroy] +item=Scabarite notes, id=11991, option=[Copy to log, null, null, null, Destroy] +item=Scabarite notes, id=11992, option=[Copy to log, null, null, null, Destroy] +item=Scabarite notes, id=11993, option=[Copy to log, null, null, null, Destroy] +item=Scabarite key, id=11994, option=[null, null, null, null, Destroy] +item=Oxidised dagger, id=11995, option=[null, null, null, null, Destroy] +item=Oxidised medium helm, id=11996, option=[null, null, null, null, Destroy] +item=Oxidised sword, id=11997, option=[null, null, null, null, Destroy] +item=Oxidised scimitar, id=11998, option=[null, null, null, null, Destroy] +item=Oxidised longsword, id=11999, option=[null, null, null, null, Destroy] +item=Oxidised full helm, id=12000, option=[null, null, null, null, Destroy] +item=Oxidised square shield, id=12001, option=[null, null, null, null, Destroy] +item=Oxidised chainbody, id=12002, option=[null, null, null, null, Destroy] +item=Oxidised kiteshield, id=12003, option=[null, null, null, null, Destroy] +item=Oxidised two-handed sword, id=12004, option=[null, null, null, null, Destroy] +item=Oxidised platelegs, id=12005, option=[null, null, null, null, Destroy] +item=Oxidised plateskirt, id=12006, option=[null, null, null, null, Destroy] +item=Spirit terrorbird pouch, id=12007, option=[null, null, null, Summon, drop] +item=Spirit terrorbird pouch, id=12008, option=[null, null, null, null, drop] +item=Granite crab pouch, id=12009, option=[null, null, null, Summon, drop] +item=Granite crab pouch, id=12010, option=[null, null, null, null, drop] +item=Praying mantis pouch, id=12011, option=[null, null, null, Summon, drop] +item=Praying mantis pouch, id=12012, option=[null, null, null, null, drop] +item=Giant ent pouch, id=12013, option=[null, null, null, Summon, drop] +item=Giant ent pouch, id=12014, option=[null, null, null, null, drop] +item=Spirit cobra pouch, id=12015, option=[null, null, null, Summon, drop] +item=Spirit cobra pouch, id=12016, option=[null, null, null, null, drop] +item=Spirit dagannoth pouch, id=12017, option=[null, null, null, Summon, drop] +item=Spirit dagannoth pouch, id=12018, option=[null, null, null, null, drop] +item=Thorny snail pouch, id=12019, option=[null, null, null, Summon, drop] +item=Thorny snail pouch, id=12020, option=[null, null, null, null, drop] +item=Beaver pouch, id=12021, option=[null, null, null, Summon, drop] +item=Beaver pouch, id=12022, option=[null, null, null, null, drop] +item=Karam. overlord pouch, id=12023, option=[null, null, null, Summon, drop] +item=Karam. overlord pouch, id=12024, option=[null, null, null, null, drop] +item=Hydra pouch, id=12025, option=[null, null, null, Summon, drop] +item=Hydra pouch, id=12026, option=[null, null, null, null, drop] +item=Spirit jelly pouch, id=12027, option=[null, null, null, Summon, drop] +item=Spirit jelly pouch, id=12028, option=[null, null, null, null, drop] +item=Bunyip pouch, id=12029, option=[null, null, null, Summon, drop] +item=Bunyip pouch, id=12030, option=[null, null, null, null, drop] +item=War tortoise pouch, id=12031, option=[null, null, null, Summon, drop] +item=War tortoise pouch, id=12032, option=[null, null, null, null, drop] +item=Fruit bat pouch, id=12033, option=[null, null, null, Summon, drop] +item=Fruit bat pouch, id=12034, option=[null, null, null, null, drop] +item=Abyssal parasite pouch, id=12035, option=[null, null, null, Summon, drop] +item=Abyssal parasite pouch, id=12036, option=[null, null, null, null, drop] +item=Abyssal lurker pouch, id=12037, option=[null, null, null, Summon, drop] +item=Abyssal lurker pouch, id=12038, option=[null, null, null, null, drop] +item=Unicorn stallion pouch, id=12039, option=[null, null, null, Summon, drop] +item=Unicorn stallion pouch, id=12040, option=[null, null, null, null, drop] +item=Magpie pouch, id=12041, option=[null, null, null, Summon, drop] +item=Magpie pouch, id=12042, option=[null, null, null, null, drop] +item=Dreadfowl pouch, id=12043, option=[null, null, null, Summon, drop] +item=Dreadfowl pouch, id=12044, option=[null, null, null, null, drop] +item=Stranger plant pouch, id=12045, option=[null, null, null, Summon, drop] +item=Stranger plant pouch, id=12046, option=[null, null, null, null, drop] +item=Spirit wolf pouch, id=12047, option=[null, null, null, Summon, drop] +item=Spirit wolf pouch, id=12048, option=[null, null, null, null, drop] +item=Desert wyrm pouch, id=12049, option=[null, null, null, Summon, drop] +item=Desert wyrm pouch, id=12050, option=[null, null, null, null, drop] +item=Evil turnip pouch, id=12051, option=[null, null, null, Summon, drop] +item=Evil turnip pouch, id=12052, option=[null, null, null, null, drop] +item=Vampire bat pouch, id=12053, option=[null, null, null, Summon, drop] +item=Vampire bat pouch, id=12054, option=[null, null, null, null, drop] +item=Spirit scorpion pouch, id=12055, option=[null, null, null, Summon, drop] +item=Spirit scorpion pouch, id=12056, option=[null, null, null, null, drop] +item=Arctic bear pouch, id=12057, option=[null, null, null, Summon, drop] +item=Arctic bear pouch, id=12058, option=[null, null, null, null, drop] +item=Spirit spider pouch, id=12059, option=[null, null, null, Summon, drop] +item=Spirit spider pouch, id=12060, option=[null, null, null, null, drop] +item=Bloated leech pouch, id=12061, option=[null, null, null, Summon, drop] +item=Bloated leech pouch, id=12062, option=[null, null, null, null, drop] +item=Spirit kalphite pouch, id=12063, option=[null, null, null, Summon, drop] +item=Spirit kalphite pouch, id=12064, option=[null, null, null, null, drop] +item=Honey badger pouch, id=12065, option=[null, null, null, Summon, drop] +item=Honey badger pouch, id=12066, option=[null, null, null, null, drop] +item=Albino rat pouch, id=12067, option=[null, null, null, Summon, drop] +item=Albino rat pouch, id=12068, option=[null, null, null, null, drop] +item=Granite lobster pouch, id=12069, option=[null, null, null, Summon, drop] +item=Granite lobster pouch, id=12070, option=[null, null, null, null, drop] +item=Macaw pouch, id=12071, option=[null, null, null, Summon, drop] +item=Macaw pouch, id=12072, option=[null, null, null, null, drop] +item=Bronze minotaur pouch, id=12073, option=[null, null, null, Summon, drop] +item=Bronze minotaur pouch, id=12074, option=[null, null, null, null, drop] +item=Iron minotaur pouch, id=12075, option=[null, null, null, Summon, drop] +item=Iron minotaur pouch, id=12076, option=[null, null, null, null, drop] +item=Steel minotaur pouch, id=12077, option=[null, null, null, Summon, drop] +item=Steel minotaur pouch, id=12078, option=[null, null, null, null, drop] +item=Mithril minotaur pouch, id=12079, option=[null, null, null, Summon, drop] +item=Mithril minotaur pouch, id=12080, option=[null, null, null, null, drop] +item=Adamant minotaur pouch, id=12081, option=[null, null, null, Summon, drop] +item=Adamant minotaur pouch, id=12082, option=[null, null, null, null, drop] +item=Rune minotaur pouch, id=12083, option=[null, null, null, Summon, drop] +item=Rune minotaur pouch, id=12084, option=[null, null, null, null, drop] +item=Smoke devil pouch, id=12085, option=[null, null, null, Summon, drop] +item=Smoke devil pouch, id=12086, option=[null, null, null, null, drop] +item=Bull ant pouch, id=12087, option=[null, null, null, Summon, drop] +item=Bull ant pouch, id=12088, option=[null, null, null, null, drop] +item=Wolpertinger pouch, id=12089, option=[null, null, null, Summon, drop] +item=Wolpertinger pouch, id=12090, option=[null, null, null, null, drop] +item=Compost mound pouch, id=12091, option=[null, null, null, Summon, drop] +item=Compost mound pouch, id=12092, option=[null, null, null, null, drop] +item=Pack yak pouch, id=12093, option=[null, null, null, Summon, drop] +item=Pack yak pouch, id=12094, option=[null, null, null, null, drop] +item=Sp. cockatrice pouch, id=12095, option=[null, null, null, Summon, drop] +item=Sp. cockatrice pouch, id=12096, option=[null, null, null, null, drop] +item=Sp. guthatrice pouch, id=12097, option=[null, null, null, Summon, drop] +item=Sp. guthatrice pouch, id=12098, option=[null, null, null, null, drop] +item=Sp. saratrice pouch, id=12099, option=[null, null, null, Summon, drop] +item=Sp. saratrice pouch, id=12100, option=[null, null, null, null, drop] +item=Sp. zamatrice pouch, id=12101, option=[null, null, null, Summon, drop] +item=Sp. zamatrice pouch, id=12102, option=[null, null, null, null, drop] +item=Sp. pengatrice pouch, id=12103, option=[null, null, null, Summon, drop] +item=Sp. pengatrice pouch, id=12104, option=[null, null, null, null, drop] +item=Sp. coraxatrice pouch, id=12105, option=[null, null, null, Summon, drop] +item=Sp. coraxatrice pouch, id=12106, option=[null, null, null, null, drop] +item=Sp. vulatrice pouch, id=12107, option=[null, null, null, Summon, drop] +item=Sp. vulatrice pouch, id=12108, option=[null, null, null, null, drop] +item=Cockatrice egg, id=12109, option=[null, null, null, null, drop] +item=Cockatrice egg, id=12110, option=[null, null, null, null, drop] +item=Guthatrice egg, id=12111, option=[null, null, null, null, drop] +item=Guthatrice egg, id=12112, option=[null, null, null, null, drop] +item=Saratrice egg, id=12113, option=[null, null, null, null, drop] +item=Saratrice egg, id=12114, option=[null, null, null, null, drop] +item=Zamatrice egg, id=12115, option=[null, null, null, null, drop] +item=Zamatrice egg, id=12116, option=[null, null, null, null, drop] +item=Pengatrice egg, id=12117, option=[null, null, null, null, drop] +item=Pengatrice egg, id=12118, option=[null, null, null, null, drop] +item=Coraxatrice egg, id=12119, option=[null, null, null, null, drop] +item=Coraxatrice egg, id=12120, option=[null, null, null, null, drop] +item=Vulatrice egg, id=12121, option=[null, null, null, null, drop] +item=Vulatrice egg, id=12122, option=[null, null, null, null, drop] +item=Barker toad pouch, id=12123, option=[null, null, null, Summon, drop] +item=Barker toad pouch, id=12124, option=[null, null, null, null, drop] +item=Flies, id=12125, option=[null, null, null, null, drop] +item=Flies, id=12126, option=[null, null, null, null, drop] +item=Beetle bits, id=12127, option=[null, null, null, null, drop] +item=Beetle bits, id=12128, option=[null, null, null, null, drop] +item=Ground fishing bait, id=12129, option=[null, null, null, null, drop] +item=Nuts, id=12130, option=[null, null, null, null, drop] +item=Nuts, id=12131, option=[null, null, null, null, drop] +item=Truffle, id=12132, option=[Eat, null, null, null, drop] +item=Truffle, id=12133, option=[null, null, null, null, drop] +item=Evil turnip, id=12134, option=[Eat, null, null, null, drop] +item=Evil turnip, id=12135, option=[null, null, null, null, drop] +item=2/3 evil turnip, id=12136, option=[Eat, null, null, null, drop] +item=2/3 evil turnip, id=12137, option=[null, null, null, null, drop] +item=1/3 evil turnip, id=12138, option=[Eat, null, null, null, drop] +item=1/3 evil turnip, id=12139, option=[null, null, null, null, drop] +item=Summoning potion(4), id=12140, option=[Drink, null, null, Empty, drop] +item=Summoning potion(4), id=12141, option=[null, null, null, null, drop] +item=Summoning potion(3), id=12142, option=[Drink, null, null, Empty, drop] +item=Summoning potion(3), id=12143, option=[null, null, null, null, drop] +item=Summoning potion(2), id=12144, option=[Drink, null, null, Empty, drop] +item=Summoning potion(2), id=12145, option=[null, null, null, null, drop] +item=Summoning potion(1), id=12146, option=[Drink, null, null, Empty, drop] +item=Summoning potion(1), id=12147, option=[null, null, null, null, drop] +item=Evil turnip seed, id=12148, option=[null, null, null, null, drop] +item=null, id=12149, option=[null, null, null, null, drop] +item=null, id=12150, option=[null, null, null, null, drop] +item=null, id=12151, option=[null, null, null, null, drop] +item=null, id=12152, option=[null, null, null, null, drop] +item=Carved evil turnip, id=12153, option=[null, null, null, null, drop] +item=Carved evil turnip, id=12154, option=[null, null, null, null, drop] +item=Pouch, id=12155, option=[null, null, null, null, drop] +item=Honeycomb, id=12156, option=[null, null, null, null, drop] +item=Honeycomb, id=12157, option=[null, null, null, null, drop] +item=Gold charm, id=12158, option=[null, null, null, null, drop] +item=Green charm, id=12159, option=[null, null, null, null, drop] +item=Crimson charm, id=12160, option=[null, null, null, null, drop] +item=Abyssal charm, id=12161, option=[null, null, null, null, drop] +item=Talon beast charm, id=12162, option=[null, null, null, null, drop] +item=Blue charm, id=12163, option=[null, null, null, null, drop] +item=Ravager charm, id=12164, option=[null, null, null, null, drop] +item=Shifter charm, id=12165, option=[null, null, null, null, drop] +item=Spinner charm, id=12166, option=[null, null, null, null, drop] +item=Torcher charm, id=12167, option=[null, null, null, null, drop] +item=Obsidian charm, id=12168, option=[null, null, null, null, drop] +item=Summoning skillcape, id=12169, option=[null, Wear, null, null, drop] +item=Summoning skillcape(t), id=12170, option=[null, Wear, null, null, drop] +item=Summoning hood, id=12171, option=[null, Wear, null, null, drop] +item=Clean spirit weed, id=12172, option=[null, null, null, null, drop] +item=Clean spirit weed, id=12173, option=[null, null, null, null, drop] +item=Grimy spirit weed, id=12174, option=[Clean, null, null, null, drop] +item=Grimy spirit weed, id=12175, option=[null, null, null, null, drop] +item=Spirit weed seed, id=12176, option=[null, null, null, null, drop] +item=null, id=12177, option=[null, null, null, null, drop] +item=null, id=12178, option=[null, null, null, null, drop] +item=null, id=12179, option=[null, null, null, null, drop] +item=null, id=12180, option=[null, null, null, null, drop] +item=Spirit weed potion(unf), id=12181, option=[null, null, null, Empty, drop] +item=Spirit weed potion(unf), id=12182, option=[null, null, null, null, drop] +item=Spirit shards, id=12183, option=[null, null, null, null, drop] +item=Gecko, id=12184, option=[null, null, null, null, drop] +item=Saradomin owl, id=12185, option=[null, null, null, null, drop] +item=Zamorak hawk, id=12186, option=[null, null, null, null, drop] +item=Guthix raptor, id=12187, option=[null, null, null, null, drop] +item=Penguin, id=12188, option=[null, null, null, null, drop] +item=Bird, id=12189, option=[null, null, null, null, drop] +item=Vulture, id=12190, option=[null, null, null, null, drop] +item=Terrier puppy, id=12191, option=[null, null, null, null, drop] +item=Greyhound puppy, id=12192, option=[null, null, null, null, drop] +item=Labrador puppy, id=12193, option=[null, null, null, null, drop] +item=Dalmatian puppy, id=12194, option=[null, null, null, null, drop] +item=Sheepdog puppy, id=12195, option=[null, null, null, null, drop] +item=Bulldog puppy, id=12196, option=[null, null, null, null, drop] +item=Dragon hatchling, id=12197, option=[null, null, null, null, drop] +item=Baby giant crab, id=12198, option=[null, null, null, null, drop] +item=Baby raccoon, id=12199, option=[null, null, null, null, drop] +item=Squirrel, id=12200, option=[null, null, null, null, drop] +item=Monkey, id=12201, option=[null, null, null, null, drop] +item=null, id=0, option=[null, null, null, null, drop] +item=Chameleon, id=12203, option=[null, null, null, null, drop] +item=Antlers, id=12204, option=[null, Wear, null, null, drop] +item=Antlers, id=12205, option=[null, null, null, null, drop] +item=Antlers (charged), id=12206, option=[null, Wear, Commune, Uncharge, drop] +item=Lizard skull, id=12207, option=[null, Wear, null, null, drop] +item=Lizard skull, id=12208, option=[null, null, null, null, drop] +item=Lizard skull (charged), id=12209, option=[null, Wear, Commune, Uncharge, drop] +item=Feather headdress, id=12210, option=[null, Wear, null, null, drop] +item=Feather headdress, id=12211, option=[null, null, null, null, drop] +item=Feather headdress (charged), id=12212, option=[null, Wear, Commune, Uncharge, drop] +item=Feather headdress, id=12213, option=[null, Wear, null, null, drop] +item=Feather headdress, id=12214, option=[null, null, null, null, drop] +item=Feather headdress (charged), id=12215, option=[null, Wear, Commune, Uncharge, drop] +item=Feather headdress, id=12216, option=[null, Wear, null, null, drop] +item=Feather headdress, id=12217, option=[null, null, null, null, drop] +item=Feather headdress (charged), id=12218, option=[null, Wear, Commune, Uncharge, drop] +item=Feather headdress, id=12219, option=[null, Wear, null, null, drop] +item=Feather headdress, id=12220, option=[null, null, null, null, drop] +item=Feather headdress (charged), id=12221, option=[null, Wear, Commune, Uncharge, drop] +item=Feather headdress, id=12222, option=[null, Wear, null, null, drop] +item=Feather headdress, id=12223, option=[null, null, null, null, drop] +item=Feather headdress (charged), id=12224, option=[null, Wear, Commune, Uncharge, drop] +item=Pouch, id=12225, option=[null, null, null, null, drop] +item=Pouch, id=12226, option=[null, null, null, null, drop] +item=Pouch, id=12227, option=[null, null, null, null, drop] +item=Pouch, id=12228, option=[null, null, null, null, drop] +item=Pouch, id=12229, option=[null, null, null, null, drop] +item=Pouch, id=12230, option=[null, null, null, null, drop] +item=Pouch, id=12231, option=[null, null, null, null, drop] +item=Pouch, id=12232, option=[null, null, null, null, drop] +item=Pouch, id=12233, option=[null, null, null, null, drop] +item=Pouch, id=12234, option=[null, null, null, null, drop] +item=Pouch, id=12235, option=[null, null, null, null, drop] +item=Pouch, id=12236, option=[null, null, null, null, drop] +item=Pouch, id=12237, option=[null, null, null, null, drop] +item=Pouch, id=12238, option=[null, null, null, null, drop] +item=Pouch, id=12239, option=[null, null, null, null, drop] +item=Pouch, id=12240, option=[null, null, null, null, drop] +item=Pouch, id=12241, option=[null, null, null, null, drop] +item=Pouch, id=12242, option=[null, null, null, null, drop] +item=Pouch, id=12243, option=[null, null, null, null, drop] +item=Pouch, id=12244, option=[null, null, null, null, drop] +item=Pouch, id=12245, option=[null, null, null, null, drop] +item=Pouch, id=12246, option=[null, null, null, null, drop] +item=Pouch, id=12247, option=[null, null, null, null, drop] +item=Pouch, id=12248, option=[null, null, null, null, drop] +item=Pouch, id=12249, option=[null, null, null, null, drop] +item=Pouch, id=12250, option=[null, null, null, null, drop] +item=Pouch, id=12251, option=[null, null, null, null, drop] +item=Pouch, id=12252, option=[null, null, null, null, drop] +item=Pouch, id=12253, option=[null, null, null, null, drop] +item=Pouch, id=12254, option=[null, null, null, null, drop] +item=Pouch, id=12255, option=[null, null, null, null, drop] +item=Pouch, id=12256, option=[null, null, null, null, drop] +item=Pouch, id=12257, option=[null, null, null, null, drop] +item=Pouch, id=12258, option=[null, null, null, null, drop] +item=Pouch, id=12259, option=[null, null, null, null, drop] +item=Pouch, id=12260, option=[null, null, null, null, drop] +item=Pouch, id=12261, option=[null, null, null, null, drop] +item=Pouch, id=12262, option=[null, null, null, null, drop] +item=Pouch, id=12263, option=[null, null, null, null, drop] +item=Pouch, id=12264, option=[null, null, null, null, drop] +item=Pouch, id=12265, option=[null, null, null, null, drop] +item=Pouch, id=12266, option=[null, null, null, null, drop] +item=Pouch, id=12267, option=[null, null, null, null, drop] +item=Pouch, id=12268, option=[null, null, null, null, drop] +item=Pouch, id=12269, option=[null, null, null, null, drop] +item=Pouch, id=12270, option=[null, null, null, null, drop] +item=Pouch, id=12271, option=[null, null, null, null, drop] +item=Pouch, id=12272, option=[null, null, null, null, drop] +item=Pouch, id=12273, option=[null, null, null, null, drop] +item=Pouch, id=12274, option=[null, null, null, null, drop] +item=Pouch, id=12275, option=[null, null, null, null, drop] +item=Pouch, id=12276, option=[null, null, null, null, drop] +item=Pouch, id=12277, option=[null, null, null, null, drop] +item=Pouch, id=12278, option=[null, null, null, null, drop] +item=Pouch, id=12279, option=[null, null, null, null, drop] +item=Pouch, id=12280, option=[null, null, null, null, drop] +item=Pouch, id=12281, option=[null, null, null, null, drop] +item=Pouch, id=12282, option=[null, null, null, null, drop] +item=Pouch, id=12283, option=[null, null, null, null, drop] +item=Pouch, id=12284, option=[null, null, null, null, drop] +item=Pouch, id=12285, option=[null, null, null, null, drop] +item=Pouch, id=12286, option=[null, null, null, null, drop] +item=Pouch, id=12287, option=[null, null, null, null, drop] +item=Pouch, id=12288, option=[null, null, null, null, drop] +item=Pouch, id=12289, option=[null, null, null, null, drop] +item=Pouch, id=12290, option=[null, null, null, null, drop] +item=Pouch, id=12291, option=[null, null, null, null, drop] +item=Pouch, id=12292, option=[null, null, null, null, drop] +item=Pouch, id=12293, option=[null, null, null, null, drop] +item=Pouch, id=12294, option=[null, null, null, null, drop] +item=Pouch, id=12295, option=[null, null, null, null, drop] +item=Pouch, id=12296, option=[null, null, null, null, drop] +item=Pouch, id=12297, option=[null, null, null, null, drop] +item=Pouch, id=12298, option=[null, null, null, null, drop] +item=Pouch, id=12299, option=[null, null, null, null, drop] +item=Pouch, id=12300, option=[null, null, null, null, drop] +item=Pouch, id=12301, option=[null, null, null, null, drop] +item=Pouch, id=12302, option=[null, null, null, null, drop] +item=Pouch, id=12303, option=[null, null, null, null, drop] +item=Pouch, id=12304, option=[null, null, null, null, drop] +item=Pouch, id=12305, option=[null, null, null, null, drop] +item=Pouch, id=12306, option=[null, null, null, null, drop] +item=Pouch, id=12307, option=[null, null, null, null, drop] +item=Pouch, id=12308, option=[null, null, null, null, drop] +item=Pouch, id=12309, option=[null, null, null, null, drop] +item=Pouch, id=12310, option=[null, null, null, null, drop] +item=Pouch, id=12311, option=[null, null, null, null, drop] +item=Pouch, id=12312, option=[null, null, null, null, drop] +item=Pouch, id=12313, option=[null, null, null, null, drop] +item=Pouch, id=12314, option=[null, null, null, null, drop] +item=Pouch, id=12315, option=[null, null, null, null, drop] +item=Pouch, id=12316, option=[null, null, null, null, drop] +item=Pouch, id=12317, option=[null, null, null, null, drop] +item=Pouch, id=12318, option=[null, null, null, null, drop] +item=Pouch, id=12319, option=[null, null, null, null, drop] +item=Pouch, id=12320, option=[null, null, null, null, drop] +item=Pouch, id=12321, option=[null, null, null, null, drop] +item=Pouch, id=12322, option=[null, null, null, null, drop] +item=Pouch, id=12323, option=[null, null, null, null, drop] +item=Pouch, id=12324, option=[null, null, null, null, drop] +item=Pouch, id=12325, option=[null, null, null, null, drop] +item=Pouch, id=12326, option=[null, null, null, null, drop] +item=Pouch, id=12327, option=[null, null, null, null, drop] +item=Pouch, id=12328, option=[null, null, null, null, drop] +item=Pouch, id=12329, option=[null, null, null, null, drop] +item=Pouch, id=12330, option=[null, null, null, null, drop] +item=Pouch, id=12331, option=[null, null, null, null, drop] +item=Pouch, id=12332, option=[null, null, null, null, drop] +item=Pouch, id=12333, option=[null, null, null, null, drop] +item=Pouch, id=12334, option=[null, null, null, null, drop] +item=Pouch, id=12335, option=[null, null, null, null, drop] +item=Pouch, id=12336, option=[null, null, null, null, drop] +item=Pouch, id=12337, option=[null, null, null, null, drop] +item=Pouch, id=12338, option=[null, null, null, null, drop] +item=Pouch, id=12339, option=[null, null, null, null, drop] +item=Pouch, id=12340, option=[null, null, null, null, drop] +item=Pouch, id=12341, option=[null, null, null, null, drop] +item=Pouch, id=12342, option=[null, null, null, null, drop] +item=Pouch, id=12343, option=[null, null, null, null, drop] +item=Pouch, id=12344, option=[null, null, null, null, drop] +item=Pouch, id=12345, option=[null, null, null, null, drop] +item=Pouch, id=12346, option=[null, null, null, null, drop] +item=Pouch, id=12347, option=[null, null, null, null, drop] +item=Pouch, id=12348, option=[null, null, null, null, drop] +item=Pouch, id=12349, option=[null, null, null, null, drop] +item=Pouch, id=12350, option=[null, null, null, null, drop] +item=Pouch, id=12351, option=[null, null, null, null, drop] +item=Pouch, id=12352, option=[null, null, null, null, drop] +item=Pouch, id=12353, option=[null, null, null, null, drop] +item=Pouch, id=12354, option=[null, null, null, null, drop] +item=Pouch, id=12355, option=[null, null, null, null, drop] +item=Pouch, id=12356, option=[null, null, null, null, drop] +item=Pouch, id=12357, option=[null, null, null, null, drop] +item=Pouch, id=12358, option=[null, null, null, null, drop] +item=Pouch, id=12359, option=[null, null, null, null, drop] +item=Pouch, id=12360, option=[null, null, null, null, drop] +item=Pouch, id=12361, option=[null, null, null, null, drop] +item=Pouch, id=12362, option=[null, null, null, null, drop] +item=Pouch, id=12363, option=[null, null, null, null, drop] +item=Pouch, id=12364, option=[null, null, null, null, drop] +item=Pouch, id=12365, option=[null, null, null, null, drop] +item=Pouch, id=12366, option=[null, null, null, null, drop] +item=Pouch, id=12367, option=[null, null, null, null, drop] +item=Pouch, id=12368, option=[null, null, null, null, drop] +item=Pouch, id=12369, option=[null, null, null, null, drop] +item=Pouch, id=12370, option=[null, null, null, null, drop] +item=Pouch, id=12371, option=[null, null, null, null, drop] +item=Pouch, id=12372, option=[null, null, null, null, drop] +item=Pouch, id=12373, option=[null, null, null, null, drop] +item=Pouch, id=12374, option=[null, null, null, null, drop] +item=Pouch, id=12375, option=[null, null, null, null, drop] +item=Pouch, id=12376, option=[null, null, null, null, drop] +item=Pouch, id=12377, option=[null, null, null, null, drop] +item=Pouch, id=12378, option=[null, null, null, null, drop] +item=Pouch, id=12379, option=[null, null, null, null, drop] +item=Pouch, id=12380, option=[null, null, null, null, drop] +item=Pouch, id=12381, option=[null, null, null, null, drop] +item=Pouch, id=12382, option=[null, null, null, null, drop] +item=Pouch, id=12383, option=[null, null, null, null, drop] +item=Pouch, id=12384, option=[null, null, null, null, drop] +item=Pouch, id=12385, option=[null, null, null, null, drop] +item=Pouch, id=12386, option=[null, null, null, null, drop] +item=Pouch, id=12387, option=[null, null, null, null, drop] +item=Pouch, id=12388, option=[null, null, null, null, drop] +item=Pouch, id=12389, option=[null, null, null, null, drop] +item=Pouch, id=12390, option=[null, null, null, null, drop] +item=Pouch, id=12391, option=[null, null, null, null, drop] +item=Pouch, id=12392, option=[null, null, null, null, drop] +item=Pouch, id=12393, option=[null, null, null, null, drop] +item=Pouch, id=12394, option=[null, null, null, null, drop] +item=Pouch, id=12395, option=[null, null, null, null, drop] +item=Pouch, id=12396, option=[null, null, null, null, drop] +item=Pouch, id=12397, option=[null, null, null, null, drop] +item=Pouch, id=12398, option=[null, null, null, null, drop] +item=Pouch, id=12399, option=[null, null, null, null, drop] +item=Pouch, id=12400, option=[null, null, null, null, drop] +item=Pouch, id=12401, option=[null, null, null, null, drop] +item=Pouch, id=12402, option=[null, null, null, null, drop] +item=Pouch, id=12403, option=[null, null, null, null, drop] +item=Pouch, id=12404, option=[null, null, null, null, drop] +item=Pouch, id=12405, option=[null, null, null, null, drop] +item=Pouch, id=12406, option=[null, null, null, null, drop] +item=Pouch, id=12407, option=[null, null, null, null, drop] +item=Pouch, id=12408, option=[null, null, null, null, drop] +item=Pouch, id=12409, option=[null, null, null, null, drop] +item=Pouch, id=12410, option=[null, null, null, null, drop] +item=Pouch, id=12411, option=[null, null, null, null, drop] +item=Pouch, id=12412, option=[null, null, null, null, drop] +item=Pouch, id=12413, option=[null, null, null, null, drop] +item=Pouch, id=12414, option=[null, null, null, null, drop] +item=Pouch, id=12415, option=[null, null, null, null, drop] +item=Pouch, id=12416, option=[null, null, null, null, drop] +item=Pouch, id=12417, option=[null, null, null, null, drop] +item=Pouch, id=12418, option=[null, null, null, null, drop] +item=Pouch, id=12419, option=[null, null, null, null, drop] +item=Pouch, id=12420, option=[null, null, null, null, drop] +item=Scroll, id=12421, option=[null, null, null, null, drop] +item=Herbcall scroll, id=12422, option=[null, null, null, null, drop] +item=Fruitfall scroll, id=12423, option=[null, null, null, null, drop] +item=Fish rain scroll, id=12424, option=[null, null, null, null, drop] +item=Howl scroll, id=12425, option=[null, null, null, null, drop] +item=Thieving fingers scroll, id=12426, option=[null, null, null, null, drop] +item=Abyssal stealth scroll, id=12427, option=[null, null, null, null, drop] +item=Egg spawn scroll, id=12428, option=[null, null, null, null, drop] +item=Multichop scroll, id=12429, option=[null, null, null, null, drop] +item=Cheese feast scroll, id=12430, option=[null, null, null, null, drop] +item=Unburden scroll, id=12431, option=[null, null, null, null, drop] +item=Venom shot scroll, id=12432, option=[null, null, null, null, drop] +item=Insane ferocity scroll, id=12433, option=[null, null, null, null, drop] +item=Healing aura scroll, id=12434, option=[null, null, null, null, drop] +item=Winter storage scroll, id=12435, option=[null, null, null, null, drop] +item=Oph. incubation scroll, id=12436, option=[null, null, null, null, drop] +item=Magic focus scroll, id=12437, option=[null, null, null, null, drop] +item=Swallow whole scroll, id=12438, option=[null, null, null, null, drop] +item=Testudo scroll, id=12439, option=[null, null, null, null, drop] +item=Generate compost scroll, id=12440, option=[null, null, null, null, drop] +item=Tireless run scroll, id=12441, option=[null, null, null, null, drop] +item=Regrowth scroll, id=12442, option=[null, null, null, null, drop] +item=Call to arms scroll, id=12443, option=[null, null, null, null, drop] +item=Blood drain scroll, id=12444, option=[null, null, null, null, drop] +item=Dreadfowl strike scroll, id=12445, option=[null, null, null, null, drop] +item=Sandstorm scroll, id=12446, option=[null, null, null, null, drop] +item=Vampire touch scroll, id=12447, option=[null, null, null, null, drop] +item=Evil flames scroll, id=12448, option=[null, null, null, null, drop] +item=Crushing claw scroll, id=12449, option=[null, null, null, null, drop] +item=Mantis strike scroll, id=12450, option=[null, null, null, null, drop] +item=Arctic blast scroll, id=12451, option=[null, null, null, null, drop] +item=Toad bark scroll, id=12452, option=[null, null, null, null, drop] +item=Dissolve scroll, id=12453, option=[null, null, null, null, drop] +item=Abyssal drain scroll, id=12454, option=[null, null, null, null, drop] +item=Doomsphere scroll, id=12455, option=[null, null, null, null, drop] +item=Spike shot scroll, id=12456, option=[null, null, null, null, drop] +item=Acorn missile scroll, id=12457, option=[null, null, null, null, drop] +item=Petrifying gaze scroll, id=12458, option=[null, null, null, null, drop] +item=Slime spray scroll, id=12459, option=[null, null, null, null, drop] +item=Electric lash scroll, id=12460, option=[null, null, null, null, drop] +item=Bronze bull rush scroll, id=12461, option=[null, null, null, null, drop] +item=Iron bull rush scroll, id=12462, option=[null, null, null, null, drop] +item=Steel bull rush scroll, id=12463, option=[null, null, null, null, drop] +item=Mith bull rush scroll, id=12464, option=[null, null, null, null, drop] +item=Addy bull rush scroll, id=12465, option=[null, null, null, null, drop] +item=Rune bull rush scroll, id=12466, option=[null, null, null, null, drop] +item=Poisonous blast scroll, id=12467, option=[null, null, null, null, drop] +item=Dust cloud scroll, id=12468, option=[null, null, null, null, drop] +item=Hatchling dragon, id=12469, option=[null, null, null, null, drop] +item=Baby dragon, id=12470, option=[null, null, null, null, drop] +item=Hatchling dragon, id=12471, option=[null, null, null, null, drop] +item=Baby dragon, id=12472, option=[null, null, null, null, drop] +item=Hatchling dragon, id=12473, option=[null, null, null, null, drop] +item=Baby dragon, id=12474, option=[null, null, null, null, drop] +item=Hatchling dragon, id=12475, option=[null, null, null, null, drop] +item=Baby dragon, id=12476, option=[null, null, null, null, drop] +item=Red dragon egg, id=12477, option=[null, null, null, null, drop] +item=Blue dragon egg, id=12478, option=[null, null, null, null, drop] +item=Green dragon egg, id=12479, option=[null, null, null, null, drop] +item=Black dragon egg, id=12480, option=[null, null, null, null, drop] +item=Baby penguin, id=12481, option=[null, null, null, null, drop] +item=Penguin, id=12482, option=[null, null, null, null, drop] +item=Penguin egg, id=12483, option=[null, null, null, null, drop] +item=Raven chick, id=12484, option=[null, null, null, null, drop] +item=Raven, id=12485, option=[null, null, null, null, drop] +item=Baby raccoon, id=12486, option=[null, null, null, null, drop] +item=Raccoon, id=12487, option=[null, null, null, null, drop] +item=Baby gecko, id=12488, option=[null, null, null, null, drop] +item=Gecko, id=12489, option=[null, null, null, null, drop] +item=Baby squirrel, id=12490, option=[null, null, null, null, drop] +item=Squirrel, id=12491, option=[null, null, null, null, drop] +item=Baby chameleon, id=12492, option=[null, null, null, null, drop] +item=Chameleon, id=12493, option=[null, null, null, null, drop] +item=Chameleon egg, id=12494, option=[null, null, null, null, drop] +item=Chameleon egg, id=12495, option=[null, null, null, null, drop] +item=Baby monkey, id=12496, option=[null, null, null, null, drop] +item=Monkey, id=12497, option=[null, null, null, null, drop] +item=Vulture chick, id=12498, option=[null, null, null, null, drop] +item=Vulture, id=12499, option=[null, null, null, null, drop] +item=Baby giant crab, id=12500, option=[null, null, null, null, drop] +item=Giant crab, id=12501, option=[null, null, null, null, drop] +item=Crunchy claw token, id=12502, option=[null, null, null, null, drop] +item=Saradomin chick, id=12503, option=[null, null, null, null, drop] +item=Saradomin bird, id=12504, option=[null, null, null, null, drop] +item=Saradomin owl, id=12505, option=[null, null, null, null, drop] +item=Zamorak chick, id=12506, option=[null, null, null, null, drop] +item=Zamorak bird, id=12507, option=[null, null, null, null, drop] +item=Zamorak hawk, id=12508, option=[null, null, null, null, drop] +item=Guthix chick, id=12509, option=[null, null, null, null, drop] +item=Guthix bird, id=12510, option=[null, null, null, null, drop] +item=Guthix raptor, id=12511, option=[null, null, null, null, drop] +item=Terrier puppy, id=12512, option=[null, null, null, null, drop] +item=Terrier, id=12513, option=[null, null, null, null, drop] +item=Greyhound puppy, id=12514, option=[null, null, null, null, drop] +item=Greyhound, id=12515, option=[null, null, null, null, drop] +item=Labrador puppy, id=12516, option=[null, null, null, null, drop] +item=Labrador, id=12517, option=[null, null, null, null, drop] +item=Dalmatian puppy, id=12518, option=[null, null, null, null, drop] +item=Dalmatian, id=12519, option=[null, null, null, null, drop] +item=Sheepdog puppy, id=12520, option=[null, null, null, null, drop] +item=Sheepdog, id=12521, option=[null, null, null, null, drop] +item=Bulldog puppy, id=12522, option=[null, null, null, null, drop] +item=Bulldog, id=12523, option=[null, null, null, null, drop] +item=Summoning cape, id=12524, option=[null, Wear, null, null, drop] +item=Pouch, id=12525, option=[null, null, null, null, Destroy] +item=Spirit wolf pouch, id=12526, option=[null, null, null, Summon, Destroy] +item=Gold charm, id=12527, option=[null, null, null, null, Destroy] +item=Trapdoor key, id=12528, option=[null, null, null, null, Destroy] +item=Howl scroll, id=12529, option=[null, null, null, null, Destroy] +item=Spirit shards, id=12530, option=[null, null, null, null, Destroy] +item=Ibis pouch, id=12531, option=[null, null, null, Summon, drop] +item=Ibis pouch, id=12532, option=[null, null, null, null, drop] +item=Stony shell scroll, id=12533, option=[null, null, null, null, drop] +item=null, id=0, option=[null, null, null, null, drop] +item=Raw pawya meat, id=12535, option=[null, null, null, null, drop] +item=Raw pawya meat, id=12536, option=[null, null, null, null, drop] +item=Grenwall, id=12537, option=[null, null, null, null, drop] +item=Grenwall, id=12538, option=[null, null, null, null, drop] +item=Grenwall spikes, id=12539, option=[null, null, null, null, drop] +item=null, id=12540, option=[null, null, null, null, drop] +item=null, id=12541, option=[null, null, null, null, drop] +item=null, id=12542, option=[null, null, null, null, drop] +item=null, id=12543, option=[null, null, null, null, drop] +item=Pawya, id=12544, option=[null, null, null, null, drop] +item=Pawya, id=12545, option=[null, null, null, null, drop] +item=Enchanted pawya meat, id=12546, option=[null, null, null, null, drop] +item=Platypus, id=12547, option=[null, null, null, null, drop] +item=Platypus, id=12548, option=[null, null, null, null, drop] +item=Platypus, id=12549, option=[null, null, null, null, drop] +item=Platypus, id=12550, option=[null, null, null, null, drop] +item=Baby platypus, id=12551, option=[null, null, null, null, drop] +item=Baby platypus, id=12552, option=[null, null, null, null, drop] +item=Baby platypus, id=12553, option=[null, null, null, null, drop] +item=Patrick, id=12554, option=[null, null, null, null, Release] +item=Penelope, id=12555, option=[null, null, null, null, Release] +item=Peter, id=12556, option=[null, null, null, null, Release] +item=Peanut, id=12557, option=[null, null, null, null, Release] +item=Mud, id=12558, option=[null, Apply, null, null, drop] +item=Ogre wig, id=12559, option=[null, Wear, null, null, drop] +item=Ogre wig, id=12560, option=[null, null, null, null, drop] +item=Ogre kilt, id=12561, option=[null, Wear, null, null, drop] +item=Ogre kilt, id=12562, option=[null, null, null, null, drop] +item=Ogre top, id=12563, option=[null, Wear, null, null, drop] +item=Ogre top, id=12564, option=[null, null, null, null, drop] +item=Ogre boots, id=12565, option=[null, Wear, null, null, drop] +item=Ogre boots, id=12566, option=[null, null, null, null, drop] +item=Diseased kebbit fur, id=12567, option=[null, null, null, null, drop] +item=Davy kebbit hat, id=12568, option=[null, Wear, null, null, drop] +item=Davy kebbit hat, id=12569, option=[null, null, null, null, drop] +item=Ogre club, id=12570, option=[null, Wield, null, null, drop] +item=Ogre club, id=12571, option=[null, null, null, null, drop] +item=Lavender, id=12572, option=[null, null, null, null, drop] +item=Lavender, id=12573, option=[null, null, null, null, drop] +item=Fever grass, id=12574, option=[null, null, null, null, drop] +item=Fever grass, id=12575, option=[null, null, null, null, drop] +item=Tansymum, id=12576, option=[null, null, null, null, drop] +item=Tansymum, id=12577, option=[null, null, null, null, drop] +item=Smouldering fever grass, id=12578, option=[null, Wield, null, Extinguish, drop] +item=Smouldering lavender, id=12579, option=[null, Wield, null, Extinguish, drop] +item=Smouldering tansymum, id=12580, option=[null, Wield, null, Extinguish, drop] +item=Eucalyptus logs, id=12581, option=[null, null, null, null, drop] +item=Eucalyptus logs, id=12582, option=[null, null, null, null, drop] +item=Eucalyptus pyre logs, id=12583, option=[null, null, null, null, drop] +item=Eucalyptus pyre logs, id=12584, option=[null, null, null, null, drop] +item=null, id=12585, option=[null, null, null, null, drop] +item=null, id=12586, option=[null, null, null, null, drop] +item=null, id=12587, option=[null, null, null, null, drop] +item=Primweed, id=12588, option=[null, null, null, null, drop] +item=Primweed, id=12589, option=[null, null, null, null, drop] +item=Stinkbloom, id=12590, option=[null, null, null, null, drop] +item=Stinkbloom, id=12591, option=[null, null, null, null, drop] +item=Diseased kebbit fur, id=12592, option=[null, null, null, null, drop] +item=Catapult schematics, id=12593, option=[Read, null, null, null, Destroy] +item=Engineer's letter, id=12594, option=[Read, null, null, null, Destroy] +item=Sailor's hat, id=12595, option=[null, Wear, null, null, Destroy] +item=Metal catapult parts, id=12596, option=[null, null, null, null, Destroy] +item=Mahogany catapult part, id=12597, option=[null, null, null, null, Destroy] +item=Mahogany catapult part, id=12598, option=[null, null, null, null, Destroy] +item=Mahogany catapult part, id=12599, option=[null, null, null, null, Destroy] +item=Mahogany catapult part, id=12600, option=[null, null, null, null, Destroy] +item=Mahogany catapult part, id=12601, option=[null, null, null, null, Destroy] +item=Mahogany catapult part, id=12602, option=[null, null, null, null, Destroy] +item=Mahogany catapult part, id=12603, option=[null, null, null, null, Destroy] +item=Mahogany catapult part, id=12604, option=[null, null, null, null, Destroy] +item=Mahogany catapult part, id=12605, option=[null, null, null, null, Destroy] +item=Mahogany catapult part, id=12606, option=[null, null, null, null, Destroy] +item=Mahogany catapult part, id=12607, option=[null, Wield, null, null, drop] +item=Amulet of farming(1), id=12608, option=[Rub, Wear, null, null, drop] +item=Amulet of farming(1), id=12609, option=[null, null, null, null, drop] +item=Amulet of farming(2), id=12610, option=[Rub, Wear, null, null, drop] +item=Amulet of farming(2), id=12611, option=[null, null, null, null, drop] +item=Amulet of farming(3), id=12612, option=[Rub, Wear, null, null, drop] +item=Amulet of farming(3), id=12613, option=[null, null, null, null, drop] +item=Amulet of farming(4), id=12614, option=[Rub, Wear, null, null, drop] +item=Amulet of farming(4), id=12615, option=[null, null, null, null, drop] +item=Amulet of farming(5), id=12616, option=[Rub, Wear, null, null, drop] +item=Amulet of farming(5), id=12617, option=[null, null, null, null, drop] +item=Amulet of farming(6), id=12618, option=[Rub, Wear, null, null, drop] +item=Amulet of farming(6), id=12619, option=[null, null, null, null, drop] +item=Amulet of farming(7), id=12620, option=[Rub, Wear, null, null, drop] +item=Amulet of farming(7), id=12621, option=[null, null, null, null, drop] +item=Amulet of farming(8), id=12622, option=[Rub, Wear, null, null, drop] +item=Amulet of farming(8), id=12623, option=[null, null, null, null, drop] +item=Ogleroot, id=12624, option=[null, null, null, null, drop] +item=Flag, id=12625, option=[null, null, null, null, Destroy] +item=Test paper, id=12626, option=[Take Exam, null, null, null, Destroy] +item=Antique lamp, id=12627, option=[Rub, null, null, null, Destroy] +item=Antique lamp, id=12628, option=[Rub, null, null, null, Destroy] +item=Safety gloves, id=12629, option=[null, Wear, null, null, Destroy] +item=Rubium, id=12630, option=[null, null, null, null, Destroy] +item=Toy train, id=12631, option=[null, null, null, null, Destroy] +item=Note, id=12632, option=[Read, null, null, null, Destroy] +item=Super fishing explosive, id=12633, option=[null, null, null, null, drop] +item=Chocatrice cape, id=12634, option=[null, Wear, null, null, Destroy] +item=Easter egg, id=12635, option=[Eat, null, null, null, Destroy] +item=Easter egg, id=12636, option=[Eat, null, null, null, Destroy] +item=Easter egg, id=12637, option=[Eat, null, null, null, Destroy] +item=Easter egg, id=12638, option=[Eat, null, null, null, Destroy] +item=Easter egg, id=12639, option=[Eat, null, null, null, Destroy] +item=Easter egg, id=12640, option=[Eat, null, null, null, Destroy] +item=Easter egg, id=12641, option=[Eat, null, null, null, Destroy] +item=Easter egg, id=12642, option=[Eat, null, null, null, Destroy] +item=Easter egg, id=12643, option=[Eat, null, null, null, Destroy] +item=Easter egg, id=12644, option=[Eat, null, null, null, Destroy] +item=Chocatrice cape, id=12645, option=[null, Wear, null, null, Destroy] +item=Chocolate egg, id=12646, option=[Eat, null, null, null, drop] +item=Chocolate egg, id=12647, option=[Eat, null, null, null, drop] +item=Chocolate egg, id=12648, option=[Eat, null, null, null, drop] +item=Bucket, id=12649, option=[null, null, null, null, drop] +item=Bucket of water, id=12650, option=[null, null, Empty, null, drop] +item=Bucket of water, id=12651, option=[null, null, Empty, null, drop] +item=Bucket of coal, id=12652, option=[null, null, Empty, null, drop] +item=Bucket of coal, id=12653, option=[null, null, Empty, null, drop] +item=Cockatrice egg, id=12654, option=[null, null, null, null, Destroy] +item=Chocatrice egg, id=12655, option=[null, null, null, null, Destroy] +item=Chocatrice object, id=12656, option=[null, null, null, null, drop] +item=Chocolate chunks, id=12657, option=[null, null, null, null, Destroy] +item=Adamant full helm (e), id=12658, option=[null, Wear, null, null, drop] +item=Adamant full helm (charged), id=12659, option=[null, Wear, Commune, Uncharge, drop] +item=Snakeskin bandana (e), id=12660, option=[null, Wear, null, null, drop] +item=Snakeskin bandana (charged), id=12661, option=[null, Wear, Commune, Uncharge, drop] +item=Splitbark helm (e), id=12662, option=[null, Wear, null, null, drop] +item=Splitbark helm (charged), id=12663, option=[null, Wear, Commune, Uncharge, drop] +item=Rune full helm (e), id=12664, option=[null, Wear, null, null, drop] +item=Rune full helm (charged), id=12665, option=[null, Wear, Commune, Uncharge, drop] +item=Dragon med helm (e), id=12666, option=[null, Wear, null, null, drop] +item=Dragon med helm (charged), id=12667, option=[null, Wear, Commune, Uncharge, drop] +item=Lunar helm (e), id=12668, option=[null, Wear, null, null, Destroy] +item=Lunar helm (charged), id=12669, option=[null, Wear, Commune, Uncharge, Destroy] +item=Armadyl helmet (e), id=12670, option=[null, Wear, null, null, drop] +item=Armadyl helmet (charged), id=12671, option=[null, Wear, Commune, Uncharge, drop] +item=Archer helm (e), id=12672, option=[null, Wear, null, null, drop] +item=Archer helm (charged), id=12673, option=[null, Wear, Commune, Uncharge, drop] +item=Berserker helm (e), id=12674, option=[null, Wear, null, null, drop] +item=Berserker helm (charged), id=12675, option=[null, Wear, Commune, Uncharge, drop] +item=Warrior helm (e), id=12676, option=[null, Wear, null, null, drop] +item=Warrior helm (charged), id=12677, option=[null, Wear, Commune, Uncharge, drop] +item=Farseer helm (e), id=12678, option=[null, Wear, null, null, drop] +item=Farseer helm (charged), id=12679, option=[null, Wear, Commune, Uncharge, drop] +item=Helm of neitiznot (e), id=12680, option=[null, Wear, null, null, drop] +item=Helm of neitiznot (charged), id=12681, option=[null, Wear, Commune, Uncharge, drop] +item=Baby monkey, id=12682, option=[null, null, null, null, drop] +item=Monkey, id=12683, option=[null, null, null, null, drop] +item=Baby monkey, id=12684, option=[null, null, null, null, drop] +item=Monkey, id=12685, option=[null, null, null, null, drop] +item=Baby monkey, id=12686, option=[null, null, null, null, drop] +item=Monkey, id=12687, option=[null, null, null, null, drop] +item=Baby monkey, id=12688, option=[null, null, null, null, drop] +item=Monkey, id=12689, option=[null, null, null, null, drop] +item=Baby monkey, id=12690, option=[null, null, null, null, drop] +item=Monkey, id=12691, option=[null, null, null, null, drop] +item=Baby monkey, id=12692, option=[null, null, null, null, drop] +item=Monkey, id=12693, option=[null, null, null, null, drop] +item=Baby monkey, id=12694, option=[null, null, null, null, drop] +item=Monkey, id=12695, option=[null, null, null, null, drop] +item=Baby monkey, id=12696, option=[null, null, null, null, drop] +item=Monkey, id=12697, option=[null, null, null, null, drop] +item=Baby monkey, id=12698, option=[null, null, null, null, drop] +item=Monkey, id=12699, option=[null, null, null, null, drop] +item=Terrier puppy, id=12700, option=[null, null, null, null, drop] +item=Terrier, id=12701, option=[null, null, null, null, drop] +item=Terrier puppy, id=12702, option=[null, null, null, null, drop] +item=Terrier, id=12703, option=[null, null, null, null, drop] +item=Greyhound puppy, id=12704, option=[null, null, null, null, drop] +item=Greyhound, id=12705, option=[null, null, null, null, drop] +item=Greyhound puppy, id=12706, option=[null, null, null, null, drop] +item=Greyhound, id=12707, option=[null, null, null, null, drop] +item=Labrador puppy, id=12708, option=[null, null, null, null, drop] +item=Labrador, id=12709, option=[null, null, null, null, drop] +item=Labrador puppy, id=12710, option=[null, null, null, null, drop] +item=Labrador, id=12711, option=[null, null, null, null, drop] +item=Dalmatian puppy, id=12712, option=[null, null, null, null, drop] +item=Dalmatian, id=12713, option=[null, null, null, null, drop] +item=Dalmatian puppy, id=12714, option=[null, null, null, null, drop] +item=Dalmatian, id=12715, option=[null, null, null, null, drop] +item=Sheepdog puppy, id=12716, option=[null, null, null, null, drop] +item=Sheepdog, id=12717, option=[null, null, null, null, drop] +item=Sheepdog puppy, id=12718, option=[null, null, null, null, drop] +item=Sheepdog, id=12719, option=[null, null, null, null, drop] +item=Bulldog puppy, id=12720, option=[null, null, null, null, drop] +item=Bulldog, id=12721, option=[null, null, null, null, drop] +item=Bulldog puppy, id=12722, option=[null, null, null, null, drop] +item=Bulldog, id=12723, option=[null, null, null, null, drop] +item=Raven chick, id=12724, option=[null, null, null, null, drop] +item=Raven, id=12725, option=[null, null, null, null, drop] +item=Raven chick, id=12726, option=[null, null, null, null, drop] +item=Raven, id=12727, option=[null, null, null, null, drop] +item=Raven chick, id=12728, option=[null, null, null, null, drop] +item=Raven, id=12729, option=[null, null, null, null, drop] +item=Raven chick, id=12730, option=[null, null, null, null, drop] +item=Raven, id=12731, option=[null, null, null, null, drop] +item=Raven chick, id=12732, option=[null, null, null, null, drop] +item=Raven, id=12733, option=[null, null, null, null, drop] +item=Baby raccoon, id=12734, option=[null, null, null, null, drop] +item=Raccoon, id=12735, option=[null, null, null, null, drop] +item=Baby raccoon, id=12736, option=[null, null, null, null, drop] +item=Raccoon, id=12737, option=[null, null, null, null, drop] +item=Baby gecko, id=12738, option=[null, null, null, null, drop] +item=Baby gecko, id=12739, option=[null, null, null, null, drop] +item=Baby gecko, id=12740, option=[null, null, null, null, drop] +item=Baby gecko, id=12741, option=[null, null, null, null, drop] +item=Gecko, id=12742, option=[null, null, null, null, drop] +item=Gecko, id=12743, option=[null, null, null, null, drop] +item=Gecko, id=12744, option=[null, null, null, null, drop] +item=Gecko, id=12745, option=[null, null, null, null, drop] +item=Baby giant crab, id=12746, option=[null, null, null, null, drop] +item=Giant crab, id=12747, option=[null, null, null, null, drop] +item=Baby giant crab, id=12748, option=[null, null, null, null, drop] +item=Giant crab, id=12749, option=[null, null, null, null, drop] +item=Baby giant crab, id=12750, option=[null, null, null, null, drop] +item=Giant crab, id=12751, option=[null, null, null, null, drop] +item=Baby giant crab, id=12752, option=[null, null, null, null, drop] +item=Giant crab, id=12753, option=[null, null, null, null, drop] +item=Baby squirrel, id=12754, option=[null, null, null, null, drop] +item=Squirrel, id=12755, option=[null, null, null, null, drop] +item=Baby squirrel, id=12756, option=[null, null, null, null, drop] +item=Squirrel, id=12757, option=[null, null, null, null, drop] +item=Baby squirrel, id=12758, option=[null, null, null, null, drop] +item=Squirrel, id=12759, option=[null, null, null, null, drop] +item=Baby squirrel, id=12760, option=[null, null, null, null, drop] +item=Squirrel, id=12761, option=[null, null, null, null, drop] +item=Penguin, id=12762, option=[null, null, null, null, drop] +item=Baby penguin, id=12763, option=[null, null, null, null, drop] +item=Penguin, id=12764, option=[null, null, null, null, drop] +item=Baby penguin, id=12765, option=[null, null, null, null, drop] +item=Vulture chick, id=12766, option=[null, null, null, null, drop] +item=Vulture, id=12767, option=[null, null, null, null, drop] +item=Vulture chick, id=12768, option=[null, null, null, null, drop] +item=Vulture, id=12769, option=[null, null, null, null, drop] +item=Vulture chick, id=12770, option=[null, null, null, null, drop] +item=Vulture, id=12771, option=[null, null, null, null, drop] +item=Vulture chick, id=12772, option=[null, null, null, null, drop] +item=Vulture, id=12773, option=[null, null, null, null, drop] +item=Vulture chick, id=12774, option=[null, null, null, null, drop] +item=Vulture, id=12775, option=[null, null, null, null, drop] +item=Swamp titan pouch, id=12776, option=[null, null, null, Summon, drop] +item=Swamp titan pouch, id=12777, option=[null, null, null, null, drop] +item=Spirit mosquito pouch, id=12778, option=[null, null, null, Summon, drop] +item=Spirit mosquito pouch, id=12779, option=[null, null, null, null, drop] +item=Void spinner pouch, id=12780, option=[null, null, null, Summon, drop] +item=Void spinner pouch, id=12781, option=[null, null, null, null, drop] +item=Forge regent pouch, id=12782, option=[null, null, null, Summon, drop] +item=Forge regent pouch, id=12783, option=[null, null, null, null, drop] +item=Spirit larupia pouch, id=12784, option=[null, null, null, Summon, drop] +item=Spirit larupia pouch, id=12785, option=[null, null, null, null, drop] +item=Geyser titan pouch, id=12786, option=[null, null, null, Summon, drop] +item=Geyser titan pouch, id=12787, option=[null, null, null, null, drop] +item=Lava titan pouch, id=12788, option=[null, null, null, Summon, drop] +item=Lava titan pouch, id=12789, option=[null, null, null, null, drop] +item=Steel titan pouch, id=12790, option=[null, null, null, Summon, drop] +item=Steel titan pouch, id=12791, option=[null, null, null, null, drop] +item=Obsidian golem pouch, id=12792, option=[null, null, null, Summon, drop] +item=Obsidian golem pouch, id=12793, option=[null, null, null, null, drop] +item=Talon beast pouch, id=12794, option=[null, null, null, Summon, drop] +item=Talon beast pouch, id=12795, option=[null, null, null, null, drop] +item=Abyssal titan pouch, id=12796, option=[null, null, null, Summon, drop] +item=Abyssal titan pouch, id=12797, option=[null, null, null, null, drop] +item=Void torcher pouch, id=12798, option=[null, null, null, Summon, drop] +item=Void torcher pouch, id=12799, option=[null, null, null, null, drop] +item=Giant chinchompa pouch, id=12800, option=[null, null, null, Summon, drop] +item=Giant chinchompa pouch, id=12801, option=[null, null, null, null, drop] +item=Fire titan pouch, id=12802, option=[null, null, null, Summon, drop] +item=Fire titan pouch, id=12803, option=[null, null, null, null, drop] +item=Moss titan pouch, id=12804, option=[null, null, null, Summon, drop] +item=Moss titan pouch, id=12805, option=[null, null, null, null, drop] +item=Ice titan pouch, id=12806, option=[null, null, null, Summon, drop] +item=Ice titan pouch, id=12807, option=[null, null, null, null, drop] +item=Spirit tz-kih pouch, id=12808, option=[null, null, null, Summon, drop] +item=Spirit tz-kih pouch, id=12809, option=[null, null, null, null, drop] +item=Spirit graahk pouch, id=12810, option=[null, null, null, Summon, drop] +item=Spirit graahk pouch, id=12811, option=[null, null, null, null, drop] +item=Spirit kyatt pouch, id=12812, option=[null, null, null, Summon, drop] +item=Spirit kyatt pouch, id=12813, option=[null, null, null, null, drop] +item=Void shifter pouch, id=12814, option=[null, null, null, Summon, drop] +item=Void shifter pouch, id=12815, option=[null, null, null, null, drop] +item=Pyrelord pouch, id=12816, option=[null, null, null, Summon, drop] +item=Pyrelord pouch, id=12817, option=[null, null, null, null, drop] +item=Void ravager pouch, id=12818, option=[null, null, null, Summon, drop] +item=Void ravager pouch, id=12819, option=[null, null, null, null, drop] +item=Ravenous locust pouch, id=12820, option=[null, null, null, Summon, drop] +item=Ravenous locust pouch, id=12821, option=[null, null, null, null, drop] +item=Iron titan pouch, id=12822, option=[null, null, null, Summon, drop] +item=Iron titan pouch, id=12823, option=[null, null, null, null, drop] +item=Titan's con. scroll, id=12824, option=[null, null, null, null, drop] +item=Steel of legends scroll, id=12825, option=[null, null, null, null, drop] +item=Volcanic str. scroll, id=12826, option=[null, null, null, null, drop] +item=Essence shipment scroll, id=12827, option=[null, null, null, null, drop] +item=Iron within scroll, id=12828, option=[null, null, null, null, drop] +item=Immense heat scroll, id=12829, option=[null, null, null, null, drop] +item=Famine scroll, id=12830, option=[null, null, null, null, drop] +item=Deadly claw scroll, id=12831, option=[null, null, null, null, drop] +item=Swamp plague scroll, id=12832, option=[null, null, null, null, drop] +item=Boil scroll, id=12833, option=[null, null, null, null, drop] +item=Explode scroll, id=12834, option=[null, null, null, null, drop] +item=Goad scroll, id=12835, option=[null, null, null, null, drop] +item=Ambush scroll, id=12836, option=[null, null, null, null, drop] +item=Ebon thunder scroll, id=12837, option=[null, null, null, null, drop] +item=Pester scroll, id=12838, option=[null, null, null, null, drop] +item=Fireball assault scroll, id=12839, option=[null, null, null, null, drop] +item=Rending scroll, id=12840, option=[null, null, null, null, drop] +item=Inferno scroll, id=12841, option=[null, null, null, null, drop] +item=Gnomecopter, id=12842, option=[null, Ride, null, null, drop] +item=Gnomecopter ticket, id=12843, option=[Read, null, null, null, Destroy] +item=Toy kite, id=12844, option=[Fly, Wield, null, null, drop] +item=Stone of power, id=12845, option=[null, Wield, null, null, Destroy] +item=Stone of power, id=12846, option=[null, Wield, null, null, Destroy] +item=Stone of power, id=12847, option=[null, Wield, null, null, Destroy] +item=Stone of power, id=12848, option=[null, Wield, null, null, Destroy] +item=Stone of power, id=12849, option=[null, Wield, null, null, Destroy] +item=Elemental rune, id=12850, option=[null, null, null, null, Destroy] +item=Catalytic rune, id=12851, option=[null, null, null, null, Destroy] +item=Fist of guthix token, id=12852, option=[null, null, null, null, drop] +item=Bandages, id=12853, option=[Heal, null, null, null, Destroy] +item=null, id=12854, option=[null, null, null, null, drop] +item=Tele-orb, id=12855, option=[Teleport, null, null, null, Destroy] +item=Irit gloves, id=12856, option=[null, Wear, Inspect, null, Destroy] +item=Avantoe gloves, id=12857, option=[null, Wear, Inspect, null, Destroy] +item=Kwuarm gloves, id=12858, option=[null, Wear, Inspect, null, Destroy] +item=Cadantine gloves, id=12859, option=[null, Wear, Inspect, null, Destroy] +item=Swordfish gloves, id=12860, option=[null, Wear, Inspect, null, Destroy] +item=Shark gloves, id=12861, option=[null, Wear, Inspect, null, Destroy] +item=Dragon slayer gloves, id=12862, option=[null, Wear, Inspect, null, Destroy] +item=Air runecrafting gloves, id=12863, option=[null, Wear, Inspect, null, Destroy] +item=Water runecrafting gloves, id=12864, option=[null, Wear, Inspect, null, Destroy] +item=Earth runecrafting gloves, id=12865, option=[null, Wear, Inspect, null, Destroy] +item=Battle hood 100, id=12866, option=[null, Wear, null, null, drop] +item=Battle hood 80, id=12867, option=[null, Wear, null, null, drop] +item=Battle hood 60, id=12868, option=[null, Wear, null, null, drop] +item=Battle hood 40, id=12869, option=[null, Wear, null, null, drop] +item=Battle hood 20, id=12870, option=[null, Wear, null, null, drop] +item=Battle hood 0, id=12871, option=[null, Wear, null, null, drop] +item=Battle hood 0, id=12872, option=[null, null, null, null, drop] +item=Battle robe top 100, id=12873, option=[null, Wear, null, null, drop] +item=Battle robe top 80, id=12874, option=[null, Wear, null, null, drop] +item=Battle robe top 60, id=12875, option=[null, Wear, null, null, drop] +item=Battle robe top 40, id=12876, option=[null, Wear, null, null, drop] +item=Battle robe top 20, id=12877, option=[null, Wear, null, null, drop] +item=Battle robe top 0, id=12878, option=[null, Wear, null, null, drop] +item=Battle robe top 0, id=12879, option=[null, null, null, null, drop] +item=Battle robe bottom 100, id=12880, option=[null, Wear, null, null, drop] +item=Battle robe bottom 80, id=12881, option=[null, Wear, null, null, drop] +item=Battle robe bottom 60, id=12882, option=[null, Wear, null, null, drop] +item=Battle robe bottom 40, id=12883, option=[null, Wear, null, null, drop] +item=Battle robe bottom 20, id=12884, option=[null, Wear, null, null, drop] +item=Battle robe bottom 0, id=12885, option=[null, Wear, null, null, drop] +item=Battle robe bottom 0, id=12886, option=[null, null, null, null, drop] +item=Druidic mage hood 100, id=12887, option=[null, Wear, null, null, drop] +item=Druidic mage hood 80, id=12888, option=[null, Wear, null, null, drop] +item=Druidic mage hood 60, id=12889, option=[null, Wear, null, null, drop] +item=Druidic mage hood 40, id=12890, option=[null, Wear, null, null, drop] +item=Druidic mage hood 20, id=12891, option=[null, Wear, null, null, drop] +item=Druidic mage hood 0, id=12892, option=[null, Wear, null, null, drop] +item=Druidic mage hood 0, id=12893, option=[null, null, null, null, drop] +item=Druidic mage top 100, id=12894, option=[null, Wear, null, null, drop] +item=Druidic mage top 80, id=12895, option=[null, Wear, null, null, drop] +item=Druidic mage top 60, id=12896, option=[null, Wear, null, null, drop] +item=Druidic mage top 40, id=12897, option=[null, Wear, null, null, drop] +item=Druidic mage top 20, id=12898, option=[null, Wear, null, null, drop] +item=Druidic mage top 0, id=12899, option=[null, Wear, null, null, drop] +item=Druidic mage top 0, id=12900, option=[null, null, null, null, drop] +item=Druidic mage bottom 100, id=12901, option=[null, Wear, null, null, drop] +item=Druidic mage bottom 80, id=12902, option=[null, Wear, null, null, drop] +item=Druidic mage bottom 60, id=12903, option=[null, Wear, null, null, drop] +item=Druidic mage bottom 40, id=12904, option=[null, Wear, null, null, drop] +item=Druidic mage bottom 20, id=12905, option=[null, Wear, null, null, drop] +item=Druidic mage bottom 0, id=12906, option=[null, Wear, null, null, drop] +item=Druidic mage bottom 0, id=12907, option=[null, null, null, null, drop] +item=Adamant spikeshield 100, id=12908, option=[null, Wield, null, null, drop] +item=Adamant spikeshield 80, id=12909, option=[null, Wield, null, null, drop] +item=Adamant spikeshield 60, id=12910, option=[null, Wield, null, null, drop] +item=Adamant spikeshield 40, id=12911, option=[null, Wield, null, null, drop] +item=Adamant spikeshield 20, id=12912, option=[null, Wield, null, null, drop] +item=Adamant spikeshield 0, id=12913, option=[null, Wield, null, null, drop] +item=Adamant spikeshield 0, id=12914, option=[null, null, null, null, drop] +item=Adamant berserker shield 100, id=12915, option=[null, Wear, null, null, drop] +item=Adamant berserker shield 80, id=12916, option=[null, Wear, null, null, drop] +item=Adamant berserker shield 60, id=12917, option=[null, Wear, null, null, drop] +item=Adamant berserker shield 40, id=12918, option=[null, Wear, null, null, drop] +item=Adamant berserker shield 20, id=12919, option=[null, Wear, null, null, drop] +item=Adamant berserker shield 0, id=12920, option=[null, Wear, null, null, drop] +item=Adamant berserker shield 0, id=12921, option=[null, null, null, null, drop] +item=Rune spikeshield 100, id=12922, option=[null, Wield, null, null, drop] +item=Rune spikeshield 80, id=12923, option=[null, Wield, null, null, drop] +item=Rune spikeshield 60, id=12924, option=[null, Wield, null, null, drop] +item=Rune spikeshield 40, id=12925, option=[null, Wield, null, null, drop] +item=Rune spikeshield 20, id=12926, option=[null, Wield, null, null, drop] +item=Rune spikeshield 0, id=12927, option=[null, Wield, null, null, drop] +item=Rune spikeshield 0, id=12928, option=[null, null, null, null, drop] +item=Rune berserker shield 100, id=12929, option=[null, Wear, null, null, drop] +item=Rune berserker shield 80, id=12930, option=[null, Wear, null, null, drop] +item=Rune berserker shield 60, id=12931, option=[null, Wear, null, null, drop] +item=Rune berserker shield 40, id=12932, option=[null, Wear, null, null, drop] +item=Rune berserker shield 20, id=12933, option=[null, Wear, null, null, drop] +item=Rune berserker shield 0, id=12934, option=[null, Wear, null, null, drop] +item=Rune berserker shield 0, id=12935, option=[null, null, null, null, drop] +item=Green d'hide coif 100, id=12936, option=[null, Wear, null, null, drop] +item=Green d'hide coif 80, id=12937, option=[null, Wear, null, null, drop] +item=Green d'hide coif 60, id=12938, option=[null, Wear, null, null, drop] +item=Green d'hide coif 40, id=12939, option=[null, Wear, null, null, drop] +item=Green d'hide coif 20, id=12940, option=[null, Wear, null, null, drop] +item=Green d'hide coif 0, id=12941, option=[null, Wear, null, null, drop] +item=Green d'hide coif 0, id=12942, option=[null, null, null, null, drop] +item=Blue d'hide coif 100, id=12943, option=[null, Wear, null, null, drop] +item=Blue d'hide coif 80, id=12944, option=[null, Wear, null, null, drop] +item=Blue d'hide coif 60, id=12945, option=[null, Wear, null, null, drop] +item=Blue d'hide coif 40, id=12946, option=[null, Wear, null, null, drop] +item=Blue d'hide coif 20, id=12947, option=[null, Wear, null, null, drop] +item=Blue d'hide coif 0, id=12948, option=[null, Wear, null, null, drop] +item=Blue d'hide coif 0, id=12949, option=[null, null, null, null, drop] +item=Red d'hide coif 100, id=12950, option=[null, Wear, null, null, drop] +item=Red d'hide coif 80, id=12951, option=[null, Wear, null, null, drop] +item=Red d'hide coif 60, id=12952, option=[null, Wear, null, null, drop] +item=Red d'hide coif 40, id=12953, option=[null, Wear, null, null, drop] +item=Red d'hide coif 20, id=12954, option=[null, Wear, null, null, drop] +item=Red d'hide coif 0, id=12955, option=[null, Wear, null, null, drop] +item=Red d'hide coif 0, id=12956, option=[null, null, null, null, drop] +item=Black d'hide coif 100, id=12957, option=[null, Wear, null, null, drop] +item=Black d'hide coif 80, id=12958, option=[null, Wear, null, null, drop] +item=Black d'hide coif 60, id=12959, option=[null, Wear, null, null, drop] +item=Black d'hide coif 40, id=12960, option=[null, Wear, null, null, drop] +item=Black d'hide coif 20, id=12961, option=[null, Wear, null, null, drop] +item=Black d'hide coif 0, id=12962, option=[null, Wear, null, null, drop] +item=Black d'hide coif 0, id=12963, option=[null, null, null, null, drop] +item=Combat hood 100, id=12964, option=[null, Wear, null, null, drop] +item=Combat hood 80, id=12965, option=[null, Wear, null, null, drop] +item=Combat hood 60, id=12966, option=[null, Wear, null, null, drop] +item=Combat hood 40, id=12967, option=[null, Wear, null, null, drop] +item=Combat hood 20, id=12968, option=[null, Wear, null, null, drop] +item=Combat hood 0, id=12969, option=[null, Wear, null, null, drop] +item=Combat hood 0, id=12970, option=[null, null, null, null, drop] +item=Combat robe top 100, id=12971, option=[null, Wear, null, null, drop] +item=Combat robe top 80, id=12972, option=[null, Wear, null, null, drop] +item=Combat robe top 60, id=12973, option=[null, Wear, null, null, drop] +item=Combat robe top 40, id=12974, option=[null, Wear, null, null, drop] +item=Combat robe top 20, id=12975, option=[null, Wear, null, null, drop] +item=Combat robe top 0, id=12976, option=[null, Wear, null, null, drop] +item=Combat robe top 0, id=12977, option=[null, null, null, null, drop] +item=Combat robe bottom 100, id=12978, option=[null, Wear, null, null, drop] +item=Combat robe bottom 80, id=12979, option=[null, Wear, null, null, drop] +item=Combat robe bottom 60, id=12980, option=[null, Wear, null, null, drop] +item=Combat robe bottom 40, id=12981, option=[null, Wear, null, null, drop] +item=Combat robe bottom 20, id=12982, option=[null, Wear, null, null, drop] +item=Combat robe bottom 0, id=12983, option=[null, Wear, null, null, drop] +item=Combat robe bottom 0, id=12984, option=[null, null, null, null, drop] +item=Bronze gauntlets, id=12985, option=[null, Wear, null, null, drop] +item=Worn-out bronze gauntlets, id=12986, option=[null, Wear, null, null, drop] +item=Worn-out bronze gauntlets, id=12987, option=[null, null, null, null, drop] +item=Iron gauntlets, id=12988, option=[null, Wear, null, null, drop] +item=Worn-out iron gauntlets, id=12989, option=[null, Wear, null, null, drop] +item=Worn-out iron gauntlets, id=12990, option=[null, null, null, null, drop] +item=Steel gauntlets, id=12991, option=[null, Wear, null, null, drop] +item=Worn-out steel gauntlets, id=12992, option=[null, Wear, null, null, drop] +item=Worn-out steel gauntlets, id=12993, option=[null, null, null, null, drop] +item=Black gauntlets, id=12994, option=[null, Wear, null, null, drop] +item=Worn-out black gauntlets, id=12995, option=[null, Wear, null, null, drop] +item=Worn-out black gauntlets, id=12996, option=[null, null, null, null, drop] +item=Mithril gauntlets, id=12997, option=[null, Wear, null, null, drop] +item=Worn-out mithril gauntlets, id=12998, option=[null, Wear, null, null, drop] +item=Worn-out mithril gauntlets, id=12999, option=[null, null, null, null, drop] +item=Adamant gauntlets, id=13000, option=[null, Wear, null, null, drop] +item=Worn-out adamant gauntlets, id=13001, option=[null, Wear, null, null, drop] +item=Worn-out adamant gauntlets, id=13002, option=[null, null, null, null, drop] +item=Rune gauntlets, id=13003, option=[null, Wear, null, null, drop] +item=Worn-out rune gauntlets, id=13004, option=[null, Wear, null, null, drop] +item=Worn-out rune gauntlets, id=13005, option=[null, null, null, null, drop] +item=Dragon gauntlets, id=13006, option=[null, Wear, null, null, drop] +item=Worn-out dragon gauntlets, id=13007, option=[null, Wear, null, null, drop] +item=Worn-out dragon gauntlets, id=13008, option=[null, null, null, null, drop] +item=null, id=13009, option=[null, null, null, null, drop] +item=Clue scroll, id=13010, option=[Read, null, null, null, drop] +item=Puzzle box, id=13011, option=[Open, null, null, null, drop] +item=Clue scroll, id=13012, option=[Read, null, null, null, drop] +item=Puzzle box, id=13013, option=[Open, null, null, null, drop] +item=Clue scroll, id=13014, option=[Read, null, null, null, drop] +item=Puzzle box, id=13015, option=[Open, null, null, null, drop] +item=Clue scroll, id=13016, option=[Read, null, null, null, drop] +item=Puzzle box, id=13017, option=[Open, null, null, null, drop] +item=Clue scroll, id=13018, option=[Read, null, null, null, drop] +item=Puzzle box, id=13019, option=[Open, null, null, null, drop] +item=Clue scroll, id=13020, option=[Read, null, null, null, drop] +item=Puzzle box, id=13021, option=[Open, null, null, null, drop] +item=Clue scroll, id=13022, option=[Read, null, null, null, drop] +item=Puzzle box, id=13023, option=[Open, null, null, null, drop] +item=Clue scroll, id=13024, option=[Read, null, null, null, drop] +item=Puzzle box, id=13025, option=[Open, null, null, null, drop] +item=Clue scroll, id=13026, option=[Read, null, null, null, drop] +item=Puzzle box, id=13027, option=[Open, null, null, null, drop] +item=Clue scroll, id=13028, option=[Read, null, null, null, drop] +item=Puzzle box, id=13029, option=[Open, null, null, null, drop] +item=Clue scroll, id=13030, option=[Read, null, null, null, drop] +item=Puzzle box, id=13031, option=[Open, null, null, null, drop] +item=Clue scroll, id=13032, option=[Read, null, null, null, drop] +item=Puzzle box, id=13033, option=[Open, null, null, null, drop] +item=Clue scroll, id=13034, option=[Read, null, null, null, drop] +item=Puzzle box, id=13035, option=[Open, null, null, null, drop] +item=Clue scroll, id=13036, option=[Read, null, null, null, drop] +item=Casket, id=13037, option=[Open, null, null, null, drop] +item=Clue scroll, id=13038, option=[Read, null, null, null, drop] +item=Casket, id=13039, option=[Open, null, null, null, drop] +item=Clue scroll, id=13040, option=[Read, null, null, null, drop] +item=Clue scroll, id=13041, option=[Read, null, null, null, drop] +item=Clue scroll, id=13042, option=[Read, null, null, null, drop] +item=Casket, id=13043, option=[Open, null, null, null, drop] +item=Clue scroll, id=13044, option=[Read, null, null, null, drop] +item=Casket, id=13045, option=[Open, null, null, null, drop] +item=Clue scroll, id=13046, option=[Read, null, null, null, drop] +item=Casket, id=13047, option=[Open, null, null, null, drop] +item=Clue scroll, id=13048, option=[Read, null, null, null, drop] +item=Clue scroll, id=13049, option=[Read, null, null, null, drop] +item=Clue scroll, id=13050, option=[Read, null, null, null, drop] +item=Clue scroll, id=13051, option=[Read, null, null, null, drop] +item=Casket, id=13052, option=[Open, null, null, null, drop] +item=Clue scroll, id=13053, option=[Read, null, null, null, drop] +item=Casket, id=13054, option=[Open, null, null, null, drop] +item=Clue scroll, id=13055, option=[Read, null, null, null, drop] +item=Clue scroll, id=13056, option=[Read, null, null, null, drop] +item=Casket, id=13057, option=[Open, null, null, null, drop] +item=Clue scroll, id=13058, option=[Read, null, null, null, drop] +item=Casket, id=13059, option=[Open, null, null, null, drop] +item=Clue scroll, id=13060, option=[Read, null, null, null, drop] +item=Clue scroll, id=13061, option=[Read, null, null, null, drop] +item=Casket, id=13062, option=[Open, null, null, null, drop] +item=Clue scroll, id=13063, option=[Read, null, null, null, drop] +item=Casket, id=13064, option=[Open, null, null, null, drop] +item=Clue scroll, id=13065, option=[Read, null, null, null, drop] +item=Casket, id=13066, option=[Open, null, null, null, drop] +item=Clue scroll, id=13067, option=[Read, null, null, null, drop] +item=Clue scroll, id=13068, option=[Read, null, null, null, drop] +item=Clue scroll, id=13069, option=[Read, null, null, null, drop] +item=Clue scroll, id=13070, option=[Read, null, null, null, drop] +item=Clue scroll, id=13071, option=[Read, null, null, null, drop] +item=Clue scroll, id=13072, option=[Read, null, null, null, drop] +item=Key, id=13073, option=[null, null, null, null, drop] +item=Clue scroll, id=13074, option=[Read, null, null, null, drop] +item=Clue scroll, id=13075, option=[Read, null, null, null, drop] +item=Clue scroll, id=13076, option=[Read, null, null, null, drop] +item=Casket, id=13077, option=[Open, null, null, null, drop] +item=Clue scroll, id=13078, option=[Read, null, null, null, drop] +item=Clue scroll, id=13079, option=[Read, null, null, null, drop] +item=Clue scroll, id=13080, option=[Read, null, null, null, drop] +item=Black crossbow, id=13081, option=[null, Wield, null, null, drop] +item=Black crossbow, id=13082, option=[null, null, null, null, drop] +item=Black bolts, id=13083, option=[null, Wield, null, null, drop] +item=Black bolts(p), id=13084, option=[null, Wield, null, null, drop] +item=Black bolts(p+), id=13085, option=[null, Wield, null, null, drop] +item=Black bolts(p++), id=13086, option=[null, Wield, null, null, drop] +item=null, id=13087, option=[null, null, null, null, drop] +item=null, id=13088, option=[null, null, null, null, drop] +item=null, id=13089, option=[null, null, null, null, drop] +item=null, id=13090, option=[null, null, null, null, drop] +item=null, id=13091, option=[null, null, null, null, drop] +item=null, id=13092, option=[null, null, null, null, drop] +item=null, id=13093, option=[null, null, null, null, drop] +item=null, id=13094, option=[null, null, null, null, drop] +item=Black cane, id=13095, option=[null, Wield, null, null, drop] +item=Black cane, id=13096, option=[null, null, null, null, drop] +item=Adamant cane, id=13097, option=[null, Wield, null, null, drop] +item=Adamant cane, id=13098, option=[null, null, null, null, drop] +item=Rune cane, id=13099, option=[null, Wield, null, null, drop] +item=Rune cane, id=13100, option=[null, null, null, null, drop] +item=Top hat, id=13101, option=[null, Wear, null, null, drop] +item=Top hat, id=13102, option=[null, null, null, null, drop] +item=Pith helmet, id=13103, option=[null, Wear, null, null, drop] +item=Pith helmet, id=13104, option=[null, null, null, null, drop] +item=Spiked helmet, id=13105, option=[null, Wear, null, null, drop] +item=Spiked helmet, id=13106, option=[null, null, null, null, drop] +item=Sheep mask, id=13107, option=[null, Wear, null, null, drop] +item=Sheep mask, id=13108, option=[null, null, null, null, drop] +item=Penguin mask, id=13109, option=[null, Wear, null, null, drop] +item=Penguin mask, id=13110, option=[null, null, null, null, drop] +item=Bat mask, id=13111, option=[null, Wear, null, null, drop] +item=Bat mask, id=13112, option=[null, null, null, null, drop] +item=Cat mask, id=13113, option=[null, Wear, null, null, drop] +item=Cat mask, id=13114, option=[null, null, null, null, drop] +item=Wolf mask, id=13115, option=[null, Wear, null, null, drop] +item=Wolf mask, id=13116, option=[null, null, null, null, drop] +item=Ivandis flail (30), id=13117, option=[null, Wield, Cast Bloom, null, drop] +item=Ivandis flail (29), id=13118, option=[null, Wield, Cast Bloom, null, drop] +item=Ivandis flail(28), id=13119, option=[null, Wield, Cast Bloom, null, drop] +item=Ivandis flail (27), id=13120, option=[null, Wield, Cast Bloom, null, drop] +item=Ivandis flail (26), id=13121, option=[null, Wield, Cast Bloom, null, drop] +item=Ivandis flail (25), id=13122, option=[null, Wield, Cast Bloom, null, drop] +item=Ivandis flail (24), id=13123, option=[null, Wield, Cast Bloom, null, drop] +item=Ivandis flail (23), id=13124, option=[null, Wield, Cast Bloom, null, drop] +item=Ivandis flail (22), id=13125, option=[null, Wield, Cast Bloom, null, drop] +item=Ivandis flail (21), id=13126, option=[null, Wield, Cast Bloom, null, drop] +item=Ivandis flail (20), id=13127, option=[null, Wield, Cast Bloom, null, drop] +item=Ivandis flail (19), id=13128, option=[null, Wield, Cast Bloom, null, drop] +item=Ivandis flail (18), id=13129, option=[null, Wield, Cast Bloom, null, drop] +item=Ivandis flail (17), id=13130, option=[null, Wield, Cast Bloom, null, drop] +item=Ivandis flail (16), id=13131, option=[null, Wield, Cast Bloom, null, drop] +item=Ivandis flail (15), id=13132, option=[null, Wield, Cast Bloom, null, drop] +item=Ivandis flail (14), id=13133, option=[null, Wield, Cast Bloom, null, drop] +item=Ivandis flail (13), id=13134, option=[null, Wield, Cast Bloom, null, drop] +item=Ivandis flail (12), id=13135, option=[null, Wield, Cast Bloom, null, drop] +item=Ivandis flail (11), id=13136, option=[null, Wield, Cast Bloom, null, drop] +item=Ivandis flail (10), id=13137, option=[null, Wield, Cast Bloom, null, drop] +item=Ivandis flail (9), id=13138, option=[null, Wield, Cast Bloom, null, drop] +item=Ivandis flail (8), id=13139, option=[null, Wield, Cast Bloom, null, drop] +item=Ivandis flail (7), id=13140, option=[null, Wield, Cast Bloom, null, drop] +item=Ivandis flail (6), id=13141, option=[null, Wield, Cast Bloom, null, drop] +item=Ivandis flail (5), id=13142, option=[null, Wield, Cast Bloom, null, drop] +item=Ivandis flail (4), id=13143, option=[null, Wield, Cast Bloom, null, drop] +item=Ivandis flail (3), id=13144, option=[null, Wield, Cast Bloom, null, drop] +item=Ivandis flail (2), id=13145, option=[null, Wield, Cast Bloom, null, drop] +item=Ivandis flail (1), id=13146, option=[null, Wield, Cast Bloom, null, drop] +item=Flail dust, id=13147, option=[null, null, null, null, drop] +item=Glove, id=13148, option=[Inspect, null, null, null, Destroy] +item=Book page, id=13149, option=[Inspect, null, null, null, Destroy] +item=Crate, id=13150, option=[Inspect, null, null, null, Destroy] +item=Combat book, id=13151, option=[Read, null, null, null, Destroy] +item=null, id=13152, option=[null, null, null, null, drop] +item=Chain link mould, id=13153, option=[null, null, null, null, drop] +item=Silvthril chain, id=13154, option=[null, null, null, null, drop] +item=Silver sickle emerald(b), id=13155, option=[null, Wield, Cast Bloom, null, drop] +item=Enchanted sickle emerald(b), id=13156, option=[null, Wield, Cast Bloom, null, drop] +item=Vyre corpse, id=13157, option=[null, null, null, null, drop] +item=Columbarium key, id=13158, option=[null, null, null, null, drop] +item=Ornate tomb key, id=13159, option=[null, null, null, null, Destroy] +item=Tome of xp 2nd ed (3), id=13160, option=[Read, null, null, null, Destroy] +item=Tome of xp 2nd ed (2), id=13161, option=[Read, null, null, null, Destroy] +item=Tome of xp 2nd ed (1), id=13162, option=[Read, null, null, null, Destroy] +item=Black cane, id=13163, option=[null, Wield, null, null, drop] +item=Adamant cane, id=13164, option=[null, Wield, null, null, drop] +item=Rune cane, id=13165, option=[null, Wield, null, null, drop] +item=Top hat, id=13166, option=[null, Wear, null, null, drop] +item=Pith helmet, id=13167, option=[null, Wear, null, null, drop] +item=Spiked helmet, id=13168, option=[null, Wear, null, null, drop] +item=Sheep mask, id=13169, option=[null, Wear, null, null, drop] +item=Penguin mask, id=13170, option=[null, Wear, null, null, drop] +item=Bat mask, id=13171, option=[null, Wear, null, null, drop] +item=Cat mask, id=13172, option=[null, Wear, null, null, drop] +item=Wolf mask, id=13173, option=[null, Wear, null, null, drop] +item=Blue navy slacks, id=13174, option=[null, Wear, null, null, drop] +item=Green navy slacks, id=13175, option=[null, Wear, null, null, drop] +item=Red navy slacks, id=13176, option=[null, Wear, null, null, drop] +item=Brown navy slacks, id=13177, option=[null, Wear, null, null, drop] +item=Black navy slacks, id=13178, option=[null, Wear, null, null, drop] +item=Purple navy slacks, id=13179, option=[null, Wear, null, null, drop] +item=Grey navy slacks, id=13180, option=[null, Wear, null, null, drop] +item=Blue naval shirt, id=13181, option=[null, Wear, null, null, drop] +item=Green naval shirt, id=13182, option=[null, Wear, null, null, drop] +item=Red naval shirt, id=13183, option=[null, Wear, null, null, drop] +item=Brown naval shirt, id=13184, option=[null, Wear, null, null, drop] +item=Black naval shirt, id=13185, option=[null, Wear, null, null, drop] +item=Purple naval shirt, id=13186, option=[null, Wear, null, null, drop] +item=Grey naval shirt, id=13187, option=[null, Wear, null, null, drop] +item=Blue tricorn hat, id=13188, option=[null, Wear, null, null, drop] +item=Green tricorn hat, id=13189, option=[null, Wear, null, null, drop] +item=Red tricorn hat, id=13190, option=[null, Wear, null, null, drop] +item=Brown tricorn hat, id=13191, option=[null, Wear, null, null, drop] +item=Black tricorn hat, id=13192, option=[null, Wear, null, null, drop] +item=Purple tricorn hat, id=13193, option=[null, Wear, null, null, drop] +item=Grey tricorn hat, id=13194, option=[null, Wear, null, null, drop] +item=null, id=13195, option=[null, null, null, null, drop] +item=null, id=13196, option=[null, null, null, null, drop] +item=null, id=13197, option=[null, null, null, null, drop] +item=null, id=13198, option=[null, null, null, null, drop] +item=null, id=13199, option=[null, null, null, null, drop] +item=null, id=13200, option=[null, null, null, null, drop] +item=null, id=13201, option=[null, null, null, null, drop] +item=null, id=13202, option=[null, null, null, null, drop] +item=null, id=13203, option=[null, null, null, null, drop] +item=null, id=13204, option=[null, null, null, null, drop] +item=null, id=13205, option=[null, null, null, null, drop] +item=null, id=13206, option=[null, null, null, null, drop] +item=null, id=13207, option=[null, null, null, null, drop] +item=null, id=13208, option=[null, null, null, null, drop] +item=null, id=13209, option=[null, null, null, null, drop] +item=null, id=13210, option=[null, null, null, null, drop] +item=null, id=13211, option=[null, null, null, null, drop] +item=null, id=13212, option=[null, null, null, null, drop] +item=null, id=13213, option=[null, null, null, null, drop] +item=null, id=13214, option=[null, null, null, null, drop] +item=null, id=13215, option=[null, null, null, null, drop] +item=null, id=13216, option=[null, null, null, null, drop] +item=null, id=13217, option=[null, null, null, null, drop] +item=null, id=13218, option=[null, null, null, null, drop] +item=null, id=13219, option=[null, null, null, null, drop] +item=null, id=13220, option=[null, null, null, null, drop] +item=null, id=13221, option=[null, null, null, null, drop] +item=null, id=13222, option=[null, null, null, null, drop] +item=null, id=13223, option=[null, null, null, null, drop] +item=null, id=13224, option=[null, null, null, null, drop] +item=null, id=13225, option=[null, null, null, null, drop] +item=null, id=13226, option=[null, null, null, null, drop] +item=Mysterious lamp, id=13227, option=[Rub, null, null, null, Destroy] +item=Crate, id=13228, option=[Look-inside, null, null, null, Destroy] +item=Letter, id=13229, option=[Read, null, null, null, Destroy] +item=Icefiend net, id=13230, option=[null, Wield, null, null, Destroy] +item=Baby icefiend, id=13231, option=[null, null, null, null, Release] +item=Tent, id=13232, option=[null, null, null, null, Destroy] +item=Plans, id=13233, option=[Read, null, null, null, Destroy] +item=Dwarven key, id=13234, option=[null, null, null, null, Destroy] +item=null, id=0, option=[null, null, null, null, drop] +item=Three little kittens, id=13236, option=[null, null, null, null, drop] +item=null, id=0, option=[null, null, null, null, drop] +item=Treated oak plank, id=13238, option=[null, null, null, null, drop] +item=Chisel, id=13239, option=[null, null, null, null, drop] +item=Chisel, id=13240, option=[null, null, null, null, drop] +item=Treated plank, id=13241, option=[null, null, null, null, drop] +item=Treated plank, id=13242, option=[null, null, null, null, drop] +item=Stone tablet, id=13243, option=[Read, null, null, null, drop] +item=Tzhaar tourist guide, id=13244, option=[Read, null, null, null, drop] +item=Stone slab, id=13245, option=[null, null, null, null, Destroy] +item=Pillar, id=13246, option=[null, null, null, null, Destroy] \ No newline at end of file diff --git a/dumps/498/498_npc_configs.txt b/dumps/498/498_npc_configs.txt new file mode 100644 index 0000000..cd7cb06 --- /dev/null +++ b/dumps/498/498_npc_configs.txt @@ -0,0 +1,505 @@ +NPC config [id=152, name=Tree, config=939, shift=0, childs=[5207, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5207, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5207, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5207, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5207, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5207, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5207, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5207, -1, -1, 5207, -1, -1, 5207, -1, -1, -1, 5207, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5207, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5207, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5207, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5207, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5207, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5207, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5208, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5208, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5208, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5208, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5208, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5208, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5208, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5208, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5208, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5208, -1]]. +NPC config [id=226, name=Sinister Stranger, config=12, shift=4, childs=[3677, 3678, -1]]. +NPC config [id=292, name=Sick-looking sheep (1), config=518, shift=13, childs=[2345, 2377, -1]]. +NPC config [id=293, name=Sick-looking sheep (2), config=518, shift=15, childs=[2346, 2378, -1]]. +NPC config [id=294, name=Sick-looking sheep (3), config=518, shift=12, childs=[2347, 2379, -1]]. +NPC config [id=295, name=Sick-looking sheep (4), config=518, shift=14, childs=[2348, 2380, -1]]. +NPC config [id=335, name=null, config=667, shift=1, childs=[-1, 3209, -1]]. +NPC config [id=381, name=Captain Barnaby, config=905, shift=27, childs=[4974, -1]]. +NPC config [id=431, name='Bird's-Eye' Jack, config=1003, shift=0, childs=[4544, -1, 4544, -1, 4544, -1, 4544, -1, 4544, -1, 4544, -1, 4544, -1, 4544, -1]]. +NPC config [id=697, name=Kennith, config=159, shift=-1, childs=[4864, 4864, 4864, 4864, 4864, 4864, 4864, 4864, 4864, 4864, 4864, -1]]. +NPC config [id=647, name=Reldo, config=568, shift=26, childs=[2661, 2660, -1]]. +NPC config [id=748, name=Cabin boy Jenkins, config=176, shift=-1, childs=[6085, 6085, 6085, 6085, 6085, 6085, 6085, 6085, -1]]. +NPC config [id=759, name=null, config=180, shift=-1, childs=[-1, -1, 7742, 7742, 7742, -1]]. +NPC config [id=715, name=Elena, config=667, shift=1, childs=[3215, -1]]. +NPC config [id=829, name=Gublinch, config=941, shift=0, childs=[5017, 5018, 5019, -1]]. +NPC config [id=844, name=Wizard Cromperty, config=1077, shift=8, childs=[2328, -1]]. +NPC config [id=1048, name=null, config=1218, shift=10, childs=[-1, 7664, -1]]. +NPC config [id=1047, name=Drezel, config=869, shift=27, childs=[7707, -1]]. +NPC config [id=1207, name=null, config=1190, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7117, -1, -1, -1, -1, 7117, -1, -1, -1, -1, 7117, -1, -1, -1, -1, 7117, -1, -1, -1, -1, 7117, -1, -1, -1, -1, 7117, -1, -1, -1, -1, 7117, -1, -1, -1, -1, 7117, -1]]. +NPC config [id=1205, name=null, config=1190, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7116, -1]]. +NPC config [id=1520, name=null, config=983, shift=0, childs=[-1, 1513, -1]]. +NPC config [id=1517, name=null, config=983, shift=0, childs=[-1, 1510, -1]]. +NPC config [id=1516, name=null, config=983, shift=0, childs=[-1, 1509, -1]]. +NPC config [id=1519, name=null, config=983, shift=0, childs=[-1, 1512, -1]]. +NPC config [id=1518, name=null, config=983, shift=0, childs=[-1, 1511, -1]]. +NPC config [id=1515, name=null, config=983, shift=0, childs=[-1, 1508, -1]]. +NPC config [id=1732, name=null, config=709, shift=31, childs=[-1, 5462, -1]]. +NPC config [id=1669, name=null, config=399, shift=-1, childs=[-1, -1, -1, -1, -1, -1, -1, -1, 1670, -1]]. +NPC config [id=1668, name=Dr Fenkenstrain, config=399, shift=-1, childs=[1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, -1]]. +NPC config [id=1671, name=Fenkenstrain's Monster, config=399, shift=-1, childs=[1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, -1]]. +NPC config [id=1667, name=Gardener Ghost, config=400, shift=31, childs=[1675, -1]]. +NPC config [id=1666, name=null, config=400, shift=31, childs=[-1, 1675, -1]]. +NPC config [id=1672, name=null, config=399, shift=-1, childs=[-1, -1, -1, -1, -1, -1, -1, -1, 1674, 1674, -1]]. +NPC config [id=1687, name=null, config=408, shift=28, childs=[-1, -1, -1, -1, 1688, 1688, 1688, 1688, 1688, -1]]. +NPC config [id=1907, name=Broken clay golem, config=437, shift=7, childs=[1908, 1908, 1909, 1909, 1910, -1]]. +NPC config [id=1899, name=null, config=435, shift=6, childs=[-1, 1901, -1]]. +NPC config [id=1900, name=null, config=435, shift=7, childs=[-1, 1901, -1]]. +NPC config [id=1903, name=Menaphite Thug, config=435, shift=11, childs=[1904, 1904, 1905, -1]]. +NPC config [id=1891, name=Villager, config=435, shift=11, childs=[1892, 1893, 1894, -1]]. +NPC config [id=1895, name=Villager, config=435, shift=11, childs=[1896, 1897, 1898, -1]]. +NPC config [id=1887, name=Villager, config=435, shift=11, childs=[1888, 1889, 1890, -1]]. +NPC config [id=1879, name=Bandit, config=435, shift=11, childs=[1880, 1880, 1881, -1]]. +NPC config [id=1877, name=null, config=435, shift=9, childs=[-1, 1878, -1]]. +NPC config [id=1876, name=null, config=435, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2548, -1]]. +NPC config [id=1869, name=Ali the Mayor, config=435, shift=18, childs=[1870, -1]]. +NPC config [id=1845, name=null, config=433, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1846, -1]]. +NPC config [id=1836, name=Dondakan the Dwarf, config=433, shift=0, childs=[1837, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1837, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1837, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1837, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1837, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1837, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1837, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1837, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1837, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1837, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1837, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1838, -1]]. +NPC config [id=1811, name=The Kendal, config=423, shift=25, childs=[1812, -1]]. +NPC config [id=2020, name=Vanstrom Klause, config=388, shift=25, childs=[1577, 1576, -1]]. +NPC config [id=2002, name=Wanderer, config=443, shift=26, childs=[2006, -1]]. +NPC config [id=2003, name=null, config=443, shift=26, childs=[-1, -1, 2006, -1]]. +NPC config [id=2004, name=null, config=443, shift=26, childs=[-1, -1, -1, 2006, -1]]. +NPC config [id=2011, name=null, config=445, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2012, -1]]. +NPC config [id=2013, name=null, config=446, shift=4, childs=[-1, 2014, -1]]. +NPC config [id=1987, name=null, config=445, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1988, 1988, 1988, 1988, 1988, 1988, 1988, -1]]. +NPC config [id=1985, name=High Priest, config=443, shift=14, childs=[1986, -1]]. +NPC config [id=1984, name=null, config=445, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1986, 1986, 1986, 1986, 1986, 1986, -1]]. +NPC config [id=1970, name=null, config=440, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1971, 1971, -1]]. +NPC config [id=1943, name=Ice block, config=442, shift=17, childs=[1944, 1948, -1]]. +NPC config [id=1949, name=null, config=442, shift=19, childs=[-1, -1, -1, -1, 1950, 1950, -1]]. +NPC config [id=1947, name=null, config=442, shift=19, childs=[-1, -1, -1, -1, 1948, 1948, -1]]. +NPC config [id=1945, name=Ice block, config=442, shift=18, childs=[1946, 1950, -1]]. +NPC config [id=1924, name=null, config=440, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1925, 1925, 1925, 1925, 1925, 1925, -1]]. +NPC config [id=1922, name=Eblis, config=440, shift=0, childs=[1923, 1923, 1923, 1923, 1923, 1923, 1923, 1923, 1923, 1923, 1923, -1]]. +NPC config [id=1932, name=Troll child, config=442, shift=19, childs=[1934, 1933, 1933, 1933, 1933, 1933, -1]]. +NPC config [id=2202, name=Drunken Dwarf, config=470, shift=0, childs=[2203, 2204, -1]]. +NPC config [id=2231, name=null, config=482, shift=23, childs=[-1, 2232, -1]]. +NPC config [id=2260, name=null, config=492, shift=-1, childs=[-1, 2261, 2261, 2261, 2261, -1]]. +NPC config [id=2257, name=Mage of Zamorak, config=492, shift=-1, childs=[2258, 2258, 2258, 2258, 2259, -1]]. +NPC config [id=2302, name=null, config=443, shift=20, childs=[-1, 2301, -1]]. +NPC config [id=2303, name=null, config=437, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2301, -1]]. +NPC config [id=2299, name=null, config=443, shift=20, childs=[-1, 2300, -1]]. +NPC config [id=2297, name=null, config=443, shift=20, childs=[-1, 2298, -1]]. +NPC config [id=2295, name=null, config=437, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2296, -1]]. +NPC config [id=2079, name=Sigmund, config=465, shift=0, childs=[2082, 2082, 2082, 2082, 2082, 2082, 2082, 2082, 2082, 2082, -1]]. +NPC config [id=2080, name=null, config=465, shift=21, childs=[-1, 2082, -1]]. +NPC config [id=2081, name=null, config=465, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2083, 2083, -1]]. +NPC config [id=2085, name=null, config=465, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, 2086, 2086, 2086, -1]]. +NPC config [id=2142, name=Riki the sculptor's model, config=482, shift=11, childs=[2143, 2144, 2145, 2147, 2146, 2148, 2149, 2150, -1]]. +NPC config [id=2125, name=Trader, config=482, shift=25, childs=[2126, -1]]. +NPC config [id=2123, name=Trader, config=482, shift=25, childs=[2124, -1]]. +NPC config [id=2435, name=Jarvald, config=520, shift=13, childs=[2436, 2437, -1]]. +NPC config [id=2488, name=null, config=320, shift=-1, childs=[-1, -1, -1, -1, -1, -1, 1167, -1]]. +NPC config [id=2483, name=Tiadeche, config=320, shift=-1, childs=[1163, 1163, 1163, 1163, 1163, 1163, -1]]. +NPC config [id=2484, name=null, config=320, shift=-1, childs=[-1, -1, -1, -1, -1, -1, 1164, -1]]. +NPC config [id=2485, name=Tinsay, config=320, shift=-1, childs=[1165, 1165, 1165, 1165, 1165, 1165, -1]]. +NPC config [id=2486, name=null, config=320, shift=-1, childs=[-1, -1, -1, -1, -1, -1, 1166, -1]]. +NPC config [id=2487, name=Tamayu, config=320, shift=-1, childs=[1167, 1167, 1167, 1167, 1167, 1167, -1]]. +NPC config [id=2510, name=null, config=534, shift=6, childs=[-1, 2511, 2512, 2512, 2512, 2512, 2512, 2512, -1]]. +NPC config [id=2507, name=null, config=534, shift=3, childs=[-1, 2508, 2509, 2509, 2509, 2509, 2509, 2509, -1]]. +NPC config [id=2504, name=null, config=534, shift=0, childs=[-1, 2505, 2506, 2506, 2506, 2506, 2506, 2506, -1]]. +NPC config [id=2525, name=null, config=534, shift=21, childs=[-1, 2526, 2527, 2527, 2527, 2527, 2527, 2527, -1]]. +NPC config [id=2522, name=null, config=534, shift=18, childs=[-1, 2523, 2524, 2524, 2524, 2524, 2524, 2524, -1]]. +NPC config [id=2519, name=null, config=534, shift=15, childs=[-1, 2520, 2521, 2521, 2521, 2521, 2521, 2521, -1]]. +NPC config [id=2516, name=null, config=534, shift=12, childs=[-1, 2517, 2518, 2518, 2518, 2518, 2518, 2518, -1]]. +NPC config [id=2513, name=null, config=534, shift=9, childs=[-1, 2514, 2515, 2515, 2515, 2515, 2515, 2515, -1]]. +NPC config [id=2528, name=null, config=534, shift=24, childs=[-1, 2529, 2530, 2530, 2530, 2530, 2530, 2530, -1]]. +NPC config [id=2531, name=null, config=534, shift=27, childs=[-1, 2532, 2533, 2533, 2533, 2533, 2533, 2533, -1]]. +NPC config [id=2375, name=null, config=518, shift=0, childs=[-1, 2376, -1]]. +NPC config [id=2370, name=null, config=518, shift=8, childs=[-1, -1, -1, -1, -1, -1, -1, 2371, 2371, 2371, 2371, 2371, 2371, 2371, 2371, 2371, 2371, 2371, -1]]. +NPC config [id=2382, name=null, config=440, shift=21, childs=[-1, 2397, -1]]. +NPC config [id=2383, name=null, config=440, shift=21, childs=[-1, 2397, -1]]. +NPC config [id=2381, name=null, config=440, shift=21, childs=[-1, 2399, -1]]. +NPC config [id=2391, name=null, config=440, shift=21, childs=[-1, 2401, -1]]. +NPC config [id=2390, name=null, config=440, shift=21, childs=[-1, 2400, -1]]. +NPC config [id=2389, name=null, config=440, shift=21, childs=[-1, 2400, -1]]. +NPC config [id=2388, name=null, config=440, shift=21, childs=[-1, 2400, -1]]. +NPC config [id=2387, name=null, config=440, shift=21, childs=[-1, 2398, -1]]. +NPC config [id=2386, name=null, config=440, shift=21, childs=[-1, 2398, -1]]. +NPC config [id=2385, name=null, config=440, shift=21, childs=[-1, 2398, -1]]. +NPC config [id=2384, name=null, config=440, shift=21, childs=[-1, 2397, -1]]. +NPC config [id=2396, name=null, config=440, shift=21, childs=[-1, 2402, -1]]. +NPC config [id=2395, name=null, config=440, shift=21, childs=[-1, 2402, -1]]. +NPC config [id=2394, name=null, config=440, shift=21, childs=[-1, 2402, -1]]. +NPC config [id=2393, name=null, config=440, shift=21, childs=[-1, 2401, -1]]. +NPC config [id=2392, name=null, config=440, shift=21, childs=[-1, 2401, -1]]. +NPC config [id=2404, name=Red Axe Director, config=482, shift=26, childs=[2107, -1]]. +NPC config [id=2405, name=Red Axe Cat, config=482, shift=26, childs=[2108, -1]]. +NPC config [id=2406, name=Gnome emissary, config=482, shift=26, childs=[2137, -1]]. +NPC config [id=2407, name=Gnome traveller, config=482, shift=26, childs=[2138, -1]]. +NPC config [id=2403, name=Red Axe Secretary, config=482, shift=26, childs=[2099, -1]]. +NPC config [id=2408, name=Gnome traveller, config=482, shift=26, childs=[2139, -1]]. +NPC config [id=2813, name=Camel, config=599, shift=31, childs=[80, 2814, -1]]. +NPC config [id=2795, name=Skippy, config=597, shift=0, childs=[2796, 2797, 2798, 2799, -1]]. +NPC config [id=2788, name=null, config=594, shift=25, childs=[-1, 2789, -1]]. +NPC config [id=2768, name=null, config=572, shift=10, childs=[-1, 2747, -1]]. +NPC config [id=2769, name=null, config=572, shift=12, childs=[-1, 2747, -1]]. +NPC config [id=2770, name=null, config=572, shift=14, childs=[-1, 2747, -1]]. +NPC config [id=2771, name=null, config=572, shift=16, childs=[-1, 2747, -1]]. +NPC config [id=2772, name=null, config=572, shift=18, childs=[-1, 2747, -1]]. +NPC config [id=2773, name=null, config=572, shift=20, childs=[-1, 2747, -1]]. +NPC config [id=2774, name=null, config=572, shift=22, childs=[-1, 2747, -1]]. +NPC config [id=2775, name=null, config=571, shift=22, childs=[-1, 2776, -1]]. +NPC config [id=2761, name=null, config=571, shift=28, childs=[-1, 2747, -1]]. +NPC config [id=2760, name=null, config=571, shift=26, childs=[-1, 2747, -1]]. +NPC config [id=2763, name=null, config=572, shift=0, childs=[-1, 2747, -1]]. +NPC config [id=2762, name=null, config=571, shift=30, childs=[-1, 2747, -1]]. +NPC config [id=2765, name=null, config=572, shift=4, childs=[-1, 2747, -1]]. +NPC config [id=2764, name=null, config=572, shift=2, childs=[-1, 2747, -1]]. +NPC config [id=2767, name=null, config=572, shift=8, childs=[-1, 2747, -1]]. +NPC config [id=2766, name=null, config=572, shift=6, childs=[-1, 2747, -1]]. +NPC config [id=2757, name=null, config=571, shift=20, childs=[-1, 2747, -1]]. +NPC config [id=2756, name=null, config=571, shift=18, childs=[-1, 2747, -1]]. +NPC config [id=2759, name=null, config=571, shift=24, childs=[-1, 2747, -1]]. +NPC config [id=2758, name=null, config=571, shift=22, childs=[-1, 2747, -1]]. +NPC config [id=2585, name=Trolley, config=553, shift=11, childs=[2584, 2582, 2583, -1]]. +NPC config [id=2652, name=null, config=568, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2653, -1, -1, -1, -1, 2653, -1, -1, -1, -1, 2653, -1]]. +NPC config [id=2654, name=Unferth, config=568, shift=13, childs=[2655, 2656, 2657, 2658, 2659, 2658, 2657, 2656, 2655, -1]]. +NPC config [id=2977, name=Rat, config=609, shift=10, childs=[2980, -1]]. +NPC config [id=2976, name=Rat, config=609, shift=9, childs=[2980, -1]]. +NPC config [id=2979, name=Rat, config=609, shift=12, childs=[2980, -1]]. +NPC config [id=2978, name=Rat, config=609, shift=11, childs=[2980, -1]]. +NPC config [id=2974, name=Rat, config=609, shift=7, childs=[2980, -1]]. +NPC config [id=2975, name=Rat, config=609, shift=8, childs=[2980, -1]]. +NPC config [id=3049, name=Target, config=616, shift=16, childs=[3047, 3048, -1]]. +NPC config [id=2818, name=null, config=599, shift=31, childs=[-1, 2822, -1]]. +NPC config [id=2819, name=null, config=599, shift=31, childs=[-1, 2823, -1]]. +NPC config [id=2816, name=null, config=599, shift=31, childs=[-1, 2820, -1]]. +NPC config [id=2817, name=null, config=599, shift=31, childs=[-1, 2821, -1]]. +NPC config [id=2920, name=null, config=602, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2921, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2921, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2921, -1]]. +NPC config [id=2922, name=null, config=602, shift=26, childs=[-1, 2910, -1]]. +NPC config [id=2923, name=null, config=602, shift=26, childs=[-1, -1, 2910, -1]]. +NPC config [id=2924, name=null, config=602, shift=28, childs=[-1, -1, 2902, -1]]. +NPC config [id=2925, name=null, config=602, shift=30, childs=[-1, -1, 2899, -1]]. +NPC config [id=2926, name=null, config=437, shift=7, childs=[-1, -1, -1, -1, -1, 1910, -1]]. +NPC config [id=2929, name=null, config=602, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2915, -1]]. +NPC config [id=2930, name=null, config=602, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2931, -1]]. +NPC config [id=2933, name=Melina, config=604, shift=13, childs=[2935, -1]]. +NPC config [id=2936, name=Droalak, config=604, shift=14, childs=[2938, -1]]. +NPC config [id=2898, name=null, config=602, shift=30, childs=[-1, 2899, -1]]. +NPC config [id=2897, name=Father Reen, config=602, shift=0, childs=[2899, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2899, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2899, -1]]. +NPC config [id=2901, name=null, config=602, shift=28, childs=[-1, 2902, -1]]. +NPC config [id=2908, name=null, config=602, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2910, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2910, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2910, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2910, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2910, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2910, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2910, -1]]. +NPC config [id=3289, name=null, config=32, shift=-1, childs=[-1, -1, -1, 287, -1]]. +NPC config [id=3290, name=Chicken, config=32, shift=-1, childs=[288, 288, 288, -1]]. +NPC config [id=3318, name=null, config=671, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3321, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3321, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3321, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3321, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3321, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3321, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3321, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3321, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3321, -1]]. +NPC config [id=3316, name=null, config=671, shift=24, childs=[-1, 3305, 3305, -1]]. +NPC config [id=3317, name=null, config=671, shift=24, childs=[-1, 3306, 3306, -1]]. +NPC config [id=3314, name=Fairy Queen, config=671, shift=22, childs=[653, -1]]. +NPC config [id=3315, name=null, config=671, shift=24, childs=[-1, 3304, 4433, -1]]. +NPC config [id=3323, name=Juliet, config=673, shift=0, childs=[637, -1, 637, -1]]. +NPC config [id=3213, name=Edmond, config=667, shift=0, childs=[714, -1]]. +NPC config [id=3214, name=null, config=667, shift=0, childs=[-1, 714, -1]]. +NPC config [id=3152, name=Boneguard, config=643, shift=6, childs=[3140, 3141, 3142, -1]]. +NPC config [id=3144, name=null, config=643, shift=0, childs=[-1, 3147, -1]]. +NPC config [id=3145, name=null, config=643, shift=0, childs=[-1, -1, 3147, -1]]. +NPC config [id=3146, name=null, config=643, shift=0, childs=[-1, -1, -1, 3147, -1]]. +NPC config [id=3143, name=Lazim, config=643, shift=0, childs=[3147, -1]]. +NPC config [id=3136, name=Enakhra, config=643, shift=4, childs=[3137, 3138, -1]]. +NPC config [id=3139, name=Boneguard, config=643, shift=6, childs=[3140, 3141, 3142, -1]]. +NPC config [id=3074, name=Monk, config=622, shift=27, childs=[3075, -1]]. +NPC config [id=3076, name=null, config=622, shift=27, childs=[-1, 3077, -1]]. +NPC config [id=3128, name=Boneguard, config=641, shift=0, childs=[3129, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3129, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3129, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3129, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3129, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3130, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3130, -1, -1, -1, -1, 3130, -1, -1, -1, -1, 3130, -1]]. +NPC config [id=3134, name=Furnace grate, config=642, shift=2, childs=[3135, -1]]. +NPC config [id=3132, name=Crust of ice, config=642, shift=1, childs=[3133, -1]]. +NPC config [id=3110, name=Sandy, config=636, shift=0, childs=[3112, -1]]. +NPC config [id=3111, name=null, config=636, shift=0, childs=[-1, 3113, -1]]. +NPC config [id=3567, name=null, config=704, shift=19, childs=[-1, 3569, -1]]. +NPC config [id=3566, name=Cornelius, config=704, shift=19, childs=[3568, -1]]. +NPC config [id=3462, name=null, config=679, shift=5, childs=[-1, 3463, 3464, -1]]. +NPC config [id=3465, name=null, config=684, shift=11, childs=[-1, 3466, -1]]. +NPC config [id=3470, name=null, config=684, shift=17, childs=[-1, 3471, -1]]. +NPC config [id=3469, name=null, config=684, shift=17, childs=[-1, 3472, -1]]. +NPC config [id=3479, name=null, config=679, shift=7, childs=[-1, 3480, 3478, -1]]. +NPC config [id=3510, name=null, config=704, shift=23, childs=[-1, 3511, 3539, -1]]. +NPC config [id=3512, name=null, config=704, shift=23, childs=[-1, 3514, -1]]. +NPC config [id=3513, name=null, config=704, shift=23, childs=[-1, 3515, -1]]. +NPC config [id=3516, name=null, config=704, shift=23, childs=[-1, 3517, -1]]. +NPC config [id=3404, name=null, config=680, shift=28, childs=[-1, -1, 3405, -1]]. +NPC config [id=3401, name=An old Dwarf, config=680, shift=28, childs=[3402, 3403, -1]]. +NPC config [id=3399, name=null, config=678, shift=0, childs=[-1, -1, -1, 3400, 3400, -1]]. +NPC config [id=3417, name=null, config=679, shift=2, childs=[-1, 3418, 3416, -1]]. +NPC config [id=3450, name=null, config=679, shift=3, childs=[-1, 3451, 3449, -1]]. +NPC config [id=3373, name=null, config=679, shift=6, childs=[-1, 3374, 3372, -1]]. +NPC config [id=3384, name=null, config=678, shift=0, childs=[-1, -1, -1, -1, 3385, -1]]. +NPC config [id=3379, name=Evil Dave, config=679, shift=4, childs=[3380, 3380, 3380, 3380, 3380, -1]]. +NPC config [id=3383, name=null, config=678, shift=0, childs=[-1, -1, -1, 3385, 3385, -1]]. +NPC config [id=3828, name=Devin Mendelberg, config=723, shift=0, childs=[3825, -1, -1, -1, -1, 3825, -1, -1, -1, -1, 3825, -1, -1, -1, -1, 3825, -1, -1, -1, -1, 3825, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3825, -1]]. +NPC config [id=3829, name=Kathy Corkat, config=723, shift=0, childs=[3830, -1, -1, -1, -1, 3831, -1, -1, -1, -1, 3831, -1, -1, -1, -1, 3831, -1, -1, -1, -1, 3831, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3831, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3831, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3831, -1, -1, -1, -1, 3831, -1, -1, -1, -1, 3831, -1, -1, -1, -1, 3831, -1, -1, -1, -1, 3831, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3831, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3831, -1, -1, -1, -1, 3831, -1, -1, -1, -1, 3831, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3831, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3831, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3831, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3831, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3831, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3831, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3831, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3831, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3831, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3831, -1]]. +NPC config [id=3834, name=null, config=723, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3821, -1]]. +NPC config [id=3832, name=Herman Caranos, config=723, shift=0, childs=[3822, -1, -1, -1, -1, 3822, -1, -1, -1, -1, 3822, -1, -1, -1, -1, 3822, -1, -1, -1, -1, 3822, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2567, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2567, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2567, -1, -1, -1, -1, 2567, -1]]. +NPC config [id=3833, name=null, config=723, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2567, -1, -1, -1, -1, 2567, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2567, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2567, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2567, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2567, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2567, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2567, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2567, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2567, -1]]. +NPC config [id=3820, name=Wise Old Man, config=723, shift=0, childs=[2253, -1, -1, -1, -1, 2253, -1, -1, -1, -1, 2253, -1, -1, -1, -1, 2253, -1, -1, -1, -1, 2253, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2253, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2253, -1]]. +NPC config [id=3778, name=null, config=1049, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 251, -1, -1, -1, -1, 3779, -1]]. +NPC config [id=3780, name=null, config=1049, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 249, -1, -1, -1, -1, 249, -1, -1, -1, -1, 249, -1]]. +NPC config [id=3638, name=Launa, config=710, shift=0, childs=[3639, -1]]. +NPC config [id=3633, name=null, config=700, shift=0, childs=[-1, 3634, -1]]. +NPC config [id=3631, name=null, config=700, shift=0, childs=[-1, 3632, -1]]. +NPC config [id=3629, name=null, config=700, shift=0, childs=[-1, 3630, -1]]. +NPC config [id=3627, name=null, config=700, shift=0, childs=[-1, 3628, -1]]. +NPC config [id=3625, name=null, config=700, shift=0, childs=[-1, 3626, -1]]. +NPC config [id=3623, name=null, config=700, shift=0, childs=[-1, 3624, -1]]. +NPC config [id=4453, name=null, config=810, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4442, -1]]. +NPC config [id=4454, name=null, config=810, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4437, -1]]. +NPC config [id=4436, name=null, config=810, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4437, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4437, -1]]. +NPC config [id=4435, name=null, config=810, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4442, -1, -1, -1, -1, 4442, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4442, -1, -1, -1, -1, 4442, -1, -1, -1, -1, 4442, -1, 4442, 4442, -1, 4442, -1, -1, -1, -1, 4442, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4442, -1]]. +NPC config [id=4432, name=null, config=810, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4434, -1, -1, -1, -1, 4434, -1, -1, -1, -1, 4434, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4434, -1, -1, -1, -1, 4434, -1, -1, -1, -1, 4434, -1, 4434, 4434, -1, 4434, -1, -1, -1, -1, 4434, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4434, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4434, -1]]. +NPC config [id=4423, name=Fairy, config=810, shift=0, childs=[57, -1, -1, -1, -1, -1, -1, -1, -1, -1, 57, -1, -1, -1, -1, -1, -1, -1, -1, -1, 57, -1, -1, -1, -1, -1, -1, -1, -1, -1, 57, -1]]. +NPC config [id=4422, name=Fairy, config=810, shift=0, childs=[57, -1, -1, -1, -1, -1, -1, -1, -1, -1, 57, -1]]. +NPC config [id=4431, name=Fairy Nuff, config=810, shift=14, childs=[4434, -1]]. +NPC config [id=4430, name=null, config=810, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4445, -1, -1, -1, -1, 4445, -1, -1, -1, -1, 4445, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4445, -1, -1, -1, -1, 4445, -1, -1, -1, -1, 4445, -1, 4445, 4445, -1, 4445, -1, -1, -1, -1, 4445, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4445, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4445, -1]]. +NPC config [id=4429, name=null, config=810, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4446, -1, -1, -1, -1, 4446, -1, -1, -1, -1, 4446, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4446, -1, -1, -1, -1, 4446, -1, -1, -1, -1, 4446, -1, 4446, 4446, -1, 4446, -1, -1, -1, -1, 4446, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4446, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4446, -1]]. +NPC config [id=4428, name=null, config=810, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4444, -1, -1, -1, -1, 4444, -1, -1, -1, -1, 4444, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4444, -1, -1, -1, -1, 4444, -1, -1, -1, -1, 4444, -1, 4444, 4444, -1, 4444, -1, -1, -1, -1, 4444, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4444, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4444, -1]]. +NPC config [id=4427, name=null, config=810, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4443, -1, -1, -1, -1, 4443, -1, -1, -1, -1, 4443, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4443, -1, -1, -1, -1, 4443, -1, -1, -1, -1, 4443, -1, 4443, 4443, -1, 4443, -1, -1, -1, -1, 4443, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4443, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4443, -1]]. +NPC config [id=4426, name=null, config=810, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 57, -1, -1, -1, -1, 57, -1, -1, -1, -1, 57, -1, -1, -1, -1, -1, -1, -1, -1, -1, 57, -1, -1, -1, -1, 57, -1, -1, -1, -1, 57, -1, 57, 57, -1, 57, -1, -1, -1, -1, 57, -1, -1, -1, -1, -1, -1, -1, -1, -1, 57, -1, -1, -1, -1, -1, -1, -1, -1, -1, 57, -1]]. +NPC config [id=4425, name=null, config=810, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4458, -1, -1, -1, -1, 4458, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4458, -1, -1, -1, -1, 4458, -1, -1, -1, -1, 4458, -1, 4458, 4458, -1, 4458, -1, -1, -1, -1, 4458, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4458, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4458, -1]]. +NPC config [id=4424, name=null, config=810, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4456, -1, -1, -1, -1, 4456, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4456, -1, -1, -1, -1, 4456, -1, -1, -1, -1, 4456, -1, 4456, 4456, -1, 4456, -1, -1, -1, -1, 4456, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4456, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4456, -1]]. +NPC config [id=4538, name=Cabin boy, config=823, shift=0, childs=[4539, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4539, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4539, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4539, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4539, -1, -1, -1, -1, 4539, -1, -1, -1, -1, 4539, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4539, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4539, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4539, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4539, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4539, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4539, -1, 4539, -1, 4539, -1, 4539, -1, 4539, -1, 4539, -1, -1, -1, -1, 4539, -1]]. +NPC config [id=4495, name=Grubfoot, config=62, shift=0, childs=[4496, 4496, 4496, 4496, 4497, 4498, 4496, -1]]. +NPC config [id=4256, name=null, config=61, shift=10, childs=[-1, 2348, -1]]. +NPC config [id=4236, name=Rick, config=738, shift=16, childs=[4235, -1, 4235, 4235, 4235, 4235, 4235, 4235, 4235, -1]]. +NPC config [id=4238, name=Maid, config=738, shift=16, childs=[4237, 4237, 4237, -1, 4237, 4237, 4237, 4237, 4237, -1]]. +NPC config [id=4253, name=null, config=61, shift=1, childs=[-1, 2345, -1]]. +NPC config [id=4255, name=null, config=61, shift=7, childs=[-1, 2347, -1]]. +NPC config [id=4254, name=null, config=61, shift=4, childs=[-1, 2346, -1]]. +NPC config [id=4240, name=Cook, config=738, shift=16, childs=[4239, 4239, 4239, 4239, 4239, -1, 4239, 4239, 4239, -1]]. +NPC config [id=4242, name=Butler, config=738, shift=16, childs=[4241, 4241, 4241, 4241, 4241, 4241, -1, 4241, 4241, -1]]. +NPC config [id=4244, name=Demon butler, config=738, shift=16, childs=[4243, 4243, 4243, 4243, 4243, 4243, 4243, 4243, -1]]. +NPC config [id=4321, name=null, config=794, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4320, -1]]. +NPC config [id=4338, name=null, config=794, shift=16, childs=[-1, 4337, -1]]. +NPC config [id=4317, name=null, config=794, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, 4318, 4318, 4318, -1]]. +NPC config [id=4319, name=null, config=794, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, 4320, 4320, 4320, -1]]. +NPC config [id=4313, name=null, config=794, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4314, -1]]. +NPC config [id=4315, name=null, config=794, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, 4316, 4316, 4316, -1]]. +NPC config [id=4882, name=null, config=874, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, 4888, 4888, 4888, 4888, 4888, 4888, -1]]. +NPC config [id=4880, name=null, config=874, shift=0, childs=[-1, 4884, 4884, 4884, 4884, 4884, 4884, 4884, 4884, 4884, 4884, 4884, 4884, 4884, 4884, -1]]. +NPC config [id=4881, name=null, config=874, shift=0, childs=[-1, -1, -1, -1, -1, 4886, 4886, 4886, 4886, 4886, 4886, 4886, 4886, 4886, 4886, -1]]. +NPC config [id=4891, name=null, config=874, shift=11, childs=[-1, 4892, -1]]. +NPC config [id=4871, name=Holgart, config=874, shift=11, childs=[699, 4896, -1]]. +NPC config [id=4869, name=null, config=159, shift=-1, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 701, 701, -1]]. +NPC config [id=4865, name=null, config=159, shift=-1, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4864, 4864, -1]]. +NPC config [id=4912, name=Jig cart, config=896, shift=9, childs=[4913, 4914, 4915, 4916, 4917, 4918, -1]]. +NPC config [id=4950, name=null, config=905, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4947, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4947, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4947, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4947, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4947, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4947, -1]]. +NPC config [id=4951, name=null, config=905, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4948, -1]]. +NPC config [id=4954, name=null, config=905, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4948, -1]]. +NPC config [id=4955, name=null, config=905, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4947, -1]]. +NPC config [id=4952, name=null, config=905, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4948, -1]]. +NPC config [id=4953, name=null, config=905, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4947, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4947, -1]]. +NPC config [id=4956, name=null, config=905, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4947, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4947, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4947, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4947, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4947, -1]]. +NPC config [id=4984, name=Ana, config=907, shift=7, childs=[822, -1]]. +NPC config [id=4985, name=Male slave, config=907, shift=4, childs=[825, 826, -1]]. +NPC config [id=4986, name=Irena, config=907, shift=10, childs=[835, -1]]. +NPC config [id=4987, name=null, config=907, shift=10, childs=[-1, 4988, -1]]. +NPC config [id=4961, name=null, config=905, shift=27, childs=[-1, 4962, -1]]. +NPC config [id=4966, name=null, config=435, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4967, -1]]. +NPC config [id=4970, name=null, config=905, shift=20, childs=[-1, 4969, -1]]. +NPC config [id=5022, name=null, config=942, shift=21, childs=[-1, 5025, -1]]. +NPC config [id=5021, name=null, config=942, shift=21, childs=[-1, 5024, -1]]. +NPC config [id=5020, name=null, config=942, shift=21, childs=[-1, 5023, -1]]. +NPC config [id=5016, name=Gublinch, config=941, shift=28, childs=[5017, 5018, 5019, -1]]. +NPC config [id=5015, name=Gublinch, config=941, shift=26, childs=[5017, 5018, 5019, -1]]. +NPC config [id=5014, name=Gublinch, config=941, shift=24, childs=[5017, 5018, 5019, -1]]. +NPC config [id=5013, name=Gublinch, config=941, shift=22, childs=[5017, 5018, 5019, -1]]. +NPC config [id=5012, name=Gublinch, config=941, shift=20, childs=[5017, 5018, 5019, -1]]. +NPC config [id=5011, name=Gublinch, config=941, shift=18, childs=[5017, 5018, 5019, -1]]. +NPC config [id=5010, name=Gublinch, config=941, shift=16, childs=[5017, 5018, 5019, -1]]. +NPC config [id=5009, name=Gublinch, config=941, shift=14, childs=[5017, 5018, 5019, -1]]. +NPC config [id=5008, name=Gublinch, config=941, shift=12, childs=[5017, 5018, 5019, -1]]. +NPC config [id=5006, name=Gublinch, config=941, shift=8, childs=[5017, 5018, 5019, -1]]. +NPC config [id=5007, name=Gublinch, config=941, shift=10, childs=[5017, 5018, 5019, -1]]. +NPC config [id=5004, name=Gublinch, config=941, shift=4, childs=[5017, 5018, 5019, -1]]. +NPC config [id=5005, name=Gublinch, config=941, shift=6, childs=[5017, 5018, 5019, -1]]. +NPC config [id=5003, name=Gublinch, config=941, shift=2, childs=[5017, 5018, 5019, -1]]. +NPC config [id=5078, name=null, config=925, shift=31, childs=[-1, 1, -1]]. +NPC config [id=5077, name=null, config=925, shift=31, childs=[-1, 1, -1]]. +NPC config [id=5066, name=null, config=912, shift=15, childs=[-1, 5053, -1]]. +NPC config [id=5064, name=null, config=912, shift=13, childs=[-1, 5056, -1]]. +NPC config [id=5065, name=null, config=912, shift=14, childs=[-1, 5054, -1]]. +NPC config [id=5070, name=null, config=925, shift=31, childs=[-1, 1, -1]]. +NPC config [id=5071, name=null, config=925, shift=31, childs=[-1, 1, -1]]. +NPC config [id=5062, name=null, config=912, shift=10, childs=[-1, 5049, 5057, -1]]. +NPC config [id=5063, name=null, config=912, shift=12, childs=[-1, 5055, -1]]. +NPC config [id=5119, name=null, config=925, shift=31, childs=[-1, 1, -1]]. +NPC config [id=5118, name=null, config=925, shift=31, childs=[-1, 1, -1]]. +NPC config [id=5107, name=null, config=925, shift=31, childs=[-1, 1, -1]]. +NPC config [id=5106, name=null, config=925, shift=31, childs=[-1, 1, -1]]. +NPC config [id=5108, name=null, config=925, shift=31, childs=[-1, 1, -1]]. +NPC config [id=5101, name=null, config=925, shift=31, childs=[-1, 1, -1]]. +NPC config [id=5102, name=null, config=925, shift=31, childs=[-1, 1, -1]]. +NPC config [id=5090, name=null, config=925, shift=31, childs=[-1, 1, -1]]. +NPC config [id=5091, name=null, config=925, shift=31, childs=[-1, 1, -1]]. +NPC config [id=4613, name=Cute creature, config=844, shift=13, childs=[4614, 4615, 1957, -1]]. +NPC config [id=4622, name=Cute creature, config=844, shift=19, childs=[4623, 4624, 1957, -1]]. +NPC config [id=4616, name=Cute creature, config=844, shift=15, childs=[4617, 4618, 1957, -1]]. +NPC config [id=4619, name=Cute creature, config=844, shift=17, childs=[4620, 4621, 1957, -1]]. +NPC config [id=4628, name=Cute creature, config=844, shift=23, childs=[4629, 4630, 1957, -1]]. +NPC config [id=4625, name=Cute creature, config=844, shift=21, childs=[4626, 4627, 1957, -1]]. +NPC config [id=4711, name=null, config=870, shift=12, childs=[-1, 4713, -1]]. +NPC config [id=4714, name=null, config=870, shift=15, childs=[-1, 4715, -1]]. +NPC config [id=4712, name=null, config=870, shift=12, childs=[-1, -1, 4713, -1]]. +NPC config [id=4859, name=Witchaven villager, config=874, shift=0, childs=[4887, 4887, 4887, 4887, 4887, 4887, 4887, 4887, 4887, -1]]. +NPC config [id=4858, name=Witchaven villager, config=874, shift=0, childs=[4885, 4885, 4885, 4885, 4885, -1]]. +NPC config [id=4857, name=Witchaven villager, config=874, shift=0, childs=[4883, -1]]. +NPC config [id=4860, name=Jeb, config=874, shift=0, childs=[4895, 4895, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896, -1]]. +NPC config [id=4855, name=Brother Maledict, config=874, shift=0, childs=[4878, 4878, 4878, 4878, 4878, 4878, 4878, 4878, 4879, 4879, 4879, 4879, 4879, 4879, -1]]. +NPC config [id=4854, name=Mayor Hobb, config=874, shift=0, childs=[4874, 4874, 4874, 4874, 4874, 4874, 4874, 4874, 4874, 4874, 4874, 4874, 4875, 4875, -1]]. +NPC config [id=4853, name=Col. O'Niall, config=874, shift=0, childs=[4872, 4872, 4872, 4872, 4872, 4872, 4872, 4872, 4872, 4873, 4873, 4873, 4873, -1]]. +NPC config [id=5443, name=null, config=968, shift=14, childs=[-1, 5444, -1]]. +NPC config [id=5440, name=KGP Agent, config=968, shift=14, childs=[5441, 5441, -1]]. +NPC config [id=5439, name=null, config=968, shift=14, childs=[-1, 5441, -1]]. +NPC config [id=5427, name=Penguin, config=968, shift=8, childs=[5428, 5428, 5428, -1]]. +NPC config [id=5423, name=null, config=968, shift=13, childs=[-1, 5424, -1]]. +NPC config [id=5606, name=null, config=980, shift=-1, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1670, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1670, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1670, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1670, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1670, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1670, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1670, -1]]. +NPC config [id=5600, name=null, config=978, shift=9, childs=[-1, 5581, -1]]. +NPC config [id=5601, name='Transmute' The Alchemist, config=977, shift=0, childs=[5585, -1, 5585, 5585, 5585, -1, 5585, -1, 5585, -1, -1, 5585, 5585, -1, 5585, -1, 5585, -1]]. +NPC config [id=5602, name='Currency' The Alchemist, config=977, shift=0, childs=[5587, -1, 5587, 5587, 5587, -1, 5587, -1, 5587, -1, -1, 5587, 5587, -1, 5587, -1, 5587, -1]]. +NPC config [id=5599, name=null, config=977, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5583, -1, 5583, -1, 5583, -1]]. +NPC config [id=5598, name=Effigy, config=977, shift=0, childs=[5578, -1, 5578, 5578, 5578, -1, 5578, -1, 5578, -1, -1, 5578, 5578, -1, 5578, -1, 5578, -1]]. +NPC config [id=5574, name=null, config=440, shift=21, childs=[-1, 5567, -1]]. +NPC config [id=5575, name=null, config=440, shift=21, childs=[-1, 5568, -1]]. +NPC config [id=5573, name=null, config=440, shift=21, childs=[-1, 5566, -1]]. +NPC config [id=5576, name=null, config=440, shift=21, childs=[-1, 5569, -1]]. +NPC config [id=5577, name=null, config=440, shift=21, childs=[-1, 5570, -1]]. +NPC config [id=5530, name=Mawnis Burowgar, config=970, shift=21, childs=[5503, 5504, -1]]. +NPC config [id=5199, name=null, config=32, shift=-1, childs=[-1, -1, -1, 5198, -1]]. +NPC config [id=5192, name=Ogre shaman, config=936, shift=27, childs=[5193, 5194, -1]]. +NPC config [id=5189, name=Ogre shaman, config=936, shift=26, childs=[5190, 5191, -1]]. +NPC config [id=5186, name=Ogre shaman, config=936, shift=25, childs=[5187, 5188, -1]]. +NPC config [id=5206, name=Alice's husband, config=939, shift=0, childs=[5202, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5202, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5202, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5202, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5202, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5202, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5202, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5202, -1, -1, 5202, -1, -1, 5202, -1, -1, -1, 5203, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5203, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5203, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5203, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5203, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5203, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5203, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5203, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5203, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5203, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5203, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5203, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5203, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5203, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5203, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5203, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5203, -1]]. +NPC config [id=5201, name=null, config=32, shift=-1, childs=[-1, -1, -1, 5200, -1]]. +NPC config [id=5183, name=Ogre shaman, config=936, shift=24, childs=[5184, 5185, -1]]. +NPC config [id=5180, name=Ogre shaman, config=936, shift=23, childs=[5181, 5182, -1]]. +NPC config [id=5175, name=Ogre shaman, config=936, shift=22, childs=[5176, 5179, -1]]. +NPC config [id=5135, name=null, config=934, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5131, -1]]. +NPC config [id=5134, name=null, config=934, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5130, -1]]. +NPC config [id=5125, name=Nickolaus, config=934, shift=0, childs=[5128, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5128, -1, -1, -1, -1, 5128, -1, -1, -1, -1, 5128, -1, -1, -1, -1, 5128, -1]]. +NPC config [id=5124, name=null, config=934, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5127, -1, -1, -1, -1, 5128, -1, -1, -1, -1, 5129, -1]]. +NPC config [id=5136, name=null, config=934, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5132, -1]]. +NPC config [id=5139, name=null, config=934, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5081, -1]]. +NPC config [id=5282, name=Osman, config=964, shift=14, childs=[924, 924, 5284, -1]]. +NPC config [id=5283, name=null, config=964, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 924, -1, -1, -1, -1, -1, -1, -1, -1, -1, 924, -1]]. +NPC config [id=5280, name=Maisa, config=964, shift=19, childs=[5281, -1]]. +NPC config [id=5257, name=null, config=964, shift=9, childs=[-1, 5258, -1]]. +NPC config [id=5259, name=null, config=964, shift=9, childs=[-1, 5260, -1]]. +NPC config [id=5261, name=null, config=964, shift=8, childs=[-1, 5262, -1]]. +NPC config [id=5263, name=null, config=964, shift=8, childs=[-1, 5264, -1]]. +NPC config [id=5265, name=null, config=964, shift=8, childs=[-1, 5266, -1]]. +NPC config [id=5267, name=null, config=964, shift=8, childs=[-1, 5268, -1]]. +NPC config [id=5269, name=null, config=964, shift=8, childs=[-1, 5270, -1]]. +NPC config [id=5271, name=null, config=964, shift=8, childs=[-1, 5272, -1]]. +NPC config [id=5273, name=null, config=964, shift=8, childs=[-1, 5274, -1]]. +NPC config [id=5275, name=null, config=964, shift=8, childs=[-1, 5276, -1]]. +NPC config [id=6000, name=Rupert the Beard, config=1017, shift=11, childs=[5992, 6001, -1]]. +NPC config [id=5997, name=Grimgnash, config=1017, shift=20, childs=[5989, -1]]. +NPC config [id=5998, name=Rupert the Beard, config=1016, shift=31, childs=[5990, 5999, -1]]. +NPC config [id=5901, name=null, config=1003, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5898, -1, 5898, -1, 5898, -1, 5898, -1, 5898, -1, 5898, -1, 5898, -1]]. +NPC config [id=5900, name=null, config=1005, shift=8, childs=[-1, -1, -1, -1, 5896, 5897, 5895, -1]]. +NPC config [id=5899, name=null, config=1005, shift=8, childs=[-1, 5896, 5897, 5895, -1]]. +NPC config [id=5892, name=null, config=997, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, 5872, -1]]. +NPC config [id=5891, name=null, config=997, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, 5871, -1]]. +NPC config [id=5890, name=null, config=997, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, 5872, 5872, -1]]. +NPC config [id=5889, name=null, config=997, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, 5871, 5871, -1]]. +NPC config [id=5888, name=null, config=997, shift=23, childs=[-1, 5870, -1]]. +NPC config [id=6082, name=null, config=176, shift=-1, childs=[-1, -1, -1, -1, -1, -1, -1, 918, 918, 918, 918, -1]]. +NPC config [id=6083, name=null, config=176, shift=-1, childs=[-1, -1, -1, -1, -1, -1, -1, -1, 918, 918, 918, -1]]. +NPC config [id=6119, name=Observatory professor, config=112, shift=-1, childs=[488, 488, 488, 488, 488, 488, -1]]. +NPC config [id=6120, name=null, config=112, shift=-1, childs=[-1, -1, -1, -1, -1, -1, 488, 488, 488, -1]]. +NPC config [id=6077, name=null, config=907, shift=14, childs=[-1, 822, -1]]. +NPC config [id=6076, name=null, config=728, shift=3, childs=[-1, 1685, -1]]. +NPC config [id=6075, name=Gravingas, config=728, shift=3, childs=[1685, -1]]. +NPC config [id=5677, name=Brother Tranquility, config=982, shift=27, childs=[5618, -1]]. +NPC config [id=5676, name=Monk, config=982, shift=27, childs=[5622, -1]]. +NPC config [id=5675, name=Monk, config=982, shift=27, childs=[5621, -1]]. +NPC config [id=5674, name=Monk, config=982, shift=27, childs=[5620, -1]]. +NPC config [id=5673, name=Monk, config=982, shift=27, childs=[5619, -1]]. +NPC config [id=5672, name=Zombie monk, config=982, shift=27, childs=[5626, 5611, -1]]. +NPC config [id=5671, name=Zombie monk, config=982, shift=27, childs=[5625, 5610, -1]]. +NPC config [id=5670, name=Zombie monk, config=982, shift=27, childs=[5624, 5609, -1]]. +NPC config [id=5669, name=Zombie monk, config=982, shift=27, childs=[5623, 5608, -1]]. +NPC config [id=5668, name=Brother Tranquility, config=980, shift=-1, childs=[5616, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5616, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5616, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5616, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5616, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5616, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5616, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5616, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5616, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5616, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5617, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5617, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5617, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5617, -1]]. +NPC config [id=5667, name=Brother Tranquility, config=980, shift=-1, childs=[5616, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5616, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5616, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5616, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5616, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5616, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5616, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5616, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5616, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5616, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5617, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5617, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5617, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5617, -1]]. +NPC config [id=5830, name=null, config=987, shift=1, childs=[-1, 5825, -1]]. +NPC config [id=5831, name=null, config=987, shift=1, childs=[-1, 5826, -1]]. +NPC config [id=5832, name=Ambassador Alvijar, config=997, shift=0, childs=[5863, 5863, 5863, 5863, 5863, 5863, 5863, 5863, 5863, 5863, 5863, -1]]. +NPC config [id=5853, name=Surok Magis, config=1181, shift=11, childs=[5834, 5835, 7000, -1]]. +NPC config [id=5869, name=null, config=997, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5868, -1]]. +NPC config [id=5887, name=null, config=997, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5863, -1]]. +NPC config [id=5787, name=Oldak, config=1094, shift=0, childs=[6392, 6392, 6392, 6392, 6392, 6392, 6392, 6392, 6392, 6392, 6392, 6392, 6392, 6392, 6392, 6392, -1, -1, 6392, -1]]. +NPC config [id=5802, name=null, config=988, shift=8, childs=[-1, 3712, -1]]. +NPC config [id=6400, name=null, config=1094, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6392, 6392, -1]]. +NPC config [id=6505, name=null, config=440, shift=21, childs=[-1, 6504, -1]]. +NPC config [id=6480, name=null, config=1094, shift=5, childs=[-1, 6479, -1]]. +NPC config [id=6333, name=null, config=1064, shift=30, childs=[-1, 6311, 6312, -1]]. +NPC config [id=6310, name=Cute creature, config=844, shift=13, childs=[6311, 6312, 1957, -1]]. +NPC config [id=6398, name=null, config=1094, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6393, 6393, -1]]. +NPC config [id=6396, name=null, config=1094, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, 6393, 6393, -1]]. +NPC config [id=6394, name=null, config=1094, shift=6, childs=[-1, 6393, -1]]. +NPC config [id=6387, name=null, config=934, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6385, -1]]. +NPC config [id=6386, name=null, config=1077, shift=8, childs=[-1, 6375, -1]]. +NPC config [id=6194, name=Carol, config=1049, shift=0, childs=[816, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 816, -1]]. +NPC config [id=6195, name=David, config=1049, shift=0, childs=[817, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 817, -1]]. +NPC config [id=6192, name=Anna, config=1049, shift=0, childs=[814, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 814, -1]]. +NPC config [id=6193, name=Bob, config=1049, shift=0, childs=[815, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 815, -1]]. +NPC config [id=6199, name=null, config=1049, shift=0, childs=[-1, -1, -1, -1, -1, 6178, -1, -1, -1, -1, 6178, -1, -1, -1, -1, 6178, -1, -1, -1, -1, 6178, -1, -1, -1, -1, 6178, -1, -1, -1, -1, 6178, -1, -1, -1, -1, 6178, -1, -1, -1, -1, 6178, -1]]. +NPC config [id=6196, name=Elizabeth, config=1049, shift=0, childs=[818, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 818, -1]]. +NPC config [id=6197, name=Frank, config=1049, shift=0, childs=[819, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 819, -1]]. +NPC config [id=6202, name=Knight, config=1048, shift=4, childs=[6201, -1]]. +NPC config [id=6186, name=null, config=1051, shift=19, childs=[-1, 806, 807, 808, 809, 810, 811, -1]]. +NPC config [id=6191, name=Guard, config=1049, shift=0, childs=[812, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 812, -1]]. +NPC config [id=7055, name=Chargurr, config=1185, shift=31, childs=[7053, -1]]. +NPC config [id=7042, name=Diseased kebbit, config=1185, shift=15, childs=[7039, 7083, -1]]. +NPC config [id=7043, name=Diseased kebbit, config=1185, shift=16, childs=[7039, 7083, -1]]. +NPC config [id=7040, name=Diseased kebbit, config=1185, shift=13, childs=[7039, 7083, -1]]. +NPC config [id=7041, name=Diseased kebbit, config=1185, shift=14, childs=[7039, 7083, -1]]. +NPC config [id=7066, name=null, config=1185, shift=31, childs=[-1, 4651, -1]]. +NPC config [id=7065, name=null, config=1185, shift=31, childs=[-1, 4654, -1]]. +NPC config [id=7056, name=null, config=1185, shift=31, childs=[-1, 7054, -1]]. +NPC config [id=7101, name=Thump, config=1185, shift=31, childs=[7061, -1]]. +NPC config [id=7100, name=Massage table, config=1185, shift=31, childs=[7060, 7059, -1]]. +NPC config [id=7103, name=null, config=1185, shift=31, childs=[-1, 7064, -1]]. +NPC config [id=7102, name=null, config=1185, shift=31, childs=[-1, 7063, -1]]. +NPC config [id=7097, name=null, config=1185, shift=11, childs=[-1, 7029, -1]]. +NPC config [id=7096, name=null, config=1185, shift=10, childs=[-1, 7028, -1]]. +NPC config [id=7099, name=Kringk, config=1185, shift=31, childs=[7058, -1]]. +NPC config [id=7098, name=null, config=1185, shift=12, childs=[-1, 7030, -1]]. +NPC config [id=7093, name=Peter, config=1185, shift=7, childs=[7029, 7083, -1]]. +NPC config [id=7092, name=Penelope, config=1185, shift=6, childs=[7028, 7083, -1]]. +NPC config [id=7095, name=null, config=1185, shift=9, childs=[-1, 7027, -1]]. +NPC config [id=7094, name=Peanut, config=1185, shift=8, childs=[7030, 7083, -1]]. +NPC config [id=7091, name=Patrick, config=1185, shift=5, childs=[7027, 7083, -1]]. +NPC config [id=7119, name=null, config=1190, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7118, -1, -1, -1, -1, 7118, 7118, -1, 7118, 7118, 7118, -1, -1, -1, -1, 7118, -1, -1, -1, -1, 7118, -1, -1, -1, -1, 7118, -1]]. +NPC config [id=7163, name=Caroline, config=1204, shift=0, childs=[696, -1]]. +NPC config [id=6989, name=null, config=1178, shift=1, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6970, -1]]. +NPC config [id=6988, name=Pikkupstix, config=1178, shift=1, childs=[6971, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6971, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6971, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6971, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6971, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6971, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6971, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6971, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6971, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6971, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6971, -1]]. +NPC config [id=7006, name=null, config=1181, shift=17, childs=[-1, 7001, -1]]. +NPC config [id=7007, name=null, config=1181, shift=17, childs=[-1, 7001, -1]]. +NPC config [id=7009, name=null, config=1181, shift=9, childs=[-1, 7002, -1]]. +NPC config [id=7008, name=null, config=1181, shift=17, childs=[-1, 7001, -1]]. +NPC config [id=7032, name=Wimpy bird, config=1185, shift=0, childs=[7031, 7083, -1]]. +NPC config [id=7033, name=Wimpy bird, config=1185, shift=1, childs=[7031, 7083, -1]]. +NPC config [id=7034, name=Wimpy bird, config=1185, shift=2, childs=[7031, 7083, -1]]. +NPC config [id=7035, name=Wimpy bird, config=1185, shift=3, childs=[7031, 7083, -1]]. +NPC config [id=7036, name=Wimpy bird, config=1185, shift=4, childs=[7031, 7083, -1]]. +NPC config [id=7037, name=null, config=925, shift=31, childs=[-1, 1, -1]]. +NPC config [id=7038, name=null, config=925, shift=31, childs=[-1, 1, -1]]. +NPC config [id=6793, name=null, config=1165, shift=22, childs=[-1, 6782, -1]]. +NPC config [id=7478, name=Bandit, config=435, shift=11, childs=[6174, 6174, 6388, -1]]. +NPC config [id=7192, name=null, config=1204, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7168, -1]]. +NPC config [id=7193, name=null, config=1204, shift=18, childs=[-1, 7171, -1]]. +NPC config [id=7194, name=null, config=1204, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7171, -1]]. +NPC config [id=7195, name=null, config=1204, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7189, -1]]. +NPC config [id=7190, name=Ezekial Lovecraft, config=1204, shift=0, childs=[4856, -1, -1, -1, -1, 4856, -1, -1, -1, -1, 4856, -1, -1, -1, -1, 4856, -1, -1, -1, -1, 4856, -1, -1, -1, -1, 4856, -1, -1, -1, -1, 4856, -1, -1, -1, -1, 4856, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4856, -1]]. +NPC config [id=7191, name=Kimberly, config=1204, shift=0, childs=[7168, -1, -1, -1, -1, 7168, -1, -1, -1, -1, 7168, -1, -1, -1, -1, 7168, -1, -1, -1, -1, 7168, -1, -1, -1, -1, 7168, -1, 7168, -1, -1, 7168, -1, -1, -1, -1, 7168, -1]]. +NPC config [id=7177, name=null, config=1204, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 701, 701, -1, -1, -1, 701, -1, -1, -1, -1, 701, 701, -1, -1, -1, 701, -1, -1, -1, -1, 701, -1, 701, -1, -1, 701, -1, -1, -1, -1, 701, -1]]. +NPC config [id=7176, name=null, config=1204, shift=19, childs=[-1, 701, -1]]. +NPC config [id=7179, name=null, config=1204, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 696, -1]]. +NPC config [id=7178, name=null, config=1204, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 701, -1, 701, -1, -1, 701, -1]]. +NPC config [id=7181, name=null, config=1204, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 696, -1]]. +NPC config [id=7180, name=null, config=1204, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 696, -1, 696, -1]]. +NPC config [id=7182, name=null, config=1204, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 696, 696, -1, -1, -1, 696, -1, -1, -1, -1, 696, 696, -1, -1, -1, 696, -1, -1, -1, -1, 696, -1, 696, -1, -1, 696, -1, -1, -1, -1, 696, -1]]. +NPC config [id=7744, name=null, config=180, shift=-1, childs=[-1, -1, -1, -1, -1, 7742, 7742, -1]]. +NPC config [id=7708, name=null, config=1218, shift=15, childs=[-1, 7664, 7665, -1]]. +NPC config [id=7709, name=null, config=1218, shift=15, childs=[-1, -1, -1, 7665, -1]]. +NPC config [id=7710, name=Flaygian Screwte, config=1218, shift=29, childs=[7672, -1]]. +NPC config [id=7689, name=null, config=1219, shift=4, childs=[-1, 7675, -1]]. +NPC config [id=7688, name=null, config=1219, shift=1, childs=[-1, 7674, -1]]. +NPC config [id=7734, name=Baby icefiend, config=1225, shift=13, childs=[7736, 7713, -1]]. +NPC config [id=7735, name=Baby icefiend, config=1225, shift=15, childs=[7736, 7713, -1]]. +NPC config [id=7732, name=Baby icefiend, config=1225, shift=9, childs=[7736, 7713, -1]]. +NPC config [id=7733, name=Baby icefiend, config=1225, shift=11, childs=[7736, 7713, -1]]. +NPC config [id=7730, name=Brother Bordiss, config=1225, shift=0, childs=[7724, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7724, -1, -1, -1, -1, 7724, -1, -1, -1, -1, 7724, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7724, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7724, -1, -1, -1, -1, 7724, -1, -1, -1, 7724, 7724, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7724, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7724, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7724, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7724, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7724, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7724, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7724, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7724, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7724, -1]]. +NPC config [id=7731, name=null, config=1225, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7725, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7725, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7725, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7725, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7725, -1]]. +NPC config [id=7728, name=Lakki the delivery dwarf, config=1225, shift=8, childs=[7722, -1]]. +NPC config [id=7729, name=Drorkar, config=1225, shift=0, childs=[7723, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7723, -1, -1, -1, -1, 7723, -1, -1, -1, -1, 7723, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7723, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7723, -1, -1, -1, -1, 7723, -1, -1, -1, 7723, 7723, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7723, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7723, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7723, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7723, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7723, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7723, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7723, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7723, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7723, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7724, -1]]. +NPC config [id=7716, name=Icefiend, config=1225, shift=0, childs=[7714, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7714, -1, -1, -1, -1, 7714, -1, -1, -1, -1, 7714, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7714, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7714, -1, -1, -1, -1, 7714, -1, -1, -1, 7714, 7715, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7715, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7715, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7715, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7715, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7715, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7715, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7715, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7715, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7715, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7714, -1]]. diff --git a/dumps/498/498_npc_dump.txt b/dumps/498/498_npc_dump.txt new file mode 100644 index 0000000..dee9b2d --- /dev/null +++ b/dumps/498/498_npc_dump.txt @@ -0,0 +1,7775 @@ +NPC id=0, name=Hans, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1, name=Man, level=2, option=[Talk-to, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=2, name=Man, level=2, option=[Talk-to, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=3, name=Man, level=2, option=[Talk-to, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=4, name=Woman, level=2, option=[Talk-to, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=5, name=Woman, level=2, option=[Talk-to, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=6, name=Woman, level=2, option=[Talk-to, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=7, name=Farmer, level=7, option=[null, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=8, name=Thief, level=16, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=9, name=Guard, level=21, option=[null, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=10, name=Schoolgirl, level=0, option=[Talk-to, null, null, null, null], anims=[7167, 7165]. +NPC id=11, name=Tramp, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=12, name=Barbarian, level=7, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=13, name=Wizard, level=9, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=14, name=Druid, level=33, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=15, name=Warrior woman, level=24, option=[null, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=16, name=Man, level=2, option=[null, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=17, name=Schoolgirl, level=0, option=[Talk-to, null, null, null, null], anims=[7167, 7165]. +NPC id=18, name=Al-Kharid warrior, level=9, option=[null, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=19, name=White Knight, level=36, option=[null, Attack, null, null, null], anims=[7047, -1]. +NPC id=20, name=Paladin, level=62, option=[null, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=21, name=Hero, level=69, option=[null, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=22, name=Forester, level=15, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=23, name=Knight of Ardougne, level=46, option=[null, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=24, name=Man, level=2, option=[Talk-to, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=25, name=Woman, level=2, option=[Talk-to, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=26, name=Knight of Ardougne, level=46, option=[null, Attack, Pickpocket, null, null], anims=[-1, -1]. +NPC id=27, name=Archer, level=37, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=28, name=Zoo keeper, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +--#82FA58 +NPC id=29, name=Chuck, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=30, name=Barman, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=31, name=Priest, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=32, name=Guard, level=20, option=[null, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=33, name=Door man, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=34, name=Watchman, level=33, option=[null, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=35, name=Soldier, level=28, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=36, name=Wyson the gardener, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=37, name=Sigbert the Adventurer, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=38, name=Shipyard worker, level=11, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=39, name=Shipyard worker, level=11, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=40, name=Shark, level=0, option=[null, null, null, null, null], anims=[-1, 10]. +NPC id=41, name=Chicken, level=1, option=[null, Attack, null, null, null], anims=[5386, 5385]. +NPC id=42, name=Sheep, level=0, option=[null, null, null, null, null], anims=[5339, 5340]. +NPC id=43, name=Sheep, level=0, option=[Shear, null, null, null, null], anims=[5335, 5334]. +NPC id=44, name=Banker, level=0, option=[Talk-to, Bank, null, Collect, null], anims=[808, 808]. +NPC id=45, name=Banker, level=0, option=[Talk-to, Bank, null, Collect, null], anims=[808, 808]. +NPC id=46, name=Duck, level=1, option=[null, Attack, null, null, null], anims=[6818, 6817]. +NPC id=47, name=Rat, level=1, option=[null, Attack, null, null, null], anims=[2704, 2703]. +NPC id=48, name=Oomlie bird, level=46, option=[null, Attack, null, null, null], anims=[5386, 5385]. +NPC id=49, name=Hellhound, level=122, option=[null, Attack, null, null, null], anims=[6561, 6583]. +NPC id=50, name=King Black Dragon, level=276, option=[null, Attack, null, null, null], anims=[90, 4635]. +NPC id=51, name=Baby dragon, level=48, option=[null, Attack, null, null, null], anims=[27, 21]. +NPC id=52, name=Baby blue dragon, level=48, option=[null, Attack, null, null, null], anims=[27, 21]. +NPC id=53, name=Red dragon, level=152, option=[null, Attack, null, null, null], anims=[90, 79]. +NPC id=54, name=Black dragon, level=227, option=[null, Attack, null, null, null], anims=[90, 79]. +NPC id=55, name=Blue dragon, level=111, option=[null, Attack, null, null, null], anims=[90, 79]. +NPC id=56, name=Dryad, level=1, option=[null, null, null, null, null], anims=[96, 93]. +NPC id=57, name=Fairy, level=0, option=[Talk-to, null, null, null, null], anims=[112, 106]. +NPC id=58, name=Shadow spider, level=52, option=[null, Attack, null, null, null], anims=[5326, 5325]. +NPC id=59, name=Giant spider, level=2, option=[null, Attack, null, null, null], anims=[5326, 5325]. +NPC id=60, name=Giant spider, level=27, option=[null, Attack, null, null, null], anims=[5326, 5325]. +NPC id=61, name=Spider, level=1, option=[null, Attack, null, null, null], anims=[6247, 6248]. +NPC id=62, name=Jungle spider, level=44, option=[null, Attack, null, null, null], anims=[5326, 5325]. +NPC id=63, name=Deadly red spider, level=34, option=[null, Attack, null, null, null], anims=[5326, 5325]. +NPC id=64, name=Ice spider, level=61, option=[null, Attack, null, null, null], anims=[5326, 5325]. +NPC id=65, name=Leprechaun, level=12, option=[null, Attack, null, null, null], anims=[195, 189]. +NPC id=66, name=Gnome, level=1, option=[Talk-to, Attack, Pickpocket, null, null], anims=[195, 189]. +NPC id=67, name=Gnome, level=1, option=[Talk-to, Attack, Pickpocket, null, null], anims=[195, 189]. +NPC id=68, name=Gnome, level=1, option=[Talk-to, Attack, Pickpocket, null, null], anims=[195, 189]. +NPC id=69, name=Lizard man, level=22, option=[null, Attack, null, null, null], anims=[179, 176]. +NPC id=70, name=Turael, level=0, option=[Talk-to, null, null, Trade, null], anims=[813, -1]. +NPC id=71, name=Orc, level=20, option=[Talk-to, null, null, null, null], anims=[232, 229]. +NPC id=72, name=Troll, level=69, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=73, name=Zombie, level=13, option=[null, Attack, null, null, null], anims=[5565, -1]. +NPC id=74, name=Zombie, level=18, option=[null, Attack, null, null, null], anims=[5576, -1]. +NPC id=75, name=Zombie, level=24, option=[null, Attack, null, null, null], anims=[5572, -1]. +NPC id=76, name=Zombie, level=25, option=[null, Attack, null, null, null], anims=[5572, -1]. +NPC id=77, name=Summoned Zombie, level=13, option=[null, Attack, null, null, null], anims=[5565, -1]. +NPC id=78, name=Giant bat, level=27, option=[null, Attack, null, null, null], anims=[4914, 4913]. +NPC id=79, name=Death wing, level=83, option=[null, Attack, null, null, null], anims=[4914, 4913]. +NPC id=80, name=Camel, level=0, option=[Talk-to, null, null, null, null], anims=[51, 45]. +NPC id=81, name=Cow, level=2, option=[null, Attack, null, null, null], anims=[5852, 5848]. +NPC id=82, name=Lesser demon, level=82, option=[null, Attack, null, null, null], anims=[66, 63]. +NPC id=83, name=Greater demon, level=92, option=[null, Attack, null, null, null], anims=[66, 63]. +NPC id=84, name=Black demon, level=172, option=[null, Attack, null, null, null], anims=[66, 63]. +NPC id=85, name=Golem, level=55, option=[null, Attack, null, null, null], anims=[155, 152]. +NPC id=86, name=Giant rat, level=3, option=[null, Attack, null, null, null], anims=[4932, 4931]. +NPC id=87, name=Giant rat, level=6, option=[null, Attack, null, null, null], anims=[4932, 4931]. +NPC id=88, name=Dungeon rat, level=12, option=[null, Attack, null, null, null], anims=[4932, 4931]. +NPC id=89, name=Unicorn, level=15, option=[null, Attack, null, null, null], anims=[6374, 6373]. +NPC id=90, name=Skeleton, level=22, option=[null, Attack, null, null, null], anims=[5483, 5481]. +NPC id=91, name=Skeleton, level=21, option=[null, Attack, null, null, null], anims=[5483, 5481]. +NPC id=92, name=Skeleton, level=25, option=[null, Attack, null, null, null], anims=[5483, 5481]. +NPC id=93, name=Skeleton, level=45, option=[null, Attack, null, null, null], anims=[5493, 5497]. +NPC id=94, name=Skeleton Mage, level=16, option=[null, Attack, null, null, null], anims=[5483, 5479]. +NPC id=95, name=Wolf, level=64, option=[null, Attack, null, null, null], anims=[6580, 6556]. +NPC id=96, name=White wolf, level=25, option=[null, Attack, null, null, null], anims=[6580, 6556]. +NPC id=97, name=White wolf, level=38, option=[null, Attack, null, null, null], anims=[6580, 6556]. +NPC id=98, name=Dog, level=0, option=[null, null, null, null, null], anims=[6561, 6560]. +NPC id=99, name=Guard dog, level=44, option=[null, Attack, null, null, null], anims=[6561, 6560]. +NPC id=100, name=Goblin, level=2, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=101, name=Goblin, level=5, option=[null, Attack, null, null, null], anims=[6186, 6187]. +NPC id=102, name=Goblin, level=13, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=103, name=Ghost, level=19, option=[null, Attack, null, null, null], anims=[5538, 5539]. +NPC id=104, name=Ghost, level=19, option=[null, Attack, null, null, null], anims=[5530, 5531]. +NPC id=105, name=Grizzly bear, level=21, option=[null, Attack, null, null, null], anims=[4919, 4923]. +NPC id=106, name=Black bear, level=19, option=[null, Attack, null, null, null], anims=[4919, 4923]. +NPC id=107, name=Scorpion, level=14, option=[null, Attack, null, null, null], anims=[6252, 6253]. +NPC id=108, name=Poison Scorpion, level=20, option=[null, Attack, null, null, null], anims=[6252, 6253]. +NPC id=109, name=Pit Scorpion, level=28, option=[null, Attack, null, null, null], anims=[6258, 6257]. +NPC id=110, name=Fire giant, level=86, option=[null, Attack, null, null, null], anims=[4662, 4660]. +NPC id=111, name=Ice giant, level=53, option=[null, Attack, null, null, null], anims=[4670, 4669]. +NPC id=112, name=Moss giant, level=42, option=[null, Attack, null, null, null], anims=[4656, 4654]. +NPC id=113, name=Jogre, level=53, option=[null, Attack, null, null, null], anims=[130, 127]. +NPC id=114, name=Ogre, level=53, option=[null, Attack, null, null, null], anims=[357, 358]. +NPC id=115, name=Ogre, level=53, option=[null, Attack, null, null, null], anims=[357, 358]. +NPC id=116, name=Cyclops, level=56, option=[null, Attack, null, null, null], anims=[4650, 4649]. +NPC id=117, name=Hill Giant, level=28, option=[null, Attack, null, null, null], anims=[4650, 4649]. +NPC id=118, name=Dwarf, level=10, option=[null, Attack, null, null, null], anims=[101, 98]. +NPC id=119, name=Chaos dwarf, level=48, option=[null, Attack, null, null, null], anims=[101, 98]. +NPC id=120, name=Dwarf, level=20, option=[null, Attack, null, null, null], anims=[101, 98]. +NPC id=121, name=Dwarf, level=9, option=[null, Attack, null, null, null], anims=[101, 98]. +NPC id=122, name=Hobgoblin, level=28, option=[null, Attack, null, null, null], anims=[166, 162]. +NPC id=123, name=Hobgoblin, level=42, option=[null, Attack, null, null, null], anims=[166, 162]. +NPC id=124, name=Earth warrior, level=51, option=[null, Attack, null, null, null], anims=[808, 841]. +NPC id=125, name=Ice warrior, level=57, option=[null, Attack, null, null, null], anims=[842, 841]. +NPC id=126, name=Otherworldly being, level=64, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=127, name=Magic axe, level=42, option=[null, Attack, null, null, null], anims=[187, 181]. +NPC id=128, name=Snake, level=5, option=[null, Attack, null, null, null], anims=[277, 274]. +NPC id=129, name=Skavid, level=2, option=[null, Attack, null, null, null], anims=[257, 254]. +NPC id=130, name=Yeti, level=58, option=[null, Attack, null, null, null], anims=[296, 293]. +NPC id=131, name=Penguin, level=2, option=[null, Attack, null, null, null], anims=[5668, 5666]. +NPC id=132, name=Monkey, level=3, option=[null, Attack, null, null, null], anims=[222, 219]. +NPC id=133, name=Black unicorn, level=27, option=[null, Attack, null, null, null], anims=[6374, 6373]. +NPC id=134, name=Poison spider, level=64, option=[null, Attack, null, null, null], anims=[5326, 5325]. +NPC id=135, name=Mammoth, level=41, option=[null, Attack, null, null, null], anims=[306, 303]. +NPC id=136, name=Mounted terrorchick gnome, level=0, option=[Talk-to, null, null, null, null], anims=[6798, 6799]. +NPC id=137, name=Terrorchick gnome, level=0, option=[null, null, null, null, null], anims=[6798, 6799]. +NPC id=138, name=Terrorbird, level=28, option=[null, Attack, null, null, null], anims=[1008, 1007]. +NPC id=139, name=Terrorbird, level=28, option=[null, Attack, null, null, null], anims=[1008, 1007]. +NPC id=140, name=Souless, level=18, option=[null, Attack, null, null, null], anims=[337, 336]. +NPC id=141, name=Big Wolf, level=73, option=[null, Attack, null, null, null], anims=[6580, 6556]. +NPC id=142, name=Wolf, level=25, option=[null, Attack, null, null, null], anims=[6580, 6556]. +NPC id=143, name=Jungle Wolf, level=64, option=[null, Attack, null, null, null], anims=[6580, 6556]. +NPC id=144, name=King Scorpion, level=32, option=[null, Attack, null, null, null], anims=[6252, 6253]. +NPC id=145, name=Ice warrior, level=57, option=[null, Attack, null, null, null], anims=[842, 841]. +NPC id=146, name=Gull, level=0, option=[null, null, null, null, null], anims=[6771, 6773]. +NPC id=147, name=Cormorant, level=0, option=[null, null, null, null, null], anims=[6772, 6774]. +NPC id=148, name=Pelican, level=0, option=[null, null, null, null, null], anims=[6772, 6774]. +NPC id=149, name=Gull, level=0, option=[null, null, null, null, null], anims=[6771, 6773]. +NPC id=150, name=Gull, level=0, option=[null, null, null, null, null], anims=[6771, 6773]. +NPC id=151, name=Fly trap, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC (wrapper) id=152, child npcs=[5207, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5207, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5207, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5207, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5207, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5207, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5207, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5207, -1, -1, 5207, -1, -1, 5207, -1, -1, -1, 5207, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5207, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5207, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5207, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5207, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5207, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5207, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5208, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5208, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5208, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5208, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5208, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5208, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5208, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5208, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5208, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5208, -1]. +NPC id=153, name=Butterfly, level=0, option=[null, null, null, null, null], anims=[362, 362]. +NPC id=154, name=Butterfly, level=0, option=[null, null, null, null, null], anims=[362, 362]. +NPC id=155, name=Butterfly, level=0, option=[null, null, null, null, null], anims=[362, 362]. +NPC id=156, name=Butterfly, level=0, option=[null, null, null, null, null], anims=[362, 362]. +NPC id=157, name=Butterfly, level=0, option=[null, null, null, null, null], anims=[362, 362]. +NPC id=158, name=Shadow warrior, level=48, option=[null, Attack, null, null, null], anims=[842, 841]. +NPC id=159, name=Gnome child, level=1, option=[Talk-to, Attack, Pickpocket, null, null], anims=[195, 189]. +NPC id=160, name=Gnome child, level=1, option=[Talk-to, Attack, Pickpocket, null, null], anims=[195, 189]. +NPC id=161, name=Gnome child, level=1, option=[Talk-to, Attack, Pickpocket, null, null], anims=[195, 189]. +NPC id=162, name=Gnome trainer, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=163, name=Gnome guard, level=23, option=[null, Attack, null, null, null], anims=[195, 189]. +NPC id=164, name=Gnome guard, level=23, option=[null, Attack, null, null, null], anims=[195, 189]. +NPC id=165, name=Gnome shop keeper, level=0, option=[null, null, null, null, null], anims=[195, 189]. +NPC id=166, name=Gnome banker, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[195, 195]. +NPC id=167, name=Gnome baller, level=0, option=[null, null, null, null, null], anims=[195, 189]. +NPC id=168, name=Gnome woman, level=1, option=[Talk-to, Attack, Pickpocket, null, null], anims=[195, 189]. +NPC id=169, name=Gnome woman, level=1, option=[Talk-to, Attack, Pickpocket, null, null], anims=[195, 189]. +NPC id=170, name=Man, level=2, option=[Talk-to, Attack, Pickpocket, null, null], anims=[813, -1]. +NPC id=171, name=Brimstail, level=0, option=[Talk-to, null, Teleport, null, null], anims=[195, 189]. +NPC id=172, name=Dark wizard, level=20, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=173, name=Invrigar the Necromancer, level=20, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=174, name=Dark wizard, level=7, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=175, name=Mugger, level=6, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=176, name=Witch, level=25, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=177, name=Witch, level=25, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=178, name=Black Knight, level=33, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=179, name=Black Knight, level=33, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=180, name=Highwayman, level=5, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=181, name=Chaos druid, level=13, option=[null, Attack, null, null, null], anims=[8528, 8527]. +NPC id=182, name=Pirate, level=23, option=[Talk-to, Attack, null, null, null], anims=[7188, -1]. +NPC id=183, name=Pirate, level=23, option=[Talk-to, Attack, null, null, null], anims=[7188, -1]. +NPC id=184, name=Pirate, level=26, option=[null, Attack, null, null, null], anims=[7188, -1]. +NPC id=185, name=Pirate, level=23, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=186, name=Thug, level=10, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=187, name=Rogue, level=15, option=[null, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=188, name=Monk of Zamorak, level=22, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=189, name=Monk of Zamorak, level=17, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=190, name=Monk of Zamorak, level=45, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=191, name=Tribesman, level=32, option=[null, Attack, null, null, null], anims=[813, -1]. +NPC id=192, name=Dark warrior, level=8, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=193, name=Chaos druid warrior, level=37, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=194, name=Necromancer, level=26, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=195, name=Bandit, level=22, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=196, name=Guard Bandit, level=22, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=197, name=Barbarian guard, level=8, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=198, name=Guildmaster, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=199, name=Gunthor the Brave, level=29, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=200, name=Lord Daquarius, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=201, name=Jailer, level=47, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=202, name=Black Heather, level=34, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=203, name=Donny the Lad, level=34, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=204, name=Speedy Keith, level=34, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=205, name=Salarin the Twisted, level=70, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=206, name=Guard, level=10, option=[Talk-to, Attack, null, null, null], anims=[101, 98]. +NPC id=207, name=Lollk, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=208, name=Captain Lawgof, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=209, name=Nulodion, level=0, option=[Talk-to, null, Trade, null, null], anims=[101, 98]. +NPC id=210, name=Grail Maiden, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=211, name=Sir Percival, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=212, name=King Percival, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=213, name=Merlin, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=214, name=Peasant, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=215, name=Peasant, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=216, name=High Priest, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=217, name=Crone, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=218, name=Galahad, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=219, name=Fisherman, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=220, name=The Fisher King, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=221, name=Black Knight Titan, level=120, option=[Talk-to, Attack, null, null, null], anims=[130, 127]. +NPC id=222, name=Monk, level=5, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=223, name=Brother Kojo, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=224, name=Dungeon rat, level=12, option=[null, Attack, null, null, null], anims=[4932, 4931]. +NPC id=225, name=Bonzo, level=0, option=[Talk-to, null, Pay, null, null], anims=[808, -1]. +NPC (wrapper) id=226, child npcs=[3677, 3678, -1]. +NPC id=227, name=Morris, level=0, option=[Talk-to, null, null, null, null], anims=[3845, -1]. +NPC id=228, name=Big Dave, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=229, name=Joshua, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=230, name=Grandpa Jack, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=231, name=Forester, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=232, name=Austri, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=233, name=Fishing spot, level=0, option=[Bait, null, null, null, null], anims=[447, 448]. +NPC id=234, name=Fishing spot, level=0, option=[Bait, null, null, null, null], anims=[447, 448]. +NPC id=235, name=Fishing spot, level=0, option=[Bait, null, null, null, null], anims=[447, 448]. +NPC id=236, name=Fishing spot, level=0, option=[Bait, null, null, null, null], anims=[447, 448]. +NPC id=237, name=Renegade Knight, level=37, option=[null, Attack, null, null, null], anims=[6927, 6928]. +NPC id=238, name=Thrantax the Mighty, level=92, option=[null, Attack, null, null, null], anims=[5538, 5539]. +NPC id=239, name=Sir Lancelot, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=240, name=Sir Gawain, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=241, name=Sir Kay, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=242, name=Sir Bedivere, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=243, name=Sir Tristram, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=244, name=Sir Pelleas, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=245, name=Sir Lucan, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=246, name=Teapotspout, level=94, option=[null, null, Walk here, Follow, Trade], anims=[8943, 8943]. +NPC id=247, name=Sir Mordred, level=39, option=[Talk-to, Attack, null, null, null], anims=[6487, 6486]. +NPC id=248, name=Morgan Le Faye, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=249, name=Merlin, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=250, name=The Lady of the Lake, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=251, name=King Arthur, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=252, name=Beggar, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=253, name=Khazard Guard, level=23, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=254, name=Khazard Guard, level=23, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=255, name=Khazard Guard, level=23, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=256, name=Khazard Guard, level=23, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=257, name=Khazard Guard, level=25, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=258, name=General Khazard, level=112, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=259, name=Khazard barman, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=260, name=Kelvin, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=261, name=Joe, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=262, name=Fightslave, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=263, name=Hengrad, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=264, name=Lady Servil, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=265, name=Jeremy Servil, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=266, name=Jeremy Servil, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=267, name=Justin Servil, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=268, name=Local, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=269, name=Bouncer, level=137, option=[null, Attack, null, null, null], anims=[6580, 6582]. +NPC id=270, name=Khazard Ogre, level=63, option=[null, Attack, null, null, null], anims=[357, 358]. +NPC id=271, name=Khazard Scorpion, level=44, option=[null, Attack, null, null, null], anims=[6252, 6262]. +NPC id=272, name=Lucien, level=14, option=[Talk-to, Attack, null, null, null], anims=[6469, 6468]. +NPC id=273, name=Lucien, level=0, option=[Talk-to, null, null, null, null], anims=[6469, 6468]. +NPC id=274, name=Guardian of Armadyl, level=45, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=275, name=Guardian of Armadyl, level=43, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=276, name=Winelda, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=277, name=Fire Warrior of Lesarkus, level=84, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=278, name=Cook, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=279, name=Brother Omad, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=280, name=Brother Cedric, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=281, name=Monk, level=3, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=282, name=Thief, level=14, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=283, name=Head Thief, level=26, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=284, name=Doric, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=285, name=Veronica, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=286, name=Professor Oddenstein, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=287, name=Ernest, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=288, name=Chicken, level=0, option=[null, null, null, null, null], anims=[2298, 2297]. +NPC id=289, name=Councillor Halgrive, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=290, name=Doctor Orbon, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=291, name=Farmer Brumty, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC (wrapper) id=292, child npcs=[2345, 2377, -1]. +NPC (wrapper) id=293, child npcs=[2346, 2378, -1]. +NPC (wrapper) id=294, child npcs=[2347, 2379, -1]. +NPC (wrapper) id=295, child npcs=[2348, 2380, -1]. +NPC id=296, name=Guard, level=21, option=[null, Attack, Pickpocket, null, null], anims=[7222, 7223]. +NPC id=297, name=Guard, level=21, option=[null, Attack, Pickpocket, null, null], anims=[7222, 7224]. +NPC id=298, name=Guard, level=21, option=[null, Attack, Pickpocket, null, null], anims=[7222, 7223]. +NPC id=299, name=Guard, level=21, option=[null, Attack, Pickpocket, null, null], anims=[7217, 7216]. +NPC id=300, name=Sedridor, level=0, option=[Talk-to, null, Teleport, null, null], anims=[813, -1]. +NPC id=301, name=Twig, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=302, name=Hadley, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=303, name=Gerald, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=304, name=Almera, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=305, name=Hudon, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=306, name=Golrie, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=307, name=Hetty, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=308, name=Master fisher, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=309, name=Fishing spot, level=0, option=[Lure, null, Bait, hidden, hidden], anims=[447, 448]. +NPC id=310, name=Fishing spot, level=0, option=[Lure, null, Bait, hidden, hidden], anims=[447, 448]. +NPC id=311, name=Fishing spot, level=0, option=[Lure, null, Bait, hidden, hidden], anims=[447, 448]. +NPC id=312, name=Fishing spot, level=0, option=[Cage, null, Harpoon, hidden, hidden], anims=[447, 448]. +NPC id=313, name=Fishing spot, level=0, option=[Net, null, Harpoon, hidden, hidden], anims=[447, 448]. +NPC id=314, name=Fishing spot, level=0, option=[Lure, null, Bait, hidden, hidden], anims=[447, 448]. +NPC id=315, name=Fishing spot, level=0, option=[Lure, null, Bait, hidden, hidden], anims=[447, 448]. +NPC id=316, name=Fishing spot, level=0, option=[Net, null, Bait, hidden, hidden], anims=[447, 448]. +NPC id=317, name=Fishing spot, level=0, option=[Lure, null, Bait, hidden, hidden], anims=[447, 448]. +NPC id=318, name=Fishing spot, level=0, option=[Lure, null, Bait, hidden, hidden], anims=[447, 448]. +NPC id=319, name=Fishing spot, level=0, option=[Net, null, Bait, hidden, hidden], anims=[447, 448]. +NPC id=320, name=Fishing spot, level=0, option=[Net, null, Bait, hidden, hidden], anims=[447, 448]. +NPC id=321, name=Fishing spot, level=0, option=[Cage, null, Harpoon, hidden, hidden], anims=[447, 448]. +NPC id=322, name=Fishing spot, level=0, option=[Net, null, Harpoon, hidden, hidden], anims=[447, 448]. +NPC id=323, name=Fishing spot, level=0, option=[Net, null, Bait, hidden, hidden], anims=[447, 448]. +NPC id=324, name=Fishing spot, level=0, option=[Cage, null, Harpoon, hidden, hidden], anims=[447, 448]. +NPC id=325, name=Fishing spot, level=0, option=[Net, null, Bait, hidden, hidden], anims=[447, 448]. +NPC id=326, name=Fishing spot, level=0, option=[Net, null, Bait, hidden, hidden], anims=[447, 448]. +NPC id=327, name=Fishing spot, level=0, option=[Net, null, Bait, hidden, hidden], anims=[447, 448]. +NPC id=328, name=Fishing spot, level=0, option=[Lure, null, Bait, hidden, hidden], anims=[447, 448]. +NPC id=329, name=Fishing spot, level=0, option=[Lure, null, Bait, hidden, hidden], anims=[447, 448]. +NPC id=330, name=Fishing spot, level=0, option=[Net, null, Bait, hidden, hidden], anims=[447, 448]. +NPC id=331, name=Fishing spot, level=0, option=[Lure, null, Bait, hidden, hidden], anims=[447, 448]. +NPC id=332, name=Fishing spot, level=0, option=[Net, null, Bait, hidden, hidden], anims=[447, 448]. +NPC id=333, name=Fishing spot, level=0, option=[Cage, null, Harpoon, hidden, hidden], anims=[447, 448]. +NPC id=334, name=Fishing spot, level=0, option=[Net, null, Harpoon, hidden, hidden], anims=[447, 448]. +NPC id=335, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=336, name=Da Vinci, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=337, name=Da Vinci, level=0, option=[Talk-to, null, null, null, null], anims=[1322, -1]. +NPC id=338, name=Chancy, level=0, option=[Talk-to, null, null, null, null], anims=[2713, -1]. +NPC id=339, name=Chancy, level=0, option=[Talk-to, null, null, null, null], anims=[1322, -1]. +NPC id=340, name=Hops, level=0, option=[Talk-to, null, null, null, null], anims=[2712, -1]. +NPC id=341, name=Hops, level=0, option=[Talk-to, null, null, null, null], anims=[1322, -1]. +NPC id=342, name=Guidor's wife, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=343, name=Guidor, level=0, option=[Talk-to, null, null, null, null], anims=[4780, -1]. +NPC id=344, name=Guard, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=345, name=Guard, level=0, option=[Talk-to, null, null, null, null], anims=[4591, -1]. +NPC id=346, name=Guard, level=0, option=[Talk-to, null, null, null, null], anims=[4591, -1]. +NPC id=347, name=Mourner, level=11, option=[Talk-to, Attack, null, null, null], anims=[813, -1]. +NPC id=348, name=Mourner, level=24, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=349, name=Kilron, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=350, name=Omart, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=351, name=Man, level=4, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=352, name=Woman, level=3, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=353, name=Woman, level=4, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=354, name=Woman, level=3, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=355, name=Child, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=356, name=Child, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=357, name=Mourner, level=18, option=[null, Attack, null, null, null], anims=[813, -1]. +NPC id=358, name=Priest, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=359, name=Man, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=360, name=Woman, level=4, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=361, name=Woman, level=12, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=362, name=Woman, level=3, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=363, name=Woman, level=14, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=364, name=King Lathas, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=365, name=Paladin, level=59, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=366, name=Jerico, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=367, name=Chemist, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=368, name=Guard, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=369, name=Mourner, level=24, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=370, name=Mourner, level=13, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=371, name=Mourner, level=12, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=372, name=Mourner, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=373, name=Nurse Sarah, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=374, name=Ogre, level=63, option=[null, Attack, null, null, null], anims=[357, 358]. +NPC id=375, name=Redbeard Frank, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=376, name=Captain Tobias, level=0, option=[Talk-to, null, Pay-fare, null, null], anims=[808, -1]. +NPC id=377, name=Seaman Lorris, level=0, option=[Talk-to, null, Pay-fare, null, null], anims=[808, -1]. +NPC id=378, name=Seaman Thresnor, level=0, option=[Talk-to, null, Pay-fare, null, null], anims=[808, -1]. +NPC id=379, name=Luthas, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=380, name=Customs officer, level=0, option=[Talk-to, null, Pay-Fare, null, null], anims=[808, -1]. +NPC (wrapper) id=381, child npcs=[4974, -1]. +NPC id=382, name=Dwarf, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=383, name=Stankers, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=384, name=Barbarian guard, level=0, option=[Talk-to, null, null, null, null], anims=[2065, 2064]. +NPC id=385, name=Kharid Scorpion, level=0, option=[Pick-up, null, null, null, null], anims=[6258, 6257]. +NPC id=386, name=Kharid Scorpion, level=0, option=[Pick-up, null, null, null, null], anims=[6258, 6257]. +NPC id=387, name=Kharid Scorpion, level=0, option=[Pick-up, null, null, null, null], anims=[6258, 6257]. +NPC id=388, name=Seer, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=389, name=Thormac, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=390, name=Big fish, level=0, option=[null, null, null, null, null], anims=[4, -1]. +NPC id=391, name=River troll, level=14, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=392, name=River troll, level=29, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=393, name=River troll, level=49, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=394, name=River troll, level=79, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=395, name=River troll, level=120, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=396, name=River troll, level=159, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=397, name=Cow, level=2, option=[null, Attack, null, null, null], anims=[5852, 5848]. +NPC id=398, name=Legends guard, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=399, name=Legends guard, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=400, name=Radimus Erkle, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=401, name=Jungle forester, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=402, name=Jungle forester, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=403, name=Fishing spot, level=0, option=[Lure, null, Bait, hidden, hidden], anims=[456, -1]. +NPC id=404, name=Fishing spot, level=0, option=[Net, null, Bait, hidden, hidden], anims=[456, -1]. +NPC id=405, name=Fishing spot, level=0, option=[Cage, null, Harpoon, hidden, hidden], anims=[456, -1]. +NPC id=406, name=Fishing spot, level=0, option=[Net, null, Harpoon, hidden, hidden], anims=[456, -1]. +NPC id=407, name=Strange plant, level=0, option=[Pick, null, null, null, null], anims=[349, -1]. +NPC id=408, name=Strange plant, level=0, option=[null, Attack, null, null, null], anims=[352, 356]. +NPC id=409, name=Genie, level=0, option=[Talk-to, null, null, null, null], anims=[792, 792]. +NPC id=410, name=Mysterious Old Man, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=411, name=Swarm, level=0, option=[null, null, null, null, null], anims=[0, 0]. +NPC id=412, name=Bat, level=6, option=[null, Attack, null, null, null], anims=[4914, 4913]. +NPC id=413, name=Rock Golem, level=14, option=[null, Attack, null, null, null], anims=[155, 152]. +NPC id=414, name=Rock Golem, level=29, option=[null, Attack, null, null, null], anims=[155, 152]. +NPC id=415, name=Rock Golem, level=49, option=[null, Attack, null, null, null], anims=[155, 152]. +NPC id=416, name=Rock Golem, level=79, option=[null, Attack, null, null, null], anims=[155, 152]. +NPC id=417, name=Rock Golem, level=120, option=[null, Attack, null, null, null], anims=[155, 152]. +NPC id=418, name=Rock Golem, level=159, option=[null, Attack, null, null, null], anims=[155, 152]. +NPC id=419, name=Zombie, level=14, option=[null, Attack, null, null, null], anims=[5572, -1]. +NPC id=420, name=Zombie, level=29, option=[null, Attack, null, null, null], anims=[5572, -1]. +NPC id=421, name=Zombie, level=49, option=[null, Attack, null, null, null], anims=[5572, -1]. +NPC id=422, name=Zombie, level=79, option=[null, Attack, null, null, null], anims=[5572, -1]. +NPC id=423, name=Zombie, level=120, option=[null, Attack, null, null, null], anims=[5572, -1]. +NPC id=424, name=Zombie, level=159, option=[null, Attack, null, null, null], anims=[5572, -1]. +NPC id=425, name=Shade, level=14, option=[null, Attack, null, null, null], anims=[15, 13]. +NPC id=426, name=Shade, level=29, option=[null, Attack, null, null, null], anims=[15, 13]. +NPC id=427, name=Shade, level=49, option=[null, Attack, null, null, null], anims=[15, 13]. +NPC id=428, name=Shade, level=79, option=[null, Attack, null, null, null], anims=[15, 13]. +NPC id=429, name=Shade, level=120, option=[null, Attack, null, null, null], anims=[15, 13]. +NPC id=430, name=Shade, level=159, option=[null, Attack, null, null, null], anims=[15, 13]. +NPC (wrapper) id=431, child npcs=[4544, -1, 4544, -1, 4544, -1, 4544, -1, 4544, -1, 4544, -1, 4544, -1, 4544, -1]. +NPC id=432, name=Cyrisus, level=138, option=[null, hidden, null, null, null], anims=[808, -1]. +NPC id=433, name=Cyrisus, level=138, option=[null, hidden, null, null, null], anims=[808, -1]. +NPC id=434, name=Cyrisus, level=138, option=[null, hidden, null, null, null], anims=[808, -1]. +NPC id=435, name=Fallen Man, level=0, option=[Talk-to, null, Inspect, null, null], anims=[6280, 6280]. +NPC id=436, name=Fallen Man, level=0, option=[Talk-to, null, Inspect, null, null], anims=[6282, 6282]. +NPC id=437, name=Cap'n Izzy No-Beard, level=0, option=[Talk-to, null, Pay, null, null], anims=[808, -1]. +NPC id=438, name=Tree spirit, level=14, option=[null, Attack, null, null, null], anims=[96, 93]. +NPC id=439, name=Tree spirit, level=29, option=[null, Attack, null, null, null], anims=[96, 93]. +NPC id=440, name=Tree spirit, level=49, option=[null, Attack, null, null, null], anims=[96, 93]. +NPC id=441, name=Tree spirit, level=79, option=[null, Attack, null, null, null], anims=[96, 93]. +NPC id=442, name=Tree spirit, level=120, option=[null, Attack, null, null, null], anims=[96, 93]. +NPC id=443, name=Tree spirit, level=159, option=[null, Attack, null, null, null], anims=[96, 93]. +NPC id=444, name=Goblin, level=5, option=[Talk-to, Attack, null, null, null], anims=[6181, 6180]. +NPC id=445, name=Goblin, level=5, option=[null, Attack, null, null, null], anims=[6186, 6187]. +NPC id=446, name=Giant rat, level=3, option=[null, Attack, null, null, null], anims=[4932, 4931]. +NPC id=447, name=Jail guard, level=26, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=448, name=Jail guard, level=26, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=449, name=Jail guard, level=26, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=450, name=Gull, level=0, option=[null, null, null, null, null], anims=[6771, 6773]. +NPC id=451, name=Gull, level=0, option=[null, null, null, null, null], anims=[6771, 6773]. +NPC id=452, name=Seth Groats, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=453, name=Suit of armour, level=19, option=[null, Attack, null, null, null], anims=[-1, -1]. +NPC id=454, name=Sanfew, level=0, option=[Talk-to, null, null, null, null], anims=[8528, 8527]. +NPC id=455, name=Kaqemeex, level=0, option=[Talk-to, null, null, null, null], anims=[8528, 8527]. +NPC id=456, name=Father Aereck, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=457, name=Restless ghost, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=458, name=Father Urhney, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=459, name=Skeleton, level=13, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=460, name=Wizard Frumscone, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=461, name=Magic Store owner, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=462, name=Wizard Distentor, level=0, option=[Talk-to, null, Teleport, null, null], anims=[813, -1]. +NPC id=463, name=Murphy, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=464, name=Murphy, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=465, name=Murphy, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=466, name=Murphy, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=467, name=Shark, level=0, option=[null, null, null, null, null], anims=[10, 10]. +NPC id=468, name=Shark, level=0, option=[null, null, null, null, null], anims=[10, 10]. +NPC id=469, name=King Bolren, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=470, name=Commander Montai, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=471, name=Bolkoy, level=0, option=[Talk-to, null, Trade, null, null], anims=[195, 189]. +NPC id=472, name=Remsai, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=473, name=Elkoy, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=474, name=Elkoy, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=475, name=Khazard trooper, level=19, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=476, name=Khazard trooper, level=19, option=[null, Attack, null, null, null], anims=[813, -1]. +NPC id=477, name=Khazard warlord, level=112, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=478, name=Khazard commander, level=48, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=479, name=Gnome troop, level=1, option=[Talk-to, Attack, null, null, null], anims=[195, 189]. +NPC id=480, name=Gnome troop, level=1, option=[Talk-to, Attack, null, null, null], anims=[195, 189]. +NPC id=481, name=Tracker gnome 1, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=482, name=Tracker gnome 2, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=483, name=Tracker gnome 3, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=484, name=Local Gnome, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=485, name=Local Gnome, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=486, name=Kalron, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=487, name=Giant, level=0, option=[null, null, null, null, null], anims=[6857, -1]. +NPC id=488, name=Observatory professor, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=489, name=Goblin guard, level=42, option=[null, Attack, null, null, null], anims=[6200, 6201]. +NPC id=490, name=Mummy, level=0, option=[null, null, null, null, null], anims=[6856, -1]. +NPC id=491, name=Ghost, level=24, option=[Talk-to, Attack, null, null, null], anims=[5538, 5539]. +NPC id=492, name=Spirit of Scorpius, level=0, option=[Talk-to, null, null, null, null], anims=[5538, 5539]. +NPC id=493, name=Grave scorpion, level=12, option=[null, Attack, null, null, null], anims=[6258, 6257]. +NPC id=494, name=Banker, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[808, 808]. +NPC id=495, name=Banker, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[808, 808]. +NPC id=496, name=Banker, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[808, 808]. +NPC id=497, name=Banker, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[808, 808]. +NPC id=498, name=Banker, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[112, 112]. +NPC id=499, name=Banker, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[808, 808]. +NPC id=500, name=Mosol Rei, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=501, name=Spirit of Zadimus, level=0, option=[Talk-to, null, null, null, null], anims=[5530, 5531]. +NPC id=502, name=Undead one, level=68, option=[null, Attack, null, null, null], anims=[5483, 5479]. +NPC id=503, name=Undead one, level=61, option=[null, Attack, null, null, null], anims=[5483, 5479]. +NPC id=504, name=Undead one, level=68, option=[null, Attack, null, null, null], anims=[5565, -1]. +NPC id=505, name=Undead one, level=73, option=[null, Attack, null, null, null], anims=[5572, -1]. +NPC id=506, name=Rashiliyia, level=0, option=[Talk-to, null, null, null, null], anims=[5530, 5531]. +NPC id=507, name=Nazastarool, level=91, option=[null, Attack, null, null, null], anims=[5572, 5582]. +NPC id=508, name=Nazastarool, level=68, option=[null, Attack, null, null, null], anims=[5505, 5506]. +NPC id=509, name=Nazastarool, level=93, option=[null, Attack, null, null, null], anims=[5530, 5531]. +NPC id=510, name=Hajedy, level=0, option=[Talk-to, null, Pay-fare, null, null], anims=[808, -1]. +NPC id=511, name=Vigroy, level=0, option=[Talk-to, null, Pay-fare, null, null], anims=[808, -1]. +NPC id=512, name=Kaleb Paramaya, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=513, name=Yohnus, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=514, name=Seravel, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=515, name=Yanni Salika, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=516, name=Obli, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=517, name=Fernahei, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=518, name=Captain Shanks, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=519, name=Bob, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=520, name=Shopkeeper, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=521, name=Shop assistant, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=522, name=Shopkeeper, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=523, name=Shop assistant, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=524, name=Shopkeeper, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=525, name=Shop assistant, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=526, name=Shopkeeper, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=527, name=Shop assistant, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=528, name=Shopkeeper, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=529, name=Shop assistant, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=530, name=Shopkeeper, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=531, name=Shop assistant, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=532, name=Shopkeeper, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=533, name=Shop assistant, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=534, name=Fairy shopkeeper, level=0, option=[Talk-to, null, Trade, null, null], anims=[112, 106]. +NPC id=535, name=Fairy shop assistant, level=0, option=[Talk-to, null, Trade, null, null], anims=[112, 106]. +NPC id=536, name=Valaine, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=537, name=Scavvo, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=538, name=Peksa, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=539, name=Silk trader, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=540, name=Gem trader, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=541, name=Zeke, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=542, name=Louie Legs, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=543, name=Karim, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=544, name=Ranael, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=545, name=Dommik, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=546, name=Zaff, level=0, option=[Talk-to, null, Trade, Buy-battlestaves, null], anims=[813, -1]. +NPC id=547, name=Baraek, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=548, name=Thessalia, level=0, option=[Talk-to, null, Trade, Change-clothes, null], anims=[808, -1]. +NPC id=549, name=Horvik, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=550, name=Lowe, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=551, name=Shopkeeper, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=552, name=Shop assistant, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=553, name=Aubury, level=0, option=[Talk-to, null, Trade, Teleport, null], anims=[808, -1]. +NPC id=554, name=Fancy-dress shop owner, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=555, name=Shopkeeper, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=556, name=Grum, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=557, name=Wydin, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=558, name=Gerrant, level=0, option=[Talk-to, null, Trade, null, null], anims=[813, -1]. +NPC id=559, name=Brian, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=560, name=Jiminua, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=561, name=Shopkeeper, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=562, name=Candle-maker, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=563, name=Arhein, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=564, name=Jukat, level=0, option=[Talk-to, null, Trade, null, null], anims=[112, 106]. +NPC id=565, name=Lunderwin, level=0, option=[Talk-to, null, null, null, null], anims=[112, 106]. +NPC id=566, name=Irksol, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=567, name=Fairy, level=0, option=[Talk-to, null, null, null, null], anims=[112, 106]. +NPC id=568, name=Zambo, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=569, name=Silver merchant, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=570, name=Gem merchant, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=571, name=Baker, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=572, name=Spice seller, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=573, name=Fur trader, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=574, name=Silk merchant, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=575, name=Hickton, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=576, name=Harry, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=577, name=Cassie, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=578, name=Frincos, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=579, name=Drogo dwarf, level=0, option=[Talk-to, null, Trade, null, null], anims=[101, 98]. +NPC id=580, name=Flynn, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=581, name=Wayne, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=582, name=Dwarf, level=0, option=[Talk-to, null, Trade, null, null], anims=[101, 98]. +NPC id=583, name=Betty, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=584, name=Herquin, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=585, name=Rommik, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=586, name=Gaius, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=587, name=Jatix, level=0, option=[Talk-to, null, Trade, null, null], anims=[8528, 8527]. +NPC id=588, name=Davon, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=589, name=Zenesha, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=590, name=Aemad, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=591, name=Kortan, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=592, name=Roachey, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=593, name=Frenita, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=594, name=Nurmof, level=0, option=[Talk-to, null, Trade, null, null], anims=[101, 98]. +NPC id=595, name=Tea seller, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=596, name=Fat Tony, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=597, name=Noterazzo, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=598, name=Hairdresser, level=0, option=[Talk-to, null, Hair-cut, null, null], anims=[808, -1]. +NPC id=599, name=Make-over Mage, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=600, name=Hudo, level=0, option=[Talk-to, null, Trade, null, null], anims=[195, 189]. +NPC id=601, name=Rometti, level=0, option=[Talk-to, null, Trade, null, null], anims=[195, 189]. +NPC id=602, name=Gulluck, level=0, option=[Talk-to, null, Trade, null, null], anims=[195, 189]. +NPC id=603, name=Heckel Funch, level=0, option=[Talk-to, null, Trade, null, null], anims=[195, 189]. +NPC id=604, name=Thurgo, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=605, name=Sir Vyvin, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=606, name=Squire, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=607, name=Gunnjorn, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=608, name=Sir Amik Varze, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=609, name=Fortress Guard, level=20, option=[Talk-to, Attack, null, null, null], anims=[813, -1]. +NPC id=610, name=Black Knight Captain, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=611, name=Witch, level=0, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=612, name=Greldo, level=0, option=[null, null, null, null, null], anims=[6200, 6201]. +NPC id=613, name=Digsite workman, level=0, option=[Talk-to, null, Steal-from, null, null], anims=[808, -1]. +NPC id=614, name=Doug Deeping, level=0, option=[Talk-to, null, Steal-from, null, null], anims=[808, -1]. +NPC id=615, name=Student, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=616, name=Student, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=617, name=Student, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[808, -1]. +NPC id=618, name=Examiner, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=619, name=Archaeological expert, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=620, name=Panning guide, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=621, name=Gnome baller, level=0, option=[Tackle, null, null, null, null], anims=[195, 189]. +NPC id=622, name=Gnome baller, level=0, option=[Tackle, null, null, null, null], anims=[195, 189]. +NPC id=623, name=Gnome baller, level=0, option=[null, null, null, null, null], anims=[205, 205]. +NPC id=624, name=Gnome baller, level=0, option=[null, null, null, null, null], anims=[208, 208]. +NPC id=625, name=Gnome baller, level=0, option=[Tackle, null, null, null, null], anims=[195, 189]. +NPC id=626, name=Gnome baller, level=0, option=[Tackle, null, null, null, null], anims=[195, 189]. +NPC id=627, name=Gnome baller, level=0, option=[null, null, null, null, null], anims=[205, 205]. +NPC id=628, name=Gnome baller, level=0, option=[null, null, null, null, null], anims=[208, 208]. +NPC id=629, name=Gnome baller, level=0, option=[Tackle, null, null, null, null], anims=[195, 189]. +NPC id=630, name=Gnome baller, level=0, option=[Tackle, null, null, null, null], anims=[195, 189]. +NPC id=631, name=Gnome baller, level=0, option=[null, null, null, null, null], anims=[205, 205]. +NPC id=632, name=Gnome baller, level=0, option=[null, null, null, null, null], anims=[208, 208]. +NPC id=633, name=Gnome winger, level=0, option=[Pass-to, null, null, null, null], anims=[195, 189]. +NPC id=634, name=Gnome winger, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=635, name=Gnome ball referee, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=636, name=Cheerleader, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=637, name=Juliet, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=638, name=Apothecary, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=639, name=Romeo, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=640, name=Father Lawrence, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=641, name=Charlie the Tramp, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=642, name=Katrine, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=643, name=Weaponsmaster, level=23, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=644, name=Straven, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=645, name=Jonny the beard, level=2, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=646, name=Curator Haig Halen, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[808, -1]. +NPC (wrapper) id=647, child npcs=[2661, 2660, -1]. +NPC id=648, name=King Roald, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=649, name=Archer, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=650, name=Warrior, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=651, name=Monk, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=652, name=Wizard, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=653, name=Fairy Queen, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=654, name=Shamus, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=655, name=Tree spirit, level=101, option=[null, Attack, null, null, null], anims=[5530, 5531]. +NPC id=656, name=Cave monk, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=657, name=Monk of Entrana, level=0, option=[Talk-to, null, Take-boat, null, null], anims=[808, -1]. +NPC id=658, name=Monk of Entrana, level=0, option=[Talk-to, null, Take-boat, null, null], anims=[808, -1]. +NPC id=659, name=Party Pete, level=0, option=[Talk-to, null, null, null, null], anims=[9227, -1]. +NPC id=660, name=Knight, level=0, option=[Talk-to, null, null, null, null], anims=[784, -1]. +NPC id=661, name=Megan, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=662, name=Lucy, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=663, name=Man, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=664, name=Dimintheis, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=665, name=Boot, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=666, name=Caleb, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=667, name=Chronozon, level=170, option=[null, Attack, null, null, null], anims=[66, 63]. +NPC id=668, name=Johnathon, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=669, name=Hazelmere, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=670, name=King Narnode Shareen, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=671, name=Glough, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=672, name=Anita, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=673, name=Charlie, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=674, name=Foreman, level=23, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=675, name=Shipyard worker, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=676, name=Femi, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=677, name=Black demon, level=172, option=[null, Attack, null, null, null], anims=[66, 63]. +NPC id=678, name=Guard, level=37, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=679, name=Ranging Guild Doorman, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=680, name=Leatherworker, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=681, name=Held vampyre juvinate, level=59, option=[null, Attack, null, null, null], anims=[3551, -1]. +NPC id=682, name=Armour salesman, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=683, name=Bow and Arrow salesman, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=684, name=Tower Advisor, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=685, name=Tower Advisor, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=686, name=Tower Advisor, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=687, name=Tower Advisor, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=688, name=Tower Archer, level=19, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=689, name=Tower Archer, level=34, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=690, name=Tower Archer, level=49, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=691, name=Tower Archer, level=64, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=692, name=Tribal Weapon Salesman, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=693, name=Competition Judge, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=694, name=Ticket Merchant, level=0, option=[Trade, null, null, null, null], anims=[808, -1]. +NPC id=695, name=Bailey, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=696, name=Caroline, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC (wrapper) id=697, child npcs=[4864, 4864, 4864, 4864, 4864, 4864, 4864, 4864, 4864, 4864, 4864, -1]. +NPC id=698, name=Holgart, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=699, name=Holgart, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=700, name=Holgart, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=701, name=Kent, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=702, name=Fisherman, level=0, option=[Talk-to, null, null, null, null], anims=[4825, 4779]. +NPC id=703, name=Fisherman, level=0, option=[Talk-to, null, null, null, null], anims=[4825, 4779]. +NPC id=704, name=Fisherman, level=0, option=[Talk-to, null, null, null, null], anims=[4825, 4779]. +NPC id=705, name=Melee combat tutor, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=706, name=Wizard Mizgog, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=707, name=Wizard Grayzag, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=708, name=Imp, level=2, option=[null, Attack, null, null, null], anims=[171, 168]. +NPC id=709, name=Imp, level=3, option=[null, Attack, null, null, null], anims=[171, 168]. +NPC id=710, name=Alrena, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=711, name=Bravek, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=712, name=Carla, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=713, name=Clerk, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=714, name=Edmond, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC (wrapper) id=715, child npcs=[3215, -1]. +NPC id=716, name=Head mourner, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=717, name=Mourner, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=718, name=Mourner, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=719, name=Mourner, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=720, name=Recruiter, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=721, name=Ted Rehnison, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=722, name=Martha Rehnison, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=723, name=Billy Rehnison, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=724, name=Milli Rehnison, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=725, name=Jethick, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=726, name=Man, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=727, name=Man, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=728, name=Man, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=729, name=Man, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=730, name=Man, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=731, name=Bartender, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=732, name=Bartender, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=733, name=Bartender, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=734, name=Bartender, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=735, name=Bartender, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=736, name=Emily, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=737, name=Bartender, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=738, name=Bartender, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=739, name=Bartender, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=740, name=Trufitus, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=741, name=Duke Horacio, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=742, name=Elvarg, level=83, option=[null, Attack, null, null, null], anims=[90, 79]. +NPC id=743, name=Ned, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=744, name=Klarense, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=745, name=Wormbrain, level=2, option=[Talk-to, Attack, null, null, null], anims=[6181, 6180]. +NPC id=746, name=Oracle, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=747, name=Oziach, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC (wrapper) id=748, child npcs=[6085, 6085, 6085, 6085, 6085, 6085, 6085, 6085, -1]. +NPC id=749, name=Angry barbarian spirit, level=166, option=[null, Attack, null, null, null], anims=[6729, 6730]. +NPC id=750, name=Enraged barbarian spirit, level=166, option=[null, Attack, null, null, null], anims=[6729, 6730]. +NPC id=751, name=Berserk barbarian spirit, level=166, option=[null, Attack, null, null, null], anims=[6729, 6730]. +NPC id=752, name=Ferocious barbarian spirit, level=166, option=[null, Attack, null, null, null], anims=[6729, 6730]. +NPC id=753, name=Melzar the Mad, level=43, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=754, name=Peaceful barbarian spirit, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=755, name=Morgan, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=756, name=Dr Harlow, level=0, option=[Talk-to, null, null, null, null], anims=[3040, -1]. +NPC id=757, name=Count Draynor, level=34, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=758, name=Fred the Farmer, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=759, name=null, level=1, option=[null, null, null, null, null], anims=[9158, 9157]. +NPC id=760, name=Kittens, level=0, option=[null, null, null, null, null], anims=[9208, 9210]. +NPC id=761, name=Kitten, level=0, option=[Pick-up, Hidden, Talk-to, Interact-with, null], anims=[9158, 9156]. +NPC id=762, name=Kitten, level=0, option=[Pick-up, Hidden, Talk-to, Interact-with, null], anims=[9158, 9156]. +NPC id=763, name=Kitten, level=0, option=[Pick-up, Hidden, Talk-to, Interact-with, null], anims=[9158, 9156]. +NPC id=764, name=Kitten, level=0, option=[Pick-up, Hidden, Talk-to, Interact-with, null], anims=[9158, 9156]. +NPC id=765, name=Kitten, level=0, option=[Pick-up, Hidden, Talk-to, Interact-with, null], anims=[9158, 9156]. +NPC id=766, name=Kitten, level=0, option=[Pick-up, Hidden, Talk-to, Interact-with, null], anims=[9158, 9156]. +NPC id=767, name=Crate, level=0, option=[Search, null, null, null, null], anims=[-1, -1]. +NPC id=768, name=Cat, level=0, option=[Pick-up, null, Talk-to, Interact-with, null], anims=[9158, 9157]. +NPC id=769, name=Cat, level=0, option=[Pick-up, null, Talk-to, Interact-with, null], anims=[9158, 9157]. +NPC id=770, name=Cat, level=0, option=[Pick-up, null, Talk-to, Interact-with, null], anims=[9158, 9157]. +NPC id=771, name=Cat, level=0, option=[Pick-up, null, Talk-to, Interact-with, null], anims=[9158, 9157]. +NPC id=772, name=Cat, level=0, option=[Pick-up, null, Talk-to, Interact-with, null], anims=[9158, 9157]. +NPC id=773, name=Cat, level=0, option=[Pick-up, null, Talk-to, Interact-with, null], anims=[9158, 9157]. +NPC id=774, name=Overgrown cat, level=0, option=[Pick-up, null, Talk-to, Interact-with, null], anims=[9158, 9157]. +NPC id=775, name=Overgrown cat, level=0, option=[Pick-up, null, Talk-to, Interact-with, null], anims=[9158, 9157]. +NPC id=776, name=Overgrown cat, level=0, option=[Pick-up, null, Talk-to, Interact-with, null], anims=[9158, 9157]. +NPC id=777, name=Overgrown cat, level=0, option=[Pick-up, null, Talk-to, Interact-with, null], anims=[9158, 9157]. +NPC id=778, name=Overgrown cat, level=0, option=[Pick-up, null, Talk-to, Interact-with, null], anims=[9158, 9157]. +NPC id=779, name=Overgrown cat, level=0, option=[Pick-up, null, Talk-to, Interact-with, null], anims=[9158, 9157]. +NPC id=780, name=Gertrude, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=781, name=Shilop, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=782, name=Philop, level=0, option=[Talk-to, null, null, null, null], anims=[7163, -1]. +NPC id=783, name=Wilough, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=784, name=Kanel, level=0, option=[Talk-to, null, null, null, null], anims=[7164, -1]. +NPC id=785, name=Civilian, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=786, name=Civilian, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=787, name=Civilian, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=788, name=Garv, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=789, name=Grubor, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=790, name=Letham, level=111, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=791, name=Seth, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=792, name=Grip, level=22, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=793, name=Alfonse the waiter, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=794, name=Charlie the cook, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=795, name=Ice Queen, level=111, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=796, name=Achietties, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=797, name=Helemos, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=798, name=Velrak the explorer, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=799, name=Pirate Guard, level=19, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=800, name=Fishing spot, level=0, option=[Bait, null, hidden, null, null], anims=[525, 525]. +NPC id=801, name=Abbot Langley, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=802, name=Brother Jered, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=803, name=Monk, level=5, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=804, name=Tanner, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=805, name=Master Crafter, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=806, name=Donovan the Family Handyman, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=807, name=Pierre, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=808, name=Hobbes, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=809, name=Louisa, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=810, name=Mary, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=811, name=Stanford, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=812, name=Guard, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=813, name=Gossip, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=814, name=Anna, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=815, name=Bob, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=816, name=Carol, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=817, name=David, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=818, name=Elizabeth, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=819, name=Frank, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=820, name=Poison Salesman, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=821, name=Sinclair Guard dog, level=0, option=[null, null, null, null, null], anims=[6561, 6560]. +NPC id=822, name=Ana, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=823, name=Ana, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=824, name=Female slave, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=825, name=Male slave, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=826, name=Escaping slave, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=827, name=Rowdy slave, level=10, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=828, name=Shanty Claws, level=0, option=[Talk-to, null, null, null, null], anims=[4738, 4740]. +NPC (wrapper) id=829, child npcs=[5017, 5018, 5019, -1]. +NPC id=830, name=Mercenary Captain, level=47, option=[Talk-to, Attack, Watch, null, null], anims=[808, -1]. +NPC id=831, name=Captain Siad, level=0, option=[Talk-to, null, null, null, null], anims=[1953, -1]. +NPC id=832, name=Al Shabim, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=833, name=Bedabin Nomad, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=834, name=Bedabin Nomad Guard, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=835, name=Irena, level=0, option=[Talk-to, null, null, null, null], anims=[2702, -1]. +NPC id=836, name=Shantay, level=0, option=[Talk-to, null, Trade, Buy-pass, null], anims=[808, -1]. +NPC id=837, name=Shantay Guard, level=22, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=838, name=Shantay Guard, level=22, option=[Talk-to, null, Bribe, null, null], anims=[808, -1]. +NPC id=839, name=Desert Wolf, level=27, option=[null, Attack, null, null, null], anims=[6580, 6556]. +NPC id=840, name=Ugthanki, level=42, option=[Talk-to, Attack, null, null, null], anims=[51, 45]. +NPC id=841, name=Mine cart driver, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=842, name=Rowdy Guard, level=43, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=843, name=RPDT employee, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC (wrapper) id=844, child npcs=[2328, -1]. +NPC id=845, name=Horacio, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=846, name=Kangai Mau, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=847, name=Head chef, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=848, name=Blurberry, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=849, name=Barman, level=0, option=[Talk-to, null, Trade, null, null], anims=[195, 189]. +NPC id=850, name=Aluft Gianne snr., level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=851, name=Gnome Waiter, level=0, option=[Talk-to, null, Trade, null, null], anims=[195, 189]. +NPC id=852, name=Ogre chieftain, level=81, option=[Talk-to, Attack, null, null, null], anims=[357, 358]. +NPC id=853, name=Og, level=0, option=[Talk-to, null, null, null, null], anims=[357, 358]. +NPC id=854, name=Grew, level=0, option=[Talk-to, null, null, null, null], anims=[357, 358]. +NPC id=855, name=Toban, level=0, option=[Talk-to, null, null, null, null], anims=[357, 358]. +NPC id=856, name=Gorad, level=68, option=[Talk-to, Attack, null, null, null], anims=[357, 358]. +NPC id=857, name=Ogre guard, level=0, option=[Talk-to, null, null, null, null], anims=[357, 358]. +NPC id=858, name=Ogre guard, level=0, option=[Talk-to, null, null, null, null], anims=[357, 358]. +NPC id=859, name=Ogre guard, level=0, option=[Talk-to, null, null, null, null], anims=[357, 358]. +NPC id=860, name=Ogre guard, level=0, option=[Talk-to, null, null, null, null], anims=[357, 358]. +NPC id=861, name=Ogre guard, level=0, option=[Talk-to, null, null, null, null], anims=[357, 358]. +NPC id=862, name=City guard, level=83, option=[Talk-to, Attack, null, null, null], anims=[357, 358]. +NPC id=863, name=Scared skavid, level=0, option=[Talk-to, null, null, null, null], anims=[257, 254]. +NPC id=864, name=Mad skavid, level=0, option=[Talk-to, null, null, null, null], anims=[257, 254]. +NPC id=865, name=Skavid, level=0, option=[Talk-to, null, null, null, null], anims=[257, 254]. +NPC id=866, name=Skavid, level=0, option=[Talk-to, null, null, null, null], anims=[257, 254]. +NPC id=867, name=Skavid, level=0, option=[Talk-to, null, null, null, null], anims=[257, 254]. +NPC id=868, name=Skavid, level=0, option=[Talk-to, null, null, null, null], anims=[257, 254]. +NPC id=869, name=Skavid, level=0, option=[Talk-to, null, null, null, null], anims=[257, 254]. +NPC id=870, name=Enclave guard, level=83, option=[Talk-to, Attack, null, null, null], anims=[357, 358]. +NPC id=871, name=Ogre shaman, level=113, option=[Talk-to, Attack, null, null, null], anims=[357, 358]. +NPC id=872, name=Watchtower Wizard, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=873, name=Ogre trader, level=0, option=[Talk-to, null, Trade, null, null], anims=[357, 358]. +NPC id=874, name=Ogre merchant, level=0, option=[Talk-to, null, Trade, null, null], anims=[357, 358]. +NPC id=875, name=Ogre trader, level=0, option=[Talk-to, null, Trade, null, null], anims=[357, 358]. +NPC id=876, name=Ogre trader, level=0, option=[Talk-to, null, Trade, null, null], anims=[357, 358]. +NPC id=877, name=Tower guard, level=28, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=878, name=Colonel Radick, level=38, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=879, name=Delrith, level=27, option=[null, Attack, null, null, null], anims=[66, 63]. +NPC id=880, name=Weakened Delrith, level=1, option=[Banish, null, null, null, null], anims=[4619, 63]. +NPC id=881, name=Traiborn, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=882, name=Gypsy Aris, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=883, name=Sir Prysin, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=884, name=Captain Rovin, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=885, name=Ceril Carnillean, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=886, name=Claus the chef, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=887, name=Guard, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=888, name=Philipe Carnillean, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=889, name=Henryeta Carnillean, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=890, name=Butler Jones, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=891, name=Alomone, level=13, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=892, name=Hazeel, level=296, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=893, name=Clivet, level=13, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=894, name=Hazeel Cultist, level=13, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=895, name=Boy, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=896, name=Nora T. Hagg, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=897, name=Witch's experiment, level=19, option=[null, Attack, null, null, null], anims=[257, 254]. +NPC id=898, name=Witch's experiment (second form), level=30, option=[null, Attack, null, null, null], anims=[5326, 5325]. +NPC id=899, name=Witch's experiment (third form), level=42, option=[null, Attack, null, null, null], anims=[4919, 4923]. +NPC id=900, name=Witch's experiment (fourth form), level=53, option=[null, Attack, null, null, null], anims=[6580, 6556]. +NPC id=901, name=Mouse, level=0, option=[null, null, null, null, null], anims=[242, 239]. +NPC id=902, name=Gundai, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[808, -1]. +NPC id=903, name=Lundail, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=904, name=Chamber guardian, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=905, name=Kolodion, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=906, name=Kolodion, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=907, name=Kolodion, level=0, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=908, name=Kolodion, level=0, option=[null, Attack, null, null, null], anims=[130, 127]. +NPC id=909, name=Kolodion, level=0, option=[null, Attack, null, null, null], anims=[5318, 5317]. +NPC id=910, name=Kolodion, level=0, option=[null, Attack, null, null, null], anims=[842, 841]. +NPC id=911, name=Kolodion, level=112, option=[null, Attack, null, null, null], anims=[66, 63]. +NPC id=912, name=Battle mage, level=54, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=913, name=Battle mage, level=54, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=914, name=Battle mage, level=54, option=[null, Attack, null, null, null], anims=[195, 189]. +NPC id=915, name=Leela, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=916, name=Joe, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=917, name=Jail guard, level=26, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=918, name=Ned, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=919, name=Lady Keli, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=920, name=Prince Ali, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=921, name=Prince Ali, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=922, name=Aggie, level=0, option=[Talk-to, null, Make-dyes, null, null], anims=[808, -1]. +NPC id=923, name=Hassan, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=924, name=Osman, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=925, name=Border Guard, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=926, name=Border Guard, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=927, name=Fishing spot, level=0, option=[Lure, null, Bait, hidden, hidden], anims=[447, 448]. +NPC id=928, name=Gujuo, level=0, option=[Talk-to, Hidden, null, null, null], anims=[813, -1]. +NPC id=929, name=Ungadulu, level=70, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=930, name=Ungadulu, level=169, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=931, name=Jungle savage, level=90, option=[null, Attack, null, null, null], anims=[813, -1]. +NPC id=932, name=Fionella, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=933, name=Siegfried Erkle, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=934, name=Nezikchened, level=187, option=[null, Attack, null, null, null], anims=[66, 63]. +NPC id=935, name=Viyeldi, level=79, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=936, name=San Tojalon, level=106, option=[Talk-to, Attack, null, null, null], anims=[5483, 5481]. +NPC id=937, name=Irvig Senay, level=100, option=[Talk-to, Attack, null, null, null], anims=[5483, 5481]. +NPC id=938, name=Ranalph Devere, level=92, option=[Talk-to, Attack, null, null, null], anims=[5483, 5481]. +NPC id=939, name=Boulder, level=0, option=[Push, null, null, null, null], anims=[-1, 6]. +NPC id=940, name=Echned Zekin, level=187, option=[Talk-to, null, null, null, null], anims=[5538, 5539]. +NPC id=941, name=Green dragon, level=79, option=[null, Attack, null, null, null], anims=[90, 79]. +NPC id=942, name=Master Chef, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=943, name=Survival Expert, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=944, name=Combat Instructor, level=146, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=945, name=RuneScape Guide, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=946, name=Magic Instructor, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=947, name=Financial Advisor, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=948, name=Mining Instructor, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=949, name=Quest Guide, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=950, name=Giant rat, level=3, option=[null, Attack, null, null, null], anims=[4932, 4931]. +NPC id=951, name=Chicken, level=3, option=[null, Attack, null, null, null], anims=[5386, 5385]. +NPC id=952, name=Fishing spot, level=0, option=[Net, null, hidden, null, null], anims=[447, 448]. +NPC id=953, name=Banker, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=954, name=Brother Brace, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=955, name=Cow, level=2, option=[null, Attack, null, null, null], anims=[5852, 5848]. +NPC id=956, name=Drunken Dwarf, level=0, option=[Talk-to, null, null, null, null], anims=[900, 104]. +NPC id=957, name=Mubariz, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=958, name=Fadli, level=0, option=[Talk-to, null, Bank, Collect, Buy], anims=[808, -1]. +NPC id=959, name=A'abla, level=0, option=[Talk-to, null, Heal, null, null], anims=[808, -1]. +NPC id=960, name=Sabreen, level=0, option=[Talk-to, null, Heal, null, null], anims=[808, -1]. +NPC id=961, name=Surgeon General Tafani, level=0, option=[Talk-to, null, Heal, null, null], anims=[808, -1]. +NPC id=962, name=Jaraah, level=0, option=[Talk-to, null, Heal, null, null], anims=[808, -1]. +NPC id=963, name=Zahwa, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=964, name=Ima, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=965, name=Sabeil, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=966, name=Jadid, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=967, name=Dalal, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=968, name=Afrah, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=969, name=Jeed, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=970, name=Diango, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=971, name=Chadwell, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=972, name=Koftik, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=973, name=Koftik, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=974, name=Koftik, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=975, name=Koftik, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=976, name=Koftik, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=977, name=Blessed spider, level=39, option=[null, Attack, null, null, null], anims=[5326, 5325]. +NPC id=978, name=Blessed giant rat, level=9, option=[null, Attack, null, null, null], anims=[4932, 4931]. +NPC id=979, name=Slave, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=980, name=Slave, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=981, name=Slave, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=982, name=Slave, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=983, name=Slave, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=984, name=Slave, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=985, name=Slave, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=986, name=Boulder, level=0, option=[Push, null, null, null, null], anims=[-1, 6]. +NPC id=987, name=Unicorn, level=15, option=[null, null, null, null, null], anims=[291, 288]. +NPC id=988, name=Sir Jerro, level=62, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=989, name=Sir Carl, level=62, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=990, name=Sir Harry, level=62, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=991, name=Half-soulless, level=1, option=[null, null, null, null, null], anims=[800, 800]. +NPC id=992, name=Kardia, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=993, name=Witch's cat, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[9158, 9157]. +NPC id=994, name=Niloof, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=995, name=Klank, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=996, name=Kamen, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=997, name=Kalrag, level=89, option=[null, Attack, null, null, null], anims=[5318, 5317]. +NPC id=998, name=Othainian, level=91, option=[null, Attack, null, null, null], anims=[66, 63]. +NPC id=999, name=Doomion, level=91, option=[null, Attack, null, null, null], anims=[66, 63]. +NPC id=1000, name=Holthion, level=91, option=[null, Attack, null, null, null], anims=[66, 63]. +NPC id=1001, name=Dark mage, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1002, name=Disciple of Iban, level=13, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=1003, name=Lord Iban, level=0, option=[null, null, null, null, null], anims=[346, -1]. +NPC id=1004, name=Spider, level=1, option=[null, Attack, null, null, null], anims=[6247, 6248]. +NPC id=1005, name=Giant bat, level=0, option=[null, null, null, null, null], anims=[4914, 4913]. +NPC id=1006, name=Sea slug, level=0, option=[Take, null, null, null, null], anims=[932, 933]. +NPC id=1007, name=Zamorak wizard, level=65, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=1008, name=Hamid, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1009, name=Poison spider, level=31, option=[null, Attack, null, null, null], anims=[5326, 5325]. +NPC id=1010, name=Rantz, level=0, option=[Talk-to, null, null, null, null], anims=[357, 358]. +NPC id=1011, name=Fycie, level=0, option=[Talk, null, null, null, null], anims=[357, 358]. +NPC id=1012, name=Bugs, level=0, option=[Talk, null, null, null, null], anims=[357, 358]. +NPC id=1013, name=Swamp toad, level=0, option=[null, null, null, null, null], anims=[1018, 1021]. +NPC id=1014, name=Bloated Toad, level=0, option=[null, null, null, null, null], anims=[1020, 1020]. +NPC id=1015, name=Iron pickaxe, level=0, option=[Take, null, null, null, null], anims=[1445, 181]. +NPC id=1016, name=Chompy bird, level=0, option=[null, null, null, Pluck, null], anims=[6768, 6768]. +NPC id=1017, name=Chicken, level=1, option=[null, Attack, null, null, null], anims=[5386, 5385]. +NPC id=1018, name=Rooster, level=3, option=[null, Attack, null, null, null], anims=[5386, 5385]. +NPC id=1019, name=Fire elemental, level=35, option=[null, Attack, null, null, null], anims=[1027, 1028]. +NPC id=1020, name=Earth elemental, level=35, option=[null, Attack, null, null, null], anims=[4866, 4867]. +NPC id=1021, name=Air elemental, level=34, option=[null, Attack, null, null, null], anims=[1039, 1039]. +NPC id=1022, name=Water elemental, level=34, option=[null, Attack, null, null, null], anims=[1045, 1047]. +NPC id=1023, name=Vampire, level=72, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=1024, name=null, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=1025, name=null, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=1026, name=null, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=1027, name=null, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=1028, name=Baby impling, level=0, option=[Catch, null, null, null, null], anims=[6613, 6614]. +NPC id=1029, name=Young impling, level=0, option=[Catch, null, null, null, null], anims=[6613, 6614]. +NPC id=1030, name=Gourmet impling, level=0, option=[Catch, null, null, null, null], anims=[6613, 6614]. +NPC id=1031, name=Earth impling, level=0, option=[Catch, null, null, null, null], anims=[6613, 6614]. +NPC id=1032, name=Essence impling, level=0, option=[Catch, null, null, null, null], anims=[6613, 6614]. +NPC id=1033, name=Eclectic impling, level=0, option=[Catch, null, null, null, null], anims=[6613, 6614]. +NPC id=1034, name=Nature impling, level=0, option=[Catch, null, null, null, null], anims=[6613, 6614]. +NPC id=1035, name=Magpie impling, level=0, option=[Catch, null, null, null, null], anims=[6613, 6614]. +NPC id=1036, name=Banker, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[808, 808]. +NPC id=1037, name=Prissy Scilla, level=0, option=[Talk-to, null, Pay, null, null], anims=[195, 189]. +NPC id=1038, name=Rufus, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=1039, name=Barker, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=1040, name=Fidelio, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=1041, name=Sbott, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=1042, name=Roavar, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=1043, name=Will o' the wisp, level=0, option=[null, null, null, null, null], anims=[1071, 1071]. +NPC id=1044, name=Monk of Zamorak, level=22, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=1045, name=Monk of Zamorak, level=17, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=1046, name=Monk of Zamorak, level=30, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC (wrapper) id=1047, child npcs=[7707, -1]. +NPC id=1048, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=1049, name=Drezel, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1050, name=Filliman Tarlock, level=0, option=[Talk-to, null, null, null, null], anims=[842, 841]. +NPC id=1051, name=Nature Spirit, level=0, option=[Talk-to, null, null, null, null], anims=[842, 841]. +NPC id=1052, name=Ghast, level=0, option=[null, null, null, null, null], anims=[1092, 1091]. +NPC id=1053, name=Ghast, level=30, option=[null, Attack, null, null, null], anims=[1086, 1085]. +NPC id=1054, name=Ulizius, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1055, name=Pirate Jackie the Fruit, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=1056, name=Mime, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=1057, name=Strange watcher, level=0, option=[null, null, null, null, null], anims=[1137, -1]. +NPC id=1058, name=Strange watcher, level=0, option=[null, null, null, null, null], anims=[1137, -1]. +NPC id=1059, name=Strange watcher, level=0, option=[null, null, null, null, null], anims=[1137, -1]. +NPC id=1060, name=Denulth, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1061, name=Sergeant, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1062, name=Sergeant, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1063, name=Soldier, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1064, name=Soldier, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1065, name=Soldier, level=48, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=1066, name=Soldier, level=0, option=[Talk-to, null, null, null, null], anims=[1144, -1]. +NPC id=1067, name=Soldier, level=0, option=[Talk-to, null, null, null, null], anims=[1144, -1]. +NPC id=1068, name=Soldier, level=0, option=[Talk-to, null, null, null, null], anims=[1144, -1]. +NPC id=1069, name=Soldier, level=0, option=[Talk-to, null, null, null, null], anims=[1147, -1]. +NPC id=1070, name=Saba, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1071, name=Tenzing, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=1072, name=Eadburg, level=4, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=1073, name=Archer, level=42, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=1074, name=Archer, level=42, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=1075, name=Archer, level=42, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=1076, name=Guard, level=37, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=1077, name=Guard, level=37, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=1078, name=Harold, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1079, name=Tostig, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=1080, name=Eohric, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1081, name=Servant, level=5, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=1082, name=Dunstan, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1083, name=Wistan, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=1084, name=Breoca, level=5, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=1085, name=Ocga, level=5, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=1086, name=Man, level=2, option=[Talk-to, Attack, Pickpocket, null, null], anims=[813, -1]. +NPC id=1087, name=Penda, level=5, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=1088, name=Hygd, level=4, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=1089, name=Ceolburg, level=4, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=1090, name=Hild, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1091, name=Bob, level=0, option=[Talk-to, null, null, null, null], anims=[9158, 9157]. +NPC id=1092, name=White Knight, level=36, option=[Talk-to, Attack, null, null, null], anims=[7047, -1]. +NPC id=1093, name=Billy, level=0, option=[null, null, null, null, null], anims=[5339, 5340]. +NPC id=1094, name=Mountain goat, level=0, option=[null, null, null, null, null], anims=[5339, 5340]. +NPC id=1095, name=Rock, level=111, option=[null, Attack, null, null, null], anims=[927, 1141]. +NPC id=1096, name=Stick, level=104, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=1097, name=Pee Hat, level=91, option=[null, Attack, null, null, null], anims=[926, 1139]. +NPC id=1098, name=Kraka, level=91, option=[null, Attack, null, null, null], anims=[926, 1139]. +NPC id=1099, name=Dung, level=0, option=[null, null, null, null, null], anims=[286, 283]. +NPC id=1100, name=Ash, level=0, option=[null, null, null, null, null], anims=[286, 283]. +NPC id=1101, name=Thrower Troll, level=67, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=1102, name=Thrower Troll, level=67, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=1103, name=Thrower Troll, level=67, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=1104, name=Thrower Troll, level=67, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=1105, name=Thrower Troll, level=67, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=1106, name=Mountain troll, level=69, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=1107, name=Mountain troll, level=69, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=1108, name=Mountain troll, level=69, option=[null, Attack, null, null, null], anims=[926, 1139]. +NPC id=1109, name=Mountain troll, level=69, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=1110, name=Mountain troll, level=69, option=[null, Attack, null, null, null], anims=[926, 1139]. +NPC id=1111, name=Mountain troll, level=69, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=1112, name=Mountain troll, level=69, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=1113, name=Eadgar, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1114, name=Godric, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1115, name=Troll general, level=113, option=[null, Attack, null, null, null], anims=[927, 1141]. +NPC id=1116, name=Troll general, level=113, option=[null, Attack, null, null, null], anims=[926, 1139]. +NPC id=1117, name=Troll general, level=113, option=[null, Attack, null, null, null], anims=[926, 1139]. +NPC id=1118, name=Troll spectator, level=71, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=1119, name=Troll spectator, level=71, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=1120, name=Troll spectator, level=71, option=[null, Attack, null, null, null], anims=[926, 1139]. +NPC id=1121, name=Troll spectator, level=71, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=1122, name=Troll spectator, level=71, option=[null, Attack, null, null, null], anims=[926, 1139]. +NPC id=1123, name=Troll spectator, level=71, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=1124, name=Troll spectator, level=71, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=1125, name=Dad, level=101, option=[Talk-to, Attack, null, null, null], anims=[925, 1140]. +NPC id=1126, name=Twig, level=71, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=1127, name=Berry, level=71, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=1128, name=Twig, level=71, option=[null, Attack, Pickpocket, null, null], anims=[1159, 283]. +NPC id=1129, name=Berry, level=71, option=[null, Attack, Pickpocket, null, null], anims=[1159, 283]. +NPC id=1130, name=Thrower troll, level=68, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=1131, name=Thrower troll, level=68, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=1132, name=Thrower troll, level=68, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=1133, name=Thrower troll, level=68, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=1134, name=Thrower troll, level=68, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=1135, name=Cook, level=0, option=[null, null, null, null, null], anims=[286, 283]. +NPC id=1136, name=Cook, level=0, option=[null, null, null, null, null], anims=[286, 283]. +NPC id=1137, name=Cook, level=0, option=[null, null, null, null, null], anims=[286, 283]. +NPC id=1138, name=Mountain troll, level=71, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=1139, name=Mushroom, level=0, option=[null, null, null, null, null], anims=[1159, 283]. +NPC id=1140, name=Mountain goat, level=0, option=[null, null, null, null, null], anims=[5339, 5340]. +NPC id=1141, name=Mountain goat, level=0, option=[null, null, null, null, null], anims=[5339, 5340]. +NPC id=1142, name=Guard, level=0, option=[null, null, null, null, null], anims=[286, 283]. +NPC id=1143, name=Guard, level=0, option=[null, null, null, null, null], anims=[286, 283]. +NPC id=1144, name=Guard, level=0, option=[null, null, null, null, null], anims=[286, 283]. +NPC id=1145, name=Guard, level=0, option=[null, null, null, null, null], anims=[286, 283]. +NPC id=1146, name=Guard, level=0, option=[null, null, null, null, null], anims=[286, 283]. +NPC id=1147, name=Guard, level=0, option=[null, null, null, null, null], anims=[286, 283]. +NPC id=1148, name=Guard, level=0, option=[null, null, null, null, null], anims=[286, 283]. +NPC id=1149, name=Guard, level=0, option=[null, null, null, null, null], anims=[286, 283]. +NPC id=1150, name=Guard, level=0, option=[null, null, null, null, null], anims=[286, 283]. +NPC id=1151, name=Burntmeat, level=0, option=[Talk-to, null, null, null, null], anims=[286, 283]. +NPC id=1152, name=Weird Old Man, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1153, name=Kalphite Worker, level=28, option=[null, Attack, null, null, null], anims=[6218, 6220]. +NPC id=1154, name=Kalphite Soldier, level=85, option=[null, Attack, null, null, null], anims=[6218, 6220]. +NPC id=1155, name=Kalphite Guardian, level=141, option=[null, Attack, null, null, null], anims=[6219, 6222]. +NPC id=1156, name=Kalphite Worker, level=28, option=[null, Attack, null, null, null], anims=[6218, 6220]. +NPC id=1157, name=Kalphite Guardian, level=141, option=[null, Attack, null, null, null], anims=[6219, 6222]. +NPC id=1158, name=Kalphite Queen, level=333, option=[null, Attack, null, null, null], anims=[6239, 6238]. +NPC id=1159, name=Kalphite Queen, level=333, option=[null, null, null, null, null], anims=[1183, 1189]. +NPC id=1160, name=Kalphite Queen, level=333, option=[null, Attack, null, null, null], anims=[6236, 6236]. +NPC id=1161, name=Kalphite Larva, level=0, option=[null, null, null, null, null], anims=[6218, 6221]. +NPC id=1162, name=Timfraku, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=1163, name=Tiadeche, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1164, name=Tiadeche, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=1165, name=Tinsay, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=1166, name=Tinsay, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=1167, name=Tamayu, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=1168, name=Tamayu, level=0, option=[Talk-to, null, Trade, null, null], anims=[813, -1]. +NPC id=1169, name=Tamayu, level=0, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=1170, name=Tamayu, level=0, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=1171, name=Lubufu, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1172, name=The Shaikahan, level=83, option=[null, Attack, null, null, null], anims=[1198, 1197]. +NPC id=1173, name=The Shaikahan, level=83, option=[null, null, null, null, null], anims=[1198, 1197]. +NPC id=1174, name=Fishing spot, level=0, option=[Net, null, null, hidden, null], anims=[447, 448]. +NPC id=1175, name=Fishing spot, level=0, option=[Net, null, null, hidden, null], anims=[447, 448]. +NPC id=1176, name=Fishing spot, level=0, option=[Fish, null, null, null, null], anims=[447, 448]. +NPC id=1177, name=Fishing spot, level=0, option=[Fish, null, null, null, null], anims=[447, 448]. +NPC id=1178, name=Fishing spot, level=0, option=[Fish, null, null, null, null], anims=[447, 448]. +NPC id=1179, name=Gull, level=0, option=[null, null, null, null, null], anims=[6771, 6773]. +NPC id=1180, name=Cormorant, level=0, option=[null, null, null, null, null], anims=[6772, 6774]. +NPC id=1181, name=Pelican, level=0, option=[null, null, null, null, null], anims=[6772, 6774]. +NPC id=1182, name=Lord Iorwerth, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1183, name=Elf warrior, level=90, option=[null, Attack, null, null, null], anims=[813, -1]. +NPC id=1184, name=Elf warrior, level=108, option=[null, Attack, null, null, null], anims=[813, -1]. +NPC id=1185, name=Elven city guard, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=1186, name=Idris, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1187, name=Essyllt, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1188, name=Morvran, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1189, name=Fishing spot, level=0, option=[Lure, null, Bait, hidden, hidden], anims=[447, 448]. +NPC id=1190, name=Fishing spot, level=0, option=[Lure, null, Bait, hidden, hidden], anims=[447, 448]. +NPC id=1191, name=Fishing spot, level=0, option=[Net, null, Harpoon, hidden, hidden], anims=[447, 448]. +NPC id=1192, name=Rabbit, level=2, option=[null, Attack, null, null, null], anims=[6089, 6088]. +NPC id=1193, name=Rabbit, level=2, option=[null, Attack, null, null, null], anims=[6089, 6088]. +NPC id=1194, name=Rabbit, level=2, option=[null, Attack, null, null, null], anims=[6089, 6088]. +NPC id=1195, name=Grizzly bear, level=42, option=[null, Attack, null, null, null], anims=[4919, 4923]. +NPC id=1196, name=Grizzly bear cub, level=33, option=[null, Attack, null, null, null], anims=[4920, 4924]. +NPC id=1197, name=Grizzly bear cub, level=36, option=[null, Attack, null, null, null], anims=[4920, 4924]. +NPC id=1198, name=Dire Wolf, level=88, option=[null, Attack, null, null, null], anims=[6580, 6556]. +NPC id=1199, name=Elf Tracker, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1200, name=Tyras guard, level=110, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=1201, name=Elf warrior, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=1202, name=Arianwyn, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1203, name=Tyras guard, level=110, option=[Talk-to, Attack, null, null, null], anims=[813, -1]. +NPC id=1204, name=Tyras guard, level=110, option=[Talk-to, Attack, null, null, null], anims=[813, -1]. +NPC id=1205, name=null, level=1, option=[null, null, null, null, null], anims=[8705, 2769]. +NPC id=1206, name=Tyras guard, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=1207, name=null, level=1, option=[null, null, null, null, null], anims=[8707, 2769]. +NPC id=1208, name=Quartermaster, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1209, name=Koftik, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1210, name=Kings messenger, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1211, name=Will o' the wisp, level=0, option=[null, null, null, null, null], anims=[1071, 1071]. +NPC id=1212, name=Will o' the wisp, level=0, option=[null, null, null, null, null], anims=[1071, 1071]. +NPC id=1213, name=Tegid, level=0, option=[Talk-to, null, null, null, null], anims=[8501, -1]. +NPC id=1214, name=Thistle, level=0, option=[Pick, null, null, null, null], anims=[-1, -1]. +NPC id=1215, name=Parrots, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=1216, name=Parroty Pete, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1217, name=Gardener, level=4, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=1218, name=Ghoul, level=42, option=[null, Attack, null, null, null], anims=[1275, -1]. +NPC id=1219, name=Leech, level=52, option=[null, Attack, null, null, null], anims=[1270, 1269]. +NPC id=1220, name=Vampire, level=72, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=1221, name=Spider, level=0, option=[null, null, null, null, null], anims=[6247, 6248]. +NPC id=1222, name=Mist, level=1, option=[null, null, null, null, null], anims=[1261, 1261]. +NPC id=1223, name=Vampire, level=61, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=1224, name=Vampyric hound, level=1, option=[null, null, null, null, null], anims=[6580, 6556]. +NPC id=1225, name=Vampire, level=25, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=1226, name=Tree, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=1227, name=Myre Blamish Snail, level=9, option=[null, Attack, null, null, null], anims=[1276, 1274]. +NPC id=1228, name=Blood Blamish Snail, level=20, option=[null, Attack, null, null, null], anims=[1276, 1274]. +NPC id=1229, name=Ochre Blamish Snail, level=10, option=[null, Attack, null, null, null], anims=[1276, 1274]. +NPC id=1230, name=Bruise Blamish Snail, level=20, option=[null, Attack, null, null, null], anims=[1276, 1274]. +NPC id=1231, name=Bark Blamish Snail, level=15, option=[null, Attack, null, null, null], anims=[1276, 1274]. +NPC id=1232, name=Myre Blamish Snail, level=10, option=[null, Attack, null, null, null], anims=[1276, 1274]. +NPC id=1233, name=Blood Blamish Snail, level=20, option=[null, Attack, null, null, null], anims=[1276, 1274]. +NPC id=1234, name=Ochre Blamish Snail, level=15, option=[null, Attack, null, null, null], anims=[1276, 1274]. +NPC id=1235, name=Bruise Blamish Snail, level=20, option=[null, Attack, null, null, null], anims=[1276, 1274]. +NPC id=1236, name=Fishing spot, level=0, option=[Bait, null, hidden, null, hidden], anims=[447, 448]. +NPC id=1237, name=Fishing spot, level=0, option=[Bait, null, hidden, null, hidden], anims=[447, 448]. +NPC id=1238, name=Fishing spot, level=0, option=[Bait, null, hidden, null, hidden], anims=[447, 448]. +NPC id=1239, name=Bedabin Nomad Fighter, level=56, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=1240, name=Loar Shadow, level=40, option=[null, Attack, null, null, null], anims=[1290, 1289]. +NPC id=1241, name=Loar Shade, level=40, option=[null, Attack, null, null, null], anims=[1282, 1281]. +NPC id=1242, name=Shade Spirit, level=0, option=[null, null, null, null, null], anims=[1308, 1308]. +NPC id=1243, name=Phrin Shadow, level=60, option=[null, Attack, null, null, null], anims=[1290, 1289]. +NPC id=1244, name=Phrin Shade, level=60, option=[null, Attack, null, null, null], anims=[1282, 1281]. +NPC id=1245, name=Riyl Shadow, level=80, option=[null, Attack, null, null, null], anims=[1290, 1289]. +NPC id=1246, name=Riyl Shade, level=80, option=[null, Attack, null, null, null], anims=[1282, 1281]. +NPC id=1247, name=Asyn Shadow, level=100, option=[null, Attack, null, null, null], anims=[1290, 1289]. +NPC id=1248, name=Asyn Shade, level=100, option=[null, Attack, null, null, null], anims=[1282, 1281]. +NPC id=1249, name=Fiyr Shadow, level=120, option=[null, Attack, null, null, null], anims=[1290, 1289]. +NPC id=1250, name=Fiyr Shade, level=120, option=[null, Attack, null, null, null], anims=[1282, 1281]. +NPC id=1251, name=Afflicted(Ulsquire), level=0, option=[Talk-to, null, null, null, null], anims=[808, 1306]. +NPC id=1252, name=Ulsquire Shauncy, level=0, option=[Talk-to, null, null, null, null], anims=[808, 819]. +NPC id=1253, name=Afflicted(Razmire), level=0, option=[Talk-to, null, null, null, null], anims=[808, 1306]. +NPC id=1254, name=Razmire Keelgan, level=0, option=[Talk-to, null, Trade-General-Store, Trade-Builders-Store, null], anims=[808, 819]. +NPC id=1255, name=Mort'ton Local, level=0, option=[Talk-to, null, null, null, null], anims=[808, 819]. +NPC id=1256, name=Mort'ton Local, level=0, option=[Talk-to, null, null, null, null], anims=[808, 819]. +NPC id=1257, name=Afflicted, level=37, option=[Talk-to, Attack, null, null, null], anims=[808, 1306]. +NPC id=1258, name=Afflicted, level=34, option=[Talk-to, Attack, null, null, null], anims=[808, 1306]. +NPC id=1259, name=Mort'ton local, level=0, option=[Talk-to, null, null, null, null], anims=[808, 819]. +NPC id=1260, name=Mort'ton local, level=0, option=[Talk-to, null, null, null, null], anims=[808, 819]. +NPC id=1261, name=Afflicted, level=32, option=[Talk-to, Attack, null, null, null], anims=[808, 1306]. +NPC id=1262, name=Afflicted, level=30, option=[Talk-to, Attack, null, null, null], anims=[808, 1306]. +NPC id=1263, name=Wizard, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1264, name=Saradomin wizard, level=108, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=1265, name=Rock Crab, level=13, option=[null, Attack, null, null, null], anims=[1310, 1311]. +NPC id=1266, name=Rocks, level=0, option=[null, null, null, null, null], anims=[1315, 1311]. +NPC id=1267, name=Rock Crab, level=13, option=[null, Attack, null, null, null], anims=[1310, 1311]. +NPC id=1268, name=Rocks, level=0, option=[null, null, null, null, null], anims=[1315, 1311]. +NPC id=1269, name=Olaf the Bard, level=0, option=[Talk-to, null, null, null, null], anims=[1318, -1]. +NPC id=1270, name=Lalli, level=0, option=[Talk-to, null, null, null, null], anims=[286, 283]. +NPC id=1271, name=Golden sheep, level=0, option=[null, null, null, null, null], anims=[5339, 5340]. +NPC id=1272, name=Golden sheep, level=0, option=[null, null, null, null, null], anims=[5345, 5344]. +NPC id=1273, name=Fossegrimen, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1274, name=Ospak, level=0, option=[Talk-to, null, null, null, null], anims=[1137, -1]. +NPC id=1275, name=Styrmir, level=0, option=[Talk-to, null, null, null, null], anims=[1137, -1]. +NPC id=1276, name=Torbrund, level=0, option=[Talk-to, null, null, null, null], anims=[1137, -1]. +NPC id=1277, name=Fridgeir, level=0, option=[Talk-to, null, null, null, null], anims=[1137, -1]. +NPC id=1278, name=Longhall Bouncer, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=1279, name=The Draugen, level=69, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=1280, name=Butterfly, level=0, option=[null, null, null, null, null], anims=[362, 362]. +NPC id=1281, name=Sigli the Huntsman, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1282, name=Sigmund The Merchant, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=1283, name=Swensen the Navigator, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=1284, name=Bjorn, level=0, option=[Talk-to, null, null, null, null], anims=[1322, -1]. +NPC id=1285, name=Eldgrim, level=0, option=[Talk-to, null, null, null, null], anims=[1322, -1]. +NPC id=1286, name=Manni the Reveller, level=0, option=[Talk-to, null, null, null, null], anims=[1322, -1]. +NPC id=1287, name=Council workman, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1288, name=Peer the Seer, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=1289, name=Thorvald the Warrior, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=1290, name=Koschei the deathless, level=0, option=[null, Attack, null, null, null], anims=[813, -1]. +NPC id=1291, name=Koschei the deathless, level=0, option=[null, Attack, null, null, null], anims=[813, -1]. +NPC id=1292, name=Koschei the deathless, level=0, option=[null, Attack, null, null, null], anims=[813, -1]. +NPC id=1293, name=Koschei the deathless, level=0, option=[null, Attack, null, null, null], anims=[813, -1]. +NPC id=1294, name=Brundt the Chieftain, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1295, name=Askeladden, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=1296, name=Guard, level=0, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=1297, name=Guard, level=0, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=1298, name=Town Guard, level=0, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=1299, name=Town Guard, level=0, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=1300, name=Thora the Barkeep, level=0, option=[Talk to, null, Trade, null, null], anims=[808, -1]. +NPC id=1301, name=Yrsa, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=1302, name=Fisherman, level=0, option=[Talk-to, null, null, null, null], anims=[623, -1]. +NPC id=1303, name=Skulgrimen, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=1304, name=Sailor, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1305, name=Agnar, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[808, -1]. +NPC id=1306, name=Freidir, level=48, option=[Talk-to, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=1307, name=Borrokar, level=48, option=[Talk-to, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=1308, name=Lanzig, level=48, option=[Talk-to, Attack, Pickpocket, null, null], anims=[813, -1]. +NPC id=1309, name=Pontak, level=48, option=[Talk-to, null, Pickpocket, null, null], anims=[813, -1]. +NPC id=1310, name=Freygerd, level=48, option=[Talk-to, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=1311, name=Lensa, level=48, option=[Talk-to, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=1312, name=Jennella, level=48, option=[Talk-to, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=1313, name=Sassilik, level=48, option=[Talk-to, null, Pickpocket, null, null], anims=[808, -1]. +NPC id=1314, name=Inga, level=48, option=[Talk-to, null, Pickpocket, null, null], anims=[808, -1]. +NPC id=1315, name=Fish monger, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=1316, name=Fur trader, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=1317, name=Market Guard, level=48, option=[null, Attack, null, null, null], anims=[813, -1]. +NPC id=1318, name=Warrior, level=48, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=1319, name=Fox, level=0, option=[null, null, null, null, null], anims=[6561, 6560]. +NPC id=1320, name=Bunny, level=2, option=[null, Attack, null, null, null], anims=[1242, 1243]. +NPC id=1321, name=Bunny, level=2, option=[null, Attack, null, null, null], anims=[1242, 1243]. +NPC id=1322, name=Gull, level=0, option=[null, null, null, null, null], anims=[6771, 6773]. +NPC id=1323, name=Gull, level=0, option=[null, null, null, null, null], anims=[6771, 6773]. +NPC id=1324, name=Gull, level=0, option=[null, null, null, null, null], anims=[6771, 6773]. +NPC id=1325, name=Gull, level=0, option=[null, null, null, null, null], anims=[6771, 6773]. +NPC id=1326, name=Bear Cub, level=15, option=[null, Attack, null, null, null], anims=[4920, 4924]. +NPC id=1327, name=Bear Cub, level=15, option=[null, Attack, null, null, null], anims=[4920, 4924]. +NPC id=1328, name=Unicorn Foal, level=12, option=[null, Attack, null, null, null], anims=[6374, 6373]. +NPC id=1329, name=Black unicorn Foal, level=22, option=[null, Attack, null, null, null], anims=[6374, 6373]. +NPC id=1330, name=Wolf, level=64, option=[null, Attack, null, null, null], anims=[6580, 6556]. +NPC id=1331, name=Fishing spot, level=0, option=[Net, null, Bait, hidden, hidden], anims=[447, 448]. +NPC id=1332, name=Fishing spot, level=0, option=[Cage, null, Harpoon, hidden, hidden], anims=[447, 448]. +NPC id=1333, name=Fishing spot, level=0, option=[Net, null, Harpoon, hidden, hidden], anims=[447, 448]. +NPC id=1334, name=Jossik, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=1335, name=Jossik, level=0, option=[Talk-to, null, null, null, null], anims=[1147, -1]. +NPC id=1336, name=Larrissa, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1337, name=Larrissa, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1338, name=Dagannoth, level=74, option=[null, Attack, null, null, null], anims=[1338, 1339]. +NPC id=1339, name=Dagannoth, level=74, option=[null, Attack, null, null, null], anims=[1338, 1339]. +NPC id=1340, name=Dagannoth, level=74, option=[null, Attack, null, null, null], anims=[1338, 1339]. +NPC id=1341, name=Dagannoth, level=92, option=[null, Attack, null, null, null], anims=[1338, 1339]. +NPC id=1342, name=Dagannoth, level=92, option=[null, Attack, null, null, null], anims=[1338, 1339]. +NPC id=1343, name=Dagannoth, level=92, option=[null, Attack, null, null, null], anims=[1338, 1339]. +NPC id=1344, name=Dagannoth, level=100, option=[null, null, null, null, null], anims=[1344, 1344]. +NPC id=1345, name=Dagannoth, level=100, option=[null, null, null, null, null], anims=[1345, 1345]. +NPC id=1346, name=Dagannoth, level=100, option=[null, null, null, null, null], anims=[1346, 1346]. +NPC id=1347, name=Dagannoth, level=100, option=[null, Attack, null, null, null], anims=[1338, 1339]. +NPC id=1348, name=Dagannoth mother, level=100, option=[null, null, null, null, null], anims=[1344, 1344]. +NPC id=1349, name=Dagannoth mother, level=100, option=[null, null, null, null, null], anims=[1345, 1345]. +NPC id=1350, name=Dagannoth mother, level=100, option=[null, null, null, null, null], anims=[1346, 1346]. +NPC id=1351, name=Dagannoth mother, level=100, option=[null, Attack, null, null, null], anims=[1338, 1339]. +NPC id=1352, name=Dagannoth mother, level=100, option=[null, Attack, null, null, null], anims=[1338, 1339]. +NPC id=1353, name=Dagannoth mother, level=100, option=[null, Attack, null, null, null], anims=[1338, 1339]. +NPC id=1354, name=Dagannoth mother, level=100, option=[null, Attack, null, null, null], anims=[1338, 1339]. +NPC id=1355, name=Dagannoth mother, level=100, option=[null, Attack, null, null, null], anims=[1338, 1339]. +NPC id=1356, name=Dagannoth mother, level=100, option=[null, Attack, null, null, null], anims=[1338, 1339]. +NPC id=1357, name=Sam, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=1358, name=Rachael, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=1359, name=Queen Sigrid, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1360, name=Banker, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[808, -1]. +NPC id=1361, name=Arnor, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1362, name=Haming, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1363, name=Moldof, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1364, name=Helga, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1365, name=Matilda, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1366, name=Ashild, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1367, name=Skraeling, level=2, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=1368, name=Skraeling, level=2, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=1369, name=Fishmonger, level=0, option=[Talk-to, null, Trade, null, null], anims=[813, -1]. +NPC id=1370, name=Greengrocer, level=0, option=[Talk-to, null, Trade, null, null], anims=[813, -1]. +NPC id=1371, name=Prince Brand, level=0, option=[Talk-to, null, null, null, null], anims=[1321, -1]. +NPC id=1372, name=Princess Astrid, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1373, name=King Vargas, level=0, option=[Talk-to, null, null, null, null], anims=[296, 293]. +NPC id=1374, name=Guard, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1375, name=Advisor Ghrim, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1376, name=Derrik, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1377, name=Farmer, level=0, option=[null, null, null, null, null], anims=[440, -1]. +NPC id=1378, name=Flower Girl, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1379, name=Ragnar, level=1, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=1380, name=Einar, level=1, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=1381, name=Alrik, level=1, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=1382, name=Thorhild, level=1, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=1383, name=Halla, level=1, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=1384, name=Yrsa, level=1, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=1385, name=Sailor, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1386, name=Rannveig, level=2, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=1387, name=Thora, level=2, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=1388, name=Valgerd, level=2, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=1389, name=Skraeling, level=2, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=1390, name=Broddi, level=2, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=1391, name=Skraeling, level=2, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=1392, name=Ragnvald, level=2, option=[Talk-to, Attack, null, null, null], anims=[813, -1]. +NPC id=1393, name=Fishmonger, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=1394, name=Greengrocer, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=1395, name=Lumberjack Leif, level=0, option=[Talk-to, null, null, null, null], anims=[1365, -1]. +NPC id=1396, name=Miner Magnus, level=0, option=[Talk-to, null, null, null, null], anims=[6935, -1]. +NPC id=1397, name=Fisherman Frodi, level=0, option=[Talk-to, null, null, null, null], anims=[7261, -1]. +NPC id=1398, name=Gardener Gunnhild, level=0, option=[Talk-to, null, null, null, null], anims=[2273, -1]. +NPC id=1399, name=Fishing spot, level=0, option=[Cage, null, Harpoon, hidden, hidden], anims=[447, 448]. +NPC id=1400, name=Gull, level=0, option=[null, Attack, null, null, null], anims=[6771, 6773]. +NPC id=1401, name=Chicken, level=1, option=[null, Attack, null, null, null], anims=[5386, 5385]. +NPC id=1402, name=Chicken, level=1, option=[null, Attack, null, null, null], anims=[5386, 5385]. +NPC id=1403, name=Rooster, level=2, option=[null, Attack, null, null, null], anims=[5386, 5385]. +NPC id=1404, name=Rabbit, level=2, option=[null, Attack, null, null, null], anims=[6089, 6088]. +NPC id=1405, name=Fishing spot, level=0, option=[Net, null, Harpoon, hidden, hidden], anims=[447, 448]. +NPC id=1406, name=Fishing spot, level=0, option=[Net, null, Harpoon, hidden, hidden], anims=[447, 448]. +NPC id=1407, name=Daero, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=1408, name=Waydar, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=1409, name=Waydar, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=1410, name=Waydar, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=1411, name=Garkor, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=1412, name=Garkor, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=1413, name=Lumo, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=1414, name=Lumo, level=0, option=[null, null, null, null, null], anims=[195, 189]. +NPC id=1415, name=Bunkdo, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=1416, name=Bunkdo, level=0, option=[null, null, null, null, null], anims=[195, 189]. +NPC id=1417, name=Carado, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=1418, name=Carado, level=0, option=[null, null, null, null, null], anims=[195, 189]. +NPC id=1419, name=Lumdo, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=1420, name=Karam, level=0, option=[Talk-to, null, null, null, null], anims=[1412, 189]. +NPC id=1421, name=Karam, level=0, option=[null, null, null, null, null], anims=[1412, 189]. +NPC id=1422, name=Karam, level=0, option=[Talk-to, null, null, null, null], anims=[1412, 189]. +NPC id=1423, name=Bunkwicket, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=1424, name=Waymottin, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=1425, name=Zooknock, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=1426, name=Zooknock, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=1427, name=G.L.O. Caranock, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=1428, name=G.L.O. Caranock, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=1429, name=Dugopul, level=0, option=[Talk-to, null, null, null, null], anims=[1386, 1380]. +NPC id=1430, name=Salenab, level=0, option=[Talk-to, null, null, null, null], anims=[222, 219]. +NPC id=1431, name=Trefaji, level=0, option=[Talk-to, null, null, null, null], anims=[1401, 1399]. +NPC id=1432, name=Aberab, level=0, option=[Talk-to, null, null, null, null], anims=[1401, 1399]. +NPC id=1433, name=Solihib, level=0, option=[Talk-to, null, Trade, null, null], anims=[1386, 1380]. +NPC id=1434, name=Daga, level=0, option=[Talk-to, null, Trade, null, null], anims=[1386, 1380]. +NPC id=1435, name=Tutab, level=0, option=[Talk-to, null, Trade, null, null], anims=[1386, 1380]. +NPC id=1436, name=Ifaba, level=0, option=[Talk-to, null, Trade, null, null], anims=[1386, 1380]. +NPC id=1437, name=Hamab, level=0, option=[Talk-to, null, Trade, null, null], anims=[1386, 1380]. +NPC id=1438, name=Hafuba, level=0, option=[Talk-to, null, null, null, null], anims=[1401, 1399]. +NPC id=1439, name=Denadu, level=0, option=[Talk-to, null, null, null, null], anims=[1387, 1380]. +NPC id=1440, name=Lofu, level=0, option=[Talk-to, null, null, null, null], anims=[1387, 1380]. +NPC id=1441, name=Kruk, level=149, option=[Talk-to, null, null, null, null], anims=[1386, 1385]. +NPC id=1442, name=Duke, level=149, option=[null, Attack, null, null, null], anims=[1386, 1385]. +NPC id=1443, name=Oipuis, level=149, option=[null, Attack, null, null, null], anims=[1386, 1385]. +NPC id=1444, name=Uyoro, level=149, option=[null, Attack, null, null, null], anims=[1386, 1385]. +NPC id=1445, name=Ouhai, level=149, option=[null, Attack, null, null, null], anims=[1386, 1385]. +NPC id=1446, name=Uodai, level=149, option=[null, Attack, null, null, null], anims=[1386, 1385]. +NPC id=1447, name=Padulah, level=149, option=[Talk-to, Attack, null, null, null], anims=[1386, 1380]. +NPC id=1448, name=Awowogei, level=0, option=[Talk-to, null, null, null, null], anims=[1386, 1380]. +NPC id=1449, name=Uwogo, level=0, option=[Talk-to, null, null, null, null], anims=[1386, 1380]. +NPC id=1450, name=Muruwoi, level=0, option=[Talk-to, null, null, null, null], anims=[1386, 1380]. +NPC id=1451, name=Sleeping Monkey, level=0, option=[Talk-to, null, null, null, null], anims=[1388, 1380]. +NPC id=1452, name=Monkey Child, level=0, option=[Talk-to, null, null, null, null], anims=[1386, 1380]. +NPC id=1453, name=The Monkey's Uncle, level=0, option=[Talk-to, null, null, null, null], anims=[1386, 1380]. +NPC id=1454, name=The Monkey's Aunt, level=0, option=[Talk-to, null, null, null, null], anims=[1386, 1380]. +NPC id=1455, name=Monkey Guard, level=149, option=[null, Attack, null, null, null], anims=[1386, 1380]. +NPC id=1456, name=Monkey Archer, level=86, option=[null, Attack, null, null, null], anims=[1386, 1380]. +NPC id=1457, name=Monkey Archer, level=86, option=[null, Attack, null, null, null], anims=[1386, 1380]. +NPC id=1458, name=Monkey Archer, level=86, option=[null, Attack, null, null, null], anims=[1386, 1380]. +NPC id=1459, name=Monkey Guard, level=167, option=[null, Attack, null, null, null], anims=[1401, 1399]. +NPC id=1460, name=Monkey Guard, level=167, option=[null, Attack, null, null, null], anims=[1401, 1399]. +NPC id=1461, name=Elder Guard, level=0, option=[Talk-to, null, null, null, null], anims=[1401, 1399]. +NPC id=1462, name=Elder Guard, level=0, option=[Talk-to, null, null, null, null], anims=[1401, 1399]. +NPC id=1463, name=Monkey, level=3, option=[Talk-to, null, null, null, null], anims=[222, 219]. +NPC id=1464, name=Monkey, level=3, option=[Talk-to, null, null, null, null], anims=[222, 219]. +NPC id=1465, name=Monkey Zombie, level=98, option=[null, Attack, null, null, null], anims=[1386, 1382]. +NPC id=1466, name=Monkey Zombie, level=129, option=[null, Attack, null, null, null], anims=[1386, 1382]. +NPC id=1467, name=Monkey Zombie, level=82, option=[null, Attack, null, null, null], anims=[1386, 1382]. +NPC id=1468, name=Bonzara, level=0, option=[Talk-to, null, null, null, null], anims=[1387, 1380]. +NPC id=1469, name=Monkey minder, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1470, name=Foreman, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=1471, name=Skeleton, level=142, option=[null, Attack, null, null, null], anims=[5517, 5518]. +NPC id=1472, name=Jungle demon, level=195, option=[null, Attack, null, null, null], anims=[66, 63]. +NPC id=1473, name=Spider, level=1, option=[null, Attack, null, null, null], anims=[6247, 6248]. +NPC id=1474, name=Spider, level=0, option=[null, null, null, null, null], anims=[6247, 6248]. +NPC id=1475, name=Bird, level=11, option=[null, Attack, null, null, null], anims=[6772, 6774]. +NPC id=1476, name=Bird, level=5, option=[null, Attack, null, null, null], anims=[6771, 6773]. +NPC id=1477, name=Scorpion, level=38, option=[null, Attack, null, null, null], anims=[6252, 6257]. +NPC id=1478, name=Jungle spider, level=37, option=[null, Attack, null, null, null], anims=[5326, 5325]. +NPC id=1479, name=Snake, level=24, option=[null, Attack, null, null, null], anims=[-1, 274]. +NPC id=1480, name=Small ninja monkey, level=1, option=[null, null, null, null, null], anims=[1386, 1380]. +NPC id=1481, name=Medium ninja monkey, level=1, option=[null, null, null, null, null], anims=[1386, 1380]. +NPC id=1482, name=Gorilla, level=1, option=[null, null, null, null, null], anims=[1401, 1399]. +NPC id=1483, name=Bearded gorilla, level=1, option=[null, null, null, null, null], anims=[1401, 1399]. +NPC id=1484, name=Ancient monkey, level=1, option=[null, null, null, null, null], anims=[1401, 1399]. +NPC id=1485, name=Small zombie monkey, level=1, option=[null, null, null, null, null], anims=[1386, 1382]. +NPC id=1486, name=Large zombie monkey, level=1, option=[null, null, null, null, null], anims=[1386, 1382]. +NPC id=1487, name=Monkey, level=1, option=[null, null, null, null, null], anims=[222, 219]. +NPC id=1488, name=Dummy, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=1489, name=Dummy, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=1490, name=Dummy, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=1491, name=Dummy, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=1492, name=Dummy, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=1493, name=Dummy, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=1494, name=Dummy, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=1495, name=Dummy, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=1496, name=Dummy, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=1497, name=Dummy, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=1498, name=Dummy, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=1499, name=Dummy, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=1500, name=Dummy, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=1501, name=Dummy, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=1502, name=Dummy, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=1503, name=Dummy, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=1504, name=Dummy, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=1505, name=Dummy, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=1506, name=Dummy, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=1507, name=Dummy, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=1508, name=Forester, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1509, name=Woman-at-arms, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1510, name=Apprentice, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=1511, name=Ranger, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1512, name=Adventurer, level=0, option=[Talk-to, null, null, null, null], anims=[7047, -1]. +NPC id=1513, name=Mage, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=1514, name=Hiylik Myna, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1515, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=1516, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=1517, name=null, level=1, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=1518, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=1519, name=null, level=1, option=[null, null, null, null, null], anims=[7047, -1]. +NPC id=1520, name=null, level=1, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=1521, name=Nail beast, level=69, option=[null, Attack, null, null, null], anims=[5986, 5987]. +NPC id=1522, name=Nail beast, level=98, option=[null, Attack, null, null, null], anims=[5986, 5987]. +NPC id=1523, name=Nail beast, level=141, option=[null, Attack, null, null, null], anims=[5986, 5987]. +NPC id=1524, name=Undead Lumberjack, level=30, option=[null, Attack, null, null, null], anims=[5965, 5965]. +NPC id=1525, name=Undead Lumberjack, level=30, option=[null, Attack, null, null, null], anims=[5966, 5966]. +NPC id=1526, name=Lanthus, level=0, option=[Talk-to, null, null, Trade-with, null], anims=[808, -1]. +NPC id=1527, name=Mine cart, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=1528, name=Zealot, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[808, -1]. +NPC id=1529, name=Sheep, level=1, option=[null, null, null, null, null], anims=[5335, 5334]. +NPC id=1530, name=Rabbit, level=1, option=[null, null, null, null, null], anims=[6089, 6088]. +NPC id=1531, name=Imp, level=1, option=[null, null, null, null, null], anims=[171, 168]. +NPC id=1532, name=Barricade, level=0, option=[null, Attack, null, null, null], anims=[-1, -1]. +NPC id=1533, name=Barricade, level=0, option=[null, Attack, null, null, null], anims=[475, -1]. +NPC id=1534, name=Barricade, level=0, option=[null, Attack, null, null, null], anims=[-1, -1]. +NPC id=1535, name=Barricade, level=0, option=[null, Attack, null, null, null], anims=[475, -1]. +NPC id=1536, name=Possessed pickaxe, level=50, option=[null, Attack, null, null, null], anims=[187, 181]. +NPC id=1537, name=Haze, level=0, option=[null, null, null, null, null], anims=[5543, 5543]. +NPC id=1538, name=Corpse, level=0, option=[null, null, null, null, null], anims=[1442, 5479]. +NPC id=1539, name=Skeletal miner, level=42, option=[null, Attack, null, null, null], anims=[5483, 5479]. +NPC id=1540, name=Treus Dayth, level=95, option=[null, Attack, null, null, null], anims=[5538, 5539]. +NPC id=1541, name=Ghost, level=95, option=[null, null, null, null, null], anims=[5543, 5543]. +NPC id=1542, name=Loading crane, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=1543, name=Innocent-looking key, level=0, option=[Take, null, null, null, null], anims=[1450, 1451]. +NPC id=1544, name=Mine cart, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=1545, name=Mine cart, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=1546, name=Mine cart, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=1547, name=Mine cart, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=1548, name=Mine cart, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=1549, name=Ghost, level=29, option=[null, Attack, null, null, null], anims=[5538, 5539]. +NPC id=1550, name=Chompy bird, level=6, option=[null, null, null, null, Attack], anims=[6764, 6765]. +NPC id=1551, name=Mischievous ghost, level=0, option=[null, null, null, null, null], anims=[5530, 5531]. +NPC id=1552, name=Santa, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1553, name=Ug, level=0, option=[Talk-to, null, null, null, null], anims=[1474, 283]. +NPC id=1554, name=Aga, level=0, option=[Talk-to, null, null, null, null], anims=[286, 283]. +NPC id=1555, name=Arrg, level=113, option=[Talk-to, null, null, null, null], anims=[286, 283]. +NPC id=1556, name=Arrg, level=113, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=1557, name=Ug, level=1, option=[Talk-to, null, null, null, null], anims=[1480, 283]. +NPC id=1558, name=Ice wolf, level=96, option=[null, Attack, null, null, null], anims=[6580, 6556]. +NPC id=1559, name=Ice wolf, level=132, option=[null, Attack, null, null, null], anims=[6580, 6556]. +NPC id=1560, name=Ice Troll, level=124, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=1561, name=Ice Troll, level=123, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=1562, name=Ice Troll, level=120, option=[null, Attack, null, null, null], anims=[926, 1139]. +NPC id=1563, name=Ice Troll, level=121, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=1564, name=Ice Troll, level=120, option=[null, Attack, null, null, null], anims=[926, 1139]. +NPC id=1565, name=Ice Troll, level=120, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=1566, name=Ice Troll, level=121, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=1567, name=Cyreg Paddlehorn, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=1568, name=Curpile Fyod, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1569, name=Veliaf Hurtz, level=0, option=[Talk-to, null, hidden, null, null], anims=[808, -1]. +NPC id=1570, name=Sani Piliu, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1571, name=Harold Evans, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1572, name=Radigad Ponfit, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1573, name=Polmafi Ferdygris, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1574, name=Ivan Strom, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1575, name=Skeleton Hellhound, level=97, option=[null, Attack, null, null, null], anims=[6580, 6577]. +NPC id=1576, name=Stranger, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=1577, name=Vanstrom Klause, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=1578, name=Mist, level=0, option=[null, null, null, null, null], anims=[1261, 1261]. +NPC id=1579, name=Vanstrom Klause, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1580, name=Vanstrom Klause, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1581, name=Vanstrom Klause, level=0, option=[Talk-to, null, null, null, null], anims=[1501, 1501]. +NPC id=1582, name=Fire giant, level=86, option=[null, Attack, null, null, null], anims=[4662, 4660]. +NPC id=1583, name=Fire giant, level=86, option=[null, Attack, null, null, null], anims=[4663, 4661]. +NPC id=1584, name=Fire giant, level=86, option=[null, Attack, null, null, null], anims=[4663, 4661]. +NPC id=1585, name=Fire giant, level=86, option=[null, Attack, null, null, null], anims=[4663, 4661]. +NPC id=1586, name=Fire giant, level=86, option=[null, Attack, null, null, null], anims=[4663, 4661]. +NPC id=1587, name=Moss giant, level=42, option=[null, Attack, null, null, null], anims=[4656, 4654]. +NPC id=1588, name=Moss giant, level=42, option=[null, Attack, null, null, null], anims=[4656, 4654]. +NPC id=1589, name=Baby red dragon, level=48, option=[null, Attack, null, null, null], anims=[27, 21]. +NPC id=1590, name=Bronze dragon, level=131, option=[null, Attack, null, null, null], anims=[90, 79]. +NPC id=1591, name=Iron dragon, level=189, option=[null, Attack, null, null, null], anims=[90, 79]. +NPC id=1592, name=Steel dragon, level=246, option=[null, Attack, null, null, null], anims=[90, 79]. +NPC id=1593, name=Wild dog, level=63, option=[null, Attack, null, null, null], anims=[6561, 6560]. +NPC id=1594, name=Wild dog, level=63, option=[null, Attack, null, null, null], anims=[6561, 6560]. +NPC id=1595, name=Saniboch, level=0, option=[Talk-to, null, Pay, null, null], anims=[808, -1]. +NPC id=1596, name=Mazchna, level=0, option=[Talk-to, null, null, Trade, null], anims=[808, -1]. +NPC id=1597, name=Vannaka, level=0, option=[Talk-to, null, null, Trade, null], anims=[2561, -1]. +NPC id=1598, name=Chaeldar, level=0, option=[Talk-to, null, null, Trade, null], anims=[112, 106]. +NPC id=1599, name=Duradel, level=0, option=[Talk-to, null, null, Trade, null], anims=[808, -1]. +NPC id=1600, name=Cave crawler, level=23, option=[null, Attack, null, null, null], anims=[226, 225]. +NPC id=1601, name=Cave crawler, level=23, option=[null, Attack, null, null, null], anims=[226, 225]. +NPC id=1602, name=Cave crawler, level=23, option=[null, Attack, null, null, null], anims=[226, 225]. +NPC id=1603, name=Cave crawler, level=23, option=[null, Attack, null, null, null], anims=[226, 225]. +NPC id=1604, name=Aberrant spectre, level=96, option=[null, Attack, null, null, null], anims=[1506, 1505]. +NPC id=1605, name=Aberrant spectre, level=96, option=[null, Attack, null, null, null], anims=[1506, 1505]. +NPC id=1606, name=Aberrant spectre, level=96, option=[null, Attack, null, null, null], anims=[1506, 1505]. +NPC id=1607, name=Aberrant spectre, level=96, option=[null, Attack, null, null, null], anims=[1506, 1505]. +NPC id=1608, name=Kurask, level=106, option=[null, Attack, null, null, null], anims=[1511, 1510]. +NPC id=1609, name=Kurask, level=106, option=[null, Attack, null, null, null], anims=[1511, 1510]. +NPC id=1610, name=Gargoyle, level=111, option=[null, Attack, null, null, null], anims=[1516, 1515]. +NPC id=1611, name=Gargoyle, level=111, option=[null, Attack, null, null, null], anims=[-1, -1]. +NPC id=1612, name=Banshee, level=23, option=[null, Attack, null, null, null], anims=[1522, 1521]. +NPC id=1613, name=Nechryael, level=115, option=[null, Attack, null, null, null], anims=[1527, 1526]. +NPC id=1614, name=Death spawn, level=46, option=[null, Attack, null, null, null], anims=[1539, 1539]. +NPC id=1615, name=Abyssal demon, level=124, option=[null, Attack, null, null, null], anims=[1536, 1534]. +NPC id=1616, name=Basilisk, level=61, option=[null, Attack, null, null, null], anims=[1545, 1544]. +NPC id=1617, name=Basilisk, level=61, option=[null, Attack, null, null, null], anims=[1545, 1544]. +NPC id=1618, name=Bloodveld, level=76, option=[null, Attack, null, null, null], anims=[1551, 1549]. +NPC id=1619, name=Bloodveld, level=76, option=[null, Attack, null, null, null], anims=[1551, 1549]. +NPC id=1620, name=Cockatrice, level=37, option=[null, Attack, null, null, null], anims=[1561, 1559]. +NPC id=1621, name=Cockatrice, level=37, option=[null, Attack, null, null, null], anims=[1561, 1559]. +NPC id=1622, name=Rockslug, level=29, option=[null, Attack, null, null, null], anims=[1566, 1564]. +NPC id=1623, name=Rockslug, level=29, option=[null, Attack, null, null, null], anims=[1566, 1564]. +NPC id=1624, name=Dust devil, level=93, option=[null, Attack, null, null, null], anims=[1556, 1554]. +NPC id=1625, name=Smokedevil, level=93, option=[null, Attack, null, null, null], anims=[1556, 1554]. +NPC id=1626, name=Turoth, level=86, option=[null, Attack, null, null, null], anims=[1594, 1593]. +NPC id=1627, name=Turoth, level=89, option=[null, Attack, null, null, null], anims=[1594, 1593]. +NPC id=1628, name=Turoth, level=87, option=[null, Attack, null, null, null], anims=[1594, 1593]. +NPC id=1629, name=Turoth, level=85, option=[null, Attack, null, null, null], anims=[1594, 1593]. +NPC id=1630, name=Turoth, level=83, option=[null, Attack, null, null, null], anims=[1594, 1593]. +NPC id=1631, name=Turoth, level=88, option=[null, Attack, null, null, null], anims=[1594, 1593]. +NPC id=1632, name=Turoth, level=88, option=[null, Attack, null, null, null], anims=[1594, 1593]. +NPC id=1633, name=Pyrefiend, level=43, option=[null, Attack, null, null, null], anims=[1578, 1579]. +NPC id=1634, name=Pyrefiend, level=43, option=[null, Attack, null, null, null], anims=[1578, 1579]. +NPC id=1635, name=Pyrefiend, level=43, option=[null, Attack, null, null, null], anims=[1578, 1579]. +NPC id=1636, name=Pyrefiend, level=43, option=[null, Attack, null, null, null], anims=[1578, 1579]. +NPC id=1637, name=Jelly, level=78, option=[null, Attack, null, null, null], anims=[1583, 1584]. +NPC id=1638, name=Jelly, level=78, option=[null, Attack, null, null, null], anims=[1583, 1584]. +NPC id=1639, name=Jelly, level=78, option=[null, Attack, null, null, null], anims=[1583, 1584]. +NPC id=1640, name=Jelly, level=78, option=[null, Attack, null, null, null], anims=[1583, 1584]. +NPC id=1641, name=Jelly, level=78, option=[null, Attack, null, null, null], anims=[1583, 1584]. +NPC id=1642, name=Jelly, level=78, option=[null, Attack, null, null, null], anims=[1583, 1584]. +NPC id=1643, name=Infernal Mage, level=66, option=[null, Attack, null, null, null], anims=[813, -1]. +NPC id=1644, name=Infernal Mage, level=66, option=[null, Attack, null, null, null], anims=[813, -1]. +NPC id=1645, name=Infernal Mage, level=66, option=[null, Attack, null, null, null], anims=[813, -1]. +NPC id=1646, name=Infernal Mage, level=66, option=[null, Attack, null, null, null], anims=[813, -1]. +NPC id=1647, name=Infernal Mage, level=66, option=[null, Attack, null, null, null], anims=[813, -1]. +NPC id=1648, name=Crawling Hand, level=8, option=[null, Attack, null, null, null], anims=[1588, 1589]. +NPC id=1649, name=Crawling Hand, level=8, option=[null, Attack, null, null, null], anims=[1588, 1589]. +NPC id=1650, name=Crawling Hand, level=7, option=[null, Attack, null, null, null], anims=[1588, 1589]. +NPC id=1651, name=Crawling Hand, level=8, option=[null, Attack, null, null, null], anims=[1588, 1589]. +NPC id=1652, name=Crawling Hand, level=8, option=[null, Attack, null, null, null], anims=[1588, 1589]. +NPC id=1653, name=Crawling Hand, level=12, option=[null, Attack, null, null, null], anims=[1588, 1589]. +NPC id=1654, name=Crawling Hand, level=12, option=[null, Attack, null, null, null], anims=[1588, 1589]. +NPC id=1655, name=Crawling Hand, level=11, option=[null, Attack, null, null, null], anims=[1588, 1589]. +NPC id=1656, name=Crawling Hand, level=12, option=[null, Attack, null, null, null], anims=[1588, 1589]. +NPC id=1657, name=Crawling Hand, level=12, option=[null, Attack, null, null, null], anims=[1588, 1589]. +NPC id=1658, name=Robe Store owner, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=1659, name=Skullball, level=0, option=[Tap, null, Kick, Shoot, Show-Goal], anims=[1607, 1608]. +NPC id=1660, name=Skullball Boss, level=0, option=[Talk-To, null, null, null, null], anims=[6539, 6541]. +NPC id=1661, name=Agility Boss, level=0, option=[Talk-To, null, null, null, null], anims=[6539, 6548]. +NPC id=1662, name=Skullball Trainer, level=0, option=[Talk-To, null, null, null, null], anims=[6539, 6541]. +NPC id=1663, name=Agility Trainer, level=0, option=[null, null, null, null, null], anims=[6539, 6541]. +NPC id=1664, name=Agility Trainer, level=0, option=[Give-Stick, null, null, null, null], anims=[6539, 6541]. +NPC id=1665, name=Werewolf, level=0, option=[Talk-To, null, null, null, null], anims=[6539, 6541]. +NPC id=1666, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC (wrapper) id=1667, child npcs=[1675, -1]. +NPC (wrapper) id=1668, child npcs=[1670, 1670, 1670, 1670, 1670, 1670, 1670, 1670, -1]. +NPC id=1669, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=1670, name=Dr Fenkenstrain, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[-1, -1]. +NPC (wrapper) id=1671, child npcs=[1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, -1]. +NPC id=1672, name=null, level=1, option=[null, null, null, null, null], anims=[1623, 1622]. +NPC id=1673, name=Fenkenstrain's Monster, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=1674, name=Lord Rologarth, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=1675, name=Gardener Ghost, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1676, name=Experiment, level=51, option=[null, Attack, null, null, null], anims=[1625, 1624]. +NPC id=1677, name=Experiment, level=25, option=[null, Attack, null, null, null], anims=[1614, 1615]. +NPC id=1678, name=Experiment, level=25, option=[null, Attack, null, null, null], anims=[1609, 1610]. +NPC id=1679, name=Eluned, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1680, name=Islwyn, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1681, name=Moss giant, level=84, option=[null, Attack, null, null, null], anims=[4656, 4654]. +NPC id=1682, name=Golrie, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=1683, name=Velorina, level=0, option=[Talk-To, null, null, null, null], anims=[808, -1]. +NPC id=1684, name=Necrovarus, level=0, option=[Talk-To, null, null, null, null], anims=[813, -1]. +NPC id=1685, name=Gravingas, level=0, option=[Talk-To, null, null, null, null], anims=[1421, -1]. +NPC id=1686, name=Ghost disciple, level=0, option=[Talk-To, null, null, null, null], anims=[813, -1]. +NPC id=1687, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=1688, name=Ak-Haranu, level=0, option=[Talk-To, null, Trade, null, null], anims=[-1, -1]. +NPC id=1689, name=null, level=0, option=[null, null, null, null, null], anims=[1644, 1645]. +NPC id=1690, name=null, level=0, option=[null, null, null, null, null], anims=[1646, 1647]. +NPC id=1691, name=Undead cow, level=2, option=[null, Attack, null, null, null], anims=[5852, 5848]. +NPC id=1692, name=Undead chicken, level=1, option=[null, Attack, null, null, null], anims=[5386, 5385]. +NPC id=1693, name=Giant lobster, level=32, option=[null, Attack, null, null, null], anims=[6263, 6264]. +NPC id=1694, name=Robin, level=0, option=[Talk-To, null, null, null, null], anims=[808, -1]. +NPC id=1695, name=Old crone, level=0, option=[Talk-To, null, null, null, null], anims=[808, -1]. +NPC id=1696, name=Old man, level=0, option=[Talk-To, null, null, null, null], anims=[808, -1]. +NPC id=1697, name=Ghost villager, level=0, option=[Talk-To, null, null, null, null], anims=[808, -1]. +NPC id=1698, name=Tortured soul, level=59, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=1699, name=Ghost shopkeeper, level=0, option=[Talk-To, null, Trade, null, null], anims=[808, -1]. +NPC id=1700, name=Ghost innkeeper, level=0, option=[Talk-To, null, null, null, null], anims=[808, -1]. +NPC id=1701, name=Ghost farmer, level=0, option=[Talk-To, null, null, null, null], anims=[808, -1]. +NPC id=1702, name=Ghost banker, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[808, 808]. +NPC id=1703, name=Ghost sailor, level=0, option=[Talk-To, null, null, null, null], anims=[808, -1]. +NPC id=1704, name=Ghost captain, level=0, option=[Talk-To, null, null, null, null], anims=[808, -1]. +NPC id=1705, name=Ghost captain, level=0, option=[Talk-To, null, null, null, null], anims=[808, -1]. +NPC id=1706, name=Ghost guard, level=0, option=[Talk-To, null, null, null, null], anims=[808, -1]. +NPC id=1707, name=Ghost (?), level=1, option=[null, null, null, null, null], anims=[1639, 1640]. +NPC id=1708, name=Ghost (?), level=1, option=[null, null, null, null, null], anims=[1639, 1640]. +NPC id=1709, name=Johanhus Ulsbrecht, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1710, name=H.A.M. Guard, level=12, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=1711, name=H.A.M. Guard, level=18, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=1712, name=H.A.M. Guard, level=22, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=1713, name=H.A.M. Deacon, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=1714, name=H.A.M. Member, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[808, -1]. +NPC id=1715, name=H.A.M. Member, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[808, -1]. +NPC id=1716, name=H.A.M. Member, level=0, option=[Talk-to, null, null, null, null], anims=[1144, -1]. +NPC id=1717, name=H.A.M. Member, level=0, option=[Talk-to, null, null, null, null], anims=[1673, -1]. +NPC id=1718, name=Jimmy the Chisel, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1719, name=Tree, level=0, option=[Chop down, null, hidden, null, null], anims=[5750, 5750]. +NPC id=1720, name=Tree, level=0, option=[Chop down, null, hidden, null, null], anims=[5750, 5750]. +NPC id=1721, name=Tree, level=0, option=[Chop down, null, hidden, null, null], anims=[5750, 5750]. +NPC id=1722, name=Dead tree, level=0, option=[Chop down, null, hidden, null, null], anims=[5750, 5750]. +NPC id=1723, name=Dead tree, level=0, option=[Chop down, null, hidden, null, null], anims=[5750, 5750]. +NPC id=1724, name=Dead tree, level=0, option=[Chop down, null, hidden, null, null], anims=[5751, 5751]. +NPC id=1725, name=Dead tree, level=0, option=[Chop down, null, hidden, null, null], anims=[5750, 5750]. +NPC id=1726, name=Dead tree, level=0, option=[Chop down, null, hidden, null, null], anims=[5750, 5750]. +NPC id=1727, name=Dead tree, level=0, option=[Chop down, null, hidden, null, null], anims=[5750, 5750]. +NPC id=1728, name=Dead tree, level=0, option=[Chop down, null, hidden, null, null], anims=[5750, 5750]. +NPC id=1729, name=Dead tree, level=0, option=[Chop down, null, hidden, null, null], anims=[5750, 5750]. +NPC id=1730, name=Dead tree, level=0, option=[Chop down, null, hidden, null, null], anims=[5750, 5750]. +NPC id=1731, name=Dead tree, level=0, option=[Chop down, null, hidden, null, null], anims=[5750, 5750]. +NPC id=1732, name=null, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1733, name=Dramen tree, level=0, option=[Chop down, null, hidden, null, null], anims=[5750, 5750]. +NPC id=1734, name=Magic tree, level=0, option=[Chop down, null, hidden, null, null], anims=[5750, 5750]. +NPC id=1735, name=Maple tree, level=0, option=[Chop down, null, hidden, null, null], anims=[5750, 5750]. +NPC id=1736, name=Willow, level=0, option=[Chop down, null, hidden, null, null], anims=[5750, 5750]. +NPC id=1737, name=Willow, level=0, option=[Chop down, null, hidden, null, null], anims=[5750, 5750]. +NPC id=1738, name=Willow, level=0, option=[Chop down, null, hidden, null, null], anims=[5750, 5750]. +NPC id=1739, name=Oak, level=0, option=[Chop down, null, hidden, null, null], anims=[5750, 5750]. +NPC id=1740, name=Yew, level=0, option=[Chop down, null, hidden, null, null], anims=[5750, 5750]. +NPC id=1741, name=Evergreen, level=0, option=[Chop down, null, hidden, null, null], anims=[5750, 5750]. +NPC id=1742, name=Evergreen, level=0, option=[Chop down, null, hidden, null, null], anims=[5750, 5750]. +NPC id=1743, name=Evergreen, level=0, option=[Chop down, null, hidden, null, null], anims=[5750, 5750]. +NPC id=1744, name=Tree, level=0, option=[Chop down, null, hidden, null, null], anims=[5750, 5750]. +NPC id=1745, name=Dead tree, level=0, option=[Chop down, null, hidden, null, null], anims=[5751, 5751]. +NPC id=1746, name=Achey Tree, level=0, option=[Chop down, null, hidden, null, null], anims=[5750, 5750]. +NPC id=1747, name=Tree, level=0, option=[Chop down, null, hidden, null, null], anims=[5750, 5750]. +NPC id=1748, name=Tree, level=0, option=[Chop down, null, hidden, null, null], anims=[5750, 5750]. +NPC id=1749, name=Hollow tree, level=0, option=[Chop down, null, hidden, null, null], anims=[5751, 5751]. +NPC id=1750, name=Hollow tree, level=0, option=[Chop down, null, hidden, null, null], anims=[5751, 5751]. +NPC id=1751, name=Terrorbird, level=28, option=[null, Attack, null, null, null], anims=[1008, 1007]. +NPC id=1752, name=Mounted terrorbird gnome, level=31, option=[null, Attack, null, null, null], anims=[6793, 6796]. +NPC id=1753, name=Mounted terrorbird gnome, level=49, option=[null, Attack, null, null, null], anims=[6793, 6796]. +NPC id=1754, name=Crow, level=0, option=[null, null, null, null, null], anims=[6785, 6784]. +NPC id=1755, name=Crow, level=0, option=[null, null, null, null, null], anims=[6786, 6784]. +NPC id=1756, name=Crow, level=0, option=[null, null, null, null, null], anims=[6787, 6784]. +NPC id=1757, name=Farmer, level=7, option=[null, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=1758, name=Farmer, level=7, option=[null, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=1759, name=Farmer, level=0, option=[null, null, null, null, null], anims=[1728, -1]. +NPC id=1760, name=Farmer, level=0, option=[null, null, null, null, null], anims=[1728, -1]. +NPC id=1761, name=Farmer, level=0, option=[null, null, null, null, null], anims=[1728, -1]. +NPC id=1762, name=Sheep, level=0, option=[null, null, null, null, null], anims=[5339, 5340]. +NPC id=1763, name=Sheep, level=0, option=[Shear, null, null, null, null], anims=[5335, 5334]. +NPC id=1764, name=Sheep, level=0, option=[null, null, null, null, null], anims=[5339, 5340]. +NPC id=1765, name=Sheep, level=0, option=[Shear, null, null, null, null], anims=[5335, 5334]. +NPC id=1766, name=Cow calf, level=2, option=[null, Attack, null, null, null], anims=[5852, 5856]. +NPC id=1767, name=Cow, level=2, option=[null, Attack, null, null, null], anims=[5852, 5848]. +NPC id=1768, name=Cow calf, level=2, option=[null, Attack, null, null, null], anims=[5852, 5856]. +NPC id=1769, name=Goblin, level=2, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=1770, name=Goblin, level=2, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=1771, name=Goblin, level=2, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=1772, name=Goblin, level=2, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=1773, name=Goblin, level=2, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=1774, name=Goblin, level=2, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=1775, name=Goblin, level=2, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=1776, name=Goblin, level=2, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=1777, name=Ilfeen, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1778, name=William, level=0, option=[Talk-to, null, Trade, null, null], anims=[1740, 1739]. +NPC id=1779, name=Ian, level=0, option=[Talk-to, null, Trade, null, null], anims=[1740, 1739]. +NPC id=1780, name=Larry, level=0, option=[Talk-to, null, Trade, null, null], anims=[1740, 1739]. +NPC id=1781, name=Darren, level=0, option=[Talk-to, null, Trade, null, null], anims=[1740, 1739]. +NPC id=1782, name=Edward, level=0, option=[Talk-to, null, Trade, null, null], anims=[1740, 1739]. +NPC id=1783, name=Richard, level=0, option=[Talk-to, null, Trade, null, null], anims=[1740, 1739]. +NPC id=1784, name=Neil, level=0, option=[Talk-to, null, Trade, null, null], anims=[1740, 1739]. +NPC id=1785, name=Edmond, level=0, option=[Talk-to, null, Trade, null, null], anims=[1740, 1739]. +NPC id=1786, name=Simon, level=0, option=[Talk-to, null, Trade, null, null], anims=[1740, 1739]. +NPC id=1787, name=Sam, level=0, option=[Talk-to, null, Trade, null, null], anims=[1740, 1739]. +NPC id=1788, name=Lumdo, level=0, option=[null, null, null, null, null], anims=[195, 189]. +NPC id=1789, name=Bunkwicket, level=0, option=[null, null, null, null, null], anims=[195, 189]. +NPC id=1790, name=Waymottin, level=0, option=[null, null, null, null, null], anims=[195, 189]. +NPC id=1791, name=Jungle Tree, level=0, option=[Chop down, null, hidden, null, null], anims=[5751, 5751]. +NPC id=1792, name=Jungle Tree, level=0, option=[Chop down, null, hidden, null, null], anims=[5751, 5751]. +NPC id=1793, name=Tassie Slipcast, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1794, name=Hammerspike Stoutbeard, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=1795, name=Dwarf gang member, level=44, option=[Talk-to, Attack, null, null, null], anims=[101, 98]. +NPC id=1796, name=Dwarf gang member, level=48, option=[Talk-to, Attack, null, null, null], anims=[101, 98]. +NPC id=1797, name=Dwarf gang member, level=49, option=[Talk-to, Attack, null, null, null], anims=[101, 98]. +NPC id=1798, name=Phantuwti Fanstuwi Farsight, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1799, name=Tindel Marchant, level=0, option=[Talk-to, null, Give-Sword, null, null], anims=[808, -1]. +NPC id=1800, name=Gnormadium Avlafrim, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=1801, name=Petra Fiyed, level=1, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1802, name=Slagilith, level=92, option=[null, Attack, null, null, null], anims=[1749, 1748]. +NPC id=1803, name=Rock pile, level=0, option=[null, null, null, null, null], anims=[1754, 1754]. +NPC id=1804, name=Slagilith, level=0, option=[null, null, null, null, null], anims=[1753, -1]. +NPC id=1805, name=Guard, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1806, name=Guard, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1807, name=Hamal the Chieftain, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1808, name=Ragnar, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1809, name=Svidi, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1810, name=Jokul, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC (wrapper) id=1811, child npcs=[1812, -1]. +NPC id=1812, name=The Kendal, level=70, option=[Talk-to, Attack, null, null, null], anims=[1756, 1757]. +NPC id=1813, name=The Kendal, level=70, option=[null, Attack, null, null, null], anims=[1756, 1757]. +NPC id=1814, name=Camp dweller, level=31, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=1815, name=Camp dweller, level=31, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=1816, name=Camp dweller, level=31, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=1817, name=Camp dweller, level=31, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=1818, name=Camp dweller, level=25, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=1819, name=Mountain Goat, level=0, option=[null, null, null, null, null], anims=[5339, 5340]. +NPC id=1820, name=Mountain Goat, level=0, option=[null, null, null, null, null], anims=[5339, 5340]. +NPC id=1821, name=Bald Headed Eagle, level=0, option=[null, null, null, null, null], anims=[1773, 1773]. +NPC id=1822, name=Cave goblin, level=3, option=[Talk-to, Attack, null, null, null], anims=[6040, 6041]. +NPC id=1823, name=Cave goblin, level=3, option=[Talk-to, Attack, null, null, null], anims=[6040, 6041]. +NPC id=1824, name=Cave goblin, level=3, option=[Talk-to, Attack, null, null, null], anims=[6040, 6041]. +NPC id=1825, name=Cave goblin, level=3, option=[Talk-to, Attack, null, null, null], anims=[6040, 6041]. +NPC id=1826, name=Hole in the wall, level=0, option=[null, null, null, null, null], anims=[1798, -1]. +NPC id=1827, name=Wall beast, level=49, option=[null, Attack, null, null, null], anims=[1799, -1]. +NPC id=1828, name=Giant frog, level=99, option=[null, Attack, null, null, null], anims=[1796, 1797]. +NPC id=1829, name=Big frog, level=24, option=[null, Attack, null, null, null], anims=[1796, 1797]. +NPC id=1830, name=Frog, level=0, option=[null, null, null, null, null], anims=[1796, 1797]. +NPC id=1831, name=Cave slime, level=23, option=[null, Attack, null, null, null], anims=[1790, 1788]. +NPC id=1832, name=Cave bug, level=6, option=[null, Attack, null, null, null], anims=[6078, 6077]. +NPC id=1833, name=Cave bug larva, level=0, option=[null, null, null, null, null], anims=[1782, 1781]. +NPC id=1834, name=Candle seller, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1835, name=Easter Bunny, level=0, option=[Talk-to, null, null, null, null], anims=[3852, 3851]. +NPC (wrapper) id=1836, child npcs=[1837, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1837, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1837, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1837, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1837, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1837, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1837, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1837, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1837, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1837, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1837, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1838, -1]. +NPC id=1837, name=Dondakan the Dwarf, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=1838, name=Dondakan the Dwarf, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=1839, name=Dondakan the Dwarf, level=0, option=[null, null, null, null, null], anims=[101, 98]. +NPC id=1840, name=Dwarven Engineer, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=1841, name=Rolad, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=1842, name=Khorvak, a dwarven engineer, level=0, option=[Talk-to, null, null, null, null], anims=[900, 104]. +NPC id=1843, name=Dwarven Ferryman, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=1844, name=Dwarven Ferryman, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=1845, name=null, level=1, option=[null, null, null, null, null], anims=[101, 98]. +NPC id=1846, name=Dwarven Boatman, level=0, option=[Talk-to, null, Deliver-gold, null, null], anims=[101, 98]. +NPC id=1847, name=Miodvetnir, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=1848, name=Dernu, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=1849, name=Derni, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=1850, name=Arzinian Avatar of Strength, level=0, option=[null, Attack, null, null, null], anims=[1838, 1839]. +NPC id=1851, name=Arzinian Avatar of Strength, level=125, option=[null, Attack, null, null, null], anims=[1838, 1839]. +NPC id=1852, name=Arzinian Avatar of Strength, level=75, option=[null, Attack, null, null, null], anims=[1838, 1839]. +NPC id=1853, name=Arzinian Avatar of Ranging, level=0, option=[null, Attack, null, null, null], anims=[1838, 1839]. +NPC id=1854, name=Arzinian Avatar of Ranging, level=125, option=[null, Attack, null, null, null], anims=[1838, 1839]. +NPC id=1855, name=Arzinian Avatar of Ranging, level=75, option=[null, Attack, null, null, null], anims=[1838, 1839]. +NPC id=1856, name=Arzinian Avatar of Magic, level=0, option=[null, Attack, null, null, null], anims=[1838, 1839]. +NPC id=1857, name=Arzinian Avatar of Magic, level=125, option=[null, Attack, null, null, null], anims=[1838, 1839]. +NPC id=1858, name=Arzinian Avatar of Magic, level=75, option=[null, Attack, null, null, null], anims=[1838, 1839]. +NPC id=1859, name=Arzinian Being of Bordanzan, level=781, option=[Talk-to, null, null, null, null], anims=[1838, 1839]. +NPC id=1860, name=Brian, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=1861, name=Ranged combat tutor, level=0, option=[Talk-to, null, Claim, null, null], anims=[808, -1]. +NPC id=1862, name=Ali Morrisane, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1863, name=Drunken Ali, level=0, option=[Talk-to, null, null, null, null], anims=[1322, -1]. +NPC id=1864, name=Ali The barman, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1865, name=Ali the Kebab seller, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1866, name=Market seller, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=1867, name=Ali the Camel Man, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=1868, name=Street urchin, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC (wrapper) id=1869, child npcs=[1870, -1]. +NPC id=1870, name=Ali the Mayor, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1871, name=Ali the Hag, level=0, option=[Talk-to, null, null, null, null], anims=[808, 1146]. +NPC id=1872, name=Ali the Snake Charmer, level=0, option=[Talk-to, null, null, null, null], anims=[1879, -1]. +NPC id=1873, name=Ali the Camel, level=0, option=[null, null, Pet, null, null], anims=[51, 45]. +NPC id=1874, name=Desert snake, level=5, option=[null, Attack, null, null, null], anims=[277, 274]. +NPC id=1875, name=Snake, level=0, option=[null, null, null, null, null], anims=[1900, 274]. +NPC id=1876, name=null, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=1877, name=null, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=1878, name=Bandit Leader, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC (wrapper) id=1879, child npcs=[1880, 1880, 1881, -1]. +NPC id=1880, name=Bandit, level=56, option=[Talk-to, Attack, Pickpocket, null, null], anims=[-1, -1]. +NPC id=1881, name=Bandit, level=56, option=[Talk-to, Attack, Pickpocket, Lure, Knock-Out], anims=[-1, -1]. +NPC id=1882, name=Sir Palomedes, level=118, option=[Talk-to, Hidden, null, null, null], anims=[808, -1]. +NPC id=1883, name=Sir Palomedes, level=118, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=1884, name=Trobert, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1885, name=Bandit champion, level=70, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=1886, name=Cowardly Bandit, level=56, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC (wrapper) id=1887, child npcs=[1888, 1889, 1890, -1]. +NPC id=1888, name=Villager, level=3, option=[Talk-to, null, Pickpocket, null, null], anims=[-1, -1]. +NPC id=1889, name=Villager, level=3, option=[Talk-to, null, Pickpocket, Lure, null], anims=[-1, -1]. +NPC id=1890, name=Villager, level=3, option=[Talk-to, null, Pickpocket, Lure, Knock-Out], anims=[-1, -1]. +NPC (wrapper) id=1891, child npcs=[1892, 1893, 1894, -1]. +NPC id=1892, name=Villager, level=3, option=[Talk-to, null, Pickpocket, null, null], anims=[-1, -1]. +NPC id=1893, name=Villager, level=3, option=[Talk-to, null, Pickpocket, Lure, null], anims=[-1, -1]. +NPC id=1894, name=Villager, level=3, option=[Talk-to, null, Pickpocket, Lure, Knock-Out], anims=[-1, -1]. +NPC (wrapper) id=1895, child npcs=[1896, 1897, 1898, -1]. +NPC id=1896, name=Villager, level=3, option=[Talk-to, null, Pickpocket, null, null], anims=[-1, -1]. +NPC id=1897, name=Villager, level=3, option=[Talk-to, null, Pickpocket, Lure, null], anims=[-1, -1]. +NPC id=1898, name=Villager, level=3, option=[Talk-to, null, Pickpocket, Lure, Knock-Out], anims=[-1, -1]. +NPC id=1899, name=null, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=1900, name=null, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=1901, name=Menaphite Leader, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=1902, name=Ali the Operator, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC (wrapper) id=1903, child npcs=[1904, 1904, 1905, -1]. +NPC id=1904, name=Menaphite Thug, level=55, option=[Talk-to, Attack, null, null, null], anims=[-1, -1]. +NPC id=1905, name=Menaphite Thug, level=55, option=[Talk-to, Attack, Pickpocket, Lure, Knock-Out], anims=[808, -1]. +NPC id=1906, name=Tough Guy, level=75, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC (wrapper) id=1907, child npcs=[1908, 1908, 1909, 1909, 1910, -1]. +NPC id=1908, name=Broken clay golem, level=0, option=[Talk-to, null, null, null, null], anims=[1913, 1912]. +NPC id=1909, name=Damaged clay golem, level=0, option=[Talk-to, null, null, null, null], anims=[1913, 1912]. +NPC id=1910, name=Clay golem, level=0, option=[Talk-to, null, null, null, null], anims=[1913, 1912]. +NPC id=1911, name=Desert Phoenix, level=0, option=[null, null, Grab-feather, null, null], anims=[6809, 6808]. +NPC id=1912, name=Elissa, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1913, name=Kamil, level=154, option=[null, Attack, null, null, null], anims=[842, 841]. +NPC id=1914, name=Dessous, level=139, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=1915, name=Dessous, level=139, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=1916, name=Ruantun, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1917, name=Bandit shopkeeper, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=1918, name=Archaeologist, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1919, name=Stranger, level=95, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=1920, name=Malak, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1921, name=Bartender, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC (wrapper) id=1922, child npcs=[1923, 1923, 1923, 1923, 1923, 1923, 1923, 1923, 1923, 1923, 1923, -1]. +NPC id=1923, name=Eblis, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1924, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=1925, name=Eblis, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1926, name=Bandit, level=74, option=[Talk-to, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=1927, name=Bandit, level=0, option=[Talk-to, null, null, null, null], anims=[1955, -1]. +NPC id=1928, name=Bandit, level=0, option=[Talk-to, null, null, null, null], anims=[1953, -1]. +NPC id=1929, name=Bandit, level=0, option=[Talk-to, null, null, null, null], anims=[1952, -1]. +NPC id=1930, name=Bandit, level=0, option=[Talk-to, null, null, null, null], anims=[1954, -1]. +NPC id=1931, name=Bandit, level=57, option=[Talk-to, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC (wrapper) id=1932, child npcs=[1934, 1933, 1933, 1933, 1933, 1933, -1]. +NPC id=1933, name=Troll child, level=0, option=[Talk-to, null, null, null, null], anims=[286, 283]. +NPC id=1934, name=Troll child, level=0, option=[Talk-to, null, null, null, null], anims=[1476, 283]. +NPC id=1935, name=Ice troll, level=0, option=[Talk-to, null, null, null, null], anims=[286, 283]. +NPC id=1936, name=Ice troll, level=124, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=1937, name=Ice troll, level=123, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=1938, name=Ice troll, level=120, option=[null, Attack, null, null, null], anims=[926, 1139]. +NPC id=1939, name=Ice troll, level=121, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=1940, name=Ice troll, level=120, option=[null, Attack, null, null, null], anims=[926, 1139]. +NPC id=1941, name=Ice troll, level=120, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=1942, name=Ice troll, level=121, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC (wrapper) id=1943, child npcs=[1944, 1948, -1]. +NPC id=1944, name=Ice block, level=0, option=[Talk-to, Smash-ice, null, null, null], anims=[-1, -1]. +NPC (wrapper) id=1945, child npcs=[1946, 1950, -1]. +NPC id=1946, name=Ice block, level=0, option=[Talk-to, Smash-ice, null, null, null], anims=[-1, -1]. +NPC id=1947, name=null, level=1, option=[null, null, null, null, null], anims=[286, 283]. +NPC id=1948, name=Troll father, level=0, option=[Talk-to, null, null, null, null], anims=[286, 283]. +NPC id=1949, name=null, level=1, option=[null, null, null, null, null], anims=[286, 283]. +NPC id=1950, name=Troll mother, level=0, option=[Talk-to, null, null, null, null], anims=[286, 283]. +NPC id=1951, name=Ice wolf, level=132, option=[null, Attack, null, null, null], anims=[6580, 6556]. +NPC id=1952, name=Ice wolf, level=132, option=[null, Attack, null, null, null], anims=[6580, 6556]. +NPC id=1953, name=Ice wolf, level=132, option=[null, Attack, null, null, null], anims=[6580, 6556]. +NPC id=1954, name=Ice wolf, level=132, option=[null, Attack, null, null, null], anims=[6580, 6556]. +NPC id=1955, name=Ice wolf, level=132, option=[null, Attack, null, null, null], anims=[6580, 6556]. +NPC id=1956, name=Ice wolf, level=132, option=[null, Attack, null, null, null], anims=[6580, 6556]. +NPC id=1957, name=null, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=1958, name=Mummy, level=96, option=[null, Attack, null, null, null], anims=[5548, 5552]. +NPC id=1959, name=Mummy, level=98, option=[null, Attack, null, null, null], anims=[5548, 5552]. +NPC id=1960, name=Mummy ashes, level=96, option=[null, null, null, null, null], anims=[5563, 5563]. +NPC id=1961, name=Mummy, level=103, option=[null, Attack, null, null, null], anims=[5548, 5552]. +NPC id=1962, name=Mummy, level=103, option=[null, Attack, null, null, null], anims=[5548, 5552]. +NPC id=1963, name=Mummy, level=103, option=[null, Attack, null, null, null], anims=[5548, 5552]. +NPC id=1964, name=Mummy, level=103, option=[null, Attack, null, null, null], anims=[5548, 5552]. +NPC id=1965, name=Mummy, level=103, option=[null, Attack, null, null, null], anims=[5548, 5552]. +NPC id=1966, name=Mummy, level=103, option=[null, Attack, null, null, null], anims=[5548, 5552]. +NPC id=1967, name=Mummy, level=103, option=[null, Attack, null, null, null], anims=[5548, 5552]. +NPC id=1968, name=Mummy, level=103, option=[null, Attack, null, null, null], anims=[5548, 5552]. +NPC id=1969, name=Scarabs, level=92, option=[null, Attack, null, null, null], anims=[1947, 1945]. +NPC id=1970, name=null, level=0, option=[null, null, null, null, null], anims=[125, 119]. +NPC id=1971, name=Azzanadra, level=0, option=[Talk-to, null, null, null, null], anims=[125, 119]. +NPC id=1972, name=Rasolo, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=1973, name=Giant skeleton, level=80, option=[null, Attack, null, null, null], anims=[5493, 5497]. +NPC id=1974, name=Damis, level=103, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=1975, name=Damis, level=174, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=1976, name=Shadow Hound, level=63, option=[null, Attack, null, null, null], anims=[6561, 6560]. +NPC id=1977, name=Fareed, level=167, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=1978, name=Slave, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1979, name=Slave, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1980, name=Embalmer, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=1981, name=Carpenter, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=1982, name=Raetul, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1983, name=Siamun, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1984, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC (wrapper) id=1985, child npcs=[1986, -1]. +NPC id=1986, name=High Priest, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1987, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=1988, name=Priest, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1989, name=Priest, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=1990, name=Sphinx, level=0, option=[Talk-to, null, null, null, null], anims=[2028, 2027]. +NPC id=1991, name=Possessed Priest, level=91, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=1992, name=Neite, level=0, option=[Talk-to, null, null, null, null], anims=[9158, 9157]. +NPC id=1993, name=Crocodile, level=63, option=[null, Attack, null, null, null], anims=[7589, 7587]. +NPC id=1994, name=Jackal, level=21, option=[null, Attack, null, null, null], anims=[6561, 6560]. +NPC id=1995, name=Locust, level=18, option=[null, Attack, null, null, null], anims=[2012, 2011]. +NPC id=1996, name=Vulture, level=31, option=[null, Attack, null, null, null], anims=[-1, -1]. +NPC id=1997, name=Plague frog, level=11, option=[null, Attack, null, null, null], anims=[1018, 1021]. +NPC id=1998, name=Plague cow, level=0, option=[Pet, null, null, null, null], anims=[5852, 5848]. +NPC id=1999, name=Plague cow, level=0, option=[Pet, null, null, null, null], anims=[5852, 5848]. +NPC id=2000, name=Plague cow, level=0, option=[Pet, null, null, null, null], anims=[5852, 5848]. +NPC id=2001, name=Scarab swarm, level=98, option=[null, Attack, null, null, null], anims=[1947, 1945]. +NPC (wrapper) id=2002, child npcs=[2006, -1]. +NPC id=2003, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2004, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2005, name=Wanderer, level=0, option=[Talk-to, null, null, null, null], anims=[808, 1146]. +NPC id=2006, name=Wanderer, level=0, option=[Talk-to, null, null, null, null], anims=[808, 1146]. +NPC id=2007, name=Het, level=81, option=[null, Attack, null, null, null], anims=[813, -1]. +NPC id=2008, name=Apmeken, level=75, option=[null, Attack, null, null, null], anims=[813, -1]. +NPC id=2009, name=Scabaras, level=75, option=[null, Attack, null, null, null], anims=[813, -1]. +NPC id=2010, name=Crondis, level=75, option=[null, Attack, null, null, null], anims=[813, -1]. +NPC id=2011, name=null, level=1, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=2012, name=Icthlarin, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=2013, name=null, level=1, option=[null, null, null, null, null], anims=[5538, 5539]. +NPC id=2014, name=Klenter, level=0, option=[Talk-to, null, null, null, null], anims=[5538, 5539]. +NPC id=2015, name=Mummy, level=84, option=[null, Attack, null, null, null], anims=[5551, 5553]. +NPC id=2016, name=Mummy, level=84, option=[null, Attack, null, null, null], anims=[5551, 5553]. +NPC id=2017, name=Mummy, level=84, option=[null, Attack, null, null, null], anims=[5551, 5553]. +NPC id=2018, name=Mummy, level=84, option=[null, Attack, null, null, null], anims=[5551, 5553]. +NPC id=2019, name=Mummy, level=84, option=[null, Attack, null, null, null], anims=[5551, 5553]. +NPC (wrapper) id=2020, child npcs=[1577, 1576, -1]. +NPC id=2021, name=Light creature, level=0, option=[null, null, null, null, null], anims=[2051, 2051]. +NPC id=2022, name=Light creature, level=0, option=[null, null, null, null, null], anims=[2051, 2051]. +NPC id=2023, name=Juna, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=2024, name=Strange Old Man, level=0, option=[Talk-to, null, null, null, null], anims=[1728, -1]. +NPC id=2025, name=Ahrim the Blighted, level=98, option=[null, Attack, null, null, null], anims=[813, -1]. +NPC id=2026, name=Dharok the Wretched, level=115, option=[null, Attack, null, null, null], anims=[2065, 2064]. +NPC id=2027, name=Guthan the Infested, level=115, option=[null, Attack, null, null, null], anims=[813, -1]. +NPC id=2028, name=Karil the Tainted, level=98, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=2029, name=Torag the Corrupted, level=115, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=2030, name=Verac the Defiled, level=115, option=[null, Attack, null, null, null], anims=[2061, 2060]. +NPC id=2031, name=Bloodworm, level=52, option=[null, Attack, null, null, null], anims=[2071, 2069]. +NPC id=2032, name=Crypt rat, level=43, option=[null, Attack, null, null, null], anims=[242, 239]. +NPC id=2033, name=Giant crypt rat, level=76, option=[null, Attack, null, null, null], anims=[4932, 4931]. +NPC id=2034, name=Crypt spider, level=56, option=[null, Attack, null, null, null], anims=[6247, 6248]. +NPC id=2035, name=Giant crypt spider, level=79, option=[null, Attack, null, null, null], anims=[5326, 5325]. +NPC id=2036, name=Skeleton, level=77, option=[null, Attack, null, null, null], anims=[5483, 5481]. +NPC id=2037, name=Skeleton, level=77, option=[null, Attack, null, null, null], anims=[5483, 5481]. +NPC id=2038, name=Grish, level=0, option=[Talk-to, null, null, null, null], anims=[357, 358]. +NPC id=2039, name=Uglug Nar, level=0, option=[Talk-to, null, Trade, null, null], anims=[357, 358]. +NPC id=2040, name=Pilg, level=0, option=[Talk-to, null, null, null, null], anims=[2088, -1]. +NPC id=2041, name=Grug, level=0, option=[Talk-to, null, null, null, null], anims=[2089, -1]. +NPC id=2042, name=Ogre guard, level=0, option=[Talk-to, null, null, null, null], anims=[357, 358]. +NPC id=2043, name=Ogre guard, level=76, option=[Talk-to, null, null, null, null], anims=[357, 358]. +NPC id=2044, name=Zogre, level=44, option=[null, Attack, null, null, null], anims=[357, 2104]. +NPC id=2045, name=Zogre, level=44, option=[null, Attack, null, null, null], anims=[357, 2104]. +NPC id=2046, name=Zogre, level=44, option=[null, Attack, null, null, null], anims=[357, 2104]. +NPC id=2047, name=Zogre, level=44, option=[null, Attack, null, null, null], anims=[357, 2104]. +NPC id=2048, name=Zogre, level=44, option=[null, Attack, null, null, null], anims=[357, 2104]. +NPC id=2049, name=Zogre, level=44, option=[null, Attack, null, null, null], anims=[357, 2104]. +NPC id=2050, name=Skogre, level=44, option=[null, Attack, null, null, null], anims=[2099, 358]. +NPC id=2051, name=Zogre, level=44, option=[null, Attack, null, null, null], anims=[2099, 2104]. +NPC id=2052, name=Zogre, level=44, option=[null, Attack, null, null, null], anims=[2099, 2104]. +NPC id=2053, name=Zogre, level=44, option=[null, Attack, null, null, null], anims=[2099, 2104]. +NPC id=2054, name=Zogre, level=44, option=[null, Attack, null, null, null], anims=[2099, 2104]. +NPC id=2055, name=Zogre, level=44, option=[null, Attack, null, null, null], anims=[2100, 2100]. +NPC id=2056, name=Skogre, level=44, option=[null, Attack, null, null, null], anims=[2100, 2100]. +NPC id=2057, name=Skogre, level=44, option=[null, Attack, null, null, null], anims=[357, 358]. +NPC id=2058, name=Zombie, level=39, option=[Talk-to, Attack, null, null, null], anims=[301, 298]. +NPC id=2059, name=Zavistic Rarve, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=2060, name=Slash Bash, level=111, option=[null, Attack, null, null, null], anims=[357, 358]. +NPC id=2061, name=Sithik Ints, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=2062, name=Sithik Ints, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=2063, name=Gargh, level=0, option=[Talk-to, null, null, null, null], anims=[357, 358]. +NPC id=2064, name=Scarg, level=0, option=[Talk-to, null, null, null, null], anims=[357, 358]. +NPC id=2065, name=Gruh, level=0, option=[Talk-to, null, null, null, null], anims=[357, 358]. +NPC id=2066, name=Irwin Feaselbaum, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2067, name=Fishing spot, level=0, option=[Net, null, Bait, hidden, hidden], anims=[2126, 2126]. +NPC id=2068, name=Fishing spot, level=0, option=[Net, null, Bait, hidden, hidden], anims=[2126, 2126]. +NPC id=2069, name=Cave goblin miner, level=11, option=[Talk-to, Attack, null, null, null], anims=[6006, 6005]. +NPC id=2070, name=Cave goblin miner, level=11, option=[Talk-to, Attack, null, null, null], anims=[6006, 6005]. +NPC id=2071, name=Cave goblin miner, level=11, option=[Talk-to, Attack, null, null, null], anims=[6006, 6005]. +NPC id=2072, name=Cave goblin miner, level=11, option=[Talk-to, Attack, null, null, null], anims=[6006, 6005]. +NPC id=2073, name=Cave goblin guard, level=26, option=[Talk-to, Attack, null, null, null], anims=[6006, 6005]. +NPC id=2074, name=Cave goblin guard, level=24, option=[Talk-to, Attack, null, null, null], anims=[6006, 6005]. +NPC id=2075, name=Cave goblin miner, level=11, option=[Talk-to, Attack, null, null, null], anims=[6004, 6005]. +NPC id=2076, name=Cave goblin miner, level=11, option=[Talk-to, Attack, null, null, null], anims=[6004, 6005]. +NPC id=2077, name=Cave goblin miner, level=11, option=[Talk-to, Attack, null, null, null], anims=[6004, 6005]. +NPC id=2078, name=Cave goblin miner, level=11, option=[Talk-to, Attack, null, null, null], anims=[6004, 6005]. +NPC (wrapper) id=2079, child npcs=[2082, 2082, 2082, 2082, 2082, 2082, 2082, 2082, 2082, 2082, -1]. +NPC id=2080, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2081, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2082, name=Sigmund, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[808, -1]. +NPC id=2083, name=Sigmund, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2084, name=Mistag, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=2085, name=null, level=1, option=[null, null, null, null, null], anims=[6006, 6005]. +NPC id=2086, name=Kazgar, level=0, option=[Talk-to, null, null, null, null], anims=[6006, 6005]. +NPC id=2087, name=Ur-tag, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=2088, name=Duke Horacio, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2089, name=Mistag, level=0, option=[null, null, null, null, null], anims=[6040, 6041]. +NPC id=2090, name=Sigmund, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2091, name=Secretary, level=0, option=[Talk-to, null, null, null, null], anims=[2157, 2156]. +NPC id=2092, name=Purple Pewter Secretary, level=0, option=[Talk-to, null, null, null, null], anims=[2157, 2156]. +NPC id=2093, name=Yellow Fortune Secretary, level=0, option=[Talk-to, null, null, null, null], anims=[2157, 2156]. +NPC id=2094, name=Blue Opal Secretary, level=0, option=[Talk-to, null, null, null, null], anims=[2158, -1]. +NPC id=2095, name=Green Gemstone Secretary, level=0, option=[Talk-to, null, null, null, null], anims=[2158, -1]. +NPC id=2096, name=White Chisel Secretary, level=0, option=[Talk-to, null, null, null, null], anims=[2158, -1]. +NPC id=2097, name=Silver Cog Secretary, level=0, option=[Talk-to, null, null, null, null], anims=[2158, -1]. +NPC id=2098, name=Brown Engine Secretary, level=0, option=[Talk-to, null, null, null, null], anims=[2158, -1]. +NPC id=2099, name=Red Axe Secretary, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2100, name=Purple Pewter Director, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2101, name=Blue Opal Director, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2102, name=Yellow Fortune Director, level=0, option=[Talk-to, null, null, null, null], anims=[2157, 2156]. +NPC id=2103, name=Green Gemstone Director, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2104, name=White Chisel Director, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2105, name=Silver Cog Director, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2106, name=Brown Engine Director, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2107, name=Red Axe Director, level=0, option=[Talk-to, null, null, null, null], anims=[2155, 2154]. +NPC id=2108, name=Red Axe Cat, level=0, option=[null, null, null, null, null], anims=[9158, 9157]. +NPC id=2109, name=Trader, level=0, option=[null, null, null, null, null], anims=[101, 98]. +NPC id=2110, name=Trader, level=0, option=[null, null, null, null, null], anims=[2157, 2156]. +NPC id=2111, name=Trader, level=0, option=[null, null, null, null, null], anims=[101, 98]. +NPC id=2112, name=Trader, level=0, option=[null, null, null, null, null], anims=[101, 98]. +NPC id=2113, name=Trader, level=0, option=[null, null, null, null, null], anims=[2157, 2156]. +NPC id=2114, name=Trader, level=0, option=[null, null, null, null, null], anims=[2157, 2156]. +NPC id=2115, name=Trader, level=0, option=[null, null, null, null, null], anims=[101, 98]. +NPC id=2116, name=Trader, level=0, option=[null, null, null, null, null], anims=[101, 98]. +NPC id=2117, name=Trader, level=0, option=[null, null, null, null, null], anims=[101, 98]. +NPC id=2118, name=Trader, level=0, option=[null, null, null, null, null], anims=[101, 98]. +NPC id=2119, name=Trader, level=0, option=[null, null, null, null, null], anims=[101, 98]. +NPC id=2120, name=Trader, level=0, option=[null, null, null, null, null], anims=[101, 98]. +NPC id=2121, name=Trader, level=0, option=[null, null, null, null, null], anims=[101, 98]. +NPC id=2122, name=Trader, level=0, option=[null, null, null, null, null], anims=[2157, 2156]. +NPC (wrapper) id=2123, child npcs=[2124, -1]. +NPC id=2124, name=Trader, level=0, option=[null, null, null, null, null], anims=[101, 98]. +NPC (wrapper) id=2125, child npcs=[2126, -1]. +NPC id=2126, name=Trader, level=0, option=[null, null, null, null, null], anims=[101, 98]. +NPC id=2127, name=Trade Referee, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2128, name=Supreme Commander, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2129, name=Commander Veldaban, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2130, name=Black Guard, level=48, option=[Talk-to, Attack, null, null, null], anims=[101, 98]. +NPC id=2131, name=Black Guard, level=48, option=[Talk-to, Attack, null, null, null], anims=[101, 98]. +NPC id=2132, name=Black Guard, level=48, option=[Talk-to, Attack, null, null, null], anims=[101, 98]. +NPC id=2133, name=Black Guard, level=48, option=[Talk-to, Attack, null, null, null], anims=[101, 98]. +NPC id=2134, name=Black Guard Berserker, level=66, option=[Talk-to, Attack, null, null, null], anims=[101, 98]. +NPC id=2135, name=Black Guard Berserker, level=66, option=[Talk-to, Attack, null, null, null], anims=[101, 98]. +NPC id=2136, name=Black Guard Berserker, level=66, option=[Talk-to, Attack, null, null, null], anims=[101, 98]. +NPC id=2137, name=Gnome emissary, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=2138, name=Gnome traveller, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=2139, name=Gnome traveller, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=2140, name=Dromund's cat, level=0, option=[Talk-to, null, null, null, null], anims=[9171, -1]. +NPC id=2141, name=Blasidar the sculptor, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC (wrapper) id=2142, child npcs=[2143, 2144, 2145, 2147, 2146, 2148, 2149, 2150, -1]. +NPC id=2143, name=Riki the sculptor's model, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2144, name=Riki the sculptor's model, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2145, name=Riki the sculptor's model, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2146, name=Riki the sculptor's model, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2147, name=Riki the sculptor's model, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2148, name=Riki the sculptor's model, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2149, name=Riki the sculptor's model, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2150, name=Riki the sculptor's model, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2151, name=Vigr, level=0, option=[Talk-to, null, Trade, null, null], anims=[101, 98]. +NPC id=2152, name=Santiri, level=0, option=[Talk-to, null, Trade, null, null], anims=[101, 98]. +NPC id=2153, name=Saro, level=0, option=[Talk-to, null, Trade, null, null], anims=[101, 98]. +NPC id=2154, name=Gunslik, level=0, option=[Talk-to, null, Trade, null, null], anims=[101, 98]. +NPC id=2155, name=Wemund, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2156, name=Randivor, level=0, option=[Talk-to, null, Trade, null, null], anims=[101, 98]. +NPC id=2157, name=Hervi, level=0, option=[Talk-to, null, Trade, null, null], anims=[101, 98]. +NPC id=2158, name=Nolar, level=0, option=[Talk-to, null, Trade, null, null], anims=[101, 98]. +NPC id=2159, name=Gulldamar, level=0, option=[Talk-to, null, Trade, null, null], anims=[101, 98]. +NPC id=2160, name=Tati, level=0, option=[Talk-to, null, Trade, null, null], anims=[2155, 2154]. +NPC id=2161, name=Agmundi, level=0, option=[Talk-to, null, Trade, null, null], anims=[2157, 2156]. +NPC id=2162, name=Vermundi, level=0, option=[Talk-to, null, Trade, null, null], anims=[2157, 2156]. +NPC id=2163, name=Banker, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[2157, 2157]. +NPC id=2164, name=Banker, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[101, 101]. +NPC id=2165, name=Librarian, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2166, name=Assistant, level=0, option=[Talk-to, null, null, null, null], anims=[2157, 2156]. +NPC id=2167, name=Customer, level=0, option=[Talk-to, null, null, null, null], anims=[2157, 2156]. +NPC id=2168, name=Customer, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2169, name=Dromund, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2170, name=Rind the gardener, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2171, name=Factory Manager, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2172, name=Factory Worker, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2173, name=Factory Worker, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2174, name=Factory Worker, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2175, name=Factory Worker, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2176, name=Inn Keeper, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2177, name=Inn Keeper, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2178, name=Barmaid, level=0, option=[Talk-to, null, null, null, null], anims=[2157, 2156]. +NPC id=2179, name=Barman, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2180, name=Cart conductor, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2181, name=Cart conductor, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2182, name=Cart conductor, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2183, name=Cart conductor, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2184, name=Cart conductor, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2185, name=Cart conductor, level=0, option=[Talk-to, null, null, null, null], anims=[900, 104]. +NPC id=2186, name=Cart conductor, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2187, name=Rowdy dwarf, level=0, option=[Talk-to, null, null, null, null], anims=[101, 104]. +NPC id=2188, name=Hegir, level=0, option=[Talk-to, null, null, null, null], anims=[2155, 2154]. +NPC id=2189, name=Haera, level=0, option=[Talk-to, null, null, null, null], anims=[2157, 2156]. +NPC id=2190, name=Runvastr, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2191, name=Sune, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2192, name=Bentamir, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2193, name=Ulifed, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2194, name=Reinald, level=0, option=[Talk-to, null, Change-armguards, null, null], anims=[101, 98]. +NPC id=2195, name=Karl, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2196, name=Gauss, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2197, name=Myndill, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2198, name=Kjut, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2199, name=Tombar, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2200, name=Odmar, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2201, name=Audmann, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC (wrapper) id=2202, child npcs=[2203, 2204, -1]. +NPC id=2203, name=Drunken Dwarf, level=0, option=[Talk-to, null, null, null, null], anims=[900, 104]. +NPC id=2204, name=Drunken Dwarf, level=0, option=[Talk-to, null, null, null, null], anims=[900, 104]. +NPC id=2205, name=Dwarven Boatman, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2206, name=Dwarven Boatman, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2207, name=Dwarven Miner, level=0, option=[null, null, null, null, null], anims=[2150, 2150]. +NPC id=2208, name=Dwarven Miner, level=0, option=[Talk-to, null, null, null, null], anims=[2150, 2150]. +NPC id=2209, name=Dwarven Miner, level=0, option=[null, null, null, null, null], anims=[101, 98]. +NPC id=2210, name=Dwarven Miner, level=0, option=[null, null, null, null, null], anims=[101, 98]. +NPC id=2211, name=Dwarven Miner, level=0, option=[null, null, null, null, null], anims=[2150, 2150]. +NPC id=2212, name=Dwarven Miner, level=0, option=[Talk-to, null, null, null, null], anims=[2150, 2150]. +NPC id=2213, name=Dwarven Miner, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2214, name=Dwarven Miner, level=0, option=[null, null, null, null, null], anims=[101, 98]. +NPC id=2215, name=Dwarven Miner, level=0, option=[null, null, null, null, null], anims=[2150, 2150]. +NPC id=2216, name=Dwarven Miner, level=0, option=[Talk-to, null, null, null, null], anims=[2150, 2150]. +NPC id=2217, name=Dwarven Miner, level=0, option=[null, null, null, null, null], anims=[101, 98]. +NPC id=2218, name=Dwarven Miner, level=0, option=[null, null, null, null, null], anims=[101, 98]. +NPC id=2219, name=Purple Pewter Director, level=0, option=[null, null, null, null, null], anims=[2151, 98]. +NPC id=2220, name=Purple Pewter Director, level=0, option=[null, null, null, null, null], anims=[101, 98]. +NPC id=2221, name=Blue Opal Director, level=0, option=[null, null, null, null, null], anims=[101, 98]. +NPC id=2222, name=Yellow Fortune Director, level=0, option=[null, null, null, null, null], anims=[2153, 2156]. +NPC id=2223, name=Green Gemstone Director, level=0, option=[null, null, null, null, null], anims=[101, 98]. +NPC id=2224, name=White Chisel Director, level=0, option=[null, null, null, null, null], anims=[2152, 98]. +NPC id=2225, name=Silver Cog Director, level=0, option=[null, null, null, null, null], anims=[101, 98]. +NPC id=2226, name=Brown Engine Director, level=0, option=[null, null, null, null, null], anims=[2152, 98]. +NPC id=2227, name=Red Axe Director, level=0, option=[null, null, null, null, null], anims=[2155, 2154]. +NPC id=2228, name=Commander Veldaban, level=0, option=[null, null, null, null, null], anims=[101, 98]. +NPC id=2229, name=Red Axe Cat, level=0, option=[null, null, null, null, null], anims=[9158, 9157]. +NPC id=2230, name=Red Axe Cat, level=0, option=[null, null, null, null, null], anims=[9169, 9157]. +NPC id=2231, name=null, level=0, option=[null, null, null, null, null], anims=[101, 98]. +NPC id=2232, name=Black Guard Berserker, level=0, option=[null, null, null, null, null], anims=[101, 98]. +NPC id=2233, name=Olivia, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=2234, name=Master Farmer, level=0, option=[null, null, Pickpocket, null, null], anims=[808, -1]. +NPC id=2235, name=Master Farmer, level=0, option=[null, null, Pickpocket, null, null], anims=[2163, 2164]. +NPC id=2236, name=Market Guard, level=20, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=2237, name=Gee, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=2238, name=Donie, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=2239, name=Pig, level=0, option=[null, null, null, null, null], anims=[2166, 2165]. +NPC id=2240, name=Pig, level=0, option=[null, null, null, null, null], anims=[2166, 2165]. +NPC id=2241, name=Piglet, level=0, option=[null, null, null, null, null], anims=[2166, 2165]. +NPC id=2242, name=Piglet, level=0, option=[null, null, null, null, null], anims=[2166, 2165]. +NPC id=2243, name=Piglet, level=0, option=[null, null, null, null, null], anims=[2166, 2165]. +NPC id=2244, name=Lumbridge Guide, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=2245, name=Khazard trooper, level=19, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=2246, name=Khazard trooper, level=19, option=[null, Attack, null, null, null], anims=[813, -1]. +NPC id=2247, name=Gnome troop, level=3, option=[null, Attack, null, null, null], anims=[195, 189]. +NPC id=2248, name=Gnome troop, level=3, option=[null, Attack, null, null, null], anims=[195, 189]. +NPC id=2249, name=Gnome, level=3, option=[null, Attack, null, null, null], anims=[195, 189]. +NPC id=2250, name=Gnome, level=1, option=[null, Attack, null, null, null], anims=[195, 189]. +NPC id=2251, name=Gnome, level=3, option=[null, Attack, null, null, null], anims=[195, 189]. +NPC id=2252, name=Crow, level=0, option=[null, null, null, null, null], anims=[6785, 6784]. +NPC id=2253, name=Wise Old Man, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=2254, name=Bed, level=0, option=[Kick, null, null, null, null], anims=[2170, -1]. +NPC id=2255, name=Thing under the bed, level=0, option=[null, Attack, null, null, null], anims=[2170, -1]. +NPC id=2256, name=Paladin, level=62, option=[null, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC (wrapper) id=2257, child npcs=[2258, 2258, 2258, 2258, 2259, -1]. +NPC id=2258, name=Mage of Zamorak, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=2259, name=Mage of Zamorak, level=0, option=[Talk-to, null, Trade, Teleport, null], anims=[808, -1]. +NPC id=2260, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2261, name=Mage of Zamorak, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2262, name=Dark mage, level=0, option=[Talk-to, null, Repair-pouches, null, null], anims=[2149, 2149]. +NPC id=2263, name=Abyssal leech, level=41, option=[null, Attack, null, null, null], anims=[2180, 2179]. +NPC id=2264, name=Abyssal guardian, level=59, option=[null, Attack, null, null, null], anims=[2185, 2184]. +NPC id=2265, name=Abyssal walker, level=81, option=[null, Attack, null, null, null], anims=[2191, 2190]. +NPC id=2266, name=Brian O'Richard, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2267, name=Rogue Guard, level=0, option=[null, null, hidden, null, null], anims=[808, -1]. +NPC id=2268, name=Rogue Guard, level=0, option=[null, null, hidden, null, null], anims=[808, -1]. +NPC id=2269, name=Rogue Guard, level=0, option=[null, null, hidden, null, null], anims=[808, -1]. +NPC id=2270, name=Martin Thwait, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=2271, name=Emerald Benedict, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[808, -1]. +NPC id=2272, name=Spin Blades, level=0, option=[null, null, null, null, null], anims=[-1, 2212]. +NPC id=2273, name=Spin Blades, level=0, option=[null, null, null, null, null], anims=[-1, 2212]. +NPC id=2274, name=Goblin, level=2, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=2275, name=Goblin, level=2, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=2276, name=Goblin, level=2, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=2277, name=Goblin, level=2, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=2278, name=Goblin, level=2, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=2279, name=Goblin, level=2, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=2280, name=Goblin, level=2, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=2281, name=Goblin, level=2, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=2282, name=Sir Spishyus, level=0, option=[Talk-to, null, null, null, null], anims=[2253, -1]. +NPC id=2283, name=Lady Table, level=0, option=[Talk-to, null, null, null, null], anims=[2256, -1]. +NPC id=2284, name=Sir Kuam Ferentse, level=0, option=[Talk-to, null, null, null, null], anims=[2253, -1]. +NPC id=2285, name=Sir Leye, level=20, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=2286, name=Sir Tinley, level=0, option=[Talk-to, null, null, null, null], anims=[2253, -1]. +NPC id=2287, name=Sir Ren Itchood, level=0, option=[Talk-to, null, null, null, null], anims=[1321, -1]. +NPC id=2288, name=Miss Cheevers, level=0, option=[Talk-to, null, null, null, null], anims=[2256, -1]. +NPC id=2289, name=Ms. Hynn Terprett, level=0, option=[Talk-to, null, null, null, null], anims=[2255, -1]. +NPC id=2290, name=Sir Tiffy Cashien, level=0, option=[Talk-to, null, null, null, null], anims=[4838, -1]. +NPC id=2291, name=Rug Merchant, level=0, option=[Talk-to, null, Travel, null, null], anims=[808, -1]. +NPC id=2292, name=Rug Merchant, level=0, option=[Talk-to, null, Travel, null, null], anims=[808, -1]. +NPC id=2293, name=Rug Merchant, level=0, option=[Talk-to, null, Travel, null, null], anims=[808, -1]. +NPC id=2294, name=Rug Merchant, level=0, option=[Talk-to, null, Travel, null, null], anims=[1144, -1]. +NPC id=2295, name=null, level=1, option=[Talk-to, null, Travel, null, null], anims=[1144, -1]. +NPC id=2296, name=Rug Merchant, level=0, option=[Talk-to, null, Travel, null, null], anims=[1144, -1]. +NPC id=2297, name=null, level=0, option=[Talk-to, null, Travel, null, null], anims=[808, -1]. +NPC id=2298, name=Rug Merchant, level=0, option=[Talk-to, null, Travel, null, null], anims=[808, -1]. +NPC id=2299, name=null, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2300, name=Rug Station Attendant, level=0, option=[Talk-to, null, Travel, null, null], anims=[808, -1]. +NPC id=2301, name=Monkey, level=0, option=[Talk-to, null, null, null, null], anims=[222, 219]. +NPC id=2302, name=null, level=0, option=[Talk-to, null, null, null, null], anims=[222, 219]. +NPC id=2303, name=null, level=0, option=[Talk-to, null, null, null, null], anims=[222, 219]. +NPC id=2304, name=Sarah, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=2305, name=Vanessa, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=2306, name=Richard, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=2307, name=Alice, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=2308, name=Capt' Arnav, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=2309, name=, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=2310, name=Cow calf, level=2, option=[null, Attack, null, null, null], anims=[5852, 5856]. +NPC id=2311, name=Sheepdog, level=0, option=[null, null, null, null, null], anims=[2268, -1]. +NPC id=2312, name=Rooster, level=0, option=[null, null, null, null, null], anims=[2298, 2297]. +NPC id=2313, name=Chicken, level=1, option=[null, Attack, null, null, null], anims=[5386, 5385]. +NPC id=2314, name=Chicken, level=1, option=[null, Attack, null, null, null], anims=[5386, 5385]. +NPC id=2315, name=Chicken, level=1, option=[null, Attack, null, null, null], anims=[5386, 5385]. +NPC id=2316, name=Pig, level=0, option=[null, null, null, null, null], anims=[2166, 2165]. +NPC id=2317, name=Pig, level=0, option=[null, null, null, null, null], anims=[2166, 2165]. +NPC id=2318, name=Piglet, level=0, option=[null, null, null, null, null], anims=[2166, 2165]. +NPC id=2319, name=Piglet, level=0, option=[null, null, null, null, null], anims=[2166, 2165]. +NPC id=2320, name=Piglet, level=0, option=[null, null, null, null, null], anims=[2166, 2165]. +NPC id=2321, name=Blandebir, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2322, name=Metarialus, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2323, name=Elstan, level=0, option=[Talk-to, null, Pay (North-west), Pay (South-east), null], anims=[2163, 2164]. +NPC id=2324, name=Dantaera, level=0, option=[Talk-to, null, Pay (North), Pay (South), null], anims=[808, -1]. +NPC id=2325, name=Kragen, level=0, option=[Talk-to, null, Pay (North), Pay (South), null], anims=[2163, 2164]. +NPC id=2326, name=Lyra, level=0, option=[Talk-to, null, Pay (North-west), Pay (South-east), null], anims=[808, -1]. +NPC id=2327, name=Francis, level=0, option=[Talk-to, null, Pay, null, null], anims=[808, -1]. +NPC id=2328, name=Wizard Cromperty, level=0, option=[Talk-to, null, Teleport, null, null], anims=[-1, -1]. +NPC id=2329, name=Muncher, level=0, option=[Interact, null, null, null, null], anims=[6580, 6577]. +NPC id=2330, name=Garth, level=0, option=[Talk-to, null, Pay, null, null], anims=[2163, 2164]. +NPC id=2331, name=Ellena, level=0, option=[Talk-to, null, Pay, null, null], anims=[808, -1]. +NPC id=2332, name=Selena, level=0, option=[Talk-to, null, Pay, null, null], anims=[808, -1]. +NPC id=2333, name=Vasquen, level=0, option=[Talk-to, null, Pay, null, null], anims=[2163, 2164]. +NPC id=2334, name=Rhonen, level=0, option=[Talk-to, null, Pay, null, null], anims=[808, -1]. +NPC id=2335, name=Dreven, level=0, option=[Talk-to, null, Pay, null, null], anims=[2163, 2164]. +NPC id=2336, name=Taria, level=0, option=[Talk-to, null, Pay, null, null], anims=[808, -1]. +NPC id=2337, name=Rhazien, level=0, option=[Talk-to, null, Pay, null, null], anims=[2163, 2164]. +NPC id=2338, name=Torrell, level=0, option=[Talk-to, null, Pay, null, null], anims=[808, -1]. +NPC id=2339, name=Alain, level=0, option=[Talk-to, null, Pay, null, null], anims=[8528, 8527]. +NPC id=2340, name=Heskel, level=0, option=[Talk-to, null, Pay, null, null], anims=[808, -1]. +NPC id=2341, name=Treznor, level=0, option=[Talk-to, null, Pay, null, null], anims=[808, -1]. +NPC id=2342, name=Fayeth, level=0, option=[Talk-to, null, Pay, null, null], anims=[808, -1]. +NPC id=2343, name=Bolongo, level=0, option=[Talk-to, null, Pay, null, null], anims=[195, 189]. +NPC id=2344, name=Gileth, level=0, option=[Talk-to, null, Pay, null, null], anims=[808, -1]. +NPC id=2345, name=Sick-looking sheep (1), level=0, option=[Prod, null, null, null, null], anims=[5335, 5334]. +NPC id=2346, name=Sick-looking sheep (2), level=0, option=[Prod, null, null, null, null], anims=[5335, 5334]. +NPC id=2347, name=Sick-looking sheep (3), level=0, option=[Prod, null, null, null, null], anims=[5335, 5334]. +NPC id=2348, name=Sick-looking sheep (4), level=0, option=[Prod, null, null, null, null], anims=[5335, 5334]. +NPC id=2349, name=Mourner, level=11, option=[null, Attack, null, null, null], anims=[813, -1]. +NPC id=2350, name=Mourner, level=11, option=[null, Attack, null, null, null], anims=[813, -1]. +NPC id=2351, name=Mourner, level=11, option=[null, Attack, null, null, null], anims=[813, -1]. +NPC id=2352, name=Eudav, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=2353, name=Oronwen, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=2354, name=Banker, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[808, 808]. +NPC id=2355, name=Banker, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[808, 808]. +NPC id=2356, name=Dalldav, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=2357, name=Gethin, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=2358, name=Arianwyn, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2359, name=Elf warrior, level=108, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=2360, name=Elf warrior, level=108, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=2361, name=Elf warrior, level=90, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=2362, name=Elf warrior, level=90, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=2363, name=Goreu, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[808, -1]. +NPC id=2364, name=Ysgawyn, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[808, -1]. +NPC id=2365, name=Arvel, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[808, -1]. +NPC id=2366, name=Mawrth, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[808, -1]. +NPC id=2367, name=Kelyn, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[808, -1]. +NPC id=2368, name=Eoin, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2369, name=Iona, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2370, name=null, level=0, option=[null, null, null, null, null], anims=[195, 189]. +NPC id=2371, name=Gnome, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=2372, name=Head mourner, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2373, name=Mourner, level=108, option=[null, Attack, null, null, null], anims=[813, -1]. +NPC id=2374, name=Mourner, level=0, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=2375, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2376, name=Eluned, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2377, name=Sick-looking sheep (1), level=0, option=[null, null, null, null, null], anims=[5335, 5334]. +NPC id=2378, name=Sick-looking sheep (2), level=0, option=[null, null, null, null, null], anims=[5335, 5334]. +NPC id=2379, name=Sick-looking sheep (3), level=0, option=[null, null, null, null, null], anims=[5335, 5334]. +NPC id=2380, name=Sick-looking sheep (4), level=0, option=[null, null, null, null, null], anims=[5335, 5334]. +NPC id=2381, name=null, level=1, option=[null, null, null, null, null], anims=[2334, 2333]. +NPC id=2382, name=null, level=1, option=[null, null, null, null, null], anims=[2334, 2333]. +NPC id=2383, name=null, level=1, option=[null, null, null, null, null], anims=[2334, 2333]. +NPC id=2384, name=null, level=1, option=[null, null, null, null, null], anims=[2334, 2333]. +NPC id=2385, name=null, level=1, option=[null, null, null, null, null], anims=[2334, 2333]. +NPC id=2386, name=null, level=1, option=[null, null, null, null, null], anims=[2334, 2333]. +NPC id=2387, name=null, level=1, option=[null, null, null, null, null], anims=[2334, 2333]. +NPC id=2388, name=null, level=1, option=[null, null, null, null, null], anims=[2334, 2333]. +NPC id=2389, name=null, level=1, option=[null, null, null, null, null], anims=[2334, 2333]. +NPC id=2390, name=null, level=1, option=[null, null, null, null, null], anims=[2334, 2333]. +NPC id=2391, name=null, level=1, option=[null, null, null, null, null], anims=[2334, 2333]. +NPC id=2392, name=null, level=1, option=[null, null, null, null, null], anims=[2334, 2333]. +NPC id=2393, name=null, level=1, option=[null, null, null, null, null], anims=[2334, 2333]. +NPC id=2394, name=null, level=1, option=[null, null, null, null, null], anims=[2334, 2333]. +NPC id=2395, name=null, level=1, option=[null, null, null, null, null], anims=[2334, 2333]. +NPC id=2396, name=null, level=1, option=[null, null, null, null, null], anims=[2334, 2333]. +NPC id=2397, name=Mysterious ghost, level=0, option=[Talk-To, null, null, null, null], anims=[2334, 2333]. +NPC id=2398, name=Mysterious ghost, level=0, option=[Talk-To, null, null, null, null], anims=[2334, 2333]. +NPC id=2399, name=Mysterious ghost, level=0, option=[Talk-To, null, null, null, null], anims=[2334, 2333]. +NPC id=2400, name=Mysterious ghost, level=0, option=[Talk-To, null, null, null, null], anims=[2334, 2333]. +NPC id=2401, name=Mysterious ghost, level=0, option=[Talk-To, null, null, null, null], anims=[2334, 2333]. +NPC id=2402, name=Mysterious ghost, level=0, option=[Talk-To, null, null, null, null], anims=[2334, 2333]. +NPC (wrapper) id=2403, child npcs=[2099, -1]. +NPC (wrapper) id=2404, child npcs=[2107, -1]. +NPC (wrapper) id=2405, child npcs=[2108, -1]. +NPC (wrapper) id=2406, child npcs=[2137, -1]. +NPC (wrapper) id=2407, child npcs=[2138, -1]. +NPC (wrapper) id=2408, child npcs=[2139, -1]. +NPC id=2409, name=Cart conductor, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2410, name=Red Axe Director, level=0, option=[null, null, null, null, null], anims=[2155, 2154]. +NPC id=2411, name=Red Axe Director, level=0, option=[Listen-to, null, null, null, null], anims=[2155, 2154]. +NPC id=2412, name=Red Axe Henchman, level=0, option=[null, null, null, null, null], anims=[2336, 2335]. +NPC id=2413, name=Red Axe Henchman, level=0, option=[Listen-to, null, null, null, null], anims=[2336, 2335]. +NPC id=2414, name=Red Axe Henchman, level=0, option=[null, null, null, null, null], anims=[101, 98]. +NPC id=2415, name=Colonel Grimsson, level=0, option=[null, null, null, null, null], anims=[2336, 2335]. +NPC id=2416, name=Colonel Grimsson, level=0, option=[null, null, null, null, null], anims=[101, 98]. +NPC id=2417, name=Ogre shaman, level=0, option=[null, null, null, null, null], anims=[357, 358]. +NPC id=2418, name=Ogre shaman, level=0, option=[Listen-to, null, null, null, null], anims=[357, 358]. +NPC id=2419, name=Grunsh, level=0, option=[null, null, null, null, null], anims=[357, 358]. +NPC id=2420, name=Gnome emissary, level=0, option=[null, null, null, null, null], anims=[195, 189]. +NPC id=2421, name=Gnome companion, level=0, option=[null, null, null, null, null], anims=[195, 189]. +NPC id=2422, name=Gnome companion, level=0, option=[null, null, null, null, null], anims=[195, 189]. +NPC id=2423, name=Chaos dwarf, level=48, option=[null, null, null, null, null], anims=[101, 98]. +NPC id=2424, name=Gunslik, level=0, option=[null, null, null, null, null], anims=[101, 98]. +NPC id=2425, name=Nolar, level=0, option=[null, null, null, null, null], anims=[101, 98]. +NPC id=2426, name=Factory Worker, level=0, option=[null, null, null, null, null], anims=[101, 98]. +NPC id=2427, name=Cart conductor, level=0, option=[null, null, null, null, null], anims=[900, 104]. +NPC id=2428, name=Gauss, level=0, option=[null, null, null, null, null], anims=[2337, 104]. +NPC id=2429, name=Drunken Dwarf, level=0, option=[null, null, null, null, null], anims=[900, 104]. +NPC id=2430, name=Rowdy dwarf, level=0, option=[null, null, null, null, null], anims=[101, 104]. +NPC id=2431, name=Ulifed, level=0, option=[Talk-to, null, null, null, null], anims=[2337, 98]. +NPC id=2432, name=Red Axe Henchman, level=1, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2433, name=Red Axe Henchman, level=1, option=[Talk-to, null, null, null, null], anims=[2341, 2335]. +NPC id=2434, name=Ogre shaman, level=1, option=[Talk-to, Attack, null, null, null], anims=[357, 358]. +NPC (wrapper) id=2435, child npcs=[2436, 2437, -1]. +NPC id=2436, name=Jarvald, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=2437, name=Jarvald, level=0, option=[Talk-to, null, Travel, null, null], anims=[813, -1]. +NPC id=2438, name=Jarvald, level=0, option=[Talk-to, null, Travel, null, null], anims=[813, -1]. +NPC id=2439, name=Askeladden, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=2440, name=Door-support, level=0, option=[null, Destroy, null, null, null], anims=[-1, -1]. +NPC id=2441, name=Door, level=0, option=[null, null, null, null, null], anims=[2351, -1]. +NPC id=2442, name=Door, level=0, option=[null, null, null, null, null], anims=[2352, -1]. +NPC id=2443, name=Door-support, level=0, option=[null, Destroy, null, null, null], anims=[2354, -1]. +NPC id=2444, name=Door, level=0, option=[null, null, null, null, null], anims=[2353, -1]. +NPC id=2445, name=Door, level=0, option=[null, null, null, null, null], anims=[2355, -1]. +NPC id=2446, name=Door-support, level=0, option=[null, Destroy, null, null, null], anims=[2357, -1]. +NPC id=2447, name=Door, level=0, option=[null, null, null, null, null], anims=[2356, -1]. +NPC id=2448, name=Door, level=0, option=[null, null, null, null, null], anims=[2358, -1]. +NPC id=2449, name=Egg, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=2450, name=Egg, level=0, option=[null, null, null, null, null], anims=[2362, 2362]. +NPC id=2451, name=Egg, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=2452, name=Giant Rock Crab, level=137, option=[null, Attack, null, null, null], anims=[1310, 1311]. +NPC id=2453, name=Boulder, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=2454, name=Dagannoth spawn, level=42, option=[null, Attack, null, null, null], anims=[1338, 2361]. +NPC id=2455, name=Dagannoth, level=90, option=[null, Attack, null, null, null], anims=[1338, 1339]. +NPC id=2456, name=Dagannoth, level=88, option=[null, Attack, null, null, null], anims=[1338, 1339]. +NPC id=2457, name=Wallasalki, level=98, option=[null, Attack, null, null, null], anims=[2364, 2363]. +NPC id=2458, name=Freaky Forester, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2459, name=Pheasant, level=3, option=[null, Attack, null, null, null], anims=[2370, 2369]. +NPC id=2460, name=Pheasant, level=3, option=[null, Attack, null, null, null], anims=[2370, 2369]. +NPC id=2461, name=Pheasant, level=3, option=[null, Attack, null, null, null], anims=[2370, 2369]. +NPC id=2462, name=Pheasant, level=3, option=[null, Attack, null, null, null], anims=[2370, 2369]. +NPC id=2463, name=Evil Chicken, level=19, option=[null, Attack, null, null, null], anims=[2298, 2297]. +NPC id=2464, name=Evil Chicken, level=38, option=[null, Attack, null, null, null], anims=[2298, 2297]. +NPC id=2465, name=Evil Chicken, level=69, option=[null, Attack, null, null, null], anims=[2298, 2297]. +NPC id=2466, name=Evil Chicken, level=81, option=[null, Attack, null, null, null], anims=[2298, 2297]. +NPC id=2467, name=Evil Chicken, level=121, option=[null, Attack, null, null, null], anims=[2298, 2297]. +NPC id=2468, name=Evil Chicken, level=159, option=[null, Attack, null, null, null], anims=[2298, 2297]. +NPC id=2469, name=Frog, level=0, option=[Talk-to, null, null, null, null], anims=[1796, 1797]. +NPC id=2470, name=Frog, level=0, option=[Talk-to, null, null, null, null], anims=[1796, 1797]. +NPC id=2471, name=Frog, level=0, option=[Talk-to, null, null, null, null], anims=[1796, 1797]. +NPC id=2472, name=Frog, level=0, option=[Talk-to, null, null, null, null], anims=[1796, 1797]. +NPC id=2473, name=Frog, level=0, option=[null, null, null, null, null], anims=[1796, 1797]. +NPC id=2474, name=Frog prince, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2475, name=Frog princess, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2476, name=Rick Turpentine, level=0, option=[Talk-to, null, null, null, null], anims=[4591, -1]. +NPC id=2477, name=Quiz Master, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2478, name=Evil Bob, level=0, option=[null, null, null, null, null], anims=[9158, 9157]. +NPC id=2479, name=Evil Bob, level=0, option=[Talk-to, null, null, null, null], anims=[9158, 9157]. +NPC id=2480, name=Servant, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2481, name=Servant, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2482, name=Giant bat, level=0, option=[null, null, null, null, null], anims=[4914, 4913]. +NPC (wrapper) id=2483, child npcs=[1163, 1163, 1163, 1163, 1163, 1163, -1]. +NPC id=2484, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC (wrapper) id=2485, child npcs=[1165, 1165, 1165, 1165, 1165, 1165, -1]. +NPC id=2486, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC (wrapper) id=2487, child npcs=[1167, 1167, 1167, 1167, 1167, 1167, -1]. +NPC id=2488, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2489, name=Bush snake, level=35, option=[null, Attack, null, null, null], anims=[277, 274]. +NPC id=2490, name=Bush snake, level=35, option=[null, Attack, null, null, null], anims=[277, 2392]. +NPC id=2491, name=Jungle spider, level=44, option=[null, Attack, null, null, null], anims=[5326, 5325]. +NPC id=2492, name=Jungle spider, level=44, option=[null, Attack, null, null, null], anims=[5326, 5333]. +NPC id=2493, name=Large mosquito, level=13, option=[null, Attack, null, null, null], anims=[2395, 2396]. +NPC id=2494, name=Mosquito swarm, level=17, option=[null, Attack, null, null, null], anims=[2395, 2396]. +NPC id=2495, name=Mosquito swarm, level=20, option=[null, Attack, null, null, null], anims=[2395, 2396]. +NPC id=2496, name=Tribesman, level=32, option=[null, null, null, null, null], anims=[2400, -1]. +NPC id=2497, name=Tribesman, level=32, option=[null, Attack, null, null, null], anims=[813, -1]. +NPC id=2498, name=Broodoo victim, level=1, option=[null, null, null, null, null], anims=[2400, -1]. +NPC id=2499, name=Broodoo victim, level=60, option=[null, Attack, null, null, null], anims=[2401, -1]. +NPC id=2500, name=Broodoo victim, level=1, option=[null, null, null, null, null], anims=[2400, -1]. +NPC id=2501, name=Broodoo victim, level=60, option=[null, Attack, null, null, null], anims=[2401, -1]. +NPC id=2502, name=Broodoo victim, level=1, option=[null, null, null, null, null], anims=[2400, -1]. +NPC id=2503, name=Broodoo victim, level=60, option=[null, Attack, null, null, null], anims=[2401, -1]. +NPC id=2504, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2505, name=Sharimika, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=2506, name=Sharimika, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=2507, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2508, name=Mamma Bufetta, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=2509, name=Mamma Bufetta, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=2510, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2511, name=Layleen, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=2512, name=Layleen, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=2513, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2514, name=Karaday, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=2515, name=Karaday, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=2516, name=null, level=1, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=2517, name=Safta Doc, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=2518, name=Safta Doc, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=2519, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2520, name=Gabooty, level=0, option=[Talk-to, null, Trade-Co-op, Trade-Drinks, null], anims=[-1, -1]. +NPC id=2521, name=Gabooty, level=0, option=[Talk-to, null, Trade-Co-op, Trade-Drinks, null], anims=[-1, -1]. +NPC id=2522, name=null, level=1, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=2523, name=Fanellaman, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=2524, name=Fanellaman, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=2525, name=null, level=1, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=2526, name=Jagbakoba, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=2527, name=Jagbakoba, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=2528, name=null, level=1, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=2529, name=Murcaily, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=2530, name=Murcaily, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=2531, name=null, level=1, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=2532, name=Rionasta, level=0, option=[Talk-to, null, Send-parcel, null, null], anims=[813, -1]. +NPC id=2533, name=Rionasta, level=0, option=[Talk-to, null, Send-parcel, null, null], anims=[813, -1]. +NPC id=2534, name=Mahogany, level=0, option=[Chop down, null, hidden, null, null], anims=[5750, 5750]. +NPC id=2535, name=Teak, level=0, option=[Chop down, null, hidden, null, null], anims=[5750, 5750]. +NPC id=2536, name=Niles, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2537, name=Miles, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2538, name=Giles, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2539, name=Cap'n Hand, level=0, option=[Talk-to, null, null, null, null], anims=[7199, -1]. +NPC id=2540, name=Dr Jekyll, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2541, name=Mr Hyde, level=14, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=2542, name=Mr Hyde, level=29, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=2543, name=Mr Hyde, level=49, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=2544, name=Mr Hyde, level=79, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=2545, name=Mr Hyde, level=120, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=2546, name=Mr Hyde, level=159, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=2547, name=Chaos druid, level=13, option=[null, Attack, null, null, null], anims=[8528, 8527]. +NPC id=2548, name=Blackjack seller, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=2549, name=Ali the dyer, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2550, name=Dwarven Miner, level=0, option=[null, null, null, null, null], anims=[101, 98]. +NPC id=2551, name=Dwarven Miner, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2552, name=Dwarven Miner, level=0, option=[null, null, null, null, null], anims=[101, 98]. +NPC id=2553, name=Blast Furnace Foreman, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2554, name=Tin ore, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=2555, name=Copper ore, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=2556, name=Iron ore, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=2557, name=Mithril ore, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=2558, name=Adamantite ore, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=2559, name=Runite ore, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=2560, name=Silver ore, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=2561, name=Gold ore, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=2562, name=Coal, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=2563, name=Perfect gold ore, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=2564, name=Ordan, level=0, option=[Talk-to, null, Trade, null, null], anims=[101, 98]. +NPC id=2565, name=Jorzik, level=0, option=[Talk-to, null, Trade, null, null], anims=[101, 98]. +NPC id=2566, name=Wise Old Man, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=2567, name=Wise Old Man, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=2568, name=Banker, level=0, option=[Talk-to, null, Bank, null, null], anims=[808, -1]. +NPC id=2569, name=Banker, level=0, option=[Talk-to, null, Bank, null, null], anims=[808, -1]. +NPC id=2570, name=Banker, level=0, option=[Talk-to, null, Bank, null, null], anims=[808, -1]. +NPC id=2571, name=Market Guard, level=20, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=2572, name=Olivia, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=2573, name=Pillory Guard, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2574, name=Bank guard, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2575, name=Purepker895, level=52, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=2576, name=Qutiedoll, level=16, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=2577, name=1337sp34kr, level=63, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=2578, name=Elfinlocks, level=87, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=2579, name=Cool Mom227, level=27, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=2580, name=Bernald, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2581, name=Ellamaria, level=0, option=[Talk-to, null, null, null, null], anims=[2578, -1]. +NPC id=2582, name=Trolley, level=0, option=[Push, null, Pull, Big-push, Place], anims=[-1, 2571]. +NPC id=2583, name=Trolley, level=0, option=[Push, null, Pull, Big-push, Place], anims=[-1, -1]. +NPC id=2584, name=Trolley, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC (wrapper) id=2585, child npcs=[2584, 2582, 2583, -1]. +NPC id=2586, name=Billy, a guard of Falador, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2587, name=Bob, another guard of Falador, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2588, name=Brother Althric, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2589, name=PKMaster0036, level=87, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2590, name=King Roald, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2591, name=TzHaar-Mej, level=103, option=[null, Attack, null, null, null], anims=[9294, 9295]. +NPC id=2592, name=TzHaar-Mej, level=103, option=[null, Attack, null, null, null], anims=[9294, 9295]. +NPC id=2593, name=TzHaar-Mej, level=103, option=[null, Attack, null, null, null], anims=[9294, 9295]. +NPC id=2594, name=TzHaar-Mej, level=103, option=[null, Attack, null, null, null], anims=[9281, 9280]. +NPC id=2595, name=TzHaar-Mej, level=103, option=[null, Attack, null, null, null], anims=[9294, 9295]. +NPC id=2596, name=TzHaar-Mej, level=103, option=[null, Attack, null, null, null], anims=[9281, 9280]. +NPC id=2597, name=TzHaar-Mej, level=103, option=[null, Attack, null, null, null], anims=[9294, 9295]. +NPC id=2598, name=TzHaar-Hur, level=74, option=[null, Attack, null, null, null], anims=[9281, 9280]. +NPC id=2599, name=TzHaar-Hur, level=74, option=[null, Attack, null, null, null], anims=[9281, 9280]. +NPC id=2600, name=TzHaar-Hur, level=74, option=[null, Attack, null, null, null], anims=[9281, 9280]. +NPC id=2601, name=TzHaar-Hur, level=74, option=[null, Attack, null, null, null], anims=[9281, 9280]. +NPC id=2602, name=TzHaar-Hur, level=74, option=[null, Attack, null, null, null], anims=[9281, 9280]. +NPC id=2603, name=TzHaar-Hur, level=74, option=[null, Attack, null, null, null], anims=[9281, 9280]. +NPC id=2604, name=TzHaar-Xil, level=133, option=[null, Attack, null, null, null], anims=[9281, 9280]. +NPC id=2605, name=TzHaar-Xil, level=133, option=[null, Attack, null, null, null], anims=[9281, 9296]. +NPC id=2606, name=TzHaar-Xil, level=133, option=[null, Attack, null, null, null], anims=[9298, 9297]. +NPC id=2607, name=TzHaar-Xil, level=133, option=[null, Attack, null, null, null], anims=[9281, 9280]. +NPC id=2608, name=TzHaar-Xil, level=133, option=[null, Attack, null, null, null], anims=[9281, 9296]. +NPC id=2609, name=TzHaar-Xil, level=133, option=[null, Attack, null, null, null], anims=[9298, 9297]. +NPC id=2610, name=TzHaar-Ket, level=149, option=[null, Attack, null, null, null], anims=[9281, 9280]. +NPC id=2611, name=TzHaar-Ket, level=149, option=[null, Attack, null, null, null], anims=[9281, 9280]. +NPC id=2612, name=TzHaar-Ket, level=149, option=[null, Attack, null, null, null], anims=[9281, 9296]. +NPC id=2613, name=TzHaar-Ket, level=149, option=[null, Attack, null, null, null], anims=[9281, 9296]. +NPC id=2614, name=TzHaar-Ket, level=149, option=[null, Attack, null, null, null], anims=[9281, 9280]. +NPC id=2615, name=TzHaar-Ket, level=149, option=[null, Attack, null, null, null], anims=[9281, 9280]. +NPC id=2616, name=TzHaar-Ket, level=149, option=[null, Attack, null, null, null], anims=[9281, 9280]. +NPC id=2617, name=TzHaar-Mej-Jal, level=0, option=[Talk-to, null, null, null, null], anims=[9294, 9295]. +NPC id=2618, name=TzHaar-Mej-Kah, level=0, option=[Talk-to, null, null, null, null], anims=[9294, 9295]. +NPC id=2619, name=TzHaar-Ket-Zuh, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[9294, 9295]. +NPC id=2620, name=TzHaar-Hur-Tel, level=0, option=[Talk-to, null, Trade, null, null], anims=[9294, 9295]. +NPC id=2621, name=Olaf Hradson, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2622, name=TzHaar-Hur-Lek, level=0, option=[Talk-to, null, Trade, null, null], anims=[9294, 9295]. +NPC id=2623, name=TzHaar-Mej-Roh, level=0, option=[Talk-to, null, Trade, null, null], anims=[9294, 9295]. +NPC id=2624, name=TzHaar-Ket, level=0, option=[Talk-to, null, null, null, null], anims=[9281, 9296]. +NPC id=2625, name=TzHaar-Ket, level=0, option=[Talk-to, null, null, null, null], anims=[9281, 9296]. +NPC id=2626, name=Rocks, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=2627, name=Tz-Kih, level=22, option=[null, Attack, null, null, null], anims=[9228, 9229]. +NPC id=2628, name=Tz-Kih, level=22, option=[null, Attack, null, null, null], anims=[9228, 9229]. +NPC id=2629, name=Tz-Kek, level=45, option=[null, Attack, null, null, null], anims=[9236, 9237]. +NPC id=2630, name=Tz-Kek, level=45, option=[null, Attack, null, null, null], anims=[9236, 9237]. +NPC id=2631, name=Tok-Xil, level=90, option=[null, Attack, null, null, null], anims=[9241, 9240]. +NPC id=2632, name=Tok-Xil, level=90, option=[null, Attack, null, null, null], anims=[9241, 9240]. +NPC id=2633, name=Wise Old Man, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=2634, name=Miss Schism, level=0, option=[Talk-to, null, null, null, null], anims=[1673, -1]. +NPC id=2635, name=Bob, level=0, option=[Talk-to, null, null, null, null], anims=[9158, 9157]. +NPC id=2636, name=Bob, level=0, option=[Talk-to, null, null, null, null], anims=[9158, 9157]. +NPC id=2637, name=Sphinx, level=0, option=[Talk-to, null, null, null, null], anims=[2028, 2027]. +NPC id=2638, name=Neite, level=0, option=[Talk-to, null, null, null, null], anims=[9158, 9157]. +NPC id=2639, name=Robert the Strong, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2640, name=Odysseus, level=0, option=[Talk-to, null, null, null, null], anims=[2668, 2667]. +NPC id=2641, name=Dragonkin, level=0, option=[null, null, null, null, null], anims=[2688, 2689]. +NPC id=2642, name=King Black Dragon, level=0, option=[null, null, null, null, null], anims=[90, 4635]. +NPC id=2643, name=R4ng3rNo0b889, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2644, name=Love Cats, level=0, option=[null, null, null, null, null], anims=[9196, 9197]. +NPC id=2645, name=Love Cats, level=0, option=[null, null, null, null, null], anims=[9194, -1]. +NPC id=2646, name=Neite, level=0, option=[Talk-to, null, null, null, null], anims=[9165, 9165]. +NPC id=2647, name=Bob, level=0, option=[Talk-to, null, null, null, null], anims=[9165, 9165]. +NPC id=2648, name=Beite, level=0, option=[Talk-to, null, null, null, null], anims=[9158, 9156]. +NPC id=2649, name=Gnome, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=2650, name=Gnome, level=0, option=[Talk-to, null, null, null, null], anims=[2691, 189]. +NPC id=2651, name=Odysseus, level=0, option=[Talk-to, null, null, null, null], anims=[2666, 2666]. +NPC id=2652, name=null, level=1, option=[null, null, null, null, null], anims=[9158, 9157]. +NPC id=2653, name=Neite, level=0, option=[Talk-to, null, null, null, null], anims=[9158, 9157]. +NPC (wrapper) id=2654, child npcs=[2655, 2656, 2657, 2658, 2659, 2658, 2657, 2656, 2655, -1]. +NPC id=2655, name=Unferth, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2656, name=Unferth, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2657, name=Unferth, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2658, name=Unferth, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2659, name=Unferth, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2660, name=Reldo, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2661, name=Reldo, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2662, name=Lazy cat, level=0, option=[Pick-up, null, Talk-to, Interact-with, null], anims=[9158, 9157]. +NPC id=2663, name=Lazy cat, level=0, option=[Pick-up, null, Talk-to, Interact-with, null], anims=[9158, 9157]. +NPC id=2664, name=Lazy cat, level=0, option=[Pick-up, null, Talk-to, Interact-with, null], anims=[9158, 9157]. +NPC id=2665, name=Lazy cat, level=0, option=[Pick-up, null, Talk-to, Interact-with, null], anims=[9158, 9157]. +NPC id=2666, name=Lazy cat, level=0, option=[Pick-up, null, Talk-to, Interact-with, null], anims=[9158, 9157]. +NPC id=2667, name=Lazy cat, level=0, option=[Pick-up, null, Talk-to, Interact-with, null], anims=[9158, 9157]. +NPC id=2668, name=Wily cat, level=0, option=[Pick-up, hidden, Talk-to, Interact-with, null], anims=[9158, 9157]. +NPC id=2669, name=Wily cat, level=0, option=[Pick-up, hidden, Talk-to, Interact-with, null], anims=[9158, 9157]. +NPC id=2670, name=Wily cat, level=0, option=[Pick-up, hidden, Talk-to, Interact-with, null], anims=[9158, 9157]. +NPC id=2671, name=Wily cat, level=0, option=[Pick-up, hidden, Talk-to, Interact-with, null], anims=[9158, 9157]. +NPC id=2672, name=Wily cat, level=0, option=[Pick-up, hidden, Talk-to, Interact-with, null], anims=[9158, 9157]. +NPC id=2673, name=Wily cat, level=0, option=[Pick-up, hidden, Talk-to, Interact-with, null], anims=[9158, 9157]. +NPC id=2674, name=Thief, level=16, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=2675, name=Man, level=2, option=[Talk-to, Attack, Pickpocket, null, null], anims=[813, -1]. +NPC id=2676, name=Make-over Mage, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=2677, name=Highwayman, level=5, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=2678, name=Goblin, level=2, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=2679, name=Goblin, level=2, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=2680, name=Goblin, level=2, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=2681, name=Goblin, level=2, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=2682, name=Rat, level=1, option=[null, Attack, null, null, null], anims=[2704, 2703]. +NPC id=2683, name=Hengel, level=2, option=[Talk-to, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=2684, name=Anja, level=2, option=[Talk-to, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=2685, name=Hobgoblin, level=28, option=[null, Attack, null, null, null], anims=[166, 162]. +NPC id=2686, name=Hobgoblin, level=28, option=[null, Attack, null, null, null], anims=[166, 162]. +NPC id=2687, name=Hobgoblin, level=28, option=[null, Attack, null, null, null], anims=[166, 162]. +NPC id=2688, name=Hobgoblin, level=28, option=[null, Attack, null, null, null], anims=[166, 162]. +NPC id=2689, name=Frog, level=0, option=[null, null, null, null, null], anims=[1796, 1797]. +NPC id=2690, name=Jack Seagull, level=0, option=[Talk-to, null, null, null, null], anims=[1322, -1]. +NPC id=2691, name=Longbow Ben, level=0, option=[Talk-to, null, null, null, null], anims=[1322, -1]. +NPC id=2692, name=Ahab, level=0, option=[Talk-to, null, null, null, null], anims=[1137, -1]. +NPC id=2693, name=Duck, level=1, option=[null, Attack, null, null, null], anims=[6818, 6817]. +NPC id=2694, name=Duckling, level=1, option=[null, Attack, null, null, null], anims=[6818, 6817]. +NPC id=2695, name=Pirate, level=23, option=[null, Attack, null, null, null], anims=[7188, -1]. +NPC id=2696, name=Thief, level=16, option=[null, Attack, null, null, null], anims=[2702, -1]. +NPC id=2697, name=Mugger, level=6, option=[null, Attack, null, null, null], anims=[2701, -1]. +NPC id=2698, name=Black knight, level=33, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=2699, name=Guard, level=21, option=[null, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=2700, name=Guard, level=21, option=[null, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=2701, name=Guard, level=21, option=[null, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=2702, name=Guard, level=21, option=[null, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=2703, name=Guard, level=21, option=[null, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=2704, name=Guard, level=0, option=[Talk-to, null, null, null, null], anims=[2700, -1]. +NPC id=2705, name=Guard, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2706, name=Crab, level=0, option=[null, null, null, null, null], anims=[1310, 1311]. +NPC id=2707, name=Seagull, level=0, option=[null, null, null, null, null], anims=[6771, 6773]. +NPC id=2708, name=Seagull, level=0, option=[null, null, null, null, null], anims=[6771, 6773]. +NPC id=2709, name=Fire wizard, level=13, option=[null, Attack, null, null, null], anims=[813, -1]. +NPC id=2710, name=Water wizard, level=13, option=[null, Attack, null, null, null], anims=[813, -1]. +NPC id=2711, name=Earth wizard, level=13, option=[null, Attack, null, null, null], anims=[813, -1]. +NPC id=2712, name=Air wizard, level=13, option=[null, Attack, null, null, null], anims=[813, -1]. +NPC id=2713, name=Malignius Mortifer, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2714, name=Zombie, level=0, option=[null, null, null, null, null], anims=[5572, 5570]. +NPC id=2715, name=Skeleton, level=0, option=[null, null, null, null, null], anims=[5483, 5479]. +NPC id=2716, name=Ghost, level=0, option=[null, null, null, null, null], anims=[5530, 5531]. +NPC id=2717, name=Skeleton mage, level=0, option=[null, null, null, null, null], anims=[5483, 5479]. +NPC id=2718, name=Betty, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=2719, name=Grum, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=2720, name=Gerrant, level=0, option=[Talk-to, null, Trade, null, null], anims=[813, -1]. +NPC id=2721, name=Wydin, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=2722, name=Fishing spot, level=0, option=[Use-rod, null, null, hidden, null], anims=[447, 448]. +NPC id=2723, name=Fishing spot, level=0, option=[Use-rod, null, null, hidden, null], anims=[456, -1]. +NPC id=2724, name=Fishing spot, level=0, option=[Net, null, Bait, hidden, hidden], anims=[447, 448]. +NPC id=2725, name=Otto Godblessed, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2726, name=Gull, level=0, option=[null, null, null, null, null], anims=[6771, 6773]. +NPC id=2727, name=Gull, level=0, option=[null, null, null, null, null], anims=[6771, 6773]. +NPC id=2728, name=Monk of Entrana, level=0, option=[Talk-to, null, Take-boat, null, null], anims=[808, -1]. +NPC id=2729, name=Monk of Entrana, level=0, option=[Talk-to, null, Take-boat, null, null], anims=[813, -1]. +NPC id=2730, name=Monk of Entrana, level=0, option=[Talk-to, null, Take-boat, null, null], anims=[808, -1]. +NPC id=2731, name=Monk of Entrana, level=0, option=[Talk-to, null, Take-boat, null, null], anims=[813, -1]. +NPC id=2732, name=Master Crafter, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2733, name=Master Crafter, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2734, name=Tz-Kih, level=22, option=[null, Attack, null, null, null], anims=[9228, 9229]. +NPC id=2735, name=Tz-Kih, level=22, option=[null, Attack, null, null, null], anims=[9228, 9229]. +NPC id=2736, name=Tz-Kek, level=45, option=[null, Attack, null, null, null], anims=[9236, 9237]. +NPC id=2737, name=Tz-Kek, level=45, option=[null, Attack, null, null, null], anims=[9236, 9237]. +NPC id=2738, name=Tz-Kek, level=22, option=[null, Attack, null, null, null], anims=[9236, 9238]. +NPC id=2739, name=Tok-Xil, level=90, option=[null, Attack, null, null, null], anims=[9241, 9240]. +NPC id=2740, name=Tok-Xil, level=90, option=[null, Attack, null, null, null], anims=[9241, 9240]. +NPC id=2741, name=Yt-MejKot, level=180, option=[null, Attack, null, null, null], anims=[9250, 9251]. +NPC id=2742, name=Yt-MejKot, level=180, option=[null, Attack, null, null, null], anims=[9250, 9251]. +NPC id=2743, name=Ket-Zek, level=360, option=[null, Attack, null, null, null], anims=[9267, 9264]. +NPC id=2744, name=Ket-Zek, level=360, option=[null, Attack, null, null, null], anims=[9267, 9264]. +NPC id=2745, name=TzTok-Jad, level=702, option=[null, Attack, null, null, null], anims=[9274, 9273]. +NPC id=2746, name=Yt-HurKot, level=108, option=[null, Attack, null, null, null], anims=[9255, 9256]. +NPC id=2747, name=Solus Dellagar, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=2748, name=Savant, level=0, option=[Talk-to, null, null, null, null], anims=[2256, -1]. +NPC id=2749, name=Lord Daquarius, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2750, name=Solus Dellagar, level=0, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=2751, name=Black Knight, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2752, name=Lord Daquarius, level=0, option=[null, null, null, null, null], anims=[2724, -1]. +NPC id=2753, name=Mage of Zamorak, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2754, name=Mage of Zamorak, level=0, option=[null, null, null, null, null], anims=[2726, -1]. +NPC id=2755, name=Mage of Zamorak, level=0, option=[null, null, null, null, null], anims=[2727, -1]. +NPC id=2756, name=null, level=1, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=2757, name=null, level=1, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=2758, name=null, level=1, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=2759, name=null, level=1, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=2760, name=null, level=1, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=2761, name=null, level=1, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=2762, name=null, level=1, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=2763, name=null, level=1, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=2764, name=null, level=1, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=2765, name=null, level=1, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=2766, name=null, level=1, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=2767, name=null, level=1, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=2768, name=null, level=1, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=2769, name=null, level=1, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=2770, name=null, level=1, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=2771, name=null, level=1, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=2772, name=null, level=1, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=2773, name=null, level=1, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=2774, name=null, level=1, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=2775, name=null, level=1, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=2776, name=Woman, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2777, name=Black Knight, level=32, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=2778, name=Black Knight, level=32, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2779, name=Ranger, level=0, option=[null, Attack, null, null, null], anims=[2728, -1]. +NPC id=2780, name=Solus Dellagar, level=0, option=[null, Attack, null, null, null], anims=[813, -1]. +NPC id=2781, name=Gnome guard, level=0, option=[null, null, null, null, null], anims=[195, 189]. +NPC id=2782, name=Shadow, level=73, option=[null, Attack, null, null, null], anims=[2740, 2737]. +NPC id=2783, name=Dark beast, level=182, option=[null, Attack, null, null, null], anims=[2730, 2729]. +NPC id=2784, name=Mourner, level=0, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=2785, name=Slave, level=0, option=[null, null, null, null, null], anims=[1728, -1]. +NPC id=2786, name=Slave, level=0, option=[null, null, null, null, null], anims=[830, -1]. +NPC id=2787, name=Slave, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2788, name=null, level=1, option=[null, null, null, null, null], anims=[101, 98]. +NPC id=2789, name=Thorgel, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2790, name=Sergeant Damien, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2791, name=Pillory Guard, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2792, name=Tramp, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2793, name=Tramp, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2794, name=Tramp, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC (wrapper) id=2795, child npcs=[2796, 2797, 2798, 2799, -1]. +NPC id=2796, name=Skippy, level=0, option=[Talk-To, null, Sober-Up, null, null], anims=[-1, -1]. +NPC id=2797, name=Skippy, level=0, option=[Talk-To, null, Sober-Up, null, null], anims=[-1, -1]. +NPC id=2798, name=Skippy, level=0, option=[Talk-To, null, Sober-Up, null, null], anims=[-1, -1]. +NPC id=2799, name=Skippy, level=0, option=[Talk-To, null, Sober-Up, null, null], anims=[-1, -1]. +NPC id=2800, name=A pile of broken glass, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=2801, name=Mogre, level=60, option=[null, Attack, null, null, null], anims=[357, 358]. +NPC id=2802, name=Gnome Coach, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=2803, name=Lizard, level=42, option=[null, Attack, null, null, null], anims=[2774, 2775]. +NPC id=2804, name=Desert Lizard, level=24, option=[null, Attack, null, null, null], anims=[2774, 2775]. +NPC id=2805, name=Desert Lizard, level=24, option=[null, Attack, null, null, null], anims=[2774, 2775]. +NPC id=2806, name=Desert Lizard, level=24, option=[null, Attack, null, null, null], anims=[2774, 2775]. +NPC id=2807, name=Small Lizard, level=12, option=[null, Attack, null, null, null], anims=[2774, 2775]. +NPC id=2808, name=Small Lizard, level=12, option=[null, Attack, null, null, null], anims=[2774, 2775]. +NPC id=2809, name=Al the Camel, level=0, option=[Talk-to, null, null, null, null], anims=[51, 45]. +NPC id=2810, name=Elly the Camel, level=0, option=[Talk-to, null, null, null, null], anims=[51, 45]. +NPC id=2811, name=Ollie the Camel, level=0, option=[Talk-to, null, null, null, null], anims=[51, 45]. +NPC id=2812, name=Cam the Camel, level=0, option=[Talk-to, null, null, null, null], anims=[51, 45]. +NPC (wrapper) id=2813, child npcs=[80, 2814, -1]. +NPC id=2814, name=Alice the Camel, level=0, option=[Talk-to, null, null, null, null], anims=[51, 45]. +NPC id=2815, name=Neferti the Camel, level=0, option=[Talk-to, null, null, null, null], anims=[51, 45]. +NPC id=2816, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2817, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2818, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2819, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2820, name=Ali the Smith, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2821, name=Ali the Farmer, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2822, name=Ali the Tailor, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2823, name=Ali the Guard, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2824, name=Ellis, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=2825, name=Pirate Pete, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=2826, name=Pirate Pete, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=2827, name=Captain Braindeath, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=2828, name=50% Luke, level=0, option=[Talk-to, null, null, null, null], anims=[5586, 5585]. +NPC id=2829, name=Davey, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=2830, name=Captain Donnie, level=0, option=[Talk-to, null, null, null, null], anims=[5656, 5655]. +NPC id=2831, name=Zombie protester, level=0, option=[Talk-to, null, null, null, null], anims=[5584, 5583]. +NPC id=2832, name=Zombie protester, level=0, option=[Talk-to, null, null, null, null], anims=[5584, 5583]. +NPC id=2833, name=Zombie protester, level=0, option=[Talk-to, null, null, null, null], anims=[5584, 5583]. +NPC id=2834, name=Zombie protester, level=0, option=[Talk-to, null, null, null, null], anims=[5584, 5583]. +NPC id=2835, name=Zombie protester, level=0, option=[Talk-to, null, null, null, null], anims=[5584, 5583]. +NPC id=2836, name=Zombie protester, level=0, option=[Talk-to, null, null, null, null], anims=[5584, 5583]. +NPC id=2837, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5646, 5645]. +NPC id=2838, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5650, 5652]. +NPC id=2839, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5650, 5652]. +NPC id=2840, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5650, 5652]. +NPC id=2841, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5646, 5645]. +NPC id=2842, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5646, 5645]. +NPC id=2843, name=Zombie swab, level=55, option=[Talk-to, Attack, Intimidate, null, null], anims=[5646, 5645]. +NPC id=2844, name=Zombie swab, level=55, option=[Talk-to, Attack, Intimidate, null, null], anims=[5646, 5645]. +NPC id=2845, name=Zombie swab, level=55, option=[Talk-to, Attack, Intimidate, null, null], anims=[5650, 5652]. +NPC id=2846, name=Zombie swab, level=55, option=[Talk-to, Attack, Intimidate, null, null], anims=[5650, 5652]. +NPC id=2847, name=Zombie swab, level=55, option=[Talk-to, Attack, Intimidate, null, null], anims=[5646, 5645]. +NPC id=2848, name=Zombie swab, level=55, option=[Talk-to, Attack, Intimidate, null, null], anims=[5646, 5645]. +NPC id=2849, name=Evil spirit, level=150, option=[null, Attack, null, null, null], anims=[2803, 2802]. +NPC id=2850, name=Fever spider, level=49, option=[null, Attack, null, null, null], anims=[5318, 5317]. +NPC id=2851, name=Brewer, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2852, name=Brewer, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2853, name=Brewer, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2854, name=Brewer, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2855, name=Brewer, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2856, name=Brewer, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2857, name=Brewer, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2858, name=Brewer, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2859, name=Fishing spot, level=0, option=[Fish, null, null, hidden, hidden], anims=[447, 448]. +NPC id=2860, name=Amaethwr, level=0, option=[Talk-to, null, Pay, null, null], anims=[808, -1]. +NPC id=2861, name=Teclyn, level=0, option=[Talk-to, null, Exchange, Teleport, null], anims=[808, -1]. +NPC id=2862, name=Death, level=0, option=[null, null, null, null, null], anims=[847, -1]. +NPC id=2863, name=Zombie, level=0, option=[Talk-To, null, Call-Over, null, null], anims=[808, -1]. +NPC id=2864, name=Most of a Zombie, level=0, option=[Talk-To, null, null, null, null], anims=[808, -1]. +NPC id=2865, name=Most of a Zombie, level=0, option=[Talk-To, null, null, null, null], anims=[2816, 2815]. +NPC id=2866, name=Zombie, level=0, option=[Talk-To, null, Insult, null, null], anims=[808, -1]. +NPC id=2867, name=Most of a Zombie, level=0, option=[Talk-To, null, null, null, null], anims=[808, -1]. +NPC id=2868, name=Zombie Head, level=0, option=[Catch, Talk-To, null, null, null], anims=[2818, 2818]. +NPC id=2869, name=Zombie, level=0, option=[Talk-To, null, Scare, null, null], anims=[808, -1]. +NPC id=2870, name=Half-Zombie, level=0, option=[Talk-To, null, null, null, null], anims=[2825, 2823]. +NPC id=2871, name=Other Half-Zombie, level=0, option=[Talk-To, null, null, null, null], anims=[2826, 2824]. +NPC id=2872, name=Child, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=2873, name=Child, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=2874, name=Child, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=2875, name=Child, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=2876, name=Child, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=2877, name=Child, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=2878, name=Zombie, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=2879, name=Bardur, level=94, option=[Talk-to, Attack, null, null, null], anims=[813, -1]. +NPC id=2880, name=Dagannoth fledgeling, level=70, option=[null, Attack, null, null, null], anims=[2774, 2775]. +NPC id=2881, name=Dagannoth Supreme, level=303, option=[null, Attack, null, null, null], anims=[2850, 2849]. +NPC id=2882, name=Dagannoth Prime, level=303, option=[null, Attack, null, null, null], anims=[2850, 2849]. +NPC id=2883, name=Dagannoth Rex, level=303, option=[null, Attack, null, null, null], anims=[2850, 2849]. +NPC id=2884, name=Wallasalki, level=98, option=[null, Attack, null, null, null], anims=[2364, 2363]. +NPC id=2885, name=Giant Rock Crab, level=137, option=[null, Attack, null, null, null], anims=[1310, 1311]. +NPC id=2886, name=Boulder, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=2887, name=Dagannoth, level=88, option=[null, Attack, null, null, null], anims=[1338, 1339]. +NPC id=2888, name=Dagannoth, level=90, option=[null, Attack, null, null, null], anims=[1338, 1339]. +NPC id=2889, name=Rock lobster, level=127, option=[null, Attack, null, null, null], anims=[2858, 2857]. +NPC id=2890, name=Rock, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=2891, name=Suspicious water, level=34, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=2892, name=Spinolyp, level=76, option=[null, Attack, null, null, null], anims=[2867, 2863]. +NPC id=2893, name=Suspicious water, level=34, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=2894, name=Spinolyp, level=76, option=[null, Attack, null, null, null], anims=[2867, 2863]. +NPC id=2895, name=Suspicious water, level=34, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=2896, name=Spinolyp, level=76, option=[null, Attack, null, null, null], anims=[2867, 2863]. +NPC (wrapper) id=2897, child npcs=[2899, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2899, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2899, -1]. +NPC id=2898, name=null, level=1, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=2899, name=Father Reen, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=2900, name=Father Reen, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2901, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2902, name=Father Badden, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2903, name=Father Badden, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2904, name=Denath, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2905, name=Denath, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2906, name=Eric, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2907, name=Eric, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2908, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2909, name=Evil Dave, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2910, name=Evil Dave, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2911, name=Matthew, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2912, name=Matthew, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2913, name=Jennifer, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2914, name=Jennifer, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2915, name=Tanya, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2916, name=Tanya, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2917, name=Patrick, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2918, name=Patrick, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2919, name=Agrith Naar, level=100, option=[null, Attack, null, null, null], anims=[4675, 4674]. +NPC id=2920, name=null, level=1, option=[null, null, null, null, null], anims=[2882, 2882]. +NPC id=2921, name=Sand storm, level=0, option=[null, null, null, null, null], anims=[2882, 2882]. +NPC id=2922, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2923, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2924, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2925, name=null, level=1, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=2926, name=null, level=1, option=[null, null, null, null, null], anims=[1913, 1912]. +NPC id=2927, name=Clay golem, level=0, option=[Talk-to, null, null, null, null], anims=[1913, 1912]. +NPC id=2928, name=Clay golem, level=0, option=[Talk-to, null, null, null, null], anims=[1913, 1912]. +NPC id=2929, name=null, level=2, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=2930, name=null, level=0, option=[null, null, null, null, null], anims=[-1, 5531]. +NPC id=2931, name=Ghost, level=0, option=[null, null, null, null, null], anims=[5530, 5531]. +NPC id=2932, name=Jorral, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC (wrapper) id=2933, child npcs=[2935, -1]. +NPC id=2934, name=Melina, level=0, option=[null, null, null, null, null], anims=[2893, -1]. +NPC id=2935, name=Melina, level=0, option=[Talk-To, null, null, null, null], anims=[808, -1]. +NPC (wrapper) id=2936, child npcs=[2938, -1]. +NPC id=2937, name=Droalak, level=0, option=[null, null, null, null, null], anims=[2893, -1]. +NPC id=2938, name=Droalak, level=0, option=[Talk-To, null, null, null, null], anims=[808, -1]. +NPC id=2939, name=Dron, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2940, name=Blanin, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2941, name=The Beast, level=0, option=[Talk-to, null, null, null, null], anims=[9158, 9157]. +NPC id=2942, name=Bellemorde, level=0, option=[Talk-to, null, null, null, null], anims=[9158, 9157]. +NPC id=2943, name=Pox, level=0, option=[Talk-to, null, null, null, null], anims=[9158, 9157]. +NPC id=2944, name=Pox, level=0, option=[null, hidden, null, null, null], anims=[9158, 9157]. +NPC id=2945, name=Bones, level=0, option=[Talk-to, null, null, null, null], anims=[9158, 9156]. +NPC id=2946, name=Grimesquit, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2947, name=Phingspet, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2948, name=Hooknosed Jack, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2949, name=Jimmy Dazzler, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=2950, name=The Face, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=2951, name=Felkrash, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=2952, name=Smokin' Joe, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2953, name=Ceril Carnillean, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2954, name=Councillor Halgrive, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2955, name=Spice seller, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2956, name=Fur trader, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2957, name=Gem merchant, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2958, name=Silver merchant, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2959, name=Silk merchant, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2960, name=Zenesha, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2961, name=Ali Morrisane, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2962, name=Guard, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2963, name=Guard, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2964, name=Guard, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2965, name=Guard, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2966, name=Guard, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2967, name=Guard, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2968, name=Guard, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2969, name=Guard, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2970, name=Guard, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2971, name=Guard, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2972, name=Guard, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=2973, name=Guard, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC (wrapper) id=2974, child npcs=[2980, -1]. +NPC (wrapper) id=2975, child npcs=[2980, -1]. +NPC (wrapper) id=2976, child npcs=[2980, -1]. +NPC (wrapper) id=2977, child npcs=[2980, -1]. +NPC (wrapper) id=2978, child npcs=[2980, -1]. +NPC (wrapper) id=2979, child npcs=[2980, -1]. +NPC id=2980, name=Rat, level=0, option=[null, Hidden, null, null, null], anims=[-1, -1]. +NPC id=2981, name=Rat, level=0, option=[null, Attack, null, null, null], anims=[2704, 2703]. +NPC id=2982, name=King rat, level=0, option=[null, Hidden, null, null, null], anims=[2704, 2703]. +NPC id=2983, name=Turbogroomer, level=0, option=[null, hidden, null, null, null], anims=[9158, 9157]. +NPC id=2984, name=Pusskins, level=0, option=[null, hidden, null, null, null], anims=[9158, 9157]. +NPC id=2985, name=Loki, level=0, option=[null, Hidden, null, null, null], anims=[9158, 9157]. +NPC id=2986, name=Captain Tom, level=0, option=[null, hidden, null, null, null], anims=[9158, 9157]. +NPC id=2987, name=Treacle, level=0, option=[null, null, null, null, null], anims=[9158, 9157]. +NPC id=2988, name=Mittens, level=0, option=[null, Hidden, null, null, null], anims=[9158, 9157]. +NPC id=2989, name=Claude, level=0, option=[null, Hidden, null, null, null], anims=[9158, 9156]. +NPC id=2990, name=Topsy, level=0, option=[null, Hidden, null, null, null], anims=[9158, 9156]. +NPC id=2991, name=Rauborn, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2992, name=Vaeringk, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2993, name=Oxi, level=0, option=[Talk-to, null, null, null, null], anims=[2155, 2154]. +NPC id=2994, name=Fior, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2995, name=Sagira, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2996, name=Anleif, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=2997, name=Gertrude's cat, level=0, option=[Talk-to, null, null, null, null], anims=[9158, 9157]. +NPC id=2998, name=Gambler, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=2999, name=Gambler, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=3000, name=Barman, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3001, name=Gambler, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3002, name=Gambler, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3003, name=Gambler, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3004, name=Gambler, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3005, name=Gambler, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3006, name=Gambler, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3007, name=Rat, level=0, option=[null, Hidden, null, null, null], anims=[2704, 2703]. +NPC id=3008, name=Rat, level=0, option=[null, Hidden, null, null, null], anims=[2704, 2703]. +NPC id=3009, name=Rat, level=0, option=[null, Hidden, null, null, null], anims=[2704, 2703]. +NPC id=3010, name=Rat, level=0, option=[null, Hidden, null, null, null], anims=[2704, 2703]. +NPC id=3011, name=Rat, level=0, option=[null, Hidden, null, null, null], anims=[2704, 2703]. +NPC id=3012, name=Rat, level=0, option=[null, Hidden, null, null, null], anims=[2704, 2703]. +NPC id=3013, name=Rat, level=0, option=[null, Hidden, null, null, null], anims=[2704, 2703]. +NPC id=3014, name=Rat, level=0, option=[null, Hidden, null, null, null], anims=[2704, 2703]. +NPC id=3015, name=Rat, level=0, option=[null, Hidden, null, null, null], anims=[2704, 2703]. +NPC id=3016, name=Rat, level=0, option=[null, Hidden, null, null, null], anims=[2704, 2703]. +NPC id=3017, name=Rat, level=0, option=[null, Hidden, null, null, null], anims=[2704, 2703]. +NPC id=3018, name=Rat, level=0, option=[null, Hidden, null, null, null], anims=[2704, 2703]. +NPC id=3019, name=Fishing spot, level=0, option=[Lure, null, Bait, hidden, hidden], anims=[447, 448]. +NPC id=3020, name=Rug Merchant, level=0, option=[Talk-to, null, Travel, null, null], anims=[808, -1]. +NPC id=3021, name=Tool leprechaun, level=0, option=[Talk-to, null, Exchange, Teleport, null], anims=[2904, 189]. +NPC id=3022, name=Genie, level=0, option=[Talk-to, null, null, null, null], anims=[792, -1]. +NPC id=3023, name=Nirrie, level=0, option=[Talk-to, null, null, null, null], anims=[2906, 2907]. +NPC id=3024, name=Tirrie, level=0, option=[Talk-to, null, null, null, null], anims=[2908, 2907]. +NPC id=3025, name=Hallak, level=0, option=[Talk-to, null, null, null, null], anims=[2906, 2907]. +NPC id=3026, name=Black golem, level=75, option=[null, Attack, null, null, null], anims=[1913, 1912]. +NPC id=3027, name=White golem, level=75, option=[null, Attack, null, null, null], anims=[1913, 1912]. +NPC id=3028, name=Grey golem, level=75, option=[null, Attack, null, null, null], anims=[1913, 1912]. +NPC id=3029, name=Ghaslor the Elder, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3030, name=Ali the Carter, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3031, name=Usi, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3032, name=Nkuku, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3033, name=Garai, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3034, name=Habibah, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3035, name=Meskhenet, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3036, name=Zahra, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3037, name=Zahur, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3038, name=Seddu, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=3039, name=Kazemde, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=3040, name=Awusah the Mayor, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=3041, name=Tarik, level=21, option=[null, Attack, null, null, null], anims=[813, -1]. +NPC id=3042, name=Poltenip, level=21, option=[null, Attack, null, null, null], anims=[813, -1]. +NPC id=3043, name=Radat, level=21, option=[null, Attack, null, null, null], anims=[813, -1]. +NPC id=3044, name=Shiratti the Custodian, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=3045, name=Rokuh, level=0, option=[Talk-to, null, Trade, null, null], anims=[2911, 2912]. +NPC id=3046, name=Nardah Banker, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[808, 808]. +NPC id=3047, name=Target, level=0, option=[null, Shoot, null, null, null], anims=[-1, -1]. +NPC id=3048, name=Target, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC (wrapper) id=3049, child npcs=[3047, 3048, -1]. +NPC id=3050, name=Larxus, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3051, name=Mystery figure, level=0, option=[null, null, null, null, null], anims=[2939, -1]. +NPC id=3052, name=Mystery figure, level=0, option=[null, null, null, null, null], anims=[2942, -1]. +NPC id=3053, name=Mystery figure, level=0, option=[null, null, null, null, null], anims=[2943, 189]. +NPC id=3054, name=Mystery figure, level=0, option=[null, null, null, null, null], anims=[9299, 9299]. +NPC id=3055, name=Mystery figure, level=0, option=[null, null, null, null, null], anims=[6542, -1]. +NPC id=3056, name=Mystery figure, level=0, option=[null, null, null, null, null], anims=[2940, -1]. +NPC id=3057, name=Earth Warrior Champion, level=102, option=[null, Attack, null, null, null], anims=[2945, -1]. +NPC id=3058, name=Giant Champion, level=56, option=[null, Attack, null, null, null], anims=[6371, 6372]. +NPC id=3059, name=Ghoul Champion, level=85, option=[null, Attack, null, null, null], anims=[1275, -1]. +NPC id=3060, name=Goblin Champion, level=24, option=[null, Attack, null, null, null], anims=[6139, 6138]. +NPC id=3061, name=Hobgoblin Champion, level=56, option=[null, Attack, null, null, null], anims=[2958, 162]. +NPC id=3062, name=Imp Champion, level=14, option=[null, Attack, null, null, null], anims=[171, 168]. +NPC id=3063, name=Jogre Champion, level=107, option=[null, Attack, null, null, null], anims=[2931, 2932]. +NPC id=3064, name=Lesser Demon Champion, level=162, option=[null, Attack, null, null, null], anims=[4675, 4674]. +NPC id=3065, name=Skeleton Champion, level=40, option=[null, Attack, null, null, null], anims=[5510, 5511]. +NPC id=3066, name=Zombies Champion, level=51, option=[null, Attack, null, null, null], anims=[5573, 5582]. +NPC id=3067, name=Leon d'Cour, level=141, option=[null, Attack, null, null, null], anims=[2561, -1]. +NPC id=3068, name=Skeletal Wyvern, level=140, option=[null, Attack, null, null, null], anims=[2984, 2982]. +NPC id=3069, name=Skeletal Wyvern, level=140, option=[null, Attack, null, null, null], anims=[2984, 2982]. +NPC id=3070, name=Skeletal Wyvern, level=140, option=[null, Attack, null, null, null], anims=[2984, 2982]. +NPC id=3071, name=Skeletal Wyvern, level=140, option=[null, Attack, null, null, null], anims=[2984, 2982]. +NPC id=3072, name=Ice giant, level=53, option=[null, Attack, null, null, null], anims=[4670, 4669]. +NPC id=3073, name=Ice warrior, level=57, option=[null, Attack, null, null, null], anims=[842, 841]. +NPC (wrapper) id=3074, child npcs=[3075, -1]. +NPC id=3075, name=Monk, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=3076, name=null, level=1, option=[null, null, null, null, null], anims=[2995, -1]. +NPC id=3077, name=Dead Monk, level=0, option=[Search, null, null, null, null], anims=[-1, -1]. +NPC id=3078, name=High Priest, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=3079, name=Monk, level=0, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=3080, name=Monk, level=0, option=[null, null, null, null, null], anims=[2993, 2994]. +NPC id=3081, name=Assassin, level=0, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=3082, name=Rosie, level=0, option=[Talk-to, null, null, null, null], anims=[3008, 3012]. +NPC id=3083, name=Sorcha, level=0, option=[Talk-to, null, null, null, null], anims=[3008, 3012]. +NPC id=3084, name=Cait, level=0, option=[Talk-to, null, null, null, null], anims=[3008, 3012]. +NPC id=3085, name=Cormac, level=0, option=[Talk-to, null, null, null, null], anims=[3008, 3012]. +NPC id=3086, name=Fionn, level=0, option=[Talk-to, null, null, null, null], anims=[3008, 3012]. +NPC id=3087, name=Donnacha, level=0, option=[Talk-to, null, null, null, null], anims=[3008, 3012]. +NPC id=3088, name=Ronan, level=0, option=[Talk-to, null, null, null, null], anims=[3008, 3012]. +NPC id=3089, name=, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=3090, name=, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=3091, name=, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=3092, name=Hooded Stranger, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3093, name=null, level=0, option=[null, null, null, null, null], anims=[663, 663]. +NPC id=3094, name=Flying Book, level=0, option=[null, null, null, null, null], anims=[3023, 3023]. +NPC id=3095, name=Flying Book, level=0, option=[null, null, null, null, null], anims=[3023, 3023]. +NPC id=3096, name=Pizzaz Hat, level=1, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=3097, name=Entrance Guardian, level=0, option=[Talk-to, null, null, null, null], anims=[3033, 3034]. +NPC id=3098, name=Telekinetic Guardian, level=0, option=[Talk-to, null, null, null, null], anims=[3033, 3034]. +NPC id=3099, name=Alchemy Guardian, level=0, option=[Talk-to, null, null, null, null], anims=[3033, 3035]. +NPC id=3100, name=Enchantment Guardian, level=0, option=[Talk-to, null, null, null, null], anims=[3033, 3034]. +NPC id=3101, name=Graveyard Guardian, level=0, option=[Talk-to, null, null, null, null], anims=[3033, 3035]. +NPC id=3102, name=Maze Guardian, level=0, option=[Talk-to, null, null, null, null], anims=[3033, 3034]. +NPC id=3103, name=Rewards Guardian, level=0, option=[Talk-to, null, null, Trade-with, null], anims=[3033, 3035]. +NPC id=3104, name=Charmed Warrior, level=0, option=[Talk-to, null, null, null, null], anims=[3026, 3027]. +NPC id=3105, name=Charmed Warrior, level=0, option=[Talk-to, null, null, null, null], anims=[3026, 3027]. +NPC id=3106, name=Charmed Warrior, level=0, option=[Talk-to, null, null, null, null], anims=[3026, 3027]. +NPC id=3107, name=Charmed Warrior, level=0, option=[Talk-to, null, null, null, null], anims=[3026, 3027]. +NPC id=3108, name=Bert, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3109, name=Guard Captain, level=0, option=[Talk-to, null, null, null, null], anims=[3040, -1]. +NPC (wrapper) id=3110, child npcs=[3112, -1]. +NPC id=3111, name=null, level=1, option=[null, null, null, null, null], anims=[3036, -1]. +NPC id=3112, name=Sandy, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[808, -1]. +NPC id=3113, name=Sandy, level=0, option=[null, null, null, null, null], anims=[3036, -1]. +NPC id=3114, name=Mazion, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3115, name=Blaec, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3116, name=Reeso, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3117, name=Sandwich lady, level=0, option=[Talk-to, null, null, null, null], anims=[3043, 3042]. +NPC id=3118, name=Prison Pete, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3119, name=Balloon Animal, level=0, option=[Pop, null, null, null, null], anims=[3049, 3048]. +NPC id=3120, name=Balloon Animal, level=0, option=[Pop, null, null, null, null], anims=[3049, 3050]. +NPC id=3121, name=Balloon Animal, level=0, option=[Pop, null, null, null, null], anims=[3049, 3048]. +NPC id=3122, name=Balloon Animal, level=0, option=[Pop, null, null, null, null], anims=[3049, 3048]. +NPC id=3123, name=Simon Templeton, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3124, name=Pyramid block, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=3125, name=Pyramid block, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=3126, name=Pentyn, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3127, name=Aristarchus, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC (wrapper) id=3128, child npcs=[3129, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3129, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3129, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3129, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3129, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3130, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3130, -1, -1, -1, -1, 3130, -1, -1, -1, -1, 3130, -1]. +NPC id=3129, name=Boneguard, level=0, option=[null, Talk-to, null, null, null], anims=[3073, 3078]. +NPC id=3130, name=Pile of bones, level=0, option=[Climb-over, null, null, null, null], anims=[-1, -1]. +NPC id=3131, name=Desert Spirit, level=0, option=[Talk-to, null, null, null, null], anims=[2334, 2333]. +NPC (wrapper) id=3132, child npcs=[3133, -1]. +NPC id=3133, name=Crust of ice, level=0, option=[null, Melt, null, null, null], anims=[-1, -1]. +NPC (wrapper) id=3134, child npcs=[3135, -1]. +NPC id=3135, name=Furnace grate, level=0, option=[null, Clear, null, null, null], anims=[-1, -1]. +NPC (wrapper) id=3136, child npcs=[3137, 3138, -1]. +NPC id=3137, name=Enakhra, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3138, name=Enakhra, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC (wrapper) id=3139, child npcs=[3140, 3141, 3142, -1]. +NPC id=3140, name=Boneguard, level=0, option=[Talk-to, null, null, null, null], anims=[3073, 3078]. +NPC id=3141, name=Akthanakos, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3142, name=Akthanakos, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC (wrapper) id=3143, child npcs=[3147, -1]. +NPC id=3144, name=null, level=1, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=3145, name=null, level=1, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=3146, name=null, level=1, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=3147, name=Lazim, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=3148, name=Enakhra, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=3149, name=Akthanakos, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=3150, name=Knight, level=0, option=[null, null, null, null, null], anims=[2561, -1]. +NPC id=3151, name=Skeleton, level=1, option=[null, null, null, null, null], anims=[5483, 5479]. +NPC (wrapper) id=3152, child npcs=[3140, 3141, 3142, -1]. +NPC id=3153, name=Harpie Bug Swarm, level=46, option=[null, Attack, null, null, null], anims=[3108, 3108]. +NPC id=3154, name=Count Draynor, level=34, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=3155, name=Bill Teach, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=3156, name=Bill Teach, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=3157, name=Bill Teach, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=3158, name=Bill Teach, level=0, option=[Talk-to, null, Return-Home, null, null], anims=[7188, -1]. +NPC id=3159, name=Bill Teach, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=3160, name=Bill Teach, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=3161, name=Charley, level=0, option=[Talk-to, null, Trade, null, null], anims=[7188, -1]. +NPC id=3162, name=Smith, level=0, option=[Talk-to, null, Trade, null, null], anims=[7188, -1]. +NPC id=3163, name=Joe, level=0, option=[Talk-to, null, Trade, null, null], anims=[7188, -1]. +NPC id=3164, name=Mama, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=3165, name=Mama, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=3166, name=Mike, level=0, option=[Talk-to, null, Trade, null, null], anims=[7188, -1]. +NPC id=3167, name=Pirate, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=3168, name=Pirate, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=3169, name=Pirate, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=3170, name=Pirate, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=3171, name=Pirate, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=3172, name=Pirate, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=3173, name=Pirate, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=3174, name=Pirate, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=3175, name=Pirate, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=3176, name=Pirate, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=3177, name=Pirate, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=3178, name=Pirate, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=3179, name=Pirate, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=3180, name=Pirate, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=3181, name=Pirate, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=3182, name=Pirate, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=3183, name=Pirate, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=3184, name=Pirate, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=3185, name=Pirate, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=3186, name=Pirate, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=3187, name=Pirate, level=57, option=[Talk-To, Attack, null, null, null], anims=[7188, -1]. +NPC id=3188, name=Pirate, level=57, option=[Talk-To, Attack, null, null, null], anims=[7188, -1]. +NPC id=3189, name=Pirate, level=57, option=[Talk-To, Attack, null, null, null], anims=[7188, -1]. +NPC id=3190, name=Pirate, level=57, option=[Talk-To, Attack, null, null, null], anims=[7188, -1]. +NPC id=3191, name=Pirate, level=57, option=[Talk-To, Attack, null, null, null], anims=[7188, -1]. +NPC id=3192, name=Pirate, level=57, option=[Talk-To, Attack, null, null, null], anims=[7188, -1]. +NPC id=3193, name=Pirate, level=57, option=[Talk-To, Attack, null, null, null], anims=[7188, -1]. +NPC id=3194, name=Pirate, level=57, option=[Talk-To, Attack, null, null, null], anims=[7188, -1]. +NPC id=3195, name=Pirate, level=57, option=[Talk-To, Attack, null, null, null], anims=[7188, -1]. +NPC id=3196, name=Pirate, level=57, option=[Talk-To, Attack, null, null, null], anims=[7188, -1]. +NPC id=3197, name=Gull, level=0, option=[null, null, null, null, null], anims=[6771, 6773]. +NPC id=3198, name=Banker, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[808, 808]. +NPC id=3199, name=Banker, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[808, 808]. +NPC id=3200, name=Chaos Elemental, level=305, option=[null, Attack, null, null, null], anims=[3144, 3145]. +NPC id=3201, name=Killerwatt, level=55, option=[null, Attack, null, null, null], anims=[3160, 3161]. +NPC id=3202, name=Killerwatt, level=55, option=[null, Attack, null, null, null], anims=[3159, 3159]. +NPC id=3203, name=Storm Cloud, level=0, option=[null, null, null, null, null], anims=[3169, 3169]. +NPC id=3204, name=Storm Cloud, level=0, option=[null, null, null, null, null], anims=[3168, 3167]. +NPC id=3205, name=Romily Weaklax, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=3206, name=Priest, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3207, name=Pious Pete, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3208, name=Taper, level=0, option=[null, null, null, null, null], anims=[3183, 3183]. +NPC id=3209, name=Elena, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3210, name=Alrena, level=0, option=[Talk-to, null, null, null, null], anims=[3185, -1]. +NPC id=3211, name=Alrena, level=0, option=[Talk-to, null, null, null, null], anims=[364, -1]. +NPC id=3212, name=Bravek, level=0, option=[Talk-to, null, null, null, null], anims=[3186, -1]. +NPC (wrapper) id=3213, child npcs=[714, -1]. +NPC id=3214, name=null, level=0, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=3215, name=Elena, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3216, name=Mourner, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3217, name=Kaylee, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3218, name=Tina, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3219, name=Dwarf, level=11, option=[null, Attack, null, null, null], anims=[101, 98]. +NPC id=3220, name=Dwarf, level=11, option=[null, Attack, null, null, null], anims=[101, 98]. +NPC id=3221, name=Dwarf, level=10, option=[null, Attack, null, null, null], anims=[101, 98]. +NPC id=3222, name=Drunken man, level=3, option=[Talk-to, Attack, Pickpocket, null, null], anims=[2770, 2769]. +NPC id=3223, name=Man, level=2, option=[Talk-to, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=3224, name=Man, level=2, option=[Talk-to, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=3225, name=Man, level=2, option=[Talk-to, Attack, Pickpocket, null, null], anims=[813, -1]. +NPC id=3226, name=Woman, level=2, option=[Talk-to, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=3227, name=Woman, level=2, option=[Talk-to, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=3228, name=Guard, level=21, option=[null, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=3229, name=Guard, level=22, option=[null, Attack, Pickpocket, null, null], anims=[4591, -1]. +NPC id=3230, name=Guard, level=19, option=[null, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=3231, name=Guard, level=22, option=[null, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=3232, name=Guard, level=22, option=[null, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=3233, name=Guard, level=22, option=[null, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=3234, name=Gardener, level=3, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=3235, name=Apprentice workman, level=0, option=[Talk-to, null, null, null, null], anims=[808, 819]. +NPC id=3236, name=Workman, level=0, option=[Talk-to, null, null, null, null], anims=[808, 819]. +NPC id=3237, name=Cuffs, level=3, option=[Talk-to, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=3238, name=Narf, level=2, option=[Talk-to, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=3239, name=Rusty, level=2, option=[Talk-to, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=3240, name=Jeff, level=2, option=[Talk-to, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=3241, name=Guard, level=19, option=[Talk-to, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=3242, name=Dark wizard, level=23, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=3243, name=Dark wizard, level=22, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=3244, name=Dark wizard, level=11, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=3245, name=Dark wizard, level=11, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=3246, name=Barbarian, level=17, option=[Talk-to, Attack, null, null, null], anims=[2065, 2064]. +NPC id=3247, name=Barbarian, level=10, option=[Talk-to, Attack, null, null, null], anims=[2561, -1]. +NPC id=3248, name=Barbarian, level=17, option=[Talk-to, Attack, null, null, null], anims=[2065, 2064]. +NPC id=3249, name=Barbarian, level=17, option=[Talk-to, Attack, null, null, null], anims=[2561, -1]. +NPC id=3250, name=Barbarian, level=10, option=[Talk-to, Attack, null, null, null], anims=[2065, 2064]. +NPC id=3251, name=Barbarian, level=10, option=[Talk-to, Attack, null, null, null], anims=[2561, -1]. +NPC id=3252, name=Barbarian, level=10, option=[Talk-to, Attack, null, null, null], anims=[2065, 2064]. +NPC id=3253, name=Barbarian, level=17, option=[Talk-to, Attack, null, null, null], anims=[2561, -1]. +NPC id=3254, name=Hunding, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3255, name=Barbarian, level=10, option=[Talk-to, Attack, null, null, null], anims=[2561, -1]. +NPC id=3256, name=Barbarian, level=10, option=[Talk-to, Attack, null, null, null], anims=[2561, -1]. +NPC id=3257, name=Barbarian, level=10, option=[Talk-to, Attack, null, null, null], anims=[2065, 2064]. +NPC id=3258, name=Barbarian, level=10, option=[Talk-to, Attack, null, null, null], anims=[2561, -1]. +NPC id=3259, name=Barbarian, level=15, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=3260, name=Barbarian, level=17, option=[Talk-to, Attack, null, null, null], anims=[813, -1]. +NPC id=3261, name=Barbarian, level=10, option=[Talk-to, Attack, null, null, null], anims=[813, -1]. +NPC id=3262, name=Barbarian, level=10, option=[Talk-to, Attack, null, null, null], anims=[813, -1]. +NPC id=3263, name=Barbarian, level=9, option=[Talk-to, Attack, null, null, null], anims=[813, -1]. +NPC id=3264, name=Goblin, level=5, option=[null, Attack, null, null, null], anims=[6186, 6187]. +NPC id=3265, name=Goblin, level=5, option=[null, Attack, null, null, null], anims=[6186, 6187]. +NPC id=3266, name=Goblin, level=5, option=[null, Attack, null, null, null], anims=[6186, 6187]. +NPC id=3267, name=Goblin, level=5, option=[null, Attack, null, null, null], anims=[6186, 6187]. +NPC id=3268, name=Dwarf, level=11, option=[null, Attack, null, null, null], anims=[101, 98]. +NPC id=3269, name=Dwarf, level=11, option=[null, Attack, null, null, null], anims=[101, 98]. +NPC id=3270, name=Dwarf, level=11, option=[null, Attack, null, null, null], anims=[101, 98]. +NPC id=3271, name=Dwarf, level=11, option=[null, Attack, null, null, null], anims=[101, 98]. +NPC id=3272, name=Dwarf, level=10, option=[null, Attack, null, null, null], anims=[101, 98]. +NPC id=3273, name=Dwarf, level=11, option=[null, Attack, null, null, null], anims=[101, 98]. +NPC id=3274, name=Dwarf, level=11, option=[null, Attack, null, null, null], anims=[101, 98]. +NPC id=3275, name=Dwarf, level=7, option=[null, Attack, null, null, null], anims=[101, 98]. +NPC id=3276, name=Black Guard, level=25, option=[null, Attack, null, null, null], anims=[101, 98]. +NPC id=3277, name=Black Guard, level=25, option=[null, Attack, null, null, null], anims=[101, 98]. +NPC id=3278, name=Black Guard, level=25, option=[null, Attack, null, null, null], anims=[101, 98]. +NPC id=3279, name=Black Guard, level=25, option=[null, Attack, null, null, null], anims=[101, 98]. +NPC id=3280, name=Engineering assistant, level=0, option=[null, null, null, null, null], anims=[3208, 3207]. +NPC id=3281, name=Engineering assistant, level=0, option=[null, null, null, null, null], anims=[3208, 3207]. +NPC id=3282, name=Engineer, level=0, option=[null, null, null, null, null], anims=[101, 98]. +NPC id=3283, name=Squirrel, level=0, option=[null, null, null, null, null], anims=[3211, 3210]. +NPC id=3284, name=Squirrel, level=0, option=[null, null, null, null, null], anims=[3212, 3210]. +NPC id=3285, name=Squirrel, level=0, option=[null, null, null, null, null], anims=[3212, 3210]. +NPC id=3286, name=Raccoon, level=0, option=[null, null, null, null, null], anims=[7718, 7719]. +NPC id=3287, name=Raccoon, level=0, option=[null, null, null, null, null], anims=[7718, 7719]. +NPC id=3288, name=Raccoon, level=0, option=[null, null, null, null, null], anims=[7718, 7719]. +NPC id=3289, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC (wrapper) id=3290, child npcs=[288, 288, 288, -1]. +NPC id=3291, name=Skeleton, level=22, option=[null, Attack, null, null, null], anims=[5483, 5481]. +NPC id=3292, name=Witch, level=25, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=3293, name=null, level=0, option=[null, null, null, null, null], anims=[-1, 3220]. +NPC id=3294, name=Dwarf, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=3295, name=Dwarf, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=3296, name=Swan, level=0, option=[null, null, null, null, null], anims=[3242, 3241]. +NPC id=3297, name=Black swan, level=0, option=[null, null, null, null, null], anims=[3242, 3241]. +NPC id=3298, name=Sweeper, level=0, option=[null, null, null, null, null], anims=[3244, 3245]. +NPC id=3299, name=Martin the Master Gardener, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[808, -1]. +NPC id=3300, name=Frog, level=0, option=[Talk-to, null, null, null, null], anims=[1796, 1797]. +NPC id=3301, name=Storm cloud, level=0, option=[null, null, null, null, null], anims=[3169, 3169]. +NPC id=3302, name=Co-ordinator, level=0, option=[Talk-to, null, null, null, null], anims=[112, 106]. +NPC id=3303, name=Fairy Nuff, level=0, option=[Talk-to, null, null, null, null], anims=[112, 106]. +NPC id=3304, name=Fairy Godfather, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=3305, name=Slim Louie, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=3306, name=Fat Rocco, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=3307, name=Gatekeeper, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3308, name=Zandar Horfyre, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=3309, name=Cow, level=2, option=[Talk-to, Attack, null, null, null], anims=[5852, 5848]. +NPC id=3310, name=Sheep, level=0, option=[Talk-to, null, null, null, null], anims=[5335, 5334]. +NPC id=3311, name=Sheep, level=0, option=[Talk-to, null, null, null, null], anims=[5339, 5340]. +NPC id=3312, name=Zanaris choir, level=0, option=[Talk-to, null, null, null, null], anims=[3252, 3253]. +NPC id=3313, name=Tanglefoot, level=111, option=[null, Attack, null, null, null], anims=[3259, 3261]. +NPC (wrapper) id=3314, child npcs=[653, -1]. +NPC id=3315, name=null, level=1, option=[null, null, null, null, null], anims=[3248, 3249]. +NPC id=3316, name=null, level=1, option=[null, null, null, null, null], anims=[3248, 3249]. +NPC id=3317, name=null, level=1, option=[null, null, null, null, null], anims=[3248, 3249]. +NPC id=3318, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=3319, name=Baby tanglefoot, level=45, option=[null, Attack, null, null, null], anims=[3259, 3261]. +NPC id=3320, name=Baby tanglefoot, level=45, option=[null, Attack, null, null, null], anims=[3259, 3261]. +NPC id=3321, name=Gatekeeper, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=3322, name=Fairy chef, level=0, option=[Talk-to, null, null, null, null], anims=[112, 106]. +NPC (wrapper) id=3323, child npcs=[637, -1, 637, -1]. +NPC id=3324, name=Draul Leptoc, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3325, name=Phillipa, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3326, name=Martina Scorsby, level=0, option=[null, null, null, null, null], anims=[3281, -1]. +NPC id=3327, name=Jeremy Clerksin, level=0, option=[null, null, null, null, null], anims=[3282, -1]. +NPC id=3328, name=Tarquin, level=0, option=[Talk-To, null, null, null, null], anims=[808, -1]. +NPC id=3329, name=Sigurd, level=0, option=[Talk-To, null, null, null, null], anims=[808, -1]. +NPC id=3330, name=Hari, level=0, option=[Talk-To, null, null, null, null], anims=[808, -1]. +NPC id=3331, name=Barfy Bill, level=0, option=[Talk-To, null, null, null, null], anims=[808, -1]. +NPC id=3332, name=Trees, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=3333, name=Trees, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=3334, name=Cavemouth, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=3335, name=Bullrush, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=3336, name=Bullrush, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=3337, name=Cave Scenery, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=3338, name=Cave Scenery, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=3339, name=Cave Scenery, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=3340, name=Giant Mole, level=230, option=[null, Attack, null, null, null], anims=[3309, 3313]. +NPC id=3341, name=Baby Mole, level=0, option=[null, null, null, null, null], anims=[3309, 3313]. +NPC id=3342, name=Baby Mole, level=0, option=[null, null, null, null, null], anims=[3309, 3313]. +NPC id=3343, name=Baby Mole, level=0, option=[null, null, null, null, null], anims=[3309, 3313]. +NPC id=3344, name=Fungi, level=74, option=[Pick, null, Hidden, null, null], anims=[3328, 3328]. +NPC id=3345, name=Fungi, level=86, option=[Pick, null, Hidden, null, null], anims=[3328, 3328]. +NPC id=3346, name=Zygomite, level=74, option=[null, Attack, Hidden, null, null], anims=[3324, 3323]. +NPC id=3347, name=Zygomite, level=86, option=[null, Attack, Hidden, null, null], anims=[3324, 3322]. +NPC id=3348, name=White Knight, level=38, option=[null, Attack, null, null, null], anims=[7047, -1]. +NPC id=3349, name=White Knight, level=39, option=[null, Attack, null, null, null], anims=[7047, -1]. +NPC id=3350, name=White Knight, level=42, option=[null, Attack, null, null, null], anims=[7047, -1]. +NPC id=3351, name=Genie, level=0, option=[Talk-to, null, null, null, null], anims=[792, 792]. +NPC id=3352, name=Mysterious Old Man, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3353, name=Swarm, level=0, option=[null, null, null, null, null], anims=[0, 0]. +NPC id=3354, name=Cap'n Hand, level=0, option=[Talk-to, null, null, null, null], anims=[7199, -1]. +NPC id=3355, name=Rick Turpentine, level=0, option=[Talk-to, null, null, null, null], anims=[4591, -1]. +NPC id=3356, name=Niles, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3357, name=Miles, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3358, name=Giles, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3359, name=Dr Jekyll, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3360, name=Mr Hyde, level=14, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=3361, name=Mr Hyde, level=29, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=3362, name=Mr Hyde, level=49, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=3363, name=Mr Hyde, level=79, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=3364, name=Mr Hyde, level=120, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=3365, name=Mr Hyde, level=159, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=3366, name=Evil Chicken, level=19, option=[null, Attack, null, null, null], anims=[2298, 2297]. +NPC id=3367, name=Evil Chicken, level=38, option=[null, Attack, null, null, null], anims=[2298, 2297]. +NPC id=3368, name=Evil Chicken, level=69, option=[null, Attack, null, null, null], anims=[2298, 2297]. +NPC id=3369, name=Evil Chicken, level=81, option=[null, Attack, null, null, null], anims=[2298, 2297]. +NPC id=3370, name=Evil Chicken, level=121, option=[null, Attack, null, null, null], anims=[2298, 2297]. +NPC id=3371, name=Evil Chicken, level=159, option=[null, Attack, null, null, null], anims=[2298, 2297]. +NPC id=3372, name=Sir Amik Varze, level=0, option=[Talk-to, null, null, null, null], anims=[3396, 3396]. +NPC id=3373, name=null, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=3374, name=Sir Amik Varze, level=0, option=[Inspect, null, null, null, null], anims=[3371, 3371]. +NPC id=3375, name=Evil Chicken, level=159, option=[null, Attack, null, null, null], anims=[2298, 2297]. +NPC id=3376, name=Baby black dragon, level=83, option=[null, Attack, null, null, null], anims=[27, 21]. +NPC id=3377, name=K'klik, level=0, option=[null, null, null, null, null], anims=[3346, -1]. +NPC id=3378, name=Evil Dave, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC (wrapper) id=3379, child npcs=[3380, 3380, 3380, 3380, 3380, -1]. +NPC id=3380, name=Evil Dave, level=0, option=[Inspect, null, null, null, null], anims=[3396, 3396]. +NPC id=3381, name=Doris, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3382, name=Hell-Rat, level=0, option=[null, null, null, null, null], anims=[2704, 2703]. +NPC id=3383, name=null, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=3384, name=null, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=3385, name=Gypsy, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3386, name=Gypsy, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3387, name=Culinaromancer, level=0, option=[null, null, null, null, null], anims=[3365, 3365]. +NPC id=3388, name=Osman, level=0, option=[null, null, null, null, null], anims=[3396, 3396]. +NPC id=3389, name=Pirate Pete, level=0, option=[null, null, null, null, null], anims=[3396, 3396]. +NPC id=3390, name=Mountain Dwarf, level=0, option=[null, null, null, null, null], anims=[3379, 3379]. +NPC id=3391, name=General Wartface, level=0, option=[null, null, null, null, null], anims=[3390, 3390]. +NPC id=3392, name=General Bentnoze, level=0, option=[null, null, null, null, null], anims=[7262, 7262]. +NPC id=3393, name=Lumbridge Guide, level=0, option=[null, null, null, null, null], anims=[3396, 3396]. +NPC id=3394, name=Evil Dave, level=0, option=[null, null, null, null, null], anims=[3396, 3396]. +NPC id=3395, name=Sir Amik Varze, level=0, option=[null, null, null, null, null], anims=[3396, 3396]. +NPC id=3396, name=Awowogei, level=0, option=[null, null, null, null, null], anims=[3395, 3395]. +NPC id=3397, name=Awowogei, level=0, option=[null, null, null, null, null], anims=[1386, 1380]. +NPC id=3398, name=Skrach Uglogwee, level=0, option=[null, null, null, null, null], anims=[3383, 3383]. +NPC id=3399, name=null, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=3400, name=Culinaromancer, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC (wrapper) id=3401, child npcs=[3402, 3403, -1]. +NPC id=3402, name=An old Dwarf, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=3403, name=Rohak, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=3404, name=null, level=1, option=[null, null, null, null, null], anims=[900, 104]. +NPC id=3405, name=Rohak, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=3406, name=Icefiend, level=18, option=[null, Attack, null, null, null], anims=[8077, 8076]. +NPC id=3407, name=Guard, level=21, option=[null, Attack, Pickpocket, null, null], anims=[7222, 7223]. +NPC id=3408, name=Guard, level=21, option=[null, Attack, Pickpocket, null, null], anims=[7217, 7216]. +NPC id=3409, name=Wild jade vine, level=167, option=[null, Attack, null, null, null], anims=[7245, -1]. +NPC id=3410, name=Wild jade vine, level=167, option=[null, Attack, null, null, null], anims=[7245, -1]. +NPC id=3411, name=Wild jade vine, level=167, option=[null, Attack, null, null, null], anims=[7245, -1]. +NPC id=3412, name=Wild jade vine, level=167, option=[null, Attack, null, null, null], anims=[7245, -1]. +NPC id=3413, name=Goblin Cook, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=3414, name=Goblin Cook, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=3415, name=Goblin Cook, level=0, option=[null, null, null, null, null], anims=[3401, 3401]. +NPC id=3416, name=Pirate Pete, level=0, option=[Talk-to, null, null, null, null], anims=[3396, 3396]. +NPC id=3417, name=null, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=3418, name=Pirate Pete, level=0, option=[Inspect, null, null, null, null], anims=[3374, 3374]. +NPC id=3419, name=Mogre Guard, level=0, option=[Talk-to, null, null, null, null], anims=[3436, 3437]. +NPC id=3420, name=Nung, level=0, option=[Talk-to, null, null, null, null], anims=[3436, 3437]. +NPC id=3421, name=Crab, level=23, option=[null, Attack, null, null, null], anims=[3424, 3426]. +NPC id=3422, name=Mudskipper, level=30, option=[null, Attack, null, null, null], anims=[3431, 3432]. +NPC id=3423, name=Mudskipper, level=31, option=[null, Attack, null, null, null], anims=[3431, 3432]. +NPC id=3424, name=Crab, level=21, option=[null, Attack, null, null, null], anims=[3424, 3426]. +NPC id=3425, name=Fish, level=0, option=[null, null, null, null, null], anims=[3442, 3441]. +NPC id=3426, name=Fish, level=0, option=[null, null, null, null, null], anims=[3442, 3441]. +NPC id=3427, name=Fish, level=0, option=[null, null, null, null, null], anims=[3442, 3441]. +NPC id=3428, name=Fish, level=0, option=[null, null, null, null, null], anims=[3442, 3441]. +NPC id=3429, name=Fish, level=0, option=[null, null, null, null, null], anims=[3442, 3441]. +NPC id=3430, name=Fish, level=0, option=[null, null, null, null, null], anims=[3442, 3441]. +NPC id=3431, name=Fish, level=0, option=[null, null, null, null, null], anims=[3442, 3441]. +NPC id=3432, name=Fish, level=0, option=[null, null, null, null, null], anims=[3442, 3441]. +NPC id=3433, name=Fish, level=0, option=[null, null, null, null, null], anims=[3442, 3441]. +NPC id=3434, name=Fish, level=0, option=[null, null, null, null, null], anims=[3442, 3441]. +NPC id=3435, name=Fish, level=0, option=[null, null, null, null, null], anims=[3442, 3441]. +NPC id=3436, name=Fish, level=0, option=[null, null, null, null, null], anims=[3442, 3441]. +NPC id=3437, name=Fish, level=0, option=[null, null, null, null, null], anims=[3442, 3441]. +NPC id=3438, name=Fish, level=0, option=[null, null, null, null, null], anims=[3442, 3441]. +NPC id=3439, name=Fish, level=0, option=[null, null, null, null, null], anims=[3442, 3441]. +NPC id=3440, name=Fish, level=0, option=[null, null, null, null, null], anims=[3442, 3441]. +NPC id=3441, name=Fish, level=0, option=[null, null, null, null, null], anims=[3442, 3441]. +NPC id=3442, name=Fish, level=0, option=[null, null, null, null, null], anims=[3442, 3441]. +NPC id=3443, name=Fish, level=0, option=[null, null, null, null, null], anims=[3444, 3443]. +NPC id=3444, name=Fish, level=0, option=[null, null, null, null, null], anims=[3444, 3443]. +NPC id=3445, name=Fish, level=0, option=[null, null, null, null, null], anims=[3444, 3443]. +NPC id=3446, name=Fish, level=0, option=[null, null, null, null, null], anims=[3444, 3443]. +NPC id=3447, name=Fish, level=0, option=[null, null, null, null, null], anims=[3444, 3443]. +NPC id=3448, name=Fish, level=0, option=[null, null, null, null, null], anims=[3444, 3443]. +NPC id=3449, name=Lumbridge Guide, level=0, option=[Talk-to, null, null, null, null], anims=[3396, 3396]. +NPC id=3450, name=null, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=3451, name=Lumbridge Guide, level=0, option=[Inspect, null, null, null, null], anims=[3362, 3362]. +NPC id=3452, name=? ? ? ?, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=3453, name=? ? ? ?, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=3454, name=? ? ? ?, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=3455, name=? ? ? ?, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=3456, name=? ? ? ?, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=3457, name=? ? ? ?, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=3458, name=? ? ? ?, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=3459, name=? ? ? ?, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=3460, name=? ? ? ?, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=3461, name=? ? ? ?, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=3462, name=null, level=0, option=[null, null, null, null, null], anims=[357, 358]. +NPC id=3463, name=Skrach Uglogwee, level=0, option=[Inspect, null, null, null, null], anims=[357, 358]. +NPC id=3464, name=Skrach Uglogwee, level=0, option=[Talk-to, null, null, null, null], anims=[357, 358]. +NPC id=3465, name=null, level=1, option=[null, null, null, null, null], anims=[357, 358]. +NPC id=3466, name=Rantz, level=0, option=[Talk-to, null, null, null, null], anims=[357, 358]. +NPC id=3467, name=Rantz, level=1, option=[Talk-to, null, null, null, null], anims=[3460, 3460]. +NPC id=3468, name=Rantz, level=1, option=[Talk-to, null, null, null, null], anims=[3462, 3462]. +NPC id=3469, name=null, level=1, option=[null, null, null, null, null], anims=[3473, 3474]. +NPC id=3470, name=null, level=1, option=[null, null, null, null, null], anims=[3473, 3474]. +NPC id=3471, name=Ogre boat, level=0, option=[Board, null, null, null, null], anims=[3473, 3474]. +NPC id=3472, name=Ogre boat, level=0, option=[Board, null, null, null, null], anims=[3473, 3474]. +NPC id=3473, name=Balloon Toad, level=0, option=[null, null, null, null, null], anims=[3469, 3469]. +NPC id=3474, name=Balloon Toad, level=0, option=[null, null, null, null, null], anims=[3469, 3469]. +NPC id=3475, name=Balloon Toad, level=0, option=[null, null, null, null, null], anims=[3472, 3472]. +NPC id=3476, name=Jubbly bird, level=9, option=[null, null, null, null, Attack], anims=[6803, 6804]. +NPC id=3477, name=Jubbly bird, level=0, option=[null, null, null, Pluck, null], anims=[6807, 6807]. +NPC id=3478, name=King Awowogei, level=0, option=[Talk-to, null, null, null, null], anims=[1386, 1380]. +NPC id=3479, name=null, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=3480, name=King Awowogei, level=0, option=[Inspect, null, null, null, null], anims=[1386, 1380]. +NPC id=3481, name=Mizaru, level=0, option=[Talk-to, null, null, null, null], anims=[3525, -1]. +NPC id=3482, name=Kikazaru, level=0, option=[Talk-to, null, null, null, null], anims=[3523, -1]. +NPC id=3483, name=Iwazaru, level=0, option=[Talk-to, null, null, null, null], anims=[3524, -1]. +NPC id=3484, name=Big Snake, level=84, option=[null, Attack, null, null, null], anims=[3535, 3537]. +NPC id=3485, name=Culinaromancer, level=0, option=[null, null, null, null, null], anims=[3846, -1]. +NPC id=3486, name=Culinaromancer, level=0, option=[null, null, null, null, null], anims=[3846, -1]. +NPC id=3487, name=Culinaromancer, level=0, option=[null, null, null, null, null], anims=[3846, -1]. +NPC id=3488, name=Culinaromancer, level=0, option=[null, null, null, null, null], anims=[3846, -1]. +NPC id=3489, name=Culinaromancer, level=0, option=[null, null, null, null, null], anims=[3846, -1]. +NPC id=3490, name=Culinaromancer, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=3491, name=Culinaromancer, level=75, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=3492, name=Culinaromancer, level=0, option=[null, null, null, null, null], anims=[3357, -1]. +NPC id=3493, name=Agrith-Na-Na, level=146, option=[null, Attack, null, null, null], anims=[3498, 3499]. +NPC id=3494, name=Flambeed, level=149, option=[null, Attack, null, null, null], anims=[1749, 1748]. +NPC id=3495, name=Karamel, level=136, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=3496, name=Dessourt, level=121, option=[null, Attack, null, null, null], anims=[3504, 3506]. +NPC id=3497, name=Gelatinnoth Mother, level=130, option=[null, Attack, null, null, null], anims=[1338, 1339]. +NPC id=3498, name=Gelatinnoth Mother, level=130, option=[null, Attack, null, null, null], anims=[1338, 1339]. +NPC id=3499, name=Gelatinnoth Mother, level=130, option=[null, Attack, null, null, null], anims=[1338, 1339]. +NPC id=3500, name=Gelatinnoth Mother, level=130, option=[null, Attack, null, null, null], anims=[1338, 1339]. +NPC id=3501, name=Gelatinnoth Mother, level=130, option=[null, Attack, null, null, null], anims=[1338, 1339]. +NPC id=3502, name=Gelatinnoth Mother, level=130, option=[null, Attack, null, null, null], anims=[1338, 1339]. +NPC id=3503, name=Overgrown hellcat, level=0, option=[Pick-up, null, Talk-to, Interact-with, null], anims=[9158, 9157]. +NPC id=3504, name=Hellcat, level=0, option=[Pick-up, null, Talk-to, Interact-with, null], anims=[9158, 9157]. +NPC id=3505, name=Hell-kitten, level=0, option=[Pick-up, Hidden, Talk-to, Interact-with, null], anims=[9158, 9157]. +NPC id=3506, name=Lazy hellcat, level=0, option=[Pick-up, null, Talk-to, Interact-with, null], anims=[9158, 9157]. +NPC id=3507, name=Wily hellcat, level=0, option=[Pick-up, null, Talk-to, Interact-with, null], anims=[9158, 9157]. +NPC id=3508, name=Leo, level=0, option=[Talk-to, null, null, null, null], anims=[2561, 2562]. +NPC id=3509, name=Sorin, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3510, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=3511, name=Wiskit, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3512, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=3513, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=3514, name=Vampyre Juvinate, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=3515, name=Vampyre Juvinate, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3516, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=3517, name=Gadderanks, level=0, option=[Talk-to, null, null, null, null], anims=[2065, 2064]. +NPC id=3518, name=Gadderanks, level=35, option=[Talk-to, Attack, null, null, null], anims=[2065, 2064]. +NPC id=3519, name=Gadderanks, level=0, option=[Talk-to, null, null, null, null], anims=[3563, -1]. +NPC id=3520, name=Vampyre Juvinate, level=50, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=3521, name=Vampyre Juvinate, level=54, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=3522, name=Vampyre Juvinate, level=54, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=3523, name=Vampyre Juvinate, level=54, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=3524, name=Vampyre Juvinate, level=54, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=3525, name=Vampyre Juvinate, level=54, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=3526, name=Vampyre Juvinate, level=64, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=3527, name=Held Vampyre Juvinate, level=54, option=[null, Attack, null, null, null], anims=[3551, -1]. +NPC id=3528, name=Vampyre Juvinate, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=3529, name=Vampyre Juvinate, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=3530, name=Mist, level=0, option=[null, null, null, null, null], anims=[1261, 1261]. +NPC id=3531, name=Vampyre Juvenile, level=45, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=3532, name=Vampyre Juvenile, level=45, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=3533, name=Vampyre Juvenile, level=45, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=3534, name=Held Vampyre Juvenile, level=45, option=[null, Attack, null, null, null], anims=[3551, -1]. +NPC id=3535, name=Ivan Strom, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3536, name=Ivan Strom, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3537, name=Vampyre Juvinate, level=75, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=3538, name=Vampyre Juvinate, level=50, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=3539, name=Veliaf Hurtz, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3540, name=Elisabeta, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3541, name=Aurel, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=3542, name=Sorin, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3543, name=Luscion, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3544, name=Sergiu, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3545, name=Radu, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3546, name=Grigore, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3547, name=Ileana, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3548, name=Valeria, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3549, name=Emilia, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3550, name=Florin, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3551, name=Catalina, level=0, option=[Talk-to, null, null, null, null], anims=[7298, 7297]. +NPC id=3552, name=Ivan, level=0, option=[Talk-to, null, null, null, null], anims=[7298, 7297]. +NPC id=3553, name=Victor, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=3554, name=Helena, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=3555, name=Teodor, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3556, name=Marius, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=3557, name=Gabriela, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3558, name=Vladimir, level=0, option=[Talk-to, null, null, null, null], anims=[1147, -1]. +NPC id=3559, name=Calin, level=0, option=[Talk-to, null, null, null, null], anims=[1144, -1]. +NPC id=3560, name=Mihail, level=0, option=[Talk-to, null, null, null, null], anims=[1144, -1]. +NPC id=3561, name=Nicoleta, level=0, option=[Talk-to, null, null, null, null], anims=[1144, -1]. +NPC id=3562, name=Simona, level=0, option=[Talk-to, null, null, null, null], anims=[1144, -1]. +NPC id=3563, name=Vasile, level=0, option=[Talk-to, null, null, null, null], anims=[3557, -1]. +NPC id=3564, name=Razvan, level=0, option=[Talk-to, null, null, null, null], anims=[3557, -1]. +NPC id=3565, name=Luminata, level=0, option=[Talk-to, null, null, null, null], anims=[3557, -1]. +NPC (wrapper) id=3566, child npcs=[3568, -1]. +NPC id=3567, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=3568, name=Cornelius, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3569, name=Cornelius, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3570, name=Benjamin, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3571, name=Liam, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3572, name=Miala, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3573, name=Verak, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3574, name=Fishing spot, level=0, option=[Net, null, Harpoon, hidden, hidden], anims=[447, 448]. +NPC id=3575, name=Fishing spot, level=0, option=[Net, null, Harpoon, hidden, hidden], anims=[447, 448]. +NPC id=3576, name=Juvinate, level=59, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=3577, name=Juvinate, level=90, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=3578, name=Juvinate, level=119, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=3579, name=Sheep, level=0, option=[Shear, null, Talk-to, null, null], anims=[3569, 3568]. +NPC id=3580, name=Tentacle, level=0, option=[null, null, null, null, null], anims=[3617, 3617]. +NPC id=3581, name=Skeleton, level=22, option=[null, Attack, null, null, null], anims=[5483, 5479]. +NPC id=3582, name=Guard dog, level=44, option=[null, Attack, null, null, null], anims=[6561, 6560]. +NPC id=3583, name=Hobgoblin, level=54, option=[null, Attack, null, null, null], anims=[166, 162]. +NPC id=3584, name=Troll, level=91, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=3585, name=Huge spider, level=81, option=[null, Attack, null, null, null], anims=[5318, 5317]. +NPC id=3586, name=Hellhound, level=122, option=[null, Attack, null, null, null], anims=[6561, 6583]. +NPC id=3587, name=Ogre, level=53, option=[null, Attack, null, null, null], anims=[357, 358]. +NPC id=3588, name=Baby red dragon, level=65, option=[null, Attack, null, null, null], anims=[27, 21]. +NPC id=3589, name=Kalphite Soldier, level=85, option=[null, Attack, null, null, null], anims=[6218, 6220]. +NPC id=3590, name=Steel dragon, level=246, option=[null, Attack, null, null, null], anims=[6496, 79]. +NPC id=3591, name=Dagannoth, level=135, option=[null, Attack, null, null, null], anims=[1338, 1339]. +NPC id=3592, name=Tok-Xil, level=135, option=[null, Attack, null, null, null], anims=[9241, 9240]. +NPC id=3593, name=Demon, level=82, option=[null, Attack, null, null, null], anims=[66, 63]. +NPC id=3594, name=Rocnar, level=97, option=[null, Attack, null, null, null], anims=[3707, 3708]. +NPC id=3595, name=Toy Soldier, level=0, option=[Pick-up, null, null, null, null], anims=[3712, 3713]. +NPC id=3596, name=Toy Doll, level=0, option=[Pick-up, null, null, null, null], anims=[3716, 3717]. +NPC id=3597, name=Toy Mouse, level=0, option=[Pick-up, null, null, null, null], anims=[3718, 3718]. +NPC id=3598, name=Clockwork cat, level=0, option=[Pick-up, null, null, null, Shoo], anims=[9158, 9157]. +NPC id=3599, name=Swamp snake, level=80, option=[null, Attack, null, null, null], anims=[3535, -1]. +NPC id=3600, name=Swamp snake, level=109, option=[null, Attack, null, null, null], anims=[3535, -1]. +NPC id=3601, name=Swamp snake, level=139, option=[null, Attack, null, null, null], anims=[3535, -1]. +NPC id=3602, name=Swamp snake, level=0, option=[null, Skin, null, null, null], anims=[3535, 3537]. +NPC id=3603, name=Dead swamp snake, level=0, option=[null, null, null, null, null], anims=[3738, -1]. +NPC id=3604, name=Dead swamp snake, level=0, option=[null, null, null, null, null], anims=[3738, -1]. +NPC id=3605, name=Dead swamp snake, level=0, option=[null, null, null, null, null], anims=[3738, -1]. +NPC id=3606, name=Ghast, level=0, option=[null, null, null, null, null], anims=[1092, 1091]. +NPC id=3607, name=Ghast, level=0, option=[null, null, null, null, null], anims=[1092, 1091]. +NPC id=3608, name=Ghast, level=0, option=[null, null, null, null, null], anims=[1092, 1091]. +NPC id=3609, name=Ghast, level=79, option=[null, Attack, null, null, null], anims=[1086, 1085]. +NPC id=3610, name=Ghast, level=109, option=[null, Attack, null, null, null], anims=[1086, 1085]. +NPC id=3611, name=Ghast, level=139, option=[null, Attack, null, null, null], anims=[1086, 1085]. +NPC id=3612, name=Giant snail, level=80, option=[null, Attack, null, null, null], anims=[3722, 3721]. +NPC id=3613, name=Giant snail, level=109, option=[null, Attack, null, null, null], anims=[3722, 3721]. +NPC id=3614, name=Giant snail, level=139, option=[null, Attack, null, null, null], anims=[3722, 3721]. +NPC id=3615, name=Riyl shadow, level=80, option=[null, Attack, null, null, null], anims=[1282, 1281]. +NPC id=3616, name=Asyn shadow, level=110, option=[null, Attack, null, null, null], anims=[1282, 1281]. +NPC id=3617, name=Shade, level=140, option=[null, Attack, null, null, null], anims=[1282, 1281]. +NPC id=3618, name=Tentacle, level=99, option=[null, Attack, null, null, null], anims=[3617, 3617]. +NPC id=3619, name=Head, level=140, option=[null, Attack, null, null, null], anims=[3730, 3730]. +NPC id=3620, name=Head, level=140, option=[null, Attack, null, null, null], anims=[3728, 3728]. +NPC id=3621, name=Tentacle, level=136, option=[null, Attack, null, null, null], anims=[3729, 3729]. +NPC id=3622, name=Zombie, level=23, option=[null, Attack, null, null, null], anims=[5572, -1]. +NPC id=3623, name=null, level=1, option=[null, null, null, null, null], anims=[7158, 7160]. +NPC id=3624, name=Smiddi Ryak, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=3625, name=null, level=1, option=[null, null, null, null, null], anims=[808, 1146]. +NPC id=3626, name=Rolayne Twickit, level=0, option=[Talk-to, null, null, null, null], anims=[808, 1146]. +NPC id=3627, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=3628, name=Jayene Kliyn, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3629, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=3630, name=Valantay Eppel, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3631, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=3632, name=Dalcian Fang, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=3633, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=3634, name=Fyiona Fray, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3635, name=Abidor Crank, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=3636, name=Spirit tree, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=3637, name=Spirit tree, level=0, option=[Talk-to, null, null, null, null], anims=[332, -1]. +NPC (wrapper) id=3638, child npcs=[3639, -1]. +NPC id=3639, name=Launa, level=0, option=[Talk-to, null, null, null, null], anims=[808, 1146]. +NPC id=3640, name=Launa, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3641, name=Brana, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=3642, name=Mawnis Burowgar, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=3643, name=Tolna, level=0, option=[Talk-to, null, null, null, null], anims=[5752, -1]. +NPC id=3644, name=Tolna, level=0, option=[null, null, null, null, null], anims=[7158, 7160]. +NPC id=3645, name=Angry bear, level=40, option=[null, Attack, null, null, null], anims=[4919, 4923]. +NPC id=3646, name=Angry unicorn, level=45, option=[null, Attack, null, null, null], anims=[6374, 6373]. +NPC id=3647, name=Angry giant rat, level=45, option=[null, Attack, null, null, null], anims=[4932, 4931]. +NPC id=3648, name=Angry goblin, level=45, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=3649, name=Fear reaper, level=42, option=[null, Attack, null, null, null], anims=[3810, 3809]. +NPC id=3650, name=Confusion beast, level=43, option=[null, Attack, null, null, null], anims=[3815, 3819]. +NPC id=3651, name=Confusion beast, level=43, option=[null, Attack, null, null, null], anims=[3815, 3819]. +NPC id=3652, name=Confusion beast, level=43, option=[null, Attack, null, null, null], anims=[3815, 3819]. +NPC id=3653, name=Confusion beast, level=43, option=[null, Attack, null, null, null], anims=[3815, 3819]. +NPC id=3654, name=Confusion beast, level=43, option=[null, Attack, null, null, null], anims=[3815, 3819]. +NPC id=3655, name=Hopeless creature, level=40, option=[null, Attack, null, null, null], anims=[3822, 3825]. +NPC id=3656, name=Hopeless creature, level=40, option=[null, Attack, null, null, null], anims=[3822, 3825]. +NPC id=3657, name=Hopeless creature, level=40, option=[null, Attack, null, null, null], anims=[3822, 3825]. +NPC id=3658, name=Tolna, level=46, option=[null, Attack, null, null, null], anims=[3828, 3828]. +NPC id=3659, name=Tolna, level=46, option=[null, Attack, null, null, null], anims=[3828, 3828]. +NPC id=3660, name=Tolna, level=46, option=[null, Attack, null, null, null], anims=[3828, 3828]. +NPC id=3661, name=Angry unicorn, level=47, option=[null, Attack, null, null, null], anims=[6374, 6373]. +NPC id=3662, name=Angry giant rat, level=47, option=[null, Attack, null, null, null], anims=[4932, 4931]. +NPC id=3663, name=Angry goblin, level=47, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=3664, name=Angry bear, level=47, option=[null, Attack, null, null, null], anims=[4919, 4923]. +NPC id=3665, name=Fear reaper, level=55, option=[null, Attack, null, null, null], anims=[3810, 3809]. +NPC id=3666, name=Confusion beast, level=63, option=[null, Attack, null, null, null], anims=[3815, 3819]. +NPC id=3667, name=Hopeless creature, level=71, option=[null, Attack, null, null, null], anims=[3822, 3825]. +NPC id=3668, name=Hopeless beast, level=71, option=[null, Attack, null, null, null], anims=[3822, 3825]. +NPC id=3669, name=Hopeless beast, level=71, option=[null, Attack, null, null, null], anims=[3822, 3825]. +NPC id=3670, name=Odd Old Man, level=0, option=[Talk-to, null, null, null, null], anims=[1740, 1739]. +NPC id=3671, name=Fortunato, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=3672, name=Ram, level=2, option=[null, Attack, null, null, null], anims=[5339, 5340]. +NPC id=3673, name=Ram, level=2, option=[null, Attack, null, null, null], anims=[5335, 5334]. +NPC id=3674, name=Bones, level=0, option=[null, null, null, null, null], anims=[3840, -1]. +NPC id=3675, name=Vulture, level=31, option=[null, Attack, null, null, null], anims=[2017, 2016]. +NPC id=3676, name=Vulture, level=31, option=[null, Attack, null, null, null], anims=[2024, 2024]. +NPC id=3677, name=Sinister Stranger, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3678, name=Sinister Stranger, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3679, name=Vestri, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=3680, name=Ali the Leaflet Dropper, level=0, option=[Talk-to, null, Take-flyer, null, null], anims=[7158, 7160]. +NPC id=3681, name=Nigel, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=3682, name=Egg, level=0, option=[null, null, null, null, null], anims=[-1, 3853]. +NPC id=3683, name=Egg, level=0, option=[null, null, null, null, null], anims=[-1, 3853]. +NPC id=3684, name=Egg, level=0, option=[null, null, null, null, null], anims=[-1, 3853]. +NPC id=3685, name=Egg, level=0, option=[null, null, null, null, null], anims=[-1, 3853]. +NPC id=3686, name=Chocolate kebbit, level=0, option=[Grab, null, null, null, null], anims=[5273, 5272]. +NPC id=3687, name=Chocolate kebbit, level=0, option=[null, null, null, null, null], anims=[5273, 5272]. +NPC id=3688, name=Easter Bunny, level=1, option=[null, null, null, null, null], anims=[1829, 1828]. +NPC id=3689, name=Egg, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=3690, name=Egg, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=3691, name=Egg, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=3692, name=Egg, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=3693, name=Egg, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=3694, name=Egg, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=3695, name=Volf Olafson, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3696, name=Ingrid Hradson, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3697, name=Skeleton fremennik, level=40, option=[null, Attack, null, null, null], anims=[6113, 6112]. +NPC id=3698, name=Skeleton fremennik, level=40, option=[null, Attack, null, null, null], anims=[6113, 6112]. +NPC id=3699, name=Skeleton fremennik, level=40, option=[null, Attack, null, null, null], anims=[6113, 6112]. +NPC id=3700, name=Skeleton fremennik, level=50, option=[null, Attack, null, null, null], anims=[6113, 6112]. +NPC id=3701, name=Skeleton fremennik, level=50, option=[null, Attack, null, null, null], anims=[6113, 6112]. +NPC id=3702, name=Skeleton fremennik, level=50, option=[null, Attack, null, null, null], anims=[6113, 6112]. +NPC id=3703, name=Skeleton fremennik, level=60, option=[null, Attack, null, null, null], anims=[6113, 6112]. +NPC id=3704, name=Skeleton fremennik, level=60, option=[null, Attack, null, null, null], anims=[6113, 6112]. +NPC id=3705, name=Skeleton fremennik, level=60, option=[null, Attack, null, null, null], anims=[6113, 6112]. +NPC id=3706, name=Ulfric, level=100, option=[null, Attack, null, null, null], anims=[6113, 6112]. +NPC id=3707, name=Brine rat, level=70, option=[null, Attack, null, null, null], anims=[6127, 6114]. +NPC id=3708, name=Boulder, level=0, option=[Roll, null, null, null, null], anims=[-1, 6120]. +NPC id=3709, name=Boulder, level=0, option=[null, null, null, null, null], anims=[-1, 6120]. +NPC id=3710, name=Ulfric, level=0, option=[null, null, null, null, null], anims=[6126, -1]. +NPC id=3711, name=Giant bat, level=27, option=[null, Attack, null, null, null], anims=[2618, 2619]. +NPC id=3712, name=Zanik, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=3713, name=Sigmund, level=64, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=3714, name=Zanik, level=41, option=[null, null, null, null, null], anims=[6040, 6041]. +NPC id=3715, name=Guard, level=22, option=[Attack, null, null, null, null], anims=[808, -1]. +NPC id=3716, name=Sigmund, level=64, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=3717, name=Sigmund, level=64, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=3718, name=Sigmund, level=64, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=3719, name=Sigmund, level=64, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=3720, name=Sigmund, level=64, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=3721, name=Zanik, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=3722, name=Zanik, level=0, option=[null, null, null, null, null], anims=[6040, 6041]. +NPC id=3723, name=General Bentnoze, level=0, option=[null, null, null, null, null], anims=[6203, 6202]. +NPC id=3724, name=General Wartface, level=0, option=[null, null, null, null, null], anims=[6203, 6202]. +NPC id=3725, name=Grubfoot, level=0, option=[null, null, null, null, null], anims=[6181, 6180]. +NPC id=3726, name=Goblin, level=0, option=[null, null, null, null, null], anims=[6181, 6180]. +NPC id=3727, name=Splatter, level=22, option=[null, Attack, null, null, null], anims=[3886, 3887]. +NPC id=3728, name=Splatter, level=33, option=[null, Attack, null, null, null], anims=[3886, 3887]. +NPC id=3729, name=Splatter, level=44, option=[null, Attack, null, null, null], anims=[3886, 3887]. +NPC id=3730, name=Splatter, level=54, option=[null, Attack, null, null, null], anims=[3886, 3887]. +NPC id=3731, name=Splatter, level=65, option=[null, Attack, null, null, null], anims=[3886, 3887]. +NPC id=3732, name=Shifter, level=38, option=[null, Attack, null, null, null], anims=[3899, 3898]. +NPC id=3733, name=Shifter, level=38, option=[null, Attack, null, null, null], anims=[3899, 3898]. +NPC id=3734, name=Shifter, level=57, option=[null, Attack, null, null, null], anims=[3899, 3898]. +NPC id=3735, name=Shifter, level=57, option=[null, Attack, null, null, null], anims=[3899, 3898]. +NPC id=3736, name=Shifter, level=76, option=[null, Attack, null, null, null], anims=[3899, 3898]. +NPC id=3737, name=Shifter, level=76, option=[null, Attack, null, null, null], anims=[3899, 3898]. +NPC id=3738, name=Shifter, level=90, option=[null, Attack, null, null, null], anims=[3899, 3898]. +NPC id=3739, name=Shifter, level=90, option=[null, Attack, null, null, null], anims=[3899, 3898]. +NPC id=3740, name=Shifter, level=104, option=[null, Attack, null, null, null], anims=[3899, 3898]. +NPC id=3741, name=Shifter, level=104, option=[null, Attack, null, null, null], anims=[3899, 3898]. +NPC id=3742, name=Ravager, level=36, option=[null, Attack, null, null, null], anims=[3913, 3914]. +NPC id=3743, name=Ravager, level=53, option=[null, Attack, null, null, null], anims=[3913, 3914]. +NPC id=3744, name=Ravager, level=71, option=[null, Attack, null, null, null], anims=[3913, 3914]. +NPC id=3745, name=Ravager, level=89, option=[null, Attack, null, null, null], anims=[3913, 3914]. +NPC id=3746, name=Ravager, level=106, option=[null, Attack, null, null, null], anims=[3913, 3914]. +NPC id=3747, name=Spinner, level=36, option=[null, Attack, null, null, null], anims=[3906, 3907]. +NPC id=3748, name=Spinner, level=55, option=[null, Attack, null, null, null], anims=[3906, 3907]. +NPC id=3749, name=Spinner, level=74, option=[null, Attack, null, null, null], anims=[3906, 3907]. +NPC id=3750, name=Spinner, level=92, option=[null, Attack, null, null, null], anims=[3906, 3907]. +NPC id=3751, name=Spinner, level=88, option=[null, Attack, null, null, null], anims=[3906, 3907]. +NPC id=3752, name=Torcher, level=33, option=[null, Attack, null, null, null], anims=[3878, 3879]. +NPC id=3753, name=Torcher, level=33, option=[null, Attack, null, null, null], anims=[3878, 3879]. +NPC id=3754, name=Torcher, level=49, option=[null, Attack, null, null, null], anims=[3878, 3879]. +NPC id=3755, name=Torcher, level=49, option=[null, Attack, null, null, null], anims=[3878, 3879]. +NPC id=3756, name=Torcher, level=66, option=[null, Attack, null, null, null], anims=[3878, 3879]. +NPC id=3757, name=Torcher, level=66, option=[null, Attack, null, null, null], anims=[3878, 3879]. +NPC id=3758, name=Torcher, level=79, option=[null, Attack, null, null, null], anims=[3878, 3879]. +NPC id=3759, name=Torcher, level=79, option=[null, Attack, null, null, null], anims=[3878, 3879]. +NPC id=3760, name=Torcher, level=91, option=[null, Attack, null, null, null], anims=[3878, 3879]. +NPC id=3761, name=Torcher, level=92, option=[null, Attack, null, null, null], anims=[3878, 3879]. +NPC id=3762, name=Defiler, level=33, option=[null, Attack, null, null, null], anims=[3918, 3919]. +NPC id=3763, name=Defiler, level=33, option=[null, Attack, null, null, null], anims=[3918, 3919]. +NPC id=3764, name=Defiler, level=50, option=[null, Attack, null, null, null], anims=[3918, 3919]. +NPC id=3765, name=Defiler, level=50, option=[null, Attack, null, null, null], anims=[3918, 3919]. +NPC id=3766, name=Defiler, level=66, option=[null, Attack, null, null, null], anims=[3918, 3919]. +NPC id=3767, name=Defiler, level=67, option=[null, Attack, null, null, null], anims=[3918, 3919]. +NPC id=3768, name=Defiler, level=80, option=[null, Attack, null, null, null], anims=[3918, 3919]. +NPC id=3769, name=Defiler, level=80, option=[null, Attack, null, null, null], anims=[3918, 3919]. +NPC id=3770, name=Defiler, level=97, option=[null, Attack, null, null, null], anims=[3918, 3919]. +NPC id=3771, name=Defiler, level=97, option=[null, Attack, null, null, null], anims=[3918, 3919]. +NPC id=3772, name=Brawler, level=51, option=[null, Attack, null, null, null], anims=[3893, 3892]. +NPC id=3773, name=Brawler, level=76, option=[null, Attack, null, null, null], anims=[3893, 3892]. +NPC id=3774, name=Brawler, level=101, option=[null, Attack, null, null, null], anims=[3893, 3892]. +NPC id=3775, name=Brawler, level=129, option=[null, Attack, null, null, null], anims=[3893, 3892]. +NPC id=3776, name=Brawler, level=158, option=[null, Attack, null, null, null], anims=[3893, 3892]. +NPC id=3777, name=Doomsayer, level=0, option=[Talk-to, null, Toggle-warnings, null, null], anims=[813, -1]. +NPC id=3778, name=null, level=1, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3779, name=Arthur, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=3780, name=null, level=1, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=3781, name=Squire, level=0, option=[Talk-to, null, Leave, null, null], anims=[813, -1]. +NPC id=3782, name=Void Knight, level=0, option=[null, hidden, null, null, null], anims=[3926, -1]. +NPC id=3783, name=Frog, level=62, option=[null, Attack, null, null, null], anims=[7258, 7259]. +NPC id=3784, name=Void Knight, level=0, option=[null, hidden, null, null, null], anims=[3926, -1]. +NPC id=3785, name=Void Knight, level=0, option=[null, hidden, null, null, null], anims=[3926, -1]. +NPC id=3786, name=Void Knight, level=0, option=[Talk-to, null, Exchange, null, null], anims=[813, -1]. +NPC id=3787, name=Sir Palomedes, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3788, name=Void Knight, level=0, option=[Talk-to, null, Exchange, null, null], anims=[813, -1]. +NPC id=3789, name=Void Knight, level=0, option=[Talk-to, null, Exchange, null, null], anims=[813, -1]. +NPC id=3790, name=Squire, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=3791, name=Squire, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=3792, name=Squire, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=3793, name=Squire, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=3794, name=Squire, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=3795, name=Squire, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=3796, name=Squire, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=3797, name=Squire, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3798, name=Squire, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=3799, name=Squire, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=3800, name=Squire, level=0, option=[Talk-to, null, Travel, null, null], anims=[813, -1]. +NPC id=3801, name=Squire, level=0, option=[Talk-to, null, Travel, null, null], anims=[813, -1]. +NPC id=3802, name=Squire (Novice), level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=3803, name=null, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=3804, name=Fishing spot, level=0, option=[Cage, null, Harpoon, hidden, hidden], anims=[447, 448]. +NPC id=3805, name=Postie Pete, level=0, option=[Talk-to, null, null, null, null], anims=[3948, 3947]. +NPC id=3806, name=Millie Miller, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3807, name=Gillie Groats, level=0, option=[Talk-to, null, null, null, null], anims=[3950, 3997]. +NPC id=3808, name=Tortoise, level=92, option=[null, Attack, null, null, null], anims=[3952, 3953]. +NPC id=3809, name=Captain Dalbur, level=0, option=[Talk-to, null, Glider, null, null], anims=[195, 189]. +NPC id=3810, name=Captain Bleemadge, level=0, option=[Talk-to, null, Glider, null, null], anims=[195, 189]. +NPC id=3811, name=Captain Errdo, level=0, option=[Talk-to, null, Glider, null, null], anims=[195, 189]. +NPC id=3812, name=Captain Klemfoodle, level=0, option=[Talk-to, null, Glider, null, null], anims=[195, 189]. +NPC id=3813, name=Captain Wimto, level=0, option=[Talk-to, null, Glider, null, null], anims=[195, 189]. +NPC id=3814, name=Gnome Archer, level=5, option=[null, Attack, null, null, null], anims=[195, 189]. +NPC id=3815, name=Gnome Driver, level=5, option=[null, Attack, null, null, null], anims=[195, 189]. +NPC id=3816, name=Gnome Mage, level=5, option=[null, Attack, null, null, null], anims=[195, 189]. +NPC id=3817, name=Lieutenant Schepbur, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=3818, name=Trainer Nacklepen, level=0, option=[Talk-to, null, null, null, null], anims=[3965, 3963]. +NPC id=3819, name=Tortoise, level=79, option=[null, Attack, null, null, null], anims=[3952, 3953]. +NPC (wrapper) id=3820, child npcs=[2253, -1, -1, -1, -1, 2253, -1, -1, -1, -1, 2253, -1, -1, -1, -1, 2253, -1, -1, -1, -1, 2253, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2253, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2253, -1]. +NPC id=3821, name=Wise Old Man, level=0, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=3822, name=Herman Caranos, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3823, name=Franklin Caranos, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3824, name=Arnold Lydspor, level=0, option=[Talk-to, null, Trade, Bank, Collect], anims=[808, -1]. +NPC id=3825, name=Devin Mendelberg, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3826, name=George Laxmeister, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3827, name=Ramara du Croissant, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC (wrapper) id=3828, child npcs=[3825, -1, -1, -1, -1, 3825, -1, -1, -1, -1, 3825, -1, -1, -1, -1, 3825, -1, -1, -1, -1, 3825, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3825, -1]. +NPC (wrapper) id=3829, child npcs=[3830, -1, -1, -1, -1, 3831, -1, -1, -1, -1, 3831, -1, -1, -1, -1, 3831, -1, -1, -1, -1, 3831, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3831, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3831, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3831, -1, -1, -1, -1, 3831, -1, -1, -1, -1, 3831, -1, -1, -1, -1, 3831, -1, -1, -1, -1, 3831, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3831, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3831, -1, -1, -1, -1, 3831, -1, -1, -1, -1, 3831, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3831, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3831, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3831, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3831, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3831, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3831, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3831, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3831, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3831, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3831, -1]. +NPC id=3830, name=Kathy Corkat, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3831, name=Kathy Corkat, level=0, option=[Talk-to, null, Travel, null, null], anims=[808, -1]. +NPC (wrapper) id=3832, child npcs=[3822, -1, -1, -1, -1, 3822, -1, -1, -1, -1, 3822, -1, -1, -1, -1, 3822, -1, -1, -1, -1, 3822, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2567, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2567, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2567, -1, -1, -1, -1, 2567, -1]. +NPC id=3833, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=3834, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=3835, name=Kalphite Queen, level=333, option=[null, Attack, null, null, null], anims=[6239, 6238]. +NPC id=3836, name=Kalphite Queen, level=333, option=[null, Attack, null, null, null], anims=[6236, 6236]. +NPC id=3837, name=Drunken Dwarf, level=0, option=[Talk-to, null, null, null, null], anims=[900, 104]. +NPC id=3838, name=Wise Old Man, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=3839, name=Wise Old Man, level=0, option=[null, null, null, null, null], anims=[3970, -1]. +NPC id=3840, name=Sea troll, level=79, option=[null, Attack, null, null, null], anims=[3987, 3984]. +NPC id=3841, name=Sea troll, level=65, option=[null, Attack, null, null, null], anims=[3987, 3984]. +NPC id=3842, name=Sea troll, level=87, option=[null, Attack, null, null, null], anims=[3987, 3984]. +NPC id=3843, name=Sea troll, level=101, option=[null, Attack, null, null, null], anims=[3987, 3984]. +NPC id=3844, name=Skeleton Mage, level=64, option=[null, null, null, null, null], anims=[5483, 5479]. +NPC id=3845, name=Sea troll, level=58, option=[null, null, null, null, null], anims=[3987, 3984]. +NPC id=3846, name=Sea Troll General, level=0, option=[null, null, null, null, null], anims=[3978, 3977]. +NPC id=3847, name=Sea Troll Queen, level=170, option=[null, Attack, null, null, null], anims=[3989, -1]. +NPC id=3848, name=Fishing spot, level=0, option=[Harpoon, null, Net, hidden, hidden], anims=[447, 448]. +NPC id=3849, name=Fishing spot, level=0, option=[Harpoon, null, Net, hidden, hidden], anims=[456, -1]. +NPC id=3850, name=Skeleton Mage, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=3851, name=Skeleton Mage, level=83, option=[null, Attack, null, null, null], anims=[5483, 5479]. +NPC id=3852, name=Suspect, level=0, option=[Grab, null, null, null, null], anims=[808, -1]. +NPC id=3853, name=Suspect, level=0, option=[Grab, null, null, null, null], anims=[808, -1]. +NPC id=3854, name=Suspect, level=0, option=[Grab, null, null, null, null], anims=[808, -1]. +NPC id=3855, name=Suspect, level=0, option=[Grab, null, null, null, null], anims=[808, -1]. +NPC id=3856, name=Suspect, level=0, option=[Grab, null, null, null, null], anims=[808, -1]. +NPC id=3857, name=Suspect, level=0, option=[Grab, null, null, null, null], anims=[808, -1]. +NPC id=3858, name=Suspect, level=0, option=[Grab, null, null, null, null], anims=[808, -1]. +NPC id=3859, name=Suspect, level=0, option=[Grab, null, null, null, null], anims=[808, -1]. +NPC id=3860, name=Suspect, level=0, option=[Grab, null, null, null, null], anims=[808, -1]. +NPC id=3861, name=Suspect, level=0, option=[Grab, null, null, null, null], anims=[808, -1]. +NPC id=3862, name=Suspect, level=0, option=[Grab, null, null, null, null], anims=[808, -1]. +NPC id=3863, name=Suspect, level=0, option=[Grab, null, null, null, null], anims=[808, -1]. +NPC id=3864, name=Suspect, level=0, option=[Grab, null, null, null, null], anims=[808, -1]. +NPC id=3865, name=Suspect, level=0, option=[Grab, null, null, null, null], anims=[808, -1]. +NPC id=3866, name=Suspect, level=0, option=[Grab, null, null, null, null], anims=[808, -1]. +NPC id=3867, name=Suspect, level=0, option=[Grab, null, null, null, null], anims=[808, -1]. +NPC id=3868, name=Suspect, level=0, option=[Grab, null, null, null, null], anims=[808, -1]. +NPC id=3869, name=Suspect, level=0, option=[Grab, null, null, null, null], anims=[808, -1]. +NPC id=3870, name=Suspect, level=0, option=[Grab, null, null, null, null], anims=[808, -1]. +NPC id=3871, name=Suspect, level=0, option=[Grab, null, null, null, null], anims=[808, -1]. +NPC id=3872, name=Suspect, level=0, option=[null, null, null, null, null], anims=[3999, 3999]. +NPC id=3873, name=Suspect, level=0, option=[null, null, null, null, null], anims=[3999, 3999]. +NPC id=3874, name=Suspect, level=0, option=[null, null, null, null, null], anims=[3999, 3999]. +NPC id=3875, name=Suspect, level=0, option=[null, null, null, null, null], anims=[3999, 3999]. +NPC id=3876, name=Suspect, level=0, option=[null, null, null, null, null], anims=[3999, 3999]. +NPC id=3877, name=Suspect, level=0, option=[null, null, null, null, null], anims=[3999, 3999]. +NPC id=3878, name=Suspect, level=0, option=[null, null, null, null, null], anims=[3999, 3999]. +NPC id=3879, name=Suspect, level=0, option=[null, null, null, null, null], anims=[3999, 3999]. +NPC id=3880, name=Suspect, level=0, option=[null, null, null, null, null], anims=[3999, 3999]. +NPC id=3881, name=Suspect, level=0, option=[null, null, null, null, null], anims=[3999, 3999]. +NPC id=3882, name=Suspect, level=0, option=[null, null, null, null, null], anims=[3999, 3999]. +NPC id=3883, name=Suspect, level=0, option=[null, null, null, null, null], anims=[3999, 3999]. +NPC id=3884, name=Suspect, level=0, option=[null, null, null, null, null], anims=[3999, 3999]. +NPC id=3885, name=Suspect, level=0, option=[null, null, null, null, null], anims=[3999, 3999]. +NPC id=3886, name=Suspect, level=0, option=[null, null, null, null, null], anims=[3999, 3999]. +NPC id=3887, name=Suspect, level=0, option=[null, null, null, null, null], anims=[3999, 3999]. +NPC id=3888, name=Suspect, level=0, option=[null, null, null, null, null], anims=[3999, 3999]. +NPC id=3889, name=Suspect, level=0, option=[null, null, null, null, null], anims=[3999, 3999]. +NPC id=3890, name=Suspect, level=0, option=[null, null, null, null, null], anims=[3999, 3999]. +NPC id=3891, name=Suspect, level=0, option=[null, null, null, null, null], anims=[3999, 3999]. +NPC id=3892, name=Molly, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3893, name=Molly, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3894, name=Molly, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3895, name=Molly, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3896, name=Molly, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3897, name=Molly, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3898, name=Molly, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3899, name=Molly, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3900, name=Molly, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3901, name=Molly, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3902, name=Molly, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3903, name=Molly, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3904, name=Molly, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3905, name=Molly, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3906, name=Molly, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3907, name=Molly, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3908, name=Molly, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3909, name=Molly, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3910, name=Molly, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3911, name=Molly, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3912, name=Flippa, level=0, option=[Talk-To, null, null, null, null], anims=[4010, 1139]. +NPC id=3913, name=Tilt, level=0, option=[Talk-To, null, null, null, null], anims=[4009, 1139]. +NPC id=3914, name=Gardener, level=4, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=3915, name=Man, level=2, option=[Talk-to, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=3916, name=Carpenter Kjallak, level=0, option=[Talk-to, null, null, null, null], anims=[1365, -1]. +NPC id=3917, name=Farmer Fromund, level=0, option=[Talk-to, null, null, null, null], anims=[2273, -1]. +NPC id=3918, name=Prince Brand, level=0, option=[null, null, null, null, null], anims=[1321, -1]. +NPC id=3919, name=Princess Astrid, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=3920, name=Runa, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=3921, name=Halla, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=3922, name=Finn, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=3923, name=Osvald, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=3924, name=Runolf, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3925, name=Tjorvi, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3926, name=Ingrid, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3927, name=Thora, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3928, name=Signy, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3929, name=Hild, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3930, name=Armod, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3931, name=Beigarth, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3932, name=Reinn, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3933, name=Alviss, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=3934, name=Fullangr, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=3935, name=Jari, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=3936, name=Thorodin, level=0, option=[Talk-to, null, null, null, null], anims=[4021, 98]. +NPC id=3937, name=Ferd, level=0, option=[Talk-to, null, null, null, null], anims=[4021, 98]. +NPC id=3938, name=Donal, level=0, option=[Talk-to, null, null, null, null], anims=[-1, 98]. +NPC id=3939, name=Sea Snake Young, level=90, option=[null, Attack, null, null, null], anims=[3535, 3537]. +NPC id=3940, name=Sea Snake Hatchling, level=62, option=[null, Attack, null, null, null], anims=[3535, 3537]. +NPC id=3941, name=Guard, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3942, name=Guard, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=3943, name=Giant Sea Snake, level=149, option=[null, Attack, null, null, null], anims=[4037, 4037]. +NPC id=3944, name=Hangman game, level=0, option=[Guess-letter, null, Banish, null, null], anims=[-1, -1]. +NPC id=3945, name=Hangman game, level=0, option=[Guess-letter, null, Banish, null, null], anims=[-1, -1]. +NPC id=3946, name=Hangman game, level=0, option=[Guess-letter, null, Banish, null, null], anims=[-1, -1]. +NPC id=3947, name=Hangman game, level=0, option=[Guess-letter, null, Banish, null, null], anims=[-1, -1]. +NPC id=3948, name=Hangman game, level=0, option=[Guess-letter, null, Banish, null, null], anims=[-1, -1]. +NPC id=3949, name=Hangman game, level=0, option=[Guess-letter, null, Banish, null, null], anims=[-1, -1]. +NPC id=3950, name=Hangman game, level=0, option=[Guess-letter, null, Banish, null, null], anims=[-1, -1]. +NPC id=3951, name=Hangman game, level=0, option=[Guess-letter, null, Banish, null, null], anims=[-1, -1]. +NPC id=3952, name=Hangman game, level=0, option=[Guess-letter, null, Banish, null, null], anims=[-1, -1]. +NPC id=3953, name=Hangman game, level=0, option=[Reset, null, Banish, null, null], anims=[-1, -1]. +NPC id=3954, name=Treasure fairy, level=0, option=[null, null, null, null, null], anims=[112, 106]. +NPC id=3955, name=Jacky Jester, level=0, option=[Banish, null, null, null, null], anims=[808, -1]. +NPC id=3956, name=Combat stone, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=3957, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=3958, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=3959, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=3960, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=3961, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=3962, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=3963, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=3964, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=3965, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=3966, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=3967, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=3968, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=3969, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=3970, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=3971, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=3972, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=3973, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=3974, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=3975, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=3976, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=3977, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=3978, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=3979, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=3980, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=3981, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=3982, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=3983, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=3984, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=3985, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=3986, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=3987, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=3988, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=3989, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=3990, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=3991, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=3992, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=3993, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=3994, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=3995, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=3996, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=3997, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=3998, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=3999, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4000, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4001, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4002, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4003, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4004, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4005, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4006, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4007, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4008, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4009, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4010, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4011, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4012, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4013, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4014, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4015, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4016, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4017, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4018, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4019, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4020, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4021, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4022, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4023, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4024, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4025, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4026, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4027, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4028, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4029, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4030, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4031, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4032, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4033, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4034, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4035, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4036, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4037, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4038, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4039, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4040, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4041, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4042, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4043, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4044, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4045, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4046, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4047, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4048, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4049, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4050, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4051, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4052, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4053, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4054, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4055, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4056, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4057, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4058, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4059, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4060, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4061, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4062, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4063, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4064, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4065, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4066, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4067, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4068, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4069, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4070, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4071, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4072, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4073, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4074, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4075, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4076, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4077, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4078, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4079, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4080, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4081, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4082, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4083, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4084, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4085, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4086, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4087, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4088, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4089, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4090, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4091, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4092, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4093, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4094, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4095, name=Elemental balance, level=0, option=[null, Banish, null, null, null], anims=[3584, -1]. +NPC id=4096, name=Combat stone, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=4097, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4098, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4099, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4100, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4101, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4102, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4103, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4104, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4105, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4106, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4107, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4108, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4109, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4110, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4111, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4112, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4113, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4114, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4115, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4116, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4117, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4118, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4119, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4120, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4121, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4122, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4123, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4124, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4125, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4126, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4127, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4128, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4129, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4130, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4131, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4132, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4133, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4134, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4135, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4136, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4137, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4138, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4139, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4140, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4141, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4142, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4143, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4144, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4145, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4146, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4147, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4148, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4149, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4150, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4151, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4152, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4153, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4154, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4155, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4156, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4157, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4158, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4159, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4160, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4161, name=Combat stone, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=4162, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4163, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4164, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4165, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4166, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4167, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4168, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4169, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4170, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4171, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4172, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4173, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4174, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4175, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4176, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4177, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4178, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4179, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4180, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4181, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4182, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4183, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4184, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4185, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4186, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4187, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4188, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4189, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4190, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4191, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4192, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4193, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4194, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4195, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4196, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4197, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4198, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4199, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4200, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4201, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4202, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4203, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4204, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4205, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4206, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4207, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4208, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4209, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4210, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4211, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4212, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4213, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4214, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4215, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4216, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4217, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4218, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4219, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4220, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4221, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4222, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4223, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4224, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4225, name=Combat stone, level=0, option=[Hit, null, null, null, null], anims=[-1, -1]. +NPC id=4226, name=Crawling hand, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=4227, name=Cockatrice, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=4228, name=Basilisk, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=4229, name=Kurask, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=4230, name=Abyssal demon, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=4231, name=Left head, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=4232, name=Middle head, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=4233, name=Right head, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=4234, name=Kalphite Queen, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=4235, name=Rick, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC (wrapper) id=4236, child npcs=[4235, -1, 4235, 4235, 4235, 4235, 4235, 4235, 4235, -1]. +NPC id=4237, name=Maid, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC (wrapper) id=4238, child npcs=[4237, 4237, 4237, -1, 4237, 4237, 4237, 4237, 4237, -1]. +NPC id=4239, name=Cook, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC (wrapper) id=4240, child npcs=[4239, 4239, 4239, 4239, 4239, -1, 4239, 4239, 4239, -1]. +NPC id=4241, name=Butler, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC (wrapper) id=4242, child npcs=[4241, 4241, 4241, 4241, 4241, 4241, -1, 4241, 4241, -1]. +NPC id=4243, name=Demon butler, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC (wrapper) id=4244, child npcs=[4243, 4243, 4243, 4243, 4243, 4243, 4243, 4243, -1]. +NPC id=4245, name=Chief servant, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4246, name=Taxidermist, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4247, name=Estate agent, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4248, name=Stonemason, level=0, option=[Talk-to, null, Trade, null, null], anims=[101, 98]. +NPC id=4249, name=Sir Renitee, level=0, option=[Talk-to, null, null, null, null], anims=[3719, -1]. +NPC id=4250, name=Sawmill operator, level=0, option=[Talk-to, null, Buy-plank, Trade, null], anims=[808, -1]. +NPC id=4251, name=Garden supplier, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=4252, name=Macaroni Penguin, level=0, option=[null, null, null, null, null], anims=[5668, 5666]. +NPC id=4253, name=null, level=1, option=[null, null, null, null, null], anims=[5335, -1]. +NPC id=4254, name=null, level=1, option=[null, null, null, null, null], anims=[5335, -1]. +NPC id=4255, name=null, level=1, option=[null, null, null, null, null], anims=[5335, -1]. +NPC id=4256, name=null, level=1, option=[null, null, null, null, null], anims=[5335, -1]. +NPC id=4257, name=Guard, level=10, option=[Talk-to, Attack, null, null, null], anims=[101, 98]. +NPC id=4258, name=Guard, level=10, option=[Talk-to, Attack, null, null, null], anims=[101, 98]. +NPC id=4259, name=Guard, level=10, option=[Talk-to, Attack, null, null, null], anims=[101, 98]. +NPC id=4260, name=Guard, level=10, option=[Talk-to, Attack, null, null, null], anims=[101, 98]. +NPC id=4261, name=Goblin, level=2, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=4262, name=Goblin, level=2, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=4263, name=Goblin, level=2, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=4264, name=Goblin, level=2, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=4265, name=Goblin, level=2, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=4266, name=Goblin, level=2, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=4267, name=Goblin, level=2, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=4268, name=Goblin, level=2, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=4269, name=Goblin, level=2, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=4270, name=Goblin, level=2, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=4271, name=Goblin, level=2, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=4272, name=Goblin, level=2, option=[null, Attack, null, null, null], anims=[6186, 6187]. +NPC id=4273, name=Goblin, level=2, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=4274, name=Goblin, level=2, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=4275, name=Goblin, level=2, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=4276, name=Goblin, level=2, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=4277, name=Buinn, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=4278, name=Animated Bronze Armour, level=11, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=4279, name=Animated Iron Armour, level=23, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=4280, name=Animated Steel Armour, level=46, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=4281, name=Animated Black Armour, level=69, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=4282, name=Animated Mithril Armour, level=92, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=4283, name=Animated Adamant Armour, level=113, option=[null, Attack, null, null, null], anims=[2065, 2064]. +NPC id=4284, name=Animated Rune Armour, level=138, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=4285, name=Ghommal, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4286, name=Harrallak Menarous, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4287, name=Gamfred, level=0, option=[Talk-to, null, Claim-Tokens, Claim-Shield, null], anims=[101, 98]. +NPC id=4288, name=Ajjat, level=0, option=[Talk-to, null, Claim-Tokens, null, null], anims=[2065, 2064]. +NPC id=4289, name=Kamfreena, level=0, option=[Talk-to, null, Claim-Tokens, null, null], anims=[2065, 2064]. +NPC id=4290, name=Shanomi, level=0, option=[Talk-to, null, Claim-Tokens, null, null], anims=[2561, 2562]. +NPC id=4291, name=Cyclops, level=56, option=[null, Attack, null, null, null], anims=[4650, 4649]. +NPC id=4292, name=Cyclops, level=76, option=[null, Attack, null, null, null], anims=[4650, 4649]. +NPC id=4293, name=Lidio, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=4294, name=Lilly, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=4295, name=Anton, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=4296, name=Jade, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[808, 808]. +NPC id=4297, name=Sloane, level=0, option=[Talk-to, null, Claim-Tokens, null, null], anims=[808, -1]. +NPC id=4298, name=Jimmy, level=0, option=[Talk-to, null, null, null, null], anims=[2770, 2769]. +NPC id=4299, name=Ref, level=0, option=[Talk-to, null, Claim-Tokens, null, null], anims=[808, -1]. +NPC id=4300, name=Ref, level=0, option=[Talk-to, null, Claim-Tokens, null, null], anims=[808, -1]. +NPC id=4301, name=Guard, level=22, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4302, name=Guard, level=22, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4303, name=Guard, level=22, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4304, name=Guard, level=22, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4305, name=Guard, level=22, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4306, name=Guard, level=22, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=4307, name=Guard, level=22, option=[Talk-to, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=4308, name=Guard, level=22, option=[Talk-to, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=4309, name=Guard, level=22, option=[Talk-to, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=4310, name=Guard, level=22, option=[Talk-to, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=4311, name=Guard, level=22, option=[Talk-to, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=4312, name=Nardok, level=0, option=[Talk-to, null, Trade, null, null], anims=[4210, -1]. +NPC id=4313, name=null, level=1, option=[null, null, null, null, null], anims=[6040, 6041]. +NPC id=4314, name=Dartog, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=4315, name=null, level=1, option=[null, null, null, null, null], anims=[101, 98]. +NPC id=4316, name=Dwarf, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=4317, name=null, level=1, option=[null, null, null, null, null], anims=[4193, 4194]. +NPC id=4318, name=H.A.M. Member, level=0, option=[Talk-to, null, null, null, null], anims=[4193, 4194]. +NPC id=4319, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=4320, name=H.A.M. Member, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4321, name=null, level=1, option=[null, null, null, null, null], anims=[4193, 4194]. +NPC id=4322, name=Zanik, level=0, option=[null, null, null, null, null], anims=[6040, 6041]. +NPC id=4323, name=Zanik, level=0, option=[null, null, null, null, null], anims=[5994, 5995]. +NPC id=4324, name=Zanik, level=0, option=[null, null, null, null, null], anims=[6040, 6041]. +NPC id=4325, name=Light creature, level=0, option=[null, null, null, null, null], anims=[2051, 2051]. +NPC id=4326, name=Zanik, level=0, option=[null, null, null, null, null], anims=[6040, 6041]. +NPC id=4327, name=HAM member, level=22, option=[null, null, null, null, null], anims=[4208, -1]. +NPC id=4328, name=Sigmund, level=0, option=[null, null, null, null, null], anims=[4208, -1]. +NPC id=4329, name=H.A.M. Deacon, level=0, option=[null, null, null, null, null], anims=[4208, -1]. +NPC id=4330, name=Johanhus Ulsbrecht, level=0, option=[null, null, null, null, null], anims=[4208, -1]. +NPC id=4331, name=Sigmund, level=0, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=4332, name=Sigmund, level=50, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=4333, name=Sigmund, level=50, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=4334, name=Sigmund, level=50, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=4335, name=Sigmund, level=50, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=4336, name=Guard, level=22, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=4337, name=Zanik, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=4338, name=null, level=1, option=[null, null, null, null, null], anims=[6040, 6041]. +NPC id=4339, name=Zanik, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=4340, name=Zanik, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=4341, name=Zanik, level=0, option=[Talk-to, null, null, null, null], anims=[6040, -1]. +NPC id=4342, name=Zanik, level=41, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=4343, name=Snake, level=35, option=[null, Attack, null, null, null], anims=[277, 274]. +NPC id=4344, name=Monkey, level=3, option=[Talk-To, Attack, null, null, null], anims=[222, 219]. +NPC id=4345, name=Albino bat, level=52, option=[null, Attack, null, null, null], anims=[4914, 4913]. +NPC id=4346, name=Crab, level=0, option=[null, null, null, null, null], anims=[3424, 3426]. +NPC id=4347, name=Giant mosquito, level=13, option=[null, Attack, null, null, null], anims=[2395, 2396]. +NPC id=4348, name=Jungle horror, level=70, option=[null, Attack, null, null, null], anims=[4231, 4236]. +NPC id=4349, name=Jungle horror, level=70, option=[null, Attack, null, null, null], anims=[4231, 4236]. +NPC id=4350, name=Jungle horror, level=70, option=[null, Attack, null, null, null], anims=[4231, 4236]. +NPC id=4351, name=Jungle horror, level=70, option=[null, Attack, null, null, null], anims=[4231, 4236]. +NPC id=4352, name=Jungle horror, level=70, option=[null, Attack, null, null, null], anims=[4231, 4236]. +NPC id=4353, name=Cave horror, level=80, option=[null, Attack, null, null, null], anims=[4231, 4236]. +NPC id=4354, name=Cave horror, level=80, option=[null, Attack, null, null, null], anims=[4231, 4236]. +NPC id=4355, name=Cave horror, level=80, option=[null, Attack, null, null, null], anims=[4231, 4236]. +NPC id=4356, name=Cave horror, level=80, option=[null, Attack, null, null, null], anims=[4231, 4236]. +NPC id=4357, name=Cave horror, level=80, option=[null, Attack, null, null, null], anims=[4231, 4236]. +NPC id=4358, name=Cavey Davey, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=4359, name=Patchy, level=0, option=[Talk-to, null, Sew, null, null], anims=[808, -1]. +NPC id=4360, name=San Fan, level=0, option=[Talk-To, null, Join-Crew, null, null], anims=[808, -1]. +NPC id=4361, name=Fancy Dan, level=0, option=[Talk-To, null, Join-Crew, null, null], anims=[808, -1]. +NPC id=4362, name=Honest Jimmy, level=0, option=[Talk-To, null, Trade, Join-Team, null], anims=[4257, 4256]. +NPC id=4363, name=Monkey, level=0, option=[Catch, null, Talk-To, null, null], anims=[222, 219]. +NPC id=4364, name=Swarm, level=0, option=[null, null, null, null, null], anims=[0, 0]. +NPC id=4365, name=null, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=4366, name=null, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=4367, name=null, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=4368, name=null, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=4369, name=null, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=4370, name=null, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=4371, name=Blue Monkey, level=1, option=[null, null, null, null, null], anims=[1386, 1380]. +NPC id=4372, name=Red Monkey, level=1, option=[null, null, null, null, null], anims=[1386, 1380]. +NPC id=4373, name=Parrot, level=0, option=[Talk-To, null, null, null, null], anims=[4259, -1]. +NPC id=4374, name=Parrot, level=0, option=[Talk-To, null, null, null, null], anims=[4259, -1]. +NPC id=4375, name=Security Guard, level=0, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=4376, name=Litara, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=4377, name=Gate of War, level=1, option=[talk, null, null, null, null], anims=[-1, -1]. +NPC id=4378, name=Ricketty door, level=1, option=[talk, null, null, null, null], anims=[-1, -1]. +NPC id=4379, name=Oozing barrier, level=1, option=[talk, null, null, null, null], anims=[-1, -1]. +NPC id=4380, name=Portal of Death, level=1, option=[talk, null, null, null, null], anims=[-1, -1]. +NPC id=4381, name=Ankou, level=75, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=4382, name=Ankou, level=82, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=4383, name=Ankou, level=86, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=4384, name=Skeleton, level=68, option=[null, Attack, null, null, null], anims=[5483, 5481]. +NPC id=4385, name=Skeleton, level=60, option=[null, Attack, null, null, null], anims=[5483, 5479]. +NPC id=4386, name=Skeleton, level=85, option=[null, Attack, null, null, null], anims=[5483, 5481]. +NPC id=4387, name=Ghost, level=77, option=[null, Attack, null, null, null], anims=[5538, 5539]. +NPC id=4388, name=Ghost, level=76, option=[null, Attack, null, null, null], anims=[5530, 5531]. +NPC id=4389, name=Flesh Crawler, level=28, option=[null, Attack, null, null, null], anims=[1183, 1189]. +NPC id=4390, name=Flesh Crawler, level=35, option=[null, Attack, null, null, null], anims=[1183, 1189]. +NPC id=4391, name=Flesh Crawler, level=41, option=[null, Attack, null, null, null], anims=[1183, 1189]. +NPC id=4392, name=Zombie, level=30, option=[null, Attack, null, null, null], anims=[5565, -1]. +NPC id=4393, name=Zombie, level=44, option=[null, Attack, null, null, null], anims=[5572, -1]. +NPC id=4394, name=Zombie, level=53, option=[null, Attack, null, null, null], anims=[5576, -1]. +NPC id=4395, name=Giant rat, level=26, option=[null, Attack, null, null, null], anims=[4932, 4931]. +NPC id=4396, name=Rat, level=1, option=[null, Attack, null, null, null], anims=[2704, 2703]. +NPC id=4397, name=Catablepon, level=49, option=[null, Attack, null, null, null], anims=[4269, 4268]. +NPC id=4398, name=Catablepon, level=64, option=[null, Attack, null, null, null], anims=[4269, 4268]. +NPC id=4399, name=Catablepon, level=68, option=[null, Attack, null, null, null], anims=[4269, 4268]. +NPC id=4400, name=Giant spider, level=50, option=[null, Attack, null, null, null], anims=[5326, 5325]. +NPC id=4401, name=Spider, level=24, option=[null, Attack, null, null, null], anims=[6247, 6248]. +NPC id=4402, name=Scorpion, level=59, option=[null, Attack, null, null, null], anims=[6252, 6253]. +NPC id=4403, name=Scorpion, level=37, option=[null, Attack, null, null, null], anims=[6252, 6253]. +NPC id=4404, name=Minotaur, level=12, option=[null, Attack, null, null, null], anims=[4264, 4263]. +NPC id=4405, name=Minotaur, level=19, option=[null, Attack, null, null, null], anims=[4264, 4263]. +NPC id=4406, name=Minotaur, level=27, option=[null, Attack, null, null, null], anims=[4264, 4263]. +NPC id=4407, name=Goblin, level=5, option=[null, Attack, null, null, null], anims=[6186, 6187]. +NPC id=4408, name=Goblin, level=13, option=[null, Attack, null, null, null], anims=[6186, 6187]. +NPC id=4409, name=Goblin, level=11, option=[null, Attack, null, null, null], anims=[6186, 6187]. +NPC id=4410, name=Goblin, level=16, option=[null, Attack, null, null, null], anims=[6186, 6187]. +NPC id=4411, name=Goblin, level=25, option=[null, Attack, null, null, null], anims=[6186, 6187]. +NPC id=4412, name=Goblin, level=16, option=[null, Attack, null, null, null], anims=[6186, 6187]. +NPC id=4413, name=Wolf, level=14, option=[null, Attack, null, null, null], anims=[6580, 6556]. +NPC id=4414, name=Wolf, level=11, option=[null, Attack, null, null, null], anims=[6580, 6556]. +NPC id=4415, name=Rat, level=1, option=[null, Attack, null, null, null], anims=[2704, 2703]. +NPC id=4416, name=Bee keeper, level=0, option=[Talk-To, null, null, null, null], anims=[808, -1]. +NPC id=4417, name=Bees!, level=0, option=[null, null, null, null, null], anims=[0, 0]. +NPC id=4418, name=Gorak, level=145, option=[null, Attack, null, null, null], anims=[4299, 4298]. +NPC id=4419, name=Cosmic Being, level=0, option=[Talk-to, null, null, null, null], anims=[4303, 4304]. +NPC id=4420, name=null, level=0, option=[null, null, null, null, null], anims=[663, 663]. +NPC id=4421, name=null, level=0, option=[null, null, null, null, null], anims=[663, 663]. +NPC (wrapper) id=4422, child npcs=[57, -1, -1, -1, -1, -1, -1, -1, -1, -1, 57, -1]. +NPC (wrapper) id=4423, child npcs=[57, -1, -1, -1, -1, -1, -1, -1, -1, -1, 57, -1, -1, -1, -1, -1, -1, -1, -1, -1, 57, -1, -1, -1, -1, -1, -1, -1, -1, -1, 57, -1]. +NPC id=4424, name=null, level=0, option=[Talk-to, null, null, null, null], anims=[4318, 4319]. +NPC id=4425, name=null, level=0, option=[Talk-to, null, null, null, null], anims=[4318, 4319]. +NPC id=4426, name=null, level=1, option=[null, null, null, null, null], anims=[112, 106]. +NPC id=4427, name=null, level=1, option=[null, null, null, null, null], anims=[112, 106]. +NPC id=4428, name=null, level=1, option=[null, null, null, null, null], anims=[112, 106]. +NPC id=4429, name=null, level=1, option=[null, null, null, null, null], anims=[112, 106]. +NPC id=4430, name=null, level=1, option=[null, null, null, null, null], anims=[112, 106]. +NPC (wrapper) id=4431, child npcs=[4434, -1]. +NPC id=4432, name=null, level=1, option=[null, null, null, null, null], anims=[112, 106]. +NPC id=4433, name=Fairy Godfather, level=0, option=[Talk-to, null, Pick-pocket, null, null], anims=[-1, -1]. +NPC id=4434, name=Fairy Nuff, level=0, option=[Talk-to, null, null, null, null], anims=[112, 106]. +NPC id=4435, name=null, level=1, option=[null, null, null, null, null], anims=[112, 106]. +NPC id=4436, name=null, level=1, option=[null, null, null, null, null], anims=[112, 106]. +NPC id=4437, name=Fairy Queen, level=0, option=[Talk-to, null, null, null, null], anims=[112, 106]. +NPC id=4438, name=Centaur, level=0, option=[Talk-to, null, null, null, null], anims=[4311, 4310]. +NPC id=4439, name=Centaur, level=0, option=[Talk-to, null, null, null, null], anims=[4311, 4310]. +NPC id=4440, name=Stag, level=15, option=[null, Attack, null, null, null], anims=[6374, 6373]. +NPC id=4441, name=Wood Dryad, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4442, name=Fairy Very Wise, level=0, option=[Talk-to, null, null, null, null], anims=[112, 106]. +NPC id=4443, name=Fairy, level=0, option=[Talk-to, null, null, null, null], anims=[112, 106]. +NPC id=4444, name=Fairy, level=0, option=[Talk-to, null, null, null, null], anims=[112, 106]. +NPC id=4445, name=Fairy, level=0, option=[Talk-to, null, null, null, null], anims=[112, 106]. +NPC id=4446, name=Fairy, level=0, option=[Talk-to, null, null, null, null], anims=[112, 106]. +NPC id=4447, name=Rabbit, level=1, option=[null, Attack, null, null, null], anims=[6089, 6088]. +NPC id=4448, name=Rabbit, level=1, option=[null, Attack, null, null, null], anims=[6089, 6088]. +NPC id=4449, name=Butterfly, level=0, option=[null, null, null, null, null], anims=[362, 362]. +NPC id=4450, name=Butterfly, level=0, option=[null, null, null, null, null], anims=[362, 362]. +NPC id=4451, name=Starflower, level=0, option=[null, null, null, null, null], anims=[4314, -1]. +NPC id=4452, name=Starflower, level=0, option=[Pick, null, null, null, null], anims=[4315, -1]. +NPC id=4453, name=null, level=1, option=[null, null, null, null, null], anims=[112, 106]. +NPC id=4454, name=null, level=1, option=[null, null, null, null, null], anims=[112, 106]. +NPC id=4455, name=Fairy Fixit, level=0, option=[Talk-to, null, null, null, null], anims=[112, 106]. +NPC id=4456, name=Ork, level=0, option=[Talk-to, null, null, null, null], anims=[4318, 4319]. +NPC id=4457, name=Ork, level=0, option=[Talk-to, null, null, null, null], anims=[4318, 4319]. +NPC id=4458, name=Ork, level=20, option=[Talk-to, null, null, null, null], anims=[4318, 4319]. +NPC id=4459, name=Ork, level=20, option=[Talk-to, null, null, null, null], anims=[4318, 4319]. +NPC id=4460, name=Fake Man, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=4461, name=Held vampyre juvinate, level=90, option=[null, Attack, null, null, null], anims=[3551, -1]. +NPC id=4462, name=Held vampyre juvinate, level=119, option=[null, Attack, null, null, null], anims=[3551, -1]. +NPC id=4463, name=Angry juvinate, level=70, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=4464, name=Angry juvinate, level=100, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=4465, name=Angry juvinate, level=130, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=4466, name=Benjamin, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4467, name=Liam, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4468, name=Miala, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4469, name=Verak, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4470, name=Tree spirit, level=14, option=[null, Attack, null, null, null], anims=[96, 93]. +NPC id=4471, name=Tree spirit, level=29, option=[null, Attack, null, null, null], anims=[96, 93]. +NPC id=4472, name=Tree spirit, level=49, option=[null, Attack, null, null, null], anims=[96, 93]. +NPC id=4473, name=Tree spirit, level=79, option=[null, Attack, null, null, null], anims=[96, 93]. +NPC id=4474, name=Tree spirit, level=120, option=[null, Attack, null, null, null], anims=[96, 93]. +NPC id=4475, name=Tree spirit, level=159, option=[null, Attack, null, null, null], anims=[96, 93]. +NPC id=4476, name=Guardian mummy, level=0, option=[Talk-to, null, Start-minigame, null, null], anims=[5558, 5557]. +NPC id=4477, name=Annoyed guardian mummy, level=0, option=[null, null, null, null, null], anims=[5558, 5557]. +NPC id=4478, name=Tarik, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4479, name=Goblin, level=5, option=[Talk-to, Attack, null, null, null], anims=[6181, 6180]. +NPC id=4480, name=Goblin, level=5, option=[Talk-to, Attack, null, null, null], anims=[6186, 6187]. +NPC id=4481, name=Goblin, level=5, option=[Talk-to, Attack, null, null, null], anims=[6181, 6180]. +NPC id=4482, name=Goblin, level=5, option=[Talk-to, Attack, null, null, null], anims=[6200, 6201]. +NPC id=4483, name=Goblin, level=5, option=[Talk-to, Attack, null, null, null], anims=[6181, 6180]. +NPC id=4484, name=Goblin, level=5, option=[Talk-to, Attack, null, null, null], anims=[6186, 6187]. +NPC id=4485, name=Goblin, level=5, option=[Talk-to, Attack, null, null, null], anims=[6186, 6187]. +NPC id=4486, name=Goblin, level=5, option=[Talk-to, Attack, null, null, null], anims=[6181, 6180]. +NPC id=4487, name=Goblin, level=5, option=[Talk-to, Attack, null, null, null], anims=[6186, 6187]. +NPC id=4488, name=Goblin, level=5, option=[Talk-to, Attack, null, null, null], anims=[6181, 6180]. +NPC id=4489, name=Goblin, level=5, option=[Talk-to, Attack, null, null, null], anims=[6200, 6201]. +NPC id=4490, name=Goblin, level=5, option=[Talk-to, Attack, null, null, null], anims=[6181, 6180]. +NPC id=4491, name=Goblin, level=5, option=[Talk-to, Attack, null, null, null], anims=[6186, 6187]. +NPC id=4492, name=Goblin, level=5, option=[Talk-to, Attack, null, null, null], anims=[6186, 6187]. +NPC id=4493, name=General Bentnoze, level=0, option=[Talk-to, null, null, null, null], anims=[6203, 6202]. +NPC id=4494, name=General Wartface, level=0, option=[Talk-to, null, null, null, null], anims=[6203, 6202]. +NPC (wrapper) id=4495, child npcs=[4496, 4496, 4496, 4496, 4497, 4498, 4496, -1]. +NPC id=4496, name=Grubfoot, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=4497, name=Grubfoot, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=4498, name=Grubfoot, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=4499, name=Goblin, level=5, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=4500, name=Scarab swarm, level=98, option=[null, Attack, null, null, null], anims=[1947, 1945]. +NPC id=4501, name=Ethereal Man, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=4502, name=Ethereal Lady, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=4503, name=Ethereal Numerator, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=4504, name=Ethereal Expert, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=4505, name=Ethereal Perceptive, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=4506, name=Ethereal Guide, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=4507, name=Ethereal Fluke, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=4508, name=Ethereal Mimic, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4509, name=Me, level=79, option=[null, Attack, null, null, null], anims=[813, -1]. +NPC id=4510, name=Me, level=79, option=[null, Attack, null, null, null], anims=[813, -1]. +NPC id=4511, name=Oneiromancer, level=0, option=[Talk-to, null, null, null, null], anims=[4424, -1]. +NPC id=4512, name=House, level=0, option=[Go-inside, null, null, null, null], anims=[4391, 4390]. +NPC id=4513, name=Baba Yaga, level=0, option=[Talk-to, null, Trade, null, null], anims=[4424, -1]. +NPC id=4514, name=Pauline Polaris, level=0, option=[Talk-to, null, null, null, null], anims=[4424, -1]. +NPC id=4515, name=Meteora, level=0, option=[Talk-to, null, null, null, null], anims=[4424, -1]. +NPC id=4516, name=Melana Moonlander, level=0, option=[Talk-to, null, Trade, null, null], anims=[4424, -1]. +NPC id=4517, name=Selene, level=0, option=[Talk-to, null, null, null, null], anims=[4424, -1]. +NPC id=4518, name=Rimae Sirsalis, level=0, option=[Talk-to, null, Trade, null, null], anims=[4424, -1]. +NPC id=4519, name=Sirsal Banker, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[4424, 4424]. +NPC id=4520, name=Clan Guard, level=0, option=[null, null, null, null, null], anims=[4424, -1]. +NPC id=4521, name=Enchanted Broom, level=0, option=[null, null, null, null, null], anims=[4372, 4372]. +NPC id=4522, name=Enchanted Broom, level=0, option=[null, null, null, null, null], anims=[4372, 4372]. +NPC id=4523, name=Enchanted Broom, level=0, option=[null, null, null, null, null], anims=[4372, 4372]. +NPC id=4524, name=Enchanted Bucket, level=0, option=[null, null, null, null, null], anims=[4374, 4374]. +NPC id=4525, name=Enchanted Bucket, level=0, option=[null, null, null, null, null], anims=[4374, 4374]. +NPC id=4526, name=Bouquet Mac Hyacinth, level=0, option=[Talk-to, null, null, null, null], anims=[4424, -1]. +NPC id=4527, name=Suqah, level=111, option=[null, Attack, null, null, null], anims=[4386, 4383]. +NPC id=4528, name=Suqah, level=111, option=[null, Attack, null, null, null], anims=[4386, 4383]. +NPC id=4529, name=Suqah, level=111, option=[null, Attack, null, null, null], anims=[4386, 4383]. +NPC id=4530, name=Suqah, level=111, option=[null, Attack, null, null, null], anims=[4386, 4383]. +NPC id=4531, name=Suqah, level=111, option=[null, Attack, null, null, null], anims=[4386, 4383]. +NPC id=4532, name=Suqah, level=111, option=[null, Attack, null, null, null], anims=[4386, 4383]. +NPC id=4533, name=Suqah, level=111, option=[null, Attack, null, null, null], anims=[4386, 4383]. +NPC id=4534, name=Moss giant, level=48, option=[null, Attack, null, null, null], anims=[4656, 4655]. +NPC id=4535, name=Parrot, level=1, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=4536, name=Lokar Searunner, level=0, option=[ gTalk-to, null, null, null, null], anims=[7188, -1]. +NPC id=4537, name=Lokar Searunner, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC (wrapper) id=4538, child npcs=[4539, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4539, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4539, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4539, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4539, -1, -1, -1, -1, 4539, -1, -1, -1, -1, 4539, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4539, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4539, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4539, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4539, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4539, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4539, -1, 4539, -1, 4539, -1, 4539, -1, 4539, -1, 4539, -1, -1, -1, -1, 4539, -1]. +NPC id=4539, name=Cabin boy, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=4540, name=Captain Bentley, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=4541, name='Beefy' Burns, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=4542, name='Eagle-eye' Shultz, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=4543, name=First mate 'Davey-boy', level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=4544, name='Bird's-Eye' Jack, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=4545, name='Picarron' Pete, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=4546, name=Jake, level=37, option=[null, Attack, null, null, null], anims=[7188, -1]. +NPC id=4547, name=Bedread the bold, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=4548, name=Wilson, level=37, option=[null, Attack, null, null, null], anims=[7188, -1]. +NPC id=4549, name=Tommy 2-times, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=4550, name=Murky Pat, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=4551, name=Jack Sails, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=4552, name=Palmer, level=37, option=[null, Attack, null, null, null], anims=[7188, -1]. +NPC id=4553, name='Betty' B.Boppin, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=4554, name='Beedy-eye' Jones, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=4555, name=Jenny Blade, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=4556, name='Lecherous' Lee, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=4557, name='Sticky' Sanders, level=0, option=[Talk-to, null, null, null, null], anims=[7188, -1]. +NPC id=4558, name=Hirko, level=0, option=[Talk-to, null, Trade, null, null], anims=[101, 98]. +NPC id=4559, name=Holoy, level=0, option=[Talk-to, null, Trade, null, null], anims=[101, 98]. +NPC id=4560, name=Frizzy Skernip, level=0, option=[Talk-to, null, Pay, null, null], anims=[195, 189]. +NPC id=4561, name=Yulf Squecks, level=0, option=[Talk-to, null, Pay, null, null], anims=[195, 189]. +NPC id=4562, name=Praistan Ebola, level=0, option=[Talk-to, null, Pay, null, null], anims=[195, 189]. +NPC id=4563, name=Hura, level=0, option=[Talk-to, null, Trade, null, null], anims=[101, 98]. +NPC id=4564, name=Digsite workman, level=0, option=[Talk-to, null, Steal-from, null, null], anims=[808, -1]. +NPC id=4565, name=Digsite workman, level=0, option=[Talk-to, null, Steal-from, null, null], anims=[808, -1]. +NPC id=4566, name=Examiner, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4567, name=Examiner, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4568, name=Researcher, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4569, name=Nick, level=0, option=[null, null, null, null, null], anims=[4594, -1]. +NPC id=4570, name=Crow, level=0, option=[null, null, null, null, null], anims=[6786, 6784]. +NPC id=4571, name=Crow, level=0, option=[null, null, null, null, null], anims=[6787, 6784]. +NPC id=4572, name=Gianne jnr., level=0, option=[Talk-to, null, null, null, null], anims=[4536, -1]. +NPC id=4573, name=Timble, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=4574, name=Tamble, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=4575, name=Spang, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=4576, name=Brambickle, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=4577, name=Wingstone, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=4578, name=Penwie, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=4579, name=Generic Diplomat, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=4580, name=Ambassador Gimblewap, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=4581, name=Ambassador Spanfipple, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=4582, name=Ambassador Ferrnook, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=4583, name=Professor Manglethorp, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=4584, name=Damwin, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=4585, name=Professor Onglewip, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=4586, name=Professor Imblewyn, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=4587, name=Perrdur, level=0, option=[Talk-to, null, null, null, null], anims=[4538, -1]. +NPC id=4588, name=Dalila, level=0, option=[Talk-to, null, null, null, null], anims=[4537, -1]. +NPC id=4589, name=Sorrn, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=4590, name=Mimm, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=4591, name=Eebel, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=4592, name=Ermin, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=4593, name=Portobello, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=4594, name=Captain Ninto, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=4595, name=Captain Daerkin, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=4596, name=Captain Lamdoo, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=4597, name=Meegle, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=4598, name=Wurbel, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=4599, name=Sarble, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=4600, name=Guard Vemmeldo, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=4601, name=Burkor, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=4602, name=Froono, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=4603, name=Fortress Guard, level=20, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=4604, name=Fortress Guard, level=20, option=[Talk-to, Attack, null, null, null], anims=[813, -1]. +NPC id=4605, name=Fortress Guard, level=20, option=[Talk-to, Attack, null, null, null], anims=[813, -1]. +NPC id=4606, name=Fortress Guard, level=20, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=4607, name=Black Cat, level=0, option=[null, null, null, null, null], anims=[9158, 9157]. +NPC id=4608, name=Monk, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=4609, name=null, level=0, option=[null, null, null, null, null], anims=[195, 189]. +NPC id=4610, name=Brimstail, level=0, option=[null, null, null, null, null], anims=[195, 189]. +NPC id=4611, name=Saboteur, level=0, option=[null, null, null, null, null], anims=[1412, 189]. +NPC id=4612, name=Gnome shop keeper, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC (wrapper) id=4613, child npcs=[4614, 4615, 1957, -1]. +NPC id=4614, name=Cute creature, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=4615, name=Evil creature, level=0, option=[null, Attack, null, null, null], anims=[-1, -1]. +NPC (wrapper) id=4616, child npcs=[4617, 4618, 1957, -1]. +NPC id=4617, name=Cute creature, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=4618, name=Evil creature, level=0, option=[null, Attack, null, null, null], anims=[-1, -1]. +NPC (wrapper) id=4619, child npcs=[4620, 4621, 1957, -1]. +NPC id=4620, name=Cute creature, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=4621, name=Evil creature, level=0, option=[null, Attack, null, null, null], anims=[-1, -1]. +NPC (wrapper) id=4622, child npcs=[4623, 4624, 1957, -1]. +NPC id=4623, name=Cute creature, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=4624, name=Evil creature, level=0, option=[null, Attack, null, null, null], anims=[-1, -1]. +NPC (wrapper) id=4625, child npcs=[4626, 4627, 1957, -1]. +NPC id=4626, name=Cute creature, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=4627, name=Evil creature, level=0, option=[null, Attack, null, null, null], anims=[-1, -1]. +NPC (wrapper) id=4628, child npcs=[4629, 4630, 1957, -1]. +NPC id=4629, name=Cute creature, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=4630, name=Evil creature, level=0, option=[null, Attack, null, null, null], anims=[-1, -1]. +NPC id=4631, name=fluffie, level=0, option=[null, null, null, null, null], anims=[4472, 4473]. +NPC id=4632, name=fluffie, level=0, option=[null, null, null, null, null], anims=[4472, 4473]. +NPC id=4633, name=Goblin, level=0, option=[null, null, null, null, null], anims=[6140, 6141]. +NPC id=4634, name=Goblin, level=0, option=[null, null, null, null, null], anims=[6140, 6141]. +NPC id=4635, name=Goblin, level=0, option=[null, null, null, null, null], anims=[6140, 6141]. +NPC id=4636, name=Goblin, level=0, option=[null, null, null, null, null], anims=[6140, 6141]. +NPC id=4637, name=Goblin, level=0, option=[null, null, null, null, null], anims=[6140, 6141]. +NPC id=4638, name=Gnome soldier, level=0, option=[null, null, null, null, null], anims=[195, 189]. +NPC id=4639, name=Gnome soldier, level=0, option=[null, null, null, null, null], anims=[195, 189]. +NPC id=4640, name=Gnome soldier, level=0, option=[null, null, null, null, null], anims=[195, 189]. +NPC id=4641, name=Gnome soldier, level=0, option=[null, null, null, null, null], anims=[195, 189]. +NPC id=4642, name=Gnome soldier, level=0, option=[null, null, null, null, null], anims=[195, 189]. +NPC id=4643, name=Healthorg and tortoise, level=0, option=[null, null, null, null, null], anims=[3952, -1]. +NPC id=4644, name=Oaknock the Engineer, level=0, option=[null, null, null, null, null], anims=[195, 189]. +NPC id=4645, name=Glouphrie the Untrusted, level=0, option=[null, null, null, null, null], anims=[195, 189]. +NPC id=4646, name=King Healthorg, level=0, option=[null, null, null, null, null], anims=[195, 189]. +NPC id=4647, name=Hazelmere, level=0, option=[null, null, null, null, null], anims=[195, 189]. +NPC id=4648, name=Nisha, level=0, option=[null, null, null, null, null], anims=[4593, -1]. +NPC id=4649, name=Tyras guard, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=4650, name=Trader Stan, level=0, option=[Talk-To, null, Trade, Charter, null], anims=[808, -1]. +NPC id=4651, name=Trader Crewmember, level=0, option=[Talk-To, null, Trade, Charter, null], anims=[808, -1]. +NPC id=4652, name=Trader Crewmember, level=0, option=[Talk-To, null, Trade, Charter, null], anims=[808, -1]. +NPC id=4653, name=Trader Crewmember, level=0, option=[Talk-To, null, Trade, Charter, null], anims=[808, -1]. +NPC id=4654, name=Trader Crewmember, level=0, option=[Talk-To, null, Trade, Charter, null], anims=[808, -1]. +NPC id=4655, name=Trader Crewmember, level=0, option=[Talk-To, null, Trade, Charter, null], anims=[808, -1]. +NPC id=4656, name=Trader Crewmember, level=0, option=[Talk-To, null, Trade, Charter, null], anims=[808, -1]. +NPC id=4657, name=Sir Prysin, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4658, name=Dark wizard, level=7, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=4659, name=Dark wizard, level=7, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=4660, name=Dark wizard, level=20, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=4661, name=Dark wizard, level=20, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=4662, name=Denath, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=4663, name=Denath, level=0, option=[null, null, null, null, null], anims=[808, 4626]. +NPC id=4664, name=Wally, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=4665, name=Baby blue dragon, level=48, option=[null, Attack, null, null, null], anims=[27, 21]. +NPC id=4666, name=Baby blue dragon, level=48, option=[null, Attack, null, null, null], anims=[27, 21]. +NPC id=4667, name=Baby red dragon, level=48, option=[null, Attack, null, null, null], anims=[27, 21]. +NPC id=4668, name=Baby red dragon, level=48, option=[null, Attack, null, null, null], anims=[27, 21]. +NPC id=4669, name=Red dragon, level=152, option=[null, Attack, null, null, null], anims=[90, 79]. +NPC id=4670, name=Red dragon, level=152, option=[null, Attack, null, null, null], anims=[90, 79]. +NPC id=4671, name=Red dragon, level=152, option=[null, Attack, null, null, null], anims=[90, 79]. +NPC id=4672, name=Red dragon, level=152, option=[null, Attack, null, null, null], anims=[90, 79]. +NPC id=4673, name=Black dragon, level=227, option=[null, Attack, null, null, null], anims=[90, 79]. +NPC id=4674, name=Black dragon, level=227, option=[null, Attack, null, null, null], anims=[90, 79]. +NPC id=4675, name=Black dragon, level=227, option=[null, Attack, null, null, null], anims=[90, 79]. +NPC id=4676, name=Black dragon, level=227, option=[null, Attack, null, null, null], anims=[90, 79]. +NPC id=4677, name=Green dragon, level=79, option=[null, Attack, null, null, null], anims=[90, 79]. +NPC id=4678, name=Green dragon, level=79, option=[null, Attack, null, null, null], anims=[90, 79]. +NPC id=4679, name=Green dragon, level=79, option=[null, Attack, null, null, null], anims=[90, 79]. +NPC id=4680, name=Green dragon, level=79, option=[null, Attack, null, null, null], anims=[90, 79]. +NPC id=4681, name=Blue dragon, level=111, option=[null, Attack, null, null, null], anims=[90, 79]. +NPC id=4682, name=Blue dragon, level=111, option=[null, Attack, null, null, null], anims=[90, 79]. +NPC id=4683, name=Blue dragon, level=111, option=[null, Attack, null, null, null], anims=[90, 79]. +NPC id=4684, name=Blue dragon, level=111, option=[null, Attack, null, null, null], anims=[90, 79]. +NPC id=4685, name=Ice giant, level=53, option=[null, Attack, null, null, null], anims=[4670, 4669]. +NPC id=4686, name=Ice giant, level=53, option=[null, Attack, null, null, null], anims=[4670, 4669]. +NPC id=4687, name=Ice giant, level=53, option=[null, Attack, null, null, null], anims=[4670, 4669]. +NPC id=4688, name=Moss giant, level=42, option=[null, Attack, null, null, null], anims=[4656, 4655]. +NPC id=4689, name=Hill Giant, level=28, option=[null, Attack, null, null, null], anims=[4650, 4649]. +NPC id=4690, name=Hill Giant, level=28, option=[null, Attack, null, null, null], anims=[4650, 4649]. +NPC id=4691, name=Hill Giant, level=28, option=[null, Attack, null, null, null], anims=[4650, 4649]. +NPC id=4692, name=Hill Giant, level=28, option=[null, Attack, null, null, null], anims=[4650, 4649]. +NPC id=4693, name=Hill Giant, level=28, option=[null, Attack, null, null, null], anims=[4650, 4649]. +NPC id=4694, name=Lesser demon, level=82, option=[null, Attack, null, null, null], anims=[66, 63]. +NPC id=4695, name=Lesser demon, level=82, option=[null, Attack, null, null, null], anims=[66, 63]. +NPC id=4696, name=Lesser demon, level=82, option=[null, Attack, null, null, null], anims=[66, 63]. +NPC id=4697, name=Lesser demon, level=82, option=[null, Attack, null, null, null], anims=[66, 63]. +NPC id=4698, name=Greater demon, level=92, option=[null, Attack, null, null, null], anims=[66, 63]. +NPC id=4699, name=Greater demon, level=92, option=[null, Attack, null, null, null], anims=[66, 63]. +NPC id=4700, name=Greater demon, level=92, option=[null, Attack, null, null, null], anims=[66, 63]. +NPC id=4701, name=Greater demon, level=92, option=[null, Attack, null, null, null], anims=[66, 63]. +NPC id=4702, name=Black demon, level=172, option=[null, Attack, null, null, null], anims=[66, 63]. +NPC id=4703, name=Black demon, level=172, option=[null, Attack, null, null, null], anims=[66, 63]. +NPC id=4704, name=Black demon, level=172, option=[null, Attack, null, null, null], anims=[66, 63]. +NPC id=4705, name=Black demon, level=172, option=[null, Attack, null, null, null], anims=[66, 63]. +NPC id=4706, name=Moss giant, level=48, option=[null, Attack, null, null, null], anims=[4656, 4654]. +NPC id=4707, name=Magic combat tutor, level=0, option=[Talk-to, null, Claim, null, null], anims=[813, -1]. +NPC id=4708, name=Old Man Ral, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4709, name=Vertida Sefalatis, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4710, name=Aeonisig Raispher, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4711, name=null, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=4712, name=null, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=4713, name=Safalaan, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4714, name=null, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=4715, name=Sarius Guile, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4716, name=Trader Sven, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4717, name=Meiyerditch citizen, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4718, name=Meiyerditch citizen, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4719, name=Meiyerditch citizen, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4720, name=Meiyerditch citizen, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4721, name=Meiyerditch citizen, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4722, name=Meiyerditch citizen, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4723, name=Meiyerditch citizen, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4724, name=Meiyerditch citizen, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4725, name=Meiyerditch citizen, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4726, name=Meiyerditch citizen, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4727, name=Meiyerditch citizen, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4728, name=Meiyerditch citizen, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4729, name=Meiyerditch citizen, level=0, option=[Talk-to, null, null, null, null], anims=[4712, -1]. +NPC id=4730, name=Meiyerditch citizen, level=0, option=[Talk-to, null, null, null, null], anims=[4712, -1]. +NPC id=4731, name=Meiyerditch citizen, level=0, option=[Talk-to, null, null, null, null], anims=[4712, -1]. +NPC id=4732, name=Meiyerditch citizen, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4733, name=Meiyerditch citizen, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4734, name=Meiyerditch citizen, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4735, name=Meiyerditch citizen, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4736, name=Meiyerditch citizen, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4737, name=Meiyerditch citizen, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4738, name=Meiyerditch citizen, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4739, name=Meiyerditch citizen, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4740, name=Meiyerditch citizen, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4741, name=Meiyerditch citizen, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4742, name=Meiyerditch citizen, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4743, name=Meiyerditch citizen, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4744, name=Meiyerditch citizen, level=0, option=[Talk-to, null, null, null, null], anims=[4712, -1]. +NPC id=4745, name=Meiyerditch citizen, level=0, option=[Talk-to, null, null, null, null], anims=[4712, -1]. +NPC id=4746, name=A Meiyerditch child, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=4747, name=A Meiyerditch child, level=0, option=[Talk-to, null, null, null, null], anims=[7298, 7297]. +NPC id=4748, name=A Meiyerditch child, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=4749, name=A Meiyerditch child, level=0, option=[Talk-to, null, null, null, null], anims=[7298, 7297]. +NPC id=4750, name=A Meiyerditch child, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=4751, name=A Meiyerditch child, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=4752, name=A Meiyerditch child, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=4753, name=A Meiyerditch child, level=0, option=[Talk-to, null, null, null, null], anims=[7298, 7297]. +NPC id=4754, name=A Meiyerditch child, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=4755, name=A Meiyerditch child, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=4756, name=Meiyerditch miner, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4757, name=Meiyerditch miner, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4758, name=Meiyerditch miner, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4759, name=Meiyerditch miner, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4760, name=Meiyerditch miner, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4761, name=Meiyerditch miner, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4762, name=Shadowy figure, level=0, option=[null, null, null, null, null], anims=[6539, 6541]. +NPC id=4763, name=Shadowy figure, level=0, option=[null, null, null, null, null], anims=[6539, 6541]. +NPC id=4764, name=Shadowy figure, level=0, option=[null, null, null, null, null], anims=[6545, 6544]. +NPC id=4765, name=null, level=0, option=[null, null, null, null, null], anims=[4753, 4754]. +NPC id=4766, name=Stray dog, level=0, option=[null, null, null, null, null], anims=[4777, 4773]. +NPC id=4767, name=Stray dog, level=0, option=[null, null, null, null, null], anims=[4777, 4773]. +NPC id=4768, name=Cat, level=0, option=[Talk-to, null, null, null, null], anims=[9158, 9157]. +NPC id=4769, name=Cat, level=0, option=[Talk-to, null, null, null, null], anims=[9158, 9157]. +NPC id=4770, name=Boat, level=0, option=[null, null, null, null, null], anims=[4755, 4756]. +NPC id=4771, name=Boat, level=0, option=[null, null, null, null, null], anims=[4756, 4756]. +NPC id=4772, name=Juvinate guard, level=54, option=[Talk-to, null, null, null, null], anims=[4702, 4699]. +NPC id=4773, name=Juvinate guard, level=54, option=[Talk-to, null, null, null, null], anims=[4702, 4700]. +NPC id=4774, name=Vampyre juvenile, level=45, option=[Talk-to, Attack, null, null, null], anims=[4702, 4699]. +NPC id=4775, name=Vampyre juvenile, level=45, option=[Talk-to, Attack, null, null, null], anims=[4703, 4700]. +NPC id=4776, name=Vampyre juvinate, level=54, option=[Talk-to, Attack, null, null, null], anims=[4702, 4699]. +NPC id=4777, name=Vampyre juvinate, level=54, option=[Talk-to, Attack, null, null, null], anims=[4702, 4700]. +NPC id=4778, name=Held vampyre juvenile, level=54, option=[Talk-to, Attack, null, null, null], anims=[4768, -1]. +NPC id=4779, name=Held vampyre juvenile, level=54, option=[Talk-to, Attack, null, null, null], anims=[4768, -1]. +NPC id=4780, name=Held vampyre juvinate, level=54, option=[Talk-to, Attack, null, null, null], anims=[4768, -1]. +NPC id=4781, name=Held vampyre juvinate, level=54, option=[Talk-to, Attack, null, null, null], anims=[4768, -1]. +NPC id=4782, name=Vampyre juvinate, level=0, option=[null, null, null, null, null], anims=[4711, 4699]. +NPC id=4783, name=Former vampyre, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=4784, name=Former vampyre, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=4785, name=Former vampyre, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=4786, name=Former vampyre, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=4787, name=Former vampyre, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=4788, name=Former vampyre, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=4789, name=Angry vampyre, level=64, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=4790, name=Angry vampyre, level=64, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=4791, name=Vanstrom Klause, level=0, option=[null, null, null, null, null], anims=[4702, 4699]. +NPC id=4792, name=Vanstrom Klause, level=0, option=[null, null, null, null, null], anims=[4702, 4699]. +NPC id=4793, name=Vanstrom Klause, level=169, option=[null, Attack, null, null, null], anims=[4702, 4699]. +NPC id=4794, name=Vanstrom Klause, level=0, option=[null, null, null, null, null], anims=[4690, 4684]. +NPC id=4795, name=Vanstrom Klause, level=0, option=[null, null, null, null, null], anims=[4707, -1]. +NPC id=4796, name=Vanstrom Klause, level=0, option=[null, null, null, null, null], anims=[4696, -1]. +NPC id=4797, name=Vanescula Drakan, level=0, option=[null, null, null, null, null], anims=[4703, 4699]. +NPC id=4798, name=Vanescula Drakan, level=0, option=[null, null, null, null, null], anims=[4703, 4700]. +NPC id=4799, name=Vanescula Drakan, level=0, option=[null, null, null, null, null], anims=[4690, 4684]. +NPC id=4800, name=Vanescula Drakan, level=0, option=[null, null, null, null, null], anims=[4707, -1]. +NPC id=4801, name=Ranis Drakan, level=0, option=[null, null, null, null, null], anims=[4702, 4699]. +NPC id=4802, name=Ranis Drakan, level=0, option=[null, null, null, null, null], anims=[4702, 4699]. +NPC id=4803, name=Ranis Drakan, level=0, option=[null, null, null, null, null], anims=[4690, 4684]. +NPC id=4804, name=Ranis Drakan, level=0, option=[null, null, null, null, null], anims=[4707, -1]. +NPC id=4805, name=Vyrewatch, level=110, option=[Talk-to, Attack, null, null, null], anims=[4703, 4700]. +NPC id=4806, name=Vyrewatch, level=120, option=[Talk-to, Attack, null, null, null], anims=[4703, 4700]. +NPC id=4807, name=Vyrewatch, level=130, option=[Talk-to, Attack, null, null, null], anims=[4703, 4700]. +NPC id=4808, name=Vyrewatch, level=140, option=[Talk-to, Attack, null, null, null], anims=[4703, 4700]. +NPC id=4809, name=Flying female vampire, level=110, option=[Talk-to, Attack, null, null, null], anims=[4706, -1]. +NPC id=4810, name=Flying female vampire, level=120, option=[Talk-to, Attack, null, null, null], anims=[4706, -1]. +NPC id=4811, name=Flying female vampire, level=130, option=[Talk-to, Attack, null, null, null], anims=[4706, -1]. +NPC id=4812, name=Flying female vampire, level=140, option=[Talk-to, Attack, null, null, null], anims=[4706, -1]. +NPC id=4813, name=Vyrewatch, level=110, option=[Talk-to, Attack, null, null, null], anims=[4689, 4683]. +NPC id=4814, name=Vyrewatch, level=120, option=[Talk-to, Attack, null, null, null], anims=[4689, 4683]. +NPC id=4815, name=Vyrewatch, level=130, option=[Talk-to, Attack, null, null, null], anims=[4689, 4683]. +NPC id=4816, name=Vyrewatch, level=140, option=[Talk-to, Attack, null, null, null], anims=[4689, 4683]. +NPC id=4817, name=Vyrewatch, level=110, option=[Talk-to, Attack, null, null, null], anims=[4702, 4699]. +NPC id=4818, name=Vyrewatch, level=120, option=[Talk-to, Attack, null, null, null], anims=[4702, 4699]. +NPC id=4819, name=Vyrewatch, level=130, option=[Talk-to, Attack, null, null, null], anims=[4702, 4699]. +NPC id=4820, name=Vyrewatch, level=140, option=[Talk-to, Attack, null, null, null], anims=[4702, 4699]. +NPC id=4821, name=Vyrewatch, level=110, option=[Talk-to, Attack, null, null, null], anims=[4706, -1]. +NPC id=4822, name=Vyrewatch, level=120, option=[Talk-to, Attack, null, null, null], anims=[4706, -1]. +NPC id=4823, name=Vyrewatch, level=130, option=[Talk-to, Attack, null, null, null], anims=[4706, -1]. +NPC id=4824, name=Vyrewatch, level=140, option=[Talk-to, Attack, null, null, null], anims=[4706, -1]. +NPC id=4825, name=Vyrewatch, level=110, option=[Talk-to, Attack, null, null, null], anims=[4689, 4683]. +NPC id=4826, name=Vyrewatch, level=120, option=[Talk-to, Attack, null, null, null], anims=[4689, 4683]. +NPC id=4827, name=Vyrewatch, level=130, option=[Talk-to, Attack, null, null, null], anims=[4689, 4683]. +NPC id=4828, name=Vyrewatch, level=140, option=[Talk-to, Attack, null, null, null], anims=[4689, 4683]. +NPC id=4829, name=Vyrewatch, level=110, option=[Talk-to, Attack, null, null, null], anims=[4689, 4683]. +NPC id=4830, name=Vyrewatch, level=120, option=[Talk-to, Attack, null, null, null], anims=[4689, 4683]. +NPC id=4831, name=Vyrewatch, level=130, option=[Talk-to, Attack, null, null, null], anims=[4689, 4683]. +NPC id=4832, name=Vyrewatch, level=140, option=[Talk-to, Attack, null, null, null], anims=[4689, 4683]. +NPC id=4833, name=Vyrewatch, level=110, option=[Talk-to, Attack, null, null, null], anims=[4689, 4683]. +NPC id=4834, name=Vyrewatch, level=120, option=[Talk-to, Attack, null, null, null], anims=[4689, 4683]. +NPC id=4835, name=Vyrewatch, level=130, option=[Talk-to, Attack, null, null, null], anims=[4689, 4683]. +NPC id=4836, name=Vyrewatch, level=140, option=[Talk-to, Attack, null, null, null], anims=[4689, 4683]. +NPC id=4837, name=Vyrewatch, level=110, option=[Talk-to, Attack, null, null, null], anims=[4703, 4700]. +NPC id=4838, name=Vyrewatch, level=120, option=[Talk-to, Attack, null, null, null], anims=[4703, 4700]. +NPC id=4839, name=Vyrewatch, level=130, option=[Talk-to, Attack, null, null, null], anims=[4703, 4700]. +NPC id=4840, name=Vyrewatch, level=140, option=[Talk-to, Attack, null, null, null], anims=[4703, 4700]. +NPC id=4841, name=Vyrewatch, level=110, option=[Talk-to, Attack, null, null, null], anims=[4702, 4699]. +NPC id=4842, name=Vyrewatch, level=120, option=[Talk-to, Attack, null, null, null], anims=[4702, 4699]. +NPC id=4843, name=Vyrewatch, level=130, option=[Talk-to, Attack, null, null, null], anims=[4702, 4699]. +NPC id=4844, name=Vyrewatch, level=140, option=[Talk-to, Attack, null, null, null], anims=[4702, 4699]. +NPC id=4845, name=Flying female vampire, level=110, option=[Talk-to, Attack, null, null, null], anims=[4706, -1]. +NPC id=4846, name=Flying female vampire, level=120, option=[Talk-to, Attack, null, null, null], anims=[4706, -1]. +NPC id=4847, name=Flying female vampire, level=130, option=[Talk-to, Attack, null, null, null], anims=[4706, -1]. +NPC id=4848, name=Flying female vampire, level=140, option=[Talk-to, Attack, null, null, null], anims=[4706, -1]. +NPC id=4849, name=Vyrewatch, level=110, option=[Talk-to, Attack, null, null, null], anims=[4706, -1]. +NPC id=4850, name=Vyrewatch, level=120, option=[Talk-to, Attack, null, null, null], anims=[4706, -1]. +NPC id=4851, name=Vyrewatch, level=130, option=[Talk-to, Attack, null, null, null], anims=[4706, -1]. +NPC id=4852, name=Vyrewatch, level=140, option=[Talk-to, Attack, null, null, null], anims=[4706, -1]. +NPC (wrapper) id=4853, child npcs=[4872, 4872, 4872, 4872, 4872, 4872, 4872, 4872, 4872, 4873, 4873, 4873, 4873, -1]. +NPC (wrapper) id=4854, child npcs=[4874, 4874, 4874, 4874, 4874, 4874, 4874, 4874, 4874, 4874, 4874, 4874, 4875, 4875, -1]. +NPC (wrapper) id=4855, child npcs=[4878, 4878, 4878, 4878, 4878, 4878, 4878, 4878, 4879, 4879, 4879, 4879, 4879, 4879, -1]. +NPC id=4856, name=Ezekial Lovecraft, level=0, option=[Talk-to, null, null, Shop, null], anims=[808, -1]. +NPC (wrapper) id=4857, child npcs=[4883, -1]. +NPC (wrapper) id=4858, child npcs=[4885, 4885, 4885, 4885, 4885, -1]. +NPC (wrapper) id=4859, child npcs=[4887, 4887, 4887, 4887, 4887, 4887, 4887, 4887, 4887, -1]. +NPC (wrapper) id=4860, child npcs=[4895, 4895, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896, -1]. +NPC id=4861, name=Sarius Guile, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=4862, name=Vanstrom Klause, level=169, option=[null, null, null, null, null], anims=[4702, 4699]. +NPC id=4863, name=Kennith, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 4789]. +NPC id=4864, name=Kennith, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=4865, name=null, level=1, option=[null, null, null, null, null], anims=[7158, 7160]. +NPC id=4866, name=Holgart, level=0, option=[Talk-to, null, null, null, null], anims=[4788, -1]. +NPC id=4867, name=Holgart, level=0, option=[Talk-to, null, null, null, null], anims=[-1, 4787]. +NPC id=4868, name=Holgart, level=0, option=[Talk-to, null, null, null, null], anims=[-1, 4790]. +NPC id=4869, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=4870, name=Fisherman, level=0, option=[Talk-to, null, null, null, null], anims=[4825, 4779]. +NPC (wrapper) id=4871, child npcs=[699, 4896, -1]. +NPC id=4872, name=Col. O'Niall, level=0, option=[Talk-to, null, null, null, null], anims=[4780, -1]. +NPC id=4873, name=Col. O'Niall, level=0, option=[Talk-to, null, null, null, null], anims=[4780, -1]. +NPC id=4874, name=Mayor Hobb, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4875, name=Mayor Hobb, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4876, name=null, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=4877, name=null, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=4878, name=Brother Maledict, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4879, name=Brother Maledict, level=0, option=[Talk-to, null, null, null, null], anims=[808, 4779]. +NPC id=4880, name=null, level=1, option=[Talk-to, null, null, null, null], anims=[808, 4779]. +NPC id=4881, name=null, level=1, option=[Talk-to, null, null, null, null], anims=[808, 4779]. +NPC id=4882, name=null, level=1, option=[Talk-to, null, null, null, null], anims=[808, 4779]. +NPC id=4883, name=Witchaven villager, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4884, name=Witchaven villager, level=0, option=[Talk-to, null, null, null, null], anims=[808, 4779]. +NPC id=4885, name=Witchaven villager, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4886, name=Witchaven villager, level=0, option=[Talk-to, null, null, null, null], anims=[808, 4779]. +NPC id=4887, name=Witchaven villager, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4888, name=Witchaven villager, level=0, option=[Talk-to, null, null, null, null], anims=[808, 4779]. +NPC id=4889, name=Mother Mallum, level=0, option=[null, null, null, null, null], anims=[4819, 4820]. +NPC id=4890, name=Slug Prince, level=62, option=[null, Attack, null, null, null], anims=[4828, 4821]. +NPC id=4891, name=null, level=1, option=[null, null, null, null, null], anims=[6263, 6264]. +NPC id=4892, name=Giant lobster, level=0, option=[null, null, null, null, null], anims=[6263, 6264]. +NPC id=4893, name=Giant Lobster, level=45, option=[null, Attack, null, null, null], anims=[6263, 6264]. +NPC id=4894, name=Sea slug, level=0, option=[null, null, null, null, null], anims=[932, 933]. +NPC id=4895, name=Jeb, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4896, name=Jeb, level=0, option=[Talk-to, null, null, null, null], anims=[808, 4824]. +NPC id=4897, name=Sir Tinley, level=0, option=[Talk-to, null, null, null, null], anims=[2253, -1]. +NPC id=4898, name=Hobgoblin, level=28, option=[null, Attack, null, null, null], anims=[166, 162]. +NPC id=4899, name=Cooking tutor, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4900, name=Crafting tutor, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4901, name=Fishing tutor, level=0, option=[Talk-to, null, null, null, null], anims=[3845, -1]. +NPC id=4902, name=Mining tutor, level=0, option=[Talk-to, null, null, null, null], anims=[2065, 2064]. +NPC id=4903, name=Prayer tutor, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4904, name=Smithing apprentice, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4905, name=Master smithing tutor, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4906, name=Woodsman tutor, level=0, option=[Talk-to, null, null, null, null], anims=[2065, 2064]. +NPC id=4907, name=Banker tutor, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[808, -1]. +NPC id=4908, name=Fishing spot, level=0, option=[Net, null, Bait, hidden, hidden], anims=[447, 448]. +NPC id=4909, name=Fritz the Glassblower, level=0, option=[Talk-to, null, null, null, null], anims=[4859, -1]. +NPC id=4910, name=Earth elemental, level=35, option=[null, Attack, null, null, null], anims=[4866, 4867]. +NPC id=4911, name=Elemental rock, level=0, option=[Mine, null, null, null, null], anims=[4864, 4864]. +NPC (wrapper) id=4912, child npcs=[4913, 4914, 4915, 4916, 4917, 4918, -1]. +NPC id=4913, name=Jig cart, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=4914, name=Jig cart, level=0, option=[Take-from, null, null, null, null], anims=[-1, -1]. +NPC id=4915, name=Jig cart, level=0, option=[Take-from, null, null, null, null], anims=[-1, -1]. +NPC id=4916, name=Jig cart, level=0, option=[Take-from, null, null, null, null], anims=[-1, -1]. +NPC id=4917, name=Jig cart, level=0, option=[Take-from, null, null, null, null], anims=[-1, -1]. +NPC id=4918, name=Jig cart, level=0, option=[Take-from, null, null, null, null], anims=[-1, -1]. +NPC id=4919, name=Abidor Crank, level=0, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=4920, name=Giant crypt rat, level=76, option=[null, Attack, null, null, null], anims=[4932, 4931]. +NPC id=4921, name=Giant crypt rat, level=76, option=[null, Attack, null, null, null], anims=[4932, 4931]. +NPC id=4922, name=Giant rat, level=3, option=[null, Attack, null, null, null], anims=[4932, 4931]. +NPC id=4923, name=Giant rat, level=3, option=[null, Attack, null, null, null], anims=[4932, 4931]. +NPC id=4924, name=Giant rat, level=3, option=[null, Attack, null, null, null], anims=[4932, 4931]. +NPC id=4925, name=Giant rat, level=3, option=[null, Attack, null, null, null], anims=[4932, 4931]. +NPC id=4926, name=Giant rat, level=6, option=[null, Attack, null, null, null], anims=[4932, 4931]. +NPC id=4927, name=Giant rat, level=6, option=[null, Attack, null, null, null], anims=[4932, 4931]. +NPC id=4928, name=Dungeon rat, level=12, option=[null, Attack, null, null, null], anims=[4932, 4931]. +NPC id=4929, name=Dungeon rat, level=12, option=[null, Attack, null, null, null], anims=[4932, 4931]. +NPC id=4930, name=Goat, level=23, option=[null, Attack, null, null, null], anims=[5339, 5340]. +NPC id=4931, name=Goat, level=23, option=[null, Attack, null, null, null], anims=[5339, 5340]. +NPC id=4932, name=Billy Goat, level=33, option=[null, Attack, null, null, null], anims=[5339, 5340]. +NPC id=4933, name=Goat, level=23, option=[null, Attack, null, null, null], anims=[5339, 5340]. +NPC id=4934, name=Goat, level=23, option=[null, Attack, null, null, null], anims=[5339, 5340]. +NPC id=4935, name=Billy Goat, level=33, option=[null, Attack, null, null, null], anims=[5339, 5340]. +NPC id=4936, name=Dungeon rat, level=12, option=[null, Attack, null, null, null], anims=[4932, 4931]. +NPC id=4937, name=Dungeon rat, level=12, option=[null, Attack, null, null, null], anims=[4932, 4931]. +NPC id=4938, name=Angry giant rat, level=45, option=[null, Attack, null, null, null], anims=[4932, 4931]. +NPC id=4939, name=Angry giant rat, level=45, option=[null, Attack, null, null, null], anims=[4932, 4931]. +NPC id=4940, name=Angry giant rat, level=47, option=[null, Attack, null, null, null], anims=[4932, 4931]. +NPC id=4941, name=Blessed giant rat, level=9, option=[null, Attack, null, null, null], anims=[4932, 4931]. +NPC id=4942, name=Giant rat, level=3, option=[null, Attack, null, null, null], anims=[4932, 4931]. +NPC id=4943, name=Giant rat, level=3, option=[null, Attack, null, null, null], anims=[4932, 4931]. +NPC id=4944, name=Giant rat, level=26, option=[null, Attack, null, null, null], anims=[4932, 4931]. +NPC id=4945, name=Giant rat, level=26, option=[null, Attack, null, null, null], anims=[4932, 4931]. +NPC id=4946, name=Ignatius Vulcan, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4947, name=My Arm, level=0, option=[Talk-to, null, null, null, null], anims=[4986, 283]. +NPC id=4948, name=My Arm, level=0, option=[null, null, null, null, null], anims=[4986, 283]. +NPC id=4949, name=My Arm, level=0, option=[Talk-to, null, null, null, null], anims=[4986, 283]. +NPC id=4950, name=null, level=1, option=[null, null, null, null, null], anims=[4986, 283]. +NPC id=4951, name=null, level=1, option=[null, null, null, null, null], anims=[4986, 283]. +NPC id=4952, name=null, level=1, option=[null, null, null, null, null], anims=[4986, 283]. +NPC id=4953, name=null, level=1, option=[null, null, null, null, null], anims=[4986, -1]. +NPC id=4954, name=null, level=1, option=[null, null, null, null, null], anims=[4986, 283]. +NPC id=4955, name=null, level=1, option=[null, null, null, null, null], anims=[4986, -1]. +NPC id=4956, name=null, level=1, option=[null, null, null, null, null], anims=[4986, 283]. +NPC id=4957, name=My Arm, level=0, option=[null, null, null, null, null], anims=[4986, -1]. +NPC id=4958, name=My Arm, level=0, option=[null, null, null, null, null], anims=[4986, -1]. +NPC id=4959, name=My Arm, level=0, option=[null, null, null, null, null], anims=[4986, -1]. +NPC id=4960, name=Adventurer, level=0, option=[null, null, null, null, null], anims=[479, -1]. +NPC id=4961, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=4962, name=Captain Barnaby, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4963, name=Murcaily, level=0, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=4964, name=Jagbakoba, level=0, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=4965, name=Tool Leprechaun, level=0, option=[Talk-to, null, Exchange, Trade, null], anims=[5002, -1]. +NPC id=4966, name=null, level=1, option=[null, null, null, null, null], anims=[0, 0]. +NPC id=4967, name=Flies, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=4968, name=Unnamed troll child, level=0, option=[null, null, null, null, null], anims=[286, 283]. +NPC id=4969, name=Drunken dwarf's leg, level=0, option=[Talk-to, null, null, null, null], anims=[286, 283]. +NPC id=4970, name=null, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=4971, name=Baby Roc, level=75, option=[null, Attack, null, null, null], anims=[5029, 5030]. +NPC id=4972, name=Giant Roc, level=172, option=[null, Attack, null, null, null], anims=[5021, 5022]. +NPC id=4973, name=Shadow, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=4974, name=Captain Barnaby, level=0, option=[Talk-to, null, Pay-fare, null, null], anims=[-1, -1]. +NPC id=4975, name=Male slave, level=0, option=[Talk-to, null, null, null, null], anims=[6935, -1]. +NPC id=4976, name=Male slave, level=0, option=[Talk-to, null, null, null, null], anims=[6935, -1]. +NPC id=4977, name=Female slave, level=0, option=[Talk-to, null, null, null, null], anims=[6935, -1]. +NPC id=4978, name=Female slave, level=0, option=[Talk-to, null, null, null, null], anims=[6935, -1]. +NPC id=4979, name=Cart Camel, level=0, option=[Talk-to, null, null, null, null], anims=[5044, -1]. +NPC id=4980, name=Mine Cart, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=4981, name=Mine Cart, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=4982, name=Ana, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=4983, name=Mercenary, level=45, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC (wrapper) id=4984, child npcs=[822, -1]. +NPC (wrapper) id=4985, child npcs=[825, 826, -1]. +NPC (wrapper) id=4986, child npcs=[835, -1]. +NPC id=4987, name=null, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=4988, name=Irena, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=4989, name=Mercenary, level=45, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=4990, name=Mercenary, level=45, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=4991, name=Mercenary, level=45, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=4992, name=Mercenary, level=45, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=4993, name=Guard, level=45, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=4994, name=Guard, level=45, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=4995, name=Guard, level=45, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=4996, name=Guard, level=45, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=4997, name=Guard, level=45, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=4998, name=Guard, level=45, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=4999, name=Guard, level=45, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=5000, name=Guard, level=45, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=5001, name=Guard, level=45, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=5002, name=Guard, level=45, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC (wrapper) id=5003, child npcs=[5017, 5018, 5019, -1]. +NPC (wrapper) id=5004, child npcs=[5017, 5018, 5019, -1]. +NPC (wrapper) id=5005, child npcs=[5017, 5018, 5019, -1]. +NPC (wrapper) id=5006, child npcs=[5017, 5018, 5019, -1]. +NPC (wrapper) id=5007, child npcs=[5017, 5018, 5019, -1]. +NPC (wrapper) id=5008, child npcs=[5017, 5018, 5019, -1]. +NPC (wrapper) id=5009, child npcs=[5017, 5018, 5019, -1]. +NPC (wrapper) id=5010, child npcs=[5017, 5018, 5019, -1]. +NPC (wrapper) id=5011, child npcs=[5017, 5018, 5019, -1]. +NPC (wrapper) id=5012, child npcs=[5017, 5018, 5019, -1]. +NPC (wrapper) id=5013, child npcs=[5017, 5018, 5019, -1]. +NPC (wrapper) id=5014, child npcs=[5017, 5018, 5019, -1]. +NPC (wrapper) id=5015, child npcs=[5017, 5018, 5019, -1]. +NPC (wrapper) id=5016, child npcs=[5017, 5018, 5019, -1]. +NPC id=5017, name=Gublinch, level=0, option=[null, Pelt, null, null, null], anims=[5070, 5069]. +NPC id=5018, name=Gublinch, level=0, option=[null, Pelt, null, null, null], anims=[5070, 5069]. +NPC id=5019, name=Gublinch, level=0, option=[null, Pelt, null, null, null], anims=[5070, 5069]. +NPC id=5020, name=null, level=0, option=[null, null, null, null, null], anims=[7158, 7160]. +NPC id=5021, name=null, level=0, option=[null, null, null, null, null], anims=[7158, 7160]. +NPC id=5022, name=null, level=0, option=[null, null, null, null, null], anims=[7158, 7160]. +NPC id=5023, name=Jack, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=5024, name=Jill, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=5025, name=Jeff, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=5026, name=Egg launcher, level=0, option=[null, null, null, null, null], anims=[5424, -1]. +NPC id=5027, name=Egg launcher, level=0, option=[null, null, null, null, null], anims=[5425, -1]. +NPC id=5028, name=Egg launcher, level=0, option=[null, null, null, null, null], anims=[5424, -1]. +NPC id=5029, name=Commander Connad, level=0, option=[Talk-to, null, Get-rewards, null, null], anims=[808, -1]. +NPC id=5030, name=Captain Cain, level=0, option=[Talk-to, null, Tutorial, null, null], anims=[808, -1]. +NPC id=5031, name=Private Paldo, level=0, option=[Talk-to, null, null, null, null], anims=[2065, 2064]. +NPC id=5032, name=Private Pendron, level=0, option=[Talk-to, null, null, null, null], anims=[2561, -1]. +NPC id=5033, name=Private Pierreb, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5034, name=Private Paldon, level=0, option=[Talk-to, null, null, null, null], anims=[2561, -1]. +NPC id=5035, name=Major Attack, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=5036, name=Major Collect, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=5037, name=Major Defend, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=5038, name=Major Heal, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=5039, name=Sergeant Sambur, level=0, option=[Talk-to, null, null, null, null], anims=[2065, 2064]. +NPC id=5040, name=Penance Fighter, level=0, option=[null, null, null, null, null], anims=[5094, 5095]. +NPC id=5041, name=Penance Ranger, level=0, option=[null, null, null, null, null], anims=[5393, 5394]. +NPC id=5042, name=Penance Runner, level=0, option=[null, null, null, null, null], anims=[5099, 5100]. +NPC id=5043, name=Penance Healer, level=0, option=[null, null, null, null, null], anims=[5104, 5107]. +NPC id=5044, name=Penance Fighter, level=30, option=[null, Attack, null, null, null], anims=[5094, 5095]. +NPC id=5045, name=Penance Fighter, level=32, option=[null, Attack, null, null, null], anims=[5094, 5095]. +NPC id=5046, name=Jack, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=5047, name=Jill, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=5048, name=Jeff, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=5049, name=Auguste, level=0, option=[Talk-to, null, null, Fly, null], anims=[808, -1]. +NPC id=5050, name=Auguste, level=0, option=[Talk-to, null, null, Fly, null], anims=[808, -1]. +NPC id=5051, name=Auguste, level=0, option=[Talk-to, null, null, Fly, null], anims=[773, -1]. +NPC id=5052, name=Auguste, level=0, option=[Talk-to, null, null, Fly, null], anims=[808, -1]. +NPC id=5053, name=Assistant Serf, level=0, option=[Talk-to, null, null, Fly, null], anims=[808, -1]. +NPC id=5054, name=Assistant Brock, level=0, option=[Talk-to, null, null, Fly, null], anims=[808, -1]. +NPC id=5055, name=Assistant Marrow, level=0, option=[Talk-to, null, null, Fly, null], anims=[808, -1]. +NPC id=5056, name=Assistant Le Smith, level=0, option=[Talk-to, null, null, Fly, null], anims=[195, 189]. +NPC id=5057, name=Assistant Stan, level=0, option=[Talk-to, null, null, Fly, null], anims=[808, -1]. +NPC id=5058, name=Bob, level=0, option=[null, null, null, null, null], anims=[5146, 5150]. +NPC id=5059, name=Curly, level=0, option=[null, null, null, null, null], anims=[5147, 5151]. +NPC id=5060, name=Moe, level=0, option=[null, null, null, null, null], anims=[5148, 5152]. +NPC id=5061, name=Larry, level=0, option=[null, null, null, null, null], anims=[5149, 5153]. +NPC id=5062, name=null, level=1, option=[Talk-to, null, null, Fly, null], anims=[808, -1]. +NPC id=5063, name=null, level=1, option=[Talk-to, null, null, Fly, null], anims=[808, -1]. +NPC id=5064, name=null, level=1, option=[Talk-to, null, null, Fly, null], anims=[195, 189]. +NPC id=5065, name=null, level=1, option=[Talk-to, null, null, Fly, null], anims=[808, -1]. +NPC id=5066, name=null, level=1, option=[Talk-to, null, null, Fly, null], anims=[808, -1]. +NPC id=5067, name=Shark, level=0, option=[null, null, null, null, null], anims=[10, 10]. +NPC id=5068, name=Shark, level=0, option=[null, null, null, null, null], anims=[10, 10]. +NPC id=5069, name=Shark, level=0, option=[null, null, null, null, null], anims=[10, 10]. +NPC id=5070, name=null, level=0, option=[null, null, null, null, hidden], anims=[-1, -1]. +NPC id=5071, name=null, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=5072, name=Tropical wagtail, level=0, option=[null, null, null, null, hidden], anims=[6771, 6773]. +NPC id=5073, name=Crimson swift, level=0, option=[null, null, null, null, hidden], anims=[6771, 6773]. +NPC id=5074, name=Cerulean twitch, level=0, option=[null, null, null, null, hidden], anims=[6771, 6773]. +NPC id=5075, name=Golden warbler, level=0, option=[null, null, null, null, hidden], anims=[6771, 6773]. +NPC id=5076, name=Copper longtail, level=0, option=[null, null, null, null, hidden], anims=[6771, 6773]. +NPC id=5077, name=null, level=0, option=[null, null, null, null, hidden], anims=[-1, -1]. +NPC id=5078, name=null, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=5079, name=Chinchompa, level=1, option=[null, Attack, null, null, null], anims=[5182, 5181]. +NPC id=5080, name=Carnivorous chinchompa, level=2, option=[null, Attack, null, null, null], anims=[5182, 5181]. +NPC id=5081, name=Ferret, level=0, option=[null, null, null, null, null], anims=[5188, 5187]. +NPC id=5082, name=Black warlock, level=0, option=[Catch, null, null, null, null], anims=[362, 362]. +NPC id=5083, name=Snowy knight, level=0, option=[Catch, null, null, null, null], anims=[362, 362]. +NPC id=5084, name=Sapphire glacialis, level=0, option=[Catch, null, null, null, null], anims=[362, 362]. +NPC id=5085, name=Ruby harvest, level=0, option=[Catch, null, null, null, null], anims=[362, 362]. +NPC id=5086, name=Prickly kebbit, level=0, option=[null, null, null, null, Hidden], anims=[5273, 5272]. +NPC id=5087, name=Sabre-toothed kebbit, level=0, option=[null, null, null, null, Hidden], anims=[5273, 5272]. +NPC id=5088, name=Barb-tailed kebbit, level=0, option=[null, null, null, null, Hidden], anims=[5273, 5272]. +NPC id=5089, name=Wild kebbit, level=0, option=[null, null, null, null, Hidden], anims=[5273, 5272]. +NPC id=5090, name=null, level=0, option=[null, null, null, null, hidden], anims=[-1, -1]. +NPC id=5091, name=null, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=5092, name=Matthias, level=0, option=[Talk-to, null, Quick-falconry, null, null], anims=[5160, 5164]. +NPC id=5093, name=Matthias, level=0, option=[Talk-to, null, Quick-falconry, null, null], anims=[5160, 5164]. +NPC id=5094, name=Gyr Falcon, level=0, option=[Retrieve, null, null, null, null], anims=[5202, 5284]. +NPC id=5095, name=Gyr Falcon, level=0, option=[Retrieve, null, null, null, null], anims=[5202, 5284]. +NPC id=5096, name=Gyr Falcon, level=0, option=[Retrieve, null, null, null, null], anims=[5202, 5284]. +NPC id=5097, name=Gyr Falcon, level=0, option=[null, null, null, null, null], anims=[5203, 5284]. +NPC id=5098, name=Spotted kebbit, level=0, option=[Catch, null, null, null, null], anims=[5273, 5272]. +NPC id=5099, name=Dark kebbit, level=0, option=[Catch, null, null, null, null], anims=[5273, 5272]. +NPC id=5100, name=Dashing kebbit, level=0, option=[Catch, null, null, null, null], anims=[5273, 5272]. +NPC id=5101, name=null, level=0, option=[null, null, null, null, hidden], anims=[-1, -1]. +NPC id=5102, name=null, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=5103, name=Sabre-toothed kyatt, level=60, option=[Tease, null, null, null, null], anims=[5225, 5226]. +NPC id=5104, name=Spined larupia, level=40, option=[Tease, null, null, null, null], anims=[5225, 5226]. +NPC id=5105, name=Horned graahk, level=50, option=[Tease, null, null, null, null], anims=[5225, 5226]. +NPC id=5106, name=null, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=5107, name=null, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=5108, name=null, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=5109, name=Artimeus, level=0, option=[Talk-to, null, null, null, Trade], anims=[808, -1]. +NPC id=5110, name=Aleck, level=0, option=[Talk-to, null, null, null, Trade], anims=[808, -1]. +NPC id=5111, name=Leon, level=0, option=[Talk-to, null, null, null, Trade], anims=[808, -1]. +NPC id=5112, name=Hunting expert, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5113, name=Hunting expert, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5114, name=Orange salamander, level=0, option=[null, null, null, null, null], anims=[5263, 5262]. +NPC id=5115, name=Red salamander, level=0, option=[null, null, null, null, null], anims=[5263, 5262]. +NPC id=5116, name=Black salamander, level=0, option=[null, null, null, null, null], anims=[5263, 5262]. +NPC id=5117, name=Swamp lizard, level=0, option=[null, null, null, null, null], anims=[5263, 5262]. +NPC id=5118, name=null, level=0, option=[null, null, null, null, hidden], anims=[-1, -1]. +NPC id=5119, name=null, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=5120, name=Eagle, level=0, option=[null, null, null, null, null], anims=[1773, 1773]. +NPC id=5121, name=Eagle, level=0, option=[null, null, null, null, null], anims=[1773, 1773]. +NPC id=5122, name=Eagle, level=0, option=[null, null, null, null, null], anims=[1773, 1773]. +NPC id=5123, name=Eagle, level=0, option=[null, null, null, null, null], anims=[1773, 1773]. +NPC id=5124, name=null, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC (wrapper) id=5125, child npcs=[5128, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5128, -1, -1, -1, -1, 5128, -1, -1, -1, -1, 5128, -1, -1, -1, -1, 5128, -1]. +NPC id=5126, name=Nickolaus, level=0, option=[null, null, null, null, null], anims=[845, 844]. +NPC id=5127, name=Nickolaus, level=0, option=[Shout-to, null, null, null, null], anims=[-1, -1]. +NPC id=5128, name=Nickolaus, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=5129, name=Nickolaus, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=5130, name=Desert eagle, level=0, option=[null, null, null, null, null], anims=[5280, 5279]. +NPC id=5131, name=Jungle eagle, level=0, option=[null, null, null, null, null], anims=[5280, 5279]. +NPC id=5132, name=Polar eagle, level=0, option=[null, null, null, null, null], anims=[5280, 5279]. +NPC id=5133, name=Eagle, level=0, option=[Walk-past, null, null, null, null], anims=[5280, 5279]. +NPC id=5134, name=null, level=0, option=[null, null, null, null, null], anims=[5280, 5279]. +NPC id=5135, name=null, level=0, option=[null, null, null, null, null], anims=[5280, 5279]. +NPC id=5136, name=null, level=0, option=[null, null, null, null, null], anims=[5280, 5279]. +NPC id=5137, name=Kebbit, level=13, option=[null, Attack, null, null, null], anims=[5302, 5301]. +NPC id=5138, name=Charlie, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5139, name=null, level=0, option=[null, null, null, null, null], anims=[5188, 5187]. +NPC id=5140, name=Boulder, level=0, option=[Push, null, null, null, null], anims=[5310, 5309]. +NPC id=5141, name=Uri, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5142, name=Uri, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5143, name=Uri, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5144, name=Double agent, level=65, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=5145, name=Double agent, level=108, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=5146, name=Li'l lamb, level=0, option=[null, null, null, null, null], anims=[5339, 5340]. +NPC id=5147, name=Lamb, level=0, option=[null, null, null, null, null], anims=[5339, 5340]. +NPC id=5148, name=Sheep, level=0, option=[null, null, null, null, null], anims=[5339, 5340]. +NPC id=5149, name=Sheep, level=0, option=[null, null, null, null, null], anims=[5339, 5340]. +NPC id=5150, name=Sheep, level=0, option=[null, null, null, null, null], anims=[5339, 5340]. +NPC id=5151, name=Sheep, level=0, option=[null, null, null, null, null], anims=[5339, 5340]. +NPC id=5152, name=Sheep, level=0, option=[null, null, null, null, null], anims=[5339, 5340]. +NPC id=5153, name=Sheep, level=0, option=[null, null, null, null, null], anims=[5339, 5340]. +NPC id=5154, name=Sheep, level=0, option=[null, null, null, null, null], anims=[5339, 5340]. +NPC id=5155, name=Sheep, level=0, option=[null, null, null, null, null], anims=[5339, 5340]. +NPC id=5156, name=Sheep, level=0, option=[Shear, null, null, null, null], anims=[5335, 5334]. +NPC id=5157, name=Sheep, level=0, option=[Shear, null, null, null, null], anims=[5335, 5334]. +NPC id=5158, name=Sheep, level=0, option=[Shear, null, null, null, null], anims=[5335, 5334]. +NPC id=5159, name=Sheep, level=0, option=[Shear, null, null, null, null], anims=[5335, 5334]. +NPC id=5160, name=Sheep, level=0, option=[Shear, null, null, null, null], anims=[5335, 5334]. +NPC id=5161, name=Sheep, level=0, option=[Shear, null, null, null, null], anims=[5335, 5334]. +NPC id=5162, name=Sheep, level=0, option=[Shear, null, null, null, null], anims=[5345, 5344]. +NPC id=5163, name=Sheep, level=0, option=[Shear, null, null, null, null], anims=[5345, 5344]. +NPC id=5164, name=Sheep, level=0, option=[Talk-to, null, null, null, null], anims=[5335, 5334]. +NPC id=5165, name=Sheep, level=0, option=[Talk-to, null, null, null, null], anims=[5339, 5340]. +NPC id=5166, name=Mountain Goat, level=0, option=[null, null, null, null, null], anims=[5339, 5340]. +NPC id=5167, name=Mountain Goat, level=0, option=[null, null, null, null, null], anims=[5339, 5340]. +NPC id=5168, name=Ram, level=2, option=[null, Attack, null, null, null], anims=[5335, 5334]. +NPC id=5169, name=Ram, level=2, option=[null, Attack, null, null, null], anims=[5335, 5334]. +NPC id=5170, name=Ram, level=2, option=[null, Attack, null, null, null], anims=[5345, 5344]. +NPC id=5171, name=Mountain goat, level=0, option=[null, null, null, null, null], anims=[5339, 5340]. +NPC id=5172, name=Golden sheep, level=0, option=[null, null, null, null, null], anims=[5339, 5340]. +NPC id=5173, name=Golden sheep, level=0, option=[null, null, null, null, null], anims=[5345, 5344]. +NPC id=5174, name=Ogre chieftain, level=81, option=[null, null, null, null, null], anims=[357, 358]. +NPC (wrapper) id=5175, child npcs=[5176, 5179, -1]. +NPC id=5176, name=Ogre shaman, level=113, option=[Talk-to, Attack, null, null, null], anims=[357, 358]. +NPC id=5177, name=Ogre shaman, level=1, option=[null, null, null, null, null], anims=[357, 358]. +NPC id=5178, name=Blue dragon, level=27, option=[null, null, null, null, null], anims=[90, 79]. +NPC id=5179, name=Ogre shaman, level=113, option=[null, null, null, null, null], anims=[357, 358]. +NPC (wrapper) id=5180, child npcs=[5181, 5182, -1]. +NPC id=5181, name=Ogre shaman, level=113, option=[Talk-to, Attack, null, null, null], anims=[357, 358]. +NPC id=5182, name=Ogre shaman, level=113, option=[null, null, null, null, null], anims=[357, 358]. +NPC (wrapper) id=5183, child npcs=[5184, 5185, -1]. +NPC id=5184, name=Ogre shaman, level=113, option=[Talk-to, Attack, null, null, null], anims=[357, 358]. +NPC id=5185, name=Ogre shaman, level=113, option=[null, null, null, null, null], anims=[357, 358]. +NPC (wrapper) id=5186, child npcs=[5187, 5188, -1]. +NPC id=5187, name=Ogre shaman, level=113, option=[Talk-to, Attack, null, null, null], anims=[357, 358]. +NPC id=5188, name=Ogre shaman, level=113, option=[null, null, null, null, null], anims=[357, 358]. +NPC (wrapper) id=5189, child npcs=[5190, 5191, -1]. +NPC id=5190, name=Ogre shaman, level=113, option=[Talk-to, Attack, null, null, null], anims=[357, 358]. +NPC id=5191, name=Ogre shaman, level=113, option=[null, null, null, null, null], anims=[357, 358]. +NPC (wrapper) id=5192, child npcs=[5193, 5194, -1]. +NPC id=5193, name=Ogre shaman, level=113, option=[Talk-to, Attack, null, null, null], anims=[357, 358]. +NPC id=5194, name=Ogre shaman, level=113, option=[null, null, null, null, null], anims=[357, 358]. +NPC id=5195, name=Wizard, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5196, name=Wizard, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5197, name=Wizard, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5198, name=Ava, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=5199, name=null, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5200, name=Witch, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5201, name=null, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5202, name=Alice's husband, level=0, option=[Talk-to, null, null, null, null], anims=[5370, 5372]. +NPC id=5203, name=Alice's husband, level=0, option=[Talk-to, null, null, null, null], anims=[5370, 5372]. +NPC id=5204, name=Alice's husband, level=0, option=[null, null, null, null, null], anims=[5370, 5372]. +NPC id=5205, name=Alice's husband, level=0, option=[null, null, null, null, null], anims=[5371, 5373]. +NPC (wrapper) id=5206, child npcs=[5202, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5202, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5202, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5202, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5202, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5202, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5202, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5202, -1, -1, 5202, -1, -1, 5202, -1, -1, -1, 5203, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5203, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5203, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5203, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5203, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5203, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5203, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5203, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5203, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5203, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5203, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5203, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5203, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5203, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5203, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5203, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5203, -1]. +NPC id=5207, name=Tree, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=5208, name=Undead tree, level=0, option=[Chop, null, null, null, null], anims=[-1, -1]. +NPC id=5209, name= Sneaky undead fowl, level=1, option=[null, null, null, null, null], anims=[5386, 5385]. +NPC id=5210, name=Cow1337killr, level=123, option=[null, null, null, null, null], anims=[2065, 2064]. +NPC id=5211, name=Undead cow, level=2, option=[null, null, null, null, null], anims=[5852, 5848]. +NPC id=5212, name=Alice, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=5213, name=Penance Fighter, level=37, option=[null, Attack, null, null, null], anims=[5094, 5095]. +NPC id=5214, name=Penance Fighter, level=42, option=[null, Attack, null, null, null], anims=[5094, 5095]. +NPC id=5215, name=Penance Fighter, level=47, option=[null, Attack, null, null, null], anims=[5094, 5095]. +NPC id=5216, name=Penance Fighter, level=56, option=[null, Attack, null, null, null], anims=[5094, 5095]. +NPC id=5217, name=Penance Fighter, level=61, option=[null, Attack, null, null, null], anims=[5094, 5095]. +NPC id=5218, name=Penance Fighter, level=68, option=[null, Attack, null, null, null], anims=[5094, 5095]. +NPC id=5219, name=Penance Fighter, level=77, option=[null, Attack, null, null, null], anims=[5094, 5095]. +NPC id=5220, name=Penance Runner, level=0, option=[null, null, null, null, null], anims=[5099, 5100]. +NPC id=5221, name=Penance Runner, level=0, option=[null, null, null, null, null], anims=[5099, 5100]. +NPC id=5222, name=Penance Runner, level=0, option=[null, null, null, null, null], anims=[5099, 5100]. +NPC id=5223, name=Penance Runner, level=0, option=[null, null, null, null, null], anims=[5099, 5100]. +NPC id=5224, name=Penance Runner, level=0, option=[null, null, null, null, null], anims=[5099, 5100]. +NPC id=5225, name=Penance Runner, level=0, option=[null, null, null, null, null], anims=[5099, 5100]. +NPC id=5226, name=Penance Runner, level=0, option=[null, null, null, null, null], anims=[5099, 5100]. +NPC id=5227, name=Penance Runner, level=0, option=[null, null, null, null, null], anims=[5099, 5100]. +NPC id=5228, name=Penance Runner, level=0, option=[null, null, null, null, null], anims=[5099, 5100]. +NPC id=5229, name=Penance Ranger, level=21, option=[null, Attack, null, null, null], anims=[5393, 5394]. +NPC id=5230, name=Penance Ranger, level=25, option=[null, Attack, null, null, null], anims=[5393, 5394]. +NPC id=5231, name=Penance Ranger, level=32, option=[null, Attack, null, null, null], anims=[5393, 5394]. +NPC id=5232, name=Penance Ranger, level=38, option=[null, Attack, null, null, null], anims=[5393, 5394]. +NPC id=5233, name=Penance Ranger, level=43, option=[null, Attack, null, null, null], anims=[5393, 5394]. +NPC id=5234, name=Penance Ranger, level=51, option=[null, Attack, null, null, null], anims=[5393, 5394]. +NPC id=5235, name=Penance Ranger, level=57, option=[null, Attack, null, null, null], anims=[5393, 5394]. +NPC id=5236, name=Penance Ranger, level=64, option=[null, Attack, null, null, null], anims=[5393, 5394]. +NPC id=5237, name=Penance Ranger, level=72, option=[null, Attack, null, null, null], anims=[5393, 5394]. +NPC id=5238, name=Penance Healer, level=0, option=[null, null, null, null, null], anims=[5104, 5107]. +NPC id=5239, name=Penance Healer, level=0, option=[null, null, null, null, null], anims=[5104, 5107]. +NPC id=5240, name=Penance Healer, level=0, option=[null, null, null, null, null], anims=[5104, 5107]. +NPC id=5241, name=Penance Healer, level=0, option=[null, null, null, null, null], anims=[5104, 5107]. +NPC id=5242, name=Penance Healer, level=0, option=[null, null, null, null, null], anims=[5104, 5107]. +NPC id=5243, name=Penance Healer, level=0, option=[null, null, null, null, null], anims=[5104, 5107]. +NPC id=5244, name=Penance Healer, level=0, option=[null, null, null, null, null], anims=[5104, 5107]. +NPC id=5245, name=Penance Healer, level=0, option=[null, null, null, null, null], anims=[5104, 5107]. +NPC id=5246, name=Penance Healer, level=0, option=[null, null, null, null, null], anims=[5104, 5107]. +NPC id=5247, name=Penance Queen, level=209, option=[null, Attack, null, null, null], anims=[5410, 5409]. +NPC id=5248, name=Queen spawn, level=63, option=[null, Attack, null, null, null], anims=[5090, 5089]. +NPC id=5249, name=Captain Errdo, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=5250, name=Scarab mage, level=93, option=[null, Attack, null, null, null], anims=[7618, 7619]. +NPC id=5251, name=Locust rider, level=106, option=[null, Attack, null, null, null], anims=[7583, 7582]. +NPC id=5252, name=Locust rider, level=98, option=[null, Attack, null, null, null], anims=[7583, 7582]. +NPC id=5253, name=Giant scarab, level=191, option=[null, Attack, null, null, null], anims=[5455, 5454]. +NPC id=5254, name=Scarab mage, level=66, option=[null, Attack, null, null, null], anims=[7618, 7619]. +NPC id=5255, name=Locust rider, level=68, option=[null, Attack, null, null, null], anims=[7583, 7582]. +NPC id=5256, name=Locust rider, level=68, option=[null, Attack, null, null, null], anims=[7583, 7582]. +NPC id=5257, name=null, level=1, option=[Talk-to, null, Bank, Collect, null], anims=[808, -1]. +NPC id=5258, name=Banker, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[808, -1]. +NPC id=5259, name=null, level=1, option=[Talk-to, null, Bank, Collect, null], anims=[808, -1]. +NPC id=5260, name=Banker, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[808, -1]. +NPC id=5261, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=5262, name=Stonemason, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5263, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=5264, name=Nathifa, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=5265, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=5266, name=Urbi, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=5267, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=5268, name=Jamila, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=5269, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=5270, name=Sophanem guard, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=5271, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=5272, name=Sophanem guard, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5273, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=5274, name=Sophanem guard, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=5275, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=5276, name=Sophanem guard, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5277, name=Menaphite guard, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=5278, name=Coenus, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=5279, name=Jex, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC (wrapper) id=5280, child npcs=[5281, -1]. +NPC id=5281, name=Maisa, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC (wrapper) id=5282, child npcs=[924, 924, 5284, -1]. +NPC id=5283, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=5284, name=Osman, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5285, name=Osman, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5286, name=Osman, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=5287, name=Osman, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=5288, name=Embalmer, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=5289, name=Carpenter, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=5290, name=Linen worker, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5291, name=Priest, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=5292, name=Giant scarab, level=0, option=[null, null, null, null, null], anims=[5455, 5454]. +NPC id=5293, name=Zombie, level=13, option=[null, Attack, null, null, null], anims=[5565, -1]. +NPC id=5294, name=Zombie, level=13, option=[null, Attack, null, null, null], anims=[5565, -1]. +NPC id=5295, name=Zombie, level=13, option=[null, Attack, null, null, null], anims=[5565, -1]. +NPC id=5296, name=Zombie, level=13, option=[null, Attack, null, null, null], anims=[5565, -1]. +NPC id=5297, name=Zombie, level=13, option=[null, Attack, null, null, null], anims=[5565, -1]. +NPC id=5298, name=Zombie, level=13, option=[null, Attack, null, null, null], anims=[5565, -1]. +NPC id=5299, name=Zombie, level=13, option=[null, Attack, null, null, null], anims=[5565, -1]. +NPC id=5300, name=Zombie, level=13, option=[null, Attack, null, null, null], anims=[5565, -1]. +NPC id=5301, name=Zombie, level=13, option=[null, Attack, null, null, null], anims=[5565, -1]. +NPC id=5302, name=Zombie, level=13, option=[null, Attack, null, null, null], anims=[5565, -1]. +NPC id=5303, name=Zombie, level=13, option=[null, Attack, null, null, null], anims=[5565, -1]. +NPC id=5304, name=Zombie, level=13, option=[null, Attack, null, null, null], anims=[5565, -1]. +NPC id=5305, name=Zombie, level=13, option=[null, Attack, null, null, null], anims=[5565, -1]. +NPC id=5306, name=Zombie, level=13, option=[null, Attack, null, null, null], anims=[5565, -1]. +NPC id=5307, name=Zombie, level=13, option=[null, Attack, null, null, null], anims=[5565, -1]. +NPC id=5308, name=Zombie, level=18, option=[null, Attack, null, null, null], anims=[5565, -1]. +NPC id=5309, name=Zombie, level=18, option=[null, Attack, null, null, null], anims=[5572, -1]. +NPC id=5310, name=Zombie, level=18, option=[null, Attack, null, null, null], anims=[5565, -1]. +NPC id=5311, name=Zombie, level=18, option=[null, Attack, null, null, null], anims=[5565, -1]. +NPC id=5312, name=Zombie, level=18, option=[null, Attack, null, null, null], anims=[5565, -1]. +NPC id=5313, name=Zombie, level=18, option=[null, Attack, null, null, null], anims=[5565, -1]. +NPC id=5314, name=Zombie, level=24, option=[null, Attack, null, null, null], anims=[5572, -1]. +NPC id=5315, name=Zombie, level=24, option=[null, Attack, null, null, null], anims=[5576, -1]. +NPC id=5316, name=Zombie, level=24, option=[null, Attack, null, null, null], anims=[5572, -1]. +NPC id=5317, name=Zombie, level=24, option=[null, Attack, null, null, null], anims=[5572, -1]. +NPC id=5318, name=Zombie, level=24, option=[null, Attack, null, null, null], anims=[5572, -1]. +NPC id=5319, name=Zombie, level=24, option=[null, Attack, null, null, null], anims=[5572, -1]. +NPC id=5320, name=Zombie, level=24, option=[null, Attack, null, null, null], anims=[5565, -1]. +NPC id=5321, name=Zombie, level=24, option=[null, Attack, null, null, null], anims=[5572, -1]. +NPC id=5322, name=Zombie, level=24, option=[null, Attack, null, null, null], anims=[5576, -1]. +NPC id=5323, name=Zombie, level=24, option=[null, Attack, null, null, null], anims=[5572, -1]. +NPC id=5324, name=Zombie, level=24, option=[null, Attack, null, null, null], anims=[5572, -1]. +NPC id=5325, name=Zombie, level=24, option=[null, Attack, null, null, null], anims=[5572, -1]. +NPC id=5326, name=Zombie, level=24, option=[null, Attack, null, null, null], anims=[5572, -1]. +NPC id=5327, name=Zombie, level=24, option=[null, Attack, null, null, null], anims=[5572, -1]. +NPC id=5328, name=Zombie, level=25, option=[null, Attack, null, null, null], anims=[5572, -1]. +NPC id=5329, name=Zombie, level=25, option=[null, Attack, null, null, null], anims=[5572, -1]. +NPC id=5330, name=Zombie, level=25, option=[null, Attack, null, null, null], anims=[5572, -1]. +NPC id=5331, name=Zombie, level=25, option=[null, Attack, null, null, null], anims=[5572, -1]. +NPC id=5332, name=Skeleton, level=22, option=[null, Attack, null, null, null], anims=[5483, 5479]. +NPC id=5333, name=Skeleton, level=22, option=[null, Attack, null, null, null], anims=[5483, 5479]. +NPC id=5334, name=Skeleton, level=22, option=[null, Attack, null, null, null], anims=[5483, 5481]. +NPC id=5335, name=Skeleton, level=21, option=[null, Attack, null, null, null], anims=[5483, 5479]. +NPC id=5336, name=Skeleton, level=21, option=[null, Attack, null, null, null], anims=[5483, 5479]. +NPC id=5337, name=Skeleton, level=25, option=[null, Attack, null, null, null], anims=[5483, 5481]. +NPC id=5338, name=Skeleton, level=25, option=[null, Attack, null, null, null], anims=[5483, 5481]. +NPC id=5339, name=Skeleton, level=25, option=[null, Attack, null, null, null], anims=[5483, 5481]. +NPC id=5340, name=Skeleton, level=25, option=[null, Attack, null, null, null], anims=[5483, 5479]. +NPC id=5341, name=Skeleton, level=45, option=[null, Attack, null, null, null], anims=[5495, 5497]. +NPC id=5342, name=Ghost, level=19, option=[null, Attack, null, null, null], anims=[5530, 5531]. +NPC id=5343, name=Ghost, level=19, option=[null, Attack, null, null, null], anims=[5530, 5531]. +NPC id=5344, name=Ghost, level=19, option=[null, Attack, null, null, null], anims=[5530, 5531]. +NPC id=5345, name=Ghost, level=19, option=[null, Attack, null, null, null], anims=[5530, 5531]. +NPC id=5346, name=Ghost, level=19, option=[null, Attack, null, null, null], anims=[5530, 5531]. +NPC id=5347, name=Ghost, level=19, option=[null, Attack, null, null, null], anims=[5530, 5531]. +NPC id=5348, name=Ghost, level=19, option=[null, Attack, null, null, null], anims=[5530, 5531]. +NPC id=5349, name=Ghost, level=19, option=[null, Attack, null, null, null], anims=[5530, 5531]. +NPC id=5350, name=Ghost, level=19, option=[null, Attack, null, null, null], anims=[5530, 5531]. +NPC id=5351, name=Ghost, level=19, option=[null, Attack, null, null, null], anims=[5530, 5531]. +NPC id=5352, name=Ghost, level=19, option=[null, Attack, null, null, null], anims=[5530, 5531]. +NPC id=5353, name=Undead one, level=68, option=[null, Attack, null, null, null], anims=[5483, 5481]. +NPC id=5354, name=Undead one, level=61, option=[null, Attack, null, null, null], anims=[5483, 5481]. +NPC id=5355, name=Undead one, level=68, option=[null, Attack, null, null, null], anims=[5565, -1]. +NPC id=5356, name=Undead one, level=68, option=[null, Attack, null, null, null], anims=[5565, -1]. +NPC id=5357, name=Undead one, level=73, option=[null, Attack, null, null, null], anims=[5572, -1]. +NPC id=5358, name=Undead one, level=73, option=[null, Attack, null, null, null], anims=[5572, -1]. +NPC id=5359, name=Giant skeleton, level=80, option=[null, Attack, null, null, null], anims=[5493, 5497]. +NPC id=5360, name=Mummy ashes, level=96, option=[null, null, null, null, null], anims=[5563, 5563]. +NPC id=5361, name=Waterfiend, level=115, option=[null, Attack, null, null, null], anims=[1578, 1579]. +NPC id=5362, name=Brutal green dragon, level=227, option=[null, Attack, null, null, null], anims=[90, 79]. +NPC id=5363, name=Mithril dragon, level=304, option=[null, Attack, null, null, null], anims=[90, 79]. +NPC id=5364, name=Confused barbarian, level=132, option=[null, Attack, null, null, null], anims=[2065, 2064]. +NPC id=5365, name=Skeleton, level=60, option=[null, Attack, null, null, null], anims=[5483, 5479]. +NPC id=5366, name=Skeleton, level=60, option=[null, Attack, null, null, null], anims=[5483, 5481]. +NPC id=5367, name=Skeleton, level=85, option=[null, Attack, null, null, null], anims=[5483, 5481]. +NPC id=5368, name=Skeleton, level=85, option=[null, Attack, null, null, null], anims=[5483, 5481]. +NPC id=5369, name=Ghost, level=77, option=[null, Attack, null, null, null], anims=[5530, 5531]. +NPC id=5370, name=Ghost, level=77, option=[null, Attack, null, null, null], anims=[5530, 5531]. +NPC id=5371, name=Ghost, level=77, option=[null, Attack, null, null, null], anims=[5530, 5531]. +NPC id=5372, name=Ghost, level=76, option=[null, Attack, null, null, null], anims=[5530, 5531]. +NPC id=5373, name=Ghost, level=76, option=[null, Attack, null, null, null], anims=[5530, 5531]. +NPC id=5374, name=Ghost, level=76, option=[null, Attack, null, null, null], anims=[5530, 5531]. +NPC id=5375, name=Zombie, level=30, option=[null, Attack, null, null, null], anims=[5565, -1]. +NPC id=5376, name=Zombie, level=30, option=[null, Attack, null, null, null], anims=[5565, -1]. +NPC id=5377, name=Zombie, level=44, option=[null, Attack, null, null, null], anims=[5572, -1]. +NPC id=5378, name=Zombie, level=44, option=[null, Attack, null, null, null], anims=[5572, -1]. +NPC id=5379, name=Zombie, level=53, option=[null, Attack, null, null, null], anims=[5576, -1]. +NPC id=5380, name=Zombie, level=53, option=[null, Attack, null, null, null], anims=[5572, -1]. +NPC id=5381, name=Skeleton, level=77, option=[null, Attack, null, null, null], anims=[5483, 5481]. +NPC id=5382, name=Animated steel armour, level=53, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=5383, name=Odovacar, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[5607, 5606]. +NPC id=5384, name=Giant skeleton, level=100, option=[null, Attack, null, null, null], anims=[5493, 5497]. +NPC id=5385, name=Skeleton, level=94, option=[null, Attack, null, null, null], anims=[5483, 5479]. +NPC id=5386, name=Skeleton, level=77, option=[null, Attack, null, null, null], anims=[5483, 5481]. +NPC id=5387, name=Skeleton, level=81, option=[null, Attack, null, null, null], anims=[5483, 5481]. +NPC id=5388, name=Skeleton, level=42, option=[null, Attack, null, null, null], anims=[5483, 5481]. +NPC id=5389, name=Skeleton, level=59, option=[null, Attack, null, null, null], anims=[5483, 5481]. +NPC id=5390, name=Skeleton, level=42, option=[null, Attack, null, null, null], anims=[5483, 5481]. +NPC id=5391, name=Skeleton, level=63, option=[null, Attack, null, null, null], anims=[5483, 5479]. +NPC id=5392, name=Skeleton, level=40, option=[null, Attack, null, null, null], anims=[5483, 5479]. +NPC id=5393, name=Zombie, level=40, option=[null, Attack, null, null, null], anims=[5576, 5577]. +NPC id=5394, name=Zombie, level=42, option=[null, Attack, null, null, null], anims=[5576, 5577]. +NPC id=5395, name=Zombie, level=47, option=[null, Attack, null, null, null], anims=[5576, 5577]. +NPC id=5396, name=Zombie, level=50, option=[null, Attack, null, null, null], anims=[5576, 5577]. +NPC id=5397, name=Zombie, level=56, option=[null, Attack, null, null, null], anims=[5576, 5577]. +NPC id=5398, name=Zombie, level=61, option=[null, Attack, null, null, null], anims=[5576, 5577]. +NPC id=5399, name=Zombie, level=67, option=[null, Attack, null, null, null], anims=[5572, 5570]. +NPC id=5400, name=Zombie, level=70, option=[null, Attack, null, null, null], anims=[5572, 5570]. +NPC id=5401, name=Zombie, level=72, option=[null, Attack, null, null, null], anims=[5572, 5570]. +NPC id=5402, name=Zombie, level=76, option=[null, Attack, null, null, null], anims=[5572, 5570]. +NPC id=5403, name=Zombie, level=80, option=[null, Attack, null, null, null], anims=[5572, 5570]. +NPC id=5404, name=Zombie, level=85, option=[null, Attack, null, null, null], anims=[5572, 5570]. +NPC id=5405, name=Zombie, level=86, option=[null, Attack, null, null, null], anims=[5572, 5570]. +NPC id=5406, name=Zombie, level=90, option=[null, Attack, null, null, null], anims=[5572, 5570]. +NPC id=5407, name=Zombie, level=95, option=[null, Attack, null, null, null], anims=[5572, 5570]. +NPC id=5408, name=Zombie, level=98, option=[null, Attack, null, null, null], anims=[5572, 5570]. +NPC id=5409, name=Zombie, level=100, option=[null, Attack, null, null, null], anims=[5572, 5570]. +NPC id=5410, name=Zombie, level=81, option=[null, Attack, null, null, null], anims=[5572, 5570]. +NPC id=5411, name=Skeleton, level=72, option=[null, Attack, null, null, null], anims=[5483, 5479]. +NPC id=5412, name=Skeleton, level=87, option=[null, Attack, null, null, null], anims=[5483, 5481]. +NPC id=5413, name=Possessed pickaxe, level=50, option=[null, Attack, null, null, null], anims=[5589, 5593]. +NPC id=5414, name=Animated spade, level=50, option=[null, Attack, null, null, null], anims=[5594, 5595]. +NPC id=5415, name=Terror dog statue, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=5416, name=Terror dog statue, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=5417, name=Terror dog, level=110, option=[null, Attack, null, null, null], anims=[5623, 5622]. +NPC id=5418, name=Terror dog, level=100, option=[null, Attack, null, null, null], anims=[5623, 5622]. +NPC id=5419, name=Tarn, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=5420, name=Tarn, level=69, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=5421, name=Mutant tarn, level=69, option=[null, Attack, null, null, null], anims=[5616, 5615]. +NPC id=5422, name=Skeleton, level=77, option=[null, Attack, null, null, null], anims=[5483, 5481]. +NPC id=5423, name=null, level=0, option=[Talk-to, null, Tuxedo-time, null, null], anims=[808, -1]. +NPC id=5424, name=Larry, level=0, option=[Talk-to, null, Tuxedo-time, null, null], anims=[808, -1]. +NPC id=5425, name=Larry, level=0, option=[Talk-to, null, null, Travel, null], anims=[808, -1]. +NPC id=5426, name=Larry, level=0, option=[Talk-to, null, Tuxedo-time, Travel, null], anims=[808, -1]. +NPC (wrapper) id=5427, child npcs=[5428, 5428, 5428, -1]. +NPC id=5428, name=Penguin, level=0, option=[null, null, null, null, null], anims=[5668, 5666]. +NPC id=5429, name=Penguin, level=0, option=[Talk-to, null, null, null, null], anims=[5668, 5666]. +NPC id=5430, name=Penguin, level=0, option=[null, null, null, null, null], anims=[5668, 5666]. +NPC id=5431, name=KGP Guard, level=0, option=[null, null, null, null, null], anims=[5668, 5666]. +NPC id=5432, name=Pescaling Pax, level=0, option=[null, null, null, null, null], anims=[5668, 5666]. +NPC id=5433, name=Ping, level=0, option=[null, null, null, null, null], anims=[5673, -1]. +NPC id=5434, name=Ping, level=0, option=[null, null, null, null, null], anims=[5668, -1]. +NPC id=5435, name=Pong, level=0, option=[null, null, null, null, null], anims=[5675, -1]. +NPC id=5436, name=Pong, level=0, option=[null, null, null, null, null], anims=[5668, -1]. +NPC id=5437, name=Ping, level=0, option=[Talk-to, null, null, null, null], anims=[5668, 5666]. +NPC id=5438, name=Pong, level=0, option=[Talk-to, null, null, null, null], anims=[5668, 5666]. +NPC id=5439, name=null, level=0, option=[Talk-to, null, null, null, null], anims=[5668, 5666]. +NPC (wrapper) id=5440, child npcs=[5441, 5441, -1]. +NPC id=5441, name=KGP Agent, level=0, option=[Talk-to, null, null, null, null], anims=[5668, 5666]. +NPC id=5442, name=KGP Agent, level=0, option=[Talk-to, null, null, null, null], anims=[5668, 5666]. +NPC id=5443, name=null, level=1, option=[null, null, null, null, null], anims=[5668, 5666]. +NPC id=5444, name=Noodle, level=0, option=[Talk-to, null, null, null, null], anims=[5668, 5666]. +NPC id=5445, name=Penguin, level=0, option=[Talk-to, null, null, null, null], anims=[5668, 5666]. +NPC id=5446, name=Penguin suit, level=0, option=[Pick-up, null, null, null, null], anims=[5668, 5666]. +NPC id=5447, name=Agility Instructor, level=0, option=[Talk-to, null, null, null, null], anims=[5677, 5676]. +NPC id=5448, name=Army Commander, level=0, option=[Talk-to, null, null, null, null], anims=[5677, 5676]. +NPC id=5449, name=Penguin, level=0, option=[null, null, null, null, null], anims=[5680, -1]. +NPC id=5450, name=Penguin, level=0, option=[null, null, null, null, null], anims=[5682, -1]. +NPC id=5451, name=Penguin, level=0, option=[null, null, null, null, null], anims=[5685, -1]. +NPC id=5452, name=Icelord, level=51, option=[null, Attack, null, null, null], anims=[5722, 5721]. +NPC id=5453, name=Icelord, level=51, option=[null, Attack, null, null, null], anims=[5722, 5721]. +NPC id=5454, name=Icelord, level=51, option=[null, Attack, null, null, null], anims=[5722, 5721]. +NPC id=5455, name=Icelord, level=51, option=[null, Attack, null, null, null], anims=[5722, 5721]. +NPC id=5456, name=Crusher, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=5457, name=Crusher, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=5458, name=Crusher, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=5459, name=Crusher, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=5460, name=Tree, level=0, option=[Chop down, null, hidden, null, null], anims=[5750, 5750]. +NPC id=5461, name=Jungle Tree, level=0, option=[Chop down, null, hidden, null, null], anims=[5751, 5751]. +NPC id=5462, name=Tolna, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5463, name=Honour guard, level=0, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=5464, name=Honour guard, level=0, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=5465, name=Fridleif Shieldson, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=5466, name=Thakkrad Sigmundson, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=5467, name=Iceberg, level=0, option=[null, null, null, null, null], anims=[5770, 5770]. +NPC id=5468, name=Iceberg, level=0, option=[null, null, null, null, null], anims=[5770, 5770]. +NPC id=5469, name=Arctic Pine, level=0, option=[Chop down, null, hidden, null, null], anims=[5773, 5773]. +NPC id=5470, name=Fishing spot, level=0, option=[Cage, null, Harpoon, hidden, hidden], anims=[447, 448]. +NPC id=5471, name=Fishing spot, level=0, option=[Net, null, Harpoon, hidden, hidden], anims=[447, 448]. +NPC id=5472, name=Ice Troll King, level=122, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=5473, name=Ice troll runt, level=74, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=5474, name=Ice troll male, level=82, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=5475, name=Ice troll female, level=82, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=5476, name=Ice troll grunt, level=102, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=5477, name=Bork Sigmundson, level=0, option=[Talk-to, null, Request-supplies, null, null], anims=[808, -1]. +NPC id=5478, name=King Gjuki Sorvott IV, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5479, name=HRH Hrafn, level=0, option=[Talk-to, null, null, null, null], anims=[9158, 9157]. +NPC id=5480, name=Thorkel Silkbeard, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5481, name=Mord Gunnars, level=0, option=[Talk-to, null, Ferry-Jatizso, null, null], anims=[808, -1]. +NPC id=5482, name=Mord Gunnars, level=0, option=[Talk-to, null, Ferry-Rellekka, null, null], anims=[808, -1]. +NPC id=5483, name=Hring Hring, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=5484, name=Flosi Dalksson, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=5485, name=Raum Urda-Stein, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=5486, name=Skuli Myrka, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=5487, name=Keepa Kettilon, level=0, option=[Talk-to, null, Trade, null, null], anims=[813, -1]. +NPC id=5488, name=Magnus Gram, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[808, -1]. +NPC id=5489, name=Guard, level=0, option=[Talk-to, null, Watch-shouting, null, null], anims=[808, -1]. +NPC id=5490, name=Guard, level=0, option=[Talk-to, null, Watch-shouting, null, null], anims=[813, -1]. +NPC id=5491, name=Guard, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5492, name=Guard, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5493, name=Freygerd, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5494, name=Lensa, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5495, name=Vanligga Gastfrihet, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5496, name=Sassilik, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5497, name=Miner, level=0, option=[Talk-to, null, null, null, null], anims=[627, -1]. +NPC id=5498, name=Miner, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5499, name=Eric, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5500, name=Gruva Patrull, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5501, name=Brendt, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=5502, name=Grundt, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=5503, name=Mawnis Burowgar, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5504, name=Mawnis Burowgar, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5505, name=Fridleif Shieldson, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5506, name=Thakkrad Sigmundson, level=0, option=[Talk-to, null, Craft-goods, null, null], anims=[808, -1]. +NPC id=5507, name=Maria Gunnars, level=0, option=[Talk-to, null, Ferry-Rellekka, null, null], anims=[808, -1]. +NPC id=5508, name=Maria Gunnars, level=0, option=[Talk-to, null, Ferry-Neitiznot, null, null], anims=[808, -1]. +NPC id=5509, name=Jofridr Mordstatter, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=5510, name=Morten Holdstrom, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5511, name=Gunnar Holdstrom, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5512, name=Anne Isaakson, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5513, name=Lisse Isaakson, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5514, name=Honour guard, level=115, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=5515, name=Honour guard, level=115, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5516, name=Honour guard, level=115, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5517, name=Honour guard, level=115, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=5518, name=Kjedelig Uppsen, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=5519, name=Trogen Konungarde, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=5520, name=Slug Hemligssen, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5521, name=Ice troll runt, level=74, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=5522, name=Ice troll male, level=82, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=5523, name=Ice troll female, level=82, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=5524, name=Ice troll grunt, level=100, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=5525, name=Ice troll runt, level=74, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=5526, name=Ice troll male, level=82, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=5527, name=Ice troll female, level=82, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=5528, name=Ice troll grunt, level=100, option=[null, Attack, null, null, null], anims=[286, 283]. +NPC id=5529, name=Yak, level=22, option=[null, Attack, null, null, null], anims=[5785, 5781]. +NPC (wrapper) id=5530, child npcs=[5503, 5504, -1]. +NPC id=5531, name=Sorceress, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5532, name=Apprentice, level=0, option=[Talk-to, null, null, Teleport, null], anims=[5800, 5799]. +NPC id=5533, name=Autumn Elemental, level=0, option=[null, null, null, null, null], anims=[5801, 5802]. +NPC id=5534, name=Autumn Elemental, level=0, option=[null, null, null, null, null], anims=[5801, 5802]. +NPC id=5535, name=Autumn Elemental, level=0, option=[null, null, null, null, null], anims=[5801, 5802]. +NPC id=5536, name=Autumn Elemental, level=0, option=[null, null, null, null, null], anims=[5801, 5802]. +NPC id=5537, name=Autumn Elemental, level=0, option=[null, null, null, null, null], anims=[5801, 5802]. +NPC id=5538, name=Autumn Elemental, level=0, option=[null, null, null, null, null], anims=[5801, 5802]. +NPC id=5539, name=Spring Elemental, level=0, option=[null, null, null, null, null], anims=[5801, 5802]. +NPC id=5540, name=Spring Elemental, level=0, option=[null, null, null, null, null], anims=[5801, 5802]. +NPC id=5541, name=Spring Elemental, level=0, option=[null, null, null, null, null], anims=[5801, 5802]. +NPC id=5542, name=Spring Elemental, level=0, option=[null, null, null, null, null], anims=[5801, 5802]. +NPC id=5543, name=Spring Elemental, level=0, option=[null, null, null, null, null], anims=[5801, 5802]. +NPC id=5544, name=Spring Elemental, level=0, option=[null, null, null, null, null], anims=[5801, 5802]. +NPC id=5545, name=Spring Elemental, level=0, option=[null, null, null, null, null], anims=[5801, 5802]. +NPC id=5546, name=Spring Elemental, level=0, option=[null, null, null, null, null], anims=[5801, 5802]. +NPC id=5547, name=Summer Elemental, level=0, option=[null, null, null, null, null], anims=[5801, 5802]. +NPC id=5548, name=Summer Elemental, level=0, option=[null, null, null, null, null], anims=[5801, 5802]. +NPC id=5549, name=Summer Elemental, level=0, option=[null, null, null, null, null], anims=[5801, 5802]. +NPC id=5550, name=Summer Elemental, level=0, option=[null, null, null, null, null], anims=[5801, 5802]. +NPC id=5551, name=Summer Elemental, level=0, option=[null, null, null, null, null], anims=[5801, 5802]. +NPC id=5552, name=Summer Elemental, level=0, option=[null, null, null, null, null], anims=[5801, 5802]. +NPC id=5553, name=Winter Elemental, level=0, option=[null, null, null, null, null], anims=[5803, 5802]. +NPC id=5554, name=Winter Elemental, level=0, option=[null, null, null, null, null], anims=[5803, 5802]. +NPC id=5555, name=Winter Elemental, level=0, option=[null, null, null, null, null], anims=[5803, 5802]. +NPC id=5556, name=Winter Elemental, level=0, option=[null, null, null, null, null], anims=[5803, 5802]. +NPC id=5557, name=Winter Elemental, level=0, option=[null, null, null, null, null], anims=[5803, 5802]. +NPC id=5558, name=Winter Elemental, level=0, option=[null, null, null, null, null], anims=[5803, 5802]. +NPC id=5559, name=Osman, level=0, option=[Talk-to, null, null, null, null], anims=[3396, 3396]. +NPC id=5560, name=Osman, level=0, option=[Talk-to, null, null, null, null], anims=[3396, 3396]. +NPC id=5561, name=Osman, level=0, option=[Inspect, null, null, null, null], anims=[3359, 3359]. +NPC id=5562, name=null, level=0, option=[null, null, null, null, null], anims=[4753, 4754]. +NPC id=5563, name=Del-Monty, level=0, option=[Talk-to, null, null, null, null], anims=[9158, 9157]. +NPC id=5564, name=Bouncer, level=160, option=[null, Attack, null, null, null], anims=[6580, 6582]. +NPC id=5565, name=Bouncer, level=160, option=[null, Attack, null, null, null], anims=[6580, 6582]. +NPC id=5566, name=General Khazard, level=0, option=[Talk-to, null, null, null, null], anims=[842, 841]. +NPC id=5567, name=Scout, level=0, option=[Talk-to, null, null, null, null], anims=[842, 841]. +NPC id=5568, name=Scout, level=0, option=[Talk-to, null, null, null, null], anims=[842, 841]. +NPC id=5569, name=Scout, level=0, option=[Talk-to, null, null, null, null], anims=[842, 841]. +NPC id=5570, name=Scout, level=0, option=[Talk-to, null, null, null, null], anims=[842, 841]. +NPC id=5571, name=Sin Seer, level=0, option=[Talk-to, null, null, null, null], anims=[5810, 5809]. +NPC id=5572, name=Ghost, level=0, option=[Talk-To, null, null, null, null], anims=[808, -1]. +NPC id=5573, name=null, level=0, option=[null, null, null, null, null], anims=[842, 841]. +NPC id=5574, name=null, level=0, option=[null, null, null, null, null], anims=[842, 841]. +NPC id=5575, name=null, level=0, option=[null, null, null, null, null], anims=[842, 841]. +NPC id=5576, name=null, level=0, option=[null, null, null, null, null], anims=[842, 841]. +NPC id=5577, name=null, level=0, option=[null, null, null, null, null], anims=[842, 841]. +NPC id=5578, name=Effigy, level=0, option=[Talk-to, null, null, null, null], anims=[808, 5822]. +NPC id=5579, name=Effigy, level=0, option=[null, null, null, null, null], anims=[808, 5822]. +NPC id=5580, name=Bonafido, level=0, option=[Talk-to, null, null, null, null], anims=[5814, -1]. +NPC id=5581, name=Homunculus, level=0, option=[Talk-to, null, null, null, null], anims=[5831, 5832]. +NPC id=5582, name=Homunculus, level=0, option=[Talk-to, null, null, null, null], anims=[5831, -1]. +NPC id=5583, name=Homunculus, level=0, option=[Talk-to, null, null, null, null], anims=[5831, -1]. +NPC id=5584, name=Cage, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=5585, name='Transmute' The Alchemist, level=0, option=[Talk-to, null, null, null, null], anims=[5823, 5822]. +NPC id=5586, name='Transmute' The Alchemist, level=0, option=[null, null, null, null, null], anims=[808, 5822]. +NPC id=5587, name='Currency' The Alchemist, level=0, option=[Talk-to, null, null, null, null], anims=[5823, 5822]. +NPC id=5588, name='Currency' The Alchemist, level=0, option=[null, null, null, null, null], anims=[808, 5822]. +NPC id=5589, name='Black-eye', level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[5817, -1]. +NPC id=5590, name='No fingers', level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[5815, -1]. +NPC id=5591, name='Gummy', level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[5816, -1]. +NPC id=5592, name='The Guns', level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[5818, -1]. +NPC id=5593, name=Frogeel, level=103, option=[null, Attack, null, null, null], anims=[5839, 5840]. +NPC id=5594, name=Spidine, level=42, option=[null, Attack, null, null, null], anims=[145, 142]. +NPC id=5595, name=Swordchick, level=46, option=[null, Attack, null, null, null], anims=[5386, 5385]. +NPC id=5596, name=Jubster, level=87, option=[null, Attack, null, null, null], anims=[6803, 6804]. +NPC id=5597, name=Newtroost, level=19, option=[null, Attack, null, null, null], anims=[2298, 2297]. +NPC (wrapper) id=5598, child npcs=[5578, -1, 5578, 5578, 5578, -1, 5578, -1, 5578, -1, -1, 5578, 5578, -1, 5578, -1, 5578, -1]. +NPC id=5599, name=null, level=0, option=[null, null, null, null, null], anims=[5831, -1]. +NPC id=5600, name=null, level=0, option=[null, null, null, null, null], anims=[5831, -1]. +NPC (wrapper) id=5601, child npcs=[5585, -1, 5585, 5585, 5585, -1, 5585, -1, 5585, -1, -1, 5585, 5585, -1, 5585, -1, 5585, -1]. +NPC (wrapper) id=5602, child npcs=[5587, -1, 5587, 5587, 5587, -1, 5587, -1, 5587, -1, -1, 5587, 5587, -1, 5587, -1, 5587, -1]. +NPC id=5603, name=Unicow, level=25, option=[null, Attack, null, null, null], anims=[5852, 5848]. +NPC id=5604, name=Elfinlocks, level=93, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=5605, name=Clockwork cat, level=0, option=[null, null, null, null, null], anims=[9158, 9157]. +NPC id=5606, name=null, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[808, -1]. +NPC id=5607, name=Clockwork cat, level=0, option=[null, null, null, null, null], anims=[9158, 9157]. +NPC id=5608, name=Monk, level=0, option=[Talk-to, null, null, null, null], anims=[5877, 5876]. +NPC id=5609, name=Monk, level=0, option=[Talk-to, null, null, null, null], anims=[5877, 5876]. +NPC id=5610, name=Monk, level=0, option=[Talk-to, null, null, null, null], anims=[5877, 5876]. +NPC id=5611, name=Monk, level=0, option=[Talk-to, null, null, null, null], anims=[5877, 5876]. +NPC id=5612, name=Rufus, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=5613, name=Mi-Gor, level=0, option=[Confront, null, null, null, null], anims=[5859, 5858]. +NPC id=5614, name=Puffin, level=0, option=[null, null, null, null, null], anims=[5873, 5872]. +NPC id=5615, name=Puffin, level=0, option=[null, null, null, null, null], anims=[5873, -1]. +NPC id=5616, name=Brother Tranquility, level=0, option=[Talk-to, null, Transport, null, null], anims=[5875, 5876]. +NPC id=5617, name=Brother Tranquility, level=0, option=[Talk-to, null, Transport, null, null], anims=[5646, 5645]. +NPC id=5618, name=Brother Tranquility, level=0, option=[Talk-to, null, null, null, null], anims=[5646, 5645]. +NPC id=5619, name=Monk, level=0, option=[Talk-to, null, null, null, null], anims=[5646, 5645]. +NPC id=5620, name=Monk, level=0, option=[Talk-to, null, null, null, null], anims=[5646, 5645]. +NPC id=5621, name=Monk, level=0, option=[Talk-to, null, null, null, null], anims=[5646, 5645]. +NPC id=5622, name=Monk, level=0, option=[Talk-to, null, null, null, null], anims=[5646, 5645]. +NPC id=5623, name=Zombie monk, level=0, option=[Talk-to, null, null, null, null], anims=[5877, 5876]. +NPC id=5624, name=Zombie monk, level=0, option=[Talk-to, null, null, null, null], anims=[5877, 5876]. +NPC id=5625, name=Zombie monk, level=0, option=[Talk-to, null, null, null, null], anims=[5877, 5876]. +NPC id=5626, name=Zombie monk, level=0, option=[Talk-to, null, null, null, null], anims=[5877, 5876]. +NPC id=5627, name=Sorebones, level=57, option=[null, Attack, null, null, null], anims=[5641, 5642]. +NPC id=5628, name=Sorebones, level=57, option=[null, Attack, null, null, null], anims=[5641, 5642]. +NPC id=5629, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5646, 5645]. +NPC id=5630, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5646, 5645]. +NPC id=5631, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5646, 5645]. +NPC id=5632, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5646, 5645]. +NPC id=5633, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5646, 5645]. +NPC id=5634, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5646, 5645]. +NPC id=5635, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5646, 5645]. +NPC id=5636, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5646, 5645]. +NPC id=5637, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5650, 5652]. +NPC id=5638, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5650, 5652]. +NPC id=5639, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5650, 5652]. +NPC id=5640, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5650, 5652]. +NPC id=5641, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5650, 5652]. +NPC id=5642, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5879, 5878]. +NPC id=5643, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5879, 5878]. +NPC id=5644, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5879, 5878]. +NPC id=5645, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5879, 5878]. +NPC id=5646, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5879, 5878]. +NPC id=5647, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5883, 5882]. +NPC id=5648, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5883, 5882]. +NPC id=5649, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5883, 5882]. +NPC id=5650, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5883, 5882]. +NPC id=5651, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5883, 5882]. +NPC id=5652, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5883, 5882]. +NPC id=5653, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5883, 5882]. +NPC id=5654, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5883, 5882]. +NPC id=5655, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5883, 5882]. +NPC id=5656, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5888, 5887]. +NPC id=5657, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5888, 5887]. +NPC id=5658, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5888, 5887]. +NPC id=5659, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5888, 5887]. +NPC id=5660, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5888, 5887]. +NPC id=5661, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5888, 5887]. +NPC id=5662, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5888, 5887]. +NPC id=5663, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5888, 5887]. +NPC id=5664, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5888, 5887]. +NPC id=5665, name=Zombie pirate, level=57, option=[null, Attack, null, null, null], anims=[5888, 5887]. +NPC id=5666, name=Barrelchest, level=190, option=[null, Attack, null, null, null], anims=[5893, 5892]. +NPC (wrapper) id=5667, child npcs=[5616, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5616, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5616, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5616, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5616, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5616, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5616, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5616, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5616, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5616, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5617, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5617, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5617, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5617, -1]. +NPC (wrapper) id=5668, child npcs=[5616, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5616, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5616, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5616, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5616, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5616, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5616, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5616, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5616, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5616, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5617, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5617, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5617, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5617, -1]. +NPC (wrapper) id=5669, child npcs=[5623, 5608, -1]. +NPC (wrapper) id=5670, child npcs=[5624, 5609, -1]. +NPC (wrapper) id=5671, child npcs=[5625, 5610, -1]. +NPC (wrapper) id=5672, child npcs=[5626, 5611, -1]. +NPC (wrapper) id=5673, child npcs=[5619, -1]. +NPC (wrapper) id=5674, child npcs=[5620, -1]. +NPC (wrapper) id=5675, child npcs=[5621, -1]. +NPC (wrapper) id=5676, child npcs=[5622, -1]. +NPC (wrapper) id=5677, child npcs=[5618, -1]. +NPC id=5678, name=Undead Lumberjack, level=30, option=[null, Attack, null, null, null], anims=[5967, 5967]. +NPC id=5679, name=Undead Lumberjack, level=30, option=[null, Attack, null, null, null], anims=[5973, 5969]. +NPC id=5680, name=Undead Lumberjack, level=30, option=[null, Attack, null, null, null], anims=[5965, 5965]. +NPC id=5681, name=Undead Lumberjack, level=30, option=[null, Attack, null, null, null], anims=[5966, 5966]. +NPC id=5682, name=Undead Lumberjack, level=30, option=[null, Attack, null, null, null], anims=[5967, 5967]. +NPC id=5683, name=Undead Lumberjack, level=30, option=[null, Attack, null, null, null], anims=[5973, 5969]. +NPC id=5684, name=Undead Lumberjack, level=35, option=[null, Attack, null, null, null], anims=[5965, 5965]. +NPC id=5685, name=Undead Lumberjack, level=35, option=[null, Attack, null, null, null], anims=[5966, 5966]. +NPC id=5686, name=Undead Lumberjack, level=35, option=[null, Attack, null, null, null], anims=[5967, 5967]. +NPC id=5687, name=Undead Lumberjack, level=35, option=[null, Attack, null, null, null], anims=[5973, 5969]. +NPC id=5688, name=Undead Lumberjack, level=35, option=[null, Attack, null, null, null], anims=[5965, 5965]. +NPC id=5689, name=Undead Lumberjack, level=35, option=[null, Attack, null, null, null], anims=[5966, 5966]. +NPC id=5690, name=Undead Lumberjack, level=35, option=[null, Attack, null, null, null], anims=[5967, 5967]. +NPC id=5691, name=Undead Lumberjack, level=35, option=[null, Attack, null, null, null], anims=[5973, 5969]. +NPC id=5692, name=Undead Lumberjack, level=40, option=[null, Attack, null, null, null], anims=[5965, 5965]. +NPC id=5693, name=Undead Lumberjack, level=40, option=[null, Attack, null, null, null], anims=[5966, 5966]. +NPC id=5694, name=Undead Lumberjack, level=40, option=[null, Attack, null, null, null], anims=[5967, 5967]. +NPC id=5695, name=Undead Lumberjack, level=40, option=[null, Attack, null, null, null], anims=[5973, 5969]. +NPC id=5696, name=Undead Lumberjack, level=40, option=[null, Attack, null, null, null], anims=[5965, 5965]. +NPC id=5697, name=Undead Lumberjack, level=40, option=[null, Attack, null, null, null], anims=[5966, 5966]. +NPC id=5698, name=Undead Lumberjack, level=40, option=[null, Attack, null, null, null], anims=[5967, 5967]. +NPC id=5699, name=Undead Lumberjack, level=40, option=[null, Attack, null, null, null], anims=[5973, 5969]. +NPC id=5700, name=Undead Lumberjack, level=45, option=[null, Attack, null, null, null], anims=[5965, 5965]. +NPC id=5701, name=Undead Lumberjack, level=45, option=[null, Attack, null, null, null], anims=[5966, 5966]. +NPC id=5702, name=Undead Lumberjack, level=45, option=[null, Attack, null, null, null], anims=[5967, 5967]. +NPC id=5703, name=Undead Lumberjack, level=45, option=[null, Attack, null, null, null], anims=[5973, 5969]. +NPC id=5704, name=Undead Lumberjack, level=45, option=[null, Attack, null, null, null], anims=[5965, 5965]. +NPC id=5705, name=Undead Lumberjack, level=45, option=[null, Attack, null, null, null], anims=[5966, 5966]. +NPC id=5706, name=Undead Lumberjack, level=45, option=[null, Attack, null, null, null], anims=[5967, 5967]. +NPC id=5707, name=Undead Lumberjack, level=45, option=[null, Attack, null, null, null], anims=[5973, 5969]. +NPC id=5708, name=Undead Lumberjack, level=50, option=[null, Attack, null, null, null], anims=[5965, 5965]. +NPC id=5709, name=Undead Lumberjack, level=50, option=[null, Attack, null, null, null], anims=[5966, 5966]. +NPC id=5710, name=Undead Lumberjack, level=50, option=[null, Attack, null, null, null], anims=[5967, 5967]. +NPC id=5711, name=Undead Lumberjack, level=50, option=[null, Attack, null, null, null], anims=[5973, 5969]. +NPC id=5712, name=Undead Lumberjack, level=50, option=[null, Attack, null, null, null], anims=[5965, 5965]. +NPC id=5713, name=Undead Lumberjack, level=50, option=[null, Attack, null, null, null], anims=[5966, 5966]. +NPC id=5714, name=Undead Lumberjack, level=50, option=[null, Attack, null, null, null], anims=[5967, 5967]. +NPC id=5715, name=Undead Lumberjack, level=50, option=[null, Attack, null, null, null], anims=[5973, 5969]. +NPC id=5716, name=Undead Lumberjack, level=55, option=[null, Attack, null, null, null], anims=[5965, 5965]. +NPC id=5717, name=Undead Lumberjack, level=55, option=[null, Attack, null, null, null], anims=[5966, 5966]. +NPC id=5718, name=Undead Lumberjack, level=55, option=[null, Attack, null, null, null], anims=[5967, 5967]. +NPC id=5719, name=Undead Lumberjack, level=55, option=[null, Attack, null, null, null], anims=[5973, 5969]. +NPC id=5720, name=Undead Lumberjack, level=55, option=[null, Attack, null, null, null], anims=[5965, 5965]. +NPC id=5721, name=Undead Lumberjack, level=55, option=[null, Attack, null, null, null], anims=[5966, 5966]. +NPC id=5722, name=Undead Lumberjack, level=55, option=[null, Attack, null, null, null], anims=[5967, 5967]. +NPC id=5723, name=Undead Lumberjack, level=55, option=[null, Attack, null, null, null], anims=[5973, 5969]. +NPC id=5724, name=Undead Lumberjack, level=60, option=[null, Attack, null, null, null], anims=[5965, 5965]. +NPC id=5725, name=Undead Lumberjack, level=60, option=[null, Attack, null, null, null], anims=[5966, 5966]. +NPC id=5726, name=Undead Lumberjack, level=60, option=[null, Attack, null, null, null], anims=[5967, 5967]. +NPC id=5727, name=Undead Lumberjack, level=60, option=[null, Attack, null, null, null], anims=[5973, 5969]. +NPC id=5728, name=Undead Lumberjack, level=60, option=[null, Attack, null, null, null], anims=[5965, 5965]. +NPC id=5729, name=Undead Lumberjack, level=60, option=[null, Attack, null, null, null], anims=[5966, 5966]. +NPC id=5730, name=Undead Lumberjack, level=60, option=[null, Attack, null, null, null], anims=[5967, 5967]. +NPC id=5731, name=Undead Lumberjack, level=60, option=[null, Attack, null, null, null], anims=[5973, 5969]. +NPC id=5732, name=Undead Lumberjack, level=64, option=[null, Attack, null, null, null], anims=[5965, 5965]. +NPC id=5733, name=Undead Lumberjack, level=64, option=[null, Attack, null, null, null], anims=[5966, 5966]. +NPC id=5734, name=Undead Lumberjack, level=64, option=[null, Attack, null, null, null], anims=[5967, 5967]. +NPC id=5735, name=Undead Lumberjack, level=64, option=[null, Attack, null, null, null], anims=[5973, 5969]. +NPC id=5736, name=Undead Lumberjack, level=64, option=[null, Attack, null, null, null], anims=[5965, 5965]. +NPC id=5737, name=Undead Lumberjack, level=64, option=[null, Attack, null, null, null], anims=[5966, 5966]. +NPC id=5738, name=Undead Lumberjack, level=64, option=[null, Attack, null, null, null], anims=[5967, 5967]. +NPC id=5739, name=Undead Lumberjack, level=64, option=[null, Attack, null, null, null], anims=[5973, 5969]. +NPC id=5740, name=Undead Lumberjack, level=70, option=[null, Attack, null, null, null], anims=[5965, 5965]. +NPC id=5741, name=Undead Lumberjack, level=70, option=[null, Attack, null, null, null], anims=[5966, 5966]. +NPC id=5742, name=Undead Lumberjack, level=70, option=[null, Attack, null, null, null], anims=[5967, 5967]. +NPC id=5743, name=Undead Lumberjack, level=70, option=[null, Attack, null, null, null], anims=[5973, 5969]. +NPC id=5744, name=Undead Lumberjack, level=70, option=[null, Attack, null, null, null], anims=[5965, 5965]. +NPC id=5745, name=Undead Lumberjack, level=70, option=[null, Attack, null, null, null], anims=[5966, 5966]. +NPC id=5746, name=Undead Lumberjack, level=70, option=[null, Attack, null, null, null], anims=[5967, 5967]. +NPC id=5747, name=Undead Lumberjack, level=70, option=[null, Attack, null, null, null], anims=[5973, 5969]. +NPC id=5748, name=Fishing spot, level=0, option=[Net, null, Bait, hidden, hidden], anims=[2126, 2126]. +NPC id=5749, name=Fishing spot, level=0, option=[Net, null, Bait, hidden, hidden], anims=[2126, 2126]. +NPC id=5750, name=Cave bug, level=96, option=[null, Attack, null, null, null], anims=[6078, 6077]. +NPC id=5751, name=Molanisk, level=51, option=[null, Attack, null, null, null], anims=[6010, 6011]. +NPC id=5752, name=Cave goblin, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[6040, 6041]. +NPC id=5753, name=Cave goblin, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[6040, 6041]. +NPC id=5754, name=Cave goblin, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[6040, 6041]. +NPC id=5755, name=Cave goblin, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[6040, 6041]. +NPC id=5756, name=Cave goblin, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[6040, 6041]. +NPC id=5757, name=Cave goblin, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[6040, 6041]. +NPC id=5758, name=Cave goblin, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[6040, 6041]. +NPC id=5759, name=Cave goblin, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[6040, 6041]. +NPC id=5760, name=Cave goblin, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[6040, 6041]. +NPC id=5761, name=Cave goblin, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[6040, 6041]. +NPC id=5762, name=Cave goblin, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[6040, 6041]. +NPC id=5763, name=Cave goblin, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[6040, 6041]. +NPC id=5764, name=Cave goblin, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[6040, 6041]. +NPC id=5765, name=Cave goblin, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[6040, 6041]. +NPC id=5766, name=Cave goblin, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[6040, 6041]. +NPC id=5767, name=Cave goblin, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[6040, 6041]. +NPC id=5768, name=Cave goblin, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[6040, 6041]. +NPC id=5769, name=Cave goblin, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[6040, 6041]. +NPC id=5770, name=Ur-zek, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=5771, name=Ur-vass, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=5772, name=Ur-taal, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=5773, name=Ur-meg, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=5774, name=Ur-lun, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=5775, name=Ur-pel, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=5776, name=Banker, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[6040, 6041]. +NPC id=5777, name=Banker, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[6040, 6041]. +NPC id=5778, name=Bartak, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=5779, name=Turgall, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=5780, name=Reldak, level=0, option=[Talk-to, null, Trade, null, null], anims=[6040, 6041]. +NPC id=5781, name=Miltog, level=0, option=[Talk-to, null, Trade, null, null], anims=[6040, 6041]. +NPC id=5782, name=Mernik, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=5783, name=Cave goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=5784, name=Crate goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6043, 6044]. +NPC id=5785, name=Cave goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=5786, name=Goblin scribe, level=0, option=[Talk-to, null, null, null, null], anims=[6045, 6046]. +NPC (wrapper) id=5787, child npcs=[6392, 6392, 6392, 6392, 6392, 6392, 6392, 6392, 6392, 6392, 6392, 6392, 6392, 6392, 6392, 6392, -1, -1, 6392, -1]. +NPC id=5788, name=Gourmet, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=5789, name=Gourmet, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=5790, name=Gourmet, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=5791, name=Gourmet, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=5792, name=Turgok, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=5793, name=Markog, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=5794, name=Durgok, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=5795, name=Tindar, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=5796, name=Gundik, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=5797, name=Zenkog, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=5798, name=Lurgon, level=0, option=[Talk-to, null, Trade, null, null], anims=[6040, 6041]. +NPC id=5799, name=Ur-tag, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=5800, name=Guard, level=26, option=[Talk-to, Attack, null, null, null], anims=[6040, 6041]. +NPC id=5801, name=Guard, level=24, option=[Talk-to, Attack, null, null, null], anims=[6040, 6041]. +NPC id=5802, name=null, level=1, option=[null, null, null, null, null], anims=[6040, 6041]. +NPC id=5803, name=Young 'un, level=0, option=[Talk-to, null, null, null, null], anims=[6058, 6057]. +NPC id=5804, name=Tyke, level=0, option=[Talk-to, null, null, null, null], anims=[6059, 6057]. +NPC id=5805, name=Nipper, level=0, option=[Talk-to, null, null, null, null], anims=[6058, 6057]. +NPC id=5806, name=Nipper, level=0, option=[Talk-to, null, null, null, null], anims=[6059, 6057]. +NPC id=5807, name=Cave goblin child, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6042]. +NPC id=5808, name=Cave goblin child, level=0, option=[Talk-to, null, null, null, null], anims=[6052, 6053]. +NPC id=5809, name=Cave goblin child, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6042]. +NPC id=5810, name=Cave goblin child, level=0, option=[Talk-to, null, null, null, null], anims=[6052, 6053]. +NPC id=5811, name=Cave goblin child, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6042]. +NPC id=5812, name=Cave goblin child, level=0, option=[Talk-to, null, null, null, null], anims=[6052, 6053]. +NPC id=5813, name=Cave goblin child, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6042]. +NPC id=5814, name=Cave goblin child, level=0, option=[Talk-to, null, null, null, null], anims=[6052, 6053]. +NPC id=5815, name=Cave goblin child, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6042]. +NPC id=5816, name=Cave goblin child, level=0, option=[Talk-to, null, null, null, null], anims=[6052, 6053]. +NPC id=5817, name=Cave goblin child, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6042]. +NPC id=5818, name=Cave goblin child, level=0, option=[Talk-to, null, null, null, null], anims=[6052, 6053]. +NPC id=5819, name=Cave goblin child, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6042]. +NPC id=5820, name=Cave goblin child, level=0, option=[Talk-to, null, null, null, null], anims=[6052, 6053]. +NPC id=5821, name=Cave goblin child, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6042]. +NPC id=5822, name=Cave goblin child, level=0, option=[Talk-to, null, null, null, null], anims=[6052, 6053]. +NPC id=5823, name=Spit goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6060, 6041]. +NPC id=5824, name=Goblin fish, level=0, option=[null, null, null, null, null], anims=[6062, 6061]. +NPC id=5825, name=Movario, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[6075, 6076]. +NPC id=5826, name=Darve, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5827, name=Moths, level=0, option=[null, null, null, null, null], anims=[6036, 6036]. +NPC id=5828, name=Barlak, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=5829, name=Rabbit, level=2, option=[null, Attack, null, null, null], anims=[6089, 6088]. +NPC id=5830, name=null, level=1, option=[null, null, null, null, null], anims=[6075, 6076]. +NPC id=5831, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC (wrapper) id=5832, child npcs=[5863, 5863, 5863, 5863, 5863, 5863, 5863, 5863, 5863, 5863, 5863, -1]. +NPC id=5833, name=Rat Burgiss, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5834, name=Surok Magis, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5835, name=Surok Magis, level=0, option=[Talk-To, null, null, null, null], anims=[808, -1]. +NPC id=5836, name=Zaff, level=0, option=[null, null, null, null, null], anims=[813, -1]. +NPC id=5837, name=Anna Jones, level=0, option=[Talk-To, null, null, null, null], anims=[6106, -1]. +NPC id=5838, name=King Roald, level=47, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=5839, name=Mishkal'un Dorn, level=0, option=[Talk-To, null, null, null, null], anims=[808, -1]. +NPC id=5840, name=Dakh'thoulan Aegis, level=0, option=[Talk-To, null, null, null, null], anims=[808, -1]. +NPC id=5841, name=Sil'as Dahcsnu, level=0, option=[Talk-To, null, null, null, null], anims=[808, -1]. +NPC id=5842, name=Outlaw, level=32, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=5843, name=Outlaw, level=32, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=5844, name=Outlaw, level=32, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=5845, name=Outlaw, level=32, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=5846, name=Outlaw, level=32, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=5847, name=Outlaw, level=32, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=5848, name=Outlaw, level=32, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=5849, name=Outlaw, level=32, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=5850, name=Outlaw, level=32, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=5851, name=Outlaw, level=32, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=5852, name=Monkey, level=1, option=[null, null, null, null, null], anims=[222, 219]. +NPC (wrapper) id=5853, child npcs=[5834, 5835, 7000, -1]. +NPC id=5854, name=Bench, level=0, option=[null, null, null, null, null], anims=[6106, -1]. +NPC id=5855, name=Goblin, level=0, option=[null, null, null, null, null], anims=[6186, 6187]. +NPC id=5856, name=Goblin, level=0, option=[null, null, null, null, null], anims=[6181, 6193]. +NPC id=5857, name=Zanik, level=0, option=[null, null, null, null, null], anims=[6040, 6215]. +NPC id=5858, name=Ur-tag, level=0, option=[null, null, null, null, null], anims=[6040, 6041]. +NPC id=5859, name=H.A.M. Archer, level=30, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=5860, name=H.A.M. Mage, level=30, option=[null, Attack, null, null, null], anims=[813, -1]. +NPC id=5861, name=Zanik, level=0, option=[Talk-to, null, null, null, null], anims=[6149, -1]. +NPC id=5862, name=Sigmund and Zanik, level=0, option=[null, null, null, null, null], anims=[6151, 6150]. +NPC id=5863, name=Ambassador Alvijar, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=5864, name=Builder, level=0, option=[Talk-to, null, null, null, null], anims=[6205, 98]. +NPC id=5865, name=Builder, level=0, option=[Talk-to, null, null, null, null], anims=[6206, 98]. +NPC id=5866, name=Builder, level=0, option=[Talk-to, null, null, null, null], anims=[6207, 98]. +NPC id=5867, name=Builder, level=0, option=[Talk-to, null, null, null, null], anims=[6208, 98]. +NPC id=5868, name=Tegdak, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=5869, name=null, level=1, option=[null, null, null, null, null], anims=[6040, 6041]. +NPC id=5870, name=Zanik, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=5871, name=Sergeant Mossfists, level=51, option=[Talk-to, null, null, null, null], anims=[6153, 6152]. +NPC id=5872, name=Sergeant Slimetoes, level=51, option=[Talk-to, null, null, null, null], anims=[6153, 6152]. +NPC id=5873, name=Cave goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=5874, name=Cave goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=5875, name=Cave goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=5876, name=Cave goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=5877, name=Cave goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=5878, name=Cave goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=5879, name=Ticket goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=5880, name=Dwarf, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=5881, name=Dwarf, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=5882, name=Dwarf, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=5883, name=Dwarf, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=5884, name=Dwarf, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=5885, name=Dwarf, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=5886, name=Ticket dwarf, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=5887, name=null, level=1, option=[null, null, null, null, null], anims=[101, 98]. +NPC id=5888, name=null, level=1, option=[null, null, null, null, null], anims=[6040, 6041]. +NPC id=5889, name=null, level=1, option=[null, null, null, null, null], anims=[6153, 6152]. +NPC id=5890, name=null, level=1, option=[null, null, null, null, null], anims=[6153, 6152]. +NPC id=5891, name=null, level=1, option=[null, null, null, null, null], anims=[6153, 6152]. +NPC id=5892, name=null, level=1, option=[null, null, null, null, null], anims=[6153, 6152]. +NPC id=5893, name=Cyrisus, level=0, option=[Talk-to, null, Inspect, null, null], anims=[6284, 6284]. +NPC id=5894, name=Cyrisus, level=0, option=[Talk-to, null, Inspect, null, null], anims=[808, -1]. +NPC id=5895, name=Cyrisus, level=0, option=[Talk-to, null, Inspect, null, null], anims=[808, -1]. +NPC id=5896, name=Cyrisus, level=0, option=[Talk-to, null, Inspect, null, null], anims=[808, -1]. +NPC id=5897, name=Cyrisus, level=0, option=[Talk-to, null, Inspect, null, null], anims=[808, -1]. +NPC id=5898, name='Bird's-Eye' Jack, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[808, -1]. +NPC id=5899, name=null, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=5900, name=null, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=5901, name=null, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=5902, name=The Inadequacy, level=343, option=[null, Attack, null, null, null], anims=[6317, 6317]. +NPC id=5903, name=The Everlasting, level=223, option=[null, Attack, null, null, null], anims=[6343, 6344]. +NPC id=5904, name=The Untouchable, level=274, option=[null, Attack, null, null, null], anims=[6328, 6328]. +NPC id=5905, name=The Illusive, level=108, option=[null, Attack, null, null, null], anims=[6338, 6339]. +NPC id=5906, name=A Doubt, level=78, option=[null, Attack, null, null, null], anims=[6311, 6312]. +NPC id=5907, name=The Illusive, level=1, option=[null, null, null, null, null], anims=[6350, 6339]. +NPC id=5908, name=Dying tree, level=0, option=[Chop down, null, hidden, null, null], anims=[5750, 5750]. +NPC id=5909, name=Barbarian, level=8, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=5910, name=Cook, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5911, name=Cook, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5912, name=Banker, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[808, 808]. +NPC id=5913, name=Banker, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[808, 808]. +NPC id=5914, name=Iffie, level=0, option=[Talk-to, null, null, null, null], anims=[6478, -1]. +NPC id=5915, name=Elsie, level=0, option=[Talk-to, null, null, null, null], anims=[6478, -1]. +NPC id=5916, name=Cleaner, level=0, option=[null, null, null, null, null], anims=[5800, 5799]. +NPC id=5917, name=Stray dog, level=0, option=[null, null, null, null, Shoo-away], anims=[4777, 4773]. +NPC id=5918, name=Stray dog, level=0, option=[null, null, null, null, Shoo-away], anims=[4777, 4773]. +NPC id=5919, name=Guard, level=21, option=[null, Attack, Pickpocket, null, null], anims=[6487, 6486]. +NPC id=5920, name=Guard, level=21, option=[null, Attack, Pickpocket, null, null], anims=[6487, 6486]. +NPC id=5921, name=Trainee Guard, level=0, option=[null, null, null, null, null], anims=[6487, 6486]. +NPC id=5922, name=Captain, level=0, option=[Talk-to, null, null, null, null], anims=[6487, 6486]. +NPC id=5923, name=Man, level=2, option=[Talk-to, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=5924, name=Woman, level=2, option=[Talk-to, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=5925, name=Benny, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5926, name=Thief, level=16, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=5927, name=Thief, level=16, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=5928, name=Thief, level=16, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=5929, name=Thief, level=16, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=5930, name=Art Critic Jacques, level=0, option=[Talk-to, null, null, null, null], anims=[6389, 6388]. +NPC id=5931, name=Historian Minas, level=0, option=[Talk-to, null, null, null, null], anims=[6393, 6395]. +NPC id=5932, name=Barnabus Hurma, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=5933, name=Marius Giste, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=5934, name=Caden Azro, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=5935, name=Thias Leacke, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=5936, name=Sinco Doar, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=5937, name=Tinse Torpe, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=5938, name=Information clerk, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5939, name=Torrcs, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5940, name=Marfet, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=5941, name=Museum guard, level=0, option=[Talk-to, null, null, null, null], anims=[6390, -1]. +NPC id=5942, name=Museum guard, level=0, option=[Talk-to, null, null, null, null], anims=[6464, -1]. +NPC id=5943, name=Museum guard, level=0, option=[Talk-to, null, null, null, null], anims=[6464, -1]. +NPC id=5944, name=Teacher and pupil, level=0, option=[Talk-to, null, null, null, null], anims=[6411, 6410]. +NPC id=5945, name=Schoolboy, level=0, option=[Talk-to, null, null, null, null], anims=[7167, 7165]. +NPC id=5946, name=Schoolboy, level=0, option=[Talk-to, null, null, null, null], anims=[7167, 7165]. +NPC id=5947, name=Teacher and pupil, level=0, option=[Talk-to, null, null, null, null], anims=[6413, 6412]. +NPC id=5948, name=Teacher and pupil, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=5949, name=Schoolboy, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=5950, name=Teacher, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=5951, name=Schoolgirl, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=5952, name=Workman, level=0, option=[null, null, null, null, null], anims=[6415, 6414]. +NPC id=5953, name=Workman, level=0, option=[null, null, null, null, null], anims=[-1, 6418]. +NPC id=5954, name=Workman, level=0, option=[null, null, null, null, null], anims=[6422, 6419]. +NPC id=5955, name=Workman, level=0, option=[null, null, null, null, null], anims=[6423, 6420]. +NPC id=5956, name=Void Knight, level=0, option=[Talk-to, null, Exchange, null, null], anims=[813, -1]. +NPC id=5957, name=Schoolgirl, level=0, option=[Talk-to, null, null, null, null], anims=[7167, 7165]. +NPC id=5958, name=Digsite workman, level=0, option=[null, null, null, null, null], anims=[6425, -1]. +NPC id=5959, name=Barge workman, level=0, option=[Talk-to, null, null, null, null], anims=[6454, -1]. +NPC id=5960, name=Barge workman, level=0, option=[Talk-to, null, null, null, null], anims=[6455, -1]. +NPC id=5961, name=Barge workman, level=0, option=[Talk-to, null, null, null, null], anims=[6456, -1]. +NPC id=5962, name=Barge workman, level=0, option=[Talk-to, null, null, null, null], anims=[6457, -1]. +NPC id=5963, name=Barge foreman, level=0, option=[Talk-to, null, null, null, null], anims=[6458, -1]. +NPC id=5964, name=Ed Wood, level=0, option=[Talk-to, null, null, null, null], anims=[2065, 2064]. +NPC id=5965, name=Orlando Smith, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5966, name=Natural historian, level=0, option=[Talk-to, null, null, null, null], anims=[6393, 6395]. +NPC id=5967, name=Natural historian, level=0, option=[Talk-to, null, null, null, null], anims=[6393, 6395]. +NPC id=5968, name=Natural historian, level=0, option=[Talk-to, null, null, null, null], anims=[6393, 6395]. +NPC id=5969, name=Natural historian, level=0, option=[Talk-to, null, null, null, null], anims=[6393, 6395]. +NPC id=5970, name=Natural historian, level=0, option=[null, null, null, null, null], anims=[6393, 6395]. +NPC id=5971, name=Leech display, level=0, option=[null, null, null, null, null], anims=[6429, -1]. +NPC id=5972, name=Sea slugs display, level=0, option=[null, null, null, null, null], anims=[6433, -1]. +NPC id=5973, name=Snail display, level=0, option=[null, null, null, null, null], anims=[6431, -1]. +NPC id=5974, name=Monkey display, level=0, option=[null, null, null, null, null], anims=[6435, -1]. +NPC id=5975, name=Lizard display, level=0, option=[null, null, null, null, null], anims=[6437, -1]. +NPC id=5976, name=Penguin display, level=0, option=[null, null, null, null, null], anims=[6439, -1]. +NPC id=5977, name=Camel display, level=0, option=[null, null, null, null, null], anims=[6441, -1]. +NPC id=5978, name=Terrorbird display, level=0, option=[null, null, null, null, null], anims=[6443, -1]. +NPC id=5979, name=Dragon display, level=0, option=[null, null, null, null, null], anims=[6447, -1]. +NPC id=5980, name=Wyvern display, level=0, option=[null, null, null, null, null], anims=[6445, -1]. +NPC id=5981, name=Battle tortoise display, level=0, option=[null, null, null, null, null], anims=[6449, -1]. +NPC id=5982, name=Mole display, level=0, option=[null, null, null, null, null], anims=[6451, -1]. +NPC id=5983, name=Schoolgirl, level=0, option=[Talk-to, null, null, null, null], anims=[7167, 7165]. +NPC id=5984, name=Schoolgirl, level=0, option=[Talk-to, null, null, null, null], anims=[7167, 7165]. +NPC id=5985, name=Schoolgirl, level=0, option=[Talk-to, null, null, null, null], anims=[7167, 7165]. +NPC id=5986, name=Workman, level=0, option=[null, null, null, null, null], anims=[6422, 6419]. +NPC id=5987, name=Sylas, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5988, name=Miazrqa, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=5989, name=Grimgnash, level=0, option=[Talk-To, null, null, null, null], anims=[6507, -1]. +NPC id=5990, name=Rupert the Beard, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=5991, name=Drain pipe, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=5992, name=Rupert the Beard, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=5993, name=Experiment No.2, level=109, option=[null, Attack, null, null, null], anims=[6511, 6510]. +NPC id=5994, name=Mouse, level=95, option=[null, Attack, null, null, null], anims=[6518, 6517]. +NPC id=5995, name=Mouse, level=95, option=[null, Attack, null, null, null], anims=[6518, 6517]. +NPC id=5996, name=Glod, level=138, option=[null, Attack, null, null, null], anims=[6504, 6505]. +NPC (wrapper) id=5997, child npcs=[5989, -1]. +NPC (wrapper) id=5998, child npcs=[5990, 5999, -1]. +NPC id=5999, name=Rupert the Beard, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC (wrapper) id=6000, child npcs=[5992, 6001, -1]. +NPC id=6001, name=Rupert the Beard, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=6002, name=Gnome, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[6533, -1]. +NPC id=6003, name=Winkin, level=0, option=[Talk-to, null, null, null, null], anims=[6534, -1]. +NPC id=6004, name=Gnome, level=0, option=[Talk-to, null, null, null, null], anims=[6535, -1]. +NPC id=6005, name=Cage, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6006, name=Werewolf, level=88, option=[null, Attack, null, null, null], anims=[6539, 6541]. +NPC id=6007, name=Werewolf, level=88, option=[null, Attack, null, null, null], anims=[6539, 6541]. +NPC id=6008, name=Werewolf, level=88, option=[null, Attack, null, null, null], anims=[6539, 6541]. +NPC id=6009, name=Werewolf, level=88, option=[null, Attack, null, null, null], anims=[6539, 6541]. +NPC id=6010, name=Werewolf, level=88, option=[null, Attack, null, null, null], anims=[6539, 6541]. +NPC id=6011, name=Werewolf, level=88, option=[null, Attack, null, null, null], anims=[6539, 6541]. +NPC id=6012, name=Werewolf, level=88, option=[null, Attack, null, null, null], anims=[6539, 6541]. +NPC id=6013, name=Werewolf, level=88, option=[null, Attack, null, null, null], anims=[6539, 6541]. +NPC id=6014, name=Werewolf, level=88, option=[null, Attack, null, null, null], anims=[6539, 6541]. +NPC id=6015, name=Werewolf, level=88, option=[null, Attack, null, null, null], anims=[6539, 6541]. +NPC id=6016, name=Werewolf, level=88, option=[null, Attack, null, null, null], anims=[6539, 6541]. +NPC id=6017, name=Werewolf, level=88, option=[null, Attack, null, null, null], anims=[6539, 6541]. +NPC id=6018, name=Werewolf, level=88, option=[null, Attack, null, null, null], anims=[6539, 6541]. +NPC id=6019, name=Werewolf, level=88, option=[null, Attack, null, null, null], anims=[6539, 6541]. +NPC id=6020, name=Werewolf, level=88, option=[null, Attack, null, null, null], anims=[6539, 6541]. +NPC id=6021, name=Werewolf, level=88, option=[null, Attack, null, null, null], anims=[6539, 6541]. +NPC id=6022, name=Werewolf, level=88, option=[null, Attack, null, null, null], anims=[6539, 6541]. +NPC id=6023, name=Werewolf, level=88, option=[null, Attack, null, null, null], anims=[6539, 6541]. +NPC id=6024, name=Werewolf, level=88, option=[null, Attack, null, null, null], anims=[6539, 6541]. +NPC id=6025, name=Werewolf, level=88, option=[null, Attack, null, null, null], anims=[6539, 6541]. +NPC id=6026, name=Boris, level=24, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=6027, name=Imre, level=24, option=[null, Attack, Talk-to, null, null], anims=[808, -1]. +NPC id=6028, name=Yuri, level=24, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=6029, name=Joseph, level=24, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=6030, name=Nikolai, level=24, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=6031, name=Eduard, level=24, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=6032, name=Lev, level=24, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=6033, name=Georgy, level=24, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=6034, name=Svetlana, level=24, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=6035, name=Irina, level=24, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=6036, name=Alexis, level=24, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=6037, name=Milla, level=24, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=6038, name=Galina, level=24, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=6039, name=Sofiya, level=24, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=6040, name=Ksenia, level=24, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=6041, name=Yadviga, level=24, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=6042, name=Nikita, level=24, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=6043, name=Vera, level=24, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=6044, name=Zoja, level=24, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=6045, name=Liliya, level=24, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC id=6046, name=Big Wolf, level=73, option=[null, Attack, null, null, null], anims=[6580, 6556]. +NPC id=6047, name=Wolf, level=25, option=[null, Attack, null, null, null], anims=[6580, 6556]. +NPC id=6048, name=Wolf, level=25, option=[null, Attack, null, null, null], anims=[6580, 6556]. +NPC id=6049, name=Wolf, level=25, option=[null, Attack, null, null, null], anims=[6580, 6556]. +NPC id=6050, name=Desert Wolf, level=27, option=[null, Attack, null, null, null], anims=[6580, 6556]. +NPC id=6051, name=Desert Wolf, level=27, option=[null, Attack, null, null, null], anims=[6580, 6556]. +NPC id=6052, name=Ice wolf, level=96, option=[null, Attack, null, null, null], anims=[6580, 6556]. +NPC id=6053, name=Ninja impling, level=0, option=[Catch, null, null, null, null], anims=[6613, 6614]. +NPC id=6054, name=Dragon impling, level=0, option=[Catch, null, null, null, null], anims=[6613, 6614]. +NPC id=6055, name=Baby impling, level=0, option=[Catch, null, null, null, null], anims=[6613, 6614]. +NPC id=6056, name=Young impling, level=0, option=[Catch, null, null, null, null], anims=[6613, 6614]. +NPC id=6057, name=Gourmet impling, level=0, option=[Catch, null, null, null, null], anims=[6613, 6614]. +NPC id=6058, name=Earth impling, level=0, option=[Catch, null, null, null, null], anims=[6613, 6614]. +NPC id=6059, name=Essence impling, level=0, option=[Catch, null, null, null, null], anims=[6613, 6614]. +NPC id=6060, name=Eclectic impling, level=0, option=[Catch, null, null, null, null], anims=[6613, 6614]. +NPC id=6061, name=Nature impling, level=0, option=[Catch, null, null, null, null], anims=[6613, 6614]. +NPC id=6062, name=Magpie impling, level=0, option=[Catch, null, null, null, null], anims=[6613, 6614]. +NPC id=6063, name=Ninja impling, level=0, option=[Catch, null, null, null, null], anims=[6613, 6614]. +NPC id=6064, name=Dragon impling, level=0, option=[Catch, null, null, null, null], anims=[6613, 6614]. +NPC id=6065, name=null, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6066, name=null, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6067, name=null, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6068, name=null, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6069, name=null, level=0, option=[null, null, null, null, null], anims=[171, 168]. +NPC id=6070, name=Elnock Inquisitor, level=0, option=[Talk-to, null, Trade, null, null], anims=[195, 189]. +NPC id=6071, name=Immenizz, level=0, option=[Talk-to, null, null, null, null], anims=[6613, 6614]. +NPC id=6072, name=Fairy Aeryka, level=0, option=[Talk-to, null, null, null, null], anims=[112, 106]. +NPC id=6073, name=Wandering impling, level=0, option=[Talk-to, null, null, null, null], anims=[6613, 6614]. +NPC id=6074, name=Imp defender, level=0, option=[null, null, null, null, null], anims=[171, 168]. +NPC (wrapper) id=6075, child npcs=[1685, -1]. +NPC id=6076, name=null, level=0, option=[Talk-To, null, null, null, null], anims=[1421, -1]. +NPC id=6077, name=null, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=6078, name=Cyclops, level=56, option=[null, Attack, null, null, null], anims=[4650, 4649]. +NPC id=6079, name=Cyclops, level=76, option=[null, Attack, null, null, null], anims=[4650, 4649]. +NPC id=6080, name=Cyclops, level=56, option=[null, Attack, null, null, null], anims=[4650, 4649]. +NPC id=6081, name=Cyclops, level=76, option=[null, Attack, null, null, null], anims=[4650, 4649]. +NPC id=6082, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=6083, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=6084, name=Captain Ned, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=6085, name=Cabin boy Jenkins, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=6086, name=Cabin boy Jenkins, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=6087, name=Elvarg, level=83, option=[null, null, null, null, null], anims=[90, 79]. +NPC id=6088, name=Zombie rat, level=3, option=[null, Attack, null, null, null], anims=[4932, 4931]. +NPC id=6089, name=Zombie rat, level=3, option=[null, Attack, null, null, null], anims=[4932, 4931]. +NPC id=6090, name=Zombie rat, level=3, option=[null, Attack, null, null, null], anims=[4932, 4931]. +NPC id=6091, name=Skeleton, level=22, option=[null, Attack, null, null, null], anims=[5483, 5481]. +NPC id=6092, name=Skeleton, level=22, option=[null, Attack, null, null, null], anims=[5483, 5481]. +NPC id=6093, name=Skeleton, level=22, option=[null, Attack, null, null, null], anims=[5483, 5479]. +NPC id=6094, name=Ghost, level=19, option=[Talk-to, Attack, null, null, null], anims=[5538, 5539]. +NPC id=6095, name=Ghost, level=19, option=[Talk-to, Attack, null, null, null], anims=[5530, 5531]. +NPC id=6096, name=Ghost, level=19, option=[Talk-to, Attack, null, null, null], anims=[5530, 5531]. +NPC id=6097, name=Ghost, level=19, option=[Talk-to, Attack, null, null, null], anims=[5530, 5531]. +NPC id=6098, name=Ghost, level=19, option=[Talk-to, Attack, null, null, null], anims=[5530, 5531]. +NPC id=6099, name=Zombie, level=24, option=[null, Attack, null, null, null], anims=[5572, -1]. +NPC id=6100, name=Zombie, level=24, option=[null, Attack, null, null, null], anims=[5572, -1]. +NPC id=6101, name=Lesser demon, level=82, option=[null, Attack, null, null, null], anims=[66, 63]. +NPC id=6102, name=Lost barbarian, level=132, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=6103, name=Skeleton hero, level=149, option=[null, Attack, null, null, null], anims=[2065, 2064]. +NPC id=6104, name=Skeleton brute, level=132, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=6105, name=Skeleton warlord, level=132, option=[null, Attack, null, null, null], anims=[2065, 2064]. +NPC id=6106, name=Skeleton heavy, level=132, option=[null, Attack, null, null, null], anims=[2561, -1]. +NPC id=6107, name=Skeleton thug, level=132, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=6108, name=Entrana firebird, level=2, option=[null, Attack, null, null, null], anims=[6809, 6808]. +NPC id=6109, name=Mounted terrorbird gnome, level=49, option=[null, Attack, null, null, null], anims=[6793, 6796]. +NPC id=6110, name=Mounted terrorbird gnome, level=49, option=[null, Attack, null, null, null], anims=[6793, 6796]. +NPC id=6111, name=Mounted terrorbird gnome, level=49, option=[null, Attack, null, null, null], anims=[6793, 6796]. +NPC id=6112, name=Ducklings, level=0, option=[null, null, null, null, null], anims=[6821, 6822]. +NPC id=6113, name=Duck, level=0, option=[null, null, null, null, null], anims=[6813, 6819]. +NPC id=6114, name=Drake, level=0, option=[null, null, null, null, null], anims=[6813, 6819]. +NPC id=6115, name=Seagull, level=2, option=[null, Attack, null, null, null], anims=[6815, 6819]. +NPC id=6116, name=Seagull, level=3, option=[null, Attack, null, null, null], anims=[6815, 6819]. +NPC id=6117, name=Mr. Mordaut, level=0, option=[Talk-to, null, null, null, null], anims=[6825, -1]. +NPC id=6118, name=Observatory assistant, level=0, option=[Talk-to, null, null, null, null], anims=[6841, -1]. +NPC (wrapper) id=6119, child npcs=[488, 488, 488, 488, 488, 488, -1]. +NPC id=6120, name=null, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=6121, name=Observatory professor, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=6122, name=Sleeping guard, level=1, option=[Prod, null, null, null, null], anims=[6828, 6187]. +NPC id=6123, name=Naghead, level=0, option=[null, null, null, null, null], anims=[6834, -1]. +NPC id=6124, name=Wagchin, level=0, option=[null, null, null, null, null], anims=[6835, -1]. +NPC id=6125, name=Goblin, level=0, option=[null, null, null, null, null], anims=[6181, 6180]. +NPC id=6126, name=Goblin, level=0, option=[null, null, null, null, null], anims=[6181, 6180]. +NPC id=6127, name=Greasycheeks, level=0, option=[Talk-to, null, null, null, null], anims=[6831, -1]. +NPC id=6128, name=Smellytoes, level=0, option=[Talk-to, null, null, null, null], anims=[6829, -1]. +NPC id=6129, name=Creakyknees, level=0, option=[Talk-to, null, null, null, null], anims=[6833, -1]. +NPC id=6130, name=Clothears, level=0, option=[Talk-to, null, null, null, null], anims=[6836, -1]. +NPC id=6131, name=Zombie, level=0, option=[null, null, null, null, null], anims=[6855, -1]. +NPC id=6132, name=Goblin, level=0, option=[null, null, null, null, null], anims=[6858, -1]. +NPC id=6133, name=Goblin, level=0, option=[null, null, null, null, null], anims=[6859, -1]. +NPC id=6134, name=Dunce, level=0, option=[null, null, null, null, null], anims=[6826, -1]. +NPC id=6135, name=Town crier, level=0, option=[Talk-to, null, null, null, null], anims=[6864, 6867]. +NPC id=6136, name=Town crier, level=0, option=[Talk-to, null, null, null, null], anims=[6864, 6867]. +NPC id=6137, name=Town crier, level=0, option=[Talk-to, null, null, null, null], anims=[6864, 6867]. +NPC id=6138, name=Town crier, level=0, option=[Talk-to, null, null, null, null], anims=[6864, 6867]. +NPC id=6139, name=Town crier, level=0, option=[Talk-to, null, null, null, null], anims=[6864, 6867]. +NPC id=6140, name=Squire (Intermediate), level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=6141, name=Squire (Veteran), level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=6142, name=Portal, level=0, option=[hidden, Attack, null, null, null], anims=[3933, 3933]. +NPC id=6143, name=Portal, level=0, option=[hidden, Attack, null, null, null], anims=[3936, 3936]. +NPC id=6144, name=Portal, level=0, option=[hidden, Attack, null, null, null], anims=[3928, 3928]. +NPC id=6145, name=Portal, level=0, option=[hidden, Attack, null, null, null], anims=[3928, 3928]. +NPC id=6146, name=Portal, level=0, option=[hidden, null, null, null, null], anims=[6879, 6879]. +NPC id=6147, name=Portal, level=0, option=[hidden, null, null, null, null], anims=[6880, 6880]. +NPC id=6148, name=Portal, level=0, option=[hidden, null, null, null, null], anims=[6878, 6878]. +NPC id=6149, name=Portal, level=0, option=[hidden, null, null, null, null], anims=[6878, 6878]. +NPC id=6150, name=Portal, level=0, option=[hidden, Attack, null, null, null], anims=[3933, 3933]. +NPC id=6151, name=Portal, level=0, option=[hidden, Attack, null, null, null], anims=[3936, 3936]. +NPC id=6152, name=Portal, level=0, option=[hidden, Attack, null, null, null], anims=[3928, 3928]. +NPC id=6153, name=Portal, level=0, option=[hidden, Attack, null, null, null], anims=[3928, 3928]. +NPC id=6154, name=Portal, level=0, option=[hidden, null, null, null, null], anims=[6879, 6879]. +NPC id=6155, name=Portal, level=0, option=[hidden, null, null, null, null], anims=[6880, 6880]. +NPC id=6156, name=Portal, level=0, option=[hidden, null, null, null, null], anims=[6878, 6878]. +NPC id=6157, name=Portal, level=0, option=[hidden, null, null, null, null], anims=[6878, 6878]. +NPC id=6158, name=Sir Lucan, level=120, option=[Talk-to, Hidden, null, null, null], anims=[808, -1]. +NPC id=6159, name=Workman, level=0, option=[null, null, null, null, null], anims=[6423, 6420]. +NPC id=6160, name=Sir Lancelot, level=127, option=[Talk-to, Hidden, null, null, null], anims=[808, -1]. +NPC id=6161, name=Sir Bedivere, level=110, option=[Talk-to, Hidden, null, null, null], anims=[808, -1]. +NPC id=6162, name=Sir Tristram, level=115, option=[Talk-to, Hidden, null, null, null], anims=[808, -1]. +NPC id=6163, name=Sir Pelleas, level=112, option=[Talk-to, Hidden, null, null, null], anims=[808, -1]. +NPC id=6164, name=Sir Gawain, level=122, option=[Talk-to, Hidden, null, null, null], anims=[808, -1]. +NPC id=6165, name=Sir Kay, level=124, option=[Talk-to, Hidden, null, null, null], anims=[808, -1]. +NPC id=6166, name=Sir Pelleas, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=6167, name=Sir Gawain, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=6168, name=Sir Kay, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=6169, name=Squire, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=6170, name=Sir Lancelot, level=127, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=6171, name=Sir Kay, level=124, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=6172, name=Sir Gawain, level=122, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=6173, name=Sir Lucan, level=120, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=6174, name=Bandit, level=41, option=[Talk-to, Attack, Pickpocket, null, null], anims=[808, -1]. +NPC id=6175, name=Sir Tristram, level=115, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=6176, name=Sir Pelleas, level=112, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=6177, name=Sir Bedivere, level=110, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=6178, name=Anna, level=0, option=[Talk-to, null, null, null, null], anims=[808, 6926]. +NPC id=6179, name=David, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=6180, name=Anna, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=6181, name=Court judge, level=0, option=[null, null, null, null, null], anims=[1322, -1]. +NPC id=6182, name=Jury, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=6183, name=Guard, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=6184, name=Guard, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=6185, name=Prosecutor, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=6186, name=null, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=6187, name=Morgan Le Faye, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=6188, name=Renegade knight, level=37, option=[null, Hidden, null, null, null], anims=[6927, 6928]. +NPC id=6189, name=Black Knight, level=33, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=6190, name=Guard, level=0, option=[null, null, null, null, null], anims=[6918, -1]. +NPC (wrapper) id=6191, child npcs=[812, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 812, -1]. +NPC (wrapper) id=6192, child npcs=[814, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 814, -1]. +NPC (wrapper) id=6193, child npcs=[815, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 815, -1]. +NPC (wrapper) id=6194, child npcs=[816, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 816, -1]. +NPC (wrapper) id=6195, child npcs=[817, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 817, -1]. +NPC (wrapper) id=6196, child npcs=[818, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 818, -1]. +NPC (wrapper) id=6197, child npcs=[819, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 819, -1]. +NPC id=6198, name=Sinclair, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=6199, name=null, level=1, option=[Talk-to, null, null, null, null], anims=[808, 6919]. +NPC id=6200, name=Banker, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[808, 808]. +NPC id=6201, name=Knight, level=0, option=[Talk-to, null, null, null, null], anims=[7003, -1]. +NPC (wrapper) id=6202, child npcs=[6201, -1]. +NPC id=6203, name=K'ril Tsutsaroth, level=650, option=[null, Attack, null, null, null], anims=[6943, 6942]. +NPC id=6204, name=Tstanon Karlak, level=145, option=[null, Attack, null, null, null], anims=[66, 63]. +NPC id=6205, name=, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6206, name=Zakl'n Gritch, level=142, option=[null, Attack, null, null, null], anims=[66, 63]. +NPC id=6207, name=, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6208, name=Balfrug Kreeyath, level=151, option=[null, Attack, null, null, null], anims=[66, 63]. +NPC id=6209, name=, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6210, name=Hellhound, level=127, option=[null, Attack, null, null, null], anims=[6580, 6582]. +NPC id=6211, name=Imp, level=7, option=[null, Attack, null, null, null], anims=[171, 168]. +NPC id=6212, name=Werewolf, level=93, option=[null, Attack, null, null, null], anims=[6539, 6541]. +NPC id=6213, name=Werewolf, level=93, option=[null, Attack, null, null, null], anims=[6539, 6541]. +NPC id=6214, name=Vampire, level=77, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=6215, name=Bloodveld, level=81, option=[null, Attack, null, null, null], anims=[1551, 1549]. +NPC id=6216, name=Pyrefiend, level=48, option=[null, Attack, null, null, null], anims=[1578, 1579]. +NPC id=6217, name=Icefiend, level=13, option=[null, Attack, null, null, null], anims=[8077, 8076]. +NPC id=6218, name=Gorak, level=149, option=[null, Attack, null, null, null], anims=[4299, 4298]. +NPC id=6219, name=Spiritual warrior, level=115, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=6220, name=Spiritual ranger, level=118, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=6221, name=Spiritual mage, level=121, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=6222, name=Kree'arra, level=580, option=[null, Attack, null, null, null], anims=[6972, 6973]. +NPC id=6223, name=Wingman Skree, level=143, option=[null, Attack, null, null, null], anims=[6949, 6950]. +NPC id=6224, name=, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6225, name=Flockleader Geerin, level=149, option=[null, Attack, null, null, null], anims=[6949, 6950]. +NPC id=6226, name=, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6227, name=Flight Kilisa, level=159, option=[null, Attack, null, null, null], anims=[6949, 6950]. +NPC id=6228, name=, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6229, name=Spiritual warrior, level=123, option=[null, Attack, null, null, null], anims=[6949, 6950]. +NPC id=6230, name=Spiritual ranger, level=127, option=[null, Attack, null, null, null], anims=[6949, 6950]. +NPC id=6231, name=Spiritual mage, level=122, option=[null, Attack, null, null, null], anims=[6949, 6950]. +NPC id=6232, name=Aviansie, level=69, option=[null, Attack, null, null, null], anims=[6949, 6950]. +NPC id=6233, name=Aviansie, level=79, option=[null, Attack, null, null, null], anims=[6949, 6950]. +NPC id=6234, name=Aviansie, level=84, option=[null, Attack, null, null, null], anims=[6949, 6950]. +NPC id=6235, name=Aviansie, level=83, option=[null, Attack, null, null, null], anims=[6949, 6950]. +NPC id=6236, name=Aviansie, level=92, option=[null, Attack, null, null, null], anims=[6949, 6950]. +NPC id=6237, name=Aviansie, level=97, option=[null, Attack, null, null, null], anims=[6949, 6950]. +NPC id=6238, name=Aviansie, level=137, option=[null, Attack, null, null, null], anims=[6949, 6950]. +NPC id=6239, name=Aviansie, level=148, option=[null, Attack, null, null, null], anims=[6949, 6950]. +NPC id=6240, name=Aviansie, level=71, option=[null, Attack, null, null, null], anims=[6949, 6950]. +NPC id=6241, name=Aviansie, level=73, option=[null, Attack, null, null, null], anims=[6949, 6950]. +NPC id=6242, name=Aviansie, level=79, option=[null, Attack, null, null, null], anims=[6949, 6950]. +NPC id=6243, name=Aviansie, level=89, option=[null, Attack, null, null, null], anims=[6949, 6950]. +NPC id=6244, name=Aviansie, level=94, option=[null, Attack, null, null, null], anims=[6949, 6950]. +NPC id=6245, name=Aviansie, level=97, option=[null, Attack, null, null, null], anims=[6949, 6950]. +NPC id=6246, name=Aviansie, level=131, option=[null, Attack, null, null, null], anims=[6949, 6950]. +NPC id=6247, name=Commander Zilyana, level=596, option=[null, Attack, null, null, null], anims=[6963, 6962]. +NPC id=6248, name=Starlight, level=149, option=[null, Attack, null, null, null], anims=[6374, 6373]. +NPC id=6249, name=, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6250, name=Growler, level=139, option=[null, Attack, null, null, null], anims=[7014, 7015]. +NPC id=6251, name=, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6252, name=Bree, level=146, option=[null, Attack, null, null, null], anims=[4311, 4310]. +NPC id=6253, name=, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6254, name=Saradomin priest, level=113, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=6255, name=Spiritual warrior, level=125, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=6256, name=Spiritual ranger, level=122, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=6257, name=Spiritual mage, level=120, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=6258, name=Knight of Saradomin, level=103, option=[null, Attack, null, null, null], anims=[-1, -1]. +NPC id=6259, name=Knight of Saradomin, level=101, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=6260, name=General Graardor, level=624, option=[null, Attack, null, null, null], anims=[7059, 7058]. +NPC id=6261, name=Sergeant Strongstack, level=141, option=[null, Attack, null, null, null], anims=[6153, 6152]. +NPC id=6262, name=, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6263, name=Sergeant Steelwill, level=142, option=[null, Attack, null, null, null], anims=[6153, 6152]. +NPC id=6264, name=, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6265, name=Sergeant Grimspike, level=142, option=[null, Attack, null, null, null], anims=[6153, 6152]. +NPC id=6266, name=, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6267, name=Ogre, level=58, option=[null, Attack, null, null, null], anims=[357, 358]. +NPC id=6268, name=Jogre, level=58, option=[null, Attack, null, null, null], anims=[2931, 2932]. +NPC id=6269, name=Cyclops, level=81, option=[null, Attack, null, null, null], anims=[4650, 4649]. +NPC id=6270, name=Cyclops, level=81, option=[null, Attack, null, null, null], anims=[4650, 4649]. +NPC id=6271, name=Ork, level=107, option=[null, Attack, null, null, null], anims=[4318, 4319]. +NPC id=6272, name=Ork, level=107, option=[null, Attack, null, null, null], anims=[4318, 4319]. +NPC id=6273, name=Ork, level=107, option=[null, Attack, null, null, null], anims=[4318, 4319]. +NPC id=6274, name=Ork, level=107, option=[null, Attack, null, null, null], anims=[4318, 4319]. +NPC id=6275, name=Hobgoblin, level=47, option=[null, Attack, null, null, null], anims=[166, 162]. +NPC id=6276, name=Spiritual ranger, level=115, option=[null, Attack, null, null, null], anims=[4318, 4319]. +NPC id=6277, name=Spiritual warrior, level=134, option=[null, Attack, null, null, null], anims=[4318, 4319]. +NPC id=6278, name=Spiritual mage, level=121, option=[null, Attack, null, null, null], anims=[4318, 4319]. +NPC id=6279, name=Goblin, level=17, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=6280, name=Goblin, level=12, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=6281, name=Goblin, level=12, option=[null, Attack, null, null, null], anims=[6139, 6138]. +NPC id=6282, name=Goblin, level=15, option=[null, Attack, null, null, null], anims=[6186, 6187]. +NPC id=6283, name=Goblin, level=13, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=6284, name=null, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6285, name=Warped terrorbird, level=81, option=[null, Attack, null, null, null], anims=[7105, 7106]. +NPC id=6286, name=Warped terrorbird, level=81, option=[null, Attack, null, null, null], anims=[7105, 7106]. +NPC id=6287, name=Warped terrorbird, level=81, option=[null, Attack, null, null, null], anims=[7105, 7106]. +NPC id=6288, name=Warped terrorbird, level=81, option=[null, Attack, null, null, null], anims=[7105, 7106]. +NPC id=6289, name=Warped terrorbird, level=81, option=[null, Attack, null, null, null], anims=[7105, 7106]. +NPC id=6290, name=Warped terrorbird, level=81, option=[null, Attack, null, null, null], anims=[7105, 7106]. +NPC id=6291, name=Warped terrorbird, level=81, option=[null, Attack, null, null, null], anims=[7105, 7106]. +NPC id=6292, name=Warped terrorbird, level=81, option=[null, Attack, null, null, null], anims=[7105, 7106]. +NPC id=6293, name=Warped terrorbird, level=143, option=[null, Attack, null, null, null], anims=[7105, 7106]. +NPC id=6294, name=Warped terrorbird, level=143, option=[null, Attack, null, null, null], anims=[7105, 7106]. +NPC id=6295, name=Warped terrorbird, level=143, option=[null, Attack, null, null, null], anims=[7105, 7106]. +NPC id=6296, name=Warped tortoise, level=96, option=[null, Attack, null, null, null], anims=[7090, 7089]. +NPC id=6297, name=Warped tortoise, level=96, option=[null, Attack, null, null, null], anims=[7090, 7089]. +NPC id=6298, name=Jeffery, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=6299, name=Big monolith, level=0, option=[Push, null, null, null, null], anims=[-1, -1]. +NPC id=6300, name=Small monolith, level=0, option=[Push, null, null, null, null], anims=[-1, -1]. +NPC id=6301, name=Cute creature, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6302, name=Evil creature, level=0, option=[null, Attack, null, null, null], anims=[-1, -1]. +NPC id=6303, name=Yewnock the engineer, level=0, option=[null, null, null, null, null], anims=[195, 189]. +NPC id=6304, name=Bolrie, level=0, option=[null, null, null, null, null], anims=[195, 189]. +NPC id=6305, name=Hazelmere, level=0, option=[null, null, null, null, null], anims=[195, 189]. +NPC id=6306, name=Bolrie, level=0, option=[null, null, null, null, null], anims=[195, 189]. +NPC id=6307, name=Advisor, level=0, option=[null, null, null, null, null], anims=[195, 189]. +NPC id=6308, name=King Argenthorg, level=0, option=[null, null, null, null, null], anims=[195, 189]. +NPC id=6309, name=Prince Argenthorg, level=0, option=[null, null, null, null, null], anims=[195, 189]. +NPC (wrapper) id=6310, child npcs=[6311, 6312, 1957, -1]. +NPC id=6311, name=Cute creature, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6312, name=Evil creature, level=0, option=[null, Attack, null, null, null], anims=[-1, -1]. +NPC id=6313, name=Terrorbird servant, level=0, option=[null, null, null, null, null], anims=[7099, 7098]. +NPC id=6314, name=Guard no. 21, level=0, option=[null, null, null, null, null], anims=[7099, 7098]. +NPC id=6315, name=Guard no. 72, level=0, option=[null, null, null, null, null], anims=[7101, 7098]. +NPC id=6316, name=Guard no. 21, level=0, option=[null, null, null, null, null], anims=[7111, 7103]. +NPC id=6317, name=Guard no. 72, level=0, option=[null, null, null, null, null], anims=[7111, 7103]. +NPC id=6318, name=Longramble, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=6319, name=null, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6320, name=Spirit tree, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6321, name=Spirit tree, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6322, name=Warped terrorbird, level=81, option=[null, Attack, null, null, null], anims=[7105, 7106]. +NPC id=6323, name=Warped terrorbird, level=81, option=[null, Attack, null, null, null], anims=[7105, 7106]. +NPC id=6324, name=Warped terrorbird, level=81, option=[null, Attack, null, null, null], anims=[7105, 7106]. +NPC id=6325, name=Warped terrorbird, level=81, option=[null, Attack, null, null, null], anims=[7105, 7106]. +NPC id=6326, name=Warped terrorbird, level=81, option=[null, Attack, null, null, null], anims=[7105, 7106]. +NPC id=6327, name=Warped terrorbird, level=81, option=[null, Attack, null, null, null], anims=[7105, 7106]. +NPC id=6328, name=Warped terrorbird, level=81, option=[null, Attack, null, null, null], anims=[7105, 7106]. +NPC id=6329, name=Warped terrorbird, level=81, option=[null, Attack, null, null, null], anims=[7105, 7106]. +NPC id=6330, name=Warped terrorbird, level=143, option=[null, Attack, null, null, null], anims=[7105, 7106]. +NPC id=6331, name=Warped terrorbird, level=143, option=[null, Attack, null, null, null], anims=[7105, 7106]. +NPC id=6332, name=Warped terrorbird, level=143, option=[null, Attack, null, null, null], anims=[7105, 7106]. +NPC id=6333, name=null, level=0, option=[null, null, null, null, null], anims=[4472, 4473]. +NPC id=6334, name=Child, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=6335, name=Child, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=6336, name=Child, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=6337, name=Child, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=6338, name=Child, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=6339, name=Child, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=6340, name=Child, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=6341, name=Child, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=6342, name=Child, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=6343, name=Child, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=6344, name=Child, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=6345, name=Child, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=6346, name=Pirate, level=23, option=[Talk-to, Attack, null, null, null], anims=[7188, -1]. +NPC id=6347, name=Pirate, level=23, option=[Talk-to, Attack, null, null, null], anims=[7188, -1]. +NPC id=6348, name=Pirate, level=23, option=[Talk-to, Attack, null, null, null], anims=[7188, -1]. +NPC id=6349, name=Pirate, level=23, option=[Talk-to, Attack, null, null, null], anims=[7188, -1]. +NPC id=6350, name=Pirate, level=23, option=[Talk-to, Attack, null, null, null], anims=[7188, -1]. +NPC id=6351, name=Pirate, level=26, option=[null, Attack, null, null, null], anims=[7188, -1]. +NPC id=6352, name=Pirate, level=26, option=[null, Attack, null, null, null], anims=[7188, -1]. +NPC id=6353, name=Pirate, level=26, option=[null, Attack, null, null, null], anims=[7188, -1]. +NPC id=6354, name=Pirate, level=26, option=[null, Attack, null, null, null], anims=[7188, -1]. +NPC id=6355, name=Pirate, level=26, option=[null, Attack, null, null, null], anims=[7188, -1]. +NPC id=6356, name=Pirate, level=26, option=[null, Attack, null, null, null], anims=[7188, -1]. +NPC id=6357, name=Street urchin, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=6358, name=Street urchin, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=6359, name=Street urchin, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=6360, name=Street urchin, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=6361, name=Street urchin, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=6362, name=Eniola, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[5607, 5606]. +NPC id=6363, name=Zamorak warrior, level=84, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=6364, name=Zamorak warrior, level=85, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=6365, name=Zamorak ranger, level=81, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=6366, name=Zamorak ranger, level=82, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=6367, name=Zamorak mage, level=84, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=6368, name=Zamorak mage, level=82, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=6369, name=Cave lizard, level=37, option=[null, Attack, null, null, null], anims=[7209, 7210]. +NPC id=6370, name=Mage of Zamorak, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=6371, name=Zamorak crafter, level=19, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=6372, name=Zamorak crafter, level=19, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=6373, name=Kennith, level=0, option=[Talk-to, null, null, null, null], anims=[7166, 7166]. +NPC id=6374, name=Guard dog, level=44, option=[null, null, null, null, null], anims=[7254, 6560]. +NPC id=6375, name=Wizard Cromperty, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=6376, name=Jungle spider, level=40, option=[null, Attack, null, null, null], anims=[5326, 5325]. +NPC id=6377, name=Jungle spider, level=40, option=[null, Attack, null, null, null], anims=[5326, 5325]. +NPC id=6378, name=Tenacious toucan, level=70, option=[null, Attack, null, null, null], anims=[6772, 6774]. +NPC id=6379, name=Giant ant worker, level=40, option=[null, Attack, null, null, null], anims=[7236, 7235]. +NPC id=6380, name=Giant ant soldier, level=50, option=[null, Attack, null, null, null], anims=[7236, 7235]. +NPC id=6381, name=Giant wasp, level=62, option=[null, Attack, null, null, null], anims=[7241, 7241]. +NPC id=6382, name=Pernicious parrot, level=66, option=[null, Attack, null, null, null], anims=[6771, 6773]. +NPC id=6383, name=Giant wasp, level=62, option=[null, Attack, null, null, null], anims=[7241, 7241]. +NPC id=6384, name=Karamjan Jungle Eagle, level=0, option=[null, null, null, null, null], anims=[1773, 1773]. +NPC id=6385, name=Karamjan Jungle eagle, level=0, option=[null, null, null, null, null], anims=[5280, 5279]. +NPC id=6386, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=6387, name=null, level=0, option=[null, null, null, null, null], anims=[5280, 5279]. +NPC id=6388, name=Bandit, level=41, option=[Talk-to, Attack, Pickpocket, Lure, Knock-Out], anims=[808, -1]. +NPC id=6389, name=Gargoyle, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6390, name=Grim Reaper, level=0, option=[Talk-to, null, null, null, null], anims=[7295, -1]. +NPC id=6391, name=Glough, level=0, option=[null, null, null, null, null], anims=[195, 189]. +NPC id=6392, name=Oldak, level=0, option=[Talk-to, null, Buy-sphere, null, null], anims=[6040, 6041]. +NPC id=6393, name=Zanik, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=6394, name=null, level=1, option=[null, null, null, null, null], anims=[6040, 6041]. +NPC id=6395, name=Zanik, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=6396, name=null, level=1, option=[null, null, null, null, null], anims=[6040, 6041]. +NPC id=6397, name=Zanik, level=0, option=[null, null, null, null, null], anims=[6040, 6041]. +NPC id=6398, name=null, level=1, option=[null, null, null, null, null], anims=[6040, 6041]. +NPC id=6399, name=Zanik, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=6400, name=null, level=0, option=[Talk-to, null, Buy-sphere, null, null], anims=[7329, 6041]. +NPC id=6401, name=Oldak, level=0, option=[Talk-to, null, null, null, null], anims=[6040, 6041]. +NPC id=6402, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6403, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6404, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6405, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6406, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6407, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6408, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6409, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6410, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6411, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6412, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6413, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6414, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6415, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6416, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6417, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6418, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6419, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6420, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6421, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6422, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6423, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6424, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6425, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6426, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6427, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6428, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6429, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6430, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6431, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6432, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6433, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6434, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6435, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6436, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6437, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6438, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6439, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6440, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6441, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6442, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6443, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6444, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6445, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6446, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6447, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6448, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6449, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6450, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6451, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6452, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6453, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6454, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6455, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6456, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6457, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6458, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6459, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6460, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6461, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6462, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6463, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6464, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6465, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6466, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6467, name=Goblin, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6468, name=Skoblin, level=15, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=6469, name=Snothead, level=35, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=6470, name=Snailfeet, level=45, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=6471, name=Mosschin, level=55, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=6472, name=Redeyes, level=65, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=6473, name=Strongbones, level=75, option=[null, Attack, null, null, null], anims=[6181, 6180]. +NPC id=6474, name=Snothead, level=0, option=[Talk-to, null, null, null, null], anims=[7325, 7325]. +NPC id=6475, name=Snailfeet, level=0, option=[Talk-to, null, null, null, null], anims=[7325, 7325]. +NPC id=6476, name=Mosschin, level=0, option=[Talk-to, null, null, null, null], anims=[7325, 7325]. +NPC id=6477, name=Redeyes, level=0, option=[Talk-to, null, null, null, null], anims=[7325, 7325]. +NPC id=6478, name=Strongbones, level=0, option=[Talk-to, null, null, null, null], anims=[7325, 7325]. +NPC id=6479, name=Grubfoot, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6480, name=null, level=1, option=[null, null, null, null, null], anims=[6181, 6180]. +NPC id=6481, name=Grubfoot, level=0, option=[Talk-to, null, null, null, null], anims=[6181, 6180]. +NPC id=6482, name=Priest, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[6181, 6180]. +NPC id=6483, name=Priest, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[6181, 6180]. +NPC id=6484, name=Priest, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[6181, 6180]. +NPC id=6485, name=Priest, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[6181, 6180]. +NPC id=6486, name=Priest, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[6181, 6180]. +NPC id=6487, name=Priest, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[6181, 6180]. +NPC id=6488, name=Preacher, level=0, option=[null, null, null, null, null], anims=[7315, 6180]. +NPC id=6489, name=High priest, level=0, option=[Talk-to, null, null, null, null], anims=[7333, 7333]. +NPC id=6490, name=Goblin, level=0, option=[null, null, null, null, null], anims=[6181, 6180]. +NPC id=6491, name=Goblin, level=0, option=[null, null, null, null, null], anims=[6181, 6180]. +NPC id=6492, name=Goblin, level=0, option=[null, null, null, null, null], anims=[6181, 6180]. +NPC id=6493, name=Goblin, level=0, option=[null, null, null, null, null], anims=[6181, 6180]. +NPC id=6494, name=Goblin, level=0, option=[null, null, null, null, null], anims=[6181, 6180]. +NPC id=6495, name=Goblin, level=0, option=[null, null, null, null, null], anims=[6181, 6180]. +NPC id=6496, name=Goblin guard, level=0, option=[Talk-to, null, null, null, null], anims=[6186, 6187]. +NPC id=6497, name=Goblin guard, level=0, option=[Talk-to, null, null, null, null], anims=[6186, 6187]. +NPC id=6498, name=Guard, level=0, option=[Talk-to, null, null, null, null], anims=[6186, 6187]. +NPC id=6499, name=Guard, level=0, option=[Talk-to, null, null, null, null], anims=[6186, 6187]. +NPC id=6500, name=Guard, level=0, option=[Talk-to, null, null, null, null], anims=[6186, 6187]. +NPC id=6501, name=Guard, level=0, option=[Talk-to, null, null, null, null], anims=[6186, 6187]. +NPC id=6502, name=Guard, level=0, option=[Talk-to, null, null, null, null], anims=[6186, 6187]. +NPC id=6503, name=Guard, level=0, option=[Talk-to, null, null, null, null], anims=[6186, 6187]. +NPC id=6504, name=Ghost, level=0, option=[Talk-to, null, null, null, null], anims=[7343, 7342]. +NPC id=6505, name=null, level=1, option=[null, null, null, null, null], anims=[7343, 7342]. +NPC id=6506, name=Registrar 1, level=0, option=[Talk-to, null, null, null, null], anims=[1705, -1]. +NPC id=6507, name=Registrar 2, level=0, option=[Talk-to, null, null, null, null], anims=[1705, -1]. +NPC id=6508, name=Registrar 3, level=0, option=[Talk-to, null, null, null, null], anims=[1705, -1]. +NPC id=6509, name=Registrar 4, level=0, option=[Talk-to, null, null, null, null], anims=[1705, -1]. +NPC id=6510, name=Jury, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=6511, name=Jury, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=6512, name=Spectator, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=6513, name=Spectator, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=6514, name=Spectator, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=6515, name=Spectator, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=6516, name=Spectator, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=6517, name=Spectator, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=6518, name=Spectator, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=6519, name=Spectator, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=6520, name=Head Registrar, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=6521, name=Grand Exchange Tutor, level=0, option=[Talk-to, null, null, null, null], anims=[7368, 7368]. +NPC id=6522, name=Brugsen Bursen, level=0, option=[Talk-to, null, null, null, null], anims=[7369, 7369]. +NPC id=6523, name=Farid Morrisane (ores), level=0, option=[Talk-to, null, Info-ores, null, null], anims=[7367, 7367]. +NPC id=6524, name=Bob Barter (herbs), level=0, option=[Talk-to, null, Info-herbs, null, null], anims=[7366, 7366]. +NPC id=6525, name=Murky Matt (runes), level=0, option=[Talk-to, null, Info-runes, null, null], anims=[7365, 7365]. +NPC id=6526, name=Relobo Blinyo (logs), level=0, option=[Talk-to, null, Info-logs, null, null], anims=[7364, 7364]. +NPC id=6527, name=Hofuthand (armour and weapons), level=0, option=[Talk-to, null, Info-combat, null, null], anims=[7370, 7370]. +NPC id=6528, name=Grand Exchange clerk, level=0, option=[Talk-to, null, Exchange, History, Sets], anims=[808, -1]. +NPC id=6529, name=Grand Exchange clerk, level=0, option=[Talk-to, null, Exchange, History, Sets], anims=[808, -1]. +NPC id=6530, name=Grand Exchange clerk, level=0, option=[Talk-to, null, Exchange, History, Sets], anims=[808, -1]. +NPC id=6531, name=Grand Exchange clerk, level=0, option=[Talk-to, null, Exchange, History, Sets], anims=[808, -1]. +NPC id=6532, name=Banker, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[808, -1]. +NPC id=6533, name=Banker, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[808, -1]. +NPC id=6534, name=Banker, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[808, -1]. +NPC id=6535, name=Banker, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[808, -1]. +NPC id=6536, name=Registrar 5, level=0, option=[Talk-to, null, null, null, null], anims=[1705, -1]. +NPC id=6537, name=Mandrith, level=0, option=[Talk-to, null, null, null, null], anims=[7389, 7390]. +NPC id=6538, name=Banker, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[5607, 5606]. +NPC id=6539, name=Charley the Cleaner, level=0, option=[Talk-to, null, null, null, null], anims=[5800, 5799]. +NPC id=6540, name=Scotty the Cleaner, level=0, option=[Talk-to, null, null, null, null], anims=[5800, 5799]. +NPC id=6541, name=Sanchez the Cleaner, level=0, option=[Talk-to, null, null, null, null], anims=[5800, 5799]. +NPC id=6542, name=Calladin, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=6543, name=, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6544, name=, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6545, name=null, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6546, name=null, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6547, name=null, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6548, name=null, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6549, name=null, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6550, name=null, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6551, name=null, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6552, name=null, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6553, name=null, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6554, name=null, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6555, name=null, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6556, name=null, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6557, name=null, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6558, name=null, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6559, name=null, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6560, name=null, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6561, name=null, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6562, name=null, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6563, name=null, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6564, name=null, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6565, name=Grave marker, level=0, option=[Read, null, null, Bless, Demolish], anims=[-1, -1]. +NPC id=6566, name=Broken grave marker, level=0, option=[Read, null, Repair, Bless, Demolish], anims=[-1, -1]. +NPC id=6567, name=Collapsing grave marker, level=0, option=[Read, null, Repair, Bless, Demolish], anims=[-1, -1]. +NPC id=6568, name=Grave marker, level=0, option=[Read, null, null, Bless, Demolish], anims=[7375, -1]. +NPC id=6569, name=Broken grave marker, level=0, option=[Read, null, Repair, Bless, Demolish], anims=[7375, -1]. +NPC id=6570, name=Collapsing grave marker, level=0, option=[Read, null, Repair, Bless, Demolish], anims=[7375, -1]. +NPC id=6571, name=Gravestone, level=0, option=[Read, null, null, Bless, Demolish], anims=[-1, -1]. +NPC id=6572, name=Broken gravestone, level=0, option=[Read, null, Repair, Bless, Demolish], anims=[-1, -1]. +NPC id=6573, name=Collapsing gravestone, level=0, option=[Read, null, Repair, Bless, Demolish], anims=[-1, -1]. +NPC id=6574, name=Gravestone, level=0, option=[Read, null, null, Bless, Demolish], anims=[-1, -1]. +NPC id=6575, name=Broken gravestone, level=0, option=[Read, null, Repair, Bless, Demolish], anims=[-1, -1]. +NPC id=6576, name=Collapsing gravestone, level=0, option=[Read, null, Repair, Bless, Demolish], anims=[-1, -1]. +NPC id=6577, name=Gravestone, level=0, option=[Read, null, null, Bless, Demolish], anims=[-1, -1]. +NPC id=6578, name=Broken gravestone, level=0, option=[Read, null, Repair, Bless, Demolish], anims=[-1, -1]. +NPC id=6579, name=Collapsing gravestone, level=0, option=[Read, null, Repair, Bless, Demolish], anims=[-1, -1]. +NPC id=6580, name=Stele, level=0, option=[Read, null, null, Bless, Demolish], anims=[-1, -1]. +NPC id=6581, name=Broken stele, level=0, option=[Read, null, Repair, Bless, Demolish], anims=[-1, -1]. +NPC id=6582, name=Collapsing stele, level=0, option=[Read, null, Repair, Bless, Demolish], anims=[-1, -1]. +NPC id=6583, name=Saradomin symbol, level=0, option=[Read, null, null, Bless, Demolish], anims=[-1, -1]. +NPC id=6584, name=Broken Saradomin symbol, level=0, option=[Read, null, Repair, Bless, Demolish], anims=[-1, -1]. +NPC id=6585, name=Collapsing Saradomin symbol, level=0, option=[Read, null, Repair, Bless, Demolish], anims=[-1, -1]. +NPC id=6586, name=Zamorak symbol, level=0, option=[Read, null, null, Bless, Demolish], anims=[-1, -1]. +NPC id=6587, name=Broken Zamorak symbol, level=0, option=[Read, null, Repair, Bless, Demolish], anims=[-1, -1]. +NPC id=6588, name=Collapsing Zamorak symbol, level=0, option=[Read, null, Repair, Bless, Demolish], anims=[-1, -1]. +NPC id=6589, name=Guthix symbol, level=0, option=[Read, null, null, Bless, Demolish], anims=[-1, -1]. +NPC id=6590, name=Broken Guthix symbol, level=0, option=[Read, null, Repair, Bless, Demolish], anims=[-1, -1]. +NPC id=6591, name=Collapsing Guthix symbol, level=0, option=[Read, null, Repair, Bless, Demolish], anims=[-1, -1]. +NPC id=6592, name=Bandos symbol, level=0, option=[Read, null, null, Bless, Demolish], anims=[-1, -1]. +NPC id=6593, name=Broken Bandos symbol, level=0, option=[Read, null, Repair, Bless, Demolish], anims=[-1, -1]. +NPC id=6594, name=Collapsing Bandos symbol, level=0, option=[Read, null, Repair, Bless, Demolish], anims=[-1, -1]. +NPC id=6595, name=Armadyl symbol, level=0, option=[Read, null, null, Bless, Demolish], anims=[-1, -1]. +NPC id=6596, name=Broken Armadyl symbol, level=0, option=[Read, null, Repair, Bless, Demolish], anims=[-1, -1]. +NPC id=6597, name=Collapsing Armadyl symbol, level=0, option=[Read, null, Repair, Bless, Demolish], anims=[-1, -1]. +NPC id=6598, name=Memorial stone, level=0, option=[Read, null, null, Bless, Demolish], anims=[-1, -1]. +NPC id=6599, name=Broken memorial stone, level=0, option=[Read, null, Repair, Bless, Demolish], anims=[-1, -1]. +NPC id=6600, name=Collapsing memorial stone, level=0, option=[Read, null, Repair, Bless, Demolish], anims=[-1, -1]. +NPC id=6601, name=Memorial stone, level=0, option=[Read, null, null, Bless, Demolish], anims=[-1, -1]. +NPC id=6602, name=Broken memorial stone, level=0, option=[Read, null, Repair, Bless, Demolish], anims=[-1, -1]. +NPC id=6603, name=Collapsing memorial stone, level=0, option=[Read, null, Repair, Bless, Demolish], anims=[-1, -1]. +NPC id=6604, name=Revenant imp, level=7, option=[null, Attack, null, null, null], anims=[7405, 7406]. +NPC id=6605, name=Revenant goblin, level=15, option=[null, Attack, null, null, null], anims=[7451, 7452]. +NPC id=6606, name=Revenant icefiend, level=45, option=[null, Attack, null, null, null], anims=[7486, 7487]. +NPC id=6607, name=Revenant werewolf, level=75, option=[null, Attack, null, null, null], anims=[7400, 7401]. +NPC id=6608, name=Revenant hobgoblin, level=60, option=[null, Attack, null, null, null], anims=[7421, 7422]. +NPC id=6609, name=Revenant werewolf, level=75, option=[null, Attack, null, null, null], anims=[7400, 7401]. +NPC id=6610, name=Revenant ork, level=105, option=[null, Attack, null, null, null], anims=[7414, 7415]. +NPC id=6611, name=Revenant knight, level=126, option=[null, Attack, null, null, null], anims=[7444, 7445]. +NPC id=6612, name=Revenant goblin, level=30, option=[null, Attack, null, null, null], anims=[7451, 7452]. +NPC id=6613, name=Revenant vampire, level=68, option=[null, Attack, null, null, null], anims=[7430, 7431]. +NPC id=6614, name=Revenant werewolf, level=75, option=[null, Attack, null, null, null], anims=[7400, 7401]. +NPC id=6615, name=Revenant ork, level=105, option=[null, Attack, null, null, null], anims=[7414, 7415]. +NPC id=6616, name=Revenant goblin, level=15, option=[null, Attack, null, null, null], anims=[7451, 7452]. +NPC id=6617, name=Revenant werewolf, level=75, option=[null, Attack, null, null, null], anims=[7400, 7401]. +NPC id=6618, name=Revenant ork, level=105, option=[null, Attack, null, null, null], anims=[7414, 7415]. +NPC id=6619, name=Revenant knight, level=126, option=[null, Attack, null, null, null], anims=[7444, 7445]. +NPC id=6620, name=Revenant goblin, level=22, option=[null, Attack, null, null, null], anims=[7451, 7452]. +NPC id=6621, name=Revenant icefiend, level=45, option=[null, Attack, null, null, null], anims=[7486, 7487]. +NPC id=6622, name=Revenant pyrefiend, level=52, option=[null, Attack, null, null, null], anims=[7486, 7487]. +NPC id=6623, name=Revenant vampire, level=68, option=[null, Attack, null, null, null], anims=[7430, 7431]. +NPC id=6624, name=Revenant ork, level=105, option=[null, Attack, null, null, null], anims=[7414, 7415]. +NPC id=6625, name=Revenant werewolf, level=75, option=[null, Attack, null, null, null], anims=[7400, 7401]. +NPC id=6626, name=Revenant ork, level=105, option=[null, Attack, null, null, null], anims=[7414, 7415]. +NPC id=6627, name=Revenant knight, level=126, option=[null, Attack, null, null, null], anims=[7444, 7445]. +NPC id=6628, name=Revenant icefiend, level=45, option=[null, Attack, null, null, null], anims=[7486, 7487]. +NPC id=6629, name=Revenant ork, level=105, option=[null, Attack, null, null, null], anims=[7414, 7415]. +NPC id=6630, name=Revenant knight, level=126, option=[null, Attack, null, null, null], anims=[7444, 7445]. +NPC id=6631, name=Revenant pyrefiend, level=52, option=[null, Attack, null, null, null], anims=[7486, 7487]. +NPC id=6632, name=Revenant werewolf, level=75, option=[null, Attack, null, null, null], anims=[7400, 7401]. +NPC id=6633, name=Revenant ork, level=105, option=[null, Attack, null, null, null], anims=[7414, 7415]. +NPC id=6634, name=Revenant knight, level=126, option=[null, Attack, null, null, null], anims=[7444, 7445]. +NPC id=6635, name=Revenant imp, level=7, option=[null, Attack, null, null, null], anims=[7405, 7406]. +NPC id=6636, name=Revenant goblin, level=15, option=[null, Attack, null, null, null], anims=[7451, 7452]. +NPC id=6637, name=Revenant goblin, level=22, option=[null, Attack, null, null, null], anims=[7451, 7452]. +NPC id=6638, name=Revenant goblin, level=30, option=[null, Attack, null, null, null], anims=[7451, 7452]. +NPC id=6639, name=Revenant goblin, level=37, option=[null, Attack, null, null, null], anims=[7451, 7452]. +NPC id=6640, name=Revenant icefiend, level=45, option=[null, Attack, null, null, null], anims=[7486, 7487]. +NPC id=6641, name=Revenant pyrefiend, level=52, option=[null, Attack, null, null, null], anims=[7486, 7487]. +NPC id=6642, name=Revenant hobgoblin, level=60, option=[null, Attack, null, null, null], anims=[7421, 7422]. +NPC id=6643, name=Revenant vampire, level=68, option=[null, Attack, null, null, null], anims=[7430, 7431]. +NPC id=6644, name=Revenant werewolf, level=75, option=[null, Attack, null, null, null], anims=[7400, 7401]. +NPC id=6645, name=Revenant cyclops, level=82, option=[null, Attack, null, null, null], anims=[7458, 7459]. +NPC id=6646, name=Revenant hellhound, level=90, option=[null, Attack, null, null, null], anims=[7465, 7466]. +NPC id=6647, name=Revenant demon, level=98, option=[null, Attack, null, null, null], anims=[7479, 7480]. +NPC id=6648, name=Revenant ork, level=105, option=[null, Attack, null, null, null], anims=[7414, 7415]. +NPC id=6649, name=Revenant dark beast, level=120, option=[null, Attack, null, null, null], anims=[7472, 7473]. +NPC id=6650, name=Revenant knight, level=126, option=[null, Attack, null, null, null], anims=[7444, 7445]. +NPC id=6651, name=Revenant goblin, level=22, option=[null, Attack, null, null, null], anims=[7451, 7452]. +NPC id=6652, name=Revenant vampire, level=68, option=[null, Attack, null, null, null], anims=[7430, 7431]. +NPC id=6653, name=Revenant ork, level=105, option=[null, Attack, null, null, null], anims=[7414, 7415]. +NPC id=6654, name=Revenant knight, level=126, option=[null, Attack, null, null, null], anims=[7444, 7445]. +NPC id=6655, name=Revenant imp, level=7, option=[null, Attack, null, null, null], anims=[7405, 7406]. +NPC id=6656, name=Revenant goblin, level=15, option=[null, Attack, null, null, null], anims=[7451, 7452]. +NPC id=6657, name=Revenant goblin, level=30, option=[null, Attack, null, null, null], anims=[7451, 7452]. +NPC id=6658, name=Revenant goblin, level=37, option=[null, Attack, null, null, null], anims=[7451, 7452]. +NPC id=6659, name=Revenant icefiend, level=45, option=[null, Attack, null, null, null], anims=[7486, 7487]. +NPC id=6660, name=Revenant pyrefiend, level=52, option=[null, Attack, null, null, null], anims=[7486, 7487]. +NPC id=6661, name=Revenant hobgoblin, level=60, option=[null, Attack, null, null, null], anims=[7421, 7422]. +NPC id=6662, name=Revenant vampire, level=68, option=[null, Attack, null, null, null], anims=[7430, 7431]. +NPC id=6663, name=Revenant werewolf, level=75, option=[null, Attack, null, null, null], anims=[7400, 7401]. +NPC id=6664, name=Revenant ork, level=105, option=[null, Attack, null, null, null], anims=[7414, 7415]. +NPC id=6665, name=Revenant knight, level=126, option=[null, Attack, null, null, null], anims=[7444, 7445]. +NPC id=6666, name=Revenant imp, level=7, option=[null, Attack, null, null, null], anims=[7405, 7406]. +NPC id=6667, name=Revenant goblin, level=30, option=[null, Attack, null, null, null], anims=[7451, 7452]. +NPC id=6668, name=Revenant pyrefiend, level=52, option=[null, Attack, null, null, null], anims=[7486, 7487]. +NPC id=6669, name=Revenant vampire, level=68, option=[null, Attack, null, null, null], anims=[7430, 7431]. +NPC id=6670, name=Revenant ork, level=105, option=[null, Attack, null, null, null], anims=[7414, 7415]. +NPC id=6671, name=Revenant vampire, level=68, option=[null, Attack, null, null, null], anims=[7430, 7431]. +NPC id=6672, name=Revenant ork, level=105, option=[null, Attack, null, null, null], anims=[7414, 7415]. +NPC id=6673, name=Revenant knight, level=126, option=[null, Attack, null, null, null], anims=[7444, 7445]. +NPC id=6674, name=Revenant vampire, level=68, option=[null, Attack, null, null, null], anims=[7430, 7431]. +NPC id=6675, name=Revenant werewolf, level=75, option=[null, Attack, null, null, null], anims=[7400, 7401]. +NPC id=6676, name=Revenant knight, level=126, option=[null, Attack, null, null, null], anims=[7444, 7445]. +NPC id=6677, name=Revenant imp, level=7, option=[null, Attack, null, null, null], anims=[7405, 7406]. +NPC id=6678, name=Revenant goblin, level=15, option=[null, Attack, null, null, null], anims=[7451, 7452]. +NPC id=6679, name=Revenant goblin, level=22, option=[null, Attack, null, null, null], anims=[7451, 7452]. +NPC id=6680, name=Revenant goblin, level=30, option=[null, Attack, null, null, null], anims=[7451, 7452]. +NPC id=6681, name=Revenant goblin, level=37, option=[null, Attack, null, null, null], anims=[7451, 7452]. +NPC id=6682, name=Revenant icefiend, level=45, option=[null, Attack, null, null, null], anims=[7486, 7487]. +NPC id=6683, name=Revenant pyrefiend, level=52, option=[null, Attack, null, null, null], anims=[7486, 7487]. +NPC id=6684, name=Revenant hobgoblin, level=60, option=[null, Attack, null, null, null], anims=[7421, 7422]. +NPC id=6685, name=Revenant vampire, level=68, option=[null, Attack, null, null, null], anims=[7430, 7431]. +NPC id=6686, name=Revenant werewolf, level=75, option=[null, Attack, null, null, null], anims=[7400, 7401]. +NPC id=6687, name=Revenant cyclops, level=82, option=[null, Attack, null, null, null], anims=[7458, 7459]. +NPC id=6688, name=Revenant hellhound, level=90, option=[null, Attack, null, null, null], anims=[7465, 7466]. +NPC id=6689, name=Revenant demon, level=98, option=[null, Attack, null, null, null], anims=[7479, 7480]. +NPC id=6690, name=Revenant ork, level=105, option=[null, Attack, null, null, null], anims=[7414, 7415]. +NPC id=6691, name=Revenant dark beast, level=120, option=[null, Attack, null, null, null], anims=[7472, 7473]. +NPC id=6692, name=Revenant knight, level=126, option=[null, Attack, null, null, null], anims=[7444, 7445]. +NPC id=6693, name=Revenant goblin, level=30, option=[null, Attack, null, null, null], anims=[7451, 7452]. +NPC id=6694, name=Revenant icefiend, level=45, option=[null, Attack, null, null, null], anims=[7486, 7487]. +NPC id=6695, name=Revenant vampire, level=68, option=[null, Attack, null, null, null], anims=[7430, 7431]. +NPC id=6696, name=Revenant ork, level=105, option=[null, Attack, null, null, null], anims=[7414, 7415]. +NPC id=6697, name=Revenant imp, level=7, option=[null, Attack, null, null, null], anims=[7405, 7406]. +NPC id=6698, name=Revenant goblin, level=22, option=[null, Attack, null, null, null], anims=[7451, 7452]. +NPC id=6699, name=Revenant goblin, level=37, option=[null, Attack, null, null, null], anims=[7451, 7452]. +NPC id=6700, name=Revenant vampire, level=68, option=[null, Attack, null, null, null], anims=[7430, 7431]. +NPC id=6701, name=Revenant werewolf, level=75, option=[null, Attack, null, null, null], anims=[7400, 7401]. +NPC id=6702, name=Revenant ork, level=105, option=[null, Attack, null, null, null], anims=[7414, 7415]. +NPC id=6703, name=Revenant imp, level=7, option=[null, Attack, null, null, null], anims=[7405, 7406]. +NPC id=6704, name=Revenant goblin, level=15, option=[null, Attack, null, null, null], anims=[7451, 7452]. +NPC id=6705, name=Revenant goblin, level=22, option=[null, Attack, null, null, null], anims=[7451, 7452]. +NPC id=6706, name=Revenant goblin, level=30, option=[null, Attack, null, null, null], anims=[7451, 7452]. +NPC id=6707, name=Revenant goblin, level=37, option=[null, Attack, null, null, null], anims=[7451, 7452]. +NPC id=6708, name=Revenant icefiend, level=45, option=[null, Attack, null, null, null], anims=[7486, 7487]. +NPC id=6709, name=Revenant pyrefiend, level=52, option=[null, Attack, null, null, null], anims=[7486, 7487]. +NPC id=6710, name=Revenant hobgoblin, level=60, option=[null, Attack, null, null, null], anims=[7421, 7422]. +NPC id=6711, name=Revenant vampire, level=68, option=[null, Attack, null, null, null], anims=[7430, 7431]. +NPC id=6712, name=Revenant werewolf, level=75, option=[null, Attack, null, null, null], anims=[7400, 7401]. +NPC id=6713, name=Revenant ork, level=105, option=[null, Attack, null, null, null], anims=[7414, 7415]. +NPC id=6714, name=Revenant knight, level=126, option=[null, Attack, null, null, null], anims=[7444, 7445]. +NPC id=6715, name=Revenant imp, level=7, option=[null, Attack, null, null, null], anims=[7405, 7406]. +NPC id=6716, name=Revenant goblin, level=15, option=[null, Attack, null, null, null], anims=[7451, 7452]. +NPC id=6717, name=Revenant goblin, level=22, option=[null, Attack, null, null, null], anims=[7451, 7452]. +NPC id=6718, name=Revenant goblin, level=30, option=[null, Attack, null, null, null], anims=[7451, 7452]. +NPC id=6719, name=Revenant goblin, level=37, option=[null, Attack, null, null, null], anims=[7451, 7452]. +NPC id=6720, name=Revenant icefiend, level=45, option=[null, Attack, null, null, null], anims=[7486, 7487]. +NPC id=6721, name=Revenant pyrefiend, level=52, option=[null, Attack, null, null, null], anims=[7486, 7487]. +NPC id=6722, name=Revenant hobgoblin, level=60, option=[null, Attack, null, null, null], anims=[7421, 7422]. +NPC id=6723, name=Revenant vampire, level=68, option=[null, Attack, null, null, null], anims=[7430, 7431]. +NPC id=6724, name=Revenant werewolf, level=75, option=[null, Attack, null, null, null], anims=[7400, 7401]. +NPC id=6725, name=Revenant ork, level=105, option=[null, Attack, null, null, null], anims=[7414, 7415]. +NPC id=6726, name=Revenant knight, level=126, option=[null, Attack, null, null, null], anims=[7444, 7445]. +NPC id=6727, name=Revenant hobgoblin, level=60, option=[null, Attack, null, null, null], anims=[7421, 7422]. +NPC id=6728, name=Revenant werewolf, level=75, option=[null, Attack, null, null, null], anims=[7400, 7401]. +NPC id=6729, name=Revenant ork, level=105, option=[null, Attack, null, null, null], anims=[7414, 7415]. +NPC id=6730, name=Revenant knight, level=126, option=[null, Attack, null, null, null], anims=[7444, 7445]. +NPC id=6731, name=Queen of Snow, level=0, option=[Talk-to, null, null, null, null], anims=[7188, 6531]. +NPC id=6732, name=Snow imp, level=0, option=[Talk-to, null, null, null, null], anims=[171, 168]. +NPC id=6733, name=Snow imp, level=0, option=[Talk-to, null, null, null, null], anims=[171, 168]. +NPC id=6734, name=Snow imp, level=0, option=[Talk-to, null, null, null, null], anims=[171, 168]. +NPC id=6735, name=Snow imp, level=0, option=[Talk-to, null, null, null, null], anims=[171, 168]. +NPC id=6736, name=Snow imp, level=0, option=[Talk-to, null, null, null, null], anims=[171, 168]. +NPC id=6737, name=Snow imp, level=0, option=[Talk-to, null, null, null, null], anims=[171, 168]. +NPC id=6738, name=Snow imp, level=0, option=[Talk-to, null, null, null, null], anims=[171, 168]. +NPC id=6739, name=Snow imp, level=0, option=[Talk-to, null, null, null, null], anims=[171, 168]. +NPC id=6740, name=Snow, level=0, option=[null, null, null, null, null], anims=[7543, 7543]. +NPC id=6741, name=Snow, level=0, option=[null, null, null, null, null], anims=[7553, 7553]. +NPC id=6742, name=Barbarian snowman, level=0, option=[Talk-to, null, null, null, null], anims=[7557, 7556]. +NPC id=6743, name=Dragon snowman, level=0, option=[Talk-to, null, null, null, null], anims=[7557, 7556]. +NPC id=6744, name=Dwarf snowman, level=0, option=[Talk-to, null, null, null, null], anims=[7557, 7556]. +NPC id=6745, name=Pirate snowman, level=0, option=[Talk-to, null, null, null, null], anims=[7557, 7556]. +NPC id=6746, name=Snowman, level=0, option=[Talk-to, null, null, null, null], anims=[7557, 7556]. +NPC id=6747, name=Snow ranger, level=29, option=[Pelt, null, Talk-to, null, null], anims=[7557, 7556]. +NPC id=6748, name=Snow warrior, level=29, option=[Pelt, null, Talk-to, null, null], anims=[7557, 7556]. +NPC id=6749, name=Snow mage, level=29, option=[Pelt, null, Talk-to, null, null], anims=[7557, 7556]. +NPC id=6750, name=Pet shop owner, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=6751, name=null, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=6752, name=Bulldog, level=0, option=[null, null, null, null, null], anims=[7575, 7576]. +NPC id=6753, name=Mummy, level=125, option=[null, Attack, null, null, null], anims=[5548, 5552]. +NPC id=6754, name=Mummy, level=125, option=[null, Attack, null, null, null], anims=[5548, 5552]. +NPC id=6755, name=Mummy, level=125, option=[null, Attack, null, null, null], anims=[5548, 5552]. +NPC id=6756, name=Mummy, level=125, option=[null, Attack, null, null, null], anims=[5548, 5552]. +NPC id=6757, name=Mummy, level=125, option=[null, Attack, null, null, null], anims=[5548, 5552]. +NPC id=6758, name=Mummy, level=125, option=[null, Attack, null, null, null], anims=[5548, 5552]. +NPC id=6759, name=Mummy, level=125, option=[null, Attack, null, null, null], anims=[5548, 5552]. +NPC id=6760, name=Mummy, level=125, option=[null, Attack, null, null, null], anims=[5548, 5552]. +NPC id=6761, name=Dried zombie, level=89, option=[null, Attack, null, null, null], anims=[5565, -1]. +NPC id=6762, name=Dried zombie, level=94, option=[null, Attack, null, null, null], anims=[5565, -1]. +NPC id=6763, name=Dried zombie, level=110, option=[null, Attack, null, null, null], anims=[5565, -1]. +NPC id=6764, name=Skeleton, level=97, option=[null, Attack, null, null, null], anims=[5483, 5481]. +NPC id=6765, name=Skeleton, level=108, option=[null, Attack, null, null, null], anims=[5483, 5481]. +NPC id=6766, name=Skeleton, level=120, option=[null, Attack, null, null, null], anims=[5483, 5481]. +NPC id=6767, name=Skeleton, level=115, option=[null, Attack, null, null, null], anims=[5483, 5481]. +NPC id=6768, name=Skeleton, level=140, option=[null, Attack, null, null, null], anims=[5483, 5479]. +NPC id=6769, name=Doorman, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=6770, name=Giant scarab, level=191, option=[null, Attack, null, null, null], anims=[7593, 7592]. +NPC id=6771, name=Giant scarab, level=206, option=[null, Attack, null, null, null], anims=[7593, 7592]. +NPC id=6772, name=Scarab larva, level=14, option=[null, Attack, null, null, null], anims=[7654, 7653]. +NPC id=6773, name=Scabaras ranger, level=103, option=[null, Attack, null, null, null], anims=[7605, 7606]. +NPC id=6774, name=Scabaras lancer, level=112, option=[null, Attack, null, null, null], anims=[7610, 7611]. +NPC id=6775, name=Scabaras priest, level=1, option=[null, null, null, null, null], anims=[7605, 7606]. +NPC id=6776, name=Scabaras locust, level=106, option=[null, Attack, null, null, null], anims=[7583, 7582]. +NPC id=6777, name=Locust lancer, level=109, option=[null, Attack, null, null, null], anims=[7583, 7582]. +NPC id=6778, name=Locust ranger, level=98, option=[null, Attack, null, null, null], anims=[7583, 7582]. +NPC id=6779, name=Crocodile, level=89, option=[null, Attack, null, null, null], anims=[7589, 7587]. +NPC id=6780, name=Scabaras mage, level=98, option=[null, Attack, null, null, null], anims=[7618, 7619]. +NPC id=6781, name=Scabaras mage, level=88, option=[null, Attack, null, null, null], anims=[7618, 7619]. +NPC id=6782, name=Maisa, level=0, option=[Talk-to, null, null, null, null], anims=[7629, 819]. +NPC id=6783, name=Maisa, level=0, option=[Talk-to, null, null, null, null], anims=[7629, 819]. +NPC id=6784, name=Priest, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=6785, name=Clay golem, level=0, option=[Talk-to, null, null, null, null], anims=[1913, 1912]. +NPC id=6786, name=Lead archaeologist Abigail, level=0, option=[Talk-to, null, null, null, null], anims=[7579, -1]. +NPC id=6787, name=Assistant archaeologist Kerner, level=0, option=[Talk-to, null, null, null, null], anims=[7578, -1]. +NPC id=6788, name=High Priest of Scabaras, level=0, option=[Talk-to, null, null, null, null], anims=[7605, 7606]. +NPC id=6789, name=High Priest of Scabaras, level=179, option=[null, Attack, null, null, null], anims=[7610, 7611]. +NPC id=6790, name=High Priest of Scabaras, level=139, option=[null, Attack, null, null, null], anims=[7605, 7606]. +NPC id=6791, name=High Priest of Scabaras, level=148, option=[null, Attack, null, null, null], anims=[7610, 7611]. +NPC id=6792, name=Vulture, level=31, option=[null, Attack, null, null, null], anims=[7659, 7658]. +NPC id=6793, name=null, level=1, option=[Talk-to, null, null, null, null], anims=[7629, -1]. +NPC id=6794, name=Spirit terrorbird, level=0, option=[Interact, null, Store, null, null], anims=[1008, 1007]. +NPC id=6795, name=Spirit terrorbird, level=62, option=[Interact, Attack, Store, null, null], anims=[1008, 1007]. +NPC id=6796, name=Granite crab, level=0, option=[Interact, null, Withdraw, null, null], anims=[8098, 8100]. +NPC id=6797, name=Granite crab, level=26, option=[Interact, Attack, Withdraw, null, null], anims=[8098, 8100]. +NPC id=6798, name=Praying mantis, level=0, option=[Interact, null, null, null, null], anims=[8067, 8072]. +NPC id=6799, name=Praying mantis, level=131, option=[Interact, Attack, null, null, null], anims=[8067, 8072]. +NPC id=6800, name=Giant ent, level=0, option=[Interact, null, Withdraw, null, null], anims=[7849, 7848]. +NPC id=6801, name=Giant ent, level=137, option=[Interact, Attack, Withdraw, null, null], anims=[7849, 7848]. +NPC id=6802, name=Spirit cobra, level=0, option=[Interact, null, null, null, null], anims=[8155, 8158]. +NPC id=6803, name=Spirit cobra, level=105, option=[Interact, Attack, null, null, null], anims=[8155, 8158]. +NPC id=6804, name=Spirit dagannoth, level=0, option=[Interact, null, null, null, null], anims=[7781, 7784]. +NPC id=6805, name=Spirit dagannoth, level=148, option=[Interact, Attack, null, null, null], anims=[7781, 7784]. +NPC id=6806, name=Thorny snail, level=0, option=[Interact, null, Store, null, null], anims=[8146, 8145]. +NPC id=6807, name=Thorny snail, level=26, option=[Interact, Attack, Store, null, null], anims=[8146, 8145]. +NPC id=6808, name=Beaver, level=0, option=[Interact, null, Withdraw, null, null], anims=[7718, 7719]. +NPC id=6809, name=Karamthulhu overlord, level=0, option=[Interact, null, null, null, Drown], anims=[7968, 7961]. +NPC id=6810, name=Karamthulhu overlord, level=95, option=[Interact, Attack, null, null, Drown], anims=[7968, 7961]. +NPC id=6811, name=Hydra, level=0, option=[Interact, null, null, null, null], anims=[7938, 7941]. +NPC id=6812, name=Hydra, level=141, option=[Interact, Attack, null, null, null], anims=[7938, 7941]. +NPC id=6813, name=Bunyip, level=0, option=[Interact, null, null, null, null], anims=[7738, 7735]. +NPC id=6814, name=Bunyip, level=70, option=[Interact, Attack, null, null, null], anims=[7738, 7735]. +NPC id=6815, name=War tortoise, level=0, option=[Interact, null, Store, null, null], anims=[8284, 8281]. +NPC id=6816, name=War tortoise, level=86, option=[Interact, Attack, Store, null, null], anims=[8284, 8281]. +NPC id=6817, name=Fruit bat, level=0, option=[Interact, null, Withdraw, null, null], anims=[8271, 8273]. +NPC id=6818, name=Abyssal parasite, level=0, option=[Interact, null, Store, null, null], anims=[7668, 7667]. +NPC id=6819, name=Abyssal parasite, level=86, option=[Interact, Attack, Store, null, null], anims=[7668, 7667]. +NPC id=6820, name=Abyssal lurker, level=0, option=[Interact, null, Store, null, null], anims=[7677, 7678]. +NPC id=6821, name=Abyssal lurker, level=93, option=[Interact, Attack, Store, null, null], anims=[7677, 7678]. +NPC id=6822, name=Unicorn stallion, level=0, option=[Interact, null, null, null, Cure], anims=[6374, 6373]. +NPC id=6823, name=Unicorn stallion, level=70, option=[Interact, Attack, null, null, Cure], anims=[6374, 6373]. +NPC id=6824, name=Magpie, level=0, option=[Interact, null, Withdraw, null, null], anims=[8008, 8007]. +NPC id=6825, name=Dreadfowl, level=0, option=[Interact, null, null, null, Special], anims=[5386, 7808]. +NPC id=6826, name=Dreadfowl, level=26, option=[Interact, Attack, null, null, Special], anims=[5386, 7808]. +NPC id=6827, name=Stranger plant, level=0, option=[Interact, null, Withdraw, null, null], anims=[8204, 8207]. +NPC id=6828, name=Stranger plant, level=107, option=[Interact, Attack, Withdraw, null, null], anims=[8204, 8207]. +NPC id=6829, name=Spirit wolf, level=0, option=[Interact, null, null, null, null], anims=[8297, 8291]. +NPC id=6830, name=Spirit wolf, level=26, option=[Interact, Attack, null, null, null], anims=[8297, 8291]. +NPC id=6831, name=Desert wyrm, level=0, option=[Interact, null, Burrow, null, null], anims=[7793, 7792]. +NPC id=6832, name=Desert wyrm, level=31, option=[Interact, Attack, Burrow, null, null], anims=[7793, 7792]. +NPC id=6833, name=Evil turnip, level=0, option=[Interact, null, Withdraw, null, null], anims=[8246, 8245]. +NPC id=6834, name=Evil turnip, level=62, option=[Interact, Attack, Withdraw, null, null], anims=[8246, 8245]. +NPC id=6835, name=Vampire bat, level=0, option=[Interact, null, null, null, null], anims=[8271, 8273]. +NPC id=6836, name=Vampire bat, level=44, option=[Interact, Attack, null, null, null], anims=[8271, 8273]. +NPC id=6837, name=Spirit scorpion, level=0, option=[Interact, null, null, null, null], anims=[6252, 6253]. +NPC id=6838, name=Spirit scorpion, level=51, option=[Interact, Attack, null, null, null], anims=[6252, 6253]. +NPC id=6839, name=Arctic bear, level=0, option=[Interact, null, null, null, null], anims=[4919, 4923]. +NPC id=6840, name=Arctic bear, level=122, option=[Interact, Attack, null, null, null], anims=[4919, 4923]. +NPC id=6841, name=Spirit spider, level=0, option=[Interact, null, null, null, null], anims=[5326, 5325]. +NPC id=6842, name=Spirit spider, level=25, option=[Interact, Attack, null, null, null], anims=[5326, 5325]. +NPC id=6843, name=Bloated leech, level=0, option=[Interact, null, null, null, null], anims=[7654, 7653]. +NPC id=6844, name=Bloated leech, level=76, option=[Interact, Attack, null, null, null], anims=[7654, 7653]. +NPC id=6845, name=Honey badger, level=0, option=[Interact, null, null, null, null], anims=[7924, 7923]. +NPC id=6846, name=Honey badger, level=45, option=[Interact, Attack, null, null, null], anims=[7924, 7923]. +NPC id=6847, name=Albino rat, level=0, option=[Interact, null, Withdraw, null, null], anims=[4932, 4931]. +NPC id=6848, name=Albino rat, level=37, option=[Interact, Attack, Withdraw, null, null], anims=[4932, 4931]. +NPC id=6849, name=Granite lobster, level=0, option=[Interact, null, Withdraw, null, null], anims=[8116, 8115]. +NPC id=6850, name=Granite lobster, level=129, option=[Interact, Attack, Withdraw, null, null], anims=[8116, 8115]. +NPC id=6851, name=Macaw, level=0, option=[Interact, null, Withdraw, null, null], anims=[8008, 8007]. +NPC id=6852, name=Macaw, level=0, option=[null, null, null, null, null], anims=[8006, -1]. +NPC id=6853, name=Bronze minotaur, level=0, option=[Interact, null, null, null, null], anims=[8021, 8022]. +NPC id=6854, name=Bronze minotaur, level=50, option=[Interact, Attack, null, null, null], anims=[8021, 8022]. +NPC id=6855, name=Iron minotaur, level=0, option=[Interact, null, null, null, null], anims=[8021, 8022]. +NPC id=6856, name=Iron minotaur, level=70, option=[Interact, Attack, null, null, null], anims=[8021, 8022]. +NPC id=6857, name=Steel minotaur, level=0, option=[Interact, null, null, null, null], anims=[8021, 8022]. +NPC id=6858, name=Steel minotaur, level=90, option=[Interact, Attack, null, null, null], anims=[8021, 8022]. +NPC id=6859, name=Mithril minotaur, level=0, option=[Interact, null, null, null, null], anims=[8021, 8022]. +NPC id=6860, name=Mithril minotaur, level=112, option=[Interact, Attack, null, null, null], anims=[8021, 8022]. +NPC id=6861, name=Adamant minotaur, level=0, option=[Interact, null, null, null, null], anims=[8021, 8022]. +NPC id=6862, name=Adamant minotaur, level=133, option=[Interact, Attack, null, null, null], anims=[8021, 8022]. +NPC id=6863, name=Rune minotaur, level=0, option=[Interact, null, null, null, null], anims=[8021, 8022]. +NPC id=6864, name=Rune minotaur, level=154, option=[Interact, Attack, null, null, null], anims=[8021, 8022]. +NPC id=6865, name=Smoke devil, level=0, option=[Interact, null, null, null, Flames], anims=[7815, 7814]. +NPC id=6866, name=Smoke devil, level=101, option=[Interact, Attack, null, null, Flames], anims=[7815, 7814]. +NPC id=6867, name=Bull ant, level=0, option=[Interact, null, Store, null, null], anims=[7893, 7899]. +NPC id=6868, name=Bull ant, level=58, option=[Interact, Attack, Store, null, null], anims=[7893, 7899]. +NPC id=6869, name=Wolpertinger, level=0, option=[Interact, null, null, null, null], anims=[8301, 8302]. +NPC id=6870, name=Wolpertinger, level=210, option=[Interact, Attack, null, null, null], anims=[8301, 8302]. +NPC id=6871, name=Compost mound, level=0, option=[Interact, null, Withdraw, null, null], anims=[7772, 7768]. +NPC id=6872, name=Compost mound, level=37, option=[Interact, Attack, Withdraw, null, null], anims=[7772, 7768]. +NPC id=6873, name=Pack yak, level=0, option=[Interact, null, Store, null, null], anims=[5785, 5781]. +NPC id=6874, name=Pack yak, level=175, option=[Interact, Attack, Store, null, null], anims=[5785, 5781]. +NPC id=6875, name=Spirit cockatrice, level=0, option=[Interact, null, Withdraw, null, Drain], anims=[7760, 7759]. +NPC id=6876, name=Spirit cockatrice, level=64, option=[Interact, Attack, Withdraw, null, Drain], anims=[7760, 7759]. +NPC id=6877, name=Spirit guthatrice, level=0, option=[Interact, null, Withdraw, null, Drain], anims=[7760, 7759]. +NPC id=6878, name=Spirit guthatrice, level=64, option=[Interact, Attack, Withdraw, null, Drain], anims=[7760, 7759]. +NPC id=6879, name=Spirit saratrice, level=0, option=[Interact, null, Withdraw, null, Drain], anims=[7760, 7759]. +NPC id=6880, name=Spirit saratrice, level=64, option=[Interact, Attack, Withdraw, null, Drain], anims=[7760, 7759]. +NPC id=6881, name=Spirit zamatrice, level=0, option=[Interact, null, Withdraw, null, Drain], anims=[7760, 7759]. +NPC id=6882, name=Spirit zamatrice, level=64, option=[Interact, Attack, Withdraw, null, Drain], anims=[7760, 7759]. +NPC id=6883, name=Spirit pengatrice, level=0, option=[Interact, null, Withdraw, null, Drain], anims=[7760, 7759]. +NPC id=6884, name=Spirit pengatrice, level=64, option=[Interact, Attack, Withdraw, null, Drain], anims=[7760, 7759]. +NPC id=6885, name=Spirit coraxatrice, level=0, option=[Interact, null, Withdraw, null, Drain], anims=[7760, 7759]. +NPC id=6886, name=Spirit coraxatrice, level=64, option=[Interact, Attack, Withdraw, null, Drain], anims=[7760, 7759]. +NPC id=6887, name=Spirit vulatrice, level=0, option=[Interact, null, Withdraw, null, Drain], anims=[7760, 7759]. +NPC id=6888, name=Spirit vulatrice, level=64, option=[Interact, Attack, Withdraw, null, Drain], anims=[7760, 7759]. +NPC id=6889, name=Barker toad, level=0, option=[Interact, null, null, null, Cannon], anims=[7258, 7259]. +NPC id=6890, name=Barker toad, level=112, option=[Interact, Attack, null, null, Cannon], anims=[7258, 7259]. +NPC id=6891, name=Penguin keeper, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=6892, name=Pet shop owner, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=6893, name=Pet shop owner, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=6894, name=Terrier, level=0, option=[null, null, null, null, null], anims=[7575, 8337]. +NPC id=6895, name=Labrador, level=0, option=[null, null, null, null, null], anims=[7575, 8335]. +NPC id=6896, name=Dalmatian, level=0, option=[null, null, null, null, null], anims=[7575, 8331]. +NPC id=6897, name=Bulldog, level=0, option=[null, null, null, null, null], anims=[7575, 7576]. +NPC id=6898, name=Pet shop owner, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=6899, name=Bulldog, level=0, option=[null, null, null, null, null], anims=[7575, 7576]. +NPC id=6900, name=Hatchling dragon, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[27, 21]. +NPC id=6901, name=Baby dragon, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[27, 21]. +NPC id=6902, name=Hatchling dragon, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[27, 21]. +NPC id=6903, name=Baby dragon, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[27, 21]. +NPC id=6904, name=Hatchling dragon, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[27, 21]. +NPC id=6905, name=Baby dragon, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[27, 21]. +NPC id=6906, name=Hatchling dragon, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[27, 21]. +NPC id=6907, name=Baby dragon, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[27, 21]. +NPC id=6908, name=Baby penguin, level=0, option=[Pick-up, null, null, Talk-to, null], anims=[8319, 8318]. +NPC id=6909, name=Penguin, level=0, option=[Pick-up, null, null, Talk-to, null], anims=[8315, 8314]. +NPC id=6910, name=Penguin, level=0, option=[Pick-up, null, null, Talk-to, null], anims=[8315, 8317]. +NPC id=6911, name=Raven chick, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8310, 8312]. +NPC id=6912, name=Raven, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8008, 8007]. +NPC id=6913, name=Baby raccoon, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[7718, 7719]. +NPC id=6914, name=Raccoon, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[7718, 7719]. +NPC id=6915, name=Baby gecko, level=0, option=[Pick-up, null, null, Talk-to, null], anims=[8360, 8358]. +NPC id=6916, name=Gecko, level=0, option=[Pick-up, null, null, Talk-to, null], anims=[8360, 8357]. +NPC id=6917, name=Baby gecko, level=0, option=[null, null, null, null, null], anims=[8360, 8358]. +NPC id=6918, name=Gecko, level=0, option=[null, null, null, null, null], anims=[8360, 8357]. +NPC id=6919, name=Baby squirrel, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8324, 8326]. +NPC id=6920, name=Squirrel, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8324, 8326]. +NPC id=6921, name=Baby squirrel, level=0, option=[null, null, null, null, null], anims=[8324, 8326]. +NPC id=6922, name=Baby chameleon, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8363, 8365]. +NPC id=6923, name=Chameleon, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8363, 8365]. +NPC id=6924, name=Baby chameleon, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8363, 8365]. +NPC id=6925, name=Chameleon, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8363, 8365]. +NPC id=6926, name=Baby chameleon, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8363, 8365]. +NPC id=6927, name=Chameleon, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8363, 8365]. +NPC id=6928, name=Baby chameleon, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8363, 8365]. +NPC id=6929, name=Chameleon, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8363, 8365]. +NPC id=6930, name=Baby chameleon, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8363, 8365]. +NPC id=6931, name=Chameleon, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8363, 8365]. +NPC id=6932, name=Baby chameleon, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8363, 8365]. +NPC id=6933, name=Chameleon, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8363, 8365]. +NPC id=6934, name=Baby chameleon, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8363, 8365]. +NPC id=6935, name=Chameleon, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8363, 8365]. +NPC id=6936, name=Baby chameleon, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8363, 8365]. +NPC id=6937, name=Chameleon, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8363, 8365]. +NPC id=6938, name=Baby chameleon, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8363, 8365]. +NPC id=6939, name=Chameleon, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8363, 8365]. +NPC id=6940, name=Baby chameleon, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8363, 8365]. +NPC id=6941, name=Chameleon, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8363, 8365]. +NPC id=6942, name=Baby monkey, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8346, 8348]. +NPC id=6943, name=Monkey, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8344, 8343]. +NPC id=6944, name=Baby monkey, level=0, option=[null, null, null, null, null], anims=[8346, 8348]. +NPC id=6945, name=Vulture chick, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8310, 8312]. +NPC id=6946, name=Vulture, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[7659, 7658]. +NPC id=6947, name=Baby giant crab, level=0, option=[Pick-up, null, null, Talk-to, null], anims=[8098, 8101]. +NPC id=6948, name=Giant crab, level=0, option=[Pick-up, null, null, Talk-to, null], anims=[8098, 8101]. +NPC id=6949, name=Saradomin chick, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8310, 8312]. +NPC id=6950, name=Saradomin bird, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8008, 8007]. +NPC id=6951, name=Saradomin owl, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8008, 8007]. +NPC id=6952, name=Zamorak chick, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8310, 8312]. +NPC id=6953, name=Zamorak bird, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8008, 8007]. +NPC id=6954, name=Zamorak hawk, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8008, 8007]. +NPC id=6955, name=Guthix chick, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8310, 8312]. +NPC id=6956, name=Guthix bird, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8008, 8007]. +NPC id=6957, name=Guthix raptor, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8008, 8007]. +NPC id=6958, name=Terrier puppy, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[7575, 8336]. +NPC id=6959, name=Terrier, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[7575, 8337]. +NPC id=6960, name=Greyhound puppy, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[7575, 8332]. +NPC id=6961, name=Greyhound, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[7575, 8333]. +NPC id=6962, name=Labrador puppy, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[7575, 8334]. +NPC id=6963, name=Labrador, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[7575, 8335]. +NPC id=6964, name=Dalmatian puppy, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[7575, 8330]. +NPC id=6965, name=Dalmatian, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[7575, 8331]. +NPC id=6966, name=Sheepdog puppy, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[7575, 8334]. +NPC id=6967, name=Sheepdog, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[7575, 8335]. +NPC id=6968, name=Bulldog, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[7575, 7576]. +NPC id=6969, name=Bulldog puppy, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[7575, 8329]. +NPC id=6970, name=Pikkupstix, level=0, option=[Talk-to, null, Trade, Enchant, null], anims=[8528, 8527]. +NPC id=6971, name=Pikkupstix, level=0, option=[Talk-to, null, null, null, null], anims=[8497, 8496]. +NPC id=6972, name=Druid, level=33, option=[null, Attack, null, null, null], anims=[8528, 8529]. +NPC id=6973, name=Druid, level=33, option=[null, Attack, null, null, null], anims=[8528, 8527]. +NPC id=6974, name=Druid, level=33, option=[null, Attack, null, null, null], anims=[8528, 8527]. +NPC id=6975, name=Druid, level=33, option=[null, Attack, null, null, null], anims=[8528, 8529]. +NPC id=6976, name=Druid, level=33, option=[null, Attack, null, null, null], anims=[8528, 8527]. +NPC id=6977, name=Druid, level=33, option=[null, Attack, null, null, null], anims=[8528, 8527]. +NPC id=6978, name=Druid, level=33, option=[null, Attack, null, null, null], anims=[8528, 8527]. +NPC id=6979, name=Druid, level=33, option=[null, Attack, null, null, null], anims=[8528, 8529]. +NPC id=6980, name=Druid, level=33, option=[null, Attack, null, null, null], anims=[8528, 8527]. +NPC id=6981, name=Druidess, level=33, option=[null, Attack, null, null, null], anims=[8528, 8527]. +NPC id=6982, name=Druidess, level=33, option=[null, Attack, null, null, null], anims=[8528, 8529]. +NPC id=6983, name=Druidess, level=33, option=[null, Attack, null, null, null], anims=[8528, 8527]. +NPC id=6984, name=Druidess, level=33, option=[null, Attack, null, null, null], anims=[8528, 8529]. +NPC id=6985, name=Druidess, level=33, option=[null, Attack, null, null, null], anims=[8528, 8527]. +NPC id=6986, name=Druidess, level=33, option=[null, Attack, null, null, null], anims=[8528, 8527]. +NPC id=6987, name=Druidess, level=33, option=[null, Attack, null, null, null], anims=[8528, 8527]. +NPC (wrapper) id=6988, child npcs=[6971, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6971, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6971, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6971, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6971, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6971, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6971, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6971, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6971, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6971, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6971, -1]. +NPC id=6989, name=null, level=0, option=[Talk-to, null, Trade, Enchant, null], anims=[8528, 8527]. +NPC id=6990, name=Giant wolpertinger, level=0, option=[null, null, null, null, null], anims=[8504, 8505]. +NPC id=6991, name=Ibis, level=0, option=[Interact, null, Withdraw, null, null], anims=[8197, 8198]. +NPC id=6992, name=Spirit jelly, level=0, option=[Interact, null, null, null, null], anims=[8572, 8575]. +NPC id=6993, name=Spirit jelly, level=88, option=[Interact, Attack, null, null, null], anims=[8572, 8575]. +NPC id=6994, name=Spirit kalphite, level=0, option=[Interact, null, Store, null, null], anims=[8518, 6220]. +NPC id=6995, name=Spirit kalphite, level=39, option=[Interact, Attack, Store, null, null], anims=[8518, 6220]. +NPC id=6996, name=Bogrog, level=0, option=[Talk-To, null, Trade, Swap, null], anims=[8574, 8573]. +NPC id=6997, name=Baby raccoon, level=0, option=[null, null, null, null, null], anims=[7718, 7719]. +NPC id=6998, name=Revenant dragon, level=135, option=[null, Attack, null, null, null], anims=[8589, 8590]. +NPC id=6999, name=Revenant dragon, level=135, option=[null, Attack, null, null, null], anims=[8589, 8590]. +NPC id=7000, name=null, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=7001, name=Dark Squall, level=0, option=[null, null, null, null, null], anims=[7188, -1]. +NPC id=7002, name=Surok Magis, level=0, option=[Talk-To, null, null, null, null], anims=[808, -1]. +NPC id=7003, name=Fire giant, level=86, option=[null, Attack, null, null, null], anims=[4662, 4660]. +NPC id=7004, name=Fire giant, level=86, option=[null, Attack, null, null, null], anims=[4663, 4661]. +NPC id=7005, name=Big wolf, level=73, option=[null, Attack, null, null, null], anims=[6580, 6556]. +NPC id=7006, name=null, level=0, option=[null, null, null, null, null], anims=[7188, -1]. +NPC id=7007, name=null, level=0, option=[null, null, null, null, null], anims=[7188, -1]. +NPC id=7008, name=null, level=0, option=[null, null, null, null, null], anims=[7188, -1]. +NPC id=7009, name=null, level=0, option=[Talk-To, null, null, null, null], anims=[808, -1]. +NPC id=7010, name=Grenwall, level=0, option=[null, null, null, null, null], anims=[8604, 8606]. +NPC id=7011, name=Grenwall, level=0, option=[null, null, null, null, null], anims=[8601, 8606]. +NPC id=7012, name=Pawya, level=0, option=[null, null, null, null, null], anims=[8609, 8608]. +NPC id=7013, name=Earth mound, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=7014, name=Pawya, level=0, option=[null, null, null, null, null], anims=[8609, -1]. +NPC id=7015, name=Platypus, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8671, 8672]. +NPC id=7016, name=Platypus, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8671, 8672]. +NPC id=7017, name=Platypus, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8671, 8672]. +NPC id=7018, name=Baby platypus, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8671, 8670]. +NPC id=7019, name=Baby platypus, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8671, 8670]. +NPC id=7020, name=Baby platypus, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8671, 8670]. +NPC id=7021, name=Platypus, level=0, option=[null, null, null, null, null], anims=[8671, 8672]. +NPC id=7022, name=Platypus, level=0, option=[null, null, null, null, null], anims=[8671, 8672]. +NPC id=7023, name=Platypus, level=0, option=[null, null, null, null, null], anims=[8671, 8672]. +NPC id=7024, name=Baby platypus, level=0, option=[null, null, null, null, null], anims=[8671, 8670]. +NPC id=7025, name=Baby platypus, level=0, option=[null, null, null, null, null], anims=[8671, 8670]. +NPC id=7026, name=Baby platypus, level=0, option=[null, null, null, null, null], anims=[8671, 8670]. +NPC id=7027, name=Patrick, level=0, option=[null, null, null, null, null], anims=[8671, 8672]. +NPC id=7028, name=Penelope, level=0, option=[null, null, null, null, null], anims=[8671, 8672]. +NPC id=7029, name=Peter, level=0, option=[null, null, null, null, null], anims=[8671, 8670]. +NPC id=7030, name=Peanut, level=0, option=[null, null, null, null, null], anims=[8671, 8670]. +NPC id=7031, name=Wimpy bird, level=0, option=[null, null, null, null, hidden], anims=[6771, 6773]. +NPC (wrapper) id=7032, child npcs=[7031, 7083, -1]. +NPC (wrapper) id=7033, child npcs=[7031, 7083, -1]. +NPC (wrapper) id=7034, child npcs=[7031, 7083, -1]. +NPC (wrapper) id=7035, child npcs=[7031, 7083, -1]. +NPC (wrapper) id=7036, child npcs=[7031, 7083, -1]. +NPC id=7037, name=null, level=0, option=[null, null, null, null, hidden], anims=[-1, -1]. +NPC id=7038, name=null, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=7039, name=Diseased kebbit, level=0, option=[null, null, null, null, Hidden], anims=[5273, 5272]. +NPC (wrapper) id=7040, child npcs=[7039, 7083, -1]. +NPC (wrapper) id=7041, child npcs=[7039, 7083, -1]. +NPC (wrapper) id=7042, child npcs=[7039, 7083, -1]. +NPC (wrapper) id=7043, child npcs=[7039, 7083, -1]. +NPC id=7044, name=Fishing spot, level=0, option=[Net, null, Harpoon, hidden, hidden], anims=[447, 448]. +NPC id=7045, name=Fishing spot, level=0, option=[Net, null, Bait, hidden, hidden], anims=[447, 448]. +NPC id=7046, name=Fishing spot, level=0, option=[Cage, null, Harpoon, hidden, hidden], anims=[447, 448]. +NPC id=7047, name=Balnea, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=7048, name=Frawd, level=0, option=[Talk-to, null, Trade, null, null], anims=[8620, 8573]. +NPC id=7049, name=Ogress banker, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[8628, 8573]. +NPC id=7050, name=Ogress banker, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[8574, 8573]. +NPC id=7051, name=Chief Tess, level=0, option=[Talk-to, null, null, null, null], anims=[8627, 8573]. +NPC id=7052, name=Seegud, level=0, option=[Talk-to, null, null, null, null], anims=[8632, 8633]. +NPC id=7053, name=Chargurr, level=0, option=[Talk-to, null, null, null, null], anims=[8655, -1]. +NPC id=7054, name=Chargurr, level=0, option=[Talk-to, null, Trade, null, null], anims=[8650, -1]. +NPC (wrapper) id=7055, child npcs=[7053, -1]. +NPC id=7056, name=null, level=0, option=[Talk-to, null, null, null, null], anims=[8650, -1]. +NPC id=7057, name=Snurgh, level=0, option=[Talk-to, null, null, null, null], anims=[8630, 8631]. +NPC id=7058, name=Kringk, level=0, option=[Talk-to, null, null, null, null], anims=[8574, 8573]. +NPC id=7059, name=Thump, level=0, option=[Talk, null, null, null, null], anims=[8619, -1]. +NPC id=7060, name=Massage table, level=0, option=[null, null, null, null, null], anims=[8619, -1]. +NPC id=7061, name=Thump, level=0, option=[Talk-to, null, null, null, null], anims=[8574, 8573]. +NPC id=7062, name=Muggh, level=0, option=[Talk-to, null, null, null, null], anims=[8574, 8573]. +NPC id=7063, name=Kringk, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=7064, name=Hairdryer, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=7065, name=null, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=7066, name=null, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=7067, name=Snert, level=0, option=[Talk-to, null, null, null, null], anims=[8627, 8626]. +NPC id=7068, name=Tyke, level=0, option=[Talk-to, null, null, null, null], anims=[8627, 8626]. +NPC id=7069, name=Snarrl, level=0, option=[Talk-to, null, null, null, null], anims=[8627, 8626]. +NPC id=7070, name=Snarrk, level=0, option=[Talk-to, null, null, null, null], anims=[8627, 8626]. +NPC id=7071, name=I'rk, level=0, option=[Talk-to, null, null, null, null], anims=[8627, 8626]. +NPC id=7072, name=Thuddley, level=0, option=[Talk-to, null, null, null, null], anims=[8627, 8626]. +NPC id=7073, name=Grr'bah, level=0, option=[Talk-to, null, null, null, null], anims=[8627, 8626]. +NPC id=7074, name=Chomp, level=0, option=[Talk-to, null, null, null, null], anims=[8627, 8626]. +NPC id=7075, name=Grubb, level=0, option=[Talk-to, null, null, null, null], anims=[8627, 8626]. +NPC id=7076, name=Grunther, level=0, option=[Talk-to, null, null, null, null], anims=[8627, 8626]. +NPC id=7077, name=Glum, level=0, option=[Talk-To, null, null, null, null], anims=[8627, 8626]. +NPC id=7078, name=Ogress champion, level=99, option=[null, Attack, null, null, null], anims=[8642, 8573]. +NPC id=7079, name=Ogress warrior, level=86, option=[null, Attack, null, null, null], anims=[8634, 8573]. +NPC id=7080, name=Ogress warrior, level=86, option=[null, Attack, null, null, null], anims=[8635, 8643]. +NPC id=7081, name=Ogress, level=69, option=[null, Attack, null, null, null], anims=[8634, 8573]. +NPC id=7082, name=Ogress, level=69, option=[null, Attack, null, null, null], anims=[8642, 8643]. +NPC id=7083, name=Flying bugs, level=0, option=[null, null, null, null, null], anims=[8667, 8667]. +NPC id=7084, name=Eucalyptus ent, level=0, option=[Chop down, null, hidden, null, null], anims=[5750, 5750]. +NPC id=7085, name=Eucalyptus ent, level=0, option=[Chop down, null, hidden, null, null], anims=[5750, 5750]. +NPC id=7086, name=Eucalyptus ent, level=0, option=[Chop down, null, hidden, null, null], anims=[5750, 5750]. +NPC id=7087, name=Balnea, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=7088, name=Chief Tess, level=0, option=[null, null, null, null, null], anims=[8627, 8573]. +NPC id=7089, name=Chargurr, level=0, option=[null, null, null, null, null], anims=[8574, -1]. +NPC id=7090, name=Wise Old Man, level=0, option=[null, null, null, null, null], anims=[813, -1]. +NPC (wrapper) id=7091, child npcs=[7027, 7083, -1]. +NPC (wrapper) id=7092, child npcs=[7028, 7083, -1]. +NPC (wrapper) id=7093, child npcs=[7029, 7083, -1]. +NPC (wrapper) id=7094, child npcs=[7030, 7083, -1]. +NPC id=7095, name=null, level=0, option=[null, null, null, null, null], anims=[8671, 8672]. +NPC id=7096, name=null, level=0, option=[null, null, null, null, null], anims=[8671, 8672]. +NPC id=7097, name=null, level=0, option=[null, null, null, null, null], anims=[8671, 8672]. +NPC id=7098, name=null, level=0, option=[null, null, null, null, null], anims=[8671, 8672]. +NPC (wrapper) id=7099, child npcs=[7058, -1]. +NPC (wrapper) id=7100, child npcs=[7060, 7059, -1]. +NPC (wrapper) id=7101, child npcs=[7061, -1]. +NPC id=7102, name=null, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=7103, name=null, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=7104, name=Dawg, level=0, option=[Talk-to, null, null, null, null], anims=[5225, 5226]. +NPC id=7105, name=Chaos druid, level=13, option=[null, Attack, null, null, null], anims=[8528, 8527]. +NPC id=7106, name=Thug, level=10, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=7107, name=Thug, level=10, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=7108, name=Thug, level=10, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=7109, name=Thug, level=10, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=7110, name=Thug, level=10, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=7111, name=Thug, level=10, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=7112, name=Thug, level=10, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=7113, name=Thug, level=10, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=7114, name=Thug, level=10, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=7115, name=Thaki the delivery dwarf, level=0, option=[Talk-to, null, null, null, null], anims=[8706, -1]. +NPC id=7116, name=Drunken sailor, level=0, option=[Talk-to, null, null, null, null], anims=[8707, 2769]. +NPC id=7117, name=Drunken sailor, level=0, option=[Talk-to, null, Search, null, null], anims=[8707, -1]. +NPC id=7118, name=Catapult engineer, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=7119, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=7120, name=Tyras guard, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=7121, name=General Hining, level=0, option=[Talk-to, null, null, null, null], anims=[813, -1]. +NPC id=7122, name=Githan, level=0, option=[null, null, null, null, null], anims=[2906, 2907]. +NPC id=7123, name=Amulet of Nature, level=0, option=[null, null, null, null, null], anims=[2906, 2907]. +NPC id=7124, name=Mud, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=7125, name=Rabbit, level=0, option=[null, null, Feed, null, null], anims=[8737, 6088]. +NPC id=7126, name=Rabbit, level=0, option=[null, null, Feed, null, null], anims=[8737, 6088]. +NPC id=7127, name=Rabbit, level=0, option=[null, null, Feed, null, null], anims=[8737, 6088]. +NPC id=7128, name=Farmer, level=0, option=[null, null, null, null, null], anims=[8726, 8723]. +NPC id=7129, name=Farmer, level=0, option=[null, null, null, null, null], anims=[8726, 8723]. +NPC id=7130, name=Farmer, level=0, option=[null, null, null, null, null], anims=[8728, 8723]. +NPC id=7131, name=Farmer Blinkin, level=0, option=[Talk-to, null, Buy-flags, Buy-roots, null], anims=[8721, 8722]. +NPC id=7132, name=Mrs. Winkin, level=0, option=[Talk-to, null, Trade, Buy flags, null], anims=[8720, 8719]. +NPC id=7133, name=Bork, level=267, option=[null, Attack, null, null, null], anims=[8753, 8752]. +NPC id=7134, name=Bork, level=267, option=[null, Attack, null, null, null], anims=[8753, 8752]. +NPC id=7135, name=Ork legion, level=70, option=[null, Attack, null, null, null], anims=[8763, 8764]. +NPC id=7136, name=Surok Magis, level=0, option=[Attack, null, null, null, null], anims=[808, -1]. +NPC id=7137, name=Dagon'hai Elite, level=0, option=[Attack, null, null, null, null], anims=[808, -1]. +NPC id=7138, name=Dagon'hai Monk, level=97, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=7139, name=Dagon'hai Monk, level=97, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=7140, name=Dagon'hai Monk, level=97, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=7141, name=null, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=7142, name=Guard, level=0, option=[Talk-to, null, null, null, null], anims=[8800, 7223]. +NPC id=7143, name=Professor Henry, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=7144, name=Gublinch jailmate, level=0, option=[null, null, null, null, null], anims=[8771, -1]. +NPC id=7145, name=Gublinchette jailmate, level=0, option=[null, null, null, null, null], anims=[8772, -1]. +NPC id=7146, name=Gublinchette jailmate, level=0, option=[null, null, null, null, null], anims=[8773, -1]. +NPC id=7147, name=Gublinch jailmate, level=0, option=[null, null, null, null, null], anims=[8774, -1]. +NPC id=7148, name=Gublinch jailmate, level=0, option=[null, null, null, null, null], anims=[8775, -1]. +NPC id=7149, name=Gublinch jailmate, level=0, option=[null, null, null, null, null], anims=[8776, -1]. +NPC id=7150, name=Gublinch jailmate, level=0, option=[null, null, null, null, null], anims=[8777, -1]. +NPC id=7151, name=Student, level=0, option=[Talk-to, null, null, null, null], anims=[8778, -1]. +NPC id=7152, name=Student, level=0, option=[Talk-to, null, null, null, null], anims=[8779, -1]. +NPC id=7153, name=Student, level=0, option=[Talk-to, null, null, null, null], anims=[8780, -1]. +NPC id=7154, name=Student, level=0, option=[Talk-to, null, null, null, null], anims=[8781, -1]. +NPC id=7155, name=Student, level=0, option=[Talk-to, null, null, null, null], anims=[8782, -1]. +NPC id=7156, name=Student, level=0, option=[Talk-to, null, null, null, null], anims=[8783, -1]. +NPC id=7157, name=Student, level=0, option=[Talk-to, null, null, null, null], anims=[8784, -1]. +NPC id=7158, name=Cockroach drone, level=8, option=[null, Attack, null, null, null], anims=[8798, 8794]. +NPC id=7159, name=Cockroach worker, level=56, option=[null, Attack, null, null, null], anims=[8797, 8796]. +NPC id=7160, name=Cockroach soldier, level=83, option=[null, Attack, null, null, null], anims=[8797, 8795]. +NPC id=7161, name=Mugger, level=6, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=7162, name=Mugger, level=6, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC (wrapper) id=7163, child npcs=[696, -1]. +NPC id=7164, name=Villager, level=0, option=[null, null, null, null, null], anims=[808, 4779]. +NPC id=7165, name=Villager, level=0, option=[null, null, null, null, null], anims=[8863, 8862]. +NPC id=7166, name=Villager, level=0, option=[null, null, null, null, null], anims=[8878, 8875]. +NPC id=7167, name=Villager, level=0, option=[null, null, null, null, null], anims=[8877, 8862]. +NPC id=7168, name=Kimberly, level=0, option=[Talk-to, null, null, null, null], anims=[7167, 7160]. +NPC id=7169, name=Kimberly, level=0, option=[Talk-to, null, null, null, null], anims=[7158, -1]. +NPC id=7170, name=Kimberly, level=0, option=[Talk-to, null, null, null, null], anims=[8816, -1]. +NPC id=7171, name=Kennith, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=7172, name=Kennith, level=0, option=[Talk-to, null, null, null, null], anims=[8807, 8808]. +NPC id=7173, name=Kennith, level=0, option=[null, null, null, null, null], anims=[8807, -1]. +NPC id=7174, name=Kennith, level=0, option=[Talk-to, null, null, null, null], anims=[8811, 8811]. +NPC id=7175, name=Kennith, level=0, option=[null, null, null, null, null], anims=[8852, -1]. +NPC id=7176, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=7177, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=7178, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=7179, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=7180, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=7181, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=7182, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=7183, name=Villager, level=0, option=[Talk-to, null, null, null, null], anims=[808, 4779]. +NPC id=7184, name=Ezekial Lovecraft, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=7185, name=Clive, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=7186, name=Katherine, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=7187, name=Katherine, level=0, option=[Talk-to, null, null, null, null], anims=[6935, -1]. +NPC id=7188, name=Clive, level=0, option=[Talk-to, null, null, null, null], anims=[6935, -1]. +NPC id=7189, name=Kent, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC (wrapper) id=7190, child npcs=[4856, -1, -1, -1, -1, 4856, -1, -1, -1, -1, 4856, -1, -1, -1, -1, 4856, -1, -1, -1, -1, 4856, -1, -1, -1, -1, 4856, -1, -1, -1, -1, 4856, -1, -1, -1, -1, 4856, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4856, -1]. +NPC (wrapper) id=7191, child npcs=[7168, -1, -1, -1, -1, 7168, -1, -1, -1, -1, 7168, -1, -1, -1, -1, 7168, -1, -1, -1, -1, 7168, -1, -1, -1, -1, 7168, -1, 7168, -1, -1, 7168, -1, -1, -1, -1, 7168, -1]. +NPC id=7192, name=null, level=1, option=[null, null, null, null, null], anims=[7158, 7160]. +NPC id=7193, name=null, level=1, option=[null, null, null, null, null], anims=[7158, 7160]. +NPC id=7194, name=null, level=1, option=[null, null, null, null, null], anims=[7158, 7160]. +NPC id=7195, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=7196, name=Rabbit hole, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=7197, name=Easter Bunny, level=0, option=[Talk-to, null, null, null, null], anims=[3852, 3851]. +NPC id=7198, name=Bunny, level=0, option=[Talk-to, null, null, null, null], anims=[1242, 1243]. +NPC id=7199, name=Bunny, level=0, option=[Talk-to, null, null, null, null], anims=[1242, 1243]. +NPC id=7200, name=Guard bunny, level=0, option=[Talk-to, null, null, null, null], anims=[1242, 1243]. +NPC id=7201, name=Chocatrice, level=0, option=[Interact, null, null, null, null], anims=[7760, 7759]. +NPC id=7202, name=Rat, level=0, option=[null, null, null, null, null], anims=[4932, 4931]. +NPC id=7203, name=Void Knight, level=0, option=[null, hidden, null, null, null], anims=[3926, -1]. +NPC id=7204, name=Rat, level=0, option=[null, null, null, null, null], anims=[4932, 4931]. +NPC id=7205, name=Mouse, level=0, option=[null, null, null, null, null], anims=[6518, 6517]. +NPC id=7206, name=Cockroach, level=0, option=[null, null, null, null, null], anims=[8798, 8794]. +NPC id=7207, name=Spider, level=0, option=[null, null, null, null, null], anims=[5326, 5325]. +NPC id=7208, name=Rabbit, level=0, option=[null, null, null, null, null], anims=[3872, 3871]. +NPC id=7209, name=Snail, level=0, option=[null, null, null, null, null], anims=[8146, 8145]. +NPC id=7210, name=Baby monkey, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8346, 8348]. +NPC id=7211, name=Monkey, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8344, 8343]. +NPC id=7212, name=Baby monkey, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8346, 8348]. +NPC id=7213, name=Monkey, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8344, 8343]. +NPC id=7214, name=Baby monkey, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8346, 8348]. +NPC id=7215, name=Monkey, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8344, 8343]. +NPC id=7216, name=Baby monkey, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8346, 8348]. +NPC id=7217, name=Monkey, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8344, 8343]. +NPC id=7218, name=Baby monkey, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8346, 8348]. +NPC id=7219, name=Monkey, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8344, 8343]. +NPC id=7220, name=Baby monkey, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8346, 8348]. +NPC id=7221, name=Monkey, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8344, 8343]. +NPC id=7222, name=Baby monkey, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8346, 8348]. +NPC id=7223, name=Monkey, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8344, 8343]. +NPC id=7224, name=Baby monkey, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8346, 8348]. +NPC id=7225, name=Monkey, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8344, 8343]. +NPC id=7226, name=Baby monkey, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8346, 8348]. +NPC id=7227, name=Monkey, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8344, 8343]. +NPC id=7228, name=Baby monkey, level=0, option=[null, null, null, null, null], anims=[8346, 8348]. +NPC id=7229, name=Baby monkey, level=0, option=[null, null, null, null, null], anims=[8346, 8348]. +NPC id=7230, name=Baby monkey, level=0, option=[null, null, null, null, null], anims=[8346, 8348]. +NPC id=7231, name=Baby monkey, level=0, option=[null, null, null, null, null], anims=[8346, 8348]. +NPC id=7232, name=Baby monkey, level=0, option=[null, null, null, null, null], anims=[8346, 8348]. +NPC id=7233, name=Baby monkey, level=0, option=[null, null, null, null, null], anims=[8346, 8348]. +NPC id=7234, name=Baby monkey, level=0, option=[null, null, null, null, null], anims=[8346, 8348]. +NPC id=7235, name=Baby monkey, level=0, option=[null, null, null, null, null], anims=[8346, 8348]. +NPC id=7236, name=Baby monkey, level=0, option=[null, null, null, null, null], anims=[8346, 8348]. +NPC id=7237, name=Terrier puppy, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8338, 8336]. +NPC id=7238, name=Terrier, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8338, 8337]. +NPC id=7239, name=Terrier puppy, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8339, 8336]. +NPC id=7240, name=Terrier, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8339, 8337]. +NPC id=7241, name=Greyhound puppy, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8338, 8332]. +NPC id=7242, name=Greyhound, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8338, 8333]. +NPC id=7243, name=Greyhound puppy, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8339, 8332]. +NPC id=7244, name=Greyhound, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8339, 8333]. +NPC id=7245, name=Labrador puppy, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8338, 8334]. +NPC id=7246, name=Labrador, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8338, 8335]. +NPC id=7247, name=Labrador puppy, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8339, 8334]. +NPC id=7248, name=Labrador, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8339, 8335]. +NPC id=7249, name=Dalmatian puppy, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8338, 8330]. +NPC id=7250, name=Dalmatian, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8338, 8331]. +NPC id=7251, name=Dalmatian puppy, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8339, 8330]. +NPC id=7252, name=Dalmatian, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8339, 8331]. +NPC id=7253, name=Sheepdog puppy, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8338, 8334]. +NPC id=7254, name=Sheepdog, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8338, 8335]. +NPC id=7255, name=Sheepdog puppy, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8339, 8334]. +NPC id=7256, name=Sheepdog, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8339, 8335]. +NPC id=7257, name=Bulldog, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8338, 7576]. +NPC id=7258, name=Bulldog, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8339, 7576]. +NPC id=7259, name=Bulldog puppy, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8338, 8329]. +NPC id=7260, name=Bulldog puppy, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8339, 8329]. +NPC id=7261, name=Raven chick, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8310, 8312]. +NPC id=7262, name=Raven, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8008, 8007]. +NPC id=7263, name=Raven chick, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8310, 8312]. +NPC id=7264, name=Raven, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8008, 8007]. +NPC id=7265, name=Raven chick, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8310, 8312]. +NPC id=7266, name=Raven, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8008, 8007]. +NPC id=7267, name=Raven chick, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8310, 8312]. +NPC id=7268, name=Raven, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8008, 8007]. +NPC id=7269, name=Raven chick, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8310, 8312]. +NPC id=7270, name=Raven, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8008, 8007]. +NPC id=7271, name=Baby raccoon, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[7718, 7719]. +NPC id=7272, name=Raccoon, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[7718, 7719]. +NPC id=7273, name=Baby raccoon, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[7718, 7719]. +NPC id=7274, name=Raccoon, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[7718, 7719]. +NPC id=7275, name=Baby Raccoon, level=0, option=[null, null, null, null, null], anims=[7718, 7719]. +NPC id=7276, name=Baby raccoon, level=0, option=[null, null, null, null, null], anims=[7718, 7719]. +NPC id=7277, name=Baby gecko, level=0, option=[Pick-up, null, null, Talk-to, null], anims=[8360, 8358]. +NPC id=7278, name=Baby gecko, level=0, option=[Pick-up, null, null, Talk-to, null], anims=[8360, 8358]. +NPC id=7279, name=Baby gecko, level=0, option=[Pick-up, null, null, Talk-to, null], anims=[8360, 8358]. +NPC id=7280, name=Baby gecko, level=0, option=[Pick-up, null, null, Talk-to, null], anims=[8360, 8358]. +NPC id=7281, name=Gecko, level=0, option=[Pick-up, null, null, Talk-to, null], anims=[8360, 8357]. +NPC id=7282, name=Gecko, level=0, option=[Pick-up, null, null, Talk-to, null], anims=[8360, 8357]. +NPC id=7283, name=Gecko, level=0, option=[Pick-up, null, null, Talk-to, null], anims=[8360, 8357]. +NPC id=7284, name=Gecko, level=0, option=[Pick-up, null, null, Talk-to, null], anims=[8360, 8357]. +NPC id=7285, name=Baby gecko, level=0, option=[null, null, null, null, null], anims=[8360, 8358]. +NPC id=7286, name=Baby gecko, level=0, option=[null, null, null, null, null], anims=[8360, 8358]. +NPC id=7287, name=Baby gecko, level=0, option=[null, null, null, null, null], anims=[8360, 8358]. +NPC id=7288, name=Baby gecko, level=0, option=[null, null, null, null, null], anims=[8360, 8358]. +NPC id=7289, name=Gecko, level=0, option=[null, null, null, null, null], anims=[8360, 8357]. +NPC id=7290, name=Gecko, level=0, option=[null, null, null, null, null], anims=[8360, 8357]. +NPC id=7291, name=Gecko, level=0, option=[null, null, null, null, null], anims=[8360, 8357]. +NPC id=7292, name=Gecko, level=0, option=[null, null, null, null, null], anims=[8360, 8357]. +NPC id=7293, name=Baby giant crab, level=0, option=[Pick-up, null, null, Talk-to, null], anims=[8098, 8101]. +NPC id=7294, name=Giant crab, level=0, option=[Pick-up, null, null, Talk-to, null], anims=[8098, 8101]. +NPC id=7295, name=Baby giant crab, level=0, option=[Pick-up, null, null, Talk-to, null], anims=[8098, 8101]. +NPC id=7296, name=Giant crab, level=0, option=[Pick-up, null, null, Talk-to, null], anims=[8098, 8101]. +NPC id=7297, name=Baby giant crab, level=0, option=[Pick-up, null, null, Talk-to, null], anims=[8098, 8101]. +NPC id=7298, name=Giant crab, level=0, option=[Pick-up, null, null, Talk-to, null], anims=[8098, 8101]. +NPC id=7299, name=Baby giant crab, level=0, option=[Pick-up, null, null, Talk-to, null], anims=[8098, 8101]. +NPC id=7300, name=Giant crab, level=0, option=[Pick-up, null, null, Talk-to, null], anims=[8098, 8101]. +NPC id=7301, name=Baby squirrel, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8324, 8326]. +NPC id=7302, name=Squirrel, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8324, 8326]. +NPC id=7303, name=Baby squirrel, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8324, 8326]. +NPC id=7304, name=Squirrel, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8324, 8326]. +NPC id=7305, name=Baby squirrel, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8324, 8326]. +NPC id=7306, name=Squirrel, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8324, 8326]. +NPC id=7307, name=Baby squirrel, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8324, 8326]. +NPC id=7308, name=Squirrel, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8324, 8326]. +NPC id=7309, name=Baby squirrel, level=0, option=[null, null, null, null, null], anims=[8324, 8326]. +NPC id=7310, name=Baby squirrel, level=0, option=[null, null, null, null, null], anims=[8324, 8326]. +NPC id=7311, name=Baby squirrel, level=0, option=[null, null, null, null, null], anims=[8324, 8326]. +NPC id=7312, name=Baby squirrel, level=0, option=[null, null, null, null, null], anims=[8324, 8326]. +NPC id=7313, name=Baby penguin, level=0, option=[Pick-up, null, null, Talk-to, null], anims=[8319, 8318]. +NPC id=7314, name=Penguin, level=0, option=[Pick-up, null, null, Talk-to, null], anims=[8315, 8314]. +NPC id=7315, name=Penguin, level=0, option=[Pick-up, null, null, Talk-to, null], anims=[8315, 8317]. +NPC id=7316, name=Baby penguin, level=0, option=[Pick-up, null, null, Talk-to, null], anims=[8319, 8318]. +NPC id=7317, name=Penguin, level=0, option=[Pick-up, null, null, Talk-to, null], anims=[8315, 8314]. +NPC id=7318, name=Penguin, level=0, option=[Pick-up, null, null, Talk-to, null], anims=[8315, 8317]. +NPC id=7319, name=Vulture chick, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8310, 8312]. +NPC id=7320, name=Vulture, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[7659, 7658]. +NPC id=7321, name=Vulture chick, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8310, 8312]. +NPC id=7322, name=Vulture, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[7659, 7658]. +NPC id=7323, name=Vulture chick, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8310, 8312]. +NPC id=7324, name=Vulture, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[7659, 7658]. +NPC id=7325, name=Vulture chick, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8310, 8312]. +NPC id=7326, name=Vulture, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[7659, 7658]. +NPC id=7327, name=Vulture chick, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[8310, 8312]. +NPC id=7328, name=Vulture, level=0, option=[Pick-up, null, Talk-to, null, null], anims=[7659, 7658]. +NPC id=7329, name=Swamp titan, level=0, option=[Interact, null, null, null, null], anims=[8220, 8219]. +NPC id=7330, name=Swamp titan, level=152, option=[Interact, Attack, null, null, null], anims=[8220, 8219]. +NPC id=7331, name=Spirit mosquito, level=0, option=[Interact, null, null, null, null], anims=[8035, 8038]. +NPC id=7332, name=Spirit mosquito, level=32, option=[Interact, Attack, null, null, null], anims=[8035, 8038]. +NPC id=7333, name=Void spinner, level=0, option=[Interact, null, null, null, null], anims=[8171, 8175]. +NPC id=7334, name=Void spinner, level=40, option=[Interact, Attack, null, null, null], anims=[8171, 8175]. +NPC id=7335, name=Forge regent, level=0, option=[Interact, null, null, null, Fireball], anims=[7867, 7868]. +NPC id=7336, name=Forge regent, level=133, option=[Interact, Attack, null, null, Fireball], anims=[7867, 7868]. +NPC id=7337, name=Spirit larupia, level=0, option=[Interact, null, null, null, null], anims=[5225, 5226]. +NPC id=7338, name=Spirit larupia, level=93, option=[Interact, Attack, null, null, null], anims=[5225, 5226]. +NPC id=7339, name=Geyser titan, level=0, option=[Interact, null, null, null, null], anims=[7876, 7877]. +NPC id=7340, name=Geyser titan, level=200, option=[Interact, Attack, null, null, null], anims=[7876, 7877]. +NPC id=7341, name=Lava titan, level=0, option=[Interact, null, null, null, null], anims=[7978, 7977]. +NPC id=7342, name=Lava titan, level=148, option=[Interact, Attack, null, null, null], anims=[7978, 7977]. +NPC id=7343, name=Steel titan, level=0, option=[Interact, null, null, null, null], anims=[8186, 8189]. +NPC id=7344, name=Steel titan, level=230, option=[Interact, Attack, null, null, null], anims=[8186, 8189]. +NPC id=7345, name=Obsidian golem, level=0, option=[Interact, null, null, null, null], anims=[8047, 8046]. +NPC id=7346, name=Obsidian golem, level=126, option=[Interact, Attack, null, null, null], anims=[8047, 8046]. +NPC id=7347, name=Talon beast, level=0, option=[Interact, null, null, null, null], anims=[5986, 5987]. +NPC id=7348, name=Talon beast, level=135, option=[Interact, Attack, null, null, null], anims=[5986, 5987]. +NPC id=7349, name=Abyssal titan, level=0, option=[Interact, null, Store, null, null], anims=[7690, 7687]. +NPC id=7350, name=Abyssal titan, level=215, option=[Interact, Attack, Store, null, null], anims=[7690, 7687]. +NPC id=7351, name=Void torcher, level=0, option=[Interact, null, null, null, Strike], anims=[8233, 8234]. +NPC id=7352, name=Void torcher, level=46, option=[Interact, Attack, null, null, Strike], anims=[8233, 8234]. +NPC id=7353, name=Giant chinchompa, level=0, option=[Interact, null, null, null, null], anims=[7751, 7750]. +NPC id=7354, name=Giant chinchompa, level=42, option=[Interact, Attack, null, null, null], anims=[7751, 7750]. +NPC id=7355, name=Fire titan, level=0, option=[Interact, null, null, null, null], anims=[7831, 7828]. +NPC id=7356, name=Fire titan, level=139, option=[Interact, Attack, null, null, null], anims=[7831, 7828]. +NPC id=7357, name=Moss titan, level=0, option=[Interact, null, null, null, null], anims=[7841, 7838]. +NPC id=7358, name=Moss titan, level=139, option=[Interact, Attack, null, null, null], anims=[7841, 7838]. +NPC id=7359, name=Ice titan, level=0, option=[Interact, null, null, null, null], anims=[8186, 7847]. +NPC id=7360, name=Ice titan, level=139, option=[Interact, Attack, null, null, null], anims=[8186, 7847]. +NPC id=7361, name=Spirit Tz-Kih, level=0, option=[Interact, null, null, null, Despair], anims=[8255, 8256]. +NPC id=7362, name=Spirit Tz-Kih, level=36, option=[Interact, Attack, null, null, Despair], anims=[8255, 8256]. +NPC id=7363, name=Spirit graahk, level=0, option=[Interact, null, null, null, null], anims=[5225, 5226]. +NPC id=7364, name=Spirit graahk, level=93, option=[Interact, Attack, null, null, null], anims=[5225, 5226]. +NPC id=7365, name=Spirit kyatt, level=0, option=[Interact, null, null, null, null], anims=[5225, 5226]. +NPC id=7366, name=Spirit kyatt, level=93, option=[Interact, Attack, null, null, null], anims=[5225, 5226]. +NPC id=7367, name=Void shifter, level=0, option=[Interact, null, null, null, null], anims=[8129, 8128]. +NPC id=7368, name=Void shifter, level=46, option=[Interact, Attack, null, null, null], anims=[8129, 8128]. +NPC id=7369, name=Void shifter, level=47, option=[Interact, null, null, null, null], anims=[8129, 8128]. +NPC id=7370, name=Void ravager, level=0, option=[Interact, null, Withdraw, null, null], anims=[8089, 8092]. +NPC id=7371, name=Void ravager, level=46, option=[Interact, Attack, Withdraw, null, null], anims=[8089, 8092]. +NPC id=7372, name=Ravenous locust, level=0, option=[Interact, null, null, null, null], anims=[7992, 7991]. +NPC id=7373, name=Ravenous locust, level=120, option=[Interact, Attack, null, null, null], anims=[7992, 7991]. +NPC id=7374, name=Ravenous locust, level=0, option=[null, null, null, null, null], anims=[8001, -1]. +NPC id=7375, name=Iron titan, level=0, option=[Interact, null, null, null, null], anims=[7949, 7952]. +NPC id=7376, name=Iron titan, level=220, option=[Interact, Attack, null, null, null], anims=[7949, 7952]. +NPC id=7377, name=Pyrelord, level=0, option=[Interact, null, null, null, null], anims=[8077, 8076]. +NPC id=7378, name=Pyrelord, level=70, option=[Interact, Attack, null, null, null], anims=[8077, 8076]. +NPC id=7379, name=Elfinlocks, level=93, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7380, name=Missi Sissi, level=98, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7381, name=Missi Sissi, level=98, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7382, name=Uberlass, level=103, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7383, name=Uberlass, level=103, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7384, name=Uberlass, level=103, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7385, name=Uberlass, level=103, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7386, name=Uberlass, level=103, option=[null, null, Walk here, Follow, Trade], anims=[8980, -1]. +NPC id=7387, name=Sannytea, level=108, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7388, name=Sannytea, level=108, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7389, name=Irollsixes, level=113, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7390, name=Irollsixes, level=113, option=[null, null, Walk here, Follow, Trade], anims=[813, -1]. +NPC id=7391, name=Foxyhunter, level=118, option=[null, null, Walk here, Follow, Trade], anims=[4591, -1]. +NPC id=7392, name=Foxyhunter, level=118, option=[null, null, Walk here, Follow, Trade], anims=[4591, -1]. +NPC id=7393, name=Foxyhunter, level=118, option=[null, null, Walk here, Follow, Trade], anims=[813, -1]. +NPC id=7394, name=Gabriela, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=7395, name=Teodor, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=7396, name=Aurel, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=7397, name=Cornelius, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=7398, name=Elisabeta, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=7399, name=Sorin, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=7400, name=Luscion, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=7401, name=Sergiu, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=7402, name=Radu, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=7403, name=Grigore, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=7404, name=Ileana, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=7405, name=Valeria, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=7406, name=Emilia, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=7407, name=Florin, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=7408, name=Catalina, level=0, option=[Talk-to, null, null, null, null], anims=[7167, 7160]. +NPC id=7409, name=Ivan, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=7410, name=Victor, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=7411, name=Helena, level=0, option=[Talk-to, null, null, null, null], anims=[7158, 7160]. +NPC id=7412, name=Mihail, level=0, option=[Talk-to, null, null, null, null], anims=[1144, -1]. +NPC id=7413, name=Nicoleta, level=0, option=[Talk-to, null, null, null, null], anims=[1144, -1]. +NPC id=7414, name=Vasile, level=0, option=[Talk-to, null, null, null, null], anims=[3557, -1]. +NPC id=7415, name=Razvan, level=0, option=[Talk-to, null, null, null, null], anims=[3557, -1]. +NPC id=7416, name=Luminata, level=0, option=[Talk-to, null, null, null, null], anims=[3557, -1]. +NPC id=7417, name=Rat, level=1, option=[Attack, null, null, null, null], anims=[2704, 2703]. +NPC id=7418, name=Juvinate, level=119, option=[Attack, null, null, null, null], anims=[808, -1]. +NPC id=7419, name=Held vampyre juvinate, level=119, option=[Attack, null, null, null, null], anims=[3551, -1]. +NPC id=7420, name=Hieronymus Avlafrim, level=0, option=[Talk-to, null, Trade, null, null], anims=[8977, -1]. +NPC id=7421, name=Sasquine Huburns, level=0, option=[Talk-to, null, null, null, null], anims=[8978, -1]. +NPC id=7422, name=Sasquine Huburns, level=0, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=7423, name=Lollery, level=82, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7424, name=Wigglewoo, level=130, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7425, name=Wigglewoo, level=130, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7426, name=Orangeowns, level=72, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7427, name=Orangeowns, level=72, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7428, name=I like m0m, level=95, option=[null, null, Walk here, Follow, Trade], anims=[7047, -1]. +NPC id=7429, name=I like m0m, level=95, option=[null, null, Walk here, Follow, Trade], anims=[7047, -1]. +NPC id=7430, name=Qutiedoll, level=99, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7431, name=Goreu, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[808, -1]. +NPC id=7432, name=Ysgawyn, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[808, -1]. +NPC id=7433, name=Arvel, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[808, -1]. +NPC id=7434, name=Mawrth, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[808, -1]. +NPC id=7435, name=Kelyn, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[808, -1]. +NPC id=7436, name=Eoin, level=0, option=[Talk-to, null, null, null, null], anims=[808, 824]. +NPC id=7437, name=Iona, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=7438, name=Elf warrior, level=108, option=[Attack, null, null, null, null], anims=[808, -1]. +NPC id=7439, name=Elf warrior, level=108, option=[Attack, null, null, null, null], anims=[808, -1]. +NPC id=7440, name=Elf warrior, level=90, option=[Attack, null, null, null, null], anims=[808, -1]. +NPC id=7441, name=Elf warrior, level=90, option=[Attack, null, null, null, null], anims=[808, -1]. +NPC id=7442, name=Arianwyn, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=7443, name=Eudav, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=7444, name=Oronwen, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=7445, name=Banker, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[808, 808]. +NPC id=7446, name=Banker, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[808, 808]. +NPC id=7447, name=Dalldav, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=7448, name=Gethin, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=7449, name=Amaethwr, level=0, option=[Talk-to, null, Pay, null, null], anims=[808, -1]. +NPC id=7450, name=Teclyn, level=0, option=[Talk-to, null, Exchange, Teleport, null], anims=[808, -1]. +NPC id=7451, name=Butterfly, level=0, option=[null, null, null, null, null], anims=[362, 362]. +NPC id=7452, name=Lapsang, level=130, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7453, name=Lapsang, level=130, option=[null, null, Walk here, Follow, Trade], anims=[8943, 8943]. +NPC id=7454, name=Souchong, level=105, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7455, name=Souchong, level=105, option=[null, null, Walk here, Follow, Trade], anims=[8944, 8944]. +NPC id=7456, name=Earlgrey, level=87, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7457, name=Earlgrey, level=87, option=[null, null, Walk here, Follow, Trade], anims=[8943, 8943]. +NPC id=7458, name=Fairtrade, level=93, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7459, name=Fairtrade, level=93, option=[null, null, Walk here, Follow, Trade], anims=[8944, 8944]. +NPC id=7460, name=Teapotspout, level=94, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7461, name=Rat, level=0, option=[null, null, null, null, null], anims=[4932, 4931]. +NPC id=7462, name=Hotwater, level=81, option=[null, null, Walk here, Follow, Trade], anims=[809, -1]. +NPC id=7463, name=Hotwater, level=81, option=[null, null, Walk here, Follow, Trade], anims=[8944, 8944]. +NPC id=7464, name=Sliceoflemon, level=124, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7465, name=Sliceoflemon, level=124, option=[null, null, Walk here, Follow, Trade], anims=[8943, 8943]. +NPC id=7466, name=Milknosugar, level=127, option=[null, null, Walk here, Follow, Trade], anims=[4591, -1]. +NPC id=7467, name=Milknosugar, level=127, option=[null, null, Walk here, Follow, Trade], anims=[8944, 8944]. +NPC id=7468, name=Randomdood, level=86, option=[null, null, Walk here, Follow, Trade], anims=[8945, -1]. +NPC id=7469, name=Employedman, level=91, option=[null, null, Walk here, Follow, Trade], anims=[8946, -1]. +NPC id=7470, name=Heidiggle, level=98, option=[null, null, Walk here, Follow, Trade], anims=[8954, -1]. +NPC id=7471, name=Dodgy Penny, level=102, option=[null, null, Walk here, Follow, Trade], anims=[8948, -1]. +NPC id=7472, name=Shadydude98, level=98, option=[null, null, Walk here, Follow, Trade], anims=[8949, -1]. +NPC id=7473, name=Madam C, level=73, option=[null, null, Walk here, Follow, Trade], anims=[8952, -1]. +NPC id=7474, name=M0m Online, level=69, option=[null, null, Walk here, Follow, Trade], anims=[8951, -1]. +NPC id=7475, name=Lady Seenit, level=138, option=[null, null, Walk here, Follow, Trade], anims=[8950, -1]. +NPC id=7476, name=Berrybree, level=68, option=[null, null, Walk here, Follow, Trade], anims=[8953, -1]. +NPC id=7477, name=Stuffstuffer, level=69, option=[null, null, Walk here, Follow, Trade], anims=[8947, -1]. +NPC (wrapper) id=7478, child npcs=[6174, 6174, 6388, -1]. +NPC id=7479, name=Learking, level=83, option=[null, null, Walk here, Follow, Trade], anims=[813, -1]. +NPC id=7480, name=Rachael, level=0, option=[Talk-to, null, Trade, null, null], anims=[808, -1]. +NPC id=7481, name=Cool Mom227, level=83, option=[null, null, Walk here, Follow, Trade], anims=[6604, -1]. +NPC id=7482, name=Purepker895, level=52, option=[null, null, Walk here, Follow, Trade], anims=[813, -1]. +NPC id=7483, name=Pkmaster0036, level=87, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7484, name=Cow1337killr, level=123, option=[null, null, Walk here, Follow, Trade], anims=[2065, 2064]. +NPC id=7485, name=Mathdude, level=93, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7486, name=Mathdude, level=93, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7487, name=1337sp34kr, level=63, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7488, name=1337sp34kr, level=63, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7489, name=Moglewee, level=103, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7490, name=Moglewee, level=103, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7491, name=Sarah Domin, level=76, option=[null, null, Walk here, Follow, Trade], anims=[5254, -1]. +NPC id=7492, name=Sarah Domin, level=76, option=[null, null, Walk here, Follow, Trade], anims=[5254, -1]. +NPC id=7493, name=Sarah Domin, level=76, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7494, name=Sue Spammers, level=112, option=[null, null, Walk here, Follow, Trade], anims=[1461, -1]. +NPC id=7495, name=Killerwail, level=86, option=[null, null, Walk here, Follow, Trade], anims=[1461, -1]. +NPC id=7496, name=Wise Old Man, level=0, option=[null, null, null, null, null], anims=[1461, -1]. +NPC id=7497, name=Sabre-toothed kyatt, level=60, option=[null, null, null, null, null], anims=[5225, 5226]. +NPC id=7498, name=Snowy knight, level=0, option=[Catch, null, null, null, null], anims=[362, 362]. +NPC id=7499, name=Sapphire glacialis, level=0, option=[Catch, null, null, null, null], anims=[362, 362]. +NPC id=7500, name=Cerulean twitch, level=0, option=[null, null, null, null, null], anims=[6771, 6773]. +NPC id=7501, name=Abone, level=74, option=[null, null, Walk here, Follow, Trade], anims=[4591, 4228]. +NPC id=7502, name=Mythmaster, level=87, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7503, name=Donkey Wrong, level=93, option=[null, null, Walk here, Follow, Trade], anims=[8980, -1]. +NPC id=7504, name=Creapantic, level=101, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7505, name=Frondlike, level=103, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7506, name=Happy Spud, level=112, option=[null, null, Walk here, Follow, Trade], anims=[4591, 4228]. +NPC id=7507, name=Nobodyhere, level=82, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7508, name=Bluehairlass, level=85, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7509, name=Evil Wibbler, level=69, option=[null, null, Walk here, Follow, Trade], anims=[4591, 4228]. +NPC id=7510, name=Ilikekebabs, level=76, option=[null, null, Walk here, Follow, Trade], anims=[4591, 4228]. +NPC id=7511, name=Trunka Lex, level=86, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7512, name=Val Razz, level=72, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7513, name=Abstractclas, level=72, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7514, name=Bigbluebox, level=93, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7515, name=Funorbrox, level=126, option=[null, null, Walk here, Follow, Trade], anims=[813, -1]. +NPC id=7516, name=Heresjohnny, level=118, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7517, name=Mogglewump, level=105, option=[null, null, Walk here, Follow, Trade], anims=[808, 1661]. +NPC id=7518, name=Morrisnorris, level=83, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7519, name=Matt Blitzer, level=138, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7520, name=Ketchuppl0x, level=108, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7521, name=Renderorder, level=61, option=[null, null, Walk here, Follow, Trade], anims=[1662, -1]. +NPC id=7522, name=Boolean, level=101, option=[null, null, Walk here, Follow, Trade], anims=[7047, -1]. +NPC id=7523, name=Stress Diva, level=79, option=[null, null, Walk here, Follow, Trade], anims=[813, -1]. +NPC id=7524, name=Treadsoftly, level=106, option=[null, null, Walk here, Follow, Trade], anims=[808, 1661]. +NPC id=7525, name=Helphelphelp, level=76, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7526, name=Doorbellpl0x, level=52, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7527, name=Fixmydoorup, level=91, option=[null, null, Walk here, Follow, Trade], anims=[2065, -1]. +NPC id=7528, name=Redheadmonky, level=81, option=[null, null, Walk here, Follow, Trade], anims=[809, -1]. +NPC id=7529, name=Wallscaler, level=62, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7530, name=2scompany, level=76, option=[null, null, Walk here, Follow, Trade], anims=[1421, -1]. +NPC id=7531, name=2scompany, level=76, option=[null, null, Walk here, Follow, Trade], anims=[809, -1]. +NPC id=7532, name=3sacrowd, level=103, option=[null, null, Walk here, Follow, Trade], anims=[808, 1661]. +NPC id=7533, name=4sjustsilly, level=103, option=[null, null, Walk here, Follow, Trade], anims=[8980, 1210]. +NPC id=7534, name=Roadblocked, level=68, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7535, name=Barricade, level=0, option=[null, Attack, null, null, null], anims=[-1, -1]. +NPC id=7536, name=Barricade, level=0, option=[null, Attack, null, null, null], anims=[475, -1]. +NPC id=7537, name=Yoinker, level=81, option=[null, null, Walk here, Follow, Trade], anims=[1421, -1]. +NPC id=7538, name=Yoinker, level=81, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7539, name=Stopthief, level=76, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7540, name=Stopthief, level=76, option=[null, null, Walk here, Follow, Trade], anims=[1421, -1]. +NPC id=7541, name=Knickknack, level=87, option=[null, null, Walk here, Follow, Trade], anims=[808, 1661]. +NPC id=7542, name=Paddywhack, level=63, option=[null, null, Walk here, Follow, Trade], anims=[7047, -1]. +NPC id=7543, name=Giveadog, level=81, option=[null, null, Walk here, Follow, Trade], anims=[5869, 5868]. +NPC id=7544, name=Spacebadgers, level=53, option=[null, null, Walk here, Follow, Trade], anims=[7047, -1]. +NPC id=7545, name=Freakypeaky, level=31, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7546, name=Rollinghome, level=112, option=[null, null, Walk here, Follow, Trade], anims=[808, 1661]. +NPC id=7547, name=Nullpointer, level=61, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7548, name=Badgerfreak, level=118, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7549, name=Windstrike32, level=91, option=[null, null, Walk here, Follow, Trade], anims=[809, -1]. +NPC id=7550, name=Void Knight, level=0, option=[null, null, null, null, null], anims=[3926, -1]. +NPC id=7551, name=Portal, level=0, option=[Attack, null, null, null, null], anims=[3933, 3933]. +NPC id=7552, name=Portal, level=0, option=[Attack, null, null, null, null], anims=[3936, 3936]. +NPC id=7553, name=Portal, level=0, option=[Attack, null, null, null, null], anims=[3928, 3928]. +NPC id=7554, name=Portal, level=0, option=[Attack, null, null, null, null], anims=[3928, 3928]. +NPC id=7555, name=Portal, level=0, option=[null, null, null, null, null], anims=[6879, 6879]. +NPC id=7556, name=Portal, level=0, option=[null, null, null, null, null], anims=[6880, 6880]. +NPC id=7557, name=Portal, level=0, option=[null, null, null, null, null], anims=[6878, 6878]. +NPC id=7558, name=Portal, level=0, option=[null, null, null, null, null], anims=[6878, 6878]. +NPC id=7559, name=Brawler, level=158, option=[Attack, null, null, null, null], anims=[3893, 3892]. +NPC id=7560, name=Lostme, level=130, option=[null, null, Walk here, Follow, Trade], anims=[7047, -1]. +NPC id=7561, name=Chiercat, level=113, option=[null, null, Walk here, Follow, Trade], anims=[808, 1661]. +NPC id=7562, name=Skydischarge, level=127, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7563, name=Agplus, level=107, option=[null, null, Walk here, Follow, Trade], anims=[8980, -1]. +NPC id=7564, name=Distantthin, level=89, option=[null, null, Walk here, Follow, Trade], anims=[2065, -1]. +NPC id=7565, name=Allmarshes, level=98, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7566, name=Explosive67, level=100, option=[null, null, Walk here, Follow, Trade], anims=[808, 1661]. +NPC id=7567, name=Wraithboss, level=102, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7568, name=What Goudron, level=107, option=[null, null, Walk here, Follow, Trade], anims=[8980, -1]. +NPC id=7569, name=Alpha1beta, level=111, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7570, name=Solltalk, level=122, option=[null, null, Walk here, Follow, Trade], anims=[808, 1661]. +NPC id=7571, name=Hm Val, level=126, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7572, name=Wizzydumped, level=130, option=[null, null, Walk here, Follow, Trade], anims=[808, 1661]. +NPC id=7573, name=Oddskater, level=129, option=[null, null, Walk here, Follow, Trade], anims=[808, 1661]. +NPC id=7574, name=Lvzyoda, level=117, option=[null, null, Walk here, Follow, Trade], anims=[808, 1661]. +NPC id=7575, name=Airstriker, level=107, option=[null, null, Walk here, Follow, Trade], anims=[4591, -1]. +NPC id=7576, name=Droepedoff, level=88, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7577, name=Plzpudding, level=125, option=[null, null, Walk here, Follow, Trade], anims=[808, 1661]. +NPC id=7578, name=Assassin10, level=115, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7579, name=Steallake, level=113, option=[null, null, Walk here, Follow, Trade], anims=[808, -1]. +NPC id=7580, name=Poledragon, level=114, option=[null, null, Walk here, Follow, Trade], anims=[813, -1]. +NPC id=7581, name=Deepkiwi, level=115, option=[null, null, Walk here, Follow, Trade], anims=[813, -1]. +NPC id=7582, name=Al Truism, level=116, option=[null, null, Walk here, Follow, Trade], anims=[808, 824]. +NPC id=7583, name=Ohhhhdude, level=117, option=[null, null, Walk here, Follow, Trade], anims=[813, -1]. +NPC id=7584, name=Bigface Oz, level=118, option=[null, null, Walk here, Follow, Trade], anims=[813, -1]. +NPC id=7585, name=Torcher, level=79, option=[Attack, null, null, null, null], anims=[3878, 3879]. +NPC id=7586, name=Torcher, level=79, option=[Attack, null, null, null, null], anims=[3878, 3879]. +NPC id=7587, name=Torcher, level=91, option=[Attack, null, null, null, null], anims=[3878, 3879]. +NPC id=7588, name=Torcher, level=92, option=[Attack, null, null, null, null], anims=[3878, 3879]. +NPC id=7589, name=Defiler, level=97, option=[Attack, null, null, null, null], anims=[3918, 3919]. +NPC id=7590, name=Defiler, level=97, option=[Attack, null, null, null, null], anims=[3918, 3919]. +NPC id=7591, name=Shifter, level=90, option=[Attack, null, null, null, null], anims=[3899, 3898]. +NPC id=7592, name=Shifter, level=90, option=[Attack, null, null, null, null], anims=[3899, 3898]. +NPC id=7593, name=Shifter, level=104, option=[Attack, null, null, null, null], anims=[3899, 3898]. +NPC id=7594, name=Shifter, level=104, option=[Attack, null, null, null, null], anims=[3899, 3898]. +NPC id=7595, name=Splatter, level=44, option=[Attack, null, null, null, null], anims=[3886, 3887]. +NPC id=7596, name=Splatter, level=54, option=[Attack, null, null, null, null], anims=[3886, 3887]. +NPC id=7597, name=Splatter, level=65, option=[Attack, null, null, null, null], anims=[3886, 3887]. +NPC id=7598, name=Spinner, level=74, option=[Attack, null, null, null, null], anims=[3906, 3907]. +NPC id=7599, name=Ravager, level=106, option=[Attack, null, null, null, null], anims=[3913, 3914]. +NPC id=7600, name=Fiara, level=0, option=[Talk-to, null, null, null, null], anims=[9009, -1]. +NPC id=7601, name=Reggie, level=0, option=[Talk-to, null, Trade, null, null], anims=[8528, 8527]. +NPC id=7602, name=Getorix, level=0, option=[Talk-to, null, null, null, null], anims=[8528, 8527]. +NPC id=7603, name=Pontimer, level=0, option=[Talk-to, null, null, null, null], anims=[8528, 8527]. +NPC id=7604, name=Alran, level=0, option=[Talk-to, null, null, null, null], anims=[8528, 8527]. +NPC id=7605, name=Banker, level=0, option=[Talk-to, null, Bank, Collect, null], anims=[5607, 5606]. +NPC id=7606, name=Vyrewatch, level=110, option=[Talk-to, Attack, null, null, null], anims=[9118, -1]. +NPC id=7607, name=Vyrewatch, level=120, option=[Talk-to, Attack, null, null, null], anims=[9118, -1]. +NPC id=7608, name=Vyrewatch, level=130, option=[Talk-to, Attack, null, null, null], anims=[9118, -1]. +NPC id=7609, name=Vyrewatch, level=140, option=[Talk-to, Attack, null, null, null], anims=[9118, -1]. +NPC id=7610, name=Flying female vampire, level=110, option=[Talk-to, Attack, null, null, null], anims=[9117, -1]. +NPC id=7611, name=Flying female vampire, level=120, option=[Talk-to, Attack, null, null, null], anims=[9117, -1]. +NPC id=7612, name=Flying female vampire, level=130, option=[Talk-to, Attack, null, null, null], anims=[9117, -1]. +NPC id=7613, name=Flying female vampire, level=140, option=[Talk-to, Attack, null, null, null], anims=[9117, -1]. +NPC id=7614, name=Vyrewatch, level=110, option=[Talk-to, Attack, null, null, null], anims=[9117, -1]. +NPC id=7615, name=Vyrewatch, level=120, option=[Talk-to, Attack, null, null, null], anims=[9117, -1]. +NPC id=7616, name=Vyrewatch, level=130, option=[Talk-to, Attack, null, null, null], anims=[9117, -1]. +NPC id=7617, name=Vyrewatch, level=140, option=[Talk-to, Attack, null, null, null], anims=[9117, -1]. +NPC id=7618, name=Vyrewatch, level=110, option=[Talk-to, Attack, null, null, null], anims=[9118, -1]. +NPC id=7619, name=Vyrewatch, level=120, option=[Talk-to, Attack, null, null, null], anims=[9118, -1]. +NPC id=7620, name=Vyrewatch, level=130, option=[Talk-to, Attack, null, null, null], anims=[9118, -1]. +NPC id=7621, name=Vyrewatch, level=140, option=[Talk-to, Attack, null, null, null], anims=[9118, -1]. +NPC id=7622, name=Vyrewatch, level=110, option=[Talk-to, Attack, null, null, null], anims=[9117, -1]. +NPC id=7623, name=Vyrewatch, level=120, option=[Talk-to, Attack, null, null, null], anims=[9117, -1]. +NPC id=7624, name=Vyrewatch, level=130, option=[Talk-to, Attack, null, null, null], anims=[9117, -1]. +NPC id=7625, name=Vyrewatch, level=140, option=[Talk-to, Attack, null, null, null], anims=[9117, -1]. +NPC id=7626, name=Vyrewatch, level=110, option=[Talk-to, Attack, null, null, null], anims=[9117, -1]. +NPC id=7627, name=Vyrewatch, level=120, option=[Talk-to, Attack, null, null, null], anims=[9117, -1]. +NPC id=7628, name=Vyrewatch, level=130, option=[Talk-to, Attack, null, null, null], anims=[9117, -1]. +NPC id=7629, name=Vyrewatch, level=140, option=[Talk-to, Attack, null, null, null], anims=[9117, -1]. +NPC id=7630, name=Vyrewatch, level=85, option=[null, Attack, null, null, null], anims=[4689, 4683]. +NPC id=7631, name=Vyrewatch, level=110, option=[null, Attack, null, null, null], anims=[4689, 4683]. +NPC id=7632, name=Vyrewatch, level=130, option=[null, Attack, null, null, null], anims=[4689, 4683]. +NPC id=7633, name=Vyrewatch, level=85, option=[Talk-to, Attack, null, null, null], anims=[9117, -1]. +NPC id=7634, name=Vyrewatch, level=110, option=[Talk-to, Attack, null, null, null], anims=[9117, -1]. +NPC id=7635, name=Vyrewatch, level=130, option=[Talk-to, Attack, null, null, null], anims=[9117, -1]. +NPC id=7636, name=Fishing spot, level=0, option=[null, null, Bait, null, hidden], anims=[2126, 2126]. +NPC id=7637, name=null, level=1, option=[null, null, null, null, null], anims=[9093, 9094]. +NPC id=7638, name=null, level=1, option=[null, null, null, null, null], anims=[9037, 9037]. +NPC id=7639, name=null, level=1, option=[null, null, null, null, null], anims=[9093, 9094]. +NPC id=7640, name=Skeletal hand, level=80, option=[null, Attack, null, null, null], anims=[9128, 9129]. +NPC id=7641, name=Zombie hand, level=90, option=[null, Attack, null, null, null], anims=[9128, 9129]. +NPC id=7642, name=Mutated bloodveld, level=126, option=[null, Attack, null, null, null], anims=[9133, -1]. +NPC id=7643, name=Mutated bloodveld, level=146, option=[null, Attack, null, null, null], anims=[9133, -1]. +NPC id=7644, name=Zaromark Sliver, level=80, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=7645, name=Zaromark Sliver, level=80, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=7646, name=Zaromark Sliver, level=80, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=7647, name=Zaromark Sliver, level=80, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=7648, name=Zaromark Sliver, level=80, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=7649, name=Zaromark Sliver, level=80, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=7650, name=Zaromark Sliver, level=80, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=7651, name=Zaromark Sliver, level=80, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=7652, name=Zaromark Sliver, level=0, option=[null, null, null, null, null], anims=[9099, -1]. +NPC id=7653, name=Zaromark Sliver, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=7654, name=Fistandantilus, level=80, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=7655, name=Fistandantilus, level=80, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=7656, name=Fistandantilus, level=80, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=7657, name=Fistandantilus, level=80, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=7658, name=Fistandantilus, level=80, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=7659, name=Fistandantilus, level=80, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=7660, name=Fistandantilus, level=80, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=7661, name=Fistandantilus, level=80, option=[null, Attack, null, null, null], anims=[808, -1]. +NPC id=7662, name=Fistandantilus, level=0, option=[null, null, null, null, null], anims=[9099, -1]. +NPC id=7663, name=Fistandantilus, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=7664, name=Mercenary Adventurer, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=7665, name=Ivan Strom, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=7666, name=Mysterious person, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=7667, name=Mysterious person, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=7668, name=Mysterious person, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=7669, name=Mysterious person, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=7670, name=Mysterious person, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=7671, name=Mysterious person, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=7672, name=Flaygian Screwte, level=0, option=[Talk-to, null, null, null, null], anims=[-1, -1]. +NPC id=7673, name=Mekritus A'hara, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=7674, name=Andiess Juip, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=7675, name=Kael Forshaw, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=7676, name=Andiess Juip, level=0, option=[Talk-to, Hidden, null, null, null], anims=[808, -1]. +NPC id=7677, name=Kael Forshaw, level=0, option=[Talk-to, Hidden, null, null, null], anims=[808, -1]. +NPC id=7678, name=Safalaan, level=0, option=[Talk-to, Hidden, null, null, null], anims=[808, -1]. +NPC id=7679, name=Andiess Juip, level=0, option=[null, Hidden, null, null, null], anims=[808, -1]. +NPC id=7680, name=Kael Forshaw, level=0, option=[null, Hidden, null, null, null], anims=[808, -1]. +NPC id=7681, name=Safalaan, level=0, option=[null, Hidden, null, null, null], anims=[808, -1]. +NPC id=7682, name=Vyrewatch, level=120, option=[null, Attack, null, null, null], anims=[4689, 4683]. +NPC id=7683, name=Vyrewatch, level=120, option=[null, Attack, null, null, null], anims=[4689, 4683]. +NPC id=7684, name=Vyrewatch, level=1, option=[null, null, null, null, null], anims=[9115, 9114]. +NPC id=7685, name=Vyrewatch, level=1, option=[null, null, null, null, null], anims=[9115, 9114]. +NPC id=7686, name=Safalaan, level=41, option=[Talk-to, hidden, null, null, null], anims=[9069, -1]. +NPC id=7687, name=Spectral Vyrewatch, level=0, option=[null, null, null, null, null], anims=[9028, 9028]. +NPC id=7688, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=7689, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=7690, name=Drezel, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=7691, name=Vyrewatch, level=110, option=[null, Attack, null, null, null], anims=[4689, 4683]. +NPC id=7692, name=Vyrewatch, level=120, option=[null, Attack, null, null, null], anims=[4689, 4683]. +NPC id=7693, name=Vyrewatch, level=130, option=[null, Attack, null, null, null], anims=[4689, 4683]. +NPC id=7694, name=Vyrewatch, level=130, option=[null, Attack, null, null, null], anims=[4689, 4683]. +NPC id=7695, name=Vyrewatch, level=110, option=[Talk-to, Attack, null, null, null], anims=[9117, -1]. +NPC id=7696, name=Vyrewatch, level=120, option=[Talk-to, Attack, null, null, null], anims=[9117, -1]. +NPC id=7697, name=Vyrewatch, level=130, option=[Talk-to, Attack, null, null, null], anims=[9117, -1]. +NPC id=7698, name=Vyrewatch, level=130, option=[Talk-to, Attack, null, null, null], anims=[9117, -1]. +NPC id=7699, name=Vyrewatch, level=110, option=[Talk-to, Attack, null, null, null], anims=[4689, 4683]. +NPC id=7700, name=Vyrewatch, level=120, option=[Talk-to, Attack, null, null, null], anims=[4689, 4683]. +NPC id=7701, name=Vyrewatch, level=130, option=[Talk-to, Attack, null, null, null], anims=[4689, 4683]. +NPC id=7702, name=Vyrewatch, level=140, option=[Talk-to, Attack, null, null, null], anims=[4689, 4683]. +NPC id=7703, name=Vyrewatch, level=110, option=[Talk-to, Attack, null, null, null], anims=[9117, -1]. +NPC id=7704, name=Vyrewatch, level=120, option=[Talk-to, Attack, null, null, null], anims=[9117, -1]. +NPC id=7705, name=Vyrewatch, level=130, option=[Talk-to, Attack, null, null, null], anims=[9117, -1]. +NPC id=7706, name=Vyrewatch, level=140, option=[Talk-to, Attack, null, null, null], anims=[9117, -1]. +NPC id=7707, name=Drezel, level=0, option=[Talk-to, null, null, null, null], anims=[808, -1]. +NPC id=7708, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=7709, name=null, level=1, option=[null, null, null, null, null], anims=[808, -1]. +NPC (wrapper) id=7710, child npcs=[7672, -1]. +NPC id=7711, name=Temple guardian, level=30, option=[null, Attack, null, null, null], anims=[6561, 6560]. +NPC id=7712, name=null, level=1, option=[null, null, null, null, null], anims=[-1, -1]. +NPC id=7713, name=Baby icefiend, level=0, option=[Catch, null, null, null, null], anims=[8077, 9153]. +NPC id=7714, name=Icefiend, level=13, option=[null, Attack, null, null, null], anims=[9145, 8076]. +NPC id=7715, name=Icefiend, level=13, option=[null, Attack, null, null, null], anims=[8077, 8076]. +NPC (wrapper) id=7716, child npcs=[7714, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7714, -1, -1, -1, -1, 7714, -1, -1, -1, -1, 7714, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7714, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7714, -1, -1, -1, -1, 7714, -1, -1, -1, 7714, 7715, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7715, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7715, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7715, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7715, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7715, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7715, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7715, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7715, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7715, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7714, -1]. +NPC id=7717, name=Professor Arblenap, level=0, option=[null, null, null, null, null], anims=[195, 189]. +NPC id=7718, name=Brother Bordiss, level=0, option=[null, null, null, null, null], anims=[101, 98]. +NPC id=7719, name=Brother Althric, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=7720, name=Drorkar, level=0, option=[null, null, null, null, null], anims=[101, 98]. +NPC id=7721, name=Nurmof, level=0, option=[null, null, null, null, null], anims=[101, 98]. +NPC id=7722, name=Lakki the delivery dwarf, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=7723, name=Drorkar, level=0, option=[Talk-to, null, Pickpocket, null, null], anims=[101, 98]. +NPC id=7724, name=Brother Bordiss, level=0, option=[Talk-to, null, null, null, null], anims=[101, 98]. +NPC id=7725, name=Professor Arblenap, level=0, option=[Talk-to, null, null, null, null], anims=[195, 189]. +NPC id=7726, name=Assistant, level=0, option=[null, null, null, null, null], anims=[9138, -1]. +NPC id=7727, name=Monk, level=5, option=[Talk-to, Attack, null, null, null], anims=[808, -1]. +NPC (wrapper) id=7728, child npcs=[7722, -1]. +NPC (wrapper) id=7729, child npcs=[7723, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7723, -1, -1, -1, -1, 7723, -1, -1, -1, -1, 7723, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7723, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7723, -1, -1, -1, -1, 7723, -1, -1, -1, 7723, 7723, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7723, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7723, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7723, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7723, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7723, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7723, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7723, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7723, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7723, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7724, -1]. +NPC (wrapper) id=7730, child npcs=[7724, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7724, -1, -1, -1, -1, 7724, -1, -1, -1, -1, 7724, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7724, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7724, -1, -1, -1, -1, 7724, -1, -1, -1, 7724, 7724, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7724, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7724, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7724, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7724, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7724, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7724, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7724, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7724, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7724, -1]. +NPC id=7731, name=null, level=1, option=[null, null, null, null, null], anims=[195, 189]. +NPC (wrapper) id=7732, child npcs=[7736, 7713, -1]. +NPC (wrapper) id=7733, child npcs=[7736, 7713, -1]. +NPC (wrapper) id=7734, child npcs=[7736, 7713, -1]. +NPC (wrapper) id=7735, child npcs=[7736, 7713, -1]. +NPC id=7736, name=Baby icefiend, level=0, option=[null, null, null, null, null], anims=[9145, 9153]. +NPC id=7737, name=Will, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=7738, name=Will, level=0, option=[null, null, null, null, null], anims=[9217, 9216]. +NPC id=7739, name=Phil, level=0, option=[null, null, null, null, null], anims=[808, -1]. +NPC id=7740, name=Jiggling crate, level=0, option=[Search, null, null, null, null], anims=[9198, -1]. +NPC id=7741, name=Three little kittens, level=0, option=[null, null, null, null, null], anims=[9208, 9210]. +NPC id=7742, name=Fluffs, level=0, option=[Pick-up, null, Stroke, Talk-to, null], anims=[9158, 9157]. +NPC id=7743, name=Fluffs, level=0, option=[null, null, null, null, null], anims=[9158, 9157]. +NPC id=7744, name=null, level=1, option=[null, null, null, null, null], anims=[9158, 9157]. +NPC id=7745, name=Kittens, level=0, option=[null, null, null, null, null], anims=[9208, 9210]. +NPC id=7746, name=TzHaar-Mej-Malk, level=0, option=[Talk-to, null, null, null, null], anims=[9281, 9281]. +NPC id=7747, name=TzHaar-Xil-Tog, level=0, option=[Talk-to, null, null, null, null], anims=[9281, 9281]. +NPC id=7748, name=TzHaar-Hur-Frok, level=0, option=[Talk-to, null, null, null, null], anims=[9281, 9281]. +NPC id=7749, name=TzHaar-Ket-Grol, level=0, option=[Talk-to, null, null, null, null], anims=[9281, 9296]. +NPC id=7750, name=TzHaar-Ket-Rok, level=0, option=[Talk-to, null, null, null, null], anims=[9281, 9296]. +NPC id=7751, name=TzHaar-Ket-Lurk, level=0, option=[Talk-to, null, null, null, null], anims=[9281, 9296]. +NPC id=7752, name=TzHaar-Mej-Lor, level=0, option=[Talk-to, null, null, null, null], anims=[9281, 9281]. +NPC id=7753, name=TzHaar-Mej, level=0, option=[Talk-to, null, null, null, null], anims=[9325, 9320]. +NPC id=7754, name=TzHaar-Hur, level=0, option=[Talk-to, null, null, null, null], anims=[9324, 9321]. +NPC id=7755, name=TzHaar-Xil, level=0, option=[Talk-to, null, null, null, null], anims=[9323, 9322]. +NPC id=7756, name=Library assistant, level=0, option=[null, null, null, null, null], anims=[9311, -1]. +NPC id=7757, name=TzHaar-Hur-Brekt, level=0, option=[Talk-to, null, null, null, null], anims=[9326, 9326]. +NPC id=7758, name=TzHaar-Hur-Brekt, level=0, option=[Talk-to, null, null, null, null], anims=[9281, 9281]. +NPC id=7759, name=TzHaar-Ket-Jok, level=0, option=[Talk-to, null, null, null, null], anims=[9314, 9281]. +NPC id=7760, name=TzHaar-Ket-Jok, level=0, option=[Talk-to, null, null, null, null], anims=[9282, 9280]. +NPC id=7761, name=TzHaar-Xil-Mor, level=0, option=[Talk-to, null, null, null, null], anims=[9313, 9281]. +NPC id=7762, name=TzHaar-Xil-Mor, level=0, option=[Talk-to, null, null, null, null], anims=[9283, 9280]. +NPC id=7763, name=TzHaar-Mej-Kol, level=0, option=[Talk-to, null, null, null, null], anims=[9314, 9281]. +NPC id=7764, name=TzHaar-Mej-Kol, level=0, option=[Talk-to, null, null, null, null], anims=[9284, 9280]. +NPC id=7765, name=TzHaar-Hur-Klag, level=0, option=[Talk-to, null, null, null, null], anims=[9313, 9281]. +NPC id=7766, name=TzHaar-Hur-Klag, level=0, option=[Talk-to, null, null, null, null], anims=[9285, 9280]. +NPC id=7767, name=TzHaar-Hur, level=74, option=[Talk-to, Attack, null, null, null], anims=[9281, 9280]. +NPC id=7768, name=TzHaar-Hur, level=74, option=[Talk-to, Attack, null, null, null], anims=[9281, 9280]. +NPC id=7769, name=TzHaar-Hur, level=74, option=[Talk-to, Attack, null, null, null], anims=[9281, 9280]. +NPC id=7770, name=TokTz-Ket-Dill, level=100, option=[null, Attack, null, null, null], anims=[9334, 9333]. +NPC id=7771, name=TokTz-Ket-Dill, level=100, option=[null, Attack, null, null, null], anims=[9334, 9333]. +NPC id=7772, name=Lava monster, level=47, option=[null, Attack, null, null, null], anims=[9339, 9339]. +NPC id=7773, name=Fire monster, level=47, option=[null, Attack, null, null, null], anims=[9343, 9343]. diff --git a/dumps/498/498_object_anims b/dumps/498/498_object_anims new file mode 100644 index 0000000..a0c2978 --- /dev/null +++ b/dumps/498/498_object_anims @@ -0,0 +1,2346 @@ +1 - Crate anim = 3206 +115 - Party Balloon anim = 498 +116 - Party Balloon anim = 498 +117 - Party Balloon anim = 498 +118 - Party Balloon anim = 498 +119 - Party Balloon anim = 498 +120 - Party Balloon anim = 498 +121 - Party Balloon anim = 498 +122 - Party Balloon anim = 498 +123 - Party Balloon anim = 499 +124 - Party Balloon anim = 499 +125 - Party Balloon anim = 499 +126 - Party Balloon anim = 499 +127 - Party Balloon anim = 499 +128 - Party Balloon anim = 499 +129 - Party Balloon anim = 500 +130 - Party Balloon anim = 501 +196 - null anim = 481 +197 - null anim = 481 +198 - null anim = 481 +199 - null anim = 481 +201 - Lamp anim = 467 +206 - null anim = 481 +207 - null anim = 481 +288 - null anim = 526 +289 - null anim = 527 +290 - null anim = 527 +470 - null anim = 907 +515 - null anim = 505 +521 - null anim = 524 +522 - null anim = 524 +672 - Broken barrel anim = 449 +673 - null anim = 523 +674 - null anim = 2709 +675 - null anim = 523 +676 - null anim = 523 +677 - null anim = 523 +683 - Grandfather clock anim = 1726 +684 - Swamp bubbles anim = 480 +685 - Weather vane anim = 488 +692 - Cauldron anim = 479 +704 - null anim = 469 +714 - Fire remains anim = 475 +715 - null anim = 476 +716 - null anim = 476 +724 - Standing torch anim = 473 +725 - null anim = 473 +726 - null anim = 1071 +731 - null anim = 493 +732 - null anim = 494 +735 - Swamp bubbles anim = 480 +740 - null anim = 504 +860 - Flagpole anim = 471 +861 - Flagpole anim = 471 +862 - Flagpole anim = 471 +869 - Flagpole anim = 471 +907 - Charms anim = 468 +955 - Spooky picture anim = 470 +1293 - Spirit tree anim = 332 +1294 - Spirit tree anim = 332 +1295 - Spirit tree anim = 333 +1395 - Fly trap anim = 492 +1778 - Millstones anim = 1731 +1779 - Sails anim = 472 +1784 - null anim = 1731 +1812 - Portal anim = 491 +1887 - null anim = 503 +1914 - null anim = 473 +2016 - null anim = 522 +2017 - null anim = 522 +2018 - null anim = 522 +2019 - Whirlpool anim = 456 +2024 - Cauldron anim = 479 +2043 - Cauldron anim = 479 +2118 - Whirlpool anim = 456 +2119 - Rocks anim = 523 +2120 - Rocks anim = 523 +2121 - Rocks anim = 523 +2122 - Rocks anim = 523 +2123 - Rocks anim = 523 +2124 - Rocks anim = 523 +2125 - Rocks anim = 523 +2126 - Rocks anim = 523 +2127 - Rocks anim = 523 +2128 - Rocks anim = 523 +2129 - Rocks anim = 523 +2130 - Rocks anim = 523 +2131 - Rocks anim = 523 +2132 - Rocks anim = 523 +2133 - Rocks anim = 523 +2134 - Rocks anim = 523 +2135 - Rocks anim = 523 +2136 - Rocks anim = 523 +2137 - Rocks anim = 523 +2138 - Rocks anim = 523 +2139 - Rocks anim = 523 +2140 - Rocks anim = 523 +2141 - Chest anim = 2709 +2142 - Cauldron of Thunder anim = 479 +2167 - Leak anim = 464 +2452 - null anim = 2714 +2453 - null anim = 2714 +2454 - null anim = 2714 +2455 - null anim = 2714 +2456 - null anim = 2714 +2457 - null anim = 2714 +2458 - null anim = 2714 +2459 - null anim = 2714 +2460 - null anim = 2714 +2461 - null anim = 2714 +2462 - null anim = 2714 +2463 - null anim = 2714 +2464 - null anim = 2714 +2465 - Portal anim = 504 +2466 - Portal anim = 504 +2467 - Portal anim = 504 +2468 - Portal anim = 504 +2469 - Portal anim = 504 +2470 - Portal anim = 504 +2471 - Portal anim = 504 +2472 - Portal anim = 504 +2473 - Portal anim = 504 +2474 - Portal anim = 504 +2475 - Portal anim = 504 +2476 - Portal anim = 504 +2477 - Portal anim = 504 +2478 - Altar anim = 503 +2479 - Altar anim = 503 +2480 - Altar anim = 503 +2481 - Altar anim = 503 +2482 - Altar anim = 503 +2483 - Altar anim = 503 +2484 - Altar anim = 503 +2485 - Altar anim = 503 +2486 - Altar anim = 503 +2487 - Altar anim = 503 +2488 - Altar anim = 503 +2489 - Altar anim = 503 +2490 - Altar anim = 503 +2492 - Portal anim = 504 +2498 - Mysterious glow anim = 502 +2499 - Mysterious glow anim = 502 +2500 - Mysterious glow anim = 502 +2501 - Mysterious glow anim = 502 +2502 - Mysterious glow anim = 502 +2586 - Rocks anim = 523 +2607 - Rocks anim = 523 +2608 - Rocks anim = 523 +2630 - Fishing spot anim = 525 +2654 - Sinclair family fountain anim = 6023 +2715 - Hellhound anim = 6561 +2724 - Fireplace anim = 477 +2725 - Fireplace anim = 478 +2726 - Fireplace anim = 478 +2727 - Cooking pot anim = 477 +2732 - Fire anim = 475 +2842 - Magical shield anim = 446 +2908 - Fire Wall anim = 476 +2909 - Fire Wall anim = 476 +2916 - Rocks anim = 523 +2933 - null anim = 449 +2980 - Flowers anim = 912 +2981 - Flowers anim = 912 +2982 - Flowers anim = 912 +2983 - Flowers anim = 912 +2984 - Flowers anim = 912 +2985 - Flowers anim = 912 +2986 - Flowers anim = 912 +2987 - Flowers anim = 912 +2988 - Flowers anim = 912 +3038 - Fire anim = 475 +3108 - Entrance anim = 917 +3109 - Entrance anim = 917 +3111 - Entrance anim = 917 +3112 - Entrance anim = 917 +3113 - Entrance anim = 917 +3114 - Entrance anim = 917 +3240 - Bridge anim = 474 +3263 - Swamp anim = 480 +3357 - null anim = 476 +3358 - null anim = 476 +3405 - null anim = 1051 +3407 - null anim = 1049 +3410 - null anim = 4860 +3411 - null anim = 1052 +3434 - null anim = 1073 +3474 - null anim = 1073 +3493 - Monument anim = 1072 +3494 - Monument anim = 1072 +3495 - Monument anim = 1072 +3496 - Monument anim = 1072 +3497 - Monument anim = 1072 +3498 - Monument anim = 1072 +3499 - Monument anim = 1072 +3509 - Fungi on log anim = 1096 +3511 - Budding branch anim = 1098 +3513 - A golden pear bush anim = 1097 +3567 - Blade anim = 1103 +3577 - Plank anim = 1104 +3581 - Ticket Dispenser anim = 1108 +3582 - Floor spikes anim = 1112 +3609 - null anim = 493 +3634 - Strange shrine anim = 1127 +3637 - null anim = 1138 +3662 - Cooking pot anim = 479 +3680 - Flagpole anim = 471 +3752 - Mysterious glow anim = 502 +3769 - Fire anim = 475 +3775 - Fire anim = 475 +3824 - Troll Stew anim = 479 +3862 - Burning bones anim = 475 +3872 - null anim = 1211 +3878 - null anim = 1212 +3918 - Elven lamp anim = 1212 +3926 - null anim = 1216 +3961 - null anim = 480 +3966 - null anim = 523 +3976 - Catapult anim = 1223 +3987 - Barrel anim = 1233 +3997 - Tent wall anim = 1234 +4004 - Well anim = 1235 +4005 - Well anim = 1235 +4024 - Barrel anim = 1231 +4025 - Barrel anim = 1233 +4046 - null anim = 1260 +4047 - null anim = 1261 +4069 - Temple wall anim = 1293 +4070 - Temple wall anim = 1294 +4071 - Temple wall anim = 1295 +4072 - Temple wall anim = 1296 +4073 - Temple wall anim = 1297 +4074 - Temple wall anim = 1298 +4075 - Temple wall anim = 1299 +4076 - Temple wall anim = 1300 +4077 - Temple wall anim = 1301 +4078 - Temple wall anim = 1302 +4080 - Temple wall anim = 1293 +4081 - Temple wall anim = 1294 +4082 - Temple wall anim = 1295 +4083 - Temple wall anim = 1296 +4084 - Temple wall anim = 1297 +4085 - Temple wall anim = 1298 +4086 - Temple wall anim = 1299 +4087 - Temple wall anim = 1300 +4088 - Temple wall anim = 1301 +4089 - Temple wall anim = 1302 +4090 - Flaming Fire altar anim = 475 +4093 - Funeral Pyre anim = 1303 +4094 - Funeral Pyre anim = 1304 +4095 - Funeral Pyre anim = 1304 +4096 - Funeral Pyre anim = 1304 +4097 - Funeral Pyre anim = 1304 +4098 - Funeral Pyre anim = 1304 +4099 - Funeral Pyre anim = 1304 +4149 - Lalli's Stew anim = 479 +4150 - Portal anim = 504 +4151 - Portal anim = 504 +4152 - Portal anim = 504 +4153 - Portal anim = 504 +4154 - Portal anim = 504 +4155 - Portal anim = 504 +4156 - Portal anim = 504 +4157 - Portal anim = 504 +4192 - null anim = 475 +4265 - Fire anim = 475 +4266 - Fire anim = 475 +4267 - Spit roast anim = 1334 +4387 - Saradomin Portal anim = 504 +4388 - Zamorak Portal anim = 504 +4389 - Portal anim = 504 +4390 - Portal anim = 504 +4406 - Portal anim = 504 +4407 - Portal anim = 504 +4408 - Guthix Portal anim = 504 +4422 - Barricade anim = 475 +4469 - Energy Barrier anim = 1433 +4470 - Energy Barrier anim = 1433 +4517 - null anim = 481 +4587 - Lighting mechanism anim = 1347 +4589 - Lighting mechanism anim = 1349 +4590 - Lighting mechanism anim = 1348 +4618 - Fireplace anim = 475 +4619 - null anim = 1362 +4650 - Fireplace anim = 475 +4668 - null anim = 1355 +4692 - Flagpole anim = 471 +4693 - Flagpole anim = 471 +4694 - null anim = 481 +4765 - Wall of flame anim = 476 +4766 - Wall of flame anim = 476 +4767 - Sacrificial Pyre anim = 1416 +4771 - Awowogei anim = 1398 +4866 - Gnome Glider anim = 1411 +4886 - Floor spikes anim = 1112 +4900 - Saradomin Standard anim = 1430 +4901 - Zamorak Standard anim = 1430 +4902 - Saradomin Standard anim = 1430 +4903 - Zamorak Standard anim = 1430 +4904 - Catapult anim = 1431 +4905 - Catapult anim = 1431 +4906 - null anim = 1430 +4907 - null anim = 1430 +5072 - Pillar anim = 473 +5116 - Statue anim = 1532 +5117 - Statue anim = 1533 +5146 - Goal anim = 1600 +5164 - Signpost anim = 1631 +5165 - Fireplace anim = 1629 +5177 - Lightning conductor anim = 1632 +5178 - Fireplace surround anim = 1630 +5179 - Fireplace surround anim = 1630 +5208 - null anim = 481 +5247 - null anim = 481 +5248 - Crystal growth anim = 1636 +5249 - Fire anim = 475 +5252 - Fire remains anim = 475 +5259 - Energy Barrier anim = 1433 +5282 - Ectofuntus anim = 1657 +5283 - Ectofuntus anim = 1657 +5461 - null anim = 1641 +5462 - null anim = 1642 +5463 - null anim = 1643 +5499 - Fire anim = 475 +5558 - Aggie's Cauldron anim = 479 +5559 - Charms anim = 468 +5589 - Water wheel anim = 1729 +5590 - Water wheel anim = 1729 +5591 - Water wheel anim = 1729 +5593 - null anim = 1729 +5594 - Water wheel anim = 1729 +5597 - Weather vane anim = 1733 +5604 - Rock anim = 1727 +5605 - Rock anim = 1727 +5606 - Rock anim = 1727 +5607 - null anim = 1727 +5608 - Spit roast anim = 1017 +5626 - null anim = 472 +5627 - Standard anim = 1734 +5628 - Standard anim = 1730 +5629 - Standard anim = 1730 +5631 - Fire anim = 1732 +5632 - Fire anim = 1732 +5811 - null anim = 1733 +5815 - Gnome landing light anim = 1747 +5816 - Flashing landing light anim = 1747 +5817 - Flashing landing light anim = 1747 +5818 - Flashing landing light anim = 1747 +5819 - Flashing landing light anim = 1747 +5820 - null anim = 1747 +5821 - null anim = 1747 +5822 - null anim = 1747 +5823 - null anim = 1747 +5826 - Swordshop Sign anim = 1430 +5883 - Mud anim = 480 +5884 - Swamp anim = 480 +5897 - Shining pool anim = 523 +5911 - null anim = 522 +5917 - Gas hole anim = 523 +5918 - Gas hole anim = 523 +5921 - null anim = 1812 +5963 - null anim = 1845 +5964 - Cannonball anim = 1845 +5965 - Gold cannonball anim = 1846 +5977 - Wall of flame anim = 476 +5978 - Wall of flame anim = 476 +5979 - Wall of flame anim = 476 +5980 - Wall of flame anim = 476 +5981 - Fire anim = 1847 +5985 - Rock anim = 1727 +5986 - Small rock anim = 1727 +5987 - Rock anim = 1727 +5988 - null anim = 1727 +6009 - Blue Fire anim = 476 +6093 - Fireplace anim = 1869 +6094 - Fireplace anim = 1869 +6095 - Fireplace anim = 1869 +6096 - Fireplace anim = 1869 +6197 - Table anim = 1868 +6199 - Table anim = 1868 +6201 - Table anim = 1868 +6202 - Lamp anim = 1868 +6203 - Lamp anim = 1868 +6246 - Table anim = 1875 +6254 - null anim = 917 +6257 - Dung anim = 1881 +6259 - Dung anim = 1881 +6282 - Portal anim = 1908 +6363 - Door anim = 1909 +6365 - null anim = 481 +6405 - null anim = 475 +6407 - null anim = 475 +6409 - null anim = 475 +6411 - null anim = 475 +6413 - Standing Torch anim = 475 +6414 - Standing Torch anim = 475 +6415 - Standing Torch anim = 475 +6416 - Standing Torch anim = 475 +6422 - null anim = 1923 +6424 - null anim = 1923 +6425 - Mystical mirror anim = 1923 +6426 - null anim = 1923 +6427 - Mystical mirror anim = 1923 +6428 - null anim = 1923 +6429 - Mystical mirror anim = 1923 +6430 - null anim = 1923 +6431 - Mystical mirror anim = 1923 +6432 - null anim = 1923 +6433 - Mystical mirror anim = 1923 +6438 - Vampire tomb anim = 1915 +6482 - null anim = 1943 +6483 - Obelisk anim = 1943 +6484 - Obelisk anim = 1943 +6485 - null anim = 1943 +6486 - Obelisk anim = 1943 +6487 - Obelisk anim = 1943 +6488 - null anim = 1943 +6489 - Obelisk anim = 1943 +6490 - Obelisk anim = 1943 +6491 - null anim = 1943 +6492 - Obelisk anim = 1943 +6493 - Obelisk anim = 1943 +6495 - null anim = 1940 +6518 - null anim = 1936 +6519 - null anim = 1937 +6520 - null anim = 1938 +6521 - Pitfall anim = 1939 +6522 - null anim = 1939 +6537 - null anim = 481 +6550 - null anim = 504 +6551 - Portal anim = 504 +6629 - Wall Crusher anim = 1944 +6642 - anim = 1998 +6643 - Doorway anim = 1999 +6657 - Juna anim = 2056 +6661 - Blue tears anim = 2054 +6662 - Green tears anim = 2054 +6665 - Blue tears anim = 2054 +6666 - Green tears anim = 2054 +6818 - null anim = 475 +6887 - null anim = 2091 +6895 - null anim = 1017 +6896 - Standing torch anim = 473 +6949 - null anim = 2131 +6967 - null anim = 2133 +6968 - null anim = 2133 +6972 - Bookcase anim = 2136 +6985 - Crusher anim = 2135 +7013 - Plant anim = 2137 +7014 - Plant anim = 2137 +7015 - Plant anim = 2137 +7129 - Fire rift anim = 2178 +7130 - Earth rift anim = 2178 +7131 - Body rift anim = 2178 +7132 - Cosmic rift anim = 2178 +7133 - Nature rift anim = 2178 +7134 - Chaos rift anim = 2178 +7135 - Law rift anim = 2178 +7136 - Death rift anim = 2178 +7137 - Water rift anim = 2178 +7138 - Soul rift anim = 2178 +7139 - Air rift anim = 2178 +7140 - Mind rift anim = 2178 +7141 - Blood rift anim = 2178 +7171 - Abyssal rift anim = 2260 +7181 - null anim = 2174 +7182 - null anim = 2174 +7189 - Tendrils anim = 2173 +7190 - Tendrils anim = 2173 +7191 - Tendrils anim = 2173 +7224 - Spinning blades anim = 2199 +7225 - Wall anim = 2198 +7227 - Floor anim = 1112 +7228 - Wall anim = 2196 +7229 - Wall anim = 2201 +7230 - Floor anim = 2203 +7241 - Pendulum anim = 2204 +7248 - Wall anim = 2209 +7252 - Blade anim = 2210 +7253 - Spin Blades anim = 2212 +7272 - Portal anim = 504 +7273 - Portal anim = 504 +7288 - Portal anim = 504 +7289 - Portal anim = 504 +7315 - Portal anim = 504 +7316 - Portal anim = 504 +7318 - Portal anim = 504 +7319 - Portal anim = 504 +7321 - Portal anim = 504 +7322 - Portal anim = 504 +7324 - Portal anim = 504 +7325 - Portal anim = 504 +7352 - Portal anim = 504 +7353 - Portal anim = 504 +7376 - null anim = 481 +8689 - Dairy cow anim = 5855 +8712 - Fireplace anim = 478 +8725 - Rock anim = 1727 +8726 - Rock anim = 1727 +8727 - Rocks anim = 1727 +8742 - Tree anim = 2313 +8767 - Elven lamp anim = 1212 +8774 - null anim = 1212 +8794 - null anim = 2331 +8796 - An empty rack anim = 2331 +8926 - Viking Boat anim = 2346 +8949 - null anim = 481 +8954 - Flag anim = 2359 +8955 - Flag anim = 2360 +8958 - Door anim = 2349 +8959 - Door anim = 2349 +8960 - Door anim = 2349 +8961 - Door anim = 2350 +8962 - Door anim = 2348 +8963 - Door anim = 2350 +8972 - Portal anim = 504 +8983 - null anim = 2379 +8985 - Uncooking pot anim = 1732 +8987 - Portal anim = 504 +9006 - Funeral Pyre anim = 1304 +9007 - Funeral Pyre anim = 1304 +9010 - Light Jungle anim = 2380 +9011 - Light Jungle anim = 2380 +9012 - Light Jungle anim = 2380 +9013 - Light Jungle anim = 2380 +9014 - Light Jungle anim = 2380 +9015 - Medium Jungle anim = 2380 +9016 - Medium Jungle anim = 2380 +9017 - Medium Jungle anim = 2380 +9018 - Medium Jungle anim = 2380 +9019 - Medium Jungle anim = 2380 +9020 - Dense Jungle anim = 2380 +9021 - Dense Jungle anim = 2380 +9022 - Dense Jungle anim = 2380 +9023 - Dense Jungle anim = 2380 +9024 - Dense Jungle anim = 2380 +9094 - Bar dispenser anim = 2440 +9099 - Smoke anim = 2439 +9100 - Conveyor belt anim = 2437 +9101 - Conveyor belt anim = 2437 +9103 - Drive belt anim = 2451 +9105 - Cogs anim = 2451 +9115 - Smoke anim = 2439 +9117 - Pipes anim = 2439 +9121 - Pipes anim = 2439 +9123 - Smoke anim = 2439 +9145 - Golden lantern anim = 1073 +9159 - Candles anim = 2564 +9160 - Candles anim = 2564 +9161 - Candles anim = 2564 +9294 - Strange floor anim = 1112 +9315 - Stepping stone anim = 3743 +9326 - Strange floor anim = 1112 +9353 - null anim = 2598 +9366 - Open hot vent door anim = 2598 +9367 - Hot vent door anim = 2598 +9368 - Hot vent door anim = 2598 +9369 - Hot vent door anim = 2598 +9375 - null anim = 523 +9376 - null anim = 2599 +9377 - Egg anim = 2600 +9378 - Egg anim = 2600 +9379 - Egg anim = 2600 +9390 - Lava forge anim = 2641 +9391 - Viewing orb anim = 2657 +9392 - null anim = 2657 +9439 - Fireplace anim = 477 +9442 - null anim = 477 +9508 - Hammock anim = 2699 +9515 - Betty's cauldron anim = 479 +9549 - Hot Coals anim = 2708 +9726 - Rocks anim = 523 +9727 - Rocks anim = 523 +9728 - Rocks anim = 523 +9729 - Rocks anim = 523 +9730 - Rocks anim = 523 +9731 - Rocks anim = 523 +9732 - Rocks anim = 523 +9733 - Rocks anim = 523 +9734 - Rocks anim = 523 +9735 - Rocks anim = 523 +9749 - Crystal collector anim = 2734 +9768 - Light door anim = 2746 +9769 - Light door anim = 2746 +9770 - Light door anim = 2746 +9771 - Light door anim = 2746 +9772 - Light door anim = 2746 +9773 - Light door anim = 2746 +9774 - Light door anim = 2746 +9775 - Light door anim = 2746 +9799 - null anim = 2747 +9800 - null anim = 2747 +9801 - null anim = 2747 +9802 - null anim = 2747 +9803 - null anim = 2747 +9804 - null anim = 2747 +9805 - null anim = 2747 +9806 - null anim = 2747 +9807 - null anim = 2747 +9808 - null anim = 2747 +9809 - null anim = 2747 +9810 - null anim = 2747 +9811 - null anim = 2747 +9812 - null anim = 2747 +9813 - null anim = 2742 +9814 - null anim = 2742 +9815 - null anim = 2742 +9816 - null anim = 2742 +9817 - null anim = 2742 +9818 - null anim = 2742 +9819 - null anim = 2742 +9992 - null anim = 2743 +10014 - Crystal anim = 2744 +10034 - Trap anim = 2209 +10041 - Tree anim = 2749 +10057 - Flagpole anim = 471 +10060 - null anim = 2768 +10087 - Ominous Fishing Spot anim = 447 +10088 - Ominous Fishing Spot anim = 447 +10089 - Ominous Fishing Spot anim = 447 +10091 - Aquarium anim = 447 +10104 - null anim = 2807 +10142 - Brewing control anim = 2807 +10143 - Brewing control anim = 2807 +10144 - Brewing control anim = 2807 +10169 - null anim = 480 +10178 - Standing Torch anim = 2870 +10179 - Standing Torch anim = 2870 +10185 - null anim = 481 +10186 - null anim = 2871 +10237 - null anim = 2871 +10251 - Portal anim = 2878 +10252 - Magic circle anim = 2883 +10292 - Rat trap anim = 2897 +10299 - Rat lever anim = 2899 +10300 - Rat barn anim = 2901 +10301 - Rat barrel anim = 2898 +10307 - Lantern anim = 2900 +10310 - Rat barrel anim = 2898 +10311 - Rat lever anim = 2899 +10312 - Rat barn anim = 2901 +10317 - Rat barrel anim = 2898 +10395 - null anim = 2905 +10398 - null anim = 2905 +10401 - null anim = 2905 +10403 - null anim = 2905 +10433 - Fire anim = 475 +10541 - Human Flag anim = 917 +10542 - Human Flag anim = 917 +10543 - Dwarf Flag anim = 917 +10544 - Dwarf Flag anim = 917 +10545 - Elf Flag anim = 917 +10546 - Elf Flag anim = 917 +10547 - Gnome Flag anim = 917 +10548 - Gnome Flag anim = 917 +10549 - Werewolf Flag anim = 917 +10550 - Werewolf Flag anim = 917 +10551 - TzHaar Flag anim = 917 +10552 - TzHaar Flag anim = 917 +10641 - Doric's Whetstone anim = 2997 +10715 - null anim = 3022 +10716 - null anim = 3022 +10717 - null anim = 3022 +10718 - null anim = 3022 +10738 - Statue anim = 3029 +10739 - Statue anim = 3029 +10761 - null anim = 3028 +10778 - Telekinetic Teleport anim = 3030 +10779 - Enchanters Teleport anim = 3030 +10780 - Alchemists Teleport anim = 3030 +10781 - Graveyard Teleport anim = 3030 +10782 - Exit Teleport anim = 3030 +10814 - Sandpit anim = 3038 +10820 - Energy Barrier anim = 1433 +10824 - Fireplace anim = 1629 +10825 - null anim = 1630 +10826 - null anim = 1630 +10875 - Stone block anim = 3070 +10877 - null anim = 3070 +10878 - null anim = 3070 +10879 - null anim = 3070 +10880 - null anim = 3070 +10881 - null anim = 3070 +10962 - Statue anim = 3099 +10963 - Statue anim = 3099 +10964 - Statue anim = 3099 +10965 - Statue anim = 3099 +10966 - Statue anim = 3100 +10967 - Statue anim = 3100 +10968 - Statue anim = 3100 +10969 - Statue anim = 3100 +11005 - Magic barrier anim = 3095 +11010 - Furnace anim = 3106 +11011 - null anim = 3105 +11012 - null anim = 3105 +11013 - null anim = 3105 +11014 - null anim = 3105 +11015 - null anim = 3107 +11016 - null anim = 3105 +11079 - Light anim = 3101 +11129 - null anim = 481 +11141 - Magic spell anim = 3097 +11143 - null anim = 481 +11158 - null anim = 3104 +11166 - Rocks anim = 523 +11167 - Rocks anim = 523 +11168 - Rocks anim = 523 +11169 - Rocks anim = 523 +11170 - Rocks anim = 523 +11171 - Rocks anim = 523 +11172 - Rocks anim = 523 +11173 - Rocks anim = 523 +11174 - Rocks anim = 523 +11175 - Rocks anim = 523 +11176 - Rocks anim = 523 +11177 - Rocks anim = 523 +11178 - Rocks anim = 523 +11179 - Rocks anim = 523 +11180 - Rocks anim = 523 +11181 - Rocks anim = 523 +11182 - Rocks anim = 523 +11192 - Rocks anim = 523 +11193 - Rocks anim = 523 +11194 - Rocks anim = 523 +11195 - Rocks anim = 523 +11208 - Coffin anim = 3113 +11221 - null anim = 464 +11222 - null anim = 464 +11223 - null anim = 464 +11224 - null anim = 464 +11225 - null anim = 464 +11226 - null anim = 464 +11317 - Ship hull anim = 464 +11318 - Ship hull anim = 464 +11354 - Interdimensional rift anim = 3174 +11355 - null anim = 3174 +11356 - Portal Home anim = 3174 +11357 - Portal machine anim = 3173 +11359 - null anim = 3174 +11361 - Raw chompy bird anim = 3180 +11362 - Raw Rabbit anim = 3180 +11363 - Iron spit anim = 3180 +11364 - Decorative Pillar anim = 3107 +11365 - Decorative Pillar anim = 3107 +11366 - Decorative Pillar anim = 3107 +11367 - Decorative Pillar anim = 3107 +11368 - null anim = 3107 +11369 - null anim = 3107 +11370 - null anim = 3107 +11371 - null anim = 3107 +11372 - null anim = 3107 +11373 - null anim = 3107 +11374 - null anim = 3107 +11375 - null anim = 3107 +11376 - null anim = 3107 +11377 - null anim = 3107 +11378 - null anim = 3107 +11397 - Pillar candle flame. anim = 3107 +11398 - Our lives anim = 4354 +11404 - Fire anim = 475 +11405 - Fire anim = 475 +11406 - Fire anim = 475 +11424 - Rocks anim = 523 +11425 - Rocks anim = 523 +11426 - Rocks anim = 523 +11427 - Rocks anim = 523 +11428 - Rocks anim = 523 +11429 - Rocks anim = 523 +11430 - Rocks anim = 523 +11431 - Rocks anim = 523 +11432 - Rocks anim = 523 +11433 - Rocks anim = 523 +11434 - Rocks anim = 523 +11435 - Rocks anim = 523 +11436 - Rocks anim = 523 +11437 - Rocks anim = 523 +11438 - Rocks anim = 523 +11439 - Rocks anim = 523 +11440 - Rocks anim = 523 +11441 - Rocks anim = 523 +11442 - Rocks anim = 523 +11443 - Rocks anim = 523 +11444 - Rocks anim = 523 +11468 - Lantern anim = 1868 +11469 - Spooky picture anim = 470 +11472 - Candles anim = 2564 +11473 - Candles anim = 2564 +11493 - Grandfather clock anim = 1726 +11495 - Gallows anim = 3217 +11496 - Chair anim = 3218 +11497 - Spooky picture anim = 3219 +11548 - Strange machine anim = 3172 +11549 - Strange machine anim = 3172 +11614 - Standard anim = 1730 +11615 - Standard anim = 1730 +11669 - null anim = 4860 +11677 - Treadmill anim = 3230 +11678 - Spinning pole anim = 3231 +11699 - Flagpole anim = 471 +11815 - null anim = 2900 +11816 - null anim = 3107 +11817 - null anim = 481 +11861 - Standard anim = 1730 +11875 - Canary anim = 3237 +11909 - null anim = 475 +11915 - Rocks anim = 523 +11916 - Rocks anim = 523 +11917 - Rocks anim = 523 +11918 - Rocks anim = 523 +11919 - Rocks anim = 523 +11920 - Rocks anim = 523 +11921 - Rocks anim = 523 +11922 - Rocks anim = 523 +11923 - Rocks anim = 523 +11924 - Rocks anim = 523 +11925 - Rocks anim = 523 +11926 - Rocks anim = 523 +11927 - Rocks anim = 523 +11928 - Rocks anim = 523 +11929 - Rocks anim = 523 +12066 - A fairy workbench anim = 3246 +12067 - A fairy workbench anim = 3247 +12093 - Chicken Shrine anim = 3264 +12101 - null anim = 4860 +12111 - Dairy Cow anim = 5855 +12114 - Cow wheel anim = 6094 +12145 - Canoe Station anim = 3304 +12151 - Canoe Station anim = 3304 +12152 - Canoe Station anim = 3304 +12153 - Canoe Station anim = 3304 +12154 - Canoe Station anim = 3304 +12159 - A Sinking Canoe anim = 3305 +12160 - A Sinking Canoe anim = 3305 +12161 - A Sinking Canoe anim = 3305 +12162 - A Sinking Canoe anim = 3305 +12168 - null anim = 3306 +12169 - null anim = 3306 +12170 - null anim = 3306 +12171 - null anim = 3306 +12203 - Light anim = 3101 +12256 - Nest anim = 3343 +12258 - Dragonfire anim = 3347 +12259 - Nest anim = 3343 +12260 - Portal anim = 3174 +12293 - Grandfather clock anim = 3511 +12300 - null anim = 3107 +12301 - Candles anim = 2564 +12302 - Candles anim = 2564 +12312 - Chair anim = 7263 +12313 - Chair anim = 7263 +12351 - Barrier anim = 3349 +12352 - Barrier anim = 3349 +12353 - Barrier anim = 3349 +12354 - null anim = 3351 +12355 - Portal anim = 3351 +12356 - Portal anim = 3351 +12357 - null anim = 3349 +12358 - null anim = 3349 +12359 - null anim = 3349 +12360 - null anim = 3349 +12361 - null anim = 3349 +12362 - null anim = 3349 +12363 - null anim = 3349 +12364 - null anim = 3349 +12365 - null anim = 3352 +12380 - null anim = 3408 +12400 - Cauldron anim = 3405 +12401 - Cauldron anim = 3406 +12402 - Explosion anim = 3407 +12477 - Kelp anim = 3438 +12519 - Coral anim = 3439 +12531 - Bubbles anim = 3440 +12532 - null anim = 3445 +12542 - null anim = 2900 +12551 - Old tree anim = 3459 +12556 - Rock and string anim = 3472 +12557 - Rock and string anim = 3472 +12594 - Snake anim = 3528 +12595 - Snake anim = 3534 +12596 - Snake anim = 3529 +12597 - Hole anim = 3530 +12598 - Snake anim = 3531 +12599 - Snake anim = 3532 +12600 - Snake anim = 3532 +12601 - Rope anim = 3101 +12605 - Light anim = 3101 +12608 - Red Banana Tree anim = 3478 +12654 - null anim = 523 +12701 - null anim = 3542 +12702 - null anim = 3542 +12703 - null anim = 3542 +12704 - null anim = 3542 +12785 - Bucket anim = 3558 +12795 - null anim = 475 +12805 - null anim = 3106 +12809 - Furnace anim = 3106 +12810 - null anim = 3104 +12811 - null anim = 3104 +12934 - null anim = 3107 +12969 - Cooking pot anim = 477 +13052 - null anim = 3107 +13053 - null anim = 3107 +13054 - null anim = 3107 +13113 - null anim = 4477 +13115 - Goblin crowd anim = 4564 +13145 - Magic barrier anim = 3586 +13169 - Clock anim = 3511 +13170 - Clock anim = 3511 +13171 - Clock anim = 3511 +13201 - Torch anim = 3105 +13203 - Torch anim = 3105 +13205 - Torch anim = 3107 +13207 - Torch anim = 3107 +13209 - Incense burner anim = 3573 +13211 - Incense burner anim = 3573 +13213 - Incense burner anim = 3573 +13215 - Bells anim = 3577 +13291 - Magic chest anim = 3117 +13292 - Magic chest anim = 3118 +13337 - Fire anim = 3105 +13341 - Torch anim = 3107 +13342 - Candle anim = 3107 +13343 - Skull anim = 3107 +13366 - Bones anim = 5483 +13367 - Guard dog anim = 6561 +13368 - Hobgoblin anim = 166 +13369 - Troll anim = 286 +13370 - Huge Spider anim = 145 +13373 - Rocnar anim = 3707 +13374 - Kalphite Soldier anim = 6218 +13375 - Steel dragon anim = 6496 +13376 - Dagannoth anim = 1338 +13377 - Tok-Xil anim = 2631 +13390 - Jacky Jester anim = 3587 +13395 - Elemental balance anim = 3582 +13396 - Elemental balance anim = 3582 +13397 - Elemental balance anim = 3582 +13405 - Portal anim = 3174 +13408 - Statue anim = 3647 +13480 - Ornamental fountain anim = 3647 +13528 - Firepit anim = 3105 +13529 - Firepit with hook anim = 3105 +13530 - Firepit with hook anim = 3105 +13531 - Firepit with pot anim = 3105 +13532 - Firepit with pot anim = 3105 +13533 - Small oven anim = 3105 +13534 - Small Oven anim = 3105 +13535 - Small oven anim = 3105 +13536 - Large oven anim = 3105 +13537 - Large oven anim = 3105 +13538 - Large oven anim = 3105 +13560 - Pump and drain anim = 3720 +13562 - Pump and tub anim = 3720 +13564 - Sink anim = 3720 +13610 - Clay fireplace anim = 3105 +13612 - Limestone fireplace anim = 3105 +13614 - Marble fireplace anim = 3105 +13615 - Varrock Portal anim = 3174 +13616 - Lumbridge Portal anim = 3174 +13617 - Falador Portal anim = 3174 +13618 - Camelot Portal anim = 3174 +13619 - Ardougne Portal anim = 3174 +13620 - Yanille Portal anim = 3174 +13621 - Kharyrll Portal anim = 3174 +13622 - Varrock Portal anim = 3174 +13623 - Lumbridge Portal anim = 3174 +13624 - Falador Portal anim = 3174 +13625 - Camelot Portal anim = 3174 +13626 - Ardougne Portal anim = 3174 +13627 - Yanille Portal anim = 3174 +13628 - Kharyrll Portal anim = 3174 +13629 - Varrock Portal anim = 3174 +13630 - Lumbridge Portal anim = 3174 +13631 - Falador Portal anim = 3174 +13632 - Camelot Portal anim = 3174 +13633 - Ardougne Portal anim = 3174 +13634 - Yanille Portal anim = 3174 +13635 - Kharyrll Portal anim = 3174 +13639 - Scrying pool anim = 3644 +13640 - Teleportation focus anim = 3646 +13641 - Greater teleport focus anim = 3648 +13654 - Small orrery anim = 3578 +13655 - Large orrery anim = 3579 +13660 - Elemental sphere anim = 3580 +13661 - Crystal of power anim = 3581 +13682 - Magic circle anim = 3615 +13683 - Greater magic circle anim = 3616 +13726 - Jacky Jester anim = 3587 +13841 - Row boat anim = 3742 +13842 - Ripples anim = 3743 +13858 - null anim = 493 +13859 - null anim = 493 +13860 - null anim = 493 +13880 - null anim = 476 +13881 - Fire anim = 476 +13925 - Hole anim = 3835 +14004 - null anim = 477 +14006 - Pot-boiler anim = 477 +14007 - Pot-boiler anim = 3105 +14008 - Pot-boiler anim = 3105 +14009 - Pot-boiler anim = 3105 +14035 - Fishing Contest Banner anim = 3843 +14172 - null anim = 475 +14174 - Driftwood anim = 3743 +14179 - Light anim = 3101 +14283 - Banner anim = 3927 +14310 - null anim = 3932 +14311 - null anim = 3932 +14312 - null anim = 3932 +14313 - null anim = 3932 +14360 - Cauldron anim = 3939 +14361 - null anim = 481 +14362 - Charms anim = 468 +14428 - Fishing spot anim = 525 +14434 - Gas bubble anim = 523 +14437 - null anim = 524 +14438 - null anim = 524 +14755 - Banner anim = 3940 +14756 - Banner anim = 3940 +14757 - Banner anim = 3940 +14814 - Rock anim = 3943 +14815 - Rock anim = 3943 +14816 - Rock anim = 3943 +14817 - Rock anim = 3943 +14825 - Obelisk anim = 3944 +14835 - Rocks anim = 523 +14836 - Rocks anim = 523 +14837 - Rocks anim = 523 +14838 - Rocks anim = 523 +14839 - Rocks anim = 523 +14840 - Rocks anim = 523 +14841 - Rocks anim = 523 +14842 - Rocks anim = 523 +14843 - Rocks anim = 523 +14844 - Rocks anim = 523 +14845 - Rocks anim = 523 +14846 - Rocks anim = 523 +14847 - Rocks anim = 523 +14848 - Rocks anim = 523 +14849 - Rocks anim = 523 +14883 - Rocks anim = 523 +14884 - Rocks anim = 523 +14885 - Rocks anim = 523 +14886 - Rocks anim = 523 +14887 - Rocks anim = 523 +14888 - Rocks anim = 523 +14889 - Rocks anim = 523 +14890 - Rocks anim = 523 +14955 - null anim = 3976 +14960 - Firebox anim = 3976 +14976 - Evil claw anim = 3998 +14996 - null anim = 3107 +15000 - Pinball Post anim = 4005 +15001 - Pinball Post anim = 4006 +15002 - Pinball Post anim = 4005 +15003 - Pinball Post anim = 4006 +15004 - Pinball Post anim = 4005 +15005 - Pinball Post anim = 4006 +15006 - Pinball Post anim = 4005 +15007 - Pinball Post anim = 4006 +15008 - Pinball Post anim = 4005 +15009 - Pinball Post anim = 4006 +15017 - null anim = 4015 +15018 - null anim = 4013 +15021 - null anim = 4014 +15156 - Fire anim = 475 +15159 - null anim = 475 +15161 - null anim = 481 +15206 - Fire remains anim = 475 +15207 - Fire remains anim = 475 +15208 - Fire remains anim = 475 +15209 - Fire remains anim = 475 +15210 - Fire remains anim = 475 +15214 - Steam Vent anim = 523 +15229 - Lift Engine anim = 4022 +15238 - null anim = 4022 +15253 - Rocks anim = 523 +15254 - Rocks anim = 523 +15255 - Rocks anim = 523 +15466 - Stone crusher anim = 3699 +15468 - Power saw anim = 3698 +15469 - Embalming tube anim = 3700 +15470 - null anim = 3700 +15477 - Portal anim = 3174 +15478 - Portal anim = 3174 +15479 - Portal anim = 3174 +15480 - Portal anim = 3174 +15481 - Portal anim = 3174 +15482 - Portal anim = 3174 +15486 - Pigeon anim = 4133 +15487 - Chimney anim = 4132 +15490 - Kalphite Queen anim = 6477 +15491 - Rocks anim = 523 +15492 - Rocks anim = 523 +15493 - Rocks anim = 523 +15506 - Wheat anim = 6470 +15508 - Wheat anim = 6470 +15538 - null anim = 4126 +15539 - null anim = 4126 +15547 - Clock anim = 3511 +15570 - Rocks anim = 523 +15571 - Rocks anim = 523 +15572 - Rocks anim = 523 +15573 - Rocks anim = 523 +15574 - Rocks anim = 523 +15575 - Rocks anim = 523 +15599 - Crate anim = 3206 +15600 - Crates anim = 3206 +15617 - Catapult anim = 4157 +15618 - Catapult anim = 4157 +15619 - Catapult anim = 4157 +15620 - Catapult anim = 4157 +15621 - Magical Animator anim = 4161 +15624 - Dummy anim = 4163 +15625 - Dummy anim = 4163 +15626 - Dummy anim = 4163 +15627 - Dummy anim = 4163 +15628 - Dummy anim = 4163 +15629 - Dummy anim = 4163 +15630 - Dummy anim = 4163 +15689 - null anim = 3107 +15709 - Zanik anim = 4220 +15710 - null anim = 4220 +15727 - Drip anim = 4217 +15728 - Drips anim = 4218 +15817 - Rock anim = 1727 +15818 - Small rock anim = 1727 +15819 - Rock anim = 1727 +15838 - Bamboo Pipes anim = 4239 +15839 - Bamboo Pipes anim = 4239 +15848 - Hopper anim = 4239 +15849 - Hopper anim = 4239 +15856 - Bridge anim = 4239 +15857 - Bridge anim = 4239 +15864 - Bamboo Pipes anim = 4239 +15865 - Bamboo Pipes anim = 4239 +15874 - Hopper anim = 4239 +15875 - Hopper anim = 4239 +15882 - Bridge anim = 4239 +15883 - Bridge anim = 4239 +15905 - Boiler anim = 4239 +15908 - Boiler anim = 4239 +15911 - Boiler anim = 4239 +15914 - Boiler anim = 4239 +15923 - Bottle machine anim = 4260 +15925 - Conveyor Belt anim = 4241 +15927 - Conveyor Belt anim = 4240 +15929 - Steam Pump anim = 4242 +15937 - Water Pump anim = 4239 +15941 - Red Flowers anim = 4239 +15942 - Blue Flowers anim = 4239 +15944 - Bridge anim = 4239 +15949 - Jungle Tree anim = 4239 +15952 - Jungle Tree anim = 4239 +15955 - Jungle Tree anim = 4239 +15962 - Bitternut Tree anim = 4247 +15963 - Bitternut Tree anim = 4247 +15964 - Bitternut Tree anim = 4246 +15965 - Bitternut Tree anim = 4246 +15966 - Bitternut Tree anim = 4245 +15967 - Bitternut Tree anim = 4245 +15968 - Bitternut Tree anim = 4244 +15969 - Bitternut Tree anim = 4244 +15996 - Portal anim = 3174 +16032 - null anim = 4274 +16042 - null anim = 523 +16043 - Portal of Death anim = 4284 +16044 - Portal of Death anim = 4284 +16050 - Portal anim = 504 +16065 - Rickety door anim = 4284 +16066 - Rickety door anim = 4284 +16082 - Portal anim = 504 +16089 - Oozing barrier anim = 4284 +16090 - Oozing barrier anim = 4284 +16109 - Stinking tendrils anim = 2173 +16110 - Dripping tendrils anim = 2173 +16111 - Tendrils anim = 2173 +16116 - Portal anim = 504 +16119 - null anim = 2379 +16123 - Gate of War anim = 4284 +16124 - Gate of War anim = 4284 +16136 - Rock anim = 1727 +16150 - Portal anim = 504 +16190 - Lightning anim = 4308 +16191 - Lightning anim = 4309 +16213 - Fairy workbench anim = 3246 +16215 - Fairy workbench anim = 3247 +16303 - Small rock anim = 1727 +16356 - null anim = 4323 +16357 - null anim = 4324 +16361 - null anim = 4325 +16362 - null anim = 4325 +16363 - null anim = 4325 +16469 - null anim = 481 +16476 - Tomb Door anim = 4338 +16483 - An anonymous looking door anim = 4339 +16484 - An anonymous looking door anim = 4339 +16485 - An anonymous looking door anim = 4339 +16486 - An anonymous looking door anim = 4339 +16487 - An anonymous looking door anim = 4339 +16488 - An anonymous looking door anim = 4339 +16489 - An anonymous looking door anim = 4339 +16490 - An anonymous looking door anim = 4339 +16491 - An anonymous looking door anim = 4339 +16492 - An anonymous looking door anim = 4339 +16493 - An anonymous looking door anim = 4339 +16494 - An anonymous looking door anim = 4339 +16495 - Sarcophagus anim = 4336 +16496 - Sarcophagus anim = 4336 +16497 - Sarcophagus anim = 4336 +16498 - Sarcophagus anim = 4336 +16499 - Sarcophagus anim = 4336 +16500 - Sarcophagus anim = 4336 +16501 - Urn anim = 4335 +16502 - Urn anim = 4335 +16503 - Urn anim = 4335 +16504 - Urn anim = 4335 +16505 - Urn anim = 4335 +16506 - Urn anim = 4335 +16507 - Urn anim = 4335 +16508 - Urn anim = 4335 +16509 - Urn anim = 4335 +16510 - Urn anim = 4335 +16511 - Urn anim = 4335 +16512 - Urn anim = 4335 +16513 - Urn anim = 4335 +16514 - Urn anim = 4335 +16515 - Urn anim = 4335 +16516 - Urn anim = 4335 +16517 - Speartrap anim = 459 +16538 - null anim = 4338 +16539 - null anim = 4338 +16540 - null anim = 4338 +16541 - null anim = 4338 +16542 - null anim = 4338 +16543 - null anim = 4338 +16544 - null anim = 4338 +16545 - null anim = 4338 +16546 - null anim = 4338 +16568 - Standard anim = 1730 +16569 - Standard anim = 1730 +16576 - Rocks anim = 523 +16577 - Rocks anim = 523 +16578 - Rocks anim = 523 +16579 - Rocks anim = 523 +16580 - Rocks anim = 523 +16581 - Rocks anim = 523 +16582 - Rocks anim = 523 +16583 - Rocks anim = 523 +16584 - Rocks anim = 523 +16599 - My life anim = 4354 +16600 - Hurdle anim = 4357 +16601 - Note anim = 4357 +16602 - Note anim = 4357 +16604 - Dream tree anim = 4355 +16619 - Zero anim = 4356 +16620 - One anim = 4356 +16621 - Two anim = 4356 +16622 - Three anim = 4356 +16623 - Four anim = 4356 +16624 - Five anim = 4356 +16625 - Six anim = 4356 +16626 - Seven anim = 4356 +16627 - Eight anim = 4356 +16628 - Nine anim = 4356 +16632 - Platform anim = 4358 +16633 - Platform anim = 4358 +16634 - Platform anim = 4358 +16635 - Platform anim = 4358 +16636 - Platform anim = 4358 +16637 - Platform anim = 4358 +16650 - null anim = 2871 +16661 - null anim = 481 +16662 - null anim = 2871 +16681 - null anim = 481 +16686 - Portal anim = 504 +16691 - Hat rack anim = 4393 +16692 - Hat rack anim = 4393 +16701 - Light anim = 4392 +16729 - Flowers anim = 4126 +16730 - Flowers anim = 4126 +16731 - Flowers anim = 4126 +16810 - Ceremonial Brazier anim = 4408 +16811 - Ceremonial Brazier anim = 4408 +16812 - Cooker anim = 4394 +16813 - Rack anim = 4395 +16814 - Stool anim = 4396 +16815 - Table anim = 4397 +16816 - null anim = 4398 +16827 - Table anim = 4377 +16828 - Table anim = 4377 +16830 - null anim = 4359 +16832 - null anim = 4359 +16834 - null anim = 4359 +16836 - null anim = 4359 +16838 - null anim = 4359 +16840 - null anim = 4359 +16842 - null anim = 4359 +16849 - Dice anim = 4361 +16850 - Dice anim = 4361 +16851 - Dice anim = 4361 +16852 - Dice anim = 4361 +16853 - Dice anim = 4361 +16854 - Dice anim = 4361 +16855 - Dice anim = 4360 +16856 - Dream puff anim = 4363 +16857 - Dream puff anim = 4364 +16859 - Hanging pirate anim = 4399 +16861 - Hammock anim = 4431 +16901 - Lantern anim = 1073 +17010 - Altar anim = 503 +17025 - null anim = 4408 +17116 - Pool of Slime anim = 493 +17117 - Pool of Slime anim = 493 +17118 - Pool of Slime anim = 493 +17130 - Office table anim = 4535 +17161 - Cauldron anim = 3939 +17162 - Cauldron anim = 3939 +17163 - null anim = 3939 +17196 - Goblin crowd anim = 4564 +17197 - Gnome crowd anim = 4565 +17198 - Gnome crowd anim = 4565 +17199 - Goblin crowd anim = 4566 +17200 - Goblin crowd anim = 4566 +17201 - Gnome crowd anim = 4567 +17202 - Gnome crowd anim = 4567 +17203 - Goblin crowd anim = 4568 +17204 - Goblin crowd anim = 4568 +17205 - Gnome crowd anim = 4569 +17206 - Gnome crowd anim = 4569 +17208 - null anim = 4577 +17235 - Table anim = 4557 +17236 - Hammock anim = 4431 +17237 - Torch anim = 3105 +17238 - Aspidistra plant anim = 4559 +17240 - Oaknock's machine anim = 4560 +17241 - Oaknock's machine anim = 4560 +17242 - Broken cogs anim = 4563 +17243 - Cogs anim = 4563 +17245 - Oaknock's Machine anim = 4561 +17246 - Oaknock's Machine anim = 4561 +17247 - Oaknock's Machine anim = 4561 +17248 - Oaknock's exchanger anim = 4562 +17249 - Oaknock's exchanger anim = 4562 +17274 - Argento anim = 4572 +17279 - Argento anim = 4571 +17280 - null anim = 4560 +17281 - null anim = 4563 +17282 - null anim = 4561 +17283 - null anim = 4562 +17324 - null anim = 4595 +17325 - Limestone fireplace anim = 3105 +17364 - Rock anim = 1727 +17365 - Small rock anim = 1727 +17366 - Rock anim = 1727 +17383 - Rocks anim = 523 +17384 - Rocks anim = 523 +17391 - Rocks anim = 523 +17434 - Wardrobe anim = 4599 +17436 - Stone table anim = 4621 +17437 - Stone table anim = 4622 +17455 - Crystal ball anim = 4627 +17461 - Ornate candle anim = 4628 +17509 - Waste pipes anim = 4746 +17511 - Waste pipes anim = 4747 +17627 - Washing Line anim = 4778 +17632 - null anim = 4744 +18075 - Wall anim = 4744 +18080 - Wall anim = 4745 +18102 - Falling door anim = 4744 +18128 - null anim = 4744 +18131 - null anim = 4745 +18134 - null anim = 4744 +18145 - Decorated wall anim = 4743 +18172 - Hammock anim = 4431 +18186 - Rowboat anim = 3743 +18187 - Rowboat anim = 3743 +18188 - null anim = 3743 +18242 - null anim = 4782 +18315 - null anim = 4126 +18323 - null anim = 4781 +18326 - Crane anim = 4798 +18348 - null anim = 3743 +18349 - null anim = 3743 +18350 - null anim = 3743 +18357 - Wreck anim = 4781 +18358 - null anim = 4783 +18366 - Crow nest anim = 4781 +18367 - Crate anim = 3743 +18368 - Crate anim = 3743 +18402 - null anim = 4781 +18403 - Kennith's ball anim = 3743 +18404 - Bottle anim = 3743 +18500 - null anim = 4860 +18511 - Water wheel anim = 1051 +18512 - Water wheel anim = 1051 +18513 - null anim = 522 +18514 - null anim = 522 +18524 - null anim = 4860 +18642 - Press support anim = 4894 +18652 - Door anim = 4879 +18653 - Door anim = 4880 +18654 - Door anim = 4881 +18655 - Door anim = 4879 +18656 - Door anim = 4880 +18657 - Door anim = 4881 +18658 - Door anim = 4879 +18659 - Door anim = 4880 +18661 - Water Tank anim = 4895 +18668 - Cog anim = 4896 +18672 - Cog anim = 4896 +18674 - Cog anim = 4896 +18677 - Cog anim = 4896 +18681 - Cog anim = 4896 +18683 - Cog anim = 4896 +18689 - null anim = 4899 +18690 - Extractor hat anim = 4883 +18694 - Extractor gun anim = 4897 +18695 - Extractor gun anim = 4897 +18723 - null anim = 4898 +18725 - null anim = 4900 +18760 - Tunnel wall anim = 4901 +18841 - Dolphin anim = 5012 +18842 - Fish anim = 5012 +18844 - null anim = 1881 +18875 - Cactus anim = 5055 +18960 - Cart Camel anim = 5044 +18967 - Rocks anim = 523 +18968 - Rocks anim = 523 +18969 - Rocks anim = 523 +18970 - Rocks anim = 523 +18971 - Rocks anim = 523 +18972 - Rocks anim = 523 +18973 - Rocks anim = 523 +18974 - Rocks anim = 523 +18975 - Rocks anim = 523 +18976 - Rocks anim = 523 +18977 - Rocks anim = 523 +18978 - Rocks anim = 523 +18979 - Rocks anim = 523 +18980 - Rocks anim = 523 +18981 - Rocks anim = 523 +18982 - Rocks anim = 523 +18983 - Rocks anim = 523 +18984 - Rocks anim = 523 +18985 - Rocks anim = 523 +18986 - Rocks anim = 523 +18987 - Rocks anim = 523 +18988 - Rocks anim = 523 +18989 - Rocks anim = 523 +18990 - Rocks anim = 523 +19037 - Cage with gublinch anim = 5073 +19038 - Wintumber tree anim = 5058 +19126 - Plank anim = 3743 +19127 - Candles anim = 2564 +19128 - Basket anim = 5141 +19129 - Basket anim = 5141 +19130 - Air balloon anim = 5141 +19133 - null anim = 5141 +19134 - null anim = 5141 +19135 - null anim = 5141 +19136 - null anim = 5141 +19137 - null anim = 5141 +19138 - null anim = 5141 +19139 - null anim = 5141 +19140 - null anim = 5141 +19141 - null anim = 5141 +19142 - null anim = 5141 +19143 - null anim = 5141 +19144 - null anim = 5141 +19156 - Basket anim = 5109 +19164 - Basket anim = 5109 +19172 - Raw bird anim = 3180 +19173 - Raw hunting beast anim = 3180 +19174 - Bird snare anim = 5170 +19176 - Bird snare anim = 5169 +19177 - Bird snare anim = 5173 +19178 - Bird snare anim = 5174 +19179 - Bird snare anim = 5173 +19180 - Bird snare anim = 5174 +19181 - Bird snare anim = 5173 +19182 - Bird snare anim = 5174 +19183 - Bird snare anim = 5173 +19184 - Bird snare anim = 5174 +19185 - Bird snare anim = 5173 +19186 - Bird snare anim = 5174 +19188 - Box trap anim = 5175 +19189 - Shaking box anim = 5179 +19190 - Shaking box anim = 5179 +19191 - Shaking box anim = 5179 +19192 - Box trap anim = 5180 +19193 - Box trap anim = 5175 +19194 - Box trap anim = 5176 +19195 - Box trap anim = 5177 +19196 - Box trap anim = 5178 +19197 - Box trap anim = 5175 +19198 - Box trap anim = 5176 +19199 - Box trap anim = 5177 +19200 - Box trap anim = 5178 +19201 - Box trap anim = 5175 +19202 - Box trap anim = 5176 +19203 - Box trap anim = 5177 +19204 - Box trap anim = 5178 +19205 - Boulder anim = 5197 +19206 - Deadfall anim = 5193 +19207 - Deadfall anim = 5195 +19208 - Deadfall anim = 5196 +19209 - Deadfall anim = 5195 +19210 - Deadfall anim = 5196 +19211 - Deadfall anim = 5195 +19212 - Deadfall anim = 5196 +19213 - Deadfall anim = 5195 +19214 - Deadfall anim = 5196 +19215 - Boulder anim = 5197 +19216 - Boulder anim = 5197 +19217 - Boulder anim = 5197 +19218 - Boulder anim = 5197 +19219 - Deadfall anim = 5194 +19221 - Occupied perch anim = 5203 +19223 - Magic box anim = 5220 +19224 - Magic box failed anim = 5219 +19225 - Magic box anim = 5222 +19226 - Magic box anim = 5221 +19253 - null anim = 5235 +19254 - null anim = 5235 +19255 - null anim = 5235 +19256 - null anim = 5235 +19257 - null anim = 5235 +19258 - null anim = 5235 +19259 - null anim = 5235 +19260 - null anim = 5235 +19261 - null anim = 5235 +19262 - null anim = 5235 +19263 - null anim = 5235 +19264 - null anim = 5235 +19265 - null anim = 5235 +19266 - null anim = 5235 +19267 - null anim = 5235 +19268 - null anim = 5235 +19334 - Broken snare anim = 5237 +19335 - Rabbit snare anim = 5239 +19336 - Rabbit snare anim = 5239 +19441 - null anim = 5260 +19442 - null anim = 5260 +19443 - null anim = 5260 +19444 - null anim = 5260 +19445 - null anim = 5260 +19446 - null anim = 5260 +19447 - null anim = 5260 +19448 - null anim = 5260 +19449 - null anim = 5260 +19450 - null anim = 5260 +19451 - null anim = 5260 +19452 - null anim = 5260 +19453 - null anim = 5260 +19454 - null anim = 5260 +19455 - null anim = 5260 +19456 - null anim = 5260 +19457 - null anim = 5260 +19458 - null anim = 5260 +19459 - null anim = 5260 +19460 - null anim = 5260 +19461 - null anim = 5260 +19462 - null anim = 5260 +19463 - null anim = 5260 +19464 - null anim = 5260 +19465 - null anim = 5260 +19466 - null anim = 5260 +19467 - null anim = 5260 +19468 - null anim = 5260 +19469 - null anim = 5260 +19470 - null anim = 5260 +19471 - null anim = 5260 +19472 - null anim = 5260 +19473 - null anim = 5260 +19474 - null anim = 5260 +19475 - null anim = 5260 +19476 - null anim = 5260 +19477 - null anim = 5260 +19478 - null anim = 5260 +19479 - null anim = 5260 +19480 - null anim = 5260 +19481 - null anim = 5260 +19482 - null anim = 5260 +19483 - null anim = 5260 +19484 - null anim = 5260 +19485 - null anim = 5260 +19486 - null anim = 5261 +19487 - null anim = 5261 +19488 - null anim = 5260 +19489 - null anim = 5260 +19490 - null anim = 5261 +19491 - null anim = 5261 +19495 - null anim = 5260 +19496 - null anim = 5260 +19497 - null anim = 5260 +19498 - null anim = 5260 +19499 - null anim = 5260 +19500 - null anim = 5260 +19501 - null anim = 5260 +19502 - null anim = 5260 +19503 - null anim = 5260 +19505 - null anim = 5260 +19506 - null anim = 5260 +19508 - null anim = 5260 +19509 - null anim = 5260 +19511 - null anim = 5260 +19512 - null anim = 5260 +19514 - null anim = 5260 +19515 - null anim = 5260 +19517 - null anim = 5260 +19518 - null anim = 5260 +19520 - null anim = 5260 +19521 - null anim = 5260 +19523 - null anim = 5260 +19524 - null anim = 5260 +19526 - null anim = 5260 +19527 - null anim = 5260 +19529 - null anim = 5260 +19530 - null anim = 5260 +19532 - null anim = 5260 +19533 - null anim = 5260 +19535 - null anim = 5260 +19536 - null anim = 5260 +19538 - null anim = 5260 +19539 - null anim = 5260 +19541 - null anim = 5260 +19542 - null anim = 5260 +19544 - null anim = 5260 +19545 - null anim = 5260 +19547 - null anim = 5260 +19548 - null anim = 5260 +19550 - null anim = 5260 +19551 - null anim = 5260 +19554 - null anim = 5260 +19555 - null anim = 5260 +19556 - null anim = 5260 +19557 - null anim = 5260 +19558 - null anim = 5260 +19559 - null anim = 5260 +19560 - null anim = 5260 +19561 - null anim = 5260 +19562 - null anim = 5260 +19564 - null anim = 5260 +19565 - null anim = 5260 +19567 - null anim = 5260 +19568 - null anim = 5260 +19570 - null anim = 5260 +19571 - null anim = 5260 +19573 - null anim = 5260 +19574 - null anim = 5260 +19576 - null anim = 5260 +19577 - null anim = 5260 +19579 - null anim = 5260 +19580 - null anim = 5260 +19582 - null anim = 5260 +19583 - null anim = 5260 +19585 - null anim = 5260 +19586 - null anim = 5260 +19588 - null anim = 5260 +19589 - null anim = 5260 +19591 - null anim = 5260 +19592 - null anim = 5260 +19642 - null anim = 5260 +19643 - null anim = 5260 +19644 - null anim = 5261 +19645 - null anim = 5261 +19646 - null anim = 5260 +19647 - null anim = 5260 +19648 - null anim = 5261 +19649 - null anim = 5261 +19650 - Young tree anim = 5267 +19654 - Net trap anim = 5269 +19655 - Net trap anim = 5268 +19656 - Net trap anim = 5271 +19657 - Net trap anim = 5270 +19658 - Net trap anim = 5268 +19659 - Net trap anim = 5269 +19660 - Net trap anim = 5270 +19661 - Net trap anim = 5271 +19662 - Young tree anim = 5267 +19666 - Net trap anim = 5268 +19667 - Net trap anim = 5269 +19668 - Net trap anim = 5270 +19669 - Net trap anim = 5271 +19670 - Young tree anim = 5267 +19674 - Net trap anim = 5268 +19675 - Net trap anim = 5269 +19676 - Net trap anim = 5270 +19677 - Net trap anim = 5271 +19678 - Young tree anim = 5267 +19686 - null anim = 5278 +19687 - null anim = 5278 +19688 - null anim = 5278 +19689 - null anim = 5278 +19785 - null anim = 475 +19786 - null anim = 475 +19851 - Boulder anim = 5197 +19881 - Campfire anim = 475 +19882 - null anim = 475 +19883 - null anim = 475 +19884 - Campfire anim = 475 +19936 - Bird feeder anim = 5308 +19937 - Bird feeder anim = 5308 +19938 - Bird feeder anim = 5308 +19939 - Bird feeder anim = 5308 +19940 - Bird feeder anim = 5308 +19941 - Bird feeder anim = 5308 +19942 - Bird feeder anim = 5308 +19943 - Bird feeder anim = 5308 +19944 - Bird feeder anim = 5308 +19951 - null anim = 5260 +19952 - null anim = 5260 +19953 - null anim = 5260 +19981 - Pedestal anim = 5295 +19982 - Pedestal anim = 5296 +19983 - Pedestal anim = 5297 +20000 - Fire anim = 475 +20001 - Fire anim = 475 +20022 - Pillar anim = 5350 +20023 - Pillar anim = 5350 +20024 - Pillar anim = 5350 +20026 - Pillar anim = 5350 +20027 - Pillar anim = 5350 +20028 - Pillar anim = 5350 +20030 - Pillar anim = 5350 +20031 - Pillar anim = 5350 +20032 - Pillar anim = 5350 +20034 - Pillar anim = 5350 +20035 - Pillar anim = 5350 +20036 - Pillar anim = 5350 +20040 - Machine anim = 5351 +20066 - null anim = 5360 +20067 - null anim = 5360 +20068 - null anim = 5360 +20069 - null anim = 5360 +20070 - null anim = 5360 +20071 - null anim = 5360 +20072 - null anim = 5360 +20073 - null anim = 5360 +20074 - null anim = 5360 +20075 - null anim = 5360 +20076 - null anim = 5360 +20077 - null anim = 5360 +20078 - null anim = 5360 +20079 - null anim = 5360 +20080 - null anim = 5360 +20081 - null anim = 5360 +20082 - null anim = 5360 +20083 - null anim = 5360 +20100 - Childerkin slaves anim = 5068 +20117 - Childerkin slaves anim = 5068 +20119 - null anim = 5073 +20120 - null anim = 5073 +20121 - null anim = 5073 +20122 - null anim = 5073 +20123 - null anim = 5073 +20124 - null anim = 5073 +20125 - null anim = 5073 +20126 - null anim = 5073 +20127 - null anim = 5073 +20128 - null anim = 5073 +20133 - Egg launcher anim = 5430 +20199 - Door anim = 1433 +20200 - Door anim = 1433 +20201 - Door anim = 1433 +20202 - Door anim = 1433 +20203 - Door anim = 1433 +20204 - Door anim = 1433 +20205 - Door anim = 1433 +20206 - Door anim = 1433 +20207 - Door anim = 1433 +20208 - Door anim = 1433 +20209 - Door anim = 1433 +20232 - Lava crater anim = 5415 +20233 - Poison crater anim = 5415 +20234 - Lava crater anim = 5415 +20235 - Poison crater anim = 5415 +20246 - null anim = 5422 +20247 - Horn of glory anim = 5423 +20248 - Horn of glory anim = 5423 +20259 - Egg launcher anim = 5429 +20260 - Hopper anim = 5431 +20261 - Hopper anim = 5431 +20262 - Hopper anim = 5431 +20263 - Egg launcher anim = 5430 +20264 - Egg hopper anim = 5432 +20265 - Egg hopper anim = 5432 +20266 - Egg hopper anim = 5432 +20271 - Floor anim = 1112 +20273 - Speartrap anim = 459 +20453 - Armour anim = 5603 +20455 - Skeleton anim = 5603 +20457 - Skeleton anim = 5603 +20468 - Passageway anim = 5599 +20469 - Passageway anim = 5601 +20510 - Crate anim = 3743 +20511 - Barrel anim = 3743 +20532 - Bars anim = 5599 +20533 - Bars anim = 5600 +20534 - Bars anim = 5601 +20537 - null anim = 5598 +20538 - null anim = 5598 +20580 - null anim = 5605 +20621 - null anim = 5598 +20622 - null anim = 5598 +20660 - null anim = 5605 +20686 - null anim = 5598 +20687 - null anim = 5598 +20725 - null anim = 5605 +20751 - null anim = 5598 +20752 - null anim = 5598 +20790 - null anim = 5605 +20915 - Floor anim = 1112 +20916 - Floor anim = 1112 +20917 - Floor anim = 1112 +20918 - Floor anim = 1112 +20919 - Floor anim = 1112 +20942 - Wall anim = 5631 +20943 - Wall anim = 5631 +20946 - Wall anim = 5631 +20947 - Wall anim = 5631 +20950 - Wall anim = 5631 +20951 - Wall anim = 5631 +20954 - Wall anim = 5631 +20955 - Wall anim = 5631 +20972 - null anim = 5603 +20973 - null anim = 5603 +20974 - null anim = 5604 +20975 - null anim = 5604 +20976 - null anim = 5604 +20985 - Mummy anim = 5564 +20986 - Mummy anim = 5564 +20995 - Golf-cart anim = 5740 +20996 - Table anim = 5742 +21001 - Interrogation chair anim = 5740 +21002 - Steam generator anim = 5737 +21003 - null anim = 5745 +21008 - Drill anim = 5743 +21009 - Lathe anim = 5744 +21085 - Spinning light anim = 5738 +21089 - null anim = 5728 +21090 - null anim = 5730 +21091 - null anim = 5729 +21092 - Crazy penguin anim = 5728 +21093 - Crazy penguin anim = 5730 +21094 - Crazy penguin anim = 5729 +21099 - null anim = 3743 +21100 - null anim = 3743 +21101 - null anim = 3743 +21108 - null anim = 5739 +21109 - null anim = 5739 +21110 - null anim = 3743 +21111 - null anim = 3743 +21120 - Stepping Stone anim = 3743 +21121 - Stepping Stone anim = 3743 +21122 - Stepping Stone anim = 3743 +21123 - Stepping Stone anim = 3743 +21124 - Stepping Stone anim = 3743 +21146 - null anim = 5741 +21148 - Ice anim = 5734 +21149 - Ice anim = 5734 +21150 - Ice anim = 5734 +21151 - Ice anim = 5734 +21152 - Ice anim = 5734 +21153 - Ice anim = 5734 +21154 - Ice anim = 5734 +21155 - Ice anim = 5734 +21156 - Ice anim = 5734 +21176 - Boat anim = 3742 +21177 - Boat anim = 3742 +21251 - Rocks anim = 523 +21252 - Rocks anim = 523 +21253 - Rocks anim = 523 +21254 - Rocks anim = 523 +21255 - Rocks anim = 523 +21256 - Rocks anim = 523 +21257 - Rocks anim = 523 +21258 - Rocks anim = 523 +21259 - Rocks anim = 523 +21260 - Rocks anim = 523 +21261 - Rocks anim = 523 +21262 - Rocks anim = 523 +21263 - Rocks anim = 523 +21264 - Rocks anim = 523 +21265 - Rocks anim = 523 +21266 - Rocks anim = 523 +21267 - Rocks anim = 523 +21268 - Rocks anim = 523 +21269 - Rocks anim = 523 +21270 - Rocks anim = 523 +21271 - Funeral Pyre anim = 1304 +21273 - Arctic Pine anim = 5773 +21355 - Large Geyser anim = 5771 +21356 - Small Geyser anim = 5772 +21500 - Banner anim = 5768 +21501 - Banner anim = 5768 +21571 - Rock anim = 1727 +21572 - Small rock anim = 1727 +21573 - Rock anim = 1727 +21620 - Fire anim = 475 +21634 - Fremennik boat anim = 3743 +21635 - Standard anim = 1730 +21636 - Standard anim = 1730 +21637 - Standard anim = 1730 +21638 - null anim = 1730 +21764 - Fountain anim = 5797 +21795 - Fireplace anim = 5798 +21832 - null anim = 5828 +21844 - Water pipes anim = 5829 +21846 - Water pipes anim = 5829 +21852 - null anim = 5830 +21856 - null anim = 5830 +21860 - null anim = 5830 +21864 - null anim = 5830 +21893 - Symbol of life anim = 5844 +21894 - Symbol of life anim = 5844 +21918 - Magic table anim = 5824 +21920 - Spinning pipe anim = 5825 +21930 - Cage anim = 5847 +21931 - Cage anim = 5847 +21942 - null anim = 4860 +21945 - Lighting mechanism anim = 1348 +22105 - Wall anim = 5900 +22106 - Wall anim = 5900 +22107 - Wall anim = 5901 +22108 - Wall anim = 5901 +22109 - Collapsed wall anim = 5900 +22110 - Collapsed wall anim = 5901 +22123 - Stand anim = 5906 +22124 - Stand anim = 5906 +22125 - Candle stand anim = 5906 +22155 - Clock anim = 3511 +22338 - null anim = 5874 +22339 - null anim = 5874 +22347 - null anim = 1727 +22348 - null anim = 1727 +22349 - null anim = 1727 +22418 - Sails anim = 5857 +22419 - Millstones anim = 1731 +22423 - null anim = 1731 +22425 - null anim = 472 +22484 - Fuse anim = 5909 +22497 - Marv (sick) anim = 5975 +22498 - Marv (very sick) anim = 5976 +22499 - Marv (ghastly!) anim = 5977 +22500 - Marv (sick) anim = 5983 +22501 - Marv (very sick) anim = 5984 +22502 - Marv (ghastly!) anim = 5985 +22503 - Marv (Well) anim = 5974 +22504 - Hank (sick) anim = 5975 +22505 - Hank (very sick) anim = 5976 +22506 - Hank (ghastly!) anim = 5977 +22507 - Hank (sick) anim = 5983 +22508 - Hank (very sick) anim = 5984 +22509 - Hank (ghastly!) anim = 5985 +22510 - Hank (Well) anim = 5983 +22511 - Wilf (sick) anim = 5975 +22512 - Wilf (very sick) anim = 5976 +22513 - Wilf (ghastly!) anim = 5977 +22514 - Wilf (sick) anim = 5983 +22515 - Wilf (very sick) anim = 5984 +22516 - Wilf (ghastly!) anim = 5985 +22517 - Wilf (Well) anim = 5974 +22518 - Sarah (sick!) anim = 5975 +22519 - Sarah (very sick!) anim = 5976 +22520 - Sarah (ghastly!) anim = 5977 +22521 - Sarah (sick!) anim = 5983 +22522 - Sarah (very sick!) anim = 5984 +22523 - Sarah (ghastly!) anim = 5985 +22524 - Sarah (Well) anim = 5974 +22525 - Rachel (sick) anim = 5975 +22526 - Rachel (very sick) anim = 5976 +22527 - Rachel (ghastly!) anim = 5977 +22528 - Rachel (sick) anim = 5983 +22529 - Rachel (very sick) anim = 5984 +22530 - Rachel (ghastly!) anim = 5985 +22531 - Rachel (Well) anim = 5974 +22545 - Molanisk anim = 6015 +22663 - Pylon anim = 6069 +22715 - Sink anim = 6037 +22727 - Chimney anim = 6038 +22728 - Wire machine anim = 6038 +22729 - Wire machine anim = 6038 +22730 - Wire anim = 6038 +22732 - Cogs anim = 6038 +22733 - Smoke anim = 5745 +22734 - Moths anim = 6036 +22735 - Zapper anim = 6035 +22736 - Zapper anim = 6035 +22737 - Zapper anim = 6034 +22760 - Lamp anim = 6029 +22761 - Lamp anim = 6029 +22762 - Lamp anim = 6029 +22763 - Empty lamp anim = 6031 +22764 - Lamp anim = 6032 +22823 - Thingymajig anim = 6027 +22826 - Magic ball anim = 6028 +22862 - Water anim = 6024 +22863 - Water anim = 6024 +22864 - Water anim = 6024 +22865 - Water anim = 6024 +22875 - null anim = 6025 +22943 - Stairs anim = 6026 +22973 - Fountain anim = 6023 +22974 - Frog spit anim = 6039 +22975 - Smoke anim = 5745 +22976 - Lamp anim = 6029 +22977 - Broken lamp anim = 6029 +22978 - null anim = 6029 +22979 - null anim = 6029 +22980 - null anim = 6029 +22981 - null anim = 6029 +22982 - null anim = 6029 +22983 - null anim = 6029 +22984 - null anim = 6029 +22985 - null anim = 6029 +22986 - null anim = 6029 +22987 - null anim = 6029 +22988 - null anim = 6029 +22989 - null anim = 6029 +22990 - null anim = 6029 +22991 - null anim = 6029 +22992 - null anim = 6029 +22993 - null anim = 6029 +22994 - null anim = 6029 +22995 - null anim = 6029 +22996 - null anim = 6029 +22997 - null anim = 6029 +22998 - null anim = 6029 +22999 - null anim = 6029 +23000 - null anim = 6029 +23001 - null anim = 6029 +23002 - null anim = 6029 +23003 - null anim = 6029 +23004 - null anim = 6029 +23005 - null anim = 6029 +23006 - null anim = 6029 +23007 - null anim = 6029 +23008 - null anim = 6029 +23009 - null anim = 6029 +23010 - null anim = 6029 +23011 - null anim = 6029 +23012 - null anim = 6029 +23013 - null anim = 6029 +23014 - null anim = 6029 +23015 - null anim = 6029 +23016 - null anim = 6029 +23017 - null anim = 6029 +23018 - null anim = 6029 +23019 - null anim = 6029 +23020 - null anim = 6029 +23021 - null anim = 6029 +23022 - null anim = 6029 +23023 - null anim = 6029 +23024 - null anim = 6029 +23025 - null anim = 6029 +23026 - null anim = 6029 +23027 - null anim = 6029 +23028 - null anim = 6029 +23029 - null anim = 6029 +23030 - null anim = 6029 +23031 - null anim = 6029 +23032 - null anim = 6029 +23033 - null anim = 6029 +23034 - null anim = 6029 +23035 - null anim = 6029 +23036 - null anim = 6029 +23037 - null anim = 6029 +23038 - null anim = 6029 +23039 - null anim = 6029 +23040 - null anim = 6029 +23041 - null anim = 6029 +23046 - Fire anim = 3105 +23063 - Camp fire anim = 475 +23093 - Portal anim = 504 +23094 - Floor anim = 504 +23095 - Portal anim = 504 +23098 - null anim = 504 +23118 - Warren exit anim = 3101 +23145 - null anim = 3101 +23165 - Rock anim = 1727 +23172 - Drip anim = 4217 +23173 - Drips anim = 4218 +23215 - null anim = 6123 +23284 - Zanik anim = 6211 +23306 - Goblin crowd anim = 6161 +23307 - Goblin crowd anim = 6162 +23308 - Goblin crowd anim = 6163 +23309 - Goblin crowd anim = 6161 +23310 - Goblin crowd anim = 6162 +23311 - Goblin crowd anim = 6163 +23312 - Goblin crowd anim = 6161 +23313 - Goblin crowd anim = 6162 +23314 - Goblin crowd anim = 6163 +23315 - Crowd of dwarves anim = 6164 +23316 - Crowd of dwarves anim = 6165 +23317 - Crowd of dwarves anim = 6166 +23318 - Council members anim = 6167 +23319 - Cave gobins anim = 6168 +23380 - null anim = 3107 +23492 - null anim = 6170 +23507 - null anim = 1868 +23514 - null anim = 1868 +23526 - Sample table anim = 6196 +23527 - Sample table anim = 6196 +23551 - Chest anim = 2709 +23552 - Chest anim = 2709 +23553 - null anim = 464 +23554 - Rocks anim = 523 +23555 - Rocks anim = 523 +23556 - Rocks anim = 523 +23557 - Rocks anim = 523 +23558 - Rocks anim = 523 +23559 - Rocks anim = 523 +23591 - Kalphite queen legs anim = 6269 +23611 - Cocoon anim = 6274 +23921 - Dummy anim = 6481 +23961 - Lathe anim = 5744 +23962 - Drill anim = 5743 +23963 - Hearth anim = 4130 +23967 - Sign anim = 4128 +23968 - Sign anim = 4128 +23969 - Sign anim = 4128 +23970 - Sign anim = 4128 +23971 - null anim = 4128 +23972 - Sign anim = 4128 +23973 - null anim = 4128 +23974 - Sign anim = 4128 +23975 - null anim = 4128 +23976 - null anim = 4128 +23977 - Sign anim = 4128 +23978 - Sign anim = 4128 +23979 - null anim = 4131 +23980 - Sign anim = 4129 +23981 - null anim = 4128 +23982 - Sign anim = 4128 +24017 - null anim = 6491 +24025 - Lamp anim = 1868 +24026 - Lantern anim = 4127 +24033 - Oil lamp anim = 4125 +24065 - Sails anim = 6495 +24067 - Mill anim = 6493 +24068 - Mill anim = 6494 +24094 - Swings anim = 6466 +24095 - Washing line anim = 6467 +24161 - Fountain anim = 6023 +24170 - Washing Line anim = 4778 +24172 - Washing Line anim = 4778 +24194 - Smoking vent anim = 4132 +24195 - Smoking vent anim = 4132 +24265 - Fountain anim = 6492 +24285 - Fireplace anim = 3105 +24313 - Oven anim = 3105 +24328 - Cooking pot anim = 4124 +24329 - Fireplace anim = 4124 +24348 - Candles anim = 2564 +24414 - null anim = 4125 +24417 - null anim = 6426 +24418 - null anim = 6426 +24552 - null anim = 6461 +24553 - null anim = 6461 +24554 - null anim = 6461 +24569 - Snake anim = 6453 +24570 - null anim = 6439 +24677 - Charms anim = 468 +24724 - Gramophone anim = 6522 +24725 - Gramophone anim = 6522 +24726 - Gramophone anim = 6522 +24727 - Gramophone anim = 6522 +24732 - Beanstalk anim = 6497 +24734 - Beanstalk anim = 6499 +24736 - Beanstalk anim = 6500 +24771 - Rupert anim = 6509 +24773 - null anim = 6509 +24774 - null anim = 6509 +24839 - Grimgnash anim = 6506 +24840 - null anim = 6506 +24843 - Floor anim = 6523 +24844 - Floor anim = 6523 +24845 - Floor anim = 6523 +24846 - Floor anim = 6523 +24847 - Floor anim = 6523 +24882 - null anim = 6522 +24984 - Crop circle anim = 6623 +24985 - Crop circle anim = 6624 +24986 - Crop circle anim = 6625 +24987 - Crop circle anim = 6626 +24988 - Centre of crop circle anim = 6627 +24989 - Magic wheat anim = 6623 +24990 - Magic wheat anim = 6625 +24991 - Centre of crop circle anim = 6627 +25022 - Growing wheat anim = 6597 +25023 - Wilting wheat anim = 6598 +25115 - Magic door anim = 6635 +25116 - Magic door anim = 6637 +25118 - Magic door anim = 6636 +25122 - Candle stand anim = 6638 +25123 - Candle stand anim = 6638 +25136 - Vines anim = 6639 +25155 - Fire anim = 6645 +25156 - Fire anim = 6646 +25157 - Jenkins anim = 6652 +25201 - Flames anim = 6653 +25205 - A flag anim = 6656 +25216 - Aged log anim = 3306 +25267 - funeral pyre anim = 3105 +25274 - Whirlpool anim = 6737 +25275 - Whirlpool anim = 6737 +25276 - Mighty torrent anim = 6732 +25277 - Mighty torrent anim = 6732 +25278 - Mighty torrent anim = 6732 +25279 - Mighty torrent anim = 6732 +25280 - null anim = 6731 +25281 - null anim = 6731 +25282 - null anim = 6731 +25283 - null anim = 6731 +25284 - null anim = 6731 +25285 - null anim = 6731 +25292 - Pyre boat anim = 6733 +25293 - Pyre boat anim = 6734 +25294 - Pyre boat anim = 6735 +25295 - Pyre boat anim = 6736 +25374 - campfire anim = 3105 +25401 - Orrery anim = 3579 +25426 - Rocking unicorn anim = 6854 +25440 - Goblin stove anim = 3105 +25441 - Goblin stove anim = 3105 +25442 - null anim = 3105 +25465 - Fire anim = 6853 +25590 - Rat wheel anim = 3230 +25620 - Novice Flag anim = 6873 +25621 - Intermediate Flag anim = 6873 +25622 - Veteran Flag anim = 6874 +25623 - Novice flag anim = 6874 +25624 - Intermediate Flag anim = 6874 +25625 - Veteran Flag anim = 6874 +25626 - null anim = 6875 +25627 - null anim = 6875 +25628 - null anim = 6875 +25634 - null anim = 6874 +25635 - null anim = 6875 +25648 - Dummy anim = 6481 +25654 - Charms anim = 468 +25659 - null anim = 5598 +25664 - Sir Lucan anim = 6912 +25665 - Sir Palomedes anim = 6913 +25666 - Sir Lancelot anim = 6914 +25667 - Sir Bedivere anim = 6915 +25731 - Grandfather clock anim = 1726 +25762 - Sign anim = 4128 +25763 - Clock anim = 3511 +25889 - Sir Tristram anim = 6925 +25944 - The jury anim = 6900 +25945 - The jury anim = 6901 +25946 - The jury anim = 6902 +25947 - The jury anim = 6903 +25955 - Alan anim = 6917 +25956 - Court judge anim = 6898 +26045 - Citizen anim = 6890 +26046 - Citizen anim = 6891 +26047 - Citizen anim = 6892 +26048 - Citizen anim = 6893 +26049 - Citizen anim = 6894 +26050 - Citizen anim = 6895 +26137 - Fly paper anim = 6931 +26192 - null anim = 478 +26205 - Present anim = 6932 +26291 - Big hole anim = 6982 +26302 - Pillar anim = 6069 +26410 - null anim = 3743 +26411 - null anim = 3743 +26412 - null anim = 3743 +26413 - null anim = 3743 +26414 - Large geyser anim = 5771 +26415 - Snow anim = 6995 +26417 - Snowfall anim = 6996 +26418 - Waterfall anim = 7007 +26419 - Waterfall anim = 7007 +26420 - Waterfall anim = 7007 +26421 - Waterfall anim = 7007 +26422 - Waterfall anim = 7007 +26468 - null anim = 7066 +26471 - null anim = 7066 +26472 - null anim = 7067 +26473 - null anim = 7066 +26476 - null anim = 7066 +26477 - null anim = 7066 +26478 - null anim = 7067 +26479 - null anim = 7066 +26481 - null anim = 7067 +26482 - null anim = 7066 +26483 - null anim = 7066 +26484 - null anim = 3440 +26578 - Gas anim = 7087 +26579 - Gas jet anim = 7087 +26597 - null anim = 7097 +26598 - null anim = 7097 +26599 - null anim = 7097 +26600 - null anim = 7097 +26604 - null anim = 5415 +26605 - null anim = 5415 +26708 - Pipe anim = 7097 +26709 - Pipe anim = 7097 +26710 - Pipe anim = 7097 +26711 - Pipe anim = 7097 +26724 - Tree anim = 6069 +26726 - Healthorg anim = 7118 +26727 - Human food anim = 7115 +26728 - Human food anim = 7117 +26729 - Human food anim = 7117 +26730 - null anim = 7120 +26731 - Spirit tree anim = 7138 +26736 - null anim = 7097 +26740 - null anim = 7144 +26741 - null anim = 7146 +26788 - Yewnock's machine anim = 4560 +26789 - Cogs anim = 4563 +26791 - Yewnock's machine anim = 4561 +26792 - Yewnock's exchanger anim = 4562 +26814 - Furnace anim = 7152 +26829 - null anim = 5415 +26830 - null anim = 5415 +26831 - null anim = 493 +26832 - null anim = 493 +26881 - null anim = 7225 +26882 - null anim = 7226 +26971 - Sign anim = 4128 +27039 - Jade vine anim = 7245 +27050 - null anim = 1726 +27051 - Grandfather clock anim = 1726 +27076 - Wild jade vine anim = 7245 +27077 - Wild jade vine anim = 7245 +27078 - Wild jade vine anim = 7245 +27089 - Tree anim = 7252 +27190 - null anim = 7231 +27196 - null anim = 7245 +27197 - null anim = 7245 +27240 - Pitfall anim = 7291 +27241 - Torch anim = 7286 +27251 - Fireplace anim = 3105 +27253 - Fishtank anim = 7283 +27254 - Dark portal anim = 3174 +27274 - Gargoyle anim = 7284 +27275 - Gargoyle anim = 7284 +27276 - Doorway anim = 7284 +27277 - null anim = 7285 \ No newline at end of file diff --git a/dumps/498/498_object_configs.txt b/dumps/498/498_object_configs.txt new file mode 100644 index 0000000..6e3c08e --- /dev/null +++ b/dumps/498/498_object_configs.txt @@ -0,0 +1,1383 @@ +Object config [object id=0, config id=0, shift=-1, childs=[-1, -1, -1, 15596, -1]]. +Object config [object id=137, config id=668, shift=0, childs=[11449, 11450, -1]]. +Object config [object id=139, config id=668, shift=2, childs=[11449, 11450, -1]]. +Object config [object id=138, config id=668, shift=1, childs=[11449, 11450, -1]]. +Object config [object id=141, config id=668, shift=4, childs=[11449, 11450, -1]]. +Object config [object id=140, config id=668, shift=3, childs=[11449, 11450, -1]]. +Object config [object id=143, config id=668, shift=6, childs=[11449, 11450, -1]]. +Object config [object id=142, config id=668, shift=5, childs=[11449, 11450, -1]]. +Object config [object id=144, config id=668, shift=7, childs=[11449, 11450, -1]]. +Object config [object id=145, config id=668, shift=8, childs=[11449, 11450, -1]]. +Object config [object id=146, config id=33, shift=1, childs=[11451, 11452, -1]]. +Object config [object id=147, config id=33, shift=2, childs=[11453, 11454, -1]]. +Object config [object id=148, config id=33, shift=3, childs=[11455, 11456, -1]]. +Object config [object id=149, config id=33, shift=4, childs=[11457, 11458, -1]]. +Object config [object id=150, config id=33, shift=5, childs=[11459, 11460, -1]]. +Object config [object id=151, config id=33, shift=6, childs=[11461, 11462, -1]]. +Object config [object id=954, config id=695, shift=-1, childs=[24069, 24070, 24070, 24070, 24070, 24070, 24070, 24070, 24070, 24070, 24070, 24070, 24070, 24070, 24070, 24070, 24070, 24070, 24070, 24070, 24070, 24070, 24070, 24070, 24070, 24070, 24070, 24070, 24070, 24070, 24070, -1]]. +Object config [object id=1781, config id=695, shift=-1, childs=[5792, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, 1782, -1]]. +Object config [object id=2146, config id=728, shift=2, childs=[15050, 15051, -1]]. +Object config [object id=2458, config id=491, shift=6, childs=[7115, 7116, -1]]. +Object config [object id=2459, config id=491, shift=7, childs=[7117, 7118, -1]]. +Object config [object id=2456, config id=491, shift=4, childs=[7111, 7112, -1]]. +Object config [object id=2457, config id=491, shift=5, childs=[7113, 7114, -1]]. +Object config [object id=2462, config id=491, shift=10, childs=[7123, 7124, -1]]. +Object config [object id=2463, config id=491, shift=11, childs=[7125, 7126, -1]]. +Object config [object id=2460, config id=491, shift=8, childs=[7119, 7120, -1]]. +Object config [object id=2461, config id=491, shift=9, childs=[7121, 7122, -1]]. +Object config [object id=2454, config id=491, shift=2, childs=[7107, 7108, -1]]. +Object config [object id=2455, config id=491, shift=3, childs=[7109, 7110, -1]]. +Object config [object id=2452, config id=491, shift=0, childs=[7103, 7104, -1]]. +Object config [object id=2453, config id=491, shift=1, childs=[7105, 7106, -1]]. +Object config [object id=2464, config id=491, shift=12, childs=[30529, 30530, -1]]. +Object config [object id=2490, config id=1218, shift=17, childs=[30492, 30491, -1]]. +Object config [object id=2532, config id=667, shift=2, childs=[11418, 11417, -1]]. +Object config [object id=2359, config id=135, shift=4, childs=[17296, 17297, -1]]. +Object config [object id=2679, config id=907, shift=0, childs=[18869, 18870, -1]]. +Object config [object id=2682, config id=907, shift=12, childs=[18958, 18959, -1]]. +Object config [object id=2870, config id=1017, shift=12, childs=[15518, 15519, -1]]. +Object config [object id=2843, config id=222, shift=21, childs=[17424, 17423, 17423, -1]]. +Object config [object id=3480, config id=1218, shift=18, childs=[30493, 30494, -1]]. +Object config [object id=3489, config id=1218, shift=19, childs=[30498, 30499, 30500, -1]]. +Object config [object id=3490, config id=1218, shift=21, childs=[30504, 30505, 30506, 30507, 30508, 30509, 30510, -1]]. +Object config [object id=3407, config id=299, shift=9, childs=[18516, 18515, -1]]. +Object config [object id=3404, config id=299, shift=3, childs=[18509, 18510, -1]]. +Object config [object id=3405, config id=299, shift=5, childs=[18512, 18511, -1]]. +Object config [object id=3403, config id=299, shift=4, childs=[18509, 18510, -1]]. +Object config [object id=3414, config id=896, shift=28, childs=[18650, 18726, -1]]. +Object config [object id=3413, config id=896, shift=6, childs=[18595, 18596, -1]]. +Object config [object id=3411, config id=299, shift=5, childs=[18587, 18530, -1]]. +Object config [object id=3410, config id=299, shift=7, childs=[18525, 18526, -1]]. +Object config [object id=3429, config id=897, shift=8, childs=[18664, 18667, 18668, 18669, -1]]. +Object config [object id=4039, config id=1178, shift=11, childs=[28675, 28675, 28676, -1]]. +Object config [object id=3978, config id=1193, shift=29, childs=[29443, 29442, 29444, -1]]. +Object config [object id=3977, config id=1193, shift=29, childs=[29440, 29439, 29441, -1]]. +Object config [object id=3976, config id=1193, shift=29, childs=[29437, 29436, 29438, -1]]. +Object config [object id=4099, config id=1185, shift=31, childs=[29087, 29086, -1]]. +Object config [object id=4105, config id=1185, shift=31, childs=[29104, 29103, -1]]. +Object config [object id=5062, config id=1218, shift=25, childs=[30514, 30513, -1]]. +Object config [object id=5063, config id=1218, shift=25, childs=[30516, 30515, -1]]. +Object config [object id=5060, config id=1218, shift=21, childs=[-1, -1, -1, -1, -1, -1, 30519, -1]]. +Object config [object id=5061, config id=1218, shift=25, childs=[30512, 30511, -1]]. +Object config [object id=5492, config id=174, shift=14, childs=[5490, 5491, 5490, 5490, -1]]. +Object config [object id=5182, config id=399, shift=-1, childs=[5180, 5180, 5180, 5181, 5180, 5180, 5180, 5180, 5180, -1]]. +Object config [object id=5963, config id=433, shift=30, childs=[5964, -1]]. +Object config [object id=5908, config id=425, shift=5, childs=[5909, 5910, -1]]. +Object config [object id=5861, config id=423, shift=29, childs=[-1, 5862, 5863, -1]]. +Object config [object id=5811, config id=417, shift=26, childs=[5809, 5810, -1]]. +Object config [object id=5823, config id=417, shift=25, childs=[5815, 5816, -1]]. +Object config [object id=5822, config id=417, shift=25, childs=[5815, 5817, -1]]. +Object config [object id=5821, config id=417, shift=25, childs=[5815, 5819, -1]]. +Object config [object id=5820, config id=417, shift=25, childs=[5815, 5818, -1]]. +Object config [object id=6560, config id=440, shift=21, childs=[-1, 6561, -1]]. +Object config [object id=6550, config id=440, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6551, -1]]. +Object config [object id=6636, config id=443, shift=11, childs=[6637, -1]]. +Object config [object id=6638, config id=443, shift=12, childs=[6639, -1]]. +Object config [object id=6634, config id=443, shift=10, childs=[6635, -1]]. +Object config [object id=6640, config id=443, shift=13, childs=[6641, -1]]. +Object config [object id=6621, config id=443, shift=20, childs=[6622, 6623, -1]]. +Object config [object id=6432, config id=440, shift=20, childs=[1396, 6433, -1]]. +Object config [object id=6440, config id=442, shift=11, childs=[6446, 6445, 6444, 6443, 6442, 6441, 6441, 6441, 6441, 6441, -1]]. +Object config [object id=6407, config id=441, shift=2, childs=[6408, 6414, -1]]. +Object config [object id=6405, config id=441, shift=1, childs=[6406, 6413, -1]]. +Object config [object id=6411, config id=441, shift=4, childs=[6412, 6416, -1]]. +Object config [object id=6409, config id=441, shift=3, childs=[6410, 6415, -1]]. +Object config [object id=6422, config id=440, shift=20, childs=[1396, 6423, -1]]. +Object config [object id=6426, config id=440, shift=20, childs=[1396, 6427, -1]]. +Object config [object id=6424, config id=440, shift=20, childs=[1396, 6425, -1]]. +Object config [object id=6430, config id=440, shift=20, childs=[1396, 6431, -1]]. +Object config [object id=6428, config id=440, shift=20, childs=[1396, 6429, -1]]. +Object config [object id=6485, config id=440, shift=15, childs=[6486, 6487, -1]]. +Object config [object id=6482, config id=440, shift=18, childs=[6483, 6484, -1]]. +Object config [object id=6491, config id=440, shift=16, childs=[6492, 6493, -1]]. +Object config [object id=6488, config id=440, shift=17, childs=[6489, 6490, -1]]. +Object config [object id=6306, config id=437, shift=13, childs=[6309, 6308, 6307, 6309, -1]]. +Object config [object id=6304, config id=437, shift=11, childs=[6307, 6308, -1]]. +Object config [object id=6305, config id=437, shift=12, childs=[6307, 6308, -1]]. +Object config [object id=6310, config id=437, shift=0, childs=[6363, 6363, 6363, 6363, 6363, 6364, 6364, 6364, 6364, 6364, 6364, -1]]. +Object config [object id=6300, config id=437, shift=16, childs=[6301, 6302, -1]]. +Object config [object id=6303, config id=437, shift=10, childs=[6307, 6308, -1]]. +Object config [object id=6293, config id=437, shift=17, childs=[6294, 6295, -1]]. +Object config [object id=7042, config id=482, shift=10, childs=[7043, -1]]. +Object config [object id=7040, config id=482, shift=10, childs=[7041, -1]]. +Object config [object id=7128, config id=1218, shift=29, childs=[-1, 30531, -1]]. +Object config [object id=7127, config id=1218, shift=28, childs=[30522, 30524, -1]]. +Object config [object id=7144, config id=491, shift=18, childs=[7161, 7158, 7156, 7158, 7161, 7165, 7161, 7158, 7154, 7158, 7161, 7165, 7159, 7160, 7162, 7163, 7166, 7167, 7169, 7170, -1]]. +Object config [object id=7145, config id=491, shift=18, childs=[7165, 7161, 7158, 7156, 7158, 7161, 7165, 7161, 7158, 7154, 7158, 7161, 7159, 7160, 7162, 7163, 7166, 7167, 7169, 7170, -1]]. +Object config [object id=7146, config id=491, shift=18, childs=[7168, 7165, 7161, 7158, 7156, 7158, 7168, 7165, 7161, 7158, 7154, 7158, 7159, 7160, 7162, 7163, 7166, 7167, 7169, 7170, -1]]. +Object config [object id=7147, config id=491, shift=18, childs=[7164, 7168, 7165, 7161, 7158, 7156, 7164, 7168, 7165, 7161, 7158, 7154, 7159, 7160, 7162, 7163, 7166, 7167, 7169, 7170, -1]]. +Object config [object id=7148, config id=491, shift=18, childs=[7154, 7164, 7168, 7165, 7161, 7158, 7156, 7164, 7168, 7165, 7161, 7158, 7159, 7160, 7162, 7163, 7166, 7167, 7169, 7170, -1]]. +Object config [object id=7149, config id=491, shift=18, childs=[7164, 7154, 7164, 7168, 7165, 7161, 7164, 7156, 7164, 7168, 7165, 7161, 7159, 7160, 7162, 7163, 7166, 7167, 7169, 7170, -1]]. +Object config [object id=7150, config id=491, shift=18, childs=[7168, 7164, 7154, 7164, 7168, 7165, 7168, 7164, 7156, 7164, 7168, 7165, 7159, 7160, 7162, 7163, 7166, 7167, 7169, 7170, -1]]. +Object config [object id=7151, config id=491, shift=18, childs=[7165, 7168, 7164, 7154, 7164, 7168, 7165, 7168, 7164, 7156, 7164, 7168, 7159, 7160, 7162, 7163, 7166, 7167, 7169, 7170, -1]]. +Object config [object id=7142, config id=491, shift=18, childs=[7156, 7158, 7161, 7165, 7168, 7164, 7154, 7164, 7168, 7165, 7161, 7158, 7159, 7160, 7162, 7163, 7166, 7167, 7169, 7170, -1]]. +Object config [object id=7143, config id=491, shift=18, childs=[7158, 7156, 7158, 7161, 7165, 7168, 7158, 7154, 7158, 7168, 7165, 7161, 7159, 7160, 7162, 7163, 7166, 7167, 7169, 7170, -1]]. +Object config [object id=7153, config id=491, shift=18, childs=[7158, 7161, 7165, 7168, 7164, 7154, 7158, 7161, 7165, 7168, 7164, 7156, 7159, 7160, 7162, 7163, 7166, 7167, 7169, 7170, -1]]. +Object config [object id=7152, config id=491, shift=18, childs=[7161, 7165, 7168, 7164, 7154, 7164, 7161, 7165, 7168, 7164, 7156, 7164, 7159, 7160, 7162, 7163, 7166, 7167, 7169, 7170, -1]]. +Object config [object id=6913, config id=465, shift=19, childs=[6918, -1]]. +Object config [object id=7031, config id=482, shift=15, childs=[7032, 7033, 7034, 7035, 7036, 7037, 7038, 7039, -1]]. +Object config [object id=6843, config id=455, shift=5, childs=[6844, 6844, 6844, 6845, 6845, 6845, -1]]. +Object config [object id=6879, config id=455, shift=16, childs=[6880, 6881, -1]]. +Object config [object id=6878, config id=455, shift=16, childs=[6880, 6882, -1]]. +Object config [object id=6899, config id=465, shift=0, childs=[6909, 6909, 6909, 6909, 6905, 6905, 6905, 6905, 6905, 6905, 6905, 6905, -1]]. +Object config [object id=6898, config id=465, shift=0, childs=[6904, 6903, 6903, 6903, 6905, 6905, 6905, 6905, 6905, 6905, 6905, 6905, -1]]. +Object config [object id=6900, config id=465, shift=0, childs=[-1, 6902, 6902, 6902, 6902, 6902, 6902, 6902, 6902, 6902, 6902, -1]]. +Object config [object id=6895, config id=665, shift=0, childs=[3375, 3372, 3373, 3374, 3382, 3383, 12561, 12562, 12563, -1]]. +Object config [object id=6887, config id=455, shift=14, childs=[6888, 6889, 6888, -1]]. +Object config [object id=6710, config id=452, shift=7, childs=[-1, 6708, -1]]. +Object config [object id=6711, config id=452, shift=8, childs=[-1, 6708, -1]]. +Object config [object id=6709, config id=452, shift=6, childs=[-1, 6708, -1]]. +Object config [object id=6718, config id=452, shift=12, childs=[6714, 6715, -1]]. +Object config [object id=6719, config id=452, shift=13, childs=[6714, 6715, -1]]. +Object config [object id=6716, config id=452, shift=10, childs=[6714, 6715, -1]]. +Object config [object id=6717, config id=452, shift=11, childs=[6714, 6715, -1]]. +Object config [object id=6712, config id=452, shift=9, childs=[-1, 6708, -1]]. +Object config [object id=6736, config id=452, shift=11, childs=[6733, 6734, -1]]. +Object config [object id=6737, config id=452, shift=12, childs=[6733, 6734, -1]]. +Object config [object id=6738, config id=452, shift=13, childs=[6733, 6734, -1]]. +Object config [object id=6739, config id=452, shift=14, childs=[6733, 6734, -1]]. +Object config [object id=6740, config id=452, shift=15, childs=[6733, 6734, -1]]. +Object config [object id=6741, config id=452, shift=16, childs=[6733, 6734, -1]]. +Object config [object id=6742, config id=452, shift=17, childs=[6733, 6734, -1]]. +Object config [object id=6743, config id=452, shift=18, childs=[6733, 6734, -1]]. +Object config [object id=6744, config id=452, shift=19, childs=[6733, 6734, -1]]. +Object config [object id=6745, config id=452, shift=20, childs=[6733, 6734, -1]]. +Object config [object id=6746, config id=452, shift=21, childs=[6733, 6734, -1]]. +Object config [object id=6747, config id=452, shift=22, childs=[6733, 6734, -1]]. +Object config [object id=6748, config id=452, shift=23, childs=[6733, 6734, -1]]. +Object config [object id=6749, config id=452, shift=24, childs=[6733, 6734, -1]]. +Object config [object id=6750, config id=452, shift=25, childs=[6733, 6734, -1]]. +Object config [object id=6751, config id=452, shift=10, childs=[-1, 6807, -1]]. +Object config [object id=6721, config id=452, shift=15, childs=[6714, 6715, -1]]. +Object config [object id=6720, config id=452, shift=14, childs=[6714, 6715, -1]]. +Object config [object id=6723, config id=452, shift=17, childs=[6714, 6715, -1]]. +Object config [object id=6722, config id=452, shift=16, childs=[6714, 6715, -1]]. +Object config [object id=6725, config id=452, shift=19, childs=[6714, 6715, -1]]. +Object config [object id=6724, config id=452, shift=18, childs=[6714, 6715, -1]]. +Object config [object id=6727, config id=452, shift=21, childs=[6714, 6715, -1]]. +Object config [object id=6726, config id=452, shift=20, childs=[6714, 6715, -1]]. +Object config [object id=6729, config id=452, shift=23, childs=[6714, 6715, -1]]. +Object config [object id=6728, config id=452, shift=22, childs=[6714, 6715, -1]]. +Object config [object id=6731, config id=452, shift=25, childs=[6714, 6715, -1]]. +Object config [object id=6730, config id=452, shift=24, childs=[6714, 6715, -1]]. +Object config [object id=6735, config id=452, shift=10, childs=[6733, 6734, -1]]. +Object config [object id=6755, config id=452, shift=14, childs=[-1, 6807, -1]]. +Object config [object id=6754, config id=452, shift=13, childs=[-1, 6807, -1]]. +Object config [object id=6753, config id=452, shift=12, childs=[-1, 6807, -1]]. +Object config [object id=6752, config id=452, shift=11, childs=[-1, 6807, -1]]. +Object config [object id=6759, config id=452, shift=18, childs=[-1, 6807, -1]]. +Object config [object id=6758, config id=452, shift=17, childs=[-1, 6807, -1]]. +Object config [object id=6757, config id=452, shift=16, childs=[-1, 6807, -1]]. +Object config [object id=6756, config id=452, shift=15, childs=[-1, 6807, -1]]. +Object config [object id=6763, config id=452, shift=22, childs=[-1, 6807, -1]]. +Object config [object id=6762, config id=452, shift=21, childs=[-1, 6807, -1]]. +Object config [object id=6761, config id=452, shift=20, childs=[-1, 6807, -1]]. +Object config [object id=6760, config id=452, shift=19, childs=[-1, 6807, -1]]. +Object config [object id=6766, config id=452, shift=25, childs=[-1, 6807, -1]]. +Object config [object id=6765, config id=452, shift=24, childs=[-1, 6807, -1]]. +Object config [object id=6764, config id=452, shift=23, childs=[-1, 6807, -1]]. +Object config [object id=7572, config id=512, shift=16, childs=[7560, 7559, 7558, 7557, 7561, 7562, 7563, 7564, 7565, 7566, 7567, 7568, 7569, 7570, 7571, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, 7560, -1]]. +Object config [object id=7579, config id=509, shift=16, childs=[7576, 7575, 7574, 7573, 7576, 7692, 7693, 7694, 7695, 7696, 7697, 7698, 7699, 7700, 7701, 7581, 7582, 7583, 7584, 7585, 7586, 7587, 7588, 7589, 7590, 7591, 7605, 7606, 7607, 7608, 7609, 7610, 7611, 7612, 7613, 7614, 7615, 7616, 7632, 7633, 7634, 7635, 7636, 7637, 7638, 7639, 7640, 7641, 7642, 7643, 7644, 7713, 7714, 7715, 7716, 7717, 7718, 7719, 7720, 7721, 7722, 7723, 7724, 7725, 7576, 7576, 7576, 7576, 7576, 7576, 7703, 7704, 7705, 7706, 7707, 7576, 7576, 7576, 7576, 7576, 7593, 7594, 7595, 7596, 7597, 7598, 7576, 7576, 7576, 7576, 7576, 7618, 7619, 7620, 7621, 7622, 7623, 7624, 7576, 7576, 7576, 7576, 7576, 7646, 7647, 7648, 7649, 7650, 7651, 7652, 7653, 7576, 7576, 7576, 7576, 7576, 7727, 7728, 7729, 7730, 7731, 7732, 7733, 7734, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7708, 7709, 7710, 7711, 7712, 7576, 7576, 7576, 7576, 7576, 7599, 7600, 7601, 7602, 7603, 7604, 7576, 7576, 7576, 7576, 7576, 7625, 7626, 7627, 7628, 7629, 7630, 7631, 7576, 7576, 7576, 7576, 7576, 7654, 7655, 7656, 7657, 7658, 7659, 7660, 7661, 7576, 7576, 7576, 7576, 7576, 7735, 7736, 7737, 7738, 7739, 7740, 7741, 7742, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7662, 7663, 7664, 7665, 7666, 7667, 7668, 7669, 7670, 7671, 7672, 7673, 7674, 7676, 7677, 7678, 7679, 7680, 7681, 7682, 7684, 7685, 7686, 7687, 7688, 7689, 7690, 7691, 7683, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7702, 7592, 7617, 7645, 7726, 7675, -1]]. +Object config [object id=7578, config id=509, shift=8, childs=[7576, 7575, 7574, 7573, 7576, 7692, 7693, 7694, 7695, 7696, 7697, 7698, 7699, 7700, 7701, 7581, 7582, 7583, 7584, 7585, 7586, 7587, 7588, 7589, 7590, 7591, 7605, 7606, 7607, 7608, 7609, 7610, 7611, 7612, 7613, 7614, 7615, 7616, 7632, 7633, 7634, 7635, 7636, 7637, 7638, 7639, 7640, 7641, 7642, 7643, 7644, 7713, 7714, 7715, 7716, 7717, 7718, 7719, 7720, 7721, 7722, 7723, 7724, 7725, 7576, 7576, 7576, 7576, 7576, 7576, 7703, 7704, 7705, 7706, 7707, 7576, 7576, 7576, 7576, 7576, 7593, 7594, 7595, 7596, 7597, 7598, 7576, 7576, 7576, 7576, 7576, 7618, 7619, 7620, 7621, 7622, 7623, 7624, 7576, 7576, 7576, 7576, 7576, 7646, 7647, 7648, 7649, 7650, 7651, 7652, 7653, 7576, 7576, 7576, 7576, 7576, 7727, 7728, 7729, 7730, 7731, 7732, 7733, 7734, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7708, 7709, 7710, 7711, 7712, 7576, 7576, 7576, 7576, 7576, 7599, 7600, 7601, 7602, 7603, 7604, 7576, 7576, 7576, 7576, 7576, 7625, 7626, 7627, 7628, 7629, 7630, 7631, 7576, 7576, 7576, 7576, 7576, 7654, 7655, 7656, 7657, 7658, 7659, 7660, 7661, 7576, 7576, 7576, 7576, 7576, 7735, 7736, 7737, 7738, 7739, 7740, 7741, 7742, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7662, 7663, 7664, 7665, 7666, 7667, 7668, 7669, 7670, 7671, 7672, 7673, 7674, 7676, 7677, 7678, 7679, 7680, 7681, 7682, 7684, 7685, 7686, 7687, 7688, 7689, 7690, 7691, 7683, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7702, 7592, 7617, 7645, 7726, 7675, -1]]. +Object config [object id=7577, config id=509, shift=0, childs=[7576, 7575, 7574, 7573, 7576, 7692, 7693, 7694, 7695, 7696, 7697, 7698, 7699, 7700, 7701, 7581, 7582, 7583, 7584, 7585, 7586, 7587, 7588, 7589, 7590, 7591, 7605, 7606, 7607, 7608, 7609, 7610, 7611, 7612, 7613, 7614, 7615, 7616, 7632, 7633, 7634, 7635, 7636, 7637, 7638, 7639, 7640, 7641, 7642, 7643, 7644, 7713, 7714, 7715, 7716, 7717, 7718, 7719, 7720, 7721, 7722, 7723, 7724, 7725, 7576, 7576, 7576, 7576, 7576, 7576, 7703, 7704, 7705, 7706, 7707, 7576, 7576, 7576, 7576, 7576, 7593, 7594, 7595, 7596, 7597, 7598, 7576, 7576, 7576, 7576, 7576, 7618, 7619, 7620, 7621, 7622, 7623, 7624, 7576, 7576, 7576, 7576, 7576, 7646, 7647, 7648, 7649, 7650, 7651, 7652, 7653, 7576, 7576, 7576, 7576, 7576, 7727, 7728, 7729, 7730, 7731, 7732, 7733, 7734, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7708, 7709, 7710, 7711, 7712, 7576, 7576, 7576, 7576, 7576, 7599, 7600, 7601, 7602, 7603, 7604, 7576, 7576, 7576, 7576, 7576, 7625, 7626, 7627, 7628, 7629, 7630, 7631, 7576, 7576, 7576, 7576, 7576, 7654, 7655, 7656, 7657, 7658, 7659, 7660, 7661, 7576, 7576, 7576, 7576, 7576, 7735, 7736, 7737, 7738, 7739, 7740, 7741, 7742, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7662, 7663, 7664, 7665, 7666, 7667, 7668, 7669, 7670, 7671, 7672, 7673, 7674, 7676, 7677, 7678, 7679, 7680, 7681, 7682, 7684, 7685, 7686, 7687, 7688, 7689, 7690, 7691, 7683, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7702, 7592, 7617, 7645, 7726, 7675, -1]]. +Object config [object id=7580, config id=509, shift=24, childs=[7576, 7575, 7574, 7573, 7576, 7692, 7693, 7694, 7695, 7696, 7697, 7698, 7699, 7700, 7701, 7581, 7582, 7583, 7584, 7585, 7586, 7587, 7588, 7589, 7590, 7591, 7605, 7606, 7607, 7608, 7609, 7610, 7611, 7612, 7613, 7614, 7615, 7616, 7632, 7633, 7634, 7635, 7636, 7637, 7638, 7639, 7640, 7641, 7642, 7643, 7644, 7713, 7714, 7715, 7716, 7717, 7718, 7719, 7720, 7721, 7722, 7723, 7724, 7725, 7576, 7576, 7576, 7576, 7576, 7576, 7703, 7704, 7705, 7706, 7707, 7576, 7576, 7576, 7576, 7576, 7593, 7594, 7595, 7596, 7597, 7598, 7576, 7576, 7576, 7576, 7576, 7618, 7619, 7620, 7621, 7622, 7623, 7624, 7576, 7576, 7576, 7576, 7576, 7646, 7647, 7648, 7649, 7650, 7651, 7652, 7653, 7576, 7576, 7576, 7576, 7576, 7727, 7728, 7729, 7730, 7731, 7732, 7733, 7734, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7708, 7709, 7710, 7711, 7712, 7576, 7576, 7576, 7576, 7576, 7599, 7600, 7601, 7602, 7603, 7604, 7576, 7576, 7576, 7576, 7576, 7625, 7626, 7627, 7628, 7629, 7630, 7631, 7576, 7576, 7576, 7576, 7576, 7654, 7655, 7656, 7657, 7658, 7659, 7660, 7661, 7576, 7576, 7576, 7576, 7576, 7735, 7736, 7737, 7738, 7739, 7740, 7741, 7742, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7662, 7663, 7664, 7665, 7666, 7667, 7668, 7669, 7670, 7671, 7672, 7673, 7674, 7676, 7677, 7678, 7679, 7680, 7681, 7682, 7684, 7685, 7686, 7687, 7688, 7689, 7690, 7691, 7683, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7576, 7702, 7592, 7617, 7645, 7726, 7675, -1]]. +Object config [object id=7495, config id=510, shift=8, childs=[7437, 7438, 7441, -1, 7444, 7445, 7446, 7447, 7448, -1, 7449, 7450, 7451, 7452, 7453, -1, 7454, 7455, 7456, 7457, 7458, -1, 7459, 7460, 7461, 7462, 7463, -1, 7464, 7465, 7466, 7467, 7468, -1, 7469, 7470, 7471, 7472, 7473, -1, 7474, 7475, 7476, 7477, 7478, -1, 7479, 7480, 7481, 7482, 7483, -1, 7484, 7485, 7486, 7487, 7488, -1, 7489, 7490, 7491, 7492, 7493, -1, 7439, 7440, -1]]. +Object config [object id=7494, config id=510, shift=0, childs=[7437, 7438, 7441, -1, 7444, 7445, 7446, 7447, 7448, -1, 7449, 7450, 7451, 7452, 7453, -1, 7454, 7455, 7456, 7457, 7458, -1, 7459, 7460, 7461, 7462, 7463, -1, 7464, 7465, 7466, 7467, 7468, -1, 7469, 7470, 7471, 7472, 7473, -1, 7474, 7475, 7476, 7477, 7478, -1, 7479, 7480, 7481, 7482, 7483, -1, 7484, 7485, 7486, 7487, 7488, -1, 7489, 7490, 7491, 7492, 7493, -1, 7439, 7440, -1, -1, 8871, 8872, 8873, 8874, -1]]. +Object config [object id=7432, config id=510, shift=24, childs=[7407, 7408, 7410, -1, 7409, -1, -1, -1, 7411, 7411, 7411, 7411, 7411, 7411, 7411, 7411, 7413, 7413, 7413, 7413, 7413, 7413, 7413, 7413, 7415, 7415, 7415, 7415, 7415, 7415, 7415, 7415, 7417, 7417, 7417, 7417, 7417, 7417, 7417, 7417, 7419, 7419, 7419, 7419, 7419, 7419, 7419, 7419, 7421, 7421, 7421, 7421, 7421, 7421, 7421, 7421, 7423, 7423, 7423, 7423, 7423, 7423, 7423, 7423, 7425, 7425, 7425, 7425, 7425, 7425, 7425, 7425, 7427, 7427, 7427, 7427, 7427, 7427, 7427, 7427, 7429, 7429, 7429, 7429, 7429, 7429, 7429, 7429, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7412, 7412, 7412, 7412, 7412, 7412, 7412, 7412, 7414, 7414, 7414, 7414, 7414, 7414, 7414, 7414, 7416, 7416, 7416, 7416, 7416, 7416, 7416, 7416, 7418, 7418, 7418, 7418, 7418, 7418, 7418, 7418, 7420, 7420, 7420, 7420, 7420, 7420, 7420, 7420, 7422, 7422, 7422, 7422, 7422, 7422, 7422, 7422, 7424, 7424, 7424, 7424, 7424, 7424, 7424, 7424, 7426, 7426, 7426, 7426, 7426, 7426, 7426, 7426, 7428, 7428, 7428, 7428, 7428, 7428, 7428, 7428, 7430, 7430, 7430, 7430, 7430, 7430, 7430, 7430, -1]]. +Object config [object id=7431, config id=510, shift=16, childs=[7407, 7408, 7410, 8870, 7409, -1, -1, -1, 7411, 7411, 7411, 7411, 7411, 7411, 7411, 7411, 7413, 7413, 7413, 7413, 7413, 7413, 7413, 7413, 7415, 7415, 7415, 7415, 7415, 7415, 7415, 7415, 7417, 7417, 7417, 7417, 7417, 7417, 7417, 7417, 7419, 7419, 7419, 7419, 7419, 7419, 7419, 7419, 7421, 7421, 7421, 7421, 7421, 7421, 7421, 7421, 7423, 7423, 7423, 7423, 7423, 7423, 7423, 7423, 7425, 7425, 7425, 7425, 7425, 7425, 7425, 7425, 7427, 7427, 7427, 7427, 7427, 7427, 7427, 7427, 7429, 7429, 7429, 7429, 7429, 7429, 7429, 7429, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7412, 7412, 7412, 7412, 7412, 7412, 7412, 7412, 7414, 7414, 7414, 7414, 7414, 7414, 7414, 7414, 7416, 7416, 7416, 7416, 7416, 7416, 7416, 7416, 7418, 7418, 7418, 7418, 7418, 7418, 7418, 7418, 7420, 7420, 7420, 7420, 7420, 7420, 7420, 7420, 7422, 7422, 7422, 7422, 7422, 7422, 7422, 7422, 7424, 7424, 7424, 7424, 7424, 7424, 7424, 7424, 7426, 7426, 7426, 7426, 7426, 7426, 7426, 7426, 7428, 7428, 7428, 7428, 7428, 7428, 7428, 7428, 7430, 7430, 7430, 7430, 7430, 7430, 7430, 7430, -1]]. +Object config [object id=7395, config id=499, shift=-1, childs=[7394, -1]]. +Object config [object id=7342, config id=497, shift=28, childs=[7343, 7344, 7344, 7345, -1]]. +Object config [object id=7296, config id=496, shift=3, childs=[7309, 7312, 7314, 7305, 7303, 7307, 7311, 7303, 7304, 7303, 7309, 7308, -1]]. +Object config [object id=7297, config id=496, shift=3, childs=[7310, 7313, 7312, 7308, 7309, 7309, 7310, 7304, 7312, 7309, 7310, -1, 7312, -1]]. +Object config [object id=7298, config id=496, shift=3, childs=[7311, 7304, 7309, 7304, 7314, 7314, 7307, 7305, 7314, 7311, -1, 7305, 7314, -1]]. +Object config [object id=7299, config id=496, shift=3, childs=[7312, 7307, 7313, 7314, 7310, 7311, 7308, -1, 7310, 7308, 7305, 7311, 7311, -1]]. +Object config [object id=7300, config id=496, shift=3, childs=[7313, 7309, 7303, 7313, 7308, 7308, 7306, 7313, -1, 7305, 7304, 7309, 7313, -1]]. +Object config [object id=7301, config id=496, shift=3, childs=[7314, 7305, 7308, 7310, 7304, 7305, 7305, 7314, 7306, -1, 7303, 7306, 7310, -1]]. +Object config [object id=7294, config id=496, shift=3, childs=[7307, 7310, -1, 7303, 7311, 7312, 7314, 7310, 7309, 7313, 7313, 7313, 7305, -1]]. +Object config [object id=7295, config id=496, shift=3, childs=[7308, -1, 7311, 7307, 7313, 7303, 7313, 7311, 7307, 7306, 7312, 7304, 7308, -1]]. +Object config [object id=7292, config id=496, shift=3, childs=[7305, 7303, 7310, 7309, -1, 7310, 7309, 7308, 7311, 7307, 7308, 7312, 7304, -1]]. +Object config [object id=7293, config id=496, shift=3, childs=[7306, 7314, 7306, -1, 7312, 7313, 7312, 7309, 7303, 7312, 7314, 7314, 7307, -1]]. +Object config [object id=7290, config id=496, shift=3, childs=[7303, 7311, 7304, 7312, 7306, 7306, -1, 7306, 7305, 7304, 7306, 7307, 7303, -1]]. +Object config [object id=7291, config id=496, shift=3, childs=[7304, 7306, 7305, 7311, 7307, -1, 7304, 7307, 7308, 7310, 7307, 7303, 7306, -1]]. +Object config [object id=7282, config id=498, shift=14, childs=[7284, -1, 7285, -1]]. +Object config [object id=7283, config id=498, shift=17, childs=[-1, 7284, -1, 7285, -1]]. +Object config [object id=7280, config id=498, shift=10, childs=[-1, 7281, -1, 7281, -1]]. +Object config [object id=7279, config id=498, shift=7, childs=[7281, -1, 7281, -1]]. +Object config [object id=7276, config id=498, shift=3, childs=[-1, 7277, -1, 7278, -1]]. +Object config [object id=7275, config id=498, shift=0, childs=[7277, -1, 7278, -1]]. +Object config [object id=8151, config id=515, shift=8, childs=[8135, 8134, 8133, 8132, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8147, 8148, 8149, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 9044, 9045, 9046, 9047, 9048, 9048, 9049, 9050, 9051, 9052, 9053, 9054, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8144, 8145, 8146, 8135, 8135, 8135, 8135, 8135, 8135, -1, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, -1]]. +Object config [object id=8150, config id=515, shift=0, childs=[8135, 8134, 8133, 8132, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8147, 8148, 8149, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 9044, 9045, 9046, 9047, 9048, 9048, 9049, 9050, 9051, 9052, 9053, 9054, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8144, 8145, 8146, 8135, 8135, 8135, 8135, 8135, 8135, -1, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, -1]]. +Object config [object id=8153, config id=515, shift=24, childs=[8138, 8137, 8136, 8132, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8147, 8148, 8149, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 9044, 9045, 9046, 9047, 9048, 9048, 9049, 9050, 9051, 9052, 9053, 9054, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8144, 8145, 8146, 8138, 8138, 8138, 8138, 8138, 8138, -1, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 8138, 8138, -1]]. +Object config [object id=8152, config id=515, shift=16, childs=[8135, 8134, 8133, 8132, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8139, 8140, 8141, 8142, 8143, 8143, 8143, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8144, 8145, 8146, 8147, 8148, 8149, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 9044, 9045, 9046, 9047, 9048, 9048, 9049, 9050, 9051, 9052, 9053, 9054, 8139, 8140, 8141, 8142, 8143, 8143, 8143, 8144, 8145, 8146, 8135, 8135, 8135, 8135, 8135, 8135, -1, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, 8135, -1]]. +Object config [object id=8173, config id=506, shift=0, childs=[8210, 8209, 8208, 8207, 8177, 8178, 8179, 8180, 8181, 8181, 8181, 8154, 8155, 8156, 8157, 8158, 8159, 8159, 8159, 8288, 8289, 8290, 8291, 8292, 8293, 8294, 8294, 8294, 8211, 8212, 8213, 8214, 8215, 8216, 8217, 8218, 8218, 8218, 8257, 8258, 8259, 8260, 8261, 8262, 8263, 8264, 8265, 8265, 8265, 8192, 8193, 8194, 8195, 8196, 8196, 8196, 8238, 8239, 8240, 8241, 8242, 8243, 8243, 8243, 8210, 8210, 8210, 8210, 8182, 8183, 8184, 8185, 8210, 8210, 8210, 8160, 8161, 8162, 8163, 8164, 8210, 8210, 8210, 8295, 8296, 8297, 8298, 8299, 8300, 8210, 8210, 8210, 8219, 8220, 8221, 8222, 8223, 8224, 8225, 8210, 8210, 8210, 8266, 8267, 8268, 8269, 8270, 8271, 8272, 8273, 8210, 8210, 8210, 8197, 8198, 8199, 8200, 8210, 8210, 8210, 8244, 8245, 8246, 8247, 8248, 8210, 8210, 8210, 8210, 8210, 8210, 8210, 8210, 8186, 8187, 8188, 8210, 8210, 8210, 8210, 8165, 8166, 8167, 8168, 8210, 8210, 8210, 8210, 8301, 8302, 8303, 8304, 8305, 8210, 8210, 8210, 8210, 8226, 8227, 8228, 8229, 8230, 8231, 8210, 8210, 8210, 8210, 8274, 8275, 8276, 8277, 8278, 8279, 8280, 8210, 8210, 8210, 8210, 8201, 8202, 8203, 8210, -1, 8210, 8210, 8249, 8250, 8251, 8252, 8210, 8210, 8210, 8210, 8210, 8210, 8210, 8210, 8189, 8190, 8191, 8210, 8210, 8210, 8210, 8169, 8170, 8171, 8172, 8210, 8210, 8210, 8210, 8306, 8307, 8308, 8309, 8310, 8210, 8210, 8210, 8210, 8232, 8233, 8234, 8235, 8236, 8237, 8210, 8210, 8210, 8210, 8281, 8282, 8283, 8284, 8285, 8286, 8287, 8210, 8210, 8210, 8210, 8204, 8205, 8206, 8210, 8210, 8210, 8210, 8253, 8254, 8255, 8256, 8210, 8210, 8210, -1]]. +Object config [object id=8174, config id=506, shift=8, childs=[8210, 8209, 8208, 8207, 8177, 8178, 8179, 8180, 8181, 8181, 8181, 8154, 8155, 8156, 8157, 8158, 8159, 8159, 8159, 8288, 8289, 8290, 8291, 8292, 8293, 8294, 8294, 8294, 8211, 8212, 8213, 8214, 8215, 8216, 8217, 8218, 8218, 8218, 8257, 8258, 8259, 8260, 8261, 8262, 8263, 8264, 8265, 8265, 8265, 8192, 8193, 8194, 8195, 8196, 8196, 8196, 8238, 8239, 8240, 8241, 8242, 8243, 8243, 8243, 8210, 8210, 8210, 8210, 8182, 8183, 8184, 8185, 8210, 8210, 8210, 8160, 8161, 8162, 8163, 8164, 8210, 8210, 8210, 8295, 8296, 8297, 8298, 8299, 8300, 8210, 8210, 8210, 8219, 8220, 8221, 8222, 8223, 8224, 8225, 8210, 8210, 8210, 8266, 8267, 8268, 8269, 8270, 8271, 8272, 8273, 8210, 8210, 8210, 8197, 8198, 8199, 8200, 8210, 8210, 8210, 8244, 8245, 8246, 8247, 8248, 8210, 8210, 8210, 8210, 8210, 8210, 8210, 8210, 8186, 8187, 8188, 8210, 8210, 8210, 8210, 8165, 8166, 8167, 8168, 8210, 8210, 8210, 8210, 8301, 8302, 8303, 8304, 8305, 8210, 8210, 8210, 8210, 8226, 8227, 8228, 8229, 8230, 8231, 8210, 8210, 8210, 8210, 8274, 8275, 8276, 8277, 8278, 8279, 8280, 8210, 8210, 8210, 8210, 8201, 8202, 8203, 8210, -1, 8210, 8210, 8249, 8250, 8251, 8252, 8210, 8210, 8210, 8210, 8210, 8210, 8210, 8210, 8189, 8190, 8191, 8210, 8210, 8210, 8210, 8169, 8170, 8171, 8172, 8210, 8210, 8210, 8210, 8306, 8307, 8308, 8309, 8310, 8210, 8210, 8210, 8210, 8232, 8233, 8234, 8235, 8236, 8237, 8210, 8210, 8210, 8210, 8281, 8282, 8283, 8284, 8285, 8286, 8287, 8210, 8210, 8210, 8210, 8204, 8205, 8206, 8210, 8210, 8210, 8210, 8253, 8254, 8255, 8256, 8210, 8210, 8210, -1]]. +Object config [object id=8175, config id=506, shift=16, childs=[8210, 8209, 8208, 8207, 8177, 8178, 8179, 8180, 8181, 8181, 8181, 8154, 8155, 8156, 8157, 8158, 8159, 8159, 8159, 8288, 8289, 8290, 8291, 8292, 8293, 8294, 8294, 8294, 8211, 8212, 8213, 8214, 8215, 8216, 8217, 8218, 8218, 8218, 8257, 8258, 8259, 8260, 8261, 8262, 8263, 8264, 8265, 8265, 8265, 8192, 8193, 8194, 8195, 8196, 8196, 8196, 8238, 8239, 8240, 8241, 8242, 8243, 8243, 8243, 8210, 8210, 8210, 8210, 8182, 8183, 8184, 8185, 8210, 8210, 8210, 8160, 8161, 8162, 8163, 8164, 8210, 8210, 8210, 8295, 8296, 8297, 8298, 8299, 8300, 8210, 8210, 8210, 8219, 8220, 8221, 8222, 8223, 8224, 8225, 8210, 8210, 8210, 8266, 8267, 8268, 8269, 8270, 8271, 8272, 8273, 8210, 8210, 8210, 8197, 8198, 8199, 8200, 8210, 8210, 8210, 8244, 8245, 8246, 8247, 8248, 8210, 8210, 8210, 8210, 8210, 8210, 8210, 8210, 8186, 8187, 8188, 8210, 8210, 8210, 8210, 8165, 8166, 8167, 8168, 8210, 8210, 8210, 8210, 8301, 8302, 8303, 8304, 8305, 8210, 8210, 8210, 8210, 8226, 8227, 8228, 8229, 8230, 8231, 8210, 8210, 8210, 8210, 8274, 8275, 8276, 8277, 8278, 8279, 8280, 8210, 8210, 8210, 8210, 8201, 8202, 8203, 8210, -1, 8210, 8210, 8249, 8250, 8251, 8252, 8210, 8210, 8210, 8210, 8210, 8210, 8210, 8210, 8189, 8190, 8191, 8210, 8210, 8210, 8210, 8169, 8170, 8171, 8172, 8210, 8210, 8210, 8210, 8306, 8307, 8308, 8309, 8310, 8210, 8210, 8210, 8210, 8232, 8233, 8234, 8235, 8236, 8237, 8210, 8210, 8210, 8210, 8281, 8282, 8283, 8284, 8285, 8286, 8287, 8210, 8210, 8210, 8210, 8204, 8205, 8206, 8210, 8210, 8210, 8210, 8253, 8254, 8255, 8256, 8210, 8210, 8210, -1]]. +Object config [object id=8176, config id=506, shift=24, childs=[8210, 8209, 8208, 8207, 8177, 8178, 8179, 8180, 8181, 8181, 8181, 8154, 8155, 8156, 8157, 8158, 8159, 8159, 8159, 8288, 8289, 8290, 8291, 8292, 8293, 8294, 8294, 8294, 8211, 8212, 8213, 8214, 8215, 8216, 8217, 8218, 8218, 8218, 8257, 8258, 8259, 8260, 8261, 8262, 8263, 8264, 8265, 8265, 8265, 8192, 8193, 8194, 8195, 8196, 8196, 8196, 8238, 8239, 8240, 8241, 8242, 8243, 8243, 8243, 8210, 8210, 8210, 8210, 8182, 8183, 8184, 8185, 8210, 8210, 8210, 8160, 8161, 8162, 8163, 8164, 8210, 8210, 8210, 8295, 8296, 8297, 8298, 8299, 8300, 8210, 8210, 8210, 8219, 8220, 8221, 8222, 8223, 8224, 8225, 8210, 8210, 8210, 8266, 8267, 8268, 8269, 8270, 8271, 8272, 8273, 8210, 8210, 8210, 8197, 8198, 8199, 8200, 8210, 8210, 8210, 8244, 8245, 8246, 8247, 8248, 8210, 8210, 8210, 8210, 8210, 8210, 8210, 8210, 8186, 8187, 8188, 8210, 8210, 8210, 8210, 8165, 8166, 8167, 8168, 8210, 8210, 8210, 8210, 8301, 8302, 8303, 8304, 8305, 8210, 8210, 8210, 8210, 8226, 8227, 8228, 8229, 8230, 8231, 8210, 8210, 8210, 8210, 8274, 8275, 8276, 8277, 8278, 8279, 8280, 8210, 8210, 8210, 8210, 8201, 8202, 8203, 8210, -1, 8210, 8210, 8249, 8250, 8251, 8252, 8210, 8210, 8210, 8210, 8210, 8210, 8210, 8210, 8189, 8190, 8191, 8210, 8210, 8210, 8210, 8169, 8170, 8171, 8172, 8210, 8210, 8210, 8210, 8306, 8307, 8308, 8309, 8310, 8210, 8210, 8210, 8210, 8232, 8233, 8234, 8235, 8236, 8237, 8210, 8210, 8210, 8210, 8281, 8282, 8283, 8284, 8285, 8286, 8287, 8210, 8210, 8210, 8210, 8204, 8205, 8206, 8210, 8210, 8210, 8210, 8253, 8254, 8255, 8256, 8210, 8210, 8210, -1]]. +Object config [object id=7964, config id=503, shift=16, childs=[8050, 8049, 8048, 8047, 8050, 8050, 8050, 8050, 7935, 7936, 7937, 7938, 7939, 7940, 7941, 7942, 7943, 7944, 7945, 7946, 7947, 7949, 7950, 7951, 7952, 7953, 7954, 7955, 7956, 7957, 7958, 7959, 7960, 7961, 7948, 7993, 7994, 7995, 7996, 7997, 7998, 8000, 8001, 8002, 8003, 8004, 8005, 8006, 8007, 8008, 8009, 8010, 8011, 8012, 8013, 8014, 8015, 8016, 8017, 8018, 8019, 7999, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8051, 8052, 8053, 8054, 8055, 8056, 8057, 8058, 8059, 8060, 8061, 8062, 8063, 8065, 8066, 8067, 8068, 8069, 8070, 8071, 8072, 8073, 8074, 8075, 8076, 8077, 8064, 8020, 8021, 8022, 8023, 8024, 8025, 8026, 8027, 8028, 8029, 8030, 8031, 8032, 8034, 8035, 8036, 8037, 8038, 8039, 8040, 8041, 8042, 8043, 8044, 8045, 8046, 8033, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 7966, 7967, 7968, 7969, 7970, 7971, 7972, 7973, 7974, 7975, 7976, 7977, 7978, 7980, 7981, 7982, 7983, 7984, 7985, 7986, 7987, 7988, 7989, 7990, 7991, 7992, 7979, 8105, 8106, 8107, 8108, 8109, 8110, 8111, 8112, 8113, 8114, 8115, 8116, 8117, 8119, 8120, 8121, 8122, 8123, 8124, 8125, 8126, 8127, 8128, 8129, 8130, 8131, 8118, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8078, 8079, 8080, 8081, 8082, 8083, 8084, 8085, 8086, 8087, 8088, 8089, 8090, 8092, 8093, 8094, 8095, 8096, 8097, 8098, 8099, 8100, 8101, 8102, 8103, 8104, 8091, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, -1]]. +Object config [object id=7965, config id=503, shift=24, childs=[8050, 8049, 8048, 8047, 8050, 8050, 8050, 8050, 7935, 7936, 7937, 7938, 7939, 7940, 7941, 7942, 7943, 7944, 7945, 7946, 7947, 7949, 7950, 7951, 7952, 7953, 7954, 7955, 7956, 7957, 7958, 7959, 7960, 7961, 7948, 7993, 7994, 7995, 7996, 7997, 7998, 8000, 8001, 8002, 8003, 8004, 8005, 8006, 8007, 8008, 8009, 8010, 8011, 8012, 8013, 8014, 8015, 8016, 8017, 8018, 8019, 7999, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8051, 8052, 8053, 8054, 8055, 8056, 8057, 8058, 8059, 8060, 8061, 8062, 8063, 8065, 8066, 8067, 8068, 8069, 8070, 8071, 8072, 8073, 8074, 8075, 8076, 8077, 8064, 8020, 8021, 8022, 8023, 8024, 8025, 8026, 8027, 8028, 8029, 8030, 8031, 8032, 8034, 8035, 8036, 8037, 8038, 8039, 8040, 8041, 8042, 8043, 8044, 8045, 8046, 8033, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 7966, 7967, 7968, 7969, 7970, 7971, 7972, 7973, 7974, 7975, 7976, 7977, 7978, 7980, 7981, 7982, 7983, 7984, 7985, 7986, 7987, 7988, 7989, 7990, 7991, 7992, 7979, 8105, 8106, 8107, 8108, 8109, 8110, 8111, 8112, 8113, 8114, 8115, 8116, 8117, 8119, 8120, 8121, 8122, 8123, 8124, 8125, 8126, 8127, 8128, 8129, 8130, 8131, 8118, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8078, 8079, 8080, 8081, 8082, 8083, 8084, 8085, 8086, 8087, 8088, 8089, 8090, 8092, 8093, 8094, 8095, 8096, 8097, 8098, 8099, 8100, 8101, 8102, 8103, 8104, 8091, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, -1]]. +Object config [object id=7962, config id=503, shift=0, childs=[8050, 8049, 8048, 8047, 8050, 8050, 8050, 8050, 7935, 7936, 7937, 7938, 7939, 7940, 7941, 7942, 7943, 7944, 7945, 7946, 7947, 7949, 7950, 7951, 7952, 7953, 7954, 7955, 7956, 7957, 7958, 7959, 7960, 7961, 7948, 7993, 7994, 7995, 7996, 7997, 7998, 8000, 8001, 8002, 8003, 8004, 8005, 8006, 8007, 8008, 8009, 8010, 8011, 8012, 8013, 8014, 8015, 8016, 8017, 8018, 8019, 7999, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8051, 8052, 8053, 8054, 8055, 8056, 8057, 8058, 8059, 8060, 8061, 8062, 8063, 8065, 8066, 8067, 8068, 8069, 8070, 8071, 8072, 8073, 8074, 8075, 8076, 8077, 8064, 8020, 8021, 8022, 8023, 8024, 8025, 8026, 8027, 8028, 8029, 8030, 8031, 8032, 8034, 8035, 8036, 8037, 8038, 8039, 8040, 8041, 8042, 8043, 8044, 8045, 8046, 8033, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 7966, 7967, 7968, 7969, 7970, 7971, 7972, 7973, 7974, 7975, 7976, 7977, 7978, 7980, 7981, 7982, 7983, 7984, 7985, 7986, 7987, 7988, 7989, 7990, 7991, 7992, 7979, 8105, 8106, 8107, 8108, 8109, 8110, 8111, 8112, 8113, 8114, 8115, 8116, 8117, 8119, 8120, 8121, 8122, 8123, 8124, 8125, 8126, 8127, 8128, 8129, 8130, 8131, 8118, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8078, 8079, 8080, 8081, 8082, 8083, 8084, 8085, 8086, 8087, 8088, 8089, 8090, 8092, 8093, 8094, 8095, 8096, 8097, 8098, 8099, 8100, 8101, 8102, 8103, 8104, 8091, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, -1]]. +Object config [object id=7963, config id=503, shift=8, childs=[8050, 8049, 8048, 8047, 8050, 8050, 8050, 8050, 7935, 7936, 7937, 7938, 7939, 7940, 7941, 7942, 7943, 7944, 7945, 7946, 7947, 7949, 7950, 7951, 7952, 7953, 7954, 7955, 7956, 7957, 7958, 7959, 7960, 7961, 7948, 7993, 7994, 7995, 7996, 7997, 7998, 8000, 8001, 8002, 8003, 8004, 8005, 8006, 8007, 8008, 8009, 8010, 8011, 8012, 8013, 8014, 8015, 8016, 8017, 8018, 8019, 7999, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8051, 8052, 8053, 8054, 8055, 8056, 8057, 8058, 8059, 8060, 8061, 8062, 8063, 8065, 8066, 8067, 8068, 8069, 8070, 8071, 8072, 8073, 8074, 8075, 8076, 8077, 8064, 8020, 8021, 8022, 8023, 8024, 8025, 8026, 8027, 8028, 8029, 8030, 8031, 8032, 8034, 8035, 8036, 8037, 8038, 8039, 8040, 8041, 8042, 8043, 8044, 8045, 8046, 8033, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 7966, 7967, 7968, 7969, 7970, 7971, 7972, 7973, 7974, 7975, 7976, 7977, 7978, 7980, 7981, 7982, 7983, 7984, 7985, 7986, 7987, 7988, 7989, 7990, 7991, 7992, 7979, 8105, 8106, 8107, 8108, 8109, 8110, 8111, 8112, 8113, 8114, 8115, 8116, 8117, 8119, 8120, 8121, 8122, 8123, 8124, 8125, 8126, 8127, 8128, 8129, 8130, 8131, 8118, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8078, 8079, 8080, 8081, 8082, 8083, 8084, 8085, 8086, 8087, 8088, 8089, 8090, 8092, 8093, 8094, 8095, 8096, 8097, 8098, 8099, 8100, 8101, 8102, 8103, 8104, 8091, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, -1]]. +Object config [object id=7837, config id=511, shift=8, childs=[7808, 7809, 7809, 7809, 7809, 7809, 7809, 7809, 7809, 7809, 7809, 7809, 7809, 7809, 7809, 7810, 7814, 7814, 7814, 7814, 7814, 7814, 7814, 7814, 7814, 7814, 7814, 7814, 7814, 7814, 7815, 7813, 7813, 7811, 7811, 7811, 7811, 7811, 7811, 7811, 7811, 7811, 7811, 7811, 7811, 7811, 7811, 7812, 7816, 7816, 7816, 7816, 7816, 7816, 7816, 7816, 7816, 7816, 7816, 7816, 7816, 7816, 7817, -1, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, -1, -1, 7828, 7828, 7828, 7828, 7828, 7828, 7828, 7828, 7828, 7828, 7828, 7828, 7828, 7828, 7829, 7830, 7830, 7830, 7830, 7830, 7830, 7830, 7830, 7830, 7830, 7830, 7830, 7830, 7830, 7831, 7813, 7813, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, -1]]. +Object config [object id=7836, config id=511, shift=0, childs=[7808, 7809, 7809, 7809, 7809, 7809, 7809, 7809, 7809, 7809, 7809, 7809, 7809, 7809, 7809, 7810, 7814, 7814, 7814, 7814, 7814, 7814, 7814, 7814, 7814, 7814, 7814, 7814, 7814, 7814, 7815, 7813, 7813, 7811, 7811, 7811, 7811, 7811, 7811, 7811, 7811, 7811, 7811, 7811, 7811, 7811, 7811, 7812, 7816, 7816, 7816, 7816, 7816, 7816, 7816, 7816, 7816, 7816, 7816, 7816, 7816, 7816, 7817, -1, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, -1, -1, 7828, 7828, 7828, 7828, 7828, 7828, 7828, 7828, 7828, 7828, 7828, 7828, 7828, 7828, 7829, 7830, 7830, 7830, 7830, 7830, 7830, 7830, 7830, 7830, 7830, 7830, 7830, 7830, 7830, 7831, 7813, 7813, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, -1]]. +Object config [object id=7839, config id=511, shift=24, childs=[7808, 7809, 7809, 7809, 7809, 7809, 7809, 7809, 7809, 7809, 7809, 7809, 7809, 7809, 7809, 7810, 7814, 7814, 7814, 7814, 7814, 7814, 7814, 7814, 7814, 7814, 7814, 7814, 7814, 7814, 7815, 7813, 7813, 7811, 7811, 7811, 7811, 7811, 7811, 7811, 7811, 7811, 7811, 7811, 7811, 7811, 7811, 7812, 7816, 7816, 7816, 7816, 7816, 7816, 7816, 7816, 7816, 7816, 7816, 7816, 7816, 7816, 7817, -1, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, -1, -1, 7828, 7828, 7828, 7828, 7828, 7828, 7828, 7828, 7828, 7828, 7828, 7828, 7828, 7828, 7829, 7830, 7830, 7830, 7830, 7830, 7830, 7830, 7830, 7830, 7830, 7830, 7830, 7830, 7830, 7831, 7813, 7813, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, 7813, -1]]. +Object config [object id=7838, config id=511, shift=16, childs=[7818, 7819, 7819, 7819, 7819, 7819, 7819, 7819, 7819, 7819, 7819, 7819, 7819, 7819, 7819, 7820, 7824, 7824, 7824, 7824, 7824, 7824, 7824, 7824, 7824, 7824, 7824, 7824, 7824, 7824, 7825, 7823, 7823, 7821, 7821, 7821, 7821, 7821, 7821, 7821, 7821, 7821, 7821, 7821, 7821, 7821, 7821, 7822, 7826, 7826, 7826, 7826, 7826, 7826, 7826, 7826, 7826, 7826, 7826, 7826, 7826, 7826, 7827, -1, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, -1, -1, 7832, 7832, 7832, 7832, 7832, 7832, 7832, 7832, 7832, 7832, 7832, 7832, 7832, 7832, 7833, 7834, 7834, 7834, 7834, 7834, 7834, 7834, 7834, 7834, 7834, 7834, 7834, 7834, 7834, 7835, 7823, 7823, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, 7823, -1]]. +Object config [object id=7847, config id=508, shift=0, childs=[7843, 7842, 7841, 7840, 7843, 7843, 7843, 7843, 7867, 7868, 7869, 7870, 7871, 7899, 7900, 7901, 7902, 7903, 7883, 7884, 7885, 7886, 7887, 7919, 7920, 7921, 7922, 7923, 7851, 7852, 7853, 7854, 7855, 7918, 7917, 7916, 7915, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7872, 7873, 7874, 7875, 7843, 7904, 7905, 7906, 7907, 7843, 7888, 7889, 7890, 7891, 7843, 7924, 7925, 7926, 7927, 7843, 7856, 7857, 7858, 7859, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7876, 7877, 7878, 7843, 7843, 7908, 7909, 7910, 7843, 7843, 7892, 7893, 7894, 7843, 7843, 7928, 7929, 7930, 7843, 7843, 7860, 7861, 7862, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7879, 7880, 7881, 7882, 7843, 7911, 7912, 7913, 7914, 7843, 7895, 7896, 7897, 7898, 7843, 7931, 7932, 7933, 7934, 7843, 7863, 7864, 7865, 7866, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, -1]]. +Object config [object id=7850, config id=508, shift=24, childs=[7846, 7845, 7844, 7840, 7846, 7846, 7846, 7846, 7867, 7868, 7869, 7870, 7871, 7899, 7900, 7901, 7902, 7903, 7883, 7884, 7885, 7886, 7887, 7919, 7920, 7921, 7922, 7923, 7851, 7852, 7853, 7854, 7855, 9340, 9339, 9338, 7915, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7872, 7873, 7874, 7875, 7846, 7904, 7905, 7906, 7907, 7846, 7888, 7889, 7890, 7891, 7846, 7924, 7925, 7926, 7927, 7846, 7856, 7857, 7858, 7859, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7846, 7876, 7877, 7878, 7846, 7846, 7908, 7909, 7910, 7846, 7846, 7892, 7893, 7894, 7843, 7843, 7928, 7929, 7930, 7843, 7843, 7860, 7861, 7862, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7879, 7880, 7881, 7882, 7843, 7911, 7912, 7913, 7914, 7843, 7895, 7896, 7897, 7898, 7843, 7931, 7932, 7933, 7934, 7843, 7863, 7864, 7865, 7866, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, -1]]. +Object config [object id=7848, config id=508, shift=8, childs=[7843, 7842, 7841, 7840, 7843, 7843, 7843, 7843, 7867, 7868, 7869, 7870, 7871, 7899, 7900, 7901, 7902, 7903, 7883, 7884, 7885, 7886, 7887, 7919, 7920, 7921, 7922, 7923, 7851, 7852, 7853, 7854, 7855, 7918, 7917, 7916, 7915, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7872, 7873, 7874, 7875, 7843, 7904, 7905, 7906, 7907, 7843, 7888, 7889, 7890, 7891, 7843, 7924, 7925, 7926, 7927, 7843, 7856, 7857, 7858, 7859, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7876, 7877, 7878, 7843, 7843, 7908, 7909, 7910, 7843, 7843, 7892, 7893, 7894, 7843, 7843, 7928, 7929, 7930, 7843, 7843, 7860, 7861, 7862, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7879, 7880, 7881, 7882, 7843, 7911, 7912, 7913, 7914, 7843, 7895, 7896, 7897, 7898, 7843, 7931, 7932, 7933, 7934, 7843, 7863, 7864, 7865, 7866, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, -1]]. +Object config [object id=7849, config id=508, shift=16, childs=[7843, 7842, 7841, 7840, 7843, 7843, 7843, 7843, 7867, 7868, 7869, 7870, 7871, 7899, 7900, 7901, 7902, 7903, 7883, 7884, 7885, 7886, 7887, 7919, 7920, 7921, 7922, 7923, 7851, 7852, 7853, 7854, 7855, 7918, 7917, 7916, 7915, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7872, 7873, 7874, 7875, 7843, 7904, 7905, 7906, 7907, 7843, 7888, 7889, 7890, 7891, 7843, 7924, 7925, 7926, 7927, 7843, 7856, 7857, 7858, 7859, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7876, 7877, 7878, 7843, 7843, 7908, 7909, 7910, 7843, 7843, 7892, 7893, 7894, 7843, 7843, 7928, 7929, 7930, 7843, 7843, 7860, 7861, 7862, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7879, 7880, 7881, 7882, 7843, 7911, 7912, 7913, 7914, 7843, 7895, 7896, 7897, 7898, 7843, 7931, 7932, 7933, 7934, 7843, 7863, 7864, 7865, 7866, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, 7843, -1]]. +Object config [object id=7771, config id=512, shift=0, childs=[7746, 7745, 7744, 7743, 7746, 7746, 7746, 7746, 7747, 7748, 7749, 7750, 7751, 7752, 7753, 7754, 7755, 7756, 7757, 7759, 7760, 7761, 7762, 7763, 7764, 7765, 7766, 7767, 7768, 7769, 7770, 7758, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, 7746, -1]]. +Object config [object id=7807, config id=507, shift=24, childs=[7775, 7774, 7773, 7772, 7776, 7777, 7778, 7779, 7780, 7781, 7782, 7783, 7784, 7785, 7786, 7787, 7788, 7789, 7790, 7792, 7793, 7794, 7795, 7796, 7797, 7798, 7799, 7800, 7801, 7802, 7803, 7804, 7805, 7806, 7791, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, 7775, -1]]. +Object config [object id=8794, config id=518, shift=8, childs=[8795, 8795, 8795, 8795, 8795, 8795, 8795, 8796, 8796, 8796, 8796, 8796, 8796, 8796, -1]]. +Object config [object id=8877, config id=521, shift=8, childs=[8864, 8863, 8862, 8861, 8865, 8866, 8867, 8868, 8869, -1]]. +Object config [object id=8885, config id=521, shift=13, childs=[5001, -1]]. +Object config [object id=8860, config id=482, shift=26, childs=[6046, -1]]. +Object config [object id=9057, config id=540, shift=20, childs=[9058, 9059, 9060, 9061, 9062, 9063, -1]]. +Object config [object id=9067, config id=540, shift=2, childs=[9064, 9064, 9064, 9068, 9068, -1]]. +Object config [object id=9065, config id=540, shift=8, childs=[9064, 9064, 9064, 9066, 9066, 9066, -1]]. +Object config [object id=9069, config id=540, shift=5, childs=[9064, 9064, 9064, 9071, 9070, -1]]. +Object config [object id=8996, config id=531, shift=10, childs=[8998, 8999, 9000, 9001, 9002, 9003, 9004, 9005, -1]]. +Object config [object id=8997, config id=531, shift=15, childs=[8998, 8999, 9000, 9001, 9002, 9003, 9004, 9005, -1]]. +Object config [object id=8994, config id=531, shift=0, childs=[8998, 8999, 9000, 9001, 9002, 9003, 9004, 9005, -1]]. +Object config [object id=8995, config id=531, shift=5, childs=[8998, 8999, 9000, 9001, 9002, 9003, 9004, 9005, -1]]. +Object config [object id=9209, config id=554, shift=18, childs=[9213, 9212, 9211, 9210, 9214, 9215, 9216, 9217, 9218, 9219, 9220, 9221, 9222, -1]]. +Object config [object id=9198, config id=554, shift=22, childs=[9203, 9204, -1, -1, 9205, 9206, 9207, 9208, -1]]. +Object config [object id=9197, config id=554, shift=15, childs=[9203, 9204, -1, -1, 9199, 9200, 9201, 9202, -1]]. +Object config [object id=9176, config id=554, shift=6, childs=[9180, 9179, 9178, 9177, 9189, 9190, 9195, 9196, -1]]. +Object config [object id=9174, config id=554, shift=3, childs=[9184, 9183, 9182, 9181, 9189, 9190, 9191, 9192, -1]]. +Object config [object id=9175, config id=554, shift=0, childs=[9188, 9187, 9186, 9185, 9189, 9190, 9193, 9194, -1]]. +Object config [object id=9165, config id=554, shift=9, childs=[9169, 9168, 9167, 9166, 9170, 9171, 9172, 9173, -1]]. +Object config [object id=9092, config id=543, shift=8, childs=[9093, 9094, 9095, 9096, -1]]. +Object config [object id=8391, config id=502, shift=24, childs=[8395, 8394, 8393, 8392, 8395, 8395, 8395, 8395, 8462, 8463, 8464, 8465, 8466, 8467, 8468, 8481, 8482, 8483, 8484, 8485, 8486, 8487, 8488, 8489, 8435, 8436, 8437, 8438, 8439, 8440, 8441, 8442, 8443, 8444, 8445, 8502, 8503, 8504, 8505, 8506, 8507, 8508, 8509, 8510, 8511, 8512, 8513, 8514, 8396, 8397, 8398, 8399, 8400, 8401, 8402, 8403, 8404, 8405, 8406, 8407, 8408, 8409, 8410, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8473, 8474, 8475, -1, 8476, 8395, 8395, 8490, 8491, 8492, 8493, 8494, -1, 8495, 8395, 8395, 8446, 8447, 8448, 8449, 8450, 8451, 8452, -1, 8453, 8395, 8395, 8515, 8516, 8517, 8518, 8519, 8520, 8521, 8522, 8523, -1, 8524, 8395, 8395, 8411, 8412, 8413, 8414, 8415, 8416, 8417, 8418, 8419, 8420, 8421, -1, 8422, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8477, 8478, 8479, -1, 8480, 8395, 8395, 8496, 8497, 8498, 8499, 8500, -1, 8501, 8395, 8395, 8454, 8455, 8456, 8457, 8458, 8459, 8460, -1, 8461, 8395, 8395, 8525, 8526, 8527, 8528, 8529, 8530, 8531, 8532, 8533, -1, 8534, 8395, 8395, 8423, 8424, 8425, 8426, 8427, 8428, 8429, 8430, 8431, 8432, 8433, -1, 8434, 8314, 8395, 8488, 8488, 8488, 8488, 8488, 8488, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, -1]]. +Object config [object id=8390, config id=502, shift=16, childs=[8395, 8394, 8393, 8392, 8395, 8395, 8395, 8395, 8462, 8463, 8464, 8465, 8466, 8467, 8468, 8481, 8482, 8483, 8484, 8485, 8486, 8487, 8488, 8489, 8435, 8436, 8437, 8438, 8439, 8440, 8441, 8442, 8443, 8444, 8445, 8502, 8503, 8504, 8505, 8506, 8507, 8508, 8509, 8510, 8511, 8512, 8513, 8514, 8396, 8397, 8398, 8399, 8400, 8401, 8402, 8403, 8404, 8405, 8406, 8407, 8408, 8409, 8410, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8473, 8474, 8475, -1, 8476, 8395, 8395, 8490, 8491, 8492, 8493, 8494, -1, 8495, 8395, 8395, 8446, 8447, 8448, 8449, 8450, 8451, 8452, -1, 8453, 8395, 8395, 8515, 8516, 8517, 8518, 8519, 8520, 8521, 8522, 8523, -1, 8524, 8395, 8395, 8411, 8412, 8413, 8414, 8415, 8416, 8417, 8418, 8419, 8420, 8421, -1, 8422, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8477, 8478, 8479, -1, 8480, 8395, 8395, 8496, 8497, 8498, 8499, 8500, -1, 8501, 8395, 8395, 8454, 8455, 8456, 8457, 8458, 8459, 8460, -1, 8461, 8395, 8395, 8525, 8526, 8527, 8528, 8529, 8530, 8531, 8532, 8533, -1, 8534, 8395, 8395, 8423, 8424, 8425, 8426, 8427, 8428, 8429, 8430, 8431, 8432, 8433, -1, 8434, 8314, 8395, 8488, 8488, 8488, 8488, 8488, 8488, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, -1]]. +Object config [object id=8389, config id=502, shift=8, childs=[8395, 8394, 8393, 8392, 8395, 8395, 8395, 8395, 8462, 8463, 8464, 8465, 8466, 8467, 8468, 8481, 8482, 8483, 8484, 8485, 8486, 8487, 8488, 8489, 8435, 8436, 8437, 8438, 8439, 8440, 8441, 8442, 8443, 8444, 8445, 8502, 8503, 8504, 8505, 8506, 8507, 8508, 8509, 8510, 8511, 8512, 8513, 8514, 8396, 8397, 8398, 8399, 8400, 8401, 8402, 8403, 8404, 8405, 8406, 8407, 8408, 8409, 8410, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8473, 8474, 8475, -1, 8476, 8395, 8395, 8490, 8491, 8492, 8493, 8494, -1, 8495, 8395, 8395, 8446, 8447, 8448, 8449, 8450, 8451, 8452, -1, 8453, 8395, 8395, 8515, 8516, 8517, 8518, 8519, 8520, 8521, 8522, 8523, -1, 8524, 8395, 8395, 8411, 8412, 8413, 8414, 8415, 8416, 8417, 8418, 8419, 8420, 8421, -1, 8422, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8477, 8478, 8479, -1, 8480, 8395, 8395, 8496, 8497, 8498, 8499, 8500, -1, 8501, 8395, 8395, 8454, 8455, 8456, 8457, 8458, 8459, 8460, -1, 8461, 8395, 8395, 8525, 8526, 8527, 8528, 8529, 8530, 8531, 8532, 8533, -1, 8534, 8395, 8395, 8423, 8424, 8425, 8426, 8427, 8428, 8429, 8430, 8431, 8432, 8433, -1, 8434, 8395, 8395, 8488, 8488, 8488, 8488, 8488, 8488, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, -1]]. +Object config [object id=8388, config id=502, shift=0, childs=[8395, 8394, 8393, 8392, 8395, 8395, 8395, 8395, 8462, 8463, 8464, 8465, 8466, 8467, 8468, 8481, 8482, 8483, 8484, 8485, 8486, 8487, 8488, 8489, 8435, 8436, 8437, 8438, 8439, 8440, 8441, 8442, 8443, 8444, 8445, 8502, 8503, 8504, 8505, 8506, 8507, 8508, 8509, 8510, 8511, 8512, 8513, 8514, 8396, 8397, 8398, 8399, 8400, 8401, 8402, 8403, 8404, 8405, 8406, 8407, 8408, 8409, 8410, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8473, 8474, 8475, -1, 8476, 8395, 8395, 8490, 8491, 8492, 8493, 8494, -1, 8495, 8395, 8395, 8446, 8447, 8448, 8449, 8450, 8451, 8452, -1, 8453, 8395, 8395, 8515, 8516, 8517, 8518, 8519, 8520, 8521, 8522, 8523, -1, 8524, 8395, 8395, 8411, 8412, 8413, 8414, 8415, 8416, 8417, 8418, 8419, 8420, 8421, -1, 8422, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8477, 8478, 8479, -1, 8480, 8395, 8395, 8496, 8497, 8498, 8499, 8500, -1, 8501, 8395, 8395, 8454, 8455, 8456, 8457, 8458, 8459, 8460, -1, 8461, 8395, 8395, 8525, 8526, 8527, 8528, 8529, 8530, 8531, 8532, 8533, -1, 8534, 8395, 8395, 8423, 8424, 8425, 8426, 8427, 8428, 8429, 8430, 8431, 8432, 8433, -1, 8434, 8395, 8395, 8488, 8488, 8488, 8488, 8488, 8488, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, -1]]. +Object config [object id=8387, config id=502, shift=24, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 8469, 8470, 8470, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 8471, -1, 8472, -1]]. +Object config [object id=8386, config id=502, shift=16, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 8469, 8470, 8470, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 8471, -1, 8472, -1]]. +Object config [object id=8385, config id=502, shift=8, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 8469, 8470, 8470, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 8471, -1, 8472, -1]]. +Object config [object id=8384, config id=502, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 8469, 8470, 8470, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 8471, -1, 8472, -1]]. +Object config [object id=8338, config id=507, shift=0, childs=[8342, 8341, 8340, 8339, 8342, 8342, 8342, 8342, 8343, 8344, 8345, 8346, 8347, 8348, 8349, 8350, 8351, 8352, 8353, 8354, 8355, 8358, 8359, 8360, 8361, 8362, 8363, 8364, 8365, 8366, 8367, 8368, 8370, 8371, 8372, 8373, 8374, 8375, 8376, 8377, 8378, 8379, 8380, 8381, 8356, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, -1]]. +Object config [object id=8337, config id=512, shift=8, childs=[8314, 8313, 8312, 8311, 8315, 8316, 8317, 8318, 8319, 8320, 8321, 8322, 8323, 8324, 8325, 8326, 8327, 8328, 8329, 8330, 8331, 8332, 8333, 8334, 8335, 8336, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, 8314, -1]]. +Object config [object id=8382, config id=507, shift=8, childs=[8342, 8341, 8340, 8339, 8342, 8342, 8342, 8342, 8343, 8344, 8345, 8346, 8347, 8348, 8349, 8350, 8351, 8352, 8353, 8354, 8355, 8358, 8359, 8360, 8361, 8362, 8363, 8364, 8365, 8366, 8367, 8368, 8370, 8371, 8372, 8373, 8374, 8375, 8376, 8377, 8378, 8379, 8380, 8381, 8356, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, -1]]. +Object config [object id=8383, config id=507, shift=16, childs=[8342, 8341, 8340, 8339, 8342, 8342, 8342, 8342, 8343, 8344, 8345, 8346, 8347, 8348, 8349, 8350, 8351, 8352, 8353, 8354, 8355, 8358, 8359, 8360, 8361, 8362, 8363, 8364, 8365, 8366, 8367, 8368, 8370, 8371, 8372, 8373, 8374, 8375, 8376, 8377, 8378, 8379, 8380, 8381, 8356, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, 8342, -1]]. +Object config [object id=8550, config id=504, shift=0, childs=[8576, 8575, 8574, 8573, 8576, 8576, 8558, 8559, 8560, 8561, 8562, 8562, 8562, 8580, 8581, 8582, 8583, 8584, 8584, 8584, 8535, 8536, 8537, 8538, 8539, 8539, 8539, 8641, 8642, 8643, 8644, 8645, 8645, 8645, 8618, 8619, 8620, 8621, 8622, 8623, 8624, 8624, 8624, 8595, 8596, 8597, 8598, 8599, 8600, 8601, 8601, 8601, 8656, 8657, 8658, 8659, 8660, 8661, 8662, 8663, 8664, 8664, 8664, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8563, 8564, 8565, 8566, 8576, 8576, 8576, 8585, 8586, 8587, 8588, 8576, 8576, 8576, 8540, 8541, 8542, 8543, 8576, 8576, 8576, 8646, 8647, 8648, 8649, 8576, 8576, 8576, 8625, 8626, 8627, 8628, 8629, 8630, 8576, 8576, 8576, 8602, 8603, 8604, 8605, 8606, 8607, 8576, 8576, 8576, 8665, 8666, 8667, 8668, 8669, 8670, 8671, 8672, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8567, 8568, 8569, 8576, 8576, 8576, 8576, 8589, 8590, 8591, 8576, 8576, 8576, 8576, 8544, 8545, 8546, 8576, 8576, 8576, 8576, 8650, 8651, 8652, 8576, 8576, 8576, 8576, 8631, 8632, 8633, 8634, 8635, 8576, 8576, 8576, 8576, 8608, 8609, 8610, 8611, 8612, 8576, 8576, 8576, 8576, 8673, 8674, 8675, 8676, 8677, 8678, 8679, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8570, 8571, 8572, 8576, 8576, 8576, 8576, 8592, 8593, 8594, 8576, 8576, 8576, 8576, 8547, 8548, 8549, 8576, 8576, 8576, 8576, 8653, 8654, 8655, 8576, 8576, 8576, 8576, 8636, 8637, 8638, 8639, 8640, 8576, 8576, 8576, 8576, 8613, 8614, 8615, 8616, 8617, 8576, 8576, 8576, 8576, 8680, 8681, 8682, 8683, 8684, 8685, 8686, 8576, 8576, 8576, 8576, -1]]. +Object config [object id=8551, config id=504, shift=8, childs=[8576, 8575, 8574, 8573, 8576, 8576, 8558, 8559, 8560, 8561, 8562, 8562, 8562, 8580, 8581, 8582, 8583, 8584, 8584, 8584, 8535, 8536, 8537, 8538, 8539, 8539, 8539, 8641, 8642, 8643, 8644, 8645, 8645, 8645, 8618, 8619, 8620, 8621, 8622, 8623, 8624, 8624, 8624, 8595, 8596, 8597, 8598, 8599, 8600, 8601, 8601, 8601, 8656, 8657, 8658, 8659, 8660, 8661, 8662, 8663, 8664, 8664, 8664, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8563, 8564, 8565, 8566, 8576, 8576, 8576, 8585, 8586, 8587, 8588, 8576, 8576, 8576, 8540, 8541, 8542, 8543, 8576, 8576, 8576, 8646, 8647, 8648, 8649, 8576, 8576, 8576, 8625, 8626, 8627, 8628, 8629, 8630, 8576, 8576, 8576, 8602, 8603, 8604, 8605, 8606, 8607, 8576, 8576, 8576, 8665, 8666, 8667, 8668, 8669, 8670, 8671, 8672, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8567, 8568, 8569, 8576, 8576, 8576, 8576, 8589, 8590, 8591, 8576, 8576, 8576, 8576, 8544, 8545, 8546, 8576, 8576, 8576, 8576, 8650, 8651, 8652, 8576, 8576, 8576, 8576, 8631, 8632, 8633, 8634, 8635, 8576, 8576, 8576, 8576, 8608, 8609, 8610, 8611, 8612, 8576, 8576, 8576, 8576, 8673, 8674, 8675, 8676, 8677, 8678, 8679, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8570, 8571, 8572, 8576, 8576, 8576, 8576, 8592, 8593, 8594, 8576, 8576, 8576, 8576, 8547, 8548, 8549, 8576, 8576, 8576, 8576, 8653, 8654, 8655, 8576, 8576, 8576, 8576, 8636, 8637, 8638, 8639, 8640, 8576, 8576, 8576, 8576, 8613, 8614, 8615, 8616, 8617, 8576, 8576, 8576, 8576, 8680, 8681, 8682, 8683, 8684, 8685, 8686, 8576, 8576, 8576, 8576, -1]]. +Object config [object id=8556, config id=505, shift=16, childs=[8579, 8578, 8577, 8573, 8579, 8579, 8558, 8559, 8560, 8561, 8562, 8562, 8562, 8580, 8581, 8582, 8583, 8584, 8584, 8584, 8535, 8536, 8537, 8538, 8539, 8539, 8539, 8641, 8642, 8643, 8644, 8645, 8645, 8645, 8618, 8619, 8620, 8621, 8622, 8623, 8624, 8624, 8624, 8595, 8596, 8597, 8598, 8599, 8600, 8601, 8601, 8601, 8656, 8657, 8658, 8659, 8660, 8661, 8662, 8663, 8664, 8664, 8664, 8579, 8579, 8579, 8579, 8579, 8579, 8579, 8563, 8564, 8565, 8566, 8579, 8579, 8579, 8585, 8586, 8587, 8588, 8579, 8579, 8579, 8540, 8541, 8542, 8543, 8579, 8579, 8579, 8646, 8647, 8648, 8649, 8579, 8579, 8579, 8625, 8626, 8627, 8628, 8629, 8630, 8579, 8579, 8579, 8602, 8603, 8604, 8605, 8606, 8607, 8579, 8579, 8579, 8665, 8666, 8667, 8668, 8669, 8670, 8671, 8672, 8579, 8579, 8579, 8579, 8579, 8579, 8579, 8579, 8579, 8579, 8579, 8567, 8568, 8569, 8579, 8579, 8579, 8579, 8589, 8590, 8591, 8579, 8579, 8579, 8579, 8544, 8545, 8546, 8579, 8579, 8579, 8579, 8650, 8651, 8652, 8579, 8579, 8579, 8579, 8631, 8632, 8633, 8634, 8635, 8579, 8579, 8579, 8579, 8608, 8609, 8610, 8611, 8612, 8579, 8579, 8579, 8579, 8673, 8674, 8675, 8676, 8677, 8678, 8679, 8579, 8579, 8579, 8579, 8579, 8579, 8579, 8579, 8579, 8579, 8579, 8570, 8571, 8572, 8579, 8579, 8579, 8579, 8592, 8593, 8594, 8579, 8579, 8579, 8579, 8547, 8548, 8549, 8579, 8579, 8579, 8579, 8653, 8654, 8655, 8579, 8579, 8579, 8579, 8636, 8637, 8638, 8639, 8640, 8579, 8579, 8579, 8579, 8613, 8614, 8615, 8616, 8617, 8579, 8579, 8579, 8579, 8680, 8681, 8682, 8683, 8684, 8685, 8686, 8579, 8579, 8579, 8579, -1]]. +Object config [object id=8557, config id=505, shift=24, childs=[8579, 8578, 8577, 8573, 8579, 8579, 8558, 8559, 8560, 8561, 8562, 8562, 8562, 8580, 8581, 8582, 8583, 8584, 8584, 8584, 8535, 8536, 8537, 8538, 8539, 8539, 8539, 8641, 8642, 8643, 8644, 8645, 8645, 8645, 8618, 8619, 8620, 8621, 8622, 8623, 8624, 8624, 8624, 8595, 8596, 8597, 8598, 8599, 8600, 8601, 8601, 8601, 8656, 8657, 8658, 8659, 8660, 8661, 8662, 8663, 8664, 8664, 8664, 8579, 8579, 8579, 8579, 8579, 8579, 8579, 8563, 8564, 8565, 8566, 8579, 8579, 8579, 8585, 8586, 8587, 8588, 8579, 8579, 8579, 8540, 8541, 8542, 8543, 8579, 8579, 8579, 8646, 8647, 8648, 8649, 8579, 8579, 8579, 8625, 8626, 8627, 8628, 8629, 8630, 8579, 8579, 8579, 8602, 8603, 8604, 8605, 8606, 8607, 8579, 8579, 8579, 8665, 8666, 8667, 8668, 8669, 8670, 8671, 8672, 8579, 8579, 8579, 8579, 8579, 8579, 8579, 8579, 8579, 8579, 8579, 8567, 8568, 8569, 8579, 8579, 8579, 8579, 8589, 8590, 8591, 8579, 8579, 8579, 8579, 8544, 8545, 8546, 8579, 8579, 8579, 8579, 8650, 8651, 8652, 8579, 8579, 8579, 8579, 8631, 8632, 8633, 8634, 8635, 8579, 8579, 8579, 8579, 8608, 8609, 8610, 8611, 8612, 8579, 8579, 8579, 8579, 8673, 8674, 8675, 8676, 8677, 8678, 8679, 8579, 8579, 8579, 8579, 8579, 8579, 8579, 8579, 8579, 8579, 8579, 8570, 8571, 8572, 8579, 8579, 8579, 8579, 8592, 8593, 8594, 8579, 8579, 8579, 8579, 8547, 8548, 8549, 8579, 8579, 8579, 8579, 8653, 8654, 8655, 8579, 8579, 8579, 8579, 8636, 8637, 8638, 8639, 8640, 8579, 8579, 8579, 8579, 8613, 8614, 8615, 8616, 8617, 8579, 8579, 8579, 8579, 8680, 8681, 8682, 8683, 8684, 8685, 8686, 8579, 8579, 8579, 8579, -1]]. +Object config [object id=8554, config id=505, shift=0, childs=[8576, 8575, 8574, 8573, 8576, 8576, 8558, 8559, 8560, 8561, 8562, 8562, 8562, 8580, 8581, 8582, 8583, 8584, 8584, 8584, 8535, 8536, 8537, 8538, 8539, 8539, 8539, 8641, 8642, 8643, 8644, 8645, 8645, 8645, 8618, 8619, 8620, 8621, 8622, 8623, 8624, 8624, 8624, 8595, 8596, 8597, 8598, 8599, 8600, 8601, 8601, 8601, 8656, 8657, 8658, 8659, 8660, 8661, 8662, 8663, 8664, 8664, 8664, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8563, 8564, 8565, 8566, 8576, 8576, 8576, 8585, 8586, 8587, 8588, 8576, 8576, 8576, 8540, 8541, 8542, 8543, 8576, 8576, 8576, 8646, 8647, 8648, 8649, 8576, 8576, 8576, 8625, 8626, 8627, 8628, 8629, 8630, 8576, 8576, 8576, 8602, 8603, 8604, 8605, 8606, 8607, 8576, 8576, 8576, 8665, 8666, 8667, 8668, 8669, 8670, 8671, 8672, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8567, 8568, 8569, 8576, 8576, 8576, 8576, 8589, 8590, 8591, 8576, 8576, 8576, 8576, 8544, 8545, 8546, 8576, 8576, 8576, 8576, 8650, 8651, 8652, 8576, 8576, 8576, 8576, 8631, 8632, 8633, 8634, 8635, 8576, 8576, 8576, 8576, 8608, 8609, 8610, 8611, 8612, 8576, 8576, 8576, 8576, 8673, 8674, 8675, 8676, 8677, 8678, 8679, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8570, 8571, 8572, 8576, 8576, 8576, 8576, 8592, 8593, 8594, 8576, 8576, 8576, 8576, 8547, 8548, 8549, 8576, 8576, 8576, 8576, 8653, 8654, 8655, 8576, 8576, 8576, 8576, 8636, 8637, 8638, 8639, 8640, 8576, 8576, 8576, 8576, 8613, 8614, 8615, 8616, 8617, 8576, 8576, 8576, 8576, 8680, 8681, 8682, 8683, 8684, 8685, 8686, 8576, 8576, 8576, 8576, -1]]. +Object config [object id=8555, config id=505, shift=8, childs=[8576, 8575, 8574, 8573, 8576, 8576, 8558, 8559, 8560, 8561, 8562, 8562, 8562, 8580, 8581, 8582, 8583, 8584, 8584, 8584, 8535, 8536, 8537, 8538, 8539, 8539, 8539, 8641, 8642, 8643, 8644, 8645, 8645, 8645, 8618, 8619, 8620, 8621, 8622, 8623, 8624, 8624, 8624, 8595, 8596, 8597, 8598, 8599, 8600, 8601, 8601, 8601, 8656, 8657, 8658, 8659, 8660, 8661, 8662, 8663, 8664, 8664, 8664, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8563, 8564, 8565, 8566, 8576, 8576, 8576, 8585, 8586, 8587, 8588, 8576, 8576, 8576, 8540, 8541, 8542, 8543, 8576, 8576, 8576, 8646, 8647, 8648, 8649, 8576, 8576, 8576, 8625, 8626, 8627, 8628, 8629, 8630, 8576, 8576, 8576, 8602, 8603, 8604, 8605, 8606, 8607, 8576, 8576, 8576, 8665, 8666, 8667, 8668, 8669, 8670, 8671, 8672, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8567, 8568, 8569, 8576, 8576, 8576, 8576, 8589, 8590, 8591, 8576, 8576, 8576, 8576, 8544, 8545, 8546, 8576, 8576, 8576, 8576, 8650, 8651, 8652, 8576, 8576, 8576, 8576, 8631, 8632, 8633, 8634, 8635, 8576, 8576, 8576, 8576, 8608, 8609, 8610, 8611, 8612, 8576, 8576, 8576, 8576, 8673, 8674, 8675, 8676, 8677, 8678, 8679, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8570, 8571, 8572, 8576, 8576, 8576, 8576, 8592, 8593, 8594, 8576, 8576, 8576, 8576, 8547, 8548, 8549, 8576, 8576, 8576, 8576, 8653, 8654, 8655, 8576, 8576, 8576, 8576, 8636, 8637, 8638, 8639, 8640, 8576, 8576, 8576, 8576, 8613, 8614, 8615, 8616, 8617, 8576, 8576, 8576, 8576, 8680, 8681, 8682, 8683, 8684, 8685, 8686, 8576, 8576, 8576, 8576, -1]]. +Object config [object id=8552, config id=504, shift=16, childs=[8576, 8575, 8574, 8573, 8576, 8576, 8558, 8559, 8560, 8561, 8562, 8562, 8562, 8580, 8581, 8582, 8583, 8584, 8584, 8584, 8535, 8536, 8537, 8538, 8539, 8539, 8539, 8641, 8642, 8643, 8644, 8645, 8645, 8645, 8618, 8619, 8620, 8621, 8622, 8623, 8624, 8624, 8624, 8595, 8596, 8597, 8598, 8599, 8600, 8601, 8601, 8601, 8656, 8657, 8658, 8659, 8660, 8661, 8662, 8663, 8664, 8664, 8664, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8563, 8564, 8565, 8566, 8576, 8576, 8576, 8585, 8586, 8587, 8588, 8576, 8576, 8576, 8540, 8541, 8542, 8543, 8576, 8576, 8576, 8646, 8647, 8648, 8649, 8576, 8576, 8576, 8625, 8626, 8627, 8628, 8629, 8630, 8576, 8576, 8576, 8602, 8603, 8604, 8605, 8606, 8607, 8576, 8576, 8576, 8665, 8666, 8667, 8668, 8669, 8670, 8671, 8672, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8567, 8568, 8569, 8576, 8576, 8576, 8576, 8589, 8590, 8591, 8576, 8576, 8576, 8576, 8544, 8545, 8546, 8576, 8576, 8576, 8576, 8650, 8651, 8652, 8576, 8576, 8576, 8576, 8631, 8632, 8633, 8634, 8635, 8576, 8576, 8576, 8576, 8608, 8609, 8610, 8611, 8612, 8576, 8576, 8576, 8576, 8673, 8674, 8675, 8676, 8677, 8678, 8679, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8570, 8571, 8572, 8576, 8576, 8576, 8576, 8592, 8593, 8594, 8576, 8576, 8576, 8576, 8547, 8548, 8549, 8576, 8576, 8576, 8576, 8653, 8654, 8655, 8576, 8576, 8576, 8576, 8636, 8637, 8638, 8639, 8640, 8576, 8576, 8576, 8576, 8613, 8614, 8615, 8616, 8617, 8576, 8576, 8576, 8576, 8680, 8681, 8682, 8683, 8684, 8685, 8686, 8576, 8576, 8576, 8576, -1]]. +Object config [object id=8553, config id=504, shift=24, childs=[8576, 8575, 8574, 8573, 8576, 8576, 8558, 8559, 8560, 8561, 8562, 8562, 8562, 8580, 8581, 8582, 8583, 8584, 8584, 8584, 8535, 8536, 8537, 8538, 8539, 8539, 8539, 8641, 8642, 8643, 8644, 8645, 8645, 8645, 8618, 8619, 8620, 8621, 8622, 8623, 8624, 8624, 8624, 8595, 8596, 8597, 8598, 8599, 8600, 8601, 8601, 8601, 8656, 8657, 8658, 8659, 8660, 8661, 8662, 8663, 8664, 8664, 8664, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8563, 8564, 8565, 8566, 8576, 8576, 8576, 8585, 8586, 8587, 8588, 8576, 8576, 8576, 8540, 8541, 8542, 8543, 8576, 8576, 8576, 8646, 8647, 8648, 8649, 8576, 8576, 8576, 8625, 8626, 8627, 8628, 8629, 8630, 8576, 8576, 8576, 8602, 8603, 8604, 8605, 8606, 8607, 8576, 8576, 8576, 8665, 8666, 8667, 8668, 8669, 8670, 8671, 8672, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8567, 8568, 8569, 8576, 8576, 8576, 8576, 8589, 8590, 8591, 8576, 8576, 8576, 8576, 8544, 8545, 8546, 8576, 8576, 8576, 8576, 8650, 8651, 8652, 8576, 8576, 8576, 8576, 8631, 8632, 8633, 8634, 8635, 8576, 8576, 8576, 8576, 8608, 8609, 8610, 8611, 8612, 8576, 8576, 8576, 8576, 8673, 8674, 8675, 8676, 8677, 8678, 8679, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8570, 8571, 8572, 8576, 8576, 8576, 8576, 8592, 8593, 8594, 8576, 8576, 8576, 8576, 8547, 8548, 8549, 8576, 8576, 8576, 8576, 8653, 8654, 8655, 8576, 8576, 8576, 8576, 8636, 8637, 8638, 8639, 8640, 8576, 8576, 8576, 8576, 8613, 8614, 8615, 8616, 8617, 8576, 8576, 8576, 8576, 8680, 8681, 8682, 8683, 8684, 8685, 8686, 8576, 8576, 8576, 8576, -1]]. +Object config [object id=9788, config id=579, shift=9, childs=[9774, 9775, -1]]. +Object config [object id=9785, config id=579, shift=13, childs=[9772, 9775, -1]]. +Object config [object id=9784, config id=579, shift=12, childs=[9772, 9775, -1]]. +Object config [object id=9787, config id=579, shift=8, childs=[9771, 9775, -1]]. +Object config [object id=9786, config id=579, shift=7, childs=[-1, 9774, -1]]. +Object config [object id=9781, config id=579, shift=6, childs=[9773, 9775, -1]]. +Object config [object id=9780, config id=579, shift=5, childs=[9769, 9775, -1]]. +Object config [object id=9783, config id=579, shift=11, childs=[9773, 9775, -1]]. +Object config [object id=9782, config id=579, shift=10, childs=[9773, 9775, -1]]. +Object config [object id=9777, config id=579, shift=1, childs=[9769, 9775, -1]]. +Object config [object id=9776, config id=579, shift=0, childs=[9769, 9775, -1]]. +Object config [object id=9779, config id=579, shift=4, childs=[9771, 9775, -1]]. +Object config [object id=9778, config id=579, shift=3, childs=[9771, 9775, -1]]. +Object config [object id=9750, config id=594, shift=26, childs=[9751, 9752, -1]]. +Object config [object id=9832, config id=592, shift=16, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, 9807, 9808, 9809, 9810, 9811, 9812, 9806, 9821, 9822, 9823, 9824, 9825, 9826, 9820, 9814, 9815, 9816, 9817, 9818, 9819, 9813, -1]]. +Object config [object id=9833, config id=591, shift=16, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, 9807, 9808, 9809, 9810, 9811, 9812, 9806, 9821, 9822, 9823, 9824, 9825, 9826, 9820, 9814, 9815, 9816, 9817, 9818, 9819, 9813, -1]]. +Object config [object id=9834, config id=587, shift=27, childs=[-1, 9821, 9822, 9823, 9824, 9825, 9826, 9820, -1]]. +Object config [object id=9835, config id=591, shift=21, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, 9807, 9808, 9809, 9810, 9811, 9812, 9806, 9821, 9822, 9823, 9824, 9825, 9826, 9820, 9814, 9815, 9816, 9817, 9818, 9819, 9813, -1]]. +Object config [object id=9836, config id=591, shift=26, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, 9807, 9808, 9809, 9810, 9811, 9812, 9806, 9821, 9822, 9823, 9824, 9825, 9826, 9820, 9814, 9815, 9816, 9817, 9818, 9819, 9813, -1]]. +Object config [object id=9837, config id=592, shift=0, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, 9807, 9808, 9809, 9810, 9811, 9812, 9806, 9821, 9822, 9823, 9824, 9825, 9826, 9820, 9814, 9815, 9816, 9817, 9818, 9819, 9813, -1]]. +Object config [object id=9838, config id=585, shift=24, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9839, config id=585, shift=27, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9827, config id=591, shift=0, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, 9807, 9808, 9809, 9810, 9811, 9812, 9806, 9821, 9822, 9823, 9824, 9825, 9826, 9820, 9814, 9815, 9816, 9817, 9818, 9819, 9813, -1]]. +Object config [object id=9828, config id=591, shift=6, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, 9807, 9808, 9809, 9810, 9811, 9812, 9806, 9821, 9822, 9823, 9824, 9825, 9826, 9820, 9814, 9815, 9816, 9817, 9818, 9819, 9813, -1]]. +Object config [object id=9829, config id=591, shift=11, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, 9807, 9808, 9809, 9810, 9811, 9812, 9806, 9821, 9822, 9823, 9824, 9825, 9826, 9820, 9814, 9815, 9816, 9817, 9818, 9819, 9813, -1]]. +Object config [object id=9830, config id=592, shift=6, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, 9807, 9808, 9809, 9810, 9811, 9812, 9806, 9821, 9822, 9823, 9824, 9825, 9826, 9820, 9814, 9815, 9816, 9817, 9818, 9819, 9813, -1]]. +Object config [object id=9831, config id=592, shift=11, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, 9807, 9808, 9809, 9810, 9811, 9812, 9806, 9821, 9822, 9823, 9824, 9825, 9826, 9820, 9814, 9815, 9816, 9817, 9818, 9819, 9813, -1]]. +Object config [object id=9849, config id=580, shift=24, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9848, config id=580, shift=21, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9851, config id=581, shift=0, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9850, config id=580, shift=27, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9853, config id=581, shift=6, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9852, config id=581, shift=3, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9855, config id=581, shift=12, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9854, config id=581, shift=9, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9841, config id=580, shift=0, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9840, config id=592, shift=21, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9843, config id=580, shift=6, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9842, config id=580, shift=3, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9845, config id=580, shift=12, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9844, config id=580, shift=9, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9847, config id=580, shift=18, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9846, config id=580, shift=15, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9798, config id=585, shift=6, childs=[-1, 9790, 9791, 9792, 9793, 9794, 9795, 9789, -1]]. +Object config [object id=9796, config id=584, shift=12, childs=[-1, 9790, 9791, 9792, 9793, 9794, 9795, 9789, -1]]. +Object config [object id=9797, config id=584, shift=24, childs=[-1, 9790, 9791, 9792, 9793, 9794, 9795, 9789, -1]]. +Object config [object id=9893, config id=585, shift=9, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9892, config id=585, shift=6, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9895, config id=585, shift=15, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9894, config id=585, shift=12, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9889, config id=584, shift=27, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9888, config id=584, shift=24, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9891, config id=585, shift=3, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9890, config id=585, shift=0, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9897, config id=585, shift=21, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9896, config id=585, shift=18, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9863, config id=582, shift=6, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9862, config id=582, shift=3, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9861, config id=582, shift=0, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9860, config id=581, shift=27, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9859, config id=581, shift=24, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9858, config id=581, shift=21, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9857, config id=581, shift=18, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9856, config id=581, shift=15, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9871, config id=582, shift=27, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9870, config id=583, shift=0, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9869, config id=582, shift=24, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9868, config id=582, shift=21, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9867, config id=582, shift=12, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9866, config id=582, shift=18, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9865, config id=582, shift=15, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9864, config id=582, shift=9, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9878, config id=583, shift=24, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9879, config id=583, shift=27, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9876, config id=583, shift=18, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9877, config id=583, shift=21, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9874, config id=583, shift=12, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9875, config id=583, shift=15, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9872, config id=583, shift=3, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9873, config id=583, shift=9, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9886, config id=584, shift=18, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9887, config id=584, shift=21, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9884, config id=584, shift=12, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9885, config id=584, shift=15, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9882, config id=584, shift=6, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9883, config id=584, shift=9, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9880, config id=584, shift=0, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9881, config id=584, shift=3, childs=[-1, 9800, 9801, 9802, 9803, 9804, 9805, 9799, -1]]. +Object config [object id=9953, config id=587, shift=18, childs=[9935, 9905, 9910, 9915, 9920, 9925, 9930, 9900, -1]]. +Object config [object id=9952, config id=587, shift=15, childs=[9934, 9904, 9909, 9914, 9919, 9924, 9929, 9899, -1]]. +Object config [object id=9955, config id=587, shift=24, childs=[9935, 9905, 9910, 9915, 9920, 9925, 9930, 9900, -1]]. +Object config [object id=9954, config id=587, shift=21, childs=[9937, 9907, 9912, 9917, 9922, 9927, 9932, 9902, -1]]. +Object config [object id=9957, config id=588, shift=3, childs=[9935, 9905, 9910, 9915, 9920, 9925, 9930, 9900, -1]]. +Object config [object id=9956, config id=588, shift=0, childs=[9933, 9903, 9908, 9913, 9918, 9923, 9928, 9898, -1]]. +Object config [object id=9959, config id=588, shift=18, childs=[9934, 9904, 9909, 9914, 9919, 9924, 9929, 9899, -1]]. +Object config [object id=9958, config id=588, shift=6, childs=[9937, 9907, 9912, 9917, 9922, 9927, 9932, 9902, -1]]. +Object config [object id=9961, config id=588, shift=24, childs=[9935, 9905, 9910, 9915, 9920, 9925, 9930, 9900, -1]]. +Object config [object id=9960, config id=588, shift=21, childs=[9935, 9905, 9910, 9915, 9920, 9925, 9930, 9900, -1]]. +Object config [object id=9963, config id=589, shift=0, childs=[9934, 9904, 9909, 9914, 9919, 9924, 9929, 9899, -1]]. +Object config [object id=9962, config id=588, shift=27, childs=[9934, 9904, 9909, 9914, 9919, 9924, 9929, 9899, -1]]. +Object config [object id=9965, config id=589, shift=6, childs=[9937, 9907, 9912, 9917, 9922, 9927, 9932, 9902, -1]]. +Object config [object id=9964, config id=589, shift=3, childs=[9934, 9904, 9909, 9914, 9919, 9924, 9929, 9899, -1]]. +Object config [object id=9967, config id=589, shift=18, childs=[9934, 9904, 9909, 9914, 9919, 9924, 9929, 9899, -1]]. +Object config [object id=9966, config id=589, shift=12, childs=[9934, 9904, 9909, 9914, 9919, 9924, 9929, 9899, -1]]. +Object config [object id=9968, config id=589, shift=21, childs=[9937, 9907, 9912, 9917, 9922, 9927, 9932, 9902, -1]]. +Object config [object id=9969, config id=589, shift=24, childs=[9936, 9906, 9911, 9916, 9921, 9926, 9931, 9901, -1]]. +Object config [object id=9970, config id=589, shift=27, childs=[9935, 9905, 9910, 9915, 9920, 9925, 9930, 9900, -1]]. +Object config [object id=9971, config id=590, shift=3, childs=[9934, 9904, 9909, 9914, 9919, 9924, 9929, 9899, -1]]. +Object config [object id=9972, config id=590, shift=6, childs=[9935, 9905, 9910, 9915, 9920, 9925, 9930, 9900, -1]]. +Object config [object id=9974, config id=594, shift=25, childs=[9976, 9975, -1]]. +Object config [object id=9938, config id=584, shift=12, childs=[9937, 9907, 9912, 9917, 9922, 9927, 9932, 9902, -1]]. +Object config [object id=9939, config id=584, shift=24, childs=[9937, 9907, 9912, 9917, 9922, 9927, 9932, 9902, -1]]. +Object config [object id=9942, config id=586, shift=6, childs=[9934, 9904, 9909, 9914, 9919, 9924, 9929, 9899, -1]]. +Object config [object id=9943, config id=586, shift=12, childs=[9937, 9907, 9912, 9917, 9922, 9927, 9932, 9902, -1]]. +Object config [object id=9940, config id=585, shift=6, childs=[9937, 9907, 9912, 9917, 9922, 9927, 9932, 9902, -1]]. +Object config [object id=9941, config id=586, shift=0, childs=[9935, 9905, 9910, 9915, 9920, 9925, 9930, 9900, -1]]. +Object config [object id=9946, config id=586, shift=21, childs=[9937, 9907, 9912, 9917, 9922, 9927, 9932, 9902, -1]]. +Object config [object id=9947, config id=586, shift=24, childs=[9936, 9906, 9911, 9916, 9921, 9926, 9931, 9901, -1]]. +Object config [object id=9944, config id=586, shift=15, childs=[9936, 9906, 9911, 9916, 9921, 9926, 9931, 9901, -1]]. +Object config [object id=9945, config id=586, shift=18, childs=[9935, 9905, 9910, 9915, 9920, 9925, 9930, 9900, -1]]. +Object config [object id=9950, config id=587, shift=6, childs=[9935, 9905, 9910, 9915, 9920, 9925, 9930, 9900, -1]]. +Object config [object id=9951, config id=587, shift=12, childs=[9934, 9904, 9909, 9914, 9919, 9924, 9929, 9899, -1]]. +Object config [object id=9948, config id=586, shift=27, childs=[9935, 9905, 9910, 9915, 9920, 9925, 9930, 9900, -1]]. +Object config [object id=9949, config id=587, shift=0, childs=[9934, 9904, 9909, 9914, 9919, 9924, 9929, 9899, -1]]. +Object config [object id=10040, config id=594, shift=23, childs=[-1, 10038, -1]]. +Object config [object id=10039, config id=594, shift=23, childs=[-1, 10037, -1]]. +Object config [object id=10104, config id=601, shift=5, childs=[10142, 10143, 10144, -1]]. +Object config [object id=10096, config id=601, shift=29, childs=[10097, 10098, 10099, 10100, 10101, 10102, -1]]. +Object config [object id=10069, config id=531, shift=2, childs=[10075, 10072, 10073, 10074, -1]]. +Object config [object id=10068, config id=531, shift=0, childs=[10075, 10072, 10073, 10074, -1]]. +Object config [object id=10071, config id=531, shift=6, childs=[10075, 10072, 10073, 10074, -1]]. +Object config [object id=10070, config id=531, shift=4, childs=[10075, 10072, 10073, 10074, -1]]. +Object config [object id=10164, config id=601, shift=1, childs=[10166, 10166, 10166, 10166, 10166, 10165, -1]]. +Object config [object id=9223, config id=554, shift=12, childs=[9227, 9226, 9225, 9224, 9228, 9229, 9230, 9231, -1]]. +Object config [object id=9232, config id=554, shift=25, childs=[9236, 9235, 9234, 9233, 9237, 9238, 9239, 9240, -1]]. +Object config [object id=9260, config id=1225, shift=0, childs=[30806, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30806, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30806, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30807, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30804, -1, -1, -1, -1, 30804, -1, -1, -1, 30804, 30806, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30806, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30806, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30806, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30806, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30806, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30806, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30806, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30806, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30806, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30806, -1]]. +Object config [object id=9250, config id=553, shift=7, childs=[9243, 9241, 9241, -1]]. +Object config [object id=9251, config id=553, shift=9, childs=[5789, 9244, 9244, -1]]. +Object config [object id=9252, config id=553, shift=9, childs=[9248, 9248, 9249, 9249, -1]]. +Object config [object id=9253, config id=553, shift=7, childs=[9246, 9246, 9247, 9247, -1]]. +Object config [object id=9254, config id=554, shift=28, childs=[9256, 9256, 9256, 9256, 9255, 9255, -1]]. +Object config [object id=9399, config id=568, shift=17, childs=[9402, 9401, 9400, 9403, 9404, 9405, 9406, 9407, 9408, -1]]. +Object config [object id=9438, config id=568, shift=7, childs=[9437, 9436, -1]]. +Object config [object id=9435, config id=568, shift=10, childs=[9430, 9431, 9432, 9433, 9434, 9431, -1]]. +Object config [object id=9442, config id=568, shift=8, childs=[9440, 9441, 9439, -1]]. +Object config [object id=11006, config id=642, shift=1, childs=[11007, 879, -1]]. +Object config [object id=10987, config id=642, shift=0, childs=[10988, 10988, 10988, 10988, 10988, 10988, 10988, 10988, 10988, 10988, 10988, 10988, 10988, 10988, 10988, 10988, 10989, 10990, 10991, 10994, 10993, 10996, 10998, 11002, 10992, 10995, 10997, 11003, 10999, 11001, 11000, 11004, -1]]. +Object config [object id=10970, config id=642, shift=16, childs=[-1, -1, -1, 10986, -1, -1, -1, 10985, -1, -1, -1, 10984, -1, -1, -1, 10981, -1, -1, -1, 10983, -1, -1, -1, 10980, -1, -1, -1, 10978, -1, -1, -1, 10975, -1, -1, -1, 10982, -1, -1, -1, 10979, -1, -1, -1, 10977, -1, -1, -1, 10974, -1, -1, -1, 10976, -1, -1, -1, 10973, -1, -1, -1, 10972, -1, -1, -1, 10971, -1]]. +Object config [object id=10952, config id=642, shift=13, childs=[10954, 10955, 10956, 10957, 10958, 10959, 10960, 10961, -1, -1, -1, -1, 10962, 10963, 10964, 10965, -1, -1, -1, -1, 10966, 10967, 10968, 10969, -1, -1, -1, -1, 10953, 10953, 10953, 10953, -1]]. +Object config [object id=10881, config id=640, shift=8, childs=[10876, 10875, -1]]. +Object config [object id=10880, config id=640, shift=7, childs=[10876, 10875, -1]]. +Object config [object id=10869, config id=640, shift=9, childs=[10871, 10870, -1]]. +Object config [object id=10873, config id=640, shift=0, childs=[10874, 10874, 10874, -1, 10874, 10874, -1]]. +Object config [object id=10872, config id=640, shift=0, childs=[10874, -1, 10874, 10874, 10874, 10874, -1]]. +Object config [object id=10877, config id=640, shift=4, childs=[10876, 10875, -1]]. +Object config [object id=10879, config id=640, shift=6, childs=[10876, 10875, -1]]. +Object config [object id=10878, config id=640, shift=5, childs=[10876, 10875, -1]]. +Object config [object id=10822, config id=638, shift=5, childs=[10820, 10820, -1]]. +Object config [object id=10823, config id=638, shift=5, childs=[10820, -1]]. +Object config [object id=10821, config id=638, shift=5, childs=[10820, 10820, 10820, -1]]. +Object config [object id=10806, config id=636, shift=2, childs=[10807, 10808, -1]]. +Object config [object id=10812, config id=636, shift=3, childs=[9516, 10813, -1]]. +Object config [object id=11242, config id=657, shift=15, childs=[-1, 11316, -1]]. +Object config [object id=11241, config id=657, shift=14, childs=[-1, 11316, -1]]. +Object config [object id=11233, config id=658, shift=11, childs=[11234, 11235, -1]]. +Object config [object id=11237, config id=657, shift=4, childs=[11238, 11239, 11315, -1]]. +Object config [object id=11213, config id=656, shift=1, childs=[11214, 11215, 11216, 11217, -1]]. +Object config [object id=11224, config id=656, shift=28, childs=[11250, 23553, 23553, 23553, -1]]. +Object config [object id=11225, config id=656, shift=28, childs=[11250, 11250, 23553, 23553, -1]]. +Object config [object id=11226, config id=656, shift=28, childs=[11250, 11250, 11250, 23553, -1]]. +Object config [object id=11227, config id=658, shift=9, childs=[11228, 11229, -1]]. +Object config [object id=11230, config id=658, shift=10, childs=[11231, 11232, -1]]. +Object config [object id=11218, config id=656, shift=27, childs=[11219, 11220, -1]]. +Object config [object id=11221, config id=657, shift=2, childs=[11317, 11318, 11319, -1]]. +Object config [object id=11222, config id=657, shift=6, childs=[11317, 11318, 11319, -1]]. +Object config [object id=11223, config id=657, shift=8, childs=[11317, 11318, 11319, -1]]. +Object config [object id=11046, config id=642, shift=25, childs=[11049, 11050, -1]]. +Object config [object id=11047, config id=642, shift=26, childs=[11049, 11050, -1]]. +Object config [object id=11045, config id=642, shift=24, childs=[11049, 11050, -1]]. +Object config [object id=11048, config id=642, shift=27, childs=[11049, 11050, -1]]. +Object config [object id=11012, config id=642, shift=6, childs=[11017, 11021, -1]]. +Object config [object id=11013, config id=642, shift=7, childs=[11017, 11022, -1]]. +Object config [object id=11014, config id=642, shift=8, childs=[11017, 11023, -1]]. +Object config [object id=11015, config id=642, shift=9, childs=[11019, 11024, -1]]. +Object config [object id=11008, config id=642, shift=2, childs=[11009, 11010, -1]]. +Object config [object id=11011, config id=642, shift=5, childs=[11017, 11020, -1]]. +Object config [object id=11016, config id=642, shift=10, childs=[11018, 11025, -1]]. +Object config [object id=11027, config id=642, shift=28, childs=[11037, 11035, 11033, 11031, 11029, 11039, -1]]. +Object config [object id=11026, config id=642, shift=28, childs=[11036, 11034, 11032, 11030, 11028, 11038, -1]]. +Object config [object id=10394, config id=616, shift=16, childs=[10402, 10404, -1]]. +Object config [object id=10395, config id=616, shift=16, childs=[-1, 10403, -1]]. +Object config [object id=10393, config id=616, shift=16, childs=[10409, 10410, -1]]. +Object config [object id=10398, config id=616, shift=14, childs=[-1, 10403, -1]]. +Object config [object id=10399, config id=616, shift=15, childs=[10407, 10408, -1]]. +Object config [object id=10396, config id=616, shift=14, childs=[10405, 10406, -1]]. +Object config [object id=10397, config id=616, shift=14, childs=[10402, 10404, -1]]. +Object config [object id=10388, config id=616, shift=0, childs=[10437, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10437, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10437, -1, -1, -1, -1, 10437, -1, 10437, -1, -1, 10437, -1, -1, -1, -1, 10437, -1, -1, -1, -1, 10437, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10437, -1, -1, -1, -1, 10437, -1, -1, -1, -1, 10436, -1]]. +Object config [object id=10389, config id=616, shift=0, childs=[10438, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10438, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10438, -1, -1, -1, -1, 10438, -1, 10438, -1, -1, 10438, -1, -1, -1, -1, 10438, -1, -1, -1, -1, 10438, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10438, -1, -1, -1, -1, 10438, -1, -1, -1, -1, 10439, -1]]. +Object config [object id=10401, config id=616, shift=15, childs=[-1, 10403, -1]]. +Object config [object id=10400, config id=616, shift=15, childs=[10402, 10404, -1]]. +Object config [object id=10266, config id=604, shift=20, childs=[10281, 10267, -1]]. +Object config [object id=10270, config id=604, shift=20, childs=[10255, 10271, -1]]. +Object config [object id=10268, config id=604, shift=20, childs=[10282, 10269, -1]]. +Object config [object id=10242, config id=602, shift=0, childs=[6328, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6328, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6328, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6328, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6328, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6328, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10246, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6328, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6328, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6328, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6328, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6328, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6328, -1, -1, -1, 6328, 6328, -1]]. +Object config [object id=10243, config id=602, shift=0, childs=[6329, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6329, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6329, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6329, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6329, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6329, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10247, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6329, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6329, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6329, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6329, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6329, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6329, -1, -1, -1, 6329, 6329, -1]]. +Object config [object id=10244, config id=602, shift=0, childs=[6330, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6330, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6330, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6330, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6330, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6330, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10248, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6330, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6330, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6330, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6330, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6330, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6330, -1, -1, -1, 6330, 6330, -1]]. +Object config [object id=10245, config id=602, shift=0, childs=[6330, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6330, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6330, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6330, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6330, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6330, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10248, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6330, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6330, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6330, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6330, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6330, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6330, -1, -1, -1, 6330, 6330, -1]]. +Object config [object id=10249, config id=602, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10250, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10250, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10250, -1]]. +Object config [object id=10272, config id=604, shift=20, childs=[10280, 10273, -1]]. +Object config [object id=10277, config id=604, shift=20, childs=[10279, 10278, -1]]. +Object config [object id=10284, config id=453, shift=16, childs=[6774, 6775, -1]]. +Object config [object id=10638, config id=622, shift=22, childs=[409, 10639, 10640, -1]]. +Object config [object id=10667, config id=623, shift=11, childs=[10652, 10653, 10654, 10658, 10659, 10660, -1]]. +Object config [object id=10670, config id=623, shift=11, childs=[10671, 10671, 10671, 10671, 10671, 10672, -1]]. +Object config [object id=10669, config id=623, shift=14, childs=[10664, 10666, 10664, -1]]. +Object config [object id=10668, config id=623, shift=11, childs=[10652, 10653, 10654, 10658, 10659, 10660, -1]]. +Object config [object id=10565, config id=617, shift=1, childs=[-1, 10566, -1]]. +Object config [object id=10567, config id=617, shift=2, childs=[-1, 10568, -1]]. +Object config [object id=10563, config id=617, shift=0, childs=[-1, 10564, -1]]. +Object config [object id=10573, config id=617, shift=5, childs=[-1, 10574, -1]]. +Object config [object id=10575, config id=617, shift=6, childs=[-1, 10576, -1]]. +Object config [object id=10569, config id=617, shift=3, childs=[-1, 10570, -1]]. +Object config [object id=10571, config id=617, shift=4, childs=[-1, 10572, -1]]. +Object config [object id=10581, config id=617, shift=9, childs=[-1, 10582, -1]]. +Object config [object id=10577, config id=617, shift=7, childs=[-1, 10578, -1]]. +Object config [object id=10579, config id=617, shift=8, childs=[-1, 10580, -1]]. +Object config [object id=12001, config id=671, shift=0, childs=[12109, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12043, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12043, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12043, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12043, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12043, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12043, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12043, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12043, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12043, -1]]. +Object config [object id=12000, config id=671, shift=0, childs=[12109, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12042, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12042, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12042, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12042, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12042, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12042, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12042, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12042, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12042, -1]]. +Object config [object id=12002, config id=671, shift=22, childs=[-1, 12090, -1]]. +Object config [object id=11998, config id=671, shift=24, childs=[12091, 12092, 12092, -1]]. +Object config [object id=11999, config id=671, shift=0, childs=[12109, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12041, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12041, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12041, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12041, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12041, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12041, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12041, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12041, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12041, -1]]. +Object config [object id=12165, config id=674, shift=16, childs=[12144, 12147, 12148, 12149, 12150, 12151, 12152, 12153, 12154, 12145, 12146, 12155, 12156, 12157, 12158, -1]]. +Object config [object id=12164, config id=674, shift=8, childs=[12144, 12147, 12148, 12149, 12150, 12151, 12152, 12153, 12154, 12145, 12146, 12155, 12156, 12157, 12158, -1]]. +Object config [object id=12167, config id=675, shift=0, childs=[12170, 12170, 12168, 12169, 12171, -1]]. +Object config [object id=12166, config id=674, shift=24, childs=[12144, 12147, 12148, 12149, 12150, 12151, 12152, 12153, 12154, 12145, 12146, 12155, 12156, 12157, 12158, -1]]. +Object config [object id=12163, config id=674, shift=0, childs=[12144, 12147, 12148, 12149, 12150, 12151, 12152, 12153, 12154, 12145, 12146, 12155, 12156, 12157, 12158, -1]]. +Object config [object id=12261, config id=680, shift=22, childs=[12262, 12263, -1]]. +Object config [object id=12266, config id=680, shift=22, childs=[12267, 12268, -1]]. +Object config [object id=12233, config id=1011, shift=0, childs=[24550, 24547, -1]]. +Object config [object id=12232, config id=1011, shift=1, childs=[24550, 24546, -1]]. +Object config [object id=12234, config id=1011, shift=4, childs=[24550, 24548, -1]]. +Object config [object id=12138, config id=1011, shift=2, childs=[24550, 24540, -1]]. +Object config [object id=12139, config id=1011, shift=6, childs=[24543, 24542, -1]]. +Object config [object id=12137, config id=1011, shift=3, childs=[24550, 24539, -1]]. +Object config [object id=11419, config id=667, shift=4, childs=[-1, 11415, -1]]. +Object config [object id=11422, config id=667, shift=4, childs=[11423, 11423, -1]]. +Object config [object id=11420, config id=667, shift=4, childs=[-1, 11411, -1]]. +Object config [object id=11421, config id=667, shift=4, childs=[-1, 11413, -1]]. +Object config [object id=11359, config id=661, shift=0, childs=[-1, 11354, -1]]. +Object config [object id=11355, config id=661, shift=0, childs=[-1, 11354, -1]]. +Object config [object id=11377, config id=666, shift=19, childs=[11390, 11365, 11391, -1]]. +Object config [object id=11376, config id=666, shift=17, childs=[11393, 11364, 11394, -1]]. +Object config [object id=11378, config id=666, shift=21, childs=[11393, 11364, 11394, -1]]. +Object config [object id=11372, config id=666, shift=9, childs=[11393, 11364, 11394, -1]]. +Object config [object id=11373, config id=666, shift=11, childs=[11384, 11367, 11385, -1]]. +Object config [object id=11374, config id=666, shift=13, childs=[11393, 11364, 11394, -1]]. +Object config [object id=11375, config id=666, shift=15, childs=[11387, 11366, 11388, -1]]. +Object config [object id=11368, config id=666, shift=1, childs=[11393, 11364, 11394, -1]]. +Object config [object id=11369, config id=666, shift=3, childs=[11390, 11365, 11391, -1]]. +Object config [object id=11370, config id=666, shift=5, childs=[11393, 11364, 11394, -1]]. +Object config [object id=11371, config id=666, shift=7, childs=[11387, 11366, 11388, -1]]. +Object config [object id=12805, config id=704, shift=21, childs=[12806, 12807, 12808, 12809, -1]]. +Object config [object id=12803, config id=704, shift=23, childs=[12891, 12804, 12804, 12891, -1]]. +Object config [object id=12810, config id=704, shift=21, childs=[-1, -1, -1, 12811, -1]]. +Object config [object id=12947, config id=870, shift=2, childs=[17956, 17957, -1]]. +Object config [object id=12945, config id=870, shift=3, childs=[-1, 17955, -1]]. +Object config [object id=12944, config id=870, shift=0, childs=[17953, 17954, -1]]. +Object config [object id=12633, config id=678, shift=30, childs=[12634, 12635, 12636, 12637, -1]]. +Object config [object id=12610, config id=685, shift=26, childs=[12606, 12607, 12608, 12609, -1]]. +Object config [object id=12549, config id=684, shift=12, childs=[12550, 12551, 12552, 12553, 12554, 12555, -1]]. +Object config [object id=12558, config id=684, shift=16, childs=[12559, 12560, -1]]. +Object config [object id=12795, config id=704, shift=27, childs=[-1, 12796, -1]]. +Object config [object id=12772, config id=704, shift=26, childs=[12773, 12770, -1]]. +Object config [object id=12760, config id=704, shift=17, childs=[12787, 12786, -1]]. +Object config [object id=12762, config id=704, shift=25, childs=[-1, 12763, -1]]. +Object config [object id=12757, config id=704, shift=27, childs=[12893, 12793, -1]]. +Object config [object id=12756, config id=704, shift=27, childs=[12893, 12792, -1]]. +Object config [object id=12759, config id=704, shift=15, childs=[12799, 12798, -1]]. +Object config [object id=12758, config id=704, shift=27, childs=[12893, 12794, -1]]. +Object config [object id=12753, config id=704, shift=27, childs=[12788, 12789, -1]]. +Object config [object id=12752, config id=704, shift=11, childs=[12787, 12786, -1]]. +Object config [object id=12755, config id=704, shift=27, childs=[12788, 12791, -1]]. +Object config [object id=12754, config id=704, shift=27, childs=[12788, 12790, -1]]. +Object config [object id=12751, config id=704, shift=9, childs=[12782, 12783, -1]]. +Object config [object id=12743, config id=704, shift=3, childs=[12744, 12745, -1]]. +Object config [object id=12738, config id=704, shift=2, childs=[12739, 12740, -1]]. +Object config [object id=12354, config id=678, shift=0, childs=[-1, -1, -1, -1, 12355, -1]]. +Object config [object id=12329, config id=679, shift=0, childs=[12318, 12330, -1]]. +Object config [object id=12331, config id=679, shift=1, childs=[-1, 12332, -1]]. +Object config [object id=12333, config id=679, shift=1, childs=[-1, 12334, -1]]. +Object config [object id=12335, config id=679, shift=1, childs=[12318, 12312, -1]]. +Object config [object id=12336, config id=679, shift=2, childs=[12318, 12337, -1]]. +Object config [object id=12338, config id=679, shift=3, childs=[12318, 12339, -1]]. +Object config [object id=12340, config id=679, shift=4, childs=[12318, 12341, -1]]. +Object config [object id=12342, config id=679, shift=5, childs=[12319, 12343, -1]]. +Object config [object id=12344, config id=679, shift=6, childs=[12318, 12345, -1]]. +Object config [object id=12346, config id=679, shift=7, childs=[12318, 12347, -1]]. +Object config [object id=12308, config id=678, shift=0, childs=[-1, -1, -1, 12309, 12309, 12309, -1]]. +Object config [object id=12416, config id=679, shift=15, childs=[12386, 12387, 12387, -1]]. +Object config [object id=12417, config id=679, shift=15, childs=[12378, 12380, 12379, -1]]. +Object config [object id=14172, config id=995, shift=0, childs=[14169, 14171, -1]]. +Object config [object id=13880, config id=710, shift=5, childs=[13881, -1]]. +Object config [object id=13898, config id=710, shift=9, childs=[13899, 13900, -1]]. +Object config [object id=13912, config id=710, shift=10, childs=[13923, 13924, -1]]. +Object config [object id=13907, config id=709, shift=13, childs=[13913, -1]]. +Object config [object id=13910, config id=709, shift=16, childs=[13919, -1]]. +Object config [object id=13911, config id=709, shift=17, childs=[13921, -1]]. +Object config [object id=13908, config id=709, shift=14, childs=[13915, -1]]. +Object config [object id=13909, config id=709, shift=15, childs=[13917, -1]]. +Object config [object id=13968, config id=710, shift=11, childs=[13969, 13970, -1]]. +Object config [object id=13993, config id=710, shift=6, childs=[13994, 13995, 13996, 13997, 13998, -1]]. +Object config [object id=14004, config id=716, shift=21, childs=[14006, 14005, 14007, 14008, 14009, -1]]. +Object config [object id=14001, config id=710, shift=13, childs=[14003, 14002, -1]]. +Object config [object id=15240, config id=731, shift=3, childs=[15230, 15231, 15231, 15231, 15232, 15232, 15232, 15232, 15232, 15232, -1]]. +Object config [object id=15241, config id=731, shift=3, childs=[15233, 15233, 15235, 15236, 15234, 15234, 15234, 15234, 15234, 15234, -1]]. +Object config [object id=15242, config id=731, shift=3, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, 15237, -1]]. +Object config [object id=15238, config id=731, shift=3, childs=[15226, 15226, 15226, 15226, 15227, 15227, 15228, 15229, 15229, 15229, -1]]. +Object config [object id=15239, config id=731, shift=3, childs=[15222, 15222, 15222, 15222, 15222, 15223, 15224, 15225, -1]]. +Object config [object id=15252, config id=731, shift=7, childs=[15217, 15216, -1]]. +Object config [object id=15193, config id=730, shift=10, childs=[15190, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15190, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15190, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15190, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15190, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15190, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15190, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15190, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15190, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15190, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15190, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15190, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15191, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15191, -1]]. +Object config [object id=15203, config id=730, shift=10, childs=[15201, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15201, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15201, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15201, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15201, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15201, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15201, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15201, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15201, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15201, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15201, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15201, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15202, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15202, -1]]. +Object config [object id=15200, config id=730, shift=10, childs=[15198, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15198, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15198, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15198, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15198, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15198, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15198, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15198, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15198, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15198, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15198, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15198, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15199, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15199, -1]]. +Object config [object id=15067, config id=729, shift=11, childs=[15063, 15064, 15065, 15066, -1]]. +Object config [object id=15071, config id=729, shift=13, childs=[15068, 15069, 15070, -1]]. +Object config [object id=15061, config id=728, shift=1, childs=[15052, 15053, -1]]. +Object config [object id=15060, config id=728, shift=0, childs=[15057, -1]]. +Object config [object id=15084, config id=729, shift=18, childs=[15080, 15081, 15082, 15083, -1]]. +Object config [object id=15074, config id=729, shift=15, childs=[15072, 15073, -1]]. +Object config [object id=15079, config id=729, shift=16, childs=[15075, 15076, 15077, 15078, -1]]. +Object config [object id=14934, config id=723, shift=13, childs=[14946, 14949, -1]]. +Object config [object id=14935, config id=723, shift=14, childs=[14947, 14950, -1]]. +Object config [object id=14933, config id=723, shift=12, childs=[14945, 14948, -1]]. +Object config [object id=14939, config id=723, shift=17, childs=[14938, 14938, 14938, 14938, 14938, 14938, -1]]. +Object config [object id=14936, config id=723, shift=15, childs=[14945, 14948, -1]]. +Object config [object id=14937, config id=723, shift=16, childs=[14946, 14949, -1]]. +Object config [object id=14955, config id=723, shift=9, childs=[14958, 14958, 14959, 14960, 14960, -1]]. +Object config [object id=14954, config id=723, shift=9, childs=[14957, 14957, 14957, 14956, 14956, -1]]. +Object config [object id=14908, config id=723, shift=0, childs=[7102, -1, -1, -1, -1, 7102, -1, -1, -1, -1, 7102, -1, -1, -1, -1, 7102, -1, -1, -1, -1, 7102, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7102, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7102, -1]]. +Object config [object id=14909, config id=723, shift=28, childs=[14910, -1]]. +Object config [object id=14911, config id=723, shift=29, childs=[14912, -1]]. +Object config [object id=16316, config id=810, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16305, -1, -1, -1, -1, 16305, -1, -1, -1, -1, 16305, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16305, -1, -1, -1, -1, 16305, -1, -1, -1, -1, 16306, -1, 16305, 16306, -1, 16306, -1, -1, -1, -1, 16304, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16304, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16304, -1]]. +Object config [object id=16315, config id=810, shift=7, childs=[-1, 16224, -1]]. +Object config [object id=16171, config id=160, shift=-1, childs=[16169, 16169, 16170, -1]]. +Object config [object id=16216, config id=810, shift=0, childs=[12060, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12060, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16217, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16217, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16217, -1, -1, -1, -1, 16217, -1, -1, -1, -1, 16217, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16217, -1, -1, -1, -1, 16217, -1, -1, -1, -1, 16217, -1, 16217, 16217, -1, 16217, -1, -1, -1, -1, 16217, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16217, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16217, -1]]. +Object config [object id=16218, config id=810, shift=0, childs=[12061, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12061, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16219, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16219, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16219, -1, -1, -1, -1, 16219, -1, -1, -1, -1, 16219, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16219, -1, -1, -1, -1, 16219, -1, -1, -1, -1, 16219, -1, 16219, 16219, -1, 16219, -1, -1, -1, -1, 16219, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16219, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16219, -1]]. +Object config [object id=16220, config id=810, shift=0, childs=[12062, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12062, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16221, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16221, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16221, -1, -1, -1, -1, 16221, -1, -1, -1, -1, 16221, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16221, -1, -1, -1, -1, 16221, -1, -1, -1, -1, 16221, -1, 16221, 16221, -1, 16221, -1, -1, -1, -1, 16221, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16221, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16221, -1]]. +Object config [object id=16222, config id=810, shift=0, childs=[12063, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12063, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16223, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16223, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16223, -1, -1, -1, -1, 16223, -1, -1, -1, -1, 16223, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16223, -1, -1, -1, -1, 16223, -1, -1, -1, -1, 16223, -1, 16223, 16223, -1, 16223, -1, -1, -1, -1, 16223, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16223, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16223, -1]]. +Object config [object id=16211, config id=810, shift=0, childs=[12064, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12064, -1]]. +Object config [object id=16212, config id=810, shift=0, childs=[12066, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12066, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16213, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16213, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16213, -1, -1, -1, -1, 16213, -1, -1, -1, -1, 16213, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16213, -1, -1, -1, -1, 16213, -1, -1, -1, -1, 16213, -1, 16213, 16213, -1, 16213, -1, -1, -1, -1, 16213, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16213, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16213, -1]]. +Object config [object id=16214, config id=810, shift=0, childs=[12067, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12067, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16215, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16215, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16215, -1, -1, -1, -1, 16215, -1, -1, -1, -1, 16215, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16215, -1, -1, -1, -1, 16215, -1, -1, -1, -1, 16215, -1, 16215, 16215, -1, 16215, -1, -1, -1, -1, 16215, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16215, -1, -1, -1, -1, -1, -1, -1, -1, -1, 16215, -1]]. +Object config [object id=16026, config id=798, shift=3, childs=[15924, 15924, 15926, -1]]. +Object config [object id=16025, config id=798, shift=1, childs=[15924, 15924, 15926, -1]]. +Object config [object id=15763, config id=794, shift=0, childs=[15749, 15749, 15749, 15749, 15749, 15749, 15749, 15749, 15749, 15749, 15749, 15749, 15749, 15748, -1]]. +Object config [object id=15765, config id=794, shift=0, childs=[15752, 15752, 15752, 15752, 15752, 15752, 15752, 15753, 15753, 15753, 15753, 15753, 15753, 15753, 15753, 15753, -1]]. +Object config [object id=15764, config id=794, shift=0, childs=[15751, 15751, 15751, 15751, 15751, 15751, 15751, 15751, 15751, 15751, 15751, 15751, 15751, 15750, -1]]. +Object config [object id=15766, config id=794, shift=22, childs=[15754, 15755, 15756, 15754, -1]]. +Object config [object id=15672, config id=793, shift=4, childs=[15668, -1]]. +Object config [object id=15673, config id=793, shift=0, childs=[15668, -1]]. +Object config [object id=15670, config id=793, shift=2, childs=[15668, -1]]. +Object config [object id=15671, config id=793, shift=3, childs=[15668, -1]]. +Object config [object id=15669, config id=793, shift=1, childs=[15668, -1]]. +Object config [object id=15712, config id=794, shift=24, childs=[-1, 15711, -1]]. +Object config [object id=15710, config id=794, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, 15709, -1]]. +Object config [object id=15701, config id=794, shift=0, childs=[15696, 15696, 15696, 15696, 15696, 15696, 15696, 15695, 15695, 15695, 15695, 15695, 15695, 15695, -1]]. +Object config [object id=15702, config id=794, shift=0, childs=[15698, 15698, 15698, 15698, 15698, 15698, 15698, 15697, 15697, 15697, 15697, 15697, 15697, 15697, -1]]. +Object config [object id=15703, config id=794, shift=0, childs=[15700, 15700, 15700, 15700, 15700, 15700, 15700, 15699, 15699, 15699, 15699, 15699, 15699, 15699, -1]]. +Object config [object id=15590, config id=1, shift=5, childs=[15, 15601, -1]]. +Object config [object id=15591, config id=1, shift=6, childs=[16, 15601, -1]]. +Object config [object id=15585, config id=828, shift=3, childs=[16585, 16586, 16587, 16588, 16589, 16590, 16591, 16592, 16593, 16594, -1]]. +Object config [object id=15586, config id=828, shift=7, childs=[16585, 16586, 16587, 16588, 16589, 16590, 16591, 16592, 16593, 16594, -1]]. +Object config [object id=15587, config id=824, shift=8, childs=[16951, 16952, 16951, -1]]. +Object config [object id=15597, config id=0, shift=-1, childs=[5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, -1]]. +Object config [object id=15592, config id=1, shift=7, childs=[17, 15601, -1]]. +Object config [object id=15593, config id=1, shift=8, childs=[18, 15601, -1]]. +Object config [object id=15594, config id=1, shift=9, childs=[19, 15601, -1]]. +Object config [object id=15595, config id=1, shift=10, childs=[20, 15601, -1]]. +Object config [object id=15484, config id=1011, shift=5, childs=[24550, 24549, -1]]. +Object config [object id=15485, config id=1011, shift=20, childs=[24630, 24631, -1]]. +Object config [object id=17428, config id=222, shift=20, childs=[17425, 17427, -1]]. +Object config [object id=17431, config id=222, shift=21, childs=[17430, 17429, 17430, -1]]. +Object config [object id=17454, config id=222, shift=23, childs=[17435, 17438, -1]]. +Object config [object id=18146, config id=870, shift=9, childs=[18144, 18145, 18145, -1]]. +Object config [object id=18116, config id=870, shift=23, childs=[18068, 18068, 18069, -1]]. +Object config [object id=18119, config id=870, shift=4, childs=[17966, 17967, 17967, 17967, 17967, 17967, 17968, 17968, 17968, 17968, 17968, 17969, 17969, 17969, 17969, 17969, -1]]. +Object config [object id=18115, config id=870, shift=23, childs=[18066, 18067, 18067, -1]]. +Object config [object id=18125, config id=870, shift=17, childs=[18040, 18041, -1]]. +Object config [object id=18124, config id=870, shift=8, childs=[-1, 18036, -1]]. +Object config [object id=18127, config id=870, shift=20, childs=[18045, 18046, -1]]. +Object config [object id=18126, config id=870, shift=18, childs=[18042, 18043, 18044, -1]]. +Object config [object id=18121, config id=870, shift=11, childs=[17988, 17989, -1]]. +Object config [object id=18120, config id=870, shift=9, childs=[17983, 17984, 17985, -1]]. +Object config [object id=18123, config id=870, shift=8, childs=[18035, -1]]. +Object config [object id=18122, config id=870, shift=8, childs=[18033, 18034, -1]]. +Object config [object id=18132, config id=870, shift=27, childs=[-1, -1, 18081, -1]]. +Object config [object id=18133, config id=870, shift=27, childs=[-1, -1, 18082, -1]]. +Object config [object id=18134, config id=870, shift=29, childs=[18101, 18102, -1]]. +Object config [object id=18135, config id=870, shift=29, childs=[-1, -1, 18103, -1]]. +Object config [object id=18128, config id=870, shift=25, childs=[18074, 18075, -1]]. +Object config [object id=18129, config id=870, shift=25, childs=[-1, -1, 18076, -1]]. +Object config [object id=18130, config id=870, shift=25, childs=[-1, -1, 18077, -1]]. +Object config [object id=18131, config id=870, shift=27, childs=[18079, 18080, -1]]. +Object config [object id=18136, config id=870, shift=29, childs=[-1, -1, 18104, -1]]. +Object config [object id=18083, config id=870, shift=21, childs=[18059, 18060, 18061, -1]]. +Object config [object id=18084, config id=870, shift=21, childs=[18062, 18063, 18064, -1]]. +Object config [object id=18323, config id=159, shift=-1, childs=[18187, 18187, 18187, 18186, 18186, 18186, 18186, 18186, 18186, 18186, 18186, 18186, 18186, -1]]. +Object config [object id=18251, config id=159, shift=-1, childs=[18381, 18381, 18381, 18381, 18381, 18381, 18381, 18381, 18381, 18380, 18380, 18380, 18380, -1]]. +Object config [object id=16525, config id=820, shift=14, childs=[16502, 16506, 16510, 16514, -1]]. +Object config [object id=16524, config id=820, shift=12, childs=[16502, 16506, 16510, 16514, -1]]. +Object config [object id=16527, config id=820, shift=18, childs=[16502, 16506, 16510, 16514, -1]]. +Object config [object id=16526, config id=820, shift=16, childs=[16502, 16506, 16510, 16514, -1]]. +Object config [object id=16521, config id=820, shift=6, childs=[16501, 16505, 16509, 16513, -1]]. +Object config [object id=16520, config id=820, shift=4, childs=[16501, 16505, 16509, 16513, -1]]. +Object config [object id=16523, config id=820, shift=10, childs=[16502, 16506, 16510, 16514, -1]]. +Object config [object id=16522, config id=820, shift=8, childs=[16501, 16505, 16509, 16513, -1]]. +Object config [object id=16519, config id=820, shift=2, childs=[16501, 16505, 16509, 16513, -1]]. +Object config [object id=16518, config id=820, shift=0, childs=[16501, 16505, 16509, 16513, -1]]. +Object config [object id=16540, config id=821, shift=10, childs=[16475, 16476, -1]]. +Object config [object id=16541, config id=821, shift=11, childs=[16475, 16476, -1]]. +Object config [object id=16542, config id=821, shift=12, childs=[16475, 16476, -1]]. +Object config [object id=16543, config id=821, shift=14, childs=[16484, 16483, 16485, -1]]. +Object config [object id=16537, config id=821, shift=2, childs=[16473, 16474, -1]]. +Object config [object id=16538, config id=821, shift=9, childs=[16475, 16476, -1]]. +Object config [object id=16539, config id=821, shift=9, childs=[16475, 16476, -1]]. +Object config [object id=16532, config id=820, shift=28, childs=[16503, 16507, 16511, 16515, -1]]. +Object config [object id=16533, config id=821, shift=2, childs=[16473, 16474, -1]]. +Object config [object id=16534, config id=821, shift=0, childs=[16495, 16496, 16497, -1]]. +Object config [object id=16528, config id=820, shift=20, childs=[16503, 16507, 16511, 16515, -1]]. +Object config [object id=16529, config id=820, shift=22, childs=[16503, 16507, 16511, 16515, -1]]. +Object config [object id=16530, config id=820, shift=24, childs=[16503, 16507, 16511, 16515, -1]]. +Object config [object id=16531, config id=820, shift=26, childs=[16503, 16507, 16511, 16515, -1]]. +Object config [object id=16552, config id=704, shift=2, childs=[16504, 16508, 16512, 16516, -1]]. +Object config [object id=16551, config id=704, shift=2, childs=[16503, 16507, 16511, 16515, -1]]. +Object config [object id=16550, config id=704, shift=2, childs=[16502, 16506, 16510, 16514, -1]]. +Object config [object id=16549, config id=820, shift=0, childs=[16501, 16505, 16509, 16513, -1]]. +Object config [object id=16548, config id=704, shift=2, childs=[16498, 16499, 16500, -1]]. +Object config [object id=16547, config id=821, shift=0, childs=[16495, 16496, 16497, -1]]. +Object config [object id=16546, config id=821, shift=20, childs=[16493, 16492, 16494, -1]]. +Object config [object id=16545, config id=821, shift=18, childs=[16490, 16489, 16491, -1]]. +Object config [object id=16544, config id=821, shift=16, childs=[16487, 16486, 16488, -1]]. +Object config [object id=17025, config id=828, shift=21, childs=[16810, 16811, -1]]. +Object config [object id=17024, config id=825, shift=0, childs=[16848, 16843, 16844, 16845, 16846, 16847, 16855, -1]]. +Object config [object id=17015, config id=824, shift=10, childs=[16938, 16953, 16938, -1]]. +Object config [object id=17023, config id=824, shift=26, childs=[16847, 16848, 16843, 16844, 16845, 16846, 16855, -1]]. +Object config [object id=17022, config id=824, shift=22, childs=[16846, 16847, 16848, 16843, 16844, 16845, 16855, -1]]. +Object config [object id=17021, config id=824, shift=18, childs=[16845, 16846, 16847, 16848, 16843, 16844, 16855, -1]]. +Object config [object id=17020, config id=824, shift=14, childs=[16844, 16845, 16846, 16847, 16848, 16843, 16855, -1]]. +Object config [object id=17019, config id=824, shift=10, childs=[16843, 16844, 16845, 16846, 16847, 16848, 16855, -1]]. +Object config [object id=17018, config id=824, shift=16, childs=[16891, 16956, 16891, -1]]. +Object config [object id=17017, config id=824, shift=14, childs=[16975, 16955, 16975, -1]]. +Object config [object id=17016, config id=824, shift=12, childs=[16862, 16954, 16862, -1]]. +Object config [object id=17283, config id=844, shift=10, childs=[17248, 17249, 17248, -1]]. +Object config [object id=17282, config id=844, shift=10, childs=[17247, 17246, 17245, -1]]. +Object config [object id=17281, config id=844, shift=10, childs=[17243, 17242, 17243, -1]]. +Object config [object id=17280, config id=844, shift=10, childs=[17241, 17240, 17241, -1]]. +Object config [object id=17369, config id=135, shift=5, childs=[17367, 17368, -1]]. +Object config [object id=17163, config id=842, shift=0, childs=[17161, 17162, -1]]. +Object config [object id=17269, config id=844, shift=12, childs=[17268, 17267, -1]]. +Object config [object id=17270, config id=844, shift=12, childs=[17268, 17267, -1]]. +Object config [object id=19545, config id=922, shift=18, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19544, config id=922, shift=18, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19547, config id=922, shift=26, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19546, config id=922, shift=26, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19549, config id=922, shift=29, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19548, config id=922, shift=26, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19551, config id=922, shift=26, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19550, config id=922, shift=26, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19537, config id=922, shift=12, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19536, config id=922, shift=9, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19539, config id=922, shift=12, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19538, config id=922, shift=12, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19541, config id=922, shift=15, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19540, config id=922, shift=15, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19543, config id=922, shift=18, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19542, config id=922, shift=15, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19528, config id=922, shift=3, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19529, config id=922, shift=3, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19530, config id=922, shift=3, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19531, config id=922, shift=6, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19532, config id=922, shift=6, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19533, config id=922, shift=6, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19534, config id=922, shift=9, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19535, config id=922, shift=9, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19520, config id=921, shift=24, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19521, config id=921, shift=24, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19522, config id=921, shift=27, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19523, config id=921, shift=27, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19524, config id=921, shift=27, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19525, config id=922, shift=0, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19526, config id=922, shift=0, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19527, config id=922, shift=0, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19579, config id=923, shift=24, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19578, config id=923, shift=24, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19577, config id=923, shift=21, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19576, config id=923, shift=21, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19583, config id=923, shift=27, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19582, config id=923, shift=27, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19581, config id=923, shift=27, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19580, config id=923, shift=24, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19571, config id=923, shift=15, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19570, config id=923, shift=15, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19569, config id=923, shift=15, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19568, config id=923, shift=12, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19575, config id=923, shift=21, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19574, config id=923, shift=18, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19573, config id=923, shift=18, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19572, config id=923, shift=18, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19562, config id=923, shift=6, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19563, config id=923, shift=9, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19560, config id=923, shift=6, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19561, config id=923, shift=6, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19566, config id=923, shift=12, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19567, config id=923, shift=12, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19564, config id=923, shift=9, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19565, config id=923, shift=9, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19554, config id=923, shift=0, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19555, config id=923, shift=0, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19558, config id=923, shift=3, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19559, config id=923, shift=3, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19556, config id=923, shift=0, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19557, config id=923, shift=3, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19481, config id=920, shift=24, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19480, config id=920, shift=24, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19483, config id=920, shift=27, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19482, config id=920, shift=27, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19477, config id=920, shift=18, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19476, config id=920, shift=18, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19479, config id=920, shift=21, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19478, config id=920, shift=21, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19473, config id=920, shift=12, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19472, config id=920, shift=12, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19475, config id=920, shift=15, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19474, config id=920, shift=15, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19468, config id=920, shift=6, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19469, config id=920, shift=6, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19470, config id=920, shift=9, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19471, config id=920, shift=9, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19464, config id=920, shift=0, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19465, config id=920, shift=0, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19466, config id=920, shift=3, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19467, config id=920, shift=3, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19460, config id=919, shift=24, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19461, config id=919, shift=24, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19462, config id=919, shift=27, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19463, config id=919, shift=27, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19456, config id=919, shift=18, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19457, config id=919, shift=18, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19458, config id=919, shift=21, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19459, config id=919, shift=21, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19519, config id=921, shift=24, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19518, config id=921, shift=21, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19517, config id=921, shift=21, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19516, config id=921, shift=21, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19515, config id=921, shift=18, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19514, config id=921, shift=18, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19513, config id=921, shift=18, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19512, config id=921, shift=15, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19511, config id=921, shift=15, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19510, config id=921, shift=15, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19509, config id=921, shift=12, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19508, config id=921, shift=12, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19507, config id=921, shift=12, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19506, config id=921, shift=9, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19505, config id=921, shift=9, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19504, config id=921, shift=9, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19502, config id=921, shift=6, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19503, config id=921, shift=6, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19500, config id=921, shift=3, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19501, config id=921, shift=6, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19498, config id=921, shift=3, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19499, config id=921, shift=3, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19496, config id=921, shift=0, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19497, config id=921, shift=0, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19495, config id=921, shift=0, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19706, config id=919, shift=9, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19707, config id=919, shift=12, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19710, config id=919, shift=21, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19711, config id=919, shift=24, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19708, config id=919, shift=15, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19709, config id=919, shift=18, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19604, config id=924, shift=23, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19605, config id=924, shift=23, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19606, config id=924, shift=23, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19607, config id=924, shift=26, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19600, config id=924, shift=17, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19601, config id=924, shift=20, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19602, config id=924, shift=20, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19603, config id=924, shift=20, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19612, config id=924, shift=29, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19613, config id=925, shift=0, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19614, config id=925, shift=0, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19615, config id=925, shift=0, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19608, config id=924, shift=26, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19609, config id=924, shift=26, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19610, config id=924, shift=29, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19611, config id=924, shift=29, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19589, config id=924, shift=3, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19588, config id=924, shift=3, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19591, config id=924, shift=6, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19590, config id=924, shift=6, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19585, config id=924, shift=0, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19584, config id=924, shift=0, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19587, config id=924, shift=3, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19586, config id=924, shift=0, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19597, config id=924, shift=14, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19596, config id=924, shift=14, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19599, config id=924, shift=17, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19598, config id=924, shift=17, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19592, config id=924, shift=6, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19595, config id=924, shift=14, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19638, config id=925, shift=24, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19639, config id=925, shift=24, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19636, config id=925, shift=21, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19637, config id=925, shift=24, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19634, config id=925, shift=21, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19635, config id=925, shift=21, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19632, config id=925, shift=18, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19633, config id=925, shift=18, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19623, config id=925, shift=9, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19622, config id=925, shift=9, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19621, config id=925, shift=6, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19620, config id=925, shift=6, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19619, config id=925, shift=6, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19618, config id=925, shift=3, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19617, config id=925, shift=3, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19616, config id=925, shift=3, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19631, config id=925, shift=18, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19630, config id=925, shift=15, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19629, config id=925, shift=15, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19628, config id=925, shift=15, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19627, config id=925, shift=12, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19626, config id=925, shift=12, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19625, config id=925, shift=12, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19624, config id=925, shift=9, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19786, config id=934, shift=0, childs=[19882, -1, -1, -1, -1, 19883, -1, -1, -1, -1, 19883, -1, -1, -1, -1, 19883, -1, -1, -1, -1, 19883, -1, -1, -1, -1, 19882, -1, -1, -1, -1, 19882, -1, -1, -1, -1, 19882, -1, -1, -1, -1, 19882, -1]]. +Object config [object id=19787, config id=934, shift=0, childs=[19885, -1, -1, -1, -1, 19886, -1, -1, -1, -1, 19886, -1, -1, -1, -1, 19886, -1, -1, -1, -1, 19886, -1, -1, -1, -1, 19885, -1, -1, -1, -1, 19885, -1, -1, -1, -1, 19885, -1, -1, -1, -1, 19885, -1]]. +Object config [object id=19784, config id=934, shift=0, childs=[19879, -1, -1, -1, -1, 19880, -1, -1, -1, -1, 19880, -1, -1, -1, -1, 19880, -1, -1, -1, -1, 19880, -1, -1, -1, -1, 19879, -1, -1, -1, -1, 19879, -1, -1, -1, -1, 19879, -1, -1, -1, -1, 19879, -1]]. +Object config [object id=19785, config id=934, shift=0, childs=[19881, -1, -1, -1, -1, 19884, -1, -1, -1, -1, 19884, -1, -1, -1, -1, 19884, -1, -1, -1, -1, 19884, -1, -1, -1, -1, 19881, -1, -1, -1, -1, 19881, -1, -1, -1, -1, 19881, -1, -1, -1, -1, 19881, -1]]. +Object config [object id=19790, config id=934, shift=0, childs=[19925, -1, -1, -1, -1, 19925, -1, -1, -1, -1, 19925, -1, -1, -1, -1, 19926, -1, -1, -1, -1, 19926, -1, -1, -1, -1, 19926, -1, -1, -1, -1, 19926, -1, -1, -1, -1, 19926, -1, -1, -1, -1, 19926, -1]]. +Object config [object id=19788, config id=934, shift=0, childs=[19887, -1, -1, -1, -1, 19888, -1, -1, -1, -1, 19888, -1, -1, -1, -1, 19888, -1, -1, -1, -1, 19888, -1, -1, -1, -1, 19887, -1, -1, -1, -1, 19887, -1, -1, -1, -1, 19887, -1, -1, -1, -1, 19887, -1]]. +Object config [object id=19789, config id=934, shift=0, childs=[-1, -1, -1, -1, -1, 19889, -1, -1, -1, -1, 19889, -1, -1, -1, -1, 19889, -1, -1, -1, -1, 19889, -1, -1, -1, -1, 19889, -1, -1, -1, -1, 19889, -1, -1, -1, -1, 19889, -1, -1, -1, -1, 19889, -1]]. +Object config [object id=19726, config id=926, shift=3, childs=[-1, -1, -1, 19642, 19643, 19644, 19645, -1]]. +Object config [object id=19727, config id=926, shift=3, childs=[-1, -1, -1, 19646, 19647, 19648, 19649, -1]]. +Object config [object id=19724, config id=926, shift=0, childs=[-1, -1, -1, 19646, 19647, 19648, 19649, -1]]. +Object config [object id=19725, config id=926, shift=0, childs=[-1, -1, -1, 19647, 19646, 19649, 19648, -1]]. +Object config [object id=19722, config id=920, shift=27, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19723, config id=926, shift=0, childs=[-1, -1, -1, 19642, 19643, 19644, 19645, -1]]. +Object config [object id=19720, config id=920, shift=21, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19721, config id=920, shift=24, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19718, config id=920, shift=15, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19719, config id=920, shift=18, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19716, config id=920, shift=9, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19717, config id=920, shift=12, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19714, config id=920, shift=3, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19715, config id=920, shift=6, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19712, config id=919, shift=27, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19713, config id=920, shift=0, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19743, config id=926, shift=18, childs=[-1, -1, -1, 19647, 19646, 19649, 19648, -1]]. +Object config [object id=19742, config id=926, shift=18, childs=[-1, -1, -1, 19646, 19647, 19648, 19649, -1]]. +Object config [object id=19741, config id=926, shift=18, childs=[-1, -1, -1, 19642, 19643, 19644, 19645, -1]]. +Object config [object id=19740, config id=926, shift=15, childs=[-1, -1, -1, 19647, 19646, 19649, 19648, -1]]. +Object config [object id=19739, config id=926, shift=15, childs=[-1, -1, -1, 19646, 19647, 19648, 19649, -1]]. +Object config [object id=19738, config id=926, shift=15, childs=[-1, -1, -1, 19642, 19643, 19644, 19645, -1]]. +Object config [object id=19737, config id=926, shift=12, childs=[-1, -1, -1, 19647, 19646, 19649, 19648, -1]]. +Object config [object id=19736, config id=926, shift=12, childs=[-1, -1, -1, 19646, 19647, 19648, 19649, -1]]. +Object config [object id=19735, config id=926, shift=12, childs=[-1, -1, -1, 19642, 19643, 19644, 19645, -1]]. +Object config [object id=19734, config id=926, shift=9, childs=[-1, -1, -1, 19647, 19646, 19649, 19648, -1]]. +Object config [object id=19733, config id=926, shift=9, childs=[-1, -1, -1, 19646, 19647, 19648, 19649, -1]]. +Object config [object id=19732, config id=926, shift=9, childs=[-1, -1, -1, 19642, 19643, 19644, 19645, -1]]. +Object config [object id=19731, config id=926, shift=6, childs=[-1, -1, -1, 19647, 19646, 19649, 19648, -1]]. +Object config [object id=19730, config id=926, shift=6, childs=[-1, -1, -1, 19646, 19647, 19648, 19649, -1]]. +Object config [object id=19729, config id=926, shift=6, childs=[-1, -1, -1, 19642, 19643, 19644, 19645, -1]]. +Object config [object id=19728, config id=926, shift=3, childs=[-1, -1, -1, 19647, 19646, 19649, 19648, -1]]. +Object config [object id=19748, config id=926, shift=24, childs=[-1, -1, -1, 19646, 19647, 19648, 19649, -1]]. +Object config [object id=19749, config id=926, shift=24, childs=[-1, -1, -1, 19647, 19646, 19649, 19648, -1]]. +Object config [object id=19744, config id=926, shift=21, childs=[-1, -1, -1, 19642, 19643, 19644, 19645, -1]]. +Object config [object id=19745, config id=926, shift=21, childs=[-1, -1, -1, 19646, 19647, 19648, 19649, -1]]. +Object config [object id=19746, config id=926, shift=21, childs=[-1, -1, -1, 19647, 19646, 19649, 19648, -1]]. +Object config [object id=19747, config id=926, shift=24, childs=[-1, -1, -1, 19642, 19643, 19644, 19645, -1]]. +Object config [object id=19947, config id=934, shift=15, childs=[19877, 19878, -1]]. +Object config [object id=19946, config id=934, shift=14, childs=[19877, 19878, -1]]. +Object config [object id=19949, config id=934, shift=17, childs=[19877, 19878, -1]]. +Object config [object id=19948, config id=934, shift=16, childs=[19877, 19878, -1]]. +Object config [object id=19954, config id=934, shift=23, childs=[-1, 19951, 19951, 19951, 19951, 19951, 19951, -1]]. +Object config [object id=19955, config id=934, shift=23, childs=[-1, 19952, 19952, 19952, 19952, 19952, 19952, -1]]. +Object config [object id=19956, config id=934, shift=23, childs=[-1, 19953, 19953, 19953, 19953, 19953, 19953, -1]]. +Object config [object id=19957, config id=934, shift=23, childs=[-1, -1, 19951, 19951, 19951, 19951, 19951, -1]]. +Object config [object id=19958, config id=934, shift=23, childs=[-1, -1, 19952, 19952, 19952, 19952, 19952, -1]]. +Object config [object id=19959, config id=934, shift=23, childs=[-1, -1, 19953, 19953, 19953, 19953, 19953, -1]]. +Object config [object id=19960, config id=934, shift=23, childs=[-1, -1, -1, 19951, 19951, 19951, 19951, -1]]. +Object config [object id=19961, config id=934, shift=23, childs=[-1, -1, -1, 19952, 19952, 19952, 19952, -1]]. +Object config [object id=19962, config id=934, shift=23, childs=[-1, -1, -1, 19953, 19953, 19953, 19953, -1]]. +Object config [object id=19963, config id=934, shift=23, childs=[-1, -1, -1, -1, 19951, 19951, 19951, -1]]. +Object config [object id=19964, config id=934, shift=23, childs=[-1, -1, -1, -1, 19952, 19952, 19952, -1]]. +Object config [object id=19965, config id=934, shift=23, childs=[-1, -1, -1, -1, 19953, 19953, 19953, -1]]. +Object config [object id=19845, config id=934, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 19927, -1, -1, -1, -1, 19927, -1, -1, -1, -1, 19927, -1, -1, -1, -1, 19927, -1, -1, -1, -1, 19927, -1, -1, -1, -1, 19927, -1]]. +Object config [object id=19844, config id=934, shift=0, childs=[19927, -1, -1, -1, -1, 19927, -1, -1, -1, -1, 19927, -1]]. +Object config [object id=19843, config id=934, shift=23, childs=[19914, 19914, 19914, 19914, 19914, 19914, 19915, -1]]. +Object config [object id=20083, config id=135, shift=4, childs=[20081, 20082, -1]]. +Object config [object id=20080, config id=135, shift=4, childs=[20078, 20079, -1]]. +Object config [object id=20077, config id=135, shift=4, childs=[20075, 20076, -1]]. +Object config [object id=20074, config id=135, shift=4, childs=[20072, 20073, -1]]. +Object config [object id=20071, config id=135, shift=4, childs=[20069, 20070, -1]]. +Object config [object id=20068, config id=936, shift=22, childs=[-1, 20066, 20067, -1]]. +Object config [object id=20033, config id=936, shift=18, childs=[20030, 20031, 20032, -1]]. +Object config [object id=20025, config id=936, shift=14, childs=[20022, 20023, 20024, -1]]. +Object config [object id=20029, config id=936, shift=16, childs=[20026, 20027, 20028, -1]]. +Object config [object id=19993, config id=935, shift=0, childs=[19985, 19986, 19987, 19988, -1]]. +Object config [object id=19992, config id=934, shift=30, childs=[19916, 19917, 19917, 19918, -1]]. +Object config [object id=19994, config id=934, shift=0, childs=[19923, -1, -1, -1, -1, 19923, -1, -1, -1, -1, 19923, -1, -1, -1, -1, 19924, -1, -1, -1, -1, 19924, -1, -1, -1, -1, 19924, -1, -1, -1, -1, 19924, -1, -1, -1, -1, 19924, -1, -1, -1, -1, 19924, -1]]. +Object config [object id=19991, config id=934, shift=30, childs=[19916, 19917, 19917, 19918, -1]]. +Object config [object id=19990, config id=934, shift=23, childs=[19914, 19914, 19914, 19914, 19914, 19914, 19915, -1]]. +Object config [object id=20128, config id=942, shift=31, childs=[19036, 19037, -1]]. +Object config [object id=20118, config id=942, shift=6, childs=[19030, 19031, 19033, 19034, 19035, -1]]. +Object config [object id=20119, config id=942, shift=22, childs=[19036, 19037, -1]]. +Object config [object id=20120, config id=942, shift=23, childs=[19036, 19037, -1]]. +Object config [object id=20121, config id=942, shift=24, childs=[19036, 19037, -1]]. +Object config [object id=20122, config id=942, shift=25, childs=[19036, 19037, -1]]. +Object config [object id=20123, config id=942, shift=26, childs=[19036, 19037, -1]]. +Object config [object id=20124, config id=942, shift=27, childs=[19036, 19037, -1]]. +Object config [object id=20125, config id=942, shift=28, childs=[19036, 19037, -1]]. +Object config [object id=20126, config id=942, shift=29, childs=[19036, 19037, -1]]. +Object config [object id=20127, config id=942, shift=30, childs=[19036, 19037, -1]]. +Object config [object id=20098, config id=939, shift=0, childs=[20096, -1, -1, -1, -1, -1, -1, -1, -1, -1, 20096, -1, -1, -1, -1, -1, -1, -1, -1, -1, 20096, -1, -1, -1, -1, -1, -1, -1, -1, -1, 20096, -1, -1, -1, -1, -1, -1, -1, -1, -1, 20096, -1, -1, -1, -1, -1, -1, -1, -1, -1, 20096, -1, -1, -1, -1, -1, -1, -1, -1, -1, 20096, -1, -1, -1, -1, -1, -1, -1, -1, -1, 20096, -1, -1, 20096, -1, -1, 20096, -1, -1, -1, 20096, -1, -1, -1, -1, -1, -1, -1, -1, -1, 20096, -1, -1, -1, -1, -1, -1, -1, -1, -1, 20096, -1, -1, -1, -1, -1, -1, -1, -1, -1, 20096, -1, -1, -1, -1, -1, -1, -1, -1, -1, 20096, -1, -1, -1, -1, -1, -1, -1, -1, -1, 20096, -1, -1, -1, -1, -1, -1, -1, -1, -1, 20096, -1, -1, -1, -1, -1, -1, -1, -1, -1, 20096, -1, -1, -1, -1, -1, -1, -1, -1, -1, 20096, -1, -1, -1, -1, -1, -1, -1, -1, -1, 20096, -1, -1, -1, -1, -1, -1, -1, -1, -1, 20097, -1, -1, -1, -1, -1, -1, -1, -1, -1, 20097, -1, -1, -1, -1, -1, -1, -1, -1, -1, 20097, -1, -1, -1, -1, -1, -1, -1, -1, -1, 20097, -1, -1, -1, -1, -1, -1, -1, -1, -1, 20097, -1, -1, -1, -1, -1, -1, -1, -1, -1, 20097, -1, -1, -1, -1, -1, -1, -1, -1, -1, 20097, -1]]. +Object config [object id=20333, config id=964, shift=8, childs=[20349, 20331, -1]]. +Object config [object id=20334, config id=964, shift=8, childs=[20349, 20332, -1]]. +Object config [object id=20267, config id=949, shift=15, childs=[20264, 20265, 20266, -1]]. +Object config [object id=20276, config id=964, shift=8, childs=[20274, 20275, -1]]. +Object config [object id=20249, config id=949, shift=22, childs=[20247, 20248, -1]]. +Object config [object id=18463, config id=874, shift=14, childs=[18430, 18431, -1]]. +Object config [object id=18513, config id=299, shift=5, childs=[-1, 2016, -1]]. +Object config [object id=18514, config id=299, shift=5, childs=[-1, 2018, -1]]. +Object config [object id=18524, config id=299, shift=7, childs=[-1, 11669, -1]]. +Object config [object id=18593, config id=896, shift=5, childs=[3422, 18594, -1]]. +Object config [object id=18724, config id=897, shift=13, childs=[-1, 18688, 18688, -1]]. +Object config [object id=18725, config id=897, shift=15, childs=[18693, 18694, 18695, -1]]. +Object config [object id=18721, config id=897, shift=10, childs=[18666, 18670, 18671, 18672, -1]]. +Object config [object id=18722, config id=897, shift=6, childs=[18665, 18673, 18674, 18675, -1]]. +Object config [object id=18723, config id=897, shift=13, childs=[18686, 18685, 18687, -1]]. +Object config [object id=18816, config id=830, shift=0, childs=[18819, 18820, 18821, 18818, 18822, 18823, 18824, 18825, 18826, 18826, 18826, 18822, 18823, 18824, 18825, 18826, 18826, 18826, 18822, 18823, 18824, 18825, 18826, 18826, 18826, 18822, 18823, 18824, 18825, 18826, 18826, 18826, 18822, 18823, 18824, 18825, 18826, 18826, 18826, 18822, 18823, 18824, 18825, 18826, 18826, 18826, 18822, 18823, 18824, 18825, 18826, 18826, 18826, 18822, 18823, 18824, 18825, 18826, 18826, 18826, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 18822, 18823, 18824, 18825, 18826, 18826, 18826, 18822, 18823, 18824, 18825, 18826, 18826, 18826, 18822, 18823, 18824, 18825, 18826, 18826, 18826, 18822, 18823, 18824, 18825, 18826, 18826, 18826, 18822, 18823, 18824, 18825, 18826, 18826, 18826, 18822, 18823, 18824, 18825, 18826, 18826, 18826, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 18827, 18828, 18829, 18827, 18828, 18829, 18827, 18828, 18829, 18827, 18828, 18829, 18827, 18828, 18829, 18827, 18828, 18829, 18827, 18828, 18829, 18827, 18828, 18829, 18827, 18828, 18829, 18827, 18828, 18829, 18827, 18828, 18829, 18827, 18828, 18829, 18827, 18828, 18829, 18827, 18828, 18829, 18830, 18831, 18832, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 9044, 9045, 9046, 9047, 9048, 9048, 9049, 9050, 9051, 9052, 9053, 9054, 18822, 18823, 18824, 18825, 18826, 18826, 18826, 18827, 18828, 18829, 18819, 18819, 18819, 18819, 18819, 18819, -1, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 18819, 18817, -1]]. +Object config [object id=18844, config id=435, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6257, -1]]. +Object config [object id=18868, config id=905, shift=20, childs=[-1, 18865, -1]]. +Object config [object id=18867, config id=905, shift=28, childs=[18845, 18846, 18847, 18848, 18849, 18849, 18850, 18850, 18851, 18851, 18852, 18853, 18854, 18854, 18855, 18855, -1]]. +Object config [object id=18963, config id=907, shift=11, childs=[-1, 18962, -1]]. +Object config [object id=19134, config id=912, shift=8, childs=[-1, -1, 19130, -1]]. +Object config [object id=19135, config id=912, shift=10, childs=[19131, 19129, 19129, -1]]. +Object config [object id=19133, config id=912, shift=8, childs=[19132, 19128, 19128, -1]]. +Object config [object id=19144, config id=912, shift=15, childs=[-1, 19130, -1]]. +Object config [object id=19147, config id=830, shift=11, childs=[8395, 8394, 8393, 8392, 8395, 8395, 8395, 8395, 8462, 8463, 8464, 8465, 8466, 8467, 8468, 8481, 8482, 8483, 8484, 8485, 8486, 8487, 8488, 8489, 8435, 8436, 8437, 8438, 8439, 8440, 8441, 8442, 8443, 8444, 8445, 8502, 8503, 8504, 8505, 8506, 8507, 8508, 8509, 8510, 8511, 8512, 8513, 8514, 8396, 8397, 8398, 8399, 8400, 8401, 8402, 8403, 8404, 8405, 8406, 8407, 8408, 8409, 8410, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8473, 8474, 8475, -1, 8476, 8395, 8395, 8490, 8491, 8492, 8493, 8494, -1, 8495, 8395, 8395, 8446, 8447, 8448, 8449, 8450, 8451, 8452, -1, 8453, 8395, 8395, 8515, 8516, 8517, 8518, 8519, 8520, 8521, 8522, 8523, -1, 8524, 8395, 8395, 8411, 8412, 8413, 8414, 8415, 8416, 8417, 8418, 8419, 8420, 8421, -1, 8422, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8477, 8478, 8479, -1, 8480, 8395, 8395, 8496, 8497, 8498, 8499, 8500, -1, 8501, 8395, 8395, 8454, 8455, 8456, 8457, 8458, 8459, 8460, -1, 8461, 8395, 8395, 8525, 8526, 8527, 8528, 8529, 8530, 8531, 8532, 8533, -1, 8534, 8395, 8395, 8423, 8424, 8425, 8426, 8427, 8428, 8429, 8430, 8431, 8432, 8433, -1, 8434, 8395, 8395, 8488, 8488, 8488, 8488, 8488, 8488, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, 8395, -1]]. +Object config [object id=19146, config id=830, shift=11, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 8469, 8470, 8470, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 8471, -1, 8472, -1]]. +Object config [object id=19141, config id=912, shift=14, childs=[19131, 19129, -1]]. +Object config [object id=19140, config id=912, shift=13, childs=[-1, 19130, -1]]. +Object config [object id=19143, config id=912, shift=15, childs=[19131, 19129, -1]]. +Object config [object id=19142, config id=912, shift=14, childs=[-1, 19130, -1]]. +Object config [object id=19137, config id=912, shift=12, childs=[19131, 19129, -1]]. +Object config [object id=19136, config id=912, shift=10, childs=[-1, 19130, 19130, -1]]. +Object config [object id=19139, config id=912, shift=13, childs=[19131, 19129, -1]]. +Object config [object id=19138, config id=912, shift=12, childs=[-1, 19130, -1]]. +Object config [object id=19253, config id=917, shift=0, childs=[19227, 19228, 19229, 19233, 19236, -1]]. +Object config [object id=19255, config id=917, shift=6, childs=[19227, 19228, 19229, 19233, 19236, -1]]. +Object config [object id=19254, config id=917, shift=3, childs=[19227, 19228, 19229, 19233, 19236, -1]]. +Object config [object id=19257, config id=917, shift=12, childs=[19227, 19228, 19229, 19233, 19236, -1]]. +Object config [object id=19256, config id=917, shift=9, childs=[19227, 19228, 19229, 19233, 19236, -1]]. +Object config [object id=19259, config id=917, shift=18, childs=[19227, 19228, 19229, 19232, 19235, -1]]. +Object config [object id=19258, config id=917, shift=15, childs=[19227, 19228, 19229, 19233, 19236, -1]]. +Object config [object id=19261, config id=917, shift=24, childs=[19227, 19228, 19229, 19232, 19235, -1]]. +Object config [object id=19260, config id=917, shift=21, childs=[19227, 19228, 19229, 19232, 19235, -1]]. +Object config [object id=19263, config id=918, shift=0, childs=[19227, 19228, 19229, 19232, 19235, -1]]. +Object config [object id=19262, config id=917, shift=27, childs=[19227, 19228, 19229, 19232, 19235, -1]]. +Object config [object id=19300, config id=918, shift=15, childs=[-1, 19248, 19240, 19240, 19240, -1]]. +Object config [object id=19301, config id=917, shift=0, childs=[-1, 19250, 19238, 19238, 19238, -1]]. +Object config [object id=19302, config id=917, shift=3, childs=[-1, 19250, 19238, 19238, 19238, -1]]. +Object config [object id=19303, config id=917, shift=6, childs=[-1, 19250, 19238, 19238, 19238, -1]]. +Object config [object id=19296, config id=918, shift=3, childs=[-1, 19248, 19240, 19240, 19240, -1]]. +Object config [object id=19297, config id=918, shift=6, childs=[-1, 19248, 19240, 19240, 19240, -1]]. +Object config [object id=19298, config id=918, shift=9, childs=[-1, 19248, 19240, 19240, 19240, -1]]. +Object config [object id=19299, config id=918, shift=12, childs=[-1, 19248, 19240, 19240, 19240, -1]]. +Object config [object id=19308, config id=917, shift=21, childs=[-1, 19242, 19238, 19238, 19238, -1]]. +Object config [object id=19309, config id=917, shift=24, childs=[-1, 19242, 19238, 19238, 19238, -1]]. +Object config [object id=19310, config id=917, shift=27, childs=[-1, 19242, 19238, 19238, 19238, -1]]. +Object config [object id=19311, config id=918, shift=0, childs=[-1, 19242, 19238, 19238, 19238, -1]]. +Object config [object id=19304, config id=917, shift=9, childs=[-1, 19250, 19238, 19238, 19238, -1]]. +Object config [object id=19305, config id=917, shift=12, childs=[-1, 19250, 19238, 19238, 19238, -1]]. +Object config [object id=19306, config id=917, shift=15, childs=[-1, 19250, 19238, 19238, 19238, -1]]. +Object config [object id=19307, config id=917, shift=18, childs=[-1, 19242, 19238, 19238, 19238, -1]]. +Object config [object id=19317, config id=917, shift=0, childs=[-1, 19249, 19237, 19237, 19237, -1]]. +Object config [object id=19316, config id=918, shift=15, childs=[-1, 19246, 19238, 19238, 19238, -1]]. +Object config [object id=19319, config id=917, shift=6, childs=[-1, 19249, 19237, 19237, 19237, -1]]. +Object config [object id=19318, config id=917, shift=3, childs=[-1, 19249, 19237, 19237, 19237, -1]]. +Object config [object id=19313, config id=918, shift=6, childs=[-1, 19246, 19238, 19238, 19238, -1]]. +Object config [object id=19312, config id=918, shift=3, childs=[-1, 19246, 19238, 19238, 19238, -1]]. +Object config [object id=19315, config id=918, shift=12, childs=[-1, 19246, 19238, 19238, 19238, -1]]. +Object config [object id=19314, config id=918, shift=9, childs=[-1, 19246, 19238, 19238, 19238, -1]]. +Object config [object id=19325, config id=917, shift=24, childs=[-1, 19241, 19237, 19237, 19237, -1]]. +Object config [object id=19324, config id=917, shift=21, childs=[-1, 19241, 19237, 19237, 19237, -1]]. +Object config [object id=19327, config id=918, shift=0, childs=[-1, 19241, 19237, 19237, 19237, -1]]. +Object config [object id=19326, config id=917, shift=27, childs=[-1, 19241, 19237, 19237, 19237, -1]]. +Object config [object id=19321, config id=917, shift=12, childs=[-1, 19249, 19237, 19237, 19237, -1]]. +Object config [object id=19320, config id=917, shift=9, childs=[-1, 19249, 19237, 19237, 19237, -1]]. +Object config [object id=19323, config id=917, shift=18, childs=[-1, 19241, 19237, 19237, 19237, -1]]. +Object config [object id=19322, config id=917, shift=15, childs=[-1, 19249, 19237, 19237, 19237, -1]]. +Object config [object id=19270, config id=917, shift=3, childs=[-1, 19251, 19239, 19239, 19239, -1]]. +Object config [object id=19271, config id=917, shift=6, childs=[-1, 19251, 19239, 19239, 19239, -1]]. +Object config [object id=19268, config id=918, shift=15, childs=[19227, 19228, 19229, 19231, 19234, -1]]. +Object config [object id=19269, config id=917, shift=0, childs=[-1, 19251, 19239, 19239, 19239, -1]]. +Object config [object id=19266, config id=918, shift=9, childs=[19227, 19228, 19229, 19231, 19234, -1]]. +Object config [object id=19267, config id=918, shift=12, childs=[19227, 19228, 19229, 19231, 19234, -1]]. +Object config [object id=19264, config id=918, shift=3, childs=[19227, 19228, 19229, 19231, 19234, -1]]. +Object config [object id=19265, config id=918, shift=6, childs=[19227, 19228, 19229, 19231, 19234, -1]]. +Object config [object id=19278, config id=917, shift=27, childs=[-1, 19243, 19239, 19239, 19239, -1]]. +Object config [object id=19279, config id=918, shift=0, childs=[-1, 19243, 19239, 19239, 19239, -1]]. +Object config [object id=19276, config id=917, shift=21, childs=[-1, 19243, 19239, 19239, 19239, -1]]. +Object config [object id=19277, config id=917, shift=24, childs=[-1, 19243, 19239, 19239, 19239, -1]]. +Object config [object id=19274, config id=917, shift=15, childs=[-1, 19251, 19239, 19239, 19239, -1]]. +Object config [object id=19275, config id=917, shift=18, childs=[-1, 19243, 19239, 19239, 19239, -1]]. +Object config [object id=19272, config id=917, shift=9, childs=[-1, 19251, 19239, 19239, 19239, -1]]. +Object config [object id=19273, config id=917, shift=12, childs=[-1, 19251, 19239, 19239, 19239, -1]]. +Object config [object id=19287, config id=917, shift=6, childs=[-1, 19252, 19240, 19240, 19240, -1]]. +Object config [object id=19286, config id=917, shift=3, childs=[-1, 19252, 19240, 19240, 19240, -1]]. +Object config [object id=19285, config id=917, shift=0, childs=[-1, 19252, 19240, 19240, 19240, -1]]. +Object config [object id=19284, config id=918, shift=15, childs=[-1, 19247, 19239, 19239, 19239, -1]]. +Object config [object id=19283, config id=918, shift=12, childs=[-1, 19247, 19239, 19239, 19239, -1]]. +Object config [object id=19282, config id=918, shift=9, childs=[-1, 19247, 19239, 19239, 19239, -1]]. +Object config [object id=19281, config id=918, shift=6, childs=[-1, 19247, 19239, 19239, 19239, -1]]. +Object config [object id=19280, config id=918, shift=3, childs=[-1, 19247, 19239, 19239, 19239, -1]]. +Object config [object id=19295, config id=918, shift=0, childs=[-1, 19244, 19240, 19240, 19240, -1]]. +Object config [object id=19294, config id=917, shift=27, childs=[-1, 19244, 19240, 19240, 19240, -1]]. +Object config [object id=19293, config id=917, shift=24, childs=[-1, 19244, 19240, 19240, 19240, -1]]. +Object config [object id=19292, config id=917, shift=21, childs=[-1, 19244, 19240, 19240, 19240, -1]]. +Object config [object id=19291, config id=917, shift=18, childs=[-1, 19244, 19240, 19240, 19240, -1]]. +Object config [object id=19290, config id=917, shift=15, childs=[-1, 19252, 19240, 19240, 19240, -1]]. +Object config [object id=19289, config id=917, shift=12, childs=[-1, 19252, 19240, 19240, 19240, -1]]. +Object config [object id=19288, config id=917, shift=9, childs=[-1, 19252, 19240, 19240, 19240, -1]]. +Object config [object id=19331, config id=918, shift=12, childs=[-1, 19245, 19237, 19237, 19237, -1]]. +Object config [object id=19330, config id=918, shift=9, childs=[-1, 19245, 19237, 19237, 19237, -1]]. +Object config [object id=19329, config id=918, shift=6, childs=[-1, 19245, 19237, 19237, 19237, -1]]. +Object config [object id=19328, config id=918, shift=3, childs=[-1, 19245, 19237, 19237, 19237, -1]]. +Object config [object id=19332, config id=918, shift=15, childs=[-1, 19245, 19237, 19237, 19237, -1]]. +Object config [object id=19452, config id=919, shift=12, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19453, config id=919, shift=12, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19454, config id=919, shift=15, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19455, config id=919, shift=15, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19448, config id=919, shift=6, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19449, config id=919, shift=6, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19450, config id=919, shift=9, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19451, config id=919, shift=9, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19444, config id=919, shift=3, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19445, config id=919, shift=3, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19446, config id=919, shift=3, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=19447, config id=919, shift=6, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19441, config id=919, shift=0, childs=[-1, -1, -1, 19484, 19485, 19486, 19487, -1]]. +Object config [object id=19442, config id=919, shift=0, childs=[-1, -1, -1, 19488, 19489, 19490, 19491, -1]]. +Object config [object id=19443, config id=919, shift=0, childs=[-1, -1, -1, 19489, 19488, 19491, 19490, -1]]. +Object config [object id=21941, config id=977, shift=31, childs=[21870, 21869, -1]]. +Object config [object id=21943, config id=977, shift=7, childs=[21880, 21880, 21881, -1]]. +Object config [object id=21950, config id=982, shift=8, childs=[8576, 8575, 8574, 8573, 8576, 8576, 8558, 8559, 8560, 8561, 8562, 8562, 8562, 8580, 8581, 8582, 8583, 8584, 8584, 8584, 8535, 8536, 8537, 8538, 8539, 8539, 8539, 8641, 8642, 8643, 8644, 8645, 8645, 8645, 8618, 8619, 8620, 8621, 8622, 8623, 8624, 8624, 8624, 8595, 8596, 8597, 8598, 8599, 8600, 8601, 8601, 8601, 8656, 8657, 8658, 8659, 8660, 8661, 8662, 8663, 8664, 8664, 8664, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8563, 8564, 8565, 8566, 8576, 8576, 8576, 8585, 8586, 8587, 8588, 8576, 8576, 8576, 8540, 8541, 8542, 8543, 8576, 8576, 8576, 8646, 8647, 8648, 8649, 8576, 8576, 8576, 8625, 8626, 8627, 8628, 8629, 8630, 8576, 8576, 8576, 8602, 8603, 8604, 8605, 8606, 8607, 8576, 8576, 8576, 8665, 8666, 8667, 8668, 8669, 8670, 8671, 8672, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8567, 8568, 8569, 8576, 8576, 8576, 8576, 8589, 8590, 8591, 8576, 8576, 8576, 8576, 8544, 8545, 8546, 8576, 8576, 8576, 8576, 8650, 8651, 8652, 8576, 8576, 8576, 8576, 8631, 8632, 8633, 8634, 8635, 8576, 8576, 8576, 8576, 8608, 8609, 8610, 8611, 8612, 8576, 8576, 8576, 8576, 8673, 8674, 8675, 8676, 8677, 8678, 8679, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8576, 8570, 8571, 8572, 8576, 8576, 8576, 8576, 8592, 8593, 8594, 8576, 8576, 8576, 8576, 8547, 8548, 8549, 8576, 8576, 8576, 8576, 8653, 8654, 8655, 8576, 8576, 8576, 8576, 8636, 8637, 8638, 8639, 8640, 8576, 8576, 8576, 8576, 8613, 8614, 8615, 8616, 8617, 8576, 8576, 8576, 8576, 8680, 8681, 8682, 8683, 8684, 8685, 8686, 8576, 8576, 8576, 8576, -1]]. +Object config [object id=21944, config id=978, shift=22, childs=[21921, 21922, -1]]. +Object config [object id=21632, config id=970, shift=20, childs=[21510, 21509, -1]]. +Object config [object id=21633, config id=970, shift=20, childs=[21510, 21509, -1]]. +Object config [object id=21630, config id=970, shift=19, childs=[21510, 21509, -1]]. +Object config [object id=21631, config id=970, shift=19, childs=[21510, 21509, -1]]. +Object config [object id=21628, config id=970, shift=18, childs=[21510, 21509, -1]]. +Object config [object id=21629, config id=970, shift=18, childs=[21510, 21509, -1]]. +Object config [object id=21549, config id=936, shift=20, childs=[21546, 21547, 21548, -1]]. +Object config [object id=22493, config id=982, shift=21, childs=[22420, 22421, 22421, 22421, 22421, 22421, 22421, 22421, 22421, 22421, 22421, 22421, 22421, 22421, 22421, 22421, 22421, 22421, 22421, 22421, 22421, 22421, 22421, 22421, 22421, 22421, 22421, 22421, 22421, 22421, 22421, -1]]. +Object config [object id=22492, config id=981, shift=25, childs=[-1, 22483, 22484, -1]]. +Object config [object id=22491, config id=981, shift=23, childs=[-1, 22483, 22484, -1]]. +Object config [object id=22490, config id=981, shift=15, childs=[-1, 22453, -1]]. +Object config [object id=22489, config id=981, shift=12, childs=[-1, 22457, 22453, 22454, 22455, 22456, -1]]. +Object config [object id=22355, config id=982, shift=6, childs=[22353, 22352, 22354, -1]]. +Object config [object id=22370, config id=981, shift=4, childs=[22368, 22369, -1]]. +Object config [object id=22111, config id=981, shift=20, childs=[22105, 22105, 22105, 22105, 22106, 22109, -1]]. +Object config [object id=22100, config id=982, shift=18, childs=[22091, 22092, 22093, -1]]. +Object config [object id=22101, config id=982, shift=18, childs=[22094, 22095, 22096, -1]]. +Object config [object id=22102, config id=982, shift=18, childs=[22097, 22098, 22099, -1]]. +Object config [object id=22119, config id=981, shift=20, childs=[22114, 22113, 22115, 22116, 22117, 22118, -1]]. +Object config [object id=22112, config id=981, shift=20, childs=[22107, 22107, 22107, 22107, 22108, 22110, -1]]. +Object config [object id=20979, config id=382, shift=-1, childs=[20528, 20528, 20528, 20528, 20528, 20528, 20528, 20528, 20528, 20528, 20528, 20527, -1]]. +Object config [object id=21249, config id=968, shift=8, childs=[-1, -1, -1, 21184, -1]]. +Object config [object id=21248, config id=968, shift=8, childs=[-1, -1, -1, 21184, -1]]. +Object config [object id=21247, config id=968, shift=8, childs=[-1, -1, -1, 21183, -1]]. +Object config [object id=21246, config id=968, shift=8, childs=[21179, 21180, 21181, 21182, -1]]. +Object config [object id=21245, config id=968, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 21157, -1, -1, -1, -1, 21157, -1]]. +Object config [object id=21091, config id=968, shift=12, childs=[21147, 21094, -1]]. +Object config [object id=21090, config id=968, shift=12, childs=[21093, 21093, -1]]. +Object config [object id=21089, config id=968, shift=11, childs=[21147, 21092, -1]]. +Object config [object id=23586, config id=1002, shift=28, childs=[-1, 23585, -1]]. +Object config [object id=23760, config id=1171, shift=7, childs=[28551, 28552, 28553, 28554, 28555, 28556, -1]]. +Object config [object id=23016, config id=991, shift=6, childs=[22976, 22977, -1]]. +Object config [object id=23017, config id=991, shift=7, childs=[22976, 22977, -1]]. +Object config [object id=23018, config id=991, shift=8, childs=[22976, 22977, -1]]. +Object config [object id=23019, config id=991, shift=9, childs=[22976, 22977, -1]]. +Object config [object id=23020, config id=991, shift=10, childs=[22976, 22977, -1]]. +Object config [object id=23021, config id=991, shift=11, childs=[22976, 22977, -1]]. +Object config [object id=23022, config id=991, shift=12, childs=[22976, 22977, -1]]. +Object config [object id=23023, config id=991, shift=13, childs=[22976, 22977, -1]]. +Object config [object id=23008, config id=990, shift=30, childs=[22976, 22977, -1]]. +Object config [object id=23009, config id=990, shift=31, childs=[22976, 22977, -1]]. +Object config [object id=23010, config id=991, shift=0, childs=[22976, 22977, -1]]. +Object config [object id=23011, config id=991, shift=1, childs=[22976, 22977, -1]]. +Object config [object id=23012, config id=991, shift=2, childs=[22976, 22977, -1]]. +Object config [object id=23013, config id=991, shift=3, childs=[22976, 22977, -1]]. +Object config [object id=23014, config id=991, shift=4, childs=[22976, 22977, -1]]. +Object config [object id=23015, config id=991, shift=5, childs=[22976, 22977, -1]]. +Object config [object id=23033, config id=991, shift=23, childs=[22976, 22977, -1]]. +Object config [object id=23032, config id=991, shift=22, childs=[22976, 22977, -1]]. +Object config [object id=23035, config id=991, shift=25, childs=[22976, 22977, -1]]. +Object config [object id=23034, config id=991, shift=24, childs=[22976, 22977, -1]]. +Object config [object id=23037, config id=991, shift=27, childs=[22976, 22977, -1]]. +Object config [object id=23036, config id=991, shift=26, childs=[22976, 22977, -1]]. +Object config [object id=23039, config id=991, shift=29, childs=[22976, 22977, -1]]. +Object config [object id=23038, config id=991, shift=28, childs=[22976, 22977, -1]]. +Object config [object id=23025, config id=991, shift=15, childs=[22976, 22977, -1]]. +Object config [object id=23024, config id=991, shift=14, childs=[22976, 22977, -1]]. +Object config [object id=23027, config id=991, shift=17, childs=[22976, 22977, -1]]. +Object config [object id=23026, config id=991, shift=16, childs=[22976, 22977, -1]]. +Object config [object id=23029, config id=991, shift=19, childs=[22976, 22977, -1]]. +Object config [object id=23028, config id=991, shift=18, childs=[22976, 22977, -1]]. +Object config [object id=23031, config id=991, shift=21, childs=[22976, 22977, -1]]. +Object config [object id=23030, config id=991, shift=20, childs=[22976, 22977, -1]]. +Object config [object id=22986, config id=990, shift=8, childs=[22976, 22977, -1]]. +Object config [object id=22987, config id=990, shift=9, childs=[22976, 22977, -1]]. +Object config [object id=22984, config id=990, shift=6, childs=[22976, 22977, -1]]. +Object config [object id=22985, config id=990, shift=7, childs=[22976, 22977, -1]]. +Object config [object id=22990, config id=990, shift=12, childs=[22976, 22977, -1]]. +Object config [object id=22991, config id=990, shift=13, childs=[22976, 22977, -1]]. +Object config [object id=22988, config id=990, shift=10, childs=[22976, 22977, -1]]. +Object config [object id=22989, config id=990, shift=11, childs=[22976, 22977, -1]]. +Object config [object id=22978, config id=990, shift=0, childs=[22976, 22977, -1]]. +Object config [object id=22979, config id=990, shift=1, childs=[22976, 22977, -1]]. +Object config [object id=22982, config id=990, shift=4, childs=[22976, 22977, -1]]. +Object config [object id=22983, config id=990, shift=5, childs=[22976, 22977, -1]]. +Object config [object id=22980, config id=990, shift=2, childs=[22976, 22977, -1]]. +Object config [object id=22981, config id=990, shift=3, childs=[22976, 22977, -1]]. +Object config [object id=23003, config id=990, shift=25, childs=[22976, 22977, -1]]. +Object config [object id=23002, config id=990, shift=24, childs=[22976, 22977, -1]]. +Object config [object id=23001, config id=990, shift=23, childs=[22976, 22977, -1]]. +Object config [object id=23000, config id=990, shift=22, childs=[22976, 22977, -1]]. +Object config [object id=23007, config id=990, shift=29, childs=[22976, 22977, -1]]. +Object config [object id=23006, config id=990, shift=28, childs=[22976, 22977, -1]]. +Object config [object id=23005, config id=990, shift=27, childs=[22976, 22977, -1]]. +Object config [object id=23004, config id=990, shift=26, childs=[22976, 22977, -1]]. +Object config [object id=22995, config id=990, shift=17, childs=[22976, 22977, -1]]. +Object config [object id=22994, config id=990, shift=16, childs=[22976, 22977, -1]]. +Object config [object id=22993, config id=990, shift=15, childs=[22976, 22977, -1]]. +Object config [object id=22992, config id=990, shift=14, childs=[22976, 22977, -1]]. +Object config [object id=22999, config id=990, shift=21, childs=[22976, 22977, -1]]. +Object config [object id=22998, config id=990, shift=20, childs=[22976, 22977, -1]]. +Object config [object id=22997, config id=990, shift=19, childs=[22976, 22977, -1]]. +Object config [object id=22996, config id=990, shift=18, childs=[22976, 22977, -1]]. +Object config [object id=23296, config id=997, shift=15, childs=[23294, 23295, 23295, -1]]. +Object config [object id=23301, config id=997, shift=19, childs=[23299, 23300, 23300, -1]]. +Object config [object id=23304, config id=997, shift=21, childs=[23297, 23298, 23298, -1]]. +Object config [object id=23534, config id=997, shift=17, childs=[23302, 23303, 23303, -1]]. +Object config [object id=23535, config id=997, shift=11, childs=[23528, 23529, 23529, -1]]. +Object config [object id=23540, config id=997, shift=21, childs=[23528, 23529, 23529, -1]]. +Object config [object id=23537, config id=997, shift=15, childs=[23528, 23529, 23529, -1]]. +Object config [object id=23536, config id=997, shift=13, childs=[23528, 23529, 23529, -1]]. +Object config [object id=23539, config id=997, shift=19, childs=[23528, 23529, 23529, -1]]. +Object config [object id=23538, config id=997, shift=17, childs=[23528, 23529, 23529, -1]]. +Object config [object id=23041, config id=991, shift=31, childs=[22976, 22977, -1]]. +Object config [object id=23040, config id=991, shift=30, childs=[22976, 22977, -1]]. +Object config [object id=23098, config id=992, shift=15, childs=[23094, 23093, -1]]. +Object config [object id=23096, config id=992, shift=8, childs=[23057, 23058, -1]]. +Object config [object id=23097, config id=992, shift=8, childs=[23059, 23060, -1]]. +Object config [object id=23260, config id=996, shift=4, childs=[23213, 23214, -1]]. +Object config [object id=23257, config id=996, shift=3, childs=[23203, 23204, -1]]. +Object config [object id=23259, config id=996, shift=3, childs=[23213, 23214, -1]]. +Object config [object id=23258, config id=996, shift=4, childs=[23203, 23204, -1]]. +Object config [object id=23293, config id=997, shift=13, childs=[23291, 23292, 23292, -1]]. +Object config [object id=23290, config id=997, shift=11, childs=[23288, 23289, 23289, -1]]. +Object config [object id=23282, config id=997, shift=0, childs=[23280, 23280, 23280, 23280, 23280, 23280, 23280, 23280, 23279, 23279, 23279, 23281, -1]]. +Object config [object id=23278, config id=983, shift=0, childs=[-1, 23276, -1]]. +Object config [object id=23277, config id=700, shift=0, childs=[-1, 23275, -1]]. +Object config [object id=26294, config id=1048, shift=1, childs=[26292, 26297, -1]]. +Object config [object id=26298, config id=1048, shift=2, childs=[26292, 26297, -1]]. +Object config [object id=26342, config id=1048, shift=0, childs=[26340, 26341, -1]]. +Object config [object id=26123, config id=1049, shift=9, childs=[26110, 26111, 26112, -1]]. +Object config [object id=26444, config id=1048, shift=1, childs=[26296, 26295, -1]]. +Object config [object id=26445, config id=1048, shift=2, childs=[26300, 26299, -1]]. +Object config [object id=26446, config id=1048, shift=4, childs=[-1, 26306, -1]]. +Object config [object id=25634, config id=1044, shift=7, childs=[-1, 25623, 25624, 25625, -1]]. +Object config [object id=25635, config id=1044, shift=7, childs=[-1, 25626, 25627, 25628, -1]]. +Object config [object id=25943, config id=1049, shift=0, childs=[25836, -1, -1, -1, -1, 25836, -1, -1, -1, -1, 25836, -1, -1, -1, -1, 25836, -1, -1, -1, -1, 25836, -1, -1, -1, -1, 25836, -1, -1, -1, -1, 25836, -1, -1, -1, -1, 25836, -1, -1, -1, -1, 25836, -1, -1, -1, -1, 25836, -1, -1, -1, -1, 25836, -1, -1, -1, -1, 25836, -1, -1, -1, -1, 25836, -1, -1, -1, -1, 25836, -1, -1, -1, -1, 25942, -1, -1, -1, -1, 25942, -1, -1, -1, -1, 25836, -1, -1, -1, -1, 25836, -1, -1, -1, -1, 25836, -1]]. +Object config [object id=25591, config id=113, shift=16, childs=[25438, 25439, -1]]. +Object config [object id=25442, config id=113, shift=15, childs=[25440, 25441, -1]]. +Object config [object id=24776, config id=1017, shift=8, childs=[-1, -1, 24767, 24767, -1]]. +Object config [object id=24775, config id=1017, shift=8, childs=[24762, 24762, 24763, 24763, 24762, -1]]. +Object config [object id=24774, config id=1017, shift=8, childs=[24768, 24769, 24771, 24772, 24768, -1]]. +Object config [object id=24773, config id=1017, shift=8, childs=[24770, 24766, 24766, 24766, 24766, -1]]. +Object config [object id=24642, config id=1011, shift=11, childs=[24550, 24643, -1]]. +Object config [object id=24653, config id=1011, shift=14, childs=[24550, 24654, -1]]. +Object config [object id=24662, config id=1011, shift=19, childs=[24550, 24663, -1]]. +Object config [object id=24623, config id=1011, shift=7, childs=[24550, 24624, 24624, -1]]. +Object config [object id=24626, config id=437, shift=17, childs=[24627, 24550, -1]]. +Object config [object id=24636, config id=1011, shift=9, childs=[24550, 24637, 24637, -1]]. +Object config [object id=24638, config id=1011, shift=15, childs=[24551, 24639, -1]]. +Object config [object id=24633, config id=1011, shift=16, childs=[24550, 24634, -1]]. +Object config [object id=25036, config id=177, shift=10, childs=[2589, 25037, -1]]. +Object config [object id=24840, config id=1017, shift=20, childs=[-1, 24839, -1]]. +Object config [object id=24886, config id=1017, shift=24, childs=[24780, 24781, -1]]. +Object config [object id=24885, config id=1017, shift=8, childs=[24778, 24778, 24779, 24779, 24778, -1]]. +Object config [object id=24884, config id=1017, shift=14, childs=[24730, 24731, 24733, 24735, 24738, -1]]. +Object config [object id=24883, config id=1017, shift=26, childs=[24728, 24729, -1]]. +Object config [object id=24882, config id=1016, shift=29, childs=[24724, 24726, 24725, 24727, -1]]. +Object config [object id=24881, config id=1016, shift=27, childs=[24721, 24722, -1]]. +Object config [object id=24879, config id=1017, shift=25, childs=[24878, 24877, -1]]. +Object config [object id=28321, config id=396, shift=18, childs=[28322, 5145, -1]]. +Object config [object id=28352, config id=1160, shift=12, childs=[28336, 28359, 28359, 28359, 28359, 28359, 28359, 28359, 28359, 28359, 28359, 28359, 28359, 28359, 28359, 28359, 28359, 28359, 28359, 28359, 28359, 28359, 28359, 28359, -1]]. +Object config [object id=28479, config id=1165, shift=24, childs=[28475, 28476, 28477, 28478, -1]]. +Object config [object id=28534, config id=1165, shift=27, childs=[28434, 28433, -1]]. +Object config [object id=28494, config id=1165, shift=10, childs=[28487, 28488, -1]]. +Object config [object id=28495, config id=1165, shift=10, childs=[28489, 28490, -1]]. +Object config [object id=28550, config id=1160, shift=1, childs=[28336, 28359, 28359, 28359, 28359, 28359, 28359, 28359, 28359, 28359, 28359, 28359, 28359, 28359, 28359, 28359, 28359, 28359, 28359, 28359, 28359, 28359, 28359, 28359, -1]]. +Object config [object id=27189, config id=1077, shift=0, childs=[27052, 27052, -1, -1, -1, 27052, -1, -1, -1, -1, 27052, -1, -1, -1, -1, 27052, -1, -1, -1, -1, 27053, -1, -1, -1, -1, 27053, -1, -1, -1, -1, 27052, -1, -1, -1, -1, 27052, -1, -1, -1, -1, 27052, -1, -1, -1, -1, 27052, -1, -1, -1, -1, 27052, -1, -1, -1, -1, 27052, -1, -1, -1, -1, 27052, -1, -1, -1, -1, 27052, -1]]. +Object config [object id=27191, config id=1077, shift=10, childs=[27058, 27059, 27060, -1]]. +Object config [object id=27190, config id=1077, shift=0, childs=[27056, 27056, -1, -1, -1, 27056, -1, -1, -1, -1, 27054, -1, -1, -1, -1, 27055, -1, -1, -1, -1, 27057, -1, -1, -1, -1, 27057, -1, -1, -1, -1, 27056, -1, -1, -1, -1, 27056, -1, -1, -1, -1, 27056, -1, -1, -1, -1, 27056, -1, -1, -1, -1, 27056, -1, -1, -1, -1, 27056, -1, -1, -1, -1, 27056, -1, -1, -1, -1, 27056, -1]]. +Object config [object id=27193, config id=1077, shift=14, childs=[27058, 27059, 27060, -1]]. +Object config [object id=27192, config id=1077, shift=12, childs=[27058, 27059, 27060, -1]]. +Object config [object id=27195, config id=1077, shift=18, childs=[27058, 27059, 27060, -1]]. +Object config [object id=27194, config id=1077, shift=16, childs=[27058, 27059, 27060, -1]]. +Object config [object id=27197, config id=1077, shift=23, childs=[27025, 27024, 27023, 27022, 27026, 27027, 27028, 27029, 27030, 27031, 27033, 27032, 27034, 27035, 27036, 27037, 27038, 27039, 27040, 27041, 27042, 27043, 27044, 27045, 27046, 27047, 27048, 27049, -1]]. +Object config [object id=27196, config id=1077, shift=0, childs=[27063, 27063, -1, -1, -1, 27063, -1, -1, -1, -1, 27063, -1, -1, -1, -1, 27063, -1, -1, -1, -1, 27063, -1, -1, -1, -1, 27063, -1, -1, -1, -1, 27063, -1, -1, -1, -1, 27063, -1, -1, -1, -1, 27061, -1, -1, -1, -1, 27061, -1, -1, -1, -1, 27061, -1, -1, -1, -1, 27062, -1, -1, -1, -1, 27061, -1, -1, -1, -1, 27064, -1]]. +Object config [object id=27331, config id=1094, shift=27, childs=[27567, 27329, 27568, -1]]. +Object config [object id=27312, config id=1094, shift=0, childs=[23049, 23049, 23049, 23049, 23049, 23049, 23049, 23049, 23049, 23049, 23049, 23049, 23049, 23049, 23049, 23049, 27327, 27327, 27327, -1]]. +Object config [object id=27313, config id=1094, shift=0, childs=[23048, 23048, 23048, 23048, 23048, 23048, 23048, 23048, 23048, 23048, 23048, 23048, 23048, 23048, 23048, 23048, 27328, 27328, 27328, -1]]. +Object config [object id=27311, config id=1094, shift=0, childs=[23048, 23048, 23048, 23048, 23048, 23048, 23048, 23048, 23048, 23048, 23048, 23048, 23048, 23048, 23048, 23048, 27326, 27326, 27326, -1]]. +Object config [object id=27310, config id=1094, shift=0, childs=[23047, 23047, 23047, 23047, 23047, 23047, 23047, 23047, 23047, 23047, 23047, 23047, 23047, 23047, 23047, 23047, 27325, 27325, 27325, -1]]. +Object config [object id=27279, config id=1085, shift=16, childs=[27257, 27280, -1]]. +Object config [object id=27563, config id=1094, shift=0, childs=[27321, 27321, 27321, 27321, 27321, 27321, 27321, 27321, 27321, 27321, 27321, 27321, 27321, 27321, 27321, 27321, 27320, 27320, 27320, -1]]. +Object config [object id=27566, config id=1094, shift=27, childs=[-1, 27329, -1]]. +Object config [object id=27565, config id=1094, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 27324, 27324, 27324, -1]]. +Object config [object id=27564, config id=1094, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 27323, 27323, 27323, -1]]. +Object config [object id=26723, config id=1063, shift=14, childs=[26720, 26720, 26720, 26721, 26721, -1]]. +Object config [object id=26805, config id=1064, shift=2, childs=[26804, 26803, -1]]. +Object config [object id=27075, config id=1077, shift=0, childs=[27073, 27073, -1, -1, -1, 27073, -1, -1, -1, -1, 27073, -1, -1, -1, -1, 27073, -1, -1, -1, -1, 27073, -1, -1, -1, -1, 27073, -1, -1, -1, -1, 27073, -1, -1, -1, -1, 27073, -1, -1, -1, -1, 27073, -1, -1, -1, -1, 27073, -1, -1, -1, -1, 27073, -1, -1, -1, -1, 27074, -1, -1, -1, -1, 27074, -1, -1, -1, -1, 27074, -1]]. +Object config [object id=27127, config id=1077, shift=0, childs=[27133, 27133, -1, -1, -1, 27133, -1, -1, -1, -1, 27133, -1, -1, -1, -1, 27133, -1, -1, -1, -1, 27133, -1, -1, -1, -1, 27133, -1, -1, -1, -1, 27133, -1, -1, -1, -1, 27126, -1, -1, -1, -1, 27126, -1, -1, -1, -1, 27126, -1, -1, -1, -1, 27126, -1, -1, -1, -1, 27126, -1, -1, -1, -1, 27126, -1, -1, -1, -1, 27126, -1]]. +Object config [object id=27050, config id=635, shift=16, childs=[683, 683, 683, 27051, 683, -1]]. +Object config [object id=27069, config id=635, shift=27, childs=[27067, 27068, -1]]. +Object config [object id=30621, config id=1218, shift=30, childs=[30532, 30533, -1]]. +Object config [object id=30623, config id=1218, shift=24, childs=[30539, 30540, -1]]. +Object config [object id=30622, config id=1218, shift=31, childs=[30535, 30536, -1]]. +Object config [object id=29877, config id=1205, shift=8, childs=[29826, 29827, 29827, 29827, 29827, 29827, 29827, 29827, 29827, 29827, 29827, 29828, -1]]. +Object config [object id=29879, config id=1205, shift=0, childs=[-1, -1, -1, -1, -1, 29856, -1, -1, -1, -1, 29856, -1, -1, -1, -1, -1, -1, -1, -1, -1, 29856, -1, -1, -1, -1, -1, -1, -1, -1, -1, 29856, -1, -1, 29856, -1, -1, -1, 29856, -1, -1, 29856, -1, -1, -1, -1, 29855, -1, -1, -1, -1, 29855, -1, -1, -1, -1, -1, -1, -1, -1, -1, 29855, -1, -1, -1, -1, -1, -1, -1, -1, -1, 29855, -1, -1, -1, -1, -1, -1, -1, -1, -1, 29855, -1, -1, -1, -1, -1, -1, -1, -1, -1, 29856, -1, -1, -1, -1, -1, -1, -1, -1, -1, 29856, -1, -1, -1, -1, -1, -1, -1, -1, -1, 29856, -1, -1, 29856, -1, -1, 29856, -1, -1, -1, 29856, -1, -1, 29856, -1, -1, 29856, -1, -1, -1, 29856, -1, -1, 29856, -1, -1, 29856, -1, -1, -1, 29856, -1, -1, 29856, -1, -1, 29856, -1, -1, -1, 29856, -1, -1, 29856, -1, -1, 29856, -1, -1, -1, 29856, -1]]. +Object config [object id=29878, config id=1205, shift=0, childs=[-1, -1, -1, -1, -1, 29854, -1, -1, -1, -1, 29854, -1, -1, -1, -1, -1, -1, -1, -1, -1, 29854, -1, -1, -1, -1, -1, -1, -1, -1, -1, 29854, -1, -1, 29854, -1, -1, -1, 29854, -1, -1, 29854, -1, -1, -1, -1, 29853, -1, -1, -1, -1, 29853, -1, -1, -1, -1, -1, -1, -1, -1, -1, 29853, -1, -1, -1, -1, -1, -1, -1, -1, -1, 29853, -1, -1, -1, -1, -1, -1, -1, -1, -1, 29853, -1, -1, -1, -1, -1, -1, -1, -1, -1, 29854, -1, -1, -1, -1, -1, -1, -1, -1, -1, 29854, -1, -1, -1, -1, -1, -1, -1, -1, -1, 29854, -1, -1, 29854, -1, -1, 29854, -1, -1, -1, 29854, -1, -1, 29854, -1, -1, 29854, -1, -1, -1, 29854, -1, -1, 29854, -1, -1, 29854, -1, -1, -1, 29854, -1, -1, 29854, -1, -1, 29854, -1, -1, -1, 29854, -1, -1, 29854, -1, -1, 29854, -1, -1, -1, 29854, -1]]. +Object config [object id=29880, config id=1205, shift=0, childs=[-1, -1, -1, -1, -1, 29857, -1, -1, -1, -1, 29857, -1, -1, -1, -1, -1, -1, -1, -1, -1, 29857, -1, -1, -1, -1, -1, -1, -1, -1, -1, 29857, -1, -1, 29857, -1, -1, -1, 29857, -1, -1, 29857, -1, -1, -1, -1, 29859, -1, -1, -1, -1, 29860, -1, -1, -1, -1, -1, -1, -1, -1, -1, 29861, -1, -1, -1, -1, -1, -1, -1, -1, -1, 29862, -1, -1, -1, -1, -1, -1, -1, -1, -1, 29863, -1, -1, -1, -1, -1, -1, -1, -1, -1, 29857, -1, -1, -1, -1, -1, -1, -1, -1, -1, 29857, -1, -1, -1, -1, -1, -1, -1, -1, -1, 29857, -1, -1, 29857, -1, -1, 29857, -1, -1, -1, 29857, -1, -1, 29857, -1, -1, 29857, -1, -1, -1, 29857, -1, -1, 29857, -1, -1, 29857, -1, -1, -1, 29857, -1, -1, 29857, -1, -1, 29857, -1, -1, -1, 29857, -1, -1, 29857, -1, -1, 29857, -1, -1, -1, 29857, -1]]. +Object config [object id=29842, config id=1205, shift=0, childs=[-1, -1, -1, -1, -1, 29840, -1, -1, -1, -1, 29840, -1, -1, -1, -1, -1, -1, -1, -1, -1, 29840, -1, -1, -1, -1, -1, -1, -1, -1, -1, 29840, -1, -1, 29840, -1, -1, -1, 29840, -1, -1, 29840, -1, -1, -1, -1, 29840, -1, -1, -1, -1, 29840, -1, -1, -1, -1, -1, -1, -1, -1, -1, 29840, -1, -1, -1, -1, -1, -1, -1, -1, -1, 29840, -1, -1, -1, -1, -1, -1, -1, -1, -1, 29840, -1, -1, -1, -1, -1, -1, -1, -1, -1, 29840, -1, -1, -1, -1, -1, -1, -1, -1, -1, 29840, -1, -1, -1, -1, -1, -1, -1, -1, -1, 29840, -1, -1, 29841, -1, -1, 29841, -1, -1, -1, 29841, -1, -1, 29841, -1, -1, 29841, -1, -1, -1, 29841, -1, -1, 29841, -1, -1, 29841, -1, -1, -1, 29841, -1, -1, 29841, -1, -1, 29841, -1, -1, -1, 29841, -1, -1, 29841, -1, -1, 29841, -1, -1, -1, 29841, -1]]. +Object config [object id=29736, config id=1203, shift=26, childs=[29730, 29731, -1]]. +Object config [object id=29735, config id=1203, shift=29, childs=[29585, 29586, -1]]. +Object config [object id=29734, config id=1203, shift=25, childs=[29577, 29578, -1]]. +Object config [object id=29801, config id=1204, shift=0, childs=[18179, -1, -1, -1, -1, 18179, -1, -1, -1, -1, 18179, -1, -1, -1, -1, 18179, -1, -1, -1, -1, 18179, -1, -1, -1, -1, 18179, -1, 18179, -1, -1, 18179, -1, -1, -1, -1, 18179, -1, -1, -1, -1, 29804, -1, -1, -1, -1, 29804, 29804, -1, -1, -1, 29804, -1, -1, -1, -1, 29804, -1, 29804, -1, -1, 29804, 29804, -1, -1, -1, 29804, -1, -1, -1, -1, 29804, 29804, -1, -1, -1, 29804, -1, -1, -1, -1, 29804, -1, 29804, -1, -1, 29804, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 18179, -1]]. +Object config [object id=29800, config id=1204, shift=0, childs=[18347, -1, -1, -1, -1, 18347, -1, -1, -1, -1, 18347, -1, -1, -1, -1, 18347, -1, -1, -1, -1, 18347, -1, -1, -1, -1, 18347, -1, 18347, -1, -1, 18347, -1, -1, -1, -1, 18347, -1, -1, -1, -1, 29803, -1, -1, -1, -1, 29803, 29803, -1, -1, -1, 29803, -1, -1, -1, -1, 29803, -1, 29803, -1, -1, 29803, 29803, -1, -1, -1, 29803, -1, -1, -1, -1, 29803, 29803, -1, -1, -1, 29803, -1, -1, -1, -1, 29803, -1, 29803, -1, -1, 29803, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 18347, -1]]. +Object config [object id=29802, config id=1204, shift=0, childs=[29806, -1, -1, -1, -1, 29806, -1, -1, -1, -1, 29806, -1, -1, -1, -1, 29806, -1, -1, -1, -1, 29806, -1, -1, -1, -1, 29806, -1, 29806, -1, -1, 29806, -1, -1, -1, -1, 29806, -1, -1, -1, -1, 29805, -1, -1, -1, -1, 29805, 29805, -1, -1, -1, 29805, -1, -1, -1, -1, 29805, -1, 29805, -1, -1, 29805, 29805, -1, -1, -1, 29805, -1, -1, -1, -1, 29805, 29805, -1, -1, -1, 29805, -1, -1, -1, -1, 29805, -1, 29805, -1, -1, 29805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 18154, -1]]. +Object config [object id=29812, config id=1204, shift=20, childs=[-1, 29808, -1]]. +Object config [object id=29813, config id=1204, shift=20, childs=[-1, -1, 29808, -1]]. +Object config [object id=29814, config id=1204, shift=20, childs=[-1, -1, -1, 29808, -1]]. +Object config [object id=29815, config id=1204, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 29808, -1]]. +Object config [object id=29570, config id=1201, shift=2, childs=[29568, 29569, 7082, -1]]. +Object config [object id=29573, config id=1201, shift=16, childs=[29571, 29572, 29546, -1]]. +Object config [object id=29558, config id=1201, shift=6, childs=[29556, 29557, 11701, -1]]. +Object config [object id=29555, config id=1201, shift=8, childs=[29553, 29554, 9668, -1]]. +Object config [object id=29552, config id=1201, shift=4, childs=[29550, 29551, 9625, -1]]. +Object config [object id=29567, config id=1201, shift=14, childs=[29565, 29566, 9519, -1]]. +Object config [object id=29564, config id=1201, shift=12, childs=[29562, 29563, 1018, -1]]. +Object config [object id=29561, config id=1201, shift=10, childs=[29559, 29560, 11662, -1]]. +Object config [object id=29543, config id=1181, shift=19, childs=[-1, 29540, -1]]. +Object config [object id=29542, config id=1181, shift=18, childs=[-1, 29540, -1]]. +Object config [object id=29549, config id=1201, shift=0, childs=[29547, 29548, 444, -1]]. +Object config [object id=29545, config id=1181, shift=16, childs=[29538, 29539, -1]]. +Object config [object id=29544, config id=1181, shift=20, childs=[-1, 29540, -1]]. +Object config [object id=29429, config id=1193, shift=26, childs=[29432, 29434, -1]]. +Object config [object id=29431, config id=1193, shift=28, childs=[29432, 29434, -1]]. +Object config [object id=29430, config id=1193, shift=27, childs=[29432, 29434, -1]]. +Object config [object id=29179, config id=1185, shift=27, childs=[29152, 29154, 29155, 29155, -1]]. +Object config [object id=29178, config id=1185, shift=25, childs=[29152, 29154, 29155, 29155, -1]]. +Object config [object id=29177, config id=1185, shift=23, childs=[29152, 29154, 29155, 29155, -1]]. +Object config [object id=29176, config id=1185, shift=21, childs=[29152, 29154, 29155, 29155, -1]]. +Object config [object id=29180, config id=1185, shift=29, childs=[29152, 29154, 29155, 29155, -1]]. +Object config [object id=29171, config id=1185, shift=21, childs=[28999, 28999, 28999, -1]]. +Object config [object id=29170, config id=1185, shift=21, childs=[28999, 28999, 28999, -1]]. +Object config [object id=29175, config id=1185, shift=29, childs=[28999, 28999, 28999, -1]]. +Object config [object id=29174, config id=1185, shift=27, childs=[28999, 28999, 28999, -1]]. +Object config [object id=29173, config id=1185, shift=25, childs=[28999, 28999, 28999, -1]]. +Object config [object id=29172, config id=1185, shift=23, childs=[28999, 28999, 28999, -1]]. +Object config [object id=29108, config id=1185, shift=31, childs=[29107, 29106, -1]]. +Object config [object id=29098, config id=1185, shift=19, childs=[29096, 29095, 29094, -1]]. +Object config [object id=29097, config id=1185, shift=17, childs=[29090, 29091, 29092, 29093, -1]]. +Object config [object id=28919, config id=830, shift=23, childs=[8050, 8049, 8048, 8047, 8050, 8050, 8050, 8050, 7935, 7936, 7937, 7938, 7939, 7940, 7941, 7942, 7943, 7944, 7945, 7946, 7947, 7949, 7950, 7951, 7952, 7953, 7954, 7955, 7956, 7957, 7958, 7959, 7960, 7961, 7948, 7993, 7994, 7995, 7996, 7997, 7998, 8000, 8001, 8002, 8003, 8004, 8005, 8006, 8007, 8008, 8009, 8010, 8011, 8012, 8013, 8014, 8015, 8016, 8017, 8018, 8019, 7999, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8051, 8052, 8053, 8054, 8055, 8056, 8057, 8058, 8059, 8060, 8061, 8062, 8063, 8065, 8066, 8067, 8068, 8069, 8070, 8071, 8072, 8073, 8074, 8075, 8076, 8077, 8064, 8020, 8021, 8022, 8023, 8024, 8025, 8026, 8027, 8028, 8029, 8030, 8031, 8032, 8034, 8035, 8036, 8037, 8038, 8039, 8040, 8041, 8042, 8043, 8044, 8045, 8046, 8033, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 7966, 7967, 7968, 7969, 7970, 7971, 7972, 7973, 7974, 7975, 7976, 7977, 7978, 7980, 7981, 7982, 7983, 7984, 7985, 7986, 7987, 7988, 7989, 7990, 7991, 7992, 7979, 8105, 8106, 8107, 8108, 8109, 8110, 8111, 8112, 8113, 8114, 8115, 8116, 8117, 8119, 8120, 8121, 8122, 8123, 8124, 8125, 8126, 8127, 8128, 8129, 8130, 8131, 8118, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8078, 8079, 8080, 8081, 8082, 8083, 8084, 8085, 8086, 8087, 8088, 8089, 8090, 8092, 8093, 8094, 8095, 8096, 8097, 8098, 8099, 8100, 8101, 8102, 8103, 8104, 8091, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, 8050, -1]]. +Object config [object id=28888, config id=1181, shift=8, childs=[28781, 28780, -1]]. +Object config [object id=31759, config id=222, shift=21, childs=[17424, 17423, 17423, -1]]. +Object config [object id=31277, config id=1227, shift=0, childs=[31258, -1, -1, -1, -1, 31258, -1, -1, -1, -1, 31258, -1, -1, -1, -1, 31258, -1, 31258, -1, -1, 31258, -1, -1, -1, -1, 31258, -1, -1, -1, -1, 31258, -1, -1, -1, -1, 31258, -1, -1, -1, -1, 31258, -1, -1, -1, -1, 31258, -1, -1, -1, -1, 31258, -1, -1, -1, -1, 31258, -1, 31292, -1, -1, 31292, -1, -1, 31292, -1]]. +Object config [object id=31276, config id=1227, shift=0, childs=[31258, -1, -1, -1, -1, 31258, -1, -1, -1, -1, 31258, -1, -1, -1, -1, 31258, -1, 31258, -1, -1, 31258, -1, -1, -1, -1, 31258, -1, -1, -1, -1, 31258, -1, -1, -1, -1, 31258, -1, -1, -1, -1, 31258, -1, -1, -1, -1, 31258, -1, -1, -1, -1, 31258, -1, -1, -1, -1, 31258, -1, 31292, -1, -1, 31292, -1, -1, 31292, -1]]. +Object config [object id=31278, config id=1227, shift=0, childs=[31258, -1, -1, -1, -1, 31292, -1, -1, -1, -1, 31292, -1, -1, -1, -1, 31292, -1, 31292, -1, -1, 31292, -1, -1, -1, -1, 31292, -1, -1, -1, -1, 31292, -1, -1, -1, -1, 31292, -1, -1, -1, -1, 31292, -1, -1, -1, -1, 31292, -1, -1, -1, -1, 31292, -1, -1, -1, -1, 31292, -1, 31292, -1, -1, 31258, -1, -1, 31258, -1]]. +Object config [object id=31449, config id=1002, shift=28, childs=[31448, -1]]. +Object config [object id=31040, config id=1225, shift=0, childs=[31007, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31007, -1, -1, -1, -1, 31007, -1, -1, -1, -1, 31007, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31007, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31007, -1, -1, -1, -1, 31007, -1, -1, -1, 31007, 31007, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31007, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31007, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31007, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31007, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31007, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31007, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31007, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31007, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31007, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31006, -1]]. +Object config [object id=31012, config id=1225, shift=0, childs=[31011, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31011, -1, -1, -1, -1, 31011, -1, -1, -1, -1, 31011, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31011, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31011, -1, -1, -1, -1, 31011, -1, -1, -1, 31011, 31011, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31011, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31011, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31011, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31011, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31011, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31011, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31011, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31011, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31011, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31010, -1]]. +Object config [object id=31031, config id=1225, shift=17, childs=[-1, 31014, -1]]. +Object config [object id=31028, config id=1225, shift=0, childs=[31026, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31026, -1, -1, -1, -1, 31026, -1, -1, -1, -1, 31026, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31026, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31026, -1, -1, -1, -1, 31026, -1, -1, -1, 31026, 31026, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31026, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31026, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31026, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31026, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31026, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31026, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31026, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31026, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31026, -1, -1, -1, -1, -1, -1, -1, -1, -1, 31027, -1]]. +Object config [object id=31038, config id=1225, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30802, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30802, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30802, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30802, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30802, -1]]. +Object config [object id=31039, config id=1225, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30803, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30803, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30803, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30803, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30803, -1]]. +Object config [object id=31036, config id=1225, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30800, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30800, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30800, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30800, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30800, -1]]. +Object config [object id=31037, config id=1225, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30801, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30801, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30801, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30801, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30801, -1]]. +Object config [object id=31034, config id=1225, shift=0, childs=[30809, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30809, -1, -1, -1, -1, 30809, -1, -1, -1, -1, 30809, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30809, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30809, -1, -1, -1, -1, 30809, -1, -1, -1, 30809, 30809, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30809, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30809, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30809, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30809, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30809, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30809, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30809, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30809, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30809, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30811, -1]]. +Object config [object id=31035, config id=1225, shift=0, childs=[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30799, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30799, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30799, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30799, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30799, -1]]. +Object config [object id=31032, config id=1225, shift=20, childs=[31017, 31015, 31016, -1]]. +Object config [object id=31033, config id=1225, shift=0, childs=[30808, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30808, -1, -1, -1, -1, 30808, -1, -1, -1, -1, 30808, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30808, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30808, -1, -1, -1, -1, 30808, -1, -1, -1, 30808, 30808, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30808, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30808, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30808, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30808, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30808, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30808, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30808, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30808, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30808, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30810, -1]]. +Object config [object id=30999, config id=1225, shift=0, childs=[30997, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30997, -1, -1, -1, -1, 30997, -1, -1, -1, -1, 30997, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30997, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30997, -1, -1, -1, -1, 30997, -1, -1, -1, 30997, 30997, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30997, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30997, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30997, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30997, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30997, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30997, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30997, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30997, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30997, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30924, -1]]. +Object config [object id=35088, config id=553, shift=9, childs=[35087, 35087, 35086, 35086, -1]]. +Object config [object id=36309, config id=518, shift=8, childs=[9328, 9328, 9328, 9328, 9328, 9328, 9328, 9329, 9329, 9329, 9329, 9329, 9329, 9329, -1]]. +Object config [object id=36756, config id=553, shift=9, childs=[36752, 36753, 36753, -1]]. +Object config [object id=36755, config id=553, shift=9, childs=[36751, 36754, 36754, -1]]. +Object config [object id=33334, config id=874, shift=14, childs=[33245, 33244, -1]]. +Object config [object id=36880, config id=695, shift=-1, childs=[36879, 36878, 36878, 36878, 36878, 36878, 36878, 36878, 36878, 36878, 36878, 36878, 36878, 36878, 36878, 36878, 36878, 36878, 36878, 36878, 36878, 36878, 36878, 36878, 36878, 36878, 36878, 36878, 36878, 36878, 36878, -1]]. +Object config [object id=36933, config id=553, shift=9, childs=[36752, 36753, -1]]. +Object config [object id=36932, config id=553, shift=9, childs=[36751, 36754, -1]]. diff --git a/dumps/498/498_object_dump.txt b/dumps/498/498_object_dump.txt new file mode 100644 index 0000000..c28dfb2 --- /dev/null +++ b/dumps/498/498_object_dump.txt @@ -0,0 +1,38027 @@ +0 - null - [null, null, null, null, null] +1 - Crate - [Search, null, null, null, null] +2 - Cave Entrance - [Enter, null, null, null, null] +3 - Door - [Open, null, null, null, null] +4 - Door - [Open, null, null, null, null] +5 - Broken multicannon - [Inspect, null, null, null, null] +6 - Dwarf multicannon - [Fire, Pick-up, null, null, null] +7 - Cannon base - [Pick-up, null, null, null, null] +8 - Cannon stand - [Pick-up, null, null, null, null] +9 - Cannon barrels - [Pick-up, null, null, null, null] +10 - Ladder - [Climb-down, null, null, null, null] +11 - Ladder - [Climb-up, null, null, null, null] +12 - Rock pile - [Climb-over, null, null, null, null] +13 - Mud pile - [Climb-over, null, null, null, null] +14 - Railing - [Inspect, null, null, null, null] +15 - Railing - [Inspect, null, null, null, null] +16 - Railing - [Inspect, null, null, null, null] +17 - Railing - [Inspect, null, null, null, null] +18 - Railing - [Inspect, null, null, null, null] +19 - Railing - [Inspect, null, null, null, null] +20 - Railing - [Inspect, null, null, null, null] +21 - Mysterious statue - [null, null, null, null, null] +22 - Door - [Open, null, null, null, null] +23 - Sacks - [Prod, Open, null, null, null] +24 - Door - [Open, null, null, null, null] +25 - Clock spindle - [null, null, null, null, null] +26 - Clock spindle - [null, null, null, null, null] +27 - Clock spindle - [null, null, null, null, null] +28 - Clock spindle - [null, null, null, null, null] +29 - Clock spindle - [null, null, null, null, null] +30 - Clock spindle - [null, null, null, null, null] +31 - Clock spindle - [null, null, null, null, null] +32 - Clock spindle - [null, null, null, null, null] +33 - Lever - [Pull, null, null, null, null] +34 - Lever - [Pull, null, null, null, null] +35 - Lever - [Pull, null, null, null, null] +36 - Lever - [Pull, null, null, null, null] +37 - Gate - [Open, null, null, null, null] +38 - Gate - [Open, null, null, null, null] +39 - Gate - [Go-through, null, null, null, null] +40 - Food trough - [null, null, null, null, null] +41 - Wall Pipe - [Search, null, null, null, null] +42 - Fishing spot - [Fish, null, null, null, null] +43 - Water - [null, null, null, null, null] +44 - Fishing spot - [Fish, null, null, null, null] +45 - Fishing spot - [Fish, null, null, null, null] +46 - Fishing spot - [Fish, null, null, null, null] +47 - Gate - [Open, null, null, null, null] +48 - Gate - [Open, null, null, null, null] +49 - Gate - [null, null, null, null, null] +50 - Gate - [null, null, null, null, null] +51 - Loose Railing - [Squeeze-through, null, null, null, null] +52 - Gate - [Open, null, null, null, null] +53 - Gate - [Open, null, null, null, null] +54 - Stairs - [Climb-up, null, null, null, null] +55 - Stairs - [Climb-down, null, null, null, null] +56 - Stairs - [Climb-up, null, null, null, null] +57 - Stairs - [Climb-down, null, null, null, null] +58 - Vine - [Check, null, null, null, null] +59 - Door - [Open, null, null, null, null] +60 - Ladder - [Climb-up, null, null, null, null] +61 - Chaos altar - [Pray-at, Check, null, null, null] +62 - Giant crystal - [Smash, null, null, null, null] +63 - Crate - [null, Hide-in, null, null, null] +64 - Crate - [null, Hide-in, null, null, null] +65 - Crate wall - [Climb-out, null, null, null, null] +66 - Crate wall - [Climb-out, null, null, null, null] +67 - Crate - [null, Check, null, null, null] +68 - Beehive - [Take-from, Take-honey, null, null, null] +69 - Gangplank - [Cross, null, null, null, null] +70 - Gangplank - [Cross, null, null, null, null] +71 - Large door - [Open, Knock-at, null, null, null] +72 - Large door - [Open, Knock-at, null, null, null] +73 - Large door - [Open, null, null, null, null] +74 - Large door - [Open, null, null, null, null] +75 - Chest - [Open, null, null, null, null] +76 - Chest - [Search, Close, null, null, null] +77 - Door - [null, null, null, null, null] +78 - Door - [null, null, null, null, null] +79 - Prison Door - [Open, null, null, null, null] +80 - Prison Door - [Open, null, null, null, null] +81 - Door - [Open, null, null, null, null] +82 - Door - [Open, null, null, null, null] +83 - null - [null, null, null, null, null] +84 - null - [null, null, null, null, null] +85 - null - [null, null, null, null, null] +86 - Lever bracket - [null, null, null, null, null] +87 - Lever - [Pull, null, null, null, null] +88 - null - [null, null, null, null, null] +89 - Gate - [Open, null, null, null, null] +90 - Gate - [Open, null, null, null, null] +91 - Lever - [Pull, Search for traps, null, null, null] +92 - Door - [Open, null, null, null, null] +93 - Door - [Open, null, null, null, null] +94 - Gate - [Open, null, null, null, null] +95 - Gate - [Open, null, null, null, null] +96 - Stairs - [Climb-up, null, null, null, null] +97 - null - [null, null, null, null, null] +98 - Stairs - [Climb-down, null, null, null, null] +99 - Door - [Open, null, null, null, null] +100 - Trapdoor - [Open, null, null, null, null] +101 - Ladder - [Climb-up, null, null, null, null] +102 - Door - [Open, null, null, null, null] +103 - Closed chest - [Open, null, null, null, null] +104 - Open chest - [Search, Shut, null, null, null] +105 - Trapdoor - [null, null, null, null, null] +106 - Trapdoor - [null, null, null, null, null] +107 - null - [null, null, null, null, null] +108 - null - [null, null, null, null, null] +109 - null - [null, null, null, null, null] +110 - null - [null, null, null, null, null] +111 - null - [null, null, null, null, null] +112 - null - [null, null, null, null, null] +113 - null - [null, null, null, null, null] +114 - Cooking range - [null, null, null, null, null] +115 - Party Balloon - [Burst, null, null, null, null] +116 - Party Balloon - [Burst, null, null, null, null] +117 - Party Balloon - [Burst, null, null, null, null] +118 - Party Balloon - [Burst, null, null, null, null] +119 - Party Balloon - [Burst, null, null, null, null] +120 - Party Balloon - [Burst, null, null, null, null] +121 - Party Balloon - [Burst, null, null, null, null] +122 - Party Balloon - [Burst, null, null, null, null] +123 - Party Balloon - [null, null, null, null, null] +124 - Party Balloon - [null, null, null, null, null] +125 - Party Balloon - [null, null, null, null, null] +126 - Party Balloon - [null, null, null, null, null] +127 - Party Balloon - [null, null, null, null, null] +128 - Party Balloon - [null, null, null, null, null] +129 - Party Balloon - [null, null, null, null, null] +130 - Party Balloon - [null, null, null, null, null] +131 - Door - [Open, null, null, null, null] +132 - Ladder - [Climb-up, null, null, null, null] +133 - Ladder - [Climb-down, null, null, null, null] +134 - Large door - [Open, null, null, null, null] +135 - Large door - [Open, null, null, null, null] +136 - Door - [Open, null, null, null, null] +137 - null - [Open, null, null, null, null] +138 - null - [Open, null, null, null, null] +139 - null - [Open, null, null, null, null] +140 - null - [Open, null, null, null, null] +141 - null - [Open, null, null, null, null] +142 - null - [Open, null, null, null, null] +143 - null - [Open, null, null, null, null] +144 - null - [Open, null, null, null, null] +145 - null - [Open, null, null, null, null] +146 - null - [Pull, Inspect, null, null, null] +147 - null - [Pull, Inspect, null, null, null] +148 - null - [Pull, Inspect, null, null, null] +149 - null - [Pull, Inspect, null, null, null] +150 - null - [Pull, Inspect, null, null, null] +151 - null - [Pull, Inspect, null, null, null] +152 - Compost heap - [Search, null, null, null, null] +153 - Fountain - [Search, null, null, null, null] +154 - Obstacle pipe - [Squeeze-through, null, null, null, null] +155 - Bookcase - [Search, null, null, null, null] +156 - Bookcase - [Search, null, null, null, null] +157 - Bookcase - [null, null, null, null, null] +158 - Wall - [null, null, null, null, null] +159 - Wall - [null, null, null, null, null] +160 - Lever - [Pull, null, null, null, null] +161 - null - [null, null, null, null, null] +162 - Strange machine - [null, null, null, null, null] +163 - Strange machine - [null, null, null, null, null] +164 - Strange machine - [null, null, null, null, null] +165 - Incinerator - [null, null, null, null, null] +166 - Gate - [Open, null, null, null, null] +167 - Gate - [Open, null, null, null, null] +168 - null - [null, null, null, null, null] +169 - null - [null, null, null, null, null] +170 - Closed chest - [Open, null, null, null, null] +171 - Open chest - [null, null, null, null, null] +172 - Closed chest - [Open, null, null, null, null] +173 - Open chest - [null, null, null, null, null] +174 - null - [null, null, null, null, null] +175 - null - [null, null, null, null, null] +176 - null - [null, null, null, null, null] +177 - null - [null, null, null, null, null] +178 - null - [null, null, null, null, null] +179 - null - [null, null, null, null, null] +180 - null - [null, null, null, null, null] +181 - null - [null, null, null, null, null] +182 - null - [null, null, null, null, null] +183 - null - [null, null, null, null, null] +184 - null - [null, null, null, null, null] +185 - null - [null, null, null, null, null] +186 - null - [null, null, null, null, null] +187 - Gnome glider - [null, null, null, null, null] +188 - Crashed glider - [null, null, null, null, null] +189 - Blurberry bar - [null, null, null, null, null] +190 - Gate - [Open, null, null, null, null] +191 - null - [null, null, null, null, null] +192 - null - [null, null, null, null, null] +193 - null - [null, null, null, null, null] +194 - Hollowed rock - [Enter, null, null, null, null] +195 - Ladder - [Climb-up, null, null, null, null] +196 - null - [null, null, null, null, null] +197 - null - [null, null, null, null, null] +198 - null - [null, null, null, null, null] +199 - null - [null, null, null, null, null] +200 - Lamp - [null, null, null, null, null] +201 - Lamp - [null, null, null, null, null] +202 - Candles - [null, null, null, null, null] +203 - Candles - [null, null, null, null, null] +204 - Candles - [null, null, null, null, null] +205 - null - [null, null, null, null, null] +206 - null - [null, null, null, null, null] +207 - null - [null, null, null, null, null] +208 - Candles - [null, null, null, null, null] +209 - Chandelier - [null, null, null, null, null] +210 - Ice Light - [null, null, null, null, null] +211 - Candles - [null, null, null, null, null] +212 - Sail - [null, null, null, null, null] +213 - null - [null, null, null, null, null] +214 - null - [null, null, null, null, null] +215 - null - [null, null, null, null, null] +216 - null - [null, null, null, null, null] +217 - null - [null, null, null, null, null] +218 - Sail - [null, null, null, null, null] +219 - null - [null, null, null, null, null] +220 - null - [null, null, null, null, null] +221 - Figurehead - [null, null, null, null, null] +222 - Figurehead - [null, null, null, null, null] +223 - null - [null, null, null, null, null] +224 - null - [null, null, null, null, null] +225 - Sail - [null, null, null, null, null] +226 - Sail - [null, null, null, null, null] +227 - Pile of rope - [null, null, null, null, null] +228 - null - [null, null, null, null, null] +229 - null - [null, null, null, null, null] +230 - null - [null, null, null, null, null] +231 - null - [null, null, null, null, null] +232 - null - [null, null, null, null, null] +233 - null - [null, null, null, null, null] +234 - null - [null, null, null, null, null] +235 - null - [null, null, null, null, null] +236 - null - [null, null, null, null, null] +237 - null - [null, null, null, null, null] +238 - null - [null, null, null, null, null] +239 - null - [null, null, null, null, null] +240 - null - [null, null, null, null, null] +241 - null - [null, null, null, null, null] +242 - null - [null, null, null, null, null] +243 - null - [null, null, null, null, null] +244 - null - [null, null, null, null, null] +245 - Ship's ladder - [Climb-up, null, null, null, null] +246 - Ship's ladder - [Climb-down, null, null, null, null] +247 - null - [null, null, null, null, null] +248 - null - [null, null, null, null, null] +249 - null - [null, null, null, null, null] +250 - null - [null, null, null, null, null] +251 - null - [null, null, null, null, null] +252 - Ship's wheel - [null, null, null, null, null] +253 - null - [null, null, null, null, null] +254 - Figurehead - [null, null, null, null, null] +255 - Winch - [Operate, null, null, null, null] +256 - null - [null, null, null, null, null] +257 - null - [null, null, null, null, null] +258 - null - [null, null, null, null, null] +259 - null - [null, null, null, null, null] +260 - Figurehead - [null, null, null, null, null] +261 - null - [null, null, null, null, null] +262 - null - [null, null, null, null, null] +263 - null - [null, null, null, null, null] +264 - null - [null, null, null, null, null] +265 - Sail - [null, null, null, null, null] +266 - Sail - [null, null, null, null, null] +267 - Sail - [null, null, null, null, null] +268 - Sail - [null, null, null, null, null] +269 - null - [null, null, null, null, null] +270 - null - [null, null, null, null, null] +271 - Anchor - [null, null, null, null, null] +272 - Ship's ladder - [Climb-up, null, null, null, null] +273 - Ship's ladder - [Climb-down, null, null, null, null] +274 - Hoisted sail - [null, null, null, null, null] +275 - Hoisted sail - [null, null, null, null, null] +276 - Hoisted sail - [null, null, null, null, null] +277 - Hoisted sail - [null, null, null, null, null] +278 - Hoisted sail - [null, null, null, null, null] +279 - Hoisted sail - [null, null, null, null, null] +280 - null - [null, null, null, null, null] +281 - null - [null, null, null, null, null] +282 - null - [null, null, null, null, null] +283 - null - [null, null, null, null, null] +284 - null - [null, null, null, null, null] +285 - null - [null, null, null, null, null] +286 - null - [null, null, null, null, null] +287 - Ladder - [Climb-down, null, null, null, null] +288 - null - [null, null, null, null, null] +289 - null - [null, null, null, null, null] +290 - null - [null, null, null, null, null] +291 - null - [null, null, null, null, null] +292 - null - [null, null, null, null, null] +293 - null - [null, null, null, null, null] +294 - null - [null, null, null, null, null] +295 - null - [null, null, null, null, null] +296 - Plough - [null, null, null, null, null] +297 - Scarecrow - [null, null, null, null, null] +298 - Hay bales - [Search, null, null, null, null] +299 - Hay bales - [Search, null, null, null, null] +300 - Haystack - [Search, null, null, null, null] +301 - Food trough - [null, null, null, null, null] +302 - Eggs - [null, null, null, null, null] +303 - Compost - [null, null, null, null, null] +304 - Hay bale - [Search, null, null, null, null] +305 - Beehive - [null, null, null, null, null] +306 - Broken cart - [null, null, null, null, null] +307 - Cart - [null, null, null, null, null] +308 - Cart - [null, null, null, null, null] +309 - Log pile - [null, null, null, null, null] +310 - Mud patch - [null, null, null, null, null] +311 - Mudpile - [null, null, null, null, null] +312 - Potato - [null, Pick, null, null, null] +313 - Wheat - [null, Pick, null, null, null] +314 - null - [null, null, null, null, null] +315 - null - [null, null, null, null, null] +316 - null - [null, null, null, null, null] +317 - null - [null, null, null, null, null] +318 - null - [null, null, null, null, null] +319 - null - [null, null, null, null, null] +320 - null - [null, null, null, null, null] +321 - null - [null, null, null, null, null] +322 - null - [null, null, null, null, null] +323 - null - [null, null, null, null, null] +324 - null - [null, null, null, null, null] +325 - null - [null, null, null, null, null] +326 - null - [null, null, null, null, null] +327 - Broken cart wheel - [null, null, null, null, null] +328 - null - [null, null, null, null, null] +329 - null - [null, null, null, null, null] +330 - null - [null, null, null, null, null] +331 - null - [null, null, null, null, null] +332 - null - [null, null, null, null, null] +333 - null - [null, null, null, null, null] +334 - null - [null, null, null, null, null] +335 - null - [null, null, null, null, null] +336 - null - [null, null, null, null, null] +337 - null - [null, null, null, null, null] +338 - null - [null, null, null, null, null] +339 - null - [null, null, null, null, null] +340 - null - [null, null, null, null, null] +341 - null - [null, null, null, null, null] +342 - null - [null, null, null, null, null] +343 - null - [null, null, null, null, null] +344 - null - [null, null, null, null, null] +345 - null - [null, null, null, null, null] +346 - Cabinet - [null, null, null, null, null] +347 - Cabinet - [null, null, null, null, null] +348 - Drawers - [Open, null, null, null, null] +349 - Drawers - [null, Search, Shut, null, null] +350 - Drawers - [Open, null, null, null, null] +351 - Drawers - [null, Search, Shut, null, null] +352 - Drawers - [Open, null, null, null, null] +353 - Drawers - [null, Search, Shut, null, null] +354 - Crate - [Search, null, null, null, null] +355 - Crate - [Search, null, null, null, null] +356 - Crate - [Search, null, null, null, null] +357 - Crate - [Search, null, null, null, null] +358 - Crate - [Search, null, null, null, null] +359 - Boxes - [Search, null, null, null, null] +360 - Boxes - [Search, null, null, null, null] +361 - Boxes - [Search, null, null, null, null] +362 - Barrel - [null, null, null, null, null] +363 - Barrel - [null, null, null, null, null] +364 - Barrel - [null, null, null, null, null] +365 - Sacks - [Search, null, null, null, null] +366 - Crate - [Search, null, null, null, null] +367 - Cupboard - [Open, null, null, null, null] +368 - Cupboard - [Open, null, null, null, null] +369 - Large cupboard - [Open, null, null, null, null] +370 - Open Cupboard - [null, Search, Shut, null, null] +371 - Cupboard - [null, Search, Shut, null, null] +372 - Large open cupboard - [null, Search, Close, null, null] +373 - Dresser - [null, null, null, null, null] +374 - Hat stand - [null, null, null, null, null] +375 - Closed chest - [Open, null, null, null, null] +376 - Closed chest - [Open, null, null, null, null] +377 - Closed chest - [Open, null, null, null, null] +378 - Open chest - [null, Search, Shut, null, null] +379 - Open chest - [null, Search, Shut, null, null] +380 - Bookcase - [Search, null, null, null, null] +381 - Bookcase - [Search, null, null, null, null] +382 - Basket - [null, null, null, null, null] +383 - Basket - [null, null, null, null, null] +384 - Basket - [null, null, null, null, null] +385 - Basket - [null, null, null, null, null] +386 - Large urn - [null, null, null, null, null] +387 - Bookshelves - [null, null, null, null, null] +388 - Wardrobe - [Open, null, null, null, null] +389 - Wardrobe - [null, Search, Close, null, null] +390 - Wardrobe - [null, Search, Close, null, null] +391 - null - [null, null, null, null, null] +392 - Full fishing net - [null, null, null, null, null] +393 - Bookcase - [Search, null, null, null, null] +394 - Bookcase - [Search, null, null, null, null] +395 - Pot - [null, null, null, null, null] +396 - Pots - [null, null, null, null, null] +397 - Cabinet - [null, null, null, null, null] +398 - Coffin - [Open, null, null, null, null] +399 - Coffin - [Close, null, null, null, null] +400 - Small gravestone - [null, null, null, null, null] +401 - Grave marker - [null, null, null, null, null] +402 - Tombstone - [null, null, null, null, null] +403 - Large grave stone - [null, null, null, null, null] +404 - Gravestone - [null, null, null, null, null] +405 - Gravestone - [null, null, null, null, null] +406 - Large grave - [null, null, null, null, null] +407 - Henge - [null, null, null, null, null] +408 - Henge - [null, null, null, null, null] +409 - Altar - [Pray-at, null, null, null, null] +410 - Altar of Guthix - [Pray-at, null, null, null, null] +411 - Chaos altar - [Pray-at, null, null, null, null] +412 - Chaos altar - [Pray-at, null, null, null, null] +413 - Dolmen - [null, null, null, null, null] +414 - Coffin - [Open, null, null, null, null] +415 - Coffin - [Open, null, null, null, null] +416 - Church organ - [Play, null, null, null, null] +417 - Bed - [null, null, null, null, null] +418 - Bed - [null, null, null, null, null] +419 - Bed - [null, null, null, null, null] +420 - Bed - [null, null, null, null, null] +421 - Bed - [null, null, null, null, null] +422 - Bed - [null, null, null, null, null] +423 - Bed - [null, null, null, null, null] +424 - Bed - [null, null, null, null, null] +425 - Bed - [null, null, null, null, null] +426 - Bed - [null, null, null, null, null] +427 - Bed - [null, null, null, null, null] +428 - Bed - [null, null, null, null, null] +429 - Bed - [null, null, null, null, null] +430 - Hammock - [null, null, null, null, null] +431 - Chaise lounge - [null, null, null, null, null] +432 - Bed - [null, null, null, null, null] +433 - Bed - [null, null, null, null, null] +434 - Bed - [null, null, null, null, null] +435 - Bed - [null, null, null, null, null] +436 - Rock - [null, null, null, null, null] +437 - Rock - [null, null, null, null, null] +438 - Rock - [null, null, null, null, null] +439 - Rock - [null, null, null, null, null] +440 - Rock - [null, null, null, null, null] +441 - Rock - [null, null, null, null, null] +442 - Rock - [null, null, null, null, null] +443 - null - [null, null, null, null, null] +444 - Boulder - [null, null, null, null, null] +445 - Boulder - [null, null, null, null, null] +446 - Stones - [null, null, null, null, null] +447 - Stones - [null, null, null, null, null] +448 - null - [null, null, null, null, null] +449 - Overhanging rock - [null, null, null, null, null] +450 - Rocks - [Mine, Prospect, hidden, null, null] +451 - Rocks - [Mine, Prospect, hidden, null, null] +452 - Rocks - [Mine, Prospect, hidden, null, null] +453 - Rocks - [Mine, Prospect, hidden, null, null] +454 - Cave rocks - [null, null, null, null, null] +455 - Cave rocks - [null, null, null, null, null] +456 - null - [null, null, null, null, null] +457 - null - [null, null, null, null, null] +458 - null - [null, null, null, null, null] +459 - null - [null, null, null, null, null] +460 - null - [null, null, null, null, null] +461 - null - [null, null, null, null, null] +462 - Mossy rock - [null, null, null, null, null] +463 - Mossy rock - [null, null, null, null, null] +464 - Column - [null, null, null, null, null] +465 - Column - [null, null, null, null, null] +466 - Column - [null, null, null, null, null] +467 - Stalactite - [null, null, null, null, null] +468 - Stalagmites - [null, null, null, null, null] +469 - Stalactite - [null, null, null, null, null] +470 - null - [null, null, null, null, null] +471 - Rockslide - [null, null, null, null, null] +472 - Rockslide - [null, null, null, null, null] +473 - Rockslide - [null, null, null, null, null] +474 - Rockslide - [null, null, null, null, null] +475 - null - [null, null, null, null, null] +476 - null - [null, null, null, null, null] +477 - Mossy rock - [null, null, null, null, null] +478 - Mossy rock - [null, null, null, null, null] +479 - Rockslide - [null, null, null, null, null] +480 - Rockslide - [null, null, null, null, null] +481 - Rockslide - [null, null, null, null, null] +482 - Rockslide - [null, null, null, null, null] +483 - Rockslide - [null, null, null, null, null] +484 - Rockslide - [null, null, null, null, null] +485 - Rockslide - [null, null, null, null, null] +486 - Rockslide - [null, null, null, null, null] +487 - null - [null, null, null, null, null] +488 - null - [null, null, null, null, null] +489 - null - [null, null, null, null, null] +490 - null - [null, null, null, null, null] +491 - null - [null, null, null, null, null] +492 - Rocks - [Climb-down, null, null, null, null] +493 - null - [null, null, null, null, null] +494 - null - [null, null, null, null, null] +495 - null - [null, null, null, null, null] +496 - null - [null, null, null, null, null] +497 - null - [null, null, null, null, null] +498 - null - [null, null, null, null, null] +499 - null - [null, null, null, null, null] +500 - null - [null, null, null, null, null] +501 - null - [null, null, null, null, null] +502 - null - [null, null, null, null, null] +503 - null - [null, null, null, null, null] +504 - null - [null, null, null, null, null] +505 - null - [null, null, null, null, null] +506 - null - [null, null, null, null, null] +507 - Rockslide - [null, null, null, null, null] +508 - Rockslide - [null, null, null, null, null] +509 - Rockslide - [null, null, null, null, null] +510 - Rockslide - [null, null, null, null, null] +511 - Rocks - [null, null, null, null, null] +512 - null - [null, null, null, null, null] +513 - null - [null, null, null, null, null] +514 - null - [null, null, null, null, null] +515 - null - [null, null, null, null, null] +516 - Ice Column - [null, null, null, null, null] +517 - Rockslide - [null, null, null, null, null] +518 - Rockslide - [null, null, null, null, null] +519 - Rockslide - [null, null, null, null, null] +520 - Rockslide - [null, null, null, null, null] +521 - null - [null, null, null, null, null] +522 - null - [null, null, null, null, null] +523 - Column - [null, null, null, null, null] +524 - Column - [null, null, null, null, null] +525 - Column - [null, null, null, null, null] +526 - Column - [null, null, null, null, null] +527 - Column - [null, null, null, null, null] +528 - Column - [null, null, null, null, null] +529 - Stalactite - [null, null, null, null, null] +530 - Stalagmites - [null, null, null, null, null] +531 - Stalactite - [null, null, null, null, null] +532 - Stalagmites - [null, null, null, null, null] +533 - Stalactite - [null, null, null, null, null] +534 - Stalagmite - [null, null, null, null, null] +535 - null - [null, null, null, null, null] +536 - null - [null, null, null, null, null] +537 - null - [null, null, null, null, null] +538 - null - [null, null, null, null, null] +539 - Stalactite - [null, null, null, null, null] +540 - null - [null, null, null, null, null] +541 - Stalagmite - [null, null, null, null, null] +542 - Stalagmite - [null, null, null, null, null] +543 - Stalactite - [null, null, null, null, null] +544 - Stalagmite - [null, null, null, null, null] +545 - Boulder - [null, null, null, null, null] +546 - Eerie statue - [null, null, null, null, null] +547 - null - [null, null, null, null, null] +548 - Rockslide - [null, null, null, null, null] +549 - Rockslide - [null, null, null, null, null] +550 - Rockslide - [null, null, null, null, null] +551 - Rockslide - [null, null, null, null, null] +552 - null - [null, null, null, null, null] +553 - null - [null, null, null, null, null] +554 - Icicle - [null, null, null, null, null] +555 - Icicle - [null, null, null, null, null] +556 - Icicle - [null, null, null, null, null] +557 - Icicle - [null, null, null, null, null] +558 - Cave entrance - [null, null, null, null, null] +559 - null - [null, null, null, null, null] +560 - null - [null, null, null, null, null] +561 - null - [null, null, null, null, null] +562 - Statue of a warrior - [null, null, null, null, null] +563 - Statue of a king - [null, null, null, null, null] +564 - Statue of a queen - [null, null, null, null, null] +565 - Statue of a king - [null, null, null, null, null] +566 - Statue of a warrior - [null, null, null, null, null] +567 - Tribal statue - [null, null, null, null, null] +568 - Dwarf statue - [null, null, null, null, null] +569 - Gnome statue - [null, null, null, null, null] +570 - Gnome statue - [null, null, null, null, null] +571 - Gnome statue - [null, null, null, null, null] +572 - Gnome statue - [null, null, null, null, null] +573 - Gnome statue - [null, null, null, null, null] +574 - Statue - [null, null, null, null, null] +575 - Statue - [null, null, null, null, null] +576 - Statue - [null, null, null, null, null] +577 - null - [null, null, null, null, null] +578 - null - [null, null, null, null, null] +579 - Statue - [null, null, null, null, null] +580 - Statue - [null, null, null, null, null] +581 - Statue - [null, null, null, null, null] +582 - Statue - [null, null, null, null, null] +583 - Vase - [null, null, null, null, null] +584 - Statue - [null, null, null, null, null] +585 - Statue of Saradomin - [null, null, null, null, null] +586 - Statue of Saradomin - [null, null, null, null, null] +587 - Statue of Zamorak - [null, null, null, null, null] +588 - Statue steps - [null, null, null, null, null] +589 - Crystal ball - [null, null, null, null, null] +590 - Bank table - [null, null, null, null, null] +591 - Bank table - [null, null, null, null, null] +592 - Bathroom table - [null, null, null, null, null] +593 - Table - [null, null, null, null, null] +594 - Table - [null, null, null, null, null] +595 - Table - [null, null, null, null, null] +596 - Table - [null, null, null, null, null] +597 - Table - [null, null, null, null, null] +598 - Table - [null, null, null, null, null] +599 - Table - [null, null, null, null, null] +600 - Table - [null, null, null, null, null] +601 - Table - [null, null, null, null, null] +602 - Table - [null, null, null, null, null] +603 - Table - [null, null, null, null, null] +604 - Table - [null, null, null, null, null] +605 - Table - [null, null, null, null, null] +606 - Table - [null, null, null, null, null] +607 - Table - [null, null, null, null, null] +608 - Study desk - [null, null, null, null, null] +609 - Workbench - [null, null, null, null, null] +610 - Workbench - [null, null, null, null, null] +611 - Picnic bench - [null, null, null, null, null] +612 - Counter - [null, null, null, null, null] +613 - Table - [null, null, null, null, null] +614 - Table - [null, null, null, null, null] +615 - Small table - [null, null, null, null, null] +616 - Table - [null, null, null, null, null] +617 - Counter - [null, null, null, null, null] +618 - Chemistry Table - [null, null, null, null, null] +619 - Chemistry Table - [null, null, null, null, null] +620 - Table - [null, null, null, null, null] +621 - Table - [null, null, null, null, null] +622 - Table - [null, null, null, null, null] +623 - Table - [null, null, null, null, null] +624 - Table - [null, null, null, null, null] +625 - null - [null, null, null, null, null] +626 - null - [null, null, null, null, null] +627 - null - [null, null, null, null, null] +628 - Silver stall - [null, null, null, null, null] +629 - Silk stall - [null, null, null, null, null] +630 - Bakery stall - [null, null, null, null, null] +631 - Gem stall - [null, null, null, null, null] +632 - Fur stall - [null, null, null, null, null] +633 - Spice stall - [null, null, null, null, null] +634 - Market stall - [null, null, null, null, null] +635 - Tea stall - [null, Steal-from, null, null, null] +636 - Buffers - [null, null, null, null, null] +637 - Mine cart - [null, null, null, null, null] +638 - null - [null, null, null, null, null] +639 - null - [null, null, null, null, null] +640 - null - [null, null, null, null, null] +641 - null - [null, null, null, null, null] +642 - null - [null, null, null, null, null] +643 - null - [null, null, null, null, null] +644 - null - [null, null, null, null, null] +645 - null - [null, null, null, null, null] +646 - null - [null, null, null, null, null] +647 - Rack - [null, null, null, null, null] +648 - Stocks - [null, null, null, null, null] +649 - Gallows - [null, null, null, null, null] +650 - null - [null, null, null, null, null] +651 - Buried skeleton - [Search, null, null, null, null] +652 - null - [null, null, null, null, null] +653 - null - [null, null, null, null, null] +654 - null - [null, null, null, null, null] +655 - null - [null, null, null, null, null] +656 - null - [null, null, null, null, null] +657 - null - [null, null, null, null, null] +658 - Pile of skulls - [null, null, null, null, null] +659 - Charred bones - [null, null, null, null, null] +660 - Corpse - [null, null, null, null, null] +661 - Corpse - [null, null, null, null, null] +662 - Corpse - [null, null, null, null, null] +663 - Corpse - [null, null, null, null, null] +664 - Corpse - [null, null, null, null, null] +665 - Corpse - [null, null, null, null, null] +666 - Corpse - [null, null, null, null, null] +667 - Corpse - [null, null, null, null, null] +668 - Pile of skulls - [null, null, null, null, null] +669 - null - [null, null, null, null, null] +670 - null - [null, null, null, null, null] +671 - Catapult - [null, null, null, null, null] +672 - Broken barrel - [null, null, null, null, null] +673 - null - [null, null, null, null, null] +674 - null - [null, null, null, null, null] +675 - null - [null, null, null, null, null] +676 - null - [null, null, null, null, null] +677 - null - [null, null, null, null, null] +678 - Fishing spot - [null, null, null, null, null] +679 - Fishing spot - [null, null, null, null, null] +680 - Piano - [null, null, null, null, null] +681 - Piano - [null, null, null, null, null] +682 - Piano stool - [null, null, null, null, null] +683 - Grandfather clock - [null, null, null, null, null] +684 - Swamp bubbles - [null, null, null, null, null] +685 - Weather vane - [null, null, null, null, null] +686 - null - [null, null, null, null, null] +687 - null - [null, null, null, null, null] +688 - null - [null, null, null, null, null] +689 - Mirror - [null, null, null, null, null] +690 - Bath screen - [null, null, null, null, null] +691 - Screen - [null, null, null, null, null] +692 - Cauldron - [null, null, null, null, null] +693 - Broom - [null, null, null, null, null] +694 - Clothes model - [null, null, null, null, null] +695 - Clothes model - [null, null, null, null, null] +696 - Hole - [null, null, null, null, null] +697 - Animal skull - [null, null, null, null, null] +698 - Big egg - [null, null, null, null, null] +699 - Carcass - [null, null, null, null, null] +700 - Curved bone - [null, null, null, null, null] +701 - Curved bone - [null, null, null, null, null] +702 - Large bone - [null, null, null, null, null] +703 - Large bone - [null, null, null, null, null] +704 - null - [null, null, null, null, null] +705 - null - [null, null, null, null, null] +706 - null - [null, null, null, null, null] +707 - Bell - [null, null, null, null, null] +708 - Bell mechanism - [null, null, null, null, null] +709 - Bell rope - [null, null, null, null, null] +710 - Hole in wall - [null, null, null, null, null] +711 - Crystal cluster - [null, null, null, null, null] +712 - Crystal cluster - [null, null, null, null, null] +713 - Crystal cluster - [null, null, null, null, null] +714 - Fire remains - [null, null, null, null, null] +715 - null - [null, null, null, null, null] +716 - null - [null, null, null, null, null] +717 - null - [null, null, null, null, null] +718 - Barrel - [null, null, null, null, null] +719 - null - [null, null, null, null, null] +720 - null - [null, null, null, null, null] +721 - null - [null, null, null, null, null] +722 - null - [null, null, null, null, null] +723 - Buried skeleton - [Search, null, null, null, null] +724 - Standing torch - [null, null, null, null, null] +725 - null - [null, null, null, null, null] +726 - null - [null, null, null, null, null] +727 - Cave web - [null, null, null, null, null] +728 - null - [null, null, null, null, null] +729 - null - [null, null, null, null, null] +730 - null - [null, null, null, null, null] +731 - null - [null, null, null, null, null] +732 - null - [null, null, null, null, null] +733 - Web - [Slash, null, null, null, null] +734 - Slashed web - [null, null, null, null, null] +735 - Swamp bubbles - [null, null, null, null, null] +736 - Animal skull - [null, null, null, null, null] +737 - Carcass - [null, null, null, null, null] +738 - null - [null, null, null, null, null] +739 - null - [null, null, null, null, null] +740 - null - [null, null, null, null, null] +741 - Broken ladder - [null, null, null, null, null] +742 - null - [null, null, null, null, null] +743 - Ladder - [null, null, null, null, null] +744 - Scaffold - [null, null, null, null, null] +745 - null - [null, null, null, null, null] +746 - null - [null, null, null, null, null] +747 - null - [null, null, null, null, null] +748 - Cave entrance - [null, null, null, null, null] +749 - null - [null, null, null, null, null] +750 - null - [null, null, null, null, null] +751 - null - [null, null, null, null, null] +752 - null - [null, null, null, null, null] +753 - null - [null, null, null, null, null] +754 - null - [null, null, null, null, null] +755 - null - [null, null, null, null, null] +756 - null - [null, null, null, null, null] +757 - null - [null, null, null, null, null] +758 - null - [null, null, null, null, null] +759 - null - [null, null, null, null, null] +760 - null - [null, null, null, null, null] +761 - null - [null, null, null, null, null] +762 - null - [null, null, null, null, null] +763 - null - [null, null, null, null, null] +764 - null - [null, null, null, null, null] +765 - null - [null, null, null, null, null] +766 - null - [null, null, null, null, null] +767 - null - [null, null, null, null, null] +768 - null - [null, null, null, null, null] +769 - null - [null, null, null, null, null] +770 - null - [null, null, null, null, null] +771 - null - [null, null, null, null, null] +772 - null - [null, null, null, null, null] +773 - null - [null, null, null, null, null] +774 - null - [null, null, null, null, null] +775 - null - [null, null, null, null, null] +776 - null - [null, null, null, null, null] +777 - null - [null, null, null, null, null] +778 - null - [null, null, null, null, null] +779 - Bamboo Door - [Open, null, null, null, null] +780 - null - [null, null, null, null, null] +781 - null - [null, null, null, null, null] +782 - null - [null, null, null, null, null] +783 - null - [null, null, null, null, null] +784 - null - [null, null, null, null, null] +785 - null - [null, null, null, null, null] +786 - null - [null, null, null, null, null] +787 - Loom - [null, Weave, null, null, null] +788 - City Gate - [Enter, null, null, null, null] +789 - City Gate - [Enter, null, null, null, null] +790 - null - [null, null, null, null, null] +791 - null - [null, null, null, null, null] +792 - null - [null, null, null, null, null] +793 - null - [null, null, null, null, null] +794 - null - [null, null, null, null, null] +795 - null - [null, null, null, null, null] +796 - null - [null, null, null, null, null] +797 - null - [null, null, null, null, null] +798 - null - [null, null, null, null, null] +799 - null - [null, null, null, null, null] +800 - null - [null, null, null, null, null] +801 - null - [null, null, null, null, null] +802 - null - [null, null, null, null, null] +803 - null - [null, null, null, null, null] +804 - null - [null, null, null, null, null] +805 - null - [null, null, null, null, null] +806 - null - [null, null, null, null, null] +807 - null - [null, null, null, null, null] +808 - null - [null, null, null, null, null] +809 - null - [null, null, null, null, null] +810 - null - [null, null, null, null, null] +811 - null - [null, null, null, null, null] +812 - null - [null, null, null, null, null] +813 - null - [null, null, null, null, null] +814 - null - [null, null, null, null, null] +815 - null - [null, null, null, null, null] +816 - null - [null, null, null, null, null] +817 - Suit of armour - [null, null, null, null, null] +818 - Suit of armour - [null, null, null, null, null] +819 - Suit of armour - [null, null, null, null, null] +820 - Suit of armour - [null, null, null, null, null] +821 - Cannon - [null, null, null, null, null] +822 - Cannonballs - [null, null, null, null, null] +823 - Dummy - [null, Attack, null, null, null] +824 - Wooden defence - [null, null, null, null, null] +825 - null - [null, null, null, null, null] +826 - null - [null, null, null, null, null] +827 - null - [null, null, null, null, null] +828 - null - [null, null, null, null, null] +829 - Target - [null, null, null, null, null] +830 - null - [null, null, null, null, null] +831 - null - [null, null, null, null, null] +832 - null - [null, null, null, null, null] +833 - null - [null, null, null, null, null] +834 - Sword cabinet - [null, null, null, null, null] +835 - Sword cabinet - [null, null, null, null, null] +836 - Bow cabinet - [null, null, null, null, null] +837 - Axe cabinet - [null, null, null, null, null] +838 - Axe cabinet - [null, null, null, null, null] +839 - Bow cabinet - [null, null, null, null, null] +840 - null - [null, null, null, null, null] +841 - null - [null, null, null, null, null] +842 - null - [null, null, null, null, null] +843 - null - [null, null, null, null, null] +844 - null - [null, null, null, null, null] +845 - null - [null, null, null, null, null] +846 - null - [null, null, null, null, null] +847 - null - [null, null, null, null, null] +848 - Spear wall - [null, null, null, null, null] +849 - Spear wall - [null, null, null, null, null] +850 - Helmet rack - [null, null, null, null, null] +851 - Standard - [null, null, null, null, null] +852 - Standard - [null, null, null, null, null] +853 - Standard - [null, null, null, null, null] +854 - Standard - [null, null, null, null, null] +855 - Standard - [null, null, null, null, null] +856 - Standard - [null, null, null, null, null] +857 - Standard - [null, null, null, null, null] +858 - Standard - [null, null, null, null, null] +859 - Standard - [null, null, null, null, null] +860 - Flagpole - [null, null, null, null, null] +861 - Flagpole - [null, null, null, null, null] +862 - Flagpole - [null, null, null, null, null] +863 - Standard - [null, null, null, null, null] +864 - Standard - [null, null, null, null, null] +865 - Standard - [null, null, null, null, null] +866 - Standard - [null, null, null, null, null] +867 - Standard - [null, null, null, null, null] +868 - Standard - [null, null, null, null, null] +869 - Flagpole - [null, null, null, null, null] +870 - Totem Pole - [null, null, null, null, null] +871 - Bath pipes - [null, null, null, null, null] +872 - Large sewer pipe - [null, null, null, null, null] +873 - Sink - [null, null, null, null, null] +874 - Sink - [null, null, null, null, null] +875 - Bath - [null, null, null, null, null] +876 - null - [null, null, null, null, null] +877 - null - [null, null, null, null, null] +878 - Well - [null, null, null, null, null] +879 - Fountain - [null, null, null, null, null] +880 - Fountain - [null, null, null, null, null] +881 - Manhole - [Open, null, null, null, null] +882 - Manhole - [Climb-down, Close, null, null, null] +883 - Gate - [Open, null, null, null, null] +884 - Well - [null, null, null, null, null] +885 - Bar pumps - [null, null, null, null, null] +886 - Bar pumps - [null, null, null, null, null] +887 - Portrait - [null, null, null, null, null] +888 - Painting - [null, null, null, null, null] +889 - Painting - [null, null, null, null, null] +890 - Portrait - [null, null, null, null, null] +891 - Landscape - [null, null, null, null, null] +892 - Painting - [null, null, null, null, null] +893 - Painting - [null, null, null, null, null] +894 - Landscape - [null, null, null, null, null] +895 - Painting - [null, null, null, null, null] +896 - Star chart - [null, null, null, null, null] +897 - Star chart - [null, null, null, null, null] +898 - Cross - [null, null, null, null, null] +899 - Hanging banner - [null, null, null, null, null] +900 - Hanging banner - [null, null, null, null, null] +901 - Hanging banner - [null, null, null, null, null] +902 - Hanging banner - [null, null, null, null, null] +903 - Unicorn's head - [null, null, null, null, null] +904 - Dragon's head - [null, null, null, null, null] +905 - Dragon's head - [null, null, null, null, null] +906 - Bull's head - [null, null, null, null, null] +907 - Charms - [null, null, null, null, null] +908 - Magical symbol - [null, null, null, null, null] +909 - Plaque - [null, null, null, null, null] +910 - Evil eye decoration - [null, null, null, null, null] +911 - Glyphs - [null, null, null, null, null] +912 - null - [null, null, null, null, null] +913 - null - [null, null, null, null, null] +914 - null - [null, null, null, null, null] +915 - Font - [null, null, null, null, null] +916 - null - [null, null, null, null, null] +917 - null - [null, null, null, null, null] +918 - null - [null, null, null, null, null] +919 - null - [null, null, null, null, null] +920 - null - [null, null, null, null, null] +921 - null - [null, null, null, null, null] +922 - null - [null, null, null, null, null] +923 - null - [null, null, null, null, null] +924 - null - [null, null, null, null, null] +925 - null - [null, null, null, null, null] +926 - null - [null, null, null, null, null] +927 - null - [null, null, null, null, null] +928 - null - [null, null, null, null, null] +929 - null - [null, null, null, null, null] +930 - null - [null, null, null, null, null] +931 - null - [null, null, null, null, null] +932 - null - [null, null, null, null, null] +933 - null - [null, null, null, null, null] +934 - null - [null, null, null, null, null] +935 - null - [null, null, null, null, null] +936 - null - [null, null, null, null, null] +937 - null - [null, null, null, null, null] +938 - null - [null, null, null, null, null] +939 - null - [null, null, null, null, null] +940 - null - [null, null, null, null, null] +941 - null - [null, null, null, null, null] +942 - null - [null, null, null, null, null] +943 - null - [null, null, null, null, null] +944 - null - [null, null, null, null, null] +945 - null - [null, null, null, null, null] +946 - null - [null, null, null, null, null] +947 - null - [null, null, null, null, null] +948 - null - [null, null, null, null, null] +949 - null - [null, null, null, null, null] +950 - null - [null, null, null, null, null] +951 - null - [null, null, null, null, null] +952 - null - [null, null, null, null, null] +953 - null - [null, null, null, null, null] +954 - null - [null, null, null, null, null] +955 - Spooky picture - [null, null, null, null, null] +956 - null - [null, null, null, null, null] +957 - null - [null, null, null, null, null] +958 - null - [null, null, null, null, null] +959 - Clock face - [null, null, null, null, null] +960 - Clock face - [null, null, null, null, null] +961 - Bank notice board - [null, null, null, null, null] +962 - Noticeboard - [null, null, null, null, null] +963 - Clothes equipment - [null, null, null, null, null] +964 - Stuffed swordfish - [null, null, null, null, null] +965 - Stuffed swordfish - [null, null, null, null, null] +966 - Jolly Roger - [null, null, null, null, null] +967 - Hanging wheel - [null, null, null, null, null] +968 - Pirate map - [null, null, null, null, null] +969 - Fishing net - [null, null, null, null, null] +970 - Plaque - [Read, null, null, null, null] +971 - Bow and Arrow - [null, null, null, null, null] +972 - Arrows - [null, null, null, null, null] +973 - Javelin - [null, null, null, null, null] +974 - Studded Leather - [null, null, null, null, null] +975 - Dragonhide Leather - [null, null, null, null, null] +976 - null - [null, null, null, null, null] +977 - null - [null, null, null, null, null] +978 - null - [null, null, null, null, null] +979 - null - [null, null, null, null, null] +980 - null - [null, null, null, null, null] +981 - null - [null, null, null, null, null] +982 - null - [null, null, null, null, null] +983 - null - [null, null, null, null, null] +984 - null - [null, null, null, null, null] +985 - null - [null, null, null, null, null] +986 - null - [null, null, null, null, null] +987 - null - [null, null, null, null, null] +988 - null - [null, null, null, null, null] +989 - null - [null, null, null, null, null] +990 - null - [null, null, null, null, null] +991 - null - [null, null, null, null, null] +992 - null - [null, null, null, null, null] +993 - Stile - [Climb-over, null, null, null, null] +994 - null - [null, null, null, null, null] +995 - null - [null, null, null, null, null] +996 - null - [null, null, null, null, null] +997 - null - [null, null, null, null, null] +998 - null - [null, null, null, null, null] +999 - null - [null, null, null, null, null] +1000 - null - [null, null, null, null, null] +1001 - null - [null, null, null, null, null] +1002 - null - [null, null, null, null, null] +1003 - null - [null, null, null, null, null] +1004 - Broken Railing - [null, null, null, null, null] +1005 - Broken Railing - [null, null, null, null, null] +1006 - Broken Railing - [null, null, null, null, null] +1007 - null - [null, null, null, null, null] +1008 - null - [null, null, null, null, null] +1009 - null - [null, null, null, null, null] +1010 - Shelves - [null, null, null, null, null] +1011 - Shelves - [null, null, null, null, null] +1012 - Shelves - [null, null, null, null, null] +1013 - Cooking shelves - [null, null, null, null, null] +1014 - Shelves - [null, null, null, null, null] +1015 - Shelves - [null, null, null, null, null] +1016 - Shelves - [null, null, null, null, null] +1017 - Shelves - [null, null, null, null, null] +1018 - Shelves - [null, null, null, null, null] +1019 - Shelf - [null, null, null, null, null] +1020 - Shelf - [null, null, null, null, null] +1021 - Shelf - [null, null, null, null, null] +1022 - null - [null, null, null, null, null] +1023 - null - [null, null, null, null, null] +1024 - Shelves - [null, null, null, null, null] +1025 - Clothing shelves - [null, null, null, null, null] +1026 - null - [null, null, null, null, null] +1027 - Tanning line - [null, null, null, null, null] +1028 - Vat - [null, null, null, null, null] +1029 - Vat - [null, null, null, null, null] +1030 - Mangle - [null, null, null, null, null] +1031 - Mangle - [null, null, null, null, null] +1032 - Danger sign - [null, null, null, null, null] +1033 - Signpost - [null, null, null, null, null] +1034 - Signpost - [null, null, null, null, null] +1035 - Signpost - [null, null, null, null, null] +1036 - null - [null, null, null, null, null] +1037 - null - [null, null, null, null, null] +1038 - null - [null, null, null, null, null] +1039 - null - [null, null, null, null, null] +1040 - null - [null, null, null, null, null] +1041 - null - [null, null, null, null, null] +1042 - null - [null, null, null, null, null] +1043 - null - [null, null, null, null, null] +1044 - null - [null, null, null, null, null] +1045 - null - [null, null, null, null, null] +1046 - null - [null, null, null, null, null] +1047 - null - [null, null, null, null, null] +1048 - null - [null, null, null, null, null] +1049 - null - [null, null, null, null, null] +1050 - null - [null, null, null, null, null] +1051 - null - [null, null, null, null, null] +1052 - null - [null, null, null, null, null] +1053 - null - [null, null, null, null, null] +1054 - null - [null, null, null, null, null] +1055 - null - [null, null, null, null, null] +1056 - null - [null, null, null, null, null] +1057 - Sign - [null, null, null, null, null] +1058 - null - [null, null, null, null, null] +1059 - null - [null, null, null, null, null] +1060 - null - [null, null, null, null, null] +1061 - null - [null, null, null, null, null] +1062 - null - [null, null, null, null, null] +1063 - null - [null, null, null, null, null] +1064 - null - [null, null, null, null, null] +1065 - null - [null, null, null, null, null] +1066 - null - [null, null, null, null, null] +1067 - null - [null, null, null, null, null] +1068 - Sign - [null, null, null, null, null] +1069 - Sign - [null, null, null, null, null] +1070 - Sign - [null, null, null, null, null] +1071 - Sign - [null, null, null, null, null] +1072 - Sign - [null, null, null, null, null] +1073 - Sign - [null, null, null, null, null] +1074 - Sign - [null, null, null, null, null] +1075 - Sign - [null, null, null, null, null] +1076 - Sign - [null, null, null, null, null] +1077 - Sign - [null, null, null, null, null] +1078 - Sign - [null, null, null, null, null] +1079 - Signpost - [null, null, null, null, null] +1080 - Signpost - [null, null, null, null, null] +1081 - Signpost - [null, null, null, null, null] +1082 - Signpost - [null, null, null, null, null] +1083 - Signpost - [null, null, null, null, null] +1084 - Signpost - [null, null, null, null, null] +1085 - Signpost - [null, null, null, null, null] +1086 - Signpost - [null, null, null, null, null] +1087 - Signpost - [null, null, null, null, null] +1088 - Chair - [null, null, null, null, null] +1089 - Smashed chair - [null, null, null, null, null] +1090 - Chair - [null, null, null, null, null] +1091 - Chair - [null, null, null, null, null] +1092 - Chair - [null, null, null, null, null] +1093 - Chair - [null, null, null, null, null] +1094 - Chair - [null, null, null, null, null] +1095 - Stool - [null, null, null, null, null] +1096 - Rocking chair - [null, null, null, null, null] +1097 - Throne - [null, null, null, null, null] +1098 - Throne - [null, null, null, null, null] +1099 - Throne - [null, null, null, null, null] +1100 - Barstool - [null, null, null, null, null] +1101 - Chair - [null, null, null, null, null] +1102 - Stool - [null, null, null, null, null] +1103 - Stool - [null, null, null, null, null] +1104 - Bench - [null, null, null, null, null] +1105 - Throne - [null, null, null, null, null] +1106 - Bench - [null, null, null, null, null] +1107 - null - [null, null, null, null, null] +1108 - Throne - [null, null, null, null, null] +1109 - Throne - [null, null, null, null, null] +1110 - Chair - [null, null, null, null, null] +1111 - Chair - [null, null, null, null, null] +1112 - Pew - [null, null, null, null, null] +1113 - Stool - [null, null, null, null, null] +1114 - Ice Throne - [null, null, null, null, null] +1115 - Chair - [null, null, null, null, null] +1116 - Hedge - [null, null, null, null, null] +1117 - Hedge - [null, null, null, null, null] +1118 - Bush - [null, null, null, null, null] +1119 - Bush - [null, null, null, null, null] +1120 - Bush - [null, null, null, null, null] +1121 - Bush - [null, null, null, null, null] +1122 - Bush - [null, null, null, null, null] +1123 - Bush - [null, null, null, null, null] +1124 - Bush - [null, null, null, null, null] +1125 - Bush - [null, null, null, null, null] +1126 - Rosebush - [null, null, null, null, null] +1127 - null - [null, null, null, null, null] +1128 - null - [null, null, null, null, null] +1129 - null - [null, null, null, null, null] +1130 - null - [null, null, null, null, null] +1131 - null - [null, null, null, null, null] +1132 - null - [null, null, null, null, null] +1133 - null - [null, null, null, null, null] +1134 - null - [null, null, null, null, null] +1135 - null - [null, null, null, null, null] +1136 - null - [null, null, null, null, null] +1137 - null - [null, null, null, null, null] +1138 - null - [null, null, null, null, null] +1139 - null - [null, null, null, null, null] +1140 - null - [null, null, null, null, null] +1141 - null - [null, null, null, null, null] +1142 - null - [null, null, null, null, null] +1143 - null - [null, null, null, null, null] +1144 - null - [null, null, null, null, null] +1145 - null - [null, null, null, null, null] +1146 - null - [null, null, null, null, null] +1147 - Fairy house - [null, null, null, null, null] +1148 - Fairy house - [null, null, null, null, null] +1149 - Fairy house - [null, null, null, null, null] +1150 - Fairy bank - [null, null, null, null, null] +1151 - Fairy market stall - [null, null, null, null, null] +1152 - Potted fern - [null, null, null, null, null] +1153 - Potted fern - [null, null, null, null, null] +1154 - Potted fern - [null, null, null, null, null] +1155 - Potted fern - [null, null, null, null, null] +1156 - Potted flower - [null, null, null, null, null] +1157 - Potted flower - [null, null, null, null, null] +1158 - Potted plant - [null, null, null, null, null] +1159 - null - [null, null, null, null, null] +1160 - Potted plant - [null, null, null, null, null] +1161 - Cabbage - [null, Pick, null, null, null] +1162 - Bullrushes - [null, null, null, null, null] +1163 - Mushroom - [null, null, null, null, null] +1164 - Mushroom - [null, null, null, null, null] +1165 - Mushroom - [null, null, null, null, null] +1166 - Mushrooms - [null, null, null, null, null] +1167 - Mushroom - [null, null, null, null, null] +1168 - Mushrooms - [null, null, null, null, null] +1169 - Mushroom - [null, null, null, null, null] +1170 - Fungus - [null, null, null, null, null] +1171 - Fungus - [null, null, null, null, null] +1172 - Fungus - [null, null, null, null, null] +1173 - Small fern - [null, null, null, null, null] +1174 - Thistle - [null, null, null, null, null] +1175 - Waterlily - [null, null, null, null, null] +1176 - Waterlily - [null, null, null, null, null] +1177 - Waterlily - [null, null, null, null, null] +1178 - Heather - [null, null, null, null, null] +1179 - Heather - [null, null, null, null, null] +1180 - Heather - [null, null, null, null, null] +1181 - Nettles - [Pick, null, null, null, null] +1182 - null - [null, null, null, null, null] +1183 - null - [null, null, null, null, null] +1184 - Creeping plant - [null, null, null, null, null] +1185 - Rockery - [null, null, null, null, null] +1186 - Curling plant - [null, null, null, null, null] +1187 - Flower - [null, null, null, null, null] +1188 - Flower - [null, null, null, null, null] +1189 - Daisies - [null, null, null, null, null] +1190 - Sunflower - [null, null, null, null, null] +1191 - Sunflowers - [null, null, null, null, null] +1192 - Flowers - [null, null, null, null, null] +1193 - Flowers - [null, null, null, null, null] +1194 - Tulips - [null, null, null, null, null] +1195 - Flowers - [null, null, null, null, null] +1196 - Flowers - [null, null, null, null, null] +1197 - Flower - [null, null, null, null, null] +1198 - Flowers - [null, null, null, null, null] +1199 - Flowerbed - [null, null, null, null, null] +1200 - Flowerbed - [null, null, null, null, null] +1201 - Flowerbed - [null, null, null, null, null] +1202 - Jungle flower - [null, null, null, null, null] +1203 - Orchid - [null, null, null, null, null] +1204 - Jungle plant - [null, null, null, null, null] +1205 - Vine - [null, null, null, null, null] +1206 - Vine - [null, null, null, null, null] +1207 - Vine - [null, null, null, null, null] +1208 - Vine - [null, null, null, null, null] +1209 - null - [null, null, null, null, null] +1210 - null - [null, null, null, null, null] +1211 - null - [null, null, null, null, null] +1212 - null - [null, null, null, null, null] +1213 - null - [null, null, null, null, null] +1214 - null - [null, null, null, null, null] +1215 - null - [null, null, null, null, null] +1216 - null - [null, null, null, null, null] +1217 - null - [null, null, null, null, null] +1218 - null - [null, null, null, null, null] +1219 - null - [null, null, null, null, null] +1220 - null - [null, null, null, null, null] +1221 - null - [null, null, null, null, null] +1222 - null - [null, null, null, null, null] +1223 - null - [null, null, null, null, null] +1224 - null - [null, null, null, null, null] +1225 - null - [null, null, null, null, null] +1226 - null - [null, null, null, null, null] +1227 - null - [null, null, null, null, null] +1228 - null - [null, null, null, null, null] +1229 - null - [null, null, null, null, null] +1230 - null - [null, null, null, null, null] +1231 - Vine - [null, null, null, null, null] +1232 - null - [null, null, null, null, null] +1233 - null - [null, null, null, null, null] +1234 - null - [null, null, null, null, null] +1235 - null - [null, null, null, null, null] +1236 - null - [null, null, null, null, null] +1237 - null - [null, null, null, null, null] +1238 - null - [null, null, null, null, null] +1239 - null - [null, null, null, null, null] +1240 - null - [null, null, null, null, null] +1241 - null - [null, null, null, null, null] +1242 - null - [null, null, null, null, null] +1243 - null - [null, null, null, null, null] +1244 - null - [null, null, null, null, null] +1245 - null - [null, null, null, null, null] +1246 - null - [null, null, null, null, null] +1247 - null - [null, null, null, null, null] +1248 - null - [null, null, null, null, null] +1249 - null - [null, null, null, null, null] +1250 - null - [null, null, null, null, null] +1251 - null - [null, null, null, null, null] +1252 - null - [null, null, null, null, null] +1253 - null - [null, null, null, null, null] +1254 - null - [null, null, null, null, null] +1255 - null - [null, null, null, null, null] +1256 - null - [null, null, null, null, null] +1257 - null - [null, null, null, null, null] +1258 - null - [null, null, null, null, null] +1259 - null - [null, null, null, null, null] +1260 - null - [null, null, null, null, null] +1261 - null - [null, null, null, null, null] +1262 - null - [null, null, null, null, null] +1263 - null - [null, null, null, null, null] +1264 - null - [null, null, null, null, null] +1265 - null - [null, null, null, null, null] +1266 - null - [null, null, null, null, null] +1267 - null - [null, null, null, null, null] +1268 - null - [null, null, null, null, null] +1269 - null - [null, null, null, null, null] +1270 - null - [null, null, null, null, null] +1271 - null - [null, null, null, null, null] +1272 - null - [null, null, null, null, null] +1273 - null - [null, null, null, null, null] +1274 - null - [null, null, null, null, null] +1275 - null - [null, null, null, null, null] +1276 - Tree - [Chop down, null, hidden, null, null] +1277 - Tree - [Chop down, null, hidden, null, null] +1278 - Tree - [Chop down, null, hidden, null, null] +1279 - Tree - [Chop down, null, hidden, null, null] +1280 - Tree - [Chop down, null, hidden, null, null] +1281 - Oak - [Chop down, null, hidden, null, null] +1282 - Dead tree - [Chop down, null, hidden, null, null] +1283 - Dead tree - [Chop down, null, hidden, null, null] +1284 - Dead tree - [Chop down, null, hidden, null, null] +1285 - Dead tree - [Chop down, null, hidden, null, null] +1286 - Dead tree - [Chop down, null, hidden, null, null] +1287 - Dead tree - [null, null, null, null, null] +1288 - Dead tree - [null, null, null, null, null] +1289 - Dead tree - [Chop down, null, hidden, null, null] +1290 - Dead tree - [Chop down, null, hidden, null, null] +1291 - Dead tree - [Chop down, null, hidden, null, null] +1292 - Dramen tree - [Chop down, null, hidden, null, null] +1293 - Spirit tree - [Talk-to, Teleport, null, null, null] +1294 - Spirit tree - [Talk-to, Teleport, null, null, null] +1295 - Spirit tree - [Talk-to, Teleport, null, null, null] +1296 - Fallen tree - [null, null, null, null, null] +1297 - Fallen tree - [null, null, null, null, null] +1298 - Fern - [null, null, null, null, null] +1299 - Fern - [null, null, null, null, null] +1300 - Fern - [null, null, null, null, null] +1301 - Tree - [null, null, null, null, null] +1302 - Leafy tree - [null, null, null, null, null] +1303 - Tree - [null, null, null, null, null] +1304 - Tree - [null, null, null, null, null] +1305 - Tree - [null, null, null, null, null] +1306 - Magic tree - [Chop down, null, hidden, null, null] +1307 - Maple tree - [Chop down, null, hidden, null, null] +1308 - Willow - [Chop down, null, hidden, null, null] +1309 - Yew - [Chop down, null, hidden, null, null] +1310 - Tree - [null, null, null, null, null] +1311 - Palm - [null, null, null, null, null] +1312 - Palm - [null, null, null, null, null] +1313 - Plant - [null, null, null, null, null] +1314 - Plant - [null, null, null, null, null] +1315 - Evergreen - [Chop down, null, hidden, null, null] +1316 - Evergreen - [Chop down, null, hidden, null, null] +1317 - Spirit tree - [Talk-to, Teleport, null, null, null] +1318 - Evergreen - [Chop down, null, hidden, null, null] +1319 - Evergreen - [Chop down, null, hidden, null, null] +1320 - Mossy branch - [null, null, null, null, null] +1321 - Mossy branch - [null, null, null, null, null] +1322 - Hollow tree - [null, null, null, null, null] +1323 - Roots - [null, null, null, null, null] +1324 - Roots - [null, null, null, null, null] +1325 - Roots - [null, null, null, null, null] +1326 - Tropical tree - [null, null, null, null, null] +1327 - Tropical tree - [null, null, null, null, null] +1328 - Tropical tree - [null, null, null, null, null] +1329 - Tropical leaves - [null, null, null, null, null] +1330 - Tree - [Chop down, null, hidden, null, null] +1331 - Tree - [Chop down, null, hidden, null, null] +1332 - Tree - [Chop down, null, hidden, null, null] +1333 - Dead tree - [null, null, null, null, null] +1334 - Hollow log - [null, null, null, null, null] +1335 - Hollow log - [null, null, null, null, null] +1336 - Hollow log - [null, null, null, null, null] +1337 - Hollow log - [null, null, null, null, null] +1338 - Hollow log - [null, null, null, null, null] +1339 - Roots - [null, null, null, null, null] +1340 - Roots - [null, null, null, null, null] +1341 - Tree stump - [null, null, null, null, null] +1342 - Tree stump - [null, null, null, null, null] +1343 - Tree stump - [null, null, null, null, null] +1344 - Tree stump - [null, null, null, null, null] +1345 - Tree stump - [null, null, null, null, null] +1346 - Tree stump - [null, null, null, null, null] +1347 - Tree stump - [null, null, null, null, null] +1348 - Tree stump - [null, null, null, null, null] +1349 - Tree stump - [null, null, null, null, null] +1350 - Tree stump - [null, null, null, null, null] +1351 - Tree stump - [null, null, null, null, null] +1352 - Tree stump - [null, null, null, null, null] +1353 - Tree stump - [null, null, null, null, null] +1354 - Tree stump - [null, null, null, null, null] +1355 - Tree stump - [null, null, null, null, null] +1356 - Tree stump - [null, null, null, null, null] +1357 - Tree stump - [null, null, null, null, null] +1358 - Tree stump - [null, null, null, null, null] +1359 - Tree stump - [null, null, null, null, null] +1360 - Tropical tree - [null, null, null, null, null] +1361 - Tropical tree - [null, null, null, null, null] +1362 - Tropical tree - [null, null, null, null, null] +1363 - Roots - [null, null, null, null, null] +1364 - Roots - [null, null, null, null, null] +1365 - Dead tree - [Chop down, null, hidden, null, null] +1366 - Roots - [null, null, null, null, null] +1367 - Roots - [null, null, null, null, null] +1368 - Roots - [null, null, null, null, null] +1369 - Plant - [null, null, null, null, null] +1370 - Hollow log - [null, null, null, null, null] +1371 - Tropical tree - [null, null, null, null, null] +1372 - Tropical tree - [null, null, null, null, null] +1373 - Tropical tree - [null, null, null, null, null] +1374 - Tropical tree - [null, null, null, null, null] +1375 - Tropical tree - [null, null, null, null, null] +1376 - Tropical tree - [null, null, null, null, null] +1377 - Tropical tree - [null, null, null, null, null] +1378 - Hollow log - [null, null, null, null, null] +1379 - Hollow log - [null, null, null, null, null] +1380 - Roots - [null, null, null, null, null] +1381 - Roots - [null, null, null, null, null] +1382 - Roots - [null, null, null, null, null] +1383 - Dead tree - [Chop down, null, hidden, null, null] +1384 - Dead tree - [Chop down, null, hidden, null, null] +1385 - null - [null, null, null, null, null] +1386 - Roots - [null, null, null, null, null] +1387 - Roots - [null, null, null, null, null] +1388 - Roots - [null, null, null, null, null] +1389 - Roots - [null, null, null, null, null] +1390 - Jungle plant - [null, null, null, null, null] +1391 - Plant - [null, null, null, null, null] +1392 - Plant - [null, null, null, null, null] +1393 - Plant - [null, null, null, null, null] +1394 - Plant - [null, null, null, null, null] +1395 - Fly trap - [null, null, null, null, null] +1396 - Cactus - [null, null, null, null, null] +1397 - Cactus - [null, null, null, null, null] +1398 - Jungle plant - [null, null, null, null, null] +1399 - Jungle plant - [null, null, null, null, null] +1400 - Jungle plant - [null, null, null, null, null] +1401 - Jungle plant - [null, null, null, null, null] +1402 - Jungle plant - [null, null, null, null, null] +1403 - Cactus - [null, null, null, null, null] +1404 - Cactus - [null, null, null, null, null] +1405 - Cactus - [null, null, null, null, null] +1406 - Cactus - [null, null, null, null, null] +1407 - Whipping Plant - [null, null, null, null, null] +1408 - Pineapple Plant - [Pick, null, null, null, null] +1409 - Pineapple Plant - [Pick, null, null, null, null] +1410 - Pineapple Plant - [Pick, null, null, null, null] +1411 - Pineapple Plant - [Pick, null, null, null, null] +1412 - Pineapple Plant - [Pick, null, null, null, null] +1413 - Pineapple Plant - [Pick, null, null, null, null] +1414 - null - [null, null, null, null, null] +1415 - null - [null, null, null, null, null] +1416 - null - [null, null, null, null, null] +1417 - null - [null, null, null, null, null] +1418 - null - [null, null, null, null, null] +1419 - null - [null, null, null, null, null] +1420 - null - [null, null, null, null, null] +1421 - null - [null, null, null, null, null] +1422 - null - [null, null, null, null, null] +1423 - null - [null, null, null, null, null] +1424 - null - [null, null, null, null, null] +1425 - null - [null, null, null, null, null] +1426 - null - [null, null, null, null, null] +1427 - null - [null, null, null, null, null] +1428 - null - [null, null, null, null, null] +1429 - null - [null, null, null, null, null] +1430 - null - [null, null, null, null, null] +1431 - null - [null, null, null, null, null] +1432 - null - [null, null, null, null, null] +1433 - null - [null, null, null, null, null] +1434 - null - [null, null, null, null, null] +1435 - null - [null, null, null, null, null] +1436 - null - [null, null, null, null, null] +1437 - null - [null, null, null, null, null] +1438 - null - [null, null, null, null, null] +1439 - null - [null, null, null, null, null] +1440 - null - [null, null, null, null, null] +1441 - null - [null, null, null, null, null] +1442 - null - [null, null, null, null, null] +1443 - null - [null, null, null, null, null] +1444 - null - [null, null, null, null, null] +1445 - null - [null, null, null, null, null] +1446 - null - [null, null, null, null, null] +1447 - null - [null, null, null, null, null] +1448 - null - [null, null, null, null, null] +1449 - null - [null, null, null, null, null] +1450 - null - [null, null, null, null, null] +1451 - null - [null, null, null, null, null] +1452 - null - [null, null, null, null, null] +1453 - null - [null, null, null, null, null] +1454 - null - [null, null, null, null, null] +1455 - null - [null, null, null, null, null] +1456 - null - [null, null, null, null, null] +1457 - null - [null, null, null, null, null] +1458 - null - [null, null, null, null, null] +1459 - null - [null, null, null, null, null] +1460 - null - [null, null, null, null, null] +1461 - null - [null, null, null, null, null] +1462 - null - [null, null, null, null, null] +1463 - null - [null, null, null, null, null] +1464 - null - [null, null, null, null, null] +1465 - null - [null, null, null, null, null] +1466 - null - [null, null, null, null, null] +1467 - null - [null, null, null, null, null] +1468 - null - [null, null, null, null, null] +1469 - null - [null, null, null, null, null] +1470 - null - [null, null, null, null, null] +1471 - null - [null, null, null, null, null] +1472 - null - [null, null, null, null, null] +1473 - null - [null, null, null, null, null] +1474 - null - [null, null, null, null, null] +1475 - null - [null, null, null, null, null] +1476 - null - [null, null, null, null, null] +1477 - null - [null, null, null, null, null] +1478 - null - [null, null, null, null, null] +1479 - null - [null, null, null, null, null] +1480 - null - [null, null, null, null, null] +1481 - null - [null, null, null, null, null] +1482 - null - [null, null, null, null, null] +1483 - null - [null, null, null, null, null] +1484 - null - [null, null, null, null, null] +1485 - null - [null, null, null, null, null] +1486 - null - [null, null, null, null, null] +1487 - null - [null, null, null, null, null] +1488 - null - [null, null, null, null, null] +1489 - null - [null, null, null, null, null] +1490 - null - [null, null, null, null, null] +1491 - null - [null, null, null, null, null] +1492 - null - [null, null, null, null, null] +1493 - null - [null, null, null, null, null] +1494 - null - [null, null, null, null, null] +1495 - null - [null, null, null, null, null] +1496 - null - [null, null, null, null, null] +1497 - null - [null, null, null, null, null] +1498 - null - [null, null, null, null, null] +1499 - null - [null, null, null, null, null] +1500 - null - [null, null, null, null, null] +1501 - null - [null, null, null, null, null] +1502 - null - [null, null, null, null, null] +1503 - null - [null, null, null, null, null] +1504 - Door - [null, null, null, null, null] +1505 - Door - [null, null, null, null, null] +1506 - Large door - [Open, null, null, null, null] +1507 - Large door - [Close, null, null, null, null] +1508 - Large door - [Open, null, null, null, null] +1509 - null - [null, null, null, null, null] +1510 - null - [null, null, null, null, null] +1511 - Large door - [Close, null, null, null, null] +1512 - Large door - [Open, null, null, null, null] +1513 - Large door - [Open, null, null, null, null] +1514 - Large door - [Close, null, null, null, null] +1515 - Large door - [Close, null, null, null, null] +1516 - Large door - [Open, null, null, null, null] +1517 - Large door - [Close, null, null, null, null] +1518 - null - [null, null, null, null, null] +1519 - Large door - [Open, null, null, null, null] +1520 - Large door - [Close, null, null, null, null] +1521 - null - [null, null, null, null, null] +1522 - null - [null, null, null, null, null] +1523 - null - [null, null, null, null, null] +1524 - null - [null, null, null, null, null] +1525 - null - [null, null, null, null, null] +1526 - Curtain - [Open, null, null, null, null] +1527 - null - [null, null, null, null, null] +1528 - Curtain - [Open, null, null, null, null] +1529 - Curtain - [Close, null, null, null, null] +1530 - Door - [Open, null, null, null, null] +1531 - Door - [Close, null, null, null, null] +1532 - null - [null, null, null, null, null] +1533 - Door - [Open, null, null, null, null] +1534 - Door - [Close, null, null, null, null] +1535 - null - [null, null, null, null, null] +1536 - Door - [Open, null, null, null, null] +1537 - Door - [Close, null, null, null, null] +1538 - null - [null, null, null, null, null] +1539 - Door - [Open, null, null, null, null] +1540 - Door - [Close, null, null, null, null] +1541 - null - [null, null, null, null, null] +1542 - Door - [Open, null, null, null, null] +1543 - Door - [Close, null, null, null, null] +1544 - Door - [Open, null, null, null, null] +1545 - Door - [Close, null, null, null, null] +1546 - null - [null, null, null, null, null] +1547 - null - [null, null, null, null, null] +1548 - null - [null, null, null, null, null] +1549 - null - [null, null, null, null, null] +1550 - null - [null, null, null, null, null] +1551 - Gate - [Open, null, null, null, null] +1552 - Gate - [Close, null, null, null, null] +1553 - Gate - [Open, null, null, null, null] +1554 - null - [null, null, null, null, null] +1555 - null - [null, null, null, null, null] +1556 - Gate - [Close, null, null, null, null] +1557 - Gate - [Open, null, null, null, null] +1558 - Gate - [Open, null, null, null, null] +1559 - Gate - [null, null, null, null, null] +1560 - Gate - [Close, null, null, null, null] +1561 - Gate - [Close, null, null, null, null] +1562 - null - [null, null, null, null, null] +1563 - null - [null, null, null, null, null] +1564 - null - [null, null, null, null, null] +1565 - null - [null, null, null, null, null] +1566 - null - [null, null, null, null, null] +1567 - null - [null, null, null, null, null] +1568 - Trapdoor - [Open, null, null, null, null] +1569 - Trapdoor - [Open, null, null, null, null] +1570 - Trapdoor - [Climb-down, Close, null, null, null] +1571 - Trapdoor - [Climb-down, Close, null, null, null] +1572 - Boarded-up door - [null, null, null, null, null] +1573 - Doors - [Open, null, null, null, null] +1574 - Doors - [Close, null, null, null, null] +1575 - Doors - [Open, null, null, null, null] +1576 - Doors - [Close, null, null, null, null] +1577 - Doorway - [null, null, null, null, null] +1578 - Doorway - [null, null, null, null, null] +1579 - Doorway - [null, null, null, null, null] +1580 - Doorway - [null, null, null, null, null] +1581 - Doorway - [null, null, null, null, null] +1582 - null - [null, null, null, null, null] +1583 - Wall - [Push, null, null, null, null] +1584 - Wall - [Push, null, null, null, null] +1585 - null - [null, null, null, null, null] +1586 - Wall - [Push, null, null, null, null] +1587 - Wall - [Push, null, null, null, null] +1588 - null - [null, null, null, null, null] +1589 - Gate - [Open, null, null, null, null] +1590 - Gate - [Open, null, null, null, null] +1591 - Door - [Open, null, null, null, null] +1592 - Odd looking wall - [Push, null, null, null, null] +1593 - null - [null, null, null, null, null] +1594 - Dungeon door - [Open, null, null, null, null] +1595 - Door - [Open, null, null, null, null] +1596 - Gate - [Open, null, null, null, null] +1597 - Gate - [Open, null, null, null, null] +1598 - Gate - [Open, null, null, null, null] +1599 - Gate - [Open, null, null, null, null] +1600 - Magic guild door - [Open, null, null, null, null] +1601 - Magic guild door - [Open, null, null, null, null] +1602 - null - [null, null, null, null, null] +1603 - null - [null, null, null, null, null] +1604 - null - [null, null, null, null, null] +1605 - null - [null, null, null, null, null] +1606 - null - [null, null, null, null, null] +1607 - null - [null, null, null, null, null] +1608 - null - [null, null, null, null, null] +1609 - Scaffold - [null, null, null, null, null] +1610 - Scaffold - [null, null, null, null, null] +1611 - Scaffold - [null, null, null, null, null] +1612 - Scaffold - [null, null, null, null, null] +1613 - Timber - [null, null, null, null, null] +1614 - Timber - [null, null, null, null, null] +1615 - null - [null, null, null, null, null] +1616 - null - [null, null, null, null, null] +1617 - null - [null, null, null, null, null] +1618 - null - [null, null, null, null, null] +1619 - null - [null, null, null, null, null] +1620 - null - [null, null, null, null, null] +1621 - null - [null, null, null, null, null] +1622 - null - [null, null, null, null, null] +1623 - null - [null, null, null, null, null] +1624 - null - [null, null, null, null, null] +1625 - null - [null, null, null, null, null] +1626 - null - [null, null, null, null, null] +1627 - null - [null, null, null, null, null] +1628 - null - [null, null, null, null, null] +1629 - null - [null, null, null, null, null] +1630 - null - [null, null, null, null, null] +1631 - null - [null, null, null, null, null] +1632 - null - [null, null, null, null, null] +1633 - null - [null, null, null, null, null] +1634 - null - [null, null, null, null, null] +1635 - null - [null, null, null, null, null] +1636 - null - [null, null, null, null, null] +1637 - null - [null, null, null, null, null] +1638 - null - [null, null, null, null, null] +1639 - null - [null, null, null, null, null] +1640 - null - [null, null, null, null, null] +1641 - null - [null, null, null, null, null] +1642 - null - [null, null, null, null, null] +1643 - null - [null, null, null, null, null] +1644 - null - [null, null, null, null, null] +1645 - null - [null, null, null, null, null] +1646 - null - [null, null, null, null, null] +1647 - null - [null, null, null, null, null] +1648 - null - [null, null, null, null, null] +1649 - null - [null, null, null, null, null] +1650 - null - [null, null, null, null, null] +1651 - null - [null, null, null, null, null] +1652 - null - [null, null, null, null, null] +1653 - null - [null, null, null, null, null] +1654 - null - [null, null, null, null, null] +1655 - null - [null, null, null, null, null] +1656 - null - [null, null, null, null, null] +1657 - null - [null, null, null, null, null] +1658 - null - [null, null, null, null, null] +1659 - null - [null, null, null, null, null] +1660 - null - [null, null, null, null, null] +1661 - Bricks - [null, null, null, null, null] +1662 - Bricks - [null, null, null, null, null] +1663 - Bricks - [null, null, null, null, null] +1664 - null - [null, null, null, null, null] +1665 - null - [null, null, null, null, null] +1666 - null - [null, null, null, null, null] +1667 - null - [null, null, null, null, null] +1668 - null - [null, null, null, null, null] +1669 - null - [null, null, null, null, null] +1670 - null - [null, null, null, null, null] +1671 - null - [null, null, null, null, null] +1672 - null - [null, null, null, null, null] +1673 - null - [null, null, null, null, null] +1674 - null - [null, null, null, null, null] +1675 - null - [null, null, null, null, null] +1676 - null - [null, null, null, null, null] +1677 - null - [null, null, null, null, null] +1678 - null - [null, null, null, null, null] +1679 - null - [null, null, null, null, null] +1680 - null - [null, null, null, null, null] +1681 - null - [null, null, null, null, null] +1682 - null - [null, null, null, null, null] +1683 - null - [null, null, null, null, null] +1684 - null - [null, null, null, null, null] +1685 - null - [null, null, null, null, null] +1686 - null - [null, null, null, null, null] +1687 - null - [null, null, null, null, null] +1688 - null - [null, null, null, null, null] +1689 - null - [null, null, null, null, null] +1690 - null - [null, null, null, null, null] +1691 - null - [null, null, null, null, null] +1692 - null - [null, null, null, null, null] +1693 - null - [null, null, null, null, null] +1694 - null - [null, null, null, null, null] +1695 - null - [null, null, null, null, null] +1696 - null - [null, null, null, null, null] +1697 - null - [null, null, null, null, null] +1698 - null - [null, null, null, null, null] +1699 - null - [null, null, null, null, null] +1700 - null - [null, null, null, null, null] +1701 - null - [null, null, null, null, null] +1702 - null - [null, null, null, null, null] +1703 - null - [null, null, null, null, null] +1704 - null - [null, null, null, null, null] +1705 - null - [null, null, null, null, null] +1706 - null - [null, null, null, null, null] +1707 - null - [null, null, null, null, null] +1708 - null - [null, null, null, null, null] +1709 - null - [null, null, null, null, null] +1710 - null - [null, null, null, null, null] +1711 - null - [null, null, null, null, null] +1712 - null - [null, null, null, null, null] +1713 - null - [null, null, null, null, null] +1714 - null - [null, null, null, null, null] +1715 - null - [null, null, null, null, null] +1716 - null - [null, null, null, null, null] +1717 - null - [null, null, null, null, null] +1718 - null - [null, null, null, null, null] +1719 - null - [null, null, null, null, null] +1720 - null - [null, null, null, null, null] +1721 - null - [null, null, null, null, null] +1722 - Staircase - [Climb-up, null, null, null, null] +1723 - Staircase - [Climb-down, null, null, null, null] +1724 - Staircase - [Climb-down, null, null, null, null] +1725 - Staircase - [Climb-up, null, null, null, null] +1726 - Staircase - [Climb-down, null, null, null, null] +1727 - Staircase - [Climb-down, null, null, null, null] +1728 - Staircase - [Climb-down, null, null, null, null] +1729 - Staircase - [Climb-up, null, null, null, null] +1730 - Staircase - [Walk-up, null, null, null, null] +1731 - Staircase - [Walk-down, null, null, null, null] +1732 - Staircase - [Climb-down, null, null, null, null] +1733 - Staircase - [Climb-down, null, null, null, null] +1734 - Staircase - [Climb-up, null, null, null, null] +1735 - Staircase - [null, null, null, null, null] +1736 - Staircase - [Climb-down, null, null, null, null] +1737 - Staircase - [Climb-up, null, null, null, null] +1738 - Staircase - [Climb-up, null, null, null, null] +1739 - Staircase - [Climb, Climb-up, Climb-down, null, null] +1740 - Staircase - [Climb-down, null, null, null, null] +1741 - Staircase - [Climb-down, null, null, null, null] +1742 - Staircase - [Climb-up, null, null, null, null] +1743 - Staircase - [Climb, Climb-up, Climb-down, null, null] +1744 - Staircase - [Climb-down, null, null, null, null] +1745 - Staircase - [Climb-down, null, null, null, null] +1746 - Ladder - [Climb-down, null, null, null, null] +1747 - Ladder - [Climb-up, null, null, null, null] +1748 - Ladder - [Climb, Climb-up, Climb-down, null, null] +1749 - Ladder - [Climb-down, null, null, null, null] +1750 - Ladder - [Climb-up, null, null, null, null] +1751 - Ladder - [Climb, Climb-up, Climb-down, null, null] +1752 - Ladder - [Climb-up, null, null, null, null] +1753 - Ladder - [Climb-down, Climb-up, null, null, null] +1754 - Ladder - [Climb-down, null, null, null, null] +1755 - Ladder - [Climb-up, null, null, null, null] +1756 - Ladder - [Climb-down, null, null, null, null] +1757 - Ladder - [Climb-up, null, null, null, null] +1758 - Ladder - [Climb-down, null, null, null, null] +1759 - Ladder - [Climb-Down, null, null, null, null] +1760 - Stepladder - [null, null, null, null, null] +1761 - Steps - [Climb-up, null, null, null, null] +1762 - Climbing rope - [Climb, null, null, null, null] +1763 - Climbing rope - [null, null, null, null, null] +1764 - Climbing rope - [Climb, null, null, null, null] +1765 - Ladder - [Climb-down, null, null, null, null] +1766 - Ladder - [Climb-up, null, null, null, null] +1767 - Ladder - [Climb-down, null, null, null, null] +1768 - Ladder - [Climb-up, null, null, null, null] +1769 - null - [null, null, null, null, null] +1770 - null - [null, null, null, null, null] +1771 - null - [null, null, null, null, null] +1772 - null - [null, null, null, null, null] +1773 - null - [null, null, null, null, null] +1774 - null - [null, null, null, null, null] +1775 - null - [null, null, null, null, null] +1776 - null - [null, null, null, null, null] +1777 - null - [null, null, null, null, null] +1778 - Millstones - [null, null, null, null, null] +1779 - Sails - [null, null, null, null, null] +1780 - Sails - [null, null, null, null, null] +1781 - Flour bin - [Empty, null, null, null, null] +1782 - Flour bin - [Empty, null, null, null, null] +1783 - null - [null, null, null, null, null] +1784 - null - [null, null, null, null, null] +1785 - null - [null, null, null, null, null] +1786 - null - [null, null, null, null, null] +1787 - null - [null, null, null, null, null] +1788 - null - [null, null, null, null, null] +1789 - null - [null, null, null, null, null] +1790 - null - [null, null, null, null, null] +1791 - null - [null, null, null, null, null] +1792 - null - [null, null, null, null, null] +1793 - null - [null, null, null, null, null] +1794 - null - [null, null, null, null, null] +1795 - null - [null, null, null, null, null] +1796 - null - [null, null, null, null, null] +1797 - Waterfall rocks - [null, null, null, null, null] +1798 - null - [null, null, null, null, null] +1799 - null - [null, null, null, null, null] +1800 - null - [null, null, null, null, null] +1801 - null - [null, null, null, null, null] +1802 - null - [null, null, null, null, null] +1803 - null - [null, null, null, null, null] +1804 - Door - [Open, null, null, null, null] +1805 - Door - [Open, null, null, null, null] +1806 - null - [null, null, null, null, null] +1807 - null - [null, null, null, null, null] +1808 - null - [null, null, null, null, null] +1809 - null - [null, null, null, null, null] +1810 - Web - [Slash, null, null, null, null] +1811 - Sliced web - [null, null, null, null, null] +1812 - Portal - [null, null, null, null, null] +1813 - Stone stand - [null, null, null, null, null] +1814 - Lever - [Pull, null, null, null, null] +1815 - Lever - [Pull, null, null, null, null] +1816 - Lever - [Pull, null, null, null, null] +1817 - Lever - [Pull, null, null, null, null] +1818 - null - [null, null, null, null, null] +1819 - null - [null, null, null, null, null] +1820 - null - [null, null, null, null, null] +1821 - null - [null, null, null, null, null] +1822 - null - [null, null, null, null, null] +1823 - null - [null, null, null, null, null] +1824 - null - [null, null, null, null, null] +1825 - null - [null, null, null, null, null] +1826 - null - [null, null, null, null, null] +1827 - null - [null, null, null, null, null] +1828 - null - [null, null, null, null, null] +1829 - null - [null, null, null, null, null] +1830 - null - [null, null, null, null, null] +1831 - null - [null, null, null, null, null] +1832 - null - [null, null, null, null, null] +1833 - null - [null, null, null, null, null] +1834 - null - [null, null, null, null, null] +1835 - null - [null, null, null, null, null] +1836 - null - [null, null, null, null, null] +1837 - null - [null, null, null, null, null] +1838 - null - [null, null, null, null, null] +1839 - null - [null, null, null, null, null] +1840 - null - [null, null, null, null, null] +1841 - null - [null, null, null, null, null] +1842 - null - [null, null, null, null, null] +1843 - null - [null, null, null, null, null] +1844 - null - [null, null, null, null, null] +1845 - null - [null, null, null, null, null] +1846 - null - [null, null, null, null, null] +1847 - null - [null, null, null, null, null] +1848 - null - [null, null, null, null, null] +1849 - null - [null, null, null, null, null] +1850 - null - [null, null, null, null, null] +1851 - null - [null, null, null, null, null] +1852 - Bay window - [null, null, null, null, null] +1853 - null - [null, null, null, null, null] +1854 - null - [null, null, null, null, null] +1855 - null - [null, null, null, null, null] +1856 - null - [null, null, null, null, null] +1857 - null - [null, null, null, null, null] +1858 - null - [null, null, null, null, null] +1859 - null - [null, null, null, null, null] +1860 - null - [null, null, null, null, null] +1861 - null - [null, null, null, null, null] +1862 - null - [null, null, null, null, null] +1863 - null - [null, null, null, null, null] +1864 - Timber defence - [null, null, null, null, null] +1865 - null - [null, null, null, null, null] +1866 - null - [null, null, null, null, null] +1867 - null - [null, null, null, null, null] +1868 - null - [null, null, null, null, null] +1869 - null - [null, null, null, null, null] +1870 - null - [null, null, null, null, null] +1871 - null - [null, null, null, null, null] +1872 - null - [null, null, null, null, null] +1873 - null - [null, null, null, null, null] +1874 - null - [null, null, null, null, null] +1875 - null - [null, null, null, null, null] +1876 - Altar slab - [null, null, null, null, null] +1877 - null - [null, null, null, null, null] +1878 - null - [null, null, null, null, null] +1879 - null - [null, null, null, null, null] +1880 - null - [null, null, null, null, null] +1881 - null - [null, null, null, null, null] +1882 - null - [null, null, null, null, null] +1883 - null - [null, null, null, null, null] +1884 - null - [null, null, null, null, null] +1885 - null - [null, null, null, null, null] +1886 - null - [null, null, null, null, null] +1887 - null - [null, null, null, null, null] +1888 - null - [null, null, null, null, null] +1889 - null - [null, null, null, null, null] +1890 - null - [null, null, null, null, null] +1891 - null - [null, null, null, null, null] +1892 - null - [null, null, null, null, null] +1893 - null - [null, null, null, null, null] +1894 - null - [null, null, null, null, null] +1895 - null - [null, null, null, null, null] +1896 - Throne - [null, null, null, null, null] +1897 - Candlestick holder - [null, null, null, null, null] +1898 - Chair - [null, null, null, null, null] +1899 - Chair - [null, null, null, null, null] +1900 - Suit of armour - [null, null, null, null, null] +1901 - Table - [null, null, null, null, null] +1902 - null - [null, null, null, null, null] +1903 - null - [null, null, null, null, null] +1904 - null - [null, null, null, null, null] +1905 - null - [null, null, null, null, null] +1906 - null - [null, null, null, null, null] +1907 - null - [null, null, null, null, null] +1908 - null - [null, null, null, null, null] +1909 - null - [null, null, null, null, null] +1910 - null - [null, null, null, null, null] +1911 - null - [null, null, null, null, null] +1912 - null - [null, null, null, null, null] +1913 - null - [null, null, null, null, null] +1914 - null - [null, null, null, null, null] +1915 - null - [null, null, null, null, null] +1916 - null - [null, null, null, null, null] +1917 - null - [null, null, null, null, null] +1918 - null - [null, null, null, null, null] +1919 - null - [null, null, null, null, null] +1920 - null - [null, null, null, null, null] +1921 - null - [null, null, null, null, null] +1922 - null - [null, null, null, null, null] +1923 - null - [null, null, null, null, null] +1924 - null - [null, null, null, null, null] +1925 - null - [null, null, null, null, null] +1926 - null - [null, null, null, null, null] +1927 - null - [null, null, null, null, null] +1928 - null - [null, null, null, null, null] +1929 - null - [null, null, null, null, null] +1930 - null - [null, null, null, null, null] +1931 - null - [null, null, null, null, null] +1932 - null - [null, null, null, null, null] +1933 - null - [null, null, null, null, null] +1934 - null - [null, null, null, null, null] +1935 - null - [null, null, null, null, null] +1936 - null - [null, null, null, null, null] +1937 - null - [null, null, null, null, null] +1938 - null - [null, null, null, null, null] +1939 - Tower - [null, null, null, null, null] +1940 - null - [null, null, null, null, null] +1941 - null - [null, null, null, null, null] +1942 - null - [null, null, null, null, null] +1943 - null - [null, null, null, null, null] +1944 - null - [null, null, null, null, null] +1945 - null - [null, null, null, null, null] +1946 - null - [null, null, null, null, null] +1947 - Crumbling wall - [Climb-over, null, null, null, null] +1948 - Crumbling wall - [Climb-over, null, null, null, null] +1949 - Bricks - [null, null, null, null, null] +1950 - Bricks - [null, null, null, null, null] +1951 - Bricks - [null, null, null, null, null] +1952 - null - [null, null, null, null, null] +1953 - null - [null, null, null, null, null] +1954 - null - [null, null, null, null, null] +1955 - null - [null, null, null, null, null] +1956 - null - [null, null, null, null, null] +1957 - null - [null, null, null, null, null] +1958 - null - [null, null, null, null, null] +1959 - null - [null, null, null, null, null] +1960 - null - [null, null, null, null, null] +1961 - null - [null, null, null, null, null] +1962 - null - [null, null, null, null, null] +1963 - null - [null, null, null, null, null] +1964 - null - [null, null, null, null, null] +1965 - null - [null, null, null, null, null] +1966 - null - [null, null, null, null, null] +1967 - Tree Door - [Open, null, null, null, null] +1968 - Tree Door - [Open, null, null, null, null] +1969 - null - [null, null, null, null, null] +1970 - null - [null, null, null, null, null] +1971 - null - [null, null, null, null, null] +1972 - null - [null, null, null, null, null] +1973 - null - [null, null, null, null, null] +1974 - null - [null, null, null, null, null] +1975 - null - [null, null, null, null, null] +1976 - null - [null, null, null, null, null] +1977 - null - [null, null, null, null, null] +1978 - null - [null, null, null, null, null] +1979 - null - [null, null, null, null, null] +1980 - null - [Open, null, null, null, null] +1981 - null - [Open, null, null, null, null] +1982 - null - [null, null, null, null, null] +1983 - null - [null, null, null, null, null] +1984 - null - [null, null, null, null, null] +1985 - Root - [Search, null, null, null, null] +1986 - Root - [Search, null, null, null, null] +1987 - Log raft - [Board, null, null, null, null] +1988 - Broken log raft - [null, null, null, null, null] +1989 - Bookcase - [Search, null, null, null, null] +1990 - Crate - [Search, null, null, null, null] +1991 - Door - [Open, null, null, null, null] +1992 - Glarial's tombstone - [Read, null, null, null, null] +1993 - Glarial's tomb - [Search, null, null, null, null] +1994 - Closed chest - [Open, null, null, null, null] +1995 - Open chest - [Search, Shut, null, null, null] +1996 - Rock - [Swim to, null, null, null, null] +1997 - Rock - [Swim to, null, null, null, null] +1998 - Rope - [null, null, null, null, null] +1999 - Crate - [Search, null, null, null, null] +2000 - Door - [Open, null, null, null, null] +2001 - null - [null, null, null, null, null] +2002 - Door - [Open, null, null, null, null] +2003 - null - [null, null, null, null, null] +2004 - Pillar - [null, null, null, null, null] +2005 - Statue of Baxtorian - [null, null, null, null, null] +2006 - Statue of Glarial - [null, null, null, null, null] +2007 - null - [null, null, null, null, null] +2008 - null - [null, null, null, null, null] +2009 - null - [null, null, null, null, null] +2010 - Ledge - [Open, null, null, null, null] +2011 - Ledge - [Open, null, null, null, null] +2012 - Ledge - [Open, null, null, null, null] +2013 - Vine - [Check, null, null, null, null] +2014 - Chalice of Eternity - [Take treasure, null, null, null, null] +2015 - Chalice of Eternity - [Take treasure, null, null, null, null] +2016 - null - [null, null, null, null, null] +2017 - null - [null, null, null, null, null] +2018 - null - [null, null, null, null, null] +2019 - Whirlpool - [null, null, null, null, null] +2020 - Dead tree - [Climb, null, null, null, null] +2021 - null - [null, null, null, null, null] +2022 - Barrel - [Get in, null, null, null, null] +2023 - Achey Tree - [Chop, null, hidden, null, null] +2024 - Cauldron - [Drink From, null, null, null, null] +2025 - Door - [Open, null, null, null, null] +2026 - Fishing spot - [null, null, null, null, null] +2027 - null - [null, null, null, null, null] +2028 - Fishing spot - [Net, Bait, hidden, hidden, null] +2029 - Fishing spot - [Harpoon, Cage, hidden, hidden, null] +2030 - Fishing spot - [Net, Harpoon, hidden, hidden, null] +2031 - Fishing spot - [Cage, Harpoon, hidden, hidden, null] +2032 - Bedroom door - [Open, null, null, null, null] +2033 - Bedroom door - [null, null, null, null, null] +2034 - Door - [Open, null, null, null, null] +2035 - Door - [null, null, null, null, null] +2036 - Door - [Open, null, null, null, null] +2037 - Door - [null, null, null, null, null] +2038 - Dummy - [Hit, null, null, null, null] +2039 - Gate - [Open, null, null, null, null] +2040 - null - [null, null, null, null, null] +2041 - Gate - [Open, null, null, null, null] +2042 - null - [null, null, null, null, null] +2043 - Cauldron - [null, null, null, null, null] +2044 - Trough - [null, null, null, null, null] +2045 - null - [null, null, null, null, null] +2046 - null - [null, null, null, null, null] +2047 - null - [null, null, null, null, null] +2048 - Door - [Open, null, null, null, null] +2049 - Door - [Open, null, null, null, null] +2050 - Gate - [Open, hidden, null, null, null] +2051 - Gate - [Open, null, null, null, null] +2052 - null - [null, null, null, null, null] +2053 - null - [null, null, null, null, null] +2054 - Door - [Open, null, null, null, null] +2055 - null - [null, null, null, null, null] +2056 - Cupboard - [Open, null, null, null, null] +2057 - Cupboard - [Search, Close, null, null, null] +2058 - Gate - [Open, null, null, null, null] +2059 - null - [null, null, null, null, null] +2060 - Gate - [Open, null, null, null, null] +2061 - null - [null, null, null, null, null] +2062 - Cupboard - [Open, null, null, null, null] +2063 - Cupboard - [Search, Close, null, null, null] +2064 - Crate - [Search, null, null, null, null] +2065 - Rope Ladder - [Investigate, null, null, null, null] +2066 - Wall - [null, null, null, null, null] +2067 - Watchtower - [Investigate, null, null, null, null] +2068 - Fence - [Squeeze-through, null, null, null, null] +2069 - Door - [Open, null, null, null, null] +2070 - null - [null, null, null, null, null] +2071 - Crate - [Search, null, null, null, null] +2072 - Crate - [Search, Fill, null, null, null] +2073 - Banana Tree - [Pick, null, null, null, null] +2074 - Banana Tree - [Pick, null, null, null, null] +2075 - Banana Tree - [Pick, null, null, null, null] +2076 - Banana Tree - [Pick, null, null, null, null] +2077 - Banana Tree - [Pick, null, null, null, null] +2078 - Banana Tree - [Search, null, null, null, null] +2079 - Chest - [Open, null, null, null, null] +2080 - null - [null, null, null, null, null] +2081 - Gangplank - [Cross, null, null, null, null] +2082 - Gangplank - [Cross, null, null, null, null] +2083 - Gangplank - [Cross, null, null, null, null] +2084 - Gangplank - [Cross, null, null, null, null] +2085 - Gangplank - [Cross, null, null, null, null] +2086 - Gangplank - [Cross, null, null, null, null] +2087 - Gangplank - [Cross, null, null, null, null] +2088 - Gangplank - [Cross, null, null, null, null] +2089 - Rockery - [null, null, null, null, null] +2090 - Rocks - [Mine, Prospect, hidden, null, null] +2091 - Rocks - [Mine, Prospect, hidden, null, null] +2092 - Rocks - [Mine, Prospect, hidden, null, null] +2093 - Rocks - [Mine, Prospect, hidden, null, null] +2094 - Rocks - [Mine, Prospect, hidden, null, null] +2095 - Rocks - [Mine, Prospect, hidden, null, null] +2096 - Rocks - [Mine, Prospect, hidden, null, null] +2097 - Rocks - [Mine, Prospect, hidden, null, null] +2098 - Rocks - [Mine, Prospect, hidden, null, null] +2099 - Rocks - [Mine, Prospect, hidden, null, null] +2100 - Rocks - [Mine, Prospect, hidden, null, null] +2101 - Rocks - [Mine, Prospect, hidden, null, null] +2102 - Rocks - [Mine, Prospect, hidden, null, null] +2103 - Rocks - [Mine, Prospect, hidden, null, null] +2104 - Rocks - [Mine, Prospect, hidden, null, null] +2105 - Rocks - [Mine, Prospect, hidden, null, null] +2106 - Rocks - [Mine, Prospect, hidden, null, null] +2107 - Rocks - [Mine, Prospect, hidden, null, null] +2108 - Rocks - [Mine, Prospect, hidden, null, null] +2109 - Rocks - [Mine, Prospect, hidden, null, null] +2110 - Rocks - [Mine, Prospect, hidden, null, null] +2111 - Rocks - [Mine, Prospect, hidden, null, null] +2112 - Door - [Open, null, null, null, null] +2113 - Ladder - [Climb-down, null, null, null, null] +2114 - Coal Truck - [Remove-coal, Investigate, null, null, null] +2115 - Gate - [Open, null, null, null, null] +2116 - Gate - [Open, null, null, null, null] +2117 - Old wall - [Search, null, null, null, null] +2118 - Whirlpool - [null, null, null, null, null] +2119 - Rocks - [Mine, Prospect, hidden, null, null] +2120 - Rocks - [Mine, Prospect, hidden, null, null] +2121 - Rocks - [Mine, Prospect, hidden, null, null] +2122 - Rocks - [Mine, Prospect, hidden, null, null] +2123 - Rocks - [Mine, Prospect, hidden, null, null] +2124 - Rocks - [Mine, Prospect, hidden, null, null] +2125 - Rocks - [Mine, Prospect, hidden, null, null] +2126 - Rocks - [Mine, Prospect, hidden, null, null] +2127 - Rocks - [Mine, Prospect, hidden, null, null] +2128 - Rocks - [Mine, Prospect, hidden, null, null] +2129 - Rocks - [Mine, Prospect, hidden, null, null] +2130 - Rocks - [Mine, Prospect, hidden, null, null] +2131 - Rocks - [Mine, Prospect, hidden, null, null] +2132 - Rocks - [Mine, Prospect, hidden, null, null] +2133 - Rocks - [Mine, Prospect, hidden, null, null] +2134 - Rocks - [Mine, Prospect, hidden, null, null] +2135 - Rocks - [Mine, Prospect, hidden, null, null] +2136 - Rocks - [Mine, Prospect, hidden, null, null] +2137 - Rocks - [Mine, Prospect, hidden, null, null] +2138 - Rocks - [Mine, Prospect, hidden, null, null] +2139 - Rocks - [Mine, Prospect, hidden, null, null] +2140 - Rocks - [Mine, Prospect, hidden, null, null] +2141 - Chest - [null, null, null, null, null] +2142 - Cauldron of Thunder - [null, null, null, null, null] +2143 - Prison door - [Open, null, null, null, null] +2144 - Prison door - [Open, null, null, null, null] +2145 - Coffin - [Open, Search, null, null, null] +2146 - null - [Search, null, null, null, null] +2147 - Ladder - [Climb-down, null, null, null, null] +2148 - Ladder - [Climb-up, null, null, null, null] +2149 - Obelisk - [null, null, null, null, null] +2150 - null - [null, null, null, null, null] +2151 - Obelisk of Water - [null, null, null, null, null] +2152 - Obelisk of Air - [null, null, null, null, null] +2153 - Obelisk of Fire - [null, null, null, null, null] +2154 - Gate - [Open, null, null, null, null] +2155 - Gate - [Open, null, null, null, null] +2156 - Magic Portal - [Enter, null, null, null, null] +2157 - Magic Portal - [Enter, null, null, null, null] +2158 - Magic Portal - [Enter, null, null, null, null] +2159 - Barrel - [Climb-on, null, null, null, null] +2160 - Barrel - [Climb-on, null, null, null, null] +2161 - Barrel - [Climb-on, null, null, null, null] +2162 - Trawler net - [null, null, null, null, null] +2163 - Trawler net - [null, null, null, null, null] +2164 - Trawler net - [Inspect, null, null, null, null] +2165 - Trawler net - [Inspect, null, null, null, null] +2166 - Trawler net - [Inspect, null, null, null, null] +2167 - Leak - [Fill, null, null, null, null] +2168 - Repaired leak - [null, null, null, null, null] +2169 - Spray - [null, null, null, null, null] +2170 - Spray - [null, null, null, null, null] +2171 - null - [null, null, null, null, null] +2172 - Trawler net - [Inspect, null, null, null, null] +2173 - Trawler net - [Inspect, null, null, null, null] +2174 - Ship's ladder - [Climb-up, null, null, null, null] +2175 - Ship's ladder - [Climb-down, null, null, null, null] +2176 - Hole - [null, null, null, null, null] +2177 - Hull - [null, null, null, null, null] +2178 - Gangplank - [Cross, null, null, null, null] +2179 - Gangplank - [Cross, null, null, null, null] +2180 - Catapult - [null, null, null, null, null] +2181 - Ballista - [null, Fire, null, null, null] +2182 - Open chest - [Search, Close, null, null, null] +2183 - Closed chest - [Open, null, null, null, null] +2184 - Door - [Open, null, null, null, null] +2185 - Crumbled wall - [Climb-over, null, null, null, null] +2186 - Loose Railing - [Squeeze-through, null, null, null, null] +2187 - Stairs - [Climb-down, null, null, null, null] +2188 - Door - [Open, null, null, null, null] +2189 - Door - [Open, null, null, null, null] +2190 - Stairs - [Climb-down, null, null, null, null] +2191 - Chest - [Open, null, null, null, null] +2192 - Door - [Open, null, null, null, null] +2193 - Door - [Open, null, null, null, null] +2194 - Chest - [Search, Close, null, null, null] +2195 - null - [null, null, null, null, null] +2196 - null - [null, null, null, null, null] +2197 - null - [null, null, null, null, null] +2198 - null - [null, null, null, null, null] +2199 - Kitchen gate - [Open, null, null, null, null] +2200 - Kitchen gate - [Open, null, null, null, null] +2201 - null - [null, null, null, null, null] +2202 - null - [null, null, null, null, null] +2203 - null - [null, null, null, null, null] +2204 - null - [null, null, null, null, null] +2205 - null - [null, null, null, null, null] +2206 - null - [null, null, null, null, null] +2207 - null - [null, null, null, null, null] +2208 - null - [null, null, null, null, null] +2209 - null - [null, null, null, null, null] +2210 - Telescope - [Use, null, null, null, null] +2211 - Grave of Scorpius - [Read, null, null, null, null] +2212 - Toy corner - [null, null, null, null, null] +2213 - Bank booth - [Use, Use-quickly, Collect, null, null] +2214 - Bank booth - [null, null, null, null, null] +2215 - Closed bank booth - [null, null, null, null, null] +2216 - Broken cart - [Look-at, Search, null, null, null] +2217 - Mound of earth - [Look-at, Search, null, null, null] +2218 - Fissure - [Look-at, Search, null, null, null] +2219 - Fissure - [Look-at, Search, null, null, null] +2220 - Cave in - [null, Search, null, null, null] +2221 - Strange looking stone - [Look-at, Investigate, null, null, null] +2222 - Loose rocks - [null, Search, null, null, null] +2223 - Old sacks - [null, Search, null, null, null] +2224 - Ancient gallows - [Look-at, Search, null, null, null] +2225 - Waterfall rocks - [Look-at, Search, null, null, null] +2226 - Smashed table - [Look-at, Craft, null, null, null] +2227 - Crude raft - [null, Disembark, null, null, null] +2228 - null - [null, null, null, null, null] +2229 - Tribal Statue - [Investigate, null, null, null, null] +2230 - Travel cart - [null, Board, Pay-fare, null, null] +2231 - Rocks - [Climb, null, null, null, null] +2232 - null - [null, null, null, null, null] +2233 - null - [null, null, null, null, null] +2234 - Well stacked rocks - [Investigate, Search, null, null, null] +2235 - Tomb dolmen - [Inspect, Search, null, null, null] +2236 - Climbing rocks - [Climb, null, null, null, null] +2237 - Palm tree - [null, Search, null, null, null] +2238 - Hillside entrance - [Enter, null, null, null, null] +2239 - Hillside entrance - [Enter, null, null, null, null] +2240 - Carved doors - [Open, Search, null, null, null] +2241 - Carved doors - [Open, Search, null, null, null] +2242 - Tomb exit - [Open, Search, null, null, null] +2243 - Tomb exit - [Open, Search, null, null, null] +2244 - Jungle plant - [null, null, null, null, null] +2245 - Jungle plant - [null, null, null, null, null] +2246 - Tomb doors - [Open, Search, null, null, null] +2247 - Tomb doors - [Open, Search, null, null, null] +2248 - Tomb doors - [Open, Search, null, null, null] +2249 - Tomb doors - [Open, Search, null, null, null] +2250 - Tomb doors - [Open, Search, null, null, null] +2251 - null - [null, null, null, null, null] +2252 - null - [null, null, null, null, null] +2253 - Tomb exit - [Open, Search, null, null, null] +2254 - Tomb exit - [Open, Search, null, null, null] +2255 - Ancient metal gate - [Open, Search, null, null, null] +2256 - Ancient metal gate - [Open, Search, null, null, null] +2257 - Rocks - [Climb, null, null, null, null] +2258 - Tomb dolmen - [Look-at, Search, null, null, null] +2259 - Metal gate - [Open, null, null, null, null] +2260 - Metal gate - [Open, null, null, null, null] +2261 - Wooden gate - [Open, null, null, null, null] +2262 - Wooden gate - [Open, null, null, null, null] +2263 - null - [null, null, null, null, null] +2264 - null - [null, null, null, null, null] +2265 - Travel cart - [null, Board, Pay-fare, null, null] +2266 - Blacksmith's door - [Open, null, null, null, null] +2267 - Blacksmith's door - [Open, null, null, null, null] +2268 - Ladder - [Climb-up, null, null, null, null] +2269 - Ladder - [Climb-down, null, null, null, null] +2270 - Plant - [null, null, null, null, null] +2271 - Cupboard - [Open, null, null, null, null] +2272 - Cupboard - [Search, Shut, null, null, null] +2273 - Rope swing - [Swing-on, null, null, null, null] +2274 - Rope swing - [Swing-on, null, null, null, null] +2275 - Rock - [null, null, null, null, null] +2276 - Rock - [null, null, null, null, null] +2277 - Rock - [null, null, null, null, null] +2278 - Rock - [null, null, null, null, null] +2279 - Ropeswing - [null, null, null, null, null] +2280 - Ropeswing - [null, null, null, null, null] +2281 - Ropeswing - [null, null, null, null, null] +2282 - Ropeswing - [Swing-on, null, null, null, null] +2283 - Ropeswing - [Swing-on, null, null, null, null] +2284 - Obstacle net - [Climb-over, null, null, null, null] +2285 - Obstacle net - [Climb-over, null, null, null, null] +2286 - Obstacle net - [Climb-over, null, null, null, null] +2287 - Obstacle pipe - [Squeeze-through, null, null, null, null] +2288 - Obstacle pipe - [Squeeze-through, null, null, null, null] +2289 - Hollow tree - [Chop down, null, hidden, null, null] +2290 - Obstacle pipe - [Squeeze-through, null, null, null, null] +2291 - null - [null, null, null, null, null] +2292 - null - [null, null, null, null, null] +2293 - null - [null, null, null, null, null] +2294 - Log balance - [Walk-across, null, null, null, null] +2295 - Log balance - [Walk-across, null, null, null, null] +2296 - Log balance - [Walk-across, null, null, null, null] +2297 - Log balance - [Walk-across, null, null, null, null] +2298 - Climbing rocks - [Climb-up, null, null, null, null] +2299 - Climbing rocks - [Climb-up, null, null, null, null] +2300 - Climbing rocks - [Climb-up, null, null, null, null] +2301 - Balancing ledge - [Walk-across, null, null, null, null] +2302 - Balancing ledge - [Walk-across, null, null, null, null] +2303 - Balancing ledge - [Walk-across, null, null, null, null] +2304 - Spikes - [null, null, null, null, null] +2305 - Spikes - [null, null, null, null, null] +2306 - null - [null, null, null, null, null] +2307 - Gate - [Open, null, null, null, null] +2308 - Gate - [Open, null, null, null, null] +2309 - Door - [Open, null, null, null, null] +2310 - Tree stump - [null, null, null, null, null] +2311 - Stepping stone - [Cross, null, null, null, null] +2312 - Balancing rope - [Walk-on, null, null, null, null] +2313 - Tree branch - [Climb, null, null, null, null] +2314 - Tree branch - [Climb-down, null, null, null, null] +2315 - Tree branch - [Climb-down, null, null, null, null] +2316 - Staircase - [Climb-up, null, null, null, null] +2317 - Pile of rubble - [Climb-up, null, null, null, null] +2318 - Pile of rubble - [Climb-down, null, null, null, null] +2319 - Monkeybars - [null, null, null, null, null] +2320 - Monkeybars - [Swing across, null, null, null, null] +2321 - Monkeybars - [Swing across, null, null, null, null] +2322 - Ropeswing - [Swing-on, null, null, null, null] +2323 - Ropeswing - [Swing-on, null, null, null, null] +2324 - Ropeswing - [Swing-on, null, null, null, null] +2325 - Ropeswing - [Swing-on, null, null, null, null] +2326 - Branch - [null, null, null, null, null] +2327 - Long branched tree - [null, null, null, null, null] +2328 - Rocks - [Climb, null, null, null, null] +2329 - null - [null, null, null, null, null] +2330 - null - [null, null, null, null, null] +2331 - null - [null, null, null, null, null] +2332 - A wooden log - [Cross, null, null, null, null] +2333 - Stepping stones - [Cross, null, null, null, null] +2334 - Stepping stones - [Cross, null, null, null, null] +2335 - Stepping stones - [Cross, null, null, null, null] +2336 - Hole - [null, null, null, null, null] +2337 - Sturdy door - [Open, null, null, null, null] +2338 - Door - [Open, null, null, null, null] +2339 - Sturdy door - [Open, null, null, null, null] +2340 - null - [null, null, null, null, null] +2341 - Wall - [Push, null, null, null, null] +2342 - Grill - [Listen-at, null, null, null, null] +2343 - Brick - [null, null, null, null, null] +2344 - Brick - [null, null, null, null, null] +2345 - Brick - [null, null, null, null, null] +2346 - Brick - [null, null, null, null, null] +2347 - Brick - [null, null, null, null, null] +2348 - Brick - [null, null, null, null, null] +2349 - Brick - [null, null, null, null, null] +2350 - Winch - [Operate, null, null, null, null] +2351 - Winch - [Operate, null, null, null, null] +2352 - Rope - [Climb-up, null, null, null, null] +2353 - Rope - [Climb-up, null, null, null, null] +2354 - Sacks - [Search, null, null, null, null] +2355 - Sacks - [Search, null, null, null, null] +2356 - Sacks - [Search, null, null, null, null] +2357 - Bush - [Search, null, null, null, null] +2358 - Bush - [Search, null, null, null, null] +2359 - null - [null, null, null, null, null] +2360 - Chest - [Search, Close, null, null, null] +2361 - Chest - [Open, null, null, null, null] +2362 - Brick - [Search, null, null, null, null] +2363 - Panning point - [Pan, null, null, null, null] +2364 - Crate - [null, null, null, null, null] +2365 - Crate - [null, null, null, null, null] +2366 - Signpost - [Read, null, null, null, null] +2367 - Signpost - [Read, null, null, null, null] +2368 - Signpost - [Read, null, null, null, null] +2369 - Signpost - [Read, null, null, null, null] +2370 - Signpost - [Read, null, null, null, null] +2371 - Signpost - [Read, null, null, null, null] +2372 - Bookcase - [Search, null, null, null, null] +2373 - Cupboard - [Open, null, null, null, null] +2374 - Cupboard - [Close, Search, null, null, null] +2375 - Specimen tray - [null, Search, null, null, null] +2376 - Soil - [null, null, null, null, null] +2377 - Soil - [null, null, null, null, null] +2378 - Soil - [null, null, null, null, null] +2379 - Campsite bed - [null, null, null, null, null] +2380 - Chest - [Search, Open, null, null, null] +2381 - Soil - [null, null, null, null, null] +2382 - Soil - [null, null, null, null, null] +2383 - Soil - [null, null, null, null, null] +2384 - null - [null, null, null, null, null] +2385 - null - [null, null, null, null, null] +2386 - null - [null, null, null, null, null] +2387 - null - [null, null, null, null, null] +2388 - null - [null, null, null, null, null] +2389 - null - [null, null, null, null, null] +2390 - null - [null, null, null, null, null] +2391 - Gate - [Open, Search, null, null, null] +2392 - Gate - [Open, Search, null, null, null] +2393 - Gnome goal - [Shoot, null, null, null, null] +2394 - Gate - [Open, null, null, null, null] +2395 - null - [null, null, null, null, null] +2396 - Bed - [null, null, null, null, null] +2397 - Door - [Open, null, null, null, null] +2398 - Door - [Open, null, null, null, null] +2399 - Door - [Open, null, null, null, null] +2400 - Cupboard - [Open, null, null, null, null] +2401 - Cupboard - [Shut, Search, null, null, null] +2402 - Bookcase - [null, Search, null, null, null] +2403 - Chest - [Open, null, null, null, null] +2404 - Chest - [Search, Close, null, null, null] +2405 - Ladder - [Climb-up, null, null, null, null] +2406 - Door - [Open, null, null, null, null] +2407 - Magic door - [Open, null, null, null, null] +2408 - Ladder - [Climb-down, null, null, null, null] +2409 - Tree - [Chop, null, null, null, null] +2410 - Ladder - [Climb-up, null, null, null, null] +2411 - Sturdy door - [Open, null, null, null, null] +2412 - Gangplank - [Cross, null, null, null, null] +2413 - Gangplank - [Cross, null, null, null, null] +2414 - Gangplank - [Cross, null, null, null, null] +2415 - Gangplank - [Cross, null, null, null, null] +2416 - Large door - [Open, null, null, null, null] +2417 - Large door - [Close, null, null, null, null] +2418 - Chest - [null, Deposit, Shut, null, null] +2419 - null - [null, null, null, null, null] +2420 - null - [null, null, null, null, null] +2421 - Lever - [Pull, null, null, null, null] +2422 - Lever - [Pull, null, null, null, null] +2423 - Lever - [Pull, null, null, null, null] +2424 - Lever - [Pull, null, null, null, null] +2425 - Lever - [Pull, null, null, null, null] +2426 - Lever - [Pull, null, null, null, null] +2427 - Door - [Open, null, null, null, null] +2428 - Door - [Open, null, null, null, null] +2429 - Door - [Open, null, null, null, null] +2430 - Door - [Open, null, null, null, null] +2431 - Door - [Open, null, null, null, null] +2432 - Gate - [Open, null, null, null, null] +2433 - Gate - [Open, null, null, null, null] +2434 - Cupboard - [Open, null, null, null, null] +2435 - Cupboard - [null, Search, Close, null, null] +2436 - Closed chest - [Open, null, null, null, null] +2437 - null - [null, null, null, null, null] +2438 - Gate - [Open, null, null, null, null] +2439 - Gate - [Open, null, null, null, null] +2440 - Pillar - [null, null, null, null, null] +2441 - Pillar - [null, null, null, null, null] +2442 - Pillar - [null, null, null, null, null] +2443 - Pillar - [null, null, null, null, null] +2444 - Trapdoor - [Open, null, null, null, null] +2445 - null - [null, null, null, null, null] +2446 - Trap door - [Open, null, null, null, null] +2447 - Tree - [Climb-up, null, null, null, null] +2448 - Tree - [Climb-down, null, null, null, null] +2449 - Daconia rocks - [null, null, null, null, null] +2450 - Daconia rocks - [null, null, null, null, null] +2451 - Roots - [Push, null, null, null, null] +2452 - Mysterious ruins - [Enter, null, null, null, null] +2453 - Mysterious ruins - [Enter, null, null, null, null] +2454 - Mysterious ruins - [Enter, null, null, null, null] +2455 - Mysterious ruins - [Enter, null, null, null, null] +2456 - Mysterious ruins - [Enter, null, null, null, null] +2457 - Mysterious ruins - [Enter, null, null, null, null] +2458 - Mysterious ruins - [Enter, null, null, null, null] +2459 - Mysterious ruins - [Enter, null, null, null, null] +2460 - Mysterious ruins - [Enter, null, null, null, null] +2461 - Mysterious ruins - [Enter, null, null, null, null] +2462 - Mysterious ruins - [Enter, null, null, null, null] +2463 - null - [null, null, null, null, null] +2464 - Strange stones - [Search, null, null, null, null] +2465 - Portal - [Use, null, null, null, null] +2466 - Portal - [Use, null, null, null, null] +2467 - Portal - [Use, null, null, null, null] +2468 - Portal - [Use, null, null, null, null] +2469 - Portal - [Use, null, null, null, null] +2470 - Portal - [Use, null, null, null, null] +2471 - Portal - [Use, null, null, null, null] +2472 - Portal - [Use, null, null, null, null] +2473 - Portal - [Use, null, null, null, null] +2474 - Portal - [Use, null, null, null, null] +2475 - Portal - [Use, null, null, null, null] +2476 - Portal - [Use, null, null, null, null] +2477 - Portal - [Use, null, null, null, null] +2478 - Altar - [Craft-rune, null, null, null, null] +2479 - Altar - [Craft-rune, null, null, null, null] +2480 - Altar - [Craft-rune, null, null, null, null] +2481 - Altar - [Craft-rune, null, null, null, null] +2482 - Altar - [Craft-rune, null, null, null, null] +2483 - Altar - [Craft-rune, null, null, null, null] +2484 - Altar - [Craft-rune, null, null, null, null] +2485 - Altar - [Craft-rune, null, null, null, null] +2486 - Altar - [Craft-rune, null, null, null, null] +2487 - Altar - [Craft-rune, null, null, null, null] +2488 - Altar - [Craft-rune, null, null, null, null] +2489 - Altar - [Craft-rune, null, null, null, null] +2490 - null - [null, null, null, null, null] +2491 - Rune Essence - [Mine, Prospect, hidden, null, null] +2492 - Portal - [Use, null, null, null, null] +2493 - Pillar - [null, null, null, null, null] +2494 - Pillar - [null, null, null, null, null] +2495 - Pillar - [null, null, null, null, null] +2496 - null - [null, null, null, null, null] +2497 - Mysterious stone - [null, null, null, null, null] +2498 - Mysterious glow - [null, null, null, null, null] +2499 - Mysterious glow - [null, null, null, null, null] +2500 - Mysterious glow - [null, null, null, null, null] +2501 - Mysterious glow - [null, null, null, null, null] +2502 - Mysterious glow - [null, null, null, null, null] +2503 - Ruined Pillar - [null, null, null, null, null] +2504 - Ruined Pillar - [null, null, null, null, null] +2505 - Pillar - [null, null, null, null, null] +2506 - Ruined Pillar - [null, null, null, null, null] +2507 - Pillar - [null, null, null, null, null] +2508 - Rubble - [null, null, null, null, null] +2509 - Rubble - [null, null, null, null, null] +2510 - Rubble - [null, null, null, null, null] +2511 - Tower ladder - [Climb-up, null, null, null, null] +2512 - Tower ladder - [Climb-down, null, null, null, null] +2513 - Target - [Fire-at, null, null, null, null] +2514 - Guild door - [Open, null, null, null, null] +2515 - Row boat - [null, null, null, null, null] +2516 - Row boat - [null, null, null, null, null] +2517 - Ladder - [Climb-up, null, null, null, null] +2518 - null - [null, null, null, null, null] +2519 - Crates - [null, null, null, null, null] +2520 - Big door - [Close, null, null, null, null] +2521 - Big door - [Close, null, null, null, null] +2522 - Spooky stairs - [Walk-down, null, null, null, null] +2523 - Spooky stairs - [Walk-up, null, null, null, null] +2524 - Cupboard - [Open, null, null, null, null] +2525 - Cupboard - [Search, Close, null, null, null] +2526 - Door - [Open, null, null, null, null] +2527 - Door - [null, null, null, null, null] +2528 - Door - [Open, null, null, null, null] +2529 - Door - [null, null, null, null, null] +2530 - Barrel - [Search, null, null, null, null] +2531 - Mud patch - [null, null, null, null, null] +2532 - null - [null, null, null, null, null] +2533 - Mud pile - [Climb, null, null, null, null] +2534 - Door - [Open, null, null, null, null] +2535 - Door - [Open, null, null, null, null] +2536 - Door - [null, null, null, null, null] +2537 - Door - [Open, null, null, null, null] +2538 - Door - [null, null, null, null, null] +2539 - Stairs - [Walk-up, null, null, null, null] +2540 - Stairs - [Walk-down, null, null, null, null] +2541 - Sewer pipe - [Open, null, null, null, null] +2542 - Pipe - [Climb-up, null, null, null, null] +2543 - Manhole - [Open, null, null, null, null] +2544 - Manhole - [Climb-down, null, null, null, null] +2545 - Manhole cover - [Close, null, null, null, null] +2546 - Door - [Open, null, null, null, null] +2547 - Door - [Close, null, null, null, null] +2548 - Door - [Open, null, null, null, null] +2549 - Door - [Close, null, null, null, null] +2550 - Door - [Open, Pick-lock, null, null, null] +2551 - Door - [Open, Pick-lock, null, null, null] +2552 - Gate - [Open, Pick-lock, null, null, null] +2553 - Gate - [Open, Pick-lock, null, null, null] +2554 - Door - [Open, Pick-lock, null, null, null] +2555 - Door - [Open, Pick-lock, null, null, null] +2556 - Door - [Open, Pick-lock, null, null, null] +2557 - Door - [Open, Pick-lock, null, null, null] +2558 - Door - [Open, Pick-lock, null, null, null] +2559 - Door - [Open, Pick-lock, null, null, null] +2560 - Silk stall - [null, Steal-from, null, null, null] +2561 - Baker's stall - [null, Steal-from, null, null, null] +2562 - Gem stall - [null, Steal-from, null, null, null] +2563 - Fur stall - [null, Steal-from, null, null, null] +2564 - Spice stall - [null, Steal-from, null, null, null] +2565 - Silver stall - [null, Steal-from, null, null, null] +2566 - Chest - [Open, Search for traps, null, null, null] +2567 - Chest - [Open, Search for traps, null, null, null] +2568 - Chest - [Open, Search for traps, null, null, null] +2569 - Chest - [Open, Search for traps, null, null, null] +2570 - Chest - [Open, Search for traps, null, null, null] +2571 - Chest - [Open, Search for traps, null, null, null] +2572 - Chest - [Open, Search for traps, null, null, null] +2573 - Chest - [Open, Search for traps, null, null, null] +2574 - null - [null, null, null, null, null] +2575 - Marshy jungle vine - [null, Search, hidden, null, null] +2576 - Marshy jungle vine - [null, null, null, null, null] +2577 - Palm tree - [null, Search, null, null, null] +2578 - Palm tree - [null, null, null, null, null] +2579 - Scorched earth - [null, Search, null, null, null] +2580 - Scorched earth - [null, null, null, null, null] +2581 - Rock - [null, Search, null, null, null] +2582 - Rock - [null, null, null, null, null] +2583 - Fungus covered Cavern wall - [null, Search, hidden, null, null] +2584 - Rocks - [null, Search, null, null, null] +2585 - Hand holds - [Climb, null, null, null, null] +2586 - Rocks - [Mine, Prospect, hidden, null, null] +2587 - Chest - [Open, null, null, null, null] +2588 - Chest - [Search, Close, null, null, null] +2589 - Hole - [Repair, null, null, null, null] +2590 - Ladder - [Climb-down, null, null, null, null] +2591 - Ladder - [Climb-down, null, null, null, null] +2592 - Ladder - [Climb-up, null, null, null, null] +2593 - Gangplank - [Cross, null, null, null, null] +2594 - Gangplank - [Cross, null, null, null, null] +2595 - Door - [Open, null, null, null, null] +2596 - Red door - [Open, null, null, null, null] +2597 - Orange door - [Open, null, null, null, null] +2598 - Yellow door - [Open, null, null, null, null] +2599 - Blue door - [Open, null, null, null, null] +2600 - Magenta door - [Open, null, null, null, null] +2601 - Green door - [Open, null, null, null, null] +2602 - Exit door - [Open, null, null, null, null] +2603 - Chest - [Open, null, null, null, null] +2604 - Chest - [Search, Close, null, null, null] +2605 - Ladder - [Climb-down, null, null, null, null] +2606 - Wall - [Open, null, null, null, null] +2607 - Rocks - [Mine, Prospect, hidden, null, null] +2608 - Rocks - [Mine, Prospect, hidden, null, null] +2609 - Rocks - [Mine, Prospect, hidden, null, null] +2610 - Rocks - [Mine, Prospect, hidden, null, null] +2611 - Rocks - [Mine, Prospect, hidden, null, null] +2612 - Cupboard - [Open, null, null, null, null] +2613 - Cupboard - [Search, Close, null, null, null] +2614 - Coffin - [Open, null, null, null, null] +2615 - Coffin - [Search, Close, null, null, null] +2616 - Stairs - [Walk-Down, null, null, null, null] +2617 - Stairs - [Walk-Up, null, null, null, null] +2618 - null - [null, null, null, null, null] +2619 - Barrel - [Search, null, null, null, null] +2620 - Crate - [Search, null, null, null, null] +2621 - Door - [Open, null, null, null, null] +2622 - Door - [Open, null, null, null, null] +2623 - Gate - [Open, null, null, null, null] +2624 - Door - [Open, null, null, null, null] +2625 - Door - [Open, null, null, null, null] +2626 - Door - [Open, null, null, null, null] +2627 - Door - [Open, null, null, null, null] +2628 - Door - [Open, null, null, null, null] +2629 - Wall - [Push, null, null, null, null] +2630 - Fishing spot - [Bait, null, hidden, null, null] +2631 - Door - [Open, null, null, null, null] +2632 - Chest - [Open, null, null, null, null] +2633 - Chest - [Search, Close, null, null, null] +2634 - Rock slide - [Investigate, Mine, null, null, null] +2635 - Cupboard - [Open, null, null, null, null] +2636 - Cupboard - [Search, Shut, null, null, null] +2637 - null - [null, null, null, null, null] +2638 - Fountain of Heroes - [null, null, null, null, null] +2639 - null - [null, null, null, null, null] +2640 - Altar - [Pray-at, null, null, null, null] +2641 - Ladder - [Climb-up, null, null, null, null] +2642 - Potter's Wheel - [null, null, null, null, null] +2643 - Pottery Oven - [Fire, null, null, null, null] +2644 - Spinning wheel - [null, Spin, null, null, null] +2645 - Sand pit - [null, null, null, null, null] +2646 - Flax - [null, Pick, null, null, null] +2647 - Guild Door - [Open, null, null, null, null] +2648 - null - [null, null, null, null, null] +2649 - null - [null, null, null, null, null] +2650 - Table - [Search, null, null, null, null] +2651 - null - [null, null, null, null, null] +2652 - Sinclair mansion drain - [null, Investigate, null, null, null] +2653 - null - [null, null, null, null, null] +2654 - Sinclair family fountain - [null, Investigate, null, null, null] +2655 - Sinclair family crest - [null, Investigate, null, null, null] +2656 - Anna's barrel - [null, Search, null, null, null] +2657 - Bob's barrel - [null, Search, null, null, null] +2658 - Carol's barrel - [null, Search, null, null, null] +2659 - David's barrel - [null, Search, null, null, null] +2660 - Elizabeth's barrel - [null, Search, null, null, null] +2661 - Frank's barrel - [null, Search, null, null, null] +2662 - null - [null, null, null, null, null] +2663 - Sacks - [null, Investigate, null, null, null] +2664 - Sturdy wooden gate - [Investigate, null, null, null, null] +2665 - Sturdy wooden gate - [Investigate, null, null, null, null] +2666 - null - [null, null, null, null, null] +2667 - Winch - [Look at, Use, null, null, null] +2668 - Winch bucket - [Look at, Use, null, null, null] +2669 - null - [null, null, null, null, null] +2670 - Kharidian cactus (Healthy) - [Cut, null, null, null, null] +2671 - Kharidian cactus (Dry) - [null, null, null, null, null] +2672 - An experimental anvil - [Use, null, null, null, null] +2673 - Gate - [Open, Search, null, null, null] +2674 - Gate - [Open, Search, null, null, null] +2675 - Mine door entrance - [Open, Watch, null, null, null] +2676 - Mine door entrance - [Open, Watch, null, null, null] +2677 - Chest - [Open, null, null, null, null] +2678 - Bookcase - [null, Search, null, null, null] +2679 - null - [null, null, null, null, null] +2680 - Barrel - [Look-in, Search, null, null, null] +2681 - Barrel - [Look in, Search, null, null, null] +2682 - null - [null, null, null, null, null] +2683 - Window - [null, Search, null, null, null] +2684 - Mine Cart - [Look at, Search, null, null, null] +2685 - Gate - [Open, Search, null, null, null] +2686 - Gate - [Open, Search, null, null, null] +2687 - Gate - [Open, Search, null, null, null] +2688 - Gate - [Open, Search, null, null, null] +2689 - Prison door - [Open, null, null, null, null] +2690 - Mine door entrance - [Open, null, null, null, null] +2691 - Mine door entrance - [Open, null, null, null, null] +2692 - Prison door - [Open, null, null, null, null] +2693 - Shantay chest - [Open, null, null, null, null] +2694 - Rock - [null, Climb-to, null, null, null] +2695 - Rock - [null, Climb-to, null, null, null] +2696 - Rock - [null, Climb-to, null, null, null] +2697 - Rock - [null, Climb down, null, null, null] +2698 - Mine cave - [Walk through, null, null, null, null] +2699 - Mine cave - [Walk through, null, null, null, null] +2700 - Tent door - [Walk-through, null, null, null, null] +2701 - null - [null, null, null, null, null] +2702 - Tracks - [Look at, Search, null, null, null] +2703 - Tracks - [Look at, Search, null, null, null] +2704 - Rocks - [Mine, Prospect, hidden, null, null] +2705 - Door - [Open, null, null, null, null] +2706 - Door - [Open, null, null, null, null] +2707 - Crate - [null, Investigate, null, null, null] +2708 - Crate - [null, Investigate, null, null, null] +2709 - Chest - [Open, null, null, null, null] +2710 - Chest - [Search, Close, null, null, null] +2711 - Stairs - [Climb-up, Investigate, null, null, null] +2712 - Door - [Open, null, null, null, null] +2713 - Hopper - [null, null, null, null, null] +2714 - Hopper - [null, null, null, null, null] +2715 - Hellhound - [null, null, null, null, Remove] +2716 - Hopper - [null, null, null, null, null] +2717 - Hopper - [null, null, null, null, null] +2718 - Hopper controls - [Operate, null, null, null, null] +2719 - null - [null, null, null, null, null] +2720 - Hopper controls - [Operate, null, null, null, null] +2721 - Hopper controls - [Operate, null, null, null, null] +2722 - Hopper controls - [null, null, null, null, null] +2723 - Kebab - [null, null, null, null, null] +2724 - Fireplace - [null, null, null, null, null] +2725 - Fireplace - [null, null, null, null, null] +2726 - Fireplace - [null, null, null, null, null] +2727 - Cooking pot - [null, null, null, null, null] +2728 - Range - [null, null, null, null, null] +2729 - Range - [null, null, null, null, null] +2730 - Range - [null, null, null, null, null] +2731 - Range - [null, null, null, null, null] +2732 - Fire - [null, null, null, null, null] +2733 - null - [null, null, null, null, null] +2734 - null - [null, null, null, null, null] +2735 - null - [null, null, null, null, null] +2736 - null - [null, null, null, null, null] +2737 - null - [null, null, null, null, null] +2738 - null - [null, null, null, null, null] +2739 - null - [null, null, null, null, null] +2740 - null - [null, null, null, null, null] +2741 - null - [null, null, null, null, null] +2742 - null - [null, null, null, null, null] +2743 - null - [null, null, null, null, null] +2744 - null - [null, null, null, null, null] +2745 - null - [null, null, null, null, null] +2746 - null - [null, null, null, null, null] +2747 - null - [null, null, null, null, null] +2748 - null - [null, null, null, null, null] +2749 - null - [null, null, null, null, null] +2750 - null - [null, null, null, null, null] +2751 - null - [null, null, null, null, null] +2752 - null - [null, null, null, null, null] +2753 - null - [null, null, null, null, null] +2754 - null - [null, null, null, null, null] +2755 - null - [null, null, null, null, null] +2756 - null - [null, null, null, null, null] +2757 - null - [null, null, null, null, null] +2758 - null - [null, null, null, null, null] +2759 - null - [null, null, null, null, null] +2760 - null - [null, null, null, null, null] +2761 - null - [null, null, null, null, null] +2762 - null - [null, null, null, null, null] +2763 - null - [null, null, null, null, null] +2764 - null - [null, null, null, null, null] +2765 - null - [null, null, null, null, null] +2766 - null - [null, null, null, null, null] +2767 - null - [null, null, null, null, null] +2768 - null - [null, null, null, null, null] +2769 - null - [null, null, null, null, null] +2770 - null - [null, null, null, null, null] +2771 - null - [null, null, null, null, null] +2772 - null - [null, null, null, null, null] +2773 - null - [null, null, null, null, null] +2774 - null - [null, null, null, null, null] +2775 - null - [null, null, null, null, null] +2776 - null - [null, null, null, null, null] +2777 - null - [null, null, null, null, null] +2778 - null - [null, null, null, null, null] +2779 - null - [null, null, null, null, null] +2780 - null - [null, null, null, null, null] +2781 - Catapult - [null, null, null, null, null] +2782 - Anvil - [null, null, null, null, null] +2783 - Anvil - [null, null, null, null, null] +2784 - Blacksmith's tools - [null, null, null, null, null] +2785 - null - [null, null, null, null, null] +2786 - City gate - [Open, null, null, null, null] +2787 - City gate - [Open, null, null, null, null] +2788 - City gate - [Open, null, null, null, null] +2789 - City gate - [Open, null, null, null, null] +2790 - Chest - [Open, null, null, null, null] +2791 - Counter - [null, null, null, null, null] +2792 - Counter - [Steal-From, null, null, null, null] +2793 - Counter - [Steal-From, null, null, null, null] +2794 - Lever - [Pull, null, null, null, null] +2795 - Lever - [Pull, null, null, null, null] +2796 - Ladder - [Climb-up, null, null, null, null] +2797 - Ladder - [Climb-down, null, null, null, null] +2798 - Bush - [Search, null, null, null, null] +2799 - Bush - [Search, null, null, null, null] +2800 - Bush - [Search, null, null, null, null] +2801 - Bush - [Search, null, null, null, null] +2802 - Bush - [Search, null, null, null, null] +2803 - Bush - [Search, null, null, null, null] +2804 - Cave entrance - [Enter, null, null, null, null] +2805 - Cave entrance - [Enter, null, null, null, null] +2806 - Cave entrance - [Enter, null, null, null, null] +2807 - Cave entrance - [Enter, null, null, null, null] +2808 - Cave entrance - [Enter, null, null, null, null] +2809 - Cave entrance - [Enter, null, null, null, null] +2810 - Cave entrance - [Enter, null, null, null, null] +2811 - Cave entrance - [Enter, null, null, null, null] +2812 - Ladder - [Climb-down, null, null, null, null] +2813 - Cave entrance - [Enter, null, null, null, null] +2814 - Gate - [Open, null, null, null, null] +2815 - Gate - [Open, null, null, null, null] +2816 - Rock of Dalgroth - [Prospect, Mine, null, null, null] +2817 - Cave exit - [Leave, null, null, null, null] +2818 - Cave exit - [Leave, null, null, null, null] +2819 - Cave exit - [Leave, null, null, null, null] +2820 - Cave exit - [Leave, null, null, null, null] +2821 - Cave exit - [Leave, null, null, null, null] +2822 - Cave exit - [Leave, null, null, null, null] +2823 - Hole - [Climb-down, null, null, null, null] +2824 - Hole - [null, null, null, null, null] +2825 - Climbing rope - [Climb, null, null, null, null] +2826 - Chest - [Open, null, null, null, null] +2827 - Chest - [Open, null, null, null, null] +2828 - null - [Close, null, null, null, null] +2829 - null - [Close, null, null, null, null] +2830 - Gap - [Jump-Over, null, null, null, null] +2831 - Gap - [Jump-Over, null, null, null, null] +2832 - Battlement - [Climb-over, null, null, null, null] +2833 - Ladder - [Climb-up, null, null, null, null] +2834 - Broken Bridge - [Cross, null, null, null, null] +2835 - Rock - [Search, null, null, null, null] +2836 - Rock - [Search, null, null, null, null] +2837 - Rock - [Search, null, null, null, null] +2838 - null - [null, null, null, null, null] +2839 - null - [null, null, null, null, null] +2840 - null - [null, null, null, null, null] +2841 - Bed - [null, null, null, null, null] +2842 - Magical shield - [null, null, null, null, null] +2843 - null - [null, null, null, null, null] +2844 - Sewer valve - [Turn-left, Turn-right, null, null, null] +2845 - Sewer valve - [Turn-left, Turn-right, null, null, null] +2846 - Sewer valve - [Turn-left, Turn-right, null, null, null] +2847 - Sewer valve - [Turn-left, Turn-right, null, null, null] +2848 - Sewer valve - [Turn-left, Turn-right, null, null, null] +2849 - Raft - [Board, null, null, null, null] +2850 - Cupboard - [Open, null, null, null, null] +2851 - Cupboard - [Search, Shut, null, null, null] +2852 - Cave entrance - [Enter, null, null, null, null] +2853 - Stairs - [Climb-up, null, null, null, null] +2854 - Wall - [Knock-at, null, null, null, null] +2855 - null - [null, null, null, null, null] +2856 - Chest - [Open, null, null, null, null] +2857 - Chest - [Search, Close, null, null, null] +2858 - Crate - [Search, null, null, null, null] +2859 - Range - [null, null, null, null, null] +2860 - Hazeel's coffin - [null, null, null, null, null] +2861 - Door - [Open, null, null, null, null] +2862 - Door - [Open, null, null, null, null] +2863 - Door - [Open, null, null, null, null] +2864 - Fountain - [null, Check, null, null, null] +2865 - Gate - [Open, null, null, null, null] +2866 - Gate - [Open, null, null, null, null] +2867 - Potted plant - [Look-under, null, null, null, null] +2868 - Cupboard - [Open, null, null, null, null] +2869 - Cupboard - [Search, Shut, null, null, null] +2870 - null - [null, null, null, null, null] +2871 - Ladder - [Climb-down, null, null, null, null] +2872 - Ladder - [Climb-up, null, null, null, null] +2873 - Statue of Saradomin - [Pray at, null, null, null, null] +2874 - Statue of Zamorak - [Pray at, null, null, null, null] +2875 - Statue of Guthix - [Pray at, null, null, null, null] +2876 - Counter - [null, null, null, null, null] +2877 - Barrel - [null, null, null, null, null] +2878 - Sparkling pool - [Step-into, null, null, null, null] +2879 - Sparkling pool - [Step-into, null, null, null, null] +2880 - Mystic portal - [Walk-through, null, null, null, null] +2881 - Prison Door - [Open, null, null, null, null] +2882 - Gate - [Open, null, null, Pay-toll(10gp), null] +2883 - Gate - [Open, null, null, Pay-toll(10gp), null] +2884 - Ladder - [Climb, Climb-up, Climb-down, null, null] +2885 - Cupboard - [Open, null, null, null, null] +2886 - Open Cupboard - [null, Search, Shut, null, null] +2887 - Jungle Tree - [Chop-down, null, hidden, null, null] +2888 - Jungle Palm - [null, null, null, null, null] +2889 - Jungle Tree - [Chop-down, null, hidden, null, null] +2890 - Jungle Tree - [Chop-down, null, hidden, null, null] +2891 - Tree stump - [null, null, null, null, null] +2892 - Jungle Bush - [Chop-down, null, hidden, null, null] +2893 - Jungle Bush - [Chop-down, null, hidden, null, null] +2894 - Slashed bush - [null, null, null, null, null] +2895 - Slashed bush - [null, null, null, null, null] +2896 - Legends Guild door - [Open, null, null, null, null] +2897 - Legends Guild door - [Open, null, null, null, null] +2898 - null - [null, null, null, null, null] +2899 - null - [null, null, null, null, null] +2900 - Bed - [null, null, null, null, null] +2901 - Sir Palomedes - [Talk-to, null, null, null, null] +2902 - Rocks - [Search, null, null, null, null] +2903 - Cave entrance - [Walk through, null, null, null, null] +2904 - Cave entrance - [Walk through, null, null, null, null] +2905 - Crate - [Look, Search, null, null, null] +2906 - Table - [Look-at, Search, null, null, null] +2907 - Bed - [null, Search, null, null, null] +2908 - Fire Wall - [Touch, Investigate, null, null, null] +2909 - Fire Wall - [Touch, Investigate, null, null, null] +2910 - Desk - [Look, Search, null, null, null] +2911 - Bookcase - [Look, Search, null, null, null] +2912 - Ancient Gate - [Open, Search, null, null, null] +2913 - Ancient Gate - [Open, Search, null, null, null] +2914 - null - [null, null, null, null, null] +2915 - null - [null, null, null, null, null] +2916 - Rocks - [Mine, Prospect, hidden, null, null] +2917 - null - [null, null, null, null, null] +2918 - Crevice - [Look-at, Search, null, null, null] +2919 - Boulder - [Smash-to-bits, null, null, null, null] +2920 - Boulder - [Smash-to-bits, null, null, null, null] +2921 - Boulder - [Smash-to-bits, null, null, null, null] +2922 - Ancient Gate - [Open, null, null, null, null] +2923 - Ancient Gate - [Open, null, null, null, null] +2924 - Ancient Gate - [null, null, null, null, null] +2925 - Ancient Gate - [null, null, null, null, null] +2926 - Jagged wall - [Look, Jump-over, null, null, null] +2927 - Marked wall - [Use, Search, null, null, null] +2928 - Carved rock - [Look, Search, null, null, null] +2929 - Buried skeleton - [Search, null, null, null, null] +2930 - Ancient Gate - [Open, Search, null, null, null] +2931 - Ancient Gate - [null, null, null, null, null] +2932 - Barrel - [Smash, null, null, null, null] +2933 - null - [null, null, null, null, null] +2934 - Winch - [Search, null, null, null, null] +2935 - Winch - [Climb-down, null, null, null, null] +2936 - Totem Pole - [Look, null, null, null, null] +2937 - Totem Pole - [Look, null, null, null, null] +2938 - Totem Pole - [Look, null, null, null, null] +2939 - Totem Pole - [Look, null, null, null, null] +2940 - Table - [null, null, null, null, null] +2941 - Sacred water - [Look, null, null, null, null] +2942 - Water Pool - [Look, Investigate, null, null, null] +2943 - Polluted water - [Look, null, null, null, null] +2944 - Tall Reeds - [Look, Search, null, null, null] +2945 - Yommi tree baby - [null, null, null, null, null] +2946 - Yommi tree sapling - [null, null, null, null, null] +2947 - Dead Yommi sapling - [null, null, null, null, null] +2948 - Adult Yommi tree - [null, null, null, null, null] +2949 - Dead Yommi - [null, null, null, null, null] +2950 - Felled Yommi tree - [null, null, null, null, null] +2951 - Rotten Yommi - [null, null, null, null, null] +2952 - Trimmed Yommi - [null, null, null, null, null] +2953 - Rotten Yommi tree - [null, null, null, null, null] +2954 - Totem pole - [Lift, null, null, null, null] +2955 - Rotten Totem pole - [null, null, null, null, null] +2956 - Fertile Soil - [null, null, null, null, null] +2957 - Damaged Earth - [null, null, null, null, null] +2958 - Climbing rope - [Climb, null, null, null, null] +2959 - Rocky Ledge - [Climb-over, null, null, null, null] +2960 - Rocky Ledge - [Climb-over, null, null, null, null] +2961 - Rocky Ledge - [Climb-over, null, null, null, null] +2962 - Rocks - [Climb-over, null, null, null, null] +2963 - Rocks - [Climb-over, null, null, null, null] +2964 - Rocks - [Climb-over, null, null, null, null] +2965 - Mossy rock - [Search, null, null, null, null] +2966 - Furnace - [Look, Search, null, null, null] +2967 - null - [null, null, null, null, null] +2968 - null - [null, null, null, null, null] +2969 - Recess - [Search, null, null, null, null] +2970 - Filled Recess - [Search, null, null, null, null] +2971 - Shimmering field - [Walk-through, Look, null, null, null] +2972 - Boulder - [Smash-to-bits, null, null, null, null] +2973 - Boulder - [Smash-to-bits, null, null, null, null] +2974 - Boulder - [Smash-to-bits, null, null, null, null] +2975 - Leafy Palm Tree - [Shake, null, null, null, null] +2976 - Leafy Palm Tree - [null, null, null, null, null] +2977 - Sand - [Look, null, null, null, null] +2978 - Sand - [Look, null, null, null, null] +2979 - Sand - [Look, null, null, null, null] +2980 - Flowers - [null, null, null, null, null] +2981 - Flowers - [null, null, null, null, null] +2982 - Flowers - [null, null, null, null, null] +2983 - Flowers - [null, null, null, null, null] +2984 - Flowers - [null, null, null, null, null] +2985 - Flowers - [null, null, null, null, null] +2986 - Flowers - [null, null, null, null, null] +2987 - Flowers - [null, null, null, null, null] +2988 - Flowers - [null, null, null, null, null] +2989 - Vine - [Check, null, null, null, null] +2990 - Vine - [Check, null, null, null, null] +2991 - Vine - [Check, null, null, null, null] +2992 - Vine - [Check, null, null, null, null] +2993 - Vine - [Check, null, null, null, null] +2994 - Vine - [Check, null, null, null, null] +2995 - Closed chest - [Open, null, null, null, null] +2996 - Closed chest - [Open, null, null, null, null] +2997 - Door - [Open, null, null, null, null] +2998 - Door - [Close, null, null, null, null] +2999 - null - [null, null, null, null, null] +3000 - Timber defence - [null, null, null, null, null] +3001 - null - [null, null, null, null, null] +3002 - null - [null, null, null, null, null] +3003 - null - [null, null, null, null, null] +3004 - null - [null, null, null, null, null] +3005 - null - [null, null, null, null, null] +3006 - null - [null, null, null, null, null] +3007 - null - [null, null, null, null, null] +3008 - null - [null, null, null, null, null] +3009 - null - [null, null, null, null, null] +3010 - null - [null, null, null, null, null] +3011 - null - [null, null, null, null, null] +3012 - null - [null, null, null, null, null] +3013 - null - [null, null, null, null, null] +3014 - Door - [Open, null, null, null, null] +3015 - Gate - [Open, null, null, null, null] +3016 - Gate - [Open, null, null, null, null] +3017 - Door - [Open, null, null, null, null] +3018 - Door - [Open, null, null, null, null] +3019 - Door - [Open, null, null, null, null] +3020 - Gate - [Open, null, null, null, null] +3021 - Gate - [Open, null, null, null, null] +3022 - Gate - [Open, null, null, null, null] +3023 - Gate - [Open, null, null, null, null] +3024 - Door - [Open, null, null, null, null] +3025 - Door - [Open, null, null, null, null] +3026 - Door - [Open, null, null, null, null] +3027 - Door - [Open, null, null, null, null] +3028 - Ladder - [Climb-up, null, null, null, null] +3029 - Ladder - [Climb-down, null, null, null, null] +3030 - Ladder - [Climb-up, null, null, null, null] +3031 - Ladder - [Climb-down, null, null, null, null] +3032 - Fishing spot - [Net, null, hidden, null, null] +3033 - Tree - [Chop down, null, hidden, null, null] +3034 - Tree - [Chop down, null, hidden, null, null] +3035 - Tree - [Chop down, null, hidden, null, null] +3036 - Tree - [Chop down, null, hidden, null, null] +3037 - Oak - [Chop down, null, hidden, null, null] +3038 - Fire - [null, null, null, null, null] +3039 - Range - [Use, null, null, null, null] +3040 - Cupboard - [Open, null, null, null, null] +3041 - Cupboard - [Search, Shut, null, null, null] +3042 - Rocks - [Mine, Prospect, null, null, null] +3043 - Rocks - [Mine, Prospect, null, null, null] +3044 - Furnace - [Use, null, null, null, null] +3045 - Bank booth - [Use, null, null, null, null] +3046 - Timber defence - [null, null, null, null, null] +3047 - null - [null, null, null, null, null] +3048 - null - [null, null, null, null, null] +3049 - null - [null, null, null, null, null] +3050 - null - [null, null, null, null, null] +3051 - null - [null, null, null, null, null] +3052 - null - [null, null, null, null, null] +3053 - null - [null, null, null, null, null] +3054 - null - [null, null, null, null, null] +3055 - null - [null, null, null, null, null] +3056 - null - [null, null, null, null, null] +3057 - null - [null, null, null, null, null] +3058 - null - [null, null, null, null, null] +3059 - null - [null, null, null, null, null] +3060 - null - [null, null, null, null, null] +3061 - null - [null, null, null, null, null] +3062 - null - [null, null, null, null, null] +3063 - null - [null, null, null, null, null] +3064 - null - [null, null, null, null, null] +3065 - null - [null, null, null, null, null] +3066 - null - [null, null, null, null, null] +3067 - null - [null, null, null, null, null] +3068 - null - [null, null, null, null, null] +3069 - null - [null, null, null, null, null] +3070 - null - [null, null, null, null, null] +3071 - null - [null, null, null, null, null] +3072 - null - [null, null, null, null, null] +3073 - null - [null, null, null, null, null] +3074 - null - [null, null, null, null, null] +3075 - null - [null, null, null, null, null] +3076 - null - [null, null, null, null, null] +3077 - Wall - [null, null, null, null, Lean against] +3078 - Wall - [null, null, null, null, Lean against] +3079 - Wall - [null, null, null, null, Lean against] +3080 - null - [null, null, null, null, null] +3081 - null - [null, null, null, null, null] +3082 - Wall - [null, null, null, null, Lean against] +3083 - Wall - [null, null, null, null, Lean against] +3084 - null - [null, null, null, null, null] +3085 - null - [null, null, null, null, null] +3086 - null - [null, null, null, null, null] +3087 - null - [null, null, null, null, null] +3088 - null - [null, null, null, null, null] +3089 - null - [null, null, null, null, null] +3090 - null - [null, null, null, null, null] +3091 - null - [null, null, null, null, null] +3092 - null - [null, null, null, null, null] +3093 - null - [null, null, null, null, null] +3094 - null - [null, null, null, null, null] +3095 - null - [null, null, null, null, null] +3096 - null - [null, null, null, null, null] +3097 - null - [null, null, null, null, null] +3098 - null - [null, null, null, null, null] +3099 - null - [null, null, null, null, null] +3100 - null - [null, null, null, null, null] +3101 - null - [null, null, null, null, null] +3102 - null - [null, null, null, null, null] +3103 - null - [null, null, null, null, null] +3104 - null - [null, null, null, null, null] +3105 - null - [null, null, null, null, null] +3106 - null - [null, null, null, null, null] +3107 - null - [null, null, null, null, null] +3108 - Entrance - [Forfeit, null, null, null, null] +3109 - Entrance - [Forfeit, null, null, null, null] +3110 - null - [null, null, null, null, null] +3111 - Entrance - [Forfeit, null, null, null, null] +3112 - Entrance - [Forfeit, null, null, null, null] +3113 - Entrance - [Forfeit, null, null, null, null] +3114 - Entrance - [Forfeit, null, null, null, null] +3115 - null - [null, null, null, null, null] +3116 - null - [null, null, null, null, null] +3117 - null - [null, null, null, null, null] +3118 - null - [null, null, null, null, null] +3119 - null - [null, null, null, null, null] +3120 - null - [null, null, null, null, null] +3121 - null - [null, null, null, null, null] +3122 - null - [null, null, null, null, null] +3123 - null - [null, null, null, null, null] +3124 - null - [null, null, null, null, null] +3125 - null - [null, null, null, null, null] +3126 - null - [null, null, null, null, null] +3127 - null - [null, null, null, null, null] +3128 - null - [null, null, null, null, null] +3129 - null - [null, null, null, null, null] +3130 - null - [null, null, null, null, null] +3131 - null - [null, null, null, null, null] +3132 - null - [null, null, null, null, null] +3133 - null - [null, null, null, null, null] +3134 - null - [null, null, null, null, null] +3135 - null - [null, null, null, null, null] +3136 - null - [null, null, null, null, null] +3137 - null - [null, null, null, null, null] +3138 - null - [null, null, null, null, null] +3139 - null - [null, null, null, null, null] +3140 - null - [null, null, null, null, null] +3141 - null - [null, null, null, null, null] +3142 - null - [null, null, null, null, null] +3143 - null - [null, null, null, null, null] +3144 - null - [null, null, null, null, null] +3145 - null - [null, null, null, null, null] +3146 - null - [null, null, null, null, null] +3147 - null - [null, null, null, null, null] +3148 - null - [null, null, null, null, null] +3149 - null - [null, null, null, null, null] +3150 - null - [null, null, null, null, null] +3151 - null - [null, null, null, null, null] +3152 - null - [null, null, null, null, null] +3153 - null - [null, null, null, null, null] +3154 - null - [null, null, null, null, null] +3155 - null - [null, null, null, null, null] +3156 - null - [null, null, null, null, null] +3157 - null - [null, null, null, null, null] +3158 - null - [null, null, null, null, null] +3159 - Bed - [null, null, null, null, null] +3160 - null - [null, null, null, null, null] +3161 - null - [null, null, null, null, null] +3162 - null - [null, null, null, null, null] +3163 - null - [null, null, null, null, null] +3164 - null - [null, null, null, null, null] +3165 - null - [null, null, null, null, null] +3166 - null - [null, null, null, null, null] +3167 - null - [null, null, null, null, null] +3168 - null - [null, null, null, null, null] +3169 - null - [null, null, null, null, null] +3170 - null - [null, null, null, null, null] +3171 - null - [null, null, null, null, null] +3172 - null - [null, null, null, null, null] +3173 - null - [null, null, null, null, null] +3174 - null - [null, null, null, null, null] +3175 - null - [null, null, null, null, null] +3176 - null - [null, null, null, null, null] +3177 - null - [null, null, null, null, null] +3178 - null - [null, null, null, null, null] +3179 - null - [null, null, null, null, null] +3180 - null - [null, null, null, null, null] +3181 - null - [null, null, null, null, null] +3182 - Chair - [null, null, null, null, null] +3183 - Hospital shelves - [null, null, null, null, null] +3184 - Hospital shelves - [null, null, null, null, null] +3185 - Hospital shelves - [null, null, null, null, null] +3186 - Operating Table - [null, null, null, null, null] +3187 - Operating Table - [null, null, null, null, null] +3188 - null - [null, null, null, null, null] +3189 - null - [null, null, null, null, null] +3190 - Drawers - [Open, null, null, null, null] +3191 - Drawers - [null, null, Shut, null, null] +3192 - Scoreboard - [View, null, null, null, null] +3193 - Closed bank chest - [Open, null, null, null, null] +3194 - Bank chest - [null, Bank, Shut, null, null] +3195 - Crate - [Buy, null, null, null, null] +3196 - Damaged armour - [null, null, null, null, null] +3197 - Gate - [Open, null, null, null, null] +3198 - Gate - [Open, null, null, null, null] +3199 - Bed - [null, null, null, null, null] +3200 - null - [null, null, null, null, null] +3201 - null - [null, null, null, null, null] +3202 - null - [null, null, null, null, null] +3203 - Trapdoor - [Forfeit, null, null, null, null] +3204 - null - [null, null, null, null, null] +3205 - Ladder - [Climb-down, null, null, null, null] +3206 - Barrel - [null, null, null, null, null] +3207 - null - [null, null, null, null, null] +3208 - null - [null, null, null, null, null] +3209 - Odd looking wall - [Push, null, null, null, null] +3210 - Odd looking wall - [null, null, null, null, null] +3211 - Odd looking wall - [Push, null, null, null, null] +3212 - Odd looking wall - [null, null, null, null, null] +3213 - Cave entrance - [Enter, null, null, null, null] +3214 - Underground Pass Exit - [Leave, null, null, null, null] +3215 - null - [null, null, null, null, null] +3216 - Mud - [null, null, null, null, null] +3217 - Cave - [Enter, null, null, null, null] +3218 - Tunnel - [Pass-through, null, null, null, null] +3219 - Tunnel - [Pass-through, null, null, null, null] +3220 - Door - [Open, null, null, null, null] +3221 - Door - [Open, null, null, null, null] +3222 - Cave Stairs - [Descend, null, null, null, null] +3223 - Cave Stairs - [Ascend, null, null, null, null] +3224 - Cave - [Enter, null, null, null, null] +3225 - null - [null, null, null, null, null] +3226 - null - [null, null, null, null, null] +3227 - Trap - [null, null, null, null, null] +3228 - Trap - [null, null, null, null, null] +3229 - Trap - [null, null, null, null, null] +3230 - Flat rock - [Search, null, null, null, null] +3231 - Plank - [null, null, null, null, null] +3232 - Stalagmites - [null, null, null, null, null] +3233 - Trap - [null, null, null, null, null] +3234 - Odd markings - [Search, null, null, null, null] +3235 - Obstacle pipe - [Squeeze-through, null, null, null, null] +3236 - Obstacle pipe - [Squeeze-through, null, null, null, null] +3237 - Obstacle pipe - [Squeeze-through, null, null, null, null] +3238 - Ledge - [Cross, null, null, null, null] +3239 - Bridge - [null, null, null, null, null] +3240 - Bridge - [null, null, null, null, null] +3241 - Lever - [Pull, null, null, null, null] +3242 - Lever - [null, null, null, null, null] +3243 - Platform - [null, null, null, null, null] +3244 - Platform - [null, null, null, null, null] +3245 - Platform - [null, null, null, null, null] +3246 - Platform - [null, null, null, null, null] +3247 - Bridge - [null, null, null, null, null] +3248 - Bridge - [null, null, null, null, null] +3249 - Bridge - [null, null, null, null, null] +3250 - Bridge - [null, null, null, null, null] +3251 - null - [null, null, null, null, null] +3252 - null - [null, null, null, null, null] +3253 - null - [null, null, null, null, null] +3254 - Bridge - [Cross, null, null, null, null] +3255 - Bridge - [Cross, null, null, null, null] +3256 - null - [null, null, null, null, null] +3257 - Platform - [null, null, null, null, null] +3258 - Bridge - [null, null, null, null, null] +3259 - Bridge - [null, null, null, null, null] +3260 - Bridge - [null, null, null, null, null] +3261 - null - [null, null, null, null, null] +3262 - null - [null, null, null, null, null] +3263 - Swamp - [Cross, null, null, null, null] +3264 - Well - [Climb-down, null, null, null, null] +3265 - Pile of rocks - [Climb, null, null, null, null] +3266 - Cage - [Pick-lock, Search, null, null, null] +3267 - Cage - [null, Search, null, null, null] +3268 - Cage - [Pick-lock, Search, null, null, null] +3269 - null - [null, null, null, null, null] +3270 - Door - [Open, Knock, null, null, null] +3271 - Door - [Close, null, null, null, null] +3272 - Chest - [Open, null, null, null, null] +3273 - Chest - [Search, null, null, null, null] +3274 - Chest - [Open, null, null, null, null] +3275 - null - [null, null, null, null, null] +3276 - Stone bridge - [Cross, null, null, null, null] +3277 - null - [null, null, null, null, null] +3278 - null - [null, null, null, null, null] +3279 - null - [null, null, null, null, null] +3280 - null - [null, null, null, null, null] +3281 - null - [null, null, null, null, null] +3282 - null - [null, null, null, null, null] +3283 - null - [null, null, null, null, null] +3284 - null - [null, null, null, null, null] +3285 - null - [null, null, null, null, null] +3286 - null - [null, null, null, null, null] +3287 - null - [null, null, null, null, null] +3288 - null - [null, null, null, null, null] +3289 - null - [null, null, null, null, null] +3290 - null - [null, null, null, null, null] +3291 - null - [null, null, null, null, null] +3292 - null - [null, null, null, null, null] +3293 - null - [null, null, null, null, null] +3294 - Furnace - [null, null, null, null, null] +3295 - Stone tablet - [Read, null, null, null, null] +3296 - Stone tablet - [Read, null, null, null, null] +3297 - Stone tablet - [Read, null, null, null, null] +3298 - Stone tablet - [Read, null, null, null, null] +3299 - Stone tablet - [Read, null, null, null, null] +3300 - Stone tablet - [null, null, null, null, null] +3301 - Stone tablet - [Read, null, null, null, null] +3302 - Stone tablet - [Read, null, null, null, null] +3303 - Portcullis - [null, null, null, null, null] +3304 - Portcullis - [null, null, null, null, null] +3305 - Well - [Search, null, null, null, null] +3306 - null - [null, null, null, null, null] +3307 - Rockpile - [Climb, null, null, null, null] +3308 - Smashed cage - [Search, null, null, null, null] +3309 - Rockslide - [Climb-over, null, null, null, null] +3310 - null - [null, null, null, null, null] +3311 - null - [null, null, null, null, null] +3312 - null - [null, null, null, null, null] +3313 - null - [null, null, null, null, null] +3314 - null - [null, null, null, null, null] +3315 - null - [null, null, null, null, null] +3316 - null - [null, null, null, null, null] +3317 - null - [null, null, null, null, null] +3318 - null - [null, null, null, null, null] +3319 - null - [null, null, null, null, null] +3320 - null - [null, null, null, null, null] +3321 - null - [null, null, null, null, null] +3322 - null - [null, null, null, null, null] +3323 - null - [null, null, null, null, null] +3324 - null - [null, null, null, null, null] +3325 - null - [null, null, null, null, null] +3326 - null - [null, null, null, null, null] +3327 - Eerie statue - [null, null, null, null, null] +3328 - Dwarf statue - [null, null, null, null, null] +3329 - null - [null, null, null, null, null] +3330 - null - [null, null, null, null, null] +3331 - null - [null, null, null, null, null] +3332 - Temple door - [null, null, null, null, null] +3333 - Door - [Open, null, null, null, null] +3334 - Door - [Open, null, null, null, null] +3335 - Door - [null, null, null, null, null] +3336 - Door - [null, null, null, null, null] +3337 - Lever - [Pull, null, null, null, null] +3338 - Hanging log - [null, null, null, null, null] +3339 - Flat rock - [Search, null, null, null, null] +3340 - Guide rope - [Fire-at, null, null, null, null] +3341 - Guide rope - [null, null, null, null, null] +3342 - null - [null, null, null, null, null] +3343 - Rock pile - [Climb-over, null, null, null, null] +3344 - Barrel - [null, null, null, null, null] +3345 - null - [null, null, null, null, null] +3346 - null - [null, null, null, null, null] +3347 - null - [null, null, null, null, null] +3348 - Iban's Throne - [null, null, null, null, null] +3349 - null - [null, null, null, null, null] +3350 - null - [null, null, null, null, null] +3351 - Cage - [Search, null, null, null, null] +3352 - Cage - [Search, null, null, null, null] +3353 - Tomb - [Search, null, null, null, null] +3354 - Tomb - [Search, null, null, null, null] +3355 - null - [null, null, null, null, null] +3356 - null - [null, null, null, null, null] +3357 - null - [null, null, null, null, null] +3358 - null - [null, null, null, null, null] +3359 - Well - [null, null, null, null, null] +3360 - Crate - [Search, null, null, null, null] +3361 - null - [null, null, null, null, null] +3362 - Window - [Search, null, null, null, null] +3363 - null - [null, null, null, null, null] +3364 - Rock - [null, null, null, null, null] +3365 - Protruding rocks - [Climb, null, null, null, null] +3366 - Onion - [null, Pick, null, null, null] +3367 - Prison Door - [Open, null, null, null, null] +3368 - null - [null, null, null, null, null] +3369 - null - [null, null, null, null, null] +3370 - null - [null, null, null, null, null] +3371 - Achey Tree stump - [null, null, null, null, null] +3372 - Ogre spit-roast - [null, null, null, null, null] +3373 - Ogre spit-roast - [null, null, null, null, null] +3374 - Ogre spit-roast - [null, null, null, null, null] +3375 - Ogre spit-roast - [null, null, null, null, null] +3376 - Ogre bench - [null, null, null, null, null] +3377 - Locked Ogre chest - [Unlock, null, null, null, null] +3378 - Unlocked Ogre chest - [Search, null, null, null, null] +3379 - Cave entrance - [Enter, null, null, null, null] +3380 - Cave exit - [Walk through, null, null, null, null] +3381 - Cave exit - [Walk through, null, null, null, null] +3382 - Ogre spit-roast - [null, null, null, null, null] +3383 - Ogre spit-roast - [null, null, null, null, null] +3384 - null - [null, null, null, null, null] +3385 - null - [null, null, null, null, null] +3386 - null - [null, null, null, null, null] +3387 - null - [null, null, null, null, null] +3388 - null - [null, null, null, null, null] +3389 - null - [null, null, null, null, null] +3390 - null - [null, null, null, null, null] +3391 - null - [null, null, null, null, null] +3392 - null - [null, null, null, null, null] +3393 - null - [null, null, null, null, null] +3394 - Crate - [Search, null, null, null, null] +3395 - Crate - [Search, null, null, null, null] +3396 - Boxes - [Search, null, null, null, null] +3397 - Boxes - [Search, null, null, null, null] +3398 - Crate - [Search, null, null, null, null] +3399 - Crate - [Search, null, null, null, null] +3400 - Crate - [Search, null, null, null, null] +3401 - Crate - [Search, null, null, null, null] +3402 - Workbench - [null, null, null, null, null] +3403 - null - [null, null, null, null, null] +3404 - null - [null, null, null, null, null] +3405 - null - [null, null, null, null, null] +3406 - Lever - [Pull, null, null, null, null] +3407 - null - [null, null, null, null, null] +3408 - Water wheel - [null, null, null, null, null] +3409 - Lever - [Pull, null, null, null, null] +3410 - null - [null, null, null, null, null] +3411 - null - [null, null, null, null, null] +3412 - null - [null, null, null, null, null] +3413 - null - [null, null, null, null, null] +3414 - null - [null, null, null, null, null] +3415 - Staircase - [Climb-down, null, null, null, null] +3416 - Staircase - [Climb-up, null, null, null, null] +3417 - Lever - [null, null, null, null, null] +3418 - null - [null, null, null, null, null] +3419 - null - [null, null, null, null, null] +3420 - null - [null, null, null, null, null] +3421 - null - [null, null, null, null, null] +3422 - Machinery - [null, null, null, null, null] +3423 - null - [null, null, null, null, null] +3424 - null - [null, null, null, null, null] +3425 - null - [null, null, null, null, null] +3426 - null - [null, null, null, null, null] +3427 - null - [null, null, null, null, null] +3428 - null - [null, null, null, null, null] +3429 - null - [null, null, null, null, null] +3430 - null - [null, null, null, null, null] +3431 - Rocks - [Mine, Prospect, hidden, null, null] +3432 - Trapdoor - [Open, null, null, null, null] +3433 - Trapdoor - [Climb-down, Close, null, null, null] +3434 - null - [null, null, null, null, null] +3435 - null - [null, null, null, null, null] +3436 - null - [null, null, null, null, null] +3437 - null - [null, null, null, null, null] +3438 - null - [null, null, null, null, null] +3439 - null - [null, null, null, null, null] +3440 - Stairs - [Use, null, null, null, null] +3441 - Stairs - [Use, null, null, null, null] +3442 - null - [null, null, null, null, null] +3443 - Holy barrier - [Pass-through, null, null, null, null] +3444 - Gate - [Open, null, null, null, null] +3445 - Gate - [Open, null, null, null, null] +3446 - null - [null, null, null, null, null] +3447 - null - [null, null, null, null, null] +3448 - null - [null, null, null, null, null] +3449 - null - [null, null, null, null, null] +3450 - null - [null, null, null, null, null] +3451 - null - [null, null, null, null, null] +3452 - null - [null, null, null, null, null] +3453 - null - [null, null, null, null, null] +3454 - null - [null, null, null, null, null] +3455 - null - [null, null, null, null, null] +3456 - null - [null, null, null, null, null] +3457 - null - [null, null, null, null, null] +3458 - null - [null, null, null, null, null] +3459 - null - [null, null, null, null, null] +3460 - null - [null, null, null, null, null] +3461 - null - [null, null, null, null, null] +3462 - null - [null, null, null, null, null] +3463 - Cell door - [Open, Talk-through, null, null, null] +3464 - null - [null, null, null, null, null] +3465 - null - [null, null, null, null, null] +3466 - Hanging meat - [null, null, null, null, null] +3467 - Hanging meat - [null, null, null, null, null] +3468 - null - [null, null, null, null, null] +3469 - null - [null, null, null, null, null] +3470 - null - [null, null, null, null, null] +3471 - null - [null, null, null, null, null] +3472 - null - [null, null, null, null, null] +3473 - null - [null, null, null, null, null] +3474 - null - [null, null, null, null, null] +3475 - null - [null, null, null, null, null] +3476 - null - [null, null, null, null, null] +3477 - null - [null, null, null, null, null] +3478 - null - [null, null, null, null, null] +3479 - Statue - [null, null, null, null, null] +3480 - null - [null, null, null, null, null] +3481 - null - [null, null, null, null, null] +3482 - null - [null, null, null, null, null] +3483 - null - [null, null, null, null, null] +3484 - null - [null, null, null, null, null] +3485 - Well - [Search, null, null, null, null] +3486 - null - [null, null, null, null, null] +3487 - null - [null, null, null, null, null] +3488 - null - [null, null, null, null, null] +3489 - null - [null, null, null, null, null] +3490 - null - [null, null, null, null, null] +3491 - null - [null, null, null, null, null] +3492 - null - [null, null, null, null, null] +3493 - Monument - [Study, Take-from, null, null, null] +3494 - Monument - [Study, Take-from, null, null, null] +3495 - Monument - [Study, Take-from, null, null, null] +3496 - Monument - [Study, Take-from, null, null, null] +3497 - Monument - [Study, Take-from, null, null, null] +3498 - Monument - [Study, Take-from, null, null, null] +3499 - Monument - [Study, Take-from, null, null, null] +3500 - Church organ - [Play, null, null, null, null] +3501 - null - [null, null, null, null, null] +3502 - null - [null, null, null, null, null] +3503 - null - [null, null, null, null, null] +3504 - null - [null, null, null, null, null] +3505 - null - [null, null, null, null, null] +3506 - Gate - [Open, null, null, null, null] +3507 - Gate - [Open, null, null, null, null] +3508 - Rotting log - [null, null, null, null, null] +3509 - Fungi on log - [null, Pick, null, null, null] +3510 - Rotting branch - [null, null, null, null, null] +3511 - Budding branch - [null, Take-cutting, null, null, null] +3512 - A small bush - [null, null, null, null, null] +3513 - A golden pear bush - [null, Pick, null, null, null] +3514 - Rotting tree - [null, null, null, null, null] +3515 - null - [null, null, null, null, null] +3516 - Grotto - [Enter, null, null, null, null] +3517 - Grotto tree - [Look-at, Search, null, null, null] +3518 - null - [null, null, null, null, null] +3519 - null - [null, null, null, null, null] +3520 - Grotto - [Search, null, null, null, null] +3521 - Altar of nature - [Pray-at, null, null, null, null] +3522 - Bridge - [Jump, null, null, null, null] +3523 - Bench - [null, null, null, null, null] +3524 - null - [null, null, null, null, null] +3525 - Grotto - [Exit, null, null, null, null] +3526 - Grotto - [Exit, null, null, null, null] +3527 - Stone - [null, null, null, null, Search] +3528 - Stone - [null, null, null, null, Search] +3529 - Stone - [null, null, null, null, Search] +3530 - null - [null, null, null, null, null] +3531 - null - [null, null, null, null, null] +3532 - null - [null, null, null, null, null] +3533 - null - [null, null, null, null, null] +3534 - null - [null, null, null, null, null] +3535 - null - [null, null, null, null, null] +3536 - null - [null, null, null, null, null] +3537 - null - [null, null, null, null, null] +3538 - null - [null, null, null, null, null] +3539 - null - [null, null, null, null, null] +3540 - null - [null, null, null, null, null] +3541 - null - [null, null, null, null, null] +3542 - null - [null, null, null, null, null] +3543 - null - [null, null, null, null, null] +3544 - null - [null, null, null, null, null] +3545 - null - [null, null, null, null, null] +3546 - Old well - [Climb-down, null, null, null, null] +3547 - null - [null, null, null, null, null] +3548 - null - [null, null, null, null, null] +3549 - null - [null, null, null, null, null] +3550 - null - [null, null, null, null, null] +3551 - Balancing rope - [Walk-on, null, null, null, null] +3552 - Balancing rope - [null, null, null, null, null] +3553 - Log balance - [Walk-on, null, null, null, null] +3554 - Log balance - [null, null, null, null, null] +3555 - Log balance - [Walk-on, null, null, null, null] +3556 - Log balance - [null, null, null, null, null] +3557 - Log balance - [Walk-on, null, null, null, null] +3558 - Log balance - [null, null, null, null, null] +3559 - Balancing ledge - [Walk-across, null, null, null, null] +3560 - Balancing ledge - [null, null, null, null, null] +3561 - Balancing ledge - [Walk-across, null, null, null, null] +3562 - Balancing ledge - [null, null, null, null, null] +3563 - Monkey bars - [null, null, null, null, null] +3564 - Monkey bars - [Swing-across, null, null, null, null] +3565 - Low wall - [Climb-over, null, null, null, null] +3566 - Rope swing - [Swing-on, null, null, null, null] +3567 - Blade - [null, null, null, null, null] +3568 - Blade - [null, null, null, null, null] +3569 - Blade - [null, null, null, null, null] +3570 - Plank - [Walk-on, null, null, null, null] +3571 - Plank - [Walk-on, null, null, null, null] +3572 - Plank - [Walk-on, null, null, null, null] +3573 - Plank - [null, null, null, null, null] +3574 - Plank - [null, null, null, null, null] +3575 - Plank - [null, null, null, null, null] +3576 - Plank - [null, null, null, null, null] +3577 - Plank - [null, null, null, null, null] +3578 - Pillar - [Jump-on, null, null, null, null] +3579 - Pillar - [null, null, null, null, null] +3580 - Spinning blades - [null, null, null, null, null] +3581 - Ticket Dispenser - [Tag, null, null, null, null] +3582 - Floor spikes - [null, null, null, null, null] +3583 - Hand holds - [Climb-across, null, null, null, null] +3584 - Hand holds - [null, null, null, null, null] +3585 - Pressure pad - [null, null, null, null, null] +3586 - null - [null, null, null, null, null] +3587 - null - [null, null, null, null, null] +3588 - null - [null, null, null, null, null] +3589 - null - [null, null, null, null, null] +3590 - null - [null, null, null, null, null] +3591 - null - [null, null, null, null, null] +3592 - null - [null, null, null, null, null] +3593 - null - [null, null, null, null, null] +3594 - null - [null, null, null, null, null] +3595 - null - [null, null, null, null, null] +3596 - null - [null, null, null, null, null] +3597 - null - [null, null, null, null, null] +3598 - null - [null, null, null, null, null] +3599 - null - [null, null, null, null, null] +3600 - null - [null, null, null, null, null] +3601 - null - [null, null, null, null, null] +3602 - null - [null, null, null, null, null] +3603 - null - [null, null, null, null, null] +3604 - null - [null, null, null, null, null] +3605 - null - [null, null, null, null, null] +3606 - null - [null, null, null, null, null] +3607 - null - [null, null, null, null, null] +3608 - Ticket Dispenser - [Tag, null, null, null, null] +3609 - null - [null, null, null, null, null] +3610 - Climbing rope - [Climb, null, null, null, null] +3611 - null - [null, null, null, null, null] +3612 - null - [null, null, null, null, null] +3613 - null - [null, null, null, null, null] +3614 - null - [null, null, null, null, null] +3615 - null - [null, null, null, null, null] +3616 - null - [null, null, null, null, null] +3617 - Ladder - [Climb-Down, null, null, null, null] +3618 - Ladder - [Climb-up, null, null, null, null] +3619 - null - [null, null, null, null, null] +3620 - null - [null, null, null, null, null] +3621 - null - [null, null, null, null, null] +3622 - null - [null, null, null, null, null] +3623 - null - [null, null, null, null, null] +3624 - null - [null, null, null, null, null] +3625 - null - [null, null, null, null, null] +3626 - Wall - [Open, null, null, null, null] +3627 - null - [null, null, null, null, null] +3628 - Wall - [Open, null, null, null, null] +3629 - Wall - [Open, null, null, null, null] +3630 - Wall - [Open, null, null, null, null] +3631 - Wall - [Open, null, null, null, null] +3632 - Wall - [Open, null, null, null, null] +3633 - null - [null, null, null, null, null] +3634 - Strange shrine - [Touch, null, null, null, null] +3635 - Chest - [Open, null, null, null, null] +3636 - Chest - [Search, null, null, null, null] +3637 - null - [null, null, null, null, null] +3638 - null - [null, null, null, null, null] +3639 - null - [null, null, null, null, null] +3640 - null - [null, null, null, null, null] +3641 - null - [null, null, null, null, null] +3642 - null - [null, null, null, null, null] +3643 - null - [null, null, null, null, null] +3644 - Spotlight - [null, null, null, null, null] +3645 - null - [null, null, null, null, null] +3646 - null - [null, null, null, null, null] +3647 - null - [null, null, null, null, null] +3648 - null - [null, null, null, null, null] +3649 - null - [null, null, null, null, null] +3650 - null - [null, null, null, null, null] +3651 - null - [null, null, null, null, null] +3652 - null - [null, null, null, null, null] +3653 - null - [null, null, null, null, null] +3654 - null - [null, null, null, null, null] +3655 - null - [null, null, null, null, null] +3656 - null - [null, null, null, null, null] +3657 - null - [null, null, null, null, null] +3658 - null - [null, null, null, null, null] +3659 - null - [null, null, null, null, null] +3660 - null - [null, null, null, null, null] +3661 - null - [null, null, null, null, null] +3662 - Cooking pot - [Search, null, null, null, null] +3663 - null - [null, null, null, null, null] +3664 - null - [null, null, null, null, null] +3665 - Bones - [null, null, null, null, null] +3666 - null - [null, null, null, null, null] +3667 - null - [null, null, null, null, null] +3668 - null - [null, null, null, null, null] +3669 - null - [null, null, null, null, null] +3670 - null - [null, null, null, null, null] +3671 - null - [null, null, null, null, null] +3672 - null - [null, null, null, null, null] +3673 - null - [null, null, null, null, null] +3674 - null - [null, null, null, null, null] +3675 - null - [null, null, null, null, null] +3676 - Stone Mechanism - [null, null, null, null, null] +3677 - Stone Mechanism - [null, null, null, null, null] +3678 - null - [null, null, null, null, null] +3679 - Standard - [null, null, null, null, null] +3680 - Flagpole - [null, null, null, null, null] +3681 - Signpost - [null, null, null, null, null] +3682 - null - [null, null, null, null, null] +3683 - null - [null, null, null, null, null] +3684 - null - [null, null, null, null, null] +3685 - Boxes - [Search, null, null, null, null] +3686 - Boxes - [Search, null, null, null, null] +3687 - Boxes - [Search, null, null, null, null] +3688 - null - [null, null, null, null, null] +3689 - null - [null, null, null, null, null] +3690 - null - [null, null, null, null, null] +3691 - null - [null, null, null, null, null] +3692 - Climbing Rope - [null, null, null, null, null] +3693 - null - [null, null, null, null, null] +3694 - Crate - [null, null, null, null, null] +3695 - null - [null, null, null, null, null] +3696 - Suit of armour - [null, null, null, null, null] +3697 - Barrel - [null, null, null, null, null] +3698 - null - [null, null, null, null, null] +3699 - null - [null, null, null, null, null] +3700 - null - [null, null, null, null, null] +3701 - null - [null, null, null, null, null] +3702 - null - [null, null, null, null, null] +3703 - null - [null, null, null, null, null] +3704 - null - [null, null, null, null, null] +3705 - null - [null, null, null, null, null] +3706 - null - [null, null, null, null, null] +3707 - null - [null, null, null, null, null] +3708 - null - [null, null, null, null, null] +3709 - null - [null, null, null, null, null] +3710 - null - [null, null, null, null, null] +3711 - null - [null, null, null, null, null] +3712 - null - [null, null, null, null, null] +3713 - null - [null, null, null, null, null] +3714 - null - [null, null, null, null, null] +3715 - null - [null, null, null, null, null] +3716 - null - [null, null, null, null, null] +3717 - null - [null, null, null, null, null] +3718 - null - [null, null, null, null, null] +3719 - null - [null, null, null, null, null] +3720 - null - [null, null, null, null, null] +3721 - null - [null, null, null, null, null] +3722 - Rocks - [Climb, null, null, null, null] +3723 - Rocks - [Climb, null, null, null, null] +3724 - null - [null, null, null, null, null] +3725 - Gate - [Open, null, null, null, null] +3726 - Gate - [Open, null, null, null, null] +3727 - Gate - [Close, null, null, null, null] +3728 - Gate - [Close, null, null, null, null] +3729 - null - [null, null, null, null, null] +3730 - Stile - [Climb-over, null, null, null, null] +3731 - null - [null, null, null, null, null] +3732 - null - [null, null, null, null, null] +3733 - null - [null, null, null, null, null] +3734 - null - [null, null, null, null, null] +3735 - Cave Entrance - [Enter, null, null, null, null] +3736 - Cave Exit - [Exit, null, null, null, null] +3737 - null - [null, null, null, null, null] +3738 - null - [null, null, null, null, null] +3739 - null - [null, null, null, null, null] +3740 - null - [null, null, null, null, null] +3741 - Danger sign - [null, null, null, null, null] +3742 - Danger sign - [Read, null, null, null, null] +3743 - Large door - [Open, null, null, null, null] +3744 - null - [null, null, null, null, null] +3745 - Door - [Open, null, null, null, null] +3746 - Door - [Open, null, null, null, null] +3747 - Door - [Open, null, null, null, null] +3748 - Rocks - [Climb, null, null, null, null] +3749 - null - [null, null, null, null, null] +3750 - null - [null, null, null, null, null] +3751 - null - [null, null, null, null, null] +3752 - Mysterious glow - [null, null, null, null, null] +3753 - null - [null, null, null, null, null] +3754 - null - [null, null, null, null, null] +3755 - null - [null, null, null, null, null] +3756 - null - [null, null, null, null, null] +3757 - Cave Entrance - [Enter, null, null, null, null] +3758 - Cave Exit - [Exit, null, null, null, null] +3759 - Cave Entrance - [Enter, null, null, null, null] +3760 - Cave Exit - [Exit, null, null, null, null] +3761 - Exit - [Open, null, null, null, null] +3762 - Secret Door - [Open, null, null, null, null] +3763 - Cell Door - [Open, null, null, null, null] +3764 - Cell Door - [Close, null, null, null, null] +3765 - Cell Door - [Unlock, null, null, null, null] +3766 - null - [null, null, null, null, null] +3767 - Cell Door - [Unlock, null, null, null, null] +3768 - null - [null, null, null, null, null] +3769 - Fire - [null, null, null, null, null] +3770 - Window - [null, null, null, null, null] +3771 - Stronghold - [Enter, null, null, null, null] +3772 - Exit - [Use, null, null, null, null] +3773 - Exit - [Leave, null, null, null, null] +3774 - Exit - [Leave, null, null, null, null] +3775 - Fire - [null, null, null, null, null] +3776 - Door - [Open, null, null, null, null] +3777 - Door - [Close, null, null, null, null] +3778 - null - [null, null, null, null, null] +3779 - null - [null, null, null, null, null] +3780 - Prison Door - [Unlock, null, null, null, null] +3781 - null - [null, null, null, null, null] +3782 - Arena Entrance - [Open, null, null, null, null] +3783 - Arena Entrance - [Open, null, null, null, null] +3784 - null - [null, null, null, null, null] +3785 - Arena Exit - [Open, null, null, null, null] +3786 - Arena Exit - [Open, null, null, null, null] +3787 - null - [null, null, null, null, null] +3788 - Stone Staircase - [Climb-up, null, null, null, null] +3789 - Stone Staircase - [Climb-down, null, null, null, null] +3790 - Rocks - [Climb, null, null, null, null] +3791 - Rocks - [Climb, null, null, null, null] +3792 - null - [null, null, null, null, null] +3793 - null - [null, null, null, null, null] +3794 - Grass - [null, null, null, null, null] +3795 - Grass - [null, null, null, null, null] +3796 - null - [null, null, null, null, null] +3797 - Corpse - [null, null, null, null, null] +3798 - Corpse - [null, null, null, null, null] +3799 - Corpse - [null, null, null, null, null] +3800 - Counter - [null, null, null, null, null] +3801 - Chair - [null, null, null, null, null] +3802 - Smashed chair - [null, null, null, null, null] +3803 - Rocks - [Climb, null, null, null, null] +3804 - Rocks - [Climb, null, null, null, null] +3805 - Rocks - [null, null, null, null, null] +3806 - Rocks - [null, null, null, null, null] +3807 - Rocks - [null, null, null, null, null] +3808 - Rocks - [null, null, null, null, null] +3809 - null - [null, null, null, null, null] +3810 - Storeroom Door - [Open, null, null, null, null] +3811 - null - [null, null, null, null, null] +3812 - null - [null, null, null, null, null] +3813 - Crate - [null, null, null, null, null] +3814 - Crates - [null, null, null, null, null] +3815 - Crates - [null, null, null, null, null] +3816 - Kitchen Drawers - [Open, null, null, null, null] +3817 - Kitchen Drawers - [Close, Search, null, null, null] +3818 - null - [null, null, null, null, null] +3819 - null - [null, null, null, null, null] +3820 - Food Trough - [null, null, null, null, null] +3821 - Rack - [Search, null, null, null, null] +3822 - Goutweed Crate - [Search, null, null, null, null] +3823 - Sign - [null, null, null, null, null] +3824 - Troll Stew - [null, null, null, null, null] +3825 - Stalagmite - [null, null, null, null, null] +3826 - Stalagmites - [null, null, null, null, null] +3827 - Tunnel entrance - [null, null, null, null, null] +3828 - Tunnel entrance - [Climb-down, null, null, null, null] +3829 - Rope - [Climb-up, null, null, null, null] +3830 - Tunnel entrance - [null, null, null, null, null] +3831 - Tunnel entrance - [Climb-down, null, null, null, null] +3832 - Rope - [Climb-up, null, null, null, null] +3833 - Cocoon - [null, null, null, null, null] +3834 - null - [null, null, null, null, null] +3835 - null - [null, null, null, null, null] +3836 - null - [null, null, null, null, null] +3837 - null - [null, null, null, null, null] +3838 - null - [null, null, null, null, null] +3839 - null - [null, null, null, null, null] +3840 - null - [null, null, null, null, null] +3841 - null - [null, null, null, null, null] +3842 - null - [null, null, null, null, null] +3843 - null - [null, null, null, null, null] +3844 - null - [null, null, null, null, null] +3845 - null - [null, null, null, null, null] +3846 - null - [null, null, null, null, null] +3847 - null - [null, null, null, null, null] +3848 - null - [null, null, null, null, null] +3849 - null - [null, null, null, null, null] +3850 - null - [null, null, null, null, null] +3851 - null - [null, null, null, null, null] +3852 - null - [null, null, null, null, null] +3853 - null - [null, null, null, null, null] +3854 - null - [null, null, null, null, null] +3855 - null - [null, null, null, null, null] +3856 - Crate - [null, null, null, null, null] +3857 - Crate - [null, null, null, null, null] +3858 - Fishing rod - [null, null, null, null, null] +3859 - Fishing rod - [null, null, null, null, null] +3860 - Barrel - [null, null, null, null, null] +3861 - Crate - [null, null, null, null, null] +3862 - Burning bones - [null, null, null, null, null] +3863 - Tribal Statue - [Pray-at, null, null, null, null] +3864 - null - [null, null, null, null, null] +3865 - null - [null, null, null, null, null] +3866 - null - [null, null, null, null, null] +3867 - null - [null, null, null, null, null] +3868 - null - [null, null, null, null, null] +3869 - null - [null, null, null, null, null] +3870 - null - [null, null, null, null, null] +3871 - null - [null, null, null, null, null] +3872 - null - [null, null, null, null, null] +3873 - null - [null, null, null, null, null] +3874 - null - [null, null, null, null, null] +3875 - null - [null, null, null, null, null] +3876 - null - [null, null, null, null, null] +3877 - null - [null, null, null, null, null] +3878 - null - [null, null, null, null, null] +3879 - Tree - [Chop down, null, hidden, null, null] +3880 - Tree stump - [null, null, null, null, null] +3881 - Tree - [Chop down, null, hidden, null, null] +3882 - Tree - [Chop down, null, hidden, null, null] +3883 - Tree - [Chop down, null, hidden, null, null] +3884 - Tree stump - [null, null, null, null, null] +3885 - Tree - [null, null, null, null, null] +3886 - Tree - [null, null, null, null, null] +3887 - Tree - [null, null, null, null, null] +3888 - Tree - [null, null, null, null, null] +3889 - Tree - [null, null, null, null, null] +3890 - Tree - [null, null, null, null, null] +3891 - Tree - [null, null, null, null, null] +3892 - Tree - [null, null, null, null, null] +3893 - Tree - [null, null, null, null, null] +3894 - null - [null, null, null, null, null] +3895 - null - [null, null, null, null, null] +3896 - null - [null, null, null, null, null] +3897 - null - [null, null, null, null, null] +3898 - null - [null, null, null, null, null] +3899 - null - [null, null, null, null, null] +3900 - null - [null, null, null, null, null] +3901 - Flowers - [null, null, null, null, null] +3902 - Flowers - [null, null, null, null, null] +3903 - Flowers - [null, null, null, null, null] +3904 - Flowers - [null, null, null, null, null] +3905 - Flowers - [null, null, null, null, null] +3906 - Flowers - [null, null, null, null, null] +3907 - null - [null, null, null, null, null] +3908 - null - [null, null, null, null, null] +3909 - null - [null, null, null, null, null] +3910 - null - [null, null, null, null, null] +3911 - null - [null, null, null, null, null] +3912 - Mushroom - [null, null, null, null, null] +3913 - Mushrooms - [null, null, null, null, null] +3914 - Mushroom - [null, null, null, null, null] +3915 - Mushroom - [null, null, null, null, null] +3916 - Mushrooms - [null, null, null, null, null] +3917 - Mushroom - [null, null, null, null, null] +3918 - Elven lamp - [null, null, null, null, null] +3919 - Twigs - [null, null, null, null, null] +3920 - null - [null, null, null, null, null] +3921 - Tripwire - [Step-over, null, null, null, null] +3922 - Sticks - [Pass, null, null, null, null] +3923 - Leaves - [Jump, null, null, null, null] +3924 - Leaves - [Jump, null, null, null, null] +3925 - Leaves - [Jump, null, null, null, null] +3926 - null - [null, null, null, null, null] +3927 - Protruding rocks - [Climb, null, null, null, null] +3928 - Tree - [null, null, null, null, null] +3929 - Log balance - [null, null, null, null, null] +3930 - Log balance - [null, null, null, null, null] +3931 - Log balance - [Cross, null, null, null, null] +3932 - Log balance - [Cross, null, null, null, null] +3933 - Log balance - [Cross, null, null, null, null] +3934 - null - [null, null, null, null, null] +3935 - null - [null, null, null, null, null] +3936 - null - [null, null, null, null, null] +3937 - Dense forest - [Enter, null, null, null, null] +3938 - Dense forest - [Enter, null, null, null, null] +3939 - Dense forest - [Enter, null, null, null, null] +3940 - null - [null, null, null, null, null] +3941 - Tracks - [Follow, null, null, null, null] +3942 - null - [null, null, null, null, null] +3943 - null - [null, null, null, null, null] +3944 - Huge Gate - [Enter, null, null, null, null] +3945 - Huge Gate - [Enter, null, null, null, null] +3946 - Huge Gate - [null, null, null, null, null] +3947 - Huge Gate - [null, null, null, null, null] +3948 - null - [null, null, null, null, null] +3949 - null - [null, null, null, null, null] +3950 - null - [null, null, null, null, null] +3951 - null - [null, null, null, null, null] +3952 - null - [null, null, null, null, null] +3953 - null - [null, null, null, null, null] +3954 - null - [null, null, null, null, null] +3955 - null - [null, null, null, null, null] +3956 - null - [null, null, null, null, null] +3957 - null - [null, null, null, null, null] +3958 - null - [null, null, null, null, null] +3959 - null - [null, null, null, null, null] +3960 - null - [null, null, null, null, null] +3961 - null - [null, null, null, null, null] +3962 - Sulphur - [Take, null, null, null, null] +3963 - Sulphur - [Take, null, null, null, null] +3964 - Sulphur - [Take, null, null, null, null] +3965 - null - [null, null, null, null, null] +3966 - null - [null, null, null, null, null] +3967 - Tree - [null, null, null, null, null] +3968 - Tree - [null, null, null, null, null] +3969 - Pile of skulls - [null, null, null, null, null] +3970 - Charred bones - [null, null, null, null, null] +3971 - Corpse - [null, null, null, null, null] +3972 - Corpse - [null, null, null, null, null] +3973 - Corpse - [null, null, null, null, null] +3974 - Corpse - [null, null, null, null, null] +3975 - Tar - [Take, null, null, null, null] +3976 - null - [null, null, null, null, null] +3977 - null - [null, null, null, null, null] +3978 - null - [null, null, null, null, null] +3979 - null - [null, null, null, null, null] +3980 - Tent flap - [Enter, null, null, null, null] +3981 - null - [null, null, null, null, null] +3982 - null - [null, null, null, null, null] +3983 - Tent - [null, null, null, null, null] +3984 - Tent - [null, null, null, null, null] +3985 - Tent - [null, null, null, null, null] +3986 - Tent - [null, null, null, null, null] +3987 - Barrel - [null, null, null, null, null] +3988 - null - [null, null, null, null, null] +3989 - null - [null, null, null, null, null] +3990 - null - [null, null, null, null, null] +3991 - null - [null, null, null, null, null] +3992 - Standard - [null, null, null, null, null] +3993 - Standard - [null, null, null, null, null] +3994 - Small furnace - [null, null, null, null, null] +3995 - Tent wall - [null, null, null, null, null] +3996 - Tent flap - [Enter, null, null, null, null] +3997 - Tent wall - [null, null, null, null, null] +3998 - Dense forest - [Enter, null, null, null, null] +3999 - Dense forest - [Enter, null, null, null, null] +4000 - Tent roof - [null, null, null, null, null] +4001 - Tent wall - [null, null, null, null, null] +4002 - Tent pole - [null, null, null, null, null] +4003 - null - [null, null, null, null, null] +4004 - Well - [Climb-down, null, null, null, null] +4005 - Well - [Climb-down, null, null, null, null] +4006 - Cave entrance - [Enter, null, null, null, null] +4007 - Cave Exit - [Exit, null, null, null, null] +4008 - Altar - [Pray-at, null, null, null, null] +4009 - null - [null, null, null, null, null] +4010 - null - [null, null, null, null, null] +4011 - null - [null, null, null, null, null] +4012 - null - [null, null, null, null, null] +4013 - null - [null, null, null, null, null] +4014 - null - [null, null, null, null, null] +4015 - null - [null, null, null, null, null] +4016 - null - [null, null, null, null, null] +4017 - null - [null, null, null, null, null] +4018 - null - [null, null, null, null, null] +4019 - null - [null, null, null, null, null] +4020 - null - [null, null, null, null, null] +4021 - null - [null, null, null, null, null] +4022 - null - [null, null, null, null, null] +4023 - null - [null, null, null, null, null] +4024 - Barrel - [null, null, null, null, null] +4025 - Barrel - [null, null, null, null, null] +4026 - Fractionalizing still - [Operate, null, null, null, null] +4027 - Pile of Rock - [Mine, Prospect, hidden, null, null] +4028 - Pile of Rock - [Mine, Prospect, hidden, null, null] +4029 - Pile of Rock - [Mine, Prospect, hidden, null, null] +4030 - Pile of Rock - [Mine, Prospect, null, null, null] +4031 - Shantay pass - [Go-through, Look-at, null, null, null] +4032 - null - [null, null, null, null, null] +4033 - null - [null, null, null, null, null] +4034 - null - [null, null, null, null, null] +4035 - Druid's robes - [null, null, null, null, null] +4036 - Druid's robes - [null, null, null, null, null] +4037 - null - [null, null, null, null, null] +4038 - null - [null, null, null, null, null] +4039 - Trapdoor - [Open, hidden, null, null, null] +4040 - null - [null, null, null, null, null] +4041 - null - [null, null, null, null, null] +4042 - null - [null, null, null, null, null] +4043 - Aviary Hatch - [null, null, null, null, null] +4044 - Standard - [null, null, null, null, null] +4045 - null - [null, null, null, null, null] +4046 - null - [null, null, null, null, null] +4047 - null - [null, null, null, null, null] +4048 - Tree - [null, null, null, null, null] +4049 - Tree - [null, null, null, null, null] +4050 - Tree - [null, null, null, null, null] +4051 - Tree - [null, null, null, null, null] +4052 - Tree - [null, null, null, null, null] +4053 - Tree - [null, null, null, null, null] +4054 - Tree - [null, null, null, null, null] +4055 - Huge Mushroom - [null, null, null, null, null] +4056 - Huge Mushroom - [null, null, null, null, null] +4057 - Huge Mushroom - [null, null, null, null, null] +4058 - Obstacle pipe - [Squeeze-through, null, null, null, null] +4059 - Balancing rope - [Walk-on, null, null, null, null] +4060 - Hollow tree - [Chop down, null, hidden, null, null] +4061 - Tree stump - [null, null, null, null, null] +4062 - Shelf - [Search, null, null, null, null] +4063 - Sink - [null, null, null, null, null] +4064 - Smashed table - [null, null, null, null, Search] +4065 - Stone stand - [null, null, null, null, null] +4066 - Signpost - [Search, null, null, null, null] +4067 - Warning sign - [null, null, null, null, null] +4068 - Broken Wall - [Repair, null, hidden, null, null] +4069 - Temple wall - [Repair, null, hidden, null, null] +4070 - Temple wall - [Repair, null, hidden, null, null] +4071 - Temple wall - [Repair, null, hidden, null, null] +4072 - Temple wall - [Repair, null, hidden, null, null] +4073 - Temple wall - [Repair, null, hidden, null, null] +4074 - Temple wall - [Repair, null, hidden, null, null] +4075 - Temple wall - [Repair, null, hidden, null, null] +4076 - Temple wall - [Repair, null, hidden, null, null] +4077 - Temple wall - [Repair, null, hidden, null, null] +4078 - Temple wall - [Reinforce, null, hidden, null, null] +4079 - Broken Wall - [Repair, null, hidden, null, null] +4080 - Temple wall - [Repair, null, hidden, null, null] +4081 - Temple wall - [Repair, null, hidden, null, null] +4082 - Temple wall - [Repair, null, hidden, null, null] +4083 - Temple wall - [Repair, null, hidden, null, null] +4084 - Temple wall - [Repair, null, hidden, null, null] +4085 - Temple wall - [Repair, null, hidden, null, null] +4086 - Temple wall - [Repair, null, hidden, null, null] +4087 - Temple wall - [Repair, null, hidden, null, null] +4088 - Temple wall - [Repair, null, hidden, null, null] +4089 - Temple wall - [Reinforce, null, hidden, null, null] +4090 - Flaming Fire altar - [null, null, null, null, null] +4091 - Fire altar - [Light, null, hidden, null, null] +4092 - Broken Fire altar - [null, null, null, null, null] +4093 - Funeral Pyre - [null, null, null, null, null] +4094 - Funeral pyre - [null, null, null, null, null] +4095 - Funeral pyre - [null, null, null, null, null] +4096 - Funeral pyre - [null, null, null, null, null] +4097 - Funeral pyre - [null, null, null, null, null] +4098 - Funeral pyre - [null, null, null, null, null] +4099 - null - [null, null, null, null, null] +4100 - Funeral pyre - [Light, null, null, null, null] +4101 - Funeral pyre - [Light, null, null, null, null] +4102 - Funeral pyre - [Light, null, null, null, null] +4103 - Funeral pyre - [Light, null, null, null, null] +4104 - Funeral pyre - [Light, null, null, null, null] +4105 - null - [null, null, null, null, null] +4106 - Solid bronze door - [Open, null, null, null, null] +4107 - Solid steel door - [Open, null, null, null, null] +4108 - Solid black door - [Open, null, null, null, null] +4109 - Solid silver door - [Open, null, null, null, null] +4110 - null - [null, null, null, null, null] +4111 - Bronze Chest - [Open, null, null, null, null] +4112 - Bronze Chest - [Open, null, null, null, null] +4113 - Bronze Chest - [Open, null, null, null, null] +4114 - Bronze Chest - [Open, null, null, null, null] +4115 - Bronze Chest - [Open, null, null, null, null] +4116 - Steel Chest - [Open, null, null, null, null] +4117 - Steel Chest - [Open, null, null, null, null] +4118 - Steel Chest - [Open, null, null, null, null] +4119 - Steel Chest - [Open, null, null, null, null] +4120 - Steel Chest - [Open, null, null, null, null] +4121 - Black Chest - [Open, null, null, null, null] +4122 - Black Chest - [Open, null, null, null, null] +4123 - Black Chest - [Open, null, null, null, null] +4124 - Black Chest - [Open, null, null, null, null] +4125 - Black Chest - [Open, null, null, null, null] +4126 - Silver Chest - [Open, null, null, null, null] +4127 - Silver Chest - [Open, null, null, null, null] +4128 - Silver Chest - [Open, null, null, null, null] +4129 - Silver Chest - [Open, null, null, null, null] +4130 - Silver Chest - [Open, null, null, null, null] +4131 - Bronze Chest - [null, null, null, null, null] +4132 - Signpost - [Read, null, null, null, null] +4133 - Signpost - [Read, null, null, null, null] +4134 - Signpost - [Read, null, null, null, null] +4135 - Signpost - [Read, null, null, null, null] +4136 - null - [null, null, null, null, null] +4137 - null - [null, null, null, null, null] +4138 - Counter - [null, null, null, null, null] +4139 - Gate - [Close, null, null, null, null] +4140 - Gate - [Close, null, null, null, null] +4141 - Strange altar - [null, null, null, null, null] +4142 - Swaying tree - [Cut-branch, null, null, null, null] +4143 - Danger sign - [Read, null, null, null, null] +4144 - Golden tree - [null, null, null, null, null] +4145 - null - [null, null, null, null, null] +4146 - null - [null, null, null, null, null] +4147 - Cave Entrance - [Enter, null, null, null, null] +4148 - Door - [Open, null, null, null, null] +4149 - Lalli's Stew - [null, null, null, null, null] +4150 - Portal - [Use, null, null, null, null] +4151 - Portal - [Use, null, null, null, null] +4152 - Portal - [Use, null, null, null, null] +4153 - Portal - [Use, null, null, null, null] +4154 - Portal - [Use, null, null, null, null] +4155 - Portal - [Use, null, null, null, null] +4156 - Portal - [Use, null, null, null, null] +4157 - Portal - [Use, null, null, null, null] +4158 - Ladder - [Climb-down, null, null, null, null] +4159 - Ladder - [Climb-up, null, null, null, null] +4160 - Ladder - [Climb-up, null, null, null, null] +4161 - Escape rope - [Climb-up, null, null, null, null] +4162 - Pipe - [Put-inside, null, null, null, null] +4163 - Ladder - [Climb-up, null, null, null, null] +4164 - Ladder - [Climb-up, null, null, null, null] +4165 - Door - [Open, null, null, null, null] +4166 - Door - [Open, null, null, null, null] +4167 - Chest - [Open, null, null, null, null] +4168 - Chest - [Close, Search, null, null, null] +4169 - Frozen table - [null, null, null, null, null] +4170 - Chest - [Open, null, null, null, null] +4171 - Bookcase - [Search, null, null, null, null] +4172 - Cooking range - [null, null, null, null, null] +4173 - Trapdoor - [Climb-down, Close, null, null, null] +4174 - Trapdoor - [Open, null, null, null, null] +4175 - Drain - [null, null, null, null, null] +4176 - Tap - [null, null, null, null, null] +4177 - Cupboard - [Open, null, null, null, null] +4178 - Cupboard - [Shut, Search, null, null, null] +4179 - Abstract mural - [Study, null, null, null, null] +4180 - Abstract mural - [Study, null, null, null, null] +4181 - Unicorn's head - [Study, null, null, null, null] +4182 - Bull's head - [Study, null, null, null, null] +4183 - Boxes - [Search, null, null, null, null] +4184 - Boxes - [Search, null, null, null, null] +4185 - Crate - [Search, null, null, null, null] +4186 - Crate - [Search, null, null, null, null] +4187 - Ladder - [null, Climb-down, Climb-up, null, null] +4188 - Ladder - [Climb-up, null, null, null, null] +4189 - Ladder - [Climb-down, null, null, null, null] +4190 - null - [null, null, null, null, null] +4191 - null - [null, null, null, null, null] +4192 - null - [null, null, null, null, null] +4193 - null - [null, null, null, null, null] +4194 - null - [null, null, null, null, null] +4195 - null - [null, null, null, null, null] +4196 - null - [null, null, null, null, null] +4197 - null - [null, null, null, null, null] +4198 - null - [null, null, null, null, null] +4199 - null - [null, null, null, null, null] +4200 - null - [null, null, null, null, null] +4201 - null - [null, null, null, null, null] +4202 - null - [null, null, null, null, null] +4203 - null - [null, null, null, null, null] +4204 - null - [null, null, null, null, null] +4205 - null - [null, null, null, null, null] +4206 - null - [null, null, null, null, null] +4207 - null - [null, null, null, null, null] +4208 - null - [null, null, null, null, null] +4209 - null - [null, null, null, null, null] +4210 - null - [null, null, null, null, null] +4211 - null - [null, null, null, null, null] +4212 - null - [null, null, null, null, null] +4213 - null - [null, null, null, null, null] +4214 - null - [null, null, null, null, null] +4215 - null - [null, null, null, null, null] +4216 - null - [null, null, null, null, null] +4217 - null - [null, null, null, null, null] +4218 - null - [null, null, null, null, null] +4219 - null - [null, null, null, null, null] +4220 - null - [null, null, null, null, null] +4221 - null - [null, null, null, null, null] +4222 - null - [null, null, null, null, null] +4223 - null - [null, null, null, null, null] +4224 - null - [null, null, null, null, null] +4225 - null - [null, null, null, null, null] +4226 - null - [null, null, null, null, null] +4227 - null - [null, null, null, null, null] +4228 - null - [null, null, null, null, null] +4229 - null - [null, null, null, null, null] +4230 - null - [null, null, null, null, null] +4231 - null - [null, null, null, null, null] +4232 - null - [null, null, null, null, null] +4233 - null - [null, null, null, null, null] +4234 - null - [null, null, null, null, null] +4235 - null - [null, null, null, null, null] +4236 - null - [null, null, null, null, null] +4237 - null - [null, null, null, null, null] +4238 - null - [null, null, null, null, null] +4239 - null - [null, null, null, null, null] +4240 - null - [null, null, null, null, null] +4241 - null - [null, null, null, null, null] +4242 - null - [null, null, null, null, null] +4243 - null - [null, null, null, null, null] +4244 - null - [null, null, null, null, null] +4245 - null - [null, null, null, null, null] +4246 - null - [null, null, null, null, null] +4247 - Door - [Open, null, null, null, null] +4248 - Door - [Close, null, null, null, null] +4249 - null - [null, null, null, null, null] +4250 - Door - [Open, null, null, null, null] +4251 - Door - [Close, null, null, null, null] +4252 - Chest - [Open, null, null, null, null] +4253 - Chest - [Close, Search, null, null, null] +4254 - null - [null, null, null, null, null] +4255 - null - [null, null, null, null, null] +4256 - null - [null, null, null, null, null] +4257 - null - [null, null, null, null, null] +4258 - null - [null, null, null, null, null] +4259 - null - [null, null, null, null, null] +4260 - null - [null, null, null, null, null] +4261 - null - [null, null, null, null, null] +4262 - null - [null, null, null, null, null] +4263 - null - [null, null, null, null, null] +4264 - null - [null, null, null, null, null] +4265 - Fire - [null, null, null, null, null] +4266 - Fire - [null, null, null, null, null] +4267 - Spit roast - [null, null, null, null, null] +4268 - null - [null, null, null, null, null] +4269 - Wooden Table - [null, null, null, null, null] +4270 - Wooden Table - [null, null, null, null, null] +4271 - Chair - [null, null, null, null, null] +4272 - Table - [null, null, null, null, null] +4273 - Bar pumps - [null, null, null, null, null] +4274 - Bar - [null, null, null, null, null] +4275 - Barrel - [null, null, null, null, null] +4276 - Market stall - [null, null, null, null, null] +4277 - Fish stall - [null, Steal-from, null, null, null] +4278 - Fur stall - [null, Steal-from, null, null, null] +4279 - null - [null, null, null, null, null] +4280 - null - [null, null, null, null, null] +4281 - null - [null, null, null, null, null] +4282 - null - [null, null, null, null, null] +4283 - Drain - [null, null, null, null, null] +4284 - null - [null, null, null, null, null] +4285 - Tap - [null, null, null, null, null] +4286 - Keg - [null, null, null, null, null] +4287 - Bed - [null, null, null, null, null] +4288 - Bed - [null, null, null, null, null] +4289 - null - [null, null, null, null, null] +4290 - null - [null, null, null, null, null] +4291 - null - [null, null, null, null, null] +4292 - null - [null, null, null, null, null] +4293 - null - [null, null, null, null, null] +4294 - null - [null, null, null, null, null] +4295 - null - [null, null, null, null, null] +4296 - Abandoned Cart - [null, null, null, null, null] +4297 - Boxes - [null, null, null, null, null] +4298 - Boxes - [null, null, null, null, null] +4299 - Boxes - [null, null, null, null, null] +4300 - Crate - [Search, null, null, null, null] +4301 - Crate - [Search, null, null, null, null] +4302 - null - [null, null, null, null, null] +4303 - null - [null, null, null, null, null] +4304 - Furnace - [null, Smelt, null, null, null] +4305 - null - [null, null, null, null, null] +4306 - Anvil - [null, null, null, null, null] +4307 - Blacksmith's tools - [null, null, null, null, null] +4308 - Pottery Oven - [Fire, null, null, null, null] +4309 - Spinning wheel - [null, Spin, null, null, null] +4310 - Potter's Wheel - [null, null, null, null, null] +4311 - Gate - [Open, null, null, null, null] +4312 - Gate - [Open, null, null, null, null] +4313 - Gate - [null, null, null, null, null] +4314 - null - [null, null, null, null, null] +4315 - null - [null, null, null, null, null] +4316 - null - [null, null, null, null, null] +4317 - null - [null, null, null, null, null] +4318 - null - [null, null, null, null, null] +4319 - null - [null, null, null, null, null] +4320 - null - [null, null, null, null, null] +4321 - null - [null, null, null, null, null] +4322 - null - [null, null, null, null, null] +4323 - null - [null, null, null, null, null] +4324 - null - [null, null, null, null, null] +4325 - null - [null, null, null, null, null] +4326 - null - [null, null, null, null, null] +4327 - null - [null, null, null, null, null] +4328 - Tree stump - [null, null, null, null, null] +4329 - Tree stump - [null, null, null, null, null] +4330 - null - [null, null, null, null, null] +4331 - null - [null, null, null, null, null] +4332 - null - [null, null, null, null, null] +4333 - null - [null, null, null, null, null] +4334 - null - [null, null, null, null, null] +4335 - null - [null, null, null, null, null] +4336 - null - [null, null, null, null, null] +4337 - null - [null, null, null, null, null] +4338 - null - [null, null, null, null, null] +4339 - null - [null, null, null, null, null] +4340 - null - [null, null, null, null, null] +4341 - null - [null, null, null, null, null] +4342 - null - [null, null, null, null, null] +4343 - null - [null, null, null, null, null] +4344 - null - [null, null, null, null, null] +4345 - null - [null, null, null, null, null] +4346 - null - [null, null, null, null, null] +4347 - null - [null, null, null, null, null] +4348 - Shell - [null, null, null, null, null] +4349 - Shell - [null, null, null, null, null] +4350 - Shell - [null, null, null, null, null] +4351 - Shell - [null, null, null, null, null] +4352 - Bowl - [null, null, null, null, null] +4353 - null - [null, null, null, null, null] +4354 - null - [null, null, null, null, null] +4355 - null - [null, null, null, null, null] +4356 - null - [null, null, null, null, null] +4357 - null - [null, null, null, null, null] +4358 - null - [null, null, null, null, null] +4359 - null - [null, null, null, null, null] +4360 - null - [null, null, null, null, null] +4361 - null - [null, null, null, null, null] +4362 - null - [null, null, null, null, null] +4363 - null - [null, null, null, null, null] +4364 - null - [null, null, null, null, null] +4365 - null - [null, null, null, null, null] +4366 - Shelf - [null, null, null, null, null] +4367 - Shelf - [null, null, null, null, null] +4368 - Shelf - [null, null, null, null, null] +4369 - Shelf - [null, null, null, null, null] +4370 - Shelf - [null, null, null, null, null] +4371 - Shelf - [null, null, null, null, null] +4372 - Table - [null, null, null, null, null] +4373 - Sand pit - [null, null, null, null, null] +4374 - null - [null, null, null, null, null] +4375 - null - [null, null, null, null, null] +4376 - null - [null, null, null, null, null] +4377 - Standard Stand - [Capture, null, null, null, null] +4378 - Standard Stand - [Capture, null, null, null, null] +4379 - null - [null, null, null, null, null] +4380 - Iron ladder - [null, null, null, null, null] +4381 - Catapult - [Operate, null, null, null, null] +4382 - Catapult - [Operate, null, null, null, null] +4383 - Iron ladder - [Climb, null, null, null, null] +4384 - null - [null, null, null, null, null] +4385 - Catapult - [Repair, null, null, null, null] +4386 - Catapult - [Repair, null, null, null, null] +4387 - Saradomin Portal - [Enter, null, null, null, null] +4388 - Zamorak Portal - [Enter, null, null, null, null] +4389 - Portal - [Exit, null, null, null, null] +4390 - Portal - [Exit, null, null, null, null] +4391 - null - [null, null, null, null, null] +4392 - null - [null, null, null, null, null] +4393 - null - [null, null, null, null, null] +4394 - null - [null, null, null, null, null] +4395 - null - [null, null, null, null, null] +4396 - null - [null, null, null, null, null] +4397 - null - [null, null, null, null, null] +4398 - null - [null, null, null, null, null] +4399 - null - [null, null, null, null, null] +4400 - null - [null, null, null, null, null] +4401 - null - [null, null, null, null, null] +4402 - null - [null, null, null, null, null] +4403 - null - [null, null, null, null, null] +4404 - null - [null, null, null, null, null] +4405 - null - [null, null, null, null, null] +4406 - Portal - [Leave, null, null, null, null] +4407 - Portal - [Leave, null, null, null, null] +4408 - Guthix Portal - [Enter, null, null, null, null] +4409 - null - [null, null, null, null, null] +4410 - null - [null, null, null, null, null] +4411 - Stepping stone - [Jump-to, null, null, null, null] +4412 - Iron ladder - [Climb, null, null, null, null] +4413 - Iron ladder - [Climb, null, null, null, null] +4414 - Staircase - [null, null, null, null, null] +4415 - Staircase - [Climb, null, null, null, null] +4416 - Staircase - [Climb, null, null, null, null] +4417 - Staircase - [Climb, null, null, null, null] +4418 - Staircase - [Climb, null, null, null, null] +4419 - Staircase - [Climb, null, null, null, null] +4420 - Staircase - [Climb, null, null, null, null] +4421 - Barricade - [null, null, null, null, null] +4422 - Barricade - [null, null, null, null, null] +4423 - Large door - [Open, Attack, null, null, null] +4424 - Large door - [Open, Attack, null, null, null] +4425 - Large door - [Close, null, null, null, null] +4426 - Large door - [Close, null, null, null, null] +4427 - Large door - [Open, Attack, null, null, null] +4428 - Large door - [Open, Attack, null, null, null] +4429 - Large door - [Close, null, null, null, null] +4430 - Large door - [Close, null, null, null, null] +4431 - Broken door - [Repair, null, null, null, null] +4432 - Broken door - [Repair, null, null, null, null] +4433 - Broken door - [Repair, null, null, null, null] +4434 - Broken door - [Repair, null, null, null, null] +4435 - null - [null, null, null, null, null] +4436 - null - [null, null, null, null, null] +4437 - Rocks - [Mine, null, hidden, null, null] +4438 - Rocks - [Mine, null, hidden, null, null] +4439 - null - [null, null, null, null, null] +4440 - null - [null, null, null, null, null] +4441 - null - [null, null, null, null, null] +4442 - null - [null, null, null, null, null] +4443 - null - [null, null, null, null, null] +4444 - Climbing Rope - [Climb, null, null, null, null] +4445 - null - [null, null, null, null, null] +4446 - Battlements - [null, null, null, null, null] +4447 - Battlements - [null, null, null, null, null] +4448 - Cave wall - [Collapse, null, hidden, null, null] +4449 - Staircase - [null, null, null, null, null] +4450 - Staircase - [null, null, null, null, null] +4451 - null - [null, null, null, null, null] +4452 - null - [null, null, null, null, null] +4453 - null - [null, null, null, null, null] +4454 - null - [null, null, null, null, null] +4455 - null - [null, null, null, null, null] +4456 - null - [null, null, null, null, null] +4457 - null - [null, null, null, null, null] +4458 - Table - [Take-from, null, null, null, null] +4459 - Table - [Take-from, null, null, null, null] +4460 - Table - [Take-from, null, null, null, null] +4461 - Table - [Take-from, null, null, null, null] +4462 - Table - [Take-from, null, null, null, null] +4463 - Table - [Take-from, null, null, null, null] +4464 - Table - [Take-from, null, null, null, null] +4465 - Door - [Unlock, null, null, null, null] +4466 - Door - [Lock, null, null, null, null] +4467 - Door - [Unlock, null, null, null, null] +4468 - Door - [Lock, null, null, null, null] +4469 - Energy Barrier - [Pass, null, null, null, null] +4470 - Energy Barrier - [Pass, null, null, null, null] +4471 - Trapdoor - [Open, null, null, null, null] +4472 - Trapdoor - [Open, null, null, null, null] +4473 - null - [null, null, null, null, null] +4474 - null - [null, null, null, null, null] +4475 - null - [null, null, null, null, null] +4476 - null - [null, null, null, null, null] +4477 - null - [null, null, null, null, null] +4478 - null - [null, null, null, null, null] +4479 - null - [null, null, null, null, null] +4480 - null - [null, null, null, null, null] +4481 - null - [null, null, null, null, null] +4482 - Tap - [null, null, null, null, null] +4483 - Bank chest - [Use, null, null, null, null] +4484 - Scoreboard - [View, null, null, null, null] +4485 - Iron ladder - [Climb, null, null, null, null] +4486 - null - [null, null, null, null, null] +4487 - Door - [Open, null, null, null, null] +4488 - null - [Open, null, null, null, null] +4489 - null - [Open, null, null, null, null] +4490 - Door - [Open, null, null, null, null] +4491 - Door - [Close, null, null, null, null] +4492 - Door - [Close, null, null, null, null] +4493 - Staircase - [Climb-up, null, null, null, null] +4494 - Staircase - [Climb-down, null, null, null, null] +4495 - Staircase - [Climb-up, null, null, null, null] +4496 - Staircase - [Climb-down, null, null, null, null] +4497 - Staircase - [Climb-up, null, null, null, null] +4498 - Staircase - [Climb-down, null, null, null, null] +4499 - Cave Entrance - [Enter, null, null, null, null] +4500 - Tunnel - [Enter, null, null, null, null] +4501 - null - [null, null, null, null, null] +4502 - null - [null, null, null, null, null] +4503 - null - [null, null, null, null, null] +4504 - null - [null, null, null, null, null] +4505 - null - [null, null, null, null, null] +4506 - null - [null, null, null, null, null] +4507 - null - [null, null, null, null, null] +4508 - null - [null, null, null, null, null] +4509 - null - [null, null, null, null, null] +4510 - null - [null, null, null, null, null] +4511 - null - [null, null, null, null, null] +4512 - null - [null, null, null, null, null] +4513 - Heap of bricks - [null, null, null, null, null] +4514 - null - [null, null, null, null, null] +4515 - null - [null, null, null, null, null] +4516 - null - [null, null, null, null, null] +4517 - null - [null, null, null, null, null] +4518 - Corpse - [null, null, null, null, null] +4519 - Corpse - [null, null, null, null, null] +4520 - Corpse - [null, null, null, null, null] +4521 - null - [null, null, null, null, null] +4522 - null - [null, null, null, null, null] +4523 - null - [null, null, null, null, null] +4524 - null - [null, null, null, null, null] +4525 - null - [null, null, null, null, null] +4526 - null - [null, null, null, null, null] +4527 - null - [null, null, null, null, null] +4528 - null - [null, null, null, null, null] +4529 - null - [null, null, null, null, null] +4530 - null - [null, null, null, null, null] +4531 - null - [null, null, null, null, null] +4532 - null - [null, null, null, null, null] +4533 - null - [null, null, null, null, null] +4534 - null - [null, null, null, null, null] +4535 - null - [null, null, null, null, null] +4536 - null - [null, null, null, null, null] +4537 - null - [null, null, null, null, null] +4538 - null - [null, null, null, null, null] +4539 - null - [null, null, null, null, null] +4540 - null - [null, null, null, null, null] +4541 - Statue - [null, null, null, null, null] +4542 - null - [null, null, null, null, null] +4543 - Strange wall - [Study, null, null, null, null] +4544 - Strange wall - [Study, null, null, null, null] +4545 - Strange wall - [Open, null, null, null, null] +4546 - Strange wall - [Open, null, null, null, null] +4547 - null - [null, null, null, null, null] +4548 - null - [null, null, null, null, null] +4549 - null - [null, null, null, null, null] +4550 - Beach - [Jump-to, null, null, null, null] +4551 - Basalt rock - [Jump-across, null, null, null, null] +4552 - Basalt rock - [Jump-across, null, null, null, null] +4553 - Basalt rock - [Jump-across, null, null, null, null] +4554 - Basalt rock - [Jump-across, null, null, null, null] +4555 - Basalt rock - [Jump-across, null, null, null, null] +4556 - Basalt rock - [Jump-across, null, null, null, null] +4557 - Basalt rock - [Jump-across, null, null, null, null] +4558 - Basalt rock - [Jump-across, null, null, null, null] +4559 - Rocky shore - [Jump-to, null, null, null, null] +4560 - null - [null, null, null, null, null] +4561 - null - [null, null, null, null, null] +4562 - null - [null, null, null, null, null] +4563 - null - [null, null, null, null, null] +4564 - null - [null, null, null, null, null] +4565 - null - [null, null, null, null, null] +4566 - null - [null, null, null, null, null] +4567 - null - [null, null, null, null, null] +4568 - Staircase - [Climb-up, null, null, null, null] +4569 - Staircase - [Climb, Climb-up, Climb-down, null, null] +4570 - Staircase - [Climb-down, null, null, null, null] +4571 - null - [null, null, null, null, null] +4572 - null - [null, null, null, null, null] +4573 - null - [null, null, null, null, null] +4574 - null - [null, null, null, null, null] +4575 - null - [null, null, null, null, null] +4576 - null - [null, null, null, null, null] +4577 - Doorway - [Walk-through, null, null, null, null] +4578 - null - [null, null, null, null, null] +4579 - null - [null, null, null, null, null] +4580 - null - [null, null, null, null, null] +4581 - null - [null, null, null, null, null] +4582 - null - [null, null, null, null, null] +4583 - null - [null, null, null, null, null] +4584 - null - [null, null, null, null, null] +4585 - null - [null, null, null, null, null] +4586 - null - [null, null, null, null, null] +4587 - Lighting mechanism - [null, null, null, null, null] +4588 - Lighting mechanism - [null, null, null, null, null] +4589 - Lighting mechanism - [null, null, null, null, null] +4590 - Lighting mechanism - [null, null, null, null, null] +4591 - null - [null, null, null, null, null] +4592 - null - [null, null, null, null, null] +4593 - null - [null, null, null, null, null] +4594 - null - [null, null, null, null, null] +4595 - null - [null, null, null, null, null] +4596 - null - [null, null, null, null, null] +4597 - null - [null, null, null, null, null] +4598 - null - [null, null, null, null, null] +4599 - null - [null, null, null, null, null] +4600 - null - [null, null, null, null, null] +4601 - null - [null, null, null, null, null] +4602 - null - [null, null, null, null, null] +4603 - null - [null, null, null, null, null] +4604 - null - [null, null, null, null, null] +4605 - null - [null, null, null, null, null] +4606 - null - [null, null, null, null, null] +4607 - null - [null, null, null, null, null] +4608 - null - [null, null, null, null, null] +4609 - null - [null, null, null, null, null] +4610 - Shell - [null, null, null, null, null] +4611 - Shell - [null, null, null, null, null] +4612 - Shell - [null, null, null, null, null] +4613 - Shell - [null, null, null, null, null] +4614 - Bowl - [null, null, null, null, null] +4615 - Broken bridge - [Cross, null, null, null, null] +4616 - Broken bridge - [Cross, null, null, null, null] +4617 - Bookcase - [Search, null, null, null, null] +4618 - Fireplace - [null, null, null, null, null] +4619 - null - [null, null, null, null, null] +4620 - Stairs - [Climb-down, null, null, null, null] +4621 - Stairs - [Climb-down, null, null, null, null] +4622 - Stairs - [Climb-up, null, null, null, null] +4623 - Stairs - [Climb-up, null, null, null, null] +4624 - Stairs - [Climb-down, null, null, null, null] +4625 - Stairs - [Climb-down, null, null, null, null] +4626 - Stairs - [Climb-up, null, null, null, null] +4627 - Stairs - [Climb-up, null, null, null, null] +4628 - null - [null, null, null, null, null] +4629 - Large door - [Open, null, null, null, null] +4630 - Large door - [Close, null, null, null, null] +4631 - Large door - [Open, null, null, null, null] +4632 - Large door - [Open, null, null, null, null] +4633 - Large door - [Open, null, null, null, null] +4634 - Large door - [Close, null, null, null, null] +4635 - null - [null, null, null, null, null] +4636 - Door - [Open, null, null, null, null] +4637 - Door - [Open, null, null, null, null] +4638 - Door - [Open, null, null, null, null] +4639 - Door - [Close, null, null, null, null] +4640 - Door - [Open, null, null, null, null] +4641 - Stacked barrels - [null, null, null, null, null] +4642 - Noticeboard - [Read, null, null, null, null] +4643 - Ladder - [Climb-up, null, null, null, null] +4644 - Ladder - [Climb-Down, null, null, null, null] +4645 - Ladder - [Climb-up, null, null, null, null] +4646 - Ladder - [Climb-Down, null, null, null, null] +4647 - Ladder - [Climb-up, null, null, null, null] +4648 - Ladder - [Climb-Down, null, null, null, null] +4649 - null - [null, null, null, null, null] +4650 - Fireplace - [null, null, null, null, null] +4651 - Table - [null, null, null, null, null] +4652 - Table - [View-game, null, null, null, null] +4653 - Table - [View-game, null, null, null, null] +4654 - null - [null, null, null, null, null] +4655 - null - [null, null, null, null, null] +4656 - Stool - [null, null, null, null, null] +4657 - null - [null, null, null, null, null] +4658 - Plaque - [null, null, null, null, null] +4659 - Plaque - [null, null, null, null, null] +4660 - Plaque - [null, null, null, null, null] +4661 - Plaque - [null, null, null, null, null] +4662 - null - [null, null, null, null, null] +4663 - null - [null, null, null, null, null] +4664 - null - [null, null, null, null, null] +4665 - null - [null, null, null, null, null] +4666 - null - [null, null, null, null, null] +4667 - null - [null, null, null, null, null] +4668 - null - [null, null, null, null, null] +4669 - Arrav - [null, null, null, null, null] +4670 - Camorra - [null, null, null, null, null] +4671 - Bookcase - [Search, null, null, null, null] +4672 - Throne Room Door - [Open, null, null, null, null] +4673 - null - [null, null, null, null, null] +4674 - Maple tree - [Chop down, null, hidden, null, null] +4675 - Herbs - [Weed, null, hidden, null, null] +4676 - Rocks - [Mine, Prospect, hidden, null, null] +4677 - Herbs - [Weed, null, hidden, null, null] +4678 - Herbs - [Weed, null, hidden, null, null] +4679 - Herbs - [Weed, null, hidden, null, null] +4680 - null - [null, null, null, null, null] +4681 - null - [null, null, null, null, null] +4682 - null - [null, null, null, null, null] +4683 - Harp - [null, null, null, null, null] +4684 - Barrel - [null, null, null, null, null] +4685 - Hollow log - [null, null, null, null, null] +4686 - Hollow log - [null, null, null, null, null] +4687 - null - [null, null, null, null, null] +4688 - null - [null, null, null, null, null] +4689 - null - [null, null, null, null, null] +4690 - Chair - [null, null, null, null, null] +4691 - null - [null, null, null, null, null] +4692 - Flagpole - [null, null, null, null, null] +4693 - Flagpole - [null, null, null, null, null] +4694 - null - [null, null, null, null, null] +4695 - null - [null, null, null, null, null] +4696 - Door - [Open, null, null, null, null] +4697 - Door - [Close, null, null, null, null] +4698 - null - [null, null, null, null, null] +4699 - null - [null, null, null, null, null] +4700 - null - [null, null, null, null, null] +4701 - Door - [null, null, null, null, null] +4702 - Chair - [null, null, null, null, null] +4703 - Bed - [null, null, null, null, null] +4704 - Bed - [null, null, null, null, null] +4705 - Fish stall - [null, Steal-from, null, null, null] +4706 - Veg stall - [null, Steal-from, null, null, null] +4707 - Fish stall - [null, Steal-from, null, null, null] +4708 - Veg stall - [null, Steal-from, null, null, null] +4709 - null - [null, null, null, null, null] +4710 - Doorway - [Open, null, null, null, null] +4711 - null - [null, null, null, null, null] +4712 - Trapdoor - [Open, null, null, null, null] +4713 - Trapdoor - [Climb-down, Close, null, null, null] +4714 - Crate - [Search, null, null, null, null] +4715 - Crate - [Search, null, null, null, null] +4716 - Crate - [Search, null, null, null, null] +4717 - Crate - [Search, null, null, null, null] +4718 - Crate - [Search, null, null, null, null] +4719 - Crate - [Search, null, null, null, null] +4720 - Crate - [Search, null, null, null, null] +4721 - Crate - [Search, null, null, null, null] +4722 - Crate - [Search, null, null, null, null] +4723 - Crate - [Search, null, null, null, null] +4724 - Crate - [Search, null, null, null, null] +4725 - Crate - [Search, null, null, null, null] +4726 - Crate - [Search, null, null, null, null] +4727 - Crate - [Search, null, null, null, null] +4728 - Climbing rope - [Climb, null, null, null, null] +4729 - Bush - [null, null, null, null, null] +4730 - null - [null, null, null, null, null] +4731 - null - [null, null, null, null, null] +4732 - null - [null, null, null, null, null] +4733 - null - [null, null, null, null, null] +4734 - null - [null, null, null, null, null] +4735 - null - [null, null, null, null, null] +4736 - null - [null, null, null, null, null] +4737 - null - [null, null, null, null, null] +4738 - null - [null, null, null, null, null] +4739 - null - [null, null, null, null, null] +4740 - null - [null, null, null, null, null] +4741 - null - [null, null, null, null, null] +4742 - null - [null, null, null, null, null] +4743 - Bamboo Ladder - [Climb-up, null, null, null, null] +4744 - Bamboo Ladder - [Climb-down, null, null, null, null] +4745 - End of bridge - [Jump off, null, null, null, null] +4746 - Crate - [Search, null, null, null, null] +4747 - null - [null, null, null, null, null] +4748 - null - [null, null, null, null, null] +4749 - Banana Tree - [Search, null, null, null, null] +4750 - Banana Tree - [Search, null, null, null, null] +4751 - Banana Tree - [Search, null, null, null, null] +4752 - Banana Tree - [Search, null, null, null, null] +4753 - Banana Tree - [Search, null, null, null, null] +4754 - Banana Tree - [Search, null, null, null, null] +4755 - Stairs - [Climb-down, null, null, null, null] +4756 - Stairs - [Climb-up, null, null, null, null] +4757 - null - [null, null, null, null, null] +4758 - null - [null, null, null, null, null] +4759 - null - [null, null, null, null, null] +4760 - null - [null, null, null, null, null] +4761 - null - [null, null, null, null, null] +4762 - null - [null, null, null, null, null] +4763 - null - [null, null, null, null, null] +4764 - Bamboo Stool - [null, null, null, null, null] +4765 - Wall of flame - [null, null, null, null, null] +4766 - Wall of flame - [null, null, null, null, null] +4767 - Sacrificial Pyre - [null, null, null, null, null] +4768 - Wall of bricks - [null, null, null, null, null] +4769 - Pile of bricks - [null, null, null, null, null] +4770 - Pile of bricks - [null, null, null, null, null] +4771 - Awowogei - [Talk-to, null, null, null, null] +4772 - Bamboo Ladder - [Climb-up, null, null, null, null] +4773 - Bamboo Ladder - [Climb-up, null, null, null, null] +4774 - Bamboo Ladder - [Climb-up, null, null, null, null] +4775 - Bamboo Ladder - [Climb-up, null, null, null, null] +4776 - Bamboo Ladder - [Climb-down, null, null, null, null] +4777 - Bamboo Ladder - [Climb-down, null, null, null, null] +4778 - Bamboo Ladder - [Climb-down, null, null, null, null] +4779 - Bamboo Ladder - [Climb-down, null, null, null, null] +4780 - Bamboo Ladder - [Climb-down, null, null, null, null] +4781 - Bamboo Ladder - [Climb-up, null, null, null, null] +4782 - null - [null, null, null, null, null] +4783 - null - [null, null, null, null, null] +4784 - null - [null, null, null, null, null] +4785 - null - [null, null, null, null, null] +4786 - Potted plant - [null, null, null, null, null] +4787 - Bamboo Gate - [Open, null, null, null, null] +4788 - Bamboo Gate - [Open, null, null, null, null] +4789 - null - [null, null, null, null, null] +4790 - null - [null, null, null, null, null] +4791 - Bamboo Bed - [null, null, null, null, null] +4792 - Bamboo Bed - [null, null, null, null, null] +4793 - Bamboo Bed - [null, null, null, null, null] +4794 - Pot - [null, null, null, null, null] +4795 - Pots - [null, null, null, null, null] +4796 - null - [null, null, null, null, null] +4797 - Bamboo Desk - [null, null, null, null, null] +4798 - Bamboo Bookcase - [null, Search, null, null, null] +4799 - Jail Door - [Pick-lock, null, null, null, null] +4800 - Jail Door - [Pick-lock, null, null, null, null] +4801 - null - [null, null, null, null, null] +4802 - null - [null, null, null, null, null] +4803 - null - [null, null, null, null, null] +4804 - null - [null, null, null, null, null] +4805 - null - [null, null, null, null, null] +4806 - null - [null, null, null, null, null] +4807 - Bamboo Door - [Open, null, null, null, null] +4808 - null - [null, null, null, null, null] +4809 - null - [null, null, null, null, null] +4810 - null - [null, null, null, null, null] +4811 - null - [null, null, null, null, null] +4812 - Jungle Grass - [null, null, null, null, null] +4813 - Jungle Grass - [null, null, null, null, null] +4814 - Jungle Grass - [null, null, null, null, null] +4815 - Long grass - [null, null, null, null, null] +4816 - Jungle Tree - [null, null, null, null, null] +4817 - Jungle Palm - [null, null, null, null, null] +4818 - Jungle Tree - [Chop-down, null, hidden, null, null] +4819 - Jungle Tree Stump - [null, null, null, null, null] +4820 - Jungle Tree - [Chop-down, null, hidden, null, null] +4821 - Jungle Tree Stump - [null, null, null, null, null] +4822 - Tree stump - [null, null, null, null, null] +4823 - Jungle Flower - [null, null, null, null, null] +4824 - Orchid - [null, null, null, null, null] +4825 - Jungle Plant - [null, null, null, null, null] +4826 - Whipping Plant - [null, null, null, null, null] +4827 - Pineapple Plant - [Pick, null, null, null, null] +4828 - Jungle Plant - [null, null, null, null, null] +4829 - Jungle Plant - [null, null, null, null, null] +4830 - Jungle Plant - [null, null, null, null, null] +4831 - Jungle Plant - [null, null, null, null, null] +4832 - Creeping Plant - [null, null, null, null, null] +4833 - Jungle Bush - [null, null, null, null, null] +4834 - Jungle Bush - [null, null, null, null, null] +4835 - Slashed Bush - [null, null, null, null, null] +4836 - null - [null, null, null, null, null] +4837 - null - [null, null, null, null, null] +4838 - null - [null, null, null, null, null] +4839 - null - [null, null, null, null, null] +4840 - null - [null, null, null, null, null] +4841 - null - [null, null, null, null, null] +4842 - null - [null, null, null, null, null] +4843 - null - [null, null, null, null, null] +4844 - null - [null, null, null, null, null] +4845 - Tropical tree - [null, null, null, null, null] +4846 - Tropical tree - [null, null, null, null, null] +4847 - Tropical tree - [null, null, null, null, null] +4848 - Tropical Leaves - [null, null, null, null, null] +4849 - Tropical tree - [null, null, null, null, null] +4850 - Tropical tree - [null, null, null, null, null] +4851 - Tropical tree - [null, null, null, null, null] +4852 - Hollow Log - [null, null, null, null, null] +4853 - Roots - [null, null, null, null, null] +4854 - Roots - [null, null, null, null, null] +4855 - Roots - [null, null, null, null, null] +4856 - Glowing Fungus - [null, null, null, null, null] +4857 - Glowing Fungus - [null, null, null, null, null] +4858 - Gorilla Statue - [null, null, null, null, null] +4859 - Gorilla Statue - [Pray-at, null, null, null, null] +4860 - Gorilla Statue - [null, null, null, null, null] +4861 - Monkey Statue - [null, null, null, null, null] +4862 - Glowing Fungus - [null, null, null, null, null] +4863 - Watchtower Legs - [null, null, null, null, null] +4864 - Watchtower Legs - [null, null, null, null, null] +4865 - Watchtower Middle - [null, null, null, null, null] +4866 - Gnome Glider - [null, null, null, null, null] +4867 - Gnome Glider - [null, null, null, null, null] +4868 - Teleportation Device - [Operate, null, null, null, null] +4869 - Teleportation Device - [Operate, null, null, null, null] +4870 - Teleportation Device - [Operate, null, null, null, null] +4871 - Reinitialisation Panel - [Operate, null, null, null, null] +4872 - Exit Sign - [null, null, null, null, null] +4873 - Lever - [null, null, null, null, null] +4874 - Crafting Stall - [null, Steal from, null, null, null] +4875 - Food Stall - [null, Steal from, null, null, null] +4876 - General Stall - [null, Steal from, null, null, null] +4877 - Magic Stall - [null, Steal from, null, null, null] +4878 - Scimitar Stall - [null, Steal from, null, null, null] +4879 - Trapdoor - [Open, null, null, null, null] +4880 - Trapdoor - [Climb-down, Close, null, null, null] +4881 - Climbing rope - [Climb, null, null, null, null] +4882 - Slight indentations - [null, null, null, null, null] +4883 - A rock - [Search, null, null, null, null] +4884 - Plank - [null, null, null, null, null] +4885 - Stalagmites - [null, null, null, null, null] +4886 - Floor spikes - [null, null, null, null, null] +4887 - A rock - [Search, null, null, null, null] +4888 - Trapdoor - [Open, null, null, null, null] +4889 - Climbing rope - [Climb, null, null, null, null] +4890 - null - [null, null, null, null, null] +4891 - null - [null, null, null, null, null] +4892 - null - [null, null, null, null, null] +4893 - null - [null, null, null, null, null] +4894 - null - [null, null, null, null, null] +4895 - null - [null, null, null, null, null] +4896 - null - [null, null, null, null, null] +4897 - null - [null, null, null, null, null] +4898 - null - [null, null, null, null, null] +4899 - null - [null, null, null, null, null] +4900 - Saradomin Standard - [Take, null, null, null, null] +4901 - Zamorak Standard - [Take, null, null, null, null] +4902 - Saradomin Standard - [Capture, null, null, null, null] +4903 - Zamorak Standard - [Capture, null, null, null, null] +4904 - Catapult - [null, null, null, null, null] +4905 - Catapult - [null, null, null, null, null] +4906 - null - [null, null, null, null, null] +4907 - null - [null, null, null, null, null] +4908 - null - [null, null, null, null, null] +4909 - null - [null, null, null, null, null] +4910 - Barrel - [null, null, null, null, null] +4911 - Ladder - [Climb-down, null, null, null, null] +4912 - Ladder - [Climb-down, null, null, null, null] +4913 - Cart tunnel - [Crawl-down, null, null, null, null] +4914 - Cart tunnel - [Crawl-down, null, null, null, null] +4915 - Cart tunnel - [Crawl-down, null, null, null, null] +4916 - null - [null, null, null, null, null] +4917 - null - [null, null, null, null, null] +4918 - Mine cart - [Climb-over, null, null, null, null] +4919 - Stairs - [Walk-down, null, null, null, null] +4920 - Cart tunnel - [Crawl-through, null, null, null, null] +4921 - Cart tunnel - [Crawl-through, null, null, null, null] +4922 - Cart tunnel - [Crawl-through, null, null, null, null] +4923 - Stairs - [Walk-up, null, null, null, null] +4924 - Water Valve - [Turn, null, null, null, null] +4925 - null - [null, null, null, null, null] +4926 - Crystal outcrop - [Cut, null, null, null, null] +4927 - Crystal outcrop - [Cut, null, null, null, null] +4928 - Crystal outcrop - [Cut, null, null, null, null] +4929 - Dark tunnel - [null, null, null, null, null] +4930 - Mine cart - [null, null, null, null, null] +4931 - null - [null, null, null, null, null] +4932 - Glowing fungus - [Pick, null, null, null, null] +4933 - Glowing fungus - [Pick, null, null, null, null] +4934 - null - [null, null, null, null, null] +4935 - Ceiling support - [null, null, null, null, null] +4936 - Wall support - [null, null, null, null, null] +4937 - Lift - [Go-down, null, null, null, null] +4938 - Lift - [Go-down, null, null, null, null] +4939 - null - [null, null, null, null, null] +4940 - Lift - [Go-down, null, null, null, null] +4941 - null - [null, null, null, null, null] +4942 - Lift - [Go-up, null, null, null, null] +4943 - null - [null, null, null, null, null] +4944 - Crate - [null, null, null, null, null] +4945 - Mine cart - [null, null, null, null, null] +4946 - null - [null, null, null, null, null] +4947 - null - [null, null, null, null, null] +4948 - null - [null, null, null, null, null] +4949 - Points settings - [Check, null, null, null, null] +4950 - Lever - [Pull, null, null, null, null] +4951 - Lever - [Pull, null, null, null, null] +4952 - Lever - [Pull, null, null, null, null] +4953 - Lever - [Pull, null, null, null, null] +4954 - Lever - [Pull, null, null, null, null] +4955 - Lever - [Pull, null, null, null, null] +4956 - Lever - [Pull, null, null, null, null] +4957 - Lever - [Pull, null, null, null, null] +4958 - Lever - [null, null, null, null, null] +4959 - Lever - [null, null, null, null, null] +4960 - Lever - [null, null, null, null, null] +4961 - Lever - [null, null, null, null, null] +4962 - Door - [Open, null, null, null, null] +4963 - Large door - [Open, null, null, null, null] +4964 - Large door - [Open, null, null, null, null] +4965 - Ladder - [Climb-down, null, null, null, null] +4966 - Ladder - [Climb-up, null, null, null, null] +4967 - Ladder - [Climb-down, null, null, null, null] +4968 - Ladder - [Climb-up, null, null, null, null] +4969 - Ladder - [Climb-down, null, null, null, null] +4970 - Ladder - [Climb-up, null, null, null, null] +4971 - Stairs - [Walk-down, null, null, null, null] +4972 - Stairs - [Walk-up, null, null, null, null] +4973 - Stairs - [Walk-up, null, null, null, null] +4974 - Mine cart - [Search, null, null, null, null] +4975 - Crate - [Search, null, null, null, null] +4976 - Mineral vein - [Mine, Prospect, null, null, null] +4977 - Mineral vein - [Mine, Prospect, null, null, null] +4978 - Mineral vein - [Mine, Prospect, null, null, null] +4979 - Mineral vein - [Mine, Prospect, null, null, null] +4980 - Mineral vein - [Mine, Prospect, null, null, null] +4981 - Mineral vein - [Mine, Prospect, null, null, null] +4982 - Mineral vein - [Mine, Prospect, null, null, null] +4983 - Mineral vein - [Mine, Prospect, null, null, null] +4984 - Mineral vein - [Mine, Prospect, null, null, null] +4985 - Mineral vein - [Mine, Prospect, null, null, null] +4986 - Mineral vein - [Mine, Prospect, null, null, null] +4987 - Mineral vein - [Mine, Prospect, null, null, null] +4988 - Mineral vein - [Mine, Prospect, null, null, null] +4989 - Mineral vein - [Mine, Prospect, null, null, null] +4990 - Mineral vein - [Mine, Prospect, null, null, null] +4991 - Mineral vein - [Mine, Prospect, null, null, null] +4992 - Mineral vein - [Mine, Prospect, null, null, null] +4993 - Mineral vein - [Mine, Prospect, null, null, null] +4994 - Mineral vein - [Mine, Prospect, null, null, null] +4995 - Mineral vein - [Mine, Prospect, null, null, null] +4996 - Mineral vein - [Mine, Prospect, null, null, null] +4997 - null - [null, null, null, null, null] +4998 - null - [null, null, null, null, null] +4999 - null - [null, null, null, null, null] +5000 - null - [null, null, null, null, null] +5001 - Wooden boards - [null, null, null, null, null] +5002 - Rope bridge - [Walk-here, null, null, null, Repair] +5003 - Broken rope bridge - [Repair, null, null, null, null] +5004 - Tree - [null, null, null, null, null] +5005 - Tree - [Climb up, Climb down, null, null, null] +5006 - Rare Flowers - [null, Pick, null, null, null] +5007 - Cave entrance - [Enter, null, null, null, null] +5008 - Tunnel - [Enter, null, null, null, null] +5009 - Tunnel - [Enter, null, null, null, null] +5010 - Tunnel - [Enter, null, null, null, null] +5011 - Tunnel - [Enter, null, null, null, null] +5012 - Tunnel - [Enter, null, null, null, null] +5013 - Tunnel - [Enter, null, null, null, null] +5014 - Tunnel - [Enter, null, null, null, null] +5015 - slope - [Slide, null, null, null, null] +5016 - slope - [Slide, null, null, null, null] +5017 - null - [null, null, null, null, null] +5018 - null - [null, null, null, null, null] +5019 - null - [null, null, null, null, null] +5020 - null - [null, null, null, null, null] +5021 - null - [null, null, null, null, null] +5022 - null - [null, null, null, null, null] +5023 - null - [null, null, null, null, null] +5024 - null - [null, null, null, null, null] +5025 - Crevasse - [Enter, null, null, null, null] +5026 - null - [null, null, null, null, null] +5027 - null - [null, null, null, null, null] +5028 - null - [null, null, null, null, null] +5029 - null - [null, null, null, null, null] +5030 - null - [null, null, null, null, null] +5031 - null - [null, null, null, null, null] +5032 - null - [null, null, null, null, null] +5033 - null - [null, null, null, null, null] +5034 - null - [null, null, null, null, null] +5035 - null - [null, null, null, null, null] +5036 - null - [null, null, hidden, null, null] +5037 - Ice covered boulder - [null, null, null, null, null] +5038 - Ice covered boulder - [null, null, null, null, null] +5039 - Ice covered boulder - [null, null, null, null, null] +5040 - null - [null, null, null, null, null] +5041 - null - [null, null, null, null, null] +5042 - null - [null, null, null, null, null] +5043 - Ice gate - [Go-through, null, null, null, null] +5044 - Ice gate - [Go-through, null, null, null, null] +5045 - Tree - [null, null, null, null, null] +5046 - Cave entrance - [Enter, null, null, null, null] +5047 - Stalagmites - [null, null, null, null, null] +5048 - Stalactite - [null, null, null, null, null] +5049 - Stalagmite - [null, null, null, null, null] +5050 - Stalagmite - [Look, Squeeze-past, null, null, null] +5051 - Swamp Boaty - [null, null, null, null, null] +5052 - Wall - [Search, null, null, null, null] +5053 - null - [null, null, null, null, null] +5054 - Ladder - [Climb-up, null, null, null, null] +5055 - Trapdoor - [Open, null, null, null, null] +5056 - Wooden doors - [Open, null, null, null, null] +5057 - Wooden doors - [Open, null, null, null, null] +5058 - Wooden doors - [Walk-through, null, null, null, null] +5059 - Wooden doors - [Walk-through, null, null, null, null] +5060 - null - [null, null, null, null, null] +5061 - null - [null, null, null, null, null] +5062 - null - [null, null, null, null, null] +5063 - null - [null, null, null, null, null] +5064 - null - [null, null, null, null, null] +5065 - null - [null, null, null, null, null] +5066 - null - [null, null, null, null, null] +5067 - null - [null, null, null, null, null] +5068 - null - [null, null, null, null, null] +5069 - null - [null, null, null, null, null] +5070 - null - [null, null, null, null, null] +5071 - null - [null, null, null, null, null] +5072 - Pillar - [null, null, null, null, null] +5073 - null - [null, null, null, null, null] +5074 - null - [null, null, null, null, null] +5075 - null - [null, null, null, null, null] +5076 - null - [null, null, null, null, null] +5077 - null - [null, null, null, null, null] +5078 - null - [null, null, null, null, null] +5079 - null - [null, null, null, null, null] +5080 - null - [null, null, null, null, null] +5081 - null - [null, null, null, null, null] +5082 - Dungeon entrance - [Enter, null, null, null, null] +5083 - Dungeon entrance - [Enter, null, null, null, null] +5084 - Exit - [Leave, null, null, null, null] +5085 - null - [null, null, null, null, null] +5086 - null - [null, null, null, null, null] +5087 - null - [null, null, null, null, null] +5088 - Log balance - [Walk-across, null, null, null, null] +5089 - null - [null, null, null, null, null] +5090 - Log balance - [Walk-across, null, null, null, null] +5091 - null - [null, null, null, null, null] +5092 - null - [null, null, null, null, null] +5093 - null - [null, null, null, null, null] +5094 - Stairs - [Walk-up, null, null, null, null] +5095 - Stairs - [null, null, null, null, null] +5096 - Stairs - [Walk-down, null, null, null, null] +5097 - Stairs - [Walk-up, null, null, null, null] +5098 - Stairs - [Walk-down, null, null, null, null] +5099 - Pipe - [Squeeze-through, null, null, null, null] +5100 - Pipe - [Squeeze-through, null, null, null, null] +5101 - null - [null, null, null, null, null] +5102 - null - [null, null, null, null, null] +5103 - Vines - [Chop-down, null, hidden, null, null] +5104 - Vines - [Chop-down, null, hidden, null, null] +5105 - Vines - [Chop-down, null, hidden, null, null] +5106 - Vines - [Chop-down, null, hidden, null, null] +5107 - Vines - [Chop-down, null, hidden, null, null] +5108 - null - [null, null, null, null, null] +5109 - null - [null, null, null, null, null] +5110 - Stepping stone - [Jump-from, null, null, null, null] +5111 - Stepping stone - [Jump-from, null, null, null, null] +5112 - Mushroom - [null, null, null, null, null] +5113 - Fungus - [null, null, null, null, null] +5114 - Fungus - [null, null, null, null, null] +5115 - Fungus - [null, null, null, null, null] +5116 - Statue - [null, null, null, null, null] +5117 - Statue - [null, null, null, null, null] +5118 - null - [null, null, null, null, null] +5119 - null - [null, null, null, null, null] +5120 - null - [null, null, null, null, null] +5121 - null - [null, null, null, null, null] +5122 - Corpse - [null, null, null, null, null] +5123 - Corpse - [null, null, null, null, null] +5124 - Corpse - [null, null, null, null, null] +5125 - Corpse - [null, null, null, null, null] +5126 - Door - [Open, null, null, null, null] +5127 - Danger sign - [Read, null, null, null, null] +5128 - Door - [Close, null, null, null, null] +5129 - null - [null, null, null, null, null] +5130 - Ladder - [Climb-up, null, null, null, null] +5131 - Trapdoor - [Open, null, null, null, null] +5132 - Trapdoor - [Climb-down, Close, null, null, null] +5133 - Hurdle - [Jump, null, null, null, null] +5134 - Hurdle - [Jump, null, null, null, null] +5135 - Hurdle - [Jump, null, null, null, null] +5136 - Skull slope - [Climb-up, null, null, null, null] +5137 - null - [null, null, null, null, null] +5138 - Stepping stone - [Jump-to, null, null, null, null] +5139 - Zip line - [Teeth-grip, null, null, null, null] +5140 - Zip line - [Teeth-grip, null, null, null, null] +5141 - Zip line - [Teeth-grip, null, null, null, null] +5142 - Zip line - [null, null, null, null, null] +5143 - Zip line - [null, null, null, null, null] +5144 - Zip line - [null, null, null, null, null] +5145 - Zip line - [null, null, null, null, null] +5146 - Goal - [null, null, null, null, null] +5147 - Goal - [null, null, null, null, null] +5148 - Goal - [null, null, null, null, null] +5149 - null - [null, null, null, null, null] +5150 - null - [null, null, null, null, null] +5151 - null - [null, null, null, null, null] +5152 - Pipe - [Squeeze-through, null, null, null, null] +5153 - null - [null, null, null, null, null] +5154 - null - [null, null, null, null, null] +5155 - null - [null, null, null, null, null] +5156 - Cupboard - [Open, null, null, null, null] +5157 - Open Cupboard - [null, Search, Shut, null, null] +5158 - Pile of canes - [Take-from, null, null, null, null] +5159 - Bridge - [Cross, null, null, null, null] +5160 - Bridge - [Cross, null, null, null, null] +5161 - Clock - [Wind, null, null, null, null] +5162 - Chest - [Open, null, null, null, null] +5163 - Chest - [Search, Close, null, null, null] +5164 - Signpost - [Read, null, null, null, null] +5165 - Fireplace - [null, null, null, null, null] +5166 - Bookcase - [Search, null, null, null, null] +5167 - Memorial - [Push, Search, null, null, null] +5168 - Grave - [Read, Dig, null, null, null] +5169 - Grave - [Read, Dig, null, null, null] +5170 - Entrance - [Open, null, null, null, null] +5171 - null - [null, null, null, null, null] +5172 - Door - [Open, null, null, null, null] +5173 - null - [null, null, null, null, null] +5174 - Door - [Open, null, null, null, null] +5175 - null - [null, null, null, null, null] +5176 - Lightning conductor - [Repair, null, null, null, null] +5177 - Lightning conductor - [null, null, null, null, null] +5178 - Fireplace surround - [null, null, null, null, null] +5179 - Fireplace surround - [null, null, null, null, null] +5180 - null - [null, null, null, null, null] +5181 - null - [null, null, null, null, null] +5182 - null - [null, null, null, null, null] +5183 - Door - [Open, null, null, null, null] +5184 - null - [Open, null, null, null, null] +5185 - null - [Open, null, null, null, null] +5186 - Door - [Open, null, null, null, null] +5187 - Door - [Close, null, null, null, null] +5188 - Door - [Close, null, null, null, null] +5189 - null - [null, null, null, null, null] +5190 - null - [null, null, null, null, null] +5191 - null - [null, null, null, null, null] +5192 - null - [null, null, null, null, null] +5193 - null - [null, null, null, null, null] +5194 - null - [null, null, null, null, null] +5195 - null - [null, null, null, null, null] +5196 - null - [null, null, null, null, null] +5197 - null - [null, null, null, null, null] +5198 - null - [null, null, null, null, null] +5199 - null - [null, null, null, null, null] +5200 - null - [null, null, null, null, null] +5201 - null - [null, null, null, null, null] +5202 - Pile of bricks - [null, null, null, null, null] +5203 - null - [null, null, null, null, null] +5204 - null - [null, null, null, null, null] +5205 - null - [null, null, null, null, null] +5206 - Staircase - [Climb-up, null, null, null, null] +5207 - Staircase - [Climb-down, null, null, null, null] +5208 - null - [null, null, null, null, null] +5209 - null - [null, null, null, null, null] +5210 - null - [null, null, null, null, null] +5211 - null - [null, null, null, null, null] +5212 - null - [null, null, null, null, null] +5213 - null - [null, null, null, null, null] +5214 - null - [null, null, null, null, null] +5215 - null - [null, null, null, null, null] +5216 - null - [null, null, null, null, null] +5217 - null - [null, null, null, null, null] +5218 - null - [null, null, null, null, null] +5219 - null - [null, null, null, null, null] +5220 - null - [null, null, null, null, null] +5221 - null - [null, null, null, null, null] +5222 - null - [null, null, null, null, null] +5223 - null - [null, null, null, null, null] +5224 - null - [null, null, null, null, null] +5225 - null - [null, null, null, null, null] +5226 - null - [null, null, null, null, null] +5227 - null - [null, null, null, null, null] +5228 - Column - [null, null, null, null, null] +5229 - Column - [null, null, null, null, null] +5230 - Column - [null, null, null, null, null] +5231 - Stalagmite - [null, null, null, null, null] +5232 - Stalagmite - [null, null, null, null, null] +5233 - null - [null, null, null, null, null] +5234 - null - [null, null, null, null, null] +5235 - null - [null, null, null, null, null] +5236 - null - [null, null, null, null, null] +5237 - null - [null, null, null, null, null] +5238 - null - [null, null, null, null, null] +5239 - null - [null, null, null, null, null] +5240 - null - [null, null, null, null, null] +5241 - null - [null, null, null, null, null] +5242 - null - [null, null, null, null, null] +5243 - null - [null, null, null, null, null] +5244 - Door - [Open, null, null, null, null] +5245 - Door - [Close, null, null, null, null] +5246 - Bed - [null, null, null, null, null] +5247 - null - [null, null, null, null, null] +5248 - Crystal growth - [null, null, null, null, null] +5249 - Fire - [null, null, null, null, null] +5250 - Ladder - [Climb-down, null, null, null, null] +5251 - Ladder - [Climb-up, null, null, null, null] +5252 - Fire remains - [Search, null, null, null, null] +5253 - Nettles - [Pick, null, null, null, null] +5254 - Nettles - [Pick, null, null, null, null] +5255 - Nettles - [Pick, null, null, null, null] +5256 - Nettles - [Pick, null, null, null, null] +5257 - Nettles - [Pick, null, null, null, null] +5258 - Nettles - [Pick, null, null, null, null] +5259 - Energy Barrier - [Pass, null, null, Pay-toll(2-Ecto), null] +5260 - null - [null, null, null, null, null] +5261 - null - [null, null, null, null, null] +5262 - Stairs - [Climb-up, null, null, null, null] +5263 - Stairs - [Climb-down, null, null, null, null] +5264 - Ladder - [Climb-up, null, null, null, null] +5265 - Ship's ladder - [Climb-up, null, null, null, null] +5266 - Ship's ladder - [Climb-down, null, null, null, null] +5267 - Trapdoor - [Open, null, null, null, null] +5268 - Trapdoor - [Climb-down, Close, null, null, null] +5269 - Rock - [Jump-To, null, null, null, null] +5270 - Closed chest - [Open, null, null, null, null] +5271 - Open chest - [null, null, null, null, null] +5272 - Closed chest - [Open, null, null, null, null] +5273 - Open chest - [Search, Close, null, null, null] +5274 - Mast - [Search, null, null, null, null] +5275 - Cooking range - [null, null, null, null, null] +5276 - Bank booth - [Use, Use-quickly, Collect, null, null] +5277 - Closed bank booth - [null, null, null, null, null] +5278 - Coffin - [Open, null, null, null, null] +5279 - Coffin - [Search, Close, null, null, null] +5280 - Staircase - [Climb-up, null, null, null, null] +5281 - Staircase - [Climb-down, null, null, null, null] +5282 - Ectofuntus - [Worship, null, null, null, null] +5283 - Ectofuntus - [null, null, null, null, null] +5284 - Bone grinder - [Wind, Empty, Status, null, null] +5285 - Gangplank - [Cross, null, null, null, null] +5286 - Gangplank - [Cross, null, null, null, null] +5287 - Pirate Captain - [Talk-To, null, null, null, null] +5288 - null - [null, null, null, null, null] +5289 - null - [null, null, null, null, null] +5290 - null - [null, null, null, null, null] +5291 - null - [null, null, null, null, null] +5292 - null - [null, null, null, null, null] +5293 - null - [null, null, null, null, null] +5294 - null - [null, null, null, null, null] +5295 - null - [null, null, null, null, null] +5296 - null - [null, null, null, null, null] +5297 - null - [null, null, null, null, null] +5298 - null - [null, null, null, null, null] +5299 - null - [null, null, null, null, null] +5300 - null - [null, null, null, null, null] +5301 - null - [null, null, null, null, null] +5302 - null - [null, null, null, null, null] +5303 - null - [null, null, null, null, null] +5304 - null - [null, null, null, null, null] +5305 - null - [null, null, null, null, null] +5306 - Boat - [null, null, null, null, null] +5307 - null - [null, null, null, null, null] +5308 - null - [null, null, null, null, null] +5309 - null - [null, null, null, null, null] +5310 - null - [null, null, null, null, null] +5311 - null - [null, null, null, null, null] +5312 - null - [null, null, null, null, null] +5313 - null - [null, null, null, null, null] +5314 - null - [null, null, null, null, null] +5315 - null - [null, null, null, null, null] +5316 - null - [null, null, null, null, null] +5317 - null - [null, null, null, null, null] +5318 - null - [null, null, null, null, null] +5319 - null - [null, null, null, null, null] +5320 - null - [null, null, null, null, null] +5321 - null - [null, null, null, null, null] +5322 - null - [null, null, null, null, null] +5323 - null - [null, null, null, null, null] +5324 - null - [null, null, null, null, null] +5325 - null - [null, null, null, null, null] +5326 - null - [null, null, null, null, null] +5327 - null - [null, null, null, null, null] +5328 - null - [null, null, null, null, null] +5329 - null - [null, null, null, null, null] +5330 - Boxes - [Search, null, null, null, null] +5331 - Plant - [null, null, null, null, null] +5332 - Plant - [null, null, null, null, null] +5333 - Plant - [null, null, null, null, null] +5334 - Plant - [null, null, null, null, null] +5335 - null - [null, null, null, null, null] +5336 - null - [null, null, null, null, null] +5337 - null - [null, null, null, null, null] +5338 - null - [null, null, null, null, null] +5339 - null - [null, null, null, null, null] +5340 - null - [null, null, null, null, null] +5341 - null - [null, null, null, null, null] +5342 - null - [null, null, null, null, null] +5343 - null - [null, null, null, null, null] +5344 - null - [null, null, null, null, null] +5345 - Chair - [null, null, null, null, null] +5346 - Chair - [null, null, null, null, null] +5347 - Chair - [null, null, null, null, null] +5348 - Smashed chair - [null, null, null, null, null] +5349 - Table - [null, null, null, null, null] +5350 - Bar pumps - [null, null, null, null, null] +5351 - Bar - [null, null, null, null, null] +5352 - Cart - [null, null, null, null, null] +5353 - Wheelbarrow - [null, null, null, null, null] +5354 - Trough - [null, null, null, null, null] +5355 - Crate - [null, null, null, null, null] +5356 - Crates - [null, null, null, null, null] +5357 - Crates - [null, null, null, null, null] +5358 - Skeleton - [null, null, null, null, null] +5359 - Skeleton - [null, null, null, null, null] +5360 - Skeleton - [null, null, null, null, null] +5361 - null - [null, null, null, null, null] +5362 - null - [null, null, null, null, null] +5363 - null - [null, null, null, null, null] +5364 - null - [null, null, null, null, null] +5365 - null - [null, null, null, null, null] +5366 - null - [null, null, null, null, null] +5367 - null - [null, null, null, null, null] +5368 - null - [null, null, null, null, null] +5369 - null - [null, null, null, null, null] +5370 - null - [null, null, null, null, null] +5371 - null - [null, null, null, null, null] +5372 - null - [null, null, null, null, null] +5373 - null - [null, null, null, null, null] +5374 - null - [null, null, null, null, null] +5375 - null - [null, null, null, null, null] +5376 - null - [null, null, null, null, null] +5377 - null - [null, null, null, null, null] +5378 - null - [null, null, null, null, null] +5379 - null - [null, null, null, null, null] +5380 - null - [null, null, null, null, null] +5381 - null - [null, null, null, null, null] +5382 - null - [null, null, null, null, null] +5383 - null - [null, null, null, null, null] +5384 - null - [null, null, null, null, null] +5385 - null - [null, null, null, null, null] +5386 - null - [null, null, null, null, null] +5387 - null - [null, null, null, null, null] +5388 - null - [null, null, null, null, null] +5389 - null - [null, null, null, null, null] +5390 - null - [null, null, null, null, null] +5391 - null - [null, null, null, null, null] +5392 - null - [null, null, null, null, null] +5393 - null - [null, null, null, null, null] +5394 - null - [null, null, null, null, null] +5395 - null - [null, null, null, null, null] +5396 - null - [null, null, null, null, null] +5397 - Figurehead - [null, null, null, null, null] +5398 - null - [null, null, null, null, null] +5399 - null - [null, null, null, null, null] +5400 - null - [null, null, null, null, null] +5401 - null - [null, null, null, null, null] +5402 - null - [null, null, null, null, null] +5403 - Ship's wheel - [null, null, null, null, null] +5404 - Mast - [null, null, null, null, null] +5405 - null - [null, null, null, null, null] +5406 - null - [null, null, null, null, null] +5407 - null - [null, null, null, null, null] +5408 - null - [null, null, null, null, null] +5409 - null - [null, null, null, null, null] +5410 - null - [null, null, null, null, null] +5411 - null - [null, null, null, null, null] +5412 - null - [null, null, null, null, null] +5413 - null - [null, null, null, null, null] +5414 - null - [null, null, null, null, null] +5415 - Ship's ladder - [Climb-up, null, null, null, null] +5416 - Ship's ladder - [Climb-down, null, null, null, null] +5417 - null - [null, null, null, null, null] +5418 - null - [null, null, null, null, null] +5419 - null - [null, null, null, null, null] +5420 - null - [null, null, null, null, null] +5421 - null - [null, null, null, null, null] +5422 - null - [null, null, null, null, null] +5423 - null - [null, null, null, null, null] +5424 - null - [null, null, null, null, null] +5425 - null - [null, null, null, null, null] +5426 - null - [null, null, null, null, null] +5427 - null - [null, null, null, null, null] +5428 - null - [null, null, null, null, null] +5429 - Captain's Table - [null, null, null, null, null] +5430 - Market stall - [null, null, null, null, null] +5431 - Market stall - [null, null, null, null, null] +5432 - null - [null, null, null, null, null] +5433 - null - [null, null, null, null, null] +5434 - null - [null, null, null, null, null] +5435 - null - [null, null, null, null, null] +5436 - null - [null, null, null, null, null] +5437 - null - [null, null, null, null, null] +5438 - null - [null, null, null, null, null] +5439 - Broken Door - [null, null, null, null, null] +5440 - null - [null, null, null, null, null] +5441 - null - [null, null, null, null, null] +5442 - null - [null, null, null, null, null] +5443 - null - [null, null, null, null, null] +5444 - null - [null, null, null, null, null] +5445 - null - [null, null, null, null, null] +5446 - null - [null, null, null, null, null] +5447 - null - [null, null, null, null, null] +5448 - null - [null, null, null, null, null] +5449 - null - [null, null, null, null, null] +5450 - null - [null, null, null, null, null] +5451 - null - [null, null, null, null, null] +5452 - null - [null, null, null, null, null] +5453 - Door - [Open, null, null, null, null] +5454 - Door - [Open, null, null, null, null] +5455 - null - [null, null, null, null, null] +5456 - null - [null, null, null, null, null] +5457 - null - [null, null, null, null, null] +5458 - null - [null, null, null, null, null] +5459 - null - [null, null, null, null, null] +5460 - null - [null, null, null, null, null] +5461 - null - [null, null, null, null, null] +5462 - null - [null, null, null, null, null] +5463 - null - [null, null, null, null, null] +5464 - null - [null, null, null, null, null] +5465 - null - [null, null, null, null, null] +5466 - null - [null, null, null, null, null] +5467 - null - [null, null, null, null, null] +5468 - null - [null, null, null, null, null] +5469 - null - [null, null, null, null, null] +5470 - null - [null, null, null, null, null] +5471 - null - [null, null, null, null, null] +5472 - null - [null, null, null, null, null] +5473 - null - [null, null, null, null, null] +5474 - null - [null, null, null, null, null] +5475 - null - [null, null, null, null, null] +5476 - null - [null, null, null, null, null] +5477 - null - [null, null, null, null, null] +5478 - null - [null, null, null, null, null] +5479 - null - [null, null, null, null, null] +5480 - null - [null, null, null, null, null] +5481 - null - [null, null, null, null, null] +5482 - null - [null, null, null, null, null] +5483 - null - [null, null, null, null, null] +5484 - null - [null, null, null, null, null] +5485 - null - [null, null, null, null, null] +5486 - null - [null, null, null, null, null] +5487 - null - [null, null, null, null, null] +5488 - Ladder - [Climb-up, null, null, null, null] +5489 - Jewellery stall - [null, null, null, null, null] +5490 - Trapdoor - [Open, null, null, hidden, Pick-Lock] +5491 - Trapdoor - [Climb-down, Close, null, null, null] +5492 - null - [null, null, null, null, null] +5493 - Ladder - [Climb-up, null, null, null, null] +5494 - Standing torch - [null, null, null, null, null] +5495 - Bed - [null, null, null, null, null] +5496 - null - [null, null, null, null, null] +5497 - Bed - [null, null, null, null, null] +5498 - Bed - [null, null, null, null, null] +5499 - Fire - [null, null, null, null, null] +5500 - null - [null, null, null, null, null] +5501 - Door - [Open, null, null, null, Pick-lock] +5502 - null - [null, null, null, null, null] +5503 - null - [null, null, null, null, null] +5504 - null - [null, null, null, null, null] +5505 - null - [null, null, null, null, null] +5506 - null - [null, null, null, null, null] +5507 - null - [null, null, null, null, null] +5508 - Lectern - [null, null, null, null, null] +5509 - null - [null, null, null, null, null] +5510 - null - [null, null, null, null, null] +5511 - null - [null, null, null, null, null] +5512 - null - [null, null, null, null, null] +5513 - null - [null, null, null, null, null] +5514 - null - [null, null, null, null, null] +5515 - null - [null, null, null, null, null] +5516 - null - [null, null, null, null, null] +5517 - null - [null, null, null, null, null] +5518 - null - [null, null, null, null, null] +5519 - null - [null, null, null, null, null] +5520 - null - [null, null, null, null, null] +5521 - null - [null, null, null, null, null] +5522 - null - [null, null, null, null, null] +5523 - null - [null, null, null, null, null] +5524 - null - [null, null, null, null, null] +5525 - null - [null, null, null, null, null] +5526 - null - [null, null, null, null, null] +5527 - null - [null, null, null, null, null] +5528 - null - [null, null, null, null, null] +5529 - null - [null, null, null, null, null] +5530 - null - [null, null, null, null, null] +5531 - null - [null, null, null, null, null] +5532 - null - [null, null, null, null, null] +5533 - null - [null, null, null, null, null] +5534 - null - [null, null, null, null, null] +5535 - null - [null, null, null, null, null] +5536 - null - [null, null, null, null, null] +5537 - null - [null, null, null, null, null] +5538 - Onion - [null, Pick, null, null, null] +5539 - Bullrushes - [null, null, null, null, null] +5540 - Bullrushes - [null, null, null, null, null] +5541 - Bullrushes - [null, null, null, null, null] +5542 - Bullrushes - [null, null, null, null, null] +5543 - Heather - [null, null, null, null, null] +5544 - Heather - [null, null, null, null, null] +5545 - Heather - [null, null, null, null, null] +5546 - Heather - [null, null, null, null, null] +5547 - Heather - [null, null, null, null, null] +5548 - Heather - [null, null, null, null, null] +5549 - Heather - [null, null, null, null, null] +5550 - Dock leaf plant - [null, null, null, null, null] +5551 - Willow - [Chop down, null, hidden, null, null] +5552 - Willow - [Chop down, null, hidden, null, null] +5553 - Willow - [Chop down, null, hidden, null, null] +5554 - Tree Stump - [null, null, hidden, null, null] +5555 - Hanging tapestry - [null, null, null, null, null] +5556 - Hanging tapestry - [null, null, null, null, null] +5557 - null - [null, null, null, null, null] +5558 - Aggie's Cauldron - [null, null, null, null, null] +5559 - Charms - [null, null, null, null, null] +5560 - Mirror - [null, null, null, null, null] +5561 - Broom - [null, null, null, null, null] +5562 - Cloth - [null, null, null, null, null] +5563 - null - [null, null, null, null, null] +5564 - Bed - [null, null, null, null, null] +5565 - Bed - [null, null, null, null, null] +5566 - null - [null, null, null, null, null] +5567 - null - [null, null, null, null, null] +5568 - null - [null, null, null, null, null] +5569 - Dry stone wall - [null, null, null, null, null] +5570 - null - [null, null, null, null, null] +5571 - Coop - [null, null, null, null, null] +5572 - Coop - [null, null, null, null, null] +5573 - Coop - [null, null, null, null, null] +5574 - Sack - [null, null, null, null, null] +5575 - Trough - [null, null, null, null, null] +5576 - Trough - [null, null, null, null, null] +5577 - Trough - [null, null, null, null, null] +5578 - Cart - [null, null, null, null, null] +5579 - Cart - [null, null, null, null, null] +5580 - Wheelbarrow - [null, null, null, null, null] +5581 - Logs - [Take-axe, null, null, null, null] +5582 - Logs - [null, null, null, null, null] +5583 - Wheat - [null, Pick, null, null, null] +5584 - Wheat - [null, Pick, null, null, null] +5585 - Wheat - [null, Pick, null, null, null] +5586 - null - [null, null, null, null, null] +5587 - null - [null, null, null, null, null] +5588 - null - [null, null, null, null, null] +5589 - Water wheel - [null, null, null, null, null] +5590 - Water wheel - [null, null, null, null, null] +5591 - Water wheel - [null, null, null, null, null] +5592 - null - [null, null, null, null, null] +5593 - null - [null, null, null, null, null] +5594 - Water wheel - [null, null, null, null, null] +5595 - Toy Stall - [null, null, null, null, null] +5596 - Market stall - [null, null, null, null, null] +5597 - Weather vane - [null, null, null, null, null] +5598 - Water Barrel - [null, null, null, null, null] +5599 - Water Barrel - [null, null, null, null, null] +5600 - null - [null, null, null, null, null] +5601 - null - [null, null, null, null, null] +5602 - null - [null, null, null, null, null] +5603 - null - [null, null, null, null, null] +5604 - Rock - [null, null, null, null, null] +5605 - Rock - [null, null, null, null, null] +5606 - Rock - [null, null, null, null, null] +5607 - null - [null, null, null, null, null] +5608 - Spit roast - [null, null, null, null, null] +5609 - Cooking Pots - [null, null, null, null, null] +5610 - Cooking Pots - [null, null, null, null, null] +5611 - null - [null, null, null, null, null] +5612 - null - [null, null, null, null, null] +5613 - Rat-hole - [null, null, null, null, null] +5614 - Chair - [null, null, null, null, null] +5615 - Bench - [null, null, null, null, null] +5616 - Signpost - [null, null, null, null, null] +5617 - null - [null, null, null, null, null] +5618 - Drawers - [Open, null, null, null, null] +5619 - Drawers - [null, Search, Shut, null, null] +5620 - null - [null, null, null, null, null] +5621 - Big vase - [null, null, null, null, null] +5622 - Wardrobe - [Open, null, null, null, null] +5623 - Wardrobe - [null, Search, Close, null, null] +5624 - Wardrobe - [null, Search, Close, null, null] +5625 - Ned's Table - [null, null, null, null, null] +5626 - null - [null, null, null, null, null] +5627 - Standard - [null, null, null, null, null] +5628 - Standard - [null, null, null, null, null] +5629 - Standard - [null, null, null, null, null] +5630 - null - [null, null, null, null, null] +5631 - Fire - [null, null, null, null, null] +5632 - Fire - [null, null, null, null, null] +5633 - null - [null, null, null, null, null] +5634 - null - [null, null, null, null, null] +5635 - null - [null, null, null, null, null] +5636 - null - [null, null, null, null, null] +5637 - null - [null, null, null, null, null] +5638 - null - [null, null, null, null, null] +5639 - null - [null, null, null, null, null] +5640 - null - [null, null, null, null, null] +5641 - null - [null, null, null, null, null] +5642 - null - [null, null, null, null, null] +5643 - null - [null, null, null, null, null] +5644 - null - [null, null, null, null, null] +5645 - null - [null, null, null, null, null] +5646 - null - [null, null, null, null, null] +5647 - null - [null, null, null, null, null] +5648 - null - [null, null, null, null, null] +5649 - null - [null, null, null, null, null] +5650 - null - [null, null, null, null, null] +5651 - null - [null, null, null, null, null] +5652 - null - [null, null, null, null, null] +5653 - null - [null, null, null, null, null] +5654 - null - [null, null, null, null, null] +5655 - null - [null, null, null, null, null] +5656 - null - [null, null, null, null, null] +5657 - null - [null, null, null, null, null] +5658 - null - [null, null, null, null, null] +5659 - null - [null, null, null, null, null] +5660 - null - [null, null, null, null, null] +5661 - null - [null, null, null, null, null] +5662 - null - [null, null, null, null, null] +5663 - null - [null, null, null, null, null] +5664 - null - [null, null, null, null, null] +5665 - null - [null, null, null, null, null] +5666 - null - [null, null, null, null, null] +5667 - Large door - [Open, null, null, null, null] +5668 - null - [null, null, null, null, null] +5669 - null - [null, null, null, null, null] +5670 - null - [null, null, null, null, null] +5671 - null - [null, null, null, null, null] +5672 - null - [null, null, null, null, null] +5673 - null - [null, null, null, null, null] +5674 - null - [null, null, null, null, null] +5675 - null - [null, null, null, null, null] +5676 - null - [null, null, null, null, null] +5677 - null - [null, null, null, null, null] +5678 - null - [null, null, null, null, null] +5679 - null - [null, null, null, null, null] +5680 - null - [null, null, null, null, null] +5681 - null - [null, null, null, null, null] +5682 - null - [null, null, null, null, null] +5683 - null - [null, null, null, null, null] +5684 - null - [null, null, null, null, null] +5685 - null - [null, null, null, null, null] +5686 - null - [null, null, null, null, null] +5687 - null - [null, null, null, null, null] +5688 - null - [null, null, null, null, null] +5689 - null - [null, null, null, null, null] +5690 - null - [null, null, null, null, null] +5691 - null - [null, null, null, null, null] +5692 - null - [null, null, null, null, null] +5693 - null - [null, null, null, null, null] +5694 - null - [null, null, null, null, null] +5695 - null - [null, null, null, null, null] +5696 - null - [null, null, null, null, null] +5697 - null - [null, null, null, null, null] +5698 - null - [null, null, null, null, null] +5699 - null - [null, null, null, null, null] +5700 - null - [null, null, null, null, null] +5701 - null - [null, null, null, null, null] +5702 - null - [null, null, null, null, null] +5703 - null - [null, null, null, null, null] +5704 - null - [null, null, null, null, null] +5705 - null - [null, null, null, null, null] +5706 - null - [null, null, null, null, null] +5707 - null - [null, null, null, null, null] +5708 - null - [null, null, null, null, null] +5709 - null - [null, null, null, null, null] +5710 - null - [null, null, null, null, null] +5711 - null - [null, null, null, null, null] +5712 - null - [null, null, null, null, null] +5713 - null - [null, null, null, null, null] +5714 - null - [null, null, null, null, null] +5715 - null - [null, null, null, null, null] +5716 - null - [null, null, null, null, null] +5717 - null - [null, null, null, null, null] +5718 - null - [null, null, null, null, null] +5719 - null - [null, null, null, null, null] +5720 - null - [null, null, null, null, null] +5721 - null - [null, null, null, null, null] +5722 - null - [null, null, null, null, null] +5723 - null - [null, null, null, null, null] +5724 - null - [null, null, null, null, null] +5725 - null - [null, null, null, null, null] +5726 - null - [null, null, null, null, null] +5727 - null - [null, null, null, null, null] +5728 - null - [null, null, null, null, null] +5729 - null - [null, null, null, null, null] +5730 - null - [null, null, null, null, null] +5731 - null - [null, null, null, null, null] +5732 - null - [null, null, null, null, null] +5733 - null - [null, null, null, null, null] +5734 - null - [null, null, null, null, null] +5735 - null - [null, null, null, null, null] +5736 - null - [null, null, null, null, null] +5737 - null - [null, null, null, null, null] +5738 - null - [null, null, null, null, null] +5739 - null - [null, null, null, null, null] +5740 - null - [null, null, null, null, null] +5741 - null - [null, null, null, null, null] +5742 - null - [null, null, null, null, null] +5743 - null - [null, null, null, null, null] +5744 - null - [null, null, null, null, null] +5745 - null - [null, null, null, null, null] +5746 - null - [null, null, null, null, null] +5747 - null - [null, null, null, null, null] +5748 - null - [null, null, null, null, null] +5749 - null - [null, null, null, null, null] +5750 - null - [null, null, null, null, null] +5751 - null - [null, null, null, null, null] +5752 - null - [null, null, null, null, null] +5753 - null - [null, null, null, null, null] +5754 - null - [null, null, null, null, null] +5755 - null - [null, null, null, null, null] +5756 - null - [null, null, null, null, null] +5757 - null - [null, null, null, null, null] +5758 - null - [null, null, null, null, null] +5759 - null - [null, null, null, null, null] +5760 - null - [null, null, null, null, null] +5761 - null - [null, null, null, null, null] +5762 - null - [null, null, null, null, null] +5763 - null - [null, null, null, null, null] +5764 - null - [null, null, null, null, null] +5765 - null - [null, null, null, null, null] +5766 - null - [null, null, null, null, null] +5767 - null - [null, null, null, null, null] +5768 - null - [null, null, null, null, null] +5769 - null - [null, null, null, null, null] +5770 - null - [null, null, null, null, null] +5771 - null - [null, null, null, null, null] +5772 - null - [null, null, null, null, null] +5773 - null - [null, null, null, null, null] +5774 - null - [null, null, null, null, null] +5775 - null - [null, null, null, null, null] +5776 - null - [null, null, null, null, null] +5777 - null - [null, null, null, null, null] +5778 - null - [null, null, null, null, null] +5779 - null - [null, null, null, null, null] +5780 - null - [null, null, null, null, null] +5781 - null - [null, null, null, null, null] +5782 - null - [null, null, null, null, null] +5783 - null - [null, null, null, null, null] +5784 - null - [null, null, null, null, null] +5785 - null - [null, null, null, null, null] +5786 - null - [null, null, null, null, null] +5787 - null - [null, null, null, null, null] +5788 - Church pew - [null, null, null, null, null] +5789 - Statue - [null, null, null, null, null] +5790 - Statue - [null, null, null, null, null] +5791 - Statue - [null, null, null, null, null] +5792 - Flour bin - [null, null, null, null, null] +5793 - Crack - [Enter, null, null, null, null] +5794 - Crack - [Enter, null, null, null, null] +5795 - Crack - [Enter, null, null, null, null] +5796 - Crack - [Enter, null, null, null, null] +5797 - Crack - [Enter, null, null, null, null] +5798 - Crack - [Enter, null, null, null, null] +5799 - Trapdoor - [Open, null, null, null, null] +5800 - Trapdoor - [Open, null, null, null, null] +5801 - Trapdoor - [Open, null, null, null, null] +5802 - Trapdoor - [Open, null, null, null, null] +5803 - Trapdoor - [Open, null, null, null, null] +5804 - Trapdoor - [Open, null, null, null, null] +5805 - Trapdoor - [Open, null, null, null, null] +5806 - Trapdoor - [Open, null, null, null, null] +5807 - null - [null, null, null, null, null] +5808 - Sculpture - [Look, null, null, null, Search] +5809 - Weathervane - [Look, null, null, null, Search] +5810 - Seers weathervane - [null, null, null, null, null] +5811 - null - [null, null, null, null, null] +5812 - null - [null, null, null, null, null] +5813 - Ladder - [Climb-down, null, null, null, null] +5814 - Landing light - [null, null, null, null, null] +5815 - Gnome landing light - [Look, null, null, null, Search] +5816 - Flashing landing light - [Look, null, null, null, null] +5817 - Flashing landing light - [Look, null, null, null, null] +5818 - Flashing landing light - [Look, null, null, null, null] +5819 - Flashing landing light - [Look, null, null, null, null] +5820 - null - [null, null, null, null, null] +5821 - null - [null, null, null, null, null] +5822 - null - [null, null, null, null, null] +5823 - null - [null, null, null, null, null] +5824 - null - [null, null, null, null, null] +5825 - Gnome glider - [null, null, null, null, null] +5826 - Swordshop Sign - [null, null, null, null, null] +5827 - null - [null, null, null, null, null] +5828 - null - [null, null, null, null, null] +5829 - null - [null, null, null, null, null] +5830 - null - [null, null, null, null, null] +5831 - Antiques Shop Stall - [Ring-bell, null, null, null, null] +5832 - null - [null, null, null, null, null] +5833 - null - [null, null, null, null, null] +5834 - null - [null, null, null, null, null] +5835 - null - [null, null, null, null, null] +5836 - null - [null, null, null, null, null] +5837 - null - [null, null, null, null, null] +5838 - null - [null, null, null, null, null] +5839 - null - [null, null, null, null, null] +5840 - null - [null, null, null, null, null] +5841 - null - [null, null, null, null, null] +5842 - Boulder - [null, null, Push, null, null] +5843 - Boulder - [null, null, null, null, null] +5844 - Rock - [null, null, null, null, null] +5845 - Rock - [null, null, null, null, null] +5846 - Rope - [null, null, null, null, null] +5847 - Rockslide - [Climb-over, null, null, null, null] +5848 - Tall tree - [null, null, Climb, null, null] +5849 - Clump of rocks - [Jump-across, null, null, null, null] +5850 - Flat stone - [Jump-across, null, null, null, null] +5851 - Flat stone - [Jump-across, null, null, null, null] +5852 - Flat stone - [null, null, null, null, null] +5853 - Flat stone - [null, null, null, null, null] +5854 - Flat stone - [null, null, null, null, null] +5855 - Shining pool - [null, null, Listen-to, null, null] +5856 - Thorny bushes - [null, null, Pick-from, null, null] +5857 - Cave entrance - [Enter, null, null, null, null] +5858 - Cave exit - [Exit, null, null, null, null] +5859 - Cave exit - [Exit, null, null, null, null] +5860 - Standing spears - [null, null, null, null, null] +5861 - null - [null, null, null, null, null] +5862 - Burial mound - [null, null, null, null, null] +5863 - Burial cairn - [null, null, null, null, null] +5864 - null - [null, null, null, null, null] +5865 - null - [null, null, null, null, null] +5866 - null - [null, null, null, null, null] +5867 - null - [null, null, null, null, null] +5868 - null - [null, null, null, null, null] +5869 - null - [null, null, null, null, null] +5870 - null - [null, null, null, null, null] +5871 - null - [null, null, null, null, null] +5872 - null - [null, null, null, null, null] +5873 - null - [null, null, null, null, null] +5874 - null - [null, null, null, null, null] +5875 - null - [null, null, null, null, null] +5876 - null - [null, null, null, null, null] +5877 - null - [null, null, null, null, null] +5878 - Wooden Table - [null, null, null, null, null] +5879 - Table - [null, null, null, null, null] +5880 - Stool - [null, null, null, null, null] +5881 - Standing torch - [null, null, null, null, null] +5882 - null - [null, null, null, null, null] +5883 - Mud - [Dig-up, null, null, null, null] +5884 - Swamp - [null, null, null, null, null] +5885 - Roots - [Dig-below, null, null, null, null] +5886 - Roots - [Dig-below, null, null, null, null] +5887 - Tent door - [Open, null, null, null, null] +5888 - Tent door - [Close, null, null, null, null] +5889 - Tent door - [Open, null, null, null, null] +5890 - Tent door - [Close, null, null, null, null] +5891 - Tent door - [Go-through, null, null, null, null] +5892 - null - [null, null, null, null, null] +5893 - Tent door - [Go-through, null, null, null, null] +5894 - null - [null, null, null, null, null] +5895 - Ancient Rock - [null, null, null, null, null] +5896 - Ancient Rock - [null, null, null, null, null] +5897 - Shining pool - [Listen-to, null, null, null, null] +5898 - null - [null, null, null, null, null] +5899 - null - [null, null, null, null, null] +5900 - null - [null, null, null, null, null] +5901 - null - [null, null, null, null, null] +5902 - Dead tree - [Chop down, null, hidden, null, null] +5903 - Dead tree - [Chop down, null, hidden, null, null] +5904 - Dead tree - [Chop down, null, hidden, null, null] +5905 - Tree stump - [Step-over, null, null, null, null] +5906 - null - [null, null, null, null, null] +5907 - null - [null, null, null, null, null] +5908 - null - [null, null, null, null, null] +5909 - Lamp oil still - [null, null, null, null, null] +5910 - Lamp oil still - [null, null, null, null, null] +5911 - null - [null, null, null, null, null] +5912 - null - [null, null, null, null, null] +5913 - null - [null, null, null, null, null] +5914 - null - [null, null, null, null, null] +5915 - null - [null, null, null, null, null] +5916 - null - [null, null, null, null, null] +5917 - Gas hole - [null, null, null, null, null] +5918 - Gas hole - [null, null, null, null, null] +5919 - null - [null, null, null, null, null] +5920 - null - [null, null, null, null, null] +5921 - null - [null, null, null, null, null] +5922 - null - [null, null, null, null, null] +5923 - null - [null, null, null, null, null] +5924 - null - [null, null, null, null, null] +5925 - null - [null, null, null, null, null] +5926 - null - [null, null, null, null, null] +5927 - null - [null, null, null, null, null] +5928 - null - [null, null, null, null, null] +5929 - null - [null, null, null, null, null] +5930 - null - [null, null, null, null, null] +5931 - null - [null, null, null, null, null] +5932 - null - [null, null, null, null, null] +5933 - null - [null, null, null, null, null] +5934 - null - [null, null, null, null, null] +5935 - null - [null, null, null, null, null] +5936 - null - [null, null, null, null, null] +5937 - null - [null, null, null, null, null] +5938 - null - [null, null, null, null, null] +5939 - null - [null, null, null, null, null] +5940 - null - [null, null, null, null, null] +5941 - null - [null, null, null, null, null] +5942 - null - [null, null, null, null, null] +5943 - null - [null, null, null, null, null] +5944 - null - [null, null, null, null, null] +5945 - null - [null, null, null, null, null] +5946 - Climbing rope - [Climb, null, null, null, null] +5947 - Dark hole - [Climb-down, null, null, null, null] +5948 - Stepping stone - [Jump-across, null, null, null, null] +5949 - Stepping stone - [Jump-across, null, null, null, null] +5950 - null - [null, null, null, null, null] +5951 - null - [null, null, null, null, null] +5952 - null - [null, null, null, null, null] +5953 - null - [null, null, null, null, null] +5954 - null - [null, null, null, null, null] +5955 - null - [null, null, null, null, null] +5956 - null - [null, null, null, null, null] +5957 - null - [null, null, null, null, null] +5958 - null - [null, null, null, null, null] +5959 - Lever - [Pull, null, null, null, null] +5960 - Lever - [Pull, null, null, null, null] +5961 - null - [null, null, null, null, null] +5962 - null - [null, null, null, null, null] +5963 - null - [null, null, null, null, null] +5964 - Cannonball - [null, null, null, null, null] +5965 - Gold cannonball - [null, null, null, null, null] +5966 - Passage - [null, null, null, null, null] +5967 - Cannonballs - [null, null, null, null, null] +5968 - Cannonballs - [null, null, null, null, null] +5969 - Cannonballs - [null, null, null, null, null] +5970 - Cannonballs - [null, null, null, null, null] +5971 - Cannonballs - [null, null, null, null, null] +5972 - Cannonballs - [null, null, null, null, null] +5973 - Cave entrance - [Go-through, null, null, null, null] +5974 - null - [null, null, null, null, null] +5975 - Dwarf MultiCannon - [Fire, null, null, null, null] +5976 - Dwarf MultiCannon - [null, null, null, null, null] +5977 - Wall of flame - [Jump-through, null, null, null, null] +5978 - Wall of flame - [Jump-through, null, null, null, null] +5979 - Wall of flame - [Jump-through, Talk-to, null, null, null] +5980 - Wall of flame - [Jump-through, Talk-to, null, null, null] +5981 - Fire - [null, null, null, null, null] +5982 - null - [null, null, null, null, null] +5983 - null - [null, null, null, null, null] +5984 - null - [null, null, null, null, null] +5985 - Rock - [null, null, null, null, null] +5986 - Small rock - [null, null, null, null, null] +5987 - Rock - [null, null, null, null, null] +5988 - null - [null, null, null, null, null] +5989 - Mineral vein - [Mine, Prospect, null, null, null] +5990 - Mineral vein - [Mine, Prospect, null, null, null] +5991 - Mineral vein - [Mine, Prospect, null, null, null] +5992 - null - [null, null, null, null, null] +5993 - null - [null, null, null, null, null] +5994 - null - [null, null, null, null, null] +5995 - null - [null, null, null, null, null] +5996 - null - [null, null, null, null, null] +5997 - null - [null, null, null, null, null] +5998 - Entrance - [Go-through, null, null, null, null] +5999 - null - [null, null, null, null, null] +6000 - null - [null, null, null, null, null] +6001 - null - [null, null, null, null, null] +6002 - null - [null, null, null, null, null] +6003 - null - [null, null, null, null, null] +6004 - null - [null, null, null, null, null] +6005 - null - [null, null, null, null, null] +6006 - null - [null, null, null, null, null] +6007 - null - [null, null, null, null, null] +6008 - null - [null, null, null, null, null] +6009 - Blue Fire - [null, null, null, null, null] +6010 - null - [null, null, null, null, null] +6011 - null - [null, null, null, null, null] +6012 - null - [null, null, null, null, null] +6013 - null - [null, null, null, null, null] +6014 - null - [null, null, null, null, null] +6015 - null - [null, null, null, null, null] +6016 - null - [null, null, null, null, null] +6017 - null - [null, null, null, null, null] +6018 - null - [null, null, null, null, null] +6019 - null - [null, null, null, null, null] +6020 - null - [null, null, null, null, null] +6021 - null - [null, null, null, null, null] +6022 - null - [null, null, null, null, null] +6023 - null - [null, null, null, null, null] +6024 - null - [null, null, null, null, null] +6025 - null - [null, null, null, null, null] +6026 - null - [null, null, null, null, null] +6027 - null - [null, null, null, null, null] +6028 - null - [null, null, null, null, null] +6029 - null - [null, null, null, null, null] +6030 - null - [null, null, null, null, null] +6031 - null - [null, null, null, null, null] +6032 - Boiler - [null, null, null, null, null] +6033 - Boiler - [null, null, null, null, null] +6034 - null - [null, null, null, null, null] +6035 - null - [null, null, null, null, null] +6036 - Ship's ladder - [null, null, null, null, null] +6037 - Ship's ladder - [null, null, null, null, null] +6038 - Ship's wheel - [null, null, null, null, null] +6039 - null - [null, null, null, null, null] +6040 - null - [null, null, null, null, null] +6041 - null - [null, null, null, null, null] +6042 - null - [null, null, null, null, null] +6043 - Boiler - [null, null, null, null, null] +6044 - Boiler - [null, null, null, null, null] +6045 - Mine cart - [Search, null, null, null, null] +6046 - null - [null, null, null, null, null] +6047 - null - [null, null, null, null, null] +6048 - null - [null, null, null, null, null] +6049 - null - [null, null, null, null, null] +6050 - null - [null, null, null, null, null] +6051 - null - [null, null, null, null, null] +6052 - null - [null, null, null, null, null] +6053 - null - [null, null, null, null, null] +6054 - null - [null, null, null, null, null] +6055 - null - [null, null, null, null, null] +6056 - null - [null, null, null, null, null] +6057 - null - [null, null, null, null, null] +6058 - null - [null, null, null, null, null] +6059 - null - [null, null, null, null, null] +6060 - null - [null, null, null, null, null] +6061 - null - [null, null, null, null, null] +6062 - null - [null, null, null, null, null] +6063 - null - [null, null, null, null, null] +6064 - Hat stand - [null, null, null, null, null] +6065 - Clothes - [null, null, null, null, null] +6066 - Weapon Rack - [null, null, null, null, null] +6067 - Weapon Rack - [null, null, null, null, null] +6068 - Weapon Rack - [null, null, null, null, null] +6069 - Weapon Rack - [null, null, null, null, null] +6070 - Cabinet - [null, null, null, null, null] +6071 - Cabinet - [null, null, null, null, null] +6072 - Cabinet - [null, null, null, null, null] +6073 - Cabinet - [null, null, null, null, null] +6074 - Cabinet - [null, null, null, null, null] +6075 - Table - [null, null, null, null, null] +6076 - Desk - [null, null, null, null, null] +6077 - Desk - [null, null, null, null, null] +6078 - Desk - [null, null, null, null, null] +6079 - Desk - [null, null, null, null, null] +6080 - Spinning Machine - [null, null, null, null, null] +6081 - Bank table - [null, null, null, null, null] +6082 - Bank table - [null, null, null, null, null] +6083 - Closed bank booth - [null, null, null, null, null] +6084 - Bank booth - [Use, Use-quickly, Collect, null, null] +6085 - Stairs - [Climb-up, null, null, null, null] +6086 - Stairs - [Climb-down, null, null, null, null] +6087 - Stairs - [Climb-up, null, null, null, null] +6088 - Stairs - [Climb-down, null, null, null, null] +6089 - Stairs - [Climb-up, null, null, null, null] +6090 - Stairs - [Climb-down, null, null, null, null] +6091 - Bookcase - [Search, null, null, null, null] +6092 - Bookcase - [Climb, null, null, null, null] +6093 - Fireplace - [null, null, null, null, null] +6094 - Fireplace - [null, null, null, null, null] +6095 - Fireplace - [null, null, null, null, null] +6096 - Fireplace - [null, null, null, null, null] +6097 - Well - [null, null, null, null, null] +6098 - null - [null, null, null, null, null] +6099 - null - [null, null, null, null, null] +6100 - Door - [Open, null, null, null, null] +6101 - Door - [Close, null, null, null, null] +6102 - Door - [Open, null, null, null, null] +6103 - Door - [Close, null, null, null, null] +6104 - Door - [Open, null, null, null, null] +6105 - Door - [Close, null, null, null, null] +6106 - Door - [Open, null, null, null, null] +6107 - Door - [Close, null, null, null, null] +6108 - Door - [Open, null, null, null, null] +6109 - Door - [Close, null, null, null, null] +6110 - Door - [Open, null, null, null, null] +6111 - Door - [Close, null, null, null, null] +6112 - Door - [Open, null, null, null, null] +6113 - Door - [Close, null, null, null, null] +6114 - Door - [Open, null, null, null, null] +6115 - Door - [Close, null, null, null, null] +6116 - null - [null, null, null, null, null] +6117 - null - [null, null, null, null, null] +6118 - null - [null, null, null, null, null] +6119 - null - [null, null, null, null, null] +6120 - null - [null, null, null, null, null] +6121 - null - [null, null, null, null, null] +6122 - null - [null, null, null, null, null] +6123 - null - [null, null, null, null, null] +6124 - null - [null, null, null, null, null] +6125 - null - [null, null, null, null, null] +6126 - null - [null, null, null, null, null] +6127 - null - [null, null, null, null, null] +6128 - null - [null, null, null, null, null] +6129 - null - [null, null, null, null, null] +6130 - null - [null, null, null, null, null] +6131 - null - [null, null, null, null, null] +6132 - null - [null, null, null, null, null] +6133 - null - [null, null, null, null, null] +6134 - null - [null, null, null, null, null] +6135 - null - [null, null, null, null, null] +6136 - null - [null, null, null, null, null] +6137 - null - [null, null, null, null, null] +6138 - null - [null, null, null, null, null] +6139 - null - [null, null, null, null, null] +6140 - null - [null, null, null, null, null] +6141 - null - [null, null, null, null, null] +6142 - null - [null, null, null, null, null] +6143 - null - [null, null, null, null, null] +6144 - null - [null, null, null, null, null] +6145 - null - [null, null, null, null, null] +6146 - Bird cage stand - [null, null, null, null, null] +6147 - Column - [null, null, null, null, null] +6148 - Column - [null, null, null, null, null] +6149 - Column - [null, null, null, null, null] +6150 - Anvil - [null, null, null, null, null] +6151 - Sink - [null, null, null, null, null] +6152 - Bar - [null, null, null, null, null] +6153 - Bar - [null, null, null, null, null] +6154 - Shelves - [null, null, null, null, null] +6155 - Shelves - [null, null, null, null, null] +6156 - Shelves - [null, null, null, null, null] +6157 - Shelves - [null, null, null, null, null] +6158 - Red fungi - [null, null, null, null, null] +6159 - Red fungi - [null, null, null, null, null] +6160 - Red fungi - [null, null, null, null, null] +6161 - Red fungi - [null, null, null, null, null] +6162 - Gem Stall - [null, Steal-from, null, null, null] +6163 - Bakery stall - [null, Steal-from, null, null, null] +6164 - Silver stall - [null, Steal-from, null, null, null] +6165 - Clothes stall - [null, Steal-from, null, null, null] +6166 - Crafting stall - [null, Steal-from, null, null, null] +6167 - null - [null, null, null, null, null] +6168 - null - [null, null, null, null, null] +6169 - null - [null, null, null, null, null] +6170 - null - [null, null, null, null, null] +6171 - null - [null, null, null, null, null] +6172 - null - [null, null, null, null, null] +6173 - Giant Dwarf - [null, null, null, null, null] +6174 - Giant Dwarf - [null, null, null, null, null] +6175 - Giant Dwarf - [null, null, null, null, null] +6176 - Boxes - [Search, null, null, null, null] +6177 - Crate - [null, null, null, null, null] +6178 - Crates - [null, null, null, null, null] +6179 - Cooking Pots - [null, null, null, null, null] +6180 - Cooking Pots - [null, null, null, null, null] +6181 - Hanging meat - [null, null, null, null, null] +6182 - Hanging meat - [null, null, null, null, null] +6183 - Bed - [null, null, null, null, null] +6184 - Bed - [null, null, null, null, null] +6185 - Armour - [null, null, null, null, null] +6186 - Armour - [null, null, null, null, null] +6187 - Armour - [null, null, null, null, null] +6188 - Blacksmith's tools - [null, null, null, null, null] +6189 - Furnace - [null, Smelt, null, null, null] +6190 - Catapult - [null, null, null, null, null] +6191 - Warhammer - [null, null, null, null, null] +6192 - Pickaxe - [null, null, null, null, null] +6193 - Dwarf mirror - [null, null, null, null, null] +6194 - Chair - [null, null, null, null, null] +6195 - Chair - [null, null, null, null, null] +6196 - Table - [null, null, null, null, null] +6197 - Table - [null, null, null, null, null] +6198 - Table - [null, null, null, null, null] +6199 - Table - [null, null, null, null, null] +6200 - Table - [null, null, null, null, null] +6201 - Table - [null, null, null, null, null] +6202 - Lamp - [null, null, null, null, null] +6203 - Lamp - [null, null, null, null, null] +6204 - Poor Bed - [null, null, null, null, null] +6205 - Bed - [null, null, null, null, null] +6206 - Dwarven Consortium Table - [null, null, null, null, null] +6207 - Throne - [null, null, null, null, null] +6208 - Throne - [null, null, null, null, null] +6209 - null - [null, null, null, null, null] +6210 - null - [null, null, null, null, null] +6211 - Table - [null, null, null, null, null] +6212 - Tree stump - [null, null, null, null, null] +6213 - Barrel - [null, null, null, null, null] +6214 - null - [null, null, null, null, null] +6215 - null - [null, null, null, null, null] +6216 - null - [null, null, null, null, null] +6217 - null - [null, null, null, null, null] +6218 - null - [null, null, null, null, null] +6219 - null - [null, null, null, null, null] +6220 - null - [null, null, null, null, null] +6221 - null - [null, null, null, null, null] +6222 - null - [null, null, null, null, null] +6223 - null - [null, null, null, null, null] +6224 - null - [null, null, null, null, null] +6225 - null - [null, null, null, null, null] +6226 - null - [null, null, null, null, null] +6227 - null - [null, null, null, null, null] +6228 - null - [null, null, null, null, null] +6229 - null - [null, null, null, null, null] +6230 - Money Pot - [null, null, null, null, null] +6231 - Table - [null, null, null, null, null] +6232 - Fountain - [null, null, null, null, null] +6233 - null - [null, null, null, null, null] +6234 - null - [null, null, null, null, null] +6235 - null - [null, null, null, null, null] +6236 - Stop! - [null, null, null, null, null] +6237 - Plant - [null, null, null, null, null] +6238 - Door - [Open, null, null, null, null] +6239 - Door - [null, null, null, null, null] +6240 - Door - [Open, null, null, null, null] +6241 - Door - [null, null, null, null, null] +6242 - Staircase - [Climb-up, null, null, null, null] +6243 - Staircase - [Climb-down, null, null, null, null] +6244 - Staircase - [Climb-Up, null, null, null, null] +6245 - Staircase - [Climb-Down, null, null, null, null] +6246 - Table - [Take-beer, null, null, null, null] +6247 - null - [null, null, null, null, null] +6248 - null - [null, null, null, null, null] +6249 - Well - [null, null, null, null, null] +6250 - Bed - [null, null, null, null, null] +6251 - null - [null, null, null, null, null] +6252 - null - [null, null, null, null, null] +6253 - null - [null, null, null, null, null] +6254 - null - [null, null, null, null, null] +6255 - Trough - [null, null, null, null, null] +6256 - Trough - [null, null, null, null, null] +6257 - Dung - [Pick-up, null, null, null, null] +6258 - Dung - [Pick-up, null, null, null, null] +6259 - Dung - [Pick-up, null, null, null, null] +6260 - Ladder - [Climb-down, null, null, null, null] +6261 - Ladder - [Climb-up, null, null, null, null] +6262 - Ladder - [Climb, Climb-up, Climb-down, null, null] +6263 - Hutch - [null, null, null, null, null] +6264 - Bird cage stand - [null, null, null, null, null] +6265 - Cage - [null, null, null, null, null] +6266 - Cage - [null, null, null, null, null] +6267 - Golden cage - [null, null, null, null, null] +6268 - Hutch - [null, null, null, null, null] +6269 - Cages - [null, null, null, null, null] +6270 - null - [null, null, null, null, null] +6271 - null - [null, null, null, null, null] +6272 - null - [null, null, null, null, null] +6273 - null - [null, null, null, null, null] +6274 - Bed - [Search, null, null, null, null] +6275 - Study desk - [Search, null, null, null, null] +6276 - Landscape - [Search, null, null, null, null] +6277 - Cactus - [Hide-behind, null, null, null, null] +6278 - Trapdoor - [Open, null, null, null, null] +6279 - Smokey well - [Climb-down, null, null, null, null] +6280 - Ladder - [Climb-up, null, null, null, null] +6281 - Ladder - [Climb-up, null, null, null, null] +6282 - Portal - [Enter, null, null, null, null] +6283 - Pillar - [null, null, null, null, null] +6284 - Pillar - [null, null, null, null, null] +6285 - Pillar - [null, null, null, null, null] +6286 - Pillar - [null, null, null, null, null] +6287 - null - [null, null, null, null, null] +6288 - null - [null, null, null, null, null] +6289 - null - [null, null, null, null, null] +6290 - null - [null, null, null, null, null] +6291 - null - [null, null, null, null, null] +6292 - Bookcase - [Search, null, null, null, null] +6293 - null - [null, null, null, null, null] +6294 - Display case - [Open, null, null, null, null] +6295 - Display case - [null, null, null, null, null] +6296 - Skeleton - [null, null, null, null, null] +6297 - Skeleton - [null, null, null, null, null] +6298 - Skeleton - [null, null, null, null, null] +6299 - Skeleton - [null, null, null, null, null] +6300 - null - [null, null, null, null, null] +6301 - Throne - [null, null, null, null, null] +6302 - Throne - [null, null, null, null, null] +6303 - null - [null, null, null, null, null] +6304 - null - [null, null, null, null, null] +6305 - null - [null, null, null, null, null] +6306 - null - [null, null, null, null, null] +6307 - Statuette in alcove - [Turn, null, null, null, null] +6308 - Statuette in alcove - [Turn, null, null, null, null] +6309 - Alcove - [null, null, null, null, null] +6310 - null - [null, null, null, null, null] +6311 - Black mushrooms - [Pick, null, null, null, null] +6312 - Staircase - [Climb-up, null, null, null, null] +6313 - Staircase - [Climb-down, null, null, null, null] +6314 - null - [null, null, null, null, null] +6315 - null - [null, null, null, null, null] +6316 - null - [null, null, null, null, null] +6317 - null - [null, null, null, null, null] +6318 - null - [null, null, null, null, null] +6319 - null - [null, null, null, null, null] +6320 - null - [null, null, null, null, null] +6321 - null - [null, null, null, null, null] +6322 - null - [null, null, null, null, null] +6323 - Golem arm - [null, null, null, null, null] +6324 - Golem foot - [null, null, null, null, null] +6325 - Golem body - [null, null, null, null, null] +6326 - Golem head - [null, null, null, null, null] +6327 - Broken kiln - [null, null, null, null, null] +6328 - Broken kiln - [null, null, null, null, null] +6329 - Broken kiln - [null, null, null, null, null] +6330 - Broken kiln - [null, null, null, null, null] +6331 - Statue - [null, null, null, null, null] +6332 - Statue - [null, null, null, null, null] +6333 - Statue - [null, null, null, null, null] +6334 - Statue - [null, null, null, null, null] +6335 - Plinth - [null, null, null, null, null] +6336 - Plinth - [null, null, null, null, null] +6337 - Plinth - [null, null, null, null, null] +6338 - Plinth - [null, null, null, null, null] +6339 - null - [null, null, null, null, null] +6340 - null - [null, null, null, null, null] +6341 - null - [null, null, null, null, null] +6342 - null - [null, null, null, null, null] +6343 - null - [null, null, null, null, null] +6344 - null - [null, null, null, null, null] +6345 - null - [null, null, null, null, null] +6346 - null - [null, null, null, null, null] +6347 - null - [null, null, null, null, null] +6348 - null - [null, null, null, null, null] +6349 - null - [null, null, null, null, null] +6350 - null - [null, null, null, null, null] +6351 - null - [null, null, null, null, null] +6352 - null - [null, null, null, null, null] +6353 - null - [null, null, null, null, null] +6354 - null - [null, null, null, null, null] +6355 - null - [null, null, null, null, null] +6356 - null - [null, null, null, null, null] +6357 - null - [null, null, null, null, null] +6358 - null - [null, null, null, null, null] +6359 - null - [null, null, null, null, null] +6360 - null - [null, null, null, null, null] +6361 - null - [null, null, null, null, null] +6362 - null - [null, null, null, null, null] +6363 - Door - [Open, null, null, null, null] +6364 - Door - [Enter, null, null, null, null] +6365 - null - [null, null, null, null, null] +6366 - null - [null, null, null, null, null] +6367 - null - [null, null, null, null, null] +6368 - null - [null, null, null, null, null] +6369 - null - [null, null, null, null, null] +6370 - null - [null, null, null, null, null] +6371 - null - [null, null, null, null, null] +6372 - Staircase - [Climb-up, null, null, null, null] +6373 - Staircase - [Climb-down, null, null, null, null] +6374 - null - [null, null, null, null, null] +6375 - null - [null, null, null, null, null] +6376 - null - [null, null, null, null, null] +6377 - null - [null, null, null, null, null] +6378 - null - [null, null, null, null, null] +6379 - null - [null, null, null, null, null] +6380 - null - [null, null, null, null, null] +6381 - Cave - [null, null, null, null, null] +6382 - Root - [null, null, null, null, null] +6383 - null - [null, null, null, null, null] +6384 - null - [null, null, null, null, null] +6385 - null - [null, null, null, null, null] +6386 - null - [null, null, null, null, null] +6387 - null - [null, null, null, null, null] +6388 - null - [null, null, null, null, null] +6389 - null - [null, null, null, null, null] +6390 - null - [null, null, null, null, null] +6391 - null - [null, null, null, null, null] +6392 - null - [null, null, null, null, null] +6393 - null - [null, null, null, null, null] +6394 - null - [null, null, null, null, null] +6395 - null - [null, null, null, null, null] +6396 - null - [null, null, null, null, null] +6397 - null - [null, null, null, null, null] +6398 - null - [null, null, null, null, null] +6399 - null - [null, null, null, null, null] +6400 - null - [null, null, null, null, null] +6401 - null - [null, null, null, null, null] +6402 - Stalagmites - [null, null, null, null, null] +6403 - Stalagmite - [null, null, null, null, null] +6404 - Standing Torch - [null, null, null, null, null] +6405 - null - [null, null, null, null, null] +6406 - Standing Torch - [null, null, null, null, null] +6407 - null - [null, null, null, null, null] +6408 - Standing Torch - [null, null, null, null, null] +6409 - null - [null, null, null, null, null] +6410 - Standing Torch - [null, null, null, null, null] +6411 - null - [null, null, null, null, null] +6412 - Standing Torch - [null, null, null, null, null] +6413 - Standing Torch - [null, null, null, null, null] +6414 - Standing Torch - [null, null, null, null, null] +6415 - Standing Torch - [null, null, null, null, null] +6416 - Standing Torch - [null, null, null, null, null] +6417 - null - [null, null, null, null, null] +6418 - Ladder - [Climb-up, null, null, null, null] +6419 - Ladder - [Climb-up, null, null, null, null] +6420 - Burnt chest - [Open, null, null, null, null] +6421 - null - [null, null, null, null, null] +6422 - null - [null, null, null, null, null] +6423 - Mystical mirror - [Look-into, null, null, null, null] +6424 - null - [null, null, null, null, null] +6425 - Mystical mirror - [Look-into, null, null, null, null] +6426 - null - [null, null, null, null, null] +6427 - Mystical mirror - [Look-into, null, null, null, null] +6428 - null - [null, null, null, null, null] +6429 - Mystical mirror - [Look-into, null, null, null, null] +6430 - null - [null, null, null, null, null] +6431 - Mystical mirror - [Look-into, null, null, null, null] +6432 - null - [null, null, null, null, null] +6433 - Mystical mirror - [Look-into, null, null, null, null] +6434 - Trapdoor - [Open, null, null, null, null] +6435 - Trapdoor - [Climb-down, null, null, null, null] +6436 - Ladder - [Climb-up, null, null, null, null] +6437 - Vampire tomb - [null, null, null, null, null] +6438 - Vampire tomb - [null, null, null, null, null] +6439 - Rope - [Climb-up, null, null, null, null] +6440 - null - [Enter, null, null, null, null] +6441 - Cave entrance - [Enter, null, null, null, null] +6442 - Cave entrance - [Enter, null, null, null, null] +6443 - Cave entrance - [Enter, null, null, null, null] +6444 - Cave entrance - [Enter, null, null, null, null] +6445 - Cave entrance - [Enter, null, null, null, null] +6446 - Cave entrance - [Enter, null, null, null, null] +6447 - Cave exit - [Enter, null, null, null, null] +6448 - Secure chest - [Open, null, null, null, null] +6449 - null - [null, null, null, null, null] +6450 - Ladder - [Climb-up, null, null, null, null] +6451 - Gate - [Open, null, null, null, null] +6452 - Gate - [Open, null, null, null, null] +6453 - null - [null, null, null, null, null] +6454 - Icy rock - [null, null, null, null, null] +6455 - Ice ledge - [Use, null, null, null, null] +6456 - Ice ledge - [Step-off, null, null, null, null] +6457 - null - [null, null, null, null, null] +6458 - null - [null, null, null, null, null] +6459 - null - [null, null, null, null, null] +6460 - null - [null, null, null, null, null] +6461 - Ice gate - [Go-through, null, null, null, null] +6462 - Ice gate - [Go-through, null, null, null, null] +6463 - null - [null, null, null, null, null] +6464 - null - [null, null, null, null, null] +6465 - null - [null, null, null, null, null] +6466 - null - [null, null, null, null, null] +6467 - null - [null, null, null, null, null] +6468 - null - [null, null, null, null, null] +6469 - null - [null, null, null, null, null] +6470 - null - [null, null, null, null, null] +6471 - null - [null, null, null, null, null] +6472 - Ice chunks - [null, null, null, null, null] +6473 - Ice chunks - [null, null, null, null, null] +6474 - Ice chunks - [null, null, null, null, null] +6475 - Ice chunks - [null, null, null, null, null] +6476 - Ice chunks - [null, null, null, null, null] +6477 - Ice chunks - [null, null, null, null, null] +6478 - null - [null, null, null, null, null] +6479 - null - [null, null, null, null, null] +6480 - null - [null, null, null, null, null] +6481 - Tunnel - [Enter, null, null, null, null] +6482 - null - [null, null, null, null, null] +6483 - Obelisk - [null, null, null, null, null] +6484 - Obelisk - [null, null, null, null, null] +6485 - null - [null, null, null, null, null] +6486 - Obelisk - [null, null, null, null, null] +6487 - Obelisk - [null, null, null, null, null] +6488 - null - [null, null, null, null, null] +6489 - Obelisk - [null, null, null, null, null] +6490 - Obelisk - [null, null, null, null, null] +6491 - null - [null, null, null, null, null] +6492 - Obelisk - [null, null, null, null, null] +6493 - Obelisk - [null, null, null, null, null] +6494 - Mystical door - [Open, null, null, null, null] +6495 - null - [null, null, null, null, null] +6496 - null - [null, null, null, null, null] +6497 - Ladder - [Climb-down, null, null, null, null] +6498 - Ladder - [Climb-down, null, null, null, null] +6499 - Ladder - [Climb-down, null, null, null, null] +6500 - Ladder - [Climb-down, null, null, null, null] +6501 - Ladder - [Climb-up, null, null, null, null] +6502 - Ladder - [Climb-up, null, null, null, null] +6503 - Ladder - [Climb-up, null, null, null, null] +6504 - Ladder - [Climb-up, null, null, null, null] +6505 - null - [null, null, null, null, null] +6506 - null - [null, null, null, null, null] +6507 - null - [null, null, null, null, null] +6508 - null - [null, null, null, null, null] +6509 - null - [null, null, null, null, null] +6510 - null - [null, null, null, null, null] +6511 - null - [null, null, null, null, null] +6512 - Sarcophagus - [Search, null, null, null, null] +6513 - Sarcophagus - [Search, null, null, null, null] +6514 - Sarcophagus - [Search, null, null, null, null] +6515 - Sarcophagus - [Search, null, null, null, null] +6516 - Sarcophagus - [Search, null, null, null, null] +6517 - Sarcophagus - [Search, null, null, null, null] +6518 - null - [null, null, null, null, null] +6519 - null - [null, null, null, null, null] +6520 - null - [null, null, null, null, null] +6521 - Pitfall - [null, null, null, null, null] +6522 - null - [null, null, null, null, null] +6523 - Ladder - [null, null, Climb-down, null, null] +6524 - Crack - [null, null, null, null, null] +6525 - null - [null, null, null, null, null] +6526 - null - [null, null, null, null, null] +6527 - null - [null, null, null, null, null] +6528 - null - [null, null, null, null, null] +6529 - null - [null, null, null, null, null] +6530 - null - [null, null, null, null, null] +6531 - null - [null, null, null, null, null] +6532 - null - [null, null, null, null, null] +6533 - null - [null, null, null, null, null] +6534 - null - [null, null, null, null, null] +6535 - null - [null, null, null, null, null] +6536 - null - [null, null, null, null, null] +6537 - null - [null, null, null, null, null] +6538 - Sphinx - [null, null, null, null, null] +6539 - null - [null, null, null, null, null] +6540 - null - [null, null, null, null, null] +6541 - null - [null, null, null, null, null] +6542 - null - [null, null, null, null, null] +6543 - null - [null, null, null, null, null] +6544 - null - [null, null, null, null, null] +6545 - Pyramid entrance - [Open, null, null, null, null] +6546 - null - [null, null, null, null, null] +6547 - Pyramid entrance - [Open, null, null, null, null] +6548 - null - [null, null, null, null, null] +6549 - Well - [null, null, null, null, null] +6550 - null - [null, null, null, null, null] +6551 - Portal - [Use, null, null, null, null] +6552 - Altar - [Pray-at, null, null, null, null] +6553 - Doorway - [Open, null, null, null, null] +6554 - null - [null, null, null, null, null] +6555 - Doorway - [Open, null, null, null, null] +6556 - null - [null, null, null, null, null] +6557 - null - [null, null, null, null, null] +6558 - null - [null, null, null, null, null] +6559 - null - [null, null, null, null, null] +6560 - null - [null, null, null, null, null] +6561 - Ladder - [Climb-down, null, null, null, null] +6562 - null - [null, null, null, null, null] +6563 - null - [null, null, null, null, null] +6564 - null - [null, null, null, null, null] +6565 - null - [null, null, null, null, null] +6566 - City gate - [null, null, null, null, null] +6567 - null - [null, null, null, null, null] +6568 - Silk stall - [null, null, null, null, null] +6569 - Bakery stall - [null, null, null, null, null] +6570 - Gem stall - [null, null, null, null, null] +6571 - Fur stall - [null, null, null, null, null] +6572 - Spice stall - [Search, null, null, null, null] +6573 - Market stall - [null, null, null, null, null] +6574 - Tea stall - [null, Steal-from, null, null, null] +6575 - Cart - [null, null, null, null, null] +6576 - null - [null, null, null, null, null] +6577 - null - [null, null, null, null, null] +6578 - null - [null, null, null, null, null] +6579 - Banana Tree - [Search, null, null, null, null] +6580 - null - [null, null, null, null, null] +6581 - Tent flap - [Enter, null, null, null, null] +6582 - null - [null, null, null, null, null] +6583 - null - [null, null, null, null, null] +6584 - null - [null, null, null, null, null] +6585 - null - [null, null, null, null, null] +6586 - null - [null, null, null, null, null] +6587 - null - [null, null, null, null, null] +6588 - null - [Open, null, null, null, null] +6589 - null - [Open, null, null, null, null] +6590 - null - [null, null, null, null, null] +6591 - null - [null, null, null, null, null] +6592 - null - [null, null, null, null, null] +6593 - null - [null, null, null, null, null] +6594 - null - [null, null, null, null, null] +6595 - null - [null, null, null, null, null] +6596 - null - [null, null, null, null, null] +6597 - null - [null, null, null, null, null] +6598 - null - [null, null, null, null, null] +6599 - null - [null, null, null, null, null] +6600 - null - [null, null, null, null, null] +6601 - null - [null, null, null, null, null] +6602 - null - [null, null, null, null, null] +6603 - null - [null, null, null, null, null] +6604 - null - [null, null, null, null, null] +6605 - Water - [null, null, null, null, null] +6606 - Centre piece - [Search, null, null, null, null] +6607 - Mirror - [null, null, null, null, null] +6608 - Mirror - [null, null, null, null, null] +6609 - Mirror - [null, null, null, null, null] +6610 - Mirror - [null, null, null, null, null] +6611 - Mirror - [null, null, null, null, null] +6612 - Mirror - [null, null, null, null, null] +6613 - Mirror - [null, null, null, null, null] +6614 - Door - [Touch, null, Open, null, null] +6615 - City gate - [Open, null, null, null, null] +6616 - null - [null, null, null, null, null] +6617 - null - [null, null, null, null, null] +6618 - null - [null, null, null, null, null] +6619 - null - [null, null, null, null, null] +6620 - Hole - [Climb-through, null, null, null, null] +6621 - null - [null, null, null, null, null] +6622 - Rock - [null, null, null, null, null] +6623 - Rock - [Enter, null, null, null, null] +6624 - Door - [Open, null, null, null, null] +6625 - Door - [Open, null, null, null, null] +6626 - Door - [Close, null, null, null, null] +6627 - Door - [Close, null, null, null, null] +6628 - null - [null, null, null, null, null] +6629 - Wall Crusher - [null, null, null, null, null] +6630 - Sarcophagus - [Search, null, null, null, null] +6631 - null - [null, null, null, null, null] +6632 - Pit - [null, Jump-Across, null, null, null] +6633 - Pit - [null, null, null, null, null] +6634 - null - [null, null, null, null, null] +6635 - Canopic Jar - [Take, null, null, null, null] +6636 - null - [null, null, null, null, null] +6637 - Canopic Jar - [Take, null, null, null, null] +6638 - null - [null, null, null, null, null] +6639 - Canopic Jar - [Take, null, null, null, null] +6640 - null - [null, null, null, null, null] +6641 - Canopic Jar - [Take, null, null, null, null] +6642 - - [null, null, null, null, null] +6643 - Doorway - [Open, null, null, null, null] +6644 - Ceremonial table - [null, null, null, null, null] +6645 - Ladder - [Climb-up, null, null, null, null] +6646 - Closed chest - [Open, null, null, null, null] +6647 - Open chest - [null, Search, Shut, null, null] +6648 - Staircase - [Climb-up, null, null, null, null] +6649 - Staircase - [Climb-down, null, null, null, null] +6650 - Bridge - [null, null, null, null, null] +6651 - Bridge - [null, null, null, null, null] +6652 - Bridge - [null, null, null, null, null] +6653 - Bridge - [null, null, null, null, null] +6654 - null - [null, null, null, null, null] +6655 - Broken logs - [null, null, null, null, null] +6656 - Cloth - [null, null, null, null, null] +6657 - Juna - [Talk-to, null, null, null, null] +6658 - Tunnel - [Enter, null, null, null, null] +6659 - Tunnel - [Enter, null, null, null, null] +6660 - Weeping wall - [Collect-from, null, null, null, null] +6661 - Blue tears - [null, null, null, null, null] +6662 - Green tears - [null, null, null, null, null] +6663 - Absence of tears - [null, null, null, null, null] +6664 - null - [null, null, null, null, null] +6665 - Blue tears - [null, null, null, null, null] +6666 - Green tears - [null, null, null, null, null] +6667 - Absence of tears - [null, null, null, null, null] +6668 - null - [null, null, null, null, null] +6669 - Rocks - [Mine, Prospect, hidden, null, null] +6670 - Rocks - [Mine, Prospect, hidden, null, null] +6671 - Rocks - [Mine, Prospect, hidden, null, null] +6672 - Rocks - [Climb, null, null, null, null] +6673 - Rocks - [Climb, null, null, null, null] +6674 - null - [null, null, null, null, null] +6675 - null - [null, null, null, null, null] +6676 - null - [null, null, null, null, null] +6677 - null - [null, null, null, null, null] +6678 - null - [null, null, null, null, null] +6679 - null - [null, null, null, null, null] +6680 - null - [null, null, null, null, null] +6681 - null - [null, null, null, null, null] +6682 - null - [null, null, null, null, null] +6683 - null - [null, null, null, null, null] +6684 - null - [null, null, null, null, null] +6685 - null - [null, null, null, null, null] +6686 - null - [null, null, null, null, null] +6687 - null - [null, null, null, null, null] +6688 - null - [null, null, null, null, null] +6689 - null - [null, null, null, null, null] +6690 - null - [null, null, null, null, null] +6691 - null - [null, null, null, null, null] +6692 - null - [null, null, null, null, null] +6693 - null - [null, null, null, null, null] +6694 - null - [null, null, null, null, null] +6695 - null - [null, null, null, null, null] +6696 - null - [null, null, null, null, null] +6697 - null - [null, null, null, null, null] +6698 - null - [null, null, null, null, null] +6699 - null - [null, null, null, null, null] +6700 - null - [null, null, null, null, null] +6701 - null - [null, null, null, null, null] +6702 - Staircase - [Climb-up, null, null, null, null] +6703 - Staircase - [Climb-up, null, null, null, null] +6704 - Staircase - [Climb-up, null, null, null, null] +6705 - Staircase - [Climb-up, null, null, null, null] +6706 - Staircase - [Climb-up, null, null, null, null] +6707 - Staircase - [Climb-up, null, null, null, null] +6708 - Ladder - [Climb-up, null, null, null, null] +6709 - null - [null, null, null, null, null] +6710 - null - [null, null, null, null, null] +6711 - null - [null, null, null, null, null] +6712 - null - [null, null, null, null, null] +6713 - Door - [null, null, null, null, null] +6714 - Door - [Open, null, null, null, null] +6715 - Door - [null, null, null, null, null] +6716 - null - [null, null, null, null, null] +6717 - null - [null, null, null, null, null] +6718 - null - [null, null, null, null, null] +6719 - null - [null, null, null, null, null] +6720 - null - [null, null, null, null, null] +6721 - null - [null, null, null, null, null] +6722 - null - [null, null, null, null, null] +6723 - null - [null, null, null, null, null] +6724 - null - [null, null, null, null, null] +6725 - null - [null, null, null, null, null] +6726 - null - [null, null, null, null, null] +6727 - null - [null, null, null, null, null] +6728 - null - [null, null, null, null, null] +6729 - null - [null, null, null, null, null] +6730 - null - [null, null, null, null, null] +6731 - null - [null, null, null, null, null] +6732 - Door - [null, null, null, null, null] +6733 - Door - [Open, null, null, null, null] +6734 - Door - [null, null, null, null, null] +6735 - null - [null, null, null, null, null] +6736 - null - [null, null, null, null, null] +6737 - null - [null, null, null, null, null] +6738 - null - [null, null, null, null, null] +6739 - null - [null, null, null, null, null] +6740 - null - [null, null, null, null, null] +6741 - null - [null, null, null, null, null] +6742 - null - [null, null, null, null, null] +6743 - null - [null, null, null, null, null] +6744 - null - [null, null, null, null, null] +6745 - null - [null, null, null, null, null] +6746 - null - [null, null, null, null, null] +6747 - null - [null, null, null, null, null] +6748 - null - [null, null, null, null, null] +6749 - null - [null, null, null, null, null] +6750 - null - [null, null, null, null, null] +6751 - null - [null, null, null, null, null] +6752 - null - [null, null, null, null, null] +6753 - null - [null, null, null, null, null] +6754 - null - [null, null, null, null, null] +6755 - null - [null, null, null, null, null] +6756 - null - [null, null, null, null, null] +6757 - null - [null, null, null, null, null] +6758 - null - [null, null, null, null, null] +6759 - null - [null, null, null, null, null] +6760 - null - [null, null, null, null, null] +6761 - null - [null, null, null, null, null] +6762 - null - [null, null, null, null, null] +6763 - null - [null, null, null, null, null] +6764 - null - [null, null, null, null, null] +6765 - null - [null, null, null, null, null] +6766 - null - [null, null, null, null, null] +6767 - Standing torch - [null, null, null, null, null] +6768 - null - [null, null, null, null, null] +6769 - null - [null, null, null, null, null] +6770 - null - [null, null, null, null, null] +6771 - Sarcophagus - [Search, null, null, null, null] +6772 - Sarcophagus - [Search, null, null, null, null] +6773 - Sarcophagus - [Search, null, null, null, null] +6774 - Chest - [Open, null, null, null, null] +6775 - Chest - [Search, Close, null, null, null] +6776 - Skeleton - [null, null, null, null, null] +6777 - Skeleton - [null, null, null, null, null] +6778 - Skeleton - [null, null, null, null, null] +6779 - null - [null, null, null, null, null] +6780 - null - [null, null, null, null, null] +6781 - null - [null, null, null, null, null] +6782 - null - [null, null, null, null, null] +6783 - null - [null, null, null, null, null] +6784 - null - [null, null, null, null, null] +6785 - null - [null, null, null, null, null] +6786 - null - [null, null, null, null, null] +6787 - null - [null, null, null, null, null] +6788 - null - [null, null, null, null, null] +6789 - null - [null, null, null, null, null] +6790 - null - [null, null, null, null, null] +6791 - Bed - [null, null, null, null, null] +6792 - null - [null, null, null, null, null] +6793 - null - [null, null, null, null, null] +6794 - null - [null, null, null, null, null] +6795 - null - [null, null, null, null, null] +6796 - null - [null, null, null, null, null] +6797 - null - [null, null, null, null, null] +6798 - null - [null, null, null, null, null] +6799 - null - [null, null, null, null, null] +6800 - null - [null, null, null, null, null] +6801 - null - [null, null, null, null, null] +6802 - null - [null, null, null, null, null] +6803 - null - [null, null, null, null, null] +6804 - null - [null, null, null, null, null] +6805 - null - [null, null, null, null, null] +6806 - null - [null, null, null, null, null] +6807 - null - [null, null, null, null, null] +6808 - null - [null, null, null, null, null] +6809 - null - [null, null, null, null, null] +6810 - null - [null, null, null, null, null] +6811 - null - [null, null, null, null, null] +6812 - null - [null, null, null, null, null] +6813 - null - [null, null, null, null, null] +6814 - null - [null, null, null, null, null] +6815 - null - [null, null, null, null, null] +6816 - null - [null, null, null, null, null] +6817 - null - [null, null, null, null, null] +6818 - null - [null, null, null, null, null] +6819 - null - [null, null, null, null, null] +6820 - null - [null, null, null, null, null] +6821 - Sarcophagus - [Search, null, null, null, null] +6822 - Sarcophagus - [Search, null, null, null, null] +6823 - Sarcophagus - [Search, null, null, null, null] +6824 - Door - [null, null, null, null, null] +6825 - null - [null, null, null, null, null] +6826 - null - [null, null, null, null, null] +6827 - Waterpump - [null, null, null, null, null] +6828 - null - [null, null, null, null, null] +6829 - null - [null, null, null, null, null] +6830 - null - [null, null, null, null, null] +6831 - null - [null, null, null, null, null] +6832 - null - [null, null, null, null, null] +6833 - null - [null, null, null, null, null] +6834 - null - [null, null, null, null, null] +6835 - Warning sign - [null, null, null, null, null] +6836 - Cage - [Unlock, null, null, null, null] +6837 - null - [null, null, null, null, null] +6838 - null - [null, null, null, null, null] +6839 - Crate - [Buy, null, null, null, null] +6840 - Fungus pattern - [null, null, hidden, null, null] +6841 - Stairs - [Climb-down, null, null, null, null] +6842 - Stairs - [Climb-up, null, null, null, null] +6843 - null - [null, null, null, null, null] +6844 - Ogre Coffin - [Search, null, null, null, null] +6845 - Ogre Coffin - [Search, null, null, null, null] +6846 - Broken Lecturn - [Search, null, null, null, null] +6847 - Bell - [Ring, null, null, null, null] +6848 - Ogre Coffin - [Open, Pick-lock, null, hidden, null] +6849 - Signpost - [Search, null, null, null, null] +6850 - Ogre Coffin - [Open, Pick-lock, null, hidden, null] +6851 - Ogre Coffin - [null, null, null, null, null] +6852 - Ogre Coffin - [null, null, null, null, null] +6853 - Ogre Coffin - [Open, Pick-lock, null, hidden, null] +6854 - Ogre Coffin - [null, null, null, null, null] +6855 - Ogre Coffin - [null, null, null, null, null] +6856 - Barricade - [null, null, null, null, null] +6857 - Barricade - [null, null, null, null, null] +6858 - Barricade - [null, null, null, null, null] +6859 - null - [null, null, null, null, null] +6860 - null - [null, null, null, null, null] +6861 - null - [null, null, null, null, null] +6862 - null - [null, null, null, null, null] +6863 - null - [null, null, null, null, null] +6864 - null - [null, null, null, null, null] +6865 - An ogre standard - [null, null, null, null, null] +6866 - Ogre fire - [null, null, null, null, null] +6867 - Ogre Drums - [null, null, null, null, null] +6868 - Ogre Drums - [null, null, null, null, null] +6869 - null - [null, null, null, null, null] +6870 - null - [null, null, null, null, null] +6871 - Ogre stone door - [Open, null, null, null, null] +6872 - Ogre stone door - [Open, null, null, null, null] +6873 - null - [null, null, null, null, null] +6874 - null - [null, null, null, null, null] +6875 - Drawers - [Search, null, null, null, null] +6876 - Cupboard - [Search, null, null, null, null] +6877 - Wardrobe - [Search, null, null, null, null] +6878 - null - [null, null, null, null, null] +6879 - null - [null, null, null, null, null] +6880 - Ogre barricade - [null, null, null, null, null] +6881 - Crushed barricade - [Climb-over, null, null, null, null] +6882 - Crushed barricade - [Climb-over, null, null, null, null] +6883 - Ogre Coffin - [Open, Pick-lock, null, hidden, null] +6884 - null - [null, null, null, null, null] +6885 - null - [null, null, null, null, null] +6886 - null - [null, null, null, null, null] +6887 - null - [null, null, null, null, null] +6888 - Sithik Ints - [Talk-to, null, null, null, null] +6889 - Sithik Ints - [Talk-to, null, null, null, null] +6890 - Ogre Coffin - [null, null, null, hidden, null] +6891 - Ogre Coffin - [null, null, null, hidden, null] +6892 - Ogre Coffin - [null, null, null, hidden, null] +6893 - Skeleton - [Search, null, null, null, null] +6894 - Bookcase - [Search, null, null, null, null] +6895 - null - [null, null, null, null, null] +6896 - Standing torch - [null, null, null, null, null] +6897 - Stand - [Search, null, null, null, null] +6898 - null - [null, null, null, null, null] +6899 - null - [null, null, null, null, null] +6900 - null - [null, null, null, null, null] +6901 - null - [null, null, null, null, null] +6902 - null - [null, null, null, null, null] +6903 - Rubble - [null, null, null, null, null] +6904 - Shelves - [null, null, null, null, null] +6905 - Hole - [Squeeze-through, null, null, null, null] +6906 - null - [null, null, null, null, null] +6907 - null - [null, null, null, null, null] +6908 - null - [null, null, null, null, null] +6909 - Wall - [null, null, null, null, null] +6910 - Chest - [Open, null, null, null, null] +6911 - Crate - [Search, null, null, null, null] +6912 - Hole - [Squeeze-through, null, null, null, null] +6913 - null - [null, null, null, null, null] +6914 - Hole - [Squeeze-through, null, null, null, null] +6915 - Rubble - [null, null, null, null, null] +6916 - Bookcase - [Search, null, null, null, null] +6917 - null - [null, null, null, null, null] +6918 - null - [null, null, null, null, null] +6919 - Door - [Open, null, null, null, null] +6920 - Door - [Open, null, null, null, null] +6921 - Symbol - [Look-at, null, null, null, null] +6922 - Symbol - [Look-at, null, null, null, null] +6923 - Symbol - [Look-at, null, null, null, null] +6924 - Symbol - [Look-at, null, null, null, null] +6925 - null - [null, null, null, null, null] +6926 - null - [null, null, null, null, null] +6927 - Big, big boulder... - [null, null, null, null, null] +6928 - Bone Crane - [null, null, null, null, null] +6929 - Bone support - [null, null, null, null, null] +6930 - Bone support - [null, null, null, null, null] +6931 - Bone arch - [null, null, null, null, null] +6932 - Bone arch - [null, null, null, null, null] +6933 - Bone arch - [null, null, null, null, null] +6934 - Bone arch - [null, null, null, null, null] +6935 - Bone arch - [null, null, null, null, null] +6936 - Bone arch - [null, null, null, null, null] +6937 - Bone arch - [null, null, null, null, null] +6938 - Bone arch - [null, null, null, null, null] +6939 - Bone arch - [null, null, null, null, null] +6940 - Bone arch - [null, null, null, null, null] +6941 - null - [null, null, null, null, null] +6942 - null - [null, null, null, null, null] +6943 - Rocks - [Mine, Prospect, hidden, null, null] +6944 - Rocks - [Mine, Prospect, hidden, null, null] +6945 - Rocks - [Mine, Prospect, hidden, null, null] +6946 - Rocks - [Mine, Prospect, hidden, null, null] +6947 - Rocks - [Mine, Prospect, hidden, null, null] +6948 - Rocks - [Mine, Prospect, hidden, null, null] +6949 - null - [null, null, null, null, null] +6950 - Boulder - [null, null, null, null, null] +6951 - Nothing - [null, null, null, null, null] +6952 - Nothing - [null, null, null, null, null] +6953 - Nothing - [null, null, null, null, null] +6954 - null - [null, null, null, null, null] +6955 - null - [null, null, null, null, null] +6956 - null - [null, null, null, null, null] +6957 - null - [null, null, null, null, null] +6958 - null - [null, null, null, null, null] +6959 - null - [null, null, null, null, null] +6960 - null - [null, null, null, null, null] +6961 - null - [null, null, null, null, null] +6962 - null - [null, null, null, null, null] +6963 - null - [null, null, null, null, null] +6964 - null - [null, null, null, null, null] +6965 - null - [null, null, null, null, null] +6966 - null - [null, null, null, null, null] +6967 - null - [null, null, null, null, null] +6968 - null - [null, null, null, null, null] +6969 - Swamp Boaty - [Board, Board ( Pay 10 ), null, null, null] +6970 - Swamp Boaty - [Board, null, null, null, null] +6971 - Cart Track - [null, null, null, null, null] +6972 - Bookcase - [null, null, null, null, null] +6973 - null - [null, null, null, null, null] +6974 - null - [null, null, null, null, null] +6975 - Door - [Open, null, null, null, null] +6976 - Door - [Close, null, null, null, null] +6977 - Door - [Open, null, null, null, null] +6978 - Door - [null, null, null, null, null] +6979 - null - [null, null, null, null, null] +6980 - null - [null, null, null, null, null] +6981 - null - [null, null, null, null, null] +6982 - null - [null, null, null, null, null] +6983 - null - [null, null, null, null, null] +6984 - Market Stall - [null, null, null, null, null] +6985 - Crusher - [null, null, null, null, null] +6986 - null - [null, null, null, null, null] +6987 - null - [null, null, null, null, null] +6988 - null - [null, null, null, null, null] +6989 - null - [null, null, null, null, null] +6990 - null - [null, null, null, null, null] +6991 - null - [null, null, null, null, null] +6992 - null - [null, null, null, null, null] +6993 - null - [null, null, null, null, null] +6994 - null - [null, null, null, null, null] +6995 - null - [null, null, null, null, null] +6996 - null - [null, null, null, null, null] +6997 - null - [null, null, null, null, null] +6998 - null - [null, null, null, null, null] +6999 - null - [null, null, null, null, null] +7000 - null - [null, null, null, null, null] +7001 - null - [null, null, null, null, null] +7002 - Statue - [null, null, null, null, null] +7003 - Statue - [null, null, null, null, null] +7004 - Statue - [null, null, null, null, null] +7005 - Statue - [null, null, null, null, null] +7006 - Statue - [null, null, null, null, null] +7007 - Statue - [null, null, null, null, null] +7008 - Statue - [null, null, null, null, null] +7009 - Statue - [null, null, null, null, null] +7010 - Almost a Statue - [null, null, null, null, null] +7011 - Plant - [null, null, null, null, null] +7012 - Plant - [null, null, null, null, null] +7013 - Plant - [null, null, null, null, null] +7014 - Plant - [null, null, null, null, null] +7015 - Plant - [null, null, null, null, null] +7016 - Pillar - [null, null, null, null, null] +7017 - Pillar - [null, null, null, null, null] +7018 - Cupboard - [null, null, null, null, null] +7019 - Cabinet - [null, null, null, null, null] +7020 - Cabinet - [null, null, null, null, null] +7021 - Cabinet - [null, null, null, null, null] +7022 - Track - [null, null, null, null, null] +7023 - Track - [null, null, null, null, null] +7024 - null - [null, null, null, null, null] +7025 - null - [null, null, null, null, null] +7026 - Track - [null, null, null, null, null] +7027 - Train cart - [null, null, null, null, null] +7028 - Train cart - [Ride, null, null, null, null] +7029 - Train cart - [Ride, null, null, null, null] +7030 - Train cart - [Ride, null, null, null, null] +7031 - null - [null, null, null, null, null] +7032 - Giant Dwarf - [null, null, null, null, null] +7033 - Giant Dwarf - [null, null, null, null, null] +7034 - Giant Dwarf - [null, null, null, null, null] +7035 - Giant Dwarf - [null, null, null, null, null] +7036 - Giant Dwarf - [null, null, null, null, null] +7037 - Giant Dwarf - [null, null, null, null, null] +7038 - Giant Dwarf - [null, null, null, null, null] +7039 - Giant Dwarf - [null, null, null, null, null] +7040 - null - [null, null, null, null, null] +7041 - Giant Dwarf - [null, null, null, null, null] +7042 - null - [null, null, null, null, null] +7043 - Giant Dwarf - [null, null, null, null, null] +7044 - Buffers - [null, null, null, null, null] +7045 - null - [null, null, null, null, null] +7046 - null - [null, null, null, null, null] +7047 - null - [null, null, null, null, null] +7048 - null - [null, null, null, null, null] +7049 - Gate - [Open, null, null, null, null] +7050 - Gate - [Open, null, null, null, null] +7051 - Gate - [Close, null, null, null, null] +7052 - Gate - [Close, null, null, null, null] +7053 - Seed Stall - [null, Steal from, null, null, null] +7054 - null - [null, null, null, null, null] +7055 - null - [null, null, null, null, null] +7056 - Staircase - [Climb-down, null, null, null, null] +7057 - Staircase - [Climb-up, null, null, null, null] +7058 - Old Bookshelf - [Search, null, null, null, null] +7059 - Old Bookshelf - [Search, null, null, null, null] +7060 - Old Bookshelf - [Search, null, null, null, null] +7061 - Old Bookshelf - [Search, null, null, null, null] +7062 - Old Bookshelf - [Search, null, null, null, null] +7063 - Old Bookshelf - [Search, null, null, null, null] +7064 - Old Bookshelf - [Search, null, null, null, null] +7065 - Old Bookshelf - [Search, null, null, null, null] +7066 - Old Bookshelf - [Search, null, null, null, null] +7067 - Old Bookshelf - [Search, null, null, null, null] +7068 - Old Bookshelf - [Search, null, null, null, null] +7069 - Old Bookshelf - [Search, null, null, null, null] +7070 - Old Bookshelf - [Search, null, null, null, null] +7071 - Old Bookshelf - [Search, null, null, null, null] +7072 - Old Bookshelf - [Search, null, null, null, null] +7073 - Old Bookshelf - [Search, null, null, null, null] +7074 - Old Bookshelf - [Search, null, null, null, null] +7075 - Old Bookshelf - [Search, null, null, null, null] +7076 - Old Bookshelf - [Search, null, null, null, null] +7077 - Old Bookshelf - [Search, null, null, null, null] +7078 - Old Bookshelf - [Search, null, null, null, null] +7079 - Old Bookshelf - [Search, null, null, null, null] +7080 - Old Bookshelf - [Search, null, null, null, null] +7081 - Old Bookshelf - [Search, null, null, null, null] +7082 - Old Bookshelf - [Search, null, null, null, null] +7083 - Old Bookshelf - [Search, null, null, null, null] +7084 - Old Bookshelf - [Search, null, null, null, null] +7085 - Old Bookshelf - [Search, null, null, null, null] +7086 - Old Bookshelf - [Search, null, null, null, null] +7087 - Old Bookshelf - [Search, null, null, null, null] +7088 - Old Bookshelf - [Search, null, null, null, null] +7089 - Old Bookshelf - [Search, null, null, null, null] +7090 - Globe of Gielinor - [null, null, null, null, null] +7091 - Study Desk - [null, null, null, null, null] +7092 - Telescope - [Observe, null, null, null, null] +7093 - null - [null, null, null, null, null] +7094 - null - [null, null, null, null, null] +7095 - null - [null, null, null, null, null] +7096 - Chart - [null, null, null, null, null] +7097 - Chart - [null, null, null, null, null] +7098 - Chart - [null, null, null, null, null] +7099 - Scrolls - [null, null, null, null, null] +7100 - Suit of armour - [null, null, null, null, null] +7101 - Hanging cape - [null, null, null, null, null] +7102 - Saradomin staff - [null, null, null, null, null] +7103 - Mysterious ruins - [null, null, null, null, null] +7104 - Mysterious ruins - [Enter, null, null, null, null] +7105 - Mysterious ruins - [null, null, null, null, null] +7106 - Mysterious ruins - [Enter, null, null, null, null] +7107 - Mysterious ruins - [null, null, null, null, null] +7108 - Mysterious ruins - [Enter, null, null, null, null] +7109 - Mysterious ruins - [null, null, null, null, null] +7110 - Mysterious ruins - [Enter, null, null, null, null] +7111 - Mysterious ruins - [null, null, null, null, null] +7112 - Mysterious ruins - [Enter, null, null, null, null] +7113 - Mysterious ruins - [null, null, null, null, null] +7114 - Mysterious ruins - [Enter, null, null, null, null] +7115 - Mysterious ruins - [null, null, null, null, null] +7116 - Mysterious ruins - [Enter, null, null, null, null] +7117 - Mysterious ruins - [null, null, null, null, null] +7118 - Mysterious ruins - [Enter, null, null, null, null] +7119 - Mysterious ruins - [null, null, null, null, null] +7120 - Mysterious ruins - [Enter, null, null, null, null] +7121 - Mysterious ruins - [null, null, null, null, null] +7122 - Mysterious ruins - [Enter, null, null, null, null] +7123 - Mysterious ruins - [null, null, null, null, null] +7124 - Mysterious ruins - [Enter, null, null, null, null] +7125 - Mysterious ruins - [null, null, null, null, null] +7126 - Mysterious ruins - [Enter, null, null, null, null] +7127 - null - [null, null, null, null, null] +7128 - null - [null, null, null, null, null] +7129 - Fire rift - [Exit-through, null, null, null, null] +7130 - Earth rift - [Exit-through, null, null, null, null] +7131 - Body rift - [Exit-through, null, null, null, null] +7132 - Cosmic rift - [Exit-through, null, null, null, null] +7133 - Nature rift - [Exit-through, null, null, null, null] +7134 - Chaos rift - [Exit-through, null, null, null, null] +7135 - Law rift - [Exit-through, null, null, null, null] +7136 - Death rift - [Exit-through, null, null, null, null] +7137 - Water rift - [Exit-through, null, null, null, null] +7138 - Soul rift - [Exit-through, null, null, null, null] +7139 - Air rift - [Exit-through, null, null, null, null] +7140 - Mind rift - [Exit-through, null, null, null, null] +7141 - Blood rift - [Exit-through, null, null, null, null] +7142 - null - [null, null, null, null, null] +7143 - Rock - [Mine, null, null, null, null] +7144 - Tendrils - [Chop, null, null, null, null] +7145 - Boil - [Burn-down, null, null, null, null] +7146 - eyes - [distract, null, null, null, null] +7147 - Gap - [squeeze-through, null, null, null, null] +7148 - Passage - [go-through, null, null, null, null] +7149 - Gap - [squeeze-through, null, null, null, null] +7150 - eyes - [distract, null, null, null, null] +7151 - Boil - [Burn-down, null, null, null, null] +7152 - Tendrils - [Chop, null, null, null, null] +7153 - Rock - [Mine, null, null, null, null] +7154 - Passage - [Go-through, null, null, null, null] +7155 - null - [null, null, null, null, null] +7156 - Blockage - [null, null, null, null, null] +7157 - null - [Go-through, null, null, null, null] +7158 - Rock - [Mine, null, null, null, null] +7159 - Rock - [null, null, null, null, null] +7160 - Broken rock - [null, null, null, null, null] +7161 - Tendrils - [Chop, null, null, null, null] +7162 - Tendrils - [null, null, null, null, null] +7163 - Chopped tendrils - [null, null, null, null, null] +7164 - Gap - [Squeeze-through, null, null, null, null] +7165 - Boil - [Burn-down, null, null, null, null] +7166 - Boil - [null, null, null, null, null] +7167 - Boil - [null, null, null, null, null] +7168 - Eyes - [Distract, null, null, null, null] +7169 - Eyes - [null, null, null, null, null] +7170 - Eyes - [null, null, null, null, null] +7171 - Abyssal rift - [null, null, null, null, null] +7172 - null - [null, null, null, null, null] +7173 - null - [null, null, null, null, null] +7174 - null - [null, null, null, null, null] +7175 - null - [null, null, null, null, null] +7176 - null - [null, null, null, null, null] +7177 - null - [null, null, null, null, null] +7178 - null - [null, null, null, null, null] +7179 - null - [null, null, null, null, null] +7180 - null - [null, null, null, null, null] +7181 - null - [null, null, null, null, null] +7182 - null - [null, null, null, null, null] +7183 - null - [null, null, null, null, null] +7184 - null - [null, null, null, null, null] +7185 - null - [null, null, null, null, null] +7186 - null - [null, null, null, null, null] +7187 - null - [null, null, null, null, null] +7188 - null - [null, null, null, null, null] +7189 - Tendrils - [null, null, null, null, null] +7190 - Tendrils - [null, null, null, null, null] +7191 - Tendrils - [null, null, null, null, null] +7192 - null - [null, null, null, null, null] +7193 - null - [null, null, null, null, null] +7194 - null - [null, null, null, null, null] +7195 - null - [null, null, null, null, null] +7196 - null - [null, null, null, null, null] +7197 - null - [null, null, null, null, null] +7198 - null - [null, null, null, null, null] +7199 - null - [null, null, null, null, null] +7200 - null - [null, null, null, null, null] +7201 - null - [null, null, null, null, null] +7202 - null - [null, null, null, null, null] +7203 - null - [null, null, null, null, null] +7204 - null - [null, null, null, null, null] +7205 - null - [null, null, null, null, null] +7206 - Corpse - [null, null, null, null, null] +7207 - Corpse - [null, null, null, null, null] +7208 - Corpse - [null, null, null, null, null] +7209 - null - [null, null, null, null, null] +7210 - null - [null, null, null, null, null] +7211 - null - [null, null, null, null, null] +7212 - null - [null, null, null, null, null] +7213 - null - [null, null, null, null, null] +7214 - null - [null, null, null, null, null] +7215 - null - [null, null, null, null, null] +7216 - null - [null, null, null, null, null] +7217 - null - [null, null, null, null, null] +7218 - null - [null, null, null, null, null] +7219 - Passageway - [Enter, null, null, null, null] +7220 - Passageway - [Enter, null, null, null, null] +7221 - Ladder - [Climb-Down, null, null, null, null] +7222 - Door - [Open, null, null, null, null] +7223 - Door - [null, null, null, null, null] +7224 - Spinning blades - [null, null, null, null, null] +7225 - Wall - [null, null, null, null, null] +7226 - null - [null, null, null, null, null] +7227 - Floor - [null, null, null, null, Search] +7228 - Wall - [null, null, null, null, Search] +7229 - Wall - [null, null, null, null, Search] +7230 - Floor - [null, null, null, null, Search] +7231 - Door - [Open, null, null, null, null] +7232 - Door - [Open, null, null, null, null] +7233 - Door - [Open, null, null, null, null] +7234 - Door - [Open, null, null, null, null] +7235 - null - [null, null, null, null, null] +7236 - Wall safe - [Crack, hidden, null, null, null] +7237 - Wall safe - [Crack, hidden, null, null, null] +7238 - null - [null, null, null, null, null] +7239 - Ledge - [Climb, null, null, null, null] +7240 - Ledge - [Climb, null, null, null, null] +7241 - Pendulum - [null, null, null, null, null] +7242 - Wooden Obstruction - [null, null, null, null, null] +7243 - Wooden Obstruction - [null, null, null, null, null] +7244 - Wooden Obstruction - [null, null, null, null, null] +7245 - Floor - [null, null, null, null, Search] +7246 - Door - [Pick-lock, null, null, null, null] +7247 - null - [null, null, null, null, null] +7248 - Wall - [null, null, null, null, null] +7249 - Wall - [null, null, null, null, Search] +7250 - Floor - [null, null, null, null, null] +7251 - Contortion Bars - [Enter, null, null, null, null] +7252 - Blade - [null, null, null, null, null] +7253 - Spin Blades - [null, null, null, null, null] +7254 - Grill - [null, null, null, null, null] +7255 - Grill - [Open, null, null, null, null] +7256 - Doorway - [Open, null, null, null, null] +7257 - Trapdoor - [Enter, null, null, null, null] +7258 - Passageway - [Enter, null, null, null, null] +7259 - Door - [Open, null, null, null, null] +7260 - Door - [Close, null, null, null, null] +7261 - null - [null, null, null, null, null] +7262 - null - [null, null, null, null, null] +7263 - null - [null, null, null, null, null] +7264 - null - [null, null, null, null, null] +7265 - null - [null, null, null, null, null] +7266 - null - [null, null, null, null, null] +7267 - null - [null, null, null, null, null] +7268 - null - [null, null, null, null, null] +7269 - null - [null, null, null, null, null] +7270 - null - [null, null, null, null, null] +7271 - null - [null, null, null, null, null] +7272 - Portal - [Use, null, null, null, null] +7273 - Portal - [Use, null, null, null, null] +7274 - Door - [Open, null, null, null, null] +7275 - null - [Pick-up, null, null, null, null] +7276 - null - [Pick-up, null, null, null, null] +7277 - Fox - [Pick-up, null, null, null, null] +7278 - Fox - [Pick-up, null, null, null, null] +7279 - null - [Pick-up, null, null, null, null] +7280 - null - [Pick-up, null, null, null, null] +7281 - Chicken - [Pick-up, null, null, null, null] +7282 - null - [Pick-up, null, null, null, null] +7283 - null - [Pick-up, null, null, null, null] +7284 - Grain - [Pick-up, null, null, null, null] +7285 - Empty Sack - [Pick-up, null, null, null, null] +7286 - Precarious bridge - [Cross, null, null, null, null] +7287 - Precarious bridge - [Cross, null, null, null, null] +7288 - Portal - [Use, null, null, null, null] +7289 - Portal - [Use, null, null, null, null] +7290 - null - [null, null, null, null, null] +7291 - null - [null, null, null, null, null] +7292 - null - [null, null, null, null, null] +7293 - null - [null, null, null, null, null] +7294 - null - [null, null, null, null, null] +7295 - null - [null, null, null, null, null] +7296 - null - [null, null, null, null, null] +7297 - null - [null, null, null, null, null] +7298 - null - [null, null, null, null, null] +7299 - null - [null, null, null, null, null] +7300 - null - [null, null, null, null, null] +7301 - null - [null, null, null, null, null] +7302 - Door - [Open, null, null, null, null] +7303 - Statue - [Touch, null, null, null, null] +7304 - Statue - [Touch, null, null, null, null] +7305 - Statue - [Touch, null, null, null, null] +7306 - Statue - [Touch, null, null, null, null] +7307 - Statue - [Touch, null, null, null, null] +7308 - Statue - [Touch, null, null, null, null] +7309 - Statue - [Touch, null, null, null, null] +7310 - Statue - [Touch, null, null, null, null] +7311 - Statue - [Touch, null, null, null, null] +7312 - Statue - [Touch, null, null, null, null] +7313 - Statue - [Touch, null, null, null, null] +7314 - Statue - [Touch, null, null, null, null] +7315 - Portal - [Use, null, null, null, null] +7316 - Portal - [Use, null, null, null, null] +7317 - Door - [Open, null, null, null, null] +7318 - Portal - [Use, null, null, null, null] +7319 - Portal - [Use, null, null, null, null] +7320 - Door - [Open, null, null, null, null] +7321 - Portal - [Use, null, null, null, null] +7322 - Portal - [Use, null, null, null, null] +7323 - Door - [Open, null, null, null, null] +7324 - Portal - [Use, null, null, null, null] +7325 - Portal - [Use, null, null, null, null] +7326 - Door - [Open, null, null, null, null] +7327 - Old Bookshelf - [Search, null, null, null, null] +7328 - Old Bookshelf - [Search, null, null, null, null] +7329 - Old Bookshelf - [Search, null, null, null, null] +7330 - Old Bookshelf - [Search, null, null, null, null] +7331 - Table - [null, null, null, null, null] +7332 - Bunsen burner - [null, null, null, null, null] +7333 - Shelves - [Search, null, null, null, null] +7334 - Shelves - [Search, null, null, null, null] +7335 - Shelves - [Search, null, null, null, null] +7336 - Shelves - [Search, null, null, null, null] +7337 - Shelves - [Search, null, null, null, null] +7338 - Shelves - [Search, null, null, null, null] +7339 - Shelves - [Search, null, null, null, null] +7340 - Shelves - [Search, null, null, null, null] +7341 - null - [null, null, null, null, null] +7342 - null - [null, null, null, null, null] +7343 - Stone Door - [Study, null, null, null, null] +7344 - Stone Door - [Pull-spade, null, null, null, null] +7345 - Open Door - [Walk-through, null, null, null, null] +7346 - Key - [null, null, null, null, null] +7347 - Crate - [Search, null, null, null, null] +7348 - Crate - [Search, null, null, null, null] +7349 - Crate - [Search, null, null, null, null] +7350 - Closed chest - [Open, null, null, null, null] +7351 - Open chest - [Search, Close, null, null, null] +7352 - Portal - [Use, null, null, null, null] +7353 - Portal - [Use, null, null, null, null] +7354 - Door - [Open, null, null, null, null] +7355 - Warning Sign - [null, null, null, null, null] +7356 - null - [null, null, null, null, null] +7357 - null - [null, null, null, null, null] +7358 - null - [null, null, null, null, null] +7359 - null - [null, null, null, null, null] +7360 - null - [null, null, null, null, null] +7361 - null - [null, null, null, null, null] +7362 - null - [null, null, null, null, null] +7363 - null - [null, null, null, null, null] +7364 - null - [null, null, null, null, null] +7365 - null - [null, null, null, null, null] +7366 - null - [null, null, null, null, null] +7367 - null - [null, null, null, null, null] +7368 - null - [null, null, null, null, null] +7369 - null - [null, null, null, null, null] +7370 - null - [null, null, null, null, null] +7371 - null - [null, null, null, null, null] +7372 - null - [null, null, null, null, null] +7373 - Door - [Open, null, null, null, null] +7374 - Door - [Close, null, null, null, null] +7375 - null - [null, null, null, null, null] +7376 - null - [null, null, null, null, null] +7377 - null - [null, null, null, null, null] +7378 - null - [null, null, null, null, null] +7379 - null - [null, null, null, null, null] +7380 - null - [null, null, null, null, null] +7381 - null - [null, null, null, null, null] +7382 - null - [null, null, null, null, null] +7383 - null - [null, null, null, null, null] +7384 - null - [null, null, null, null, null] +7385 - Chair - [null, null, null, null, null] +7386 - null - [null, null, null, null, null] +7387 - null - [null, null, null, null, null] +7388 - Bench - [null, null, null, null, null] +7389 - null - [null, null, null, null, null] +7390 - Hookah - [null, null, null, null, null] +7391 - Rolled up rug - [null, null, null, null, null] +7392 - Rolled up rugs - [null, null, null, null, null] +7393 - Little tent - [null, null, null, null, null] +7394 - Rug - [null, null, null, null, null] +7395 - null - [null, null, null, null, null] +7396 - Carpet Exhibit - [null, null, null, null, null] +7397 - Leafy tree - [null, null, null, null, null] +7398 - Leafy tree - [null, null, null, null, null] +7399 - Tree Stump - [null, null, hidden, null, null] +7400 - Tree Stump - [null, null, hidden, null, null] +7401 - Tree Stump - [null, null, hidden, null, null] +7402 - Tree Stump - [null, null, hidden, null, null] +7403 - Apple Barrel - [null, null, null, null, null] +7404 - Apple Barrel - [null, null, null, null, null] +7405 - null - [null, null, null, null, null] +7406 - Barrel Tap - [null, null, null, null, null] +7407 - Barrel - [null, null, null, null, null] +7408 - Barrel - [Drain, null, null, null, null] +7409 - Barrel - [Drain, null, null, null, null] +7410 - Barrel - [Drain, null, null, null, null] +7411 - Dwarven Stout - [Level, null, null, null, null] +7412 - Mature Dwarven Stout - [Level, null, null, null, null] +7413 - Asgarnian Ale - [Level, null, null, null, null] +7414 - Mature Asgarnian Ale - [Level, null, null, null, null] +7415 - Greenmans Ale - [Level, null, null, null, null] +7416 - Mature Greenmans Ale - [Level, null, null, null, null] +7417 - Wizards Mind Bomb - [Level, null, null, null, null] +7418 - Mature Wizards Mind Bomb - [Level, null, null, null, null] +7419 - Dragon Bitter - [Level, null, null, null, null] +7420 - Mature Dragon Bitter - [Level, null, null, null, null] +7421 - Moonlight Mead - [Level, null, null, null, null] +7422 - Mature Moonlight Mead - [Level, null, null, null, null] +7423 - Axeman's Folly - [Level, null, null, null, null] +7424 - Mature Axeman's Folly - [Level, null, null, null, null] +7425 - Chef's Delight - [Level, null, null, null, null] +7426 - Mature Chef's Delight - [Level, null, null, null, null] +7427 - Slayer's Respite - [Level, null, null, null, null] +7428 - Mature Slayer's Respite - [Level, null, null, null, null] +7429 - Cider - [Level, null, null, null, null] +7430 - Mature Cider - [Level, null, null, null, null] +7431 - null - [null, null, null, null, null] +7432 - null - [null, null, null, null, null] +7433 - ladder - [Climb-up, null, null, null, null] +7434 - Trapdoor - [Open, null, null, null, null] +7435 - Trapdoor - [Climb-down, Close, null, null, null] +7436 - Barrel - [null, null, null, null, null] +7437 - Fermenting Vat - [null, null, null, null, null] +7438 - Fermenting Vat - [null, null, null, null, null] +7439 - Fermenting Vat - [null, null, null, null, null] +7440 - Fermenting Vat - [null, null, null, null, null] +7441 - Fermenting Vat - [null, null, null, null, null] +7442 - Valve - [Turn, null, null, null, null] +7443 - Valve - [Turn, null, null, null, null] +7444 - Fermenting Vat - [null, null, null, null, null] +7445 - Fermenting Vat - [null, null, null, null, null] +7446 - Fermenting Vat - [null, null, null, null, null] +7447 - Fermenting Vat - [null, null, null, null, null] +7448 - Fermenting Vat - [null, null, null, null, null] +7449 - Fermenting Vat - [null, null, null, null, null] +7450 - Fermenting Vat - [null, null, null, null, null] +7451 - Fermenting Vat - [null, null, null, null, null] +7452 - Fermenting Vat - [null, null, null, null, null] +7453 - Fermenting Vat - [null, null, null, null, null] +7454 - Fermenting Vat - [null, null, null, null, null] +7455 - Fermenting Vat - [null, null, null, null, null] +7456 - Fermenting Vat - [null, null, null, null, null] +7457 - Fermenting Vat - [null, null, null, null, null] +7458 - Fermenting Vat - [null, null, null, null, null] +7459 - Fermenting Vat - [null, null, null, null, null] +7460 - Fermenting Vat - [null, null, null, null, null] +7461 - Fermenting Vat - [null, null, null, null, null] +7462 - Fermenting Vat - [null, null, null, null, null] +7463 - Fermenting Vat - [null, null, null, null, null] +7464 - Fermenting Vat - [null, null, null, null, null] +7465 - Fermenting Vat - [null, null, null, null, null] +7466 - Fermenting Vat - [null, null, null, null, null] +7467 - Fermenting Vat - [null, null, null, null, null] +7468 - Fermenting Vat - [null, null, null, null, null] +7469 - Fermenting Vat - [null, null, null, null, null] +7470 - Fermenting Vat - [null, null, null, null, null] +7471 - Fermenting Vat - [null, null, null, null, null] +7472 - Fermenting Vat - [null, null, null, null, null] +7473 - Fermenting Vat - [null, null, null, null, null] +7474 - Fermenting Vat - [null, null, null, null, null] +7475 - Fermenting Vat - [null, null, null, null, null] +7476 - Fermenting Vat - [null, null, null, null, null] +7477 - Fermenting Vat - [null, null, null, null, null] +7478 - Fermenting Vat - [null, null, null, null, null] +7479 - Fermenting Vat - [null, null, null, null, null] +7480 - Fermenting Vat - [null, null, null, null, null] +7481 - Fermenting Vat - [null, null, null, null, null] +7482 - Fermenting Vat - [null, null, null, null, null] +7483 - Fermenting Vat - [null, null, null, null, null] +7484 - Fermenting Vat - [null, null, null, null, null] +7485 - Fermenting Vat - [null, null, null, null, null] +7486 - Fermenting Vat - [null, null, null, null, null] +7487 - Fermenting Vat - [null, null, null, null, null] +7488 - Fermenting Vat - [null, null, null, null, null] +7489 - Fermenting Vat - [null, null, null, null, null] +7490 - Fermenting Vat - [null, null, null, null, null] +7491 - Fermenting Vat - [null, null, null, null, null] +7492 - Fermenting Vat - [null, null, null, null, null] +7493 - Fermenting Vat - [null, null, null, null, null] +7494 - null - [null, null, null, null, null] +7495 - null - [null, null, null, null, null] +7496 - Counter - [null, null, null, null, null] +7497 - Counter - [null, null, null, null, null] +7498 - Shelves - [null, null, null, null, null] +7499 - Shelves - [null, null, null, null, null] +7500 - Shelves - [null, null, null, null, null] +7501 - Shelves - [null, null, null, null, null] +7502 - Shelves - [null, null, null, null, null] +7503 - null - [null, null, null, null, null] +7504 - Chair - [null, null, null, null, null] +7505 - Chair - [null, null, null, null, null] +7506 - Shelves - [null, null, null, null, null] +7507 - Shelves - [null, null, null, null, null] +7508 - Shelves - [null, null, null, null, null] +7509 - Shelves - [null, null, null, null, null] +7510 - Shelves - [null, null, null, null, null] +7511 - Shelves - [null, null, null, null, null] +7512 - Sacks - [null, null, null, null, null] +7513 - Crate - [null, null, null, null, null] +7514 - Crate - [null, null, null, null, null] +7515 - null - [null, null, null, null, null] +7516 - Tools - [null, null, null, null, null] +7517 - null - [null, null, null, null, null] +7518 - null - [null, null, null, null, null] +7519 - null - [null, null, null, null, null] +7520 - null - [null, null, null, null, null] +7521 - null - [null, null, null, null, null] +7522 - null - [null, null, null, null, null] +7523 - null - [null, null, null, null, null] +7524 - null - [null, null, null, null, null] +7525 - null - [null, null, null, null, null] +7526 - null - [null, null, null, null, null] +7527 - Stile - [Climb-over, null, null, null, null] +7528 - Fermenting Vat - [null, null, null, null, null] +7529 - Fermenting Vat - [null, null, null, null, null] +7530 - Fermenting Vat - [null, null, null, null, null] +7531 - Barrel - [null, null, null, null, null] +7532 - Valve - [null, null, null, null, null] +7533 - null - [null, null, null, null, null] +7534 - null - [null, null, null, null, null] +7535 - null - [null, null, null, null, null] +7536 - null - [null, null, null, null, null] +7537 - null - [null, null, null, null, null] +7538 - null - [null, null, null, null, null] +7539 - null - [null, null, null, null, null] +7540 - null - [null, null, null, null, null] +7541 - null - [null, null, null, null, null] +7542 - null - [null, null, null, null, null] +7543 - null - [null, null, null, null, null] +7544 - null - [null, null, null, null, null] +7545 - null - [null, null, null, null, null] +7546 - null - [null, null, null, null, null] +7547 - null - [null, null, null, null, null] +7548 - null - [null, null, null, null, null] +7549 - null - [null, null, null, null, null] +7550 - null - [null, null, null, null, null] +7551 - null - [null, null, null, null, null] +7552 - null - [null, null, null, null, null] +7553 - null - [null, null, null, null, null] +7554 - null - [null, null, null, null, null] +7555 - null - [null, null, null, null, null] +7556 - null - [null, null, null, null, null] +7557 - Belladonna patch - [null, Inspect, null, Guide, null] +7558 - Belladonna patch - [null, Inspect, null, Guide, null] +7559 - Belladonna patch - [null, Inspect, null, Guide, null] +7560 - Belladonna patch - [null, Inspect, null, Guide, null] +7561 - Belladonna - [null, Inspect, null, Guide, null] +7562 - Belladonna - [null, Inspect, null, Guide, null] +7563 - Belladonna - [null, Inspect, null, Guide, null] +7564 - Belladonna - [null, Inspect, null, Guide, null] +7565 - Belladonna - [Pick, Inspect, null, Guide, null] +7566 - Diseased Belladonna - [null, Inspect, null, Guide, null] +7567 - Diseased Belladonna - [null, Inspect, null, Guide, null] +7568 - Diseased Belladonna - [null, Inspect, null, Guide, null] +7569 - Dead Belladonna - [null, Inspect, null, Guide, null] +7570 - Dead Belladonna - [null, Inspect, null, Guide, null] +7571 - Dead Belladonna - [null, Inspect, null, Guide, null] +7572 - null - [null, null, null, null, null] +7573 - Bush Patch - [null, Inspect, null, Guide, null] +7574 - Bush Patch - [null, Inspect, null, Guide, null] +7575 - Bush Patch - [null, Inspect, null, Guide, null] +7576 - Bush Patch - [null, Inspect, null, Guide, null] +7577 - null - [null, null, null, null, null] +7578 - null - [null, null, null, null, null] +7579 - null - [null, null, null, null, null] +7580 - null - [null, null, null, null, null] +7581 - Cadavaberry bush - [null, Inspect, null, Guide, null] +7582 - Cadavaberry bush - [null, Inspect, null, Guide, null] +7583 - Cadavaberry bush - [null, Inspect, null, Guide, null] +7584 - Cadavaberry bush - [null, Inspect, null, Guide, null] +7585 - Cadavaberry bush - [null, Inspect, null, Guide, null] +7586 - Cadavaberry bush - [null, Inspect, null, Guide, null] +7587 - Cadavaberry bush - [null, Inspect, null, Guide, null] +7588 - Cadavaberry bush - [Pick-from, Inspect, null, Guide, null] +7589 - Cadavaberry bush - [Pick-from, Inspect, null, Guide, null] +7590 - Cadavaberry bush - [Pick-from, Inspect, null, Guide, null] +7591 - Cadavaberry bush - [Pick-from, Inspect, null, Guide, null] +7592 - Cadavaberry bush - [Check-health, Inspect, null, Guide, null] +7593 - Diseased cadavaberry bush - [null, Inspect, null, Guide, null] +7594 - Diseased cadavaberry bush - [null, Inspect, null, Guide, null] +7595 - Diseased cadavaberry bush - [null, Inspect, null, Guide, null] +7596 - Diseased cadavaberry bush - [null, Inspect, null, Guide, null] +7597 - Diseased cadavaberry bush - [null, Inspect, null, Guide, null] +7598 - Diseased cadavaberry bush - [null, Inspect, null, Guide, null] +7599 - Dead cadavaberry bush - [null, Inspect, null, Guide, null] +7600 - Dead cadavaberry bush - [null, Inspect, null, Guide, null] +7601 - Dead cadavaberry bush - [null, Inspect, null, Guide, null] +7602 - Dead cadavaberry bush - [null, Inspect, null, Guide, null] +7603 - Dead cadavaberry bush - [null, Inspect, null, Guide, null] +7604 - Dead cadavaberry bush - [null, Inspect, null, Guide, null] +7605 - Dwellberry bush - [null, Inspect, null, Guide, null] +7606 - Dwellberry bush - [null, Inspect, null, Guide, null] +7607 - Dwellberry bush - [null, Inspect, null, Guide, null] +7608 - Dwellberry bush - [null, Inspect, null, Guide, null] +7609 - Dwellberry bush - [null, Inspect, null, Guide, null] +7610 - Dwellberry bush - [null, Inspect, null, Guide, null] +7611 - Dwellberry bush - [null, Inspect, null, Guide, null] +7612 - Dwellberry bush - [null, Inspect, null, Guide, null] +7613 - Dwellberry bush - [Pick-from, Inspect, null, Guide, null] +7614 - Dwellberry bush - [Pick-from, Inspect, null, Guide, null] +7615 - Dwellberry bush - [Pick-from, Inspect, null, Guide, null] +7616 - Dwellberry bush - [Pick-from, Inspect, null, Guide, null] +7617 - Dwellberry bush - [Check-health, Inspect, null, Guide, null] +7618 - Diseased dwellberry bush - [null, Inspect, null, Guide, null] +7619 - Diseased dwellberry bush - [null, Inspect, null, Guide, null] +7620 - Diseased dwellberry bush - [null, Inspect, null, Guide, null] +7621 - Diseased dwellberry bush - [null, Inspect, null, Guide, null] +7622 - Diseased dwellberry bush - [null, Inspect, null, Guide, null] +7623 - Diseased dwellberry bush - [null, Inspect, null, Guide, null] +7624 - Diseased dwellberry bush - [null, Inspect, null, Guide, null] +7625 - Dead dwellberry bush - [null, Inspect, null, Guide, null] +7626 - Dead dwellberry bush - [null, Inspect, null, Guide, null] +7627 - Dead dwellberry bush - [null, Inspect, null, Guide, null] +7628 - Dead dwellberry bush - [null, Inspect, null, Guide, null] +7629 - Dead dwellberry bush - [null, Inspect, null, Guide, null] +7630 - Dead dwellberry bush - [null, Inspect, null, Guide, null] +7631 - Dead dwellberry bush - [null, Inspect, null, Guide, null] +7632 - Jangerberry bush - [null, Inspect, null, Guide, null] +7633 - Jangerberry bush - [null, Inspect, null, Guide, null] +7634 - Jangerberry bush - [null, Inspect, null, Guide, null] +7635 - Jangerberry bush - [null, Inspect, null, Guide, null] +7636 - Jangerberry bush - [null, Inspect, null, Guide, null] +7637 - Jangerberry bush - [null, Inspect, null, Guide, null] +7638 - Jangerberry bush - [null, Inspect, null, Guide, null] +7639 - Jangerberry bush - [null, Inspect, null, Guide, null] +7640 - Jangerberry bush - [null, Inspect, null, Guide, null] +7641 - Jangerberry bush - [Pick-from, Inspect, null, Guide, null] +7642 - Jangerberry bush - [Pick-from, Inspect, null, Guide, null] +7643 - Jangerberry bush - [Pick-from, Inspect, null, Guide, null] +7644 - Jangerberry bush - [Pick-from, Inspect, null, Guide, null] +7645 - Jangerberry bush - [Check-health, Inspect, null, Guide, null] +7646 - Diseased jangerberry bush - [null, Inspect, null, Guide, null] +7647 - Diseased jangerberry bush - [null, Inspect, null, Guide, null] +7648 - Diseased jangerberry bush - [null, Inspect, null, Guide, null] +7649 - Diseased jangerberry bush - [null, Inspect, null, Guide, null] +7650 - Diseased jangerberry bush - [null, Inspect, null, Guide, null] +7651 - Diseased jangerberry bush - [null, Inspect, null, Guide, null] +7652 - Diseased jangerberry bush - [null, Inspect, null, Guide, null] +7653 - Diseased jangerberry bush - [null, Inspect, null, Guide, null] +7654 - Dead jangerberry bush - [null, Inspect, null, Guide, null] +7655 - Dead jangerberry bush - [null, Inspect, null, Guide, null] +7656 - Dead jangerberry bush - [null, Inspect, null, Guide, null] +7657 - Dead jangerberry bush - [null, Inspect, null, Guide, null] +7658 - Dead jangerberry bush - [null, Inspect, null, Guide, null] +7659 - Dead jangerberry bush - [null, Inspect, null, Guide, null] +7660 - Dead jangerberry bush - [null, Inspect, null, Guide, null] +7661 - Dead jangerberry bush - [null, Inspect, null, Guide, null] +7662 - Poison Ivy bush - [null, Inspect, null, Guide, null] +7663 - Poison Ivy bush - [null, Inspect, null, Guide, null] +7664 - Poison Ivy bush - [null, Inspect, null, Guide, null] +7665 - Poison Ivy bush - [null, Inspect, null, Guide, null] +7666 - Poison Ivy bush - [null, Inspect, null, Guide, null] +7667 - Poison Ivy bush - [null, Inspect, null, Guide, null] +7668 - Poison Ivy bush - [null, Inspect, null, Guide, null] +7669 - Poison Ivy bush - [null, Inspect, null, Guide, null] +7670 - Poison Ivy bush - [null, Inspect, null, Guide, null] +7671 - Poison Ivy bush - [Pick-from, Inspect, null, Guide, null] +7672 - Poison Ivy bush - [Pick-from, Inspect, null, Guide, null] +7673 - Poison Ivy bush - [Pick-from, Inspect, null, Guide, null] +7674 - Poison Ivy bush - [Pick-from, Inspect, null, Guide, null] +7675 - Poison Ivy bush - [Check-health, Inspect, null, Guide, null] +7676 - Diseased Poison Ivy bush - [null, Inspect, null, Guide, null] +7677 - Diseased Poison Ivy bush - [null, Inspect, null, Guide, null] +7678 - Diseased Poison Ivy bush - [null, Inspect, null, Guide, null] +7679 - Diseased Poison Ivy bush - [null, Inspect, null, Guide, null] +7680 - Diseased Poison Ivy bush - [null, Inspect, null, Guide, null] +7681 - Diseased Poison Ivy bush - [null, Inspect, null, Guide, null] +7682 - Diseased Poison Ivy bush - [null, Inspect, null, Guide, null] +7683 - Diseased Poison Ivy bush - [null, Inspect, null, Guide, null] +7684 - Dead Poison Ivy bush - [null, Inspect, null, Guide, null] +7685 - Dead Poison Ivy bush - [null, Inspect, null, Guide, null] +7686 - Dead Poison Ivy bush - [null, Inspect, null, Guide, null] +7687 - Dead Poison Ivy bush - [null, Inspect, null, Guide, null] +7688 - Dead Poison Ivy bush - [null, Inspect, null, Guide, null] +7689 - Dead Poison Ivy bush - [null, Inspect, null, Guide, null] +7690 - Dead Poison Ivy bush - [null, Inspect, null, Guide, null] +7691 - Dead Poison Ivy bush - [null, Inspect, null, Guide, null] +7692 - Redberry bush - [null, Inspect, null, Guide, null] +7693 - Redberry bush - [null, Inspect, null, Guide, null] +7694 - Redberry bush - [null, Inspect, null, Guide, null] +7695 - Redberry bush - [null, Inspect, null, Guide, null] +7696 - Redberry bush - [null, Inspect, null, Guide, null] +7697 - Redberry bush - [null, Inspect, null, Guide, null] +7698 - Redberry bush - [Pick-from, Inspect, null, Guide, null] +7699 - Redberry bush - [Pick-from, Inspect, null, Guide, null] +7700 - Redberry bush - [Pick-from, Inspect, null, Guide, null] +7701 - Redberry bush - [Pick-from, Inspect, null, Guide, null] +7702 - Redberry bush - [Check-health, Inspect, null, Guide, null] +7703 - Diseased redberry bush - [null, Inspect, null, Guide, null] +7704 - Diseased redberry bush - [null, Inspect, null, Guide, null] +7705 - Diseased redberry bush - [null, Inspect, null, Guide, null] +7706 - Diseased redberry bush - [null, Inspect, null, Guide, null] +7707 - Diseased redberry bush - [null, Inspect, null, Guide, null] +7708 - Dead redberry bush - [null, Inspect, null, Guide, null] +7709 - Dead redberry bush - [null, Inspect, null, Guide, null] +7710 - Dead redberry bush - [null, Inspect, null, Guide, null] +7711 - Dead redberry bush - [null, Inspect, null, Guide, null] +7712 - Dead redberry bush - [null, Inspect, null, Guide, null] +7713 - Whiteberry bush - [null, Inspect, null, Guide, null] +7714 - Whiteberry bush - [null, Inspect, null, Guide, null] +7715 - Whiteberry bush - [null, Inspect, null, Guide, null] +7716 - Whiteberry bush - [null, Inspect, null, Guide, null] +7717 - Whiteberry bush - [null, Inspect, null, Guide, null] +7718 - Whiteberry bush - [null, Inspect, null, Guide, null] +7719 - Whiteberry bush - [null, Inspect, null, Guide, null] +7720 - Whiteberry bush - [null, Inspect, null, Guide, null] +7721 - Whiteberry bush - [null, Inspect, null, Guide, null] +7722 - Whiteberry bush - [Pick-from, Inspect, null, Guide, null] +7723 - Whiteberry bush - [Pick-from, Inspect, null, Guide, null] +7724 - Whiteberry bush - [Pick-from, Inspect, null, Guide, null] +7725 - Whiteberry bush - [Pick-from, Inspect, null, Guide, null] +7726 - Whiteberry bush - [Check-health, Inspect, null, Guide, null] +7727 - Diseased whiteberry bush - [null, Inspect, null, Guide, null] +7728 - Diseased whiteberry bush - [null, Inspect, null, Guide, null] +7729 - Diseased whiteberry bush - [null, Inspect, null, Guide, null] +7730 - Diseased whiteberry bush - [null, Inspect, null, Guide, null] +7731 - Diseased whiteberry bush - [null, Inspect, null, Guide, null] +7732 - Diseased whiteberry bush - [null, Inspect, null, Guide, null] +7733 - Diseased whiteberry bush - [null, Inspect, null, Guide, null] +7734 - Diseased whiteberry bush - [null, Inspect, null, Guide, null] +7735 - Dead whiteberry bush - [null, Inspect, null, Guide, null] +7736 - Dead whiteberry bush - [null, Inspect, null, Guide, null] +7737 - Dead whiteberry bush - [null, Inspect, null, Guide, null] +7738 - Dead whiteberry bush - [null, Inspect, null, Guide, null] +7739 - Dead whiteberry bush - [null, Inspect, null, Guide, null] +7740 - Dead whiteberry bush - [null, Inspect, null, Guide, null] +7741 - Dead whiteberry bush - [null, Inspect, null, Guide, null] +7742 - Dead whiteberry bush - [null, Inspect, null, Guide, null] +7743 - Cactus patch - [null, Inspect, null, Guide, null] +7744 - Cactus patch - [null, Inspect, null, Guide, null] +7745 - Cactus patch - [null, Inspect, null, Guide, null] +7746 - Cactus patch - [null, Inspect, null, Guide, null] +7747 - Cactus - [null, Inspect, null, Guide, null] +7748 - Cactus - [null, Inspect, null, Guide, null] +7749 - Cactus - [null, Inspect, null, Guide, null] +7750 - Cactus - [null, Inspect, null, Guide, null] +7751 - Cactus - [null, Inspect, null, Guide, null] +7752 - Cactus - [null, Inspect, null, Guide, null] +7753 - Cactus - [null, Inspect, null, Guide, null] +7754 - Cactus - [null, Inspect, null, Guide, null] +7755 - Cactus - [Pick-spine, Inspect, null, Guide, null] +7756 - Cactus - [Pick-spine, Inspect, null, Guide, null] +7757 - Cactus - [Pick-spine, Inspect, null, Guide, null] +7758 - Cactus - [Check-health, Inspect, null, Guide, null] +7759 - Diseased cactus - [null, Inspect, null, Guide, null] +7760 - Diseased cactus - [null, Inspect, null, Guide, null] +7761 - Diseased cactus - [null, Inspect, null, Guide, null] +7762 - Diseased cactus - [null, Inspect, null, Guide, null] +7763 - Diseased cactus - [null, Inspect, null, Guide, null] +7764 - Diseased cactus - [null, Inspect, null, Guide, null] +7765 - Dead cactus - [null, Inspect, null, Guide, null] +7766 - Dead cactus - [null, Inspect, null, Guide, null] +7767 - Dead cactus - [null, Inspect, null, Guide, null] +7768 - Dead cactus - [null, Inspect, null, Guide, null] +7769 - Dead cactus - [null, Inspect, null, Guide, null] +7770 - Dead cactus - [null, Inspect, null, Guide, null] +7771 - null - [null, null, null, null, null] +7772 - Calquat patch - [null, Inspect, null, Guide, null] +7773 - Calquat patch - [null, Inspect, null, Guide, null] +7774 - Calquat patch - [null, Inspect, null, Guide, null] +7775 - Calquat patch - [null, Inspect, null, Guide, null] +7776 - Calquat Tree - [null, Inspect, null, Guide, null] +7777 - Calquat Tree - [null, Inspect, null, Guide, null] +7778 - Calquat Tree - [null, Inspect, null, Guide, null] +7779 - Calquat Tree - [null, Inspect, null, Guide, null] +7780 - Calquat Tree - [null, Inspect, null, Guide, null] +7781 - Calquat Tree - [null, Inspect, null, Guide, null] +7782 - Calquat Tree - [null, Inspect, null, Guide, null] +7783 - Calquat Tree - [null, Inspect, null, Guide, null] +7784 - Calquat Tree - [null, Inspect, null, Guide, null] +7785 - Calquat Tree - [Pick-fruit, Inspect, null, Guide, null] +7786 - Calquat Tree - [Pick-fruit, Inspect, null, Guide, null] +7787 - Calquat Tree - [Pick-fruit, Inspect, null, Guide, null] +7788 - Calquat Tree - [Pick-fruit, Inspect, null, Guide, null] +7789 - Calquat Tree - [Pick-fruit, Inspect, null, Guide, null] +7790 - Calquat Tree - [Pick-fruit, Inspect, null, Guide, null] +7791 - Calquat Tree - [Check-health, Inspect, null, Guide, null] +7792 - Diseased Calquat - [null, Inspect, null, Guide, null] +7793 - Diseased Calquat - [null, Inspect, null, Guide, null] +7794 - Diseased Calquat - [null, Inspect, null, Guide, null] +7795 - Diseased Calquat - [null, Inspect, null, Guide, null] +7796 - Diseased Calquat - [null, Inspect, null, Guide, null] +7797 - Diseased Calquat - [null, Inspect, null, Guide, null] +7798 - Diseased Calquat - [null, Inspect, null, Guide, null] +7799 - Dead Calquat - [null, Inspect, null, Guide, null] +7800 - Dead Calquat - [null, Inspect, null, Guide, null] +7801 - Dead Calquat - [null, Inspect, null, Guide, null] +7802 - Dead Calquat - [null, Inspect, null, Guide, null] +7803 - Dead Calquat - [null, Inspect, null, Guide, null] +7804 - Dead Calquat - [null, Inspect, null, Guide, null] +7805 - Dead Calquat - [null, Inspect, null, Guide, null] +7806 - Dead Calquat - [null, Inspect, null, Guide, null] +7807 - null - [null, null, null, null, null] +7808 - Compost Bin - [null, null, null, null, null] +7809 - Compost Bin - [null, null, null, null, null] +7810 - Compost Bin - [Close, null, null, null, null] +7811 - Compost Bin - [null, null, null, null, null] +7812 - Compost Bin - [Close, null, null, null, null] +7813 - Compost Bin - [Open, null, null, null, null] +7814 - Compost Bin - [null, null, null, null, null] +7815 - Compost Bin - [null, null, null, null, null] +7816 - Compost Bin - [null, null, null, null, null] +7817 - Compost Bin - [null, null, null, null, null] +7818 - Compost Bin - [null, null, null, null, null] +7819 - Compost Bin - [null, null, null, null, null] +7820 - Compost Bin - [Close, null, null, null, null] +7821 - Compost Bin - [null, null, null, null, null] +7822 - Compost Bin - [Close, null, null, null, null] +7823 - Compost Bin - [Open, null, null, null, null] +7824 - Compost Bin - [null, null, null, null, null] +7825 - Compost Bin - [null, null, null, null, null] +7826 - Compost Bin - [null, null, null, null, null] +7827 - Compost Bin - [null, null, null, null, null] +7828 - Compost Bin - [null, null, null, null, null] +7829 - Compost Bin - [Close, null, null, null, null] +7830 - Compost Bin - [Take-tomato, null, null, null, null] +7831 - Compost Bin - [Take-tomato, null, null, null, null] +7832 - Compost Bin - [null, null, null, null, null] +7833 - Compost Bin - [Close, null, null, null, null] +7834 - Compost Bin - [Take-tomato, null, null, null, null] +7835 - Compost Bin - [Take-tomato, null, null, null, null] +7836 - null - [null, null, null, null, null] +7837 - null - [null, null, null, null, null] +7838 - null - [null, null, null, null, null] +7839 - null - [null, null, null, null, null] +7840 - Flower Patch - [null, Inspect, null, Guide, null] +7841 - Flower Patch - [null, Inspect, null, Guide, null] +7842 - Flower Patch - [null, Inspect, null, Guide, null] +7843 - Flower Patch - [null, Inspect, null, Guide, null] +7844 - Flower Patch - [null, Inspect, null, Guide, null] +7845 - Flower Patch - [null, Inspect, null, Guide, null] +7846 - Flower Patch - [null, Inspect, null, Guide, null] +7847 - null - [null, null, null, null, null] +7848 - null - [null, null, null, null, null] +7849 - null - [null, null, null, null, null] +7850 - null - [null, null, null, null, null] +7851 - Limpwurt plant - [null, Inspect, null, Guide, null] +7852 - Limpwurt plant - [null, Inspect, null, Guide, null] +7853 - Limpwurt plant - [null, Inspect, null, Guide, null] +7854 - Limpwurt plant - [null, Inspect, null, Guide, null] +7855 - Limpwurt plant - [Pick, Inspect, null, Guide, null] +7856 - Limpwurt plant - [null, Inspect, null, Guide, null] +7857 - Limpwurt plant - [null, Inspect, null, Guide, null] +7858 - Limpwurt plant - [null, Inspect, null, Guide, null] +7859 - Limpwurt plant - [null, Inspect, null, Guide, null] +7860 - Diseased limpwurt plant - [null, Inspect, null, Guide, null] +7861 - Diseased limpwurt plant - [null, Inspect, null, Guide, null] +7862 - Diseased limpwurt plant - [null, Inspect, null, Guide, null] +7863 - Dead limpwurt plant - [null, Inspect, null, Guide, null] +7864 - Dead limpwurt plant - [null, Inspect, null, Guide, null] +7865 - Dead limpwurt plant - [null, Inspect, null, Guide, null] +7866 - Dead limpwurt plant - [null, Inspect, null, Guide, null] +7867 - Marigold - [null, Inspect, null, Guide, null] +7868 - Marigold - [null, Inspect, null, Guide, null] +7869 - Marigold - [null, Inspect, null, Guide, null] +7870 - Marigold - [null, Inspect, null, Guide, null] +7871 - Marigold - [Pick, Inspect, null, Guide, null] +7872 - Marigold - [null, Inspect, null, Guide, null] +7873 - Marigold - [null, Inspect, null, Guide, null] +7874 - Marigold - [null, Inspect, null, Guide, null] +7875 - Marigold - [null, Inspect, null, Guide, null] +7876 - Diseased marigold - [null, Inspect, null, Guide, null] +7877 - Diseased marigold - [null, Inspect, null, Guide, null] +7878 - Diseased marigold - [null, Inspect, null, Guide, null] +7879 - Dead marigold - [null, Inspect, null, Guide, null] +7880 - Dead marigold - [null, Inspect, null, Guide, null] +7881 - Dead marigold - [null, Inspect, null, Guide, null] +7882 - Dead marigold - [null, Inspect, null, Guide, null] +7883 - Nasturtium - [null, Inspect, null, Guide, null] +7884 - Nasturtium - [null, Inspect, null, Guide, null] +7885 - Nasturtium - [null, Inspect, null, Guide, null] +7886 - Nasturtium - [null, Inspect, null, Guide, null] +7887 - Nasturtium - [Pick, Inspect, null, Guide, null] +7888 - Nasturtium - [null, Inspect, null, Guide, null] +7889 - Nasturtium - [null, Inspect, null, Guide, null] +7890 - Nasturtium - [null, Inspect, null, Guide, null] +7891 - Nasturtium - [null, Inspect, null, Guide, null] +7892 - Diseased nasturtium - [null, Inspect, null, Guide, null] +7893 - Diseased nasturtium - [null, Inspect, null, Guide, null] +7894 - Diseased nasturtium - [null, Inspect, null, Guide, null] +7895 - Dead nasturtium - [null, Inspect, null, Guide, null] +7896 - Dead nasturtium - [null, Inspect, null, Guide, null] +7897 - Dead nasturtium - [null, Inspect, null, Guide, null] +7898 - Dead nasturtium - [null, Inspect, null, Guide, null] +7899 - Rosemary - [null, Inspect, null, Guide, null] +7900 - Rosemary - [null, Inspect, null, Guide, null] +7901 - Rosemary - [null, Inspect, null, Guide, null] +7902 - Rosemary - [null, Inspect, null, Guide, null] +7903 - Rosemary - [Pick, Inspect, null, Guide, null] +7904 - Rosemary - [null, Inspect, null, Guide, null] +7905 - Rosemary - [null, Inspect, null, Guide, null] +7906 - Rosemary - [null, Inspect, null, Guide, null] +7907 - Rosemary - [null, Inspect, null, Guide, null] +7908 - Diseased rosemary - [null, Inspect, null, Guide, null] +7909 - Diseased rosemary - [null, Inspect, null, Guide, null] +7910 - Diseased rosemary - [null, Inspect, null, Guide, null] +7911 - Dead rosemary - [null, Inspect, null, Guide, null] +7912 - Dead rosemary - [null, Inspect, null, Guide, null] +7913 - Dead rosemary - [null, Inspect, null, Guide, null] +7914 - Dead rosemary - [null, Inspect, null, Guide, null] +7915 - Scarecrow - [null, Inspect, null, Guide, null] +7916 - Scarecrow - [null, Inspect, null, Guide, null] +7917 - Scarecrow - [null, Inspect, null, Guide, null] +7918 - Scarecrow - [null, Inspect, null, Guide, null] +7919 - Woad plant - [null, Inspect, null, Guide, null] +7920 - Woad plant - [null, Inspect, null, Guide, null] +7921 - Woad plant - [null, Inspect, null, Guide, null] +7922 - Woad plant - [null, Inspect, null, Guide, null] +7923 - Woad plant - [Pick, Inspect, null, Guide, null] +7924 - Woad plant - [null, Inspect, null, Guide, null] +7925 - Woad plant - [null, Inspect, null, Guide, null] +7926 - Woad plant - [null, Inspect, null, Guide, null] +7927 - Woad plant - [null, Inspect, null, Guide, null] +7928 - Diseased woad plant - [null, Inspect, null, Guide, null] +7929 - Diseased woad plant - [null, Inspect, null, Guide, null] +7930 - Diseased woad plant - [null, Inspect, null, Guide, null] +7931 - Dead woad plant - [null, Inspect, null, Guide, null] +7932 - Dead woad plant - [null, Inspect, null, Guide, null] +7933 - Dead woad plant - [null, Inspect, null, Guide, null] +7934 - Dead woad plant - [null, Inspect, null, Guide, null] +7935 - Apple tree - [null, Inspect, null, Guide, null] +7936 - Apple tree - [null, Inspect, null, Guide, null] +7937 - Apple tree - [null, Inspect, null, Guide, null] +7938 - Apple tree - [null, Inspect, null, Guide, null] +7939 - Apple tree - [null, Inspect, null, Guide, null] +7940 - Apple tree - [null, Inspect, null, Guide, null] +7941 - Apple tree - [Chop-down, Inspect, null, Guide, null] +7942 - Apple tree - [Pick-apple, Inspect, null, Guide, null] +7943 - Apple tree - [Pick-apple, Inspect, null, Guide, null] +7944 - Apple tree - [Pick-apple, Inspect, null, Guide, null] +7945 - Apple tree - [Pick-apple, Inspect, null, Guide, null] +7946 - Apple tree - [Pick-apple, Inspect, null, Guide, null] +7947 - Apple tree - [Pick-apple, Inspect, null, Guide, null] +7948 - Apple tree - [Check-health, Inspect, null, Guide, null] +7949 - Diseased apple tree - [null, Inspect, null, Guide, null] +7950 - Diseased apple tree - [null, Inspect, null, Guide, null] +7951 - Diseased apple tree - [null, Inspect, null, Guide, null] +7952 - Diseased apple tree - [null, Inspect, null, Guide, null] +7953 - Diseased apple tree - [null, Inspect, null, Guide, null] +7954 - Diseased apple tree - [null, Inspect, null, Guide, null] +7955 - Dead apple tree - [null, Inspect, null, Guide, null] +7956 - Dead apple tree - [null, Inspect, null, Guide, null] +7957 - Dead apple tree - [null, Inspect, null, Guide, null] +7958 - Dead apple tree - [null, Inspect, null, Guide, null] +7959 - Dead apple tree - [null, Inspect, null, Guide, null] +7960 - Dead apple tree - [null, Inspect, null, Guide, null] +7961 - Apple tree stump - [null, Inspect, null, Guide, null] +7962 - null - [null, null, null, null, null] +7963 - null - [null, null, null, null, null] +7964 - null - [null, null, null, null, null] +7965 - null - [null, null, null, null, null] +7966 - Pineapple plant - [null, Inspect, null, Guide, null] +7967 - Pineapple plant - [null, Inspect, null, Guide, null] +7968 - Pineapple plant - [null, Inspect, null, Guide, null] +7969 - Pineapple plant - [null, Inspect, null, Guide, null] +7970 - Pineapple plant - [null, Inspect, null, Guide, null] +7971 - Pineapple plant - [null, Inspect, null, Guide, null] +7972 - Pineapple plant - [Chop down, Inspect, null, Guide, null] +7973 - Pineapple plant - [Pick-pineapple, Inspect, null, Guide, null] +7974 - Pineapple plant - [Pick-pineapple, Inspect, null, Guide, null] +7975 - Pineapple plant - [Pick-pineapple, Inspect, null, Guide, null] +7976 - Pineapple plant - [Pick-pineapple, Inspect, null, Guide, null] +7977 - Pineapple plant - [Pick-pineapple, Inspect, null, Guide, null] +7978 - Pineapple plant - [Pick-pineapple, Inspect, null, Guide, null] +7979 - Pineapple plant - [Check-health, Inspect, null, Guide, null] +7980 - Diseased pineapple plant - [null, Inspect, null, Guide, null] +7981 - Diseased pineapple plant - [null, Inspect, null, Guide, null] +7982 - Diseased pineapple plant - [null, Inspect, null, Guide, null] +7983 - Diseased pineapple plant - [null, Inspect, null, Guide, null] +7984 - Diseased pineapple plant - [null, Inspect, null, Guide, null] +7985 - Diseased pineapple plant - [null, Inspect, null, Guide, null] +7986 - Dead pineapple plant - [null, Inspect, null, Guide, null] +7987 - Dead pineapple plant - [null, Inspect, null, Guide, null] +7988 - Dead pineapple plant - [null, Inspect, null, Guide, null] +7989 - Dead pineapple plant - [null, Inspect, null, Guide, null] +7990 - Dead pineapple plant - [null, Inspect, null, Guide, null] +7991 - Dead pineapple plant - [null, Inspect, null, Guide, null] +7992 - Pineapple plant stump - [null, Inspect, null, Guide, null] +7993 - Banana tree - [null, Inspect, null, Guide, null] +7994 - Banana tree - [null, Inspect, null, Guide, null] +7995 - Banana tree - [null, Inspect, null, Guide, null] +7996 - Banana tree - [null, Inspect, null, Guide, null] +7997 - Banana tree - [null, Inspect, null, Guide, null] +7998 - Banana tree - [null, Inspect, null, Guide, null] +7999 - Banana tree - [Check-health, Inspect, null, Guide, null] +8000 - Banana tree - [Chop-down, Inspect, null, Guide, null] +8001 - Banana tree - [Pick-banana, Inspect, null, Guide, null] +8002 - Banana tree - [Pick-banana, Inspect, null, Guide, null] +8003 - Banana tree - [Pick-banana, Inspect, null, Guide, null] +8004 - Banana tree - [Pick-banana, Inspect, null, Guide, null] +8005 - Banana tree - [Pick-banana, Inspect, null, Guide, null] +8006 - Banana tree - [Pick-banana, Inspect, null, Guide, null] +8007 - Diseased banana tree - [null, Inspect, null, Guide, null] +8008 - Diseased banana tree - [null, Inspect, null, Guide, null] +8009 - Diseased banana tree - [null, Inspect, null, Guide, null] +8010 - Diseased banana tree - [null, Inspect, null, Guide, null] +8011 - Diseased banana tree - [null, Inspect, null, Guide, null] +8012 - Diseased banana tree - [null, Inspect, null, Guide, null] +8013 - Dead banana tree - [null, Inspect, null, Guide, null] +8014 - Dead banana tree - [null, Inspect, null, Guide, null] +8015 - Dead banana tree - [null, Inspect, null, Guide, null] +8016 - Dead banana tree - [null, Inspect, null, Guide, null] +8017 - Dead banana tree - [null, Inspect, null, Guide, null] +8018 - Dead banana tree - [null, Inspect, null, Guide, null] +8019 - Banana tree stump - [null, Inspect, null, Guide, null] +8020 - Curry tree - [null, Inspect, null, Guide, null] +8021 - Curry tree - [null, Inspect, null, Guide, null] +8022 - Curry tree - [null, Inspect, null, Guide, null] +8023 - Curry tree - [null, Inspect, null, Guide, null] +8024 - Curry tree - [null, Inspect, null, Guide, null] +8025 - Curry tree - [null, Inspect, null, Guide, null] +8026 - Curry tree - [Chop-down, Inspect, null, Guide, null] +8027 - Curry tree - [Pick-leaf, Inspect, null, Guide, null] +8028 - Curry tree - [Pick-leaf, Inspect, null, Guide, null] +8029 - Curry tree - [Pick-leaf, Inspect, null, Guide, null] +8030 - Curry tree - [Pick-leaf, Inspect, null, Guide, null] +8031 - Curry tree - [Pick-leaf, Inspect, null, Guide, null] +8032 - Curry tree - [Pick-leaf, Inspect, null, Guide, null] +8033 - Curry tree - [Check-health, Inspect, null, Guide, null] +8034 - Diseased curry tree - [null, Inspect, null, Guide, null] +8035 - Diseased curry tree - [null, Inspect, null, Guide, null] +8036 - Diseased curry tree - [null, Inspect, null, Guide, null] +8037 - Diseased curry tree - [null, Inspect, null, Guide, null] +8038 - Diseased curry tree - [null, Inspect, null, Guide, null] +8039 - Diseased curry tree - [null, Inspect, null, Guide, null] +8040 - Dead curry tree - [null, Inspect, null, Guide, null] +8041 - Dead curry tree - [null, Inspect, null, Guide, null] +8042 - Dead curry tree - [null, Inspect, null, Guide, null] +8043 - Dead curry tree - [null, Inspect, null, Guide, null] +8044 - Dead curry tree - [null, Inspect, null, Guide, null] +8045 - Dead curry tree - [null, Inspect, null, Guide, null] +8046 - Curry tree stump - [null, Inspect, null, Guide, null] +8047 - Fruit Tree Patch - [null, Inspect, null, Guide, null] +8048 - Fruit Tree Patch - [null, Inspect, null, Guide, null] +8049 - Fruit Tree Patch - [null, Inspect, null, Guide, null] +8050 - Fruit Tree Patch - [null, Inspect, null, Guide, null] +8051 - Orange tree - [null, Inspect, null, Guide, null] +8052 - Orange tree - [null, Inspect, null, Guide, null] +8053 - Orange tree - [null, Inspect, null, Guide, null] +8054 - Orange tree - [null, Inspect, null, Guide, null] +8055 - Orange tree - [null, Inspect, null, Guide, null] +8056 - Orange tree - [null, Inspect, null, Guide, null] +8057 - Orange tree - [Chop-down, Inspect, null, Guide, null] +8058 - Orange tree - [Pick-orange, Inspect, null, Guide, null] +8059 - Orange tree - [Pick-orange, Inspect, null, Guide, null] +8060 - Orange tree - [Pick-orange, Inspect, null, Guide, null] +8061 - Orange tree - [Pick-orange, Inspect, null, Guide, null] +8062 - Orange tree - [Pick-orange, Inspect, null, Guide, null] +8063 - Orange tree - [Pick-orange, Inspect, null, Guide, null] +8064 - Orange tree - [Check-health, Inspect, null, Guide, null] +8065 - Diseased orange tree - [null, Inspect, null, Guide, null] +8066 - Diseased orange tree - [null, Inspect, null, Guide, null] +8067 - Diseased orange tree - [null, Inspect, null, Guide, null] +8068 - Diseased orange tree - [null, Inspect, null, Guide, null] +8069 - Diseased orange tree - [null, Inspect, null, Guide, null] +8070 - Diseased orange tree - [Chop-down, Inspect, null, Guide, null] +8071 - Dead orange tree - [null, Inspect, null, Guide, null] +8072 - Dead orange tree - [null, Inspect, null, Guide, null] +8073 - Dead orange tree - [null, Inspect, null, Guide, null] +8074 - Dead orange tree - [null, Inspect, null, Guide, null] +8075 - Dead orange tree - [null, Inspect, null, Guide, null] +8076 - Dead orange tree - [null, Inspect, null, Guide, null] +8077 - Orange tree stump - [null, Inspect, null, Guide, null] +8078 - Palm tree - [null, Inspect, null, Guide, null] +8079 - Palm tree - [null, Inspect, null, Guide, null] +8080 - Palm tree - [null, Inspect, null, Guide, null] +8081 - Palm tree - [null, Inspect, null, Guide, null] +8082 - Palm tree - [null, Inspect, null, Guide, null] +8083 - Palm tree - [null, Inspect, null, Guide, null] +8084 - Palm tree - [Chop-down, Inspect, null, Guide, null] +8085 - Palm tree - [Pick-coconut, Inspect, null, Guide, null] +8086 - Palm tree - [Pick-coconut, Inspect, null, Guide, null] +8087 - Palm tree - [Pick-coconut, Inspect, null, Guide, null] +8088 - Palm tree - [Pick-coconut, Inspect, null, Guide, null] +8089 - Palm tree - [Pick-coconut, Inspect, null, Guide, null] +8090 - Palm tree - [Pick-coconut, Inspect, null, Guide, null] +8091 - Palm tree - [Check-health, Inspect, null, Guide, null] +8092 - Diseased palm tree - [null, Inspect, null, Guide, null] +8093 - Diseased palm tree - [null, Inspect, null, Guide, null] +8094 - Diseased palm tree - [null, Inspect, null, Guide, null] +8095 - Diseased palm tree - [null, Inspect, null, Guide, null] +8096 - Diseased palm tree - [null, Inspect, null, Guide, null] +8097 - Diseased palm tree - [null, Inspect, null, Guide, null] +8098 - Dead palm tree - [null, Inspect, null, Guide, null] +8099 - Dead palm tree - [null, Inspect, null, Guide, null] +8100 - Dead palm tree - [null, Inspect, null, Guide, null] +8101 - Dead palm tree - [null, Inspect, null, Guide, null] +8102 - Dead palm tree - [null, Inspect, null, Guide, null] +8103 - Dead palm tree - [null, Inspect, null, Guide, null] +8104 - Palm tree stump - [null, Inspect, null, Guide, null] +8105 - Papaya tree - [null, Inspect, null, Guide, null] +8106 - Papaya tree - [null, Inspect, null, Guide, null] +8107 - Papaya tree - [null, Inspect, null, Guide, null] +8108 - Papaya tree - [null, Inspect, null, Guide, null] +8109 - Papaya tree - [null, Inspect, null, Guide, null] +8110 - Papaya tree - [null, Inspect, null, Guide, null] +8111 - Papaya tree - [Chop-down, Inspect, null, Guide, null] +8112 - Papaya tree - [Pick-fruit, Inspect, null, Guide, null] +8113 - Papaya tree - [Pick-fruit, Inspect, null, Guide, null] +8114 - Papaya tree - [Pick-fruit, Inspect, null, Guide, null] +8115 - Papaya tree - [Pick-fruit, Inspect, null, Guide, null] +8116 - Papaya tree - [Pick-fruit, Inspect, null, Guide, null] +8117 - Papaya tree - [Pick-fruit, Inspect, null, Guide, null] +8118 - Papaya tree - [Check-health, Inspect, null, Guide, null] +8119 - Diseased papaya tree - [null, Inspect, null, Guide, null] +8120 - Diseased papaya tree - [null, Inspect, null, Guide, null] +8121 - Diseased papaya tree - [null, Inspect, null, Guide, null] +8122 - Diseased papaya tree - [null, Inspect, null, Guide, null] +8123 - Diseased papaya tree - [null, Inspect, null, Guide, null] +8124 - Diseased papaya tree - [null, Inspect, null, Guide, null] +8125 - Dead papaya tree - [null, Inspect, null, Guide, null] +8126 - Dead papaya tree - [null, Inspect, null, Guide, null] +8127 - Dead papaya tree - [null, Inspect, null, Guide, null] +8128 - Dead papaya tree - [null, Inspect, null, Guide, null] +8129 - Dead papaya tree - [null, Inspect, null, Guide, null] +8130 - Dead papaya tree - [null, Inspect, null, Guide, null] +8131 - Papaya tree stump - [null, Inspect, null, Guide, null] +8132 - Herb patch - [null, Inspect, null, Guide, null] +8133 - Herb patch - [null, Inspect, null, Guide, null] +8134 - Herb patch - [null, Inspect, null, Guide, null] +8135 - Herb patch - [null, Inspect, null, Guide, null] +8136 - Herb patch - [null, Inspect, null, Guide, null] +8137 - Herb patch - [null, Inspect, null, Guide, null] +8138 - Herb patch - [null, Inspect, null, Guide, null] +8139 - Herbs - [null, Inspect, null, Guide, null] +8140 - Herbs - [null, Inspect, null, Guide, null] +8141 - Herbs - [null, Inspect, null, Guide, null] +8142 - Herbs - [null, Inspect, null, Guide, null] +8143 - Herbs - [Pick, Inspect, null, Guide, null] +8144 - Diseased herbs - [null, Inspect, null, Guide, null] +8145 - Diseased herbs - [null, Inspect, null, Guide, null] +8146 - Diseased herbs - [null, Inspect, null, Guide, null] +8147 - Dead herbs - [null, Inspect, null, Guide, null] +8148 - Dead herbs - [null, Inspect, null, Guide, null] +8149 - Dead herbs - [null, Inspect, null, Guide, null] +8150 - null - [null, null, null, null, null] +8151 - null - [null, null, null, null, null] +8152 - null - [null, null, null, null, null] +8153 - null - [null, null, null, null, null] +8154 - Asgarnian Hops - [null, Inspect, null, Guide, null] +8155 - Asgarnian Hops - [null, Inspect, null, Guide, null] +8156 - Asgarnian Hops - [null, Inspect, null, Guide, null] +8157 - Asgarnian Hops - [null, Inspect, null, Guide, null] +8158 - Asgarnian Hops - [null, Inspect, null, Guide, null] +8159 - Asgarnian Hops - [Harvest, Inspect, null, Guide, null] +8160 - Asgarnian Hops - [null, Inspect, null, Guide, null] +8161 - Asgarnian Hops - [null, Inspect, null, Guide, null] +8162 - Asgarnian Hops - [null, Inspect, null, Guide, null] +8163 - Asgarnian Hops - [null, Inspect, null, Guide, null] +8164 - Asgarnian Hops - [null, Inspect, null, Guide, null] +8165 - Diseased Asgarnian Hops - [null, Inspect, null, Guide, null] +8166 - Diseased Asgarnian Hops - [null, Inspect, null, Guide, null] +8167 - Diseased Asgarnian Hops - [null, Inspect, null, Guide, null] +8168 - Diseased Asgarnian Hops - [null, Inspect, null, Guide, null] +8169 - Dead Asgarnian Hops - [null, Inspect, null, Guide, null] +8170 - Dead Asgarnian Hops - [null, Inspect, null, Guide, null] +8171 - Dead Asgarnian Hops - [null, Inspect, null, Guide, null] +8172 - Dead Asgarnian Hops - [null, Inspect, null, Guide, null] +8173 - null - [null, null, null, null, null] +8174 - null - [null, null, null, null, null] +8175 - null - [null, null, null, null, null] +8176 - null - [null, null, null, null, null] +8177 - Hammerstone Hops - [null, Inspect, null, Guide, null] +8178 - Hammerstone Hops - [null, Inspect, null, Guide, null] +8179 - Hammerstone Hops - [null, Inspect, null, Guide, null] +8180 - Hammerstone Hops - [null, Inspect, null, Guide, null] +8181 - Hammerstone Hops - [Harvest, Inspect, null, Guide, null] +8182 - Hammerstone Hops - [null, Inspect, null, Guide, null] +8183 - Hammerstone Hops - [null, Inspect, null, Guide, null] +8184 - Hammerstone Hops - [null, Inspect, null, Guide, null] +8185 - Hammerstone Hops - [null, Inspect, null, Guide, null] +8186 - Diseased Hammerstone Hops - [null, Inspect, null, Guide, null] +8187 - Diseased Hammerstone Hops - [null, Inspect, null, Guide, null] +8188 - Diseased Hammerstone Hops - [null, Inspect, null, Guide, null] +8189 - Dead Hammerstone Hops - [null, Inspect, null, Guide, null] +8190 - Dead Hammerstone Hops - [null, Inspect, null, Guide, null] +8191 - Dead Hammerstone Hops - [null, Inspect, null, Guide, null] +8192 - Barley - [null, Inspect, null, Guide, null] +8193 - Barley - [null, Inspect, null, Guide, null] +8194 - Barley - [null, Inspect, null, Guide, null] +8195 - Barley - [null, Inspect, null, Guide, null] +8196 - Barley - [Harvest, Inspect, null, Guide, null] +8197 - Barley - [null, Inspect, null, Guide, null] +8198 - Barley - [null, Inspect, null, Guide, null] +8199 - Barley - [null, Inspect, null, Guide, null] +8200 - Barley - [null, Inspect, null, Guide, null] +8201 - Diseased Barley - [null, Inspect, null, Guide, null] +8202 - Diseased Barley - [null, Inspect, null, Guide, null] +8203 - Diseased Barley - [null, Inspect, null, Guide, null] +8204 - Dead Barley - [null, Inspect, null, Guide, null] +8205 - Dead Barley - [null, Inspect, null, Guide, null] +8206 - Dead Barley - [null, Inspect, null, Guide, null] +8207 - Hops Patch - [null, Inspect, null, Guide, null] +8208 - Hops Patch - [null, Inspect, null, Guide, null] +8209 - Hops Patch - [null, Inspect, null, Guide, null] +8210 - Hops Patch - [null, Inspect, null, Guide, null] +8211 - Krandorian Hops - [null, Inspect, null, Guide, null] +8212 - Krandorian Hops - [null, Inspect, null, Guide, null] +8213 - Krandorian Hops - [null, Inspect, null, Guide, null] +8214 - Krandorian Hops - [null, Inspect, null, Guide, null] +8215 - Krandorian Hops - [null, Inspect, null, Guide, null] +8216 - Krandorian Hops - [null, Inspect, null, Guide, null] +8217 - Krandorian Hops - [null, Inspect, null, Guide, null] +8218 - Krandorian Hops - [Harvest, Inspect, null, Guide, null] +8219 - Krandorian Hops - [null, Inspect, null, Guide, null] +8220 - Krandorian Hops - [null, Inspect, null, Guide, null] +8221 - Krandorian Hops - [null, Inspect, null, Guide, null] +8222 - Krandorian Hops - [null, Inspect, null, Guide, null] +8223 - Krandorian Hops - [null, Inspect, null, Guide, null] +8224 - Krandorian Hops - [null, Inspect, null, Guide, null] +8225 - Krandorian Hops - [null, Inspect, null, Guide, null] +8226 - Diseased Krandorian Hops - [null, Inspect, null, Guide, null] +8227 - Diseased Krandorian Hops - [null, Inspect, null, Guide, null] +8228 - Diseased Krandorian Hops - [null, Inspect, null, Guide, null] +8229 - Diseased Krandorian Hops - [null, Inspect, null, Guide, null] +8230 - Diseased Krandorian Hops - [null, Inspect, null, Guide, null] +8231 - Diseased Krandorian Hops - [null, Inspect, null, Guide, null] +8232 - Dead Krandorian Hops - [null, Inspect, null, Guide, null] +8233 - Dead Krandorian Hops - [null, Inspect, null, Guide, null] +8234 - Dead Krandorian Hops - [null, Inspect, null, Guide, null] +8235 - Dead Krandorian Hops - [null, Inspect, null, Guide, null] +8236 - Dead Krandorian Hops - [null, Inspect, null, Guide, null] +8237 - Dead Krandorian Hops - [null, Inspect, null, Guide, null] +8238 - Jute - [null, Inspect, null, Guide, null] +8239 - Jute - [null, Inspect, null, Guide, null] +8240 - Jute - [null, Inspect, null, Guide, null] +8241 - Jute - [null, Inspect, null, Guide, null] +8242 - Jute - [null, Inspect, null, Guide, null] +8243 - Jute - [Harvest, Inspect, null, Guide, null] +8244 - Jute - [null, Inspect, null, Guide, null] +8245 - Jute - [null, Inspect, null, Guide, null] +8246 - Jute - [null, Inspect, null, Guide, null] +8247 - Jute - [null, Inspect, null, Guide, null] +8248 - Jute - [null, Inspect, null, Guide, null] +8249 - Diseased Jute - [null, Inspect, null, Guide, null] +8250 - Diseased Jute - [null, Inspect, null, Guide, null] +8251 - Diseased Jute - [null, Inspect, null, Guide, null] +8252 - Diseased Jute - [null, Inspect, null, Guide, null] +8253 - Dead Jute - [null, Inspect, null, Guide, null] +8254 - Dead Jute - [null, Inspect, null, Guide, null] +8255 - Dead Jute - [null, Inspect, null, Guide, null] +8256 - Dead Jute - [null, Inspect, null, Guide, null] +8257 - Wildblood Hops - [null, Inspect, null, Guide, null] +8258 - Wildblood Hops - [null, Inspect, null, Guide, null] +8259 - Wildblood Hops - [null, Inspect, null, Guide, null] +8260 - Wildblood Hops - [null, Inspect, null, Guide, null] +8261 - Wildblood Hops - [null, Inspect, null, Guide, null] +8262 - Wildblood Hops - [null, Inspect, null, Guide, null] +8263 - Wildblood Hops - [null, Inspect, null, Guide, null] +8264 - Wildblood Hops - [null, Inspect, null, Guide, null] +8265 - Wildblood Hops - [Harvest, Inspect, null, Guide, null] +8266 - Wildblood Hops - [null, Inspect, null, Guide, null] +8267 - Wildblood Hops - [null, Inspect, null, Guide, null] +8268 - Wildblood Hops - [null, Inspect, null, Guide, null] +8269 - Wildblood Hops - [null, Inspect, null, Guide, null] +8270 - Wildblood Hops - [null, Inspect, null, Guide, null] +8271 - Wildblood Hops - [null, Inspect, null, Guide, null] +8272 - Wildblood Hops - [null, Inspect, null, Guide, null] +8273 - Wildblood Hops - [null, Inspect, null, Guide, null] +8274 - Diseased Wildblood Hops - [null, Inspect, null, Guide, null] +8275 - Diseased Wildblood Hops - [null, Inspect, null, Guide, null] +8276 - Diseased Wildblood Hops - [null, Inspect, null, Guide, null] +8277 - Diseased Wildblood Hops - [null, Inspect, null, Guide, null] +8278 - Diseased Wildblood Hops - [null, Inspect, null, Guide, null] +8279 - Diseased Wildblood Hops - [null, Inspect, null, Guide, null] +8280 - Diseased Wildblood Hops - [null, Inspect, null, Guide, null] +8281 - Dead Wildblood Hops - [null, Inspect, null, Guide, null] +8282 - Dead Wildblood Hops - [null, Inspect, null, Guide, null] +8283 - Dead Wildblood Hops - [null, Inspect, null, Guide, null] +8284 - Dead Wildblood Hops - [null, Inspect, null, Guide, null] +8285 - Dead Wildblood Hops - [null, Inspect, null, Guide, null] +8286 - Dead Wildblood Hops - [null, Inspect, null, Guide, null] +8287 - Dead Wildblood Hops - [null, Inspect, null, Guide, null] +8288 - Yanillian Hops - [null, Inspect, null, Guide, null] +8289 - Yanillian Hops - [null, Inspect, null, Guide, null] +8290 - Yanillian Hops - [null, Inspect, null, Guide, null] +8291 - Yanillian Hops - [null, Inspect, null, Guide, null] +8292 - Yanillian Hops - [null, Inspect, null, Guide, null] +8293 - Yanillian Hops - [null, Inspect, null, Guide, null] +8294 - Yanillian Hops - [Harvest, Inspect, null, Guide, null] +8295 - Yanillian Hops - [null, Inspect, null, Guide, null] +8296 - Yanillian Hops - [null, Inspect, null, Guide, null] +8297 - Yanillian Hops - [null, Inspect, null, Guide, null] +8298 - Yanillian Hops - [null, Inspect, null, Guide, null] +8299 - Yanillian Hops - [null, Inspect, null, Guide, null] +8300 - Yanillian Hops - [null, Inspect, null, Guide, null] +8301 - Diseased Yanillian Hops - [null, Inspect, null, Guide, null] +8302 - Diseased Yanillian Hops - [null, Inspect, null, Guide, null] +8303 - Diseased Yanillian Hops - [null, Inspect, null, Guide, null] +8304 - Diseased Yanillian Hops - [null, Inspect, null, Guide, null] +8305 - Diseased Yanillian Hops - [null, Inspect, null, Guide, null] +8306 - Dead Yanillian Hops - [null, Inspect, null, Guide, null] +8307 - Dead Yanillian Hops - [null, Inspect, null, Guide, null] +8308 - Dead Yanillian Hops - [null, Inspect, null, Guide, null] +8309 - Dead Yanillian Hops - [null, Inspect, null, Guide, null] +8310 - Dead Yanillian Hops - [null, Inspect, null, Guide, null] +8311 - Mushroom patch - [null, Inspect, null, Guide, null] +8312 - Mushroom patch - [null, Inspect, null, Guide, null] +8313 - Mushroom patch - [null, Inspect, null, Guide, null] +8314 - Mushroom patch - [null, Inspect, null, Guide, null] +8315 - Bittercap Mushrooms - [null, Inspect, null, Guide, null] +8316 - Bittercap Mushrooms - [null, Inspect, null, Guide, null] +8317 - Bittercap Mushrooms - [null, Inspect, null, Guide, null] +8318 - Bittercap Mushrooms - [null, Inspect, null, Guide, null] +8319 - Bittercap Mushrooms - [null, Inspect, null, Guide, null] +8320 - Bittercap Mushrooms - [null, Inspect, null, Guide, null] +8321 - Bittercap Mushrooms - [Pick, Inspect, null, Guide, null] +8322 - Bittercap Mushrooms - [Pick, Inspect, null, Guide, null] +8323 - Bittercap Mushrooms - [Pick, Inspect, null, Guide, null] +8324 - Bittercap Mushrooms - [Pick, Inspect, null, Guide, null] +8325 - Bittercap Mushrooms - [Pick, Inspect, null, Guide, null] +8326 - Bittercap Mushrooms - [Pick, Inspect, null, Guide, null] +8327 - Diseased Bittercap Mushrooms - [null, Inspect, null, Guide, null] +8328 - Diseased Bittercap Mushrooms - [null, Inspect, null, Guide, null] +8329 - Diseased Bittercap Mushrooms - [null, Inspect, null, Guide, null] +8330 - Diseased Bittercap Mushrooms - [null, Inspect, null, Guide, null] +8331 - Diseased Bittercap Mushrooms - [null, Inspect, null, Guide, null] +8332 - Dead Bittercap Mushrooms - [null, Inspect, null, Guide, null] +8333 - Dead Bittercap Mushrooms - [null, Inspect, null, Guide, null] +8334 - Dead Bittercap Mushrooms - [null, Inspect, null, Guide, null] +8335 - Dead Bittercap Mushrooms - [null, Inspect, null, Guide, null] +8336 - Dead Bittercap Mushrooms - [null, Inspect, null, Guide, null] +8337 - null - [null, null, null, null, null] +8338 - null - [null, null, null, null, null] +8339 - Spirit Tree Patch - [null, Inspect, null, Guide, null] +8340 - Spirit Tree Patch - [null, Inspect, null, Guide, null] +8341 - Spirit Tree Patch - [null, Inspect, null, Guide, null] +8342 - Spirit Tree Patch - [null, Inspect, null, Guide, null] +8343 - Spirit Tree - [null, Inspect, null, Guide, null] +8344 - Spirit Tree - [null, Inspect, null, Guide, null] +8345 - Spirit Tree - [null, Inspect, null, Guide, null] +8346 - Spirit Tree - [null, Inspect, null, Guide, null] +8347 - Spirit Tree - [null, Inspect, null, Guide, null] +8348 - Spirit Tree - [null, Inspect, null, Guide, null] +8349 - Spirit Tree - [null, Inspect, null, Guide, null] +8350 - Spirit Tree - [null, Inspect, null, Guide, null] +8351 - Spirit Tree - [null, Inspect, null, Guide, null] +8352 - Spirit Tree - [null, Inspect, null, Guide, null] +8353 - Spirit Tree - [null, Inspect, null, Guide, null] +8354 - Spirit Tree - [null, Inspect, null, Guide, null] +8355 - Spirit Tree - [Talk-to, Inspect, null, Guide, null] +8356 - Spirit Tree - [Check-health, Inspect, null, Guide, null] +8357 - Spirit Tree Stump - [null, Inspect, null, Guide, null] +8358 - Diseased Spirit Tree - [null, Inspect, null, Guide, null] +8359 - Diseased Spirit Tree - [null, Inspect, null, Guide, null] +8360 - Diseased Spirit Tree - [null, Inspect, null, Guide, null] +8361 - Diseased Spirit Tree - [null, Inspect, null, Guide, null] +8362 - Diseased Spirit Tree - [null, Inspect, null, Guide, null] +8363 - Diseased Spirit Tree - [null, Inspect, null, Guide, null] +8364 - Diseased Spirit Tree - [null, Inspect, null, Guide, null] +8365 - Diseased Spirit Tree - [null, Inspect, null, Guide, null] +8366 - Diseased Spirit Tree - [null, Inspect, null, Guide, null] +8367 - Diseased Spirit Tree - [null, Inspect, null, Guide, null] +8368 - Diseased Spirit Tree - [null, Inspect, null, Guide, null] +8369 - Diseased Spirit Tree - [null, Inspect, null, Guide, null] +8370 - Dead Spirit Tree - [null, Inspect, null, Guide, null] +8371 - Dead Spirit Tree - [null, Inspect, null, Guide, null] +8372 - Dead Spirit Tree - [null, Inspect, null, Guide, null] +8373 - Dead Spirit Tree - [null, Inspect, null, Guide, null] +8374 - Dead Spirit Tree - [null, Inspect, null, Guide, null] +8375 - Dead Spirit Tree - [null, Inspect, null, Guide, null] +8376 - Dead Spirit Tree - [null, Inspect, null, Guide, null] +8377 - Dead Spirit Tree - [null, Inspect, null, Guide, null] +8378 - Dead Spirit Tree - [null, Inspect, null, Guide, null] +8379 - Dead Spirit Tree - [null, Inspect, null, Guide, null] +8380 - Dead Spirit Tree - [null, Inspect, null, Guide, null] +8381 - Dead Spirit Tree - [null, Inspect, null, Guide, null] +8382 - null - [null, null, null, null, null] +8383 - null - [null, null, null, null, null] +8384 - null - [null, null, null, null, null] +8385 - null - [null, null, null, null, null] +8386 - null - [null, null, null, null, null] +8387 - null - [null, null, null, null, null] +8388 - null - [null, null, null, null, null] +8389 - null - [null, null, null, null, null] +8390 - null - [null, null, null, null, null] +8391 - null - [null, null, null, null, null] +8392 - Tree patch - [null, Inspect, null, Guide, null] +8393 - Tree patch - [null, Inspect, null, Guide, null] +8394 - Tree patch - [null, Inspect, null, Guide, null] +8395 - Tree patch - [null, Inspect, null, Guide, null] +8396 - Magic Tree - [null, Inspect, null, Guide, null] +8397 - Magic Tree - [null, Inspect, null, Guide, null] +8398 - Magic Tree - [null, Inspect, null, Guide, null] +8399 - Magic Tree - [null, Inspect, null, Guide, null] +8400 - Magic Tree - [null, Inspect, null, Guide, null] +8401 - Magic Tree - [null, Inspect, null, Guide, null] +8402 - Magic Tree - [null, Inspect, null, Guide, null] +8403 - Magic Tree - [null, Inspect, null, Guide, null] +8404 - Magic Tree - [null, Inspect, null, Guide, null] +8405 - Magic Tree - [null, Inspect, null, Guide, null] +8406 - Magic Tree - [null, Inspect, null, Guide, null] +8407 - Magic Tree - [null, Inspect, null, Guide, null] +8408 - Magic Tree - [Check-health, Inspect, null, Guide, null] +8409 - Magic Tree - [Chop down, Inspect, hidden, Guide, null] +8410 - Magic Tree Stump - [null, Inspect, null, Guide, null] +8411 - Diseased Magic Tree - [null, Inspect, null, Guide, null] +8412 - Diseased Magic Tree - [null, Inspect, null, Guide, null] +8413 - Diseased Magic Tree - [null, Inspect, null, Guide, null] +8414 - Diseased Magic Tree - [null, Inspect, null, Guide, null] +8415 - Diseased Magic Tree - [null, Inspect, null, Guide, null] +8416 - Diseased Magic Tree - [null, Inspect, null, Guide, null] +8417 - Diseased Magic Tree - [null, Inspect, null, Guide, null] +8418 - Diseased Magic Tree - [null, Inspect, null, Guide, null] +8419 - Diseased Magic Tree - [null, Inspect, null, Guide, null] +8420 - Diseased Magic Tree - [null, Inspect, null, Guide, null] +8421 - Diseased Magic Tree - [null, Inspect, null, Guide, null] +8422 - Diseased Magic Tree - [null, Inspect, null, Guide, null] +8423 - Dead Magic Tree - [null, Inspect, null, Guide, null] +8424 - Dead Magic Tree - [null, Inspect, null, Guide, null] +8425 - Dead Magic Tree - [null, Inspect, null, Guide, null] +8426 - Dead Magic Tree - [null, Inspect, null, Guide, null] +8427 - Dead Magic Tree - [null, Inspect, null, Guide, null] +8428 - Dead Magic Tree - [null, Inspect, null, Guide, null] +8429 - Dead Magic Tree - [null, Inspect, null, Guide, null] +8430 - Dead Magic Tree - [null, Inspect, null, Guide, null] +8431 - Dead Magic Tree - [null, Inspect, null, Guide, null] +8432 - Dead Magic Tree - [null, Inspect, null, Guide, null] +8433 - Dead Magic Tree - [null, Inspect, null, Guide, null] +8434 - Dead Magic Tree - [null, Inspect, null, Guide, null] +8435 - Maple Tree - [null, Inspect, null, Guide, null] +8436 - Maple Tree - [null, Inspect, null, Guide, null] +8437 - Maple Tree - [null, Inspect, null, Guide, null] +8438 - Maple Tree - [null, Inspect, null, Guide, null] +8439 - Maple Tree - [null, Inspect, null, Guide, null] +8440 - Maple Tree - [null, Inspect, null, Guide, null] +8441 - Maple Tree - [null, Inspect, null, Guide, null] +8442 - Maple Tree - [null, Inspect, null, Guide, null] +8443 - Maple Tree - [Check-health, Inspect, null, Guide, null] +8444 - Maple Tree - [Chop down, Inspect, hidden, Guide, null] +8445 - Maple tree stump - [null, Inspect, null, Guide, null] +8446 - Diseased Maple - [null, Inspect, null, Guide, null] +8447 - Diseased Maple - [null, Inspect, null, Guide, null] +8448 - Diseased Maple - [null, Inspect, null, Guide, null] +8449 - Diseased Maple - [null, Inspect, null, Guide, null] +8450 - Diseased Maple - [null, Inspect, null, Guide, null] +8451 - Diseased Maple - [null, Inspect, null, Guide, null] +8452 - Diseased Maple - [null, Inspect, null, Guide, null] +8453 - Diseased Maple - [null, Inspect, null, Guide, null] +8454 - Dead Maple - [null, Inspect, null, Guide, null] +8455 - Dead Maple - [null, Inspect, null, Guide, null] +8456 - Dead Maple - [null, Inspect, null, Guide, null] +8457 - Dead Maple - [null, Inspect, null, Guide, null] +8458 - Dead Maple - [null, Inspect, null, Guide, null] +8459 - Dead Maple - [null, Inspect, null, Guide, null] +8460 - Dead Maple - [null, Inspect, null, Guide, null] +8461 - Dead Maple - [null, Inspect, null, Guide, null] +8462 - Oak - [null, Inspect, null, Guide, null] +8463 - Oak - [null, Inspect, null, Guide, null] +8464 - Oak - [null, Inspect, null, Guide, null] +8465 - Oak - [null, Inspect, null, Guide, null] +8466 - Oak - [Check-health, Inspect, null, Guide, null] +8467 - Oak - [Chop down, Inspect, hidden, Guide, null] +8468 - Oak tree stump - [null, Inspect, null, Guide, null] +8469 - null - [null, null, null, null, null] +8470 - null - [null, null, null, null, null] +8471 - null - [null, null, null, null, null] +8472 - null - [null, null, null, null, null] +8473 - Diseased Oak - [null, Inspect, null, Guide, null] +8474 - Diseased Oak - [null, Inspect, null, Guide, null] +8475 - Diseased Oak - [null, Inspect, null, Guide, null] +8476 - Diseased Oak - [null, Inspect, null, Guide, null] +8477 - Dead Oak - [null, Inspect, null, Guide, null] +8478 - Dead Oak - [null, Inspect, null, Guide, null] +8479 - Dead Oak - [null, Inspect, null, Guide, null] +8480 - Dead Oak - [null, Inspect, null, Guide, null] +8481 - Willow Tree - [null, Inspect, null, Guide, null] +8482 - Willow Tree - [null, Inspect, null, Guide, null] +8483 - Willow Tree - [null, Inspect, null, Guide, null] +8484 - Willow Tree - [null, Inspect, null, Guide, null] +8485 - Willow Tree - [null, Inspect, null, Guide, null] +8486 - Willow Tree - [null, Inspect, null, Guide, null] +8487 - Willow Tree - [Check-health, Inspect, null, Guide, null] +8488 - Willow Tree - [Chop down, Inspect, hidden, Guide, null] +8489 - Willow tree stump - [null, Inspect, null, Guide, null] +8490 - Diseased Willow - [null, Inspect, null, Guide, null] +8491 - Diseased Willow - [null, Inspect, null, Guide, null] +8492 - Diseased Willow - [null, Inspect, null, Guide, null] +8493 - Diseased Willow - [null, Inspect, null, Guide, null] +8494 - Diseased Willow - [null, Inspect, null, Guide, null] +8495 - Diseased Willow - [null, Inspect, null, Guide, null] +8496 - Dead Willow - [null, Inspect, null, Guide, null] +8497 - Dead Willow - [null, Inspect, null, Guide, null] +8498 - Dead Willow - [null, Inspect, null, Guide, null] +8499 - Dead Willow - [null, Inspect, null, Guide, null] +8500 - Dead Willow - [null, Inspect, null, Guide, null] +8501 - Dead Willow - [null, Inspect, null, Guide, null] +8502 - Yew sapling - [null, Inspect, null, Guide, null] +8503 - Yew tree - [null, Inspect, null, Guide, null] +8504 - Yew tree - [null, Inspect, null, Guide, null] +8505 - Yew tree - [null, Inspect, null, Guide, null] +8506 - Yew tree - [null, Inspect, null, Guide, null] +8507 - Yew tree - [null, Inspect, null, Guide, null] +8508 - Yew tree - [null, Inspect, null, Guide, null] +8509 - Yew tree - [null, Inspect, null, Guide, null] +8510 - Yew tree - [null, Inspect, null, Guide, null] +8511 - Yew tree - [null, Inspect, null, Guide, null] +8512 - Yew tree - [Check-health, Inspect, null, Guide, null] +8513 - Yew tree - [Chop down, Inspect, hidden, Guide, null] +8514 - Yew tree stump - [null, Inspect, null, Guide, null] +8515 - Diseased Yew - [null, Inspect, null, Guide, null] +8516 - Diseased Yew - [null, Inspect, null, Guide, null] +8517 - Diseased Yew - [null, Inspect, null, Guide, null] +8518 - Diseased Yew - [null, Inspect, null, Guide, null] +8519 - Diseased Yew - [null, Inspect, null, Guide, null] +8520 - Diseased Yew - [null, Inspect, null, Guide, null] +8521 - Diseased Yew - [null, Inspect, null, Guide, null] +8522 - Diseased Yew - [null, Inspect, null, Guide, null] +8523 - Diseased Yew - [null, Inspect, null, Guide, null] +8524 - Diseased Yew - [null, Inspect, null, Guide, null] +8525 - Dead Yew - [null, Inspect, null, Guide, null] +8526 - Dead Yew - [null, Inspect, null, Guide, null] +8527 - Dead Yew - [null, Inspect, null, Guide, null] +8528 - Dead Yew - [null, Inspect, null, Guide, null] +8529 - Dead Yew - [null, Inspect, null, Guide, null] +8530 - Dead Yew - [null, Inspect, null, Guide, null] +8531 - Dead Yew - [null, Inspect, null, Guide, null] +8532 - Dead Yew - [null, Inspect, null, Guide, null] +8533 - Dead Yew - [null, Inspect, null, Guide, null] +8534 - Dead Yew - [null, Inspect, null, Guide, null] +8535 - Cabbages - [null, Inspect, null, Guide, null] +8536 - Cabbages - [null, Inspect, null, Guide, null] +8537 - Cabbages - [null, Inspect, null, Guide, null] +8538 - Cabbages - [null, Inspect, null, Guide, null] +8539 - Cabbages - [Harvest, Inspect, null, Guide, null] +8540 - Cabbages - [null, Inspect, null, Guide, null] +8541 - Cabbages - [null, Inspect, null, Guide, null] +8542 - Cabbages - [null, Inspect, null, Guide, null] +8543 - Cabbages - [null, Inspect, null, Guide, null] +8544 - Diseased cabbages - [null, Inspect, null, Guide, null] +8545 - Diseased cabbages - [null, Inspect, null, Guide, null] +8546 - Diseased cabbages - [null, Inspect, null, Guide, null] +8547 - Dead cabbages - [null, Inspect, null, Guide, null] +8548 - Dead cabbages - [null, Inspect, null, Guide, null] +8549 - Dead cabbages - [null, Inspect, null, Guide, null] +8550 - null - [null, null, null, null, null] +8551 - null - [null, null, null, null, null] +8552 - null - [null, null, null, null, null] +8553 - null - [null, null, null, null, null] +8554 - null - [null, null, null, null, null] +8555 - null - [null, null, null, null, null] +8556 - null - [null, null, null, null, null] +8557 - null - [null, null, null, null, null] +8558 - Potato seed - [null, Inspect, null, Guide, null] +8559 - Potato plant - [null, Inspect, null, Guide, null] +8560 - Potato plant - [null, Inspect, null, Guide, null] +8561 - Potato plant - [null, Inspect, null, Guide, null] +8562 - Potato - [Harvest, Inspect, null, Guide, null] +8563 - Potato seed - [null, Inspect, null, Guide, null] +8564 - Potato plant - [null, Inspect, null, Guide, null] +8565 - Potato plant - [null, Inspect, null, Guide, null] +8566 - Potato plant - [null, Inspect, null, Guide, null] +8567 - Diseased potatoes - [null, Inspect, null, Guide, null] +8568 - Diseased potatoes - [null, Inspect, null, Guide, null] +8569 - Diseased potatoes - [null, Inspect, null, Guide, null] +8570 - Dead potatoes - [null, Inspect, null, Guide, null] +8571 - Dead potatoes - [null, Inspect, null, Guide, null] +8572 - Dead potatoes - [null, Inspect, null, Guide, null] +8573 - Allotment - [null, Inspect, null, Guide, null] +8574 - Allotment - [null, Inspect, null, Guide, null] +8575 - Allotment - [null, Inspect, null, Guide, null] +8576 - Allotment - [null, Inspect, null, Guide, null] +8577 - Allotment - [null, Inspect, null, Guide, null] +8578 - Allotment - [null, Inspect, null, Guide, null] +8579 - Allotment - [null, Inspect, null, Guide, null] +8580 - Onion seeds - [null, Inspect, null, Guide, null] +8581 - Onion plant - [null, Inspect, null, Guide, null] +8582 - Onion plant - [null, Inspect, null, Guide, null] +8583 - Onion plant - [null, Inspect, null, Guide, null] +8584 - Onion - [Harvest, Inspect, null, Guide, null] +8585 - Onion seeds - [null, Inspect, null, Guide, null] +8586 - Onion plant - [null, Inspect, null, Guide, null] +8587 - Onion plant - [null, Inspect, null, Guide, null] +8588 - Onion plant - [null, Inspect, null, Guide, null] +8589 - Diseased onions - [null, Inspect, null, Guide, null] +8590 - Diseased onions - [null, Inspect, null, Guide, null] +8591 - Diseased onions - [null, Inspect, null, Guide, null] +8592 - Dead onions - [null, Inspect, null, Guide, null] +8593 - Dead onions - [null, Inspect, null, Guide, null] +8594 - Dead onions - [null, Inspect, null, Guide, null] +8595 - Strawberry seed - [null, Inspect, null, Guide, null] +8596 - Strawberry plant - [null, Inspect, null, Guide, null] +8597 - Strawberry plant - [null, Inspect, null, Guide, null] +8598 - Strawberry plant - [null, Inspect, null, Guide, null] +8599 - Strawberry plant - [null, Inspect, null, Guide, null] +8600 - Strawberry plant - [null, Inspect, null, Guide, null] +8601 - Strawberry - [Harvest, Inspect, null, Guide, null] +8602 - Strawberry seed - [null, Inspect, null, Guide, null] +8603 - Strawberry plant - [null, Inspect, null, Guide, null] +8604 - Strawberry plant - [null, Inspect, null, Guide, null] +8605 - Strawberry plant - [null, Inspect, null, Guide, null] +8606 - Strawberry plant - [null, Inspect, null, Guide, null] +8607 - Strawberry plant - [null, Inspect, null, Guide, null] +8608 - Diseased strawberry plant - [null, Inspect, null, Guide, null] +8609 - Diseased strawberry plant - [null, Inspect, null, Guide, null] +8610 - Diseased strawberry plant - [null, Inspect, null, Guide, null] +8611 - Diseased strawberry plant - [null, Inspect, null, Guide, null] +8612 - Diseased strawberry plant - [null, Inspect, null, Guide, null] +8613 - Dead strawberry plant - [null, Inspect, null, Guide, null] +8614 - Dead strawberry plant - [null, Inspect, null, Guide, null] +8615 - Dead strawberry plant - [null, Inspect, null, Guide, null] +8616 - Dead strawberry plant - [null, Inspect, null, Guide, null] +8617 - Dead strawberry plant - [null, Inspect, null, Guide, null] +8618 - Sweetcorn seed - [null, Inspect, null, Guide, null] +8619 - Sweetcorn plant - [null, Inspect, null, Guide, null] +8620 - Sweetcorn plant - [null, Inspect, null, Guide, null] +8621 - Sweetcorn plant - [null, Inspect, null, Guide, null] +8622 - Sweetcorn plant - [null, Inspect, null, Guide, null] +8623 - Sweetcorn plant - [null, Inspect, null, Guide, null] +8624 - Sweetcorn - [Harvest, Inspect, null, Guide, null] +8625 - Sweetcorn seed - [null, Inspect, null, Guide, null] +8626 - Sweetcorn plant - [null, Inspect, null, Guide, null] +8627 - Sweetcorn plant - [null, Inspect, null, Guide, null] +8628 - Sweetcorn plant - [null, Inspect, null, Guide, null] +8629 - Sweetcorn plant - [null, Inspect, null, Guide, null] +8630 - Sweetcorn plant - [null, Inspect, null, Guide, null] +8631 - Diseased sweetcorn plant - [null, Inspect, null, Guide, null] +8632 - Diseased sweetcorn plant - [null, Inspect, null, Guide, null] +8633 - Diseased sweetcorn plant - [null, Inspect, null, Guide, null] +8634 - Diseased sweetcorn plant - [null, Inspect, null, Guide, null] +8635 - Diseased sweetcorn plant - [null, Inspect, null, Guide, null] +8636 - Dead sweetcorn plant - [null, Inspect, null, Guide, null] +8637 - Dead sweetcorn plant - [null, Inspect, null, Guide, null] +8638 - Dead sweetcorn plant - [null, Inspect, null, Guide, null] +8639 - Dead sweetcorn plant - [null, Inspect, null, Guide, null] +8640 - Dead sweetcorn plant - [null, Inspect, null, Guide, null] +8641 - Tomato plant - [null, Inspect, null, Guide, null] +8642 - Tomato plant - [null, Inspect, null, Guide, null] +8643 - Tomato plant - [null, Inspect, null, Guide, null] +8644 - Tomato plant - [null, Inspect, null, Guide, null] +8645 - Tomato - [Harvest, Inspect, null, Guide, null] +8646 - Tomato plant - [null, Inspect, null, Guide, null] +8647 - Tomato plant - [null, Inspect, null, Guide, null] +8648 - Tomato plant - [null, Inspect, null, Guide, null] +8649 - Tomato plant - [null, Inspect, null, Guide, null] +8650 - Diseased tomato plant - [null, Inspect, null, Guide, null] +8651 - Diseased tomato plant - [null, Inspect, null, Guide, null] +8652 - Diseased tomato plant - [null, Inspect, null, Guide, null] +8653 - Dead tomato plant - [null, Inspect, null, Guide, null] +8654 - Dead tomato plant - [null, Inspect, null, Guide, null] +8655 - Dead tomato plant - [null, Inspect, null, Guide, null] +8656 - Watermelon seed - [null, Inspect, null, Guide, null] +8657 - Watermelons - [null, Inspect, null, Guide, null] +8658 - Watermelons - [null, Inspect, null, Guide, null] +8659 - Watermelons - [null, Inspect, null, Guide, null] +8660 - Watermelons - [null, Inspect, null, Guide, null] +8661 - Watermelons - [null, Inspect, null, Guide, null] +8662 - Watermelons - [null, Inspect, null, Guide, null] +8663 - Watermelons - [null, Inspect, null, Guide, null] +8664 - Watermelon - [Harvest, Inspect, null, Guide, null] +8665 - Watermelon seed - [null, Inspect, null, Guide, null] +8666 - Watermelons - [null, Inspect, null, Guide, null] +8667 - Watermelons - [null, Inspect, null, Guide, null] +8668 - Watermelons - [null, Inspect, null, Guide, null] +8669 - Watermelons - [null, Inspect, null, Guide, null] +8670 - Watermelons - [null, Inspect, null, Guide, null] +8671 - Watermelons - [null, Inspect, null, Guide, null] +8672 - Watermelons - [null, Inspect, null, Guide, null] +8673 - Diseased watermelons - [null, Inspect, null, Guide, null] +8674 - Diseased watermelons - [null, Inspect, null, Guide, null] +8675 - Diseased watermelons - [null, Inspect, null, Guide, null] +8676 - Diseased watermelons - [null, Inspect, null, Guide, null] +8677 - Diseased watermelons - [null, Inspect, null, Guide, null] +8678 - Diseased watermelons - [null, Inspect, null, Guide, null] +8679 - Diseased watermelons - [null, Inspect, null, Guide, null] +8680 - Dead watermelons - [null, Inspect, null, Guide, null] +8681 - Dead watermelons - [null, Inspect, null, Guide, null] +8682 - Dead watermelons - [null, Inspect, null, Guide, null] +8683 - Dead watermelons - [null, Inspect, null, Guide, null] +8684 - Dead watermelons - [null, Inspect, null, Guide, null] +8685 - Dead watermelons - [null, Inspect, null, Guide, null] +8686 - Dead watermelons - [null, Inspect, null, Guide, null] +8687 - null - [null, null, null, null, null] +8688 - Dresser - [null, null, null, null, null] +8689 - Dairy cow - [Milk, Steal-cowbell, null, null, null] +8690 - Milk Urns - [null, null, null, null, null] +8691 - Milk Urns - [null, null, null, null, null] +8692 - null - [null, null, null, null, null] +8693 - null - [null, null, null, null, null] +8694 - null - [null, null, null, null, null] +8695 - Door - [Open, null, null, null, null] +8696 - Door - [Close, null, null, null, null] +8697 - null - [null, null, null, null, null] +8698 - null - [null, null, null, null, null] +8699 - Sink - [null, null, null, null, null] +8700 - Table - [null, null, null, null, null] +8701 - Table - [null, null, null, null, null] +8702 - Water barrel - [null, null, null, null, null] +8703 - Water barrel - [null, null, null, null, null] +8704 - null - [null, null, null, null, null] +8705 - null - [null, null, null, null, null] +8706 - null - [null, null, null, null, null] +8707 - null - [null, null, null, null, null] +8708 - null - [null, null, null, null, null] +8709 - null - [null, null, null, null, null] +8710 - null - [null, null, null, null, null] +8711 - null - [null, null, null, null, null] +8712 - Fireplace - [null, null, null, null, null] +8713 - Hay bale - [null, null, null, null, null] +8714 - Haystack - [null, null, null, null, null] +8715 - Hay bale - [null, null, null, null, null] +8716 - Haystack - [null, null, null, null, null] +8717 - Loom - [null, Weave, null, null, null] +8718 - null - [null, null, null, null, null] +8719 - null - [null, null, null, null, null] +8720 - null - [null, null, null, null, null] +8721 - null - [null, null, null, null, null] +8722 - null - [null, null, null, null, null] +8723 - null - [null, null, null, null, null] +8724 - null - [null, null, null, null, null] +8725 - Rock - [null, null, null, null, null] +8726 - Rock - [null, null, null, null, null] +8727 - Rocks - [null, null, null, null, null] +8728 - Rockslide - [null, null, null, null, null] +8729 - Rockslide - [null, null, null, null, null] +8730 - Rockslide - [null, null, null, null, null] +8731 - Rockslide - [null, null, null, null, null] +8732 - null - [null, null, null, null, null] +8733 - null - [null, null, null, null, null] +8734 - null - [null, null, null, null, null] +8735 - null - [null, null, null, null, null] +8736 - null - [null, null, null, null, null] +8737 - Barrel Tap - [null, null, null, null, null] +8738 - Ardougne Wall Door - [Open, null, null, null, null] +8739 - Ardougne Wall Door - [Open, null, null, null, null] +8740 - Ardougne Wall Door - [Open, null, null, null, null] +8741 - Ardougne Wall Door - [Open, null, null, null, null] +8742 - Tree - [Pass, null, null, null, null] +8743 - Tree - [null, null, null, null, null] +8744 - ladder - [Climb-up, null, null, null, null] +8745 - ladder - [Climb, Climb-up, Climb-down, null, null] +8746 - ladder - [Climb-down, null, null, null, null] +8747 - Well - [null, null, null, null, null] +8748 - Spinning wheel - [null, Spin, null, null, null] +8749 - Altar - [Pray-at, null, null, null, null] +8750 - Cooking range - [null, null, null, null, null] +8751 - Table - [null, null, null, null, null] +8752 - Bookcase - [Search, null, null, null, null] +8753 - Bookcase - [Search, null, null, null, null] +8754 - Bookcase - [Search, null, null, null, null] +8755 - null - [null, null, null, null, null] +8756 - null - [null, null, null, null, null] +8757 - null - [null, null, null, null, null] +8758 - null - [null, null, null, null, null] +8759 - null - [null, null, null, null, null] +8760 - null - [null, null, null, null, null] +8761 - null - [null, null, null, null, null] +8762 - null - [null, null, null, null, null] +8763 - null - [null, null, null, null, null] +8764 - null - [null, null, null, null, null] +8765 - null - [null, null, null, null, null] +8766 - null - [null, null, null, null, null] +8767 - Elven lamp - [null, null, null, null, null] +8768 - Table - [null, null, null, null, null] +8769 - Table - [null, null, null, null, null] +8770 - Chair - [null, null, null, null, null] +8771 - Painting - [null, null, null, null, null] +8772 - Bench - [null, null, null, null, null] +8773 - Bow and Arrow - [null, null, null, null, null] +8774 - null - [null, null, null, null, null] +8775 - Arrows - [null, null, null, null, null] +8776 - Clothing shelves - [null, null, null, null, null] +8777 - null - [null, null, null, null, null] +8778 - Clothes model - [null, null, null, null, null] +8779 - Clothes model - [null, null, null, null, null] +8780 - null - [null, null, null, null, null] +8781 - null - [null, null, null, null, null] +8782 - null - [null, null, null, null, null] +8783 - Trapdoor - [Open, null, null, null, null] +8784 - null - [null, null, null, null, null] +8785 - Ladder - [Climb-up, null, null, null, null] +8786 - Door - [Open, null, null, null, null] +8787 - Door - [Open, null, null, null, null] +8788 - Door - [Open, null, null, null, null] +8789 - Door - [Open, null, null, null, null] +8790 - Door - [null, null, null, null, null] +8791 - Door - [Close, null, null, null, null] +8792 - Door - [null, null, null, null, null] +8793 - Door - [null, null, null, null, null] +8794 - null - [null, null, null, null, null] +8795 - Gnome on a rack - [Talk-to, Release, null, null, null] +8796 - An empty rack - [null, null, null, null, null] +8797 - Closed chest - [Open, null, null, null, null] +8798 - Open chest - [Search, Shut, null, null, null] +8799 - Desk - [Search, null, null, null, null] +8800 - Closed chest - [Open, null, null, null, null] +8801 - Grain sacks - [null, null, null, null, null] +8802 - Grain sacks - [null, null, null, null, null] +8803 - Grain sacks - [null, null, null, null, null] +8804 - Grain sacks - [null, null, null, null, null] +8805 - Grain sacks - [null, null, null, null, null] +8806 - Grain sacks - [null, null, null, null, null] +8807 - Apple Barrel - [null, null, null, null, null] +8808 - Apple Barrel - [null, null, null, null, null] +8809 - Rotten Apple Pile - [Take-from, null, null, null, null] +8810 - Gate - [Open, null, null, null, null] +8811 - Gate - [Open, null, null, null, null] +8812 - Gate - [Close, null, null, null, null] +8813 - Gate - [Close, null, null, null, null] +8814 - Bed - [null, null, null, null, null] +8815 - Bed - [null, null, null, null, null] +8816 - Bed - [null, null, null, null, null] +8817 - Bed - [null, null, null, null, null] +8818 - Door - [Open, null, null, null, null] +8819 - Door - [Close, null, null, null, null] +8820 - Door - [Open, null, null, null, null] +8821 - Door - [Close, null, null, null, null] +8822 - null - [null, null, null, null, null] +8823 - null - [null, null, null, null, null] +8824 - null - [null, null, null, null, null] +8825 - null - [null, null, null, null, null] +8826 - null - [null, null, null, null, null] +8827 - null - [null, null, null, null, null] +8828 - Rocks - [null, null, null, null, null] +8829 - Rocks - [null, null, null, null, null] +8830 - Rocks - [null, null, null, null, null] +8831 - Mine cart - [null, null, null, null, null] +8832 - null - [null, null, null, null, null] +8833 - null - [null, null, null, null, null] +8834 - null - [null, null, null, null, null] +8835 - null - [null, null, null, null, null] +8836 - null - [null, null, null, null, null] +8837 - null - [null, null, null, null, null] +8838 - null - [null, null, null, null, null] +8839 - null - [null, null, null, null, null] +8840 - Stocks - [null, null, null, null, null] +8841 - null - [null, null, null, null, null] +8842 - Apple Tree - [null, null, null, null, null] +8843 - Apple Tree - [null, null, null, null, null] +8844 - null - [Enter, null, null, null, null] +8845 - null - [Enter, null, null, null, null] +8846 - null - [null, null, null, null, null] +8847 - null - [null, null, null, null, null] +8848 - null - [null, null, null, null, null] +8849 - null - [null, null, null, null, null] +8850 - null - [null, null, null, null, null] +8851 - null - [null, null, null, null, null] +8852 - null - [null, null, null, null, null] +8853 - null - [null, null, null, null, null] +8854 - null - [null, null, null, null, null] +8855 - null - [null, null, null, null, null] +8856 - null - [null, null, null, null, null] +8857 - null - [null, null, null, null, null] +8858 - null - [null, null, null, null, null] +8859 - null - [null, null, null, null, null] +8860 - null - [null, null, null, null, null] +8861 - Kelda Hops Patch - [null, null, null, null, null] +8862 - Kelda Hops Patch - [null, null, null, null, null] +8863 - Kelda Hops Patch - [null, null, null, null, null] +8864 - Kelda Hops Patch - [null, null, null, null, null] +8865 - Kelda Hops - [null, Inspect, null, null, null] +8866 - Kelda Hops - [null, Inspect, null, null, null] +8867 - Kelda Hops - [null, Inspect, null, null, null] +8868 - Kelda Hops - [null, Inspect, null, null, null] +8869 - Kelda Hops - [Harvest, Inspect, null, null, null] +8870 - Kelda Stout - [Level, null, null, null, null] +8871 - Fermenting Vat - [null, null, null, null, null] +8872 - Fermenting Vat - [null, null, null, null, null] +8873 - Fermenting Vat - [null, null, null, null, null] +8874 - Fermenting Vat - [null, null, null, null, null] +8875 - null - [null, null, null, null, null] +8876 - null - [null, null, null, null, null] +8877 - null - [null, null, null, null, null] +8878 - Dwarven machinery - [Control, null, null, null, null] +8879 - Box - [Search, null, null, null, null] +8880 - Box - [null, null, null, null, null] +8881 - Cave entrance - [Go-through, null, null, null, null] +8882 - Cave entrance - [null, null, null, null, null] +8883 - Cave entrance - [Enter, null, null, null, null] +8884 - Cave entrance - [Enter, null, null, null, null] +8885 - null - [null, null, null, null, null] +8886 - Buffers - [null, null, null, null, null] +8887 - Track - [null, null, null, null, null] +8888 - Track - [null, null, null, null, null] +8889 - Track - [null, null, null, null, null] +8890 - Track - [null, null, null, null, null] +8891 - Track - [null, null, null, null, null] +8892 - Track - [null, null, null, null, null] +8893 - Track - [null, null, null, null, null] +8894 - Track - [null, null, null, null, null] +8895 - Track - [null, null, null, null, null] +8896 - Track - [null, null, null, null, null] +8897 - Track - [null, null, null, null, null] +8898 - Track - [null, null, null, null, null] +8899 - Track support - [null, null, null, null, null] +8900 - Track support - [null, null, null, null, null] +8901 - Track support - [null, null, null, null, null] +8902 - Track support - [null, null, null, null, null] +8903 - Track support - [null, null, null, null, null] +8904 - Track support - [null, null, null, null, null] +8905 - null - [null, null, null, null, null] +8906 - null - [null, null, null, null, null] +8907 - null - [null, null, null, null, null] +8908 - null - [null, null, null, null, null] +8909 - null - [null, null, null, null, null] +8910 - Bookcase - [Search, null, null, null, null] +8911 - Crate - [null, null, null, null, null] +8912 - Crates - [null, null, null, null, null] +8913 - Crate - [Search, null, null, null, null] +8914 - Crate - [Search, null, null, null, null] +8915 - Crate - [Search, null, null, null, null] +8916 - Crate - [Search, null, null, null, null] +8917 - null - [null, null, null, null, null] +8918 - Banner - [null, null, null, null, null] +8919 - null - [null, null, null, null, null] +8920 - null - [null, null, null, null, null] +8921 - null - [null, null, null, null, null] +8922 - null - [null, null, null, null, null] +8923 - null - [null, null, null, null, null] +8924 - Train cart - [Ride, Return, null, null, null] +8925 - Train cart - [Ride, null, null, null, null] +8926 - Viking Boat - [null, null, null, null, null] +8927 - Well - [null, null, null, null, null] +8928 - null - [null, null, null, null, null] +8929 - Cave entrance - [Enter, null, null, null, null] +8930 - Cave entrance - [Enter, null, null, null, null] +8931 - null - [null, null, null, null, null] +8932 - null - [null, null, null, null, null] +8933 - null - [null, null, null, null, null] +8934 - null - [null, null, null, null, null] +8935 - null - [null, null, null, null, null] +8936 - null - [null, null, null, null, null] +8937 - null - [null, null, null, null, null] +8938 - null - [null, null, null, null, null] +8939 - null - [null, null, null, null, null] +8940 - null - [null, null, null, null, null] +8941 - null - [null, null, null, null, null] +8942 - null - [null, null, null, null, null] +8943 - null - [null, null, null, null, null] +8944 - null - [null, null, null, null, null] +8945 - null - [null, null, null, null, null] +8946 - null - [null, null, null, null, null] +8947 - null - [null, null, null, null, null] +8948 - null - [null, null, null, null, null] +8949 - null - [null, null, null, null, null] +8950 - Rock - [null, null, null, null, null] +8951 - Rock - [null, null, null, null, null] +8952 - Rock - [null, null, null, null, null] +8953 - null - [null, null, null, null, null] +8954 - Flag - [null, null, null, null, null] +8955 - Flag - [null, null, null, null, null] +8956 - Iron ladder - [Climb, Climb-up, Climb-down, null, null] +8957 - null - [null, null, null, null, null] +8958 - Door - [Open, null, null, null, null] +8959 - Door - [Open, null, null, null, null] +8960 - Door - [Open, null, null, null, null] +8961 - Door - [null, null, null, null, null] +8962 - Door - [null, null, null, null, null] +8963 - Door - [null, null, null, null, null] +8964 - null - [null, null, null, null, null] +8965 - null - [null, null, null, null, null] +8966 - Steps - [Climb, null, null, null, null] +8967 - Door - [null, null, null, null, null] +8968 - null - [null, null, null, null, null] +8969 - null - [null, null, null, null, null] +8970 - null - [null, null, null, null, null] +8971 - null - [null, null, null, null, null] +8972 - Portal - [Enter, null, null, null, null] +8973 - Tree - [null, null, null, null, null] +8974 - Tree - [null, null, null, null, null] +8975 - null - [null, null, null, null, null] +8976 - null - [null, null, null, null, null] +8977 - null - [null, null, null, null, null] +8978 - null - [null, null, null, null, null] +8979 - null - [null, null, null, null, null] +8980 - null - [null, null, null, null, null] +8981 - null - [null, null, null, null, null] +8982 - null - [null, null, null, null, null] +8983 - null - [null, null, null, null, null] +8984 - null - [null, null, null, null, null] +8985 - Uncooking pot - [null, null, null, null, null] +8986 - Fishing spot - [Net, hidden, null, null, null] +8987 - Portal - [Enter, null, null, null, null] +8988 - Chest - [Open, null, null, null, null] +8989 - Open Chest - [null, null, null, null, null] +8990 - null - [null, null, null, null, null] +8991 - null - [null, null, null, null, null] +8992 - null - [null, null, null, null, null] +8993 - null - [null, null, null, null, null] +8994 - null - [null, null, null, null, null] +8995 - null - [null, null, null, null, null] +8996 - null - [null, null, null, null, null] +8997 - null - [null, null, null, null, null] +8998 - Appendage - [Operate, null, null, null, null] +8999 - Appendage - [Operate, null, null, null, null] +9000 - Appendage - [Operate, null, null, null, null] +9001 - Appendage - [Operate, null, null, null, null] +9002 - Appendage - [Operate, null, null, null, null] +9003 - Appendage - [Operate, null, null, null, null] +9004 - Appendage - [Operate, null, null, null, null] +9005 - Appendage - [Operate, null, null, null, null] +9006 - Funeral pyre - [null, null, null, null, null] +9007 - Funeral pyre - [null, null, null, null, null] +9008 - Funeral pyre - [Light, null, null, null, null] +9009 - Funeral pyre - [Light, null, null, null, null] +9010 - Light Jungle - [null, null, null, Hack, null] +9011 - Light Jungle - [null, null, null, Hack, null] +9012 - Light Jungle - [null, null, null, Hack, null] +9013 - Light Jungle - [null, null, null, Hack, null] +9014 - Light Jungle - [null, null, null, null, null] +9015 - Medium Jungle - [null, null, null, Hack, null] +9016 - Medium Jungle - [null, null, null, Hack, null] +9017 - Medium Jungle - [null, null, null, Hack, null] +9018 - Medium Jungle - [null, null, null, Hack, null] +9019 - Medium Jungle - [null, null, null, null, null] +9020 - Dense Jungle - [null, null, null, Hack, null] +9021 - Dense Jungle - [null, null, null, Hack, null] +9022 - Dense Jungle - [null, null, null, Hack, null] +9023 - Dense Jungle - [null, null, null, Hack, null] +9024 - Dense Jungle - [null, null, null, null, null] +9025 - Rotten village fence - [Repair, null, null, null, null] +9026 - Partial fence - [Repair, null, null, null, null] +9027 - Short fence - [Repair, null, null, null, null] +9028 - Medium fence - [Repair, null, null, null, null] +9029 - Village fence - [Reinforce, null, null, null, null] +9030 - Gem Rock - [Mine, Prospect, hidden, null, null] +9031 - Gem Rock - [Mine, Prospect, hidden, null, null] +9032 - Gem Rock - [Mine, Prospect, hidden, null, null] +9033 - Gout Tuber Plant - [null, null, null, null, null] +9034 - Mahogany - [Chop down, null, hidden, null, null] +9035 - Tree stump - [null, null, null, null, null] +9036 - Teak - [Chop down, null, hidden, null, null] +9037 - Tree stump - [null, null, null, null, null] +9038 - Hardwood Grove Doors - [Open, Quick-Pay(100), null, null, null] +9039 - Hardwood Grove Doors - [Open, Quick-Pay(100), null, null, null] +9040 - null - [null, null, null, null, null] +9041 - null - [null, null, null, null, null] +9042 - null - [null, null, null, null, null] +9043 - null - [null, null, null, null, null] +9044 - Goutweed - [null, Inspect, null, Guide, null] +9045 - Goutweed - [null, Inspect, null, Guide, null] +9046 - Goutweed - [null, Inspect, null, Guide, null] +9047 - Goutweed - [null, Inspect, null, Guide, null] +9048 - Goutweed - [Pick, Inspect, null, Guide, null] +9049 - Diseased goutweed - [null, Inspect, null, Guide, null] +9050 - Diseased goutweed - [null, Inspect, null, Guide, null] +9051 - Diseased goutweed - [null, Inspect, null, Guide, null] +9052 - Dead goutweed - [null, Inspect, null, Guide, null] +9053 - Dead goutweed - [null, Inspect, null, Guide, null] +9054 - Dead goutweed - [null, Inspect, null, Guide, null] +9055 - null - [null, null, null, null, null] +9056 - null - [null, null, null, null, null] +9057 - null - [null, null, null, null, null] +9058 - Ali M's Market - [null, null, null, null, null] +9059 - Ali M's Market - [null, null, null, null, null] +9060 - Ali M's Market - [null, null, null, null, null] +9061 - Ali M's Market - [null, null, null, null, null] +9062 - Ali M's Market - [null, null, null, null, null] +9063 - Ali M's Market - [null, null, null, null, null] +9064 - Crate - [null, null, null, null, null] +9065 - null - [null, null, null, null, null] +9066 - Crate of rune caskets - [null, null, null, null, null] +9067 - null - [null, null, null, null, null] +9068 - Crate - [null, null, null, null, null] +9069 - null - [null, null, null, null, null] +9070 - Crate - [null, null, null, null, null] +9071 - Crate - [null, null, null, null, null] +9072 - rune casket - [null, null, null, null, null] +9073 - rune casket - [null, null, null, null, null] +9074 - rune casket - [null, null, null, null, null] +9075 - rune casket - [null, null, null, null, null] +9076 - Cloth - [null, null, null, null, null] +9077 - Hanging dye - [null, null, null, null, null] +9078 - Hanging dye - [null, null, null, null, null] +9079 - Dyed fabric - [null, null, null, null, null] +9080 - Dyed fabric - [null, null, null, null, null] +9081 - Dyed fabric - [null, null, null, null, null] +9082 - Table - [null, null, null, null, null] +9083 - Dye Pots - [null, null, null, null, null] +9084 - Stairs - [Climb-down, null, null, null, null] +9085 - Stove - [Refuel, null, null, null, null] +9086 - Stove - [Refuel, null, null, null, null] +9087 - Stove - [Refuel, null, null, null, null] +9088 - Coke - [Collect, null, null, null, null] +9089 - Temperature gauge - [Read, null, null, null, null] +9090 - Pump - [Operate, null, null, null, null] +9091 - Bars - [Retrieve, null, null, null, null] +9092 - null - [null, null, null, null, null] +9093 - Bar dispenser - [Search, null, null, null, null] +9094 - Bar dispenser - [null, null, null, null, null] +9095 - Bar dispenser - [null, null, null, null, null] +9096 - Bar dispenser - [Take, null, null, null, null] +9097 - Pedals - [Pedal, null, null, null, null] +9098 - Melting Pot - [null, null, null, null, null] +9099 - Smoke - [null, null, null, null, null] +9100 - Conveyor belt - [Put-ore-on, null, null, null, null] +9101 - Conveyor belt - [null, null, null, null, null] +9102 - Drive belt - [null, null, null, null, null] +9103 - Drive belt - [Repair, null, null, null, null] +9104 - Cogs - [null, null, null, null, null] +9105 - Cogs - [Repair, null, null, null, null] +9106 - Gear box - [null, null, null, null, null] +9107 - Drive belt - [null, null, null, null, null] +9108 - Cogs - [null, null, null, null, null] +9109 - null - [null, null, null, null, null] +9110 - null - [null, null, null, null, null] +9111 - null - [null, null, null, null, null] +9112 - null - [null, null, null, null, null] +9113 - null - [null, null, null, null, null] +9114 - null - [null, null, null, null, null] +9115 - Smoke - [null, null, null, null, null] +9116 - Pipes - [null, null, null, null, null] +9117 - Pipes - [Repair, null, null, null, null] +9118 - null - [null, null, null, null, null] +9119 - null - [null, null, null, null, null] +9120 - Pipes - [null, null, null, null, null] +9121 - Pipes - [Repair, null, null, null, null] +9122 - null - [null, null, null, null, null] +9123 - Smoke - [null, null, null, null, null] +9124 - null - [null, null, null, null, null] +9125 - null - [null, null, null, null, null] +9126 - null - [null, null, null, null, null] +9127 - null - [null, null, null, null, null] +9128 - null - [null, null, null, null, null] +9129 - null - [null, null, null, null, null] +9130 - null - [null, null, null, null, null] +9131 - null - [null, null, null, null, null] +9132 - null - [null, null, null, null, null] +9133 - null - [null, null, null, null, null] +9134 - null - [null, null, null, null, null] +9135 - null - [null, null, null, null, null] +9136 - null - [null, null, null, null, null] +9137 - null - [null, null, null, null, null] +9138 - Stairs - [Climb-up, null, null, null, null] +9139 - null - [null, null, null, null, null] +9140 - Gate - [Open, null, null, null, null] +9141 - Gate - [Open, null, null, null, null] +9142 - Gate - [null, null, null, null, null] +9143 - Sink - [Fill-bucket, null, null, null, null] +9144 - Candelabrum - [null, null, null, null, null] +9145 - Golden lantern - [null, null, null, null, null] +9146 - Old Bookshelf - [Search, null, null, null, null] +9147 - Old Bookshelf - [Search, null, null, null, null] +9148 - Chair - [null, null, null, null, null] +9149 - Gold Screen - [null, null, null, null, null] +9150 - Wall - [null, null, null, null, null] +9151 - Hole in the wall - [null, null, null, null, null] +9152 - Patched Wall - [null, null, null, null, null] +9153 - null - [null, null, null, null, null] +9154 - null - [null, null, null, null, null] +9155 - Globe of Gielinor - [null, null, null, null, null] +9156 - Study Desk - [null, null, null, null, null] +9157 - Suit of armour - [null, null, null, null, null] +9158 - null - [null, null, null, null, null] +9159 - Candles - [null, null, null, null, null] +9160 - Candles - [null, null, null, null, null] +9161 - Candles - [null, null, null, null, null] +9162 - null - [null, null, null, null, null] +9163 - null - [null, null, null, null, null] +9164 - null - [null, null, null, null, null] +9165 - null - [null, null, null, null, null] +9166 - Delphinium patch - [null, Inspect, null, null, null] +9167 - Delphinium patch - [null, Inspect, null, null, null] +9168 - Delphinium patch - [null, Inspect, null, null, null] +9169 - Delphinium patch - [null, Inspect, null, null, null] +9170 - Delphiniums - [null, null, null, null, null] +9171 - Delphiniums - [null, null, null, null, null] +9172 - Delphiniums - [null, null, null, null, null] +9173 - Delphiniums - [null, null, null, null, null] +9174 - null - [null, null, null, null, null] +9175 - null - [null, null, null, null, null] +9176 - null - [null, null, null, null, null] +9177 - Pink rose bush patch - [null, Inspect, null, null, null] +9178 - Pink rose bush patch - [null, Inspect, null, null, null] +9179 - Pink rose bush patch - [null, Inspect, null, null, null] +9180 - Pink rose bush patch - [null, Inspect, null, null, null] +9181 - White rose bush patch - [null, Inspect, null, null, null] +9182 - White rose bush patch - [null, Inspect, null, null, null] +9183 - White rose bush patch - [null, Inspect, null, null, null] +9184 - White rose bush patch - [null, Inspect, null, null, null] +9185 - Red rose bush patch - [null, Inspect, null, null, null] +9186 - Red rose bush patch - [null, Inspect, null, null, null] +9187 - Red rose bush patch - [null, Inspect, null, null, null] +9188 - Red rose bush patch - [null, Inspect, null, null, null] +9189 - Rose bush - [null, null, null, null, null] +9190 - Rose bush - [null, null, null, null, null] +9191 - Rose bush - [null, null, null, null, null] +9192 - Rose bush - [null, null, null, null, null] +9193 - Rose bush - [null, null, null, null, null] +9194 - Rose bush - [null, null, null, null, null] +9195 - Rose bush - [null, null, null, null, null] +9196 - Rose bush - [null, null, null, null, null] +9197 - null - [null, null, null, null, null] +9198 - null - [null, null, null, null, null] +9199 - Orchids - [null, null, null, null, null] +9200 - Orchids - [null, null, null, null, null] +9201 - Orchids - [null, null, null, null, null] +9202 - Orchids - [null, null, null, null, null] +9203 - Plantpot - [null, Inspect, null, null, null] +9204 - Plantpot - [null, Inspect, null, null, null] +9205 - Yellow orchids - [null, null, null, null, null] +9206 - Yellow orchids - [null, null, null, null, null] +9207 - Yellow orchids - [null, null, null, null, null] +9208 - Yellow orchids - [null, null, null, null, null] +9209 - null - [null, null, null, null, null] +9210 - White Tree patch - [null, Inspect, null, null, null] +9211 - White Tree patch - [null, Inspect, null, null, null] +9212 - White Tree patch - [null, Inspect, null, null, null] +9213 - White Tree patch - [null, Inspect, null, null, null] +9214 - White Tree patch - [null, null, null, null, null] +9215 - White Tree patch - [null, null, null, null, null] +9216 - White Tree patch - [null, null, null, null, null] +9217 - White Tree patch - [null, null, null, null, null] +9218 - White Tree patch - [null, null, null, null, null] +9219 - White Tree patch - [Pick-fruit, null, null, null, null] +9220 - White Tree patch - [Pick-fruit, null, null, null, null] +9221 - White Tree patch - [Pick-fruit, null, null, null, null] +9222 - White Tree patch - [Pick-fruit, null, null, null, null] +9223 - null - [null, null, null, null, null] +9224 - Snowdrop patch - [null, Inspect, null, null, null] +9225 - Snowdrop patch - [null, Inspect, null, null, null] +9226 - Snowdrop patch - [null, Inspect, null, null, null] +9227 - Snowdrop patch - [null, Inspect, null, null, null] +9228 - Snowdrops - [null, null, null, null, null] +9229 - Snowdrops - [null, null, null, null, null] +9230 - Snowdrops - [null, null, null, null, null] +9231 - Snowdrops - [null, null, null, null, null] +9232 - null - [null, null, null, null, null] +9233 - Vine patch - [null, Inspect, null, null, null] +9234 - Vine patch - [null, Inspect, null, null, null] +9235 - Vine patch - [null, Inspect, null, null, null] +9236 - Vine patch - [null, Inspect, null, null, null] +9237 - Vines - [null, null, null, null, null] +9238 - Vines - [null, null, null, null, null] +9239 - Vines - [null, null, null, null, null] +9240 - Vines - [null, null, null, null, null] +9241 - Plinth - [null, null, null, null, null] +9242 - Plinth - [null, null, null, null, null] +9243 - Statue of Saradomin - [null, null, null, null, null] +9244 - Plinth - [null, null, null, null, null] +9245 - Statue - [null, null, null, null, null] +9246 - Statue plinth - [null, Inspect, null, null, null] +9247 - Statue of Saradomin - [null, null, null, null, null] +9248 - Statue plinth - [null, Inspect, null, null, null] +9249 - Statue - [null, null, null, null, null] +9250 - null - [null, null, null, null, null] +9251 - null - [null, null, null, null, null] +9252 - null - [null, null, null, null, null] +9253 - null - [null, null, null, null, null] +9254 - null - [null, null, null, null, null] +9255 - Grapevines - [null, null, null, null, null] +9256 - Diseased Grapevines - [null, null, null, null, null] +9257 - null - [null, null, null, null, null] +9258 - Hole - [Use, null, null, null, null] +9259 - Hole - [Use, null, null, null, null] +9260 - null - [null, null, null, null, null] +9261 - Roses - [Take-seed, null, null, null, null] +9262 - Roses - [Take-seed, null, null, null, null] +9263 - White Tree - [null, null, null, null, null] +9264 - null - [null, null, null, null, null] +9265 - null - [null, null, null, null, null] +9266 - null - [null, null, null, null, null] +9267 - null - [null, null, null, null, null] +9268 - null - [null, null, null, null, null] +9269 - null - [null, null, null, null, null] +9270 - null - [null, null, null, null, null] +9271 - null - [null, null, null, null, null] +9272 - null - [null, null, null, null, null] +9273 - null - [null, null, null, null, null] +9274 - null - [null, null, null, null, null] +9275 - null - [null, null, null, null, null] +9276 - null - [null, null, null, null, null] +9277 - null - [null, null, null, null, null] +9278 - null - [null, null, null, null, null] +9279 - null - [null, null, null, null, null] +9280 - null - [null, null, null, null, null] +9281 - null - [null, null, null, null, null] +9282 - null - [null, null, null, null, null] +9283 - null - [null, null, null, null, null] +9284 - null - [null, null, null, null, null] +9285 - null - [null, null, null, null, null] +9286 - null - [null, null, null, null, null] +9287 - null - [null, null, null, null, null] +9288 - null - [null, null, null, null, null] +9289 - null - [null, null, null, null, null] +9290 - null - [null, null, null, null, null] +9291 - Picnic bench - [null, null, null, null, null] +9292 - Statue - [null, null, null, null, null] +9293 - Obstacle pipe - [Squeeze-through, null, null, null, null] +9294 - Strange floor - [Jump-over, null, null, null, null] +9295 - Obstacle pipe - [Squeeze-through, null, null, null, null] +9296 - Rocks - [Climb, null, null, null, null] +9297 - Rocks - [Climb, null, null, null, null] +9298 - null - [null, null, null, null, null] +9299 - Fence - [Squeeze-through, null, null, null, null] +9300 - Fence - [Jump-over, null, null, null, null] +9301 - Castle wall - [Climb-under, null, null, null, null] +9302 - Hole - [Climb-into, null, null, null, null] +9303 - Rocks - [Climb, null, null, null, null] +9304 - Rocks - [Climb, null, null, null, null] +9305 - Rocks - [Climb, null, null, null, null] +9306 - Rocks - [Climb, null, null, null, null] +9307 - Weathered wall - [Jump-up, null, null, null, null] +9308 - Weathered wall - [Jump-down, null, null, null, null] +9309 - Underwall tunnel - [Climb-into, null, null, null, null] +9310 - Underwall tunnel - [Climb-into, null, null, null, null] +9311 - Underwall tunnel - [Climb-into, null, null, null, null] +9312 - Underwall tunnel - [Climb-into, null, null, null, null] +9313 - Damaged wall - [null, null, null, null, null] +9314 - Jutting wall - [Squeeze-past, null, null, null, null] +9315 - Stepping stone - [Jump-onto, null, null, null, null] +9316 - Rocks - [Climb, null, null, null, null] +9317 - Rocks - [Climb, null, null, null, null] +9318 - null - [null, null, null, null, null] +9319 - Spikey chain - [Climb-up, null, null, null, null] +9320 - Spikey chain - [Climb-down, null, null, null, null] +9321 - Crevice - [Squeeze-through, null, null, null, null] +9322 - Log balance - [Walk-across, null, null, null, null] +9323 - Log balance - [Walk-across, null, null, null, null] +9324 - Log balance - [Walk-across, null, null, null, null] +9325 - Crevice - [Squeeze-through, null, null, null, null] +9326 - Strange floor - [Jump-over, null, null, null, null] +9327 - Rocks - [Climb, null, null, null, null] +9328 - Log balance - [Walk-across, null, null, null, null] +9329 - Log balance - [Walk-across, null, null, null, null] +9330 - Log balance - [Walk-across, null, null, null, null] +9331 - Rocks - [Climb, null, null, null, null] +9332 - Rocks - [Climb, null, null, null, null] +9333 - null - [null, null, null, null, null] +9334 - Ornate railing - [Squeeze-through, null, null, null, null] +9335 - Rocks - [Climb, null, null, null, null] +9336 - Rocks - [Climb, null, null, null, null] +9337 - Ornate railing - [Squeeze-through, null, null, null, null] +9338 - Scarecrow - [null, Inspect, null, Guide, null] +9339 - Scarecrow - [null, Inspect, null, Guide, null] +9340 - Scarecrow - [null, Inspect, null, Guide, null] +9341 - null - [null, null, null, null, null] +9342 - null - [null, null, null, null, null] +9343 - null - [null, null, null, null, null] +9344 - null - [null, null, null, null, null] +9345 - null - [null, null, null, null, null] +9346 - null - [null, null, null, null, null] +9347 - null - [null, null, null, null, null] +9348 - null - [null, null, null, null, null] +9349 - null - [null, null, null, null, null] +9350 - null - [null, null, null, null, null] +9351 - null - [null, null, null, null, null] +9352 - null - [null, null, null, null, null] +9353 - null - [null, null, null, null, null] +9354 - Cave exit - [null, null, null, null, null] +9355 - Cave entrance - [null, null, null, null, null] +9356 - Cave entrance - [Enter, null, null, null, null] +9357 - Cave entrance - [Enter, null, null, null, null] +9358 - Crack in wall - [Go-through, null, null, null, null] +9359 - Cave exit - [Enter, null, null, null, null] +9360 - null - [null, null, null, null, null] +9361 - null - [null, null, null, null, null] +9362 - null - [null, null, null, null, null] +9363 - null - [null, null, null, null, null] +9364 - null - [null, null, null, null, null] +9365 - null - [null, null, null, null, null] +9366 - Open hot vent door - [null, null, null, null, null] +9367 - Hot vent door - [Pass, null, null, null, null] +9368 - Hot vent door - [Pass, null, null, null, null] +9369 - Hot vent door - [Pass, null, null, null, null] +9370 - null - [null, null, null, null, null] +9371 - null - [null, null, null, null, null] +9372 - null - [null, null, null, null, null] +9373 - null - [null, null, null, null, null] +9374 - Sulphur vent - [null, null, null, null, null] +9375 - null - [null, null, null, null, null] +9376 - Obsidian wall - [Mine, Prospect, hidden, null, null] +9377 - Egg - [null, null, null, null, null] +9378 - Egg - [null, null, null, null, null] +9379 - Egg - [null, null, null, null, null] +9380 - TzHaar statue - [null, null, null, null, null] +9381 - Crate - [null, null, null, null, null] +9382 - Crates - [null, null, null, null, null] +9383 - null - [null, null, null, null, null] +9384 - null - [null, null, null, null, null] +9385 - null - [null, null, null, null, null] +9386 - null - [null, null, null, null, null] +9387 - null - [null, null, null, null, null] +9388 - null - [null, null, null, null, null] +9389 - null - [null, null, null, null, null] +9390 - Lava forge - [null, Smelt, null, null, null] +9391 - Viewing orb - [Look-into, null, null, null, null] +9392 - null - [null, null, null, null, null] +9393 - null - [null, null, null, null, null] +9394 - null - [null, null, null, null, null] +9395 - null - [null, null, null, null, null] +9396 - null - [null, null, null, null, null] +9397 - null - [null, null, null, null, null] +9398 - Bank Deposit Box - [Deposit, null, null, null, null] +9399 - null - [null, null, null, null, null] +9400 - Unferth's patch - [null, null, null, null, null] +9401 - Unferth's patch - [null, null, null, null, null] +9402 - Unferth's patch - [null, null, null, null, null] +9403 - Unferth's patch - [null, null, null, null, null] +9404 - Potato plants - [null, null, null, null, null] +9405 - Potato plants - [null, null, null, null, null] +9406 - Potato plants - [null, null, null, null, null] +9407 - Potato plants - [null, null, null, null, null] +9408 - Potatoes - [null, null, null, null, null] +9409 - null - [null, null, null, null, null] +9410 - null - [null, null, null, null, null] +9411 - null - [null, null, null, null, null] +9412 - null - [null, null, null, null, null] +9413 - null - [null, null, null, null, null] +9414 - null - [null, null, null, null, null] +9415 - null - [null, null, null, null, null] +9416 - null - [null, null, null, null, null] +9417 - null - [null, null, null, null, null] +9418 - null - [null, null, null, null, null] +9419 - null - [null, null, null, null, null] +9420 - null - [null, null, null, null, null] +9421 - null - [null, null, null, null, null] +9422 - null - [null, null, null, null, null] +9423 - null - [null, null, null, null, null] +9424 - null - [null, null, null, null, null] +9425 - null - [null, null, null, null, null] +9426 - null - [null, null, null, null, null] +9427 - null - [null, null, null, null, null] +9428 - null - [null, null, null, null, null] +9429 - null - [null, null, null, null, null] +9430 - Table - [Inspect, null, null, null, null] +9431 - Table - [Inspect, null, null, null, null] +9432 - Table - [Inspect, null, null, null, null] +9433 - Table - [Inspect, null, null, null, null] +9434 - Table - [Inspect, null, null, null, null] +9435 - null - [null, null, null, null, null] +9436 - Bed - [null, null, null, null, null] +9437 - Bed - [Make, null, null, null, null] +9438 - null - [null, null, null, null, null] +9439 - Fireplace - [null, null, null, null, null] +9440 - Fireplace - [null, null, null, null, null] +9441 - Fireplace - [null, null, null, null, null] +9442 - null - [null, null, null, null, null] +9443 - Bookcase - [Search, null, null, null, null] +9444 - null - [null, null, null, null, null] +9445 - null - [null, null, null, null, null] +9446 - null - [null, null, null, null, null] +9447 - null - [null, null, null, null, null] +9448 - null - [null, null, null, null, null] +9449 - null - [null, null, null, null, null] +9450 - null - [null, null, null, null, null] +9451 - null - [null, null, null, null, null] +9452 - null - [null, null, null, null, null] +9453 - null - [null, null, null, null, null] +9454 - null - [null, null, null, null, null] +9455 - null - [null, null, null, null, null] +9456 - null - [null, null, null, null, null] +9457 - null - [null, null, null, null, null] +9458 - null - [null, null, null, null, null] +9459 - null - [null, null, null, null, null] +9460 - null - [null, null, null, null, null] +9461 - null - [null, null, null, null, null] +9462 - null - [null, null, null, null, null] +9463 - null - [null, null, null, null, null] +9464 - null - [null, null, null, null, null] +9465 - null - [null, null, null, null, null] +9466 - null - [null, null, null, null, null] +9467 - null - [null, null, null, null, null] +9468 - null - [null, null, null, null, null] +9469 - null - [null, null, null, null, null] +9470 - Staircase - [Climb-up, null, null, null, null] +9471 - Staircase - [Climb-down, null, null, null, null] +9472 - Trapdoor - [Climb-down, null, null, null, null] +9473 - null - [null, null, null, null, null] +9474 - null - [null, null, null, null, null] +9475 - null - [null, null, null, null, null] +9476 - null - [null, null, null, null, null] +9477 - null - [null, null, null, null, null] +9478 - null - [null, null, null, null, null] +9479 - null - [null, null, null, null, null] +9480 - null - [null, null, null, null, null] +9481 - null - [null, null, null, null, null] +9482 - null - [null, null, null, null, null] +9483 - null - [null, null, null, null, null] +9484 - null - [null, null, null, null, null] +9485 - null - [null, null, null, null, null] +9486 - null - [null, null, null, null, null] +9487 - null - [null, null, null, null, null] +9488 - null - [null, null, null, null, null] +9489 - null - [null, null, null, null, null] +9490 - null - [null, null, null, null, null] +9491 - null - [null, null, null, null, null] +9492 - null - [null, null, null, null, null] +9493 - null - [null, null, null, null, null] +9494 - null - [null, null, null, null, null] +9495 - null - [null, null, null, null, null] +9496 - null - [null, null, null, null, null] +9497 - null - [null, null, null, null, null] +9498 - Plant - [null, null, null, null, null] +9499 - Plant - [null, null, null, null, null] +9500 - Plant - [null, null, null, null, null] +9501 - Plant - [null, null, null, null, null] +9502 - null - [null, null, null, null, null] +9503 - null - [null, null, null, null, null] +9504 - null - [null, null, null, null, null] +9505 - null - [null, null, null, null, null] +9506 - null - [null, null, null, null, null] +9507 - null - [null, null, null, null, null] +9508 - Hammock - [null, null, null, null, null] +9509 - Bed - [null, null, null, null, null] +9510 - Signpost - [null, null, null, null, null] +9511 - null - [null, null, null, null, null] +9512 - null - [null, null, null, null, null] +9513 - null - [null, null, null, null, null] +9514 - Chair - [null, null, null, null, null] +9515 - Betty's cauldron - [null, null, null, null, null] +9516 - Counter - [null, null, null, null, null] +9517 - null - [null, null, null, null, null] +9518 - null - [null, null, null, null, null] +9519 - Barrel - [null, null, null, null, null] +9520 - Barrel - [null, null, null, null, null] +9521 - Barrel - [null, null, null, null, null] +9522 - Anchor - [null, null, null, null, null] +9523 - Bookcase - [Search, null, null, null, null] +9524 - Chain - [null, null, null, null, null] +9525 - Cart - [null, null, null, null, null] +9526 - Shelves - [null, null, null, null, null] +9527 - Shelves - [null, null, null, null, null] +9528 - Shelves - [null, null, null, null, null] +9529 - Shelves - [null, null, null, null, null] +9530 - Fungus - [null, null, null, null, null] +9531 - Bench - [null, null, null, null, null] +9532 - Picnic bench - [null, null, null, null, null] +9533 - Crate - [Search, null, null, null, null] +9534 - Crate - [Search, null, null, null, null] +9535 - Crates - [Search, null, null, null, null] +9536 - Boxes - [Search, null, null, null, null] +9537 - Crane - [null, null, null, null, null] +9538 - Row boat - [null, null, null, null, null] +9539 - null - [null, null, null, null, null] +9540 - null - [null, null, null, null, null] +9541 - null - [null, null, null, null, null] +9542 - null - [null, null, null, null, null] +9543 - null - [null, null, null, null, null] +9544 - null - [null, null, null, null, null] +9545 - null - [null, null, null, null, null] +9546 - null - [null, null, null, null, null] +9547 - null - [null, null, null, null, null] +9548 - Hot Coals - [null, null, null, null, null] +9549 - Hot Coals - [null, null, null, null, null] +9550 - null - [null, null, null, null, null] +9551 - null - [null, null, null, null, null] +9552 - null - [null, null, null, null, null] +9553 - null - [null, null, null, null, null] +9554 - null - [null, null, null, null, null] +9555 - null - [null, null, null, null, null] +9556 - null - [null, null, null, null, null] +9557 - null - [null, null, null, null, null] +9558 - Ladder - [Climb-up, null, null, null, null] +9559 - Ladder - [Climb-down, null, null, null, null] +9560 - Trapdoor - [Climb-down, null, null, null, null] +9561 - Bed - [null, null, null, null, null] +9562 - Cell door - [Open, null, null, null, null] +9563 - Cell door - [Open, null, null, null, null] +9564 - Cell door - [Close, null, null, null, null] +9565 - Door - [Open, null, null, null, Pick-lock] +9566 - null - [null, null, null, null, null] +9567 - Bucket - [null, null, null, null, null] +9568 - Bucket - [null, null, null, null, null] +9569 - null - [null, null, null, null, null] +9570 - null - [null, null, null, null, null] +9571 - null - [null, null, null, null, null] +9572 - null - [null, null, null, null, null] +9573 - null - [null, null, null, null, null] +9574 - null - [null, null, null, null, null] +9575 - null - [null, null, null, null, null] +9576 - null - [null, null, null, null, null] +9577 - null - [null, null, null, null, null] +9578 - null - [null, null, null, null, null] +9579 - null - [null, null, null, null, null] +9580 - null - [null, null, null, null, null] +9581 - null - [null, null, null, null, null] +9582 - Staircase - [Climb-up, null, null, null, null] +9583 - null - [null, null, null, null, null] +9584 - Staircase - [Climb-down, null, null, null, null] +9585 - null - [null, null, null, null, null] +9586 - null - [null, null, null, null, null] +9587 - null - [null, null, null, null, null] +9588 - null - [null, null, null, null, null] +9589 - null - [null, null, null, null, null] +9590 - null - [null, null, null, null, null] +9591 - null - [null, null, null, null, null] +9592 - null - [null, null, null, null, null] +9593 - null - [null, null, null, null, null] +9594 - null - [null, null, null, null, null] +9595 - null - [null, null, null, null, null] +9596 - null - [null, null, null, null, null] +9597 - null - [null, null, null, null, null] +9598 - null - [null, null, null, null, null] +9599 - null - [null, null, null, null, null] +9600 - null - [null, null, null, null, null] +9601 - null - [null, null, null, null, null] +9602 - null - [null, null, null, null, null] +9603 - null - [null, null, null, null, null] +9604 - Plant - [null, null, null, null, null] +9605 - Plant - [null, null, null, null, null] +9606 - Plant - [null, null, null, null, null] +9607 - Bookcase - [Search, null, null, null, null] +9608 - Bookcase - [Search, null, null, null, null] +9609 - Bookcase - [Search, null, null, null, null] +9610 - Easel - [null, null, null, null, null] +9611 - Bookcase - [Search, null, null, null, null] +9612 - Bed - [null, null, null, null, null] +9613 - Large Table - [null, null, null, null, null] +9614 - Table - [null, null, null, null, null] +9615 - Small Table - [null, null, null, null, null] +9616 - Counter - [null, null, null, null, null] +9617 - Warehouse shelves - [null, null, null, null, null] +9618 - Warehouse shelves - [null, null, null, null, null] +9619 - Warehouse shelves - [null, null, null, null, null] +9620 - Warehouse shelves - [null, null, null, null, null] +9621 - Chair - [null, null, null, null, null] +9622 - Chair - [null, null, null, null, null] +9623 - null - [null, null, null, null, null] +9624 - Plough - [null, null, null, null, null] +9625 - Wheelbarrow - [null, null, null, null, null] +9626 - null - [null, null, null, null, null] +9627 - null - [null, null, null, null, null] +9628 - null - [null, null, null, null, null] +9629 - null - [null, null, null, null, null] +9630 - null - [null, null, null, null, null] +9631 - null - [null, null, null, null, null] +9632 - null - [null, null, null, null, null] +9633 - null - [null, null, null, null, null] +9634 - null - [null, null, null, null, null] +9635 - null - [null, null, null, null, null] +9636 - null - [null, null, null, null, null] +9637 - null - [null, null, null, null, null] +9638 - null - [null, null, null, null, null] +9639 - null - [null, null, null, null, null] +9640 - null - [null, null, null, null, null] +9641 - null - [null, null, null, null, null] +9642 - null - [null, null, null, null, null] +9643 - null - [null, null, null, null, null] +9644 - null - [null, null, null, null, null] +9645 - null - [null, null, null, null, null] +9646 - null - [null, null, null, null, null] +9647 - null - [null, null, null, null, null] +9648 - null - [null, null, null, null, null] +9649 - null - [null, null, null, null, null] +9650 - null - [null, null, null, null, null] +9651 - null - [null, null, null, null, null] +9652 - null - [null, null, null, null, null] +9653 - null - [null, null, null, null, null] +9654 - null - [null, null, null, null, null] +9655 - null - [null, null, null, null, null] +9656 - null - [null, null, null, null, null] +9657 - null - [null, null, null, null, null] +9658 - null - [null, null, null, null, null] +9659 - null - [null, null, null, null, null] +9660 - null - [null, null, null, null, null] +9661 - Tree stump - [null, null, null, null, null] +9662 - Spade - [Take, null, null, null, null] +9663 - Fallen tree - [null, null, null, null, null] +9664 - Roots - [null, null, null, null, null] +9665 - Roots - [null, null, null, null, null] +9666 - Roots - [null, null, null, null, null] +9667 - Scarecrow - [null, null, null, null, null] +9668 - Mysterious statue - [null, null, null, null, null] +9669 - null - [null, null, null, null, null] +9670 - null - [null, null, null, null, null] +9671 - null - [null, null, null, null, null] +9672 - null - [null, null, null, null, null] +9673 - null - [null, null, null, null, null] +9674 - null - [null, null, null, null, null] +9675 - null - [null, null, null, null, null] +9676 - null - [null, null, null, null, null] +9677 - null - [null, null, null, null, null] +9678 - null - [null, null, null, null, null] +9679 - null - [null, null, null, null, null] +9680 - null - [null, null, null, null, null] +9681 - null - [null, null, null, null, null] +9682 - Range - [null, null, null, null, null] +9683 - Range chimney - [null, null, null, null, null] +9684 - Sink - [null, null, null, null, null] +9685 - Table - [null, null, null, null, null] +9686 - Cloth - [null, null, null, null, null] +9687 - Clothes model - [null, null, null, null, null] +9688 - Clothes model - [null, null, null, null, null] +9689 - Clothes model - [null, null, null, null, null] +9690 - Clothes model - [null, null, null, null, null] +9691 - null - [null, null, null, null, null] +9692 - null - [null, null, null, null, null] +9693 - null - [null, null, null, null, null] +9694 - Noticeboard - [null, null, null, null, null] +9695 - Noticeboard - [null, null, null, null, null] +9696 - Sign - [null, null, null, null, null] +9697 - Large Table - [null, null, null, null, null] +9698 - Large Table - [null, null, null, null, null] +9699 - Large Table - [null, null, null, null, null] +9700 - Large Table - [null, null, null, null, null] +9701 - null - [null, null, null, null, null] +9702 - Table - [null, null, null, null, null] +9703 - Candlestick holder - [null, null, null, null, null] +9704 - Chair - [null, null, null, null, null] +9705 - Chair - [null, null, null, null, null] +9706 - Lever - [Pull, null, null, null, null] +9707 - Lever - [Pull, null, null, null, null] +9708 - Rocks - [Mine, Prospect, hidden, null, null] +9709 - Rocks - [Mine, Prospect, hidden, null, null] +9710 - Rocks - [Mine, Prospect, hidden, null, null] +9711 - Rocks - [Mine, Prospect, hidden, null, null] +9712 - Rocks - [Mine, Prospect, hidden, null, null] +9713 - Rocks - [Mine, Prospect, hidden, null, null] +9714 - Rocks - [Mine, Prospect, hidden, null, null] +9715 - Rocks - [Mine, Prospect, hidden, null, null] +9716 - Rocks - [Mine, Prospect, hidden, null, null] +9717 - Rocks - [Mine, Prospect, hidden, null, null] +9718 - Rocks - [Mine, Prospect, hidden, null, null] +9719 - Rocks - [Mine, Prospect, hidden, null, null] +9720 - Rocks - [Mine, Prospect, hidden, null, null] +9721 - Rocks - [Mine, Prospect, hidden, null, null] +9722 - Rocks - [Mine, Prospect, hidden, null, null] +9723 - Rocks - [Mine, Prospect, hidden, null, null] +9724 - Rocks - [Mine, Prospect, hidden, null, null] +9725 - Rocks - [Mine, Prospect, hidden, null, null] +9726 - Rocks - [Mine, Prospect, hidden, null, null] +9727 - Rocks - [Mine, Prospect, hidden, null, null] +9728 - Rocks - [Mine, Prospect, hidden, null, null] +9729 - Rocks - [Mine, Prospect, hidden, null, null] +9730 - Rocks - [Mine, Prospect, hidden, null, null] +9731 - Rocks - [Mine, Prospect, hidden, null, null] +9732 - Rocks - [Mine, Prospect, hidden, null, null] +9733 - Rocks - [Mine, Prospect, hidden, null, null] +9734 - Rocks - [Mine, Prospect, hidden, null, null] +9735 - Rocks - [Mine, Prospect, hidden, null, null] +9736 - Rocks - [Mine, Prospect, hidden, null, null] +9737 - Rocks - [Mine, Prospect, hidden, null, null] +9738 - Ruined Pillar - [null, null, null, null, null] +9739 - Ruined Pillar - [null, null, null, null, null] +9740 - Ruined Pillar - [null, null, null, null, null] +9741 - Trawler net - [null, null, null, null, null] +9742 - Trawler net - [null, null, null, null, null] +9743 - null - [null, null, null, null, null] +9744 - Ship's ladder - [Climb-up, null, null, null, null] +9745 - Ship's ladder - [Climb-down, null, null, null, null] +9746 - null - [null, null, null, null, null] +9747 - null - [null, null, null, null, null] +9748 - Crystal collector - [Collect, null, null, null, null] +9749 - Crystal collector - [Pull, null, null, null, null] +9750 - null - [null, null, null, null, null] +9751 - Crystal - [Search, null, null, null, null] +9752 - Crystal - [null, null, null, null, null] +9753 - Open chest - [Search, Shut, null, null, null] +9754 - Closed chest - [Open, null, null, null, null] +9755 - Open chest - [Search, Shut, null, null, null] +9756 - Closed chest - [Open, null, null, null, null] +9757 - Open chest - [Search, Shut, null, null, null] +9758 - Closed chest - [Open, null, null, null, null] +9759 - Open chest - [Search, Shut, null, null, null] +9760 - Closed chest - [Open, null, null, null, null] +9761 - Open chest - [Search, Shut, null, null, null] +9762 - Closed chest - [Open, null, null, null, null] +9763 - Guard - [Search, null, null, null, null] +9764 - Guard - [Search, null, null, null, null] +9765 - Guard - [Search, null, null, null, null] +9766 - Slave - [Search, null, null, null, null] +9767 - Slave - [Search, null, null, null, null] +9768 - Light door - [null, null, null, null, null] +9769 - Light door - [null, null, null, null, null] +9770 - Light door - [null, null, null, null, null] +9771 - Light door - [null, null, null, null, null] +9772 - Light door - [null, null, null, null, null] +9773 - Light door - [null, null, null, null, null] +9774 - Light door - [null, null, null, null, null] +9775 - Light door - [Pass-through, null, null, null, null] +9776 - null - [Pass, null, null, null, null] +9777 - null - [Pass, null, null, null, null] +9778 - null - [Pass, null, null, null, null] +9779 - null - [Pass, null, null, null, null] +9780 - null - [Pass, null, null, null, null] +9781 - null - [Pass, null, null, null, null] +9782 - null - [Pass, null, null, null, null] +9783 - null - [Pass, null, null, null, null] +9784 - null - [Pass, null, null, null, null] +9785 - null - [Pass, null, null, null, null] +9786 - null - [Pass, null, null, null, null] +9787 - null - [Pass, null, null, null, null] +9788 - null - [Pass, null, null, null, null] +9789 - null - [null, null, null, null, null] +9790 - null - [null, null, null, null, null] +9791 - null - [null, null, null, null, null] +9792 - null - [null, null, null, null, null] +9793 - null - [null, null, null, null, null] +9794 - null - [null, null, null, null, null] +9795 - null - [null, null, null, null, null] +9796 - null - [null, null, null, null, null] +9797 - null - [null, null, null, null, null] +9798 - null - [null, null, null, null, null] +9799 - null - [null, null, null, null, null] +9800 - null - [null, null, null, null, null] +9801 - null - [null, null, null, null, null] +9802 - null - [null, null, null, null, null] +9803 - null - [null, null, null, null, null] +9804 - null - [null, null, null, null, null] +9805 - null - [null, null, null, null, null] +9806 - null - [null, null, null, null, null] +9807 - null - [null, null, null, null, null] +9808 - null - [null, null, null, null, null] +9809 - null - [null, null, null, null, null] +9810 - null - [null, null, null, null, null] +9811 - null - [null, null, null, null, null] +9812 - null - [null, null, null, null, null] +9813 - null - [null, null, null, null, null] +9814 - null - [null, null, null, null, null] +9815 - null - [null, null, null, null, null] +9816 - null - [null, null, null, null, null] +9817 - null - [null, null, null, null, null] +9818 - null - [null, null, null, null, null] +9819 - null - [null, null, null, null, null] +9820 - null - [null, null, null, null, null] +9821 - null - [null, null, null, null, null] +9822 - null - [null, null, null, null, null] +9823 - null - [null, null, null, null, null] +9824 - null - [null, null, null, null, null] +9825 - null - [null, null, null, null, null] +9826 - null - [null, null, null, null, null] +9827 - null - [null, null, null, null, null] +9828 - null - [null, null, null, null, null] +9829 - null - [null, null, null, null, null] +9830 - null - [null, null, null, null, null] +9831 - null - [null, null, null, null, null] +9832 - null - [null, null, null, null, null] +9833 - null - [null, null, null, null, null] +9834 - null - [null, null, null, null, null] +9835 - null - [null, null, null, null, null] +9836 - null - [null, null, null, null, null] +9837 - null - [null, null, null, null, null] +9838 - null - [null, null, null, null, null] +9839 - null - [null, null, null, null, null] +9840 - null - [null, null, null, null, null] +9841 - null - [null, null, null, null, null] +9842 - null - [null, null, null, null, null] +9843 - null - [null, null, null, null, null] +9844 - null - [null, null, null, null, null] +9845 - null - [null, null, null, null, null] +9846 - null - [null, null, null, null, null] +9847 - null - [null, null, null, null, null] +9848 - null - [null, null, null, null, null] +9849 - null - [null, null, null, null, null] +9850 - null - [null, null, null, null, null] +9851 - null - [null, null, null, null, null] +9852 - null - [null, null, null, null, null] +9853 - null - [null, null, null, null, null] +9854 - null - [null, null, null, null, null] +9855 - null - [null, null, null, null, null] +9856 - null - [null, null, null, null, null] +9857 - null - [null, null, null, null, null] +9858 - null - [null, null, null, null, null] +9859 - null - [null, null, null, null, null] +9860 - null - [null, null, null, null, null] +9861 - null - [null, null, null, null, null] +9862 - null - [null, null, null, null, null] +9863 - null - [null, null, null, null, null] +9864 - null - [null, null, null, null, null] +9865 - null - [null, null, null, null, null] +9866 - null - [null, null, null, null, null] +9867 - null - [null, null, null, null, null] +9868 - null - [null, null, null, null, null] +9869 - null - [null, null, null, null, null] +9870 - null - [null, null, null, null, null] +9871 - null - [null, null, null, null, null] +9872 - null - [null, null, null, null, null] +9873 - null - [null, null, null, null, null] +9874 - null - [null, null, null, null, null] +9875 - null - [null, null, null, null, null] +9876 - null - [null, null, null, null, null] +9877 - null - [null, null, null, null, null] +9878 - null - [null, null, null, null, null] +9879 - null - [null, null, null, null, null] +9880 - null - [null, null, null, null, null] +9881 - null - [null, null, null, null, null] +9882 - null - [null, null, null, null, null] +9883 - null - [null, null, null, null, null] +9884 - null - [null, null, null, null, null] +9885 - null - [null, null, null, null, null] +9886 - null - [null, null, null, null, null] +9887 - null - [null, null, null, null, null] +9888 - null - [null, null, null, null, null] +9889 - null - [null, null, null, null, null] +9890 - null - [null, null, null, null, null] +9891 - null - [null, null, null, null, null] +9892 - null - [null, null, null, null, null] +9893 - null - [null, null, null, null, null] +9894 - null - [null, null, null, null, null] +9895 - null - [null, null, null, null, null] +9896 - null - [null, null, null, null, null] +9897 - null - [null, null, null, null, null] +9898 - Pillar of Light - [Search, null, null, null, null] +9899 - Pillar of Light - [Search, null, null, null, null] +9900 - Pillar of Light - [Search, null, null, null, null] +9901 - Pillar of Light - [Search, null, null, null, null] +9902 - Pillar of Light - [Search, null, null, null, null] +9903 - Pillar of Light - [Search, null, null, null, null] +9904 - Pillar of Light - [Search, null, null, null, null] +9905 - Pillar of Light - [Search, null, null, null, null] +9906 - Pillar of Light - [Search, null, null, null, null] +9907 - Pillar of Light - [Search, null, null, null, null] +9908 - Pillar of Light - [Search, null, null, null, null] +9909 - Pillar of Light - [Search, null, null, null, null] +9910 - Pillar of Light - [Search, null, null, null, null] +9911 - Pillar of Light - [Search, null, null, null, null] +9912 - Pillar of Light - [Search, null, null, null, null] +9913 - Pillar of Light - [Search, null, null, null, null] +9914 - Pillar of Light - [Search, null, null, null, null] +9915 - Pillar of Light - [Search, null, null, null, null] +9916 - Pillar of Light - [Search, null, null, null, null] +9917 - Pillar of Light - [Search, null, null, null, null] +9918 - Pillar of Light - [Search, null, null, null, null] +9919 - Pillar of Light - [Search, null, null, null, null] +9920 - Pillar of Light - [Search, null, null, null, null] +9921 - Pillar of Light - [Search, null, null, null, null] +9922 - Pillar of Light - [Search, null, null, null, null] +9923 - Pillar of Light - [Search, null, null, null, null] +9924 - Pillar of Light - [Search, null, null, null, null] +9925 - Pillar of Light - [Search, null, null, null, null] +9926 - Pillar of Light - [Search, null, null, null, null] +9927 - Pillar of Light - [Search, null, null, null, null] +9928 - Pillar of Light - [Search, null, null, null, null] +9929 - Pillar of Light - [Search, null, null, null, null] +9930 - Pillar of Light - [Search, null, null, null, null] +9931 - Pillar of Light - [Search, null, null, null, null] +9932 - Pillar of Light - [Search, null, null, null, null] +9933 - Pillar of Light - [Search, null, null, null, null] +9934 - Pillar of Light - [Search, null, null, null, null] +9935 - Pillar of Light - [Search, null, null, null, null] +9936 - Pillar of Light - [Search, null, null, null, null] +9937 - Pillar of Light - [Search, null, null, null, null] +9938 - null - [null, null, null, null, null] +9939 - null - [null, null, null, null, null] +9940 - null - [null, null, null, null, null] +9941 - null - [null, null, null, null, null] +9942 - null - [null, null, null, null, null] +9943 - null - [null, null, null, null, null] +9944 - null - [null, null, null, null, null] +9945 - null - [null, null, null, null, null] +9946 - null - [null, null, null, null, null] +9947 - null - [null, null, null, null, null] +9948 - null - [null, null, null, null, null] +9949 - null - [null, null, null, null, null] +9950 - null - [null, null, null, null, null] +9951 - null - [null, null, null, null, null] +9952 - null - [null, null, null, null, null] +9953 - null - [null, null, null, null, null] +9954 - null - [null, null, null, null, null] +9955 - null - [null, null, null, null, null] +9956 - null - [null, null, null, null, null] +9957 - null - [null, null, null, null, null] +9958 - null - [null, null, null, null, null] +9959 - null - [null, null, null, null, null] +9960 - null - [null, null, null, null, null] +9961 - null - [null, null, null, null, null] +9962 - null - [null, null, null, null, null] +9963 - null - [null, null, null, null, null] +9964 - null - [null, null, null, null, null] +9965 - null - [null, null, null, null, null] +9966 - null - [null, null, null, null, null] +9967 - null - [null, null, null, null, null] +9968 - null - [null, null, null, null, null] +9969 - null - [null, null, null, null, null] +9970 - null - [null, null, null, null, null] +9971 - null - [null, null, null, null, null] +9972 - null - [null, null, null, null, null] +9973 - Pillar of Light - [Search, null, null, null, null] +9974 - null - [null, null, null, null, null] +9975 - Cave Stairs - [Descend, null, null, null, null] +9976 - Cave wall - [null, null, null, null, null] +9977 - Tunnel - [Enter, null, null, null, null] +9978 - Ladder - [Climb-up, null, null, null, null] +9979 - Ladder - [Climb-down, null, null, null, null] +9980 - Final Pillar - [null, null, null, null, null] +9981 - Pillar of Light - [null, null, null, null, null] +9982 - Pillar of Light - [null, null, null, null, null] +9983 - Pillar of Light - [null, null, null, null, null] +9984 - Pillar of Light - [null, null, null, null, null] +9985 - Pillar of Light - [null, null, null, null, null] +9986 - Pillar of Light - [null, null, null, null, null] +9987 - null - [null, null, null, null, null] +9988 - Pillar of Light - [null, null, null, null, null] +9989 - null - [null, null, null, null, null] +9990 - null - [null, null, null, null, null] +9991 - null - [null, null, null, null, null] +9992 - null - [null, null, null, null, null] +9993 - null - [null, null, null, null, null] +9994 - null - [null, null, null, null, null] +9995 - null - [null, null, null, null, null] +9996 - null - [null, null, null, null, null] +9997 - null - [null, null, null, null, null] +9998 - null - [null, null, null, null, null] +9999 - null - [null, null, null, null, null] +10000 - null - [null, null, null, null, null] +10001 - null - [null, null, null, null, null] +10002 - Light door - [null, null, null, null, null] +10003 - Light door - [null, null, null, null, null] +10004 - Light door - [null, null, null, null, null] +10005 - Light door - [null, null, null, null, null] +10006 - Light door - [null, null, null, null, null] +10007 - Light door - [null, null, null, null, null] +10008 - Light door - [null, null, null, null, null] +10009 - Light door - [null, null, null, null, null] +10010 - Light door - [null, null, null, null, null] +10011 - Light door - [null, null, null, null, null] +10012 - Light door - [null, null, null, null, null] +10013 - Light door - [null, null, null, null, null] +10014 - Crystal - [null, null, null, null, null] +10015 - Staircase - [Climb-up, null, null, null, null] +10016 - Staircase - [Climb-down, null, null, null, null] +10017 - Staircase - [Climb-up, null, null, null, null] +10018 - Staircase - [Climb-down, null, null, null, null] +10019 - Pillar - [null, null, null, null, null] +10020 - Pillar - [null, null, null, null, null] +10021 - Pillar - [null, null, null, null, null] +10022 - Pillar - [null, null, null, null, null] +10023 - null - [null, null, null, null, null] +10024 - null - [null, null, null, null, null] +10025 - null - [null, null, null, null, null] +10026 - null - [null, null, null, null, null] +10027 - null - [null, null, null, null, null] +10028 - null - [null, null, null, null, null] +10029 - null - [null, null, null, null, null] +10030 - null - [null, null, null, null, null] +10031 - null - [null, null, null, null, null] +10032 - null - [null, null, null, null, null] +10033 - Wall support - [Climb, null, null, null, null] +10034 - Trap - [null, null, null, null, null] +10035 - Low wall - [Climb-over, null, null, null, null] +10036 - Rock - [Climb-down, null, null, null, null] +10037 - Rope - [null, null, null, null, null] +10038 - Rope - [Climb-up, null, null, null, null] +10039 - null - [null, null, null, null, null] +10040 - null - [null, null, null, null, null] +10041 - Tree - [Chop down, Talk to, null, null, null] +10042 - null - [null, null, null, null, null] +10043 - null - [null, null, null, null, null] +10044 - null - [null, null, null, null, null] +10045 - null - [null, null, null, null, null] +10046 - null - [null, null, null, null, null] +10047 - null - [null, null, null, null, null] +10048 - null - [null, null, null, null, null] +10049 - null - [null, null, null, null, null] +10050 - null - [null, null, null, null, null] +10051 - null - [null, null, null, null, null] +10052 - null - [null, null, null, null, null] +10053 - null - [null, null, null, null, null] +10054 - Container - [null, null, null, null, null] +10055 - Gate - [null, null, null, null, null] +10056 - Gate - [null, null, null, null, null] +10057 - Flagpole - [null, null, null, null, null] +10058 - null - [null, null, null, null, null] +10059 - null - [null, null, null, null, null] +10060 - null - [null, null, null, null, null] +10061 - null - [null, null, null, null, null] +10062 - Obstacle net - [null, null, null, null, null] +10063 - Obstacle pipe - [null, null, null, null, null] +10064 - null - [null, null, null, null, null] +10065 - null - [null, null, null, null, null] +10066 - null - [null, null, null, null, null] +10067 - null - [null, null, null, null, null] +10068 - null - [null, null, null, null, null] +10069 - null - [null, null, null, null, null] +10070 - null - [null, null, null, null, null] +10071 - null - [null, null, null, null, null] +10072 - null - [null, null, null, null, null] +10073 - null - [null, null, null, null, null] +10074 - null - [null, null, null, null, null] +10075 - null - [null, null, null, null, null] +10076 - Exercise mat - [Use, null, null, null, null] +10077 - Exercise mat - [Use, null, null, null, null] +10078 - Exercise mat - [Use, null, null, null, null] +10079 - Exercise mat - [Use, null, null, null, null] +10080 - Target - [null, null, null, null, null] +10081 - Tree - [null, null, hidden, null, null] +10082 - Tree - [null, null, hidden, null, null] +10083 - Oak - [null, null, hidden, null, null] +10084 - Hay Bales - [null, null, null, null, null] +10085 - Hay Bales - [null, null, null, null, null] +10086 - Haystack - [null, null, null, null, null] +10087 - Ominous Fishing Spot - [Lure, Bait, null, null, null] +10088 - Ominous Fishing Spot - [Lure, Bait, null, null, null] +10089 - Ominous Fishing Spot - [Lure, Bait, null, null, null] +10090 - Signpost - [Read, null, null, null, null] +10091 - Aquarium - [Fish-In, null, null, null, null] +10092 - null - [null, null, null, null, null] +10093 - Dairy churn - [Churn, null, null, null, null] +10094 - Dairy churn - [Churn, null, null, null, null] +10095 - null - [null, null, null, null, null] +10096 - null - [null, null, null, null, null] +10097 - Blindweed Patch - [null, Inspect, null, null, null] +10098 - Blindweed Patch - [null, Inspect, null, null, null] +10099 - Blindweed Patch - [null, Inspect, null, null, null] +10100 - Blindweed Patch - [null, Inspect, null, null, null] +10101 - Blindweed Patch - [null, Inspect, null, null, null] +10102 - Blindweed Patch - [Pick, Inspect, null, null, null] +10103 - Trashed Patch - [null, Inspect, null, null, null] +10104 - null - [null, null, null, null, null] +10105 - Stagnant Lake - [null, null, null, null, null] +10106 - null - [null, null, null, null, null] +10107 - null - [null, null, null, null, null] +10108 - null - [null, null, null, null, null] +10109 - null - [null, null, null, null, null] +10110 - null - [null, null, null, null, null] +10111 - null - [null, null, null, null, null] +10112 - null - [null, null, null, null, null] +10113 - null - [null, null, null, null, null] +10114 - null - [null, null, null, null, null] +10115 - null - [null, null, null, null, null] +10116 - null - [null, null, null, null, null] +10117 - null - [null, null, null, null, null] +10118 - null - [null, null, null, null, null] +10119 - null - [null, null, null, null, null] +10120 - null - [null, null, null, null, null] +10121 - null - [null, null, null, null, null] +10122 - null - [null, null, null, null, null] +10123 - null - [null, null, null, null, null] +10124 - null - [null, null, null, null, null] +10125 - null - [null, null, null, null, null] +10126 - null - [null, null, null, null, null] +10127 - null - [null, null, null, null, null] +10128 - null - [null, null, null, null, null] +10129 - Chimney Pipe - [null, null, null, null, null] +10130 - null - [null, null, null, null, null] +10131 - null - [null, null, null, null, null] +10132 - null - [null, null, null, null, null] +10133 - null - [null, null, null, null, null] +10134 - null - [null, null, null, null, null] +10135 - null - [null, null, null, null, null] +10136 - Wooden Stair - [Climb-Up, null, null, null, null] +10137 - Wooden Stair - [Climb-Down, null, null, null, null] +10138 - Row boat - [null, null, null, null, null] +10139 - Palm tree - [null, null, null, null, null] +10140 - Palm tree - [null, null, null, null, null] +10141 - Palm tree - [null, null, null, null, null] +10142 - Brewing control - [null, null, null, null, null] +10143 - Brewing control - [null, null, null, null, null] +10144 - Brewing control - [null, null, null, null, null] +10145 - Brewing vat - [null, null, null, null, null] +10146 - Brewing vat - [null, null, null, null, null] +10147 - Brewing vat - [null, null, null, null, null] +10148 - Output Tap - [Turn, null, null, null, null] +10149 - null - [null, null, null, null, null] +10150 - null - [null, null, null, null, null] +10151 - null - [null, null, null, null, null] +10152 - null - [null, null, null, null, null] +10153 - null - [null, null, null, null, null] +10154 - null - [null, null, null, null, null] +10155 - null - [null, null, null, null, null] +10156 - null - [null, null, null, null, null] +10157 - Barrels - [null, null, null, null, null] +10158 - Brewer's Barrel - [null, null, null, null, null] +10159 - Crate - [Search, null, null, null, null] +10160 - Crates - [Search, null, null, null, null] +10161 - Boxes - [null, null, null, null, null] +10162 - Cupboard - [Open, null, null, null, null] +10163 - Open Cupboard - [null, Search, Shut, null, null] +10164 - null - [Pull, null, null, null, null] +10165 - Pressure Lever - [Pull, null, null, null, null] +10166 - Pressure Lever - [Pull, null, null, null, null] +10167 - Ladder - [Climb-up, null, null, null, null] +10168 - Ladder - [Climb-down, null, null, null, null] +10169 - null - [null, null, null, null, null] +10170 - Hopper - [null, null, null, null, null] +10171 - Pressure Barrel - [null, Count, null, null, null] +10172 - Gate - [Open, null, null, null, null] +10173 - null - [null, null, null, null, null] +10174 - Pirate Sign - [null, null, null, null, null] +10175 - Sink - [null, null, null, null, null] +10176 - null - [null, null, null, null, null] +10177 - Iron ladder - [Climb, Climb-up, Climb-down, null, null] +10178 - Standing Torch - [null, null, null, null, null] +10179 - Standing Torch - [null, null, null, null, null] +10180 - null - [null, null, null, null, null] +10181 - null - [null, null, null, null, null] +10182 - null - [null, null, null, null, null] +10183 - null - [null, null, null, null, null] +10184 - null - [null, null, null, null, null] +10185 - null - [null, null, null, null, null] +10186 - null - [null, null, null, null, null] +10187 - null - [null, null, null, null, null] +10188 - null - [null, null, null, null, null] +10189 - null - [null, null, null, null, null] +10190 - null - [null, null, null, null, null] +10191 - null - [null, null, null, null, null] +10192 - null - [null, null, null, null, null] +10193 - Ladder - [Climb-up, null, null, null, null] +10194 - Ladder - [Climb-up, null, null, null, null] +10195 - Ladder - [Climb-down, null, null, null, null] +10196 - Ladder - [Climb-up, null, null, null, null] +10197 - Ladder - [Climb-down, null, null, null, null] +10198 - Ladder - [Climb-up, null, null, null, null] +10199 - Ladder - [Climb-down, null, null, null, null] +10200 - Ladder - [Climb-up, null, null, null, null] +10201 - Ladder - [Climb-down, null, null, null, null] +10202 - Ladder - [Climb-up, null, null, null, null] +10203 - Ladder - [Climb-up, null, null, null, null] +10204 - Ladder - [Climb-down, null, null, null, null] +10205 - Ladder - [Climb-down, null, null, null, null] +10206 - Ladder - [Climb-up, null, null, null, null] +10207 - Ladder - [Climb-up, null, null, null, null] +10208 - Ladder - [Climb-down, null, null, null, null] +10209 - Ladder - [Climb-down, null, null, null, null] +10210 - Ladder - [Climb-up, null, null, null, null] +10211 - Ladder - [Climb-up, null, null, null, null] +10212 - Ladder - [Climb-down, null, null, null, null] +10213 - Ladder - [Climb-down, null, null, null, null] +10214 - Ladder - [Climb-up, null, null, null, null] +10215 - Ladder - [Climb-down, null, null, null, null] +10216 - Ladder - [Climb-up, null, null, null, null] +10217 - Ladder - [Climb-up, null, null, null, null] +10218 - Ladder - [Climb-down, null, null, null, null] +10219 - Ladder - [Climb-up, null, null, null, null] +10220 - Ladder - [Climb-down, null, null, null, null] +10221 - Ladder - [Climb-down, null, null, null, null] +10222 - Ladder - [Climb-up, null, null, null, null] +10223 - Ladder - [Climb-down, null, null, null, null] +10224 - Ladder - [Climb-up, null, null, null, null] +10225 - Ladder - [Climb-down, null, null, null, null] +10226 - Ladder - [Climb-up, null, null, null, null] +10227 - Ladder - [Climb-down, null, null, null, null] +10228 - Ladder - [Climb-up, null, null, null, null] +10229 - Ladder - [Climb-up, null, null, null, null] +10230 - Ladder - [Climb-down, null, null, null, null] +10231 - null - [null, null, null, null, null] +10232 - null - [null, null, null, null, null] +10233 - null - [null, null, null, null, null] +10234 - null - [null, null, null, null, null] +10235 - null - [null, null, null, null, null] +10236 - null - [null, null, null, null, null] +10237 - null - [null, null, null, null, null] +10238 - null - [null, null, null, null, null] +10239 - null - [null, null, null, null, null] +10240 - null - [null, null, null, null, null] +10241 - null - [null, null, null, null, null] +10242 - null - [null, null, null, null, null] +10243 - null - [null, null, null, null, null] +10244 - null - [null, null, null, null, null] +10245 - null - [null, null, null, null, null] +10246 - Broken kiln - [Look-in, null, null, null, null] +10247 - Broken kiln - [Look-in, null, null, null, null] +10248 - Broken kiln - [Look-in, null, null, null, null] +10249 - null - [null, null, null, null, null] +10250 - Eric - [null, null, null, null, null] +10251 - Portal - [Enter, null, null, null, null] +10252 - Magic circle - [null, null, null, null, null] +10253 - Standard - [null, null, null, null, null] +10254 - null - [null, null, null, null, null] +10255 - Bed - [null, null, null, null, null] +10256 - Shelf - [null, null, null, null, null] +10257 - Shelf - [null, null, null, null, null] +10258 - Table - [null, null, null, null, null] +10259 - Chair - [null, null, null, null, null] +10260 - Door - [Open, null, null, null, null] +10261 - Door - [Close, null, null, null, null] +10262 - Door - [Open, null, null, null, null] +10263 - Door - [Close, null, null, null, null] +10264 - Door - [Open, null, null, null, null] +10265 - Door - [Close, null, null, null, null] +10266 - null - [null, null, null, null, null] +10267 - Shield Display - [Study, null, null, null, null] +10268 - null - [null, null, null, null, null] +10269 - Large Display - [Study, null, null, null, null] +10270 - null - [null, null, null, null, null] +10271 - Large Display - [Study, null, null, null, null] +10272 - null - [null, null, null, null, null] +10273 - Bookcase - [Study, null, null, null, null] +10274 - Sacks - [null, null, null, null, null] +10275 - null - [null, null, null, null, null] +10276 - null - [null, null, null, null, null] +10277 - null - [null, null, null, null, null] +10278 - Catapult - [null, null, null, null, null] +10279 - Crates - [null, null, null, null, null] +10280 - Crates - [null, null, null, null, null] +10281 - Crate - [null, null, null, null, null] +10282 - Crates - [null, null, null, null, null] +10283 - River - [Swim, null, null, null, null] +10284 - null - [null, null, null, null, null] +10285 - null - [null, null, null, null, null] +10286 - Sack - [null, null, null, null, null] +10287 - Stairs - [Climb-up, null, null, null, null] +10288 - Stairs - [Climb-down, null, null, null, null] +10289 - null - [null, null, null, null, null] +10290 - Rat trap - [Take, null, null, null, null] +10291 - Rat trap - [Take, null, null, null, null] +10292 - Rat trap - [null, null, null, null, null] +10293 - Barrel - [null, null, null, null, null] +10294 - Barrel - [null, null, null, null, null] +10295 - Bar pumps - [null, null, null, null, null] +10296 - Stool - [null, null, null, null, null] +10297 - null - [null, null, null, null, null] +10298 - Crates - [null, null, null, null, null] +10299 - Rat lever - [null, null, null, null, null] +10300 - Rat barn - [null, null, null, null, null] +10301 - Rat barrel - [null, null, null, null, null] +10302 - Rat barrel - [null, null, null, null, null] +10303 - Rat barrel - [null, null, null, null, null] +10304 - Sacks - [null, null, null, null, null] +10305 - Sack - [null, null, null, null, null] +10306 - Sack - [null, null, null, null, null] +10307 - Lantern - [null, null, null, null, null] +10308 - Ladder - [Climb-down, null, null, null, null] +10309 - Ladder - [Climb-up, null, null, null, null] +10310 - Rat barrel - [null, null, null, null, null] +10311 - Rat lever - [null, null, null, null, null] +10312 - Rat barn - [null, null, null, null, null] +10313 - Sacks - [null, null, null, null, null] +10314 - Sack - [null, null, null, null, null] +10315 - Sack - [null, null, null, null, null] +10316 - Rat barrel - [null, null, null, null, null] +10317 - Rat barrel - [null, null, null, null, null] +10318 - Gates - [Open, null, null, null, null] +10319 - Trellis top - [Climb-down, null, null, null, null] +10320 - Hole in wall - [null, null, null, null, null] +10321 - Manhole - [Climb-down, null, null, null, null] +10322 - Ladder - [Climb-down, null, null, null, null] +10323 - Trellis - [Climb-up, Look-up, null, null, null] +10324 - Trellis - [null, null, null, null, null] +10325 - Door - [Open, null, null, null, null] +10326 - Door - [null, null, null, null, null] +10327 - Door - [Close, null, null, null, null] +10328 - null - [null, null, null, null, null] +10329 - null - [null, null, null, null, null] +10330 - null - [null, null, null, null, null] +10331 - null - [null, null, null, null, null] +10332 - null - [null, null, null, null, null] +10333 - null - [null, null, null, null, null] +10334 - null - [null, null, null, null, null] +10335 - Rat wall - [Spectate, null, null, null, null] +10336 - Rat wall - [Spectate, null, null, null, null] +10337 - Rat wall - [Spectate, null, null, null, null] +10338 - Rat wall - [Spectate, null, null, null, null] +10339 - null - [null, null, null, null, null] +10340 - null - [null, null, null, null, null] +10341 - null - [null, null, null, null, null] +10342 - Rat Wall - [Spectate, null, null, null, null] +10343 - Rat Wall - [Spectate, null, null, null, null] +10344 - Rat Wall - [Spectate, null, null, null, null] +10345 - Rat Wall - [Spectate, null, null, null, null] +10346 - Rat hole - [null, null, null, null, null] +10347 - Rat hole - [null, null, null, null, null] +10348 - Rat hole - [null, null, null, null, null] +10349 - Rat hole - [null, null, null, null, null] +10350 - Rat hole - [null, null, null, null, null] +10351 - null - [null, null, null, null, null] +10352 - null - [null, null, null, null, null] +10353 - null - [null, null, null, null, null] +10354 - null - [null, null, null, null, null] +10355 - null - [null, null, null, null, null] +10356 - null - [null, null, null, null, null] +10357 - null - [null, null, null, null, null] +10358 - Bed - [null, null, null, null, null] +10359 - Bed - [null, null, null, null, null] +10360 - Rolled up rugs - [null, null, null, null, null] +10361 - Door - [null, null, null, null, null] +10362 - Hay Bales - [null, null, null, null, null] +10363 - null - [null, null, null, null, null] +10364 - null - [null, null, null, null, null] +10365 - null - [null, null, null, null, null] +10366 - null - [null, null, null, null, null] +10367 - null - [null, null, null, null, null] +10368 - null - [null, null, null, null, null] +10369 - null - [null, null, null, null, null] +10370 - null - [null, null, null, null, null] +10371 - Barrel - [null, null, null, null, null] +10372 - null - [null, null, null, null, null] +10373 - null - [null, null, null, null, null] +10374 - Crates - [null, null, null, null, null] +10375 - Tools - [Take, null, null, null, null] +10376 - Choc-Ice Stall - [null, null, null, null, null] +10377 - Clay Oven - [null, null, null, null, null] +10378 - Crate - [Search, null, null, null, null] +10379 - Crates - [Search, null, null, null, null] +10380 - Boxes - [Search, null, null, null, null] +10381 - Crates - [Search, null, null, null, null] +10382 - Cupboard - [Open, null, null, null, null] +10383 - Cupboard - [null, Search, Shut, null, null] +10384 - Cupboard - [Open, null, null, null, null] +10385 - Cupboard - [null, Search, Shut, null, null] +10386 - Cupboard - [null, Search, Shut, null, null] +10387 - Cupboard - [null, Search, Shut, null, null] +10388 - null - [null, null, null, null, null] +10389 - null - [null, null, null, null, null] +10390 - null - [null, null, null, null, null] +10391 - null - [null, null, null, null, null] +10392 - null - [null, null, null, null, null] +10393 - null - [null, null, null, null, null] +10394 - null - [null, null, null, null, null] +10395 - null - [null, null, null, null, null] +10396 - null - [null, null, null, null, null] +10397 - null - [null, null, null, null, null] +10398 - null - [null, null, null, null, null] +10399 - null - [null, null, null, null, null] +10400 - null - [null, null, null, null, null] +10401 - null - [null, null, null, null, null] +10402 - Water Channel - [null, null, null, null, null] +10403 - null - [null, null, null, null, null] +10404 - Water Channel - [null, null, null, null, null] +10405 - Water Channel - [Clear, null, hidden, null, null] +10406 - Water Channel - [null, null, null, null, null] +10407 - Water Channel - [Clear, null, null, null, null] +10408 - Water Channel - [null, null, null, null, null] +10409 - Water Channel - [null, null, null, null, null] +10410 - Water Channel - [null, null, null, null, null] +10411 - null - [null, null, null, null, null] +10412 - Hole - [null, null, null, null, null] +10413 - Bed - [null, null, null, null, null] +10414 - Table - [null, null, null, null, null] +10415 - Rolled up rugs - [null, null, null, null, null] +10416 - Crevice - [Climb-down, null, null, null, null] +10417 - Cave exit - [Leave, null, null, null, null] +10418 - Door - [Open, null, null, null, null] +10419 - Door - [Open, null, null, null, null] +10420 - Door - [Open, null, null, null, null] +10421 - Door - [Open, null, null, null, null] +10422 - null - [null, null, null, null, null] +10423 - Door - [Open, null, null, null, null] +10424 - null - [null, null, null, null, null] +10425 - Door - [Open, null, null, null, null] +10426 - null - [null, null, null, null, null] +10427 - Door - [Open, null, null, null, null] +10428 - null - [null, null, null, null, null] +10429 - Door - [Open, null, null, null, null] +10430 - null - [null, null, null, null, null] +10431 - Door - [Open, null, null, null, null] +10432 - null - [null, null, null, null, null] +10433 - Fire - [null, null, null, null, null] +10434 - Rope - [Climb, null, null, null, null] +10435 - null - [null, null, null, null, null] +10436 - Fountain - [null, null, null, null, null] +10437 - Fountain - [null, null, null, null, null] +10438 - Statuette Plinth - [null, null, null, null, null] +10439 - Elidinis Statuette - [Pray-at, null, null, null, null] +10440 - Rock Chair - [null, null, null, null, null] +10441 - null - [null, null, null, null, null] +10442 - null - [null, null, null, null, null] +10443 - null - [null, null, null, null, null] +10444 - null - [null, null, null, null, null] +10445 - null - [null, null, null, null, null] +10446 - null - [null, null, null, null, null] +10447 - null - [null, null, null, null, null] +10448 - null - [null, null, null, null, null] +10449 - null - [null, null, null, null, null] +10450 - null - [null, null, null, null, null] +10451 - null - [null, null, null, null, null] +10452 - null - [null, null, null, null, null] +10453 - null - [null, null, null, null, null] +10454 - null - [null, null, null, null, null] +10455 - null - [null, null, null, null, null] +10456 - null - [null, null, null, null, null] +10457 - Cart - [null, null, null, null, null] +10458 - Barrel - [null, null, null, null, null] +10459 - null - [null, null, null, null, null] +10460 - null - [null, null, null, null, null] +10461 - null - [null, null, null, null, null] +10462 - null - [null, null, null, null, null] +10463 - null - [null, null, null, null, null] +10464 - null - [null, null, null, null, null] +10465 - null - [null, null, null, null, null] +10466 - null - [null, null, null, null, null] +10467 - null - [null, null, null, null, null] +10468 - null - [null, null, null, null, null] +10469 - null - [null, null, null, null, null] +10470 - null - [null, null, null, null, null] +10471 - null - [null, null, null, null, null] +10472 - null - [null, null, null, null, null] +10473 - null - [null, null, null, null, null] +10474 - null - [null, null, null, null, null] +10475 - null - [null, null, null, null, null] +10476 - null - [null, null, null, null, null] +10477 - null - [null, null, null, null, null] +10478 - null - [null, null, null, null, null] +10479 - null - [null, null, null, null, null] +10480 - null - [null, null, null, null, null] +10481 - null - [null, null, null, null, null] +10482 - null - [null, null, null, null, null] +10483 - null - [null, null, null, null, null] +10484 - null - [null, null, null, null, null] +10485 - Counter - [null, null, null, null, null] +10486 - Counter - [null, null, null, null, null] +10487 - Blacksmith's tools - [null, null, null, null, null] +10488 - null - [null, null, null, null, null] +10489 - Armour - [null, null, null, null, null] +10490 - Table - [null, null, null, null, null] +10491 - Chair - [null, null, null, null, null] +10492 - Chair - [null, null, null, null, null] +10493 - Ladder - [Climb-up, null, null, null, null] +10494 - Ladder - [Climb-down, null, null, null, null] +10495 - Warehouse shelves - [null, null, null, null, null] +10496 - Warehouse shelves - [null, null, null, null, null] +10497 - Warehouse shelves - [null, null, null, null, null] +10498 - Warehouse shelves - [null, null, null, null, null] +10499 - Potted fern - [null, null, null, null, null] +10500 - Potted fern - [null, null, null, null, null] +10501 - Potted fern - [null, null, null, null, null] +10502 - Potted fern - [null, null, null, null, null] +10503 - Pile of bricks - [null, null, null, null, null] +10504 - Cooking Pots - [null, null, null, null, null] +10505 - Cooking Pots - [null, null, null, null, null] +10506 - Shelf - [null, null, null, null, null] +10507 - null - [null, null, null, null, null] +10508 - Stone Pew - [null, null, null, null, null] +10509 - Table - [null, null, null, null, null] +10510 - Bookcase - [null, null, null, null, null] +10511 - Bed - [null, null, null, null, null] +10512 - Bed - [null, null, null, null, null] +10513 - Shelves - [null, null, null, null, null] +10514 - Shelves - [null, null, null, null, null] +10515 - null - [null, null, null, null, null] +10516 - Wheelbarrow - [null, null, null, null, null] +10517 - Bank booth - [Use, Use-quickly, Collect, null, null] +10518 - Closed bank booth - [null, null, null, null, null] +10519 - null - [null, null, null, null, null] +10520 - null - [null, null, null, null, null] +10521 - Chalice - [null, null, null, null, null] +10522 - Tapestry - [null, null, null, null, null] +10523 - null - [null, null, null, null, null] +10524 - null - [null, null, null, null, null] +10525 - Staircase - [Climb-up, null, null, null, null] +10526 - Staircase - [Climb-down, null, null, null, null] +10527 - Door - [Open, null, null, null, null] +10528 - Door - [Close, null, null, null, null] +10529 - Door - [Open, null, null, null, null] +10530 - Door - [Close, null, null, null, null] +10531 - null - [null, null, null, null, null] +10532 - null - [null, null, null, null, null] +10533 - null - [null, null, null, null, null] +10534 - null - [null, null, null, null, null] +10535 - null - [null, null, null, null, null] +10536 - null - [null, null, null, null, null] +10537 - null - [null, null, null, null, null] +10538 - null - [null, null, null, null, null] +10539 - null - [null, null, null, null, null] +10540 - null - [null, null, null, null, null] +10541 - Human Flag - [null, null, null, null, null] +10542 - Human Flag - [null, null, null, null, null] +10543 - Dwarf Flag - [null, null, null, null, null] +10544 - Dwarf Flag - [null, null, null, null, null] +10545 - Elf Flag - [null, null, null, null, null] +10546 - Elf Flag - [null, null, null, null, null] +10547 - Gnome Flag - [null, null, null, null, null] +10548 - Gnome Flag - [null, null, null, null, null] +10549 - Werewolf Flag - [null, null, null, null, null] +10550 - Werewolf Flag - [null, null, null, null, null] +10551 - TzHaar Flag - [null, null, null, null, null] +10552 - TzHaar Flag - [null, null, null, null, null] +10553 - Portcullis - [Open, null, null, null, null] +10554 - Ladder - [Climb-up, null, null, null, null] +10555 - null - [null, null, null, null, null] +10556 - Champion Statue - [Open, null, null, null, null] +10557 - Champion Statue - [Climb-down, null, null, null, null] +10558 - Trapdoor - [Open, null, null, null, null] +10559 - Trapdoor - [Climb-down, Close, null, null, null] +10560 - Ladder - [Climb-up, null, null, null, null] +10561 - null - [null, null, null, null, null] +10562 - Bank chest - [Use, null, null, null, null] +10563 - null - [null, null, null, null, null] +10564 - Banner - [null, null, null, null, null] +10565 - null - [null, null, null, null, null] +10566 - Banner - [null, null, null, null, null] +10567 - null - [null, null, null, null, null] +10568 - Banner - [null, null, null, null, null] +10569 - null - [null, null, null, null, null] +10570 - Banner - [null, null, null, null, null] +10571 - null - [null, null, null, null, null] +10572 - Banner - [null, null, null, null, null] +10573 - null - [null, null, null, null, null] +10574 - Banner - [null, null, null, null, null] +10575 - null - [null, null, null, null, null] +10576 - Banner - [null, null, null, null, null] +10577 - null - [null, null, null, null, null] +10578 - Banner - [null, null, null, null, null] +10579 - null - [null, null, null, null, null] +10580 - Banner - [null, null, null, null, null] +10581 - null - [null, null, null, null, null] +10582 - Banner - [null, null, null, null, null] +10583 - Rocks - [Mine, Prospect, hidden, null, null] +10584 - Rocks - [Mine, Prospect, hidden, null, null] +10585 - Rocks - [Mine, Prospect, hidden, null, null] +10586 - Rocks - [Mine, Prospect, hidden, null, null] +10587 - Rocks - [Mine, Prospect, hidden, null, null] +10588 - null - [null, null, null, null, null] +10589 - null - [null, null, null, null, null] +10590 - null - [null, null, null, null, null] +10591 - null - [null, null, null, null, null] +10592 - null - [null, null, null, null, null] +10593 - null - [null, null, null, null, null] +10594 - null - [null, null, null, null, null] +10595 - Icy Cavern - [Enter, null, null, null, null] +10596 - Icy Cavern - [Enter, null, null, null, null] +10597 - null - [null, null, null, null, null] +10598 - null - [null, null, null, null, null] +10599 - null - [null, null, null, null, null] +10600 - null - [null, null, null, null, null] +10601 - null - [null, null, null, null, null] +10602 - null - [null, null, null, null, null] +10603 - null - [null, null, null, null, null] +10604 - null - [null, null, null, null, null] +10605 - Danger Sign - [null, null, null, null, null] +10606 - - [null, null, null, null, null] +10607 - Bronze Chest - [null, null, null, null, null] +10608 - Bronze Chest - [null, null, null, null, null] +10609 - Bronze Chest - [null, null, null, null, null] +10610 - Bronze Chest - [null, null, null, null, null] +10611 - Steel Chest - [null, null, null, null, null] +10612 - Steel Chest - [null, null, null, null, null] +10613 - Steel Chest - [null, null, null, null, null] +10614 - Steel Chest - [null, null, null, null, null] +10615 - Steel Chest - [null, null, null, null, null] +10616 - Black Chest - [null, null, null, null, null] +10617 - Black Chest - [null, null, null, null, null] +10618 - Black Chest - [null, null, null, null, null] +10619 - Black Chest - [null, null, null, null, null] +10620 - Black Chest - [null, null, null, null, null] +10621 - Silver Chest - [null, null, null, null, null] +10622 - Silver Chest - [null, null, null, null, null] +10623 - Silver Chest - [null, null, null, null, null] +10624 - Silver Chest - [null, null, null, null, null] +10625 - Silver Chest - [null, null, null, null, null] +10626 - null - [null, null, null, null, null] +10627 - null - [null, null, null, null, null] +10628 - null - [null, null, null, null, null] +10629 - null - [null, null, null, null, null] +10630 - null - [null, null, null, null, null] +10631 - null - [null, null, null, null, null] +10632 - null - [null, null, null, null, null] +10633 - null - [null, null, null, null, null] +10634 - null - [null, null, null, null, null] +10635 - null - [null, null, null, null, null] +10636 - null - [null, null, null, null, null] +10637 - null - [null, null, null, null, null] +10638 - null - [null, null, null, null, null] +10639 - Altar - [Pray-at, null, null, null, null] +10640 - Altar - [Pray-at, null, null, null, null] +10641 - Doric's Whetstone - [null, null, null, null, null] +10642 - null - [null, null, null, null, null] +10643 - null - [null, null, null, null, null] +10644 - null - [null, null, null, null, null] +10645 - null - [null, null, null, null, null] +10646 - null - [null, null, null, null, null] +10647 - null - [null, null, null, null, null] +10648 - null - [null, null, null, null, null] +10649 - null - [null, null, null, null, null] +10650 - null - [null, null, null, null, null] +10651 - null - [null, null, null, null, null] +10652 - Evergreen. - [null, null, null, null, null] +10653 - Evergreen. - [null, null, null, null, null] +10654 - Evergreen. - [null, null, null, null, null] +10655 - Evergreen. - [null, null, null, null, null] +10656 - Evergreen. - [null, null, null, null, null] +10657 - Evergreen. - [null, null, null, null, null] +10658 - Evergreen. - [null, null, null, null, null] +10659 - Evergreen. - [null, null, null, null, null] +10660 - Evergreen. - [null, null, null, null, null] +10661 - Evergreen. - [null, null, null, null, null] +10662 - Evergreen. - [null, null, null, null, null] +10663 - Evergreen. - [null, null, null, null, null] +10664 - Tree - [null, null, null, null, null] +10665 - Gifts - [null, null, null, null, null] +10666 - Gifts - [Unwrap presents, null, null, null, null] +10667 - null - [null, null, null, null, null] +10668 - null - [null, null, null, null, null] +10669 - null - [null, null, null, null, null] +10670 - null - [null, null, null, null, null] +10671 - Crate - [null, null, null, null, null] +10672 - Crate - [Take-marionette, null, null, null, null] +10673 - Paintcans - [Paint-bauble, null, null, null, null] +10674 - Paintcans - [Paint-bauble, null, null, null, null] +10675 - Paintcans - [Paint-bauble, null, null, null, null] +10676 - Workbench - [null, null, null, null, null] +10677 - Workbench - [null, null, null, null, null] +10678 - Workbench - [null, null, null, null, null] +10679 - Decorations Box - [Take-decoration, null, null, null, null] +10680 - Decorations Box - [Take-decoration, null, null, null, null] +10681 - Decorations Box - [Take-decoration, null, null, null, null] +10682 - Decorations Box - [Take-decoration, null, null, null, null] +10683 - Decorations Box - [Take-decoration, null, null, null, null] +10684 - Decorations Box - [Take-decoration, null, null, null, null] +10685 - Decorations Box - [Take-decoration, null, null, null, null] +10686 - Puppet heads - [Add, null, null, null, null] +10687 - Puppet torsos - [Take, null, null, null, null] +10688 - Puppet arms - [Add, null, null, null, null] +10689 - Puppet legs - [Add, null, null, null, null] +10690 - Puppet heads - [Add, null, null, null, null] +10691 - Puppet torsos - [Take, null, null, null, null] +10692 - Puppet arms - [Add, null, null, null, null] +10693 - Puppet legs - [Add, null, null, null, null] +10694 - Puppet heads - [Add, null, null, null, null] +10695 - Puppet torsos - [Take, null, null, null, null] +10696 - Puppet arms - [Add, null, null, null, null] +10697 - Puppet legs - [Add, null, null, null, null] +10698 - Trapdoor - [Climb-down, null, null, null, null] +10699 - Trapdoor Steps - [Climb-up, null, null, null, null] +10700 - null - [null, null, null, null, null] +10701 - Crate - [null, null, null, null, null] +10702 - Crate - [null, null, null, null, null] +10703 - Crate - [null, null, null, null, null] +10704 - Crate - [null, null, null, null, null] +10705 - Crates - [null, null, null, null, null] +10706 - Large Box - [null, null, null, null, null] +10707 - Ladder - [Climb-up, null, null, null, null] +10708 - Ladder - [Climb-down, null, null, null, null] +10709 - null - [null, null, null, null, null] +10710 - Paint Pots - [null, null, null, null, null] +10711 - null - [null, null, null, null, null] +10712 - null - [null, null, null, null, null] +10713 - null - [null, null, null, null, null] +10714 - null - [null, null, null, null, null] +10715 - null - [null, null, null, null, null] +10716 - null - [null, null, null, null, null] +10717 - null - [null, null, null, null, null] +10718 - null - [null, null, null, null, null] +10719 - null - [null, null, null, null, null] +10720 - null - [null, null, null, null, null] +10721 - Doorway - [Enter, null, null, null, null] +10722 - Old Bookshelf - [Search, null, null, null, null] +10723 - Old Bookshelf - [Search, null, null, null, null] +10724 - Chair - [null, null, null, null, null] +10725 - Bones - [Grab, null, null, null, null] +10726 - Bones - [Grab, null, null, null, null] +10727 - Bones - [Grab, null, null, null, null] +10728 - Bones - [Grab, null, null, null, null] +10729 - null - [null, null, null, null, null] +10730 - null - [null, null, null, null, null] +10731 - null - [null, null, null, null, null] +10732 - null - [null, null, null, null, null] +10733 - Portal - [null, null, null, null, null] +10734 - Coin Collector - [Deposit, null, null, null, null] +10735 - Food chute - [Deposit, null, null, null, null] +10736 - Statue - [null, null, null, null, null] +10737 - Statue - [null, null, null, null, null] +10738 - Statue - [null, null, null, null, null] +10739 - Statue - [null, null, null, null, null] +10740 - null - [null, null, null, null, null] +10741 - null - [null, null, null, null, null] +10742 - null - [null, null, null, null, null] +10743 - null - [null, null, null, null, null] +10744 - null - [null, null, null, null, null] +10745 - null - [null, null, null, null, null] +10746 - null - [null, null, null, null, null] +10747 - null - [null, null, null, null, null] +10748 - null - [null, null, null, null, null] +10749 - null - [null, null, null, null, null] +10750 - null - [null, null, null, null, null] +10751 - null - [null, null, null, null, null] +10752 - null - [null, null, null, null, null] +10753 - null - [null, null, null, null, null] +10754 - null - [null, null, null, null, null] +10755 - null - [null, null, null, null, null] +10756 - null - [null, null, null, null, null] +10757 - null - [null, null, null, null, null] +10758 - null - [null, null, null, null, null] +10759 - null - [null, null, null, null, null] +10760 - null - [null, null, null, null, null] +10761 - null - [null, null, null, null, null] +10762 - null - [null, null, null, null, null] +10763 - null - [null, null, null, null, null] +10764 - null - [null, null, null, null, null] +10765 - null - [null, null, null, null, null] +10766 - null - [null, null, null, null, null] +10767 - null - [null, null, null, null, null] +10768 - Bank - [null, null, null, null, null] +10769 - null - [null, null, null, null, null] +10770 - null - [null, null, null, null, null] +10771 - Stairs - [Climb-up, null, null, null, null] +10772 - Stairs - [Climb, null, null, null, null] +10773 - Stairs - [Climb-down, null, null, null, null] +10774 - Stairs - [Climb-down, null, null, null, null] +10775 - Stairs - [Climb-up, null, null, null, null] +10776 - Stairs - [Climb-down, null, null, null, null] +10777 - null - [null, null, null, null, null] +10778 - Telekinetic Teleport - [Enter, null, null, null, null] +10779 - Enchanters Teleport - [Enter, null, null, null, null] +10780 - Alchemists Teleport - [Enter, null, null, null, null] +10781 - Graveyard Teleport - [Enter, null, null, null, null] +10782 - Exit Teleport - [Enter, null, null, null, null] +10783 - Cupboard - [Search, null, null, null, null] +10784 - Cupboard - [Search, null, null, null, null] +10785 - Cupboard - [Search, null, null, null, null] +10786 - Cupboard - [Search, null, null, null, null] +10787 - Cupboard - [Search, null, null, null, null] +10788 - Cupboard - [Search, null, null, null, null] +10789 - Cupboard - [Search, null, null, null, null] +10790 - Cupboard - [Search, null, null, null, null] +10791 - Cupboard - [Search, null, null, null, null] +10792 - Cupboard - [Search, null, null, null, null] +10793 - Cupboard - [Search, null, null, null, null] +10794 - Cupboard - [Search, null, null, null, null] +10795 - Cupboard - [Search, null, null, null, null] +10796 - Cupboard - [Search, null, null, null, null] +10797 - Cupboard - [Search, null, null, null, null] +10798 - Cupboard - [Search, null, null, null, null] +10799 - Cube Pile - [Take-from, null, null, null, null] +10800 - Cylinder Pile - [Take-from, null, null, null, null] +10801 - Icosahedron Pile - [Take-from, null, null, null, null] +10802 - Pentamid Pile - [Take-from, null, null, null, null] +10803 - Hole - [Deposit, null, null, null, null] +10804 - Trapdoor - [Climb-down, null, null, null, null] +10805 - Sandy's Desk - [Search, null, null, null, null] +10806 - null - [null, null, null, null, null] +10807 - Sandy's Coffee Mug - [null, null, null, null, null] +10808 - Table - [null, null, null, null, null] +10809 - Waste Paper Bin - [null, null, null, null, null] +10810 - null - [null, null, null, null, null] +10811 - null - [null, null, null, null, null] +10812 - null - [null, null, null, null, null] +10813 - Counter - [null, null, null, null, null] +10814 - Sandpit - [null, null, null, null, null] +10815 - null - [null, null, null, null, null] +10816 - null - [null, null, null, null, null] +10817 - Lever - [Pull, null, null, null, null] +10818 - Locked door - [Open, null, null, null, null] +10819 - Locked door - [Open, null, null, null, null] +10820 - Energy Barrier - [null, null, null, null, null] +10821 - null - [null, null, null, null, null] +10822 - null - [null, null, null, null, null] +10823 - null - [null, null, null, null, null] +10824 - Fireplace - [null, null, null, null, null] +10825 - null - [null, null, null, null, null] +10826 - null - [null, null, null, null, null] +10827 - Fountain - [null, null, null, null, null] +10828 - Trawler net - [null, null, null, null, null] +10829 - Trawler net - [null, null, null, null, null] +10830 - Trawler net - [null, null, null, null, null] +10831 - Trawler net - [null, null, null, null, null] +10832 - Trawler net - [null, null, null, null, null] +10833 - Trawler net - [null, null, null, null, null] +10834 - Trawler net - [null, null, null, null, null] +10835 - Trawler net - [null, null, null, null, null] +10836 - Trawler net - [null, null, null, null, null] +10837 - null - [null, null, null, null, null] +10838 - null - [null, null, null, null, null] +10839 - null - [null, null, null, null, null] +10840 - null - [null, null, null, null, null] +10841 - null - [null, null, null, null, null] +10842 - null - [null, null, null, null, null] +10843 - null - [null, null, null, null, null] +10844 - null - [null, null, null, null, null] +10845 - null - [null, null, null, null, null] +10846 - null - [null, null, null, null, null] +10847 - null - [null, null, null, null, null] +10848 - Doorway - [null, null, null, null, null] +10849 - Doorway - [null, null, null, null, null] +10850 - null - [null, null, null, null, null] +10851 - Climbing rocks - [Climb, null, null, null, null] +10852 - Climbing rocks - [Climb, null, null, null, null] +10853 - null - [null, null, null, null, null] +10854 - null - [null, null, null, null, null] +10855 - Doorway - [Enter, null, null, null, null] +10856 - Doorway - [Enter, null, null, null, null] +10857 - Stairs - [Climb-up, null, null, null, null] +10858 - Stairs - [Climb-down, null, null, null, null] +10859 - Gap - [Jump, null, null, null, null] +10860 - Ledge - [Cross, null, null, null, null] +10861 - Gap - [Cross, null, null, null, null] +10862 - Gap - [Cross, null, null, null, null] +10863 - Gap - [Cross, null, null, null, null] +10864 - Gap - [Cross, null, null, null, null] +10865 - Low wall - [Climb-over, null, null, null, null] +10866 - null - [null, null, null, null, null] +10867 - Plank - [Cross, null, null, null, null] +10868 - Plank - [Cross, null, null, null, null] +10869 - null - [null, null, null, null, null] +10870 - null - [null, null, null, null, null] +10871 - null - [null, null, null, null, null] +10872 - null - [null, null, null, null, null] +10873 - null - [null, null, null, null, null] +10874 - null - [null, null, null, null, null] +10875 - Stone block - [null, null, null, null, null] +10876 - Stone block - [null, null, null, null, null] +10877 - null - [null, null, null, null, null] +10878 - null - [null, null, null, null, null] +10879 - null - [null, null, null, null, null] +10880 - null - [null, null, null, null, null] +10881 - null - [null, null, null, null, null] +10882 - Gap - [Cross, null, null, null, null] +10883 - Gap - [Cross, null, null, null, null] +10884 - Gap - [Cross, null, null, null, null] +10885 - Gap - [Cross, null, null, null, null] +10886 - Ledge - [Cross, null, null, null, null] +10887 - Ledge - [Cross, null, null, null, null] +10888 - Ledge - [Cross, null, null, null, null] +10889 - Ledge - [Cross, null, null, null, null] +10890 - null - [null, null, null, null, null] +10891 - null - [null, null, null, null, null] +10892 - null - [null, null, null, null, null] +10893 - null - [null, null, null, null, null] +10894 - null - [null, null, null, null, null] +10895 - null - [null, null, null, null, null] +10896 - null - [null, null, null, null, null] +10897 - null - [null, null, null, null, null] +10898 - null - [null, null, null, null, null] +10899 - null - [null, null, null, null, null] +10900 - null - [null, null, null, null, null] +10901 - null - [null, null, null, null, null] +10902 - null - [null, null, null, null, null] +10903 - null - [null, null, null, null, null] +10904 - null - [null, null, null, null, null] +10905 - null - [null, null, null, null, null] +10906 - null - [null, null, null, null, null] +10907 - null - [null, null, null, null, null] +10908 - null - [null, null, null, null, null] +10909 - null - [null, null, null, null, null] +10910 - null - [null, null, null, null, null] +10911 - null - [null, null, null, null, null] +10912 - null - [null, null, null, null, null] +10913 - null - [null, null, null, null, null] +10914 - null - [null, null, null, null, null] +10915 - null - [null, null, null, null, null] +10916 - null - [null, null, null, null, null] +10917 - null - [null, null, null, null, null] +10918 - null - [null, null, null, null, null] +10919 - null - [null, null, null, null, null] +10920 - null - [null, null, null, null, null] +10921 - null - [null, null, null, null, null] +10922 - null - [null, null, null, null, null] +10923 - null - [null, null, null, null, null] +10924 - null - [null, null, null, null, null] +10925 - null - [null, null, null, null, null] +10926 - null - [null, null, null, null, null] +10927 - null - [null, null, null, null, null] +10928 - null - [null, null, null, null, null] +10929 - null - [null, null, null, null, null] +10930 - null - [null, null, null, null, null] +10931 - null - [null, null, null, null, null] +10932 - null - [null, null, null, null, null] +10933 - null - [null, null, null, null, null] +10934 - null - [null, null, null, null, null] +10935 - null - [null, null, null, null, null] +10936 - null - [null, null, null, null, null] +10937 - null - [null, null, null, null, null] +10938 - null - [null, null, null, null, null] +10939 - null - [null, null, null, null, null] +10940 - null - [null, null, null, null, null] +10941 - null - [null, null, null, null, null] +10942 - null - [null, null, null, null, null] +10943 - null - [null, null, null, null, null] +10944 - Rocks - [Mine, Prospect, hidden, null, null] +10945 - Rocks - [Mine, Prospect, hidden, null, null] +10946 - Rocks - [Mine, Prospect, hidden, null, null] +10947 - Rocks - [Mine, Prospect, hidden, null, null] +10948 - Rocks - [Mine, Prospect, hidden, null, null] +10949 - Rocks - [Mine, Prospect, hidden, null, null] +10950 - Sand pile - [Climb, null, null, null, null] +10951 - null - [null, null, null, null, null] +10952 - null - [null, null, null, null, null] +10953 - Hole - [null, null, null, null, null] +10954 - Flat ground - [null, null, null, null, null] +10955 - Headless statue - [null, null, null, null, null] +10956 - Headless statue - [null, null, null, null, null] +10957 - Headless statue - [null, null, null, null, null] +10958 - Lazim's statue - [null, null, null, null, null] +10959 - Zamorak's statue - [null, null, null, null, null] +10960 - Icthlarin's statue - [null, null, null, null, null] +10961 - Camel's statue - [null, null, null, null, null] +10962 - Statue - [null, null, null, null, null] +10963 - Statue - [null, null, null, null, null] +10964 - Statue - [null, null, null, null, null] +10965 - Statue - [null, null, null, null, null] +10966 - Statue - [null, null, null, null, null] +10967 - Statue - [null, null, null, null, null] +10968 - Statue - [null, null, null, null, null] +10969 - Statue - [null, null, null, null, null] +10970 - null - [null, null, null, null, null] +10971 - Fallen statue - [null, null, null, null, null] +10972 - Fallen statue - [null, null, null, null, null] +10973 - Fallen statue - [null, null, null, null, null] +10974 - Fallen statue - [null, null, null, null, null] +10975 - Fallen statue - [null, null, null, null, null] +10976 - Fallen statue - [null, null, null, null, null] +10977 - Fallen statue - [null, null, null, null, null] +10978 - Fallen statue - [null, null, null, null, null] +10979 - Fallen statue - [null, null, null, null, null] +10980 - Fallen statue - [null, null, null, null, null] +10981 - Fallen statue - [null, null, null, null, null] +10982 - Fallen statue - [null, null, null, null, null] +10983 - Fallen statue - [null, null, null, null, null] +10984 - Fallen statue - [null, null, null, null, null] +10985 - Fallen statue - [null, null, null, null, null] +10986 - Fallen statue - [null, null, null, null, null] +10987 - null - [null, null, null, null, null] +10988 - Pedestal - [null, null, null, null, null] +10989 - Pedestal - [null, null, null, null, null] +10990 - Pedestal - [null, null, null, null, null] +10991 - Pedestal - [null, null, null, null, null] +10992 - Pedestal - [null, null, null, null, null] +10993 - Pedestal - [null, null, null, null, null] +10994 - Pedestal - [null, null, null, null, null] +10995 - Pedestal - [null, null, null, null, null] +10996 - Pedestal - [null, null, null, null, null] +10997 - Pedestal - [null, null, null, null, null] +10998 - Pedestal - [null, null, null, null, null] +10999 - Pedestal - [null, null, null, null, null] +11000 - Pedestal - [null, null, null, null, null] +11001 - Pedestal - [null, null, null, null, null] +11002 - Pedestal - [null, null, null, null, null] +11003 - Pedestal - [null, null, null, null, null] +11004 - Pedestal - [null, null, null, null, null] +11005 - Magic barrier - [Pass-through, null, null, null, null] +11006 - null - [null, null, null, null, null] +11007 - Fountain - [null, null, null, null, null] +11008 - null - [null, null, null, null, null] +11009 - Furnace - [null, null, null, null, null] +11010 - Furnace - [null, Smelt, null, null, null] +11011 - null - [null, null, null, null, null] +11012 - null - [null, null, null, null, null] +11013 - null - [null, null, null, null, null] +11014 - null - [null, null, null, null, null] +11015 - null - [null, null, null, null, null] +11016 - null - [null, null, null, null, null] +11017 - Brazier - [Investigate, null, null, null, null] +11018 - Brazier - [Investigate, null, null, null, null] +11019 - Brazier - [Investigate, null, null, null, null] +11020 - Brazier - [Investigate, null, null, null, null] +11021 - Brazier - [Investigate, null, null, null, null] +11022 - Brazier - [Investigate, null, null, null, null] +11023 - Brazier - [Investigate, null, null, null, null] +11024 - Brazier - [Investigate, null, null, null, null] +11025 - Brazier - [Investigate, null, null, null, null] +11026 - null - [null, null, null, null, null] +11027 - null - [null, null, null, null, null] +11028 - Wall - [null, null, null, null, null] +11029 - Wall - [null, null, null, null, null] +11030 - Wall - [null, null, null, null, null] +11031 - Wall - [null, null, null, null, null] +11032 - Wall - [null, null, null, null, null] +11033 - Wall - [null, null, null, null, null] +11034 - Wall - [null, null, null, null, null] +11035 - Wall - [null, null, null, null, null] +11036 - Wall - [null, null, null, null, null] +11037 - Wall - [null, null, null, null, null] +11038 - Wall - [null, null, null, null, null] +11039 - Wall - [null, null, null, null, null] +11040 - Rubble - [Take-rock, null, null, null, null] +11041 - Ladder - [Climb-up, null, null, null, null] +11042 - Ladder - [Climb-down, null, null, null, null] +11043 - Stone Ladder - [Climb-up, null, null, null, null] +11044 - Stone Ladder - [Climb-down, null, null, null, null] +11045 - null - [null, null, null, null, null] +11046 - null - [null, null, null, null, null] +11047 - null - [null, null, null, null, null] +11048 - null - [null, null, null, null, null] +11049 - Boulder - [null, null, null, null, null] +11050 - Secret entrance - [Climb-down, null, null, null, null] +11051 - Door - [Open, null, null, null, null] +11052 - Door - [null, null, null, null, null] +11053 - Door - [Open, null, null, null, null] +11054 - Door - [null, null, null, null, null] +11055 - Door - [Open, null, null, null, null] +11056 - Door - [null, null, null, null, null] +11057 - Door - [Open, null, null, null, null] +11058 - Door - [null, null, null, null, null] +11059 - Pedestal - [null, null, null, null, null] +11060 - Pedestal - [Take-sigil, null, null, null, null] +11061 - Pedestal - [Take-sigil, null, null, null, null] +11062 - Pedestal - [Take-sigil, null, null, null, null] +11063 - Pedestal - [Take-sigil, null, null, null, null] +11064 - Door - [Open, null, null, null, null] +11065 - Door - [null, null, null, null, null] +11066 - Door - [Open, null, null, null, null] +11067 - Door - [null, null, null, null, null] +11068 - Door - [Open, null, null, null, null] +11069 - Door - [null, null, null, null, null] +11070 - Door - [Open, null, null, null, null] +11071 - Door - [null, null, null, null, null] +11072 - Ruins - [null, null, null, null, null] +11073 - Ruins - [null, null, null, null, null] +11074 - Ruins - [null, null, null, null, null] +11075 - Ruins - [null, null, null, null, null] +11076 - null - [null, null, null, null, null] +11077 - null - [null, null, null, null, null] +11078 - null - [null, null, null, null, null] +11079 - Light - [null, null, null, null, null] +11080 - Scaffold - [null, null, null, null, null] +11081 - Ladder - [null, null, null, null, null] +11082 - Wheelbarrow - [null, null, null, null, null] +11083 - null - [null, null, null, null, null] +11084 - null - [null, null, null, null, null] +11085 - null - [null, null, null, null, null] +11086 - null - [null, null, null, null, null] +11087 - null - [null, null, null, null, null] +11088 - null - [null, null, null, null, null] +11089 - null - [null, null, null, null, null] +11090 - null - [null, null, null, null, null] +11091 - null - [null, null, null, null, null] +11092 - null - [null, null, null, null, null] +11093 - null - [null, null, null, null, null] +11094 - null - [null, null, null, null, null] +11095 - null - [null, null, null, null, null] +11096 - null - [null, null, null, null, null] +11097 - Rock - [Take-axe, null, null, null, null] +11098 - Rock - [null, null, null, null, null] +11099 - null - [null, null, null, null, null] +11100 - null - [null, null, null, null, null] +11101 - null - [null, null, null, null, null] +11102 - null - [null, null, null, null, null] +11103 - null - [null, null, null, null, null] +11104 - null - [null, null, null, null, null] +11105 - null - [null, null, null, null, null] +11106 - null - [null, null, null, null, null] +11107 - null - [null, null, null, null, null] +11108 - null - [null, null, null, null, null] +11109 - null - [null, null, null, null, null] +11110 - null - [null, null, null, null, null] +11111 - null - [null, null, null, null, null] +11112 - Dead tree - [null, null, null, null, null] +11113 - Bush - [null, null, null, null, null] +11114 - null - [null, null, null, null, null] +11115 - null - [null, null, null, null, null] +11116 - null - [null, null, null, null, null] +11117 - null - [null, null, null, null, null] +11118 - null - [null, null, null, null, null] +11119 - null - [null, null, null, null, null] +11120 - null - [null, null, null, null, null] +11121 - null - [null, null, null, null, null] +11122 - null - [null, null, null, null, null] +11123 - null - [null, null, null, null, null] +11124 - null - [null, null, null, null, null] +11125 - null - [null, null, null, null, null] +11126 - null - [null, null, null, null, null] +11127 - null - [null, null, null, null, null] +11128 - null - [null, null, null, null, null] +11129 - null - [null, null, null, null, null] +11130 - null - [null, null, null, null, null] +11131 - null - [null, null, null, null, null] +11132 - null - [null, null, null, null, null] +11133 - null - [null, null, null, null, null] +11134 - null - [null, null, null, null, null] +11135 - null - [null, null, null, null, null] +11136 - null - [null, null, null, null, null] +11137 - null - [null, null, null, null, null] +11138 - null - [null, null, null, null, null] +11139 - null - [null, null, null, null, null] +11140 - null - [null, null, null, null, null] +11141 - Magic spell - [null, null, null, null, null] +11142 - null - [null, null, null, null, null] +11143 - null - [null, null, null, null, null] +11144 - null - [null, null, null, null, null] +11145 - null - [null, null, null, null, null] +11146 - null - [null, null, null, null, null] +11147 - null - [null, null, null, null, null] +11148 - null - [null, null, null, null, null] +11149 - null - [null, null, null, null, null] +11150 - null - [null, null, null, null, null] +11151 - Door - [Open, null, null, null, null] +11152 - Door - [Open, null, null, null, null] +11153 - Pedestal - [null, null, null, null, null] +11154 - null - [null, null, null, null, null] +11155 - null - [null, null, null, null, null] +11156 - null - [null, null, null, null, null] +11157 - null - [null, null, null, null, null] +11158 - null - [null, null, null, null, null] +11159 - null - [null, null, null, null, null] +11160 - null - [null, null, null, null, null] +11161 - null - [null, null, null, null, null] +11162 - Loader - [null, null, null, null, null] +11163 - Bone grinder - [Wind, Status, null, null, null] +11164 - Bin - [Empty, null, null, null, null] +11165 - Rocks - [Mine, Prospect, hidden, null, null] +11166 - Rocks - [Mine, Prospect, hidden, null, null] +11167 - Rocks - [Mine, Prospect, hidden, null, null] +11168 - Rocks - [Mine, Prospect, hidden, null, null] +11169 - Rocks - [Mine, Prospect, hidden, null, null] +11170 - Rocks - [Mine, Prospect, hidden, null, null] +11171 - Rocks - [Mine, Prospect, hidden, null, null] +11172 - Rocks - [Mine, Prospect, hidden, null, null] +11173 - Rocks - [Mine, Prospect, hidden, null, null] +11174 - Rocks - [Mine, Prospect, hidden, null, null] +11175 - Rocks - [Mine, Prospect, hidden, null, null] +11176 - Rocks - [Mine, Prospect, hidden, null, null] +11177 - Rocks - [Mine, Prospect, hidden, null, null] +11178 - Rocks - [Mine, Prospect, hidden, null, null] +11179 - Rocks - [Mine, Prospect, hidden, null, null] +11180 - Rocks - [Mine, Prospect, hidden, null, null] +11181 - Rocks - [Mine, Prospect, hidden, null, null] +11182 - Rocks - [Mine, Prospect, hidden, null, null] +11183 - Rocks - [Mine, Prospect, hidden, null, null] +11184 - Rocks - [Mine, Prospect, hidden, null, null] +11185 - Rocks - [Mine, Prospect, hidden, null, null] +11186 - Rocks - [Mine, Prospect, hidden, null, null] +11187 - Rocks - [Mine, Prospect, hidden, null, null] +11188 - Rocks - [Mine, Prospect, hidden, null, null] +11189 - Rocks - [Mine, Prospect, hidden, null, null] +11190 - Rocks - [Mine, Prospect, hidden, null, null] +11191 - Rocks - [Mine, Prospect, hidden, null, null] +11192 - Rocks - [Mine, Prospect, hidden, null, null] +11193 - Rocks - [Mine, Prospect, hidden, null, null] +11194 - Rocks - [Mine, Prospect, hidden, null, null] +11195 - Rocks - [Mine, Prospect, hidden, null, null] +11196 - Door - [Open, null, null, null, null] +11197 - Door - [Open, null, null, null, null] +11198 - Ladder - [Climb-up, null, null, null, null] +11199 - Ladder - [Climb-Down, null, null, null, null] +11200 - Ladder - [Climb-up, null, null, null, null] +11201 - Ladder - [Climb-Down, null, null, null, null] +11202 - Table - [View-game, null, null, null, null] +11203 - Table - [View-game, null, null, null, null] +11204 - Plaque - [null, null, null, null, null] +11205 - Plaque - [null, null, null, null, null] +11206 - Plaque - [null, null, null, null, null] +11207 - Plaque - [null, null, null, null, null] +11208 - Coffin - [null, null, null, null, null] +11209 - Gangplank - [Cross, null, null, null, null] +11210 - Gangplank - [Cross, null, null, null, null] +11211 - Gangplank - [Cross, null, null, null, null] +11212 - Gangplank - [Cross, null, null, null, null] +11213 - null - [Load, null, null, null, null] +11214 - Cannon - [Inspect, Empty-Out, null, null, null] +11215 - Broken Cannon - [Repair, null, null, null, null] +11216 - Broken Cannon - [Repair, null, null, null, null] +11217 - Cannon - [Fire!, null, null, null, null] +11218 - null - [null, null, null, null, null] +11219 - Cannon - [null, null, null, null, null] +11220 - Broken Cannon - [null, null, null, null, null] +11221 - null - [Repair, null, null, null, null] +11222 - null - [Repair, null, null, null, null] +11223 - null - [Repair, null, null, null, null] +11224 - null - [null, null, null, null, null] +11225 - null - [null, null, null, null, null] +11226 - null - [null, null, null, null, null] +11227 - null - [Loot, null, null, null, null] +11228 - Crate - [Loot, null, null, null, null] +11229 - Crate - [Loot, null, null, null, null] +11230 - null - [Plunder, null, null, null, null] +11231 - Closed chest - [Plunder, null, null, null, null] +11232 - Open chest - [Plunder, null, null, null, null] +11233 - null - [Loot, null, null, null, null] +11234 - Barrel - [Ransack, null, null, null, null] +11235 - Barrel - [Ransack, null, null, null, null] +11236 - Plunder Storage - [Count-Plunder, Store-Plunder, null, null, null] +11237 - null - [Take-Powder, null, null, null, null] +11238 - Powder Barrel - [Take-Powder, null, null, null, null] +11239 - Barrel - [Take-Powder, null, null, null, null] +11240 - Barrel - [Take-Powder, null, null, null, null] +11241 - null - [null, null, null, null, null] +11242 - null - [null, null, null, null, null] +11243 - null - [Climb, null, null, null, null] +11244 - Climbing Net - [Climb-Down, null, null, null, null] +11245 - Powder Barrel - [Take-Powder, null, null, null, null] +11246 - Repair Locker - [Open, null, null, null, null] +11247 - Repair Locker - [Search, Close, null, null, null] +11248 - Gun Locker - [Open, null, null, null, null] +11249 - Gun Locker - [Search, Close, null, null, null] +11250 - null - [null, null, null, null, null] +11251 - null - [null, null, null, null, null] +11252 - null - [null, null, null, null, null] +11253 - null - [null, null, null, null, null] +11254 - null - [null, null, null, null, null] +11255 - null - [null, null, null, null, null] +11256 - null - [null, null, null, null, null] +11257 - null - [null, null, null, null, null] +11258 - null - [null, null, null, null, null] +11259 - null - [null, null, null, null, null] +11260 - null - [null, null, null, null, null] +11261 - null - [null, null, null, null, null] +11262 - null - [null, null, null, null, null] +11263 - null - [null, null, null, null, null] +11264 - null - [null, null, null, null, null] +11265 - null - [null, null, null, null, null] +11266 - null - [null, null, null, null, null] +11267 - null - [null, null, null, null, null] +11268 - null - [null, null, null, null, null] +11269 - null - [null, null, null, null, null] +11270 - null - [null, null, null, null, null] +11271 - null - [null, null, null, null, null] +11272 - null - [null, null, null, null, null] +11273 - null - [null, null, null, null, null] +11274 - null - [null, null, null, null, null] +11275 - null - [null, null, null, null, null] +11276 - Mast - [null, null, null, null, null] +11277 - Mast - [null, null, null, null, null] +11278 - Mast - [null, null, null, null, null] +11279 - Mast - [null, null, null, null, null] +11280 - Sail - [null, null, null, null, null] +11281 - Sail - [null, null, null, null, null] +11282 - Sail - [null, null, null, null, null] +11283 - Sail - [null, null, null, null, null] +11284 - null - [null, null, null, null, null] +11285 - null - [null, null, null, null, null] +11286 - null - [null, null, null, null, null] +11287 - Figurehead - [null, null, null, null, null] +11288 - null - [null, null, null, null, null] +11289 - Ship's ladder - [Climb-up, null, null, null, null] +11290 - Ship's ladder - [Climb-down, null, null, null, null] +11291 - Sail - [null, null, null, null, null] +11292 - Hoisted sail - [null, null, null, null, null] +11293 - Hoisted sail - [null, null, null, null, null] +11294 - Hoisted sail - [null, null, null, null, null] +11295 - null - [null, null, null, null, null] +11296 - null - [null, null, null, null, null] +11297 - Hoisted sail - [null, null, null, null, null] +11298 - Hoisted sail - [null, null, null, null, null] +11299 - Hoisted sail - [null, null, null, null, null] +11300 - Hoisted sail - [null, null, null, null, null] +11301 - Hoisted sail - [null, null, null, null, null] +11302 - Sail - [null, null, null, null, null] +11303 - Hoisted sail - [null, null, null, null, null] +11304 - Hoisted sail - [null, null, null, null, null] +11305 - Barrel - [null, null, null, null, null] +11306 - Ship's wheel - [null, null, null, null, null] +11307 - Anchor - [null, null, null, null, null] +11308 - Ship's ladder - [Climb-up, null, null, null, null] +11309 - Ship's ladder - [Climb-down, null, null, null, null] +11310 - Climbing net - [Climb, null, null, null, null] +11311 - Rope - [null, null, null, null, null] +11312 - Cannon - [null, null, null, null, null] +11313 - Cannon - [null, null, null, null, null] +11314 - Cannon - [null, null, null, null, null] +11315 - Barrel - [null, null, null, null, null] +11316 - Fuse - [null, null, null, null, null] +11317 - Ship hull - [Fill, null, null, null, null] +11318 - Ship hull - [Waterproof, null, null, null, null] +11319 - Ship hull - [null, null, null, null, null] +11320 - Barrel - [null, null, null, null, null] +11321 - null - [null, null, null, null, null] +11322 - Barrel - [null, null, null, null, null] +11323 - Chest - [null, null, null, null, null] +11324 - Ancient Pillar - [null, null, null, null, null] +11325 - null - [null, null, null, null, null] +11326 - null - [null, null, null, null, null] +11327 - null - [null, null, null, null, null] +11328 - null - [null, null, null, null, null] +11329 - null - [null, null, null, null, null] +11330 - Crate - [null, null, null, null, null] +11331 - Crate - [null, null, null, null, null] +11332 - Gate - [null, null, null, null, null] +11333 - Gate - [null, null, null, null, null] +11334 - null - [null, null, null, null, null] +11335 - Bamboo Desk - [null, null, null, null, null] +11336 - Bamboo Desk - [null, null, null, null, null] +11337 - Bamboo Desk - [null, null, null, null, null] +11338 - Bank booth - [Use, Use-quickly, Collect, null, null] +11339 - Open chest - [null, null, null, null, null] +11340 - null - [null, null, null, null, null] +11341 - Closed chest - [null, null, null, null, null] +11342 - Repair Locker - [null, null, null, null, null] +11343 - Gun Locker - [null, null, null, null, null] +11344 - null - [null, null, null, null, null] +11345 - null - [null, null, null, null, null] +11346 - null - [null, null, null, null, null] +11347 - null - [null, null, null, null, null] +11348 - null - [null, null, null, null, null] +11349 - null - [null, null, null, null, null] +11350 - null - [null, null, null, null, null] +11351 - null - [null, null, null, null, null] +11352 - null - [null, null, null, null, null] +11353 - null - [null, null, null, null, null] +11354 - Interdimensional rift - [Enter, null, null, null, null] +11355 - null - [null, null, null, null, null] +11356 - Portal Home - [Enter, null, null, null, null] +11357 - Portal machine - [null, null, null, null, null] +11358 - Staircase - [Climb-up, null, null, null, null] +11359 - null - [null, null, null, null, null] +11360 - Pie stall - [null, null, null, null, null] +11361 - Raw chompy bird - [null, null, null, null, null] +11362 - Raw Rabbit - [null, null, null, null, null] +11363 - Iron spit - [null, null, null, null, null] +11364 - Decorative Pillar - [Light, null, null, null, null] +11365 - Decorative Pillar - [Light, null, null, null, null] +11366 - Decorative Pillar - [Light, null, null, null, null] +11367 - Decorative Pillar - [Light, null, null, null, null] +11368 - null - [Light, null, null, null, null] +11369 - null - [Light, null, null, null, null] +11370 - null - [Light, null, null, null, null] +11371 - null - [Light, null, null, null, null] +11372 - null - [Light, null, null, null, null] +11373 - null - [Light, null, null, null, null] +11374 - null - [Light, null, null, null, null] +11375 - null - [Light, null, null, null, null] +11376 - null - [Light, null, null, null, null] +11377 - null - [Light, null, null, null, null] +11378 - null - [Light, null, null, null, null] +11379 - Large door - [Open, null, null, null, null] +11380 - Large door - [Close, null, null, null, null] +11381 - Large door - [Open, null, null, null, null] +11382 - Large door - [Close, null, null, null, null] +11383 - Decorative Pillar - [Light, null, null, null, null] +11384 - Decorative Pillar - [Light, null, null, null, null] +11385 - Decorative Pillar - [Light, null, null, null, null] +11386 - Decorative Pillar - [Light, null, null, null, null] +11387 - Decorative Pillar - [Light, null, null, null, null] +11388 - Decorative Pillar - [Light, null, null, null, null] +11389 - Decorative Pillar - [Light, null, null, null, null] +11390 - Decorative Pillar - [Light, null, null, null, null] +11391 - Decorative Pillar - [Light, null, null, null, null] +11392 - Decorative Pillar - [Light, null, null, null, null] +11393 - Decorative Pillar - [Light, null, null, null, null] +11394 - Decorative Pillar - [Light, null, null, null, null] +11395 - Pillar candle. - [null, null, null, null, null] +11396 - Melted candle. - [null, null, null, null, null] +11397 - Pillar candle flame. - [null, null, null, null, null] +11398 - Our lives - [Read, Leave, null, null, null] +11399 - Cave entrance - [Crawl-through, null, null, null, null] +11400 - Web - [Slash, null, null, null, null] +11401 - Slashed web - [null, null, null, null, null] +11402 - Bank booth - [Use, Use-quickly, Collect, null, null] +11403 - null - [null, null, null, null, null] +11404 - Fire - [null, null, null, null, null] +11405 - Fire - [null, null, null, null, null] +11406 - Fire - [null, null, null, null, null] +11407 - null - [null, null, null, null, null] +11408 - null - [null, null, null, null, null] +11409 - pipe with rope - [null, null, null, null, null] +11410 - Pipe - [null, null, null, null, null] +11411 - Rope - [null, null, null, null, null] +11412 - straight rope - [null, null, null, null, null] +11413 - Rope - [null, null, null, null, null] +11414 - Rope - [null, null, null, null, null] +11415 - Rope - [null, null, null, null, null] +11416 - Rope - [null, null, null, null, null] +11417 - Dug hole - [Climb-down, null, null, null, null] +11418 - Mud patch - [null, null, null, null, null] +11419 - null - [null, null, null, null, null] +11420 - null - [null, null, null, null, null] +11421 - null - [null, null, null, null, null] +11422 - null - [null, null, null, null, null] +11423 - Grill - [Open, null, null, null, null] +11424 - Rocks - [Mine, Prospect, hidden, null, null] +11425 - Rocks - [Mine, Prospect, hidden, null, null] +11426 - Rocks - [Mine, Prospect, hidden, null, null] +11427 - Rocks - [Mine, Prospect, hidden, null, null] +11428 - Rocks - [Mine, Prospect, hidden, null, null] +11429 - Rocks - [Mine, Prospect, hidden, null, null] +11430 - Rocks - [Mine, Prospect, hidden, null, null] +11431 - Rocks - [Mine, Prospect, hidden, null, null] +11432 - Rocks - [Mine, Prospect, hidden, null, null] +11433 - Rocks - [Mine, Prospect, hidden, null, null] +11434 - Rocks - [Mine, Prospect, hidden, null, null] +11435 - Rocks - [Mine, Prospect, hidden, null, null] +11436 - Rocks - [Mine, Prospect, hidden, null, null] +11437 - Rocks - [Mine, Prospect, hidden, null, null] +11438 - Rocks - [Mine, Prospect, hidden, null, null] +11439 - Rocks - [Mine, Prospect, hidden, null, null] +11440 - Rocks - [Mine, Prospect, hidden, null, null] +11441 - Rocks - [Mine, Prospect, hidden, null, null] +11442 - Rocks - [Mine, Prospect, hidden, null, null] +11443 - Rocks - [Mine, Prospect, hidden, null, null] +11444 - Rocks - [Mine, Prospect, hidden, null, null] +11445 - null - [null, null, null, null, null] +11446 - null - [null, null, null, null, null] +11447 - null - [null, null, null, null, null] +11448 - null - [null, null, null, null, null] +11449 - Door - [null, null, null, null, null] +11450 - Door - [Open, null, null, null, null] +11451 - Lever A - [Pull, Inspect, null, null, null] +11452 - Lever A - [Pull, Inspect, null, null, null] +11453 - Lever B - [Pull, Inspect, null, null, null] +11454 - Lever B - [Pull, Inspect, null, null, null] +11455 - Lever C - [Pull, Inspect, null, null, null] +11456 - Lever C - [Pull, Inspect, null, null, null] +11457 - Lever D - [Pull, Inspect, null, null, null] +11458 - Lever D - [Pull, Inspect, null, null, null] +11459 - Lever E - [Pull, Inspect, null, null, null] +11460 - Lever E - [Pull, Inspect, null, null, null] +11461 - Lever F - [Pull, Inspect, null, null, null] +11462 - Lever F - [Pull, Inspect, null, null, null] +11463 - null - [null, null, null, null, null] +11464 - null - [null, null, null, null, null] +11465 - null - [null, null, null, null, null] +11466 - null - [null, null, null, null, null] +11467 - null - [null, null, null, null, null] +11468 - Lantern - [null, null, null, null, null] +11469 - Spooky picture - [null, null, null, null, null] +11470 - Door - [Open, null, null, null, null] +11471 - Door - [Close, null, null, null, null] +11472 - Candles - [null, null, null, null, null] +11473 - Candles - [null, null, null, null, null] +11474 - null - [null, null, null, null, null] +11475 - null - [null, null, null, null, null] +11476 - null - [null, null, null, null, null] +11477 - null - [null, null, null, null, null] +11478 - null - [null, null, null, null, null] +11479 - null - [null, null, null, null, null] +11480 - null - [null, null, null, null, null] +11481 - null - [null, null, null, null, null] +11482 - null - [null, null, null, null, null] +11483 - Door - [Open, null, null, null, null] +11484 - Barrel - [null, null, null, null, null] +11485 - Crate - [Search, null, null, null, null] +11486 - Crates - [Search, null, null, null, null] +11487 - Boxes - [null, null, null, null, null] +11488 - Crates - [null, null, null, null, null] +11489 - Chair - [null, null, null, null, null] +11490 - Chair - [null, null, null, null, null] +11491 - Large Table - [null, null, null, null, null] +11492 - Smashed chair - [null, null, null, null, null] +11493 - Grandfather clock - [null, null, null, null, null] +11494 - Cabbage - [Pick, null, null, null, null] +11495 - Gallows - [null, null, null, null, null] +11496 - Chair - [null, null, null, null, null] +11497 - Spooky picture - [null, null, null, null, null] +11498 - Staircase - [Climb-up, null, null, null, null] +11499 - Staircase - [Climb-down, null, null, null, null] +11500 - Table - [null, null, null, null, null] +11501 - Table - [null, null, null, null, null] +11502 - Table - [null, null, null, null, null] +11503 - Table - [null, null, null, null, null] +11504 - Table - [null, null, null, null, null] +11505 - null - [null, null, null, null, null] +11506 - null - [null, null, null, null, null] +11507 - null - [null, null, null, null, null] +11508 - null - [null, null, null, null, null] +11509 - null - [null, null, null, null, null] +11510 - Dead tree - [null, null, null, null, null] +11511 - Staircase - [Climb-up, null, null, null, null] +11512 - null - [null, null, null, null, null] +11513 - null - [null, null, null, null, null] +11514 - null - [null, null, null, null, null] +11515 - null - [null, null, null, null, null] +11516 - null - [null, null, null, null, null] +11517 - null - [null, null, null, null, null] +11518 - null - [null, null, null, null, null] +11519 - null - [null, null, null, null, null] +11520 - null - [null, null, null, null, null] +11521 - null - [null, null, null, null, null] +11522 - null - [null, null, null, null, null] +11523 - null - [null, null, null, null, null] +11524 - null - [null, null, null, null, null] +11525 - null - [null, null, null, null, null] +11526 - null - [null, null, null, null, null] +11527 - null - [null, null, null, null, null] +11528 - null - [null, null, null, null, null] +11529 - null - [null, null, null, null, null] +11530 - null - [null, null, null, null, null] +11531 - null - [null, null, null, null, null] +11532 - null - [null, null, null, null, null] +11533 - null - [null, null, null, null, null] +11534 - null - [null, null, null, null, null] +11535 - null - [null, null, null, null, null] +11536 - null - [null, null, null, null, null] +11537 - null - [null, null, null, null, null] +11538 - null - [null, null, null, null, null] +11539 - null - [null, null, null, null, null] +11540 - null - [null, null, null, null, null] +11541 - null - [null, null, null, null, null] +11542 - null - [null, null, null, null, null] +11543 - null - [null, null, null, null, null] +11544 - null - [null, null, null, null, null] +11545 - null - [null, null, null, null, null] +11546 - Strange machine - [null, null, null, null, null] +11547 - Strange machine - [null, null, null, null, null] +11548 - Strange machine - [null, null, null, null, null] +11549 - Strange machine - [null, null, null, null, null] +11550 - Strange machine - [null, null, null, null, null] +11551 - Table - [null, null, null, null, null] +11552 - Rocks - [Mine, Prospect, hidden, null, null] +11553 - Rocks - [Mine, Prospect, hidden, null, null] +11554 - Rocks - [Mine, Prospect, hidden, null, null] +11555 - Rocks - [Mine, Prospect, hidden, null, null] +11556 - Rocks - [Mine, Prospect, hidden, null, null] +11557 - Rocks - [Mine, Prospect, hidden, null, null] +11558 - null - [null, null, null, null, null] +11559 - null - [null, null, null, null, null] +11560 - null - [null, null, null, null, null] +11561 - null - [null, null, null, null, null] +11562 - null - [null, null, null, null, null] +11563 - null - [null, null, null, null, null] +11564 - null - [null, null, null, null, null] +11565 - null - [null, null, null, null, null] +11566 - null - [null, null, null, null, null] +11567 - null - [null, null, null, null, null] +11568 - null - [null, null, null, null, null] +11569 - null - [null, null, null, null, null] +11570 - null - [null, null, null, null, null] +11571 - null - [null, null, null, null, null] +11572 - null - [null, null, null, null, null] +11573 - null - [null, null, null, null, null] +11574 - null - [null, null, null, null, null] +11575 - null - [null, null, null, null, null] +11576 - null - [null, null, null, null, null] +11577 - null - [null, null, null, null, null] +11578 - null - [null, null, null, null, null] +11579 - null - [null, null, null, null, null] +11580 - null - [null, null, null, null, null] +11581 - null - [null, null, null, null, null] +11582 - null - [null, null, null, null, null] +11583 - null - [null, null, null, null, null] +11584 - null - [null, null, null, null, null] +11585 - null - [null, null, null, null, null] +11586 - null - [null, null, null, null, null] +11587 - null - [null, null, null, null, null] +11588 - null - [null, null, null, null, null] +11589 - Barrel - [null, null, null, null, null] +11590 - Barrel - [null, null, null, null, null] +11591 - null - [null, null, null, null, null] +11592 - null - [null, null, null, null, null] +11593 - null - [null, null, null, null, null] +11594 - null - [null, null, null, null, null] +11595 - null - [null, null, null, null, null] +11596 - null - [null, null, null, null, null] +11597 - null - [null, null, null, null, null] +11598 - null - [null, null, null, null, null] +11599 - Crate - [null, null, null, null, null] +11600 - Crates - [Search, null, null, null, null] +11601 - Pottery Oven - [Fire, null, null, null, null] +11602 - null - [null, null, null, null, null] +11603 - Stool - [null, null, null, null, null] +11604 - null - [null, null, null, null, null] +11605 - null - [null, null, null, null, null] +11606 - Standing torch - [null, null, null, null, null] +11607 - null - [null, null, null, null, null] +11608 - null - [null, null, null, null, null] +11609 - null - [null, null, null, null, null] +11610 - null - [null, null, null, null, null] +11611 - null - [null, null, null, null, null] +11612 - null - [null, null, null, null, null] +11613 - null - [null, null, null, null, null] +11614 - Standard - [null, null, null, null, null] +11615 - Standard - [null, null, null, null, null] +11616 - Door - [Open, null, null, null, null] +11617 - Door - [Close, null, null, null, null] +11618 - null - [null, null, null, null, null] +11619 - Table - [null, null, null, null, null] +11620 - Longhall door - [Open, null, null, null, null] +11621 - Longhall door - [Open, null, null, null, null] +11622 - null - [null, null, null, null, null] +11623 - null - [null, null, null, null, null] +11624 - Longhall door - [Close, null, null, null, null] +11625 - Longhall door - [Close, null, null, null, null] +11626 - Counter - [null, null, null, null, null] +11627 - Small Table - [null, null, null, null, null] +11628 - null - [null, null, null, null, null] +11629 - Rock - [null, null, null, null, null] +11630 - Stone signpost - [null, null, null, null, null] +11631 - Stone signpost - [null, null, null, null, null] +11632 - null - [null, null, null, null, null] +11633 - null - [null, null, null, null, null] +11634 - Rock - [null, null, null, null, null] +11635 - Rock - [null, null, null, null, null] +11636 - Rock - [null, null, null, null, null] +11637 - Rock - [null, null, null, null, null] +11638 - Rock - [null, null, null, null, null] +11639 - Rock - [null, null, null, null, null] +11640 - City gate - [null, null, null, null, null] +11641 - City gate - [null, null, null, null, null] +11642 - City gate - [null, null, null, null, null] +11643 - City gate - [null, null, null, null, null] +11644 - City gate - [null, null, null, null, null] +11645 - City gate - [null, null, null, null, null] +11646 - City gate - [null, null, null, null, null] +11647 - City gate - [null, null, null, null, null] +11648 - City gate - [null, null, null, null, null] +11649 - City gate - [null, null, null, null, null] +11650 - City gate - [null, null, null, null, null] +11651 - City gate - [null, null, null, null, null] +11652 - null - [null, null, null, null, null] +11653 - null - [null, null, null, null, null] +11654 - null - [null, null, null, null, null] +11655 - null - [null, null, null, null, null] +11656 - null - [null, null, null, null, null] +11657 - Rack - [null, null, null, null, null] +11658 - Shelves - [null, null, null, null, null] +11659 - Barrel - [null, null, null, null, null] +11660 - Table - [null, null, null, null, null] +11661 - Waterpump - [null, null, null, null, null] +11662 - Shop counter - [null, null, null, null, null] +11663 - Cabinet - [null, null, null, null, null] +11664 - null - [null, null, null, null, null] +11665 - null - [null, null, null, null, null] +11666 - Furnace - [null, Smelt, null, null, null] +11667 - null - [null, null, null, null, null] +11668 - null - [null, null, null, null, null] +11669 - null - [null, null, null, null, null] +11670 - null - [null, null, null, null, null] +11671 - null - [null, null, null, null, null] +11672 - null - [null, null, null, null, null] +11673 - null - [null, null, null, null, null] +11674 - Sign - [null, null, null, null, null] +11675 - Banner - [null, null, null, null, null] +11676 - null - [null, null, null, null, null] +11677 - Treadmill - [null, null, null, null, null] +11678 - Spinning pole - [null, null, null, null, null] +11679 - null - [null, null, null, null, null] +11680 - null - [null, null, null, null, null] +11681 - null - [null, null, null, null, null] +11682 - Table - [null, null, null, null, null] +11683 - null - [null, null, null, null, null] +11684 - null - [null, null, null, null, null] +11685 - null - [null, null, null, null, null] +11686 - null - [null, null, null, null, null] +11687 - null - [null, null, null, null, null] +11688 - null - [null, null, null, null, null] +11689 - null - [null, null, null, null, null] +11690 - null - [null, null, null, null, null] +11691 - null - [null, null, null, null, null] +11692 - null - [null, null, null, null, null] +11693 - Statue - [null, null, null, null, null] +11694 - Statue - [null, null, null, null, null] +11695 - Statue - [null, null, null, null, null] +11696 - Statue - [null, null, null, null, null] +11697 - Statue - [null, null, null, null, null] +11698 - Old bookshelf - [Search, null, null, null, null] +11699 - Flagpole - [null, null, null, null, null] +11700 - Statue of Saradomin - [null, null, null, null, null] +11701 - Statue of Saradomin - [null, null, null, null, null] +11702 - null - [null, null, null, null, null] +11703 - null - [null, null, null, null, null] +11704 - null - [null, null, null, null, null] +11705 - null - [null, null, null, null, null] +11706 - Rockery - [null, null, null, null, null] +11707 - Door - [Open, null, null, null, null] +11708 - Door - [Close, null, null, null, null] +11709 - Door - [Open, null, null, null, null] +11710 - Door - [Close, null, null, null, null] +11711 - Door - [Open, null, null, null, null] +11712 - Door - [Close, null, null, null, null] +11713 - Door - [Open, null, null, null, null] +11714 - Door - [Open, null, null, null, null] +11715 - Door - [Close, null, null, null, null] +11716 - Castle door - [Open, null, null, null, null] +11717 - Castle door - [Open, null, null, null, null] +11718 - Castle door - [Close, null, null, null, null] +11719 - Castle door - [Open, null, null, null, null] +11720 - Castle door - [Close, null, null, null, null] +11721 - Castle door - [Open, null, null, null, null] +11722 - Castle door - [Close, null, null, null, null] +11723 - Castle door - [Close, null, null, null, null] +11724 - Staircase - [Climb-up, null, null, null, null] +11725 - Staircase - [Climb-down, null, null, null, null] +11726 - null - [null, null, null, null, null] +11727 - Ladder - [Climb-up, null, null, null, null] +11728 - Ladder - [Climb-down, null, null, null, null] +11729 - Staircase - [Climb-up, null, null, null, null] +11730 - null - [null, null, null, null, null] +11731 - Staircase - [Climb-down, null, null, null, null] +11732 - Staircase - [Climb-up, null, null, null, null] +11733 - Staircase - [Climb-down, null, null, null, null] +11734 - Staircase - [Climb-up, null, null, null, null] +11735 - Staircase - [Climb-down, null, null, null, null] +11736 - Staircase - [Climb-up, null, null, null, null] +11737 - Staircase - [Climb-down, null, null, null, null] +11738 - Large table - [null, null, null, null, null] +11739 - Ladder - [Climb-up, null, null, null, null] +11740 - Ladder - [Climb-up, null, null, null, null] +11741 - Ladder - [Climb-down, null, null, null, null] +11742 - Ladder - [Climb-down, null, null, null, null] +11743 - Table - [null, null, null, null, null] +11744 - Boxes - [Search, null, null, null, null] +11745 - Crates - [Search, null, null, null, null] +11746 - Stool - [null, null, null, null, null] +11747 - Bed - [null, null, null, null, null] +11748 - Table - [null, null, null, null, null] +11749 - Table - [null, null, null, null, null] +11750 - null - [null, null, null, null, null] +11751 - null - [null, null, null, null, null] +11752 - null - [null, null, null, null, null] +11753 - Suit of armour - [null, null, null, null, null] +11754 - null - [null, null, null, null, null] +11755 - Noticeboard - [Read, null, null, null, null] +11756 - Noticeboard - [Read, null, null, null, null] +11757 - Chest - [null, null, null, null, null] +11758 - Bank booth - [Use, Use-quickly, Collect, null, null] +11759 - Fountain - [null, null, null, null, null] +11760 - Chair - [null, null, null, null, null] +11761 - Statue - [null, null, null, null, null] +11762 - Bar pumps - [null, null, null, null, null] +11763 - Bar - [null, null, null, null, null] +11764 - Picnic table - [null, null, null, null, null] +11765 - Barrel - [null, null, null, null, null] +11766 - Barrel - [null, null, null, null, null] +11767 - Bookcase - [Search, null, null, null, null] +11768 - Shelves - [null, null, null, null, null] +11769 - Shelves - [null, null, null, null, null] +11770 - Shelves - [null, null, null, null, null] +11771 - Shelves - [null, null, null, null, null] +11772 - null - [null, null, null, null, null] +11773 - null - [null, null, null, null, null] +11774 - null - [null, null, null, null, null] +11775 - null - [null, null, null, null, null] +11776 - null - [null, null, null, null, null] +11777 - null - [null, null, null, null, null] +11778 - null - [null, null, null, null, null] +11779 - null - [null, null, null, null, null] +11780 - null - [null, null, null, null, null] +11781 - null - [null, null, null, null, null] +11782 - Standing stone - [null, null, null, null, null] +11783 - Standing stone - [null, null, null, null, null] +11784 - Standing stone - [null, null, null, null, null] +11785 - Standing stone - [null, null, null, null, null] +11786 - null - [null, null, null, null, null] +11787 - null - [null, null, null, null, null] +11788 - null - [null, null, null, null, null] +11789 - Rocks - [null, null, null, null, null] +11790 - Rocks - [null, null, null, null, null] +11791 - Rocks - [null, null, null, null, null] +11792 - null - [null, null, null, null, null] +11793 - Well - [null, null, null, null, null] +11794 - Chair - [null, null, null, null, null] +11795 - Chair - [null, null, null, null, null] +11796 - Mirror - [null, null, null, null, null] +11797 - null - [null, null, null, null, null] +11798 - null - [null, null, null, null, null] +11799 - Heater - [null, null, null, null, null] +11800 - null - [null, null, null, null, null] +11801 - null - [null, null, null, null, null] +11802 - null - [null, null, null, null, null] +11803 - null - [null, null, null, null, null] +11804 - null - [null, null, null, null, null] +11805 - null - [null, null, null, null, null] +11806 - null - [null, null, null, null, null] +11807 - null - [null, null, null, null, null] +11808 - null - [null, null, null, null, null] +11809 - null - [null, null, null, null, null] +11810 - null - [null, null, null, null, null] +11811 - null - [null, null, null, null, null] +11812 - Bathtub - [null, null, null, null, null] +11813 - Workbench - [null, null, null, null, null] +11814 - Workbench - [null, null, null, null, null] +11815 - null - [null, null, null, null, null] +11816 - null - [null, null, null, null, null] +11817 - null - [null, null, null, null, null] +11818 - null - [null, null, null, null, null] +11819 - null - [null, null, null, null, null] +11820 - null - [null, null, null, null, null] +11821 - null - [null, null, null, null, null] +11822 - null - [null, null, null, null, null] +11823 - null - [null, null, null, null, null] +11824 - null - [null, null, null, null, null] +11825 - null - [null, null, null, null, null] +11826 - null - [null, null, null, null, null] +11827 - null - [null, null, null, null, null] +11828 - null - [null, null, null, null, null] +11829 - null - [null, null, null, null, null] +11830 - null - [null, null, null, null, null] +11831 - null - [null, null, null, null, null] +11832 - null - [null, null, null, null, null] +11833 - null - [null, null, null, null, null] +11834 - null - [null, null, null, null, null] +11835 - null - [null, null, null, null, null] +11836 - null - [null, null, null, null, null] +11837 - null - [null, null, null, null, null] +11838 - null - [null, null, null, null, null] +11839 - null - [null, null, null, null, null] +11840 - Bricks - [null, null, null, null, null] +11841 - Bricks - [null, null, null, null, null] +11842 - null - [null, null, null, null, null] +11843 - null - [null, null, null, null, null] +11844 - Crumbling wall - [Climb-over, null, null, null, null] +11845 - null - [null, null, null, null, null] +11846 - null - [null, null, null, null, null] +11847 - null - [null, null, null, null, null] +11848 - Bow cabinet - [null, null, null, null, null] +11849 - Table - [null, null, null, null, null] +11850 - null - [null, null, null, null, null] +11851 - null - [null, null, null, null, null] +11852 - null - [null, null, null, null, null] +11853 - null - [null, null, null, null, null] +11854 - null - [null, null, null, null, null] +11855 - null - [null, null, null, null, null] +11856 - null - [null, null, null, null, null] +11857 - null - [null, null, null, null, null] +11858 - null - [null, null, null, null, null] +11859 - null - [null, null, null, null, null] +11860 - null - [null, null, null, null, null] +11861 - Standard - [null, null, null, null, null] +11862 - Dwarf bath - [null, null, null, null, null] +11863 - Winch - [null, null, null, null, null] +11864 - null - [null, null, null, null, null] +11865 - null - [null, null, null, null, null] +11866 - null - [null, null, null, null, null] +11867 - Trapdoor - [Climb-down, null, null, null, null] +11868 - Dwarf multicannon - [null, null, null, null, null] +11869 - Multicannon parts - [null, null, null, null, null] +11870 - Multicannon parts - [null, null, null, null, null] +11871 - null - [null, null, null, null, null] +11872 - null - [null, null, null, null, null] +11873 - Multicannon parts - [null, null, null, null, null] +11874 - Multicannon parts - [null, null, null, null, null] +11875 - Canary - [null, null, null, null, null] +11876 - Blacksmiths' tools - [null, null, null, null, null] +11877 - Bed - [null, null, null, null, null] +11878 - null - [null, null, null, null, null] +11879 - null - [null, null, null, null, null] +11880 - null - [null, null, null, null, null] +11881 - null - [null, null, null, null, null] +11882 - null - [null, null, null, null, null] +11883 - null - [null, null, null, null, null] +11884 - null - [null, null, null, null, null] +11885 - null - [null, null, null, null, null] +11886 - null - [null, null, null, null, null] +11887 - null - [null, null, null, null, null] +11888 - Staircase - [Climb-up, null, null, null, null] +11889 - Staircase - [Climb, Climb-up, Climb-down, null, null] +11890 - Staircase - [Climb-down, null, null, null, null] +11891 - Sinister barrel - [null, null, null, null, null] +11892 - Table - [null, null, null, null, null] +11893 - Bookcase - [null, null, null, null, null] +11894 - Bookcase - [null, null, null, null, null] +11895 - Thorns - [null, null, null, null, null] +11896 - Thorns - [null, null, null, null, null] +11897 - Thorns - [null, null, null, null, null] +11898 - null - [null, null, null, null, null] +11899 - null - [null, null, null, null, null] +11900 - null - [null, null, null, null, null] +11901 - null - [null, null, null, null, null] +11902 - null - [null, null, null, null, null] +11903 - null - [null, null, null, null, null] +11904 - null - [null, null, null, null, null] +11905 - null - [null, null, null, null, null] +11906 - null - [null, null, null, null, null] +11907 - null - [null, null, null, null, null] +11908 - null - [null, null, null, null, null] +11909 - null - [null, null, null, null, null] +11910 - Creature - [null, null, null, null, null] +11911 - Bush - [null, null, null, null, null] +11912 - Bush - [null, null, null, null, null] +11913 - Bush - [null, null, null, null, null] +11914 - Bush - [null, null, null, null, null] +11915 - Rocks - [Mine, Prospect, hidden, null, null] +11916 - Rocks - [Mine, Prospect, hidden, null, null] +11917 - Rocks - [Mine, Prospect, hidden, null, null] +11918 - Rocks - [Mine, Prospect, hidden, null, null] +11919 - Rocks - [Mine, Prospect, hidden, null, null] +11920 - Rocks - [Mine, Prospect, hidden, null, null] +11921 - Rocks - [Mine, Prospect, hidden, null, null] +11922 - Rocks - [Mine, Prospect, hidden, null, null] +11923 - Rocks - [Mine, Prospect, hidden, null, null] +11924 - Rocks - [Mine, Prospect, hidden, null, null] +11925 - Rocks - [Mine, Prospect, hidden, null, null] +11926 - Rocks - [Mine, Prospect, hidden, null, null] +11927 - Rocks - [Mine, Prospect, hidden, null, null] +11928 - Rocks - [Mine, Prospect, hidden, null, null] +11929 - Rocks - [Mine, Prospect, hidden, null, null] +11930 - Rocks - [Mine, Prospect, hidden, null, null] +11931 - Rocks - [Mine, Prospect, hidden, null, null] +11932 - Rocks - [Mine, Prospect, hidden, null, null] +11933 - Rocks - [Mine, Prospect, hidden, null, null] +11934 - Rocks - [Mine, Prospect, hidden, null, null] +11935 - Rocks - [Mine, Prospect, hidden, null, null] +11936 - Rocks - [Mine, Prospect, hidden, null, null] +11937 - Rocks - [Mine, Prospect, hidden, null, null] +11938 - Rocks - [Mine, Prospect, hidden, null, null] +11939 - Rocks - [Mine, Prospect, hidden, null, null] +11940 - Rocks - [Mine, Prospect, hidden, null, null] +11941 - Rocks - [Mine, Prospect, hidden, null, null] +11942 - Rocks - [Mine, Prospect, hidden, null, null] +11943 - Rocks - [Mine, Prospect, hidden, null, null] +11944 - Rocks - [Mine, Prospect, hidden, null, null] +11945 - Rocks - [Mine, Prospect, hidden, null, null] +11946 - Rocks - [Mine, Prospect, hidden, null, null] +11947 - Rocks - [Mine, Prospect, hidden, null, null] +11948 - Rocks - [Mine, Prospect, hidden, null, null] +11949 - Rocks - [Mine, Prospect, hidden, null, null] +11950 - Rocks - [Mine, Prospect, hidden, null, null] +11951 - Rocks - [Mine, Prospect, hidden, null, null] +11952 - Rocks - [Mine, Prospect, hidden, null, null] +11953 - Rocks - [Mine, Prospect, hidden, null, null] +11954 - Rocks - [Mine, Prospect, hidden, null, null] +11955 - Rocks - [Mine, Prospect, hidden, null, null] +11956 - Rocks - [Mine, Prospect, hidden, null, null] +11957 - Rocks - [Mine, Prospect, hidden, null, null] +11958 - Rocks - [Mine, Prospect, hidden, null, null] +11959 - Rocks - [Mine, Prospect, hidden, null, null] +11960 - Rocks - [Mine, Prospect, hidden, null, null] +11961 - Rocks - [Mine, Prospect, hidden, null, null] +11962 - Rocks - [Mine, Prospect, hidden, null, null] +11963 - Rocks - [Mine, Prospect, hidden, null, null] +11964 - Rocks - [Mine, Prospect, hidden, null, null] +11965 - Rocks - [Mine, Prospect, hidden, null, null] +11966 - null - [null, null, null, null, null] +11967 - null - [null, null, null, null, null] +11968 - null - [null, null, null, null, null] +11969 - null - [null, null, null, null, null] +11970 - null - [null, null, null, null, null] +11971 - null - [null, null, null, null, null] +11972 - null - [null, null, null, null, null] +11973 - null - [null, null, null, null, null] +11974 - null - [null, null, null, null, null] +11975 - null - [null, null, null, null, null] +11976 - null - [null, null, null, null, null] +11977 - null - [null, null, null, null, null] +11978 - null - [null, null, null, null, null] +11979 - null - [null, null, null, null, null] +11980 - null - [null, null, null, null, null] +11981 - null - [null, null, null, null, null] +11982 - null - [null, null, null, null, null] +11983 - null - [null, null, null, null, null] +11984 - null - [null, null, null, null, null] +11985 - null - [null, null, null, null, null] +11986 - null - [null, null, null, null, null] +11987 - null - [null, null, null, null, null] +11988 - null - [null, null, null, null, null] +11989 - null - [null, null, null, null, null] +11990 - null - [null, null, null, null, null] +11991 - null - [null, null, null, null, null] +11992 - null - [null, null, null, null, null] +11993 - Door - [Open, null, null, null, null] +11994 - Door - [Close, null, null, null, null] +11995 - null - [null, null, null, null, null] +11996 - null - [null, null, null, null, null] +11997 - null - [null, null, null, null, null] +11998 - null - [null, null, null, null, null] +11999 - null - [null, null, null, null, null] +12000 - null - [null, null, null, null, null] +12001 - null - [null, null, null, null, null] +12002 - null - [null, null, null, null, null] +12003 - Fairy ring - [Use, null, null, null, null] +12004 - A gap through the wall - [Squeeze-through, null, null, null, null] +12005 - Mushroom torch - [null, null, null, null, null] +12006 - Mushroom torch - [null, null, null, null, null] +12007 - null - [null, null, null, null, null] +12008 - null - [null, null, null, null, null] +12009 - null - [null, null, null, null, null] +12010 - null - [null, null, null, null, null] +12011 - null - [null, null, null, null, null] +12012 - null - [null, null, null, null, null] +12013 - null - [null, null, null, null, null] +12014 - null - [null, null, null, null, null] +12015 - null - [null, null, null, null, null] +12016 - null - [null, null, null, null, null] +12017 - null - [null, null, null, null, null] +12018 - null - [null, null, null, null, null] +12019 - null - [null, null, null, null, null] +12020 - null - [null, null, null, null, null] +12021 - null - [null, null, null, null, null] +12022 - null - [null, null, null, null, null] +12023 - null - [null, null, null, null, null] +12024 - null - [null, null, null, null, null] +12025 - null - [null, null, null, null, null] +12026 - null - [null, null, null, null, null] +12027 - null - [null, null, null, null, null] +12028 - null - [null, null, null, null, null] +12029 - null - [null, null, null, null, null] +12030 - null - [null, null, null, null, null] +12031 - null - [null, null, null, null, null] +12032 - null - [null, null, null, null, null] +12033 - null - [null, null, null, null, null] +12034 - null - [null, null, null, null, null] +12035 - null - [null, null, null, null, null] +12036 - null - [null, null, null, null, null] +12037 - null - [null, null, null, null, null] +12038 - null - [null, null, null, null, null] +12039 - null - [null, null, null, null, null] +12040 - null - [null, null, null, null, null] +12041 - A gap through the wall - [Squeeze-through, null, null, null, null] +12042 - A wall - [null, null, null, null, null] +12043 - A wall - [null, null, null, null, null] +12044 - null - [null, null, null, null, null] +12045 - Magic door - [Open, null, null, null, null] +12046 - Magic door - [Close, null, null, null, null] +12047 - Magic door - [Open, null, null, null, null] +12048 - Magic door - [Close, null, null, null, null] +12049 - null - [null, null, null, null, null] +12050 - null - [null, null, null, null, null] +12051 - null - [null, null, null, null, null] +12052 - null - [null, null, null, null, null] +12053 - null - [null, null, null, null, null] +12054 - null - [null, null, null, null, null] +12055 - null - [null, null, null, null, null] +12056 - null - [null, null, null, null, null] +12057 - null - [null, null, null, null, null] +12058 - null - [null, null, null, null, null] +12059 - null - [null, null, null, null, null] +12060 - Potion shelves - [null, null, null, null, null] +12061 - Potion shelves - [null, null, null, null, null] +12062 - Potion shelf - [null, null, null, null, null] +12063 - Potion shelf - [null, null, null, null, null] +12064 - Healing certificate - [Examine, null, null, null, null] +12065 - Certificate of healing - [null, null, null, null, null] +12066 - A fairy workbench - [null, null, null, null, null] +12067 - A fairy workbench - [null, null, null, null, null] +12068 - null - [null, null, null, null, null] +12069 - null - [null, null, null, null, null] +12070 - null - [null, null, null, null, null] +12071 - null - [null, null, null, null, null] +12072 - null - [null, null, null, null, null] +12073 - null - [null, null, null, null, null] +12074 - null - [null, null, null, null, null] +12075 - null - [null, null, null, null, null] +12076 - null - [null, null, null, null, null] +12077 - null - [null, null, null, null, null] +12078 - null - [null, null, null, null, null] +12079 - null - [null, null, null, null, null] +12080 - null - [null, null, null, null, null] +12081 - null - [null, null, null, null, null] +12082 - null - [null, null, null, null, null] +12083 - null - [null, null, null, null, null] +12084 - null - [null, null, null, null, null] +12085 - null - [null, null, null, null, null] +12086 - null - [null, null, null, null, null] +12087 - null - [null, null, null, null, null] +12088 - null - [null, null, null, null, null] +12089 - Fairy fountain - [null, null, null, null, null] +12090 - Fairy Queen - [null, null, null, null, null] +12091 - Fairy Queen throne - [null, null, null, null, null] +12092 - Godfather throne - [null, null, null, null, null] +12093 - Chicken Shrine - [null, null, null, null, null] +12094 - Fairy ring - [Use, null, null, null, null] +12095 - Fairy ring - [Use, null, null, null, null] +12096 - null - [null, null, null, null, null] +12097 - null - [null, null, null, null, null] +12098 - null - [null, null, null, null, null] +12099 - null - [null, null, null, null, null] +12100 - Furnace - [null, Smelt, null, null, null] +12101 - null - [null, null, null, null, null] +12102 - Range - [null, null, null, null, null] +12103 - Crate - [Search, null, null, null, null] +12104 - Crates - [Search, null, null, null, null] +12105 - Crate - [Search, null, null, null, null] +12106 - Table - [null, null, null, null, null] +12107 - Barrel - [null, null, null, null, null] +12108 - Table - [null, null, null, null, null] +12109 - Wall - [null, null, null, null, null] +12110 - G.A.G. banner - [null, null, null, null, null] +12111 - Dairy Cow - [Talk-to, Milk, null, Steal-cowbell, null] +12112 - Ladder - [Climb-up, null, null, null, null] +12113 - Ladder - [Climb-down, null, null, null, null] +12114 - Cow wheel - [null, null, null, null, null] +12115 - Sacks - [null, null, null, null, null] +12116 - null - [null, null, null, null, null] +12117 - null - [null, null, null, null, null] +12118 - null - [null, null, null, null, null] +12119 - null - [null, null, null, null, null] +12120 - Closed chest - [Open, null, null, null, null] +12121 - Open chest - [null, Search, Shut, null, null] +12122 - Water Trough - [null, null, null, null, null] +12123 - null - [null, null, null, null, null] +12124 - null - [null, null, null, null, null] +12125 - Gravestone - [null, null, null, null, null] +12126 - Damaged wall - [null, null, null, null, null] +12127 - Jutting wall - [Squeeze-past, null, null, null, null] +12128 - Fairy ring - [Use, null, null, null, null] +12129 - null - [null, null, null, null, null] +12130 - null - [null, null, null, null, null] +12131 - Stairs - [null, null, null, null, null] +12132 - Tomb - [null, null, null, null, null] +12133 - Juliet - [null, null, null, null, null] +12134 - Coffin - [null, null, null, null, null] +12135 - Coffin - [null, null, null, null, null] +12136 - null - [null, null, null, null, null] +12137 - null - [Study, null, null, null, null] +12138 - null - [Study, null, null, null, null] +12139 - null - [Study, null, null, null, null] +12140 - Church pew - [null, null, null, null, null] +12141 - null - [null, null, null, null, null] +12142 - null - [null, null, null, null, null] +12143 - null - [null, null, null, null, null] +12144 - Canoe Station - [Chop-down, null, null, null, null] +12145 - Canoe Station - [null, null, null, null, null] +12146 - Canoe Station - [Shape-Canoe, null, hidden, null, null] +12147 - Canoe Station - [Float Log, null, hidden, null, null] +12148 - Canoe Station - [Float Canoe, null, null, null, null] +12149 - Canoe Station - [Float Canoe, null, null, null, null] +12150 - Canoe Station - [Float Canoe, null, null, null, null] +12151 - Canoe Station - [Paddle Log, null, null, null, null] +12152 - Canoe Station - [Paddle Canoe, null, null, null, null] +12153 - Canoe Station - [Paddle Canoe, null, null, null, null] +12154 - Canoe Station - [Paddle Canoe, null, null, null, null] +12155 - Canoe Station - [Paddle Canoe, null, null, null, null] +12156 - Canoe Station - [Paddle Canoe, null, null, null, null] +12157 - Canoe Station - [Paddle Canoe, null, null, null, null] +12158 - Canoe Station - [Paddle Canoe, null, null, null, null] +12159 - A Sinking Canoe - [null, null, null, null, null] +12160 - A Sinking Canoe - [null, null, null, null, null] +12161 - A Sinking Canoe - [null, null, null, null, null] +12162 - A Sinking Canoe - [null, null, null, null, null] +12163 - Canoe station - [Chop-down, null, null, null, null] +12164 - Canoe station - [Chop-down, null, null, null, null] +12165 - Canoe station - [Chop-down, null, null, null, null] +12166 - Canoe station - [Chop-down, null, null, null, null] +12167 - null - [null, null, null, null, null] +12168 - null - [null, null, null, null, null] +12169 - null - [null, null, null, null, null] +12170 - null - [null, null, null, null, null] +12171 - null - [null, null, null, null, null] +12172 - null - [null, null, null, null, null] +12173 - null - [null, null, null, null, null] +12174 - null - [null, null, null, null, null] +12175 - null - [null, null, null, null, null] +12176 - null - [null, null, null, null, null] +12177 - null - [null, null, null, null, null] +12178 - null - [null, null, null, null, null] +12179 - null - [null, null, null, null, null] +12180 - null - [null, null, null, null, null] +12181 - null - [null, null, null, null, null] +12182 - null - [null, null, null, null, null] +12183 - null - [null, null, null, null, null] +12184 - null - [null, null, null, null, null] +12185 - null - [null, null, null, null, null] +12186 - null - [null, null, null, null, null] +12187 - null - [null, null, null, null, null] +12188 - null - [null, null, null, null, null] +12189 - null - [null, null, null, null, null] +12190 - null - [null, null, null, null, null] +12191 - null - [null, null, null, null, null] +12192 - null - [null, null, null, null, null] +12193 - null - [null, null, null, null, null] +12194 - null - [null, null, null, null, null] +12195 - null - [null, null, null, null, null] +12196 - null - [null, null, null, null, null] +12197 - null - [null, null, null, null, null] +12198 - null - [null, null, null, null, null] +12199 - null - [null, null, null, null, null] +12200 - null - [null, null, null, null, null] +12201 - Well - [null, null, null, null, null] +12202 - Mole hill - [null, null, null, null, null] +12203 - Light - [null, null, null, null, null] +12204 - null - [null, null, null, null, null] +12205 - null - [null, null, null, null, null] +12206 - null - [null, null, null, null, null] +12207 - null - [null, null, null, null, null] +12208 - null - [null, null, null, null, null] +12209 - null - [null, null, null, null, null] +12210 - null - [null, null, null, null, null] +12211 - null - [null, null, null, null, null] +12212 - null - [null, null, null, null, null] +12213 - null - [null, null, null, null, null] +12214 - null - [null, null, null, null, null] +12215 - null - [null, null, null, null, null] +12216 - null - [null, null, null, null, null] +12217 - null - [null, null, null, null, null] +12218 - null - [null, null, null, null, null] +12219 - null - [null, null, null, null, null] +12220 - null - [null, null, null, null, null] +12221 - null - [null, null, null, null, null] +12222 - null - [null, null, null, null, null] +12223 - null - [null, null, null, null, null] +12224 - null - [null, null, null, null, null] +12225 - null - [null, null, null, null, null] +12226 - null - [null, null, null, null, null] +12227 - null - [null, null, null, null, null] +12228 - null - [null, null, null, null, null] +12229 - null - [null, null, null, null, null] +12230 - Rope - [Climb, null, null, null, null] +12231 - null - [null, null, null, null, null] +12232 - null - [Study, null, null, null, null] +12233 - null - [Study, null, null, null, null] +12234 - null - [Study, null, null, null, null] +12235 - Kurask head - [null, null, null, null, null] +12236 - Mounted sea bass - [null, null, null, null, null] +12237 - Mounted swordfish - [null, null, null, null, null] +12238 - null - [null, null, null, null, null] +12239 - Vanilla plant - [Search, null, null, null, null] +12240 - Bones - [null, null, null, null, null] +12241 - Bones - [null, null, null, null, null] +12242 - Bones - [null, null, null, null, null] +12243 - Skeleton - [null, null, null, null, null] +12244 - Skeleton - [null, null, null, null, null] +12245 - Skeleton - [null, null, null, null, null] +12246 - Skeleton - [null, null, null, null, null] +12247 - Skeleton - [null, null, null, null, null] +12248 - Skeleton - [null, null, null, null, null] +12249 - null - [null, null, null, null, null] +12250 - null - [null, null, null, null, null] +12251 - null - [null, null, null, null, null] +12252 - null - [null, null, null, null, null] +12253 - Tunnel entrance - [null, null, null, null, null] +12254 - Tunnel entrance - [Climb-down, null, null, null, null] +12255 - Rope - [Climb-up, null, null, null, null] +12256 - Nest - [Search, null, null, null, null] +12257 - Dragon egg - [null, null, null, null, null] +12258 - Dragonfire - [null, null, null, null, null] +12259 - Nest - [null, null, null, null, null] +12260 - Portal - [Use, null, null, null, null] +12261 - null - [null, null, null, null, null] +12262 - Trapdoor - [Open, null, null, null, null] +12263 - Trapdoor - [Go-down, null, null, null, null] +12264 - Ladder - [Climb, null, null, null, null] +12265 - Cellar stairs - [Climb, null, null, null, null] +12266 - null - [null, null, null, null, null] +12267 - Trapdoor - [Open, null, null, null, null] +12268 - Open trapdoor - [Go-down, Close, null, null, null] +12269 - Stove - [null, null, null, null, null] +12270 - null - [null, null, null, null, null] +12271 - null - [null, null, null, null, null] +12272 - null - [null, null, null, null, null] +12273 - null - [null, null, null, null, null] +12274 - null - [null, null, null, null, null] +12275 - null - [null, null, null, null, null] +12276 - null - [null, null, null, null, null] +12277 - null - [null, null, null, null, null] +12278 - null - [null, null, null, null, null] +12279 - Sink - [null, null, null, null, null] +12280 - Large Table - [null, null, null, null, null] +12281 - Small Table - [null, null, null, null, null] +12282 - Bookcase - [null, null, null, null, null] +12283 - null - [null, null, null, null, null] +12284 - null - [null, null, null, null, null] +12285 - null - [null, null, null, null, null] +12286 - null - [null, null, null, null, null] +12287 - null - [null, null, null, null, null] +12288 - null - [null, null, null, null, null] +12289 - null - [null, null, null, null, null] +12290 - null - [null, null, null, null, null] +12291 - null - [null, null, null, null, null] +12292 - null - [null, null, null, null, null] +12293 - Grandfather clock - [null, null, null, null, null] +12294 - null - [null, null, null, null, null] +12295 - null - [null, null, null, null, null] +12296 - null - [null, null, null, null, null] +12297 - null - [null, null, null, null, null] +12298 - null - [null, null, null, null, null] +12299 - null - [null, null, null, null, null] +12300 - null - [null, null, null, null, null] +12301 - Candles - [null, null, null, null, null] +12302 - Candles - [null, null, null, null, null] +12303 - null - [null, null, null, null, null] +12304 - null - [null, null, null, null, null] +12305 - null - [null, null, null, null, null] +12306 - null - [null, null, null, null, null] +12307 - null - [null, null, null, null, null] +12308 - null - [null, null, null, null, null] +12309 - Chest - [Bank, Buy-food, Buy-items, null, null] +12310 - Chair - [null, null, null, null, null] +12311 - Chair - [null, null, null, null, null] +12312 - Chair - [null, null, null, null, null] +12313 - Chair - [null, null, null, null, null] +12314 - Banquet table - [null, null, null, null, null] +12315 - Banquet table - [null, null, null, null, null] +12316 - Banquet table - [null, null, null, null, null] +12317 - Banquet table - [null, null, null, null, null] +12318 - Chair - [null, null, null, null, null] +12319 - Chair - [null, null, null, null, null] +12320 - Pirate Pete - [null, null, null, null, null] +12321 - Dwarf - [null, null, null, null, null] +12322 - General Wartface - [null, null, null, null, null] +12323 - General Bentnoze - [null, null, null, null, null] +12324 - Lumbridge Guide - [null, null, null, null, null] +12325 - Evil Dave - [null, null, null, null, null] +12326 - Sir Amik Varze - [null, null, null, null, null] +12327 - Awowogei - [null, null, null, null, null] +12328 - Skrach Uglogwee - [null, null, null, null, null] +12329 - null - [null, null, null, null, null] +12330 - Dwarf - [Inspect, null, null, null, null] +12331 - null - [null, null, null, null, null] +12332 - General Bentnoze - [Inspect, null, null, null, null] +12333 - null - [null, null, null, null, null] +12334 - General Wartface - [Inspect, null, null, null, null] +12335 - null - [null, null, null, null, null] +12336 - null - [null, null, null, null, null] +12337 - Pirate Pete - [Inspect, null, null, null, null] +12338 - null - [null, null, null, null, null] +12339 - Lumbridge Guide - [Inspect, null, null, null, null] +12340 - null - [null, null, null, null, null] +12341 - Evil Dave - [Inspect, null, null, null, null] +12342 - null - [null, null, null, null, null] +12343 - Skrach Uglogwee - [Inspect, null, null, null, null] +12344 - null - [null, null, null, null, null] +12345 - Sir Amik Varze - [Inspect, null, null, null, null] +12346 - null - [null, null, null, null, null] +12347 - Awowogei - [Inspect, null, null, null, null] +12348 - Door - [Open, null, null, null, null] +12349 - Large door - [Open, null, null, null, null] +12350 - Large door - [Open, null, null, null, null] +12351 - Barrier - [Pass-through, null, null, null, null] +12352 - Barrier - [Pass-through, null, null, null, null] +12353 - Barrier - [Pass-through, null, null, null, null] +12354 - null - [null, null, null, null, null] +12355 - Portal - [Use, null, null, null, null] +12356 - Portal - [Use, null, null, null, null] +12357 - null - [null, null, null, null, null] +12358 - null - [null, null, null, null, null] +12359 - null - [null, null, null, null, null] +12360 - null - [null, null, null, null, null] +12361 - null - [null, null, null, null, null] +12362 - null - [null, null, null, null, null] +12363 - null - [null, null, null, null, null] +12364 - null - [null, null, null, null, null] +12365 - null - [null, null, null, null, null] +12366 - null - [null, null, null, null, null] +12367 - null - [null, null, null, null, null] +12368 - null - [null, null, null, null, null] +12369 - null - [null, null, null, null, null] +12370 - null - [null, null, null, null, null] +12371 - null - [null, null, null, null, null] +12372 - null - [null, null, null, null, null] +12373 - null - [null, null, null, null, null] +12374 - null - [null, null, null, null, null] +12375 - null - [null, null, null, null, null] +12376 - null - [null, null, null, null, null] +12377 - null - [null, null, null, null, null] +12378 - null - [null, null, null, null, null] +12379 - null - [null, null, null, null, null] +12380 - null - [null, null, null, null, null] +12381 - null - [null, null, null, null, null] +12382 - null - [null, null, null, null, null] +12383 - null - [null, null, null, null, null] +12384 - null - [null, null, null, null, null] +12385 - null - [null, null, null, null, null] +12386 - Table - [null, null, null, null, null] +12387 - Table - [null, null, null, null, null] +12388 - Table - [null, null, null, null, null] +12389 - Ladder - [Climb-Down, null, null, null, null] +12390 - Ladder - [Climb-up, null, null, null, null] +12391 - Ladder - [Climb-up, null, null, null, null] +12392 - Sacks - [null, null, null, null, null] +12393 - Sacks - [null, null, null, null, null] +12394 - Sack Pile - [null, null, null, null, null] +12395 - Sack Pile - [null, null, null, null, null] +12396 - Sack - [null, null, null, null, null] +12397 - null - [null, null, null, null, null] +12398 - null - [null, null, null, null, null] +12399 - Sack - [null, null, null, null, null] +12400 - Cauldron - [null, null, null, null, null] +12401 - Cauldron - [null, null, null, null, null] +12402 - Explosion - [null, null, null, null, null] +12403 - Shelves - [null, null, null, null, null] +12404 - Shelves - [null, null, null, null, null] +12405 - Cupboard - [null, null, null, null, null] +12406 - Cupboard - [null, null, null, null, null] +12407 - Stool - [null, null, null, null, null] +12408 - Stool - [null, null, null, null, null] +12409 - Stool - [null, null, null, null, null] +12410 - Saucepan - [null, null, null, null, null] +12411 - Saucepan - [null, null, null, null, null] +12412 - Rolling pin - [null, null, null, null, null] +12413 - Rolling pin - [null, null, null, null, null] +12414 - Spork - [null, null, null, null, null] +12415 - Spork - [null, null, null, null, null] +12416 - null - [null, null, null, null, null] +12417 - null - [null, null, null, null, null] +12418 - null - [null, null, null, null, null] +12419 - null - [null, null, null, null, null] +12420 - null - [null, null, null, null, null] +12421 - null - [null, null, null, null, null] +12422 - null - [null, null, null, null, null] +12423 - null - [null, null, null, null, null] +12424 - null - [null, null, null, null, null] +12425 - null - [null, null, null, null, null] +12426 - null - [null, null, null, null, null] +12427 - null - [null, null, null, null, null] +12428 - null - [null, null, null, null, null] +12429 - null - [null, null, null, null, null] +12430 - null - [null, null, null, null, null] +12431 - null - [null, null, null, null, null] +12432 - null - [null, null, null, null, null] +12433 - null - [null, null, null, null, null] +12434 - Barrel - [null, null, null, null, null] +12435 - Barrel - [null, null, null, null, null] +12436 - null - [null, null, null, null, null] +12437 - null - [null, null, null, null, null] +12438 - null - [null, null, null, null, null] +12439 - null - [null, null, null, null, null] +12440 - Stool - [null, null, null, null, null] +12441 - null - [null, null, null, null, null] +12442 - Crate - [null, null, null, null, null] +12443 - Crate - [null, null, null, null, null] +12444 - Door - [Open, null, null, null, null] +12445 - Door - [Close, null, null, null, null] +12446 - Large door - [Open, null, null, null, null] +12447 - Large door - [Close, null, null, null, null] +12448 - Large door - [Open, null, null, null, null] +12449 - Large door - [Close, null, null, null, null] +12450 - Table - [null, null, null, null, null] +12451 - Chest - [Open, null, null, null, null] +12452 - Chest - [Close, Search, null, null, null] +12453 - Skulls - [null, null, null, null, null] +12454 - null - [null, null, null, null, null] +12455 - null - [null, null, null, null, null] +12456 - null - [null, null, null, null, null] +12457 - null - [null, null, null, null, null] +12458 - null - [null, null, null, null, null] +12459 - null - [null, null, null, null, null] +12460 - Underwater Cavern Entrance - [Enter, null, null, null, null] +12461 - Underwater Cavern Entrance - [Enter, null, null, null, null] +12462 - Underwater Cavern Entrance - [Exit, null, null, null, null] +12463 - Underwater Cavern Entrance - [Exit, null, null, null, null] +12464 - null - [null, null, null, null, null] +12465 - null - [null, null, null, null, null] +12466 - null - [null, null, null, null, null] +12467 - Pen Door - [Open, null, null, null, null] +12468 - Pen Door - [Open, null, null, null, null] +12469 - null - [null, null, null, null, null] +12470 - null - [null, null, null, null, null] +12471 - null - [null, null, null, null, null] +12472 - null - [null, null, null, null, null] +12473 - null - [null, null, null, null, null] +12474 - Anchor - [null, null, null, null, null] +12475 - Anchor - [Climb, null, null, null, null] +12476 - Anchor - [null, null, null, null, null] +12477 - Kelp - [null, null, null, null, null] +12478 - Kelp - [Pick, null, null, null, null] +12479 - Coral Reef - [null, null, null, null, null] +12480 - Coral - [null, null, null, null, null] +12481 - Coral - [null, null, null, null, null] +12482 - Coral - [null, null, null, null, null] +12483 - Coral - [null, null, null, null, null] +12484 - Coral - [null, null, null, null, null] +12485 - Coral - [null, null, null, null, null] +12486 - Coral - [null, null, null, null, null] +12487 - Coral - [null, null, null, null, null] +12488 - Coral - [null, null, null, null, null] +12489 - Coral - [null, null, null, null, null] +12490 - Coral - [null, null, null, null, null] +12491 - Coral - [null, null, null, null, null] +12492 - Coral - [null, null, null, null, null] +12493 - Coral - [null, null, null, null, null] +12494 - Coral - [null, null, null, null, null] +12495 - Coral - [null, null, null, null, null] +12496 - Coral - [null, null, null, null, null] +12497 - Coral - [null, null, null, null, null] +12498 - Coral - [null, null, null, null, null] +12499 - Coral Reef - [null, null, null, null, null] +12500 - Coral - [null, null, null, null, null] +12501 - Coral - [null, null, null, null, null] +12502 - Coral - [null, null, null, null, null] +12503 - Coral - [null, null, null, null, null] +12504 - Coral - [null, null, null, null, null] +12505 - Coral - [null, null, null, null, null] +12506 - Coral - [null, null, null, null, null] +12507 - Coral - [null, null, null, null, null] +12508 - Coral - [null, null, null, null, null] +12509 - Coral Reef - [null, null, null, null, null] +12510 - Coral - [null, null, null, null, null] +12511 - Coral - [null, null, null, null, null] +12512 - Coral - [null, null, null, null, null] +12513 - Coral - [null, null, null, null, null] +12514 - Coral - [null, null, null, null, null] +12515 - Coral - [null, null, null, null, null] +12516 - Coral - [null, null, null, null, null] +12517 - Coral - [null, null, null, null, null] +12518 - Coral - [null, null, null, null, null] +12519 - Coral - [null, null, null, null, null] +12520 - Coral Reef - [null, null, null, null, null] +12521 - Coral - [null, null, null, null, null] +12522 - Coral - [null, null, null, null, null] +12523 - Coral - [null, null, null, null, null] +12524 - Coral - [null, null, null, null, null] +12525 - Coral - [null, null, null, null, null] +12526 - Coral - [null, null, null, null, null] +12527 - Coral - [null, null, null, null, null] +12528 - Coral - [null, null, null, null, null] +12529 - Coral - [null, null, null, null, null] +12530 - Anchor - [null, null, null, null, null] +12531 - Bubbles - [null, null, null, null, null] +12532 - null - [null, null, null, null, null] +12533 - null - [null, null, null, null, null] +12534 - null - [null, null, null, null, null] +12535 - null - [null, null, null, null, null] +12536 - Staircase - [Climb-up, null, null, null, null] +12537 - Staircase - [Climb, Climb-up, Climb-down, null, null] +12538 - Staircase - [Climb-down, null, null, null, null] +12539 - Bookcase - [Search, null, null, null, null] +12540 - Bookcase - [Search, null, null, null, null] +12541 - Table - [null, null, null, null, null] +12542 - null - [null, null, null, null, null] +12543 - Large table - [null, null, null, null, null] +12544 - Table - [null, null, null, null, null] +12545 - Boxes - [Search, null, null, null, null] +12546 - Crate - [Search, null, null, null, null] +12547 - Crate - [Search, null, null, null, null] +12548 - Crates - [Search, null, null, null, null] +12549 - null - [null, null, null, null, null] +12550 - Old tree - [null, null, null, null, null] +12551 - Old tree - [null, null, null, null, null] +12552 - Old tree - [null, null, null, null, null] +12553 - Old tree - [null, null, null, null, null] +12554 - Crude boat - [null, null, null, null, null] +12555 - Roots - [null, null, null, null, null] +12556 - Rock and string - [null, null, null, null, null] +12557 - Rock and string - [null, null, null, null, null] +12558 - null - [null, null, null, null, null] +12559 - Tree - [null, null, null, null, null] +12560 - Tree - [null, null, null, null, null] +12561 - Ogre spit-roast - [null, null, null, null, null] +12562 - Ogre spit-roast - [null, null, null, null, null] +12563 - Ogre spit-roast - [null, null, null, null, null] +12564 - Pile of Rock - [Mine, Prospect, hidden, null, null] +12565 - Pile of Rock - [Mine, Prospect, hidden, null, null] +12566 - Pile of Rock - [Mine, Prospect, hidden, null, null] +12567 - Pile of Rock - [Mine, Prospect, null, null, null] +12568 - Stepping stone - [Jump-to, null, null, null, null] +12569 - Temp Stone 4 Zip - [Climb-down, null, null, null, null] +12570 - Tropical tree - [Climb, null, null, null, null] +12571 - Tropical tree - [null, null, null, null, null] +12572 - Tropical tree - [null, null, null, null, null] +12573 - Monkeybars - [Swing Across, null, null, null, null] +12574 - null - [null, null, null, null, null] +12575 - Monkeybars - [Swing Across, null, null, null, null] +12576 - Skull slope - [Climb-up, null, null, null, null] +12577 - null - [null, null, null, null, null] +12578 - Rope - [Swing, null, null, null, null] +12579 - Tropical tree - [null, null, null, null, null] +12580 - Tropical tree - [null, null, null, null, null] +12581 - Hole - [Enter, null, null, null, null] +12582 - null - [null, null, null, null, null] +12583 - null - [null, null, null, null, null] +12584 - null - [null, null, null, null, null] +12585 - null - [null, null, null, null, null] +12586 - null - [null, null, null, null, null] +12587 - null - [null, null, null, null, null] +12588 - null - [null, null, null, null, null] +12589 - Rock - [null, null, null, null, null] +12590 - Rock - [null, null, null, null, null] +12591 - null - [null, null, null, null, null] +12592 - null - [null, null, null, null, null] +12593 - null - [null, null, null, null, null] +12594 - Snake - [null, null, null, null, null] +12595 - Snake - [null, null, null, null, null] +12596 - Snake - [null, null, null, null, null] +12597 - Hole - [null, null, null, null, null] +12598 - Snake - [null, null, null, null, null] +12599 - Snake - [null, null, null, null, null] +12600 - Snake - [null, null, null, null, null] +12601 - Rope - [Climb, null, null, null, null] +12602 - Pit - [Enter, null, null, null, null] +12603 - Tchiki Monkey Nut Bush - [Pick Nuts, null, null, null, null] +12604 - Strange Banana Tree - [Pick Banana, null, null, null, null] +12605 - Light - [Climb, null, null, null, null] +12606 - Banana tree - [Pick, null, null, null, null] +12607 - Banana tree - [Pick, null, null, null, null] +12608 - Red Banana Tree - [null, null, null, null, null] +12609 - Red Banana Tree - [Pick, null, null, null, null] +12610 - null - [null, null, null, null, null] +12611 - null - [null, null, null, null, null] +12612 - null - [null, null, null, null, null] +12613 - null - [null, null, null, null, null] +12614 - null - [null, null, null, null, null] +12615 - Bush - [Pick, null, null, null, null] +12616 - Exit - [Climb-up, null, null, null, null] +12617 - Exit - [Enter, null, null, null, null] +12618 - Tropical tree - [Climb-down, null, null, null, null] +12619 - null - [null, null, null, null, null] +12620 - null - [null, null, null, null, null] +12621 - null - [null, null, null, null, null] +12622 - Vine - [Climb-down, null, null, null, null] +12623 - null - [null, null, null, null, null] +12624 - null - [null, null, null, null, null] +12625 - null - [null, null, null, null, null] +12626 - null - [null, null, null, null, null] +12627 - Tropical tree - [null, null, null, null, null] +12628 - null - [null, null, null, null, null] +12629 - null - [null, null, null, null, null] +12630 - null - [null, null, null, null, null] +12631 - null - [null, null, null, null, null] +12632 - null - [null, null, null, null, null] +12633 - null - [null, null, null, null, null] +12634 - Rock - [null, null, null, null, null] +12635 - Rock - [null, null, null, null, null] +12636 - Rock - [null, null, null, null, null] +12637 - Rock - [null, null, null, null, null] +12638 - null - [null, null, null, null, null] +12639 - null - [null, null, null, null, null] +12640 - null - [null, null, null, null, null] +12641 - null - [null, null, null, null, null] +12642 - null - [null, null, null, null, null] +12643 - null - [null, null, null, null, null] +12644 - null - [null, null, null, null, null] +12645 - null - [null, null, null, null, null] +12646 - null - [null, null, null, null, null] +12647 - null - [null, null, null, null, null] +12648 - null - [null, null, null, null, null] +12649 - null - [null, null, null, null, null] +12650 - null - [null, null, null, null, null] +12651 - null - [null, null, null, null, null] +12652 - null - [null, null, null, null, null] +12653 - null - [null, null, null, null, null] +12654 - null - [null, null, null, null, null] +12655 - null - [null, null, null, null, null] +12656 - null - [null, null, null, null, null] +12657 - Exit - [Enter, null, null, null, null] +12658 - null - [null, null, null, null, null] +12659 - null - [null, null, null, null, null] +12660 - null - [null, null, null, null, null] +12661 - Signpost - [null, null, null, null, null] +12662 - null - [null, null, null, null, null] +12663 - null - [null, null, null, null, null] +12664 - null - [null, null, null, null, null] +12665 - null - [null, null, null, null, null] +12666 - null - [null, null, null, null, null] +12667 - null - [null, null, null, null, null] +12668 - null - [null, null, null, null, null] +12669 - null - [null, null, null, null, null] +12670 - null - [null, null, null, null, null] +12671 - null - [null, null, null, null, null] +12672 - null - [null, null, null, null, null] +12673 - null - [null, null, null, null, null] +12674 - null - [null, null, null, null, null] +12675 - null - [null, null, null, null, null] +12676 - null - [null, null, null, null, null] +12677 - null - [null, null, null, null, null] +12678 - null - [null, null, null, null, null] +12679 - null - [null, null, null, null, null] +12680 - null - [null, null, null, null, null] +12681 - null - [null, null, null, null, null] +12682 - null - [null, null, null, null, null] +12683 - Bridge - [null, null, null, null, null] +12684 - Bridge - [null, null, null, null, null] +12685 - null - [null, null, null, null, null] +12686 - null - [null, null, null, null, null] +12687 - null - [null, null, null, null, null] +12688 - null - [null, null, null, null, null] +12689 - null - [null, null, null, null, null] +12690 - null - [null, null, null, null, null] +12691 - null - [null, null, null, null, null] +12692 - null - [null, null, null, null, null] +12693 - null - [null, null, null, null, null] +12694 - null - [null, null, null, null, null] +12695 - null - [null, null, null, null, null] +12696 - null - [null, null, null, null, null] +12697 - null - [null, null, null, null, null] +12698 - null - [null, null, null, null, null] +12699 - null - [null, null, null, null, null] +12700 - null - [null, null, null, null, null] +12701 - null - [null, null, null, null, null] +12702 - null - [null, null, null, null, null] +12703 - null - [null, null, null, null, null] +12704 - null - [null, null, null, null, null] +12705 - null - [null, null, null, null, null] +12706 - null - [null, null, null, null, null] +12707 - null - [null, null, null, null, null] +12708 - null - [null, null, null, null, null] +12709 - null - [null, null, null, null, null] +12710 - null - [null, null, null, null, null] +12711 - Grave - [Dig, null, null, null, null] +12712 - Grave - [Dig, null, null, null, null] +12713 - Grave - [Dig, null, null, null, null] +12714 - Grave - [Dig, null, null, null, null] +12715 - Grave - [Dig, null, null, null, null] +12716 - Gravestone - [Read, null, null, null, null] +12717 - Gravestone - [Read, null, null, null, null] +12718 - Gravestone - [Read, null, null, null, null] +12719 - Gravestone - [Read, null, null, null, null] +12720 - Gravestone - [Read, null, null, null, null] +12721 - Grave - [Take-Coffin, null, null, null, null] +12722 - Grave - [Take-Coffin, null, null, null, null] +12723 - Grave - [Take-Coffin, null, null, null, null] +12724 - Grave - [Take-Coffin, null, null, null, null] +12725 - Grave - [Take-Coffin, null, null, null, null] +12726 - Grave - [null, null, null, null, null] +12727 - Grave - [null, null, null, null, null] +12728 - Grave - [null, null, null, null, null] +12729 - Grave - [hidden, null, null, null, null] +12730 - Grave - [hidden, null, null, null, null] +12731 - Mausoleum - [Deposit, null, null, null, null] +12732 - Dead tree - [null, null, null, null, null] +12733 - Tree stump - [null, null, null, null, null] +12734 - Table - [Search, null, null, null, null] +12735 - Closed chest - [Open, null, null, null, null] +12736 - Open chest - [null, Search, null, null, null] +12737 - Broken down wall - [Climb-over, null, null, null, null] +12738 - null - [null, null, null, null, null] +12739 - Rubble - [null, null, null, null, null] +12740 - Rubble - [null, null, null, null, null] +12741 - Fallen Wall - [Search, null, null, null, null] +12742 - Rubble - [null, null, null, null, null] +12743 - null - [null, null, null, null, null] +12744 - Trapdoor - [Open, null, null, null, null] +12745 - Trapdoor - [Climb-down, Close, null, null, null] +12746 - Rubble - [Mine, Prospect, hidden, null, null] +12747 - Pile of rubble. - [null, null, null, null, null] +12748 - Ladder - [Climb-up, null, null, null, null] +12749 - Rubble Pile - [null, Search, null, null, null] +12750 - Plaque - [Search, null, null, null, null] +12751 - null - [null, null, null, null, null] +12752 - null - [null, null, null, null, null] +12753 - null - [null, null, null, null, null] +12754 - null - [null, null, null, null, null] +12755 - null - [null, null, null, null, null] +12756 - null - [null, null, null, null, null] +12757 - null - [null, null, null, null, null] +12758 - null - [null, null, null, null, null] +12759 - null - [null, null, null, null, null] +12760 - null - [null, null, null, null, null] +12761 - Door - [Open, null, null, null, null] +12762 - null - [null, null, null, null, null] +12763 - Trapdoor - [Climb-down, null, null, null, null] +12764 - Ladder - [Climb-up, null, null, null, null] +12765 - Keyhole - [Search, null, null, null, null] +12766 - Bookcase - [Search, null, null, null, null] +12767 - Bookcase - [Search, null, null, null, null] +12768 - Closed chest - [Open, null, null, null, null] +12769 - Open chest - [Search, Close, null, null, null] +12770 - Cave entrance - [Enter, null, null, null, null] +12771 - Cave entrance - [Enter, null, null, null, null] +12772 - null - [null, null, null, null, null] +12773 - Wooden boards - [null, null, null, null, null] +12774 - Rock - [null, null, null, null, null] +12775 - Marius - [Talk-to, null, null, null, null] +12776 - Low fence - [Jump-over, null, null, null, null] +12777 - Trapdoor - [null, null, null, null, null] +12778 - Trapdoor - [null, null, null, null, null] +12779 - Ladder - [Climb-up, null, null, null, null] +12780 - Ladder - [Climb-up, null, null, null, null] +12781 - Ladder - [Climb-down, null, null, null, null] +12782 - Broken Roof - [Search, null, null, null, null] +12783 - Repaired roof - [Search, null, null, null, null] +12784 - Bucket - [null, null, null, null, null] +12785 - Bucket - [null, null, null, null, null] +12786 - Repaired wall - [null, null, null, null, null] +12787 - Damaged wall - [Search, null, null, null, null] +12788 - null - [null, null, null, null, null] +12789 - null - [null, null, null, null, null] +12790 - null - [null, null, null, null, null] +12791 - null - [null, null, null, null, null] +12792 - null - [null, null, null, null, null] +12793 - null - [null, null, null, null, null] +12794 - null - [null, null, null, null, null] +12795 - null - [null, null, null, null, null] +12796 - Fire - [null, null, null, null, null] +12797 - null - [null, null, null, null, null] +12798 - Bank Booth - [Use, Use-quickly, Collect, null, null] +12799 - Bank Booth - [Search, null, null, null, null] +12800 - Bank Booth - [null, null, null, null, null] +12801 - Bank Booth - [null, null, null, null, null] +12802 - Tomb - [Search, null, null, null, null] +12803 - null - [null, null, null, null, null] +12804 - Barrel - [null, null, null, null, null] +12805 - null - [null, null, null, null, null] +12806 - Broken furnace - [Search, null, null, null, null] +12807 - Repaired furnace - [Search, null, null, null, null] +12808 - Repaired furnace - [Search, null, null, null, null] +12809 - Furnace - [null, Smelt, null, null, null] +12810 - null - [null, null, null, null, null] +12811 - null - [null, null, null, null, null] +12812 - Rubble - [Mine, Prospect, hidden, null, null] +12813 - Rubble - [Mine, Prospect, hidden, null, null] +12814 - Rubble - [Mine, Prospect, hidden, null, null] +12815 - Rubble - [null, null, null, null, null] +12816 - Gate - [Open, null, null, null, null] +12817 - Gate - [Open, null, null, null, null] +12818 - Gate - [null, null, null, null, null] +12819 - null - [null, null, null, null, null] +12820 - Exit path - [Search, Escape, null, null, null] +12821 - null - [null, null, null, null, null] +12822 - null - [null, null, null, null, null] +12823 - null - [null, null, null, null, null] +12824 - null - [null, null, null, null, null] +12825 - null - [null, null, null, null, null] +12826 - null - [null, null, null, null, null] +12827 - null - [null, null, null, null, null] +12828 - null - [null, null, null, null, null] +12829 - null - [null, null, null, null, null] +12830 - null - [null, null, null, null, null] +12831 - null - [null, null, null, null, null] +12832 - null - [null, null, null, null, null] +12833 - null - [null, null, null, null, null] +12834 - null - [null, null, null, null, null] +12835 - null - [null, null, null, null, null] +12836 - null - [null, null, null, null, null] +12837 - null - [null, null, null, null, null] +12838 - null - [null, null, null, null, null] +12839 - null - [null, null, null, null, null] +12840 - null - [null, null, null, null, null] +12841 - null - [null, null, null, null, null] +12842 - null - [null, null, null, null, null] +12843 - null - [null, null, null, null, null] +12844 - Pile of bricks - [null, null, null, null, null] +12845 - null - [null, null, null, null, null] +12846 - null - [null, null, null, null, null] +12847 - null - [null, null, null, null, null] +12848 - null - [null, null, null, null, null] +12849 - null - [null, null, null, null, null] +12850 - null - [null, null, null, null, null] +12851 - null - [null, null, null, null, null] +12852 - null - [null, null, null, null, null] +12853 - null - [null, null, null, null, null] +12854 - null - [null, null, null, null, null] +12855 - Table - [null, null, null, null, null] +12856 - Store door - [null, null, null, null, null] +12857 - Bar pumps - [null, null, null, null, null] +12858 - null - [null, null, null, null, null] +12859 - null - [null, null, null, null, null] +12860 - null - [null, null, null, null, null] +12861 - null - [null, null, null, null, null] +12862 - null - [null, null, null, null, null] +12863 - null - [null, null, null, null, null] +12864 - null - [null, null, null, null, null] +12865 - null - [null, null, null, null, null] +12866 - null - [null, null, null, null, null] +12867 - null - [null, null, null, null, null] +12868 - null - [null, null, null, null, null] +12869 - null - [null, null, null, null, null] +12870 - null - [null, null, null, null, null] +12871 - null - [null, null, null, null, null] +12872 - Trapdoor - [null, null, null, null, null] +12873 - Bookcase - [null, null, null, null, null] +12874 - Crate - [null, null, null, null, null] +12875 - Wheelbarrow - [null, null, null, null, null] +12876 - Crate - [null, null, null, null, null] +12877 - Crates - [null, null, null, null, null] +12878 - Boxes - [null, null, null, null, null] +12879 - Crate - [null, null, null, null, null] +12880 - Bed - [null, null, null, null, null] +12881 - Bookcase - [null, null, null, null, null] +12882 - Bookcase - [null, null, null, null, null] +12883 - Bookcase - [null, null, null, null, null] +12884 - Table - [null, null, null, null, null] +12885 - Chair - [null, null, null, null, null] +12886 - Chair - [null, null, null, null, null] +12887 - Chair - [null, null, null, null, null] +12888 - Chair - [null, null, null, null, null] +12889 - Smashed chair - [null, null, null, null, null] +12890 - Barrel - [null, null, null, null, null] +12891 - Barrel - [null, null, null, null, null] +12892 - Small Table - [null, null, null, null, null] +12893 - null - [null, null, null, null, null] +12894 - Tree Stump - [null, null, null, null, null] +12895 - Tree - [null, null, null, null, null] +12896 - Tree - [null, null, null, null, null] +12897 - Well - [null, null, null, null, null] +12898 - null - [null, null, null, null, null] +12899 - null - [null, null, null, null, null] +12900 - null - [null, null, null, null, null] +12901 - null - [null, null, null, null, null] +12902 - null - [null, null, null, null, null] +12903 - null - [null, null, null, null, null] +12904 - null - [null, null, null, null, null] +12905 - null - [null, null, null, null, null] +12906 - Ladder - [Climb-down, null, null, null, null] +12907 - Ladder - [Climb-up, null, null, null, null] +12908 - null - [null, null, null, null, null] +12909 - null - [null, null, null, null, null] +12910 - null - [null, null, null, null, null] +12911 - null - [null, null, null, null, null] +12912 - null - [null, null, null, null, null] +12913 - null - [null, null, null, null, null] +12914 - null - [null, null, null, null, null] +12915 - null - [null, null, null, null, null] +12916 - null - [null, null, null, null, null] +12917 - null - [null, null, null, null, null] +12918 - null - [null, null, null, null, null] +12919 - null - [null, null, null, null, null] +12920 - null - [null, null, null, null, null] +12921 - null - [null, null, null, null, null] +12922 - null - [null, null, null, null, null] +12923 - null - [null, null, null, null, null] +12924 - null - [null, null, null, null, null] +12925 - null - [null, null, null, null, null] +12926 - null - [null, null, null, null, null] +12927 - null - [null, null, null, null, null] +12928 - null - [null, null, null, null, null] +12929 - null - [null, null, null, null, null] +12930 - null - [null, null, null, null, null] +12931 - null - [null, null, null, null, null] +12932 - null - [null, null, null, null, null] +12933 - Counter - [null, null, null, null, null] +12934 - null - [null, null, null, null, null] +12935 - null - [null, null, null, null, null] +12936 - null - [null, null, null, null, null] +12937 - null - [null, null, null, null, null] +12938 - null - [null, null, null, null, null] +12939 - null - [null, null, null, null, null] +12940 - null - [null, null, null, null, null] +12941 - Mineral vein - [Mine, Prospect, null, null, null] +12942 - Mineral vein - [Mine, Prospect, null, null, null] +12943 - Mineral vein - [Mine, Prospect, null, null, null] +12944 - null - [null, null, null, null, null] +12945 - null - [null, null, null, null, null] +12946 - null - [null, null, null, null, null] +12947 - null - [null, null, null, null, null] +12948 - null - [null, null, null, null, null] +12949 - null - [null, null, null, null, null] +12950 - null - [null, null, null, null, null] +12951 - null - [null, null, null, null, null] +12952 - null - [null, null, null, null, null] +12953 - null - [null, null, null, null, null] +12954 - null - [null, null, null, null, null] +12955 - null - [null, null, null, null, null] +12956 - null - [null, null, null, null, null] +12957 - null - [null, null, null, null, null] +12958 - null - [null, null, null, null, null] +12959 - null - [null, null, null, null, null] +12960 - null - [null, null, null, null, null] +12961 - Crate - [null, null, null, null, null] +12962 - Table - [null, null, null, null, null] +12963 - Crate - [Search, null, null, null, null] +12964 - Ladder - [Climb-up, null, null, null, null] +12965 - Ladder - [Climb, Climb-up, Climb-down, null, null] +12966 - Ladder - [Climb-down, null, null, null, null] +12967 - Barrel - [null, null, null, null, null] +12968 - Barrel - [null, null, null, null, null] +12969 - Cooking pot - [null, null, null, null, null] +12970 - Bed - [null, null, null, null, null] +12971 - Table - [null, null, null, null, null] +12972 - Table - [null, null, null, null, null] +12973 - Chair - [null, null, null, null, null] +12974 - Sink - [null, null, null, null, null] +12975 - null - [null, null, null, null, null] +12976 - null - [null, null, null, null, null] +12977 - Crate - [null, null, null, null, null] +12978 - Crate - [null, null, null, null, null] +12979 - Rocking chair - [null, null, null, null, null] +12980 - Shelves - [null, null, null, null, null] +12981 - Hat stand - [null, null, null, null, null] +12982 - Stile - [Climb-over, null, null, null, null] +12983 - null - [null, null, null, null, null] +12984 - null - [null, null, null, null, null] +12985 - null - [null, null, null, null, null] +12986 - Gate - [Open, null, null, null, null] +12987 - Gate - [Open, null, null, null, null] +12988 - Gate - [Close, null, null, null, null] +12989 - Gate - [Close, null, null, null, null] +12990 - null - [null, null, null, null, null] +12991 - null - [null, null, null, null, null] +12992 - null - [null, null, null, null, null] +12993 - null - [null, null, null, null, null] +12994 - null - [null, null, null, null, null] +12995 - null - [null, null, null, null, null] +12996 - null - [null, null, null, null, null] +12997 - null - [null, null, null, null, null] +12998 - null - [null, null, null, null, null] +12999 - null - [null, null, null, null, null] +13000 - null - [null, null, null, null, null] +13001 - Door - [Open, null, null, null, null] +13002 - Door - [Close, null, null, null, null] +13003 - Closed chest - [null, null, null, null, null] +13004 - Open chest - [null, null, null, null, null] +13005 - null - [null, null, null, null, null] +13006 - Door - [Open, null, null, null, null] +13007 - Door - [Open, null, null, null, null] +13008 - Door - [Close, null, null, null, null] +13009 - Door - [Close, null, null, null, null] +13010 - null - [null, null, null, null, null] +13011 - null - [null, null, null, null, null] +13012 - null - [null, null, null, null, null] +13013 - null - [null, null, null, null, null] +13014 - null - [null, null, null, null, null] +13015 - Door - [Open, null, null, null, null] +13016 - Door - [Open, null, null, null, null] +13017 - Door - [Close, null, null, null, null] +13018 - Door - [Close, null, null, null, null] +13019 - null - [null, null, null, null, null] +13020 - null - [null, null, null, null, null] +13021 - null - [null, null, null, null, null] +13022 - null - [null, null, null, null, null] +13023 - null - [null, null, null, null, null] +13024 - null - [null, null, null, null, null] +13025 - null - [null, null, null, null, null] +13026 - null - [null, null, null, null, null] +13027 - null - [null, null, null, null, null] +13028 - null - [null, null, null, null, null] +13029 - null - [null, null, null, null, null] +13030 - null - [null, null, null, null, null] +13031 - null - [null, null, null, null, null] +13032 - null - [null, null, null, null, null] +13033 - null - [null, null, null, null, null] +13034 - null - [null, null, null, null, null] +13035 - null - [null, null, null, null, null] +13036 - null - [null, null, null, null, null] +13037 - null - [null, null, null, null, null] +13038 - null - [null, null, null, null, null] +13039 - null - [null, null, null, null, null] +13040 - null - [null, null, null, null, null] +13041 - null - [null, null, null, null, null] +13042 - null - [null, null, null, null, null] +13043 - null - [null, null, null, null, null] +13044 - null - [null, null, null, null, null] +13045 - null - [null, null, null, null, null] +13046 - null - [null, null, null, null, null] +13047 - null - [null, null, null, null, null] +13048 - null - [null, null, null, null, null] +13049 - null - [null, null, null, null, null] +13050 - null - [null, null, null, null, null] +13051 - null - [null, null, null, null, null] +13052 - null - [null, null, null, null, null] +13053 - null - [null, null, null, null, null] +13054 - null - [null, null, null, null, null] +13055 - null - [null, null, null, null, null] +13056 - null - [null, null, null, null, null] +13057 - null - [null, null, null, null, null] +13058 - null - [null, null, null, null, null] +13059 - null - [null, null, null, null, null] +13060 - null - [null, null, null, null, null] +13061 - null - [null, null, null, null, null] +13062 - null - [null, null, null, null, null] +13063 - null - [null, null, null, null, null] +13064 - null - [null, null, null, null, null] +13065 - null - [null, null, null, null, null] +13066 - null - [null, null, null, null, null] +13067 - null - [null, null, null, null, null] +13068 - null - [null, null, null, null, null] +13069 - null - [null, null, null, null, null] +13070 - null - [null, null, null, null, null] +13071 - null - [null, null, null, null, null] +13072 - null - [null, null, null, null, null] +13073 - null - [null, null, null, null, null] +13074 - null - [null, null, null, null, null] +13075 - null - [null, null, null, null, null] +13076 - null - [null, null, null, null, null] +13077 - null - [null, null, null, null, null] +13078 - null - [null, null, null, null, null] +13079 - null - [null, null, null, null, null] +13080 - null - [null, null, null, null, null] +13081 - null - [null, null, null, null, null] +13082 - null - [null, null, null, null, null] +13083 - null - [null, null, null, null, null] +13084 - null - [null, null, null, null, null] +13085 - null - [null, null, null, null, null] +13086 - null - [null, null, null, null, null] +13087 - null - [null, null, null, null, null] +13088 - null - [null, null, null, null, null] +13089 - null - [null, null, null, null, null] +13090 - null - [null, null, null, null, null] +13091 - null - [null, null, null, null, null] +13092 - null - [null, null, null, null, null] +13093 - null - [null, null, null, null, null] +13094 - Large door - [Open, null, null, null, null] +13095 - Large door - [Close, null, null, null, null] +13096 - Large door - [Open, null, null, null, null] +13097 - Large door - [Close, null, null, null, null] +13098 - null - [null, null, null, null, null] +13099 - null - [null, null, null, null, null] +13100 - Door - [Open, null, null, null, null] +13101 - Door - [Open, null, null, null, null] +13102 - Door - [Close, null, null, null, null] +13103 - Door - [Close, null, null, null, null] +13104 - Hazelmere statue - [null, null, null, null, null] +13105 - Glouphrie statue - [null, null, null, null, null] +13106 - Glouphrie statue - [null, null, null, null, null] +13107 - Door - [Open, null, null, null, null] +13108 - Door - [Close, null, null, null, null] +13109 - Door - [Open, null, null, null, null] +13110 - Door - [Close, null, null, null, null] +13111 - null - [null, null, null, null, null] +13112 - null - [null, null, null, null, null] +13113 - null - [null, null, null, null, null] +13114 - Ornament - [Examine, null, null, null, null] +13115 - Goblin crowd - [null, null, null, null, null] +13116 - null - [null, null, null, null, null] +13117 - null - [null, null, null, null, null] +13118 - Door - [Open, null, null, null, null] +13119 - Door - [Open, null, null, null, null] +13120 - Door - [Close, null, null, null, null] +13121 - Door - [Close, null, null, null, null] +13122 - null - [null, null, null, null, null] +13123 - null - [null, null, null, null, null] +13124 - null - [null, null, null, null, null] +13125 - null - [null, null, null, null, null] +13126 - Boxing mat - [null, null, null, null, Remove] +13127 - Boxing mat - [null, null, null, null, Remove] +13128 - Boxing mat - [null, null, null, null, Remove] +13129 - Boxing ring - [Climb-over, null, null, null, Remove] +13130 - Boxing ring - [Climb-over, null, null, null, Remove] +13131 - Boxing ring - [Climb-over, null, null, null, Remove] +13132 - Boxing ring - [Climb-over, null, null, null, Remove] +13133 - Fencing ring - [Climb-over, null, null, null, Remove] +13134 - Fencing ring - [null, null, null, null, Remove] +13135 - Fencing ring - [null, null, null, null, Remove] +13136 - Fencing ring - [null, null, null, null, Remove] +13137 - Combat ring - [Climb-over, null, null, null, Remove] +13138 - Combat ring - [null, null, null, null, Remove] +13139 - Combat ring - [null, null, null, null, Remove] +13140 - Combat ring - [null, null, null, null, Remove] +13141 - Nothing - [hidden, null, null, null, null] +13142 - Balance beam - [Stand-on, hidden, null, Get-down, Remove] +13143 - Balance beam - [Stand-on, hidden, null, Get-down, Remove] +13144 - Balance beam - [Stand-on, hidden, null, Get-down, Remove] +13145 - Magic barrier - [Walk-through, null, null, null, Remove] +13146 - Magic barrier - [Walk-through, null, null, null, null] +13147 - Ranging spot - [null, null, null, null, Remove] +13148 - Bed - [null, null, null, null, Remove] +13149 - Bed - [null, null, null, null, Remove] +13150 - Bed - [null, null, null, null, Remove] +13151 - Bed - [null, null, null, null, Remove] +13152 - Bed - [null, null, null, null, Remove] +13153 - Bed - [null, null, null, null, Remove] +13154 - Bed - [null, null, null, null, Remove] +13155 - Shoe box - [Change-clothes, null, null, null, Remove] +13156 - Oak drawers - [Change-clothes, null, null, null, Remove] +13157 - Oak wardrobe - [Change-clothes, null, null, null, Remove] +13158 - Teak drawers - [Change-clothes, null, null, null, Remove] +13159 - Teak wardrobe - [Change-clothes, null, null, null, Remove] +13160 - Mahogany Wardrobe - [Change-clothes, null, null, null, Remove] +13161 - Gilded wardrobe - [Change-clothes, null, null, null, Remove] +13162 - Shaving stand - [Preen, null, null, null, Remove] +13163 - Shaving stand - [Preen, null, null, null, Remove] +13164 - Dresser - [Preen, null, null, null, Remove] +13165 - Dresser - [Preen, null, null, null, Remove] +13166 - Dresser - [Preen, null, null, null, Remove] +13167 - Dresser - [Preen, null, null, null, Remove] +13168 - Dresser - [Preen, null, null, null, Remove] +13169 - Clock - [Read, null, null, null, Remove] +13170 - Clock - [Read, null, null, null, Remove] +13171 - Clock - [Read, null, null, null, Remove] +13172 - Symbol of Saradomin - [null, null, null, null, Remove] +13173 - Symbol of Zamorak - [null, null, null, null, Remove] +13174 - Symbol of Guthix - [null, null, null, null, Remove] +13175 - Icon of Saradomin - [null, null, null, null, Remove] +13176 - Icon of Zamorak - [null, null, null, null, Remove] +13177 - Icon of Guthix - [null, null, null, null, Remove] +13178 - Icon of Bob - [null, null, null, null, Remove] +13179 - Altar - [Pray, null, null, null, Remove] +13180 - Altar - [Pray, null, null, null, Remove] +13181 - Altar - [Pray, null, null, null, Remove] +13182 - Altar - [Pray, null, null, null, Remove] +13183 - Altar - [Pray, null, null, null, Remove] +13184 - Altar - [Pray, null, null, null, Remove] +13185 - Altar - [Pray, null, null, null, Remove] +13186 - Altar - [Pray, null, null, null, Remove] +13187 - Altar - [Pray, null, null, null, Remove] +13188 - Altar - [Pray, null, null, null, Remove] +13189 - Altar - [Pray, null, null, null, Remove] +13190 - Altar - [Pray, null, null, null, Remove] +13191 - Altar - [Pray, null, null, null, Remove] +13192 - Altar - [Pray, null, null, null, Remove] +13193 - Altar - [Pray, null, null, null, Remove] +13194 - Altar - [Pray, null, null, null, Remove] +13195 - Altar - [Pray, null, null, null, Remove] +13196 - Altar - [Pray, null, null, null, Remove] +13197 - Altar - [Pray, null, null, null, Remove] +13198 - Altar - [Pray, null, null, null, Remove] +13199 - Altar - [Pray, null, null, null, Remove] +13200 - Torch - [Light, null, null, null, Remove] +13201 - Torch - [null, null, null, null, Remove] +13202 - Torch - [Light, null, null, null, Remove] +13203 - Torch - [null, null, null, null, Remove] +13204 - Torch - [Light, null, null, null, Remove] +13205 - Torch - [null, null, null, null, Remove] +13206 - Torch - [Light, null, null, null, Remove] +13207 - Torch - [null, null, null, null, Remove] +13208 - Incense burner - [Light, null, null, null, Remove] +13209 - Incense burner - [null, null, null, null, Remove] +13210 - Incense burner - [Light, null, null, null, Remove] +13211 - Incense burner - [null, null, null, null, Remove] +13212 - Incense burner - [Light, null, null, null, Remove] +13213 - Incense burner - [null, null, null, null, Remove] +13214 - Windchimes - [Play, null, null, null, Remove] +13215 - Bells - [Play, null, null, null, Remove] +13216 - Organ - [Play, null, null, null, Remove] +13217 - Shuttered window - [null, null, null, null, Remove] +13218 - Decorative window - [null, null, null, null, Remove] +13219 - Stained-glass window - [null, null, null, null, Remove] +13220 - Decorative window - [null, null, null, null, Remove] +13221 - Stained-glass window - [null, null, null, null, Remove] +13222 - Decorative window - [null, null, null, null, Remove] +13223 - Stained-glass window - [null, null, null, null, Remove] +13224 - Decorative window - [null, null, null, null, Remove] +13225 - Stained-glass window - [null, null, null, null, Remove] +13226 - Shuttered window - [null, null, null, null, Remove] +13227 - Decorative window - [null, null, null, null, Remove] +13228 - Stained-glass window - [null, null, null, null, Remove] +13229 - Decorative window - [null, null, null, null, Remove] +13230 - Stained-glass window - [null, null, null, null, Remove] +13231 - Decorative window - [null, null, null, null, Remove] +13232 - Stained-glass window - [null, null, null, null, Remove] +13233 - Decorative window - [null, null, null, null, Remove] +13234 - Stained-glass window - [null, null, null, null, Remove] +13235 - Shuttered window - [null, null, null, null, Remove] +13236 - Decorative window - [null, null, null, null, Remove] +13237 - Stained-glass window - [null, null, null, null, Remove] +13238 - Decorative window - [null, null, null, null, Remove] +13239 - Stained-glass window - [null, null, null, null, Remove] +13240 - Decorative window - [null, null, null, null, Remove] +13241 - Stained-glass window - [null, null, null, null, Remove] +13242 - Decorative window - [null, null, null, null, Remove] +13243 - Stained-glass window - [null, null, null, null, Remove] +13244 - Shuttered window - [null, null, null, null, Remove] +13245 - Decorative window - [null, null, null, null, Remove] +13246 - Stained-glass window - [null, null, null, null, Remove] +13247 - Decorative window - [null, null, null, null, Remove] +13248 - Stained-glass window - [null, null, null, null, Remove] +13249 - Decorative window - [null, null, null, null, Remove] +13250 - Stained-glass window - [null, null, null, null, Remove] +13251 - Decorative window - [null, null, null, null, Remove] +13252 - Stained-glass window - [null, null, null, null, Remove] +13253 - Shuttered window - [null, null, null, null, Remove] +13254 - Decorative window - [null, null, null, null, Remove] +13255 - Stained-glass window - [null, null, null, null, Remove] +13256 - Decorative window - [null, null, null, null, Remove] +13257 - Stained-glass window - [null, null, null, null, Remove] +13258 - Decorative window - [null, null, null, null, Remove] +13259 - Stained-glass window - [null, null, null, null, Remove] +13260 - Decorative window - [null, null, null, null, Remove] +13261 - Stained-glass window - [null, null, null, null, Remove] +13262 - Shuttered window - [null, null, null, null, Remove] +13263 - Decorative window - [null, null, null, null, Remove] +13264 - Stained-glass window - [null, null, null, null, Remove] +13265 - Decorative window - [null, null, null, null, Remove] +13266 - Stained-glass window - [null, null, null, null, Remove] +13267 - Decorative window - [null, null, null, null, Remove] +13268 - Stained-glass window - [null, null, null, null, Remove] +13269 - Decorative window - [null, null, null, null, Remove] +13270 - Stained-glass window - [null, null, null, null, Remove] +13271 - Statue - [null, null, null, null, Remove] +13272 - Statue - [null, null, null, null, Remove] +13273 - Statue - [null, null, null, null, Remove] +13274 - Statue - [null, null, null, null, Remove] +13275 - Statue - [null, null, null, null, Remove] +13276 - Statue - [null, null, null, null, Remove] +13277 - Statue - [null, null, null, null, Remove] +13278 - Statue - [null, null, null, null, Remove] +13279 - Statue - [null, null, null, null, Remove] +13280 - Statue - [null, null, null, null, Remove] +13281 - Statue - [null, null, null, null, Remove] +13282 - Statue - [null, null, null, null, Remove] +13283 - Wooden crate - [Open, null, null, null, Remove] +13284 - Wooden crate - [Search, null, null, null, null] +13285 - Oak chest - [Open, null, null, null, Remove] +13286 - Oak chest - [Search, null, null, null, null] +13287 - Teak chest - [Open, null, null, null, Remove] +13288 - Teak chest - [Search, null, null, null, null] +13289 - Mahogany chest - [Open, null, null, null, Remove] +13290 - Mahogany chest - [Search, null, null, null, null] +13291 - Magic chest - [Open, null, null, null, Remove] +13292 - Magic chest - [Search, null, null, null, null] +13293 - Wooden table - [null, null, null, null, Remove] +13294 - Oak table - [null, null, null, null, Remove] +13295 - Oak table - [null, null, null, null, Remove] +13296 - Teak table - [null, null, null, null, Remove] +13297 - Teak table - [null, null, null, null, Remove] +13298 - Mahogany table - [null, null, null, null, Remove] +13299 - Opulent table - [null, null, null, null, Remove] +13300 - Wooden bench - [Sit-on, null, null, null, Remove] +13301 - Oak bench - [Sit-on, null, null, null, Remove] +13302 - Carved oak bench - [Sit-on, null, null, null, Remove] +13303 - Teak bench - [Sit-on, null, null, null, Remove] +13304 - Carved teak bench - [Sit-on, null, null, null, Remove] +13305 - Mahogany bench - [Sit-on, null, null, null, Remove] +13306 - Gilded bench - [Sit-on, null, null, null, Remove] +13307 - Rope bell-pull - [Ring, null, null, null, Remove] +13308 - Bell-pull - [Ring, null, null, null, Remove] +13309 - Posh bell-pull - [Ring, null, null, null, Remove] +13310 - Skeleton - [null, null, null, null, Remove] +13311 - Pipe - [null, null, null, null, Remove] +13312 - Blood - [null, null, null, null, Remove] +13313 - Cage - [null, null, null, Build-in, Remove] +13314 - Door - [Open, Pick-lock, Force, null, Remove] +13315 - Door - [Close, null, null, null, null] +13316 - Cage - [null, null, null, Build-in, Remove] +13317 - Door - [Open, Pick-lock, Force, null, Remove] +13318 - Door - [Close, null, null, null, null] +13319 - Cage - [null, null, null, Build-in, Remove] +13320 - Door - [Open, Pick-lock, Force, null, Remove] +13321 - Door - [Close, null, null, null, null] +13322 - Cage - [null, null, null, Build-in, Remove] +13323 - Door - [Open, Pick-lock, Force, null, Remove] +13324 - Door - [Close, null, null, null, null] +13325 - Cage - [null, null, null, Build-in, Remove] +13326 - Door - [Open, Pick-lock, Force, null, Remove] +13327 - Door - [Close, null, null, null, null] +13328 - Ladder - [Climb, null, null, Remove-room, Remove] +13329 - Ladder - [Climb, null, null, Remove-room, Remove] +13330 - Ladder - [Climb, null, null, Remove-room, Remove] +13331 - Slimy water - [null, null, null, null, Remove] +13332 - Slimy water - [null, null, null, null, Remove] +13333 - Slimy water - [null, null, null, null, Remove] +13334 - Spikes - [null, null, null, null, Remove] +13335 - Spikes - [null, null, null, null, Remove] +13336 - Spikes - [null, null, null, null, Remove] +13337 - Fire - [null, null, null, null, Remove] +13338 - Floor - [null, null, null, null, null] +13339 - Floor - [null, null, null, null, null] +13340 - Floor - [null, null, null, null, null] +13341 - Torch - [null, null, null, null, Remove] +13342 - Candle - [null, null, null, null, Remove] +13343 - Skull - [null, null, null, null, Remove] +13344 - Door - [Open, Pick-lock, Force, null, Remove] +13345 - Door - [Open, Pick-lock, Force, null, Remove] +13346 - Door - [Open, Pick-lock, Force, null, Remove] +13347 - Door - [Open, Pick-lock, Force, null, Remove] +13348 - Door - [Open, Pick-lock, Force, null, Remove] +13349 - Door - [Open, Pick-lock, Force, null, Remove] +13350 - Door - [Close, null, null, null, null] +13351 - Door - [Close, null, null, null, null] +13352 - Door - [Close, null, null, null, null] +13353 - Door - [Close, null, null, null, null] +13354 - Door - [Close, null, null, null, null] +13355 - Door - [Close, null, null, null, null] +13356 - Spike trap - [null, null, null, null, Remove] +13357 - Man trap - [null, null, null, null, Remove] +13358 - Tangle vine - [null, null, null, null, Remove] +13359 - Marble trap - [null, null, null, null, Remove] +13360 - Teleport trap - [null, null, null, null, Remove] +13361 - Spike hidden - [null, null, null, null, Remove] +13362 - Man hidden - [null, null, null, null, Remove] +13363 - Tangle hidden - [null, null, null, null, Remove] +13364 - Marble hidden - [null, null, null, null, Remove] +13365 - Teleport hidden - [null, null, null, null, Remove] +13366 - Bones - [null, null, null, null, Remove] +13367 - Guard dog - [null, null, null, null, Remove] +13368 - Hobgoblin - [null, null, null, null, Remove] +13369 - Troll - [null, null, null, null, Remove] +13370 - Huge Spider - [null, null, null, null, Remove] +13371 - null - [null, null, null, null, null] +13372 - Baby red dragon - [null, null, null, null, Remove] +13373 - Rocnar - [null, null, null, null, Remove] +13374 - Kalphite Soldier - [null, null, null, null, Remove] +13375 - Steel dragon - [null, null, null, null, Remove] +13376 - Dagannoth - [null, null, null, null, Remove] +13377 - Tok-Xil - [null, null, null, null, Remove] +13378 - Demon - [null, null, null, null, Remove] +13379 - Treasure Hunt Fairy House - [Activate, null, null, null, Remove] +13380 - Treasure Hunt Fairy House - [Activate, null, null, null, Remove] +13381 - Glove Rack - [Search, null, null, null, Remove] +13382 - Weapons Rack - [Search, null, null, null, Remove] +13383 - Weapons Rack - [Search, null, null, null, Remove] +13384 - Oak prize chest - [null, null, null, null, Remove] +13385 - Oak prize chest - [Open, null, null, null, Remove] +13386 - Teak prize chest - [null, null, null, null, Remove] +13387 - Teak prize chest - [Open, null, null, null, Remove] +13388 - Mahogany prize chest - [null, null, null, null, Remove] +13389 - Mahogany prize chest - [Open, null, null, null, Remove] +13390 - Jacky Jester - [Activate, null, null, null, Remove] +13391 - Jacky Jester - [Activate, null, null, null, null] +13392 - Attack stone - [Set-up, null, null, null, Remove] +13393 - Attack stone - [Set-up, null, null, null, Remove] +13394 - Attack stone - [Set-up, null, null, null, Remove] +13395 - Elemental balance - [Activate, null, null, null, Remove] +13396 - Elemental balance - [Activate, null, null, null, Remove] +13397 - Elemental balance - [Activate, null, null, null, Remove] +13398 - Stick - [Hoop, null, null, null, Remove] +13399 - Stick and hoop - [Hoop, null, null, null, Remove] +13400 - Dartboard - [Throw-at, null, null, null, Remove] +13401 - Dartboard - [Throw-at, null, null, null, Remove] +13402 - Archery target - [Shoot-at, null, null, null, Remove] +13403 - Archery target - [Shoot-at, null, null, null, Remove] +13404 - Hangman game - [Activate, null, null, null, Remove] +13405 - Portal - [Enter, Lock, null, null, Remove] +13406 - Rock - [null, null, null, null, Remove] +13407 - Pond - [null, null, null, null, Remove] +13408 - Statue - [null, null, null, null, Remove] +13409 - Dungeon entrance - [Enter, null, null, Remove-room, Remove] +13410 - null - [null, null, null, null, null] +13411 - Dead tree - [null, null, null, null, Remove] +13412 - Tree - [null, null, null, null, Remove] +13413 - Oak tree - [null, null, null, null, Remove] +13414 - Willow tree - [null, null, null, null, Remove] +13415 - Maple tree - [null, null, null, null, Remove] +13416 - Yew tree - [null, null, null, null, Remove] +13417 - Magic tree - [null, null, null, null, Remove] +13418 - Dead Tree - [null, null, null, null, Remove] +13419 - Tree - [null, null, null, null, Remove] +13420 - Oak Tree - [null, null, null, null, Remove] +13421 - Willow Tree - [null, null, null, null, Remove] +13422 - Yew tree - [null, null, null, null, Remove] +13423 - Maple tree - [null, null, null, null, Remove] +13424 - Magic tree - [null, null, null, null, Remove] +13425 - Fern - [null, null, null, null, Remove] +13426 - Bush - [null, null, null, null, Remove] +13427 - Tall Plant - [null, null, null, null, Remove] +13428 - Short Plant - [null, null, null, null, Remove] +13429 - Large-leaf Plant - [null, null, null, null, Remove] +13430 - Huge plant - [null, null, null, null, Remove] +13431 - Plant - [null, null, null, null, Remove] +13432 - Small fern - [null, null, null, null, Remove] +13433 - Fern - [null, null, null, null, Remove] +13434 - Dock Leaf - [null, null, null, null, Remove] +13435 - Thistle - [null, null, null, null, Remove] +13436 - Reeds - [null, null, null, null, Remove] +13437 - Rosemary - [null, null, null, null, Remove] +13438 - Daffodils - [null, null, null, null, Remove] +13439 - Bluebells - [null, null, null, null, Remove] +13440 - Rosemary - [null, null, null, null, Remove] +13441 - Daffodils - [null, null, null, null, Remove] +13442 - Bluebells - [null, null, null, null, Remove] +13443 - Sunflower - [null, null, null, null, Remove] +13444 - Marigolds - [null, null, null, null, Remove] +13445 - Roses - [null, null, null, null, Remove] +13446 - Sunflowers - [null, null, null, null, Remove] +13447 - Marigolds - [null, null, null, null, Remove] +13448 - Roses - [null, null, null, null, Remove] +13449 - Boundary stones - [null, null, null, null, Remove] +13450 - Wooden fence - [null, null, null, null, Remove] +13451 - Stone wall - [null, null, null, null, Remove] +13452 - Iron railings - [null, null, null, null, Remove] +13453 - Picket fence - [null, null, null, null, Remove] +13454 - Garden fence - [null, null, null, null, Remove] +13455 - Marble wall - [null, null, null, null, Remove] +13456 - Hedge - [null, null, null, null, Remove] +13457 - Hedge - [null, null, null, null, Remove] +13458 - Hedge - [null, null, null, null, Remove] +13459 - Hedge - [null, null, null, null, Remove] +13460 - Hedge - [null, null, null, null, Remove] +13461 - Hedge - [null, null, null, null, Remove] +13462 - Hedge - [null, null, null, null, Remove] +13463 - Hedge - [null, null, null, null, Remove] +13464 - Hedge - [null, null, null, null, Remove] +13465 - Hedge - [null, null, null, null, Remove] +13466 - Hedge - [null, null, null, null, Remove] +13467 - Hedge - [null, null, null, null, Remove] +13468 - Hedge - [null, null, null, null, Remove] +13469 - Hedge - [null, null, null, null, Remove] +13470 - Hedge - [null, null, null, null, Remove] +13471 - Hedge - [null, null, null, null, Remove] +13472 - Hedge - [null, null, null, null, Remove] +13473 - Hedge - [null, null, null, null, Remove] +13474 - Hedge - [null, null, null, null, Remove] +13475 - Hedge - [null, null, null, null, Remove] +13476 - Hedge - [null, null, null, null, Remove] +13477 - Gazebo - [null, null, null, null, Remove] +13478 - Small fountain - [null, null, null, null, Remove] +13479 - Large fountain - [null, null, null, null, Remove] +13480 - Ornamental fountain - [null, null, null, null, Remove] +13481 - Crawling hand - [Talk-to, null, null, null, Remove] +13482 - Cockatrice head - [Talk-to, null, null, null, Remove] +13483 - Basilisk head - [Talk-to, null, null, null, Remove] +13484 - Kurask head - [Talk-to, null, null, null, Remove] +13485 - Abyssal demon head - [Talk-to, null, null, null, Remove] +13486 - KBD heads - [Talk-to, null, null, null, Remove] +13487 - KQ head - [Talk-to, null, null, null, Remove] +13488 - Mounted sea bass - [null, null, null, null, Remove] +13489 - Mounted swordfish - [null, null, null, null, Remove] +13490 - Mounted shark - [null, null, null, null, Remove] +13491 - Mithril armour - [null, null, null, null, Remove] +13492 - Adamant armour - [null, null, null, null, Remove] +13493 - Rune armour - [null, null, null, null, Remove] +13494 - null - [null, null, null, null, null] +13495 - White Castlewars armour - [null, null, null, null, Remove] +13496 - Gold Castlewars armour - [null, null, null, null, Remove] +13497 - Staircase - [Climb-up, null, null, Remove-room, Remove] +13498 - Staircase - [Climb-down, null, null, Remove-room, Remove] +13499 - Staircase - [Climb-up, null, null, Remove-room, Remove] +13500 - Staircase - [Climb-down, null, null, Remove-room, Remove] +13501 - Staircase - [Climb-up, null, null, Remove-room, Remove] +13502 - Staircase - [Climb-down, null, null, Remove-room, Remove] +13503 - Staircase - [Climb, Climb-up, Climb-down, Remove-room, Remove] +13504 - Staircase - [Climb, null, Climb-down, Remove-room, Remove] +13505 - Staircase - [Climb, Climb-up, Climb-down, Remove-room, Remove] +13506 - Staircase - [Climb, null, Climb-down, Remove-room, Remove] +13507 - Rune display case - [null, null, null, null, Remove] +13508 - Rune display case - [null, null, null, null, Remove] +13509 - Rune display case - [null, null, null, null, Remove] +13510 - Portrait - [null, null, null, null, Remove] +13511 - Portrait - [null, null, null, null, Remove] +13512 - Painting - [null, null, null, null, Remove] +13513 - Portrait - [null, null, null, null, Remove] +13514 - Desert painting - [null, null, null, null, Remove] +13515 - Isafdar painting - [null, null, null, null, Remove] +13516 - Karamja painting - [null, null, null, null, Remove] +13517 - Lumbridge painting - [null, null, null, null, Remove] +13518 - Morytania painting - [null, null, null, null, Remove] +13519 - Silverlight - [null, null, null, null, Remove] +13520 - Darklight - [null, null, null, null, Remove] +13521 - Excalibur - [null, null, null, null, Remove] +13522 - Anti-Dragon Breath Shield - [null, null, null, null, Remove] +13523 - Amulet of Glory - [Rub, null, null, null, Remove] +13524 - Cape of Legends - [null, null, null, null, Remove] +13525 - Map - [null, null, null, null, Remove] +13526 - Map - [null, null, null, null, Remove] +13527 - Map - [null, null, null, null, Remove] +13528 - Firepit - [null, null, null, null, Remove] +13529 - Firepit with hook - [null, null, null, null, Remove] +13530 - Firepit with hook - [Take-kettle, null, null, null, null] +13531 - Firepit with pot - [null, null, null, null, Remove] +13532 - Firepit with pot - [Take-kettle, null, null, null, null] +13533 - Small oven - [null, null, null, null, Remove] +13534 - Small Oven - [null, null, null, null, Remove] +13535 - Small oven - [Take-kettle, null, null, null, null] +13536 - Large oven - [null, null, null, null, Remove] +13537 - Large oven - [null, null, null, null, Remove] +13538 - Large oven - [Take-kettle, null, null, null, null] +13539 - Steel range - [null, null, null, null, Remove] +13540 - Steel range - [Take-kettle, null, null, null, null] +13541 - Steel range - [null, null, null, null, Remove] +13542 - Fancy range - [null, null, null, null, Remove] +13543 - Fancy range - [Take-kettle, null, null, null, null] +13544 - Fancy range - [null, null, null, null, Remove] +13545 - Shelves - [Search, null, null, null, Remove] +13546 - Shelves - [Search, null, null, null, Remove] +13547 - Shelves - [Search, null, null, null, Remove] +13548 - Shelves - [Search, null, null, null, Remove] +13549 - Shelves - [Search, null, null, null, Remove] +13550 - Shelves - [Search, null, null, null, Remove] +13551 - Shelves - [Search, null, null, null, Remove] +13552 - Shelves - [Search, null, null, null, Remove] +13553 - Shelves - [Search, null, null, null, Remove] +13554 - Shelves - [Search, null, null, null, Remove] +13555 - Shelves - [Search, null, null, null, Remove] +13556 - Shelves - [Search, null, null, null, Remove] +13557 - Shelves - [Search, null, null, null, Remove] +13558 - Shelves - [Search, null, null, null, Remove] +13559 - Pump and drain - [null, null, null, null, Remove] +13560 - Pump and drain - [null, null, null, null, Remove] +13561 - Pump and tub - [null, null, null, null, Remove] +13562 - Pump and tub - [null, null, null, null, Remove] +13563 - Sink - [null, null, null, null, Remove] +13564 - Sink - [null, null, null, null, Remove] +13565 - Larder - [Search, null, null, null, Remove] +13566 - Larder - [Search, null, null, null, Remove] +13567 - Larder - [Search, null, null, null, Remove] +13568 - Beer barrel - [null, null, null, null, Remove] +13569 - Cider barrel - [null, null, null, null, Remove] +13570 - Asgarnian ale - [null, null, null, null, Remove] +13571 - Greenman's ale - [null, null, null, null, Remove] +13572 - Dragon bitter - [null, null, null, null, Remove] +13573 - Chef's Delight - [null, null, null, null, Remove] +13574 - Pet blanket - [null, null, null, null, Remove] +13575 - Pet basket - [null, null, null, null, Remove] +13576 - Pet basket - [null, null, null, null, Remove] +13577 - Wooden table - [null, null, null, null, Remove] +13578 - Oak table - [null, null, null, null, Remove] +13579 - Teak table - [null, null, null, null, Remove] +13580 - Pet blanket - [Sleep-in, null, null, null, Remove] +13581 - Chair - [Sit-on, null, null, null, Remove] +13582 - Chair - [Sit-on, null, null, null, Remove] +13583 - Chair - [Sit-on, null, null, null, Remove] +13584 - Chair - [Sit-on, null, null, null, Remove] +13585 - Chair - [Sit-on, null, null, null, Remove] +13586 - Chair - [Sit-on, null, null, null, Remove] +13587 - Chair - [Sit-on, null, null, null, Remove] +13588 - Rug - [null, null, null, null, Remove] +13589 - Rug - [null, null, null, null, Remove] +13590 - Rug - [null, null, null, null, Remove] +13591 - Rug - [null, null, null, null, Remove] +13592 - Rug - [null, null, null, null, Remove] +13593 - Rug - [null, null, null, null, Remove] +13594 - Rug - [null, null, null, null, Remove] +13595 - Rug - [null, null, null, null, Remove] +13596 - Rug - [null, null, null, null, Remove] +13597 - Bookcase - [Search, null, null, null, Remove] +13598 - Bookcase - [Search, null, null, null, Remove] +13599 - Bookcase - [Search, null, null, null, Remove] +13600 - Scroll rack - [Search, null, null, null, Remove] +13601 - Scroll rack - [Search, null, null, null, Remove] +13602 - Scroll rack - [Search, null, null, null, Remove] +13603 - Curtains - [null, null, null, null, Remove] +13604 - Curtains - [null, null, null, null, Remove] +13605 - Curtains - [null, null, null, null, Remove] +13606 - Wall decoration - [null, null, null, null, Remove] +13607 - Wall decoration - [null, null, null, null, Remove] +13608 - Wall decoration - [null, null, null, null, Remove] +13609 - Clay fireplace - [Light, null, null, null, Remove] +13610 - Clay fireplace - [null, null, null, null, null] +13611 - Limestone fireplace - [Light, null, null, null, Remove] +13612 - Limestone fireplace - [null, null, null, null, null] +13613 - Marble fireplace - [Light, null, null, null, Remove] +13614 - Marble fireplace - [null, null, null, null, null] +13615 - Varrock Portal - [Enter, null, null, null, Remove] +13616 - Lumbridge Portal - [Enter, null, null, null, Remove] +13617 - Falador Portal - [Enter, null, null, null, Remove] +13618 - Camelot Portal - [Enter, null, null, null, Remove] +13619 - Ardougne Portal - [Enter, null, null, null, Remove] +13620 - Yanille Portal - [Enter, null, null, null, Remove] +13621 - Kharyrll Portal - [Enter, null, null, null, Remove] +13622 - Varrock Portal - [Enter, null, null, null, Remove] +13623 - Lumbridge Portal - [Enter, null, null, null, Remove] +13624 - Falador Portal - [Enter, null, null, null, Remove] +13625 - Camelot Portal - [Enter, null, null, null, Remove] +13626 - Ardougne Portal - [Enter, null, null, null, Remove] +13627 - Yanille Portal - [Enter, null, null, null, Remove] +13628 - Kharyrll Portal - [Enter, null, null, null, Remove] +13629 - Varrock Portal - [Enter, null, null, null, Remove] +13630 - Lumbridge Portal - [Enter, null, null, null, Remove] +13631 - Falador Portal - [Enter, null, null, null, Remove] +13632 - Camelot Portal - [Enter, null, null, null, Remove] +13633 - Ardougne Portal - [Enter, null, null, null, Remove] +13634 - Yanille Portal - [Enter, null, null, null, Remove] +13635 - Kharyrll Portal - [Enter, null, null, null, Remove] +13636 - Portal frame - [null, null, null, null, Remove] +13637 - Portal frame - [null, null, null, null, Remove] +13638 - Portal frame - [null, null, null, null, Remove] +13639 - Scrying pool - [Direct-portal, Scry, null, null, Remove] +13640 - Teleportation focus - [Direct-portal, null, null, null, Remove] +13641 - Greater teleport focus - [Direct-portal, null, null, null, Remove] +13642 - Lectern - [Study, null, null, null, Remove] +13643 - Lectern - [Study, null, null, null, Remove] +13644 - Lectern - [Study, null, null, null, Remove] +13645 - Lectern - [Study, null, null, null, Remove] +13646 - Lectern - [Study, null, null, null, Remove] +13647 - Lectern - [Study, null, null, null, Remove] +13648 - Lectern - [Study, null, null, null, Remove] +13649 - Globe - [null, null, null, null, Remove] +13650 - Ornamental globe - [null, null, null, null, Remove] +13651 - Lunar globe - [null, null, null, null, Remove] +13652 - Celestial globe - [null, null, null, null, Remove] +13653 - Armillary sphere - [null, null, null, null, Remove] +13654 - Small orrery - [null, null, null, null, Remove] +13655 - Large orrery - [null, null, null, null, Remove] +13656 - Telescope - [Observe, null, null, null, Remove] +13657 - Telescope - [Observe, null, null, null, Remove] +13658 - Telescope - [Observe, null, null, null, Remove] +13659 - Crystal ball - [null, null, null, null, Remove] +13660 - Elemental sphere - [null, null, null, null, Remove] +13661 - Crystal of power - [null, null, null, null, Remove] +13662 - Alchemical chart - [Study, null, null, null, Remove] +13663 - Astronomical chart - [Study, null, null, null, Remove] +13664 - Infernal chart - [Study, null, null, null, Remove] +13665 - Throne - [Sit-on, null, null, null, Remove] +13666 - Throne - [Sit-on, null, null, null, Remove] +13667 - Throne - [Sit-on, null, null, null, Remove] +13668 - Throne - [Sit-on, null, null, null, Remove] +13669 - Throne - [Sit-on, null, null, null, Remove] +13670 - Throne - [Sit-on, null, null, null, Remove] +13671 - Throne - [Sit-on, null, null, null, Remove] +13672 - Lever - [Pull, Challenge-mode, null, null, Remove] +13673 - Lever - [Pull, Challenge-mode, null, null, Remove] +13674 - Lever - [Pull, Challenge-mode, null, null, Remove] +13675 - Trapdoor - [Open, null, null, Remove-room, Remove] +13676 - Trapdoor - [Open, null, null, Remove-room, Remove] +13677 - Trapdoor - [Open, null, null, Remove-room, Remove] +13678 - Trapdoor - [Go-down, Close, null, Remove-room, Remove] +13679 - Trapdoor - [Go-down, Close, null, Remove-room, Remove] +13680 - Trapdoor - [Go-down, Close, null, Remove-room, Remove] +13681 - Steel cage - [null, null, null, null, Remove] +13682 - Magic circle - [null, null, null, null, Remove] +13683 - Greater magic circle - [null, null, null, null, Remove] +13684 - Floor decoration - [null, null, null, null, Remove] +13685 - Floor decoration - [null, null, null, null, Remove] +13686 - Floor decoration - [null, null, null, null, Remove] +13687 - Floor decoration - [null, null, null, null, Remove] +13688 - Floor decoration - [null, null, null, null, Remove] +13689 - Floor decoration - [null, null, null, null, Remove] +13690 - Hanging - [null, null, null, null, Remove] +13691 - Decoration - [null, null, null, null, Remove] +13692 - Decoration - [null, null, null, null, Remove] +13693 - Decoration - [null, null, null, null, Remove] +13694 - Teak bench - [Sit-on, null, null, null, Remove] +13695 - Mahogany bench - [Sit-on, null, null, null, Remove] +13696 - Gilded bench - [Sit-on, null, null, null, Remove] +13697 - Nothing - [null, null, null, null, null] +13698 - Throne - [null, null, null, null, null] +13699 - Tools - [Search, null, null, Upgrade, Remove] +13700 - Tools - [Search, null, null, Upgrade, Remove] +13701 - Tools - [Search, null, null, Upgrade, Remove] +13702 - Tools - [Search, null, null, Upgrade, Remove] +13703 - Tools - [Search, null, null, null, Remove] +13704 - Workbench - [Work-at, null, null, null, Remove] +13705 - Workbench - [Work-at, null, null, null, Remove] +13706 - Workbench - [Work-at, null, null, Upgrade, Remove] +13707 - Workbench - [Work-at, null, null, Upgrade, Remove] +13708 - Workbench - [Work-at, null, null, null, Remove] +13709 - Clockmaker's bench - [Craft, null, null, Upgrade, Remove] +13710 - Clockmaker's bench - [Craft, null, null, Upgrade, Remove] +13711 - Clockmaker's bench - [Craft, null, null, Upgrade, Remove] +13712 - Clockmaker's bench - [Craft, null, null, null, Remove] +13713 - Repair bench - [null, null, null, null, Remove] +13714 - Whetstone - [null, null, null, null, Remove] +13715 - Armour repair stand - [null, null, null, null, Remove] +13716 - Helmet pluming stand - [Make-helmet, null, null, null, Remove] +13717 - Painting stand - [Use, null, null, null, Remove] +13718 - Banner making stand - [Use, null, null, null, Remove] +13719 - Stool - [null, null, null, null, null] +13720 - Stool - [null, null, null, null, null] +13721 - Nothing - [null, null, null, null, null] +13722 - Nothing - [null, null, null, null, null] +13723 - Nothing - [null, null, null, null, null] +13724 - Nothing - [null, null, null, null, null] +13725 - null - [null, null, null, null, null] +13726 - Jacky Jester - [null, null, null, null, null] +13727 - Jacky Jester - [null, null, null, null, null] +13728 - Window space - [null, null, null, null, Build] +13729 - Window space - [null, null, null, null, Build] +13730 - Window space - [null, null, null, null, Build] +13731 - Window space - [null, null, null, null, Build] +13732 - Window space - [null, null, null, null, Build] +13733 - Window space - [null, null, null, null, Build] +13734 - Round shield - [null, null, null, null, Remove] +13735 - Round shield - [null, null, null, null, Remove] +13736 - Round shield - [null, null, null, null, Remove] +13737 - Round shield - [null, null, null, null, Remove] +13738 - Round shield - [null, null, null, null, Remove] +13739 - Round shield - [null, null, null, null, Remove] +13740 - Round shield - [null, null, null, null, Remove] +13741 - Round shield - [null, null, null, null, Remove] +13742 - Round shield - [null, null, null, null, Remove] +13743 - Round shield - [null, null, null, null, Remove] +13744 - Round shield - [null, null, null, null, Remove] +13745 - Round shield - [null, null, null, null, Remove] +13746 - Round shield - [null, null, null, null, Remove] +13747 - Round shield - [null, null, null, null, Remove] +13748 - Round shield - [null, null, null, null, Remove] +13749 - Round shield - [null, null, null, null, Remove] +13750 - Kite shield - [null, null, null, null, Remove] +13751 - Kite shield - [null, null, null, null, Remove] +13752 - Kite shield - [null, null, null, null, Remove] +13753 - Kite shield - [null, null, null, null, Remove] +13754 - Kite shield - [null, null, null, null, Remove] +13755 - Kite shield - [null, null, null, null, Remove] +13756 - Kite shield - [null, null, null, null, Remove] +13757 - Kite shield - [null, null, null, null, Remove] +13758 - Kite shield - [null, null, null, null, Remove] +13759 - Kite shield - [null, null, null, null, Remove] +13760 - Kite shield - [null, null, null, null, Remove] +13761 - Kite shield - [null, null, null, null, Remove] +13762 - Kite shield - [null, null, null, null, Remove] +13763 - Kite shield - [null, null, null, null, Remove] +13764 - Kite shield - [null, null, null, null, Remove] +13765 - Kite shield - [null, null, null, null, Remove] +13766 - Square shield - [null, null, null, null, Remove] +13767 - Square shield - [null, null, null, null, Remove] +13768 - Square shield - [null, null, null, null, Remove] +13769 - Square shield - [null, null, null, null, Remove] +13770 - Square shield - [null, null, null, null, Remove] +13771 - Square shield - [null, null, null, null, Remove] +13772 - Square shield - [null, null, null, null, Remove] +13773 - Square shield - [null, null, null, null, Remove] +13774 - Square shield - [null, null, null, null, Remove] +13775 - Square shield - [null, null, null, null, Remove] +13776 - Square shield - [null, null, null, null, Remove] +13777 - Square shield - [null, null, null, null, Remove] +13778 - Square shield - [null, null, null, null, Remove] +13779 - Square shield - [null, null, null, null, Remove] +13780 - Square shield - [null, null, null, null, Remove] +13781 - Square shield - [null, null, null, null, Remove] +13782 - Mahogany wall decoration - [null, null, null, null, Remove] +13783 - Mahogany wall decoration - [null, null, null, null, Remove] +13784 - Mahogany wall decoration - [null, null, null, null, Remove] +13785 - Mahogany wall decoration - [null, null, null, null, Remove] +13786 - Mahogany wall decoration - [null, null, null, null, Remove] +13787 - Mahogany wall decoration - [null, null, null, null, Remove] +13788 - Mahogany wall decoration - [null, null, null, null, Remove] +13789 - Mahogany wall decoration - [null, null, null, null, Remove] +13790 - Mahogany wall decoration - [null, null, null, null, Remove] +13791 - Mahogany wall decoration - [null, null, null, null, Remove] +13792 - Mahogany wall decoration - [null, null, null, null, Remove] +13793 - Mahogany wall decoration - [null, null, null, null, Remove] +13794 - Mahogany wall decoration - [null, null, null, null, Remove] +13795 - Mahogany wall decoration - [null, null, null, null, Remove] +13796 - Mahogany wall decoration - [null, null, null, null, Remove] +13797 - Mahogany wall decoration - [null, null, null, null, Remove] +13798 - Oak wall decoration - [null, null, null, null, Remove] +13799 - Oak wall decoration - [null, null, null, null, Remove] +13800 - Oak wall decoration - [null, null, null, null, Remove] +13801 - Oak wall decoration - [null, null, null, null, Remove] +13802 - Oak wall decoration - [null, null, null, null, Remove] +13803 - Oak wall decoration - [null, null, null, null, Remove] +13804 - Oak wall decoration - [null, null, null, null, Remove] +13805 - Oak wall decoration - [null, null, null, null, Remove] +13806 - Oak wall decoration - [null, null, null, null, Remove] +13807 - Oak wall decoration - [null, null, null, null, Remove] +13808 - Oak wall decoration - [null, null, null, null, Remove] +13809 - Oak wall decoration - [null, null, null, null, Remove] +13810 - Oak wall decoration - [null, null, null, null, Remove] +13811 - Oak wall decoration - [null, null, null, null, Remove] +13812 - Oak wall decoration - [null, null, null, null, Remove] +13813 - Oak wall decoration - [null, null, null, null, Remove] +13814 - Teak wall decoration - [null, null, null, null, Remove] +13815 - Teak wall decoration - [null, null, null, null, Remove] +13816 - Teak wall decoration - [null, null, null, null, Remove] +13817 - Teak wall decoration - [null, null, null, null, Remove] +13818 - Teak wall decoration - [null, null, null, null, Remove] +13819 - Teak wall decoration - [null, null, null, null, Remove] +13820 - Teak wall decoration - [null, null, null, null, Remove] +13821 - Teak wall decoration - [null, null, null, null, Remove] +13822 - Teak wall decoration - [null, null, null, null, Remove] +13823 - Teak wall decoration - [null, null, null, null, Remove] +13824 - Teak wall decoration - [null, null, null, null, Remove] +13825 - Teak wall decoration - [null, null, null, null, Remove] +13826 - Teak wall decoration - [null, null, null, null, Remove] +13827 - Teak wall decoration - [null, null, null, null, Remove] +13828 - Teak wall decoration - [null, null, null, null, Remove] +13829 - Teak wall decoration - [null, null, null, null, Remove] +13830 - Window - [null, null, null, null, null] +13831 - Path - [null, Evade-event, null, null, null] +13832 - Path - [Look-at, Continue-trek, null, null, null] +13833 - Path - [Look-at, Escape, null, null, null] +13834 - Broken bridge - [Search, null, null, null, null] +13835 - Partially broken bridge - [Search, null, null, null, null] +13836 - Slightly broken bridge - [Search, null, null, null, null] +13837 - Fixed bridge - [Search, Walk-across, null, null, null] +13838 - Bog - [Stand-on, null, null, null, null] +13839 - Bog - [Stand-on, null, null, null, null] +13840 - Spiny bush - [null, null, null, null, null] +13841 - Row boat - [null, null, null, null, null] +13842 - Ripples - [null, null, null, null, null] +13843 - Swamp tree - [null, null, null, null, null] +13844 - Swamp tree - [null, null, null, null, null] +13845 - Swamp tree - [null, null, null, null, null] +13846 - Vine hanging from branch - [Look-at, Swing-on, null, null, null] +13847 - Swamp tree - [null, null, null, null, null] +13848 - Swamp tree - [null, null, null, null, null] +13849 - Swamp tree - [null, null, null, null, null] +13850 - Swamp tree - [null, null, null, null, null] +13851 - null - [null, null, null, null, null] +13852 - null - [null, null, null, null, null] +13853 - null - [null, null, null, null, null] +13854 - null - [null, null, null, null, null] +13855 - null - [null, null, null, null, null] +13856 - null - [null, null, null, null, null] +13857 - null - [null, null, null, null, null] +13858 - null - [null, null, null, null, null] +13859 - null - [null, null, null, null, null] +13860 - null - [null, null, null, null, null] +13861 - null - [null, null, null, null, null] +13862 - null - [null, null, null, null, null] +13863 - null - [null, null, null, null, null] +13864 - Boat - [null, null, null, Continue-trek, Escape-event] +13865 - null - [null, null, null, null, null] +13866 - Path - [Look-at, Continue-trek, null, null, null] +13867 - Path - [Look-at, Continue-trek, null, null, null] +13868 - Path - [Look-at, Return-to-Burgh, null, null, null] +13869 - Path - [null, Evade-event, null, null, null] +13870 - Path - [Look-at, Continue-trek, null, null, null] +13871 - Path - [Look-at, Escape, null, null, null] +13872 - Backpack - [Search, null, null, null, null] +13873 - Signpost - [Read, null, null, null, null] +13874 - null - [null, null, null, null, null] +13875 - null - [null, null, null, null, null] +13876 - null - [null, null, null, null, null] +13877 - null - [null, null, null, null, null] +13878 - Exit - [Use, null, null, null, null] +13879 - Exit - [Use, null, null, null, null] +13880 - null - [null, null, null, null, null] +13881 - Fire - [null, null, null, null, null] +13882 - Exit - [Enter, null, null, null, null] +13883 - null - [null, null, null, null, null] +13884 - null - [null, null, null, null, null] +13885 - null - [null, null, null, null, null] +13886 - null - [null, null, null, null, null] +13887 - null - [null, null, null, null, null] +13888 - null - [null, null, null, null, null] +13889 - null - [null, null, null, null, null] +13890 - null - [null, null, null, null, null] +13891 - Dark hole - [Look-inside, null, null, null, null] +13892 - Dark hole - [Look-inside, null, null, null, null] +13893 - Dark hole - [Look-inside, null, null, null, null] +13894 - Dark hole - [Look-inside, null, null, null, null] +13895 - Dark hole - [Look-inside, null, null, null, null] +13896 - Dark hole - [Look-inside, null, null, null, null] +13897 - null - [null, null, null, null, null] +13898 - null - [Enter, null, null, null, null] +13899 - Black hole - [Enter, null, null, null, null] +13900 - Black hole - [Enter, null, null, null, null] +13901 - Exit - [Use, null, null, null, null] +13902 - null - [null, null, null, null, null] +13903 - null - [null, null, null, null, null] +13904 - Exit - [Use, null, null, null, null] +13905 - null - [null, null, null, null, null] +13906 - null - [null, null, null, null, null] +13907 - null - [Enter, null, null, null, null] +13908 - null - [Enter, null, null, null, null] +13909 - null - [Enter, null, null, null, null] +13910 - null - [Enter, null, null, null, null] +13911 - null - [Enter, null, null, null, null] +13912 - null - [Enter, null, null, null, null] +13913 - Confusing door - [Enter, null, null, null, null] +13914 - Confusing door - [Enter, null, null, null, null] +13915 - Confusing door - [Enter, null, null, null, null] +13916 - Confusing door - [Enter, null, null, null, null] +13917 - Confusing door - [Enter, null, null, null, null] +13918 - Confusing door - [Enter, null, null, null, null] +13919 - Confusing door - [Enter, null, null, null, null] +13920 - Confusing door - [Enter, null, null, null, null] +13921 - Confusing door - [Enter, null, null, null, null] +13922 - Confusing door - [Enter, null, null, null, null] +13923 - Confusing door - [Enter, null, null, null, null] +13924 - Confusing door - [Enter, null, null, null, null] +13925 - Hole - [null, null, null, null, null] +13926 - null - [null, null, null, null, null] +13927 - null - [null, null, null, null, null] +13928 - null - [null, null, null, null, null] +13929 - null - [null, null, null, null, null] +13930 - null - [null, null, null, null, null] +13931 - null - [null, null, null, null, null] +13932 - Exit - [Use, null, null, null, null] +13933 - Exit - [Use, null, null, null, null] +13934 - null - [null, null, null, null, null] +13935 - null - [null, null, null, null, null] +13936 - null - [null, null, null, null, null] +13937 - null - [null, null, null, null, null] +13938 - Hope bridge - [null, null, null, null, null] +13939 - Hope bridge - [null, null, null, null, null] +13940 - Hope bridge - [null, null, null, null, null] +13941 - Hope bridge - [null, null, null, null, null] +13942 - Hope bridge - [null, null, null, null, null] +13943 - Hope bridge - [null, null, null, null, null] +13944 - Hope bridge - [null, null, null, null, null] +13945 - Hope bridge - [null, null, null, null, null] +13946 - Hope bridge - [null, null, null, null, null] +13947 - Hope bridge - [null, null, null, null, null] +13948 - Hope bridge - [null, null, null, null, null] +13949 - Hope bridge - [null, null, null, null, null] +13950 - Hope bridge - [null, null, null, null, null] +13951 - Hope bridge - [null, null, null, null, null] +13952 - Hope bridge - [null, null, null, null, null] +13953 - Hope bridge - [null, null, null, null, null] +13954 - Hope bridge - [null, null, null, null, null] +13955 - Hope bridge - [null, null, null, null, null] +13956 - Hope bridge - [null, null, null, null, null] +13957 - Hope bridge - [null, null, null, null, null] +13958 - Hope bridge - [null, null, null, null, null] +13959 - Hope bridge - [null, null, null, null, null] +13960 - Hope bridge - [null, null, null, null, null] +13961 - Hope bridge - [null, null, null, null, null] +13962 - null - [null, null, null, null, null] +13963 - null - [null, null, null, null, null] +13964 - null - [null, null, null, null, null] +13965 - null - [null, null, null, null, null] +13966 - null - [null, null, null, null, null] +13967 - Rift - [Enter, null, null, null, null] +13968 - null - [Enter, null, null, null, null] +13969 - Rift - [Enter, null, null, null, null] +13970 - Rift - [Enter, null, null, null, null] +13971 - Rift - [Enter, null, null, null, null] +13972 - Rift - [Enter, null, null, null, null] +13973 - Rift - [Enter, null, null, null, null] +13974 - Rift - [Enter, null, null, null, null] +13975 - Rift - [Enter, null, null, null, null] +13976 - Rift - [Enter, null, null, null, null] +13977 - Rift - [Enter, null, null, null, null] +13978 - Rift - [Enter, null, null, null, null] +13979 - Rift - [Enter, null, null, null, null] +13980 - Rift - [Enter, null, null, null, null] +13981 - null - [null, null, null, null, null] +13982 - null - [null, null, null, null, null] +13983 - null - [null, null, null, null, null] +13984 - null - [null, null, null, null, null] +13985 - null - [null, null, null, null, null] +13986 - null - [null, null, null, null, null] +13987 - null - [null, null, null, null, null] +13988 - null - [null, null, null, null, null] +13989 - null - [null, null, null, null, null] +13990 - null - [null, null, null, null, null] +13991 - null - [null, null, null, null, null] +13992 - null - [null, null, null, null, null] +13993 - null - [Take-from, null, null, null, null] +13994 - Weapon rack - [Take-from, null, null, null, null] +13995 - Weapon rack - [Take-from, null, null, null, null] +13996 - Weapon rack - [Take-from, null, null, null, null] +13997 - Weapon rack - [Take-from, null, null, null, null] +13998 - Weapon rack - [Take-from, null, null, null, null] +13999 - Rope - [Climb-up, null, null, null, null] +14000 - null - [Climb-down, null, null, null, null] +14001 - null - [Read, null, null, null, null] +14002 - Warning sign - [Read, null, null, null, null] +14003 - Grass - [null, null, null, null, null] +14004 - null - [hidden, null, null, null, null] +14005 - Pot-boiler - [null, null, null, null, null] +14006 - Pot-boiler - [null, null, null, null, null] +14007 - Pot-boiler - [Remove-Pot, null, null, null, null] +14008 - Pot-boiler - [null, null, null, null, null] +14009 - Pot-boiler - [Remove-Bone, null, null, null, null] +14010 - Wish-list - [Read, null, null, null, null] +14011 - Market stall - [null, Steal-From, null, null, null] +14012 - Market stall - [null, Steal-From, null, null, null] +14013 - Massive ribs - [null, null, null, null, null] +14014 - null - [null, null, null, null, null] +14015 - null - [null, null, null, null, null] +14016 - Box of bones - [null, null, null, null, null] +14017 - Box of bones - [null, null, null, null, null] +14018 - Bones - [null, null, null, null, null] +14019 - Bones - [null, null, null, null, null] +14020 - Bones - [null, null, null, null, null] +14021 - Bones - [null, null, null, null, null] +14022 - Bones - [null, null, null, null, null] +14023 - Bones - [null, null, null, null, null] +14024 - Bones - [null, null, null, null, null] +14025 - Bones - [null, null, null, null, null] +14026 - Bones - [null, null, null, null, null] +14027 - Bones - [null, null, null, null, null] +14028 - Bones - [null, null, null, null, null] +14029 - Bones - [null, null, null, null, null] +14030 - Bones - [null, null, null, null, null] +14031 - Bones - [null, null, null, null, null] +14032 - Bones - [null, null, null, null, null] +14033 - null - [null, null, null, null, null] +14034 - null - [null, null, null, null, null] +14035 - Fishing Contest Banner - [null, null, null, null, null] +14036 - null - [null, null, null, null, null] +14037 - null - [null, null, null, null, null] +14038 - null - [null, null, null, null, null] +14039 - null - [null, null, null, null, null] +14040 - Bonzo's Table - [null, null, null, null, null] +14041 - Bonzo's Table - [null, null, null, null, null] +14042 - null - [null, null, null, null, null] +14043 - Barrel - [null, null, null, null, null] +14044 - Table - [null, null, null, null, null] +14045 - Bed - [null, null, null, null, null] +14046 - null - [null, null, null, null, null] +14047 - null - [null, null, null, null, null] +14048 - null - [null, null, null, null, null] +14049 - Table - [null, null, null, null, null] +14050 - Chair - [null, null, null, null, null] +14051 - Small Table - [null, null, null, null, null] +14052 - null - [null, null, null, null, null] +14053 - null - [null, null, null, null, null] +14054 - null - [null, null, null, null, null] +14055 - null - [null, null, null, null, null] +14056 - null - [null, null, null, null, null] +14057 - null - [null, null, null, null, null] +14058 - Fairy ring - [Use, null, null, null, null] +14059 - null - [null, null, null, null, null] +14060 - null - [null, null, null, null, null] +14061 - Fairy ring - [Use, null, null, null, null] +14062 - null - [null, null, null, null, null] +14063 - null - [null, null, null, null, null] +14064 - Fairy ring - [Use, null, null, null, null] +14065 - null - [null, null, null, null, null] +14066 - null - [null, null, null, null, null] +14067 - Fairy ring - [Use, null, null, null, null] +14068 - null - [null, null, null, null, null] +14069 - null - [null, null, null, null, null] +14070 - Fairy ring - [Use, null, null, null, null] +14071 - null - [null, null, null, null, null] +14072 - null - [null, null, null, null, null] +14073 - Fairy ring - [Use, null, null, null, null] +14074 - null - [null, null, null, null, null] +14075 - null - [null, null, null, null, null] +14076 - Fairy ring - [Use, null, null, null, null] +14077 - null - [null, null, null, null, null] +14078 - null - [null, null, null, null, null] +14079 - Fairy ring - [Use, null, null, null, null] +14080 - null - [null, null, null, null, null] +14081 - null - [null, null, null, null, null] +14082 - Fairy ring - [Use, null, null, null, null] +14083 - null - [null, null, null, null, null] +14084 - null - [null, null, null, null, null] +14085 - Fairy ring - [Use, null, null, null, null] +14086 - null - [null, null, null, null, null] +14087 - null - [null, null, null, null, null] +14088 - Fairy ring - [Use, null, null, null, null] +14089 - null - [null, null, null, null, null] +14090 - null - [null, null, null, null, null] +14091 - Fairy ring - [Use, null, null, null, null] +14092 - null - [null, null, null, null, null] +14093 - null - [null, null, null, null, null] +14094 - Fairy ring - [Use, null, null, null, null] +14095 - null - [null, null, null, null, null] +14096 - null - [null, null, null, null, null] +14097 - Fairy ring - [Use, null, null, null, null] +14098 - null - [null, null, null, null, null] +14099 - null - [null, null, null, null, null] +14100 - Fairy ring - [Use, null, null, null, null] +14101 - null - [null, null, null, null, null] +14102 - null - [null, null, null, null, null] +14103 - Fairy ring - [Use, null, null, null, null] +14104 - null - [null, null, null, null, null] +14105 - null - [null, null, null, null, null] +14106 - Fairy ring - [Use, null, null, null, null] +14107 - null - [null, null, null, null, null] +14108 - null - [null, null, null, null, null] +14109 - Fairy ring - [Use, null, null, null, null] +14110 - null - [null, null, null, null, null] +14111 - null - [null, null, null, null, null] +14112 - Fairy ring - [Use, null, null, null, null] +14113 - null - [null, null, null, null, null] +14114 - null - [null, null, null, null, null] +14115 - Fairy ring - [Use, null, null, null, null] +14116 - null - [null, null, null, null, null] +14117 - null - [null, null, null, null, null] +14118 - Fairy ring - [Use, null, null, null, null] +14119 - null - [null, null, null, null, null] +14120 - null - [null, null, null, null, null] +14121 - Fairy ring - [Use, null, null, null, null] +14122 - null - [null, null, null, null, null] +14123 - null - [null, null, null, null, null] +14124 - Fairy ring - [Use, null, null, null, null] +14125 - null - [null, null, null, null, null] +14126 - null - [null, null, null, null, null] +14127 - Fairy ring - [Use, null, null, null, null] +14128 - null - [null, null, null, null, null] +14129 - null - [null, null, null, null, null] +14130 - Fairy ring - [Use, null, null, null, null] +14131 - null - [null, null, null, null, null] +14132 - null - [null, null, null, null, null] +14133 - Fairy ring - [Use, null, null, null, null] +14134 - null - [null, null, null, null, null] +14135 - null - [null, null, null, null, null] +14136 - Fairy ring - [Use, null, null, null, null] +14137 - null - [null, null, null, null, null] +14138 - null - [null, null, null, null, null] +14139 - Fairy ring - [Use, null, null, null, null] +14140 - null - [null, null, null, null, null] +14141 - null - [null, null, null, null, null] +14142 - Fairy ring - [Use, null, null, null, null] +14143 - null - [null, null, null, null, null] +14144 - null - [null, null, null, null, null] +14145 - Fairy ring - [Use, null, null, null, null] +14146 - null - [null, null, null, null, null] +14147 - null - [null, null, null, null, null] +14148 - Fairy ring - [Use, null, null, null, null] +14149 - null - [null, null, null, null, null] +14150 - null - [null, null, null, null, null] +14151 - Fairy ring - [Use, null, null, null, null] +14152 - null - [null, null, null, null, null] +14153 - null - [null, null, null, null, null] +14154 - Fairy ring - [Use, null, null, null, null] +14155 - null - [null, null, null, null, null] +14156 - null - [null, null, null, null, null] +14157 - Fairy ring - [Use, null, null, null, null] +14158 - null - [null, null, null, null, null] +14159 - null - [null, null, null, null, null] +14160 - Fairy ring - [Use, null, null, null, null] +14161 - null - [null, null, null, null, null] +14162 - null - [null, null, null, null, null] +14163 - Table - [null, null, null, null, null] +14164 - null - [null, null, null, null, null] +14165 - null - [null, null, null, null, null] +14166 - null - [null, null, null, null, null] +14167 - null - [null, null, null, null, null] +14168 - Easter bird perch. - [null, null, null, null, null] +14169 - Fire - [null, null, null, null, null] +14170 - null - [Use-Logs, null, null, null, null] +14171 - Embers - [Use-Driftwood, null, null, null, null] +14172 - null - [null, null, null, null, null] +14173 - Olaf's boat - [null, null, null, null, null] +14174 - Driftwood - [null, null, null, null, null] +14175 - Chute - [Enter, null, null, null, null] +14176 - null - [null, null, null, null, null] +14177 - null - [null, null, null, null, null] +14178 - Chute - [Climb Down, null, null, null, null] +14179 - Light - [Jump-out, null, null, null, null] +14180 - null - [null, null, null, null, null] +14181 - null - [null, null, null, null, null] +14182 - null - [null, null, null, null, null] +14183 - null - [null, null, null, null, null] +14184 - null - [null, null, null, null, null] +14185 - null - [null, null, null, null, null] +14186 - null - [null, null, null, null, null] +14187 - null - [null, null, null, null, null] +14188 - null - [null, null, null, null, null] +14189 - null - [null, null, null, null, null] +14190 - null - [null, null, null, null, null] +14191 - null - [null, null, null, null, null] +14192 - null - [null, null, null, null, null] +14193 - null - [null, null, null, null, null] +14194 - null - [null, null, null, null, null] +14195 - null - [null, null, null, null, null] +14196 - Chest - [null, null, null, null, null] +14197 - Chest - [Open, null, null, null, null] +14198 - null - [null, null, null, null, null] +14199 - null - [null, null, null, null, null] +14200 - null - [null, null, null, null, null] +14201 - null - [null, null, null, null, null] +14202 - null - [null, null, null, null, null] +14203 - Hole - [null, null, null, null, null] +14204 - Mound - [null, null, null, null, null] +14205 - Mound - [null, null, null, null, null] +14206 - Mound - [null, null, null, null, null] +14207 - Mound - [null, null, null, null, null] +14208 - Mound - [null, null, null, null, null] +14209 - Mound - [null, null, null, null, null] +14210 - null - [null, null, null, null, null] +14211 - null - [null, null, null, null, null] +14212 - Wall - [null, null, null, null, null] +14213 - Wall - [null, null, null, null, null] +14214 - null - [null, null, null, null, null] +14215 - null - [null, null, null, null, null] +14216 - Wall - [null, hidden, Repair, null, null] +14217 - Wall - [null, hidden, Repair, null, null] +14218 - Wall - [null, hidden, Repair, null, null] +14219 - Wall - [null, hidden, Repair, null, null] +14220 - Wall - [null, null, Repair, null, null] +14221 - Wall - [null, null, Repair, null, null] +14222 - null - [null, null, null, null, null] +14223 - null - [null, null, null, null, null] +14224 - Barricade - [null, hidden, null, null, null] +14225 - Barricade - [null, hidden, null, null, null] +14226 - Barricade - [null, hidden, null, null, null] +14227 - Barricade - [null, hidden, Repair, null, null] +14228 - Barricade - [null, hidden, Repair, null, null] +14229 - Barricade - [null, hidden, Repair, null, null] +14230 - Barricade - [null, null, Repair, null, null] +14231 - Barricade - [null, null, Repair, null, null] +14232 - Barricade - [null, null, Repair, null, null] +14233 - Gate - [Open, hidden, null, null, null] +14234 - Gate - [Close, hidden, null, null, null] +14235 - Gate - [Open, hidden, null, null, null] +14236 - Gate - [Close, hidden, null, null, null] +14237 - Gate - [Open, hidden, Repair, null, null] +14238 - Gate - [Close, hidden, Repair, null, null] +14239 - Gate - [Open, hidden, Repair, null, null] +14240 - Gate - [Close, hidden, Repair, null, null] +14241 - Gate - [Open, hidden, Repair, null, null] +14242 - Gate - [Close, hidden, Repair, null, null] +14243 - Gate - [Open, hidden, Repair, null, null] +14244 - Gate - [Close, hidden, Repair, null, null] +14245 - Gate - [Open, null, Repair, null, null] +14246 - Gate - [Close, null, Repair, null, null] +14247 - Gate - [Open, null, Repair, null, null] +14248 - Gate - [Close, null, Repair, null, null] +14249 - null - [null, null, null, null, null] +14250 - null - [null, null, null, null, null] +14251 - null - [null, null, null, null, null] +14252 - null - [null, null, null, null, null] +14253 - null - [null, null, null, null, null] +14254 - null - [null, null, null, null, null] +14255 - null - [null, null, null, null, null] +14256 - null - [null, null, null, null, null] +14257 - null - [null, null, null, null, null] +14258 - Lander boat - [null, null, null, null, null] +14259 - Lander boat - [null, null, null, null, null] +14260 - Lander boat - [null, null, null, null, null] +14261 - Lander boat - [null, null, null, null, null] +14262 - Lander boat - [null, null, null, null, null] +14263 - Lander boat - [null, null, null, null, null] +14264 - Lander boat - [null, null, null, null, null] +14265 - Lander boat - [null, null, null, null, null] +14266 - Lander boat - [null, null, null, null, null] +14267 - Lander boat - [null, null, null, null, null] +14268 - Lander boat - [null, null, null, null, null] +14269 - Lander hatch - [null, null, null, null, null] +14270 - null - [null, null, null, null, null] +14271 - null - [null, null, null, null, null] +14272 - null - [null, null, null, null, null] +14273 - null - [null, null, null, null, null] +14274 - null - [null, null, null, null, null] +14275 - null - [null, null, null, null, null] +14276 - null - [null, null, null, null, null] +14277 - null - [null, null, null, null, null] +14278 - null - [null, null, null, null, null] +14279 - null - [null, null, null, null, null] +14280 - null - [null, null, null, null, null] +14281 - null - [null, null, null, null, null] +14282 - null - [null, null, null, null, null] +14283 - Banner - [null, null, null, null, null] +14284 - null - [null, null, null, null, null] +14285 - null - [null, null, null, null, null] +14286 - null - [null, null, null, null, null] +14287 - null - [null, null, null, null, null] +14288 - null - [null, null, null, null, null] +14289 - null - [null, null, null, null, null] +14290 - null - [null, null, null, null, null] +14291 - null - [null, null, null, null, null] +14292 - null - [null, null, null, null, null] +14293 - null - [null, null, null, null, null] +14294 - null - [null, null, null, null, null] +14295 - null - [null, null, null, null, null] +14296 - Ladder - [Climb, null, null, null, null] +14297 - null - [null, null, null, null, null] +14298 - null - [null, null, null, null, null] +14299 - null - [null, null, null, null, null] +14300 - null - [null, null, null, null, null] +14301 - null - [null, null, null, null, null] +14302 - null - [null, null, null, null, null] +14303 - null - [null, null, null, null, null] +14304 - Gangplank - [Cross, null, null, null, null] +14305 - Gangplank - [Cross, null, null, null, null] +14306 - Gangplank - [Cross, null, null, null, null] +14307 - Gangplank - [Cross, null, null, null, null] +14308 - Tree - [Chop down, null, hidden, null, null] +14309 - Tree - [Chop down, null, hidden, null, null] +14310 - null - [null, null, null, null, null] +14311 - null - [null, null, null, null, null] +14312 - null - [null, null, null, null, null] +14313 - null - [null, null, null, null, null] +14314 - Ladder - [Climb, null, null, null, null] +14315 - Gangplank - [Cross, null, null, null, null] +14316 - null - [null, null, null, null, null] +14317 - null - [null, null, null, null, null] +14318 - null - [null, null, null, null, null] +14319 - null - [null, null, null, null, null] +14320 - null - [null, null, null, null, null] +14321 - null - [null, null, null, null, null] +14322 - null - [null, null, null, null, null] +14323 - null - [null, null, null, null, null] +14324 - null - [null, null, null, null, null] +14325 - null - [null, null, null, null, null] +14326 - null - [null, null, null, null, null] +14327 - null - [null, null, null, null, null] +14328 - null - [null, null, null, null, null] +14329 - null - [null, null, null, null, null] +14330 - null - [null, null, null, null, null] +14331 - null - [null, null, null, null, null] +14332 - null - [null, null, null, null, null] +14333 - null - [null, null, null, null, null] +14334 - null - [null, null, null, null, null] +14335 - Bones - [null, null, null, null, null] +14336 - null - [null, null, null, null, null] +14337 - null - [null, null, null, null, null] +14338 - null - [null, null, null, null, null] +14339 - null - [null, null, null, null, null] +14340 - null - [null, null, null, null, null] +14341 - null - [null, null, null, null, null] +14342 - null - [null, null, null, null, null] +14343 - null - [null, null, null, null, null] +14344 - null - [null, null, null, null, null] +14345 - null - [null, null, null, null, null] +14346 - null - [null, null, null, null, null] +14347 - null - [null, null, null, null, null] +14348 - null - [null, null, null, null, null] +14349 - null - [null, null, null, null, null] +14350 - null - [null, null, null, null, null] +14351 - null - [null, null, null, null, null] +14352 - null - [null, null, null, null, null] +14353 - null - [null, null, null, null, null] +14354 - null - [null, null, null, null, null] +14355 - Pile of bricks - [null, null, null, null, null] +14356 - Shelves - [null, null, null, null, null] +14357 - Shelves - [null, null, null, null, null] +14358 - Shelves - [null, null, null, null, null] +14359 - Shelves - [null, null, null, null, null] +14360 - Cauldron - [null, null, null, null, null] +14361 - null - [null, null, null, null, null] +14362 - Charms - [null, null, null, null, null] +14363 - Table - [null, null, null, null, null] +14364 - Rocking chair - [null, null, null, null, null] +14365 - null - [null, null, null, null, null] +14366 - Counter - [null, null, null, null, null] +14367 - Bank booth - [Use, Use-quickly, Collect, null, null] +14368 - Bank booth - [null, null, null, null, null] +14369 - Crate - [null, null, null, null, null] +14370 - Crates - [null, null, null, null, null] +14371 - Boxes - [null, null, null, null, null] +14372 - Crates - [null, null, null, null, null] +14373 - Blacksmith's tools - [null, null, null, null, null] +14374 - Barrel - [null, null, null, null, null] +14375 - Shelves - [null, null, null, null, null] +14376 - Shelves - [null, null, null, null, null] +14377 - Shelves - [null, null, null, null, null] +14378 - Shelves - [null, null, null, null, null] +14379 - Shelves - [null, null, null, null, null] +14380 - null - [null, null, null, null, null] +14381 - Stool - [null, null, null, null, null] +14382 - Bank chest - [null, null, null, null, null] +14383 - null - [null, null, null, null, null] +14384 - null - [null, null, null, null, null] +14385 - null - [null, null, null, null, null] +14386 - null - [null, null, null, null, null] +14387 - null - [null, null, null, null, null] +14388 - null - [null, null, null, null, null] +14389 - null - [null, null, null, null, null] +14390 - null - [null, null, null, null, null] +14391 - null - [null, null, null, null, null] +14392 - null - [null, null, null, null, null] +14393 - null - [null, null, null, null, null] +14394 - null - [null, null, null, null, null] +14395 - null - [null, null, null, null, null] +14396 - null - [null, null, null, null, null] +14397 - null - [null, null, null, null, null] +14398 - null - [null, null, null, null, null] +14399 - null - [null, null, null, null, null] +14400 - null - [null, null, null, null, null] +14401 - null - [null, null, null, null, null] +14402 - null - [null, null, null, null, null] +14403 - null - [null, null, null, null, null] +14404 - null - [null, null, null, null, null] +14405 - null - [null, null, null, null, null] +14406 - null - [null, null, null, null, null] +14407 - null - [null, null, null, null, null] +14408 - null - [null, null, null, null, null] +14409 - null - [null, null, null, null, null] +14410 - null - [null, null, null, null, null] +14411 - null - [null, null, null, null, null] +14412 - null - [null, null, null, null, null] +14413 - null - [null, null, null, null, null] +14414 - null - [null, null, null, null, null] +14415 - Study desk - [null, null, null, null, null] +14416 - null - [null, null, null, null, null] +14417 - null - [null, null, null, null, null] +14418 - null - [null, null, null, null, null] +14419 - null - [null, null, null, null, null] +14420 - null - [null, null, null, null, null] +14421 - null - [null, null, null, null, null] +14422 - null - [null, null, null, null, null] +14423 - null - [null, null, null, null, null] +14424 - null - [null, null, null, null, null] +14425 - null - [null, null, null, null, null] +14426 - null - [null, null, null, null, null] +14427 - null - [null, null, null, null, null] +14428 - Fishing spot - [Bait, null, hidden, null, null] +14429 - null - [null, null, null, null, null] +14430 - null - [null, null, null, null, null] +14431 - Rift - [null, null, null, null, null] +14432 - null - [null, null, null, null, null] +14433 - null - [null, null, null, null, null] +14434 - Gas bubble - [null, null, null, null, null] +14435 - null - [null, null, null, null, null] +14436 - Cave entrance - [null, null, null, null, null] +14437 - null - [null, null, null, null, null] +14438 - null - [null, null, null, null, null] +14439 - null - [null, null, null, null, null] +14440 - null - [null, null, null, null, null] +14441 - null - [null, null, null, null, null] +14442 - null - [null, null, null, null, null] +14443 - Mushroom - [null, null, null, null, null] +14444 - Mushroom - [null, null, null, null, null] +14445 - Mushroom - [null, null, null, null, null] +14446 - Mushroom - [null, null, null, null, null] +14447 - Mushroom - [null, null, null, null, null] +14448 - Mushroom - [null, null, null, null, null] +14449 - Mushroom - [null, null, null, null, null] +14450 - null - [null, null, null, null, null] +14451 - null - [null, null, null, null, null] +14452 - null - [null, null, null, null, null] +14453 - null - [null, null, null, null, null] +14454 - null - [null, null, null, null, null] +14455 - null - [null, null, null, null, null] +14456 - null - [null, null, null, null, null] +14457 - null - [null, null, null, null, null] +14458 - null - [null, null, null, null, null] +14459 - null - [null, null, null, null, null] +14460 - null - [null, null, null, null, null] +14461 - null - [null, null, null, null, null] +14462 - null - [null, null, null, null, null] +14463 - null - [null, null, null, null, null] +14464 - null - [null, null, null, null, null] +14465 - null - [null, null, null, null, null] +14466 - null - [null, null, null, null, null] +14467 - null - [null, null, null, null, null] +14468 - null - [null, null, null, null, null] +14469 - null - [null, null, null, null, null] +14470 - null - [null, null, null, null, null] +14471 - null - [null, null, null, null, null] +14472 - Skeleton - [null, null, null, null, null] +14473 - Cage - [null, null, null, null, null] +14474 - Cage - [null, null, null, null, null] +14475 - Skeleton - [null, null, null, null, null] +14476 - Skeleton - [null, null, null, null, null] +14477 - Skeleton - [null, null, null, null, null] +14478 - Skeleton - [null, null, null, null, null] +14479 - Stocks - [null, null, null, null, null] +14480 - Skeleton - [null, null, null, null, null] +14481 - Skeleton - [null, null, null, null, null] +14482 - null - [null, null, null, null, null] +14483 - null - [null, null, null, null, null] +14484 - null - [null, null, null, null, null] +14485 - null - [null, null, null, null, null] +14486 - null - [null, null, null, null, null] +14487 - null - [null, null, null, null, null] +14488 - null - [null, null, null, null, null] +14489 - null - [null, null, null, null, null] +14490 - null - [null, null, null, null, null] +14491 - null - [null, null, null, null, null] +14492 - null - [null, null, null, null, null] +14493 - null - [null, null, null, null, null] +14494 - null - [null, null, null, null, null] +14495 - null - [null, null, null, null, null] +14496 - null - [null, null, null, null, null] +14497 - null - [null, null, null, null, null] +14498 - null - [null, null, null, null, null] +14499 - null - [null, null, null, null, null] +14500 - null - [null, null, null, null, null] +14501 - null - [null, null, null, null, null] +14502 - null - [null, null, null, null, null] +14503 - Wilderness Sign - [null, null, null, null, null] +14504 - Wilderness Sign - [null, null, null, null, null] +14505 - Wilderness Sign - [null, null, null, null, null] +14506 - Wilderness Sign - [null, null, null, null, null] +14507 - Wilderness Sign - [null, null, null, null, null] +14508 - null - [null, null, null, null, null] +14509 - null - [null, null, null, null, null] +14510 - null - [null, null, null, null, null] +14511 - null - [null, null, null, null, null] +14512 - null - [null, null, null, null, null] +14513 - Tree - [null, null, null, null, null] +14514 - Tree - [null, null, null, null, null] +14515 - Tree - [null, null, null, null, null] +14516 - Tree stump - [null, null, null, null, null] +14517 - Tree Stump - [null, null, null, null, null] +14518 - Roots - [null, null, null, null, null] +14519 - Roots - [null, null, null, null, null] +14520 - Roots - [null, null, null, null, null] +14521 - Tree - [null, null, null, null, null] +14522 - null - [null, null, null, null, null] +14523 - Skeleton - [null, null, null, null, null] +14524 - Skeleton - [null, null, null, null, null] +14525 - Skeleton - [null, null, null, null, null] +14526 - Bones - [null, null, null, null, null] +14527 - Bones - [null, null, null, null, null] +14528 - Bones - [null, null, null, null, null] +14529 - Bones - [null, null, null, null, null] +14530 - Bones - [null, null, null, null, null] +14531 - Bones - [null, null, null, null, null] +14532 - Bones - [null, null, null, null, null] +14533 - Bones - [null, null, null, null, null] +14534 - Bones - [null, null, null, null, null] +14535 - Bones - [null, null, null, null, null] +14536 - Bones - [null, null, null, null, null] +14537 - Bones - [null, null, null, null, null] +14538 - Mushroom - [null, null, null, null, null] +14539 - Mushroom - [null, null, null, null, null] +14540 - Mushroom - [null, null, null, null, null] +14541 - Mushroom - [null, null, null, null, null] +14542 - Mushroom - [null, null, null, null, null] +14543 - null - [null, null, null, null, null] +14544 - null - [null, null, null, null, null] +14545 - null - [null, null, null, null, null] +14546 - null - [null, null, null, null, null] +14547 - null - [null, null, null, null, null] +14548 - null - [null, null, null, null, null] +14549 - null - [null, null, null, null, null] +14550 - null - [null, null, null, null, null] +14551 - null - [null, null, null, null, null] +14552 - null - [null, null, null, null, null] +14553 - null - [null, null, null, null, null] +14554 - null - [null, null, null, null, null] +14555 - null - [null, null, null, null, null] +14556 - Stone Pile - [null, null, null, null, null] +14557 - Stone Pile - [null, null, null, null, null] +14558 - null - [null, null, null, null, null] +14559 - null - [null, null, null, null, null] +14560 - null - [null, null, null, null, null] +14561 - null - [null, null, null, null, null] +14562 - null - [null, null, null, null, null] +14563 - null - [null, null, null, null, null] +14564 - Tree - [null, null, null, null, null] +14565 - Tree - [null, null, null, null, null] +14566 - Tree - [null, null, null, null, null] +14567 - Tree Stump - [null, null, null, null, null] +14568 - Roots - [null, null, null, null, null] +14569 - Roots - [null, null, null, null, null] +14570 - Roots - [null, null, null, null, null] +14571 - Tree - [null, null, null, null, null] +14572 - null - [null, null, null, null, null] +14573 - Skeleton - [null, null, null, null, null] +14574 - Skeleton - [null, null, null, null, null] +14575 - Skeleton - [null, null, null, null, null] +14576 - Bones - [null, null, null, null, null] +14577 - Bones - [null, null, null, null, null] +14578 - Bones - [null, null, null, null, null] +14579 - Bones - [null, null, null, null, null] +14580 - Bones - [null, null, null, null, null] +14581 - Bones - [null, null, null, null, null] +14582 - Bones - [null, null, null, null, null] +14583 - Bones - [null, null, null, null, null] +14584 - Bones - [null, null, null, null, null] +14585 - Bones - [null, null, null, null, null] +14586 - Bones - [null, null, null, null, null] +14587 - Bones - [null, null, null, null, null] +14588 - Mushroom - [null, null, null, null, null] +14589 - Mushroom - [null, null, null, null, null] +14590 - Mushroom - [null, null, null, null, null] +14591 - Mushroom - [null, null, null, null, null] +14592 - Mushroom - [null, null, null, null, null] +14593 - Tree - [null, null, null, null, null] +14594 - Tree - [null, null, null, null, null] +14595 - Tree - [null, null, null, null, null] +14596 - Tree Stump - [null, null, null, null, null] +14597 - Roots - [null, null, null, null, null] +14598 - Roots - [null, null, null, null, null] +14599 - Roots - [null, null, null, null, null] +14600 - Tree - [null, null, null, null, null] +14601 - null - [null, null, null, null, null] +14602 - Skeleton - [null, null, null, null, null] +14603 - Skeleton - [null, null, null, null, null] +14604 - Skeleton - [null, null, null, null, null] +14605 - Bones - [null, null, null, null, null] +14606 - Bones - [null, null, null, null, null] +14607 - Bones - [null, null, null, null, null] +14608 - Bones - [null, null, null, null, null] +14609 - Bones - [null, null, null, null, null] +14610 - Bones - [null, null, null, null, null] +14611 - Bones - [null, null, null, null, null] +14612 - Bones - [null, null, null, null, null] +14613 - Bones - [null, null, null, null, null] +14614 - Bones - [null, null, null, null, null] +14615 - Bones - [null, null, null, null, null] +14616 - Bones - [null, null, null, null, null] +14617 - Mushroom - [null, null, null, null, null] +14618 - Mushroom - [null, null, null, null, null] +14619 - Mushroom - [null, null, null, null, null] +14620 - Mushroom - [null, null, null, null, null] +14621 - Mushroom - [null, null, null, null, null] +14622 - null - [null, null, null, null, null] +14623 - null - [null, null, null, null, null] +14624 - null - [null, null, null, null, null] +14625 - null - [null, null, null, null, null] +14626 - null - [null, null, null, null, null] +14627 - null - [null, null, null, null, null] +14628 - null - [null, null, null, null, null] +14629 - null - [null, null, null, null, null] +14630 - Stone Pile - [null, null, null, null, null] +14631 - Stone Pile - [null, null, null, null, null] +14632 - null - [null, null, null, null, null] +14633 - null - [null, null, null, null, null] +14634 - null - [null, null, null, null, null] +14635 - Tree - [null, null, null, null, null] +14636 - Tree - [null, null, null, null, null] +14637 - Tree - [null, null, null, null, null] +14638 - Tree Stump - [null, null, null, null, null] +14639 - Roots - [null, null, null, null, null] +14640 - Roots - [null, null, null, null, null] +14641 - Roots - [null, null, null, null, null] +14642 - Tree - [null, null, null, null, null] +14643 - null - [null, null, null, null, null] +14644 - Skeleton - [null, null, null, null, null] +14645 - Skeleton - [null, null, null, null, null] +14646 - Skeleton - [null, null, null, null, null] +14647 - Bones - [null, null, null, null, null] +14648 - Bones - [null, null, null, null, null] +14649 - Bones - [null, null, null, null, null] +14650 - Bones - [null, null, null, null, null] +14651 - Bones - [null, null, null, null, null] +14652 - Bones - [null, null, null, null, null] +14653 - Bones - [null, null, null, null, null] +14654 - Bones - [null, null, null, null, null] +14655 - Bones - [null, null, null, null, null] +14656 - Bones - [null, null, null, null, null] +14657 - Bones - [null, null, null, null, null] +14658 - Bones - [null, null, null, null, null] +14659 - Mushroom - [null, null, null, null, null] +14660 - Mushroom - [null, null, null, null, null] +14661 - Mushroom - [null, null, null, null, null] +14662 - Mushroom - [null, null, null, null, null] +14663 - Mushroom - [null, null, null, null, null] +14664 - Tree - [null, null, null, null, null] +14665 - Tree - [null, null, null, null, null] +14666 - Tree - [null, null, null, null, null] +14667 - Tree Stump - [null, null, null, null, null] +14668 - Roots - [null, null, null, null, null] +14669 - Roots - [null, null, null, null, null] +14670 - Roots - [null, null, null, null, null] +14671 - Tree - [null, null, null, null, null] +14672 - null - [null, null, null, null, null] +14673 - Skeleton - [null, null, null, null, null] +14674 - Skeleton - [null, null, null, null, null] +14675 - Skeleton - [null, null, null, null, null] +14676 - Bones - [null, null, null, null, null] +14677 - Bones - [null, null, null, null, null] +14678 - Bones - [null, null, null, null, null] +14679 - Bones - [null, null, null, null, null] +14680 - Bones - [null, null, null, null, null] +14681 - Bones - [null, null, null, null, null] +14682 - Bones - [null, null, null, null, null] +14683 - Bones - [null, null, null, null, null] +14684 - Bones - [null, null, null, null, null] +14685 - Bones - [null, null, null, null, null] +14686 - Bones - [null, null, null, null, null] +14687 - Bones - [null, null, null, null, null] +14688 - Mushroom - [null, null, null, null, null] +14689 - Mushroom - [null, null, null, null, null] +14690 - Mushroom - [null, null, null, null, null] +14691 - Mushroom - [null, null, null, null, null] +14692 - Mushroom - [null, null, null, null, null] +14693 - Tree - [null, null, null, null, null] +14694 - Tree - [null, null, null, null, null] +14695 - Tree - [null, null, null, null, null] +14696 - Tree - [null, null, null, null, null] +14697 - Tree Stump - [null, null, null, null, null] +14698 - Roots - [null, null, null, null, null] +14699 - Roots - [null, null, null, null, null] +14700 - Roots - [null, null, null, null, null] +14701 - Tree - [null, null, null, null, null] +14702 - null - [null, null, null, null, null] +14703 - Skeleton - [null, null, null, null, null] +14704 - Skeleton - [null, null, null, null, null] +14705 - Skeleton - [null, null, null, null, null] +14706 - Bones - [null, null, null, null, null] +14707 - Bones - [null, null, null, null, null] +14708 - Bones - [null, null, null, null, null] +14709 - Bones - [null, null, null, null, null] +14710 - Bones - [null, null, null, null, null] +14711 - Bones - [null, null, null, null, null] +14712 - Bones - [null, null, null, null, null] +14713 - Bones - [null, null, null, null, null] +14714 - Bones - [null, null, null, null, null] +14715 - Bones - [null, null, null, null, null] +14716 - Bones - [null, null, null, null, null] +14717 - Bones - [null, null, null, null, null] +14718 - Mushroom - [null, null, null, null, null] +14719 - Mushroom - [null, null, null, null, null] +14720 - Mushroom - [null, null, null, null, null] +14721 - Mushroom - [null, null, null, null, null] +14722 - Mushroom - [null, null, null, null, null] +14723 - null - [null, null, null, null, null] +14724 - null - [null, null, null, null, null] +14725 - null - [null, null, null, null, null] +14726 - null - [null, null, null, null, null] +14727 - null - [null, null, null, null, null] +14728 - null - [null, null, null, null, null] +14729 - null - [null, null, null, null, null] +14730 - null - [null, null, null, null, null] +14731 - Stone Pile - [null, null, null, null, null] +14732 - Stone Pile - [null, null, null, null, null] +14733 - null - [null, null, null, null, null] +14734 - null - [null, null, null, null, null] +14735 - Staircase - [Climb-up, null, null, null, null] +14736 - Staircase - [Climb, Climb-up, Climb-down, null, null] +14737 - Staircase - [Climb-down, null, null, null, null] +14738 - Tree - [null, null, null, null, null] +14739 - Crate - [null, null, null, null, null] +14740 - Barrel - [null, null, null, null, null] +14741 - Crates - [null, null, null, null, null] +14742 - Pile of Crates - [Search, null, null, null, null] +14743 - Sack - [Search, null, null, null, null] +14744 - null - [null, null, null, null, null] +14745 - Ladder - [Climb-up, null, null, null, null] +14746 - Ladder - [Climb-down, null, null, null, null] +14747 - Ladder - [Climb, Climb-up, Climb-down, null, null] +14748 - Ladder - [null, null, null, null, null] +14749 - Door - [Open, null, null, null, null] +14750 - Door - [Close, null, null, null, null] +14751 - Door - [Open, null, null, null, null] +14752 - Door - [Open, null, null, null, null] +14753 - Door - [Close, null, null, null, null] +14754 - Door - [Close, null, null, null, null] +14755 - Banner - [null, null, null, null, null] +14756 - Banner - [null, null, null, null, null] +14757 - Banner - [null, null, null, null, null] +14758 - Ladder - [Climb-down, null, null, null, null] +14759 - Roots - [null, null, null, null, null] +14760 - Roots - [null, null, null, null, null] +14761 - Roots - [null, null, null, null, null] +14762 - Table - [null, null, null, null, null] +14763 - Table - [null, null, null, null, null] +14764 - Stool - [null, null, null, null, null] +14765 - Gravestone - [null, null, null, null, null] +14766 - Gravestone - [null, null, null, null, null] +14767 - Gravestone - [null, null, null, null, null] +14768 - Gravestone - [null, null, null, null, null] +14769 - Gravestone - [null, null, null, null, null] +14770 - null - [null, null, null, null, null] +14771 - Bed - [null, null, null, null, null] +14772 - Bed - [null, null, null, null, null] +14773 - Chest - [Open, null, null, null, null] +14774 - Chest - [Search, Close, null, null, null] +14775 - null - [null, null, null, null, null] +14776 - null - [null, null, null, null, null] +14777 - null - [null, null, null, null, null] +14778 - null - [null, null, null, null, null] +14779 - null - [null, null, null, null, null] +14780 - null - [null, null, null, null, null] +14781 - null - [null, null, null, null, null] +14782 - null - [null, null, null, null, null] +14783 - null - [null, null, null, null, null] +14784 - null - [null, null, null, null, null] +14785 - null - [null, null, null, null, null] +14786 - null - [null, null, null, null, null] +14787 - null - [null, null, null, null, null] +14788 - null - [null, null, null, null, null] +14789 - null - [null, null, null, null, null] +14790 - null - [null, null, null, null, null] +14791 - null - [null, null, null, null, null] +14792 - null - [null, null, null, null, null] +14793 - null - [null, null, null, null, null] +14794 - null - [null, null, null, null, null] +14795 - null - [null, null, null, null, null] +14796 - Tree - [null, null, null, null, null] +14797 - Tree - [null, null, null, null, null] +14798 - Tree - [null, null, null, null, null] +14799 - Tree - [null, null, null, null, null] +14800 - Tree - [null, null, null, null, null] +14801 - Tree - [null, null, null, null, null] +14802 - Tree - [null, null, null, null, null] +14803 - Tree - [null, null, null, null, null] +14804 - Tree - [null, null, null, null, null] +14805 - Tree - [null, null, null, null, null] +14806 - Tree - [null, null, null, null, null] +14807 - Tree - [null, null, null, null, null] +14808 - Creeper - [null, null, null, null, null] +14809 - Creeper - [null, null, null, null, null] +14810 - Creeper - [null, null, null, null, null] +14811 - Creeper - [null, null, null, null, null] +14812 - Creeper - [null, null, null, null, null] +14813 - Creeper - [null, null, null, null, null] +14814 - Rock - [null, null, null, null, null] +14815 - Rock - [null, null, null, null, null] +14816 - Rock - [null, null, null, null, null] +14817 - Rock - [null, null, null, null, null] +14818 - null - [null, null, null, null, null] +14819 - null - [null, null, null, null, null] +14820 - null - [null, null, null, null, null] +14821 - null - [null, null, null, null, null] +14822 - null - [null, null, null, null, null] +14823 - null - [null, null, null, null, null] +14824 - null - [null, null, null, null, null] +14825 - Obelisk - [null, null, null, null, null] +14826 - Obelisk - [Activate, null, null, null, null] +14827 - Obelisk - [Activate, null, null, null, null] +14828 - Obelisk - [Activate, null, null, null, null] +14829 - Obelisk - [Activate, null, null, null, null] +14830 - Obelisk - [Activate, null, null, null, null] +14831 - Obelisk - [Activate, null, null, null, null] +14832 - Rocks - [Mine, Prospect, hidden, null, null] +14833 - Rocks - [Mine, Prospect, hidden, null, null] +14834 - Rocks - [Mine, Prospect, hidden, null, null] +14835 - Rocks - [Mine, Prospect, hidden, null, null] +14836 - Rocks - [Mine, Prospect, hidden, null, null] +14837 - Rocks - [Mine, Prospect, hidden, null, null] +14838 - Rocks - [Mine, Prospect, hidden, null, null] +14839 - Rocks - [Mine, Prospect, hidden, null, null] +14840 - Rocks - [Mine, Prospect, hidden, null, null] +14841 - Rocks - [Mine, Prospect, hidden, null, null] +14842 - Rocks - [Mine, Prospect, hidden, null, null] +14843 - Rocks - [Mine, Prospect, hidden, null, null] +14844 - Rocks - [Mine, Prospect, hidden, null, null] +14845 - Rocks - [Mine, Prospect, hidden, null, null] +14846 - Rocks - [Mine, Prospect, hidden, null, null] +14847 - Rocks - [Mine, Prospect, hidden, null, null] +14848 - Rocks - [Mine, Prospect, hidden, null, null] +14849 - Rocks - [Mine, Prospect, hidden, null, null] +14850 - Rocks - [Mine, Prospect, hidden, null, null] +14851 - Rocks - [Mine, Prospect, hidden, null, null] +14852 - Rocks - [Mine, Prospect, hidden, null, null] +14853 - Rocks - [Mine, Prospect, hidden, null, null] +14854 - Rocks - [Mine, Prospect, hidden, null, null] +14855 - Rocks - [Mine, Prospect, hidden, null, null] +14856 - Rocks - [Mine, Prospect, hidden, null, null] +14857 - Rocks - [Mine, Prospect, hidden, null, null] +14858 - Rocks - [Mine, Prospect, hidden, null, null] +14859 - Rocks - [Mine, Prospect, hidden, null, null] +14860 - Rocks - [Mine, Prospect, hidden, null, null] +14861 - Rocks - [Mine, Prospect, hidden, null, null] +14862 - Rocks - [Mine, Prospect, hidden, null, null] +14863 - Rocks - [Mine, Prospect, hidden, null, null] +14864 - Rocks - [Mine, Prospect, hidden, null, null] +14865 - Barrel - [null, null, null, null, null] +14866 - Barrel - [null, null, null, null, null] +14867 - Barrel - [null, null, null, null, null] +14868 - Sink - [null, null, null, null, null] +14869 - Shelves - [null, null, null, null, null] +14870 - null - [null, null, null, null, null] +14871 - null - [null, null, null, null, null] +14872 - Stool - [null, null, null, null, null] +14873 - Hanging meat - [null, null, null, null, null] +14874 - Hanging meat - [null, null, null, null, null] +14875 - null - [null, null, null, null, null] +14876 - null - [null, null, null, null, null] +14877 - null - [null, null, null, null, null] +14878 - null - [null, null, null, null, null] +14879 - Trapdoor - [Open, null, null, null, null] +14880 - Trapdoor - [Climb-down, null, null, null, null] +14881 - null - [null, null, null, null, null] +14882 - null - [null, null, null, null, null] +14883 - Rocks - [Mine, Prospect, hidden, null, null] +14884 - Rocks - [Mine, Prospect, hidden, null, null] +14885 - Rocks - [Mine, Prospect, hidden, null, null] +14886 - Rocks - [Mine, Prospect, hidden, null, null] +14887 - Rocks - [Mine, Prospect, hidden, null, null] +14888 - Rocks - [Mine, Prospect, hidden, null, null] +14889 - Rocks - [Mine, Prospect, hidden, null, null] +14890 - Rocks - [Mine, Prospect, hidden, null, null] +14891 - Bed - [null, null, null, null, null] +14892 - Rocks - [Mine, Prospect, hidden, null, null] +14893 - Rocks - [Mine, Prospect, hidden, null, null] +14894 - Rocks - [Mine, Prospect, hidden, null, null] +14895 - Rocks - [Mine, Prospect, hidden, null, null] +14896 - Rocks - [Mine, Prospect, hidden, null, null] +14897 - Rocks - [Mine, Prospect, hidden, null, null] +14898 - Rocks - [Mine, Prospect, hidden, null, null] +14899 - Rocks - [Mine, Prospect, hidden, null, null] +14900 - Rocks - [Mine, Prospect, hidden, null, null] +14901 - Rocks - [Mine, Prospect, hidden, null, null] +14902 - Rocks - [Mine, Prospect, hidden, null, null] +14903 - Rocks - [Mine, Prospect, hidden, null, null] +14904 - Rocks - [Mine, Prospect, hidden, null, null] +14905 - Rocks - [Mine, Prospect, hidden, null, null] +14906 - Rocks - [Mine, Prospect, hidden, null, null] +14907 - Rocks - [Mine, Prospect, hidden, null, null] +14908 - null - [null, null, null, null, null] +14909 - null - [null, null, null, null, null] +14910 - Bronze pickaxe - [Take, null, null, null, null] +14911 - null - [null, null, null, null, null] +14912 - Bronze axe - [Take, null, null, null, null] +14913 - Rocks - [Mine, Prospect, hidden, null, null] +14914 - Rocks - [Mine, Prospect, hidden, null, null] +14915 - Rocks - [Mine, Prospect, hidden, null, null] +14916 - Rocks - [Mine, Prospect, hidden, null, null] +14917 - Sink - [null, null, null, null, null] +14918 - Washbasin - [null, null, null, null, null] +14919 - Range - [null, null, null, null, null] +14920 - Table - [null, null, null, null, null] +14921 - Small furnace - [null, Smelt, null, null, null] +14922 - Hole - [Enter, null, null, null, null] +14923 - Door - [Open, null, null, null, null] +14924 - Door - [Close, null, null, null, null] +14925 - null - [null, null, null, null, null] +14926 - null - [null, null, null, null, null] +14927 - null - [null, null, null, null, null] +14928 - null - [null, null, null, null, null] +14929 - Colony gate - [Open, null, null, null, null] +14930 - null - [null, null, null, null, null] +14931 - Colony gate - [Open, null, null, null, null] +14932 - null - [null, null, null, null, null] +14933 - null - [null, null, null, null, null] +14934 - null - [null, null, null, null, null] +14935 - null - [null, null, null, null, null] +14936 - null - [null, null, null, null, null] +14937 - null - [null, null, null, null, null] +14938 - Fishing spot - [Net, null, hidden, null, null] +14939 - null - [null, null, null, null, null] +14940 - null - [null, null, null, null, null] +14941 - null - [null, null, null, null, null] +14942 - null - [null, null, null, null, null] +14943 - null - [null, null, null, null, null] +14944 - null - [null, null, null, null, null] +14945 - Broken wall - [null, null, null, null, null] +14946 - Broken wall - [null, null, null, null, null] +14947 - Broken wall - [null, null, null, null, null] +14948 - Patched wall - [null, null, null, null, null] +14949 - Patched wall - [null, null, null, null, null] +14950 - Patched wall - [null, null, null, null, null] +14951 - Cogs - [null, null, null, null, null] +14952 - Junk - [null, null, null, null, null] +14953 - Fishing weights - [null, null, null, null, null] +14954 - null - [null, null, null, null, null] +14955 - null - [null, null, null, null, null] +14956 - Metal Press - [null, null, null, null, null] +14957 - Metal Press - [null, null, null, null, null] +14958 - Firebox - [null, null, null, null, null] +14959 - Firebox - [null, null, null, null, null] +14960 - Firebox - [null, null, null, null, null] +14961 - Shelves - [null, null, null, null, null] +14962 - Crates - [null, null, null, null, null] +14963 - Crates - [null, null, null, null, null] +14964 - Barrel - [Take-from, null, null, null, null] +14965 - Large barrel - [null, null, null, null, null] +14966 - Rack of barrels - [null, null, null, null, null] +14967 - Large Barrel - [null, null, null, null, null] +14968 - Barrow - [null, null, null, null, null] +14969 - Barrow - [null, null, null, null, null] +14970 - Barrow - [null, null, null, null, null] +14971 - Herman's desk - [Search, null, null, null, null] +14972 - Net - [null, null, null, null, null] +14973 - Net - [Take-from, null, null, null, null] +14974 - null - [null, null, null, null, null] +14975 - null - [null, null, null, null, null] +14976 - Evil claw - [null, null, null, null, null] +14977 - null - [null, null, null, null, null] +14978 - Control panel - [Use, null, null, null, null] +14979 - null - [null, null, null, null, null] +14980 - null - [null, null, null, null, null] +14981 - null - [null, null, null, null, null] +14982 - Door - [Open, null, null, null, null] +14983 - null - [Close, null, null, null, null] +14984 - null - [null, null, null, null, null] +14985 - Crates - [null, null, null, null, null] +14986 - Crate - [null, null, null, null, null] +14987 - Crates - [null, null, null, null, null] +14988 - Cogs - [null, null, null, null, null] +14989 - Junk - [null, null, null, null, null] +14990 - Rack of barrels - [null, null, null, null, null] +14991 - Barrel - [null, null, null, null, null] +14992 - Barrow - [null, null, null, null, null] +14993 - null - [null, null, null, null, null] +14994 - null - [null, null, null, null, null] +14995 - null - [null, null, null, null, null] +14996 - null - [null, null, null, null, null] +14997 - null - [null, null, null, null, null] +14998 - Sack Pile - [null, null, null, null, null] +14999 - Sack Pile - [null, null, null, null, null] +15000 - Pinball Post - [Tag, null, null, null, null] +15001 - Pinball Post - [Tag, null, null, null, null] +15002 - Pinball Post - [Tag, null, null, null, null] +15003 - Pinball Post - [Tag, null, null, null, null] +15004 - Pinball Post - [Tag, null, null, null, null] +15005 - Pinball Post - [Tag, null, null, null, null] +15006 - Pinball Post - [Tag, null, null, null, null] +15007 - Pinball Post - [Tag, null, null, null, null] +15008 - Pinball Post - [Tag, null, null, null, null] +15009 - Pinball Post - [Tag, null, null, null, null] +15010 - Cave Exit - [Exit, null, null, null, null] +15011 - null - [null, null, null, null, null] +15012 - null - [null, null, null, null, null] +15013 - null - [null, null, null, null, null] +15014 - null - [null, null, null, null, null] +15015 - null - [null, null, null, null, null] +15016 - null - [null, null, null, null, null] +15017 - null - [null, null, null, null, null] +15018 - null - [null, null, null, null, null] +15019 - null - [null, null, null, null, null] +15020 - null - [null, null, null, null, null] +15021 - null - [null, null, null, null, null] +15022 - null - [null, null, null, null, null] +15023 - null - [null, null, null, null, null] +15024 - null - [null, null, null, null, null] +15025 - null - [null, null, null, null, null] +15026 - null - [null, null, null, null, null] +15027 - null - [null, null, null, null, null] +15028 - null - [null, null, null, null, null] +15029 - null - [null, null, null, null, null] +15030 - Crate - [Search, null, null, null, null] +15031 - Crate - [Search, null, null, null, null] +15032 - Crates - [Search, null, null, null, null] +15033 - null - [null, null, null, null, null] +15034 - null - [null, null, null, null, null] +15035 - null - [null, null, null, null, null] +15036 - null - [null, null, null, null, null] +15037 - null - [null, null, null, null, null] +15038 - null - [null, null, null, null, null] +15039 - Stool - [null, null, null, null, null] +15040 - Counter - [null, null, null, null, null] +15041 - Picnic table - [null, null, null, null, null] +15042 - null - [Take, null, null, null, null] +15043 - null - [null, null, null, null, null] +15044 - Table - [null, null, null, null, null] +15045 - Bar pumps - [null, null, null, null, null] +15046 - Warehouse shelves - [null, null, null, null, null] +15047 - Warehouse shelves - [null, null, null, null, null] +15048 - Warehouse shelves - [null, null, null, null, null] +15049 - Warehouse shelves - [null, null, null, null, null] +15050 - Altar - [Search, null, null, null, null] +15051 - Altar - [Search, null, null, null, null] +15052 - Coffin - [Close, Search, null, null, null] +15053 - Coffin - [Close, Search, null, null, null] +15054 - null - [null, null, null, null, null] +15055 - null - [null, null, null, null, null] +15056 - Door - [Open, null, null, null, null] +15057 - Skeleton - [null, null, null, null, null] +15058 - null - [null, null, null, null, null] +15059 - null - [null, null, null, null, null] +15060 - null - [null, null, null, null, null] +15061 - null - [Close, Search, null, null, null] +15062 - Teak - [Chop down, null, null, null, null] +15063 - Weedy patch - [null, null, null, null, null] +15064 - Weedy patch - [null, null, null, null, null] +15065 - Weedy patch - [null, null, null, null, null] +15066 - Weedy patch - [null, null, null, null, null] +15067 - null - [null, null, null, null, null] +15068 - Dry patch - [null, null, null, null, null] +15069 - Dry patch - [null, null, null, null, null] +15070 - Dry patch - [null, null, null, null, null] +15071 - null - [null, null, null, null, null] +15072 - Barren patch - [null, null, null, null, null] +15073 - Barren patch - [null, null, null, null, null] +15074 - null - [null, null, null, null, null] +15075 - Flax - [null, null, null, null, null] +15076 - Flax - [null, null, null, null, null] +15077 - Flax - [null, null, null, null, null] +15078 - Flax - [null, null, null, null, null] +15079 - null - [null, null, null, null, null] +15080 - Herbs - [null, null, null, null, null] +15081 - Herbs - [null, null, null, null, null] +15082 - Herbs - [null, null, null, null, null] +15083 - Herbs - [null, null, null, null, null] +15084 - null - [null, null, null, null, null] +15085 - null - [null, null, null, null, null] +15086 - null - [null, null, null, null, null] +15087 - null - [null, null, null, null, null] +15088 - Bench - [null, null, null, null, null] +15089 - null - [null, null, null, null, null] +15090 - null - [null, null, null, null, null] +15091 - Chair - [null, null, null, null, null] +15092 - Table - [null, null, null, null, null] +15093 - Stool - [null, null, null, null, null] +15094 - Bed - [null, null, null, null, null] +15095 - Bed - [null, null, null, null, null] +15096 - Bed - [null, null, null, null, null] +15097 - Bed - [null, null, null, null, null] +15098 - Shelf - [null, null, null, null, null] +15099 - Shelf - [null, null, null, null, null] +15100 - Shelf - [null, null, null, null, null] +15101 - Shelf - [null, null, null, null, null] +15102 - Shelf - [null, null, null, null, null] +15103 - Bar pumps - [null, null, null, null, null] +15104 - Bar - [null, null, null, null, null] +15105 - Barrel - [null, null, null, null, null] +15106 - Crates - [null, null, null, null, null] +15107 - Crate - [null, null, null, null, null] +15108 - Barrel - [null, null, null, null, null] +15109 - Crates - [null, null, null, null, null] +15110 - Warehouse shelves - [null, null, null, null, null] +15111 - Warehouse shelves - [null, null, null, null, null] +15112 - Warehouse shelves - [null, null, null, null, null] +15113 - Warehouse shelves - [null, null, null, null, null] +15114 - Counter - [null, null, null, null, null] +15115 - Ladder - [Climb-up, null, null, null, null] +15116 - Ladder - [Climb-down, null, null, null, null] +15117 - Bookcase - [null, null, null, null, null] +15118 - Bookcase - [null, null, null, null, null] +15119 - Bookcase - [null, null, null, null, null] +15120 - Fungus - [null, null, null, null, null] +15121 - Fungus - [null, null, null, null, null] +15122 - null - [null, null, null, null, null] +15123 - null - [null, null, null, null, null] +15124 - null - [null, null, null, null, null] +15125 - null - [null, null, null, null, null] +15126 - null - [null, null, null, null, null] +15127 - Rocks - [Take-axe, null, null, null, null] +15128 - Rocks - [null, null, null, null, null] +15129 - null - [null, null, null, null, null] +15130 - null - [null, null, null, null, null] +15131 - null - [null, null, null, null, null] +15132 - null - [null, null, null, null, null] +15133 - null - [null, null, null, null, null] +15134 - Dyed fabric - [null, null, null, null, null] +15135 - Dyed fabric - [null, null, null, null, null] +15136 - Dyed fabric - [null, null, null, null, null] +15137 - Table - [null, null, null, null, null] +15138 - Dye Pots - [null, null, null, null, null] +15139 - Cloth - [null, null, null, null, null] +15140 - Clothes model - [null, null, null, null, null] +15141 - Clothes model - [null, null, null, null, null] +15142 - Clothes model - [null, null, null, null, null] +15143 - Clothes model - [null, null, null, null, null] +15144 - Clothes equipment - [null, null, null, null, null] +15145 - Clothing shelves - [null, null, null, null, null] +15146 - null - [null, null, null, null, null] +15147 - null - [null, null, null, null, null] +15148 - null - [null, null, null, null, null] +15149 - null - [null, null, null, null, null] +15150 - null - [null, null, null, null, null] +15151 - null - [null, null, null, null, null] +15152 - null - [null, null, null, null, null] +15153 - null - [null, null, null, null, null] +15154 - null - [null, null, null, null, null] +15155 - null - [null, null, null, null, null] +15156 - Fire - [null, null, null, null, null] +15157 - null - [null, null, null, null, null] +15158 - Standing torch - [null, null, null, null, null] +15159 - null - [null, null, null, null, null] +15160 - null - [null, null, null, null, null] +15161 - null - [null, null, null, null, null] +15162 - null - [null, null, null, null, null] +15163 - null - [null, null, null, null, null] +15164 - null - [null, null, null, null, null] +15165 - Hat stand - [null, null, null, null, null] +15166 - Armour - [null, null, null, null, null] +15167 - Armour - [null, null, null, null, null] +15168 - null - [null, null, null, null, null] +15169 - null - [null, null, null, null, null] +15170 - null - [null, null, null, null, null] +15171 - null - [null, null, null, null, null] +15172 - null - [null, null, null, null, null] +15173 - null - [null, null, null, null, null] +15174 - null - [null, null, null, null, null] +15175 - null - [null, null, null, null, null] +15176 - null - [null, null, null, null, null] +15177 - null - [null, null, null, null, null] +15178 - null - [null, null, null, null, null] +15179 - null - [null, null, null, null, null] +15180 - null - [null, null, null, null, null] +15181 - null - [null, null, null, null, null] +15182 - Eggs - [null, null, null, null, null] +15183 - Eggs - [null, null, null, null, null] +15184 - Eggs - [null, null, null, null, null] +15185 - Eggs - [null, null, null, null, null] +15186 - Crevice - [Squeeze-through, null, null, null, null] +15187 - Crevice - [Squeeze-through, null, null, null, null] +15188 - Tunnel - [Enter, null, null, null, null] +15189 - Tunnel - [Enter, null, null, null, null] +15190 - Light - [null, null, null, null, null] +15191 - Exit - [Climb-up, null, null, null, null] +15192 - null - [null, null, null, null, null] +15193 - null - [null, null, null, null, null] +15194 - Crevice - [Squeeze-through, null, null, null, null] +15195 - Crevice - [Squeeze-through, null, null, null, null] +15196 - Crevice - [Squeeze-through, null, null, null, null] +15197 - Crevice - [Squeeze-through, null, null, null, null] +15198 - Rock - [null, null, null, null, null] +15199 - Rock - [null, null, null, null, null] +15200 - null - [null, null, null, null, null] +15201 - Hole - [null, null, null, null, null] +15202 - Hole - [Climb-down, null, null, null, null] +15203 - null - [null, null, null, null, null] +15204 - Door - [Open, null, null, null, null] +15205 - Door - [Close, null, null, null, null] +15206 - Fire remains - [Search, null, null, null, null] +15207 - Fire remains - [Search, null, null, null, null] +15208 - Fire remains - [Search, null, null, null, null] +15209 - Fire remains - [Search, null, null, null, null] +15210 - Fire remains - [Search, null, null, null, null] +15211 - null - [null, null, null, null, null] +15212 - null - [null, null, null, null, null] +15213 - Rocks - [Look-at, null, null, null, null] +15214 - Steam Vent - [null, null, null, null, null] +15215 - Steam Vent - [null, null, null, null, null] +15216 - Ropeswing - [Swing-on, null, null, null, null] +15217 - Rock - [null, null, null, null, null] +15218 - Rock - [null, null, null, null, null] +15219 - Rock - [null, null, null, null, null] +15220 - null - [null, null, null, null, null] +15221 - null - [null, null, null, null, null] +15222 - Platform - [null, null, null, null, null] +15223 - Platform - [null, null, null, null, null] +15224 - Platform - [null, null, null, null, null] +15225 - Platform - [Use-Lift, null, null, null, null] +15226 - Platform - [null, null, null, null, null] +15227 - Engine Platform - [null, null, null, null, null] +15228 - Lift Engine - [null, null, null, null, null] +15229 - Lift Engine - [null, null, null, null, null] +15230 - Broken Scaffold - [null, null, null, null, null] +15231 - Scaffold - [null, null, null, null, null] +15232 - Scaffold - [null, null, null, null, null] +15233 - Broken Scaffold - [null, null, null, null, null] +15234 - Scaffold - [null, null, null, null, null] +15235 - Scaffold - [null, null, null, null, null] +15236 - Scaffold - [null, null, null, null, null] +15237 - Lift Platform - [Use-Lift, null, null, null, null] +15238 - null - [null, null, null, null, null] +15239 - null - [null, null, null, null, null] +15240 - null - [null, null, null, null, null] +15241 - null - [null, null, null, null, null] +15242 - null - [null, null, null, null, null] +15243 - Crate - [Take-Beam, null, null, null, null] +15244 - Crate - [Take-Pulley-Beam, null, null, null, null] +15245 - Crate - [Take-Rope, null, null, null, null] +15246 - Rocks - [Mine, Prospect, hidden, null, null] +15247 - Rocks - [Mine, Prospect, hidden, null, null] +15248 - Rocks - [Mine, Prospect, hidden, null, null] +15249 - Rocks - [Mine, Prospect, hidden, null, null] +15250 - Rocks - [Mine, Prospect, hidden, null, null] +15251 - Rocks - [Mine, Prospect, hidden, null, null] +15252 - null - [null, null, null, null, null] +15253 - Rocks - [Mine, Prospect, hidden, null, null] +15254 - Rocks - [Mine, Prospect, hidden, null, null] +15255 - Rocks - [Mine, Prospect, hidden, null, null] +15256 - Treasure space - [null, null, null, null, Build] +15257 - Monster space - [null, null, null, null, Build] +15258 - Monster space 3 - [null, null, null, null, Build] +15259 - Decoration space - [null, null, null, null, Build] +15260 - Bed space - [null, null, null, null, Build] +15261 - Wardrobe space - [null, null, null, null, Build] +15262 - Dresser space - [null, null, null, null, Build] +15263 - Curtain space - [null, null, null, null, Build] +15264 - Rug space - [null, null, null, null, Build] +15265 - Rug space - [null, null, null, null, Build] +15266 - Rug space - [null, null, null, null, Build] +15267 - Fireplace space - [null, null, null, null, Build] +15268 - Clock space - [null, null, null, null, Build] +15269 - Icon space - [null, null, null, null, Build] +15270 - Altar space - [null, null, null, null, Build] +15271 - Lamp space - [null, null, null, null, Build] +15272 - Rug space - [null, null, null, null, Build] +15273 - Rug space - [null, null, null, null, Build] +15274 - Rug space - [null, null, null, null, Build] +15275 - Statue space - [null, null, null, null, Build] +15276 - Musical space - [null, null, null, null, Build] +15277 - Combat ring space - [null, null, null, null, Build] +15278 - Combat ring space - [null, null, null, null, Build] +15279 - Combat ring space - [null, null, null, null, Build] +15280 - Combat ring space - [null, null, null, null, Build] +15281 - Combat ring space - [null, null, null, null, Build] +15282 - Combat ring space - [null, null, null, null, Build] +15283 - Combat ring space - [null, null, null, null, Build] +15284 - Combat ring space - [null, null, null, null, Build] +15285 - Combat ring space - [null, null, null, null, Build] +15286 - Combat ring space - [null, null, null, null, Build] +15287 - Combat ring space - [null, null, null, null, Build] +15288 - Combat ring space - [null, null, null, null, Build] +15289 - Combat ring space - [null, null, null, null, Build] +15290 - Combat ring space - [null, null, null, null, Build] +15291 - Combat ring space - [null, null, null, null, Build] +15292 - Combat ring space - [null, null, null, null, Build] +15293 - Combat ring space - [null, null, null, null, Build] +15294 - Combat ring space - [null, null, null, null, Build] +15295 - Combat ring space - [null, null, null, null, Build] +15296 - Storage space - [null, null, null, null, Build] +15297 - Decoration space - [null, null, null, null, Build] +15298 - Table space - [null, null, null, null, Build] +15299 - Seating space - [null, null, null, null, Build] +15300 - Seating space - [null, null, null, null, Build] +15301 - Fireplace space - [null, null, null, null, Build] +15302 - Curtain space - [null, null, null, null, Build] +15303 - Decoration space - [null, null, null, null, Build] +15304 - Bell pull space - [null, null, null, null, Build] +15305 - Door hotspot - [null, null, null, null, Build] +15306 - Door hotspot - [null, null, null, null, Build] +15307 - Door hotspot - [null, null, null, null, Build] +15308 - Door hotspot - [null, null, null, null, Build] +15309 - Door hotspot - [null, null, null, null, Build] +15310 - Door hotspot - [null, null, null, null, Build] +15311 - Door hotspot - [null, null, null, null, Build] +15312 - Door hotspot - [null, null, null, null, Build] +15313 - Door hotspot - [null, null, null, null, Build] +15314 - Door hotspot - [null, null, null, null, Build] +15315 - Door hotspot - [null, null, null, null, Build] +15316 - Door hotspot - [null, null, null, null, Build] +15317 - Door hotspot - [null, null, null, null, Build] +15318 - Door hotspot - [null, null, null, null, Build] +15319 - Door hotspot - [null, null, null, null, Build] +15320 - Door hotspot - [null, null, null, null, Build] +15321 - Door hotspot - [null, null, null, null, Build] +15322 - Door hotspot - [null, null, null, null, Build] +15323 - Guard space - [null, null, null, null, Build] +15324 - Trap space - [null, null, null, null, Build] +15325 - Trap space - [null, null, null, null, Build] +15326 - Door space - [null, null, null, null, Build] +15327 - Door space - [null, null, null, null, Build] +15328 - Door space - [null, null, null, null, Build] +15329 - Door space - [null, null, null, null, Build] +15330 - Lighting space - [null, null, null, null, Build] +15331 - Decoration space - [null, null, null, null, Build] +15332 - Rug space - [null, null, null, null, Build] +15333 - Rug space - [null, null, null, null, Build] +15334 - Rug space - [null, null, null, null, Build] +15335 - Rug space - [null, null, null, null, Build] +15336 - Guard space - [null, null, null, null, Build] +15337 - Guard space - [null, null, null, null, Build] +15338 - Door space - [null, null, null, null, Build] +15339 - Door space - [null, null, null, null, Build] +15340 - Lighting space - [null, null, null, null, Build] +15341 - Decoration space - [null, null, null, null, Build] +15342 - Game space - [null, null, null, null, Build] +15343 - Prize chest space - [null, null, null, null, Build] +15344 - Stone space - [null, null, null, null, Build] +15345 - Elemental balance space - [null, null, null, null, Build] +15346 - Ranging game space - [null, null, null, null, Build] +15347 - Floor space mid - [null, null, null, null, Build] +15348 - Floor space side - [null, null, null, null, Build] +15349 - Floor space corner - [null, null, null, null, Build] +15350 - Floor space - [null, null, null, null, Build] +15351 - Floor space - [null, null, null, null, Build] +15352 - Prison space - [null, null, null, null, Build] +15353 - Prison space - [null, null, null, null, Build] +15354 - Guard space - [null, null, null, null, Build] +15355 - Lighting space - [null, null, null, null, Build] +15356 - Ladder space - [null, null, null, null, Build] +15357 - Door space - [null, null, null, null, Build] +15358 - Door space - [null, null, null, null, Build] +15359 - Door space - [null, null, null, null, Build] +15360 - Door space - [null, null, null, null, Build] +15361 - Centrepiece space - [null, null, null, null, Build] +15362 - Big Tree space - [null, null, null, null, Build] +15363 - Tree space - [null, null, null, null, Build] +15364 - Big Plant space 1 - [null, null, null, null, Build] +15365 - Big Plant space 2 - [null, null, null, null, Build] +15366 - Small Plant space 1 - [null, null, null, null, Build] +15367 - Small Plant space 2 - [null, null, null, null, Build] +15368 - Centrepiece space - [null, null, null, null, Build] +15369 - Fencing - [null, null, null, null, Build] +15370 - Hedging - [null, null, null, null, Build] +15371 - Hedging - [null, null, null, null, Build] +15372 - Hedging - [null, null, null, null, Build] +15373 - Big plant - [null, null, null, null, Build] +15374 - Big plant 2 - [null, null, null, null, Build] +15375 - Small plant - [null, null, null, null, Build] +15376 - Small plant 2 - [null, null, null, null, Build] +15377 - Rug space - [null, null, null, null, Build] +15378 - Rug space - [null, null, null, null, Build] +15379 - Rug space - [null, null, null, null, Build] +15380 - Stair Space - [null, null, null, null, Build] +15381 - Stair Space - [null, null, null, null, Build] +15382 - Head trophy space - [null, null, null, null, Build] +15383 - Fishing trophy space - [null, null, null, null, Build] +15384 - Armour space - [null, null, null, null, Build] +15385 - Armour space - [null, null, null, null, Build] +15386 - Rune case space - [null, null, null, null, Build] +15387 - Rug space - [null, null, null, null, Build] +15388 - Rug space - [null, null, null, null, Build] +15389 - Rug space - [null, null, null, null, Build] +15390 - Stair Space - [null, null, null, null, Build] +15391 - Stair Space - [null, null, null, null, Build] +15392 - Portrait space - [null, null, null, null, Build] +15393 - Landscape space - [null, null, null, null, Build] +15394 - Guild trophy space - [null, null, null, null, Build] +15395 - Sword space - [null, null, null, null, Build] +15396 - Map space - [null, null, null, null, Build] +15397 - Bookcase space - [null, null, null, null, Build] +15398 - Stove space - [null, null, null, null, Build] +15399 - Shelf space - [null, null, null, null, Build] +15400 - Shelf space - [null, null, null, null, Build] +15401 - Barrel space - [null, null, null, null, Build] +15402 - Cat basket space - [null, null, null, null, Build] +15403 - Larder space - [null, null, null, null, Build] +15404 - Sink space - [null, null, null, null, Build] +15405 - Table space - [null, null, null, null, Build] +15406 - Portal space - [null, null, null, null, Build] +15407 - Portal space - [null, null, null, null, Build] +15408 - Portal space - [null, null, null, null, Build] +15409 - Centrepiece space - [null, null, null, null, Build] +15410 - Chair space - [null, null, null, null, Build] +15411 - Chair space - [null, null, null, null, Build] +15412 - Chair space - [null, null, null, null, Build] +15413 - Rug space - [null, null, null, null, Build] +15414 - Rug space - [null, null, null, null, Build] +15415 - Rug space - [null, null, null, null, Build] +15416 - Bookcase space - [null, null, null, null, Build] +15417 - Bookcase space - [null, null, null, null, Build] +15418 - Fireplace space - [null, null, null, null, Build] +15419 - Curtain space - [null, null, null, null, Build] +15420 - Lectern space - [null, null, null, null, Build] +15421 - Globe space - [null, null, null, null, Build] +15422 - Crystal ball space - [null, null, null, null, Build] +15423 - Wall chart space - [null, null, null, null, Build] +15424 - Telescope space - [null, null, null, null, Build] +15425 - Bookcase space - [null, null, null, null, Build] +15426 - Throne space - [null, null, null, null, Build] +15427 - Floor space - [null, null, null, null, Build] +15428 - Floor space - [null, null, null, null, Build] +15429 - Floor space - [null, null, null, null, Build] +15430 - Floor space - [null, null, null, null, Build] +15431 - Floor space - [null, null, null, null, Build] +15432 - Floor space - [null, null, null, null, Build] +15433 - Decoration space - [null, null, null, null, Build] +15434 - Decoration space - [null, null, null, null, Build] +15435 - Lever space - [null, null, null, null, Build] +15436 - Seating space - [null, null, null, null, Build] +15437 - Seating space - [null, null, null, null, Build] +15438 - Trapdoor space - [null, null, null, null, Build] +15439 - Workbench space - [null, null, null, null, Build] +15440 - Nothing - [null, null, null, null, Build] +15441 - Clockmaking space - [null, null, null, null, Build] +15442 - Nothing - [null, null, null, null, Build] +15443 - Tool space - [null, null, null, null, Build] +15444 - Tool space - [null, null, null, null, Build] +15445 - Tool space - [null, null, null, null, Build] +15446 - Tool space - [null, null, null, null, Build] +15447 - Tool space - [null, null, null, null, Build] +15448 - Repair space - [null, null, null, null, Build] +15449 - Nothing - [null, null, null, null, Build] +15450 - Heraldry space - [null, null, null, null, Build] +15451 - Doorway - [null, null, null, null, Carpent] +15452 - Wall - [null, null, null, null, null] +15453 - null - [null, null, null, null, null] +15454 - null - [null, null, null, null, null] +15455 - null - [null, null, null, null, null] +15456 - null - [null, null, null, null, null] +15457 - null - [null, null, null, null, null] +15458 - null - [null, null, null, null, null] +15459 - null - [null, null, null, null, null] +15460 - null - [null, null, null, null, null] +15461 - Bookcase - [null, null, null, null, null] +15462 - Chair - [null, null, null, null, null] +15463 - Hat stand - [null, null, null, null, null] +15464 - Picture - [null, null, null, null, null] +15465 - Display board - [null, null, null, null, null] +15466 - Stone crusher - [null, null, null, null, null] +15467 - Cleaning supplies - [null, null, null, null, null] +15468 - Power saw - [null, null, null, null, null] +15469 - Embalming tube - [null, null, null, null, null] +15470 - null - [null, null, null, null, null] +15471 - Fish bowl - [null, null, null, null, null] +15472 - Gloves and duster - [null, null, null, null, null] +15473 - Mahogany table - [null, null, null, null, null] +15474 - null - [null, null, null, null, null] +15475 - null - [null, null, null, null, null] +15476 - null - [null, null, null, null, null] +15477 - Portal - [Enter, null, null, null, null] +15478 - Portal - [Enter, null, null, null, null] +15479 - Portal - [Enter, null, null, null, null] +15480 - Portal - [Enter, null, null, null, null] +15481 - Portal - [Enter, null, null, null, null] +15482 - Portal - [Enter, null, null, null, null] +15483 - null - [null, null, null, null, null] +15484 - null - [Study, null, null, null, null] +15485 - null - [null, null, null, null, null] +15486 - Pigeon - [null, null, null, null, null] +15487 - Chimney - [null, null, null, null, null] +15488 - Tree trunk - [null, null, null, null, null] +15489 - Tree - [null, null, null, null, null] +15490 - Kalphite Queen - [null, null, null, null, null] +15491 - Rocks - [Mine, Prospect, hidden, null, null] +15492 - Rocks - [Mine, Prospect, hidden, null, null] +15493 - Rocks - [Mine, Prospect, hidden, null, null] +15494 - null - [null, null, null, null, null] +15495 - null - [null, null, null, null, null] +15496 - null - [null, null, null, null, null] +15497 - null - [null, null, null, null, null] +15498 - null - [null, null, null, null, null] +15499 - null - [null, null, null, null, null] +15500 - null - [null, null, null, null, null] +15501 - null - [null, null, null, null, null] +15502 - null - [null, null, null, null, null] +15503 - Rocks - [Mine, Prospect, hidden, null, null] +15504 - Rocks - [Mine, Prospect, hidden, null, null] +15505 - Rocks - [Mine, Prospect, hidden, null, null] +15506 - Wheat - [null, Pick, null, null, null] +15507 - Wheat - [null, Pick, null, null, null] +15508 - Wheat - [null, Pick, null, null, null] +15509 - null - [null, null, null, null, null] +15510 - Gate - [Open, null, null, null, null] +15511 - Gate - [Close, null, null, null, null] +15512 - Gate - [Open, null, null, null, null] +15513 - Gate - [Close, null, null, null, null] +15514 - Gate - [Open, null, null, null, null] +15515 - Gate - [Close, null, null, null, null] +15516 - Gate - [Open, null, null, null, null] +15517 - Gate - [Close, null, null, null, null] +15518 - Mouse hole - [null, null, null, null, null] +15519 - Mouse hole - [null, null, null, null, null] +15520 - null - [null, null, null, null, null] +15521 - Piano stool - [Sit-On, null, null, null, null] +15522 - Signpost - [Read, null, null, null, null] +15523 - Trapdoor - [Open, null, null, null, null] +15524 - Barrel - [null, null, null, null, null] +15525 - null - [null, null, null, null, null] +15526 - null - [null, null, null, null, null] +15527 - null - [null, null, null, null, null] +15528 - null - [null, null, null, null, null] +15529 - null - [null, null, null, null, null] +15530 - null - [null, null, null, null, null] +15531 - null - [null, null, null, null, null] +15532 - null - [null, null, null, null, null] +15533 - null - [null, null, null, null, null] +15534 - null - [null, null, null, null, null] +15535 - Door - [Close, null, null, null, null] +15536 - Door - [Open, null, null, null, null] +15537 - Drain - [null, null, null, null, null] +15538 - null - [null, null, null, null, null] +15539 - null - [null, null, null, null, null] +15540 - null - [null, null, null, null, null] +15541 - Bookcase - [Search, null, null, null, null] +15542 - Bookcase - [Search, null, null, null, null] +15543 - Bookcase - [Search, null, null, null, null] +15544 - Bookcase - [Search, null, null, null, null] +15545 - null - [null, null, null, null, null] +15546 - Oak chair - [null, null, null, null, null] +15547 - Clock - [null, null, null, null, null] +15548 - null - [null, null, null, null, null] +15549 - null - [null, null, null, null, null] +15550 - null - [null, null, null, null, null] +15551 - Desk - [null, null, null, null, null] +15552 - null - [null, null, null, null, null] +15553 - null - [null, null, null, null, null] +15554 - null - [null, null, null, null, null] +15555 - null - [null, null, null, null, null] +15556 - null - [null, null, null, null, null] +15557 - null - [null, null, null, null, null] +15558 - null - [null, null, null, null, null] +15559 - Painting - [null, null, null, null, null] +15560 - Painting - [null, null, null, null, null] +15561 - Dragon's head - [null, null, null, null, null] +15562 - Dragon's head - [null, null, null, null, null] +15563 - Dragon's head - [null, null, null, null, null] +15564 - Dragon's head - [null, null, null, null, null] +15565 - Dragon's head - [null, null, null, null, null] +15566 - Warning sign - [Read, null, null, null, null] +15567 - null - [null, null, null, null, null] +15568 - null - [null, null, null, null, null] +15569 - null - [null, null, null, null, null] +15570 - Rocks - [Mine, Prospect, hidden, null, null] +15571 - Rocks - [Mine, Prospect, hidden, null, null] +15572 - Rocks - [Mine, Prospect, hidden, null, null] +15573 - Rocks - [Mine, Prospect, hidden, null, null] +15574 - Rocks - [Mine, Prospect, hidden, null, null] +15575 - Rocks - [Mine, Prospect, hidden, null, null] +15576 - Rocks - [Mine, Prospect, hidden, null, null] +15577 - Rocks - [Mine, Prospect, hidden, null, null] +15578 - Rocks - [Mine, Prospect, hidden, null, null] +15579 - Rocks - [Mine, Prospect, hidden, null, null] +15580 - Rocks - [Mine, Prospect, hidden, null, null] +15581 - Rocks - [Mine, Prospect, hidden, null, null] +15582 - Rocks - [Mine, Prospect, hidden, null, null] +15583 - Rocks - [Mine, Prospect, hidden, null, null] +15584 - Rocks - [Mine, Prospect, hidden, null, null] +15585 - null - [null, null, null, null, null] +15586 - null - [null, null, null, null, null] +15587 - null - [null, null, null, null, null] +15588 - null - [null, null, null, null, null] +15589 - null - [null, null, null, null, null] +15590 - null - [null, null, null, null, null] +15591 - null - [null, null, null, null, null] +15592 - null - [null, null, null, null, null] +15593 - null - [null, null, null, null, null] +15594 - null - [null, null, null, null, null] +15595 - null - [null, null, null, null, null] +15596 - Dwarf remains - [Take, null, null, null, null] +15597 - null - [null, null, null, null, null] +15598 - Boxes - [Search, null, null, null, null] +15599 - Crate - [Search, null, null, null, null] +15600 - Crates - [Search, null, null, null, null] +15601 - Railing - [Inspect, null, null, null, null] +15602 - Railing - [null, null, null, null, null] +15603 - Railing - [null, null, null, null, null] +15604 - Gate - [Open, null, null, null, null] +15605 - Gate - [Open, null, null, null, null] +15606 - null - [null, null, null, null, null] +15607 - null - [null, null, null, null, null] +15608 - Statue of a warrior - [null, null, null, null, null] +15609 - Statue of a warrior - [null, null, null, null, null] +15610 - Statue of a king - [null, null, null, null, null] +15611 - Statue of a queen - [null, null, null, null, null] +15612 - Gnome statue - [null, null, null, null, null] +15613 - Statue of a king - [null, null, null, null, null] +15614 - null - [null, null, null, null, null] +15615 - null - [null, null, null, null, null] +15616 - Catapult - [null, null, null, null, null] +15617 - Catapult - [null, null, null, null, null] +15618 - Catapult - [null, null, null, null, null] +15619 - Catapult - [null, null, null, null, null] +15620 - Catapult - [null, null, null, null, null] +15621 - Magical Animator - [null, null, null, null, null] +15622 - null - [null, null, null, null, null] +15623 - null - [null, null, null, null, null] +15624 - Dummy - [Hit, null, null, null, null] +15625 - Dummy - [Hit, null, null, null, null] +15626 - Dummy - [Hit, null, null, null, null] +15627 - Dummy - [Hit, null, null, null, null] +15628 - Dummy - [Hit, null, null, null, null] +15629 - Dummy - [Hit, null, null, null, null] +15630 - Dummy - [Hit, null, null, null, null] +15631 - Hole - [null, null, null, null, null] +15632 - Hole - [null, null, null, null, null] +15633 - Hole - [null, null, null, null, null] +15634 - Hole - [null, null, null, null, null] +15635 - Hole - [null, null, null, null, null] +15636 - Hole - [null, null, null, null, null] +15637 - Hole - [null, null, null, null, null] +15638 - Staircase - [Climb-down, null, null, null, null] +15639 - null - [null, null, null, null, null] +15640 - null - [null, null, null, null, null] +15641 - Door - [Open, null, null, null, null] +15642 - Door - [Close, null, null, null, null] +15643 - null - [null, null, null, null, null] +15644 - Door - [Open, null, null, null, null] +15645 - Door - [Close, null, null, null, null] +15646 - null - [null, null, null, null, null] +15647 - Door - [Open, null, null, null, null] +15648 - Door - [Close, null, null, null, null] +15649 - null - [null, null, null, null, null] +15650 - Door - [Open, null, null, null, null] +15651 - Door - [Close, null, null, null, null] +15652 - null - [null, null, null, null, null] +15653 - Door - [Open, null, null, null, null] +15654 - Door - [Close, null, null, null, null] +15655 - null - [null, null, null, null, null] +15656 - Information Scroll - [View, null, null, null, null] +15657 - Information Scroll - [View, null, null, null, null] +15658 - Heavy door - [Open, null, null, null, null] +15659 - Heavy door - [null, null, null, null, null] +15660 - Heavy door - [Open, null, null, null, null] +15661 - Heavy door - [null, null, null, null, null] +15662 - Keg - [null, null, null, null, null] +15663 - Keg - [null, null, null, null, null] +15664 - Shot - [Throw, null, null, null, null] +15665 - Shot - [Throw, null, null, null, null] +15666 - null - [null, null, null, null, null] +15667 - null - [null, null, null, null, null] +15668 - Keg - [Pick-up, null, null, null, null] +15669 - null - [null, null, null, null, null] +15670 - null - [null, null, null, null, null] +15671 - null - [null, null, null, null, null] +15672 - null - [null, null, null, null, null] +15673 - null - [null, null, null, null, null] +15674 - Barrel - [null, null, null, null, null] +15675 - Barrel - [null, null, null, null, null] +15676 - Barrel - [null, null, null, null, null] +15677 - Bank table - [null, null, null, null, null] +15678 - Sink - [null, null, null, null, null] +15679 - Stool - [null, null, null, null, null] +15680 - Table - [null, null, null, null, null] +15681 - null - [null, null, null, null, null] +15682 - null - [null, null, null, null, null] +15683 - Bed - [null, null, null, null, null] +15684 - Table - [null, null, null, null, null] +15685 - Cooking shelves - [null, null, null, null, null] +15686 - Cooking shelves - [null, null, null, null, null] +15687 - null - [null, null, null, null, null] +15688 - null - [null, null, null, null, null] +15689 - null - [null, null, null, null, null] +15690 - Portrait - [null, null, null, null, null] +15691 - Painting - [null, null, null, null, null] +15692 - Crate - [null, null, null, null, null] +15693 - Crates - [null, null, null, null, null] +15694 - null - [null, null, null, null, null] +15695 - Crate - [Search, null, null, null, null] +15696 - Crate - [Search, null, null, null, null] +15697 - Crate - [null, null, null, null, null] +15698 - Crate - [null, null, null, null, null] +15699 - Box cart - [null, null, null, null, null] +15700 - Box cart - [null, null, null, null, null] +15701 - null - [null, null, null, null, null] +15702 - null - [null, null, null, null, null] +15703 - null - [null, null, null, null, null] +15704 - Crate - [Search, null, null, null, null] +15705 - Crate - [null, null, null, null, null] +15706 - Crate - [null, null, null, null, null] +15707 - Crate - [null, null, null, null, null] +15708 - null - [null, null, null, null, null] +15709 - Zanik - [null, null, null, null, null] +15710 - null - [null, null, null, null, null] +15711 - Zanik - [Inspect, null, null, null, null] +15712 - null - [null, null, null, null, null] +15713 - Drilling machine - [Smash, null, null, null, null] +15714 - Drilling machine - [null, null, null, null, null] +15715 - Broken drilling machine - [null, null, null, null, null] +15716 - null - [null, null, null, null, null] +15717 - null - [null, null, null, null, null] +15718 - null - [null, null, null, null, null] +15719 - Table - [null, null, null, null, null] +15720 - Crate - [Search, null, null, null, null] +15721 - Crate - [Search, null, null, null, null] +15722 - Small chest - [Open, null, null, null, null] +15723 - Small chest - [Open, null, null, null, null] +15724 - Small chest - [Open, null, null, null, null] +15725 - Small chest - [null, null, null, null, null] +15726 - Small chest - [Open, null, null, null, null] +15727 - Drip - [null, null, null, null, null] +15728 - Drips - [null, null, null, null, null] +15729 - null - [null, null, null, null, null] +15730 - null - [null, null, null, null, null] +15731 - Crack - [Squeeze-through, null, null, null, null] +15732 - Wall - [null, null, null, null, null] +15733 - Wall - [null, null, null, null, null] +15734 - null - [null, null, null, null, null] +15735 - null - [null, null, null, null, null] +15736 - null - [null, null, null, null, null] +15737 - null - [null, null, null, null, null] +15738 - null - [null, null, null, null, null] +15739 - null - [null, null, null, null, null] +15740 - null - [null, null, null, null, null] +15741 - null - [null, null, null, null, null] +15742 - null - [null, null, null, null, null] +15743 - null - [null, null, null, null, null] +15744 - null - [null, null, null, null, null] +15745 - null - [null, null, null, null, null] +15746 - Ladder - [Climb-up, null, null, null, null] +15747 - Ladder - [Climb-up, null, null, null, null] +15748 - Tunnel - [Squeeze-through, null, null, null, null] +15749 - Tunnel - [null, null, null, null, null] +15750 - Tunnel - [Squeeze-through, null, null, null, null] +15751 - Tunnel - [Unblock, null, null, null, null] +15752 - Trapdoor - [Open, null, null, null, null] +15753 - Trapdoor - [Go-down, null, null, null, null] +15754 - Rubble - [null, null, null, null, null] +15755 - Hidden trapdoor - [Open, Pick-lock, null, null, null] +15756 - Trapdoor - [Climb-down, null, null, null, null] +15757 - Large door - [Listen-at, null, null, null, null] +15758 - Large door - [Listen-at, null, null, null, null] +15759 - Door - [Open, null, null, Pick-lock, null] +15760 - Sack - [null, null, null, null, null] +15761 - Sack Pile - [null, null, null, null, null] +15762 - Sacks - [null, null, null, null, null] +15763 - null - [null, null, null, null, null] +15764 - null - [null, null, null, null, null] +15765 - null - [null, null, null, null, null] +15766 - null - [null, null, null, null, null] +15767 - Cave entrance - [Enter, null, null, null, null] +15768 - Cave entrance - [null, null, null, null, null] +15769 - Cave - [null, null, null, null, null] +15770 - Cave - [null, null, null, null, null] +15771 - Boulders - [null, null, null, null, null] +15772 - Boulders - [null, null, null, null, null] +15773 - Ruins - [null, null, null, null, null] +15774 - Slab - [null, null, null, null, null] +15775 - Stump - [null, null, null, null, null] +15776 - Tree - [null, null, null, null, null] +15777 - Tree - [null, null, null, null, null] +15778 - Tropical tree - [null, null, null, null, null] +15779 - Tropical tree - [null, null, null, null, null] +15780 - Tropical tree - [null, null, null, null, null] +15781 - Tropical tree - [null, null, null, null, null] +15782 - Tropical tree - [null, null, null, null, null] +15783 - Tropical tree - [null, null, null, null, null] +15784 - Tropical tree - [null, null, null, null, null] +15785 - null - [null, null, null, null, null] +15786 - null - [null, null, null, null, null] +15787 - null - [null, null, null, null, null] +15788 - Leaves - [null, null, null, null, null] +15789 - Leaves - [null, null, null, null, null] +15790 - Staircase - [Climb-up, null, null, null, null] +15791 - Staircase - [Climb-Down, null, null, null, null] +15792 - null - [null, null, null, null, null] +15793 - null - [null, null, null, null, null] +15794 - null - [null, null, null, null, null] +15795 - null - [null, null, null, null, null] +15796 - null - [null, null, null, null, null] +15797 - null - [null, null, null, null, null] +15798 - null - [null, null, null, null, null] +15799 - null - [null, null, null, null, null] +15800 - null - [null, null, null, null, null] +15801 - null - [null, null, null, null, null] +15802 - null - [null, null, null, null, null] +15803 - null - [null, null, null, null, null] +15804 - null - [null, null, null, null, null] +15805 - null - [null, null, null, null, null] +15806 - null - [null, null, null, null, null] +15807 - null - [null, null, null, null, null] +15808 - null - [null, null, null, null, null] +15809 - null - [null, null, null, null, null] +15810 - Hole - [Enter, null, null, null, null] +15811 - Cave - [Exit, null, null, null, null] +15812 - Cave - [Exit, null, null, null, null] +15813 - Boulders - [null, null, null, null, null] +15814 - Boulders - [null, null, null, null, null] +15815 - Mushrooms - [null, null, null, null, null] +15816 - Mushrooms - [null, null, null, null, null] +15817 - Rock - [null, null, null, null, null] +15818 - Small rock - [null, null, null, null, null] +15819 - Rock - [null, null, null, null, null] +15820 - null - [null, null, null, null, null] +15821 - null - [null, null, null, null, null] +15822 - null - [null, null, null, null, null] +15823 - null - [null, null, null, null, null] +15824 - null - [null, null, null, null, null] +15825 - null - [null, null, null, null, null] +15826 - null - [null, null, null, null, null] +15827 - null - [null, null, null, null, null] +15828 - null - [null, null, null, null, null] +15829 - null - [null, null, null, null, null] +15830 - null - [null, null, null, null, null] +15831 - null - [null, null, null, null, null] +15832 - null - [null, null, null, null, null] +15833 - null - [null, null, null, null, null] +15834 - null - [null, null, null, null, null] +15835 - null - [null, null, null, null, null] +15836 - null - [null, null, null, null, null] +15837 - Bamboo Pipes - [null, null, null, null, null] +15838 - Bamboo Pipes - [null, null, null, null, null] +15839 - Bamboo Pipes - [null, null, null, null, null] +15840 - Bamboo Pipes - [null, null, null, null, null] +15841 - Bamboo Pipes - [null, null, null, null, null] +15842 - Bamboo Pipes - [null, null, null, null, null] +15843 - Bamboo Pipes - [null, null, null, null, null] +15844 - Bamboo Pipes - [null, null, null, null, null] +15845 - Rum Crate - [null, null, null, null, null] +15846 - Red flowers - [Pick, null, null, null, null] +15847 - Hopper - [null, null, null, null, null] +15848 - Hopper - [null, null, null, null, null] +15849 - Hopper - [null, null, null, null, null] +15850 - Hopper - [null, null, null, null, null] +15851 - Hopper - [null, null, null, null, null] +15852 - Hopper - [null, null, null, null, null] +15853 - Hopper - [null, null, null, null, null] +15854 - Hopper - [null, null, null, null, null] +15855 - Bridge - [null, null, null, null, null] +15856 - Bridge - [null, null, null, null, null] +15857 - Bridge - [null, null, null, null, null] +15858 - Bridge - [null, null, null, null, null] +15859 - Bridge - [null, null, null, null, null] +15860 - Bridge - [null, null, null, null, null] +15861 - Bridge - [null, null, null, null, null] +15862 - Bridge - [null, null, null, null, null] +15863 - Bamboo Pipes - [null, null, null, null, null] +15864 - Bamboo Pipes - [null, null, null, null, null] +15865 - Bamboo Pipes - [null, null, null, null, null] +15866 - Bamboo Pipes - [null, null, null, null, null] +15867 - Bamboo Pipes - [null, null, null, null, null] +15868 - Bamboo Pipes - [null, null, null, null, null] +15869 - Bamboo Pipes - [null, null, null, null, null] +15870 - Bamboo Pipes - [null, null, null, null, null] +15871 - Rum Crate - [null, null, null, null, null] +15872 - Blue flowers - [Pick, null, null, null, null] +15873 - Hopper - [null, null, null, null, null] +15874 - Hopper - [null, null, null, null, null] +15875 - Hopper - [null, null, null, null, null] +15876 - Hopper - [null, null, null, null, null] +15877 - Hopper - [null, null, null, null, null] +15878 - Hopper - [null, null, null, null, null] +15879 - Hopper - [null, null, null, null, null] +15880 - Hopper - [null, null, null, null, null] +15881 - Bridge - [null, null, null, null, null] +15882 - Bridge - [null, null, null, null, null] +15883 - Bridge - [null, null, null, null, null] +15884 - Bridge - [null, null, null, null, null] +15885 - Bridge - [null, null, null, null, null] +15886 - Bridge - [null, null, null, null, null] +15887 - Bridge - [null, null, null, null, null] +15888 - Bridge - [null, null, null, null, null] +15889 - null - [null, null, null, null, null] +15890 - Bamboo Ladder - [Climb-up, null, null, null, null] +15891 - Bamboo Ladder - [null, null, null, null, null] +15892 - Bamboo Ladder - [Climb-down, null, null, null, null] +15893 - Bamboo Ladder - [Climb-up, null, null, null, null] +15894 - Bamboo Ladder - [null, null, null, null, null] +15895 - Bamboo Ladder - [Climb-down, null, null, null, null] +15896 - Copper Ladder - [Climb-up, null, null, null, null] +15897 - Copper Ladder - [null, null, null, null, null] +15898 - Copper Ladder - [Climb-down, null, null, null, null] +15899 - Copper Ladder - [Climb-up, null, null, null, null] +15900 - Copper Ladder - [null, null, null, null, null] +15901 - Copper Ladder - [Climb-down, null, null, null, null] +15902 - Posts - [null, null, null, null, null] +15903 - Boiler - [null, null, null, null, null] +15904 - Boiler - [null, null, null, null, null] +15905 - Boiler - [null, null, null, null, null] +15906 - Boiler - [null, null, null, null, null] +15907 - Boiler - [null, null, null, null, null] +15908 - Boiler - [null, null, null, null, null] +15909 - Boiler - [null, null, null, null, null] +15910 - Boiler - [null, null, null, null, null] +15911 - Boiler - [null, null, null, null, null] +15912 - Boiler - [null, null, null, null, null] +15913 - Boiler - [null, null, null, null, null] +15914 - Boiler - [null, null, null, null, null] +15915 - null - [null, null, null, null, null] +15916 - middle section - [null, null, null, null, null] +15917 - middle section - [null, null, null, null, null] +15918 - middle section - [null, null, null, null, null] +15919 - middle section - [null, null, null, null, null] +15920 - middle section - [null, null, null, null, null] +15921 - middle section - [null, null, null, null, null] +15922 - Bottle Machine - [null, null, null, null, null] +15923 - Bottle machine - [null, null, null, null, null] +15924 - Conveyor Belt - [null, null, null, null, null] +15925 - Conveyor Belt - [null, null, null, null, null] +15926 - Conveyor Belt - [Take-Rum, null, null, null, null] +15927 - Conveyor Belt - [null, null, null, null, null] +15928 - Steam Pump - [Pump, Vent, hidden, null, null] +15929 - Steam Pump - [hidden, null, hidden, null, null] +15930 - Steam_Pump - [hidden, null, hidden, null, null] +15931 - Log Store - [Take-Log, null, null, null, null] +15932 - Workbench - [null, null, null, null, null] +15933 - Workbench - [null, null, null, null, null] +15934 - Workbench - [Take-Tool, null, null, null, null] +15935 - Watering Hole - [null, null, null, null, null] +15936 - Water Pump - [null, null, null, null, null] +15937 - Water Pump - [null, null, null, null, null] +15938 - Water Pump - [null, null, null, null, null] +15939 - Red Flowers - [null, null, null, null, null] +15940 - Blue Flowers - [null, null, null, null, null] +15941 - Red Flowers - [null, null, null, null, null] +15942 - Blue Flowers - [null, null, null, null, null] +15943 - Bridge - [null, null, null, null, null] +15944 - Bridge - [null, null, null, null, null] +15945 - Bridge - [null, null, null, null, null] +15946 - Sweetgrub Mound - [null, null, null, null, null] +15947 - Sweetgrub Mound - [null, null, null, null, null] +15948 - Jungle Tree - [Cut-Down, null, hidden, null, null] +15949 - Jungle Tree - [null, null, null, null, null] +15950 - Jungle Tree - [null, null, null, null, null] +15951 - Jungle Tree - [Cut-Down, null, hidden, null, null] +15952 - Jungle Tree - [null, null, null, null, null] +15953 - Jungle Tree - [null, null, null, null, null] +15954 - Jungle Tree - [Cut-Down, null, hidden, null, null] +15955 - Jungle Tree - [null, null, null, null, null] +15956 - Jungle Tree - [null, null, null, null, null] +15957 - Tropical tree - [null, null, null, null, null] +15958 - Tropical tree - [null, null, null, null, null] +15959 - Tropical tree - [null, null, null, null, null] +15960 - Tropical leaves - [null, null, null, null, null] +15961 - Bitternut Tree - [null, null, null, null, null] +15962 - Bitternut Tree - [null, null, null, null, null] +15963 - Bitternut Tree - [null, null, null, null, null] +15964 - Bitternut Tree - [null, null, null, null, null] +15965 - Bitternut Tree - [null, null, null, null, null] +15966 - Bitternut Tree - [null, null, null, null, null] +15967 - Bitternut Tree - [null, null, null, null, null] +15968 - Bitternut Tree - [null, null, null, null, null] +15969 - Bitternut Tree - [null, null, null, null, null] +15970 - Scrapey Tree - [Cut-Down, null, hidden, null, null] +15971 - Scrapey Tree - [null, null, null, null, null] +15972 - null - [null, null, null, null, null] +15973 - null - [null, null, null, null, null] +15974 - null - [null, null, null, null, null] +15975 - null - [null, null, null, null, null] +15976 - null - [null, null, null, null, null] +15977 - null - [null, null, null, null, null] +15978 - Jungle Plant - [null, null, null, null, null] +15979 - null - [null, null, null, null, null] +15980 - null - [null, null, null, null, null] +15981 - Chair - [null, null, null, null, null] +15982 - Table - [null, null, null, null, null] +15983 - Kettle - [null, null, null, null, null] +15984 - Waiting Room Door - [Open, null, null, null, null] +15985 - Deposit Box - [Deposit, null, null, null, null] +15986 - Bitternut Sign - [null, null, null, null, null] +15987 - Sweetgrub Sign - [null, null, null, null, null] +15988 - Scrapey Bark Sign - [null, null, null, null, null] +15989 - Red Water Sign - [null, null, null, null, null] +15990 - Blue Water Sign - [null, null, null, null, null] +15991 - Water Sign - [null, null, null, null, null] +15992 - Sign - [null, null, null, null, null] +15993 - Sign - [null, null, null, null, null] +15994 - Sign - [null, null, null, null, null] +15995 - Stall - [null, null, null, null, null] +15996 - Portal - [Exit, null, null, null, null] +15997 - Pirate Flag - [null, null, null, null, null] +15998 - Pirate Flag - [null, null, null, null, null] +15999 - null - [null, null, null, null, null] +16000 - null - [null, null, null, null, null] +16001 - Crate - [null, null, null, null, null] +16002 - Crate - [null, null, null, null, null] +16003 - Barrel - [null, null, null, null, null] +16004 - null - [null, null, null, null, null] +16005 - Stepping log - [Jump-to, null, null, null, null] +16006 - Stepping log - [null, null, null, null, null] +16007 - Stepping log - [null, null, null, null, null] +16008 - null - [null, null, null, null, null] +16009 - null - [null, null, null, null, null] +16010 - Telescope - [Peer-Through, null, null, null, null] +16011 - null - [null, null, null, null, null] +16012 - Stepping Stone - [null, null, null, null, null] +16013 - Stepping stone - [null, null, null, null, null] +16014 - null - [null, null, null, null, null] +16015 - null - [null, null, null, null, null] +16016 - null - [null, null, null, null, null] +16017 - null - [null, null, null, null, null] +16018 - null - [null, null, null, null, null] +16019 - null - [null, null, null, null, null] +16020 - null - [null, null, null, null, null] +16021 - null - [null, null, null, null, null] +16022 - null - [null, null, null, null, null] +16023 - null - [null, null, null, null, null] +16024 - null - [null, null, null, null, null] +16025 - null - [Take-Rum, null, null, null, null] +16026 - null - [Take-Rum, null, null, null, null] +16027 - null - [null, null, null, null, null] +16028 - null - [null, null, null, null, null] +16029 - null - [null, null, null, null, null] +16030 - null - [null, null, null, null, null] +16031 - null - [null, null, null, null, null] +16032 - null - [null, null, null, null, null] +16033 - null - [null, null, null, null, null] +16034 - null - [null, null, null, null, null] +16035 - null - [null, null, null, null, null] +16036 - null - [null, null, null, null, null] +16037 - null - [null, null, null, null, null] +16038 - null - [null, null, null, null, null] +16039 - null - [null, null, null, null, null] +16040 - null - [null, null, null, null, null] +16041 - Sulphur vent - [null, null, null, null, null] +16042 - null - [null, null, null, null, null] +16043 - Portal of Death - [Open, null, null, null, null] +16044 - Portal of Death - [Open, null, null, null, null] +16045 - Portal of Death - [null, null, null, null, null] +16046 - Portal of Death - [null, null, null, null, null] +16047 - Cradle of Life - [Search, null, null, null, null] +16048 - Bone Chain - [Climb-up, null, null, null, null] +16049 - Boney ladder - [Climb-up, null, null, null, null] +16050 - Portal - [Use, null, null, null, null] +16051 - null - [null, null, null, null, null] +16052 - null - [null, null, null, null, null] +16053 - null - [null, null, null, null, null] +16054 - null - [null, null, null, null, null] +16055 - Skeleton - [null, null, null, null, null] +16056 - Skeleton - [null, null, null, null, null] +16057 - Skeleton - [null, null, null, null, null] +16058 - null - [null, null, null, null, null] +16059 - null - [null, null, null, null, null] +16060 - null - [null, null, null, null, null] +16061 - null - [null, null, null, null, null] +16062 - null - [null, null, null, null, null] +16063 - null - [null, null, null, null, null] +16064 - null - [null, null, null, null, null] +16065 - Rickety door - [Open, null, null, null, null] +16066 - Rickety door - [Open, null, null, null, null] +16067 - Rickety door - [null, null, null, null, null] +16068 - Rickety door - [null, null, null, null, null] +16069 - null - [null, null, null, null, null] +16070 - null - [null, null, null, null, null] +16071 - null - [null, null, null, null, null] +16072 - null - [null, null, null, null, null] +16073 - null - [null, null, null, null, null] +16074 - Skeleton - [null, null, null, null, null] +16075 - Skeleton - [null, null, null, null, null] +16076 - Skeleton - [null, null, null, null, null] +16077 - Grain of Plenty - [Search, null, null, null, null] +16078 - Rope - [Climb-up, null, null, null, null] +16079 - Rope - [Climb-down, null, null, null, null] +16080 - Ladder - [Climb-up, null, null, null, null] +16081 - Ladder - [Climb-down, null, null, null, null] +16082 - Portal - [Use, null, null, null, null] +16083 - Danger Sign - [null, null, null, null, null] +16084 - null - [null, null, null, null, null] +16085 - null - [null, null, null, null, null] +16086 - null - [null, null, null, null, null] +16087 - null - [null, null, null, null, null] +16088 - null - [null, null, null, null, null] +16089 - Oozing barrier - [Open, null, null, null, null] +16090 - Oozing barrier - [Open, null, null, null, null] +16091 - null - [null, null, null, null, null] +16092 - Oozing barrier - [null, null, null, null, null] +16093 - null - [null, null, null, null, null] +16094 - null - [null, null, null, null, null] +16095 - null - [null, null, null, null, null] +16096 - null - [null, null, null, null, null] +16097 - null - [null, null, null, null, null] +16098 - null - [null, null, null, null, null] +16099 - null - [null, null, null, null, null] +16100 - null - [null, null, null, null, null] +16101 - null - [null, null, null, null, null] +16102 - null - [null, null, null, null, null] +16103 - Skeleton - [null, null, null, null, null] +16104 - Skeleton - [null, null, null, null, null] +16105 - Skeleton - [null, null, null, null, null] +16106 - null - [null, null, null, null, null] +16107 - null - [null, null, null, null, null] +16108 - null - [null, null, null, null, null] +16109 - Stinking tendrils - [null, null, null, null, null] +16110 - Dripping tendrils - [null, null, null, null, null] +16111 - Tendrils - [null, null, null, null, null] +16112 - Goo covered vine - [Climb-up, null, null, null, null] +16113 - Goo covered vine - [Climb-down, null, null, null, null] +16114 - Dripping vine - [Climb-up, null, null, null, null] +16115 - Dripping vine - [Climb-down, null, null, null, null] +16116 - Portal - [Use, null, null, null, null] +16117 - Danger Sign - [null, null, null, null, null] +16118 - Box of Health - [Open, null, null, null, null] +16119 - null - [null, null, null, null, null] +16120 - null - [null, null, null, null, null] +16121 - null - [null, null, null, null, null] +16122 - null - [null, null, null, null, null] +16123 - Gate of War - [Open, null, null, null, null] +16124 - Gate of War - [Open, null, null, null, null] +16125 - null - [null, null, null, null, null] +16126 - Gate of War - [null, null, null, null, null] +16127 - Gate of War - [null, null, null, null, null] +16128 - null - [null, null, null, null, null] +16129 - null - [null, null, null, null, null] +16130 - null - [null, null, null, null, null] +16131 - null - [null, null, null, null, null] +16132 - null - [null, null, null, null, null] +16133 - null - [null, null, null, null, null] +16134 - null - [null, null, null, null, null] +16135 - Gift of Peace - [Open, null, null, null, null] +16136 - Rock - [null, null, null, null, null] +16137 - null - [null, null, null, null, null] +16138 - null - [null, null, null, null, null] +16139 - null - [null, null, null, null, null] +16140 - null - [null, null, null, null, null] +16141 - null - [null, null, null, null, null] +16142 - null - [null, null, null, null, null] +16143 - Skeleton - [null, null, null, null, null] +16144 - Skeleton - [null, null, null, null, null] +16145 - Skeleton - [null, null, null, null, null] +16146 - Spikey chain - [Climb-up, null, null, null, null] +16147 - Spikey chain - [Climb-down, null, null, null, null] +16148 - Ladder - [Climb-up, null, null, null, null] +16149 - Ladder - [Climb-down, null, null, null, null] +16150 - Portal - [Use, null, null, null, null] +16151 - Danger Sign - [null, null, null, null, null] +16152 - Dead Explorer - [Search, null, null, null, null] +16153 - Rock - [null, null, null, null, null] +16154 - Entrance - [Climb-down, null, null, null, null] +16155 - Beehive part - [null, null, null, null, null] +16156 - Beehive part - [null, null, null, null, null] +16157 - Beehive part - [null, null, null, null, null] +16158 - Beehive part - [null, null, null, null, null] +16159 - Interface surround - [null, null, null, null, null] +16160 - Button up - [null, null, null, null, null] +16161 - Button down - [null, null, null, null, null] +16162 - Button left - [null, null, null, null, null] +16163 - Button right - [null, null, null, null, null] +16164 - Button build - [null, null, null, null, null] +16165 - Beehive - [null, null, null, null, null] +16166 - null - [null, null, null, null, null] +16167 - null - [null, null, null, null, null] +16168 - null - [null, null, null, null, null] +16169 - Table - [null, null, null, null, null] +16170 - Table - [null, null, null, null, null] +16171 - null - [null, null, null, null, null] +16172 - Staircase - [Climb-down, null, null, null, null] +16173 - Staircase - [Climb-up, null, null, null, null] +16174 - Bone Chain - [Climb-down, null, null, null, null] +16175 - null - [null, null, null, null, null] +16176 - null - [null, null, null, null, null] +16177 - Waterlily - [null, null, null, null, null] +16178 - Waterlily - [null, null, null, null, null] +16179 - Waterlily - [null, null, null, null, null] +16180 - null - [null, null, null, null, null] +16181 - Fairy ring - [Use, null, null, null, null] +16182 - null - [null, null, null, null, null] +16183 - null - [null, null, null, null, null] +16184 - Fairy ring - [Use, null, null, null, null] +16185 - null - [null, null, null, null, null] +16186 - null - [null, null, null, null, null] +16187 - Cloud bank - [Enter-cloud, null, null, null, null] +16188 - null - [null, null, null, null, null] +16189 - Cloud bank - [Enter-cloud, null, null, null, null] +16190 - Lightning - [null, null, null, null, null] +16191 - Lightning - [null, null, null, null, null] +16192 - null - [null, null, null, null, null] +16193 - null - [null, null, null, null, null] +16194 - null - [null, null, null, null, null] +16195 - null - [null, null, null, null, null] +16196 - null - [null, null, null, null, null] +16197 - null - [null, null, null, null, null] +16198 - Lifeless Matter - [null, null, null, null, null] +16199 - Lifeless Matter - [null, null, null, null, null] +16200 - null - [null, null, null, null, null] +16201 - null - [null, null, null, null, null] +16202 - null - [null, null, null, null, null] +16203 - null - [null, null, null, null, null] +16204 - null - [null, null, null, null, null] +16205 - null - [null, null, null, null, null] +16206 - null - [null, null, null, null, null] +16207 - null - [null, null, null, null, null] +16208 - null - [null, null, null, null, null] +16209 - null - [null, null, null, null, null] +16210 - null - [null, null, null, null, null] +16211 - null - [null, null, null, null, null] +16212 - null - [null, null, null, null, null] +16213 - Fairy workbench - [Search, null, null, null, null] +16214 - null - [null, null, null, null, null] +16215 - Fairy workbench - [Search, null, null, null, null] +16216 - null - [null, null, null, null, null] +16217 - Potion shelves - [Search, null, null, null, null] +16218 - null - [null, null, null, null, null] +16219 - Potion shelves - [Search, null, null, null, null] +16220 - null - [null, null, null, null, null] +16221 - Potion shelf - [Search, null, null, null, null] +16222 - null - [null, null, null, null, null] +16223 - Potion shelf - [Search, null, null, null, null] +16224 - Healing certificate - [Take, null, null, null, null] +16225 - null - [null, null, null, null, null] +16226 - null - [null, null, null, null, null] +16227 - null - [null, null, null, null, null] +16228 - null - [null, null, null, null, null] +16229 - null - [null, null, null, null, null] +16230 - null - [null, null, null, null, null] +16231 - null - [null, null, null, null, null] +16232 - null - [null, null, null, null, null] +16233 - null - [null, null, null, null, null] +16234 - Hurt fairy - [null, null, null, null, null] +16235 - Injured fairy - [null, null, null, null, null] +16236 - Wounded fairy - [null, null, null, null, null] +16237 - Hurt fairy - [null, null, null, null, null] +16238 - Stretcher - [null, null, null, null, null] +16239 - First aid box - [null, null, null, null, null] +16240 - Crutch - [null, null, null, null, null] +16241 - Crutch - [null, null, null, null, null] +16242 - Crutch - [null, null, null, null, null] +16243 - null - [null, null, null, null, null] +16244 - Medical table - [null, null, null, null, null] +16245 - Map table - [null, null, null, null, null] +16246 - Stool - [null, null, null, null, null] +16247 - Wall map - [null, null, null, null, null] +16248 - Crate of wands - [null, null, null, null, null] +16249 - Crate - [null, null, null, null, null] +16250 - Crate - [Search, null, null, null, null] +16251 - Crates - [Search, null, null, null, null] +16252 - Crate - [Search, null, null, null, null] +16253 - Barrel - [null, null, null, null, null] +16254 - Tactical map frame - [null, null, null, null, null] +16255 - null - [null, null, null, null, null] +16256 - null - [null, null, null, null, null] +16257 - null - [null, null, null, null, null] +16258 - null - [null, null, null, null, null] +16259 - null - [null, null, null, null, null] +16260 - Stalagmite - [null, null, null, null, null] +16261 - Stalagmite - [null, null, null, null, null] +16262 - Stalagmite - [null, null, null, null, null] +16263 - Stalagmite - [null, null, null, null, null] +16264 - Tree - [Chop-down, null, null, null, null] +16265 - Tree - [Chop-down, null, null, null, null] +16266 - Tree Stump - [null, null, null, null, null] +16267 - Plant - [null, null, null, null, null] +16268 - Plant - [null, null, null, null, null] +16269 - Plant - [null, null, null, null, null] +16270 - Plant - [null, null, null, null, null] +16271 - null - [null, null, null, null, null] +16272 - null - [null, null, null, null, null] +16273 - null - [null, null, null, null, null] +16274 - null - [null, null, null, null, null] +16275 - null - [null, null, null, null, null] +16276 - null - [null, null, null, null, null] +16277 - null - [null, null, null, null, null] +16278 - null - [null, null, null, null, null] +16279 - null - [null, null, null, null, null] +16280 - null - [null, null, null, null, null] +16281 - null - [null, null, null, null, null] +16282 - null - [null, null, null, null, null] +16283 - Large rock - [null, null, null, null, null] +16284 - Large rock - [null, null, null, null, null] +16285 - null - [null, null, null, null, null] +16286 - null - [null, null, null, null, null] +16287 - null - [null, null, null, null, null] +16288 - null - [null, null, null, null, null] +16289 - null - [null, null, null, null, null] +16290 - null - [null, null, null, null, null] +16291 - null - [null, null, null, null, null] +16292 - null - [null, null, null, null, null] +16293 - null - [null, null, null, null, null] +16294 - null - [null, null, null, null, null] +16295 - null - [null, null, null, null, null] +16296 - null - [null, null, null, null, null] +16297 - null - [null, null, null, null, null] +16298 - null - [null, null, null, null, null] +16299 - null - [null, null, null, null, null] +16300 - null - [null, null, null, null, null] +16301 - null - [null, null, null, null, null] +16302 - Waterfall - [null, null, null, null, null] +16303 - Small rock - [null, null, null, null, null] +16304 - Stretcher - [null, null, null, null, null] +16305 - Fairy Queen - [null, null, null, null, null] +16306 - Fairy Queen - [null, null, null, null, null] +16307 - Rune temple sign - [Read, null, null, null, null] +16308 - Cave entrance - [Enter, null, null, null, null] +16309 - Cave entrance - [Enter, null, null, null, null] +16310 - null - [null, null, null, null, null] +16311 - null - [null, null, null, null, null] +16312 - null - [null, null, null, null, null] +16313 - null - [null, null, null, null, null] +16314 - null - [null, null, null, null, null] +16315 - null - [null, null, null, null, null] +16316 - null - [null, null, null, null, null] +16317 - null - [null, null, null, null, null] +16318 - null - [null, null, null, null, null] +16319 - null - [null, null, null, null, null] +16320 - null - [null, null, null, null, null] +16321 - null - [null, null, null, null, null] +16322 - null - [null, null, null, null, null] +16323 - null - [null, null, null, null, null] +16324 - null - [null, null, null, null, null] +16325 - null - [null, null, null, null, null] +16326 - null - [null, null, null, null, null] +16327 - null - [null, null, null, null, null] +16328 - null - [null, null, null, null, null] +16329 - null - [null, null, null, null, null] +16330 - null - [null, null, null, null, null] +16331 - null - [null, null, null, null, null] +16332 - null - [null, null, null, null, null] +16333 - null - [null, null, null, null, null] +16334 - null - [null, null, null, null, null] +16335 - null - [null, null, null, null, null] +16336 - null - [null, null, null, null, null] +16337 - null - [null, null, null, null, null] +16338 - null - [null, null, null, null, null] +16339 - null - [null, null, null, null, null] +16340 - null - [null, null, null, null, null] +16341 - null - [null, null, null, null, null] +16342 - null - [null, null, null, null, null] +16343 - null - [null, null, null, null, null] +16344 - null - [null, null, null, null, null] +16345 - null - [null, null, null, null, null] +16346 - null - [null, null, null, null, null] +16347 - null - [null, null, null, null, null] +16348 - null - [null, null, null, null, null] +16349 - null - [null, null, null, null, null] +16350 - null - [null, null, null, null, null] +16351 - null - [null, null, null, null, null] +16352 - null - [null, null, null, null, null] +16353 - null - [null, null, null, null, null] +16354 - null - [null, null, null, null, null] +16355 - null - [null, null, null, null, null] +16356 - null - [null, null, null, null, null] +16357 - null - [null, null, null, null, null] +16358 - null - [null, null, null, null, null] +16359 - null - [null, null, null, null, null] +16360 - null - [null, null, null, null, null] +16361 - null - [null, null, null, null, null] +16362 - null - [null, null, null, null, null] +16363 - null - [null, null, null, null, null] +16364 - null - [null, null, null, null, null] +16365 - null - [null, null, null, null, null] +16366 - null - [null, null, null, null, null] +16367 - null - [null, null, null, null, null] +16368 - null - [null, null, null, null, null] +16369 - null - [null, null, null, null, null] +16370 - null - [null, null, null, null, null] +16371 - null - [null, null, null, null, null] +16372 - null - [null, null, null, null, null] +16373 - null - [null, null, null, null, null] +16374 - Potion shelves - [null, null, null, null, null] +16375 - Potion shelves - [null, null, null, null, null] +16376 - Potion shelf - [null, null, null, null, null] +16377 - Potion shelf - [null, null, null, null, null] +16378 - Healing certificate - [Examine, null, null, null, null] +16379 - Healing certificate - [Examine, null, null, null, null] +16380 - null - [null, null, null, null, null] +16381 - null - [null, null, null, null, null] +16382 - null - [null, null, null, null, null] +16383 - null - [null, null, null, null, null] +16384 - null - [null, null, null, null, null] +16385 - null - [null, null, null, null, null] +16386 - null - [null, null, null, null, null] +16387 - null - [null, null, null, null, null] +16388 - null - [null, null, null, null, null] +16389 - null - [null, null, null, null, null] +16390 - null - [null, null, null, null, null] +16391 - null - [null, null, null, null, null] +16392 - null - [null, null, null, null, null] +16393 - null - [null, null, null, null, null] +16394 - null - [null, null, null, null, null] +16395 - null - [null, null, null, null, null] +16396 - null - [null, null, null, null, null] +16397 - null - [null, null, null, null, null] +16398 - null - [null, null, null, null, null] +16399 - null - [null, null, null, null, null] +16400 - null - [null, null, null, null, null] +16401 - null - [null, null, null, null, null] +16402 - null - [null, null, null, null, null] +16403 - null - [null, null, null, null, null] +16404 - null - [null, null, null, null, null] +16405 - null - [null, null, null, null, null] +16406 - null - [null, null, null, null, null] +16407 - null - [null, null, null, null, null] +16408 - null - [null, null, null, null, null] +16409 - null - [null, null, null, null, null] +16410 - null - [null, null, null, null, null] +16411 - null - [null, null, null, null, null] +16412 - null - [null, null, null, null, null] +16413 - null - [null, null, null, null, null] +16414 - null - [null, null, null, null, null] +16415 - null - [null, null, null, null, null] +16416 - null - [null, null, null, null, null] +16417 - null - [null, null, null, null, null] +16418 - null - [null, null, null, null, null] +16419 - null - [null, null, null, null, null] +16420 - null - [null, null, null, null, null] +16421 - null - [null, null, null, null, null] +16422 - null - [null, null, null, null, null] +16423 - null - [null, null, null, null, null] +16424 - null - [null, null, null, null, null] +16425 - null - [null, null, null, null, null] +16426 - null - [null, null, null, null, null] +16427 - null - [null, null, null, null, null] +16428 - null - [null, null, null, null, null] +16429 - null - [null, null, null, null, null] +16430 - null - [null, null, null, null, null] +16431 - null - [null, null, null, null, null] +16432 - null - [null, null, null, null, null] +16433 - null - [null, null, null, null, null] +16434 - null - [null, null, null, null, null] +16435 - null - [null, null, null, null, null] +16436 - null - [null, null, null, null, null] +16437 - null - [null, null, null, null, null] +16438 - null - [null, null, null, null, null] +16439 - null - [null, null, null, null, null] +16440 - null - [null, null, null, null, null] +16441 - null - [null, null, null, null, null] +16442 - null - [null, null, null, null, null] +16443 - null - [null, null, null, null, null] +16444 - null - [null, null, null, null, null] +16445 - null - [null, null, null, null, null] +16446 - null - [null, null, null, null, null] +16447 - null - [null, null, null, null, null] +16448 - null - [null, null, null, null, null] +16449 - null - [null, null, null, null, null] +16450 - Ladder - [Climb-up, null, null, null, null] +16451 - null - [null, null, null, null, null] +16452 - null - [null, null, null, null, null] +16453 - null - [null, null, null, null, null] +16454 - null - [null, null, null, null, null] +16455 - null - [null, null, null, null, null] +16456 - null - [null, null, null, null, null] +16457 - null - [null, null, null, null, null] +16458 - Tomb Door - [Leave Tomb, null, null, null, null] +16459 - Tomb Door - [Leave Tomb, null, null, null, null] +16460 - null - [null, null, null, null, null] +16461 - null - [null, null, null, null, null] +16462 - null - [null, null, null, null, null] +16463 - null - [null, null, null, null, null] +16464 - null - [null, null, null, null, null] +16465 - null - [null, null, null, null, null] +16466 - null - [null, null, null, null, null] +16467 - null - [null, null, null, null, null] +16468 - null - [null, null, null, null, null] +16469 - null - [null, null, null, null, null] +16470 - null - [null, null, null, null, null] +16471 - null - [null, null, null, null, null] +16472 - null - [null, null, null, null, null] +16473 - Grand Gold Chest - [Search, null, null, null, null] +16474 - Opened gold chest - [null, null, null, null, null] +16475 - Tomb Door - [Pick-lock, null, null, null, null] +16476 - Tomb Door - [Enter, null, null, null, null] +16477 - null - [null, null, null, null, null] +16478 - null - [null, null, null, null, null] +16479 - null - [null, null, null, null, null] +16480 - Bust - [null, null, null, null, null] +16481 - Bust - [null, null, null, null, null] +16482 - Obelisk - [null, null, null, null, null] +16483 - An anonymous looking door - [null, null, null, null, null] +16484 - An anonymous looking door - [Search, null, null, null, null] +16485 - An anonymous looking door - [Search, null, null, null, null] +16486 - An anonymous looking door - [null, null, null, null, null] +16487 - An anonymous looking door - [Search, null, null, null, null] +16488 - An anonymous looking door - [Search, null, null, null, null] +16489 - An anonymous looking door - [null, null, null, null, null] +16490 - An anonymous looking door - [Search, null, null, null, null] +16491 - An anonymous looking door - [Search, null, null, null, null] +16492 - An anonymous looking door - [null, null, null, null, null] +16493 - An anonymous looking door - [Search, null, null, null, null] +16494 - An anonymous looking door - [Enter, null, null, null, null] +16495 - Sarcophagus - [Open, null, null, null, null] +16496 - Sarcophagus - [Search, null, null, null, null] +16497 - Sarcophagus - [null, null, null, null, null] +16498 - Sarcophagus - [null, null, null, null, null] +16499 - Sarcophagus - [null, null, null, null, null] +16500 - Sarcophagus - [null, null, null, null, null] +16501 - Urn - [Search, Check for Snakes, null, null, null] +16502 - Urn - [Search, Check for Snakes, null, null, null] +16503 - Urn - [Search, Check for Snakes, null, null, null] +16504 - Urn - [null, null, null, null, null] +16505 - Urn - [Search, null, null, null, null] +16506 - Urn - [Search, null, null, null, null] +16507 - Urn - [Search, null, null, null, null] +16508 - Urn - [null, null, null, null, null] +16509 - Urn - [Search, null, Charm Snake, null, null] +16510 - Urn - [Search, null, Charm Snake, null, null] +16511 - Urn - [Search, null, Charm Snake, null, null] +16512 - Urn - [Search, null, Charm Snake, null, null] +16513 - Urn - [Search, null, null, null, null] +16514 - Urn - [Search, null, null, null, null] +16515 - Urn - [Search, null, null, null, null] +16516 - Urn - [Search, null, null, null, null] +16517 - Speartrap - [Pass, null, null, null, null] +16518 - null - [null, null, null, null, null] +16519 - null - [null, null, null, null, null] +16520 - null - [null, null, null, null, null] +16521 - null - [null, null, null, null, null] +16522 - null - [null, null, null, null, null] +16523 - null - [null, null, null, null, null] +16524 - null - [null, null, null, null, null] +16525 - null - [null, null, null, null, null] +16526 - null - [null, null, null, null, null] +16527 - null - [null, null, null, null, null] +16528 - null - [null, null, null, null, null] +16529 - null - [null, null, null, null, null] +16530 - null - [null, null, null, null, null] +16531 - null - [null, null, null, null, null] +16532 - null - [null, null, null, null, null] +16533 - null - [null, null, null, null, null] +16534 - null - [null, null, null, null, null] +16535 - Climbing rocks - [Climb, null, null, null, null] +16536 - Climbing rocks - [Climb, null, null, null, null] +16537 - null - [null, null, null, null, null] +16538 - null - [null, null, null, null, null] +16539 - null - [null, null, null, null, null] +16540 - null - [null, null, null, null, null] +16541 - null - [null, null, null, null, null] +16542 - null - [null, null, null, null, null] +16543 - null - [null, null, null, null, null] +16544 - null - [null, null, null, null, null] +16545 - null - [null, null, null, null, null] +16546 - null - [null, null, null, null, null] +16547 - null - [null, null, null, null, null] +16548 - null - [null, null, null, null, null] +16549 - null - [null, null, null, null, null] +16550 - null - [null, null, null, null, null] +16551 - null - [null, null, null, null, null] +16552 - null - [null, null, null, null, null] +16553 - null - [null, null, null, null, null] +16554 - null - [null, null, null, null, null] +16555 - null - [null, null, null, null, null] +16556 - Ladder - [Climb-down, null, null, null, null] +16557 - Ladder - [null, null, null, null, null] +16558 - Changing Curtain - [null, null, null, null, null] +16559 - Crate - [Search, null, null, null, null] +16560 - Crate - [Search, null, null, null, null] +16561 - Crate - [Search, null, null, null, null] +16562 - Table - [null, null, null, null, null] +16563 - null - [null, null, null, null, null] +16564 - Crate - [Search, null, null, null, null] +16565 - Crate - [Search, null, null, null, null] +16566 - Barrel - [null, null, null, null, null] +16567 - null - [null, null, null, null, null] +16568 - Standard - [null, null, null, null, null] +16569 - Standard - [null, null, null, null, null] +16570 - null - [null, null, null, null, null] +16571 - null - [null, null, null, null, null] +16572 - null - [null, null, null, null, null] +16573 - Timber defence - [null, null, null, null, null] +16574 - null - [null, null, null, null, null] +16575 - null - [null, null, null, null, null] +16576 - Rocks - [Mine, Prospect, hidden, null, null] +16577 - Rocks - [Mine, Prospect, hidden, null, null] +16578 - Rocks - [Mine, Prospect, hidden, null, null] +16579 - Rocks - [Mine, Prospect, hidden, null, null] +16580 - Rocks - [Mine, Prospect, hidden, null, null] +16581 - Rocks - [Mine, Prospect, hidden, null, null] +16582 - Rocks - [Mine, Prospect, hidden, null, null] +16583 - Rocks - [Mine, Prospect, hidden, null, null] +16584 - Rocks - [Mine, Prospect, hidden, null, null] +16585 - Log pile - [Deposit, null, null, null, null] +16586 - Log pile - [Deposit, null, null, null, null] +16587 - Log pile - [Deposit, null, null, null, null] +16588 - Log pile - [Deposit, null, null, null, null] +16589 - Log pile - [Deposit, null, null, null, null] +16590 - Log pile - [Deposit, null, null, null, null] +16591 - Log pile - [Deposit, null, null, null, null] +16592 - Log pile - [Deposit, null, null, null, null] +16593 - Log pile - [Deposit, null, null, null, null] +16594 - Log pile - [Deposit, null, null, null, null] +16595 - null - [null, null, null, null, null] +16596 - null - [null, null, null, null, null] +16597 - null - [null, null, null, null, null] +16598 - Dream puff - [null, null, null, null, null] +16599 - My life - [Read, null, null, null, null] +16600 - Hurdle - [Jump-over, null, null, null, null] +16601 - Note - [null, null, null, null, null] +16602 - Note - [null, null, null, null, null] +16603 - null - [null, null, null, null, null] +16604 - Dream tree - [Chop, null, null, null, null] +16605 - Dream Tree stump - [null, null, null, null, null] +16606 - null - [null, null, null, null, null] +16607 - null - [null, null, null, null, null] +16608 - null - [null, null, null, null, null] +16609 - null - [null, null, null, null, null] +16610 - null - [null, null, null, null, null] +16611 - null - [null, null, null, null, null] +16612 - null - [null, null, null, null, null] +16613 - null - [null, null, null, null, null] +16614 - null - [null, null, null, null, null] +16615 - null - [null, null, null, null, null] +16616 - null - [null, null, null, null, null] +16617 - null - [null, null, null, null, null] +16618 - null - [null, null, null, null, null] +16619 - Zero - [Press, null, null, null, null] +16620 - One - [Press, null, null, null, null] +16621 - Two - [Press, null, null, null, null] +16622 - Three - [Press, null, null, null, null] +16623 - Four - [Press, null, null, null, null] +16624 - Five - [Press, null, null, null, null] +16625 - Six - [Press, null, null, null, null] +16626 - Seven - [Press, null, null, null, null] +16627 - Eight - [Press, null, null, null, null] +16628 - Nine - [Press, null, null, null, null] +16629 - null - [null, null, null, null, null] +16630 - null - [null, null, null, null, null] +16631 - null - [null, null, null, null, null] +16632 - Platform - [Step-on, null, null, null, null] +16633 - Platform - [Step-on, null, null, null, null] +16634 - Platform - [Step-on, null, null, null, null] +16635 - Platform - [Step-on, null, null, null, null] +16636 - Platform - [Step-on, null, null, null, null] +16637 - Platform - [Step-on, null, null, null, null] +16638 - Dream puff - [Jump-to, null, null, null, null] +16639 - Windswept Tree - [null, null, null, null, null] +16640 - Ladder - [Climb-up, null, null, null, null] +16641 - Ladder - [Climb-down, null, null, null, null] +16642 - null - [null, null, null, null, null] +16643 - Water Source - [null, null, null, null, null] +16644 - null - [null, null, null, null, null] +16645 - null - [null, null, null, null, null] +16646 - null - [null, null, null, null, null] +16647 - null - [null, null, null, null, null] +16648 - null - [null, null, null, null, null] +16649 - null - [null, null, null, null, null] +16650 - null - [null, null, null, null, null] +16651 - null - [null, null, null, null, null] +16652 - null - [null, null, null, null, null] +16653 - null - [null, null, null, null, null] +16654 - null - [null, null, null, null, null] +16655 - null - [null, null, null, null, null] +16656 - null - [null, null, null, null, null] +16657 - null - [null, null, null, null, null] +16658 - null - [null, null, null, null, null] +16659 - null - [null, null, null, null, null] +16660 - null - [null, null, null, null, null] +16661 - null - [null, null, null, null, null] +16662 - null - [null, null, null, null, null] +16663 - null - [null, null, null, null, null] +16664 - null - [null, null, null, null, null] +16665 - null - [null, null, null, null, null] +16666 - null - [null, null, null, null, null] +16667 - null - [null, null, null, null, null] +16668 - null - [null, null, null, null, null] +16669 - null - [null, null, null, null, null] +16670 - null - [null, null, null, null, null] +16671 - null - [null, null, null, null, null] +16672 - null - [null, null, null, null, null] +16673 - null - [null, null, null, null, null] +16674 - null - [null, null, null, null, null] +16675 - null - [null, null, null, null, null] +16676 - null - [null, null, null, null, null] +16677 - null - [null, null, null, null, null] +16678 - null - [null, null, null, null, null] +16679 - Stalagmites - [Mine, null, null, null, null] +16680 - Stalagmite - [Mine, null, null, null, null] +16681 - null - [null, null, null, null, null] +16682 - null - [null, null, null, null, null] +16683 - null - [null, null, null, null, null] +16684 - Rock - [Mine, Prospect, hidden, null, null] +16685 - null - [null, null, null, null, null] +16686 - Portal - [Use, null, null, null, null] +16687 - Rune essence - [Mine, Prospect, hidden, null, null] +16688 - Tar Barrel - [null, null, null, null, null] +16689 - Tanning Barrel - [null, null, null, null, null] +16690 - null - [null, null, null, null, null] +16691 - Hat rack - [null, null, null, null, null] +16692 - Hat rack - [null, null, null, null, null] +16693 - Clothes rack - [null, null, null, null, null] +16694 - null - [null, null, null, null, null] +16695 - Bank chest - [null, null, null, null, null] +16696 - Bank chest - [null, null, null, null, null] +16697 - Chest - [null, null, null, null, null] +16698 - null - [null, null, null, null, null] +16699 - null - [null, null, null, null, null] +16700 - Bank booth - [Use, Use-quickly, Collect, null, null] +16701 - Light - [null, null, null, null, null] +16702 - Cooker - [null, null, null, null, null] +16703 - Cooker - [null, null, null, null, null] +16704 - Sink - [null, null, null, null, null] +16705 - Sink - [null, null, null, null, null] +16706 - Bench - [null, null, null, null, null] +16707 - Bookcase - [null, null, null, null, null] +16708 - Tall mirror - [Admire, null, null, null, null] +16709 - null - [null, null, null, null, null] +16710 - null - [null, null, null, null, null] +16711 - null - [null, null, null, null, null] +16712 - null - [null, null, null, null, null] +16713 - null - [null, null, null, null, null] +16714 - Bags for sale - [null, null, null, null, null] +16715 - Bags for sale - [null, null, null, null, null] +16716 - null - [null, null, null, null, null] +16717 - null - [null, null, null, null, null] +16718 - null - [null, null, null, null, null] +16719 - Bed - [null, null, null, null, null] +16720 - Bed - [null, null, null, null, null] +16721 - Bed - [null, null, null, null, null] +16722 - null - [null, null, null, null, null] +16723 - null - [null, null, null, null, null] +16724 - null - [null, null, null, null, null] +16725 - null - [null, null, null, null, null] +16726 - null - [null, null, null, null, null] +16727 - null - [null, null, null, null, null] +16728 - null - [null, null, null, null, null] +16729 - Flowers - [null, null, null, null, null] +16730 - Flowers - [null, null, null, null, null] +16731 - Flowers - [null, null, null, null, null] +16732 - Stairs - [Climb-down, null, null, null, null] +16733 - Stairs - [Climb-down, null, null, null, null] +16734 - Stairs - [Climb-up, null, null, null, null] +16735 - Ladder - [Climb-up, null, null, null, null] +16736 - Ladder - [Climb-down, null, null, null, null] +16737 - Table - [null, null, null, null, null] +16738 - Table - [null, null, null, null, null] +16739 - Table - [null, null, null, null, null] +16740 - Table - [null, null, null, null, null] +16741 - Table - [null, null, null, null, null] +16742 - Table - [null, null, null, null, null] +16743 - Chair - [null, null, null, null, null] +16744 - Chair - [null, null, null, null, null] +16745 - Stool - [null, null, null, null, null] +16746 - null - [null, null, null, null, null] +16747 - null - [null, null, null, null, null] +16748 - null - [null, null, null, null, null] +16749 - null - [null, null, null, null, null] +16750 - null - [null, null, null, null, null] +16751 - null - [null, null, null, null, null] +16752 - null - [null, null, null, null, null] +16753 - null - [null, null, null, null, null] +16754 - null - [null, null, null, null, null] +16755 - null - [null, null, null, null, null] +16756 - null - [null, null, null, null, null] +16757 - null - [null, null, null, null, null] +16758 - null - [null, null, null, null, null] +16759 - null - [null, null, null, null, null] +16760 - null - [null, null, null, null, null] +16761 - null - [null, null, null, null, null] +16762 - null - [null, null, null, null, null] +16763 - null - [null, null, null, null, null] +16764 - null - [null, null, null, null, null] +16765 - null - [null, null, null, null, null] +16766 - null - [null, null, null, null, null] +16767 - null - [null, null, null, null, null] +16768 - null - [null, null, null, null, null] +16769 - null - [null, null, null, null, null] +16770 - null - [null, null, null, null, null] +16771 - null - [null, null, null, null, null] +16772 - null - [null, null, null, null, null] +16773 - null - [null, null, null, null, null] +16774 - Door - [Open, null, null, null, null] +16775 - null - [null, null, null, null, null] +16776 - Door - [Open, null, null, null, null] +16777 - Door - [Close, null, null, null, null] +16778 - Door - [Open, null, null, null, null] +16779 - Door - [Close, null, null, null, null] +16780 - null - [null, null, null, null, null] +16781 - null - [null, null, null, null, null] +16782 - null - [null, null, null, null, null] +16783 - null - [null, null, null, null, null] +16784 - null - [null, null, null, null, null] +16785 - null - [null, null, null, null, null] +16786 - null - [null, null, null, null, null] +16787 - null - [null, null, null, null, null] +16788 - null - [null, null, null, null, null] +16789 - null - [null, null, null, null, null] +16790 - null - [null, null, null, null, null] +16791 - null - [null, null, null, null, null] +16792 - null - [null, null, null, null, null] +16793 - null - [null, null, null, null, null] +16794 - null - [null, null, null, null, null] +16795 - null - [null, null, null, null, null] +16796 - null - [null, null, null, null, null] +16797 - null - [null, null, null, null, null] +16798 - null - [null, null, null, null, null] +16799 - null - [null, null, null, null, null] +16800 - null - [null, null, null, null, null] +16801 - null - [null, null, null, null, null] +16802 - null - [null, null, null, null, null] +16803 - null - [null, null, null, null, null] +16804 - null - [null, null, null, null, null] +16805 - null - [null, null, null, null, null] +16806 - null - [null, null, null, null, null] +16807 - null - [null, null, null, null, null] +16808 - Ceremonial Brazier - [null, null, null, null, null] +16809 - Ceremonial Brazier - [null, null, null, null, null] +16810 - Ceremonial Brazier - [null, null, null, null, null] +16811 - Ceremonial Brazier - [null, null, null, null, null] +16812 - Cooker - [null, null, null, null, null] +16813 - Rack - [null, null, null, null, null] +16814 - Stool - [null, null, null, null, null] +16815 - Table - [null, null, null, null, null] +16816 - null - [null, null, null, null, null] +16817 - null - [null, null, null, null, null] +16818 - null - [null, null, null, null, null] +16819 - null - [null, null, null, null, null] +16820 - null - [null, null, null, null, null] +16821 - null - [null, null, null, null, null] +16822 - null - [null, null, null, null, null] +16823 - null - [null, null, null, null, null] +16824 - null - [null, null, null, null, null] +16825 - null - [null, null, null, null, null] +16826 - null - [null, null, null, null, null] +16827 - Table - [null, null, null, null, null] +16828 - Table - [null, null, null, null, null] +16829 - Transport platform - [Step-on, null, null, null, null] +16830 - null - [null, null, null, null, null] +16831 - Transport platform - [Step-on, null, null, null, null] +16832 - null - [null, null, null, null, null] +16833 - Transport platform - [Step-on, null, null, null, null] +16834 - null - [null, null, null, null, null] +16835 - Transport platform - [Step-on, null, null, null, null] +16836 - null - [null, null, null, null, null] +16837 - Transport platform - [Step-on, null, null, null, null] +16838 - null - [null, null, null, null, null] +16839 - Transport platform - [Step-on, null, null, null, null] +16840 - null - [null, null, null, null, null] +16841 - Transport platform - [Step-on, null, null, null, null] +16842 - null - [null, null, null, null, null] +16843 - Dice - [Roll, null, null, null, null] +16844 - Dice - [Roll, null, null, null, null] +16845 - Dice - [Roll, null, null, null, null] +16846 - Dice - [Roll, null, null, null, null] +16847 - Dice - [Roll, null, null, null, null] +16848 - Dice - [Roll, null, null, null, null] +16849 - Dice - [null, null, null, null, null] +16850 - Dice - [null, null, null, null, null] +16851 - Dice - [null, null, null, null, null] +16852 - Dice - [null, null, null, null, null] +16853 - Dice - [null, null, null, null, null] +16854 - Dice - [null, null, null, null, null] +16855 - Dice - [null, null, null, null, null] +16856 - Dream puff - [null, null, null, null, null] +16857 - Dream puff - [null, null, null, null, null] +16858 - Platform edge - [Jump-to, null, null, null, null] +16859 - Hanging pirate - [null, null, null, null, null] +16860 - Tar barrel - [Take-from, null, null, null, null] +16861 - Hammock - [null, null, null, null, null] +16862 - Crate - [null, null, null, null, null] +16863 - Crate - [null, null, null, null, null] +16864 - Crate - [null, null, null, null, null] +16865 - Crate - [null, null, null, null, null] +16866 - Sack pile - [null, null, null, null, null] +16867 - Sack pile - [null, null, null, null, null] +16868 - Sack pile - [null, null, null, null, null] +16869 - Sack pile - [null, null, null, null, null] +16870 - Sack pile - [null, null, null, null, null] +16871 - Sack pile - [null, null, null, null, null] +16872 - Fish bits - [null, null, null, null, null] +16873 - Fish bits - [null, null, null, null, null] +16874 - Table - [null, null, null, null, null] +16875 - Stool - [null, null, null, null, null] +16876 - Barrel - [null, null, null, null, null] +16877 - Barrel - [null, null, null, null, null] +16878 - Sack - [null, null, null, null, null] +16879 - Cannonballs - [null, null, null, null, null] +16880 - Cannonballs - [null, null, null, null, null] +16881 - Barrel - [null, null, null, null, null] +16882 - Barrel - [null, null, null, null, null] +16883 - Barrel - [null, null, null, null, null] +16884 - Barrel - [Take-from, null, null, null, null] +16885 - Barrel - [Take-from, null, null, null, null] +16886 - Barrel - [null, null, null, null, null] +16887 - Wooden chest - [null, null, null, null, null] +16888 - Wooden chest - [null, null, null, null, null] +16889 - Wooden chest - [null, null, null, null, null] +16890 - Chest - [null, null, null, null, null] +16891 - Chest - [null, null, null, null, null] +16892 - null - [null, null, null, null, null] +16893 - Cooking range - [null, null, null, null, null] +16894 - Extra anchor - [null, null, null, null, null] +16895 - Extra chain - [null, null, null, null, null] +16896 - null - [null, null, null, null, null] +16897 - null - [null, null, null, null, null] +16898 - null - [null, null, null, null, null] +16899 - Wooden table - [null, null, null, null, null] +16900 - Chair - [null, null, null, null, null] +16901 - Lantern - [null, null, null, null, null] +16902 - Door - [Open, null, null, null, null] +16903 - Door - [Close, null, null, null, null] +16904 - null - [null, null, null, null, null] +16905 - null - [null, null, null, null, null] +16906 - Wheel - [null, null, null, null, null] +16907 - null - [null, null, null, null, null] +16908 - null - [null, null, null, null, null] +16909 - null - [null, null, null, null, null] +16910 - null - [null, null, null, null, null] +16911 - null - [null, null, null, null, null] +16912 - null - [null, null, null, null, null] +16913 - null - [null, null, null, null, null] +16914 - null - [null, null, null, null, null] +16915 - null - [null, null, null, null, null] +16916 - null - [null, null, null, null, null] +16917 - null - [null, null, null, null, null] +16918 - null - [null, null, null, null, null] +16919 - null - [null, null, null, null, null] +16920 - null - [null, null, null, null, null] +16921 - null - [null, null, null, null, null] +16922 - null - [null, null, null, null, null] +16923 - null - [null, null, null, null, null] +16924 - null - [null, null, null, null, null] +16925 - null - [null, null, null, null, null] +16926 - null - [null, null, null, null, null] +16927 - null - [null, null, null, null, null] +16928 - null - [null, null, null, null, null] +16929 - null - [null, null, null, null, null] +16930 - null - [null, null, null, null, null] +16931 - null - [null, null, null, null, null] +16932 - null - [null, null, null, null, null] +16933 - null - [null, null, null, null, null] +16934 - null - [null, null, null, null, null] +16935 - null - [null, null, null, null, null] +16936 - null - [null, null, null, null, null] +16937 - null - [null, null, null, null, null] +16938 - Cannon - [null, null, null, null, null] +16939 - Cannon - [null, null, null, null, null] +16940 - null - [null, null, null, null, null] +16941 - Support - [null, null, null, null, null] +16942 - null - [null, null, null, null, null] +16943 - null - [null, null, null, null, null] +16944 - null - [null, null, null, null, null] +16945 - Stairs - [Climb, null, null, null, null] +16946 - Stairs - [Climb, null, null, null, null] +16947 - Stairs - [Climb, null, null, null, null] +16948 - Stairs - [Climb, null, null, null, null] +16949 - null - [null, null, null, null, null] +16950 - null - [null, null, null, null, null] +16951 - Support - [null, null, null, null, null] +16952 - Support - [null, null, null, null, null] +16953 - Cannon - [null, null, null, null, null] +16954 - Crate - [null, null, null, null, null] +16955 - Wall chart - [null, null, null, null, null] +16956 - Chest - [null, null, null, null, null] +16957 - Crane - [null, null, null, null, null] +16958 - Row boat - [null, null, null, null, null] +16959 - Ladder - [Climb, null, null, null, null] +16960 - Ladder - [Climb, null, null, null, null] +16961 - Ladder - [Climb, null, null, null, null] +16962 - Ladder - [Climb, null, null, null, null] +16963 - null - [null, null, null, null, null] +16964 - null - [null, null, null, null, null] +16965 - null - [null, null, null, null, null] +16966 - null - [null, null, null, null, null] +16967 - null - [null, null, null, null, null] +16968 - Shelf - [null, null, null, null, null] +16969 - Shelf - [null, null, null, null, null] +16970 - Shelf - [null, null, null, null, null] +16971 - Shelf - [null, null, null, null, null] +16972 - Shelf - [null, null, null, null, null] +16973 - Shelf - [null, null, null, null, null] +16974 - Table - [null, null, null, null, null] +16975 - Wallchart - [null, null, null, null, null] +16976 - null - [null, null, null, null, null] +16977 - null - [null, null, null, null, null] +16978 - Chart - [null, null, null, null, null] +16979 - Chart - [null, null, null, null, null] +16980 - Chart - [null, null, null, null, null] +16981 - Scrolls - [null, null, null, null, null] +16982 - null - [null, null, null, null, null] +16983 - null - [null, null, null, null, null] +16984 - null - [null, null, null, null, null] +16985 - null - [null, null, null, null, null] +16986 - null - [null, null, null, null, null] +16987 - null - [null, null, null, null, null] +16988 - null - [null, null, null, null, null] +16989 - null - [null, null, null, null, null] +16990 - null - [null, null, null, null, null] +16991 - null - [null, null, null, null, null] +16992 - null - [null, null, null, null, null] +16993 - null - [null, null, null, null, null] +16994 - null - [null, null, null, null, null] +16995 - null - [null, null, null, null, null] +16996 - null - [null, null, null, null, null] +16997 - null - [null, null, null, null, null] +16998 - Rocks - [Mine, Prospect, hidden, null, null] +16999 - Rocks - [Mine, Prospect, hidden, null, null] +17000 - Rocks - [Mine, Prospect, hidden, null, null] +17001 - Rocks - [Mine, Prospect, hidden, null, null] +17002 - Rocks - [Mine, Prospect, hidden, null, null] +17003 - Rocks - [Mine, Prospect, hidden, null, null] +17004 - Rocks - [Mine, Prospect, hidden, null, null] +17005 - Rocks - [Mine, Prospect, hidden, null, null] +17006 - Rocks - [Mine, Prospect, hidden, null, null] +17007 - Rocks - [Mine, Prospect, hidden, null, null] +17008 - Rocks - [Mine, Prospect, hidden, null, null] +17009 - Rocks - [Mine, Prospect, hidden, null, null] +17010 - Altar - [Craft-rune, Pray, null, null, null] +17011 - Pillar - [null, null, null, null, null] +17012 - Pillar - [null, null, null, null, null] +17013 - Pillar - [null, null, null, null, null] +17014 - null - [null, null, null, null, null] +17015 - null - [null, null, null, null, null] +17016 - null - [null, null, null, null, null] +17017 - null - [null, null, null, null, null] +17018 - null - [null, null, null, null, null] +17019 - null - [null, null, null, null, null] +17020 - null - [null, null, null, null, null] +17021 - null - [null, null, null, null, null] +17022 - null - [null, null, null, null, null] +17023 - null - [null, null, null, null, null] +17024 - null - [null, null, null, null, null] +17025 - null - [null, null, null, null, null] +17026 - Rocks - [Mine, Prospect, hidden, null, null] +17027 - Rocks - [Mine, Prospect, hidden, null, null] +17028 - Rocks - [Mine, Prospect, hidden, null, null] +17029 - null - [null, null, null, null, null] +17030 - null - [null, null, null, null, null] +17031 - Crossbow stall - [null, Steal-from, null, null, null] +17032 - null - [null, null, null, null, null] +17033 - Crate - [null, null, null, null, null] +17034 - null - [null, null, null, null, null] +17035 - null - [null, null, null, null, null] +17036 - Strong Tree - [null, null, null, null, null] +17037 - Strong Tree - [null, null, null, null, null] +17038 - Strong Tree - [null, null, null, null, null] +17039 - Strong Yew - [null, null, null, null, null] +17040 - Strong Yew - [null, null, null, null, null] +17041 - Strong Yew - [null, null, null, null, null] +17042 - Rocks - [Grapple, null, null, null, null] +17043 - Rocks - [Grapple, null, null, null, null] +17044 - null - [null, null, null, null, null] +17045 - null - [null, null, null, null, null] +17046 - Strong Tree - [Grapple, null, null, null, null] +17047 - Wall - [Grapple, null, null, null, null] +17048 - Wall - [Jump, null, null, null, null] +17049 - Wall - [Grapple, null, null, null, null] +17050 - Wall - [Grapple, null, null, null, null] +17051 - Wall - [Jump, null, null, null, null] +17052 - Wall - [Jump, null, null, null, null] +17053 - null - [null, null, null, null, null] +17054 - null - [null, null, null, null, null] +17055 - null - [null, null, null, null, null] +17056 - Crossbow Tree - [null, null, null, null, null] +17057 - Crossbow Tree - [null, null, null, null, null] +17058 - Crossbow Tree - [null, null, null, null, null] +17059 - Crossbow Tree - [null, null, null, null, null] +17060 - Crossbow Tree - [null, null, null, null, null] +17061 - Crossbow Tree - [null, null, null, null, null] +17062 - Crossbow Tree - [Grapple, null, null, null, null] +17063 - Crossbow Tree - [null, null, null, null, null] +17064 - Rocks - [null, null, null, null, null] +17065 - Rocks - [null, null, null, null, null] +17066 - null - [null, null, null, null, null] +17067 - null - [null, null, null, null, null] +17068 - Broken Raft - [Grapple, null, null, null, null] +17069 - Broken Raft - [null, null, null, null, null] +17070 - Broken Raft - [null, null, null, null, null] +17071 - Broken Raft - [null, null, null, null, null] +17072 - null - [null, null, null, null, null] +17073 - null - [null, null, null, null, null] +17074 - Strong Tree - [Grapple, null, null, null, null] +17075 - Strong Tree - [Grapple, null, null, null, null] +17076 - Strong Tree - [Grapple, null, null, null, null] +17077 - Strong Tree - [Grapple, null, null, null, null] +17078 - null - [null, null, null, null, null] +17079 - null - [null, null, null, null, null] +17080 - Strong Tree - [Grapple, null, null, null, null] +17081 - Strong Tree - [Grapple, null, null, null, null] +17082 - null - [null, null, null, null, null] +17083 - null - [null, null, null, null, null] +17084 - null - [null, null, null, null, null] +17085 - null - [null, null, null, null, null] +17086 - null - [null, null, null, null, null] +17087 - null - [null, null, null, null, null] +17088 - null - [null, null, null, null, null] +17089 - Large door - [Open, null, null, null, null] +17090 - Large door - [Close, null, null, null, null] +17091 - Large door - [Open, null, null, null, null] +17092 - Large door - [Close, null, null, null, null] +17093 - Large door - [Open, null, null, null, null] +17094 - Large door - [Close, null, null, null, null] +17095 - Shelf - [null, null, null, null, null] +17096 - Shelf - [null, null, null, null, null] +17097 - Shelf - [null, null, null, null, null] +17098 - Stool - [null, null, null, null, null] +17099 - Table - [null, null, null, null, null] +17100 - Crate - [Search, null, null, null, null] +17101 - Crate - [Search, null, null, null, null] +17102 - null - [null, null, null, null, null] +17103 - null - [null, null, null, null, null] +17104 - null - [null, null, null, null, null] +17105 - null - [null, null, null, null, null] +17106 - null - [null, null, null, null, null] +17107 - null - [null, null, null, null, null] +17108 - null - [null, null, null, null, null] +17109 - null - [null, null, null, null, null] +17110 - null - [null, null, null, null, null] +17111 - null - [null, null, null, null, null] +17112 - null - [null, null, null, null, null] +17113 - null - [null, null, null, null, null] +17114 - Door - [Open, null, null, null, null] +17115 - Door - [Close, null, null, null, null] +17116 - Pool of Slime - [null, null, null, null, null] +17117 - Pool of Slime - [null, null, null, null, null] +17118 - Pool of Slime - [null, null, null, null, null] +17119 - Pool of Slime - [null, null, null, null, null] +17120 - Ladder - [Climb-up, null, null, null, null] +17121 - Ladder - [Climb, Climb-up, Climb-down, null, null] +17122 - Ladder - [Climb-down, null, null, null, null] +17123 - null - [null, null, null, null, null] +17124 - null - [null, null, null, null, null] +17125 - Gnome chair - [null, null, null, null, null] +17126 - Gnome table - [null, null, null, null, null] +17127 - Gnome table - [null, null, null, null, null] +17128 - Gnome table - [null, null, null, null, null] +17129 - Gnome table - [null, null, null, null, null] +17130 - Office table - [null, null, null, null, null] +17131 - Gnome cooker - [null, null, null, null, null] +17132 - Kitchen cabinet - [Search, null, null, null, null] +17133 - Gnome cabinet - [null, null, null, null, null] +17134 - Gnome barrel - [null, null, null, null, null] +17135 - Gnome barrels - [null, null, null, null, null] +17136 - Gnome crates - [null, null, null, null, null] +17137 - Gnome crate - [null, null, null, null, null] +17138 - null - [null, null, null, null, null] +17139 - null - [null, null, null, null, null] +17140 - Oaknock statue - [null, null, null, null, null] +17141 - Healthorg statue - [null, null, null, null, null] +17142 - null - [null, null, null, null, null] +17143 - Staircase - [Climb-up, null, null, null, null] +17144 - Boxes - [Search, null, null, null, null] +17145 - Table - [null, null, null, null, null] +17146 - Chair - [null, null, null, null, null] +17147 - null - [null, null, null, null, null] +17148 - Ladder - [Climb-up, null, null, null, null] +17149 - Ladder - [Climb-down, null, null, null, null] +17150 - Storage shelves - [null, null, null, null, null] +17151 - Shelves - [null, null, null, null, null] +17152 - Shelves - [null, null, null, null, null] +17153 - Sinister barrel - [null, null, null, null, null] +17154 - null - [null, null, null, null, null] +17155 - Staircase - [Climb-down, null, null, null, null] +17156 - null - [null, null, null, null, null] +17157 - null - [null, null, null, null, null] +17158 - Stool - [null, null, null, null, null] +17159 - Ladder - [Climb-up, null, null, null, null] +17160 - Ladder - [Climb-down, null, null, null, null] +17161 - Cauldron - [null, null, null, null, null] +17162 - Cauldron - [null, null, null, null, null] +17163 - null - [null, null, null, null, null] +17164 - null - [null, null, null, null, null] +17165 - null - [null, null, null, null, null] +17166 - null - [null, null, null, null, null] +17167 - null - [null, null, null, null, null] +17168 - null - [null, null, null, null, null] +17169 - null - [null, null, null, null, null] +17170 - null - [null, null, null, null, null] +17171 - null - [null, null, null, null, null] +17172 - null - [null, null, null, null, null] +17173 - null - [null, null, null, null, null] +17174 - null - [null, null, null, null, null] +17175 - null - [null, null, null, null, null] +17176 - null - [null, null, null, null, null] +17177 - null - [null, null, null, null, null] +17178 - null - [null, null, null, null, null] +17179 - null - [null, null, null, null, null] +17180 - null - [null, null, null, null, null] +17181 - null - [null, null, null, null, null] +17182 - null - [null, null, null, null, null] +17183 - null - [null, null, null, null, null] +17184 - null - [null, null, null, null, null] +17185 - null - [null, null, null, null, null] +17186 - null - [null, null, null, null, null] +17187 - null - [null, null, null, null, null] +17188 - null - [null, null, null, null, null] +17189 - null - [null, null, null, null, null] +17190 - null - [null, null, null, null, null] +17191 - null - [null, null, null, null, null] +17192 - null - [null, null, null, null, null] +17193 - null - [null, null, null, null, null] +17194 - null - [null, null, null, null, null] +17195 - null - [null, null, null, null, null] +17196 - Goblin crowd - [null, null, null, null, null] +17197 - Gnome crowd - [null, null, null, null, null] +17198 - Gnome crowd - [null, null, null, null, null] +17199 - Goblin crowd - [null, null, null, null, null] +17200 - Goblin crowd - [null, null, null, null, null] +17201 - Gnome crowd - [null, null, null, null, null] +17202 - Gnome crowd - [null, null, null, null, null] +17203 - Goblin crowd - [null, null, null, null, null] +17204 - Goblin crowd - [null, null, null, null, null] +17205 - Gnome crowd - [null, null, null, null, null] +17206 - Gnome crowd - [null, null, null, null, null] +17207 - A Goblin standard - [null, null, null, null, null] +17208 - null - [null, null, null, null, null] +17209 - Cave entrance - [Enter, null, null, null, null] +17210 - null - [null, null, null, null, null] +17211 - null - [null, null, null, null, null] +17212 - null - [null, null, null, null, null] +17213 - null - [null, null, null, null, null] +17214 - null - [null, null, null, null, null] +17215 - null - [null, null, null, null, null] +17216 - null - [null, null, null, null, null] +17217 - null - [null, null, null, null, null] +17218 - null - [null, null, null, null, null] +17219 - null - [null, null, null, null, null] +17220 - null - [null, null, null, null, null] +17221 - null - [null, null, null, null, null] +17222 - Tunnel - [Exit, null, null, null, null] +17223 - Tunnel - [Exit, null, null, null, null] +17224 - null - [null, null, null, null, null] +17225 - null - [null, null, null, null, null] +17226 - null - [null, null, null, null, null] +17227 - null - [null, null, null, null, null] +17228 - null - [null, null, null, null, null] +17229 - null - [null, null, null, null, null] +17230 - null - [null, null, null, null, null] +17231 - null - [null, null, null, null, null] +17232 - Drawers - [Search, null, null, null, null] +17233 - Drawers - [null, null, null, null, null] +17234 - Chair - [null, null, null, null, null] +17235 - Table - [Take-bowl, null, null, null, null] +17236 - Hammock - [null, null, null, null, null] +17237 - Torch - [null, null, null, null, null] +17238 - Aspidistra plant - [Search, null, null, null, null] +17239 - Singing bowl - [Inspect, null, Sing-glass, Revert-crystal, null] +17240 - Oaknock's machine - [Repair, null, null, null, null] +17241 - Oaknock's machine - [null, null, null, null, null] +17242 - Broken cogs - [null, null, null, null, null] +17243 - Cogs - [null, null, null, null, null] +17244 - null - [null, null, null, null, null] +17245 - Oaknock's Machine - [Operate, null, null, null, null] +17246 - Oaknock's Machine - [Repair, null, null, null, null] +17247 - Oaknock's Machine - [Unlock, null, null, null, null] +17248 - Oaknock's exchanger - [Use, null, null, null, null] +17249 - Oaknock's exchanger - [Repair, null, null, null, null] +17250 - null - [null, null, null, null, null] +17251 - null - [null, null, null, null, null] +17252 - null - [null, null, null, null, null] +17253 - null - [null, null, null, null, null] +17254 - null - [null, null, null, null, null] +17255 - null - [null, null, null, null, null] +17256 - Rift - [null, null, null, null, null] +17257 - Rift - [null, null, null, null, null] +17258 - Rift - [null, null, null, null, null] +17259 - Rift - [null, null, null, null, null] +17260 - Rift - [null, null, null, null, null] +17261 - Rift - [null, null, null, null, null] +17262 - Rift - [null, null, null, null, null] +17263 - Rift - [null, null, null, null, null] +17264 - Rift - [null, null, null, null, null] +17265 - Rift - [null, null, null, null, null] +17266 - Rift - [null, null, null, null, null] +17267 - Crystal bridge - [Walk-across, null, null, null, null] +17268 - A chasm - [null, null, null, null, null] +17269 - null - [null, null, null, null, null] +17270 - null - [null, null, null, null, null] +17271 - Crate - [null, null, null, null, null] +17272 - Machine panel - [Look-at, null, null, null, null] +17273 - Argento - [null, null, null, null, null] +17274 - Argento - [null, null, null, null, null] +17275 - Argento - [null, null, null, null, null] +17276 - Argento - [test, null, null, null, null] +17277 - Argento - [null, null, null, null, null] +17278 - Argento - [null, null, null, null, null] +17279 - Argento - [null, null, null, null, null] +17280 - null - [null, null, null, null, null] +17281 - null - [null, null, null, null, null] +17282 - null - [null, null, null, null, null] +17283 - null - [null, null, null, null, null] +17284 - Door - [null, null, null, null, null] +17285 - null - [null, null, null, null, null] +17286 - Hoisted sail - [null, null, null, null, null] +17287 - Hoisted sail - [null, null, null, null, null] +17288 - Hoisted sail - [null, null, null, null, null] +17289 - Hoisted sail - [null, null, null, null, null] +17290 - Hoisted sail - [null, null, null, null, null] +17291 - Hoisted sail - [null, null, null, null, null] +17292 - Hoisted sail - [null, null, null, null, null] +17293 - Hoisted sail - [null, null, null, null, null] +17294 - Hoisted sail - [null, null, null, null, null] +17295 - Hoisted sail - [null, null, null, null, null] +17296 - Barrel - [Open, Search, null, null, null] +17297 - Barrel - [null, Search, null, null, null] +17298 - null - [null, null, null, null, null] +17299 - Table - [null, null, null, null, null] +17300 - Cupboard - [Open, null, null, null, null] +17301 - Cupboard - [Close, Search, null, null, null] +17302 - Cupboard - [Open, null, null, null, null] +17303 - Cupboard - [Close, Search, null, null, null] +17304 - Crate - [null, null, null, null, null] +17305 - Crate - [null, null, null, null, null] +17306 - Stool - [null, null, null, null, null] +17307 - Barrel - [null, null, null, null, null] +17308 - Barrel - [null, null, null, null, null] +17309 - Study desk - [null, null, null, null, null] +17310 - null - [null, null, null, null, null] +17311 - Chair - [null, null, null, null, null] +17312 - Bench - [null, null, null, null, null] +17313 - Hedge - [null, null, null, null, null] +17314 - Hedge - [null, null, null, null, null] +17315 - Hedge - [null, null, null, null, null] +17316 - Door - [Open, null, null, null, null] +17317 - Door - [Close, null, null, null, null] +17318 - null - [null, null, null, null, null] +17319 - Bookcase - [Search, null, null, null, null] +17320 - Bookcase - [Search, null, null, null, null] +17321 - Bookcase - [Search, null, null, null, null] +17322 - Log pile - [null, null, null, null, null] +17323 - Candles - [null, null, null, null, null] +17324 - null - [null, null, null, null, null] +17325 - Limestone fireplace - [null, null, null, null, null] +17326 - null - [null, null, null, null, null] +17327 - null - [null, null, null, null, null] +17328 - null - [null, null, null, null, null] +17329 - null - [null, null, null, null, null] +17330 - null - [null, null, null, null, null] +17331 - null - [null, null, null, null, null] +17332 - null - [null, null, null, null, null] +17333 - null - [null, null, null, null, null] +17334 - Lava - [null, null, null, null, null] +17335 - Lava - [null, null, null, null, null] +17336 - Lava - [null, null, null, null, null] +17337 - Lava - [null, null, null, null, null] +17338 - Lava - [null, null, null, null, null] +17339 - Lava - [null, null, null, null, null] +17340 - Lava - [null, null, null, null, null] +17341 - Lava - [null, null, null, null, null] +17342 - Lava - [null, null, null, null, null] +17343 - Lava - [null, null, null, null, null] +17344 - Lava - [null, null, null, null, null] +17345 - Lava - [null, null, null, null, null] +17346 - null - [null, null, null, null, null] +17347 - null - [null, null, null, null, null] +17348 - Table - [null, null, null, null, null] +17349 - null - [null, null, null, null, null] +17350 - Rock - [null, null, null, null, null] +17351 - Rock - [null, null, null, null, null] +17352 - Rock - [null, null, null, null, null] +17353 - Rock - [null, null, null, null, null] +17354 - Rock - [null, null, null, null, null] +17355 - Rock - [null, null, null, null, null] +17356 - Rock - [null, null, null, null, null] +17357 - Rock - [null, null, null, null, null] +17358 - Rock - [null, null, null, null, null] +17359 - null - [null, null, null, null, null] +17360 - null - [null, null, null, null, null] +17361 - null - [null, null, null, null, null] +17362 - Urn - [null, null, null, null, null] +17363 - null - [null, null, null, null, null] +17364 - Rock - [null, null, null, null, null] +17365 - Small rock - [null, null, null, null, null] +17366 - Rock - [null, null, null, null, null] +17367 - Stone Tablet - [Take, null, null, null, null] +17368 - Floor - [null, null, null, null, null] +17369 - null - [null, null, null, null, null] +17370 - Rift - [null, null, null, null, null] +17371 - Rift - [null, null, null, null, null] +17372 - Rift - [null, null, null, null, null] +17373 - Rift - [null, null, null, null, null] +17374 - Rift - [null, null, null, null, null] +17375 - Rift - [null, null, null, null, null] +17376 - Rift - [null, null, null, null, null] +17377 - Rift - [null, null, null, null, null] +17378 - Rift - [null, null, null, null, null] +17379 - Rift - [null, null, null, null, null] +17380 - Rift - [null, null, null, null, null] +17381 - Rift - [null, null, null, null, null] +17382 - Bookcase - [Search, null, null, null, null] +17383 - Rocks - [Mine, Prospect, hidden, null, null] +17384 - Rocks - [Mine, Prospect, hidden, null, null] +17385 - Rocks - [Mine, Prospect, hidden, null, null] +17386 - Rocks - [Mine, Prospect, hidden, null, null] +17387 - Rocks - [Mine, Prospect, hidden, null, null] +17388 - Rocks - [Mine, Prospect, hidden, null, null] +17389 - Rocks - [Mine, Prospect, hidden, null, null] +17390 - Rocks - [Mine, Prospect, hidden, null, null] +17391 - Rocks - [Mine, Prospect, hidden, null, null] +17392 - Gangplank - [Cross, null, null, null, null] +17393 - Gangplank - [Cross, null, null, null, null] +17394 - Gangplank - [Cross, null, null, null, null] +17395 - Gangplank - [Cross, null, null, null, null] +17396 - Gangplank - [Cross, null, null, null, null] +17397 - Gangplank - [Cross, null, null, null, null] +17398 - Gangplank - [Cross, null, null, null, null] +17399 - Gangplank - [Cross, null, null, null, null] +17400 - Gangplank - [Cross, null, null, null, null] +17401 - Gangplank - [Cross, null, null, null, null] +17402 - Gangplank - [Cross, null, null, null, null] +17403 - Gangplank - [Cross, null, null, null, null] +17404 - Gangplank - [Cross, null, null, null, null] +17405 - Gangplank - [Cross, null, null, null, null] +17406 - Gangplank - [Cross, null, null, null, null] +17407 - Gangplank - [Cross, null, null, null, null] +17408 - Gangplank - [Cross, null, null, null, null] +17409 - Gangplank - [Cross, null, null, null, null] +17410 - null - [null, null, null, null, null] +17411 - null - [null, null, null, null, null] +17412 - null - [null, null, null, null, null] +17413 - null - [null, null, null, null, null] +17414 - null - [null, null, null, null, null] +17415 - null - [null, null, null, null, null] +17416 - null - [null, null, null, null, null] +17417 - null - [null, null, null, null, null] +17418 - null - [null, null, null, null, null] +17419 - null - [null, null, null, null, null] +17420 - null - [null, null, null, null, null] +17421 - null - [null, null, null, null, null] +17422 - null - [null, null, null, null, null] +17423 - Drain - [Search, null, null, null, null] +17424 - Drain - [Search, null, null, null, null] +17425 - Sword case - [null, null, null, null, null] +17426 - Sword case - [null, null, null, null, null] +17427 - Sword case - [null, null, null, null, null] +17428 - null - [null, null, null, null, null] +17429 - Rusty key - [Take, null, null, null, null] +17430 - Mud - [null, null, null, null, null] +17431 - Rusty key - [Take, null, null, null, null] +17432 - Sewer pipe - [Search, null, null, null, null] +17433 - Wardrobe - [null, null, null, null, null] +17434 - Wardrobe - [null, null, null, null, null] +17435 - Stone table - [null, null, null, null, null] +17436 - Stone table - [null, null, null, null, null] +17437 - Stone table - [null, null, null, null, null] +17438 - Stone table - [null, null, null, null, null] +17439 - Stone circle wall - [null, null, null, null, null] +17440 - Stone circle wall - [null, null, null, null, null] +17441 - Stone circle wall - [null, null, null, null, null] +17442 - Stone circle wall - [null, null, null, null, null] +17443 - Stone circle wall - [null, null, null, null, null] +17444 - Stone circle wall - [null, null, null, null, null] +17445 - Stone circle wall - [null, null, null, null, null] +17446 - null - [null, null, null, null, null] +17447 - null - [null, null, null, null, null] +17448 - null - [null, null, null, null, null] +17449 - null - [null, null, null, null, null] +17450 - Dragon head - [null, null, null, null, null] +17451 - Chess - [null, null, null, null, null] +17452 - null - [null, null, null, null, null] +17453 - null - [null, null, null, null, null] +17454 - null - [null, null, null, null, null] +17455 - Crystal ball - [null, null, null, null, null] +17456 - null - [null, null, null, null, null] +17457 - null - [null, null, null, null, null] +17458 - null - [null, null, null, null, null] +17459 - null - [null, null, null, null, null] +17460 - null - [null, null, null, null, null] +17461 - Ornate candle - [null, null, null, null, null] +17462 - Chair - [null, null, null, null, null] +17463 - Chair - [null, null, null, null, null] +17464 - Desk - [null, null, null, null, null] +17465 - Bed - [null, null, null, null, null] +17466 - Drawers - [Open, null, null, null, null] +17467 - Shelf - [null, null, null, null, null] +17468 - Shelf - [null, null, null, null, null] +17469 - null - [null, null, null, null, null] +17470 - null - [null, null, null, null, null] +17471 - null - [null, null, null, null, null] +17472 - null - [null, null, null, null, null] +17473 - null - [null, null, null, null, null] +17474 - null - [null, null, null, null, null] +17475 - null - [null, null, null, null, null] +17476 - null - [null, null, null, null, null] +17477 - Dragon's head - [null, null, null, null, null] +17478 - Dragon's head - [null, null, null, null, null] +17479 - Dragon's head - [null, null, null, null, null] +17480 - Dragon's head - [null, null, null, null, null] +17481 - Dragon's head - [null, null, null, null, null] +17482 - Dragon's head - [null, null, null, null, null] +17483 - Dragon's head - [null, null, null, null, null] +17484 - Dragon's head - [null, null, null, null, null] +17485 - Dragon's head - [null, null, null, null, null] +17486 - Dragon's head - [null, null, null, null, null] +17487 - null - [null, null, null, null, null] +17488 - Door - [null, null, null, null, null] +17489 - null - [null, null, null, null, null] +17490 - null - [null, null, null, null, null] +17491 - null - [null, null, null, null, null] +17492 - null - [null, null, null, null, null] +17493 - null - [null, null, null, null, null] +17494 - null - [null, null, null, null, null] +17495 - null - [null, null, null, null, null] +17496 - null - [null, null, null, null, null] +17497 - Wall - [null, null, null, null, null] +17498 - Wall - [null, null, null, null, null] +17499 - null - [null, null, null, null, null] +17500 - Wall - [null, null, null, null, null] +17501 - null - [null, null, null, null, null] +17502 - null - [null, null, null, null, null] +17503 - null - [null, null, null, null, null] +17504 - null - [null, null, null, null, null] +17505 - null - [null, null, null, null, null] +17506 - null - [null, null, null, null, null] +17507 - null - [null, null, null, null, null] +17508 - Waste pipes - [null, null, null, null, null] +17509 - Waste pipes - [null, null, null, null, null] +17510 - Waste pipes - [null, null, null, null, null] +17511 - Waste pipes - [null, null, null, null, null] +17512 - null - [null, null, null, null, null] +17513 - null - [null, null, null, null, null] +17514 - null - [null, null, null, null, null] +17515 - null - [null, null, null, null, null] +17516 - null - [null, null, null, null, null] +17517 - null - [null, null, null, null, null] +17518 - null - [null, null, null, null, null] +17519 - null - [null, null, null, null, null] +17520 - null - [null, null, null, null, null] +17521 - null - [null, null, null, null, null] +17522 - null - [null, null, null, null, null] +17523 - null - [null, null, null, null, null] +17524 - null - [null, null, null, null, null] +17525 - null - [null, null, null, null, null] +17526 - null - [null, null, null, null, null] +17527 - null - [null, null, null, null, null] +17528 - null - [null, null, null, null, null] +17529 - null - [null, null, null, null, null] +17530 - null - [null, null, null, null, null] +17531 - null - [null, null, null, null, null] +17532 - null - [null, null, null, null, null] +17533 - null - [null, null, null, null, null] +17534 - null - [null, null, null, null, null] +17535 - null - [null, null, null, null, null] +17536 - null - [null, null, null, null, null] +17537 - null - [null, null, null, null, null] +17538 - null - [null, null, null, null, null] +17539 - null - [null, null, null, null, null] +17540 - null - [null, null, null, null, null] +17541 - null - [null, null, null, null, null] +17542 - null - [null, null, null, null, null] +17543 - null - [null, null, null, null, null] +17544 - null - [null, null, null, null, null] +17545 - Table - [null, null, null, null, null] +17546 - Table - [null, null, null, null, null] +17547 - Chair - [null, null, null, null, null] +17548 - Chair - [null, null, null, null, null] +17549 - Chair - [null, null, null, null, null] +17550 - Chair - [null, null, null, null, null] +17551 - Stool - [null, null, null, null, null] +17552 - Stool - [null, null, null, null, null] +17553 - Bed - [null, null, null, null, null] +17554 - Bed - [null, null, null, null, null] +17555 - Bed - [null, null, null, null, null] +17556 - Bucket - [null, null, null, null, null] +17557 - Bucket - [null, null, null, null, null] +17558 - Bucket - [null, null, null, null, null] +17559 - Panning tray - [null, null, null, null, null] +17560 - Panning tray - [null, null, null, null, null] +17561 - Pots - [null, null, null, null, null] +17562 - Pots - [null, null, null, null, null] +17563 - Floor below - [null, null, null, null, null] +17564 - null - [null, null, null, null, null] +17565 - null - [null, null, null, null, null] +17566 - null - [null, null, null, null, null] +17567 - null - [null, null, null, null, null] +17568 - null - [null, null, null, null, null] +17569 - null - [null, null, null, null, null] +17570 - null - [null, null, null, null, null] +17571 - null - [null, null, null, null, null] +17572 - null - [null, null, null, null, null] +17573 - null - [null, null, null, null, null] +17574 - null - [null, null, null, null, null] +17575 - null - [null, null, null, null, null] +17576 - null - [null, null, null, null, null] +17577 - null - [null, null, null, null, null] +17578 - null - [null, null, null, null, null] +17579 - null - [null, null, null, null, null] +17580 - null - [null, null, null, null, null] +17581 - null - [null, null, null, null, null] +17582 - null - [null, null, null, null, null] +17583 - null - [null, null, null, null, null] +17584 - null - [null, null, null, null, null] +17585 - null - [null, null, null, null, null] +17586 - null - [null, null, null, null, null] +17587 - null - [null, null, null, null, null] +17588 - null - [null, null, null, null, null] +17589 - null - [null, null, null, null, null] +17590 - null - [null, null, null, null, null] +17591 - null - [null, null, null, null, null] +17592 - null - [null, null, null, null, null] +17593 - null - [null, null, null, null, null] +17594 - null - [null, null, null, null, null] +17595 - null - [null, null, null, null, null] +17596 - null - [null, null, null, null, null] +17597 - null - [null, null, null, null, null] +17598 - null - [null, null, null, null, null] +17599 - null - [null, null, null, null, null] +17600 - Door - [Open, null, null, null, null] +17601 - Door - [Open, null, null, null, null] +17602 - null - [null, null, null, null, null] +17603 - null - [null, null, null, null, null] +17604 - null - [null, null, null, null, null] +17605 - null - [null, null, null, null, null] +17606 - null - [null, null, null, null, null] +17607 - null - [null, null, null, null, null] +17608 - null - [null, null, null, null, null] +17609 - null - [null, null, null, null, null] +17610 - null - [null, null, null, null, null] +17611 - null - [null, null, null, null, null] +17612 - null - [null, null, null, null, null] +17613 - null - [null, null, null, null, null] +17614 - null - [null, null, null, null, null] +17615 - null - [null, null, null, null, null] +17616 - null - [null, null, null, null, null] +17617 - null - [null, null, null, null, null] +17618 - null - [null, null, null, null, null] +17619 - null - [null, null, null, null, null] +17620 - null - [null, null, null, null, null] +17621 - null - [null, null, null, null, null] +17622 - null - [null, null, null, null, null] +17623 - null - [null, null, null, null, null] +17624 - null - [null, null, null, null, null] +17625 - null - [null, null, null, null, null] +17626 - Rubble - [null, null, null, null, null] +17627 - Washing Line - [null, null, null, null, null] +17628 - null - [null, null, null, null, null] +17629 - null - [null, null, null, null, null] +17630 - null - [null, null, null, null, null] +17631 - null - [null, null, null, null, null] +17632 - null - [null, null, null, null, null] +17633 - null - [null, null, null, null, null] +17634 - null - [null, null, null, null, null] +17635 - Scaffolding - [null, null, null, null, null] +17636 - Scaffolding - [null, null, null, null, null] +17637 - Ladder - [null, null, null, null, null] +17638 - null - [null, null, null, null, null] +17639 - null - [null, null, null, null, null] +17640 - Fireplace - [null, null, null, null, null] +17641 - Fireplace - [null, null, null, null, null] +17642 - Fireplace - [null, null, null, null, null] +17643 - Fireplace - [null, null, null, null, null] +17644 - Barricade - [null, null, null, null, null] +17645 - Barricade - [null, null, null, null, null] +17646 - Barricade - [null, null, null, null, null] +17647 - Sickle logo - [null, null, null, null, null] +17648 - Sickle logo - [null, null, null, null, null] +17649 - null - [null, null, null, null, null] +17650 - null - [null, null, null, null, null] +17651 - null - [null, null, null, null, null] +17652 - null - [null, null, null, null, null] +17653 - null - [null, null, null, null, null] +17654 - Barrel - [null, null, null, null, null] +17655 - Crate - [null, null, null, null, null] +17656 - Crates - [null, null, null, null, null] +17657 - Boxes - [null, null, null, null, null] +17658 - Crate - [null, null, null, null, null] +17659 - Staircase - [null, null, null, null, null] +17660 - Staircase - [null, null, null, null, null] +17661 - Table - [null, null, null, null, null] +17662 - Table - [null, null, null, null, null] +17663 - Chair - [null, null, null, null, null] +17664 - null - [null, null, null, null, null] +17665 - null - [null, null, null, null, null] +17666 - Table - [null, null, null, null, null] +17667 - Stool - [null, null, null, null, null] +17668 - Bunk bed - [Search, null, null, null, null] +17669 - Bunk bed - [Search, null, null, null, null] +17670 - Blackboard - [null, null, null, null, null] +17671 - Locker - [Search, null, null, null, null] +17672 - Locker - [Search, null, null, null, null] +17673 - null - [null, null, null, null, null] +17674 - null - [null, null, null, null, null] +17675 - null - [null, null, null, null, null] +17676 - Wall - [null, null, null, null, null] +17677 - Wall - [null, null, null, null, null] +17678 - Wall - [null, null, null, null, null] +17679 - Rock - [Jump, null, null, null, null] +17680 - Wall - [null, null, null, null, null] +17681 - Wall - [null, null, null, null, null] +17682 - Wall - [null, null, null, null, null] +17683 - Wall - [null, null, null, null, null] +17684 - Wall - [null, null, null, null, null] +17685 - Wall - [null, null, null, null, null] +17686 - Wall - [null, null, null, null, null] +17687 - Wall - [null, null, null, null, null] +17688 - Wall - [null, null, null, null, null] +17689 - null - [null, null, null, null, null] +17690 - null - [null, null, null, null, null] +17691 - null - [null, null, null, null, null] +17692 - null - [null, null, null, null, null] +17693 - null - [null, null, null, null, null] +17694 - null - [null, null, null, null, null] +17695 - null - [null, null, null, null, null] +17696 - null - [null, null, null, null, null] +17697 - null - [null, null, null, null, null] +17698 - Wall - [null, null, null, null, null] +17699 - null - [null, null, null, null, null] +17700 - null - [null, null, null, null, null] +17701 - null - [null, null, null, null, null] +17702 - Floor - [null, null, null, null, null] +17703 - null - [null, null, null, null, null] +17704 - null - [null, null, null, null, null] +17705 - null - [null, null, null, null, null] +17706 - null - [null, null, null, null, null] +17707 - null - [null, null, null, null, null] +17708 - null - [null, null, null, null, null] +17709 - Floor - [null, null, null, null, null] +17710 - Floor - [null, null, null, null, null] +17711 - Floor - [null, null, null, null, null] +17712 - Floor - [null, null, null, null, null] +17713 - null - [null, null, null, null, null] +17714 - null - [null, null, null, null, null] +17715 - null - [null, null, null, null, null] +17716 - null - [null, null, null, null, null] +17717 - null - [null, null, null, null, null] +17718 - null - [null, null, null, null, null] +17719 - null - [null, null, null, null, null] +17720 - null - [null, null, null, null, null] +17721 - null - [null, null, null, null, null] +17722 - null - [null, null, null, null, null] +17723 - null - [null, null, null, null, null] +17724 - null - [null, null, null, null, null] +17725 - null - [null, null, null, null, null] +17726 - null - [null, null, null, null, null] +17727 - null - [null, null, null, null, null] +17728 - null - [null, null, null, null, null] +17729 - null - [null, null, null, null, null] +17730 - null - [null, null, null, null, null] +17731 - null - [null, null, null, null, null] +17732 - null - [null, null, null, null, null] +17733 - null - [null, null, null, null, null] +17734 - null - [null, null, null, null, null] +17735 - null - [null, null, null, null, null] +17736 - null - [null, null, null, null, null] +17737 - null - [null, null, null, null, null] +17738 - null - [null, null, null, null, null] +17739 - null - [null, null, null, null, null] +17740 - null - [null, null, null, null, null] +17741 - null - [null, null, null, null, null] +17742 - null - [null, null, null, null, null] +17743 - null - [null, null, null, null, null] +17744 - null - [null, null, null, null, null] +17745 - null - [null, null, null, null, null] +17746 - null - [null, null, null, null, null] +17747 - null - [null, null, null, null, null] +17748 - null - [null, null, null, null, null] +17749 - null - [null, null, null, null, null] +17750 - null - [null, null, null, null, null] +17751 - null - [null, null, null, null, null] +17752 - null - [null, null, null, null, null] +17753 - null - [null, null, null, null, null] +17754 - null - [null, null, null, null, null] +17755 - null - [null, null, null, null, null] +17756 - null - [null, null, null, null, null] +17757 - Chair - [null, null, null, null, null] +17758 - Chair - [null, null, null, null, null] +17759 - Chair - [null, null, null, null, null] +17760 - Chair - [null, null, null, null, null] +17761 - Chair - [null, null, null, null, null] +17762 - Table - [null, null, null, null, null] +17763 - Bookcase - [null, null, null, null, null] +17764 - Bench - [null, null, null, null, null] +17765 - Grandfather clock - [null, null, null, null, null] +17766 - The middle of a fireplace - [null, null, null, null, null] +17767 - Left side of a fireplace - [null, null, null, null, null] +17768 - Right side of a fireplace - [null, null, null, null, null] +17769 - Ornate vase - [null, null, null, null, null] +17770 - null - [null, null, null, null, null] +17771 - null - [null, null, null, null, null] +17772 - null - [null, null, null, null, null] +17773 - null - [null, null, null, null, null] +17774 - null - [null, null, null, null, null] +17775 - null - [null, null, null, null, null] +17776 - null - [null, null, null, null, null] +17777 - null - [null, null, null, null, null] +17778 - null - [null, null, null, null, null] +17779 - null - [null, null, null, null, null] +17780 - null - [null, null, null, null, null] +17781 - null - [null, null, null, null, null] +17782 - Fence end - [null, null, null, null, null] +17783 - Fence mid - [null, null, null, null, null] +17784 - Fence corner - [null, null, null, null, null] +17785 - Fence t-piece - [null, null, null, null, null] +17786 - Single pillar - [null, null, null, null, null] +17787 - Fence mid - [null, null, null, null, null] +17788 - Fence corner - [null, null, null, null, null] +17789 - Fence bits - [null, null, null, null, null] +17790 - Fence mid - [null, null, null, null, null] +17791 - Fence mid - [null, null, null, null, null] +17792 - null - [null, null, null, null, null] +17793 - null - [null, null, null, null, null] +17794 - null - [null, null, null, null, null] +17795 - null - [null, null, null, null, null] +17796 - null - [null, null, null, null, null] +17797 - null - [null, null, null, null, null] +17798 - null - [null, null, null, null, null] +17799 - null - [null, null, null, null, null] +17800 - null - [null, null, null, null, null] +17801 - null - [null, null, null, null, null] +17802 - null - [null, null, null, null, null] +17803 - null - [null, null, null, null, null] +17804 - null - [null, null, null, null, null] +17805 - null - [null, null, null, null, null] +17806 - null - [null, null, null, null, null] +17807 - null - [null, null, null, null, null] +17808 - null - [null, null, null, null, null] +17809 - null - [null, null, null, null, null] +17810 - null - [null, null, null, null, null] +17811 - null - [null, null, null, null, null] +17812 - null - [null, null, null, null, null] +17813 - null - [null, null, null, null, null] +17814 - null - [null, null, null, null, null] +17815 - null - [null, null, null, null, null] +17816 - null - [null, null, null, null, null] +17817 - null - [null, null, null, null, null] +17818 - null - [null, null, null, null, null] +17819 - null - [null, null, null, null, null] +17820 - null - [null, null, null, null, null] +17821 - null - [null, null, null, null, null] +17822 - null - [null, null, null, null, null] +17823 - null - [null, null, null, null, null] +17824 - null - [null, null, null, null, null] +17825 - null - [null, null, null, null, null] +17826 - null - [null, null, null, null, null] +17827 - null - [null, null, null, null, null] +17828 - Rock wall - [null, null, null, null, null] +17829 - null - [null, null, null, null, null] +17830 - null - [null, null, null, null, null] +17831 - null - [null, null, null, null, null] +17832 - null - [null, null, null, null, null] +17833 - null - [null, null, null, null, null] +17834 - null - [null, null, null, null, null] +17835 - null - [null, null, null, null, null] +17836 - null - [null, null, null, null, null] +17837 - null - [null, null, null, null, null] +17838 - null - [null, null, null, null, null] +17839 - null - [null, null, null, null, null] +17840 - null - [null, null, null, null, null] +17841 - null - [null, null, null, null, null] +17842 - null - [null, null, null, null, null] +17843 - null - [null, null, null, null, null] +17844 - null - [null, null, null, null, null] +17845 - null - [null, null, null, null, null] +17846 - Rift - [null, null, null, null, null] +17847 - Rift - [null, null, null, null, null] +17848 - Rift - [null, null, null, null, null] +17849 - Rift - [null, null, null, null, null] +17850 - Rift - [null, null, null, null, null] +17851 - Rift - [null, null, null, null, null] +17852 - Rift - [null, null, null, null, null] +17853 - Rift - [null, null, null, null, null] +17854 - Rift - [null, null, null, null, null] +17855 - Rift - [null, null, null, null, null] +17856 - Rift - [null, null, null, null, null] +17857 - null - [null, null, null, null, null] +17858 - null - [null, null, null, null, null] +17859 - null - [null, null, null, null, null] +17860 - null - [null, null, null, null, null] +17861 - null - [null, null, null, null, null] +17862 - null - [null, null, null, null, null] +17863 - null - [null, null, null, null, null] +17864 - null - [null, null, null, null, null] +17865 - null - [null, null, null, null, null] +17866 - null - [null, null, null, null, null] +17867 - null - [null, null, null, null, null] +17868 - null - [null, null, null, null, null] +17869 - null - [null, null, null, null, null] +17870 - null - [null, null, null, null, null] +17871 - null - [null, null, null, null, null] +17872 - null - [null, null, null, null, null] +17873 - null - [null, null, null, null, null] +17874 - null - [null, null, null, null, null] +17875 - null - [null, null, null, null, null] +17876 - null - [null, null, null, null, null] +17877 - null - [null, null, null, null, null] +17878 - null - [null, null, null, null, null] +17879 - Rift - [null, null, null, null, null] +17880 - Rift - [null, null, null, null, null] +17881 - Rift - [null, null, null, null, null] +17882 - Rift - [null, null, null, null, null] +17883 - Rift - [null, null, null, null, null] +17884 - Rift - [null, null, null, null, null] +17885 - Rift - [null, null, null, null, null] +17886 - Rift - [null, null, null, null, null] +17887 - Rift - [null, null, null, null, null] +17888 - Rift - [null, null, null, null, null] +17889 - Rift - [null, null, null, null, null] +17890 - Bookshelf - [null, null, null, null, null] +17891 - Bookshelf - [null, null, null, null, null] +17892 - null - [null, null, null, null, null] +17893 - Lab table - [null, null, null, null, null] +17894 - Lab table - [null, null, null, null, null] +17895 - Lab table - [null, null, null, null, null] +17896 - Lab table - [null, null, null, null, null] +17897 - Lab tube - [null, null, null, null, null] +17898 - Lab tube - [null, null, null, null, null] +17899 - Experiment booth - [null, null, null, null, null] +17900 - null - [null, null, null, null, null] +17901 - null - [null, null, null, null, null] +17902 - null - [null, null, null, null, null] +17903 - null - [null, null, null, null, null] +17904 - Barrel - [null, null, null, null, null] +17905 - Crate - [null, null, null, null, null] +17906 - Crates - [null, null, null, null, null] +17907 - Boxes - [null, null, null, null, null] +17908 - Crate - [null, null, null, null, null] +17909 - Stool - [null, null, null, null, null] +17910 - Stool - [null, null, null, null, null] +17911 - null - [null, null, null, null, null] +17912 - null - [null, null, null, null, null] +17913 - null - [null, null, null, null, null] +17914 - null - [null, null, null, null, null] +17915 - null - [null, null, null, null, null] +17916 - null - [null, null, null, null, null] +17917 - null - [null, null, null, null, null] +17918 - null - [null, null, null, null, null] +17919 - null - [null, null, null, null, null] +17920 - null - [null, null, null, null, null] +17921 - null - [null, null, null, null, null] +17922 - null - [null, null, null, null, null] +17923 - null - [null, null, null, null, null] +17924 - null - [null, null, null, null, null] +17925 - null - [null, null, null, null, null] +17926 - null - [null, null, null, null, null] +17927 - null - [null, null, null, null, null] +17928 - null - [null, null, null, null, null] +17929 - null - [null, null, null, null, null] +17930 - null - [null, null, null, null, null] +17931 - null - [null, null, null, null, null] +17932 - null - [null, null, null, null, null] +17933 - null - [null, null, null, null, null] +17934 - Wall - [null, null, null, null, null] +17935 - Wall - [null, null, null, null, null] +17936 - Wall - [null, null, null, null, null] +17937 - Wall - [null, null, null, null, null] +17938 - Wall - [null, null, null, null, null] +17939 - Wall - [null, null, null, null, null] +17940 - Wall - [null, null, null, null, null] +17941 - Wall - [null, null, null, null, null] +17942 - null - [null, null, null, null, null] +17943 - Wall - [null, null, null, null, null] +17944 - null - [null, null, null, null, null] +17945 - null - [null, null, null, null, null] +17946 - null - [null, null, null, null, null] +17947 - null - [null, null, null, null, null] +17948 - null - [null, null, null, null, null] +17949 - null - [null, null, null, null, null] +17950 - null - [null, null, null, null, null] +17951 - null - [null, null, null, null, null] +17952 - null - [null, null, null, null, null] +17953 - Boat - [Search, null, null, null, null] +17954 - Boat - [Search, Push, null, null, null] +17955 - Boat - [Board, null, null, null, null] +17956 - Boat Chute - [Look-at, null, null, null, null] +17957 - Boat Chute - [Look-at, null, null, null, null] +17958 - Rock - [Jump-onto, null, null, null, null] +17959 - Rock - [Climb-up, null, null, null, null] +17960 - Rock - [Climb-down, null, null, null, null] +17961 - Boat - [Jump-onto, null, null, null, null] +17962 - Daeyalt rocks - [Mine, Prospect, null, null, null] +17963 - Daeyalt rocks - [Mine, Prospect, null, null, null] +17964 - Daeyalt rocks - [Mine, Prospect, null, null, null] +17965 - Daeyalt rocks - [null, Prospect, null, null, null] +17966 - Mine cart - [Search, null, null, null, null] +17967 - Mine cart - [Search, null, null, null, null] +17968 - Mine cart - [Search, null, null, null, null] +17969 - Mine cart - [Search, null, null, null, null] +17970 - Rock - [Jump-to, null, null, null, null] +17971 - Rock - [Climb-down, null, null, null, null] +17972 - Rock - [Climb-down, null, null, null, null] +17973 - Door - [Open, null, null, null, null] +17974 - Ladder - [Climb-up, null, null, null, null] +17975 - Ladder - [Climb-down, null, null, null, null] +17976 - Stairs up - [Climb-up, null, null, null, null] +17977 - Broken stairs - [Climb-up, null, null, null, null] +17978 - Stairs down - [Climb-down, null, null, null, null] +17979 - Broken stairs - [Climb-down, null, null, null, null] +17980 - Wall - [null, null, null, Search, Push] +17981 - null - [null, null, null, null, null] +17982 - Decorated wall - [null, Search, null, null, Press] +17983 - Rug - [null, null, null, null, null] +17984 - Lumpy rug - [Open, null, null, null, null] +17985 - Trapdoor - [Climb-down, Close, null, null, null] +17986 - Ladder - [Climb-up, null, null, null, null] +17987 - Boxes - [Search, null, null, null, null] +17988 - Bush - [null, null, null, null, null] +17989 - Bush - [Search, null, null, null, null] +17990 - Bush - [null, null, null, null, null] +17991 - Bush - [null, null, null, null, null] +17992 - null - [null, null, null, null, null] +17993 - null - [null, null, null, null, null] +17994 - null - [null, null, null, null, null] +17995 - Ladder - [null, Climb-down, null, null, null] +17996 - Ladder - [Climb-up, null, null, null, null] +17997 - Ladder - [Climb-up, null, null, null, null] +17998 - Ladder - [null, Climb-down, null, null, null] +17999 - Ladder - [null, Climb-down, null, null, null] +18000 - Ladder - [null, Climb-up, null, null, null] +18001 - Ladder - [null, Climb-down, null, null, null] +18002 - Ladder - [null, Climb-up, null, null, null] +18003 - null - [null, null, null, null, null] +18004 - null - [null, null, null, null, null] +18005 - null - [null, null, null, null, null] +18006 - Barrel of fishbones - [null, null, null, null, null] +18007 - Corner Table - [null, null, null, null, null] +18008 - Cutting Table - [null, null, null, null, null] +18009 - Broken fish display - [null, null, null, null, null] +18010 - Stagnant fish display - [null, null, null, null, null] +18011 - A fallen barrel - [null, null, null, null, null] +18012 - Broken barrel - [null, null, null, null, null] +18013 - Stacked crates - [null, null, null, null, null] +18014 - Table and till - [null, null, null, null, null] +18015 - Barrel - [null, null, null, null, null] +18016 - Broken counter - [null, null, null, null, null] +18017 - Counter - [null, null, null, null, null] +18018 - Counter - [null, null, null, null, null] +18019 - null - [null, null, null, null, null] +18020 - null - [null, null, null, null, null] +18021 - null - [null, null, null, null, null] +18022 - null - [null, null, null, null, null] +18023 - null - [null, null, null, null, null] +18024 - null - [null, null, null, null, null] +18025 - null - [null, null, null, null, null] +18026 - null - [null, null, null, null, null] +18027 - null - [null, null, null, null, null] +18028 - Skeleton - [null, null, null, null, null] +18029 - Skeleton - [null, null, null, null, null] +18030 - Machine - [null, null, null, null, null] +18031 - Door - [Close, null, null, null, null] +18032 - Door - [Close, null, null, null, null] +18033 - Floor - [Search, null, null, null, Kick-down] +18034 - Floor - [null, null, null, null, Climb-down] +18035 - Floor - [null, null, null, null, null] +18036 - Floor - [Climb-up, null, null, null, null] +18037 - Wall rubble - [Climb-over, null, null, null, null] +18038 - Wall rubble - [Climb-over, null, null, null, null] +18039 - Fireplace - [Look-at, null, null, null, null] +18040 - Tapestry - [null, null, null, null, null] +18041 - Slashed tapestry - [null, null, null, null, Walk-through] +18042 - Portrait - [null, null, null, null, Look-at] +18043 - Portrait - [Search, null, null, null, Look-at] +18044 - Portrait - [Search, null, null, null, Look-at] +18045 - Vampyre statue - [null, null, Search, null, null] +18046 - Statue with key - [null, null, Search, null, null] +18047 - Door - [Open, null, null, null, null] +18048 - Door - [null, null, null, null, null] +18049 - Staircase - [Climb-down, null, null, null, null] +18050 - Staircase - [Climb-up, null, null, null, null] +18051 - Table - [Search, null, null, null, null] +18052 - Broken rune case - [null, Search, null, null, null] +18053 - Rubble - [null, null, null, null, null] +18054 - Barricade - [Open, null, null, null, null] +18055 - Barricade - [null, null, null, null, null] +18056 - Rocky surface - [Look-at, Search, null, null, null] +18057 - Door - [Open, null, null, null, null] +18058 - Door - [null, null, null, null, null] +18059 - Table - [Search, null, null, null, null] +18060 - Trapdoor table - [Open, null, null, null, null] +18061 - Trapdoor tunnel - [Climb-into, null, null, null, null] +18062 - Table - [Search, null, null, null, null] +18063 - Trapdoor table - [Open, null, null, null, null] +18064 - Trapdoor table - [null, null, null, null, null] +18065 - Pots - [Search, null, null, null, null] +18066 - Wall - [Search, null, null, null, null] +18067 - Wall - [Search, null, null, null, null] +18068 - Broken ladder - [Search, null, null, null, null] +18069 - Ladder - [Climb-down, null, null, null, null] +18070 - Floorboards - [null, null, null, null, Jump-to] +18071 - Floorboards - [null, null, null, null, Jump-to] +18072 - Floorboards - [null, null, null, null, Jump-to] +18073 - Floorboards - [null, null, null, null, Jump-to] +18074 - Wall - [null, null, null, null, Push] +18075 - Wall - [null, null, null, null, null] +18076 - Floor - [Walk-across, null, null, null, null] +18077 - Floor - [Walk-across, null, null, null, null] +18078 - Wall - [null, null, null, null, Crawl-under] +18079 - Wall - [null, null, null, null, Push] +18080 - Wall - [null, null, null, null, null] +18081 - Floor - [Walk-across, null, null, null, null] +18082 - Floor - [Walk-across, null, null, null, null] +18083 - null - [null, null, null, null, null] +18084 - null - [null, null, null, null, null] +18085 - Tunnel - [null, null, null, null, Climb-into] +18086 - Shelf - [null, null, null, null, Climb-up] +18087 - Shelf - [null, null, null, null, Climb-down] +18088 - Wall - [null, null, null, null, Crawl-under] +18089 - Floorboards - [null, null, null, null, Jump-to] +18090 - Floorboards - [null, null, null, null, Jump-to] +18091 - Door - [Open, null, null, null, null] +18092 - Door - [Open, null, null, null, null] +18093 - Floorboards - [null, null, null, null, Jump-to] +18094 - Floorboards - [null, null, null, null, Jump-to] +18095 - Shelf - [null, null, null, null, Climb-up] +18096 - Shelf - [null, null, null, null, Climb-down] +18097 - Floorboards - [null, null, null, null, Jump-to] +18098 - Floorboards - [null, null, null, null, Jump-to] +18099 - Washing line - [null, null, null, null, Walk-across] +18100 - Washing line - [null, null, null, null, Walk-across] +18101 - Wall - [null, null, null, null, Push] +18102 - Falling door - [null, null, null, null, null] +18103 - Floor - [Walk-across, null, null, null, null] +18104 - Floor - [Walk-across, null, null, null, null] +18105 - Shelf - [null, null, null, null, Climb-up] +18106 - Shelf - [null, null, null, null, Climb-down] +18107 - Shelf - [null, null, null, null, Climb-down] +18108 - Shelf - [null, null, null, null, Climb-up] +18109 - Floorboards - [null, null, null, null, Jump-to] +18110 - Floorboards - [null, null, null, null, Jump-to] +18111 - Floorboards - [null, null, null, null, Jump-to] +18112 - Floorboards - [null, null, null, null, Jump-to] +18113 - Floorboards - [null, null, null, null, Jump-to] +18114 - Floorboards - [null, null, null, null, Jump-to] +18115 - null - [null, null, null, null, null] +18116 - null - [null, null, null, null, null] +18117 - Floorboards - [null, null, null, null, Jump-to] +18118 - Floorboards - [null, null, null, null, Jump-to] +18119 - null - [null, null, null, null, null] +18120 - null - [null, null, null, null, null] +18121 - null - [null, null, null, null, null] +18122 - null - [null, null, null, null, null] +18123 - null - [null, null, null, null, null] +18124 - null - [null, null, null, null, null] +18125 - null - [null, null, null, null, null] +18126 - null - [null, null, null, null, null] +18127 - null - [null, null, null, null, null] +18128 - null - [null, null, null, null, null] +18129 - null - [null, null, null, null, null] +18130 - null - [null, null, null, null, null] +18131 - null - [null, null, null, null, null] +18132 - null - [null, null, null, null, null] +18133 - null - [null, null, null, null, null] +18134 - null - [null, null, null, null, null] +18135 - null - [null, null, null, null, null] +18136 - null - [null, null, null, null, null] +18137 - Windswept tree - [Chop down, null, null, null, null] +18138 - null - [null, null, null, null, null] +18139 - null - [null, null, null, null, null] +18140 - null - [null, null, null, null, null] +18141 - null - [null, null, null, null, null] +18142 - null - [null, null, null, null, null] +18143 - null - [null, null, null, null, null] +18144 - Decorated wall - [null, Search, null, null, Press] +18145 - Decorated wall - [null, Search, null, null, null] +18146 - null - [null, null, null, null, null] +18147 - null - [null, null, null, null, null] +18148 - null - [null, null, null, null, null] +18149 - null - [null, null, null, null, null] +18150 - null - [null, null, null, null, null] +18151 - null - [null, null, null, null, null] +18152 - null - [null, null, null, null, null] +18153 - null - [null, null, null, null, null] +18154 - Smashed table - [null, null, null, null, null] +18155 - Shelf - [Search, null, null, null, null] +18156 - Shelf - [Search, null, null, null, null] +18157 - Dolls and balls - [null, null, null, null, null] +18158 - null - [null, null, null, null, null] +18159 - null - [null, null, null, null, null] +18160 - null - [null, null, null, null, null] +18161 - null - [null, null, null, null, null] +18162 - null - [null, null, null, null, null] +18163 - null - [null, null, null, null, null] +18164 - null - [null, null, null, null, null] +18165 - null - [null, null, null, null, null] +18166 - null - [null, null, null, null, null] +18167 - null - [null, null, null, null, null] +18168 - Door - [Open, null, null, null, null] +18169 - null - [null, null, null, null, null] +18170 - Clay oven - [null, null, null, null, null] +18171 - Washbasin - [null, null, null, null, null] +18172 - Hammock - [null, null, null, null, null] +18173 - null - [null, null, null, null, null] +18174 - null - [null, null, null, null, null] +18175 - null - [null, null, null, null, null] +18176 - Large table - [null, null, null, null, null] +18177 - Display table - [null, null, null, null, null] +18178 - Display table - [null, null, null, null, null] +18179 - null - [null, null, null, null, null] +18180 - null - [null, null, null, null, null] +18181 - null - [null, null, null, null, null] +18182 - Barrel - [null, null, null, null, null] +18183 - Bucket - [null, null, null, null, null] +18184 - Suit of armour - [null, null, null, null, null] +18185 - Suit of armour - [null, null, null, null, null] +18186 - Rowboat - [null, null, null, null, null] +18187 - Rowboat - [null, null, null, null, null] +18188 - null - [null, null, null, null, null] +18189 - Broken boat - [null, null, null, null, null] +18190 - Broken boat - [null, null, null, null, null] +18191 - Broken boat - [null, null, null, null, null] +18192 - null - [null, null, null, null, null] +18193 - null - [null, null, null, null, null] +18194 - null - [null, null, null, null, null] +18195 - null - [null, null, null, null, null] +18196 - null - [null, null, null, null, null] +18197 - null - [null, null, null, null, null] +18198 - null - [null, null, null, null, null] +18199 - null - [null, null, null, null, null] +18200 - A barrel of rainwater - [null, null, null, null, null] +18201 - Stacked crates - [null, null, null, null, null] +18202 - Crates - [null, null, null, null, null] +18203 - null - [null, null, null, null, null] +18204 - null - [null, null, null, null, null] +18205 - Barrel - [null, null, null, null, null] +18206 - null - [null, null, null, null, null] +18207 - null - [null, null, null, null, null] +18208 - Life buoy - [null, null, null, null, null] +18209 - null - [null, null, null, null, null] +18210 - null - [null, null, null, null, null] +18211 - null - [null, null, null, null, null] +18212 - null - [null, null, null, null, null] +18213 - null - [null, null, null, null, null] +18214 - null - [null, null, null, null, null] +18215 - null - [null, null, null, null, null] +18216 - null - [null, null, null, null, null] +18217 - null - [null, null, null, null, null] +18218 - null - [null, null, null, null, null] +18219 - null - [null, null, null, null, null] +18220 - Pillar - [null, null, null, null, null] +18221 - Study desk - [Search, null, null, null, null] +18222 - Painting - [null, null, null, null, null] +18223 - Painting - [null, null, null, null, null] +18224 - Painting - [null, null, null, null, null] +18225 - Sailfish - [null, null, null, null, null] +18226 - Shark head - [null, null, null, null, null] +18227 - Large vase - [null, null, null, null, null] +18228 - Small vase - [null, null, null, null, null] +18229 - Vase set - [null, null, null, null, null] +18230 - Ladder - [Climb-up, null, null, null, null] +18231 - Ladder - [Climb-down, null, null, null, null] +18232 - Ladder - [Climb-up, null, null, null, null] +18233 - Ladder - [Climb-down, null, null, null, null] +18234 - Bench - [null, null, null, null, null] +18235 - Bookcase - [null, null, null, null, null] +18236 - Drawers - [null, null, null, null, null] +18237 - Wardrobe - [null, null, null, null, null] +18238 - Dummy - [null, null, null, null, null] +18239 - Anchor - [null, null, null, null, null] +18240 - Bed - [null, null, null, null, null] +18241 - Lectern - [null, null, null, null, null] +18242 - null - [null, null, null, null, null] +18243 - null - [null, null, null, null, null] +18244 - null - [null, null, null, null, null] +18245 - null - [null, null, null, null, null] +18246 - null - [null, null, null, null, null] +18247 - null - [null, null, null, null, null] +18248 - null - [null, null, null, null, null] +18249 - null - [null, null, null, null, null] +18250 - null - [null, null, null, null, null] +18251 - null - [null, null, null, null, null] +18252 - null - [null, null, null, null, null] +18253 - null - [null, null, null, null, null] +18254 - Altar - [Pray, null, null, null, null] +18255 - null - [null, null, null, null, null] +18256 - Steeple - [null, null, null, null, null] +18257 - Pillar - [null, null, null, null, null] +18258 - Pillar - [null, null, null, null, null] +18259 - Statue - [null, null, null, null, null] +18260 - null - [null, null, null, null, null] +18261 - null - [null, null, null, null, null] +18262 - null - [null, null, null, null, null] +18263 - null - [null, null, null, null, null] +18264 - null - [null, null, null, null, null] +18265 - null - [null, null, null, null, null] +18266 - Old ruin entrance - [Climb-down, null, null, null, null] +18267 - null - [null, null, null, null, null] +18268 - null - [null, null, null, null, null] +18269 - null - [null, null, null, null, null] +18270 - null - [null, null, null, null, null] +18271 - null - [null, null, null, null, null] +18272 - null - [null, null, null, null, null] +18273 - null - [null, null, null, null, null] +18274 - null - [null, null, null, null, null] +18275 - null - [null, null, null, null, null] +18276 - null - [null, null, null, null, null] +18277 - null - [null, null, null, null, null] +18278 - null - [null, null, null, null, null] +18279 - null - [null, null, null, null, null] +18280 - null - [null, null, null, null, null] +18281 - null - [null, null, null, null, null] +18282 - null - [null, null, null, null, null] +18283 - null - [null, null, null, null, null] +18284 - null - [null, null, null, null, null] +18285 - null - [null, null, null, null, null] +18286 - null - [null, null, null, null, null] +18287 - null - [null, null, null, null, null] +18288 - null - [null, null, null, null, null] +18289 - null - [null, null, null, null, null] +18290 - null - [null, null, null, null, null] +18291 - null - [null, null, null, null, null] +18292 - null - [null, null, null, null, null] +18293 - null - [null, null, null, null, null] +18294 - null - [null, null, null, null, null] +18295 - null - [null, null, null, null, null] +18296 - null - [null, null, null, null, null] +18297 - null - [null, null, null, null, null] +18298 - null - [null, null, null, null, null] +18299 - null - [null, null, null, null, null] +18300 - null - [null, null, null, null, null] +18301 - null - [null, null, null, null, null] +18302 - null - [null, null, null, null, null] +18303 - null - [null, null, null, null, null] +18304 - Chest - [Open, null, null, null, null] +18305 - null - [null, null, null, null, null] +18306 - null - [null, null, null, null, null] +18307 - null - [null, null, null, null, null] +18308 - null - [null, null, null, null, null] +18309 - null - [null, null, null, null, null] +18310 - null - [null, null, null, null, null] +18311 - null - [null, null, null, null, null] +18312 - Stool - [null, null, null, null, null] +18313 - null - [null, null, null, null, null] +18314 - Table - [null, null, null, null, null] +18315 - null - [null, null, null, null, null] +18316 - Chair - [null, null, null, null, null] +18317 - Hanger - [null, null, null, null, null] +18318 - Mirror - [null, null, null, null, null] +18319 - null - [null, null, null, null, null] +18320 - null - [null, null, null, null, null] +18321 - Chest - [null, Search, Shut, null, null] +18322 - Ladder - [Climb-down, null, null, null, null] +18323 - null - [null, null, null, null, null] +18324 - Ladder - [Climb-up, null, null, null, null] +18325 - Ladder - [Climb-down, null, null, null, null] +18326 - Crane - [null, null, null, null, null] +18327 - Crane - [Rotate, null, null, null, null] +18328 - null - [null, null, null, null, null] +18329 - null - [null, null, null, null, null] +18330 - null - [null, null, null, null, null] +18331 - null - [null, null, null, null, null] +18332 - null - [null, null, null, null, null] +18333 - null - [null, null, null, null, null] +18334 - null - [null, null, null, null, null] +18335 - null - [null, null, null, null, null] +18336 - null - [null, null, null, null, null] +18337 - null - [null, null, null, null, null] +18338 - null - [null, null, null, null, null] +18339 - null - [null, null, null, null, null] +18340 - null - [null, null, null, null, null] +18341 - null - [null, null, null, null, null] +18342 - null - [null, null, null, null, null] +18343 - null - [null, null, null, null, null] +18344 - null - [null, null, null, null, null] +18345 - null - [null, null, null, null, null] +18346 - null - [null, null, null, null, null] +18347 - null - [null, null, null, null, null] +18348 - null - [null, null, null, null, null] +18349 - null - [null, null, null, null, null] +18350 - null - [null, null, null, null, null] +18351 - Barrel - [null, null, null, null, null] +18352 - Wreck - [null, null, null, null, null] +18353 - Wreck - [null, null, null, null, null] +18354 - Wreck - [null, null, null, null, null] +18355 - Wreck - [null, null, null, null, null] +18356 - Wreck - [null, null, null, null, null] +18357 - Wreck - [null, null, null, null, null] +18358 - null - [null, null, null, null, null] +18359 - null - [null, null, null, null, null] +18360 - null - [null, null, null, null, null] +18361 - null - [null, null, null, null, null] +18362 - Bed - [null, null, null, null, null] +18363 - Child's bed - [null, null, null, null, null] +18364 - Floats - [null, null, null, null, null] +18365 - Broken boat - [null, null, null, null, null] +18366 - Crow nest - [null, null, null, null, null] +18367 - Crate - [null, null, null, null, null] +18368 - Crate - [null, null, null, null, null] +18369 - null - [null, null, null, null, null] +18370 - null - [null, null, null, null, null] +18371 - null - [null, null, null, null, null] +18372 - null - [null, null, null, null, null] +18373 - null - [null, null, null, null, null] +18374 - null - [null, null, null, null, null] +18375 - null - [null, null, null, null, null] +18376 - null - [null, null, null, null, null] +18377 - null - [null, null, null, null, null] +18378 - null - [null, null, null, null, null] +18379 - null - [null, null, null, null, null] +18380 - Broken wall - [null, null, null, null, null] +18381 - Badly repaired wall - [Kick, null, null, null, null] +18382 - null - [null, null, null, null, null] +18383 - null - [null, null, null, null, null] +18384 - null - [null, null, null, null, null] +18385 - null - [null, null, null, null, null] +18386 - null - [null, null, null, null, null] +18387 - null - [null, null, null, null, null] +18388 - null - [null, null, null, null, null] +18389 - null - [null, null, null, null, null] +18390 - null - [null, null, null, null, null] +18391 - null - [null, null, null, null, null] +18392 - null - [null, null, null, null, null] +18393 - null - [null, null, null, null, null] +18394 - null - [null, null, null, null, null] +18395 - null - [null, null, null, null, null] +18396 - null - [null, null, null, null, null] +18397 - null - [null, null, null, null, null] +18398 - null - [null, null, null, null, null] +18399 - Bone barrel - [null, null, null, null, null] +18400 - Ice cube - [null, null, null, null, null] +18401 - null - [null, null, null, null, null] +18402 - null - [null, null, null, null, null] +18403 - Kennith's ball - [null, null, null, null, null] +18404 - Bottle - [null, null, null, null, null] +18405 - null - [null, null, null, null, null] +18406 - null - [null, null, null, null, null] +18407 - null - [null, null, null, null, null] +18408 - null - [null, null, null, null, null] +18409 - null - [null, null, null, null, null] +18410 - null - [null, null, null, null, null] +18411 - Broken fence - [Climb-over, null, null, null, null] +18412 - Broken boat - [null, null, null, null, null] +18413 - null - [null, null, null, null, null] +18414 - null - [null, null, null, null, null] +18415 - null - [null, null, null, null, null] +18416 - null - [null, null, null, null, null] +18417 - null - [null, null, null, null, null] +18418 - Wall corner - [null, null, null, null, null] +18419 - null - [null, null, null, null, null] +18420 - null - [null, null, null, null, null] +18421 - null - [null, null, null, null, null] +18422 - null - [null, null, null, null, null] +18423 - null - [null, null, null, null, null] +18424 - null - [null, null, null, null, null] +18425 - null - [null, null, null, null, null] +18426 - Torture Rack - [null, null, null, null, null] +18427 - Exit - [Climb-up, null, null, null, null] +18428 - null - [null, null, null, null, null] +18429 - null - [null, null, null, null, null] +18430 - Wall - [Push, null, null, null, null] +18431 - Wall opening - [Enter, null, null, null, null] +18432 - null - [null, null, null, null, null] +18433 - null - [null, null, null, null, null] +18434 - null - [null, null, null, null, null] +18435 - null - [null, null, null, null, null] +18436 - null - [null, null, null, null, null] +18437 - null - [null, null, null, null, null] +18438 - null - [null, null, null, null, null] +18439 - null - [null, null, null, null, null] +18440 - Passage - [Enter, null, null, null, null] +18441 - Imposing Doors - [Open, null, null, null, null] +18442 - Imposing Doors - [Open, null, null, null, null] +18443 - Imposing Doors - [Open, null, null, null, null] +18444 - Shortcut - [Climb-through, null, null, null, null] +18445 - null - [null, null, null, null, null] +18446 - null - [null, null, null, null, null] +18447 - null - [null, null, null, null, null] +18448 - null - [null, null, null, null, null] +18449 - null - [null, null, null, null, null] +18450 - null - [null, null, null, null, null] +18451 - null - [null, null, null, null, null] +18452 - null - [null, null, null, null, null] +18453 - null - [null, null, null, null, null] +18454 - null - [null, null, null, null, null] +18455 - null - [null, null, null, null, null] +18456 - null - [null, null, null, null, null] +18457 - null - [null, null, null, null, null] +18458 - null - [null, null, null, null, null] +18459 - null - [null, null, null, null, null] +18460 - null - [null, null, null, null, null] +18461 - null - [null, null, null, null, null] +18462 - Slug goo - [null, null, null, null, null] +18463 - null - [null, null, null, null, null] +18464 - null - [null, null, null, null, null] +18465 - null - [null, null, null, null, null] +18466 - null - [null, null, null, null, null] +18467 - null - [null, null, null, null, null] +18468 - null - [null, null, null, null, null] +18469 - null - [null, null, null, null, null] +18470 - null - [null, null, null, null, null] +18471 - null - [null, null, null, null, null] +18472 - null - [null, null, null, null, null] +18473 - null - [null, null, null, null, null] +18474 - null - [null, null, null, null, null] +18475 - null - [null, null, null, null, null] +18476 - null - [null, null, null, null, null] +18477 - null - [null, null, null, null, null] +18478 - null - [null, null, null, null, null] +18479 - null - [null, null, null, null, null] +18480 - null - [null, null, null, null, null] +18481 - null - [null, null, null, null, null] +18482 - Big fish - [null, null, null, null, null] +18483 - Shelves - [null, null, null, null, null] +18484 - null - [null, null, null, null, null] +18485 - Stool - [null, null, null, null, null] +18486 - Table - [null, null, null, null, null] +18487 - null - [null, null, null, null, null] +18488 - Bench - [null, null, null, null, null] +18489 - Door - [Open, null, null, null, null] +18490 - Door - [Close, null, null, null, null] +18491 - Bank booth - [Use, Use-quickly, Collect, null, null] +18492 - Closed booth - [null, null, null, null, null] +18493 - Signpost - [Read, null, null, null, null] +18494 - null - [null, null, null, null, null] +18495 - Bookcase - [Search, null, null, null, null] +18496 - null - [null, null, null, null, null] +18497 - Furnace - [null, Smelt, null, null, null] +18498 - null - [null, null, null, null, null] +18499 - null - [null, null, null, null, null] +18500 - null - [null, null, null, null, null] +18501 - Crane - [null, null, null, null, null] +18502 - Crate - [Search, null, null, null, null] +18503 - Staircase - [Climb-up, null, null, null, null] +18504 - Staircase - [Climb-down, null, null, null, null] +18505 - Odd looking wall - [Pass, null, null, null, null] +18506 - Crate - [Search, null, null, null, null] +18507 - Crate - [Search, null, null, null, null] +18508 - Crates - [Search, null, null, null, null] +18509 - Water controls - [Turn, null, null, null, null] +18510 - Water controls - [Turn, null, null, null, null] +18511 - Water wheel - [null, null, null, null, null] +18512 - Water wheel - [null, null, null, null, null] +18513 - null - [null, null, null, null, null] +18514 - null - [null, null, null, null, null] +18515 - Bellows - [null, null, null, null, null] +18516 - Bellows - [Fix, null, null, null, null] +18517 - null - [null, null, null, null, null] +18518 - null - [null, null, null, null, null] +18519 - Lava trough - [null, null, null, null, null] +18520 - Lava trough - [null, null, null, null, null] +18521 - Lava trough - [null, null, null, null, null] +18522 - Lava trough - [null, null, null, null, null] +18523 - Lava trough - [null, null, null, null, null] +18524 - null - [null, null, null, null, null] +18525 - Furnace - [null, null, null, null, null] +18526 - Furnace - [null, null, null, null, null] +18527 - null - [null, null, null, null, null] +18528 - null - [null, null, null, null, null] +18529 - null - [null, null, null, null, null] +18530 - Machinery - [null, null, null, null, null] +18531 - null - [null, null, null, null, null] +18532 - null - [null, null, null, null, null] +18533 - null - [null, null, null, null, null] +18534 - null - [null, null, null, null, null] +18535 - null - [null, null, null, null, null] +18536 - null - [null, null, null, null, null] +18537 - null - [null, null, null, null, null] +18538 - null - [null, null, null, null, null] +18539 - null - [null, null, null, null, null] +18540 - null - [null, null, null, null, null] +18541 - null - [null, null, null, null, null] +18542 - null - [null, null, null, null, null] +18543 - null - [null, null, null, null, null] +18544 - null - [null, null, null, null, null] +18545 - null - [null, null, null, null, null] +18546 - null - [null, null, null, null, null] +18547 - null - [null, null, null, null, null] +18548 - null - [null, null, null, null, null] +18549 - null - [null, null, null, null, null] +18550 - null - [null, null, null, null, null] +18551 - null - [null, null, null, null, null] +18552 - null - [null, null, null, null, null] +18553 - null - [null, null, null, null, null] +18554 - null - [null, null, null, null, null] +18555 - null - [null, null, null, null, null] +18556 - null - [null, null, null, null, null] +18557 - null - [null, null, null, null, null] +18558 - null - [null, null, null, null, null] +18559 - null - [null, null, null, null, null] +18560 - null - [null, null, null, null, null] +18561 - null - [null, null, null, null, null] +18562 - null - [null, null, null, null, null] +18563 - null - [null, null, null, null, null] +18564 - null - [null, null, null, null, null] +18565 - null - [null, null, null, null, null] +18566 - null - [null, null, null, null, null] +18567 - null - [null, null, null, null, null] +18568 - null - [null, null, null, null, null] +18569 - null - [null, null, null, null, null] +18570 - null - [null, null, null, null, null] +18571 - null - [null, null, null, null, null] +18572 - null - [null, null, null, null, null] +18573 - null - [null, null, null, null, null] +18574 - null - [null, null, null, null, null] +18575 - null - [null, null, null, null, null] +18576 - null - [null, null, null, null, null] +18577 - null - [null, null, null, null, null] +18578 - null - [null, null, null, null, null] +18579 - null - [null, null, null, null, null] +18580 - null - [null, null, null, null, null] +18581 - null - [null, null, null, null, null] +18582 - null - [null, null, null, null, null] +18583 - null - [null, null, null, null, null] +18584 - null - [null, null, null, null, null] +18585 - null - [null, null, null, null, null] +18586 - null - [null, null, null, null, null] +18587 - Machinery - [null, null, null, null, null] +18588 - null - [null, null, null, null, null] +18589 - null - [null, null, null, null, null] +18590 - null - [null, null, null, null, null] +18591 - null - [null, null, null, null, null] +18592 - null - [null, null, null, null, null] +18593 - null - [null, null, null, null, null] +18594 - Machinery - [Search, null, null, null, null] +18595 - Hatch - [Open, null, null, null, null] +18596 - Hatch - [Climb-down, null, null, null, null] +18597 - Stairwell - [Climb-down, null, null, null, null] +18598 - Stairs - [Climb-up, null, null, null, null] +18599 - Stairs - [Climb-up, null, null, null, null] +18600 - null - [null, null, null, null, null] +18601 - null - [null, null, null, null, null] +18602 - null - [null, null, null, null, null] +18603 - null - [null, null, null, null, null] +18604 - null - [null, null, null, null, null] +18605 - null - [null, null, null, null, null] +18606 - null - [null, null, null, null, null] +18607 - null - [null, null, null, null, null] +18608 - null - [null, null, null, null, null] +18609 - null - [null, null, null, null, null] +18610 - Stairs - [Climb-up, null, null, null, null] +18611 - Stairs - [Climb-down, null, null, null, null] +18612 - Crate - [Search, null, null, null, null] +18613 - Crate - [Search, null, null, null, null] +18614 - Crates - [Search, null, null, null, null] +18615 - Crates - [Search, null, null, null, null] +18616 - Crate - [Search, null, null, null, null] +18617 - Crates - [Search, null, null, null, null] +18618 - Crate - [Search, null, null, null, null] +18619 - Crate - [Search, null, null, null, null] +18620 - Lever - [Pull, null, null, null, null] +18621 - An old lever - [Pull, null, null, null, null] +18622 - An old lever - [Pull, null, null, null, null] +18623 - Old crane - [null, null, null, null, null] +18624 - Old crane - [null, null, null, null, null] +18625 - Old crane - [null, null, null, null, null] +18626 - Old crane - [null, null, null, null, null] +18627 - Old crane - [null, null, null, null, null] +18628 - Old crane - [null, null, null, null, null] +18629 - Old crane - [null, null, null, null, null] +18630 - Old crane - [null, null, null, null, null] +18631 - Old crane - [null, null, null, null, null] +18632 - Old crane - [null, null, null, null, null] +18633 - Old crane - [null, null, null, null, null] +18634 - Old crane - [null, null, null, null, null] +18635 - Old crane - [null, null, null, null, null] +18636 - Old crane - [null, null, null, null, null] +18637 - Old crane - [null, null, null, null, null] +18638 - Old Crane - [null, null, null, null, null] +18639 - null - [null, null, null, null, null] +18640 - An old lever - [Pull, null, null, null, null] +18641 - Junction box - [Open, null, null, null, null] +18642 - Press support - [null, null, null, null, null] +18643 - Steam press - [null, null, null, null, null] +18644 - Steam press - [null, null, null, null, null] +18645 - Steam press - [null, null, null, null, null] +18646 - Water valve - [Turn, null, null, null, null] +18647 - Water valve - [Turn, null, null, null, null] +18648 - An old lever - [Pull, null, null, null, null] +18649 - Corkscrew lever - [Turn, null, null, null, null] +18650 - Piping - [null, null, null, null, null] +18651 - Door - [null, null, null, null, null] +18652 - Door - [null, null, null, null, null] +18653 - Door - [null, null, null, null, null] +18654 - Door - [null, null, null, null, null] +18655 - Door - [null, null, null, null, null] +18656 - Door - [null, null, null, null, null] +18657 - Door - [null, null, null, null, null] +18658 - Door - [null, null, null, null, null] +18659 - Door - [null, null, null, null, null] +18660 - Water Tank - [null, null, null, null, null] +18661 - Water Tank - [null, null, null, null, null] +18662 - null - [null, null, null, null, null] +18663 - An old lever - [Pull, null, null, null, null] +18664 - Pin - [null, null, null, null, null] +18665 - Pin - [null, null, null, null, null] +18666 - Pin - [null, null, null, null, null] +18667 - Cog - [Take, null, null, null, null] +18668 - Cog - [Take, null, null, null, null] +18669 - Cog - [Take, null, null, null, null] +18670 - Cog - [Take, null, null, null, null] +18671 - Cog - [Take, null, null, null, null] +18672 - Cog - [Take, null, null, null, null] +18673 - Cog - [Take, null, null, null, null] +18674 - Cog - [Take, null, null, null, null] +18675 - Cog - [Take, null, null, null, null] +18676 - Cog - [Take, null, null, null, null] +18677 - Cog - [Take, null, null, null, null] +18678 - Cog - [Take, null, null, null, null] +18679 - Cog - [Take, null, null, null, null] +18680 - Cog - [Take, null, null, null, null] +18681 - Cog - [Take, null, null, null, null] +18682 - Cog - [Take, null, null, null, null] +18683 - Cog - [Take, null, null, null, null] +18684 - Cog - [Take, null, null, null, null] +18685 - Fan blade - [null, null, null, null, null] +18686 - Fan blade - [null, null, null, null, null] +18687 - Fan blade - [null, null, null, null, null] +18688 - null - [null, null, null, null, null] +18689 - null - [null, null, null, null, null] +18690 - Extractor hat - [Operate, null, null, null, null] +18691 - Extractor hat - [Operate, null, null, null, null] +18692 - Extractor hat-top - [null, null, null, null, null] +18693 - Extractor gun - [null, null, null, null, null] +18694 - Extractor gun - [Take-from, null, null, null, null] +18695 - Extractor gun - [Take-from, null, null, null, null] +18696 - Extractor gun - [null, null, null, null, null] +18697 - null - [null, null, null, null, null] +18698 - Mind Door - [Open, null, null, null, null] +18699 - Mind Door - [Close, null, null, null, null] +18700 - Mind Door - [Open, null, null, null, null] +18701 - Mind Door - [Close, null, null, null, null] +18702 - Door - [Open, null, null, null, null] +18703 - Door - [Open, null, null, null, null] +18704 - Connection pipe - [null, null, null, null, null] +18705 - Connection pipe - [null, null, null, null, null] +18706 - Connection pipe - [null, null, null, null, null] +18707 - Connection pipe - [null, null, null, null, null] +18708 - null - [null, null, null, null, null] +18709 - null - [null, null, null, null, null] +18710 - Stairs - [null, null, null, null, null] +18711 - Schematic crate - [Take-from, null, null, null, null] +18712 - null - [null, null, null, null, null] +18713 - null - [null, null, null, null, null] +18714 - null - [null, null, null, null, null] +18715 - null - [null, null, null, null, null] +18716 - null - [null, null, null, null, null] +18717 - null - [null, null, null, null, null] +18718 - null - [null, null, null, null, null] +18719 - null - [null, null, null, null, null] +18720 - null - [null, null, null, null, null] +18721 - null - [null, null, null, null, null] +18722 - null - [null, null, null, null, null] +18723 - null - [null, null, null, null, null] +18724 - null - [null, null, null, null, null] +18725 - null - [null, null, null, null, null] +18726 - Piping - [null, null, null, null, null] +18727 - null - [null, null, null, null, null] +18728 - null - [null, null, null, null, null] +18729 - null - [null, null, null, null, null] +18730 - null - [null, null, null, null, null] +18731 - null - [null, null, null, null, null] +18732 - null - [null, null, null, null, null] +18733 - null - [null, null, null, null, null] +18734 - null - [null, null, null, null, null] +18735 - null - [null, null, null, null, null] +18736 - null - [null, null, null, null, null] +18737 - null - [null, null, null, null, null] +18738 - null - [null, null, null, null, null] +18739 - null - [null, null, null, null, null] +18740 - null - [null, null, null, null, null] +18741 - null - [null, null, null, null, null] +18742 - null - [null, null, null, null, null] +18743 - null - [null, null, null, null, null] +18744 - null - [null, null, null, null, null] +18745 - null - [null, null, null, null, null] +18746 - Mine cart sign - [null, null, null, null, null] +18747 - Track - [null, null, null, null, null] +18748 - null - [null, null, null, null, null] +18749 - null - [null, null, null, null, null] +18750 - Track - [null, null, null, null, null] +18751 - Track - [null, null, null, null, null] +18752 - null - [null, null, null, null, null] +18753 - null - [null, null, null, null, null] +18754 - null - [null, null, null, null, null] +18755 - null - [null, null, null, null, null] +18756 - null - [null, null, null, null, null] +18757 - null - [null, null, null, null, null] +18758 - Tunnel roof - [null, null, null, null, null] +18759 - Tunnel roof - [null, null, null, null, null] +18760 - Tunnel wall - [null, null, null, null, null] +18761 - null - [null, null, null, null, null] +18762 - null - [null, null, null, null, null] +18763 - null - [null, null, null, null, null] +18764 - null - [null, null, null, null, null] +18765 - null - [null, null, null, null, null] +18766 - Oak cape rack - [Search, null, null, null, Remove] +18767 - Teak cape rack - [Search, null, null, null, Remove] +18768 - Mahogany cape rack - [Search, null, null, null, Remove] +18769 - Gilded cape rack - [Search, null, null, null, Remove] +18770 - Marble cape rack - [Search, null, null, null, Remove] +18771 - Magic cape rack - [Search, null, null, null, Remove] +18772 - Fancy dress box - [Open, null, null, null, Remove] +18773 - Fancy dress box - [Search, Close, null, null, null] +18774 - Fancy dress box - [Open, null, null, null, Remove] +18775 - Fancy dress box - [Search, Close, null, null, null] +18776 - Fancy dress box - [Open, null, null, null, Remove] +18777 - Fancy dress box - [Search, Close, null, null, null] +18778 - Armour case - [Open, null, null, null, Remove] +18779 - Armour case - [Search, Close, null, null, null] +18780 - Armour case - [Open, null, null, null, Remove] +18781 - Armour case - [Search, Close, null, null, null] +18782 - Armour case - [Open, null, null, null, Remove] +18783 - Armour case - [Search, Close, null, null, null] +18784 - Magic wardrobe - [Open, null, null, null, Remove] +18785 - Magic wardrobe - [Search, Close, null, null, null] +18786 - Magic wardrobe - [Open, null, null, null, Remove] +18787 - Magic wardrobe - [Search, Close, null, null, null] +18788 - Magic wardrobe - [Open, null, null, null, Remove] +18789 - Magic wardrobe - [Search, Close, null, null, null] +18790 - Magic wardrobe - [Open, null, null, null, Remove] +18791 - Magic wardrobe - [Search, Close, null, null, null] +18792 - Magic wardrobe - [Open, null, null, null, Remove] +18793 - Magic wardrobe - [Search, Close, null, null, null] +18794 - Magic wardrobe - [Open, null, null, null, Remove] +18795 - Magic wardrobe - [Search, Close, null, null, null] +18796 - Magic wardrobe - [Open, null, null, null, Remove] +18797 - Magic wardrobe - [Search, Close, null, null, null] +18798 - Toy box - [Open, null, null, null, Remove] +18799 - Toy box - [Search, Close, null, null, null] +18800 - Toy box - [Open, null, null, null, Remove] +18801 - Toy box - [Search, Close, null, null, null] +18802 - Toy box - [Open, null, null, null, Remove] +18803 - Toy box - [Search, Close, null, null, null] +18804 - Treasure chest - [Open, null, null, null, Remove] +18805 - Treasure chest - [Search, Close, null, null, null] +18806 - Treasure chest - [Open, null, null, null, Remove] +18807 - Treasure chest - [Search, Close, null, null, null] +18808 - Treasure chest - [Open, null, null, null, Remove] +18809 - Treasure chest - [Search, Close, null, null, null] +18810 - Cape rack space - [null, null, null, null, Build] +18811 - Magic wardrobe space - [null, null, null, null, Build] +18812 - Toy box space - [null, null, null, null, Build] +18813 - Treasure chest space - [null, null, null, null, Build] +18814 - Fancy dress box space - [null, null, null, null, Build] +18815 - Armour case space - [null, null, null, null, Build] +18816 - null - [null, null, null, null, null] +18817 - Rocks - [null, null, null, null, null] +18818 - Herb patch - [null, Inspect, null, null, null] +18819 - Herb patch - [null, Inspect, null, null, null] +18820 - Herb patch - [null, Inspect, null, null, null] +18821 - Herb patch - [null, Inspect, null, null, null] +18822 - Herb patch - [null, Inspect, null, null, null] +18823 - Herb patch - [null, Inspect, null, null, null] +18824 - Herbs - [null, Inspect, null, null, null] +18825 - Herbs - [null, Inspect, null, null, null] +18826 - Herbs - [Pick, Inspect, null, null, null] +18827 - Diseased herbs - [null, Inspect, null, null, null] +18828 - Diseased herbs - [null, Inspect, null, null, null] +18829 - Diseased herbs - [null, Inspect, null, null, null] +18830 - Dead herbs - [null, Inspect, null, null, null] +18831 - Dead herbs - [null, Inspect, null, null, null] +18832 - Dead herbs - [null, Inspect, null, null, null] +18833 - Troll ladder - [Climb-down, null, null, null, null] +18834 - Troll ladder - [Climb-up, null, null, null, null] +18835 - Crate - [null, null, null, null, null] +18836 - Tree branch - [null, null, null, null, null] +18837 - Goat - [null, null, null, null, null] +18838 - Trolley - [null, null, null, null, null] +18839 - Fish - [null, null, null, null, null] +18840 - Rocks - [null, null, null, null, null] +18841 - Dolphin - [null, null, null, null, null] +18842 - Fish - [null, null, null, null, null] +18843 - Ladder - [Climb-down, null, null, null, null] +18844 - null - [null, null, null, null, null] +18845 - Soil patch - [null, null, null, null, null] +18846 - Soil patch - [null, null, null, null, null] +18847 - Weeds - [null, null, null, null, null] +18848 - Weeds - [null, null, null, null, null] +18849 - Weeds - [null, null, null, null, null] +18850 - New farming patch - [null, null, null, null, null] +18851 - Hardy goutweed - [null, null, null, null, null] +18852 - Diseased hardy goutweed - [null, null, null, null, null] +18853 - Dead hardy goutweed - [null, null, null, null, null] +18854 - Hardy goutweed - [null, null, null, null, null] +18855 - Hardy goutweed - [Pick, null, null, null, null] +18856 - Parasol - [null, null, null, null, null] +18857 - null - [null, null, null, null, null] +18858 - null - [null, null, null, null, null] +18859 - null - [null, null, null, null, null] +18860 - null - [null, null, null, null, null] +18861 - null - [null, null, null, null, null] +18862 - null - [null, null, null, null, null] +18863 - null - [null, null, null, null, null] +18864 - Drunken Dwarf - [null, null, null, null, null] +18865 - Broken beer glass - [null, null, null, null, null] +18866 - Deckchair - [null, null, null, null, null] +18867 - null - [null, null, null, null, null] +18868 - null - [null, null, null, null, null] +18869 - Cell wall window - [Bend, null, null, null, null] +18870 - Cell wall window - [Escape, null, null, null, null] +18871 - Rock - [null, Climb, null, null, null] +18872 - Rock - [null, Climb, null, null, null] +18873 - Rock - [null, Climb, null, null, null] +18874 - Danger sign - [null, null, null, null, null] +18875 - Cactus - [Inspect, null, null, null, null] +18876 - Sign post - [null, null, null, null, null] +18877 - Footprints - [Look at, Search, null, null, null] +18878 - Footprints - [Look at, Search, null, null, null] +18879 - Footprints - [Look at, Search, null, null, null] +18880 - Footprints - [Look at, Search, null, null, null] +18881 - Footprints - [Look at, Search, null, null, null] +18882 - Footprints - [Look at, Search, null, null, null] +18883 - Footprints - [Look at, Search, null, null, null] +18884 - Footprints - [Look at, Search, null, null, null] +18885 - Footprints - [Look at, Search, null, null, null] +18886 - Footprints - [Look at, Search, null, null, null] +18887 - Barrel - [null, null, null, null, null] +18888 - Winch - [Look at, Operate, null, null, null] +18889 - Crate - [Search, null, null, null, null] +18890 - Crate - [null, null, null, null, null] +18891 - null - [null, null, null, null, null] +18892 - Rockslide - [null, null, null, null, null] +18893 - Rockslide - [null, null, null, null, null] +18894 - Rockslide - [null, null, null, null, null] +18895 - Rockslide - [null, null, null, null, null] +18896 - null - [null, null, null, null, null] +18897 - null - [null, null, null, null, null] +18898 - Footprints - [Look at, Search, null, null, null] +18899 - Footprints - [Look at, Search, null, null, null] +18900 - Footprints - [Look at, Search, null, null, null] +18901 - null - [null, null, null, null, null] +18902 - Table - [null, Search, null, null, null] +18903 - Ladder - [Climb-up, null, null, null, null] +18904 - Ladder - [Climb-down, null, null, null, null] +18905 - null - [null, null, null, null, null] +18906 - null - [null, null, null, null, null] +18907 - Chest - [Open, null, null, null, null] +18908 - null - [null, null, null, null, null] +18909 - null - [null, null, null, null, null] +18910 - null - [null, null, null, null, null] +18911 - null - [null, null, null, null, null] +18912 - null - [null, null, null, null, null] +18913 - null - [null, null, null, null, null] +18914 - null - [null, null, null, null, null] +18915 - null - [null, null, null, null, null] +18916 - null - [null, null, null, null, null] +18917 - null - [null, null, null, null, null] +18918 - Crate - [null, null, null, null, null] +18919 - Crate - [null, null, null, null, null] +18920 - Barrel - [null, null, null, null, null] +18921 - Barrel - [null, null, null, null, null] +18922 - Cliff edge - [Climb-down, null, null, null, null] +18923 - Cliff - [Climb-up, null, null, null, null] +18924 - Cliff - [Climb-down, null, null, null, null] +18925 - null - [null, null, null, null, null] +18926 - null - [null, null, null, null, null] +18927 - null - [null, null, null, null, null] +18928 - null - [null, null, null, null, null] +18929 - null - [null, null, null, null, null] +18930 - null - [null, null, null, null, null] +18931 - null - [null, null, null, null, null] +18932 - null - [null, null, null, null, null] +18933 - null - [null, null, null, null, null] +18934 - null - [null, null, null, null, null] +18935 - null - [null, null, null, null, null] +18936 - null - [null, null, null, null, null] +18937 - null - [null, null, null, null, null] +18938 - Cart track sign - [null, null, null, null, null] +18939 - null - [null, null, null, null, null] +18940 - null - [null, null, null, null, null] +18941 - null - [null, null, null, null, null] +18942 - null - [null, null, null, null, null] +18943 - null - [null, null, null, null, null] +18944 - null - [null, null, null, null, null] +18945 - null - [null, null, null, null, null] +18946 - Buffers - [null, null, null, null, null] +18947 - null - [null, null, null, null, null] +18948 - null - [null, null, null, null, null] +18949 - null - [null, null, null, null, null] +18950 - null - [null, null, null, null, null] +18951 - Winch bucket - [Look at, Use, null, null, null] +18952 - Rocks - [Mine, Prospect, hidden, null, null] +18953 - Rocks - [Mine, Prospect, hidden, null, null] +18954 - Rocks - [Mine, Prospect, hidden, null, null] +18955 - Skeleton - [null, null, null, null, null] +18956 - Skeleton - [null, null, null, null, null] +18957 - Skeleton - [null, null, null, null, null] +18958 - Wooden cart - [Look at, Search, null, null, null] +18959 - Wooden cart - [Look at, Search, null, null, null] +18960 - Cart Camel - [Talk-to, null, null, null, null] +18961 - Rocks - [Mine, Prospect, hidden, null, null] +18962 - Barrel - [Look-in, Search, null, null, null] +18963 - null - [null, null, null, null, null] +18964 - null - [null, null, null, null, null] +18965 - null - [null, null, null, null, null] +18966 - null - [null, null, null, null, null] +18967 - Rocks - [Mine, Prospect, hidden, null, null] +18968 - Rocks - [Mine, Prospect, hidden, null, null] +18969 - Rocks - [Mine, Prospect, hidden, null, null] +18970 - Rocks - [Mine, Prospect, hidden, null, null] +18971 - Rocks - [Mine, Prospect, hidden, null, null] +18972 - Rocks - [Mine, Prospect, hidden, null, null] +18973 - Rocks - [Mine, Prospect, hidden, null, null] +18974 - Rocks - [Mine, Prospect, hidden, null, null] +18975 - Rocks - [Mine, Prospect, hidden, null, null] +18976 - Rocks - [Mine, Prospect, hidden, null, null] +18977 - Rocks - [Mine, Prospect, hidden, null, null] +18978 - Rocks - [Mine, Prospect, hidden, null, null] +18979 - Rocks - [Mine, Prospect, hidden, null, null] +18980 - Rocks - [Mine, Prospect, hidden, null, null] +18981 - Rocks - [Mine, Prospect, hidden, null, null] +18982 - Rocks - [Mine, Prospect, hidden, null, null] +18983 - Rocks - [Mine, Prospect, hidden, null, null] +18984 - Rocks - [Mine, Prospect, hidden, null, null] +18985 - Rocks - [Mine, Prospect, hidden, null, null] +18986 - Rocks - [Mine, Prospect, hidden, null, null] +18987 - Rocks - [Mine, Prospect, hidden, null, null] +18988 - Rocks - [Mine, Prospect, hidden, null, null] +18989 - Rocks - [Mine, Prospect, hidden, null, null] +18990 - Rocks - [Mine, Prospect, hidden, null, null] +18991 - Rocks - [Mine, Prospect, hidden, null, null] +18992 - Rocks - [Mine, Prospect, hidden, null, null] +18993 - Rocks - [Mine, Prospect, hidden, null, null] +18994 - Rocks - [Mine, Prospect, hidden, null, null] +18995 - Rocks - [Mine, Prospect, hidden, null, null] +18996 - Rocks - [Mine, Prospect, hidden, null, null] +18997 - Rocks - [Mine, Prospect, hidden, null, null] +18998 - Rocks - [Mine, Prospect, hidden, null, null] +18999 - Rocks - [Mine, Prospect, hidden, null, null] +19000 - Rocks - [Mine, Prospect, hidden, null, null] +19001 - Rocks - [Mine, Prospect, hidden, null, null] +19002 - Rocks - [Mine, Prospect, hidden, null, null] +19003 - Rocks - [Mine, Prospect, hidden, null, null] +19004 - Rocks - [Mine, Prospect, hidden, null, null] +19005 - Rocks - [Mine, Prospect, hidden, null, null] +19006 - Rocks - [Mine, Prospect, hidden, null, null] +19007 - Rocks - [Mine, Prospect, hidden, null, null] +19008 - Rocks - [Mine, Prospect, hidden, null, null] +19009 - Rocks - [Mine, Prospect, hidden, null, null] +19010 - Rocks - [Mine, Prospect, hidden, null, null] +19011 - Rocks - [Mine, Prospect, hidden, null, null] +19012 - Rocks - [Mine, Prospect, hidden, null, null] +19013 - Rocks - [Mine, Prospect, hidden, null, null] +19014 - Rocks - [Mine, Prospect, hidden, null, null] +19015 - Rocks - [Mine, Prospect, hidden, null, null] +19016 - Rocks - [Mine, Prospect, hidden, null, null] +19017 - Rocks - [Mine, Prospect, hidden, null, null] +19018 - Rocks - [Mine, Prospect, hidden, null, null] +19019 - Rocks - [Mine, Prospect, hidden, null, null] +19020 - Rocks - [Mine, Prospect, hidden, null, null] +19021 - Rocks - [Mine, Prospect, hidden, null, null] +19022 - Rocks - [Mine, Prospect, hidden, null, null] +19023 - Rocks - [Mine, Prospect, hidden, null, null] +19024 - Rocks - [Mine, Prospect, hidden, null, null] +19025 - Rocks - [Mine, Prospect, hidden, null, null] +19026 - Rocks - [Mine, Prospect, hidden, null, null] +19027 - Rocks - [Mine, Prospect, hidden, null, null] +19028 - Rocks - [Mine, Prospect, hidden, null, null] +19029 - Rocks - [Mine, Prospect, hidden, null, null] +19030 - Snow - [Make-ball-of, null, hidden, null, null] +19031 - Snow - [Make-ball-of, null, hidden, null, null] +19032 - Large root - [Pull Up, null, null, null, null] +19033 - Snow - [Make-ball-of, null, hidden, null, null] +19034 - Snow - [Make-ball-of, null, hidden, null, null] +19035 - Snow - [Make-ball-of, null, hidden, null, null] +19036 - Cage - [null, null, null, null, null] +19037 - Cage with gublinch - [null, null, null, null, null] +19038 - Wintumber tree - [Dig-up, hidden, null, null, null] +19039 - Cave entrance - [Climb-down, Search, null, null, null] +19040 - Ladder - [Climb-up, null, null, null, null] +19041 - null - [null, null, null, null, null] +19042 - null - [null, null, null, null, null] +19043 - null - [null, null, null, null, null] +19044 - null - [null, null, null, null, null] +19045 - null - [null, null, null, null, null] +19046 - null - [null, null, null, null, null] +19047 - null - [null, null, null, null, null] +19048 - null - [null, null, null, null, null] +19049 - null - [null, null, null, null, null] +19050 - null - [null, null, null, null, null] +19051 - null - [null, null, null, null, null] +19052 - null - [null, null, null, null, null] +19053 - null - [null, null, null, null, null] +19054 - null - [null, null, null, null, null] +19055 - null - [null, null, null, null, null] +19056 - null - [null, null, null, null, null] +19057 - null - [null, null, null, null, null] +19058 - null - [null, null, null, null, null] +19059 - null - [null, null, null, null, null] +19060 - null - [null, null, null, null, null] +19061 - null - [null, null, null, null, null] +19062 - null - [null, null, null, null, null] +19063 - null - [null, null, null, null, null] +19064 - Paint cans - [null, null, null, null, null] +19065 - Large box - [null, null, null, null, null] +19066 - Puppet arms - [null, null, null, null, null] +19067 - Puppet arms - [null, null, null, null, null] +19068 - Puppet heads - [null, null, null, null, null] +19069 - Puppet heads - [null, null, null, null, null] +19070 - Crate - [null, null, null, null, null] +19071 - Crates - [null, null, null, null, null] +19072 - Crate - [null, null, null, null, null] +19073 - Crate - [null, null, null, null, null] +19074 - Crate - [null, null, null, null, null] +19075 - null - [null, null, null, null, null] +19076 - null - [null, null, null, null, null] +19077 - null - [null, null, null, null, null] +19078 - null - [null, null, null, null, null] +19079 - null - [null, null, null, null, null] +19080 - null - [null, null, null, null, null] +19081 - null - [null, null, null, null, null] +19082 - null - [null, null, null, null, null] +19083 - null - [null, null, null, null, null] +19084 - null - [null, null, null, null, null] +19085 - Decorations box - [null, null, null, null, null] +19086 - Decorations box - [null, null, null, null, null] +19087 - null - [null, null, null, null, null] +19088 - null - [null, null, null, null, null] +19089 - null - [null, null, null, null, null] +19090 - null - [null, null, null, null, null] +19091 - null - [null, null, null, null, null] +19092 - null - [null, null, null, null, null] +19093 - Climbing rope - [Climb, null, null, null, null] +19094 - Decorations box - [null, null, null, null, null] +19095 - Decorations box - [null, null, null, null, null] +19096 - Decorations box - [null, null, null, null, null] +19097 - Decorations box - [null, null, null, null, null] +19098 - Decorations box - [null, null, null, null, null] +19099 - Paint cans - [null, null, null, null, null] +19100 - Paint cans - [null, null, null, null, null] +19101 - Paint cans - [null, null, null, null, null] +19102 - Puppet torsos - [null, null, null, null, null] +19103 - Puppet legs - [null, null, null, null, null] +19104 - Puppet heads - [null, null, null, null, null] +19105 - Puppet torsos - [null, null, null, null, null] +19106 - Puppet legs - [null, null, null, null, null] +19107 - Puppet torsos - [null, null, null, null, null] +19108 - Puppet arms - [null, null, null, null, null] +19109 - Puppet legs - [null, null, null, null, null] +19110 - Roots - [Climb, null, null, null, null] +19111 - Roots - [null, null, null, null, null] +19112 - null - [null, null, null, null, null] +19113 - null - [null, null, null, null, null] +19114 - null - [null, null, null, null, null] +19115 - null - [null, null, null, null, null] +19116 - null - [null, null, null, null, null] +19117 - null - [null, null, null, null, null] +19118 - null - [null, null, null, null, null] +19119 - null - [null, null, null, null, null] +19120 - null - [null, null, null, null, null] +19121 - null - [null, null, null, null, null] +19122 - null - [null, null, null, null, null] +19123 - null - [null, null, null, null, null] +19124 - Shark head - [null, null, null, null, null] +19125 - Dirt - [Leave, null, null, null, null] +19126 - Plank - [Use, null, null, null, null] +19127 - Candles - [Steal, null, null, null, null] +19128 - Basket - [Use, null, null, null, null] +19129 - Basket - [Use, null, null, null, null] +19130 - Air balloon - [null, null, null, null, null] +19131 - Rock - [null, null, null, null, null] +19132 - Basket - [null, null, null, null, null] +19133 - null - [null, null, null, null, null] +19134 - null - [null, null, null, null, null] +19135 - null - [null, null, null, null, null] +19136 - null - [null, null, null, null, null] +19137 - null - [null, null, null, null, null] +19138 - null - [null, null, null, null, null] +19139 - null - [null, null, null, null, null] +19140 - null - [null, null, null, null, null] +19141 - null - [null, null, null, null, null] +19142 - null - [null, null, null, null, null] +19143 - null - [null, null, null, null, null] +19144 - null - [null, null, null, null, null] +19145 - Altar - [Pray-at, null, null, null, null] +19146 - null - [null, null, null, null, null] +19147 - null - [null, null, null, null, null] +19148 - null - [null, null, null, null, null] +19149 - null - [null, null, null, null, null] +19150 - null - [null, null, null, null, null] +19151 - null - [null, null, null, null, null] +19152 - null - [null, null, null, null, null] +19153 - null - [null, null, null, null, null] +19154 - null - [null, null, null, null, null] +19155 - null - [null, null, null, null, null] +19156 - Basket - [null, null, null, null, null] +19157 - Bed - [null, null, null, null, null] +19158 - Table - [null, null, null, null, null] +19159 - Bookcase - [Search, null, null, null, null] +19160 - null - [null, null, null, null, null] +19161 - Basket - [null, null, null, null, null] +19162 - Frame - [null, null, null, null, null] +19163 - null - [null, null, null, null, null] +19164 - Basket - [null, null, null, null, null] +19165 - Tree - [null, null, null, null, null] +19166 - Tree - [null, null, null, null, null] +19167 - Tree - [null, null, null, null, null] +19168 - null - [null, null, null, null, null] +19169 - null - [null, null, null, null, null] +19170 - null - [null, null, null, null, null] +19171 - Loose Railing - [Squeeze-through, null, null, null, null] +19172 - Raw bird - [null, null, null, null, null] +19173 - Raw hunting beast - [null, null, null, null, null] +19174 - Bird snare - [Dismantle, null, null, null, null] +19175 - Bird snare - [Dismantle, Investigate, null, null, null] +19176 - Bird snare - [null, null, null, null, null] +19177 - Bird snare - [null, null, null, null, null] +19178 - Bird snare - [Check, null, null, null, null] +19179 - Bird snare - [null, null, null, null, null] +19180 - Bird snare - [Check, null, null, null, null] +19181 - Bird snare - [null, null, null, null, null] +19182 - Bird snare - [Check, null, null, null, null] +19183 - Bird snare - [null, null, null, null, null] +19184 - Bird snare - [Check, null, null, null, null] +19185 - Bird snare - [null, null, null, null, null] +19186 - Bird snare - [Check, null, null, null, null] +19187 - Box trap - [Dismantle, Investigate, null, null, null] +19188 - Box trap - [null, null, null, null, null] +19189 - Shaking box - [Check, null, null, null, null] +19190 - Shaking box - [Check, null, null, null, null] +19191 - Shaking box - [Check, null, null, null, null] +19192 - Box trap - [Dismantle, null, null, null, null] +19193 - Box trap - [null, null, null, null, null] +19194 - Box trap - [null, null, null, null, null] +19195 - Box trap - [null, null, null, null, null] +19196 - Box trap - [null, null, null, null, null] +19197 - Box trap - [null, null, null, null, null] +19198 - Box trap - [null, null, null, null, null] +19199 - Box trap - [null, null, null, null, null] +19200 - Box trap - [null, null, null, null, null] +19201 - Box trap - [null, null, null, null, null] +19202 - Box trap - [null, null, null, null, null] +19203 - Box trap - [null, null, null, null, null] +19204 - Box trap - [null, null, null, null, null] +19205 - Boulder - [Set-trap, null, null, null, null] +19206 - Deadfall - [Dismantle, Investigate, null, null, null] +19207 - Deadfall - [null, null, null, null, null] +19208 - Deadfall - [null, null, null, null, null] +19209 - Deadfall - [null, null, null, null, null] +19210 - Deadfall - [null, null, null, null, null] +19211 - Deadfall - [null, null, null, null, null] +19212 - Deadfall - [null, null, null, null, null] +19213 - Deadfall - [null, null, null, null, null] +19214 - Deadfall - [null, null, null, null, null] +19215 - Boulder - [Check, null, null, null, null] +19216 - Boulder - [Check, null, null, null, null] +19217 - Boulder - [Check, null, null, null, null] +19218 - Boulder - [Check, null, null, null, null] +19219 - Deadfall - [null, null, null, null, null] +19220 - Perch - [null, null, null, null, hidden] +19221 - Occupied perch - [null, null, null, null, hidden] +19222 - Stile - [Climb-over, null, null, null, null] +19223 - Magic box - [Deactivate, Investigate, null, null, null] +19224 - Magic box failed - [Deactivate, null, null, null, null] +19225 - Magic box - [null, null, null, null, null] +19226 - Magic box - [Retrieve, null, null, null, null] +19227 - Pit - [null, null, Trap, null, null] +19228 - Spiked pit - [Jump, Dismantle, null, null, null] +19229 - Collapsed trap - [null, null, null, null, null] +19230 - Bank booth - [Use, Use-quickly, Collect, null, null] +19231 - Collapsed trap - [null, Dismantle, null, null, null] +19232 - Collapsed trap - [null, Dismantle, null, null, null] +19233 - Collapsed trap - [null, Dismantle, null, null, null] +19234 - Collapsed trap - [null, Dismantle, null, null, null] +19235 - Collapsed trap - [null, Dismantle, null, null, null] +19236 - Collapsed trap - [null, Dismantle, null, null, null] +19237 - null - [null, null, null, null, null] +19238 - null - [null, null, null, null, null] +19239 - null - [null, null, null, null, null] +19240 - null - [null, null, null, null, null] +19241 - null - [null, null, null, null, null] +19242 - null - [null, null, null, null, null] +19243 - null - [null, null, null, null, null] +19244 - null - [null, null, null, null, null] +19245 - null - [null, null, null, null, null] +19246 - null - [null, null, null, null, null] +19247 - null - [null, null, null, null, null] +19248 - null - [null, null, null, null, null] +19249 - null - [null, null, null, null, null] +19250 - null - [null, null, null, null, null] +19251 - null - [null, null, null, null, null] +19252 - null - [null, null, null, null, null] +19253 - null - [null, null, null, null, null] +19254 - null - [null, null, null, null, null] +19255 - null - [null, null, null, null, null] +19256 - null - [null, null, null, null, null] +19257 - null - [null, null, null, null, null] +19258 - null - [null, null, null, null, null] +19259 - null - [null, null, null, null, null] +19260 - Pit - [Trap, null, null, null, null] +19261 - Pit - [Trap, null, null, null, null] +19262 - Pit - [Trap, null, null, null, null] +19263 - Pit - [Trap, null, null, null, null] +19264 - Pit - [Trap, null, null, null, null] +19265 - Pit - [Trap, null, null, null, null] +19266 - Pit - [Trap, null, null, null, null] +19267 - Pit - [Trap, null, null, null, null] +19268 - Pit - [Trap, null, null, null, null] +19269 - null - [null, null, null, null, null] +19270 - null - [null, null, null, null, null] +19271 - null - [null, null, null, null, null] +19272 - null - [null, null, null, null, null] +19273 - null - [null, null, null, null, null] +19274 - null - [null, null, null, null, null] +19275 - null - [null, null, null, null, null] +19276 - null - [null, null, null, null, null] +19277 - null - [null, null, null, null, null] +19278 - null - [null, null, null, null, null] +19279 - null - [null, null, null, null, null] +19280 - null - [null, null, null, null, null] +19281 - null - [null, null, null, null, null] +19282 - null - [null, null, null, null, null] +19283 - null - [null, null, null, null, null] +19284 - null - [null, null, null, null, null] +19285 - null - [null, null, null, null, null] +19286 - null - [null, null, null, null, null] +19287 - null - [null, null, null, null, null] +19288 - null - [null, null, null, null, null] +19289 - null - [null, null, null, null, null] +19290 - null - [null, null, null, null, null] +19291 - null - [null, null, null, null, null] +19292 - null - [null, null, null, null, null] +19293 - null - [null, null, null, null, null] +19294 - null - [null, null, null, null, null] +19295 - null - [null, null, null, null, null] +19296 - null - [null, null, null, null, null] +19297 - null - [null, null, null, null, null] +19298 - null - [null, null, null, null, null] +19299 - null - [null, null, null, null, null] +19300 - null - [null, null, null, null, null] +19301 - null - [null, null, null, null, null] +19302 - null - [null, null, null, null, null] +19303 - null - [null, null, null, null, null] +19304 - null - [null, null, null, null, null] +19305 - null - [null, null, null, null, null] +19306 - null - [null, null, null, null, null] +19307 - null - [null, null, null, null, null] +19308 - null - [null, null, null, null, null] +19309 - null - [null, null, null, null, null] +19310 - null - [null, null, null, null, null] +19311 - null - [null, null, null, null, null] +19312 - null - [null, null, null, null, null] +19313 - null - [null, null, null, null, null] +19314 - null - [null, null, null, null, null] +19315 - null - [null, null, null, null, null] +19316 - null - [null, null, null, null, null] +19317 - null - [null, null, null, null, null] +19318 - null - [null, null, null, null, null] +19319 - null - [null, null, null, null, null] +19320 - null - [null, null, null, null, null] +19321 - null - [null, null, null, null, null] +19322 - null - [null, null, null, null, null] +19323 - null - [null, null, null, null, null] +19324 - null - [null, null, null, null, null] +19325 - null - [null, null, null, null, null] +19326 - null - [null, null, null, null, null] +19327 - null - [null, null, null, null, null] +19328 - null - [null, null, null, null, null] +19329 - null - [null, null, null, null, null] +19330 - null - [null, null, null, null, null] +19331 - null - [null, null, null, null, null] +19332 - null - [null, null, null, null, null] +19333 - Rabbit snare - [Dismantle, Investigate, null, null, null] +19334 - Broken snare - [Dismantle, null, null, null, null] +19335 - Rabbit snare - [Check, null, null, null, null] +19336 - Rabbit snare - [Check, null, null, null, null] +19337 - Rabbit hole - [Flush, null, null, null, null] +19338 - Rabbitless hole - [null, null, null, null, null] +19339 - Plant - [Inspect, null, null, null, null] +19340 - Plant - [Inspect, null, null, null, null] +19341 - Plant - [Inspect, null, null, null, null] +19342 - Plant - [Inspect, null, null, null, null] +19343 - Plant - [Inspect, null, null, null, null] +19344 - Plant - [Inspect, null, null, null, null] +19345 - Plant - [Inspect, null, null, null, null] +19346 - Plant - [Inspect, null, null, null, null] +19347 - Plant - [Inspect, null, null, null, null] +19348 - Plant - [Inspect, null, null, null, null] +19349 - Plant - [Inspect, null, null, null, null] +19350 - Plant - [Inspect, null, null, null, null] +19351 - Plant - [Inspect, null, null, null, null] +19352 - Plant - [Inspect, null, null, null, null] +19353 - Plant - [Inspect, null, null, null, null] +19354 - Plant - [Inspect, null, null, null, null] +19355 - Plant - [Inspect, null, null, null, null] +19356 - Plant - [Inspect, null, null, null, null] +19357 - Plant - [Inspect, null, null, null, null] +19358 - Plant - [Inspect, null, null, null, null] +19359 - Plant - [Inspect, null, null, null, null] +19360 - Plant - [Inspect, null, null, null, null] +19361 - Plant - [Inspect, null, null, null, null] +19362 - Plant - [Inspect, null, null, null, null] +19363 - Plant - [Inspect, null, null, null, null] +19364 - Plant - [Inspect, null, null, null, null] +19365 - Plant - [Inspect, null, null, null, null] +19366 - Plant - [Inspect, null, null, null, null] +19367 - Plant - [Inspect, null, null, null, null] +19368 - Plant - [Inspect, null, null, null, null] +19369 - Plant - [Inspect, null, null, null, null] +19370 - Plant - [Inspect, null, null, null, null] +19371 - Plant - [Inspect, null, null, null, null] +19372 - Plant - [Inspect, null, null, null, null] +19373 - Plant - [Inspect, null, null, null, null] +19374 - Plant - [Inspect, null, null, null, null] +19375 - Plant - [Inspect, null, null, null, null] +19376 - Plant - [Inspect, null, null, null, null] +19377 - Plant - [Inspect, null, null, null, null] +19378 - Plant - [Inspect, null, null, null, null] +19379 - Plant - [Inspect, null, null, null, null] +19380 - Plant - [Inspect, null, null, null, null] +19381 - Plant - [Inspect, null, null, null, null] +19382 - Plant - [Inspect, null, null, null, null] +19383 - Plant - [Inspect, null, null, null, null] +19384 - Plant - [Inspect, null, null, null, null] +19385 - Plant - [Inspect, null, null, null, null] +19386 - Plant - [Inspect, null, null, null, null] +19387 - Plant - [Inspect, null, null, null, null] +19388 - Cactus - [Inspect, null, null, null, null] +19389 - Cactus - [Inspect, null, null, null, null] +19390 - Rockslide - [Inspect, null, null, null, null] +19391 - Cactus - [Inspect, null, null, null, null] +19392 - Cactus - [Inspect, null, null, null, null] +19393 - Rockslide - [Inspect, null, null, null, null] +19394 - Cactus - [Inspect, null, null, null, null] +19395 - Cactus - [Inspect, null, null, null, null] +19396 - Rockslide - [Inspect, null, null, null, null] +19397 - Rockslide - [Inspect, null, null, null, null] +19398 - Cactus - [Inspect, null, null, null, null] +19399 - Cactus - [Inspect, null, null, null, null] +19400 - Rockslide - [Inspect, null, null, null, null] +19401 - Cactus - [Inspect, null, null, null, null] +19402 - Rockslide - [Inspect, null, null, null, null] +19403 - Jungle plant - [Inspect, null, null, null, null] +19404 - Jungle plant - [Inspect, null, null, null, null] +19405 - Jungle plant - [Inspect, null, null, null, null] +19406 - Jungle plant - [Inspect, null, null, null, null] +19407 - Jungle plant - [Inspect, null, null, null, null] +19408 - Jungle plant - [Inspect, null, null, null, null] +19409 - Jungle plant - [Inspect, null, null, null, null] +19410 - Jungle plant - [Inspect, null, null, null, null] +19411 - Jungle plant - [Inspect, null, null, null, null] +19412 - Jungle plant - [Inspect, null, null, null, null] +19413 - Jungle plant - [Inspect, null, null, null, null] +19414 - Jungle plant - [Inspect, null, null, null, null] +19415 - Jungle plant - [Inspect, null, null, null, null] +19416 - Jungle plant - [Inspect, null, null, null, null] +19417 - Jungle plant - [Inspect, null, null, null, null] +19418 - Hollow log - [Inspect, null, null, null, null] +19419 - Tunnel - [Inspect, null, null, null, null] +19420 - Tunnel - [Inspect, null, null, null, null] +19421 - Tunnel - [Inspect, null, null, null, null] +19422 - Hollow log - [Inspect, null, null, null, null] +19423 - Tunnel - [Inspect, null, null, null, null] +19424 - Tunnel - [Inspect, null, null, null, null] +19425 - Hollow log - [Inspect, null, null, null, null] +19426 - Tunnel - [Inspect, null, null, null, null] +19427 - Bush - [Search, Attack, null, null, null] +19428 - Bush - [Search, Attack, null, null, null] +19429 - Bush - [Search, Attack, null, null, null] +19430 - Disturbed sand - [Search, Attack, null, null, null] +19431 - null - [null, null, null, null, null] +19432 - null - [null, null, null, null, null] +19433 - null - [null, null, null, null, null] +19434 - Tunnel - [Inspect, null, null, null, null] +19435 - Snow drift - [Search, Attack, null, null, null] +19436 - null - [null, null, null, null, null] +19437 - null - [null, null, null, null, null] +19438 - Burrow - [Inspect, null, null, null, null] +19439 - Burrow - [Inspect, null, null, null, null] +19440 - Burrow - [Inspect, null, null, null, null] +19441 - null - [null, null, null, null, null] +19442 - null - [null, null, null, null, null] +19443 - null - [null, null, null, null, null] +19444 - null - [null, null, null, null, null] +19445 - null - [null, null, null, null, null] +19446 - null - [null, null, null, null, null] +19447 - null - [null, null, null, null, null] +19448 - null - [null, null, null, null, null] +19449 - null - [null, null, null, null, null] +19450 - null - [null, null, null, null, null] +19451 - null - [null, null, null, null, null] +19452 - null - [null, null, null, null, null] +19453 - null - [null, null, null, null, null] +19454 - null - [null, null, null, null, null] +19455 - null - [null, null, null, null, null] +19456 - null - [null, null, null, null, null] +19457 - null - [null, null, null, null, null] +19458 - null - [null, null, null, null, null] +19459 - null - [null, null, null, null, null] +19460 - null - [null, null, null, null, null] +19461 - null - [null, null, null, null, null] +19462 - null - [null, null, null, null, null] +19463 - null - [null, null, null, null, null] +19464 - null - [null, null, null, null, null] +19465 - null - [null, null, null, null, null] +19466 - null - [null, null, null, null, null] +19467 - null - [null, null, null, null, null] +19468 - null - [null, null, null, null, null] +19469 - null - [null, null, null, null, null] +19470 - null - [null, null, null, null, null] +19471 - null - [null, null, null, null, null] +19472 - null - [null, null, null, null, null] +19473 - null - [null, null, null, null, null] +19474 - null - [null, null, null, null, null] +19475 - null - [null, null, null, null, null] +19476 - null - [null, null, null, null, null] +19477 - null - [null, null, null, null, null] +19478 - null - [null, null, null, null, null] +19479 - null - [null, null, null, null, null] +19480 - null - [null, null, null, null, null] +19481 - null - [null, null, null, null, null] +19482 - null - [null, null, null, null, null] +19483 - null - [null, null, null, null, null] +19484 - null - [null, null, null, null, null] +19485 - null - [null, null, null, null, null] +19486 - null - [null, null, null, null, null] +19487 - null - [null, null, null, null, null] +19488 - null - [null, null, null, null, null] +19489 - null - [null, null, null, null, null] +19490 - null - [null, null, null, null, null] +19491 - null - [null, null, null, null, null] +19492 - Burrow - [Inspect, null, null, null, null] +19493 - Burrow - [Inspect, null, null, null, null] +19494 - Burrow - [Inspect, null, null, null, null] +19495 - null - [null, null, null, null, null] +19496 - null - [null, null, null, null, null] +19497 - null - [null, null, null, null, null] +19498 - null - [null, null, null, null, null] +19499 - null - [null, null, null, null, null] +19500 - null - [null, null, null, null, null] +19501 - null - [null, null, null, null, null] +19502 - null - [null, null, null, null, null] +19503 - null - [null, null, null, null, null] +19504 - null - [null, null, null, null, null] +19505 - null - [null, null, null, null, null] +19506 - null - [null, null, null, null, null] +19507 - null - [null, null, null, null, null] +19508 - null - [null, null, null, null, null] +19509 - null - [null, null, null, null, null] +19510 - null - [null, null, null, null, null] +19511 - null - [null, null, null, null, null] +19512 - null - [null, null, null, null, null] +19513 - null - [null, null, null, null, null] +19514 - null - [null, null, null, null, null] +19515 - null - [null, null, null, null, null] +19516 - null - [null, null, null, null, null] +19517 - null - [null, null, null, null, null] +19518 - null - [null, null, null, null, null] +19519 - null - [null, null, null, null, null] +19520 - null - [null, null, null, null, null] +19521 - null - [null, null, null, null, null] +19522 - null - [null, null, null, null, null] +19523 - null - [null, null, null, null, null] +19524 - null - [null, null, null, null, null] +19525 - null - [null, null, null, null, null] +19526 - null - [null, null, null, null, null] +19527 - null - [null, null, null, null, null] +19528 - null - [null, null, null, null, null] +19529 - null - [null, null, null, null, null] +19530 - null - [null, null, null, null, null] +19531 - null - [null, null, null, null, null] +19532 - null - [null, null, null, null, null] +19533 - null - [null, null, null, null, null] +19534 - null - [null, null, null, null, null] +19535 - null - [null, null, null, null, null] +19536 - null - [null, null, null, null, null] +19537 - null - [null, null, null, null, null] +19538 - null - [null, null, null, null, null] +19539 - null - [null, null, null, null, null] +19540 - null - [null, null, null, null, null] +19541 - null - [null, null, null, null, null] +19542 - null - [null, null, null, null, null] +19543 - null - [null, null, null, null, null] +19544 - null - [null, null, null, null, null] +19545 - null - [null, null, null, null, null] +19546 - null - [null, null, null, null, null] +19547 - null - [null, null, null, null, null] +19548 - null - [null, null, null, null, null] +19549 - null - [null, null, null, null, null] +19550 - null - [null, null, null, null, null] +19551 - null - [null, null, null, null, null] +19552 - Burrow - [Inspect, null, null, null, null] +19553 - Burrow - [Inspect, null, null, null, null] +19554 - null - [null, null, null, null, null] +19555 - null - [null, null, null, null, null] +19556 - null - [null, null, null, null, null] +19557 - null - [null, null, null, null, null] +19558 - null - [null, null, null, null, null] +19559 - null - [null, null, null, null, null] +19560 - null - [null, null, null, null, null] +19561 - null - [null, null, null, null, null] +19562 - null - [null, null, null, null, null] +19563 - null - [null, null, null, null, null] +19564 - null - [null, null, null, null, null] +19565 - null - [null, null, null, null, null] +19566 - null - [null, null, null, null, null] +19567 - null - [null, null, null, null, null] +19568 - null - [null, null, null, null, null] +19569 - null - [null, null, null, null, null] +19570 - null - [null, null, null, null, null] +19571 - null - [null, null, null, null, null] +19572 - null - [null, null, null, null, null] +19573 - null - [null, null, null, null, null] +19574 - null - [null, null, null, null, null] +19575 - null - [null, null, null, null, null] +19576 - null - [null, null, null, null, null] +19577 - null - [null, null, null, null, null] +19578 - null - [null, null, null, null, null] +19579 - null - [null, null, null, null, null] +19580 - null - [null, null, null, null, null] +19581 - null - [null, null, null, null, null] +19582 - null - [null, null, null, null, null] +19583 - null - [null, null, null, null, null] +19584 - null - [null, null, null, null, null] +19585 - null - [null, null, null, null, null] +19586 - null - [null, null, null, null, null] +19587 - null - [null, null, null, null, null] +19588 - null - [null, null, null, null, null] +19589 - null - [null, null, null, null, null] +19590 - null - [null, null, null, null, null] +19591 - null - [null, null, null, null, null] +19592 - null - [null, null, null, null, null] +19593 - Burrow - [Inspect, null, null, null, null] +19594 - Burrow - [Inspect, null, null, null, null] +19595 - null - [null, null, null, null, null] +19596 - null - [null, null, null, null, null] +19597 - null - [null, null, null, null, null] +19598 - null - [null, null, null, null, null] +19599 - null - [null, null, null, null, null] +19600 - null - [null, null, null, null, null] +19601 - null - [null, null, null, null, null] +19602 - null - [null, null, null, null, null] +19603 - null - [null, null, null, null, null] +19604 - null - [null, null, null, null, null] +19605 - null - [null, null, null, null, null] +19606 - null - [null, null, null, null, null] +19607 - null - [null, null, null, null, null] +19608 - null - [null, null, null, null, null] +19609 - null - [null, null, null, null, null] +19610 - null - [null, null, null, null, null] +19611 - null - [null, null, null, null, null] +19612 - null - [null, null, null, null, null] +19613 - null - [null, null, null, null, null] +19614 - null - [null, null, null, null, null] +19615 - null - [null, null, null, null, null] +19616 - null - [null, null, null, null, null] +19617 - null - [null, null, null, null, null] +19618 - null - [null, null, null, null, null] +19619 - null - [null, null, null, null, null] +19620 - null - [null, null, null, null, null] +19621 - null - [null, null, null, null, null] +19622 - null - [null, null, null, null, null] +19623 - null - [null, null, null, null, null] +19624 - null - [null, null, null, null, null] +19625 - null - [null, null, null, null, null] +19626 - null - [null, null, null, null, null] +19627 - null - [null, null, null, null, null] +19628 - null - [null, null, null, null, null] +19629 - null - [null, null, null, null, null] +19630 - null - [null, null, null, null, null] +19631 - null - [null, null, null, null, null] +19632 - null - [null, null, null, null, null] +19633 - null - [null, null, null, null, null] +19634 - null - [null, null, null, null, null] +19635 - null - [null, null, null, null, null] +19636 - null - [null, null, null, null, null] +19637 - null - [null, null, null, null, null] +19638 - null - [null, null, null, null, null] +19639 - null - [null, null, null, null, null] +19640 - Hole - [Inspect, null, null, null, null] +19641 - Hole - [Inspect, null, null, null, null] +19642 - null - [null, null, null, null, null] +19643 - null - [null, null, null, null, null] +19644 - null - [null, null, null, null, null] +19645 - null - [null, null, null, null, null] +19646 - null - [null, null, null, null, null] +19647 - null - [null, null, null, null, null] +19648 - null - [null, null, null, null, null] +19649 - null - [null, null, null, null, null] +19650 - Young tree - [Dismantle, Investigate, null, null, null] +19651 - Net trap - [Dismantle, Investigate, null, null, null] +19652 - Young tree - [Set-trap, null, null, null, null] +19653 - Young tree - [null, null, null, null, null] +19654 - Net trap - [Check, null, null, null, null] +19655 - Net trap - [null, null, null, null, null] +19656 - Net trap - [Dismantle, null, null, null, null] +19657 - Net trap - [null, null, null, null, null] +19658 - Net trap - [null, null, null, null, null] +19659 - Net trap - [Check, null, null, null, null] +19660 - Net trap - [null, null, null, null, null] +19661 - Net trap - [Dismantle, null, null, null, null] +19662 - Young tree - [Dismantle, Investigate, null, null, null] +19663 - Young tree - [Set-trap, null, null, null, null] +19664 - Young tree - [null, null, null, null, null] +19665 - Net trap - [Dismantle, Investigate, null, null, null] +19666 - Net trap - [null, null, null, null, null] +19667 - Net trap - [Check, null, null, null, null] +19668 - Net trap - [null, null, null, null, null] +19669 - Net trap - [Dismantle, null, null, null, null] +19670 - Young tree - [Dismantle, Investigate, null, null, null] +19671 - Young tree - [Set-trap, null, null, null, null] +19672 - Young tree - [null, null, null, null, null] +19673 - Net trap - [Dismantle, Investigate, null, null, null] +19674 - Net trap - [null, null, null, null, null] +19675 - Net trap - [Check, null, null, null, null] +19676 - Net trap - [null, null, null, null, null] +19677 - Net trap - [Dismantle, null, null, null, null] +19678 - Young tree - [Dismantle, Investigate, null, null, null] +19679 - Young tree - [Set-trap, null, null, null, null] +19680 - Young tree - [null, null, null, null, null] +19681 - Net trap - [Dismantle, Investigate, null, null, null] +19682 - null - [null, null, null, null, null] +19683 - null - [null, null, null, null, null] +19684 - null - [null, null, null, null, null] +19685 - null - [null, null, null, null, null] +19686 - null - [null, null, null, null, null] +19687 - null - [null, null, null, null, null] +19688 - null - [null, null, null, null, null] +19689 - null - [null, null, null, null, null] +19690 - Steps - [Ascend, null, null, null, null] +19691 - Steps - [Descend, null, null, null, null] +19692 - null - [null, null, null, null, null] +19693 - null - [null, null, null, null, null] +19694 - null - [null, null, null, null, null] +19695 - null - [null, null, null, null, null] +19696 - null - [null, null, null, null, null] +19697 - null - [null, null, null, null, null] +19698 - null - [null, null, null, null, null] +19699 - Counter - [null, null, null, null, null] +19700 - null - [null, null, null, null, null] +19701 - null - [null, null, null, null, null] +19702 - null - [null, null, null, null, null] +19703 - null - [null, null, null, null, null] +19704 - null - [null, null, null, null, null] +19705 - null - [null, null, null, null, null] +19706 - null - [null, null, null, null, null] +19707 - null - [null, null, null, null, null] +19708 - null - [null, null, null, null, null] +19709 - null - [null, null, null, null, null] +19710 - null - [null, null, null, null, null] +19711 - null - [null, null, null, null, null] +19712 - null - [null, null, null, null, null] +19713 - null - [null, null, null, null, null] +19714 - null - [null, null, null, null, null] +19715 - null - [null, null, null, null, null] +19716 - null - [null, null, null, null, null] +19717 - null - [null, null, null, null, null] +19718 - null - [null, null, null, null, null] +19719 - null - [null, null, null, null, null] +19720 - null - [null, null, null, null, null] +19721 - null - [null, null, null, null, null] +19722 - null - [null, null, null, null, null] +19723 - null - [null, null, null, null, null] +19724 - null - [null, null, null, null, null] +19725 - null - [null, null, null, null, null] +19726 - null - [null, null, null, null, null] +19727 - null - [null, null, null, null, null] +19728 - null - [null, null, null, null, null] +19729 - null - [null, null, null, null, null] +19730 - null - [null, null, null, null, null] +19731 - null - [null, null, null, null, null] +19732 - null - [null, null, null, null, null] +19733 - null - [null, null, null, null, null] +19734 - null - [null, null, null, null, null] +19735 - null - [null, null, null, null, null] +19736 - null - [null, null, null, null, null] +19737 - null - [null, null, null, null, null] +19738 - null - [null, null, null, null, null] +19739 - null - [null, null, null, null, null] +19740 - null - [null, null, null, null, null] +19741 - null - [null, null, null, null, null] +19742 - null - [null, null, null, null, null] +19743 - null - [null, null, null, null, null] +19744 - null - [null, null, null, null, null] +19745 - null - [null, null, null, null, null] +19746 - null - [null, null, null, null, null] +19747 - null - [null, null, null, null, null] +19748 - null - [null, null, null, null, null] +19749 - null - [null, null, null, null, null] +19750 - null - [null, null, null, null, null] +19751 - null - [null, null, null, null, null] +19752 - Rockslide - [Shout-over, null, null, null, null] +19753 - Cave - [Enter, null, null, null, null] +19754 - Cave - [null, null, null, null, null] +19755 - null - [null, null, null, null, null] +19756 - null - [null, null, null, null, null] +19757 - null - [null, null, null, null, null] +19758 - null - [null, null, null, null, null] +19759 - Cave - [Exit, null, null, null, null] +19760 - Cave - [Exit, null, null, null, null] +19761 - Cave - [null, null, null, null, null] +19762 - Cave - [Enter, null, null, null, null] +19763 - Cave - [Exit, null, null, null, null] +19764 - Cave - [Exit, null, null, null, null] +19765 - null - [null, null, null, null, null] +19766 - null - [null, null, null, null, null] +19767 - null - [null, null, null, null, null] +19768 - null - [null, null, null, null, null] +19769 - null - [null, null, null, null, null] +19770 - null - [null, null, null, null, null] +19771 - null - [null, null, null, null, null] +19772 - null - [null, null, null, null, null] +19773 - null - [null, null, null, null, null] +19774 - null - [null, null, null, null, null] +19775 - null - [null, null, null, null, null] +19776 - null - [null, null, null, null, null] +19777 - null - [null, null, null, null, null] +19778 - null - [null, null, null, null, null] +19779 - null - [null, null, null, null, null] +19780 - null - [null, null, null, null, null] +19781 - null - [null, null, null, null, null] +19782 - null - [null, null, null, null, null] +19783 - null - [null, null, null, null, null] +19784 - null - [null, null, null, null, null] +19785 - null - [Inspect, null, null, null, null] +19786 - null - [null, null, null, null, null] +19787 - null - [Inspect, null, null, null, null] +19788 - null - [Inspect, null, null, null, null] +19789 - null - [null, null, null, null, null] +19790 - null - [Enter, Inspect, null, null, null] +19791 - Cave - [Exit, null, null, null, null] +19792 - Cave - [Exit, null, null, null, null] +19793 - null - [null, null, null, null, null] +19794 - null - [null, null, null, null, null] +19795 - null - [null, null, null, null, null] +19796 - null - [null, null, null, null, null] +19797 - Cave - [null, null, null, null, null] +19798 - Cave - [Enter, null, null, null, null] +19799 - null - [null, null, null, null, null] +19800 - null - [null, null, null, null, null] +19801 - null - [null, null, null, null, null] +19802 - null - [null, null, null, null, null] +19803 - null - [null, null, null, null, null] +19804 - null - [null, null, null, null, null] +19805 - null - [null, null, null, null, null] +19806 - null - [null, null, null, null, null] +19807 - null - [null, null, null, null, null] +19808 - Rockslide - [null, null, null, null, null] +19809 - Cave - [Enter, null, null, null, null] +19810 - Large cave - [null, null, null, null, null] +19811 - Cave - [Exit, null, null, null, null] +19812 - Cave - [Exit, null, null, null, null] +19813 - null - [null, null, null, null, null] +19814 - null - [null, null, null, null, null] +19815 - null - [null, null, null, null, null] +19816 - null - [null, null, null, null, null] +19817 - null - [null, null, null, null, null] +19818 - null - [null, null, null, null, null] +19819 - null - [null, null, null, null, null] +19820 - null - [null, null, null, null, null] +19821 - null - [null, null, null, null, null] +19822 - null - [null, null, null, null, null] +19823 - null - [null, null, null, null, null] +19824 - null - [null, null, null, null, null] +19825 - null - [null, null, null, null, null] +19826 - null - [null, null, null, null, null] +19827 - null - [null, null, null, null, null] +19828 - null - [null, null, null, null, null] +19829 - null - [null, null, null, null, null] +19830 - null - [null, null, null, null, null] +19831 - null - [null, null, null, null, null] +19832 - null - [null, null, null, null, null] +19833 - null - [null, null, null, null, null] +19834 - null - [null, null, null, null, null] +19835 - null - [null, null, null, null, null] +19836 - null - [null, null, null, null, null] +19837 - null - [null, null, null, null, null] +19838 - null - [null, null, null, null, null] +19839 - Fern - [null, null, null, null, null] +19840 - Fern - [null, null, null, null, null] +19841 - null - [null, null, null, null, null] +19842 - null - [null, null, null, null, null] +19843 - null - [Open, null, null, null, null] +19844 - null - [null, null, null, null, null] +19845 - null - [null, null, null, null, null] +19846 - Rocky handholds - [Climb, null, null, null, null] +19847 - Rocky handholds - [Climb, null, null, null, null] +19848 - null - [null, null, null, null, null] +19849 - Rocks - [Climb, null, null, null, null] +19850 - null - [null, null, null, null, null] +19851 - Boulder - [null, null, null, null, null] +19852 - Hill - [null, null, null, null, null] +19853 - null - [null, null, null, null, null] +19854 - null - [null, null, null, null, null] +19855 - null - [null, null, null, null, null] +19856 - null - [null, null, null, null, null] +19857 - null - [null, null, null, null, null] +19858 - null - [null, null, null, null, null] +19859 - null - [null, null, null, null, null] +19860 - null - [null, null, null, null, null] +19861 - null - [null, null, null, null, null] +19862 - null - [null, null, null, null, null] +19863 - null - [null, null, null, null, null] +19864 - null - [null, null, null, null, null] +19865 - null - [null, null, null, null, null] +19866 - null - [null, null, null, null, null] +19867 - null - [null, null, null, null, null] +19868 - null - [null, null, null, null, null] +19869 - null - [null, null, null, null, null] +19870 - Stone Gate - [null, null, null, null, null] +19871 - Stone Gate - [null, null, null, null, null] +19872 - null - [null, null, null, null, null] +19873 - null - [null, null, null, null, null] +19874 - null - [null, null, null, null, null] +19875 - null - [null, null, null, null, null] +19876 - null - [null, null, null, null, null] +19877 - Eagle lever - [Pull-down, null, null, null, null] +19878 - Eagle lever - [null, Push-up, null, null, null] +19879 - null - [null, null, null, null, null] +19880 - null - [null, null, null, null, null] +19881 - Campfire - [null, null, null, null, null] +19882 - null - [null, null, null, null, null] +19883 - null - [null, null, null, null, null] +19884 - Campfire - [Inspect, null, null, null, null] +19885 - Books - [null, null, null, null, null] +19886 - Books - [Inspect, null, null, null, null] +19887 - Camping equipment - [null, null, null, null, null] +19888 - Camping equipment - [Inspect, null, null, null, null] +19889 - null - [null, null, null, null, null] +19890 - null - [null, null, null, null, null] +19891 - Cave entrance - [Exit, null, null, null, null] +19892 - null - [null, null, null, null, null] +19893 - null - [null, null, null, null, null] +19894 - Tunnel - [Enter, null, null, null, null] +19895 - null - [null, null, null, null, null] +19896 - null - [null, null, null, null, null] +19897 - Tunnel - [Enter, null, null, null, null] +19898 - null - [null, null, null, null, null] +19899 - null - [null, null, null, null, null] +19900 - Tunnel - [Enter, null, null, null, null] +19901 - null - [null, null, null, null, null] +19902 - null - [null, null, null, null, null] +19903 - Tunnel - [Enter, null, null, null, null] +19904 - null - [null, null, null, null, null] +19905 - null - [null, null, null, null, null] +19906 - Tunnel - [Enter, null, null, null, null] +19907 - null - [null, null, null, null, null] +19908 - null - [null, null, null, null, null] +19909 - Tunnel - [Enter, null, null, null, null] +19910 - null - [null, null, null, null, null] +19911 - Stone pedestal - [null, null, null, null, null] +19912 - null - [null, null, null, null, null] +19913 - null - [null, null, null, null, null] +19914 - Stone door - [Open, null, null, null, null] +19915 - Stone door - [Open, null, null, null, null] +19916 - Stone door - [Open, null, null, null, null] +19917 - Stone door - [Open, null, null, null, null] +19918 - Stone door - [Open, null, null, null, null] +19919 - Birdseed holder - [Take-from, null, null, null, null] +19920 - Bird feeder - [null, null, null, null, null] +19921 - Bird feeder - [null, null, null, null, null] +19922 - Giant feathers - [Take, null, null, null, null] +19923 - Rocky outcrop - [null, Inspect, null, null, null] +19924 - Cave entrance - [Enter, null, null, null, null] +19925 - Rocky outcrop - [null, Inspect, null, null, null] +19926 - Cave entrance - [Enter, null, null, null, null] +19927 - null - [null, null, null, null, null] +19928 - Table - [null, null, null, null, null] +19929 - Chair - [null, null, null, null, null] +19930 - Leftovers - [null, null, null, null, null] +19931 - Chest - [null, null, null, null, null] +19932 - Bookcase - [null, null, null, null, null] +19933 - Chair - [null, null, null, null, null] +19934 - Armour - [null, null, null, null, null] +19935 - Metal bird - [null, null, null, null, null] +19936 - Bird feeder - [null, null, null, null, null] +19937 - Bird feeder - [null, null, null, null, null] +19938 - Bird feeder - [null, null, null, null, null] +19939 - Bird feeder - [null, null, null, null, null] +19940 - Bird feeder - [null, null, null, null, null] +19941 - Bird feeder - [null, null, null, null, null] +19942 - Bird feeder - [null, null, null, null, null] +19943 - Bird feeder - [null, null, null, null, null] +19944 - Bird feeder - [null, null, null, null, null] +19945 - Reset Lever - [Pull, null, null, null, null] +19946 - null - [Pull-down, Push-up, null, null, null] +19947 - null - [Pull-down, Push-up, null, null, null] +19948 - null - [Pull-down, Push-up, null, null, null] +19949 - null - [Pull-down, Push-up, null, null, null] +19950 - Stone pedestal - [Take-from, null, null, null, null] +19951 - null - [null, null, null, null, null] +19952 - null - [null, null, null, null, null] +19953 - null - [null, null, null, null, null] +19954 - null - [null, null, null, null, null] +19955 - null - [null, null, null, null, null] +19956 - null - [null, null, null, null, null] +19957 - null - [null, null, null, null, null] +19958 - null - [null, null, null, null, null] +19959 - null - [null, null, null, null, null] +19960 - null - [null, null, null, null, null] +19961 - null - [null, null, null, null, null] +19962 - null - [null, null, null, null, null] +19963 - null - [null, null, null, null, null] +19964 - null - [null, null, null, null, null] +19965 - null - [null, null, null, null, null] +19966 - null - [null, null, null, null, null] +19967 - Opening - [Inspect, null, null, null, null] +19968 - null - [null, null, null, null, null] +19969 - Rocks - [Inspect, null, null, null, null] +19970 - Rocks - [Inspect, null, null, null, null] +19971 - Rocks - [Inspect, null, null, null, null] +19972 - Rocks - [Inspect, null, null, null, null] +19973 - Rocks - [Inspect, null, null, null, null] +19974 - Stone pedestal - [Inspect, null, null, null, null] +19975 - Stone pedestal - [Take-from, null, null, null, null] +19976 - Winch - [Operate, null, null, null, null] +19977 - Winch - [Operate, null, null, null, null] +19978 - Winch - [Operate, null, null, null, null] +19979 - Winch - [Operate, null, null, null, null] +19980 - Pedestal - [Take-from, null, null, null, null] +19981 - Pedestal - [null, null, null, null, null] +19982 - Pedestal - [null, null, null, null, null] +19983 - Pedestal - [null, null, null, null, null] +19984 - Stone pedestal - [Take-from, null, null, null, null] +19985 - Young vine - [Climb, null, null, null, null] +19986 - Young vine - [Climb, null, null, null, null] +19987 - Growing vine - [Climb, null, null, null, null] +19988 - Tall vine - [Climb, null, null, null, null] +19989 - Tall vine - [Climb, null, null, null, null] +19990 - null - [null, null, null, null, null] +19991 - null - [Open, null, null, null, null] +19992 - null - [null, null, null, null, null] +19993 - null - [Climb, null, null, null, null] +19994 - null - [Enter, Inspect, null, null, null] +19995 - null - [null, null, null, null, null] +19996 - Buried skeleton - [Search, null, null, null, null] +19997 - Animal skull - [null, null, null, null, null] +19998 - Curved bone - [null, null, null, null, null] +19999 - Large bone - [null, null, null, null, null] +20000 - Fire - [null, null, null, null, null] +20001 - Fire - [null, null, null, null, null] +20002 - null - [null, null, null, null, null] +20003 - null - [null, null, null, null, null] +20004 - Rope bridge support - [null, null, null, null, null] +20005 - Rope bridge support - [null, null, null, null, null] +20006 - Rope bridge support - [null, null, null, null, null] +20007 - Rope bridge support - [null, null, null, null, null] +20008 - null - [null, null, null, null, null] +20009 - null - [null, null, null, null, null] +20010 - null - [null, null, null, null, null] +20011 - null - [null, null, null, null, null] +20012 - null - [null, null, null, null, null] +20013 - null - [null, null, null, null, null] +20014 - null - [null, null, null, null, null] +20015 - null - [null, null, null, null, null] +20016 - null - [null, null, null, null, null] +20017 - null - [null, null, null, null, null] +20018 - null - [null, null, null, null, null] +20019 - null - [null, null, null, null, null] +20020 - null - [null, null, null, null, null] +20021 - null - [null, null, null, null, null] +20022 - Pillar - [null, null, null, null, null] +20023 - Pillar - [null, null, null, null, null] +20024 - Pillar - [null, null, null, null, null] +20025 - null - [null, null, null, null, null] +20026 - Pillar - [null, null, null, null, null] +20027 - Pillar - [null, null, null, null, null] +20028 - Pillar - [null, null, null, null, null] +20029 - null - [null, null, null, null, null] +20030 - Pillar - [null, null, null, null, null] +20031 - Pillar - [null, null, null, null, null] +20032 - Pillar - [null, null, null, null, null] +20033 - null - [null, null, null, null, null] +20034 - null - [null, null, null, null, null] +20035 - null - [null, null, null, null, null] +20036 - null - [null, null, null, null, null] +20037 - Bed - [null, null, null, null, null] +20038 - Switch - [null, null, null, null, null] +20039 - Switch - [null, null, null, null, null] +20040 - Machine - [null, null, null, null, null] +20041 - null - [null, null, null, null, null] +20042 - null - [null, null, null, null, null] +20043 - null - [null, null, null, null, null] +20044 - null - [null, null, null, null, null] +20045 - Gate - [Open, null, null, null, null] +20046 - Gate - [Open, null, null, null, null] +20047 - null - [null, null, null, null, null] +20048 - null - [null, null, null, null, null] +20049 - Gate - [Close, null, null, null, null] +20050 - Gate - [Close, null, null, null, null] +20051 - null - [null, null, null, null, null] +20052 - null - [null, null, null, null, null] +20053 - null - [null, null, null, null, null] +20054 - null - [null, null, null, null, null] +20055 - null - [null, null, null, null, null] +20056 - Trellis - [Climb-up, null, null, null, null] +20057 - Trellis - [null, null, null, null, null] +20058 - Table - [null, null, null, null, null] +20059 - Stool - [null, null, null, null, null] +20060 - Table - [null, null, null, null, null] +20061 - Shelf - [null, null, null, null, null] +20062 - Shelf - [null, null, null, null, null] +20063 - A bunk bed - [null, null, null, null, null] +20064 - null - [null, null, null, null, null] +20065 - Chair - [null, null, null, null, null] +20066 - null - [null, null, null, null, null] +20067 - null - [null, null, null, null, null] +20068 - null - [null, null, null, null, null] +20069 - null - [null, null, null, null, null] +20070 - null - [null, null, null, null, null] +20071 - null - [null, null, null, null, null] +20072 - null - [null, null, null, null, null] +20073 - null - [null, null, null, null, null] +20074 - null - [null, null, null, null, null] +20075 - null - [null, null, null, null, null] +20076 - null - [null, null, null, null, null] +20077 - null - [null, null, null, null, null] +20078 - null - [null, null, null, null, null] +20079 - null - [null, null, null, null, null] +20080 - null - [null, null, null, null, null] +20081 - null - [null, null, null, null, null] +20082 - null - [null, null, null, null, null] +20083 - null - [null, null, null, null, null] +20084 - Castle wall - [Climb-under, null, null, null, null] +20085 - Hole - [Climb-into, null, null, null, null] +20086 - null - [null, null, null, null, null] +20087 - City gate - [Close, null, null, null, null] +20088 - City gate - [Close, null, null, null, null] +20089 - City gate - [Close, null, null, null, null] +20090 - City gate - [Close, null, null, null, null] +20091 - null - [null, null, null, null, null] +20092 - null - [null, null, null, null, null] +20093 - null - [null, null, null, null, null] +20094 - null - [null, null, null, null, null] +20095 - Open chest - [null, Search, Shut, null, null] +20096 - Bed - [null, null, null, null, null] +20097 - Bed - [null, null, null, null, null] +20098 - null - [null, null, null, null, null] +20099 - null - [null, null, null, null, null] +20100 - Childerkin slaves - [null, null, null, null, null] +20101 - null - [null, null, null, null, null] +20102 - null - [null, null, null, null, null] +20103 - null - [null, null, null, null, null] +20104 - null - [null, null, null, null, null] +20105 - null - [null, null, null, null, null] +20106 - null - [null, null, null, null, null] +20107 - null - [null, null, null, null, null] +20108 - null - [null, null, null, null, null] +20109 - null - [null, null, null, null, null] +20110 - null - [null, null, null, null, null] +20111 - null - [null, null, null, null, null] +20112 - null - [null, null, null, null, null] +20113 - null - [null, null, null, null, null] +20114 - null - [null, null, null, null, null] +20115 - null - [null, null, null, null, null] +20116 - null - [null, null, null, null, null] +20117 - Childerkin slaves - [null, null, null, null, null] +20118 - null - [null, null, null, null, null] +20119 - null - [null, null, null, null, null] +20120 - null - [null, null, null, null, null] +20121 - null - [null, null, null, null, null] +20122 - null - [null, null, null, null, null] +20123 - null - [null, null, null, null, null] +20124 - null - [null, null, null, null, null] +20125 - null - [null, null, null, null, null] +20126 - null - [null, null, null, null, null] +20127 - null - [null, null, null, null, null] +20128 - null - [null, null, null, null, null] +20129 - null - [null, null, null, null, null] +20130 - null - [null, null, null, null, null] +20131 - null - [null, null, null, null, null] +20132 - null - [null, null, null, null, null] +20133 - Egg launcher - [Shoot, null, null, null, null] +20134 - Blackboard - [Read, null, null, null, null] +20135 - Runner trap(2) - [null, null, null, null, null] +20136 - Trapdoor - [null, null, null, null, null] +20137 - Trapdoor - [null, null, null, null, null] +20138 - Trapdoor - [null, null, null, null, null] +20139 - Trapdoor - [null, null, null, null, null] +20140 - Trapdoor - [null, null, null, null, null] +20141 - Trapdoor - [null, null, null, null, null] +20142 - Trapdoor - [null, null, null, null, null] +20143 - Trapdoor - [null, null, null, null, null] +20144 - Trapdoor - [null, null, null, null, null] +20145 - Trapdoor - [null, null, null, null, null] +20146 - Trapdoor - [null, null, null, null, null] +20147 - Trapdoor - [null, null, null, null, null] +20148 - Winch - [null, null, null, null, null] +20149 - Scroll table - [Take-from, null, null, null, null] +20150 - Healer spring - [Drink-from, null, Take-from, null, null] +20151 - Lure cave - [Enter, null, null, null, null] +20152 - null - [null, null, null, null, null] +20153 - null - [null, null, null, null, null] +20154 - null - [null, null, null, null, null] +20155 - null - [null, null, null, null, null] +20156 - null - [null, null, null, null, null] +20157 - null - [null, null, null, null, null] +20158 - null - [null, null, null, null, null] +20159 - null - [null, null, null, null, null] +20160 - null - [null, null, null, null, null] +20161 - null - [null, null, null, null, null] +20162 - null - [null, null, null, null, null] +20163 - null - [null, null, null, null, null] +20164 - Penance Fighter statue - [Inspect, null, null, null, null] +20165 - Penance Healer statue - [Inspect, null, null, null, null] +20166 - Penance Runner statue - [Inspect, null, null, null, null] +20167 - Penance Ranger statue - [Inspect, null, null, null, null] +20168 - Penance Queen spawn statue - [Inspect, null, null, null, null] +20169 - null - [null, null, null, null, null] +20170 - null - [null, null, null, null, null] +20171 - null - [null, null, null, null, null] +20172 - null - [null, null, null, null, null] +20173 - null - [null, null, null, null, null] +20174 - null - [null, null, null, null, null] +20175 - null - [null, null, null, null, null] +20176 - null - [null, null, null, null, null] +20177 - null - [null, null, null, null, null] +20178 - null - [null, null, null, null, null] +20179 - null - [null, null, null, null, null] +20180 - null - [null, null, null, null, null] +20181 - null - [null, null, null, null, null] +20182 - null - [null, null, null, null, null] +20183 - One - [null, null, null, null, null] +20184 - Two - [null, null, null, null, null] +20185 - Three - [null, null, null, null, null] +20186 - Four - [null, null, null, null, null] +20187 - Five - [null, null, null, null, null] +20188 - Six - [null, null, null, null, null] +20189 - Seven - [null, null, null, null, null] +20190 - Eight - [null, null, null, null, null] +20191 - Nine - [null, null, null, null, null] +20192 - Ten - [null, null, null, null, null] +20193 - Ladder - [Climb-down, null, null, null, null] +20194 - Ladder - [Climb-up, null, null, null, null] +20195 - Barbarian door - [Open, null, null, null, null] +20196 - Barbarian door - [Open, null, null, null, null] +20197 - Barbarian door - [Close, null, null, null, null] +20198 - Barbarian door - [Close, null, null, null, null] +20199 - Door - [Pass, null, null, null, null] +20200 - Door - [Pass, null, null, null, null] +20201 - Door - [Pass, null, null, null, null] +20202 - Door - [Pass, null, null, null, null] +20203 - Door - [Pass, null, null, null, null] +20204 - Door - [Pass, null, null, null, null] +20205 - Door - [Pass, null, null, null, null] +20206 - Door - [Pass, null, null, null, null] +20207 - Door - [Pass, null, null, null, null] +20208 - Door - [Pass, null, null, null, null] +20209 - Door - [Pass, null, null, null, null] +20210 - Obstacle pipe - [Squeeze-through, null, null, null, null] +20211 - Obstacle net - [Climb-over, null, null, null, null] +20212 - null - [null, null, null, null, null] +20213 - null - [null, null, null, null, null] +20214 - null - [null, null, null, null, null] +20215 - null - [null, null, null, null, null] +20216 - Crate - [null, null, null, null, null] +20217 - Barrel - [null, null, null, null, null] +20218 - null - [null, null, null, null, null] +20219 - null - [null, null, null, null, null] +20220 - null - [null, null, null, null, null] +20221 - null - [null, null, null, null, null] +20222 - null - [null, null, null, null, null] +20223 - null - [null, null, null, null, null] +20224 - null - [null, null, null, null, null] +20225 - null - [null, null, null, null, null] +20226 - Ladder - [Climb-down, null, null, null, null] +20227 - Ladder - [Climb-up, null, null, null, null] +20228 - Bank deposit box - [Deposit, null, null, null, null] +20229 - Information scroll - [Read, null, null, null, null] +20230 - Runner trap(1) - [Fix, null, null, null, null] +20231 - Broken trap(0) - [Fix, null, null, null, null] +20232 - Lava crater - [Dunk, null, null, null, null] +20233 - Poison crater - [Dunk, null, null, null, null] +20234 - Lava crater - [Dunk, null, null, null, null] +20235 - Poison crater - [Dunk, null, null, null, null] +20236 - null - [null, null, null, null, null] +20237 - Penance cave - [Block, null, null, null, null] +20238 - Penance cave - [Demolish, null, null, null, null] +20239 - Penance cave - [Fix, null, null, null, null] +20240 - null - [null, null, null, null, null] +20241 - Attacker item machine - [null, Take-Runes, Take-Arrows, null, null] +20242 - Defender item machine - [Stock-Up, Take-Crackers, Take-Tofu, Take-Worms, null] +20243 - Healer item machine - [Stock-Up, Take-Vial, Take-Tofu, Take-Worms, Take-Meat] +20244 - null - [null, null, null, null, null] +20245 - null - [null, null, null, null, null] +20246 - null - [null, null, null, null, null] +20247 - Horn of glory - [Call, null, null, null, null] +20248 - Horn of glory - [Call, null, null, null, null] +20249 - null - [null, null, null, null, null] +20250 - Petrified mushroom - [Get-Spikes, null, null, null, null] +20251 - Petrified mushroom - [null, null, null, null, null] +20252 - null - [null, null, null, null, null] +20253 - null - [null, null, null, null, null] +20254 - null - [null, null, null, null, null] +20255 - null - [null, null, null, null, null] +20256 - null - [null, null, null, null, null] +20257 - null - [null, null, null, null, null] +20258 - null - [null, null, null, null, null] +20259 - Egg launcher - [null, null, null, null, null] +20260 - Hopper - [null, null, null, null, null] +20261 - Hopper - [null, null, null, null, null] +20262 - Hopper - [null, null, null, null, null] +20263 - Egg launcher - [null, null, null, null, null] +20264 - Egg hopper - [Load, Look-in, null, null, null] +20265 - Egg hopper - [Load, Look-in, null, null, null] +20266 - Egg hopper - [Load, Look-in, null, null, null] +20267 - null - [Load, Look-in, null, null, null] +20268 - null - [null, null, null, null, null] +20269 - null - [null, null, null, null, null] +20270 - null - [null, null, null, null, null] +20271 - Floor - [Search, null, null, null, null] +20272 - Odd markings - [Search, null, null, null, null] +20273 - Speartrap - [null, null, null, null, null] +20274 - Trapdoor - [null, null, null, null, null] +20275 - Ladder - [Climb-down, null, null, null, null] +20276 - null - [null, null, null, null, null] +20277 - Ladder - [Climb-up, null, null, null, null] +20278 - Ladder - [Climb-down, null, null, null, null] +20279 - Trapdoor - [null, null, null, null, null] +20280 - Ladder - [Climb-up, null, null, null, null] +20281 - Ladder - [Climb-up, null, null, null, null] +20282 - null - [Climb-up, null, null, null, null] +20283 - null - [Climb-up, null, null, null, null] +20284 - Ladder - [Climb-up, null, null, null, null] +20285 - Ladder - [Climb-down, null, null, null, null] +20286 - Ladder - [Climb-up, null, null, null, null] +20287 - Ladder - [Climb-down, null, null, null, null] +20288 - Kaleef's body - [Search, null, null, null, null] +20289 - null - [null, null, null, null, null] +20290 - null - [null, null, null, null, null] +20291 - null - [null, null, null, null, null] +20292 - null - [null, null, null, null, null] +20293 - null - [null, null, null, null, null] +20294 - null - [null, null, null, null, null] +20295 - null - [null, null, null, null, null] +20296 - null - [null, null, null, null, null] +20297 - Corpse - [null, null, null, null, null] +20298 - Corpse - [null, null, null, null, null] +20299 - Corpse - [null, null, null, null, null] +20300 - Corpse - [null, null, null, null, null] +20301 - null - [null, null, null, null, null] +20302 - null - [null, null, null, null, null] +20303 - null - [null, null, null, null, null] +20304 - null - [null, null, null, null, null] +20305 - null - [null, null, null, null, null] +20306 - null - [null, null, null, null, null] +20307 - null - [null, null, null, null, null] +20308 - null - [null, null, null, null, null] +20309 - null - [null, null, null, null, null] +20310 - null - [null, null, null, null, null] +20311 - null - [null, null, null, null, null] +20312 - null - [null, null, null, null, null] +20313 - null - [null, null, null, null, null] +20314 - null - [null, null, null, null, null] +20315 - null - [null, null, null, null, null] +20316 - null - [null, null, null, null, null] +20317 - null - [null, null, null, null, null] +20318 - null - [null, null, null, null, null] +20319 - null - [null, null, null, null, null] +20320 - null - [null, null, null, null, null] +20321 - null - [null, null, null, null, null] +20322 - Red Castlewars armour - [null, null, null, null, Remove] +20323 - Private bank booth - [null, null, null, null, null] +20324 - Private bank booth - [null, null, null, null, null] +20325 - Bank booth - [Use, Use-quickly, Collect, null, null] +20326 - Bank booth - [null, null, null, null, null] +20327 - Bank booth - [null, null, null, null, null] +20328 - Bank booth - [null, null, null, null, null] +20329 - Bank table - [null, null, null, null, null] +20330 - Bank table - [null, null, null, null, null] +20331 - Dagger stall - [null, null, null, null, null] +20332 - Craft stall - [null, null, null, null, null] +20333 - null - [null, null, null, null, null] +20334 - null - [null, null, null, null, null] +20335 - Floor - [null, null, null, null, null] +20336 - null - [null, null, null, null, null] +20337 - null - [null, null, null, null, null] +20338 - null - [null, null, null, null, null] +20339 - null - [null, null, null, null, null] +20340 - Trapdoor - [Climb-down, null, null, null, null] +20341 - Gate - [Open, null, null, null, null] +20342 - Cart - [null, null, null, null, null] +20343 - Cart - [null, null, null, null, null] +20344 - Silk stall - [null, null, null, null, null] +20345 - Bakery stall - [null, null, null, null, null] +20346 - Gem stall - [null, null, null, null, null] +20347 - Fur stall - [null, null, null, null, null] +20348 - Spice stall - [Search, null, null, null, null] +20349 - Market stall - [null, null, null, null, null] +20350 - Tea stall - [null, Steal-from, null, null, null] +20351 - Table - [null, null, null, null, null] +20352 - Chair - [null, null, null, null, null] +20353 - Ladder - [Climb-up, null, null, null, null] +20354 - Ladder - [Climb-down, null, null, null, null] +20355 - null - [null, null, null, null, null] +20356 - Ladder - [Climb-up, null, null, null, null] +20357 - Ladder - [Climb-down, null, null, null, null] +20358 - Sink - [null, null, null, null, null] +20359 - Wheelbarrow - [null, null, null, null, null] +20360 - Work bench - [null, null, null, null, null] +20361 - null - [null, null, null, null, null] +20362 - Shelf - [null, null, null, null, null] +20363 - null - [null, null, null, null, null] +20364 - Clothing shelves - [null, null, null, null, null] +20365 - Spinning wheel - [null, Spin, null, null, null] +20366 - null - [null, null, null, null, null] +20367 - Crate - [null, null, null, null, null] +20368 - Crate - [null, null, null, null, null] +20369 - Boxes - [Search, null, null, null, null] +20370 - Log pile - [null, null, null, null, null] +20371 - Broken logs - [null, null, null, null, null] +20372 - Hollow log - [null, null, null, null, null] +20373 - Logs - [null, null, null, null, null] +20374 - Logs - [null, null, null, null, null] +20375 - Potter's wheel - [null, null, null, null, null] +20376 - Clothes - [null, null, null, null, null] +20377 - Altar - [Pray-at, null, null, null, null] +20378 - Altar - [Pray-at, null, null, null, null] +20379 - Altar - [null, null, null, null, null] +20380 - null - [null, null, null, null, null] +20381 - null - [null, null, null, null, null] +20382 - null - [null, null, null, null, null] +20383 - null - [null, null, null, null, null] +20384 - null - [null, null, null, null, null] +20385 - null - [null, null, null, null, null] +20386 - Bed - [null, null, null, null, null] +20387 - Bed - [null, null, null, null, null] +20388 - Cloth covered table - [null, null, null, null, null] +20389 - null - [null, null, null, null, null] +20390 - null - [null, null, null, null, null] +20391 - Gate - [Open, Use-quickly, null, null, null] +20392 - null - [null, null, null, null, null] +20393 - null - [null, null, null, null, null] +20394 - null - [null, null, null, null, null] +20395 - null - [null, null, null, null, null] +20396 - null - [null, null, null, null, null] +20397 - null - [null, null, null, null, null] +20398 - null - [null, null, null, null, null] +20399 - null - [null, null, null, null, null] +20400 - null - [null, null, null, null, null] +20401 - null - [null, null, null, null, null] +20402 - Buffers - [null, null, null, null, null] +20403 - null - [null, null, null, null, null] +20404 - null - [null, null, null, null, null] +20405 - null - [null, null, null, null, null] +20406 - null - [null, null, null, null, null] +20407 - Ore vein - [Mine, Prospect, null, null, null] +20408 - Ore vein - [Mine, Prospect, null, null, null] +20409 - Ore vein - [Mine, Prospect, null, null, null] +20410 - Ore vein - [Mine, Prospect, null, null, null] +20411 - Ore vein - [Mine, Prospect, null, null, null] +20412 - Ore vein - [Mine, Prospect, null, null, null] +20413 - Ore vein - [Mine, Prospect, null, null, null] +20414 - Ore vein - [Mine, Prospect, null, null, null] +20415 - Ore vein - [Mine, Prospect, null, null, null] +20416 - Ore vein - [Mine, Prospect, null, null, null] +20417 - Ore vein - [Mine, Prospect, null, null, null] +20418 - Ore vein - [Mine, Prospect, null, null, null] +20419 - Ore vein - [Mine, Prospect, null, null, null] +20420 - Ore vein - [Mine, Prospect, null, null, null] +20421 - Ore vein - [Mine, Prospect, null, null, null] +20422 - Ore vein - [Mine, Prospect, null, null, null] +20423 - Ore vein - [Mine, Prospect, null, null, null] +20424 - Ore vein - [Mine, Prospect, null, null, null] +20425 - Ore vein - [Mine, Prospect, null, null, null] +20426 - Stairs - [Walk-up, null, null, null, null] +20427 - null - [null, null, null, null, null] +20428 - null - [null, null, null, null, null] +20429 - Crate - [null, null, null, null, null] +20430 - Crate - [null, null, null, null, null] +20431 - Barrel - [null, null, null, null, null] +20432 - null - [null, null, null, null, null] +20433 - Cart tunnel - [null, null, null, null, null] +20434 - null - [null, null, null, null, null] +20435 - Stairs - [Walk-down, null, null, null, null] +20436 - null - [null, null, null, null, null] +20437 - null - [null, null, null, null, null] +20438 - null - [null, null, null, null, null] +20439 - Depleted vein - [Mine, Prospect, null, null, null] +20440 - Depleted vein - [Mine, Prospect, null, null, null] +20441 - Depleted vein - [Mine, Prospect, null, null, null] +20442 - Depleted vein - [Mine, Prospect, null, null, null] +20443 - Ore vein - [Mine, Prospect, null, null, null] +20444 - Ore vein - [Mine, Prospect, null, null, null] +20445 - Ore vein - [Mine, Prospect, null, null, null] +20446 - Ore vein - [Mine, Prospect, null, null, null] +20447 - Ore vein - [Mine, Prospect, null, null, null] +20448 - Ore vein - [Mine, Prospect, null, null, null] +20449 - Ore vein - [Mine, Prospect, null, null, null] +20450 - Ore vein - [Mine, Prospect, null, null, null] +20451 - Ore vein - [Mine, Prospect, null, null, null] +20452 - Armour - [null, null, null, null, null] +20453 - Armour - [null, null, null, null, null] +20454 - Skeleton - [null, null, null, null, null] +20455 - Skeleton - [null, null, null, null, null] +20456 - Skeleton - [null, null, null, null, null] +20457 - Skeleton - [null, null, null, null, null] +20458 - Locker - [null, null, null, null, null] +20459 - Stool - [null, null, null, null, null] +20460 - Small table - [null, null, null, null, null] +20461 - Bookcase - [null, null, null, null, null] +20462 - Bed - [null, null, null, null, null] +20463 - Crate - [Search, null, null, null, null] +20464 - Crate - [Search, null, null, null, null] +20465 - Passageway - [Enter, null, null, null, null] +20466 - Passageway - [Enter, null, null, null, null] +20467 - Passageway - [Enter, null, null, null, null] +20468 - Passageway - [Enter, null, null, null, null] +20469 - Passageway - [Enter, null, null, null, null] +20470 - null - [null, null, null, null, null] +20471 - null - [null, null, null, null, null] +20472 - null - [null, null, null, null, null] +20473 - null - [null, null, null, null, null] +20474 - null - [null, null, null, null, null] +20475 - null - [null, null, null, null, null] +20476 - null - [null, null, null, null, null] +20477 - null - [null, null, null, null, null] +20478 - null - [null, null, null, null, null] +20479 - null - [null, null, null, null, null] +20480 - null - [null, null, null, null, null] +20481 - null - [null, null, null, null, null] +20482 - null - [null, null, null, null, null] +20483 - null - [null, null, null, null, null] +20484 - null - [null, null, null, null, null] +20485 - null - [null, null, null, null, null] +20486 - null - [null, null, null, null, null] +20487 - null - [null, null, null, null, null] +20488 - null - [null, null, null, null, null] +20489 - null - [null, null, null, null, null] +20490 - null - [null, null, null, null, null] +20491 - null - [null, null, null, null, null] +20492 - null - [null, null, null, null, null] +20493 - null - [null, null, null, null, null] +20494 - null - [null, null, null, null, null] +20495 - null - [null, null, null, null, null] +20496 - null - [null, null, null, null, null] +20497 - null - [null, null, null, null, null] +20498 - null - [null, null, null, null, null] +20499 - null - [null, null, null, null, null] +20500 - null - [null, null, null, null, null] +20501 - null - [null, null, null, null, null] +20502 - null - [null, null, null, null, null] +20503 - null - [null, null, null, null, null] +20504 - null - [null, null, null, null, null] +20505 - null - [null, null, null, null, null] +20506 - null - [null, null, null, null, null] +20507 - null - [null, null, null, null, null] +20508 - null - [null, null, null, null, null] +20509 - null - [null, null, null, null, null] +20510 - Crate - [null, null, null, null, null] +20511 - Barrel - [null, null, null, null, null] +20512 - null - [null, null, null, null, null] +20513 - null - [null, null, null, null, null] +20514 - null - [null, null, null, null, null] +20515 - null - [null, null, null, null, null] +20516 - null - [null, null, null, null, null] +20517 - null - [null, null, null, null, null] +20518 - null - [null, null, null, null, null] +20519 - Buffers - [null, null, null, null, null] +20520 - null - [null, null, null, null, null] +20521 - null - [null, null, null, null, null] +20522 - null - [null, null, null, null, null] +20523 - null - [null, null, null, null, null] +20524 - Cart tunnel - [Crawl-through, null, null, null, null] +20525 - Cart tunnel - [Crawl-through, null, null, null, null] +20526 - Wall support - [null, null, null, null, null] +20527 - Entrance - [Enter, null, null, null, null] +20528 - Entrance - [null, null, null, null, null] +20529 - null - [null, null, null, null, null] +20530 - null - [null, null, null, null, null] +20531 - Bars - [null, null, null, null, null] +20532 - Bars - [null, null, null, null, null] +20533 - Bars - [null, null, null, null, null] +20534 - Bars - [null, null, null, null, null] +20535 - Stairs - [Climb, null, null, null, null] +20536 - Stairs - [null, null, null, null, null] +20537 - null - [null, null, null, null, null] +20538 - null - [null, null, null, null, null] +20539 - null - [null, null, null, null, null] +20540 - null - [null, null, null, null, null] +20541 - null - [null, null, null, null, null] +20542 - null - [null, null, null, null, null] +20543 - null - [null, null, null, null, null] +20544 - null - [null, null, null, null, null] +20545 - null - [null, null, null, null, null] +20546 - null - [null, null, null, null, null] +20547 - null - [null, null, null, null, null] +20548 - null - [null, null, null, null, null] +20549 - null - [null, null, null, null, null] +20550 - null - [null, null, null, null, null] +20551 - null - [null, null, null, null, null] +20552 - null - [null, null, null, null, null] +20553 - null - [null, null, null, null, null] +20554 - null - [null, null, null, null, null] +20555 - null - [null, null, null, null, null] +20556 - null - [null, null, null, null, null] +20557 - null - [null, null, null, null, null] +20558 - null - [null, null, null, null, null] +20559 - null - [null, null, null, null, null] +20560 - null - [null, null, null, null, null] +20561 - null - [null, null, null, null, null] +20562 - null - [null, null, null, null, null] +20563 - null - [null, null, null, null, null] +20564 - null - [null, null, null, null, null] +20565 - null - [null, null, null, null, null] +20566 - null - [null, null, null, null, null] +20567 - null - [null, null, null, null, null] +20568 - null - [null, null, null, null, null] +20569 - null - [null, null, null, null, null] +20570 - null - [null, null, null, null, null] +20571 - null - [null, null, null, null, null] +20572 - Passageway - [Enter, null, null, null, null] +20573 - Passageway - [Enter, null, null, null, null] +20574 - Passageway - [Enter, null, null, null, null] +20575 - Passageway - [Enter, null, null, null, null] +20576 - Passageway - [Enter, null, null, null, null] +20577 - Passageway - [Enter, null, null, null, null] +20578 - null - [null, null, null, null, null] +20579 - null - [null, null, null, null, null] +20580 - null - [null, null, null, null, null] +20581 - null - [null, null, null, null, null] +20582 - null - [null, null, null, null, null] +20583 - null - [null, null, null, null, null] +20584 - null - [null, null, null, null, null] +20585 - null - [null, null, null, null, null] +20586 - null - [null, null, null, null, null] +20587 - null - [null, null, null, null, null] +20588 - null - [null, null, null, null, null] +20589 - null - [null, null, null, null, null] +20590 - null - [null, null, null, null, null] +20591 - null - [null, null, null, null, null] +20592 - null - [null, null, null, null, null] +20593 - null - [null, null, null, null, null] +20594 - null - [null, null, null, null, null] +20595 - null - [null, null, null, null, null] +20596 - null - [null, null, null, null, null] +20597 - null - [null, null, null, null, null] +20598 - null - [null, null, null, null, null] +20599 - null - [null, null, null, null, null] +20600 - null - [null, null, null, null, null] +20601 - null - [null, null, null, null, null] +20602 - null - [null, null, null, null, null] +20603 - null - [null, null, null, null, null] +20604 - null - [null, null, null, null, null] +20605 - null - [null, null, null, null, null] +20606 - null - [null, null, null, null, null] +20607 - null - [null, null, null, null, null] +20608 - null - [null, null, null, null, null] +20609 - null - [null, null, null, null, null] +20610 - null - [null, null, null, null, null] +20611 - null - [null, null, null, null, null] +20612 - null - [null, null, null, null, null] +20613 - null - [null, null, null, null, null] +20614 - null - [null, null, null, null, null] +20615 - null - [null, null, null, null, null] +20616 - null - [null, null, null, null, null] +20617 - null - [null, null, null, null, null] +20618 - null - [null, null, null, null, null] +20619 - Stairs - [Climb, null, null, null, null] +20620 - Stairs - [null, null, null, null, null] +20621 - null - [null, null, null, null, null] +20622 - null - [null, null, null, null, null] +20623 - null - [null, null, null, null, null] +20624 - null - [null, null, null, null, null] +20625 - null - [null, null, null, null, null] +20626 - null - [null, null, null, null, null] +20627 - null - [null, null, null, null, null] +20628 - null - [null, null, null, null, null] +20629 - null - [null, null, null, null, null] +20630 - null - [null, null, null, null, null] +20631 - null - [null, null, null, null, null] +20632 - null - [null, null, null, null, null] +20633 - null - [null, null, null, null, null] +20634 - null - [null, null, null, null, null] +20635 - null - [null, null, null, null, null] +20636 - null - [null, null, null, null, null] +20637 - null - [null, null, null, null, null] +20638 - null - [null, null, null, null, null] +20639 - null - [null, null, null, null, null] +20640 - null - [null, null, null, null, null] +20641 - null - [null, null, null, null, null] +20642 - null - [null, null, null, null, null] +20643 - null - [null, null, null, null, null] +20644 - null - [null, null, null, null, null] +20645 - null - [null, null, null, null, null] +20646 - null - [null, null, null, null, null] +20647 - null - [null, null, null, null, null] +20648 - null - [null, null, null, null, null] +20649 - null - [null, null, null, null, null] +20650 - null - [null, null, null, null, null] +20651 - null - [null, null, null, null, null] +20652 - Passageway - [Enter, null, null, null, null] +20653 - Passageway - [Enter, null, null, null, null] +20654 - Passageway - [Enter, null, null, null, null] +20655 - Passageway - [Enter, null, null, null, null] +20656 - Passageway - [Enter, null, null, null, null] +20657 - Passageway - [Enter, null, null, null, null] +20658 - null - [null, null, null, null, null] +20659 - null - [null, null, null, null, null] +20660 - null - [null, null, null, null, null] +20661 - null - [null, null, null, null, null] +20662 - null - [null, null, null, null, null] +20663 - null - [null, null, null, null, null] +20664 - null - [null, null, null, null, null] +20665 - null - [null, null, null, null, null] +20666 - null - [null, null, null, null, null] +20667 - null - [null, null, null, null, null] +20668 - null - [null, null, null, null, null] +20669 - null - [null, null, null, null, null] +20670 - null - [null, null, null, null, null] +20671 - null - [null, null, null, null, null] +20672 - null - [null, null, null, null, null] +20673 - null - [null, null, null, null, null] +20674 - null - [null, null, null, null, null] +20675 - null - [null, null, null, null, null] +20676 - null - [null, null, null, null, null] +20677 - null - [null, null, null, null, null] +20678 - null - [null, null, null, null, null] +20679 - null - [null, null, null, null, null] +20680 - null - [null, null, null, null, null] +20681 - null - [null, null, null, null, null] +20682 - null - [null, null, null, null, null] +20683 - null - [null, null, null, null, null] +20684 - Stairs - [Climb, null, null, null, null] +20685 - Stairs - [null, null, null, null, null] +20686 - null - [null, null, null, null, null] +20687 - null - [null, null, null, null, null] +20688 - null - [null, null, null, null, null] +20689 - null - [null, null, null, null, null] +20690 - null - [null, null, null, null, null] +20691 - null - [null, null, null, null, null] +20692 - null - [null, null, null, null, null] +20693 - Ledge - [Walk-across, null, null, null, null] +20694 - null - [null, null, null, null, null] +20695 - null - [null, null, null, null, null] +20696 - null - [null, null, null, null, null] +20697 - null - [null, null, null, null, null] +20698 - null - [null, null, null, null, null] +20699 - null - [null, null, null, null, null] +20700 - null - [null, null, null, null, null] +20701 - null - [null, null, null, null, null] +20702 - null - [null, null, null, null, null] +20703 - null - [null, null, null, null, null] +20704 - null - [null, null, null, null, null] +20705 - null - [null, null, null, null, null] +20706 - null - [null, null, null, null, null] +20707 - null - [null, null, null, null, null] +20708 - null - [null, null, null, null, null] +20709 - null - [null, null, null, null, null] +20710 - null - [null, null, null, null, null] +20711 - null - [null, null, null, null, null] +20712 - null - [null, null, null, null, null] +20713 - null - [null, null, null, null, null] +20714 - null - [null, null, null, null, null] +20715 - null - [null, null, null, null, null] +20716 - null - [null, null, null, null, null] +20717 - Passageway - [Enter, null, null, null, null] +20718 - Passageway - [Enter, null, null, null, null] +20719 - Passageway - [Enter, null, null, null, null] +20720 - Passageway - [Enter, null, null, null, null] +20721 - Passageway - [Enter, null, null, null, null] +20722 - Passageway - [Enter, null, null, null, null] +20723 - null - [null, null, null, null, null] +20724 - null - [null, null, null, null, null] +20725 - null - [null, null, null, null, null] +20726 - null - [null, null, null, null, null] +20727 - null - [null, null, null, null, null] +20728 - null - [null, null, null, null, null] +20729 - null - [null, null, null, null, null] +20730 - null - [null, null, null, null, null] +20731 - null - [null, null, null, null, null] +20732 - null - [null, null, null, null, null] +20733 - null - [null, null, null, null, null] +20734 - null - [null, null, null, null, null] +20735 - null - [null, null, null, null, null] +20736 - null - [null, null, null, null, null] +20737 - null - [null, null, null, null, null] +20738 - null - [null, null, null, null, null] +20739 - null - [null, null, null, null, null] +20740 - null - [null, null, null, null, null] +20741 - null - [null, null, null, null, null] +20742 - null - [null, null, null, null, null] +20743 - null - [null, null, null, null, null] +20744 - null - [null, null, null, null, null] +20745 - null - [null, null, null, null, null] +20746 - null - [null, null, null, null, null] +20747 - null - [null, null, null, null, null] +20748 - null - [null, null, null, null, null] +20749 - Stairs - [Climb, null, null, null, null] +20750 - Stairs - [null, null, null, null, null] +20751 - null - [null, null, null, null, null] +20752 - null - [null, null, null, null, null] +20753 - null - [null, null, null, null, null] +20754 - null - [null, null, null, null, null] +20755 - null - [null, null, null, null, null] +20756 - null - [null, null, null, null, null] +20757 - null - [null, null, null, null, null] +20758 - null - [null, null, null, null, null] +20759 - null - [null, null, null, null, null] +20760 - null - [null, null, null, null, null] +20761 - null - [null, null, null, null, null] +20762 - null - [null, null, null, null, null] +20763 - null - [null, null, null, null, null] +20764 - null - [null, null, null, null, null] +20765 - null - [null, null, null, null, null] +20766 - null - [null, null, null, null, null] +20767 - null - [null, null, null, null, null] +20768 - null - [null, null, null, null, null] +20769 - null - [null, null, null, null, null] +20770 - null - [null, null, null, null, null] +20771 - null - [null, null, null, null, null] +20772 - null - [null, null, null, null, null] +20773 - null - [null, null, null, null, null] +20774 - null - [null, null, null, null, null] +20775 - null - [null, null, null, null, null] +20776 - null - [null, null, null, null, null] +20777 - null - [null, null, null, null, null] +20778 - null - [null, null, null, null, null] +20779 - null - [null, null, null, null, null] +20780 - null - [null, null, null, null, null] +20781 - null - [null, null, null, null, null] +20782 - Passageway - [Enter, null, null, null, null] +20783 - Passageway - [Enter, null, null, null, null] +20784 - Passageway - [Enter, null, null, null, null] +20785 - Passageway - [Enter, null, null, null, null] +20786 - Passageway - [Enter, null, null, null, null] +20787 - Passageway - [Enter, null, null, null, null] +20788 - null - [null, null, null, null, null] +20789 - null - [null, null, null, null, null] +20790 - null - [null, null, null, null, null] +20791 - null - [null, null, null, null, null] +20792 - null - [null, null, null, null, null] +20793 - null - [null, null, null, null, null] +20794 - null - [null, null, null, null, null] +20795 - null - [null, null, null, null, null] +20796 - null - [null, null, null, null, null] +20797 - null - [null, null, null, null, null] +20798 - null - [null, null, null, null, null] +20799 - null - [null, null, null, null, null] +20800 - null - [null, null, null, null, null] +20801 - null - [null, null, null, null, null] +20802 - null - [null, null, null, null, null] +20803 - null - [null, null, null, null, null] +20804 - null - [null, null, null, null, null] +20805 - null - [null, null, null, null, null] +20806 - null - [null, null, null, null, null] +20807 - null - [null, null, null, null, null] +20808 - null - [null, null, null, null, null] +20809 - null - [null, null, null, null, null] +20810 - null - [null, null, null, null, null] +20811 - null - [null, null, null, null, null] +20812 - null - [null, null, null, null, null] +20813 - null - [null, null, null, null, null] +20814 - Passageway - [Enter, null, null, null, null] +20815 - Passageway - [Enter, null, null, null, null] +20816 - Stairs - [Enter, null, null, null, null] +20817 - Passageway - [Enter, null, null, null, null] +20818 - Stairs - [Enter, null, null, null, null] +20819 - Stairs - [Enter, null, null, null, null] +20820 - Passageway - [Enter, null, null, null, null] +20821 - Passageway - [Enter, null, null, null, null] +20822 - Passageway - [Enter, null, null, null, null] +20823 - Passageway - [Enter, null, null, null, null] +20824 - Passageway - [Enter, null, null, null, null] +20825 - Passageway - [Enter, null, null, null, null] +20826 - Stairs - [Enter, null, null, null, null] +20827 - Passageway - [Enter, null, null, null, null] +20828 - Stairs - [Enter, null, null, null, null] +20829 - Passageway - [Enter, null, null, null, null] +20830 - Passageway - [Enter, null, null, null, null] +20831 - Passageway - [Enter, null, null, null, null] +20832 - Passageway - [Enter, null, null, null, null] +20833 - Passageway - [Enter, null, null, null, null] +20834 - Passageway - [Enter, null, null, null, null] +20835 - Passageway - [Enter, null, null, null, null] +20836 - Passageway - [Enter, null, null, null, null] +20837 - Passageway - [Enter, null, null, null, null] +20838 - Passageway - [Enter, null, null, null, null] +20839 - Passageway - [Enter, null, null, null, null] +20840 - Stairs - [Enter, null, null, null, null] +20841 - Passageway - [Enter, null, null, null, null] +20842 - Passageway - [Enter, null, null, null, null] +20843 - Passageway - [Enter, null, null, null, null] +20844 - Passageway - [Enter, null, null, null, null] +20845 - Passageway - [Enter, null, null, null, null] +20846 - Passageway - [Enter, null, null, null, null] +20847 - Passageway - [Enter, null, null, null, null] +20848 - Passageway - [Enter, null, null, null, null] +20849 - Passageway - [Enter, null, null, null, null] +20850 - Passageway - [Enter, null, null, null, null] +20851 - Passageway - [Enter, null, null, null, null] +20852 - Passageway - [Enter, null, null, null, null] +20853 - Passageway - [Enter, null, null, null, null] +20854 - Passageway - [Enter, null, null, null, null] +20855 - Passageway - [Enter, null, null, null, null] +20856 - Passageway - [Enter, null, null, null, null] +20857 - Passageway - [Enter, null, null, null, null] +20858 - Passageway - [Enter, null, null, null, null] +20859 - Passageway - [Enter, null, null, null, null] +20860 - Passageway - [Enter, null, null, null, null] +20861 - Passageway - [Enter, null, null, null, null] +20862 - Passageway - [Enter, null, null, null, null] +20863 - Passageway - [Enter, null, null, null, null] +20864 - Passageway - [Enter, null, null, null, null] +20865 - Passageway - [Enter, null, null, null, null] +20866 - Passageway - [Enter, null, null, null, null] +20867 - Passageway - [Enter, null, null, null, null] +20868 - Passageway - [Enter, null, null, null, null] +20869 - Passageway - [Enter, null, null, null, null] +20870 - Passageway - [Enter, null, null, null, null] +20871 - Passageway - [Enter, null, null, null, null] +20872 - Pillar - [null, null, null, null, Jump-to] +20873 - Pillar - [null, null, null, null, Jump-to] +20874 - Pillar - [null, null, null, null, Jump-to] +20875 - Pillar - [null, null, null, null, Jump-to] +20876 - Pillar - [null, null, null, null, Jump-to] +20877 - Pillar - [null, null, null, null, Jump-to] +20878 - Pillar - [null, null, null, null, Jump-to] +20879 - Pillar - [null, null, null, null, Jump-to] +20880 - Pillar - [null, null, null, null, Jump-to] +20881 - Pillar - [null, null, null, null, Jump-to] +20882 - Pillar - [null, null, null, null, Jump-to] +20883 - Pillar - [null, null, null, null, Jump-to] +20884 - Pillar - [null, null, null, null, Jump-to] +20885 - Pillar - [null, null, null, null, Jump-to] +20886 - Pillar - [null, null, null, null, Jump-to] +20887 - Pillar - [null, null, null, null, Jump-to] +20888 - Pillar - [null, null, null, null, Jump-to] +20889 - Pillar - [null, null, null, null, Jump-to] +20890 - Ledge - [null, null, null, null, Jump-to] +20891 - Ledge - [null, null, null, null, Jump-to] +20892 - Ledge - [null, null, null, null, Jump-to] +20893 - Ledge - [null, null, null, null, Jump-to] +20894 - Ledge - [null, null, null, null, Jump-to] +20895 - Ledge - [null, null, null, null, Jump-to] +20896 - Ledge - [null, null, null, null, Jump-to] +20897 - Ledge - [null, null, null, null, Jump-to] +20898 - Ledge - [null, null, null, null, Jump-to] +20899 - Ledge - [null, null, null, null, Jump-to] +20900 - Ledge - [null, null, null, null, Jump-to] +20901 - Ledge - [null, null, null, null, Jump-to] +20902 - Trap bypass - [null, null, null, null, null] +20903 - Hanging log - [null, null, null, null, null] +20904 - Hanging log - [null, null, null, null, null] +20905 - Hanging log - [null, null, null, null, null] +20906 - Hanging log - [null, null, null, null, null] +20907 - null - [null, null, null, null, null] +20908 - null - [null, null, null, null, null] +20909 - null - [null, null, null, null, null] +20910 - null - [null, null, null, null, null] +20911 - null - [null, null, null, null, null] +20912 - null - [null, null, null, null, null] +20913 - null - [null, null, null, null, null] +20914 - null - [null, null, null, null, null] +20915 - Floor - [null, null, null, null, Search] +20916 - Floor - [null, null, null, null, Search] +20917 - Floor - [null, null, null, null, Search] +20918 - Floor - [null, null, null, null, Search] +20919 - Floor - [null, null, null, null, null] +20920 - Wall - [null, null, null, null, Search] +20921 - Wall - [null, null, null, null, null] +20922 - Wall - [null, null, null, null, Search] +20923 - Wall - [null, null, null, null, null] +20924 - Wall - [null, null, null, null, Search] +20925 - Wall - [null, null, null, null, Search] +20926 - Wall - [null, null, null, null, Search] +20927 - Wall - [null, null, null, null, null] +20928 - Wall - [null, null, null, null, Search] +20929 - Wall - [null, null, null, null, null] +20930 - Wall - [null, null, null, null, Search] +20931 - Wall - [null, null, null, null, Search] +20932 - Wall - [null, null, null, null, null] +20933 - Wall - [null, null, null, null, null] +20934 - Wall - [null, null, null, null, null] +20935 - Wall - [null, null, null, null, null] +20936 - Wall - [null, null, null, null, null] +20937 - Wall - [null, null, null, null, null] +20938 - Wall - [null, null, null, null, null] +20939 - Wall - [null, null, null, null, null] +20940 - Wall - [null, null, null, null, null] +20941 - Wall - [null, null, null, null, null] +20942 - Wall - [null, null, null, null, null] +20943 - Wall - [null, null, null, null, null] +20944 - Wall - [null, null, null, null, null] +20945 - Wall - [null, null, null, null, null] +20946 - Wall - [null, null, null, null, null] +20947 - Wall - [null, null, null, null, null] +20948 - Wall - [null, null, null, null, null] +20949 - Wall - [null, null, null, null, null] +20950 - Wall - [null, null, null, null, null] +20951 - Wall - [null, null, null, null, null] +20952 - Wall - [null, null, null, null, null] +20953 - Wall - [null, null, null, null, null] +20954 - Wall - [null, null, null, null, null] +20955 - Wall - [null, null, null, null, null] +20956 - Floor - [null, null, null, null, null] +20957 - Floor - [null, null, null, null, null] +20958 - Floor - [null, null, null, null, null] +20959 - Floor - [null, null, null, null, null] +20960 - Floor - [null, null, null, null, null] +20961 - Floor - [null, null, null, null, null] +20962 - Floor - [null, null, null, null, null] +20963 - Floor - [null, null, null, null, null] +20964 - Floor - [Search, null, null, null, null] +20965 - Floor - [Search, null, null, null, null] +20966 - Floor - [Search, null, null, null, null] +20967 - Floor - [Search, null, null, null, null] +20968 - Floor - [Search, null, null, null, null] +20969 - Floor - [Search, null, null, null, null] +20970 - Floor - [Search, null, null, null, null] +20971 - Floor - [Search, null, null, null, null] +20972 - null - [null, null, null, null, null] +20973 - null - [null, null, null, null, null] +20974 - null - [null, null, null, null, null] +20975 - null - [null, null, null, null, null] +20976 - null - [null, null, null, null, null] +20977 - null - [null, null, null, null, null] +20978 - Gnome skeleton - [null, null, null, null, null] +20979 - null - [null, null, null, null, null] +20980 - null - [null, null, null, null, null] +20981 - null - [null, null, null, null, null] +20982 - null - [null, null, null, null, null] +20983 - null - [null, null, null, null, null] +20984 - null - [null, null, null, null, null] +20985 - Mummy - [null, null, null, null, null] +20986 - Mummy - [null, null, null, null, null] +20987 - Ladder - [Climb-down, null, null, null, null] +20988 - null - [null, null, null, null, null] +20989 - null - [null, null, null, null, null] +20990 - null - [null, null, null, null, null] +20991 - null - [null, null, null, null, null] +20992 - null - [null, null, null, null, null] +20993 - null - [null, null, null, null, null] +20994 - null - [null, null, null, null, null] +20995 - Golf-cart - [null, null, null, null, null] +20996 - Table - [null, null, null, null, null] +20997 - null - [null, null, null, null, null] +20998 - null - [null, null, null, null, null] +20999 - Chair - [null, null, null, null, null] +21000 - Map - [null, null, null, null, null] +21001 - Interrogation chair - [null, null, null, null, null] +21002 - Steam generator - [null, null, null, null, null] +21003 - null - [null, null, null, null, null] +21004 - null - [null, null, null, null, null] +21005 - null - [null, null, null, null, null] +21006 - null - [null, null, null, null, null] +21007 - null - [null, null, null, null, null] +21008 - Drill - [null, null, null, null, null] +21009 - Lathe - [null, null, null, null, null] +21010 - Gigantic penguin - [null, null, null, null, null] +21011 - null - [null, null, null, null, null] +21012 - null - [null, null, null, null, null] +21013 - Crate - [null, null, null, null, null] +21014 - Crate - [null, null, null, null, null] +21015 - Crates - [null, null, null, null, null] +21016 - Barrel - [null, null, null, null, null] +21017 - null - [null, null, null, null, null] +21018 - Workbench - [null, null, null, null, null] +21019 - Workbench - [null, null, null, null, null] +21020 - null - [null, null, null, null, null] +21021 - null - [null, null, null, null, null] +21022 - Bed - [null, null, null, null, null] +21023 - Lockers - [null, null, null, null, null] +21024 - Foot lockers - [null, null, null, null, null] +21025 - Cello - [null, null, null, null, null] +21026 - Guitar - [null, null, null, null, null] +21027 - Harp - [null, null, null, null, null] +21028 - Flute - [null, null, null, null, null] +21029 - Trumpet - [null, null, null, null, null] +21030 - Piano - [null, null, null, null, null] +21031 - Stool - [null, null, null, null, null] +21032 - Clarinet - [null, null, null, null, null] +21033 - Music Scores - [null, null, null, null, null] +21034 - null - [null, null, null, null, null] +21035 - Chasm - [Use, null, null, null, null] +21036 - null - [null, null, null, null, null] +21037 - null - [null, null, null, null, null] +21038 - null - [null, null, null, null, null] +21039 - null - [null, null, null, null, null] +21040 - null - [null, null, null, null, null] +21041 - null - [null, null, null, null, null] +21042 - null - [null, null, null, null, null] +21043 - null - [null, null, null, null, null] +21044 - null - [null, null, null, null, null] +21045 - null - [null, null, null, null, null] +21046 - null - [null, null, null, null, null] +21047 - null - [null, null, null, null, null] +21048 - null - [null, null, null, null, null] +21049 - null - [null, null, null, null, null] +21050 - null - [null, null, null, null, null] +21051 - null - [null, null, null, null, null] +21052 - null - [null, null, null, null, null] +21053 - null - [null, null, null, null, null] +21054 - null - [null, null, null, null, null] +21055 - Control panel - [Use, null, null, null, null] +21056 - null - [null, null, null, null, null] +21057 - null - [null, null, null, null, null] +21058 - null - [null, null, null, null, null] +21059 - null - [null, null, null, null, null] +21060 - null - [null, null, null, null, null] +21061 - null - [null, null, null, null, null] +21062 - null - [null, null, null, null, null] +21063 - null - [null, null, null, null, null] +21064 - null - [null, null, null, null, null] +21065 - Door - [Open, null, null, null, null] +21066 - Door - [null, null, null, null, null] +21067 - Door - [null, null, null, null, null] +21068 - Door - [Open, null, null, null, null] +21069 - null - [null, null, null, null, null] +21070 - null - [null, null, null, null, null] +21071 - null - [null, null, null, null, null] +21072 - null - [null, null, null, null, null] +21073 - null - [null, null, null, null, null] +21074 - null - [null, null, null, null, null] +21075 - null - [null, null, null, null, null] +21076 - null - [null, null, null, null, null] +21077 - null - [null, null, null, null, null] +21078 - null - [null, null, null, null, null] +21079 - null - [null, null, null, null, null] +21080 - null - [null, null, null, null, null] +21081 - null - [null, null, null, null, null] +21082 - null - [null, null, null, null, null] +21083 - null - [null, null, null, null, null] +21084 - null - [null, null, null, null, null] +21085 - Spinning light - [null, null, null, null, null] +21086 - Big Button - [Use, null, null, null, null] +21087 - null - [null, null, null, null, null] +21088 - null - [null, null, null, null, null] +21089 - null - [null, null, null, null, null] +21090 - null - [null, null, null, null, null] +21091 - null - [null, null, null, null, null] +21092 - Crazy penguin - [null, null, null, null, null] +21093 - Crazy penguin - [null, null, null, null, null] +21094 - Crazy penguin - [null, null, null, null, null] +21095 - Ice steps - [Climb, null, null, null, null] +21096 - null - [null, null, null, null, null] +21097 - null - [null, null, null, null, null] +21098 - null - [null, null, null, null, null] +21099 - null - [null, null, null, null, null] +21100 - null - [null, null, null, null, null] +21101 - null - [null, null, null, null, null] +21102 - null - [null, null, null, null, null] +21103 - null - [null, null, null, null, null] +21104 - null - [null, null, null, null, null] +21105 - null - [null, null, null, null, null] +21106 - Start - [null, null, null, null, null] +21107 - Sign - [null, null, null, null, null] +21108 - null - [null, null, null, null, null] +21109 - null - [null, null, null, null, null] +21110 - null - [null, null, null, null, null] +21111 - null - [null, null, null, null, null] +21112 - null - [null, null, null, null, null] +21113 - null - [null, null, null, null, null] +21114 - null - [null, null, null, null, null] +21115 - null - [null, null, null, null, null] +21116 - null - [null, null, null, null, null] +21117 - null - [null, null, null, null, null] +21118 - null - [null, null, null, null, null] +21119 - null - [null, null, null, null, null] +21120 - Stepping Stone - [Climb, null, null, null, null] +21121 - Stepping Stone - [null, null, null, null, null] +21122 - Stepping Stone - [null, null, null, null, null] +21123 - Stepping Stone - [null, null, null, null, null] +21124 - Stepping Stone - [null, null, null, null, null] +21125 - null - [null, null, null, null, null] +21126 - Stepping Stone - [Jump, null, null, null, null] +21127 - Stepping Stone - [Jump, null, null, null, null] +21128 - Stepping Stone - [Jump, null, null, null, null] +21129 - Stepping Stone - [Jump, null, null, null, null] +21130 - Stepping Stone - [Jump, null, null, null, null] +21131 - Stepping Stone - [Jump, null, null, null, null] +21132 - Stepping Stone - [Jump, null, null, null, null] +21133 - Stepping Stone - [Jump, null, null, null, null] +21134 - Icicles - [Tread-softly, null, null, null, null] +21135 - null - [null, null, null, null, null] +21136 - null - [null, null, null, null, null] +21137 - null - [null, null, null, null, null] +21138 - null - [null, null, null, null, null] +21139 - null - [null, null, null, null, null] +21140 - null - [null, null, null, null, null] +21141 - null - [null, null, null, null, null] +21142 - Snow jump - [Jump, null, null, null, null] +21143 - Snow jump - [Jump, null, null, null, null] +21144 - null - [null, null, null, null, null] +21145 - null - [null, null, null, null, null] +21146 - null - [null, null, null, null, null] +21147 - Wooden platform - [null, null, null, null, null] +21148 - Ice - [Cross, null, null, null, null] +21149 - Ice - [Cross, null, null, null, null] +21150 - Ice - [Cross, null, null, null, null] +21151 - Ice - [Cross, null, null, null, null] +21152 - Ice - [Cross, null, null, null, null] +21153 - Ice - [Cross, null, null, null, null] +21154 - Ice - [Cross, null, null, null, null] +21155 - Ice - [Cross, null, null, null, null] +21156 - Ice - [Cross, null, null, null, null] +21157 - A crack - [Use, null, null, null, null] +21158 - Avalanche - [Use, null, null, null, null] +21159 - Avalanche - [Use, null, null, null, null] +21160 - Door - [Open, null, null, null, null] +21161 - Door - [Close, null, null, null, null] +21162 - Door - [Open, null, null, null, null] +21163 - null - [null, null, null, null, null] +21164 - Door - [Open, null, null, null, null] +21165 - null - [null, null, null, null, null] +21166 - Door - [null, null, null, null, null] +21167 - Door - [Open, null, null, null, null] +21168 - null - [null, null, null, null, null] +21169 - Door - [Open, null, null, null, null] +21170 - Door - [Open, null, null, null, null] +21171 - Door - [Open, null, null, null, null] +21172 - Gate - [Open, null, null, null, null] +21173 - null - [null, null, null, null, null] +21174 - null - [null, null, null, null, null] +21175 - Boat - [Travel, null, null, null, null] +21176 - Boat - [Travel, null, null, null, null] +21177 - Boat - [Travel, null, null, null, null] +21178 - null - [null, null, null, null, null] +21179 - Firm snow patch - [Use, null, null, null, null] +21180 - Bird hide structure - [Use, null, null, null, null] +21181 - Snowy bird hide - [Use, null, null, null, null] +21182 - Destroyed bird hide - [Use, null, null, null, null] +21183 - Suspicious footprints - [null, null, null, null, null] +21184 - Suspicious footprints - [null, null, null, null, null] +21185 - Suspicious footprints - [null, null, null, null, null] +21186 - null - [null, null, null, null, null] +21187 - Chasm - [Use, null, null, null, null] +21188 - null - [null, null, null, null, null] +21189 - null - [null, null, null, null, null] +21190 - null - [null, null, null, null, null] +21191 - null - [null, null, null, null, null] +21192 - null - [null, null, null, null, null] +21193 - null - [null, null, null, null, null] +21194 - null - [null, null, null, null, null] +21195 - null - [null, null, null, null, null] +21196 - null - [null, null, null, null, null] +21197 - null - [null, null, null, null, null] +21198 - null - [null, null, null, null, null] +21199 - Snow - [null, null, null, null, null] +21200 - Snow - [null, null, null, null, null] +21201 - Door - [null, null, null, null, null] +21202 - null - [null, null, null, null, null] +21203 - null - [null, null, null, null, null] +21204 - null - [null, null, null, null, null] +21205 - null - [null, null, null, null, null] +21206 - null - [null, null, null, null, null] +21207 - null - [null, null, null, null, null] +21208 - null - [null, null, null, null, null] +21209 - null - [null, null, null, null, null] +21210 - null - [null, null, null, null, null] +21211 - null - [null, null, null, null, null] +21212 - null - [null, null, null, null, null] +21213 - null - [null, null, null, null, null] +21214 - null - [null, null, null, null, null] +21215 - null - [null, null, null, null, null] +21216 - null - [null, null, null, null, null] +21217 - null - [null, null, null, null, null] +21218 - null - [null, null, null, null, null] +21219 - null - [null, null, null, null, null] +21220 - null - [null, null, null, null, null] +21221 - null - [null, null, null, null, null] +21222 - null - [null, null, null, null, null] +21223 - null - [null, null, null, null, null] +21224 - null - [null, null, null, null, null] +21225 - null - [null, null, null, null, null] +21226 - null - [null, null, null, null, null] +21227 - null - [null, null, null, null, null] +21228 - null - [null, null, null, null, null] +21229 - null - [null, null, null, null, null] +21230 - null - [null, null, null, null, null] +21231 - null - [null, null, null, null, null] +21232 - null - [null, null, null, null, null] +21233 - null - [null, null, null, null, null] +21234 - null - [null, null, null, null, null] +21235 - null - [null, null, null, null, null] +21236 - null - [null, null, null, null, null] +21237 - null - [null, null, null, null, null] +21238 - null - [null, null, null, null, null] +21239 - null - [null, null, null, null, null] +21240 - null - [null, null, null, null, null] +21241 - null - [null, null, null, null, null] +21242 - null - [null, null, null, null, null] +21243 - Door - [Open, null, null, null, null] +21244 - null - [null, null, null, null, null] +21245 - null - [Use, null, null, null, null] +21246 - null - [Use, null, null, null, null] +21247 - null - [null, null, null, null, null] +21248 - null - [null, null, null, null, null] +21249 - null - [null, null, null, null, null] +21250 - Collector Converter - [Convert, null, null, null, null] +21251 - Rocks - [Mine, Prospect, hidden, null, null] +21252 - Rocks - [Mine, Prospect, hidden, null, null] +21253 - Rocks - [Mine, Prospect, hidden, null, null] +21254 - Rocks - [Mine, Prospect, hidden, null, null] +21255 - Rocks - [Mine, Prospect, hidden, null, null] +21256 - Rocks - [Mine, Prospect, hidden, null, null] +21257 - Rocks - [Mine, Prospect, hidden, null, null] +21258 - Rocks - [Mine, Prospect, hidden, null, null] +21259 - Rocks - [Mine, Prospect, hidden, null, null] +21260 - Rocks - [Mine, Prospect, hidden, null, null] +21261 - Rocks - [Mine, Prospect, hidden, null, null] +21262 - Rocks - [Mine, Prospect, hidden, null, null] +21263 - Rocks - [Mine, Prospect, hidden, null, null] +21264 - Rocks - [Mine, Prospect, hidden, null, null] +21265 - Rocks - [Mine, Prospect, hidden, null, null] +21266 - Rocks - [Mine, Prospect, hidden, null, null] +21267 - Rocks - [Mine, Prospect, hidden, null, null] +21268 - Rocks - [Mine, Prospect, hidden, null, null] +21269 - Rocks - [Mine, Prospect, hidden, null, null] +21270 - Rocks - [Mine, Prospect, hidden, null, null] +21271 - Funeral pyre - [null, null, null, null, null] +21272 - Funeral pyre - [Light, null, null, null, null] +21273 - Arctic Pine - [Cut down, null, hidden, null, null] +21274 - Tree Stump - [null, null, null, null, null] +21275 - Rocks - [Mine, Prospect, hidden, null, null] +21276 - Rocks - [Mine, Prospect, hidden, null, null] +21277 - Rocks - [Mine, Prospect, hidden, null, null] +21278 - Rocks - [Mine, Prospect, hidden, null, null] +21279 - Rocks - [Mine, Prospect, hidden, null, null] +21280 - Rocks - [Mine, Prospect, hidden, null, null] +21281 - Rocks - [Mine, Prospect, hidden, null, null] +21282 - Rocks - [Mine, Prospect, hidden, null, null] +21283 - Rocks - [Mine, Prospect, hidden, null, null] +21284 - Rocks - [Mine, Prospect, hidden, null, null] +21285 - Rocks - [Mine, Prospect, hidden, null, null] +21286 - Rocks - [Mine, Prospect, hidden, null, null] +21287 - Rocks - [Mine, Prospect, hidden, null, null] +21288 - Rocks - [Mine, Prospect, hidden, null, null] +21289 - Rocks - [Mine, Prospect, hidden, null, null] +21290 - Rocks - [Mine, Prospect, hidden, null, null] +21291 - Rocks - [Mine, Prospect, hidden, null, null] +21292 - Rocks - [Mine, Prospect, hidden, null, null] +21293 - Rocks - [Mine, Prospect, hidden, null, null] +21294 - Rocks - [Mine, Prospect, hidden, null, null] +21295 - Rocks - [Mine, Prospect, hidden, null, null] +21296 - Rocks - [Mine, Prospect, hidden, null, null] +21297 - Rocks - [Mine, Prospect, hidden, null, null] +21298 - Rocks - [Mine, Prospect, hidden, null, null] +21299 - Chest - [Open, null, null, null, null] +21300 - Chest - [Search, null, null, null, null] +21301 - Bank chest - [Use, null, null, null, null] +21302 - Clay oven - [null, null, null, null, null] +21303 - Clay forge - [null, Smelt-ore, null, null, null] +21304 - Spinning wheel - [Spin, null, null, null, null] +21305 - Woodcutting stump - [Cut-wood, null, null, null, null] +21306 - Rope bridge - [Walk-across, null, null, null, null] +21307 - Rope bridge - [Walk-across, null, null, null, null] +21308 - Rope bridge - [Walk-across, null, null, null, null] +21309 - Rope bridge - [Walk-across, null, null, null, null] +21310 - Rope bridge - [Walk-across, Repair, null, null, null] +21311 - Rope bridge - [Walk-across, Repair, null, null, null] +21312 - Rope bridge - [Walk-across, Repair, null, null, null] +21313 - Rope bridge - [Walk-across, Repair, null, null, null] +21314 - Rope bridge - [Cross-bridge, null, null, null, null] +21315 - Rope bridge - [Walk-across, null, null, null, null] +21316 - Rope bridge - [Walk-across, null, null, null, null] +21317 - Rope bridge - [Walk-across, null, null, null, null] +21318 - Rope bridge - [Walk-across, null, null, null, null] +21319 - Rope bridge - [Walk-across, null, null, null, null] +21320 - null - [null, null, null, null, null] +21321 - null - [null, null, null, null, null] +21322 - null - [null, null, null, null, null] +21323 - null - [null, null, null, null, null] +21324 - null - [null, null, null, null, null] +21325 - null - [null, null, null, null, null] +21326 - null - [null, null, null, null, null] +21327 - null - [null, null, null, null, null] +21328 - null - [null, null, null, null, null] +21329 - null - [null, null, null, null, null] +21330 - null - [null, null, null, null, null] +21331 - null - [null, null, null, null, null] +21332 - null - [null, null, null, null, null] +21333 - null - [null, null, null, null, null] +21334 - null - [null, null, null, null, null] +21335 - null - [null, null, null, null, null] +21336 - null - [null, null, null, null, null] +21337 - null - [null, null, null, null, null] +21338 - null - [null, null, null, null, null] +21339 - null - [null, null, null, null, null] +21340 - Door - [Open, null, null, null, null] +21341 - Door - [Open, null, null, null, null] +21342 - Door - [Close, null, null, null, null] +21343 - Door - [Close, null, null, null, null] +21344 - null - [null, null, null, null, null] +21345 - null - [null, null, null, null, null] +21346 - null - [null, null, null, null, null] +21347 - null - [null, null, null, null, null] +21348 - null - [null, null, null, null, null] +21349 - null - [null, null, null, null, null] +21350 - null - [null, null, null, null, null] +21351 - null - [null, null, null, null, null] +21352 - null - [null, null, null, null, null] +21353 - null - [null, null, null, null, null] +21354 - Chair - [null, null, null, null, null] +21355 - Large Geyser - [null, null, null, null, null] +21356 - Small Geyser - [null, null, null, null, null] +21357 - null - [null, null, null, null, null] +21358 - Bank Table - [null, null, null, null, null] +21359 - Table - [null, null, null, null, null] +21360 - Table - [null, null, null, null, null] +21361 - Smashed chair - [null, null, null, null, null] +21362 - Bed - [null, null, null, null, null] +21363 - null - [null, null, null, null, null] +21364 - null - [null, null, null, null, null] +21365 - null - [null, null, null, null, null] +21366 - null - [null, null, null, null, null] +21367 - null - [null, null, null, null, null] +21368 - null - [null, null, null, null, null] +21369 - null - [null, null, null, null, null] +21370 - null - [null, null, null, null, null] +21371 - null - [null, null, null, null, null] +21372 - null - [null, null, null, null, null] +21373 - null - [null, null, null, null, null] +21374 - null - [null, null, null, null, null] +21375 - null - [null, null, null, null, null] +21376 - null - [null, null, null, null, null] +21377 - null - [null, null, null, null, null] +21378 - null - [null, null, null, null, null] +21379 - null - [null, null, null, null, null] +21380 - null - [null, null, null, null, null] +21381 - null - [null, null, null, null, null] +21382 - null - [null, null, null, null, null] +21383 - null - [null, null, null, null, null] +21384 - null - [null, null, null, null, null] +21385 - null - [null, null, null, null, null] +21386 - null - [null, null, null, null, null] +21387 - null - [null, null, null, null, null] +21388 - Table - [null, null, null, null, null] +21389 - Table - [null, null, null, null, null] +21390 - Sacks - [null, null, null, null, null] +21391 - null - [null, null, null, null, null] +21392 - null - [null, null, null, null, null] +21393 - Throne - [null, null, null, null, null] +21394 - Bell - [Ring-bell, null, null, null, null] +21395 - Ladder - [Climb-up, null, null, null, null] +21396 - Ladder - [Climb-down, null, null, null, null] +21397 - Large door - [Open, null, null, null, null] +21398 - Large door - [Close, null, null, null, null] +21399 - Large door - [Open, null, null, null, null] +21400 - Large door - [Open, null, null, null, null] +21401 - Large door - [Close, null, null, null, null] +21402 - Large door - [Close, null, null, null, null] +21403 - Gate - [Open, null, null, null, null] +21404 - Gate - [Close, null, null, null, null] +21405 - Gate - [Open, null, null, null, null] +21406 - Gate - [Close, null, null, null, null] +21407 - null - [null, null, null, null, null] +21408 - null - [null, null, null, null, null] +21409 - null - [null, null, null, null, null] +21410 - null - [null, null, null, null, null] +21411 - null - [null, null, null, null, null] +21412 - null - [null, null, null, null, null] +21413 - null - [null, null, null, null, null] +21414 - null - [null, null, null, null, null] +21415 - null - [null, null, null, null, null] +21416 - null - [null, null, null, null, null] +21417 - null - [null, null, null, null, null] +21418 - null - [null, null, null, null, null] +21419 - null - [null, null, null, null, null] +21420 - null - [null, null, null, null, null] +21421 - null - [null, null, null, null, null] +21422 - null - [null, null, null, null, null] +21423 - null - [null, null, null, null, null] +21424 - null - [null, null, null, null, null] +21425 - null - [null, null, null, null, null] +21426 - null - [null, null, null, null, null] +21427 - null - [null, null, null, null, null] +21428 - null - [null, null, null, null, null] +21429 - null - [null, null, null, null, null] +21430 - null - [null, null, null, null, null] +21431 - null - [null, null, null, null, null] +21432 - null - [null, null, null, null, null] +21433 - null - [null, null, null, null, null] +21434 - null - [null, null, null, null, null] +21435 - null - [null, null, null, null, null] +21436 - null - [null, null, null, null, null] +21437 - Axe case - [null, null, null, null, null] +21438 - Sword case - [null, null, null, null, null] +21439 - Swords - [null, null, null, null, null] +21440 - null - [null, null, null, null, null] +21441 - Chopping table - [null, null, null, null, null] +21442 - Ore crate - [null, null, null, null, null] +21443 - Ore table - [null, null, null, null, null] +21444 - Ore stones - [null, null, null, null, null] +21445 - Shield display - [null, null, null, null, null] +21446 - Shield display - [null, null, null, null, null] +21447 - Armour display - [null, null, null, null, null] +21448 - null - [null, null, null, null, null] +21449 - null - [null, null, null, null, null] +21450 - null - [null, null, null, null, null] +21451 - null - [null, null, null, null, null] +21452 - null - [null, null, null, null, null] +21453 - null - [null, null, null, null, null] +21454 - null - [null, null, null, null, null] +21455 - Staircase - [Climb-Down, null, null, null, null] +21456 - null - [null, null, null, null, null] +21457 - null - [null, null, null, null, null] +21458 - null - [null, null, null, null, null] +21459 - Arch - [null, null, null, null, null] +21460 - Arch - [null, null, null, null, null] +21461 - Arch - [null, null, null, null, null] +21462 - null - [null, null, null, null, null] +21463 - null - [null, null, null, null, null] +21464 - Throne - [null, null, null, null, null] +21465 - Torch - [null, null, null, null, null] +21466 - null - [null, null, null, null, null] +21467 - null - [null, null, null, null, null] +21468 - null - [null, null, null, null, null] +21469 - null - [null, null, null, null, null] +21470 - null - [null, null, null, null, null] +21471 - null - [null, null, null, null, null] +21472 - null - [null, null, null, null, null] +21473 - null - [null, null, null, null, null] +21474 - null - [null, null, null, null, null] +21475 - null - [null, null, null, null, null] +21476 - null - [null, null, null, null, null] +21477 - null - [null, null, null, null, null] +21478 - null - [null, null, null, null, null] +21479 - null - [null, null, null, null, null] +21480 - null - [null, null, null, null, null] +21481 - null - [null, null, null, null, null] +21482 - null - [null, null, null, null, null] +21483 - null - [null, null, null, null, null] +21484 - null - [null, null, null, null, null] +21485 - null - [null, null, null, null, null] +21486 - null - [null, null, null, null, null] +21487 - null - [null, null, null, null, null] +21488 - null - [null, null, null, null, null] +21489 - null - [null, null, null, null, null] +21490 - null - [null, null, null, null, null] +21491 - null - [null, null, null, null, null] +21492 - null - [null, null, null, null, null] +21493 - null - [null, null, null, null, null] +21494 - null - [null, null, null, null, null] +21495 - null - [null, null, null, null, null] +21496 - null - [null, null, null, null, null] +21497 - null - [null, null, null, null, null] +21498 - null - [null, null, null, null, null] +21499 - null - [null, null, null, null, null] +21500 - Banner - [null, null, null, null, null] +21501 - Banner - [null, null, null, null, null] +21502 - null - [null, hidden, null, null, null] +21503 - null - [null, null, null, null, null] +21504 - null - [null, null, null, null, null] +21505 - Door - [Open, null, null, null, null] +21506 - Door - [Close, null, null, null, null] +21507 - Door - [Open, null, null, null, null] +21508 - Door - [Close, null, null, null, null] +21509 - Rope bridge - [null, null, null, null, null] +21510 - Broken rope bridge - [null, null, null, null, null] +21511 - null - [Climb-up, null, null, null, null] +21512 - Ladder - [Climb-up, null, null, null, null] +21513 - Ladder - [Climb-down, null, null, null, null] +21514 - Ladder - [Climb-up, null, null, null, null] +21515 - Ladder - [Climb-down, null, null, null, null] +21516 - null - [null, null, null, null, null] +21517 - null - [null, null, null, null, null] +21518 - null - [null, null, null, null, null] +21519 - null - [null, null, null, null, null] +21520 - null - [null, null, null, null, null] +21521 - null - [null, null, null, null, null] +21522 - null - [null, null, null, null, null] +21523 - null - [null, null, null, null, null] +21524 - null - [null, null, null, null, null] +21525 - null - [null, null, null, null, null] +21526 - null - [null, null, null, null, null] +21527 - null - [null, null, null, null, null] +21528 - null - [null, null, null, null, null] +21529 - Rift - [null, null, null, null, null] +21530 - Rift - [null, null, null, null, null] +21531 - Rift - [null, null, null, null, null] +21532 - Rift - [null, null, null, null, null] +21533 - Rift - [null, null, null, null, null] +21534 - Rift - [null, null, null, null, null] +21535 - Rift - [null, null, null, null, null] +21536 - Rift - [null, null, null, null, null] +21537 - Rift - [null, null, null, null, null] +21538 - Rift - [null, null, null, null, null] +21539 - Rift - [null, null, null, null, null] +21540 - null - [null, null, null, null, null] +21541 - null - [null, null, null, null, null] +21542 - null - [null, null, null, null, null] +21543 - null - [null, null, null, null, null] +21544 - null - [null, null, null, null, null] +21545 - Vault - [null, null, null, null, null] +21546 - Pillar - [null, null, null, null, null] +21547 - Pillar - [null, null, null, null, null] +21548 - Pillar - [null, null, null, null, null] +21549 - null - [null, null, null, null, null] +21550 - Banana Tree - [Search, null, null, null, null] +21551 - null - [null, null, null, null, null] +21552 - null - [null, null, null, null, null] +21553 - null - [null, null, null, null, null] +21554 - null - [null, null, null, null, null] +21555 - null - [null, null, null, null, null] +21556 - null - [null, null, null, null, null] +21557 - null - [null, null, null, null, null] +21558 - null - [null, null, null, null, null] +21559 - null - [null, null, null, null, null] +21560 - Exit cavern - [Exit-cave, null, null, null, null] +21561 - null - [null, null, null, null, null] +21562 - null - [null, null, null, null, null] +21563 - null - [null, null, null, null, null] +21564 - null - [null, null, null, null, null] +21565 - null - [null, null, null, null, null] +21566 - null - [null, null, null, null, null] +21567 - null - [null, null, null, null, null] +21568 - null - [null, null, null, null, null] +21569 - Mushrooms - [null, null, null, null, null] +21570 - Mushrooms - [null, null, null, null, null] +21571 - Rock - [null, null, null, null, null] +21572 - Small rock - [null, null, null, null, null] +21573 - Rock - [null, null, null, null, null] +21574 - Boulders - [null, null, null, null, null] +21575 - Boulders - [null, null, null, null, null] +21576 - null - [null, null, null, null, null] +21577 - null - [null, null, null, null, null] +21578 - Staircase - [Climb-up, null, null, null, null] +21579 - null - [null, null, null, null, null] +21580 - Cave - [null, null, null, null, null] +21581 - Cave - [Open, null, null, null, null] +21582 - Cave - [null, null, null, null, null] +21583 - Cave - [Open, null, null, null, null] +21584 - Cave - [Open, null, null, null, null] +21585 - Cave - [Open, null, null, null, null] +21586 - Cave - [Open, null, null, null, null] +21587 - Cave - [Close, null, null, null, null] +21588 - Cave - [Close, null, null, null, null] +21589 - Cave - [Close, null, null, null, null] +21590 - Cave - [Close, null, null, null, null] +21591 - Stone ladder - [null, null, null, null, null] +21592 - Stone ladder - [Climb-up, null, null, null, null] +21593 - Stone ladder - [Climb-down, null, null, null, null] +21594 - Cave opening - [Exit, null, null, null, null] +21595 - Cave opening - [Exit, null, null, null, null] +21596 - Cave opening - [Exit, null, null, null, null] +21597 - Cave opening - [Exit, null, null, null, null] +21598 - Cave opening - [Exit, null, null, null, null] +21599 - Cave opening - [Exit, null, null, null, null] +21600 - Gate - [Open, null, null, null, null] +21601 - Gate - [Close, null, null, null, null] +21602 - null - [null, null, null, null, null] +21603 - Broken barrel - [null, null, null, null, null] +21604 - null - [null, null, null, null, null] +21605 - null - [null, null, null, null, null] +21606 - null - [null, null, null, null, null] +21607 - Chair - [null, null, null, null, null] +21608 - Table - [null, null, null, null, null] +21609 - Table - [null, null, null, null, null] +21610 - Table - [null, null, null, null, null] +21611 - Bed - [null, null, null, null, null] +21612 - Crate - [null, null, null, null, null] +21613 - null - [null, null, null, null, null] +21614 - Shelf - [null, null, null, null, null] +21615 - Shelf - [null, null, null, null, null] +21616 - null - [null, null, null, null, null] +21617 - null - [null, null, null, null, null] +21618 - null - [null, null, null, null, null] +21619 - null - [null, null, null, null, null] +21620 - Fire - [null, null, null, null, null] +21621 - null - [null, null, null, null, null] +21622 - Ice Troll King - [Decapitate, null, null, null, null] +21623 - Ice Troll King - [null, null, null, null, null] +21624 - null - [null, null, null, null, null] +21625 - null - [null, null, null, null, null] +21626 - null - [null, null, null, null, null] +21627 - null - [null, null, null, null, null] +21628 - null - [null, null, null, null, null] +21629 - null - [null, null, null, null, null] +21630 - null - [null, null, null, null, null] +21631 - null - [null, null, null, null, null] +21632 - null - [null, null, null, null, null] +21633 - null - [null, null, null, null, null] +21634 - Fremennik boat - [null, null, null, null, null] +21635 - Standard - [null, null, null, null, null] +21636 - Standard - [null, null, null, null, null] +21637 - Standard - [null, null, null, null, null] +21638 - null - [null, null, null, null, null] +21639 - null - [null, null, null, null, null] +21640 - null - [null, null, null, null, null] +21641 - null - [null, null, null, null, null] +21642 - null - [null, null, null, null, null] +21643 - null - [null, null, null, null, null] +21644 - null - [null, null, null, null, null] +21645 - null - [null, null, null, null, null] +21646 - null - [null, null, null, null, null] +21647 - null - [null, null, null, null, null] +21648 - null - [null, null, null, null, null] +21649 - null - [null, null, null, null, null] +21650 - null - [null, null, null, null, null] +21651 - null - [null, null, null, null, null] +21652 - null - [null, null, null, null, null] +21653 - null - [null, null, null, null, null] +21654 - null - [null, null, null, null, null] +21655 - null - [null, null, null, null, null] +21656 - null - [null, null, null, null, null] +21657 - null - [null, null, null, null, null] +21658 - null - [null, null, null, null, null] +21659 - null - [null, null, null, null, null] +21660 - null - [null, null, null, null, null] +21661 - null - [null, null, null, null, null] +21662 - null - [null, null, null, null, null] +21663 - null - [null, null, null, null, null] +21664 - null - [null, null, null, null, null] +21665 - null - [null, null, null, null, null] +21666 - null - [null, null, null, null, null] +21667 - Torch - [null, null, null, null, null] +21668 - Herbs - [Pick, null, null, null, null] +21669 - Herbs - [Pick, null, null, null, null] +21670 - Herbs - [Pick, null, null, null, null] +21671 - Herbs - [Pick, null, null, null, null] +21672 - Gate - [Open, null, null, null, null] +21673 - Gate - [Open, null, null, null, null] +21674 - Gate - [Open, null, null, null, null] +21675 - Gate - [Open, null, null, null, null] +21676 - null - [null, null, null, null, null] +21677 - null - [null, null, null, null, null] +21678 - null - [null, null, null, null, null] +21679 - null - [null, null, null, null, null] +21680 - null - [null, null, null, null, null] +21681 - null - [null, null, null, null, null] +21682 - null - [null, null, null, null, null] +21683 - null - [null, null, null, null, null] +21684 - null - [null, null, null, null, null] +21685 - null - [null, null, null, null, null] +21686 - null - [null, null, null, null, null] +21687 - Gate - [Open, null, null, null, null] +21688 - null - [null, null, null, null, null] +21689 - null - [null, null, null, null, null] +21690 - null - [null, null, null, null, null] +21691 - null - [null, null, null, null, null] +21692 - null - [null, null, null, null, null] +21693 - null - [null, null, null, null, null] +21694 - null - [null, null, null, null, null] +21695 - null - [null, null, null, null, null] +21696 - null - [null, null, null, null, null] +21697 - null - [null, null, null, null, null] +21698 - null - [null, null, null, null, null] +21699 - null - [null, null, null, null, null] +21700 - null - [null, null, null, null, null] +21701 - null - [null, null, null, null, null] +21702 - null - [null, null, null, null, null] +21703 - null - [null, null, null, null, null] +21704 - null - [null, null, null, null, null] +21705 - null - [null, null, null, null, null] +21706 - null - [null, null, null, null, null] +21707 - null - [null, null, null, null, null] +21708 - null - [null, null, null, null, null] +21709 - Gate - [Open, null, null, null, null] +21710 - null - [null, null, null, null, null] +21711 - null - [null, null, null, null, null] +21712 - null - [null, null, null, null, null] +21713 - null - [null, null, null, null, null] +21714 - null - [null, null, null, null, null] +21715 - null - [null, null, null, null, null] +21716 - null - [null, null, null, null, null] +21717 - null - [null, null, null, null, null] +21718 - null - [null, null, null, null, null] +21719 - null - [null, null, null, null, null] +21720 - null - [null, null, null, null, null] +21721 - null - [null, null, null, null, null] +21722 - null - [null, null, null, null, null] +21723 - null - [null, null, null, null, null] +21724 - null - [null, null, null, null, null] +21725 - null - [null, null, null, null, null] +21726 - null - [null, null, null, null, null] +21727 - null - [null, null, null, null, null] +21728 - null - [null, null, null, null, null] +21729 - null - [null, null, null, null, null] +21730 - null - [null, null, null, null, null] +21731 - Gate - [Open, null, null, null, null] +21732 - null - [null, null, null, null, null] +21733 - null - [null, null, null, null, null] +21734 - null - [null, null, null, null, null] +21735 - null - [null, null, null, null, null] +21736 - null - [null, null, null, null, null] +21737 - null - [null, null, null, null, null] +21738 - null - [null, null, null, null, null] +21739 - null - [null, null, null, null, null] +21740 - null - [null, null, null, null, null] +21741 - null - [null, null, null, null, null] +21742 - null - [null, null, null, null, null] +21743 - null - [null, null, null, null, null] +21744 - null - [null, null, null, null, null] +21745 - null - [null, null, null, null, null] +21746 - null - [null, null, null, null, null] +21747 - null - [null, null, null, null, null] +21748 - null - [null, null, null, null, null] +21749 - null - [null, null, null, null, null] +21750 - null - [null, null, null, null, null] +21751 - null - [null, null, null, null, null] +21752 - null - [null, null, null, null, null] +21753 - Gate - [Open, null, null, null, null] +21754 - null - [null, null, null, null, null] +21755 - null - [null, null, null, null, null] +21756 - null - [null, null, null, null, null] +21757 - null - [null, null, null, null, null] +21758 - null - [null, null, null, null, null] +21759 - null - [null, null, null, null, null] +21760 - null - [null, null, null, null, null] +21761 - null - [null, null, null, null, null] +21762 - null - [null, null, null, null, null] +21763 - null - [null, null, null, null, null] +21764 - Fountain - [Drink-from, null, null, null, null] +21765 - null - [null, null, null, null, null] +21766 - Sq'irk tree - [Pick-Fruit, null, null, null, null] +21767 - Sq'irk tree - [Pick-Fruit, null, null, null, null] +21768 - Sq'irk tree - [Pick-Fruit, null, null, null, null] +21769 - Sq'irk tree - [Pick-Fruit, null, null, null, null] +21770 - null - [null, null, null, null, null] +21771 - null - [null, null, null, null, null] +21772 - null - [null, null, null, null, null] +21773 - null - [null, null, null, null, null] +21774 - null - [null, null, null, null, null] +21775 - null - [null, null, null, null, null] +21776 - null - [null, null, null, null, null] +21777 - null - [null, null, null, null, null] +21778 - null - [null, null, null, null, null] +21779 - null - [null, null, null, null, null] +21780 - null - [null, null, null, null, null] +21781 - Ladder - [Climb-up, null, null, null, null] +21782 - Ladder - [Climb-down, null, null, null, null] +21783 - null - [null, null, null, null, null] +21784 - null - [null, null, null, null, null] +21785 - null - [null, null, null, null, null] +21786 - null - [null, null, null, null, null] +21787 - null - [null, null, null, null, null] +21788 - null - [null, null, null, null, null] +21789 - null - [null, null, null, null, null] +21790 - null - [null, null, null, null, null] +21791 - null - [null, null, null, null, null] +21792 - Range - [null, null, null, null, null] +21793 - Table - [null, null, null, null, null] +21794 - Shelves - [Search, null, null, null, null] +21795 - Fireplace - [null, null, null, null, null] +21796 - null - [null, null, null, null, null] +21797 - null - [null, null, null, null, null] +21798 - null - [null, null, null, null, null] +21799 - null - [null, null, null, null, null] +21800 - Crack - [Enter, null, null, null, null] +21801 - null - [null, null, null, null, null] +21802 - Corpse - [null, null, null, null, null] +21803 - Corpse - [null, null, null, null, null] +21804 - null - [null, null, null, null, null] +21805 - null - [null, null, null, null, null] +21806 - null - [null, null, null, null, null] +21807 - null - [null, null, null, null, null] +21808 - null - [null, null, null, null, null] +21809 - null - [null, null, null, null, null] +21810 - null - [null, null, null, null, null] +21811 - null - [null, null, null, null, null] +21812 - null - [null, null, null, null, null] +21813 - null - [null, null, null, null, null] +21814 - Tower door - [Open, null, null, null, null] +21815 - null - [null, null, null, null, null] +21816 - null - [null, null, null, null, null] +21817 - null - [null, null, null, null, null] +21818 - null - [null, null, null, null, null] +21819 - null - [null, null, null, null, null] +21820 - null - [null, null, null, null, null] +21821 - null - [null, null, null, null, null] +21822 - null - [null, null, null, null, null] +21823 - null - [null, null, null, null, null] +21824 - null - [null, null, null, null, null] +21825 - null - [null, null, null, null, null] +21826 - null - [null, null, null, null, null] +21827 - null - [null, null, null, null, null] +21828 - null - [null, null, null, null, null] +21829 - null - [null, null, null, null, null] +21830 - null - [null, null, null, null, null] +21831 - null - [null, null, null, null, null] +21832 - null - [null, null, null, null, null] +21833 - null - [null, null, null, null, null] +21834 - null - [null, null, null, null, null] +21835 - null - [null, null, null, null, null] +21836 - null - [null, null, null, null, null] +21837 - null - [null, null, null, null, null] +21838 - null - [null, null, null, null, null] +21839 - null - [null, null, null, null, null] +21840 - null - [null, null, null, null, null] +21841 - null - [null, null, null, null, null] +21842 - null - [null, null, null, null, null] +21843 - null - [null, null, null, null, null] +21844 - Water pipes - [null, null, null, null, null] +21845 - Water pipes - [null, null, null, null, null] +21846 - Water pipes - [null, null, null, null, null] +21847 - Water pipes - [null, null, null, null, null] +21848 - Water pipes - [null, null, null, null, null] +21849 - Barricade - [null, null, null, null, null] +21850 - null - [null, null, null, null, null] +21851 - null - [null, null, null, null, null] +21852 - null - [null, null, null, null, null] +21853 - null - [null, null, null, null, null] +21854 - null - [null, null, null, null, null] +21855 - null - [null, null, null, null, null] +21856 - null - [null, null, null, null, null] +21857 - null - [null, null, null, null, null] +21858 - null - [null, null, null, null, null] +21859 - null - [null, null, null, null, null] +21860 - null - [null, null, null, null, null] +21861 - null - [null, null, null, null, null] +21862 - null - [null, null, null, null, null] +21863 - null - [null, null, null, null, null] +21864 - null - [null, null, null, null, null] +21865 - null - [null, null, null, null, null] +21866 - null - [null, null, null, null, null] +21867 - null - [null, null, null, null, null] +21868 - Rift - [null, null, null, null, null] +21869 - Cage - [null, null, null, null, null] +21870 - Cage - [Fix, null, null, null, null] +21871 - Stairs - [Climb-up, null, null, null, null] +21872 - Stairs - [Climb-down, null, null, null, null] +21873 - Pressure machine - [Fix, null, null, null, null] +21874 - Huge vat - [null, null, null, null, null] +21875 - Pipe - [null, null, null, null, null] +21876 - Pipe - [null, null, null, null, null] +21877 - Pipe - [null, null, null, null, null] +21878 - Pipe - [null, null, null, null, null] +21879 - Furnace - [null, null, null, null, null] +21880 - Pipe machine - [Fix, null, null, null, null] +21881 - Pipe machine - [null, null, null, null, null] +21882 - Pipe - [null, null, null, null, null] +21883 - Pipe - [null, null, null, null, null] +21884 - null - [null, null, null, null, null] +21885 - null - [null, null, null, null, null] +21886 - null - [null, null, null, null, null] +21887 - null - [null, null, null, null, null] +21888 - null - [null, null, null, null, null] +21889 - null - [null, null, null, null, null] +21890 - Support - [null, null, null, null, null] +21891 - null - [null, null, null, null, null] +21892 - null - [null, null, null, null, null] +21893 - Symbol of life - [Inspect, Activate, null, null, null] +21894 - Symbol of life - [Inspect, Activate, null, null, null] +21895 - null - [null, null, null, null, null] +21896 - null - [null, null, null, null, null] +21897 - null - [null, null, null, null, null] +21898 - null - [null, null, null, null, null] +21899 - null - [null, null, null, null, null] +21900 - null - [null, null, null, null, null] +21901 - Tube - [null, null, null, null, null] +21902 - Magic well - [null, null, null, null, null] +21903 - Magic well - [null, null, null, null, null] +21904 - Magic well - [null, null, null, null, null] +21905 - Pipe - [null, null, null, null, null] +21906 - Operation table - [null, null, null, null, null] +21907 - Operation chair - [null, null, null, null, null] +21908 - Crate - [Search, null, null, null, null] +21909 - Crate - [Search, null, null, null, null] +21910 - Crate - [Search, null, null, null, null] +21911 - Crate - [Search, null, null, null, null] +21912 - Crate - [Search, null, null, null, null] +21913 - Crate - [Search, null, null, null, null] +21914 - Crate - [Search, null, null, null, null] +21915 - Crate - [Search, null, null, null, null] +21916 - Crate - [Search, null, null, null, null] +21917 - Crate - [Search, null, null, null, null] +21918 - Magic table - [null, null, null, null, null] +21919 - null - [null, null, null, null, null] +21920 - Spinning pipe - [null, null, null, null, null] +21921 - Trapdoor - [Open, null, null, null, null] +21922 - Trapdoor - [Climb-down, Close, null, null, null] +21923 - Specimen - [null, null, null, null, null] +21924 - Plant - [Search, null, null, null, null] +21925 - Pipe - [null, null, null, null, null] +21926 - Pipe - [null, null, null, null, null] +21927 - null - [null, null, null, null, null] +21928 - null - [null, null, null, null, null] +21929 - Tower door - [Enter, null, null, null, null] +21930 - Cage - [null, null, null, null, null] +21931 - Cage - [null, null, null, null, null] +21932 - Shackle table - [null, null, null, null, null] +21933 - Retorts - [null, null, null, null, null] +21934 - Experiment table - [null, null, null, null, null] +21935 - Experiment table - [null, null, null, null, null] +21936 - Experiment table - [null, null, null, null, null] +21937 - Experiment cabinet - [null, null, null, null, null] +21938 - Crate - [null, null, null, null, null] +21939 - Crate - [null, null, null, null, null] +21940 - Crate - [null, null, null, null, null] +21941 - null - [null, null, null, null, null] +21942 - null - [null, null, null, null, null] +21943 - null - [null, null, null, null, null] +21944 - null - [null, null, null, null, null] +21945 - Lighting mechanism - [null, null, null, null, null] +21946 - Staircase - [Climb-up, null, null, null, null] +21947 - Staircase - [Climb-down, null, null, null, null] +21948 - null - [null, null, null, null, null] +21949 - null - [null, null, null, null, null] +21950 - null - [null, null, null, null, null] +21951 - null - [null, null, null, null, null] +21952 - null - [null, null, null, null, null] +21953 - null - [null, null, null, null, null] +21954 - null - [null, null, null, null, null] +21955 - null - [null, null, null, null, null] +21956 - null - [null, null, null, null, null] +21957 - null - [null, null, null, null, null] +21958 - null - [null, null, null, null, null] +21959 - null - [null, null, null, null, null] +21960 - null - [null, null, null, null, null] +21961 - null - [null, null, null, null, null] +21962 - null - [null, null, null, null, null] +21963 - null - [null, null, null, null, null] +21964 - null - [null, null, null, null, null] +21965 - null - [null, null, null, null, null] +21966 - null - [null, null, null, null, null] +21967 - null - [null, null, null, null, null] +21968 - null - [null, null, null, null, null] +21969 - null - [null, null, null, null, null] +21970 - null - [null, null, null, null, null] +21971 - null - [null, null, null, null, null] +21972 - null - [null, null, null, null, null] +21973 - null - [null, null, null, null, null] +21974 - null - [null, null, null, null, null] +21975 - null - [null, null, null, null, null] +21976 - null - [null, null, null, null, null] +21977 - null - [null, null, null, null, null] +21978 - null - [null, null, null, null, null] +21979 - null - [null, null, null, null, null] +21980 - null - [null, null, null, null, null] +21981 - null - [null, null, null, null, null] +21982 - null - [null, null, null, null, null] +21983 - null - [null, null, null, null, null] +21984 - null - [null, null, null, null, null] +21985 - null - [null, null, null, null, null] +21986 - null - [null, null, null, null, null] +21987 - null - [null, null, null, null, null] +21988 - null - [null, null, null, null, null] +21989 - null - [null, null, null, null, null] +21990 - null - [null, null, null, null, null] +21991 - null - [null, null, null, null, null] +21992 - null - [null, null, null, null, null] +21993 - null - [null, null, null, null, null] +21994 - null - [null, null, null, null, null] +21995 - null - [null, null, null, null, null] +21996 - null - [null, null, null, null, null] +21997 - null - [null, null, null, null, null] +21998 - null - [null, null, null, null, null] +21999 - null - [null, null, null, null, null] +22000 - null - [null, null, null, null, null] +22001 - null - [null, null, null, null, null] +22002 - null - [null, null, null, null, null] +22003 - null - [null, null, null, null, null] +22004 - null - [null, null, null, null, null] +22005 - null - [null, null, null, null, null] +22006 - null - [null, null, null, null, null] +22007 - Door - [Open, null, null, null, null] +22008 - null - [null, null, null, null, null] +22009 - null - [null, null, null, null, null] +22010 - null - [null, null, null, null, null] +22011 - null - [null, null, null, null, null] +22012 - null - [null, null, null, null, null] +22013 - null - [null, null, null, null, null] +22014 - null - [null, null, null, null, null] +22015 - null - [null, null, null, null, null] +22016 - null - [null, null, null, null, null] +22017 - null - [null, null, null, null, null] +22018 - null - [null, null, null, null, null] +22019 - null - [null, null, null, null, null] +22020 - null - [null, null, null, null, null] +22021 - null - [null, null, null, null, null] +22022 - null - [null, null, null, null, null] +22023 - null - [null, null, null, null, null] +22024 - null - [null, null, null, null, null] +22025 - null - [null, null, null, null, null] +22026 - null - [null, null, null, null, null] +22027 - null - [null, null, null, null, null] +22028 - null - [null, null, null, null, null] +22029 - null - [null, null, null, null, null] +22030 - null - [null, null, null, null, null] +22031 - null - [null, null, null, null, null] +22032 - null - [null, null, null, null, null] +22033 - null - [null, null, null, null, null] +22034 - null - [null, null, null, null, null] +22035 - null - [null, null, null, null, null] +22036 - null - [null, null, null, null, null] +22037 - null - [null, null, null, null, null] +22038 - null - [null, null, null, null, null] +22039 - null - [null, null, null, null, null] +22040 - null - [null, null, null, null, null] +22041 - null - [null, null, null, null, null] +22042 - null - [null, null, null, null, null] +22043 - null - [null, null, null, null, null] +22044 - null - [null, null, null, null, null] +22045 - null - [null, null, null, null, null] +22046 - null - [null, null, null, null, null] +22047 - null - [null, null, null, null, null] +22048 - null - [null, null, null, null, null] +22049 - null - [null, null, null, null, null] +22050 - null - [null, null, null, null, null] +22051 - null - [null, null, null, null, null] +22052 - null - [null, null, null, null, null] +22053 - null - [null, null, null, null, null] +22054 - null - [null, null, null, null, null] +22055 - null - [null, null, null, null, null] +22056 - null - [null, null, null, null, null] +22057 - null - [null, null, null, null, null] +22058 - null - [null, null, null, null, null] +22059 - null - [null, null, null, null, null] +22060 - null - [null, null, null, null, null] +22061 - null - [null, null, null, null, null] +22062 - null - [null, null, null, null, null] +22063 - null - [null, null, null, null, null] +22064 - null - [null, null, null, null, null] +22065 - null - [null, null, null, null, null] +22066 - null - [null, null, null, null, null] +22067 - null - [null, null, null, null, null] +22068 - null - [null, null, null, null, null] +22069 - null - [null, null, null, null, null] +22070 - null - [null, null, null, null, null] +22071 - null - [null, null, null, null, null] +22072 - null - [null, null, null, null, null] +22073 - null - [null, null, null, null, null] +22074 - null - [null, null, null, null, null] +22075 - null - [null, null, null, null, null] +22076 - null - [null, null, null, null, null] +22077 - null - [null, null, null, null, null] +22078 - null - [null, null, null, null, null] +22079 - null - [null, null, null, null, null] +22080 - null - [null, null, null, null, null] +22081 - null - [null, null, null, null, null] +22082 - null - [null, null, null, null, null] +22083 - null - [null, null, null, null, null] +22084 - null - [null, null, null, null, null] +22085 - null - [null, null, null, null, null] +22086 - null - [null, null, null, null, null] +22087 - null - [null, null, null, null, null] +22088 - null - [null, null, null, null, null] +22089 - null - [null, null, null, null, null] +22090 - null - [null, null, null, null, null] +22091 - Wall - [null, null, null, null, null] +22092 - Wall - [null, null, null, null, null] +22093 - Wall - [null, null, null, null, null] +22094 - Wall - [null, null, null, null, null] +22095 - Wall - [null, null, null, null, null] +22096 - Wall - [null, null, null, null, null] +22097 - Peephole - [Peer-through, null, null, null, null] +22098 - Rubble - [null, null, null, null, null] +22099 - Rubble - [null, null, null, null, null] +22100 - null - [null, null, null, null, null] +22101 - null - [null, null, null, null, null] +22102 - null - [null, null, null, null, null] +22103 - null - [null, null, null, null, null] +22104 - null - [null, null, null, null, null] +22105 - Wall - [null, null, null, null, null] +22106 - Wall - [null, null, null, null, null] +22107 - Wall - [null, null, null, null, null] +22108 - Wall - [null, null, null, null, null] +22109 - Collapsed wall - [null, null, null, null, null] +22110 - Collapsed wall - [null, null, null, null, null] +22111 - null - [null, null, null, null, null] +22112 - null - [null, null, null, null, null] +22113 - Door - [Open, null, null, null, null] +22114 - Door - [Open, null, null, null, null] +22115 - Door - [Open, null, null, null, null] +22116 - Door - [Open, null, null, null, null] +22117 - Door - [Open, null, null, null, null] +22118 - Door - [Open, null, null, null, null] +22119 - null - [Open, null, null, null, null] +22120 - Bench - [null, null, null, null, null] +22121 - Ladder - [Climb-up, null, null, null, null] +22122 - Ladder - [Climb-down, null, null, null, null] +22123 - Stand - [null, null, null, null, null] +22124 - Stand - [null, null, null, null, null] +22125 - Candle stand - [null, null, null, null, null] +22126 - Bookcase - [null, null, null, null, null] +22127 - Bookcase - [null, null, null, null, null] +22128 - Bookcase - [null, null, null, null, null] +22129 - Bookcase - [null, null, null, null, null] +22130 - null - [null, null, null, null, null] +22131 - Bookcase - [null, null, null, null, null] +22132 - Bed - [null, null, null, null, null] +22133 - Bed - [null, null, null, null, null] +22134 - Drawers - [null, null, null, null, null] +22135 - Drawers - [null, null, null, null, null] +22136 - Drawers - [null, null, null, null, null] +22137 - Drawers - [null, null, null, null, null] +22138 - Drawers - [null, null, null, null, null] +22139 - Drawers - [null, null, null, null, null] +22140 - Drawers - [null, null, null, null, null] +22141 - Drawers - [null, null, null, null, null] +22142 - Drawers - [null, null, null, null, null] +22143 - Drawers - [null, null, null, null, null] +22144 - Wardrobe - [null, null, null, null, null] +22145 - Wardrobe - [null, null, null, null, null] +22146 - Wardrobe - [null, null, null, null, null] +22147 - Wardrobe - [null, null, null, null, null] +22148 - Wardrobe - [null, null, null, null, null] +22149 - Wardrobe - [null, null, null, null, null] +22150 - Wardrobe - [null, null, null, null, null] +22151 - Wardrobe - [null, null, null, null, null] +22152 - Wardrobe - [null, null, null, null, null] +22153 - Wardrobe - [null, null, null, null, null] +22154 - Cooking range - [null, null, null, null, null] +22155 - Clock - [null, null, null, null, null] +22156 - Chair - [null, null, null, null, null] +22157 - Chair - [null, null, null, null, null] +22158 - Bench - [null, null, null, null, null] +22159 - Table - [null, null, null, null, null] +22160 - Table - [null, null, null, null, null] +22161 - Potted plant - [null, null, null, null, null] +22162 - Larder - [null, null, null, null, null] +22163 - null - [null, null, null, null, null] +22164 - Ladder - [Climb-down, null, null, null, null] +22165 - null - [null, null, null, null, null] +22166 - null - [null, null, null, null, null] +22167 - null - [null, null, null, null, null] +22168 - null - [null, null, null, null, null] +22169 - null - [null, null, null, null, null] +22170 - null - [null, null, null, null, null] +22171 - null - [null, null, null, null, null] +22172 - Ladder - [Climb-up, null, null, null, null] +22173 - Ladder - [Climb-down, null, null, null, null] +22174 - null - [null, null, null, null, null] +22175 - null - [null, null, null, null, null] +22176 - null - [null, null, null, null, null] +22177 - null - [null, null, null, null, null] +22178 - null - [null, null, null, null, null] +22179 - null - [null, null, null, null, null] +22180 - null - [null, null, null, null, null] +22181 - null - [null, null, null, null, null] +22182 - null - [null, null, null, null, null] +22183 - null - [null, null, null, null, null] +22184 - null - [null, null, null, null, null] +22185 - null - [null, null, null, null, null] +22186 - null - [null, null, null, null, null] +22187 - null - [null, null, null, null, null] +22188 - null - [null, null, null, null, null] +22189 - null - [null, null, null, null, null] +22190 - null - [null, null, null, null, null] +22191 - null - [null, null, null, null, null] +22192 - null - [null, null, null, null, null] +22193 - null - [null, null, null, null, null] +22194 - null - [null, null, null, null, null] +22195 - null - [null, null, null, null, null] +22196 - null - [null, null, null, null, null] +22197 - null - [null, null, null, null, null] +22198 - null - [null, null, null, null, null] +22199 - null - [null, null, null, null, null] +22200 - null - [null, null, null, null, null] +22201 - null - [null, null, null, null, null] +22202 - null - [null, null, null, null, null] +22203 - null - [null, null, null, null, null] +22204 - null - [null, null, null, null, null] +22205 - null - [null, null, null, null, null] +22206 - null - [null, null, null, null, null] +22207 - null - [null, null, null, null, null] +22208 - null - [null, null, null, null, null] +22209 - null - [null, null, null, null, null] +22210 - null - [null, null, null, null, null] +22211 - null - [null, null, null, null, null] +22212 - null - [null, null, null, null, null] +22213 - null - [null, null, null, null, null] +22214 - null - [null, null, null, null, null] +22215 - null - [null, null, null, null, null] +22216 - null - [null, null, null, null, null] +22217 - null - [null, null, null, null, null] +22218 - null - [null, null, null, null, null] +22219 - null - [null, null, null, null, null] +22220 - null - [null, null, null, null, null] +22221 - null - [null, null, null, null, null] +22222 - null - [null, null, null, null, null] +22223 - null - [null, null, null, null, null] +22224 - null - [null, null, null, null, null] +22225 - null - [null, null, null, null, null] +22226 - null - [null, null, null, null, null] +22227 - null - [null, null, null, null, null] +22228 - null - [null, null, null, null, null] +22229 - null - [null, null, null, null, null] +22230 - null - [null, null, null, null, null] +22231 - null - [null, null, null, null, null] +22232 - null - [null, null, null, null, null] +22233 - null - [null, null, null, null, null] +22234 - null - [null, null, null, null, null] +22235 - null - [null, null, null, null, null] +22236 - null - [null, null, null, null, null] +22237 - null - [null, null, null, null, null] +22238 - null - [null, null, null, null, null] +22239 - null - [null, null, null, null, null] +22240 - null - [null, null, null, null, null] +22241 - null - [null, null, null, null, null] +22242 - null - [null, null, null, null, null] +22243 - null - [null, null, null, null, null] +22244 - null - [null, null, null, null, null] +22245 - null - [null, null, null, null, null] +22246 - null - [null, null, null, null, null] +22247 - Stairs - [Climb-up, null, null, null, null] +22248 - Stairs - [Climb-up, null, null, null, null] +22249 - null - [null, null, null, null, null] +22250 - Stairs - [Climb-up, null, null, null, null] +22251 - null - [null, null, null, null, null] +22252 - Stairs - [Climb-down, null, null, null, null] +22253 - Stairs - [Climb-down, null, null, null, null] +22254 - Stairs - [Climb-down, null, null, null, null] +22255 - null - [null, null, null, null, null] +22256 - null - [null, null, null, null, null] +22257 - null - [null, null, null, null, null] +22258 - null - [null, null, null, null, null] +22259 - null - [null, null, null, null, null] +22260 - null - [null, null, null, null, null] +22261 - null - [null, null, null, null, null] +22262 - null - [null, null, null, null, null] +22263 - null - [null, null, null, null, null] +22264 - null - [null, null, null, null, null] +22265 - null - [null, null, null, null, null] +22266 - null - [null, null, null, null, null] +22267 - null - [null, null, null, null, null] +22268 - null - [null, null, null, null, null] +22269 - null - [null, null, null, null, null] +22270 - Support - [null, null, null, null, null] +22271 - Cannon - [null, null, null, null, null] +22272 - Cannon - [null, null, null, null, null] +22273 - Broken cannon - [null, null, null, null, null] +22274 - Ladder - [Climb, null, null, null, null] +22275 - Ladder - [Climb, null, null, null, null] +22276 - null - [null, null, null, null, null] +22277 - Crate - [null, null, null, null, null] +22278 - Barrel - [null, null, null, null, null] +22279 - Barrel - [null, null, null, null, null] +22280 - Barrel - [null, null, null, null, null] +22281 - Locked door - [null, null, null, null, null] +22282 - Locked door - [null, null, null, null, null] +22283 - Locked door - [null, null, null, null, null] +22284 - null - [null, null, null, null, null] +22285 - null - [null, null, null, null, null] +22286 - null - [null, null, null, null, null] +22287 - null - [null, null, null, null, null] +22288 - null - [null, null, null, null, null] +22289 - null - [null, null, null, null, null] +22290 - null - [null, null, null, null, null] +22291 - null - [null, null, null, null, null] +22292 - null - [null, null, null, null, null] +22293 - null - [null, null, null, null, null] +22294 - null - [null, null, null, null, null] +22295 - null - [null, null, null, null, null] +22296 - null - [null, null, null, null, null] +22297 - null - [null, null, null, null, null] +22298 - Locker - [Open, null, null, null, null] +22299 - Locker - [Search, Close, null, null, null] +22300 - Wheat - [null, Pick, null, null, null] +22301 - Cabbage - [null, Pick, null, null, null] +22302 - Stile - [Climb-over, null, null, null, null] +22303 - null - [null, null, null, null, null] +22304 - null - [null, null, null, null, null] +22305 - null - [null, null, null, null, null] +22306 - null - [null, null, null, null, null] +22307 - null - [null, null, null, null, null] +22308 - null - [null, null, null, null, null] +22309 - null - [null, null, null, null, null] +22310 - null - [null, null, null, null, null] +22311 - null - [null, null, null, null, null] +22312 - null - [null, null, null, null, null] +22313 - null - [null, null, null, null, null] +22314 - null - [null, null, null, null, null] +22315 - null - [null, null, null, null, null] +22316 - null - [null, null, null, null, null] +22317 - null - [null, null, null, null, null] +22318 - null - [null, null, null, null, null] +22319 - null - [null, null, null, null, null] +22320 - null - [null, null, null, null, null] +22321 - null - [null, null, null, null, null] +22322 - null - [null, null, null, null, null] +22323 - null - [null, null, null, null, null] +22324 - null - [null, null, null, null, null] +22325 - null - [null, null, null, null, null] +22326 - null - [null, null, null, null, null] +22327 - null - [null, null, null, null, null] +22328 - null - [null, null, null, null, null] +22329 - null - [null, null, null, null, null] +22330 - null - [null, null, null, null, null] +22331 - null - [null, null, null, null, null] +22332 - null - [null, null, null, null, null] +22333 - null - [null, null, null, null, null] +22334 - null - [null, null, null, null, null] +22335 - null - [null, null, null, null, null] +22336 - null - [null, null, null, null, null] +22337 - null - [null, null, null, null, null] +22338 - null - [null, null, null, null, null] +22339 - null - [null, null, null, null, null] +22340 - null - [null, null, null, null, null] +22341 - null - [null, null, null, null, null] +22342 - null - [null, null, null, null, null] +22343 - null - [null, null, null, null, null] +22344 - null - [null, null, null, null, null] +22345 - null - [null, null, null, null, null] +22346 - null - [null, null, null, null, null] +22347 - null - [null, null, null, null, null] +22348 - null - [null, null, null, null, null] +22349 - null - [null, null, null, null, null] +22350 - null - [null, null, null, null, null] +22351 - null - [null, null, null, null, null] +22352 - Statue - [null, null, null, null, null] +22353 - Statue - [Pull, null, null, null, null] +22354 - Statue - [Climb-down, null, null, null, null] +22355 - null - [hidden, null, null, null, null] +22356 - null - [null, null, null, null, null] +22357 - null - [null, null, null, null, null] +22358 - null - [null, null, null, null, null] +22359 - null - [null, null, null, null, null] +22360 - null - [null, null, null, null, null] +22361 - null - [null, null, null, null, null] +22362 - null - [null, null, null, null, null] +22363 - null - [null, null, null, null, null] +22364 - null - [null, null, null, null, null] +22365 - Stairs - [Descend, null, null, null, null] +22366 - Stairs - [Descend, null, null, null, null] +22367 - Stairs - [Climb, null, null, null, null] +22368 - Stairs - [Repair, Climb, null, null, null] +22369 - Stairs - [null, Climb, null, null, null] +22370 - null - [hidden, Climb, null, null, null] +22371 - Ladder - [Climb, null, null, null, null] +22372 - Ladder - [Climb, null, null, null, null] +22373 - Granary wall - [null, null, null, null, null] +22374 - Granary wall - [null, null, null, null, null] +22375 - Granary wall - [null, null, null, null, null] +22376 - Granary wall - [null, null, null, null, null] +22377 - Granary wall - [null, null, null, null, null] +22378 - Granary wall - [null, null, null, null, null] +22379 - Granary wall - [null, null, null, null, null] +22380 - Granary wall - [null, null, null, null, null] +22381 - null - [null, null, null, null, null] +22382 - null - [null, null, null, null, null] +22383 - null - [null, null, null, null, null] +22384 - null - [null, null, null, null, null] +22385 - Granary roof - [null, null, null, null, null] +22386 - Granary roof - [null, null, null, null, null] +22387 - Granary roof - [null, null, null, null, null] +22388 - Granary roof - [null, null, null, null, null] +22389 - Granary roof - [null, null, null, null, null] +22390 - Granary roof - [null, null, null, null, null] +22391 - Granary roof - [null, null, null, null, null] +22392 - Granary roof - [null, null, null, null, null] +22393 - Granary roof - [null, null, null, null, null] +22394 - Granary roof - [null, null, null, null, null] +22395 - Granary roof - [null, null, null, null, null] +22396 - Granary roof - [null, null, null, null, null] +22397 - Granary roof - [null, null, null, null, null] +22398 - Granary roof - [null, null, null, null, null] +22399 - Granary roof - [null, null, null, null, null] +22400 - Granary roof - [null, null, null, null, null] +22401 - Granary roof - [null, null, null, null, null] +22402 - Granary roof - [null, null, null, null, null] +22403 - Granary roof - [null, null, null, null, null] +22404 - Granary roof - [null, null, null, null, null] +22405 - Granary roof - [null, null, null, null, null] +22406 - Granary roof - [null, null, null, null, null] +22407 - Granary roof - [null, null, null, null, null] +22408 - Granary roof - [null, null, null, null, null] +22409 - Granary roof - [null, null, null, null, null] +22410 - Granary roof - [null, null, null, null, null] +22411 - Granary roof - [null, null, null, null, null] +22412 - Granary roof - [null, null, null, null, null] +22413 - Granary roof - [null, null, null, null, null] +22414 - Granary roof - [null, null, null, null, null] +22415 - Granary roof - [null, null, null, null, null] +22416 - Granary roof - [null, null, null, null, null] +22417 - Granary roof - [null, null, null, null, null] +22418 - Sails - [null, null, null, null, null] +22419 - Millstones - [null, null, null, null, null] +22420 - Flour bin - [null, null, null, null, null] +22421 - Flour bin - [Empty, null, null, null, null] +22422 - Hopper - [null, null, null, null, null] +22423 - null - [null, null, null, null, null] +22424 - Lever - [Pull, null, null, null, null] +22425 - null - [null, null, null, null, null] +22426 - Crate - [null, null, null, null, null] +22427 - Crate - [Search, null, null, null, null] +22428 - null - [null, null, null, null, null] +22429 - null - [null, null, null, null, null] +22430 - Sack - [null, null, null, null, null] +22431 - Table - [null, null, null, null, null] +22432 - Ladder - [Climb-up, null, null, null, null] +22433 - Ladder - [Climb, Climb-up, Climb-down, null, null] +22434 - Ladder - [Climb-down, null, null, null, null] +22435 - Large door - [Open, null, null, null, null] +22436 - Large door - [Close, null, null, null, null] +22437 - Large door - [Open, null, null, null, null] +22438 - Large door - [Close, null, null, null, null] +22439 - Rock wall - [null, null, null, null, null] +22440 - Rock wall - [null, null, null, null, null] +22441 - Rock wall - [null, null, null, null, null] +22442 - Rock wall - [null, null, null, null, null] +22443 - Rock wall - [null, null, null, null, null] +22444 - Rock wall - [null, null, null, null, null] +22445 - Rock wall - [null, null, null, null, null] +22446 - Rock wall - [null, null, null, null, null] +22447 - Rock wall - [null, null, null, null, null] +22448 - Rock wall - [null, null, null, null, null] +22449 - Rock wall - [null, null, null, null, null] +22450 - Rock wall - [null, null, null, null, null] +22451 - Rock wall - [null, null, null, null, null] +22452 - Rock wall - [null, null, null, null, null] +22453 - Crate - [Add-bottom, null, null, null, null] +22454 - Crate - [Fill, null, null, null, null] +22455 - Crate - [null, null, null, null, null] +22456 - Crate - [null, null, null, null, null] +22457 - Crate - [Build, null, null, null, null] +22458 - null - [null, null, null, null, null] +22459 - null - [null, null, null, null, null] +22460 - null - [null, null, null, null, null] +22461 - null - [null, null, null, null, null] +22462 - null - [null, null, null, null, null] +22463 - null - [null, null, null, null, null] +22464 - null - [null, null, null, null, null] +22465 - null - [null, null, null, null, null] +22466 - null - [null, null, null, null, null] +22467 - null - [null, null, null, null, null] +22468 - null - [null, null, null, null, null] +22469 - null - [null, null, null, null, null] +22470 - null - [null, null, null, null, null] +22471 - null - [null, null, null, null, null] +22472 - Lectern - [null, null, null, null, null] +22473 - Wheat - [null, Pick, null, null, null] +22474 - Wheat - [null, Pick, null, null, null] +22475 - Wheat - [null, Pick, null, null, null] +22476 - Wheat - [null, Pick, null, null, null] +22477 - Door - [null, null, null, null, null] +22478 - Wall - [null, null, null, null, null] +22479 - Wall - [null, null, null, null, null] +22480 - Wall - [null, null, null, null, null] +22481 - Wall - [null, null, null, null, null] +22482 - Wall - [null, null, null, null, null] +22483 - Fuse - [null, null, null, null, null] +22484 - Fuse - [null, null, null, null, null] +22485 - null - [null, null, null, null, null] +22486 - null - [null, null, null, null, null] +22487 - null - [null, null, null, null, null] +22488 - null - [null, null, null, null, null] +22489 - null - [hidden, null, null, null, null] +22490 - null - [null, null, null, null, null] +22491 - null - [null, null, null, null, null] +22492 - null - [null, null, null, null, null] +22493 - null - [null, null, null, null, null] +22494 - null - [null, null, null, null, null] +22495 - null - [null, null, null, null, null] +22496 - Path - [Look-at, Return-to-Paterdomus, null, null, null] +22497 - Marv (sick) - [Talk-to, null, null, null, null] +22498 - Marv (very sick) - [Talk-to, null, null, null, null] +22499 - Marv (ghastly!) - [Talk-to, null, null, null, null] +22500 - Marv (sick) - [Talk-to, null, null, null, null] +22501 - Marv (very sick) - [Talk-to, null, null, null, null] +22502 - Marv (ghastly!) - [Talk-to, null, null, null, null] +22503 - Marv (Well) - [Talk-to, null, hidden, null, null] +22504 - Hank (sick) - [Talk-to, null, null, null, null] +22505 - Hank (very sick) - [Talk-to, null, null, null, null] +22506 - Hank (ghastly!) - [Talk-to, null, null, null, null] +22507 - Hank (sick) - [Talk-to, null, null, null, null] +22508 - Hank (very sick) - [Talk-to, null, null, null, null] +22509 - Hank (ghastly!) - [Talk-to, null, null, null, null] +22510 - Hank (Well) - [Talk-to, null, hidden, null, null] +22511 - Wilf (sick) - [Talk-to, null, null, null, null] +22512 - Wilf (very sick) - [Talk-to, null, null, null, null] +22513 - Wilf (ghastly!) - [Talk-to, null, null, null, null] +22514 - Wilf (sick) - [Talk-to, null, null, null, null] +22515 - Wilf (very sick) - [Talk-to, null, null, null, null] +22516 - Wilf (ghastly!) - [Talk-to, null, null, null, null] +22517 - Wilf (Well) - [Talk-to, null, hidden, null, null] +22518 - Sarah (sick!) - [Talk-to, null, null, null, null] +22519 - Sarah (very sick!) - [Talk-to, null, null, null, null] +22520 - Sarah (ghastly!) - [Talk-to, null, null, null, null] +22521 - Sarah (sick!) - [Talk-to, null, null, null, null] +22522 - Sarah (very sick!) - [Talk-to, null, null, null, null] +22523 - Sarah (ghastly!) - [Talk-to, null, null, null, null] +22524 - Sarah (Well) - [Talk-to, null, hidden, null, null] +22525 - Rachel (sick) - [Talk-to, null, null, null, null] +22526 - Rachel (very sick) - [Talk-to, null, null, null, null] +22527 - Rachel (ghastly!) - [Talk-to, null, null, null, null] +22528 - Rachel (sick) - [Talk-to, null, null, null, null] +22529 - Rachel (very sick) - [Talk-to, null, null, null, null] +22530 - Rachel (ghastly!) - [Talk-to, null, null, null, null] +22531 - Rachel (Well) - [Talk-to, null, hidden, null, null] +22532 - Empty clothes - [null, null, null, null, null] +22533 - Partially broken bridge - [Search, null, null, null, null] +22534 - Slightly broken bridge - [Search, null, null, null, null] +22535 - Fixed bridge - [Search, Walk-across, null, null, null] +22536 - null - [null, null, null, null, null] +22537 - Tunnel - [Enter, null, null, null, null] +22538 - Tunnel - [Enter, null, null, null, null] +22539 - null - [null, null, null, null, null] +22540 - null - [null, null, null, null, null] +22541 - Stalagmite - [null, null, null, null, null] +22542 - Large stalagmite - [null, null, null, null, null] +22543 - Connected stalagmites - [null, null, null, null, null] +22544 - null - [null, null, null, null, null] +22545 - Molanisk - [null, null, null, null, null] +22546 - null - [null, null, null, null, null] +22547 - null - [null, null, null, null, null] +22548 - null - [null, null, null, null, null] +22549 - Rock - [null, null, null, null, null] +22550 - Rock - [null, null, null, null, null] +22551 - Rock - [null, null, null, null, null] +22552 - Jutting wall - [Squeeze-past, null, null, null, null] +22553 - null - [null, null, null, null, null] +22554 - null - [null, null, null, null, null] +22555 - null - [null, null, null, null, null] +22556 - Hole - [Squeeze-through, null, null, null, null] +22557 - Tunnel - [Squeeze-through, null, null, null, null] +22558 - null - [null, null, null, null, null] +22559 - null - [null, null, null, null, null] +22560 - null - [null, null, null, null, null] +22561 - null - [null, null, null, null, null] +22562 - null - [null, null, null, null, null] +22563 - Ladder - [null, null, null, null, null] +22564 - Ladder - [Swing-across, null, null, null, null] +22565 - null - [null, null, null, null, null] +22566 - Ladder - [null, null, null, null, null] +22567 - Ladder - [null, null, null, null, null] +22568 - Cable - [null, null, null, null, null] +22569 - Cable - [Walk-across, null, null, null, null] +22570 - Lamppost - [null, null, null, null, null] +22571 - Lamppost - [null, null, null, null, null] +22572 - Cable - [Swing, null, null, null, null] +22573 - null - [null, null, null, null, null] +22574 - null - [null, null, null, null, null] +22575 - null - [null, null, null, null, null] +22576 - Cable - [null, null, null, null, null] +22577 - null - [null, null, null, null, null] +22578 - null - [null, null, null, null, null] +22579 - null - [null, null, null, null, null] +22580 - null - [null, null, null, null, null] +22581 - null - [null, null, null, null, null] +22582 - null - [null, null, null, null, null] +22583 - null - [null, null, null, null, null] +22584 - null - [null, null, null, null, null] +22585 - null - [null, null, null, null, null] +22586 - null - [null, null, null, null, null] +22587 - null - [null, null, null, null, null] +22588 - null - [null, null, null, null, null] +22589 - Pylon - [null, null, null, null, null] +22590 - Pylon - [null, null, null, null, null] +22591 - Pylon - [null, null, null, null, null] +22592 - null - [null, null, null, null, null] +22593 - null - [null, null, null, null, null] +22594 - null - [null, null, null, null, null] +22595 - null - [null, null, null, null, null] +22596 - null - [null, null, null, null, null] +22597 - null - [null, null, null, null, null] +22598 - null - [null, null, null, null, null] +22599 - null - [null, null, null, null, null] +22600 - Ladder - [Climb-up, null, null, null, null] +22601 - Ladder - [Climb-up, null, null, null, null] +22602 - Ladder - [Climb-down, null, null, null, null] +22603 - null - [null, null, null, null, null] +22604 - null - [null, null, null, null, null] +22605 - null - [null, null, null, null, null] +22606 - null - [null, null, null, null, null] +22607 - Stairs - [null, null, null, null, null] +22608 - Stairs - [Climb-up, null, null, null, null] +22609 - Stairs - [Climb-down, null, null, null, null] +22610 - null - [null, null, null, null, null] +22611 - null - [null, null, null, null, null] +22612 - null - [null, null, null, null, null] +22613 - null - [null, null, null, null, null] +22614 - null - [null, null, null, null, null] +22615 - null - [null, null, null, null, null] +22616 - null - [null, null, null, null, null] +22617 - null - [null, null, null, null, null] +22618 - null - [null, null, null, null, null] +22619 - null - [null, null, null, null, null] +22620 - null - [null, null, null, null, null] +22621 - null - [null, null, null, null, null] +22622 - null - [null, null, null, null, null] +22623 - null - [null, null, null, null, null] +22624 - Dial - [null, null, null, null, null] +22625 - Levers - [null, null, null, null, null] +22626 - null - [null, null, null, null, null] +22627 - null - [null, null, null, null, null] +22628 - null - [null, null, null, null, null] +22629 - null - [null, null, null, null, null] +22630 - null - [null, null, null, null, null] +22631 - null - [null, null, null, null, null] +22632 - null - [null, null, null, null, null] +22633 - null - [null, null, null, null, null] +22634 - Console - [null, null, null, null, null] +22635 - Boiler - [null, null, null, null, null] +22636 - null - [null, null, null, null, null] +22637 - null - [null, null, null, null, null] +22638 - null - [null, null, null, null, null] +22639 - null - [null, null, null, null, null] +22640 - null - [null, null, null, null, null] +22641 - null - [null, null, null, null, null] +22642 - null - [null, null, null, null, null] +22643 - null - [null, null, null, null, null] +22644 - null - [null, null, null, null, null] +22645 - null - [null, null, null, null, null] +22646 - null - [null, null, null, null, null] +22647 - null - [null, null, null, null, null] +22648 - null - [null, null, null, null, null] +22649 - Stairs - [null, null, null, null, null] +22650 - Stairs - [Climb-up, null, null, null, null] +22651 - Stairs - [Climb-down, null, null, null, null] +22652 - null - [null, null, null, null, null] +22653 - null - [null, null, null, null, null] +22654 - null - [null, null, null, null, null] +22655 - null - [null, null, null, null, null] +22656 - Blocked tunnel - [Enter, null, null, null, null] +22657 - Blocked tunnel - [Enter, null, null, null, null] +22658 - Open gate - [null, null, null, null, null] +22659 - Blocked tunnel - [null, null, null, null, null] +22660 - null - [null, null, null, null, null] +22661 - null - [null, null, null, null, null] +22662 - null - [null, null, null, null, null] +22663 - Pylon - [null, null, null, null, null] +22664 - Pylon - [Grapple, null, null, null, null] +22665 - Rocks - [null, null, null, null, null] +22666 - Ladder top - [Climb-down, null, null, null, null] +22667 - Rocks - [Climb-down, null, null, null, null] +22668 - Sign - [null, null, null, null, null] +22669 - Bench - [null, null, null, null, null] +22670 - Stool - [null, null, null, null, null] +22671 - Shelf - [null, null, null, null, null] +22672 - Table - [null, null, null, null, null] +22673 - null - [null, null, null, null, null] +22674 - null - [null, null, null, null, null] +22675 - null - [null, null, null, null, null] +22676 - Chair - [null, null, null, null, null] +22677 - Table - [null, null, null, null, null] +22678 - Table - [null, null, null, null, null] +22679 - Bed - [null, null, null, null, null] +22680 - Bed - [null, null, null, null, null] +22681 - Chest - [Open, Pick-lock, null, null, null] +22682 - Chest - [Open, Pick-lock, null, null, null] +22683 - Chest - [null, null, null, null, null] +22684 - Ladder - [null, null, null, null, null] +22685 - Shelf - [null, null, null, null, null] +22686 - Shelf - [null, null, null, null, null] +22687 - null - [null, null, null, null, null] +22688 - null - [null, null, null, null, null] +22689 - null - [null, null, null, null, null] +22690 - Table - [null, null, null, null, null] +22691 - Stool - [null, null, null, null, null] +22692 - Chair - [null, null, null, null, null] +22693 - Table - [null, null, null, null, null] +22694 - Table - [null, null, null, null, null] +22695 - Bed - [null, null, null, null, null] +22696 - Bed - [null, null, null, null, null] +22697 - Chest - [Open, Pick-lock, null, null, null] +22698 - Chest - [Open, Pick-lock, null, null, null] +22699 - Chest - [null, null, null, null, null] +22700 - Ladder - [null, null, null, null, null] +22701 - Shelf - [null, null, null, null, null] +22702 - Shelf - [null, null, null, null, null] +22703 - Chair - [null, null, null, null, null] +22704 - Chair - [null, null, null, null, null] +22705 - Table - [null, null, null, null, null] +22706 - Carving - [null, null, null, null, null] +22707 - Carving - [null, null, null, null, null] +22708 - Carving - [null, null, null, null, null] +22709 - Statue - [null, null, null, null, null] +22710 - Statue - [null, null, null, null, null] +22711 - Bust - [null, null, null, null, null] +22712 - Bust - [null, null, null, null, null] +22713 - Range - [null, null, null, null, null] +22714 - Range - [null, null, null, null, null] +22715 - Sink - [null, null, null, null, null] +22716 - Kitchen table - [null, null, null, null, null] +22717 - Pots - [null, null, null, null, null] +22718 - Shelves - [null, null, null, null, null] +22719 - Shelves - [null, null, null, null, null] +22720 - Shelves - [null, null, null, null, null] +22721 - Furnace - [null, null, null, null, null] +22722 - Bellows - [null, null, null, null, null] +22723 - Chimney - [null, null, null, null, null] +22724 - Chimney pipe - [null, null, null, null, null] +22725 - Anvil - [null, null, null, null, null] +22726 - Sandpit - [null, null, null, null, null] +22727 - Chimney - [null, null, null, null, null] +22728 - Wire machine - [null, null, null, null, null] +22729 - Wire machine - [null, null, null, null, null] +22730 - Wire - [Grab, null, null, null, null] +22731 - Wire - [null, null, null, null, null] +22732 - Cogs - [null, null, null, null, null] +22733 - Smoke - [null, null, null, null, null] +22734 - Moths - [null, null, null, null, null] +22735 - Zapper - [hidden, null, null, null, null] +22736 - Zapper - [null, null, null, null, null] +22737 - Zapper - [null, null, null, null, null] +22738 - Lamppost - [null, null, null, null, null] +22739 - Lamppost - [null, null, null, null, null] +22740 - Lamppost - [null, null, null, null, null] +22741 - Lamppost - [null, null, null, null, null] +22742 - Lamppost - [null, null, null, null, null] +22743 - Lamppost - [null, null, null, null, null] +22744 - Lamppost - [null, null, null, null, null] +22745 - Lamppost - [null, null, null, null, null] +22746 - Lamppost - [null, null, null, null, null] +22747 - Lamppost - [null, null, null, null, null] +22748 - Lamppost - [null, null, null, null, null] +22749 - Lamppost - [null, null, null, null, null] +22750 - Cable - [null, null, null, null, null] +22751 - Cable - [null, null, null, null, null] +22752 - Cable - [null, null, null, null, null] +22753 - Cable - [null, null, null, null, null] +22754 - Cable - [null, null, null, null, null] +22755 - Cable - [null, null, null, null, null] +22756 - Cable - [null, null, null, null, null] +22757 - Cable - [null, null, null, null, null] +22758 - Cable - [null, null, null, null, null] +22759 - Cable - [null, null, null, null, null] +22760 - Lamp - [null, null, null, null, null] +22761 - Lamp - [null, null, null, null, null] +22762 - Lamp - [null, null, null, null, null] +22763 - Empty lamp - [Inspect, null, null, null, null] +22764 - Lamp - [null, null, null, null, null] +22765 - Market stall - [null, null, null, null, null] +22766 - Market stall - [null, null, null, null, null] +22767 - Market stall - [null, null, null, null, null] +22768 - Market stall - [null, null, null, null, null] +22769 - Market stall - [null, null, null, null, null] +22770 - Market stall - [null, null, null, null, null] +22771 - Market stall - [null, null, null, null, null] +22772 - Lamp stall - [null, null, null, null, null] +22773 - Lamp still - [null, null, null, null, null] +22774 - Armour stall - [null, null, null, null, null] +22775 - Barrier - [null, null, null, null, null] +22776 - Barrier - [null, null, null, null, null] +22777 - null - [null, null, null, null, null] +22778 - Gate - [Close, null, null, null, null] +22779 - Gate - [Open, null, null, null, null] +22780 - null - [null, null, null, null, null] +22781 - Toy range - [null, null, null, null, null] +22782 - Toy sink - [null, null, null, null, null] +22783 - Toy table - [null, null, null, null, null] +22784 - Play blocks - [null, null, null, null, null] +22785 - Play blocks - [null, null, null, null, null] +22786 - Play blocks - [null, null, null, null, null] +22787 - Crib - [null, null, null, null, null] +22788 - Chalk patterns - [null, null, null, null, null] +22789 - Chalk patterns - [null, null, null, null, null] +22790 - Chalk patterns - [null, null, null, null, null] +22791 - Chalk patterns - [null, null, null, null, null] +22792 - Chalk patterns - [null, null, null, null, null] +22793 - Chalk patterns - [null, null, null, null, null] +22794 - Shape puzzle - [null, null, null, null, null] +22795 - Shape puzzle - [null, null, null, null, null] +22796 - Mushrooms - [null, null, null, null, null] +22797 - Mushrooms - [null, null, null, null, null] +22798 - Mushrooms - [null, null, null, null, null] +22799 - Mushrooms - [null, null, null, null, null] +22800 - Mushrooms - [null, null, null, null, null] +22801 - Mushrooms - [null, null, null, null, null] +22802 - Mushrooms - [null, null, null, null, null] +22803 - Mushrooms - [null, null, null, null, null] +22804 - Fern - [null, null, null, null, null] +22805 - Fern - [null, null, null, null, null] +22806 - Fern - [null, null, null, null, null] +22807 - Fern - [null, null, null, null, null] +22808 - Flowering fern - [null, null, null, null, null] +22809 - Flowering fern - [null, null, null, null, null] +22810 - Box - [null, null, null, null, null] +22811 - Counter - [null, null, null, null, null] +22812 - Bone rack - [null, null, null, null, null] +22813 - Bone rack - [null, null, null, null, null] +22814 - Bone rack - [null, null, null, null, null] +22815 - Bone rack - [null, null, null, null, null] +22816 - Bone rack - [null, null, null, null, null] +22817 - Bone rack - [null, null, null, null, null] +22818 - Bone rack - [null, null, null, null, null] +22819 - Bank booth - [Use, Use-quickly, Collect, null, null] +22820 - Desk - [null, null, null, null, null] +22821 - Desk - [null, null, null, null, null] +22822 - Bank safe - [null, null, null, null, null] +22823 - Thingymajig - [null, null, null, null, null] +22824 - Oojimaflip - [null, null, null, null, null] +22825 - Plinth - [null, null, null, null, null] +22826 - Magic ball - [null, null, null, null, null] +22827 - Workbench - [null, null, null, null, null] +22828 - Beetle - [null, null, null, null, null] +22829 - Frog - [null, null, null, null, null] +22830 - Table - [null, null, null, null, null] +22831 - Table - [null, null, null, null, null] +22832 - Table - [null, null, null, null, null] +22833 - Shelf - [null, null, null, null, null] +22834 - Shelf - [null, null, null, null, null] +22835 - Fungus seat - [null, null, null, null, null] +22836 - Moth - [null, null, null, null, null] +22837 - null - [null, null, null, null, null] +22838 - null - [null, null, null, null, null] +22839 - null - [null, null, null, null, null] +22840 - null - [null, null, null, null, null] +22841 - Bust - [null, null, null, null, null] +22842 - Bust - [null, null, null, null, null] +22843 - Chair - [null, null, null, null, null] +22844 - Table - [null, null, null, null, null] +22845 - Table - [null, null, null, null, null] +22846 - Table - [null, null, null, null, null] +22847 - Table - [null, null, null, null, null] +22848 - Table - [nul + + + +null, null] +23253 - Wreck - [null, null, null, null, null] +23254 - Wreck - [null, null, null, null, null] +23255 - Wreck - [null, null, null, null, null] +23256 - Wreck - [null, null, null, null, null] +23257 - null - [null, null, null, null, null] +23258 - null - [null, null, null, null, null] +23259 - null - [null, null, null, null, null] +23260 - null - [null, null, null, null, null] +23261 - null - [null, null, null, null, null] +23262 - null - [null, null, null, null, null] +23263 - null - [null, null, null, null, null] +23264 - null - [null, null, null, null, null] +23265 - null - [null, null, null, null, null] +23266 - null - [null, null, null, null, null] +23267 - null - [null, null, null, null, null] +23268 - null - [null, null, null, null, null] +23269 - null - [null, null, null, null, null] +23270 - null - [null, null, null, null, null] +23271 - Wilderness Ditch - [Cross, null, null, null, null] +23272 - null - [null, null, null, null, null] +23273 - null - [null, null, null, null, null] +23274 - Gate - [Open, null, null, null, null] +23275 - Sign - [Read, null, null, null, null] +23276 - Sign - [Read, null, null, null, null] +23277 - null - [null, null, null, null, null] +23278 - null - [null, null, null, null, null] +23279 - Ladder - [Climb-down, null, null, null, null] +23280 - Rocks - [null, null, null, null, null] +23281 - Rocks - [null, null, null, null, null] +23282 - null - [null, null, null, null, null] +23283 - Crate - [Hide-behind, hidden, null, null, null] +23284 - Zanik - [Untie, null, null, null, null] +23285 - Doorway - [Enter, null, null, null, null] +23286 - Doorway - [Enter, null, null, null, null] +23287 - Doorway - [Enter, null, null, null, null] +23288 - Artefact - [null, null, null, null, null] +23289 - Hole - [null, null, null, null, null] +23290 - null - [null, null, null, null, null] +23291 - Artefact - [null, null, null, null, null] +23292 - Hole - [null, null, null, null, null] +23293 - null - [null, null, null, null, null] +23294 - Artefact - [null, null, null, null, null] +23295 - Hole - [null, null, null, null, null] +23296 - null - [null, null, null, null, null] +23297 - Artefact - [null, null, null, null, null] +23298 - Hole - [null, null, null, null, null] +23299 - Artefact - [null, null, null, null, null] +23300 - Hole - [null, null, null, null, null] +23301 - null - [null, null, null, null, null] +23302 - Artefact - [null, null, null, null, null] +23303 - Hole - [null, null, null, null, null] +23304 - null - [null, null, null, null, null] +23305 - Specimen table - [null, null, null, null, null] +23306 - Goblin crowd - [null, null, null, null, null] +23307 - Goblin crowd - [null, null, null, null, null] +23308 - Goblin crowd - [null, null, null, null, null] +23309 - Goblin crowd - [null, null, null, null, null] +23310 - Goblin crowd - [null, null, null, null, null] +23311 - Goblin crowd - [null, null, null, null, null] +23312 - Goblin crowd - [null, null, null, null, null] +23313 - Goblin crowd - [null, null, null, null, null] +23314 - Goblin crowd - [null, null, null, null, null] +23315 - Crowd of dwarves - [null, null, null, null, null] +23316 - Crowd of dwarves - [null, null, null, null, null] +23317 - Crowd of dwarves - [null, null, null, null, null] +23318 - Council members - [null, null, null, null, null] +23319 - Cave gobins - [null, null, null, null, null] +23320 - null - [null, null, null, null, null] +23321 - null - [null, null, null, null, null] +23322 - null - [null, null, null, null, null] +23323 - null - [null, null, null, null, null] +23324 - null - [null, null, null, null, null] +23325 - null - [null, null, null, null, null] +23326 - null - [null, null, null, null, null] +23327 - null - [null, null, null, null, null] +23328 - null - [null, null, null, null, null] +23329 - null - [null, null, null, null, null] +23330 - null - [null, null, null, null, null] +23331 - null - [null, null, null, null, null] +23332 - null - [null, null, null, null, null] +23333 - null - [null, null, null, null, null] +23334 - null - [null, null, null, null, null] +23335 - null - [null, null, null, null, null] +23336 - null - [null, null, null, null, null] +23337 - null - [null, null, null, null, null] +23338 - Door - [Open, null, null, null, null] +23339 - Door - [Close, null, null, null, null] +23340 - Large door - [Open, null, null, null, null] +23341 - Large door - [Close, null, null, null, null] +23342 - Large door - [Open, null, null, null, null] +23343 - Large door - [Close, null, null, null, null] +23344 - null - [null, null, null, null, null] +23345 - null - [null, null, null, null, null] +23346 - null - [null, null, null, null, null] +23347 - null - [null, null, null, null, null] +23348 - Wall - [null, null, null, null, null] +23349 - Wall - [null, null, null, null, null] +23350 - Wall - [null, null, null, null, null] +23351 - null - [null, null, null, null, null] +23352 - null - [null, null, null, null, null] +23353 - null - [null, null, null, null, null] +23354 - null - [null, null, null, null, null] +23355 - null - [null, null, null, null, null] +23356 - Crate - [null, null, null, null, null] +23357 - Crate - [null, null, null, null, null] +23358 - Crate - [null, null, null, null, null] +23359 - null - [null, null, null, null, null] +23360 - null - [null, null, null, null, null] +23361 - null - [null, null, null, null, null] +23362 - null - [null, null, null, null, null] +23363 - null - [null, null, null, null, null] +23364 - null - [null, null, null, null, null] +23365 - null - [null, null, null, null, null] +23366 - Barrel - [null, null, null, null, null] +23367 - null - [null, null, null, null, null] +23368 - null - [null, null, null, null, null] +23369 - null - [null, null, null, null, null] +23370 - null - [null, null, null, null, null] +23371 - null - [null, null, null, null, null] +23372 - null - [null, null, null, null, null] +23373 - null - [null, null, null, null, null] +23374 - null - [null, null, null, null, null] +23375 - null - [null, null, null, null, null] +23376 - Ladder - [Climb-down, null, null, null, null] +23377 - Ladder - [Climb-up, null, null, null, null] +23378 - Door - [Open, null, null, null, null] +23379 - Door - [null, null, null, null, null] +23380 - null - [null, null, null, null, null] +23381 - Dead tree - [null, null, null, null, null] +23382 - null - [null, null, null, null, null] +23383 - null - [null, null, null, null, null] +23384 - null - [null, null, null, null, null] +23385 - null - [null, null, null, null, null] +23386 - null - [null, null, null, null, null] +23387 - null - [null, null, null, null, null] +23388 - null - [null, null, null, null, null] +23389 - null - [null, null, null, null, null] +23390 - null - [null, null, null, null, null] +23391 - null - [null, null, null, null, null] +23392 - null - [null, null, null, null, null] +23393 - null - [null, null, null, null, null] +23394 - null - [null, null, null, null, null] +23395 - null - [null, null, null, null, null] +23396 - null - [null, null, null, null, null] +23397 - null - [null, null, null, null, null] +23398 - null - [null, null, null, null, null] +23399 - null - [null, null, null, null, null] +23400 - null - [null, null, null, null, null] +23401 - null - [null, null, null, null, null] +23402 - null - [null, null, null, null, null] +23403 - null - [null, null, null, null, null] +23404 - null - [null, null, null, null, null] +23405 - null - [null, null, null, null, null] +23406 - null - [null, null, null, null, null] +23407 - null - [null, null, null, null, null] +23408 - null - [null, null, null, null, null] +23409 - null - [null, null, null, null, null] +23410 - null - [null, null, null, null, null] +23411 - null - [null, null, null, null, null] +23412 - null - [null, null, null, null, null] +23413 - null - [null, null, null, null, null] +23414 - null - [null, null, null, null, null] +23415 - null - [null, null, null, null, null] +23416 - null - [null, null, null, null, null] +23417 - null - [null, null, null, null, null] +23418 - null - [null, null, null, null, null] +23419 - null - [null, null, null, null, null] +23420 - null - [null, null, null, null, null] +23421 - null - [null, null, null, null, null] +23422 - null - [null, null, null, null, null] +23423 - null - [null, null, null, null, null] +23424 - null - [null, null, null, null, null] +23425 - null - [null, null, null, null, null] +23426 - null - [null, null, null, null, null] +23427 - null - [null, null, null, null, null] +23428 - null - [null, null, null, null, null] +23429 - null - [null, null, null, null, null] +23430 - null - [null, null, null, null, null] +23431 - null - [null, null, null, null, null] +23432 - null - [null, null, null, null, null] +23433 - null - [null, null, null, null, null] +23434 - null - [null, null, null, null, null] +23435 - null - [null, null, null, null, null] +23436 - null - [null, null, null, null, null] +23437 - null - [null, null, null, null, null] +23438 - null - [null, null, null, null, null] +23439 - null - [null, null, null, null, null] +23440 - null - [null, null, null, null, null] +23441 - null - [null, null, null, null, null] +23442 - null - [null, null, null, null, null] +23443 - null - [null, null, null, null, null] +23444 - null - [null, null, null, null, null] +23445 - null - [null, null, null, null, null] +23446 - null - [null, null, null, null, null] +23447 - null - [null, null, null, null, null] +23448 - null - [null, null, null, null, null] +23449 - null - [null, null, null, null, null] +23450 - null - [null, null, null, null, null] +23451 - null - [null, null, null, null, null] +23452 - null - [null, null, null, null, null] +23453 - null - [null, null, null, null, null] +23454 - null - [null, null, null, null, null] +23455 - null - [null, null, null, null, null] +23456 - null - [null, null, null, null, null] +23457 - null - [null, null, null, null, null] +23458 - null - [null, null, null, null, null] +23459 - null - [null, null, null, null, null] +23460 - null - [null, null, null, null, null] +23461 - null - [null, null, null, null, null] +23462 - null - [null, null, null, null, null] +23463 - null - [null, null, null, null, null] +23464 - null - [null, null, null, null, null] +23465 - null - [null, null, null, null, null] +23466 - null - [null, null, null, null, null] +23467 - null - [null, null, null, null, null] +23468 - null - [null, null, null, null, null] +23469 - null - [null, null, null, null, null] +23470 - null - [null, null, null, null, null] +23471 - null - [null, null, null, null, null] +23472 - null - [null, null, null, null, null] +23473 - null - [null, null, null, null, null] +23474 - null - [null, null, null, null, null] +23475 - null - [null, null, null, null, null] +23476 - null - [null, null, null, null, null] +23477 - null - [null, null, null, null, null] +23478 - null - [null, null, null, null, null] +23479 - null - [null, null, null, null, null] +23480 - null - [null, null, null, null, null] +23481 - null - [null, null, null, null, null] +23482 - null - [null, null, null, null, null] +23483 - null - [null, null, null, null, null] +23484 - null - [null, null, null, null, null] +23485 - null - [null, null, null, null, null] +23486 - null - [null, null, null, null, null] +23487 - null - [null, null, null, null, null] +23488 - null - [null, null, null, null, null] +23489 - null - [null, null, null, null, null] +23490 - null - [null, null, null, null, null] +23491 - null - [null, null, null, null, null] +23492 - null - [null, null, null, null, null] +23493 - null - [null, null, null, null, null] +23494 - null - [null, null, null, null, null] +23495 - null - [null, null, null, null, null] +23496 - null - [null, null, null, null, null] +23497 - null - [null, null, null, null, null] +23498 - null - [null, null, null, null, null] +23499 - Tunnel - [Walk-along, null, null, null, null] +23500 - Tunnel - [null, null, null, null, null] +23501 - null - [null, null, null, null, null] +23502 - null - [null, null, null, null, null] +23503 - null - [null, null, null, null, null] +23504 - Ladder - [Climb-up, null, null, null, null] +23505 - null - [null, null, null, null, null] +23506 - null - [null, null, null, null, null] +23507 - null - [null, null, null, null, null] +23508 - null - [null, null, null, null, null] +23509 - null - [null, null, null, null, null] +23510 - null - [null, null, null, null, null] +23511 - null - [null, null, null, null, null] +23512 - null - [null, null, null, null, null] +23513 - null - [null, null, null, null, null] +23514 - null - [null, null, null, null, null] +23515 - null - [null, null, null, null, null] +23516 - null - [null, null, null, null, null] +23517 - null - [null, null, null, null, null] +23518 - null - [null, null, null, null, null] +23519 - null - [null, null, null, null, null] +23520 - null - [null, null, null, null, null] +23521 - null - [null, null, null, null, null] +23522 - null - [null, null, null, null, null] +23523 - null - [null, null, null, null, null] +23524 - null - [null, null, null, null, null] +23525 - null - [null, null, null, null, null] +23526 - Sample table - [null, null, null, null, null] +23527 - Sample table - [null, null, null, null, null] +23528 - Buried artefact - [null, null, null, null, null] +23529 - Hole - [null, null, null, null, null] +23530 - Crate - [Hide-behind, null, null, null, null] +23531 - Ladder - [Climb-up, null, null, null, null] +23532 - Ladder - [Climb-down, null, null, null, null] +23533 - Crate - [Hide-behind, null, null, null, null] +23534 - null - [null, null, null, null, null] +23535 - null - [null, null, null, null, null] +23536 - null - [null, null, null, null, null] +23537 - null - [null, null, null, null, null] +23538 - null - [null, null, null, null, null] +23539 - null - [null, null, null, null, null] +23540 - null - [null, null, null, null, null] +23541 - null - [null, null, null, null, null] +23542 - Trawler net - [null, null, null, null, null] +23543 - Trawler net - [null, null, null, null, null] +23544 - Trawler net - [null, null, null, null, null] +23545 - Trawler net - [null, null, null, null, null] +23546 - Trawler net - [null, null, null, null, null] +23547 - Trawler net - [null, null, null, null, null] +23548 - Trawler net - [null, null, null, null, null] +23549 - Trawler net - [null, null, null, null, null] +23550 - Trawler net - [null, null, null, null, null] +23551 - Chest - [null, null, null, null, null] +23552 - Chest - [null, null, null, null, null] +23553 - null - [Fill, null, null, null, null] +23554 - Rocks - [Mine, Prospect, hidden, null, null] +23555 - Rocks - [Mine, Prospect, hidden, null, null] +23556 - Rocks - [Mine, Prospect, hidden, null, null] +23557 - Rocks - [Mine, Prospect, hidden, null, null] +23558 - Rocks - [Mine, Prospect, hidden, null, null] +23559 - Rocks - [Mine, Prospect, hidden, null, null] +23560 - Rocks - [Mine, Prospect, hidden, null, null] +23561 - Rocks - [Mine, Prospect, hidden, null, null] +23562 - Rocks - [Mine, Prospect, hidden, null, null] +23563 - Rocks - [Mine, Prospect, hidden, null, null] +23564 - Rocks - [Mine, Prospect, hidden, null, null] +23565 - Rocks - [Mine, Prospect, hidden, null, null] +23566 - Rocks - [Mine, Prospect, hidden, null, null] +23567 - Rocks - [Mine, Prospect, hidden, null, null] +23568 - Rocks - [Mine, Prospect, hidden, null, null] +23569 - Rocks - [Mine, Prospect, hidden, null, null] +23570 - Rocks - [Mine, Prospect, hidden, null, null] +23571 - Rocks - [Mine, Prospect, hidden, null, null] +23572 - null - [null, null, null, null, null] +23573 - null - [null, null, null, null, null] +23574 - null - [null, null, null, null, null] +23575 - null - [null, null, null, null, null] +23576 - null - [null, null, null, null, null] +23577 - null - [null, null, null, null, null] +23578 - null - [null, null, null, null, null] +23579 - null - [null, null, null, null, null] +23580 - null - [null, null, null, null, null] +23581 - null - [null, null, null, null, null] +23582 - null - [null, null, null, null, null] +23583 - null - [null, null, null, null, null] +23584 - Ladder - [Climb-up, null, null, null, null] +23585 - Ladder - [Climb-down, null, null, null, null] +23586 - null - [null, null, null, null, null] +23587 - null - [null, null, null, null, null] +23588 - null - [null, null, null, null, null] +23589 - null - [null, null, null, null, null] +23590 - null - [null, null, null, null, null] +23591 - Kalphite queen legs - [null, null, null, null, null] +23592 - null - [null, null, null, null, null] +23593 - null - [null, null, null, null, null] +23594 - null - [null, null, null, null, null] +23595 - null - [null, null, null, null, null] +23596 - Tunnel - [Enter, null, null, null, null] +23597 - null - [null, null, null, null, null] +23598 - null - [null, null, null, null, null] +23599 - null - [null, null, null, null, null] +23600 - null - [null, null, null, null, null] +23601 - null - [null, null, null, null, null] +23602 - null - [null, null, null, null, null] +23603 - null - [null, null, null, null, null] +23604 - null - [null, null, null, null, null] +23605 - null - [null, null, null, null, null] +23606 - Stalagmites - [null, null, null, null, null] +23607 - Stalagmites - [null, null, null, null, null] +23608 - null - [null, null, null, null, null] +23609 - Tunnel entrance - [null, null, null, null, null] +23610 - Tunnel entrance - [Climb-down, null, null, null, null] +23611 - Cocoon - [hidden, null, null, null, null] +23612 - null - [null, null, null, null, null] +23613 - null - [null, null, null, null, null] +23614 - null - [null, null, null, null, null] +23615 - A cart full of logs - [null, null, null, hidden, null] +23616 - Roses - [null, null, null, null, null] +23617 - null - [null, null, null, null, null] +23618 - null - [null, null, null, null, null] +23619 - null - [null, null, null, null, null] +23620 - null - [null, null, null, null, null] +23621 - null - [null, null, null, null, null] +23622 - null - [null, null, null, null, null] +23623 - null - [null, null, null, null, null] +23624 - Chair - [null, null, null, null, null] +23625 - Cadava bush - [Pick-from, null, null, null, null] +23626 - Cadava bush - [Pick-from, null, null, null, null] +23627 - Cadava bush - [Pick-from, null, null, null, null] +23628 - Redberry bush - [Pick-from, null, null, null, null] +23629 - Redberry bush - [Pick-from, null, null, null, null] +23630 - Redberry bush - [Pick-from, null, null, null, null] +23631 - Door - [null, null, null, null, null] +23632 - Stand - [null, null, null, null, null] +23633 - Newspapers - [null, null, null, null, null] +23634 - Display case - [null, null, null, null, null] +23635 - Display case - [null, null, null, null, null] +23636 - Plaque - [Read, null, null, null, null] +23637 - Door - [null, null, null, null, null] +23638 - null - [null, null, null, null, null] +23639 - null - [null, null, null, null, null] +23640 - Door - [null, null, null, null, null] +23641 - null - [null, null, null, null, null] +23642 - null - [null, null, null, null, null] +23643 - null - [null, null, null, null, null] +23644 - null - [null, null, null, null, null] +23645 - null - [null, null, null, null, null] +23646 - null - [null, null, null, null, null] +23647 - null - [null, null, null, null, null] +23648 - null - [null, null, null, null, null] +23649 - null - [null, null, null, null, null] +23650 - null - [null, null, null, null, null] +23651 - null - [null, null, null, null, null] +23652 - null - [null, null, null, null, null] +23653 - null - [null, null, null, null, null] +23654 - null - [null, null, null, null, null] +23655 - null - [null, null, null, null, null] +23656 - null - [null, null, null, null, null] +23657 - null - [null, null, null, null, null] +23658 - null - [null, null, null, null, null] +23659 - null - [null, null, null, null, null] +23660 - null - [null, null, null, null, null] +23661 - null - [null, null, null, null, null] +23662 - null - [null, null, null, null, null] +23663 - null - [null, null, null, null, null] +23664 - null - [null, null, null, null, null] +23665 - null - [null, null, null, null, null] +23666 - null - [null, null, null, null, null] +23667 - null - [null, null, null, null, null] +23668 - null - [null, null, null, null, null] +23669 - null - [null, null, null, null, null] +23670 - null - [null, null, null, null, null] +23671 - null - [null, null, null, null, null] +23672 - null - [null, null, null, null, null] +23673 - null - [null, null, null, null, null] +23674 - null - [null, null, null, null, null] +23675 - null - [null, null, null, null, null] +23676 - null - [null, null, null, null, null] +23677 - null - [null, null, null, null, null] +23678 - null - [null, null, null, null, null] +23679 - null - [null, null, null, null, null] +23680 - null - [null, null, null, null, null] +23681 - null - [null, null, null, null, null] +23682 - null - [null, null, null, null, null] +23683 - null - [null, null, null, null, null] +23684 - null - [null, null, null, null, null] +23685 - null - [null, null, null, null, null] +23686 - null - [null, null, null, null, null] +23687 - null - [null, null, null, null, null] +23688 - null - [null, null, null, null, null] +23689 - null - [null, null, null, null, null] +23690 - null - [null, null, null, null, null] +23691 - null - [null, null, null, null, null] +23692 - null - [null, null, null, null, null] +23693 - null - [null, null, null, null, null] +23694 - null - [null, null, null, null, null] +23695 - null - [null, null, null, null, null] +23696 - null - [null, null, null, null, null] +23697 - null - [null, null, null, null, null] +23698 - null - [null, null, null, null, null] +23699 - null - [null, null, null, null, null] +23700 - null - [null, null, null, null, null] +23701 - null - [null, null, null, null, null] +23702 - null - [null, null, null, null, null] +23703 - null - [null, null, null, null, null] +23704 - null - [null, null, null, null, null] +23705 - null - [null, null, null, null, null] +23706 - null - [null, null, null, null, null] +23707 - null - [null, null, null, null, null] +23708 - null - [null, null, null, null, null] +23709 - null - [null, null, null, null, null] +23710 - null - [null, null, null, null, null] +23711 - null - [null, null, null, null, null] +23712 - null - [null, null, null, null, null] +23713 - null - [null, null, null, null, null] +23714 - null - [null, null, null, null, null] +23715 - null - [null, null, null, null, null] +23716 - null - [null, null, null, null, null] +23717 - null - [null, null, null, null, null] +23718 - null - [null, null, null, null, null] +23719 - null - [null, null, null, null, null] +23720 - null - [null, null, null, null, null] +23721 - null - [null, null, null, null, null] +23722 - null - [null, null, null, null, null] +23723 - null - [null, null, null, null, null] +23724 - null - [null, null, null, null, null] +23725 - null - [null, null, null, null, null] +23726 - null - [null, null, null, null, null] +23727 - null - [null, null, null, null, null] +23728 - null - [null, null, null, null, null] +23729 - null - [null, null, null, null, null] +23730 - null - [null, null, null, null, null] +23731 - Door - [Open, null, null, null, null] +23732 - null - [null, null, null, null, null] +23733 - null - [null, null, null, null, null] +23734 - null - [null, null, null, null, null] +23735 - null - [null, null, null, null, null] +23736 - null - [null, null, null, null, null] +23737 - null - [null, null, null, null, null] +23738 - null - [null, null, null, null, null] +23739 - null - [null, null, null, null, null] +23740 - null - [null, null, null, null, null] +23741 - null - [null, null, null, null, null] +23742 - null - [null, null, null, null, null] +23743 - null - [null, null, null, null, null] +23744 - null - [null, null, null, null, null] +23745 - null - [null, null, null, null, null] +23746 - null - [null, null, null, null, null] +23747 - null - [null, null, null, null, null] +23748 - null - [null, null, null, null, null] +23749 - null - [null, null, null, null, null] +23750 - null - [null, null, null, null, null] +23751 - null - [null, null, null, null, null] +23752 - null - [null, null, null, null, null] +23753 - null - [null, null, null, null, null] +23754 - null - [null, null, null, null, null] +23755 - null - [null, null, null, null, null] +23756 - null - [null, null, null, null, null] +23757 - null - [null, null, null, null, null] +23758 - null - [null, null, null, null, null] +23759 - null - [null, null, null, null, null] +23760 - null - [null, null, null, null, null] +23761 - null - [null, null, null, null, null] +23762 - null - [null, null, null, null, null] +23763 - null - [null, null, null, null, null] +23764 - null - [null, null, null, null, null] +23765 - null - [null, null, null, null, null] +23766 - null - [null, null, null, null, null] +23767 - null - [null, null, null, null, null] +23768 - null - [null, null, null, null, null] +23769 - null - [null, null, null, null, null] +23770 - null - [null, null, null, null, null] +23771 - null - [null, null, null, null, null] +23772 - null - [null, null, null, null, null] +23773 - null - [null, null, null, null, null] +23774 - null - [null, null, null, null, null] +23775 - null - [null, null, null, null, null] +23776 - null - [null, null, null, null, null] +23777 - null - [null, null, null, null, null] +23778 - null - [null, null, null, null, null] +23779 - null - [null, null, null, null, null] +23780 - null - [null, null, null, null, null] +23781 - null - [null, null, null, null, null] +23782 - null - [null, null, null, null, null] +23783 - null - [null, null, null, null, null] +23784 - null - [null, null, null, null, null] +23785 - null - [null, null, null, null, null] +23786 - null - [null, null, null, null, null] +23787 - null - [null, null, null, null, null] +23788 - null - [null, null, null, null, null] +23789 - null - [null, null, null, null, null] +23790 - null - [null, null, null, null, null] +23791 - null - [null, null, null, null, null] +23792 - null - [null, null, null, null, null] +23793 - null - [null, null, null, null, null] +23794 - null - [null, null, null, null, null] +23795 - null - [null, null, null, null, null] +23796 - null - [null, null, null, null, null] +23797 - null - [null, null, null, null, null] +23798 - null - [null, null, null, null, null] +23799 - null - [null, null, null, null, null] +23800 - null - [null, null, null, null, null] +23801 - null - [null, null, null, null, null] +23802 - null - [null, null, null, null, null] +23803 - null - [null, null, null, null, null] +23804 - null - [null, null, null, null, null] +23805 - null - [null, null, null, null, null] +23806 - null - [null, null, null, null, null] +23807 - null - [null, null, null, null, null] +23808 - null - [null, null, null, null, null] +23809 - null - [null, null, null, null, null] +23810 - null - [null, null, null, null, null] +23811 - null - [null, null, null, null, null] +23812 - null - [null, null, null, null, null] +23813 - null - [null, null, null, null, null] +23814 - null - [null, null, null, null, null] +23815 - null - [null, null, null, null, null] +23816 - null - [null, null, null, null, null] +23817 - null - [null, null, null, null, null] +23818 - null - [null, null, null, null, null] +23819 - null - [null, null, null, null, null] +23820 - null - [null, null, null, null, null] +23821 - null - [null, null, null, null, null] +23822 - null - [null, null, null, null, null] +23823 - null - [null, null, null, null, null] +23824 - null - [null, null, null, null, null] +23825 - null - [null, null, null, null, null] +23826 - null - [null, null, null, null, null] +23827 - null - [null, null, null, null, null] +23828 - null - [null, null, null, null, null] +23829 - null - [null, null, null, null, null] +23830 - null - [null, null, null, null, null] +23831 - null - [null, null, null, null, null] +23832 - null - [null, null, null, null, null] +23833 - null - [null, null, null, null, null] +23834 - null - [null, null, null, null, null] +23835 - null - [null, null, null, null, null] +23836 - null - [null, null, null, null, null] +23837 - null - [null, null, null, null, null] +23838 - null - [null, null, null, null, null] +23839 - null - [null, null, null, null, null] +23840 - null - [null, null, null, null, null] +23841 - null - [null, null, null, null, null] +23842 - null - [null, null, null, null, null] +23843 - null - [null, null, null, null, null] +23844 - null - [null, null, null, null, null] +23845 - null - [null, null, null, null, null] +23846 - null - [null, null, null, null, null] +23847 - null - [null, null, null, null, null] +23848 - null - [null, null, null, null, null] +23849 - null - [null, null, null, null, null] +23850 - null - [null, null, null, null, null] +23851 - null - [null, null, null, null, null] +23852 - null - [null, null, null, null, null] +23853 - null - [null, null, null, null, null] +23854 - null - [null, null, null, null, null] +23855 - null - [null, null, null, null, null] +23856 - null - [null, null, null, null, null] +23857 - null - [null, null, null, null, null] +23858 - null - [null, null, null, null, null] +23859 - null - [null, null, null, null, null] +23860 - null - [null, null, null, null, null] +23861 - null - [null, null, null, null, null] +23862 - null - [null, null, null, null, null] +23863 - null - [null, null, null, null, null] +23864 - null - [null, null, null, null, null] +23865 - null - [null, null, null, null, null] +23866 - null - [null, null, null, null, null] +23867 - null - [null, null, null, null, null] +23868 - null - [null, null, null, null, null] +23869 - null - [null, null, null, null, null] +23870 - null - [null, null, null, null, null] +23871 - null - [null, null, null, null, null] +23872 - null - [null, null, null, null, null] +23873 - null - [null, null, null, null, null] +23874 - null - [null, null, null, null, null] +23875 - null - [null, null, null, null, null] +23876 - null - [null, null, null, null, null] +23877 - null - [null, null, null, null, null] +23878 - null - [null, null, null, null, null] +23879 - null - [null, null, null, null, null] +23880 - null - [null, null, null, null, null] +23881 - null - [null, null, null, null, null] +23882 - null - [null, null, null, null, null] +23883 - null - [null, null, null, null, null] +23884 - null - [null, null, null, null, null] +23885 - null - [null, null, null, null, null] +23886 - null - [null, null, null, null, null] +23887 - null - [null, null, null, null, null] +23888 - null - [null, null, null, null, null] +23889 - null - [null, null, null, null, null] +23890 - null - [null, null, null, null, null] +23891 - null - [null, null, null, null, null] +23892 - null - [null, null, null, null, null] +23893 - null - [null, null, null, null, null] +23894 - null - [null, null, null, null, null] +23895 - null - [null, null, null, null, null] +23896 - null - [null, null, null, null, null] +23897 - null - [null, null, null, null, null] +23898 - null - [null, null, null, null, null] +23899 - null - [null, null, null, null, null] +23900 - null - [null, null, null, null, null] +23901 - null - [null, null, null, null, null] +23902 - null - [null, null, null, null, null] +23903 - null - [null, null, null, null, null] +23904 - null - [null, null, null, null, null] +23905 - null - [null, null, null, null, null] +23906 - null - [null, null, null, null, null] +23907 - null - [null, null, null, null, null] +23908 - null - [null, null, null, null, null] +23909 - null - [null, null, null, null, null] +23910 - null - [null, null, null, null, null] +23911 - null - [null, null, null, null, null] +23912 - null - [null, null, null, null, null] +23913 - null - [null, null, null, null, null] +23914 - null - [null, null, null, null, null] +23915 - null - [null, null, null, null, null] +23916 - null - [null, null, null, null, null] +23917 - Gate - [Open, null, null, null, null] +23918 - Gate - [Close, null, null, null, null] +23919 - Gate - [Close, null, null, null, null] +23920 - Pump and drain - [null, null, null, null, null] +23921 - Dummy - [Attack, null, null, null, null] +23922 - null - [null, null, null, null, null] +23923 - null - [null, null, null, null, null] +23924 - Leaflets - [null, null, null, null, null] +23925 - Chest - [null, null, null, null, null] +23926 - Chest - [null, null, null, null, null] +23927 - null - [null, null, null, null, null] +23928 - Bank table - [null, null, null, null, null] +23929 - Gold - [null, null, null, null, null] +23930 - Statue - [null, null, null, null, null] +23931 - null - [null, null, null, null, null] +23932 - null - [null, null, null, null, null] +23933 - Chandelier - [null, null, null, null, null] +23934 - null - [null, null, null, null, null] +23935 - null - [null, null, null, null, null] +23936 - null - [null, null, null, null, null] +23937 - null - [null, null, null, null, null] +23938 - null - [null, null, null, null, null] +23939 - Safe - [null, null, null, null, null] +23940 - Rack - [null, null, null, null, null] +23941 - Barrel - [null, null, null, null, null] +23942 - Table - [null, null, null, null, null] +23943 - Barrel - [null, null, null, null, null] +23944 - Rack - [null, null, null, null, null] +23945 - null - [null, null, null, null, null] +23946 - null - [null, null, null, null, null] +23947 - Bellows - [null, null, null, null, null] +23948 - null - [null, null, null, null, null] +23949 - null - [null, null, null, null, null] +23950 - null - [null, null, null, null, null] +23951 - Metal pieces - [null, null, null, null, null] +23952 - null - [null, null, null, null, null] +23953 - null - [null, null, null, null, null] +23954 - null - [null, null, null, null, null] +23955 - Chimney - [null, null, null, null, null] +23956 - null - [null, null, null, null, null] +23957 - null - [null, null, null, null, null] +23958 - null - [null, null, null, null, null] +23959 - null - [null, null, null, null, null] +23960 - Workbench - [null, null, null, null, null] +23961 - Lathe - [null, null, null, null, null] +23962 - Drill - [null, null, null, null, null] +23963 - Hearth - [null, null, null, null, null] +23964 - Mould - [null, null, null, null, null] +23965 - Poster - [null, null, null, null, null] +23966 - null - [null, null, null, null, null] +23967 - Sign - [null, null, null, null, null] +23968 - Sign - [null, null, null, null, null] +23969 - Sign - [null, null, null, null, null] +23970 - Sign - [null, null, null, null, null] +23971 - null - [null, null, null, null, null] +23972 - Sign - [null, null, null, null, null] +23973 - null - [null, null, null, null, null] +23974 - Sign - [null, null, null, null, null] +23975 - null - [null, null, null, null, null] +23976 - null - [null, null, null, null, null] +23977 - Sign - [null, null, null, null, null] +23978 - Sign - [null, null, null, null, null] +23979 - null - [null, null, null, null, null] +23980 - Sign - [null, null, null, null, null] +23981 - null - [null, null, null, null, null] +23982 - Sign - [null, null, null, null, null] +23983 - Market stall - [null, null, null, null, null] +23984 - Market stall - [null, null, null, null, null] +23985 - Market stall - [null, null, null, null, null] +23986 - Market stall - [null, null, null, null, null] +23987 - Market stall - [null, null, null, null, null] +23988 - Scuttle - [null, null, null, null, null] +23989 - Pokers - [null, null, null, null, null] +23990 - null - [null, null, null, null, null] +23991 - null - [null, null, null, null, null] +23992 - null - [null, null, null, null, null] +23993 - Bar - [null, null, null, null, null] +23994 - Bar - [null, null, null, null, null] +23995 - Bar - [null, null, null, null, null] +23996 - Bar - [null, null, null, null, null] +23997 - Bar - [null, null, null, null, null] +23998 - Bar - [null, null, null, null, null] +23999 - Bar - [null, null, null, null, null] +24000 - Bar - [null, null, null, null, null] +24001 - Bar - [null, null, null, null, null] +24002 - null - [null, null, null, null, null] +24003 - null - [null, null, null, null, null] +24004 - null - [null, null, null, null, null] +24005 - null - [null, null, null, null, null] +24006 - null - [null, null, null, null, null] +24007 - null - [null, null, null, null, null] +24008 - null - [null, null, null, null, null] +24009 - null - [null, null, null, null, null] +24010 - null - [null, null, null, null, null] +24011 - Table - [null, null, null, null, null] +24012 - Table - [null, null, null, null, null] +24013 - Table - [null, null, null, null, null] +24014 - Table - [null, null, null, null, null] +24015 - null - [null, null, null, null, null] +24016 - Wine rack - [null, null, null, null, null] +24017 - null - [null, null, null, null, null] +24018 - null - [null, null, null, null, null] +24019 - null - [null, null, null, null, null] +24020 - null - [null, null, null, null, null] +24021 - null - [null, null, null, null, null] +24022 - null - [null, null, null, null, null] +24023 - null - [null, null, null, null, null] +24024 - null - [null, null, null, null, null] +24025 - Lamp - [null, null, null, null, null] +24026 - Lantern - [null, null, null, null, null] +24027 - Sewing machine - [null, null, null, null, null] +24028 - Table - [null, null, null, null, null] +24029 - null - [null, null, null, null, null] +24030 - Clothes - [null, null, null, null, null] +24031 - Cloth - [null, null, null, null, null] +24032 - null - [null, null, null, null, null] +24033 - Oil lamp - [null, null, null, null, null] +24034 - Fabric - [null, null, null, null, null] +24035 - Fabric - [null, null, null, null, null] +24036 - null - [null, null, null, null, null] +24037 - null - [null, null, null, null, null] +24038 - null - [null, null, null, null, null] +24039 - null - [null, null, null, null, null] +24040 - null - [null, null, null, null, null] +24041 - null - [null, null, null, null, null] +24042 - null - [null, null, null, null, null] +24043 - Bed - [null, null, null, null, null] +24044 - Clothes - [null, null, null, null, null] +24045 - Clothes - [null, null, null, null, null] +24046 - Clothes - [null, null, null, null, null] +24047 - Clothes - [null, null, null, null, null] +24048 - Clothes - [null, null, null, null, null] +24049 - Clothes - [null, null, null, null, null] +24050 - Clothes - [null, null, null, null, null] +24051 - null - [null, null, null, null, null] +24052 - null - [null, null, null, null, null] +24053 - null - [null, null, null, null, null] +24054 - null - [null, null, null, null, null] +24055 - null - [null, null, null, null, null] +24056 - null - [null, null, null, null, null] +24057 - null - [null, null, null, null, null] +24058 - null - [null, null, null, null, null] +24059 - null - [null, null, null, null, null] +24060 - null - [null, null, null, null, null] +24061 - null - [null, null, null, null, null] +24062 - null - [null, null, null, null, null] +24063 - null - [null, null, null, null, null] +24064 - null - [null, null, null, null, null] +24065 - Sails - [null, null, null, null, null] +24066 - Mill - [null, null, null, null, null] +24067 - Mill - [null, null, null, null, null] +24068 - Mill - [null, null, null, null, null] +24069 - Mill - [null, null, null, null, null] +24070 - Flour bin - [Empty, null, null, null, null] +24071 - Hopper - [null, null, null, null, null] +24072 - Hopper controls - [Operate, null, null, null, null] +24073 - Staircase - [Climb-up, null, null, null, null] +24074 - Staircase - [Climb, Climb-up, Climb-down, null, null] +24075 - Staircase - [Climb-down, null, null, null, null] +24076 - Table - [null, null, null, null, null] +24077 - null - [null, null, null, null, null] +24078 - null - [null, null, null, null, null] +24079 - Shelves - [null, null, null, null, null] +24080 - Shelves - [null, null, null, null, null] +24081 - Picture - [null, null, null, null, null] +24082 - Picture - [null, null, null, null, null] +24083 - Picture - [null, null, null, null, null] +24084 - Table - [null, null, null, null, null] +24085 - Shelves - [Search, null, null, null, null] +24086 - Shelves - [Search, null, null, null, null] +24087 - Study desk - [Search, null, null, null, null] +24088 - Table - [null, null, null, null, null] +24089 - null - [null, null, null, null, null] +24090 - Dead bat - [null, null, null, null, null] +24091 - Herbs - [null, null, null, null, null] +24092 - Cabinet - [null, null, null, null, null] +24093 - Cabinet - [null, null, null, null, null] +24094 - Swings - [null, null, null, null, null] +24095 - Washing line - [null, null, null, null, null] +24096 - Toy bricks - [null, null, null, null, null] +24097 - Toy weapons - [null, null, null, null, null] +24098 - Cat basket - [null, null, null, null, null] +24099 - Bunkbed - [null, null, null, null, null] +24100 - Flowerbed - [null, null, null, null, null] +24101 - Flowerbed - [null, null, null, null, null] +24102 - null - [null, null, null, null, null] +24103 - null - [null, null, null, null, null] +24104 - Table - [null, null, null, null, null] +24105 - Sword cabinet - [null, null, null, null, null] +24106 - Sword in stone - [null, null, null, null, null] +24107 - null - [null, null, null, null, null] +24108 - null - [null, null, null, null, null] +24109 - Sword case - [null, null, null, null, null] +24110 - Sword case - [null, null, null, null, null] +24111 - Sword case - [null, null, null, null, null] +24112 - Sink - [null, null, null, null, null] +24113 - Dishes - [null, null, null, null, null] +24114 - Dishes - [null, null, null, null, null] +24115 - Dishes - [null, null, null, null, null] +24116 - Sword case - [null, null, null, null, null] +24117 - Poster - [null, null, null, null, null] +24118 - Poster - [null, null, null, null, null] +24119 - Poster - [null, null, null, null, null] +24120 - null - [null, null, null, null, null] +24121 - null - [null, null, null, null, null] +24122 - Stepladder - [null, null, null, null, null] +24123 - null - [null, null, null, null, null] +24124 - Shop counter - [null, null, null, null, null] +24125 - null - [null, null, null, null, null] +24126 - null - [null, null, null, null, null] +24127 - Notices - [null, null, null, null, null] +24128 - null - [null, null, null, null, null] +24129 - null - [null, null, null, null, null] +24130 - null - [null, null, null, null, null] +24131 - null - [null, null, null, null, null] +24132 - null - [null, null, null, null, null] +24133 - null - [null, null, null, null, null] +24134 - Bow cabinet - [null, null, null, null, null] +24135 - Workbench - [null, null, null, null, null] +24136 - null - [null, null, null, null, null] +24137 - null - [null, null, null, null, null] +24138 - Bow case - [null, null, null, null, null] +24139 - Crate - [null, null, null, null, null] +24140 - Crate - [null, null, null, null, null] +24141 - Wood - [null, null, null, null, null] +24142 - Barrel - [null, null, null, null, null] +24143 - Poster - [null, null, null, null, null] +24144 - Poster - [null, null, null, null, null] +24145 - null - [null, null, null, null, null] +24146 - null - [null, null, null, null, null] +24147 - Mannequin - [null, null, null, null, null] +24148 - Bookcase - [null, null, null, null, null] +24149 - null - [null, null, null, null, null] +24150 - null - [null, null, null, null, null] +24151 - null - [null, null, null, null, null] +24152 - null - [null, null, null, null, null] +24153 - Cart - [null, null, null, null, null] +24154 - null - [null, null, null, null, null] +24155 - null - [null, null, null, null, null] +24156 - null - [null, null, null, null, null] +24157 - null - [null, null, null, null, null] +24158 - null - [null, null, null, null, null] +24159 - null - [null, null, null, null, null] +24160 - Waterpump - [null, null, null, null, null] +24161 - Fountain - [null, null, null, null, null] +24162 - Statue - [null, null, null, null, null] +24163 - Statue - [null, null, null, null, null] +24164 - Trough - [null, null, null, null, null] +24165 - Plough - [null, null, null, null, null] +24166 - Well - [null, null, null, null, null] +24167 - Spear wall - [null, null, null, null, null] +24168 - Dying tree - [Chop down, null, hidden, null, null] +24169 - Dying tree Stump - [null, null, null, null, null] +24170 - Washing Line - [null, null, null, null, null] +24171 - Washing Line - [null, null, null, null, null] +24172 - Washing Line - [null, null, null, null, null] +24173 - null - [null, null, null, null, null] +24174 - null - [null, null, null, null, null] +24175 - null - [null, null, null, null, null] +24176 - null - [null, null, null, null, null] +24177 - null - [null, null, null, null, null] +24178 - null - [null, null, null, null, null] +24179 - null - [null, null, null, null, null] +24180 - null - [null, null, null, null, null] +24181 - null - [null, null, null, null, null] +24182 - null - [null, null, null, null, null] +24183 - Painting - [null, null, null, null, null] +24184 - Painting - [null, null, null, null, null] +24185 - null - [null, null, null, null, null] +24186 - null - [null, null, null, null, null] +24187 - null - [null, null, null, null, null] +24188 - null - [null, null, null, null, null] +24189 - null - [null, null, null, null, null] +24190 - null - [null, null, null, null, null] +24191 - null - [null, null, null, null, null] +24192 - Combat Scroll - [Read, null, null, null, null] +24193 - null - [null, null, null, null, null] +24194 - Smoking vent - [null, null, null, null, null] +24195 - Smoking vent - [null, null, null, null, null] +24196 - null - [null, null, null, null, null] +24197 - null - [null, null, null, null, null] +24198 - null - [null, null, null, null, null] +24199 - null - [null, null, null, null, null] +24200 - Shield - [null, null, null, null, null] +24201 - null - [null, null, null, null, null] +24202 - null - [null, null, null, null, null] +24203 - Closed chest - [Open, null, null, null, null] +24204 - Open chest - [Search, Shut, null, null, null] +24205 - Crate - [Search, null, null, null, null] +24206 - Boxes - [Search, null, null, null, null] +24207 - Barrel - [null, null, null, null, null] +24208 - Crate - [Search, null, null, null, null] +24209 - Barrel - [null, null, null, null, null] +24210 - null - [Search, null, null, null, null] +24211 - Barrel - [null, null, null, null, null] +24212 - Barrel - [null, null, null, null, null] +24213 - null - [null, null, null, null, null] +24214 - Fountain - [null, null, null, null, null] +24215 - Suit of armour - [null, null, null, null, null] +24216 - Standard - [null, null, null, null, null] +24217 - null - [null, null, null, null, null] +24218 - null - [null, null, null, null, null] +24219 - null - [null, null, null, null, null] +24220 - null - [null, null, null, null, null] +24221 - null - [null, null, null, null, null] +24222 - null - [null, null, null, null, null] +24223 - null - [null, null, null, null, null] +24224 - null - [null, null, null, null, null] +24225 - null - [null, null, null, null, null] +24226 - null - [null, null, null, null, null] +24227 - null - [null, null, null, null, null] +24228 - null - [null, null, null, null, null] +24229 - null - [null, null, null, null, null] +24230 - null - [null, null, null, null, null] +24231 - null - [null, null, null, null, null] +24232 - Paper - [null, null, null, null, null] +24233 - Paper - [null, null, null, null, null] +24234 - Drain - [null, null, null, null, null] +24235 - Drain - [null, null, null, null, null] +24236 - null - [null, null, null, null, null] +24237 - null - [null, null, null, null, null] +24238 - null - [null, null, null, null, null] +24239 - null - [null, null, null, null, null] +24240 - null - [null, null, null, null, null] +24241 - null - [null, null, null, null, null] +24242 - null - [null, null, null, null, null] +24243 - null - [null, null, null, null, null] +24244 - null - [null, null, null, null, null] +24245 - null - [null, null, null, null, null] +24246 - null - [null, null, null, null, null] +24247 - null - [null, null, null, null, null] +24248 - null - [null, null, null, null, null] +24249 - null - [null, null, null, null, null] +24250 - null - [null, null, null, null, null] +24251 - null - [null, null, null, null, null] +24252 - Rotten food - [null, null, null, null, null] +24253 - Rotten food - [null, null, null, null, null] +24254 - Rotten food - [null, null, null, null, null] +24255 - Rat - [null, null, null, null, null] +24256 - Mushroom - [null, null, null, null, null] +24257 - Mushrooms - [null, null, null, null, null] +24258 - Mushroom - [null, null, null, null, null] +24259 - Cannon - [null, null, null, null, null] +24260 - Banner - [null, null, null, null, null] +24261 - null - [null, null, null, null, null] +24262 - null - [null, null, null, null, null] +24263 - Signpost - [Read, null, null, null, null] +24264 - Hole - [Climb-down, null, null, null, null] +24265 - Fountain - [null, null, null, null, null] +24266 - null - [null, null, null, null, null] +24267 - null - [null, null, null, null, null] +24268 - null - [null, null, null, null, null] +24269 - null - [null, null, null, null, null] +24270 - null - [null, null, null, null, null] +24271 - null - [null, null, null, null, null] +24272 - null - [null, null, null, null, null] +24273 - null - [null, null, null, null, null] +24274 - null - [null, null, null, null, null] +24275 - null - [null, null, null, null, null] +24276 - null - [null, null, null, null, null] +24277 - null - [null, null, null, null, null] +24278 - null - [null, null, null, null, null] +24279 - null - [null, null, null, null, null] +24280 - null - [null, null, null, null, null] +24281 - Bookcase - [Search, null, null, null, null] +24282 - Bookcase - [Search, null, null, null, null] +24283 - Range - [null, null, null, null, null] +24284 - Range - [null, null, null, null, null] +24285 - Fireplace - [null, null, null, null, null] +24286 - null - [null, null, null, null, null] +24287 - Chair - [null, null, null, null, null] +24288 - Bed - [null, null, null, null, null] +24289 - Bed - [null, null, null, null, null] +24290 - Bed - [null, null, null, null, null] +24291 - Bed - [null, null, null, null, null] +24292 - Chest - [null, null, null, null, null] +24293 - Wardrobe - [null, null, null, null, null] +24294 - Drawers - [Open, null, null, null, null] +24295 - Drawers - [Search, Close, null, null, null] +24296 - Dresser - [null, null, null, null, null] +24297 - Wardrobe - [null, null, null, null, null] +24298 - Wardrobe - [null, null, null, null, null] +24299 - Bed - [null, null, null, null, null] +24300 - Mossy rock - [Search, null, null, null, null] +24301 - Table - [null, null, null, null, null] +24302 - Table - [null, null, null, null, null] +24303 - Table - [null, null, null, null, null] +24304 - Chair - [null, null, null, null, null] +24305 - Teak table - [null, null, null, null, null] +24306 - Teak table - [null, null, null, null, null] +24307 - Table - [null, null, null, null, null] +24308 - Table - [null, null, null, null, null] +24309 - Table - [null, null, null, null, null] +24310 - Throne - [null, null, null, null, null] +24311 - Cabinet - [null, null, null, null, null] +24312 - Cabinet - [null, null, null, null, null] +24313 - Oven - [null, null, null, null, null] +24314 - Sink - [null, null, null, null, null] +24315 - Larder - [null, null, null, null, null] +24316 - Dresser - [null, null, null, null, null] +24317 - Mirror - [null, null, null, null, null] +24318 - Bath screen - [null, null, null, null, null] +24319 - Bathtub - [null, null, null, null, null] +24320 - Table - [null, null, null, null, null] +24321 - Bench - [null, null, null, null, null] +24322 - Drawers - [Search, Close, null, null, null] +24323 - Piano - [null, null, null, null, null] +24324 - Piano stool - [null, null, null, null, null] +24325 - null - [null, null, null, null, null] +24326 - null - [null, null, null, null, null] +24327 - null - [null, null, null, null, null] +24328 - Cooking pot - [null, null, null, null, null] +24329 - Fireplace - [null, null, null, null, null] +24330 - null - [null, null, null, null, null] +24331 - null - [null, null, null, null, null] +24332 - null - [null, null, null, null, null] +24333 - Chair - [null, null, null, null, null] +24334 - Chair - [null, null, null, null, null] +24335 - Table - [null, null, null, null, null] +24336 - Table - [null, null, null, null, null] +24337 - Chest - [null, null, null, null, null] +24338 - Bed - [null, null, null, null, null] +24339 - Bunk bed - [null, null, null, null, null] +24340 - Trunk - [null, null, null, null, null] +24341 - Locker - [null, null, null, null, null] +24342 - Saradomin star - [null, null, null, null, null] +24343 - Altar - [Pray-at, null, null, null, null] +24344 - Church pew - [null, null, null, null, null] +24345 - null - [null, null, null, null, null] +24346 - null - [null, null, null, null, null] +24347 - null - [null, null, null, null, null] +24348 - Candles - [null, null, null, null, null] +24349 - Staircase - [Climb-up, null, null, null, null] +24350 - Staircase - [Climb-up, null, null, null, null] +24351 - Staircase - [Climb, Climb-up, Climb-down, null, null] +24352 - Staircase - [Climb, Climb-up, Climb-down, null, null] +24353 - Staircase - [Climb-down, null, null, null, null] +24354 - Ladder - [Climb-up, null, null, null, null] +24355 - Ladder - [Climb-down, null, null, null, null] +24356 - Staircase - [Climb-up, null, null, null, null] +24357 - Staircase - [Climb-up, null, null, null, null] +24358 - Staircase - [Climb-up, null, null, null, null] +24359 - Staircase - [Climb-down, null, null, null, null] +24360 - Staircase - [Climb-down, null, null, null, null] +24361 - Ladder - [Climb-up, null, null, null, null] +24362 - Ladder - [Climb-down, null, null, null, null] +24363 - Ladder - [Climb-down, null, null, null, null] +24364 - Ladder - [Climb-up, null, null, null, null] +24365 - Staircase - [Climb-up, null, null, null, null] +24366 - Ladder - [Climb-up, null, null, null, null] +24367 - Staircase - [Climb-up, null, null, null, null] +24368 - Door - [null, null, null, null, null] +24369 - Gate - [Open, null, null, null, null] +24370 - Gate - [Open, null, null, null, null] +24371 - null - [null, null, null, null, null] +24372 - null - [null, null, null, null, null] +24373 - Gate - [Close, null, null, null, null] +24374 - Gate - [Close, null, null, null, null] +24375 - Door - [Close, null, null, null, null] +24376 - Door - [Open, null, null, null, null] +24377 - Door - [Close, null, null, null, null] +24378 - Door - [Open, null, null, null, null] +24379 - Door - [Close, null, null, null, null] +24380 - null - [null, null, null, null, null] +24381 - Door - [Open, null, null, null, null] +24382 - Door - [null, null, null, null, null] +24383 - Door - [Close, null, null, null, null] +24384 - Door - [Open, null, null, null, null] +24385 - null - [null, null, null, null, null] +24386 - null - [null, null, null, null, null] +24387 - null - [null, null, null, null, null] +24388 - null - [null, null, null, null, null] +24389 - Door - [Knock-at, null, null, null, null] +24390 - Map - [Look-at, Take, null, null, null] +24391 - Map - [Look-at, Take, null, null, null] +24392 - Map - [Look-at, Take, null, null, null] +24393 - null - [null, null, null, null, null] +24394 - null - [null, null, null, null, null] +24395 - null - [null, null, null, null, null] +24396 - null - [null, null, null, null, null] +24397 - null - [null, null, null, null, null] +24398 - null - [null, null, null, null, null] +24399 - null - [null, null, null, null, null] +24400 - null - [null, null, null, null, null] +24401 - null - [null, null, null, null, null] +24402 - null - [null, null, null, null, null] +24403 - null - [null, null, null, null, null] +24404 - null - [null, null, null, null, null] +24405 - null - [null, null, null, null, null] +24406 - null - [null, null, null, null, null] +24407 - null - [null, null, null, null, null] +24408 - null - [null, null, null, null, null] +24409 - null - [null, null, null, null, null] +24410 - null - [null, null, null, null, null] +24411 - null - [null, null, null, null, null] +24412 - null - [null, null, null, null, null] +24413 - null - [null, null, null, null, null] +24414 - null - [null, null, null, null, null] +24415 - null - [null, null, null, null, null] +24416 - null - [null, null, null, null, null] +24417 - null - [null, null, null, null, null] +24418 - null - [null, null, null, null, null] +24419 - null - [null, null, null, null, null] +24420 - null - [null, null, null, null, null] +24421 - null - [null, null, null, null, null] +24422 - null - [null, null, null, null, null] +24423 - null - [null, null, null, null, null] +24424 - null - [null, null, null, null, null] +24425 - null - [null, null, null, null, null] +24426 - null - [null, null, null, null, null] +24427 - Stairs - [Walk-up, null, null, null, null] +24428 - Stairs - [Walk-down, null, null, null, null] +24429 - null - [null, null, null, null, null] +24430 - null - [null, null, null, null, null] +24431 - null - [null, null, null, null, null] +24432 - null - [null, null, null, null, null] +24433 - null - [null, null, null, null, null] +24434 - null - [null, null, null, null, null] +24435 - null - [null, null, null, null, null] +24436 - null - [null, null, null, null, null] +24437 - null - [null, null, null, null, null] +24438 - null - [null, null, null, null, null] +24439 - null - [null, null, null, null, null] +24440 - null - [null, null, null, null, null] +24441 - null - [null, null, null, null, null] +24442 - null - [null, null, null, null, null] +24443 - null - [null, null, null, null, null] +24444 - null - [null, null, null, null, null] +24445 - null - [null, null, null, null, null] +24446 - null - [null, null, null, null, null] +24447 - null - [null, null, null, null, null] +24448 - null - [null, null, null, null, null] +24449 - null - [null, null, null, null, null] +24450 - null - [null, null, null, null, null] +24451 - null - [null, null, null, null, null] +24452 - Information booth - [Look-at, null, null, null, null] +24453 - null - [null, null, null, null, null] +24454 - null - [null, null, null, null, null] +24455 - Canal barge - [null, null, null, null, null] +24456 - Canal barge - [null, null, null, null, null] +24457 - Canal barge - [null, null, null, null, null] +24458 - Canal barge - [null, null, null, null, null] +24459 - Canal barge - [null, null, null, null, null] +24460 - Canal barge - [null, null, null, null, null] +24461 - Canal barge - [null, null, null, null, null] +24462 - Canal barge - [null, null, null, null, null] +24463 - Canal barge - [null, null, null, null, null] +24464 - Canal barge - [null, null, null, null, null] +24465 - Canal barge - [null, null, null, null, null] +24466 - Canal barge - [null, null, null, null, null] +24467 - Canal barge - [null, null, null, null, null] +24468 - Canal barge - [null, null, null, null, null] +24469 - Canal barge - [null, null, null, null, null] +24470 - Canal barge - [null, null, null, null, null] +24471 - Canal barge - [null, null, null, null, null] +24472 - Canal barge - [null, null, null, null, null] +24473 - Canal barge - [null, null, null, null, null] +24474 - Canal barge - [null, null, null, null, null] +24475 - Canal barge - [null, null, null, null, null] +24476 - Canal barge - [null, null, null, null, null] +24477 - Canal barge - [null, null, null, null, null] +24478 - Canal barge - [null, null, null, null, null] +24479 - Canal barge - [null, null, null, null, null] +24480 - Canal barge - [null, null, null, null, null] +24481 - Canal barge - [null, null, null, null, null] +24482 - Canal barge - [null, null, null, null, null] +24483 - Canal barge - [null, null, null, null, null] +24484 - Canal barge - [null, null, null, null, null] +24485 - Canal barge - [null, null, null, null, null] +24486 - Canal barge - [null, null, null, null, null] +24487 - Canal wall - [null, null, null, null, null] +24488 - Canal wall - [null, null, null, null, null] +24489 - null - [null, null, null, null, null] +24490 - null - [null, null, null, null, null] +24491 - null - [null, null, null, null, null] +24492 - null - [null, null, null, null, null] +24493 - null - [null, null, null, null, null] +24494 - null - [null, null, null, null, null] +24495 - null - [null, null, null, null, null] +24496 - null - [null, null, null, null, null] +24497 - null - [null, null, null, null, null] +24498 - null - [null, null, null, null, null] +24499 - null - [null, null, null, null, null] +24500 - Tar buckets - [null, null, null, null, null] +24501 - Short planks - [null, null, null, null, null] +24502 - Long planks - [null, null, null, null, null] +24503 - Canal barge - [null, null, null, null, null] +24504 - Canal barge - [null, null, null, null, null] +24505 - Canal barge - [null, null, null, null, null] +24506 - Canal barge - [null, null, null, null, null] +24507 - Canal barge - [null, null, null, null, null] +24508 - Canal barge - [null, null, null, null, null] +24509 - Canal barge - [null, null, null, null, null] +24510 - Canal barge - [null, null, null, null, null] +24511 - Canal barge - [null, null, null, null, null] +24512 - Canal barge - [null, null, null, null, null] +24513 - Canal barge - [null, null, null, null, null] +24514 - Canal barge - [null, null, null, null, null] +24515 - Canal barge - [null, null, null, null, null] +24516 - Canal barge - [null, null, null, null, null] +24517 - Canal barge - [null, null, null, null, null] +24518 - Canal barge - [null, null, null, null, null] +24519 - Canal barge - [null, null, null, null, null] +24520 - Canal barge - [null, null, null, null, null] +24521 - Canal barge - [null, null, null, null, null] +24522 - Canal barge - [null, null, null, null, null] +24523 - Canal barge - [null, null, null, null, null] +24524 - Canal barge - [null, null, null, null, null] +24525 - Canal barge - [null, null, null, null, null] +24526 - Canal barge - [null, null, null, null, null] +24527 - Canal barge - [null, null, null, null, null] +24528 - Canal barge - [null, null, null, null, null] +24529 - Canal barge - [null, null, null, null, null] +24530 - Canal barge - [null, null, null, null, null] +24531 - Canal wall - [null, null, null, null, null] +24532 - Canal wall - [null, null, null, null, null] +24533 - null - [null, null, null, null, null] +24534 - Storage crate - [null, null, null, null, null] +24535 - Tools - [Take, null, null, null, null] +24536 - Gate - [Open, null, null, null, null] +24537 - null - [null, null, null, null, null] +24538 - null - [null, null, null, null, null] +24539 - Display case - [Study, null, null, null, null] +24540 - Display case - [Study, null, null, null, null] +24541 - Display case - [Study, null, null, null, null] +24542 - Display case - [Study, null, null, null, null] +24543 - Display case - [Study, null, null, null, null] +24544 - Display case - [Study, null, null, null, null] +24545 - Display case - [Study, null, null, null, null] +24546 - Display case - [Study, null, null, null, null] +24547 - Display case - [Study, null, null, null, null] +24548 - Display case - [Study, null, null, null, null] +24549 - Display case - [Study, null, null, null, null] +24550 - Display case - [Study, null, null, null, null] +24551 - Display case - [Study, null, null, null, null] +24552 - null - [null, null, null, null, null] +24553 - null - [null, null, null, null, null] +24554 - null - [null, null, null, null, null] +24555 - Specimen table - [null, null, null, null, null] +24556 - Specimen table - [null, null, null, null, null] +24557 - Rocks - [null, null, null, null, null] +24558 - null - [null, null, null, null, null] +24559 - Dig Site specimen rocks - [Take, null, null, null, null] +24560 - Gate - [Open, null, null, null, null] +24561 - Gate - [Open, null, null, null, null] +24562 - Gap - [null, null, null, null, null] +24563 - Doorway - [Walk-through, null, null, null, null] +24564 - Gate - [Open, null, null, null, null] +24565 - Door - [Open, null, null, null, null] +24566 - Door - [null, null, null, null, null] +24567 - Door - [Open, null, null, null, null] +24568 - Door - [null, null, null, null, null] +24569 - Snake - [null, null, null, null, null] +24570 - null - [null, null, null, null, null] +24571 - Machine - [null, null, null, null, null] +24572 - Machine - [null, null, null, null, null] +24573 - Machine - [null, null, null, null, null] +24574 - Machine - [null, null, null, null, null] +24575 - Machine - [null, null, null, null, null] +24576 - Machine - [null, null, null, null, null] +24577 - Machine - [null, null, null, null, null] +24578 - Machine - [null, null, null, null, null] +24579 - Machine - [null, null, null, null, null] +24580 - Machine - [null, null, null, null, null] +24581 - Machine - [null, null, null, null, null] +24582 - Machine - [null, null, null, null, null] +24583 - Machine - [null, null, null, null, null] +24584 - Machine - [null, null, null, null, null] +24585 - Machine - [null, null, null, null, null] +24586 - Machine - [null, null, null, null, null] +24587 - Machine - [null, null, null, null, null] +24588 - Button - [null, null, null, null, null] +24589 - Button - [null, null, null, null, null] +24590 - Button - [Push, null, null, null, null] +24591 - Button - [Push, null, null, null, null] +24592 - Button - [Push, null, null, null, null] +24593 - Button - [Push, null, null, null, null] +24594 - Button - [Push, null, null, null, null] +24595 - Button - [Push, null, null, null, null] +24596 - Button - [Push, null, null, null, null] +24597 - Button - [Push, null, null, null, null] +24598 - Button - [Push, null, null, null, null] +24599 - Button - [Push, null, null, null, null] +24600 - Button - [Push, null, null, null, null] +24601 - Button - [Push, null, null, null, null] +24602 - Button - [Push, null, null, null, null] +24603 - Button - [Push, null, null, null, null] +24604 - null - [null, null, null, null, null] +24605 - Plaque - [Study, null, null, null, null] +24606 - Plaque - [Study, null, null, null, null] +24607 - Plaque - [Study, null, null, null, null] +24608 - Plaque - [Study, null, null, null, null] +24609 - Plaque - [Study, null, null, null, null] +24610 - Plaque - [Study, null, null, null, null] +24611 - Plaque - [Study, null, null, null, null] +24612 - Plaque - [Study, null, null, null, null] +24613 - Plaque - [Study, null, null, null, null] +24614 - Plaque - [Study, null, null, null, null] +24615 - Plaque - [Study, null, null, null, null] +24616 - Plaque - [Study, null, null, null, null] +24617 - Plaque - [Study, null, null, null, null] +24618 - Plaque - [Study, null, null, null, null] +24619 - Display case - [null, null, null, null, null] +24620 - Painting - [Study, null, null, null, null] +24621 - Display case - [Study, null, null, null, null] +24622 - Display case - [Study, null, null, null, null] +24623 - null - [null, null, null, null, null] +24624 - Display case - [Study, null, null, null, null] +24625 - Display case - [Study, null, null, null, null] +24626 - null - [null, null, null, null, null] +24627 - Display case - [Study, Open, null, null, null] +24628 - Display case - [Study, null, null, null, null] +24629 - Display case - [Study, null, null, null, null] +24630 - Display case - [Study, null, null, null, null] +24631 - Display case - [Study, null, null, null, null] +24632 - Display case - [Study, null, null, null, null] +24633 - null - [null, null, null, null, null] +24634 - Display case - [Study, null, null, null, null] +24635 - Display case - [Study, null, null, null, null] +24636 - null - [null, null, null, null, null] +24637 - Display case - [Study, null, null, null, null] +24638 - null - [null, null, null, null, null] +24639 - Display case - [Study, null, null, null, null] +24640 - Display case - [Study, null, null, null, null] +24641 - Display case - [Study, null, null, null, null] +24642 - null - [null, null, null, null, null] +24643 - Display case - [Study, null, null, null, null] +24644 - Display case - [Study, null, null, null, null] +24645 - Display case - [Study, null, null, null, null] +24646 - Display case - [Study, null, null, null, null] +24647 - Display case - [Study, null, null, null, null] +24648 - Display case - [Study, null, null, null, null] +24649 - Display case - [Study, null, null, null, null] +24650 - Display case - [Study, null, null, null, null] +24651 - Display case - [Study, null, null, null, null] +24652 - Display case - [Study, null, null, null, null] +24653 - null - [null, null, null, null, null] +24654 - Display case - [Study, null, null, null, null] +24655 - Display case - [Study, null, null, null, null] +24656 - Display case - [Study, null, null, null, null] +24657 - Display case - [Study, null, null, null, null] +24658 - Display case - [Study, null, null, null, null] +24659 - Display case - [Study, null, null, null, null] +24660 - Display case - [Study, null, null, null, null] +24661 - Display case - [Study, null, null, null, null] +24662 - null - [null, null, null, null, null] +24663 - Display case - [Study, null, null, null, null] +24664 - null - [null, null, null, null, null] +24665 - null - [null, null, null, null, null] +24666 - Candles - [null, null, null, null, null] +24667 - Table - [null, null, null, null, null] +24668 - Wardrobe - [Open, null, null, null, null] +24669 - Wardrobe - [null, Search, Close, null, null] +24670 - Wardrobe - [Open, null, null, null, null] +24671 - Wardrobe - [null, Search, Close, null, null] +24672 - Staircase - [Walk-up, null, null, null, null] +24673 - Staircase - [Walk-down, null, null, null, null] +24674 - Mirror - [null, null, null, null, null] +24675 - Shelf - [null, null, null, null, null] +24676 - Shelf - [null, null, null, null, null] +24677 - Charms - [null, null, null, null, null] +24678 - null - [null, null, null, null, null] +24679 - Bed - [null, null, null, null, null] +24680 - Dresser - [null, null, null, null, null] +24681 - Drawers - [Open, null, null, null, null] +24682 - Drawers - [null, Search, Close, null, null] +24683 - Chair - [null, null, null, null, null] +24684 - Table - [null, null, null, null, null] +24685 - Door - [Close, null, null, null, null] +24686 - Door - [Open, null, null, null, null] +24687 - Staircase - [Climb-up, null, null, null, null] +24688 - Broken experiment tube - [null, null, null, null, null] +24689 - Experiment tube - [null, null, null, null, null] +24690 - Box - [null, null, null, null, null] +24691 - Stacked Boxes - [null, null, null, null, null] +24692 - Boxes - [Search, null, null, null, null] +24693 - Rock - [null, null, null, null, null] +24694 - Rock - [null, null, null, null, null] +24695 - Rock - [null, null, null, null, null] +24696 - Rock - [null, null, null, null, null] +24697 - Rock - [null, null, null, null, null] +24698 - Rock - [null, null, null, null, null] +24699 - Rock - [null, null, null, null, null] +24700 - Rock - [null, null, null, null, null] +24701 - Rock - [null, null, null, null, null] +24702 - null - [null, null, null, null, null] +24703 - null - [null, null, null, null, null] +24704 - null - [null, null, null, null, null] +24705 - null - [null, null, null, null, null] +24706 - Skeleton - [null, null, null, null, null] +24707 - Skeleton - [null, null, null, null, null] +24708 - Skeleton - [null, null, null, null, null] +24709 - Barrel - [null, null, null, null, null] +24710 - Sack - [Search, null, null, null, null] +24711 - Smashed chair - [null, null, null, null, null] +24712 - Broken cart wheel - [null, null, null, null, null] +24713 - null - [null, null, null, null, null] +24714 - null - [null, null, null, null, null] +24715 - null - [null, null, null, null, null] +24716 - Mysterious statue - [null, null, null, null, null] +24717 - Ladder - [Climb-up, null, null, null, null] +24718 - Ladder - [Climb-down, null, null, null, null] +24719 - null - [null, null, null, null, null] +24720 - null - [null, null, null, null, null] +24721 - Piano - [Play, null, null, null, null] +24722 - Piano - [Play, null, Search, null, null] +24723 - Drain Pipe - [Talk-into, null, Climb, null, null] +24724 - Gramophone - [Wind-up, null, null, null, null] +24725 - Gramophone - [Turn-Off, null, null, null, null] +24726 - Gramophone - [Kick, null, null, null, null] +24727 - Gramophone - [null, null, null, null, null] +24728 - Music Stand - [Search, null, null, null, null] +24729 - Music Stand - [null, null, null, null, null] +24730 - Earth Mound - [null, null, null, null, null] +24731 - Bean Mound - [null, null, null, null, null] +24732 - Beanstalk - [null, null, null, null, null] +24733 - Beanstalk - [Climb, null, Chop, null, null] +24734 - Beanstalk - [null, null, null, null, null] +24735 - Beanstalk - [null, null, Chop, null, null] +24736 - Beanstalk - [null, null, null, null, null] +24737 - Beanstalk - [null, null, null, null, null] +24738 - Beanstump - [null, null, null, null, null] +24739 - null - [null, null, null, null, null] +24740 - null - [null, null, null, null, null] +24741 - null - [null, null, null, null, null] +24742 - null - [null, null, null, null, null] +24743 - null - [null, null, null, null, null] +24744 - null - [null, null, null, null, null] +24745 - null - [null, null, null, null, null] +24746 - null - [null, null, null, null, null] +24747 - null - [null, null, null, null, null] +24748 - null - [null, null, null, null, null] +24749 - Crumbling wall - [Climb-over, null, null, null, null] +24750 - null - [null, null, null, null, null] +24751 - null - [null, null, null, null, null] +24752 - null - [null, null, null, null, null] +24753 - null - [null, null, null, null, null] +24754 - null - [null, null, null, null, null] +24755 - null - [null, null, null, null, null] +24756 - null - [null, null, null, null, null] +24757 - null - [null, null, null, null, null] +24758 - null - [null, null, null, null, null] +24759 - Door - [Open, null, null, null, null] +24760 - null - [null, null, null, null, null] +24761 - null - [null, null, null, null, null] +24762 - null - [null, null, null, null, null] +24763 - null - [null, null, null, null, null] +24764 - null - [null, null, null, null, null] +24765 - Window - [null, null, null, null, null] +24766 - Window - [null, null, null, null, null] +24767 - Beard - [Climb up, null, null, null, null] +24768 - Window - [null, null, null, null, null] +24769 - Rupert - [null, null, null, null, null] +24770 - Rupert - [null, null, null, null, null] +24771 - Rupert - [Talk-to, null, Climb-down, null, null] +24772 - Rupert - [Talk-to, null, Climb-down, null, null] +24773 - null - [null, null, null, null, null] +24774 - null - [null, null, null, null, null] +24775 - null - [null, null, null, null, null] +24776 - null - [null, null, null, null, null] +24777 - null - [null, null, null, null, null] +24778 - Window - [null, null, null, null, null] +24779 - Beard - [null, null, null, null, null] +24780 - Pendant - [Take, null, null, null, null] +24781 - Rock - [null, null, null, null, null] +24782 - null - [null, null, null, null, null] +24783 - null - [null, null, null, null, null] +24784 - null - [null, null, null, null, null] +24785 - null - [null, null, null, null, null] +24786 - null - [null, null, null, null, null] +24787 - null - [null, null, null, null, null] +24788 - null - [null, null, null, null, null] +24789 - null - [null, null, null, null, null] +24790 - null - [null, null, null, null, null] +24791 - null - [null, null, null, null, null] +24792 - null - [null, null, null, null, null] +24793 - null - [null, null, null, null, null] +24794 - null - [null, null, null, null, null] +24795 - Nails - [Climb-up, null, null, null, null] +24796 - Nails - [Climb-down, null, null, null, null] +24797 - null - [null, null, null, null, null] +24798 - null - [null, null, null, null, null] +24799 - Mouse hole - [Enter, null, null, null, null] +24800 - null - [null, null, null, null, null] +24801 - null - [null, null, null, null, null] +24802 - Grate - [Enter, null, null, null, null] +24803 - Lock - [null, null, null, null, null] +24804 - Nails - [null, null, null, null, null] +24805 - Witch's charm - [null, null, null, null, null] +24806 - null - [null, null, null, null, null] +24807 - null - [null, null, null, null, null] +24808 - Drain - [null, null, null, null, null] +24809 - null - [null, null, null, null, null] +24810 - null - [null, null, null, null, null] +24811 - null - [null, null, null, null, null] +24812 - null - [null, null, null, null, null] +24813 - null - [null, null, null, null, null] +24814 - Chair - [null, null, null, null, null] +24815 - Door - [Close, null, null, null, null] +24816 - Door - [Open, null, null, null, null] +24817 - null - [null, null, null, null, null] +24818 - null - [null, null, null, null, null] +24819 - Beanstalk - [Climb-down, null, null, null, null] +24820 - null - [null, null, null, null, null] +24821 - null - [null, null, null, null, null] +24822 - null - [null, null, null, null, null] +24823 - null - [null, null, null, null, null] +24824 - null - [null, null, null, null, null] +24825 - null - [null, null, null, null, null] +24826 - null - [null, null, null, null, null] +24827 - null - [null, null, null, null, null] +24828 - null - [null, null, null, null, null] +24829 - null - [null, null, null, null, null] +24830 - null - [null, null, null, null, null] +24831 - null - [null, null, null, null, null] +24832 - null - [null, null, null, null, null] +24833 - null - [null, null, null, null, null] +24834 - null - [null, null, null, null, null] +24835 - null - [null, null, null, null, null] +24836 - null - [null, null, null, null, null] +24837 - null - [null, null, null, null, null] +24838 - null - [null, null, null, null, null] +24839 - Grimgnash - [Talk-to, null, null, null, null] +24840 - null - [Talk-to, null, null, null, null] +24841 - Feathers - [Take, null, null, null, null] +24842 - Manhole - [Enter, null, null, null, null] +24843 - Floor - [null, null, null, null, null] +24844 - Floor - [null, null, null, null, null] +24845 - Floor - [null, null, null, null, null] +24846 - Floor - [null, null, null, null, null] +24847 - Floor - [null, null, null, null, null] +24848 - null - [null, null, null, null, null] +24849 - null - [null, null, null, null, null] +24850 - null - [null, null, null, null, null] +24851 - null - [null, null, null, null, null] +24852 - null - [null, null, null, null, null] +24853 - null - [null, null, null, null, null] +24854 - null - [null, null, null, null, null] +24855 - null - [null, null, null, null, null] +24856 - null - [null, null, null, null, null] +24857 - null - [null, null, null, null, null] +24858 - null - [null, null, null, null, null] +24859 - null - [null, null, null, null, null] +24860 - null - [null, null, null, null, null] +24861 - null - [null, null, null, null, null] +24862 - null - [null, null, null, null, null] +24863 - null - [null, null, null, null, null] +24864 - null - [null, null, null, null, null] +24865 - null - [null, null, null, null, null] +24866 - null - [null, null, null, null, null] +24867 - null - [null, null, null, null, null] +24868 - null - [null, null, null, null, null] +24869 - null - [null, null, null, null, null] +24870 - null - [null, null, null, null, null] +24871 - null - [null, null, null, null, null] +24872 - null - [null, null, null, null, null] +24873 - null - [null, null, null, null, null] +24874 - Cheese - [Take, null, null, null, null] +24875 - Coins - [Take, null, null, null, null] +24876 - Bones - [Take, null, null, null, null] +24877 - Witch Glyph - [null, null, null, null, null] +24878 - Witch Glyph - [null, null, null, null, null] +24879 - null - [null, null, null, null, null] +24880 - Crumbling wall - [Climb-over, null, null, null, null] +24881 - null - [null, null, null, null, null] +24882 - null - [hidden, null, null, null, null] +24883 - null - [null, null, null, null, null] +24884 - null - [null, null, null, null, null] +24885 - null - [null, null, null, null, null] +24886 - null - [null, null, null, null, null] +24887 - Cage - [null, null, null, null, null] +24888 - Scuttle - [null, null, null, null, null] +24889 - Barstool - [null, null, null, null, null] +24890 - Barstool - [null, null, null, null, null] +24891 - Bar - [null, null, null, null, null] +24892 - Bar - [null, null, null, null, null] +24893 - Bar - [null, null, null, null, null] +24894 - Bar - [null, null, null, null, null] +24895 - Bar - [null, null, null, null, null] +24896 - Bar - [null, null, null, null, null] +24897 - Bar - [null, null, null, null, null] +24898 - Bar - [null, null, null, null, null] +24899 - Bar - [null, null, null, null, null] +24900 - Table - [null, null, null, null, null] +24901 - null - [null, null, null, null, null] +24902 - null - [null, null, null, null, null] +24903 - null - [null, null, null, null, null] +24904 - null - [null, null, null, null, null] +24905 - null - [null, null, null, null, null] +24906 - null - [null, null, null, null, null] +24907 - Old Bookshelf - [Search, null, null, null, null] +24908 - Old Bookshelf - [Search, null, null, null, null] +24909 - Old Bookshelf - [Search, null, null, null, null] +24910 - Old Bookshelf - [Search, null, null, null, null] +24911 - Crate - [Search, null, null, null, null] +24912 - null - [null, null, null, null, null] +24913 - Bed - [null, null, null, null, null] +24914 - Bank booth - [Use, Use-quickly, Collect, null, null] +24915 - null - [null, null, null, null, null] +24916 - Shelves - [null, null, null, null, null] +24917 - Stepladder - [null, null, null, null, null] +24918 - Ladder - [Climb-up, null, null, null, null] +24919 - Ladder - [Climb-down, null, null, null, null] +24920 - Mangle - [null, null, null, null, null] +24921 - Mangle - [null, null, null, null, null] +24922 - Table - [null, null, null, null, null] +24923 - null - [null, null, null, null, null] +24924 - null - [null, null, null, null, null] +24925 - Staircase - [Climb-up, null, null, null, null] +24926 - Staircase - [Climb-down, null, null, null, null] +24927 - Table - [null, null, null, null, null] +24928 - null - [null, null, null, null, null] +24929 - Tanning line - [null, null, null, null, null] +24930 - Door - [Close, null, null, null, null] +24931 - Door - [Open, null, null, null, null] +24932 - Door - [Close, null, null, null, null] +24933 - Door - [Open, null, null, null, null] +24934 - Door - [null, null, null, null, null] +24935 - Door - [Close, null, null, null, null] +24936 - Door - [Open, null, null, null, null] +24937 - null - [null, null, null, null, null] +24938 - null - [null, null, null, null, null] +24939 - null - [null, null, null, null, null] +24940 - null - [null, null, null, null, null] +24941 - null - [null, null, null, null, null] +24942 - null - [null, null, null, null, null] +24943 - null - [null, null, null, null, null] +24944 - null - [null, null, null, null, null] +24945 - null - [null, null, null, null, null] +24946 - null - [null, null, null, null, null] +24947 - null - [null, null, null, null, null] +24948 - null - [null, null, null, null, null] +24949 - null - [null, null, null, null, null] +24950 - null - [null, null, null, null, null] +24951 - null - [null, null, null, null, null] +24952 - null - [null, null, null, null, null] +24953 - null - [null, null, null, null, null] +24954 - null - [null, null, null, null, null] +24955 - null - [null, null, null, null, null] +24956 - null - [null, null, null, null, null] +24957 - null - [null, null, null, null, null] +24958 - null - [null, null, null, null, null] +24959 - null - [null, null, null, null, null] +24960 - null - [null, null, null, null, null] +24961 - null - [null, null, null, null, null] +24962 - null - [null, null, null, null, null] +24963 - null - [null, null, null, null, null] +24964 - null - [null, null, null, null, null] +24965 - null - [null, null, null, null, null] +24966 - null - [null, null, null, null, null] +24967 - null - [null, null, null, null, null] +24968 - null - [null, null, null, null, null] +24969 - null - [null, null, null, null, null] +24970 - null - [null, null, null, null, null] +24971 - null - [null, null, null, null, null] +24972 - null - [null, null, null, null, null] +24973 - null - [null, null, null, null, null] +24974 - null - [null, null, null, null, null] +24975 - null - [null, null, null, null, null] +24976 - Clothes equipment - [null, null, null, null, null] +24977 - null - [null, null, null, null, null] +24978 - null - [null, null, null, null, null] +24979 - null - [null, null, null, null, null] +24980 - null - [null, null, null, null, null] +24981 - null - [null, null, null, null, null] +24982 - null - [null, null, null, null, null] +24983 - null - [null, null, null, null, null] +24984 - Crop circle - [null, null, null, null, null] +24985 - Crop circle - [null, null, null, null, null] +24986 - Crop circle - [null, null, null, null, null] +24987 - Crop circle - [null, null, null, null, null] +24988 - Centre of crop circle - [Enter, null, null, null, null] +24989 - Magic wheat - [null, null, null, null, null] +24990 - Magic wheat - [null, null, null, null, null] +24991 - Centre of crop circle - [Enter, null, null, null, null] +24992 - null - [null, null, null, null, null] +24993 - null - [null, null, null, null, null] +24994 - null - [null, null, null, null, null] +24995 - null - [null, null, null, null, null] +24996 - null - [null, null, null, null, null] +24997 - null - [null, null, null, null, null] +24998 - null - [null, null, null, null, null] +24999 - null - [null, null, null, null, null] +25000 - null - [null, null, null, null, null] +25001 - null - [null, null, null, null, null] +25002 - null - [null, null, null, null, null] +25003 - null - [null, null, null, null, null] +25004 - null - [null, null, null, null, null] +25005 - null - [null, null, null, null, null] +25006 - null - [null, null, null, null, null] +25007 - null - [null, null, null, null, null] +25008 - null - [null, null, null, null, null] +25009 - null - [null, null, null, null, null] +25010 - null - [null, null, null, null, null] +25011 - null - [null, null, null, null, null] +25012 - null - [null, null, null, null, null] +25013 - null - [null, null, null, null, null] +25014 - Portal - [Leave, null, null, null, null] +25015 - null - [null, null, null, null, null] +25016 - Magical wheat - [null, null, null, null, Push-through] +25017 - Magical wheat - [null, null, null, null, null] +25018 - Magical wheat - [null, null, null, null, null] +25019 - Magical wheat - [null, null, null, null, Push-through] +25020 - Magical wheat - [null, null, null, null, Push-through] +25021 - Magical wheat - [null, null, null, null, Push-through] +25022 - Growing wheat - [null, null, null, null, null] +25023 - Wilting wheat - [null, null, null, null, null] +25024 - Magical wheat - [null, null, null, null, null] +25025 - Magical wheat - [null, null, null, null, null] +25026 - Magical wheat - [null, null, null, null, null] +25027 - Magical wheat - [null, null, null, null, null] +25028 - Magical wheat - [null, null, null, null, null] +25029 - Magical wheat - [null, null, null, null, Push-through] +25030 - null - [null, null, null, null, null] +25031 - null - [null, null, null, null, null] +25032 - null - [null, null, null, null, null] +25033 - Dragon's head - [null, null, null, null, null] +25034 - Drawers - [Open, null, null, null, null] +25035 - Drawers - [Search, Close, null, null, null] +25036 - null - [Repair, null, null, null, null] +25037 - Hull - [null, null, null, null, null] +25038 - Ladder - [Climb-up, null, null, null, null] +25039 - Wall - [null, null, null, null, null] +25040 - Wardrobe - [Open, null, null, null, null] +25041 - Wardrobe - [null, Search, Close, null, null] +25042 - Wardrobe - [null, Search, Close, null, null] +25043 - Wardrobe - [null, Search, Close, null, null] +25044 - Wardrobe - [null, Search, Close, null, null] +25045 - Ladder - [Climb-down, null, null, null, null] +25046 - Bookshelves - [Search, null, null, null, null] +25047 - Table - [null, null, null, null, null] +25048 - Chair - [null, null, null, null, null] +25049 - null - [null, null, null, null, null] +25050 - null - [null, null, null, null, null] +25051 - null - [null, null, null, null, null] +25052 - null - [null, null, null, null, null] +25053 - null - [null, null, null, null, null] +25054 - null - [null, null, null, null, null] +25055 - null - [null, null, null, null, null] +25056 - null - [null, null, null, null, null] +25057 - null - [null, null, null, null, null] +25058 - null - [null, null, null, null, null] +25059 - null - [null, null, null, null, null] +25060 - null - [null, null, null, null, null] +25061 - null - [null, null, null, null, null] +25062 - null - [null, null, null, null, null] +25063 - null - [null, null, null, null, null] +25064 - null - [null, null, null, null, null] +25065 - null - [null, null, null, null, null] +25066 - null - [null, null, null, null, null] +25067 - null - [null, null, null, null, null] +25068 - null - [null, null, null, null, null] +25069 - null - [null, null, null, null, null] +25070 - null - [null, null, null, null, null] +25071 - null - [null, null, null, null, null] +25072 - null - [null, null, null, null, null] +25073 - null - [null, null, null, null, null] +25074 - null - [null, null, null, null, null] +25075 - null - [null, null, null, null, null] +25076 - null - [null, null, null, null, null] +25077 - null - [null, null, null, null, null] +25078 - null - [null, null, null, null, null] +25079 - null - [null, null, null, null, null] +25080 - Column - [null, null, null, null, null] +25081 - Column - [null, null, null, null, null] +25082 - Column - [null, null, null, null, null] +25083 - Stalactite - [null, null, null, null, null] +25084 - Stalagmites - [null, null, null, null, null] +25085 - Stalagmites - [null, null, null, null, null] +25086 - null - [null, null, null, null, null] +25087 - Skeleton - [null, null, null, null, null] +25088 - Skeleton - [null, null, null, null, null] +25089 - Skeleton - [null, null, null, null, null] +25090 - Skeleton - [null, null, null, null, null] +25091 - Shield - [null, null, null, null, null] +25092 - null - [null, null, null, null, null] +25093 - null - [null, null, null, null, null] +25094 - null - [null, null, null, null, null] +25095 - null - [null, null, null, null, null] +25096 - null - [null, null, null, null, null] +25097 - null - [null, null, null, null, null] +25098 - null - [null, null, null, null, null] +25099 - null - [null, null, null, null, null] +25100 - null - [null, null, null, null, null] +25101 - null - [null, null, null, null, null] +25102 - null - [null, null, null, null, null] +25103 - null - [null, null, null, null, null] +25104 - null - [null, null, null, null, null] +25105 - null - [null, null, null, null, null] +25106 - null - [null, null, null, null, null] +25107 - null - [null, null, null, null, null] +25108 - null - [null, null, null, null, null] +25109 - null - [null, null, null, null, null] +25110 - null - [null, null, null, null, null] +25111 - null - [null, null, null, null, null] +25112 - null - [null, null, null, null, null] +25113 - null - [null, null, null, null, null] +25114 - null - [null, null, null, null, null] +25115 - Magic door - [Open, null, null, null, null] +25116 - Magic door - [null, null, null, null, null] +25117 - Magic door - [null, null, null, null, null] +25118 - Magic door - [Open, null, null, null, null] +25119 - null - [null, null, null, null, null] +25120 - null - [null, null, null, null, null] +25121 - null - [null, null, null, null, null] +25122 - Candle stand - [null, null, null, null, null] +25123 - Candle stand - [null, null, null, null, null] +25124 - null - [null, null, null, null, null] +25125 - null - [null, null, null, null, null] +25126 - null - [null, null, null, null, null] +25127 - null - [null, null, null, null, null] +25128 - null - [null, null, null, null, null] +25129 - Vines - [null, null, null, null, null] +25130 - Vines - [null, null, null, null, null] +25131 - Vines - [null, null, null, null, null] +25132 - Vines - [null, null, null, null, null] +25133 - null - [null, null, null, null, null] +25134 - null - [null, null, null, null, null] +25135 - null - [null, null, null, null, null] +25136 - Vines - [null, null, null, null, null] +25137 - Plant - [null, null, null, null, null] +25138 - Fungus - [null, null, null, null, null] +25139 - Fungus - [null, null, null, null, null] +25140 - null - [null, null, null, null, null] +25141 - null - [null, null, null, null, null] +25142 - null - [null, null, null, null, null] +25143 - null - [null, null, null, null, null] +25144 - null - [null, null, null, null, null] +25145 - null - [null, null, null, null, null] +25146 - null - [null, null, null, null, null] +25147 - null - [null, null, null, null, null] +25148 - Wall - [null, null, null, null, null] +25149 - Wall - [null, null, null, null, null] +25150 - Wall - [null, null, null, null, null] +25151 - Wall - [null, null, null, null, null] +25152 - Pillar - [null, null, null, null, null] +25153 - Pillar - [null, null, null, null, null] +25154 - Hole - [Enter, null, null, null, null] +25155 - Fire - [null, null, null, null, null] +25156 - Fire - [null, null, null, null, null] +25157 - Jenkins - [null, null, null, null, null] +25158 - Rock - [null, null, null, null, null] +25159 - Rock - [null, null, null, null, null] +25160 - Rock - [null, null, null, null, null] +25161 - Wall - [Climb-over, null, null, null, null] +25162 - null - [null, null, null, null, null] +25163 - null - [null, null, null, null, null] +25164 - null - [null, null, null, null, null] +25165 - null - [null, null, null, null, null] +25166 - null - [null, null, null, null, null] +25167 - null - [null, null, null, null, null] +25168 - null - [null, null, null, null, null] +25169 - Tree - [null, null, null, null, null] +25170 - White tree - [null, null, null, null, null] +25171 - Tree - [null, null, null, null, null] +25172 - Tree - [null, null, null, null, null] +25173 - null - [null, null, null, null, null] +25174 - Tree - [null, null, null, null, null] +25175 - Fern - [null, null, null, null, null] +25176 - Fern - [null, null, null, null, null] +25177 - Fern - [null, null, null, null, null] +25178 - Fern - [null, null, null, null, null] +25179 - Flowering fern - [null, null, null, null, null] +25180 - Flowering fern - [null, null, null, null, null] +25181 - Dead calquat - [null, null, null, null, null] +25182 - Diseased calquat - [null, null, null, null, null] +25183 - Tree - [null, null, null, null, null] +25184 - Tree - [null, null, null, null, null] +25185 - Tree - [null, null, null, null, null] +25186 - Tree stump - [null, null, null, null, null] +25187 - A burnt tree - [null, null, null, null, null] +25188 - A burnt tree - [null, null, null, null, null] +25189 - Tree - [null, null, null, null, null] +25190 - A tropical tree - [null, null, null, null, null] +25191 - A tropical tree - [null, null, null, null, null] +25192 - Weeds - [null, null, null, null, null] +25193 - null - [null, null, null, null, null] +25194 - Dragon statue - [null, null, null, null, null] +25195 - null - [null, null, null, null, null] +25196 - null - [null, null, null, null, null] +25197 - null - [null, null, null, null, null] +25198 - null - [null, null, null, null, null] +25199 - Circle - [null, null, null, null, null] +25200 - Beacon - [null, null, null, null, null] +25201 - Flames - [null, null, null, null, null] +25202 - Dragon corpse - [null, null, null, null, null] +25203 - Dragon corpse - [null, null, null, null, null] +25204 - Tent - [null, null, null, null, null] +25205 - Flag - [null, null, null, null, null] +25206 - Suit of armour - [null, null, null, null, null] +25207 - Hoisted sail - [null, null, null, null, null] +25208 - Hoisted sail - [null, null, null, null, null] +25209 - null - [null, null, null, null, null] +25210 - Magic door - [null, null, null, null, null] +25211 - Magic door - [null, null, null, null, null] +25212 - null - [null, null, null, null, null] +25213 - Climbing rope - [Climb, null, null, null, null] +25214 - Trapdoor - [Open, null, null, null, null] +25215 - null - [null, null, null, null, null] +25216 - Aged log - [Ride, null, null, null, null] +25217 - null - [null, null, null, null, null] +25218 - null - [null, null, null, null, null] +25219 - null - [null, null, null, null, null] +25220 - null - [null, null, null, null, null] +25221 - null - [null, null, null, null, null] +25222 - null - [null, null, null, null, null] +25223 - null - [null, null, null, null, null] +25224 - null - [null, null, null, null, null] +25225 - null - [null, null, null, null, null] +25226 - null - [null, null, null, null, null] +25227 - null - [null, null, null, null, null] +25228 - null - [null, null, null, null, null] +25229 - null - [null, null, null, null, null] +25230 - null - [null, null, null, null, null] +25231 - null - [null, null, null, null, null] +25232 - null - [null, null, null, null, null] +25233 - null - [null, null, null, null, null] +25234 - null - [null, null, null, null, null] +25235 - null - [null, null, null, null, null] +25236 - null - [null, null, null, null, null] +25237 - null - [null, null, null, null, null] +25238 - null - [null, null, null, null, null] +25239 - null - [null, null, null, null, null] +25240 - null - [null, null, null, null, null] +25241 - null - [null, null, null, null, null] +25242 - null - [null, null, null, null, null] +25243 - null - [null, null, null, null, null] +25244 - null - [null, null, null, null, null] +25245 - null - [null, null, null, null, null] +25246 - null - [null, null, null, null, null] +25247 - null - [null, null, null, null, null] +25248 - null - [null, null, null, null, null] +25249 - null - [null, null, null, null, null] +25250 - null - [null, null, null, null, null] +25251 - null - [null, null, null, null, null] +25252 - Door - [null, null, null, null, null] +25253 - null - [null, null, null, null, null] +25254 - null - [null, null, null, null, null] +25255 - null - [null, null, null, null, null] +25256 - null - [null, null, null, null, null] +25257 - null - [null, null, null, null, null] +25258 - null - [null, null, null, null, null] +25259 - null - [null, null, null, null, null] +25260 - null - [null, null, null, null, null] +25261 - null - [null, null, null, null, null] +25262 - null - [null, null, null, null, null] +25263 - funeral pyre - [null, null, null, null, null] +25264 - funeral pyre - [null, null, null, null, null] +25265 - funeral pyre - [null, null, null, null, null] +25266 - funeral pyre - [null, null, null, null, null] +25267 - funeral pyre - [null, null, null, null, null] +25268 - Barbarian bed - [Search, null, null, null, null] +25269 - Barbarian table - [null, null, null, null, null] +25270 - Barbarian chair - [null, null, null, null, null] +25271 - null - [null, null, null, null, null] +25272 - null - [null, null, null, null, null] +25273 - null - [null, null, null, null, null] +25274 - Whirlpool - [Dive in, null, null, null, null] +25275 - Whirlpool - [Dive in, null, null, null, null] +25276 - Mighty torrent - [null, null, null, null, null] +25277 - Mighty torrent - [null, null, null, null, null] +25278 - Mighty torrent - [null, null, null, null, null] +25279 - Mighty torrent - [null, null, null, null, null] +25280 - null - [null, null, null, null, null] +25281 - null - [null, null, null, null, null] +25282 - null - [null, null, null, null, null] +25283 - null - [null, null, null, null, null] +25284 - null - [null, null, null, null, null] +25285 - null - [null, null, null, null, null] +25286 - Pyre site - [Construct, null, null, null, null] +25287 - Boat station - [null, null, null, null, null] +25288 - Carved log - [null, null, null, null, null] +25289 - Carved log - [null, null, null, null, null] +25290 - Pyre boat - [null, null, null, null, null] +25291 - Pyre boat - [null, null, null, null, null] +25292 - Pyre boat - [null, null, null, null, null] +25293 - Pyre boat - [null, null, null, null, null] +25294 - Pyre boat - [null, null, null, null, null] +25295 - Pyre boat - [null, null, null, null, null] +25296 - null - [null, null, null, null, null] +25297 - null - [null, null, null, null, null] +25298 - null - [null, null, null, null, null] +25299 - null - [null, null, null, null, null] +25300 - null - [null, null, null, null, null] +25301 - null - [null, null, null, null, null] +25302 - null - [null, null, null, null, null] +25303 - null - [null, null, null, null, null] +25304 - null - [null, null, null, null, null] +25305 - null - [null, null, null, null, null] +25306 - null - [null, null, null, null, null] +25307 - null - [null, null, null, null, null] +25308 - null - [null, null, null, null, null] +25309 - null - [null, null, null, null, null] +25310 - null - [null, null, null, null, null] +25311 - null - [null, null, null, null, null] +25312 - null - [null, null, null, null, null] +25313 - null - [null, null, null, null, null] +25314 - null - [null, null, null, null, null] +25315 - null - [null, null, null, null, null] +25316 - null - [null, null, null, null, null] +25317 - null - [null, null, null, null, null] +25318 - null - [null, null, null, null, null] +25319 - null - [null, null, null, null, null] +25320 - null - [null, null, null, null, null] +25321 - null - [null, null, null, null, null] +25322 - null - [null, null, null, null, null] +25323 - null - [null, null, null, null, null] +25324 - null - [null, null, null, null, null] +25325 - null - [null, null, null, null, null] +25326 - null - [null, null, null, null, null] +25327 - null - [null, null, null, null, null] +25328 - null - [null, null, null, null, null] +25329 - null - [null, null, null, null, null] +25330 - null - [null, null, null, null, null] +25331 - null - [null, null, null, null, null] +25332 - null - [null, null, null, null, null] +25333 - null - [null, null, null, null, null] +25334 - null - [null, null, null, null, null] +25335 - null - [null, null, null, null, null] +25336 - Stairs - [Climb-up, null, null, null, null] +25337 - Stairs - [Climb-up, null, null, null, null] +25338 - Stairs - [Climb-down, null, null, null, null] +25339 - Stairs - [Climb-up, null, null, null, null] +25340 - Stairs - [Climb-down, null, null, null, null] +25341 - Mithril door - [Open, null, null, null, null] +25342 - null - [null, null, null, null, null] +25343 - null - [null, null, null, null, null] +25344 - null - [null, null, null, null, null] +25345 - null - [null, null, null, null, null] +25346 - null - [null, null, null, null, null] +25347 - null - [null, null, null, null, null] +25348 - null - [null, null, null, null, null] +25349 - Barbarian anvil - [null, null, null, null, null] +25350 - null - [null, null, null, null, null] +25351 - null - [null, null, null, null, null] +25352 - null - [null, null, null, null, null] +25353 - null - [null, null, null, null, null] +25354 - null - [null, null, null, null, null] +25355 - null - [null, null, null, null, null] +25356 - null - [null, null, null, null, null] +25357 - null - [null, null, null, null, null] +25358 - null - [null, null, null, null, null] +25359 - null - [null, null, null, null, null] +25360 - null - [null, null, null, null, null] +25361 - null - [null, null, null, null, null] +25362 - Skeleton - [Rummage, null, null, null, null] +25363 - null - [null, null, null, null, null] +25364 - null - [null, null, null, null, null] +25365 - null - [null, null, null, null, null] +25366 - null - [null, null, null, null, null] +25367 - null - [null, null, null, null, null] +25368 - Rocks - [Mine, Prospect, hidden, null, null] +25369 - Rocks - [Mine, Prospect, hidden, null, null] +25370 - Rocks - [Mine, Prospect, hidden, null, null] +25371 - Rocks - [Mine, Prospect, hidden, null, null] +25372 - Rocks - [Mine, Prospect, hidden, null, null] +25373 - Rocks - [Mine, Prospect, hidden, null, null] +25374 - campfire - [null, null, null, null, null] +25375 - null - [null, null, null, null, null] +25376 - Wardrobe - [null, null, null, null, null] +25377 - Drawers - [null, null, null, null, null] +25378 - Drawers - [null, null, null, null, null] +25379 - null - [null, null, null, null, null] +25380 - null - [null, null, null, null, null] +25381 - null - [null, null, null, null, null] +25382 - null - [null, null, null, null, null] +25383 - null - [null, null, null, null, null] +25384 - null - [null, null, null, null, null] +25385 - Chest - [Open, null, null, null, null] +25386 - Chest - [Search, Close, null, null, null] +25387 - Chest - [Open, null, null, null, null] +25388 - Chest - [Search, Close, null, null, null] +25389 - Chest - [Open, null, null, null, null] +25390 - Chest - [Search, Close, null, null, null] +25391 - Chest - [Open, null, null, null, null] +25392 - Chest - [Search, Close, null, null, null] +25393 - Telescope - [null, null, null, null, null] +25394 - null - [null, null, null, null, null] +25395 - null - [null, null, null, null, null] +25396 - null - [null, null, null, null, null] +25397 - Signpost - [Read, null, null, null, null] +25398 - null - [null, null, null, null, null] +25399 - null - [null, null, null, null, null] +25400 - null - [null, null, null, null, null] +25401 - Orrery - [View, null, null, null, null] +25402 - Bookcase - [null, null, null, null, null] +25403 - Bookcase - [null, null, null, null, null] +25404 - Bookcase - [null, null, null, null, null] +25405 - Bookcase - [null, null, null, null, null] +25406 - Bookcase - [null, null, null, null, null] +25407 - Old bookshelf - [null, null, null, null, null] +25408 - Old bookshelf - [null, null, null, null, null] +25409 - null - [null, null, null, null, null] +25410 - null - [null, null, null, null, null] +25411 - Professor's table - [null, null, null, null, null] +25412 - null - [null, null, null, null, null] +25413 - null - [null, null, null, null, null] +25414 - null - [null, null, null, null, null] +25415 - Stalagmites - [null, null, null, null, null] +25416 - null - [null, null, null, null, null] +25417 - Door - [Close, null, null, null, null] +25418 - Door - [Open, null, null, null, null] +25419 - Bluebells - [null, null, null, null, null] +25420 - Sunflower - [null, null, null, null, null] +25421 - Sunflowers - [null, null, null, null, null] +25422 - Students' art - [null, null, null, null, null] +25423 - Work board - [null, null, null, null, null] +25424 - Work board - [null, null, null, null, null] +25425 - Coat rack - [null, null, null, null, null] +25426 - Rocking unicorn - [null, null, null, null, null] +25427 - Blackboard - [null, null, null, null, null] +25428 - Empty desk - [null, null, null, null, null] +25429 - Stairs - [Climb up, null, null, null, null] +25430 - null - [null, null, null, null, null] +25431 - Stairs - [Climb-up, null, null, null, null] +25432 - Stairs - [Climb-down, null, null, null, null] +25433 - null - [null, null, null, null, null] +25434 - Stairs - [Climb-down, null, null, null, null] +25435 - null - [null, null, null, null, null] +25436 - null - [null, null, null, null, null] +25437 - Stairs - [Climb-down, null, null, null, null] +25438 - Telescope - [View, null, null, null, null] +25439 - Telescope - [View, null, null, null, null] +25440 - Goblin stove - [Inspect, null, null, null, null] +25441 - Goblin stove - [Inspect, null, null, null, null] +25442 - null - [Inspect, null, null, null, null] +25443 - Spiderwebs - [null, null, null, null, null] +25444 - null - [null, null, null, null, null] +25445 - null - [null, null, null, null, null] +25446 - null - [null, null, null, null, null] +25447 - null - [null, null, null, null, null] +25448 - null - [null, null, null, null, null] +25449 - null - [null, null, null, null, null] +25450 - null - [null, null, null, null, null] +25451 - null - [null, null, null, null, null] +25452 - null - [null, null, null, null, null] +25453 - null - [null, null, null, null, null] +25454 - null - [null, null, null, null, null] +25455 - null - [null, null, null, null, null] +25456 - null - [null, null, null, null, null] +25457 - null - [null, null, null, null, null] +25458 - null - [null, null, null, null, null] +25459 - null - [null, null, null, null, null] +25460 - null - [null, null, null, null, null] +25461 - null - [null, null, null, null, null] +25462 - null - [null, null, null, null, null] +25463 - null - [null, null, null, null, null] +25464 - Potential fire - [null, null, null, null, null] +25465 - Fire - [null, null, null, null, null] +25466 - null - [null, null, null, null, null] +25467 - null - [null, null, null, null, null] +25468 - null - [null, null, null, null, null] +25469 - null - [null, null, null, null, null] +25470 - null - [null, null, null, null, null] +25471 - null - [null, null, null, null, null] +25472 - null - [null, null, null, null, null] +25473 - null - [null, null, null, null, null] +25474 - null - [null, null, null, null, null] +25475 - null - [null, null, null, null, null] +25476 - null - [null, null, null, null, null] +25477 - null - [null, null, null, null, null] +25478 - null - [null, null, null, null, null] +25479 - null - [null, null, null, null, null] +25480 - null - [null, null, null, null, null] +25481 - null - [null, null, null, null, null] +25482 - null - [null, null, null, null, null] +25483 - null - [null, null, null, null, null] +25484 - null - [null, null, null, null, null] +25485 - null - [null, null, null, null, null] +25486 - null - [null, null, null, null, null] +25487 - null - [null, null, null, null, null] +25488 - null - [null, null, null, null, null] +25489 - null - [null, null, null, null, null] +25490 - null - [null, null, null, null, null] +25491 - null - [null, null, null, null, null] +25492 - null - [null, null, null, null, null] +25493 - null - [null, null, null, null, null] +25494 - null - [null, null, null, null, null] +25495 - null - [null, null, null, null, null] +25496 - null - [null, null, null, null, null] +25497 - null - [null, null, null, null, null] +25498 - null - [null, null, null, null, null] +25499 - null - [null, null, null, null, null] +25500 - null - [null, null, null, null, null] +25501 - null - [null, null, null, null, null] +25502 - null - [null, null, null, null, null] +25503 - null - [null, null, null, null, null] +25504 - null - [null, null, null, null, null] +25505 - null - [null, null, null, null, null] +25506 - null - [null, null, null, null, null] +25507 - null - [null, null, null, null, null] +25508 - null - [null, null, null, null, null] +25509 - null - [null, null, null, null, null] +25510 - null - [null, null, null, null, null] +25511 - null - [null, null, null, null, null] +25512 - null - [null, null, null, null, null] +25513 - null - [null, null, null, null, null] +25514 - null - [null, null, null, null, null] +25515 - null - [null, null, null, null, null] +25516 - null - [null, null, null, null, null] +25517 - null - [null, null, null, null, null] +25518 - null - [null, null, null, null, null] +25519 - null - [null, null, null, null, null] +25520 - null - [null, null, null, null, null] +25521 - null - [null, null, null, null, null] +25522 - null - [null, null, null, null, null] +25523 - null - [null, null, null, null, null] +25524 - null - [null, null, null, null, null] +25525 - null - [null, null, null, null, null] +25526 - Door - [Open, null, null, null, null] +25527 - Door - [Open, null, null, null, null] +25528 - null - [null, null, null, null, null] +25529 - null - [null, null, null, null, null] +25530 - null - [null, null, null, null, null] +25531 - null - [null, null, null, null, null] +25532 - null - [null, null, null, null, null] +25533 - null - [null, null, null, null, null] +25534 - null - [null, null, null, null, null] +25535 - null - [null, null, null, null, null] +25536 - null - [null, null, null, null, null] +25537 - null - [null, null, null, null, null] +25538 - null - [null, null, null, null, null] +25539 - null - [null, null, null, null, null] +25540 - null - [null, null, null, null, null] +25541 - null - [null, null, null, null, null] +25542 - null - [null, null, null, null, null] +25543 - null - [null, null, null, null, null] +25544 - null - [null, null, null, null, null] +25545 - null - [null, null, null, null, null] +25546 - null - [null, null, null, null, null] +25547 - null - [null, null, null, null, null] +25548 - null - [null, null, null, null, null] +25549 - null - [null, null, null, null, null] +25550 - null - [null, null, null, null, null] +25551 - null - [null, null, null, null, null] +25552 - null - [null, null, null, null, null] +25553 - null - [null, null, null, null, null] +25554 - null - [null, null, null, null, null] +25555 - null - [null, null, null, null, null] +25556 - null - [null, null, null, null, null] +25557 - null - [null, null, null, null, null] +25558 - null - [null, null, null, null, null] +25559 - null - [null, null, null, null, null] +25560 - null - [null, null, null, null, null] +25561 - null - [null, null, null, null, null] +25562 - null - [null, null, null, null, null] +25563 - null - [null, null, null, null, null] +25564 - null - [null, null, null, null, null] +25565 - null - [null, null, null, null, null] +25566 - null - [null, null, null, null, null] +25567 - null - [null, null, null, null, null] +25568 - null - [null, null, null, null, null] +25569 - null - [null, null, null, null, null] +25570 - null - [null, null, null, null, null] +25571 - null - [null, null, null, null, null] +25572 - null - [null, null, null, null, null] +25573 - null - [null, null, null, null, null] +25574 - null - [null, null, null, null, null] +25575 - null - [null, null, null, null, null] +25576 - null - [null, null, null, null, null] +25577 - null - [null, null, null, null, null] +25578 - Star chart - [Look-at, null, null, null, null] +25579 - Star chart - [Look-at, null, null, null, null] +25580 - Star chart - [Look-at, null, null, null, null] +25581 - Star chart - [Look-at, null, null, null, null] +25582 - Star chart - [Look-at, null, null, null, null] +25583 - Star chart - [Look-at, null, null, null, null] +25584 - null - [null, null, null, null, null] +25585 - null - [null, null, null, null, null] +25586 - null - [null, null, null, null, null] +25587 - null - [null, null, null, null, null] +25588 - Stone arch - [null, null, null, null, null] +25589 - null - [null, null, null, null, null] +25590 - Rat wheel - [null, null, null, null, null] +25591 - null - [View, null, null, null, null] +25592 - Closed chest - [Open, null, null, null, null] +25593 - Open chest - [null, Search, Shut, null, null] +25594 - Large door - [Open, null, null, null, null] +25595 - Large door - [Open, null, null, null, null] +25596 - null - [null, null, null, null, null] +25597 - null - [null, null, null, null, null] +25598 - null - [null, null, null, null, null] +25599 - Suit of armour - [null, null, null, null, null] +25600 - Barrel - [null, null, null, null, null] +25601 - Bench - [null, null, null, null, null] +25602 - Bow cabinet - [null, null, null, null, null] +25603 - Table - [null, null, null, null, null] +25604 - Staircase - [Climb-down, null, null, null, null] +25605 - Throne - [null, null, null, null, null] +25606 - Ladder - [Climb-down, null, null, null, null] +25607 - Bookcase - [Search, null, null, null, null] +25608 - Cabinet - [null, null, null, null, null] +25609 - Cabinet - [null, null, null, null, null] +25610 - Wardrobe - [null, null, null, null, null] +25611 - Shelves - [null, null, null, null, null] +25612 - Shelves - [null, null, null, null, null] +25613 - null - [null, null, null, null, null] +25614 - Crystal ball - [null, null, null, null, null] +25615 - Table - [null, null, null, null, null] +25616 - Chair - [null, null, null, null, null] +25617 - null - [null, null, null, null, null] +25618 - null - [null, null, null, null, null] +25619 - null - [null, null, null, null, null] +25620 - Novice Flag - [null, null, null, null, null] +25621 - Intermediate Flag - [null, null, null, null, null] +25622 - Veteran Flag - [null, null, null, null, null] +25623 - Novice flag - [null, null, null, null, null] +25624 - Intermediate Flag - [null, null, null, null, null] +25625 - Veteran Flag - [null, null, null, null, null] +25626 - null - [null, null, null, null, null] +25627 - null - [null, null, null, null, null] +25628 - null - [null, null, null, null, null] +25629 - Ladder - [Climb, null, null, null, null] +25630 - Ladder - [Climb, null, null, null, null] +25631 - Gangplank - [Cross, null, null, null, null] +25632 - Gangplank - [Cross, null, null, null, null] +25633 - null - [null, null, null, null, null] +25634 - null - [null, null, null, null, null] +25635 - null - [null, null, null, null, null] +25636 - Barricade - [null, null, null, null, null] +25637 - null - [null, null, null, null, null] +25638 - Large door - [Open, null, null, null, null] +25639 - Large door - [Close, null, null, null, null] +25640 - Large door - [Open, null, null, null, null] +25641 - Large door - [Close, null, null, null, null] +25642 - Door - [Open, null, null, null, null] +25643 - Door - [Close, null, null, null, null] +25644 - Crate - [null, null, null, null, null] +25645 - Crate - [null, null, null, null, null] +25646 - Cannon - [null, null, null, null, null] +25647 - Closed chest - [Open, null, null, null, null] +25648 - Dummy - [null, null, null, null, null] +25649 - Rack - [null, null, null, null, null] +25650 - null - [null, null, null, null, null] +25651 - Bow and arrow - [null, null, null, null, null] +25652 - Shelf - [null, null, null, null, null] +25653 - Shelf - [null, null, null, null, null] +25654 - Charms - [null, null, null, null, null] +25655 - Crate - [null, Hide-in, null, null, null] +25656 - null - [null, null, null, null, null] +25657 - null - [null, null, null, null, null] +25658 - null - [null, null, null, null, null] +25659 - null - [null, null, null, null, null] +25660 - Crate - [null, null, null, null, null] +25661 - Crate - [null, null, null, null, null] +25662 - Ladder - [Climb-down, null, null, null, null] +25663 - Ladder - [Climb-up, null, null, null, null] +25664 - Sir Lucan - [Talk-to, null, null, null, null] +25665 - Mossy rock - [Search, null, null, null, null] +25666 - Sir Lancelot - [Talk-to, null, null, null, null] +25667 - Sir Bedivere - [Talk-to, null, null, null, null] +25668 - Hedge - [null, null, null, null, null] +25669 - Hedge - [null, null, null, null, null] +25670 - Hedge - [null, null, null, null, null] +25671 - null - [null, null, null, null, null] +25672 - null - [null, null, null, null, null] +25673 - null - [null, null, null, null, null] +25674 - null - [null, null, null, null, null] +25675 - Food trough - [null, null, null, null, null] +25676 - Bench - [null, null, null, null, null] +25677 - null - [null, null, null, null, null] +25678 - null - [null, null, null, null, null] +25679 - null - [null, null, null, null, null] +25680 - null - [null, null, null, null, null] +25681 - Bed - [null, null, null, null, null] +25682 - Staircase - [Climb-up, null, null, null, null] +25683 - Staircase - [Climb-down, null, null, null, null] +25684 - Bookcase - [Search, null, null, null, null] +25685 - Chest - [Open, null, null, null, null] +25686 - Chest - [Search, Close, null, null, null] +25687 - Ladder - [Climb-up, null, null, null, null] +25688 - Ladder - [Climb-down, null, null, null, null] +25689 - Bookcase - [Search, null, null, null, null] +25690 - Bookcase - [null, null, null, null, null] +25691 - Bookcase - [null, null, null, null, null] +25692 - Bookcase - [null, null, null, null, null] +25693 - Bookcase - [null, null, null, null, null] +25694 - Bookcase - [Search, null, null, null, null] +25695 - Bookcase - [Search, null, null, null, null] +25696 - Bookcase - [Search, null, null, null, null] +25697 - Bookcase - [Search, null, null, null, null] +25698 - Bookcase - [Search, null, null, null, null] +25699 - Cabinet - [null, null, null, null, null] +25700 - Cabinet - [null, null, null, null, null] +25701 - Drawers - [Open, null, null, null, null] +25702 - Drawers - [Search, Shut, null, null, null] +25703 - Drawers - [Open, null, null, null, null] +25704 - Drawers - [Search, Shut, null, null, null] +25705 - Drawers - [Open, null, null, null, null] +25706 - Drawers - [Search, Shut, null, null, null] +25707 - Drawers - [null, null, null, null, null] +25708 - Drawers - [Open, null, null, null, null] +25709 - Drawers - [Search, Shut, null, null, null] +25710 - Drawers - [Open, null, null, null, null] +25711 - Drawers - [Search, Shut, null, null, null] +25712 - Drawers - [Open, null, null, null, null] +25713 - Drawers - [Search, Shut, null, null, null] +25714 - Drawers - [Open, null, null, null, null] +25715 - Drawers - [Search, Shut, null, null, null] +25716 - Door - [Open, null, null, null, null] +25717 - Door - [Close, null, null, null, null] +25718 - Door - [Open, null, null, null, null] +25719 - Door - [Close, null, null, null, null] +25720 - Dairy churn - [Churn, null, null, null, null] +25721 - Barrel - [null, null, null, null, null] +25722 - Barrel of flour - [null, Take From, null, null, null] +25723 - Anna's barrel - [null, Search, null, null, null] +25724 - Bob's barrel - [null, Search, null, null, null] +25725 - Carol's barrel - [null, Search, null, null, null] +25726 - David's barrel - [null, Search, null, null, null] +25727 - Elizabeth's barrel - [null, Search, null, null, null] +25728 - Frank's barrel - [null, Search, null, null, null] +25729 - Sink - [null, null, null, null, null] +25730 - Range - [null, null, null, null, null] +25731 - Grandfather clock - [null, null, null, null, null] +25732 - Dragon's head - [null, null, null, null, null] +25733 - Table - [null, null, null, null, null] +25734 - Table - [null, null, null, null, null] +25735 - Bed - [null, null, null, null, null] +25736 - Shelf - [null, null, null, null, null] +25737 - Shelf - [null, null, null, null, null] +25738 - Painting - [null, null, null, null, null] +25739 - Portrait - [null, null, null, null, null] +25740 - Landscape - [null, null, null, null, null] +25741 - Painting - [null, null, null, null, null] +25742 - Painting - [null, null, null, null, null] +25743 - Landscape - [null, null, null, null, null] +25744 - Painting - [null, null, null, null, null] +25745 - null - [null, null, null, null, null] +25746 - null - [null, null, null, null, null] +25747 - null - [null, null, null, null, null] +25748 - Large door - [Open, null, null, null, null] +25749 - null - [Close, null, null, null, null] +25750 - Large door - [Open, null, null, null, null] +25751 - null - [Close, null, null, null, null] +25752 - null - [null, null, null, null, null] +25753 - null - [null, null, null, null, null] +25754 - null - [null, null, null, null, null] +25755 - null - [null, null, null, null, null] +25756 - null - [null, null, null, null, null] +25757 - null - [null, null, null, null, null] +25758 - null - [null, null, null, null, null] +25759 - null - [null, null, null, null, null] +25760 - null - [null, null, null, null, null] +25761 - Blacksmith's tools - [null, null, null, null, null] +25762 - Sign - [null, null, null, null, null] +25763 - Clock - [null, null, null, null, null] +25764 - Piano - [null, null, null, null, null] +25765 - Piano stool - [null, null, null, null, null] +25766 - Drawers - [Open, null, null, null, null] +25767 - Drawers - [Search, Shut, null, null, null] +25768 - Bench - [null, null, null, null, null] +25769 - Cabinet - [null, null, null, null, null] +25770 - Cabinet - [null, null, null, null, null] +25771 - Chair - [null, null, null, null, null] +25772 - Smashed chair - [null, null, null, null, null] +25773 - Stool - [null, null, null, null, null] +25774 - Workbench - [null, null, null, null, null] +25775 - Crate - [Search, null, null, null, null] +25776 - Crates - [null, null, null, null, null] +25777 - null - [null, null, null, null, null] +25778 - Table - [null, null, null, null, null] +25779 - Statue - [null, null, null, null, null] +25780 - Barrel - [null, null, null, null, null] +25781 - Cooking shelves - [null, null, null, null, null] +25782 - Old bookshelf - [Search, null, null, null, null] +25783 - Rocking chair - [null, null, null, null, null] +25784 - Chair - [null, null, null, null, null] +25785 - Rack - [null, null, null, null, null] +25786 - Staircase - [Climb-up, null, null, null, null] +25787 - Staircase - [Climb-down, null, null, null, null] +25788 - Large door - [Open, null, null, null, null] +25789 - Large door - [Close, null, null, null, null] +25790 - Large door - [Open, null, null, null, null] +25791 - Large door - [Close, null, null, null, null] +25792 - Suit of armour - [null, null, null, null, null] +25793 - Closed chest - [Open, null, null, null, null] +25794 - Open chest - [null, Search, Shut, null, null] +25795 - null - [null, null, null, null, null] +25796 - null - [null, null, null, null, null] +25797 - null - [null, null, null, null, null] +25798 - Cannon - [null, null, null, null, null] +25799 - Door - [Open, null, null, null, null] +25800 - Door - [Close, null, null, null, null] +25801 - Staircase - [Climb-down, null, null, null, null] +25802 - null - [null, null, null, null, null] +25803 - null - [null, null, null, null, null] +25804 - Large door - [Open, null, null, null, null] +25805 - Large door - [Close, null, null, null, null] +25806 - Large door - [Open, null, null, null, null] +25807 - Large door - [Close, null, null, null, null] +25808 - Bank booth - [Use, Use-quickly, Collect, null, null] +25809 - Closed booth - [null, null, null, null, null] +25810 - null - [null, null, null, null, null] +25811 - null - [null, null, null, null, null] +25812 - null - [null, null, null, null, null] +25813 - Large door - [Open, null, null, null, null] +25814 - Large door - [Open, null, null, null, null] +25815 - Large door - [Close, null, null, null, null] +25816 - Large door - [Close, null, null, null, null] +25817 - Study desk - [null, null, null, null, null] +25818 - Church organ - [Play, null, null, null, null] +25819 - Door - [Open, null, null, null, null] +25820 - Door - [Close, null, null, null, null] +25821 - Bow cabinet - [null, null, null, null, null] +25822 - Bed - [null, null, null, null, null] +25823 - Mirror - [null, null, null, null, null] +25824 - Spinning wheel - [null, Spin, null, null, null] +25825 - Door - [Open, null, null, null, null] +25826 - Door - [Close, null, null, null, null] +25827 - Door - [Open, null, null, null, null] +25828 - Door - [Close, null, null, null, null] +25829 - null - [null, null, null, null, null] +25830 - null - [null, null, null, null, null] +25831 - null - [null, null, null, null, null] +25832 - Chair - [null, null, null, null, null] +25833 - null - [null, null, null, null, null] +25834 - null - [null, null, null, null, null] +25835 - null - [null, null, null, null, null] +25836 - Crate - [null, null, null, null, null] +25837 - Crate - [null, null, null, null, null] +25838 - null - [null, null, null, null, null] +25839 - null - [null, null, null, null, null] +25840 - null - [null, null, null, null, null] +25841 - null - [null, null, null, null, null] +25842 - null - [null, null, null, null, null] +25843 - Ladder - [Climb-down, null, null, null, null] +25844 - Ladder - [Climb-up, null, null, null, null] +25845 - null - [null, null, null, null, null] +25846 - null - [null, null, null, null, null] +25847 - null - [null, null, null, null, null] +25848 - null - [null, null, null, null, null] +25849 - null - [null, null, null, null, null] +25850 - null - [null, null, null, null, null] +25851 - null - [null, null, null, null, null] +25852 - null - [null, null, null, null, null] +25853 - null - [null, null, null, null, null] +25854 - null - [null, null, null, null, null] +25855 - null - [null, null, null, null, null] +25856 - null - [null, null, null, null, null] +25857 - null - [null, null, null, null, null] +25858 - null - [null, null, null, null, null] +25859 - null - [null, null, null, null, null] +25860 - null - [null, null, null, null, null] +25861 - null - [null, null, null, null, null] +25862 - null - [null, null, null, null, null] +25863 - null - [null, null, null, null, null] +25864 - null - [null, null, null, null, null] +25865 - null - [null, null, null, null, null] +25866 - null - [null, null, null, null, null] +25867 - null - [null, null, null, null, null] +25868 - null - [null, null, null, null, null] +25869 - null - [null, null, null, null, null] +25870 - null - [null, null, null, null, null] +25871 - null - [null, null, null, null, null] +25872 - null - [null, null, null, null, null] +25873 - null - [null, null, null, null, null] +25874 - null - [null, null, null, null, null] +25875 - null - [null, null, null, null, null] +25876 - Metal door - [Open, null, null, null, null] +25877 - Metal door - [Close, null, null, null, null] +25878 - null - [null, null, null, null, null] +25879 - Vent - [null, null, null, null, null] +25880 - Vent - [Reach, null, null, null, null] +25881 - null - [null, null, null, null, null] +25882 - null - [null, null, null, null, null] +25883 - null - [null, null, null, null, null] +25884 - null - [null, null, null, null, null] +25885 - null - [null, null, null, null, null] +25886 - null - [null, null, null, null, null] +25887 - null - [null, null, null, null, null] +25888 - null - [null, null, null, null, null] +25889 - Sir Tristram - [Talk-to, null, null, null, null] +25890 - null - [null, null, null, null, null] +25891 - null - [null, null, null, null, null] +25892 - null - [null, null, null, null, null] +25893 - null - [null, null, null, null, null] +25894 - null - [null, null, null, null, null] +25895 - null - [null, null, null, null, null] +25896 - null - [null, null, null, null, null] +25897 - null - [null, null, null, null, null] +25898 - null - [null, null, null, null, null] +25899 - null - [null, null, null, null, null] +25900 - null - [null, null, null, null, null] +25901 - null - [null, null, null, null, null] +25902 - null - [null, null, null, null, null] +25903 - null - [null, null, null, null, null] +25904 - null - [null, null, null, null, null] +25905 - null - [null, null, null, null, null] +25906 - null - [null, null, null, null, null] +25907 - null - [null, null, null, null, null] +25908 - null - [null, null, null, null, null] +25909 - null - [null, null, null, null, null] +25910 - null - [null, null, null, null, null] +25911 - null - [null, null, null, null, null] +25912 - null - [null, null, null, null, null] +25913 - null - [null, null, null, null, null] +25914 - null - [null, null, null, null, null] +25915 - null - [null, null, null, null, null] +25916 - null - [null, null, null, null, null] +25917 - null - [null, null, null, null, null] +25918 - null - [null, null, null, null, null] +25919 - null - [null, null, null, null, null] +25920 - null - [null, null, null, null, null] +25921 - null - [null, null, null, null, null] +25922 - null - [null, null, null, null, null] +25923 - null - [null, null, null, null, null] +25924 - null - [null, null, null, null, null] +25925 - null - [null, null, null, null, null] +25926 - null - [null, null, null, null, null] +25927 - Bookcase - [Search, null, null, null, null] +25928 - Table - [null, null, null, null, null] +25929 - Sink - [null, null, null, null, null] +25930 - Table - [null, null, null, null, null] +25931 - Table - [null, null, null, null, null] +25932 - Bar pumps - [null, null, null, null, null] +25933 - Shelves - [null, null, null, null, null] +25934 - Shelves - [null, null, null, null, null] +25935 - Staircase - [Climb-up, null, null, null, null] +25936 - null - [null, null, null, null, null] +25937 - Bank deposit box - [Deposit, null, null, null, null] +25938 - Ladder - [Climb-up, null, null, null, null] +25939 - Ladder - [Climb-down, null, null, null, null] +25940 - Ladder - [Climb-down, null, null, null, null] +25941 - Ladder - [Climb-up, null, null, null, null] +25942 - King Arthur - [Free, null, null, null, null] +25943 - null - [Free, null, null, null, null] +25944 - The jury - [null, null, null, null, null] +25945 - The jury - [null, null, null, null, null] +25946 - The jury - [null, null, null, null, null] +25947 - The jury - [null, null, null, null, null] +25948 - The jury - [null, null, null, null, null] +25949 - The jury - [null, null, null, null, null] +25950 - The jury - [null, null, null, null, null] +25951 - The jury - [null, null, null, null, null] +25952 - The jury - [null, null, null, null, null] +25953 - null - [null, null, null, null, null] +25954 - null - [null, null, null, null, null] +25955 - Alan - [null, null, null, null, null] +25956 - Court judge - [Talk-to, null, null, null, null] +25957 - null - [null, null, null, null, null] +25958 - null - [null, null, null, null, null] +25959 - null - [null, null, null, null, null] +25960 - null - [null, null, null, null, null] +25961 - null - [null, null, null, null, null] +25962 - null - [null, null, null, null, null] +25963 - null - [null, null, null, null, null] +25964 - null - [null, null, null, null, null] +25965 - null - [null, null, null, null, null] +25966 - null - [null, null, null, null, null] +25967 - null - [null, null, null, null, null] +25968 - null - [null, null, null, null, null] +25969 - null - [null, null, null, null, null] +25970 - null - [null, null, null, null, null] +25971 - null - [null, null, null, null, null] +25972 - null - [null, null, null, null, null] +25973 - null - [null, null, null, null, null] +25974 - null - [null, null, null, null, null] +25975 - null - [null, null, null, null, null] +25976 - null - [null, null, null, null, null] +25977 - null - [null, null, null, null, null] +25978 - null - [null, null, null, null, null] +25979 - null - [null, null, null, null, null] +25980 - null - [null, null, null, null, null] +25981 - Locked gate - [null, null, null, null, null] +25982 - null - [null, null, null, null, null] +25983 - null - [null, null, null, null, null] +25984 - null - [null, null, null, null, null] +25985 - null - [null, null, null, null, null] +25986 - null - [null, null, null, null, null] +25987 - null - [null, null, null, null, null] +25988 - null - [null, null, null, null, null] +25989 - null - [null, null, null, null, null] +25990 - null - [null, null, null, null, null] +25991 - null - [null, null, null, null, null] +25992 - null - [null, null, null, null, null] +25993 - null - [null, null, null, null, null] +25994 - null - [null, null, null, null, null] +25995 - null - [null, null, null, null, null] +25996 - null - [null, null, null, null, null] +25997 - null - [null, null, null, null, null] +25998 - null - [null, null, null, null, null] +25999 - null - [null, null, null, null, null] +26000 - null - [null, null, null, null, null] +26001 - null - [null, null, null, null, null] +26002 - null - [null, null, null, null, null] +26003 - null - [null, null, null, null, null] +26004 - null - [null, null, null, null, null] +26005 - null - [null, null, null, null, null] +26006 - null - [null, null, null, null, null] +26007 - null - [null, null, null, null, null] +26008 - null - [null, null, null, null, null] +26009 - null - [null, null, null, null, null] +26010 - null - [null, null, null, null, null] +26011 - null - [null, null, null, null, null] +26012 - null - [null, null, null, null, null] +26013 - null - [null, null, null, null, null] +26014 - null - [null, null, null, null, null] +26015 - null - [null, null, null, null, null] +26016 - null - [null, null, null, null, null] +26017 - Stairs - [Climb-down, null, null, null, null] +26018 - null - [null, null, null, null, null] +26019 - null - [null, null, null, null, null] +26020 - Table - [null, null, null, null, null] +26021 - null - [null, null, null, null, null] +26022 - null - [null, null, null, null, null] +26023 - null - [null, null, null, null, null] +26024 - null - [null, null, null, null, null] +26025 - null - [null, null, null, null, null] +26026 - null - [null, null, null, null, null] +26027 - null - [null, null, null, null, null] +26028 - null - [null, null, null, null, null] +26029 - null - [null, null, null, null, null] +26030 - null - [null, null, null, null, null] +26031 - null - [null, null, null, null, null] +26032 - null - [null, null, null, null, null] +26033 - null - [null, null, null, null, null] +26034 - null - [null, null, null, null, null] +26035 - null - [null, null, null, null, null] +26036 - null - [null, null, null, null, null] +26037 - null - [null, null, null, null, null] +26038 - null - [null, null, null, null, null] +26039 - null - [null, null, null, null, null] +26040 - null - [null, null, null, null, null] +26041 - null - [null, null, null, null, null] +26042 - Gate - [Exit, null, null, null, null] +26043 - Desk - [null, null, null, null, null] +26044 - Desk - [null, null, null, null, null] +26045 - Citizen - [null, null, null, null, null] +26046 - Citizen - [null, null, null, null, null] +26047 - Citizen - [null, null, null, null, null] +26048 - Citizen - [null, null, null, null, null] +26049 - Citizen - [null, null, null, null, null] +26050 - Citizen - [null, null, null, null, null] +26051 - Stairs - [null, null, null, null, null] +26052 - null - [null, null, null, null, null] +26053 - Bookcase - [Search, null, null, null, null] +26054 - null - [null, null, null, null, null] +26055 - null - [null, null, null, null, null] +26056 - null - [null, null, null, null, null] +26057 - null - [null, null, null, null, null] +26058 - null - [null, null, null, null, null] +26059 - null - [null, null, null, null, null] +26060 - null - [null, null, null, null, null] +26061 - null - [null, null, null, null, null] +26062 - null - [null, null, null, null, null] +26063 - null - [null, null, null, null, null] +26064 - null - [null, null, null, null, null] +26065 - null - [null, null, null, null, null] +26066 - null - [null, null, null, null, null] +26067 - null - [null, null, null, null, null] +26068 - null - [null, null, null, null, null] +26069 - null - [null, null, null, null, null] +26070 - null - [null, null, null, null, null] +26071 - null - [null, null, null, null, null] +26072 - null - [null, null, null, null, null] +26073 - Statue - [Search, null, null, null, null] +26074 - Table - [null, null, null, null, null] +26075 - Chair - [null, null, null, null, null] +26076 - Chair - [null, null, null, null, null] +26077 - Chair - [null, null, null, null, null] +26078 - null - [null, null, null, null, null] +26079 - null - [null, null, null, null, null] +26080 - null - [null, null, null, null, null] +26081 - Gate - [Open, null, null, null, null] +26082 - Gate - [Open, null, null, null, null] +26083 - null - [Close, null, null, null, null] +26084 - null - [Close, null, null, null, null] +26085 - null - [null, null, null, null, null] +26086 - null - [null, null, null, null, null] +26087 - null - [null, null, null, null, null] +26088 - null - [null, null, null, null, null] +26089 - null - [null, null, null, null, null] +26090 - null - [null, null, null, null, null] +26091 - null - [null, null, null, null, null] +26092 - null - [null, null, null, null, null] +26093 - null - [null, null, null, null, null] +26094 - null - [null, null, null, null, null] +26095 - null - [null, null, null, null, null] +26096 - null - [null, null, null, null, null] +26097 - null - [null, null, null, null, null] +26098 - null - [null, null, null, null, null] +26099 - null - [null, null, null, null, null] +26100 - null - [null, null, null, null, null] +26101 - null - [null, null, null, null, null] +26102 - null - [null, null, null, null, null] +26103 - null - [null, null, null, null, null] +26104 - null - [null, null, null, null, null] +26105 - null - [null, null, null, null, null] +26106 - Staircase - [Climb-up, null, null, null, null] +26107 - Ladder - [Climb-up, null, null, null, null] +26108 - null - [null, null, null, null, null] +26109 - Spiders' nest - [null, Investigate, null, null, null] +26110 - Smashed window - [null, Investigate, Break, null, null] +26111 - Smashed window - [null, Investigate, Break, null, null] +26112 - Window - [null, Investigate, Break, null, null] +26113 - Bookcase - [Search, null, null, null, null] +26114 - Odd looking wall - [Open, null, null, null, null] +26115 - Odd looking wall - [Open, null, null, null, null] +26116 - Odd looking wall - [null, null, null, null, null] +26117 - Odd looking wall - [null, null, null, null, null] +26118 - Ladder - [Climb-up, null, null, null, null] +26119 - Trapdoor - [Climb-down, null, null, null, null] +26120 - Sinclair family compost heap - [null, Investigate, null, null, null] +26121 - Sinclair family beehive - [null, Investigate, null, null, null] +26122 - Barrel of flour - [null, Take From, null, null, null] +26123 - null - [null, null, null, null, null] +26124 - null - [null, null, null, null, null] +26125 - null - [null, null, null, null, null] +26126 - null - [null, null, null, null, null] +26127 - null - [null, null, null, null, null] +26128 - null - [null, null, null, null, null] +26129 - null - [null, null, null, null, null] +26130 - Gate - [Open, null, null, null, null] +26131 - Gate - [Open, null, null, null, null] +26132 - Gate - [Close, null, null, null, null] +26133 - Gate - [Close, null, null, null, null] +26134 - null - [null, null, null, null, null] +26135 - null - [null, null, null, null, null] +26136 - null - [null, null, null, null, null] +26137 - Fly paper - [null, null, null, null, null] +26138 - null - [null, null, null, null, null] +26139 - null - [null, null, null, null, null] +26140 - Gramophone - [null, null, null, null, null] +26141 - Gramophone - [null, null, null, null, null] +26142 - Table - [null, null, null, null, null] +26143 - Spinning wheel - [null, Spin, null, null, null] +26144 - Staircase - [Climb-up, null, null, null, null] +26145 - Staircase - [Climb-up, null, null, null, null] +26146 - Staircase - [Climb-up, null, null, null, null] +26147 - Staircase - [Climb-up, null, null, null, null] +26148 - Staircase - [Climb-down, null, null, null, null] +26149 - Staircase - [Climb-down, null, null, null, null] +26150 - Staircase - [Climb-down, null, null, null, null] +26151 - Staircase - [Climb-down, null, null, null, null] +26152 - null - [null, null, null, null, null] +26153 - null - [null, null, null, null, null] +26154 - null - [null, null, null, null, null] +26155 - null - [null, null, null, null, null] +26156 - null - [null, null, null, null, null] +26157 - null - [null, null, null, null, null] +26158 - null - [null, null, null, null, null] +26159 - null - [null, null, null, null, null] +26160 - null - [null, null, null, null, null] +26161 - null - [null, null, null, null, null] +26162 - null - [null, null, null, null, null] +26163 - null - [null, null, null, null, null] +26164 - null - [null, null, null, null, null] +26165 - null - [null, null, null, null, null] +26166 - null - [null, null, null, null, null] +26167 - null - [null, null, null, null, null] +26168 - null - [null, null, null, null, null] +26169 - null - [null, null, null, null, null] +26170 - null - [null, null, null, null, null] +26171 - null - [null, null, null, null, null] +26172 - null - [null, null, null, null, null] +26173 - null - [null, null, null, null, null] +26174 - null - [null, null, null, null, null] +26175 - null - [null, null, null, null, null] +26176 - null - [null, null, null, null, null] +26177 - null - [null, null, null, null, null] +26178 - null - [null, null, null, null, null] +26179 - null - [null, null, null, null, null] +26180 - null - [null, null, null, null, null] +26181 - null - [null, null, null, null, null] +26182 - null - [null, null, null, null, null] +26183 - null - [null, null, null, null, null] +26184 - null - [null, null, null, null, null] +26185 - null - [null, null, null, null, null] +26186 - null - [null, null, null, null, null] +26187 - null - [null, null, null, null, null] +26188 - Locked door - [Open, null, null, null, null] +26189 - Locked door - [Open, null, null, null, null] +26190 - null - [null, null, null, null, null] +26191 - Lever - [Pull, null, null, null, null] +26192 - null - [Examine, Warm-by, null, null, null] +26193 - Chest - [Open, null, null, null, null] +26194 - Lever - [Pull, null, null, null, null] +26195 - null - [null, null, null, null, null] +26196 - null - [null, null, null, null, null] +26197 - null - [null, null, null, null, null] +26198 - Birthday cake - [null, null, null, null, null] +26199 - Birthday cake - [null, null, null, null, null] +26200 - Birthday cake - [null, null, null, null, null] +26201 - Table - [null, null, null, null, null] +26202 - Table - [null, null, null, null, null] +26203 - Table - [null, null, null, null, null] +26204 - Present - [null, null, null, null, null] +26205 - Present - [null, null, null, null, null] +26206 - Table - [null, null, null, null, null] +26207 - Large door - [Close, null, null, null, null] +26208 - Staircase - [Climb-up, null, null, null, null] +26209 - Skeleton - [null, null, null, null, null] +26210 - Skeleton - [null, null, null, null, null] +26211 - Skeleton - [null, null, null, null, null] +26212 - Skeleton - [null, null, null, null, null] +26213 - Bones - [null, null, null, null, null] +26214 - Bones - [null, null, null, null, null] +26215 - Bones - [null, null, null, null, null] +26216 - Skeleton - [null, null, null, null, null] +26217 - Crushed skeleton - [null, null, null, null, null] +26218 - Skeleton - [null, null, null, null, null] +26219 - null - [null, null, null, null, null] +26220 - null - [null, null, null, null, null] +26221 - null - [null, null, null, null, null] +26222 - null - [null, null, null, null, null] +26223 - null - [null, null, null, null, null] +26224 - null - [null, null, null, null, null] +26225 - null - [null, null, null, null, null] +26226 - null - [null, null, null, null, null] +26227 - Skeleton - [null, null, null, null, null] +26228 - null - [null, null, null, null, null] +26229 - Battle tower - [null, null, null, null, null] +26230 - Broken catapult - [null, null, null, null, null] +26231 - Crossbow - [null, null, null, null, null] +26232 - Chain - [null, null, null, null, null] +26233 - Battering ram - [null, null, null, null, null] +26234 - Arrow - [null, null, null, null, null] +26235 - Broken mast - [null, null, null, null, null] +26236 - Skeleton - [null, null, null, null, null] +26237 - Wheel - [null, null, null, null, null] +26238 - Hammer - [null, null, null, null, null] +26239 - Armour - [null, null, null, null, null] +26240 - Ladder - [null, null, null, null, null] +26241 - Crate - [null, null, null, null, null] +26242 - Arm - [null, null, null, null, null] +26243 - Barrels - [null, null, null, null, null] +26244 - null - [null, null, null, null, null] +26245 - null - [null, null, null, null, null] +26246 - null - [null, null, null, null, null] +26247 - Old axe - [null, null, null, null, null] +26248 - Column - [null, null, null, null, null] +26249 - Cannonball - [null, null, null, null, null] +26250 - Spikes - [null, null, null, null, null] +26251 - Crate - [null, null, null, null, null] +26252 - Spikes - [null, null, null, null, null] +26253 - Barrels - [null, null, null, null, null] +26254 - Barrels - [null, null, null, null, null] +26255 - Pole - [null, null, null, null, null] +26256 - Catapult - [null, null, null, null, null] +26257 - Crates - [null, null, null, null, null] +26258 - Crates - [null, null, null, null, null] +26259 - Crossbow - [null, null, null, null, null] +26260 - Crates - [null, null, null, null, null] +26261 - Crates - [null, null, null, null, null] +26262 - Spikes - [null, null, null, null, null] +26263 - Wood - [null, null, null, null, null] +26264 - Spikes - [null, null, null, null, null] +26265 - Stormram - [null, null, null, null, null] +26266 - Skullshield - [null, null, null, null, null] +26267 - Barrels - [null, null, null, null, null] +26268 - Boards - [null, null, null, null, null] +26269 - Crane - [null, null, null, null, null] +26270 - Handle - [null, null, null, null, null] +26271 - Frozen warrior - [null, null, null, null, null] +26272 - Frozen warrior - [null, null, null, null, null] +26273 - Frozen warrior - [null, null, null, null, null] +26274 - Frozen warrior - [null, null, null, null, null] +26275 - Frozen warrior - [null, null, null, null, null] +26276 - Frozen warrior - [null, null, null, null, null] +26277 - Frozen warrior - [null, null, null, null, null] +26278 - Frozen warrior - [null, null, null, null, null] +26279 - Frozen warrior - [null, null, null, null, null] +26280 - Frozen warrior - [null, null, null, null, null] +26281 - Frozen demon - [null, null, null, null, null] +26282 - Frozen demon - [null, null, null, null, null] +26283 - Frozen orc - [null, null, null, null, null] +26284 - Frozen orc - [null, null, null, null, null] +26285 - Frozen orc - [null, null, null, null, null] +26286 - Zamorak altar - [Pray-at, Teleport, null, null, null] +26287 - Saradomin altar - [Pray-at, Teleport, null, null, null] +26288 - Armadyl altar - [Pray-at, Teleport, null, null, null] +26289 - Bandos altar - [Pray-at, Teleport, null, null, null] +26290 - null - [null, null, null, null, null] +26291 - Big hole - [null, null, null, null, null] +26292 - Rope - [null, null, null, null, null] +26293 - Rope - [Climb, null, null, null, null] +26294 - null - [null, null, null, null, null] +26295 - Rock - [null, Climb-down, null, null, null] +26296 - Rock - [Tie-rope, null, null, null, null] +26297 - Rope - [Climb-up, null, null, null, null] +26298 - null - [null, null, null, null, null] +26299 - Rock - [null, Climb-down, null, null, null] +26300 - Rock - [Tie-rope, null, null, null, null] +26301 - Rope - [Climb-up, null, null, null, null] +26302 - Pillar - [null, null, null, null, null] +26303 - Pillar - [Grapple, null, null, null, null] +26304 - null - [null, null, null, null, null] +26305 - Little crack - [Crawl-through, null, null, null, null] +26306 - Knight - [null, null, Search, null, null] +26307 - null - [null, null, null, null, null] +26308 - null - [null, null, null, null, null] +26309 - null - [null, null, null, null, null] +26310 - null - [null, null, null, null, null] +26311 - null - [null, null, null, null, null] +26312 - null - [null, null, null, null, null] +26313 - null - [null, null, null, null, null] +26314 - null - [null, null, null, null, null] +26315 - null - [null, null, null, null, null] +26316 - null - [null, null, null, null, null] +26317 - null - [null, null, null, null, null] +26318 - null - [null, null, null, null, null] +26319 - null - [null, null, null, null, null] +26320 - null - [null, null, null, null, null] +26321 - null - [null, null, null, null, null] +26322 - null - [null, null, null, null, null] +26323 - Rocky handholds - [Climb, null, null, null, null] +26324 - Rocky handholds - [Climb, null, null, null, null] +26325 - Rocky handholds - [Climb, null, null, null, null] +26326 - null - [null, null, null, null, null] +26327 - Rocky handholds - [Climb, null, null, null, null] +26328 - Rocky handholds - [Climb, null, null, null, null] +26329 - Rocky handholds - [Climb, null, null, null, null] +26330 - null - [null, null, null, null, null] +26331 - null - [null, null, null, null, null] +26332 - null - [null, null, null, null, null] +26333 - null - [null, null, null, null, null] +26334 - null - [null, null, null, null, null] +26335 - null - [null, null, null, null, null] +26336 - null - [null, null, null, null, null] +26337 - null - [null, null, null, null, null] +26338 - Boulder - [Move, null, null, null, null] +26339 - Boulder - [null, null, null, null, null] +26340 - Hole - [Tie-rope, null, null, null, null] +26341 - Hole - [Climb-down, null, null, null, null] +26342 - null - [null, null, null, null, null] +26343 - Broken pillar - [Tie-rope, null, null, null, null] +26344 - Broken pillar - [null, null, null, null, null] +26345 - Rope - [Climb-down, null, null, null, null] +26346 - null - [null, null, null, null, null] +26347 - null - [null, null, null, null, null] +26348 - null - [null, null, null, null, null] +26349 - null - [null, null, null, null, null] +26350 - null - [null, null, null, null, null] +26351 - null - [null, null, null, null, null] +26352 - null - [null, null, null, null, null] +26353 - null - [null, null, null, null, null] +26354 - null - [null, null, null, null, null] +26355 - null - [null, null, null, null, null] +26356 - null - [null, null, null, null, null] +26357 - null - [null, null, null, null, null] +26358 - null - [null, null, null, null, null] +26359 - null - [null, null, null, null, null] +26360 - null - [null, null, null, null, null] +26361 - null - [null, null, null, null, null] +26362 - null - [null, null, null, null, null] +26363 - null - [null, null, null, null, null] +26364 - null - [null, null, null, null, null] +26365 - null - [null, null, null, null, null] +26366 - null - [null, null, null, null, null] +26367 - null - [null, null, null, null, null] +26368 - null - [null, null, null, null, null] +26369 - null - [null, null, null, null, null] +26370 - null - [null, null, null, null, null] +26371 - null - [null, null, null, null, null] +26372 - null - [null, null, null, null, null] +26373 - null - [null, null, null, null, null] +26374 - null - [null, null, null, null, null] +26375 - null - [null, null, null, null, null] +26376 - null - [null, null, null, null, null] +26377 - null - [null, null, null, null, null] +26378 - null - [null, null, null, null, null] +26379 - null - [null, null, null, null, null] +26380 - Frozen door - [null, null, null, null, null] +26381 - Frozen door - [null, null, null, null, null] +26382 - null - [null, null, null, null, null] +26383 - null - [null, null, null, null, null] +26384 - Big door - [Bang, null, null, null, null] +26385 - null - [null, null, null, null, null] +26386 - null - [null, null, null, null, null] +26387 - Door - [null, null, null, null, null] +26388 - null - [null, null, null, null, null] +26389 - null - [null, null, null, null, null] +26390 - null - [null, null, null, null, null] +26391 - null - [null, null, null, null, null] +26392 - null - [null, null, null, null, null] +26393 - null - [null, null, null, null, null] +26394 - null - [null, null, null, null, null] +26395 - null - [null, null, null, null, null] +26396 - null - [null, null, null, null, null] +26397 - null - [null, null, null, null, null] +26398 - null - [null, null, null, null, null] +26399 - null - [null, null, null, null, null] +26400 - null - [null, null, null, null, null] +26401 - null - [null, null, null, null, null] +26402 - null - [null, null, null, null, null] +26403 - null - [null, null, null, null, null] +26404 - null - [null, null, null, null, null] +26405 - null - [null, null, null, null, null] +26406 - null - [null, null, null, null, null] +26407 - null - [null, null, null, null, null] +26408 - null - [null, null, null, null, null] +26409 - null - [null, null, null, null, null] +26410 - null - [null, null, null, null, null] +26411 - null - [null, null, null, null, null] +26412 - null - [null, null, null, null, null] +26413 - null - [null, null, null, null, null] +26414 - Large geyser - [null, null, null, null, null] +26415 - Snow - [null, null, null, null, null] +26416 - null - [null, null, null, null, null] +26417 - Snowfall - [null, null, null, null, null] +26418 - Waterfall - [null, null, null, null, null] +26419 - Waterfall - [null, null, null, null, null] +26420 - Waterfall - [null, null, null, null, null] +26421 - Waterfall - [null, null, null, null, null] +26422 - Waterfall - [null, null, null, null, null] +26423 - null - [null, null, null, null, null] +26424 - null - [null, null, null, null, null] +26425 - Big door - [Open, null, null, null, null] +26426 - Big door - [Open, null, null, null, null] +26427 - Big door - [Open, null, null, null, null] +26428 - Big door - [Open, null, null, null, null] +26429 - null - [null, null, null, null, null] +26430 - null - [null, null, null, null, null] +26431 - null - [null, null, null, null, null] +26432 - null - [null, null, null, null, null] +26433 - null - [null, null, null, null, null] +26434 - null - [null, null, null, null, null] +26435 - null - [null, null, null, null, null] +26436 - null - [null, null, null, null, null] +26437 - null - [null, null, null, null, null] +26438 - null - [null, null, null, null, null] +26439 - Ice bridge - [Climb-off, null, null, null, null] +26440 - Crate - [Search, null, null, null, null] +26441 - null - [null, null, null, null, null] +26442 - null - [null, null, null, null, null] +26443 - null - [null, null, null, null, null] +26444 - null - [null, null, null, null, null] +26445 - null - [null, null, null, null, null] +26446 - null - [null, null, null, null, null] +26447 - null - [null, null, null, null, null] +26448 - null - [null, null, null, null, null] +26449 - null - [null, null, null, null, null] +26450 - null - [null, null, null, null, null] +26451 - null - [null, null, null, null, null] +26452 - null - [null, null, null, null, null] +26453 - null - [null, null, null, null, null] +26454 - null - [null, null, null, null, null] +26455 - null - [null, null, null, null, null] +26456 - null - [null, null, null, null, null] +26457 - null - [null, null, null, null, null] +26458 - null - [null, null, null, null, null] +26459 - null - [null, null, null, null, null] +26460 - null - [null, null, null, null, null] +26461 - null - [null, null, null, null, null] +26462 - null - [null, null, null, null, null] +26463 - null - [null, null, null, null, null] +26464 - null - [null, null, null, null, null] +26465 - null - [null, null, null, null, null] +26466 - null - [null, null, null, null, null] +26467 - null - [null, null, null, null, null] +26468 - null - [null, null, null, null, null] +26469 - null - [null, null, null, null, null] +26470 - null - [null, null, null, null, null] +26471 - null - [null, null, null, null, null] +26472 - null - [null, null, null, null, null] +26473 - null - [null, null, null, null, null] +26474 - null - [null, null, null, null, null] +26475 - null - [null, null, null, null, null] +26476 - null - [null, null, null, null, null] +26477 - null - [null, null, null, null, null] +26478 - null - [null, null, null, null, null] +26479 - null - [null, null, null, null, null] +26480 - null - [null, null, null, null, null] +26481 - null - [null, null, null, null, null] +26482 - null - [null, null, null, null, null] +26483 - null - [null, null, null, null, null] +26484 - null - [null, null, null, null, null] +26485 - null - [null, null, null, null, null] +26486 - null - [null, null, null, null, null] +26487 - null - [null, null, null, null, null] +26488 - Staircase - [Climb, null, null, null, null] +26489 - Staircase - [Climb, null, null, null, null] +26490 - null - [null, null, null, null, null] +26491 - null - [null, null, null, null, null] +26492 - null - [null, null, null, null, null] +26493 - null - [null, null, null, null, null] +26494 - Crate - [Search, null, null, null, null] +26495 - Crate - [Search, null, null, null, null] +26496 - null - [null, null, null, null, null] +26497 - null - [null, null, null, null, null] +26498 - null - [null, null, null, null, null] +26499 - null - [null, null, null, null, null] +26500 - null - [null, null, null, null, null] +26501 - null - [null, null, null, null, null] +26502 - null - [null, null, null, null, null] +26503 - null - [null, null, null, null, null] +26504 - null - [null, null, null, null, null] +26505 - null - [null, null, null, null, null] +26506 - null - [null, null, null, null, null] +26507 - null - [null, null, null, null, null] +26508 - null - [null, null, null, null, null] +26509 - null - [null, null, null, null, null] +26510 - null - [null, null, null, null, null] +26511 - null - [null, null, null, null, null] +26512 - null - [null, null, null, null, null] +26513 - null - [null, null, null, null, null] +26514 - null - [null, null, null, null, null] +26515 - null - [null, null, null, null, null] +26516 - null - [null, null, null, null, null] +26517 - null - [null, null, null, null, null] +26518 - Ladder - [Climb-up, null, null, null, null] +26519 - Ladder - [Climb-down, null, null, null, null] +26520 - null - [null, null, null, null, null] +26521 - null - [null, null, null, null, null] +26522 - null - [null, null, null, null, null] +26523 - null - [null, null, null, null, null] +26524 - null - [null, null, null, null, null] +26525 - null - [null, null, null, null, null] +26526 - null - [null, null, null, null, null] +26527 - null - [null, null, null, null, null] +26528 - null - [null, null, null, null, null] +26529 - null - [null, null, null, null, null] +26530 - null - [null, null, null, null, null] +26531 - null - [null, null, null, null, null] +26532 - null - [null, null, null, null, null] +26533 - null - [null, null, null, null, null] +26534 - null - [null, null, null, null, null] +26535 - null - [null, null, null, null, null] +26536 - null - [null, null, null, null, null] +26537 - null - [null, null, null, null, null] +26538 - null - [null, null, null, null, null] +26539 - null - [null, null, null, null, null] +26540 - null - [null, null, null, null, null] +26541 - null - [null, null, null, null, null] +26542 - null - [null, null, null, null, null] +26543 - null - [null, null, null, null, null] +26544 - null - [null, null, null, null, null] +26545 - null - [null, null, null, null, null] +26546 - null - [null, null, null, null, null] +26547 - null - [null, null, null, null, null] +26548 - null - [null, null, null, null, null] +26549 - null - [null, null, null, null, null] +26550 - null - [null, null, null, null, null] +26551 - null - [null, null, null, null, null] +26552 - null - [null, null, null, null, null] +26553 - null - [null, null, null, null, null] +26554 - null - [null, null, null, null, null] +26555 - null - [null, null, null, null, null] +26556 - null - [null, null, null, null, null] +26557 - null - [null, null, null, null, null] +26558 - null - [null, null, null, null, null] +26559 - null - [null, null, null, null, null] +26560 - Metal door - [Open, null, null, null, null] +26561 - Metal door - [Close, null, null, null, null] +26562 - null - [null, null, null, null, null] +26563 - null - [null, null, null, null, null] +26564 - null - [null, null, null, null, null] +26565 - null - [null, null, null, null, null] +26566 - null - [null, null, null, null, null] +26567 - null - [null, null, null, null, null] +26568 - null - [null, null, null, null, null] +26569 - null - [null, null, null, null, null] +26570 - Sewer exit - [Exit, null, null, null, null] +26571 - Sewer exit - [Exit, null, null, null, null] +26572 - Sewer exit - [Exit, null, null, null, null] +26573 - Sewer exit - [Exit, null, null, null, null] +26574 - Sewer exit - [Exit, null, null, null, null] +26575 - Sewer exit - [Exit, null, null, null, null] +26576 - null - [null, null, null, null, null] +26577 - null - [null, null, null, null, null] +26578 - Gas - [null, null, null, null, null] +26579 - Gas jet - [null, null, null, null, null] +26580 - null - [null, null, null, null, null] +26581 - null - [null, null, null, null, null] +26582 - null - [null, null, null, null, null] +26583 - null - [null, null, null, null, null] +26584 - null - [null, null, null, null, null] +26585 - null - [null, null, null, null, null] +26586 - null - [null, null, null, null, null] +26587 - null - [null, null, null, null, null] +26588 - null - [null, null, null, null, null] +26589 - null - [null, null, null, null, null] +26590 - null - [null, null, null, null, null] +26591 - null - [null, null, null, null, null] +26592 - null - [null, null, null, null, null] +26593 - null - [null, null, null, null, null] +26594 - null - [null, null, null, null, null] +26595 - null - [null, null, null, null, null] +26596 - null - [null, null, null, null, null] +26597 - null - [null, null, null, null, null] +26598 - null - [null, null, null, null, null] +26599 - null - [null, null, null, null, null] +26600 - null - [null, null, null, null, null] +26601 - null - [null, null, null, null, null] +26602 - null - [null, null, null, null, null] +26603 - null - [null, null, null, null, null] +26604 - null - [null, null, null, null, null] +26605 - null - [null, null, null, null, null] +26606 - null - [null, null, null, null, null] +26607 - null - [null, null, null, null, null] +26608 - null - [null, null, null, null, null] +26609 - null - [null, null, null, null, null] +26610 - null - [null, null, null, null, null] +26611 - null - [null, null, null, null, null] +26612 - null - [null, null, null, null, null] +26613 - null - [null, null, null, null, null] +26614 - null - [null, null, null, null, null] +26615 - null - [null, null, null, null, null] +26616 - null - [null, null, null, null, null] +26617 - null - [null, null, null, null, null] +26618 - null - [null, null, null, null, null] +26619 - null - [null, null, null, null, null] +26620 - null - [null, null, null, null, null] +26621 - null - [null, null, null, null, null] +26622 - null - [null, null, null, null, null] +26623 - null - [null, null, null, null, null] +26624 - null - [null, null, null, null, null] +26625 - null - [null, null, null, null, null] +26626 - null - [null, null, null, null, null] +26627 - null - [null, null, null, null, null] +26628 - null - [null, null, null, null, null] +26629 - null - [null, null, null, null, null] +26630 - null - [null, null, null, null, null] +26631 - null - [null, null, null, null, null] +26632 - null - [null, null, null, null, null] +26633 - null - [null, null, null, null, null] +26634 - null - [null, null, null, null, null] +26635 - null - [null, null, null, null, null] +26636 - null - [null, null, null, null, null] +26637 - null - [null, null, null, null, null] +26638 - null - [null, null, null, null, null] +26639 - null - [null, null, null, null, null] +26640 - null - [null, null, null, null, null] +26641 - null - [null, null, null, null, null] +26642 - null - [null, null, null, null, null] +26643 - null - [null, null, null, null, null] +26644 - null - [null, null, null, null, null] +26645 - null - [null, null, null, null, null] +26646 - null - [null, null, null, null, null] +26647 - null - [null, null, null, null, null] +26648 - null - [null, null, null, null, null] +26649 - null - [null, null, null, null, null] +26650 - null - [null, null, null, null, null] +26651 - null - [null, null, null, null, null] +26652 - null - [null, null, null, null, null] +26653 - null - [null, null, null, null, null] +26654 - null - [null, null, null, null, null] +26655 - null - [null, null, null, null, null] +26656 - null - [null, null, null, null, null] +26657 - null - [null, null, null, null, null] +26658 - null - [null, null, null, null, null] +26659 - null - [null, null, null, null, null] +26660 - null - [null, null, null, null, null] +26661 - null - [null, null, null, null, null] +26662 - null - [null, null, null, null, null] +26663 - null - [null, null, null, null, null] +26664 - null - [null, null, null, null, null] +26665 - null - [null, null, null, null, null] +26666 - null - [null, null, null, null, null] +26667 - null - [null, null, null, null, null] +26668 - null - [null, null, null, null, null] +26669 - null - [null, null, null, null, null] +26670 - null - [null, null, null, null, null] +26671 - null - [null, null, null, null, null] +26672 - null - [null, null, null, null, null] +26673 - null - [null, null, null, null, null] +26674 - null - [null, null, null, null, null] +26675 - null - [null, null, null, null, null] +26676 - null - [null, null, null, null, null] +26677 - null - [null, null, null, null, null] +26678 - null - [null, null, null, null, null] +26679 - null - [null, null, null, null, null] +26680 - null - [null, null, null, null, null] +26681 - null - [null, null, null, null, null] +26682 - null - [null, null, null, null, null] +26683 - null - [null, null, null, null, null] +26684 - Sewer entrance - [Enter, null, null, null, null] +26685 - Sewer entrance - [Enter, null, null, null, null] +26686 - Sewer entrance - [Enter, null, null, null, null] +26687 - null - [null, null, null, null, null] +26688 - null - [null, null, null, null, null] +26689 - null - [null, null, null, null, null] +26690 - null - [null, null, null, null, null] +26691 - null - [null, null, null, null, null] +26692 - null - [null, null, null, null, null] +26693 - null - [null, null, null, null, null] +26694 - null - [null, null, null, null, null] +26695 - null - [null, null, null, null, null] +26696 - null - [null, null, null, null, null] +26697 - null - [null, null, null, null, null] +26698 - null - [null, null, null, null, null] +26699 - null - [null, null, null, null, null] +26700 - null - [null, null, null, null, null] +26701 - null - [null, null, null, null, null] +26702 - Secure door - [null, null, null, null, null] +26703 - Secure door - [null, null, null, null, null] +26704 - null - [null, null, null, null, null] +26705 - null - [null, null, null, null, null] +26706 - Metal door - [Open, null, null, null, null] +26707 - Metal door - [Close, null, null, null, null] +26708 - Pipe - [null, null, null, null, null] +26709 - Pipe - [null, null, null, null, null] +26710 - Pipe - [null, null, null, null, null] +26711 - Pipe - [null, null, null, null, null] +26712 - null - [null, null, null, null, null] +26713 - Warped tree roots - [Enter, null, null, null, null] +26714 - Warped tree roots - [Enter, null, null, null, null] +26715 - Warped tree roots - [Enter, null, null, null, null] +26716 - Parted tree roots - [null, null, null, null, null] +26717 - Parted tree roots - [null, null, null, null, null] +26718 - Warped tree roots - [null, null, null, null, null] +26719 - Parted tree roots - [null, null, null, null, null] +26720 - Spirit tree - [Talk-to, null, null, null, null] +26721 - Spirit tree - [Talk-to, Teleport, null, null, null] +26722 - Spirit tree - [null, null, null, null, null] +26723 - null - [null, null, null, null, null] +26724 - Tree - [null, null, null, null, null] +26725 - Tree - [Grapple, null, null, null, null] +26726 - Healthorg - [null, null, null, null, null] +26727 - Human food - [null, null, null, null, null] +26728 - Human food - [null, null, null, null, null] +26729 - Human food - [null, null, null, null, null] +26730 - null - [null, null, null, null, null] +26731 - Spirit tree - [null, null, null, null, null] +26732 - Healthorg - [null, null, null, null, null] +26733 - Healthorg - [null, null, null, null, null] +26734 - Alarm button - [null, null, null, null, null] +26735 - null - [null, null, null, null, null] +26736 - null - [null, null, null, null, null] +26737 - null - [null, null, null, null, null] +26738 - null - [null, null, null, null, null] +26739 - null - [null, null, null, null, null] +26740 - null - [null, null, null, null, null] +26741 - null - [null, null, null, null, null] +26742 - Singing bowl - [Inspect, null, Sing-glass, Revert-crystal, null] +26743 - Mahogany chest - [Open, null, null, null, null] +26744 - Mahogany chest - [Search, Close, null, null, null] +26745 - Chest - [Open, null, null, null, null] +26746 - Chest - [Search, Close, null, null, null] +26747 - Chest - [Open, null, null, null, null] +26748 - Chest - [Search, Close, null, null, null] +26749 - Tunnel - [Crawl, null, null, null, null] +26750 - Tunnel - [Crawl, null, null, null, null] +26751 - null - [null, null, null, null, null] +26752 - null - [null, null, null, null, null] +26753 - null - [null, null, null, null, null] +26754 - Tunnel - [Crawl, null, null, null, null] +26755 - null - [null, null, null, null, null] +26756 - null - [null, null, null, null, null] +26757 - null - [null, null, null, null, null] +26758 - null - [null, null, null, null, null] +26759 - null - [null, null, null, null, null] +26760 - null - [null, null, null, null, null] +26761 - null - [null, null, null, null, null] +26762 - Rocks - [null, null, null, null, null] +26763 - Rocks - [null, null, null, null, null] +26764 - Rocks - [null, null, null, null, null] +26765 - Rocks - [null, null, null, null, null] +26766 - Gnome barrel - [null, null, null, null, null] +26767 - Gnome barrels - [null, null, null, null, null] +26768 - Gnome crates - [null, null, null, null, null] +26769 - Gnome crate - [null, null, null, null, null] +26770 - Barrel - [null, null, null, null, null] +26771 - Crate - [Search, null, null, null, null] +26772 - Crate - [Search, null, null, null, null] +26773 - Crate - [Search, null, null, null, null] +26774 - null - [null, null, null, null, null] +26775 - null - [null, null, null, null, null] +26776 - null - [null, null, null, null, null] +26777 - null - [null, null, null, null, null] +26778 - null - [null, null, null, null, null] +26779 - null - [null, null, null, null, null] +26780 - null - [null, null, null, null, null] +26781 - null - [null, null, null, null, null] +26782 - null - [null, null, null, null, null] +26783 - Table - [null, null, null, null, null] +26784 - Stool - [null, null, null, null, null] +26785 - Smashed chair - [null, null, null, null, null] +26786 - null - [null, null, null, null, null] +26787 - Door - [Open, null, null, null, null] +26788 - Yewnock's machine - [null, null, null, null, null] +26789 - Cogs - [null, null, null, null, null] +26790 - null - [null, null, null, null, null] +26791 - Yewnock's machine - [Operate, null, null, null, null] +26792 - Yewnock's exchanger - [Use, null, null, null, null] +26793 - null - [null, null, null, null, null] +26794 - null - [null, null, null, null, null] +26795 - null - [null, null, null, null, null] +26796 - null - [null, null, null, null, null] +26797 - null - [null, null, null, null, null] +26798 - null - [null, null, null, null, null] +26799 - null - [null, null, null, null, null] +26800 - null - [null, null, null, null, null] +26801 - null - [null, null, null, null, null] +26802 - Lectern - [Read, null, null, null, null] +26803 - Hatch door - [Peek, null, null, null, null] +26804 - Hatch door - [Peek, null, null, null, null] +26805 - null - [null, null, null, null, null] +26806 - Staircase - [Climb-up, null, null, null, null] +26807 - Table - [null, J-mod Options, null, null, null] +26808 - Door - [Open, null, null, null, null] +26809 - null - [null, null, null, null, null] +26810 - Door - [Open, null, null, null, null] +26811 - null - [null, null, null, null, null] +26812 - null - [null, null, null, null, null] +26813 - null - [null, null, null, null, null] +26814 - Furnace - [null, Smelt, null, null, null] +26815 - Whetstone - [null, null, null, null, null] +26816 - Lathe - [null, null, null, null, null] +26817 - Anvil - [null, null, null, null, null] +26818 - Bellows - [null, null, null, null, null] +26819 - Cart - [null, null, null, null, null] +26820 - Junk - [null, null, null, null, null] +26821 - null - [null, null, null, null, null] +26822 - null - [null, null, null, null, null] +26823 - Coal - [null, null, null, null, null] +26824 - Coal - [null, null, null, null, null] +26825 - null - [null, null, null, null, null] +26826 - null - [null, null, null, null, null] +26827 - null - [null, null, null, null, null] +26828 - null - [null, null, null, null, null] +26829 - null - [null, null, null, null, null] +26830 - null - [null, null, null, null, null] +26831 - null - [null, null, null, null, null] +26832 - null - [null, null, null, null, null] +26833 - null - [null, null, null, null, null] +26834 - null - [null, null, null, null, null] +26835 - null - [null, null, null, null, null] +26836 - null - [null, null, null, null, null] +26837 - null - [null, null, null, null, null] +26838 - null - [null, null, null, null, null] +26839 - null - [null, null, null, null, null] +26840 - null - [null, null, null, null, null] +26841 - null - [null, null, null, null, null] +26842 - null - [null, null, null, null, null] +26843 - null - [null, null, null, null, null] +26844 - Crack - [Squeeze-through, null, null, null, null] +26845 - Crack - [Squeeze-through, null, null, null, null] +26846 - null - [null, null, null, null, null] +26847 - Runecrafting altar - [Craft-rune, null, null, null, null] +26848 - null - [null, null, null, null, null] +26849 - Ladder - [Climb, null, null, null, null] +26850 - Ladder - [Climb, null, null, null, null] +26851 - Big door - [Close, null, null, null, null] +26852 - Big door - [Close, null, null, null, null] +26853 - null - [null, null, null, null, null] +26854 - null - [null, null, null, null, null] +26855 - null - [null, null, null, null, null] +26856 - null - [null, null, null, null, null] +26857 - null - [null, null, null, null, null] +26858 - null - [null, null, null, null, null] +26859 - null - [null, null, null, null, null] +26860 - null - [null, null, null, null, null] +26861 - null - [null, null, null, null, null] +26862 - null - [null, null, null, null, null] +26863 - null - [null, null, null, null, null] +26864 - null - [null, null, null, null, null] +26865 - null - [null, null, null, null, null] +26866 - null - [null, null, null, null, null] +26867 - null - [null, null, null, null, null] +26868 - null - [null, null, null, null, null] +26869 - null - [null, null, null, null, null] +26870 - null - [null, null, null, null, null] +26871 - null - [null, null, null, null, null] +26872 - null - [null, null, null, null, null] +26873 - null - [null, null, null, null, null] +26874 - null - [null, null, null, null, null] +26875 - null - [null, null, null, null, null] +26876 - null - [null, null, null, null, null] +26877 - null - [null, null, null, null, null] +26878 - null - [null, null, null, null, null] +26879 - null - [null, null, null, null, null] +26880 - null - [null, null, null, null, null] +26881 - null - [null, null, null, null, null] +26882 - null - [null, null, null, null, null] +26883 - null - [null, null, null, null, null] +26884 - Rocks - [Mine, Prospect, hidden, null, null] +26885 - null - [null, null, null, null, null] +26886 - null - [null, null, null, null, null] +26887 - null - [null, null, null, null, null] +26888 - Rocks - [Mine, Prospect, hidden, null, null] +26889 - null - [null, null, null, null, null] +26890 - null - [null, null, null, null, null] +26891 - null - [null, null, null, null, null] +26892 - null - [null, null, null, null, null] +26893 - null - [null, null, null, null, null] +26894 - null - [null, null, null, null, null] +26895 - null - [null, null, null, null, null] +26896 - null - [null, null, null, null, null] +26897 - null - [null, null, null, null, null] +26898 - null - [null, null, null, null, null] +26899 - null - [null, null, null, null, null] +26900 - null - [null, null, null, null, null] +26901 - null - [null, null, null, null, null] +26902 - null - [null, null, null, null, null] +26903 - null - [null, null, null, null, null] +26904 - null - [null, null, null, null, null] +26905 - null - [null, null, null, null, null] +26906 - Large door - [Open, null, null, null, null] +26907 - Large door - [Close, null, null, null, null] +26908 - Large door - [Open, null, null, null, null] +26909 - Large door - [Close, null, null, null, null] +26910 - Large door - [Open, null, null, null, null] +26911 - Large door - [Close, null, null, null, null] +26912 - null - [null, null, null, null, null] +26913 - Large door - [Open, null, null, null, null] +26914 - Large door - [Close, null, null, null, null] +26915 - null - [null, null, null, null, null] +26916 - Door - [Close, null, null, null, null] +26917 - Door - [Open, null, null, null, null] +26918 - Rack - [null, null, null, null, null] +26919 - null - [null, null, null, null, null] +26920 - null - [null, null, null, null, null] +26921 - null - [null, null, null, null, null] +26922 - null - [null, null, null, null, null] +26923 - null - [null, null, null, null, null] +26924 - null - [null, null, null, null, null] +26925 - null - [null, null, null, null, null] +26926 - null - [null, null, null, null, null] +26927 - null - [null, null, null, null, null] +26928 - null - [null, null, null, null, null] +26929 - null - [null, null, null, null, null] +26930 - null - [null, null, null, null, null] +26931 - null - [null, null, null, null, null] +26932 - null - [null, null, null, null, null] +26933 - Trapdoor - [Open, null, null, null, null] +26934 - Trapdoor - [Climb-down, Close, null, null, null] +26935 - Coffin - [Open, null, null, null, null] +26936 - Coffin - [Close, null, null, null, null] +26937 - Coffin - [Open, null, null, null, null] +26938 - Coffin - [Close, null, null, null, null] +26939 - Coffin - [Open, null, null, null, null] +26940 - Coffin - [Close, null, null, null, null] +26941 - Coffin - [Open, null, null, null, null] +26942 - Coffin - [Close, null, null, null, null] +26943 - Coffin - [Open, null, null, null, null] +26944 - Coffin - [Close, null, null, null, null] +26945 - Well - [null, null, null, null, null] +26946 - null - [null, null, null, null, null] +26947 - Warehouse shelves - [null, null, null, null, null] +26948 - Warehouse shelves - [null, null, null, null, null] +26949 - Warehouse shelves - [null, null, null, null, null] +26950 - Warehouse shelves - [null, null, null, null, null] +26951 - Bookcase - [null, null, null, null, null] +26952 - Bookcase - [null, null, null, null, null] +26953 - Stepladder - [null, null, null, null, null] +26954 - Bed - [null, null, null, null, null] +26955 - Bed - [null, null, null, null, null] +26956 - null - [null, null, null, null, null] +26957 - Large table - [null, null, null, null, null] +26958 - Small table - [null, null, null, null, null] +26959 - Small table - [null, null, null, null, null] +26960 - null - [null, null, null, null, null] +26961 - Crate - [Search, null, null, null, null] +26962 - Crates - [Search, null, null, null, null] +26963 - Stool - [null, null, null, null, null] +26964 - null - [null, null, null, null, null] +26965 - null - [null, null, null, null, null] +26966 - Sink - [null, null, null, null, null] +26967 - null - [null, null, null, null, null] +26968 - null - [null, null, null, null, null] +26969 - Bank deposit box - [Deposit, null, null, null, null] +26970 - Bank table - [null, null, null, null, null] +26971 - Sign - [null, null, null, null, null] +26972 - Bank booth - [Use, Use-quickly, Collect, null, null] +26973 - null - [null, null, null, null, null] +26974 - null - [null, null, null, null, null] +26975 - null - [null, null, null, null, null] +26976 - null - [null, null, null, null, null] +26977 - null - [null, null, null, null, null] +26978 - null - [null, null, null, null, null] +26979 - null - [null, null, null, null, null] +26980 - null - [null, null, null, null, null] +26981 - null - [null, null, null, null, null] +26982 - Ladder - [Climb-up, null, null, null, null] +26983 - Ladder - [Climb-down, null, null, null, null] +26984 - null - [null, null, null, null, null] +26985 - null - [null, null, null, null, null] +26986 - null - [null, null, null, null, null] +26987 - null - [null, null, null, null, null] +26988 - null - [null, null, null, null, null] +26989 - null - [null, null, null, null, null] +26990 - null - [null, null, null, null, null] +26991 - null - [null, null, null, null, null] +26992 - null - [null, null, null, null, null] +26993 - null - [null, null, null, null, null] +26994 - null - [null, null, null, null, null] +26995 - null - [null, null, null, null, null] +26996 - null - [null, null, null, null, null] +26997 - null - [null, null, null, null, null] +26998 - null - [null, null, null, null, null] +26999 - null - [null, null, null, null, null] +27000 - null - [null, null, null, null, null] +27001 - null - [null, null, null, null, null] +27002 - null - [null, null, null, null, null] +27003 - null - [null, null, null, null, null] +27004 - null - [null, null, null, null, null] +27005 - Suit of armour - [null, null, null, null, null] +27006 - Hanging banner - [null, null, null, null, null] +27007 - Hanging banner - [null, null, null, null, null] +27008 - Clothes equipment - [null, null, null, null, null] +27009 - null - [null, null, null, null, null] +27010 - Staircase - [Climb, null, null, null, null] +27011 - Staircase - [Climb, null, null, null, null] +27012 - Crate - [Search, null, null, null, null] +27013 - Crate - [Search, null, null, null, null] +27014 - Table - [Take-from, null, null, null, null] +27015 - Crate - [Search, null, null, null, null] +27016 - Boxes - [Search, null, null, null, null] +27017 - Crate - [Search, null, null, null, null] +27018 - null - [null, null, null, null, null] +27019 - null - [null, null, null, null, null] +27020 - null - [null, null, null, null, null] +27021 - null - [null, null, null, null, null] +27022 - Jade vine patch - [null, Inspect, null, Guide, null] +27023 - Jade vine patch - [null, Inspect, null, Guide, null] +27024 - Jade vine patch - [null, Inspect, null, Guide, null] +27025 - Jade vine patch - [null, Inspect, null, Guide, null] +27026 - Jade vine - [null, Inspect, null, Guide, null] +27027 - Jade vine - [null, Inspect, null, Guide, null] +27028 - Jade vine - [null, Inspect, null, Guide, null] +27029 - Jade vine - [null, Inspect, null, Guide, null] +27030 - Jade vine - [null, Inspect, null, Guide, null] +27031 - Jade vine - [null, Inspect, null, Guide, null] +27032 - Jade vine - [null, Inspect, null, Guide, null] +27033 - Jade vine - [Check-health, Inspect, null, Guide, null] +27034 - Jade vine - [Prune, Inspect, null, Guide, null] +27035 - Jade vine - [Prune, Inspect, null, Guide, null] +27036 - Jade vine - [Prune, Inspect, null, Guide, null] +27037 - Jade vine - [Prune, Inspect, null, Guide, null] +27038 - Jade vine - [Prune, Inspect, null, Guide, null] +27039 - Jade vine - [Attack, null, null, null, null] +27040 - Diseased jade vine - [null, Inspect, null, Guide, null] +27041 - Diseased jade vine - [null, Inspect, null, Guide, null] +27042 - Diseased jade vine - [null, Inspect, null, Guide, null] +27043 - Diseased jade vine - [null, Inspect, null, Guide, null] +27044 - Diseased jade vine - [null, Inspect, null, Guide, null] +27045 - Dead jade vine - [null, Inspect, null, Guide, null] +27046 - Dead jade vine - [null, Inspect, null, Guide, null] +27047 - Dead jade vine - [null, Inspect, null, Guide, null] +27048 - Dead jade vine - [null, Inspect, null, Guide, null] +27049 - Dead jade vine - [null, Inspect, null, Guide, null] +27050 - null - [null, null, null, null, null] +27051 - Grandfather clock - [null, null, null, null, null] +27052 - Table - [null, null, null, null, null] +27053 - A parcel - [null, null, null, null, null] +27054 - Smelly package - [null, null, null, null, null] +27055 - Smelly package - [Open, null, null, null, null] +27056 - Table - [null, null, null, null, null] +27057 - Open package - [null, null, null, null, null] +27058 - Loose soil - [Dig, null, null, null, null] +27059 - Roots - [Cut, null, null, null, null] +27060 - Cut roots - [null, null, null, null, null] +27061 - Horacio's jade vine patch - [null, null, null, null, null] +27062 - Wild jade vine - [Attack, null, null, null, null] +27063 - Horacio's patch - [null, null, null, null, null] +27064 - Horacio's jade vine patch - [null, null, null, null, null] +27065 - Gate - [Open, null, null, null, null] +27066 - Gate - [Open, null, null, null, null] +27067 - Grave - [null, null, null, null, null] +27068 - Grave - [null, null, null, null, null] +27069 - null - [null, null, null, null, null] +27070 - Loose earth - [null, null, null, null, null] +27071 - Exposed root - [null, null, null, null, null] +27072 - Cut root - [null, null, null, null, null] +27073 - Ugly flowerbed - [null, null, null, null, null] +27074 - Beautiful flowerbed - [null, null, null, null, null] +27075 - null - [null, null, null, null, null] +27076 - Wild jade vine - [null, null, null, null, null] +27077 - Wild jade vine - [null, null, null, null, null] +27078 - Wild jade vine - [Cut, null, null, null, null] +27079 - null - [null, null, null, null, null] +27080 - null - [null, null, null, null, null] +27081 - null - [null, null, null, null, null] +27082 - Counter - [null, null, null, null, null] +27083 - Table - [null, null, null, null, null] +27084 - Barrel - [null, null, null, null, null] +27085 - Boxes - [Search, null, null, null, null] +27086 - Crates - [Search, null, null, null, null] +27087 - Crate - [Search, null, null, null, null] +27088 - null - [null, null, null, null, null] +27089 - Tree - [null, null, null, null, null] +27090 - null - [null, null, null, null, null] +27091 - null - [null, null, null, null, null] +27092 - null - [null, null, null, null, null] +27093 - null - [null, null, null, null, null] +27094 - null - [null, null, null, null, null] +27095 - null - [null, null, null, null, null] +27096 - null - [null, null, null, null, null] +27097 - null - [null, null, null, null, null] +27098 - null - [null, null, null, null, null] +27099 - null - [null, null, null, null, null] +27100 - null - [null, null, null, null, null] +27101 - null - [null, null, null, null, null] +27102 - null - [null, null, null, null, null] +27103 - null - [null, null, null, null, null] +27104 - null - [null, null, null, null, null] +27105 - null - [null, null, null, null, null] +27106 - null - [null, null, null, null, null] +27107 - null - [null, null, null, null, null] +27108 - null - [null, null, null, null, null] +27109 - null - [null, null, null, null, null] +27110 - null - [null, null, null, null, null] +27111 - null - [null, null, null, null, null] +27112 - null - [null, null, null, null, null] +27113 - null - [null, null, null, null, null] +27114 - null - [null, null, null, null, null] +27115 - null - [null, null, null, null, null] +27116 - null - [null, null, null, null, null] +27117 - null - [null, null, null, null, null] +27118 - null - [null, null, null, null, null] +27119 - null - [null, null, null, null, null] +27120 - null - [null, null, null, null, null] +27121 - null - [null, null, null, null, null] +27122 - null - [null, null, null, null, null] +27123 - null - [null, null, null, null, null] +27124 - null - [null, null, null, null, null] +27125 - null - [null, null, null, null, null] +27126 - Vine - [Climb-up, null, null, null, null] +27127 - null - [null, null, null, null, null] +27128 - Vine - [Climb-up, null, null, null, null] +27129 - Vine - [Climb-down, null, null, null, null] +27130 - Vine - [Climb-down, null, null, null, null] +27131 - null - [null, null, null, null, null] +27132 - Vine - [null, null, null, null, null] +27133 - Vine - [null, null, null, null, null] +27134 - null - [null, null, null, null, null] +27135 - null - [null, null, null, null, null] +27136 - null - [null, null, null, null, null] +27137 - null - [null, null, null, null, null] +27138 - null - [null, null, null, null, null] +27139 - null - [null, null, null, null, null] +27140 - null - [null, null, null, null, null] +27141 - null - [null, null, null, null, null] +27142 - null - [null, null, null, null, null] +27143 - null - [null, null, null, null, null] +27144 - null - [null, null, null, null, null] +27145 - null - [null, null, null, null, null] +27146 - null - [null, null, null, null, null] +27147 - null - [null, null, null, null, null] +27148 - null - [null, null, null, null, null] +27149 - null - [null, null, null, null, null] +27150 - null - [null, null, null, null, null] +27151 - Vine - [Climb-up, null, null, null, null] +27152 - Vine - [Climb-up, null, null, null, null] +27153 - null - [null, null, null, null, null] +27154 - null - [null, null, null, null, null] +27155 - null - [null, null, null, null, null] +27156 - null - [null, null, null, null, null] +27157 - null - [null, null, null, null, null] +27158 - null - [null, null, null, null, null] +27159 - null - [null, null, null, null, null] +27160 - null - [null, null, null, null, null] +27161 - null - [null, null, null, null, null] +27162 - null - [null, null, null, null, null] +27163 - null - [null, null, null, null, null] +27164 - null - [null, null, null, null, null] +27165 - null - [null, null, null, null, null] +27166 - null - [null, null, null, null, null] +27167 - null - [null, null, null, null, null] +27168 - null - [null, null, null, null, null] +27169 - null - [null, null, null, null, null] +27170 - null - [null, null, null, null, null] +27171 - null - [null, null, null, null, null] +27172 - null - [null, null, null, null, null] +27173 - Vines - [null, null, null, Cut, null] +27174 - Cut vines - [Crawl-through, null, null, null, null] +27175 - Vines - [Squeeze-through, null, null, null, null] +27176 - Vines - [Crawl-through, null, null, null, null] +27177 - null - [null, null, null, null, null] +27178 - null - [null, null, null, null, null] +27179 - null - [null, null, null, null, null] +27180 - Vine - [Swing-on, null, null, null, null] +27181 - Vine - [Enter, null, null, null, null] +27182 - Vine - [Enter, null, null, null, null] +27183 - null - [null, null, null, null, null] +27184 - null - [null, null, null, null, null] +27185 - Vine - [Cross, null, null, null, null] +27186 - Hole - [Enter, null, null, null, null] +27187 - Wasp nest - [null, null, null, null, null] +27188 - null - [null, null, null, null, null] +27189 - null - [null, null, null, null, null] +27190 - null - [null, null, null, null, null] +27191 - null - [null, null, null, null, null] +27192 - null - [null, null, null, null, null] +27193 - null - [null, null, null, null, null] +27194 - null - [null, null, null, null, null] +27195 - null - [null, null, null, null, null] +27196 - null - [null, null, null, null, null] +27197 - null - [null, null, null, null, null] +27198 - null - [null, null, null, null, null] +27199 - null - [null, null, null, null, null] +27200 - null - [null, null, null, null, null] +27201 - Bush - [null, null, null, null, null] +27202 - null - [null, null, null, null, null] +27203 - null - [null, null, null, null, null] +27204 - null - [null, null, null, null, null] +27205 - null - [null, null, null, null, null] +27206 - null - [null, null, null, null, null] +27207 - null - [null, null, null, null, null] +27208 - null - [null, null, null, null, null] +27209 - null - [null, null, null, null, null] +27210 - null - [null, null, null, null, null] +27211 - Ramp - [Exit, null, null, null, null] +27212 - Ramp - [Enter, null, null, null, null] +27213 - null - [null, null, null, null, null] +27214 - null - [null, null, null, null, null] +27215 - null - [null, null, null, null, null] +27216 - null - [null, null, null, null, null] +27217 - null - [null, null, null, null, null] +27218 - Slide - [Slide-down, null, null, null, null] +27219 - null - [null, null, null, null, null] +27220 - null - [null, null, null, null, null] +27221 - null - [null, null, null, null, null] +27222 - null - [null, null, null, null, null] +27223 - null - [null, null, null, null, null] +27224 - null - [null, null, null, null, null] +27225 - null - [null, null, null, null, null] +27226 - null - [null, null, null, null, null] +27227 - null - [null, null, null, null, null] +27228 - null - [null, null, null, null, null] +27229 - null - [null, null, null, null, null] +27230 - null - [null, null, null, null, null] +27231 - null - [null, null, null, null, null] +27232 - null - [null, null, null, null, null] +27233 - null - [null, null, null, null, null] +27234 - null - [null, null, null, null, null] +27235 - null - [null, null, null, null, null] +27236 - null - [null, null, null, null, null] +27237 - null - [null, null, null, null, null] +27238 - null - [null, null, null, null, null] +27239 - null - [null, null, null, null, null] +27240 - Pitfall - [null, null, null, null, null] +27241 - Torch - [null, null, null, null, null] +27242 - Staircase - [Climb-up, null, null, null, null] +27243 - Staircase - [Climb-down, null, null, null, null] +27244 - Chair - [null, null, null, null, null] +27245 - Table - [Search, null, null, null, null] +27246 - Cabinets - [Search, null, null, null, null] +27247 - Cabinets - [Search, null, null, null, null] +27248 - Bookcases - [Search, null, null, null, null] +27249 - Bookcases - [Search, null, null, null, null] +27250 - Bookcases - [Search, null, null, null, null] +27251 - Fireplace - [Search, null, null, null, null] +27252 - Sofa - [Search, null, null, null, null] +27253 - Fishtank - [Search, null, null, null, null] +27254 - Dark portal - [Enter, null, null, null, null] +27255 - Grim chest - [Open, null, null, null, null] +27256 - Grim chest - [Search, null, null, null, null] +27257 - Skull - [Pick-up, null, null, null, null] +27258 - Skeleton portrait - [null, null, null, null, null] +27259 - Zombie portrait - [null, null, null, null, null] +27260 - Shelves - [Search, null, null, null, null] +27261 - Shelves - [Search, null, null, null, null] +27262 - Sullen tree - [null, null, null, null, null] +27263 - Bleak tree - [null, null, null, null, null] +27264 - Foul tree - [null, null, null, null, null] +27265 - Wretched tree - [null, null, null, null, null] +27266 - Spider web - [Pass, null, null, null, null] +27267 - null - [null, null, null, null, null] +27268 - null - [null, null, null, null, null] +27269 - null - [null, null, null, null, null] +27270 - null - [null, null, null, null, null] +27271 - null - [null, null, null, null, null] +27272 - null - [null, null, null, null, null] +27273 - null - [null, null, null, null, null] +27274 - Gargoyle - [null, null, null, null, null] +27275 - Gargoyle - [null, null, null, null, null] +27276 - Doorway - [Pass, null, null, null, null] +27277 - null - [null, null, null, null, null] +27278 - Springboard - [Step-on, null, null, null, null] +27279 - null - [null, null, null, null, null] +27280 - Worm - [null, null, null, null, null] +27281 - Cursed tree - [null, null, null, null, null] +27282 - Doorway - [null, null, null, null, null] +27283 - Grave - [Say-name, null, null, null, null] +27284 - Grave - [Say-name, null, null, null, null] +27285 - Grave - [Say-name, null, null, null, null] +27286 - Grave - [Say-name, null, null, null, null] +27287 - Grave - [Say-name, null, null, null, null] +27288 - Grave - [null, null, null, null, null] +27289 - null - [null, null, null, null, null] +27290 - null - [null, null, null, null, null] +27291 - null - [null, null, null, null, null] +27292 - null - [null, null, null, null, null] +27293 - null - [null, null, null, null, null] +27294 - Tendrils - [null, null, null, null, null] +27295 - Tendrils - [null, null, null, null, null] +27296 - Tendrils - [null, null, null, null, null] +27297 - Fire - [null, null, null, null, null] +27298 - null - [null, null, null, null, null] +27299 - null - [null, null, null, null, null] +27300 - null - [null, null, null, null, null] +27301 - null - [null, null, null, null, null] +27302 - null - [null, null, null, null, null] +27303 - null - [null, null, null, null, null] +27304 - null - [null, null, null, null, null] +27305 - Crate - [Search, null, null, null, null] +27306 - Altar - [Pray-at, null, null, null, null] +27307 - Altar - [null, null, null, null, null] +27308 - Altar - [null, null, null, null, null] +27309 - Altar - [null, null, null, null, null] +27310 - null - [null, null, null, null, null] +27311 - null - [null, null, null, null, null] +27312 - null - [null, null, null, null, null] +27313 - null - [null, null, null, null, null] +27314 - Stone pew - [null, null, null, null, null] +27315 - Stool - [null, null, null, null, null] +27316 - null - [null, null, null, null, null] +27317 - null - [null, null, null, null, null] +27318 - null - [null, null, null, null, null] +27319 - null - [null, null, null, null, null] +27320 - Machine - [Adjust, null, null, null, null] +27321 - Rock wall - [null, null, null, null, null] +27322 - null - [null, null, null, null, null] +27323 - null - [null, null, null, null, null] +27324 - null - [null, null, null, null, null] +27325 - Fairy ring - [Use, null, null, null, null] +27326 - null - [null, null, null, null, null] +27327 - null - [null, null, null, null, null] +27328 - null - [null, null, null, null, null] +27329 - Fairy portal - [null, null, null, null, null] +27330 - Fairy portal - [null, null, null, null, null] +27331 - null - [null, null, null, null, null] +27332 - Door - [Open, null, null, null, null] +27333 - Door - [Open, null, null, null, null] +27334 - Altar - [null, null, null, null, null] +27335 - null - [null, null, null, null, null] +27336 - null - [null, null, null, null, null] +27337 - null - [null, null, null, null, null] +27338 - Altar - [Pray-at, null, null, null, null] +27339 - Altar - [Pray-at, null, null, null, null] +27340 - Archway - [null, null, null, null, null] +27341 - Mushroom tree - [null, null, null, null, null] +27342 - Mushroom tree - [null, null, null, null, null] +27343 - Mushroom tree - [null, null, null, null, null] +27344 - Plant - [null, null, null, null, null] +27345 - Plants - [null, null, null, null, null] +27346 - Plant - [null, null, null, null, null] +27347 - Plant - [null, null, null, null, null] +27348 - Plant - [null, null, null, null, null] +27349 - null - [null, null, null, null, null] +27350 - null - [null, null, null, null, null] +27351 - null - [null, null, null, null, null] +27352 - null - [null, null, null, null, null] +27353 - null - [null, null, null, null, null] +27354 - Tent - [null, null, null, null, null] +27355 - Plant - [null, null, null, null, null] +27356 - Plant - [null, null, null, null, null] +27357 - Plant - [null, null, null, null, null] +27358 - null - [null, null, null, null, null] +27359 - null - [null, null, null, null, null] +27360 - null - [null, null, null, null, null] +27361 - null - [null, null, null, null, null] +27362 - null - [null, null, null, null, null] +27363 - null - [null, null, null, null, null] +27364 - null - [null, null, null, null, null] +27365 - null - [null, null, null, null, null] +27366 - null - [null, null, null, null, null] +27367 - null - [null, null, null, null, null] +27368 - null - [null, null, null, null, null] +27369 - null - [null, null, null, null, null] +27370 - null - [null, null, null, null, null] +27371 - null - [null, null, null, null, null] +27372 - null - [null, null, null, null, null] +27373 - null - [null, null, null, null, null] +27374 - null - [null, null, null, null, null] +27375 - null - [null, null, null, null, null] +27376 - null - [null, null, null, null, null] +27377 - null - [null, null, null, null, null] +27378 - null - [null, null, null, null, null] +27379 - null - [null, null, null, null, null] +27380 - null - [null, null, null, null, null] +27381 - null - [null, null, null, null, null] +27382 - null - [null, null, null, null, null] +27383 - null - [null, null, null, null, null] +27384 - null - [null, null, null, null, null] +27385 - null - [null, null, null, null, null] +27386 - null - [null, null, null, null, null] +27387 - null - [null, null, null, null, null] +27388 - null - [null, null, null, null, null] +27389 - null - [null, null, null, null, null] +27390 - null - [null, null, null, null, null] +27391 - null - [null, null, null, null, null] +27392 - null - [null, null, null, null, null] +27393 - null - [null, null, null, null, null] +27394 - null - [null, null, null, null, null] +27395 - null - [null, null, null, null, null] +27396 - null - [null, null, null, null, null] +27397 - null - [null, null, null, null, null] +27398 - null - [null, null, null, null, null] +27399 - null - [null, null, null, null, null] +27400 - null - [null, null, null, null, null] +27401 - null - [null, null, null, null, null] +27402 - null - [null, null, null, null, null] +27403 - null - [null, null, null, null, null] +27404 - null - [null, null, null, null, null] +27405 - null - [null, null, null, null, null] +27406 - null - [null, null, null, null, null] +27407 - null - [null, null, null, null, null] +27408 - null - [null, null, null, null, null] +27409 - null - [null, null, null, null, null] +27410 - null - [null, null, null, null, null] +27411 - null - [null, null, null, null, null] +27412 - null - [null, null, null, null, null] +27413 - null - [null, null, null, null, null] +27414 - null - [null, null, null, null, null] +27415 - null - [null, null, null, null, null] +27416 - null - [null, null, null, null, null] +27417 - null - [null, null, null, null, null] +27418 - null - [null, null, null, null, null] +27419 - null - [null, null, null, null, null] +27420 - null - [null, null, null, null, null] +27421 - null - [null, null, null, null, null] +27422 - null - [null, null, null, null, null] +27423 - null - [null, null, null, null, null] +27424 - null - [null, null, null, null, null] +27425 - null - [null, null, null, null, null] +27426 - null - [null, null, null, null, null] +27427 - null - [null, null, null, null, null] +27428 - null - [null, null, null, null, null] +27429 - null - [null, null, null, null, null] +27430 - null - [null, null, null, null, null] +27431 - null - [null, null, null, null, null] +27432 - null - [null, null, null, null, null] +27433 - null - [null, null, null, null, null] +27434 - null - [null, null, null, null, null] +27435 - null - [null, null, null, null, null] +27436 - null - [null, null, null, null, null] +27437 - null - [null, null, null, null, null] +27438 - null - [null, null, null, null, null] +27439 - null - [null, null, null, null, null] +27440 - null - [null, null, null, null, null] +27441 - null - [null, null, null, null, null] +27442 - null - [null, null, null, null, null] +27443 - null - [null, null, null, null, null] +27444 - null - [null, null, null, null, null] +27445 - null - [null, null, null, null, null] +27446 - null - [null, null, null, null, null] +27447 - null - [null, null, null, null, null] +27448 - null - [null, null, null, null, null] +27449 - null - [null, null, null, null, null] +27450 - null - [null, null, null, null, null] +27451 - null - [null, null, null, null, null] +27452 - null - [null, null, null, null, null] +27453 - null - [null, null, null, null, null] +27454 - null - [null, null, null, null, null] +27455 - null - [null, null, null, null, null] +27456 - null - [null, null, null, null, null] +27457 - null - [null, null, null, null, null] +27458 - null - [null, null, null, null, null] +27459 - null - [null, null, null, null, null] +27460 - null - [null, null, null, null, null] +27461 - null - [null, null, null, null, null] +27462 - null - [null, null, null, null, null] +27463 - null - [null, null, null, null, null] +27464 - null - [null, null, null, null, null] +27465 - null - [null, null, null, null, null] +27466 - null - [null, null, null, null, null] +27467 - null - [null, null, null, null, null] +27468 - null - [null, null, null, null, null] +27469 - null - [null, null, null, null, null] +27470 - null - [null, null, null, null, null] +27471 - null - [null, null, null, null, null] +27472 - null - [null, null, null, null, null] +27473 - null - [null, null, null, null, null] +27474 - null - [null, null, null, null, null] +27475 - null - [null, null, null, null, null] +27476 - null - [null, null, null, null, null] +27477 - null - [null, null, null, null, null] +27478 - null - [null, null, null, null, null] +27479 - null - [null, null, null, null, null] +27480 - null - [null, null, null, null, null] +27481 - null - [null, null, null, null, null] +27482 - null - [null, null, null, null, null] +27483 - null - [null, null, null, null, null] +27484 - null - [null, null, null, null, null] +27485 - null - [null, null, null, null, null] +27486 - null - [null, null, null, null, null] +27487 - null - [null, null, null, null, null] +27488 - null - [null, null, null, null, null] +27489 - null - [null, null, null, null, null] +27490 - null - [null, null, null, null, null] +27491 - null - [null, null, null, null, null] +27492 - null - [null, null, null, null, null] +27493 - null - [null, null, null, null, null] +27494 - null - [null, null, null, null, null] +27495 - null - [null, null, null, null, null] +27496 - null - [null, null, null, null, null] +27497 - null - [null, null, null, null, null] +27498 - null - [null, null, null, null, null] +27499 - null - [null, null, null, null, null] +27500 - null - [null, null, null, null, null] +27501 - null - [null, null, null, null, null] +27502 - null - [null, null, null, null, null] +27503 - null - [null, null, null, null, null] +27504 - null - [null, null, null, null, null] +27505 - null - [null, null, null, null, null] +27506 - null - [null, null, null, null, null] +27507 - null - [null, null, null, null, null] +27508 - null - [null, null, null, null, null] +27509 - null - [null, null, null, null, null] +27510 - null - [null, null, null, null, null] +27511 - null - [null, null, null, null, null] +27512 - null - [null, null, null, null, null] +27513 - null - [null, null, null, null, null] +27514 - null - [null, null, null, null, null] +27515 - null - [null, null, null, null, null] +27516 - null - [null, null, null, null, null] +27517 - null - [null, null, null, null, null] +27518 - null - [null, null, null, null, null] +27519 - null - [null, null, null, null, null] +27520 - null - [null, null, null, null, null] +27521 - null - [null, null, null, null, null] +27522 - null - [null, null, null, null, null] +27523 - null - [null, null, null, null, null] +27524 - null - [null, null, null, null, null] +27525 - Prison door - [Talk-through, null, null, null, null] +27526 - Prison door - [null, null, null, null, null] +27527 - Candle - [null, null, null, null, null] +27528 - null - [null, null, null, null, null] +27529 - Crater - [null, null, null, null, null] +27530 - Crater - [null, null, null, null, null] +27531 - Crater - [null, null, null, null, null] +27532 - null - [null, null, null, null, null] +27533 - null - [null, null, null, null, null] +27534 - null - [null, null, null, null, null] +27535 - null - [null, null, null, null, null] +27536 - null - [null, null, null, null, null] +27537 - null - [null, null, null, null, null] +27538 - null - [null, null, null, null, null] +27539 - null - [null, null, null, null, null] +27540 - null - [null, null, null, null, null] +27541 - null - [null, null, null, null, null] +27542 - null - [null, null, null, null, null] +27543 - Stairs - [Climb-down, null, null, null, null] +27544 - null - [null, null, null, null, null] +27545 - null - [null, null, null, null, null] +27546 - null - [null, null, null, null, null] +27547 - null - [null, null, null, null, null] +27548 - null - [null, null, null, null, null] +27549 - null - [null, null, null, null, null] +27550 - null - [null, null, null, null, null] +27551 - null - [null, null, null, null, null] +27552 - null - [null, null, null, null, null] +27553 - null - [null, null, null, null, null] +27554 - null - [null, null, null, null, null] +27555 - null - [null, null, null, null, null] +27556 - null - [null, null, null, null, null] +27557 - null - [null, null, null, null, null] +27558 - null - [null, null, null, null, null] +27559 - null - [null, null, null, null, null] +27560 - Gate - [Open, null, null, null, null] +27561 - Goblin door - [null, null, null, null, null] +27562 - null - [null, null, null, null, null] +27563 - null - [null, null, null, null, null] +27564 - null - [null, null, null, null, null] +27565 - null - [null, null, null, null, null] +27566 - null - [null, null, null, null, null] +27567 - Portal - [Enter, null, null, null, null] +27568 - Portal - [Enter, null, null, null, null] +27569 - null - [null, null, null, null, null] +27570 - null - [null, null, null, null, null] +27571 - null - [null, null, null, null, null] +27572 - null - [null, null, null, null, null] +27573 - null - [null, null, null, null, null] +27574 - null - [null, null, null, null, null] +27575 - null - [null, null, null, null, null] +27576 - null - [null, null, null, null, null] +27577 - null - [null, null, null, null, null] +27578 - null - [null, null, null, null, null] +27579 - null - [null, null, null, null, null] +27580 - null - [null, null, null, null, null] +27581 - null - [null, null, null, null, null] +27582 - null - [null, null, null, null, null] +27583 - null - [null, null, null, null, null] +27584 - null - [null, null, null, null, null] +27585 - null - [null, null, null, null, null] +27586 - null - [null, null, null, null, null] +27587 - null - [null, null, null, null, null] +27588 - null - [null, null, null, null, null] +27589 - null - [null, null, null, null, null] +27590 - null - [null, null, null, null, null] +27591 - null - [null, null, null, null, null] +27592 - null - [null, null, null, null, null] +27593 - null - [null, null, null, null, null] +27594 - null - [null, null, null, null, null] +27595 - null - [null, null, null, null, null] +27596 - null - [null, null, null, null, null] +27597 - null - [null, null, null, null, null] +27598 - null - [null, null, null, null, null] +27599 - null - [null, null, null, null, null] +27600 - null - [null, null, null, null, null] +27601 - null - [null, null, null, null, null] +27602 - null - [null, null, null, null, null] +27603 - null - [null, null, null, null, null] +27604 - null - [null, null, null, null, null] +27605 - null - [null, null, null, null, null] +27606 - null - [null, null, null, null, null] +27607 - null - [null, null, null, null, null] +27608 - null - [null, null, null, null, null] +27609 - null - [null, null, null, null, null] +27610 - null - [null, null, null, null, null] +27611 - null - [null, null, null, null, null] +27612 - null - [null, null, null, null, null] +27613 - null - [null, null, null, null, null] +27614 - null - [null, null, null, null, null] +27615 - Oozing rock - [null, null, null, null, null] +27616 - null - [null, null, null, null, null] +27617 - null - [null, null, null, null, null] +27618 - null - [null, null, null, null, null] +27619 - null - [null, null, null, null, null] +27620 - null - [null, null, null, null, null] +27621 - null - [null, null, null, null, null] +27622 - null - [null, null, null, null, null] +27623 - null - [null, null, null, null, null] +27624 - null - [null, null, null, null, null] +27625 - null - [null, null, null, null, null] +27626 - null - [null, null, null, null, null] +27627 - null - [null, null, null, null, null] +27628 - null - [null, null, null, null, null] +27629 - null - [null, null, null, null, null] +27630 - null - [null, null, null, null, null] +27631 - null - [null, null, null, null, null] +27632 - null - [null, null, null, null, null] +27633 - null - [null, null, null, null, null] +27634 - null - [null, null, null, null, null] +27635 - null - [null, null, null, null, null] +27636 - null - [null, null, null, null, null] +27637 - null - [null, null, null, null, null] +27638 - null - [null, null, null, null, null] +27639 - null - [null, null, null, null, null] +27640 - null - [null, null, null, null, null] +27641 - null - [null, null, null, null, null] +27642 - null - [null, null, null, null, null] +27643 - null - [null, null, null, null, null] +27644 - null - [null, null, null, null, null] +27645 - null - [null, null, null, null, null] +27646 - null - [null, null, null, null, null] +27647 - null - [null, null, null, null, null] +27648 - null - [null, null, null, null, null] +27649 - null - [null, null, null, null, null] +27650 - null - [null, null, null, null, null] +27651 - null - [null, null, null, null, null] +27652 - null - [null, null, null, null, null] +27653 - null - [null, null, null, null, null] +27654 - Strange box - [Open, null, null, null, null] +27655 - Strange box - [null, null, null, null, null] +27656 - Strange box - [null, null, null, null, null] +27657 - null - [null, null, null, null, null] +27658 - null - [null, null, null, null, null] +27659 - null - [null, null, null, null, null] +27660 - null - [null, null, null, null, null] +27661 - Altar - [Pray-at, null, null, null, null] +27662 - Bank chest - [Open, null, null, null, null] +27663 - Bank chest - [null, Bank, null, null, null] +27664 - null - [null, null, null, null, null] +27665 - null - [null, null, null, null, null] +27666 - null - [null, null, null, null, null] +27667 - Bookcase - [null, null, null, null, null] +27668 - Tournament exit - [Climb-up, null, null, null, null] +27669 - Tournament entrance - [Climb-down, null, null, null, null] +27670 - Roof - [null, null, null, null, null] +27671 - null - [null, null, null, null, null] +27672 - Stool - [null, null, null, null, null] +27673 - Hospital bench - [null, null, null, null, null] +27674 - null - [Close, null, null, null, null] +27675 - Door - [Open, null, null, null, null] +27676 - Drawers - [null, null, null, null, null] +27677 - Drawers - [null, null, null, null, null] +27678 - Drawers - [null, null, null, null, null] +27679 - Drawers - [null, null, null, null, null] +27680 - Upcoming tournament rules - [View, null, null, null, null] +27681 - Upcoming tournament rules - [View, null, null, null, null] +27682 - Upcoming tournament rules - [View, null, null, null, null] +27683 - Upcoming tournament rules - [View, null, null, null, null] +27684 - Ladder - [Climb-down, null, null, null, null] +27685 - Ladder - [Climb-up, null, null, null, null] +27686 - Trapdoor - [Forfeit, null, null, null, null] +27687 - Entrance - [Forfeit, null, null, null, null] +27688 - Entrance - [Forfeit, null, null, null, null] +27689 - Entrance - [Forfeit, null, null, null, null] +27690 - Entrance - [Forfeit, null, null, null, null] +27691 - Entrance - [Forfeit, null, null, null, null] +27692 - Entrance - [Forfeit, null, null, null, null] +27693 - Wall - [null, null, null, null, Lean against] +27694 - Wall - [null, null, null, null, Lean against] +27695 - Wall - [null, null, null, null, Lean against] +27696 - Wall - [null, null, null, null, Lean against] +27697 - Wall - [null, null, null, null, Lean against] +27698 - Tournament scoreboard - [View, null, null, null, null] +27699 - KO Board - Arena 2 - [View, null, null, null, null] +27700 - KO Board - Arena 2 - [View, null, null, null, null] +27701 - KO Board - Arena 3 - [View, null, null, null, null] +27702 - KO Board - Arena 4 - [View, null, null, null, null] +27703 - KO Board - Arena 5 - [View, null, null, null, null] +27704 - KO Board - Arena 6 - [View, null, null, null, null] +27705 - null - [null, null, null, null, null] +27706 - Crates - [null, null, null, null, null] +27707 - Crates - [null, null, null, null, null] +27708 - Crate - [null, null, null, null, null] +27709 - Barrel - [null, null, null, null, null] +27710 - Barrel - [null, null, null, null, null] +27711 - Barrel - [null, null, null, null, null] +27712 - Barrel - [null, null, null, null, null] +27713 - Barrel of swords - [null, null, null, null, null] +27714 - Bench - [null, null, null, null, null] +27715 - Operation lights - [null, null, null, null, null] +27716 - Drip - [null, null, null, null, null] +27717 - Hospital bed - [null, null, null, null, null] +27718 - Hospital bed - [null, null, null, null, null] +27719 - Hospital bed - [null, null, null, null, null] +27720 - Shelves - [null, null, null, null, null] +27721 - Cabinet - [null, null, null, null, null] +27722 - Shelves - [null, null, null, null, null] +27723 - Shelves - [null, null, null, null, null] +27724 - Shelves - [null, null, null, null, null] +27725 - Shelves - [null, null, null, null, null] +27726 - Shelves - [null, null, null, null, null] +27727 - Boxes - [null, null, null, null, null] +27728 - Boxes - [null, null, null, null, null] +27729 - Boxes - [null, null, null, null, null] +27730 - Crate - [null, null, null, null, null] +27731 - Hospital chair - [null, null, null, null, null] +27732 - Hospital chair - [null, null, null, null, null] +27733 - null - [null, null, null, null, null] +27734 - null - [null, null, null, null, null] +27735 - null - [null, null, null, null, null] +27736 - null - [null, null, null, null, null] +27737 - null - [null, null, null, null, null] +27738 - null - [null, null, null, null, null] +27739 - null - [null, null, null, null, null] +27740 - null - [null, null, null, null, null] +27741 - null - [null, null, null, null, null] +27742 - null - [null, null, null, null, null] +27743 - null - [null, null, null, null, null] +27744 - null - [null, null, null, null, null] +27745 - null - [null, null, null, null, null] +27746 - null - [null, null, null, null, null] +27747 - null - [null, null, null, null, null] +27748 - null - [null, null, null, null, null] +27749 - null - [null, null, null, null, null] +27750 - null - [null, null, null, null, null] +27751 - null - [null, null, null, null, null] +27752 - null - [null, null, null, null, null] +27753 - null - [null, null, null, null, null] +27754 - null - [null, null, null, null, null] +27755 - null - [null, null, null, null, null] +27756 - null - [null, null, null, null, null] +27757 - null - [null, null, null, null, null] +27758 - null - [null, null, null, null, null] +27759 - null - [null, null, null, null, null] +27760 - null - [null, null, null, null, null] +27761 - null - [null, null, null, null, null] +27762 - null - [null, null, null, null, null] +27763 - null - [null, null, null, null, null] +27764 - null - [null, null, null, null, null] +27765 - null - [null, null, null, null, null] +27766 - null - [null, null, null, null, null] +27767 - null - [null, null, null, null, null] +27768 - null - [null, null, null, null, null] +27769 - null - [null, null, null, null, null] +27770 - null - [null, null, null, null, null] +27771 - null - [null, null, null, null, null] +27772 - null - [null, null, null, null, null] +27773 - null - [null, null, null, null, null] +27774 - null - [null, null, null, null, null] +27775 - null - [null, null, null, null, null] +27776 - null - [null, null, null, null, null] +27777 - null - [null, null, null, null, null] +27778 - null - [null, null, null, null, null] +27779 - null - [null, null, null, null, null] +27780 - null - [null, null, null, null, null] +27781 - null - [null, null, null, null, null] +27782 - null - [null, null, null, null, null] +27783 - null - [null, null, null, null, null] +27784 - null - [null, null, null, null, null] +27785 - null - [null, null, null, null, null] +27786 - null - [null, null, null, null, null] +27787 - null - [null, null, null, null, null] +27788 - null - [null, null, null, null, null] +27789 - null - [null, null, null, null, null] +27790 - null - [null, null, null, null, null] +27791 - null - [null, null, null, null, null] +27792 - null - [null, null, null, null, null] +27793 - null - [null, null, null, null, null] +27794 - null - [null, null, null, null, null] +27795 - null - [null, null, null, null, null] +27796 - null - [null, null, null, null, null] +27797 - null - [null, null, null, null, null] +27798 - null - [null, null, null, null, null] +27799 - null - [null, null, null, null, null] +27800 - null - [null, null, null, null, null] +27801 - null - [null, null, null, null, null] +27802 - null - [null, null, null, null, null] +27803 - null - [null, null, null, null, null] +27804 - null - [null, null, null, null, null] +27805 - null - [null, null, null, null, null] +27806 - null - [null, null, null, null, null] +27807 - null - [null, null, null, null, null] +27808 - null - [null, null, null, null, null] +27809 - null - [null, null, null, null, null] +27810 - null - [null, null, null, null, null] +27811 - null - [null, null, null, null, null] +27812 - null - [null, null, null, null, null] +27813 - null - [null, null, null, null, null] +27814 - null - [null, null, null, null, null] +27815 - null - [null, null, null, null, null] +27816 - null - [null, null, null, null, null] +27817 - null - [null, null, null, null, null] +27818 - null - [null, null, null, null, null] +27819 - null - [null, null, null, null, null] +27820 - null - [null, null, null, null, null] +27821 - null - [null, null, null, null, null] +27822 - null - [null, null, null, null, null] +27823 - null - [null, null, null, null, null] +27824 - null - [null, null, null, null, null] +27825 - null - [null, null, null, null, null] +27826 - null - [null, null, null, null, null] +27827 - null - [null, null, null, null, null] +27828 - null - [null, null, null, null, null] +27829 - null - [null, null, null, null, null] +27830 - null - [null, null, null, null, null] +27831 - null - [null, null, null, null, null] +27832 - null - [null, null, null, null, null] +27833 - null - [null, null, null, null, null] +27834 - null - [null, null, null, null, null] +27835 - null - [null, null, null, null, null] +27836 - null - [null, null, null, null, null] +27837 - null - [null, null, null, null, null] +27838 - null - [null, null, null, null, null] +27839 - null - [null, null, null, null, null] +27840 - null - [null, null, null, null, null] +27841 - null - [null, null, null, null, null] +27842 - null - [null, null, null, null, null] +27843 - null - [null, null, null, null, null] +27844 - null - [null, null, null, null, null] +27845 - Gate - [null, null, null, null, null] +27846 - Gate - [Open, null, null, null, null] +27847 - Gate - [null, null, null, null, null] +27848 - Gate - [Open, null, null, null, null] +27849 - Chair - [null, null, null, null, null] +27850 - Table - [null, null, null, null, null] +27851 - Gate - [Close, null, null, null, null] +27852 - Gate - [Open, null, null, null, null] +27853 - Gate - [Close, null, null, null, null] +27854 - Gate - [Open, null, null, null, null] +27855 - null - [null, null, null, null, null] +27856 - null - [null, null, null, null, null] +27857 - null - [null, null, null, null, null] +27858 - null - [null, null, null, null, null] +27859 - null - [null, null, null, null, null] +27860 - null - [null, null, null, null, null] +27861 - null - [null, null, null, null, null] +27862 - null - [null, null, null, null, null] +27863 - null - [null, null, null, null, null] +27864 - null - [null, null, null, null, null] +27865 - null - [null, null, null, null, null] +27866 - null - [null, null, null, null, null] +27867 - null - [null, null, null, null, null] +27868 - null - [null, null, null, null, null] +27869 - null - [null, null, null, null, null] +27870 - null - [null, null, null, null, null] +27871 - null - [null, null, null, null, null] +27872 - null - [null, null, null, null, null] +27873 - null - [null, null, null, null, null] +27874 - null - [null, null, null, null, null] +27875 - null - [null, null, null, null, null] +27876 - null - [null, null, null, null, null] +27877 - null - [null, null, null, null, null] +27878 - null - [null, null, null, null, null] +27879 - null - [null, null, null, null, null] +27880 - null - [null, null, null, null, null] +27881 - null - [null, null, null, null, null] +27882 - null - [null, null, null, null, null] +27883 - null - [null, null, null, null, null] +27884 - null - [null, null, null, null, null] +27885 - null - [null, null, null, null, null] +27886 - null - [null, null, null, null, null] +27887 - null - [null, null, null, null, null] +27888 - null - [null, null, null, null, null] +27889 - null - [null, null, null, null, null] +27890 - null - [null, null, null, null, null] +27891 - Torch - [null, null, null, null, null] +27892 - Operation lights - [null, null, null, null, null] +27893 - Operation lights - [null, null, null, null, null] +27894 - Operation lights - [null, null, null, null, null] +27895 - Operation side table - [null, null, null, null, null] +27896 - null - [null, null, null, null, null] +27897 - null - [null, null, null, null, null] +27898 - null - [null, null, null, null, null] +27899 - null - [null, null, null, null, null] +27900 - null - [null, null, null, null, null] +27901 - null - [null, null, null, null, null] +27902 - null - [null, null, null, null, null] +27903 - Operation side table - [null, null, null, null, null] +27904 - Plant - [null, null, null, null, null] +27905 - Plant - [null, null, null, null, null] +27906 - null - [null, null, null, null, null] +27907 - null - [null, null, null, null, null] +27908 - null - [null, null, null, null, null] +27909 - null - [null, null, null, null, null] +27910 - null - [null, null, null, null, null] +27911 - null - [null, null, null, null, null] +27912 - null - [null, null, null, null, null] +27913 - null - [null, null, null, null, null] +27914 - null - [null, null, null, null, null] +27915 - null - [null, null, null, null, null] +27916 - null - [null, null, null, null, null] +27917 - null - [null, null, null, null, null] +27918 - null - [null, null, null, null, null] +27919 - null - [null, null, null, null, null] +27920 - null - [null, null, null, null, null] +27921 - null - [null, null, null, null, null] +27922 - null - [null, null, null, null, null] +27923 - null - [null, null, null, null, null] +27924 - null - [null, null, null, null, null] +27925 - null - [null, null, null, null, null] +27926 - null - [null, null, null, null, null] +27927 - null - [null, null, null, null, null] +27928 - null - [null, null, null, null, null] +27929 - null - [null, null, null, null, null] +27930 - null - [null, null, null, null, null] +27931 - null - [null, null, null, null, null] +27932 - null - [null, null, null, null, null] +27933 - null - [null, null, null, null, null] +27934 - null - [null, null, null, null, null] +27935 - null - [null, null, null, null, null] +27936 - null - [null, null, null, null, null] +27937 - null - [null, null, null, null, null] +27938 - null - [null, null, null, null, null] +27939 - null - [null, null, null, null, null] +27940 - null - [null, null, null, null, null] +27941 - null - [null, null, null, null, null] +27942 - null - [null, null, null, null, null] +27943 - null - [null, null, null, null, null] +27944 - null - [null, null, null, null, null] +27945 - null - [null, null, null, null, null] +27946 - null - [null, null, null, null, null] +27947 - null - [null, null, null, null, null] +27948 - null - [null, null, null, null, null] +27949 - null - [null, null, null, null, null] +27950 - null - [null, null, null, null, null] +27951 - null - [null, null, null, null, null] +27952 - null - [null, null, null, null, null] +27953 - null - [null, null, null, null, null] +27954 - null - [null, null, null, null, null] +27955 - null - [null, null, null, null, null] +27956 - null - [null, null, null, null, null] +27957 - null - [null, null, null, null, null] +27958 - null - [null, null, null, null, null] +27959 - null - [null, null, null, null, null] +27960 - null - [null, null, null, null, null] +27961 - null - [null, null, null, null, null] +27962 - null - [null, null, null, null, null] +27963 - null - [null, null, null, null, null] +27964 - null - [null, null, null, null, null] +27965 - null - [null, null, null, null, null] +27966 - null - [null, null, null, null, null] +27967 - null - [null, null, null, null, null] +27968 - null - [null, null, null, null, null] +27969 - null - [null, null, null, null, null] +27970 - null - [null, null, null, null, null] +27971 - null - [null, null, null, null, null] +27972 - null - [null, null, null, null, null] +27973 - null - [null, null, null, null, null] +27974 - null - [null, null, null, null, null] +27975 - null - [null, null, null, null, null] +27976 - null - [null, null, null, null, null] +27977 - null - [null, null, null, null, null] +27978 - null - [null, null, null, null, null] +27979 - null - [null, null, null, null, null] +27980 - null - [null, null, null, null, null] +27981 - null - [null, null, null, null, null] +27982 - null - [null, null, null, null, null] +27983 - Plant - [null, null, null, null, null] +27984 - null - [null, null, null, null, null] +27985 - null - [null, null, null, null, null] +27986 - null - [null, null, null, null, null] +27987 - null - [null, null, null, null, null] +27988 - Door - [Open, null, null, null, null] +27989 - Door - [Close, null, null, null, null] +27990 - null - [null, null, null, null, null] +27991 - null - [null, null, null, null, null] +27992 - null - [null, null, null, null, null] +27993 - null - [null, null, null, null, null] +27994 - null - [null, null, null, null, null] +27995 - null - [null, null, null, null, null] +27996 - null - [null, null, null, null, null] +27997 - null - [null, null, null, null, null] +27998 - null - [null, null, null, null, null] +27999 - null - [null, null, null, null, null] +28000 - null - [null, null, null, null, null] +28001 - null - [null, null, null, null, null] +28002 - null - [null, null, null, null, null] +28003 - null - [null, null, null, null, null] +28004 - null - [null, null, null, null, null] +28005 - null - [null, null, null, null, null] +28006 - null - [null, null, null, null, null] +28007 - null - [null, null, null, null, null] +28008 - null - [null, null, null, null, null] +28009 - null - [null, null, null, null, null] +28010 - null - [null, null, null, null, null] +28011 - null - [null, null, null, null, null] +28012 - null - [null, null, null, null, null] +28013 - null - [null, null, null, null, null] +28014 - null - [null, null, null, null, null] +28015 - null - [null, null, null, null, null] +28016 - null - [null, null, null, null, null] +28017 - null - [null, null, null, null, null] +28018 - null - [null, null, null, null, null] +28019 - null - [null, null, null, null, null] +28020 - null - [null, null, null, null, null] +28021 - null - [null, null, null, null, null] +28022 - null - [null, null, null, null, null] +28023 - null - [null, null, null, null, null] +28024 - null - [null, null, null, null, null] +28025 - null - [null, null, null, null, null] +28026 - null - [null, null, null, null, null] +28027 - null - [null, null, null, null, null] +28028 - null - [null, null, null, null, null] +28029 - null - [null, null, null, null, null] +28030 - null - [null, null, null, null, null] +28031 - null - [null, null, null, null, null] +28032 - null - [null, null, null, null, null] +28033 - null - [null, null, null, null, null] +28034 - null - [null, null, null, null, null] +28035 - null - [null, null, null, null, null] +28036 - null - [null, null, null, null, null] +28037 - null - [null, null, null, null, null] +28038 - null - [null, null, null, null, null] +28039 - null - [null, null, null, null, null] +28040 - null - [null, null, null, null, null] +28041 - null - [null, null, null, null, null] +28042 - null - [null, null, null, null, null] +28043 - null - [null, null, null, null, null] +28044 - null - [null, null, null, null, null] +28045 - null - [null, null, null, null, null] +28046 - null - [null, null, null, null, null] +28047 - null - [null, null, null, null, null] +28048 - null - [null, null, null, null, null] +28049 - null - [null, null, null, null, null] +28050 - null - [null, null, null, null, null] +28051 - null - [null, null, null, null, null] +28052 - null - [null, null, null, null, null] +28053 - null - [null, null, null, null, null] +28054 - null - [null, null, null, null, null] +28055 - null - [null, null, null, null, null] +28056 - null - [null, null, null, null, null] +28057 - null - [null, null, null, null, null] +28058 - null - [null, null, null, null, null] +28059 - null - [null, null, null, null, null] +28060 - null - [null, null, null, null, null] +28061 - null - [null, null, null, null, null] +28062 - null - [null, null, null, null, null] +28063 - null - [null, null, null, null, null] +28064 - null - [null, null, null, null, null] +28065 - null - [null, null, null, null, null] +28066 - null - [null, null, null, null, null] +28067 - null - [null, null, null, null, null] +28068 - null - [null, null, null, null, null] +28069 - null - [null, null, null, null, null] +28070 - null - [null, null, null, null, null] +28071 - null - [null, null, null, null, null] +28072 - null - [null, null, null, null, null] +28073 - null - [null, null, null, null, null] +28074 - null - [null, null, null, null, null] +28075 - null - [null, null, null, null, null] +28076 - null - [null, null, null, null, null] +28077 - null - [null, null, null, null, null] +28078 - null - [null, null, null, null, null] +28079 - null - [null, null, null, null, null] +28080 - null - [null, null, null, null, null] +28081 - null - [null, null, null, null, null] +28082 - null - [null, null, null, null, null] +28083 - null - [null, null, null, null, null] +28084 - null - [null, null, null, null, null] +28085 - null - [null, null, null, null, null] +28086 - null - [null, null, null, null, null] +28087 - null - [null, null, null, null, null] +28088 - null - [null, null, null, null, null] +28089 - Desk - [Use, Exchange, Collect, History, Sets] +28090 - null - [null, null, null, null, null] +28091 - null - [null, null, null, null, null] +28092 - null - [null, null, null, null, null] +28093 - Grand Exchange pillar - [null, null, null, null, null] +28094 - Hidden trapdoor - [Open, null, null, null, null] +28095 - Upcoming tournament rules - [View, null, null, null, null] +28096 - null - [null, null, null, null, null] +28097 - null - [null, null, null, null, null] +28098 - null - [null, null, null, null, null] +28099 - null - [null, null, null, null, null] +28100 - null - [null, null, null, null, null] +28101 - null - [null, null, null, null, null] +28102 - null - [null, null, null, null, null] +28103 - null - [null, null, null, null, null] +28104 - null - [null, null, null, null, null] +28105 - null - [null, null, null, null, null] +28106 - null - [null, null, null, null, null] +28107 - null - [null, null, null, null, null] +28108 - null - [null, null, null, null, null] +28109 - null - [null, null, null, null, null] +28110 - Cave - [Exit, null, null, null, null] +28111 - null - [null, null, null, null, null] +28112 - null - [null, null, null, null, null] +28113 - null - [null, null, null, null, null] +28114 - null - [null, null, null, null, null] +28115 - Rogues' scoreboard - [View, null, null, null, null] +28116 - Hunters' scoreboard - [View, null, null, null, null] +28117 - null - [null, null, null, null, null] +28118 - null - [null, null, null, null, null] +28119 - Low-level crater - [Enter, null, null, null, null] +28120 - Med-level crater - [Enter, null, null, null, null] +28121 - High-level crater - [Enter, null, null, null, null] +28122 - Cave - [Exit, null, null, null, null] +28123 - null - [null, null, null, null, null] +28124 - null - [null, null, null, null, null] +28125 - null - [null, null, null, null, null] +28126 - null - [null, null, null, null, null] +28127 - null - [null, null, null, null, null] +28128 - null - [null, null, null, null, null] +28129 - null - [null, null, null, null, null] +28130 - null - [null, null, null, null, null] +28131 - null - [null, null, null, null, null] +28132 - null - [null, null, null, null, null] +28133 - null - [null, null, null, null, null] +28134 - null - [null, null, null, null, null] +28135 - null - [null, null, null, null, null] +28136 - null - [null, null, null, null, null] +28137 - null - [null, null, null, null, null] +28138 - null - [null, null, null, null, null] +28139 - Tomato barrel - [take tomato, null, null, null, null] +28140 - Portal - [Leave, null, null, null, null] +28141 - null - [null, null, null, null, null] +28142 - null - [null, null, null, null, null] +28143 - null - [null, null, null, null, null] +28144 - null - [null, null, null, null, null] +28145 - null - [null, null, null, null, null] +28146 - null - [null, null, null, null, null] +28147 - null - [null, null, null, null, null] +28148 - null - [null, null, null, null, null] +28149 - null - [null, null, null, null, null] +28150 - null - [null, null, null, null, null] +28151 - null - [null, null, null, null, null] +28152 - null - [null, null, null, null, null] +28153 - null - [null, null, null, null, null] +28154 - null - [null, null, null, null, null] +28155 - null - [null, null, null, null, null] +28156 - null - [null, null, null, null, null] +28157 - null - [null, null, null, null, null] +28158 - null - [null, null, null, null, null] +28159 - null - [null, null, null, null, null] +28160 - null - [null, null, null, null, null] +28161 - null - [null, null, null, null, null] +28162 - null - [null, null, null, null, null] +28163 - null - [null, null, null, null, null] +28164 - null - [null, null, null, null, null] +28165 - null - [null, null, null, null, null] +28166 - null - [null, null, null, null, null] +28167 - null - [null, null, null, null, null] +28168 - null - [null, null, null, null, null] +28169 - null - [null, null, null, null, null] +28170 - null - [null, null, null, null, null] +28171 - null - [null, null, null, null, null] +28172 - null - [null, null, null, null, null] +28173 - null - [null, null, null, null, null] +28174 - null - [null, null, null, null, null] +28175 - null - [null, null, null, null, null] +28176 - null - [null, null, null, null, null] +28177 - null - [null, null, null, null, null] +28178 - null - [null, null, null, null, null] +28179 - null - [null, null, null, null, null] +28180 - null - [null, null, null, null, null] +28181 - null - [null, null, null, null, null] +28182 - null - [null, null, null, null, null] +28183 - null - [null, null, null, null, null] +28184 - null - [null, null, null, null, null] +28185 - null - [null, null, null, null, null] +28186 - null - [null, null, null, null, null] +28187 - null - [null, null, null, null, null] +28188 - null - [null, null, null, null, null] +28189 - null - [null, null, null, null, null] +28190 - null - [null, null, null, null, null] +28191 - null - [null, null, null, null, null] +28192 - null - [null, null, null, null, null] +28193 - null - [null, null, null, null, null] +28194 - Viewing orb - [Look-into, null, null, null, null] +28195 - null - [null, null, null, null, null] +28196 - null - [null, null, null, null, null] +28197 - null - [null, null, null, null, null] +28198 - null - [null, null, null, null, null] +28199 - Table - [null, null, null, null, null] +28200 - Stool - [null, null, null, null, null] +28201 - Crate - [null, null, null, null, null] +28202 - Barrel - [null, null, null, null, null] +28203 - Pile of crates - [null, null, null, null, null] +28204 - Torch - [null, null, null, null, null] +28205 - Banner - [null, null, null, null, null] +28206 - Banner - [null, null, null, null, null] +28207 - null - [null, null, null, null, null] +28208 - null - [null, null, null, null, null] +28209 - Low-level orb - [View, null, null, null, null] +28210 - Mid-level orb - [View, null, null, null, null] +28211 - High-level orb - [View, null, null, null, null] +28212 - null - [null, null, null, null, null] +28213 - Portal - [Enter, null, null, null, null] +28214 - Portal - [Leave, null, null, null, null] +28215 - null - [null, null, null, null, null] +28216 - null - [null, null, null, null, null] +28217 - null - [null, null, null, null, null] +28218 - null - [null, null, null, null, null] +28219 - null - [null, null, null, null, null] +28220 - Lava crater - [null, null, null, null, null] +28221 - null - [null, null, null, null, null] +28222 - null - [null, null, null, null, null] +28223 - null - [null, null, null, null, null] +28224 - null - [null, null, null, null, null] +28225 - null - [null, null, null, null, null] +28226 - null - [null, null, null, null, null] +28227 - null - [null, null, null, null, null] +28228 - null - [null, null, null, null, null] +28229 - null - [null, null, null, null, null] +28230 - null - [null, null, null, null, null] +28231 - null - [null, null, null, null, null] +28232 - null - [null, null, null, null, null] +28233 - null - [null, null, null, null, null] +28234 - null - [null, null, null, null, null] +28235 - null - [null, null, null, null, null] +28236 - null - [null, null, null, null, null] +28237 - null - [null, null, null, null, null] +28238 - null - [null, null, null, null, null] +28239 - null - [null, null, null, null, null] +28240 - null - [null, null, null, null, null] +28241 - null - [null, null, null, null, null] +28242 - null - [null, null, null, null, null] +28243 - null - [null, null, null, null, null] +28244 - null - [null, null, null, null, null] +28245 - null - [null, null, null, null, null] +28246 - null - [null, null, null, null, null] +28247 - null - [null, null, null, null, null] +28248 - null - [null, null, null, null, null] +28249 - null - [null, null, null, null, null] +28250 - null - [null, null, null, null, null] +28251 - null - [null, null, null, null, null] +28252 - null - [null, null, null, null, null] +28253 - null - [null, null, null, null, null] +28254 - null - [null, null, null, null, null] +28255 - null - [null, null, null, null, null] +28256 - null - [null, null, null, null, null] +28257 - null - [null, null, null, null, null] +28258 - null - [null, null, null, null, null] +28259 - null - [null, null, null, null, null] +28260 - null - [null, null, null, null, null] +28261 - null - [null, null, null, null, null] +28262 - Table - [null, null, null, null, null] +28263 - null - [null, null, null, null, null] +28264 - null - [null, null, null, null, null] +28265 - null - [null, null, null, null, null] +28266 - Snowman - [Add-to, null, null, null, null] +28267 - Snowman - [Add-to, null, null, null, null] +28268 - Snowman - [Add-to, null, null, null, null] +28269 - Snowman - [Add-to, null, null, null, null] +28270 - Snowman - [Add-to, null, null, null, null] +28271 - Snowman - [Add-to, null, null, null, null] +28272 - Snowman - [Add-to, null, null, null, null] +28273 - Snowman - [Add-to, null, null, null, null] +28274 - Snowman - [Add-to, null, null, null, null] +28275 - Snowman - [Add-to, null, null, null, null] +28276 - Snowman - [Add-to, null, null, null, null] +28277 - Snowman - [Add-to, null, null, null, null] +28278 - Snowman - [Add-to, null, null, null, null] +28279 - Snowman - [Add-to, null, null, null, null] +28280 - Snowman - [Add-to, null, null, null, null] +28281 - Snowman - [Add-to, null, null, null, null] +28282 - Snowman - [Add-to, null, null, null, null] +28283 - Snowman - [Add-to, null, null, null, null] +28284 - Snowman - [Add-to, null, null, null, null] +28285 - Snowman - [Add-to, null, null, null, null] +28286 - Snowman - [Add-to, null, null, null, null] +28287 - Snowman - [Add-to, null, null, null, null] +28288 - Snowman - [Add-to, null, null, null, null] +28289 - Snowman - [Add-to, null, null, null, null] +28290 - Snowman - [Add-to, null, null, null, null] +28291 - Snowman - [Add-to, null, null, null, null] +28292 - Snowman - [Add-to, null, null, null, null] +28293 - Snowman - [Add-to, null, null, null, null] +28294 - Snowman - [Add-to, null, null, null, null] +28295 - Snowman - [Add-to, null, null, null, null] +28296 - Snow - [Collect, null, null, null, null] +28297 - Snow - [Collect, null, null, null, null] +28298 - Sleigh - [null, null, null, null, null] +28299 - Sleigh - [null, null, null, null, null] +28300 - null - [null, null, null, null, null] +28301 - null - [null, null, null, null, null] +28302 - null - [null, null, null, null, null] +28303 - null - [null, null, null, null, null] +28304 - null - [null, null, null, null, null] +28305 - null - [null, null, null, null, null] +28306 - null - [null, null, null, null, null] +28307 - null - [null, null, null, null, null] +28308 - null - [null, null, null, null, null] +28309 - null - [null, null, null, null, null] +28310 - null - [null, null, null, null, null] +28311 - null - [null, null, null, null, null] +28312 - null - [null, null, null, null, null] +28313 - null - [null, null, null, null, null] +28314 - null - [null, null, null, null, null] +28315 - null - [null, null, null, null, null] +28316 - Throne - [null, null, null, null, null] +28317 - Food trough - [null, null, null, null, null] +28318 - Stags - [null, null, null, null, null] +28319 - Stags - [null, null, null, null, null] +28320 - null - [null, null, null, null, null] +28321 - null - [null, null, null, null, null] +28322 - Zip line - [null, null, null, null, null] +28323 - null - [null, null, null, null, null] +28324 - null - [null, null, null, null, null] +28325 - null - [null, null, null, null, null] +28326 - Door - [null, null, null, null, null] +28327 - null - [null, null, null, null, null] +28328 - Jar - [null, null, null, null, null] +28329 - null - [null, null, null, null, null] +28330 - null - [null, null, null, null, null] +28331 - null - [null, null, null, null, null] +28332 - null - [null, null, null, null, null] +28333 - Shelves - [null, null, null, null, null] +28334 - null - [null, null, null, null, null] +28335 - Birdcage - [null, null, null, null, null] +28336 - Incubator - [null, null, null, null, null] +28337 - Cat basket - [null, null, null, null, null] +28338 - Dog basket - [null, null, null, null, null] +28339 - Dog baskets - [null, null, null, null, null] +28340 - Fish tank - [null, null, null, null, null] +28341 - Pen - [null, null, null, null, null] +28342 - null - [null, null, null, null, null] +28343 - Hay - [null, null, null, null, null] +28344 - Scale - [null, null, null, null, null] +28345 - Collars - [null, null, null, null, null] +28346 - null - [null, null, null, null, null] +28347 - null - [null, null, null, null, null] +28348 - null - [null, null, null, null, null] +28349 - null - [null, null, null, null, null] +28350 - null - [null, null, null, null, null] +28351 - Pet shop - [null, null, null, null, null] +28352 - null - [hidden, hidden, null, null, null] +28353 - Shelves - [null, null, null, null, null] +28354 - Shelves - [null, null, null, null, null] +28355 - Shelves - [null, null, null, null, null] +28356 - Cat - [null, null, null, null, null] +28357 - Counter - [null, null, null, null, null] +28358 - Counter - [null, null, null, null, null] +28359 - Incubator - [Take-Egg, Inspect, null, null, null] +28360 - Ball - [null, null, null, null, null] +28361 - Pillow - [null, null, null, null, null] +28362 - null - [null, null, null, null, null] +28363 - Counter - [null, null, null, null, null] +28364 - Counter - [null, null, null, null, null] +28365 - null - [null, null, null, null, null] +28366 - null - [null, null, null, null, null] +28367 - null - [null, null, null, null, null] +28368 - null - [null, null, null, null, null] +28369 - null - [null, null, null, null, null] +28370 - Spring - [null, null, null, null, null] +28371 - null - [null, null, null, null, null] +28372 - null - [null, null, null, null, null] +28373 - null - [null, null, null, null, null] +28374 - null - [null, null, null, null, null] +28375 - null - [null, null, null, null, null] +28376 - Sealed door - [null, null, null, null, null] +28377 - Sealed door - [null, null, null, null, null] +28378 - Sealed door - [null, null, null, null, null] +28379 - Sealed door - [null, null, null, null, null] +28380 - Sealed door - [null, null, null, null, null] +28381 - null - [null, null, null, null, null] +28382 - null - [null, null, null, null, null] +28383 - null - [null, null, null, null, null] +28384 - null - [null, null, null, null, null] +28385 - null - [null, null, null, null, null] +28386 - Ladder - [Climb, null, null, null, null] +28387 - null - [Climb, null, null, null, null] +28388 - Ladder - [Climb, null, null, null, null] +28389 - null - [null, null, null, null, null] +28390 - null - [null, null, null, null, null] +28391 - null - [null, null, null, null, null] +28392 - null - [null, null, null, null, null] +28393 - null - [null, null, null, null, null] +28394 - null - [null, null, null, null, null] +28395 - null - [null, null, null, null, null] +28396 - null - [null, null, null, null, null] +28397 - null - [null, null, null, null, null] +28398 - null - [null, null, null, null, null] +28399 - null - [null, null, null, null, null] +28400 - null - [null, null, null, null, null] +28401 - Exit - [Leave through, null, null, null, null] +28402 - null - [null, null, null, null, null] +28403 - null - [null, null, null, null, null] +28404 - null - [null, null, null, null, null] +28405 - null - [null, null, null, null, null] +28406 - null - [null, null, null, null, null] +28407 - Door - [Open, null, null, null, null] +28408 - Door - [Close, null, null, null, null] +28409 - Door - [Open, null, null, null, null] +28410 - Door - [Close, null, null, null, null] +28411 - null - [null, null, null, null, null] +28412 - null - [null, null, null, null, null] +28413 - null - [null, null, null, null, null] +28414 - null - [null, null, null, null, null] +28415 - null - [null, null, null, null, null] +28416 - null - [null, null, null, null, null] +28417 - null - [null, null, null, null, null] +28418 - Monument - [null, null, null, null, null] +28419 - Statue of Scabaras - [null, null, null, null, null] +28420 - Statue - [null, null, null, null, null] +28421 - Crate - [Search, null, null, null, null] +28422 - null - [null, null, null, null, null] +28423 - null - [null, null, null, null, null] +28424 - null - [null, null, null, null, null] +28425 - null - [null, null, null, null, null] +28426 - null - [null, null, null, null, null] +28427 - null - [null, null, null, null, null] +28428 - Stairs - [null, null, null, null, null] +28429 - null - [null, null, null, null, null] +28430 - Stairs - [null, null, null, null, null] +28431 - Stairs - [null, null, null, null, null] +28432 - null - [null, null, null, null, null] +28433 - Furnace - [Stoke, null, null, null, null] +28434 - Furnace - [Stoke, null, null, null, null] +28435 - Lever - [Pull, null, null, null, null] +28436 - Lever - [Pull, null, null, null, null] +28437 - Lever - [Pull, null, null, null, null] +28438 - Lever - [Pull, null, null, null, null] +28439 - Mysterious mechanism - [Investigate, null, null, null, null] +28440 - null - [null, null, null, null, null] +28441 - Pipe - [Cross, null, null, null, null] +28442 - Pipe - [Cross, null, null, null, null] +28443 - Greasy pipe - [Cross, null, null, null, null] +28444 - Ladder - [Climb down, null, null, null, null] +28445 - Greasy pipe - [Cross, null, null, null, null] +28446 - null - [null, null, null, null, null] +28447 - null - [null, null, null, null, null] +28448 - null - [null, null, null, null, null] +28449 - null - [null, null, null, null, null] +28450 - Ancient pillar - [null, null, null, null, null] +28451 - Broken pillar - [null, null, null, null, null] +28452 - Incomplete pillar - [null, null, null, null, null] +28453 - Vandalised pillar - [null, null, null, null, null] +28454 - Swamp tree - [null, null, null, null, null] +28455 - Slimy tree - [null, null, null, null, null] +28456 - null - [null, null, null, null, null] +28457 - null - [null, null, null, null, null] +28458 - null - [null, null, null, null, null] +28459 - null - [null, null, null, null, null] +28460 - null - [null, null, null, null, null] +28461 - null - [null, null, null, null, null] +28462 - null - [null, null, null, null, null] +28463 - null - [null, null, null, null, null] +28464 - null - [null, null, null, null, null] +28465 - null - [null, null, null, null, null] +28466 - null - [null, null, null, null, null] +28467 - null - [null, null, null, null, null] +28468 - null - [null, null, null, null, null] +28469 - null - [null, null, null, null, null] +28470 - null - [null, null, null, null, null] +28471 - null - [null, null, null, null, null] +28472 - Reeds - [Push through, null, null, null, null] +28473 - Reeds - [Push through, null, null, null, null] +28474 - Reeds - [Push through, null, null, null, null] +28475 - Storage box - [Remove fuel, null, null, null, null] +28476 - Storage box - [Remove fuel, null, null, null, null] +28477 - Storage box - [Remove fuel, null, null, null, null] +28478 - Storage box - [Remove fuel, null, null, null, null] +28479 - null - [null, null, null, null, null] +28480 - Scratchy writing - [Read, null, null, null, null] +28481 - Stairs down - [Enter, null, null, null, null] +28482 - null - [null, null, null, null, null] +28483 - null - [null, null, null, null, null] +28484 - null - [null, null, null, null, null] +28485 - null - [null, null, null, null, null] +28486 - Warm campfire - [null, null, null, null, null] +28487 - Rock - [null, null, null, null, null] +28488 - Rope - [Climb down, null, null, null, null] +28489 - Rock - [null, null, null, null, null] +28490 - Rope - [Climb up, null, null, null, null] +28491 - null - [null, null, null, null, null] +28492 - Ladder - [Climb, null, null, null, null] +28493 - null - [null, null, null, null, null] +28494 - null - [null, null, null, null, null] +28495 - null - [null, null, null, null, null] +28496 - Dung - [null, null, null, null, null] +28497 - Dung - [null, null, null, null, null] +28498 - Dung - [null, null, null, null, null] +28499 - Dung - [null, null, null, null, null] +28500 - null - [null, null, null, null, null] +28501 - null - [null, null, null, null, null] +28502 - Chest - [Search, null, null, null, null] +28503 - Chest - [Search, null, null, null, null] +28504 - Chair - [null, null, null, null, null] +28505 - Broken chair - [null, null, null, null, null] +28506 - Broken chair - [null, null, null, null, null] +28507 - Broken chair - [null, null, null, null, null] +28508 - Table - [null, null, null, null, null] +28509 - Broken table - [null, null, null, null, null] +28510 - Broken table - [null, null, null, null, null] +28511 - Broken table - [null, null, null, null, null] +28512 - Low wall - [Climb, null, null, null, null] +28513 - null - [null, null, null, null, null] +28514 - Gate - [Open, Use-quickly, null, null, null] +28515 - Fallen pillar - [Climb, null, null, null, null] +28516 - Fallen pillar - [Climb, null, null, null, null] +28517 - null - [null, null, null, null, null] +28518 - Gate - [Close, null, null, null, null] +28519 - Power indicator - [null, null, null, null, null] +28520 - Power indicator - [null, null, null, null, null] +28521 - Power indicator - [null, null, null, null, null] +28522 - Power indicator - [null, null, null, null, null] +28523 - Power indicator - [null, null, null, null, null] +28524 - Power indicator - [null, null, null, null, null] +28525 - Floor - [Search, null, null, null, null] +28526 - Odd markings. - [Search, null, null, null, null] +28527 - Spear trap - [null, null, null, null, null] +28528 - null - [null, null, null, null, null] +28529 - null - [null, null, null, null, null] +28530 - null - [null, null, null, null, null] +28531 - null - [null, null, null, null, null] +28532 - Steam - [null, null, null, null, null] +28533 - Steam - [null, null, null, null, null] +28534 - null - [null, null, null, null, null] +28535 - null - [null, null, null, null, null] +28536 - null - [null, null, null, null, null] +28537 - null - [null, null, null, null, null] +28538 - null - [null, null, null, null, null] +28539 - null - [null, null, null, null, null] +28540 - null - [null, null, null, null, null] +28541 - null - [null, null, null, null, null] +28542 - null - [null, null, null, null, null] +28543 - null - [null, null, null, null, null] +28544 - null - [null, null, null, null, null] +28545 - null - [null, null, null, null, null] +28546 - null - [null, null, null, null, null] +28547 - null - [null, null, null, null, null] +28548 - null - [null, null, null, null, null] +28549 - null - [null, null, null, null, null] +28550 - null - [hidden, hidden, null, null, null] +28551 - Evil turnip patch - [null, Inspect, null, null, null] +28552 - Evil turnip patch - [null, Inspect, null, null, null] +28553 - Evil turnip patch - [null, Inspect, null, null, null] +28554 - Evil turnip patch - [null, Inspect, null, null, null] +28555 - Evil turnip patch - [null, Inspect, null, null, null] +28556 - Evil turnip patch - [Pick, Inspect, null, null, null] +28557 - Shaking box - [Check, null, null, null, null] +28558 - Shaking box - [Check, null, null, null, null] +28559 - Net trap - [null, null, null, null, null] +28560 - Net trap - [Check, null, null, null, null] +28561 - Net trap - [null, null, null, null, null] +28562 - Net trap - [Dismantle, null, null, null, null] +28563 - Young tree - [Dismantle, Investigate, null, null, null] +28564 - Young tree - [Set-trap, null, null, null, null] +28565 - Young tree - [null, null, null, null, null] +28566 - Net trap - [Dismantle, Investigate, null, null, null] +28567 - Shaking box - [Check, null, null, null, null] +28568 - Box trap - [null, null, null, null, null] +28569 - Box trap - [null, null, null, null, null] +28570 - Box trap - [null, null, null, null, null] +28571 - Box trap - [null, null, null, null, null] +28572 - Ladder - [Climb-up, null, null, null, null] +28573 - null - [null, null, null, null, null] +28574 - null - [null, null, null, null, null] +28575 - null - [null, null, null, null, null] +28576 - null - [null, null, null, null, null] +28577 - null - [null, null, null, null, null] +28578 - null - [null, null, null, null, null] +28579 - null - [null, null, null, null, null] +28580 - null - [null, null, null, null, null] +28581 - null - [null, null, null, null, null] +28582 - null - [null, null, null, null, null] +28583 - null - [null, null, null, null, null] +28584 - null - [null, null, null, null, null] +28585 - null - [null, null, null, null, null] +28586 - Dead body - [Search, null, null, null, null] +28587 - null - [null, null, null, null, null] +28588 - Door - [Close, null, null, null, null] +28589 - Door - [Open, null, null, null, null] +28590 - Door - [null, null, null, null, null] +28591 - null - [null, null, null, null, null] +28592 - null - [null, null, null, null, null] +28593 - null - [null, null, null, null, null] +28594 - null - [null, null, null, null, null] +28595 - null - [null, null, null, null, null] +28596 - null - [null, null, null, null, null] +28597 - null - [null, null, null, null, null] +28598 - null - [null, null, null, null, null] +28599 - null - [null, null, null, null, null] +28600 - null - [null, null, null, null, null] +28601 - null - [null, null, null, null, null] +28602 - null - [null, null, null, null, null] +28603 - null - [null, null, null, null, null] +28604 - null - [null, null, null, null, null] +28605 - null - [null, null, null, null, null] +28606 - null - [null, null, null, null, null] +28607 - null - [null, null, null, null, null] +28608 - null - [null, null, null, null, null] +28609 - null - [null, null, null, null, null] +28610 - null - [null, null, null, null, null] +28611 - null - [null, null, null, null, null] +28612 - null - [null, null, null, null, null] +28613 - null - [null, null, null, null, null] +28614 - null - [null, null, null, null, null] +28615 - null - [null, null, null, null, null] +28616 - null - [null, null, null, null, null] +28617 - null - [null, null, null, null, null] +28618 - null - [null, null, null, null, null] +28619 - null - [null, null, null, null, null] +28620 - null - [null, null, null, null, null] +28621 - Table - [null, null, null, null, null] +28622 - Sword cabinet - [null, null, null, null, null] +28623 - Sign - [null, null, null, null, null] +28624 - Sword case - [null, null, null, null, null] +28625 - Crate - [Search, null, null, null, null] +28626 - Crate - [Search, null, null, null, null] +28627 - Chair - [null, null, null, null, null] +28628 - Table - [null, null, null, null, null] +28629 - Table - [null, null, null, null, null] +28630 - Stool - [null, null, null, null, null] +28631 - Stool - [null, null, null, null, null] +28632 - Drawers - [Open, null, null, null, null] +28633 - Drawers - [null, Search, Close, null, null] +28634 - Bed - [null, null, null, null, null] +28635 - Stone table - [null, null, null, null, null] +28636 - Bench - [null, null, null, null, null] +28637 - Bookshelves - [null, null, null, null, null] +28638 - Bookshelves - [null, null, null, null, null] +28639 - Stone table - [null, null, null, null, null] +28640 - Destroyed bed - [null, null, null, null, null] +28641 - Gnawed drawers - [null, null, null, null, null] +28642 - Ruined bookshelves - [null, null, null, null, null] +28643 - Broken stool - [null, null, null, null, null] +28644 - Book heap - [null, null, null, null, null] +28645 - Wooden pieces - [null, null, null, null, null] +28646 - Splinters - [null, null, null, null, null] +28647 - null - [null, null, null, null, null] +28648 - null - [null, null, null, null, null] +28649 - null - [null, null, null, null, null] +28650 - null - [null, null, null, null, null] +28651 - Ladder - [Climb-up, null, null, null, null] +28652 - Ladder - [Climb-down, null, null, null, null] +28653 - Ladder - [Climb-down, null, null, null, null] +28654 - Pillar - [null, null, null, null, null] +28655 - Pillar - [null, null, null, null, null] +28656 - null - [null, null, null, null, null] +28657 - null - [null, null, null, null, null] +28658 - null - [null, null, null, null, null] +28659 - null - [null, null, null, null, null] +28660 - Table - [null, null, null, null, null] +28661 - Stool - [null, null, null, null, null] +28662 - Fountain - [null, null, null, null, null] +28663 - null - [null, null, null, null, null] +28664 - null - [null, null, null, null, null] +28665 - null - [null, null, null, null, null] +28666 - null - [null, null, null, null, null] +28667 - null - [null, null, null, null, null] +28668 - null - [null, null, null, null, null] +28669 - null - [null, null, null, null, null] +28670 - null - [null, null, null, null, null] +28671 - null - [null, null, null, null, null] +28672 - null - [null, null, null, null, null] +28673 - null - [null, null, null, null, null] +28674 - null - [null, null, null, null, null] +28675 - Trapdoor - [Open, null, null, null, null] +28676 - Trapdoor - [Climb-down, Close, null, null, null] +28677 - null - [null, null, null, null, null] +28678 - null - [null, null, null, null, null] +28679 - null - [null, null, null, null, null] +28680 - null - [null, null, null, null, null] +28681 - null - [null, null, null, null, null] +28682 - null - [null, null, null, null, null] +28683 - null - [null, null, null, null, null] +28684 - null - [null, null, null, null, null] +28685 - null - [null, null, null, null, null] +28686 - null - [null, null, null, null, null] +28687 - null - [null, null, null, null, null] +28688 - null - [null, null, null, null, null] +28689 - null - [null, null, null, null, null] +28690 - Gate - [Open, null, null, null, null] +28691 - Gate - [Open, null, null, null, null] +28692 - Gate - [Close, null, null, null, null] +28693 - Gate - [Close, null, null, null, null] +28694 - Druid's Circle stone - [null, null, null, null, null] +28695 - Druid's Circle stone - [null, null, null, null, null] +28696 - Druid's Circle stone - [null, null, null, null, null] +28697 - Druid's Circle stone - [null, null, null, null, null] +28698 - Altar of Guthix - [Pray, null, null, null, null] +28699 - Druid's Circle torch - [null, null, null, null, null] +28700 - null - [null, null, null, null, null] +28701 - null - [null, null, null, null, null] +28702 - null - [null, null, null, null, null] +28703 - null - [null, null, null, null, null] +28704 - null - [null, null, null, null, null] +28705 - null - [null, null, null, null, null] +28706 - null - [null, null, null, null, null] +28707 - Druid's robes - [null, null, null, null, null] +28708 - Druid's robes - [null, null, null, null, null] +28709 - null - [null, null, null, null, null] +28710 - null - [null, null, null, null, null] +28711 - null - [null, null, null, null, null] +28712 - null - [null, null, null, null, null] +28713 - null - [null, null, null, null, null] +28714 - Ladder - [Climb, null, null, null, null] +28715 - Wishing well - [Make-Wish, null, null, null, null] +28716 - Obelisk - [Infuse-Pouch, Renew-Points, null, null, null] +28717 - Inert obelisk - [null, null, null, null, null] +28718 - Inert obelisk - [null, null, null, null, null] +28719 - Obelisk - [Infuse-Pouch, Renew-Points, null, null, null] +28720 - Inert obelisk - [null, null, null, null, null] +28721 - Inert obelisk - [null, null, null, null, null] +28722 - Obelisk - [Infuse-Pouch, Renew-Points, null, null, null] +28723 - Inert obelisk - [null, null, null, null, null] +28724 - Inert obelisk - [null, null, null, null, null] +28725 - Obelisk - [Infuse-Pouch, Renew-Points, null, null, null] +28726 - Inert obelisk - [null, null, null, null, null] +28727 - Inert obelisk - [null, null, null, null, null] +28728 - Obelisk - [Infuse-Pouch, Renew-Points, null, null, null] +28729 - Inert obelisk - [null, null, null, null, null] +28730 - Inert obelisk - [null, null, null, null, null] +28731 - Obelisk - [Infuse-Pouch, Renew-Points, null, null, null] +28732 - Inert obelisk - [null, null, null, null, null] +28733 - Inert obelisk - [null, null, null, null, null] +28734 - Obelisk - [Infuse-Pouch, Renew-Points, null, null, null] +28735 - Inert obelisk - [null, null, null, null, null] +28736 - Inert obelisk - [null, null, null, null, null] +28737 - Desert ladder - [Climb-down, null, null, null, null] +28738 - null - [null, null, null, null, null] +28739 - null - [null, null, null, null, null] +28740 - Ladder - [Climb-Up, null, null, null, null] +28741 - Trapdoor - [Open, null, null, null, null] +28742 - Trapdoor - [Climb-down, Close, null, null, null] +28743 - Ladder - [Climb-up, null, null, null, null] +28744 - null - [null, null, null, null, null] +28745 - null - [null, null, null, null, null] +28746 - null - [null, null, null, null, null] +28747 - null - [null, null, null, null, null] +28748 - null - [null, null, null, null, null] +28749 - null - [null, null, null, null, null] +28750 - Net trap - [null, null, null, null, null] +28751 - Net trap - [Check, null, null, null, null] +28752 - Net trap - [null, null, null, null, null] +28753 - Net trap - [Dismantle, null, null, null, null] +28754 - Box trap - [null, null, null, null, null] +28755 - Box trap - [null, null, null, null, null] +28756 - Box trap - [null, null, null, null, null] +28757 - Box trap - [null, null, null, null, null] +28758 - Box trap - [null, null, null, null, null] +28759 - Box trap - [null, null, null, null, null] +28760 - Box trap - [null, null, null, null, null] +28761 - Laundry Basket - [Search, null, null, null, null] +28762 - null - [null, null, null, null, null] +28763 - null - [null, null, null, null, null] +28764 - null - [null, null, null, null, null] +28765 - null - [null, null, null, null, null] +28766 - null - [null, null, null, null, null] +28767 - null - [null, null, null, null, null] +28768 - null - [null, null, null, null, null] +28769 - null - [null, null, null, null, null] +28770 - null - [null, null, null, null, null] +28771 - null - [null, null, null, null, null] +28772 - null - [null, null, null, null, null] +28773 - null - [null, null, null, null, null] +28774 - null - [null, null, null, null, null] +28775 - null - [null, null, null, null, null] +28776 - null - [null, null, null, null, null] +28777 - Box trap - [null, null, null, null, null] +28778 - null - [null, null, null, null, null] +28779 - Portal - [Use, null, null, null, null] +28780 - Portal - [Use, null, null, null, null] +28781 - Portal - [null, null, null, null, null] +28782 - Exit - [Climb-up, null, null, null, null] +28783 - null - [null, null, null, null, null] +28784 - null - [null, null, null, null, null] +28785 - null - [null, null, null, null, null] +28786 - null - [null, null, null, null, null] +28787 - Stairs - [Climb, null, null, null, null] +28788 - null - [null, null, null, null, null] +28789 - null - [null, null, null, null, null] +28790 - null - [null, null, null, null, null] +28791 - null - [null, null, null, null, null] +28792 - null - [null, null, null, null, null] +28793 - null - [null, null, null, null, null] +28794 - null - [null, null, null, null, null] +28795 - null - [null, null, null, null, null] +28796 - Skeleton - [null, null, null, null, null] +28797 - Skeleton - [null, null, null, null, null] +28798 - Skeleton - [null, null, null, null, null] +28799 - null - [null, null, null, null, null] +28800 - null - [null, null, null, null, null] +28801 - null - [null, null, null, null, null] +28802 - null - [null, null, null, null, null] +28803 - null - [null, null, null, null, null] +28804 - null - [null, null, null, null, null] +28805 - null - [null, null, null, null, null] +28806 - null - [null, null, null, null, null] +28807 - null - [null, null, null, null, null] +28808 - null - [null, null, null, null, null] +28809 - null - [null, null, null, null, null] +28810 - null - [null, null, null, null, null] +28811 - null - [null, null, null, null, null] +28812 - null - [null, null, null, null, null] +28813 - null - [null, null, null, null, null] +28814 - null - [null, null, null, null, null] +28815 - null - [null, null, null, null, null] +28816 - null - [null, null, null, null, null] +28817 - null - [null, null, null, null, null] +28818 - null - [null, null, null, null, null] +28819 - Mushroom - [null, null, null, null, null] +28820 - Mushroom - [null, null, null, null, null] +28821 - Mushrooms - [null, null, null, null, null] +28822 - null - [null, null, null, null, null] +28823 - Crate - [Search, null, null, null, null] +28824 - Crate - [Search, null, null, null, null] +28825 - Sack pile - [null, null, null, null, null] +28826 - Barrel - [null, null, null, null, null] +28827 - null - [null, null, null, null, null] +28828 - null - [null, null, null, null, null] +28829 - null - [null, null, null, null, null] +28830 - null - [null, null, null, null, null] +28831 - null - [null, null, null, null, null] +28832 - null - [null, null, null, null, null] +28833 - null - [null, null, null, null, null] +28834 - null - [null, null, null, null, null] +28835 - null - [null, null, null, null, null] +28836 - null - [null, null, null, null, null] +28837 - null - [null, null, null, null, null] +28838 - null - [null, null, null, null, null] +28839 - null - [null, null, null, null, null] +28840 - null - [null, null, null, null, null] +28841 - null - [null, null, null, null, null] +28842 - null - [null, null, null, null, null] +28843 - null - [null, null, null, null, null] +28844 - null - [null, null, null, null, null] +28845 - null - [null, null, null, null, null] +28846 - null - [null, null, null, null, null] +28847 - Beacon - [null, null, null, null, null] +28848 - Flames - [null, null, null, null, null] +28849 - Skeleton - [null, null, null, null, null] +28850 - Skeleton - [null, null, null, null, null] +28851 - Skeleton - [null, null, null, null, null] +28852 - null - [null, null, null, null, null] +28853 - null - [null, null, null, null, null] +28854 - null - [null, null, null, null, null] +28855 - null - [null, null, null, null, null] +28856 - null - [null, null, null, null, null] +28857 - null - [null, null, null, null, null] +28858 - null - [null, null, null, null, null] +28859 - null - [null, null, null, null, null] +28860 - null - [null, null, null, null, null] +28861 - null - [null, null, null, null, null] +28862 - null - [null, null, null, null, null] +28863 - null - [null, null, null, null, null] +28864 - null - [null, null, null, null, null] +28865 - null - [null, null, null, null, null] +28866 - null - [null, null, null, null, null] +28867 - null - [null, null, null, null, null] +28868 - null - [null, null, null, null, null] +28869 - null - [null, null, null, null, null] +28870 - null - [null, null, null, null, null] +28871 - null - [null, null, null, null, null] +28872 - null - [null, null, null, null, null] +28873 - null - [null, null, null, null, null] +28874 - null - [null, null, null, null, null] +28875 - Plant - [null, null, null, null, null] +28876 - Plant - [null, null, null, null, null] +28877 - Plant - [null, null, null, null, null] +28878 - Plant - [null, null, null, null, null] +28879 - null - [null, null, null, null, null] +28880 - null - [null, null, null, null, null] +28881 - null - [null, null, null, null, null] +28882 - null - [null, null, null, null, null] +28883 - null - [null, null, null, null, null] +28884 - null - [null, null, null, null, null] +28885 - null - [null, null, null, null, null] +28886 - null - [null, null, null, null, null] +28887 - null - [null, null, null, null, null] +28888 - null - [null, null, null, null, null] +28889 - null - [null, null, null, null, null] +28890 - null - [null, null, null, null, null] +28891 - Rift - [Enter, null, null, null, null] +28892 - Rift - [Enter, null, null, null, null] +28893 - Rift - [Enter, null, null, null, null] +28894 - null - [null, null, null, null, null] +28895 - null - [null, null, null, null, null] +28896 - null - [null, null, null, null, null] +28897 - null - [null, null, null, null, null] +28898 - null - [null, null, null, null, null] +28899 - null - [null, null, null, null, null] +28900 - null - [null, null, null, null, null] +28901 - Slimy skulls - [null, null, null, null, null] +28902 - null - [null, null, null, null, null] +28903 - null - [null, null, null, null, null] +28904 - null - [null, null, null, null, null] +28905 - null - [null, null, null, null, null] +28906 - Shaking box - [Check, null, null, null, null] +28907 - Box trap - [Dismantle, null, null, null, null] +28908 - Box trap - [null, null, null, null, null] +28909 - Box trap - [null, null, null, null, null] +28910 - Box trap - [null, null, null, null, null] +28911 - Box trap - [null, null, null, null, null] +28912 - Dummy pawya corpse - [null, null, null, null, null] +28913 - Shaking box - [Check, null, null, null, null] +28914 - Box trap - [Dismantle, null, null, null, null] +28915 - Box trap - [null, null, null, null, null] +28916 - Box trap - [null, null, null, null, null] +28917 - Box trap - [null, null, null, null, null] +28918 - Box trap - [null, null, null, null, null] +28919 - null - [null, null, null, null, null] +28920 - Shaking box - [Check, null, null, null, null] +28921 - Shaking box - [Check, null, null, null, null] +28922 - Shaking box - [Check, null, null, null, null] +28923 - Shaking box - [Check, null, null, null, null] +28924 - Shaking box - [Check, null, null, null, null] +28925 - Shaking box - [Check, null, null, null, null] +28926 - Shaking box - [Check, null, null, null, null] +28927 - Shaking box - [Check, null, null, null, null] +28928 - Shaking box - [Check, null, null, null, null] +28929 - Shaking box - [Check, null, null, null, null] +28930 - Bird snare - [Check, null, null, null, null] +28931 - Bird snare - [Check, null, null, null, null] +28932 - Bird snare - [Check, null, null, null, null] +28933 - Bird snare - [Check, null, null, null, null] +28934 - Bird snare - [Check, null, null, null, null] +28935 - Boulder - [Set-trap, null, null, null, null] +28936 - Boulder - [null, null, null, null, null] +28937 - Deadfall trap - [Dismantle, Investigate, null, null, null] +28938 - Deadfall trap - [null, null, null, null, null] +28939 - Deadfall trap - [null, null, null, null, null] +28940 - Deadfall trap - [null, null, null, null, null] +28941 - Boulder - [Check, null, null, null, null] +28942 - Boulder - [Check, null, null, null, null] +28943 - Boulder - [Check, null, null, null, null] +28944 - Boulder - [Check, null, null, null, null] +28945 - Boulder - [Check, null, null, null, null] +28946 - null - [null, null, null, null, null] +28947 - null - [null, null, null, null, null] +28948 - null - [null, null, null, null, null] +28949 - null - [null, null, null, null, null] +28950 - null - [null, null, null, null, null] +28951 - Eucalyptus tree - [Chop down, null, hidden, null, null] +28952 - Eucalyptus tree - [Chop down, null, hidden, null, null] +28953 - Eucalyptus tree - [Chop down, null, hidden, null, null] +28954 - Eucalyptus stump - [null, null, null, null, null] +28955 - Eucalyptus stump - [null, null, null, null, null] +28956 - Eucalyptus stump - [null, null, null, null, null] +28957 - null - [null, null, null, null, null] +28958 - null - [null, null, null, null, null] +28959 - null - [null, null, null, null, null] +28960 - null - [null, null, null, null, null] +28961 - null - [null, null, null, null, null] +28962 - null - [null, null, null, null, null] +28963 - null - [null, null, null, null, null] +28964 - null - [null, null, null, null, null] +28965 - null - [null, null, null, null, null] +28966 - null - [null, null, null, null, null] +28967 - null - [null, null, null, null, null] +28968 - null - [null, null, null, null, null] +28969 - null - [null, null, null, null, null] +28970 - null - [null, null, null, null, null] +28971 - null - [null, null, null, null, null] +28972 - null - [null, null, null, null, null] +28973 - null - [null, null, null, null, null] +28974 - null - [null, null, null, null, null] +28975 - null - [null, null, null, null, null] +28976 - null - [null, null, null, null, null] +28977 - null - [null, null, null, null, null] +28978 - null - [null, null, null, null, null] +28979 - null - [null, null, null, null, null] +28980 - null - [null, null, null, null, null] +28981 - null - [null, null, null, null, null] +28982 - null - [null, null, null, null, null] +28983 - null - [null, null, null, null, null] +28984 - null - [null, null, null, null, null] +28985 - null - [null, null, null, null, null] +28986 - null - [null, null, null, null, null] +28987 - null - [null, null, null, null, null] +28988 - null - [null, null, null, null, null] +28989 - null - [null, null, null, null, null] +28990 - null - [null, null, null, null, null] +28991 - null - [null, null, null, null, null] +28992 - null - [null, null, null, null, null] +28993 - null - [null, null, null, null, null] +28994 - null - [null, null, null, null, null] +28995 - null - [null, null, null, null, null] +28996 - null - [null, null, null, null, null] +28997 - null - [null, null, null, null, null] +28998 - null - [null, null, null, null, null] +28999 - Bugs - [null, null, null, null, null] +29000 - Bugs - [null, null, null, null, null] +29001 - Mud bath - [null, null, null, null, null] +29002 - Mud bath - [null, null, null, null, null] +29003 - Mud bath - [null, null, null, null, null] +29004 - Rocks - [Climb-over, null, null, null, null] +29005 - Rocks - [Climb-over, null, null, null, null] +29006 - Mud bath - [null, null, null, null, null] +29007 - Mud bath - [null, null, null, null, null] +29008 - Mud bath - [null, null, null, null, null] +29009 - Mud bath - [null, null, null, null, null] +29010 - Mud bath - [null, null, null, null, null] +29011 - Mud bath - [null, null, null, null, null] +29012 - Mud bath - [null, null, null, null, null] +29013 - Mud bath - [null, null, null, null, null] +29014 - Mud bath - [null, null, null, null, null] +29015 - Sulphur spring - [null, null, null, null, null] +29016 - Sulphur spring - [null, null, null, null, null] +29017 - Sulphur spring - [null, null, null, null, null] +29018 - Rocks - [Climb-over, null, null, null, null] +29019 - Rocks - [Climb-over, null, null, null, null] +29020 - Sulphur spring - [null, null, null, null, null] +29021 - Sulphur spring - [null, null, null, null, null] +29022 - Sulphur spring - [null, null, null, null, null] +29023 - Sulphur spring - [null, null, null, null, null] +29024 - Sulphur spring - [null, null, null, null, null] +29025 - Sulphur spring - [null, null, null, null, null] +29026 - Sulphur spring - [null, null, null, null, null] +29027 - Sulphur spring - [null, null, null, null, null] +29028 - Sulphur spring - [null, null, null, null, null] +29029 - Salt-water spring - [null, null, null, null, null] +29030 - Salt-water spring - [null, null, null, null, null] +29031 - Rocks - [Climb-over, null, null, null, null] +29032 - Rocks - [Climb-over, null, null, null, null] +29033 - Salt-water spring - [null, null, null, null, null] +29034 - Salt-water spring - [null, null, null, null, null] +29035 - Salt-water spring - [null, null, null, null, null] +29036 - Salt-water spring - [null, null, null, null, null] +29037 - Salt-water spring - [null, null, null, null, null] +29038 - Salt-water spring - [null, null, null, null, null] +29039 - Salt-water spring - [null, null, null, null, null] +29040 - Salt-water spring - [null, null, null, null, null] +29041 - Salt-water spring - [null, null, null, null, null] +29042 - Thermal bath - [null, null, null, null, null] +29043 - Thermal bath - [null, null, null, null, null] +29044 - Rocks - [Climb-over, null, null, null, null] +29045 - Rocks - [Climb-over, null, null, null, null] +29046 - Thermal bath - [null, null, null, null, null] +29047 - Thermal bath - [null, null, null, null, null] +29048 - Thermal bath - [null, null, null, null, null] +29049 - Thermal bath - [null, null, null, null, null] +29050 - Thermal bath - [null, null, null, null, null] +29051 - Thermal bath - [null, null, null, null, null] +29052 - Thermal bath - [null, null, null, null, null] +29053 - Thermal spring - [null, null, null, null, null] +29054 - Thermal bath - [null, null, null, null, null] +29055 - Bandos pool - [null, null, null, null, null] +29056 - Bandos pool - [null, null, null, null, null] +29057 - Rocks - [Climb-over, null, null, null, null] +29058 - Rocks - [Climb-over, null, null, null, null] +29059 - Bandos pool - [null, null, null, null, null] +29060 - Bandos pool - [null, null, null, null, null] +29061 - Bandos pool - [null, null, null, null, null] +29062 - Bandos pool - [null, null, null, null, null] +29063 - Bandos pool - [null, null, null, null, null] +29064 - Bandos pool - [null, null, null, null, null] +29065 - Bandos pool - [null, null, null, null, null] +29066 - Bandos pool - [null, null, null, null, null] +29067 - Bandos pool - [null, null, null, null, null] +29068 - null - [null, null, null, null, null] +29069 - null - [null, null, null, null, null] +29070 - null - [null, null, null, null, null] +29071 - null - [null, null, null, null, null] +29072 - null - [null, null, null, null, null] +29073 - null - [null, null, null, null, null] +29074 - null - [null, null, null, null, null] +29075 - null - [null, null, null, null, null] +29076 - null - [null, null, null, null, null] +29077 - null - [null, null, null, null, null] +29078 - null - [null, null, null, null, null] +29079 - null - [null, null, null, null, null] +29080 - null - [null, null, null, null, null] +29081 - null - [null, null, null, null, null] +29082 - null - [null, null, null, null, null] +29083 - null - [null, null, null, null, null] +29084 - null - [null, null, null, null, null] +29085 - Bank booth - [Use, Use-quickly, Collect, null, null] +29086 - Hotel bed - [null, null, null, null, null] +29087 - Hotel bed - [null, null, null, null, null] +29088 - Achey tree - [null, null, Chop, null, null] +29089 - Achey tree - [null, null, Chop, null, null] +29090 - Achey tree - [null, null, null, null, null] +29091 - Spear spit - [null, null, null, null, null] +29092 - Uncooked chompies - [null, null, null, null, null] +29093 - Slowly roasting chompies - [null, null, null, null, null] +29094 - Cooking fire - [null, null, null, null, null] +29095 - Unlit fire - [Light, null, null, hidden, null] +29096 - Fire pit - [null, null, null, null, null] +29097 - null - [null, null, null, null, null] +29098 - null - [null, null, null, null, null] +29099 - Rock passage - [Squeeze-through, null, null, null, null] +29100 - null - [null, null, null, null, null] +29101 - null - [null, null, null, null, null] +29102 - null - [null, null, null, null, null] +29103 - Salon customer - [Talk-to, null, null, null, null] +29104 - Hairdryer - [null, null, null, null, null] +29105 - Sink - [null, null, null, null, null] +29106 - Grimechin - [Talk-to, null, null, null, null] +29107 - Chair - [null, null, null, null, null] +29108 - null - [null, null, null, null, null] +29109 - Glorious mud - [null, null, null, null, null] +29110 - null - [null, null, null, null, null] +29111 - null - [null, null, null, null, null] +29112 - Platypus hole - [null, null, null, null, null] +29113 - Fever grass - [Pick, null, null, null, null] +29114 - Lavender - [Pick, null, null, null, null] +29115 - Tansymum - [Pick, null, null, null, null] +29116 - Primweed - [Pick, null, null, null, null] +29117 - Stinkbloom - [Pick, null, null, null, null] +29118 - Crowd of dwarves - [null, null, null, null, null] +29119 - null - [null, null, null, null, null] +29120 - null - [null, null, null, null, null] +29121 - null - [null, null, null, null, null] +29122 - null - [null, null, null, null, null] +29123 - null - [null, null, null, null, null] +29124 - Ogre roof leaves - [null, null, null, null, null] +29125 - Barrel - [null, null, null, null, null] +29126 - Crate - [null, null, null, null, null] +29127 - null - [null, null, null, null, null] +29128 - null - [null, null, null, null, null] +29129 - Logs - [null, null, null, null, null] +29130 - Shelves - [null, null, null, null, null] +29131 - Table - [null, null, null, null, null] +29132 - Oil lamp - [null, null, null, null, null] +29133 - Oil lamp - [null, null, null, null, null] +29134 - Cooking utensils - [null, null, null, null, null] +29135 - null - [null, null, null, null, null] +29136 - null - [null, null, null, null, null] +29137 - Chair - [null, null, null, null, null] +29138 - Throne - [null, null, null, null, null] +29139 - Fire - [null, null, null, null, null] +29140 - Spikes - [null, null, null, null, null] +29141 - Post - [null, null, null, null, null] +29142 - Pennant - [null, null, null, null, null] +29143 - Pennant - [null, null, null, null, null] +29144 - Shop counter - [null, null, null, null, null] +29145 - Shelves - [null, null, null, null, null] +29146 - Shelves - [null, null, null, null, null] +29147 - Shelves - [null, null, null, null, null] +29148 - Large crate - [null, null, null, null, null] +29149 - Crate - [Search, null, null, null, null] +29150 - Barrels - [null, null, null, null, null] +29151 - Barrel - [null, null, null, null, null] +29152 - Fire pit - [null, Check, null, null, null] +29153 - Fire pit - [null, Check-contents, null, hidden, null] +29154 - Fire pit - [null, Check-contents, null, hidden, null] +29155 - Fire pit - [null, Check, null, null, null] +29156 - Pile of stones - [null, null, null, null, null] +29157 - Pile of stones - [null, null, null, null, null] +29158 - Pile of stones - [null, null, null, null, null] +29159 - Pile of stones - [null, null, null, null, null] +29160 - Pile of stones - [null, null, null, null, null] +29161 - Deadfall - [null, null, null, null, null] +29162 - Deadfall - [null, null, null, null, null] +29163 - Boulder - [Check, null, null, null, null] +29164 - Bird snare - [null, null, null, null, null] +29165 - Bird snare - [Check, null, null, null, null] +29166 - Funeral pyre - [null, null, null, null, null] +29167 - Funeral pyre - [Light, null, null, null, null] +29168 - Gangplank - [Cross, null, null, null, null] +29169 - Gangplank - [Cross, null, null, null, null] +29170 - null - [null, null, null, null, null] +29171 - null - [null, null, null, null, null] +29172 - null - [null, null, null, null, null] +29173 - null - [null, null, null, null, null] +29174 - null - [null, null, null, null, null] +29175 - null - [null, null, null, null, null] +29176 - null - [null, null, null, null, null] +29177 - null - [null, null, null, null, null] +29178 - null - [null, null, null, null, null] +29179 - null - [null, null, null, null, null] +29180 - null - [null, null, null, null, null] +29181 - Funeral pyre - [null, null, null, null, null] +29182 - Funeral pyre - [Light, null, null, null, null] +29183 - null - [null, null, null, null, null] +29184 - null - [null, null, null, null, null] +29185 - Box trap - [null, null, null, null, null] +29186 - Box trap - [null, null, null, null, null] +29187 - Box trap - [null, null, null, null, null] +29188 - Box trap - [null, null, null, null, null] +29189 - Box trap - [null, null, null, null, null] +29190 - Box trap - [null, null, null, null, null] +29191 - Box trap - [null, null, null, null, null] +29192 - Box trap - [null, null, null, null, null] +29193 - null - [null, null, null, null, null] +29194 - Rocks - [Mine, Prospect, hidden, null, null] +29195 - Rocks - [Mine, Prospect, hidden, null, null] +29196 - Rocks - [Mine, Prospect, hidden, null, null] +29197 - Rocks - [Mine, Prospect, hidden, null, null] +29198 - Rocks - [Mine, Prospect, hidden, null, null] +29199 - Rocks - [Mine, Prospect, hidden, null, null] +29200 - Rocks - [Mine, Prospect, hidden, null, null] +29201 - Rocks - [Mine, Prospect, hidden, null, null] +29202 - Rocks - [Mine, Prospect, hidden, null, null] +29203 - Rocks - [Mine, Prospect, hidden, null, null] +29204 - Rocks - [Mine, Prospect, hidden, null, null] +29205 - Rocks - [Mine, Prospect, hidden, null, null] +29206 - Rocks - [Mine, Prospect, hidden, null, null] +29207 - Rocks - [Mine, Prospect, hidden, null, null] +29208 - Rocks - [Mine, Prospect, hidden, null, null] +29209 - Rocks - [Mine, Prospect, hidden, null, null] +29210 - Rocks - [Mine, Prospect, hidden, null, null] +29211 - Rocks - [Mine, Prospect, hidden, null, null] +29212 - Rocks - [Mine, Prospect, hidden, null, null] +29213 - Rocks - [Mine, Prospect, hidden, null, null] +29214 - Rocks - [Mine, Prospect, hidden, null, null] +29215 - Rocks - [Mine, Prospect, hidden, null, null] +29216 - Rocks - [Mine, Prospect, hidden, null, null] +29217 - Rocks - [Mine, Prospect, hidden, null, null] +29218 - Rocks - [Mine, Prospect, hidden, null, null] +29219 - Rocks - [Mine, Prospect, hidden, null, null] +29220 - Rocks - [Mine, Prospect, hidden, null, null] +29221 - Rocks - [Mine, Prospect, hidden, null, null] +29222 - Rocks - [Mine, Prospect, hidden, null, null] +29223 - Rocks - [Mine, Prospect, hidden, null, null] +29224 - Rocks - [Mine, Prospect, hidden, null, null] +29225 - Rocks - [Mine, Prospect, hidden, null, null] +29226 - Rocks - [Mine, Prospect, hidden, null, null] +29227 - Rocks - [Mine, Prospect, hidden, null, null] +29228 - Rocks - [Mine, Prospect, hidden, null, null] +29229 - Rocks - [Mine, Prospect, hidden, null, null] +29230 - Rocks - [Mine, Prospect, hidden, null, null] +29231 - Rocks - [Mine, Prospect, hidden, null, null] +29232 - Rocks - [Mine, Prospect, hidden, null, null] +29233 - Rocks - [Mine, Prospect, hidden, null, null] +29234 - Rocks - [Mine, Prospect, hidden, null, null] +29235 - Rocks - [Mine, Prospect, hidden, null, null] +29236 - Rocks - [Mine, Prospect, hidden, null, null] +29237 - Rocks - [Mine, Prospect, hidden, null, null] +29238 - Rocks - [Mine, Prospect, hidden, null, null] +29239 - null - [null, null, null, null, null] +29240 - null - [null, null, null, null, null] +29241 - null - [null, null, null, null, null] +29242 - null - [null, null, null, null, null] +29243 - null - [null, null, null, null, null] +29244 - null - [null, null, null, null, null] +29245 - null - [null, null, null, null, null] +29246 - null - [null, null, null, null, null] +29247 - null - [null, null, null, null, null] +29248 - null - [null, null, null, null, null] +29249 - null - [null, null, null, null, null] +29250 - null - [null, null, null, null, null] +29251 - null - [null, null, null, null, null] +29252 - null - [null, null, null, null, null] +29253 - null - [null, null, null, null, null] +29254 - null - [null, null, null, null, null] +29255 - null - [null, null, null, null, null] +29256 - null - [null, null, null, null, null] +29257 - null - [null, null, null, null, null] +29258 - null - [null, null, null, null, null] +29259 - null - [null, null, null, null, null] +29260 - null - [null, null, null, null, null] +29261 - Metal door - [Open, null, null, null, null] +29262 - Metal door - [Close, null, null, null, null] +29263 - null - [null, null, null, null, null] +29264 - null - [null, null, null, null, null] +29265 - null - [null, null, null, null, null] +29266 - null - [null, null, null, null, null] +29267 - null - [null, null, null, null, null] +29268 - null - [null, null, null, null, null] +29269 - null - [null, null, null, null, null] +29270 - null - [null, null, null, null, null] +29271 - null - [null, null, null, null, null] +29272 - null - [null, null, null, null, null] +29273 - null - [null, null, null, null, null] +29274 - null - [null, null, null, null, null] +29275 - null - [null, null, null, null, null] +29276 - null - [null, null, null, null, null] +29277 - null - [null, null, null, null, null] +29278 - null - [null, null, null, null, null] +29279 - null - [null, null, null, null, null] +29280 - null - [null, null, null, null, null] +29281 - null - [null, null, null, null, null] +29282 - null - [null, null, null, null, null] +29283 - null - [null, null, null, null, null] +29284 - null - [null, null, null, null, null] +29285 - null - [null, null, null, null, null] +29286 - null - [null, null, null, null, null] +29287 - null - [null, null, null, null, null] +29288 - null - [null, null, null, null, null] +29289 - null - [null, null, null, null, null] +29290 - null - [null, null, null, null, null] +29291 - null - [null, null, null, null, null] +29292 - null - [null, null, null, null, null] +29293 - null - [null, null, null, null, null] +29294 - null - [null, null, null, null, null] +29295 - null - [null, null, null, null, null] +29296 - null - [null, null, null, null, null] +29297 - null - [null, null, null, null, null] +29298 - Stalagmite - [null, null, null, null, null] +29299 - null - [null, null, null, null, null] +29300 - null - [null, null, null, null, null] +29301 - null - [null, null, null, null, null] +29302 - null - [null, null, null, null, null] +29303 - null - [null, null, null, null, null] +29304 - null - [null, null, null, null, null] +29305 - null - [null, null, null, null, null] +29306 - null - [null, null, null, null, null] +29307 - null - [null, null, null, null, null] +29308 - null - [null, null, null, null, null] +29309 - null - [null, null, null, null, null] +29310 - null - [null, null, null, null, null] +29311 - null - [null, null, null, null, null] +29312 - null - [null, null, null, null, null] +29313 - null - [null, null, null, null, null] +29314 - Rack - [null, null, null, null, null] +29315 - Metal door - [Open, null, null, null, null] +29316 - Metal door - [Open, null, null, null, null] +29317 - Metal door - [Close, null, null, null, null] +29318 - Metal door - [Close, null, null, null, null] +29319 - Metal door - [Open, null, null, null, null] +29320 - Metal door - [Open, null, null, null, null] +29321 - Metal door - [Close, null, null, null, null] +29322 - Metal door - [Close, null, null, null, null] +29323 - null - [null, null, null, null, null] +29324 - null - [null, null, null, null, null] +29325 - null - [null, null, null, null, null] +29326 - null - [null, null, null, null, null] +29327 - null - [null, null, null, null, null] +29328 - null - [null, null, null, null, null] +29329 - null - [null, null, null, null, null] +29330 - null - [null, null, null, null, null] +29331 - null - [null, null, null, null, null] +29332 - null - [null, null, null, null, null] +29333 - Barrel - [null, null, null, null, null] +29334 - null - [null, null, null, null, null] +29335 - null - [null, null, null, null, null] +29336 - null - [null, null, null, null, null] +29337 - null - [null, null, null, null, null] +29338 - null - [null, null, null, null, null] +29339 - null - [null, null, null, null, null] +29340 - Corpse - [null, null, null, null, null] +29341 - Corpse - [null, null, null, null, null] +29342 - Corpse - [null, null, null, null, null] +29343 - Corpse - [null, null, null, null, null] +29344 - Animal skull - [null, null, null, null, null] +29345 - Curved bone - [null, null, null, null, null] +29346 - Large bone - [null, null, null, null, null] +29347 - Pile of skulls - [null, null, null, null, null] +29348 - null - [null, null, null, null, null] +29349 - null - [null, null, null, null, null] +29350 - null - [null, null, null, null, null] +29351 - Crates - [Search, null, null, null, null] +29352 - Crate - [Search, null, null, null, null] +29353 - null - [null, null, null, null, null] +29354 - Spiderweb - [Pass, null, null, null, null] +29355 - Ladder - [Climb-up, null, null, null, null] +29356 - Counter - [null, null, null, null, null] +29357 - Ladder - [Climb-down, null, null, null, null] +29358 - Ladder - [Climb-down, null, null, null, null] +29359 - Odd-looking wall - [Push, null, null, null, null] +29360 - Odd-looking wall - [Push, null, null, null, null] +29361 - Odd-looking wall - [Push, null, null, null, null] +29362 - Odd-looking wall - [Push, null, null, null, null] +29363 - null - [null, null, null, null, null] +29364 - null - [null, null, null, null, null] +29365 - null - [null, null, null, null, null] +29366 - null - [null, null, null, null, null] +29367 - null - [null, null, null, null, null] +29368 - null - [null, null, null, null, null] +29369 - null - [null, null, null, null, null] +29370 - Pipe - [Squeeze-through, null, null, null, null] +29371 - null - [null, null, null, null, null] +29372 - null - [null, null, null, null, null] +29373 - Danger sign - [null, null, null, null, null] +29374 - Monkey bars - [null, null, null, null, null] +29375 - Monkey bars - [Swing across, null, null, null, null] +29376 - Monkey bars - [Swing across, null, null, null, null] +29377 - null - [null, null, null, null, null] +29378 - null - [null, null, null, null, null] +29379 - null - [null, null, null, null, null] +29380 - null - [null, null, null, null, null] +29381 - null - [null, null, null, null, null] +29382 - null - [null, null, null, null, null] +29383 - null - [null, null, null, null, null] +29384 - null - [null, null, null, null, null] +29385 - null - [null, null, null, null, null] +29386 - null - [null, null, null, null, null] +29387 - null - [null, null, null, null, null] +29388 - null - [null, null, null, null, null] +29389 - null - [null, null, null, null, null] +29390 - null - [null, null, null, null, null] +29391 - null - [null, null, null, null, null] +29392 - null - [null, null, null, null, null] +29393 - null - [null, null, null, null, null] +29394 - null - [null, null, null, null, null] +29395 - null - [null, null, null, null, null] +29396 - null - [null, null, null, null, null] +29397 - null - [null, null, null, null, null] +29398 - null - [null, null, null, null, null] +29399 - Chest - [Search, Close, null, null, null] +29400 - Chest - [Open, null, null, null, null] +29401 - null - [null, null, null, null, null] +29402 - null - [null, null, null, null, null] +29403 - null - [null, null, null, null, null] +29404 - null - [null, null, null, null, null] +29405 - null - [null, null, null, null, null] +29406 - null - [null, null, null, null, null] +29407 - null - [null, null, null, null, null] +29408 - null - [null, null, null, null, null] +29409 - null - [null, null, null, null, null] +29410 - null - [null, null, null, null, null] +29411 - null - [null, null, null, null, null] +29412 - null - [null, null, null, null, null] +29413 - null - [null, null, null, null, null] +29414 - null - [null, null, null, null, null] +29415 - Obelisk of Earth - [null, null, null, null, null] +29416 - null - [null, null, null, null, null] +29417 - null - [null, null, null, null, null] +29418 - null - [null, null, null, null, null] +29419 - null - [null, null, null, null, null] +29420 - null - [null, null, null, null, null] +29421 - Magical symbol - [null, null, null, null, null] +29422 - null - [null, null, null, null, null] +29423 - null - [null, null, null, null, null] +29424 - null - [null, null, null, null, null] +29425 - Catapult - [null, null, null, null, null] +29426 - Catapult - [null, null, null, null, null] +29427 - Catapult - [null, null, null, null, null] +29428 - Catapult - [null, null, null, null, null] +29429 - null - [null, null, null, null, null] +29430 - null - [null, null, null, null, null] +29431 - null - [null, null, null, null, null] +29432 - Target rock - [null, null, null, null, null] +29433 - Target rock - [null, null, null, null, null] +29434 - Target rock - [null, null, null, null, null] +29435 - Boulder - [null, null, null, null, null] +29436 - Catapult - [null, null, null, null, null] +29437 - Rotten Catapult - [null, null, null, null, null] +29438 - Catapult - [null, null, null, null, null] +29439 - Catapult-winch - [null, null, null, null, null] +29440 - Catapult-winch - [null, null, null, null, null] +29441 - Catapult-winch - [null, null, null, null, null] +29442 - Catapult-lever - [null, null, null, null, null] +29443 - Catapult-lever - [null, null, null, null, null] +29444 - Catapult-lever - [null, null, null, null, null] +29445 - null - [null, null, null, null, null] +29446 - Dirt - [Dig, Flag, Inspect, null, null] +29447 - null - [null, null, null, null, null] +29448 - null - [null, null, null, null, null] +29449 - null - [null, null, null, null, null] +29450 - null - [null, null, null, null, null] +29451 - null - [null, null, null, null, null] +29452 - null - [null, null, null, null, null] +29453 - null - [null, null, null, null, null] +29454 - null - [null, null, null, null, null] +29455 - null - [null, null, null, null, null] +29456 - Dead plant - [null, null, null, null, null] +29457 - Flag - [null, null, null, null, null] +29458 - Dead plant - [null, null, null, null, null] +29459 - Flag - [null, null, null, null, null] +29460 - Stile - [Climb-over, null, null, null, null] +29461 - Instruction sign - [Read, null, null, null, null] +29462 - Instruction sign - [Read, null, null, null, null] +29463 - Instruction sign - [Read, null, null, null, null] +29464 - Instruction sign - [Read, null, null, null, null] +29465 - null - [null, null, null, null, null] +29466 - null - [null, null, null, null, null] +29467 - Table - [null, null, null, null, null] +29468 - Table - [null, null, null, null, null] +29469 - Counter - [null, null, null, null, null] +29470 - Crate - [null, null, null, null, null] +29471 - Crates - [null, null, null, null, null] +29472 - Chair - [null, null, null, null, null] +29473 - Cabinet - [null, null, null, null, null] +29474 - Barrel - [null, null, null, null, null] +29475 - Barrels - [null, null, null, null, null] +29476 - Hole - [Dig, Flag, Inspect, null, null] +29477 - Hole - [Dig, Flag, Inspect, null, null] +29478 - Hole - [Dig, Flag, Inspect, null, null] +29479 - null - [null, null, null, null, null] +29480 - null - [null, null, null, null, null] +29481 - null - [null, null, null, null, null] +29482 - null - [null, null, null, null, null] +29483 - null - [null, null, null, null, null] +29484 - null - [null, null, null, null, null] +29485 - null - [null, null, null, null, null] +29486 - null - [null, null, null, null, null] +29487 - null - [null, null, null, null, null] +29488 - null - [null, null, null, null, null] +29489 - null - [null, null, null, null, null] +29490 - null - [null, null, null, null, null] +29491 - null - [null, null, null, null, null] +29492 - null - [null, null, null, null, null] +29493 - null - [null, null, null, null, null] +29494 - null - [null, null, null, null, null] +29495 - null - [null, null, null, null, null] +29496 - null - [null, null, null, null, null] +29497 - null - [null, null, null, null, null] +29498 - null - [null, null, null, null, null] +29499 - null - [null, null, null, null, null] +29500 - null - [null, null, null, null, null] +29501 - null - [null, null, null, null, null] +29502 - null - [null, null, null, null, null] +29503 - null - [null, null, null, null, null] +29504 - null - [null, null, null, null, null] +29505 - null - [null, null, null, null, null] +29506 - null - [null, null, null, null, null] +29507 - null - [null, null, null, null, null] +29508 - null - [null, null, null, null, null] +29509 - null - [null, null, null, null, null] +29510 - null - [null, null, null, null, null] +29511 - null - [null, null, null, null, null] +29512 - null - [null, null, null, null, null] +29513 - null - [null, null, null, null, null] +29514 - null - [null, null, null, null, null] +29515 - null - [null, null, null, null, null] +29516 - null - [null, null, null, null, null] +29517 - null - [null, null, null, null, null] +29518 - null - [null, null, null, null, null] +29519 - null - [null, null, null, null, null] +29520 - null - [null, null, null, null, null] +29521 - null - [null, null, null, null, null] +29522 - null - [null, null, null, null, null] +29523 - null - [null, null, null, null, null] +29524 - null - [null, null, null, null, null] +29525 - null - [null, null, null, null, null] +29526 - null - [null, null, null, null, null] +29527 - null - [null, null, null, null, null] +29528 - null - [null, null, null, null, null] +29529 - null - [null, null, null, null, null] +29530 - null - [null, null, null, null, null] +29531 - null - [null, null, null, null, null] +29532 - null - [null, null, null, null, null] +29533 - Hole - [null, null, null, null, null] +29534 - Portal - [Enter, null, null, null, null] +29535 - null - [null, null, null, null, null] +29536 - null - [null, null, null, null, null] +29537 - Portal - [Use, null, null, null, null] +29538 - null - [null, null, null, null, null] +29539 - null - [null, null, null, null, null] +29540 - Footprints - [null, null, null, null, null] +29541 - Footprints - [null, null, null, null, null] +29542 - null - [null, null, null, null, null] +29543 - null - [null, null, null, null, null] +29544 - null - [null, null, null, null, null] +29545 - null - [null, null, null, null, null] +29546 - Bar shelves - [null, null, null, null, null] +29547 - Boulder - [null, null, null, null, null] +29548 - Boulder - [null, null, Take-Egg, null, null] +29549 - null - [null, null, null, null, null] +29550 - Wheelbarrow - [null, null, null, null, null] +29551 - Wheelbarrow - [null, null, Take-Egg, null, null] +29552 - null - [null, null, null, null, null] +29553 - Mysterious statue - [null, null, null, null, null] +29554 - Mysterious statue - [null, null, Take-Egg, null, null] +29555 - null - [null, null, null, null, null] +29556 - Statue of Saradomin - [null, null, null, null, null] +29557 - Statue of Saradomin - [null, null, Take-Egg, null, null] +29558 - null - [null, null, null, null, null] +29559 - Shop counter - [null, null, null, null, null] +29560 - Shop counter - [null, null, Take-Egg, null, null] +29561 - null - [null, null, null, null, null] +29562 - Shelves - [null, null, null, null, null] +29563 - Shelves - [null, null, Take-Egg, null, null] +29564 - null - [null, null, null, null, null] +29565 - Barrel - [null, null, null, null, null] +29566 - Barrel - [null, null, Take-Egg, null, null] +29567 - null - [null, null, null, null, null] +29568 - Old bookshelf - [null, null, null, null, null] +29569 - Old bookshelf - [null, null, Take-Egg, null, null] +29570 - null - [null, null, null, null, null] +29571 - Bar shelves - [null, null, null, null, null] +29572 - Bar shelves - [null, null, Take-Egg, null, null] +29573 - null - [null, null, null, null, null] +29574 - null - [null, null, null, null, null] +29575 - Door - [Open, null, null, null, null] +29576 - null - [null, null, null, null, null] +29577 - Treasure chest - [Open, null, null, null, null] +29578 - Treasure chest - [Search, null, null, null, null] +29579 - Slimy skulls - [null, null, null, null, null] +29580 - Slimy skulls - [null, null, null, null, null] +29581 - Bookcase - [null, null, null, null, null] +29582 - Bookcase - [null, null, null, null, null] +29583 - Satchel - [null, null, null, null, null] +29584 - Coat of arms - [null, null, null, null, null] +29585 - Poster - [null, null, null, null, null] +29586 - Poster - [Pull-back, null, null, null, null] +29587 - Desk - [null, null, null, null, null] +29588 - Big desk - [null, null, null, null, null] +29589 - Stairs - [Climb-up, null, null, null, null] +29590 - null - [null, null, null, null, null] +29591 - null - [null, null, null, null, null] +29592 - Stairs - [Climb-down, null, null, null, null] +29593 - Jail bunk - [null, null, null, null, null] +29594 - Jail bunk - [null, null, null, null, null] +29595 - Jail door - [Read-plaque on, null, null, null, null] +29596 - Jail door - [Read-plaque on, null, null, null, null] +29597 - Jail door - [Read-plaque on, null, null, null, null] +29598 - Jail door - [Read-plaque on, null, null, null, null] +29599 - Jail door - [Read-plaque on, null, null, null, null] +29600 - Jail door - [Read-plaque on, null, null, null, null] +29601 - Jail door - [Read-plaque on, null, null, null, null] +29602 - Jail entrance - [Leave, null, null, null, null] +29603 - Jail entrance - [Use, null, null, null, null] +29604 - null - [null, null, null, null, null] +29605 - null - [null, null, null, null, null] +29606 - null - [null, null, null, null, null] +29607 - null - [null, null, null, null, null] +29608 - Broken plaque - [null, null, null, null, null] +29609 - null - [null, null, null, null, null] +29610 - null - [null, null, null, null, null] +29611 - null - [null, null, null, null, null] +29612 - null - [null, null, null, null, null] +29613 - null - [null, null, null, null, null] +29614 - null - [null, null, null, null, null] +29615 - null - [null, null, null, null, null] +29616 - null - [null, null, null, null, null] +29617 - null - [null, null, null, null, null] +29618 - null - [null, null, null, null, null] +29619 - null - [null, null, null, null, null] +29620 - null - [null, null, null, null, null] +29621 - null - [null, null, null, null, null] +29622 - null - [null, null, null, null, null] +29623 - Tunnel - [Use, null, null, null, null] +29624 - Jail door - [Open, null, null, null, null] +29625 - null - [enter, null, null, null, null] +29626 - null - [null, null, null, null, null] +29627 - null - [null, null, null, null, null] +29628 - null - [null, null, null, null, null] +29629 - null - [null, null, null, null, null] +29630 - null - [null, null, null, null, null] +29631 - null - [null, null, null, null, null] +29632 - null - [null, null, null, null, null] +29633 - null - [null, null, null, null, null] +29634 - Rock pile - [null, null, null, null, null] +29635 - null - [null, null, null, null, null] +29636 - null - [null, null, null, null, null] +29637 - null - [null, null, null, null, null] +29638 - null - [null, null, null, null, null] +29639 - null - [null, null, null, null, null] +29640 - null - [null, null, null, null, null] +29641 - null - [null, null, null, null, null] +29642 - null - [null, null, null, null, null] +29643 - null - [null, null, null, null, null] +29644 - null - [null, null, null, null, null] +29645 - null - [null, null, null, null, null] +29646 - null - [null, null, null, null, null] +29647 - null - [null, null, null, null, null] +29648 - null - [null, null, null, null, null] +29649 - null - [null, null, null, null, null] +29650 - null - [null, null, null, null, null] +29651 - null - [null, null, null, null, null] +29652 - null - [null, null, null, null, null] +29653 - null - [null, null, null, null, null] +29654 - null - [null, null, null, null, null] +29655 - Stairs - [Climb-down, null, null, null, null] +29656 - Stairs - [Climb-up, null, null, null, null] +29657 - null - [null, null, null, null, null] +29658 - null - [null, null, null, null, null] +29659 - Stairs - [Climb-down, null, null, null, null] +29660 - Stairs - [Climb-up, null, null, null, null] +29661 - null - [null, null, null, null, null] +29662 - null - [null, null, null, null, null] +29663 - Stairs - [Climb-down, null, null, null, null] +29664 - Stairs - [Climb-up, null, null, null, null] +29665 - null - [null, null, null, null, null] +29666 - null - [null, null, null, null, null] +29667 - Stairs - [Climb-down, null, null, null, null] +29668 - Stairs - [Climb-up, null, null, null, null] +29669 - null - [null, null, null, null, null] +29670 - null - [null, null, null, null, null] +29671 - Stairs - [Climb-down, null, null, null, null] +29672 - Stairs - [Climb-up, null, null, null, null] +29673 - null - [null, null, null, null, null] +29674 - null - [null, null, null, null, null] +29675 - null - [null, null, null, null, null] +29676 - null - [null, null, null, null, null] +29677 - null - [null, null, null, null, null] +29678 - null - [null, null, null, null, null] +29679 - null - [null, null, null, null, null] +29680 - null - [null, null, null, null, null] +29681 - null - [null, null, null, null, null] +29682 - null - [null, null, null, null, null] +29683 - null - [null, null, null, null, null] +29684 - null - [null, null, null, null, null] +29685 - null - [null, null, null, null, null] +29686 - null - [null, null, null, null, null] +29687 - null - [null, null, null, null, null] +29688 - null - [null, null, null, null, null] +29689 - null - [null, null, null, null, null] +29690 - null - [null, null, null, null, null] +29691 - null - [null, null, null, null, null] +29692 - null - [null, null, null, null, null] +29693 - null - [null, null, null, null, null] +29694 - null - [null, null, null, null, null] +29695 - null - [null, null, null, null, null] +29696 - null - [null, null, null, null, null] +29697 - null - [null, null, null, null, null] +29698 - null - [null, null, null, null, null] +29699 - null - [null, null, null, null, null] +29700 - null - [null, null, null, null, null] +29701 - null - [null, null, null, null, null] +29702 - null - [null, null, null, null, null] +29703 - null - [null, null, null, null, null] +29704 - null - [null, null, null, null, null] +29705 - null - [null, null, null, null, null] +29706 - null - [null, null, null, null, null] +29707 - null - [null, null, null, null, null] +29708 - null - [null, null, null, null, null] +29709 - null - [null, null, null, null, null] +29710 - null - [null, null, null, null, null] +29711 - null - [null, null, null, null, null] +29712 - null - [null, null, null, null, null] +29713 - null - [null, null, null, null, null] +29714 - null - [null, null, null, null, null] +29715 - null - [null, null, null, null, null] +29716 - null - [null, null, null, null, null] +29717 - null - [null, null, null, null, null] +29718 - null - [null, null, null, null, null] +29719 - null - [null, null, null, null, null] +29720 - null - [null, null, null, null, null] +29721 - null - [null, null, null, null, null] +29722 - null - [null, null, null, null, null] +29723 - null - [null, null, null, null, null] +29724 - null - [null, null, null, null, null] +29725 - null - [null, null, null, null, null] +29726 - Rocks - [null, null, null, null, null] +29727 - Rocks - [null, null, null, null, null] +29728 - Crevice - [Enter, null, null, null, null] +29729 - Rope - [Climb, null, null, null, null] +29730 - An old lever - [Pull, null, null, null, null] +29731 - An old lever - [Pull, null, null, null, null] +29732 - Door - [Open, null, null, null, null] +29733 - null - [null, null, null, null, null] +29734 - null - [null, null, null, null, null] +29735 - null - [null, null, null, null, null] +29736 - null - [null, null, null, null, null] +29737 - Kennith - [Talk-to, null, null, null, null] +29738 - Ezekial Lovecraft - [Talk-to, null, null, null, null] +29739 - Villagers - [null, null, null, null, null] +29740 - Minecart - [Crouch, null, null, null, null] +29741 - Steam vent - [Use, null, null, null, null] +29742 - Steam vent - [null, null, null, null, null] +29743 - Iron pickaxe - [Pick-up, null, null, null, null] +29744 - Lever - [Use, null, null, null, null] +29745 - Rocks - [Break, null, hidden, null, null] +29746 - Rubium - [Mine, Prospect, hidden, null, null] +29747 - Wall - [Prospect, null, null, null, null] +29748 - Wall - [Prospect, null, null, null, null] +29749 - Wall - [Mine, Prospect, hidden, null, null] +29750 - Wall - [Enter, null, null, null, null] +29751 - null - [null, null, null, null, null] +29752 - null - [null, null, null, null, null] +29753 - null - [null, null, null, null, null] +29754 - null - [null, null, null, null, null] +29755 - null - [null, null, null, null, null] +29756 - null - [null, null, null, null, null] +29757 - null - [null, null, null, null, null] +29758 - null - [null, null, null, null, null] +29759 - null - [null, null, null, null, null] +29760 - null - [null, null, null, null, null] +29761 - null - [null, null, null, null, null] +29762 - null - [null, null, null, null, null] +29763 - null - [null, null, null, null, null] +29764 - null - [null, null, null, null, null] +29765 - null - [null, null, null, null, null] +29766 - null - [null, null, null, null, null] +29767 - null - [null, null, null, null, null] +29768 - null - [null, null, null, null, null] +29769 - null - [null, null, null, null, null] +29770 - null - [null, null, null, null, null] +29771 - null - [null, null, null, null, null] +29772 - null - [null, null, null, null, null] +29773 - null - [null, null, null, null, null] +29774 - null - [null, null, null, null, null] +29775 - Door - [Open, null, null, null, null] +29776 - Door - [Open, null, null, null, null] +29777 - Door - [Open, null, null, null, null] +29778 - Door - [Open, null, null, null, null] +29779 - null - [null, null, null, null, null] +29780 - null - [null, null, null, null, null] +29781 - null - [null, null, null, null, null] +29782 - null - [null, null, null, null, null] +29783 - null - [null, null, null, null, null] +29784 - null - [null, null, null, null, null] +29785 - null - [null, null, null, null, null] +29786 - null - [null, null, null, null, null] +29787 - null - [null, null, null, null, null] +29788 - null - [null, null, null, null, null] +29789 - null - [null, null, null, null, null] +29790 - null - [null, null, null, null, null] +29791 - null - [null, null, null, null, null] +29792 - null - [null, null, null, null, null] +29793 - null - [null, null, null, null, null] +29794 - null - [null, null, null, null, null] +29795 - null - [null, null, null, null, null] +29796 - null - [null, null, null, null, null] +29797 - Bed - [null, null, null, null, null] +29798 - Chair - [null, null, null, null, null] +29799 - null - [null, null, null, null, null] +29800 - null - [null, null, null, null, null] +29801 - null - [null, null, null, null, null] +29802 - null - [null, null, null, null, null] +29803 - Barrel - [null, null, null, null, null] +29804 - Broken lobster trap - [null, null, null, null, null] +29805 - null - [null, null, null, null, null] +29806 - null - [null, null, null, null, null] +29807 - Rocks - [Climb-over, null, null, null, null] +29808 - Toy train - [Pick-up, null, null, null, null] +29809 - Entrance - [Enter, null, null, null, null] +29810 - Entrance - [Enter, null, null, null, null] +29811 - Bed - [null, null, null, null, null] +29812 - null - [null, null, null, null, null] +29813 - null - [null, null, null, null, null] +29814 - null - [null, null, null, null, null] +29815 - null - [null, null, null, null, null] +29816 - null - [null, null, null, null, null] +29817 - null - [null, null, null, null, null] +29818 - null - [null, null, null, null, null] +29819 - null - [null, null, null, null, null] +29820 - null - [null, null, null, null, null] +29821 - null - [null, null, null, null, null] +29822 - null - [null, null, null, null, null] +29823 - null - [null, null, null, null, null] +29824 - null - [null, null, null, null, null] +29825 - Sign - [null, null, null, null, null] +29826 - Rabbit hole - [Investigate, null, null, null, null] +29827 - Rabbit hole - [Deposit-Eggs, null, null, null, null] +29828 - Rabbit hole - [Enter, null, null, null, null] +29829 - Rabbit hole - [Leave-Warren, null, null, null, null] +29830 - Rabbit hole - [Enter, null, null, null, null] +29831 - Rabbit hole - [Enter, null, null, null, null] +29832 - Easter banqueting table - [null, null, null, null, null] +29833 - Easter dining chair - [null, null, null, null, null] +29834 - null - [null, null, null, null, null] +29835 - null - [null, null, null, null, null] +29836 - null - [null, null, null, null, null] +29837 - Easter flag - [null, null, null, null, null] +29838 - Easter banner - [null, null, null, null, null] +29839 - Incubator instructions - [Read, null, null, null, null] +29840 - Chocolate mixer - [Add-Chocolate, null, null, null, null] +29841 - Chocolate mixer - [Add-Chocolate, null, null, null, null] +29842 - null - [null, null, null, null, null] +29843 - null - [null, null, null, null, null] +29844 - null - [null, null, null, null, null] +29845 - null - [null, null, null, null, null] +29846 - null - [null, null, null, null, null] +29847 - null - [null, null, null, null, null] +29848 - null - [null, null, null, null, null] +29849 - null - [null, null, null, null, null] +29850 - null - [null, null, null, null, null] +29851 - null - [null, null, null, null, null] +29852 - Basket - [null, null, null, null, null] +29853 - Incubator water tank - [Add-Water, Check, null, null, null] +29854 - Incubator water tank - [Add-Water, Check, null, null, null] +29855 - Incubator coal scuttle - [Add-Coal, Check, null, null, null] +29856 - Incubator coal scuttle - [Add-Coal, Check, null, null, null] +29857 - Incubator - [Add-Egg, null, null, null, null] +29858 - Incubator - [null, null, null, null, null] +29859 - Incubator - [null, null, null, null, null] +29860 - Incubator - [null, null, null, null, null] +29861 - Incubator - [null, null, null, null, null] +29862 - Incubator - [null, null, null, null, null] +29863 - Incubator - [null, null, null, null, null] +29864 - Incubator controls - [Adjust-Temperature, null, null, null, null] +29865 - Cockatrice eggs - [Take-Egg, null, null, null, null] +29866 - Cockatrice eggs - [Take-Egg, null, null, null, null] +29867 - Large table - [Take-Bucket, null, null, null, null] +29868 - Coal - [Fill-Buckets, null, null, null, null] +29869 - Chocolate pool - [Dip-Egg, null, null, null, null] +29870 - null - [null, null, null, null, null] +29871 - Water pool - [Fill-Buckets, null, null, null, null] +29872 - null - [null, null, null, null, null] +29873 - null - [null, null, null, null, null] +29874 - null - [null, null, null, null, null] +29875 - null - [null, null, null, null, null] +29876 - null - [null, null, null, null, null] +29877 - null - [null, null, null, null, null] +29878 - null - [null, null, null, null, null] +29879 - null - [null, null, null, null, null] +29880 - null - [null, null, null, null, null] +29881 - null - [null, null, null, null, null] +29882 - Small obelisk - [Renew-points, null, null, null, null] +29883 - null - [null, null, null, null, null] +29884 - null - [null, null, null, null, null] +29885 - null - [null, null, null, null, null] +29886 - null - [null, null, null, null, null] +29887 - Shaking box - [Check, null, null, null, null] +29888 - Shaking box - [Check, null, null, null, null] +29889 - Box trap - [null, null, null, null, null] +29890 - Box trap - [null, null, null, null, null] +29891 - Box trap - [null, null, null, null, null] +29892 - Box trap - [null, null, null, null, null] +29893 - Box trap - [null, null, null, null, null] +29894 - Box trap - [null, null, null, null, null] +29895 - Box trap - [null, null, null, null, null] +29896 - Box trap - [null, null, null, null, null] +29897 - Shaking box - [Check, null, null, null, null] +29898 - Shaking box - [Check, null, null, null, null] +29899 - Shaking box - [Check, null, null, null, null] +29900 - Shaking box - [Check, null, null, null, null] +29901 - Shaking box - [Check, null, null, null, null] +29902 - Shaking box - [Check, null, null, null, null] +29903 - Shaking box - [Check, null, null, null, null] +29904 - Shaking box - [Check, null, null, null, null] +29905 - Shaking box - [Check, null, null, null, null] +29906 - Box trap - [null, null, null, null, null] +29907 - Box trap - [null, null, null, null, null] +29908 - Box trap - [null, null, null, null, null] +29909 - Box trap - [null, null, null, null, null] +29910 - Shaking box - [Check, null, null, null, null] +29911 - Shaking box - [Check, null, null, null, null] +29912 - Shaking box - [Check, null, null, null, null] +29913 - Shaking box - [Check, null, null, null, null] +29914 - Box trap - [null, null, null, null, null] +29915 - Box trap - [null, null, null, null, null] +29916 - Box trap - [null, null, null, null, null] +29917 - Box trap - [null, null, null, null, null] +29918 - Box trap - [null, null, null, null, null] +29919 - Box trap - [null, null, null, null, null] +29920 - Box trap - [null, null, null, null, null] +29921 - Box trap - [null, null, null, null, null] +29922 - Box trap - [null, null, null, null, null] +29923 - Box trap - [null, null, null, null, null] +29924 - Box trap - [null, null, null, null, null] +29925 - Box trap - [null, null, null, null, null] +29926 - Box trap - [null, null, null, null, null] +29927 - Box trap - [null, null, null, null, null] +29928 - Box trap - [null, null, null, null, null] +29929 - Box trap - [null, null, null, null, null] +29930 - Net trap - [Check, null, null, null, null] +29931 - Net trap - [Check, null, null, null, null] +29932 - Net trap - [Check, null, null, null, null] +29933 - Net trap - [Check, null, null, null, null] +29934 - Net trap - [Check, null, null, null, null] +29935 - Net trap - [Check, null, null, null, null] +29936 - Net trap - [Check, null, null, null, null] +29937 - Net trap - [Check, null, null, null, null] +29938 - Small obelisk - [Renew-points, null, null, null, null] +29939 - Small obelisk - [Renew-points, null, null, null, null] +29940 - Small obelisk - [Renew-points, null, null, null, null] +29941 - Small obelisk - [Renew-points, null, null, null, null] +29942 - Small obelisk - [Renew-points, null, null, null, null] +29943 - Small obelisk - [Renew-points, null, null, null, null] +29944 - Small obelisk - [Renew-points, null, null, null, null] +29945 - Small obelisk - [Renew-points, null, null, null, null] +29946 - Small obelisk - [Renew-points, null, null, null, null] +29947 - Small obelisk - [Renew-points, null, null, null, null] +29948 - Small obelisk - [Renew-points, null, null, null, null] +29949 - Small obelisk - [Renew-points, null, null, null, null] +29950 - Small obelisk - [Renew-points, null, null, null, null] +29951 - Small obelisk - [Renew-points, null, null, null, null] +29952 - Small obelisk - [Renew-points, null, null, null, null] +29953 - Small obelisk - [Renew-points, null, null, null, null] +29954 - Small obelisk - [Renew-points, null, null, null, null] +29955 - Small obelisk - [Renew-points, null, null, null, null] +29956 - Small obelisk - [Renew-points, null, null, null, null] +29957 - Small obelisk - [Renew-points, null, null, null, null] +29958 - Small obelisk - [Renew-points, null, null, null, null] +29959 - Small obelisk - [Renew-points, null, null, null, null] +29960 - Box trap - [null, null, null, null, null] +29961 - Box trap - [null, null, null, null, null] +29962 - Box trap - [null, null, null, null, null] +29963 - Box trap - [null, null, null, null, null] +29964 - Box trap - [null, null, null, null, null] +29965 - Box trap - [null, null, null, null, null] +29966 - Box trap - [null, null, null, null, null] +29967 - Box trap - [null, null, null, null, null] +29968 - Box trap - [null, null, null, null, null] +29969 - Box trap - [null, null, null, null, null] +29970 - Box trap - [null, null, null, null, null] +29971 - Box trap - [null, null, null, null, null] +29972 - Box trap - [null, null, null, null, null] +29973 - Box trap - [null, null, null, null, null] +29974 - Box trap - [null, null, null, null, null] +29975 - Box trap - [null, null, null, null, null] +29976 - Box trap - [null, null, null, null, null] +29977 - Box trap - [null, null, null, null, null] +29978 - Box trap - [null, null, null, null, null] +29979 - Box trap - [null, null, null, null, null] +29980 - Box trap - [null, null, null, null, null] +29981 - Box trap - [null, null, null, null, null] +29982 - Box trap - [null, null, null, null, null] +29983 - Box trap - [null, null, null, null, null] +29984 - Box trap - [null, null, null, null, null] +29985 - Box trap - [null, null, null, null, null] +29986 - Box trap - [null, null, null, null, null] +29987 - Box trap - [null, null, null, null, null] +29988 - Box trap - [null, null, null, null, null] +29989 - Box trap - [null, null, null, null, null] +29990 - Box trap - [null, null, null, null, null] +29991 - Box trap - [null, null, null, null, null] +29992 - null - [null, null, null, null, null] +29993 - null - [null, null, null, null, null] +29994 - null - [null, null, null, null, null] +29995 - null - [null, null, null, null, null] +29996 - null - [null, null, null, null, null] +29997 - null - [null, null, null, null, null] +29998 - null - [null, null, null, null, null] +29999 - null - [null, null, null, null, null] +30000 - null - [null, null, null, null, null] +30001 - null - [null, null, null, null, null] +30002 - null - [null, null, null, null, null] +30003 - null - [null, null, null, null, null] +30004 - null - [null, null, null, null, null] +30005 - null - [null, null, null, null, null] +30006 - null - [null, null, null, null, null] +30007 - null - [null, null, null, null, null] +30008 - null - [null, null, null, null, null] +30009 - null - [null, null, null, null, null] +30010 - Rubble - [null, null, null, null, null] +30011 - Trapdoor - [Open, null, null, null, null] +30012 - Broken roof - [null, null, null, null, null] +30013 - Damaged wall - [null, null, null, null, null] +30014 - Repaired wall - [null, null, null, null, null] +30015 - Bank booth - [null, null, null, null, null] +30016 - Bank booth - [Use, Use-quickly, Collect, null, null] +30017 - Fire - [null, null, null, null, null] +30018 - Broken furnace - [null, null, null, null, null] +30019 - Repaired furnace - [null, null, null, null, null] +30020 - Repaired furnace - [null, null, null, null, null] +30021 - Furnace - [Smelt, null, null, null, null] +30022 - Shelves - [null, null, null, null, null] +30023 - null - [null, null, null, null, null] +30024 - null - [null, null, null, null, null] +30025 - null - [null, null, null, null, null] +30026 - null - [null, null, null, null, null] +30027 - null - [null, null, null, null, null] +30028 - null - [null, null, null, null, null] +30029 - null - [null, null, null, null, null] +30030 - null - [null, null, null, null, null] +30031 - Ladder - [Climb-up, null, null, null, null] +30032 - Gnomecopter - [Fly, null, null, null, null] +30033 - Gnomecopter - [null, null, null, null, null] +30034 - Gnomecopter - [null, null, null, null, null] +30035 - Gnome stall - [null, null, null, null, null] +30036 - Entrance sign - [Read, null, null, null, null] +30037 - Advertisement - [Read, null, null, null, null] +30038 - null - [null, null, null, null, null] +30039 - Signpost - [Read, null, null, null, null] +30040 - Signpost - [Read, null, null, null, null] +30041 - null - [null, null, null, null, null] +30042 - null - [null, null, null, null, null] +30043 - Windsock - [null, null, null, null, null] +30044 - Deposit box - [Deposit, null, null, null, null] +30045 - Deposit box - [Deposit, null, null, null, null] +30046 - null - [null, null, null, null, null] +30047 - null - [null, null, null, null, null] +30048 - null - [null, null, null, null, null] +30049 - null - [null, null, null, null, null] +30050 - null - [null, null, null, null, null] +30051 - null - [null, null, null, null, null] +30052 - null - [null, null, null, null, null] +30053 - null - [null, null, null, null, null] +30054 - null - [null, null, null, null, null] +30055 - null - [null, null, null, null, null] +30056 - null - [null, null, null, null, null] +30057 - null - [null, null, null, null, null] +30058 - null - [null, null, null, null, null] +30059 - null - [null, null, null, null, null] +30060 - null - [null, null, null, null, null] +30061 - null - [null, null, null, null, null] +30062 - null - [null, null, null, null, null] +30063 - null - [null, null, null, null, null] +30064 - null - [null, null, null, null, null] +30065 - null - [null, null, null, null, null] +30066 - null - [null, null, null, null, null] +30067 - null - [null, null, null, null, null] +30068 - null - [null, null, null, null, null] +30069 - null - [null, null, null, null, null] +30070 - Windsock - [null, null, null, null, null] +30071 - null - [null, null, null, null, null] +30072 - null - [null, null, null, null, null] +30073 - null - [null, null, null, null, null] +30074 - Table - [View-game, null, null, null, null] +30075 - Table - [View-game, null, null, null, null] +30076 - Table - [View-game, null, null, null, null] +30077 - Table - [View-game, null, null, null, null] +30078 - Table - [null, null, null, null, null] +30079 - Table - [null, null, null, null, null] +30080 - Table - [null, null, null, null, null] +30081 - Table - [null, null, null, null, null] +30082 - Pit - [null, null, null, null, null] +30083 - Spiked pit - [null, null, null, null, null] +30084 - Collapsed trap - [null, null, null, null, null] +30085 - Collapsed trap - [null, null, null, null, null] +30086 - Pit trap - [null, null, null, null, null] +30087 - Pit trap - [null, null, null, null, null] +30088 - Pit trap - [null, null, null, null, null] +30089 - Pit trap - [null, null, null, null, null] +30090 - Pit trap - [null, null, null, null, null] +30091 - Pit trap - [null, null, null, null, null] +30092 - Pit trap - [null, null, null, null, null] +30093 - Pit trap - [null, null, null, null, null] +30094 - Hole - [null, null, null, null, null] +30095 - Tracks - [null, null, null, null, null] +30096 - Tracks - [null, null, null, null, null] +30097 - Tracks - [null, null, null, null, null] +30098 - Snow drift - [null, null, null, null, null] +30099 - Hollow log - [null, null, null, null, null] +30100 - Hollow log - [null, null, null, null, null] +30101 - Hollow log - [null, null, null, null, null] +30102 - Tunnel - [null, null, null, null, null] +30103 - Steps - [null, null, null, null, null] +30104 - Steps - [null, null, null, null, null] +30105 - Bird snare - [null, null, null, null, null] +30106 - Bird snare - [null, null, null, null, null] +30107 - Bird snare - [null, null, null, null, null] +30108 - Bird snare - [null, null, null, null, null] +30109 - Bird snare - [null, null, null, null, null] +30110 - Bird snare - [null, null, null, null, null] +30111 - Bird snare - [null, null, null, null, null] +30112 - Bird snare - [null, null, null, null, null] +30113 - Bird snare - [null, null, null, null, null] +30114 - - [null, null, null, null, null] +30115 - Staircase - [Climb, null, null, null, null] +30116 - Gate - [Open, null, null, null, null] +30117 - Gate - [Close, null, null, null, null] +30118 - Gate - [Open, null, null, null, null] +30119 - Gate - [Close, null, null, null, null] +30120 - Gate - [Open, null, Repair, null, null] +30121 - Gate - [Close, null, Repair, null, null] +30122 - Gate - [Open, null, Repair, null, null] +30123 - Gate - [Close, null, Repair, null, null] +30124 - Gate - [Open, null, Repair, null, null] +30125 - Gate - [Close, null, Repair, null, null] +30126 - Gate - [Open, null, Repair, null, null] +30127 - Gate - [Close, null, Repair, null, null] +30128 - Gate - [Open, null, Repair, null, null] +30129 - Gate - [Close, null, Repair, null, null] +30130 - Gate - [Open, null, Repair, null, null] +30131 - Gate - [Close, null, Repair, null, null] +30132 - Tree - [Chop down, null, null, null, null] +30133 - Tree - [Chop down, null, null, null, null] +30134 - null - [null, null, null, null, null] +30135 - null - [null, null, null, null, null] +30136 - null - [null, null, null, null, null] +30137 - null - [null, null, null, null, null] +30138 - null - [null, null, null, null, null] +30139 - null - [null, null, null, null, null] +30140 - null - [null, null, null, null, null] +30141 - Energy barrier - [Pass, null, null, null, null] +30142 - Stone dispenser - [null, null, null, null, null] +30143 - Stone dispenser - [Take-stone, null, null, null, null] +30144 - Forfeit tunnel - [Exit-through, null, null, null, null] +30145 - Forfeit tunnel - [Exit-through, null, null, null, null] +30146 - Portal - [Use, null, null, null, null] +30147 - null - [null, null, null, null, null] +30148 - null - [null, null, null, null, null] +30149 - null - [null, null, null, null, null] +30150 - null - [null, null, null, null, null] +30151 - null - [null, null, null, null, null] +30152 - null - [null, null, null, null, null] +30153 - null - [null, null, null, null, null] +30154 - null - [null, null, null, null, null] +30155 - null - [null, null, null, null, null] +30156 - null - [null, null, null, null, null] +30157 - null - [null, null, null, null, null] +30158 - null - [null, null, null, null, null] +30159 - null - [null, null, null, null, null] +30160 - null - [null, null, null, null, null] +30161 - null - [null, null, null, null, null] +30162 - null - [null, null, null, null, null] +30163 - null - [null, null, null, null, null] +30164 - null - [null, null, null, null, null] +30165 - null - [null, null, null, null, null] +30166 - null - [null, null, null, null, null] +30167 - null - [null, null, null, null, null] +30168 - null - [null, null, null, null, null] +30169 - null - [null, null, null, null, null] +30170 - null - [null, null, null, null, null] +30171 - null - [null, null, null, null, null] +30172 - null - [null, null, null, null, null] +30173 - null - [null, null, null, null, null] +30174 - null - [null, null, null, null, null] +30175 - null - [null, null, null, null, null] +30176 - null - [null, null, null, null, null] +30177 - null - [null, null, null, null, null] +30178 - null - [null, null, null, null, null] +30179 - null - [null, null, null, null, null] +30180 - null - [null, null, null, null, null] +30181 - null - [null, null, null, null, null] +30182 - null - [null, null, null, null, null] +30183 - null - [null, null, null, null, null] +30184 - null - [null, null, null, null, null] +30185 - null - [null, null, null, null, null] +30186 - null - [null, null, null, null, null] +30187 - null - [null, null, null, null, null] +30188 - null - [null, null, null, null, null] +30189 - null - [null, null, null, null, null] +30190 - null - [null, null, null, null, null] +30191 - null - [null, null, null, null, null] +30192 - null - [null, null, null, null, null] +30193 - null - [null, null, null, null, null] +30194 - null - [null, null, null, null, null] +30195 - null - [null, null, null, null, null] +30196 - null - [null, null, null, null, null] +30197 - null - [null, null, null, null, null] +30198 - null - [null, null, null, null, null] +30199 - null - [null, null, null, null, null] +30200 - null - [null, null, null, null, null] +30201 - null - [null, null, null, null, null] +30202 - null - [null, null, null, null, null] +30203 - Stairs - [Exit, null, null, null, null] +30204 - Cave entrance - [Enter, null, null, null, null] +30205 - Scoreboard - [Look-at, null, null, null, null] +30206 - Crates - [null, null, null, null, null] +30207 - Crates - [null, null, null, null, null] +30208 - Crate - [null, null, null, null, null] +30209 - Shelf - [null, null, null, null, null] +30210 - Small shelf - [null, null, null, null, null] +30211 - Spear barrel - [null, null, null, null, null] +30212 - Counter - [null, null, null, null, null] +30213 - Entrance - [null, null, null, null, null] +30214 - Bench - [null, null, null, null, null] +30215 - Bench - [null, null, null, null, null] +30216 - Bench - [null, null, null, null, null] +30217 - Bench - [null, null, null, null, null] +30218 - Bench - [null, null, null, null, null] +30219 - Punchbag - [null, null, null, null, null] +30220 - Punchbag - [null, null, null, null, null] +30221 - Suit of armour - [null, null, null, null, null] +30222 - Table - [null, null, null, null, null] +30223 - Fountain - [null, null, null, null, null] +30224 - Passageway - [Go-through, null, null, null, null] +30225 - null - [null, null, null, null, null] +30226 - null - [null, null, null, null, null] +30227 - null - [null, null, null, null, null] +30228 - null - [null, null, null, null, null] +30229 - null - [null, null, null, null, null] +30230 - null - [null, null, null, null, null] +30231 - null - [null, null, null, null, null] +30232 - null - [null, null, null, null, null] +30233 - null - [null, null, null, null, null] +30234 - null - [null, null, null, null, null] +30235 - null - [null, null, null, null, null] +30236 - null - [null, null, null, null, null] +30237 - null - [null, null, null, null, null] +30238 - null - [null, null, null, null, null] +30239 - null - [null, null, null, null, null] +30240 - null - [null, null, null, null, null] +30241 - null - [null, null, null, null, null] +30242 - null - [null, null, null, null, null] +30243 - null - [null, null, null, null, null] +30244 - null - [null, null, null, null, null] +30245 - null - [null, null, null, null, null] +30246 - null - [null, null, null, null, null] +30247 - null - [null, null, null, null, null] +30248 - null - [null, null, null, null, null] +30249 - null - [null, null, null, null, null] +30250 - null - [null, null, null, null, null] +30251 - null - [null, null, null, null, null] +30252 - null - [null, null, null, null, null] +30253 - null - [null, null, null, null, null] +30254 - null - [null, null, null, null, null] +30255 - null - [null, null, null, null, null] +30256 - null - [null, null, null, null, null] +30257 - null - [null, null, null, null, null] +30258 - null - [null, null, null, null, null] +30259 - null - [null, null, null, null, null] +30260 - null - [null, null, null, null, null] +30261 - Wooden doors - [Open, null, null, null, null] +30262 - Wooden doors - [Open, null, null, null, null] +30263 - Wooden doors - [Walk-through, null, null, null, null] +30264 - Wooden doors - [Walk-through, null, null, null, null] +30265 - Wooden doors - [Open, null, null, null, null] +30266 - Wooden doors - [null, null, null, null, null] +30267 - null - [null, null, null, null, null] +30268 - null - [null, null, null, null, null] +30269 - null - [null, null, null, null, null] +30270 - null - [null, null, null, null, null] +30271 - null - [null, null, null, null, null] +30272 - null - [null, null, null, null, null] +30273 - null - [null, null, null, null, null] +30274 - null - [null, null, null, null, null] +30275 - Ladder - [null, null, null, null, null] +30276 - null - [null, null, null, null, null] +30277 - Shelves - [null, null, null, null, null] +30278 - Corpse - [null, null, null, null, null] +30279 - Bookshelf - [null, null, null, null, null] +30280 - Bookshelf - [null, null, null, null, null] +30281 - Lab table - [null, null, null, null, null] +30282 - null - [null, null, null, null, null] +30283 - null - [null, null, null, null, null] +30284 - null - [null, null, null, null, null] +30285 - null - [null, null, null, null, null] +30286 - null - [null, null, null, null, null] +30287 - null - [null, null, null, null, null] +30288 - Crate - [null, null, null, null, null] +30289 - Gnome skeleton - [null, null, null, null, null] +30290 - null - [null, null, null, null, null] +30291 - null - [null, null, null, null, null] +30292 - null - [null, null, null, null, null] +30293 - null - [null, null, null, null, null] +30294 - null - [null, null, null, null, null] +30295 - Column - [null, null, null, null, null] +30296 - Column - [null, null, null, null, null] +30297 - Column - [null, null, null, null, null] +30298 - null - [null, null, null, null, null] +30299 - null - [null, null, null, null, null] +30300 - null - [null, null, null, null, null] +30301 - null - [null, null, null, null, null] +30302 - null - [null, null, null, null, null] +30303 - null - [null, null, null, null, null] +30304 - null - [null, null, null, null, null] +30305 - null - [null, null, null, null, null] +30306 - null - [null, null, null, null, null] +30307 - null - [null, null, null, null, null] +30308 - null - [null, null, null, null, null] +30309 - null - [null, null, null, null, null] +30310 - null - [null, null, null, null, null] +30311 - null - [null, null, null, null, null] +30312 - null - [null, null, null, null, null] +30313 - null - [null, null, null, null, null] +30314 - null - [null, null, null, null, null] +30315 - null - [null, null, null, null, null] +30316 - null - [null, null, null, null, null] +30317 - null - [null, null, null, null, null] +30318 - null - [null, null, null, null, null] +30319 - Broken rusty cage - [null, null, null, null, null] +30320 - Rusty broken cage - [null, null, null, null, null] +30321 - Broken rusting cage - [null, null, null, null, null] +30322 - Caged skeleton - [null, null, null, null, null] +30323 - Broken range - [null, null, null, null, null] +30324 - Equipment table - [null, null, null, null, null] +30325 - Broken equipment table - [null, null, null, null, null] +30326 - Operating table - [null, null, null, null, null] +30327 - Restraining table - [null, null, null, null, null] +30328 - Restraining table - [null, null, null, null, null] +30329 - Restraining table. - [null, null, null, null, null] +30330 - Research desk - [null, null, null, null, null] +30331 - Research desk - [null, null, null, null, null] +30332 - Research table - [null, null, null, null, null] +30333 - null - [null, null, null, null, null] +30334 - null - [null, null, null, null, null] +30335 - Crate - [null, null, null, null, null] +30336 - null - [null, null, null, null, null] +30337 - Large rowboat - [null, null, null, null, null] +30338 - null - [null, null, null, null, null] +30339 - null - [null, null, null, null, null] +30340 - null - [null, null, null, null, null] +30341 - null - [null, null, null, null, null] +30342 - null - [null, null, null, null, null] +30343 - null - [null, null, null, null, null] +30344 - null - [null, null, null, null, null] +30345 - null - [null, null, null, null, null] +30346 - null - [null, null, null, null, null] +30347 - null - [null, null, null, null, null] +30348 - null - [null, null, null, null, null] +30349 - null - [null, null, null, null, null] +30350 - null - [null, null, null, null, null] +30351 - null - [null, null, null, null, null] +30352 - null - [null, null, null, null, null] +30353 - null - [null, null, null, null, null] +30354 - null - [null, null, null, null, null] +30355 - null - [null, null, null, null, null] +30356 - null - [null, null, null, null, null] +30357 - null - [null, null, null, null, null] +30358 - null - [null, null, null, null, null] +30359 - null - [null, null, null, null, null] +30360 - null - [null, null, null, null, null] +30361 - null - [null, null, null, null, null] +30362 - null - [null, null, null, null, null] +30363 - null - [null, null, null, null, null] +30364 - null - [null, null, null, null, null] +30365 - null - [null, null, null, null, null] +30366 - null - [null, null, null, null, null] +30367 - null - [null, null, null, null, null] +30368 - null - [null, null, null, null, null] +30369 - null - [null, null, null, null, null] +30370 - null - [null, null, null, null, null] +30371 - null - [null, null, null, null, null] +30372 - null - [null, null, null, null, null] +30373 - null - [null, null, null, null, null] +30374 - null - [null, null, null, null, null] +30375 - null - [null, null, null, null, null] +30376 - null - [null, null, null, null, null] +30377 - null - [null, null, null, null, null] +30378 - null - [null, null, null, null, null] +30379 - null - [null, null, null, null, null] +30380 - null - [null, null, null, null, null] +30381 - null - [null, null, null, null, null] +30382 - null - [null, null, null, null, null] +30383 - null - [null, null, null, null, null] +30384 - null - [null, null, null, null, null] +30385 - null - [null, null, null, null, null] +30386 - null - [null, null, null, null, null] +30387 - null - [null, null, null, null, null] +30388 - null - [null, null, null, null, null] +30389 - null - [null, null, null, null, null] +30390 - null - [null, null, null, null, null] +30391 - null - [null, null, null, null, null] +30392 - null - [null, null, null, null, null] +30393 - null - [null, null, null, null, null] +30394 - null - [null, null, null, null, null] +30395 - null - [null, null, null, null, null] +30396 - null - [null, null, null, null, null] +30397 - null - [null, null, null, null, null] +30398 - null - [null, null, null, null, null] +30399 - null - [null, null, null, null, null] +30400 - null - [null, null, null, null, null] +30401 - null - [null, null, null, null, null] +30402 - null - [null, null, null, null, null] +30403 - null - [null, null, null, null, null] +30404 - null - [null, null, null, null, null] +30405 - null - [null, null, null, null, null] +30406 - null - [null, null, null, null, null] +30407 - null - [null, null, null, null, null] +30408 - null - [null, null, null, null, null] +30409 - null - [null, null, null, null, null] +30410 - null - [null, null, null, null, null] +30411 - null - [null, null, null, null, null] +30412 - null - [null, null, null, null, null] +30413 - null - [null, null, null, null, null] +30414 - null - [null, null, null, null, null] +30415 - null - [null, null, null, null, null] +30416 - null - [null, null, null, null, null] +30417 - null - [null, null, null, null, null] +30418 - null - [null, null, null, null, null] +30419 - null - [null, null, null, null, null] +30420 - null - [null, null, null, null, null] +30421 - null - [null, null, null, null, null] +30422 - null - [null, null, null, null, null] +30423 - null - [null, null, null, null, null] +30424 - null - [null, null, null, null, null] +30425 - null - [null, null, null, null, null] +30426 - null - [null, null, null, null, null] +30427 - null - [null, null, null, null, null] +30428 - null - [null, null, null, null, null] +30429 - null - [null, null, null, null, null] +30430 - null - [null, null, null, null, null] +30431 - null - [null, null, null, null, null] +30432 - null - [null, null, null, null, null] +30433 - null - [null, null, null, null, null] +30434 - null - [null, null, null, null, null] +30435 - null - [null, null, null, null, null] +30436 - null - [null, null, null, null, null] +30437 - null - [null, null, null, null, null] +30438 - null - [null, null, null, null, null] +30439 - null - [null, null, null, null, null] +30440 - null - [null, null, null, null, null] +30441 - null - [null, null, null, null, null] +30442 - null - [null, null, null, null, null] +30443 - null - [null, null, null, null, null] +30444 - null - [null, null, null, null, null] +30445 - null - [null, null, null, null, null] +30446 - null - [null, null, null, null, null] +30447 - null - [null, null, null, null, null] +30448 - null - [null, null, null, null, null] +30449 - null - [null, null, null, null, null] +30450 - null - [null, null, null, null, null] +30451 - null - [null, null, null, null, null] +30452 - null - [null, null, null, null, null] +30453 - null - [null, null, null, null, null] +30454 - null - [null, null, null, null, null] +30455 - null - [null, null, null, null, null] +30456 - null - [null, null, null, null, null] +30457 - null - [null, null, null, null, null] +30458 - Wooden beam - [null, null, null, null, null] +30459 - Wooden beam - [climb-up, null, null, null, null] +30460 - Safalaan - [Look-at, null, null, null, null] +30461 - null - [null, null, null, null, null] +30462 - Andiess Juip - [Look-at, null, null, null, null] +30463 - Kael Forshaw - [Look-at, null, null, null, null] +30464 - Safalaan - [null, null, null, null, null] +30465 - Andiess Juip - [null, null, null, null, null] +30466 - Kael Forshaw - [null, null, null, null, null] +30467 - Funeral pyre - [null, null, null, null, null] +30468 - Funeral pyre - [null, null, null, null, null] +30469 - Funeral pyre - [null, null, null, null, null] +30470 - Funeral pyre - [null, null, null, null, null] +30471 - Funeral pyre - [null, null, null, null, null] +30472 - Funeral pyre - [null, null, null, null, null] +30473 - Funeral pyre - [null, null, null, null, null] +30474 - Funeral pyre - [null, null, null, null, null] +30475 - Funeral pyre - [null, null, null, null, null] +30476 - Funeral pyre - [null, null, null, null, null] +30477 - Funeral pyre - [null, null, null, null, null] +30478 - Funeral pyre - [Light, null, null, null, null] +30479 - Funeral pyre - [Light, null, null, null, null] +30480 - Funeral pyre - [Light, null, null, null, null] +30481 - Funeral pyre - [Light, null, null, null, null] +30482 - Funeral pyre - [Light, null, null, null, null] +30483 - Funeral pyre - [Light, null, null, null, null] +30484 - Funeral pyre - [Light, null, null, null, null] +30485 - Funeral pyre - [Light, null, null, null, null] +30486 - Funeral pyre - [Light, null, null, null, null] +30487 - Funeral pyre - [Light, null, null, null, null] +30488 - Stone stand - [null, null, null, null, null] +30489 - Ladder - [Climb-up, null, null, null, null] +30490 - Crude table - [Search, null, null, null, null] +30491 - Bunk bed - [Search, null, null, null, null] +30492 - Bunk bed - [Search, null, null, null, null] +30493 - Wooden post - [null, null, null, null, null] +30494 - Wooden post - [Climb-up, null, null, null, null] +30495 - Wooden beam - [Climb-down, null, null, null, null] +30496 - Floorboards - [null, null, null, null, Jump-to] +30497 - Floorboards - [null, null, null, null, Jump-to] +30498 - Damaged wall - [null, null, null, null, Jump-onto] +30499 - Damaged wall - [null, null, null, null, Jump-onto] +30500 - Destroyed wall - [null, null, null, null, Jump-thru] +30501 - Floorboards - [null, null, null, null, Jump-to] +30502 - Floorboards - [null, null, null, null, Jump-to] +30503 - Door - [Open, null, null, null, null] +30504 - Mass of debris - [null, null, null, null, null] +30505 - Mass of debris - [Search, null, hidden, null, Excavate] +30506 - Mass of debris - [Search, null, hidden, null, Excavate] +30507 - Mass of debris - [Search, null, hidden, null, Excavate] +30508 - Empty furnace - [null, null, null, null, null] +30509 - Coal-filled furnace - [null, null, null, null, null] +30510 - Furnace - [null, Smelt, null, null, null] +30511 - Barrel - [Search, null, null, null, null] +30512 - Barrel - [null, null, null, null, null] +30513 - Shelf - [Search, null, null, null, null] +30514 - Shelf - [null, null, null, null, null] +30515 - Tool rack - [Search, null, null, null, null] +30516 - Tool rack - [Search, null, null, null, null] +30517 - Crate - [Search, null, null, null, null] +30518 - Banner - [null, null, null, null, null] +30519 - null - [null, null, null, null, null] +30520 - Trough - [null, null, null, null, null] +30521 - Trough - [Search, null, null, null, null] +30522 - Door - [Search, null, null, null, null] +30523 - Door - [Search, null, null, null, null] +30524 - Door - [Climb-thru, null, null, null, null] +30525 - Door - [null, null, null, null, null] +30526 - Door - [Search, null, null, null, null] +30527 - Door - [Search, null, null, null, null] +30528 - Strange stones - [Search, null, null, null, null] +30529 - Strange stones - [Search, null, null, null, null] +30530 - Strange stones - [Enter, null, null, null, null] +30531 - Instructions - [Look-at, Read, null, null, null] +30532 - Wall - [null, null, null, null, null] +30533 - Stairway - [Climb-down, null, null, null, null] +30534 - Stairs - [Climb-up, null, null, null, null] +30535 - Wall storage - [Search, Open, null, null, null] +30536 - Wall storage - [Search, null, null, null, null] +30537 - Wooden recess - [Open, null, null, null, null] +30538 - Wooden recess - [Open, null, null, null, null] +30539 - Coal barrel - [Search, null, null, null, null] +30540 - Empty barrel - [null, null, null, null, null] +30541 - Boxes - [null, null, null, null, null] +30542 - Crate - [null, null, null, null, null] +30543 - Coffin - [null, null, hidden, null, null] +30544 - Coffin - [null, null, hidden, null, null] +30545 - Coffin - [null, null, null, null, null] +30546 - Coffin - [null, null, null, null, null] +30547 - Coffin - [null, null, null, null, null] +30548 - Raised coffin - [null, null, null, null, null] +30549 - Skull stonepile - [null, null, null, null, null] +30550 - Stone coffin - [null, null, null, null, null] +30551 - Stone coffin - [null, null, null, null, null] +30552 - Skull stonepile - [null, null, null, null, null] +30553 - Stone coffin - [null, null, null, null, null] +30554 - Gravestone - [null, null, null, null, null] +30555 - Jutting wall - [Squeeze-past, null, null, null, null] +30556 - Jutting wall - [Squeeze-past, null, null, null, null] +30557 - Jutting wall - [Squeeze-past, null, null, null, null] +30558 - Speartrap - [null, null, null, null, null] +30559 - Cave entrance - [Enter, null, null, null, null] +30560 - Cave entrance - [Enter, null, null, null, null] +30561 - Cave entrance - [Enter, null, null, null, null] +30562 - Blackboard - [null, null, null, null, null] +30563 - Fishing rods - [Search, null, null, null, null] +30564 - Wall chest coffin - [null, null, null, null, null] +30565 - Wall chest coffin - [null, null, null, null, null] +30566 - Corpse - [Look-at, null, null, null, Search] +30567 - Lectern - [Search, null, null, null, null] +30568 - null - [null, null, null, null, null] +30569 - Torch - [null, null, null, null, null] +30570 - Cell door - [Open, null, null, null, null] +30571 - Trapdoor - [Open, null, null, null, null] +30572 - Ladder - [Climb-down, Close, null, null, null] +30573 - Trapdoor - [Open, null, null, null, null] +30574 - Ladder - [Climb-down, null, null, null, null] +30575 - Ladder - [Climb-up, null, null, null, null] +30576 - Column - [null, null, null, null, null] +30577 - Column - [null, null, null, null, null] +30578 - Column - [null, null, null, null, null] +30579 - null - [null, null, null, null, null] +30580 - null - [null, null, null, null, null] +30581 - null - [null, null, null, null, null] +30582 - null - [null, null, null, null, null] +30583 - null - [null, null, null, null, null] +30584 - null - [null, null, null, null, null] +30585 - null - [null, null, null, null, null] +30586 - null - [null, null, null, null, null] +30587 - null - [null, null, null, null, null] +30588 - null - [null, null, null, null, null] +30589 - null - [null, null, null, null, null] +30590 - null - [null, null, null, null, null] +30591 - null - [null, null, null, null, null] +30592 - null - [null, null, null, null, null] +30593 - null - [null, null, null, null, null] +30594 - null - [null, null, null, null, null] +30595 - null - [null, null, null, null, null] +30596 - null - [null, null, null, null, null] +30597 - null - [null, null, null, null, null] +30598 - null - [null, null, null, null, null] +30599 - null - [null, null, null, null, null] +30600 - null - [null, null, null, null, null] +30601 - null - [null, null, null, null, null] +30602 - null - [null, null, null, null, null] +30603 - null - [null, null, null, null, null] +30604 - null - [null, null, null, null, null] +30605 - null - [null, null, null, null, null] +30606 - null - [null, null, null, null, null] +30607 - null - [null, null, null, null, null] +30608 - null - [null, null, null, null, null] +30609 - null - [null, null, null, null, null] +30610 - null - [null, null, null, null, null] +30611 - null - [null, null, null, null, null] +30612 - null - [null, null, null, null, null] +30613 - null - [null, null, null, null, null] +30614 - null - [null, null, null, null, null] +30615 - null - [null, null, null, null, null] +30616 - null - [null, null, null, null, null] +30617 - null - [null, null, null, null, null] +30618 - Statue - [null, null, null, null, null] +30619 - Statue - [null, null, null, null, null] +30620 - null - [null, null, null, null, null] +30621 - null - [null, null, null, null, null] +30622 - null - [null, null, null, null, null] +30623 - null - [null, null, null, null, null] +30624 - Altar - [Craft-rune, null, null, null, null] +30625 - Gravestone - [null, null, null, null, null] +30626 - Shelves - [null, null, null, null, null] +30627 - null - [null, null, null, null, null] +30628 - null - [null, null, null, null, null] +30629 - null - [null, null, null, null, null] +30630 - null - [null, null, null, null, null] +30631 - null - [null, null, null, null, null] +30632 - null - [null, null, null, null, null] +30633 - null - [null, null, null, null, null] +30634 - null - [null, null, null, null, null] +30635 - null - [null, null, null, null, null] +30636 - null - [null, null, null, null, null] +30637 - null - [null, null, null, null, null] +30638 - null - [null, null, null, null, null] +30639 - null - [null, null, null, null, null] +30640 - null - [null, null, null, null, null] +30641 - null - [null, null, null, null, null] +30642 - null - [null, null, null, null, null] +30643 - null - [null, null, null, null, null] +30644 - null - [null, null, null, null, null] +30645 - null - [null, null, null, null, null] +30646 - null - [null, null, null, null, null] +30647 - Shelves - [null, null, null, null, null] +30648 - Shelves - [null, null, null, null, null] +30649 - Shelves - [null, null, null, null, null] +30650 - Shelves - [null, null, null, null, null] +30651 - Bookcase - [null, null, null, null, null] +30652 - Crate - [null, null, null, null, null] +30653 - null - [null, null, null, null, null] +30654 - null - [null, null, null, null, null] +30655 - null - [null, null, null, null, null] +30656 - null - [null, null, null, null, null] +30657 - null - [null, null, null, null, null] +30658 - null - [null, null, null, null, null] +30659 - null - [null, null, null, null, null] +30660 - null - [null, null, null, null, null] +30661 - null - [null, null, null, null, null] +30662 - null - [null, null, null, null, null] +30663 - null - [null, null, null, null, null] +30664 - null - [null, null, null, null, null] +30665 - null - [null, null, null, null, null] +30666 - null - [null, null, null, null, null] +30667 - Gravestone - [null, null, null, null, null] +30668 - Gravestone - [null, null, null, null, null] +30669 - Gravestone - [null, null, null, null, null] +30670 - Gravestone - [null, null, null, null, null] +30671 - Gravestone - [null, null, null, null, null] +30672 - Gravestone - [null, null, null, null, null] +30673 - null - [null, null, null, null, null] +30674 - null - [null, null, null, null, null] +30675 - null - [null, null, null, null, null] +30676 - null - [null, null, null, null, null] +30677 - null - [null, null, null, null, null] +30678 - null - [null, null, null, null, null] +30679 - null - [null, null, null, null, null] +30680 - null - [null, null, null, null, null] +30681 - null - [null, null, null, null, null] +30682 - null - [null, null, null, null, null] +30683 - null - [null, null, null, null, null] +30684 - null - [null, null, null, null, null] +30685 - Statue - [null, null, null, null, null] +30686 - Bust - [null, null, null, null, null] +30687 - Bust - [null, null, null, null, null] +30688 - null - [null, null, null, null, null] +30689 - null - [null, null, null, null, null] +30690 - null - [null, null, null, null, null] +30691 - Bench - [null, null, null, null, null] +30692 - null - [null, null, null, null, null] +30693 - null - [null, null, null, null, null] +30694 - null - [null, null, null, null, null] +30695 - null - [null, null, null, null, null] +30696 - null - [null, null, null, null, null] +30697 - null - [null, null, null, null, null] +30698 - null - [null, null, null, null, null] +30699 - null - [null, null, null, null, null] +30700 - null - [null, null, null, null, null] +30701 - null - [null, null, null, null, null] +30702 - null - [null, null, null, null, null] +30703 - null - [null, null, null, null, null] +30704 - null - [null, null, null, null, null] +30705 - null - [null, null, null, null, null] +30706 - null - [null, null, null, null, null] +30707 - Large door - [Open, Knock-at, null, null, null] +30708 - Large door - [Open, Knock-at, null, null, null] +30709 - null - [null, null, null, null, null] +30710 - null - [null, null, null, null, null] +30711 - null - [null, null, null, null, null] +30712 - null - [null, null, null, null, null] +30713 - null - [null, null, null, null, null] +30714 - null - [null, null, null, null, null] +30715 - null - [null, null, null, null, null] +30716 - null - [null, null, null, null, null] +30717 - null - [null, null, null, null, null] +30718 - null - [null, null, null, null, null] +30719 - null - [null, null, null, null, null] +30720 - null - [null, null, null, null, null] +30721 - null - [null, null, null, null, null] +30722 - Staircase - [Climb-up, null, null, null, null] +30723 - Staircase top - [Climb-down, null, null, null, null] +30724 - Staircase - [Climb-up, null, null, null, null] +30725 - Staircase top - [Climb-down, null, null, null, null] +30726 - Altar - [Pray-at, null, null, null, null] +30727 - Candle - [null, null, null, null, null] +30728 - Morytania coffin - [Open, null, null, null, null] +30729 - Church pew - [null, null, null, null, null] +30730 - Broken church pew - [null, null, null, null, null] +30731 - Broken church pew - [null, null, null, null, null] +30732 - Ladder - [Climb-up, null, null, null, null] +30733 - Ladder - [Climb-down, null, null, null, null] +30734 - Table - [null, null, null, null, null] +30735 - Lantern - [null, null, null, null, null] +30736 - Chair - [null, null, null, null, null] +30737 - Broken Chair - [null, null, null, null, null] +30738 - Broken Chair - [null, null, null, null, null] +30739 - Broken Chair - [null, null, null, null, null] +30740 - Bookcase - [Search, null, null, null, null] +30741 - Bookcase - [Search, null, null, null, null] +30742 - Desk - [null, null, null, null, null] +30743 - Stand - [null, null, null, null, null] +30744 - Jail bed - [null, null, null, null, null] +30745 - null - [null, null, null, null, null] +30746 - null - [null, null, null, null, null] +30747 - null - [null, null, null, null, null] +30748 - null - [null, null, null, null, null] +30749 - null - [null, null, null, null, null] +30750 - null - [null, null, null, null, null] +30751 - Broken Table - [null, null, null, null, null] +30752 - Candles - [null, null, null, null, null] +30753 - Candles - [null, null, null, null, null] +30754 - Church organ - [Play, null, null, null, null] +30755 - null - [null, null, null, null, null] +30756 - Massive ribs - [null, null, null, null, null] +30757 - null - [null, null, null, null, null] +30758 - null - [null, null, null, null, null] +30759 - null - [null, null, null, null, null] +30760 - null - [null, null, null, null, null] +30761 - null - [null, null, null, null, null] +30762 - null - [null, null, null, null, null] +30763 - null - [null, null, null, null, null] +30764 - null - [null, null, null, null, null] +30765 - null - [null, null, null, null, null] +30766 - null - [null, null, null, null, null] +30767 - null - [null, null, null, null, null] +30768 - null - [null, null, null, null, null] +30769 - null - [null, null, null, null, null] +30770 - null - [null, null, null, null, null] +30771 - null - [null, null, null, null, null] +30772 - null - [null, null, null, null, null] +30773 - null - [null, null, null, null, null] +30774 - null - [null, null, null, null, null] +30775 - null - [null, null, null, null, null] +30776 - null - [null, null, null, null, null] +30777 - null - [null, null, null, null, null] +30778 - null - [null, null, null, null, null] +30779 - null - [null, null, null, null, null] +30780 - null - [null, null, null, null, null] +30781 - null - [null, null, null, null, null] +30782 - null - [null, null, null, null, null] +30783 - null - [null, null, null, null, null] +30784 - null - [null, null, null, null, null] +30785 - null - [null, null, null, null, null] +30786 - null - [null, null, null, null, null] +30787 - null - [null, null, null, null, null] +30788 - null - [null, null, null, null, null] +30789 - null - [null, null, null, null, null] +30790 - null - [null, null, null, null, null] +30791 - null - [null, null, null, null, null] +30792 - null - [null, null, null, null, null] +30793 - null - [null, null, null, null, null] +30794 - Torch - [null, null, null, null, null] +30795 - Tree - [null, null, null, null, null] +30796 - null - [null, null, null, null, null] +30797 - null - [null, null, null, null, null] +30798 - null - [null, null, null, null, null] +30799 - Snow - [null, null, null, null, null] +30800 - Snow - [null, null, null, null, null] +30801 - Snow - [null, null, null, null, null] +30802 - Snow - [null, null, null, null, null] +30803 - Snow - [null, null, null, null, null] +30804 - Dying roses - [Take-seed, null, null, null, null] +30805 - Growing roses - [Take-seed, null, null, null, null] +30806 - Roses - [Take-seed, null, null, null, null] +30807 - Roses - [Take-seed, null, null, null, null] +30808 - Dragon machine - [null, null, null, null, null] +30809 - Machine - [null, null, null, null, null] +30810 - Machine - [null, null, null, null, null] +30811 - Machine - [null, null, null, null, null] +30812 - Convertor - [null, null, null, null, null] +30813 - Pickaxe machine - [null, null, null, null, null] +30814 - null - [null, null, null, null, null] +30815 - null - [null, null, null, null, null] +30816 - null - [null, null, null, null, null] +30817 - Bookcase - [Search, null, null, null, null] +30818 - Bookcase - [Search, null, null, null, null] +30819 - Bench - [null, null, null, null, null] +30820 - Fountain - [null, null, null, null, null] +30821 - Font - [null, null, null, null, null] +30822 - Small table - [null, null, null, null, null] +30823 - Drawers - [Open, null, null, null, null] +30824 - Drawers - [null, Search, Shut, null, null] +30825 - Bed - [null, null, null, null, null] +30826 - Stool - [null, null, null, null, null] +30827 - Table - [null, null, null, null, null] +30828 - Table - [null, null, null, null, null] +30829 - Barrel - [null, null, null, null, null] +30830 - Table - [null, null, null, null, null] +30831 - null - [null, null, null, null, null] +30832 - null - [null, null, null, null, null] +30833 - null - [null, null, null, null, null] +30834 - null - [null, null, null, null, null] +30835 - null - [null, null, null, null, null] +30836 - null - [null, null, null, null, null] +30837 - null - [null, null, null, null, null] +30838 - null - [null, null, null, null, null] +30839 - null - [null, null, null, null, null] +30840 - null - [null, null, null, null, null] +30841 - null - [null, null, null, null, null] +30842 - null - [null, null, null, null, null] +30843 - null - [null, null, null, null, null] +30844 - null - [null, null, null, null, null] +30845 - null - [null, null, null, null, null] +30846 - null - [null, null, null, null, null] +30847 - null - [null, null, null, null, null] +30848 - null - [null, null, null, null, null] +30849 - null - [null, null, null, null, null] +30850 - null - [null, null, null, null, null] +30851 - null - [null, null, null, null, null] +30852 - null - [null, null, null, null, null] +30853 - null - [null, null, null, null, null] +30854 - null - [null, null, null, null, null] +30855 - null - [null, null, null, null, null] +30856 - null - [null, null, null, null, null] +30857 - null - [null, null, null, null, null] +30858 - null - [null, null, null, null, null] +30859 - null - [null, null, null, null, null] +30860 - null - [null, null, null, null, null] +30861 - null - [null, null, null, null, null] +30862 - null - [null, null, null, null, null] +30863 - Ladder - [Climb-down, null, null, null, null] +30864 - Door - [Open, null, null, null, null] +30865 - Door - [Close, null, null, null, null] +30866 - Workbench - [null, null, null, null, null] +30867 - null - [null, null, null, null, null] +30868 - Crevice - [Squeeze-through, null, null, null, null] +30869 - null - [null, null, null, null, null] +30870 - null - [null, null, null, null, null] +30871 - null - [null, null, null, null, null] +30872 - null - [null, null, null, null, null] +30873 - null - [null, null, null, null, null] +30874 - null - [null, null, null, null, null] +30875 - null - [null, null, null, null, null] +30876 - Rockslide - [null, null, null, null, null] +30877 - Rockslide - [null, null, null, null, null] +30878 - Rockslide - [null, null, null, null, null] +30879 - null - [null, null, null, null, null] +30880 - null - [null, null, null, null, null] +30881 - null - [null, null, null, null, null] +30882 - null - [null, null, null, null, null] +30883 - null - [null, null, null, null, null] +30884 - null - [null, null, null, null, null] +30885 - null - [null, null, null, null, null] +30886 - null - [null, null, null, null, null] +30887 - null - [null, null, null, null, null] +30888 - null - [null, null, null, null, null] +30889 - null - [null, null, null, null, null] +30890 - null - [null, null, null, null, null] +30891 - null - [null, null, null, null, null] +30892 - null - [null, null, null, null, null] +30893 - null - [null, null, null, null, null] +30894 - null - [null, null, null, null, null] +30895 - null - [null, null, null, null, null] +30896 - null - [null, null, null, null, null] +30897 - null - [null, null, null, null, null] +30898 - null - [null, null, null, null, null] +30899 - null - [null, null, null, null, null] +30900 - null - [null, null, null, null, null] +30901 - null - [null, null, null, null, null] +30902 - null - [null, null, null, null, null] +30903 - null - [null, null, null, null, null] +30904 - null - [null, null, null, null, null] +30905 - null - [null, null, null, null, null] +30906 - null - [null, null, null, null, null] +30907 - null - [null, null, null, null, null] +30908 - null - [null, null, null, null, null] +30909 - null - [null, null, null, null, null] +30910 - null - [null, null, null, null, null] +30911 - null - [null, null, null, null, null] +30912 - null - [null, null, null, null, null] +30913 - null - [null, null, null, null, null] +30914 - null - [null, null, null, null, null] +30915 - null - [null, null, null, null, null] +30916 - null - [null, null, null, null, null] +30917 - null - [null, null, null, null, null] +30918 - null - [null, null, null, null, null] +30919 - Stalagmite - [null, null, null, null, null] +30920 - null - [null, null, null, null, null] +30921 - null - [null, null, null, null, null] +30922 - null - [null, null, null, null, null] +30923 - Counter - [null, null, null, null, null] +30924 - Crates - [Search, null, null, null, null] +30925 - Crate - [Search, null, null, null, null] +30926 - Barrel - [null, null, null, null, null] +30927 - Chest - [Search, null, Close, null, null] +30928 - Chest - [Open, null, null, null, null] +30929 - Stool - [null, null, null, null, null] +30930 - null - [null, null, null, null, null] +30931 - null - [null, null, null, null, null] +30932 - null - [null, null, null, null, null] +30933 - Torch - [null, null, null, null, null] +30934 - Flames - [null, null, null, null, null] +30935 - null - [null, null, null, null, null] +30936 - null - [null, null, null, null, null] +30937 - null - [null, null, null, null, null] +30938 - Sacks - [Search, null, null, null, null] +30939 - Table - [null, null, null, null, null] +30940 - null - [null, null, null, null, null] +30941 - Ladder - [Climb-up, null, null, null, null] +30942 - Ladder - [Climb-down, null, null, null, null] +30943 - Stairs - [Climb-up, null, null, null, null] +30944 - Stairs - [Climb-down, null, null, null, null] +30945 - A shabby tent - [null, null, null, null, null] +30946 - null - [null, null, null, null, null] +30947 - null - [null, null, null, null, null] +30948 - null - [null, null, null, null, null] +30949 - null - [null, null, null, null, null] +30950 - null - [null, null, null, null, null] +30951 - null - [null, null, null, null, null] +30952 - null - [null, null, null, null, null] +30953 - null - [null, null, null, null, null] +30954 - null - [null, null, null, null, null] +30955 - null - [null, null, null, null, null] +30956 - null - [null, null, null, null, null] +30957 - null - [null, null, null, null, null] +30958 - null - [null, null, null, null, null] +30959 - null - [null, null, null, null, null] +30960 - null - [null, null, null, null, null] +30961 - Machine - [null, null, null, null, null] +30962 - Chest - [null, null, null, null, null] +30963 - Chest - [Open, null, null, null, null] +30964 - Machine - [null, null, null, null, null] +30965 - null - [null, null, null, null, null] +30966 - null - [null, null, null, null, null] +30967 - null - [null, null, null, null, null] +30968 - null - [null, null, null, null, null] +30969 - null - [null, null, null, null, null] +30970 - null - [null, null, null, null, null] +30971 - null - [null, null, null, null, null] +30972 - null - [null, null, null, null, null] +30973 - null - [null, null, null, null, null] +30974 - null - [null, null, null, null, null] +30975 - null - [null, null, null, null, null] +30976 - null - [null, null, null, null, null] +30977 - null - [null, null, null, null, null] +30978 - null - [null, null, null, null, null] +30979 - null - [null, null, null, null, null] +30980 - null - [null, null, null, null, null] +30981 - null - [null, null, null, null, null] +30982 - null - [null, null, null, null, null] +30983 - null - [null, null, null, null, null] +30984 - null - [null, null, null, null, null] +30985 - null - [null, null, null, null, null] +30986 - null - [null, null, null, null, null] +30987 - null - [null, null, null, null, null] +30988 - null - [null, null, null, null, null] +30989 - null - [null, null, null, null, null] +30990 - null - [null, null, null, null, null] +30991 - null - [null, null, null, null, null] +30992 - null - [null, null, null, null, null] +30993 - null - [null, null, null, null, null] +30994 - null - [null, null, null, null, null] +30995 - null - [null, null, null, null, null] +30996 - null - [null, null, null, null, null] +30997 - Dragon eggs - [null, null, null, null, null] +30998 - Rocks - [null, null, null, null, null] +30999 - null - [null, null, null, null, null] +31000 - Bush - [null, null, null, null, null] +31001 - Ladder - [Climb-down, null, null, null, null] +31002 - Ladder - [Climb-up, null, null, null, null] +31003 - Ladder - [Climb-up, null, null, null, null] +31004 - null - [null, null, null, null, null] +31005 - Nesting bird - [null, null, null, null, null] +31006 - Nesting bird - [null, null, null, null, null] +31007 - Nesting bird - [null, null, null, null, null] +31008 - null - [null, null, null, null, null] +31009 - null - [null, null, null, null, null] +31010 - Trapdoor - [Climb-down, null, null, null, null] +31011 - Trapdoor - [Open, null, null, null, null] +31012 - null - [null, null, null, null, null] +31013 - Crate - [Search, null, null, null, null] +31014 - Wrecked tent - [Take, null, null, null, null] +31015 - Remains - [null, null, null, null, null] +31016 - Tent - [null, null, null, null, null] +31017 - Tent - [null, null, null, null, null] +31018 - Bush - [Search, null, null, null, null] +31019 - Bush - [Search, null, null, null, null] +31020 - Bush - [Search, null, null, null, null] +31021 - Bush - [Search, null, null, null, null] +31022 - Bush - [Search, null, null, null, null] +31023 - Bush - [Search, null, null, null, null] +31024 - Bush - [Search, null, null, null, null] +31025 - Bush - [Search, null, null, null, null] +31026 - Cart - [null, null, null, null, null] +31027 - Rocks - [null, null, null, null, null] +31028 - null - [null, null, null, null, null] +31029 - Parachuting gnome - [null, null, null, null, null] +31030 - Door - [null, null, null, null, null] +31031 - null - [null, null, null, null, null] +31032 - null - [null, null, null, null, null] +31033 - null - [null, null, null, null, null] +31034 - null - [null, null, null, null, null] +31035 - null - [null, null, null, null, null] +31036 - null - [null, null, null, null, null] +31037 - null - [null, null, null, null, null] +31038 - null - [null, null, null, null, null] +31039 - null - [null, null, null, null, null] +31040 - null - [null, null, null, null, null] +31041 - null - [null, null, null, null, null] +31042 - null - [null, null, null, null, null] +31043 - null - [null, null, null, null, null] +31044 - null - [null, null, null, null, null] +31045 - null - [null, null, null, null, null] +31046 - null - [null, null, null, null, null] +31047 - null - [null, null, null, null, null] +31048 - null - [null, null, null, null, null] +31049 - null - [null, null, null, null, null] +31050 - null - [null, null, null, null, null] +31051 - null - [null, null, null, null, null] +31052 - null - [null, null, null, null, null] +31053 - null - [null, null, null, null, null] +31054 - null - [null, null, null, null, null] +31055 - null - [null, null, null, null, null] +31056 - null - [null, null, null, null, null] +31057 - Tree stump - [null, null, null, null, null] +31058 - null - [null, null, null, null, null] +31059 - Rocks - [Mine, Prospect, hidden, null, null] +31060 - Rocks - [Mine, Prospect, hidden, null, null] +31061 - Rocks - [Mine, Prospect, hidden, null, null] +31062 - Rocks - [Mine, Prospect, hidden, null, null] +31063 - Rocks - [Mine, Prospect, hidden, null, null] +31064 - Rocks - [Mine, Prospect, hidden, null, null] +31065 - Rocks - [Mine, Prospect, hidden, null, null] +31066 - Rocks - [Mine, Prospect, hidden, null, null] +31067 - Rocks - [Mine, Prospect, hidden, null, null] +31068 - Rocks - [Mine, Prospect, hidden, null, null] +31069 - Rocks - [Mine, Prospect, hidden, null, null] +31070 - Rocks - [Mine, Prospect, hidden, null, null] +31071 - Rocks - [Mine, Prospect, hidden, null, null] +31072 - Rocks - [Mine, Prospect, hidden, null, null] +31073 - Rocks - [Mine, Prospect, hidden, null, null] +31074 - Rocks - [Mine, Prospect, hidden, null, null] +31075 - Rocks - [Mine, Prospect, hidden, null, null] +31076 - Rocks - [Mine, Prospect, hidden, null, null] +31077 - Rocks - [Mine, Prospect, hidden, null, null] +31078 - Rocks - [Mine, Prospect, hidden, null, null] +31079 - Rocks - [Mine, Prospect, hidden, null, null] +31080 - Rocks - [Mine, Prospect, hidden, null, null] +31081 - Rocks - [Mine, Prospect, hidden, null, null] +31082 - Rocks - [Mine, Prospect, hidden, null, null] +31083 - Rocks - [Mine, Prospect, hidden, null, null] +31084 - Rocks - [Mine, Prospect, hidden, null, null] +31085 - Rocks - [Mine, Prospect, hidden, null, null] +31086 - Rocks - [Mine, Prospect, hidden, null, null] +31087 - Rocks - [Mine, Prospect, hidden, null, null] +31088 - Rocks - [Mine, Prospect, hidden, null, null] +31089 - null - [null, null, null, null, null] +31090 - null - [null, null, null, null, null] +31091 - null - [null, null, null, null, null] +31092 - null - [null, null, null, null, null] +31093 - null - [null, null, null, null, null] +31094 - Rocks - [Mine, Prospect, hidden, null, null] +31095 - Rocks - [Mine, Prospect, hidden, null, null] +31096 - Rocks - [Mine, Prospect, hidden, null, null] +31097 - Rocks - [Mine, Prospect, hidden, null, null] +31098 - Rocks - [Mine, Prospect, hidden, null, null] +31099 - Rocks - [Mine, Prospect, hidden, null, null] +31100 - Rocks - [Mine, Prospect, hidden, null, null] +31101 - Rocks - [Mine, Prospect, hidden, null, null] +31102 - Rocks - [Mine, Prospect, hidden, null, null] +31103 - Rocks - [Mine, Prospect, hidden, null, null] +31104 - Rocks - [Mine, Prospect, hidden, null, null] +31105 - Rocks - [Mine, Prospect, hidden, null, null] +31106 - Rocks - [Mine, Prospect, hidden, null, null] +31107 - Rocks - [Mine, Prospect, hidden, null, null] +31108 - Rocks - [Mine, Prospect, hidden, null, null] +31109 - Rocks - [Mine, Prospect, hidden, null, null] +31110 - Rocks - [Mine, Prospect, hidden, null, null] +31111 - Rocks - [Mine, Prospect, hidden, null, null] +31112 - Rocks - [Mine, Prospect, hidden, null, null] +31113 - Rocks - [Mine, Prospect, hidden, null, null] +31114 - Rocks - [Mine, Prospect, hidden, null, null] +31115 - Rocks - [Mine, Prospect, hidden, null, null] +31116 - Rocks - [Mine, Prospect, hidden, null, null] +31117 - Rocks - [Mine, Prospect, hidden, null, null] +31118 - Rocks - [Mine, Prospect, hidden, null, null] +31119 - null - [null, null, null, null, null] +31120 - null - [null, null, null, null, null] +31121 - null - [null, null, null, null, null] +31122 - null - [null, null, null, null, null] +31123 - null - [null, null, null, null, null] +31124 - null - [null, null, null, null, null] +31125 - null - [null, null, null, null, null] +31126 - null - [null, null, null, null, null] +31127 - null - [null, null, null, null, null] +31128 - null - [null, null, null, null, null] +31129 - null - [null, null, null, null, null] +31130 - null - [null, null, null, null, null] +31131 - null - [null, null, null, null, null] +31132 - null - [null, null, null, null, null] +31133 - null - [null, null, null, null, null] +31134 - null - [null, null, null, null, null] +31135 - null - [null, null, null, null, null] +31136 - Barrel - [null, null, null, null, null] +31137 - Crate - [Search, null, null, null, null] +31138 - Crate - [Search, null, null, null, null] +31139 - Crate - [Search, null, null, null, null] +31140 - Crate - [Search, null, null, null, null] +31141 - null - [null, null, null, null, null] +31142 - null - [null, null, null, null, null] +31143 - null - [null, null, null, null, null] +31144 - null - [null, null, null, null, null] +31145 - null - [null, null, null, null, null] +31146 - null - [null, null, null, null, null] +31147 - null - [null, null, null, null, null] +31148 - null - [null, null, null, null, null] +31149 - Fence - [Squeeze-under, null, null, null, null] +31150 - null - [null, null, null, null, null] +31151 - null - [null, null, null, null, null] +31152 - Large gate - [null, null, null, null, null] +31153 - null - [null, null, null, null, null] +31154 - null - [null, null, null, null, null] +31155 - Doogle bush - [Pick-leaf, null, null, null, null] +31156 - null - [null, null, null, null, null] +31157 - null - [null, null, null, null, null] +31158 - null - [null, null, null, null, null] +31159 - null - [null, null, null, null, null] +31160 - null - [null, null, null, null, null] +31161 - null - [null, null, null, null, null] +31162 - Some logs - [null, null, null, hidden, null] +31163 - null - [null, null, null, null, null] +31164 - null - [null, null, null, null, null] +31165 - null - [null, null, null, null, null] +31166 - null - [null, null, null, null, null] +31167 - Rocks - [Mine, Prospect, hidden, null, null] +31168 - Rocks - [Mine, Prospect, hidden, null, null] +31169 - Rocks - [Mine, Prospect, hidden, null, null] +31170 - Rocks - [Mine, Prospect, hidden, null, null] +31171 - Rocks - [Mine, Prospect, hidden, null, null] +31172 - Rocks - [Mine, Prospect, hidden, null, null] +31173 - Rocks - [Mine, Prospect, hidden, null, null] +31174 - Rocks - [Mine, Prospect, hidden, null, null] +31175 - Rocks - [Mine, Prospect, hidden, null, null] +31176 - null - [null, null, null, null, null] +31177 - null - [null, null, null, null, null] +31178 - null - [null, null, null, null, null] +31179 - null - [null, null, null, null, null] +31180 - null - [null, null, null, null, null] +31181 - null - [null, null, null, null, null] +31182 - null - [null, null, null, null, null] +31183 - null - [null, null, null, null, null] +31184 - null - [null, null, null, null, null] +31185 - null - [null, null, null, null, null] +31186 - null - [null, null, null, null, null] +31187 - null - [null, null, null, null, null] +31188 - null - [null, null, null, null, null] +31189 - null - [null, null, null, null, null] +31190 - null - [null, null, null, null, null] +31191 - null - [null, null, null, null, null] +31192 - null - [null, null, null, null, null] +31193 - null - [null, null, null, null, null] +31194 - null - [null, null, null, null, null] +31195 - null - [null, null, null, null, null] +31196 - null - [null, null, null, null, null] +31197 - Rocks - [Mine, Prospect, hidden, null, null] +31198 - Rocks - [Mine, Prospect, hidden, null, null] +31199 - Rocks - [Mine, Prospect, hidden, null, null] +31200 - Rocks - [Mine, Prospect, hidden, null, null] +31201 - Rocks - [Mine, Prospect, hidden, null, null] +31202 - Rocks - [Mine, Prospect, hidden, null, null] +31203 - Rocks - [Mine, Prospect, hidden, null, null] +31204 - Rocks - [Mine, Prospect, hidden, null, null] +31205 - Rocks - [Mine, Prospect, hidden, null, null] +31206 - Tunnel - [Go-through, null, null, null, null] +31207 - Bookcase - [Search, null, null, null, null] +31208 - Tunnel Entrance - [null, null, null, null, null] +31209 - Tunnel Entrance - [null, null, null, null, null] +31210 - Tunnel Entrance - [null, null, null, null, null] +31211 - Tunnel Entrance - [null, null, null, null, null] +31212 - Tunnel Entrance - [null, null, null, null, null] +31213 - Tunnel Entrance - [null, null, null, null, null] +31214 - Stepping stone - [Jump-over, null, null, null, null] +31215 - Stepping stone - [Jump-over, null, null, null, null] +31216 - Stepping stone - [Jump-over, null, null, null, null] +31217 - Stepping stone - [null, null, null, null, null] +31218 - Stepping stone - [null, null, null, null, null] +31219 - Stepping stone - [null, null, null, null, null] +31220 - Stepping stone - [null, null, null, null, null] +31221 - Tunnel entrance - [Go-through-wall, null, null, null, null] +31222 - null - [null, null, null, null, null] +31223 - null - [null, null, null, null, null] +31224 - null - [null, null, null, null, null] +31225 - null - [null, null, null, null, null] +31226 - null - [null, null, null, null, null] +31227 - null - [null, null, null, null, null] +31228 - null - [null, null, null, null, null] +31229 - Obsidian wall - [Mine, Prospect, hidden, null, null] +31230 - Obsidian wall - [Mine, Prospect, hidden, null, null] +31231 - Crack in wall - [null, null, null, null, null] +31232 - Crack in wall - [Go-through, null, null, null, null] +31233 - null - [null, null, null, null, null] +31234 - null - [null, null, null, null, null] +31235 - null - [null, null, null, null, null] +31236 - null - [null, null, null, null, null] +31237 - null - [null, null, null, null, null] +31238 - Collapsed tunnel - [Mine-through, null, null, null, null] +31239 - Collapsed tunnel - [Mine-through, null, null, null, null] +31240 - Collapsed tunnel - [Mine-through, null, null, null, null] +31241 - Caved-in wall - [null, null, null, null, null] +31242 - Repaired caved-in wall - [null, null, null, null, null] +31243 - Caved-in wall - [null, null, null, null, null] +31244 - Repaired caved in wall - [null, null, null, null, null] +31245 - Caved-in wall - [null, null, null, null, null] +31246 - null - [null, null, null, null, null] +31247 - null - [null, null, null, null, null] +31248 - Stone pillar - [Push-over, null, null, null, null] +31249 - Stone pillar - [null, null, null, null, null] +31250 - Pillar - [null, null, null, null, null] +31251 - Cave-in - [Jump-over, null, null, null, null] +31252 - Cave-in - [null, null, null, null, null] +31253 - Cave-in - [Jump-over, null, null, null, null] +31254 - Cave-in - [Jump-over, null, null, null, null] +31255 - Rock - [Push, null, null, null, null] +31256 - Rock - [null, null, null, null, null] +31257 - Rock - [null, null, null, null, null] +31258 - Cave entrance - [Mine-through, null, null, null, null] +31259 - Bookcase - [Search, null, null, null, null] +31260 - Bookcase - [Search, null, null, null, null] +31261 - Bookcase - [Search, null, null, null, null] +31262 - Bookcase - [Search, null, null, null, null] +31263 - Bookcase - [Search, null, null, null, null] +31264 - Bookcase - [Search, null, null, null, null] +31265 - null - [null, null, null, null, null] +31266 - null - [null, null, null, null, null] +31267 - null - [null, null, null, null, null] +31268 - null - [null, null, null, null, null] +31269 - null - [null, null, null, null, null] +31270 - Bench - [null, null, null, null, null] +31271 - Bench - [null, null, null, null, null] +31272 - Rock prop - [null, null, null, null, null] +31273 - Rock prop - [null, null, null, null, null] +31274 - Rock prop - [null, null, null, null, null] +31275 - Rock prop - [null, null, null, null, null] +31276 - null - [null, null, null, null, null] +31277 - null - [null, null, null, null, null] +31278 - null - [null, null, null, null, null] +31279 - null - [null, null, null, null, null] +31280 - null - [null, null, null, null, null] +31281 - null - [null, null, null, null, null] +31282 - null - [null, null, null, null, null] +31283 - null - [null, null, null, null, null] +31284 - Cave entrance - [Enter, null, null, null, null] +31285 - null - [null, null, null, null, null] +31286 - Cave entrance - [null, null, null, null, null] +31287 - Tunnel - [Go-through, null, null, null, null] +31288 - Tunnel - [Go-through, null, null, null, null] +31289 - Tunnel - [Go-through, null, null, null, null] +31290 - Tunnel - [Go-through, null, null, null, null] +31291 - Tunnel - [Go-through, null, null, null, null] +31292 - Cave entrance - [Go-through, null, null, null, null] +31293 - null - [null, null, null, null, null] +31294 - Wooden doors - [Open, null, null, null, null] +31295 - Wooden doors - [null, null, null, null, null] +31296 - Signpost - [Read, null, null, null, null] +31297 - Signpost - [Read, null, null, null, null] +31298 - Signpost - [Read, null, null, null, null] +31299 - Signpost - [Read, null, null, null, null] +31300 - Signpost - [Read, null, null, null, null] +31301 - Signpost - [Read, null, null, null, null] +31302 - Juna - [Talk-to, null, null, null, null] +31303 - Juna - [Talk-to, null, Tell-story, null, null] +31304 - null - [null, null, null, null, null] +31305 - Broken door - [null, null, null, null, null] +31306 - Sticks - [Pass, null, null, null, null] +31307 - Sticks - [Pass, null, null, null, null] +31308 - Sticks - [Pass, null, null, null, null] +31309 - Sarcophagus - [null, null, null, null, null] +31310 - Mummy - [null, null, null, null, null] +31311 - null - [null, null, null, null, null] +31312 - Skeleton - [null, null, null, null, null] +31313 - Skeleton - [null, null, null, null, null] +31314 - Wavering mystic barrier - [Pass, null, null, null, null] +31315 - Wavering mystic barrier - [null, null, null, null, null] +31316 - Bucket rope - [Climb-up, null, null, null, null] +31317 - Flames - [null, null, null, null, null] +31318 - Ashy Pedestal - [null, null, null, null, null] +31319 - Exit - [Leave through, null, null, null, null] +31320 - null - [null, null, null, null, null] +31321 - null - [null, null, null, null, null] +31322 - null - [null, null, null, null, null] +31323 - Tomb - [Search, null, null, null, null] +31324 - Tomb - [Search, null, null, null, null] +31325 - Tomb - [Search, null, null, null, null] +31326 - Tomb - [Search, null, null, null, null] +31327 - null - [Search, null, null, null, null] +31328 - Wall - [Search, null, null, null, null] +31329 - null - [null, null, null, null, null] +31330 - Solid wall - [null, null, null, null, null] +31331 - A holey wall - [Search, null, null, null, null] +31332 - A holey wall - [Search, null, null, null, null] +31333 - Broken door - [null, null, null, null, null] +31334 - Broken door - [Destroy, null, null, null, null] +31335 - Broken door - [Destroy, null, null, null, null] +31336 - Broken door - [Destroy, null, null, null, null] +31337 - Broken door - [Destroy, null, null, null, null] +31338 - Broken door - [Destroy, null, null, null, null] +31339 - Broken door - [Destroy, null, null, null, null] +31340 - Door - [Open, null, null, null, null] +31341 - Door - [Close, null, null, null, null] +31342 - Door - [Open, null, null, null, null] +31343 - Door - [Close, null, null, null, null] +31344 - null - [null, null, null, null, null] +31345 - null - [null, null, null, null, null] +31346 - null - [null, null, null, null, null] +31347 - null - [null, null, null, null, null] +31348 - Sarcophagus - [null, null, null, null, null] +31349 - Sarcophagus - [null, null, null, null, null] +31350 - Floor - [Search, null, null, null, null] +31351 - Odd markings - [Search, null, null, null, null] +31352 - null - [null, null, null, null, null] +31353 - null - [null, null, null, null, null] +31354 - null - [null, null, null, null, null] +31355 - null - [null, null, null, null, null] +31356 - null - [null, null, null, null, null] +31357 - Lever - [Pull, null, null, null, null] +31358 - Lever - [Pull, null, null, null, null] +31359 - Well - [Climb-down, null, null, null, null] +31360 - null - [null, null, null, null, null] +31361 - Open tome - [null, null, null, null, null] +31362 - Ashy pedestal - [null, null, null, null, null] +31363 - Pulsing markings - [Enter, null, null, null, null] +31364 - Dull markings - [null, null, null, null, null] +31365 - null - [null, null, null, null, null] +31366 - null - [null, null, null, null, null] +31367 - A dark hole - [Enter, null, null, null, null] +31368 - null - [null, null, null, null, null] +31369 - Mystic barrier - [null, null, null, null, null] +31370 - Mystic barrier - [null, null, null, null, null] +31371 - Intact sarcophagus - [null, null, null, null, null] +31372 - Damaged sarcophagus - [null, null, null, null, null] +31373 - Empty sarcophagus - [null, null, null, null, null] +31374 - null - [null, null, null, null, null] +31375 - null - [null, null, null, null, null] +31376 - null - [null, null, null, null, null] +31377 - Pile of skulls - [null, null, null, null, null] +31378 - null - [null, null, null, null, null] +31379 - null - [null, null, null, null, null] +31380 - null - [null, null, null, null, null] +31381 - null - [null, null, null, null, null] +31382 - null - [null, null, null, null, null] +31383 - null - [null, null, null, null, null] +31384 - null - [null, null, null, null, null] +31385 - null - [null, null, null, null, null] +31386 - null - [null, null, null, null, null] +31387 - null - [null, null, null, null, null] +31388 - null - [null, null, null, null, null] +31389 - null - [null, null, null, null, null] +31390 - Dark stairs - [Enter, null, null, null, null] +31391 - null - [null, null, null, null, null] +31392 - null - [null, null, null, null, null] +31393 - null - [null, null, null, null, null] +31394 - null - [null, null, null, null, null] +31395 - null - [null, null, null, null, null] +31396 - null - [null, null, null, null, null] +31397 - null - [null, null, null, null, null] +31398 - null - [null, null, null, null, null] +31399 - null - [null, null, null, null, null] +31400 - null - [null, null, null, null, null] +31401 - null - [null, null, null, null, null] +31402 - null - [null, null, null, null, null] +31403 - null - [null, null, null, null, null] +31404 - null - [null, null, null, null, null] +31405 - null - [null, null, null, null, null] +31406 - null - [null, null, null, null, null] +31407 - null - [null, null, null, null, null] +31408 - null - [null, null, null, null, null] +31409 - null - [null, null, null, null, null] +31410 - null - [null, null, null, null, null] +31411 - null - [null, null, null, null, null] +31412 - Stairs - [Climb-down, null, null, null, null] +31413 - null - [null, null, null, null, null] +31414 - null - [null, null, null, null, null] +31415 - null - [null, null, null, null, null] +31416 - null - [null, null, null, null, null] +31417 - Stairs - [Climb-up, null, null, null, null] +31418 - null - [null, null, null, null, null] +31419 - null - [null, null, null, null, null] +31420 - null - [null, null, null, null, null] +31421 - Subterranean spring - [null, null, null, null, null] +31422 - Machinery - [null, null, null, null, null] +31423 - Machinery - [null, null, null, null, null] +31424 - Incomprehensible machinery - [null, null, null, null, null] +31425 - Rock mound - [null, null, null, null, null] +31426 - Rock mound - [null, null, null, null, null] +31427 - Spiky pillar - [null, null, null, null, null] +31428 - Smashed pillar - [null, null, null, null, null] +31429 - Crystalline structure - [null, null, null, null, null] +31430 - null - [null, null, null, null, null] +31431 - null - [null, null, null, null, null] +31432 - null - [null, null, null, null, null] +31433 - null - [null, null, null, null, null] +31434 - null - [null, null, null, null, null] +31435 - Mystic barrier - [Pass, null, null, null, null] +31436 - Mystic barrier - [Pass, null, null, null, null] +31437 - Kurask head - [null, null, null, null, null] +31438 - null - [null, null, null, null, null] +31439 - null - [null, null, null, null, null] +31440 - null - [null, null, null, null, null] +31441 - null - [null, null, null, null, null] +31442 - null - [null, null, null, null, null] +31443 - null - [null, null, null, null, null] +31444 - null - [null, null, null, null, null] +31445 - null - [null, null, null, null, null] +31446 - null - [null, null, null, null, null] +31447 - Flowerbed - [null, null, null, null, null] +31448 - Soil - [null, null, null, null, null] +31449 - null - [null, null, null, null, null] +31450 - null - [null, null, null, null, null] +31451 - null - [null, null, null, null, null] +31452 - Bed - [Search, null, null, null, null] +31453 - null - [null, null, null, null, null] +31454 - Door - [Open, null, null, null, null] +31455 - Door - [Open, null, null, null, null] +31456 - Pipes - [Listen, Tap, null, null, null] +31457 - Pipes - [Jiggle, null, null, null, null] +31458 - Dead guy - [null, null, null, null, null] +31459 - Customs Sergeant - [Talk-to, null, null, null, null] +31460 - Locker - [Store, null, null, null, null] +31461 - null - [null, null, null, null, null] +31462 - null - [null, null, null, null, null] +31463 - null - [null, null, null, null, null] +31464 - null - [null, null, null, null, null] +31465 - null - [null, null, null, null, null] +31466 - null - [null, null, null, null, null] +31467 - null - [null, null, null, null, null] +31468 - null - [null, null, null, null, null] +31469 - null - [null, null, null, null, null] +31470 - null - [null, null, null, null, null] +31471 - null - [null, null, null, null, null] +31472 - null - [null, null, null, null, null] +31473 - null - [null, null, null, null, null] +31474 - null - [null, null, null, null, null] +31475 - null - [null, null, null, null, null] +31476 - null - [null, null, null, null, null] +31477 - null - [null, null, null, null, null] +31478 - null - [null, null, null, null, null] +31479 - null - [null, null, null, null, null] +31480 - null - [null, null, null, null, null] +31481 - null - [null, null, null, null, null] +31482 - null - [null, null, null, null, null] +31483 - null - [null, null, null, null, null] +31484 - null - [null, null, null, null, null] +31485 - null - [null, null, null, null, null] +31486 - null - [null, null, null, null, null] +31487 - null - [null, null, null, null, null] +31488 - null - [null, null, null, null, null] +31489 - null - [null, null, null, null, null] +31490 - null - [null, null, null, null, null] +31491 - null - [null, null, null, null, null] +31492 - null - [null, null, null, null, null] +31493 - null - [null, null, null, null, null] +31494 - null - [null, null, null, null, null] +31495 - Barred window - [Shout-through, null, null, null, null] +31496 - Cell door - [null, null, null, null, null] +31497 - null - [null, null, null, null, null] +31498 - null - [null, null, null, null, null] +31499 - null - [null, null, null, null, null] +31500 - null - [null, null, null, null, null] +31501 - null - [null, null, null, null, null] +31502 - null - [null, null, null, null, null] +31503 - null - [null, null, null, null, null] +31504 - null - [null, null, null, null, null] +31505 - null - [null, null, null, null, null] +31506 - null - [null, null, null, null, null] +31507 - null - [null, null, null, null, null] +31508 - null - [null, null, null, null, null] +31509 - null - [null, null, null, null, null] +31510 - null - [null, null, null, null, null] +31511 - null - [null, null, null, null, null] +31512 - null - [null, null, null, null, null] +31513 - null - [null, null, null, null, null] +31514 - null - [null, null, null, null, null] +31515 - null - [null, null, null, null, null] +31516 - null - [null, null, null, null, null] +31517 - null - [null, null, null, null, null] +31518 - null - [null, null, null, null, null] +31519 - null - [null, null, null, null, null] +31520 - null - [null, null, null, null, null] +31521 - null - [null, null, null, null, null] +31522 - null - [null, null, null, null, null] +31523 - null - [null, null, null, null, null] +31524 - null - [null, null, null, null, null] +31525 - null - [null, null, null, null, null] +31526 - null - [null, null, null, null, null] +31527 - null - [null, null, null, null, null] +31528 - Desk - [null, null, null, null, null] +31529 - Stairs - [Climb, null, null, null, null] +31530 - Stairs - [Climb, null, null, null, null] +31531 - null - [null, null, null, null, null] +31532 - null - [null, null, null, null, null] +31533 - Door - [null, null, null, null, null] +31534 - Door - [Shout-through, Open, null, null, null] +31535 - Door - [Close, null, null, null, null] +31536 - Pipes - [null, null, null, null, null] +31537 - Pipes - [null, null, null, null, null] +31538 - Pipes - [null, null, null, null, null] +31539 - Door - [Open, null, null, null, null] +31540 - Door - [Close, null, null, null, null] +31541 - Sharp rock - [null, null, null, null, null] +31542 - Cabinet - [Open, null, null, null, null] +31543 - Cabinet - [Open, null, null, null, null] +31544 - Rubble - [null, null, null, null, null] +31545 - Rubble - [null, null, null, null, null] +31546 - Rubble - [Search, null, null, null, null] +31547 - Rubble - [null, null, null, null, null] +31548 - Bed - [null, null, null, null, null] +31549 - null - [null, null, null, null, null] +31550 - Bed - [null, null, null, null, null] +31551 - Bed - [null, null, null, null, null] +31552 - Desk - [null, null, null, null, null] +31553 - Bookcase - [null, null, null, null, null] +31554 - Locker - [null, null, null, null, null] +31555 - null - [null, null, null, null, null] +31556 - null - [null, null, null, null, null] +31557 - Perch rock - [null, null, null, null, null] +31558 - Perch rock - [null, null, null, null, null] +31559 - Perch rock - [null, null, null, null, null] +31560 - Perch rock - [null, null, null, null, null] +31561 - Perch rock - [null, null, null, null, null] +31562 - Anchor - [Climb, null, null, null, null] +31563 - Anchor - [Climb, null, null, null, null] +31564 - Anchor - [Climb, null, null, null, null] +31565 - null - [null, null, null, null, null] +31566 - null - [null, null, null, null, null] +31567 - null - [null, null, null, null, null] +31568 - null - [null, null, null, null, null] +31569 - null - [null, null, null, null, null] +31570 - null - [null, null, null, null, null] +31571 - null - [null, null, null, null, null] +31572 - null - [null, null, null, null, null] +31573 - null - [null, null, null, null, null] +31574 - null - [null, null, null, null, null] +31575 - null - [null, null, null, null, null] +31576 - null - [null, null, null, null, null] +31577 - null - [null, null, null, null, null] +31578 - null - [null, null, null, null, null] +31579 - null - [null, null, null, null, null] +31580 - null - [null, null, null, null, null] +31581 - null - [null, null, null, null, null] +31582 - null - [null, null, null, null, null] +31583 - null - [null, null, null, null, null] +31584 - null - [null, null, null, null, null] +31585 - null - [null, null, null, null, null] +31586 - null - [null, null, null, null, null] +31587 - null - [null, null, null, null, null] +31588 - null - [null, null, null, null, null] +31589 - null - [null, null, null, null, null] +31590 - null - [null, null, null, null, null] +31591 - null - [null, null, null, null, null] +31592 - Mess - [Dig, null, null, null, null] +31593 - Mess - [Dig, null, null, null, null] +31594 - Idol - [Take, null, null, null, null] +31595 - Shelf - [null, null, null, null, null] +31596 - Shelf - [null, null, null, null, null] +31597 - Shelf - [null, null, null, null, null] +31598 - null - [null, null, null, null, null] +31599 - null - [null, null, null, null, null] +31600 - null - [null, null, null, null, null] +31601 - null - [null, null, null, null, null] +31602 - null - [null, null, null, null, null] +31603 - null - [null, null, null, null, null] +31604 - null - [null, null, null, null, null] +31605 - null - [null, null, null, null, null] +31606 - null - [null, null, null, null, null] +31607 - null - [null, null, null, null, null] +31608 - null - [null, null, null, null, null] +31609 - null - [null, null, null, null, null] +31610 - null - [null, null, null, null, null] +31611 - null - [null, null, null, null, null] +31612 - null - [null, null, null, null, null] +31613 - null - [null, null, null, null, null] +31614 - null - [null, null, null, null, null] +31615 - null - [null, null, null, null, null] +31616 - null - [null, null, null, null, null] +31617 - null - [null, null, null, null, null] +31618 - null - [null, null, null, null, null] +31619 - null - [null, null, null, null, null] +31620 - null - [null, null, null, null, null] +31621 - null - [null, null, null, null, null] +31622 - null - [null, null, null, null, null] +31623 - null - [null, null, null, null, null] +31624 - null - [null, null, null, null, null] +31625 - null - [null, null, null, null, null] +31626 - null - [null, null, null, null, null] +31627 - null - [null, null, null, null, null] +31628 - null - [null, null, null, null, null] +31629 - null - [null, null, null, null, null] +31630 - null - [null, null, null, null, null] +31631 - null - [null, null, null, null, null] +31632 - null - [null, null, null, null, null] +31633 - null - [null, null, null, null, null] +31634 - null - [null, null, null, null, null] +31635 - null - [null, null, null, null, null] +31636 - null - [null, null, null, null, null] +31637 - null - [null, null, null, null, null] +31638 - null - [null, null, null, null, null] +31639 - null - [null, null, null, null, null] +31640 - null - [null, null, null, null, null] +31641 - null - [null, null, null, null, null] +31642 - null - [null, null, null, null, null] +31643 - null - [null, null, null, null, null] +31644 - null - [null, null, null, null, null] +31645 - null - [null, null, null, null, null] +31646 - null - [null, null, null, null, null] +31647 - null - [null, null, null, null, null] +31648 - null - [null, null, null, null, null] +31649 - Notices - [Read, null, null, null, null] +31650 - null - [null, null, null, null, null] +31651 - Pier - [Dive, null, null, null, null] +31652 - Chain - [Dive, null, null, null, null] +31653 - Chest - [Open, null, null, null, null] +31654 - Chest - [Search, null, null, null, null] +31655 - null - [null, null, null, null, null] +31656 - null - [null, null, null, null, null] +31657 - null - [null, null, null, null, null] +31658 - null - [null, null, null, null, null] +31659 - null - [null, null, null, null, null] +31660 - null - [null, null, null, null, null] +31661 - null - [null, null, null, null, null] +31662 - null - [null, null, null, null, null] +31663 - null - [null, null, null, null, null] +31664 - null - [null, null, null, null, null] +31665 - null - [null, null, null, null, null] +31666 - null - [null, null, null, null, null] +31667 - null - [null, null, null, null, null] +31668 - null - [null, null, null, null, null] +31669 - null - [null, null, null, null, null] +31670 - null - [null, null, null, null, null] +31671 - null - [null, null, null, null, null] +31672 - null - [null, null, null, null, null] +31673 - null - [null, null, null, null, null] +31674 - null - [null, null, null, null, null] +31675 - null - [null, null, null, null, null] +31676 - null - [null, null, null, null, null] +31677 - null - [null, null, null, null, null] +31678 - null - [null, null, null, null, null] +31679 - null - [null, null, null, null, null] +31680 - null - [null, null, null, null, null] +31681 - Cannon - [null, null, null, null, null] +31682 - null - [null, null, null, null, null] +31683 - null - [null, null, null, null, null] +31684 - null - [null, null, null, null, null] +31685 - null - [null, null, null, null, null] +31686 - null - [null, null, null, null, null] +31687 - null - [hidden, null, null, null, null] +31688 - null - [hidden, null, null, null, null] +31689 - null - [hidden, null, null, null, null] +31690 - null - [hidden, hidden, null, null, null] +31691 - null - [hidden, null, null, null, null] +31692 - null - [null, null, null, null, null] +31693 - null - [null, Check, null, null, null] +31694 - null - [null, null, null, null, null] +31695 - null - [null, null, null, null, null] +31696 - null - [null, null, null, null, null] +31697 - null - [null, null, null, null, null] +31698 - null - [null, null, null, null, null] +31699 - null - [null, null, null, null, null] +31700 - null - [null, null, null, null, null] +31701 - null - [null, null, null, null, null] +31702 - null - [null, null, null, null, null] +31703 - null - [null, null, null, null, null] +31704 - null - [null, null, null, null, null] +31705 - null - [null, null, null, null, null] +31706 - null - [null, null, null, null, null] +31707 - null - [null, null, null, null, null] +31708 - null - [null, null, null, null, null] +31709 - null - [null, null, null, null, null] +31710 - null - [null, null, null, null, null] +31711 - null - [null, null, null, null, null] +31712 - null - [null, null, null, null, null] +31713 - null - [null, null, null, null, null] +31714 - null - [null, null, null, null, null] +31715 - null - [null, null, null, null, null] +31716 - null - [null, null, null, null, null] +31717 - null - [null, null, null, null, null] +31718 - null - [null, null, null, null, null] +31719 - null - [null, null, null, null, null] +31720 - null - [null, null, null, null, null] +31721 - null - [null, null, null, null, null] +31722 - null - [null, null, null, null, null] +31723 - null - [null, null, null, null, null] +31724 - null - [null, null, null, null, null] +31725 - null - [null, null, null, null, null] +31726 - null - [null, null, null, null, null] +31727 - null - [null, null, null, null, null] +31728 - null - [null, null, null, null, null] +31729 - null - [null, null, null, null, null] +31730 - null - [null, null, null, null, null] +31731 - null - [null, null, null, null, null] +31732 - null - [null, null, null, null, null] +31733 - null - [null, null, null, null, null] +31734 - null - [null, null, null, null, null] +31735 - null - [null, null, null, null, null] +31736 - null - [null, null, null, null, null] +31737 - null - [null, null, null, null, null] +31738 - null - [null, null, null, null, null] +31739 - null - [null, null, null, null, null] +31740 - null - [null, null, null, null, null] +31741 - null - [null, null, null, null, null] +31742 - null - [null, null, null, null, null] +31743 - Posts - [null, null, null, null, null] +31744 - null - [null, null, null, null, null] +31745 - Pirate Flag - [null, null, null, null, null] +31746 - null - [null, null, null, null, null] +31747 - null - [null, null, null, null, null] +31748 - null - [null, null, null, null, null] +31749 - null - [null, null, null, null, null] +31750 - null - [null, null, null, null, null] +31751 - null - [null, null, null, null, null] +31752 - null - [null, null, null, null, null] +31753 - null - [null, null, null, null, null] +31754 - null - [null, null, null, null, null] +31755 - null - [null, null, null, null, null] +31756 - null - [null, null, null, null, null] +31757 - null - [null, null, null, null, null] +31758 - null - [null, null, null, null, null] +31759 - Drain - [Search, null, null, null, null] +31760 - null - [null, null, null, null, null] +31761 - null - [null, null, null, null, null] +31762 - null - [null, null, null, null, null] +31763 - null - [null, null, null, null, null] +31764 - null - [null, null, null, null, null] +31765 - null - [null, null, null, null, null] +31766 - null - [null, null, null, null, null] +31767 - Cooking shelves - [null, null, null, null, null] +31768 - null - [null, null, null, null, null] +31769 - null - [null, null, null, null, null] +31770 - null - [null, null, null, null, null] +31771 - null - [null, null, null, null, null] +31772 - null - [null, null, null, null, null] +31773 - null - [null, null, null, null, null] +31774 - null - [null, null, null, null, null] +31775 - null - [null, null, null, null, null] +31776 - null - [null, null, null, null, null] +31777 - null - [null, null, null, null, null] +31778 - null - [null, null, null, null, null] +31779 - null - [null, null, null, null, null] +31780 - null - [null, null, null, null, null] +31781 - null - [null, null, null, null, null] +31782 - null - [null, null, null, null, null] +31783 - null - [null, null, null, null, null] +31784 - null - [null, null, null, null, null] +31785 - null - [null, null, null, null, null] +31786 - null - [null, null, null, null, null] +31787 - null - [null, null, null, null, null] +31788 - null - [null, null, null, null, null] +31789 - null - [null, null, null, null, null] +31790 - null - [null, null, null, null, null] +31791 - null - [null, null, null, null, null] +31792 - null - [null, null, null, null, null] +31793 - null - [null, null, null, null, null] +31794 - null - [null, null, null, null, null] +31795 - null - [null, null, null, null, null] +31796 - null - [null, null, null, null, null] +31797 - null - [null, null, null, null, null] +31798 - null - [null, null, null, null, null] +31799 - null - [null, null, null, null, null] +31800 - null - [null, null, null, null, null] +31801 - null - [null, null, null, null, null] +31802 - null - [null, null, null, null, null] +31803 - null - [null, null, null, null, null] +31804 - null - [null, null, null, null, null] +31805 - null - [null, null, null, null, null] +31806 - null - [null, null, null, null, null] +31807 - null - [null, null, null, null, null] +31808 - Large door - [Open, null, null, null, null] +31809 - Large door - [Close, null, null, null, null] +31810 - null - [null, null, null, null, null] +31811 - Large door - [Open, null, null, null, null] +31812 - Large door - [Close, null, null, null, null] +31813 - null - [null, null, null, null, null] +31814 - Large door - [Open, null, null, null, null] +31815 - Large door - [Open, null, null, null, null] +31816 - Large door - [Close, null, null, null, null] +31817 - Large door - [Close, null, null, null, null] +31818 - Large door - [Open, null, null, null, null] +31819 - Large door - [Open, null, null, null, null] +31820 - Large door - [Open, null, null, null, null] +31821 - Large door - [Close, null, null, null, null] +31822 - Large door - [Open, null, null, null, null] +31823 - Large door - [Close, null, null, null, null] +31824 - Door - [Close, null, null, null, null] +31825 - Door - [Open, null, null, null, null] +31826 - Door - [Close, null, null, null, null] +31827 - Door - [Open, null, null, null, null] +31828 - Large door - [Close, null, null, null, null] +31829 - Door - [Close, null, null, null, null] +31830 - Door - [Open, null, null, null, null] +31831 - Door - [Close, null, null, null, null] +31832 - Door - [Open, null, null, null, null] +31833 - Ancient Gate - [Open, Search, null, null, null] +31834 - Ancient Gate - [Open, Search, null, null, null] +31835 - null - [null, null, null, null, null] +31836 - null - [null, null, null, null, null] +31837 - null - [null, null, null, null, null] +31838 - Door - [Open, null, null, null, null] +31839 - Door - [Close, null, null, null, null] +31840 - null - [null, null, null, null, null] +31841 - Door - [Open, null, null, null, null] +31842 - Door - [Close, null, null, null, null] +31843 - null - [null, null, null, null, null] +31844 - Door - [Open, null, null, null, null] +31845 - Door - [Close, null, null, null, null] +31846 - null - [null, null, null, null, null] +31847 - null - [null, null, null, null, null] +31848 - null - [null, null, null, null, null] +31849 - null - [null, null, null, null, null] +31850 - null - [null, null, null, null, null] +31851 - null - [null, null, null, null, null] +31852 - null - [null, null, null, null, null] +31853 - null - [null, null, null, null, null] +31854 - null - [null, null, null, null, null] +31855 - null - [null, null, null, null, null] +31856 - null - [null, null, null, null, null] +31857 - null - [null, null, null, null, null] +31858 - null - [null, null, null, null, null] +31859 - null - [null, null, null, null, null] +31860 - null - [null, null, null, null, null] +31861 - null - [null, null, null, null, null] +31862 - null - [null, null, null, null, null] +31863 - null - [null, null, null, null, null] +31864 - null - [null, null, null, null, null] +31865 - null - [null, null, null, null, null] +31866 - null - [null, null, null, null, null] +31867 - null - [null, null, null, null, null] +31868 - null - [null, null, null, null, null] +31869 - null - [null, null, null, null, null] +31870 - null - [null, null, null, null, null] +31871 - null - [null, null, null, null, null] +31872 - null - [null, null, null, null, null] +31873 - null - [null, null, null, null, null] +31874 - null - [null, null, null, null, null] +31875 - null - [null, null, null, null, null] +31876 - null - [null, null, null, null, null] +31877 - null - [null, null, null, null, null] +31878 - null - [null, null, null, null, null] +31879 - null - [null, null, null, null, null] +31880 - null - [null, null, null, null, null] +31881 - null - [null, null, null, null, null] +31882 - null - [null, null, null, null, null] +31883 - null - [null, null, null, null, null] +31884 - null - [null, null, null, null, null] +31885 - null - [null, null, null, null, null] +31886 - null - [null, null, null, null, null] +31887 - null - [null, null, null, null, null] +31888 - null - [null, null, null, null, null] +31889 - null - [null, null, null, null, null] +31890 - null - [null, null, null, null, null] +31891 - null - [null, null, null, null, null] +31892 - null - [null, null, null, null, null] +31893 - null - [null, null, null, null, null] +31894 - null - [null, null, null, null, null] +31895 - null - [null, null, null, null, null] +31896 - null - [null, null, null, null, null] +31897 - null - [null, null, null, null, null] +31898 - null - [null, null, null, null, null] +31899 - null - [null, null, null, null, null] +31900 - null - [null, null, null, null, null] +31901 - null - [null, null, null, null, null] +31902 - null - [null, null, null, null, null] +31903 - null - [null, null, null, null, null] +31904 - null - [null, null, null, null, null] +31905 - null - [null, null, null, null, null] +31906 - null - [null, null, null, null, null] +31907 - null - [null, null, null, null, null] +31908 - null - [null, null, null, null, null] +31909 - null - [null, null, null, null, null] +31910 - null - [null, null, null, null, null] +31911 - null - [null, null, null, null, null] +31912 - null - [null, null, null, null, null] +31913 - null - [null, null, null, null, null] +31914 - null - [null, null, null, null, null] +31915 - null - [null, null, null, null, null] +31916 - null - [null, null, null, null, null] +31917 - null - [null, null, null, null, null] +31918 - null - [null, null, null, null, null] +31919 - null - [null, null, null, null, null] +31920 - null - [null, null, null, null, null] +31921 - null - [null, null, null, null, null] +31922 - null - [null, null, null, null, null] +31923 - null - [null, null, null, null, null] +31924 - null - [null, null, null, null, null] +31925 - null - [null, null, null, null, null] +31926 - null - [null, null, null, null, null] +31927 - null - [null, null, null, null, null] +31928 - null - [null, null, null, null, null] +31929 - null - [null, null, null, null, null] +31930 - null - [null, null, null, null, null] +31931 - null - [null, null, null, null, null] +31932 - null - [null, null, null, null, null] +31933 - null - [null, null, null, null, null] +31934 - null - [null, null, null, null, null] +31935 - null - [null, null, null, null, null] +31936 - null - [null, null, null, null, null] +31937 - null - [null, null, null, null, null] +31938 - null - [null, null, null, null, null] +31939 - null - [null, null, null, null, null] +31940 - null - [null, null, null, null, null] +31941 - null - [null, null, null, null, null] +31942 - null - [null, null, null, null, null] +31943 - null - [null, null, null, null, null] +31944 - null - [null, null, null, null, null] +31945 - null - [null, null, null, null, null] +31946 - null - [null, null, null, null, null] +31947 - null - [null, null, null, null, null] +31948 - null - [null, null, null, null, null] +31949 - null - [null, null, null, null, null] +31950 - null - [null, null, null, null, null] +31951 - null - [null, null, null, null, null] +31952 - null - [null, null, null, null, null] +31953 - null - [null, null, null, null, null] +31954 - null - [null, null, null, null, null] +31955 - null - [null, null, null, null, null] +31956 - null - [null, null, null, null, null] +31957 - null - [null, null, null, null, null] +31958 - null - [null, null, null, null, null] +31959 - null - [null, null, null, null, null] +31960 - null - [null, null, null, null, null] +31961 - null - [null, null, null, null, null] +31962 - null - [null, null, null, null, null] +31963 - null - [null, null, null, null, null] +31964 - null - [null, null, null, null, null] +31965 - null - [null, null, null, null, null] +31966 - null - [null, null, null, null, null] +31967 - null - [null, null, null, null, null] +31968 - null - [null, null, null, null, null] +31969 - null - [null, null, null, null, null] +31970 - null - [null, null, null, null, null] +31971 - null - [null, null, null, null, null] +31972 - null - [null, null, null, null, null] +31973 - null - [null, null, null, null, null] +31974 - null - [null, null, null, null, null] +31975 - null - [null, null, null, null, null] +31976 - null - [null, null, null, null, null] +31977 - null - [null, null, null, null, null] +31978 - null - [null, null, null, null, null] +31979 - null - [null, null, null, null, null] +31980 - null - [null, null, null, null, null] +31981 - null - [null, null, null, null, null] +31982 - null - [null, null, null, null, null] +31983 - null - [null, null, null, null, null] +31984 - null - [null, null, null, null, null] +31985 - null - [null, null, null, null, null] +31986 - null - [null, null, null, null, null] +31987 - null - [null, null, null, null, null] +31988 - null - [null, null, null, null, null] +31989 - null - [null, null, null, null, null] +31990 - null - [null, null, null, null, null] +31991 - null - [null, null, null, null, null] +31992 - null - [null, null, null, null, null] +31993 - null - [null, null, null, null, null] +31994 - null - [null, null, null, null, null] +31995 - null - [null, null, null, null, null] +31996 - null - [null, null, null, null, null] +31997 - null - [null, null, null, null, null] +31998 - null - [null, null, null, null, null] +31999 - null - [null, null, null, null, null] +32000 - null - [null, null, null, null, null] +32001 - null - [null, null, null, null, null] +32002 - null - [null, null, null, null, null] +32003 - Pillar - [null, null, null, null, null] +32004 - null - [null, null, null, null, null] +32005 - Coal - [null, null, null, null, null] +32006 - null - [null, null, null, null, null] +32007 - null - [null, null, null, null, null] +32008 - Rock - [null, null, null, null, null] +32009 - Open chest - [Search, Close, null, null, null] +32010 - Closed chest - [Open, null, null, null, null] +32011 - null - [null, null, null, null, null] +32012 - Animal skull - [null, null, null, null, null] +32013 - Animal skull - [null, null, null, null, null] +32014 - Animal skull - [null, null, null, null, null] +32015 - Ladder - [Climb-up, null, null, null, null] +32016 - Ladder - [Climb-up, null, null, null, null] +32017 - null - [null, null, null, null, null] +32018 - null - [null, null, null, null, null] +32019 - null - [null, null, null, null, null] +32020 - null - [null, null, null, null, null] +32021 - null - [null, null, null, null, null] +32022 - Standard - [null, null, null, null, null] +32023 - Well - [Search, null, null, null, null] +32024 - Well - [Climb-down, null, null, null, null] +32025 - null - [null, null, null, null, null] +32026 - null - [null, null, null, null, null] +32027 - null - [null, null, null, null, null] +32028 - Shelf - [null, null, null, null, null] +32029 - Bed - [null, null, null, null, null] +32030 - Bed - [null, null, null, null, null] +32031 - Bed - [null, null, null, null, null] +32032 - Chair - [null, null, null, null, null] +32033 - Stool - [null, null, null, null, null] +32034 - Hanging log - [null, null, null, null, null] +32035 - null - [null, null, null, null, null] +32036 - null - [null, null, null, null, null] +32037 - null - [null, null, null, null, null] +32038 - null - [null, null, null, null, null] +32039 - null - [null, null, null, null, null] +32040 - null - [null, null, null, null, null] +32041 - null - [null, null, null, null, null] +32042 - null - [null, null, null, null, null] +32043 - null - [null, null, null, null, null] +32044 - null - [null, null, null, null, null] +32045 - null - [null, null, null, null, null] +32046 - null - [null, null, null, null, null] +32047 - null - [null, null, null, null, null] +32048 - Staircase - [Climb-up, null, null, null, null] +32049 - Sacks - [Search, null, null, null, null] +32050 - Spear wall - [null, null, null, null, null] +32051 - Spear wall - [null, null, null, null, null] +32052 - null - [null, null, null, null, null] +32053 - null - [null, null, null, null, null] +32054 - null - [null, null, null, null, null] +32055 - null - [null, null, null, null, null] +32056 - null - [null, null, null, null, null] +32057 - null - [null, null, null, null, null] +32058 - null - [null, null, null, null, null] +32059 - null - [null, null, null, null, null] +32060 - null - [null, null, null, null, null] +32061 - null - [null, null, null, null, null] +32062 - null - [null, null, null, null, null] +32063 - Barrel - [null, null, null, null, null] +32064 - null - [null, null, null, null, null] +32065 - Fungus - [null, null, null, null, null] +32066 - Fungus - [null, null, null, null, null] +32067 - Fungus - [null, null, null, null, null] +32068 - Tunnel - [Pass-through, null, null, null, null] +32069 - Tunnel - [Pass-through, null, null, null, null] +32070 - Bench - [null, null, null, null, null] +32071 - Charred bones - [null, null, null, null, null] +32072 - Corpse - [null, null, null, null, null] +32073 - Corpse - [null, null, null, null, null] +32074 - Corpse - [null, null, null, null, null] +32075 - Corpse - [null, null, null, null, null] +32076 - Stalagmites - [null, null, null, null, null] +32077 - Flat rock - [Search, null, null, null, null] +32078 - Odd markings - [Search, null, null, null, null] +32079 - Chaos altar - [Pray-at, null, null, null, null] +32080 - null - [null, null, null, null, null] +32081 - null - [null, null, null, null, null] +32082 - null - [null, null, null, null, null] +32083 - null - [null, null, null, null, null] +32084 - null - [null, null, null, null, null] +32085 - null - [null, null, null, null, null] +32086 - null - [null, null, null, null, null] +32087 - null - [null, null, null, null, null] +32088 - null - [null, null, null, null, null] +32089 - null - [null, null, null, null, null] +32090 - null - [null, null, null, null, null] +32091 - null - [null, null, null, null, null] +32092 - null - [null, null, null, null, null] +32093 - null - [null, null, null, null, null] +32094 - null - [null, null, null, null, null] +32095 - null - [null, null, null, null, null] +32096 - null - [null, null, null, null, null] +32097 - null - [null, null, null, null, null] +32098 - null - [null, null, null, null, null] +32099 - Fire - [null, null, null, null, null] +32100 - null - [null, null, null, null, null] +32101 - null - [null, null, null, null, null] +32102 - null - [null, null, null, null, null] +32103 - null - [null, null, null, null, null] +32104 - null - [null, null, null, null, null] +32105 - a cooking pot - [null, null, null, null, null] +32106 - Fungus covered Cavern wall - [null, Search, hidden, null, null] +32107 - Fungus pattern - [null, null, hidden, null, null] +32108 - null - [null, null, null, null, null] +32109 - null - [null, null, null, null, null] +32110 - null - [null, null, null, null, null] +32111 - null - [null, null, null, null, null] +32112 - null - [null, null, null, null, null] +32113 - null - [null, null, null, null, null] +32114 - null - [null, null, null, null, null] +32115 - null - [null, null, null, null, null] +32116 - null - [null, null, null, null, null] +32117 - null - [null, null, null, null, null] +32118 - null - [null, null, null, null, null] +32119 - null - [null, null, null, null, null] +32120 - Smashed chair - [null, null, null, null, null] +32121 - Table - [null, null, null, null, null] +32122 - null - [null, null, null, null, null] +32123 - null - [null, null, null, null, null] +32124 - null - [null, null, null, null, null] +32125 - null - [null, null, null, null, null] +32126 - null - [null, null, null, null, null] +32127 - null - [null, null, null, null, null] +32128 - null - [null, null, null, null, null] +32129 - null - [null, null, null, null, null] +32130 - null - [null, null, null, null, null] +32131 - Passage - [null, null, null, null, null] +32132 - null - [null, null, null, null, null] +32133 - null - [null, null, null, null, null] +32134 - null - [null, null, null, null, null] +32135 - null - [null, null, null, null, null] +32136 - null - [null, null, null, null, null] +32137 - null - [null, null, null, null, null] +32138 - null - [null, null, null, null, null] +32139 - null - [null, null, null, null, null] +32140 - null - [null, null, null, null, null] +32141 - null - [null, null, null, null, null] +32142 - null - [null, null, null, null, null] +32143 - null - [null, null, null, null, null] +32144 - null - [null, null, null, null, null] +32145 - null - [null, null, null, null, null] +32146 - null - [null, null, null, null, null] +32147 - null - [null, null, null, null, null] +32148 - null - [null, null, null, null, null] +32149 - null - [null, null, null, null, null] +32150 - null - [null, null, null, null, null] +32151 - null - [null, null, null, null, null] +32152 - null - [null, null, null, null, null] +32153 - null - [null, null, null, null, null] +32154 - null - [null, null, null, null, null] +32155 - null - [null, null, null, null, null] +32156 - null - [null, null, null, null, null] +32157 - null - [null, null, null, null, null] +32158 - null - [null, null, null, null, null] +32159 - null - [null, null, null, null, null] +32160 - null - [null, null, null, null, null] +32161 - null - [null, null, null, null, null] +32162 - null - [null, null, null, null, null] +32163 - null - [null, null, null, null, null] +32164 - null - [null, null, null, null, null] +32165 - null - [null, null, null, null, null] +32166 - null - [null, null, null, null, null] +32167 - null - [null, null, null, null, null] +32168 - null - [null, null, null, null, null] +32169 - null - [null, null, null, null, null] +32170 - null - [null, null, null, null, null] +32171 - null - [null, null, null, null, null] +32172 - null - [null, null, null, null, null] +32173 - null - [null, null, null, null, null] +32174 - null - [null, null, null, null, null] +32175 - null - [null, null, null, null, null] +32176 - null - [null, null, null, null, null] +32177 - null - [null, null, null, null, null] +32178 - null - [null, null, null, null, null] +32179 - null - [null, null, null, null, null] +32180 - null - [null, null, null, null, null] +32181 - null - [null, null, null, null, null] +32182 - null - [null, null, null, null, null] +32183 - null - [null, null, null, null, null] +32184 - null - [null, null, null, null, null] +32185 - null - [null, null, null, null, null] +32186 - null - [null, null, null, null, null] +32187 - null - [null, null, null, null, null] +32188 - null - [null, null, null, null, null] +32189 - null - [null, null, null, null, null] +32190 - null - [null, null, null, null, null] +32191 - null - [null, null, null, null, null] +32192 - null - [null, null, null, null, null] +32193 - null - [null, null, null, null, null] +32194 - null - [null, null, null, null, null] +32195 - null - [null, null, null, null, null] +32196 - null - [null, null, null, null, null] +32197 - null - [null, null, null, null, null] +32198 - null - [null, null, null, null, null] +32199 - null - [null, null, null, null, null] +32200 - null - [null, null, null, null, null] +32201 - null - [null, null, null, null, null] +32202 - null - [null, null, null, null, null] +32203 - null - [null, null, null, null, null] +32204 - null - [null, null, null, null, null] +32205 - null - [null, null, null, null, null] +32206 - null - [null, null, null, null, null] +32207 - null - [null, null, null, null, null] +32208 - null - [null, null, null, null, null] +32209 - null - [null, null, null, null, null] +32210 - null - [null, null, null, null, null] +32211 - null - [null, null, null, null, null] +32212 - null - [null, null, null, null, null] +32213 - null - [null, null, null, null, null] +32214 - null - [null, null, null, null, null] +32215 - null - [null, null, null, null, null] +32216 - null - [null, null, null, null, null] +32217 - null - [null, null, null, null, null] +32218 - null - [null, null, null, null, null] +32219 - null - [null, null, null, null, null] +32220 - null - [null, null, null, null, null] +32221 - null - [null, null, null, null, null] +32222 - null - [null, null, null, null, null] +32223 - null - [null, null, null, null, null] +32224 - null - [null, null, null, null, null] +32225 - null - [null, null, null, null, null] +32226 - null - [null, null, null, null, null] +32227 - null - [null, null, null, null, null] +32228 - null - [null, null, null, null, null] +32229 - null - [null, null, null, null, null] +32230 - null - [null, null, null, null, null] +32231 - null - [null, null, null, null, null] +32232 - null - [null, null, null, null, null] +32233 - null - [null, null, null, null, null] +32234 - null - [null, null, null, null, null] +32235 - null - [null, null, null, null, null] +32236 - null - [null, null, null, null, null] +32237 - null - [null, null, null, null, null] +32238 - null - [null, null, null, null, null] +32239 - null - [null, null, null, null, null] +32240 - null - [null, null, null, null, null] +32241 - null - [null, null, null, null, null] +32242 - null - [null, null, null, null, null] +32243 - null - [null, null, null, null, null] +32244 - null - [null, null, null, null, null] +32245 - null - [null, null, null, null, null] +32246 - null - [null, null, null, null, null] +32247 - null - [null, null, null, null, null] +32248 - null - [null, null, null, null, null] +32249 - null - [null, null, null, null, null] +32250 - null - [null, null, null, null, null] +32251 - Bed - [null, null, null, null, null] +32252 - Tomb - [null, null, null, null, null] +32253 - pillar - [null, null, null, null, null] +32254 - null - [null, null, null, null, null] +32255 - null - [null, null, null, null, null] +32256 - null - [null, null, null, null, null] +32257 - null - [null, null, null, null, null] +32258 - null - [null, null, null, null, null] +32259 - null - [null, null, null, null, null] +32260 - null - [null, null, null, null, null] +32261 - null - [null, null, null, null, null] +32262 - null - [null, null, null, null, null] +32263 - null - [null, null, null, null, null] +32264 - Rock - [null, null, null, null, null] +32265 - Rock - [null, null, null, null, null] +32266 - Rock - [null, null, null, null, null] +32267 - Rock - [null, null, null, null, null] +32268 - null - [null, null, null, null, null] +32269 - null - [null, null, null, null, null] +32270 - Staircase - [Climb-up, null, null, null, null] +32271 - Staircase - [Climb-down, null, null, null, null] +32272 - Large grave - [null, null, null, null, null] +32273 - Chair - [null, null, null, null, null] +32274 - Chair - [null, null, null, null, null] +32275 - Throne - [null, null, null, null, null] +32276 - Bamboo Ladder - [Climb-up, null, null, null, null] +32277 - Bamboo Ladder - [Climb-down, null, null, null, null] +32278 - Wooden defence - [null, null, null, null, null] +32279 - Climbing rope - [null, null, null, null, null] +32280 - null - [null, null, null, null, null] +32281 - Exit Sign - [null, null, null, null, null] +32282 - Lever - [null, null, null, null, null] +32283 - Cooking shelves - [null, null, null, null, null] +32284 - Shelves - [null, null, null, null, null] +32285 - Throne - [null, null, null, null, null] +32286 - Chair - [null, null, null, null, null] +32287 - Candle - [null, null, null, null, null] +32288 - Candle - [null, null, null, null, null] +32289 - Altar slab - [null, null, null, null, null] +32290 - Coffin - [Open, null, null, null, null] +32291 - Coffin - [Close, null, null, null, null] +32292 - Suit of armour - [null, null, null, null, null] +32293 - Suit of armour - [null, null, null, null, null] +32294 - Dead tree - [Chop down, null, hidden, null, null] +32295 - Standard - [null, null, null, null, null] +32296 - Obstacle pipe - [Squeeze-through, null, null, null, null] +32297 - Obstacle pipe - [Squeeze-through, null, null, null, null] +32298 - Obstacle pipe - [null, null, null, null, null] +32299 - Obstacle pipe - [null, null, null, null, null] +32300 - Obstacle pipe - [null, null, null, null, null] +32301 - Obstacle pipe - [null, null, null, null, null] +32302 - Obstacle pipe - [null, null, null, null, null] +32303 - Obstacle pipe - [null, null, null, null, null] +32304 - Obstacle pipe - [null, null, null, null, null] +32305 - Obstacle pipe - [null, null, null, null, null] +32306 - null - [null, null, null, null, null] +32307 - Bush - [null, null, null, null, null] +32308 - Fungus - [null, null, null, null, null] +32309 - Fungus - [null, null, null, null, null] +32310 - Fungus - [null, null, null, null, null] +32311 - Eggs - [null, null, null, null, null] +32312 - Eggs - [null, null, null, null, null] +32313 - Big egg - [null, null, null, null, null] +32314 - null - [null, null, null, null, null] +32315 - null - [null, null, null, null, null] +32316 - null - [null, null, null, null, null] +32317 - null - [null, null, null, null, null] +32318 - null - [null, null, null, null, null] +32319 - Root - [Search, null, null, null, null] +32320 - Root - [Search, null, null, null, null] +32321 - null - [null, null, null, null, null] +32322 - Wallshield - [null, null, null, null, null] +32323 - Helmet rack - [null, null, null, null, null] +32324 - Magical symbol - [null, null, null, null, null] +32325 - Magical symbol - [null, null, null, null, null] +32326 - Painting - [null, null, null, null, null] +32327 - null - [null, null, null, null, null] +32328 - null - [null, null, null, null, null] +32329 - null - [null, null, null, null, null] +32330 - null - [null, null, null, null, null] +32331 - null - [null, null, null, null, null] +32332 - null - [null, null, null, null, null] +32333 - null - [null, null, null, null, null] +32334 - null - [null, null, null, null, null] +32335 - null - [null, null, null, null, null] +32336 - null - [null, null, null, null, null] +32337 - null - [null, null, null, null, null] +32338 - null - [null, null, null, null, null] +32339 - null - [null, null, null, null, null] +32340 - null - [null, null, null, null, null] +32341 - null - [null, null, null, null, null] +32342 - null - [null, null, null, null, null] +32343 - null - [null, null, null, null, null] +32344 - null - [null, null, null, null, null] +32345 - null - [null, null, null, null, null] +32346 - null - [null, null, null, null, null] +32347 - null - [null, null, null, null, null] +32348 - null - [null, null, null, null, null] +32349 - null - [null, null, null, null, null] +32350 - null - [null, null, null, null, null] +32351 - null - [null, null, null, null, null] +32352 - null - [null, null, null, null, null] +32353 - null - [null, null, null, null, null] +32354 - null - [null, null, null, null, null] +32355 - null - [null, null, null, null, null] +32356 - null - [null, null, null, null, null] +32357 - null - [null, null, null, null, null] +32358 - null - [null, null, null, null, null] +32359 - null - [null, null, null, null, null] +32360 - null - [null, null, null, null, null] +32361 - null - [null, null, null, null, null] +32362 - null - [null, null, null, null, null] +32363 - null - [null, null, null, null, null] +32364 - null - [null, null, null, null, null] +32365 - null - [null, null, null, null, null] +32366 - null - [null, null, null, null, null] +32367 - null - [null, null, null, null, null] +32368 - null - [null, null, null, null, null] +32369 - null - [null, null, null, null, null] +32370 - null - [null, null, null, null, null] +32371 - null - [null, null, null, null, null] +32372 - null - [null, null, null, null, null] +32373 - null - [null, null, null, null, null] +32374 - null - [null, null, null, null, null] +32375 - null - [null, null, null, null, null] +32376 - null - [null, null, null, null, null] +32377 - null - [null, null, null, null, null] +32378 - null - [null, null, null, null, null] +32379 - null - [null, null, null, null, null] +32380 - null - [null, null, null, null, null] +32381 - null - [null, null, null, null, null] +32382 - null - [null, null, null, null, null] +32383 - null - [null, null, null, null, null] +32384 - null - [null, null, null, null, null] +32385 - null - [null, null, null, null, null] +32386 - null - [null, null, null, null, null] +32387 - null - [null, null, null, null, null] +32388 - null - [null, null, null, null, null] +32389 - null - [null, null, null, null, null] +32390 - null - [null, null, null, null, null] +32391 - null - [null, null, null, null, null] +32392 - null - [null, null, null, null, null] +32393 - null - [null, null, null, null, null] +32394 - null - [null, null, null, null, null] +32395 - null - [null, null, null, null, null] +32396 - null - [null, null, null, null, null] +32397 - null - [null, null, null, null, null] +32398 - null - [null, null, null, null, null] +32399 - null - [null, null, null, null, null] +32400 - null - [null, null, null, null, null] +32401 - null - [null, null, null, null, null] +32402 - null - [null, null, null, null, null] +32403 - null - [null, null, null, null, null] +32404 - null - [null, null, null, null, null] +32405 - null - [null, null, null, null, null] +32406 - null - [null, null, null, null, null] +32407 - null - [null, null, null, null, null] +32408 - null - [null, null, null, null, null] +32409 - null - [null, null, null, null, null] +32410 - null - [null, null, null, null, null] +32411 - null - [null, null, null, null, null] +32412 - null - [null, null, null, null, null] +32413 - null - [null, null, null, null, null] +32414 - null - [null, null, null, null, null] +32415 - null - [null, null, null, null, null] +32416 - null - [null, null, null, null, null] +32417 - null - [null, null, null, null, null] +32418 - null - [null, null, null, null, null] +32419 - null - [null, null, null, null, null] +32420 - null - [null, null, null, null, null] +32421 - null - [null, null, null, null, null] +32422 - null - [null, null, null, null, null] +32423 - null - [null, null, null, null, null] +32424 - null - [null, null, null, null, null] +32425 - null - [null, null, null, null, null] +32426 - Rocks - [Mine, Prospect, hidden, null, null] +32427 - Rocks - [Mine, Prospect, hidden, null, null] +32428 - Rocks - [Mine, Prospect, hidden, null, null] +32429 - Rocks - [Mine, Prospect, hidden, null, null] +32430 - Rocks - [Mine, Prospect, hidden, null, null] +32431 - Rocks - [Mine, Prospect, hidden, null, null] +32432 - Rocks - [Mine, Prospect, hidden, null, null] +32433 - Rocks - [Mine, Prospect, hidden, null, null] +32434 - Rocks - [Mine, Prospect, hidden, null, null] +32435 - Rocks - [Mine, Prospect, hidden, null, null] +32436 - Rocks - [Mine, Prospect, hidden, null, null] +32437 - Rocks - [Mine, Prospect, hidden, null, null] +32438 - Rocks - [Mine, Prospect, hidden, null, null] +32439 - Rocks - [Mine, Prospect, hidden, null, null] +32440 - Rocks - [Mine, Prospect, hidden, null, null] +32441 - Rocks - [Mine, Prospect, hidden, null, null] +32442 - Rocks - [Mine, Prospect, hidden, null, null] +32443 - Rocks - [Mine, Prospect, hidden, null, null] +32444 - Rocks - [Mine, Prospect, hidden, null, null] +32445 - Rocks - [Mine, Prospect, hidden, null, null] +32446 - Rocks - [Mine, Prospect, hidden, null, null] +32447 - Rocks - [Mine, Prospect, hidden, null, null] +32448 - Rocks - [Mine, Prospect, hidden, null, null] +32449 - Rocks - [Mine, Prospect, hidden, null, null] +32450 - Rocks - [Mine, Prospect, hidden, null, null] +32451 - Rocks - [Mine, Prospect, hidden, null, null] +32452 - Rocks - [Mine, Prospect, hidden, null, null] +32453 - null - [null, null, null, null, null] +32454 - null - [null, null, null, null, null] +32455 - null - [null, null, null, null, null] +32456 - null - [null, null, null, null, null] +32457 - null - [null, null, null, null, null] +32458 - null - [null, null, null, null, null] +32459 - null - [null, null, null, null, null] +32460 - null - [null, null, null, null, null] +32461 - null - [null, null, null, null, null] +32462 - null - [null, null, null, null, null] +32463 - null - [null, null, null, null, null] +32464 - null - [null, null, null, null, null] +32465 - null - [null, null, null, null, null] +32466 - null - [null, null, null, null, null] +32467 - null - [null, null, null, null, null] +32468 - null - [null, null, null, null, null] +32469 - null - [null, null, null, null, null] +32470 - null - [null, null, null, null, null] +32471 - null - [null, null, null, null, null] +32472 - null - [null, null, null, null, null] +32473 - null - [null, null, null, null, null] +32474 - null - [null, null, null, null, null] +32475 - null - [null, null, null, null, null] +32476 - null - [null, null, null, null, null] +32477 - null - [null, null, null, null, null] +32478 - null - [null, null, null, null, null] +32479 - null - [null, null, null, null, null] +32480 - null - [null, null, null, null, null] +32481 - null - [null, null, null, null, null] +32482 - null - [null, null, null, null, null] +32483 - null - [null, null, null, null, null] +32484 - null - [null, null, null, null, null] +32485 - null - [null, null, null, null, null] +32486 - null - [null, null, null, null, null] +32487 - null - [null, null, null, null, null] +32488 - null - [null, null, null, null, null] +32489 - null - [null, null, null, null, null] +32490 - null - [null, null, null, null, null] +32491 - null - [null, null, null, null, null] +32492 - null - [null, null, null, null, null] +32493 - null - [null, null, null, null, null] +32494 - Cave Exit - [Exit, null, null, null, null] +32495 - Cave Exit - [Exit, null, null, null, null] +32496 - null - [null, null, null, null, null] +32497 - null - [null, null, null, null, null] +32498 - null - [null, null, null, null, null] +32499 - null - [null, null, null, null, null] +32500 - null - [null, null, null, null, null] +32501 - null - [null, null, null, null, null] +32502 - null - [null, null, null, null, null] +32503 - null - [null, null, null, null, null] +32504 - null - [null, null, null, null, null] +32505 - null - [null, null, null, null, null] +32506 - null - [null, null, null, null, null] +32507 - null - [null, null, null, null, null] +32508 - null - [null, null, null, null, null] +32509 - null - [null, null, null, null, null] +32510 - null - [null, null, null, null, null] +32511 - null - [null, null, null, null, null] +32512 - null - [null, null, null, null, null] +32513 - null - [null, null, null, null, null] +32514 - null - [null, null, null, null, null] +32515 - null - [null, null, null, null, null] +32516 - null - [null, null, null, null, null] +32517 - null - [null, null, null, null, null] +32518 - null - [null, null, null, null, null] +32519 - null - [null, null, null, null, null] +32520 - null - [null, null, null, null, null] +32521 - null - [null, null, null, null, null] +32522 - null - [null, null, null, null, null] +32523 - null - [null, null, null, null, null] +32524 - null - [null, null, null, null, null] +32525 - null - [null, null, null, null, null] +32526 - null - [null, null, null, null, null] +32527 - null - [null, null, null, null, null] +32528 - null - [null, null, null, null, null] +32529 - null - [null, null, null, null, null] +32530 - null - [null, null, null, null, null] +32531 - null - [null, null, null, null, null] +32532 - null - [null, null, null, null, null] +32533 - null - [null, null, null, null, null] +32534 - null - [null, null, null, null, null] +32535 - null - [null, null, null, null, null] +32536 - null - [null, null, null, null, null] +32537 - null - [null, null, null, null, null] +32538 - null - [null, null, null, null, null] +32539 - null - [null, null, null, null, null] +32540 - null - [null, null, null, null, null] +32541 - null - [null, null, null, null, null] +32542 - null - [null, null, null, null, null] +32543 - null - [null, null, null, null, null] +32544 - null - [null, null, null, null, null] +32545 - null - [null, null, null, null, null] +32546 - null - [null, null, null, null, null] +32547 - null - [null, null, null, null, null] +32548 - null - [null, null, null, null, null] +32549 - null - [null, null, null, null, null] +32550 - null - [null, null, null, null, null] +32551 - null - [null, null, null, null, null] +32552 - null - [null, null, null, null, null] +32553 - null - [null, null, null, null, null] +32554 - null - [null, null, null, null, null] +32555 - null - [null, null, null, null, null] +32556 - null - [null, null, null, null, null] +32557 - null - [null, null, null, null, null] +32558 - null - [null, null, null, null, null] +32559 - null - [null, null, null, null, null] +32560 - null - [null, null, null, null, null] +32561 - null - [null, null, null, null, null] +32562 - null - [null, null, null, null, null] +32563 - null - [null, null, null, null, null] +32564 - null - [null, null, null, null, null] +32565 - null - [null, null, null, null, null] +32566 - null - [null, null, null, null, null] +32567 - null - [null, null, null, null, null] +32568 - null - [null, null, null, null, null] +32569 - null - [null, null, null, null, null] +32570 - null - [null, null, null, null, null] +32571 - null - [null, null, null, null, null] +32572 - null - [null, null, null, null, null] +32573 - null - [null, null, null, null, null] +32574 - null - [null, null, null, null, null] +32575 - null - [null, null, null, null, null] +32576 - null - [null, null, null, null, null] +32577 - null - [null, null, null, null, null] +32578 - null - [null, null, null, null, null] +32579 - null - [null, null, null, null, null] +32580 - null - [null, null, null, null, null] +32581 - null - [null, null, null, null, null] +32582 - null - [null, null, null, null, null] +32583 - null - [null, null, null, null, null] +32584 - null - [null, null, null, null, null] +32585 - null - [null, null, null, null, null] +32586 - null - [null, null, null, null, null] +32587 - null - [null, null, null, null, null] +32588 - null - [null, null, null, null, null] +32589 - null - [null, null, null, null, null] +32590 - null - [null, null, null, null, null] +32591 - null - [null, null, null, null, null] +32592 - null - [null, null, null, null, null] +32593 - null - [null, null, null, null, null] +32594 - null - [null, null, null, null, null] +32595 - null - [null, null, null, null, null] +32596 - null - [null, null, null, null, null] +32597 - null - [null, null, null, null, null] +32598 - null - [null, null, null, null, null] +32599 - null - [null, null, null, null, null] +32600 - null - [null, null, null, null, null] +32601 - null - [null, null, null, null, null] +32602 - null - [null, null, null, null, null] +32603 - null - [null, null, null, null, null] +32604 - null - [null, null, null, null, null] +32605 - null - [null, null, null, null, null] +32606 - null - [null, null, null, null, null] +32607 - null - [null, null, null, null, null] +32608 - null - [null, null, null, null, null] +32609 - null - [null, null, null, null, null] +32610 - null - [null, null, null, null, null] +32611 - null - [null, null, null, null, null] +32612 - null - [null, null, null, null, null] +32613 - null - [null, null, null, null, null] +32614 - null - [null, null, null, null, null] +32615 - null - [null, null, null, null, null] +32616 - null - [null, null, null, null, null] +32617 - null - [null, null, null, null, null] +32618 - null - [null, null, null, null, null] +32619 - null - [null, null, null, null, null] +32620 - null - [null, null, null, null, null] +32621 - null - [null, null, null, null, null] +32622 - null - [null, null, null, null, null] +32623 - null - [null, null, null, null, null] +32624 - null - [null, null, null, null, null] +32625 - null - [null, null, null, null, null] +32626 - null - [null, null, null, null, null] +32627 - null - [null, null, null, null, null] +32628 - null - [null, null, null, null, null] +32629 - null - [null, null, null, null, null] +32630 - null - [null, null, null, null, null] +32631 - null - [null, null, null, null, null] +32632 - null - [null, null, null, null, null] +32633 - null - [null, null, null, null, null] +32634 - null - [null, null, null, null, null] +32635 - null - [null, null, null, null, null] +32636 - null - [null, null, null, null, null] +32637 - null - [null, null, null, null, null] +32638 - null - [null, null, null, null, null] +32639 - null - [null, null, null, null, null] +32640 - null - [null, null, null, null, null] +32641 - null - [null, null, null, null, null] +32642 - null - [null, null, null, null, null] +32643 - null - [null, null, null, null, null] +32644 - null - [null, null, null, null, null] +32645 - null - [null, null, null, null, null] +32646 - null - [null, null, null, null, null] +32647 - null - [null, null, null, null, null] +32648 - null - [null, null, null, null, null] +32649 - null - [null, null, null, null, null] +32650 - null - [null, null, null, null, null] +32651 - null - [null, null, null, null, null] +32652 - null - [null, null, null, null, null] +32653 - null - [null, null, null, null, null] +32654 - null - [null, null, null, null, null] +32655 - null - [null, null, null, null, null] +32656 - null - [null, null, null, null, null] +32657 - null - [null, null, null, null, null] +32658 - null - [null, null, null, null, null] +32659 - null - [null, null, null, null, null] +32660 - null - [null, null, null, null, null] +32661 - null - [null, null, null, null, null] +32662 - null - [null, null, null, null, null] +32663 - null - [null, null, null, null, null] +32664 - null - [null, null, null, null, null] +32665 - null - [null, null, null, null, null] +32666 - null - [null, null, null, null, null] +32667 - null - [null, null, null, null, null] +32668 - null - [null, null, null, null, null] +32669 - null - [null, null, null, null, null] +32670 - null - [null, null, null, null, null] +32671 - null - [null, null, null, null, null] +32672 - null - [null, null, null, null, null] +32673 - null - [null, null, null, null, null] +32674 - null - [null, null, null, null, null] +32675 - null - [null, null, null, null, null] +32676 - null - [null, null, null, null, null] +32677 - null - [null, null, null, null, null] +32678 - null - [null, null, null, null, null] +32679 - null - [null, null, null, null, null] +32680 - null - [null, null, null, null, null] +32681 - null - [null, null, null, null, null] +32682 - null - [null, null, null, null, null] +32683 - null - [null, null, null, null, null] +32684 - null - [null, null, null, null, null] +32685 - null - [null, null, null, null, null] +32686 - null - [null, null, null, null, null] +32687 - null - [null, null, null, null, null] +32688 - null - [null, null, null, null, null] +32689 - null - [null, null, null, null, null] +32690 - null - [null, null, null, null, null] +32691 - null - [null, null, null, null, null] +32692 - null - [null, null, null, null, null] +32693 - null - [null, null, null, null, null] +32694 - null - [null, null, null, null, null] +32695 - null - [null, null, null, null, null] +32696 - Obstacle pipe - [null, null, null, null, null] +32697 - Obstacle pipe - [null, null, null, null, null] +32698 - Obstacle pipe - [null, null, null, null, null] +32699 - null - [null, null, null, null, null] +32700 - null - [null, null, null, null, null] +32701 - null - [null, null, null, null, null] +32702 - null - [null, null, null, null, null] +32703 - null - [null, null, null, null, null] +32704 - null - [null, null, null, null, null] +32705 - null - [null, null, null, null, null] +32706 - null - [null, null, null, null, null] +32707 - null - [null, null, null, null, null] +32708 - null - [null, null, null, null, null] +32709 - null - [null, null, null, null, null] +32710 - null - [null, null, null, null, null] +32711 - Door - [Open, null, null, null, null] +32712 - null - [null, null, null, null, null] +32713 - null - [null, null, null, null, null] +32714 - null - [null, null, null, null, null] +32715 - null - [null, null, null, null, null] +32716 - null - [null, null, null, null, null] +32717 - null - [null, null, null, null, null] +32718 - null - [null, null, null, null, null] +32719 - null - [null, null, null, null, null] +32720 - null - [null, null, null, null, null] +32721 - null - [null, null, null, null, null] +32722 - null - [null, null, null, null, null] +32723 - null - [null, null, null, null, null] +32724 - null - [null, null, null, null, null] +32725 - null - [null, null, null, null, null] +32726 - null - [null, null, null, null, null] +32727 - null - [null, null, null, null, null] +32728 - null - [null, null, null, null, null] +32729 - null - [null, null, null, null, null] +32730 - null - [null, null, null, null, null] +32731 - null - [null, null, null, null, null] +32732 - null - [null, null, null, null, null] +32733 - null - [null, null, null, null, null] +32734 - null - [null, null, null, null, null] +32735 - null - [null, null, null, null, null] +32736 - null - [null, null, null, null, null] +32737 - Cave Exit - [Exit, null, null, null, null] +32738 - Cave Exit - [Exit, null, null, null, null] +32739 - null - [null, null, null, null, null] +32740 - null - [null, null, null, null, null] +32741 - null - [null, null, null, null, null] +32742 - null - [null, null, null, null, null] +32743 - Cave Exit - [Exit, null, null, null, null] +32744 - null - [null, null, null, null, null] +32745 - null - [null, null, null, null, null] +32746 - null - [null, null, null, null, null] +32747 - null - [null, null, null, null, null] +32748 - null - [null, null, null, null, null] +32749 - null - [null, null, null, null, null] +32750 - null - [null, null, null, null, null] +32751 - null - [null, null, null, null, null] +32752 - null - [null, null, null, null, null] +32753 - null - [null, null, null, null, null] +32754 - null - [null, null, null, null, null] +32755 - null - [null, null, null, null, null] +32756 - null - [null, null, null, null, null] +32757 - null - [null, null, null, null, null] +32758 - null - [null, null, null, null, null] +32759 - null - [null, null, null, null, null] +32760 - null - [null, null, null, null, null] +32761 - null - [null, null, null, null, null] +32762 - null - [null, null, null, null, null] +32763 - null - [null, null, null, null, null] +32764 - null - [null, null, null, null, null] +32765 - null - [null, null, null, null, null] +32766 - Old spike - [null, null, null, null, null] +32767 - Old spike - [null, null, null, null, null] +32768 - null - [null, null, null, null, null] +32769 - null - [null, null, null, null, null] +32770 - null - [null, null, null, null, null] +32771 - Rope - [null, null, null, null, null] +32772 - Rope - [null, null, null, null, null] +32773 - null - [null, null, null, null, null] +32774 - null - [null, null, null, null, null] +32775 - null - [null, null, null, null, null] +32776 - null - [null, null, null, null, null] +32777 - null - [null, null, null, null, null] +32778 - null - [null, null, null, null, null] +32779 - null - [null, null, null, null, null] +32780 - null - [null, null, null, null, null] +32781 - null - [null, null, null, null, null] +32782 - null - [null, null, null, null, null] +32783 - null - [null, null, null, null, null] +32784 - null - [null, null, null, null, null] +32785 - null - [null, null, null, null, null] +32786 - null - [null, null, null, null, null] +32787 - null - [null, null, null, null, null] +32788 - null - [null, null, null, null, null] +32789 - null - [null, null, null, null, null] +32790 - null - [null, null, null, null, null] +32791 - null - [null, null, null, null, null] +32792 - null - [null, null, null, null, null] +32793 - null - [null, null, null, null, null] +32794 - null - [null, null, null, null, null] +32795 - null - [null, null, null, null, null] +32796 - null - [null, null, null, null, null] +32797 - null - [null, null, null, null, null] +32798 - null - [null, null, null, null, null] +32799 - null - [null, null, null, null, null] +32800 - null - [null, null, null, null, null] +32801 - null - [null, null, null, null, null] +32802 - null - [null, null, null, null, null] +32803 - null - [null, null, null, null, null] +32804 - null - [null, null, null, null, null] +32805 - null - [null, null, null, null, null] +32806 - null - [null, null, null, null, null] +32807 - null - [null, null, null, null, null] +32808 - null - [null, null, null, null, null] +32809 - null - [null, null, null, null, null] +32810 - null - [null, null, null, null, null] +32811 - null - [null, null, null, null, null] +32812 - null - [null, null, null, null, null] +32813 - null - [null, null, null, null, null] +32814 - null - [null, null, null, null, null] +32815 - null - [null, null, null, null, null] +32816 - null - [null, null, null, null, null] +32817 - null - [null, null, null, null, null] +32818 - null - [null, null, null, null, null] +32819 - null - [null, null, null, null, null] +32820 - null - [null, null, null, null, null] +32821 - null - [null, null, null, null, null] +32822 - null - [null, null, null, null, null] +32823 - null - [null, null, null, null, null] +32824 - null - [null, null, null, null, null] +32825 - null - [null, null, null, null, null] +32826 - null - [null, null, null, null, null] +32827 - null - [null, null, null, null, null] +32828 - null - [null, null, null, null, null] +32829 - null - [null, null, null, null, null] +32830 - null - [null, null, null, null, null] +32831 - null - [null, null, null, null, null] +32832 - null - [null, null, null, null, null] +32833 - null - [null, null, null, null, null] +32834 - null - [null, null, null, null, null] +32835 - Stairs - [Walk-down, null, null, null, null] +32836 - Stairs - [Walk-up, null, null, null, null] +32837 - null - [null, null, null, null, null] +32838 - null - [null, null, null, null, null] +32839 - null - [null, null, null, null, null] +32840 - null - [null, null, null, null, null] +32841 - null - [null, null, null, null, null] +32842 - null - [null, null, null, null, null] +32843 - null - [null, null, null, null, null] +32844 - null - [null, null, null, null, null] +32845 - null - [null, null, null, null, null] +32846 - null - [null, null, null, null, null] +32847 - null - [null, null, null, null, null] +32848 - null - [null, null, null, null, null] +32849 - null - [null, null, null, null, null] +32850 - null - [null, null, null, null, null] +32851 - null - [null, null, null, null, null] +32852 - null - [null, null, null, null, null] +32853 - null - [null, null, null, null, null] +32854 - null - [null, null, null, null, null] +32855 - null - [null, null, null, null, null] +32856 - null - [null, null, null, null, null] +32857 - null - [null, null, null, null, null] +32858 - null - [null, null, null, null, null] +32859 - null - [null, null, null, null, null] +32860 - null - [null, null, null, null, null] +32861 - null - [null, null, null, null, null] +32862 - null - [null, null, null, null, null] +32863 - null - [null, null, null, null, null] +32864 - null - [null, null, null, null, null] +32865 - null - [null, null, null, null, null] +32866 - null - [null, null, null, null, null] +32867 - null - [null, null, null, null, null] +32868 - null - [null, null, null, null, null] +32869 - null - [null, null, null, null, null] +32870 - null - [null, null, null, null, null] +32871 - null - [null, null, null, null, null] +32872 - null - [null, null, null, null, null] +32873 - null - [null, null, null, null, null] +32874 - null - [null, null, null, null, null] +32875 - null - [null, null, null, null, null] +32876 - null - [null, null, null, null, null] +32877 - null - [null, null, null, null, null] +32878 - null - [null, null, null, null, null] +32879 - null - [null, null, null, null, null] +32880 - null - [null, null, null, null, null] +32881 - null - [null, null, null, null, null] +32882 - null - [null, null, null, null, null] +32883 - null - [null, null, null, null, null] +32884 - null - [null, null, null, null, null] +32885 - null - [null, null, null, null, null] +32886 - null - [null, null, null, null, null] +32887 - null - [null, null, null, null, null] +32888 - null - [null, null, null, null, null] +32889 - null - [null, null, null, null, null] +32890 - null - [null, null, null, null, null] +32891 - Roots - [null, null, null, null, null] +32892 - null - [null, null, null, null, null] +32893 - Roots - [null, null, null, null, null] +32894 - null - [null, null, null, null, null] +32895 - Roots - [null, null, null, null, null] +32896 - null - [null, null, null, null, null] +32897 - Elven lamp - [null, null, null, null, null] +32898 - null - [null, null, null, null, null] +32899 - null - [null, null, null, null, null] +32900 - null - [null, null, null, null, null] +32901 - null - [null, null, null, null, null] +32902 - null - [null, null, null, null, null] +32903 - null - [null, null, null, null, null] +32904 - null - [null, null, null, null, null] +32905 - null - [null, null, null, null, null] +32906 - null - [null, null, null, null, null] +32907 - null - [null, null, null, null, null] +32908 - null - [null, null, null, null, null] +32909 - null - [null, null, null, null, null] +32910 - null - [null, null, null, null, null] +32911 - null - [null, null, null, null, null] +32912 - null - [null, null, null, null, null] +32913 - null - [null, null, null, null, null] +32914 - null - [null, null, null, null, null] +32915 - null - [null, null, null, null, null] +32916 - null - [null, null, null, null, null] +32917 - null - [null, null, null, null, null] +32918 - null - [null, null, null, null, null] +32919 - null - [null, null, null, null, null] +32920 - null - [null, null, null, null, null] +32921 - null - [null, null, null, null, null] +32922 - null - [null, null, null, null, null] +32923 - null - [null, null, null, null, null] +32924 - null - [null, null, null, null, null] +32925 - null - [null, null, null, null, null] +32926 - null - [null, null, null, null, null] +32927 - null - [null, null, null, null, null] +32928 - null - [null, null, null, null, null] +32929 - null - [null, null, null, null, null] +32930 - null - [null, null, null, null, null] +32931 - null - [null, null, null, null, null] +32932 - null - [null, null, null, null, null] +32933 - null - [null, null, null, null, null] +32934 - null - [null, null, null, null, null] +32935 - null - [null, null, null, null, null] +32936 - null - [null, null, null, null, null] +32937 - null - [null, null, null, null, null] +32938 - null - [null, null, null, null, null] +32939 - null - [null, null, null, null, null] +32940 - null - [null, null, null, null, null] +32941 - null - [null, null, null, null, null] +32942 - null - [null, null, null, null, null] +32943 - null - [null, null, null, null, null] +32944 - Tunnel - [Enter, null, null, null, null] +32945 - null - [null, null, null, null, null] +32946 - null - [null, null, null, null, null] +32947 - null - [null, null, null, null, null] +32948 - null - [null, null, null, null, null] +32949 - null - [null, null, null, null, null] +32950 - null - [null, null, null, null, null] +32951 - null - [null, null, null, null, null] +32952 - Door - [Open, null, null, null, null] +32953 - Door - [Open, null, null, null, null] +32954 - Door - [Open, null, null, null, null] +32955 - Door - [Open, null, null, null, null] +32956 - null - [null, null, null, null, null] +32957 - null - [null, null, null, null, null] +32958 - null - [null, null, null, null, null] +32959 - null - [null, null, null, null, null] +32960 - null - [null, null, null, null, null] +32961 - null - [null, null, null, null, null] +32962 - null - [null, null, null, null, null] +32963 - null - [null, null, null, null, null] +32964 - null - [null, null, null, null, null] +32965 - null - [null, null, null, null, null] +32966 - null - [null, null, null, null, null] +32967 - null - [null, null, null, null, null] +32968 - Exit door - [Open, null, null, null, null] +32969 - null - [null, null, null, null, null] +32970 - null - [null, null, null, null, null] +32971 - null - [null, null, null, null, null] +32972 - null - [null, null, null, null, null] +32973 - null - [null, null, null, null, null] +32974 - null - [null, null, null, null, null] +32975 - null - [null, null, null, null, null] +32976 - null - [null, null, null, null, null] +32977 - null - [null, null, null, null, null] +32978 - null - [null, null, null, null, null] +32979 - null - [null, null, null, null, null] +32980 - null - [null, null, null, null, null] +32981 - null - [null, null, null, null, null] +32982 - null - [null, null, null, null, null] +32983 - null - [null, null, null, null, null] +32984 - null - [null, null, null, null, null] +32985 - null - [null, null, null, null, null] +32986 - null - [null, null, null, null, null] +32987 - null - [null, null, null, null, null] +32988 - null - [null, null, null, null, null] +32989 - null - [null, null, null, null, null] +32990 - null - [null, null, null, null, null] +32991 - null - [null, null, null, null, null] +32992 - null - [null, null, null, null, null] +32993 - null - [null, null, null, null, null] +32994 - null - [null, null, null, null, null] +32995 - null - [null, null, null, null, null] +32996 - null - [null, null, null, null, null] +32997 - null - [null, null, null, null, null] +32998 - null - [null, null, null, null, null] +32999 - null - [null, null, null, null, null] +33000 - null - [null, null, null, null, null] +33001 - null - [null, null, null, null, null] +33002 - null - [null, null, null, null, null] +33003 - null - [null, null, null, null, null] +33004 - null - [null, null, null, null, null] +33005 - null - [null, null, null, null, null] +33006 - null - [null, null, null, null, null] +33007 - null - [null, null, null, null, null] +33008 - null - [null, null, null, null, null] +33009 - null - [null, null, null, null, null] +33010 - null - [null, null, null, null, null] +33011 - null - [null, null, null, null, null] +33012 - null - [null, null, null, null, null] +33013 - null - [null, null, null, null, null] +33014 - null - [null, null, null, null, null] +33015 - null - [null, null, null, null, null] +33016 - null - [null, null, null, null, null] +33017 - null - [null, null, null, null, null] +33018 - Entrance - [Enter, null, null, null, null] +33019 - null - [null, null, null, null, null] +33020 - null - [null, null, null, null, null] +33021 - null - [null, null, null, null, null] +33022 - null - [null, null, null, null, null] +33023 - null - [null, null, null, null, null] +33024 - null - [null, null, null, null, null] +33025 - null - [null, null, null, null, null] +33026 - null - [null, null, null, null, null] +33027 - null - [null, null, null, null, null] +33028 - null - [null, null, null, null, null] +33029 - null - [null, null, null, null, null] +33030 - null - [null, null, null, null, null] +33031 - null - [null, null, null, null, null] +33032 - null - [null, null, null, null, null] +33033 - null - [null, null, null, null, null] +33034 - null - [null, null, null, null, null] +33035 - null - [null, null, null, null, null] +33036 - null - [null, null, null, null, null] +33037 - null - [null, null, null, null, null] +33038 - null - [null, null, null, null, null] +33039 - null - [null, null, null, null, null] +33040 - null - [null, null, null, null, null] +33041 - null - [null, null, null, null, null] +33042 - null - [null, null, null, null, null] +33043 - null - [null, null, null, null, null] +33044 - null - [null, null, null, null, null] +33045 - null - [null, null, null, null, null] +33046 - Closed chest - [Open, null, null, null, null] +33047 - Open chest - [Search, Close, null, null, null] +33048 - null - [null, null, null, null, null] +33049 - Rubble - [Search, null, null, null, null] +33050 - Fire remains - [null, null, null, null, null] +33051 - Stool - [null, null, null, null, null] +33052 - Table - [null, null, null, null, null] +33053 - null - [null, null, null, null, null] +33054 - Table - [null, null, null, null, null] +33055 - Bed - [null, null, null, null, null] +33056 - Bookcase - [Search, null, null, null, null] +33057 - Bookcase - [Search, null, null, null, null] +33058 - Chair - [null, null, null, null, null] +33059 - null - [null, null, null, null, null] +33060 - Large door - [Open, null, null, null, null] +33061 - Mirror - [null, null, null, null, null] +33062 - Cabinet - [Open, null, null, null, null] +33063 - Cabinet - [null, Search, Close, null, null] +33064 - Hanging banner - [null, null, null, null, null] +33065 - Hanging banner - [null, null, null, null, null] +33066 - Glarial's tomb - [Search, null, null, null, null] +33067 - null - [null, null, null, null, null] +33068 - null - [null, null, null, null, null] +33069 - null - [null, null, null, null, null] +33070 - null - [null, null, null, null, null] +33071 - null - [null, null, null, null, null] +33072 - null - [null, null, null, null, null] +33073 - null - [null, null, null, null, null] +33074 - null - [null, null, null, null, null] +33075 - null - [null, null, null, null, null] +33076 - null - [null, null, null, null, null] +33077 - null - [null, null, null, null, null] +33078 - Rocks - [Mine, Prospect, hidden, null, null] +33079 - Rocks - [Mine, Prospect, hidden, null, null] +33080 - Roots - [null, null, null, null, null] +33081 - Roots - [null, null, null, null, null] +33082 - Roots - [null, null, null, null, null] +33083 - null - [null, null, null, null, null] +33084 - null - [null, null, null, null, null] +33085 - null - [null, null, null, null, null] +33086 - null - [null, null, null, null, null] +33087 - null - [null, null, null, null, null] +33088 - null - [null, null, null, null, null] +33089 - null - [null, null, null, null, null] +33090 - null - [null, null, null, null, null] +33091 - null - [null, null, null, null, null] +33092 - null - [null, null, null, null, null] +33093 - null - [null, null, null, null, null] +33094 - null - [null, null, null, null, null] +33095 - null - [null, null, null, null, null] +33096 - null - [null, null, null, null, null] +33097 - null - [null, null, null, null, null] +33098 - null - [null, null, null, null, null] +33099 - null - [null, null, null, null, null] +33100 - null - [null, null, null, null, null] +33101 - null - [null, null, null, null, null] +33102 - null - [null, null, null, null, null] +33103 - null - [null, null, null, null, null] +33104 - null - [null, null, null, null, null] +33105 - null - [null, null, null, null, null] +33106 - null - [null, null, null, null, null] +33107 - null - [null, null, null, null, null] +33108 - Door - [Open, null, null, null, null] +33109 - Door - [Open, null, null, null, null] +33110 - Door - [Open, null, null, null, null] +33111 - Door - [Open, null, null, null, null] +33112 - null - [null, null, null, null, null] +33113 - null - [null, null, null, null, null] +33114 - null - [null, null, null, null, null] +33115 - null - [null, null, null, null, null] +33116 - null - [null, null, null, null, null] +33117 - null - [null, null, null, null, null] +33118 - null - [null, null, null, null, null] +33119 - null - [null, null, null, null, null] +33120 - Barrel - [null, null, null, null, null] +33121 - Barrel - [null, null, null, null, null] +33122 - null - [null, null, null, null, null] +33123 - null - [null, null, null, null, null] +33124 - Barrel - [null, null, null, null, null] +33125 - null - [null, null, null, null, null] +33126 - null - [null, null, null, null, null] +33127 - null - [null, null, null, null, null] +33128 - Counter - [null, null, null, null, null] +33129 - Table - [null, null, null, null, null] +33130 - null - [null, null, null, null, null] +33131 - null - [null, null, null, null, null] +33132 - null - [null, null, null, null, null] +33133 - null - [null, null, null, null, null] +33134 - null - [null, null, null, null, null] +33135 - null - [null, null, null, null, null] +33136 - null - [null, null, null, null, null] +33137 - null - [null, null, null, null, null] +33138 - null - [null, null, null, null, null] +33139 - null - [null, null, null, null, null] +33140 - null - [null, null, null, null, null] +33141 - null - [null, null, null, null, null] +33142 - null - [null, null, null, null, null] +33143 - null - [null, null, null, null, null] +33144 - null - [null, null, null, null, null] +33145 - null - [null, null, null, null, null] +33146 - null - [null, null, null, null, null] +33147 - null - [null, null, null, null, null] +33148 - null - [null, null, null, null, null] +33149 - null - [null, null, null, null, null] +33150 - null - [null, null, null, null, null] +33151 - null - [null, null, null, null, null] +33152 - null - [null, null, null, null, null] +33153 - null - [null, null, null, null, null] +33154 - null - [null, null, null, null, null] +33155 - null - [null, null, null, null, null] +33156 - null - [null, null, null, null, null] +33157 - null - [null, null, null, null, null] +33158 - null - [null, null, null, null, null] +33159 - Table - [null, null, null, null, null] +33160 - null - [null, null, null, null, null] +33161 - null - [null, null, null, null, null] +33162 - null - [null, null, null, null, null] +33163 - null - [null, null, null, null, null] +33164 - null - [null, null, null, null, null] +33165 - null - [null, null, null, null, null] +33166 - null - [null, null, null, null, null] +33167 - null - [null, null, null, null, null] +33168 - null - [null, null, null, null, null] +33169 - null - [null, null, null, null, null] +33170 - null - [null, null, null, null, null] +33171 - null - [null, null, null, null, null] +33172 - null - [null, null, null, null, null] +33173 - Cave - [Exit, null, null, null, null] +33174 - Icy Cavern - [Enter, null, null, null, null] +33175 - null - [null, null, null, null, null] +33176 - null - [null, null, null, null, null] +33177 - null - [null, null, null, null, null] +33178 - null - [null, null, null, null, null] +33179 - null - [null, null, null, null, null] +33180 - null - [null, null, null, null, null] +33181 - null - [null, null, null, null, null] +33182 - null - [null, null, null, null, null] +33183 - Ice Light - [null, null, null, null, null] +33184 - Ladder - [Climb-up, null, null, null, null] +33185 - Crevasse - [Enter, null, null, null, null] +33186 - null - [null, null, null, null, null] +33187 - Suit of armour - [null, null, null, null, null] +33188 - Wallshield - [null, null, null, null, null] +33189 - Wallshield - [null, null, null, null, null] +33190 - Wallshield - [null, null, null, null, null] +33191 - Wallshield - [null, null, null, null, null] +33192 - Bow cabinet - [null, null, null, null, null] +33193 - Chair - [null, null, null, null, null] +33194 - Chair - [null, null, null, null, null] +33195 - Chair - [null, null, null, null, null] +33196 - Chair - [null, null, null, null, null] +33197 - Bench - [null, null, null, null, null] +33198 - null - [null, null, null, null, null] +33199 - null - [null, null, null, null, null] +33200 - null - [null, null, null, null, null] +33201 - Table - [null, null, null, null, null] +33202 - Table - [null, null, null, null, null] +33203 - null - [null, null, null, null, null] +33204 - null - [null, null, null, null, null] +33205 - null - [null, null, null, null, null] +33206 - null - [null, null, null, null, null] +33207 - null - [null, null, null, null, null] +33208 - null - [null, null, null, null, null] +33209 - null - [null, null, null, null, null] +33210 - null - [null, null, null, null, null] +33211 - null - [null, null, null, null, null] +33212 - null - [null, null, null, null, null] +33213 - null - [null, null, null, null, null] +33214 - null - [null, null, null, null, null] +33215 - null - [null, null, null, null, null] +33216 - Corpse - [null, null, null, null, null] +33217 - Corpse - [null, null, null, null, null] +33218 - Corpse - [null, null, null, null, null] +33219 - Corpse - [null, null, null, null, null] +33220 - Rocks - [Mine, Prospect, hidden, null, null] +33221 - Rocks - [Mine, Prospect, hidden, null, null] +33222 - Rocks - [Mine, Prospect, hidden, null, null] +33223 - Rocks - [Mine, Prospect, hidden, null, null] +33224 - Cabinet - [null, null, null, null, null] +33225 - null - [null, null, null, null, null] +33226 - null - [null, null, null, null, null] +33227 - null - [null, null, null, null, null] +33228 - null - [null, null, null, null, null] +33229 - null - [null, null, null, null, null] +33230 - Candles - [null, null, null, null, null] +33231 - Cabinet - [null, null, null, null, null] +33232 - Stairs - [Climb-up, null, null, null, null] +33233 - Table - [null, null, null, null, null] +33234 - null - [null, null, null, null, null] +33235 - null - [null, null, null, null, null] +33236 - null - [null, null, null, null, null] +33237 - Web - [Slash, null, null, null, null] +33238 - Slashed web - [null, null, null, null, null] +33239 - null - [null, null, null, null, null] +33240 - null - [null, null, null, null, null] +33241 - null - [null, null, null, null, null] +33242 - null - [null, null, null, null, null] +33243 - null - [null, null, null, null, null] +33244 - Wall opening - [Enter, null, null, null, null] +33245 - Wall - [Push, null, null, null, null] +33246 - Exit - [Climb-up, null, null, null, null] +33247 - null - [null, null, null, null, null] +33248 - null - [null, null, null, null, null] +33249 - null - [null, null, null, null, null] +33250 - Lever - [Pull, null, null, null, null] +33251 - Lever - [Pull, null, null, null, null] +33252 - null - [null, null, null, null, null] +33253 - - [null, null, null, null, null] +33254 - null - [null, null, null, null, null] +33255 - null - [null, null, null, null, null] +33256 - null - [null, null, null, null, null] +33257 - null - [null, null, null, null, null] +33258 - null - [null, null, null, null, null] +33259 - null - [null, null, null, null, null] +33260 - null - [null, null, null, null, null] +33261 - Wall - [null, null, null, null, null] +33262 - null - [null, null, null, null, null] +33263 - Cart Track - [null, null, null, null, null] +33264 - null - [null, null, null, null, null] +33265 - null - [null, null, null, null, null] +33266 - null - [null, null, null, null, null] +33267 - null - [null, null, null, null, null] +33268 - null - [null, null, null, null, null] +33269 - null - [null, null, null, null, null] +33270 - null - [null, null, null, null, null] +33271 - null - [null, null, null, null, null] +33272 - null - [null, null, null, null, null] +33273 - null - [null, null, null, null, null] +33274 - null - [null, null, null, null, null] +33275 - null - [null, null, null, null, null] +33276 - null - [null, null, null, null, null] +33277 - null - [null, null, null, null, null] +33278 - null - [null, null, null, null, null] +33279 - null - [null, null, null, null, null] +33280 - null - [null, null, null, null, null] +33281 - null - [null, null, null, null, null] +33282 - null - [null, null, null, null, null] +33283 - null - [null, null, null, null, null] +33284 - null - [null, null, null, null, null] +33285 - null - [null, null, null, null, null] +33286 - null - [null, null, null, null, null] +33287 - null - [null, null, null, null, null] +33288 - null - [null, null, null, null, null] +33289 - null - [null, null, null, null, null] +33290 - null - [null, null, null, null, null] +33291 - null - [null, null, null, null, null] +33292 - null - [null, null, null, null, null] +33293 - null - [null, null, null, null, null] +33294 - null - [null, null, null, null, null] +33295 - null - [null, null, null, null, null] +33296 - null - [null, null, null, null, null] +33297 - null - [null, null, null, null, null] +33298 - null - [null, null, null, null, null] +33299 - null - [null, null, null, null, null] +33300 - null - [null, null, null, null, null] +33301 - null - [null, null, null, null, null] +33302 - null - [null, null, null, null, null] +33303 - null - [null, null, null, null, null] +33304 - null - [null, null, null, null, null] +33305 - null - [null, null, null, null, null] +33306 - null - [null, null, null, null, null] +33307 - null - [null, null, null, null, null] +33308 - null - [null, null, null, null, null] +33309 - null - [null, null, null, null, null] +33310 - null - [null, null, null, null, null] +33311 - null - [null, null, null, null, null] +33312 - null - [null, null, null, null, null] +33313 - null - [null, null, null, null, null] +33314 - null - [null, null, null, null, null] +33315 - null - [null, null, null, null, null] +33316 - null - [null, null, null, null, null] +33317 - null - [null, null, null, null, null] +33318 - null - [null, null, null, null, null] +33319 - null - [null, null, null, null, null] +33320 - null - [null, null, null, null, null] +33321 - null - [null, null, null, null, null] +33322 - null - [null, null, null, null, null] +33323 - null - [null, null, null, null, null] +33324 - null - [null, null, null, null, null] +33325 - null - [null, null, null, null, null] +33326 - null - [null, null, null, null, null] +33327 - null - [null, null, null, null, null] +33328 - null - [null, null, null, null, null] +33329 - null - [null, null, null, null, null] +33330 - null - [null, null, null, null, null] +33331 - null - [null, null, null, null, null] +33332 - null - [null, null, null, null, null] +33333 - null - [null, null, null, null, null] +33334 - null - [null, null, null, null, null] +33335 - null - [null, null, null, null, null] +33336 - null - [null, null, null, null, null] +33337 - null - [null, null, null, null, null] +33338 - null - [null, null, null, null, null] +33339 - null - [null, null, null, null, null] +33340 - null - [null, null, null, null, null] +33341 - null - [null, null, null, null, null] +33342 - null - [null, null, null, null, null] +33343 - null - [null, null, null, null, null] +33344 - null - [null, null, null, null, null] +33345 - null - [null, null, null, null, null] +33346 - null - [null, null, null, null, null] +33347 - null - [null, null, null, null, null] +33348 - null - [null, null, null, null, null] +33349 - null - [null, null, null, null, null] +33350 - null - [null, null, null, null, null] +33351 - null - [null, null, null, null, null] +33352 - null - [null, null, null, null, null] +33353 - null - [null, null, null, null, null] +33354 - null - [null, null, null, null, null] +33355 - null - [null, null, null, null, null] +33356 - null - [null, null, null, null, null] +33357 - null - [null, null, null, null, null] +33358 - null - [null, null, null, null, null] +33359 - null - [null, null, null, null, null] +33360 - null - [null, null, null, null, null] +33361 - null - [null, null, null, null, null] +33362 - null - [null, null, null, null, null] +33363 - null - [null, null, null, null, null] +33364 - null - [null, null, null, null, null] +33365 - null - [null, null, null, null, null] +33366 - null - [null, null, null, null, null] +33367 - null - [null, null, null, null, null] +33368 - null - [null, null, null, null, null] +33369 - null - [null, null, null, null, null] +33370 - null - [null, null, null, null, null] +33371 - null - [null, null, null, null, null] +33372 - null - [null, null, null, null, null] +33373 - null - [null, null, null, null, null] +33374 - null - [null, null, null, null, null] +33375 - null - [null, null, null, null, null] +33376 - null - [null, null, null, null, null] +33377 - null - [null, null, null, null, null] +33378 - null - [null, null, null, null, null] +33379 - null - [null, null, null, null, null] +33380 - null - [null, null, null, null, null] +33381 - null - [null, null, null, null, null] +33382 - Icicle - [null, null, null, null, null] +33383 - Icicle - [null, null, null, null, null] +33384 - Icicle - [null, null, null, null, null] +33385 - snowrock - [null, null, null, null, null] +33386 - snowrock - [null, null, null, null, null] +33387 - snowrock - [null, null, null, null, null] +33388 - snowrock - [null, null, null, null, null] +33389 - null - [null, null, null, null, null] +33390 - null - [null, null, null, null, null] +33391 - null - [null, null, null, null, null] +33392 - null - [null, null, null, null, null] +33393 - null - [null, null, null, null, null] +33394 - null - [null, null, null, null, null] +33395 - null - [null, null, null, null, null] +33396 - null - [null, null, null, null, null] +33397 - null - [null, null, null, null, null] +33398 - Pillar - [null, null, null, null, null] +33399 - Pillar - [null, null, null, null, null] +33400 - Rocks - [Mine, Prospect, hidden, null, null] +33401 - Rocks - [Mine, Prospect, hidden, null, null] +33402 - Rocks - [Mine, Prospect, hidden, null, null] +33403 - null - [null, null, null, null, null] +33404 - null - [null, null, null, null, null] +33405 - null - [null, null, null, null, null] +33406 - null - [null, null, null, null, null] +33407 - null - [null, null, null, null, null] +33408 - null - [null, null, null, null, null] +33409 - null - [null, null, null, null, null] +33410 - null - [null, null, null, null, null] +33411 - null - [null, null, null, null, null] +33412 - null - [null, null, null, null, null] +33413 - null - [null, null, null, null, null] +33414 - null - [null, null, null, null, null] +33415 - null - [null, null, null, null, null] +33416 - null - [null, null, null, null, null] +33417 - null - [null, null, null, null, null] +33418 - null - [null, null, null, null, null] +33419 - null - [null, null, null, null, null] +33420 - null - [null, null, null, null, null] +33421 - null - [null, null, null, null, null] +33422 - null - [null, null, null, null, null] +33423 - null - [null, null, null, null, null] +33424 - null - [null, null, null, null, null] +33425 - null - [null, null, null, null, null] +33426 - null - [null, null, null, null, null] +33427 - null - [null, null, null, null, null] +33428 - null - [null, null, null, null, null] +33429 - null - [null, null, null, null, null] +33430 - null - [null, null, null, null, null] +33431 - null - [null, null, null, null, null] +33432 - null - [null, null, null, null, null] +33433 - null - [null, null, null, null, null] +33434 - Window - [null, null, null, null, null] +33435 - null - [null, null, null, null, null] +33436 - null - [null, null, null, null, null] +33437 - null - [null, null, null, null, null] +33438 - null - [null, null, null, null, null] +33439 - null - [null, null, null, null, null] +33440 - null - [null, null, null, null, null] +33441 - null - [null, null, null, null, null] +33442 - null - [null, null, null, null, null] +33443 - null - [null, null, null, null, null] +33444 - null - [null, null, null, null, null] +33445 - null - [null, null, null, null, null] +33446 - null - [null, null, null, null, null] +33447 - null - [null, null, null, null, null] +33448 - null - [null, null, null, null, null] +33449 - null - [null, null, null, null, null] +33450 - null - [null, null, null, null, null] +33451 - null - [null, null, null, null, null] +33452 - null - [null, null, null, null, null] +33453 - null - [null, null, null, null, null] +33454 - null - [null, null, null, null, null] +33455 - null - [null, null, null, null, null] +33456 - null - [null, null, null, null, null] +33457 - null - [null, null, null, null, null] +33458 - Sink - [null, null, null, null, null] +33459 - null - [null, null, null, null, null] +33460 - null - [null, null, null, null, null] +33461 - Drawers - [Open, null, null, null, null] +33462 - Drawers - [null, Search, Shut, null, null] +33463 - Dresser - [null, null, null, null, null] +33464 - null - [null, null, null, null, null] +33465 - null - [null, null, null, null, null] +33466 - null - [null, null, null, null, null] +33467 - null - [null, null, null, null, null] +33468 - null - [null, null, null, null, null] +33469 - null - [null, null, null, null, null] +33470 - null - [null, null, null, null, null] +33471 - null - [null, null, null, null, null] +33472 - Oil lamp - [null, null, null, null, null] +33473 - null - [null, null, null, null, null] +33474 - null - [null, null, null, null, null] +33475 - null - [null, null, null, null, null] +33476 - null - [null, null, null, null, null] +33477 - null - [null, null, null, null, null] +33478 - null - [null, null, null, null, null] +33479 - null - [null, null, null, null, null] +33480 - null - [null, null, null, null, null] +33481 - null - [null, null, null, null, null] +33482 - null - [null, null, null, null, null] +33483 - null - [null, null, null, null, null] +33484 - null - [null, null, null, null, null] +33485 - null - [null, null, null, null, null] +33486 - null - [null, null, null, null, null] +33487 - null - [null, null, null, null, null] +33488 - Chest - [Open, null, null, null, null] +33489 - null - [null, null, null, null, null] +33490 - null - [null, null, null, null, null] +33491 - null - [null, null, null, null, null] +33492 - null - [null, null, null, null, null] +33493 - null - [null, null, null, null, null] +33494 - null - [null, null, null, null, null] +33495 - null - [null, null, null, null, null] +33496 - null - [null, null, null, null, null] +33497 - null - [null, null, null, null, null] +33498 - Fireplace - [null, null, null, null, null] +33499 - Cooking pot - [null, null, null, null, null] +33500 - Range - [null, null, null, null, null] +33501 - null - [null, null, null, null, null] +33502 - Cupboard - [Open, null, null, null, null] +33503 - Cupboard - [Search, Close, null, null, null] +33504 - null - [null, null, null, null, null] +33505 - null - [null, null, null, null, null] +33506 - null - [null, null, null, null, null] +33507 - null - [null, null, null, null, null] +33508 - null - [null, null, null, null, null] +33509 - null - [null, null, null, null, null] +33510 - null - [null, null, null, null, null] +33511 - null - [null, null, null, null, null] +33512 - null - [null, null, null, null, null] +33513 - null - [null, null, null, null, null] +33514 - null - [null, null, null, null, null] +33515 - null - [null, null, null, null, null] +33516 - null - [null, null, null, null, null] +33517 - null - [null, null, null, null, null] +33518 - null - [null, null, null, null, null] +33519 - null - [null, null, null, null, null] +33520 - null - [null, null, null, null, null] +33521 - null - [null, null, null, null, null] +33522 - null - [null, null, null, null, null] +33523 - null - [null, null, null, null, null] +33524 - null - [null, null, null, null, null] +33525 - null - [null, null, null, null, null] +33526 - null - [null, null, null, null, null] +33527 - null - [null, null, null, null, null] +33528 - null - [null, null, null, null, null] +33529 - null - [null, null, null, null, null] +33530 - null - [null, null, null, null, null] +33531 - null - [null, null, null, null, null] +33532 - null - [null, null, null, null, null] +33533 - null - [null, null, null, null, null] +33534 - null - [null, null, null, null, null] +33535 - null - [null, null, null, null, null] +33536 - null - [null, null, null, null, null] +33537 - null - [null, null, null, null, null] +33538 - null - [null, null, null, null, null] +33539 - null - [null, null, null, null, null] +33540 - null - [null, null, null, null, null] +33541 - null - [null, null, null, null, null] +33542 - null - [null, null, null, null, null] +33543 - null - [null, null, null, null, null] +33544 - null - [null, null, null, null, null] +33545 - null - [null, null, null, null, null] +33546 - null - [null, null, null, null, null] +33547 - null - [null, null, null, null, null] +33548 - null - [null, null, null, null, null] +33549 - null - [null, null, null, null, null] +33550 - null - [null, null, null, null, null] +33551 - null - [null, null, null, null, null] +33552 - null - [null, null, null, null, null] +33553 - null - [null, null, null, null, null] +33554 - null - [null, null, null, null, null] +33555 - null - [null, null, null, null, null] +33556 - null - [null, null, null, null, null] +33557 - null - [null, null, null, null, null] +33558 - null - [null, null, null, null, null] +33559 - null - [null, null, null, null, null] +33560 - null - [null, null, null, null, null] +33561 - null - [null, null, null, null, null] +33562 - null - [null, null, null, null, null] +33563 - null - [null, null, null, null, null] +33564 - null - [null, null, null, null, null] +33565 - null - [null, null, null, null, null] +33566 - null - [null, null, null, null, null] +33567 - null - [null, null, null, null, null] +33568 - null - [null, null, null, null, null] +33569 - null - [null, null, null, null, null] +33570 - null - [null, null, null, null, null] +33571 - null - [null, null, null, null, null] +33572 - null - [null, null, null, null, null] +33573 - null - [null, null, null, null, null] +33574 - null - [null, null, null, null, null] +33575 - null - [null, null, null, null, null] +33576 - null - [null, null, null, null, null] +33577 - null - [null, null, null, null, null] +33578 - null - [null, null, null, null, null] +33579 - null - [null, null, null, null, null] +33580 - null - [null, null, null, null, null] +33581 - null - [null, null, null, null, null] +33582 - null - [null, null, null, null, null] +33583 - null - [null, null, null, null, null] +33584 - null - [null, null, null, null, null] +33585 - null - [null, null, null, null, null] +33586 - null - [null, null, null, null, null] +33587 - null - [null, null, null, null, null] +33588 - null - [null, null, null, null, null] +33589 - null - [null, null, null, null, null] +33590 - null - [null, null, null, null, null] +33591 - null - [null, null, null, null, null] +33592 - null - [null, null, null, null, null] +33593 - null - [null, null, null, null, null] +33594 - null - [null, null, null, null, null] +33595 - null - [null, null, null, null, null] +33596 - null - [null, null, null, null, null] +33597 - null - [null, null, null, null, null] +33598 - null - [null, null, null, null, null] +33599 - null - [null, null, null, null, null] +33600 - null - [null, null, null, null, null] +33601 - null - [null, null, null, null, null] +33602 - null - [null, null, null, null, null] +33603 - null - [null, null, null, null, null] +33604 - null - [null, null, null, null, null] +33605 - null - [null, null, null, null, null] +33606 - null - [null, null, null, null, null] +33607 - null - [null, null, null, null, null] +33608 - null - [null, null, null, null, null] +33609 - null - [null, null, null, null, null] +33610 - null - [null, null, null, null, null] +33611 - null - [null, null, null, null, null] +33612 - null - [null, null, null, null, null] +33613 - null - [null, null, null, null, null] +33614 - null - [null, null, null, null, null] +33615 - null - [null, null, null, null, null] +33616 - null - [null, null, null, null, null] +33617 - null - [null, null, null, null, null] +33618 - null - [null, null, null, null, null] +33619 - null - [null, null, null, null, null] +33620 - null - [null, null, null, null, null] +33621 - null - [null, null, null, null, null] +33622 - null - [null, null, null, null, null] +33623 - null - [null, null, null, null, null] +33624 - null - [null, null, null, null, null] +33625 - null - [null, null, null, null, null] +33626 - null - [null, null, null, null, null] +33627 - null - [null, null, null, null, null] +33628 - null - [null, null, null, null, null] +33629 - null - [null, null, null, null, null] +33630 - null - [null, null, null, null, null] +33631 - null - [null, null, null, null, null] +33632 - null - [null, null, null, null, null] +33633 - null - [null, null, null, null, null] +33634 - null - [null, null, null, null, null] +33635 - null - [null, null, null, null, null] +33636 - null - [null, null, null, null, null] +33637 - null - [null, null, null, null, null] +33638 - null - [null, null, null, null, null] +33639 - null - [null, null, null, null, null] +33640 - null - [null, null, null, null, null] +33641 - null - [null, null, null, null, null] +33642 - null - [null, null, null, null, null] +33643 - null - [null, null, null, null, null] +33644 - null - [null, null, null, null, null] +33645 - null - [null, null, null, null, null] +33646 - null - [null, null, null, null, null] +33647 - null - [null, null, null, null, null] +33648 - null - [null, null, null, null, null] +33649 - null - [null, null, null, null, null] +33650 - null - [null, null, null, null, null] +33651 - null - [null, null, null, null, null] +33652 - null - [null, null, null, null, null] +33653 - null - [null, null, null, null, null] +33654 - null - [null, null, null, null, null] +33655 - null - [null, null, null, null, null] +33656 - null - [null, null, null, null, null] +33657 - null - [null, null, null, null, null] +33658 - null - [null, null, null, null, null] +33659 - null - [null, null, null, null, null] +33660 - null - [null, null, null, null, null] +33661 - null - [null, null, null, null, null] +33662 - null - [null, null, null, null, null] +33663 - null - [null, null, null, null, null] +33664 - null - [null, null, null, null, null] +33665 - null - [null, null, null, null, null] +33666 - null - [null, null, null, null, null] +33667 - null - [null, null, null, null, null] +33668 - null - [null, null, null, null, null] +33669 - null - [null, null, null, null, null] +33670 - null - [null, null, null, null, null] +33671 - null - [null, null, null, null, null] +33672 - null - [null, null, null, null, null] +33673 - null - [null, null, null, null, null] +33674 - null - [null, null, null, null, null] +33675 - null - [null, null, null, null, null] +33676 - null - [null, null, null, null, null] +33677 - null - [null, null, null, null, null] +33678 - null - [null, null, null, null, null] +33679 - null - [null, null, null, null, null] +33680 - null - [null, null, null, null, null] +33681 - null - [null, null, null, null, null] +33682 - null - [null, null, null, null, null] +33683 - null - [null, null, null, null, null] +33684 - null - [null, null, null, null, null] +33685 - null - [null, null, null, null, null] +33686 - null - [null, null, null, null, null] +33687 - null - [null, null, null, null, null] +33688 - null - [null, null, null, null, null] +33689 - null - [null, null, null, null, null] +33690 - null - [null, null, null, null, null] +33691 - null - [null, null, null, null, null] +33692 - null - [null, null, null, null, null] +33693 - null - [null, null, null, null, null] +33694 - null - [null, null, null, null, null] +33695 - null - [null, null, null, null, null] +33696 - null - [null, null, null, null, null] +33697 - null - [null, null, null, null, null] +33698 - null - [null, null, null, null, null] +33699 - null - [null, null, null, null, null] +33700 - null - [null, null, null, null, null] +33701 - null - [null, null, null, null, null] +33702 - null - [null, null, null, null, null] +33703 - null - [null, null, null, null, null] +33704 - null - [null, null, null, null, null] +33705 - null - [null, null, null, null, null] +33706 - null - [null, null, null, null, null] +33707 - null - [null, null, null, null, null] +33708 - null - [null, null, null, null, null] +33709 - null - [null, null, null, null, null] +33710 - null - [null, null, null, null, null] +33711 - null - [null, null, null, null, null] +33712 - null - [null, null, null, null, null] +33713 - null - [null, null, null, null, null] +33714 - null - [null, null, null, null, null] +33715 - null - [null, null, null, null, null] +33716 - null - [null, null, null, null, null] +33717 - null - [null, null, null, null, null] +33718 - null - [null, null, null, null, null] +33719 - null - [null, null, null, null, null] +33720 - null - [null, null, null, null, null] +33721 - null - [null, null, null, null, null] +33722 - null - [null, null, null, null, null] +33723 - null - [null, null, null, null, null] +33724 - null - [null, null, null, null, null] +33725 - null - [null, null, null, null, null] +33726 - null - [null, null, null, null, null] +33727 - null - [null, null, null, null, null] +33728 - null - [null, null, null, null, null] +33729 - null - [null, null, null, null, null] +33730 - null - [null, null, null, null, null] +33731 - null - [null, null, null, null, null] +33732 - null - [null, null, null, null, null] +33733 - null - [null, null, null, null, null] +33734 - null - [null, null, null, null, null] +33735 - null - [null, null, null, null, null] +33736 - null - [null, null, null, null, null] +33737 - null - [null, null, null, null, null] +33738 - null - [null, null, null, null, null] +33739 - null - [null, null, null, null, null] +33740 - null - [null, null, null, null, null] +33741 - null - [null, null, null, null, null] +33742 - null - [null, null, null, null, null] +33743 - null - [null, null, null, null, null] +33744 - null - [null, null, null, null, null] +33745 - null - [null, null, null, null, null] +33746 - null - [null, null, null, null, null] +33747 - null - [null, null, null, null, null] +33748 - null - [null, null, null, null, null] +33749 - null - [null, null, null, null, null] +33750 - null - [null, null, null, null, null] +33751 - null - [null, null, null, null, null] +33752 - null - [null, null, null, null, null] +33753 - null - [null, null, null, null, null] +33754 - null - [null, null, null, null, null] +33755 - Weather vane - [null, null, null, null, null] +33756 - null - [null, null, null, null, null] +33757 - null - [null, null, null, null, null] +33758 - null - [null, null, null, null, null] +33759 - null - [null, null, null, null, null] +33760 - null - [null, null, null, null, null] +33761 - null - [null, null, null, null, null] +33762 - null - [null, null, null, null, null] +33763 - null - [null, null, null, null, null] +33764 - null - [null, null, null, null, null] +33765 - null - [null, null, null, null, null] +33766 - null - [null, null, null, null, null] +33767 - null - [null, null, null, null, null] +33768 - null - [null, null, null, null, null] +33769 - null - [null, null, null, null, null] +33770 - null - [null, null, null, null, null] +33771 - null - [null, null, null, null, null] +33772 - null - [null, null, null, null, null] +33773 - null - [null, null, null, null, null] +33774 - null - [null, null, null, null, null] +33775 - null - [null, null, null, null, null] +33776 - null - [null, null, null, null, null] +33777 - null - [null, null, null, null, null] +33778 - null - [null, null, null, null, null] +33779 - null - [null, null, null, null, null] +33780 - null - [null, null, null, null, null] +33781 - null - [null, null, null, null, null] +33782 - null - [null, null, null, null, null] +33783 - null - [null, null, null, null, null] +33784 - null - [null, null, null, null, null] +33785 - null - [null, null, null, null, null] +33786 - null - [null, null, null, null, null] +33787 - null - [null, null, null, null, null] +33788 - null - [null, null, null, null, null] +33789 - null - [null, null, null, null, null] +33790 - null - [null, null, null, null, null] +33791 - null - [null, null, null, null, null] +33792 - null - [null, null, null, null, null] +33793 - Weapon rack - [null, null, null, null, null] +33794 - Weapon rack - [null, null, null, null, null] +33795 - null - [null, null, null, null, null] +33796 - null - [null, null, null, null, null] +33797 - null - [null, null, null, null, null] +33798 - null - [null, null, null, null, null] +33799 - null - [null, null, null, null, null] +33800 - null - [null, null, null, null, null] +33801 - null - [null, null, null, null, null] +33802 - null - [null, null, null, null, null] +33803 - null - [null, null, null, null, null] +33804 - null - [null, null, null, null, null] +33805 - null - [null, null, null, null, null] +33806 - null - [null, null, null, null, null] +33807 - null - [null, null, null, null, null] +33808 - null - [null, null, null, null, null] +33809 - null - [null, null, null, null, null] +33810 - null - [null, null, null, null, null] +33811 - null - [null, null, null, null, null] +33812 - null - [null, null, null, null, null] +33813 - null - [null, null, null, null, null] +33814 - null - [null, null, null, null, null] +33815 - null - [null, null, null, null, null] +33816 - null - [null, null, null, null, null] +33817 - null - [null, null, null, null, null] +33818 - null - [null, null, null, null, null] +33819 - null - [null, null, null, null, null] +33820 - null - [null, null, null, null, null] +33821 - null - [null, null, null, null, null] +33822 - null - [null, null, null, null, null] +33823 - null - [null, null, null, null, null] +33824 - null - [null, null, null, null, null] +33825 - null - [null, null, null, null, null] +33826 - Javelin - [null, null, null, null, null] +33827 - null - [null, null, null, null, null] +33828 - null - [null, null, null, null, null] +33829 - null - [null, null, null, null, null] +33830 - null - [null, null, null, null, null] +33831 - null - [null, null, null, null, null] +33832 - null - [null, null, null, null, null] +33833 - null - [null, null, null, null, null] +33834 - Archery Range - [hidden, null, null, null, null] +33835 - null - [null, null, null, null, null] +33836 - null - [null, null, null, null, null] +33837 - null - [null, null, null, null, null] +33838 - null - [null, null, null, null, null] +33839 - null - [null, null, null, null, null] +33840 - null - [null, null, null, null, null] +33841 - null - [null, null, null, null, null] +33842 - Stile - [Climb-over, null, null, null, null] +33843 - null - [null, null, null, null, null] +33844 - null - [null, null, null, null, null] +33845 - null - [null, null, null, null, null] +33846 - null - [null, null, null, null, null] +33847 - null - [null, null, null, null, null] +33848 - null - [null, null, null, null, null] +33849 - null - [null, null, null, null, null] +33850 - Gate - [null, null, null, null, null] +33851 - null - [null, null, null, null, null] +33852 - null - [null, null, null, null, null] +33853 - null - [null, null, null, null, null] +33854 - null - [null, null, null, null, null] +33855 - null - [null, null, null, null, null] +33856 - null - [null, null, null, null, null] +33857 - null - [null, null, null, null, null] +33858 - null - [null, null, null, null, null] +33859 - null - [null, null, null, null, null] +33860 - null - [null, null, null, null, null] +33861 - null - [null, null, null, null, null] +33862 - null - [null, null, null, null, null] +33863 - null - [null, null, null, null, null] +33864 - null - [null, null, null, null, null] +33865 - null - [null, null, null, null, null] +33866 - null - [null, null, null, null, null] +33867 - null - [null, null, null, null, null] +33868 - null - [null, null, null, null, null] +33869 - null - [null, null, null, null, null] +33870 - null - [null, null, null, null, null] +33871 - null - [null, null, null, null, null] +33872 - null - [null, null, null, null, null] +33873 - null - [null, null, null, null, null] +33874 - null - [null, null, null, null, null] +33875 - null - [null, null, null, null, null] +33876 - null - [null, null, null, null, null] +33877 - null - [null, null, null, null, null] +33878 - null - [null, null, null, null, null] +33879 - null - [null, null, null, null, null] +33880 - null - [null, null, null, null, null] +33881 - null - [null, null, null, null, null] +33882 - null - [null, null, null, null, null] +33883 - null - [null, null, null, null, null] +33884 - null - [null, null, null, null, null] +33885 - null - [null, null, null, null, null] +33886 - null - [null, null, null, null, null] +33887 - null - [null, null, null, null, null] +33888 - null - [null, null, null, null, null] +33889 - null - [null, null, null, null, null] +33890 - null - [null, null, null, null, null] +33891 - null - [null, null, null, null, null] +33892 - null - [null, null, null, null, null] +33893 - null - [null, null, null, null, null] +33894 - null - [null, null, null, null, null] +33895 - null - [null, null, null, null, null] +33896 - null - [null, null, null, null, null] +33897 - null - [null, null, null, null, null] +33898 - null - [null, null, null, null, null] +33899 - null - [null, null, null, null, null] +33900 - null - [null, null, null, null, null] +33901 - null - [null, null, null, null, null] +33902 - null - [null, null, null, null, null] +33903 - null - [null, null, null, null, null] +33904 - null - [null, null, null, null, null] +33905 - null - [null, null, null, null, null] +33906 - null - [null, null, null, null, null] +33907 - null - [null, null, null, null, null] +33908 - null - [null, null, null, null, null] +33909 - null - [null, null, null, null, null] +33910 - null - [null, null, null, null, null] +33911 - null - [null, null, null, null, null] +33912 - null - [null, null, null, null, null] +33913 - null - [null, null, null, null, null] +33914 - null - [null, null, null, null, null] +33915 - null - [null, null, null, null, null] +33916 - null - [null, null, null, null, null] +33917 - null - [null, null, null, null, null] +33918 - null - [null, null, null, null, null] +33919 - null - [null, null, null, null, null] +33920 - Wall - [null, null, null, null, null] +33921 - Wall - [null, null, null, null, null] +33922 - Wall - [null, null, null, null, null] +33923 - Wall - [null, null, null, null, null] +33924 - null - [null, null, null, null, null] +33925 - null - [null, null, null, null, null] +33926 - null - [null, null, null, null, null] +33927 - null - [null, null, null, null, null] +33928 - null - [null, null, null, null, null] +33929 - null - [null, null, null, null, null] +33930 - null - [null, null, null, null, null] +33931 - Drawers - [Open, null, null, null, null] +33932 - Drawers - [null, Search, Shut, null, null] +33933 - Closed chest - [Open, null, null, null, null] +33934 - Closed chest - [Open, null, null, null, null] +33935 - null - [null, null, null, null, null] +33936 - null - [null, null, null, null, null] +33937 - null - [null, null, null, null, null] +33938 - null - [null, null, null, null, null] +33939 - null - [null, null, null, null, null] +33940 - null - [null, null, null, null, null] +33941 - null - [null, null, null, null, null] +33942 - null - [null, null, null, null, null] +33943 - null - [null, null, null, null, null] +33944 - null - [null, null, null, null, null] +33945 - null - [null, null, null, null, null] +33946 - null - [null, null, null, null, null] +33947 - null - [null, null, null, null, null] +33948 - null - [null, null, null, null, null] +33949 - null - [null, null, null, null, null] +33950 - null - [null, null, null, null, null] +33951 - null - [null, null, null, null, null] +33952 - null - [null, null, null, null, null] +33953 - null - [null, null, null, null, null] +33954 - null - [null, null, null, null, null] +33955 - null - [null, null, null, null, null] +33956 - null - [null, null, null, null, null] +33957 - null - [null, null, null, null, null] +33958 - Lander boat - [null, null, null, null, null] +33959 - Lander hatch - [null, null, null, null, null] +33960 - Lander hatch - [null, null, null, null, null] +33961 - null - [null, null, null, null, null] +33962 - null - [null, null, null, null, null] +33963 - Wardrobe - [Open, null, null, null, null] +33964 - Bookcase - [Search, null, null, null, null] +33965 - null - [null, null, null, null, null] +33966 - null - [null, null, null, null, null] +33967 - null - [null, null, null, null, null] +33968 - null - [null, null, null, null, null] +33969 - null - [null, null, null, null, null] +33970 - null - [null, null, null, null, null] +33971 - null - [null, null, null, null, null] +33972 - null - [null, null, null, null, null] +33973 - null - [null, null, null, null, null] +33974 - null - [null, null, null, null, null] +33975 - null - [null, null, null, null, null] +33976 - null - [null, null, null, null, null] +33977 - Ladder - [Climb-up, null, null, null, null] +33978 - null - [null, null, null, null, null] +33979 - null - [null, null, null, null, null] +33980 - null - [null, null, null, null, null] +33981 - null - [null, null, null, null, null] +33982 - null - [null, null, null, null, null] +33983 - null - [null, null, null, null, null] +33984 - null - [null, null, null, null, null] +33985 - null - [null, null, null, null, null] +33986 - null - [null, null, null, null, null] +33987 - null - [null, null, null, null, null] +33988 - null - [null, null, null, null, null] +33989 - null - [null, null, null, null, null] +33990 - null - [null, null, null, null, null] +33991 - null - [null, null, null, null, null] +33992 - null - [null, null, null, null, null] +33993 - null - [null, null, null, null, null] +33994 - null - [null, null, null, null, null] +33995 - null - [null, null, null, null, null] +33996 - null - [null, null, null, null, null] +33997 - null - [null, null, null, null, null] +33998 - null - [null, null, null, null, null] +33999 - null - [null, null, null, null, null] +34000 - null - [null, null, null, null, null] +34001 - null - [null, null, null, null, null] +34002 - null - [null, null, null, null, null] +34003 - null - [null, null, null, null, null] +34004 - null - [null, null, null, null, null] +34005 - Door - [Open, null, null, null, Pick-lock] +34006 - null - [null, null, null, null, null] +34007 - null - [null, null, null, null, null] +34008 - null - [null, null, null, null, null] +34009 - null - [null, null, null, null, null] +34010 - null - [null, null, null, null, null] +34011 - null - [null, null, null, null, null] +34012 - Ladder - [Climb-down, null, null, null, null] +34013 - null - [null, null, null, null, null] +34014 - null - [null, null, null, null, null] +34015 - null - [null, null, null, null, null] +34016 - null - [null, null, null, null, null] +34017 - null - [null, null, null, null, null] +34018 - null - [null, null, null, null, null] +34019 - null - [null, null, null, null, null] +34020 - null - [null, null, null, null, null] +34021 - null - [null, null, null, null, null] +34022 - null - [null, null, null, null, null] +34023 - null - [null, null, null, null, null] +34024 - null - [null, null, null, null, null] +34025 - null - [null, null, null, null, null] +34026 - null - [null, null, null, null, null] +34027 - null - [null, null, null, null, null] +34028 - null - [null, null, null, null, null] +34029 - null - [null, null, null, null, null] +34030 - null - [null, null, null, null, null] +34031 - null - [null, null, null, null, null] +34032 - Open chest - [null, Search, Shut, null, null] +34033 - null - [null, null, null, null, null] +34034 - null - [null, null, null, null, null] +34035 - null - [null, null, null, null, null] +34036 - null - [null, null, null, null, null] +34037 - Cabinet - [null, null, null, null, null] +34038 - Cabinet - [null, null, null, null, null] +34039 - Cabinet - [null, null, null, null, null] +34040 - Stairs - [Climb-up, null, null, null, null] +34041 - Stairs - [Climb-down, null, null, null, null] +34042 - Door - [Open, null, null, null, null] +34043 - Door - [Close, null, null, null, null] +34044 - Door - [Open, null, null, null, null] +34045 - Door - [Close, null, null, null, null] +34046 - Door - [Open, null, null, null, null] +34047 - null - [null, null, null, null, null] +34048 - null - [null, null, null, null, null] +34049 - null - [null, null, null, null, null] +34050 - null - [null, null, null, null, null] +34051 - null - [null, null, null, null, null] +34052 - null - [null, null, null, null, null] +34053 - null - [null, null, null, null, null] +34054 - null - [null, null, null, null, null] +34055 - null - [null, null, null, null, null] +34056 - null - [null, null, null, null, null] +34057 - null - [null, null, null, null, null] +34058 - null - [null, null, null, null, null] +34059 - null - [null, null, null, null, null] +34060 - null - [null, null, null, null, null] +34061 - null - [null, null, null, null, null] +34062 - null - [null, null, null, null, null] +34063 - null - [null, null, null, null, null] +34064 - null - [null, null, null, null, null] +34065 - null - [null, null, null, null, null] +34066 - null - [null, null, null, null, null] +34067 - null - [null, null, null, null, null] +34068 - null - [null, null, null, null, null] +34069 - null - [null, null, null, null, null] +34070 - null - [null, null, null, null, null] +34071 - null - [null, null, null, null, null] +34072 - null - [null, null, null, null, null] +34073 - null - [null, null, null, null, null] +34074 - null - [null, null, null, null, null] +34075 - null - [null, null, null, null, null] +34076 - Staircase - [Climb-up, null, null, null, null] +34077 - null - [null, null, null, null, null] +34078 - null - [null, null, null, null, null] +34079 - null - [null, null, null, null, null] +34080 - null - [Climb-up, null, null, null, null] +34081 - null - [null, null, null, null, null] +34082 - Sink - [null, null, null, null, null] +34083 - null - [null, null, null, null, null] +34084 - null - [null, null, null, null, null] +34085 - null - [null, null, null, null, null] +34086 - null - [null, null, null, null, null] +34087 - null - [null, null, null, null, null] +34088 - null - [null, null, null, null, null] +34089 - null - [null, null, null, null, null] +34090 - null - [null, null, null, null, null] +34091 - null - [null, null, null, null, null] +34092 - null - [null, null, null, null, null] +34093 - null - [null, null, null, null, null] +34094 - null - [null, null, null, null, null] +34095 - null - [null, null, null, null, null] +34096 - null - [null, null, null, null, null] +34097 - null - [null, null, null, null, null] +34098 - null - [null, null, null, null, null] +34099 - null - [null, null, null, null, null] +34100 - null - [null, null, null, null, null] +34101 - null - [null, null, null, null, null] +34102 - null - [null, null, null, null, null] +34103 - null - [null, null, null, null, null] +34104 - null - [null, null, null, null, null] +34105 - null - [null, null, null, null, null] +34106 - Shelves - [null, null, null, null, null] +34107 - Shelves - [null, null, null, null, null] +34108 - null - [null, null, null, null, null] +34109 - null - [null, null, null, null, null] +34110 - null - [null, null, null, null, null] +34111 - null - [null, null, null, null, null] +34112 - null - [null, null, null, null, null] +34113 - null - [null, null, null, null, null] +34114 - null - [null, null, null, null, null] +34115 - null - [null, null, null, null, null] +34116 - null - [null, null, null, null, null] +34117 - null - [null, null, null, null, null] +34118 - null - [null, null, null, null, null] +34119 - null - [null, null, null, null, null] +34120 - null - [null, null, null, null, null] +34121 - null - [null, null, null, null, null] +34122 - null - [null, null, null, null, null] +34123 - null - [null, null, null, null, null] +34124 - null - [null, null, null, null, null] +34125 - null - [null, null, null, null, null] +34126 - null - [null, null, null, null, null] +34127 - null - [null, null, null, null, null] +34128 - null - [null, null, null, null, null] +34129 - null - [null, null, null, null, null] +34130 - null - [null, null, null, null, null] +34131 - null - [null, null, null, null, null] +34132 - null - [null, null, null, null, null] +34133 - null - [null, null, null, null, null] +34134 - null - [null, null, null, null, null] +34135 - null - [null, null, null, null, null] +34136 - null - [null, null, null, null, null] +34137 - Crate - [Search, null, null, null, null] +34138 - Lighting space - [null, null, null, null, Build] +34139 - null - [null, null, null, null, null] +34140 - null - [null, null, null, null, null] +34141 - null - [null, null, null, null, null] +34142 - null - [null, null, null, null, null] +34143 - null - [null, null, null, null, null] +34144 - null - [null, null, null, null, null] +34145 - null - [null, null, null, null, null] +34146 - null - [null, null, null, null, null] +34147 - null - [null, null, null, null, null] +34148 - null - [null, null, null, null, null] +34149 - null - [null, null, null, null, null] +34150 - null - [null, null, null, null, null] +34151 - null - [null, null, null, null, null] +34152 - null - [null, null, null, null, null] +34153 - null - [null, null, null, null, null] +34154 - null - [null, null, null, null, null] +34155 - null - [null, null, null, null, null] +34156 - null - [null, null, null, null, null] +34157 - null - [null, null, null, null, null] +34158 - null - [null, null, null, null, null] +34159 - null - [null, null, null, null, null] +34160 - null - [null, null, null, null, null] +34161 - null - [null, null, null, null, null] +34162 - null - [null, null, null, null, null] +34163 - null - [null, null, null, null, null] +34164 - null - [null, null, null, null, null] +34165 - null - [null, null, null, null, null] +34166 - null - [null, null, null, null, null] +34167 - null - [null, null, null, null, null] +34168 - null - [null, null, null, null, null] +34169 - null - [null, null, null, null, null] +34170 - null - [null, null, null, null, null] +34171 - null - [null, null, null, null, null] +34172 - null - [null, null, null, null, null] +34173 - null - [null, null, null, null, null] +34174 - null - [null, null, null, null, null] +34175 - null - [null, null, null, null, null] +34176 - null - [null, null, null, null, null] +34177 - null - [null, null, null, null, null] +34178 - null - [null, null, null, null, null] +34179 - null - [null, null, null, null, null] +34180 - null - [null, null, null, null, null] +34181 - null - [null, null, null, null, null] +34182 - null - [null, null, null, null, null] +34183 - null - [null, null, null, null, null] +34184 - null - [null, null, null, null, null] +34185 - null - [null, null, null, null, null] +34186 - null - [null, null, null, null, null] +34187 - null - [null, null, null, null, null] +34188 - null - [null, null, null, null, null] +34189 - null - [null, null, null, null, null] +34190 - null - [null, null, null, null, null] +34191 - null - [null, null, null, null, null] +34192 - null - [null, null, null, null, null] +34193 - null - [null, null, null, null, null] +34194 - null - [null, null, null, null, null] +34195 - null - [null, null, null, null, null] +34196 - null - [null, null, null, null, null] +34197 - null - [null, null, null, null, null] +34198 - null - [null, null, null, null, null] +34199 - null - [null, null, null, null, null] +34200 - null - [null, null, null, null, null] +34201 - null - [null, null, null, null, null] +34202 - null - [null, null, null, null, null] +34203 - Sack - [null, null, null, null, null] +34204 - Table - [null, null, null, null, null] +34205 - Bank booth - [null, null, null, null, null] +34206 - Closed bank booth - [null, null, null, null, null] +34207 - Closed bank booth - [null, null, null, null, null] +34208 - null - [null, null, null, null, null] +34209 - null - [null, null, null, null, null] +34210 - null - [null, null, null, null, null] +34211 - null - [null, null, null, null, null] +34212 - null - [null, null, null, null, null] +34213 - null - [null, null, null, null, null] +34214 - null - [null, null, null, null, null] +34215 - null - [null, null, null, null, null] +34216 - Bamboo Ladder - [Climb-up, null, null, null, null] +34217 - Bamboo Ladder - [Climb-up, null, null, null, null] +34218 - null - [null, null, null, null, null] +34219 - null - [null, null, null, null, null] +34220 - null - [null, null, null, null, null] +34221 - null - [null, null, null, null, null] +34222 - Watchtower Legs - [null, null, null, null, null] +34223 - Teleportation Device - [Operate, null, null, null, null] +34224 - Teleportation Device - [Operate, null, null, null, null] +34225 - Crate - [Search, null, null, null, null] +34226 - Crates - [Search, null, null, null, null] +34227 - Chair - [null, null, null, null, null] +34228 - null - [null, null, null, null, null] +34229 - null - [null, null, null, null, null] +34230 - null - [null, null, null, null, null] +34231 - null - [null, null, null, null, null] +34232 - null - [null, null, null, null, null] +34233 - null - [null, null, null, null, null] +34234 - Door - [Open, null, null, null, null] +34235 - null - [null, null, null, null, null] +34236 - null - [null, null, null, null, null] +34237 - null - [null, null, null, null, null] +34238 - null - [null, null, null, null, null] +34239 - null - [null, null, null, null, null] +34240 - null - [null, null, null, null, null] +34241 - null - [null, null, null, null, null] +34242 - null - [null, null, null, null, null] +34243 - null - [null, null, null, null, null] +34244 - null - [null, null, null, null, null] +34245 - Wardrobe - [Open, null, null, null, null] +34246 - Wardrobe - [Open, null, null, null, null] +34247 - Wardrobe - [null, Search, Close, null, null] +34248 - Chest - [null, null, null, null, null] +34249 - null - [null, null, null, null, null] +34250 - null - [null, null, null, null, null] +34251 - null - [null, null, null, null, null] +34252 - null - [null, null, null, null, null] +34253 - null - [null, null, null, null, null] +34254 - null - [null, null, null, null, null] +34255 - null - [null, null, null, null, null] +34256 - null - [null, null, null, null, null] +34257 - null - [null, null, null, null, null] +34258 - null - [null, null, null, null, null] +34259 - null - [null, null, null, null, null] +34260 - null - [null, null, null, null, null] +34261 - null - [null, null, null, null, null] +34262 - null - [null, null, null, null, null] +34263 - null - [null, null, null, null, null] +34264 - null - [null, null, null, null, null] +34265 - null - [null, null, null, null, null] +34266 - null - [null, null, null, null, null] +34267 - null - [null, null, null, null, null] +34268 - null - [null, null, null, null, null] +34269 - null - [null, null, null, null, null] +34270 - null - [null, null, null, null, null] +34271 - null - [null, null, null, null, null] +34272 - Keg - [null, null, null, null, null] +34273 - Bed - [null, null, null, null, null] +34274 - null - [null, null, null, null, null] +34275 - null - [null, null, null, null, null] +34276 - null - [null, null, null, null, null] +34277 - null - [null, null, null, null, null] +34278 - null - [null, null, null, null, null] +34279 - null - [null, null, null, null, null] +34280 - null - [null, null, null, null, null] +34281 - null - [null, null, null, null, null] +34282 - null - [null, null, null, null, null] +34283 - null - [null, null, null, null, null] +34284 - null - [null, null, null, null, null] +34285 - null - [null, null, null, null, null] +34286 - Ladder - [null, Climb-down, Climb-up, null, null] +34287 - Ladder - [null, Climb-down, Climb-up, null, null] +34288 - Door - [Open, null, null, null, null] +34289 - Door - [Open, null, null, null, null] +34290 - Door - [null, null, null, null, null] +34291 - Door - [null, null, null, null, null] +34292 - null - [null, null, null, null, null] +34293 - null - [null, null, null, null, null] +34294 - null - [null, null, null, null, null] +34295 - null - [null, null, null, null, null] +34296 - null - [null, null, null, null, null] +34297 - null - [null, null, null, null, null] +34298 - null - [null, null, null, null, null] +34299 - Tomb - [null, null, null, null, null] +34300 - null - [null, null, null, null, null] +34301 - null - [null, null, null, null, null] +34302 - null - [null, null, null, null, null] +34303 - null - [null, null, null, null, null] +34304 - null - [null, null, null, null, null] +34305 - null - [null, null, null, null, null] +34306 - null - [null, null, null, null, null] +34307 - null - [null, null, null, null, null] +34308 - null - [null, null, null, null, null] +34309 - null - [null, null, null, null, null] +34310 - null - [null, null, null, null, null] +34311 - null - [null, null, null, null, null] +34312 - Door - [Open, null, null, null, null] +34313 - Door - [Close, null, null, null, null] +34314 - null - [null, null, null, null, null] +34315 - null - [null, null, null, null, null] +34316 - null - [null, null, null, null, null] +34317 - Pillar - [null, null, null, null, null] +34318 - null - [null, null, null, null, null] +34319 - null - [null, null, null, null, null] +34320 - null - [null, null, null, null, null] +34321 - null - [null, null, null, null, null] +34322 - null - [null, null, null, null, null] +34323 - null - [null, null, null, null, null] +34324 - null - [null, null, null, null, null] +34325 - null - [null, null, null, null, null] +34326 - null - [null, null, null, null, null] +34327 - null - [null, null, null, null, null] +34328 - null - [null, null, null, null, null] +34329 - null - [null, null, null, null, null] +34330 - null - [null, null, null, null, null] +34331 - null - [null, null, null, null, null] +34332 - null - [null, null, null, null, null] +34333 - null - [null, null, null, null, null] +34334 - null - [null, null, null, null, null] +34335 - null - [null, null, null, null, null] +34336 - null - [null, null, null, null, null] +34337 - null - [null, null, null, null, null] +34338 - null - [null, null, null, null, null] +34339 - null - [null, null, null, null, null] +34340 - null - [null, null, null, null, null] +34341 - null - [null, null, null, null, null] +34342 - null - [null, null, null, null, null] +34343 - null - [null, null, null, null, null] +34344 - null - [null, null, null, null, null] +34345 - null - [null, null, null, null, null] +34346 - null - [null, null, null, null, null] +34347 - null - [null, null, null, null, null] +34348 - null - [null, null, null, null, null] +34349 - null - [null, null, null, null, null] +34350 - null - [null, null, null, null, null] +34351 - null - [null, null, null, null, null] +34352 - null - [null, null, null, null, null] +34353 - Door - [Close, null, null, null, null] +34354 - Door - [Open, null, null, null, null] +34355 - null - [null, null, null, null, null] +34356 - null - [null, null, null, null, null] +34357 - null - [null, null, null, null, null] +34358 - null - [null, null, null, null, null] +34359 - null - [null, null, null, null, null] +34360 - null - [null, null, null, null, null] +34361 - null - [null, null, null, null, null] +34362 - null - [null, null, null, null, null] +34363 - null - [null, null, null, null, null] +34364 - null - [null, null, null, null, null] +34365 - null - [null, null, null, null, null] +34366 - Shelves - [null, null, null, null, null] +34367 - Shelves - [null, null, null, null, null] +34368 - Shelves - [null, null, null, null, null] +34369 - Shelves - [null, null, null, null, null] +34370 - Shelf - [null, null, null, null, null] +34371 - null - [null, null, null, null, null] +34372 - null - [null, null, null, null, null] +34373 - null - [null, null, null, null, null] +34374 - null - [null, null, null, null, null] +34375 - Row boat - [null, null, null, null, null] +34376 - Cart - [null, null, null, null, null] +34377 - null - [null, null, null, null, null] +34378 - null - [null, null, null, null, null] +34379 - null - [null, null, null, null, null] +34380 - null - [null, null, null, null, null] +34381 - Market stall - [null, null, null, null, null] +34382 - Silver stall - [null, Steal-from, null, null, null] +34383 - Silk stall - [null, Steal-from, null, null, null] +34384 - Baker's stall - [null, Steal-from, null, null, null] +34385 - Gem stall - [null, Steal-from, null, null, null] +34386 - Spice stall - [null, Steal-from, null, null, null] +34387 - Fur stall - [null, Steal-from, null, null, null] +34388 - Staircase - [Climb-up, null, null, null, null] +34389 - Staircase - [Climb, Climb-up, Climb-down, null, null] +34390 - Staircase - [Climb-down, null, null, null, null] +34391 - Staircase - [Climb-up, null, null, null, null] +34392 - Staircase - [Climb, Climb-up, Climb-down, null, null] +34393 - Staircase - [Climb-down, null, null, null, null] +34394 - Ladder - [Climb-up, null, null, null, null] +34395 - Ladder - [Climb, Climb-up, Climb-down, null, null] +34396 - Ladder - [Climb-down, null, null, null, null] +34397 - Staircase - [Climb-up, null, null, null, null] +34398 - Staircase - [Climb-down, null, null, null, null] +34399 - null - [null, null, null, null, null] +34400 - null - [null, null, null, null, null] +34401 - Bed - [null, null, null, null, null] +34402 - Bed - [null, null, null, null, null] +34403 - Bunk bed - [null, null, null, null, null] +34404 - Drawers - [Open, null, null, null, null] +34405 - Drawers - [Search, Shut, null, null, null] +34406 - Wardrobe - [null, null, null, null, null] +34407 - Dresser - [null, null, null, null, null] +34408 - null - [null, null, null, null, null] +34409 - Larder - [null, null, null, null, null] +34410 - Cooking range - [null, null, null, null, null] +34411 - Sink - [null, null, null, null, null] +34412 - Shelves - [null, null, null, null, null] +34413 - Shelves - [null, null, null, null, null] +34414 - Shelves - [null, null, null, null, null] +34415 - Shelves - [null, null, null, null, null] +34416 - Shelf - [null, null, null, null, null] +34417 - Shelf - [null, null, null, null, null] +34418 - null - [null, null, null, null, null] +34419 - null - [null, null, null, null, null] +34420 - null - [null, null, null, null, null] +34421 - null - [null, null, null, null, null] +34422 - Row boat - [null, null, null, null, null] +34423 - Cart - [null, null, null, null, null] +34424 - null - [null, null, null, null, null] +34425 - null - [null, null, null, null, null] +34426 - null - [null, null, null, null, null] +34427 - Broken Door - [null, null, null, null, null] +34428 - Broken cart wheel - [null, null, null, null, null] +34429 - Table - [null, null, null, null, null] +34430 - Smashed chair - [null, null, null, null, null] +34431 - Table - [null, null, null, null, null] +34432 - Ladder - [null, null, null, null, null] +34433 - Broken Chair - [null, null, null, null, null] +34434 - Broken Chair - [null, null, null, null, null] +34435 - Broken Chair - [null, null, null, null, null] +34436 - Cart - [null, null, null, null, null] +34437 - Broken range - [null, null, null, null, null] +34438 - Stool - [null, null, null, null, null] +34439 - Washing Line - [null, null, null, null, null] +34440 - Washing Line - [null, null, null, null, null] +34441 - Washing Line - [null, null, null, null, null] +34442 - null - [null, null, null, null, null] +34443 - Broken Chair - [null, null, null, null, null] +34444 - null - [null, null, null, null, null] +34445 - null - [null, null, null, null, null] +34446 - null - [null, null, null, null, null] +34447 - null - [null, null, null, null, null] +34448 - Tanning line - [null, null, null, null, null] +34449 - Mangle - [null, null, null, null, null] +34450 - Mangle - [null, null, null, null, null] +34451 - null - [null, null, null, null, null] +34452 - null - [null, null, null, null, null] +34453 - null - [null, null, null, null, null] +34454 - null - [null, null, null, null, null] +34455 - null - [null, null, null, null, null] +34456 - null - [null, null, null, null, null] +34457 - null - [null, null, null, null, null] +34458 - null - [null, null, null, null, null] +34459 - null - [null, null, null, null, null] +34460 - null - [null, null, null, null, null] +34461 - null - [null, null, null, null, null] +34462 - null - [null, null, null, null, null] +34463 - null - [null, null, null, null, null] +34464 - null - [null, null, null, null, null] +34465 - null - [null, null, null, null, null] +34466 - null - [null, null, null, null, null] +34467 - null - [null, null, null, null, null] +34468 - null - [null, null, null, null, null] +34469 - Table - [null, null, null, null, null] +34470 - Table - [null, null, null, null, null] +34471 - Chart Table - [null, null, null, null, null] +34472 - Globe Table - [null, null, null, null, null] +34473 - Table - [null, null, null, null, null] +34474 - Table - [null, null, null, null, null] +34475 - Bed - [null, null, null, null, null] +34476 - Bed - [null, null, null, null, null] +34477 - Bookcase - [null, null, null, null, null] +34478 - Bookcase - [null, null, null, null, null] +34479 - Bookcase - [null, null, null, null, null] +34480 - Books - [null, null, null, null, null] +34481 - Books - [null, null, null, null, null] +34482 - Drawers - [Open, null, null, null, null] +34483 - Drawers - [Search, Close, null, null, null] +34484 - Wardrobe - [null, null, null, null, null] +34485 - Wardrobe - [null, null, null, null, null] +34486 - Wardrobe - [null, null, null, null, null] +34487 - Wardrobe - [null, null, null, null, null] +34488 - Box - [null, null, null, null, null] +34489 - Box - [null, null, null, null, null] +34490 - Dresser - [null, null, null, null, null] +34491 - Telescope - [null, null, null, null, null] +34492 - null - [null, null, null, null, null] +34493 - Grandfather clock - [null, null, null, null, null] +34494 - Larder - [null, null, null, null, null] +34495 - Range - [null, null, null, null, null] +34496 - Sink - [null, null, null, null, null] +34497 - Spinning wheel - [Spin, null, null, null, null] +34498 - Staircase - [Climb-up, null, null, null, null] +34499 - Staircase - [Climb-down, null, null, null, null] +34500 - null - [null, null, null, null, null] +34501 - null - [null, null, null, null, null] +34502 - null - [null, null, null, null, null] +34503 - null - [null, null, null, null, null] +34504 - null - [null, null, null, null, null] +34505 - null - [null, null, null, null, null] +34506 - null - [null, null, null, null, null] +34507 - null - [null, null, null, null, null] +34508 - null - [null, null, null, null, null] +34509 - Painting - [null, null, null, null, null] +34510 - Painting - [null, null, null, null, null] +34511 - Painting - [null, null, null, null, null] +34512 - null - [null, null, null, null, null] +34513 - null - [null, null, null, null, null] +34514 - null - [null, null, null, null, null] +34515 - null - [null, null, null, null, null] +34516 - null - [null, null, null, null, null] +34517 - null - [null, null, null, null, null] +34518 - Table - [null, null, null, null, null] +34519 - Table - [null, null, null, null, null] +34520 - Table - [null, null, null, null, null] +34521 - Table - [null, null, null, null, null] +34522 - null - [null, null, null, null, null] +34523 - null - [null, null, null, null, null] +34524 - null - [null, null, null, null, null] +34525 - Bookcase - [null, null, null, null, null] +34526 - Bookcase - [null, null, null, null, null] +34527 - Bookcase - [Search, null, null, null, null] +34528 - Drawers - [Open, null, null, null, null] +34529 - Drawers - [Search, Close, null, null, null] +34530 - Drawers - [Open, null, null, null, null] +34531 - Drawers - [Search, Close, null, null, null] +34532 - Wardrobe - [null, null, null, null, null] +34533 - Wardrobe - [null, null, null, null, null] +34534 - Wardrobe - [null, null, null, null, null] +34535 - Wardrobe - [null, null, null, null, null] +34536 - Wardrobe - [null, null, null, null, null] +34537 - Wardrobe - [null, null, null, null, null] +34538 - Wardrobe - [null, null, null, null, null] +34539 - Box - [null, null, null, null, null] +34540 - Box - [null, null, null, null, null] +34541 - Box - [null, null, null, null, null] +34542 - Box - [null, null, null, null, null] +34543 - Dresser - [null, null, null, null, null] +34544 - Grandfather clock - [null, null, null, null, null] +34545 - Grandfather clock - [null, null, null, null, null] +34546 - Range - [null, null, null, null, null] +34547 - Sink - [null, null, null, null, null] +34548 - Staircase - [Climb-up, null, null, null, null] +34549 - Staircase - [Climb, Climb-up, Climb-down, null, null] +34550 - Staircase - [Climb-down, null, null, null, null] +34551 - null - [null, null, null, null, null] +34552 - null - [null, null, null, null, null] +34553 - null - [null, null, null, null, null] +34554 - null - [null, null, null, null, null] +34555 - null - [null, null, null, null, null] +34556 - Bed - [null, null, null, null, null] +34557 - Bed - [null, null, null, null, null] +34558 - Bunk bed - [null, null, null, null, null] +34559 - Drawers - [Open, null, null, null, null] +34560 - Drawers - [Search, Shut, null, null, null] +34561 - Wardrobe - [null, null, null, null, null] +34562 - Dresser - [null, null, null, null, null] +34563 - null - [null, null, null, null, null] +34564 - Larder - [null, null, null, null, null] +34565 - Cooking range - [null, null, null, null, null] +34566 - Sink - [null, null, null, null, null] +34567 - Staircase - [Climb-up, null, null, null, null] +34568 - Staircase - [Climb-down, null, null, null, null] +34569 - null - [null, null, null, null, null] +34570 - null - [null, null, null, null, null] +34571 - null - [null, null, null, null, null] +34572 - Swings - [null, null, null, null, null] +34573 - null - [null, null, null, null, null] +34574 - null - [null, null, null, null, null] +34575 - null - [null, null, null, null, null] +34576 - Well - [null, null, null, null, null] +34577 - Waterpump - [null, null, null, null, null] +34578 - Weather vane - [null, null, null, null, null] +34579 - Fountain - [null, null, null, null, null] +34580 - Wheelbarrow - [null, null, null, null, null] +34581 - Sack - [null, null, null, null, null] +34582 - Sack - [null, null, null, null, null] +34583 - Sacks - [Search, null, null, null, null] +34584 - null - [null, null, null, null, null] +34585 - Crate - [Search, null, null, null, null] +34586 - Crate - [Search, null, null, null, null] +34587 - Storage crate - [null, null, null, null, null] +34588 - Boxes - [Search, null, null, null, null] +34589 - Barrels - [null, null, null, null, null] +34590 - Barrel - [null, null, null, null, null] +34591 - Barrel - [null, null, null, null, null] +34592 - Barrel - [null, null, null, null, null] +34593 - Hay bales - [null, null, null, null, null] +34594 - Hay bales - [null, null, null, null, null] +34595 - null - [null, null, null, null, null] +34596 - null - [null, null, null, null, null] +34597 - null - [null, null, null, null, null] +34598 - null - [null, null, null, null, null] +34599 - null - [null, null, null, null, null] +34600 - null - [null, null, null, null, null] +34601 - null - [null, null, null, null, null] +34602 - null - [null, null, null, null, null] +34603 - null - [null, null, null, null, null] +34604 - null - [null, null, null, null, null] +34605 - null - [null, null, null, null, null] +34606 - null - [null, null, null, null, null] +34607 - null - [null, null, null, null, null] +34608 - null - [null, null, null, null, null] +34609 - null - [null, null, null, null, null] +34610 - null - [null, null, null, null, null] +34611 - null - [null, null, null, null, null] +34612 - null - [null, null, null, null, null] +34613 - null - [null, null, null, null, null] +34614 - null - [null, null, null, null, null] +34615 - Candles - [null, null, null, null, null] +34616 - Altar - [Pray, null, null, null, null] +34617 - Organ - [Play, null, null, null, null] +34618 - null - [null, null, null, null, null] +34619 - null - [null, null, null, null, null] +34620 - Gravestone - [null, null, null, null, null] +34621 - Gravestone - [null, null, null, null, null] +34622 - Gravestone - [null, null, null, null, null] +34623 - Gravestone - [null, null, null, null, null] +34624 - Gravestone - [null, null, null, null, null] +34625 - Gravestone - [null, null, null, null, null] +34626 - Gravestone - [null, null, null, null, null] +34627 - Gravestone - [null, null, null, null, null] +34628 - Gravestone - [null, null, null, null, null] +34629 - Gravestone - [null, null, null, null, null] +34630 - null - [null, null, null, null, null] +34631 - null - [null, null, null, null, null] +34632 - null - [null, null, null, null, null] +34633 - null - [null, null, null, null, null] +34634 - null - [null, null, null, null, null] +34635 - null - [null, null, null, null, null] +34636 - null - [null, null, null, null, null] +34637 - null - [null, null, null, null, null] +34638 - null - [null, null, null, null, null] +34639 - null - [null, null, null, null, null] +34640 - null - [null, null, null, null, null] +34641 - null - [null, null, null, null, null] +34642 - null - [null, null, null, null, null] +34643 - null - [null, null, null, null, null] +34644 - null - [null, null, null, null, null] +34645 - null - [null, null, null, null, null] +34646 - null - [null, null, null, null, null] +34647 - null - [null, null, null, null, null] +34648 - null - [null, null, null, null, null] +34649 - null - [null, null, null, null, null] +34650 - null - [null, null, null, null, null] +34651 - null - [null, null, null, null, null] +34652 - null - [null, null, null, null, null] +34653 - null - [null, null, null, null, null] +34654 - null - [null, null, null, null, null] +34655 - null - [null, null, null, null, null] +34656 - null - [null, null, null, null, null] +34657 - null - [null, null, null, null, null] +34658 - null - [null, null, null, null, null] +34659 - null - [null, null, null, null, null] +34660 - null - [null, null, null, null, null] +34661 - null - [null, null, null, null, null] +34662 - null - [null, null, null, null, null] +34663 - null - [null, null, null, null, null] +34664 - null - [null, null, null, null, null] +34665 - null - [null, null, null, null, null] +34666 - null - [null, null, null, null, null] +34667 - null - [null, null, null, null, null] +34668 - null - [null, null, null, null, null] +34669 - null - [null, null, null, null, null] +34670 - null - [null, null, null, null, null] +34671 - null - [null, null, null, null, null] +34672 - null - [null, null, null, null, null] +34673 - null - [null, null, null, null, null] +34674 - null - [null, null, null, null, null] +34675 - null - [null, null, null, null, null] +34676 - null - [null, null, null, null, null] +34677 - null - [null, null, null, null, null] +34678 - null - [null, null, null, null, null] +34679 - null - [null, null, null, null, null] +34680 - null - [null, null, null, null, null] +34681 - null - [null, null, null, null, null] +34682 - null - [null, null, null, null, null] +34683 - null - [null, null, null, null, null] +34684 - null - [null, null, null, null, null] +34685 - null - [null, null, null, null, null] +34686 - null - [null, null, null, null, null] +34687 - null - [null, null, null, null, null] +34688 - null - [null, null, null, null, null] +34689 - null - [null, null, null, null, null] +34690 - null - [null, null, null, null, null] +34691 - null - [null, null, null, null, null] +34692 - null - [null, null, null, null, null] +34693 - null - [null, null, null, null, null] +34694 - null - [null, null, null, null, null] +34695 - null - [null, null, null, null, null] +34696 - null - [null, null, null, null, null] +34697 - null - [null, null, null, null, null] +34698 - null - [null, null, null, null, null] +34699 - null - [null, null, null, null, null] +34700 - null - [null, null, null, null, null] +34701 - null - [null, null, null, null, null] +34702 - null - [null, null, null, null, null] +34703 - null - [null, null, null, null, null] +34704 - null - [null, null, null, null, null] +34705 - null - [null, null, null, null, null] +34706 - null - [null, null, null, null, null] +34707 - null - [null, null, null, null, null] +34708 - null - [null, null, null, null, null] +34709 - null - [null, null, null, null, null] +34710 - null - [null, null, null, null, null] +34711 - null - [null, null, null, null, null] +34712 - null - [null, null, null, null, null] +34713 - null - [null, null, null, null, null] +34714 - null - [null, null, null, null, null] +34715 - null - [null, null, null, null, null] +34716 - null - [null, null, null, null, null] +34717 - null - [null, null, null, null, null] +34718 - null - [null, null, null, null, null] +34719 - null - [null, null, null, null, null] +34720 - null - [null, null, null, null, null] +34721 - null - [null, null, null, null, null] +34722 - null - [null, null, null, null, null] +34723 - null - [null, null, null, null, null] +34724 - null - [null, null, null, null, null] +34725 - null - [null, null, null, null, null] +34726 - null - [null, null, null, null, null] +34727 - null - [null, null, null, null, null] +34728 - null - [null, null, null, null, null] +34729 - null - [null, null, null, null, null] +34730 - null - [null, null, null, null, null] +34731 - null - [null, null, null, null, null] +34732 - null - [null, null, null, null, null] +34733 - null - [null, null, null, null, null] +34734 - null - [null, null, null, null, null] +34735 - null - [null, null, null, null, null] +34736 - null - [null, null, null, null, null] +34737 - null - [null, null, null, null, null] +34738 - Gate - [null, null, null, null, null] +34739 - null - [null, null, null, null, null] +34740 - Bar - [null, null, null, null, null] +34741 - Bar - [null, null, null, null, null] +34742 - Bar - [null, null, null, null, null] +34743 - Bar - [null, null, null, null, null] +34744 - Bar - [null, null, null, null, null] +34745 - Bar - [null, null, null, null, null] +34746 - Bar - [null, null, null, null, null] +34747 - Bar - [null, null, null, null, null] +34748 - Bar - [null, null, null, null, null] +34749 - null - [null, null, null, null, null] +34750 - Barstool - [null, null, null, null, null] +34751 - Small table - [null, null, null, null, null] +34752 - Bank booth - [Use, Use-quickly, Collect, null, null] +34753 - null - [null, null, null, null, null] +34754 - null - [null, null, null, null, null] +34755 - Bank deposit box - [Deposit, null, null, null, null] +34756 - Safe - [null, null, null, null, null] +34757 - null - [null, null, null, null, null] +34758 - null - [null, null, null, null, null] +34759 - null - [null, null, null, null, null] +34760 - null - [null, null, null, null, null] +34761 - null - [null, null, null, null, null] +34762 - null - [null, null, null, null, null] +34763 - null - [null, null, null, null, null] +34764 - null - [null, null, null, null, null] +34765 - null - [null, null, null, null, null] +34766 - null - [null, null, null, null, null] +34767 - null - [null, null, null, null, null] +34768 - Stairs - [Climb-up, null, null, null, null] +34769 - Stairs - [Climb-down, null, null, null, null] +34770 - Stairs - [Climb-up, null, null, null, null] +34771 - Stairs - [Climb-down, null, null, null, null] +34772 - null - [null, null, null, null, null] +34773 - null - [null, null, null, null, null] +34774 - null - [null, null, null, null, null] +34775 - null - [null, null, null, null, null] +34776 - Stile - [Climb-over, null, null, null, null] +34777 - Gate - [Close, null, null, null, null] +34778 - Gate - [Close, null, null, null, null] +34779 - Gate - [Open, null, null, null, null] +34780 - Gate - [Open, null, null, null, null] +34781 - null - [null, null, null, null, null] +34782 - null - [null, null, null, null, null] +34783 - null - [null, null, null, null, null] +34784 - null - [null, null, null, null, null] +34785 - Ladder - [Climb-up, null, null, null, null] +34786 - Ladder - [Climb-up, null, null, null, null] +34787 - Ladder - [Climb, Climb-up, Climb-down, null, null] +34788 - Ladder - [Climb-down, null, null, null, null] +34789 - Ladder - [Climb-down, null, null, null, null] +34790 - null - [null, null, null, null, null] +34791 - null - [null, null, null, null, null] +34792 - null - [null, null, null, null, null] +34793 - null - [null, null, null, null, null] +34794 - null - [null, null, null, null, null] +34795 - null - [null, null, null, null, null] +34796 - Coal - [null, null, null, null, null] +34797 - null - [null, null, null, null, null] +34798 - Sewing machine - [null, null, null, null, null] +34799 - Table - [null, null, null, null, null] +34800 - Dairy churn - [Churn, null, null, null, null] +34801 - Potter's Wheel - [null, null, null, null, null] +34802 - Pottery Oven - [Fire, null, null, null, null] +34803 - null - [null, null, null, null, null] +34804 - null - [null, null, null, null, null] +34805 - Door - [Open, Pick-lock, null, null, null] +34806 - Door - [Open, Pick-lock, null, null, null] +34807 - Door - [Open, null, null, null, null] +34808 - Door - [Close, null, null, null, null] +34809 - Door - [Open, null, null, null, null] +34810 - Door - [Close, null, null, null, null] +34811 - Door - [Open, null, null, null, null] +34812 - Door - [Open, Pick-lock, null, null, null] +34813 - Door - [Close, null, null, null, null] +34814 - null - [null, null, null, null, null] +34815 - null - [null, null, null, null, null] +34816 - Door - [Open, null, null, null, null] +34817 - Door - [Open, null, null, null, null] +34818 - Door - [Close, null, null, null, null] +34819 - Door - [Open, null, null, null, null] +34820 - Door - [Close, null, null, null, null] +34821 - null - [null, null, null, null, null] +34822 - Door - [Open, null, null, null, null] +34823 - Door - [Close, null, null, null, null] +34824 - null - [null, null, null, null, null] +34825 - Wooden Door - [Open, null, null, null, null] +34826 - Wooden Door - [Close, null, null, null, null] +34827 - Wooden Door - [Open, null, null, null, null] +34828 - Wooden Door - [Close, null, null, null, null] +34829 - Ladder - [Climb-up, null, null, null, null] +34830 - null - [null, null, null, null, null] +34831 - null - [null, null, null, null, null] +34832 - null - [null, null, null, null, null] +34833 - null - [null, null, null, null, null] +34834 - null - [null, null, null, null, null] +34835 - null - [null, null, null, null, null] +34836 - null - [null, null, null, null, null] +34837 - null - [null, null, null, null, null] +34838 - null - [null, null, null, null, null] +34839 - null - [null, null, null, null, null] +34840 - Rack - [null, null, null, null, null] +34841 - null - [null, null, null, null, null] +34842 - null - [null, null, null, null, null] +34843 - null - [null, null, null, null, null] +34844 - null - [null, null, null, null, null] +34845 - null - [null, null, null, null, null] +34846 - null - [null, null, null, null, null] +34847 - null - [null, null, null, null, null] +34848 - null - [null, null, null, null, null] +34849 - null - [null, null, null, null, null] +34850 - null - [null, null, null, null, null] +34851 - null - [null, null, null, null, null] +34852 - null - [null, null, null, null, null] +34853 - null - [null, null, null, null, null] +34854 - null - [null, null, null, null, null] +34855 - null - [null, null, null, null, null] +34856 - null - [null, null, null, null, null] +34857 - null - [null, null, null, null, null] +34858 - null - [null, null, null, null, null] +34859 - null - [null, null, null, null, null] +34860 - null - [null, null, null, null, null] +34861 - null - [null, null, null, null, null] +34862 - null - [null, null, null, null, null] +34863 - null - [null, null, null, null, null] +34864 - null - [null, null, null, null, null] +34865 - null - [null, null, null, null, null] +34866 - null - [null, null, null, null, null] +34867 - null - [null, null, null, null, null] +34868 - null - [null, null, null, null, null] +34869 - null - [null, null, null, null, null] +34870 - null - [null, null, null, null, null] +34871 - Staircase - [Climb-up, null, null, null, null] +34872 - Staircase - [Climb, Climb-up, Climb-down, null, null] +34873 - Staircase - [Climb-down, null, null, null, null] +34874 - Staircase - [Climb-up, null, null, null, null] +34875 - Staircase - [Climb, Climb-up, Climb-down, null, null] +34876 - Staircase - [Climb-down, null, null, null, null] +34877 - Ladder - [Climb-up, null, null, null, null] +34878 - Ladder - [Climb-down, null, null, null, null] +34879 - null - [null, null, null, null, null] +34880 - null - [null, null, null, null, null] +34881 - null - [null, null, null, null, null] +34882 - null - [null, null, null, null, null] +34883 - null - [null, null, null, null, null] +34884 - null - [null, null, null, null, null] +34885 - null - [null, null, null, null, null] +34886 - null - [null, null, null, null, null] +34887 - Axe cabinet - [null, null, null, null, null] +34888 - Sword cabinet - [null, null, null, null, null] +34889 - Wardrobe - [null, null, null, null, null] +34890 - Wardrobe - [null, null, null, null, null] +34891 - Throne - [null, null, null, null, null] +34892 - Dresser - [null, null, null, null, null] +34893 - null - [null, null, null, null, null] +34894 - null - [null, null, null, null, null] +34895 - null - [null, null, null, null, null] +34896 - null - [null, null, null, null, null] +34897 - null - [null, null, null, null, null] +34898 - null - [null, null, null, null, null] +34899 - Rope - [null, null, null, null, null] +34900 - null - [null, null, null, null, null] +34901 - null - [null, null, null, null, null] +34902 - Statue of Baxtorian - [null, null, null, null, null] +34903 - Statue of Glarial - [null, null, null, null, null] +34904 - null - [null, null, null, null, null] +34905 - Chalice of Eternity - [null, null, null, null, null] +34906 - null - [null, null, null, null, null] +34907 - null - [null, null, null, null, null] +34908 - null - [null, null, null, null, null] +34909 - null - [null, null, null, null, null] +34910 - null - [null, null, null, null, null] +34911 - null - [null, null, null, null, null] +34912 - null - [null, null, null, null, null] +34913 - null - [null, null, null, null, null] +34914 - null - [null, null, null, null, null] +34915 - Waterfall - [null, null, null, null, null] +34916 - null - [null, null, null, null, null] +34917 - Jagged wall - [Look, Jump-over, null, null, null] +34918 - null - [null, null, null, null, null] +34919 - null - [null, null, null, null, null] +34920 - null - [null, null, null, null, null] +34921 - null - [null, null, null, null, null] +34922 - null - [null, null, null, null, null] +34923 - null - [null, null, null, null, null] +34924 - null - [null, null, null, null, null] +34925 - Shelf - [null, null, null, null, null] +34926 - Shelf - [null, null, null, null, null] +34927 - Table - [null, null, null, null, null] +34928 - Wallchart - [null, null, null, null, null] +34929 - null - [null, null, null, null, null] +34930 - null - [null, null, null, null, null] +34931 - null - [null, null, null, null, null] +34932 - Hammock - [null, null, null, null, null] +34933 - Sack - [null, null, null, null, null] +34934 - Barrel - [null, null, null, null, null] +34935 - null - [null, null, null, null, null] +34936 - Extra anchor - [null, null, null, null, null] +34937 - Lantern - [null, null, null, null, null] +34938 - Lantern - [null, null, null, null, null] +34939 - null - [null, null, null, null, null] +34940 - null - [null, null, null, null, null] +34941 - null - [null, null, null, null, null] +34942 - null - [null, null, null, null, null] +34943 - null - [null, null, null, null, null] +34944 - null - [null, null, null, null, null] +34945 - null - [null, null, null, null, null] +34946 - null - [null, null, null, null, null] +34947 - Solid bronze door - [Open, null, null, null, null] +34948 - null - [null, null, null, null, null] +34949 - null - [null, null, null, null, null] +34950 - null - [null, null, null, null, null] +34951 - null - [null, null, null, null, null] +34952 - null - [null, null, null, null, null] +34953 - null - [null, null, null, null, null] +34954 - null - [null, null, null, null, null] +34955 - null - [null, null, null, null, null] +34956 - null - [null, null, null, null, null] +34957 - null - [null, null, null, null, null] +34958 - null - [null, null, null, null, null] +34959 - null - [null, null, null, null, null] +34960 - null - [null, null, null, null, null] +34961 - null - [null, null, null, null, null] +34962 - null - [null, null, null, null, null] +34963 - Cave exit - [Exit, null, null, null, null] +34964 - null - [null, null, null, null, null] +34965 - null - [null, null, null, null, null] +34966 - null - [null, null, null, null, null] +34967 - null - [null, null, null, null, null] +34968 - Table - [null, null, null, null, null] +34969 - null - [null, null, null, null, null] +34970 - null - [null, null, null, null, null] +34971 - null - [null, null, null, null, null] +34972 - null - [null, null, null, null, null] +34973 - null - [null, null, null, null, null] +34974 - null - [null, null, null, null, null] +34975 - null - [null, null, null, null, null] +34976 - Mineral vein - [Mine, Prospect, null, null, null] +34977 - Mineral vein - [Mine, Prospect, null, null, null] +34978 - Staircase - [Climb-down, null, null, null, null] +34979 - Skeleton - [null, null, null, null, null] +34980 - null - [null, null, null, null, null] +34981 - null - [null, null, null, null, null] +34982 - null - [null, null, null, null, null] +34983 - null - [null, null, null, null, null] +34984 - null - [null, null, null, null, null] +34985 - null - [null, null, null, null, null] +34986 - null - [null, null, null, null, null] +34987 - null - [null, null, null, null, null] +34988 - Crater - [null, null, null, null, null] +34989 - null - [null, null, null, null, null] +34990 - null - [null, null, null, null, null] +34991 - null - [null, null, null, null, null] +34992 - null - [null, null, null, null, null] +34993 - null - [null, null, null, null, null] +34994 - null - [null, null, null, null, null] +34995 - Ladder - [Climb-down, null, null, null, null] +34996 - null - [null, null, null, null, null] +34997 - null - [null, null, null, null, null] +34998 - null - [null, null, null, null, null] +34999 - null - [null, null, null, null, null] +35000 - null - [null, null, null, null, null] +35001 - null - [null, null, null, null, null] +35002 - Cave Exit - [Exit, null, null, null, null] +35003 - null - [null, null, null, null, null] +35004 - null - [null, null, null, null, null] +35005 - null - [null, null, null, null, null] +35006 - null - [null, null, null, null, null] +35007 - null - [null, null, null, null, null] +35008 - null - [null, null, null, null, null] +35009 - null - [null, null, null, null, null] +35010 - null - [null, null, null, null, null] +35011 - null - [null, null, null, null, null] +35012 - null - [null, null, null, null, null] +35013 - null - [null, null, null, null, null] +35014 - null - [null, null, null, null, null] +35015 - crate - [null, null, null, null, null] +35016 - null - [null, null, null, null, null] +35017 - barrel - [null, null, null, null, null] +35018 - null - [null, null, null, null, null] +35019 - null - [null, null, null, null, null] +35020 - null - [null, null, null, null, null] +35021 - null - [null, null, null, null, null] +35022 - null - [null, null, null, null, null] +35023 - null - [null, null, null, null, null] +35024 - null - [null, null, null, null, null] +35025 - null - [null, null, null, null, null] +35026 - null - [null, null, null, null, null] +35027 - null - [null, null, null, null, null] +35028 - null - [null, null, null, null, null] +35029 - null - [null, null, null, null, null] +35030 - null - [null, null, null, null, null] +35031 - null - [null, null, null, null, null] +35032 - null - [null, null, null, null, null] +35033 - null - [null, null, null, null, null] +35034 - null - [null, null, null, null, null] +35035 - null - [null, null, null, null, null] +35036 - null - [null, null, null, null, null] +35037 - null - [null, null, null, null, null] +35038 - null - [null, null, null, null, null] +35039 - null - [null, null, null, null, null] +35040 - null - [null, null, null, null, null] +35041 - null - [null, null, null, null, null] +35042 - null - [null, null, null, null, null] +35043 - null - [null, null, null, null, null] +35044 - null - [null, null, null, null, null] +35045 - null - [null, null, null, null, null] +35046 - null - [null, null, null, null, null] +35047 - null - [null, null, null, null, null] +35048 - null - [null, null, null, null, null] +35049 - null - [null, null, null, null, null] +35050 - null - [null, null, null, null, null] +35051 - null - [null, null, null, null, null] +35052 - null - [null, null, null, null, null] +35053 - null - [null, null, null, null, null] +35054 - null - [null, null, null, null, null] +35055 - null - [null, null, null, null, null] +35056 - null - [null, null, null, null, null] +35057 - null - [null, null, null, null, null] +35058 - null - [null, null, null, null, null] +35059 - null - [null, null, null, null, null] +35060 - null - [null, null, null, null, null] +35061 - null - [null, null, null, null, null] +35062 - null - [null, null, null, null, null] +35063 - null - [null, null, null, null, null] +35064 - null - [null, null, null, null, null] +35065 - null - [null, null, null, null, null] +35066 - null - [null, null, null, null, null] +35067 - null - [null, null, null, null, null] +35068 - null - [null, null, null, null, null] +35069 - null - [null, null, null, null, null] +35070 - null - [null, null, null, null, null] +35071 - null - [null, null, null, null, null] +35072 - null - [null, null, null, null, null] +35073 - null - [null, null, null, null, null] +35074 - null - [null, null, null, null, null] +35075 - null - [null, null, null, null, null] +35076 - null - [null, null, null, null, null] +35077 - Tent - [null, null, null, null, null] +35078 - Ogre Coffin - [Open, Pick-lock, null, hidden, null] +35079 - Ogre Coffin - [Open, Pick-lock, null, hidden, null] +35080 - Ogre Coffin - [Open, Pick-lock, null, hidden, null] +35081 - Ogre Coffin - [null, null, null, null, null] +35082 - Ogre Coffin - [null, null, null, null, null] +35083 - Ogre Coffin - [null, null, null, null, null] +35084 - Ogre Coffin - [null, null, null, null, null] +35085 - Ogre Coffin - [Open, Pick-lock, null, hidden, null] +35086 - Statue - [null, null, null, null, null] +35087 - Statue - [null, null, null, null, null] +35088 - null - [null, null, null, null, null] +35089 - null - [null, null, null, null, null] +35090 - null - [null, null, null, null, null] +35091 - null - [null, null, null, null, null] +35092 - null - [null, null, null, null, null] +35093 - null - [null, null, null, null, null] +35094 - null - [null, null, null, null, null] +35095 - Fremennik boat - [null, null, null, null, null] +35096 - null - [null, null, null, null, null] +35097 - null - [null, null, null, null, null] +35098 - null - [null, null, null, null, null] +35099 - null - [null, null, null, null, null] +35100 - null - [null, null, null, null, null] +35101 - Torch - [null, null, null, null, null] +35102 - Torch - [null, null, null, null, null] +35103 - null - [null, null, null, null, null] +35104 - null - [null, null, null, null, null] +35105 - null - [null, null, null, null, null] +35106 - null - [null, null, null, null, null] +35107 - null - [null, null, null, null, null] +35108 - null - [null, null, null, null, null] +35109 - null - [null, null, null, null, null] +35110 - null - [null, null, null, null, null] +35111 - null - [null, null, null, null, null] +35112 - null - [null, null, null, null, null] +35113 - null - [null, null, null, null, null] +35114 - null - [null, null, null, null, null] +35115 - null - [null, null, null, null, null] +35116 - null - [null, null, null, null, null] +35117 - null - [null, null, null, null, null] +35118 - null - [null, null, null, null, null] +35119 - null - [null, null, null, null, null] +35120 - null - [null, null, null, null, null] +35121 - Stairs - [Climb-down, null, null, null, null] +35122 - Closed chest - [Open, null, null, null, null] +35123 - Open chest - [Search, Shut, null, null, null] +35124 - null - [null, null, null, null, null] +35125 - Ladder - [Climb-up, null, null, null, null] +35126 - Tunnel - [Enter, null, null, null, null] +35127 - Tunnel - [Enter, null, null, null, null] +35128 - null - [null, null, null, null, null] +35129 - null - [null, null, null, null, null] +35130 - null - [null, null, null, null, null] +35131 - null - [null, null, null, null, null] +35132 - null - [null, null, null, null, null] +35133 - Wardrobe - [null, Search, Close, null, null] +35134 - Wardrobe - [null, Search, Close, null, null] +35135 - Wardrobe - [null, Search, Close, null, null] +35136 - Wardrobe - [null, Search, Close, null, null] +35137 - null - [null, null, null, null, null] +35138 - null - [null, null, null, null, null] +35139 - null - [null, null, null, null, null] +35140 - Pillar - [null, null, null, null, null] +35141 - Pillar - [null, null, null, null, null] +35142 - null - [null, null, null, null, null] +35143 - null - [null, null, null, null, null] +35144 - null - [null, null, null, null, null] +35145 - Flag - [null, null, null, null, null] +35146 - Door - [Open, null, null, null, null] +35147 - null - [null, null, null, null, null] +35148 - Boxes - [null, null, null, null, null] +35149 - Chair - [null, null, null, null, null] +35150 - Rat barrel - [null, null, null, null, null] +35151 - Rat barrel - [null, null, null, null, null] +35152 - null - [null, null, null, null, null] +35153 - null - [null, null, null, null, null] +35154 - null - [null, null, null, null, null] +35155 - null - [null, null, null, null, null] +35156 - A bunk bed - [null, null, null, null, null] +35157 - null - [null, null, null, null, null] +35158 - Rift - [Enter, null, null, null, null] +35159 - Rift - [Enter, null, null, null, null] +35160 - null - [null, null, null, null, null] +35161 - null - [null, null, null, null, null] +35162 - null - [null, null, null, null, null] +35163 - null - [null, null, null, null, null] +35164 - null - [null, null, null, null, null] +35165 - null - [null, null, null, null, null] +35166 - null - [null, null, null, null, null] +35167 - null - [null, null, null, null, null] +35168 - null - [null, null, null, null, null] +35169 - null - [null, null, null, null, null] +35170 - null - [null, null, null, null, null] +35171 - null - [null, null, null, null, null] +35172 - null - [null, null, null, null, null] +35173 - null - [null, null, null, null, null] +35174 - null - [null, null, null, null, null] +35175 - null - [null, null, null, null, null] +35176 - null - [null, null, null, null, null] +35177 - null - [null, null, null, null, null] +35178 - null - [null, null, null, null, null] +35179 - null - [null, null, null, null, null] +35180 - null - [null, null, null, null, null] +35181 - null - [null, null, null, null, null] +35182 - null - [null, null, null, null, null] +35183 - null - [null, null, null, null, null] +35184 - null - [null, null, null, null, null] +35185 - null - [null, null, null, null, null] +35186 - null - [null, null, null, null, null] +35187 - null - [null, null, null, null, null] +35188 - null - [null, null, null, null, null] +35189 - null - [null, null, null, null, null] +35190 - null - [null, null, null, null, null] +35191 - null - [null, null, null, null, null] +35192 - Boat - [null, null, null, null, null] +35193 - null - [null, null, null, null, null] +35194 - null - [null, null, null, null, null] +35195 - null - [null, null, null, null, null] +35196 - null - [null, null, null, null, null] +35197 - null - [null, null, null, null, null] +35198 - null - [null, null, null, null, null] +35199 - null - [null, null, null, null, null] +35200 - null - [null, null, null, null, null] +35201 - null - [null, null, null, null, null] +35202 - null - [null, null, null, null, null] +35203 - null - [null, null, null, null, null] +35204 - null - [null, null, null, null, null] +35205 - null - [null, null, null, null, null] +35206 - null - [null, null, null, null, null] +35207 - null - [null, null, null, null, null] +35208 - null - [null, null, null, null, null] +35209 - null - [null, null, null, null, null] +35210 - null - [null, null, null, null, null] +35211 - null - [null, null, null, null, null] +35212 - null - [null, null, null, null, null] +35213 - null - [null, null, null, null, null] +35214 - null - [null, null, null, null, null] +35215 - null - [null, null, null, null, null] +35216 - null - [null, null, null, null, null] +35217 - null - [null, null, null, null, null] +35218 - null - [null, null, null, null, null] +35219 - null - [null, null, null, null, null] +35220 - null - [null, null, null, null, null] +35221 - Bench - [null, null, null, null, null] +35222 - Cupboard - [Open, null, null, null, null] +35223 - Cupboard - [Close, Search, null, null, null] +35224 - Bookcase - [Search, null, null, null, null] +35225 - Bookcase - [Search, null, null, null, null] +35226 - Bookcase - [Search, null, null, null, null] +35227 - Bookcase - [Search, null, null, null, null] +35228 - null - [null, null, null, null, null] +35229 - null - [null, null, null, null, null] +35230 - null - [null, null, null, null, null] +35231 - null - [null, null, null, null, null] +35232 - null - [null, null, null, null, null] +35233 - null - [null, null, null, null, null] +35234 - null - [null, null, null, null, null] +35235 - null - [null, null, null, null, null] +35236 - null - [null, null, null, null, null] +35237 - null - [null, null, null, null, null] +35238 - null - [null, null, null, null, null] +35239 - null - [null, null, null, null, null] +35240 - null - [null, null, null, null, null] +35241 - Door - [Open, null, null, null, null] +35242 - Door - [Close, null, null, null, null] +35243 - Door - [Open, null, null, null, null] +35244 - null - [null, null, null, null, null] +35245 - null - [null, null, null, null, null] +35246 - null - [null, null, null, null, null] +35247 - null - [null, null, null, null, null] +35248 - null - [null, null, null, null, null] +35249 - null - [null, null, null, null, null] +35250 - null - [null, null, null, null, null] +35251 - null - [null, null, null, null, null] +35252 - null - [null, null, null, null, null] +35253 - null - [null, null, null, null, null] +35254 - null - [null, null, null, null, null] +35255 - null - [null, null, null, null, null] +35256 - null - [null, null, null, null, null] +35257 - null - [null, null, null, null, null] +35258 - null - [null, null, null, null, null] +35259 - null - [null, null, null, null, null] +35260 - null - [null, null, null, null, null] +35261 - null - [null, null, null, null, null] +35262 - null - [null, null, null, null, null] +35263 - null - [null, null, null, null, null] +35264 - null - [null, null, null, null, null] +35265 - null - [null, null, null, null, null] +35266 - null - [null, null, null, null, null] +35267 - null - [null, null, null, null, null] +35268 - null - [null, null, null, null, null] +35269 - null - [null, null, null, null, null] +35270 - null - [null, null, null, null, null] +35271 - null - [null, null, null, null, null] +35272 - null - [null, null, null, null, null] +35273 - null - [null, null, null, null, null] +35274 - null - [null, null, null, null, null] +35275 - null - [null, null, null, null, null] +35276 - null - [null, null, null, null, null] +35277 - null - [null, null, null, null, null] +35278 - null - [null, null, null, null, null] +35279 - null - [null, null, null, null, null] +35280 - null - [null, null, null, null, null] +35281 - null - [null, null, null, null, null] +35282 - null - [null, null, null, null, null] +35283 - null - [null, null, null, null, null] +35284 - null - [null, null, null, null, null] +35285 - null - [null, null, null, null, null] +35286 - null - [null, null, null, null, null] +35287 - null - [null, null, null, null, null] +35288 - null - [null, null, null, null, null] +35289 - null - [null, null, null, null, null] +35290 - null - [null, null, null, null, null] +35291 - null - [null, null, null, null, null] +35292 - null - [null, null, null, null, null] +35293 - null - [null, null, null, null, null] +35294 - null - [null, null, null, null, null] +35295 - null - [null, null, null, null, null] +35296 - null - [null, null, null, null, null] +35297 - null - [null, null, null, null, null] +35298 - null - [null, null, null, null, null] +35299 - null - [null, null, null, null, null] +35300 - null - [null, null, null, null, null] +35301 - null - [null, null, null, null, null] +35302 - null - [null, null, null, null, null] +35303 - null - [null, null, null, null, null] +35304 - null - [null, null, null, null, null] +35305 - null - [null, null, null, null, null] +35306 - null - [null, null, null, null, null] +35307 - null - [null, null, null, null, null] +35308 - null - [null, null, null, null, null] +35309 - null - [null, null, null, null, null] +35310 - null - [null, null, null, null, null] +35311 - null - [null, null, null, null, null] +35312 - null - [null, null, null, null, null] +35313 - null - [null, null, null, null, null] +35314 - null - [null, null, null, null, null] +35315 - null - [null, null, null, null, null] +35316 - null - [null, null, null, null, null] +35317 - null - [null, null, null, null, null] +35318 - null - [null, null, null, null, null] +35319 - null - [null, null, null, null, null] +35320 - null - [null, null, null, null, null] +35321 - null - [null, null, null, null, null] +35322 - null - [null, null, null, null, null] +35323 - null - [null, null, null, null, null] +35324 - null - [null, null, null, null, null] +35325 - null - [null, null, null, null, null] +35326 - null - [null, null, null, null, null] +35327 - null - [null, null, null, null, null] +35328 - null - [null, null, null, null, null] +35329 - null - [null, null, null, null, null] +35330 - null - [null, null, null, null, null] +35331 - null - [null, null, null, null, null] +35332 - null - [null, null, null, null, null] +35333 - null - [null, null, null, null, null] +35334 - null - [null, null, null, null, null] +35335 - null - [null, null, null, null, null] +35336 - null - [null, null, null, null, null] +35337 - null - [null, null, null, null, null] +35338 - null - [null, null, null, null, null] +35339 - null - [null, null, null, null, null] +35340 - null - [null, null, null, null, null] +35341 - null - [null, null, null, null, null] +35342 - null - [null, null, null, null, null] +35343 - null - [null, null, null, null, null] +35344 - null - [null, null, null, null, null] +35345 - null - [null, null, null, null, null] +35346 - null - [null, null, null, null, null] +35347 - null - [null, null, null, null, null] +35348 - null - [null, null, null, null, null] +35349 - null - [null, null, null, null, null] +35350 - null - [null, null, null, null, null] +35351 - null - [null, null, null, null, null] +35352 - null - [null, null, null, null, null] +35353 - null - [null, null, null, null, null] +35354 - null - [null, null, null, null, null] +35355 - null - [null, null, null, null, null] +35356 - null - [null, null, null, null, null] +35357 - null - [null, null, null, null, null] +35358 - null - [null, null, null, null, null] +35359 - null - [null, null, null, null, null] +35360 - null - [null, null, null, null, null] +35361 - null - [null, null, null, null, null] +35362 - null - [null, null, null, null, null] +35363 - null - [null, null, null, null, null] +35364 - null - [null, null, null, null, null] +35365 - null - [null, null, null, null, null] +35366 - null - [null, null, null, null, null] +35367 - null - [null, null, null, null, null] +35368 - null - [null, null, null, null, null] +35369 - null - [null, null, null, null, null] +35370 - null - [null, null, null, null, null] +35371 - null - [null, null, null, null, null] +35372 - null - [null, null, null, null, null] +35373 - null - [null, null, null, null, null] +35374 - null - [null, null, null, null, null] +35375 - null - [null, null, null, null, null] +35376 - null - [null, null, null, null, null] +35377 - null - [null, null, null, null, null] +35378 - null - [null, null, null, null, null] +35379 - Mushroom - [null, null, null, null, null] +35380 - Mushrooms - [null, null, null, null, null] +35381 - null - [null, null, null, null, null] +35382 - null - [null, null, null, null, null] +35383 - Bed - [null, null, null, null, null] +35384 - Bed - [null, null, null, null, null] +35385 - Painting - [null, null, null, null, null] +35386 - Dragon's head - [null, null, null, null, null] +35387 - Clothes equipment - [null, null, null, null, null] +35388 - Bow cabinet - [null, null, null, null, null] +35389 - null - [null, null, null, null, null] +35390 - null - [null, null, null, null, null] +35391 - null - [null, null, null, null, null] +35392 - null - [null, null, null, null, null] +35393 - null - [null, null, null, null, null] +35394 - null - [null, null, null, null, null] +35395 - null - [null, null, null, null, null] +35396 - null - [null, null, null, null, null] +35397 - null - [null, null, null, null, null] +35398 - null - [null, null, null, null, null] +35399 - null - [null, null, null, null, null] +35400 - Shantay Pass - [Go-through, Look-at, Quick-pass, null, null] +35401 - Jail Door - [Open, null, null, null, null] +35402 - null - [null, null, null, null, null] +35403 - null - [null, null, null, null, null] +35404 - null - [null, null, null, null, null] +35405 - null - [null, null, null, null, null] +35406 - null - [null, null, null, null, null] +35407 - null - [null, null, null, null, null] +35408 - null - [null, null, null, null, null] +35409 - null - [null, null, null, null, null] +35410 - null - [null, null, null, null, null] +35411 - null - [null, null, null, null, null] +35412 - null - [null, null, null, null, null] +35413 - null - [null, null, null, null, null] +35414 - null - [null, null, null, null, null] +35415 - null - [null, null, null, null, null] +35416 - Cactus - [null, null, null, null, null] +35417 - Cactus - [null, null, null, null, null] +35418 - Cactus - [null, null, null, null, null] +35419 - Cactus - [null, null, null, null, null] +35420 - Cactus - [null, null, null, null, null] +35421 - Cactus - [null, null, null, null, null] +35422 - Cactus - [null, null, null, null, null] +35423 - Cactus - [null, null, null, null, null] +35424 - Cactus - [null, null, null, null, null] +35425 - Cactus - [null, null, null, null, null] +35426 - Cactus - [null, null, null, null, null] +35427 - Cactus - [null, null, null, null, null] +35428 - Cactus - [null, null, null, null, null] +35429 - Cactus - [null, null, null, null, null] +35430 - Cactus - [null, null, null, null, null] +35431 - null - [null, null, null, null, null] +35432 - Plant - [null, null, null, null, null] +35433 - null - [null, null, null, null, null] +35434 - null - [null, null, null, null, null] +35435 - null - [null, null, null, null, null] +35436 - null - [null, null, null, null, null] +35437 - Gem stall - [null, null, null, null, null] +35438 - Information - [null, null, null, null, null] +35439 - Gnome glider - [null, null, null, null, null] +35440 - null - [null, null, null, null, null] +35441 - null - [null, null, null, null, null] +35442 - null - [null, null, null, null, null] +35443 - null - [null, null, null, null, null] +35444 - null - [null, null, null, null, null] +35445 - null - [null, null, null, null, null] +35446 - null - [null, null, null, null, null] +35447 - null - [null, null, null, null, null] +35448 - Kebab cooker - [null, null, null, null, null] +35449 - Fireplace - [null, null, null, null, null] +35450 - null - [null, null, null, null, null] +35451 - Chair - [null, null, null, null, null] +35452 - Throne - [null, null, null, null, null] +35453 - Palatial table - [null, null, null, null, null] +35454 - Opulent table - [null, null, null, null, null] +35455 - Mini-table - [null, null, null, null, null] +35456 - A display case - [null, null, null, null, null] +35457 - Large urns - [null, null, null, null, null] +35458 - Urns - [null, null, null, null, null] +35459 - null - [null, null, null, null, null] +35460 - null - [null, null, null, null, null] +35461 - null - [null, null, null, null, null] +35462 - null - [null, null, null, null, null] +35463 - null - [null, null, null, null, null] +35464 - null - [null, null, null, null, null] +35465 - null - [null, null, null, null, null] +35466 - null - [null, null, null, null, null] +35467 - null - [null, null, null, null, null] +35468 - null - [null, null, null, null, null] +35469 - Carved fountain - [null, null, null, null, null] +35470 - Ornate Chest - [Open, null, null, null, null] +35471 - Ornate chest - [Close, Search, null, null, null] +35472 - null - [null, null, null, null, null] +35473 - null - [null, null, null, null, null] +35474 - Divan - [null, null, null, null, null] +35475 - null - [null, null, null, null, null] +35476 - null - [null, null, null, null, null] +35477 - null - [null, null, null, null, null] +35478 - null - [null, null, null, null, null] +35479 - null - [null, null, null, null, null] +35480 - null - [null, null, null, null, null] +35481 - null - [null, null, null, null, null] +35482 - null - [null, null, null, null, null] +35483 - null - [null, null, null, null, null] +35484 - null - [null, null, null, null, null] +35485 - null - [null, null, null, null, null] +35486 - null - [null, null, null, null, null] +35487 - null - [null, null, null, null, null] +35488 - null - [null, null, null, null, null] +35489 - null - [null, null, null, null, null] +35490 - null - [null, null, null, null, null] +35491 - null - [null, null, null, null, null] +35492 - null - [null, null, null, null, null] +35493 - null - [null, null, null, null, null] +35494 - null - [null, null, null, null, null] +35495 - null - [null, null, null, null, null] +35496 - null - [null, null, null, null, null] +35497 - null - [null, null, null, null, null] +35498 - null - [null, null, null, null, null] +35499 - null - [null, null, null, null, null] +35500 - null - [null, null, null, null, null] +35501 - null - [null, null, null, null, null] +35502 - null - [null, null, null, null, null] +35503 - null - [null, null, null, null, null] +35504 - null - [null, null, null, null, null] +35505 - null - [null, null, null, null, null] +35506 - null - [null, null, null, null, null] +35507 - null - [null, null, null, null, null] +35508 - null - [null, null, null, null, null] +35509 - null - [null, null, null, null, null] +35510 - null - [null, null, null, null, null] +35511 - null - [null, null, null, null, null] +35512 - null - [null, null, null, null, null] +35513 - null - [null, null, null, null, null] +35514 - null - [null, null, null, null, null] +35515 - null - [null, null, null, null, null] +35516 - Steps - [Climb-up, null, null, null, null] +35517 - Steps - [null, null, null, null, null] +35518 - Steps - [Climb-down, null, null, null, null] +35519 - null - [null, null, null, null, null] +35520 - Large door - [Open, null, null, null, null] +35521 - null - [null, null, null, null, null] +35522 - null - [null, null, null, null, null] +35523 - null - [null, null, null, null, null] +35524 - null - [null, null, null, null, null] +35525 - Werewolf statue - [null, null, null, null, null] +35526 - Statue - [null, null, null, null, null] +35527 - null - [null, null, null, null, null] +35528 - null - [null, null, null, null, null] +35529 - null - [null, null, null, null, null] +35530 - null - [null, null, null, null, null] +35531 - null - [null, null, null, null, null] +35532 - null - [null, null, null, null, null] +35533 - Staircase - [Climb-up, null, null, null, null] +35534 - Staircase - [Climb-down, null, null, null, null] +35535 - null - [null, null, null, null, null] +35536 - null - [null, null, null, null, null] +35537 - null - [null, null, null, null, null] +35538 - null - [null, null, null, null, null] +35539 - null - [null, null, null, null, null] +35540 - Cell door - [Open, null, null, null, null] +35541 - Cell door - [Close, null, null, null, null] +35542 - Shantay Pass - [Go-through, Look-at, Quick-pass, null, null] +35543 - Shantay Pass - [Go-through, Look-at, Quick-pass, null, null] +35544 - Shantay Pass - [Go-through, Look-at, Quick-pass, null, null] +35545 - Shantay Pass - [Go-through, Look-at, Quick-pass, null, null] +35546 - Shantay Pass - [Go-through, Look-at, Quick-pass, null, null] +35547 - Shantay Pass - [Go-through, Look-at, Quick-pass, null, null] +35548 - Shantay Pass - [Go-through, Look-at, Quick-pass, null, null] +35549 - Gate - [Open, null, null, Pay-toll(10gp), null] +35550 - Gate - [null, null, null, null, null] +35551 - Gate - [Open, null, null, Pay-toll(10gp), null] +35552 - Gate - [null, null, null, null, null] +35553 - null - [null, null, null, null, null] +35554 - null - [null, null, null, null, null] +35555 - Danger sign - [null, null, null, null, null] +35556 - null - [null, null, null, null, null] +35557 - null - [null, null, null, null, null] +35558 - null - [null, null, null, null, null] +35559 - null - [null, null, null, null, null] +35560 - null - [null, null, null, null, null] +35561 - null - [null, null, null, null, null] +35562 - null - [null, null, null, null, null] +35563 - null - [null, null, null, null, null] +35564 - null - [null, null, null, null, null] +35565 - null - [null, null, null, null, null] +35566 - null - [null, null, null, null, null] +35567 - null - [null, null, null, null, null] +35568 - null - [null, null, null, null, null] +35569 - null - [null, null, null, null, null] +35570 - null - [null, null, null, null, null] +35571 - null - [null, null, null, null, null] +35572 - null - [null, null, null, null, null] +35573 - null - [null, null, null, null, null] +35574 - null - [null, null, null, null, null] +35575 - null - [null, null, null, null, null] +35576 - null - [null, null, null, null, null] +35577 - null - [null, null, null, null, null] +35578 - null - [null, null, null, null, null] +35579 - null - [null, null, null, null, null] +35580 - null - [null, null, null, null, null] +35581 - null - [null, null, null, null, null] +35582 - null - [null, null, null, null, null] +35583 - null - [null, null, null, null, null] +35584 - null - [null, null, null, null, null] +35585 - null - [null, null, null, null, null] +35586 - null - [null, null, null, null, null] +35587 - null - [null, null, null, null, null] +35588 - null - [null, null, null, null, null] +35589 - null - [null, null, null, null, null] +35590 - null - [null, null, null, null, null] +35591 - null - [null, null, null, null, null] +35592 - null - [null, null, null, null, null] +35593 - null - [null, null, null, null, null] +35594 - null - [null, null, null, null, null] +35595 - null - [null, null, null, null, null] +35596 - null - [null, null, null, null, null] +35597 - null - [null, null, null, null, null] +35598 - null - [null, null, null, null, null] +35599 - null - [null, null, null, null, null] +35600 - null - [null, null, null, null, null] +35601 - null - [null, null, null, null, null] +35602 - null - [null, null, null, null, null] +35603 - null - [null, null, null, null, null] +35604 - null - [null, null, null, null, null] +35605 - null - [null, null, null, null, null] +35606 - null - [null, null, null, null, null] +35607 - null - [null, null, null, null, null] +35608 - null - [null, null, null, null, null] +35609 - null - [null, null, null, null, null] +35610 - null - [null, null, null, null, null] +35611 - null - [null, null, null, null, null] +35612 - null - [null, null, null, null, null] +35613 - null - [null, null, null, null, null] +35614 - null - [null, null, null, null, null] +35615 - null - [null, null, null, null, null] +35616 - null - [null, null, null, null, null] +35617 - null - [null, null, null, null, null] +35618 - null - [null, null, null, null, null] +35619 - null - [null, null, null, null, null] +35620 - null - [null, null, null, null, null] +35621 - null - [null, null, null, null, null] +35622 - null - [null, null, null, null, null] +35623 - null - [null, null, null, null, null] +35624 - null - [null, null, null, null, null] +35625 - null - [null, null, null, null, null] +35626 - null - [null, null, null, null, null] +35627 - null - [null, null, null, null, null] +35628 - null - [null, null, null, null, null] +35629 - null - [null, null, null, null, null] +35630 - Door - [Open, null, null, null, null] +35631 - Door - [Close, null, null, null, null] +35632 - null - [null, null, null, null, null] +35633 - null - [null, null, null, null, null] +35634 - null - [null, null, null, null, null] +35635 - null - [null, null, null, null, null] +35636 - null - [null, null, null, null, null] +35637 - null - [null, null, null, null, null] +35638 - null - [null, null, null, null, null] +35639 - Shelf - [null, null, null, null, null] +35640 - Shelf - [null, null, null, null, null] +35641 - Shelf - [null, null, null, null, null] +35642 - Round table - [null, null, null, null, null] +35643 - null - [null, null, null, null, null] +35644 - null - [null, null, null, null, null] +35645 - Stairs - [Climb-down, null, null, null, null] +35646 - Stairs - [Climb-up, null, null, null, null] +35647 - Bank booth - [Use, Use-quickly, Collect, null, null] +35648 - Bank booth - [null, null, null, null, null] +35649 - Sign - [null, null, null, null, null] +35650 - Cushioned chair - [null, null, null, null, null] +35651 - Cushioned chair - [null, null, null, null, null] +35652 - Cushioned chair - [null, null, null, null, null] +35653 - Cushioned chair - [null, null, null, null, null] +35654 - Cushioned chair - [null, null, null, null, null] +35655 - Cushioned chair - [null, null, null, null, null] +35656 - Cushioned chair - [null, null, null, null, null] +35657 - Padded chair - [null, null, null, null, null] +35658 - Padded chair - [null, null, null, null, null] +35659 - Padded chair - [null, null, null, null, null] +35660 - Padded chair - [null, null, null, null, null] +35661 - Padded chair - [null, null, null, null, null] +35662 - Stone table - [null, null, null, null, null] +35663 - Vast table - [null, null, null, null, null] +35664 - Messy table - [null, null, null, null, null] +35665 - Crescent table - [null, null, null, null, null] +35666 - null - [null, null, null, null, null] +35667 - Large bed - [null, null, null, null, null] +35668 - Small bed - [null, null, null, null, null] +35669 - Stylish stool - [null, null, null, null, null] +35670 - Ornate vase - [null, null, null, null, null] +35671 - Well - [null, null, null, null, null] +35672 - Ladder - [Climb-up, null, null, null, null] +35673 - Ladder - [Climb-down, null, null, null, null] +35674 - null - [null, null, null, null, null] +35675 - null - [null, null, null, null, null] +35676 - null - [null, null, null, null, null] +35677 - null - [null, null, null, null, null] +35678 - null - [null, null, null, null, null] +35679 - null - [null, null, null, null, null] +35680 - null - [null, null, null, null, null] +35681 - null - [null, null, null, null, null] +35682 - null - [null, null, null, null, null] +35683 - null - [null, null, null, null, null] +35684 - null - [null, null, null, null, null] +35685 - null - [null, null, null, null, null] +35686 - null - [null, null, null, null, null] +35687 - null - [null, null, null, null, null] +35688 - null - [null, null, null, null, null] +35689 - null - [null, null, null, null, null] +35690 - null - [null, null, null, null, null] +35691 - null - [null, null, null, null, null] +35692 - null - [null, null, null, null, null] +35693 - null - [null, null, null, null, null] +35694 - null - [null, null, null, null, null] +35695 - null - [null, null, null, null, null] +35696 - null - [null, null, null, null, null] +35697 - null - [null, null, null, null, null] +35698 - null - [null, null, null, null, null] +35699 - null - [null, null, null, null, null] +35700 - null - [null, null, null, null, null] +35701 - null - [null, null, null, null, null] +35702 - null - [null, null, null, null, null] +35703 - null - [null, null, null, null, null] +35704 - null - [null, null, null, null, null] +35705 - null - [null, null, null, null, null] +35706 - null - [null, null, null, null, null] +35707 - null - [null, null, null, null, null] +35708 - null - [null, null, null, null, null] +35709 - null - [null, null, null, null, null] +35710 - null - [null, null, null, null, null] +35711 - null - [null, null, null, null, null] +35712 - null - [null, null, null, null, null] +35713 - null - [null, null, null, null, null] +35714 - null - [null, null, null, null, null] +35715 - null - [null, null, null, null, null] +35716 - null - [null, null, null, null, null] +35717 - null - [null, null, null, null, null] +35718 - null - [null, null, null, null, null] +35719 - null - [null, null, null, null, null] +35720 - null - [null, null, null, null, null] +35721 - null - [null, null, null, null, null] +35722 - null - [null, null, null, null, null] +35723 - null - [null, null, null, null, null] +35724 - null - [null, null, null, null, null] +35725 - null - [null, null, null, null, null] +35726 - null - [null, null, null, null, null] +35727 - null - [null, null, null, null, null] +35728 - null - [null, null, null, null, null] +35729 - null - [null, null, null, null, null] +35730 - null - [null, null, null, null, null] +35731 - null - [null, null, null, null, null] +35732 - null - [null, null, null, null, null] +35733 - null - [null, null, null, null, null] +35734 - null - [null, null, null, null, null] +35735 - null - [null, null, null, null, null] +35736 - null - [null, null, null, null, null] +35737 - null - [null, null, null, null, null] +35738 - null - [null, null, null, null, null] +35739 - null - [null, null, null, null, null] +35740 - null - [null, null, null, null, null] +35741 - null - [null, null, null, null, null] +35742 - null - [null, null, null, null, null] +35743 - null - [null, null, null, null, null] +35744 - null - [null, null, null, null, null] +35745 - null - [null, null, null, null, null] +35746 - null - [null, null, null, null, null] +35747 - null - [null, null, null, null, null] +35748 - null - [null, null, null, null, null] +35749 - null - [null, null, null, null, null] +35750 - null - [null, null, null, null, null] +35751 - Bookcase - [null, null, null, null, null] +35752 - null - [null, null, null, null, null] +35753 - Shield - [null, null, null, null, null] +35754 - Bookcase - [Search, null, null, null, null] +35755 - Bookcase - [Search, null, null, null, null] +35756 - Bookcase - [Search, null, null, null, null] +35757 - Wardrobe - [null, null, null, null, null] +35758 - Cabinet - [null, null, null, null, null] +35759 - Cabinet - [null, null, null, null, null] +35760 - Cabinet - [null, null, null, null, null] +35761 - Cabinet - [null, null, null, null, null] +35762 - Sink - [null, null, null, null, null] +35763 - Bookcase - [Search, null, null, null, null] +35764 - Desk - [null, null, null, null, null] +35765 - Smashed table - [null, null, null, null, null] +35766 - Bed - [null, null, null, null, null] +35767 - Bunk bed - [null, null, null, null, null] +35768 - null - [null, null, null, null, null] +35769 - null - [null, null, null, null, null] +35770 - null - [null, null, null, null, null] +35771 - null - [null, null, null, null, null] +35772 - null - [null, null, null, null, null] +35773 - null - [null, null, null, null, null] +35774 - null - [null, null, null, null, null] +35775 - null - [null, null, null, null, null] +35776 - null - [null, null, null, null, null] +35777 - null - [null, null, null, null, null] +35778 - null - [null, null, null, null, null] +35779 - null - [null, null, null, null, null] +35780 - null - [null, null, null, null, null] +35781 - Staircase - [Climb-up, null, null, null, null] +35782 - Staircase - [Climb-down, null, null, null, null] +35783 - Staircase - [Climb-down, null, null, null, null] +35784 - Crates - [Search, null, null, null, null] +35785 - Crates - [Search, null, null, null, null] +35786 - null - [null, null, null, null, null] +35787 - null - [null, null, null, null, null] +35788 - null - [null, null, null, null, null] +35789 - null - [null, null, null, null, null] +35790 - null - [null, null, null, null, null] +35791 - null - [null, null, null, null, null] +35792 - null - [null, null, null, null, null] +35793 - null - [null, null, null, null, null] +35794 - null - [null, null, null, null, null] +35795 - null - [null, null, null, null, null] +35796 - null - [null, null, null, null, null] +35797 - null - [null, null, null, null, null] +35798 - null - [null, null, null, null, null] +35799 - null - [null, null, null, null, null] +35800 - null - [null, null, null, null, null] +35801 - null - [null, null, null, null, null] +35802 - null - [null, null, null, null, null] +35803 - null - [null, null, null, null, null] +35804 - null - [null, null, null, null, null] +35805 - null - [null, null, null, null, null] +35806 - null - [null, null, null, null, null] +35807 - null - [null, null, null, null, null] +35808 - null - [null, null, null, null, null] +35809 - null - [null, null, null, null, null] +35810 - null - [null, null, null, null, null] +35811 - null - [null, null, null, null, null] +35812 - null - [null, null, null, null, null] +35813 - null - [null, null, null, null, null] +35814 - null - [null, null, null, null, null] +35815 - null - [null, null, null, null, null] +35816 - null - [null, null, null, null, null] +35817 - null - [null, null, null, null, null] +35818 - null - [null, null, null, null, null] +35819 - null - [null, null, null, null, null] +35820 - null - [null, null, null, null, null] +35821 - null - [null, null, null, null, null] +35822 - null - [null, null, null, null, null] +35823 - null - [null, null, null, null, null] +35824 - null - [null, null, null, null, null] +35825 - null - [null, null, null, null, null] +35826 - null - [null, null, null, null, null] +35827 - null - [null, null, null, null, null] +35828 - null - [null, null, null, null, null] +35829 - null - [null, null, null, null, null] +35830 - null - [null, null, null, null, null] +35831 - null - [null, null, null, null, null] +35832 - null - [null, null, null, null, null] +35833 - null - [null, null, null, null, null] +35834 - null - [null, null, null, null, null] +35835 - null - [null, null, null, null, null] +35836 - null - [null, null, null, null, null] +35837 - null - [null, null, null, null, null] +35838 - null - [null, null, null, null, null] +35839 - null - [null, null, null, null, null] +35840 - null - [null, null, null, null, null] +35841 - null - [null, null, null, null, null] +35842 - null - [null, null, null, null, null] +35843 - null - [null, null, null, null, null] +35844 - null - [null, null, null, null, null] +35845 - null - [null, null, null, null, null] +35846 - null - [null, null, null, null, null] +35847 - null - [null, null, null, null, null] +35848 - null - [null, null, null, null, null] +35849 - null - [null, null, null, null, null] +35850 - null - [null, null, null, null, null] +35851 - null - [null, null, null, null, null] +35852 - null - [null, null, null, null, null] +35853 - null - [null, null, null, null, null] +35854 - null - [null, null, null, null, null] +35855 - null - [null, null, null, null, null] +35856 - null - [null, null, null, null, null] +35857 - null - [null, null, null, null, null] +35858 - null - [null, null, null, null, null] +35859 - null - [null, null, null, null, null] +35860 - null - [null, null, null, null, null] +35861 - null - [null, null, null, null, null] +35862 - null - [null, null, null, null, null] +35863 - null - [null, null, null, null, null] +35864 - null - [null, null, null, null, null] +35865 - null - [null, null, null, null, null] +35866 - null - [null, null, null, null, null] +35867 - null - [null, null, null, null, null] +35868 - null - [null, null, null, null, null] +35869 - null - [null, null, null, null, null] +35870 - null - [null, null, null, null, null] +35871 - null - [null, null, null, null, null] +35872 - null - [null, null, null, null, null] +35873 - null - [null, null, null, null, null] +35874 - null - [null, null, null, null, null] +35875 - null - [null, null, null, null, null] +35876 - null - [null, null, null, null, null] +35877 - null - [null, null, null, null, null] +35878 - null - [null, null, null, null, null] +35879 - null - [null, null, null, null, null] +35880 - null - [null, null, null, null, null] +35881 - null - [null, null, null, null, null] +35882 - null - [null, null, null, null, null] +35883 - null - [null, null, null, null, null] +35884 - null - [null, null, null, null, null] +35885 - null - [null, null, null, null, null] +35886 - null - [null, null, null, null, null] +35887 - null - [null, null, null, null, null] +35888 - null - [null, null, null, null, null] +35889 - null - [null, null, null, null, null] +35890 - null - [null, null, null, null, null] +35891 - null - [null, null, null, null, null] +35892 - null - [null, null, null, null, null] +35893 - null - [null, null, null, null, null] +35894 - null - [null, null, null, null, null] +35895 - null - [null, null, null, null, null] +35896 - null - [null, null, null, null, null] +35897 - null - [null, null, null, null, null] +35898 - null - [null, null, null, null, null] +35899 - null - [null, null, null, null, null] +35900 - null - [null, null, null, null, null] +35901 - null - [null, null, null, null, null] +35902 - null - [null, null, null, null, null] +35903 - null - [null, null, null, null, null] +35904 - null - [null, null, null, null, null] +35905 - null - [null, null, null, null, null] +35906 - null - [null, null, null, null, null] +35907 - bannister end - [null, null, null, null, null] +35908 - null - [null, null, null, null, null] +35909 - null - [null, null, null, null, null] +35910 - null - [null, null, null, null, null] +35911 - null - [null, null, null, null, null] +35912 - null - [null, null, null, null, null] +35913 - null - [null, null, null, null, null] +35914 - null - [null, null, null, null, null] +35915 - null - [null, null, null, null, null] +35916 - null - [null, null, null, null, null] +35917 - null - [null, null, null, null, null] +35918 - null - [null, null, null, null, null] +35919 - null - [null, null, null, null, null] +35920 - null - [null, null, null, null, null] +35921 - null - [null, null, null, null, null] +35922 - null - [null, null, null, null, null] +35923 - null - [null, null, null, null, null] +35924 - null - [null, null, null, null, null] +35925 - null - [null, null, null, null, null] +35926 - null - [null, null, null, null, null] +35927 - null - [null, null, null, null, null] +35928 - null - [null, null, null, null, null] +35929 - null - [null, null, null, null, null] +35930 - Mithril door - [null, null, null, null, null] +35931 - Dairy churn - [Churn, null, null, null, null] +35932 - null - [null, null, null, null, null] +35933 - null - [null, null, null, null, null] +35934 - null - [null, null, null, null, null] +35935 - null - [null, null, null, null, null] +35936 - null - [null, null, null, null, null] +35937 - null - [null, null, null, null, null] +35938 - null - [null, null, null, null, null] +35939 - null - [null, null, null, null, null] +35940 - null - [null, null, null, null, null] +35941 - null - [null, null, null, null, null] +35942 - null - [null, null, null, null, null] +35943 - null - [null, null, null, null, null] +35944 - null - [null, null, null, null, null] +35945 - null - [null, null, null, null, null] +35946 - null - [null, null, null, null, null] +35947 - null - [null, null, null, null, null] +35948 - null - [null, null, null, null, null] +35949 - null - [null, null, null, null, null] +35950 - null - [null, null, null, null, null] +35951 - null - [null, null, null, null, null] +35952 - null - [null, null, null, null, null] +35953 - null - [null, null, null, null, null] +35954 - null - [null, null, null, null, null] +35955 - null - [null, null, null, null, null] +35956 - null - [null, null, null, null, null] +35957 - null - [null, null, null, null, null] +35958 - null - [null, null, null, null, null] +35959 - null - [null, null, null, null, null] +35960 - null - [null, null, null, null, null] +35961 - null - [null, null, null, null, null] +35962 - null - [null, null, null, null, null] +35963 - null - [null, null, null, null, null] +35964 - null - [null, null, null, null, null] +35965 - null - [null, null, null, null, null] +35966 - Rope swing - [Swing-on, null, null, null, null] +35967 - Rope swing - [Swing-on, null, null, null, null] +35968 - Rock - [null, null, null, null, null] +35969 - Balancing ledge - [Walk-across, null, null, null, null] +35970 - Tree branch - [Climb, null, null, null, null] +35971 - null - [null, null, null, null, null] +35972 - null - [null, null, null, null, null] +35973 - null - [null, null, null, null, null] +35974 - null - [null, null, null, null, null] +35975 - null - [null, null, null, null, null] +35976 - null - [null, null, null, null, null] +35977 - null - [null, null, null, null, null] +35978 - null - [null, null, null, null, null] +35979 - null - [null, null, null, null, null] +35980 - null - [null, null, null, null, null] +35981 - null - [null, null, null, null, null] +35982 - null - [null, null, null, null, null] +35983 - null - [null, null, null, null, null] +35984 - null - [null, null, null, null, null] +35985 - null - [null, null, null, null, null] +35986 - null - [null, null, null, null, null] +35987 - null - [null, null, null, null, null] +35988 - null - [null, null, null, null, null] +35989 - long walkway - [null, null, null, null, null] +35990 - null - [null, null, null, null, null] +35991 - Door - [Open, null, null, null, null] +35992 - Door - [null, null, null, null, null] +35993 - null - [null, null, null, null, null] +35994 - null - [null, null, null, null, null] +35995 - null - [null, null, null, null, null] +35996 - Stepping stone - [Jump-to, null, null, null, null] +35997 - Log balance - [Walk-across, null, null, null, null] +35998 - Log balance - [Walk-across, null, null, null, null] +35999 - Log balance - [Walk-across, null, null, null, null] +36000 - Cave entrance - [Enter, null, null, null, null] +36001 - Hanging log - [null, null, null, null, null] +36002 - Smokey well - [Climb-down, null, null, null, null] +36003 - Rift - [null, null, null, null, null] +36004 - null - [null, null, null, null, null] +36005 - null - [null, null, null, null, null] +36006 - null - [null, null, null, null, null] +36007 - null - [null, null, null, null, null] +36008 - null - [null, null, null, null, null] +36009 - null - [null, null, null, null, null] +36010 - null - [null, null, null, null, null] +36011 - null - [null, null, null, null, null] +36012 - null - [null, null, null, null, null] +36013 - null - [null, null, null, null, null] +36014 - null - [null, null, null, null, null] +36015 - null - [null, null, null, null, null] +36016 - null - [null, null, null, null, null] +36017 - null - [null, null, null, null, null] +36018 - null - [null, null, null, null, null] +36019 - null - [null, null, null, null, null] +36020 - null - [null, null, null, null, null] +36021 - Door - [Close, null, null, null, null] +36022 - Door - [Open, null, null, null, null] +36023 - null - [null, null, null, null, null] +36024 - null - [null, null, null, null, null] +36025 - null - [null, null, null, null, null] +36026 - null - [null, null, null, null, null] +36027 - null - [null, null, null, null, null] +36028 - null - [null, null, null, null, null] +36029 - null - [null, null, null, null, null] +36030 - null - [null, null, null, null, null] +36031 - null - [null, null, null, null, null] +36032 - null - [null, null, null, null, null] +36033 - null - [null, null, null, null, null] +36034 - null - [null, null, null, null, null] +36035 - null - [null, null, null, null, null] +36036 - null - [null, null, null, null, null] +36037 - null - [null, null, null, null, null] +36038 - null - [null, null, null, null, null] +36039 - null - [null, null, null, null, null] +36040 - null - [null, null, null, null, null] +36041 - null - [null, null, null, null, null] +36042 - null - [null, null, null, null, null] +36043 - null - [null, null, null, null, null] +36044 - null - [null, null, null, null, null] +36045 - null - [null, null, null, null, null] +36046 - null - [null, null, null, null, null] +36047 - null - [null, null, null, null, null] +36048 - null - [null, null, null, null, null] +36049 - null - [null, null, null, null, null] +36050 - null - [null, null, null, null, null] +36051 - null - [null, null, null, null, null] +36052 - null - [null, null, null, null, null] +36053 - null - [null, null, null, null, null] +36054 - null - [null, null, null, null, null] +36055 - null - [null, null, null, null, null] +36056 - null - [null, null, null, null, null] +36057 - null - [null, null, null, null, null] +36058 - null - [null, null, null, null, null] +36059 - null - [null, null, null, null, null] +36060 - null - [null, null, null, null, null] +36061 - null - [null, null, null, null, null] +36062 - null - [null, null, null, null, null] +36063 - null - [null, null, null, null, null] +36064 - null - [null, null, null, null, null] +36065 - null - [null, null, null, null, null] +36066 - null - [null, null, null, null, null] +36067 - null - [null, null, null, null, null] +36068 - null - [null, null, null, null, null] +36069 - null - [null, null, null, null, null] +36070 - null - [null, null, null, null, null] +36071 - null - [null, null, null, null, null] +36072 - null - [null, null, null, null, null] +36073 - null - [null, null, null, null, null] +36074 - null - [null, null, null, null, null] +36075 - null - [null, null, null, null, null] +36076 - null - [null, null, null, null, null] +36077 - null - [null, null, null, null, null] +36078 - null - [null, null, null, null, null] +36079 - null - [null, null, null, null, null] +36080 - null - [null, null, null, null, null] +36081 - null - [null, null, null, null, null] +36082 - null - [null, null, null, null, null] +36083 - null - [null, null, null, null, null] +36084 - null - [null, null, null, null, null] +36085 - null - [null, null, null, null, null] +36086 - null - [null, null, null, null, null] +36087 - null - [null, null, null, null, null] +36088 - null - [null, null, null, null, null] +36089 - null - [null, null, null, null, null] +36090 - null - [null, null, null, null, null] +36091 - null - [null, null, null, null, null] +36092 - null - [null, null, null, null, null] +36093 - null - [null, null, null, null, null] +36094 - null - [null, null, null, null, null] +36095 - null - [null, null, null, null, null] +36096 - null - [null, null, null, null, null] +36097 - null - [null, null, null, null, null] +36098 - null - [null, null, null, null, null] +36099 - null - [null, null, null, null, null] +36100 - null - [null, null, null, null, null] +36101 - null - [null, null, null, null, null] +36102 - null - [null, null, null, null, null] +36103 - null - [null, null, null, null, null] +36104 - null - [null, null, null, null, null] +36105 - null - [null, null, null, null, null] +36106 - null - [null, null, null, null, null] +36107 - null - [null, null, null, null, null] +36108 - null - [null, null, null, null, null] +36109 - null - [null, null, null, null, null] +36110 - null - [null, null, null, null, null] +36111 - null - [null, null, null, null, null] +36112 - null - [null, null, null, null, null] +36113 - null - [null, null, null, null, null] +36114 - null - [null, null, null, null, null] +36115 - null - [null, null, null, null, null] +36116 - null - [null, null, null, null, null] +36117 - null - [null, null, null, null, null] +36118 - null - [null, null, null, null, null] +36119 - null - [null, null, null, null, null] +36120 - null - [null, null, null, null, null] +36121 - null - [null, null, null, null, null] +36122 - null - [null, null, null, null, null] +36123 - null - [null, null, null, null, null] +36124 - null - [null, null, null, null, null] +36125 - null - [null, null, null, null, null] +36126 - null - [null, null, null, null, null] +36127 - null - [null, null, null, null, null] +36128 - null - [null, null, null, null, null] +36129 - null - [null, null, null, null, null] +36130 - null - [null, null, null, null, null] +36131 - null - [null, null, null, null, null] +36132 - null - [null, null, null, null, null] +36133 - null - [null, null, null, null, null] +36134 - null - [null, null, null, null, null] +36135 - null - [null, null, null, null, null] +36136 - null - [null, null, null, null, null] +36137 - null - [null, null, null, null, null] +36138 - null - [null, null, null, null, null] +36139 - null - [null, null, null, null, null] +36140 - null - [null, null, null, null, null] +36141 - null - [null, null, null, null, null] +36142 - null - [null, null, null, null, null] +36143 - null - [null, null, null, null, null] +36144 - null - [null, null, null, null, null] +36145 - null - [null, null, null, null, null] +36146 - null - [null, null, null, null, null] +36147 - null - [null, null, null, null, null] +36148 - null - [null, null, null, null, null] +36149 - null - [null, null, null, null, null] +36150 - null - [null, null, null, null, null] +36151 - null - [null, null, null, null, null] +36152 - null - [null, null, null, null, null] +36153 - null - [null, null, null, null, null] +36154 - null - [null, null, null, null, null] +36155 - null - [null, null, null, null, null] +36156 - null - [null, null, null, null, null] +36157 - null - [null, null, null, null, null] +36158 - null - [null, null, null, null, null] +36159 - null - [null, null, null, null, null] +36160 - null - [null, null, null, null, null] +36161 - null - [null, null, null, null, null] +36162 - null - [null, null, null, null, null] +36163 - null - [null, null, null, null, null] +36164 - null - [null, null, null, null, null] +36165 - null - [null, null, null, null, null] +36166 - null - [null, null, null, null, null] +36167 - null - [null, null, null, null, null] +36168 - null - [null, null, null, null, null] +36169 - null - [null, null, null, null, null] +36170 - null - [null, null, null, null, null] +36171 - null - [null, null, null, null, null] +36172 - null - [null, null, null, null, null] +36173 - null - [null, null, null, null, null] +36174 - null - [null, null, null, null, null] +36175 - null - [null, null, null, null, null] +36176 - null - [null, null, null, null, null] +36177 - null - [null, null, null, null, null] +36178 - null - [null, null, null, null, null] +36179 - null - [null, null, null, null, null] +36180 - null - [null, null, null, null, null] +36181 - null - [null, null, null, null, null] +36182 - null - [null, null, null, null, null] +36183 - null - [null, null, null, null, null] +36184 - null - [null, null, null, null, null] +36185 - null - [null, null, null, null, null] +36186 - null - [null, null, null, null, null] +36187 - null - [null, null, null, null, null] +36188 - null - [null, null, null, null, null] +36189 - null - [null, null, null, null, null] +36190 - null - [null, null, null, null, null] +36191 - null - [null, null, null, null, null] +36192 - null - [null, null, null, null, null] +36193 - null - [null, null, null, null, null] +36194 - null - [null, null, null, null, null] +36195 - null - [null, null, null, null, null] +36196 - null - [null, null, null, null, null] +36197 - null - [null, null, null, null, null] +36198 - null - [null, null, null, null, null] +36199 - null - [null, null, null, null, null] +36200 - null - [null, null, null, null, null] +36201 - null - [null, null, null, null, null] +36202 - null - [null, null, null, null, null] +36203 - null - [null, null, null, null, null] +36204 - null - [null, null, null, null, null] +36205 - null - [null, null, null, null, null] +36206 - null - [null, null, null, null, null] +36207 - null - [null, null, null, null, null] +36208 - null - [null, null, null, null, null] +36209 - null - [null, null, null, null, null] +36210 - null - [null, null, null, null, null] +36211 - null - [null, null, null, null, null] +36212 - null - [null, null, null, null, null] +36213 - null - [null, null, null, null, null] +36214 - null - [null, null, null, null, null] +36215 - null - [null, null, null, null, null] +36216 - null - [null, null, null, null, null] +36217 - null - [null, null, null, null, null] +36218 - null - [null, null, null, null, null] +36219 - null - [null, null, null, null, null] +36220 - null - [null, null, null, null, null] +36221 - null - [null, null, null, null, null] +36222 - null - [null, null, null, null, null] +36223 - null - [null, null, null, null, null] +36224 - null - [null, null, null, null, null] +36225 - null - [null, null, null, null, null] +36226 - null - [null, null, null, null, null] +36227 - null - [null, null, null, null, null] +36228 - null - [null, null, null, null, null] +36229 - null - [null, null, null, null, null] +36230 - Flag Banner - [null, null, null, null, null] +36231 - Flag Banner - [null, null, null, null, null] +36232 - Flag Banner - [null, null, null, null, null] +36233 - Flag Banner - [null, null, null, null, null] +36234 - Flag Banner - [null, null, null, null, null] +36235 - Flag Banner - [null, null, null, null, null] +36236 - Flag Banner - [null, null, null, null, null] +36237 - Flag Banner - [null, null, null, null, null] +36238 - Flag Banner - [null, null, null, null, null] +36239 - Flag Banner - [null, null, null, null, null] +36240 - null - [null, null, null, null, null] +36241 - null - [null, null, null, null, null] +36242 - null - [null, null, null, null, null] +36243 - null - [null, null, null, null, null] +36244 - null - [null, null, null, null, null] +36245 - null - [null, null, null, null, null] +36246 - null - [null, null, null, null, null] +36247 - null - [null, null, null, null, null] +36248 - null - [null, null, null, null, null] +36249 - null - [null, null, null, null, null] +36250 - null - [null, null, null, null, null] +36251 - null - [null, null, null, null, null] +36252 - null - [null, null, null, null, null] +36253 - null - [null, null, null, null, null] +36254 - null - [null, null, null, null, null] +36255 - Table - [null, null, null, null, null] +36256 - Bed - [null, null, null, null, null] +36257 - Bed - [null, null, null, null, null] +36258 - null - [null, null, null, null, null] +36259 - null - [null, null, null, null, null] +36260 - null - [null, null, null, null, null] +36261 - null - [null, null, null, null, null] +36262 - Bank booth - [null, null, null, null, null] +36263 - Gold bars - [null, null, null, null, null] +36264 - null - [null, null, null, null, null] +36265 - null - [null, null, null, null, null] +36266 - null - [null, null, null, null, null] +36267 - null - [null, null, null, null, null] +36268 - null - [null, null, null, null, null] +36269 - null - [null, null, null, null, null] +36270 - null - [null, null, null, null, null] +36271 - null - [null, null, null, null, null] +36272 - null - [null, null, null, null, null] +36273 - Suit of armour - [null, null, null, null, null] +36274 - null - [null, null, null, null, null] +36275 - null - [null, null, null, null, null] +36276 - null - [null, null, null, null, null] +36277 - null - [null, null, null, null, null] +36278 - null - [null, null, null, null, null] +36279 - null - [null, null, null, null, null] +36280 - null - [null, null, null, null, null] +36281 - null - [null, null, null, null, null] +36282 - null - [null, null, null, null, null] +36283 - null - [null, null, null, null, null] +36284 - null - [null, null, null, null, null] +36285 - null - [null, null, null, null, null] +36286 - null - [null, null, null, null, null] +36287 - Suit of armour - [null, null, null, null, null] +36288 - null - [null, null, null, null, null] +36289 - null - [null, null, null, null, null] +36290 - null - [null, null, null, null, null] +36291 - null - [null, null, null, null, null] +36292 - null - [null, null, null, null, null] +36293 - null - [null, null, null, null, null] +36294 - null - [null, null, null, null, null] +36295 - null - [null, null, null, null, null] +36296 - null - [null, null, null, null, null] +36297 - null - [null, null, null, null, null] +36298 - null - [null, null, null, null, null] +36299 - null - [null, null, null, null, null] +36300 - null - [null, null, null, null, null] +36301 - null - [null, null, null, null, null] +36302 - null - [null, null, null, null, null] +36303 - null - [null, null, null, null, null] +36304 - null - [null, null, null, null, null] +36305 - null - [null, null, null, null, null] +36306 - Ladder - [Climb-down, null, null, null, null] +36307 - Rope Ladder - [null, null, null, null, null] +36308 - Wall - [null, null, null, null, null] +36309 - null - [null, null, null, null, null] +36310 - null - [null, null, null, null, null] +36311 - null - [null, null, null, null, null] +36312 - Climbing Rope - [Climb, null, null, null, null] +36313 - Battlements - [null, null, null, null, null] +36314 - Battlements - [null, null, null, null, null] +36315 - Door - [Open, null, null, null, null] +36316 - Door - [Close, null, null, null, null] +36317 - Door - [Open, null, null, null, null] +36318 - Door - [Close, null, null, null, null] +36319 - Door - [Close, null, null, null, null] +36320 - Door - [Open, null, null, null, null] +36321 - null - [null, null, null, null, null] +36322 - Boxes - [null, null, null, null, null] +36323 - Crate - [null, null, null, null, null] +36324 - Crate - [null, null, null, null, null] +36325 - Barrel of swords - [null, null, null, null, null] +36326 - Barrel - [null, null, null, null, null] +36327 - Barrel - [null, null, null, null, null] +36328 - null - [null, null, null, null, null] +36329 - null - [null, null, null, null, null] +36330 - null - [null, null, null, null, null] +36331 - null - [null, null, null, null, null] +36332 - null - [null, null, null, null, null] +36333 - null - [null, null, null, null, null] +36334 - null - [null, null, null, null, null] +36335 - Shelves - [null, null, null, null, null] +36336 - Shelves - [null, null, null, null, null] +36337 - Shelves - [null, null, null, null, null] +36338 - Shelves - [null, null, null, null, null] +36339 - Door - [Open, null, null, null, null] +36340 - Door - [Close, null, null, null, null] +36341 - Door - [Open, null, null, null, null] +36342 - Door - [Close, null, null, null, null] +36343 - Door - [Close, null, null, null, null] +36344 - Door - [Open, null, null, null, null] +36345 - null - [null, null, null, null, null] +36346 - null - [null, null, null, null, null] +36347 - Ladder - [Climb-up, null, null, null, null] +36348 - Ladder - [Climb, Climb-up, Climb-down, null, null] +36349 - Ladder - [Climb-down, null, null, null, null] +36350 - Table - [null, null, null, null, null] +36351 - Crate - [null, null, null, null, null] +36352 - Crate - [null, null, null, null, null] +36353 - Barrel - [null, null, null, null, null] +36354 - Boxes - [null, null, null, null, null] +36355 - Door - [Open, null, null, null, null] +36356 - Door - [Close, null, null, null, null] +36357 - Door - [Open, null, null, null, null] +36358 - Door - [Close, null, null, null, null] +36359 - Door - [Close, null, null, null, null] +36360 - Door - [Open, null, null, null, null] +36361 - null - [null, null, null, null, null] +36362 - null - [null, null, null, null, null] +36363 - Ladder - [Climb-up, null, null, null, null] +36364 - Ladder - [Climb, Climb-up, Climb-down, null, null] +36365 - Ladder - [Climb-down, null, null, null, null] +36366 - Table - [null, null, null, null, null] +36367 - Barrel - [null, null, null, null, null] +36368 - Boxes - [null, null, null, null, null] +36369 - Crate - [null, null, null, null, null] +36370 - Crate - [null, null, null, null, null] +36371 - null - [null, null, null, null, null] +36372 - null - [null, null, null, null, null] +36373 - null - [null, null, null, null, null] +36374 - null - [null, null, null, null, null] +36375 - null - [null, null, null, null, null] +36376 - null - [null, null, null, null, null] +36377 - null - [null, null, null, null, null] +36378 - null - [null, null, null, null, null] +36379 - null - [null, null, null, null, null] +36380 - null - [null, null, null, null, null] +36381 - null - [null, null, null, null, null] +36382 - null - [null, null, null, null, null] +36383 - null - [null, null, null, null, null] +36384 - null - [null, null, null, null, null] +36385 - null - [null, null, null, null, null] +36386 - null - [null, null, null, null, null] +36387 - null - [null, null, null, null, null] +36388 - null - [null, null, null, null, null] +36389 - null - [null, null, null, null, null] +36390 - null - [null, null, null, null, null] +36391 - null - [null, null, null, null, null] +36392 - null - [null, null, null, null, null] +36393 - null - [null, null, null, null, null] +36394 - null - [null, null, null, null, null] +36395 - null - [null, null, null, null, null] +36396 - null - [null, null, null, null, null] +36397 - null - [null, null, null, null, null] +36398 - null - [null, null, null, null, null] +36399 - null - [null, null, null, null, null] +36400 - null - [null, null, null, null, null] +36401 - null - [null, null, null, null, null] +36402 - null - [null, null, null, null, null] +36403 - null - [null, null, null, null, null] +36404 - null - [null, null, null, null, null] +36405 - null - [null, null, null, null, null] +36406 - null - [null, null, null, null, null] +36407 - null - [null, null, null, null, null] +36408 - null - [null, null, null, null, null] +36409 - null - [null, null, null, null, null] +36410 - null - [null, null, null, null, null] +36411 - null - [null, null, null, null, null] +36412 - null - [null, null, null, null, null] +36413 - null - [null, null, null, null, null] +36414 - null - [null, null, null, null, null] +36415 - null - [null, null, null, null, null] +36416 - null - [null, null, null, null, null] +36417 - null - [null, null, null, null, null] +36418 - null - [null, null, null, null, null] +36419 - null - [null, null, null, null, null] +36420 - null - [null, null, null, null, null] +36421 - null - [null, null, null, null, null] +36422 - null - [null, null, null, null, null] +36423 - null - [null, null, null, null, null] +36424 - null - [null, null, null, null, null] +36425 - null - [null, null, null, null, null] +36426 - null - [null, null, null, null, null] +36427 - null - [null, null, null, null, null] +36428 - null - [null, null, null, null, null] +36429 - null - [null, null, null, null, null] +36430 - null - [null, null, null, null, null] +36431 - null - [null, null, null, null, null] +36432 - null - [null, null, null, null, null] +36433 - null - [null, null, null, null, null] +36434 - null - [null, null, null, null, null] +36435 - null - [null, null, null, null, null] +36436 - null - [null, null, null, null, null] +36437 - null - [null, null, null, null, null] +36438 - null - [null, null, null, null, null] +36439 - null - [null, null, null, null, null] +36440 - null - [null, null, null, null, null] +36441 - Steps - [null, null, null, null, null] +36442 - null - [null, null, null, null, null] +36443 - Steps - [null, null, null, null, null] +36444 - null - [null, null, null, null, null] +36445 - Steps - [null, null, null, null, null] +36446 - null - [null, null, null, null, null] +36447 - null - [null, null, null, null, null] +36448 - null - [null, null, null, null, null] +36449 - null - [null, null, null, null, null] +36450 - null - [null, null, null, null, null] +36451 - Stairs - [Climb, null, null, null, null] +36452 - null - [null, null, null, null, null] +36453 - null - [null, null, null, null, null] +36454 - null - [null, null, null, null, null] +36455 - null - [null, null, null, null, null] +36456 - null - [null, null, null, null, null] +36457 - null - [null, null, null, null, null] +36458 - null - [null, null, null, null, null] +36459 - null - [null, null, null, null, null] +36460 - null - [null, null, null, null, null] +36461 - null - [null, null, null, null, null] +36462 - null - [null, null, null, null, null] +36463 - null - [null, null, null, null, null] +36464 - null - [null, null, null, null, null] +36465 - null - [null, null, null, null, null] +36466 - null - [null, null, null, null, null] +36467 - null - [null, null, null, null, null] +36468 - Steps - [null, null, null, null, null] +36469 - Steps - [null, null, null, null, null] +36470 - null - [null, null, null, null, null] +36471 - null - [null, null, null, null, null] +36472 - Steps - [null, null, null, null, null] +36473 - null - [null, null, null, null, null] +36474 - Steps - [null, null, null, null, null] +36475 - Stairs - [Climb, null, null, null, null] +36476 - null - [Climb, null, null, null, null] +36477 - null - [null, null, null, null, null] +36478 - Stairs - [Climb, null, null, null, null] +36479 - null - [Climb, null, null, null, null] +36480 - Steps - [Climb-up, null, null, null, null] +36481 - Steps - [Climb-up, null, null, null, null] +36482 - null - [null, null, null, null, null] +36483 - null - [null, null, null, null, null] +36484 - Steps - [Climb-up, null, null, null, null] +36485 - null - [null, null, null, null, null] +36486 - null - [null, null, null, null, null] +36487 - null - [null, null, null, null, null] +36488 - null - [null, null, null, null, null] +36489 - null - [null, null, null, null, null] +36490 - null - [null, null, null, null, null] +36491 - null - [null, null, null, null, null] +36492 - null - [null, null, null, null, null] +36493 - null - [null, null, null, null, null] +36494 - null - [null, null, null, null, null] +36495 - Steps - [Climb-up, null, null, null, null] +36496 - null - [null, null, null, null, null] +36497 - null - [null, null, null, null, null] +36498 - null - [null, null, null, null, null] +36499 - null - [null, null, null, null, null] +36500 - null - [Climb, null, null, null, null] +36501 - Stairs - [Climb, null, null, null, null] +36502 - null - [null, null, null, null, null] +36503 - null - [null, null, null, null, null] +36504 - null - [null, null, null, null, null] +36505 - null - [null, null, null, null, null] +36506 - null - [null, null, null, null, null] +36507 - null - [null, null, null, null, null] +36508 - null - [null, null, null, null, null] +36509 - null - [null, null, null, null, null] +36510 - null - [null, null, null, null, null] +36511 - null - [null, null, null, null, null] +36512 - null - [null, null, null, null, null] +36513 - Steps - [null, null, null, null, null] +36514 - Steps - [null, null, null, null, null] +36515 - null - [null, null, null, null, null] +36516 - null - [null, null, null, null, null] +36517 - Steps - [null, null, null, null, null] +36518 - null - [null, null, null, null, null] +36519 - Steps - [null, null, null, null, null] +36520 - null - [null, null, null, null, null] +36521 - Steps - [Climb-up, null, null, null, null] +36522 - null - [null, null, null, null, null] +36523 - Steps - [Climb-up, null, null, null, null] +36524 - null - [null, null, null, null, null] +36525 - null - [null, null, null, null, null] +36526 - null - [null, null, null, null, null] +36527 - null - [null, null, null, null, null] +36528 - null - [null, null, null, null, null] +36529 - null - [null, null, null, null, null] +36530 - null - [null, null, null, null, null] +36531 - null - [null, null, null, null, null] +36532 - Steps - [Climb-up, null, null, null, null] +36533 - null - [null, null, null, null, null] +36534 - null - [null, null, null, null, null] +36535 - null - [null, null, null, null, null] +36536 - null - [null, null, null, null, null] +36537 - null - [null, null, null, null, null] +36538 - null - [null, null, null, null, null] +36539 - null - [null, null, null, null, null] +36540 - Steps - [Climb-up, null, null, null, null] +36541 - null - [null, null, null, null, null] +36542 - null - [null, null, null, null, null] +36543 - null - [null, null, null, null, null] +36544 - null - [null, null, null, null, null] +36545 - null - [null, null, null, null, null] +36546 - null - [null, null, null, null, null] +36547 - null - [null, null, null, null, null] +36548 - null - [null, null, null, null, null] +36549 - null - [null, null, null, null, null] +36550 - null - [null, null, null, null, null] +36551 - null - [null, null, null, null, null] +36552 - null - [null, null, null, null, null] +36553 - null - [null, null, null, null, null] +36554 - null - [null, null, null, null, null] +36555 - null - [null, null, null, null, null] +36556 - null - [null, null, null, null, null] +36557 - null - [null, null, null, null, null] +36558 - null - [null, null, null, null, null] +36559 - null - [null, null, null, null, null] +36560 - null - [null, null, null, null, null] +36561 - null - [null, null, null, null, null] +36562 - null - [null, null, null, null, null] +36563 - null - [null, null, null, null, null] +36564 - null - [null, null, null, null, null] +36565 - null - [null, null, null, null, null] +36566 - null - [null, null, null, null, null] +36567 - null - [null, null, null, null, null] +36568 - null - [null, null, null, null, null] +36569 - null - [null, null, null, null, null] +36570 - null - [null, null, null, null, null] +36571 - null - [null, null, null, null, null] +36572 - null - [null, null, null, null, null] +36573 - Table - [Take-from, null, null, null, null] +36574 - Table - [Take-from, null, null, null, null] +36575 - Table - [Take-from, null, null, null, null] +36576 - Table - [Take-from, null, null, null, null] +36577 - Table - [Take-from, null, null, null, null] +36578 - Table - [Take-from, null, null, null, null] +36579 - Table - [Take-from, null, null, null, null] +36580 - Table - [Take-from, null, null, null, null] +36581 - Table - [Take-from, null, null, null, null] +36582 - Table - [Take-from, null, null, null, null] +36583 - Table - [Take-from, null, null, null, null] +36584 - Table - [Take-from, null, null, null, null] +36585 - Table - [Take-from, null, null, null, null] +36586 - Table - [Take-from, null, null, null, null] +36587 - null - [null, null, null, null, null] +36588 - null - [null, null, null, null, null] +36589 - null - [null, null, null, null, null] +36590 - null - [null, null, null, null, null] +36591 - null - [null, null, null, null, null] +36592 - null - [null, null, null, null, null] +36593 - null - [null, null, null, null, null] +36594 - null - [null, null, null, null, null] +36595 - null - [null, null, null, null, null] +36596 - null - [null, null, null, null, null] +36597 - null - [null, null, null, null, null] +36598 - null - [null, null, null, null, null] +36599 - null - [null, null, null, null, null] +36600 - null - [null, null, null, null, null] +36601 - null - [null, null, null, null, null] +36602 - null - [null, null, null, null, null] +36603 - null - [null, null, null, null, null] +36604 - null - [null, null, null, null, null] +36605 - null - [null, null, null, null, null] +36606 - null - [null, null, null, null, null] +36607 - null - [null, null, null, null, null] +36608 - null - [null, null, null, null, null] +36609 - null - [null, null, null, null, null] +36610 - null - [null, null, null, null, null] +36611 - null - [null, null, null, null, null] +36612 - null - [null, null, null, null, null] +36613 - null - [null, null, null, null, null] +36614 - null - [null, null, null, null, null] +36615 - null - [null, null, null, null, null] +36616 - null - [null, null, null, null, null] +36617 - null - [null, null, null, null, null] +36618 - null - [null, null, null, null, null] +36619 - null - [null, null, null, null, null] +36620 - null - [null, null, null, null, null] +36621 - null - [null, null, null, null, null] +36622 - null - [null, null, null, null, null] +36623 - null - [null, null, null, null, null] +36624 - null - [null, null, null, null, null] +36625 - Trapdoor - [Go-down, null, null, null, null] +36626 - Rock - [null, null, null, null, null] +36627 - Rock - [null, null, null, null, null] +36628 - Rocks - [null, null, null, null, null] +36629 - null - [null, null, null, null, null] +36630 - null - [null, null, null, null, null] +36631 - null - [null, null, null, null, null] +36632 - null - [null, null, null, null, null] +36633 - null - [null, null, null, null, null] +36634 - null - [null, null, null, null, null] +36635 - null - [null, null, null, null, null] +36636 - null - [null, null, null, null, null] +36637 - null - [null, null, null, null, null] +36638 - null - [null, null, null, null, null] +36639 - null - [null, null, null, null, null] +36640 - null - [null, null, null, null, null] +36641 - null - [null, null, null, null, null] +36642 - null - [null, null, null, null, null] +36643 - null - [null, null, null, null, null] +36644 - Ladder - [Climb-up, null, null, null, null] +36645 - Ladder - [Climb-up, null, null, null, null] +36646 - Ladder - [Climb-up, null, null, null, null] +36647 - null - [null, null, null, null, null] +36648 - null - [null, null, null, null, null] +36649 - null - [null, null, null, null, null] +36650 - null - [null, null, null, null, null] +36651 - null - [null, null, null, null, null] +36652 - null - [null, null, null, null, null] +36653 - null - [null, null, null, null, null] +36654 - null - [null, null, null, null, null] +36655 - null - [null, null, null, null, null] +36656 - null - [null, null, null, null, null] +36657 - null - [null, null, null, null, null] +36658 - null - [null, null, null, null, null] +36659 - null - [null, null, null, null, null] +36660 - null - [null, null, null, null, null] +36661 - null - [null, null, null, null, null] +36662 - null - [null, null, null, null, null] +36663 - null - [null, null, null, null, null] +36664 - null - [null, null, null, null, null] +36665 - null - [null, null, null, null, null] +36666 - null - [null, null, null, null, null] +36667 - null - [null, null, null, null, null] +36668 - null - [null, null, null, null, null] +36669 - null - [null, null, null, null, null] +36670 - null - [null, null, null, null, null] +36671 - null - [null, null, null, null, null] +36672 - null - [null, null, null, null, null] +36673 - null - [null, null, null, null, null] +36674 - null - [null, null, null, null, null] +36675 - null - [null, null, null, null, null] +36676 - null - [null, null, null, null, null] +36677 - null - [null, null, null, null, null] +36678 - null - [null, null, null, null, null] +36679 - null - [null, null, null, null, null] +36680 - null - [null, null, null, null, null] +36681 - null - [null, null, null, null, null] +36682 - null - [null, null, null, null, null] +36683 - null - [null, null, null, null, null] +36684 - null - [null, null, null, null, null] +36685 - null - [null, null, null, null, null] +36686 - null - [null, null, null, null, null] +36687 - Trapdoor - [Climb-down, null, null, null, null] +36688 - Hollow log - [Inspect, null, null, null, null] +36689 - Hollow log - [Inspect, null, null, null, null] +36690 - Hollow log - [Inspect, null, null, null, null] +36691 - Trapdoor - [Climb-down, null, null, null, null] +36692 - Ladder - [null, null, null, null, null] +36693 - Ladder - [Climb-down, null, null, null, null] +36694 - Ladder - [Climb-down, null, null, null, null] +36695 - Fountain of Heroes - [null, null, null, null, null] +36696 - Ruined Pillar - [null, null, null, null, null] +36697 - Ruined Pillar - [null, null, null, null, null] +36698 - Pillar - [null, null, null, null, null] +36699 - Ruined Pillar - [null, null, null, null, null] +36700 - Ruined Pillar - [null, null, null, null, null] +36701 - Ruined Pillar - [null, null, null, null, null] +36702 - Ruined Pillar - [null, null, null, null, null] +36703 - Ladder - [Climb-down, null, null, null, null] +36704 - null - [null, null, null, null, null] +36705 - Hedge - [null, null, null, null, null] +36706 - Hedge - [null, null, null, null, null] +36707 - Young vine - [Climb, null, null, null, null] +36708 - Young vine - [Climb, null, null, null, null] +36709 - Growing vine - [Climb, null, null, null, null] +36710 - Tall vine - [Climb, null, null, null, null] +36711 - Tropical tree - [null, null, null, null, null] +36712 - Floor spikes - [null, null, null, null, null] +36713 - Opening - [Inspect, null, null, null, null] +36714 - Ogre Coffin - [Open, Pick-lock, null, hidden, null] +36715 - Ogre Coffin - [Open, Pick-lock, null, hidden, null] +36716 - null - [null, null, null, null, null] +36717 - null - [null, null, null, null, null] +36718 - null - [null, null, null, null, null] +36719 - null - [null, null, null, null, null] +36720 - null - [null, null, null, null, null] +36721 - null - [null, null, null, null, null] +36722 - null - [null, null, null, null, null] +36723 - null - [null, null, null, null, null] +36724 - null - [null, null, null, null, null] +36725 - null - [null, null, null, null, null] +36726 - Chair - [null, null, null, null, null] +36727 - Table - [null, null, null, null, null] +36728 - Table - [null, null, null, null, null] +36729 - Wardrobe - [null, null, null, null, null] +36730 - Table - [null, null, null, null, null] +36731 - Table - [null, null, null, null, null] +36732 - Wooden defence - [null, null, null, null, null] +36733 - null - [null, null, null, null, null] +36734 - null - [null, null, null, null, null] +36735 - null - [null, null, null, null, null] +36736 - Coffin - [Close, null, null, null, null] +36737 - Coffin - [Close, null, null, null, null] +36738 - Coffin - [Close, null, null, null, null] +36739 - Coffin - [Close, null, null, null, null] +36740 - null - [null, null, null, null, null] +36741 - null - [null, null, null, null, null] +36742 - null - [null, null, null, null, null] +36743 - null - [null, null, null, null, null] +36744 - Pillar - [null, null, null, null, null] +36745 - Rope swing - [Swing-on, null, null, null, null] +36746 - Rope swing - [Swing-on, null, null, null, null] +36747 - Cave wall - [null, null, null, null, null] +36748 - Cart Camel - [Talk-to, null, null, null, null] +36749 - Statue - [null, null, null, null, null] +36750 - Statue - [null, null, null, null, null] +36751 - Statue - [null, null, null, null, null] +36752 - Statue - [null, null, null, null, null] +36753 - Statue - [null, null, null, null, null] +36754 - Plinth - [null, null, null, null, null] +36755 - null - [null, null, null, null, null] +36756 - null - [null, null, null, null, null] +36757 - null - [null, null, null, null, null] +36758 - null - [null, null, null, null, null] +36759 - null - [null, null, null, null, null] +36760 - null - [null, null, null, null, null] +36761 - null - [null, null, null, null, null] +36762 - null - [null, null, null, null, null] +36763 - null - [null, null, null, null, null] +36764 - null - [null, null, null, null, null] +36765 - Swamp Boaty - [Board, null, null, null, null] +36766 - null - [null, null, null, null, null] +36767 - null - [null, null, null, null, null] +36768 - Ladder - [Climb-up, null, null, null, null] +36769 - Ladder - [Climb, Climb-up, Climb-down, null, null] +36770 - Ladder - [Climb-down, null, null, null, null] +36771 - Ladder - [Climb-up, null, null, null, null] +36772 - Ladder - [Climb-down, null, null, null, null] +36773 - Staircase - [Climb-up, null, null, null, null] +36774 - Staircase - [Climb, Climb-up, Climb-down, null, null] +36775 - Staircase - [Climb-down, null, null, null, null] +36776 - Staircase - [Climb-up, null, null, null, null] +36777 - Staircase - [Climb, Climb-up, Climb-down, null, null] +36778 - Staircase - [Climb-down, null, null, null, null] +36779 - Suit of armour - [null, null, null, null, null] +36780 - Cannon - [null, null, null, null, null] +36781 - Fountain - [null, null, null, null, null] +36782 - Bush - [null, null, null, null, null] +36783 - Chair - [null, null, null, null, null] +36784 - Hanging meat - [null, null, null, null, null] +36785 - Hanging meat - [null, null, null, null, null] +36786 - Bank booth - [Use, Use-quickly, Collect, null, null] +36787 - Closed Bank booth - [null, null, null, null, null] +36788 - Bank deposit box - [Deposit, null, null, null, null] +36789 - Bank table - [null, null, null, null, null] +36790 - Cannonballs - [null, null, null, null, null] +36791 - Stairs - [Climb-up, null, null, null, null] +36792 - Stairs - [Climb-down, null, null, null, null] +36793 - Stairs - [Climb-up, null, null, null, null] +36794 - Stairs - [Climb-down, null, null, null, null] +36795 - Ladder - [Climb-up, null, null, null, null] +36796 - Ladder - [Climb, Climb-up, Climb-down, null, null] +36797 - Ladder - [Climb-down, null, null, null, null] +36798 - Barrel - [null, null, null, null, null] +36799 - Barrel - [null, null, null, null, null] +36800 - Barrel - [null, null, null, null, null] +36801 - Barrel of swords - [null, null, null, null, null] +36802 - Barrel - [null, null, null, null, null] +36803 - Painting - [null, null, null, null, null] +36804 - Painting - [null, null, null, null, null] +36805 - Painting - [null, null, null, null, null] +36806 - Painting - [null, null, null, null, null] +36807 - Hanging tapestry - [null, null, null, null, null] +36808 - Hanging tapestry - [null, null, null, null, null] +36809 - Hanging tapestry - [null, null, null, null, null] +36810 - null - [null, null, null, null, null] +36811 - Painting - [null, null, null, null, null] +36812 - Painting - [null, null, null, null, null] +36813 - Painting - [null, null, null, null, null] +36814 - Painting - [null, null, null, null, null] +36815 - Fireplace - [null, null, null, null, null] +36816 - Fireplace - [null, null, null, null, null] +36817 - Axe cabinet - [null, null, null, null, null] +36818 - Sword cabinet - [null, null, null, null, null] +36819 - Small table - [null, null, null, null, null] +36820 - Table - [null, null, null, null, null] +36821 - Table - [null, null, null, null, null] +36822 - Large table - [null, null, null, null, null] +36823 - Shelves - [null, null, null, null, null] +36824 - Shelves - [null, null, null, null, null] +36825 - Shelves - [null, null, null, null, null] +36826 - Shelves - [null, null, null, null, null] +36827 - null - [null, null, null, null, null] +36828 - null - [null, null, null, null, null] +36829 - Shelves - [null, null, null, null, null] +36830 - Chair - [null, null, null, null, null] +36831 - Chair - [null, null, null, null, null] +36832 - Bookcase - [Search, null, null, null, null] +36833 - Bookcase - [Search, null, null, null, null] +36834 - Bookcase - [Search, null, null, null, null] +36835 - null - [null, null, null, null, null] +36836 - Workbench - [null, null, null, null, null] +36837 - Stool - [null, null, null, null, null] +36838 - null - [null, null, null, null, null] +36839 - null - [null, null, null, null, null] +36840 - null - [null, null, null, null, null] +36841 - Bed - [null, null, null, null, null] +36842 - null - [null, null, null, null, null] +36843 - null - [null, null, null, null, null] +36844 - Door - [Open, null, null, null, null] +36845 - Door - [Close, null, null, null, null] +36846 - Door - [Open, null, null, null, null] +36847 - Door - [Open, null, null, null, null] +36848 - Door - [Close, null, null, null, null] +36849 - null - [null, null, null, null, null] +36850 - null - [null, null, null, null, null] +36851 - Door - [Open, null, null, null, null] +36852 - Door - [Open, null, null, null, null] +36853 - Door - [Close, null, null, null, null] +36854 - null - [null, null, null, null, null] +36855 - null - [null, null, null, null, null] +36856 - Door - [Open, null, null, null, null] +36857 - Door - [Open, null, null, null, null] +36858 - Door - [Close, null, null, null, null] +36859 - Door - [Close, null, null, null, null] +36860 - null - [null, null, null, null, null] +36861 - null - [null, null, null, null, null] +36862 - Door - [Open, null, null, null, null] +36863 - Door - [Open, null, null, null, null] +36864 - Door - [Close, null, null, null, null] +36865 - Door - [Close, null, null, null, null] +36866 - Flag - [null, null, null, null, null] +36867 - Water wheel - [null, null, null, null, null] +36868 - Water wheel - [null, null, null, null, null] +36869 - Water wheel - [null, null, null, null, null] +36870 - null - [null, null, null, null, null] +36871 - Water wheel - [null, null, null, null, null] +36872 - Sails - [null, null, null, null, null] +36873 - Sails - [null, null, null, null, null] +36874 - Mill - [null, null, null, null, null] +36875 - Mill - [null, null, null, null, null] +36876 - null - [null, null, null, null, null] +36877 - Mill - [null, null, null, null, null] +36878 - Flour bin - [Empty, null, null, null, null] +36879 - Mill - [null, null, null, null, null] +36880 - null - [null, null, null, null, null] +36881 - Hopper - [null, null, null, null, null] +36882 - Log pile - [null, null, null, null, null] +36883 - Plough - [null, null, null, null, null] +36884 - Food trough - [null, null, null, null, null] +36885 - Trough - [null, null, null, null, null] +36886 - Trough - [null, null, null, null, null] +36887 - Trough - [null, null, null, null, null] +36888 - Scarecrow - [null, null, null, null, null] +36889 - Cart - [null, null, null, null, null] +36890 - Wheelbarrow - [null, null, null, null, null] +36891 - Tree stump - [null, null, null, null, null] +36892 - Hay bale - [Search, null, null, null, null] +36893 - Hay bale - [Search, null, null, null, null] +36894 - Hay bales - [Search, null, null, null, null] +36895 - Hay bales - [Search, null, null, null, null] +36896 - Hay bales - [Search, null, null, null, null] +36897 - Hay bales - [Search, null, null, null, null] +36898 - Hay bales - [Search, null, null, null, null] +36899 - Hay bales - [Search, null, null, null, null] +36900 - null - [null, null, null, null, null] +36901 - null - [null, null, null, null, null] +36902 - null - [null, null, null, null, null] +36903 - Sack - [null, null, null, null, null] +36904 - Sack - [null, null, null, null, null] +36905 - Bench - [null, null, null, null, null] +36906 - Hat stand - [null, null, null, null, null] +36907 - Quiver - [null, null, null, null, null] +36908 - Wardrobe - [null, null, null, null, null] +36909 - Wardrobe - [null, null, null, null, null] +36910 - Table - [null, null, null, null, null] +36911 - Signpost - [null, null, null, null, null] +36912 - Gate - [Close, null, null, null, null] +36913 - Gate - [Open, null, null, null, null] +36914 - Gate - [Close, null, null, null, null] +36915 - Gate - [Open, null, null, null, null] +36916 - Gate - [Close, null, null, null, null] +36917 - Gate - [Open, null, null, null, null] +36918 - Gate - [Close, null, null, null, null] +36919 - Gate - [Open, null, null, null, null] +36920 - Trapdoor - [Open, null, null, null, null] +36921 - Trapdoor - [Go-down, null, null, null, null] +36922 - null - [null, null, null, null, null] +36923 - Hanging tapestry - [null, null, null, null, null] +36924 - Standard - [null, null, null, null, null] +36925 - Standard - [null, null, null, null, null] +36926 - Standard - [null, null, null, null, null] +36927 - null - [null, null, null, null, null] +36928 - Wooden defence - [null, null, null, null, null] +36929 - Sacks - [Search, null, null, null, null] +36930 - Desk - [null, null, null, null, null] +36931 - A bunk bed - [null, null, null, null, null] +36932 - null - [null, null, null, null, null] +36933 - null - [null, null, null, null, null] +36934 - Cabinet - [null, null, null, null, null] +36935 - Counter - [null, null, null, null, null] +36936 - Stepladder - [null, null, null, null, null] +36937 - Grandfather clock - [null, null, null, null, null] +36938 - null - [null, null, null, null, null] +36939 - null - [null, null, null, null, null] +36940 - null - [null, null, null, null, null] +36941 - Bed - [null, null, null, null, null] +36942 - Bed - [null, null, null, null, null] +36943 - Bed - [null, null, null, null, null] +36944 - Bed - [null, null, null, null, null] +36945 - Ladder - [Climb-up, null, null, null, null] +36946 - Ladder - [Climb-down, null, null, null, null] +36947 - Ladder - [Climb-up, null, null, null, null] +36948 - Ladder - [Climb-down, null, null, null, null] +36949 - Wheelbarrow - [null, null, null, null, null] +36950 - null - [null, null, null, null, null] +36951 - Coop - [null, null, null, null, null] +36952 - Coop - [null, null, null, null, null] +36953 - Coop - [null, null, null, null, null] +36954 - Water barrel - [null, null, null, null, null] +36955 - Water barrel - [null, null, null, null, null] +36956 - Furnace - [null, Smelt, null, null, null] +36957 - null - [null, null, null, null, null] +36958 - null - [null, null, null, null, null] +36959 - Combat dummy - [Attack, null, null, null, null] +36960 - Stairs - [Climb-up, null, null, null, null] +36961 - Stairs - [Climb-down, null, null, null, null] +36962 - Stairs - [Climb-up, null, null, null, null] +36963 - Stairs - [Climb-down, null, null, null, null] +36964 - Stairs - [Climb-up, null, null, null, null] +36965 - Stairs - [Climb-up, null, null, null, null] +36966 - Stairs - [null, null, null, null, null] +36967 - Stairs - [null, null, null, null, null] +36968 - Stairs - [Climb-down, null, null, null, null] +36969 - Stairs - [Climb-down, null, null, null, null] +36970 - Spinning wheel - [Spin, null, null, null, null] +36971 - Sink - [null, null, null, null, null] +36972 - Altar - [Pray, null, null, null, null] +36973 - Range - [null, null, null, null, null] +36974 - Logs - [Take-axe, null, null, null, null] +36975 - Logs - [null, null, null, null, null] +36976 - Bell - [Ring, null, null, null, null] +36977 - Bell - [null, null, null, null, null] +36978 - Organ - [Play, null, null, null, null] +36979 - Organ - [Play, null, null, null, null] +36980 - null - [null, null, null, null, null] +36981 - null - [null, null, null, null, null] +36982 - Stand - [null, null, null, null, null] +36983 - Stand - [null, null, null, null, null] +36984 - Ladder - [Climb-up, null, null, null, null] +36985 - Ladder - [Climb-down, null, null, null, null] +36986 - Ladder - [Climb-up, null, null, null, null] +36987 - Ladder - [Climb-down, null, null, null, null] +36988 - Ladder - [Climb-up, null, null, null, null] +36989 - Ladder - [Climb-up, null, null, null, null] +36990 - Ladder - [Climb-down, null, null, null, null] +36991 - Ladder - [Climb-down, null, null, null, null] +36992 - null - [null, null, null, null, null] +36993 - Ladder - [Climb-up, null, null, null, null] +36994 - Ladder - [Climb-down, null, null, null, null] +36995 - Ladder - [Climb-up, null, null, null, null] +36996 - Ladder - [Climb-down, null, null, null, null] +36997 - Ladder - [Climb-up, null, null, null, null] +36998 - Ladder - [Climb-down, null, null, null, null] +36999 - Church door - [Open, null, null, null, null] +37000 - Church door - [Close, null, null, null, null] +37001 - null - [null, null, null, null, null] +37002 - Church door - [Open, null, null, null, null] +37003 - Church door - [Close, null, null, null, null] +37004 - null - [null, null, null, null, null] +37005 - Gravestone - [null, null, null, null, null] +37006 - Gravestone - [null, null, null, null, null] +37007 - Candle - [null, null, null, null, null] +37008 - Organ - [null, null, null, null, null] +37009 - Closed chest - [Open, null, null, null, null] +37010 - Open chest - [null, Search, Shut, null, null] +37011 - Drawers - [Open, null, null, null, null] +37012 - Drawers - [null, Search, Close, null, null] +37013 - Drawers - [Open, null, null, null, null] +37014 - Drawers - [null, Search, Close, null, null] +37015 - Crate - [Search, null, null, null, null] +37016 - Crate - [Search, null, null, null, null] +37017 - Boxes - [Search, null, null, null, null] +37018 - Doorway - [null, null, null, null, null] +37019 - null - [null, null, null, null, null] +37020 - null - [Open, null, null, null, null] +37021 - null - [null, null, null, null, null] +37022 - null - [null, null, null, null, null] +37023 - Staircase - [Climb-down, null, null, null, null] +37024 - null - [null, null, null, null, null] +37025 - Cabinet - [null, null, null, null, null] +37026 - Cabinet - [null, null, null, null, null] +37027 - Drawers - [Open, null, null, null, null] +37028 - Drawers - [null, Search, Shut, null, null] +37029 - Crate - [Search, null, null, null, null] +37030 - Crate - [Search, null, null, null, null] +37031 - Crate - [Search, null, null, null, null] +37032 - sacks - [Search, null, null, null, null] +37033 - null - [null, null, null, null, null] +37034 - Cupboard - [Open, null, null, null, null] +37035 - Cupboard - [Open, null, null, null, null] +37036 - Open Cupboard - [null, Search, Shut, null, null] +37037 - Cupboard - [Open, null, null, null, null] +37038 - Open Cupboard - [null, Search, Shut, null, null] +37039 - Cupboard - [null, Search, Shut, null, null] +37040 - Closed chest - [Open, null, null, null, null] +37041 - Closed chest - [Open, null, null, null, null] +37042 - Open chest - [null, Search, Shut, null, null] +37043 - Open chest - [null, Search, Shut, null, null] +37044 - Open chest - [null, Search, Shut, null, null] +37045 - Open chest - [null, Search, Shut, null, null] +37046 - Open chest - [null, Search, Shut, null, null] +37047 - Bookcase - [Search, null, null, null, null] +37048 - Wardrobe - [Open, null, null, null, null] +37049 - Wardrobe - [null, Search, Close, null, null] +37050 - Wardrobe - [null, Search, Close, null, null] +37051 - Wardrobe - [Open, null, null, null, null] +37052 - Wardrobe - [null, Search, Close, null, null] +37053 - Wardrobe - [null, Search, Close, null, null] +37054 - null - [null, null, null, null, null] +37055 - null - [null, null, null, null, null] +37056 - null - [null, null, null, null, null] +37057 - null - [null, null, null, null, null] +37058 - null - [null, null, null, null, null] +37059 - null - [null, null, null, null, null] +37060 - null - [null, null, null, null, null] +37061 - null - [null, null, null, null, null] +37062 - Ship's ladder - [Climb-up, null, null, null, null] +37063 - null - [null, null, null, null, null] +37064 - null - [null, null, null, null, null] +37065 - null - [null, null, null, null, null] +37066 - null - [null, null, null, null, null] +37067 - null - [null, null, null, null, null] +37068 - Figurehead - [null, null, null, null, null] +37069 - null - [null, null, null, null, null] +37070 - null - [null, null, null, null, null] +37071 - null - [null, null, null, null, null] +37072 - null - [null, null, null, null, null] +37073 - Stags - [null, null, null, null, null] +37074 - Ectoplasm - [null, null, null, null, null] +37075 - null - [null, null, null, null, null] +37076 - null - [null, null, null, null, null] +37077 - null - [null, null, null, null, null] +37078 - null - [null, null, null, null, null] +37079 - null - [null, null, null, null, null] +37080 - null - [null, null, null, null, null] +37081 - null - [null, null, null, null, null] +37082 - null - [null, null, null, null, null] +37083 - null - [null, null, null, null, null] +37084 - null - [null, null, null, null, null] +37085 - null - [null, null, null, null, null] +37086 - null - [null, null, null, null, null] +37087 - Tiling - [null, null, null, null, null] +37088 - Trapdoor - [Climb-down, null, null, null, null] +37089 - null - [null, null, null, null, null] +37090 - null - [null, null, null, null, null] +37091 - Trapdoor - [null, null, null, null, null] +37092 - Springboard - [Step-on, null, null, null, null] +37093 - null - [null, null, null, null, null] +37094 - null - [null, null, null, null, null] +37095 - Archery target - [Shoot-at, null, null, null, null] +37096 - Archery target - [Shoot-at, null, null, null, null] +37097 - null - [null, null, null, null, null] +37098 - null - [null, null, null, null, null] +37099 - null - [null, null, null, null, null] +37100 - null - [null, null, null, null, null] +37101 - null - [null, null, null, null, null] +37102 - null - [null, null, null, null, null] +37103 - null - [null, null, null, null, null] +37104 - null - [null, null, null, null, null] +37105 - null - [null, null, null, null, null] +37106 - null - [null, null, null, null, null] +37107 - null - [null, null, null, null, null] +37108 - null - [null, null, null, null, null] +37109 - null - [null, null, null, null, null] +37110 - null - [null, null, null, null, null] +37111 - null - [null, null, null, null, null] +37112 - null - [null, null, null, null, null] +37113 - null - [null, null, null, null, null] +37114 - Barrel - [null, null, null, null, null] +37115 - null - [null, null, null, null, null] +37116 - null - [null, null, null, null, null] +37117 - null - [null, null, null, null, null] +37118 - Bookcase - [Search, null, null, null, null] +37119 - Bookcase - [Search, null, null, null, null] +37120 - null - [null, null, null, null, null] +37121 - Mirror - [null, null, null, null, null] +37122 - Broom - [null, null, null, null, null] +37123 - Carcass - [null, null, null, null, null] +37124 - null - [null, null, null, null, null] +37125 - null - [null, null, null, null, null] +37126 - null - [null, null, null, null, null] +37127 - null - [null, null, null, null, null] +37128 - null - [null, null, null, null, null] +37129 - null - [null, null, null, null, null] +37130 - null - [null, null, null, null, null] +37131 - null - [null, null, null, null, null] +37132 - null - [null, null, null, null, null] +37133 - null - [null, null, null, null, null] +37134 - null - [null, null, null, null, null] +37135 - null - [null, null, null, null, null] +37136 - null - [null, null, null, null, null] +37137 - null - [null, null, null, null, null] +37138 - null - [null, null, null, null, null] +37139 - null - [null, null, null, null, null] +37140 - null - [null, null, null, null, null] +37141 - null - [null, null, null, null, null] +37142 - null - [null, null, null, null, null] +37143 - null - [null, null, null, null, null] +37144 - null - [null, null, null, null, null] +37145 - null - [null, null, null, null, null] +37146 - null - [null, null, null, null, null] +37147 - null - [null, null, null, null, null] +37148 - null - [null, null, null, null, null] +37149 - null - [null, null, null, null, null] +37150 - Cooking Pots - [null, null, null, null, null] +37151 - null - [null, null, null, null, null] +37152 - null - [null, null, null, null, null] +37153 - Sign - [null, null, null, null, null] +37154 - Sink - [null, null, null, null, null] +37155 - Sink - [null, null, null, null, null] +37156 - Bath - [null, null, null, null, null] +37157 - Bar pumps - [null, null, null, null, null] +37158 - Bank table - [null, null, null, null, null] +37159 - Bank table - [null, null, null, null, null] +37160 - Table - [null, null, null, null, null] +37161 - Table - [null, null, null, null, null] +37162 - Table - [null, null, null, null, null] +37163 - Table - [null, null, null, null, null] +37164 - Table - [null, null, null, null, null] +37165 - Table - [null, null, null, null, null] +37166 - Table - [null, null, null, null, null] +37167 - Table - [null, null, null, null, null] +37168 - Study desk - [null, null, null, null, null] +37169 - Counter - [null, null, null, null, null] +37170 - Shelves - [null, null, null, null, null] +37171 - Shelves - [null, null, null, null, null] +37172 - Shelves - [null, null, null, null, null] +37173 - Shelves - [null, null, null, null, null] +37174 - Shelves - [null, null, null, null, null] +37175 - Shelves - [null, null, null, null, null] +37176 - Shelves - [null, null, null, null, null] +37177 - Shelves - [null, null, null, null, null] +37178 - Shelves - [null, null, null, null, null] +37179 - Shelves - [null, null, null, null, null] +37180 - Shelves - [null, null, null, null, null] +37181 - Shelf - [null, null, null, null, null] +37182 - null - [null, null, null, null, null] +37183 - null - [null, null, null, null, null] +37184 - null - [null, null, null, null, null] +37185 - null - [null, null, null, null, null] +37186 - null - [null, null, null, null, null] +37187 - null - [null, null, null, null, null] +37188 - null - [null, null, null, null, null] +37189 - null - [null, null, null, null, null] +37190 - null - [null, null, null, null, null] +37191 - null - [null, null, null, null, null] +37192 - null - [null, null, null, null, null] +37193 - Stalactite - [null, null, null, null, null] +37194 - Crashed glider - [null, null, null, null, null] +37195 - null - [null, null, null, null, null] +37196 - Whirpool - [null, null, null, null, null] +37197 - null - [null, null, null, null, null] +37198 - null - [null, null, null, null, null] +37199 - null - [null, null, null, null, null] +37200 - null - [null, null, null, null, null] +37201 - null - [null, null, null, null, null] +37202 - null - [null, null, null, null, null] +37203 - null - [null, null, null, null, null] +37204 - null - [null, null, null, null, null] +37205 - null - [null, null, null, null, null] +37206 - null - [null, null, null, null, null] +37207 - null - [null, null, null, null, null] +37208 - Rocks - [Mine, Prospect, hidden, null, null] +37209 - null - [null, null, null, null, null] +37210 - Whirpool - [null, null, null, null, null] +37211 - null - [null, null, null, null, null] +37212 - null - [null, null, null, null, null] +37213 - null - [null, null, null, null, null] +37214 - null - [null, null, null, null, null] +37215 - null - [null, null, null, null, null] +37216 - null - [null, null, null, null, null] +37217 - null - [null, null, null, null, null] +37218 - null - [null, null, null, null, null] +37219 - null - [null, null, null, null, null] +37220 - null - [null, null, null, null, null] +37221 - null - [null, null, null, null, null] +37222 - null - [null, null, null, null, null] +37223 - null - [null, null, null, null, null] +37224 - null - [null, null, null, null, null] +37225 - null - [null, null, null, null, null] +37226 - null - [null, null, null, null, null] +37227 - null - [null, null, null, null, null] +37228 - null - [null, null, null, null, null] +37229 - null - [null, null, null, null, null] +37230 - null - [null, null, null, null, null] +37231 - null - [null, null, null, null, null] +37232 - null - [null, null, null, null, null] +37233 - null - [null, null, null, null, null] +37234 - null - [null, null, null, null, null] +37235 - null - [null, null, null, null, null] +37236 - null - [null, null, null, null, null] +37237 - null - [null, null, null, null, null] +37238 - null - [null, null, null, null, null] +37239 - null - [null, null, null, null, null] +37240 - null - [null, null, null, null, null] +37241 - null - [null, null, null, null, null] +37242 - null - [null, null, null, null, null] +37243 - null - [null, null, null, null, null] +37244 - null - [null, null, null, null, null] +37245 - Ledge - [Open, null, null, null, null] +37246 - Ledge - [Open, null, null, null, null] +37247 - Ledge - [Open, null, null, null, null] +37248 - null - [null, null, null, null, null] +37249 - null - [null, null, null, null, null] +37250 - null - [null, null, null, null, null] +37251 - null - [null, null, null, null, null] +37252 - null - [null, null, null, null, null] +37253 - null - [null, null, null, null, null] +37254 - null - [null, null, null, null, null] +37255 - null - [null, null, null, null, null] +37256 - null - [null, null, null, null, null] +37257 - null - [null, null, null, null, null] +37258 - null - [null, null, null, null, null] +37259 - null - [null, null, null, null, null] +37260 - null - [null, null, null, null, null] +37261 - null - [null, null, null, null, null] +37262 - null - [null, null, null, null, null] +37263 - null - [null, null, null, null, null] +37264 - null - [null, null, null, null, null] +37265 - null - [null, null, null, null, null] +37266 - null - [null, null, null, null, null] +37267 - null - [null, null, null, null, null] +37268 - null - [null, null, null, null, null] +37269 - null - [null, null, null, null, null] +37270 - null - [null, null, null, null, null] +37271 - null - [null, null, null, null, null] +37272 - null - [null, null, null, null, null] +37273 - null - [null, null, null, null, null] +37274 - null - [null, null, null, null, null] +37275 - null - [null, null, null, null, null] +37276 - null - [null, null, null, null, null] +37277 - null - [null, null, null, null, null] +37278 - null - [null, null, null, null, null] +37279 - null - [null, null, null, null, null] +37280 - null - [null, null, null, null, null] +37281 - null - [null, null, null, null, null] +37282 - null - [null, null, null, null, null] +37283 - null - [null, null, null, null, null] +37284 - null - [null, null, null, null, null] +37285 - null - [null, null, null, null, null] +37286 - null - [null, null, null, null, null] +37287 - null - [null, null, null, null, null] +37288 - null - [null, null, null, null, null] +37289 - null - [null, null, null, null, null] +37290 - null - [null, null, null, null, null] +37291 - null - [null, null, null, null, null] +37292 - null - [null, null, null, null, null] +37293 - null - [null, null, null, null, null] +37294 - null - [null, null, null, null, null] +37295 - Bookcase - [Search, null, null, null, null] +37296 - Corpse - [null, null, null, null, null] +37297 - Smashed chair - [null, null, null, null, null] +37298 - Bench - [null, null, null, null, null] +37299 - Shelves - [null, null, null, null, null] +37300 - Shelves - [null, null, null, null, null] +37301 - Shelves - [null, null, null, null, null] +37302 - null - [null, null, null, null, null] +37303 - null - [null, null, null, null, null] +37304 - Rocks - [Mine, Prospect, hidden, null, null] +37305 - Rocks - [Mine, Prospect, hidden, null, null] +37306 - Rocks - [Mine, Prospect, hidden, null, null] +37307 - Rocks - [Mine, Prospect, hidden, null, null] +37308 - Rocks - [Mine, Prospect, hidden, null, null] +37309 - Rocks - [Mine, Prospect, hidden, null, null] +37310 - Rocks - [Mine, Prospect, hidden, null, null] +37311 - Rocks - [Mine, Prospect, hidden, null, null] +37312 - Rocks - [Mine, Prospect, hidden, null, null] +37313 - null - [null, null, null, null, null] +37314 - null - [null, null, null, null, null] +37315 - Pillar - [null, null, null, null, null] +37316 - null - [null, null, null, null, null] +37317 - Pillar - [null, null, null, null, null] +37318 - Shelves - [null, null, null, null, null] +37319 - Shelves - [null, null, null, null, null] +37320 - null - [null, null, null, null, null] +37321 - Hanging roots - [null, null, null, null, null] +37322 - Hanging roots - [null, null, null, null, null] +37323 - null - [null, null, null, null, null] +37324 - null - [null, null, null, null, null] +37325 - null - [null, null, null, null, null] +37326 - null - [null, null, null, null, null] +37327 - Flower - [null, null, null, null, null] +37328 - Trollweiss flowers - [null, Pick, null, null, null] +37329 - Flowerbed - [null, null, null, null, null] +37330 - Flowers - [null, null, null, null, null] +37331 - null - [null, null, null, null, null] +37332 - null - [null, null, null, null, null] +37333 - null - [null, null, null, null, null] +37334 - Dead tree - [null, null, null, null, null] +37335 - Flag - [Raise, null, null, null, null] +37336 - Winch - [Operate, null, null, null, null] +37337 - Chair - [null, null, null, null, null] +37338 - Pillar - [null, null, null, null, null] +37339 - Pillar - [null, null, null, null, null] +37340 - Pillar - [null, null, null, null, null] +37341 - Pillar - [null, null, null, null, null] +37342 - null - [null, null, null, null, null] +37343 - Stool - [null, null, null, null, null] +37344 - null - [null, null, null, null, null] +37345 - null - [null, null, null, null, null] +37346 - null - [null, null, null, null, null] +37347 - null - [null, null, null, null, null] +37348 - null - [null, null, null, null, null] +37349 - null - [null, null, null, null, null] +37350 - Table - [null, null, null, null, null] +37351 - Gate - [Close, null, null, null, null] +37352 - Gate - [Open, null, null, null, null] +37353 - Gate - [Close, null, null, null, null] +37354 - Gate - [Open, null, null, null, null] +37355 - null - [null, null, null, null, null] +37356 - null - [null, null, null, null, null] +37357 - null - [null, null, null, null, null] +37358 - null - [null, null, null, null, null] +37359 - null - [null, null, null, null, null] +37360 - null - [null, null, null, null, null] +37361 - null - [null, null, null, null, null] +37362 - null - [null, null, null, null, null] +37363 - null - [null, null, null, null, null] +37364 - Stones - [null, null, null, null, null] +37365 - Stones - [null, null, null, null, null] +37366 - Stones - [null, null, null, null, null] +37367 - Stones - [null, null, null, null, null] +37368 - Tree - [null, null, null, null, null] +37369 - null - [null, null, null, null, null] +37370 - null - [null, null, null, null, null] +37371 - null - [null, null, null, null, null] +37372 - null - [null, null, null, null, null] +37373 - Food trough - [null, null, null, null, null] +37374 - Crate - [null, null, null, null, null] +37375 - Crate - [null, null, null, null, null] +37376 - Crate - [Search, null, null, null, null] +37377 - Sack - [Search, null, null, null, null] +37378 - null - [null, null, null, null, null] +37379 - null - [null, null, null, null, null] +37380 - null - [null, null, null, null, null] +37381 - null - [null, null, null, null, null] +37382 - null - [null, null, null, null, null] +37383 - null - [null, null, null, null, null] +37384 - null - [null, null, null, null, null] +37385 - Shelf - [null, null, null, null, null] +37386 - null - [null, null, null, null, null] +37387 - null - [null, null, null, null, null] +37388 - null - [null, null, null, null, null] +37389 - null - [null, null, null, null, null] +37390 - null - [null, null, null, null, null] +37391 - Foliage - [null, null, null, null, null] +37392 - Foliage - [null, null, null, null, null] +37393 - Tropical tree - [null, null, null, null, null] +37394 - Palm tree - [null, null, null, null, null] +37395 - null - [null, null, null, null, null] +37396 - null - [null, null, null, null, null] +37397 - null - [null, null, null, null, null] +37398 - null - [null, null, null, null, null] +37399 - Stone Pile - [null, null, null, null, null] +37400 - Barrel - [null, null, null, null, null] +37401 - Barrel - [null, null, null, null, null] +37402 - Stool - [null, null, null, null, null] +37403 - Stool - [null, null, null, null, null] +37404 - Foliage - [Search, null, null, null, null] +37405 - Foliage - [Search, null, null, null, null] +37406 - null - [null, null, null, null, null] +37407 - null - [null, null, null, null, null] +37408 - null - [null, null, null, null, null] +37409 - null - [null, null, null, null, null] +37410 - null - [null, null, null, null, null] +37411 - null - [null, null, null, null, null] +37412 - null - [null, null, null, null, null] +37413 - null - [null, null, null, null, null] +37414 - null - [null, null, null, null, null] +37415 - null - [null, null, null, null, null] +37416 - null - [null, null, null, null, null] +37417 - null - [null, null, null, null, null] +37418 - null - [null, null, null, null, null] +37419 - Table - [null, null, null, null, null] +37420 - Wardrobe - [null, null, null, null, null] +37421 - Bed - [null, null, null, null, null] +37422 - Ladder - [Climb-up, null, null, null, null] +37423 - Ladder - [Climb-down, null, null, null, null] +37424 - null - [null, null, null, null, null] +37425 - null - [null, null, null, null, null] +37426 - Fireplace - [null, null, null, null, null] +37427 - null - [null, null, null, null, null] +37428 - null - [null, null, null, null, null] +37429 - null - [null, null, null, null, null] +37430 - null - [null, null, null, null, null] +37431 - null - [null, null, null, null, null] +37432 - null - [null, null, null, null, null] +37433 - null - [null, null, null, null, null] +37434 - null - [null, null, null, null, null] +37435 - null - [null, null, null, null, null] +37436 - null - [null, null, null, null, null] +37437 - null - [null, null, null, null, null] +37438 - Ancient Door - [null, Open, Search, null, null] +37439 - Ancient Door - [null, null, null, null, null] +37440 - Ancient Door - [null, Open, Search, null, null] +37441 - Ancient Door - [null, null, null, null, null] +37442 - Ancient Door - [null, null, null, Enter, null] +37443 - Ancient Door - [null, null, null, null, null] +37444 - Ancient Door - [null, null, Enter, null, null] +37445 - Ancient Door - [null, null, null, null, null] +37446 - null - [null, null, null, null, null] +37447 - null - [null, null, null, null, null] +37448 - null - [null, null, null, null, null] +37449 - null - [null, null, null, null, null] +37450 - null - [null, null, null, null, null] +37451 - Pillar - [null, null, null, null, null] +37452 - Bridge - [null, null, null, null, null] +37453 - null - [null, null, null, null, null] +37454 - Staircase - [Climb-up, null, null, null, null] +37455 - null - [null, null, null, null, null] +37456 - null - [null, null, null, null, null] +37457 - null - [null, null, null, null, null] +37458 - null - [null, null, null, null, null] +37459 - null - [null, null, null, null, null] +37460 - null - [null, null, null, null, null] +37461 - null - [null, null, null, null, null] +37462 - null - [null, null, null, null, null] +37463 - null - [null, null, null, null, null] +37464 - null - [null, null, null, null, null] +37465 - Rocks - [Mine, Prospect, hidden, null, null] +37466 - Rocks - [Mine, Prospect, hidden, null, null] +37467 - Rocks - [Mine, Prospect, hidden, null, null] +37468 - Rocks - [Mine, Prospect, hidden, null, null] +37469 - Rocks - [Mine, Prospect, hidden, null, null] +37470 - Rocks - [Mine, Prospect, hidden, null, null] +37471 - Rocks - [Mine, Prospect, hidden, null, null] +37472 - Rocks - [Mine, Prospect, hidden, null, null] +37473 - Rocks - [Mine, Prospect, hidden, null, null] +37474 - Bank booth - [Use, null, null, null, null] +37475 - Bell - [Ring, null, null, null, null] +37476 - Spinning wheel - [Spin, null, null, null, null] +37477 - Tree - [Chop down, null, hidden, null, null] +37478 - Tree - [Chop down, null, hidden, null, null] +37479 - Oak - [Chop down, null, hidden, null, null] +37480 - Willow - [Chop down, null, hidden, null, null] +37481 - Dead tree - [Chop down, null, hidden, null, null] +37482 - Dead tree - [Chop down, null, hidden, null, null] +37483 - Dead tree - [Chop down, null, hidden, null, null] +37484 - Trapdoor - [Open, null, null, null, null] +37485 - Sign - [null, null, null, null, null] +37486 - Door - [null, null, null, null, null] +37487 - Staircase - [Climb-up, null, null, null, null] +37488 - Staircase - [Climb, Climb-up, Climb-down, null, null] +37489 - Staircase - [Climb-down, null, null, null, null] +37490 - Staircase - [Climb-up, null, null, null, null] +37491 - Staircase - [Climb, Climb-up, Climb-down, null, null] +37492 - Staircase - [Climb-down, null, null, null, null] +37493 - Staircase - [Climb-up, null, null, null, null] +37494 - Staircase - [Climb-up, null, null, null, null] +37495 - Staircase - [Climb, Climb-up, Climb-down, null, null] +37496 - Staircase - [Climb, Climb-up, Climb-down, null, null] +37497 - Staircase - [Climb-down, null, null, null, null] +37498 - Staircase - [Climb-down, null, null, null, null] +37499 - null - [null, null, null, null, null] +37500 - null - [null, null, null, null, null] +37501 - null - [null, null, null, null, null] +37502 - Ladder - [Climb-up, null, null, null, null] +37503 - Ladder - [Climb-down, null, null, null, null] +37504 - Flag - [Raise, null, null, null, null] +37505 - Gate - [null, null, null, null, null] +37506 - Gate - [null, null, null, null, null] +37507 - Gate - [Open, null, null, null, null] +37508 - null - [null, null, null, null, null] +37509 - null - [null, null, null, null, null] +37510 - null - [null, null, null, null, null] +37511 - null - [null, null, null, null, null] +37512 - null - [null, null, null, null, null] +37513 - null - [null, null, null, null, null] +37514 - null - [null, null, null, null, null] +37515 - null - [null, null, null, null, null] +37516 - null - [null, null, null, null, null] +37517 - null - [null, null, null, null, null] +37518 - null - [null, null, null, null, null] +37519 - null - [null, null, null, null, null] +37520 - null - [null, null, null, null, null] +37521 - null - [null, null, null, null, null] +37522 - null - [null, null, null, null, null] +37523 - null - [null, null, null, null, null] +37524 - null - [null, null, null, null, null] +37525 - null - [null, null, null, null, null] +37526 - null - [null, null, null, null, null] +37527 - null - [null, null, null, null, null] +37528 - null - [null, null, null, null, null] +37529 - null - [null, null, null, null, null] +37530 - null - [null, null, null, null, null] +37531 - null - [null, null, null, null, null] +37532 - null - [null, null, null, null, null] +37533 - null - [null, null, null, null, null] +37534 - null - [null, null, null, null, null] +37535 - null - [null, null, null, null, null] +37536 - null - [null, null, null, null, null] +37537 - null - [null, null, null, null, null] +37538 - null - [null, null, null, null, null] +37539 - null - [null, null, null, null, null] +37540 - null - [null, null, null, null, null] +37541 - null - [null, null, null, null, null] +37542 - null - [null, null, null, null, null] +37543 - null - [null, null, null, null, null] +37544 - null - [null, null, null, null, null] +37545 - null - [null, null, null, null, null] +37546 - null - [null, null, null, null, null] +37547 - null - [null, null, null, null, null] +37548 - null - [null, null, null, null, null] +37549 - null - [null, null, null, null, null] +37550 - null - [null, null, null, null, null] +37551 - null - [null, null, null, null, null] +37552 - null - [null, null, null, null, null] +37553 - null - [null, null, null, null, null] +37554 - null - [null, null, null, null, null] +37555 - null - [null, null, null, null, null] +37556 - null - [null, null, null, null, null] +37557 - null - [null, null, null, null, null] +37558 - null - [null, null, null, null, null] +37559 - null - [null, null, null, null, null] +37560 - null - [null, null, null, null, null] +37561 - null - [null, null, null, null, null] +37562 - null - [null, null, null, null, null] +37563 - null - [null, null, null, null, null] +37564 - null - [null, null, null, null, null] +37565 - null - [null, null, null, null, null] +37566 - null - [null, null, null, null, null] +37567 - null - [null, null, null, null, null] +37568 - null - [null, null, null, null, null] +37569 - null - [null, null, null, null, null] +37570 - null - [null, null, null, null, null] +37571 - null - [null, null, null, null, null] +37572 - null - [null, null, null, null, null] +37573 - null - [null, null, null, null, null] +37574 - null - [null, null, null, null, null] +37575 - null - [null, null, null, null, null] +37576 - null - [null, null, null, null, null] +37577 - null - [null, null, null, null, null] +37578 - null - [null, null, null, null, null] +37579 - null - [null, null, null, null, null] +37580 - null - [null, null, null, null, null] +37581 - Stool - [null, null, null, null, null] +37582 - Sir Vant - [null, null, null, null, null] +37583 - Barrel - [null, null, null, null, null] +37584 - Barrel - [null, null, null, null, null] +37585 - Water barrel - [null, null, null, null, null] +37586 - Barrel - [null, null, null, null, null] +37587 - Crate - [null, null, null, null, null] +37588 - Crate - [null, null, null, null, null] +37589 - Crates - [null, null, null, null, null] +37590 - Storage crate - [null, null, null, null, null] +37591 - Stacked crates - [null, null, null, null, null] +37592 - Shelves - [null, null, null, null, null] +37593 - Shelves - [null, null, null, null, null] +37594 - Barrel stack - [null, null, null, null, null] +37595 - null - [null, null, null, null, null] +37596 - Torch - [null, null, null, null, null] +37597 - Fire - [null, null, null, null, null] +37598 - Puddle - [null, null, null, null, null] +37599 - Puddle - [null, null, null, null, null] +37600 - Puddle - [null, null, null, null, null] +37601 - Puddle - [null, null, null, null, null] +37602 - Puddle - [null, null, null, null, null] +37603 - null - [null, null, null, null, null] +37604 - null - [null, null, null, null, null] +37605 - null - [null, null, null, null, null] +37606 - null - [null, null, null, null, null] +37607 - null - [null, null, null, null, null] +37608 - null - [null, null, null, null, null] +37609 - null - [null, null, null, null, null] +37610 - null - [null, null, null, null, null] +37611 - null - [null, null, null, null, null] +37612 - Buffers - [null, null, null, null, null] +37613 - null - [null, null, null, null, null] +37614 - null - [null, null, null, null, null] +37615 - null - [null, null, null, null, null] +37616 - null - [null, null, null, null, null] +37617 - null - [null, null, null, null, null] +37618 - Mine Cart - [null, null, null, null, null] +37619 - Rock - [null, null, null, null, null] +37620 - Rock - [null, null, null, null, null] +37621 - Rock - [null, null, null, null, null] +37622 - Anvil - [null, null, null, null, null] +37623 - Crate - [Search, null, null, null, null] +37624 - Ladder - [Climb-up, null, null, null, null] +37625 - Ladder - [Climb-down, null, null, null, null] +37626 - Archery target - [Shoot-at, null, null, null, null] +37627 - Archery target - [Shoot-at, null, null, null, null] +37628 - Sword and shield - [null, null, null, null, null] +37629 - Range - [null, null, null, null, null] +37630 - Altar - [Pray, null, null, null, null] +37631 - Mine entrance - [Enter, null, null, null, null] +37632 - Mine entrance - [Enter, null, null, null, null] +37633 - Caved-in mine - [null, null, null, null, null] +37634 - Caved-in mine - [null, null, null, null, null] +37635 - null - [null, null, null, null, null] +37636 - Steps - [Exit, null, null, null, null] +37637 - Rocks - [Mine, Prospect, hidden, null, null] +37638 - Rocks - [Mine, Prospect, hidden, null, null] +37639 - Rocks - [Mine, Prospect, hidden, null, null] +37640 - null - [null, null, null, null, null] +37641 - null - [null, null, null, null, null] +37642 - Rocks - [Mine, Prospect, hidden, null, null] +37643 - Rocks - [Mine, Prospect, hidden, null, null] +37644 - Rocks - [Mine, Prospect, hidden, null, null] +37645 - Rocks - [Mine, Prospect, hidden, null, null] +37646 - Rocks - [Mine, Prospect, hidden, null, null] +37647 - Rocks - [Mine, Prospect, hidden, null, null] +37648 - Rocks - [Mine, Prospect, hidden, null, null] +37649 - Rocks - [Mine, Prospect, hidden, null, null] +37650 - Rocks - [Mine, Prospect, hidden, null, null] +37651 - Furnace - [null, Smelt, null, null, null] +37652 - Tree - [Chop down, null, hidden, null, null] +37653 - Tree stump - [null, null, null, null, null] +37654 - null - [null, null, null, null, null] +37655 - Lumbridge map - [View, null, null, null, null] +37656 - Rock column - [null, null, null, null, null] +37657 - Rock column - [null, null, null, null, null] +37658 - Rock column - [null, null, null, null, null] +37659 - null - [null, null, null, null, null] +37660 - null - [null, null, null, null, null] +37661 - null - [null, null, null, null, null] +37662 - null - [null, null, null, null, null] +37663 - null - [null, null, null, null, null] +37664 - null - [null, null, null, null, null] +37665 - null - [null, null, null, null, null] +37666 - null - [null, null, null, null, null] +37667 - null - [null, null, null, null, null] +37668 - Railing - [Taunt-through, null, null, null, null] +37669 - Rocks - [null, null, null, null, null] +37670 - Rocks - [Mine, Prospect, hidden, null, null] +37671 - Globe table - [null, null, null, null, null] +37672 - Chart table - [null, null, null, null, null] +37673 - Compass table - [null, null, null, null, null] +37674 - null - [null, null, null, null, null] +37675 - Kalphite Queen head - [null, null, null, null, null] +37676 - Big vase - [null, null, null, null, null] +37677 - null - [null, null, null, null, null] +37678 - null - [null, null, null, null, null] +37679 - null - [null, null, null, null, null] +37680 - null - [null, null, null, null, null] +37681 - null - [null, null, null, null, null] +37682 - Flag - [null, null, null, null, null] +37683 - Ladder - [Climb-down, null, null, null, null] +37684 - Ladder - [Climb-up, null, null, null, null] +37685 - Rocks - [Mine, Prospect, hidden, null, null] +37686 - Rocks - [Mine, Prospect, hidden, null, null] +37687 - Rocks - [Mine, Prospect, hidden, null, null] +37688 - Rocks - [Mine, Prospect, hidden, null, null] +37689 - Rocks - [Mine, Prospect, hidden, null, null] +37690 - Rocks - [Mine, Prospect, hidden, null, null] +37691 - Rocks - [Mine, Prospect, hidden, null, null] +37692 - Rocks - [Mine, Prospect, hidden, null, null] +37693 - Rocks - [Mine, Prospect, hidden, null, null] +37694 - Rocks - [Mine, Prospect, hidden, null, null] +37695 - Rocks - [Mine, Prospect, hidden, null, null] +37696 - Rocks - [Mine, Prospect, hidden, null, null] +37697 - Rocks - [Mine, Prospect, hidden, null, null] +37698 - Rocks - [Mine, Prospect, hidden, null, null] +37699 - Rocks - [Mine, Prospect, hidden, null, null] +37700 - Rocks - [Mine, Prospect, hidden, null, null] +37701 - Rocks - [Mine, Prospect, hidden, null, null] +37702 - Rocks - [Mine, Prospect, hidden, null, null] +37703 - Broken railing - [Squeeze-through, null, null, null, null] +37704 - Stepping stone - [Cross, null, null, null, null] +37705 - null - [null, null, null, null, null] +37706 - null - [null, null, null, null, null] +37707 - null - [null, null, null, null, null] +37708 - null - [null, null, null, null, null] +37709 - null - [null, null, null, null, null] +37710 - Trapdoor - [null, null, null, null, null] +37711 - Rope bridge - [null, null, null, null, null] +37712 - Rope bridge - [null, null, null, null, null] +37713 - Rope bridge - [null, null, null, null, null] +37714 - null - [null, null, null, null, null] +37715 - null - [null, null, null, null, null] +37716 - null - [null, null, null, null, null] +37717 - null - [null, null, null, null, null] +37718 - Wall - [null, null, null, null, Lean against] +37719 - Wall - [null, null, null, null, Lean against] +37720 - Wall - [null, null, null, null, Lean against] +37721 - Wall - [null, null, null, null, Lean against] +37722 - Wall - [null, null, null, null, Lean against] +37723 - Wall - [null, null, null, null, Lean against] +37724 - Stuffed swordfish - [null, null, null, null, null] +37725 - Stuffed swordfish - [null, null, null, null, null] +37726 - Fire - [null, null, null, null, null] +37727 - Fairy ring - [Use, null, null, null, null] +37728 - null - [null, null, null, null, null] +37729 - null - [null, null, null, null, null] +37730 - null - [null, null, null, null, null] +37731 - null - [null, null, null, null, null] +37732 - null - [null, null, null, null, null] +37733 - null - [null, null, null, null, null] +37734 - null - [null, null, null, null, null] +37735 - Obstacle pipe - [Squeeze-through, null, null, null, null] +37736 - null - [null, null, null, null, null] +37737 - Lever - [Pull, null, null, null, null] +37738 - Door - [null, null, null, null, null] +37739 - Gate - [null, null, null, null, null] +37740 - Gate - [null, null, null, null, null] +37741 - Gate - [null, null, null, null, null] +37742 - Gate - [null, null, null, null, null] +37743 - Rubble - [Search, null, null, null, null] +37744 - null - [null, null, null, null, null] +37745 - Trapdoor - [Open, null, null, null, null] +37746 - Ladder - [Climb-down, Close, null, null, null] +37747 - null - [null, null, null, null, null] +37748 - null - [null, null, null, null, null] +37749 - Entrance - [Go-through, null, null, null, null] +37750 - Entrance - [null, null, null, null, null] +37751 - Tree Stump - [null, null, null, null, null] +37752 - Disc - [null, null, null, null, null] +37753 - Disc - [null, null, null, null, null] +37754 - Disc - [null, null, null, null, null] +37755 - Disc - [null, null, null, null, null] +37756 - Disc - [null, null, null, null, null] +37757 - Disc - [null, null, null, null, null] +37758 - Disc - [null, null, null, null, null] +37759 - Disc - [null, null, null, null, null] +37760 - Disc - [null, null, null, null, null] +37761 - Disc - [null, null, null, null, null] +37762 - Disc - [null, null, null, null, null] +37763 - Disc - [null, null, null, null, null] +37764 - Disc - [null, null, null, null, null] +37765 - Disc - [null, null, null, null, null] +37766 - Disc - [null, null, null, null, null] +37767 - Disc - [null, null, null, null, null] +37768 - Disc - [null, null, null, null, null] +37769 - Disc - [null, null, null, null, null] +37770 - Disc - [null, null, null, null, null] +37771 - Disc - [null, null, null, null, null] +37772 - Disc - [null, null, null, null, null] +37773 - Disc - [null, null, null, null, null] +37774 - Disc - [null, null, null, null, null] +37775 - Disc - [null, null, null, null, null] +37776 - Disc - [null, null, null, null, null] +37777 - Disc - [null, null, null, null, null] +37778 - Disc - [null, null, null, null, null] +37779 - Disc - [null, null, null, null, null] +37780 - Disc - [null, null, null, null, null] +37781 - Disc - [null, null, null, null, null] +37782 - Disc - [null, null, null, null, null] +37783 - Disc - [null, null, null, null, null] +37784 - Disc - [null, null, null, null, null] +37785 - Disc - [null, null, null, null, null] +37786 - Disc - [null, null, null, null, null] +37787 - Disc - [null, null, null, null, null] +37788 - Disc - [null, null, null, null, null] +37789 - Disc - [null, null, null, null, null] +37790 - Disc - [null, null, null, null, null] +37791 - Disc - [null, null, null, null, null] +37792 - Disc - [null, null, null, null, null] +37793 - Disc - [null, null, null, null, null] +37794 - Disc - [null, null, null, null, null] +37795 - Disc - [null, null, null, null, null] +37796 - Disc - [null, null, null, null, null] +37797 - Disc - [null, null, null, null, null] +37798 - Disc - [null, null, null, null, null] +37799 - Disc - [null, null, null, null, null] +37800 - Disc - [null, null, null, null, null] +37801 - Disc - [null, null, null, null, null] +37802 - Disc - [null, null, null, null, null] +37803 - Disc - [null, null, null, null, null] +37804 - Disc - [null, null, null, null, null] +37805 - Disc - [null, null, null, null, null] +37806 - Disc - [null, null, null, null, null] +37807 - Barrel - [null, null, null, null, null] +37808 - Barrel - [null, null, null, null, null] +37809 - Crate - [Search, null, null, null, null] +37810 - Crate - [Search, null, null, null, null] +37811 - Crate - [Search, null, null, null, null] +37812 - Sack - [Search, null, null, null, null] +37813 - Stool - [null, null, null, null, null] +37814 - Stool - [null, null, null, null, null] +37815 - Table - [null, null, null, null, null] +37816 - Shelf - [null, null, null, null, null] +37817 - Wardrobe - [null, null, null, null, null] +37818 - Bed - [null, null, null, null, null] +37819 - Statue - [null, null, null, null, null] +37820 - Standing torch - [null, null, null, null, null] +37821 - Cursed magic tree - [Chop down, null, hidden, null, null] +37822 - Tree Stump - [null, null, hidden, null, null] +37823 - Magic tree - [Chop down, null, hidden, null, null] +37824 - Tree Stump - [null, null, hidden, null, null] +37825 - Barrel - [null, null, null, null, null] +37826 - Barrel - [null, null, null, null, null] +37827 - null - [null, null, null, null, null] +37828 - null - [null, null, null, null, null] +37829 - Hollow log - [null, null, null, null, null] +37830 - Hollow log - [Pick, null, null, null, null] +37831 - Hollow log - [null, null, null, null, null] +37832 - null - [null, null, null, null, null] +37833 - null - [null, null, null, null, null] +37834 - Wardrobe - [Open, null, null, null, null] +37835 - Wardrobe - [null, null, null, null, null] +37836 - Wardrobe - [null, null, null, null, null] +37837 - Wardrobe - [null, null, null, null, null] +37838 - null - [null, null, null, null, null] +37839 - null - [null, null, null, null, null] +37840 - null - [null, null, null, null, null] +37841 - null - [null, null, null, null, null] +37842 - Plant - [null, Inspect, null, null, null] +37843 - Plant - [null, Inspect, null, null, null] +37844 - Flower patch - [null, Inspect, null, null, null] +37845 - null - [null, null, null, null, null] +37846 - Flower patch - [null, Inspect, null, Guide, null] +37847 - Flower patch - [null, Inspect, null, Guide, null] +37848 - Flower patch - [null, Inspect, null, Guide, null] +37849 - Flower patch - [null, Inspect, null, Guide, null] +37850 - null - [null, null, null, null, null] +37851 - null - [null, null, null, null, null] +37852 - null - [null, null, null, null, null] +37853 - null - [null, null, null, null, null] +37854 - null - [null, null, null, null, null] +37855 - null - [null, null, null, null, null] +37856 - null - [null, null, null, null, null] +37857 - null - [null, null, null, null, null] +37858 - null - [null, null, null, null, null] +37859 - null - [null, null, null, null, null] +37860 - null - [null, null, null, null, null] +37861 - null - [null, null, null, null, null] +37862 - null - [null, null, null, null, null] +37863 - null - [null, null, null, null, null] +37864 - null - [null, null, null, null, null] +37865 - null - [null, null, null, null, null] +37866 - null - [null, null, null, null, null] +37867 - null - [null, null, null, null, null] +37868 - null - [null, null, null, null, null] +37869 - null - [null, null, null, null, null] +37870 - null - [null, null, null, null, null] +37871 - null - [null, null, null, null, null] +37872 - null - [null, null, null, null, null] +37873 - null - [null, null, null, null, null] +37874 - null - [null, null, null, null, null] +37875 - null - [null, null, null, null, null] +37876 - null - [null, null, null, null, null] +37877 - null - [null, null, null, null, null] +37878 - null - [null, null, null, null, null] +37879 - null - [null, null, null, null, null] +37880 - null - [null, null, null, null, null] +37881 - Stones - [null, null, null, null, null] +37882 - Stones - [null, null, null, null, null] +37883 - Stones - [null, null, null, null, null] +37884 - Stones - [null, null, null, null, null] +37885 - null - [null, null, null, null, null] +37886 - null - [null, null, null, null, null] +37887 - null - [null, null, null, null, null] +37888 - null - [null, null, null, null, null] +37889 - null - [null, null, null, null, null] +37890 - null - [null, null, null, null, null] +37891 - null - [null, null, null, null, null] +37892 - Stones - [null, null, null, null, null] +37893 - Stones - [null, null, null, null, null] +37894 - null - [null, null, null, null, null] +37895 - null - [null, null, null, null, null] +37896 - null - [null, null, null, null, null] +37897 - null - [null, null, null, null, null] +37898 - null - [null, null, null, null, null] +37899 - null - [null, null, null, null, null] +37900 - Ladder - [Climb-up, null, null, null, null] +37901 - Altar - [null, null, null, null, null] +37902 - Altar - [null, null, null, null, null] +37903 - Altar - [null, null, null, null, null] +37904 - Altar - [null, null, null, null, null] +37905 - Altar - [null, null, null, null, null] +37906 - Altar - [null, null, null, null, null] +37907 - Altar - [null, null, null, null, null] +37908 - Altar - [null, null, null, null, null] +37909 - Altar - [null, null, null, null, null] +37910 - Altar - [null, null, null, null, null] +37911 - Altar - [null, null, null, null, null] +37912 - Altar - [null, null, null, null, null] +37913 - null - [null, null, null, null, null] +37914 - Coffin - [Open, null, null, null, null] +37915 - Coffin - [Close, Search, null, null, null] +37916 - null - [null, null, null, null, null] +37917 - null - [null, null, null, null, null] +37918 - null - [null, null, null, null, null] +37919 - null - [null, null, null, null, null] +37920 - null - [null, null, null, null, null] +37921 - null - [null, null, null, null, null] +37922 - null - [null, null, null, null, null] +37923 - null - [null, null, null, null, null] +37924 - Portal - [null, null, null, null, null] +37925 - Portal - [null, null, null, null, null] +37926 - null - [null, null, null, null, null] +37927 - null - [null, null, null, null, null] +37928 - Exit - [Go-through, null, null, null, null] +37929 - Passage - [Go-through, null, null, null, null] +37930 - null - [null, null, null, null, null] +37931 - null - [null, null, null, null, null] +37932 - null - [null, null, null, null, null] +37933 - null - [null, null, null, null, null] +37934 - null - [null, null, null, null, null] +37935 - null - [null, null, null, null, null] +37936 - null - [null, null, null, null, null] +37937 - null - [null, null, null, null, null] +37938 - null - [null, null, null, null, null] +37939 - null - [null, null, null, null, null] +37940 - null - [null, null, null, null, null] +37941 - null - [null, null, null, null, null] +37942 - null - [null, null, null, null, null] +37943 - null - [null, null, null, null, null] +37944 - null - [null, null, null, null, null] +37945 - null - [null, null, null, null, null] +37946 - null - [null, null, null, null, null] +37947 - null - [null, null, null, null, null] +37948 - null - [null, null, null, null, null] +37949 - null - [null, null, null, null, null] +37950 - null - [null, null, null, null, null] +37951 - null - [null, null, null, null, null] +37952 - Roots - [null, null, null, null, null] +37953 - Roots - [null, null, null, null, null] +37954 - Roots - [null, null, null, null, null] +37955 - Roots - [null, null, null, null, null] +37956 - Roots - [null, null, null, null, null] +37957 - Roots - [null, null, null, null, null] +37958 - Roots - [null, null, null, null, null] +37959 - Roots - [Chop, null, hidden, null, null] +37960 - Roots - [null, null, null, null, null] +37961 - Roots - [Chop, null, hidden, null, null] +37962 - Roots - [null, null, null, null, null] +37963 - Roots - [Chop, null, hidden, null, null] +37964 - Puddle - [null, null, null, null, null] +37965 - Puddle - [null, null, null, null, null] +37966 - Puddle - [null, null, null, null, null] +37967 - Hole - [null, null, null, null, null] +37968 - Hole - [null, null, null, null, null] +37969 - Soft soil - [null, null, null, null, null] +37970 - Fire pit - [null, null, null, null, null] +37971 - Gravestone - [null, null, null, null, null] +37972 - null - [null, null, null, null, null] +37973 - Grave marker - [null, null, null, null, null] +37974 - null - [null, null, null, null, null] +37975 - Grave marker - [null, null, null, null, null] +37976 - null - [null, null, null, null, null] +37977 - Grave marker - [null, null, null, null, null] +37978 - null - [null, null, null, null, null] +37979 - Grave marker - [null, null, null, null, null] +37980 - null - [null, null, null, null, null] +37981 - null - [null, null, null, null, null] +37982 - null - [null, null, null, null, null] +37983 - null - [null, null, null, null, null] +37984 - null - [null, null, null, null, null] +37985 - Decayed altar - [Pray, null, null, null, null] +37986 - null - [null, null, null, null, null] +37987 - null - [null, null, null, null, null] +37988 - null - [null, null, null, null, null] +37989 - Invisible Portal - [null, null, null, null, null] +37990 - Chaos altar - [Pray-at, null, null, null, null] +37991 - null - [null, null, null, null, null] +37992 - null - [null, null, null, null, null] +37993 - null - [null, null, null, null, null] +37994 - null - [null, null, null, null, null] +37995 - Door - [Open, null, null, null, null] +37996 - Door - [Close, null, null, null, null] +37997 - Rift - [null, null, null, null, null] +37998 - Rift - [null, null, null, null, null] +37999 - Rift - [null, null, null, null, null] +38000 - Rift - [null, null, null, null, null] +38001 - null - [null, null, null, null, null] +38002 - null - [null, null, null, null, null] +38003 - null - [null, null, null, null, null] +38004 - null - [null, null, null, null, null] +38005 - null - [null, null, null, null, null] +38006 - null - [null, null, null, null, null] +38007 - null - [null, null, null, null, null] +38008 - null - [null, null, null, null, null] +38009 - null - [null, null, null, null, null] +38010 - null - [null, null, null, null, null] +38011 - null - [null, null, null, null, null] +38012 - Staircase - [Climb, Climb-up, Climb-down, null, null] +38013 - Pear seedling - [Inspect, null, null, null, null] +38014 - Mango seedling - [Inspect, null, null, null, null] +38015 - Quince seedling - [Inspect, null, null, null, null] +38016 - Lemon seedling - [Inspect, null, null, null, null] +38017 - Avocado seedling - [Inspect, null, null, null, null] +38018 - Plum seedling - [Inspect, null, null, null, null] +38019 - Fruit tree patch - [Inspect, null, null, null, null] +38020 - Table - [null, null, null, null, null] +38021 - Table - [null, null, null, null, null] +38022 - null - [null, null, null, null, null] +38023 - null - [null, null, null, null, null] +38024 - null - [null, null, null, null, null] +38025 - Food trough - [null, null, null, null, null] +38026 - Beehive - [null, null, null, null, null] +38027 - Rocks - [null, null, null, null, null] +38028 - null - [null, null, null, null, null] +38029 - null - [null, null, null, null, null] +38030 - null - [null, null, null, null, null] +38031 - null - [null, null, null, null, null] +38032 - null - [null, null, null, null, null] +38033 - null - [null, null, null, null, null] +38034 - null - [null, null, null, null, null] +38035 - null - [null, null, null, null, null] +38036 - null - [null, null, null, null, null] +38037 - null - [null, null, null, null, null] +38038 - null - [null, null, null, null, null] +38039 - Reeds - [null, null, null, null, null] +38040 - Reeds - [null, null, null, null, null] +38041 - Reeds - [null, null, null, null, null] +38042 - Reeds - [null, null, null, null, null] +38043 - Fire pit - [null, null, null, null, null] +38044 - null - [null, null, null, null, null] +38045 - null - [null, null, null, null, null] +38046 - null - [null, null, null, null, null] +38047 - Grave - [Read, null, null, null, null] +38048 - Crate - [null, null, null, null, null] +38049 - Bucket - [null, null, null, null, null] +38050 - Barrel - [null, null, null, null, null] +38051 - Avocado tree - [Inspect, null, null, null, null] +38052 - Dead avocado tree - [Inspect, null, null, null, null] +38053 - Lemon tree - [Inspect, null, null, null, null] +38054 - Dead lemon tree - [Inspect, null, null, null, null] +38055 - Mango tree - [Inspect, null, null, null, null] +38056 - Dead mango tree - [Inspect, null, null, null, null] +38057 - Pear tree - [Inspect, null, null, null, null] +38058 - Dead pear tree - [Inspect, null, null, null, null] +38059 - Plum tree - [Inspect, null, null, null, null] +38060 - Dead plum tree - [Inspect, null, null, null, null] +38061 - Quince tree - [Inspect, null, null, null, null] +38062 - Dead quince tree - [Inspect, null, null, null, null] +38063 - null - [null, null, null, null, null] +38064 - null - [null, null, null, null, null] +38065 - null - [null, null, null, null, null] +38066 - null - [null, null, null, null, null] +38067 - null - [null, null, null, null, null] +38068 - null - [null, null, null, null, null] +38069 - null - [null, null, null, null, null] +38070 - null - [null, null, null, null, null] +38071 - null - [null, null, null, null, null] +38072 - null - [null, null, null, null, null] +38073 - null - [null, null, null, null, null] +38074 - null - [null, null, null, null, null] +38075 - null - [null, null, null, null, null] +38076 - null - [null, null, null, null, null] +38077 - null - [null, null, null, null, null] +38078 - null - [null, null, null, null, null] +38079 - null - [null, null, null, null, null] +38080 - null - [null, null, null, null, null] +38081 - null - [null, null, null, null, null] +38082 - null - [null, null, null, null, null] +38083 - null - [null, null, null, null, null] +38084 - null - [null, null, null, null, null] +38085 - null - [null, null, null, null, null] +38086 - null - [null, null, null, null, null] +38087 - null - [null, null, null, null, null] +38088 - null - [null, null, null, null, null] +38089 - null - [null, null, null, null, null] +38090 - null - [null, null, null, null, null] +38091 - null - [null, null, null, null, null] +38092 - null - [null, null, null, null, null] +38093 - null - [null, null, null, null, null] +38094 - null - [null, null, null, null, null] +38095 - null - [null, null, null, null, null] +38096 - null - [null, null, null, null, null] +38097 - null - [null, null, null, null, null] +38098 - null - [null, null, null, null, null] +38099 - null - [null, null, null, null, null] +38100 - Bedside table - [Search, null, null, null, null] +38101 - Side table - [Search, null, null, null, null] +38102 - Table - [null, null, null, null, null] +38103 - null - [null, null, null, null, null] +38104 - null - [null, null, null, null, null] +38105 - Shelves - [Search, null, null, null, null] +38106 - Shelves - [Search, null, null, null, null] +38107 - Basket - [null, null, null, null, null] +38108 - Bed - [null, null, null, null, null] +38109 - Bed - [null, null, null, null, null] +38110 - Pot - [null, null, null, null, null] +38111 - Pots - [null, null, null, null, null] +38112 - Pots - [null, null, null, null, null] +38113 - Pot - [null, null, null, null, null] +38114 - Pots - [Collect, null, null, null, null] +38115 - null - [null, null, null, null, null] +38116 - null - [null, null, null, null, null] +38117 - Shelf - [null, null, null, null, null] +38118 - Shelf - [null, null, null, null, null] +38119 - Bed - [null, null, null, null, null] +38120 - Bed - [null, null, null, null, null] +38121 - Basket - [null, null, null, null, null] +38122 - Basket - [null, null, null, null, null] +38123 - Door - [Close, null, null, null, null] +38124 - Door - [Open, null, null, null, null] +38125 - Cooking pot - [null, null, null, null, null] +38126 - Soil mound - [Inspect, null, null, null, null] +38127 - null - [null, null, null, null, null] +38128 - null - [null, null, null, null, null] +38129 - null - [null, null, null, null, null] +38130 - null - [null, null, null, null, null] +38131 - null - [null, null, null, null, null] +38132 - null - [null, null, null, null, null] +38133 - null - [null, null, null, null, null] +38134 - null - [null, null, null, null, null] +38135 - null - [null, null, null, null, null] +38136 - null - [null, null, null, null, null] +38137 - null - [null, null, null, null, null] +38138 - null - [null, null, null, null, null] +38139 - null - [null, null, null, null, null] +38140 - null - [null, null, null, null, null] +38141 - Door - [Open, null, null, null, null] +38142 - Door - [Close, null, null, null, null] +38143 - null - [null, null, null, null, null] +38144 - Barrier - [Pass, null, null, null, null] +38145 - Barrier - [Pass, null, null, null, null] +38146 - Barrier. - [null, null, null, null, null] +38147 - Barrier. - [null, null, null, null, null] +38148 - Barrier. - [null, null, null, null, null] +38149 - Barrier. - [null, null, null, null, null] +38150 - Portal - [null, null, null, null, null] +38151 - null - [null, null, null, null, null] +38152 - null - [null, null, null, null, null] +38153 - null - [null, null, null, null, null] +38154 - null - [null, null, null, null, null] +38155 - null - [null, null, null, null, null] +38156 - null - [null, null, null, null, null] +38157 - null - [null, null, null, null, null] +38158 - null - [null, null, null, null, null] +38159 - null - [null, null, null, null, null] +38160 - null - [null, null, null, null, null] +38161 - null - [null, null, null, null, null] +38162 - null - [null, null, null, null, null] +38163 - null - [null, null, null, null, null] +38164 - null - [null, null, null, null, null] +38165 - Campfire - [null, null, null, null, null] +38166 - Campfire - [null, null, null, null, null] +38167 - null - [null, null, null, null, null] +38168 - null - [null, null, null, null, null] +38169 - null - [null, null, null, null, null] +38170 - null - [null, null, null, null, null] +38171 - null - [null, null, null, null, null] +38172 - null - [null, null, null, null, null] +38173 - Display case - [Study, null, null, null, null] +38174 - null - [null, null, null, null, null] +38175 - null - [null, null, null, null, null] +38176 - null - [null, null, null, null, null] +38177 - null - [null, null, null, null, null] +38178 - null - [null, null, null, null, null] +38179 - null - [null, null, null, null, null] +38180 - null - [null, null, null, null, null] +38181 - null - [null, null, null, null, null] +38182 - Dead tree - [null, null, null, null, null] +38183 - Rubble - [null, null, null, null, null] +38184 - Rubble - [null, null, null, null, null] +38185 - Rubble - [null, null, null, null, null] +38186 - Rubble - [null, null, null, null, null] +38187 - null - [null, null, null, null, null] +38188 - null - [null, null, null, null, null] +38189 - null - [null, null, null, null, null] +38190 - null - [null, null, null, null, null] +38191 - null - [null, null, null, null, null] +38192 - null - [null, null, null, null, null] +38193 - null - [null, null, null, null, null] +38194 - null - [null, null, null, null, null] +38195 - null - [null, null, null, null, null] +38196 - null - [null, null, null, null, null] +38197 - null - [null, null, null, null, null] +38198 - null - [null, null, null, null, null] +38199 - null - [null, null, null, null, null] +38200 - null - [null, null, null, null, null] +38201 - null - [null, null, null, null, null] +38202 - null - [null, null, null, null, null] +38203 - null - [null, null, null, null, null] +38204 - null - [null, null, null, null, null] +38205 - null - [null, null, null, null, null] +38206 - null - [null, null, null, null, null] +38207 - null - [null, null, null, null, null] +38208 - null - [null, null, null, null, null] +38209 - null - [null, null, null, null, null] +38210 - null - [null, null, null, null, null] +38211 - null - [null, null, null, null, null] +38212 - null - [null, null, null, null, null] +38213 - null - [null, null, null, null, null] +38214 - null - [null, null, null, null, null] +38215 - null - [null, null, null, null, null] +38216 - null - [null, null, null, null, null] +38217 - null - [null, null, null, null, null] +38218 - null - [null, null, null, null, null] +38219 - null - [null, null, null, null, null] +38220 - null - [null, null, null, null, null] +38221 - Ladder - [Climb-up, null, null, null, null] +38222 - Ladder - [Climb-down, null, null, null, null] +38223 - null - [null, null, null, null, null] +38224 - null - [null, null, null, null, null] +38225 - null - [null, null, null, null, null] +38226 - null - [null, null, null, null, null] +38227 - null - [null, null, null, null, null] +38228 - null - [null, null, null, null, null] +38229 - null - [null, null, null, null, null] +38230 - null - [null, null, null, null, null] +38231 - null - [null, null, null, null, null] +38232 - null - [null, null, null, null, null] +38233 - null - [null, null, null, null, null] +38234 - null - [null, null, null, null, null] +38235 - null - [null, null, null, null, null] +38236 - null - [null, null, null, null, null] +38237 - null - [null, null, null, null, null] +38238 - null - [null, null, null, null, null] +38239 - null - [null, null, null, null, null] +38240 - null - [null, null, null, null, null] +38241 - null - [null, null, null, null, null] +38242 - null - [null, null, null, null, null] +38243 - null - [null, null, null, null, null] +38244 - null - [null, null, null, null, null] +38245 - null - [null, null, null, null, null] +38246 - null - [null, null, null, null, null] +38247 - null - [null, null, null, null, null] +38248 - null - [null, null, null, null, null] +38249 - null - [null, null, null, null, null] +38250 - null - [null, null, null, null, null] +38251 - null - [null, null, null, null, null] +38252 - null - [null, null, null, null, null] +38253 - null - [null, null, null, null, null] +38254 - null - [null, null, null, null, null] +38255 - null - [null, null, null, null, null] +38256 - Column - [null, null, null, null, null] +38257 - Column - [null, null, null, null, null] +38258 - Column - [null, null, null, null, null] +38259 - null - [null, null, null, null, null] +38260 - null - [null, null, null, null, null] +38261 - null - [null, null, null, null, null] +38262 - null - [null, null, null, null, null] +38263 - null - [null, null, null, null, null] +38264 - null - [null, null, null, null, null] +38265 - null - [null, null, null, null, null] +38266 - Beacon - [null, null, null, null, null] +38267 - Flames - [null, null, null, null, null] +38268 - null - [null, null, null, null, null] +38269 - null - [null, null, null, null, null] +38270 - null - [null, null, null, null, null] +38271 - null - [null, null, null, null, null] +38272 - null - [null, null, null, null, null] +38273 - null - [null, null, null, null, null] +38274 - null - [null, null, null, null, null] +38275 - null - [null, null, null, null, null] +38276 - null - [null, null, null, null, null] +38277 - null - [null, null, null, null, null] +38278 - null - [null, null, null, null, null] +38279 - Portal - [Enter, null, null, null, null] +38280 - Runes - [null, null, null, null, null] +38281 - null - [null, null, null, null, null] +38282 - null - [null, null, null, null, null] +38283 - null - [null, null, null, null, null] +38284 - null - [null, null, null, null, null] +38285 - null - [null, null, null, null, null] +38286 - null - [null, null, null, null, null] +38287 - null - [null, null, null, null, null] +38288 - null - [null, null, null, null, null] +38289 - null - [null, null, null, null, null] +38290 - null - [null, null, null, null, null] +38291 - null - [null, null, null, null, null] +38292 - null - [null, null, null, null, null] +38293 - null - [null, null, null, null, null] +38294 - null - [null, null, null, null, null] +38295 - null - [null, null, null, null, null] +38296 - null - [null, null, null, null, null] +38297 - null - [null, null, null, null, null] +38298 - null - [null, null, null, null, null] +38299 - null - [null, null, null, null, null] +38300 - null - [null, null, null, null, null] +38301 - null - [null, null, null, null, null] +38302 - null - [null, null, null, null, null] +38303 - null - [null, null, null, null, null] +38304 - null - [null, null, null, null, null] +38305 - null - [null, null, null, null, null] +38306 - null - [null, null, null, null, null] +38307 - null - [null, null, null, null, null] +38308 - null - [null, null, null, null, null] +38309 - null - [null, null, null, null, null] +38310 - null - [null, null, null, null, null] +38311 - null - [null, null, null, null, null] +38312 - null - [null, null, null, null, null] +38313 - null - [null, null, null, null, null] +38314 - null - [null, null, null, null, null] +38315 - Map table - [Study, null, null, null, null] +38316 - Table - [null, null, null, null, null] +38317 - Table - [null, null, null, null, null] +38318 - Table - [null, null, null, null, null] +38319 - Table - [null, null, null, null, null] +38320 - Table - [null, null, null, null, null] +38321 - Workbench - [null, null, null, null, null] +38322 - Bookcase - [Search, null, null, null, null] +38323 - Bookcase - [Search, null, null, null, null] +38324 - Bookcase - [Search, null, null, null, null] +38325 - Tube - [null, null, null, null, null] +38326 - Tube - [null, null, null, null, null] +38327 - Containment unit - [Activate, null, null, null, null] +38328 - Storage unit - [null, null, null, null, null] +38329 - Runestone accelerator - [Activate, null, null, null, null] +38330 - Gyroscope - [Activate, null, null, null, null] +38331 - Glass spheres - [Activate, null, null, null, null] +38332 - Trapdoor - [null, null, null, null, null] +38333 - null - [null, null, null, null, null] +38334 - Map - [Study, null, null, null, null] +38335 - Map - [Study, null, null, null, null] +38336 - null - [null, null, null, null, null] +38337 - null - [null, null, null, null, null] +38338 - null - [null, null, null, null, null] +38339 - null - [null, null, null, null, null] +38340 - null - [null, null, null, null, null] +38341 - null - [null, null, null, null, null] +38342 - null - [null, null, null, null, null] +38343 - null - [null, null, null, null, null] +38344 - null - [null, null, null, null, null] +38345 - null - [null, null, null, null, null] +38346 - null - [null, null, null, null, null] +38347 - null - [null, null, null, null, null] +38348 - null - [null, null, null, null, null] +38349 - null - [null, null, null, null, null] +38350 - null - [null, null, null, null, null] +38351 - null - [null, null, null, null, null] +38352 - Pillar - [null, null, null, null, null] +38353 - Pillar - [null, null, null, null, null] +38354 - Pillar - [null, null, null, null, null] +38355 - Pillar - [null, null, null, null, null] +38356 - Pillar - [null, null, null, null, null] +38357 - Pillar - [null, null, null, null, null] +38358 - Pillar - [null, null, null, null, null] +38359 - Pillar - [null, null, null, null, null] +38360 - Pillar - [null, null, null, null, null] +38361 - Pillar - [null, null, null, null, null] +38362 - Pillar - [null, null, null, null, null] +38363 - Pillar - [null, null, null, null, null] +38364 - null - [null, null, null, null, null] +38365 - null - [null, null, null, null, null] +38366 - null - [null, null, null, null, null] +38367 - null - [null, null, null, null, null] +38368 - null - [null, null, null, null, null] +38369 - null - [null, null, null, null, null] +38370 - null - [null, null, null, null, null] +38371 - null - [null, null, null, null, null] +38372 - null - [null, null, null, null, null] +38373 - null - [null, null, null, null, null] +38374 - null - [null, null, null, null, null] +38375 - null - [null, null, null, null, null] +38376 - null - [null, null, null, null, null] +38377 - Barrier - [Pass-through, Destroy, null, null, null] +38378 - Barrier - [Pass-through, Destroy, null, null, null] +38379 - Tree - [null, null, null, null, null] +38380 - Tree - [null, null, null, null, null] +38381 - Oak - [null, null, null, null, null] +38382 - Dead tree - [null, null, null, null, null] +38383 - Dead tree - [null, null, null, null, null] +38384 - null - [null, null, null, null, null] +38385 - null - [null, null, null, null, null] +38386 - null - [null, null, null, null, null] +38387 - null - [null, null, null, null, null] +38388 - null - [null, null, null, null, null] +38389 - null - [null, null, null, null, null] +38390 - null - [null, null, null, null, null] +38391 - null - [null, null, null, null, null] +38392 - null - [null, null, null, null, null] +38393 - null - [null, null, null, null, null] +38394 - null - [null, null, null, null, null] +38395 - null - [null, null, null, null, null] +38396 - null - [null, null, null, null, null] +38397 - null - [null, null, null, null, null] +38398 - null - [null, null, null, null, null] +38399 - null - [null, null, null, null, null] +38400 - null - [null, null, null, null, null] +38401 - null - [null, null, null, null, null] +38402 - null - [null, null, null, null, null] +38403 - null - [null, null, null, null, null] +38404 - null - [null, null, null, null, null] +38405 - null - [null, null, null, null, null] +38406 - null - [null, null, null, null, null] +38407 - null - [null, null, null, null, null] +38408 - null - [null, null, null, null, null] +38409 - null - [null, null, null, null, null] +38410 - null - [null, null, null, null, null] +38411 - null - [null, null, null, null, null] +38412 - null - [null, null, null, null, null] +38413 - null - [null, null, null, null, null] +38414 - null - [null, null, null, null, null] +38415 - null - [null, null, null, null, null] +38416 - null - [null, null, null, null, null] +38417 - null - [null, null, null, null, null] +38418 - null - [null, null, null, null, null] +38419 - null - [null, null, null, null, null] +38420 - Pillar - [null, null, null, null, null] +38421 - Map - [Study, null, null, null, null] +38422 - Map - [Study, null, null, null, null] +38423 - null - [null, null, null, null, null] +38424 - Painting - [null, null, null, null, null] +38425 - null - [null, null, null, null, null] +38426 - null - [null, null, null, null, null] diff --git a/dumps/530/530_interface_names.txt b/dumps/530/530_interface_names.txt new file mode 100644 index 0000000..8013a26 --- /dev/null +++ b/dumps/530/530_interface_names.txt @@ -0,0 +1,760 @@ +0 100guide_eggs_overlay +1 100guide_flour_overlay +2 100guide_inv_flour +3 100guide_milk_overlay +4 tog_water_bowl +5 agilityarena_overlay +6 agilityarena_trade +7 ahoy_blackout +8 ahoy_islandmap +9 ahoy_runedraw +10 ahoy_windspeed +11 bank_deposit_box +13 bankpin_main +14 bankpin_settings +15 banner_padlock_keys +16 banner_anti_virus +21 banner_scamming +22 banner_security +23 banner_xmas +24 barrows_overlay +25 barrows_puzzle +26 fancy_book +27 fancy_book_2 +28 blast_furnace_bar_stock +29 blast_furnace_plan_scroll +30 blast_furnace_temp_gauge +31 boardgames_challenge +32 boardgames_draughts +33 boardgames_draughts_options +34 boardgames_draughts_overlay +35 boardgames_draughts_view +36 boardgames_runelink +37 boardgames_runelink_options +38 boardgames_runelink_overlay +39 boardgames_runelink_view +40 boardgames_runesquares +41 boardgames_runesquares_options +42 boardgames_runesquares_overlay +43 boardgames_runesquares_view +44 boardgames_runeversi +45 boardgames_runeversi_options +46 boardgames_runeversi_overlay +47 boardgames_runeversi_view +48 bob_locator_amulet +49 fancy_book_3 +50 brooch +51 burgh_map +52 canoe +53 canoe_stations_map +54 castlewars_catapult +55 castlewars_score +56 castlewars_shopside +57 castlewars_status_overlay +58 castlewars_status_overlay_saradomin +59 castlewars_status_overlay_zamorak +60 castlewars_trade +61 cat_naming +62 cave_goblin_markers +63 champions_scroll +64 chat1 +65 chat2 +66 chat3 +67 chat4 +68 chat_np1 +69 chat_np2 +70 chat_np3 +71 chat_np4 +72 Cheese churning? +73 Cheese and butter churning? +74 Churn cream, churn butter, churn cheese +75 borderless-attack-styles +76 same but hammers +77 same but bows +78 same but claws +79 bows again +80 aim and fire or kick +81 slash chop etc +82 2h +83 pickaxe +84 halberd +85 staff with no cast options +86 reap chop jab +87 spear +88 mace +89 stab slash lunge block +90 staff with autocast +91 darts or knives +93 whip +94 confirm_destroy +95 sailing_transport_world_map +96 darkness_dark +97 darkness_light +98 darkness_medium +99 death_dice +100 deep_blue +101 scroll with blood +102 items kept on death +103 pattern_next +104 star charts +105 stockmarket +106 GE tutorial +107 stockside +108 GE tutorial confirm offer +109 stockcollect +110 ge tutorial buy offer +111 dwarf_rock_book +112 dwarf_rock_cannon +113 dwarf_rock_schematics +114 dwarf_rock_schematics_control +115 fade to black +116 scroll with title +117 enakh_film +118 enakh_smoke_overlay +119 fade to black v2 +120 fade_to_black +121 fade_to_light_blue +122 fade_to_white +123 fairy_certificate +124 symptoms list fairy queen +125 farming_tools +126 farming_tools_side +127 favour_keyring +128 junction map +129 junction map 2 +130 junction map 3 +131 doubleobjbox +132 garden_list +133 garden_quiz +134 stat advancement interface +135 aide_compass +136 "Both" +137 chatdefault +138 glidermap +139 gnomeball +140 Select an Option +141 coffin with grave +142 horror_metaldoor +143 grave digger item +144 hauntedmine_controls +145 RFD miniquest list +146 spinning black hole +147 golden puzzle +148 Select an option at the top +149 inventory +150 keldagrim_map +151 keldagrim_story1 +152 keldagrim_titles +153 aide_death +154 leather_crafting +155 legends_mirror +156 scroll_with_title +157 quickchat_tutorial +158 spining black hole part 2 +159 hand builder? +160 rocko_kittens +161 smki_assignment +162 black hole but it fades this time +163 smki_learn +164 smki_buy +165 smki_smoke_overlay +166 rocko_cannonball +167 rocko_underwater +168 rocko_seagull +169 puro puro interface +170 fade_from_black +171 fade black-to-white +172 coin slot? +173 chatlarge +174 wom_scroll +175 heat_overlay +176 white box in chat box +177 fade_from_white +178 light2 +179 light_blue +180 lightning_flash +181 rotate mirror +182 logout +183 history of the goblin race +184 is this a... +185 macro_combilock +186 macro_evil_bob +187 music_v3 +188 macro_mime_emotes +189 lockpicking? +190 shape 1 shape 2 shape 3 +191 macro_quizshow +192 magic +193 magic_zaros +194 mta points +195 enchantment pizazz poitns +196 magictraining_grave +197 magictraining_shop +198 magictraining_tele +199 hardresser beard +200 Yrsa's Shoe Store confirm (500 gold) +201 Thessalia's legs +202 thesallia's torso +203 hardresser female +204 hairdresser male +205 skin color & gender +206 thesallia's legs again +207thesallia's torso again +208 blank black screen +209 mazetimer +210 message1 +211 message2 +212 message3 +213 message4 +214 message5 +215 message_np1 +216 message_np2 +217 message_np3 +218 message_np4 +219 message_np5 +220 messagescroll +221 messagescroll2 +222 blank scroll +223 peng_emote +224 misc_shipjourney +225 mm_message +226 mole_mud +227 mourning_deathalter_list +228 multi2 +229 multi2_chat +230 multi3 +231 multi3_chat +232 multi4 +233 multi4_chat +234 multi5 +235 multi5_chat +236 multivar2 +237 multivar4 +238 multivar5 +239 engineer claus mousetrap +240 joystick with button +241 npcchat1 +242 npcchat2 +243 npcchat3 +244 npcchat4 +245 npcchat_np1 +246 npcchat_np2 +247 npcchat_np3 +248 npcchat_np4 +249 surok_letter1 +250 surok_letter2 +251 beacon ring instructions -zaff +252 olaf2_lock_gate +253 olaf2_skull_puzzle +254 olaf2_treasuremap +255 blank tattered scroll +256 team list +257 white flash and fade +258 train passing camera +259 area_task +260 dream_armour +261 options +262 attach/detach pipe +263 pinball_interface +264 paint_cannon +265 clanwars_overlay +266 sing --- +267 pest_rewards +268 glowing box +269 buttons cogs pinion counter 20 +270 newcomer map? +271 prayer +272 priestperil_gravemonument +273 prisonpete +274 questjournal_v2 +275 questjournal_scroll +276 blank +277 quest comletion scroll +278 ranging guild ticket exchange +279 cat fight +280 do you really want to bet x? +281 cat hp meters +282 ratcatcher_flute +283 ratcatcher_flute_music +284 ratcatcher_overlay +285 rd_combolock +286 regicide_still +287 grid on table? +288 rogue trader rune sudoku +289 another rune thing with open casket +290 roguesden_dials +291 roguesden_gear_select +292 roguesden_gears +293 roguesden_puzzle +294 rum deal bob yarn +295 rum_deal_title +296 sandstorm +297 sandwich lady +298 seer_combolock +299 ship travel +300 smithing_new +301 xp assist system +302 scroll with gold badge +303 what would you like to make +304 same +305 same +306 same +307 skill_cookmany +308 lotr_scroll +309 skill_multi1 +310 slayer_staff_spells +311 smelting +312 goblinch +313 smokeoverlay +314 blank chatbox +315 soulbane_angerbar +316 soulbane_cut +317 soulbane_darkness +318 soulbane_scare +319 staff_spells +320 stats +321 swamp_boatjourney +322 swamp_boatjourney_back +324 tanner +325 target +326 teleport_other +327 cws_warning_11 +328 temple_screen +329 templetrek_map +330 safe with lock +331 combo for lock note +332 staff enchanting +333 black screen +334 tradeconfirm +335 trademain +336 tradeside +337 tral_map001 +338 trail_map002 +339 tral_map003 +340 trail_map004 +341 trail_map005 +342 trail_map006 +343 trail_map007 +344 trail_map008 +345 trail_cluelong +346 trail_map01 +347 trail_map02 +348 trail_map03 +349 trail_map04 +350 trail_map05 +351 trail_map06 +352 trail_map07 +353 trail_map08 +354 trail_map09 +355 trail_map10 +356 trail_map11 +357 trail_map12 +358 trail_map13 +359 trail_map14 +360 trail_map15 +361 trail_map16 +362 trail_map17 +363 trail_puzzle +364 trail_reward +365 trail_sextant +366 trawler_overlay +367 trawler_reward +368 trawler_start +369 combination lock door +370 snow +371 tutorial_progress +372 tutorial_text +373 tzhaar_fightpit +374 fight pits spectator +375 unmorph +376 something with water and coins +377 Tai Bwo Bwannai favor +378 welcome_screen +379 werewolf_goal +380 welcome_final_tex +381 wilderness_overlay +382 wilderness_warning +383 pick a colour +384 womscroll +385 cracked screen +386 wom_telescope +387 wornitems +388 ancients +389 objdialog +390 show riddle with furniture +391 kingdoms of misc +392 resources collected misc +393 poh_hangman +394 furniture creation menu +395 green flash in chatbox +396 furniture creation menu 2 +397 furniture creation menu fancy +398 poh_house_options +399 home loading screen +400 poh_magic_tablets +401 poh_ranging +402 room build screen +403 poh_sawmill +404 poh_scrying_pool +405 banner_poh +406 pest_mace +407 pest_lander_overlay +408 pest_status_overlay +409 mcannon_interface +410 warguild_defence +411 warguild_defence_mini +412 warguild_dummy +413 brew_telescope_overlay +414 brew_game_over +415 brew_overlay +416 brew_worktable +417 brew_tools +418 castle wars players waiting +419 accessory combiner +420 bee house +421 tutorial_text2 +422 dark and pulsating red +423 fairy2_certificate_broken +424 fairy2_message +425 fair_wall_plaque +426 falling snow? +427 scroll_godfather +428 ntk_overlay +429 Choose a character??? +430 magic_lunar +431 ship circling pirate cove +432 xbows_enchant_bolt +433 xbows_pouch +434 gnome battas +435 gnome bowls +436 gnome cocktails +437 gnome crunchies +438 crafting_silver_casting +439 banners moving on map and colliding +440 certificate of qualification earth sciences +441 earth sciences 2 +442 coin slot +443 multicolor box stack +444 earch sciences 3 +445 openurl +446 crafting_gold +447 banner_chatheads +448 brain_water_overlay +449 nothing +450 light coming in from left side of screen +451 multivar3 +452 myq3_statue_painting +453 myq3_blackout +454 myq3_boat_map +455 scroll with tower on it +456 scroll with towers 2nd half +457 more towers +458 select an option +459 crafting_spinning +460 green overlay with X +461 seaslug_boat_travel +462 idk control panel of some kidn piece 1 piece 2 piece 3 +463 kings_letter_v2 +464 emotes +465 ooglog ogress opens health spa +466 switch diagram +467 menu with big buttons +468 diango item return +469 zep_balloon_map +470 zep_interface +471 zep_interface_side +472 hot air balloon diagram +473 chinchompa attack options +474 salamander attack options +475 chins again +476 salamanders again +477 custom fur clothingclothin +478 imp release negotiation form +479 weird tubes bro +480 anma_rgb +481 thicc snow +482 less thicc snow +483 back to thicc snow +484 barbassault_horn +485 barbassault_over_att +486 barbassault_over_col +487 barbassault_over_def +488 barbassault_over_heal +489 players in room attackers defenders etc +490 barbassault_playerstat +491 barbassault_reward_shop +492 barb assault role accept +493 barb assault role select +494 barbassault_timer_overlay +495 barbassault_turret +496 barbassault_tutorial +497 barbassault_wavecomplete +498 contact_scroll_blood +499 skill_guide_v2 +500 medallion with a $ on it +501 box with cannonball ramrod etc +502 box with rope hammer nails plank +503 clockwork mechanism, chapter 1.0 +504 peeking through planks +505 map of rellekka and others +506 jester controls +507 poh_hangman_german +508 tol_homonculus_overlay +509 tol_cage_puzzle +510 tol_pressure_machine +511 tol_pipe_machine +512 inventory_ranging +513 inventory_wear +514 brain_cat_overlay +515 brain_gas_overlay +516 black +517 turn off black +518 old follower inv? +519 objbox +521 dream_cyrisus +522 dream_monster_stat +523 dream_player_stats +524 dream_title +525 half a scroll +526 the full scroll +527 vm_museum_map +528 vm_digsite +529 other half of scroll +530 whiteb ook +531 VTAM +532 vm_kudos +533 display number 03 +534 vm_timeline +535 piano +536 shrink-me-quick recipe +537 piano instructions +538 grim_tasklist +539 noexit +540 impling exchange +541 flash to white +542 crafting_glass +543 dragon_slayer_qip_clouds +544 dragon_slayer_qip_cr_journey +545 dragon_slayer_qip_elvarg +546 dragon_slayer_qip_elvarg_fly +547 dragon_slayer_qip_map +548 toplevel +549 toplevel_full +550 friends2 +551 ignore2 +552 telescope +553 snapshot_main +554 select an option +555 nothing +556 nothing +557 multi2_mes +558 skill_multi6 +559 pattern_cards +560 cws_warning_9 +561 cws_warning_21 +562 cws_warning_2 +563 cws_warning_5 +564 cws_warning_23 +565 cws_warning_10 +566 cws_warning_6 +567 cws_warning_14 +568 cws_warning_3 +569 cws_warning_16 +570 cws_warning_17 +571 cws_warning_19 +572 cws_warning_13 +573 cws_warning_12 +574 cws_warning_1 +576 cws_warning_8 +577 cws_warning_18 +578 cws_warning_15 +579 cws_warning_4 +580 cws_warning_20 +581 cws_warning_24 +582 skill_multi1_small +583 cws_doomsayer +584 kr_king_statue +585 kr_pyramid_escape +588 kr_picklock +589 clanjoin +590 clansetup +591 Thessalias Makeovers +592 Hairdressers salon +593 Reinalds Smithing Emporium +594 Thessalias Makeovers +595 Reinalds Smithing Emporium +596 Hairdressers salon +597 godwars kill count +598 godwars kill count +599 godwars kill count +600 cws_warning_25 +601 godwars_overlay +602 nothing +603 pulsating ball in hand +604 map with banners +605 peer into cabinet +606 hatching ball +607 putting up posters +608 spinning spirit tree +609 taking down left poster +610 slide to left +611 show posters +612 nothing +613 hand with slots +614 posters with background +615 zoom in on gnome king +616 map with banners +617 bolrie's diary +618 left poster missing +619 pay bank charge with... +620 shop_template +621 shop_template_side +622 banner_group +623 banner_group_assist +624 fairy ring power relay +625 select your goblin +626 duel stake windows +627 cws_warning_26 +628 duel2_side +629 tournament value +630 fucking slot machine hand +631 stacke windows +632 duel2_scoreboard +633 you are victorious +634 victorious but with money +635 nothing +636 tournament rules +637 duel confirmation +638 duel2_challengeoverlay +639 more duel windows +640 duel2_select_type +641 tournament overlay +642 logs item costs +643 exchange_history +644 exchange_sets_side +645 exchange_itemsets +646 exchange_sand_timer +647 falador party chest +648 no tabs +649 clanwars_viewing_orb +650 cws_warning_30 +651 bork i think? +652 gravestone_shop +653 bounty_overlay +654 bounty hunters leaderboard +655 rogues leaderboard +656 bounty_overlay_waiting +657 bounty_warning +658 snowman hat +659 snowglobe lumbridge +660 white circle +661 runes must be in sets of three +662 lore_stats_side +663 lore_cats_side +664 bash focus summon +665 lore_bank_side +666 summoning creation screen +667 equip_screen2 +668 pick a puppy +669 pouch creation +670 inventory_wear2 +671 lore_bank +672 pouch creation again +673 scroll creation again +674 tutorial2_mesbox +675 mould selection +676 cws_warning_27 +677 cws_warning_28 +678 cws_warning_29 +679 banner_summoning +680 triangle at the bottom of screen +681 catapult builder +682 fire catapult +683 catapult viewer control panel +684 rabbit_tutorial +685 Vinesweeper instructions +686 rabbit_shop +687 vinesweeper_tutorial +688 vinesweeper_tutorial_2 +689 rabbit_overlay +690 vinesweeper_tutorial_3 +691 things crawling out of the ground +692 actually bork +693 congrats you have slain bork +694 player safety test +695 naught gublinchette +696 p safety 2 +697 p safety 3 +698 gublinch again +699 p safety 4 +700 report abuse +701 gublinc again again again again +702 more gublinc +703 gublinccc +704 p safety 6 +705 p safety 7 +706 fuck this +715 banner_easter08 +722 summoning_side +723 carpet_info +724 carpet_runesquares +725 carpet_runelink +726 carpet_runeversi +727 carpet_draughts +728 carpet_main +729 carpet_ticket +742 graphics_options +743 sound_options +744 loginscreen +745 statusicons +746 toplevel_fullscreen +747 topstat_lore +748 topstat_hitpoints +749 topstat_prayer +750 topstat_run +751 filterbuttons +752 chattop +754 pmchat +755 worldmap +756 boardgames_options +757 npcchatlarge +758 canoe_travel +760 tutorial2_objbox +762 bank_v2_main +763 bank_v2_side +765 tutorial2_switch_task +766 tutorial2_death +767 bank_v2_help +769 tutorial2_text +778 rcguild_side +779 rcguild_rewards +780 rcguild_map +781 rcguild_overlay +783 crcs_tightrope +784 crcs_side +785 crcs_rewards +786 crcs_equipment +788 crcs_scoreboard +790 clanwars_end +791 clanwars_setup +792 clanwars_setup_side +800 banner_halloween +801 quickchat_locked +802 sc_tutorial_overlay +803 sc_scores_border +805 sc_item_transfer +806 sc_remaining_clay +810 sc_scores +811 sc_reward_shop +813 sc_processing +814 luc2_chapter2 +816 luc2_telescope_view +822 luc2_chapter3 +826 luc2_chapter1 +827 luc2_lucien_projectiles +828 journal with map? +829 Goblin language further access prohibited +830 drawings on ice +831 drawings on ice again +832 again +833 again ALL SEEM TO BE FOR BARB ASSAULT diff --git a/dumps/530/530_npcs_after_498 b/dumps/530/530_npcs_after_498 new file mode 100644 index 0000000..00011b4 --- /dev/null +++ b/dumps/530/530_npcs_after_498 @@ -0,0 +1,269 @@ +7774 Skeleton +7775 Skeleton +7776 Skeleton +7777 Skeleton +7778 Skeleton +7779 null +7780 Sumona +7781 Jesmona +7782 Catolax +7783 null +7784 null +7785 Ali Cat +7786 Mighty banshee +7787 Cave crawler +7788 Skeleton +7789 Zombie +7790 Zombie +7791 Zombie +7792 Zombie +7793 Banshee mistress +7794 Banshee mistress +7795 Insectoid assassin +7796 Insectoid assassin +7797 Kurask overlord +7798 Monstrous cave crawler +7799 Basilisk boss +7800 Mightiest turoth +7801 Aberrant spectre +7802 Aberrant spectre +7803 Aberrant spectre +7804 Aberrant spectre +7805 Kurask minion +7806 Mummy warrior +7807 Mummy warrior +7808 Mummy warrior +7809 Cat +7810 Banshee +7811 Kurask +7812 Cave crawler +7813 Basilisk +7814 Turoth +7815 Skeleton +7816 Master +7817 Zombie +7818 Zombie +7819 Zombie +7820 Zombie +7821 A wanderer. +7822 A wanderer. +7823 Wall beast +7824 Osman +7825 50 Ships Mufassah +7826 Karamthulu +7827 Karamthulu +7828 Giant lobster +7829 Giant crab +7830 Customs sergeant +7831 Customs sergeant +7832 Young Ralph +7833 Young Ralph +7834 Young Ralph +7835 Young Ralph +7836 Young Ralph +7837 Customs officer +7838 Customs officer +7839 Customs officer +7840 Heavy-Handed Harry +7841 Player +7842 Locker Officer +7843 Locker Officer +7844 Ex-ex-parrot +7845 Pirate impling +7846 Pirate impling +7847 Captain Rabid Jack +7848 Jack +7849 Bosun Giles +7850 Pirate +7851 Lizzie +7852 Cap'n Izzie No-beard +7853 Ralph +7854 Brass Hand Harry +7855 Bill Teach +7856 Pirate +7857 Brass Hand Harry +7858 Karamthulu +7859 Young Ralph +7860 Gull +7861 Jack +7862 Fishing spot +7863 Fishing spot +7864 Fishing spot +7865 Guardsman Dante +7866 Guardsman DeShawn +7867 Guardsman Brawn +7868 Iain +7869 Julian +7870 Lachtopher +7871 Samuel +7872 Victoria +7873 Man +7874 Man +7875 Man +7876 Man +7877 Man +7878 Man +7879 Man +7880 Woman +7881 Woman +7882 Woman +7883 Woman +7884 Woman +7885 Guardsman Dante +7886 Guardsman DeShawn +7887 Guardsman Brawn +7888 Sergeant Abram +7889 Guardsman Pazel +7890 Guardsman Peale +7891 Melee dummy +7892 General Wartface +7893 General Bentnoze +7894 null +7895 General Wartface +7896 null +7897 General Wartface +7898 Afflicted(Ulsquire) +7899 Afflicted(Razmire) +7900 Loar Shadow +7901 Loar Shadow +7902 Sergeant Abram +7903 Guardsman Pazel +7904 Guardsman Peale +7905 Barricade guard +7906 Barricade guard +7907 Barricade guard +7908 Barricade guard +7909 Barricade guard +7910 Barricade guard +7911 Barricade guard +7912 Border guard +7913 Iain +7914 Julian +7915 Lachtopher +7916 Samuel +7917 Victoria +7918 Man +7919 Man +7920 Man +7921 Man +7922 Man +7923 Man +7924 Man +7925 Woman +7926 Woman +7927 Woman +7928 Woman +7929 Lumbridge Guide +7930 Doomsayer +7931 Donie +7932 Gee +7933 Duke Horacio +7934 Sigmund +7935 Hans +7936 Cook +7937 Father Aereck +7938 Sir Vant +7939 Sir Vant +7940 Sir Vant +7941 Sir Vant +7942 Sir Vant +7943 Dragon +7944 Dragon +7945 Dragon +7946 Dragon +7947 Dragon +7948 Dragon +7949 Lumbridge Guide +7950 Melee tutor +7951 Ranged tutor +7952 Magic tutor +7953 Cooking tutor +7954 Crafting tutor +7955 Fishing tutor +7956 Mining tutor +7957 Prayer tutor +7958 Smelting tutor +7959 Smithing tutor +7960 Woodcutting tutor +7961 Bank tutor +7962 Gee +7963 Spirit +7964 Goblin +7965 Goblin +7966 Chaos druid +7967 Shopkeeper +7968 null +7969 Explorer Jack +7970 Smithing tutor +7971 Mining tutor +7972 null +7973 null +7974 null +7975 null +7976 Spirit +7977 Spirit +7978 Spirit +7979 Spirit +7980 Spirit +7981 Spirit +7982 Spirit +7983 Spirit +7984 Spirit +7985 +7986 Summer Bonde +7987 Spirit +7988 Spirit +7989 Erik Bonde +7990 Spirit +7991 Jallek Lenkin +7992 Spirit +7993 Meranek Thanatos +7994 Ghostly warrior +7995 Spirit beast +7996 Spirit beast +7997 Spirit beast +7998 Ghost +7999 Ghost +8000 Goth Leprechaun +8001 null +8002 Jack +8003 Sarah +8004 Laura +8005 Laura +8006 Roger +8007 Jorral +8008 Guthix +8009 Max the traveller +8010 Man +8011 Man +8012 Woman +8013 Woman +8014 Haluned +8015 Jack +8016 Baby Sarah +8017 Snowy +8018 Roger +8019 Portal +8020 Portal +8021 Yellow orb +8022 Yellow orb +8023 Yellow orb +8024 Yellow orb +8025 Green orb +8026 Green orb +8027 Green orb +8028 Green orb +8029 Wizard Korvak +8030 Wizard Vief +8031 Wizard Acantha +8032 Wizard Elriss +8033 Wizard +8034 Wizard +8035 Wizard +8036 Wizard +8037 Wizard +8038 Wizard +8039 Wizard +8040 Wizard +8041 Imiago +8042 Squire Fyre diff --git a/dumps/530/530_synth_debug_names.txt b/dumps/530/530_synth_debug_names.txt new file mode 100644 index 0000000..324fc9d --- /dev/null +++ b/dumps/530/530_synth_debug_names.txt @@ -0,0 +1,3816 @@ +# this list is sourced from the OSRS synth debug names/IDs. +# it only goes up to 3826, the exact point where OSRS diverged. +# see: quest_prefix_internal_names.txt to find content related to a quest. + +eyeglo_battle_fighting_1=0 +eyeglo_aspidistra=1 +eyeglo_battle_gnomes_scared=2 +eyeglo_battle_gnomes_1=3 +eyeglo_battle_gnomes_scared_running=4 +eyeglo_battle_gnomes_scared_2=5 +eyeglo_crystal_axe_recharge=6 +eyeglo_battle_goblins_1=7 +eyeglo_bowl_ring=8 +eyeglo_bowl_ring2=9 +eyeglo_coin=10 +eyeglo_creature_attack=11 +sword_hit2=12 +sword_hit2_mail=13 +steel_mail=14 +steel=15 +big_bar=16 +big_bar_mail=17 +swordclash4_mail=18 +dragon_armour=19 +dragon_mail=20 +swordclash4=21 +blade3_mail=22 +blade3=23 +leather_hit=24 +steel2=25 +steel2_mail=26 +swordclash3_mail=27 +blade2_mail=28 +blade2=29 +crystal_armour_4=30 +stone_armour1=31 +stone_armour2=32 +stone_armour3=33 +bamboo_door_close=34 +a_door_close=35 +a_door_open=36 +barrows_door_unlock=37 +bamboo_door_open=38 +bamboodoor_close=39 +bamboodoor_open=40 +barrows_door_open=41 +bookcase_open_and_close=42 +big_wooden_door_close=43 +big_wooden_door_open=44 +bigdoor_close=45 +bigdoor_open=46 +bone_door_close=47 +bone_door_open=48 +creakydoor_close=49 +casket_open=50 +chest_close=51 +chest_open=52 +coffin_close=53 +coffin_open=54 +small_creaky_door_close=55 +creakydoor_open=56 +cupboard_close=57 +cupboard_open=58 +curtain_open=59 +door_close=60 +door_creak=61 +door_open=62 +drawer_close=63 +drawer_open=64 +fire_door_pass=65 +gate_close=66 +gate_open=67 +grate_close=68 +grate_open=69 +iron_door_close=70 +iron_door_open=71 +irondoor_locked=72 +jar_open=73 +manhole_close=74 +manhole_open=75 +marble_door_close=76 +marble_door_open=77 +new_door_close=78 +new_door_open=79 +nicedoor_close=80 +nicedoor_open=81 +portcullis_close=82 +portcullis_open=83 +sliding_grate=84 +small_creaky_door_open=85 +stone_door=86 +stone_door_locked=87 +trap_door_close=88 +trap_door_open=89 +trapdoor_close=90 +trapdoor_open=91 +treedoor_close=92 +treedoor_open=93 +vent_door_open=94 +wardrobe_close=95 +wardrobe_open=96 +high_alchemy=97 +low_alchemy=98 +bind_impact=99 +bind_all=100 +bind_cast=101 +blood_barrage_impact=102 +blood_blitz_all=103 +blood_blitz_impact=104 +blood_burst_impact=105 +blood_cast=106 +blood_rush_all=107 +blood_rush_casting=108 +blood_rush_fail=109 +blood_rush_impact=110 +blood_rush_work=111 +blood_travel=112 +blood_travel_2=113 +bones_to_bananas_all=114 +charge_earth_orb=115 +charge_air_orb=116 +charge_fire_orb=117 +charge_water_orb=118 +confuse_cast_and_fire=119 +confuse_all=120 +confuse_hit=121 +crumble_cast_and_fire=122 +crumble_all=123 +crumble_hit=124 +curse_all=125 +curse_hit=126 +curse_cast_and_fire=127 +earthblast_cast_and_fire=128 +earthblast_hit=129 +earthbolt_cast_and_fire=130 +earthbolt_hit=131 +earthstrike_cast_and_fire=132 +earthstrike_hit=133 +earthwave_cast_and_fire=134 +earthwave_hit=135 +enchant_sapphire_amulet=136 +enchant_diamond_amulet=137 +enchant_diamond_ring=138 +enchant_dragon_amulet=139 +enchant_dragon_ring=140 +enchant_emerald_amulet=141 +enchant_emerald_ring=142 +enchant_onyx_amulet=143 +enchant_onyx_ring=144 +enchant_ruby_amulet=145 +enchant_ruby_ring=146 +enchant_sapphire_ring=147 +enfeeble_cast_and_fire=148 +enfeeble_all=149 +enfeeble_hit=150 +entangle_cast_and_fire=151 +entangle_all=152 +entangle_hit=153 +paralyze=154 +fireblast_cast_and_fire=155 +fireblast_hit=156 +firebolt_cast_and_fire=157 +firebolt_hit=158 +firebreath=159 +firestrike_cast_and_fire=160 +firestrike_hit=161 +firewave_cast_and_fire=162 +firewave_hit=163 +lesserdemon_fire_cast=164 +doubleheal=165 +heal=166 +selfheal=167 +ice_barrage_impact=168 +ice_blitz_impact=169 +ice_burst_impact=170 +ice_cast=171 +ice_magic_all=172 +ice_rush_impact=173 +magic_dart_hit=174 +shadow_barrage_impact=175 +shadow_blitz_impact=176 +shadow_burst_impact=177 +shadow_cast=178 +shadow_rush_impact=179 +smoke_barrage_impact=180 +smoke_blitz_impact=181 +smoke_burst_impact=182 +smoke_cast=183 +smoke_cast2=184 +smoke_rush_impact=185 +snare_all=186 +stun_all=187 +summon_npc=188 +summon_zombie=189 +superheat_all=190 +superheat_fail=191 +telegrab_all=192 +aide_teleport_chalk=193 +aide_teleport_book=194 +aide_teleport_portal=195 +aide_teleport_sitdown=196 +block_teleport=197 +quick_teleport=198 +tele_other_cast=199 +teleport_all=200 +teleport_reverse=201 +teleportblock_cast=202 +teleportblock_impact=203 +wilderness_teleport=204 +undead_rot=205 +vulnerability_all=206 +waterblast_cast_and_fire=207 +waterblast_hit=208 +waterbolt_cast_and_fire=209 +waterbolt_hit=210 +waterstrike_cast_and_fire=211 +waterstrike_hit=212 +waterwave_cast_and_fire=213 +waterwave_hit=214 +weaken_all=215 +windblast_cast_and_fire=216 +windblast_hit=217 +windbolt_cast_and_fire=218 +windbolt_hit=219 +windstrike_cast_and_fire=220 +windstrike_hit=221 +windwave_cast_and_fire=222 +windwave_hit=223 +zap=224 +darklight_weaken=225 +equip_magic=226 +spellfail=227 +wave_wand=228 +zamorak_flame=229 +abyssal_leech_death=230 +abyssal_leech_hit=231 +abyssal_leech_suck=232 +abyssal_walker_attack=233 +abyssal_walker_death=234 +abyssal_walker_hit=235 +fourface_attack=236 +fourface_death=237 +fourface_hit=238 +fourface_ranged=239 +underwater_mogre_attack=240 +mudskipper_attack=241 +mudskipper_death=242 +mudskipper_hit=243 +mugre_attack=244 +mugre_death=245 +mugre_hit=246 +underwater_mugre_attack=247 +underwater_mugre_death=248 +underwater_mugre_hit=249 +tzhaar_ket_attack_club=250 +tzhaar_hur_attack=251 +tzhaar_hur_death=252 +tzhaar_hur_hit=253 +tzhaar_ket_attack_multiclub=254 +tzhaar_ket_attack_punch=255 +tzhaar_ket_death=256 +tzhaar_ket_hit=257 +tzhaar_ket_hit_shield=258 +tzhaar_ket_hit_shield2=259 +tzhaar_mej_attack=260 +tzhaar_mej_attack_punch=261 +tzhaar_mej_attack_staff=262 +tzhaar_mej_death=263 +tzhaar_mej_hit=264 +tzhaar_staff=265 +tzhaar_xil_attack_blade=266 +tzhaar_xil_attack_fork=267 +tzhaar_xil_attack_multiblade=268 +tzhaar_xil_attack_ring=269 +tzhaar_xil_death=270 +tzhaar_xil_hit=271 +spectre_attack=272 +goo_hit=273 +spectre_death=274 +spectre_hit=275 +abyssal_attack=276 +abyssal_death=277 +abyssal_hit=278 +animated_death2=279 +animated_death=280 +animated_hit=281 +banshee_attack=282 +banshee_attack_earmuffs=283 +banshee_attack_normal=284 +banshee_death=285 +banshee_hit=286 +basilisk_attack=287 +basilisk_attack2=288 +basilisk_death=289 +basilisk_hit=290 +firebat_attack=291 +bat_attack=292 +bat_death=293 +bat_hit=294 +firebat_death=295 +firebat_hit=296 +anger_bear_attack=297 +anger_bear_death=298 +anger_bear_hit=299 +bear_attack=300 +bear_death=301 +bear_hit=302 +bearman_attack=303 +bearman_death=304 +bearman_hit=305 +bird_attack=306 +bird_death=307 +bird_hit=308 +seagull_attack=309 +seagull_death=310 +seagull_hit=311 +bloodveld_attack=312 +bloodveld_death=313 +bloodveld_hit=314 +large_boneguard_attack=315 +large_boneguard_death=316 +large_boneguard_hit=317 +small_boneguard_attack=318 +small_boneguard_death=319 +small_boneguard_hit=320 +boulder_rolling_loop=321 +boulder_loop=322 +brawler_attack=323 +brawler_cry=324 +brawler_death=325 +brawler_hit=326 +camel_disgruntled=327 +catablepon_attack=328 +catablepon_death=329 +catablepon_hit=330 +catablepon_hit2=331 +kitten_attack=332 +cat_attack=333 +cat_death=334 +cat_hiss=335 +cat_hit=336 +kitten_death=337 +kitten_hit=338 +kittens_mew=339 +purr=340 +cave_crawler_attack=341 +cave_crawler_death=342 +cave_crawler_hit=343 +chaos_elemental_confusion_cast=344 +chaos_elemental_attack=345 +chaos_elemental_confusion_impact=346 +chaos_elemental_death=347 +chaos_elemental_discord=348 +chaos_elemental_discord_cast=349 +chaos_elemental_discord_impact=350 +chaos_elemental_hit=351 +chaos_elemental_madness_cast=352 +chaos_elemental_madness_impact=353 +rubber_chicken_cluck=354 +chicken_attack=355 +chicken_death=356 +chicken_hit=357 +lay_egg=358 +chinchompa_attack=359 +chinchompa_explode=360 +chinchompa_hit=361 +chinchompa_trapped=362 +cockatrice_attack=363 +cockatrice_death=364 +cockatrice_hit=365 +calf_attack=366 +calf_death=367 +calf_hit=368 +cow_attack=369 +cow_death=370 +cow_hit=371 +milk_cow=372 +milk_cow2=373 +small_crab_attack=374 +small_crab_death=375 +small_crab_hit=376 +hand_attack=377 +hand_death=378 +hand_hit=379 +fake_creeper_death=380 +creeper_attack=381 +creeper_death=382 +creeper_hit=383 +creeper_impact=384 +creeper_spit=385 +crocodile_attack=386 +crocodile_death=387 +crocodile_hit=388 +dark_beast_attack=389 +dark_beast_death=390 +dark_beast_hit=391 +defiler_attack=392 +defiler_death=393 +defiler_hit=394 +defiler_spike=395 +demon_champion_attack=396 +black_demon_attack=397 +black_demon_death=398 +black_demon_hit=399 +demon_attack=400 +demon_champion_death=401 +demon_champion_hit=402 +demon_death=403 +demon_hit=404 +babydragon_attack=405 +babydragon_death=406 +babydragon_hit=407 +dragon_attack=408 +dragon_death=409 +dragon_hit=410 +duck_death=411 +duck_hit=412 +quack=413 +dust_devil_attack=414 +dust_devil_death=415 +dust_devil_hit=416 +dwarf_attack=417 +dwarf_death=418 +dwarf_hit=419 +dwarf_work=420 +eagle_attack=421 +eagle_attack2=422 +eagle_death=423 +eagle_hit=424 +elf_attack=425 +elf_death=426 +elf_hit=427 +gargoyle_attack=428 +gargoyle_death=429 +gargoyle_hit=430 +ghast_disappear=431 +ghast_appear=432 +ghast_attack=433 +ghast_death=434 +ghast_hit=435 +ghost_attack=436 +ghost_attack2=437 +ghost_death=438 +ghost_hit=439 +ghost_hit2=440 +ghoul_champion_attack=441 +ghoul_attack=442 +ghoul_death=443 +ghoul_hit=444 +giant_champion_attack=445 +earth_giant_attack=446 +fire_giant_attack=447 +giant_attack=448 +moss_giant_attack=449 +giant_death=450 +giant_hit=451 +gnome_glider_attack=452 +gnome_attack=453 +gnome_death=454 +gnome_hit=455 +gnome_tortoise_mounted_attack=456 +gnome_tortoise_attack=457 +gnome_tortoise_death=458 +gnome_tortoise_hit=459 +gnome_tortoise_mounted_death=460 +gnome_tortoise_mounted_hit=461 +anger_goblin_attack=462 +anger_goblin_death=463 +anger_goblin_hit=464 +cave_goblin_attack=465 +cave_goblin_death=466 +cave_goblin_hit=467 +goblin_armed=468 +goblin_attack=469 +goblin_champion_attack=470 +goblin_death=471 +goblin_hit=472 +hobgoblin_champion_hit=473 +golem_attack=474 +golem_death=475 +golem_hit=476 +gorilla_beat_loop=477 +gorilla_attack=478 +gorilla_beatchest=479 +gorilla_death=480 +gorilla_hit=481 +gorilla_hit2=482 +growl=483 +growl2=484 +growl3=485 +growl4=486 +growl5=487 +growl6=488 +half_werewolf_attack=489 +half_werewolf_death=490 +half_werewolf_hit=491 +hopeless_attack=492 +hopeless_death=493 +hopeless_hit=494 +hopeless_suck=495 +jungle_horror_attack=496 +cave_horror_howl=497 +jungle_horror_attack2=498 +jungle_horror_death=499 +jungle_horror_hit=500 +barbarian_female_hit=501 +barbarian_death=502 +human_underwater_death=503 +barbarian_hit=504 +female_death=505 +female_hit=506 +female_hit1=507 +female_hit2=508 +female_hit_1=509 +female_hit_2=510 +human_block_1=511 +human_death=512 +human_hit=513 +human_hit2=514 +human_hit3=515 +human_hit4=516 +human_hit5=517 +human_hit_1=518 +human_hit_2=519 +human_hit_3=520 +human_hit_4=521 +human_hit_6=522 +human_hit_7=523 +huntingbeast_death=524 +kebbit_attack=525 +kebbit_caught=526 +kebbit_death=527 +kebbit_hit=528 +ice_warrior_death=529 +ice_warrior_hit=530 +icefiend_attack=531 +icefiend_death=532 +icefiend_hit=533 +imp_attack=534 +imp_death=535 +imp_hit=536 +insect_attack=537 +insect_death=538 +insect_hit=539 +insect_trapped=540 +kilrag_attack=541 +kilrag_death=542 +kilrag_hit=543 +jackal_attack=544 +jackal_death=545 +jackal_hit=546 +jelly_attack=547 +jelly=548 +jelly_death=549 +jelly_hit=550 +kalphite_flyingqueen_attack=551 +kalphite_crack_open=552 +kalphite_flyingqueen_death=553 +kalphite_flyingqueen_hit=554 +kalphite_queen_spines=555 +kalthite_egg_crack=556 +kalthite_lightning=557 +kalthite_lightning_glow=558 +kalthite_lightning_impact=559 +kalthite_lord_attack=560 +kalthite_lord_death=561 +kalthite_lord_hit=562 +kalthite_queen_attack=563 +kalthite_queen_death=564 +kalthite_queen_hit=565 +kalthite_queen_hit2=566 +kalthite_soldier_attack=567 +kalthite_soldier_death=568 +kalthite_soldier_hit=569 +kalthite_squeal=570 +kalthite_worker_attack=571 +kalthite_worker_death=572 +kalthite_worker_hit=573 +mandibles=574 +killerwatt_ball_attack=575 +killerwatt_attack=576 +killerwatt_electrocutes=577 +killerwatt_ball_death=578 +killerwatt_ball_hit=579 +killerwatt_death=580 +killerwatt_electrocute=581 +killerwatt_transforms=582 +killerwatt_hit=583 +lightningbreath=584 +dragonbreath=585 +kingicebreath=586 +toxicbreath=587 +kurask_attack=588 +kurask_death=589 +kurask_hit=590 +lava_launch=591 +lava_hit=592 +lava_hit_2=593 +lava_launch_and_hit=594 +lavabeast_attack=595 +lavabeast_death=596 +lavabeast_hit=597 +magmaquiris_attack=598 +magmaquiris_death=599 +magmaquiris_hit=600 +magmaquiris_spines=601 +leech_death=602 +leech_hit=603 +leech_suck=604 +lizard_attack=605 +lizard_death=606 +lizard_hit=607 +lizard_cleric_attack=608 +lizard_cleric_death=609 +lizard_cleric_hit=610 +lizardman_attack=611 +lizardman_death=612 +lizardman_hit=613 +locust_attack=614 +locust_mage_attack=615 +locust_death=616 +locust_hit=617 +locust_mage_death=618 +locust_mage_hit=619 +locust_rider_death=620 +locust_rider_hit=621 +locust_rider_rear=622 +mammoth_attack=623 +mammoth_death=624 +mammoth_hit=625 +minotaur_attack=626 +minotaur_death=627 +minotaur_hit=628 +zombie_monkey_attack=629 +monkey_attack=630 +monkey_caught=631 +monkey_death=632 +monkey_escape=633 +monkey_hit=634 +zombie_monkey_death=635 +zombie_monkey_hit=636 +giant_mosquito_attack=637 +mummy_ash_death=638 +mummy_appear=639 +mummy_on_fire_attack=640 +mummy_attack=641 +mummy_death=642 +mummy_hit=643 +mummy_on_fire_death=644 +nechrayel_attack=645 +nechrayel_death=646 +nechrayel_hit=647 +orc_attack=648 +orc_death=649 +orc_hit=650 +nasty_tree_attack=651 +barklike=652 +birdlike=653 +cry1=654 +cry3=655 +goblin2=656 +horse_hit=657 +rock_spirit_appear=658 +rock_spirit=659 +scream2=660 +scream=661 +otherworld_attack=662 +otherworld_death=663 +otherworld_hit=664 +screech2=665 +panther_attack=666 +panther_death=667 +panther_hit=668 +penance_queen_range_impact=669 +penance_fighter_attack=670 +penance_fighter_death=671 +penance_fighter_hit=672 +penance_healer_heal=673 +penance_healer_poison=674 +penance_queen_attack=675 +penance_queen_death=676 +penance_queen_hit=677 +penance_queen_range=678 +penance_ranger_range_hit=679 +penance_ranger_attack=680 +penance_ranger_death=681 +penance_ranger_hit=682 +penance_spawn_death=683 +penance_spawn_spawn=684 +penance_spawn_hit=685 +penguinsheep_escape=686 +penguin_attack=687 +penguin_death=688 +penguin_hit=689 +pheasant_attack=690 +pheasant_death=691 +pheasant_hit=692 +pig_attack=693 +pig_death=694 +pig_hit=695 +pyrefiend_attack=696 +pyrefiend_death=697 +pyrefiend_hit=698 +rabbit_atmospheric=699 +rabbit_attack=700 +rabbit_death=701 +rabbit_hit=702 +anger_rat_attack=703 +anger_rat_death=704 +anger_rat_hit=705 +king_rat_attack=706 +king_rat_death=707 +king_rat_hiss=708 +king_rat_hit=709 +rat_attack=710 +rat_death=711 +rat_drown=712 +rat_hit=713 +ravager_attack=714 +ravager_death=715 +ravager_hit=716 +small_rock_crab_attack=717 +rock_crab_attack=718 +rock_crab_death=719 +rock_crab_hit=720 +underwater_rock_crab_attack=721 +small_rock_crab_death=722 +small_rock_crab_hit=723 +underwater_rock_crab_death=724 +underwater_rock_crab_hit=725 +rock_lobster_attack=726 +rock_lobster_death=727 +rock_lobster_hit=728 +rockslug_attack=729 +rockslug_death=730 +rockslug_hit=731 +equip_salamander=732 +salamander_attack=733 +salamander_belch=734 +salamander_blast=735 +salamander_blaze=736 +salamander_death=737 +salamander_flame=738 +salamander_hit=739 +salamander_scorch=740 +scarab_boss_attack=741 +scarab_boss_death=742 +scarab_boss_hit=743 +shade_appear=744 +shade_attack=745 +shade_death=746 +shade_hit=747 +shade_sigh=748 +shadow_beast_attack=749 +shadow_beast_death=750 +shadow_beast_hit=751 +shark_attack=752 +shark_death=753 +shark_hit=754 +angry_sheep=755 +cattleprod=756 +ram_attack=757 +ram_death=758 +ram_hit=759 +shear_once=760 +shear_sheep=761 +sheep_attack=762 +sheep_death=763 +sheep_hit=764 +sheepcall1=765 +shifter_attack=766 +shifter_death=767 +shifter_hit=768 +skwy_bite=769 +skwy_death=770 +skwy_hit=771 +skwy_ice=772 +skwy_tail=773 +armed_skeleton_hit=774 +armed_skeleton=775 +skeleton_attack=776 +skeleton_death=777 +skeletons_hiss=778 +skelly_hit=779 +slagilith_appear=780 +slagilith_attack=781 +slagilith_death=782 +slagilith_hit=783 +slime_attack=784 +slime_death=785 +slime_hit=786 +snail_death=787 +snail_spit2=788 +snail_hit=789 +snail_spit=790 +big_seasnake_attack=791 +big_seasnake_death=792 +big_seasnake_hit=793 +seasnake_attack=794 +seasnake_death=795 +seasnake_hit=796 +snake_attack=797 +snake_death=798 +snake_hiss=799 +snake_hit=800 +snaketest1=801 +sphinx_attack=802 +sphinx_death=803 +sphinx_hit=804 +spinner_attack=805 +spinner_death=806 +spinner_hit=807 +spinner_spin=808 +splatter_attack=809 +splatter_death=810 +splatter_hit=811 +stag_attack=812 +stag_death=813 +stag_hit=814 +sukqa_attack=815 +sukqa_death=816 +sukqa_hit=817 +swarm_appear=818 +swarm_attack=819 +swarm_death=820 +swarm_hit=821 +tanglewood_large_attack=822 +tanglewood_large_death=823 +tanglewood_large_hit=824 +tanglewood_small_attack=825 +tanglewood_small_death=826 +tanglewood_small_hit=827 +dragonkin_attack=828 +dragonkin_death=829 +dragonkin_hit=830 +terrorbird_appear=831 +terrorbird_attack=832 +terrorbird_death=833 +terrorbird_hit=834 +tiger_attack=835 +tiger_death=836 +tiger_hit=837 +giant_toad_attack=838 +giant_toad_death=839 +giant_toad_hit=840 +toad2=841 +toad_attack=842 +toad_death=843 +toad_hit=844 +torcher_attack=845 +torcher_death=846 +torcher_fire=847 +torcher_hit=848 +ice_troll_hit=849 +sea_troll_appear=850 +rock_impact=851 +sea_troll_queen_appear=852 +sea_troll_attack=853 +sea_troll_death=854 +sea_troll_general=855 +sea_troll_hit=856 +sea_troll_queen_attack=857 +sea_troll_queen_death=858 +sea_troll_queen_hit=859 +stone_impact=860 +troll_attack=861 +troll_champion_attack=862 +troll_champion_death=863 +troll_champion_hit=864 +troll_champion_swing=865 +troll_death=866 +troll_guard_attack=867 +troll_hit=868 +troll_snore=869 +troll_throw_rock=870 +troll_with_rock_attack=871 +trolls_shout=872 +turoth_attack=873 +turoth_death=874 +turoth_hit=875 +anger_unicorn_attack=876 +anger_unicorn_death=877 +anger_unicorn_hit=878 +vampire_attack=879 +flapping=880 +vampire_death_mist=881 +vampire_death=882 +vyrewatch_vampire_hit=883 +vampire_hit=884 +vampire_land=885 +vampire_suck=886 +vampire_weaken=887 +vyrewatch_vampire_attack=888 +vyrewatch_vampire_death=889 +vulture_attack=890 +vulture_death=891 +vulture_hit=892 +wall_beast_attack=893 +wall_beast_death=894 +wall_beast_foiled=895 +wall_beast_hit=896 +wall_beast_swipe=897 +water_creature_attack=898 +water_creature_death=899 +water_creature_hit=900 +water_creature_spines=901 +elemental_summon_skeleton=902 +elemental_summon_ghost=903 +elemental_summon_skeletonmage=904 +elemental_summon_zombie=905 +elemental_wizard_death=906 +human_into_mushroom=907 +mushroom_into_human=908 +wolf_attack=909 +wolf_attack2=910 +wolf_death=911 +wolf_hit=912 +zogre_axe_attack=913 +zogre_attack=914 +zogre_shield_hit=915 +zogre_death=916 +zogre_hit=917 +zombie_attack=918 +zombie2=919 +zombie_atmospheric1=920 +zombie_champion_attack=921 +zombie_death=922 +zombie_hit=923 +zombie_pirate_attack=924 +zombie_pirate_death=925 +zombie_pirate_hit=926 +zombie_pirate_limbfall=927 +zombie_pirate_punch=928 +npc_trapped=929 +poh_build_metal=930 +POH_man_trap=931 +bell_peal=932 +ping=933 +poh_bigcage=934 +poh_boil=935 +poh_oub_monster_attack=936 +poh_build_stone=937 +poh_build_wood=938 +poh_change_hair=939 +poh_clay_hit=940 +poh_clockwork=941 +poh_cloth=942 +poh_dart_land=943 +poh_dart_miss=944 +poh_dropcage=945 +poh_fairy_appear=946 +poh_forcedoor=947 +poh_hit_clay=948 +poh_hit_limestone=949 +poh_hit_marble=950 +poh_hoop_misses=951 +poh_jester_appear=952 +poh_limestone_hit=953 +poh_man_trap_avoid=954 +poh_marble_hit=955 +poh_marbles=956 +poh_marbles_avoid=957 +poh_offer_bones=958 +poh_pitfall_land_spikes=959 +poh_oub_monster_death=960 +poh_oub_monster_hit=961 +poh_pitfall_land_fire=962 +poh_pitfall_land_floor=963 +poh_pitfall_land_half=964 +poh_tablet_break_teleport=965 +poh_pitfall_land_water=966 +poh_portal_shrink=967 +poh_portal_unshrink=968 +poh_pugel=969 +poh_select=970 +poh_setup_stone=971 +poh_smallcage=972 +poh_sphere_balanced=973 +poh_sphere_powerdown=974 +poh_sphere_powerup=975 +poh_stick_on_hoop=976 +poh_stone_shatter=977 +poh_stonehit=978 +poh_tablet_break=979 +poh_tanglevine_dissappear=980 +poh_tanglevine=981 +poh_tentacle_dissappear=982 +poh_tanglevine_loop=983 +poh_teleport=984 +poh_tentacle=985 +poh_tentacle_appear=986 +poh_tentacle_hit=987 +poh_toy_fallover=988 +poh_wind=989 +poh_wrong=990 +100_jubbly_escape_work2=991 +100_jubbly_arrowhit=992 +100_jubbly_bounce=993 +100_jubbly_escape=994 +100_jubbly_escape_work3=995 +100_jubbly_escape_wprk=996 +100_jubbly_escapes=997 +100_ogre_swim=998 +100_rantz_kicks_tree=999 +100_underwater_passage=1000 +100_bubbles=1001 +100_divebomb=1002 +100_equip_claw=1003 +100_sink=1004 +100_iron_door_open_underwater=1005 +100_underwater_pick=1006 +100_fairy_dragon_appear=1007 +100_cat_into_hellcat=1008 +100_fairy_appear=1009 +100_fairy_disappear=1010 +100_fairy_dissappear=1011 +100_flambe=1012 +100_hellcat_into_cat=1013 +100_drop_rockcake=1014 +100_drop_coin=1015 +100_rockcake_burn_fingers=1016 +100_dwarf_cooking=1017 +100_eat_rockcake=1018 +100_sizzle_gloves=1019 +100_cauldron_outside_first=1020 +100_cauldron_explodes=1021 +100_cauldron_outside=1022 +100_cauldron_outside_second=1023 +100_cauldron_shake=1024 +100_cauldron_shake_initial=1025 +100_cauldron_shake_loop=1026 +100_cauldron_shake_loop2=1027 +100_goblin_falls=1028 +100_question_correct=1029 +100_egg_hatch=1030 +100_question_wrong=1031 +100_pull_tree=1032 +100_throw_rope=1033 +100_unfreeze=1034 +100_blowup=1035 +100_romancer_entangle=1036 +100_romancer_explode=1037 +100_summon=1038 +100_whiteout=1039 +PIN_pending=1040 +PIN_beep=1041 +PIN_cancel=1042 +PIN_pending2=1043 +barbassault_egg_explode=1044 +barbassault_fill_vial=1045 +barbassault_trap=1046 +barbassault_trapdoor=1047 +barbassault_turret_fire=1048 +BF_collect_coke=1049 +BF_conveyor_loop=1050 +BF_cooldown=1051 +BF_conveyor_loop_with_pedals=1052 +BF_drivebreaks=1053 +BF_oreinfurnace=1054 +BF_overheat=1055 +BF_pedal_loop=1056 +BF_pipebreaks=1057 +BF_pump_loop=1058 +BF_refuel_stove=1059 +BF_repair=1060 +BF_smelt=1061 +dagganoth_plate_body=1062 +dagganoth_egg_open=1063 +dagganoth_hide_hit=1064 +dagganoth_pressure_door_openandclose=1065 +dagganoth_pressure_door_fall=1066 +dagganoth_pressure_door_open=1067 +dagganoth_range_body=1068 +dagganoth_shell_body=1069 +dagganoth_splash=1070 +dagganoth_support_door=1071 +dagganoth_whirlpool=1072 +meganoth_death=1073 +meganoth_hit=1074 +meganoth_melee_attack=1075 +support_death=1076 +wallasalki_attack=1077 +wallasalki_death=1078 +wallasalki_hit=1079 +DTTD_bone_crossbow_sa=1080 +DTTD_bone_crossbow=1081 +DTTD_zanik_ladygoblin_attack=1082 +DTTD_bone_dagger_slash=1083 +DTTD_bone_dagger_stab=1084 +DTTD_drink=1085 +DTTD_zanik_ladygoblin_death=1086 +DTTD_zanik_ladygoblin_hit=1087 +branding_zanik=1088 +dttd_branding=1089 +dttd_branding_2=1090 +juna_meditates=1091 +pick_up_zaniks_body=1092 +smash_machine=1093 +zanik_gets_in_crate=1094 +zanik_resurrection=1095 +FT_chicken_into_human=1096 +FT_enchant_flower=1097 +FT_fairy_teleport=1098 +FT_female_to_male=1099 +FT_human_into_chicken=1100 +FT_human_into_piglet=1101 +FT_male_to_female=1102 +FT_piglet_into_human=1103 +FT_princess=1104 +FT_raincloud=1105 +FT_secateurs=1106 +FT_squeeze_past=1107 +female_to_male=1108 +forget_box_close=1109 +fall_off_chair=1110 +forget_box_open=1111 +forget_cart_move=1112 +forget_cart_turn=1113 +forget_foottramp=1114 +forget_glass_chink=1115 +forget_placestone=1116 +forget_shaman_all=1117 +forget_trackswitch=1118 +chesspiece_move=1119 +column_full=1120 +king=1121 +runelink_bottom=1122 +runelink_fall=1123 +GT_cart_bigpush=1124 +GT_cart_push=1125 +GT_cutscene_statue=1126 +GT_grind_rune=1127 +GT_shakegrass=1128 +GT_slap=1129 +GT_statue=1130 +grinder_grinding=1131 +fill_ectoplasm=1132 +fill_grinder=1133 +goobubble=1134 +goofade=1135 +grinder_empty=1136 +grinder_wind=1137 +stung=1138 +dwarf_spinning=1139 +clang1=1140 +clang2=1141 +dwarf_fillmachine=1142 +hammering1=1143 +hammering2=1144 +hammering3=1145 +steam_double=1146 +steam_filtered=1147 +steam_high=1148 +steam_low=1149 +steam_mid=1150 +steam_soft=1151 +steam_veryhigh=1152 +steamship=1153 +steamship_crashes=1154 +steamshunt=1155 +whistle1=1156 +whistle2=1157 +whistle3=1158 +collect_sap=1159 +boil_off=1160 +cat_angry=1161 +ics_spectre_appear=1162 +happy_meeoow=1163 +hypnotise=1164 +ics_spectre_attack=1165 +ics_spectre_death=1166 +ics_spectre_hit=1167 +ics_spectre_remove=1168 +meeoow=1169 +pet_cow=1170 +pit_fall=1171 +pit_jump=1172 +pit_jump_fall=1173 +pit_land=1174 +pit_shoot=1175 +sad_meeoow=1176 +scrape_glass=1177 +tile_move=1178 +tile_reset=1179 +vader_breath=1180 +wall_crushed=1181 +wall_crusher=1182 +grind_snail=1183 +acid_burn=1184 +skeletal_hellhound_hit=1185 +mist_appears=1186 +skeletal_hellhound_attack=1187 +skeletal_hellhound_death=1188 +summon_skeletalhound=1189 +vanstrom_appears=1190 +vanstrom_disappears=1191 +vanstrom_laughs=1192 +vanstrom_ldisappears=1193 +vanstrom_wings=1194 +carpet_descend=1195 +carpet_rise=1196 +history_key_burning=1197 +history_key_cold=1198 +history_key_freezing=1199 +history_key_hot=1200 +history_key_steaming=1201 +history_key_warm=1202 +mourning_bellowsfill=1203 +mourning_firegun=1204 +mourning_impact=1205 +mourning_impact_sheep=1206 +mourning_lightdoor=1207 +mourning_sneeze=1208 +mourning_tickle=1209 +mourning_toadfill=1210 +mourning_toadload=1211 +mourning_toadunload=1212 +squish_apples=1213 +NTK_door_with_mummy=1214 +NTK_chest_open=1215 +NTK_jar_with_snake=1216 +NTK_jar_open=1217 +NTK_sarcophagus_open=1218 +NTK_snake_charm=1219 +NTK_stone_door_locked=1220 +mousetrap_spring=1221 +create_smoke=1222 +poison_cheese=1223 +rat_lever=1224 +smoke_out_rats=1225 +smoke_rats=1226 +RT_unlock_casket=1227 +RT_picklock=1228 +RT_place_rune=1229 +RT_select_rune=1230 +RTplace_rune=1231 +rogue_gear_select=1232 +player_dive=1233 +rogue_timedblades_avoid=1234 +rogue_magic_door=1235 +rogue_pendulum_hit=1236 +rogue_placegear=1237 +rogue_safe_open=1238 +rogue_scythe_avoid=1239 +rogue_spinblades_2=1240 +rogue_squeeze=1241 +spring_floor=1242 +safe_crack=1243 +sos_deathdoor_close=1244 +sos_bigdoor=1245 +sos_choir=1246 +sos_creaks=1247 +sos_deathdoor_open_close=1248 +sos_famdoor_close=1249 +sos_famdoor_open_close=1250 +sos_pestdoor_close=1251 +sos_pestdoor_open_close=1252 +sos_sack=1253 +sos_wardoor_close=1254 +sos_wardoor_open=1255 +sos_wardoor_open_close=1256 +SE_remove_rock=1257 +SE_lassoo=1258 +SE_waterdoor_unlock=1259 +SE_waterpour=1260 +banana_slicing=1261 +beast_attack=1262 +beast_death=1263 +beast_hit=1264 +throwup1=1265 +TBCU_broodoo_hit=1266 +TBCU_broodoo=1267 +TBCU_diseasecure=1268 +TBCU_fencefail=1269 +TBCU_findgem=1270 +TBCU_mosquito=1271 +TBCU_mosquito_3=1272 +TBCU_mosquito_5=1273 +TBCU_prepare_wood=1274 +TBCU_repair_fence=1275 +TBCU_repair_middle=1276 +TBCU_repellant=1277 +TBCU_snake=1278 +TBCU_spider=1279 +TBCU_spider_stick=1280 +TBCU_tribesman=1281 +TBCU_tuber=1282 +TBCU_wooden_money=1283 +chippings=1284 +machete_fail=1285 +machete_slash=1286 +vegetation_shake=1287 +vegetation_sucess=1288 +fractured_light_beam=1289 +TL_mirrorfall_1=1290 +TL_mirrorfall_2=1291 +TL_mirrorfall_many=1292 +TL_place_crystal=1293 +TL_place_fractured=1294 +TL_place_mirror=1295 +TL_rebound=1296 +TL_rotate_crystal=1297 +TL_take_crystal=1298 +blue_light_beam=1299 +red_light_beam=1300 +green_light_beam=1301 +light_beam_start=1302 +orange_light_beam=1303 +purple_light_beam=1304 +white_light_beam_start=1305 +white_light_beam=1306 +yellow_light_beam=1307 +splash_and_river=1308 +bone_club=1309 +squeeze_through_rocks=1310 +agrith_portalclose=1311 +agrith_appear=1312 +agrith_circle=1313 +agrith_sandstorm=1314 +agrith_summon=1315 +dharok_axe_crush=1316 +ahrim_attack=1317 +ahrims_aura=1318 +dharok_attack=1319 +dharok_axe=1320 +dharok_axe_slash=1321 +flail=1322 +flail_crush=1323 +flail_stab=1324 +guthan_attack=1325 +guthan_breastplate=1326 +karil_attack=1327 +karil_spikebody=1328 +quarterstaff=1329 +torag_attack=1330 +torag_breastplate=1331 +torag_crush=1332 +verac_attack=1333 +verac_brassard=1334 +verac_crush=1335 +verac_slash=1336 +verac_stab=1337 +wight_death=1338 +wight_hit=1339 +wraith_death=1340 +iban lightning=1341 +barrel_incoming=1342 +catapult_fire=1343 +bigfire=1344 +crystal_armour_1=1345 +catapult_winch=1346 +coalfill=1347 +forest_doublesqueeze=1348 +crystal_armour_2=1349 +crystal_armour_3=1350 +crystal_bow=1351 +crystal_bow2=1352 +crystal_polearm=1353 +crystal_sword_1=1354 +crystal_sword_2=1355 +crystal_sword_3=1356 +crystal_sword_4=1357 +forest_lowwall=1358 +crystal_sword_initial_swipe=1359 +tripwire_with_arrows=1360 +forest_sidesqueeze=1361 +high_pressure=1362 +loom=1363 +low_pressure=1364 +mid_pressure=1365 +pressure_off=1366 +pressure_toohigh=1367 +springtrap=1368 +tripwire=1369 +valveturn=1370 +wom_bed_attack=1371 +wom_bed_death=1372 +wom_bed_hit=1373 +wom_bless=1374 +blade_swing_double=1375 +blade_hit=1376 +blade_swing=1377 +dart_fire_avoid=1378 +collapse_avoid=1379 +dart_fire=1380 +floor_spikes_avoid=1381 +dart_fire_hit=1382 +floor_spikes=1383 +roof_collapse=1384 +pillartag=1385 +saw_rise_and_spin=1386 +roof_collapse2=1387 +saw_fall=1388 +saw_hit=1389 +saw_rise=1390 +snap_and_fall=1391 +saw_spin=1392 +sliced=1393 +speartrap=1394 +pyramid_block=1395 +pyramid_scrape=1396 +pyramid_slip=1397 +skippy_throwglass=1398 +skippy_bucket=1399 +skippy_throwglass_impact=1400 +skippy_throwglass_throw=1401 +avatar_warrior_attack=1402 +avatar_mage_attack=1403 +avatar_warrior_death=1404 +demon_shakeroom=1405 +dwarf_kickrock=1406 +fire_jump=1407 +gold_cannonball=1408 +fly_and_land=1409 +rock_cannon_fire=1410 +light_cannon=1411 +paper_move=1412 +paper_turn=1413 +BK_cabbage_hit=1414 +BK_cauldron_bubbles=1415 +BK_cabbage_land=1416 +BK_explodsion=1417 +BK_explosion=1418 +BK_froth=1419 +BK_throw_cabbage=1420 +cf_swingacross_fail=1421 +cf_attach_cannon=1422 +cf_attach_fuse=1423 +cf_cannonfire=1424 +cf_cannonhit=1425 +cf_detach_cannon=1426 +cf_hammer=1427 +cf_jumpdown=1428 +cf_loadcannon=1429 +cf_pour_gunpowder=1430 +cf_ramrod=1431 +cf_roll_canister=1432 +cf_smear_paste=1433 +cf_splash=1434 +cf_strike=1435 +cf_swim=1436 +cf_swingacross=1437 +cf_swingacross_sucess=1438 +cf_tierope=1439 +castlewars_catapult_fire=1440 +castlewars_button=1441 +castlewars_catapult_destroyed=1442 +castlewars_catapult_repaired=1443 +castlewars_exploding_vial=1444 +castlewars_onfire=1445 +castlewars_putout=1446 +castlewars_setupbarricade=1447 +chompy_bird_screech=1448 +chompy_bird_attack=1449 +chompy_bird_death=1450 +chompy_bird_hit=1451 +ogre_bow=1452 +chompy_bird_squak=1453 +ogre_bellows_suck=1454 +ogre_bellows=1455 +spit_roast=1456 +toad_burst=1457 +toad_croak=1458 +toad_hiss=1459 +contact_darkness_impact=1460 +contact_archers_fire=1461 +contact_scarab_boss_dissappear=1462 +contact_extinguish_lights=1463 +contact_rumble=1464 +contact_rumble_long=1465 +contact_scarabs_disappear=1466 +contact_summon_scarabs=1467 +bookcasedoor=1468 +brushing=1469 +digspade=1470 +lightning=1471 +lightning2=1472 +unlock_and_move=1473 +dice_roll=1474 +dice_shake=1475 +place_crystal=1476 +pitfall=1477 +scarabs_appear=1478 +scarabs2=1479 +scarabs_attack2=1480 +scarabs_attack=1481 +scarabs_death=1482 +scarabs_hit=1483 +vampire_swipe=1484 +devious_grind=1485 +exploding_vial=1486 +explosion=1487 +fuse=1488 +bloom_branch=1489 +spirit_transform=1490 +bloom_mushroom=1491 +bloom_pears=1492 +cast_bloom=1493 +food_rot=1494 +spirit_transform_start=1495 +parrot1=1496 +dunk=1497 +parrot2=1498 +throw_club=1499 +washing=1500 +peak_giant_kebbit_appear=1501 +giant_kebbit_attack=1502 +giant_kebbit_death=1503 +giant_kebbit_hit=1504 +peak_bird_move=1505 +peak_bird_move_loop=1506 +peak_eagle_door=1507 +peak_empty_feeder=1508 +peak_fill_feeder=1509 +peak_nettrap_reset=1510 +peak_nettrap=1511 +peak_place_feather_rumble=1512 +peak_place_feather=1513 +peak_winch=1514 +broken_rune_altar_ambience=1515 +woodcutting_birdsnest=1516 +galvek_attack=1517 +vorkath_attack_2=1518 +vorkath_area=1519 +easter06_human_into_egg=1520 +vorkath_attack=1521 +vorkath_spawn=1522 +vorkath_death=1523 +galvek_air=1524 +Abo_death_2=1525 +Abo_death_1=1526 +air_elemental_attack=1527 +air_elemental_death=1528 +air_elemental_hit=1529 +big_bellows=1530 +earth_elemental_attack=1531 +earth_elemental_death=1532 +earth_elemental_hit=1533 +fire_elemental_attack=1534 +fire_elemental_death=1535 +fire_elemental_hit=1536 +lava_bowl_fill=1537 +lava_bowl_pour=1538 +shield_appear=1539 +sluice_gate=1540 +squeaky_valve=1541 +squeaky_valve_gush=1542 +water_elemental_attack=1543 +water_elemental_death=1544 +water_elemental_death2=1545 +water_elemental_hit=1546 +water_wheel_start=1547 +water_wheel_stop=1548 +enak_chisel_wall=1549 +enak_attach=1550 +enak_barrier=1551 +enak_blocked=1552 +enak_chisel=1553 +enak_place_clay=1554 +enak_door=1555 +enak_hiss=1556 +enak_interference_loop=1557 +enak_place_sigil=1558 +enak_push=1559 +enak_wind=1560 +enakh_statue=1561 +enakh_transform=1562 +enakh_wall_fall=1563 +chicken_into_human=1564 +ernest_clunk=1565 +ernest_sprinkle=1566 +end_whistle=1567 +catch=1568 +whistle=1569 +gnomeball_referee_gives_ball=1570 +gnomeball_tackled_gnome=1571 +gnomeball_tackled_gnome_miss=1572 +gnomeball_tackled_miss=1573 +gnomeball_tackled_player=1574 +score=1575 +throw=1576 +cave_bug_attack=1577 +cave_bug_death=1578 +cave_bug_death2=1579 +cave_bug_hit=1580 +insect_bites=1581 +insect_swarm=1582 +lantern_explodes=1583 +demon_approach=1584 +machine2=1585 +machinery=1586 +handsand_vialshatter=1587 +handsand_drop_hand=1588 +handsand_gulp=1589 +handsand_orb=1590 +handsand_sandswirl=1591 +handsand_serum=1592 +handsand_take_hand=1593 +crane_move_and_snap=1594 +bigghost_appear=1595 +bigghost_attack=1596 +bigghost_death=1597 +bigghost_disappear=1598 +bigghost_hit=1599 +bigghost_laugh=1600 +bigghost_reappear=1601 +cart_away=1602 +cart_hit=1603 +cart_into_turn=1604 +cart_loop=1605 +cart_loop_short=1606 +cart_turn=1607 +crane_jaws=1608 +crane_move=1609 +lift_fall=1610 +pickaxe_attack=1611 +points_change=1612 +shard_attack=1613 +shard_attack2=1614 +dagganoth_attack=1615 +dagganoth_critter_attack=1616 +dagganoth_changes=1617 +dagganoth_chitters=1618 +dagganoth_critter_death=1619 +dagganoth_critter_hit=1620 +dagganoth_death=1621 +dagganoth_hit=1622 +dagganoth_spines=1623 +meganoth_spines=1624 +strangedoor_close=1625 +strangedoor_open=1626 +strangedoor_sound=1627 +found_ice_arrows=1628 +fire_teleport=1629 +lava_bridge=1630 +lockeddoor=1631 +mizgog_placebeads=1632 +mizgog_beads=1633 +curse_lift=1634 +bling=1635 +bling2=1636 +bling3=1637 +bling4=1638 +summon_skeleton=1639 +bullroarer=1640 +mole_burrow_down=1641 +mole_attack=1642 +mole_burrow=1643 +mole_burrow_up=1644 +mole_death=1645 +mole_hit=1646 +mud_pie_impact=1647 +mud_pie_miss=1648 +mud_pie_throw=1649 +charge_gone=1650 +charge=1651 +claws_of_guthix_fail=1652 +claws_of_guthix=1653 +flames_of_zamorak_fail=1654 +flames_of_zamorak=1655 +saradomin_strike_fail=1656 +magical_barrier=1657 +pool_plop=1658 +saradomin_strike=1659 +mta_deposit_bone=1660 +mta_bonefall=1661 +mta_change=1662 +mta_deposit_fruit=1663 +mta_deposit_orb=1664 +mta_lock_statue=1665 +mta_move_statue=1666 +mcannon_fire=1667 +fire_loop_quiet=1668 +fire_loop=1669 +fire_loud_to_quiet=1670 +human_into_smallmonkey=1671 +fire_quiet_to_loud=1672 +gorilla_bigpunch=1673 +gorilla_into_human=1674 +heromonkey=1675 +human_into_gorilla=1676 +human_into_monkey=1677 +rumbling=1678 +ooks=1679 +human_into_zombiemonkey=1680 +monkey_into_human=1681 +monkeycalls=1682 +smallmonkey_into_human=1683 +ravinegate_open=1684 +rumbling_fade=1685 +rumbling_loop=1686 +skeleton_resurrect=1687 +snore=1688 +wing_unfold=1689 +zombiemonkey_into_human=1690 +moon_kick_letters=1691 +moon_babahouse=1692 +moon_dice_roll=1693 +moon_ejector=1694 +moon_fall_land=1695 +moon_hurdle=1696 +moon_jump=1697 +moon_press_number=1698 +moon_rubdown=1699 +moon_slip=1700 +moon_watering=1701 +moon_woodchop=1702 +place_stone=1703 +abseil=1704 +tree_climbing=1705 +polevault=1706 +scoopmud=1707 +split_rock=1708 +m2_fillcoal=1709 +m2_build=1710 +m2_rod_capture=1711 +m2_fillpot=1712 +m2_rod_of_command=1713 +m3_place_symbol=1714 +m3_electrocute=1715 +m3_kick_wall=1716 +m3_place_key=1717 +magic_dart_fire=1718 +m3_push_wall=1719 +m3_search_jars=1720 +m3_slash=1721 +m3_walk_rubble=1722 +m3_writing=1723 +animaterock_spell=1724 +fix_weathervane=1725 +water_boil=1726 +pest_portal_hit=1727 +pest_hammer=1728 +pest_portal_shrink=1729 +plague_pull_grill=1730 +plague_attach=1731 +plague_tomato=1732 +holy_water_pour=1733 +howl1=1734 +knock_knock=1735 +lycanthropy=1736 +rag_pour_vinegar=1737 +rag_boiling=1738 +rag_placelogs=1739 +rag_placepot=1740 +rag_put_in_pot=1741 +recruit_spade=1742 +RG_ghost_approach=1743 +RG_place_skull=1744 +RG_skeleton_attack=1745 +RG_skeleton_awake=1746 +crystal_tree_planting=1747 +royal_comedy_slip=1748 +royal_addrope=1749 +royal_build=1750 +royal_engine_chug=1751 +royal_engine_start=1752 +royal_footsteps=1753 +royal_steam=1754 +rumdeal_spirit_depart=1755 +deal_spirit_attack=1756 +deal_spirit_hit=1757 +kwamthulhu_walk=1758 +rumdeal_clank1=1759 +rumdeal_clank2=1760 +rumdeal_hiss1=1761 +rumdeal_hopper_1=1762 +rumdeal_pressurize=1763 +rumdeal_stuff_other=1764 +rumdeal_stuff_slugling=1765 +wrench_crush=1766 +hammer_and_build=1767 +brick_build=1768 +wall_destroy=1769 +hammering=1770 +log_down=1771 +oil_pour=1772 +bane_tolna_final_death=1773 +bane_attach_rope=1774 +bane_door_open=1775 +bane_fire_loop=1776 +bane_opening_close=1777 +bane_reaper_attack=1778 +bane_reaper_death=1779 +bane_reaper_hit=1780 +bane_summon_dragon=1781 +bane_tolna_attack=1782 +bane_tolna_death=1783 +bane_tolna_spit=1784 +bane_tolna_hit=1785 +swan_repair_wall=1786 +swan_kung_fu=1787 +swan_open_pot=1788 +swan_press=1789 +swan_rumble=1790 +swan_skeleton_rise=1791 +light_creature_down=1792 +collect_bad_tear=1793 +collect_good_tear=1794 +collect_tear=1795 +drink_and_magic=1796 +juna_hiss=1797 +light_creature_loop=1798 +light_creature_up=1799 +trek_bridge_placelog=1800 +trek_bog_leave=1801 +trek_bog_suck=1802 +trek_repair_bridge=1803 +trek_cutting=1804 +trek_heal_cast=1805 +trek_lasoo=1806 +trek_make_rope=1807 +trek_prod_firm=1808 +trek_prod_soft=1809 +trek_prod_suck=1810 +trek_tentacle_appear=1811 +trek_skin_snake=1812 +trek_swim_bog=1813 +trek_tentacle_head_appear=1814 +trek_walkaway=1815 +trek_walktoward=1816 +camelsnake=1817 +charmflute_a#=1818 +charmflute_a=1819 +charmflute_b=1820 +charmflute_c#=1821 +charmflute_c=1822 +charmflute_d#=1823 +charmflute_d=1824 +charmflute_e=1825 +charmflute_f#=1826 +charmflute_f=1827 +charmflute_g#=1828 +charmflute_g=1829 +charmflute_low_a#=1830 +charmflute_low_a=1831 +charmflute_low_b=1832 +charmflute_low_c#=1833 +charmflute_low_c=1834 +charmflute_low_d#=1835 +charmflute_low_d=1836 +charmflute_low_e=1837 +charmflute_low_f#=1838 +charmflute_low_f=1839 +charmflute_low_g#=1840 +charmflute_low_g=1841 +cudgel=1842 +drips=1843 +safeclang=1844 +safeclick=1845 +safeopen=1846 +snakehiss=1847 +golem_demondoor=1848 +golem_program=1849 +golem_repairclay=1850 +golem_teleport=1851 +turn_statue=1852 +parrotcall=1853 +kiss=1854 +penguin=1855 +writing=1856 +tradefloor_ore=1857 +leak=1858 +slide_puzzle=1859 +icegate_open=1860 +blizzard=1861 +windy=1862 +sled_start_longer=1863 +equip_sled=1864 +sled_jump=1865 +sled_loop=1866 +sled_loop2=1867 +sled_start=1868 +sled_stop=1869 +sledcrash=1870 +wax_sled=1871 +brew_conveyor_breaks=1872 +brew_collect_grubs=1873 +brew_conveyor=1874 +brew_release_pressure=1875 +brew_douse_flames=1876 +brew_drain_water=1877 +brew_fill_hopper=1878 +brew_monkey_climb=1879 +brew_monkey_combat=1880 +brew_monkey_talk=1881 +brew_monkeyclimb=1882 +brew_place_logs=1883 +brew_pump=1884 +brew_pump_single=1885 +brew_refuel_boiler=1886 +brew_refuel_empty=1887 +brew_strike_and_light=1888 +brew_repair_bridge=1889 +brew_repair_patch=1890 +brew_repair_pipe=1891 +brew_throw_coconut=1892 +twocats_shear=1893 +cut_coffin_vampire=1894 +garlic_grow=1895 +cutwrist=1896 +regular_vampire_appear=1897 +vampire_bats_appear=1898 +vampire_summon=1899 +wanted_scan=1900 +shotput_land=1901 +dust_hands=1902 +hiccup=1903 +warguild_animate_alive=1904 +shotput_spin_throw=1905 +shotput_step_throw=1906 +shotput_throw=1907 +take_shotput=1908 +warguild_animate=1909 +warguild_animator_activate=1910 +warguild_catapult_anvil=1911 +warguild_catapult=1912 +warguild_catapult_blades=1913 +warguild_catapult_ball=1914 +warguild_catapult_defend_anvil=1915 +warguild_catapult_defend_blades=1916 +warguild_catapult_defend_ball=1917 +warguild_catapult_defend_missile=1918 +warguild_catapult_missile=1919 +warguild_drop_barrels=1920 +warguild_drop_barrels_1=1921 +warguild_drop_barrels_2=1922 +warguild_dummies=1923 +warguild_dummies_down=1924 +warguild_dummies_up=1925 +warguild_iron_door_open=1926 +warguild_iron_door_push=1927 +warguild_take_barrel=1928 +warguild_take_barrel_grunt=1929 +smokepuff=1930 +smokepuff2=1931 +deathslide=1932 +bite=1933 +deathslide_first=1934 +deathslide_second=1935 +hurdle=1936 +skeletongoal=1937 +skullball_collide=1938 +skullball_roll=1939 +skullball_scratchy=1940 +skullball_tap=1941 +throw_stick=1942 +myq4_energy_2=1943 +Abo_hurt_2=1944 +myq4_energy_explosion=1945 +Abo_attack_1=1946 +Abo_drain_1=1947 +myq4_energy_1=1948 +Abo_attack_3=1949 +Abo_attack_2=1950 +Abo_attack_4=1951 +down_stone_stairs=1952 +bonewalk=1953 +ogre_destroy_barricade=1954 +drip_poison=1955 +up_stone_stairs=1956 +search_vine=1957 +zogre_writing=1958 +zogre_bell=1959 +adolescent_zygomite_attack=1960 +adolescent_zygomite_death=1961 +adolescent_zygomite_hit=1962 +zygo_grow=1963 +zygo_reload=1964 +zygo_spore_cast_and_fire=1965 +zygo_spore_impact=1966 +zygo_spray=1967 +zygomite_attack=1968 +zygomite_death=1969 +zygomite_hit=1970 +swordclash5=1971 +blade5=1972 +brassclash=1973 +dragon_shield=1974 +swordclash3=1975 +brassclash2=1976 +swordclash2=1977 +swordclash6=1978 +blade4=1979 +wood_armour3=1980 +eyeglo_creature_death=1981 +protect_items=1982 +eyeglo_creature_hit=1983 +bird_twitter_1=1984 +bird_twitter_2=1985 +bird_twitter_3=1986 +bird_twitter_4=1987 +bird_twitter_5=1988 +chick_cheep=1989 +cicadas_1=1990 +cicadas_2=1991 +crickets_1=1992 +crickets_2=1993 +croak_1=1994 +croak_2=1995 +croak_3=1996 +cuckoo_1=1997 +distant_bark_1=1998 +flapping_1=1999 +goblin_call_1=2000 +goblin_call_2=2001 +goblin_call_3=2002 +gull1=2003 +gull_1=2004 +gull_2=2005 +gull_3=2006 +gull_4=2007 +mosquitos_1=2008 +mosquitos_2=2009 +owl_part_1=2010 +owl_part_2=2011 +owl_part_3=2012 +peacock1=2013 +peacock2=2014 +pidgeon=2015 +screech_owl_1=2016 +screech_owl_2=2017 +toowit_1=2018 +warbler_1=2019 +warbler_2=2020 +bank_drawer=2021 +bank_bell=2022 +bank_shuffling_1=2023 +bank_locking=2024 +bank_shuffling_2=2025 +bank_stamp=2026 +bank_unlocking=2027 +battle_1=2028 +battle_2_troops=2029 +battle_1_test=2030 +battle_2=2031 +battle_4_terrorbird=2032 +battle_3_gnomes=2033 +battle_4_gnomes=2034 +battle_7_mediumfight=2035 +battle_5_birdkill=2036 +battle_6_archers=2037 +battle_7_smallfight=2038 +cave_collapse_1=2039 +cave_bats=2040 +cave_bubbling_loop_1=2041 +cave_growl_1=2042 +cave_insects_1=2043 +cave_insects_2=2044 +cave_rumbling_1=2045 +cave_rumbling_2=2046 +cave_rumbling_3=2047 +cave_rumbling_loop_1=2048 +cave_stalagtite_loop_1=2049 +stalagtite_drip=2050 +stalagtite_drip_2=2051 +stalagtite_drip_loop1=2052 +sheep_atmospheric1=2053 +clucks_1=2054 +clucks_2=2055 +cow_work=2056 +crows_1=2057 +crows_2=2058 +pig_call_1=2059 +pig_call_2=2060 +pig_call_3=2061 +sheep_atmospheric2=2062 +fire_crackling_fierce=2063 +fire_crackling_big=2064 +fire_crackling_small=2065 +fire_crackling_med=2066 +animal_growl_1=2067 +animal_growl_2=2068 +chipmunk=2069 +tree_creak_1=2070 +tree_creak_2=2071 +tree_creak_3=2072 +tree_rustle_1=2073 +tree_rustle_2=2074 +tree_wind_1=2075 +woodpecker=2076 +icy_wind_loop_1=2077 +icy_wind=2078 +icy_wind_loop_2=2079 +icy_wind_loop_3=2080 +wolfcall_1=2081 +wolfcall_2=2082 +jungle_ambience_loop=2083 +exotic_bird_1=2084 +exotic_bird_2=2085 +exotic_bird_3=2086 +exotic_bird_4=2087 +jungle_ambience_loop_1=2088 +jungle_insect_1=2089 +jungle_monkey_1=2090 +jungle_snake_1=2091 +kookaburra_1=2092 +parrot_1=2093 +parrot_2=2094 +warbler_3=2095 +hammer_and_smash=2096 +demolish_1=2097 +demolish_2=2098 +hammer_steel=2099 +hammer_stone=2100 +hammer_wood=2101 +hammering_1=2102 +hammering_2=2103 +hammering_3=2104 +sawing_1=2105 +sawing_2=2106 +snapwood_1=2107 +snapwood_2=2108 +thump_1=2109 +tidyup_1=2110 +tighten_1=2111 +coin_single_1=2112 +chopping=2113 +coins_jingle_1=2114 +coins=2115 +counting_coins_1=2116 +coins_jingle_2=2117 +coins_jingle_3=2118 +coins_jingle_4=2119 +market_ambience_1=2120 +morytania_creature_1=2121 +morytania_creature_2=2122 +morytania_creature_3=2123 +morytania_wind_loop_1=2124 +werewolf_call_1=2125 +werewolf_call_2=2126 +glass_break=2127 +glass_break2=2128 +glass_chink_1=2129 +glass_chink_2=2130 +glass_chink_3=2131 +pub_fillup=2132 +pub_jingle_1=2133 +pub_pourliquid=2134 +swamp_fart_1=2135 +swamp_fart_2=2136 +swamp_fart_3=2137 +swamp_gas=2138 +bubbling_low=2139 +bloop=2140 +underground_river_loop_1=2141 +bubbling_loop_1=2142 +bubbling_loop_2=2143 +bubbling_loop_3=2144 +bubbling_mid=2145 +bubbling_mid_loop=2146 +bubbling_stream_1=2147 +fish_splash=2148 +fountain_loop_1=2149 +fountain_loop_2=2150 +fountain_loop_3=2151 +high_drip=2152 +lapping_1=2153 +lapping_2=2154 +low_drip=2155 +mid2_drip=2156 +mid_drip=2157 +ocean_loop_1=2158 +ocean_loop_2=2159 +ocean_loop_3=2160 +ocean_wave1=2161 +ocean_wave2=2162 +ocean_wave3=2163 +ocean_wave4=2164 +ocean_wave5=2165 +river_loop_1=2166 +seashore_1=2167 +stream_loop_1=2168 +stream_loop_2=2169 +stream_loop_3=2170 +stream_loop_4=2171 +waterfall_loop_1=2172 +lava_flame_2=2173 +lava_flame=2174 +lava_gloop_loop_1=2175 +lava_flame_3=2176 +lava_gloop_loop_2=2177 +lava_gloop_loop_3=2178 +wilderness_wind_1=2179 +wilderness_wind_2=2180 +wolfcry_1=2181 +blustery_wind_loop_1=2182 +blustery_wind_loop_2=2183 +breeze_loop_1=2184 +breeze_loop_2=2185 +ocean_wind_1=2186 +ocean_wind_2=2187 +strong_wind_loop_1=2188 +fireplace_loop_1=2189 +ambient_bell_1=2190 +ambient_bell_2=2191 +bell=2192 +bell_peal_1=2193 +bubblin_loop=2194 +bubbling=2195 +bubbling4=2196 +bubbling_soup=2197 +cooking_loop_1=2198 +cooking_loop_2=2199 +cooking_loop_3=2200 +cosmic_star=2201 +droplet1=2202 +electric_drill=2203 +mid plop=2204 +fireplace_loop_2=2205 +foot_tramp_1=2206 +force_field_loop=2207 +furnace_loop_1=2208 +furnace_loop_2=2209 +furnace_loop_3=2210 +hi_plop=2211 +murmur_work=2212 +sea_bell_1=2213 +pop1=2214 +pop2=2215 +pour_sticky_liquid=2216 +sea_bell_2=2217 +sea_bell_3=2218 +windmill_blades_loop=2219 +spit_roast_loop=2220 +swamp=2221 +synth_crowd_1=2222 +tanning_vat=2223 +weak_distant_cry=2224 +windchimes_1=2225 +windmill_grindstones_loop=2226 +windmill_outside_loop=2227 +wood_creak_1=2228 +equip_axe=2229 +equip_elemental_staff=2230 +equip_banner=2231 +equip_baxe=2232 +equip_blunt=2233 +equip_body=2234 +equip_bolt=2235 +equip_hands=2236 +equip_feet=2237 +equip_fun=2238 +equip_metal_body=2239 +equip_helmet=2240 +equip_leather=2241 +equip_legs=2242 +equip_metal_legs=2243 +equip_ranged=2244 +equip_shield=2245 +equip_spiked=2246 +equip_staff=2247 +equip_sword=2248 +equip_whip=2249 +equip_wood=2250 +plate_break=2251 +human_roar=2252 +nethead=2253 +splitzombie_split=2254 +plate_spin=2255 +rubber_chicken_attack_faster=2256 +rubber_chicken_attack=2257 +scarekid=2258 +splitzombie_split_half=2259 +splitzombie_split_head=2260 +yoyo1=2261 +yoyo2=2262 +yoyo3=2263 +yoyo4=2264 +yoyo_wind=2265 +interface_select1=2266 +interface_wait=2267 +interface_wrong=2268 +interface_wrong2=2269 +twin_move_crane_loop=2270 +twin_crane_drop=2271 +twin_lower_crane=2272 +twin_move_crane=2273 +pillory_success=2274 +pillory_locked=2275 +pillory_unlock=2276 +pillory_wrong=2277 +pillartag_pinball=2278 +pinball_pillar1=2279 +pinball_pillar2=2280 +pinball_pillar3=2281 +pinball_pillar4=2282 +pinball_pillar5=2283 +troll_pinball=2284 +apple_splat=2285 +beehive_movepart=2286 +attach_handle=2287 +evil_chicken_attack=2288 +beehive_placepart=2289 +beehive_rotatepart=2290 +beehive_selectpart=2291 +candle_move=2292 +cat_into_hellcat=2293 +cavein=2294 +disgruntled_anvil=2295 +dryad_appear=2296 +dwarf_whistle=2297 +hypnotist_appear=2298 +gas_explosion=2299 +gas_hiss=2300 +genie_appear=2301 +hand_wave=2302 +piratechest_coins=2303 +knife_break=2304 +light_candle=2305 +lost_pickaxe=2306 +piratechest_turn=2307 +piratechest_unlock=2308 +quiz_correct=2309 +quiz_select=2310 +rake_breaks=2311 +sourhog_hit=2312 +sourhog_attack_ranged=2313 +sourhog_attack_melee=2314 +sourhog_death_cry=2315 +tanglevine_appear=2316 +sourhog_death_collapse=2317 +haloween_2020_pumpkin_head=2318 +tremor=2319 +triffid_appear=2320 +triffid_attack=2321 +uncooking=2322 +whirlpool=2323 +zombie_moan=2324 +ew2_extractor_loop2=2325 +ew2_dial_spin=2326 +dagganoth_plate_body_1=2327 +dagganoth_plate_body_2=2328 +dagganoth_plate_body_3=2329 +trailblazer_unlock_raise=2330 +trailblazer_unlock_twunkles=2331 +earth_wave_all=2332 +earth_wave_fail=2333 +dagganoth_plate_body_4=2334 +dagganoth_plate_body_5=2335 +fire_blast_all=2336 +dagganoth_range_body_1=2337 +dagganoth_range_body_2=2338 +dagganoth_range_body_3=2339 +fire_bolt_all=2340 +dagganoth_range_body_4=2341 +dagganoth_range_body_5=2342 +dagganoth_shell_body_1=2343 +trailblazer_unlock_power=2344 +dagganoth_shell_body_2=2345 +trailblazer_teleport_draw_symbol=2346 +dagganoth_shell_body_3=2347 +fire_wave_all=2348 +dagganoth_shell_body_4=2349 +fire_wave_fail=2350 +dagganoth_shell_body_5=2351 +guthan_breastplate_1=2352 +trailblazer_unlock_map=2353 +guthan_breastplate_2=2354 +guthan_breastplate_3=2355 +guthan_breastplate_4=2356 +guthan_breastplate_5=2357 +karil_spikebody_1=2358 +karil_spikebody_2=2359 +karil_spikebody_3=2360 +water_strike_fail=2361 +water_wave_all=2362 +water_wave_fail=2363 +karil_spikebody_4=2364 +karil_spikebody_5=2365 +torag_breastplate_1=2366 +torag_breastplate_2=2367 +torag_breastplate_3=2368 +torag_breastplate_4=2369 +torag_breastplate_5=2370 +verac_brassard1=2371 +drain=2372 +digsite_dig_pick=2373 +wind_wave_all=2374 +wind_wave_fail=2375 +digsite_dig_trowel=2376 +digsite_panning=2377 +panning=2378 +bigbang=2379 +bell1=2380 +destroy_object=2381 +biglever=2382 +break=2383 +burst=2384 +cavernous=2385 +disarm_trap_failure=2386 +disarm_trap=2387 +disease_hitsplat=2388 +doorslam=2389 +drink=2390 +drinkwork=2391 +drip_liquid=2392 +eat=2393 +errorsound=2394 +fill_glass=2395 +firework=2396 +trailblazer_teleport_flyaway=2397 +grim_reaper_appear=2398 +ice_troll_attack=2399 +lever=2400 +liquid=2401 +locked=2402 +lovely_lazer=2403 +trailblazer_teleport_spin=2404 +trailblazer_teleport_draw_line=2405 +bear_attack_undead_stomp_02=2406 +pick_lock=2407 +poison_hitsplat=2408 +scissors=2409 +scrape=2410 +silence=2411 +sizzle=2412 +small_cry=2413 +snap=2414 +strange_bird=2415 +bear_death_undead=2416 +turn_book_page=2417 +undead_appear=2418 +unlock=2419 +up_and_down_stairs=2420 +waterwheel_bubbes=2421 +waterwheel_loop=2422 +waterwheel_loop2=2423 +waterwheel_loop3=2424 +whiteout=2425 +bear_attack_undead_02=2426 +farming_compost=2427 +compost_close=2428 +compost_open=2429 +farming_amulet=2430 +farming_emptybarrel=2431 +farming_dibbing=2432 +farming_fillplantpot=2433 +farming_fill=2434 +farming_plant_scarecrow=2435 +farming_fillpot=2436 +farming_pick=2437 +farming_plantcure=2438 +farming_pourpint=2439 +farming_prune=2440 +farming_putin=2441 +farming_raking=2442 +farming_scoop=2443 +farming_sprinkle=2444 +farming_valve=2445 +farming_watering=2446 +fill_vat=2447 +pick_cactus=2448 +slice_watermelon=2449 +handholds_grab_to_second=2450 +balancing_ledge=2451 +climb_under=2452 +climb_wall=2453 +climbing_loop=2454 +fall_land=2455 +handholds_grab=2456 +handholds_grab2=2457 +jump_land_bridge=2458 +handholds_loop=2459 +handholds_off=2460 +jump=2461 +jump2=2462 +jump_and_fall=2463 +jump_blades=2464 +jump_further=2465 +monkeybars_loop=2466 +jump_no_land=2467 +jump_up=2468 +land_flat=2469 +log_balance=2470 +logtrap=2471 +pitfall_fall_half=2472 +monkeybars_off=2473 +monkeybars_on=2474 +pitfall2=2475 +pitfall_fall=2476 +springtrap_release=2477 +pitfall_open=2478 +plank_break=2479 +plankwalk=2480 +pressups=2481 +ropeclimb=2482 +ropeclimb_loop=2483 +runonspot=2484 +sidestep=2485 +situps=2486 +spear_jump=2487 +springtrap_reset=2488 +squeeze_in=2489 +squeeze_out=2490 +squeeze_thru_crack=2491 +star_jump=2492 +stumble_loop=2493 +swing_across=2494 +tightrope=2495 +watersplash=2496 +baxe_crush=2497 +baxe_slash=2498 +hacksword_crush=2499 +hacksword_slash=2500 +hacksword_stab=2501 +2H_crush=2502 +2H_slash=2503 +2H_stab=2504 +keris_crush=2505 +keris_slash=2506 +keris_stab=2507 +mace_crush=2508 +mace_stab=2509 +sword_hit=2510 +spiked_blackjack_crush=2511 +blackjack_crush=2512 +boxing_glove=2513 +broken_hatchet=2514 +crabclaw_stab=2515 +cudgel_2=2516 +farmersfork_stab=2517 +flower_attack=2518 +spanner_crush=2519 +tzhaar_ket_om_crush=2520 +weapon_miss=2521 +scythe_double=2522 +scythe_hit=2523 +scythe_slash=2524 +scythe_stab=2525 +sickle_slash=2526 +sickle_stab=2527 +chainshot=2528 +cleave=2529 +dragon_axe_thunder=2530 +clobber=2531 +clobber2=2532 +halberd_swipe=2533 +impale=2534 +neptune_blast=2535 +powershot=2536 +puncture=2537 +rampage=2538 +sanctuary=2539 +sever=2540 +shatter=2541 +shock=2542 +shock2=2543 +shove=2544 +snapshot=2545 +soulshot=2546 +stabsword_crush=2547 +stabsword_slash=2548 +stabsword_stab=2549 +bonespear_crush_testsound=2550 +bonespear_crush=2551 +staff_double_faster=2552 +bonespear_lunge=2553 +bonespear_stab=2554 +newstaff=2555 +staff_crush=2556 +staff_double=2557 +tzhaar_staff_crush=2558 +staff_faster=2559 +staff_hit=2560 +staff_lunge=2561 +staff_stab=2562 +wand_crush=2563 +human_attack=2564 +unarmed_kick=2565 +unarmed_punch=2566 +warhammer_crush=2567 +wood_sword_crush=2568 +wood_armour1=2569 +wood_armour2=2570 +wood_armour_2=2571 +wood_sword_slash=2572 +wood_sword_stab=2573 +churn=2574 +hopperlever=2575 +fill_grain=2576 +fry=2577 +spit_roasting=2578 +millstones=2579 +oven=2580 +pick=2581 +pick2=2582 +pour_tea=2583 +sand_bucket=2584 +attach_orb=2585 +chisel=2586 +loom_weave=2587 +pottery=2588 +smash_gem=2589 +spinning=2590 +stiching=2591 +stitching=2592 +stringing=2593 +strike_and_light=2594 +bunsen_burner=2595 +fire_lit=2596 +flint=2597 +fuse_light=2598 +tinderbox_strike=2599 +fishing_cast=2600 +fish_swim=2601 +lavacast=2602 +net=2603 +fletch_once=2604 +fletch=2605 +string_bow=2606 +dragon_potion_finished=2607 +grind=2608 +tap_fill=2609 +vial_empty=2610 +vial_mix=2611 +vial_mix_smokepuff=2612 +vial_pour=2613 +vialpour=2614 +well_fill=2615 +eagle_flap_loop=2616 +crow_1=2617 +eagle_cry=2618 +hunting_bigcat_jump=2619 +eagle_flap_loop2=2620 +eagle_fly=2621 +eagle_flyaway=2622 +hunting_butterflynet=2623 +hunting_birdcall=2624 +hunting_birdcaught=2625 +hunting_birdtrap=2626 +hunting_boxtrap=2627 +noose_wand=2628 +lasoo=2629 +hunting_collapsebranches=2630 +hunting_deadfall=2631 +hunting_dismantle=2632 +hunting_falcon_fly=2633 +hunting_falcon_swoop=2634 +hunting_jump=2635 +hunting_layboxtrap=2636 +hunting_noose=2637 +hunting_pitfall_collapse=2638 +hunting_placebranches=2639 +hunting_placeleaves=2640 +hunting_placeleaves2=2641 +hunting_release_butterfly=2642 +hunting_search=2643 +hunting_set_twitchnet=2644 +hunting_setdeadfall=2645 +hunting_setnoose=2646 +hunting_setsnare=2647 +hunting_smokepuff_escape=2648 +hunting_takebranches=2649 +hunting_takeleaves=2650 +hunting_tease_feline=2651 +hunting_twitchnet=2652 +hunting_twitchnet_smoke=2653 +hunting_twitchnet_smoke2=2654 +found_gem=2655 +mine=2656 +mine_3=2657 +mine_5=2658 +mine_quick=2659 +mining_3=2660 +prospect=2661 +improved_reflexes=2662 +cancel_prayer=2663 +clarity=2664 +eagle_eye=2665 +hawk_eye=2666 +incredible_reflexes=2667 +mystic_lore=2668 +mystic_might=2669 +mystic_will=2670 +prayer_boost=2671 +prayer_drain=2672 +prayer_off=2673 +prayer_recharge=2674 +protect_from_magic=2675 +protect_from_melee=2676 +protect_from_missiles=2677 +rapid_heal=2678 +rapid_restore=2679 +redemption=2680 +redemption_heal=2681 +retribution=2682 +retribution_test=2683 +rock_skin=2684 +sharp_eye=2685 +smite=2686 +steel_skin=2687 +strength_burst=2688 +superhuman_strength=2689 +thick_skin=2690 +ultimate_strength=2691 +arrow_launch=2692 +arrowlaunch2=2693 +bonehit=2694 +crossbow=2695 +dart=2696 +flashpowder=2697 +grease_hit=2698 +javelin=2699 +longbow=2700 +outofammo=2701 +shortbow=2702 +slayer_arrow=2703 +throw_grease=2704 +throw_grease2=2705 +throwingaxe=2706 +throwingknife=2707 +thrown=2708 +abyssal_squeezethrough=2709 +bind_runes=2710 +boil_burst=2711 +slayer_statuemove=2712 +energydrain=2713 +granite_maul=2714 +quicksmash=2715 +slayer_throwbucket=2716 +slayerdoors=2717 +slayerdoors_close=2718 +sprinkle_salt=2719 +whip=2720 +anvil_4=2721 +anvil=2722 +anvil2=2723 +glassblowing=2724 +furnace=2725 +new_anvil=2726 +stunned=2727 +canoe_paddle_loop=2728 +build_canoe=2729 +woodchop_quick=2730 +canoe_roll=2731 +canoe_sink=2732 +remove_axe=2733 +tree_fall=2734 +woodchop=2735 +woodchop_4=2736 +anothercry=2737 +bones_down=2738 +put_down=2739 +bear_hit_undead_02=2740 +bear_attack_undead_stomp=2742 +harpiebugswarm_attack=2743 +harpiebugswarm_death=2744 +harpiebugswarm_hit=2745 +swordclash6_1=2746 +swordclash6_2=2747 +swordclash6_3=2748 +swordclash6_4=2749 +swordclash6_5=2750 +blade4_1=2751 +blade4_2=2752 +blade4_3=2753 +blade4_4=2754 +blade4_5=2755 +wood_armour3_1=2756 +wood_armour3_2=2757 +wood_armour3_3=2758 +wood_armour3_4=2759 +wood_armour3_5=2760 +sword_hit2_mail_1=2761 +sword_hit2_mail_2=2762 +sword_hit2_mail_3=2763 +sword_hit2_mail_4=2764 +sword_hit2_mail_5=2765 +sword_hit2_1=2766 +sword_hit2_2=2767 +sword_hit2_3=2768 +sword_hit2_4=2769 +sword_hit2_5=2770 +steel_mail_1=2771 +steel_1=2772 +steel_mail_2=2773 +steel_mail_3=2774 +steel_mail_4=2775 +steel_mail_5=2776 +steel_2=2777 +steel_3=2778 +steel_4=2779 +steel_5=2780 +big_bar_mail_1=2781 +big_bar_1=2782 +big_bar_2=2783 +big_bar_3=2784 +big_bar_4=2785 +big_bar_mail_2=2786 +big_bar_mail_3=2787 +big_bar_mail_4=2788 +big_bar_mail_5=2789 +big_bar_5=2790 +dragon_armour_1=2791 +dragon_armour_2=2792 +dragon_armour_3=2793 +dragon_armour_4=2794 +dragon_armour_5=2795 +dragon_mail_1=2796 +dragon_mail_2=2797 +dragon_mail_3=2798 +dragon_mail_4=2799 +dragon_mail_5=2800 +blade3_mail_1=2801 +blade3_mail_2=2802 +blade3_mail_3=2803 +blade3_mail_4=2804 +blade3_mail_5=2805 +blade3_1=2806 +blade3_2=2807 +blade3_3=2808 +blade3_4=2809 +blade3_5=2810 +leather_hit_1=2811 +leather_hit_2=2812 +leather_hit_3=2813 +leather_hit_4=2814 +leather_hit_5=2815 +steel2_mail_1=2816 +steel2_mail_2=2817 +steel2_mail_3=2818 +steel2_mail_4=2819 +steel2_mail_5=2820 +steel2_1=2821 +steel2_2=2822 +steel2_3=2823 +steel2_4=2824 +steel2_5=2825 +swordclash3_mail_1=2826 +swordclash3_mail_2=2827 +swordclash3_mail_3=2828 +swordclash3_mail_4=2829 +swordclash3_mail_5=2830 +swordclash3_1=2831 +swordclash3_2=2832 +swordclash3_3=2833 +swordclash3_4=2834 +swordclash3_5=2835 +blade2_mail_1=2836 +blade2_mail_2=2837 +blade2_mail_3=2838 +blade2_mail_4=2839 +blade2_mail_5=2840 +blade2_1=2841 +blade2_2=2842 +blade2_3=2843 +blade2_4=2844 +blade2_5=2845 +stone_armour4=2846 +stone_armour5=2847 +brassclash_1=2848 +brassclash_2=2849 +brassclash_3=2850 +brassclash_4=2851 +brassclash_5=2852 +brassclash2_1=2853 +brassclash2_2=2854 +brassclash2_3=2855 +brassclash2_4=2856 +brassclash2_5=2857 +sos_through_door=2858 +swordclash2_1=2859 +swordclash2_2=2860 +swordclash2_3=2861 +swordclash2_4=2862 +swordclash2_5=2863 +cosmic_entity_death=2864 +cosmic_entity_hit=2865 +fairy_death=2866 +gorak_attack=2867 +gorak_death=2868 +gorak_hit=2869 +FT_fairy_appear=2870 +FT_fairyrings=2871 +FT_shooting_star=2872 +FT_starflower_die=2873 +FT_starflower_grow=2874 +dreamland_globes=2875 +mcannon_setup=2876 +mcannon_turn=2877 +underwater_macro_bubbles=2878 +lunar_bake_pie=2879 +lunar_cast_1=2880 +lunar_cast=2881 +lunar_cure_group=2882 +lunar_cast_2=2883 +lunar_cure=2884 +lunar_energy_transfer=2885 +lunar_cure_other=2886 +lunar_cure_other2=2887 +lunar_embue_runes=2888 +lunar_cure_other_individual=2889 +lunar_flax_to_bowstring=2890 +lunar_fertilize=2891 +lunar_heal_other_individual=2892 +lunar_heal=2893 +lunar_heal_group=2894 +lunar_heal_other=2895 +lunar_heatglass=2896 +lunar_stat_share_individual=2897 +lunar_initial_casting=2898 +lunar_stat_share=2899 +lunar_statheal_other=2900 +lunar_strength_share=2901 +lunar_strength_share2=2902 +lunar_string_amulet=2903 +lunar_strength_share_individual=2904 +lunar_string_amulet2=2905 +lunar_transfer_other=2906 +lunar_vengence=2907 +lunar_vengence_other=2908 +lunar_watering=2909 +armour_piercing=2910 +blood_sacrifice=2911 +clear_mind=2912 +crossbow_diamond=2913 +down_to_earth=2914 +dragons_breath=2915 +earths_fury=2916 +life_leech=2917 +lucky_lightning=2918 +magical_poison=2919 +sea_curse=2920 +enchanted_tipping=2921 +fletch_crossbow=2922 +flight_feathers=2923 +string_crossbow=2924 +tipping=2925 +mining_loop=2926 +mining_8=2927 +crossbow_grappling=2928 +crossbow_grapple_splash=2929 +fanfare=2930 +eyeglo_crystal_axe=2931 +eyeglo_crystal_axe_crush=2932 +eyeglo_crystal_axe_slash=2933 +eyeglo_damage_machine_1=2934 +eyeglo_damage_machine_2=2935 +eyeglo_damage_machine_low=2936 +eyeglo_destroy_machine=2937 +eyeglo_fluffy_evil_cry=2938 +eyeglo_mind_meld=2939 +eyeglo_repair_machine=2940 +eyeglo_thunder=2941 +eyeglo_tortoise_appear=2942 +eyeglo_transform=2943 +eyeglo_tree_reveal=2944 +eyeglo_treesplit_lightning=2945 +wood_armour4=2946 +wood_armour5=2947 +swordclash5_1=2948 +swordclash5_2=2949 +swordclash5_3=2950 +swordclash5_4=2951 +swordclash5_5=2952 +blade5_1=2953 +blade5_2=2954 +blade5_3=2955 +blade5_4=2956 +blade5_5=2957 +dragon_shield_1=2958 +dragon_shield_2=2959 +dragon_shield_3=2960 +dragon_shield_4=2961 +dragon_shield_5=2962 +granite_shield_1=2963 +granite_shield_2=2964 +granite_shield_3=2965 +granite_shield_4=2966 +granite_shield_5=2967 +crystal_armour_5=2968 +man_hole_close=2969 +swinging_sign_rusty=2970 +DS_crystal_ball_anim=2971 +DS_big_door_unlock=2972 +DS_bone_spell=2973 +DS_break_table=2974 +DS_crystal_ball_end=2975 +DS_crystal_ball_start=2976 +DS_cupboard_appear=2977 +DS_cupboard_dissappear=2978 +DS_cupboard_fall=2979 +DS_delrith_appear=2980 +DS_delrith_banished=2981 +DS_drain=2982 +DS_key_fall=2983 +DS_portal_close=2984 +DS_portal_open=2985 +DS_replace_table=2986 +DS_summon_demon=2987 +DS_table_explosion=2988 +DS_wally_sword=2989 +equip_silverlight=2990 +vampire_arrives=2991 +vampire_flap_loop=2992 +vampire_flies_away=2993 +vampire_transform=2994 +m3_climb_down_shelves=2995 +m3_climb_shelves=2996 +m3_climb_up_shelves=2997 +m3_mine_jas_ore=2998 +m3_place_ore=2999 +m3_push_boat=3000 +m3_repair=3001 +snare_impact=3002 +snare_cast_and_fire=3003 +stun_cast_and_fire=3004 +stun_impact=3005 +telegrab_cast_and_fire=3006 +telegrab_hit=3007 +vulnerability_impact=3008 +vulnerability_cast_and_fire=3009 +weaken_hit=3010 +weaken_cast_and_fire=3011 +zap_impact=3012 +leak_1=3013 +leak_2=3014 +leak_3=3015 +leak_4=3016 +leak_5=3017 +grail_bell=3018 +seaslug_hit=3019 +slug_crane_turn_and_lower=3020 +slug_crane_turn=3021 +slug_fisherman_attack=3022 +slug_dry_sticks=3023 +slug_kick_panel=3024 +slug_scoop_slug=3025 +slug_smear_paste=3026 +slug_torch_attack=3027 +slug_torch_lit=3028 +slug2_light_flash=3029 +slug2_bigdoor=3030 +slug2_teleport_fail=3031 +slug2_place_rune=3032 +slug2_rumbling=3033 +slug_prince_attack=3034 +slug_prince_death=3035 +slug_prince_hit=3036 +woodchop1=3037 +woodchop2=3038 +woodchop3=3039 +woodchop4=3040 +woodchop5=3041 +woodchop6=3042 +troll_champion_sword_attack=3043 +cow_atmospheric=3044 +bee_loop_1=3045 +bees_1=3046 +bird_twitter_6=3047 +crickets_slow=3048 +croak_slow=3049 +cave_rumbling_loop_quieter=3050 +cave_bubble_1=3051 +cave_bubble_2=3052 +cave_bubble_3=3053 +cave_bubble_4=3054 +cave_bubble_5=3055 +cluck_1=3056 +cluck_2=3057 +cluck_3=3058 +cluck_4=3059 +cluck_5=3060 +tree_wind_loop=3061 +human_chatter_1=3062 +human_chatter_2=3063 +human_chatter_3=3064 +human_chatter_4=3065 +human_chatter_5=3066 +human_chatter_6=3067 +human_cry_1=3068 +human_cry_2=3069 +human_cry_3=3070 +human_laugh_1=3071 +human_laugh_2=3072 +gas_loop_1=3073 +aquarium=3074 +air_bubbles_loop_1=3075 +air_bubbles_loop_2=3076 +bubbling_loop_4=3077 +bubbling_stream_2=3078 +drain_loop_1=3079 +high_drip_2=3080 +high_drip_3=3081 +leak_loop_1=3082 +ocean_gentle=3083 +ocean_gentle_1=3084 +ocean_gentle_2=3085 +ocean_gentle_3=3086 +rock_pool_loop=3087 +trickle_1=3088 +underwater_loop_1=3089 +lava_fire_loop_1=3090 +breeze_loop_3=3091 +breeze_loop_4=3092 +cave_wind_loop=3093 +coastal_wind_loop=3094 +swamp_wind_loop=3095 +windy_loop_1=3096 +abyss_1=3097 +abyss_2=3098 +abyss_3=3099 +abyss_4=3100 +rat_scuttle=3101 +rat_squeak_1=3102 +rat_squeak_2=3103 +rat_squeak_3=3104 +desert_animal_1=3105 +desert_animal_2=3106 +desert_wind_1=3107 +desert_wind_2=3108 +desert_wind_loop=3109 +rattlesnake_1=3110 +rattlesnake_2=3111 +vulture_1=3112 +vulture_2=3113 +cow_wheel=3114 +cauldron_loop_1=3115 +bubblin_loop_2=3116 +bubbling_vat_1=3117 +bubbling_vials=3118 +deal_control_shake=3119 +clock_tick_1=3120 +rat_wheel=3121 +rain_1=3122 +deserttreasure_wall_crusher=3123 +flag_flutter_1=3124 +flag_flutter_2=3125 +flag_flutter_3=3126 +flag_flutter_4=3127 +furnace_chimney_loop=3128 +heartbeat=3129 +heartbeat_breathing=3130 +light_beam_loop_1=3131 +lighthouse_loop=3132 +machine_loop_1=3133 +magic_tree_loop=3134 +magic_tree_loop_2=3135 +magic_tree_loop_3=3136 +musical_tree=3137 +pendulum_swing_loop=3138 +portal_loop_1=3139 +rune_altar_ambience=3140 +rune_temple_ambience=3141 +steam_loop_1=3142 +stone_grind_loop=3143 +stone_grinding_loop_1=3144 +wheel_loop_1=3145 +whetstone_grind=3146 +windchimes_work=3147 +elem_bg_steam_1=3148 +ew2_ambient_loop=3149 +ew2_machine_loop=3150 +tol_wolf_whistle=3151 +elem_bg_steam_2=3152 +big_bellows_loop=3153 +elem_bg_rumble_1=3154 +elem_bg_rumble_2=3155 +elem_bg_steam_3=3156 +elem_boiler_loop=3157 +tainted_shot=3158 +upass_bridgefall=3159 +flint1=3160 +flint2=3161 +flint3=3162 +flint4=3163 +flint5=3164 +flint6=3165 +ew2_extractor_operation=3166 +ew2_cart_loop=3167 +ew2_cool_bar=3168 +ew2_crane_lower=3169 +ew2_crane_turn=3170 +ew2_extractor_loop=3171 +ew2_mind_electrocute=3172 +ew2_extractor_zap=3173 +ew2_fanblade=3174 +ew2_machine_rumble=3175 +ew2_mind_control=3176 +ew2_place_bar=3177 +ew2_place_cog=3178 +ew2_place_pipe=3179 +ew2_press_bar=3180 +ew2_remove_pipe=3181 +ew2_screw_turn=3182 +ew2_water_flow=3183 +ew2_water_rack=3184 +ew2_water_valve=3185 +king_troll_hit=3186 +troll_armour=3187 +troll_with_stone_shield_hit=3188 +giant_roc_approaches=3189 +giant_roc_appear=3190 +giant_roc_boulder_attack=3191 +giant_roc_death=3192 +giant_roc_flap_attack=3193 +giant_roc_hit=3194 +giant_roc_peck_attack=3195 +my_arm_sealoop_finish=3196 +my_arm_sealoop=3197 +myarm_bubbling_cauldren=3198 +myarm_armour_thrown=3199 +myarm_male_scream=3200 +myarm_flyback=3201 +myarm_leprechaun_scared=3202 +myarm_patchgrown=3203 +myarm_pick_goutweed=3204 +myarm_roc_akka=3205 +myarm_roc_akka_once=3206 +myarm_roc_squeek=3207 +myarm_sealoop=3208 +myarm_spatula=3209 +myarm_tear_bush=3210 +myarm_troll_jumping=3211 +TT_winching_loop=3212 +TT_bend_bars=3213 +TT_cart_loop=3214 +TT_down_stairs=3215 +TT_fall_back=3216 +TT_knocking=3217 +TT_squeeze_out=3218 +TT_up_stairs=3219 +mine1=3220 +mine2=3221 +mine3=3222 +mine4=3223 +mine5=3224 +mine6=3225 +skill_light_candle=3226 +equip_halloween_pumpkin=3227 +equip_halloween_spray=3228 +Abo_hurt_1=3229 +tob_xarpus_exhumes_open=3230 +tob_xarpus_exhume_health_shots=3231 +tob_nylocas_range_death_bang=3232 +tob_sotetseg_redspiral_grid_playercollision=3233 +tob_maiden_shadow_attack_part_2=3234 +tob_verzik_vampire_spawn=3235 +halloween_ghost_attack=3236 +halloween_ghost_death=3237 +halloween_ghost_hit=3238 +zep_air_escape_fast=3239 +zep_air_blast=3240 +zep_air_blast_interface=3241 +zep_air_escape_slow=3242 +zep_balloon_burns=3243 +zep_balloon_crash=3244 +zep_balloon_float=3245 +zep_balloon_move=3246 +zep_breeze=3247 +zep_construct=3248 +zep_drop_ballast=3249 +zep_hammering_1=3250 +zep_use_logs=3251 +pop3=3252 +fishing_cast1=3253 +fishing_cast2=3254 +fishing_cast3=3255 +fishing_cast4=3256 +fishing_cast5=3257 +fishing_cast6=3258 +hunting_laymagicboxtrap=3259 +hunting_take_creature=3260 +imp_cleaver_attack=3261 +imp_knife_attack=3262 +lambcall1=3263 +ram_attack2=3264 +watchtower_machine=3265 +watchtower_dragon_attack=3266 +watchtower_make_relic=3267 +watchtower_shaman_cry=3268 +watchtower_smokepuff=3269 +watchtower_spell_cast=3270 +watchtower_spell_hit=3271 +anma_chicken_grab_2=3272 +anma_adorn_amulet=3273 +anma_axe_bounce=3274 +anma_chicken_catch=3275 +anma_chicken_grab=3276 +anma_equip_chicken_sack=3277 +anma_craft_container=3278 +anma_interface_button=3279 +anma_hammer_iron=3280 +anma_polish_buttons=3281 +anma_magnet=3282 +anma_puzzle_complete=3283 +equip_backpack=3284 +equip_jester=3285 +tob_sotetseg_death=3286 +gublinch_make_snowball=3287 +tob_bloat_jar_bgsound_loop=3288 +tob_magic_death_bang=3289 +tob_xarpus_attack_ranged_projectile_5=3290 +tob_pillar_hit=3291 +gublinch_hit=3292 +tob_maiden_shadow_attack=3293 +tob_nylocas_deathdetonate_shriek=3294 +gublinch_snowball=3295 +barbassault_atomic=3296 +barbassault_build=3297 +barbassault_build_trapdoor=3298 +barbassault_egg_dipping=3299 +barbassault_egglauncher=3300 +barbassault_fire_egg=3301 +barbassault_horn=3302 +barbassault_lay_egg=3303 +barbassault_load_egg=3304 +barbassault_poison=3305 +barbassault_smash=3306 +barbassault_spikes=3307 +barbassault_splat=3308 +barbassault_stun=3309 +barbassault_vending=3310 +penance_spawn_attack=3311 +hatchet_skeleton_attack=3312 +warhammer_skeleton_attack=3313 +mace_skeleton_attack=3314 +lotr_ghost_hit=3315 +lotr_click=3316 +lotr_random_bang=3317 +lotr_logtrap=3318 +lotr_random_skeleton=3319 +lotr_random_bark=3320 +lotr_random_metal=3321 +lotr_tarn_castandfire=3322 +lotr_random_slam=3323 +lotr_random_stone=3324 +lotr_summon_armour=3325 +lotr_terrordog_attack=3326 +lotr_tarn_impact=3327 +lotr_terrordog_death=3328 +lotr_terrordog_explode=3329 +lotr_terrordog_hit=3330 +lotr_trans_attack=3331 +lotr_trans_death=3332 +lotr_trans_hit=3333 +lotr_trans_speak=3334 +lotr_trans_speak1=3335 +lotr_trans_speak2=3336 +lotr_trans_speak3=3337 +lotr_trans_speak4=3338 +lotr_trans_speak5=3339 +lotr_trans_speak6=3340 +lotr_trans_speak7=3341 +lotr_trans_speak8=3342 +lotr_trans_speak9=3343 +lotr_trans_spell=3344 +lotr_trans_walk=3345 +lotr_transmute=3346 +lotr_zombie_attack=3347 +lotr_zombie_death=3348 +lotr_zombie_hit=3349 +skeletal_gorilla_attack=3350 +skeletal_gorilla_death=3351 +skeletal_gorilla_hit=3352 +peng_antimagic_bgsound=3353 +human_into_penguin=3354 +peng_machine_bgsound=3355 +peng_block_move=3356 +peng_fall_snow=3357 +peng_icicle_fall=3358 +peng_jump_slip=3359 +peng_lathe_bgsound=3360 +peng_rumble_bgsound=3361 +peng_penguin_call=3362 +peng_penguin_flap=3363 +peng_penguincall_1=3364 +peng_penguincall_2=3365 +peng_penguincall_3=3366 +peng_penguincall_4=3367 +peng_spinninglight_bgsound=3368 +peng_sled_forward=3369 +peng_sled_jump=3370 +peng_slip_snow=3371 +penguin_into_human=3372 +icelord_attack2=3373 +icelord_attack=3374 +icelord_death=3375 +icelord_hit=3376 +slip_up=3377 +yak_attack=3378 +yak_death=3379 +yak_hit=3380 +barbarian_grunt_attack=3381 +barbarian_grunt_death=3382 +barbarian_grunt_hit=3383 +FI_bell_work=3384 +FI_bell=3385 +FI_dripping=3386 +FI_clap=3387 +FI_fighting_closer=3388 +FI_fighting=3389 +FI_jester_dance_5=3390 +FI_footsteps=3391 +FI_jester_bow=3392 +FI_jester_clap=3393 +FI_jester_juggle_loop=3394 +FI_jester_jangle=3395 +FI_jester_jig=3396 +FI_jester_jig_loop=3397 +FI_jester_juggle=3398 +FI_jester_skip_loop=3399 +FI_jester_talk_stick=3400 +FI_jester_throwpie=3401 +FI_jesterstick=3402 +FI_rock_hit=3403 +FI_steel=3404 +FI_trollking_roar=3405 +coins_jingle_5=3406 +osman_pick_high=3407 +osman_drips=3408 +ghost_dog_attack=3409 +ghost_dog_death=3410 +ghost_dog_hit=3411 +ghost_sword_crush=3412 +ghost_sword_slash=3413 +ghost_sword_stab=3414 +severed_leg_attack=3415 +severed_leg_drop=3416 +tol_creature_appear=3417 +tol_break_cage=3418 +tol_door_open_and_close=3419 +tol_fix_cage=3420 +tol_fix_machine=3421 +tol_homonculus_appear=3422 +tol_homonculus_boo=3423 +tol_homonculus_crying=3424 +tol_liquid_flow=3425 +tol_long_wolf_whistle=3426 +tol_low_hum=3427 +tol_magic_explosions=3428 +tol_move_pipe=3429 +tol_newtroost_attack=3430 +tol_newtroost_death=3431 +tol_newtroost_hit=3432 +tol_place_pipe=3433 +tol_pumping_liquid=3434 +tol_rooster_synth=3435 +tol_valve=3436 +tol_whistle_dance=3437 +tol_whistle_runescape=3438 +tol_wolf_whistle2=3439 +whirlpool_loop=3440 +brain_barrelchest_attack=3453 +brain_anchor_attack=3454 +brain_barrelchest_normal_attack=3455 +brain_barrelchest_death=3456 +brain_barrelchest_hit=3457 +brain_pull_statue=3458 +brain_idea=3459 +brain_barrelchest_special_attack=3460 +brain_boat_sound_1=3461 +brain_boat_sound_2=3462 +brain_boat_sound_3=3463 +brain_boat_sound_4=3464 +brain_boat_sound_5=3465 +brain_clockwork_cat=3466 +brain_creaky_ship=3467 +brain_creaky_ship_2=3468 +brain_explosion=3469 +brain_fuse_burn=3470 +brain_fuse_light=3471 +brain_zombie_underwater_attack=3472 +brain_special_brine_saber=3473 +brain_whistle=3474 +brain_zombie_pirate_attack=3475 +brain_zombie_pirate_death=3476 +brain_zombie_pirate_hit=3477 +new_brain_zombie_underwater_attack=3478 +brain_zombie_underwater_death=3479 +brain_zombie_underwater_hit=3480 +anchor_sunder=3481 +ramble_nailbeast_attack=3482 +ramble_ghast_birth=3483 +ramble_nailbeast_death=3484 +ramble_nailbeast_hit=3485 +ramble_sploosh=3486 +treevillage_catabow_hit=3487 +treevillage_catabow_launch=3488 +giantcavebug_attack=3489 +giantcavebug_death=3490 +giantcavebug_hit=3491 +molanisk_attack=3492 +molanisk_death=3493 +molanisk_hit=3494 +dorg_machine_loop_bgsound=3495 +dorg_artifact_teleport=3496 +dorg_boiler_loop=3497 +dorg_break_part=3498 +dorg_bulb_pop=3499 +dorg_catch=3500 +dorg_clap=3501 +dorg_conductor_coil=3502 +dorg_crossbow_grapple=3503 +dorg_kick_ball=3504 +dorg_machine_loop=3505 +dorg_machine_spool=3506 +dorg_pat=3507 +dorg_remove_part=3508 +dorg_repair_bulb=3509 +dorg_spitroast=3510 +dorg_take_wire=3511 +dorg_zapper=3512 +dorg_zapper_bgsound=3513 +goblin_warhammer_attack=3514 +goblin_axe_attack=3515 +goblin_guard_attack=3516 +goblin_hit_shield=3517 +goblin_knife_attack=3518 +goblin_shield=3519 +goblin_spear_attack=3520 +goblin_staff_attack=3521 +slayer_molanisk_bell=3522 +surok_destroy_letter=3523 +surok_bindwand=3524 +surok_equip_ring=3525 +surok_mine_statue=3526 +surok_jump=3527 +surok_mindcontrol_impact=3528 +surok_mindcontrol_cast=3529 +surok_mindcontrol_spell=3530 +surok_monkspell=3531 +surok_outlaw_death=3532 +surok_outlaw_hit=3533 +surok_pickaxe_swing=3534 +surok_smash_statue=3535 +surok_spellfail=3536 +surok_teleport=3537 +surok_teleport_cast_only=3538 +tob_sotetseg_attack_ranged=3539 +tob_sotetseg_attack_melee_4=3540 +tob_xarpus_idle_wingflap_1=3541 +tob_verzik_vampire_death=3542 +tob_verzik_spark_1=3543 +tob_bloat_flies_attack_1=3544 +tob_bloat_shout=3545 +tob_nylocas_web_spawn=3546 +tob_maiden_blood_impact=3547 +tob_xarpus_fly_up_forward_wings_4=3548 +tob_xarpus_death_screech=3549 +tob_nylocas_deathdetonate_spinning_3=3550 +olaf2_brinesabre_slash=3551 +olaf2_brinesabre_stab=3552 +olaf2_fall_into_cave=3553 +olaf2_roll_boulder=3554 +olaf2_splash=3555 +olaf2_ulfric_rise=3556 +twocats_fry_noob=3557 +goblin_crowd_calls2=3558 +goblin_arrow_death=3559 +goblin_bolt_death=3560 +goblin_crowd=3561 +goblin_crowd2=3562 +goblin_crowd3=3563 +goblin_crowd4=3564 +goblin_crowd_calls=3565 +slice_sphere_teleport=3566 +goblin_crowd_cheer=3567 +goblin_crowd_loop=3568 +goblin_crowd_loop2=3569 +goblin_crowd_loop3=3570 +goblin_crowd_loop4=3571 +goblin_crowd_loop5=3572 +slice_arrow_hit=3573 +slice_bow_attack=3574 +slice_brush=3575 +slice_crossbow=3576 +slice_fire_arrow=3577 +slice_flare=3578 +slice_human_fall=3579 +slice_ladder=3580 +slice_mace_slash=3581 +slice_train_approach=3582 +slice_train=3583 +slice_train_journey=3584 +slice_train_arrive=3585 +slice_train_depart=3586 +slice_zanik_ladygoblin_hit=3587 +slice_train_old=3588 +slice_untie_zanic=3589 +slice_zanik_ladygoblin_attack=3590 +slice_zanik_ladygoblin_death=3591 +goblin_mace=3592 +vm_rockpick=3593 +vm_brush=3594 +vm_brush_1=3595 +vm_brush_2=3596 +vm_rockpick_1=3597 +vm_rockpick_2=3598 +vm_rockpick_3=3599 +mine_ore=3600 +atjun_medium_monkey=3601 +atjun_easy_parrot=3602 +atjun_hard_lion=3603 +small_spider_attack=3604 +big_spider_attack=3605 +big_spider_death=3606 +big_spider_hit=3607 +small_spider_death=3608 +small_spider_hit=3609 +scorpion_death=3610 +scorpion_attack=3611 +scorpion_hit=3612 +lunar_change_spellbook=3613 +lunar_humidify=3614 +lunar_hunter_kit=3615 +lunar_hunter_kit_inv=3616 +lunar_make_plank=3617 +lunar_npc_contact=3618 +lunar_sleep=3619 +lunar_stat_spy=3620 +lunar_stat_spy_impact=3621 +dream_everlasting_attack=3622 +dream_burrow_down=3623 +dream_burrow_up=3624 +dream_everlasting_death=3625 +dream_everlasting_hit=3626 +dream_heartbeat=3627 +dream_illusive_attack=3628 +dream_illusive_death=3629 +dream_illusive_hit=3630 +dream_inadequacy_attack=3631 +dream_inadequacy_death=3632 +dream_inadequacy_hit=3633 +dream_razorbeast_attack=3634 +dream_razorbeast_death=3635 +dream_razorbeast_hit=3636 +dream_squish_illusive=3637 +dream_untouchable_attack=3638 +dream_untouchable_death=3639 +dream_untouchable_hit=3640 +dream_whiteout=3641 +vm_barrier_open=3642 +vm_all_correct=3643 +vm_bg_digsite_cleaning=3644 +vm_bg_cleaning=3645 +vm_drop_plank=3646 +vm_camel=3647 +vm_correct=3648 +vm_dragon=3649 +vm_displaycase_open=3650 +vm_empty_wheelbarrow=3651 +vm_footsteps_ambience=3652 +vm_gain_kudos=3653 +vm_incorrect=3654 +vm_kalphite=3655 +vm_leech=3656 +vm_lizard=3657 +vm_mechanism_1=3658 +vm_mechanism_2=3659 +vm_mole_burrow_down=3660 +vm_mole_burrow_up=3661 +vm_monkey=3662 +vm_penguin=3663 +vm_push_button=3664 +vm_seaslug=3665 +vm_snail=3666 +vm_snake=3667 +vm_terrorbird=3668 +vm_tortoise=3669 +vm_wheelbarrow_squeek=3670 +vm_wyvern=3671 +drill_bgsound=3672 +lathe_bgsound=3673 +grim_giant_attack=3674 +grim_beanstalk_shrinking=3675 +grim_beanstalk_fall=3676 +grim_beanstalk_grow=3677 +grim_drink_shrinking_potion=3678 +grim_bgsound_cloudbreeze=3679 +grim_experiment2_attack=3680 +grim_experiment2_death=3681 +grim_experiment2_hit=3682 +grim_experiment2_range=3683 +grim_giant_death=3684 +grim_giant_hit=3685 +grim_giant_roar=3686 +grim_giant_taunt=3687 +grim_grimgnash_attack=3688 +grim_mouse_attack=3689 +grim_mouse_death=3690 +grim_mouse_hit=3691 +grim_piano_a4=3692 +grim_piano_a5=3693 +grim_piano_b4=3694 +grim_piano_b5=3695 +grim_piano_c4=3696 +grim_piano_c5=3697 +grim_piano_d4=3698 +grim_piano_d5=3699 +grim_piano_e4=3700 +grim_piano_e5=3701 +grim_piano_f4=3702 +grim_piano_f5=3703 +grim_piano_g4=3704 +grim_piano_g5=3705 +grim_potion_wears_off=3706 +grim_scared_gnome_1=3707 +grim_scared_gnome_2=3708 +grim_sewer_water=3709 +grim_throw_gnomehead=3710 +grim_wolf=3711 +grim_wolf2=3712 +grim_wolf3=3713 +grim_wolf_growl=3714 +dog_attack=3717 +dog_death=3718 +dog_hit=3719 +ii_clock_tick=3720 +ii_breeze=3721 +ii_impling_spawn=3722 +ii_imp_disgust=3723 +ii_imp_fail=3724 +ii_imp_kick=3725 +ii_jar_generator=3726 +ii_longwave=3727 +ii_push_thru_wheat=3728 +ii_wheat_growing=3729 +ii_wheat_wilt=3730 +darkbow_doublefire=3731 +darkbow_doublefire_new=3732 +darkbow_dragon_attack=3733 +darkbow_fire=3734 +darkbow_impact=3735 +darkbow_shadow_attack=3736 +darkbow_shadow_impact=3737 +equip_darkbow=3738 +dragonslayer_bgsound_magicdoor=3739 +dragonslayer_absorb_fire=3740 +dragonslayer_burningfire=3741 +dragonslayer_crash_ship=3742 +dragonslayer_cutoffhead=3743 +dragonslayer_cutoffhead1=3744 +dragonslayer_cutoffhead2=3745 +dragonslayer_demon_attack=3746 +dragonslayer_demon_death=3747 +dragonslayer_demon_hit=3748 +dragonslayer_dragonball=3749 +dragonslayer_dragonbreath=3750 +dragonslayer_dragonscream=3751 +dragonslayer_dragonstomp3=3752 +dragonslayer_dragonwalk=3753 +dragonslayer_flapwings=3754 +dragonslayer_ghost_attack=3755 +dragonslayer_ghost_death=3756 +dragonslayer_ghost_hit=3757 +dragonslayer_magicdoor=3758 +dragonslayer_melzar_spell=3759 +dragonslayer_shield_empty=3760 +dragonslayer_shieldfire=3761 +dragonslayer_thunder=3762 +dragonslayer_zombie_attack=3763 +dragonslayer_zombie_death=3764 +dragonslayer_zombie_hit=3765 +string_bow_pluck_string=3766 +string_bow_pull_string=3767 +string_bow_tension_string=3768 +string_bow_tie_string=3769 +anvil01=3770 +anvil02=3771 +waterfiend_death=3772 +waterfiend_hit=3773 +waterfiend_attack=3774 +remove_axe2=3775 +brutal_jump_into_whirlpool=3776 +brutal_hand_fishing=3777 +brutal_hand_mining_2=3778 +brutal_woodchop=3779 +brutal_hand_mining=3780 +brutal_hand_mining_1=3781 +brutal_fire_cloak_steam=3782 +brutal_decant=3783 +brutal_pulloutfish=3784 +brutal_bow_fire_2=3785 +brutal_bow_firemaking=3786 +brutal_bow_fire_1=3787 +brutal_hand_in_water=3788 +anvil05=3789 +anvil_single_1=3790 +anvil_single_2=3791 +anvil06=3792 +anvil03=3793 +anvil04=3794 +pog_mutated_terror_bird_attack=3795 +pog_mutated_terror_bird_death=3796 +pog_mutated_terror_bird_hit=3797 +goblin_snore2=3798 +goblin_snore=3799 +observatory_screwdriver=3800 +observatory_fix_lens=3801 +observatory_hammer=3802 +observatory_goblin_spit=3803 +observatory_planets=3804 +patterns_rockingchair=3805 +patterns_chair_tap_forward=3806 +patterns_chair_tap_backward=3807 +patterns_slamdesk=3808 +patterns_turncard=3809 +patterns_shuffle_desk=3810 +pest_portal_shield_down=3811 +pest_portal_shield=3812 +town_crier_ring_bell_up=3813 +town_crier_ring_bell=3814 +town_crier_ring_bell_up-old=3815 +town_crier_scratch_head=3816 +town_crier_ring_bell_down=3817 +town_crier_ring_bell_down-old=3818 +kr_check_lock=3819 +kr_bgsound_writing=3820 +kr_smash_window=3821 +kr_judge_hammer=3822 +kr_pick_lock=3823 +kr_jury_whisper=3824 +kr_piety=3825 +kr_chivalry=3826 diff --git a/dumps/530/anim-skeleton-gfx-relations.txt b/dumps/530/anim-skeleton-gfx-relations.txt new file mode 100644 index 0000000..4c600e1 --- /dev/null +++ b/dumps/530/anim-skeleton-gfx-relations.txt @@ -0,0 +1,11216 @@ +Base: 0 +Linked animations: [3, 5, 13, 14, 15, 70, 71, 87, 88, 173, 226, 227, 228, 329, 330, 331, 346, 347, 352, 356, 363, 364, 365, 376, 377, 378, 379, 380, 381, 382, 383, 385, 386, 387, 388, 389, 390, 391, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 406, 407, 409, 410, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 440, 451, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 582, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 642, 645, 654, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 748, 749, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 791, 792, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 904, 905, 906, 908, 909, 910, 911, 915, 916, 918, 919, 920, 921, 923, 929, 931, 1026, 1034, 1035, 1036, 1037, 1056, 1057, 1058, 1060, 1062, 1064, 1067, 1068, 1074, 1077, 1078, 1084, 1100, 1105, 1106, 1110, 1113, 1114, 1115, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1128, 1129, 1130, 1131, 1132, 1133, 1137, 1144, 1145, 1146, 1147, 1148, 1156, 1157, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1191, 1192, 1193, 1194, 1195, 1196, 1203, 1205, 1206, 1207, 1208, 1209, 1210, 1236, 1237, 1238, 1239, 1240, 1241, 1248, 1249, 1252, 1258, 1263, 1264, 1265, 1266, 1267, 1268, 1275, 1280, 1306, 1307, 1309, 1318, 1319, 1320, 1321, 1322, 1323, 1324, 1325, 1326, 1327, 1328, 1329, 1330, 1331, 1332, 1333, 1335, 1336, 1337, 1350, 1351, 1352, 1353, 1354, 1363, 1364, 1365, 1366, 1367, 1368, 1369, 1370, 1371, 1374, 1375, 1379, 1407, 1408, 1409, 1421, 1422, 1423, 1424, 1425, 1426, 1427, 1428, 1429, 1440, 1441, 1457, 1458, 1459, 1460, 1461, 1462, 1463, 1464, 1465, 1466, 1467, 1468, 1469, 1470, 1471, 1472, 1473, 1481, 1482, 1483, 1484, 1485, 1486, 1487, 1499, 1500, 1501, 1502, 1504, 1505, 1506, 1507, 1508, 1509, 1510, 1511, 1514, 1515, 1516, 1517, 1531, 1544, 1548, 1550, 1551, 1552, 1559, 1560, 1563, 1565, 1567, 1572, 1575, 1601, 1602, 1603, 1604, 1605, 1606, 1633, 1634, 1638, 1648, 1649, 1650, 1651, 1652, 1653, 1654, 1655, 1658, 1659, 1660, 1661, 1662, 1663, 1664, 1665, 1666, 1667, 1670, 1671, 1672, 1673, 1705, 1722, 1723, 1724, 1725, 1728, 1734, 1739, 1740, 1743, 1744, 1745, 1746, 1755, 1762, 1763, 1764, 1765, 1766, 1767, 1768, 1769, 1770, 1771, 1772, 1809, 1810, 1811, 1816, 1818, 1819, 1820, 1830, 1831, 1832, 1833, 1834, 1835, 1836, 1837, 1850, 1851, 1852, 1871, 1872, 1877, 1878, 1879, 1880, 1894, 1895, 1897, 1902, 1903, 1904, 1905, 1906, 1907, 1914, 1950, 1952, 1953, 1954, 1955, 1972, 1978, 1979, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 2009, 2010, 2033, 2034, 2036, 2037, 2040, 2041, 2042, 2043, 2044, 2045, 2046, 2047, 2048, 2049, 2050, 2059, 2060, 2061, 2062, 2063, 2064, 2065, 2066, 2067, 2068, 2074, 2075, 2076, 2077, 2078, 2079, 2080, 2081, 2082, 2092, 2093, 2094, 2095, 2096, 2097, 2098, 2105, 2106, 2107, 2108, 2109, 2110, 2111, 2112, 2113, 2127, 2128, 2139, 2140, 2141, 2142, 2143, 2144, 2145, 2146, 2147, 2148, 2149, 2163, 2164, 2171, 2239, 2240, 2241, 2242, 2243, 2244, 2245, 2246, 2247, 2248, 2249, 2250, 2251, 2252, 2253, 2254, 2255, 2256, 2257, 2258, 2259, 2261, 2262, 2263, 2267, 2269, 2270, 2271, 2272, 2273, 2274, 2275, 2276, 2277, 2278, 2279, 2280, 2281, 2282, 2283, 2284, 2285, 2286, 2288, 2289, 2290, 2291, 2292, 2293, 2295, 2304, 2305, 2306, 2311, 2313, 2316, 2317, 2318, 2319, 2320, 2321, 2322, 2323, 2324, 2325, 2326, 2332, 2333, 2334, 2338, 2339, 2340, 2343, 2376, 2377, 2378, 2382, 2383, 2384, 2385, 2386, 2387, 2388, 2389, 2390, 2393, 2394, 2400, 2401, 2403, 2409, 2410, 2411, 2413, 2414, 2420, 2421, 2422, 2423, 2424, 2425, 2426, 2427, 2428, 2429, 2430, 2431, 2432, 2433, 2441, 2442, 2443, 2450, 2553, 2554, 2555, 2556, 2557, 2561, 2562, 2563, 2565, 2566, 2569, 2570, 2572, 2573, 2574, 2575, 2576, 2577, 2578, 2579, 2580, 2581, 2582, 2583, 2584, 2585, 2586, 2588, 2589, 2590, 2591, 2592, 2593, 2594, 2595, 2614, 2661, 2692, 2693, 2695, 2696, 2697, 2698, 2700, 2701, 2702, 2710, 2712, 2713, 2716, 2717, 2720, 2721, 2724, 2726, 2727, 2728, 2741, 2750, 2751, 2752, 2753, 2754, 2755, 2756, 2757, 2758, 2759, 2760, 2761, 2762, 2763, 2764, 2769, 2770, 2771, 2779, 2780, 2781, 2782, 2783, 2784, 2785, 2786, 2787, 2788, 2791, 2793, 2794, 2795, 2796, 2797, 2798, 2799, 2800, 2801, 2810, 2811, 2812, 2813, 2815, 2816, 2817, 2818, 2819, 2820, 2829, 2831, 2833, 2835, 2837, 2838, 2839, 2840, 2843, 2844, 2845, 2846, 2847, 2876, 2879, 2880, 2881, 2888, 2890, 2891, 2902, 2903, 2909, 2910, 2911, 2912, 2913, 2914, 2920, 2921, 2922, 2923, 2924, 2925, 2926, 2927, 2928, 2929, 2930, 2933, 2937, 2938, 2939, 2940, 2941, 2953, 2967, 2968, 2972, 2984, 2985, 2986, 2987, 2988, 2991, 2992, 2993, 2994, 2995, 2999, 3000, 3001, 3002, 3003, 3004, 3005, 3006, 3007, 3032, 3036, 3039, 3040, 3041, 3042, 3043, 3044, 3045, 3053, 3054, 3055, 3056, 3057, 3058, 3059, 3060, 3061, 3062, 3063, 3064, 3065, 3066, 3067, 3068, 3069, 3071, 3090, 3091, 3094, 3102, 3103, 3108, 3109, 3110, 3115, 3116, 3128, 3129, 3130, 3131, 3132, 3133, 3134, 3135, 3136, 3137, 3140, 3141, 3142, 3143, 3157, 3170, 3171, 3175, 3176, 3177, 3178, 3181, 3182, 3184, 3185, 3186, 3187, 3191, 3192, 3194, 3195, 3238, 3239, 3240, 3243, 3254, 3255, 3256, 3257, 3265, 3266, 3269, 3270, 3271, 3272, 3274, 3275, 3276, 3277, 3278, 3279, 3280, 3281, 3282, 3283, 3284, 3285, 3286, 3287, 3288, 3289, 3290, 3291, 3292, 3293, 3294, 3295, 3296, 3297, 3298, 3299, 3300, 3301, 3302, 3303, 3324, 3325, 3326, 3327, 3334, 3335, 3337, 3338, 3339, 3340, 3341, 3342, 3348, 3353, 3356, 3358, 3359, 3360, 3361, 3362, 3363, 3364, 3365, 3366, 3367, 3368, 3369, 3370, 3371, 3372, 3373, 3374, 3375, 3396, 3397, 3399, 3415, 3416, 3417, 3418, 3419, 3420, 3421, 3422, 3423, 3450, 3451, 3452, 3461, 3471, 3475, 3495, 3496, 3497, 3543, 3544, 3547, 3550, 3551, 3552, 3553, 3555, 3557, 3563, 3564, 3565, 3566, 3571, 3572, 3592, 3593, 3594, 3595, 3596, 3597, 3598, 3599, 3600, 3602, 3603, 3605, 3606, 3608, 3609, 3611, 3621, 3622, 3623, 3624, 3625, 3626, 3627, 3630, 3634, 3635, 3636, 3639, 3640, 3641, 3645, 3649, 3651, 3652, 3653, 3654, 3655, 3656, 3657, 3658, 3659, 3660, 3661, 3662, 3663, 3664, 3665, 3666, 3667, 3668, 3669, 3670, 3671, 3672, 3673, 3674, 3675, 3676, 3677, 3678, 3679, 3680, 3683, 3684, 3685, 3686, 3687, 3688, 3689, 3690, 3691, 3692, 3693, 3694, 3695, 3696, 3697, 3701, 3702, 3703, 3704, 3705, 3719, 3734, 3735, 3739, 3740, 3741, 3745, 3747, 3804, 3806, 3807, 3838, 3839, 3844, 3845, 3846, 3855, 3857, 3859, 3860, 3861, 3862, 3863, 3865, 3866, 3873, 3926, 3931, 3945, 3950, 3970, 3971, 3972, 3973, 3996, 3997, 3999, 4001, 4003, 4004, 4018, 4019, 4023, 4024, 4028, 4029, 4030, 4031, 4036, 4043, 4044, 4045, 4046, 4047, 4048, 4049, 4050, 4051, 4052, 4053, 4054, 4055, 4056, 4057, 4058, 4059, 4060, 4061, 4062, 4063, 4064, 4065, 4066, 4067, 4068, 4070, 4071, 4073, 4074, 4075, 4076, 4077, 4078, 4079, 4080, 4081, 4082, 4083, 4084, 4085, 4086, 4087, 4088, 4089, 4090, 4091, 4092, 4093, 4094, 4095, 4096, 4097, 4098, 4099, 4100, 4101, 4102, 4103, 4104, 4105, 4106, 4107, 4108, 4109, 4110, 4111, 4112, 4113, 4114, 4115, 4116, 4117, 4136, 4141, 4142, 4143, 4144, 4145, 4146, 4147, 4148, 4149, 4150, 4151, 4152, 4153, 4154, 4166, 4167, 4168, 4169, 4170, 4171, 4172, 4173, 4174, 4175, 4177, 4178, 4179, 4180, 4181, 4182, 4183, 4184, 4185, 4188, 4189, 4190, 4191, 4192, 4193, 4194, 4195, 4196, 4197, 4198, 4199, 4200, 4207, 4208, 4209, 4226, 4227, 4228, 4230, 4238, 4250, 4254, 4255, 4256, 4257, 4258, 4275, 4276, 4278, 4280, 4282, 4283, 4285, 4293, 4316, 4329, 4330, 4340, 4341, 4342, 4343, 4344, 4345, 4348, 4349, 4350, 4352, 4365, 4366, 4367, 4368, 4369, 4370, 4371, 4378, 4379, 4380, 4381, 4382, 4400, 4401, 4402, 4406, 4409, 4410, 4411, 4412, 4413, 4424, 4425, 4426, 4427, 4428, 4429, 4430, 4432, 4433, 4434, 4435, 4436, 4437, 4438, 4439, 4440, 4441, 4442, 4454, 4455, 4456, 4457, 4458, 4459, 4460, 4462, 4464, 4465, 4466, 4467, 4468, 4470, 4471, 4479, 4480, 4481, 4482, 4483, 4484, 4485, 4486, 4487, 4488, 4489, 4490, 4491, 4492, 4493, 4494, 4495, 4496, 4497, 4498, 4499, 4500, 4501, 4502, 4503, 4504, 4505, 4506, 4507, 4508, 4509, 4510, 4511, 4512, 4513, 4514, 4515, 4516, 4517, 4518, 4519, 4520, 4521, 4522, 4523, 4524, 4525, 4526, 4527, 4528, 4529, 4530, 4531, 4532, 4533, 4534, 4540, 4544, 4546, 4547, 4549, 4551, 4552, 4553, 4558, 4581, 4586, 4591, 4592, 4593, 4594, 4596, 4597, 4598, 4602, 4603, 4604, 4605, 4606, 4607, 4611, 4612, 4613, 4614, 4615, 4617, 4632, 4633, 4634, 4636, 4637, 4639, 4640, 4641, 4643, 4645, 4646, 4682, 4709, 4710, 4712, 4713, 4718, 4719, 4720, 4721, 4722, 4723, 4724, 4726, 4727, 4728, 4731, 4750, 4757, 4758, 4759, 4760, 4761, 4762, 4763, 4764, 4765, 4766, 4771, 4772, 4779, 4780, 4785, 4786, 4787, 4788, 4790, 4791, 4793, 4794, 4795, 4797, 4804, 4806, 4807, 4809, 4824, 4825, 4826, 4834, 4835, 4838, 4839, 4841, 4847, 4848, 4849, 4850, 4851, 4852, 4853, 4855, 4857, 4858, 4859, 4861, 4862, 4863, 4873, 4874, 4884, 4885, 4905, 4909, 4937, 4939, 4941, 4943, 4945, 4947, 4949, 4951, 4953, 4955, 4957, 4959, 4961, 4963, 4965, 4967, 4969, 4973, 4975, 4977, 4979, 4981, 5006, 5015, 5037, 5038, 5039, 5040, 5041, 5042, 5043, 5046, 5047, 5048, 5049, 5050, 5051, 5052, 5054, 5056, 5057, 5059, 5063, 5067, 5074, 5075, 5078, 5079, 5080, 5083, 5088, 5103, 5108, 5140, 5142, 5146, 5147, 5148, 5149, 5150, 5151, 5152, 5153, 5155, 5158, 5160, 5161, 5162, 5163, 5164, 5165, 5166, 5167, 5168, 5206, 5207, 5208, 5209, 5210, 5211, 5212, 5213, 5215, 5216, 5217, 5236, 5243, 5244, 5245, 5246, 5247, 5248, 5249, 5250, 5251, 5252, 5253, 5254, 5255, 5256, 5257, 5258, 5259, 5293, 5298, 5299, 5300, 5311, 5312, 5313, 5315, 5316, 5349, 5352, 5354, 5355, 5361, 5362, 5363, 5364, 5365, 5366, 5367, 5368, 5369, 5370, 5371, 5372, 5373, 5374, 5375, 5376, 5377, 5378, 5379, 5383, 5384, 5400, 5407, 5416, 5417, 5418, 5419, 5428, 5429, 5436, 5438, 5439, 5440, 5441, 5442, 5443, 5444, 5471, 5472, 5473, 5474, 5475, 5476, 5524, 5525, 5602, 5606, 5607, 5608, 5609, 5611, 5620, 5633, 5637, 5713, 5714, 5716, 5718, 5732, 5746, 5748, 5749, 5752, 5753, 5754, 5755, 5756, 5759, 5760, 5761, 5762, 5763, 5776, 5777, 5778, 5796, 5799, 5800, 5812, 5814, 5815, 5816, 5817, 5818, 5819, 5821, 5822, 5823, 5827, 5845, 5846, 5853, 5860, 5862, 5863, 5864, 5865, 5866, 5867, 5868, 5869, 5870, 5907, 6063, 6064, 6066, 6067, 6068, 6075, 6076, 6083, 6085, 6086, 6087, 6095, 6096, 6098, 6099, 6100, 6101, 6102, 6103, 6104, 6106, 6111, 6112, 6113, 6118, 6122, 6124, 6128, 6129, 6130, 6131, 6132, 6143, 6146, 6147, 6197, 6198, 6209, 6213, 6217, 6280, 6281, 6282, 6283, 6284, 6285, 6286, 6287, 6288, 6289, 6290, 6291, 6292, 6293, 6294, 6295, 6296, 6297, 6298, 6299, 6300, 6301, 6303, 6304, 6305, 6361, 6362, 6363, 6364, 6365, 6366, 6367, 6378, 6379, 6380, 6381, 6382, 6383, 6384, 6385, 6386, 6387, 6388, 6389, 6390, 6391, 6392, 6393, 6394, 6395, 6396, 6397, 6398, 6399, 6400, 6401, 6402, 6403, 6404, 6405, 6406, 6407, 6408, 6409, 6424, 6425, 6459, 6462, 6464, 6465, 6468, 6469, 6478, 6479, 6480, 6486, 6487, 6488, 6489, 6490, 6525, 6526, 6527, 6528, 6529, 6530, 6531, 6532, 6554, 6584, 6592, 6593, 6594, 6595, 6600, 6601, 6603, 6605, 6606, 6608, 6609, 6610, 6611, 6616, 6631, 6632, 6633, 6634, 6649, 6650, 6651, 6654, 6655, 6657, 6658, 6659, 6660, 6661, 6662, 6663, 6664, 6665, 6671, 6672, 6673, 6674, 6675, 6676, 6677, 6678, 6679, 6680, 6681, 6682, 6683, 6684, 6685, 6686, 6687, 6688, 6689, 6695, 6696, 6700, 6702, 6703, 6704, 6705, 6706, 6707, 6708, 6709, 6710, 6711, 6712, 6713, 6714, 6715, 6716, 6717, 6718, 6719, 6720, 6723, 6724, 6738, 6739, 6740, 6741, 6742, 6743, 6744, 6745, 6746, 6747, 6748, 6749, 6750, 6751, 6752, 6753, 6754, 6755, 6756, 6757, 6758, 6814, 6816, 6820, 6838, 6839, 6840, 6841, 6842, 6843, 6844, 6845, 6846, 6847, 6848, 6849, 6863, 6864, 6865, 6866, 6867, 6887, 6896, 6897, 6912, 6913, 6914, 6915, 6918, 6919, 6922, 6923, 6926, 6927, 6928, 6929, 6933, 6935, 6939, 6940, 6941, 6978, 6979, 6988, 6989, 6990, 6991, 6992, 6993, 6994, 6997, 6998, 6999, 7000, 7001, 7002, 7003, 7004, 7005, 7023, 7039, 7040, 7041, 7042, 7043, 7044, 7045, 7046, 7047, 7048, 7049, 7050, 7070, 7071, 7072, 7073, 7074, 7078, 7081, 7082, 7084, 7088, 7095, 7096, 7112, 7113, 7139, 7151, 7181, 7182, 7183, 7184, 7185, 7186, 7187, 7188, 7189, 7190, 7191, 7192, 7193, 7194, 7195, 7196, 7197, 7198, 7199, 7200, 7201, 7202, 7203, 7211, 7227, 7228, 7230, 7232, 7253, 7261, 7264, 7265, 7266, 7267, 7268, 7269, 7270, 7271, 7272, 7273, 7274, 7275, 7276, 7277, 7299, 7301, 7302, 7303, 7304, 7307, 7321, 7363, 7364, 7365, 7366, 7368, 7369, 7376, 7377, 7383, 7392, 7523, 7524, 7528, 7529, 7530, 7531, 7532, 7533, 7534, 7538, 7578, 7579, 7597, 7598, 7599, 7627, 7628, 7629, 7633, 7640, 7650, 7652, 7660, 7745, 7774, 7892, 8136, 8137, 8496, 8497, 8498, 8499, 8500, 8501, 8502, 8525, 8527, 8528, 8529, 8651, 8681, 8682, 8683, 8684, 8685, 8686, 8687, 8688, 8690, 8691, 8692, 8693, 8694, 8695, 8698, 8699, 8701, 8702, 8704, 8705, 8707, 8709, 8710, 8711, 8736, 8767, 8768, 8770, 8778, 8779, 8780, 8781, 8782, 8783, 8784, 8804, 8805, 8820, 8821, 8829, 8830, 8831, 8832, 8833, 8834, 8835, 8836, 8837, 8838, 8839, 8840, 8841, 8842, 8846, 8847, 8848, 8849, 8858, 8859, 8860, 8861, 8862, 8863, 8864, 8865, 8866, 8867, 8868, 8869, 8870, 8871, 8872, 8873, 8874, 8875, 8876, 8877, 8878, 8879, 8901, 8902, 8903, 8904, 8905, 8906, 8907, 8908, 8909, 8939, 8941, 8943, 8953, 8954, 8973, 8975, 8976, 8977, 8978, 8979, 8980, 8981, 8982, 8983, 8984, 8985, 8986, 8987, 8988, 8989, 8990, 8991, 8996, 8997, 8998, 8999, 9000, 9001, 9002, 9003, 9004, 9012, 9013, 9016, 9018, 9021, 9022, 9023, 9024, 9025, 9031, 9032, 9039, 9040, 9044, 9045, 9047, 9048, 9049, 9050, 9051, 9052, 9053, 9054, 9055, 9057, 9058, 9059, 9060, 9061, 9062, 9063, 9064, 9065, 9068, 9069, 9070, 9071, 9072, 9073, 9074, 9086, 9087, 9091, 9092, 9095, 9096, 9097, 9098, 9099, 9100, 9104, 9105, 9109, 9110, 9111, 9119, 9121, 9136, 9141, 9151, 9152, 9212, 9213, 9214, 9215, 9216, 9217, 9218, 9219, 9220, 9221, 9222, 9223, 9224, 9226, 9227, 9304, 9305, 9306, 9307, 9308, 9309, 9310, 9350, 9359, 9360, 9361, 9362, 9363, 9364, 9365, 9366, 9367, 9368, 9429, 9497, 9498, 9499, 9502, 9503, 9504, 9516, 9521, 9523, 9526, 9534, 9535, 9536, 9537, 9542, 9544, 9547, 9549, 9551, 9552, 9553, 9554, 9555, 9557, 9558, 9561, 9562, 9565, 9566, 9568, 9570, 9571, 9572, 9573, 9575, 9579, 9583, 9587, 9588, 9591, 9595, 9596, 9597, 9598, 9599, 9600, 9601, 9602, 9603, 9604, 9605, 9606, 9607, 9608, 9609, 9610, 9622, 9623, 9625, 9627, 9629, 9631, 9633, 9635, 9637, 9648, 9649, 9676, 9677, 9678, 9679, 9680, 9685, 9686, 9687, 9688, 9689, 9690, 9691, 9692, 9693, 9694, 9695, 9696, 9697, 9698, 9699, 9700, 9701, 9702, 9703, 9704, 9705, 9706, 9707, 9708, 9709, 9710, 9711, 9712, 9713, 9714, 9715, 9716, 9717, 9718, 9721, 9724, 9725, 9726, 9727, 9728, 9729, 9730, 9734, 9735, 9736, 9738, 9739, 9754, 9755, 9756, 9868, 9869, 9870, 9872, 9873, 9874, 9875, 9876, 9879, 9880, 9883, 9884, 9885, 9886, 9907, 9908, 9935, 9936, 9937, 9938, 9939, 9940, 9941, 9942, 9943, 9944, 9945, 9946, 9947, 9948, 9949, 9950, 9951, 9952, 9953, 9954, 9955, 9956, 9957, 9958, 9959, 9960, 9961, 9962, 9976, 9977, 9978, 9984, 9986, 9988, 9990, 9992, 9993, 9994, 9995, 9996, 9997, 9998, 9999, 10000, 10001, 10002, 10003, 10004, 10005, 10006, 10007, 10008, 10009, 10010, 10011, 10012, 10013, 10014, 10015, 10016, 10017, 10018, 10019, 10020, 10021, 10022, 10023, 10044, 10045, 10069, 10070, 10071, 10072, 10073, 10074, 10075, 10076, 10077, 10078, 10080, 10081, 10082, 10100, 10101, 10102, 10103, 10104, 10105, 10106, 10107, 10108, 10109, 10110, 10111, 10112, 10113, 10114, 10115, 10119, 10132, 10172, 10173, 10180, 10182, 10184, 10186, 10202, 10210, 10211, 10212, 10213, 10222, 10223, 10224, 10225, 10226, 10227, 10228, 10246, 10247, 10248, 10249, 10250, 10251, 10252, 10253, 10254, 10255, 10256, 10257, 10258, 10260, 10261, 10262, 10265, 10266, 10267, 10268, 10269, 10270, 10271, 10288, 10289, 10290, 10291, 10292, 10293, 10294, 10295, 10296, 10297, 10298, 10299, 10300, 10301, 10303, 10305, 10312, 10313, 10335, 10336, 10337, 10338, 10339, 10340, 10341, 10342, 10343, 10344, 10345, 10346, 10347, 10348, 10355, 10374, 10377, 10416, 10417, 10418, 10434, 10435, 10436, 10452, 10453, 10454, 10455, 10456, 10457, 10458, 10459, 10466, 10467, 10468, 10470, 10471, 10473, 10475, 10476, 10477, 10478, 10482, 10483, 10485, 10490, 10491, 10492, 10493, 10494, 10495, 10498, 10499, 10501, 10502, 10503, 10504, 10505, 10513, 10516, 10518, 10524, 10530, 10532, 10534, 10535, 10537, 10538, 10542, 10543, 10544, 10545, 10546, 10550, 10551, 10564, 10565, 10566, 10567, 10568, 10569, 10570, 10571, 10572, 10573, 10574, 10575, 10576, 10577, 10578, 10579, 10580, 10583, 10584, 10587, 10588, 10589, 10590, 10602, 10603, 10604, 10605, 10606, 10607, 10608, 10609, 10610, 10611, 10612, 10613, 10614, 10615, 10616, 10617, 10618, 10619, 10620, 10621, 10622, 10623, 10627, 10646, 10647, 10650, 10651, 10653, 10654, 10662, 10663, 10704, 10705, 10706, 10709, 10711, 10715, 10716, 10717, 10718, 10719, 10720, 10721, 10722, 10724, 10725, 10726, 10727, 10728, 10729, 10730, 10731, 10732, 10733, 10734, 10735, 10737, 10738, 10739, 10740, 10741, 10742, 10743, 10744, 10745, 10747, 10749, 10753, 10755, 10756, 10758, 10768, 10793, 10794, 10795, 10796, 10797, 10798, 10799, 10800, 10801, 10822, 10823, 10824, 10825, 10830, 10836, 10841, 10842, 10843, 10844, 10845, 10846, 10847, 10848, 10849, 10850, 10851, 10852, 10853, 10854, 10855, 10856, 10857, 10858, 10865, 10866, 10867, 10868, 10869, 10870, 10871, 10872, 10873, 10876, 10881, 10883, 10885, 10886, 10887, 10898, 10899, 10913, 10914, 10915, 10916, 10961, 10963, 10968, 10969, 10970, 10971, 10972, 10973, 10974, 10975, 10977, 10980, 10981, 10982, 10987, 10988, 10990, 10992, 10993, 10994, 10995, 11007, 11008, 11010, 11011, 11013, 11019, 11020, 11021, 11022, 11023, 11024, 11025, 11026, 11028, 11029, 11030, 11031, 11033, 11041, 11042, 11043, 11044, 11048, 11051, 11052, 11053, 11057, 11060, 11061, 11062, 11063, 11064, 11065, 11066, 11067, 11068, 11069, 11070, 11071, 11088, 11089, 11091, 11141, 11142, 11143, 11144, 11145, 11146, 11147, 11148, 11150, 11151, 11152, 11153, 11154, 11155, 11156, 11157, 11158, 11159, 11160, 11161, 11162, 11163, 11164, 11165, 11166, 11167, 11168, 11169, 11170, 11171, 11172, 11173, 11174, 11175, 11176, 11177, 11178, 11179, 11180, 11181, 11182, 11183, 11184, 11185, 11186, 11187, 11188, 11189, 11190, 11191, 11192, 11193, 11194, 11220, 11227, 11228, 11229, 11230, 11231, 11232, 11233, 11234, 11235, 11236, 11237, 11238, 11258, 11283, 11309, 11310, 11337, 11342, 11359, 11380, 11387, 11388, 11481, 11482, 11486, 11487, 11489, 11490, 11491, 11492, 11493, 11495, 11524, 11541, 11542, 11543, 11544, 11545, 11547, 11553, 11556, 11557, 11558, 11562, 11569, 11571, 11572, 11573, 11574, 11577, 11578, 11579, 11588, 11589, 11590, 11594, 11595, 11596, 11597, 11598, 11599, 11600, 11601, 11602, 11603, 11604, 11617, 11618, 11619, 11620, 11622, 11623, 11625, 11656, 11657, 11658, 11659, 11660, 11661, 11662, 11663, 11664, 11665, 11666, 11667, 11671, 11672, 11673, 11674, 11675, 11676, 11677, 11678, 11679, 11680, 11681, 11682, 11683, 11684, 11685, 11686, 11687, 11690, 11726, 11727, 11728, 11729, 11731, 11732, 11733, 11735, 11739, 11782, 11783, 11784, 11785, 11786, 11787, 11788, 11789, 11790, 11791, 11792, 11793, 11794, 11795, 11796, 11797, 11798, 11799, 11802, 11803, 11804, 11805, 11806, 11807, 11809, 11810, 11811, 11812, 11813, 11814, 11815, 11816, 11817, 11871, 11873, 11878, 11879, 11880, 11881, 11885, 11893, 11900, 11901, 11902, 11904, 11908, 11909, 11910, 11911, 11919, 11920, 11921, 11922, 11924, 11931, 11933, 11942, 11944, 11945, 11946, 11947, 11948, 11949, 11950, 11951, 11956, 11957, 11958, 11960, 11963, 11964, 11965, 11966, 11967, 11968, 11969, 11970, 11971, 11973, 11974, 11975, 11976, 11977, 11978, 11979, 11980, 11981, 11982, 11983, 11984, 11985, 11986, 11987, 11988, 11989, 11991, 11993, 11995, 11999, 12000, 12001, 12002, 12003, 12004, 12005, 12006, 12007, 12008, 12009, 12010, 12011, 12012, 12013, 12014, 12015, 12016, 12017, 12019, 12021, 12022, 12023, 12024, 12025, 12026, 12027, 12028, 12029, 12030, 12031, 12033, 12035, 12036, 12055, 12057, 12059, 12106, 12107, 12108, 12114, 12120, 12122, 12126, 12127, 12152, 12153, 12154, 12155, 12156, 12161, 12162, 12163, 12164, 12169, 12171, 12174, 12175, 12183, 12187, 12188, 12189, 12190, 12191, 12216, 12217, 12226, 12227, 12228, 12229, 12230, 12232, 12233, 12234, 12235, 12237, 12238, 12239, 12258, 12260, 12261, 12265, 12267, 12268, 12269, 12270, 12272, 12274, 12276, 12277, 12278, 12280, 12282, 12283, 12284, 12285, 12288, 12289, 12290, 12291, 12292, 12303, 12305, 12306, 12307, 12308, 12309, 12310, 12311, 12312, 12313, 12314, 12315, 12316, 12317, 12318, 12319, 12322, 12323, 12324, 12325, 12326, 12327, 12328, 12329, 12330, 12331, 12332, 12333, 12334, 12335, 12336, 12337, 12338, 12339, 12340, 12341, 12342, 12343, 12344, 12345, 12346, 12347, 12348, 12349, 12350, 12361, 12362, 12363, 12364, 12365, 12366, 12367, 12368, 12375, 12376, 12377, 12378, 12379, 12380, 12381, 12382, 12383, 12384, 12398, 12400, 12413, 12414, 12415, 12418, 12419, 12420, 12422, 12423, 12429, 12431, 12436, 12438, 12441, 12442, 12445, 12446, 12449, 12450, 12453, 12454, 12455, 12456, 12457, 12458, 12463, 12465, 12466, 12467, 12468, 12469, 12470, 12471, 12472, 12473, 12474, 12475, 12476, 12477, 12478, 12479, 12480, 12481, 12482, 12489, 12490, 12492, 12493, 12494, 12495, 12496, 12504, 12505, 12509, 12510, 12511, 12513, 12529, 12531, 12532, 12542, 12543, 12547, 12548, 12551, 12552, 12563, 12564, 12565, 12567, 12569, 12573, 12575, 12583, 12584, 12589, 12591, 12592, 12593, 12594, 12595, 12598, 12601, 12602, 12603, 12606, 12610, 12611, 12614, 12615, 12616, 12618, 12619, 12620, 12621, 12625, 12626, 12628, 12629, 12633, 12640, 12641, 12642, 12643, 12645, 12651, 12652, 12653, 12657, 12658, 12661, 12662, 12663, 12664, 12665, 12667, 12668, 12669, 12670, 12671, 12672, 12673, 12674, 12675, 12676, 12677, 12678, 12689, 12690, 12691, 12737, 12738, 12739, 12740, 12741, 12742, 12743, 12745, 12746, 12747, 12748, 12749, 12754, 12755, 12756, 12757, 12758, 12759, 12760, 12761, 12762, 12764, 12765, 12766, 12767, 12768, 12769, 12770, 12771, 12772, 12773, 12774, 12776, 12777, 12780, 12781, 12784, 12785, 12786, 12787, 12804, 12806, 12810, 12814, 12828, 12829, 12830, 12832, 12835, 12837, 12849, 12850, 12851, 12852, 12853, 12854, 12855, 12856, 12857, 12858, 12859, 12860, 12875, 12876, 12877, 12878, 12879, 12880, 12881, 12882, 12900, 12906, 12907, 12908, 12909, 12910, 12911, 12912, 12913, 12914, 12915, 12916, 12917, 12919, 12920, 12921, 12923, 12982, 13034, 13035, 13036, 13037, 13038, 13039, 13040, 13041, 13042, 13043, 13044, 13045, 13046, 13047, 13048, 13049, 13050, 13051, 13052, 13053, 13054, 13055, 13065, 13066, 13068, 13074, 13075, 13076, 13077, 13078, 13079, 13080, 13081, 13082, 13083, 13084, 13085, 13086, 13087, 13088, 13089, 13090, 13091, 13092, 13093, 13094, 13095, 13096, 13097, 13098, 13099, 13100, 13101, 13102, 13103, 13104, 13105, 13106, 13107, 13108, 13109, 13110, 13111, 13112, 13113, 13114, 13115, 13116, 13117, 13118, 13119, 13120, 13121, 13122, 13123, 13124, 13125, 13126, 13127, 13128, 13129, 13130, 13131, 13132, 13133, 13134, 13135, 13136, 13137, 13138, 13139, 13140, 13141, 13142, 13143, 13144, 13145, 13146, 13147, 13148, 13149, 13150, 13179, 13180, 13181, 13182, 13183, 13184, 13185, 13186, 13187, 13188, 13189, 13190, 13192, 13193, 13194, 13217, 13218, 13219, 13220, 13221, 13222, 13223, 13225, 13226, 13227, 13228, 13229, 13230, 13231, 13232, 13233, 13234, 13235, 13236, 13237, 13238, 13239, 13240, 13241, 13242, 13243, 13244, 13245, 13246, 13247, 13248, 13249, 13250, 13251, 13252, 13253, 13254, 13270, 13271, 13276, 13285, 13288, 13301, 13325, 13326, 13350, 13351, 13353, 13354, 13355, 13356, 13357, 13358, 13359, 13360, 13361, 13362, 13363, 13364, 13365, 13366, 13367, 13368, 13369, 13370, 13371, 13372, 13373, 13375, 13376, 13377, 13378, 13379, 13380, 13381, 13382, 13383, 13384, 13410, 13412, 13413, 13417, 13493, 13494, 13512, 13513, 13514, 13537, 13538, 13540, 13541, 13543, 13544, 13547, 13548, 13560, 13564, 13565, 13568, 13569, 13573, 13584, 13585, 13633, 13646, 13647, 13648, 13649, 13650, 13651, 13652, 13654, 13657, 13658, 13659, 13662, 13691, 13692, 13693, 13694, 13695, 13710, 13711, 13740, 13742, 13743, 13744, 13745, 13746, 13747, 13748, 13749, 13750, 13751, 13752, 13753, 13754, 13755, 13756, 13758, 13759, 13760, 13798, 13799, 13800, 13801, 13802, 13803, 13804, 13805, 13806, 13807, 13808, 13809, 13810, 13811, 13812, 13813, 13818, 13819, 13820, 13821, 13822, 13823, 13824, 13825, 13828, 13829, 13830, 13831, 13842, 13843, 13844, 13845, 13936, 13938, 13948, 13974, 13980, 14010, 14061, 14063, 14080, 14081, 14082, 14098, 14103, 14125, 14126, 14127, 14128, 14149, 14150, 14151, 14152, 14164, 14165, 14177, 14179, 14180, 14181, 14182, 14183, 14184, 14185, 14186, 14189, 14190, 14191, 14192, 14193, 14194, 14195, 14196, 14197, 14198, 14199, 14200, 14207, 14209, 14220, 14221, 14222, 14223, 14224, 14228, 14232, 14233, 14234, 14235, 14236, 14238, 14239, 14240, 14242, 14279, 14293, 14298, 14299, 14300, 14301, 14302, 14308, 14309, 14310, 14318, 14319, 14320, 14338, 14339, 14340, 14341, 14346, 14347, 14350, 14351, 14352, 14353, 14356, 14357, 14358, 14359, 14360, 14361, 14362, 14363, 14364, 14365, 14366, 14367, 14368, 14388, 14409, 14413, 14419, 14519, 14520, 14522, 14524, 14545, 14550, 14554, 14555, 14557, 14560, 14564, 14565, 14566, 14567, 14568, 14569, 14571, 14572, 14573, 14574, 14575, 14576, 14577, 14578, 14579, 14580, 14581, 14582, 14583, 14584, 14585, 14586, 14588, 14589, 14590, 14591, 14592, 14593, 14594, 14595, 14596, 14597, 14598, 14599, 14600, 14601, 14602, 14603, 14604, 14605, 14606, 14607, 14608, 14609, 14610, 14611, 14612, 14613, 14614, 14615, 14616, 14617] +Linked NPCs: Hans (0), Man (1), Man (2), Man (3), Woman (4), Woman (5), Woman (6), Farmer (7), Thief (8), Guard (9), Tramp (11), Barbarian (12), Wizard (13), Druid (14), Warrior woman (15), Man (16), Al-Kharid warrior (18), White Knight (19), Paladin (20), Hero (21), Forester (22), Knight of Ardougne (23), Man (24), Woman (25), Knight of Ardougne (26), Archer (27), Zookeeper (28), Musician (29), Musician (30), Priest (31), Guard (32), Door man (33), Watchman (34), Soldier (35), Wyson the gardener (36), Sigbert the Adventurer (37), Shipyard worker (38), Shipyard worker (39), Banker (44), Banker (45), null (70), Earth warrior (124), Ice warrior (125), Ice warrior (145), Shadow warrior (158), Man (170), Dark wizard (172), Invrigar the Necromancer (173), Dark wizard (174), Mugger (175), Witch (176), Witch (177), Black Knight (178), Black Knight (179), Highwayman (180), Chaos druid (181), Pirate (182), Pirate (183), Pirate (184), Pirate (185), Thug (186), Rogue (187), Monk of Zamorak (188), Monk of Zamorak (189), Monk of Zamorak (190), Tribesman (191), Dark warrior (192), Chaos druid warrior (193), Necromancer (194), Bandit (195), Guard Bandit (196), Barbarian guard (197), Guildmaster (198), Gunthor the Brave (199), Lord Daquarius (200), Jailer (201), Black Heather (202), Donny the Lad (203), Speedy Keith (204), Salarin the Twisted (205), Grail Maiden (210), Sir Percival (211), King Percival (212), Peasant (214), Peasant (215), High Priest (216), Crone (217), Galahad (218), Fisherman (219), The Fisher King (220), Monk (222), Brother Kojo (223), Bonzo (225), null (226), Morris (227), Big Dave (228), Joshua (229), Grandpa Jack (230), Forester (231), Renegade Knight (237), Sir Lancelot (239), Sir Gawain (240), Sir Kay (241), Sir Bedivere (242), Sir Tristram (243), Sir Pelleas (244), Sir Lucan (245), Beefy Bill (246), Sir Mordred (247), Morgan Le Faye (248), Merlin (249), The Lady of the Lake (250), King Arthur (251), Beggar (252), Khazard Guard (253), Khazard Guard (254), Khazard Guard (255), Khazard Guard (256), Khazard Guard (257), null (258), Angor (259), Kelvin (260), Joe (261), Slave fighter (262), Hengrad (263), null (267), Local (268), Lucien (272), Lucien (273), Guardian of Armadyl (274), Guardian of Armadyl (275), Winelda (276), Fire Warrior of Lesarkus (277), Cook (278), Brother Omad (279), Brother Cedric (280), Monk (281), Thief (282), Head Thief (283), Veronica (285), Professor Oddenstein (286), Ernest (287), Councillor Halgrive (289), Doctor Orbon (290), Farmer Brumty (291), Sedridor (300), Hadley (302), Gerald (303), Almera (304), Hetty (307), Master fisher (308), null (335), Da Vinci (336), Da Vinci (337), Chancy (338), Chancy (339), Hops (340), Hops (341), Guidor's wife (342), Guidor (343), Guard (344), Guard (345), Guard (346), Mourner (347), Mourner (348), Kilron (349), Omart (350), Man (351), Woman (352), Woman (353), Woman (354), Mourner (357), Priest (358), Man (359), Woman (360), Woman (361), Woman (362), Woman (363), King Lathas (364), Paladin (365), Jerico (366), Chemist (367), Guard (368), Mourner (369), Mourner (370), Mourner (371), Mourner (372), Nurse Sarah (373), Redbeard Frank (375), Luthas (379), Customs officer (380), null (381), Barbarian guard (384), Seer (388), Thormac (389), Legends guard (398), Legends guard (399), Jungle forester (401), Jungle forester (402), Eluned (404), null (405), Lokar Searunner (406), Captain Bentley (407), Captain Bentley (408), Genie (409), Mysterious Old Man (410), null (413), null (414), null (431), Cyrisus (432), Cyrisus (433), Cyrisus (434), Fallen Man (435), Fallen Man (436), Cap'n Izzy No-Beard (437), Jail guard (447), Jail guard (448), Jail guard (449), Seth Groats (452), Suit of armour (453), Sanfew (454), Kaqemeex (455), Father Aereck (456), Restless ghost (457), Father Urhney (458), Skeleton warlock (459), Wizard Frumscone (460), Magic Store owner (461), Wizard Distentor (462), Murphy (463), Murphy (464), Murphy (465), Murphy (466), Khazard trooper (475), Khazard trooper (476), Khazard warlord (477), Khazard commander (478), Observatory professor (488), Banker (494), Banker (495), Banker (496), Banker (497), Banker (499), Mosol Rei (500), Hajedy (510), Vigroy (511), Kaleb Paramaya (512), Yohnus (513), Seravel (514), Yanni Salika (515), Obli (516), Fernahei (517), Captain Shanks (518), Bob (519), Shopkeeper (520), Shop assistant (521), Shopkeeper (522), Shop assistant (523), Shopkeeper (524), Shop assistant (525), Shopkeeper (526), Shop assistant (527), Shopkeeper (528), Shop assistant (529), Shopkeeper (530), Shop assistant (531), Valaine (536), Scavvo (537), Peksa (538), Silk trader (539), Gem trader (540), Zeke (541), Louie Legs (542), Karim (543), Ranael (544), Dommik (545), Zaff (546), Baraek (547), Thessalia (548), Horvik (549), Lowe (550), Shopkeeper (551), Shop assistant (552), Aubury (553), Fancy-dress shop owner (554), Shopkeeper (555), Grum (556), Wydin (557), Gerrant (558), Brian (559), Jiminua (560), Shopkeeper (561), Candle-maker (562), Arhein (563), Zambo (568), Silver merchant (569), Gem merchant (570), Baker (571), Spice seller (572), Fur trader (573), Silk merchant (574), Hickton (575), Harry (576), Cassie (577), Frincos (578), Flynn (580), Wayne (581), Betty (583), Herquin (584), Rommik (585), Gaius (586), Jatix (587), Davon (588), Zenesha (589), Aemad (590), Kortan (591), Roachey (592), Frenita (593), Tea seller (595), Fat Tony (596), Noterazzo (597), Hairdresser (598), Make-over Mage (599), Sir Vyvin (605), Squire (606), Gunnjorn (607), Sir Amik Varze (608), Fortress Guard (609), Black Knight Captain (610), Witch (611), Digsite workman (613), Doug Deeping (614), Student (615), Student (616), Student (617), Examiner (618), Archaeological expert (619), Panning guide (620), Juliet (637), Apothecary (638), Romeo (639), Father Lawrence (640), Charlie the Tramp (641), Katrine (642), Weaponsmaster (643), Straven (644), Jonny the beard (645), Curator Haig Halen (646), null (647), King Roald (648), Archer (649), Warrior (650), Monk (651), Wizard (652), Cave monk (656), Monk of Entrana (657), Monk of Entrana (658), Party Pete (659), Knight (660), Megan (661), Lucy (662), Man (663), null (664), Caleb (666), Johnathon (668), Charlie (673), Foreman (674), Shipyard worker (675), Guard (678), Ranging Guild Doorman (679), Leatherworker (680), Held vampyre juvinate (681), Armour salesman (682), Bow and Arrow salesman (683), Tower Advisor (684), Tower Advisor (685), Tower Advisor (686), Tower Advisor (687), Tower Archer (688), Tower Archer (689), Tower Archer (690), Tower Archer (691), Tribal Weapon Salesman (692), Ticket Merchant (694), Bailey (695), Caroline (696), Holgart (698), Holgart (699), Holgart (700), Kent (701), Fisherman (702), Fisherman (703), Fisherman (704), Melee instructor (705), Wizard Mizgog (706), Wizard Grayzag (707), Alrena (710), Bravek (711), Carla (712), Clerk (713), Edmond (714), null (715), Head mourner (716), Mourner (717), Mourner (718), Mourner (719), Recruiter (720), Ted Rehnison (721), Martha Rehnison (722), Jethick (725), Registrar 1 (726), Registrar 2 (727), Man (728), Man (729), Registrar 3 (730), Bartender (731), Bartender (732), Bartender (735), Emily (736), Bartender (737), Bartender (738), Bartender (739), Trufitus (740), Duke Horacio (741), Ned (743), Klarense (744), Oracle (746), Oziach (747), null (748), Melzar the Mad (753), Morgan (755), Dr Harlow (756), Prince Brand (757), Fred the Farmer (758), Gertrude (780), Civilian (785), Civilian (786), Civilian (787), Garv (788), Grubor (789), Seth (791), Grip (792), Alfonse the waiter (793), Charlie the cook (794), Ice Queen (795), Achietties (796), Helemos (797), Velrak the explorer (798), Pirate Guard (799), Abbot Langley (801), Brother Jered (802), Monk (803), Tanner (804), Master Crafter (805), Donovan the Family Handyman (806), Pierre (807), Hobbes (808), Louisa (809), Mary (810), Stanford (811), Guard (812), Gossip (813), Anna (814), Bob (815), Carol (816), David (817), Elizabeth (818), Frank (819), Poison Salesman (820), Ana (822), Female slave (824), Male slave (825), Escaping slave (826), Rowdy slave (827), Mercenary Captain (830), Captain Siad (831), Al Shabim (832), Bedabin Nomad (833), Bedabin Nomad Guard (834), Irena (835), Shantay (836), Shantay Guard (837), Shantay Guard (838), Mine cart driver (841), Rowdy Guard (842), RPDT employee (843), null (844), Horacio (845), Kangai Mau (846), Head chef (847), null (871), Watchtower Wizard (872), Tower guard (877), Colonel Radick (878), Traiborn (881), Gypsy Aris (882), Sir Prysin (883), Captain Rovin (884), Ceril Carnillean (885), Claus the chef (886), Guard (887), Henryeta Carnillean (889), Butler Jones (890), Alomone (891), Hazeel (892), Clivet (893), Hazeel Cultist (894), Nora T. Hagg (896), Gundai (902), Lundail (903), Chamber guardian (904), Kolodion (905), Kolodion (906), Kolodion (907), Battle mage (912), Battle mage (913), Leela (915), Joe (916), Jail guard (917), Ned (918), Lady Keli (919), Prince Ali (920), Prince Ali (921), Aggie (922), Hassan (923), Osman (924), Border Guard (925), Border Guard (926), Gujuo (928), Ungadulu (929), Ungadulu (930), Jungle savage (931), Fionella (932), Siegfried Erkle (933), Viyeldi (935), Master chef (942), Survival expert (943), Combat instructor (944), RuneScape guide (945), Magic instructor (946), Financial advisor (947), Mining instructor (948), Quest guide (949), Banker (953), Brother Brace (954), Mubariz (957), Fadli (958), A'abla (959), Sabreen (960), Surgeon General Tafani (961), Jaraah (962), Zahwa (963), Ima (964), Sabeil (965), Jadid (966), Dalal (967), Afrah (968), Jeed (969), Diango (970), Chadwell (971), Koftik (972), Koftik (973), Koftik (974), Koftik (975), Koftik (976), Slave (979), Slave (980), Slave (981), Slave (982), Slave (983), Slave (984), Slave (985), Sir Jerro (988), Sir Carl (989), Sir Harry (990), Half-soulless (991), Kardia (992), Dark mage (1001), Disciple of Iban (1002), Lord Iban (1003), Zamorak wizard (1007), Hamid (1008), Vampire (1023), Banker (1036), Rufus (1038), Barker (1039), Fidelio (1040), Sbott (1041), Roavar (1042), Monk of Zamorak (1044), Monk of Zamorak (1045), Monk of Zamorak (1046), null (1047), null (1048), Drezel (1049), Filliman Tarlock (1050), Nature Spirit (1051), Ulizius (1054), Pirate Jackie the Fruit (1055), Mime (1056), Strange watcher (1057), Strange watcher (1058), Strange watcher (1059), Denulth (1060), Sergeant (1061), Sergeant (1062), Soldier (1063), Soldier (1064), Soldier (1065), Soldier (1066), Soldier (1067), Soldier (1068), Soldier (1069), Saba (1070), null (1071), Eadburg (1072), Archer (1073), Archer (1074), Archer (1075), Guard (1076), Guard (1077), Harold (1078), Tostig (1079), Eohric (1080), Servant (1081), Dunstan (1082), Wistan (1083), Breoca (1084), Ocga (1085), Man (1086), Penda (1087), Hygd (1088), Ceolburg (1089), Hild (1090), White Knight (1092), Eadgar (1113), Godric (1114), Weird Old Man (1152), Timfraku (1162), Tiadeche (1163), Tiadeche (1164), Tinsay (1165), Tinsay (1166), Tamayu (1167), Tamayu (1168), Tamayu (1169), Tamayu (1170), Lubufu (1171), Lord Iorwerth (1182), Elf warrior (1183), Elf warrior (1184), Elven city guard (1185), Idris (1186), Essyllt (1187), Morvran (1188), Elf Tracker (1199), Tyras guard (1200), Elf warrior (1201), Arianwyn (1202), Tyras guard (1203), Tyras guard (1204), null (1205), Tyras guard (1206), null (1207), Quartermaster (1208), Koftik (1209), King's messenger (1210), Tegid (1213), Parroty Pete (1216), Gardener (1217), Ghoul (1218), Vampire (1220), Vampire (1223), Vampire (1225), Bedabin Nomad Fighter (1239), Afflicted(Ulsquire) (1251), Ulsquire Shauncy (1252), Afflicted(Razmire) (1253), Razmire Keelgan (1254), Mort'ton Local (1255), Mort'ton Local (1256), Afflicted (1257), Afflicted (1258), Mort'ton local (1259), Mort'ton local (1260), Afflicted (1261), Afflicted (1262), Wizard (1263), Saradomin wizard (1264), Olaf the Bard (1269), Fossegrimen (1273), Ospak (1274), Styrmir (1275), Torbrund (1276), Fridgeir (1277), Longhall Bouncer (1278), The Draugen (1279), Sigli the Huntsman (1281), Sigmund The Merchant (1282), Swensen the Navigator (1283), Bjorn (1284), Eldgrim (1285), Manni the Reveller (1286), Council workman (1287), Peer the Seer (1288), Thorvald the Warrior (1289), Koschei the deathless (1290), Koschei the deathless (1291), Koschei the deathless (1292), Koschei the deathless (1293), Brundt the Chieftain (1294), Guard (1296), Guard (1297), Town Guard (1298), Town Guard (1299), Thora the Barkeep (1300), Yrsa (1301), Fisherman (1302), Skulgrimen (1303), Sailor (1304), Agnar (1305), Freidir (1306), Borrokar (1307), Lanzig (1308), Pontak (1309), Freygerd (1310), Lensa (1311), Jennella (1312), Sassilik (1313), Inga (1314), Fish monger (1315), Fur trader (1316), Market Guard (1317), Warrior (1318), Jossik (1334), Jossik (1335), Larrissa (1336), Larrissa (1337), Sam (1357), Rachael (1358), Banker (1360), Arnor (1361), Haming (1362), Moldof (1363), Helga (1364), Matilda (1365), Ashild (1366), Skraeling (1367), Skraeling (1368), Fishmonger (1369), Greengrocer (1370), null (1373), Guard (1374), Advisor Ghrim (1375), Derrik (1376), Farmer (1377), Flower Girl (1378), Ragnar (1379), Einar (1380), Alrik (1381), Thorhild (1382), Halla (1383), Yrsa (1384), Sailor (1385), Rannveig (1386), Thora (1387), Valgerd (1388), Skraeling (1389), Broddi (1390), Skraeling (1391), Ragnvald (1392), Fishmonger (1393), Greengrocer (1394), Lumberjack Leif (1395), Miner Magnus (1396), Fisherman Frodi (1397), Gardener Gunnhild (1398), Cook's brother (1430), Monkey minder (1469), Foreman (1470), Forester (1508), Woman-at-arms (1509), Apprentice (1510), Ranger (1511), Adventurer (1512), Mage (1513), Hiylik Myna (1514), null (1515), null (1516), null (1517), null (1518), null (1519), null (1520), Lanthus (1526), Zealot (1528), Santa (1552), Cyreg Paddlehorn (1567), Curpile Fyod (1568), Veliaf Hurtz (1569), Sani Piliu (1570), Harold Evans (1571), Radigad Ponfit (1572), Polmafi Ferdygris (1573), Ivan Strom (1574), Vanstrom Klause (1579), Vanstrom Klause (1580), Vanstrom Klause (1581), Saniboch (1595), null (1596), Vannaka (1597), null (1599), Infernal Mage (1643), Infernal Mage (1644), Infernal Mage (1645), Infernal Mage (1646), Infernal Mage (1647), Robe Store owner (1658), null (1666), null (1667), null (1668), null (1669), Gardener Ghost (1675), null (1679), Islwyn (1680), Velorina (1683), Necrovarus (1684), Gravingas (1685), Ghost disciple (1686), null (1687), Robin (1694), Old crone (1695), Old man (1696), Ghost villager (1697), Tortured soul (1698), Ghost shopkeeper (1699), Ghost innkeeper (1700), Ghost farmer (1701), Ghost banker (1702), Ghost sailor (1703), Ghost captain (1704), Ghost captain (1705), Ghost guard (1706), Johanhus Ulsbrecht (1709), H.A.M. Guard (1710), H.A.M. Guard (1711), H.A.M. Guard (1712), H.A.M. Deacon (1713), H.A.M. Member (1714), H.A.M. Member (1715), H.A.M. Member (1716), H.A.M. Member (1717), Jimmy the Chisel (1718), Sigmund (1730), Sigmund (1731), null (1732), Sigmund (1733), Sigmund (1734), Sigmund (1735), Sigmund (1736), Sigmund (1737), Sigmund (1738), Milton the Miller (1739), H.A.M. guard (1740), H.A.M. guard (1741), H.A.M. agent Brian (1742), H.A.M. agent William (1743), H.A.M. agent Charles (1744), H.A.M. agent Sam (1745), H.A.M. agent Christopher (1746), H.A.M. agent Daniel (1747), H.A.M. agent Michael (1748), Merchant Walton (1750), Farmer (1757), Farmer (1758), Farmer (1759), Farmer (1760), Farmer (1761), Ilfeen (1777), William (1778), Ian (1779), Larry (1780), Darren (1781), Edward (1782), Richard (1783), Neil (1784), Edmond (1785), Simon (1786), Sam (1787), H.A.M. agent Walton (1791), null (1792), Tassie Slipcast (1793), Phantuwti Fanstuwi Farsight (1798), Tindel Marchant (1799), Petra Fiyed (1801), Guard (1805), Guard (1806), Hamal the Chieftain (1807), Ragnar (1808), Svidi (1809), Jokul (1810), Camp dweller (1814), Camp dweller (1815), Camp dweller (1816), Camp dweller (1817), Camp dweller (1818), Candle seller (1834), Brian (1860), Ranged instructor (1861), Ali Morrisane (1862), Drunken Ali (1863), Ali the Barman (1864), Ali the Kebab seller (1865), Market seller (1866), Ali the Camel Man (1867), null (1869), Ali the Mayor (1870), Ali the Hag (1871), Ali the Snake Charmer (1872), null (1876), null (1877), Bandit Leader (1878), null (1879), Bandit (1880), Bandit (1881), Sir Palomedes (1882), Sir Palomedes (1883), Trobert (1884), Bandit champion (1885), Cowardly Bandit (1886), null (1887), Villager (1888), Villager (1889), Villager (1890), null (1891), Villager (1892), Villager (1893), Villager (1894), null (1895), Villager (1896), Villager (1897), Villager (1898), null (1899), null (1900), Ali the Operator (1902), null (1903), Menaphite Thug (1904), Menaphite Thug (1905), Tough Guy (1906), Elissa (1912), Kamil (1913), Dessous (1914), Dessous (1915), Ruantun (1916), Bandit shopkeeper (1917), Archaeologist (1918), Stranger (1919), Malak (1920), Bartender (1921), null (1922), Eblis (1923), null (1924), Eblis (1925), Bandit (1926), Bandit (1927), Bandit (1928), Bandit (1929), Bandit (1930), Bandit (1931), Rasolo (1972), Damis (1974), Damis (1975), Fareed (1977), Slave (1978), Slave (1979), Embalmer (1980), Carpenter (1981), Raetul (1982), Siamun (1983), null (1984), null (1985), High Priest (1986), null (1987), Priest (1988), Priest (1989), Possessed Priest (1991), null (2002), null (2003), null (2004), Wanderer (2005), Wanderer (2006), Het (2007), Apmeken (2008), Scabaras (2009), Crondis (2010), null (2011), Icthlarin (2012), Strange Old Man (2024), Ahrim the Blighted (2025), Dharok the Wretched (2026), Guthan the Infested (2027), Karil the Tainted (2028), Torag the Corrupted (2029), Verac the Defiled (2030), Zavistic Rarve (2059), Irwin Feaselbaum (2066), null (2080), null (2081), Sigmund (2082), Sigmund (2083), Duke Horacio (2088), Sigmund (2090), Customer (2168), Olivia (2233), Master Farmer (2234), Master Farmer (2235), Market Guard (2236), Gee (2237), Donie (2238), Khazard trooper (2245), Khazard trooper (2246), Wise Old Man (2253), Paladin (2256), null (2257), Mage of Zamorak (2258), Mage of Zamorak (2259), null (2260), Mage of Zamorak (2261), Dark mage (2262), Brian O'Richard (2266), Rogue Guard (2267), Rogue Guard (2268), Rogue Guard (2269), Martin Thwait (2270), Emerald Benedict (2271), Sir Spishyus (2282), Lady Table (2283), Sir Kuam Ferentse (2284), Sir Leye (2285), Sir Tinley (2286), Sir Ren Itchood (2287), Miss Cheevers (2288), Ms. Hynn Terprett (2289), Sir Tiffy Cashien (2290), Rug Merchant (2291), Rug Merchant (2292), Rug Merchant (2293), Rug Merchant (2294), null (2295), Rug Merchant (2296), null (2297), Rug Merchant (2298), null (2299), Rug Station Attendant (2300), Sarah (2304), Vanessa (2305), Richard (2306), Alice (2307), Cap'n Arnav (2308), Tanner (2320), Metarialus (2322), Elstan (2323), Dantaera (2324), Kragen (2325), Lyra (2326), Francis (2327), Garth (2330), Ellena (2331), Selena (2332), Vasquen (2333), Rhonen (2334), Dreven (2335), Taria (2336), Rhazien (2337), Torrell (2338), Alain (2339), Heskel (2340), Treznor (2341), Fayeth (2342), Gileth (2344), Mourner (2349), Mourner (2350), Mourner (2351), Eudav (2352), Oronwen (2353), Banker (2354), Banker (2355), Dalldav (2356), Gethin (2357), Arianwyn (2358), Elf warrior (2359), Elf warrior (2360), Elf warrior (2361), Elf warrior (2362), Goreu (2363), Ysgawyn (2364), Arvel (2365), Mawrth (2366), Kelyn (2367), Eoin (2368), Iona (2369), Head mourner (2372), Mourner (2373), Mourner (2374), null (2375), Eluned (2376), null (2381), null (2382), null (2383), null (2384), null (2385), null (2386), null (2387), null (2388), null (2389), null (2390), null (2391), null (2392), null (2393), null (2394), null (2395), null (2396), Mysterious ghost (2397), Mysterious ghost (2398), Mysterious ghost (2399), Mysterious ghost (2400), Mysterious ghost (2401), Mysterious ghost (2402), null (2435), Jarvald (2436), Jarvald (2437), Jarvald (2438), Freaky Forester (2458), Merchant Vernon (2463), Merchant Uriah (2464), Merchant Xenia (2465), Merchant Yuri (2466), Merchant Zakia (2467), H.A.M. agent Walton (2468), H.A.M. agent Walton (2469), H.A.M. agent Walton (2470), H.A.M. agent Walton (2471), H.A.M. agent Walton (2473), Frog Prince (2474), Frog Princess (2475), Rick Turpentine (2476), Quiz Master (2477), H.A.M. agent Walton (2480), Servant (2481), null (2483), null (2484), null (2485), null (2486), null (2487), null (2488), Tribesman (2496), Tribesman (2497), Broodoo victim (2498), Broodoo victim (2499), Broodoo victim (2500), Broodoo victim (2501), Broodoo victim (2502), Broodoo victim (2503), null (2504), null (2507), null (2510), null (2513), Karaday (2514), Karaday (2515), null (2516), Safta Doc (2517), Safta Doc (2518), null (2519), Gabooty (2520), Gabooty (2521), null (2522), Fanellaman (2523), Fanellaman (2524), null (2525), null (2528), Murcaily (2529), Murcaily (2530), null (2531), Rionasta (2532), Rionasta (2533), H.A.M. agent Walton (2534), Niles (2536), Miles (2537), Giles (2538), Cap'n Hand (2539), Dr Jekyll (2540), Chaos druid (2547), Blackjack seller (2548), Ali the dyer (2549), Wise Old Man (2566), Wise Old Man (2567), Banker (2568), Banker (2569), Banker (2570), Market Guard (2571), Olivia (2572), Pillory Guard (2573), Bank guard (2574), Purepker895 (2575), Qutiedoll (2576), 1337sp34kr (2577), Elfinlocks (2578), Cool Mom227 (2579), Bernald (2580), Ellamaria (2581), Billy, a guard of Falador (2586), Bob, another guard of Falador (2587), Brother Althric (2588), PKMaster0036 (2589), King Roald (2590), Olaf Hradson (2621), Wise Old Man (2633), Miss Schism (2634), Robert the Strong (2639), R4ng3rNo0b889 (2643), null (2654), Unferth (2655), Unferth (2656), Unferth (2657), Unferth (2658), Unferth (2659), Reldo (2660), Reldo (2661), Thief (2674), Man (2675), Make-over Mage (2676), Highwayman (2677), Hengel (2683), Anja (2684), Jack Seagull (2690), Longbow Ben (2691), Ahab (2692), Pirate (2695), Thief (2696), Mugger (2697), Black knight (2698), Guard (2699), Guard (2700), Guard (2701), Guard (2702), Guard (2703), Guard (2704), Guard (2705), Fire wizard (2709), Water wizard (2710), Earth wizard (2711), Air wizard (2712), Malignius Mortifer (2713), Betty (2718), Grum (2719), Gerrant (2720), Wydin (2721), Otto Godblessed (2725), Monk of Entrana (2728), Monk of Entrana (2729), Monk of Entrana (2730), Monk of Entrana (2731), Master Crafter (2732), Master Crafter (2733), Solus Dellagar (2747), Savant (2748), Lord Daquarius (2749), Solus Dellagar (2750), Black Knight (2751), Lord Daquarius (2752), Mage of Zamorak (2753), Mage of Zamorak (2754), Mage of Zamorak (2755), null (2756), null (2757), null (2758), null (2759), null (2760), null (2761), null (2762), null (2763), null (2764), null (2765), null (2766), null (2767), null (2768), null (2769), null (2770), null (2771), null (2772), null (2773), null (2774), null (2775), Woman (2776), Black Knight (2777), Black Knight (2778), Ranger (2779), Solus Dellagar (2780), Mourner (2784), Slave (2785), Slave (2786), Slave (2787), Sergeant Damien (2790), Pillory guard (2791), Tramp (2792), Tramp (2793), Tramp (2794), null (2795), null (2816), null (2817), null (2818), null (2819), Ali the Smith (2820), Ali the Farmer (2821), Ali the Tailor (2822), Ali the Guard (2823), Ellis (2824), Pirate Pete (2825), Pirate Pete (2826), Captain Braindeath (2827), Davey (2829), Brewer (2851), Brewer (2852), Brewer (2853), Brewer (2854), Brewer (2855), Brewer (2856), Brewer (2857), Brewer (2858), Amaethwr (2860), Teclyn (2861), Death (2862), Zombie (2863), Most of a Zombie (2864), Most of a Zombie (2865), Zombie (2866), Most of a Zombie (2867), Zombie Head (2868), Zombie (2869), Bardur (2879), null (2897), null (2898), Father Reen (2899), Father Reen (2900), null (2901), Father Badden (2902), Father Badden (2903), Denath (2904), Denath (2905), Eric (2906), Eric (2907), null (2908), Evil Dave (2909), Evil Dave (2910), Matthew (2911), Matthew (2912), Jennifer (2913), Jennifer (2914), Tanya (2915), Tanya (2916), Patrick (2917), Patrick (2918), null (2922), null (2923), null (2924), null (2925), Jorral (2932), null (2933), Melina (2935), null (2936), Droalak (2938), Dron (2939), Blanin (2940), Grimesquit (2946), Phingspet (2947), Hooknosed Jack (2948), Jimmy Dazzler (2949), The Face (2950), Felkrash (2951), Ceril Carnillean (2953), Councillor Halgrive (2954), Spice seller (2955), Fur trader (2956), Gem merchant (2957), Silver merchant (2958), Silk merchant (2959), Zenesha (2960), Ali Morrisane (2961), Guard (2962), Guard (2963), Guard (2964), Guard (2965), Guard (2966), Guard (2967), Guard (2968), Guard (2969), Guard (2970), Guard (2971), Guard (2972), Guard (2973), Gambler (2998), Gambler (2999), Barman (3000), Gambler (3001), Gambler (3002), Gambler (3003), Gambler (3004), Gambler (3005), Gambler (3006), Rug Merchant (3020), Genie (3022), Ghaslor the Elder (3029), Ali the Carter (3030), Usi (3031), Nkuku (3032), Garai (3033), Habibah (3034), Meskhenet (3035), Zahra (3036), Zahur (3037), Seddu (3038), Kazemde (3039), Awusah the Mayor (3040), Tarik (3041), Poltenip (3042), Radat (3043), Shiratti the Custodian (3044), Rokuh (3045), Nardah Banker (3046), Larxus (3050), Mystery figure (3051), Mystery figure (3056), Ghoul Champion (3059), Leon d'Cour (3067), Ice warrior (3073), null (3074), null (3076), Dead Monk (3077), High Priest (3078), Monk (3079), Monk (3080), Assassin (3081), Hooded Stranger (3092), Bert (3108), Guard Captain (3109), null (3110), null (3111), Sandy (3112), Sandy (3113), Mazion (3114), Blaec (3115), Reeso (3116), Prison Pete (3118), Simon Templeton (3123), Pentyn (3126), Aristarchus (3127), Desert Spirit (3131), null (3132), Furnace grate (3135), null (3136), Enakhra (3137), Enakhra (3138), null (3139), Akthanakos (3141), Akthanakos (3142), null (3143), null (3144), null (3145), null (3146), Lazim (3147), Enakhra (3148), Akthanakos (3149), Knight (3150), null (3152), Princess Astrid (3154), Bill Teach (3155), Bill Teach (3156), null (3157), Bill Teach (3158), Bill Teach (3159), Bill Teach (3160), Charley (3161), Smith (3162), Joe (3163), Mama (3164), Mama (3165), Mike (3166), Pirate (3167), Pirate (3168), Pirate (3169), Pirate (3170), Pirate (3171), Pirate (3172), Pirate (3173), Pirate (3174), Pirate (3175), Pirate (3176), Pirate (3177), Pirate (3178), Pirate (3179), Pirate (3180), Pirate (3181), Pirate (3182), Pirate (3183), Pirate (3184), Pirate (3185), Pirate (3186), Pirate (3187), Pirate (3188), Pirate (3189), Pirate (3190), Pirate (3191), Pirate (3192), Pirate (3193), Pirate (3194), Pirate (3195), Pirate (3196), Banker (3198), Banker (3199), Romily Weaklax (3205), Elena (3209), Alrena (3210), Alrena (3211), Bravek (3212), null (3213), null (3214), Elena (3215), Mourner (3216), Kaylee (3217), Tina (3218), Drunken man (3222), Man (3223), Man (3224), Man (3225), Woman (3226), Dell Monti (3227), Guard (3228), Guard (3229), Guard (3230), Guard (3231), Guard (3232), Guard (3233), Gardener (3234), Apprentice workman (3235), Workman (3236), Cuffs (3237), Narf (3238), Rusty (3239), Jeff (3240), Guard (3241), Dark wizard (3242), Dark wizard (3243), Dark wizard (3244), Dark wizard (3245), Barbarian (3246), Barbarian (3247), Barbarian (3248), Barbarian (3249), Barbarian (3250), Barbarian (3251), Barbarian (3252), Barbarian (3253), Hunding (3254), Barbarian (3255), Barbarian (3256), Barbarian (3257), Barbarian (3258), Barbarian (3259), Barbarian (3260), Barbarian (3261), Barbarian (3262), Barbarian (3263), null (3289), Maris (3292), Martin the Master Gardener (3299), Zandar Horfyre (3308), null (3323), Draul Leptoc (3324), Phillipa (3325), Martina Scorsby (3326), Jeremy Clerksin (3327), Tarquin (3328), Sigurd (3329), Hari (3330), Barfy Bill (3331), White Knight (3348), White Knight (3349), White Knight (3350), Genie (3351), Mysterious Old Man (3352), Niles (3356), Miles (3357), Giles (3358), Sir Amik Varze (3372), Sir Amik Varze (3374), Evil Dave (3378), Evil Dave (3380), Doris (3381), null (3383), null (3384), Gypsy (3385), Gypsy (3386), Culinaromancer (3387), Osman (3388), Pirate Pete (3389), Lumbridge Sage (3393), Evil Dave (3394), Sir Amik Varze (3395), Culinaromancer (3400), Pirate Pete (3416), Pirate Pete (3418), ? ? ? ? (3452), ? ? ? ? (3453), ? ? ? ? (3454), ? ? ? ? (3455), ? ? ? ? (3456), ? ? ? ? (3457), ? ? ? ? (3458), ? ? ? ? (3459), ? ? ? ? (3460), ? ? ? ? (3461), Culinaromancer (3485), Culinaromancer (3486), Culinaromancer (3487), Culinaromancer (3488), Culinaromancer (3489), Culinaromancer (3490), Culinaromancer (3491), Karamel (3495), Leo (3508), Sorin (3509), null (3510), Wiskit (3511), null (3512), null (3513), Vampyre Juvinate (3515), null (3516), Gadderanks (3517), Gadderanks (3518), Gadderanks (3519), Vampyre Juvinate (3520), Vampyre Juvinate (3521), Vampyre Juvinate (3522), Vampyre Juvinate (3523), Vampyre Juvinate (3524), Vampyre Juvinate (3525), Vampyre Juvinate (3526), Held Vampyre Juvinate (3527), Vampyre Juvinate (3528), Vampyre Juvinate (3529), Vampyre Juvenile (3531), Vampyre Juvenile (3532), Vampyre Juvenile (3533), Held Vampyre Juvenile (3534), Ivan Strom (3535), Ivan Strom (3536), Vampyre Juvinate (3537), Vampyre Juvinate (3538), Veliaf Hurtz (3539), Elisabeta (3540), Aurel (3541), Sorin (3542), Luscion (3543), Sergiu (3544), Radu (3545), Grigore (3546), Ileana (3547), Valeria (3548), Emilia (3549), Florin (3550), Teodor (3555), Gabriela (3557), Vladimir (3558), Calin (3559), Mihail (3560), Nicoleta (3561), Simona (3562), Vasile (3563), Razvan (3564), Luminata (3565), null (3566), null (3567), Cornelius (3568), Cornelius (3569), Benjamin (3570), Liam (3571), Miala (3572), Verak (3573), Juvinate (3576), Juvinate (3577), Juvinate (3578), null (3625), Rolayne Twickit (3626), null (3627), Jayene Kliyn (3628), null (3629), Valantay Eppel (3630), null (3631), Dalcian Fang (3632), null (3633), Fyiona Fray (3634), Abidor Crank (3635), null (3638), Launa (3639), Launa (3640), Brana (3641), Mawnis Burowgar (3642), Tolna (3643), Odd Old Man (3670), Fortunato (3671), Sinister Stranger (3677), Sinister Stranger (3678), Nigel (3681), Volf Olafson (3695), Ingrid Hradson (3696), Skeleton fremennik (3697), Skeleton fremennik (3698), Skeleton fremennik (3699), Skeleton fremennik (3700), Skeleton fremennik (3701), Skeleton fremennik (3702), Skeleton fremennik (3703), Skeleton fremennik (3704), Skeleton fremennik (3705), Ulfric (3706), Fisherman's wife (3709), Sigmund (3713), Guard (3715), Sigmund (3716), Sigmund (3717), Sigmund (3718), Sigmund (3719), Sigmund (3720), Doomsayer (3777), null (3778), Arthur (3779), null (3780), Squire (3781), Void Knight (3782), Void Knight (3784), Void Knight (3785), Void Knight (3786), Sir Palomedes (3787), Void Knight (3788), Void Knight (3789), Squire (3790), Squire (3791), Squire (3792), Squire (3793), Squire (3794), Squire (3795), Squire (3796), Squire (3797), Squire (3798), Squire (3799), Squire (3800), Squire (3801), Squire (Novice) (3802), Millie Miller (3806), Gillie Groats (3807), Wise Old Man (3821), Herman Caranos (3822), Franklin Caranos (3823), Arnold Lydspor (3824), Devin Mendelberg (3825), George Laxmeister (3826), Ramara du Croissant (3827), null (3828), null (3829), Kathy Corkat (3830), Kathy Corkat (3831), null (3832), null (3833), null (3834), Wise Old Man (3838), Wise Old Man (3839), Suspect (3852), Suspect (3853), Suspect (3854), Suspect (3855), Suspect (3856), Suspect (3857), Suspect (3858), Suspect (3859), Suspect (3860), Suspect (3861), Suspect (3862), Suspect (3863), Suspect (3864), Suspect (3865), Suspect (3866), Suspect (3867), Suspect (3868), Suspect (3869), Suspect (3870), Suspect (3871), Suspect (3872), Suspect (3873), Suspect (3874), Suspect (3875), Suspect (3876), Suspect (3877), Suspect (3878), Suspect (3879), Suspect (3880), Suspect (3881), Suspect (3882), Suspect (3883), Suspect (3884), Suspect (3885), Suspect (3886), Suspect (3887), Suspect (3888), Suspect (3889), Suspect (3890), Suspect (3891), Molly (3892), Molly (3893), Molly (3894), Molly (3895), Molly (3896), Molly (3897), Molly (3898), Molly (3899), Molly (3900), Molly (3901), Molly (3902), Molly (3903), Molly (3904), Molly (3905), Molly (3906), Molly (3907), Molly (3908), Molly (3909), Molly (3910), Molly (3911), Gardener (3914), Man (3915), Carpenter Kjallak (3916), Farmer Fromund (3917), Prince Brand (3918), Princess Astrid (3919), Runa (3920), Halla (3921), Finn (3922), Osvald (3923), Runolf (3924), Tjorvi (3925), Ingrid (3926), Thora (3927), Signy (3928), Hild (3929), Armod (3930), Beigarth (3931), Reinn (3932), Guard (3941), Guard (3942), Jacky Jester (3955), Rick (4235), null (4236), Maid (4237), null (4238), Cook (4239), null (4240), Butler (4241), null (4242), Demon butler (4243), null (4244), Chief servant (4245), Taxidermist (4246), Estate agent (4247), Sir Renitee (4249), Sawmill operator (4250), Garden supplier (4251), Animated Bronze Armour (4278), Animated Iron Armour (4279), Animated Steel Armour (4280), Animated Black Armour (4281), Animated Mithril Armour (4282), Animated Adamant Armour (4283), Animated Rune Armour (4284), Ghommal (4285), Ajjat (4288), Kamfreena (4289), Shanomi (4290), Lidio (4293), Lilly (4294), Anton (4295), Jade (4296), Sloane (4297), Jimmy (4298), Ref (4299), Ref (4300), Guard (4301), Guard (4302), Guard (4303), Guard (4304), Guard (4305), Guard (4306), Guard (4307), Guard (4308), Guard (4309), Guard (4310), Guard (4311), null (4317), H.A.M. Member (4318), null (4319), H.A.M. Member (4320), null (4321), HAM member (4327), Sigmund (4328), H.A.M. Deacon (4329), Johanhus Ulsbrecht (4330), Sigmund (4331), Sigmund (4332), Sigmund (4333), Sigmund (4334), Sigmund (4335), Guard (4336), Cavey Davey (4358), Patchy (4359), San Fan (4360), Fancy Dan (4361), Honest Jimmy (4362), Security Guard (4375), Litara (4376), Ankou (4381), Ankou (4382), Ankou (4383), Wood Dryad (4441), Held vampyre juvinate (4461), Held vampyre juvinate (4462), Angry juvinate (4463), Angry juvinate (4464), Angry juvinate (4465), Benjamin (4466), Liam (4467), Miala (4468), Verak (4469), Ned (4475), Tarik (4478), Ethereal Man (4501), Ethereal Lady (4502), Ethereal Numerator (4503), Ethereal Expert (4504), Ethereal Perceptive (4505), Ethereal Guide (4506), Ethereal Fluke (4507), Ethereal Mimic (4508), Me (4509), Me (4510), Oneiromancer (4511), Baba Yaga (4513), Pauline Polaris (4514), Meteora (4515), Melana Moonlander (4516), Selene (4517), Rimae Sirsalis (4518), Sirsal Banker (4519), Clan Guard (4520), Bouquet Mac Hyacinth (4526), Lokar Searunner (4537), 'Beefy' Burns (4541), 'Eagle-eye' Shultz (4542), First mate 'Davey-boy' (4543), 'Bird's-Eye' Jack (4544), 'Picarron' Pete (4545), Jake (4546), Bedread the bold (4547), Wilson (4548), Tommy 2-times (4549), Murky Pat (4550), Jack Sails (4551), Palmer (4552), 'Betty' B.Boppin (4553), 'Beedy-eye' Jones (4554), Jenny Blade (4555), 'Lecherous' Lee (4556), 'Sticky' Sanders (4557), Digsite workman (4564), Digsite workman (4565), Examiner (4566), Examiner (4567), Researcher (4568), Nick (4569), Fortress Guard (4603), Fortress Guard (4604), Fortress Guard (4605), Fortress Guard (4606), Monk (4608), Nisha (4648), Tyras guard (4649), Trader Stan (4650), Trader Crewmember (4651), Trader Crewmember (4652), Trader Crewmember (4653), Trader Crewmember (4654), Trader Crewmember (4655), Trader Crewmember (4656), Sir Prysin (4657), Dark wizard (4658), Dark wizard (4659), Dark wizard (4660), Dark wizard (4661), Denath (4663), Wally (4664), Magic instructor (4707), Old Man Ral (4708), Vertida Sefalatis (4709), Aeonisig Raispher (4710), null (4711), null (4712), Safalaan (4713), null (4714), Sarius Guile (4715), Trader Sven (4716), Meiyerditch citizen (4717), Meiyerditch citizen (4718), Meiyerditch citizen (4719), Meiyerditch citizen (4720), Meiyerditch citizen (4721), Meiyerditch citizen (4722), Meiyerditch citizen (4723), Meiyerditch citizen (4724), Meiyerditch citizen (4725), Meiyerditch citizen (4726), Meiyerditch citizen (4727), Meiyerditch citizen (4728), Meiyerditch citizen (4729), Meiyerditch citizen (4730), Meiyerditch citizen (4731), Meiyerditch citizen (4732), Meiyerditch citizen (4733), Meiyerditch citizen (4734), Meiyerditch citizen (4735), Meiyerditch citizen (4736), Meiyerditch citizen (4737), Meiyerditch citizen (4738), Meiyerditch citizen (4739), Meiyerditch citizen (4740), Meiyerditch citizen (4741), Meiyerditch citizen (4742), Meiyerditch citizen (4743), Meiyerditch citizen (4744), Meiyerditch citizen (4745), Meiyerditch miner (4756), Meiyerditch miner (4757), Meiyerditch miner (4758), Meiyerditch miner (4759), Meiyerditch miner (4760), Meiyerditch miner (4761), Former vampyre (4783), Former vampyre (4784), Former vampyre (4785), Former vampyre (4786), Former vampyre (4787), Former vampyre (4788), Angry vampyre (4789), Angry vampyre (4790), null (4854), null (4855), Ezekial Lovecraft (4856), null (4857), null (4858), null (4859), null (4860), Sarius Guile (4861), Holgart (4866), Holgart (4867), Holgart (4868), null (4869), Fisherman (4870), null (4871), Col. O'Niall (4872), Col. O'Niall (4873), Mayor Hobb (4874), Mayor Hobb (4875), null (4876), null (4877), Brother Maledict (4878), Brother Maledict (4879), null (4880), null (4881), null (4882), Witchaven villager (4883), Witchaven villager (4884), Witchaven villager (4885), Witchaven villager (4886), Witchaven villager (4887), Witchaven villager (4888), Jeb (4895), Jeb (4896), Sir Tinley (4897), Cordero (4899), Cadmus (4900), Finlay (4901), Monlum (4902), Priest Yauchomi (4903), Apprentice smith (4904), Sani (4905), Wilfred (4906), Banker (4907), Fritz the Glassblower (4909), Abidor Crank (4919), Ignatius Vulcan (4946), null (4961), Captain Barnaby (4962), Murcaily (4963), Jagbakoba (4964), Male slave (4975), Male slave (4976), Female slave (4977), Female slave (4978), Mercenary (4983), null (4984), null (4985), null (4986), null (4987), Irena (4988), Mercenary (4989), Mercenary (4990), Mercenary (4991), Mercenary (4992), Guard (4993), Guard (4994), Guard (4995), Guard (4996), Guard (4997), Guard (4998), Guard (4999), Guard (5000), Guard (5001), Guard (5002), Apprentice Clerval (5026), Commander Connad (5029), Captain Cain (5030), Private Paldo (5031), Private Pendron (5032), Private Pierreb (5033), Private Paldon (5034), Major Attack (5035), Major Collect (5036), Major Defend (5037), Major Heal (5038), Sergeant Sambur (5039), Auguste (5049), Auguste (5050), Auguste (5051), Auguste (5052), Assistant Serf (5053), Assistant Brock (5054), Assistant Marrow (5055), Assistant Stan (5057), Bob (5058), Curly (5059), Moe (5060), Larry (5061), null (5062), null (5063), null (5065), null (5066), Matthias (5092), Matthias (5093), Artimeus (5109), Aleck (5110), Leon (5111), Hunting expert (5112), Hunting expert (5113), null (5124), null (5125), Nickolaus (5126), Charlie (5138), Uri (5141), Uri (5142), Uri (5143), Double agent (5144), Double agent (5145), Wizard (5195), Wizard (5196), Wizard (5197), Ava (5198), null (5199), Witch (5200), null (5201), Alice's husband (5202), Alice's husband (5203), Alice's husband (5204), Alice's husband (5205), null (5206), Cow1337killr (5210), Alice (5212), null (5257), Banker (5258), null (5259), Banker (5260), null (5261), Stonemason (5262), null (5263), Nathifa (5264), null (5265), Urbi (5266), null (5267), Jamila (5268), null (5269), Sophanem guard (5270), null (5271), Sophanem guard (5272), null (5273), Sophanem guard (5274), null (5275), Sophanem guard (5276), Menaphite guard (5277), Coenus (5278), Jex (5279), null (5280), Maisa (5281), null (5282), null (5283), Osman (5284), Osman (5285), Osman (5286), Osman (5287), Embalmer (5288), Carpenter (5289), Linen worker (5290), Priest (5291), Confused barbarian (5364), Animated steel armour (5382), Odovacar (5383), Tarn (5419), Tarn (5420), null (5423), Larry (5424), Larry (5425), Larry (5426), Musician (5439), Musician (5442), Tolna (5462), Honour guard (5463), Honour guard (5464), Fridleif Shieldson (5465), Thakkrad Sigmundson (5466), Bork Sigmundson (5477), King Gjuki Sorvott IV (5478), Thorkel Silkbeard (5480), Mord Gunnars (5481), Mord Gunnars (5482), Hring Hring (5483), Flosi Dalksson (5484), Raum Urda-Stein (5485), Skuli Myrka (5486), Keepa Kettilon (5487), Magnus Gram (5488), Guard (5489), Guard (5490), Guard (5491), Guard (5492), Freygerd (5493), Lensa (5494), Vanligga Gastfrihet (5495), Sassilik (5496), Miner (5497), Miner (5498), Eric (5499), Gruva Patrull (5500), Mawnis Burowgar (5503), Mawnis Burowgar (5504), Fridleif Shieldson (5505), Thakkrad Sigmundson (5506), Maria Gunnars (5507), Maria Gunnars (5508), Jofridr Mordstatter (5509), Morten Holdstrom (5510), Gunnar Holdstrom (5511), Anne Isaakson (5512), Lisse Isaakson (5513), Honour guard (5514), Honour guard (5515), Honour guard (5516), Honour guard (5517), Kjedelig Uppsen (5518), Trogen Konungarde (5519), Slug Hemligssen (5520), null (5530), Sorceress (5531), Apprentice (5532), Osman (5559), Osman (5560), Osman (5561), General Khazard (5566), Scout (5567), Scout (5568), Scout (5569), Scout (5570), Ghost (5572), null (5573), null (5574), null (5575), null (5576), null (5577), Effigy (5578), Effigy (5579), Bonafido (5580), 'Transmute' The Alchemist (5585), 'Transmute' The Alchemist (5586), 'Currency' The Alchemist (5587), 'Currency' The Alchemist (5588), 'Black-eye' (5589), 'No fingers' (5590), 'Gummy' (5591), 'The Guns' (5592), null (5598), null (5601), null (5602), Elfinlocks (5604), null (5606), Rufus (5612), Movario (5825), Darve (5826), null (5830), null (5831), Rat Burgiss (5833), Surok Magis (5834), Surok Magis (5835), Zaff (5836), Anna Jones (5837), King Roald (5838), Mishkal'un Dorn (5839), Dakh'thoulan Aegis (5840), Sil'as Dahcsnu (5841), Outlaw (5842), Outlaw (5843), Outlaw (5844), Outlaw (5845), Outlaw (5846), Outlaw (5847), Outlaw (5848), Outlaw (5849), Outlaw (5850), Outlaw (5851), null (5853), Bench (5854), H.A.M. Archer (5859), H.A.M. Mage (5860), Cyrisus (5893), Cyrisus (5894), Cyrisus (5895), Cyrisus (5896), Cyrisus (5897), 'Bird's-Eye' Jack (5898), null (5899), null (5900), null (5901), Barbarian (5909), Cook (5910), Cook (5911), Banker (5912), Banker (5913), Iffie (5914), Elsie (5915), Cleaner (5916), Guard (5919), Guard (5920), Trainee Guard (5921), Captain (5922), Man (5923), Woman (5924), Benny (5925), Thief (5926), Thief (5927), Thief (5928), Thief (5929), Art Critic Jacques (5930), Historian Minas (5931), Information clerk (5938), Torrcs (5939), Marfet (5940), Museum guard (5941), Museum guard (5942), Museum guard (5943), Void Knight (5956), Digsite workman (5958), Ed Wood (5964), Orlando Smith (5965), Natural historian (5966), Natural historian (5967), Natural historian (5968), Natural historian (5969), Natural historian (5970), Sylas (5987), Miazrqa (5988), Boris (6026), Imre (6027), Yuri (6028), Joseph (6029), Nikolai (6030), Eduard (6031), Lev (6032), Georgy (6033), Svetlana (6034), Irina (6035), Alexis (6036), Milla (6037), Galina (6038), Sofiya (6039), Ksenia (6040), Yadviga (6041), Nikita (6042), Vera (6043), Zoja (6044), Liliya (6045), null (6075), null (6076), null (6077), null (6082), null (6083), Captain Ned (6084), Cabin boy Jenkins (6085), Cabin boy Jenkins (6086), Lost barbarian (6102), Skeleton hero (6103), Skeleton brute (6104), Skeleton warlord (6105), Skeleton heavy (6106), Skeleton thug (6107), Observatory assistant (6118), null (6119), null (6120), Observatory professor (6121), Town crier (6135), Town crier (6136), Town crier (6137), Town crier (6138), Town crier (6139), Squire (Intermediate) (6140), Squire (Veteran) (6141), Sir Lucan (6158), Sir Lancelot (6160), Sir Bedivere (6161), Sir Tristram (6162), Sir Pelleas (6163), Sir Gawain (6164), Sir Kay (6165), Sir Pelleas (6166), Sir Gawain (6167), Sir Kay (6168), Squire (6169), Sir Lancelot (6170), Sir Kay (6171), Sir Gawain (6172), Sir Lucan (6173), Bandit (6174), Sir Tristram (6175), Sir Pelleas (6176), Sir Bedivere (6177), Anna (6178), David (6179), Anna (6180), Court judge (6181), Jury (6182), Prosecutor (6185), null (6186), Morgan Le Faye (6187), Renegade knight (6188), Black Knight (6189), Guard (6190), null (6191), null (6192), null (6193), null (6194), null (6195), null (6196), null (6197), Sinclair (6198), null (6199), Banker (6200), Knight (6201), null (6202), Vampire (6214), Spiritual warrior (6219), Spiritual ranger (6220), Spiritual mage (6221), Saradomin priest (6254), Spiritual warrior (6255), Spiritual ranger (6256), Spiritual mage (6257), Knight of Saradomin (6258), Knight of Saradomin (6259), Jeffery (6298), Pirate (6346), Pirate (6347), Pirate (6348), Pirate (6349), Pirate (6350), Pirate (6351), Pirate (6352), Pirate (6353), Pirate (6354), Pirate (6355), Pirate (6356), Eniola (6362), Zamorak warrior (6363), Zamorak warrior (6364), Zamorak ranger (6365), Zamorak ranger (6366), Zamorak mage (6367), Zamorak mage (6368), Mage of Zamorak (6370), Zamorak crafter (6371), Zamorak crafter (6372), Wizard Cromperty (6375), null (6386), Bandit (6388), Jury (6510), Jury (6511), Spectator (6512), Spectator (6513), Spectator (6514), Spectator (6515), Spectator (6516), Spectator (6517), Spectator (6518), Spectator (6519), Head registrar (6520), Grand Exchange Tutor (6521), Brugsen Bursen (6522), Bob Barter (herbs) (6524), Murky Matt (runes) (6525), Relobo Blinyo (logs) (6526), Grand Exchange clerk (6528), Grand Exchange clerk (6529), Grand Exchange clerk (6530), Grand Exchange clerk (6531), Banker (6532), Banker (6533), Banker (6534), Banker (6535), Banker (6538), null (6539), Nastroth (6540), Canon the barbarian (6541), Queen of Snow (6731), Pet shop owner (6750), Doorman (6769), Maisa (6782), Maisa (6783), Priest (6784), Lead archaeologist Abigail (6786), Assistant archaeologist Kerner (6787), null (6793), Penguin keeper (6891), Pet shop owner (6892), Pet shop owner (6893), Pet shop owner (6898), Pikkupstix (6970), Pikkupstix (6971), Druid (6972), Druid (6973), Druid (6974), Druid (6975), Druid (6976), Druid (6977), Druid (6978), Druid (6979), Druid (6980), Druidess (6981), Druidess (6982), Druidess (6983), Druidess (6984), Druidess (6985), Druidess (6986), Druidess (6987), null (6988), null (6989), Dark Squall (7001), Surok Magis (7002), null (7006), null (7007), null (7008), null (7009), Balnea (7047), null (7065), null (7066), Balnea (7087), Wise Old Man (7090), Chaos druid (7105), Thug (7106), Thug (7107), Thug (7108), Thug (7109), Thug (7110), Thug (7111), Thug (7112), Thug (7113), Thug (7114), Drunken sailor (7116), Drunken sailor (7117), Catapult engineer (7118), null (7119), Tyras guard (7120), General Hining (7121), Surok Magis (7136), Dagon'hai Elite (7137), Dagon'hai Monk (7138), Dagon'hai Monk (7139), Dagon'hai Monk (7140), Professor Henry (7143), Student (7151), Student (7152), Student (7153), Student (7154), Student (7155), Student (7156), Student (7157), Mugger (7161), Mugger (7162), null (7163), Villager (7164), Villager (7165), Villager (7166), Villager (7167), null (7176), null (7177), null (7178), null (7179), null (7180), null (7181), null (7182), Villager (7183), Ezekial Lovecraft (7184), Clive (7185), Katherine (7186), Katherine (7187), Clive (7188), Kent (7189), null (7190), null (7195), Void Knight (7203), Mysterious mage (7383), Young Brundt (7384), Young Mawnis (7385), Prince Vargas (7386), Prince Vargas (7387), Asleif Hamalsdotter (7389), Nial Swiftfling (7390), Brundt the Chieftain (7394), Brundt the Chieftain (7395), Mawnis Burowgar (7396), Mawnis Burowgar (7397), Thora the barkeep (7398), King Vargas (7399), King Vargas (7400), Asleif Hamalsdotter (7401), null (7406), Highwayman (7443), Ali the Wise (7447), Jhallan (7448), Jhallan (7449), Jhallan (7450), Jhallan (7451), null (7468), Ali the Wise (7469), Pharaoh Queen (7470), Pharaoh Queen (7471), Pharaoh Queen (7472), Pharaoh Queen (7473), Pharaoh Queen (7474), null (7478), Bandit looter (7492), Bandit looter (7493), Bandit looter (7494), Bandit looter (7495), Bandit looter (7496), null (7499), Khazard Guard (7504), Khazard Guard (7505), Khazard Guard (7506), Khazard Guard (7507), Khazard Guard (7508), Khazard Guard (7509), Khazard Guard (7510), Khazard Guard (7511), Khazard Guard (7512), Khazard Guard (7513), Khazard Guard (7514), Khazard Guard (7515), Khazard Guard (7518), Khazard Guard (7519), Khazard Guard (7520), Khazard Guard (7528), Lady Servil (7529), Lady Servil (7530), Justin Servil (7535), Justin Servil (7536), null (7537), null (7538), null (7539), null (7540), null (7541), Justin Servil (7542), General Khazard (7551), General Khazard (7552), General Khazard (7553), Citizen (7554), Zookeeper (7570), Zookeeper (7571), Monkey minder (7572), Monkey minder (7573), null (7574), null (7575), null (7576), null (7577), null (7580), Chief Zookeeper (7581), Reggie (7601), Getorix (7602), Pontimer (7603), Alran (7604), Banker (7605), Zaromark Sliver (7644), Zaromark Sliver (7645), Zaromark Sliver (7646), Zaromark Sliver (7647), Zaromark Sliver (7648), Zaromark Sliver (7649), Zaromark Sliver (7650), Zaromark Sliver (7651), Zaromark Sliver (7652), Zaromark Sliver (7653), Fistandantilus (7654), Fistandantilus (7655), Fistandantilus (7656), Fistandantilus (7657), Fistandantilus (7658), Fistandantilus (7659), Fistandantilus (7660), Fistandantilus (7661), Fistandantilus (7662), Fistandantilus (7663), Mercenary Adventurer (7664), Ivan Strom (7665), Mysterious person (7666), Mysterious person (7667), Mysterious person (7668), Mysterious person (7669), Mysterious person (7670), Mysterious person (7671), Flaygian Screwte (7672), Mekritus A'hara (7673), Andiess Juip (7674), Kael Forshaw (7675), Andiess Juip (7676), Kael Forshaw (7677), Safalaan (7678), Andiess Juip (7679), Kael Forshaw (7680), Safalaan (7681), Safalaan (7686), null (7688), null (7689), Drezel (7690), Drezel (7707), null (7708), null (7709), null (7710), Brother Althric (7719), Monk (7727), Will (7737), Will (7738), Phil (7739), null (7779), Sumona (7780), Jesmona (7781), Catolax (7782), null (7783), A wanderer. (7821), A wanderer. (7822), Osman (7824), 50 Ships Mufassah (7825), Customs Officer (7837), Customs Officer (7838), Customs Officer (7839), Heavy-Handed Harry (7840), Locker Officer (7842), Locker Officer (7843), Captain Rabid Jack (7847), Jack (7848), Bosun Giles (7849), Pirate (7850), Lizzie (7851), Cap'n Izzy No-Beard (7852), Ralph (7853), Brass Hand Harry (7854), Bill Teach (7855), Pirate (7856), Brass Hand Harry (7857), Jack (7861), Iain (7868), Julian (7869), Lachtopher (7870), Samuel (7871), Victoria (7872), Man (7873), Man (7874), Man (7875), Man (7876), Man (7877), Man (7878), Man (7879), Woman (7880), Woman (7881), Woman (7882), Woman (7883), Woman (7884), null (7898), Torsteg (7907), Hilda (7908), Man (7909), Man (7910), Doomsayer (7930), Donie (7931), Gee (7932), Duke Horacio (7933), Sigmund (7934), Hans (7935), Cook (7936), Father Aereck (7937), Sir Vant (7938), Sir Vant (7939), Sir Vant (7940), Sir Vant (7941), Sir Vant (7942), Lumbridge Sage (7949), Melee Tutor (7950), Ranged Tutor (7951), Magic Tutor (7952), Cooking Tutor (7953), Crafting Tutor (7954), Chief Thief Robin (7955), Mining Tutor (7956), Prayer Tutor (7957), Smelting Tutor (7958), Smithing Tutor (7959), Woodcutting Tutor (7960), Bank Tutor (7961), Gee (7962), Chaos druid (7966), Shopkeeper (7967), Explorer Jack (7969), Spirit (7987), Spirit (7988), Erik Bonde (7989), Spirit (7990), Jallek Lenkin (7991), Spirit (7992), Meranek Thanatos (7993), Ghostly warrior (7994), Jack (8002), Sarah (8003), Laura (8004), Laura (8005), Roger (8006), Jorral (8007), Guthix (8008), Max the traveller (8009), Man (8010), Man (8011), Woman (8012), Woman (8013), Haluned (8014), Jack (8015), Baby Sarah (8016), Wizard (8033), Wizard (8034), Wizard (8035), Wizard (8036), Wizard (8037), Wizard (8038), Wizard (8039), Wizard (8040), Imiago (8041), null (8065), null (8066), null (8067), null (8068), null (8069), null (8070), null (8071), Maggie (8078), Audience (8086), Audience (8087), null (8089), Shooting star shadow (8092), Calladin (8111), Erik Bonde (8115), Erik Bonde (8116), Jallek Lenkin (8117), Jallek Lenkin (8118), Meranek Thanatos (8119), Meranek Thanatos (8120), Spirit (8121), Rogue (8122), null (8123), null (8124), Spirit (8134), Erik Bonde (8136), Jallek Lenkin (8137), Meranek Thanatos (8138), Hartwin (8139), Hartwin (8140), null (8141), Arrav (8168), Arrav (8169), Dimintheis (8171), Dimintheis (8172), Guard (8173), Clive (8174), Ellamaria (8175), Monk of Zamorak (8178), Acrobat (8185), Acrobat (8186), Acrobat (8187), Acrobat (8188), Acrobat (8189), Acrobat (8190), Acrobat (8191), Acrobat (8192), Acrobat (8193), Acrobat (8194), Acrobat (8195), Acrobat (8196), Acrobat (8197), Acrobat (8198), Acrobat (8199), Acrobat (8200), Wendy (8201), Gus (8205), Lottie (8206), Aggie (8207), Guardian of Armadyl (8226), Head mystic (8227), Rewards mystic (8228), Mystic (8229), Mystic (8230), Mystic (8234), Mystic (8235), Head mystic (8239), Grindxplox (8250), Grindxplox (8251), null (8266), null (8267), null (8269), Yadech Strongarm (8270), null (8271), Turael (8273), Mazchna (8274), Duradel (8275), null (8277), null (8278), Cyrisus (8279), Sloane (8280), Balance Elemental (8285), Harrallak Menarous (8299), Harrallak Menarous (8300), Harrallak Menarous (8301), Turael (8302), Turael (8303), Cyrisus (8304), Cyrisus (8305), Ghommal (8306), Mazchna (8307), Mazchna (8308), Mazchna (8309), Duradel (8310), Sloane (8311), Elite Dark Warrior (8312), Elite Dark Warrior (8313), Elite Dark Warrior (8314), Elite Dark Warrior (8315), Elite Dark Ranger (8316), Elite Dark Ranger (8317), Elite Dark Ranger (8318), Elite Dark Ranger (8319), Elite Dark Mage (8320), Elite Dark Mage (8321), Elite Dark Mage (8322), Elite Dark Mage (8323), Elite Black Knight (8324), Elite Black Knight (8325), Elite Black Knight (8326), Elite Black Knight (8327), Elite Black Knight (8328), Elite Black Knight (8329), Elite Black Knight (8330), Guardian of Armadyl (8331), Guardian of Armadyl (8332), Guardian of Armadyl (8333), Mercenary axeman (8334), Mercenary mage (8335), Idria (8336), Idria (8337), Akrisae (8338), Shady stranger (8339), Shady stranger (8340), Shady stranger (8341), null (8342), Guardian of Armadyl (8343), Guardian of Armadyl (8344), null (8345), Local thug (8346), null (8347), Local mage (8348), Vasador (8393), Valator (8394), Vaasdor (8395), Varosad (8396), Verisad (8397), Vudisor (8398), Vlatoad (8399), Vedolas (8400), Vundiar (8401), Versita (8402), Vislota (8403), Vanjuta (8404), Vasador (8405), Valator (8406), Vaasdor (8407), Varosad (8408), Verisad (8409), Vudisor (8410), Vlatoad (8411), Vedolas (8412), Vundiar (8413), Versita (8414), Vislota (8415), Vanjuta (8416), Ivy Sophista (8417), Thaerisk Cemphier (8418), Thaerisk Cemphier (8419), null (8420), null (8421), Assassin (8422), Assassin (8423), Khazard launderer (8428), Khazard cook (8429), Silif (8433), Silif (8434), Shady stranger (8435), Suspicious outsider (8436), Elite Khazard guard (8437), Elite Khazard guard (8438), Elite Khazard guard (8439), Elite Khazard guard (8440), Dark Squall (8441), Surok Magis (8442), Druid (8444), Druid (8445), Druid (8446), Druid bodyguard (8447), Druid bodyguard (8448), Movario (8449), Darve (8450), Movario (8452), Darve (8453), Druid spirit (8456), Druid spirit (8457), Druid spirit (8458), Druid spirit (8459), Turael (8461), Spria (8462), Mazchna (8464), Achtryn (8465), Duradel (8466), Lapalok (8467), null (8468), null (8469), null (8470), null (8471), null (8472), null (8474), null (8475), null (8476), null (8477), null (8478), null (8479), null (8480), null (8481), null (8482), null (8483), Cook's brother (8500), Jack Frost (8517), Jack Frost (8518), Jack Frost (8519), Competition Judge (8523), Competition Judge (8524), null (8525), Queen of Snow (8539), Isidor (8544), Mystic (8545), Priest of Guthix (8555), Brian Twitcher (8556), null (8579), Geoffrey (8590), Nomad (8591), null (8602), null (8603), null (8604), null (8605), null (8606), Nomad (8607), Nomad (8608), Sandwich lady (8629), null (8630), Sandwich lady (8631), Mysterious Old Man (8632), Niles (8633), Miles (8634), Giles (8635), Rick Turpentine (8641), Dr Jekyll (8642), Dr Jekyll (8643), Shade (8645), Bee keeper (8649), null (8693), null (8694), null (8695), Musician (8698), Musician (8699), Musician (8700), Musician (8701), Musician (8702), Musician (8703), Musician (8704), Musician (8705), Musician (8706), Musician (8707), Musician (8708), null (8709), Musician (8710), Musician (8711), Ghostly piper (8713), Ghostly piper (8714), Drunken musician (8715), Musician (8716), Musician (8717), Musician (8718), Drummer (8719), Drummer (8720), Musician (8721), Bill Blakey (8722), Elf musician (8723), Dark wizard (8830), Lumbridge Sage (8847), Sir Vant (8848), Sir Vant (8849), Sir Vant (8850), Sir Vant (8851), Sir Vant (8852), Sir Vant (8853), Squire (8857), Roddeck (8863), Hank (8864), Roddeck (8867), Dark wizard (8871), Dark wizard (8872), Dark wizard (8873), Dark wizard (8874), null (8878), Iconis (8879), Gwir (8894), Scotty (8901), Sanchez (8902), Overseer (8904), Arianwyn (8913), Arianwyn (8914), null (8915), null (8916), Junior Cadet Mal (8917), Junior Cadet Mal (8918), Junior Cadet Mal (8919), Junior Cadet Mal (8920), Junior Cadet Mal (8921), null (8922), Serjeant Cole (8923), null (8924), Commander Loman (8925), null (8926), War-chief Reeves (8927), null (8928), Lord Marshal Brogan (8929), null (8938), Junior Cadet Finda (8939), null (8940), Junior Cadet Bertol (8941), Operator Jen (8949), Arianwyn (8950), null (8951), null (8952), Mourner (8953), Operator Lil (8954), Operator Dor (8959), Operator Gron (8964), Arianwyn (8966), Registrar 4 (8967), Registrar 5 (8968), Junior Cadet Mina (8969), null (9036), null (9037), Cook's brother (9038), Assassin (9044), null (9045), Azzanadra (9047), Azzanadra (9048), Digsite workman (9049), Azzanadra (9051), Monk of Zamorak (9082), Kuradal (9084), Kuradal (9085), Queen Sigrid (9088), Baba Yaga (9093), Baba Yaga (9094), Silas (9095), King Vargas (9099), King Vargas (9102), Bardur (9105), Brundt the Chieftain (9118), Koschei the Deathless (9119), Market guard (9122), Fremennik warrior (9123), Agnar (9124), Pontak (9125), Jennella (9126), Sassilik (9127), null (9134), Brundt the Chieftain (9135), Prince Brand (9136), Princess Astrid (9137), Queen Sigrid (9138), Brundt the Chieftain (9139), King Vargas (9142), Prince Brand (9143), Princess Astrid (9144), Queen Sigrid (9145), Baba Yaga (9146), Prince Brand (9147), Princess Astrid (9148), Koschei the Deathless (9149), Faruq (9159), Arrav (9160), Arrav (9161), Marion (9166), Geoff (9168), Baba Yaga (9307), Prince Brand (9308), Princess Astrid (9309), Koschei the Deathless (9310), Brundt the Chieftain (9315), King Vargas (9316), Queen Sigrid (9317), Eir (9318), Asleif Hamalsdotter (9319), Nial Swiftfling (9320), Eir (9321), Eir (9322), Brundt the Chieftain (9323), Baba Yaga (9324), Koschei the Deathless (9325), Baba Yaga (9326), Koschei the Deathless (9327), Prince Brand (9328), Princess Astrid (9329), Baba Yaga (9330), Brundt the Chieftain (9331), Prince Brand (9332), Princess Astrid (9333), Honour guard (9335), Sigli the Huntsman (9336), Mawnis Burowgar (9337), Fridleif Shieldson (9338), Baba Yaga (9339), Silas (9340), Baba Yaga (9341), Silas (9342), Baba Yaga (9347), Oneiromancer (9348), Dr Harlow (9355), Edward Honda (9358), null (9359), Sir Prysin (9360), Gypsy Aris (9361), Jack Frost (9365), Cook (9367), Partygoer (9380), Partygoer (9381), Partygoer (9382), Partygoer (9384), Partygoer (9385), Partygoer (9387), Partygoer (9388), Partygoer (9390), Partygoer (9391), Partygoer (9393), Partygoer (9394), Betty (9395), Sir Amik Varze (9397), Queen of Snow (9398), Jack Frost (9403), Cook (9405), Sir Amik Varze (9416), Cook (9418), Partygoer (9420), Knight (9448), Knight (9449), null (9450), Elite Dark Warrior (9456), Elite Dark Ranger (9457), Elite Dark Mage (9458), Elite Dark Mage (9459), Pikkenmix (9492), Pikkenmix (9493), Reese (9623), Reese (9624), Reese (9625), Caitlin (9626), Caitlin (9627), Kayle (9628), Kayle (9629), Ilona (9630), Ilona (9631), Xenia (9634), Xenia (9635), Xenia (9636), Reese (9637), Caitlin (9638), Kayle (9639), Ilona (9640), Fisherman (9676), Fisherman (9677), Fisherman (9678), Fisherman's wife (9679), Fisherman's wife (9680), A strange courier (9684), Courier (9685), Hooded client (9691), Fremennik shipmaster (9707), Fremennik shipmaster (9708), Fremennik warrior (9709), Dungeoneering tutor (9712), Thok, Master of Dungeoneering (9713), Estrith (9714), Sonje (9715), Wiglaf (9716), null (9722), null (9723), Sagittare (9753), Sagittare (9754), Sagittare (9755), Sagittare (9756), Sagittare (9757), Sagittare (9758), Sagittare (9759), Sagittare (9760), Sagittare (9761), Sagittare (9762), Sagittare (9763), Sagittare (9764), Sagittare (9765), Sagittare (9766), Astea Frostweb (9965), Astea Frostweb (9966), Astea Frostweb (9967), Astea Frostweb (9968), Astea Frostweb (9969), Astea Frostweb (9970), Astea Frostweb (9971), Astea Frostweb (9972), Astea Frostweb (9973), Astea Frostweb (9974), Astea Frostweb (9975), Astea Frostweb (9976), Astea Frostweb (9977), Astea Frostweb (9978), Astea Frostweb (9979), Astea Frostweb (9980), Astea Frostweb (9981), Astea Frostweb (9982), Astea Frostweb (9983), Astea Frostweb (9984), Astea Frostweb (9985), Astea Frostweb (9986), Astea Frostweb (9987), Astea Frostweb (9988), Astea Frostweb (9989), Astea Frostweb (9990), Astea Frostweb (9991), Astea Frostweb (9992), Astea Frostweb (9993), Astea Frostweb (9994), Astea Frostweb (9995), Astea Frostweb (9996), Astea Frostweb (9997), Astea Frostweb (9998), Astea Frostweb (9999), Astea Frostweb (10000), Astea Frostweb (10001), Astea Frostweb (10002), Astea Frostweb (10003), Astea Frostweb (10004), Astea Frostweb (10005), Astea Frostweb (10006), Astea Frostweb (10007), Astea Frostweb (10008), Astea Frostweb (10009), Astea Frostweb (10010), Astea Frostweb (10011), Astea Frostweb (10012), Astea Frostweb (10013), Astea Frostweb (10014), Astea Frostweb (10015), Astea Frostweb (10016), Astea Frostweb (10017), Astea Frostweb (10018), Astea Frostweb (10019), Astea Frostweb (10020), Astea Frostweb (10021), Portal controller (10142), Earth warrior (10178), Earth warrior (10179), Earth warrior (10180), Earth warrior (10181), Earth warrior (10182), Earth warrior (10183), Earth warrior (10184), Earth warrior (10185), Earth warrior (10186), Earth warrior (10187), Necromancer (10196), Necromancer (10197), Necromancer (10198), Necromancer (10199), Necromancer (10200), Necromancer (10201), Necromancer (10202), Necromancer (10203), Necromancer (10204), Necromancer (10205), Necromancer (10206), Ice warrior (10225), Ice warrior (10226), Ice warrior (10227), Ice warrior (10228), Ice warrior (10229), Ice warrior (10230), Ice warrior (10231), Ice warrior (10232), Ice warrior (10233), Ice warrior (10234), Ice warrior (10235), Forgotten warrior (10246), Forgotten warrior (10247), Forgotten warrior (10248), Forgotten warrior (10249), Forgotten warrior (10250), Forgotten warrior (10251), Forgotten warrior (10252), Forgotten warrior (10253), Forgotten warrior (10254), Forgotten warrior (10255), Forgotten warrior (10256), Forgotten warrior (10257), Forgotten warrior (10258), Forgotten warrior (10259), Forgotten warrior (10260), Forgotten warrior (10261), Forgotten warrior (10262), Forgotten warrior (10263), Forgotten warrior (10264), Forgotten warrior (10265), Forgotten warrior (10266), Forgotten warrior (10267), Forgotten warrior (10268), Forgotten warrior (10269), Forgotten warrior (10270), Forgotten warrior (10271), Forgotten warrior (10272), Forgotten warrior (10273), Forgotten warrior (10274), Forgotten warrior (10275), Forgotten warrior (10276), Forgotten warrior (10277), Forgotten warrior (10278), Forgotten warrior (10279), Forgotten warrior (10280), Forgotten warrior (10281), Forgotten warrior (10282), Forgotten warrior (10283), Forgotten warrior (10284), Forgotten warrior (10285), Forgotten warrior (10286), Forgotten warrior (10287), Forgotten warrior (10288), Forgotten warrior (10289), Forgotten warrior (10290), Forgotten warrior (10291), Forgotten warrior (10292), Forgotten warrior (10293), Forgotten warrior (10294), Forgotten warrior (10295), Forgotten warrior (10296), Forgotten warrior (10297), Forgotten warrior (10298), Forgotten warrior (10299), Forgotten warrior (10300), Forgotten warrior (10301), Forgotten warrior (10302), Forgotten warrior (10303), Forgotten warrior (10304), Forgotten warrior (10305), Forgotten warrior (10306), Forgotten warrior (10307), Forgotten warrior (10308), Forgotten ranger (10320), Forgotten ranger (10321), Forgotten ranger (10322), Forgotten ranger (10323), Forgotten ranger (10324), Forgotten ranger (10325), Forgotten ranger (10326), Forgotten ranger (10327), Forgotten ranger (10328), Forgotten ranger (10329), Forgotten ranger (10330), Forgotten ranger (10331), Forgotten ranger (10332), Forgotten ranger (10333), Forgotten ranger (10334), Forgotten ranger (10335), Forgotten ranger (10336), Forgotten ranger (10337), Forgotten ranger (10338), Forgotten ranger (10339), Forgotten ranger (10340), Forgotten ranger (10341), Forgotten ranger (10342), Forgotten ranger (10343), Forgotten ranger (10344), Forgotten ranger (10345), Forgotten ranger (10346), Forgotten ranger (10347), Forgotten ranger (10348), Forgotten ranger (10349), Forgotten ranger (10350), Forgotten ranger (10351), Forgotten ranger (10352), Forgotten ranger (10353), Forgotten ranger (10354), Forgotten ranger (10355), Forgotten ranger (10356), Forgotten ranger (10357), Forgotten ranger (10358), Forgotten ranger (10359), Forgotten ranger (10360), Forgotten ranger (10361), Forgotten ranger (10362), Forgotten ranger (10363), Forgotten warrior (10397), Forgotten warrior (10398), Forgotten warrior (10399), Forgotten warrior (10400), Forgotten warrior (10401), Forgotten warrior (10402), Forgotten warrior (10403), Forgotten warrior (10404), Forgotten warrior (10405), Forgotten warrior (10406), Forgotten warrior (10407), Forgotten warrior (10408), Forgotten warrior (10409), Forgotten warrior (10410), Forgotten warrior (10411), Forgotten warrior (10412), Forgotten warrior (10413), Forgotten warrior (10414), Forgotten warrior (10415), Forgotten warrior (10416), Forgotten warrior (10417), Forgotten warrior (10418), Forgotten warrior (10419), Forgotten warrior (10420), Forgotten warrior (10421), Forgotten warrior (10422), Forgotten warrior (10423), Forgotten warrior (10424), Forgotten warrior (10425), Forgotten warrior (10426), Forgotten warrior (10427), Forgotten warrior (10428), Forgotten warrior (10429), Forgotten warrior (10430), Forgotten warrior (10431), Forgotten warrior (10432), Forgotten warrior (10433), Forgotten warrior (10434), Forgotten warrior (10435), Forgotten warrior (10436), Forgotten warrior (10437), Forgotten warrior (10438), Forgotten warrior (10439), Forgotten warrior (10440), Forgotten warrior (10441), Forgotten warrior (10442), Forgotten warrior (10443), Forgotten warrior (10444), Forgotten warrior (10445), Forgotten warrior (10446), Forgotten warrior (10447), Forgotten warrior (10448), Forgotten warrior (10449), Forgotten warrior (10450), Forgotten warrior (10451), Forgotten warrior (10452), Forgotten warrior (10453), Forgotten warrior (10454), Forgotten warrior (10455), Forgotten warrior (10456), Forgotten warrior (10457), Forgotten warrior (10458), Forgotten warrior (10459), Forgotten warrior (10507), Forgotten warrior (10508), Forgotten warrior (10509), Forgotten warrior (10510), Forgotten warrior (10511), Forgotten warrior (10512), Forgotten warrior (10513), Forgotten warrior (10514), Forgotten warrior (10515), Forgotten warrior (10516), Forgotten warrior (10517), Forgotten warrior (10518), Forgotten warrior (10519), Forgotten warrior (10520), Forgotten warrior (10521), Forgotten warrior (10522), Forgotten warrior (10523), Forgotten warrior (10524), Forgotten warrior (10525), Forgotten warrior (10526), Forgotten warrior (10527), Forgotten warrior (10528), Forgotten warrior (10529), Forgotten warrior (10530), Forgotten warrior (10531), Forgotten warrior (10532), Forgotten warrior (10533), Forgotten warrior (10534), Forgotten warrior (10535), Forgotten warrior (10536), Forgotten warrior (10537), Forgotten warrior (10538), Forgotten warrior (10539), Forgotten warrior (10540), Forgotten warrior (10541), Forgotten warrior (10542), Forgotten warrior (10543), Forgotten warrior (10544), Forgotten warrior (10545), Forgotten warrior (10546), Forgotten warrior (10547), Forgotten warrior (10548), Forgotten mage (10560), Forgotten mage (10561), Forgotten mage (10562), Forgotten mage (10563), Forgotten mage (10564), Forgotten mage (10565), Forgotten mage (10566), Forgotten mage (10567), Forgotten mage (10568), Forgotten mage (10569), Forgotten mage (10570), Forgotten mage (10571), Forgotten mage (10572), Forgotten mage (10573), Forgotten mage (10574), Forgotten mage (10575), Forgotten mage (10576), Forgotten mage (10577), Forgotten mage (10578), Forgotten mage (10579), Forgotten mage (10580), Forgotten mage (10581), Forgotten mage (10582), Forgotten mage (10583), Forgotten mage (10584), Forgotten mage (10585), Forgotten mage (10586), Forgotten mage (10587), Forgotten mage (10588), Forgotten mage (10589), Forgotten mage (10590), Forgotten mage (10591), Forgotten mage (10592), Forgotten mage (10593), Forgotten mage (10594), Forgotten mage (10595), Forgotten mage (10596), Forgotten mage (10597), Forgotten mage (10598), Forgotten mage (10599), Forgotten mage (10600), Forgotten mage (10601), Forgotten mage (10602), Forgotten mage (10603), Spiritual guardian (10700), Ankou (10736), Ankou (10737), Ankou (10738), Ankou (10739), Ankou (10740), Ankou (10741), Ankou (10742), Ankou (10743), Forgotten warrior (10843), Forgotten warrior (10844), Forgotten warrior (10845), Forgotten warrior (10846), Forgotten warrior (10847), Forgotten warrior (10848), Forgotten warrior (10849), Forgotten warrior (10850), Forgotten warrior (10851), Forgotten warrior (10852), Forgotten warrior (10853), Forgotten warrior (10854), Forgotten warrior (10855), Forgotten warrior (10856), Forgotten warrior (10857), Forgotten warrior (10858), Forgotten warrior (10859), Forgotten warrior (10860), Forgotten warrior (10861), Forgotten warrior (10862), Forgotten warrior (10863), Forgotten warrior (10864), Forgotten warrior (10865), Forgotten warrior (10866), Forgotten warrior (10867), Forgotten warrior (10868), Forgotten warrior (10869), Forgotten warrior (10870), Forgotten warrior (10871), Forgotten warrior (10872), Forgotten warrior (10873), Forgotten warrior (10874), Forgotten warrior (10875), Forgotten warrior (10876), Forgotten warrior (10877), Forgotten warrior (10878), Forgotten warrior (10879), Forgotten warrior (10880), Forgotten warrior (10881), Forgotten warrior (10882), Forgotten warrior (10883), Forgotten warrior (10884), Forgotten warrior (10885), Forgotten warrior (10886), Forgotten warrior (10887), Forgotten warrior (10888), Forgotten warrior (10889), Forgotten warrior (10890), Forgotten warrior (10891), Forgotten warrior (10892), Forgotten warrior (10893), Forgotten warrior (10894), Forgotten warrior (10895), Forgotten warrior (10896), Forgotten warrior (10897), Forgotten warrior (10898), Forgotten warrior (10899), Forgotten warrior (10900), Forgotten warrior (10901), Forgotten warrior (10902), Forgotten warrior (10903), Forgotten warrior (10904), Forgotten warrior (10905), Statue (10966), Statue (10967), Statue (10968), Fremennik scout (11001), Statue (11012), Statue (11013), Statue (11014), Statue (11015), Statue (11016), Statue (11017), Statue (11018), Statue (11019), Statue (11020), Statue (11021), Statue (11022), Statue (11023), Statue (11024), Statue (11025), Statue (11026), Statue (11027), Statue (11028), Statue (11029), Statue (11030), Statue (11031), Statue (11032), Statue (11033), Statue (11034), Statue (11035), Smuggler (11226), Poltergeist (11245), Astea Frostweb (11246), Mage statue (11247), Ranger statue (11248), Melee statue (11249), Mage statue (11250), Ranger statue (11251), Melee statue (11252), rand_skeletal_melee (11253), rand_skeletal_mage (11254), rand_skeletal_ranger (11255), Ravenous vampire (11264), Ravenous ghoul (11265), Stiles (11267), Market guard (11269), Guard (11271), Registrar (11272), Darren Lightfinger (11274), Guildmaster Darren Lightfinger (11275), Guildmaster Darren Lightfinger (11276), Guildmaster Darren Lightfinger (11277), Guildmaster Darren Lightfinger (11278), Chief Thief Robin (11280), Pickpocketing trainer (11281), Pickpocketing volunteer (11282), Pickpocketing volunteer (11284), Pickpocketing volunteer (11286), Coshing volunteer (11288), Coshing volunteer (11290), Coshing volunteer (11292), Locks and traps trainer (11294), Safe-cracking trainer (11295), Advanced pickpocketing trainer (11296), Dodgy Derek (11298), Mr Pinsworth (11299), Rick (11303), Maid (11304), Cook (11305), Butler (11306), Demon butler (11307), Mugger (level: 6) (11452), Roger Murray (11453), Moira (11455), Molly (11456), Botros (11458), Oliver B'Gard (11459), Richard Maney (11460), Clerk (11461), Court judge (11462), Jury (11463), Defender (11464), Prosecutor (11465), null (11466), null (11467), null (11468), null (11469), null (11470), null (11471), null (11472), null (11473), null (11474), Xenia (11476), null (11478), null (11479), Knight Bernard (11480), Knight Bernard (11481), null (11482), null (11483), Knight Ami (11484), Knight Ami (11485), null (11486), null (11487), Knight Diana (11488), Knight Diana (11489), Commodore Matthias (11493), Jessika (11494), Captain Tyr (11495), Knight Bernard (11496), null (11497), Commodore Matthias (11498), Jessika (11499), null (11500), null (11501), null (11502), null (11503), null (11504), null (11505), Commander Korasi (11506), Commander Korasi (11507), Commander Korasi (11508), null (11509), Captain Tyr (11510), Commodore Tyr (11511), Sir Tiffy (11512), null (11513), null (11514), null (11515), null (11516), null (11517), null (11518), null (11519), null (11520), null (11521), Knight Ami (11522), Knight Diana (11523), Terry Gord (11524), Mrs Gord (11525), Knight Mikhal (11526), Mariah (11527), Mariah (11528), Squire Sam (11529), Knight Bernard (11530), Mysterious figure (11538), Commodore Matthias (11539), Knight Diana (11541), Knight Bernard (11542), Knight Ami (11543), Squire Sam (11544), Knight Mikhal (11545), Milk seller (11547), Commodore Matthias (11548), Commander Korasi (11549), Knight Diana (11550), Knight Bernard (11551), Knight Ami (11552), Wise Old Man (11568), Wise Old Man (11569), Zenevivia (11571), Wise Old Man (11575), Zenevivia (11577), Zenevivia (11578), Zenevivia (11579), Zenevivia (11580), Zenevivia (11581), Zenevivia (11582), Wise Old Man (11583), Zenevivia (11599), Sedridor (11601), Wizard Mizgog (11602), Wizard Grayzag (11603), Traiborn (11604), Dionysius (11607), Dionysius (11608), Dionysius (11609), Dionysius (11610), Dionysius (11611), Dionysius (11612), Zenevivia (11613), Zenevivia (11614), Zenevivia (11615), Zenevivia (11616), Zenevivia (11617), Yambo (11618), Yambo (11619), My Name Rocks (11623), Pee Ker XXL (11624), Mabel (11625), Zenevivia (11628), Mabel (11631), Guthix wizard (11638), Guthix wizard (11639), Ali Tist (11642), Ali Tist (11643), Customer (11645), Customer (11647), Captain Korasi (11648), Jessika (11660), Shopkeeper Kofi (11674), Shopkeeper Kofi (11675), Bartender (11676), Shop assistant (11678), Shop assistant (11679), Chemist (11680), Commodore Tyr (11682), Captain Korasi (11683), Jessika (11684), Black Knight guard (11685), Indentured worker (11687), Laden indentured worker (11688), Laden indentured worker (11689), Black Knight doorkeeper (11690), Black Knight doorkeeper (11692), Indentured worker (11693), Indentured worker (11694), Indentured worker (11695), Black Knight guardian (11696), Black Knight guardian (11697), Void leech (11698), Gerrant (11699), Captain Tobias (11700), Seaman Lorris (11701), Seaman Thresnor (11702), Captain Tobias (11703), Seaman Lorris (11704), Seaman Thresnor (11705), Bartender (11706), Bartender (11707), Portal controller (11721), Necrolord (11737), Necrolord (11738), Necrolord (11739), Necrolord (11740), Necrolord (11741), Necrolord (11742), Necrolord (11743), Necrolord (11744), Necrolord (11745), Necrolord (11746), Necrolord (11747), Necrolord (11748), Necrolord (11749), Necrolord (11750), Necrolord (11751), Mysterious mage (11887), Mysterious mage (11888), Mysterious mage (11889), Mysterious mage (11890), Mysterious mage (11891), Mysterious mage (11892), Mysterious mage (11893), Mysterious mage (11894), Skeletal warrior (11940), Skeletal warrior (11941), Skeletal warrior (11942), Skeletal warrior (11943), Skeletal warrior (11944), Skeletal warrior (11945), Skeletal warrior (11946), Skeletal warrior (11947), Skeletal warrior (11948), Skeletal warrior (11949), Skeletal warrior (11950), Skeletal warrior (11951), Skeletal warrior (11952), Skeletal warrior (11953), Skeletal warrior (11954), Skeletal warrior (11955), Skeletal warrior (11956), Skeletal warrior (11957), Skeletal warrior (11958), Skeletal warrior (11959), Skeletal warrior (11960), Skeletal warrior (11961), Skeletal warrior (11962), Skeletal warrior (11963), Skeletal warrior (11964), Skeletal warrior (11965), Skeletal warrior (11966), Skeletal warrior (11967), Skeletal warrior (11968), Skeletal warrior (11969), Skeletal warrior (11970), Skeletal warrior (11971), Skeletal warrior (11972), Skeletal warrior (11973), Skeletal warrior (11974), Skeletal warrior (11975), Skeletal warrior (11976), Skeletal warrior (11977), Skeletal warrior (11978), Skeletal warrior (11979), Skeletal warrior (11980), Skeletal warrior (11981), Skeletal warrior (11982), Skeletal warrior (11983), Skeletal warrior (11984), Skeletal sorcerer (11999), Skeletal sorcerer (12000), Skeletal sorcerer (12001), Skeletal sorcerer (12002), Skeletal sorcerer (12003), Skeletal sorcerer (12004), Skeletal sorcerer (12005), Skeletal sorcerer (12006), Skeletal sorcerer (12007), Skeletal sorcerer (12008), Skeletal sorcerer (12009), Skeletal sorcerer (12010), Skeletal sorcerer (12011), Skeletal sorcerer (12012), Skeletal sorcerer (12013), Skeletal sorcerer (12014), Skeletal sorcerer (12015), Skeletal sorcerer (12016), Skeletal sorcerer (12017), Skeletal sorcerer (12018), Skeletal sorcerer (12019), Skeletal sorcerer (12020), Skeletal sorcerer (12021), Skeletal sorcerer (12022), Skeletal sorcerer (12023), Skeletal sorcerer (12024), Skeletal sorcerer (12025), Skeletal sorcerer (12026), Skeletal sorcerer (12027), Skeletal sorcerer (12028), Skeletal sorcerer (12029), Skeletal sorcerer (12030), Skeletal sorcerer (12031), Skeletal sorcerer (12032), Skeletal sorcerer (12033), Skeletal sorcerer (12034), Skeletal sorcerer (12035), Skeletal sorcerer (12036), Skeletal sorcerer (12037), Skeletal sorcerer (12038), Skeletal sorcerer (12039), Skeletal sorcerer (12040), Skeletal sorcerer (12041), Skeletal sorcerer (12042), Skeletal sorcerer (12043), Skeletal archer (12044), Skeletal archer (12045), Skeletal archer (12046), Skeletal archer (12047), Skeletal archer (12048), Skeletal archer (12049), Skeletal archer (12050), Skeletal archer (12051), Skeletal archer (12052), Skeletal archer (12053), Skeletal archer (12054), Skeletal archer (12055), Skeletal archer (12056), Skeletal archer (12057), Skeletal archer (12058), Skeletal archer (12059), Skeletal archer (12060), Skeletal archer (12061), Skeletal archer (12062), Skeletal archer (12063), Skeletal archer (12064), Skeletal archer (12065), Skeletal archer (12066), Skeletal archer (12067), Skeletal archer (12068), Skeletal archer (12069), Skeletal archer (12070), Skeletal archer (12071), Skeletal archer (12072), Skeletal archer (12073), Skeletal archer (12074), Skeletal archer (12075), Skeletal archer (12076), Skeletal archer (12077), Skeletal archer (12078), Skeletal archer (12079), Skeletal archer (12080), Skeletal archer (12081), Skeletal archer (12082), Skeletal archer (12083), Skeletal archer (12084), Skeletal archer (12085), Skeletal archer (12086), Skeletal archer (12087), Skeletal archer (12088), Statue (12106), Statue (12107), Statue (12108), Statue (12109), Statue (12110), Statue (12111), Statue (12112), Statue (12113), Statue (12114), Enemy Scout (12162), Enemy Foot Soldier (12163), Enemy Halberdier (12164), Archer (12178), Mage (12179), Knight (12180), Enemy Champion (12181), Enemy Archer (12182), Enemy Mage (12183), Enemy Knight (12184) +Linked graphics: 56, 432, 560, 720, 1174, 1557, 1578, 1956, 1957, 1971, 2205, 2685, 2693, 2694, 2695, 2696, 2697, 2743 +Linked objects: Sir Palomedes (2901), Commodore Matthias (4458), Korasi (4459), Diana (4460), Bernard (4461), Ami (4463), Commodore Matthias (4480), Commodore Matthias (4481), Commodore Matthias (4908), Commodore Matthias (4910), Commodore Matthias (4911), Commodore Matthias (4912), Korasi (7390), John Everyman (12962), null (12964), Clive Dresdon (12966), Burt McKrakon (12967), Mavis Grey (12969), Korasi (13495), Korasi (13496), Korasi (15385), Music appreciator (16037), Music appreciator (16038), Music appreciator (16039), Music appreciator (16040), Music appreciator (16041), Music appreciator (16045), Music appreciator (16046), Korasi (20322), Fremennik warrior (25365), Fremennik warrior (25366), Sir Lucan (25664), Sir Lancelot (25666), Sir Bedivere (25667), Korasi (25891), Diana (25892), Diana (25893), Diana (25894), Diana (25948), Diana (25949), Diana (25950), Bernard (25951), Bernard (25952), Bernard (25968), Bernard (25976), Bernard (25977), Bernard (26001), Ami (26003), Ami (26018), Ami (26019), Ami (26488), Ami (26489), Ami (26490), Ezekial Lovecraft (29738), Customs Sergeant (31459), Fremennik warrior (35929), Sir Vant (37582), Warrior woman (39184), Clive (39185), Guard (39215), Guard (39216), Guard (39217), Guard (39218), Guard (39219), Wounded guardian (41167), Unconscious guardian (41168), Dermot (44280), Ardal (44281), Frank (44282), Cookie (44317), Border guard (45856), Border guard (45857), Border guard (45858), Border guard (45859), Border guard (45862), Border guard (45863), Silas (47251) + +Base: 1 +Linked animations: [2055, 2056, 2057] +Linked objects: null (6657) + +Base: 2 +Linked animations: [2054] +Linked objects: Blue tears (6661), Green tears (6662), Blue tears (6665), Green tears (6666) + +Base: 3 +Linked animations: [2051, 2052, 2053, 10937, 10938] +Linked NPCs: Light creature (2021), Light creature (2022), Light creature (4325), Light creature (8454), Light creature (8455) +Linked graphics: 1932, 1933 + +Base: 4 +Linked animations: [2058] +Linked graphics: 397 + +Base: 5 +Linked animations: [1535, 2172, 2260, 2996, 12549] +Linked graphics: 409, 503, 504 +Linked objects: Abyssal rift (7171) + +Base: 6 +Linked animations: [2174, 2175, 2176, 2177] +Linked objects: null (7181) + +Base: 7 +Linked animations: [2178] +Linked objects: Fire rift (7129), Earth rift (7130), Body rift (7131), Cosmic rift (7132), Nature rift (7133), Chaos rift (7134), Law rift (7135), Death rift (7136), Water rift (7137), Soul rift (7138), Air rift (7139), Mind rift (7140), Blood rift (7141), Etching (41044), Etching (41046), Etching (41048), Etching (41050) + +Base: 8 +Linked animations: [2173] +Linked objects: Tendrils (7189), Tendrils (7190), Tendrils (7191), Stinking tendrils (16109), Dripping tendrils (16110), Tendrils (16111), Tendrils (27294), Tendrils (27295), Tendrils (27296) + +Base: 9 +Linked animations: [2179, 2180, 2181, 2182, 2183] +Linked NPCs: Abyssal leech (2263) + +Base: 10 +Linked animations: [2184, 2185, 2186, 2187, 2188, 2189] +Linked NPCs: Abyssal guardian (2264) + +Base: 11 +Linked animations: [2190, 2191, 2192, 2193, 2194] +Linked NPCs: Abyssal walker (2265) + +Base: 12 +Linked animations: [2871] +Linked objects: null (10186), null (10237), null (16650), null (16662) + +Base: 13 +Linked animations: [2346] +Linked objects: Viking Boat (8926), Viking Boat (25298), Brundt's boat (47261) + +Base: 14 +Linked animations: [2359, 2360] +Linked objects: Flag (8954), Flag (8955), Bank deposit box (39830) + +Base: 15 +Linked animations: [2362] +Linked NPCs: Egg (2450) + +Base: 16 +Linked animations: [2849, 2850, 2851, 2852, 2853, 2854, 2855, 2856] +Linked NPCs: Dagannoth Supreme (2881), Dagannoth Prime (2882), Dagannoth Rex (2883) + +Base: 17 +Linked animations: [2857, 2858, 2859, 2860, 2861, 2862] +Linked NPCs: Rock lobster (2889) + +Base: 18 +Linked animations: [2363, 2364, 2365, 2366, 2367] +Linked NPCs: Wallasalki (2457), Wallasalki (2884), Wallasalki (9096) + +Base: 19 +Linked animations: [2863, 2864, 2865, 2866, 2867, 2868, 2869] +Linked NPCs: Spinolyp (2892), Spinolyp (2894), Spinolyp (2896) + +Base: 20 +Linked animations: [2347, 2348, 2349, 2350] +Linked objects: Door (8958), Door (8959), Door (8960), Door (8961), Door (8962), Door (8963) + +Base: 21 +Linked animations: [2872] +Linked graphics: 473 + +Base: 22 +Linked animations: [2873] +Linked graphics: 474 + +Base: 23 +Linked animations: [2874] +Linked graphics: 475 + +Base: 24 +Linked animations: [2875] +Linked graphics: 476 + +Base: 25 +Linked animations: [2848] +Linked graphics: 477 + +Base: 26 +Linked animations: [9592] +Linked objects: Standing Torch (10178), Standing Torch (10179) + +Base: 27 +Linked animations: [2351, 2352, 2353, 2354, 2355, 2356, 2357, 2358] +Linked NPCs: Door (2441), Door (2442), Door-support (2443), Door (2444), Door (2445), Door-support (2446), Door (2447), Door (2448) + +Base: 28 +Linked animations: [2131] +Linked objects: null (6949) + +Base: 29 +Linked animations: [2132] +Linked graphics: 406 + +Base: 30 +Linked animations: [1812] +Linked objects: null (5921) + +Base: 31 +Linked animations: [2126] +Linked NPCs: Fishing spot (2067), Fishing spot (2068), Fishing spot (5748), Fishing spot (5749), Fishing spot (7636) + +Base: 32 +Linked animations: [1774, 1775, 1776, 1777, 1778, 1779, 1780] + +Base: 33 +Linked animations: [1783, 1784, 1785, 1786, 1787, 2118, 2119, 2120, 2121, 2122, 2123, 2124, 2125, 4210, 4211] +Linked NPCs: Nardok (4312) + +Base: 34 +Linked animations: [1781, 1782] +Linked NPCs: Cave bug larva (1833) + +Base: 35 +Linked animations: [1788, 1789, 1790, 1791, 1792] +Linked NPCs: Cave slime (1831), Cave slime (10696) + +Base: 36 +Linked animations: [1793, 1794, 1795, 1796, 1797, 2374, 2375] +Linked NPCs: null (390), null (391), null (392), null (393), null (394), null (395), null (396), null (403), Giant frog (1828), Big frog (1829), Frog (1830), Frog Herald (2472), Frog (2689), Frog (3300), Frog (8636), Frog (8637), Frog (8638) + +Base: 37 +Linked animations: [1798, 1799, 1800, 1801, 1802, 1803, 1804, 1805, 1806, 1807, 1808] +Linked NPCs: Hole in the wall (2058), Wall beast (7823) + +Base: 38 +Linked animations: [3028] +Linked objects: null (10761) + +Base: 39 +Linked animations: [3022] +Linked objects: null (10715), null (10716), null (10717), null (10718) + +Base: 40 +Linked animations: [3030, 3031] +Linked objects: Telekinetic Teleport (10778), Enchanters Teleport (10779), Alchemists Teleport (10780), Graveyard Teleport (10781), Exit Teleport (10782) + +Base: 41 +Linked animations: [3029] +Linked objects: Statue (10738), Statue (10739) + +Base: 42 +Linked animations: [3023] +Linked NPCs: Flying Book (3094), Flying Book (3095), Animated book (10744), Animated book (10745), Animated book (10746), Animated book (10747), Animated book (10748), Animated book (10749), Animated book (10750), Animated book (10751), Animated book (10752), Animated book (10753) + +Base: 43 +Linked animations: [3025] + +Base: 44 +Linked animations: [3033, 3034, 3035] +Linked NPCs: Entrance Guardian (3097), Telekinetic Guardian (3098), Alchemy Guardian (3099), Enchantment Guardian (3100), Graveyard Guardian (3101), Maze Guardian (3102), Rewards Guardian (3103), null (9435), Rune guardian (9436), null (9438), Rune guardian (9439), Rune guardian (9460), Rune guardian (9461), Rune guardian (9642), Rune guardian (9643), Rune guardian (9644), Rune guardian (9645), Rune guardian (9646), Rune guardian (9647), Rune guardian (9648), Rune guardian (9649), Rune guardian (9650), Rune guardian (9651), Rune guardian (9652), Rune guardian (9653), Rune guardian (9654), Rune guardian (9655), Rune guardian (9656), Rune guardian (9657), Rune guardian (9658), Rune guardian (9659), Rune guardian (9660), Rune guardian (9661), Rune guardian (9662), Rune guardian (9663), Rune guardian (9664), Rune guardian (9665), Rune guardian (9666), Rune guardian (9667), Rune guardian (9668), Rune guardian (9669) + +Base: 45 +Linked animations: [3026, 3027, 3244, 3245] +Linked NPCs: Charmed Warrior (3104), Charmed Warrior (3105), Charmed Warrior (3106), Charmed Warrior (3107), Sweeper (3298) + +Base: 46 +Linked animations: [3021] +Linked graphics: 520, 521, 522, 523 + +Base: 47 +Linked animations: [3024] +Linked graphics: 519 + +Base: 48 +Linked animations: [2772, 2773] +Linked NPCs: Fishbowl (8737), Fishbowl (8738), Fishbowl (8739) + +Base: 49 +Linked animations: [2216] + +Base: 50 +Linked animations: [2202, 2203] +Linked objects: Floor (7230) + +Base: 51 +Linked animations: [2205] + +Base: 52 +Linked animations: [2204] +Linked objects: Pendulum (7241), Pendulum (49659), Pendulum (49660), Pendulum (49661), Pendulum (54309) + +Base: 53 +Linked animations: [2200, 2201] +Linked objects: Wall (7229) + +Base: 54 +Linked animations: [2212] +Linked NPCs: Spin Blades (2272), Spin Blades (2273) +Linked objects: Spin Blades (7253) + +Base: 55 +Linked animations: [2207] + +Base: 56 +Linked animations: [2211] + +Base: 57 +Linked animations: [2208, 2209] +Linked objects: Wall (7248), Trap (10034), Wall (49656), Wall (49657), Wall (49658), Wall (54308) + +Base: 58 +Linked animations: [2197, 2198] +Linked objects: Wall (7225) + +Base: 59 +Linked animations: [2195, 2196] +Linked objects: Wall (7228) + +Base: 60 +Linked animations: [2213, 2214, 2215] + +Base: 61 +Linked animations: [3940] +Linked objects: Banner (14755), Banner (14756), Banner (14757) + +Base: 62 +Linked animations: [3943] +Linked objects: Rock (14814), Rock (14815), Rock (14816), Rock (14817) + +Base: 63 + +Base: 64 +Linked animations: [3144, 3145, 3146, 3147, 3148, 3149] +Linked NPCs: Chaos Elemental (3200) + +Base: 65 +Linked animations: [3153] +Linked graphics: 554 + +Base: 66 +Linked animations: [3150] +Linked graphics: 550, 553, 556 + +Base: 67 +Linked animations: [3152, 5359, 5399] +Linked graphics: 552, 555, 865, 971 + +Base: 68 +Linked animations: [3151, 5358] +Linked graphics: 551, 557, 970 + +Base: 69 +Linked animations: [3154, 3155] + +Base: 70 +Linked animations: [3156] +Linked graphics: 558 + +Base: 71 +Linked animations: [3158, 7079] +Linked graphics: 559, 1225 + +Base: 72 +Linked animations: [3942, 4625] +Linked graphics: 660, 782 + +Base: 73 +Linked animations: [3941] +Linked graphics: 659, 783 + +Base: 74 +Linked animations: [3305] +Linked objects: A sinking canoe (12159), A sinking canoe (12160), A sinking canoe (12161), A sinking canoe (12162) + +Base: 75 +Linked animations: [3304] +Linked objects: Canoe station (12145), Canoe station (12151), Canoe station (12152), Canoe station (12153), Canoe station (12154) + +Base: 76 +Linked animations: [3306] +Linked objects: null (12168), null (12169), null (12170), null (12171) + +Base: 77 +Linked animations: [4119, 4120, 4121, 4122] + +Base: 78 +Linked animations: [1824, 1825, 1826, 1827, 3874, 3875, 3876, 3877] + +Base: 79 + +Base: 80 +Linked animations: [584, 585, 586, 587] + +Base: 81 +Linked animations: [580] + +Base: 82 +Linked animations: [554, 555, 556, 557, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 1637, 1854, 1991, 2674, 3321, 3510, 3512, 3513, 3514, 3515, 3516, 3517, 3518, 3519, 3520, 3521, 3522, 4221, 4587, 4588, 4589, 4590, 7651, 10084] + +Base: 83 +Linked animations: [1126] +Linked graphics: 1178 + +Base: 84 +Linked animations: [558, 559, 560, 561] + +Base: 85 +Linked animations: [1109] +Linked graphics: 270 + +Base: 86 +Linked animations: [1111, 1112, 1420, 5632, 10707] +Linked objects: Floor spikes (3582), Floor (7227), Strange floor (9294), Strange floor (9326), Floor (20271), Floor (20915), Floor (20916), Floor (20917), Floor (20918), Floor (20919), Floor (28525), Floor (31350), Floor spikes (36712), Floor (41381), Floor (41382) + +Base: 87 +Linked animations: [1104] +Linked objects: Plank (3577) + +Base: 88 +Linked animations: [1108] +Linked objects: Ticket Dispenser (3581) + +Base: 89 +Linked animations: [1107, 2199, 2206] +Linked objects: Spinning blades (7224), Spinning blades (49662), Spinning blades (49663), Spinning blades (49664), Spinning blades (54310) + +Base: 90 +Linked animations: [12596, 12597] +Linked graphics: 2267, 2268 + +Base: 91 +Linked animations: [1103, 2210] +Linked objects: Blade (3567), Blade (7252), null (37432) + +Base: 92 +Linked animations: [3070] +Linked objects: Stone block (10875), null (10877), null (10878), null (10879), null (10880), null (10881) + +Base: 93 +Linked animations: [2069, 2070, 2071, 2072, 2073] +Linked NPCs: Bloodworm (2031) + +Base: 94 +Linked animations: [2086, 2087] +Linked graphics: 400, 401 + +Base: 95 +Linked animations: [2083] +Linked graphics: 398 + +Base: 96 +Linked animations: [2084] +Linked graphics: 399 + +Base: 97 +Linked animations: [2439] +Linked objects: Smoke (9099), Smoke (9115), Pipes (9117), Pipes (9121), Smoke (9123) + +Base: 98 +Linked animations: [2435, 2437] +Linked objects: Conveyor belt (9100), Conveyor belt (9101) + +Base: 99 +Linked animations: [2436, 2438] + +Base: 100 +Linked animations: [2451] +Linked objects: Drive belt (9103), Cogs (9105) + +Base: 101 +Linked animations: [2434] + +Base: 102 +Linked animations: [2440] +Linked objects: Bar dispenser (9094) + +Base: 103 +Linked animations: [2452, 2453, 2454, 2455, 2456, 2457, 2458, 2459, 2460, 2461, 2462, 2463, 2464, 2465, 2466, 2467, 2468, 2469, 2470, 2471, 2472, 2473, 2474, 2475, 2476, 2477, 2478, 2479, 2480, 2481, 2482, 2483, 2484, 2485, 2486, 2487, 2488, 2489, 2490, 2491, 2492, 2493, 2494, 2495, 2496, 2497, 2498, 2499, 2500, 2501, 2502, 2503, 2504, 2505, 2506, 2507, 2508, 2509, 2510, 2511, 2512, 2513, 2514, 2515, 2516, 2517, 2518, 2519, 2520, 2521, 2522, 2523, 2524, 2525, 2526, 2527, 2528, 2529, 2530, 2531, 2532, 2533, 2534, 2535, 2536, 2537, 2538, 2539, 2540, 2541, 2542, 2543, 2544, 2545, 2546, 2547, 2548, 2549, 2550, 2551, 2552] + +Base: 104 +Linked animations: [2448, 2449] + +Base: 105 +Linked animations: [2444, 2445, 2446, 2447] + +Base: 106 +Linked animations: [1430] +Linked objects: Saradomin flag (4900), Zamorak flag (4901), Saradomin flag (4902), Zamorak flag (4903), null (4906), null (4907), Swordshop Sign (5826) + +Base: 107 +Linked animations: [14176] +Linked graphics: 2691 + +Base: 108 +Linked animations: [1433] +Linked objects: Energy Barrier (52760), Energy Barrier (52761) + +Base: 109 +Linked animations: [1432] + +Base: 110 +Linked animations: [2976] + +Base: 111 +Linked animations: [2945, 2946, 2947, 2948, 2949, 2950, 2951, 2952] +Linked NPCs: Earth Warrior Champion (3057) + +Base: 112 +Linked animations: [2931, 2932] + +Base: 113 + +Base: 114 +Linked animations: [2969, 2970] +Linked graphics: 495, 496 + +Base: 115 +Linked animations: [2957] +Linked graphics: 494 + +Base: 116 +Linked animations: [2965, 6133] +Linked graphics: 488 + +Base: 117 + +Base: 118 +Linked animations: [2960] +Linked graphics: 490 + +Base: 119 +Linked animations: [2956] +Linked graphics: 493 + +Base: 120 +Linked animations: [3320] + +Base: 121 +Linked animations: [3309, 3310, 3311, 3312, 3313, 3314, 3315] +Linked NPCs: Giant Mole (3340), Baby Mole (3341), Baby Mole (3342), Baby Mole (3343) + +Base: 122 +Linked animations: [3317] +Linked graphics: 571 + +Base: 123 +Linked animations: [3318] +Linked graphics: 572 + +Base: 124 +Linked animations: [3319] +Linked graphics: 573 + +Base: 125 +Linked animations: [3316] +Linked graphics: 570 + +Base: 126 +Linked animations: [3927] +Linked objects: Banner (14283) + +Base: 127 +Linked animations: [3939] +Linked objects: Cauldron of Thunder (2142), Cauldron (14360), Cauldron (17161), Cauldron (17162), null (17163), Cauldron (40104) + +Base: 128 +Linked animations: [3925] + +Base: 129 +Linked animations: [3905, 3928, 3929, 3930, 3933, 3934, 3935, 3936, 3937, 3938, 6878, 6879, 6880, 6881, 6882, 6883, 6884, 6885, 6886] +Linked NPCs: Portal (6142), Portal (6143), Portal (6144), Portal (6145), Portal (6146), Portal (6147), Portal (6148), Portal (6149), Portal (6150), Portal (6151), Portal (6152), Portal (6153), Portal (6154), Portal (6155), Portal (6156), Portal (6157) +Linked graphics: 654 + +Base: 130 +Linked animations: [3932] +Linked objects: null (14310), null (14311), null (14312), null (14313) + +Base: 131 +Linked animations: [3892, 3893, 3894, 3895, 3896, 3897, 6870] +Linked NPCs: Brawler (3772), Brawler (3773), Brawler (3774), Brawler (3775), Brawler (3776), Brawler (11531) + +Base: 132 +Linked animations: [3918, 3919, 3920, 3921, 3922, 6872] +Linked NPCs: Defiler (3762), Defiler (3763), Defiler (3764), Defiler (3765), Defiler (3766), Defiler (3767), Defiler (3768), Defiler (3769), Defiler (3770), Defiler (3771), Defiler (11536), Defiler (11537) + +Base: 133 +Linked animations: [3913, 3914, 3915, 3916, 3917, 6871] +Linked NPCs: Ravager (3742), Ravager (3743), Ravager (3744), Ravager (3745), Ravager (3746) + +Base: 134 +Linked animations: [3898, 3899, 3900, 3901, 3902, 3903, 3904] +Linked NPCs: Shifter (3732), Shifter (3733), Shifter (3734), Shifter (3735), Shifter (3736), Shifter (3737), Shifter (3738), Shifter (3739), Shifter (3740), Shifter (3741), Shifter (11532), Shifter (11533) + +Base: 135 +Linked animations: [3906, 3907, 3908, 3909, 3910, 6876] +Linked NPCs: Spinner (3747), Spinner (3748), Spinner (3749), Spinner (3750), Spinner (3751), Spinner (11491) + +Base: 136 +Linked animations: [3886, 3887, 3888, 3890, 3891, 6869] +Linked NPCs: Splatter (3727), Splatter (3728), Splatter (3729), Splatter (3730), Splatter (3731), Splatter (11490) + +Base: 137 +Linked animations: [3878, 3879, 3880, 3881, 3882, 6868] +Linked NPCs: Torcher (3752), Torcher (3753), Torcher (3754), Torcher (3755), Torcher (3756), Torcher (3757), Torcher (3758), Torcher (3759), Torcher (3760), Torcher (3761), Torcher (11492), Torcher (11534), Torcher (11535), Torcher (11546) + +Base: 138 +Linked animations: [3923, 3924] +Linked graphics: 655, 657 + +Base: 139 +Linked animations: [3911] + +Base: 140 +Linked animations: [3912] +Linked graphics: 658 + +Base: 141 +Linked animations: [3889] +Linked graphics: 649, 650, 651, 652, 653 + +Base: 142 +Linked animations: [3883] +Linked graphics: 646 + +Base: 143 +Linked animations: [3885] +Linked graphics: 648 + +Base: 144 +Linked animations: [3884] +Linked graphics: 647 + +Base: 145 +Linked animations: [3748, 3749, 3750, 3751, 3752, 3753, 3754, 3755, 3756, 3757, 3758, 3759, 3760, 3761, 3762, 3763, 3764, 3765, 3766, 3767, 3768, 3769, 3770, 3771, 3772, 3773, 3774, 3775, 3776, 3778, 3779, 3780, 3781, 3782, 3783, 3784, 3785, 3786, 3787, 3788, 3789, 3790, 3791, 3792, 3793, 3794, 3795, 3796, 3797, 3798, 3799, 3800, 3801, 3802, 5910, 5911, 5912, 5913, 5914, 5915, 5916, 5917, 5918, 5919, 5920, 5921, 5922, 5923, 5924, 5925, 5926, 5927, 5928, 5929, 5930, 5931, 5932, 5933, 5934, 5935, 5936, 5937, 5938, 5939, 5940, 5941, 5942, 5943, 5944, 5945, 5946, 5947, 5948, 5949, 5950, 5951, 5952, 5953, 5954, 5955, 5956, 5957, 5958, 5959, 5960, 5961, 5962, 5963, 5964] + +Base: 146 +Linked animations: [3777] + +Base: 147 +Linked animations: [3742, 3743, 5769] +Linked objects: Row boat (13841), Ripples (13842), Rowboat (18187), null (18188), null (18323), null (18402), Plank (19126), Crate (20510), Barrel (20511), null (21100), null (21110), null (21111), Stepping Stone (21120), Stepping Stone (21121), Stepping Stone (21122), Stepping Stone (21123), Stepping Stone (21124), Boat (21176), Boat (21177), null (26413), Crate (30288), Large rowboat (30337), Ripples (40086) + +Base: 148 +Linked animations: [3721, 3722, 3723, 3724, 3726, 3727] +Linked NPCs: Giant snail (3612), Giant snail (3613), Giant snail (3614) + +Base: 149 +Linked animations: [3728, 3730, 3731, 3732, 3733] +Linked NPCs: Head (3619), Head (3620) + +Base: 150 +Linked animations: [3744] +Linked graphics: 625 + +Base: 151 +Linked animations: [3725] +Linked graphics: 627 + +Base: 152 +Linked animations: [2821, 2823, 2825, 2827] +Linked NPCs: Half-Zombie (2870) + +Base: 153 +Linked animations: [2822, 2824, 2826] +Linked NPCs: Other Half-Zombie (2871) + +Base: 154 +Linked animations: [2834] +Linked graphics: 469 + +Base: 155 +Linked animations: [2830] +Linked graphics: 467 + +Base: 156 +Linked animations: [2832] +Linked graphics: 468 + +Base: 157 +Linked animations: [2828] +Linked graphics: 466 + +Base: 158 +Linked animations: [2601, 2602, 2603, 2604, 2605, 2606, 2607, 2608, 2609, 2610, 2611, 2612, 2613] + +Base: 159 +Linked animations: [2650, 2651, 2652, 2653, 2654, 2655, 2656] + +Base: 160 +Linked animations: [2618, 2619, 2620, 2621, 2622] +Linked NPCs: Giant bat (3711) + +Base: 161 +Linked animations: [2642, 2643, 2644, 2645, 2646, 2647] + +Base: 162 +Linked animations: [2623, 2624, 2625, 2626, 2627] + +Base: 163 +Linked animations: [2634, 2635, 2636, 2637, 2638, 2639] + +Base: 164 +Linked animations: [2628, 2629, 2630, 2631, 2632, 2633] + +Base: 165 +Linked animations: [2616] +Linked graphics: 439 + +Base: 166 +Linked animations: [2648] +Linked graphics: 445 + +Base: 167 +Linked animations: [2649] +Linked graphics: 446 + +Base: 168 +Linked animations: [2659] +Linked graphics: 448, 449, 450 + +Base: 169 +Linked animations: [2658] +Linked graphics: 447 + +Base: 170 +Linked animations: [2615] +Linked graphics: 442 + +Base: 171 +Linked animations: [2640] +Linked graphics: 444 + +Base: 172 +Linked animations: [2719] +Linked graphics: 453 + +Base: 173 +Linked animations: [2660] +Linked graphics: 451 + +Base: 174 +Linked animations: [2598] +Linked objects: null (9353), Open hot vent door (9366), Hot vent door (9367), Hot vent door (9368), Hot vent door (9369) + +Base: 175 +Linked animations: [2641] +Linked objects: Lava forge (9390) + +Base: 176 +Linked animations: [6500] +Linked objects: Beanstalk (24736) + +Base: 177 +Linked animations: [2600] +Linked objects: Egg (9377), Egg (9378), Egg (9379) + +Base: 178 +Linked animations: [2599] + +Base: 179 +Linked animations: [2657, 10372, 10373] +Linked objects: Viewing orb (9391), null (9392), Viewing orb (28194), Low-level orb (28209), Mid-level orb (28210), High-level orb (28211), null (28212), Viewing orb (38693) + +Base: 180 +Linked animations: [1598, 1599, 1600] +Linked objects: Goal (5146) + +Base: 181 +Linked animations: [1614, 1615, 1616, 1617, 1618] +Linked NPCs: Experiment (1677) + +Base: 182 +Linked animations: [1609, 1610, 1611, 1612, 1613] +Linked NPCs: Experiment (1678) + +Base: 183 +Linked animations: [1607, 1608, 2567, 2568] +Linked NPCs: Skullball (1659) + +Base: 184 + +Base: 185 + +Base: 186 +Linked animations: [11550, 11551] +Linked NPCs: Easter Bird (7417), Easter Bird (7418), Easter Bird (7419), Easter Bird (9696) + +Base: 187 +Linked animations: [3853] +Linked NPCs: Egg (3682), Egg (3683), Egg (3684), Egg (3685) + +Base: 188 + +Base: 189 +Linked animations: [6125] + +Base: 190 +Linked animations: [3008, 3009, 3010, 3011, 3012, 3013, 3014] +Linked NPCs: Rosie (3082), Sorcha (3083), Cait (3084), Cormac (3085), Fionn (3086), Donnacha (3087), Ronan (3088) + +Base: 191 +Linked animations: [3016, 3017, 3018, 3019] +Linked graphics: 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518 + +Base: 192 +Linked animations: [3020] +Linked graphics: 506 + +Base: 193 + +Base: 194 + +Base: 195 + +Base: 196 + +Base: 197 + +Base: 198 + +Base: 199 +Linked animations: [1317] + +Base: 200 +Linked animations: [2675, 2676, 2677, 2678, 2679, 2680, 2681, 2682, 2683, 2684] + +Base: 201 +Linked animations: [3559, 3560, 3561, 3562] + +Base: 202 +Linked animations: [3307] + +Base: 203 +Linked animations: [3308] + +Base: 204 +Linked animations: [1149, 1150, 1151, 1152, 1153, 1154, 1155] + +Base: 205 +Linked animations: [2138] + +Base: 206 +Linked animations: [1848] + +Base: 207 +Linked animations: [1855] + +Base: 208 +Linked animations: [1856, 1857, 1858, 1859, 1860, 1861, 1862, 1863, 1864, 1865, 1866, 1867] + +Base: 209 +Linked animations: [1254, 1255, 1256] + +Base: 210 +Linked animations: [3093] + +Base: 211 +Linked animations: [1376, 1377, 1378, 2114, 2115, 2116, 2117, 2665, 3410, 3411, 3412, 3413, 3414, 3541, 9723, 10710, 10895, 10978] + +Base: 212 +Linked animations: [1882, 1883, 1885, 1886, 1887, 1888, 1889, 1890, 1891, 1892, 1893] + +Base: 213 +Linked animations: [1884] + +Base: 214 +Linked animations: [2085] + +Base: 215 +Linked animations: [785, 786] + +Base: 216 +Linked animations: [3457, 3458] + +Base: 217 +Linked animations: [3454] + +Base: 218 +Linked animations: [3456] + +Base: 219 +Linked animations: [3455] + +Base: 220 +Linked animations: [3453] + +Base: 221 +Linked animations: [2008] + +Base: 222 +Linked animations: [2003, 2004, 2005, 2006, 2007] + +Base: 223 +Linked animations: [2001, 2002] + +Base: 224 +Linked animations: [3166] + +Base: 225 + +Base: 226 +Linked animations: [2765, 2766, 2767] + +Base: 227 + +Base: 228 +Linked animations: [11224] + +Base: 229 +Linked animations: [1372, 1373, 2344, 2345, 5764, 5765, 5766, 5767] + +Base: 230 + +Base: 231 +Linked animations: [3092] + +Base: 232 + +Base: 233 + +Base: 234 +Linked animations: [2221, 2222, 2223, 2224, 2225, 2226, 2227, 2228, 2229] + +Base: 235 +Linked animations: [2230] + +Base: 236 +Linked animations: [2231] + +Base: 237 +Linked animations: [2232] + +Base: 238 +Linked animations: [2233] + +Base: 239 +Linked animations: [2234] + +Base: 240 +Linked animations: [2235] + +Base: 241 +Linked animations: [2236] + +Base: 242 +Linked animations: [2237] + +Base: 243 +Linked animations: [2238] + +Base: 244 +Linked animations: [2217, 2218, 2219, 2220] + +Base: 245 +Linked animations: [1355, 1356] +Linked objects: null (4668) + +Base: 246 +Linked animations: [1357, 1358, 1359, 1360, 1361] + +Base: 247 + +Base: 248 +Linked animations: [949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006] + +Base: 249 +Linked animations: [934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948] + +Base: 250 +Linked animations: [630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 3476, 3477, 3545, 3546] + +Base: 251 +Linked animations: [1921, 9681] + +Base: 252 +Linked animations: [1489] + +Base: 253 +Linked animations: [1490] + +Base: 254 +Linked animations: [1491, 1492] + +Base: 255 + +Base: 256 +Linked animations: [2690] + +Base: 257 +Linked animations: [646] + +Base: 258 +Linked animations: [902] + +Base: 259 +Linked animations: [788] + +Base: 260 +Linked animations: [789] + +Base: 261 +Linked animations: [1024] +Linked graphics: 241 + +Base: 262 +Linked animations: [903] + +Base: 263 +Linked animations: [787] + +Base: 264 +Linked animations: [1127] +Linked objects: Strange shrine (3634) + +Base: 265 +Linked animations: [1138] +Linked objects: null (3637) + +Base: 266 +Linked animations: [1135, 1136] + +Base: 267 +Linked animations: [2379] +Linked objects: null (8983), null (16119) + +Base: 269 +Linked animations: [3048, 3049, 3050, 3052] +Linked NPCs: Balloon animal (3119), Balloon animal (3120), Balloon animal (3121), Balloon animal (3122) + +Base: 270 +Linked animations: [3051] +Linked graphics: 524 + +Base: 271 +Linked animations: [4] +Linked objects: null (10060) + +Base: 272 + +Base: 273 +Linked animations: [29, 30, 31, 32, 33, 34, 35, 36] + +Base: 274 +Linked animations: [3952, 3953, 3954, 3955, 3956, 3957, 3958, 3959, 3960, 3961, 3962, 6448, 6449] +Linked NPCs: Tortoise (3808), Tortoise (3819), Healthorg and tortoise (4643), Battle tortoise display (5981) + +Base: 275 +Linked animations: [37, 38, 39, 40, 41, 42, 43, 44] + +Base: 276 +Linked animations: [341, 342, 343, 344, 345, 5288] +Linked graphics: 72, 960 + +Base: 277 +Linked animations: [6] +Linked NPCs: Boulder (939), Boulder (986) + +Base: 278 +Linked animations: [362] +Linked NPCs: Butterfly (153), Butterfly (154), Butterfly (155), Butterfly (156), Butterfly (157), Butterfly (1280), Butterfly (4449), Butterfly (4450), Black warlock (5082), Snowy knight (5083), Sapphire glacialis (5084), Ruby harvest (5085) + +Base: 279 +Linked animations: [45, 46, 47, 48, 49, 50, 51, 52, 1898] + +Base: 280 +Linked animations: [314, 315, 316, 317, 318, 319, 320, 1823, 2134, 2159, 2160, 2161, 2662, 2663, 2664, 2694] + +Base: 281 +Linked animations: [53, 54, 55, 56, 57, 5826] + +Base: 282 +Linked animations: [58, 59, 60, 61, 62, 2162, 2303, 2312] + +Base: 283 + +Base: 284 +Linked animations: [16, 17, 18, 19, 20] + +Base: 285 +Linked animations: [73] + +Base: 286 +Linked animations: [1418, 2887] + +Base: 287 + +Base: 288 +Linked animations: [74, 75, 76, 77, 78] + +Base: 289 +Linked animations: [2268] +Linked NPCs: Sheepdog (2311) + +Base: 290 +Linked animations: [4972, 12231, 12246, 12247, 12248, 12249, 12250, 12251, 12252, 12253, 12254, 12255, 12256, 12257, 12259, 14244, 14245, 14253, 14254, 14255, 14256, 14257, 14258, 14259, 14260, 14266] +Linked NPCs: Red dragon (53), Black dragon (54), Blue dragon (55), Elvarg (742), Green dragon (941), Red dragon (4669), Red dragon (4670), Red dragon (4671), Red dragon (4672), Black dragon (4673), Black dragon (4674), Black dragon (4675), Black dragon (4676), Green dragon (4677), Green dragon (4678), Green dragon (4679), Green dragon (4680), Blue dragon (4681), Blue dragon (4682), Blue dragon (4683), Blue dragon (4684), Blue dragon (5178), Brutal green dragon (5362), Dragon display (5979), Elvarg (6087), Mr. Mordaut (6117), Dragon (8858), Dragon (8859), Dragon (8860), Dragon (8861) + +Base: 291 +Linked animations: [14281] +Linked objects: Mysterious entrance (52849), Mysterious entrance (52850), Mysterious entrance (52851), Mysterious entrance (52852), Mysterious entrance (52853), Mysterious entrance (52854), Mysterious entrance (52855), Mysterious entrance (52856), Mysterious entrance (52857), Mysterious entrance (52858), Mysterious entrance (52859), Mysterious entrance (52860), Mysterious entrance (52861), Mysterious entrance (52862), Mysterious entrance (52863), Mysterious door (52864), Mysterious door (52865), Mysterious door (52866), Mysterious door (52867), Mysterious door (52868), Mysterious door (52869), Mysterious door (52870), Mysterious door (52871), Mysterious door (52872), Mysterious door (52873), Mysterious door (52874), Mysterious door (52875), Mysterious door (52876) + +Base: 292 +Linked animations: [14282, 14283, 14284, 14285, 14286] +Linked graphics: 833, 834, 2747, 2748, 2749 + +Base: 293 +Linked animations: [14305, 14306, 14307] +Linked graphics: 90, 91, 92 + +Base: 294 +Linked animations: [14304] +Linked graphics: 127, 128, 129 + +Base: 295 +Linked animations: [93, 94, 95, 96, 97] +Linked NPCs: Dryad (56), Tree spirit (4470) + +Base: 296 +Linked animations: [6917] +Linked objects: Alan (4419), Alan (25955) + +Base: 297 +Linked animations: [98, 99, 100, 101, 102, 104, 105, 900, 928, 1253, 1853, 2150, 2151, 2152, 2153, 2154, 2155, 2156, 2157, 2158, 2315, 2335, 2336, 2337, 2341, 2342, 2942, 3072, 3207, 3208, 3209, 3376, 3377, 3378, 3379, 3398, 4021, 5809, 5810, 6160, 6170, 6205, 6206, 6207, 6208, 7370, 8706, 9138, 10464, 10465, 10469, 11736, 11737, 11738, 12118, 12119, 12121, 12128, 12129, 12131, 12132, 12133, 12134, 12139, 12140, 12141, 12142, 12143, 12144, 12145, 12173, 12177, 12179, 12180, 12181, 12184, 12185, 12186, 12211, 12212, 12300, 12421, 12435] +Linked NPCs: Dwarf (118), Chaos dwarf (119), Dwarf (120), Dwarf (121), Guard (206), Lollk (207), Captain Lawgof (208), Nulodion (209), Austri (232), Doric (284), Dwarf (382), Stankers (383), Drogo dwarf (579), Dwarf (582), Nurmof (594), Thurgo (604), Boot (665), Drunken Dwarf (956), Niloof (994), Klank (995), Kamen (996), Hammerspike Stoutbeard (1794), Dwarf gang member (1795), Dwarf gang member (1796), Dwarf gang member (1797), null (1836), Dondakan the Dwarf (1839), Dwarven Engineer (1840), Rolad (1841), Khorvak, a dwarven engineer (1842), Dwarven Ferryman (1843), Dwarven Ferryman (1844), null (1845), Dwarven Boatman (1846), Miodvetnir (1847), Dernu (1848), Derni (1849), Purple Pewter Secretary (2092), Yellow Fortune Secretary (2093), Blue Opal Secretary (2094), Green Gemstone Secretary (2095), White Chisel Secretary (2096), Silver Cog Secretary (2097), Brown Engine Secretary (2098), Red Axe Secretary (2099), Purple Pewter Director (2100), Blue Opal Director (2101), Yellow Fortune Director (2102), Green Gemstone Director (2103), White Chisel Director (2104), Silver Cog Director (2105), Brown Engine Director (2106), Red Axe Director (2107), Trader (2109), Trader (2110), Trader (2111), Trader (2112), Trader (2113), Trader (2114), Trader (2115), Trader (2116), Trader (2117), Trader (2118), Trader (2119), Trader (2120), Trader (2121), Trader (2122), null (2123), Trader (2124), null (2125), Trader (2126), Trade Referee (2127), Supreme Commander (2128), Black Guard (2130), Black Guard (2131), Black Guard (2132), Black Guard (2133), Black Guard Berserker (2134), Black Guard Berserker (2135), Black Guard Berserker (2136), Blasidar the sculptor (2141), null (2142), Riki the sculptor's model (2143), Riki the sculptor's model (2144), Riki the sculptor's model (2145), Riki the sculptor's model (2146), Riki the sculptor's model (2147), Riki the sculptor's model (2148), Riki the sculptor's model (2149), Riki the sculptor's model (2150), Vigr (2151), Santiri (2152), Saro (2153), Gunslik (2154), Wemund (2155), Randivor (2156), Hervi (2157), Nolar (2158), Gulldamar (2159), Tati (2160), Agmundi (2161), Vermundi (2162), Banker (2163), Banker (2164), Librarian (2165), Assistant (2166), Customer (2167), Dromund (2169), Rind the gardener (2170), Factory Manager (2171), Factory Worker (2172), Factory Worker (2173), Factory Worker (2174), Factory Worker (2175), Inn Keeper (2176), Inn Keeper (2177), Barmaid (2178), Barman (2179), Cart conductor (2180), Cart conductor (2181), Cart conductor (2182), Cart conductor (2183), Cart conductor (2184), Cart conductor (2185), Cart conductor (2186), Rowdy dwarf (2187), Hegir (2188), Haera (2189), Runvastr (2190), Sune (2191), Bentamir (2192), Ulifed (2193), Reinald (2194), Karl (2195), Gauss (2196), Myndill (2197), Kjut (2198), Tombar (2199), Odmar (2200), Audmann (2201), null (2202), Drunken Dwarf (2203), Drunken Dwarf (2204), Dwarven Boatman (2205), Dwarven Boatman (2206), Dwarven Miner (2207), Dwarven Miner (2208), Dwarven Miner (2209), Dwarven Miner (2210), Dwarven Miner (2211), Dwarven Miner (2212), Dwarven Miner (2213), Dwarven Miner (2214), Dwarven Miner (2215), Dwarven Miner (2216), Dwarven Miner (2217), Dwarven Miner (2218), Purple Pewter Director (2219), Purple Pewter Director (2220), Blue Opal Director (2221), Yellow Fortune Director (2222), Green Gemstone Director (2223), White Chisel Director (2224), Silver Cog Director (2225), Brown Engine Director (2226), Red Axe Director (2227), Commander Veldaban (2228), null (2231), Black Guard berserker (2232), Blandebir (2321), null (2403), null (2404), Cart conductor (2409), Red Axe Director (2410), Red Axe Director (2411), Red Axe Henchman (2412), Red Axe Henchman (2413), Red Axe Henchman (2414), Colonel Grimsson (2415), Colonel Grimsson (2416), Chaos dwarf (2423), Gunslik (2424), Nolar (2425), Factory Worker (2426), Cart conductor (2427), Gauss (2428), Drunken Dwarf (2429), Rowdy dwarf (2430), Ulifed (2431), Red Axe Henchman (2432), Red Axe Henchman (2433), Dwarven Miner (2550), Dwarven Miner (2551), Dwarven Miner (2552), Blast Furnace Foreman (2553), Ordan (2564), Jorzik (2565), null (2788), Thorgel (2789), Smokin' Joe (2952), Rauborn (2991), Vaeringk (2992), Oxi (2993), Fior (2994), Sagira (2995), Anleif (2996), Mystery figure (3052), Dwarf (3219), Dwarf (3220), Dwarf (3221), Dwarf (3268), Dwarf (3269), Dwarf (3270), Dwarf (3271), Dwarf (3272), Dwarf (3273), Dwarf (3274), Dwarf (3275), Black Guard (3276), Black Guard (3277), Black Guard (3278), Black Guard (3279), Engineering assistant (3280), Engineering assistant (3281), Engineer (3282), Dwarf (3294), Dwarf (3295), Mountain Dwarf (3390), null (3401), null (3404), Vestri (3679), Drunken Dwarf (3837), Alviss (3933), Fullangr (3934), Jari (3935), Thorodin (3936), Ferd (3937), Donal (3938), Stonemason (4248), Guard (4257), Guard (4258), Guard (4259), Guard (4260), Gamfred (4287), null (4315), Dwarf (4316), Hirko (4558), Holoy (4559), Hura (4563), Brendt (5501), Grundt (5502), Sin Seer (5571), null (5832), Builder (5864), Builder (5865), Builder (5866), Builder (5867), Dwarf (5880), Dwarf (5881), Dwarf (5882), Dwarf (5883), Dwarf (5884), Dwarf (5885), Ticket dwarf (5886), null (5887), null (5998), null (6000), Hofuthand (armour and weapons) (6527), Thaki the delivery dwarf (7115), Brother Bordiss (7718), Drorkar (7720), Nurmof (7721), Lakki the delivery dwarf (7722), Drorkar (7723), Brother Bordiss (7724), Assistant (7726), null (7728), null (7729), null (7730), Ramarno (8170), Mystic (8233), Mystic (8238), null (8680), null (8681), null (8682), null (8683), Glosur (8684), Baden (8685), Obert (8686), Medwin (8687), Lieutenant Brae (8749), Lieutenant Brae (8751), Black Guard (8752), Commander Veldaban (8754), Commander Veldaban (8757), Commander Veldaban (8758), Commander Veldaban (8759), Commander Veldaban (8761), Commander Veldaban (8762), Commander Veldaban (8763), Commander Veldaban (8767), Black Guard (8768), Black Guard (8769), Black Guard (8772), Black Guard (8773), Black Guard (8774), Chaos dwarf hand cannoneer (8776), Chaos dwarf hand cannoneer (8777), Chaos dwarf (8778), Chaos dwarf (8779), Black Guard crossbowdwarf (8781), Black Guard crossbowdwarf (8782), Black Guard berserker (8783), Black Guard berserker (8784), Thak (8786), Chaos dwarf (8788), Brunolt (8789), Chaos dwarf (8791), Chaos dwarf (8792), Chaos dwarf (8793), Red Axe Director (8794), Colonel Grimsson (8797), Chaos dwarf hand cannoneer (8799), Chaos dwarf hand cannoneer (8800), Fjoila (8801), Prisoner (8802), Prisoner (8803), Prisoner (8804), Prisoner (8807), Prisoner (8808), Prisoner (8809), Prisoner (8810), Prisoner (8811), Commander Veldaban (8812), Trade floor guard (8813), Colonel Grenda (8814), Colonel Grenda (8818), Supreme Commander (8819), Supreme Commander (8820), Commander Veldaban (8821), Orange Flame director (8822), Orange Flame secretary (8823), Trader (8824), Trader (8827), null (8896), Dwarf (8897), Urist Loric (11270) +Linked objects: null (23492), Commander Veldaban (45061), null (45062), null (45063), Farli (45091), null (46486), Thorgel (46487) + +Base: 298 +Linked animations: [332, 333] +Linked NPCs: Spirit tree (3637) +Linked objects: Spirit tree (1293), Spirit tree (1294), Spirit tree (1295) + +Base: 299 +Linked animations: [106, 107, 108, 109, 110, 111, 112, 113, 3248, 3249] +Linked NPCs: null (4453), null (4454), null (11378) + +Base: 300 + +Base: 301 +Linked animations: [119, 120, 121, 122, 123, 124, 125, 126, 1434, 1435, 1436, 1957] +Linked NPCs: null (1970), Azzanadra (1971) + +Base: 302 +Linked animations: [127, 128, 129, 130, 131, 132, 133, 134] +Linked NPCs: Black Knight Titan (221) + +Base: 303 +Linked animations: [135, 136] +Linked graphics: 191 + +Base: 304 + +Base: 305 + +Base: 306 +Linked animations: [142, 143, 144, 145, 146, 147, 148, 149, 2391, 2809] +Linked NPCs: Spidine (5594) + +Base: 307 +Linked animations: [150, 151] +Linked graphics: 190 + +Base: 308 +Linked animations: [308, 309, 310, 311, 312, 313, 1737, 1738, 3403, 4578, 6984, 6985] + +Base: 309 +Linked animations: [2167, 2168, 2169, 2170] +Linked NPCs: Bed (2254), Thing under the bed (2255) + +Base: 310 +Linked animations: [152, 153, 154, 155, 156, 5347, 5348] +Linked NPCs: Golem (85), Rock golem (8648) +Linked graphics: 968 + +Base: 311 +Linked animations: [157, 158, 159, 160, 161] + +Base: 312 +Linked animations: [162, 166, 2959, 2961] + +Base: 313 +Linked animations: [3015] + +Base: 314 + +Base: 315 +Linked animations: [1197, 1198, 1199, 1200, 1201, 1202] +Linked NPCs: The Shaikahan (1172), The Shaikahan (1173) + +Base: 316 +Linked animations: [176, 177, 178, 179, 180] +Linked NPCs: Lizard man (69) + +Base: 317 +Linked animations: [181, 182, 183, 184, 185, 186, 187, 188, 1445, 1446, 1448, 1449] +Linked NPCs: Magic axe (127), Iron pickaxe (1015), Possessed pickaxe (1536), Animated pickaxe (10168), Animated pickaxe (10169), Animated pickaxe (10170), Animated pickaxe (10171), Animated pickaxe (10172), Animated pickaxe (10173), Animated pickaxe (10174), Animated pickaxe (10175), Animated pickaxe (10176), Animated pickaxe (10177) +Linked graphics: 307, 309 + +Base: 318 +Linked animations: [303, 304, 305, 306, 307] +Linked NPCs: Mammoth (135) + +Base: 319 +Linked animations: [189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 1412, 1413, 1414, 1415, 2691, 2841, 2842, 2904, 2943, 3193, 3963, 3964, 3965, 3966, 3967, 3968, 3969, 4331, 4332, 4536, 4537, 4538, 4579, 4580, 4582, 4583, 4585, 5002, 5496, 6109, 6471, 6472, 6473, 6474, 6475, 6484, 6485, 6533, 6534, 6535, 6666, 7121, 7122, 7123, 7124, 7125, 7126, 7127, 7128, 7142, 7143, 7147, 8944, 9139, 9140, 10951, 10952] +Linked NPCs: Leprechaun (65), Gnome (66), Gnome (67), Gnome (68), Gnome child (159), Gnome child (160), Gnome child (161), Gnome trainer (162), Gnome guard (163), Gnome guard (164), Gnome shop keeper (165), Gnome banker (166), Gnome baller (167), Gnome woman (168), Gnome woman (169), Brimstail (171), Golrie (306), King Bolren (469), Commander Montai (470), Bolkoy (471), Remsai (472), null (473), null (474), Gnome troop (479), Gnome troop (480), Tracker gnome 1 (481), Tracker gnome 2 (482), Tracker gnome 3 (483), Local Gnome (484), Local Gnome (485), Kalron (486), Hudo (600), Rometti (601), Gulluck (602), Heckel Funch (603), Gnome baller (621), Gnome baller (622), Gnome baller (623), Gnome baller (624), Gnome baller (625), Gnome baller (626), Gnome baller (627), Gnome baller (628), Gnome baller (629), Gnome baller (630), Gnome baller (631), Gnome baller (632), Gnome winger (633), Gnome winger (634), Gnome ball referee (635), Cheerleader (636), King Narnode Shareen (670), Glough (671), Anita (672), Femi (676), Glophren (767), Farquie the Cleaner (790), Blurberry (848), Barman (849), Aluft Gianne snr. (850), Gnome Waiter (851), Battle mage (914), Prissy Scilla (1037), Daero (1407), Waydar (1408), Waydar (1409), Garkor (1411), Garkor (1412), Lumo (1413), Lumo (1414), Bunkdo (1415), Bunkdo (1416), Carado (1417), Carado (1418), Lumdo (1419), Karam (1420), Karam (1421), Karam (1422), Bunkwicket (1423), Waymottin (1424), Zooknock (1425), Zooknock (1426), G.L.O. Caranock (1427), G.L.O. Caranock (1428), Golrie (1682), Lumdo (1788), Bunkwicket (1789), Waymottin (1790), Gnormadium Avlafrim (1800), Gnome emissary (2137), Gnome traveller (2138), Gnome traveller (2139), Gnome troop (2247), Gnome troop (2248), Gnome (2249), Gnome (2250), Gnome (2251), Bolongo (2343), null (2370), Gnome (2371), null (2406), null (2407), null (2408), Gnome emissary (2420), Gnome companion (2421), Gnome companion (2422), Gnome (2649), Gnome (2650), Gnome guard (2781), Gnome Coach (2802), Child (2872), Child (2873), Child (2874), Child (2875), Child (2876), Child (2877), Mystery figure (3053), Captain Dalbur (3809), Captain Bleemadge (3810), Captain Errdo (3811), Captain Klemfoodle (3812), Gnome Archer (3814), Gnome Driver (3815), Gnome Mage (3816), Lieutenant Schepbur (3817), Trainer Nacklepen (3818), Frizzy Skernip (4560), Yulf Squecks (4561), Praistan Ebola (4562), Gianne jnr. (4572), Timble (4573), Tamble (4574), Spang (4575), Brambickle (4576), Wingstone (4577), Penwie (4578), Generic Diplomat (4579), Ambassador Gimblewap (4580), Ambassador Spanfipple (4581), Ambassador Ferrnook (4582), Professor Manglethorp (4583), Damwin (4584), Professor Onglewip (4585), Professor Imblewyn (4586), Perrdur (4587), Dalila (4588), Sorrn (4589), Mimm (4590), Eebel (4591), Ermin (4592), Portobello (4593), Captain Ninto (4594), Captain Daerkin (4595), Captain Lamdoo (4596), Meegle (4597), Wurbel (4598), Sarble (4599), Guard Vemmeldo (4600), Burkor (4601), Froono (4602), null (4609), Brimstail (4610), Saboteur (4611), Gnome shop keeper (4612), Gnome soldier (4638), Gnome soldier (4639), Gnome soldier (4640), Gnome soldier (4641), Gnome soldier (4642), Oaknock the Engineer (4644), Glouphrie the Untrusted (4645), King Healthorg (4646), Hazelmere (4647), Jack (5046), Jill (5047), Jeff (5048), Assistant Le Smith (5056), null (5064), Elkoy (5179), Elkoy (5182), Captain Errdo (5249), Gnome (6002), Winkin (6003), Gnome (6004), Elnock Inquisitor (6070), Yewnock the engineer (6303), Bolrie (6304), Hazelmere (6305), Bolrie (6306), Advisor (6307), King Argenthorg (6308), Prince Argenthorg (6309), Longramble (6318), Glough (6391), Professor Arblenap (7717), Professor Arblenap (7725), null (7731), null (8276), null (8460), Glophren (8724), Gnome technician (8787) + +Base: 320 +Linked animations: [219, 220, 221, 222, 223, 1419, 12321, 13937] +Linked NPCs: Monkey (132), Monkey (1463), Monkey (1464), Monkey (1487), Monkey (2301), null (2302), null (2303), Monkey (4344), Monkey (4363), Monkey (5852) + +Base: 321 +Linked animations: [357, 358, 359, 360, 361, 1025, 2104, 3382, 3383, 3436, 3437, 5357] +Linked NPCs: null (3462), Skrach Uglogwee (3463), Skrach Uglogwee (3464) + +Base: 322 +Linked animations: [229, 230, 231, 232, 233] +Linked NPCs: Orc (71) + +Base: 323 +Linked animations: [2666, 2667, 2668, 2669, 2670] +Linked NPCs: Odysseus (2640), Odysseus (2651) + +Base: 324 +Linked animations: [234, 235, 236, 237, 238] + +Base: 325 +Linked animations: [3210, 3211, 3212] +Linked NPCs: Squirrel (3283), Squirrel (3284), Squirrel (3285), Fluffy (7413), Beny (7414), Bubbles (7415), Big Ben (7416), Fluffy (9682), Fluffy (9692), Beny (9693), Bubbles (9694), Big Ben (9695) + +Base: 326 +Linked animations: [2703, 2704, 2705, 2706, 2707, 2894] +Linked NPCs: Rat (47), Rat (2682), null (2974), null (2975), null (2976), null (2977), null (2978), null (2979), Rat (2981), King rat (2982), Rat (3008), Rat (3009), Rat (3010), Rat (3011), Rat (3012), Rat (3013), Rat (3014), Rat (3015), Rat (3016), Rat (3017), Rat (3018), Hell-Rat (3382), Rat (4396), Rat (4415) + +Base: 327 +Linked animations: [2369, 2370, 2371, 2372, 2373] +Linked NPCs: Pheasant (2459), Pheasant (2460), Pheasant (2461), Pheasant (2462) + +Base: 328 +Linked animations: [3947, 3948, 3949] +Linked NPCs: Postie Pete (3805) + +Base: 329 +Linked animations: [1242, 1243, 1244, 1245, 1246, 3867, 3868, 3869, 3870, 3871, 3872] +Linked NPCs: Bunny (1320), Bunny (1321), Bunny (7198), Bunny (7199), Guard bunny (7200), Rabbit (7208) + +Base: 330 +Linked animations: [3213, 3214, 3215, 3216] + +Base: 331 +Linked animations: [239, 240, 241, 242, 243] +Linked NPCs: Mouse (901), Crypt rat (2032) + +Base: 332 +Linked animations: [2297, 2298, 2299, 2300, 2301, 2302] +Linked NPCs: Chicken (288), Rooster (2312), null (3290), Evil Chicken (3375), Newtroost (5597), Evil Chicken (8644) + +Base: 333 +Linked animations: [244, 245, 246, 247, 248] + +Base: 334 +Linked animations: [932, 933] +Linked NPCs: Sea slug (1006), Sea slug (4894) + +Base: 335 +Linked animations: [10, 11, 12] +Linked NPCs: Shark (40), Shark (467), Shark (468), Shark (5067), Shark (5068), Shark (5069), Shark (8625), Shark (8626), Shark (8627), Shark (8628) + +Base: 336 +Linked animations: [249, 250, 251, 252, 253, 1736, 3841, 3842, 4936] + +Base: 337 +Linked animations: [254, 255, 256, 257, 258, 5356] +Linked NPCs: Skavid (129), Scared skavid (863), Mad skavid (864), Skavid (865), Skavid (866), Skavid (867), Skavid (868), Skavid (869), Witch's experiment (897) + +Base: 338 +Linked animations: [9487, 9488, 9489, 9490, 9491, 9492] +Linked NPCs: Nechryael (1613), Nechryael (10702) + +Base: 339 +Linked animations: [269, 270, 271, 272, 273] + +Base: 340 +Linked animations: [274, 275, 276, 277, 278, 1899, 1900, 1901, 2392] +Linked NPCs: Snake (128), Snake (1479), Desert snake (1874), Bush snake (2489), Bush snake (2490), Snake (4343) + +Base: 341 +Linked animations: [336, 337, 338, 339, 340] +Linked NPCs: Soulless (140) + +Base: 342 +Linked animations: [279, 280, 281, 282] + +Base: 343 +Linked animations: [3241, 3242] +Linked NPCs: Swan (3296), Black swan (3297) + +Base: 344 +Linked animations: [0, 1, 2] +Linked NPCs: Swarm (411), Swarm (4364), null (4966), Bees! (8650) + +Base: 345 + +Base: 346 + +Base: 347 +Linked animations: [3568, 3569, 3570] +Linked NPCs: Sheep (3579) + +Base: 348 + +Base: 349 + +Base: 350 + +Base: 351 + +Base: 352 + +Base: 353 + +Base: 354 + +Base: 355 + +Base: 356 + +Base: 357 + +Base: 358 + +Base: 359 + +Base: 360 + +Base: 361 + +Base: 362 + +Base: 363 + +Base: 364 + +Base: 365 + +Base: 366 + +Base: 367 + +Base: 368 + +Base: 369 + +Base: 370 + +Base: 371 + +Base: 372 + +Base: 373 + +Base: 374 + +Base: 375 +Linked animations: [348, 349, 350] +Linked NPCs: Strange plant (8640) + +Base: 376 +Linked animations: [288, 289, 290, 291, 292, 3232, 3233, 3234, 3235, 3236] + +Base: 377 +Linked animations: [293, 294, 295, 296, 297] +Linked NPCs: Yeti (130) + +Base: 378 +Linked animations: [9506, 9507, 9508, 9509, 9510, 9511] +Linked NPCs: Rockslug (1631), Rockslug (1632) + +Base: 379 +Linked animations: [1016, 1017] +Linked objects: Spit roast (5608), null (6895) + +Base: 380 +Linked animations: [1018, 1019, 1020, 1021, 1022] +Linked NPCs: Swamp toad (1013), Bloated Toad (1014), Plague frog (1997) + +Base: 381 +Linked animations: [1023, 2329] +Linked graphics: 240, 417, 419, 421, 423, 425 + +Base: 382 +Linked animations: [1011, 3463, 3464, 3465, 3466] + +Base: 383 +Linked animations: [3610] +Linked graphics: 614 + +Base: 384 +Linked animations: [3575] + +Base: 385 +Linked animations: [3574] + +Base: 386 +Linked animations: [3706] +Linked graphics: 624 +Linked objects: Altar (44926), Altar (44927), Altar (44928), Altar (44929), Altar (44930), Altar (44931), Altar (44932), Altar (44933), Altar (44934), Altar (44935), Altar (44936), Altar (44937), Altar (44938), Altar (44939), Altar (44940), Altar (44941), Altar (44942), Altar (44943), Altar (44944), Altar (44945), Altar (44946) + +Base: 387 +Linked animations: [3613, 3614] + +Base: 388 +Linked animations: [3580, 3581] +Linked objects: Elemental sphere (13660), Crystal of power (13661) + +Base: 389 +Linked animations: [3607] +Linked graphics: 613 + +Base: 390 +Linked animations: [3681] + +Base: 391 +Linked animations: [3582, 3583, 3584, 3585] +Linked NPCs: Elemental balance (4021), Elemental balance (4022), Elemental balance (4023), Elemental balance (4024), Elemental balance (4025), Elemental balance (4026), Elemental balance (4027), Elemental balance (4028), Elemental balance (4029), Elemental balance (4030), Elemental balance (4031), Elemental balance (4032), Elemental balance (4033), Elemental balance (4034), Elemental balance (4035), Elemental balance (4036), Elemental balance (4037), Elemental balance (4038), Elemental balance (4039), Elemental balance (4040), Elemental balance (4041), Elemental balance (4042), Elemental balance (4043), Elemental balance (4044), Elemental balance (4045), Elemental balance (4046), Elemental balance (4047), Elemental balance (4048), Elemental balance (4049), Elemental balance (4050), Elemental balance (4051), Elemental balance (4052), Elemental balance (4053), Elemental balance (4054), Elemental balance (4055), Elemental balance (4056), Elemental balance (4057), Elemental balance (4058), Elemental balance (4059), Elemental balance (4060), Elemental balance (4061), Elemental balance (4062), Elemental balance (4063), Elemental balance (4064), Elemental balance (4065), Elemental balance (4066), Elemental balance (4067), Elemental balance (4068), Elemental balance (4069), Elemental balance (4070), Elemental balance (4071), Elemental balance (4072), Elemental balance (4073), Elemental balance (4074), Elemental balance (4075), Elemental balance (4076), Elemental balance (4077), Elemental balance (4078), Elemental balance (4079), Elemental balance (4080), Elemental balance (4081), Elemental balance (4082), Elemental balance (4083), Elemental balance (4084), Elemental balance (4085), Elemental balance (4086), Elemental balance (4087), Elemental balance (4088), Elemental balance (4089), Elemental balance (4090), Elemental balance (4091), Elemental balance (4092), Elemental balance (4093), Elemental balance (4094), Elemental balance (4095) +Linked objects: Elemental balance (13395), Elemental balance (13396), Elemental balance (13397) + +Base: 392 +Linked animations: [3105, 3107, 9586, 9983] +Linked objects: null (2148), null (2669), null (3478), null (4033), null (11011), null (11012), null (11013), null (11014), null (11015), null (11016), null (11816), null (12300), null (12934), null (13052), null (13053), null (13054), Torch (13205), Torch (13207), Fire (13337), Torch (13341), Candle (13342), Skull (13343), Firepit (13528), Firepit with hook (13529), Firepit with hook (13530), Firepit with pot (13531), Firepit with pot (13532), Small oven (13533), Small Oven (13534), Small oven (13535), Large oven (13536), Large oven (13537), Large oven (13538), Clay fireplace (13610), null (14004), Pot boiler (14006), Pot boiler (14007), Pot boiler (14008), Pot boiler (14009), null (14996), null (15545), null (15689), null (18307), Fire (23046), null (23380), campfire (25374), Goblin stove (25440), Goblin stove (25441), null (25442), Candles (30752), null (31392), null (31393), null (31395), null (31704), null (33455), null (33795), null (33796), null (34378), null (34425), null (35124), null (35799), null (36810), null (38265), null (38268), null (41173), null (41423), Skull (41647), null (42360), null (44060), Candles (45271), null (45815), null (46256), null (48848) + +Base: 393 +Linked animations: [3579] +Linked objects: Large orrery (13655), Orrery (25401) + +Base: 394 +Linked animations: [3578] +Linked objects: Small orrery (13654) + +Base: 395 +Linked animations: [3511, 4610, 12507] +Linked objects: Grandfather clock (12293), Clock (13169), Clock (13170), Clock (13171), Clock (15547), Clock (22155), Clock (25763), Death clock (27896), Grandfather clock (34544), Grandfather clock (34545), Grandfather clock (36937), Clock (40029), Grandfather clock (45295), Death clock (46774), Death clock (46775), Death clock (46776), null (47652), Spooky clock (47655), Grandfather clock (47900), Grandfather clock (49059), Clock (52809) + +Base: 396 +Linked animations: [3601] + +Base: 397 +Linked animations: [3573] +Linked objects: Incense burner (13209), Incense burner (13211), Incense burner (13213), Incense burner (52824) + +Base: 398 +Linked animations: [3587, 3588, 3589, 3590, 3591] +Linked graphics: 610, 611 +Linked objects: Jacky Jester (13390), Jacky Jester (13726) + +Base: 399 +Linked animations: [3612] + +Base: 400 +Linked animations: [3616] +Linked objects: Greater magic circle (13683) + +Base: 401 +Linked animations: [3615] +Linked objects: Magic circle (13682) + +Base: 402 +Linked animations: [3586] +Linked objects: Magic barrier (13145) + +Base: 403 +Linked animations: [3629] +Linked graphics: 616 + +Base: 404 +Linked animations: [3637, 3638] +Linked graphics: 620, 621 + +Base: 405 +Linked animations: [3577] +Linked objects: Bells (13215) + +Base: 406 +Linked animations: [3631, 3632, 3633] +Linked graphics: 617, 618, 619 + +Base: 407 +Linked animations: [3650] + +Base: 408 +Linked animations: [3174, 3642, 14289] +Linked objects: Interdimensional rift (11354), null (11355), Portal Home (11356), null (11359), Portal (12260), Portal (13405), Varrock Portal (13615), Lumbridge Portal (13616), Falador Portal (13617), Camelot Portal (13618), Ardougne Portal (13619), Yanille Portal (13620), Kharyrll Portal (13621), Varrock Portal (13622), Lumbridge Portal (13623), Falador Portal (13624), Camelot Portal (13625), Ardougne Portal (13626), Yanille Portal (13627), Kharyrll Portal (13628), Varrock Portal (13629), Lumbridge Portal (13630), Falador Portal (13631), Camelot Portal (13632), Ardougne Portal (13633), Yanille Portal (13634), Kharyrll Portal (13635), Portal (15477), Portal (15478), Portal (15479), Portal (15480), Portal (15481), Portal (15482), Portal (15996), Dark portal (27254), Portal (28139), Portal (28213), Portal (28214), Portal (29534), Portal (38694), Portal (38695), Portal (38696), Free-for-all (safe) (38698), Free-for-all (dangerous) (38699), Portal (38700), Portal (42021), Portal (42022), Soul Wars portal (42219), Edgeville portal (42220), Portal (42278), Portal (42279), Dark portal (46931), Portal (46935) + +Base: 409 +Linked animations: [3647] +Linked objects: Statue (13408), Ornamental fountain (13480), Ornamental fountain (52800) + +Base: 410 +Linked animations: [3644] +Linked objects: Scrying pool (13639) + +Base: 411 +Linked animations: [3628] +Linked graphics: 615 + +Base: 412 +Linked animations: [3604] +Linked graphics: 612 + +Base: 413 +Linked animations: [3682] +Linked graphics: 623 + +Base: 414 +Linked animations: [3646] +Linked objects: Teleportation focus (13640) + +Base: 415 +Linked animations: [3648] +Linked objects: Greater teleport focus (13641) + +Base: 416 +Linked animations: [3617, 3618, 3619, 3620, 3729] +Linked NPCs: Tentacle (3580), Tentacle (3618), Tentacle (3621) + +Base: 417 +Linked animations: [3117, 4118] +Linked objects: Magic chest (13291) + +Base: 418 +Linked animations: [3118, 3119, 3120] +Linked objects: Magic chest (13292) + +Base: 419 +Linked animations: [3121, 3122] + +Base: 420 +Linked animations: [3720] +Linked objects: Pump and drain (13560), Pump and tub (13562), Sink (13564) + +Base: 421 +Linked animations: [2997, 2998] +Linked objects: Doric's Whetstone (10641) + +Base: 422 +Linked animations: [3576] + +Base: 423 +Linked animations: [3707, 3708, 3709, 3710, 3711] +Linked NPCs: Rocnar (3594) +Linked objects: Rocnar (13373) + +Base: 424 +Linked animations: [3716, 3717] +Linked NPCs: Toy Doll (3596) + +Base: 425 +Linked animations: [3718] +Linked NPCs: Toy Mouse (3597) + +Base: 426 +Linked animations: [3712, 3713, 3714, 3715] +Linked NPCs: Toy Soldier (3595) + +Base: 427 +Linked animations: [3698] +Linked objects: Power saw (15468) + +Base: 428 +Linked animations: [4072] +Linked graphics: 678 + +Base: 429 +Linked animations: [3699] +Linked objects: Stone crusher (15466) + +Base: 430 +Linked animations: [3700] +Linked objects: Embalming tube (15469), null (15470) + +Base: 431 +Linked animations: [366, 1075, 7624, 7642, 10263, 10264, 10942, 10953] +Linked graphics: 18, 19, 20, 21, 22, 23, 24, 25, 26, 243, 250, 256, 325, 403, 472, 806, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1116, 1293, 1294, 1801, 1802, 1872, 1873, 1874, 1875, 1876, 1904, 1918, 2466, 2468, 2470, 2472, 2474, 2476, 2478, 2480, 2482, 2484, 2486, 2488, 2490, 2492, 2494, 2496, 2498, 2500, 2502, 2504, 2506, 2508 + +Base: 432 + +Base: 433 +Linked animations: [367, 6074, 7204] +Linked graphics: 28, 699, 1036, 1233 + +Base: 434 + +Base: 435 + +Base: 436 +Linked animations: [922] +Linked graphics: 33 + +Base: 437 +Linked animations: [373] +Linked graphics: 54, 438 + +Base: 438 +Linked animations: [368] +Linked graphics: 206, 207, 208, 209, 210, 211, 1855 + +Base: 439 + +Base: 440 +Linked animations: [371] +Linked graphics: 42, 43, 44, 45, 46, 47, 48, 290, 338, 1856 + +Base: 441 +Linked animations: [1069] +Linked graphics: 257 + +Base: 442 +Linked animations: [372, 1070] +Linked graphics: 35, 36, 37, 38, 39, 40, 41, 258 + +Base: 443 +Linked animations: [369] +Linked graphics: 219, 220, 221, 222, 223, 224, 225 + +Base: 444 +Linked animations: [374] +Linked graphics: 30, 50, 52, 193 + +Base: 445 +Linked animations: [375] +Linked graphics: 29, 49, 51, 55, 192 + +Base: 446 +Linked animations: [1657] +Linked objects: Ectofuntus (5282), Ectofuntus (5283) + +Base: 447 + +Base: 448 + +Base: 449 +Linked animations: [1644, 1645] +Linked NPCs: null (1689) + +Base: 450 +Linked animations: [1639, 1640] +Linked NPCs: Ghost (?) (1707), Ghost (?) (1708) + +Base: 451 +Linked animations: [1646, 1647, 4833] +Linked NPCs: null (1690) +Linked graphics: 793, 794 + +Base: 452 + +Base: 453 +Linked animations: [3558] +Linked objects: Bucket (12785) + +Base: 454 +Linked animations: [3106] +Linked objects: null (3490), null (5060), null (11008), Furnace (11010), null (12805), Furnace (12809), Furnace (30510) + +Base: 455 +Linked animations: [3104] +Linked objects: null (11158), null (12810), null (12811), null (30519) + +Base: 456 +Linked animations: [3567] +Linked graphics: 609 + +Base: 457 +Linked animations: [3548] +Linked graphics: 604 + +Base: 458 +Linked animations: [2892, 3549, 6604] +Linked graphics: 482, 605, 606, 1121 + +Base: 459 +Linked animations: [2893, 3554] +Linked NPCs: Melina (2934), Droalak (2937) +Linked graphics: 607 + +Base: 460 +Linked animations: [3556] +Linked graphics: 608 + +Base: 461 +Linked animations: [283, 284, 285, 286, 287, 925, 926, 927, 1139, 1140, 1141, 1142, 1158, 1159, 1259, 1474, 1475, 1476, 1477, 1478, 1480, 1488, 4007, 4008, 4009, 4010, 4983, 4985, 4986, 4987, 4988, 4989, 4990, 4991, 4992, 4993, 4994, 4995, 4996, 4997, 4998, 4999, 5000, 5001, 5016, 5775, 5779, 10236, 10243] +Linked NPCs: Troll (72), Rock (1095), Stick (1096), Pee Hat (1097), Kraka (1098), Dung (1099), Ash (1100), Thrower Troll (1101), Thrower Troll (1102), Thrower Troll (1103), Thrower Troll (1104), Thrower Troll (1105), Mountain troll (1106), Mountain troll (1107), Mountain troll (1108), Mountain troll (1109), Mountain troll (1110), Mountain troll (1111), Mountain troll (1112), Troll general (1115), Troll general (1116), Troll general (1117), Troll spectator (1118), Troll spectator (1119), Troll spectator (1120), Troll spectator (1121), Troll spectator (1122), Troll spectator (1123), Troll spectator (1124), Dad (1125), Twig (1126), Berry (1127), Twig (1128), Berry (1129), Thrower troll (1130), Thrower troll (1131), Thrower troll (1132), Thrower troll (1133), Thrower troll (1134), Cook (1135), Cook (1136), Cook (1137), Mountain troll (1138), Mushroom (1139), Guard (1142), Guard (1143), Guard (1144), Guard (1145), Guard (1146), Guard (1147), Guard (1148), Guard (1149), Guard (1150), Burntmeat (1151), Lalli (1270), Ug (1553), Aga (1554), Arrg (1555), Arrg (1556), Ug (1557), Ice Troll (1560), Ice Troll (1561), Ice Troll (1562), Ice Troll (1563), Ice Troll (1564), Ice Troll (1565), Ice Troll (1566), null (1932), Troll child (1933), Troll child (1934), Ice troll (1935), Ice troll (1936), Ice troll (1937), Ice troll (1938), Ice troll (1939), Ice troll (1940), Ice troll (1941), Ice troll (1942), null (1947), Troll father (1948), null (1949), Troll mother (1950), Troll (3584), Flippa (3912), Tilt (3913), My Arm (4947), My Arm (4948), My Arm (4949), null (4950), null (4951), null (4952), null (4953), null (4954), null (4955), null (4956), My Arm (4957), My Arm (4958), My Arm (4959), Unnamed troll child (4968), Drunken dwarf's leg (4969), Ice Troll King (5472), Ice troll runt (5473), Ice troll male (5474), Ice troll female (5475), Ice troll grunt (5476), Ice troll runt (5521), Ice troll male (5522), Ice troll female (5523), Ice troll grunt (5524), Ice troll runt (5525), Ice troll male (5526), Ice troll female (5527), Ice troll grunt (5528), null (8074), null (8075), River troll (8646) +Linked graphics: 837, 838 +Linked objects: Troll (13369) + +Base: 462 +Linked animations: [1143, 5017] +Linked graphics: 275, 850 + +Base: 463 +Linked animations: [1940, 1941, 1942] +Linked objects: null (6495) + +Base: 464 +Linked animations: [1943] +Linked objects: null (6482), Obelisk (6483), Obelisk (6484), null (6485), Obelisk (6486), Obelisk (6487), null (6488), Obelisk (6489), Obelisk (6490), null (6491), Obelisk (6492), Obelisk (6493) + +Base: 465 +Linked animations: [1939, 7291] +Linked objects: Pitfall (6521), null (6522), Pitfall (27240) + +Base: 466 +Linked animations: [1938, 2905] +Linked objects: null (6520), null (10395), null (10398), null (10401), null (10403) + +Base: 467 +Linked animations: [1944] +Linked objects: Wall Crusher (6629) + +Base: 468 +Linked animations: [1945, 1946, 1947, 1948, 1949, 5464] +Linked NPCs: Scarabs (1969), Scarab swarm (2001), Scarab swarm (4500) + +Base: 469 +Linked animations: [1925, 1926, 1927, 1928, 1929, 1934] + +Base: 470 +Linked animations: [1935] + +Base: 471 +Linked animations: [1936, 1937] +Linked graphics: 355, 356 +Linked objects: null (6518), null (6519) + +Base: 472 +Linked animations: [1951] +Linked graphics: 354 + +Base: 473 +Linked animations: [1845, 1846] +Linked objects: null (5963), Cannonball (5964), Gold cannonball (5965) + +Base: 474 +Linked animations: [1847] +Linked objects: Fire (5981) + +Base: 475 +Linked animations: [2135] +Linked objects: Crusher (6985) + +Base: 476 +Linked animations: [2136] +Linked objects: Bookcase (6972) + +Base: 477 +Linked animations: [1869] +Linked objects: Fireplace (6093), Fireplace (6094), Fireplace (6095), Fireplace (6096) + +Base: 478 +Linked animations: [1868] +Linked objects: Table (6197), Table (6199), Table (6201), Lamp (6202), Lamp (6203), Lantern (11468), null (23507), null (23514) + +Base: 479 +Linked animations: [2137] +Linked objects: Plant (7013), Plant (7014), Plant (7015) + +Base: 480 +Linked animations: [1870] + +Base: 481 +Linked animations: [1838, 1839, 1840, 1841, 1842, 1843, 1844] +Linked NPCs: Arzinian Avatar of Strength (1850), Arzinian Avatar of Strength (1851), Arzinian Avatar of Strength (1852), Arzinian Avatar of Ranging (1853), Arzinian Avatar of Ranging (1854), Arzinian Avatar of Ranging (1855), Arzinian Avatar of Magic (1856), Arzinian Avatar of Magic (1857), Arzinian Avatar of Magic (1858), Arzinian Being of Bordanzan (1859) + +Base: 482 +Linked animations: [1049] +Linked objects: null (3407) + +Base: 483 +Linked animations: [1051] +Linked objects: null (3405), Water wheel (18511), Water wheel (18512) + +Base: 484 +Linked animations: [1052] +Linked objects: null (3411) + +Base: 485 +Linked animations: [1039, 1040, 1041, 1042] +Linked NPCs: Air elemental (1021) + +Base: 486 + +Base: 487 +Linked animations: [1027, 1029, 1030, 1031] +Linked NPCs: Fire elemental (1019) + +Base: 488 +Linked animations: [1044, 1045, 1046, 1047, 1048] +Linked NPCs: Water elemental (1022) + +Base: 489 +Linked animations: [1053] +Linked graphics: 244, 809, 2683 + +Base: 490 +Linked animations: [2915] + +Base: 491 +Linked animations: [2906, 2907, 2908] +Linked NPCs: Nirrie (3023), Tirrie (3024), Hallak (3025), Githan (7122), Amulet of Nature (7123) + +Base: 492 +Linked animations: [2916] +Linked graphics: 487 + +Base: 493 +Linked animations: [3098] + +Base: 494 +Linked animations: [3100] +Linked objects: Statue (10966), Statue (10967), Statue (10968), Statue (10969) + +Base: 495 +Linked animations: [3099] +Linked objects: Statue (10962), Statue (10963), Statue (10964), Statue (10965) + +Base: 496 +Linked animations: [3097] +Linked objects: Magic spell (11141) + +Base: 497 +Linked animations: [3095, 3096] +Linked objects: Magic barrier (11005) + +Base: 498 +Linked animations: [3101] +Linked objects: Light (11079), Light (12203), Rope (12601), Light (12605), Light (14179), Warren exit (23118), null (23145), Rabbit hole (29829), Rabbit hole (30074), null (41840), null (42907) + +Base: 499 +Linked animations: [3073, 3074, 3075, 3076, 3077, 3078, 3088] +Linked NPCs: null (3128), Boneguard (3129), Boneguard (3140) + +Base: 500 +Linked animations: [3079, 3080, 3081, 3082, 3083, 3084, 3085, 3086, 3087, 3089] +Linked graphics: 525, 526, 527, 528, 529, 530, 531, 532, 533, 535 + +Base: 501 +Linked animations: [3246] +Linked objects: A fairy workbench (12066), Fairy workbench (16213) + +Base: 502 +Linked animations: [3247] +Linked objects: A fairy workbench (12067), Fairy workbench (16215) + +Base: 503 +Linked animations: [3264] +Linked objects: Chicken Shrine (12093) + +Base: 504 +Linked animations: [13899] + +Base: 505 +Linked animations: [13889, 13890] +Linked NPCs: Zanaris choir (3312) + +Base: 506 +Linked animations: [3259, 3260, 3261, 3262, 3263] + +Base: 507 +Linked animations: [3258] +Linked graphics: 568, 569 + +Base: 508 +Linked animations: [1621] + +Base: 509 +Linked animations: [1620] + +Base: 510 +Linked animations: [1629] +Linked objects: Fireplace (5165), Fireplace (10824) + +Base: 511 +Linked animations: [1630] +Linked objects: Fireplace surround (5178), Fireplace surround (5179), null (10825), null (10826) + +Base: 512 +Linked animations: [1632] +Linked objects: Lightning conductor (5177) + +Base: 513 +Linked animations: [1631] +Linked objects: Signpost (5164) + +Base: 514 +Linked animations: [1622, 1623] +Linked NPCs: null (1671), null (1672) + +Base: 515 +Linked animations: [1624, 1625, 1626, 1627, 1628] +Linked NPCs: Experiment (1676) + +Base: 516 +Linked animations: [3124] +Linked graphics: 542 + +Base: 517 +Linked animations: [3127] +Linked graphics: 547 + +Base: 518 +Linked animations: [3125, 3126] +Linked graphics: 545, 546 + +Base: 519 +Linked animations: [3123] + +Base: 520 +Linked animations: [3843] +Linked objects: Fishing Contest Banner (14035), null (48836) + +Base: 521 +Linked animations: [1920] + +Base: 522 +Linked animations: [1924] +Linked graphics: 353, 358 + +Base: 523 +Linked animations: [1922, 1923] +Linked objects: null (6422), null (6424), Mystical mirror (6425), null (6426), Mystical mirror (6427), null (6428), Mystical mirror (6429), null (6430), Mystical mirror (6431), null (6432), Mystical mirror (6433) + +Base: 524 + +Base: 525 + +Base: 526 +Linked animations: [1912, 1913, 2884, 2885, 2886, 2917, 2918, 2919, 7623] +Linked NPCs: null (1907), Broken clay golem (1908), Damaged clay golem (1909), Clay golem (1910), null (2926), Clay golem (2927), Clay golem (2928), Black golem (3026), White golem (3027), Grey golem (3028), Clay golem (6785) + +Base: 527 +Linked animations: [1908, 2878] +Linked objects: Portal (6282), Portal (10251) + +Base: 528 +Linked animations: [1910, 1911] + +Base: 529 +Linked animations: [1909] +Linked objects: Door (6363) + +Base: 531 +Linked animations: [3037, 3038] +Linked objects: Sandpit (10814) + +Base: 532 +Linked animations: [1452] + +Base: 533 +Linked animations: [1453, 1454, 1455, 1456] + +Base: 534 +Linked animations: [1450, 1451] +Linked NPCs: Innocent-looking key (1543) + +Base: 535 +Linked animations: [1347] +Linked objects: Lighting mechanism (4587) + +Base: 536 +Linked animations: [1349] +Linked objects: Lighting mechanism (4589) + +Base: 537 +Linked animations: [1348] +Linked objects: Lighting mechanism (4590), Lighting mechanism (21945) + +Base: 538 +Linked animations: [1338, 1339, 1340, 1341, 1342, 1343, 1344, 1345, 1346, 1527, 1528, 1529, 1530, 1540, 1541, 2361] +Linked NPCs: Dagannoth (1338), Dagannoth (1339), Dagannoth (1340), Dagannoth (1341), Dagannoth (1342), Dagannoth (1343), Dagannoth (1344), Dagannoth (1345), Dagannoth (1346), Dagannoth (1347), Dagannoth mother (1348), Dagannoth mother (1349), Dagannoth mother (1350), Dagannoth mother (1351), Dagannoth mother (1352), Dagannoth mother (1353), Dagannoth mother (1354), Dagannoth mother (1355), Dagannoth mother (1356), Dagannoth spawn (2454), Dagannoth (2455), Dagannoth (2456), Dagannoth (2887), Dagannoth (2888), Gelatinnoth Mother (3497), Gelatinnoth Mother (3498), Gelatinnoth Mother (3499), Gelatinnoth Mother (3500), Gelatinnoth Mother (3501), Gelatinnoth Mother (3502), Dagannoth (3591), Dagannoth sentinel (9089), Dagannoth guardian (9092), Dagannoth (9097), Dagannoth (9098), Dagannoth (9103), Dagannoth Mother (9106), Dagannoth Mother (9107), Dagannoth Mother (9108), Dagannoth Mother (9109), Dagannoth Mother (9112), Dagannoth Mother (9113), Dagannoth Mother (9114), Dagannoth Mother (9115), Dagannoth Mother (9116), Dagannoth Mother (9117), Dagannoth (9128), Dagannoth (9129), Dagannoth (9132), Dagannoth (9133), Dagannoth Mother (9343), Dagannoth (9344), Dagannoth (9345), Dagannoth (9346) +Linked objects: Dagannoth (13376) + +Base: 539 +Linked animations: [1310, 1311, 1312, 1313, 1314, 1315, 1316, 2368] +Linked NPCs: Rock Crab (1265), Rocks (1266), Rock Crab (1267), Rocks (1268), Giant Rock Crab (2452), Crab (2706), Giant Rock Crab (2885) + +Base: 540 +Linked animations: [3408, 3409] +Linked graphics: 582 +Linked objects: null (12380) + +Base: 541 +Linked animations: [3404, 3405, 3406, 3407] +Linked graphics: 581 +Linked objects: Cauldron (12400), Cauldron (12401), Explosion (12402) + +Base: 542 +Linked animations: [3445] +Linked objects: null (12532), null (42908) + +Base: 543 +Linked animations: [3446, 3447, 3448, 3449] +Linked graphics: 583, 584, 585, 586 + +Base: 544 +Linked animations: [3478] +Linked objects: Red Banana Tree (12608) + +Base: 545 +Linked animations: [3527, 3528, 3529, 3530, 3531, 3532, 3533, 3534] +Linked objects: Snake (12594), Snake (12595), Snake (12596), Hole (12597), Snake (12598), Snake (12599), Snake (12600) + +Base: 546 +Linked animations: [3349] +Linked objects: Barrier (12351), Barrier (12352), Barrier (12353), null (12357), null (12358), null (12359), null (12360), null (12361), null (12362), null (12363), null (12364) + +Base: 547 +Linked animations: [3350, 3351, 3352] +Linked graphics: 601 +Linked objects: null (12354), Portal (12355), Portal (12356), null (12365), Portal (46500) + +Base: 548 +Linked animations: [3498, 3499, 3500, 3501, 3502, 3503] +Linked NPCs: Agrith-Na-Na (3493) + +Base: 549 +Linked animations: [3504, 3505, 3506, 3507, 3508, 3509] +Linked NPCs: Dessourt (3496) + +Base: 550 +Linked animations: [7263] +Linked objects: Chair (12312), Chair (12313) + +Base: 551 +Linked animations: [3357] +Linked NPCs: Culinaromancer (3492) +Linked graphics: 591 + +Base: 552 +Linked animations: [3354, 3355] +Linked graphics: 589, 590, 592, 593, 594, 595, 596, 597, 598, 599, 600, 602, 836, 839, 853, 854 + +Base: 553 +Linked animations: [3459, 11447] +Linked objects: Old tree (12551) + +Base: 554 +Linked animations: [3469, 3472] +Linked NPCs: Balloon Toad (3473), Balloon Toad (3474), Balloon Toad (3475) +Linked objects: Rock and string (12556), Rock and string (12557) + +Base: 555 +Linked animations: [3473, 3474] + +Base: 556 +Linked animations: [3470] +Linked graphics: 587 + +Base: 557 +Linked animations: [3440] +Linked graphics: 603 +Linked objects: Bubbles (12531), null (26484), null (31565) + +Base: 558 +Linked animations: [3439] + +Base: 559 +Linked animations: [3424, 3425, 3426, 3427, 3428, 3429, 3430, 8098, 8099, 8100, 8101, 8102, 8103, 8104, 8105, 8106, 8107, 8108, 8109, 8370, 8541, 14276, 14277] +Linked NPCs: Crab (3421), Crab (3424), Crab (4346), Granite crab (6796), Granite crab (6797), Baby giant crab (6947), Giant crab (6948), Baby giant crab (7293), Giant crab (7294), Baby giant crab (7295), Giant crab (7296), Baby giant crab (7297), Giant crab (7298), Baby giant crab (7299), Giant crab (7300), Giant crab (7829), Giant crab (9218), Giant crab (9219), Giant crab (9220), Giant crab (9221), Giant crab (9222) + +Base: 560 +Linked animations: [3441, 3442] +Linked NPCs: Fish (3425), Fish (3426), Fish (3427), Fish (3428), Fish (3429), Fish (3430), Fish (3431), Fish (3432), Fish (3433), Fish (3434), Fish (3435), Fish (3436), Fish (3437), Fish (3438), Fish (3439), Fish (3440), Fish (3441), Fish (3442) + +Base: 561 +Linked animations: [3438] +Linked objects: Kelp (12477), null (31598) + +Base: 562 +Linked animations: [3431, 3432, 3433, 3434, 3435] +Linked NPCs: Mudskipper (3422), Mudskipper (3423) + +Base: 563 +Linked animations: [3443, 3444] +Linked NPCs: Fish (3443), Fish (3444), Fish (3445), Fish (3446), Fish (3447), Fish (3448) + +Base: 564 +Linked animations: [3347] +Linked graphics: 579 +Linked objects: Dragonfire (12258) + +Base: 565 +Linked animations: [3343] +Linked objects: Nest (12256), Nest (12259) + +Base: 566 +Linked animations: [3344] + +Base: 567 +Linked animations: [3345, 3346] +Linked NPCs: K'klik (3377) + +Base: 568 +Linked animations: [1997, 1998] +Linked objects: (6642) + +Base: 569 +Linked animations: [1999, 2000] +Linked objects: Doorway (6643) + +Base: 570 +Linked animations: [2031, 2032, 2035, 2038, 2039] + +Base: 571 +Linked animations: [2011, 2012, 2013, 2014, 2015] +Linked NPCs: Locust (1995) + +Base: 572 +Linked animations: [2027, 2028, 2029, 2030] + +Base: 573 +Linked animations: [2018] + +Base: 574 +Linked animations: [1174, 1175] + +Base: 575 +Linked animations: [1183, 1184, 1186, 1187, 1189, 1190, 1251] +Linked NPCs: Kalphite Queen (1159), Flesh Crawler (4389), Flesh Crawler (4390), Flesh Crawler (4391) + +Base: 576 + +Base: 577 +Linked animations: [1176, 1177, 1179, 1180, 1181, 1182] + +Base: 578 + +Base: 579 +Linked animations: [3542] +Linked objects: null (12701), null (12702), null (12703), null (12704) + +Base: 580 +Linked animations: [1761] + +Base: 581 +Linked animations: [1756, 1757, 1758, 1759, 1760] +Linked NPCs: null (1811), The Kendal (1812), The Kendal (1813) + +Base: 582 +Linked animations: [1398] +Linked objects: Awowogei (4771) + +Base: 583 + +Base: 584 +Linked animations: [1410, 1411] +Linked objects: Gnome Glider (4866) + +Base: 585 + +Base: 586 +Linked animations: [1416] + +Base: 587 +Linked animations: [1399, 1400, 1401, 1402, 1403, 1404, 1405, 1406, 3479] +Linked NPCs: Trefaji (1431), Aberab (1432), Hafuba (1438), Monkey Guard (1459), Monkey Guard (1460), Elder Guard (1461), Elder Guard (1462), Gorilla (1482), Bearded gorilla (1483), Ancient monkey (1484), null (9034), null (9035) + +Base: 588 +Linked animations: [1380, 1381, 1382, 1383, 1384, 1385, 1386, 1387, 1388, 1389, 1390, 1391, 1392, 1393, 1394, 1395, 1396, 1397, 3390, 3392, 3393, 3394, 3480, 3481, 3482, 3484, 3485, 3486, 3487, 3488, 3489, 3490, 3491, 3492, 3493, 3494, 3523, 3524, 3525, 3526, 11952, 13941, 13942, 13943, 13944, 13945] +Linked NPCs: Dugopul (1429), Solihib (1433), Daga (1434), Tutab (1435), Ifaba (1436), Hamab (1437), Denadu (1439), Lofu (1440), Kruk (1441), Duke (1442), Oipuis (1443), Uyoro (1444), Ouhai (1445), Uodai (1446), Padulah (1447), Awowogei (1448), Uwogo (1449), Muruwoi (1450), Sleeping Monkey (1451), Monkey Child (1452), The Monkey's Uncle (1453), The Monkey's Aunt (1454), Monkey Guard (1455), Monkey Archer (1456), Monkey Archer (1457), Monkey Archer (1458), Monkey Zombie (1465), Monkey Zombie (1466), Monkey Zombie (1467), Bonzara (1468), Small ninja monkey (1480), Medium ninja monkey (1481), Small zombie monkey (1485), Large zombie monkey (1486), Awowogei (3396), Awowogei (3397), King Awowogei (3478), Mizaru (3481), Kikazaru (3482), Iwazaru (3483), Blue Monkey (4371), Red Monkey (4372), King Awowogei (7446) + +Base: 589 +Linked animations: [2307] +Linked graphics: 412, 413, 414, 415 + +Base: 590 +Linked animations: [12109] +Linked objects: Tree (8743) + +Base: 591 +Linked animations: [2330, 2331] +Linked objects: An empty rack (9329), null (36309) + +Base: 592 +Linked animations: [2743] +Linked objects: null (9992), null (46405), null (46443) + +Base: 593 +Linked animations: [2744] +Linked objects: Crystal (10014) + +Base: 594 +Linked animations: [2746] +Linked objects: Light door (9768), Light door (9769), Light door (9770), Light door (9771), Light door (9772), Light door (9773), Light door (9774), Light door (9775) + +Base: 595 +Linked animations: [2747, 2748] +Linked objects: null (9799), null (9800), null (9801), null (9802), null (9803), null (9804), null (9805), null (9806), null (9807), null (9808), null (9809), null (9810), null (9811), null (9812), Light beam (46511), Light beam (46512), Light beam (46513), Light beam (46514), Light beam (46515), Light beam (46516), Light beam (46517) + +Base: 596 +Linked animations: [2734] +Linked objects: Crystal collector (9749) + +Base: 597 +Linked animations: [2742] +Linked objects: null (9813), null (9814), null (9815), null (9816), null (9817), null (9818), null (9819) + +Base: 598 +Linked animations: [2745] + +Base: 599 +Linked animations: [2735, 2736, 2737, 2738, 2739, 2740] +Linked NPCs: Shadow (2782) + +Base: 600 +Linked animations: [2327, 2328] +Linked graphics: 416, 418, 420, 422, 424 + +Base: 601 +Linked animations: [1098] +Linked graphics: 262 +Linked objects: Budding branch (3511) + +Base: 602 +Linked animations: [1096] +Linked graphics: 260 +Linked objects: Fungi on log (3509) + +Base: 603 +Linked animations: [1097] +Linked graphics: 261 +Linked objects: A golden pear bush (3513) + +Base: 604 +Linked animations: [1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095] +Linked NPCs: Ghast (1052), Ghast (1053), Ghast (3606), Ghast (3607), Ghast (3608), Ghast (3609), Ghast (3610), Ghast (3611) +Linked graphics: 265 + +Base: 605 +Linked animations: [1099] +Linked graphics: 263 + +Base: 606 +Linked animations: [1101] +Linked graphics: 264 + +Base: 607 +Linked animations: [1102] +Linked graphics: 255, 259 + +Base: 608 +Linked animations: [1747] +Linked objects: Gnome landing light (5815), Flashing landing light (5816), Flashing landing light (5817), Flashing landing light (5818), Flashing landing light (5819), null (5820), null (5821), null (5822), null (5823) + +Base: 609 +Linked animations: [1748, 1749, 1750, 1751, 1752, 1753, 1754, 9731, 9732, 9733] +Linked NPCs: Slagilith (1802), Rock pile (1803), Slagilith (1804), Flambeed (3494) + +Base: 610 +Linked animations: [3190] + +Base: 611 +Linked animations: [3188, 3189] + +Base: 612 +Linked animations: [3840] +Linked NPCs: Bones (3674) + +Base: 613 +Linked animations: [2895] +Linked graphics: 486 + +Base: 614 +Linked animations: [2900] +Linked objects: Lantern (10307), null (11815), null (12542) + +Base: 615 +Linked animations: [2897] +Linked objects: Rat trap (10292) + +Base: 616 +Linked animations: [2898] +Linked objects: Rat barrel (10301), Rat barrel (10310), Rat barrel (10317), Rat barrel (35151) + +Base: 617 +Linked animations: [2901] +Linked objects: Rat barn (10300), Rat barn (10312) + +Base: 618 +Linked animations: [2896] +Linked graphics: 484, 485 + +Base: 619 +Linked animations: [2899] +Linked objects: Rat lever (10299), Rat lever (10311) + +Base: 620 +Linked animations: [1212] +Linked objects: null (3878), Elven lamp (3918), Elven lamp (8767), null (8774), Elven lamp (32897) + +Base: 621 +Linked animations: [1234] +Linked objects: Tent wall (3997) + +Base: 622 +Linked animations: [1211] +Linked objects: null (3872) + +Base: 623 +Linked animations: [1230] +Linked graphics: 287 + +Base: 624 + +Base: 625 +Linked animations: [1229] +Linked graphics: 286 + +Base: 626 + +Base: 627 + +Base: 628 +Linked animations: [1231, 1232] +Linked objects: Barrel (4024) + +Base: 629 +Linked animations: [1233] +Linked objects: Barrel (3987), Barrel (4025) + +Base: 630 +Linked animations: [1235] +Linked objects: Well (4004), Well (4005) + +Base: 631 +Linked animations: [1213] + +Base: 632 +Linked animations: [1217, 1218] + +Base: 633 +Linked animations: [1215, 1216] +Linked objects: null (3926) + +Base: 634 +Linked animations: [1214] + +Base: 635 +Linked animations: [1219] + +Base: 636 + +Base: 637 +Linked animations: [1493, 1494, 1495, 1496, 1497, 1498] + +Base: 638 +Linked animations: [1274, 1276, 1277, 1278, 1279] +Linked NPCs: Myre Blamish Snail (1227), Blood Blamish Snail (1228), Ochre Blamish Snail (1229), Bruise Blamish Snail (1230), Bark Blamish Snail (1231), Myre Blamish Snail (1232), Blood Blamish Snail (1233), Ochre Blamish Snail (1234), Bruise Blamish Snail (1235) + +Base: 639 +Linked animations: [1503] +Linked graphics: 311 + +Base: 640 +Linked animations: [1635, 1636] +Linked objects: Crystal growth (5248) + +Base: 641 +Linked animations: [3535, 3536, 3537, 3538, 3539, 3540, 3736, 3737, 3738] +Linked NPCs: Big Snake (3484), Swamp snake (3599), Swamp snake (3600), Swamp snake (3601), Swamp snake (3602), Dead swamp snake (3603), Dead swamp snake (3604), Dead swamp snake (3605), Sea Snake Young (3939), Sea Snake Hatchling (3940) + +Base: 642 +Linked animations: [2807] +Linked objects: null (10104), Brewing control (10142), Brewing control (10143), Brewing control (10144) + +Base: 643 +Linked animations: [2808] + +Base: 644 +Linked animations: [2802, 2803, 2804, 2805, 2806] +Linked NPCs: Evil spirit (2849) + +Base: 646 +Linked animations: [1293, 1294, 1295, 1296, 1297, 1298, 1299, 1300, 1301, 1302] +Linked objects: Temple wall (4069), Temple wall (4070), Temple wall (4071), Temple wall (4072), Temple wall (4073), Temple wall (4074), Temple wall (4075), Temple wall (4076), Temple wall (4077), Temple wall (4078), Temple wall (4080), Temple wall (4081), Temple wall (4082), Temple wall (4083), Temple wall (4084), Temple wall (4085), Temple wall (4086), Temple wall (4087), Temple wall (4088), Temple wall (4089) + +Base: 647 +Linked animations: [1303, 1304] +Linked objects: Funeral Pyre (4093), Funeral pyre (4094), Funeral pyre (4095), Funeral pyre (4096), Funeral pyre (4097), Funeral pyre (4098), Funeral pyre (9006), Funeral pyre (9007), Funeral pyre (21271), Funeral pyre (29166), Funeral pyre (29181), Funeral pyre (30467), Funeral pyre (30468), Funeral pyre (30469), Funeral pyre (30470), Funeral pyre (30471), Funeral pyre (30472), Funeral pyre (30473), Funeral pyre (30474), Funeral pyre (30475), Funeral pyre (30476), Funeral pyre (30477) + +Base: 648 +Linked animations: [1305, 9066] +Linked graphics: 292, 1597 + +Base: 649 +Linked animations: [1281, 1282, 1283, 1284, 1286, 1287, 1288, 1308] +Linked NPCs: Loar Shade (1241), Shade Spirit (1242), Phrin Shade (1244), Riyl Shade (1246), Asyn Shade (1248), Fiyr Shade (1250), Riyl shadow (3615), Asyn shadow (3616), Shade (3617), Loar Shadow (7900) + +Base: 650 +Linked animations: [1285] +Linked graphics: 293 + +Base: 651 +Linked animations: [1289, 1290, 1291, 1292] +Linked NPCs: Loar Shadow (1240), Phrin Shadow (1243), Riyl Shadow (1245), Asyn Shadow (1247), Fiyr Shadow (1249), Loar Shadow (7900), Loar Shadow (7901) + +Base: 652 +Linked animations: [3835] +Linked objects: Hole (13925) + +Base: 653 +Linked animations: [3815, 3816, 3817, 3818, 3819, 3820, 3821] +Linked NPCs: Confusion beast (3650), Confusion beast (3651), Confusion beast (3652), Confusion beast (3653), Confusion beast (3654), Confusion beast (3666) + +Base: 654 +Linked animations: [3809, 3810, 3811, 3812, 3813, 3814] +Linked NPCs: Fear reaper (3649), Fear reaper (3665) + +Base: 655 +Linked animations: [3822, 3823, 3824, 3825, 3826, 3827] +Linked NPCs: Hopeless creature (3655), Hopeless creature (3656), Hopeless creature (3657), Hopeless creature (3667), Hopeless beast (3668), Hopeless beast (3669) + +Base: 656 +Linked animations: [3828, 3829, 3830, 3831, 3832, 3833, 3834] +Linked NPCs: Tolna (3658), Tolna (3659), Tolna (3660) +Linked graphics: 632 + +Base: 657 +Linked animations: [3808] +Linked graphics: 631 + +Base: 658 +Linked animations: [3805] +Linked graphics: 630 + +Base: 659 +Linked animations: [2882] +Linked NPCs: null (2920), Sand storm (2921) + +Base: 660 +Linked animations: [2814] +Linked graphics: 465, 480 + +Base: 661 +Linked animations: [2889] +Linked graphics: 483 + +Base: 662 +Linked animations: [2883] +Linked graphics: 481 +Linked objects: Magic circle (10252) + +Base: 663 +Linked animations: [3976] +Linked objects: null (14955), Firebox (14960) + +Base: 664 +Linked animations: [3983, 3984, 3985, 3986, 3987, 3988] +Linked NPCs: Sea troll (3840), Sea troll (3841), Sea troll (3842), Sea troll (3843), Sea troll (3845) + +Base: 665 +Linked animations: [3977, 3978, 3979, 3980, 3981, 3982] +Linked NPCs: Sea Troll General (3846) + +Base: 666 +Linked animations: [3989, 3990, 3991, 3992, 3993] +Linked NPCs: Sea Troll Queen (3847) + +Base: 667 +Linked animations: [3974] +Linked graphics: 663 + +Base: 668 +Linked animations: [3975] +Linked graphics: 664 + +Base: 669 +Linked animations: [3995] +Linked graphics: 662 + +Base: 670 +Linked animations: [1875, 1876] +Linked objects: Table (6246) + +Base: 671 +Linked animations: [1881] +Linked objects: Dung (6257), Dung (6259), null (18844) + +Base: 672 +Linked animations: [2571] +Linked NPCs: Trolley (2582), null (2585) + +Base: 673 +Linked animations: [1160, 6302, 11689] +Linked graphics: 277, 349, 1056, 2048 + +Base: 674 +Linked animations: [1479] +Linked graphics: 574 + +Base: 675 +Linked animations: [2672, 2673] + +Base: 676 +Linked animations: [2685, 2686, 2687, 2688, 2689] +Linked NPCs: Dragonkin (2641), Sithaph (8493), Strisath (8494), Sakirth (8495) + +Base: 677 +Linked animations: [2671] + +Base: 678 +Linked animations: [1269, 1270, 1271, 1272, 1273, 6428, 6429] +Linked NPCs: Leech (1219), Leech display (5971) + +Base: 679 +Linked animations: [1260] +Linked objects: null (4046) + +Base: 680 +Linked animations: [1261, 1262] +Linked NPCs: Mist (1222), Mist (1578), Mist (3530) +Linked graphics: 310 +Linked objects: null (4047) + +Base: 681 + +Base: 682 +Linked animations: [1915] +Linked objects: Vampire tomb (6438) + +Base: 683 +Linked animations: [1917, 1918, 1919] +Linked graphics: 351, 352 + +Base: 684 + +Base: 685 +Linked animations: [1916] +Linked graphics: 350 + +Base: 686 +Linked animations: [1334] +Linked objects: Spit roast (4267) + +Base: 689 +Linked animations: [2722] +Linked graphics: 454 + +Base: 690 +Linked animations: [2091] +Linked objects: null (6889) + +Base: 691 +Linked animations: [2103] + +Base: 692 +Linked animations: [3273] + +Base: 693 +Linked animations: [2133] +Linked objects: null (6967), null (6968) + +Base: 694 +Linked animations: [473] +Linked objects: null (725) + +Base: 696 +Linked animations: [474] +Linked objects: Bridge (3240) + +Base: 697 +Linked animations: [454, 455] +Linked graphics: 57, 58 + +Base: 698 +Linked animations: [2711] + +Base: 699 +Linked animations: [453] + +Base: 700 +Linked animations: [2714] +Linked objects: Instruction sign (29461), Instruction sign (29462), Instruction sign (29463), Instruction sign (29464), Signpost (31298), Signpost (31300), Signpost (31301) + +Base: 701 +Linked animations: [503] +Linked objects: null (1887), Altar (2478), Altar (2479), Altar (2480), Altar (2481), Altar (2482), Altar (2483), Altar (2484), Altar (2485), Altar (2486), Altar (2487), Altar (2488), Altar (17010), Altar (30624) + +Base: 702 +Linked animations: [502] +Linked objects: Mysterious glow (2498), Mysterious glow (2500), Mysterious glow (2501), Mysterious glow (3752), Mysterious glow (44441) + +Base: 703 +Linked animations: [505] +Linked objects: null (515) + +Base: 704 +Linked animations: [3217] +Linked objects: Gallows (11495) + +Base: 705 +Linked animations: [3172, 3173] +Linked objects: Portal machine (11357), Strange machine (11548), Strange machine (11549), Strange machine (47608), Strange machine (47609), Portal machine (47611) + +Base: 706 +Linked animations: [3218] +Linked objects: Chair (11496) + +Base: 707 +Linked animations: [3219] +Linked objects: Spooky picture (11497) + +Base: 708 +Linked animations: [3220] +Linked NPCs: null (3293), null (9350), null (9351), null (9352) + +Base: 709 + +Base: 710 +Linked animations: [3237] +Linked objects: Canary (11875) + +Base: 711 +Linked animations: [3230] +Linked objects: Rat wheel (11370), Treadmill (11677) + +Base: 712 +Linked animations: [504, 1055] +Linked graphics: 246, 247, 332, 626 +Linked objects: null (740), Portal (2465), Portal (2466), Portal (2467), Portal (2469), Portal (2470), Portal (2471), Portal (2472), Portal (2473), Portal (2474), Portal (2476), Portal (2477), Portal (2492), null (6550), Portal (6551), Portal (7272), Portal (7273), Portal (7288), Portal (7289), Portal (7315), Portal (7316), Portal (7318), Portal (7319), Portal (7321), Portal (7322), Portal (7324), Portal (7325), Portal (7352), Portal (7353), Portal (8972), Portal (8987), Portal (16050), Portal (16082), Portal (16116), Portal (16150), Portal (16686), Portal (23093), Floor (23094), Portal (23095), null (23098), Portal (28140), Portal (28779), Portal (28780), null (28888), Portal (29537), Portal (30146), Exit (36339), Exit (36340), Exit (36341), Portal (38697), Portal (41681) + +Base: 713 +Linked animations: [480] +Linked graphics: 470 +Linked objects: Swamp bubbles (684), Swamp bubbles (735), Swamp (3263), null (3961), Mud (5883), Swamp (5884), null (10169) + +Base: 714 +Linked animations: [2564] +Linked objects: Candles (9159), Candles (9160), Candles (9161), Candles (11472), Candles (11473), Candles (12301), Candles (12302), Candles (12980), Candles (12981), Candles (19127), Candles (24348), Candles (34615), Candles (39841) + +Base: 715 +Linked animations: [479] +Linked NPCs: Adventurer (4960) +Linked objects: Cauldron (692), Cauldron (2043), Cooking pot (3662), Troll Stew (3824), Lalli's Stew (4149), Betty's cauldron (9515), Aggie's Cauldron (9736), Cauldron (14338), Cauldron (14339) + +Base: 716 +Linked animations: [2708] +Linked objects: Hot Coals (9549) + +Base: 717 +Linked animations: [482, 483, 484, 485, 486, 487] + +Base: 718 +Linked animations: [477] +Linked objects: Fireplace (2724), Cooking pot (2727), Furnace (3294), Fireplace (9439), null (9442), Limestone fireplace (13612), Marble fireplace (13614), Limestone fireplace (17325), Fireplace (24285), Oven (24313), Furnace (26828), Fireplace (27251), Cooking pot (33499), Fireplace (36815), Fireplace (37426), Fireplace (40195), Fireplace (42350), Fireplace (46801), Fireplace (46802), Fireplace (46803), Fireplace (47573), null (52336) + +Base: 719 +Linked animations: [478] +Linked objects: Fireplace (2725), Fireplace (2726), Fireplace (8712), null (26192), Fireplace (33498) + +Base: 720 +Linked animations: [466] + +Base: 721 +Linked animations: [467] +Linked objects: Lamp (201) + +Base: 722 +Linked animations: [1731] +Linked objects: Millstones (1778), null (1784), Millstones (22419), null (22423) + +Base: 723 +Linked animations: [472] +Linked objects: Sails (1779), null (5626), null (22425) + +Base: 724 + +Base: 725 +Linked animations: [449] +Linked graphics: 239 +Linked objects: Broken barrel (672), null (2933) + +Base: 726 +Linked animations: [441, 442, 443, 444, 445] + +Base: 727 +Linked animations: [1732] +Linked objects: Fire (5631), Fire (5632), Uncooking pot (8985) + +Base: 728 +Linked animations: [475] +Linked objects: Fire remains (714), Fire (2732), Fire (3038), Fire (3775), Burning bones (3862), Flaming Fire altar (4090), null (4192), Fire (4265), Fire (4266), Fireplace (4618), Fireplace (4650), Fire (4766), Fire (5249), Fire remains (5252), Fire (5499), null (6405), null (6407), null (6409), null (6411), Standing Torch (6413), Standing Torch (6414), Standing Torch (6415), Standing Torch (6416), null (6818), Fire (10433), Fire (11404), Fire (11405), Fire (11406), null (12795), Fire (12796), Fire (14169), null (14172), Fire (15156), Fire remains (15206), Fire remains (15207), Fire remains (15208), Fire remains (15209), Fire remains (15210), null (19785), null (19786), Campfire (19881), null (19882), null (19883), Campfire (19884), Fire (20000), Fire (20001), Fire (21620), Camp fire (23063), Warm campfire (28486), Fire remains (33050), Standing torch (38618), Fire (49940), Fire (49941), Fire (49942), Fire (49943), Fire (49944), Fire (49945), Fire (49946), Fire (49947), Fire (49948), Fire (49949) + +Base: 729 +Linked animations: [476, 901, 1849, 1956] +Linked graphics: 78, 197, 357 +Linked objects: null (715), null (716), null (3357), null (3358), Wall of flame (5977), Wall of flame (5978), Wall of flame (5979), Wall of flame (5980), Blue Fire (6009) + +Base: 730 +Linked animations: [471] +Linked objects: Flagpole (860), Flagpole (861), Flagpole (862), Flagpole (869), Flagpole (3680), Flagpole (4692), Flagpole (4693), Flagpole (10057), Flagpole (11699) + +Base: 731 +Linked animations: [2699, 4431] +Linked objects: Hammock (9508), Hammock (16861), Hammock (17236), Hammock (18172), Hammock (34932) + +Base: 732 +Linked animations: [493] +Linked objects: null (731), null (3609), null (13858), null (13859), null (13860), Pool of Slime (17116), Pool of Slime (17117), Pool of Slime (17118), null (26831), null (26832) + +Base: 733 +Linked animations: [494] +Linked objects: null (732) + +Base: 734 +Linked animations: [495] + +Base: 735 +Linked animations: [525, 9719] +Linked objects: Fishing spot (14428) + +Base: 736 +Linked animations: [1032, 1033, 1730] +Linked objects: Standard (5628), Standard (5629), Standard (11615), Standard (11861), Standard (16568), Standard (16569), Standard (21635), Standard (21636), Standard (21637), null (21638) + +Base: 737 + +Base: 738 +Linked animations: [1727] +Linked objects: Rock (5604), Rock (5605), Rock (5606), null (5607), Rock (5985), Small rock (5986), Rock (5987), null (5988), Rock (8725), Rock (8726), Rocks (8727), Rock (15817), Small rock (15818), Rock (15819), Rock (16136), Small rock (16303), Rock (17364), Small rock (17365), Rock (17366), Rock (21571), Small rock (21572), Rock (21573), null (22347), null (22348), null (22349), Rock (23165), Rock (36626), Rock (36627), Rocks (36628), Rock (37619), Rock (37620), Rock (37621), null (40787), null (40789), null (40791) + +Base: 739 +Linked animations: [7255] + +Base: 740 +Linked animations: [1729] +Linked objects: Water wheel (5589), Water wheel (5590), Water wheel (5591), null (5593), Water wheel (5594), Water wheel (36867), Water wheel (36868), Water wheel (36869), null (36870), Water wheel (36871), Water wheel (45502), Water wheel (46022) + +Base: 741 +Linked animations: [1733] +Linked objects: Weather vane (5597), null (5811), Weather vane (33755), Weather vane (34578) + +Base: 742 +Linked animations: [488] +Linked objects: Weather vane (685) + +Base: 743 +Linked animations: [492, 1247] +Linked objects: Fly trap (1395) + +Base: 744 +Linked animations: [2749] +Linked objects: Tree (39328) + +Base: 745 +Linked animations: [496] +Linked graphics: 8 + +Base: 746 +Linked animations: [499] +Linked objects: Party Balloon (123), Party Balloon (124), Party Balloon (125), Party Balloon (126), Party Balloon (127), Party Balloon (128) + +Base: 747 +Linked animations: [501] +Linked objects: Party Balloon (130) + +Base: 748 +Linked animations: [500] +Linked objects: Party Balloon (129) + +Base: 749 +Linked animations: [498] +Linked objects: Party Balloon (115), Party Balloon (116), Party Balloon (117), Party Balloon (118), Party Balloon (119), Party Balloon (120), Party Balloon (121), Party Balloon (122) + +Base: 750 +Linked animations: [450] + +Base: 751 +Linked animations: [730] + +Base: 752 +Linked animations: [732] +Linked graphics: 183 + +Base: 753 +Linked animations: [731] +Linked graphics: 182 + +Base: 754 +Linked animations: [490] + +Base: 755 +Linked animations: [447, 448] + +Base: 756 +Linked animations: [912] +Linked objects: Flowers (2980), Flowers (2981), Flowers (2982), Flowers (2983), Flowers (2984), Flowers (2985), Flowers (2986), Flowers (2987), Flowers (2988) + +Base: 757 +Linked animations: [523] +Linked objects: null (673), null (675), null (676), null (677), null (3966), Shining pool (5897), Gas hole (5917), Gas hole (5918), null (12654), Steam Vent (15214) + +Base: 758 +Linked animations: [446] +Linked objects: Magical shield (2842) + +Base: 759 +Linked animations: [506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 3222, 3223, 3224, 3225, 3226, 3227, 3228, 3229] + +Base: 760 +Linked animations: [489] +Linked graphics: 67 + +Base: 761 + +Base: 762 +Linked animations: [522] +Linked objects: null (2016), null (2017), null (2018), null (5911), null (18513), null (18514) + +Base: 763 +Linked animations: [465, 914] +Linked graphics: 31, 68, 69, 456, 541, 622, 858 + +Base: 764 +Linked animations: [464] +Linked objects: Leak (2167), null (11221), null (11222), null (11223), null (11224), null (11225), null (11226), Ship hull (11317), Ship hull (11318), null (23553) + +Base: 765 +Linked animations: [526] +Linked objects: null (288) + +Base: 766 +Linked animations: [527] +Linked objects: null (289), null (290) + +Base: 767 +Linked animations: [907, 3231] +Linked objects: null (470), Spinning pole (11678) + +Base: 768 +Linked animations: [1726] +Linked objects: Grandfather clock (683), Grandfather clock (11493), Grandfather clock (25731), null (27050), Grandfather clock (27051), Grandfather clock (34493) + +Base: 769 +Linked animations: [470] +Linked objects: Spooky picture (955), Spooky picture (11469) + +Base: 770 +Linked animations: [462, 463] +Linked graphics: 65, 66 + +Base: 771 +Linked animations: [457] +Linked graphics: 60, 271, 302, 405, 1628 + +Base: 772 +Linked animations: [459] +Linked graphics: 62 +Linked objects: Speartrap (16517), Speartrap (20273), Spear trap (28527), Speartrap (30558) + +Base: 773 +Linked animations: [460, 461] +Linked graphics: 63, 64 + +Base: 774 + +Base: 775 +Linked animations: [458] +Linked graphics: 61 + +Base: 776 +Linked animations: [456] +Linked graphics: 59 +Linked objects: Whirlpool (2019) + +Base: 777 + +Base: 778 + +Base: 779 +Linked animations: [1362] +Linked objects: null (4619) + +Base: 780 +Linked animations: [491] +Linked objects: Portal (1812) + +Base: 781 +Linked animations: [469] +Linked objects: null (704) + +Base: 782 +Linked animations: [481, 4792, 9585] +Linked graphics: 789 +Linked objects: null (196), null (197), null (198), null (199), Standing torch (724), null (1914), null (4517), null (4694), Pillar (5072), null (5208), null (5247), null (6365), null (6537), Standing torch (6896), null (7376), null (8949), null (10116), null (10185), null (11129), null (11143), null (11817), null (11909), Torch (13201), Torch (13203), null (14361), null (15159), null (15161), null (16469), null (16661), null (16681), Torch (17237), null (28204), null (30286), null (30850), null (31706), null (31746), null (31765), Pillar (33398), Pillar (33399), null (33456), null (33464), null (33465), null (33466), null (33467), null (33468), null (33478), null (33493), null (33494), null (33799), Pillar (34317), null (34377), null (34424), Torch (35101), Torch (35102), null (35800), null (35801), null (36686), Standing torch (37820), null (38033), null (39354), null (41446), null (43034), Wall torch (43919), Wall torch (43928), Torch (44108), null (44131), null (44134), null (44159), null (44160), null (44172), null (48847), null (52294) + +Base: 783 +Linked animations: [468] +Linked objects: Charms (907), Charms (5559), Charms (14362), Charms (24677), Charms (25654), Charms (40075) + +Base: 784 +Linked animations: [524] +Linked objects: null (14437), null (14438) + +Base: 785 +Linked animations: [3946] +Linked graphics: 661 + +Base: 786 +Linked animations: [3944] +Linked objects: Obelisk (14825) + +Base: 787 +Linked animations: [3179] +Linked graphics: 561 + +Base: 788 + +Base: 789 +Linked animations: [3180] +Linked graphics: 562, 563, 564, 565, 566 +Linked objects: Raw chompy bird (11361), Raw Rabbit (11362), Iron spit (11363), Raw bird (19172), Raw hunting beast (19173) + +Base: 790 +Linked animations: [2165, 2166] +Linked NPCs: Pig (2239), Pig (2240), Piglet (2241), Piglet (2242), Piglet (2243), Pig (2316), Pig (2317), Piglet (2318), Piglet (2319), Piglet (8907) + +Base: 791 +Linked animations: [2296] +Linked graphics: 411 + +Base: 792 +Linked animations: [2294] +Linked graphics: 410 + +Base: 793 +Linked animations: [1773] +Linked NPCs: Bald Headed Eagle (1821), Eagle (5120), Eagle (5121), Eagle (5122), Eagle (5123), Karamjan Jungle Eagle (6384) + +Base: 794 + +Base: 795 +Linked animations: [1534, 1536, 1537, 1538, 2309] +Linked NPCs: Abyssal demon (1615), Abyssal minion (8624), Abyssal demon (9086), Abyssal minion (9245) + +Base: 796 + +Base: 797 +Linked animations: [1546] + +Base: 798 + +Base: 799 + +Base: 800 +Linked animations: [1562] + +Base: 801 + +Base: 802 + +Base: 803 + +Base: 804 +Linked animations: [1554, 1555, 1556, 1557, 1558] +Linked NPCs: Dust devil (1624), Smokedevil (1625) + +Base: 805 + +Base: 806 + +Base: 807 + +Base: 808 +Linked animations: [3159] + +Base: 809 +Linked animations: [3160, 3161, 3162, 3163, 3164, 3165] + +Base: 810 + +Base: 811 + +Base: 812 +Linked animations: [1564, 1566] + +Base: 813 +Linked animations: [1582, 1583, 1584, 1585] +Linked NPCs: Harpie Bug Swarm (3153) + +Base: 814 +Linked animations: [1577, 1578, 1579, 1580, 1581, 6436, 6437] +Linked NPCs: Lizard (2803), Desert Lizard (2804), Desert Lizard (2805), Desert Lizard (2806), Small Lizard (2807), Small Lizard (2808), Dagannoth fledgeling (2880), Lizard display (5975) + +Base: 815 + +Base: 816 + +Base: 817 +Linked animations: [1586, 1587, 1588, 1589, 1590, 1591, 1592, 1593] +Linked NPCs: Skeletal Wyvern (3068), Skeletal Wyvern (3069), Skeletal Wyvern (3070), Skeletal Wyvern (3071) + +Base: 818 +Linked animations: [1597, 2310, 2774, 2775, 2776, 2777, 2778, 2982, 2983] +Linked NPCs: Fungi (3344), Fungi (3345), Zygomite (3346), Zygomite (3347) +Linked graphics: 577, 578 + +Base: 819 +Linked animations: [224] +Linked graphics: 73 + +Base: 820 +Linked animations: [1573] +Linked graphics: 337 + +Base: 821 +Linked animations: [1569, 1570, 1571] +Linked graphics: 334, 335, 336, 633, 634, 635, 636, 637, 638, 639, 640, 641, 2184, 2185, 2186 + +Base: 822 +Linked animations: [1595] +Linked graphics: 500 + +Base: 823 +Linked animations: [1594] +Linked graphics: 499 + +Base: 824 +Linked animations: [1596] +Linked graphics: 501 + +Base: 825 +Linked animations: [2989] +Linked graphics: 575, 576 + +Base: 826 +Linked animations: [1576] +Linked graphics: 328, 330 + +Base: 827 +Linked animations: [1668] +Linked graphics: 340 + +Base: 828 +Linked animations: [1574] +Linked graphics: 327 + +Base: 829 + +Base: 830 + +Base: 831 +Linked animations: [664] +Linked graphics: 346 + +Base: 832 +Linked animations: [663] +Linked NPCs: null (3093), null (4420), null (4421) +Linked graphics: 185, 268 + +Base: 833 +Linked animations: [1966, 1967] +Linked graphics: 376, 377, 538 + +Base: 834 +Linked animations: [1970, 1971] +Linked graphics: 373, 375 + +Base: 835 +Linked animations: [1968, 1969] +Linked graphics: 372, 374, 537 + +Base: 836 +Linked animations: [662] +Linked graphics: 502 + +Base: 837 +Linked animations: [661] + +Base: 838 +Linked animations: [680] +Linked graphics: 141 + +Base: 839 +Linked animations: [174, 705] +Linked graphics: 81, 781 + +Base: 840 +Linked animations: [688] +Linked graphics: 149, 150, 151, 152 + +Base: 841 +Linked animations: [3169] +Linked NPCs: Storm Cloud (3203), Storm cloud (3301) + +Base: 842 +Linked animations: [3167, 3168, 4308, 4309] +Linked NPCs: Storm Cloud (3204) +Linked objects: Lightning (16190), Lightning (16191) + +Base: 843 +Linked animations: [668] +Linked graphics: 102 + +Base: 844 +Linked animations: [670] +Linked graphics: 104 + +Base: 845 +Linked animations: [669] +Linked graphics: 103 + +Base: 846 +Linked animations: [684] +Linked graphics: 145 + +Base: 847 +Linked animations: [686] +Linked graphics: 147 + +Base: 848 +Linked animations: [685] +Linked graphics: 146 + +Base: 849 +Linked animations: [674] +Linked graphics: 108 + +Base: 850 +Linked animations: [676] +Linked graphics: 110 + +Base: 851 +Linked animations: [675] +Linked graphics: 109, 168 + +Base: 852 + +Base: 853 +Linked animations: [677, 678, 679] +Linked graphics: 114, 115, 116 + +Base: 854 +Linked animations: [689, 690, 2718] +Linked graphics: 153, 154, 452 + +Base: 855 +Linked animations: [930] +Linked graphics: 238 + +Base: 856 +Linked animations: [696] +Linked graphics: 170 + +Base: 857 +Linked animations: [698] +Linked graphics: 172 + +Base: 858 +Linked animations: [697] +Linked graphics: 171 + +Base: 859 +Linked animations: [702] +Linked graphics: 177 + +Base: 860 +Linked animations: [704] +Linked graphics: 179, 180, 181 + +Base: 861 +Linked animations: [703] +Linked graphics: 178 + +Base: 862 +Linked animations: [701] +Linked graphics: 176 + +Base: 863 +Linked animations: [653, 3746] +Linked graphics: 85, 339, 629 + +Base: 864 +Linked animations: [650] +Linked graphics: 79 + +Base: 865 +Linked animations: [648] +Linked graphics: 77, 187 + +Base: 866 +Linked animations: [652] +Linked graphics: 84 + +Base: 867 +Linked animations: [655, 13177, 13612, 14386] +Linked graphics: 87, 2441, 2589 + +Base: 868 +Linked animations: [657] +Linked graphics: 89 + +Base: 869 +Linked animations: [656, 14387] +Linked graphics: 88 + +Base: 870 +Linked animations: [649] +Linked graphics: 83 + +Base: 871 +Linked animations: [1964, 1965] +Linked graphics: 368, 369, 370, 371, 539 + +Base: 872 +Linked animations: [1961] +Linked graphics: 363, 364, 365 + +Base: 873 +Linked animations: [1960] +Linked graphics: 362 + +Base: 874 +Linked animations: [1962, 1963] +Linked graphics: 366, 367, 540 + +Base: 875 +Linked animations: [1959] +Linked graphics: 361 + +Base: 876 +Linked animations: [1958] +Linked graphics: 360 + +Base: 877 +Linked animations: [913] +Linked graphics: 199 + +Base: 878 +Linked animations: [3138, 3139] +Linked graphics: 548, 549 + +Base: 879 +Linked animations: [2596] +Linked graphics: 436 + +Base: 880 +Linked animations: [2597, 2617] +Linked graphics: 437, 441 + +Base: 881 +Linked animations: [790] +Linked graphics: 186 + +Base: 882 +Linked animations: [647] +Linked graphics: 76 + +Base: 883 +Linked animations: [1976, 1977] +Linked graphics: 382, 383 + +Base: 884 +Linked animations: [1973] +Linked graphics: 379, 381 + +Base: 885 +Linked animations: [1974] +Linked graphics: 378 + +Base: 886 +Linked animations: [1975] +Linked graphics: 380, 536 + +Base: 887 +Linked animations: [1985, 1987] +Linked graphics: 389, 391 + +Base: 888 +Linked animations: [1984, 1986] +Linked graphics: 388, 390 + +Base: 889 +Linked animations: [1982, 1983] +Linked graphics: 385, 387 + +Base: 890 +Linked animations: [1980, 1981] +Linked graphics: 384, 386 + +Base: 891 +Linked animations: [2709, 5205] +Linked graphics: 931 +Linked objects: null (674) + +Base: 892 +Linked animations: [103, 334, 335, 351, 1717, 1718, 5018, 5482, 5484, 5486, 5488, 5490, 5492, 5804, 5805, 5806, 5807, 5808, 6268, 11691, 11692, 11693, 11694, 11695, 11696, 11697, 11698, 11699, 11700, 11701, 11702, 11703, 11704, 11705] +Linked NPCs: Leprechaun (418), Leprechaun (419), Shamus (654), Tool leprechaun (3021), Tool Leprechaun (4965), Tool leprechaun (7557), Tool leprechaun (7558), Tool leprechaun (7559), Tool leprechaun (7560), Tool leprechaun (7561), Tool leprechaun (7562), Tool leprechaun (7563), Tool leprechaun (7564), Tool leprechaun (7565), null (7566), Tool leprechaun (7567), null (7568), Tool leprechaun (7569), Goth leprechaun (8000), null (8001) + +Base: 893 + +Base: 894 +Linked animations: [1059, 12034] +Linked graphics: 248, 2117 + +Base: 895 +Linked animations: [924] +Linked graphics: 274 + +Base: 896 +Linked animations: [1063] +Linked graphics: 252, 306 + +Base: 897 +Linked animations: [1061] +Linked graphics: 251 + +Base: 898 +Linked animations: [1065, 12018] +Linked graphics: 253, 2116 + +Base: 899 +Linked animations: [1204] +Linked graphics: 282, 283, 284, 285 + +Base: 900 +Linked animations: [658] +Linked graphics: 194 + +Base: 901 +Linked animations: [660] +Linked graphics: 196, 269, 329, 331, 429, 430, 431, 677, 1883 + +Base: 902 +Linked animations: [659] +Linked graphics: 195, 676 + +Base: 903 +Linked animations: [699] +Linked graphics: 173 + +Base: 904 +Linked animations: [700] +Linked graphics: 174 + +Base: 905 +Linked animations: [706, 1054, 1066, 1257, 1874, 5437, 9968] +Linked graphics: 80, 245, 254, 291, 348, 426, 981, 1724 + +Base: 906 + +Base: 907 +Linked animations: [1822] +Linked graphics: 345 + +Base: 908 +Linked animations: [1821] +Linked graphics: 344 + +Base: 909 +Linked animations: [681] +Linked graphics: 142 + +Base: 910 +Linked animations: [683] +Linked graphics: 144 + +Base: 911 +Linked animations: [682] +Linked graphics: 143 + +Base: 912 +Linked animations: [1447] +Linked graphics: 308 + +Base: 913 +Linked animations: [1817] +Linked graphics: 343 + +Base: 914 +Linked animations: [1813, 1814, 1815] +Linked graphics: 342 + +Base: 915 +Linked animations: [694] +Linked graphics: 167 + +Base: 916 +Linked animations: [695] +Linked graphics: 169 + +Base: 917 +Linked animations: [2558, 2559, 2560] +Linked graphics: 433, 434, 435 + +Base: 918 +Linked animations: [691] + +Base: 919 +Linked animations: [693, 12724, 12725] +Linked graphics: 71, 198, 266, 305, 359, 505, 2278, 2279, 2282 + +Base: 920 +Linked animations: [692] + +Base: 921 +Linked animations: [671, 5529] +Linked graphics: 105, 998 + +Base: 922 +Linked animations: [673] +Linked graphics: 107, 489, 492, 1725 + +Base: 923 +Linked animations: [672] +Linked graphics: 106 + +Base: 924 +Linked animations: [651] +Linked graphics: 82 + +Base: 925 +Linked animations: [2725] +Linked graphics: 455 + +Base: 926 +Linked animations: [1076] +Linked graphics: 272 + +Base: 927 +Linked animations: [1072] +Linked objects: Monument (3493), Monument (3494), Monument (3495), Monument (3496), Monument (3497), Monument (3498), Monument (3499) + +Base: 928 +Linked animations: [1073] +Linked objects: null (3434), null (3474), Golden lantern (9145), Lantern (16901), null (31775), null (31776), Lantern (34937), Lantern (34938) + +Base: 929 +Linked animations: [1079, 1080, 1081, 1082, 1083, 1619] + +Base: 930 +Linked animations: [1071] +Linked NPCs: Will o' the wisp (1043), Will o' the wisp (1211), Will o' the wisp (1212) +Linked objects: null (726) + +Base: 931 +Linked animations: [2380, 5013] +Linked objects: Light jungle (9010), Light jungle (9011), Light jungle (9012), Light jungle (9013), Light jungle (9014), Medium jungle (9015), Medium jungle (9016), Medium jungle (9017), Medium jungle (9018), Medium jungle (9019), Dense jungle (9020), Dense jungle (9021), Dense jungle (9022), Dense jungle (9023), Dense jungle (9024) + +Base: 932 +Linked animations: [2395, 2396, 2397, 2398, 2399] +Linked NPCs: Large mosquito (2493), Mosquito swarm (2494), Mosquito swarm (2495), Giant mosquito (4347) + +Base: 933 +Linked animations: [2404] +Linked graphics: 428 + +Base: 934 +Linked animations: [2381] +Linked graphics: 427 + +Base: 935 +Linked animations: [3998, 4000, 4002] +Linked graphics: 666, 667 +Linked objects: Claw (14976) + +Base: 936 +Linked animations: [4011, 4012, 4013, 4014, 4015] +Linked objects: null (15017), null (15018), null (15021) + +Base: 937 +Linked animations: [4016] + +Base: 938 +Linked animations: [4005, 4006] +Linked objects: Pinball Post (15000), Pinball Post (15001), Pinball Post (15002), Pinball Post (15003), Pinball Post (15004), Pinball Post (15005), Pinball Post (15006), Pinball Post (15007), Pinball Post (15008), Pinball Post (15009) + +Base: 939 +Linked animations: [4020] +Linked graphics: 668 + +Base: 940 +Linked animations: [4022] +Linked objects: Lift Engine (15229), null (15238) + +Base: 941 +Linked animations: [4032, 4033, 4034, 4035] +Linked graphics: 672, 673, 674, 675 + +Base: 942 +Linked animations: [4037, 4038, 4039, 4040, 4041, 4042] +Linked NPCs: Giant Sea Snake (3943) + +Base: 943 +Linked animations: [4025, 4026] +Linked graphics: 669, 670 + +Base: 944 +Linked animations: [4027] +Linked graphics: 671 + +Base: 945 + +Base: 946 +Linked animations: [4126] +Linked objects: null (15538), null (15539), Flowers (16729), Flowers (16730), Flowers (16731), null (18315) + +Base: 947 +Linked animations: [4125] +Linked objects: Oil lamp (24033), null (24414), Oil lamp (33472), Oil lamp (43171), null (44951) + +Base: 948 + +Base: 949 +Linked animations: [4134, 4135] + +Base: 950 +Linked animations: [4137, 4138] + +Base: 951 +Linked animations: [3196, 3197, 3198, 3199, 3200, 3201, 3202, 3203, 3204, 3205, 4155, 4156] + +Base: 952 +Linked animations: [4161] +Linked objects: Magical Animator (15621) + +Base: 953 +Linked animations: [4157, 4158, 4159, 4160] +Linked objects: Catapult (15617), Catapult (15618), Catapult (15619), Catapult (15620) + +Base: 954 +Linked animations: [4162, 4163, 4164] +Linked objects: Dummy (15624), Dummy (15625), Dummy (15626), Dummy (15627), Dummy (15628), Dummy (15629), Dummy (15630) + +Base: 955 +Linked animations: [4165] +Linked graphics: 679, 680, 681, 682 + +Base: 956 +Linked animations: [4186] +Linked graphics: 689 + +Base: 957 +Linked animations: [4176] +Linked graphics: 683 + +Base: 958 +Linked animations: [4187] +Linked graphics: 684, 685, 686, 687, 688 + +Base: 959 +Linked animations: [3206] +Linked objects: Crate (1), Crate (15599), Crates (15600) + +Base: 960 + +Base: 961 +Linked animations: [6094] +Linked objects: Cow wheel (12114), Cow wheel (52530) + +Base: 962 +Linked animations: [4222] + +Base: 963 +Linked animations: [4217, 4218] +Linked objects: Drip (15727), Drips (15728), Drip (23172), Drips (23173) + +Base: 964 +Linked animations: [4224] +Linked graphics: 701, 702, 703 + +Base: 965 +Linked animations: [4215] +Linked graphics: 693 + +Base: 966 +Linked animations: [4212] +Linked graphics: 695 + +Base: 967 +Linked animations: [4214] +Linked graphics: 692 + +Base: 968 +Linked animations: [4225] +Linked graphics: 704 + +Base: 969 +Linked animations: [4223] +Linked graphics: 700 + +Base: 970 +Linked animations: [4213] +Linked graphics: 691 + +Base: 971 +Linked animations: [4216] +Linked graphics: 694 + +Base: 972 +Linked animations: [4229] +Linked graphics: 705 + +Base: 973 +Linked animations: [4284] +Linked objects: Portal of Death (16043), Portal of Death (16044), Rickety door (16065), Rickety door (16066), Oozing barrier (16089), Oozing barrier (16090), Gate of War (16123), Gate of War (16124) + +Base: 974 +Linked animations: [4231, 4232, 4233, 4234, 4235, 4236, 4237] +Linked NPCs: Jungle horror (4348), Jungle horror (4349), Jungle horror (4350), Jungle horror (4351), Jungle horror (4352), Cave horror (4353), Cave horror (4354), Cave horror (4355), Cave horror (4356), Cave horror (4357) + +Base: 975 +Linked animations: [4262] + +Base: 976 +Linked animations: [4244, 4245, 4246, 4247, 4253] +Linked objects: Bitternut Tree (15962), Bitternut Tree (15963), Bitternut Tree (15964), Bitternut Tree (15965), Bitternut Tree (15966), Bitternut Tree (15967), Bitternut Tree (15968), Bitternut Tree (15969) + +Base: 977 +Linked animations: [4260] +Linked objects: Bottle machine (15923) + +Base: 978 +Linked animations: [4240, 4241] +Linked objects: Conveyor Belt (15925), Conveyor Belt (15927) + +Base: 979 +Linked animations: [4239] +Linked objects: Bamboo Pipes (15838), Bamboo Pipes (15839), Hopper (15848), Hopper (15849), Bamboo Pipes (15864), Bamboo Pipes (15865), Hopper (15874), Hopper (15875), Boiler (15905), Boiler (15908), Boiler (15911), Boiler (15914), Water Pump (15937), Red Flowers (15941), Blue Flowers (15942), Jungle Tree (15949), Jungle Tree (15952), Jungle Tree (15955), Burning tree (41857), Burning tree (41858), Burning tree (41859), null (42133), Burning tree (42134), Burning tree (42135), Volcanic habitat (44826), Burning tree (52716), Burning tree (52717) + +Base: 980 +Linked animations: [4242, 4243] +Linked objects: Steam Pump (15929) + +Base: 981 +Linked animations: [4259] +Linked NPCs: Parrot (4373), Parrot (4374) + +Base: 982 +Linked animations: [4248, 4249] +Linked graphics: 706, 707 + +Base: 983 +Linked animations: [4261] +Linked graphics: 711 + +Base: 984 +Linked animations: [4252] +Linked graphics: 709, 710 + +Base: 985 +Linked animations: [4251] +Linked graphics: 708 + +Base: 986 +Linked animations: [4274] +Linked objects: null (16032) + +Base: 987 + +Base: 988 +Linked animations: [4281] + +Base: 989 +Linked animations: [4268, 4269, 4270, 4271, 4272, 4273] +Linked NPCs: Catablepon (4397), Catablepon (4398), Catablepon (4399) + +Base: 990 +Linked animations: [4263, 4264, 4265, 4266, 4267] +Linked NPCs: Minotaur (4404), Minotaur (4405), Minotaur (4406), Minotaur (11258) + +Base: 991 +Linked animations: [4279] +Linked graphics: 713 + +Base: 992 + +Base: 993 +Linked animations: [4286] +Linked graphics: 714 + +Base: 994 +Linked animations: [4323] +Linked objects: null (16356) + +Base: 995 +Linked animations: [4324] +Linked objects: null (16357) + +Base: 996 +Linked animations: [4325] +Linked objects: null (16361), null (16362) + +Base: 997 + +Base: 998 +Linked animations: [4312, 4313, 4314, 4315] +Linked NPCs: Starflower (4451), Starflower (4452) + +Base: 999 +Linked animations: [7054] +Linked graphics: 1215 + +Base: 1000 +Linked animations: [4303, 4304, 4305, 4306, 4307, 4326, 4327] +Linked NPCs: Cosmic Being (4419) + +Base: 1001 +Linked animations: [4298, 4299, 4300, 4301, 4302] +Linked NPCs: Gorak (4418), Gorak (6218), Gorak (10207), Gorak (10208), Gorak (10209), Gorak (10210), Gorak (10211) + +Base: 1003 +Linked animations: [4318, 4319, 4320, 4321, 4322, 7051, 7052, 7058, 7059, 7060, 7061, 7062, 7063, 7064, 11293, 11298, 11301, 11357, 11373, 11399, 11400, 11401, 11402, 11406, 11407, 11408, 11409, 11410] +Linked NPCs: General Graardor (6260), Spiritual ranger (6276), Spiritual warrior (6277), Spiritual mage (6278), Ork statue (7084), Ourg statue (7086) +Linked objects: Ork statue (42589), Ork statue (42590), Ork statue (42604), Ork statue (42607) + +Base: 1004 +Linked animations: [4333] + +Base: 1005 + +Base: 1006 +Linked animations: [4339] +Linked objects: An anonymous looking door (16483), An anonymous looking door (16484), An anonymous looking door (16485), An anonymous looking door (16486), An anonymous looking door (16487), An anonymous looking door (16488), An anonymous looking door (16489), An anonymous looking door (16490), An anonymous looking door (16491), An anonymous looking door (16492), An anonymous looking door (16493), An anonymous looking door (16494) + +Base: 1007 +Linked animations: [4336, 4337] +Linked objects: Sarcophagus (16495), Sarcophagus (16496), Sarcophagus (16497), Sarcophagus (16498), Sarcophagus (16499), Sarcophagus (16500) + +Base: 1008 +Linked animations: [4338] +Linked objects: Tomb Door (16476), null (16538), null (16539), null (16540), null (16541), null (16542), null (16543), null (16544), null (16545), null (16546) + +Base: 1009 +Linked animations: [4335] +Linked objects: Urn (16501), Urn (16502), Urn (16503), Urn (16504), Urn (16505), Urn (16506), Urn (16507), Urn (16508), Urn (16509), Urn (16510), Urn (16511), Urn (16512), Urn (16513), Urn (16514), Urn (16515), Urn (16516) + +Base: 1010 +Linked animations: [4334] +Linked graphics: 715 + +Base: 1011 +Linked animations: [4346, 4347] + +Base: 1012 +Linked animations: [4351] +Linked graphics: 716, 717, 718 + +Base: 1013 +Linked animations: [4399] +Linked objects: Hanging pirate (16859) + +Base: 1014 +Linked animations: [4383, 4384, 4385, 4386, 4387, 4388, 4389] +Linked NPCs: Suqah (4527), Suqah (4528), Suqah (4529), Suqah (4530), Suqah (4531), Suqah (4532), Suqah (4533) + +Base: 1015 +Linked animations: [4408] +Linked objects: Ceremonial Brazier (16810), Ceremonial Brazier (16811), null (17025) + +Base: 1016 +Linked animations: [4377] +Linked objects: Table (16827), Table (16828) + +Base: 1017 +Linked animations: [4392] +Linked objects: Light (16701) + +Base: 1018 +Linked animations: [4393] +Linked objects: Hat rack (16691), Hat rack (16692) + +Base: 1019 +Linked animations: [4394, 4395, 4396, 4397, 4398] +Linked objects: Cooker (16812), Rack (16813), Stool (16814), Table (16815), null (16816) + +Base: 1020 +Linked animations: [4390, 4391] +Linked NPCs: House (4512) + +Base: 1021 +Linked animations: [4372] +Linked NPCs: Enchanted Broom (4521), Enchanted Broom (4522), Enchanted Broom (4523) + +Base: 1022 +Linked animations: [4373, 4374, 4375, 4376] +Linked NPCs: Enchanted Bucket (4524), Enchanted Bucket (4525) + +Base: 1023 +Linked animations: [4353] +Linked graphics: 719 + +Base: 1024 +Linked animations: [4403, 4404, 4405] + +Base: 1025 +Linked animations: [4355] +Linked objects: Dream tree (16604) + +Base: 1026 +Linked animations: [4358, 4359] +Linked objects: Platform (16632), Platform (16633), Platform (16634), Platform (16635), Platform (16636), Platform (16637), null (16830), null (16832), null (16834), null (16836), null (16838), null (16840), null (16842) + +Base: 1027 +Linked animations: [4357] +Linked objects: Hurdle (16600), Note (16601), Note (16602) + +Base: 1028 +Linked animations: [4356] +Linked objects: Zero (16619), One (16620), Two (16621), Three (16622), Four (16623), Five (16624), Six (16625), Seven (16626), Eight (16627), Nine (16628), null (29447), null (29448), null (29449), null (29450), null (29451), null (29452), null (29453), null (29454), null (29455) + +Base: 1029 +Linked animations: [4354] +Linked objects: Our lives (11398), My life (16599), Our Lives (47255) + +Base: 1030 +Linked animations: [4362, 4363, 4364] +Linked objects: Dream puff (16856), Dream puff (16857) + +Base: 1031 +Linked animations: [4360, 4361] +Linked objects: Dice (16849), Dice (16850), Dice (16851), Dice (16852), Dice (16853), Dice (16854), Dice (16855) + +Base: 1032 +Linked animations: [4422] +Linked graphics: 746 + +Base: 1033 +Linked animations: [4418, 4420, 4421] +Linked graphics: 727, 728, 729, 730, 731, 732, 733, 742, 744, 745, 748 + +Base: 1034 +Linked animations: [4414] +Linked graphics: 734, 736, 738 + +Base: 1035 +Linked animations: [4419] +Linked graphics: 722, 735, 737, 739, 740, 741, 743 + +Base: 1036 +Linked animations: [4423] +Linked graphics: 747 + +Base: 1037 +Linked animations: [4417] +Linked graphics: 725, 726 + +Base: 1038 +Linked animations: [4415, 4416] +Linked graphics: 723, 724 + +Base: 1039 +Linked animations: [4407, 4735, 4736, 4737] +Linked graphics: 721, 784, 785, 786 + +Base: 1040 + +Base: 1041 +Linked animations: [4448] +Linked graphics: 754 + +Base: 1042 +Linked animations: [4445] +Linked graphics: 751 + +Base: 1043 +Linked animations: [4451] +Linked graphics: 757 + +Base: 1044 +Linked animations: [4450] +Linked graphics: 756 + +Base: 1045 +Linked animations: [4449] +Linked graphics: 755 + +Base: 1046 +Linked animations: [4463] +Linked graphics: 759 + +Base: 1047 +Linked animations: [4453, 4461, 12437] +Linked graphics: 760, 2171 + +Base: 1048 +Linked animations: [4447] +Linked graphics: 753 + +Base: 1049 +Linked animations: [4443, 4575] +Linked graphics: 281, 749, 1715 + +Base: 1050 +Linked animations: [4446] +Linked graphics: 752 + +Base: 1051 +Linked animations: [4444] +Linked graphics: 750 + +Base: 1052 +Linked animations: [4452] +Linked graphics: 758 + +Base: 1053 +Linked animations: [4469] + +Base: 1054 +Linked animations: [4472, 4473, 4474, 4475, 4476] +Linked NPCs: null (4613), null (4616), null (4619), null (4622), null (4625), null (4628), fluffie (4631), fluffie (4632), null (6310), null (6333) + +Base: 1055 +Linked animations: [4477] +Linked objects: null (13113) + +Base: 1056 +Linked animations: [4478] +Linked graphics: 776 + +Base: 1057 +Linked animations: [4577] +Linked objects: null (17208) + +Base: 1058 +Linked animations: [4565, 4567, 4569] +Linked objects: Gnome crowd (17197), Gnome crowd (17198), Gnome crowd (17201), Gnome crowd (17202), Gnome crowd (17205), Gnome crowd (17206) + +Base: 1059 +Linked animations: [4564, 4566, 4568, 6161, 6162, 6163] +Linked objects: Goblin crowd (13115), Goblin crowd (17196), Goblin crowd (17199), Goblin crowd (17200), Goblin crowd (17203), Goblin crowd (17204), Goblin crowd (23306), Goblin crowd (23307), Goblin crowd (23308), Goblin crowd (23309), Goblin crowd (23310), Goblin crowd (23311), Goblin crowd (23312), Goblin crowd (23313), Goblin crowd (23314), null (29183), null (29184) + +Base: 1060 +Linked animations: [4559] +Linked objects: Aspidistra plant (17238) + +Base: 1061 +Linked animations: [4557] +Linked objects: Table (17235) + +Base: 1062 +Linked animations: [4563] +Linked objects: Broken cogs (17242), Cogs (17243), null (17281), Cogs (26789) + +Base: 1063 +Linked animations: [4560] +Linked objects: Oaknock's machine (17240), Oaknock's machine (17241), null (17280), Yewnock's machine (26788) + +Base: 1064 +Linked animations: [4561] +Linked objects: Oaknock's Machine (17245), Oaknock's Machine (17246), Oaknock's Machine (17247), null (17282), Yewnock's machine (26791) + +Base: 1065 +Linked animations: [4562] +Linked objects: Oaknock's exchanger (17248), Oaknock's exchanger (17249), null (17283), Yewnock's exchanger (26792) + +Base: 1066 +Linked animations: [4576] + +Base: 1067 +Linked animations: [4570, 4571, 4572, 4573] +Linked objects: Argento (17274), Argento (17279) + +Base: 1068 +Linked animations: [4584] +Linked graphics: 774 + +Base: 1069 +Linked animations: [4535] +Linked objects: Office table (17130) + +Base: 1070 +Linked animations: [4541, 4542, 6760] +Linked graphics: 765, 766, 1170 + +Base: 1071 +Linked animations: [4543, 4545, 7149, 7150] +Linked graphics: 767, 769, 1230, 1232 + +Base: 1072 +Linked animations: [4548] +Linked graphics: 768 + +Base: 1073 +Linked animations: [4554, 4555] +Linked graphics: 771, 772 + +Base: 1074 +Linked animations: [4550] +Linked graphics: 770 + +Base: 1075 +Linked animations: [4556] +Linked graphics: 773 + +Base: 1076 +Linked animations: [4574] + +Base: 1077 +Linked animations: [4595] +Linked objects: null (17324) + +Base: 1078 +Linked animations: [63, 64, 65, 66, 67, 68, 69, 4619, 4620, 4623, 4624, 4629, 4630, 4644, 4674, 4675, 4676, 4677, 4678, 4679, 4680, 4681, 12608, 12627, 12983, 13278, 13283, 13597, 13598, 13599, 13600, 13601, 13602, 13603, 13604, 13605, 13606, 13611, 13761, 13762, 13763, 14237] +Linked NPCs: Lesser demon (82), Greater demon (83), Black demon (84), Chronozon (667), Black demon (677), Delrith (879), Weakened Delrith (880), Kolodion (911), Nezikchened (934), Othainian (998), Doomion (999), Holthion (1000), Jungle demon (1472), Agrith Naar (2919), Lesser Demon Champion (3064), Demon (3593), Lesser demon (4694), Lesser demon (4695), Lesser demon (4696), Lesser demon (4697), Greater demon (4698), Greater demon (4699), Greater demon (4700), Greater demon (4701), Black demon (4702), Black demon (4703), Black demon (4704), Black demon (4705), Lesser demon (6101), Tstanon Karlak (6204), Zakl'n Gritch (6206), Balfrug Kreeyath (6208), Har'Lakk the Riftsplitter (9898), Har'Lakk the Riftsplitter (9899), Har'Lakk the Riftsplitter (9900), Har'Lakk the Riftsplitter (9901), Har'Lakk the Riftsplitter (9902), Har'Lakk the Riftsplitter (9903), Har'Lakk the Riftsplitter (9904), Har'Lakk the Riftsplitter (9905), Har'Lakk the Riftsplitter (9906), Har'Lakk the Riftsplitter (9907), Har'Lakk the Riftsplitter (9908), Har'Lakk the Riftsplitter (9909), Har'Lakk the Riftsplitter (9910), Har'Lakk the Riftsplitter (9911), To'Kash the Bloodchiller (10024), To'Kash the Bloodchiller (10025), To'Kash the Bloodchiller (10026), To'Kash the Bloodchiller (10027), To'Kash the Bloodchiller (10028), To'Kash the Bloodchiller (10029), To'Kash the Bloodchiller (10030), To'Kash the Bloodchiller (10031), To'Kash the Bloodchiller (10032), To'Kash the Bloodchiller (10033), To'Kash the Bloodchiller (10034), To'Kash the Bloodchiller (10035), To'Kash the Bloodchiller (10036), To'Kash the Bloodchiller (10037), To'Kash the Bloodchiller (10038), To'Kash the Bloodchiller (10039), Bal'lak the Pummeller (10128), Bal'lak the Pummeller (10129), Bal'lak the Pummeller (10130), Bal'lak the Pummeller (10131), Bal'lak the Pummeller (10132), Bal'lak the Pummeller (10133), Bal'lak the Pummeller (10134), Bal'lak the Pummeller (10135), Bal'lak the Pummeller (10136), Bal'lak the Pummeller (10137), Bal'lak the Pummeller (10138), Bal'lak the Pummeller (10139), Bal'lak the Pummeller (10140), Bal'lak the Pummeller (10141), Lesser demon (10492), Lesser demon (10493), Lesser demon (10494), Lesser demon (10495), Greater demon (10718), Greater demon (10719), Greater demon (10720), Greater demon (10721), Black demon (10722), Black demon (10723), Black demon (10724), Black demon (10725), Pit black demon (11566), Pit black demon (11592), Pit black demon (11593) +Linked objects: Pit black demon (39264), Pit black demon (41607) + +Base: 1079 +Linked animations: [4631] +Linked graphics: 497 + +Base: 1080 +Linked animations: [21, 25, 26, 27, 28, 79, 80, 81, 82, 83, 84, 89, 90, 91, 92, 2265, 2266, 4635, 4638, 4642, 6446, 6447, 6496, 6642, 6643, 6722, 6825, 8342, 9912, 9913, 9914, 9915, 9916, 9917, 9918, 9919, 9920, 9921, 9922, 9923, 9924, 9925, 9926, 9927, 9928, 9929, 9930, 9931, 9932, 9933, 9934, 10939] +Linked NPCs: King Black Dragon (50), King Black Dragon (2642), Baby red dragon (3588), Steel dragon (3590), Hatchling dragon (6900), Baby dragon (6901), Hatchling dragon (6902), Baby dragon (6903), Hatchling dragon (6904), Baby dragon (6905), Hatchling dragon (6906), Baby dragon (6907), Dragon (7943), Dragon (7944), Dragon (7945), Dragon (7946), Dragon (7947), Dragon (7948), Baby dragon (9208), Baby dragon (9209), Baby dragon (9210), Baby dragon (9211) +Linked objects: Baby red dragon (13372), Steel dragon (13375) + +Base: 1081 +Linked animations: [4649, 4650, 4651, 4652, 4653, 4654, 4655, 4656, 4657, 4658, 4659, 4660, 4661, 4662, 4663, 4664, 4665, 4666, 4667, 4668, 4669, 4670, 4671, 4672, 4673, 6368, 6369, 6370, 6371, 6372] +Linked NPCs: Fire giant (110), Ice giant (111), Moss giant (112), Cyclops (116), Hill Giant (117), Fire giant (1582), Fire giant (1583), Fire giant (1584), Fire giant (1585), Fire giant (1586), Moss giant (1587), Moss giant (1588), Moss giant (1681), Giant Champion (3058), Ice giant (3072), Cyclops (4291), Cyclops (4292), Moss giant (4534), Ice giant (4685), Ice giant (4686), Ice giant (4687), Moss giant (4688), Hill Giant (4689), Hill Giant (4690), Hill Giant (4691), Hill Giant (4692), Hill Giant (4693), Moss giant (4706), Cyclops (6078), Cyclops (6079), Cyclops (6080), Cyclops (6081), Cyclops (6269), Cyclops (6270), Fire giant (7003), Fire giant (7004), Hill giant (10706), Hill giant (10707), Hill giant (10708), Hill giant (10709), Hill giant (10710), Hill giant (10711), Hill giant (10712), Hill giant (10713), Hill giant (10714), Hill giant (10715), Hill giant (10716), Hill giant (10717), Fire giant (10754), Fire giant (10755), Fire giant (10756), Fire giant (10757), Fire giant (10758), Fire giant (10759), Fire giant (10760), Fire giant (10761), Ice giant (10762), Ice giant (10763), Ice giant (10764), Ice giant (10765), Ice giant (10766), Ice giant (10767), Ice giant (10768), Ice giant (10769), Fire giant (11622) + +Base: 1082 + +Base: 1083 +Linked animations: [4621, 4622, 12609] +Linked objects: Stone table (17436), Stone table (17437) + +Base: 1084 +Linked animations: [4599, 4600] +Linked objects: Wardrobe (17434) + +Base: 1085 +Linked animations: [4601] +Linked graphics: 777 + +Base: 1086 + +Base: 1087 + +Base: 1088 + +Base: 1089 + +Base: 1090 +Linked animations: [86, 1990, 2264] +Linked graphics: 1, 393, 394, 395, 396, 440, 498, 1718 + +Base: 1091 +Linked animations: [4755, 4756] +Linked NPCs: Boat (4770), Boat (4771) + +Base: 1092 +Linked animations: [4744] +Linked objects: null (17632), Wall (18075), Falling door (18102), null (18128), null (18134) + +Base: 1093 +Linked animations: [4745] +Linked objects: Wall (18080), null (18131) + +Base: 1094 +Linked animations: [4743] +Linked objects: Decorated wall (18145) + +Base: 1095 +Linked animations: [4746] +Linked objects: Waste pipes (17509) + +Base: 1096 +Linked animations: [4747] +Linked objects: Waste pipes (17511) + +Base: 1097 +Linked animations: [4683, 4685, 4687, 4689, 4691, 4693, 4695, 4697, 4706, 9106, 9107, 9108, 9112, 9113, 9114, 9115, 9116, 9117] +Linked NPCs: Flying female vampire (4809), Flying female vampire (4810), Flying female vampire (4811), Flying female vampire (4812), Vyrewatch (4813), Vyrewatch (4814), Vyrewatch (4815), Vyrewatch (4816), Vyrewatch (4821), Vyrewatch (4822), Vyrewatch (4823), Vyrewatch (4824), Vyrewatch (4825), Vyrewatch (4826), Vyrewatch (4827), Vyrewatch (4828), Vyrewatch (4829), Vyrewatch (4830), Vyrewatch (4831), Vyrewatch (4832), Vyrewatch (4833), Vyrewatch (4834), Vyrewatch (4835), Vyrewatch (4836), Flying female vampire (4845), Flying female vampire (4846), Flying female vampire (4847), Flying female vampire (4848), Vyrewatch (4849), Vyrewatch (4850), Vyrewatch (4851), Vyrewatch (4852), Flying female vampire (7610), Flying female vampire (7611), Flying female vampire (7612), Flying female vampire (7613), Vyrewatch (7614), Vyrewatch (7615), Vyrewatch (7616), Vyrewatch (7617), Vyrewatch (7622), Vyrewatch (7623), Vyrewatch (7624), Vyrewatch (7625), Vyrewatch (7626), Vyrewatch (7627), Vyrewatch (7628), Vyrewatch (7629), Vyrewatch (7630), Vyrewatch (7631), Vyrewatch (7632), Vyrewatch (7633), Vyrewatch (7634), Vyrewatch (7635), Vyrewatch (7682), Vyrewatch (7683), Vyrewatch (7684), Vyrewatch (7685), Vyrewatch (7691), Vyrewatch (7692), Vyrewatch (7693), Vyrewatch (7694), Vyrewatch (7695), Vyrewatch (7696), Vyrewatch (7697), Vyrewatch (7698), Vyrewatch (7699), Vyrewatch (7700), Vyrewatch (7701), Vyrewatch (7702), Vyrewatch (7703), Vyrewatch (7704), Vyrewatch (7705), Vyrewatch (7706) + +Base: 1098 +Linked animations: [4699, 4700, 4701, 4702, 4703, 4704, 4705, 4708, 4711, 4714, 4715, 4716, 4717, 4725, 4729, 4732, 4733, 4734, 4767, 4768, 4769, 4770, 9020, 9118] +Linked NPCs: Juvinate guard (4772), Juvinate guard (4773), Vampyre juvenile (4774), Vampyre juvenile (4775), Vampyre juvinate (4776), Vampyre juvinate (4777), Held vampyre juvenile (4778), Held vampyre juvenile (4779), Held vampyre juvinate (4780), Held vampyre juvinate (4781), Vampyre juvinate (4782), Vanstrom Klause (4791), Vanstrom Klause (4792), Vanstrom Klause (4793), Vanescula Drakan (4797), Vanescula Drakan (4798), Ranis Drakan (4801), Ranis Drakan (4802), Vyrewatch (4805), Vyrewatch (4806), Vyrewatch (4807), Vyrewatch (4808), Vyrewatch (4817), Vyrewatch (4818), Vyrewatch (4819), Vyrewatch (4820), Vyrewatch (4837), Vyrewatch (4838), Vyrewatch (4839), Vyrewatch (4840), Vyrewatch (4841), Vyrewatch (4842), Vyrewatch (4843), Vyrewatch (4844), Vanstrom Klause (4862), Vyrewatch (7606), Vyrewatch (7607), Vyrewatch (7608), Vyrewatch (7609), Vyrewatch (7618), Vyrewatch (7619), Vyrewatch (7620), Vyrewatch (7621) + +Base: 1099 +Linked animations: [4684, 4686, 4688, 4690, 4692, 4694, 4696, 4698, 4707] +Linked NPCs: Vanstrom Klause (4794), Vanstrom Klause (4795), Vanstrom Klause (4796), Vanescula Drakan (4799), Vanescula Drakan (4800), Ranis Drakan (4803), Ranis Drakan (4804) + +Base: 1100 +Linked animations: [4753, 4754] +Linked NPCs: null (4765), null (5562) + +Base: 1101 +Linked animations: [4738, 4739, 4740, 4741, 4742] +Linked NPCs: Shanty Claws (828) + +Base: 1102 +Linked animations: [4730] +Linked graphics: 787 + +Base: 1103 +Linked animations: [4751, 4752] + +Base: 1104 +Linked animations: [4748, 4749, 9026, 9027] + +Base: 1105 +Linked animations: [4773, 4774, 4775, 4776, 4777] +Linked NPCs: Stray dog (4766), Stray dog (4767), Stray dog (5917), Stray dog (5918) + +Base: 1107 +Linked animations: [6123] +Linked objects: null (23215) + +Base: 1108 +Linked animations: [4782] +Linked objects: null (25885) + +Base: 1109 +Linked animations: [4781] + +Base: 1110 +Linked animations: [4783] +Linked objects: null (7173), null (18358) + +Base: 1111 +Linked animations: [4837] +Linked graphics: 798 + +Base: 1112 +Linked animations: [4822, 4823] + +Base: 1113 +Linked animations: [4811, 4812, 4813, 4814, 4815, 4816, 4817, 4818] + +Base: 1114 +Linked animations: [4821, 4828, 4829, 4830, 4831, 4832] +Linked NPCs: Slug Prince (4890) +Linked graphics: 796 + +Base: 1115 +Linked animations: [4819, 4820, 4842] +Linked NPCs: Mother Mallum (4889) + +Base: 1116 +Linked animations: [4827] +Linked graphics: 792, 795 + +Base: 1117 +Linked animations: [4840] +Linked graphics: 799 + +Base: 1118 +Linked animations: [4836] +Linked graphics: 797 + +Base: 1119 +Linked animations: [4799, 4800, 4801, 4802, 4803] + +Base: 1120 +Linked animations: [4796, 4798] +Linked objects: Crane (18326) + +Base: 1121 + +Base: 1122 +Linked animations: [4810] +Linked graphics: 791 + +Base: 1123 +Linked animations: [4808] +Linked graphics: 790 + +Base: 1124 +Linked animations: [4843, 4844, 4845, 4846, 8388, 8389, 8390, 8391, 8392, 8393, 8394, 8403, 8404, 8405, 8406, 8898, 8899, 8900, 10555] + +Base: 1125 + +Base: 1126 + +Base: 1127 + +Base: 1128 + +Base: 1129 +Linked animations: [4860] +Linked objects: null (3410), null (11669), null (12101), null (18524), null (21942) + +Base: 1130 +Linked animations: [4864, 4865, 4866, 4867, 4868, 4869, 4870] +Linked NPCs: Earth elemental (1020), Earth elemental (4910), Elemental rock (4911) + +Base: 1131 +Linked animations: [4912] + +Base: 1132 +Linked animations: [4887, 4888, 4889, 4890] + +Base: 1133 +Linked animations: [4899] +Linked objects: null (18689) + +Base: 1134 +Linked animations: [4960] +Linked graphics: 823 + +Base: 1135 +Linked animations: [4897, 4900] +Linked objects: Extractor gun (18694), Extractor gun (18695), null (18725) + +Base: 1136 +Linked animations: [4882, 4883] +Linked graphics: 807 +Linked objects: Extractor hat (18690) + +Base: 1137 +Linked animations: [4898] +Linked objects: null (18723) + +Base: 1139 +Linked animations: [4908] + +Base: 1140 +Linked animations: [4962] +Linked graphics: 824 + +Base: 1141 +Linked animations: [4894] +Linked objects: Press support (18642) + +Base: 1142 +Linked animations: [14243] +Linked graphics: 2745, 2746 + +Base: 1143 +Linked animations: [1050] +Linked graphics: 813 + +Base: 1144 +Linked animations: [4895, 4902, 4903] +Linked objects: Water Tank (18661) + +Base: 1145 +Linked animations: [4875, 4876, 4877, 4878, 4879, 4880, 4881] +Linked objects: Door (18652), Door (18653), Door (18654), Door (18655), Door (18656), Door (18657), Door (18658), Door (18659) + +Base: 1146 +Linked animations: [4896, 4906, 4907] +Linked objects: Cog (18668), Cog (18672), Cog (18674) + +Base: 1147 +Linked animations: [4966] +Linked graphics: 826 + +Base: 1148 +Linked animations: [4901] +Linked objects: Tunnel wall (18760) + +Base: 1149 +Linked animations: [4886] +Linked graphics: 808 + +Base: 1150 +Linked animations: [4893] +Linked graphics: 810, 811, 2686 + +Base: 1151 +Linked animations: [4919, 4920, 4921, 4922, 4923, 4924, 4925, 4926, 4927, 4928, 4929, 4930, 5719, 5720, 8522, 8523, 8524, 8566, 10234, 10242] +Linked NPCs: Grizzly bear (105), Black bear (106), Witch's experiment (third form) (899), Grizzly bear (1195), Grizzly bear cub (1196), Grizzly bear cub (1197), Bear Cub (1326), Bear Cub (1327), Angry bear (3645), Angry bear (3664), Arctic bear (6839), Arctic bear (6840), null (8076), null (8677), Chuck (8678), Chuck (12188) + +Base: 1152 +Linked animations: [4931, 4932, 4933, 4934, 4935, 7904, 7905, 7906, 7907, 8545] +Linked NPCs: Giant rat (86), Giant rat (87), Dungeon rat (88), Dungeon rat (224), Giant rat (446), Giant rat (950), Blessed giant rat (978), Giant crypt rat (2033), Giant rat (2091), Angry giant rat (3647), Angry giant rat (3662), Giant rat (4395), Giant crypt rat (4920), Giant crypt rat (4921), Giant rat (4922), Giant rat (4923), Giant rat (4924), Giant rat (4925), Giant rat (4926), Giant rat (4927), Dungeon rat (4928), Dungeon rat (4929), Dungeon rat (4936), Dungeon rat (4937), Angry giant rat (4938), Angry giant rat (4939), Angry giant rat (4940), Blessed giant rat (4941), Giant rat (4942), Giant rat (4943), Giant rat (4944), Giant rat (4945), Zombie rat (6088), Zombie rat (6089), Zombie rat (6090), Albino rat (6847), Albino rat (6848), Rat (7202), Rat (7204), Rat (7461), Warped rat (7920), Giant rat (8828), Giant rat (8829), Albino rat (9472), Giant rat (10480), Giant rat (10481), Giant rat (10482), Giant rat (10483), Giant rat (10484), Giant rat (10485), Giant rat (10486) + +Base: 1153 +Linked animations: [4913, 4914, 4915, 4916, 4917, 4918, 8271, 8272, 8273, 8274, 8275, 8276, 8277, 8279, 8320, 8321, 8563, 12459, 12460, 12461, 12462] +Linked NPCs: Giant bat (78), Death wing (79), Bat (412), Giant bat (1005), Giant bat (2482), Albino bat (4345), Fruit bat (6817), Vampire bat (6835), Vampire bat (6836), Warped bat (7922), Vampire bat (9474), Bat (10906), Bat (10907), Bat (10908), Bat (10909), Giant bat (10910), Giant bat (10911), Giant bat (10912), Giant bat (10913), Giant bat (10914) + +Base: 1154 +Linked animations: [4948] +Linked graphics: 817 + +Base: 1155 +Linked animations: [4978] +Linked graphics: 830 + +Base: 1156 + +Base: 1157 +Linked animations: [4954] +Linked graphics: 820 + +Base: 1158 +Linked animations: [1043, 4956] +Linked graphics: 821, 2684 + +Base: 1159 +Linked animations: [4950] +Linked graphics: 818 + +Base: 1160 + +Base: 1161 +Linked animations: [4964] +Linked graphics: 825 + +Base: 1162 +Linked animations: [4976] +Linked graphics: 831 + +Base: 1163 +Linked animations: [4952] +Linked graphics: 819 + +Base: 1164 +Linked animations: [4938] +Linked graphics: 812 + +Base: 1165 +Linked animations: [4970] +Linked graphics: 835 + +Base: 1166 + +Base: 1167 + +Base: 1168 +Linked animations: [4942] +Linked graphics: 814 + +Base: 1169 +Linked animations: [4980] +Linked graphics: 829 + +Base: 1170 +Linked animations: [4946] +Linked graphics: 816 + +Base: 1171 +Linked animations: [4974] +Linked graphics: 832 + +Base: 1172 +Linked animations: [2130, 4871, 4872, 4968] +Linked NPCs: Ballista (11450), Ballista (11451) + +Base: 1173 +Linked animations: [4944] +Linked graphics: 815 + +Base: 1174 +Linked animations: [4982] +Linked graphics: 828 + +Base: 1175 + +Base: 1176 +Linked animations: [4958, 10484] +Linked graphics: 822 + +Base: 1177 +Linked animations: [5012] +Linked objects: Dolphin (18841), Fish (18842) + +Base: 1178 +Linked animations: [5021, 5022, 5023, 5024, 5025, 5026, 5027, 5028, 5029, 5030, 5031, 5032, 5033] +Linked NPCs: Baby Roc (4971), Giant Roc (4972) + +Base: 1179 +Linked animations: [5019, 5020] +Linked graphics: 851, 852 + +Base: 1180 +Linked animations: [5014] +Linked graphics: 849 + +Base: 1181 +Linked animations: [5004] +Linked graphics: 841 + +Base: 1182 +Linked animations: [5010, 5011] +Linked graphics: 846, 847 + +Base: 1183 +Linked animations: [5003] +Linked graphics: 840 + +Base: 1184 +Linked animations: [4984] +Linked graphics: 848 + +Base: 1185 +Linked animations: [5005, 5007, 5008, 5009] +Linked graphics: 842, 843, 844, 845 + +Base: 1186 +Linked animations: [5035, 5036] +Linked graphics: 856, 857 + +Base: 1187 +Linked animations: [5034] +Linked graphics: 855 + +Base: 1188 +Linked animations: [5421] + +Base: 1189 +Linked animations: [5415, 8845] +Linked objects: Lava crater (20232), Poison crater (20233), Lava crater (20234), Poison crater (20235), null (26604), null (26605), null (26829), null (26830), Lava crater (28220), null (29271), null (29272), Steam vent (29741), Steam vent (29742), Volcanic habitat (44827) + +Base: 1190 +Linked animations: [5430] +Linked objects: Egg launcher (20133) + +Base: 1191 +Linked animations: [5431, 5432] +Linked objects: Egg hopper (20264), Egg hopper (20265), Egg hopper (20266), null (20267) + +Base: 1192 +Linked animations: [5424, 5425, 5426] +Linked NPCs: Egg launcher (5028) + +Base: 1193 +Linked animations: [5423] +Linked objects: Horn of glory (20247) + +Base: 1194 +Linked animations: [5076] + +Base: 1195 +Linked animations: [5077] + +Base: 1196 + +Base: 1197 + +Base: 1198 +Linked animations: [5420] + +Base: 1199 +Linked animations: [5055] +Linked objects: Cactus (18875) + +Base: 1200 +Linked animations: [5053] + +Base: 1201 +Linked animations: [5044, 5045] +Linked NPCs: Cart Camel (4979) + +Base: 1202 + +Base: 1203 +Linked animations: [5181, 5182, 5183, 5184, 5185] +Linked NPCs: Chinchompa (5079), Carnivorous chinchompa (5080) + +Base: 1204 + +Base: 1205 +Linked animations: [5187, 5188, 5189, 5190, 5191, 5192] +Linked NPCs: Ferret (5081), null (5139) + +Base: 1206 +Linked animations: [5225, 5226, 5227, 5228, 5229, 5230, 5231, 5232, 5233, 5234, 5235, 7014, 7015, 7016, 7017, 7018, 7019, 7909, 7910, 7911, 7912, 7913, 7914, 7915, 7916, 7918, 7919, 8917, 12088, 12823] +Linked NPCs: Sabre-toothed kyatt (5103), Spined larupia (5104), Horned graahk (5105), Growler (6250), Dawg (7104), Spirit larupia (7337), Spirit larupia (7338), Spirit graahk (7363), Spirit graahk (7364), Spirit kyatt (7365), Spirit kyatt (7366), Spirit kyatt (9478), Spirit larupia (9479), Rogue spirit larupia (9583), Rogue spirit larupia (9584), Rogue spirit larupia (9585), Rogue spirit larupia (9586) +Linked graphics: 937, 938, 939, 940, 941, 942, 1365, 1366, 1367, 1369 +Linked objects: null (19253), null (19254), null (19255), null (19256), null (19257), null (19258), null (19259), null (19260), null (19261), null (19262), null (19263), null (19264), null (19265), null (19266), null (19267), null (19268), null (43614) + +Base: 1207 +Linked animations: [5279, 5280, 5281, 5282] +Linked NPCs: Desert eagle (5130), Jungle eagle (5131), Polar eagle (5132), Eagle (5133), null (5134), null (5135), null (5136), Karamjan Jungle eagle (6385), null (6387) + +Base: 1208 +Linked animations: [5204, 5272, 5273, 5275, 5276, 5277, 6110, 8689] +Linked NPCs: Chocolate kebbit (3686), Chocolate kebbit (3687), Prickly kebbit (5086), Sabre-toothed kebbit (5087), Barb-tailed kebbit (5088), Wild kebbit (5089), Spotted kebbit (5098), Dark kebbit (5099), Dashing kebbit (5100), Diseased kebbit (7039), null (7040), null (7041), null (7042), null (7043) +Linked graphics: 928, 929, 930, 1046, 1047 + +Base: 1209 +Linked animations: [5262, 5263] +Linked NPCs: Orange salamander (5114), Red salamander (5115), Black salamander (5116), Swamp lizard (5117) + +Base: 1210 +Linked animations: [5265] +Linked graphics: 954 + +Base: 1211 +Linked animations: [5264] +Linked graphics: 952, 953 + +Base: 1212 + +Base: 1213 +Linked animations: [5081, 5214] +Linked graphics: 910, 911, 912, 913, 914, 915, 916, 917, 2299, 2300, 2301, 2302 + +Base: 1214 +Linked animations: [5186] +Linked graphics: 908, 909 + +Base: 1215 + +Base: 1216 + +Base: 1217 +Linked animations: [5110, 5111, 5112, 5113, 5114, 5115, 5116, 5117, 5118, 5119, 5120, 5121, 5122, 5123, 5124, 5125, 5126, 5127, 5128, 5129, 5130, 5131, 5132, 5133, 5134, 5135, 5136, 5137, 5138, 5139] + +Base: 1218 +Linked animations: [5141] +Linked objects: Basket (19128), Basket (19129), Air balloon (19130), null (19133), null (19134), null (19135), null (19136), null (19137), null (19138), null (19139), null (19140), null (19141), null (19142), null (19143), null (19144) + +Base: 1219 +Linked animations: [5109] +Linked objects: Basket (19156), Basket (19164) + +Base: 1220 +Linked animations: [5157] + +Base: 1221 +Linked animations: [5154] + +Base: 1222 +Linked animations: [5143, 5144] +Linked graphics: 877, 878, 880, 881, 883, 884, 886, 887, 889, 890, 892, 893, 895, 896, 898, 899, 901, 902, 904, 905 + +Base: 1223 +Linked animations: [5145, 5156] +Linked graphics: 879, 882, 885, 888, 891, 894, 897, 900, 903, 906 + +Base: 1224 +Linked animations: [5223, 5224] +Linked graphics: 933, 934, 935, 936 + +Base: 1225 +Linked animations: [5169, 5170] +Linked objects: Bird snare (19174), Bird snare (19176) + +Base: 1226 +Linked animations: [12115] + +Base: 1227 +Linked animations: [5260, 5261] +Linked objects: null (19441), null (19442), null (19443), null (19444), null (19445), null (19446), null (19447), null (19448), null (19449), null (19450), null (19451), null (19452), null (19453), null (19454), null (19455), null (19456), null (19457), null (19458), null (19459), null (19460), null (19461), null (19462), null (19463), null (19464), null (19465), null (19466), null (19467), null (19468), null (19469), null (19470), null (19471), null (19472), null (19473), null (19474), null (19475), null (19476), null (19477), null (19478), null (19479), null (19480), null (19481), null (19482), null (19483), null (19484), null (19485), null (19486), null (19487), null (19488), null (19489), null (19490), null (19491), null (19495), null (19496), null (19497), null (19498), null (19499), null (19500), null (19501), null (19502), null (19503), null (19505), null (19506), null (19508), null (19509), null (19511), null (19512), null (19514), null (19515), null (19517), null (19518), null (19520), null (19521), null (19523), null (19524), null (19526), null (19527), null (19529), null (19530), null (19532), null (19533), null (19535), null (19536), null (19538), null (19539), null (19541), null (19542), null (19544), null (19545), null (19547), null (19548), null (19550), null (19551), null (19554), null (19555), null (19556), null (19557), null (19558), null (19559), null (19560), null (19561), null (19562), null (19564), null (19565), null (19567), null (19568), null (19570), null (19571), null (19573), null (19574), null (19576), null (19577), null (19579), null (19580), null (19582), null (19583), null (19585), null (19586), null (19588), null (19589), null (19591), null (19592), null (19642), null (19643), null (19644), null (19645), null (19646), null (19647), null (19648), null (19649), null (19951), null (19952), null (19953), null (43280), null (43281), null (43282), null (43283), null (43284), null (43285), null (43286), null (43287), null (43288), null (43289), null (43290), null (43291), null (43292), null (43293), null (43294), null (43295), null (43296), null (43297), null (43298), null (43299), null (43300), null (43301), null (43302), null (43303), null (43304), null (43305), null (43306), null (43307), null (43308), null (43309), null (43310), null (43311), null (43312), null (43313), null (43314), null (43315), null (43316), null (43317), null (43318), null (43319), null (43320), null (43321), null (43322), null (43323), null (43324), null (43325), null (43326), null (43327), null (43328), null (43329), null (43330), null (43331), null (43332), null (43333), null (43334), null (43335), null (43336), null (43337), null (43338), null (43339), null (43340), null (43341), null (43342), null (43343), null (43344), null (43345), null (43346), null (43347), null (43348), null (43349), null (43350), null (43351), null (43352), null (43353), null (43354), null (43355), null (43356), null (43357), null (43358), null (43359), null (43360), null (43361), null (43362), null (43363), null (43364), null (43365), null (43366), null (43367), null (43368), null (43369) + +Base: 1228 +Linked animations: [5219, 5220, 5221, 5222] +Linked objects: Magic box (19223), Magic box failed (19224), Magic box (19225), Magic box (19226) + +Base: 1229 +Linked animations: [5278, 5770] +Linked NPCs: Iceberg (5467), Iceberg (5468) + +Base: 1230 + +Base: 1231 +Linked animations: [5175, 5176, 5177, 5178, 5179, 11771, 11772, 11773, 11774, 11775, 11776, 11777, 11778] +Linked objects: Box trap (19188), Shaking box (19189), Shaking box (19190), Shaking box (19191), Box trap (19193), Box trap (19194), Box trap (19195), Box trap (19196), Box trap (19197), Box trap (19198), Box trap (19199), Box trap (19200), Box trap (19201), Box trap (19202), Box trap (19203), Box trap (19204), Shaking box (28557), Shaking box (28558), Shaking box (28567), Box trap (28568), Box trap (28569), Box trap (28570), Box trap (28571), Box trap (28754), Box trap (28755), Box trap (28756), Box trap (28757), Box trap (28758), Box trap (28759), Box trap (28760), Box trap (28777), Shaking box (28906), Box trap (28908), Box trap (28909), Box trap (28910), Box trap (28911), Shaking box (28913), Box trap (28915), Box trap (28916), Box trap (28917), Box trap (28918), Shaking box (28920), Shaking box (28921), Shaking box (28922), Shaking box (28923), Shaking box (28924), Shaking box (28925), Shaking box (28926), Shaking box (28927), Shaking box (28928), Shaking box (28929), Box trap (29185), Box trap (29186), Box trap (29187), Box trap (29188), Box trap (29189), Box trap (29190), Box trap (29191), Box trap (29192), Shaking box (29887), Shaking box (29888), Box trap (29889), Box trap (29890), Box trap (29891), Box trap (29892), Box trap (29893), Box trap (29894), Box trap (29895), Box trap (29896), Shaking box (29897), Shaking box (29898), Shaking box (29899), Shaking box (29900), Shaking box (29901), Shaking box (29902), Shaking box (29903), Shaking box (29904), Shaking box (29905), Box trap (29906), Box trap (29907), Box trap (29908), Box trap (29909), Shaking box (29910), Shaking box (29911), Shaking box (29912), Shaking box (29913), Box trap (29914), Box trap (29915), Box trap (29916), Box trap (29917), Box trap (29918), Box trap (29919), Box trap (29920), Box trap (29921), Box trap (29922), Box trap (29923), Box trap (29924), Box trap (29925), Box trap (29926), Box trap (29927), Box trap (29928), Box trap (29929), Box trap (29960), Box trap (29961), Box trap (29962), Box trap (29963), Box trap (29964), Box trap (29965), Box trap (29966), Box trap (29967), Box trap (29968), Box trap (29969), Box trap (29970), Box trap (29971), Box trap (29972), Box trap (29973), Box trap (29974), Box trap (29975), Box trap (29976), Box trap (29977), Box trap (29978), Box trap (29979), Box trap (29980), Box trap (29981), Box trap (29982), Box trap (29983), Box trap (29984), Box trap (29985), Box trap (29986), Box trap (29987), Box trap (29988), Box trap (29989), Box trap (29990), Box trap (29991), Shaking box (43470), Shaking box (43471), Shaking box (43472), Shaking box (43473), Box trap (43474), Box trap (43475), Box trap (43476), Box trap (43477) + +Base: 1232 +Linked animations: [5193, 5194, 5195, 5196, 5197, 5274, 5664, 5679, 5683, 5686, 5687, 5711] +Linked graphics: 947, 948, 949, 950, 951 +Linked objects: Boulder (19205), Deadfall (19206), Deadfall (19207), Deadfall (19208), Deadfall (19209), Deadfall (19210), Deadfall (19211), Deadfall (19212), Deadfall (19213), Deadfall (19214), Boulder (19215), Boulder (19216), Boulder (19217), Boulder (19218), Deadfall (19219), Boulder (19851), Boulder (28935), Boulder (28936), Deadfall trap (28937), Deadfall trap (28938), Deadfall trap (28939), Deadfall trap (28940), Boulder (28941), Boulder (28942), Boulder (28943), Boulder (28944), Boulder (28945), Deadfall (29161), Deadfall (29162), Boulder (29163), Boulder (43462), Boulder (43463), Deadfall (43464), Deadfall (43465), Deadfall (43466), Deadfall (43467), Boulder (43468), Boulder (43469) + +Base: 1233 + +Base: 1234 + +Base: 1235 + +Base: 1236 +Linked animations: [5266, 5267, 5268, 5269, 5270, 5271] +Linked objects: Young tree (19650), Net trap (19654), Net trap (19655), Net trap (19656), Net trap (19657), Net trap (19658), Net trap (19659), Net trap (19660), Net trap (19661), Young tree (19662), Net trap (19666), Net trap (19667), Net trap (19668), Net trap (19669), Young tree (19670), Net trap (19674), Net trap (19675), Net trap (19676), Net trap (19677), Young tree (19678), Net trap (28559), Net trap (28560), Net trap (28561), Net trap (28562), Young tree (28563), Net trap (28750), Net trap (28751), Net trap (28752), Net trap (28753), Net trap (29930), Net trap (29931), Net trap (29932), Net trap (29933), Net trap (29934), Net trap (29935), Net trap (29936), Net trap (29937), Net trap (43478), Net trap (43479), Net trap (43480), Net trap (43481), Old fishing rod (43482) + +Base: 1237 + +Base: 1238 +Linked animations: [4133, 5198, 5199, 5200, 5201, 5202, 5203, 5283, 5284] +Linked NPCs: Gyr Falcon (5094), Gyr Falcon (5095), Gyr Falcon (5096), Gyr Falcon (5097) +Linked graphics: 918, 919, 920, 921, 922, 923, 924, 925, 926, 927 +Linked objects: Pigeon (15486), Occupied perch (19221) + +Base: 1239 +Linked animations: [5159] +Linked graphics: 907 + +Base: 1240 +Linked animations: [168, 169, 170, 171, 172, 2954, 2955, 4287, 4288, 4289, 4616, 4618, 4626, 4627, 4648, 5218, 5285, 6628, 6629, 6630, 6826, 6986, 7574, 11059, 11903] +Linked NPCs: Imp (708), Imp (709), Imp (1531), Imp Champion (3062), null (6069), Imp defender (6074), Dunce (6134), Imp (6211), Snow imp (6732), Snow imp (6733), Snow imp (6734), Snow imp (6735), Snow imp (6736), Snow imp (6737), Snow imp (6738), Snow imp (6739), Marvin (8512), Marius (8513), Benny (8514), Zimberfizz (8526), null (8527), Zimberfizz (8533), Zimberfizz (8534), Snow imp (8536), Snow imp (8537), Snow imp (8538), Head snow imp (8541), Head snow imp (8542), Head snow imp (8543), Zimberfizz (8592), null (8609), Zimberfizz (8610), null (8611), null (8612), Zimberfizz (8613), Snow imp (9364), null (9372), null (9373), null (9374), null (9375), Snow imp (9376), Snow imp (9377), Snow imp (9378), Snow imp (9379), Imp (11605) +Linked graphics: 932 + +Base: 1241 +Linked animations: [5286, 5477, 7080] +Linked graphics: 697, 955, 993, 1226 + +Base: 1242 +Linked animations: [5306, 5307, 5308] +Linked objects: Bird feeder (19936), Bird feeder (19937), Bird feeder (19938), Bird feeder (19939), Bird feeder (19940), Bird feeder (19941), Bird feeder (19942), Bird feeder (19943), Bird feeder (19944) + +Base: 1243 +Linked animations: [5295, 5296, 5297] +Linked objects: Pedestal (19981), Pedestal (19982), Pedestal (19983) + +Base: 1244 +Linked animations: [5309, 5310] +Linked NPCs: Boulder (5140) + +Base: 1245 +Linked animations: [5287, 5289, 5290, 5291, 5292] +Linked graphics: 956, 957, 958, 959, 961, 962, 963, 964 + +Base: 1246 +Linked animations: [5294, 5301, 5302, 5303, 5304, 5305] +Linked NPCs: Kebbit (5137) +Linked graphics: 965, 966 + +Base: 1247 +Linked animations: [5334, 5335, 5336, 5337, 5338, 5339, 5340, 5341, 5342, 5343, 5344, 5345, 5346] +Linked NPCs: Sheep (42), Sheep (43), null (292), null (293), null (294), null (295), Billy (1093), Mountain goat (1094), Mountain goat (1140), Mountain goat (1141), Golden sheep (1271), Golden sheep (1272), Sheep (1529), Sheep (1762), Sheep (1763), Sheep (1764), Sheep (1765), Mountain Goat (1819), Mountain Goat (1820), Sick-looking sheep (1) (2345), Sick-looking sheep (2) (2346), Sick-looking sheep (3) (2347), Sick-looking sheep (4) (2348), Sick-looking sheep (1) (2377), Sick-looking sheep (2) (2378), Sick-looking sheep (3) (2379), Sick-looking sheep (4) (2380), Sheep (3310), Sheep (3311), Ram (3672), Ram (3673), null (4253), null (4254), null (4255), null (4256), Goat (4930), Goat (4931), Billy Goat (4932), Goat (4933), Goat (4934), Billy Goat (4935), Li'l lamb (5146), Lamb (5147), Sheep (5148), Sheep (5149), Sheep (5150), Sheep (5151), Sheep (5152), Sheep (5153), Sheep (5154), Sheep (5155), Sheep (5156), Sheep (5157), Sheep (5158), Sheep (5159), Sheep (5160), Sheep (5161), Sheep (5162), Sheep (5163), Sheep (5164), Mountain Goat (5166), Mountain Goat (5167), Ram (5168), Ram (5169), Ram (5170), Mountain goat (5171), Golden sheep (5172), Golden sheep (5173), Sheep (8876), Sheep (8877) + +Base: 1248 +Linked animations: [5317, 5318, 5319, 5320, 5321, 5322, 5323, 5324, 5325, 5326, 5327, 5328, 5329, 5330, 5331, 5332, 5333, 6862, 8162, 8163, 8164, 8165, 8170, 8544, 12464] +Linked NPCs: Shadow spider (58), Giant spider (59), Giant spider (60), Jungle spider (62), Deadly red spider (63), Ice spider (64), Poison spider (134), Witch's experiment (second form) (898), Blessed spider (977), Kalrag (997), Poison spider (1009), Jungle spider (1478), Giant crypt spider (2035), Jungle spider (2491), Jungle spider (2492), Fever spider (2850), Huge spider (3585), Giant spider (4400), Jungle spider (6376), Jungle spider (6377), Knight of the Eight-Fold Seal (6507), Grand Chamberlain of the Web (6508), Marshall of the Teeming Horde (6509), Master Web-Spinner (6536), Spirit spider (6841), Spirit spider (6842), Spider (7207), Royal Fly-Catcher (8973), Keeper of the Royal Eggs (8974), Ice spider (10157), Ice spider (10158), Ice spider (10159), Ice spider (10160), Ice spider (10161), Ice spider (10162), Ice spider (10163), Ice spider (10164), Ice spider (10165), Ice spider (10166), Ice spider (10167), Dungeon spider (10496), Dungeon spider (10497), Dungeon spider (10498), Dungeon spider (10499), Dungeon spider (10500), Dungeon spider (10501), Dungeon spider (10502), Dungeon spider (10503), Dungeon spider (10504), Dungeon spider (10505), Dungeon spider (10506), Night spider (10698) +Linked objects: Huge Spider (13370), null (46654), null (46655), null (46656) + +Base: 1249 +Linked animations: [5350] +Linked objects: Pillar (20022), Pillar (20023), Pillar (20024), Pillar (20026), Pillar (20027), Pillar (20028), Pillar (20030), Pillar (20031), Pillar (20032), Pillar (21546), Pillar (21547), Pillar (21548) + +Base: 1250 +Linked animations: [5351] +Linked objects: Machine (20040) + +Base: 1251 +Linked animations: [5360] +Linked objects: null (20066), null (20067), null (20068), null (20069), null (20070), null (20071), null (20072), null (20073), null (20074), null (20075), null (20076), null (20077), null (20078), null (20079), null (20080), null (20081), null (20082), null (20083) + +Base: 1252 +Linked animations: [5353] +Linked graphics: 969 + +Base: 1253 +Linked animations: [5382] +Linked graphics: 972 + +Base: 1254 +Linked animations: [5381] +Linked graphics: 973 + +Base: 1255 +Linked animations: [3951, 5380, 5385, 5386, 5387, 5388, 5389, 7807, 7808, 7809, 7810, 7813, 8555] +Linked NPCs: Chicken (41), Oomlie bird (48), Chicken (951), Chicken (1017), Rooster (1018), Chicken (1401), Chicken (1402), Rooster (1403), Undead chicken (1692), Chicken (2313), Chicken (2314), Chicken (2315), Sneaky undead fowl (5209), Swordchick (5595), Dreadfowl (6825), Dreadfowl (6826), Chicken (11256), Chicken (11257) + +Base: 1256 +Linked animations: [5062] + +Base: 1257 +Linked animations: [5068] +Linked objects: Childerkin slaves (20100), Childerkin slaves (20117) + +Base: 1258 +Linked animations: [5058] +Linked objects: Wintumber tree (19038) + +Base: 1259 +Linked animations: [5061, 5069, 5070, 5071, 5072, 5073, 8771, 8772, 8773, 8774, 8775, 8776, 8777] +Linked NPCs: null (829), null (5003), null (5004), null (5005), null (5006), null (5007), null (5008), null (5009), null (5010), null (5011), null (5012), null (5013), null (5014), null (5015), null (5016), Gublinch (5017), Gublinch (5018), Gublinch (5019), Gublinch jailmate (7144), Gublinchette jailmate (7145), Gublinchette jailmate (7146), Gublinch jailmate (7147), Gublinch jailmate (7148), Gublinch jailmate (7149), Gublinch jailmate (7150) +Linked objects: Cage with gublinch (19037), null (20119), null (20120), null (20121), null (20122), null (20123), null (20124), null (20125), null (20126), null (20127), null (20128) + +Base: 1260 +Linked animations: [5060] +Linked graphics: 859 + +Base: 1261 +Linked animations: [5064, 5065, 5066] +Linked graphics: 860, 861, 862, 1281, 1282 + +Base: 1262 +Linked animations: [5094, 5095, 5096, 5097, 5098] +Linked NPCs: Penance Fighter (5040), Penance Fighter (5044), Penance Fighter (5045), Penance Fighter (5213), Penance Fighter (5214), Penance Fighter (5215), Penance Fighter (5216), Penance Fighter (5217), Penance Fighter (5218), Penance Fighter (5219) + +Base: 1263 +Linked animations: [5104, 5105, 5106, 5107] +Linked NPCs: Penance Healer (5043), Penance Healer (5238), Penance Healer (5239), Penance Healer (5240), Penance Healer (5241), Penance Healer (5242), Penance Healer (5243), Penance Healer (5244), Penance Healer (5245), Penance Healer (5246) + +Base: 1264 +Linked animations: [5082, 5086] + +Base: 1265 +Linked animations: [5408, 5409, 5410, 5411, 5412, 5413, 5414] +Linked NPCs: Penance Queen (5247) + +Base: 1266 +Linked animations: [5089, 5090, 5091, 5092, 5093] +Linked NPCs: Queen spawn (5248) + +Base: 1267 +Linked animations: [5393, 5394, 5395, 5396, 5397] +Linked NPCs: Penance Ranger (5041), Penance Ranger (5229), Penance Ranger (5230), Penance Ranger (5231), Penance Ranger (5232), Penance Ranger (5233), Penance Ranger (5234), Penance Ranger (5235), Penance Ranger (5236), Penance Ranger (5237) + +Base: 1268 +Linked animations: [5099, 5100, 5101, 5102] +Linked NPCs: Penance Runner (5042), Penance Runner (5220), Penance Runner (5221), Penance Runner (5222), Penance Runner (5223), Penance Runner (5224), Penance Runner (5225), Penance Runner (5226), Penance Runner (5227), Penance Runner (5228) + +Base: 1269 +Linked animations: [5433] +Linked graphics: 975 + +Base: 1270 +Linked animations: [5434] +Linked graphics: 976, 980 + +Base: 1271 +Linked animations: [5435] +Linked graphics: 977, 978, 979 + +Base: 1272 + +Base: 1273 +Linked animations: [5422] +Linked objects: null (20246) + +Base: 1274 +Linked animations: [5392] +Linked graphics: 863, 864 + +Base: 1275 +Linked animations: [5403, 5404, 5405] +Linked graphics: 870, 871, 872 + +Base: 1276 +Linked animations: [5398] +Linked graphics: 866 + +Base: 1277 +Linked animations: [5401, 5402] +Linked graphics: 867, 868, 869, 876, 974 + +Base: 1278 +Linked animations: [5445, 5446, 5447, 5448, 5449, 5450, 5451, 7581, 7582, 7583, 7584, 7585, 7586] +Linked NPCs: Locust rider (5251), Locust rider (5252), Locust rider (5255), Locust rider (5256), Scabaras locust (6776), Locust lancer (6777), Locust ranger (6778) + +Base: 1279 +Linked animations: [5452, 5453, 5454, 5455, 5456, 5457, 5458, 7592, 7593, 7594, 7595, 7596, 7635, 11631, 11632, 11633, 11634, 11635] +Linked NPCs: Giant scarab (5253), Giant scarab (5292), Giant scarab (6770), Giant scarab (6771), Small scarab (7500), Small scarab (7501), Small scarab (7502), Small scarab (7503) + +Base: 1280 +Linked animations: [5459] +Linked graphics: 982 + +Base: 1281 +Linked animations: [5460] +Linked graphics: 984 + +Base: 1282 +Linked animations: [5461] +Linked graphics: 985 + +Base: 1283 +Linked animations: [5462] +Linked graphics: 986 + +Base: 1284 +Linked animations: [5465, 5466, 5467, 5468, 5469, 5470] +Linked graphics: 987, 988, 989, 990, 991, 992 + +Base: 1285 +Linked animations: [5463] +Linked graphics: 983 + +Base: 1286 +Linked animations: [1930, 1931, 1932, 1933, 5504, 5548, 5549, 5550, 5551, 5552, 5553, 5554, 5555, 5556, 5557, 5558, 5559, 5560, 5561, 5562, 5563, 9392, 12514, 12515, 12516, 12517, 12518] +Linked NPCs: Mummy (1958), Mummy (1959), Mummy ashes (1960), Mummy (1961), Mummy (1962), Mummy (1963), Mummy (1964), Mummy (1965), Mummy (1966), Mummy (1967), Mummy (1968), Mummy (2015), Mummy (2016), Mummy (2017), Mummy (2018), Mummy (2019), Guardian mummy (4476), Annoyed guardian mummy (4477), Mummy ashes (5360), Mummy (6753), Mummy (6754), Mummy (6755), Mummy (6756), Mummy (6757), Mummy (6758), Mummy (6759), Mummy (6760), Mummy warrior (7806), Mummy warrior (7807), Mummy warrior (7808), Mummy Champion (8988), Mummy Champion (8989), Mummy Champion (8992) + +Base: 1287 +Linked animations: [5564] +Linked objects: Mummy (20985), Mummy (20986), Mummy (31310) + +Base: 1288 +Linked animations: [5565, 5566, 5567, 5568, 5569, 5570, 5571, 5572, 5573, 5574, 5575, 5576, 5577, 5578, 5579, 5580, 5581, 5582, 5583, 5584, 5587, 5788, 5789, 5790, 5791, 5792, 5793, 6932, 9395, 10415, 10420, 10474, 14499, 14500, 14501, 14502, 14503, 14504, 14506, 14507, 14509] +Linked NPCs: Zombie (73), Zombie (74), Zombie (75), Zombie (76), Summoned Zombie (77), Undead one (504), Undead one (505), Nazastarool (507), Gravecreeper (532), Gravecreeper (533), Zombie (1826), Zombie (2714), Zombie protester (2831), Zombie protester (2832), Zombie protester (2833), Zombie protester (2834), Zombie protester (2835), Zombie protester (2836), Zombie Champion (3066), Zombie (3622), Zombie (4392), Zombie (4393), Zombie (4394), Zombie (5293), Zombie (5294), Zombie (5295), Zombie (5296), Zombie (5297), Zombie (5298), Zombie (5299), Zombie (5300), Zombie (5301), Zombie (5302), Zombie (5303), Zombie (5304), Zombie (5305), Zombie (5306), Zombie (5307), Zombie (5308), Zombie (5309), Zombie (5310), Zombie (5311), Zombie (5312), Zombie (5313), Zombie (5314), Zombie (5315), Zombie (5316), Zombie (5317), Zombie (5318), Zombie (5319), Zombie (5320), Zombie (5321), Zombie (5322), Zombie (5323), Zombie (5324), Zombie (5325), Zombie (5326), Zombie (5327), Zombie (5328), Zombie (5329), Zombie (5330), Zombie (5331), Undead one (5355), Undead one (5356), Undead one (5357), Undead one (5358), Zombie (5375), Zombie (5376), Zombie (5377), Zombie (5378), Zombie (5379), Zombie (5380), Zombie (5393), Zombie (5394), Zombie (5395), Zombie (5396), Zombie (5397), Zombie (5398), Zombie (5399), Zombie (5400), Zombie (5401), Zombie (5402), Zombie (5403), Zombie (5404), Zombie (5405), Zombie (5406), Zombie (5407), Zombie (5408), Zombie (5409), Zombie (5410), Zombie (6099), Zombie (6100), Dried zombie (6761), Dried zombie (6762), Dried zombie (6763), Zombie (7789), Zombie (7790), Zombie (7791), Zombie (7792), Zombie (7817), Zombie (7818), Zombie (7819), Zombie (7820), Zombie (8142), Zombie (8143), Zombie (8144), Zombie (8145), Armoured zombie (8149), Armoured zombie (8150), Armoured zombie (8151), Armoured zombie (8152), Armoured zombie (8153), Armoured zombie (8154), Armoured zombie (8155), Armoured zombie (8156), Armoured zombie (8157), Armoured zombie (8158), Armoured zombie (8159), Armoured zombie (8160), Armoured zombie (8161), Armoured zombie (8162), Armoured zombie (8163), Armoured zombie (8164), Armoured zombie (9162), Armoured zombie (9163), Armoured zombie (9165), Zombie (10364), Zombie (10365), Zombie (10366), Zombie (10367), Zombie (10368), Zombie (10369), Zombie (10370), Zombie (10371), Zombie (10372), Zombie (10373), Zombie (10374), Zombie (10375), Zombie (10376), Zombie (10377), Zombie (10378), Zombie (10379), Zombie (10380), Zombie (10381), Zombie (10382), Zombie (10383), Zombie (10384), Zombie (10385), Gravecreeper (11708), Gravecreeper (11709), Gravecreeper (11710), Gravecreeper (11711), Gravecreeper (11712), Gravecreeper (11713), Gravecreeper (11714), Gravecreeper (11715), Gravecreeper (11716), Gravecreeper (11717), Gravecreeper (11718), Gravecreeper (11719), Gravecreeper (11720) + +Base: 1289 +Linked animations: [5478, 5530, 5531, 5532, 5533, 5534, 5535, 5536, 5537, 5544, 5546, 5794, 5795, 7439, 7440, 7441, 7442, 7443, 7444, 7445, 7508, 7522, 11221] +Linked NPCs: Ghost (104), Spirit of Zadimus (501), Rashiliyia (506), Nazastarool (509), Tree spirit (655), Mischievous ghost (1551), Ghost (2716), null (2930), Ghost (2931), Ghost (4388), Ghost (5342), Ghost (5343), Ghost (5344), Ghost (5345), Ghost (5346), Ghost (5347), Ghost (5348), Ghost (5349), Ghost (5350), Ghost (5351), Ghost (5352), Ghost (5369), Ghost (5370), Ghost (5371), Ghost (5372), Ghost (5373), Ghost (5374), Ghost (6095), Ghost (6096), Ghost (6097), Ghost (6098), Revenant knight (6611), Revenant knight (6619), Revenant knight (6627), Revenant knight (6630), Revenant knight (6634), Revenant knight (6650), Revenant knight (6654), Revenant knight (6665), Revenant knight (6673), Revenant knight (6676), Revenant knight (6692), Revenant knight (6714), Revenant knight (6726), Revenant knight (6730), Ghost (7998), Ghost (7999), Tormented wraith (8125), Ghost (8623), Spectral tender (9451), Spectral cultivator (9452), Spectral worshipper (9453), Spectral attendant (9454), Ghost (10822), Ghost (10823), Ghost (10824), Ghost (10825), Ghost (10826), Ghost (10827), Ghost (10828), Ghost (10830) +Linked graphics: 1997 + +Base: 1290 +Linked animations: [1437, 1438, 1439, 4647, 5538, 5539, 5540, 5541, 5542, 5543, 5545, 5547, 9028, 13395, 13396, 13397, 13398, 13405, 13406, 13407] +Linked NPCs: Ghost (103), Thrantax the Mighty (238), Ghost (491), Spirit of Scorpius (492), Echned Zekin (940), Haze (1537), Treus Dayth (1540), Ghost (1541), Ghost (1549), null (2013), Klenter (2014), Ghost (4387), Ghost (6094), Spectral Vyrewatch (7687), null (9721), Ghost (10821), Ghost (10829), Mysterious shade (10831), Mysterious shade (10832), Mysterious shade (10833), Mysterious shade (10834), Mysterious shade (10835), Mysterious shade (10836), Mysterious shade (10837), Mysterious shade (10838), Mysterious shade (10839), Mysterious shade (10840), Mysterious shade (10841), Mysterious shade (10842), Ghost (10981), Ghost (10982), Ghost (10983), Ghost (10984), Ghost (10985), Ghost (10986), Ghost (10987), Ghost (10988), Ghost (10989), Ghost (10990), Ghost (10991), Ghost (10992), Ghost (10993), Ghost (10994), Ghost (10995), Ghost (10996), Ghost (10997), Ghost (10998), Ghost (10999), Ghost (11000) + +Base: 1291 +Linked animations: [259, 1442, 1443, 1444, 3994, 4017, 5479, 5481, 5483, 5485, 5487, 5489, 5491, 5493, 5495, 5497, 5499, 5501, 5503, 5505, 5506, 5507, 5508, 5509, 5510, 5511, 5512, 5513, 5514, 5517, 5518, 5519, 5520, 5521, 5522, 5523, 5527, 5528, 9398, 9402, 9407, 10943, 10949, 10950, 11636, 11637, 12632, 13462, 13463, 13464, 14549] +Linked NPCs: Skeleton (90), Skeleton (91), Skeleton (92), Skeleton (93), Skeleton Mage (94), Undead one (502), Undead one (503), Nazastarool (508), San Tojalon (936), Irvig Senay (937), Ranalph Devere (938), Skeleton (1471), Corpse (1538), Skeletal miner (1539), Giant skeleton (1973), Skeleton (2036), Skeleton (2037), Skeleton (2715), Skeleton mage (2717), Skeleton Champion (3065), Skeleton (3151), Skeleton (3291), Skeleton (3581), Skeleton Mage (3844), Skeleton Mage (3851), Skeleton (4384), Skeleton (4385), Skeleton (4386), Skeleton (5332), Skeleton (5333), Skeleton (5334), Skeleton (5335), Skeleton (5336), Skeleton (5337), Skeleton (5338), Skeleton (5339), Skeleton (5340), Skeleton (5341), Undead one (5353), Undead one (5354), Giant skeleton (5359), Skeleton (5365), Skeleton (5366), Skeleton (5367), Skeleton (5368), Skeleton (5381), Giant skeleton (5384), Skeleton (5385), Skeleton (5386), Skeleton (5387), Skeleton (5388), Skeleton (5389), Skeleton (5390), Skeleton (5391), Skeleton (5392), Skeleton (5411), Skeleton (5412), Skeleton (5422), Skeleton (6091), Skeleton (6092), Skeleton (6093), Skeleton (6764), Skeleton (6765), Skeleton (6766), Skeleton (6767), Skeleton (6768), Skeleton looter (7481), Skeleton looter (7482), Skeleton looter (7483), Skeleton looter (7484), Skeleton looter (7485), Skeleton looter (7486), Skeleton looter (7487), Skeleton looter (7488), Skeleton looter (7489), Skeleton looter (7490), Skeleton looter (7491), Skeleton (7774), Skeleton (7775), Skeleton (7776), Skeleton (7777), Skeleton (7778), Skeleton (7788), Skeleton (7815), Undead mage (8486), Giant skeleton (10469), Giant skeleton (10470), Giant skeleton (10471), Giant skeleton (10472), Giant skeleton (10473), Giant skeleton (10474), Giant skeleton (10475), Giant skeleton (10476), Giant skeleton (10477), Giant skeleton (10478), Giant skeleton (10479), Skeleton (10629), Skeleton (10630), Skeleton (10631), Skeleton (10632), Skeleton (10633), Skeleton (10634), Skeleton (10635), Skeleton (10636), Skeleton (10637), Skeleton (10638), Skeleton (10639), Skeleton (10640), Skeleton (10641), Skeleton (10642), Skeleton (10643), Skeleton (10644), Skeleton (10645), Skeleton (10646), Skeleton (10647), Skeleton (10648), Skeleton (10649), Skeleton (10650), Skeleton (10651), Skeleton (10652), Skeleton (10653), Skeleton (10654), Skeleton (10655), Skeleton (10656), Skeleton (10657), Skeleton (10658), Skeleton (10659), Skeleton (10660), Skeleton (10661), Skeleton (10662), Skeleton (10663), Skeleton (10664), Skeleton (10665), Skeleton (10666), Skeleton (10667), Skeleton (10668), Skeleton (10669), Skeleton (10670), Skeleton (10671), Skeleton (10672), Skeleton (10673), Skeleton (10674), Skeleton (10675), Skeleton (10676), Skeleton (10677), Skeleton (10678), Skeleton (10679), Skeleton (10680), Skeleton (10681), Skeleton (10682), Skeleton (10683), Skeleton (10684), Skeleton (10685), Skeleton (10686), Skeleton (10687), Skeleton (10688), Skeleton (10689), Skeleton (10690), Skeleton (10691), Skeleton (10692), Skeleton (10693), Skeletal minion (11722), Skeletal minion (11723), Skeletal minion (11724), Skeletal minion (11725), Skeletal minion (11726), Skeletal minion (11727), Skeletal minion (11728), Skeletal minion (11729), Skeletal minion (11730), Skeletal minion (11731), Skeletal minion (11732), Skeletal minion (11733), Skeletal minion (11734), Skeletal minion (11735), Skeletal minion (11736) +Linked objects: Bones (13366) + +Base: 1292 +Linked animations: [5515, 5516] +Linked graphics: 994, 995 + +Base: 1293 +Linked animations: [5526] +Linked graphics: 996, 997 + +Base: 1294 +Linked animations: [5603, 5604, 9405, 9406] +Linked objects: Armour (20453), Skeleton (20455), Skeleton (20457), null (20972), null (20973), null (20974), null (20975), null (20976), Skeleton (31312), Skeleton (31313) + +Base: 1295 +Linked animations: [5599, 5600, 5601] +Linked objects: Passageway (20468), Passageway (20469), Bars (20532), Bars (20533), Bars (20534) + +Base: 1296 +Linked animations: [5605] +Linked objects: null (20580), null (20660), null (20725), null (20790) + +Base: 1297 +Linked animations: [5588] + +Base: 1298 +Linked animations: [5631] +Linked objects: Wall (20942), Wall (20943), Wall (20946), Wall (20947), Wall (20950), Wall (20951), Wall (20954), Wall (20955) + +Base: 1299 +Linked animations: [5612, 5613, 5615, 5616, 5617, 5618, 5619] +Linked NPCs: Mutant tarn (5421) +Linked graphics: 1004 + +Base: 1300 +Linked animations: [5589, 5590, 5591, 5592, 5593, 5594, 5595, 5596, 5597] +Linked NPCs: Possessed pickaxe (5413), Animated spade (5414) + +Base: 1301 +Linked animations: [5621, 5622, 5623, 5624, 5625, 5626, 5627, 5628, 5629] +Linked NPCs: Terror dog (5417), Terror dog (5418), Terror dog (11365) + +Base: 1302 +Linked animations: [5610, 5614, 5660, 7661] +Linked graphics: 1002, 1003, 1013, 1316 + +Base: 1303 +Linked animations: [5630] +Linked graphics: 1005 + +Base: 1304 +Linked animations: [2715, 5585, 5586, 5641, 5642, 5643, 5644, 5645, 5646, 5647, 5648, 5649, 5650, 5651, 5652, 5653, 5654, 5655, 5656, 5657, 5658, 5875, 5876, 5877, 5878, 5879, 5880, 5881, 5882, 5883, 5884, 5885, 5886, 5887, 5888, 5889, 5890, 5891, 7389, 7390, 9560] +Linked NPCs: 50% Luke (2828), Captain Donnie (2830), Zombie pirate (2837), Zombie pirate (2838), Zombie pirate (2839), Zombie pirate (2840), Zombie pirate (2841), Zombie pirate (2842), Zombie swab (2843), Zombie swab (2844), Zombie swab (2845), Zombie swab (2846), Zombie swab (2847), Zombie swab (2848), Monk (5608), Monk (5609), Monk (5610), Monk (5611), Brother Tranquility (5616), Brother Tranquility (5617), Brother Tranquility (5618), Monk (5619), Monk (5620), Monk (5621), Monk (5622), Zombie monk (5623), Zombie monk (5624), Zombie monk (5625), Zombie monk (5626), Sorebones (5627), Sorebones (5628), Zombie pirate (5629), Zombie pirate (5630), Zombie pirate (5631), Zombie pirate (5632), Zombie pirate (5633), Zombie pirate (5634), Zombie pirate (5635), Zombie pirate (5636), Zombie pirate (5637), Zombie pirate (5638), Zombie pirate (5639), Zombie pirate (5640), Zombie pirate (5641), Zombie pirate (5642), Zombie pirate (5643), Zombie pirate (5644), Zombie pirate (5645), Zombie pirate (5646), Zombie pirate (5647), Zombie pirate (5648), Zombie pirate (5649), Zombie pirate (5650), Zombie pirate (5651), Zombie pirate (5652), Zombie pirate (5653), Zombie pirate (5654), Zombie pirate (5655), Zombie pirate (5656), Zombie pirate (5657), Zombie pirate (5658), Zombie pirate (5659), Zombie pirate (5660), Zombie pirate (5661), Zombie pirate (5662), Zombie pirate (5663), Zombie pirate (5664), Zombie pirate (5665), null (5667), null (5668), null (5669), null (5670), null (5671), null (5672), null (5673), null (5674), null (5675), null (5676), null (5677), null (6537), Mandrith (8725) + +Base: 1305 +Linked animations: [5638, 5639, 5640, 6097, 9120] +Linked graphics: 1009, 1010, 1011, 1037, 1604 + +Base: 1306 +Linked animations: [5634, 5635, 5636] +Linked graphics: 999, 1000, 1001, 1006, 1007, 1008 + +Base: 1307 +Linked animations: [3329, 5598, 6653] +Linked objects: Candlestick (2146), null (20256), null (20262), null (20537), null (20538), null (20621), null (20622), null (20686), null (20687), null (20751), null (20752), Flames (25201), null (25659), Torch (26195), Grave (27283), Grave (27284), Grave (27285), Grave (27286), Grave (27287), Grave (27288), Torch (27891), Druid's Circle torch (28699), Flames (28848), Oil lamp (29132), Oil lamp (29133), null (29302), null (30240), null (30395), Torch (30569), null (30642), Flames (30934), null (30940), Fire (37597), null (38223), Flames (38267), null (38371), null (39220), Torch (39763), null (40454), null (40568), null (41356), null (41357), null (41358), null (42491), null (42677), null (42678), null (42720), null (44087), null (49192), null (49193), null (49238), null (53572), null (55200) + +Base: 1308 +Linked animations: [5659] +Linked graphics: 1012 + +Base: 1309 +Linked animations: [5661, 5662, 5663, 5665] + +Base: 1310 +Linked animations: [4139, 4140, 5666, 5667, 5668, 5669, 5670, 5671, 5672, 5673, 5674, 5675, 5676, 5677, 5678, 5680, 5681, 5682, 5684, 5685, 5688, 5689, 5690, 5691, 5692, 5693, 5694, 5695, 5696, 5697, 5698, 5699, 5700, 5701, 5702, 5703, 5704, 5705, 5706, 5707, 5708, 5709, 5710, 5715, 5717, 6438, 6439, 8314, 8315, 8316, 8317, 8318, 8319, 11730, 11742, 11743, 11744, 11745, 11746, 11747, 11748, 11750, 11751, 11752, 11753, 11754, 11755, 11756, 11757, 11758, 11779, 11780, 11781] +Linked NPCs: Penguin (131), Macaroni Penguin (4252), null (5427), Penguin (5428), Penguin (5429), Penguin (5430), KGP Guard (5431), Pescaling Pax (5432), Ping (5433), Ping (5434), Pong (5435), Pong (5436), Ping (5437), Pong (5438), KGP Agent (5441), null (5443), Noodle (5444), Penguin (5445), Penguin suit (5446), Agility Instructor (5447), Army Commander (5448), Penguin (5449), Penguin (5450), Penguin (5451), Penguin display (5976), Baby penguin (6908), Penguin (6909), Penguin (6910), Baby penguin (7313), Penguin (7314), Penguin (7315), Baby penguin (7316), Penguin (7317), Penguin (7318), KGP Interrogator (7582), Captain Marlin (7583), Captain Marlin (7584), Office penguin (7585), Office penguin (7586), Office penguin (7587), Office penguin (7588), Office penguin (7589), Office penguin (7590), Office penguin (7591), Office penguin (7592), Trainee KGP agent (7593), null (7594), KGP agent (7595), Penguin suit (7596), Penguin suit (7597), Penguin suit (7598), Penguin suit (7599), Penguin (7841), Penguin (7894), Penguin (7895), Penguin (7896), Penguin (7897), Penguin (8094), Penguin (8095), Penguin (8096), Penguin (8097), Penguin (8098), Penguin (8099), Penguin (8100), Penguin (8101), Penguin (8102), Penguin (8103), Penguin (8663), Penguin (8664), Penguin (8665), Penguin (8666), Penguin (8667), Penguin (8668), Penguin (8669), Penguin (8670), Penguin (8671), null (8672), null (8673), Penguin (8688), Penguin (8689), Penguin (8690), Penguin (8691), Penguin (8692), null (8696), KGP Agent (8697), Penguin (8882), Penguin (8883), Penguin (8884), Penguin (8886), Penguin (8887), Penguin (8888), Penguin (8889), Penguin (8891), Penguin (8892), Penguin (8893), Penguin (9233), Penguin (9234), Penguin (9235) +Linked graphics: 1015, 1016, 2050 +Linked objects: null (24570) + +Base: 1311 +Linked animations: [5741] +Linked objects: null (21146) + +Base: 1312 +Linked animations: [5739] +Linked objects: null (21108), null (21109) + +Base: 1313 +Linked animations: [5734] +Linked objects: Ice (21148), Ice (21149), Ice (21150), Ice (21151), Ice (21152), Ice (21153), Ice (21154), Ice (21155), Ice (21156) + +Base: 1314 +Linked animations: [5729] +Linked objects: null (21091), Crazy penguin (21094) + +Base: 1315 +Linked animations: [5728, 9577, 9581] +Linked objects: null (21089), Crazy penguin (21092), Cannon (31681) + +Base: 1316 +Linked animations: [5730] +Linked objects: null (21090), Crazy penguin (21093) + +Base: 1317 +Linked animations: [5735, 5736] + +Base: 1318 +Linked animations: [5740, 11724] +Linked objects: Captured penguin (43394), Captured penguin (43395), Captured penguin (43396), Captured penguin (43397), Interrogation chair (43398) + +Base: 1319 +Linked animations: [5737] +Linked objects: Steam generator (21002) + +Base: 1320 +Linked animations: [5731, 5733] + +Base: 1321 +Linked animations: [5738] +Linked objects: Spinning light (21085), Spinning light (43169), Spinning light (43170) + +Base: 1322 +Linked animations: [5742] +Linked objects: Table (20996) + +Base: 1323 +Linked animations: [5721, 5722, 5723, 5724, 5725, 5726] +Linked NPCs: Icelord (5452), Icelord (5453), Icelord (5454), Icelord (5455) + +Base: 1324 +Linked animations: [5712] +Linked graphics: 1014 + +Base: 1325 +Linked animations: [5727] +Linked graphics: 1017 + +Base: 1326 + +Base: 1327 +Linked animations: [5747] +Linked graphics: 1018 + +Base: 1328 +Linked animations: [5743] +Linked objects: Drill (23962) + +Base: 1329 +Linked animations: [5744] +Linked objects: Lathe (23961) + +Base: 1330 +Linked animations: [5745, 8735] +Linked objects: null (21003), Smoke (22733), Smoke (22975), null (29535), null (40156) + +Base: 1331 + +Base: 1332 +Linked animations: [5768] +Linked objects: Banner (21500), Banner (21501) + +Base: 1333 +Linked animations: [5771, 5772, 11485] +Linked objects: Large Geyser (21355), Small Geyser (21356), Large geyser (26414), null (30067) + +Base: 1334 +Linked animations: [5773, 5774] +Linked NPCs: Arctic Pine (5469) +Linked objects: Arctic Pine (21273), null (28238), null (28240), null (28243), null (28245), null (28248), null (28250), Tree (39430) + +Base: 1335 +Linked animations: [5758] +Linked graphics: 1020 + +Base: 1336 +Linked animations: [5757] +Linked graphics: 1021 + +Base: 1337 +Linked animations: [5780] +Linked graphics: 1022 + +Base: 1338 +Linked animations: [1735, 5781, 5782, 5783, 5784, 5785, 5786, 5787, 5848, 5849, 5850, 5851, 5852, 5854, 5855, 5856, 8056, 8058, 8059, 8536, 12827] +Linked NPCs: Cow (81), Cow (397), Cow (955), Undead cow (1691), Cow calf (1766), Cow (1767), Cow calf (1768), Plague cow (1998), Plague cow (1999), Plague cow (2000), Cow calf (2310), Cow (3309), Undead cow (5211), Yak (5529), Unicow (5603), Pack yak (6873), Pack yak (6874), Pack yak (9491), Rogue pack yak (9603), Rogue pack yak (9604), Rogue pack yak (9605), Rogue pack yak (9606) +Linked objects: Dairy cow (8689), Dairy Cow (12111), Prized dairy cow (47721) + +Base: 1339 +Linked animations: [5797] +Linked objects: Fountain (21764) + +Base: 1340 +Linked animations: [5801, 5802, 5803] +Linked NPCs: Autumn Elemental (5533), Autumn Elemental (5534), Autumn Elemental (5535), Autumn Elemental (5536), Autumn Elemental (5537), Autumn Elemental (5538), Spring Elemental (5539), Spring Elemental (5540), Spring Elemental (5541), Spring Elemental (5542), Spring Elemental (5543), Spring Elemental (5544), Spring Elemental (5545), Spring Elemental (5546), Summer Elemental (5547), Summer Elemental (5548), Summer Elemental (5549), Summer Elemental (5550), Summer Elemental (5551), Summer Elemental (5552), Winter Elemental (5553), Winter Elemental (5554), Winter Elemental (5555), Winter Elemental (5556), Winter Elemental (5557), Winter Elemental (5558) + +Base: 1341 +Linked animations: [5798] +Linked objects: Fireplace (21795) + +Base: 1342 + +Base: 1343 +Linked animations: [5811] +Linked graphics: 1024 + +Base: 1344 +Linked animations: [5813] + +Base: 1345 +Linked animations: [5844] +Linked objects: Symbol of life (21893), Symbol of life (21894) + +Base: 1346 +Linked animations: [5830] +Linked objects: null (21852), null (21856), null (21860), null (21864) + +Base: 1347 +Linked animations: [5847] +Linked objects: Cage (21930), Cage (21931) + +Base: 1348 +Linked animations: [5829] +Linked objects: Water pipes (21844), Water pipes (21846) + +Base: 1349 +Linked animations: [5825] +Linked objects: Spinning pipe (21920) + +Base: 1350 +Linked animations: [5824] +Linked objects: Magic table (21918) + +Base: 1351 +Linked animations: [5828] +Linked objects: null (21832) + +Base: 1352 +Linked animations: [5820] +Linked graphics: 1025 + +Base: 1353 +Linked animations: [5835] +Linked graphics: 1026 + +Base: 1354 +Linked animations: [5839, 5840, 5841, 5842, 5843] +Linked NPCs: Frogeel (5593) + +Base: 1355 +Linked animations: [5831, 5832, 5833, 5834] +Linked NPCs: Homunculus (5581), Homunculus (5582), Homunculus (5583), null (5599), null (5600) + +Base: 1356 +Linked animations: [5836, 5837, 5838] + +Base: 1357 +Linked animations: [5892, 5893, 5894, 5895, 5896, 5897, 5898] +Linked NPCs: Barrelchest (5666) + +Base: 1358 +Linked animations: [5858, 5859] +Linked NPCs: Mi-Gor (5613) + +Base: 1359 +Linked animations: [5872, 5873] +Linked NPCs: Puffin (5614), Puffin (5615) + +Base: 1360 +Linked animations: [5857] +Linked objects: Sails (22418) + +Base: 1361 +Linked animations: [5861] + +Base: 1362 +Linked animations: [5909] +Linked objects: Fuse (22484) + +Base: 1363 +Linked animations: [5905, 5906] +Linked objects: Stand (22123), Stand (22124), Candle stand (22125), Stand (36982), Stand (36983) + +Base: 1364 +Linked animations: [5900, 5901] +Linked objects: Wall (22105), Wall (22106), Wall (22107), Wall (22108), Collapsed wall (22109), Collapsed wall (22110) + +Base: 1365 +Linked animations: [5902] + +Base: 1366 +Linked animations: [5903, 5904] + +Base: 1367 +Linked animations: [5874] +Linked objects: null (22338), null (22339), null (42887), null (42889) + +Base: 1368 +Linked animations: [5908] + +Base: 1369 +Linked animations: [5871] +Linked graphics: 1027 + +Base: 1370 +Linked animations: [5899] +Linked graphics: 1028 + +Base: 1371 +Linked animations: [5974, 5975, 5976, 5977, 5978, 5979, 5980, 5981, 5982, 5983, 5984, 5985] +Linked objects: Marv (sick) (22497), Marv (very sick) (22498), Marv (ghastly!) (22499), Marv (sick) (22500), Marv (very sick) (22501), Marv (ghastly!) (22502), Marv (Well) (22503), Hank (sick) (22504), Hank (very sick) (22505), Hank (ghastly!) (22506), Hank (sick) (22507), Hank (very sick) (22508), Hank (ghastly!) (22509), Hank (Well) (22510), Wilf (sick) (22511), Wilf (very sick) (22512), Wilf (ghastly!) (22513), Wilf (sick) (22514), Wilf (very sick) (22515), Wilf (ghastly!) (22516), Wilf (Well) (22517), Sarah (sick!) (22518), Sarah (very sick!) (22519), Sarah (ghastly!) (22520), Sarah (sick!) (22521), Sarah (very sick!) (22522), Sarah (ghastly!) (22523), Sarah (Well) (22524), Rachel (sick) (22525), Rachel (very sick) (22526), Rachel (ghastly!) (22527), Rachel (sick) (22528), Rachel (very sick) (22529), Rachel (ghastly!) (22530), Rachel (Well) (22531) + +Base: 1372 +Linked animations: [5986, 5987, 5988, 5989, 5990, 8043, 8044, 8045, 8933] +Linked NPCs: Nail beast (1521), Nail beast (1522), Nail beast (1523), Talon beast (7347), Talon beast (7348) + +Base: 1373 +Linked animations: [5965, 5966, 5967, 5968, 5969, 5970, 5971, 5972, 5973] +Linked NPCs: Undead Lumberjack (1524), Undead Lumberjack (1525), Undead Lumberjack (5678), Undead Lumberjack (5679), Undead Lumberjack (5680), Undead Lumberjack (5681), Undead Lumberjack (5682), Undead Lumberjack (5683), Undead Lumberjack (5684), Undead Lumberjack (5685), Undead Lumberjack (5686), Undead Lumberjack (5687), Undead Lumberjack (5688), Undead Lumberjack (5689), Undead Lumberjack (5690), Undead Lumberjack (5691), Undead Lumberjack (5692), Undead Lumberjack (5693), Undead Lumberjack (5694), Undead Lumberjack (5695), Undead Lumberjack (5696), Undead Lumberjack (5697), Undead Lumberjack (5698), Undead Lumberjack (5699), Undead Lumberjack (5700), Undead Lumberjack (5701), Undead Lumberjack (5702), Undead Lumberjack (5703), Undead Lumberjack (5704), Undead Lumberjack (5705), Undead Lumberjack (5706), Undead Lumberjack (5707), Undead Lumberjack (5708), Undead Lumberjack (5709), Undead Lumberjack (5710), Undead Lumberjack (5711), Undead Lumberjack (5712), Undead Lumberjack (5713), Undead Lumberjack (5714), Undead Lumberjack (5715), Undead Lumberjack (5716), Undead Lumberjack (5717), Undead Lumberjack (5718), Undead Lumberjack (5719), Undead Lumberjack (5720), Undead Lumberjack (5721), Undead Lumberjack (5722), Undead Lumberjack (5723), Undead Lumberjack (5724), Undead Lumberjack (5725), Undead Lumberjack (5726), Undead Lumberjack (5727), Undead Lumberjack (5728), Undead Lumberjack (5729), Undead Lumberjack (5730), Undead Lumberjack (5731), Undead Lumberjack (5732), Undead Lumberjack (5733), Undead Lumberjack (5734), Undead Lumberjack (5735), Undead Lumberjack (5736), Undead Lumberjack (5737), Undead Lumberjack (5738), Undead Lumberjack (5739), Undead Lumberjack (5740), Undead Lumberjack (5741), Undead Lumberjack (5742), Undead Lumberjack (5743), Undead Lumberjack (5744), Undead Lumberjack (5745), Undead Lumberjack (5746), Undead Lumberjack (5747) + +Base: 1374 +Linked animations: [6069, 6070, 6071, 6072, 6073] +Linked objects: Pylon (22663), Pillar (26302), Tree (26724) + +Base: 1375 +Linked animations: [6023] +Linked objects: Sinclair family fountain (2654), Fountain (22973), Fountain (24161), Fountain (28662), Fountain (30223), Fountain (30820), Fountain (34579), Fountain of Heroes (36695), Fountain (36781), Fountain (41448) + +Base: 1376 +Linked animations: [6039] +Linked objects: Frog spit (22974) + +Base: 1377 +Linked animations: [6037] +Linked objects: Sink (22715) + +Base: 1378 +Linked animations: [6029, 6030, 6031, 6032] +Linked objects: Lamp (22760), Lamp (22761), Lamp (22762), Empty lamp (22763), Lamp (22764), Lamp (22976), Broken lamp (22977), null (22978), null (22979), null (22980), null (22981), null (22982), null (22983), null (22984), null (22985), null (22986), null (22987), null (22988), null (22989), null (22990), null (22991), null (22992), null (22993), null (22994), null (22995), null (22996), null (22997), null (22998), null (22999), null (23000), null (23001), null (23002), null (23003), null (23004), null (23005), null (23006), null (23007), null (23008), null (23009), null (23010), null (23011), null (23012), null (23013), null (23014), null (23015), null (23016), null (23017), null (23018), null (23019), null (23020), null (23021), null (23022), null (23023), null (23024), null (23025), null (23026), null (23027), null (23028), null (23029), null (23030), null (23031), null (23032), null (23033), null (23034), null (23035), null (23036), null (23037), null (23038), null (23039), null (23040), null (23041) + +Base: 1379 +Linked animations: [6033, 6034, 6035, 6036] +Linked NPCs: Moths (5827) +Linked objects: Moths (22734), Zapper (22735), Zapper (22736), Zapper (22737) + +Base: 1380 +Linked animations: [6027] +Linked objects: Thingymajig (22823) + +Base: 1381 +Linked animations: [6028] +Linked objects: Magic ball (22826) + +Base: 1382 +Linked animations: [6038] +Linked objects: Chimney (22727), Wire machine (22728), Wire machine (22729), Wire (22730), Cogs (22732) + +Base: 1383 +Linked animations: [2308, 2402, 2405, 2406, 2407, 2408, 2412, 2768, 3183, 4201, 4202, 4203, 4204, 4205, 4206, 5750, 5751, 5991, 5992, 5993, 5994, 5995, 5996, 5997, 5998, 5999, 6000, 6001, 6002, 6003, 6004, 6005, 6006, 6007, 6008, 6040, 6041, 6042, 6043, 6044, 6045, 6046, 6047, 6048, 6049, 6050, 6051, 6052, 6053, 6054, 6055, 6060, 6084, 6107, 6149, 6159, 6194, 6210, 6212, 6214, 6215, 6359, 6360, 7312, 7313, 7314, 7322, 7328, 7329, 10940, 10941, 11225, 11226, 11259, 11260, 11261, 11262, 11263, 11264, 11265, 11266, 11267, 11268, 11269, 11270, 11271, 11272, 11273, 11274, 11288, 11289, 11290, 11291, 11299, 11304, 11306, 11307, 11308, 11327, 11328, 11329, 11330, 11331, 11332, 11341, 11362, 11363, 11364, 11365, 11367, 11368, 11378, 11381, 11386, 11390, 11391, 11392, 11393] +Linked NPCs: Captain Undak (422), null (423), null (424), null (425), Captain Undak (426), Captain Undak (427), Captain Undak (428), Captain Undak (429), Captain Undak (430), Torzek (438), null (439), Andil (440), null (441), Delgon (442), null (443), Gerdi (1719), null (1720), Jobo (1721), null (1722), Andil (1723), Delgon (1724), Gerdi (1725), Jobo (1726), Torzek (1727), null (1728), Oldak (1729), Goblin scribe (1749), Cave goblin (1822), Cave goblin (1823), Cave goblin (1824), Cave goblin (1825), Cave goblin miner (2069), Cave goblin miner (2070), Cave goblin miner (2071), Cave goblin miner (2072), Cave goblin guard (2073), Cave goblin guard (2074), Cave goblin miner (2075), Cave goblin miner (2076), Cave goblin miner (2077), Cave goblin miner (2078), Mistag (2084), null (2085), Kazgar (2086), Ur-tag (2087), Mistag (2089), Zanik (2542), Zanik (2543), Zanik (2544), null (2545), Zanik (2546), Zanik (2723), Zanik (3117), Zanik (3206), Zanik (3207), Zanik (3353), Zanik (3354), Zanik (3355), Zanik (3359), Zanik (3360), Zanik (3361), Zanik (3362), null (3363), Zanik (3364), Zanik (3365), Zanik (3366), Zanik (3367), Zanik (3369), Zanik (3370), Zanik (3371), Zanik (3712), Zanik (3714), Zanik (3721), Zanik (3722), null (4313), Dartog (4314), Zanik (4322), Zanik (4323), Zanik (4324), Zanik (4326), Zanik (4337), null (4338), Zanik (4339), Zanik (4340), Zanik (4341), Zanik (4342), Cave goblin (5752), Cave goblin (5753), Cave goblin (5754), Cave goblin (5755), Cave goblin (5756), Cave goblin (5757), Cave goblin (5758), Cave goblin (5759), Cave goblin (5760), Cave goblin (5761), Cave goblin (5762), Cave goblin (5763), Cave goblin (5764), Cave goblin (5765), Cave goblin (5766), Cave goblin (5767), Cave goblin (5768), Cave goblin (5769), Ur-zek (5770), Ur-vass (5771), Ur-taal (5772), Ur-meg (5773), Ur-lun (5774), Ur-pel (5775), Banker (5776), Banker (5777), Bartak (5778), Turgall (5779), Reldak (5780), Miltog (5781), Mernik (5782), Cave goblin (5783), Crate goblin (5784), Cave goblin (5785), Goblin scribe (5786), null (5787), Gourmet (5788), Gourmet (5789), Gourmet (5790), Gourmet (5791), Turgok (5792), Markog (5793), Durgok (5794), Tindar (5795), Gundik (5796), Zenkog (5797), Lurgon (5798), Ur-tag (5799), Guard (5800), Guard (5801), null (5802), Bozin (5807), Bozin (5808), Fandon (5809), Fandon (5810), Horgon (5811), Horgon (5812), Lorzan (5813), Lorzan (5814), Caldi (5815), Caldi (5816), Elzik (5817), Elzik (5818), Inglin (5819), Inglin (5820), Kenti (5821), Kenti (5822), Spit goblin (5823), Barlak (5828), Zanik (5857), Ur-tag (5858), Zanik (5861), Tegdak (5868), null (5869), Zanik (5870), Cave goblin (5873), Cave goblin (5874), Cave goblin (5875), Cave goblin (5876), Cave goblin (5877), Cave goblin (5878), Ticket goblin (5879), null (5888), Oldak (6392), Zanik (6393), null (6394), Zanik (6395), null (6396), Zanik (6397), null (6398), Zanik (6399), null (6400), Oldak (6401), Cave goblin (8451), null (8473), null (8651), null (8652), null (8653), null (8654), null (8655) +Linked graphics: 478 +Linked objects: Cave goblin (21257), Cave goblin (21258), Cave goblin (21259), Cave goblin (21260), Cave goblin (21261), Cave goblin (21262), Cave goblin (21263), Cave goblin (21264), Cave goblin (21265), Cave goblin (21266), Cave goblin (21267), Cave goblin (21268), Cave goblin (21269), Cave goblin (21270), Cave goblin (23551), Cave goblin (23552), Cave goblin (23554), Cave goblin (23555), Cave goblin (23556), Cave goblin (23557), Cave goblin (23558), Cave goblin (23559), Cave goblin (23560), Cave goblin (23561), Cave goblin (23562), Cave goblin (23563), Cave goblin (23564), Cave goblin (23565), Cave goblin (23566), Cave goblin (23567), Cave goblin (23568), Cave goblin (23569), Cave goblin (23570), Cave goblin (23571), Cave goblin (25590), Cave goblin (26191), Cave goblin (26884), Cave goblin (26888), Cave goblin (29194), Cave goblin (29195), Cave goblin (29196), Cave goblin (29197), Cave goblin (29198), Cave goblin (29199), Cave goblin (29200), Cave goblin (29201), Cave goblin (29202), Cave goblin (29203), Cave goblin (29204), Cave goblin (29205), Cave goblin (29206), Cave goblin (29207), Cave goblin (29208), Cave goblin (29209), Cave goblin (29210), Cave goblin (29211), Cave goblin (29212), Cave goblin (29213), Cave goblin (29214), Cave goblin (31094), Cave goblin (31095), Cave goblin (31096), Cave goblin (31097), Cave goblin (31098), Cave goblin (31099), Cave goblin (31100), Cave goblin (31101), Cave goblin (31102), Cave goblin (31103), Cave goblin (31104), Cave goblin (31105), Cave goblin (31106), Cave goblin (31107), Cave goblin (31108), Cave goblin (31109), Cave goblin (31110), Cave goblin (31111), Cave goblin (31112), Cave goblin (31113), Cave goblin (31114), Cave goblin (31115), Cave goblin (31116), Cave goblin (31117), Cave goblin (31118), Cave goblin (31197), Cave goblin (31198), Cave goblin (31199), Cave goblin (31200), Cave goblin (31201), Cave goblin (31202), Cave goblin (31203), Cave goblin (31204), Cave goblin (31205), Cave goblin (36713), Cave goblin (42372), Cave goblin (42373), Cave goblin (42374), Cave goblin (42375), Cave goblin (42376), Cave goblin (42377), Cave goblin (42378), Cave goblin (42379), Cave goblin (42380), Cave goblin (42381), Cave goblin (42382), Cave goblin (42383), Cave goblin (42384), Cave goblin (42385), Cave goblin (42386), Cave goblin (42387), Cave goblin (42388), Cave goblin (42389), Cave goblin (42390), Cave goblin (42391), Cave goblin (42392), Cave goblin (42393) + +Base: 1384 +Linked animations: [6057, 6058, 6059] +Linked NPCs: Young 'un (5803), Tyke (5804), Nipper (5805), Nipper (5806) + +Base: 1385 +Linked animations: [6061, 6062] +Linked NPCs: Goblin fish (5824) + +Base: 1386 +Linked animations: [6065, 11382, 11383] +Linked graphics: 1034, 2003, 2004 + +Base: 1387 +Linked animations: [6056] +Linked graphics: 1035 + +Base: 1388 +Linked animations: [6025] +Linked objects: null (22875) + +Base: 1389 +Linked animations: [6024] +Linked objects: null (22862), null (22863), Water (22864), Water (22865), null (32963) + +Base: 1390 +Linked animations: [6026] +Linked objects: Stairs (22943) + +Base: 1391 +Linked animations: [6009] +Linked graphics: 1029 + +Base: 1392 +Linked animations: [6010, 6011, 6012, 6013, 6014, 6015, 6016, 6017, 6018, 6019, 6020, 6021, 6022] +Linked NPCs: Molanisk (5751) +Linked graphics: 1030, 1031, 1032, 1033 +Linked objects: Molanisk (22545) + +Base: 1393 +Linked animations: [6077, 6078, 6079, 6080, 6081, 6082] +Linked NPCs: Cave bug (1832), Cave bug (5750) + +Base: 1394 +Linked animations: [4219, 4220] +Linked objects: Zanik (15709), null (15710) + +Base: 1395 +Linked animations: [1828, 1829, 3847, 3848, 3849, 3854, 3856, 6088, 6089, 6090, 6091, 6092, 6093, 8717, 8718, 8734, 8737, 8738, 8739, 8740] +Linked NPCs: Rabbit (1192), Rabbit (1193), Rabbit (1194), Rabbit (1404), Rabbit (1530), Easter Bunny (3688), Rabbit (4447), Rabbit (4448), Rabbit (5829), Rabbit (7125), Rabbit (7126), Rabbit (7127) +Linked graphics: 645, 943, 1039 + +Base: 1396 +Linked animations: [5237, 5238, 5239, 5240, 5241, 5242] +Linked graphics: 944, 945, 946 +Linked objects: Broken snare (19334), Rabbit snare (19335), Rabbit snare (19336) + +Base: 1397 +Linked animations: [6105] +Linked graphics: 1038 + +Base: 1398 +Linked animations: [3851, 3852] +Linked NPCs: Easter Bunny (1835), Easter Bunny (7197) + +Base: 1399 +Linked animations: [3864] +Linked graphics: 643 + +Base: 1400 +Linked animations: [3850] +Linked graphics: 642 + +Base: 1401 +Linked animations: [6108] +Linked graphics: 644 + +Base: 1402 +Linked animations: [3858] +Linked graphics: 1040, 1041, 1042, 1043, 1044, 1045 + +Base: 1403 +Linked animations: [6120, 11411] +Linked NPCs: Boulder (9670), Boulder (9671) + +Base: 1404 +Linked animations: [6114, 6115, 6116, 6117, 6127] +Linked NPCs: Brine rat (3707) + +Base: 1405 +Linked animations: [6126] +Linked NPCs: Ulfric (3710) + +Base: 1406 +Linked animations: [6119] +Linked graphics: 1048 + +Base: 1407 +Linked animations: [6121] + +Base: 1408 +Linked animations: [6167, 6168] +Linked objects: Council members (23318), Cave gobins (23319) + +Base: 1409 +Linked animations: [6164, 6165, 6166] +Linked objects: Crowd of dwarves (23315), Crowd of dwarves (23316), Crowd of dwarves (23317), Crowd of dwarves (29118), null (29119), null (29120) + +Base: 1410 +Linked animations: [6211] +Linked objects: Zanik (23284) + +Base: 1411 +Linked animations: [6171, 6172, 6173, 6174, 6175, 6176, 6177, 6178, 6179] + +Base: 1412 +Linked animations: [6169] + +Base: 1413 +Linked animations: [6150, 6151] +Linked NPCs: Sigmund and Zanik (5862) + +Base: 1414 +Linked animations: [6152, 6153, 6154, 6155, 6156, 6157, 6158, 7027, 7029] +Linked NPCs: Sergeant Mossfists (5871), Sergeant Slimetoes (5872), null (5889), null (5890), null (5891), null (5892), Sergeant Strongstack (6261), Sergeant Steelwill (6263), Sergeant Grimspike (6265) +Linked graphics: 1201, 1205 + +Base: 1415 +Linked animations: [2963, 2964, 3221, 3384, 3385, 3386, 3387, 3388, 3389, 3391, 3395, 3400, 3401, 3402, 6134, 6135, 6136, 6137, 6138, 6139, 6140, 6141, 6180, 6181, 6182, 6183, 6184, 6185, 6186, 6187, 6188, 6189, 6190, 6192, 6193, 6195, 6199, 6200, 6201, 6202, 6203, 6204, 6827, 6829, 6830, 6833, 6834, 6835, 6836, 6837, 7024, 7305, 7306, 7308, 7309, 7310, 7311, 7315, 7316, 7317, 7318, 7319, 7320, 7323, 7324, 7325, 7326, 7327, 7330, 7331, 7332, 7333, 9650, 9963, 9964, 9965, 9966, 10233, 10240, 11275, 11278, 11279, 11285, 11294, 11297, 11303, 11320, 11321, 11338, 11361, 11374, 11394, 11395, 11396, 11397, 11398, 11800, 11801, 11848, 12301, 12637, 12638, 12654, 12655] +Linked NPCs: Goblin (100), Goblin (101), Goblin (102), High Priest (420), High Priest (421), Goblin (444), Goblin (445), Goblin guard (489), Greldo (612), Wormbrain (745), Goblin (1769), Goblin (1770), Goblin (1771), Goblin (1772), Goblin (1773), Goblin (1774), Goblin (1775), Goblin (1776), Goblin (2274), Goblin (2275), Goblin (2276), Goblin (2277), Goblin (2278), Goblin (2279), Goblin (2280), Goblin (2281), High Priest (2535), Bandos avatar (2541), Goblin (2678), Goblin (2679), Goblin (2680), Goblin (2681), Goblin Champion (3060), Goblin (3264), Goblin (3265), Goblin (3266), Goblin (3267), General Wartface (3391), General Bentnoze (3392), Goblin Cook (3413), Goblin Cook (3414), Goblin Cook (3415), General Wartface (3479), Angry goblin (3648), Angry goblin (3663), General Bentnoze (3723), General Wartface (3724), Grubfoot (3725), Goblin (3726), Grubfoot (3849), Goblin (4261), Goblin (4262), Goblin (4263), Goblin (4264), Goblin (4265), Goblin (4266), Goblin (4267), Goblin (4268), Goblin (4269), Goblin (4270), Goblin (4271), Goblin (4272), Goblin (4273), Goblin (4274), Goblin (4275), Goblin (4276), Goblin (4407), Goblin (4408), Goblin (4409), Goblin (4410), Goblin (4411), Goblin (4412), Prisoner (4416), Grubfoot (4417), Goblin (4479), Goblin (4480), Goblin (4481), Goblin (4482), Goblin (4483), Goblin (4484), Goblin (4485), Goblin (4486), Goblin (4487), Goblin (4488), Goblin (4489), Goblin (4490), Goblin (4491), Goblin (4492), General Bentnoze (4493), General Wartface (4494), null (4495), Grubfoot (4496), Grubfoot (4497), Grubfoot (4498), Goblin (4499), Grubfoot (4536), Goblin (4633), Goblin (4634), Goblin (4635), Goblin (4636), Goblin (4637), Goblin (5855), Goblin (5856), Goblin statue (5908), Sleeping guard (6122), Naghead (6123), Wagchin (6124), Goblin (6125), Goblin (6126), Smellytoes (6128), Creakyknees (6129), Clothears (6130), Goblin (6279), Goblin (6280), Goblin (6281), Goblin (6282), Goblin (6283), Goblin (6402), Goblin (6403), Goblin (6404), Goblin (6405), Goblin (6406), Goblin (6407), Goblin (6408), Goblin (6409), Goblin (6410), Goblin (6411), Goblin (6412), Goblin (6413), Goblin (6414), Goblin (6415), Goblin (6416), Goblin (6417), Goblin (6418), Goblin (6419), Goblin (6420), Goblin (6421), Goblin (6422), Goblin (6423), Goblin (6424), Goblin (6425), Goblin (6426), Goblin (6427), Goblin (6428), Goblin (6429), Goblin (6430), Goblin (6431), Goblin (6432), Goblin (6433), Goblin (6434), Goblin (6435), Goblin (6436), Goblin (6437), Goblin (6438), Goblin (6439), Goblin (6440), Goblin (6441), Goblin (6442), Goblin (6443), Goblin (6444), Goblin (6445), Goblin (6446), Goblin (6447), Goblin (6448), Goblin (6449), Goblin (6450), Goblin (6451), Goblin (6452), Goblin (6453), Goblin (6454), Goblin (6455), Goblin (6456), Goblin (6457), Goblin (6458), Goblin (6459), Goblin (6460), Goblin (6461), Goblin (6462), Goblin (6463), Goblin (6464), Goblin (6465), Goblin (6466), Goblin (6467), Skoblin (6468), Snothead (6469), Snailfeet (6470), Mosschin (6471), Redeyes (6472), Strongbones (6473), Snothead (6474), Snailfeet (6475), Mosschin (6476), Redeyes (6477), Strongbones (6478), Grubfoot (6479), null (6480), Grubfoot (6481), Priest (6482), Priest (6483), Priest (6484), Priest (6485), Priest (6486), Priest (6487), Preacher (6488), null (6489), Goblin (6490), Goblin (6491), Goblin (6492), Goblin (6493), Goblin (6494), Goblin (6495), Goblin guard (6496), Goblin guard (6497), Guard (6498), Guard (6499), Guard (6500), Guard (6501), Guard (6502), Guard (6503), General Bentnoze (7444), General Wartface (7892), General Bentnoze (7893), Goblin (7964), Goblin (7965), null (8072), Mystic (8231), Mystic (8236), null (8656), null (8657), Goblin musician (8712), Goblin (8862), null (8936), Junior Cadet Grimeface (8937), General Wartface (9408), General Bentnoze (9410), General Bentnoze (9412), General Wartface (9414), Skoblin (9611), Goblin courier (9683), Phlegm Knee (9690), Goblin (11259), Goblin (11260), Goblin (11261) +Linked graphics: 1248, 1249, 1250, 1251, 1252, 1253, 1254, 1255, 1256, 1257, 1258, 1259 +Linked objects: Goblin statue (42586), Goblin statue (42587), Goblin statue (42603), Goblin statue (42606), Goblin cook (45315) + +Base: 1416 +Linked animations: [6142, 6191] +Linked graphics: 1049, 1053 + +Base: 1417 +Linked animations: [6144, 6145] +Linked graphics: 1050, 1051 + +Base: 1418 +Linked animations: [6148] +Linked graphics: 1052 + +Base: 1419 +Linked animations: [6196, 6461] +Linked objects: Sample table (23526), Sample table (23527), null (24552), null (24553), null (24554) + +Base: 1420 +Linked animations: [6216, 6460] +Linked graphics: 1054, 1076 + +Base: 1421 +Linked animations: [6243, 6244, 6245, 6246, 7630, 7631, 7632, 7636, 7637, 7638, 7639, 7641, 8380, 8381, 8382, 8383, 8384, 8385, 8386, 8387, 8475, 8476, 8477, 8478, 9358, 10553, 11605, 11606, 11607, 11608] + +Base: 1422 +Linked animations: [1172, 1173, 1185, 1188, 6218, 6219, 6220, 6221, 6222, 6223, 6224, 6225, 6226, 6227, 6228, 6229, 6230, 6231, 6232, 6238, 6239, 6240, 6241, 6242, 6476, 6477, 8516, 8517, 8518, 8519, 8531] +Linked NPCs: Kalphite Worker (1153), Kalphite Soldier (1154), Kalphite Guardian (1155), Kalphite Worker (1156), Kalphite Guardian (1157), Kalphite Queen (1158), Kalphite Larva (1161), Kalphite Soldier (3589), Kalphite Queen (3835), Spirit kalphite (6994), Spirit kalphite (6995), Kalphite worker (11621) +Linked graphics: 278 +Linked objects: Kalphite Soldier (13374), Kalphite Queen (15490) + +Base: 1423 +Linked animations: [6269] +Linked graphics: 1055 +Linked objects: Kalphite queen legs (23591) + +Base: 1424 +Linked animations: [6271] +Linked graphics: 280 + +Base: 1425 +Linked animations: [1170, 1171, 1178, 1250, 6233, 6234, 6235, 6236, 6237, 6270] +Linked NPCs: Kalphite Queen (1160), Kalphite Queen (3836) +Linked graphics: 279 + +Base: 1426 +Linked animations: [6252, 6253, 6254, 6255, 6256, 6257, 6258, 6259, 6260, 6261, 6262, 6263, 6264, 6265, 6266, 6267, 8123, 8124, 8127, 8546] +Linked NPCs: Scorpion (107), Poison Scorpion (108), Pit Scorpion (109), King Scorpion (144), Khazard scorpion (271), Kharid Scorpion (385), Kharid Scorpion (386), Kharid Scorpion (387), Grave scorpion (493), Scorpion (1477), Giant lobster (1693), Scorpion (4402), Scorpion (4403), null (4891), Giant lobster (4892), Giant Lobster (4893), Spirit scorpion (6837), Spirit scorpion (6838), null (7523), Giant lobster (7828), Lobster (9720) + +Base: 1427 +Linked animations: [6247, 6248, 6249, 6250, 6251] +Linked NPCs: Spider (61), Spider (1004), Spider (1221), Spider (1473), Spider (1474), Crypt spider (2034), Spider (4401), Spider Courtier (8972), Eek the Spider (8985) + +Base: 1428 +Linked animations: [6272, 6273, 6274] +Linked objects: Cocoon (23611) + +Base: 1429 +Linked animations: [6275, 6276, 6277, 6278, 6279] + +Base: 1430 +Linked animations: [4129] +Linked objects: Sign (23980) + +Base: 1431 +Linked animations: [4127] +Linked objects: Lantern (24026) + +Base: 1432 +Linked animations: [6466] +Linked objects: Swings (24094), Swings (34572) + +Base: 1433 +Linked animations: [6467] +Linked objects: Washing line (24095), null (34575), null (43044) + +Base: 1434 +Linked animations: [4130] +Linked objects: Hearth (23963) + +Base: 1435 +Linked animations: [6492] +Linked objects: Fountain (24265) + +Base: 1436 +Linked animations: [4124] +Linked objects: Cooking pot (24328), Fireplace (24329), Fireplace (35449), Fireplace (36816) + +Base: 1437 +Linked animations: [6491] +Linked objects: null (24017) + +Base: 1438 +Linked animations: [4131] +Linked objects: null (23979) + +Base: 1439 +Linked animations: [4132] +Linked objects: Chimney (15487), Smoking vent (24194), Smoking vent (24195) + +Base: 1440 +Linked animations: [6343, 6344, 6345, 6346, 6347, 6356] +Linked NPCs: The Everlasting (5903) + +Base: 1441 +Linked animations: [6338, 6339, 6340, 6341, 6342, 6348, 6349, 6350, 6351] +Linked NPCs: The Illusive (5905), The Illusive (5907) + +Base: 1442 +Linked animations: [6317, 6318, 6319, 6320, 6321, 6322, 6324, 6325, 6354] +Linked NPCs: The Inadequacy (5902) + +Base: 1443 +Linked animations: [6310, 6311, 6312, 6313, 6314, 6315] +Linked NPCs: A Doubt (5906) + +Base: 1444 +Linked animations: [6328, 6329, 6330, 6331, 6332] +Linked NPCs: The Untouchable (5904) + +Base: 1445 +Linked animations: [6307] +Linked graphics: 1061 + +Base: 1446 +Linked animations: [6353] +Linked graphics: 1074 + +Base: 1447 +Linked animations: [6308] +Linked graphics: 1063 + +Base: 1448 +Linked animations: [6309] +Linked graphics: 1062 + +Base: 1449 +Linked animations: [6327] +Linked graphics: 1067 + +Base: 1450 +Linked animations: [6326] +Linked graphics: 1066 + +Base: 1451 +Linked animations: [6352] +Linked graphics: 1075 + +Base: 1452 +Linked animations: [6306] +Linked graphics: 1059, 1060 + +Base: 1453 +Linked animations: [6316] +Linked graphics: 1064 + +Base: 1454 +Linked animations: [6335, 6336] +Linked graphics: 1071, 1072 + +Base: 1455 +Linked animations: [6337] +Linked graphics: 1073 + +Base: 1456 +Linked animations: [6323, 6355] +Linked graphics: 1065, 1068 + +Base: 1457 +Linked animations: [6333, 6334] +Linked graphics: 1069, 1070 + +Base: 1458 +Linked animations: [6357, 6358, 6498] +Linked graphics: 1057, 1058, 1077 + +Base: 1459 +Linked animations: [6481, 6482, 6483] +Linked objects: Dummy (23921), Dummy (25648), Dummy (46957) + +Base: 1460 +Linked animations: [4128, 12647] +Linked objects: Sign (23967), Sign (23968), Sign (23969), Sign (23970), null (23971), Sign (23972), null (23973), Sign (23974), null (23975), null (23976), Sign (23977), Sign (23978), null (23981), Sign (23982), Sign (25762), Sign (26971), Pet shop (28351), Sign (28623), Signpost (31297), Signpost (31299), Sign (35649), null (36901), null (36902), Poison Arrow pub (44292), Sign (45179), Sign (45180), Sign (45181), null (47749), null (47750), null (47751), null (47752), null (47753), null (47754), null (52460), null (52461), null (52462) + +Base: 1461 +Linked animations: [6470] +Linked objects: Wheat (15506), Wheat (15508) + +Base: 1462 +Linked animations: [6493] +Linked objects: Mill (24067), null (36875) + +Base: 1463 +Linked animations: [6494] +Linked objects: Mill (24068), Mill (36877), Flour bin (52549), Flour bin (52550) + +Base: 1464 +Linked animations: [6495] +Linked objects: Sails (24065), Sails (36872), Sails (36873), Sails (46009), null (46010) + +Base: 1465 +Linked animations: [6426] +Linked objects: null (24417), null (24418) + +Base: 1466 +Linked animations: [6427] + +Base: 1467 +Linked animations: [6450, 6451] +Linked NPCs: Mole display (5982) + +Base: 1468 +Linked animations: [6430, 6431] +Linked NPCs: Snail display (5973) + +Base: 1469 +Linked animations: [6452, 6453] +Linked objects: Snake (24569) + +Base: 1470 +Linked animations: [6444, 6445] +Linked NPCs: Wyvern display (5980) + +Base: 1471 +Linked animations: [6432, 6433] +Linked NPCs: Sea slugs display (5972) + +Base: 1472 +Linked animations: [6373, 6374, 6375, 6376, 6377, 8265, 8266, 8267, 8565] +Linked NPCs: Unicorn (89), Black unicorn (133), Unicorn (987), Unicorn Foal (1328), Black unicorn Foal (1329), Angry unicorn (3646), Angry unicorn (3661), Stag (4440), Starlight (6248), Unicorn stallion (6822), Unicorn stallion (6823) + +Base: 1473 +Linked animations: [6434, 6435] +Linked NPCs: Monkey display (5974) + +Base: 1474 +Linked animations: [6463] + +Base: 1475 +Linked animations: [6412, 6413] +Linked NPCs: Teacher and pupil (5947) + +Base: 1476 +Linked animations: [6410, 6411] +Linked NPCs: Teacher and pupil (5944) + +Base: 1477 +Linked animations: [6414, 6415, 6416, 6417, 6418, 6454, 6455, 6456, 6457, 6458] +Linked NPCs: Workman (5952), Workman (5953), Barge workman (5959), Barge workman (5960), Barge workman (5961), Barge workman (5962), Barge foreman (5963) + +Base: 1478 +Linked animations: [6419, 6420, 6421, 6422, 6423] +Linked NPCs: Workman (5954), Workman (5955), Workman (5986), Workman (6159) + +Base: 1479 +Linked animations: [4123] +Linked objects: null (9375) + +Base: 1480 +Linked animations: [6497, 6499] +Linked objects: Beanstalk (24732), Beanstalk (24734) + +Base: 1481 +Linked animations: [6522] +Linked objects: Gramophone (24724), Gramophone (24725), Gramophone (24726), Gramophone (24727), null (24882) + +Base: 1482 +Linked animations: [6523] +Linked objects: Floor (24843), Floor (24844), Floor (24845), Floor (24846), Floor (24847) + +Base: 1483 +Linked animations: [6509] +Linked objects: Rupert (24771), null (24773), null (24774) + +Base: 1484 +Linked animations: [6510, 6511, 6512, 6513, 6514, 6515] +Linked NPCs: Experiment No.2 (5993) + +Base: 1485 +Linked animations: [6501, 6502, 6503, 6504, 6505, 6524] +Linked NPCs: Glod (5996) + +Base: 1486 +Linked animations: [6517, 6518, 6519, 6520, 6521, 11546] +Linked NPCs: Mouse (5994), Mouse (5995), Mouse (7205) + +Base: 1487 +Linked animations: [6506, 6507, 6508] +Linked NPCs: Grimgnash (5989), null (5997) +Linked objects: Grimgnash (24839), null (24840) + +Base: 1488 +Linked animations: [6516] +Linked graphics: 1078 + +Base: 1489 +Linked animations: [225, 1518, 6550, 6551, 6552, 6553, 6555, 8371, 8372, 8373, 8374, 8375, 8581, 8582, 9178, 9179, 9180, 9181, 9182, 9183, 9184, 9185, 9186, 9187, 9188, 9189, 9190, 9191, 9192, 9193, 9201, 9202, 9203, 9225, 10552, 11536, 11710] + +Base: 1490 +Linked animations: [6536, 6537, 6538, 6539, 6540, 6541, 6542, 6543, 6544, 6545, 6546, 6547, 6548, 6549] +Linked NPCs: Skullball Boss (1660), Agility Boss (1661), Skullball Trainer (1662), Agility Trainer (1663), Agility Trainer (1664), Werewolf (1665), Mystery figure (3055), Shadowy figure (4762), Shadowy figure (4763), Shadowy figure (4764), Werewolf (6006), Werewolf (6007), Werewolf (6008), Werewolf (6009), Werewolf (6010), Werewolf (6011), Werewolf (6012), Werewolf (6013), Werewolf (6014), Werewolf (6015), Werewolf (6016), Werewolf (6017), Werewolf (6018), Werewolf (6019), Werewolf (6020), Werewolf (6021), Werewolf (6022), Werewolf (6023), Werewolf (6024), Werewolf (6025), Werewolf (6212), Werewolf (6213) +Linked graphics: 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098 + +Base: 1491 +Linked animations: [6556, 6557, 6558, 6559, 6560, 6561, 6562, 6563, 6564, 6565, 6566, 6567, 6568, 6569, 6570, 6571, 6572, 6573, 6574, 6575, 6576, 6577, 6578, 6579, 6580, 6581, 6582, 6583, 7254, 7575, 7576, 8291, 8292, 8293, 8294, 8295, 8296, 8297, 8298, 8329, 8330, 8331, 8332, 8333, 8334, 8335, 8336, 8337, 8338, 8339, 8340, 8341, 8532, 12297] +Linked NPCs: Hellhound (49), Wolf (95), White wolf (96), White wolf (97), Dog (98), Guard dog (99), Big Wolf (141), Wolf (142), Jungle Wolf (143), Bouncer (269), Sinclair Guard dog (821), Desert Wolf (839), Witch's experiment (fourth form) (900), Dire Wolf (1198), Vampyric hound (1224), Fox (1319), Fenris wolf (1330), Ice wolf (1558), Ice wolf (1559), Skeleton Hellhound (1575), Wild dog (1593), Wild dog (1594), Ice wolf (1951), Ice wolf (1952), Ice wolf (1953), Ice wolf (1954), Ice wolf (1955), Ice wolf (1956), Shadow Hound (1976), Jackal (1994), Muncher (2329), Guard dog (3582), Hellhound (3586), Wolf (4413), Wolf (4414), Bouncer (5564), Bouncer (5565), Big Wolf (6046), Wolf (6047), Wolf (6048), Wolf (6049), Desert Wolf (6050), Desert Wolf (6051), Ice wolf (6052), Hellhound (6210), Guard dog (6374), Bulldog (6752), Spirit wolf (6829), Spirit wolf (6830), Terrier (6894), Labrador (6895), Dalmatian (6896), Bulldog (6897), Bulldog (6899), Terrier puppy (6958), Terrier (6959), Greyhound puppy (6960), Greyhound (6961), Labrador puppy (6962), Labrador (6963), Dalmatian puppy (6964), Dalmatian (6965), Sheepdog puppy (6966), Sheepdog (6967), Bulldog (6968), Bulldog puppy (6969), Big wolf (7005), Terrier puppy (7237), Terrier (7238), Terrier puppy (7239), Terrier (7240), Greyhound puppy (7241), Greyhound (7242), Greyhound puppy (7243), Greyhound (7244), Labrador puppy (7245), Labrador (7246), Labrador puppy (7247), Labrador (7248), Dalmatian puppy (7249), Dalmatian (7250), Dalmatian puppy (7251), Dalmatian (7252), Sheepdog puppy (7253), Sheepdog (7254), Sheepdog puppy (7255), Sheepdog (7256), Bulldog (7257), Bulldog (7258), Bulldog puppy (7259), Bulldog puppy (7260), null (7521), Temple guardian (7711), Snowy (8017), Muncher (8868), Muncher (8983), Terrier (9190), Terrier (9191), Terrier (9192), Greyhound (9193), Greyhound (9194), Greyhound (9195), Labrador (9196), Labrador (9197), Labrador (9198), Dalmatian (9199), Dalmatian (9200), Dalmatian (9201), Sheepdog (9202), Sheepdog (9203), Sheepdog (9204), Bulldog (9205), Bulldog (9206), Bulldog (9207), Spirit wolf (9468), Hellhound (10188), Hellhound (10189), Hellhound (10190), Hellhound (10191), Hellhound (10192), Hellhound (10193), Hellhound (10194), Hellhound (10195), Guard dog (10726), Guard dog (10727), Guard dog (10728), Guard dog (10729), Guard dog (10730), Guard dog (10731), Guard dog (10732), Guard dog (10733), Guard dog (10734), Guard dog (10735), Wolf (11262), Wolf (11263), Pit dog (11562), Pit dog (11584), Pit dog (11585) +Linked objects: Hellhound (2715), Guard dog (13367), Pit dog (39260), Pit dog (41589) + +Base: 1492 +Linked animations: [370, 581] +Linked graphics: 232, 233, 234, 235, 236, 237, 273, 1123, 1234, 1235, 1236, 1237, 1238, 1239, 1240, 1242 + +Base: 1493 +Linked animations: [6623, 6624, 6625, 6626, 6627] +Linked objects: Crop circle (24984), Crop circle (24985), Crop circle (24986), Crop circle (24987), Centre of crop circle (24988), Magic wheat (24989), Magic wheat (24990), Centre of crop circle (24991) + +Base: 1494 +Linked animations: [6613, 6614, 6615, 6617, 6618, 11511, 11515, 12263, 12264, 12831, 12833, 12834] +Linked NPCs: Baby impling (1028), Young impling (1029), Gourmet impling (1030), Earth impling (1031), Essence impling (1032), Eclectic impling (1033), Nature impling (1034), Magpie impling (1035), Ninja impling (6053), Dragon impling (6054), Baby impling (6055), Young impling (6056), Gourmet impling (6057), Earth impling (6058), Essence impling (6059), Eclectic impling (6060), Nature impling (6061), Magpie impling (6062), Ninja impling (6063), Dragon impling (6064), Immenizz (6071), Wandering impling (6073), Easter impling (7420), Impling worker (7421), Impling worker (7422), Impling worker (7424), Impling manager (7425), Impling worker (7426), Pirate impling (7845), Pirate impling (7846), Spirit impling (7866), Pirate impling (7867), Zombie impling (7902), Kingly impling (7903), Spirit impling (7904), Zombie impling (7905), Kingly impling (7906), null (9698), null (9699), null (9702), Impling manager (9703), Impling manager (9704), Impling manager (9705), Impling worker (9706) +Linked objects: Impling worker (45799), Impling worker (49102), Impling worker (49103), Impling worker (49104), Impling worker (49105), Impling manager (49106) + +Base: 1495 +Linked animations: [6622] +Linked graphics: 1120, 1122 + +Base: 1496 +Linked animations: [6619, 6620, 6621] +Linked graphics: 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 2327, 2328, 2329, 2330, 2331, 2332, 2333, 2334, 2335, 2336, 2337, 2338 + +Base: 1497 +Linked animations: [6596, 6597, 6598, 6599] +Linked objects: Growing wheat (25022), Wilting wheat (25023) + +Base: 1498 +Linked animations: [6591] +Linked graphics: 1117 + +Base: 1499 +Linked animations: [6602] +Linked graphics: 1118 + +Base: 1500 +Linked animations: [6612] +Linked graphics: 1119 + +Base: 1501 +Linked animations: [6585, 6586] +Linked graphics: 1099, 1100 + +Base: 1502 +Linked animations: [6587, 6588, 6589, 6590] +Linked graphics: 1101, 1102, 1103 + +Base: 1503 +Linked animations: [2729, 2730, 2731, 2732, 2733, 13840, 13841] +Linked NPCs: Dark beast (2783), Kolodion (11302) + +Base: 1504 +Linked animations: [6656, 9647] +Linked objects: Flag (25205), Flag (35145) + +Base: 1505 +Linked animations: [6635, 6636, 6637] +Linked objects: Magic door (25115), Magic door (25116), Magic door (25118) + +Base: 1506 +Linked animations: [6638] +Linked objects: Candle stand (25122), Candle stand (25123) + +Base: 1507 +Linked animations: [6639] +Linked objects: Vines (25136) + +Base: 1508 +Linked animations: [6644] + +Base: 1509 +Linked animations: [6641] + +Base: 1510 +Linked animations: [6645] +Linked objects: Fire (25155) + +Base: 1511 +Linked animations: [6646, 6853, 12320, 12373] +Linked objects: Fire (25156), Fire (25465), Fire (27297), Altar (27306), null (30452), Torch (30794), Fire (41687), null (41688), Torch (42148), Torch (42149), Torch (43030), Torch (46329), Torch (48115) + +Base: 1512 +Linked animations: [6852] +Linked graphics: 1173 + +Base: 1513 +Linked animations: [6652] +Linked objects: Jenkins (25157) + +Base: 1514 +Linked animations: [6640] + +Base: 1515 +Linked animations: [6648] +Linked graphics: 1155 + +Base: 1516 +Linked animations: [6647] +Linked graphics: 1154 + +Base: 1517 +Linked animations: [6698] +Linked graphics: 1166 + +Base: 1518 +Linked animations: [6699] +Linked graphics: 1167 + +Base: 1519 +Linked animations: [6697] +Linked graphics: 1165 + +Base: 1520 +Linked animations: [6690, 6691, 6692, 6693, 6694, 6701] +Linked graphics: 1160, 1161, 1162, 1163, 1164, 1168 + +Base: 1521 +Linked animations: [6667, 6668, 6669, 6670] +Linked graphics: 1156, 1157, 1158, 1159 + +Base: 1522 +Linked animations: [6737] +Linked objects: Whirlpool (25274), Whirlpool (25275) + +Base: 1523 + +Base: 1524 +Linked animations: [6731, 6732] +Linked objects: Mighty torrent (25276), Mighty torrent (25277), Mighty torrent (25278), Mighty torrent (25279), null (25280), null (25281), null (25282), null (25283), null (25284), null (25285), null (33484), null (33485), null (33486), null (33487) + +Base: 1525 +Linked animations: [6733, 6734, 6735, 6736, 9640] +Linked objects: funeral pyre (25267), Pyre boat (25292), Pyre boat (25293), Pyre boat (25294), Pyre boat (25295) + +Base: 1526 +Linked animations: [6725, 6726, 6727, 6728, 6729, 6730] +Linked NPCs: Angry barbarian spirit (749), Enraged barbarian spirit (750), Berserk barbarian spirit (751), Ferocious barbarian spirit (752) + +Base: 1527 +Linked animations: [6721] +Linked graphics: 1169 + +Base: 1528 + +Base: 1529 + +Base: 1530 + +Base: 1531 + +Base: 1532 + +Base: 1533 +Linked animations: [1007, 1008, 1009, 1010, 1012, 1013, 6442, 6443, 6759, 6769, 6770, 6789, 6790, 6791, 6792, 6793, 6794, 6795, 6796, 6797, 6798, 6799, 8229, 8230, 8231, 8557] +Linked NPCs: Mounted terrorchick gnome (136), Terrorchick gnome (137), Terrorbird (138), Terrorbird (139), Terrorbird (1751), Mounted terrorbird gnome (1752), Mounted terrorbird gnome (1753), Terrorbird display (5978), Mounted terrorbird gnome (6109), Mounted terrorbird gnome (6110), Mounted terrorbird gnome (6111), Spirit terrorbird (6794), Spirit terrorbird (6795) + +Base: 1534 +Linked animations: [6784, 6785, 6786, 6787, 6788] +Linked NPCs: Crow (1754), Crow (1755), Crow (1756), Crow (2252), Crow (4570), Crow (4571), Rook (9719) + +Base: 1535 +Linked animations: [6808, 6809, 6810, 6811, 6812] +Linked NPCs: Desert Phoenix (1911), Entrana firebird (6108) + +Base: 1536 +Linked animations: [6761, 6762, 6763, 6764, 6765, 6766, 6767, 6768, 6800, 6801, 6802, 6803, 6804, 6805, 6806, 6807, 6823] +Linked NPCs: Chompy bird (1016), Chompy bird (1550), Jubbly bird (3476), Jubbly bird (3477), Jubster (5596) + +Base: 1537 +Linked animations: [8005, 8007, 8008, 8009, 8010, 8011, 8012, 8013, 8014, 8020, 8310, 8311, 8312, 8553, 10230, 10232] +Linked NPCs: Magpie (6824), Macaw (6851), Raven chick (6911), Raven (6912), Vulture chick (6945), Saradomin chick (6949), Saradomin bird (6950), Saradomin owl (6951), Zamorak chick (6952), Zamorak bird (6953), Zamorak hawk (6954), Guthix chick (6955), Guthix bird (6956), Guthix raptor (6957), Raven chick (7261), Raven (7262), Raven chick (7263), Raven (7264), Raven chick (7265), Raven (7266), Raven chick (7267), Raven (7268), Raven chick (7269), Raven (7270), Vulture chick (7319), Vulture chick (7321), Vulture chick (7323), Vulture chick (7325), Vulture chick (7327), Saradomin owl (7816), Ex-ex-parrot (7844), Zamorak hawk (9186), Guthix raptor (9187), Ex-ex-parrot (9212), Raven (9239), Raven (9240), Raven (9241), Raven (9242), Raven (9243), Raven (9244) +Linked graphics: 1778 + +Base: 1538 +Linked animations: [5171, 5172, 5173, 5174, 6771, 6772, 6773, 6774, 6775, 6776, 6777, 6778, 6779, 6780, 6781, 6782, 6783, 8006] +Linked NPCs: Gull (146), Cormorant (147), Pelican (148), Gull (149), Gull (150), Gull (450), Gull (451), Gull (1179), Cormorant (1180), Pelican (1181), Gull (1322), Gull (1323), Gull (1324), Gull (1325), Gull (1400), Bird (1475), Bird (1476), Seagull (2707), Seagull (2708), Gull (2726), Gull (2727), Gull (3197), Tropical wagtail (5072), Crimson swift (5073), Cerulean twitch (5074), Golden warbler (5075), Copper longtail (5076), Tenacious toucan (6378), Pernicious parrot (6382), Macaw (6852), Wimpy bird (7031), null (7032), null (7033), null (7034), null (7035), null (7036), Gull (7860), Gull (9334), Gull (9717), Cormorant (9718) +Linked objects: Bird snare (19177), Bird snare (19178), Bird snare (19179), Bird snare (19180), Bird snare (19181), Bird snare (19182), Bird snare (19183), Bird snare (19184), Bird snare (19185), Bird snare (19186), Bird snare (28930), Bird snare (28931), Bird snare (28932), Bird snare (28933), Bird snare (28934), Bird snare (29164), Bird snare (29165) + +Base: 1539 +Linked animations: [747, 750, 1014, 1015, 3268, 3467, 3468, 6813, 6815, 6817, 6818, 6819, 6821, 6822] +Linked NPCs: Duck (46), Duck (2693), Duckling (2694), Ducklings (6112), Duck (6113), Drake (6114), Seagull (6115), Seagull (6116) + +Base: 1540 +Linked animations: [7, 8, 9, 6824, 10556, 11540] + +Base: 1541 +Linked animations: [6850, 6851] + +Base: 1542 +Linked animations: [6857] +Linked NPCs: Giant (487) + +Base: 1543 +Linked animations: [6858, 6859] +Linked NPCs: Goblin (6132), Goblin (6133) + +Base: 1544 +Linked animations: [6856] +Linked NPCs: Mummy (490) + +Base: 1545 +Linked animations: [6855] +Linked NPCs: Zombie (6131) + +Base: 1546 +Linked animations: [6854] +Linked objects: Rocking unicorn (25426) + +Base: 1547 +Linked animations: [6860] + +Base: 1548 +Linked animations: [6861] + +Base: 1549 +Linked animations: [6888, 6889] +Linked graphics: 1176, 1177 + +Base: 1550 +Linked animations: [6877] +Linked graphics: 1175 + +Base: 1551 +Linked animations: [6873, 6874, 6875] +Linked objects: Novice Flag (25620), Intermediate Flag (25621), Veteran Flag (25622), Novice flag (25623), Intermediate Flag (25624), Veteran Flag (25625), null (25626), null (25627), null (25628), null (25634), null (25635), Novice Flag (41519), Intermediate Flag (41520), Veteran Flag (41521) + +Base: 1552 +Linked animations: [1431, 6900, 6901, 6902, 6903, 6904, 6905, 6906, 6907, 6908, 6909, 6910, 6911, 14153, 14154, 14155, 14156, 14157, 14158, 14159, 14160, 14161, 14162, 14163, 14166, 14167, 14168, 14169, 14170, 14171, 14172, 14173, 14174] +Linked objects: The Jury (4414), The Jury (4416), The Jury (4417), The Jury (4418), The jury (25944), The jury (25945), The jury (25946), The jury (25947) + +Base: 1553 +Linked animations: [6916, 6925] +Linked objects: Sir Tristram (25889) + +Base: 1554 +Linked animations: [6898, 6899] +Linked objects: Judge (4420), Court judge (25956) + +Base: 1555 +Linked animations: [6921] + +Base: 1556 +Linked animations: [6890, 6891, 6892, 6893, 6894, 6895] +Linked objects: Citizen (26045), Citizen (26046), Citizen (26047), Citizen (26048), Citizen (26049), Citizen (26050) + +Base: 1557 +Linked animations: [6920] + +Base: 1558 +Linked animations: [6924] +Linked graphics: 1179 + +Base: 1559 +Linked animations: [6930] +Linked graphics: 1180 + +Base: 1560 + +Base: 1561 +Linked animations: [6931] +Linked objects: Fly paper (26137) + +Base: 1562 +Linked animations: [1549, 6934, 7625, 7626, 9386, 9387] +Linked objects: Lever (31358), Candle sconce (47405), Lever (47406) + +Base: 1563 +Linked animations: [6936, 6937, 6938] +Linked graphics: 1181, 1182, 1183 + +Base: 1564 +Linked animations: [4310, 4311, 7009, 7010, 7011, 14089, 14090] +Linked NPCs: Centaur (4438), Centaur (4439), Bree (6252) + +Base: 1565 +Linked animations: [7076, 12020] +Linked graphics: 1224, 2115 + +Base: 1566 +Linked animations: [7025, 7026, 7028] +Linked graphics: 1202, 1203, 1204 + +Base: 1567 +Linked animations: [7037, 7038] +Linked graphics: 1212, 1213 + +Base: 1568 +Linked animations: [6969] +Linked graphics: 1195 + +Base: 1569 +Linked animations: [6987] + +Base: 1570 +Linked animations: [7035, 7036] +Linked graphics: 1210, 1211 + +Base: 1571 +Linked animations: [6968] +Linked graphics: 1194 + +Base: 1572 +Linked animations: [7032, 7034] +Linked graphics: 1208, 1209 + +Base: 1573 +Linked animations: [7031] +Linked graphics: 1207 + +Base: 1574 +Linked animations: [7021] +Linked graphics: 1185 + +Base: 1575 +Linked animations: [6970] +Linked graphics: 1196, 1197, 1198 + +Base: 1576 +Linked animations: [6958] +Linked graphics: 1191 + +Base: 1577 +Linked animations: [6957] +Linked graphics: 1190 + +Base: 1578 +Linked animations: [6959, 6960] +Linked graphics: 1192, 1199 + +Base: 1579 +Linked animations: [6961] +Linked graphics: 1193 + +Base: 1580 +Linked animations: [7020, 7022] +Linked graphics: 1184, 1186 + +Base: 1581 +Linked animations: [7030] +Linked graphics: 1206 + +Base: 1582 +Linked animations: [7068, 11994] +Linked graphics: 1220, 2109 + +Base: 1583 +Linked animations: [7006] +Linked graphics: 1200 + +Base: 1584 +Linked animations: [7077, 11992] +Linked graphics: 1223, 2114 + +Base: 1585 +Linked animations: [7012, 7013] +Linked graphics: 1187, 1188 + +Base: 1586 + +Base: 1587 +Linked animations: [7075, 11990] +Linked graphics: 1222, 2113 + +Base: 1588 +Linked animations: [6948] +Linked graphics: 1189 + +Base: 1589 +Linked animations: [6972, 6973, 6974, 6975, 6976, 6977] +Linked NPCs: Kree'arra (6222) + +Base: 1590 +Linked animations: [6949, 6950, 6951, 6952, 6953, 6954, 6955, 6956, 6962, 6963, 6964, 6965, 6966, 6967, 6971, 7432, 7433, 7434, 7435, 7436, 7437, 7438] +Linked NPCs: Wingman Skree (6223), Flockleader Geerin (6225), Flight Kilisa (6227), Spiritual warrior (6229), Spiritual ranger (6230), Spiritual mage (6231), Aviansie (6232), Aviansie (6233), Aviansie (6234), Aviansie (6235), Aviansie (6236), Aviansie (6237), Aviansie (6238), Aviansie (6239), Aviansie (6240), Aviansie (6241), Aviansie (6242), Aviansie (6243), Aviansie (6244), Aviansie (6245), Aviansie (6246), Commander Zilyana (6247) + +Base: 1591 +Linked animations: [7067] +Linked objects: null (26472), null (26478), null (26481) + +Base: 1592 +Linked animations: [6983] + +Base: 1593 +Linked animations: [7007, 7008] +Linked objects: Waterfall (26418), Waterfall (26419), Waterfall (26420), Waterfall (26421), Waterfall (26422) + +Base: 1594 +Linked animations: [6996] +Linked objects: Snowfall (26417) + +Base: 1595 +Linked animations: [6982] +Linked objects: Big hole (26291) + +Base: 1596 +Linked animations: [7066] +Linked objects: null (26468), null (26471), null (26473), null (26476), null (26477), null (26479), null (26482), null (26483) + +Base: 1597 +Linked animations: [6980, 6981] + +Base: 1598 +Linked animations: [6995] +Linked objects: Snow (26415) + +Base: 1599 +Linked animations: [7053] +Linked graphics: 1214 + +Base: 1600 +Linked animations: [7057] +Linked graphics: 1218 + +Base: 1601 +Linked animations: [7056] +Linked graphics: 1217 + +Base: 1602 +Linked animations: [7055] +Linked graphics: 1216 + +Base: 1603 +Linked animations: [7065, 8119] +Linked graphics: 1219, 1351 + +Base: 1604 +Linked animations: [7131, 7134, 7136] + +Base: 1605 +Linked animations: [7140, 7141, 10905] + +Base: 1606 +Linked animations: [7130] + +Base: 1607 +Linked animations: [7132, 7133, 7137] + +Base: 1608 +Linked animations: [7129, 7135] + +Base: 1609 + +Base: 1610 +Linked animations: [7144] +Linked objects: null (26740) + +Base: 1611 +Linked animations: [7097] +Linked objects: null (26597), null (26598), null (26599), null (26600), Pipe (26708), Pipe (26709), Pipe (26710), Pipe (26711), null (26736), null (29242), Wall Pipe (48844) + +Base: 1612 +Linked animations: [7086, 7087, 7145, 7146, 7362] +Linked graphics: 1271 +Linked objects: Gas (26578), Gas jet (26579), null (26741) + +Base: 1613 +Linked animations: [7138] +Linked objects: Spirit tree (26731) + +Base: 1614 +Linked animations: [7119, 7120] +Linked objects: null (26730) + +Base: 1615 +Linked animations: [7114, 7115] +Linked objects: Human food (26727) + +Base: 1616 +Linked animations: [7116, 7117] +Linked objects: Human food (26728), Human food (26729) + +Base: 1617 +Linked animations: [7118] +Linked objects: Healthorg (26726) + +Base: 1618 + +Base: 1619 + +Base: 1620 +Linked animations: [7083, 7085] +Linked graphics: 1228, 1229 + +Base: 1621 +Linked animations: [7107, 8511, 8512] +Linked graphics: 1227, 1467, 1468, 1518 + +Base: 1622 +Linked animations: [7094, 7105, 7106, 7108, 7109, 7110] +Linked NPCs: Warped terrorbird (6285), Warped terrorbird (6286), Warped terrorbird (6287), Warped terrorbird (6288), Warped terrorbird (6289), Warped terrorbird (6290), Warped terrorbird (6291), Warped terrorbird (6292), Warped terrorbird (6293), Warped terrorbird (6294), Warped terrorbird (6295), Warped terrorbird (6322), Warped terrorbird (6323), Warped terrorbird (6324), Warped terrorbird (6325), Warped terrorbird (6326), Warped terrorbird (6327), Warped terrorbird (6328), Warped terrorbird (6329), Warped terrorbird (6330), Warped terrorbird (6331), Warped terrorbird (6332) + +Base: 1623 +Linked animations: [7098, 7099, 7100, 7101, 7102, 7103, 7104, 7111] +Linked NPCs: Terrorbird servant (6313), Guard no. 21 (6314), Guard no. 72 (6315), Guard no. 21 (6316), Guard no. 72 (6317) + +Base: 1624 +Linked animations: [7089, 7090, 7091, 7092, 7093] +Linked NPCs: Warped tortoise (6296), Warped tortoise (6297) + +Base: 1625 +Linked animations: [7148, 8307] +Linked graphics: 1231, 1464 + +Base: 1626 +Linked animations: [7152] +Linked objects: Furnace (26814) + +Base: 1627 +Linked animations: [7168, 7169, 7170, 7171, 7172, 7173, 7174, 7175, 7176, 7177, 7178, 7179, 7180, 8814, 8815, 8824, 9682, 9683, 9684, 9737] + +Base: 1628 +Linked animations: [3803, 3836, 3837, 4789, 4805, 7153, 7154, 7155, 7156, 7157, 7158, 7159, 7160, 7161, 7162, 7163, 7164, 7165, 7166, 7167, 7297, 7298, 7367, 7384, 8719, 8720, 8721, 8722, 8723, 8724, 8725, 8726, 8727, 8728, 8729, 8730, 8731, 8732, 8733, 8807, 8808, 8809, 8817, 8852, 10032, 10033, 10036, 10037, 10038, 10041, 10049, 10050, 10079, 10116, 10117, 10944, 10945, 10946, 10947, 10948, 10958, 10959, 10960, 10962, 11609, 11610, 11611, 11612, 11613, 11614, 11615] +Linked NPCs: Schoolgirl (10), Schoolgirl (17), null (264), null (265), null (266), Hudon (305), Child (355), Child (356), null (697), Billy Rehnison (723), Milli Rehnison (724), Shilop (781), Philop (782), Wilough (783), Kanel (784), Philipe Carnillean (888), Boy (895), Askeladden (1295), Street urchin (1868), Askeladden (2439), Catalina (3551), Ivan (3552), Victor (3553), Helena (3554), null (3623), Smiddi Ryak (3624), Tolna (3644), Ali the Leaflet Dropper (3680), null (4538), Cabin boy (4539), A Meiyerditch child (4746), A Meiyerditch child (4747), A Meiyerditch child (4748), A Meiyerditch child (4749), A Meiyerditch child (4750), A Meiyerditch child (4751), A Meiyerditch child (4752), A Meiyerditch child (4753), A Meiyerditch child (4754), A Meiyerditch child (4755), Kennith (4863), Kennith (4864), null (4865), null (5020), null (5021), null (5022), Jack (5023), Jill (5024), Jeff (5025), Schoolboy (5945), Schoolboy (5946), Schoolgirl (5957), Schoolgirl (5983), Schoolgirl (5984), Schoolgirl (5985), Child (6334), Child (6335), Child (6336), Child (6337), Child (6338), Child (6339), Child (6340), Child (6341), Child (6342), Child (6343), Child (6344), Child (6345), Street urchin (6357), Street urchin (6358), Street urchin (6359), Street urchin (6360), Street urchin (6361), Kennith (6373), Farid Morrisane (ores) (6523), Summer Bonde (6542), Farmer (7128), Farmer (7129), Farmer (7130), Farmer Blinkin (7131), Mrs. Winkin (7132), Kimberly (7168), Kimberly (7169), Kennith (7171), Kennith (7172), Kennith (7173), Kennith (7175), null (7191), null (7192), null (7193), null (7194), null (7404), null (7405), Erjolf (7462), Erjolf (7463), Erjolf (7464), Erjolf (7465), Erjolf (7466), Erjolf (7467), Jeremy Servil (7531), Jeremy Servil (7532), null (7533), Jeremy Servil (7534), null (7543), null (7544), null (7545), null (7546), null (7547), null (7548), null (7549), Spirit (7963), null (7972), null (7973), null (7974), null (7975), Spirit (7981), Spirit (7982), Spirit (7983), Spirit (7984), null (7985), Summer Bonde (7986), null (8112), Summer Bonde (8113), Summer Bonde (8114), Summer Bonde (8135), Laidee Gnonock (8484), Hazelmere (8485), Hazelmere (8489), Hazelmere (8490), null (8492), Junior Cadet Nirol (8932), null (8933), Junior Cadet Boff (8934), null (8935), Zambo (11620) +Linked objects: Kennith (29737), null (38164) + +Base: 1629 +Linked animations: [7205, 7207, 7208, 7209, 7210, 8351, 8352, 8353, 8354, 8355, 8356, 8357, 8358, 8359, 8360, 8361, 8362] +Linked NPCs: Cave lizard (6369), Baby gecko (6915), Gecko (6916), Baby gecko (6917), Gecko (6918), Baby gecko (7277), Baby gecko (7278), Baby gecko (7279), Baby gecko (7280), Gecko (7281), Gecko (7282), Gecko (7283), Gecko (7284), Baby gecko (7285), Baby gecko (7286), Baby gecko (7287), Baby gecko (7288), Gecko (7289), Gecko (7290), Gecko (7291), Gecko (7292), Gecko (9213), Gecko (9214), Gecko (9215), Gecko (9216), Gecko (9217) + +Base: 1630 +Linked animations: [7225, 7226] +Linked objects: null (26881), null (26882) + +Base: 1631 +Linked animations: [22, 23, 24, 85, 583, 7212, 7213, 7214, 7215, 7216, 7217, 7218, 7219, 7220, 7221, 7222, 7223, 7224, 8800] +Linked NPCs: Guard (296), Guard (297), Guard (298), Guard (299), Guard (3407), Guard (3408), Guard (6183), Guard (6184), Guard (7142), Guardsman Dante (7885), Guardsman DeShawn (7886), Guardsman Brawn (7887), Sergeant Abram (7888), Guardsman Pazel (7889), Guardsman Peale (7890), Arresting officer (11457) +Linked objects: Border guard (45860), Border guard (45861) + +Base: 1632 +Linked animations: [7233] + +Base: 1633 + +Base: 1634 +Linked animations: [7240, 7252] +Linked objects: Tree (27089) + +Base: 1635 +Linked animations: [7231] +Linked objects: null (27190) + +Base: 1636 +Linked animations: [7241, 7242, 7243, 7244] +Linked NPCs: Giant wasp (6381), Giant wasp (6383), Warped fly (7915) + +Base: 1637 +Linked animations: [7245, 7246, 7247, 7248, 7249] +Linked NPCs: Wild jade vine (3409), Wild jade vine (3410), Wild jade vine (3411), Wild jade vine (3412) +Linked objects: Jade vine (27039), Wild jade vine (27076), Wild jade vine (27077), Wild jade vine (27078), null (27196), null (27197) + +Base: 1638 +Linked animations: [7235, 7236, 7237, 7238, 7239] +Linked NPCs: Giant ant worker (6379), Giant ant soldier (6380) + +Base: 1639 +Linked animations: [7234] +Linked graphics: 1172 + +Base: 1640 +Linked animations: [7229] +Linked graphics: 1171 + +Base: 1641 +Linked animations: [7251] +Linked graphics: 1243 + +Base: 1642 +Linked animations: [7250] +Linked graphics: 1241 + +Base: 1643 +Linked animations: [7256, 7257, 7258, 7259, 7260, 7700, 7701, 7702, 7703, 7704, 7705, 8539] +Linked NPCs: Frog (3783), Barker toad (6889), Barker toad (6890), Barker toad (9482) + +Base: 1644 +Linked animations: [7280, 7281, 7282] + +Base: 1645 +Linked animations: [7294] +Linked graphics: 1246 + +Base: 1646 +Linked animations: [7279] +Linked graphics: 534, 1244, 1544, 1545 + +Base: 1647 + +Base: 1648 +Linked animations: [7284, 7285] +Linked objects: Gargoyle (27274), Gargoyle (27275), Doorway (27276), null (27277) + +Base: 1649 +Linked animations: [7278] + +Base: 1650 +Linked animations: [7283, 7293] +Linked objects: Fishtank (27253) + +Base: 1651 +Linked animations: [7292] +Linked graphics: 1245 + +Base: 1652 +Linked animations: [7286, 7287, 7288, 7289, 7290] +Linked objects: Torch (27241) + +Base: 1653 +Linked animations: [7296] + +Base: 1654 +Linked animations: [7295] +Linked NPCs: Grim Reaper (6390) +Linked objects: Grim Reaper (45802) + +Base: 1655 +Linked animations: [7300] +Linked graphics: 1247 + +Base: 1656 +Linked animations: [7342, 7343] +Linked NPCs: Ghost (6504), null (6505) + +Base: 1657 +Linked animations: [7354] +Linked objects: null (27317), Machine (27320) + +Base: 1658 +Linked animations: [7349, 7350, 7351, 7352, 7353] +Linked objects: null (27316), Fairy portal (27329), Fairy portal (27330) + +Base: 1659 +Linked animations: [7346, 7347, 7348] +Linked objects: Door (27333) + +Base: 1660 + +Base: 1661 +Linked animations: [7334, 7335, 7336] +Linked graphics: 1260, 1261, 1262 + +Base: 1662 +Linked animations: [7345] +Linked graphics: 1269 + +Base: 1663 +Linked animations: [7344] +Linked graphics: 1263 + +Base: 1664 +Linked animations: [7355] +Linked graphics: 1270 + +Base: 1665 +Linked animations: [7337, 7338] +Linked graphics: 1264, 1265 + +Base: 1666 +Linked animations: [7339] +Linked graphics: 1266 + +Base: 1667 +Linked animations: [7340] +Linked graphics: 1267 + +Base: 1668 +Linked animations: [7341] +Linked graphics: 1268 + +Base: 1669 +Linked animations: [7358, 7359, 7360] +Linked objects: Strange box (27654), Strange box (27655), Strange box (27656) + +Base: 1670 +Linked animations: [7356] +Linked objects: null (27570), null (27653), null (27660), null (30338) + +Base: 1671 +Linked animations: [7361] +Linked objects: null (27331), Portal (27567), Portal (27568), null (27571) + +Base: 1672 +Linked animations: [7357] +Linked objects: null (27569), Oozing rock (27615) + +Base: 1673 +Linked animations: [7372] + +Base: 1674 +Linked animations: [7374, 8806] + +Base: 1675 +Linked animations: [7371] + +Base: 1676 +Linked animations: [7373] + +Base: 1677 +Linked animations: [7375, 7396, 7490] +Linked NPCs: Grave marker (6568), Broken grave marker (6569), Collapsing grave marker (6570) +Linked objects: null (27997) + +Base: 1678 + +Base: 1679 +Linked animations: [7511] +Linked graphics: 1278 + +Base: 1680 +Linked animations: [7494, 7495, 8597] +Linked graphics: 1276, 1277 + +Base: 1681 +Linked animations: [7509] +Linked graphics: 1279 + +Base: 1682 +Linked animations: [7386, 7387, 7388] + +Base: 1683 +Linked animations: [7378, 7379, 7380, 7381] +Linked objects: null (28135), null (28136), null (28137), null (28138) + +Base: 1684 + +Base: 1685 +Linked animations: [7411, 7412, 7413, 7414, 7415, 7416, 7417, 7505, 7518] +Linked NPCs: Revenant ork (6610), Revenant ork (6615), Revenant ork (6618), Revenant ork (6624), Revenant ork (6626), Revenant ork (6629), Revenant ork (6633), Revenant ork (6648), Revenant ork (6653), Revenant ork (6664), Revenant ork (6670), Revenant ork (6672), Revenant ork (6690), Revenant ork (6696), Revenant ork (6702), Revenant ork (6713), Revenant ork (6725), Revenant ork (6729) + +Base: 1686 +Linked animations: [7453, 7454, 7455, 7456, 7457, 7458, 7459, 7497, 7510] +Linked NPCs: Revenant cyclops (6645), Revenant cyclops (6687) + +Base: 1687 +Linked animations: [7397, 7398, 7399, 7400, 7401, 7402, 7403, 7496, 7521] +Linked NPCs: Revenant werewolf (6607), Revenant werewolf (6609), Revenant werewolf (6614), Revenant werewolf (6617), Revenant werewolf (6625), Revenant werewolf (6632), Revenant werewolf (6644), Revenant werewolf (6663), Revenant werewolf (6675), Revenant werewolf (6686), Revenant werewolf (6701), Revenant werewolf (6712), Revenant werewolf (6724), Revenant werewolf (6728) + +Base: 1688 +Linked animations: [7404, 7405, 7406, 7407, 7408, 7409, 7410, 7504, 7517] +Linked NPCs: Revenant imp (6604), Revenant imp (6635), Revenant imp (6655), Revenant imp (6666), Revenant imp (6677), Revenant imp (6697), Revenant imp (6703), Revenant imp (6715) + +Base: 1689 +Linked animations: [7460, 7461, 7462, 7463, 7464, 7465, 7466, 7467, 7468, 7469, 7470, 7471, 7472, 7473, 7500, 7501, 7502, 7514, 7515] +Linked NPCs: Revenant hellhound (6646), Revenant dark beast (6649), Revenant hellhound (6688), Revenant dark beast (6691) + +Base: 1690 +Linked animations: [7446, 7447, 7448, 7449, 7450, 7451, 7452, 7499, 7513] +Linked NPCs: Revenant goblin (6605), Revenant goblin (6612), Revenant goblin (6616), Revenant goblin (6620), Revenant goblin (6636), Revenant goblin (6637), Revenant goblin (6638), Revenant goblin (6639), Revenant goblin (6651), Revenant goblin (6656), Revenant goblin (6657), Revenant goblin (6658), Revenant goblin (6667), Revenant goblin (6678), Revenant goblin (6679), Revenant goblin (6680), Revenant goblin (6681), Revenant goblin (6693), Revenant goblin (6698), Revenant goblin (6699), Revenant goblin (6704), Revenant goblin (6705), Revenant goblin (6706), Revenant goblin (6707), Revenant goblin (6716), Revenant goblin (6717), Revenant goblin (6718), Revenant goblin (6719) + +Base: 1691 +Linked animations: [7474, 7475, 7476, 7477, 7478, 7479, 7480, 7498, 7512] +Linked NPCs: Revenant demon (6647), Revenant demon (6689) + +Base: 1692 +Linked animations: [7425, 7426, 7427, 7428, 7429, 7430, 7431, 7507, 7520] +Linked NPCs: Revenant vampire (6613), Revenant vampire (6623), Revenant vampire (6643), Revenant vampire (6652), Revenant vampire (6662), Revenant vampire (6669), Revenant vampire (6671), Revenant vampire (6674), Revenant vampire (6685), Revenant vampire (6695), Revenant vampire (6700), Revenant vampire (6711), Revenant vampire (6723) + +Base: 1693 +Linked animations: [7481, 7482, 7483, 7484, 7485, 7486, 7487, 7506, 7519] +Linked NPCs: Revenant icefiend (6606), Revenant icefiend (6621), Revenant pyrefiend (6622), Revenant icefiend (6628), Revenant pyrefiend (6631), Revenant icefiend (6640), Revenant pyrefiend (6641), Revenant icefiend (6659), Revenant pyrefiend (6660), Revenant pyrefiend (6668), Revenant icefiend (6682), Revenant pyrefiend (6683), Revenant icefiend (6694), Revenant icefiend (6708), Revenant pyrefiend (6709), Revenant icefiend (6720), Revenant pyrefiend (6721) + +Base: 1694 +Linked animations: [7418, 7419, 7420, 7421, 7422, 7423, 7424, 7503, 7516] +Linked NPCs: Revenant hobgoblin (6608), Revenant hobgoblin (6642), Revenant hobgoblin (6661), Revenant hobgoblin (6684), Revenant hobgoblin (6710), Revenant hobgoblin (6722), Revenant hobgoblin (6727) + +Base: 1695 +Linked animations: [7394, 7395, 7489] + +Base: 1696 +Linked animations: [7491, 7492, 7493] + +Base: 1697 +Linked animations: [7488] +Linked graphics: 1274 + +Base: 1698 +Linked animations: [7539, 7540, 7541, 7542, 8447, 8448, 8449, 8450, 11371, 11372] + +Base: 1699 + +Base: 1700 +Linked animations: [7566] +Linked graphics: 1287 + +Base: 1701 +Linked animations: [7569, 7570] +Linked graphics: 1290, 1291 + +Base: 1702 +Linked animations: [7561] +Linked graphics: 1286 + +Base: 1703 +Linked animations: [7547] +Linked graphics: 1283 + +Base: 1704 +Linked animations: [7567] +Linked graphics: 1288 + +Base: 1705 +Linked animations: [7549, 7572] +Linked graphics: 1285, 1292 + +Base: 1706 +Linked animations: [7568] +Linked graphics: 1289 + +Base: 1707 +Linked animations: [7544, 7545, 7548] +Linked graphics: 1284 +Linked objects: Snow (28297) + +Base: 1708 +Linked animations: [7550, 7551] + +Base: 1709 +Linked animations: [7546] +Linked objects: null (28305), null (28306), null (28307), null (28308), null (28309), null (28310), null (28311), null (30336) + +Base: 1710 +Linked animations: [7552] +Linked objects: Stags (28318), Stags (28319), Reindeer (41723), Reindeer (41724) + +Base: 1711 +Linked animations: [7556, 7557, 7558, 7559, 7560, 7562, 7563, 7564, 7565, 7571, 7573, 10480] +Linked NPCs: Barbarian snowman (6742), Dragon snowman (6743), Dwarf snowman (6744), Pirate snowman (6745), Snowman (6746), Snow ranger (6747), Snow warrior (6748), Snow mage (6749) + +Base: 1712 +Linked animations: [7543, 7553, 7554, 7555] +Linked NPCs: Snow (6740), Snow (6741) + +Base: 1713 +Linked animations: [7577] +Linked objects: Cat (28356) + +Base: 1714 +Linked animations: [7876, 7877, 7878, 7879, 7880, 7881, 7882, 7883, 7887, 7891, 8916] +Linked NPCs: Geyser titan (7339), Geyser titan (7340), Geyser titan (9490) + +Base: 1715 +Linked animations: [7955, 7956, 7957, 7958, 7959] + +Base: 1716 +Linked animations: [8301, 8302, 8303, 8304, 8305, 8306, 8308, 8309, 8534] +Linked NPCs: Wolpertinger (6869), Wolpertinger (6870) + +Base: 1717 +Linked animations: [8245, 8246, 8247, 8248, 8249, 8250, 8251, 8252, 12820] +Linked NPCs: Evil turnip (6833), Evil turnip (6834), Rogue evil turnip (9571), Rogue evil turnip (9572), Rogue evil turnip (9573), Rogue evil turnip (9574) + +Base: 1718 +Linked animations: [8021, 8022, 8023, 8024, 8025, 8026, 8029, 8031, 8549, 12826] +Linked NPCs: Bronze minotaur (6853), Bronze minotaur (6854), Iron minotaur (6855), Iron minotaur (6856), Steel minotaur (6857), Steel minotaur (6858), Mithril minotaur (6859), Mithril minotaur (6860), Adamant minotaur (6861), Adamant minotaur (6862), Rune minotaur (6863), Rune minotaur (6864), Rogue adamant minotaur (9599), Rogue adamant minotaur (9600), Rogue adamant minotaur (9601), Rogue adamant minotaur (9602) + +Base: 1719 +Linked animations: [8204, 8205, 8206, 8207, 8208, 8209, 8211, 8212, 8214, 8216, 8533, 12824] +Linked NPCs: Stranger plant (6827), Stranger plant (6828), Rogue stranger plant (9587), Rogue stranger plant (9588), Rogue stranger plant (9589), Rogue stranger plant (9590) + +Base: 1720 +Linked animations: [8281, 8282, 8283, 8284, 8285, 8286, 8287, 8288, 8542] +Linked NPCs: War tortoise (6815), War tortoise (6816), War tortoise (9483) + +Base: 1721 +Linked animations: [7728, 7729, 7730, 7731, 7732, 10954, 10955, 10956, 10957] +Linked NPCs: Wild broav (8487), null (8488), Broav (8491), Broav (9188) + +Base: 1722 +Linked animations: [7863, 7864, 7865, 7866, 7867, 7868, 7869, 7870, 7871, 8255, 8256, 8257, 8258, 8259, 8260, 8927, 8934] +Linked NPCs: Forge regent (7335), Forge regent (7336), Spirit Tz-Kih (7361), Spirit Tz-Kih (7362), Spirit Tz-Kih (9471), Forge regent (9486) + +Base: 1723 +Linked animations: [7961, 7962, 7963, 7964, 7967, 7968, 7969, 7970, 7972, 7974, 8543] +Linked NPCs: Karamthulhu overlord (6809), Karamthulhu overlord (6810), Karamthulhu overlord (9480) + +Base: 1724 +Linked animations: [7923, 7924, 7925, 7926, 7927, 7928, 7929, 7930, 8568] +Linked NPCs: Honey badger (6845), Honey badger (6846) + +Base: 1725 +Linked animations: [7792, 7793, 7794, 7795, 7796, 7797, 7798, 7800, 7803, 7804, 8152, 8153, 8154, 8155, 8156, 8157, 8158, 8159, 8537, 8550] +Linked NPCs: Spirit cobra (6802), Spirit cobra (6803), Desert wyrm (6831), Desert wyrm (6832), Desert wyrm (9470), Spirit cobra (9481) + +Base: 1726 +Linked animations: [7653, 7654, 7655, 7656, 7657, 7711, 7712, 7715, 7717, 8567] +Linked NPCs: Scarab larva (6772), Bloated leech (6843), Bloated leech (6844) + +Base: 1727 +Linked animations: [8076, 8077, 8078, 8079, 8080, 8081, 8082, 8084, 8085, 8930, 9145, 9153, 11211, 12539, 12544] +Linked NPCs: Pyrefiend (1633), Pyrefiend (1634), Pyrefiend (1635), Pyrefiend (1636), Icefiend (3406), Pyrefiend (6216), Icefiend (6217), Pyrelord (7377), Pyrelord (7378), Baby icefiend (7713), Icefiend (7714), Icefiend (7715), null (7716), null (7732), null (7733), null (7734), null (7735), Baby icefiend (7736), Pyrefiend (8598), Pyrefiend (8616), Icefiend (9066), Icefiend (9067), Icefiend (9068), Icefiend (9069), Icefiend (9072), Icefiend (9073), Icefiend (9074), Icefiend (9075), Icefiend (9076), Pyrelord (9477), Icefiend (10212), Icefiend (10213), Icefiend (10214), Icefiend (10215), Icefiend (10216), Icefiend (10217), Icefiend (10218), Pyrefiend (10697) + +Base: 1728 +Linked animations: [7768, 7769, 7770, 7771, 7772, 7773, 7775, 7776, 7777, 8368, 8540, 12817] +Linked NPCs: Compost mound (6871), Compost mound (6872), Compost mound (9473), Rogue compost mound (9563), Rogue compost mound (9564), Rogue compost mound (9565), Rogue compost mound (9566) + +Base: 1729 +Linked animations: [8046, 8047, 8048, 8049, 8050, 8051, 8052, 8053, 8924] +Linked NPCs: Obsidian golem (7345), Obsidian golem (7346), Obsidian golem (9485) + +Base: 1730 +Linked animations: [8141, 8142, 8143, 8144, 8145, 8146, 8147, 8148, 8561, 8911, 12816] +Linked NPCs: Thorny snail (6806), Thorny snail (6807), Snail (7209), Thorny snail (9469), Rogue thorny snail (9559), Rogue thorny snail (9560), Rogue thorny snail (9561), Rogue thorny snail (9562), Ravenous snail (11266) + +Base: 1731 +Linked animations: [7848, 7849, 7850, 7851, 7852, 7853, 7854, 7855, 7858, 8559, 12825] +Linked NPCs: Giant ent (6800), Giant ent (6801), Rogue giant ent (9591), Rogue giant ent (9592), Rogue giant ent (9593), Rogue giant ent (9594) + +Base: 1732 +Linked animations: [7667, 7668, 7669, 7671, 7672, 7675, 7676, 8556, 8910] +Linked NPCs: Abyssal parasite (6818), Abyssal parasite (6819) + +Base: 1733 +Linked animations: [7735, 7736, 7737, 7738, 7739, 7740, 7741, 7746, 7747, 8547] +Linked NPCs: Bunyip (6813), Bunyip (6814) + +Base: 1734 +Linked animations: [7977, 7978, 7979, 7980, 7981, 7982, 7986, 7987, 8928] +Linked NPCs: Lava titan (7341), Lava titan (7342), Lava titan (9489) + +Base: 1735 +Linked animations: [8233, 8234, 8235, 8236, 8237, 8238, 8239, 8243, 8921] +Linked NPCs: Void torcher (7351), Void torcher (7352) + +Base: 1736 +Linked animations: [8112, 8113, 8114, 8115, 8116, 8117, 8118, 8122, 8548] +Linked NPCs: Granite lobster (6849), Granite lobster (6850) + +Base: 1737 +Linked animations: [7780, 7781, 7782, 7783, 7784, 7785, 7786, 7787, 7791, 8560] +Linked NPCs: Spirit dagannoth (6804), Spirit dagannoth (6805) + +Base: 1738 +Linked animations: [8343, 8344, 8345, 8346, 8347, 8348, 8349, 8350] +Linked NPCs: Baby monkey (6942), Monkey (6943), Baby monkey (6944), Baby monkey (7210), Monkey (7211), Baby monkey (7212), Monkey (7213), Baby monkey (7214), Monkey (7215), Baby monkey (7216), Monkey (7217), Baby monkey (7218), Monkey (7219), Baby monkey (7220), Monkey (7221), Baby monkey (7222), Monkey (7223), Baby monkey (7224), Monkey (7225), Baby monkey (7226), Monkey (7227), Baby monkey (7228), Baby monkey (7229), Baby monkey (7230), Baby monkey (7231), Baby monkey (7232), Baby monkey (7233), Baby monkey (7234), Baby monkey (7235), Baby monkey (7236), Monkey (9223), Monkey (9224), Monkey (9225), Monkey (9226), Monkey (9227), Monkey (9228), Monkey (9229), Monkey (9230), Monkey (9231), Monkey (9232), Dealga (11475) + +Base: 1739 +Linked animations: [8064, 8065, 8066, 8067, 8068, 8069, 8070, 8071, 8072, 8075, 8558] +Linked NPCs: Praying mantis (6798), Praying mantis (6799) + +Base: 1740 +Linked animations: [7687, 7688, 7689, 7690, 7691, 7692, 7693, 7694, 7698, 7837, 7838, 7839, 7840, 7841, 7842, 7843, 7844, 7845, 7846, 7847, 7946, 7947, 7948, 7949, 7950, 7951, 7952, 7954, 8183, 8184, 8185, 8186, 8187, 8188, 8189, 8190, 8196, 8914, 8918, 8923, 8926, 12818] +Linked NPCs: Steel titan (7343), Steel titan (7344), Abyssal titan (7349), Abyssal titan (7350), Moss titan (7357), Moss titan (7358), Ice titan (7359), Ice titan (7360), Iron titan (7375), Iron titan (7376), Rogue ice titan (9595), Rogue ice titan (9596), Rogue ice titan (9597), Rogue ice titan (9598) +Linked graphics: 1443 + +Base: 1741 +Linked animations: [7814, 7815, 7816, 7817, 7818, 7819, 7820, 7821, 7824, 8530] +Linked NPCs: Smoke devil (6865), Smoke devil (6866) + +Base: 1742 +Linked animations: [8128, 8129, 8130, 8131, 8132, 8133, 8134, 8139, 8919] +Linked NPCs: Void shifter (7367), Void shifter (7368), Void shifter (7369) + +Base: 1743 +Linked animations: [2016, 2017, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026, 7643, 7644, 7645, 7646, 7647, 7648, 7649, 7658, 7659, 7677, 7678, 7679, 7680, 7681, 7682, 7683, 7684, 8197, 8198, 8199, 8200, 8201, 8202, 8313, 8552, 8564] +Linked NPCs: Vulture (3675), Vulture (3676), Vulture (6792), Abyssal lurker (6820), Abyssal lurker (6821), Vulture (6946), Ibis (6991), Vulture (7320), Vulture (7322), Vulture (7324), Vulture (7326), Vulture (7328), Vulture (9256), Vulture (9257), Vulture (9258), Vulture (9259), Vulture (9260), Vulture (9261) + +Base: 1744 +Linked animations: [7670, 8171, 8172, 8173, 8174, 8175, 8176, 8179, 8181, 8182, 8920, 12819] +Linked NPCs: Void spinner (7333), Void spinner (7334), Rogue void spinner (9567), Rogue void spinner (9568), Rogue void spinner (9569), Rogue void spinner (9570) + +Base: 1745 +Linked animations: [7893, 7894, 7895, 7896, 7897, 7898, 7899, 7900, 7903, 8032, 8033, 8034, 8035, 8036, 8037, 8038, 8039, 8040, 8041, 8042, 8554, 8915] +Linked NPCs: Bull ant (6867), Bull ant (6868), Spirit mosquito (7331), Spirit mosquito (7332) +Linked graphics: 1439, 1440, 1441, 1442 + +Base: 1746 +Linked animations: [7934, 7935, 7936, 7937, 7938, 7939, 7940, 7941, 7945, 8538] +Linked NPCs: Hydra (6811), Hydra (6812), Hydra (9488), Hydra (10610), Hydra (10611), Hydra (10612), Hydra (10613), Hydra (10614), Hydra (10615), Hydra (10616), Hydra (10617), Hydra (10618) + +Base: 1747 +Linked animations: [8086, 8087, 8088, 8089, 8090, 8091, 8092, 8093, 8094, 8097, 8929, 8937] +Linked NPCs: Void ravager (7370), Void ravager (7371), Void ravager (9476) + +Base: 1748 +Linked animations: [7718, 7719, 7720, 7721, 7722, 7724, 7726, 7727, 8535] +Linked NPCs: Raccoon (3286), Raccoon (3287), Raccoon (3288), Beaver (6808), Baby raccoon (6913), Raccoon (6914), Baby raccoon (6997), Baby raccoon (7271), Raccoon (7272), Baby raccoon (7273), Raccoon (7274), Baby Raccoon (7275), Baby raccoon (7276), Raccoon (9236), Raccoon (9237), Raccoon (9238), Beaver (9475) + +Base: 1749 +Linked animations: [7750, 7751, 7752, 7753, 7754, 7755, 7756, 7758, 8922, 12822] +Linked NPCs: Giant chinchompa (7353), Giant chinchompa (7354), Rogue giant chinchompa (9579), Rogue giant chinchompa (9580), Rogue giant chinchompa (9581), Rogue giant chinchompa (9582) + +Base: 1750 +Linked animations: [384, 392, 405, 8324, 8325, 8326, 8327, 8328, 12266] +Linked NPCs: Squirrel (3284), Squirrel (3285), Baby squirrel (6919), Squirrel (6920), Baby squirrel (6921), Baby squirrel (7301), Squirrel (7302), Baby squirrel (7303), Squirrel (7304), Baby squirrel (7305), Squirrel (7306), Baby squirrel (7307), Squirrel (7308), Baby squirrel (7309), Baby squirrel (7310), Baby squirrel (7311), Baby squirrel (7312), Fluffy (7413), Beny (7414), Bubbles (7415), Big Ben (7416), Sparky (9170), Squirrel (9250), Squirrel (9251), Squirrel (9252), Squirrel (9253), Squirrel (9254), Charlie the squirrel (9681), Fluffy (9682), Charlie the squirrel (9686), Fluffy (9692), Beny (9693), Bubbles (9694), Big Ben (9695) +Linked graphics: 2145 + +Base: 1751 +Linked animations: [7828, 7829, 7830, 7831, 7832, 7833, 7834, 7835, 8925] +Linked NPCs: Fire titan (7355), Fire titan (7356), Fire titan (9487) + +Base: 1752 +Linked animations: [7991, 7992, 7993, 7994, 7995, 7996, 7997, 7998, 7999, 8000, 8001, 8931] +Linked NPCs: Ravenous locust (7372), Ravenous locust (7373), Ravenous locust (7374), Ravenous locust (9484) + +Base: 1753 +Linked animations: [8219, 8220, 8221, 8222, 8223, 8224, 8225, 8226, 8932] +Linked NPCs: Swamp titan (7329), Swamp titan (7330) + +Base: 1754 +Linked animations: [8363, 8364, 8365] +Linked NPCs: Baby chameleon (6922), Chameleon (6923), Baby chameleon (6924), Chameleon (6925), Baby chameleon (6926), Chameleon (6927), Baby chameleon (6928), Chameleon (6929), Baby chameleon (6930), Chameleon (6931), Baby chameleon (6932), Chameleon (6933), Baby chameleon (6934), Chameleon (6935), Baby chameleon (6936), Chameleon (6937), Baby chameleon (6938), Chameleon (6939), Baby chameleon (6940), Chameleon (6941), Karma the chameleon (8580), Karma the chameleon (8581), Karma the chameleon (8582), Karma the chameleon (8583), Karma the chameleon (8584), Karma the chameleon (8585), Karma the chameleon (8586), Karma the chameleon (8587), Karma the chameleon (8588), Karma the chameleon (8589), Chameleon (9262), Chameleon (9263), Chameleon (9264), Chameleon (9265), Chameleon (9266), Chameleon (9267), Chameleon (9268), Chameleon (9269), Chameleon (9270), Chameleon (9271) + +Base: 1755 +Linked animations: [7759, 7760, 7761, 7762, 7763, 7764, 7765, 7766, 8551, 12821] +Linked NPCs: Cockatrice (1620), Cockatrice (1621), Spirit cockatrice (6875), Spirit cockatrice (6876), Spirit guthatrice (6877), Spirit guthatrice (6878), Spirit saratrice (6879), Spirit saratrice (6880), Spirit zamatrice (6881), Spirit zamatrice (6882), Spirit pengatrice (6883), Spirit pengatrice (6884), Spirit coraxatrice (6885), Spirit coraxatrice (6886), Spirit vulatrice (6887), Spirit vulatrice (6888), Chocatrice (7201), Minitrice (8620), Minitrice (9247), Rogue spirit coraxatrice (9575), Rogue spirit coraxatrice (9576), Rogue spirit coraxatrice (9577), Rogue spirit coraxatrice (9578) + +Base: 1756 +Linked animations: [7602] +Linked objects: Power indicator (28521), Power indicator (28522), Power indicator (28523), Power indicator (28524), null (31352) + +Base: 1757 +Linked animations: [7603] +Linked objects: null (28371), null (32576) + +Base: 1758 +Linked animations: [7634] + +Base: 1759 +Linked animations: [7600] +Linked objects: Steam (28532), Steam (28533) + +Base: 1760 +Linked animations: [7601] +Linked objects: Furnace (28433), null (28534) + +Base: 1761 +Linked animations: [7604, 7605, 7606, 7607, 7608, 7609, 7610, 7611, 7612, 7613, 7614, 7615, 7616, 7617, 7618, 7619, 7620, 7621, 7622, 9376] +Linked NPCs: Scarab mage (5250), Scarab mage (5254), Scabaras ranger (6773), Scabaras lancer (6774), Scabaras priest (6775), Scabaras mage (6780), Scabaras mage (6781), High Priest of Scabaras (6788), High Priest of Scabaras (6789), High Priest of Scabaras (6790), High Priest of Scabaras (6791), Insectoid assassin (7795), Insectoid assassin (7796), Pit scarabite (11565), Pit scabarite (11590), Pit scabarite (11591) +Linked objects: Pit scabarite (39263), Pit scabarite (41606) + +Base: 1762 +Linked animations: [7587, 7588, 7589, 7590, 7591] +Linked NPCs: Crocodile (1993), Crocodile (6779) + +Base: 1763 +Linked animations: [8624, 8647, 12299] +Linked objects: Fire (3769), Sacrificial Pyre (4767), Cooking fire (29094), null (29098), Fire (29139), Fire pit (29155), null (29176), null (29177), null (29178), null (29179), null (29180), null (31692), null (31693), Tomb (34299), Fire (37726), Campfire (38165), null (38167), null (44166), null (44178), Fire pit (44371), null (44392), Spit-roast (45090), Spitroast (45313), Sacrificial Pyre (46399), null (46400), Campfire (52709) + +Base: 1764 +Linked animations: [7953] +Linked graphics: 1450 + +Base: 1765 +Linked animations: [7920, 7921] +Linked graphics: 1370, 1371 + +Base: 1766 +Linked animations: [7983] +Linked graphics: 1490 + +Base: 1767 +Linked animations: [7917] +Linked graphics: 1368 + +Base: 1768 +Linked animations: [8588] +Linked graphics: 1523 + +Base: 1769 +Linked animations: [7960] +Linked graphics: 1359 + +Base: 1770 +Linked animations: [8367] +Linked graphics: 1360 + +Base: 1771 +Linked animations: [8015] +Linked graphics: 1321 + +Base: 1772 +Linked animations: [7985, 8121, 8194] +Linked graphics: 1353, 1381, 1448, 1455 + +Base: 1773 +Linked animations: [8210] +Linked graphics: 1509 + +Base: 1774 +Linked animations: [8213] +Linked graphics: 1508 + +Base: 1775 +Linked animations: [7662] +Linked graphics: 1295, 1296, 1297, 1298, 1299, 1300, 1301, 1302, 1303, 1304, 1305, 1306, 1307, 1308, 1309, 1310, 1311, 1313 + +Base: 1776 +Linked animations: [8289, 8290] +Linked graphics: 1414, 1415 + +Base: 1777 +Linked animations: [8030] +Linked graphics: 1498 + +Base: 1778 +Linked animations: [8027] +Linked graphics: 1496 + +Base: 1779 +Linked animations: [7734] +Linked graphics: 1345 + +Base: 1780 +Linked animations: [8278, 8280] +Linked graphics: 1324, 1325 + +Base: 1781 +Linked animations: [8191, 8192] +Linked graphics: 1444, 1445 + +Base: 1782 +Linked animations: [8073, 8074] +Linked graphics: 1379, 1380 + +Base: 1783 +Linked animations: [8063] +Linked graphics: 1408 + +Base: 1784 +Linked animations: [8111] +Linked graphics: 1327 + +Base: 1785 +Linked animations: [8203, 8322] +Linked graphics: 1331, 1337 + +Base: 1786 +Linked animations: [7856] +Linked graphics: 1361 + +Base: 1787 +Linked animations: [7872, 7873, 7874] +Linked graphics: 1393, 1394, 1395 + +Base: 1788 +Linked animations: [7901, 7902] +Linked graphics: 1382, 1383 + +Base: 1789 +Linked animations: [8299, 8300] +Linked graphics: 1333, 1334, 1349, 1350 + +Base: 1790 +Linked animations: [7975, 7976] +Linked graphics: 1478, 1479 + +Base: 1791 +Linked animations: [8264] +Linked graphics: 1486 + +Base: 1792 +Linked animations: [8262] +Linked graphics: 1329, 1484 + +Base: 1793 +Linked animations: [7699] +Linked graphics: 1457 + +Base: 1794 +Linked animations: [7965, 7966, 7971, 7973] +Linked graphics: 1474, 1475, 1476, 1477 + +Base: 1795 +Linked animations: [7922] +Linked graphics: 1372 + +Base: 1796 +Linked animations: [8323] +Linked graphics: 1332 + +Base: 1797 +Linked animations: [7931, 7932, 7933] +Linked graphics: 1397, 1398, 1399 + +Base: 1798 +Linked animations: [7713, 7714, 7716] +Linked graphics: 1416, 1417, 1418, 1419, 1420, 1421 + +Base: 1799 +Linked animations: [8083] +Linked graphics: 1463 + +Base: 1800 +Linked animations: [7757] +Linked graphics: 1364 + +Base: 1801 +Linked animations: [7875] +Linked graphics: 1396 + +Base: 1802 +Linked animations: [8938] +Linked graphics: 1575 + +Base: 1803 +Linked animations: [7733] +Linked graphics: 1344 + +Base: 1804 +Linked animations: [8110] +Linked graphics: 1326 + +Base: 1805 +Linked animations: [8195] +Linked graphics: 1449 + +Base: 1806 +Linked animations: [7778, 7779] +Linked graphics: 1424, 1425 + +Base: 1807 +Linked animations: [8160] +Linked graphics: 1389 + +Base: 1808 +Linked animations: [7988, 7989, 7990] +Linked graphics: 1492, 1493, 1494 + +Base: 1809 +Linked animations: [8180] +Linked graphics: 1507 + +Base: 1810 +Linked animations: [7827] +Linked graphics: 1473 + +Base: 1811 +Linked animations: [8096] +Linked graphics: 1438 + +Base: 1812 +Linked animations: [8166] +Linked graphics: 1340 + +Base: 1813 +Linked animations: [7790] +Linked graphics: 1427 + +Base: 1814 +Linked animations: [8055] +Linked graphics: 1466 + +Base: 1815 +Linked animations: [8054] +Linked graphics: 1465 + +Base: 1816 +Linked animations: [7685, 7686] +Linked graphics: 1338, 1339 + +Base: 1817 +Linked animations: [8193] +Linked graphics: 1446, 1447, 1495 + +Base: 1818 +Linked animations: [7788, 7789] +Linked graphics: 1426, 1428 + +Base: 1819 +Linked animations: [8270] +Linked graphics: 1323 + +Base: 1820 +Linked animations: [8028] +Linked graphics: 1497 + +Base: 1821 +Linked animations: [7942] +Linked graphics: 1488 + +Base: 1822 +Linked animations: [8227, 8228] +Linked graphics: 1521 + +Base: 1823 +Linked animations: [7673, 7674] +Linked graphics: 1422, 1423 + +Base: 1824 +Linked animations: [8369] +Linked graphics: 1312 + +Base: 1825 +Linked animations: [7908] +Linked graphics: 1384 + +Base: 1826 +Linked animations: [7748] +Linked graphics: 1481 + +Base: 1827 +Linked animations: [8261] +Linked graphics: 1483 + +Base: 1828 +Linked animations: [8060, 8061, 8062] +Linked graphics: 1405, 1406, 1407 + +Base: 1829 +Linked animations: [8018, 8019] +Linked graphics: 1335, 1336 + +Base: 1830 +Linked animations: [7799, 7805, 8095, 8616, 8617] +Linked graphics: 1409, 1412, 1437, 1524, 1525 + +Base: 1831 +Linked animations: [8232, 8240, 8241, 8242, 8244] +Linked graphics: 1429, 1430, 1431, 1432, 1433 + +Base: 1832 +Linked animations: [8215] +Linked graphics: 1510 + +Base: 1833 +Linked animations: [8218] +Linked graphics: 1462 + +Base: 1834 +Linked animations: [8168] +Linked graphics: 1342 + +Base: 1835 +Linked animations: [7695, 7696] +Linked graphics: 1451, 1452, 1453, 1454 + +Base: 1836 +Linked animations: [7663, 7664, 7665, 7666, 10067, 10231] +Linked graphics: 1314, 1315, 1319, 1738, 1739, 1777, 2744 + +Base: 1837 +Linked animations: [7943] +Linked graphics: 1489 + +Base: 1838 +Linked animations: [7749] +Linked graphics: 1482 + +Base: 1839 +Linked animations: [7944] +Linked graphics: 1487 + +Base: 1840 +Linked animations: [7885] +Linked graphics: 1374 + +Base: 1841 +Linked animations: [8177] +Linked graphics: 1505 + +Base: 1842 +Linked animations: [8366] +Linked graphics: 1480, 1652 + +Base: 1843 +Linked animations: [8268, 8269] +Linked graphics: 1356, 1357 + +Base: 1844 +Linked animations: [7825] +Linked graphics: 1472 + +Base: 1845 +Linked animations: [7822, 7823, 7826] +Linked graphics: 1470, 1471 + +Base: 1846 +Linked animations: [7812] +Linked graphics: 1318 + +Base: 1847 +Linked animations: [7706, 7707, 7708] +Linked graphics: 1400, 1401, 1402 + +Base: 1848 +Linked animations: [8057] +Linked graphics: 1358 + +Base: 1849 +Linked animations: [8135, 8138, 8140] +Linked graphics: 1499, 1500, 1501, 1502, 1503, 1506, 2006 + +Base: 1850 +Linked animations: [8016] +Linked graphics: 1322 + +Base: 1851 +Linked animations: [8120] +Linked graphics: 1352 + +Base: 1852 +Linked animations: [8017] +Linked graphics: 1320 + +Base: 1853 +Linked animations: [7860] +Linked graphics: 1390 + +Base: 1854 +Linked animations: [8169] +Linked graphics: 1343 + +Base: 1855 +Linked animations: [7709] +Linked graphics: 1403 + +Base: 1856 +Linked animations: [8167] +Linked graphics: 1341 + +Base: 1857 +Linked animations: [7697] +Linked graphics: 1456 + +Base: 1858 +Linked animations: [8178] +Linked graphics: 1504 + +Base: 1859 +Linked animations: [8253, 8254] +Linked graphics: 1328, 1330 + +Base: 1860 +Linked animations: [7710] +Linked graphics: 1404, 1511 + +Base: 1861 +Linked animations: [7723, 7725] +Linked graphics: 1458, 1459 + +Base: 1862 +Linked animations: [7801, 7802, 7806] +Linked graphics: 1410, 1411, 1413 + +Base: 1863 +Linked animations: [8149, 8150, 8151] +Linked graphics: 1385, 1386, 1387 + +Base: 1864 +Linked animations: [8263] +Linked graphics: 1485 + +Base: 1865 +Linked animations: [8125, 8126] +Linked graphics: 1354, 1355 + +Base: 1866 +Linked animations: [7836] +Linked graphics: 1512, 1513, 1514 + +Base: 1867 +Linked animations: [8002, 8003, 8004] +Linked graphics: 1346, 1347, 1348 + +Base: 1868 +Linked animations: [7742, 7743, 7744] +Linked graphics: 1434, 1435, 1436 + +Base: 1869 +Linked animations: [7811] +Linked graphics: 1317 + +Base: 1870 +Linked animations: [8217] +Linked graphics: 1460, 1461 + +Base: 1871 +Linked animations: [7884, 7886, 7888, 7889, 7890] +Linked graphics: 1373, 1375, 1376, 1377, 1378 + +Base: 1872 +Linked animations: [7857, 7859] +Linked graphics: 1362, 1363 + +Base: 1873 +Linked animations: [7984] +Linked graphics: 1491 + +Base: 1874 +Linked animations: [8161] +Linked graphics: 1388 + +Base: 1875 +Linked animations: [7861, 7862] +Linked graphics: 1391, 1392 + +Base: 1876 +Linked animations: [7767] +Linked graphics: 1469 + +Base: 1877 +Linked animations: [1642, 8495] +Linked graphics: 1515 + +Base: 1878 +Linked animations: [8415, 8416, 8417, 8418] + +Base: 1879 +Linked animations: [8399, 8400, 8401, 8402] + +Base: 1880 +Linked animations: [8427, 8428, 8429, 8430] + +Base: 1881 +Linked animations: [8376, 8377, 8378, 8379] + +Base: 1882 +Linked animations: [8411, 8412, 8413, 8414] + +Base: 1883 +Linked animations: [8451, 8452, 8453, 8454, 8491, 8492, 8493, 8494] + +Base: 1884 +Linked animations: [8423, 8424, 8425, 8426] + +Base: 1885 +Linked animations: [8395, 8396, 8397, 8398, 10554] + +Base: 1886 +Linked animations: [8431, 8432, 8433, 8434] + +Base: 1887 +Linked animations: [8443, 8444, 8445, 8446, 9315, 9316, 9317, 9318, 9319] + +Base: 1888 +Linked animations: [8419, 8420, 8421, 8422] + +Base: 1889 +Linked animations: [8479, 8480, 8481, 8482] + +Base: 1890 +Linked animations: [8467, 8468, 8469, 8470] + +Base: 1891 +Linked animations: [8435, 8436, 8437, 8438, 8439, 8440, 8441, 8442, 8455, 8456, 8457, 8458, 8459, 8460, 8461, 8462] + +Base: 1892 +Linked animations: [8463, 8464, 8465, 8466] + +Base: 1893 +Linked animations: [8471, 8472, 8473, 8474] + +Base: 1894 +Linked animations: [8487, 8488, 8489, 8490] + +Base: 1895 +Linked animations: [8483, 8484, 8485, 8486] + +Base: 1896 +Linked animations: [8407, 8408, 8409, 8410] + +Base: 1897 +Linked animations: [8504, 8505, 8506, 8507] +Linked NPCs: Giant wolpertinger (6990) + +Base: 1898 +Linked animations: [8503, 8508] +Linked graphics: 1516, 1517 + +Base: 1899 +Linked animations: [8587] +Linked graphics: 1522 + +Base: 1900 +Linked animations: [8526] +Linked objects: Wishing well (28715) + +Base: 1901 +Linked animations: [8509, 8510] +Linked objects: Obelisk (28716), Inert obelisk (28717), Inert obelisk (28718), Obelisk (28719), Inert obelisk (28720), Inert obelisk (28721), Obelisk (28722), Inert obelisk (28723), Inert obelisk (28724), Obelisk (28725), Inert obelisk (28726), Inert obelisk (28727), Obelisk (28728), Inert obelisk (28729), Inert obelisk (28730), Obelisk (28731), Inert obelisk (28732), Inert obelisk (28733), Obelisk (28734), Inert obelisk (28735), Inert obelisk (28736), Small obelisk (29882), Small obelisk (29938), Small obelisk (29939), Small obelisk (29940), Small obelisk (29941), Small obelisk (29942), Small obelisk (29943), Small obelisk (29944), Small obelisk (29945), Small obelisk (29946), Small obelisk (29947), Small obelisk (29948), Small obelisk (29949), Small obelisk (29950), Small obelisk (29951), Small obelisk (29952), Small obelisk (29953), Small obelisk (29954), Small obelisk (29955), Small obelisk (29956), Small obelisk (29957), Small obelisk (29958), Small obelisk (29959), Small obelisk (44837), Small obelisk (44838), Small obelisk (44839), Small obelisk (44840), Small obelisk (44841), Small obelisk (44842), PLACEHOLDER: Summoning Obelisk (50204) + +Base: 1902 +Linked animations: [8521] +Linked graphics: 1520 + +Base: 1903 +Linked animations: [8513, 8514, 8515, 8562, 8569, 8570, 8571, 8572, 8575, 11210] +Linked NPCs: Jelly (1637), Jelly (1638), Jelly (1639), Jelly (1640), Jelly (1641), Jelly (1642), Spirit jelly (6992), Spirit jelly (6993), Jelly (7459), Jelly (7460), Jelly (8599), Jelly (8617), Jelly (10699) + +Base: 1904 +Linked animations: [8520] +Linked graphics: 1519 + +Base: 1905 +Linked animations: [2090, 2100, 2101, 2102, 3380, 3381, 3460, 3462, 8573, 8574, 8576, 8577, 8578, 8620, 8621, 8622, 8626, 8627, 8628, 8629, 8630, 8631, 8632, 8633, 8634, 8635, 8636, 8637, 8638, 8639, 8640, 8641, 8642, 8643, 8644, 8649, 8650, 8655, 10625, 10626, 11295, 11296, 11302, 11358, 11375, 11403, 11404, 11405, 11415, 11416, 11417, 11418, 11419, 11420, 11421, 11422, 11423, 11424, 11425, 11426, 11427, 11428, 11431, 11432, 11433, 11434, 11435, 11436, 11437, 11438, 11439, 11441, 11442, 11443, 11444, 11445, 11446, 11448, 11449, 11450, 11454, 11457, 11458, 11459, 11460, 11461, 12302, 12512, 13837, 13838, 13839] +Linked NPCs: Jogre (113), Mogre (114), Ogre (115), Khazard ogre (270), Ogre (374), Og (853), Grew (854), Toban (855), Gorad (856), Ogre guard (857), Ogre guard (858), Ogre guard (859), Ogre guard (860), Ogre guard (861), City guard (862), Enclave guard (870), Ogre trader (873), Ogre merchant (874), Ogre trader (875), Ogre trader (876), Kolodion (908), Rantz (1010), Fycie (1011), Bugs (1012), Grish (2038), Uglug Nar (2039), Pilg (2040), Grug (2041), Ogre guard (2042), Ogre guard (2043), Zogre (2044), Zogre (2045), Zogre (2046), Zogre (2047), Zogre (2048), Zogre (2049), Skogre (2050), Zogre (2051), Zogre (2052), Zogre (2053), Zogre (2054), Zogre (2055), Skogre (2056), Skogre (2057), Slash Bash (2060), Gargh (2063), Scarg (2064), Gruh (2065), Ogre shaman (2417), Ogre shaman (2418), Grunsh (2419), Ogre shaman (2434), Ogre (2801), Jogre Champion (3063), Skrach Uglogwee (3398), Ogre (3419), Mogre Guard (3420), Jogre (3449), Jogre (3450), Ogre (3451), Nung (3465), Ogre (3466), Rantz (3467), Rantz (3468), Rantz (3587), null (4471), Bogrog (4472), Ogre chieftain (5174), Jogre (6268), Frawd (7048), Ogress banker (7049), Ogress banker (7050), Chief Tess (7051), Seegud (7052), Chargurr (7053), Chargurr (7054), null (7055), null (7056), Snurgh (7057), Kringk (7058), Thump (7061), Muggh (7062), Snert (7067), Tyke (7068), Snarrl (7069), Snarrk (7070), I'rk (7071), Thuddley (7072), Grr'bah (7073), Chomp (7074), Grubb (7075), Grunther (7076), Glum (7077), Ogress champion (7078), Ogress warrior (7079), Ogress warrior (7080), Ogress (7081), Ogress (7082), Ogre statue (7085), Chief Tess (7088), Chargurr (7089), null (7099), null (7101), null (7522), Mystic (8232), Mystic (8237), Ogre (8658), null (8659), Ogre shaman (8798), Ogre (9184), Ogre (9185), Pit ogre (11563), Pit ogre (11586), Pit ogre (11587) +Linked objects: Pit ogre (39261), Pit ogre (41604), Ogre statue (42592), Ogre statue (42593), Ogre statue (42605), Ogre statue (42608) + +Base: 1906 +Linked animations: [8579, 8580, 8583, 8584, 8585, 8586, 8598, 8656, 8657, 8658, 8659, 8660, 8661, 8662] + +Base: 1907 +Linked animations: [8589, 8590, 8591, 8592, 8593, 8594, 8595, 8596] + +Base: 1908 +Linked animations: [8599, 8600, 8601, 8602, 8603, 8604, 8605, 8606, 8607] +Linked NPCs: Grenwall (7010), Grenwall (7011) + +Base: 1909 +Linked animations: [8608, 8609, 8610, 8611, 8612, 8613, 8614, 8615] +Linked NPCs: Pawya (7012), Pawya (7014) + +Base: 1910 +Linked animations: [8625] + +Base: 1911 +Linked animations: [8645] + +Base: 1912 +Linked animations: [8668, 8669, 8670, 8671, 8672, 8673, 8680] +Linked NPCs: Platypus (7015), Platypus (7016), Platypus (7017), Baby platypus (7018), Baby platypus (7019), Baby platypus (7020), Platypus (7021), Platypus (7022), Platypus (7023), Baby platypus (7024), Baby platypus (7025), Baby platypus (7026), Patrick (7027), Penelope (7028), Peter (7029), Peanut (7030), null (7091), null (7092), null (7093), null (7094), null (7095), null (7096), null (7097), null (7098), Platypus (9304), Platypus (9305), Platypus (9306) + +Base: 1913 +Linked animations: [8619] +Linked NPCs: Thump (7059) + +Base: 1914 +Linked animations: [8618] +Linked objects: null (4105), Salon customer (29103) + +Base: 1915 +Linked animations: [8646] +Linked objects: Grimechin (29106), null (29108) + +Base: 1916 +Linked animations: [8654] +Linked objects: null (29121) + +Base: 1917 +Linked animations: [8653] +Linked objects: null (29083) + +Base: 1918 +Linked animations: [8664] +Linked objects: Sulphur spring (29016), Sulphur spring (29017), Rocks (29019), Sulphur spring (29021), Sulphur spring (29023), Sulphur spring (29026), Sulphur spring (29028) + +Base: 1919 +Linked animations: [8648, 8667] +Linked NPCs: Flying bugs (7083) +Linked objects: null (29170), null (29171), null (29172), null (29173), null (29174), null (29175) + +Base: 1920 +Linked animations: [8665] +Linked objects: Thermal bath (29043), Rocks (29045), Thermal bath (29047), Thermal bath (29049), Thermal bath (29052), Thermal bath (29054) + +Base: 1921 +Linked animations: [8666] +Linked objects: Salt-water spring (29030), Rocks (29032), Salt-water spring (29034), Salt-water spring (29036), Salt-water spring (29039), Salt-water spring (29041), Bandos pool (29056), Rocks (29058), Bandos pool (29060), Bandos pool (29062), Bandos pool (29063), Bandos pool (29065), Bandos pool (29066), Bandos pool (29067) + +Base: 1922 +Linked animations: [8663] +Linked objects: Mud bath (29002), Mud bath (29003), Rocks (29004), Rocks (29005), Mud bath (29007), Mud bath (29009), Mud bath (29012), Mud bath (29014) + +Base: 1923 +Linked animations: [11455, 11456] +Linked graphics: 2025, 2026 + +Base: 1924 +Linked animations: [8696] +Linked graphics: 1535 + +Base: 1925 +Linked animations: [8623, 8652] +Linked graphics: 1527, 1528 + +Base: 1926 +Linked animations: [8674, 8675, 8676, 8677, 8678, 8679] +Linked graphics: 1529, 1530, 1531, 1532, 1533, 1534 + +Base: 1927 +Linked animations: [8697] +Linked graphics: 1536 + +Base: 1928 +Linked animations: [11452, 11453] +Linked NPCs: null (3469), null (3470), Ogre boat (3471), Ogre boat (3472) + +Base: 1929 +Linked animations: [11451] + +Base: 1930 +Linked animations: [2415, 11818] +Linked graphics: 1019, 1537 +Linked objects: null (43520) + +Base: 1931 +Linked animations: [2419, 8703] +Linked graphics: 1539, 1540 + +Base: 1932 +Linked animations: [1221] + +Base: 1933 +Linked animations: [1220] + +Base: 1934 +Linked animations: [1222, 1223, 1224, 1225, 1226, 1227, 1228, 9664, 9722] +Linked objects: Catapult (2781), null (3976), Catapult (29436), Rotten Catapult (29437), Catapult (29438) + +Base: 1935 +Linked animations: [2416, 2417, 2418, 8700, 9576] +Linked graphics: 1538, 1669 +Linked objects: Explosion (18504), null (29429), null (29430), null (29431), Target rock (29433) + +Base: 1936 +Linked animations: [8714] +Linked objects: null (29521) + +Base: 1937 +Linked animations: [8713] + +Base: 1938 +Linked animations: [8708, 8712] +Linked graphics: 1541 +Linked objects: Flag (29457), Flag (29459) + +Base: 1939 +Linked animations: [8716] +Linked graphics: 1543 + +Base: 1940 +Linked animations: [8715] +Linked graphics: 1542 + +Base: 1941 +Linked animations: [8752, 8753, 8754, 8755, 8756, 8757, 8758] +Linked NPCs: Bork (7133), Bork (7134) + +Base: 1942 + +Base: 1943 +Linked animations: [8751, 8760, 8761, 8762, 8763, 8764, 8765] +Linked NPCs: Ork legion (7135) + +Base: 1944 +Linked animations: [8741, 8742, 8743] +Linked graphics: 1546, 1547, 1548 + +Base: 1945 +Linked animations: [8749] +Linked graphics: 1549 + +Base: 1946 +Linked animations: [8759] +Linked graphics: 1551 + +Base: 1947 +Linked animations: [8750] +Linked graphics: 1550 + +Base: 1948 +Linked animations: [8748, 8766, 10964] +Linked graphics: 1552, 1951 + +Base: 1949 +Linked animations: [8745, 8746] + +Base: 1950 +Linked animations: [8744] + +Base: 1951 +Linked animations: [8747] + +Base: 1952 +Linked animations: [8802, 8803] + +Base: 1953 +Linked animations: [8769] +Linked graphics: 1553 + +Base: 1954 +Linked animations: [8801] +Linked graphics: 1554 + +Base: 1955 +Linked animations: [8785, 8786, 8787, 8788, 8789, 8790, 8791, 8792, 8793, 8794, 8795, 8796, 8797, 8798, 8799] +Linked NPCs: Cockroach drone (7158), Cockroach worker (7159), Cockroach soldier (7160), Cockroach (7206), Warped cockroach (7913) + +Base: 1956 +Linked animations: [8857] +Linked objects: null (29800), null (29801), null (29802), Barrel (29803), Broken lobster trap (29804), null (29805) + +Base: 1957 +Linked animations: [8880, 8881] +Linked objects: Villagers (29739) + +Base: 1958 +Linked animations: [8825, 8826, 8827, 8828] + +Base: 1959 + +Base: 1960 +Linked animations: [8816, 8818, 8819] +Linked NPCs: Kimberly (7170) + +Base: 1961 +Linked animations: [8811, 8812, 8822] +Linked NPCs: Kennith (7174) + +Base: 1962 +Linked animations: [8856] +Linked graphics: 1564 + +Base: 1963 +Linked animations: [8823, 8850, 8851] +Linked graphics: 1558, 1559, 1560 + +Base: 1964 +Linked animations: [8853, 8854, 8855] +Linked graphics: 1561, 1562, 1563 + +Base: 1965 +Linked animations: [8810] +Linked graphics: 1555 + +Base: 1966 +Linked animations: [8813] +Linked graphics: 1556 + +Base: 1967 +Linked animations: [8882] +Linked graphics: 1567 + +Base: 1968 +Linked animations: [8896] +Linked graphics: 1568 + +Base: 1969 +Linked animations: [8886] +Linked graphics: 1570 + +Base: 1970 + +Base: 1971 +Linked animations: [8885] +Linked graphics: 1569 + +Base: 1972 +Linked animations: [8895] + +Base: 1973 +Linked animations: [8883] +Linked graphics: 1566 + +Base: 1974 +Linked animations: [8887, 8897] +Linked objects: Chocolate pool (29869) + +Base: 1975 +Linked animations: [8888, 8889, 8890, 8891, 8892, 8893, 11513] +Linked objects: Incubator coal scuttle (29855), Incubator coal scuttle (29856), Incubator (29857), Incubator (29858), Incubator (29859), Incubator (29860), Incubator (29861), Incubator (29862), Incubator (29863), null (29878), null (29879), null (29880), Incubator (42743), Oven (49130) + +Base: 1976 +Linked animations: [8894] +Linked objects: Chocolate mixer (29840), Chocolate mixer (29841), null (29842) + +Base: 1977 +Linked animations: [8884] + +Base: 1978 +Linked animations: [8912, 8913] +Linked graphics: 1571, 1572 + +Base: 1979 +Linked animations: [8935, 8936] +Linked graphics: 1573, 1574 + +Base: 1980 +Linked animations: [8940, 8942] +Linked graphics: 1576, 1577, 1587, 1588, 1678, 1679 + +Base: 1981 +Linked animations: [11484] + +Base: 1982 +Linked animations: [8955, 8956, 8957, 8958, 8959, 8960, 8961, 8969, 8971, 8972, 11488] +Linked NPCs: Gnoeals (7381), Gnoeals (7382), Gnoeals (7392), Gnoeals (7393) + +Base: 1983 +Linked animations: [1539, 8945] +Linked objects: Fremennik warrior (25307), Fremennik warrior (25313), Fremennik warrior (25358), null (30019) + +Base: 1984 +Linked animations: [8950] +Linked graphics: 2028 + +Base: 1985 +Linked animations: [8974] +Linked objects: null (38178), null (38179), null (38180), null (38181) + +Base: 1986 +Linked animations: [8970] +Linked objects: Windsock (30070) + +Base: 1987 +Linked animations: [8962, 8963, 8964] +Linked graphics: 1580, 1581, 1582, 2027 + +Base: 1988 +Linked animations: [11567, 11568] +Linked objects: Fallen log (42855), Fallen log (42856), Canoe (42857) + +Base: 1989 +Linked animations: [11552] + +Base: 1990 + +Base: 1991 +Linked animations: [9014, 9015, 9611] +Linked graphics: 1589, 1590, 1680 + +Base: 1992 +Linked animations: [8992] +Linked graphics: 1583 + +Base: 1993 +Linked animations: [8994] +Linked graphics: 1585 + +Base: 1994 +Linked animations: [8995] +Linked graphics: 1586 + +Base: 1995 +Linked animations: [8993] +Linked graphics: 1584 + +Base: 1996 +Linked animations: [9017, 9019] +Linked graphics: 1591, 1592 + +Base: 1997 +Linked animations: [9007, 9008] +Linked objects: null (30193), null (30194), null (30195), null (30196), null (30197), null (30198), null (30199), null (30200), null (30201), null (30202), null (30242) + +Base: 1998 +Linked animations: [9005, 9006, 10446, 10449] +Linked objects: Energy barrier (30141) + +Base: 1999 +Linked animations: [9010] +Linked objects: Scoreboard (30205) + +Base: 2000 +Linked animations: [9011] +Linked objects: Stone dispenser (30143) + +Base: 2001 +Linked animations: [9009] +Linked NPCs: Fiara (7600) + +Base: 2002 +Linked animations: [328, 9124, 12526] +Linked graphics: 74, 86, 184, 188, 267, 1605, 2190 + +Base: 2003 +Linked animations: [9041, 9042, 9043] +Linked objects: null (30622) + +Base: 2004 +Linked animations: [9083, 9084, 9085, 9088, 9089, 9090] +Linked objects: Safalaan (30460), Andiess Juip (30462), Kael Forshaw (30463), Safalaan (30464), Andiess Juip (30465), Kael Forshaw (30466) + +Base: 2005 +Linked animations: [9036] +Linked objects: null (30568) + +Base: 2006 +Linked animations: [9056] + +Base: 2007 +Linked animations: [9101] +Linked objects: null (2464) + +Base: 2008 +Linked animations: [9033, 9034, 9035] +Linked objects: Door (30526), Door (30527) + +Base: 2009 +Linked animations: [9122] + +Base: 2010 +Linked animations: [9103] +Linked graphics: 1603 + +Base: 2011 +Linked animations: [9046] +Linked graphics: 1594 + +Base: 2012 +Linked animations: [9067] +Linked graphics: 1598 + +Base: 2013 +Linked animations: [9029, 9030] +Linked graphics: 1595, 1596 + +Base: 2014 +Linked animations: [9079, 9080, 9081, 9082] +Linked graphics: 1599, 1600, 1601, 1602 + +Base: 2015 +Linked animations: [9123] +Linked objects: Holy barrier (3443) + +Base: 2016 +Linked animations: [9075, 9076, 9077, 9078] + +Base: 2017 +Linked animations: [7580, 9102, 9130, 9131, 9132, 9133, 9134, 9430, 9431, 9432, 9433, 9434, 9435, 9436, 9437, 9438] +Linked NPCs: Bloodveld (1618), Bloodveld (1619), Bloodveld (6215), Mutated bloodveld (7642), Mutated bloodveld (7643) + +Base: 2018 +Linked animations: [9037, 9093, 9094, 9125, 9126, 9127, 9128, 9129, 9444, 9445, 9446, 9447, 9448, 9493, 9494, 9495, 9496] +Linked NPCs: Crawling Hand (1648), Crawling Hand (1649), Crawling Hand (1650), Crawling Hand (1651), Crawling Hand (1652), Crawling Hand (1653), Crawling Hand (1654), Crawling Hand (1655), Crawling Hand (1656), Crawling Hand (1657), null (7637), null (7638), null (7639), Skeletal hand (7640), Zombie hand (7641), Creeping hand (8619), Creeping hand (9246), Crawling hand (10694) + +Base: 2019 +Linked animations: [9038] +Linked graphics: 1593 + +Base: 2020 +Linked animations: [9135] +Linked objects: null (30755), A stream of light (37280) + +Base: 2021 +Linked animations: [2935, 9911, 10120, 10121] +Linked objects: null (2452), null (2453), null (2454), null (2455), null (2456), null (2457), null (2458), null (2459), null (2460), null (2461), null (2462), Mysterious ruins (7103), Mysterious ruins (7104), Mysterious ruins (7105), Mysterious ruins (7106), Mysterious ruins (7107), Mysterious ruins (7108), Mysterious ruins (7109), Mysterious ruins (7110), Mysterious ruins (7111), Mysterious ruins (7112), Mysterious ruins (7113), Mysterious ruins (7114), Mysterious ruins (7115), Mysterious ruins (7116), Mysterious ruins (7117), Mysterious ruins (7118), Mysterious ruins (7119), Mysterious ruins (7120), Mysterious ruins (7121), Mysterious ruins (7122), Mysterious ruins (7123), Mysterious ruins (7124) + +Base: 2022 +Linked animations: [9148] + +Base: 2023 +Linked animations: [9147] + +Base: 2024 +Linked animations: [9142] + +Base: 2025 +Linked animations: [4292, 9146, 9149] +Linked objects: Parachuting gnome (31029) + +Base: 2026 +Linked animations: [4294] + +Base: 2027 +Linked animations: [9137] +Linked objects: Convertor (30812), Machine (30961) + +Base: 2028 +Linked animations: [9144] +Linked objects: null (31008), null (31009) + +Base: 2029 +Linked animations: [9150] +Linked objects: Remains (31015), Tent (31016), Tent (31017), null (31032) + +Base: 2030 +Linked animations: [4295, 4297] +Linked objects: Dragon machine (30808), Machine (30810), null (31033) + +Base: 2031 +Linked animations: [4296] +Linked objects: Machine (30809), Machine (30811), null (31034) + +Base: 2032 +Linked animations: [4290, 4291] +Linked objects: null (9260), Dying roses (30804), Growing roses (30805), Roses (30806), Roses (30807) + +Base: 2033 +Linked animations: [9143, 10122] +Linked objects: Nesting bird (31006), Nesting bird (31007), null (31040), Pillar (38420) + +Base: 2034 +Linked animations: [2870, 9154, 9512, 9589, 10237, 10976, 11961] +Linked objects: null (206), null (207), null (11372), null (26196), null (31143), null (31145), null (31747), null (31795), null (31796), null (31930), null (32018), null (32019), null (32020), null (32021), Fire (32099), null (32100), Cooking pot (32105), null (32682), null (32683), null (32684), null (32740), null (32976), null (33073), null (33074), null (33160), null (33469), null (33470), null (33471), null (37024), null (37899), Unlit beacon (38429), Unlit beacon (38433), Unlit beacon (38437), Warning beacon (38441), Emergency beacon (38442), Warning beacon (38443), Emergency beacon (38444), Warning beacon (38445), Emergency beacon (38446), null (38448), null (38449), null (38450), null (38451), null (38452), null (38453), null (38454), null (38455), null (38456), null (38457), null (38458), null (38459), null (38460), null (38461), Cave wall (41009), null (41362), Orb (41371), null (41376), null (41377), null (41378), null (41379), null (41380), null (41511), null (41752), null (41778), null (41834), null (42492), Spit (44277), null (45559), null (46213), null (47044), null (47045), null (47046), null (48504), null (48544), null (48732), null (48770), null (48771), Pillar of light (49266), Pillar of light (49267), null (50605), null (50606), null (50607), null (50608), null (50758), null (50843), null (50844), null (50845), null (50846), null (50847), null (50848), null (50849), Torch (50991), Brazier (50993), null (50995), Brazier (50997), null (51062), null (51114), null (51115), null (51148), null (51157), null (51158), null (51159), null (51160), null (51309), null (51389), null (51390), null (51391), null (51392), null (51393), null (51394), null (51395), Torch (51537), Brazier (51539), null (51541), Brazier (51543), null (51610), Tangle gum fire (51663), Seeping elm fire (51664), Blood spindle fire (51665), Utuku fire (51666), Spinebeam fire (51667), Bovistrangler fire (51668), Thigat fire (51669), Corpsethorn fire (51670), Entgallow fire (51671), Grave creeper fire (51672), Fire remains (51673), Fire remains (51674), Fire remains (51675), Fire remains (51676), Fire remains (51677), Fire remains (51678), Fire remains (51679), Fire remains (51680), Fire remains (51681), Fire remains (51682), null (51705), null (51706), null (51707), null (51708), null (51857), null (51937), null (51938), null (51939), null (51940), null (51941), null (51942), null (51943), Torch (52085), Brazier (52087), null (52089), Brazier (52091), null (52155), Pillar of light (52250), null (52264), null (52271), null (52333), null (53040), null (53041), null (53369), null (53377), null (53385), null (53740), Censer (54102), Censer (54103), Censer (54104), Censer (54105), null (54701), null (54702), null (54703), null (54710), null (54711), null (54720), null (54731), null (54732), null (54764), null (54765), null (54766), Torch (54958), Candle (54960), Candle (54962), Candle (54964), null (55087), null (55100), null (55101), null (55102), null (55103), null (55104), null (55105), null (55106), null (55107), null (55108), Altar (55127) + +Base: 2035 +Linked animations: [9156, 9157, 9158, 9159, 9160, 9161, 9162, 9163, 9164, 9165, 9166, 9167, 9168, 9169, 9170, 9171, 9172, 9173, 9174, 9175, 9200, 9205, 9206, 9522, 9524, 9525, 9527, 9528, 9529, 10235, 10241] +Linked NPCs: null (759), Kitten (761), Kitten (762), Kitten (763), Kitten (764), Kitten (765), Kitten (766), Cat (768), Cat (769), Cat (770), Cat (771), Cat (772), Cat (773), Overgrown cat (774), Overgrown cat (775), Overgrown cat (776), Overgrown cat (777), Overgrown cat (778), Overgrown cat (779), Witch's cat (993), Bob (1091), Neite (1992), Red Axe Cat (2108), Dromund's cat (2140), Red Axe Cat (2229), Red Axe Cat (2230), null (2405), Evil Bob (2478), Evil Bob (2479), Bob (2635), Bob (2636), Neite (2638), Neite (2646), Bob (2647), Beite (2648), null (2652), Neite (2653), Lazy cat (2662), Lazy cat (2663), Lazy cat (2664), Lazy cat (2665), Lazy cat (2666), Lazy cat (2667), Wily cat (2668), Wily cat (2669), Wily cat (2670), Wily cat (2671), Wily cat (2672), Wily cat (2673), The Beast (2941), Bellemorde (2942), Pox (2943), Pox (2944), Bones (2945), Turbogroomer (2983), Pusskins (2984), Loki (2985), Captain Tom (2986), Treacle (2987), Mittens (2988), Claude (2989), Topsy (2990), Gertrude's cat (2997), Overgrown hellcat (3503), Hellcat (3504), Hell-kitten (3505), Lazy hellcat (3506), Wily hellcat (3507), Clockwork cat (3598), Black Cat (4607), Cat (4768), Cat (4769), HRH Hrafn (5479), Del-Monty (5563), Clockwork cat (5605), Clockwork cat (5607), Fluffs (7742), Fluffs (7743), null (7744), null (7784), Ali Cat (7785), null (8073), Trogs (8202), Cat (8214), Lazy cat (8215), Overgrown cat (8216), Kitten (8217), Wily cat (8218), Clockwork cat (8736), Cat (9272), Cat (9273), Cat (9274), Cat (9275), Cat (9276), Cat (9277), Hellcat (9278), Cat (9279), Lazy cat (9280), Lazy cat (9281), Lazy cat (9282), Lazy cat (9283), Lazy cat (9284), Lazy cat (9285), Lazy hellcat (9286), Lazy cat (9287), Overgrown cat (9288), Overgrown cat (9289), Overgrown cat (9290), Overgrown cat (9291), Overgrown cat (9292), Overgrown cat (9293), Overgrown hellcat (9294), Overgrown cat (9295), Wily cat (9296), Wily cat (9297), Wily cat (9298), Wily cat (9299), Wily cat (9300), Wily cat (9301), Wily hellcat (9302), Wily cat (9303) +Linked graphics: 1606, 1610, 1611, 1612, 1613, 1614, 1615, 1660, 1661 + +Base: 2036 +Linked animations: [9194, 9195, 9196, 9197, 9204, 9207, 9208, 9209, 9210, 9211, 9584] +Linked NPCs: Kittens (760), Love Cats (2644), Love Cats (2645), Three little kittens (7741), Kittens (7745) + +Base: 2037 +Linked animations: [9198] +Linked NPCs: Jiggling crate (7740) + +Base: 2038 +Linked animations: [9176] +Linked graphics: 1608 + +Base: 2039 +Linked animations: [9155, 9177] +Linked graphics: 1607, 1609 + +Base: 2040 +Linked animations: [9199, 12394, 12395, 12396, 12397] +Linked objects: null (31160), null (31161), Conveyor belt (46298), Conveyor belt (46299), Plank stack (empty) (46310), Planks (46311), Planks (46312), Planks (46313), Planks (46314), Planks (46315), Planks (46316) + +Base: 2041 +Linked animations: [9246, 9247, 9248, 9249, 9250, 9251, 9252, 9253, 9254, 9255, 9256, 9257] +Linked NPCs: Yt-MejKot (2741), Yt-MejKot (2742), Yt-HurKot (2746) + +Base: 2042 +Linked animations: [9233, 9234, 9235, 9236, 9237, 9238] +Linked NPCs: Tz-Kek (2629), Tz-Kek (2630), Tz-Kek (2736), Tz-Kek (2737), Tz-Kek (2738) + +Base: 2043 +Linked animations: [9273, 9274, 9276, 9277, 9278, 9279, 9300] +Linked NPCs: TzTok-Jad (2745) + +Base: 2044 +Linked animations: [9228, 9229, 9230, 9231, 9232] +Linked NPCs: Tz-Kih (2627), Tz-Kih (2628), Tz-Kih (2734), Tz-Kih (2735) + +Base: 2045 +Linked animations: [9260, 9280, 9281, 9282, 9283, 9284, 9285, 9286, 9287, 9288, 9289, 9290, 9291, 9292, 9293, 9294, 9295, 9296, 9297, 9298, 9299, 9311, 9312, 9313, 9314, 9320, 9321, 9322, 9323, 9324, 9325, 9326, 9345, 9349] +Linked NPCs: TzHaar-Mej (2591), TzHaar-Mej (2592), TzHaar-Mej (2593), TzHaar-Mej (2594), TzHaar-Mej (2595), TzHaar-Mej (2596), TzHaar-Mej (2597), TzHaar-Hur (2598), TzHaar-Hur (2599), TzHaar-Hur (2600), TzHaar-Hur (2601), TzHaar-Hur (2602), TzHaar-Hur (2603), TzHaar-Xil (2604), TzHaar-Xil (2605), TzHaar-Xil (2606), TzHaar-Xil (2607), TzHaar-Xil (2608), TzHaar-Xil (2609), TzHaar-Ket (2610), TzHaar-Ket (2611), TzHaar-Ket (2612), TzHaar-Ket (2613), TzHaar-Ket (2614), TzHaar-Ket (2615), TzHaar-Ket (2616), TzHaar-Mej-Jal (2617), TzHaar-Mej-Kah (2618), TzHaar-Ket-Zuh (2619), TzHaar-Hur-Tel (2620), TzHaar-Hur-Lek (2622), TzHaar-Mej-Roh (2623), TzHaar-Ket (2624), TzHaar-Ket (2625), Mystery figure (3054), TzHaar-Mej-Malk (7746), TzHaar-Xil-Tog (7747), TzHaar-Hur-Frok (7748), TzHaar-Ket-Grol (7749), TzHaar-Ket-Rok (7750), TzHaar-Ket-Lurk (7751), TzHaar-Mej-Lor (7752), TzHaar-Mej (7753), TzHaar-Hur (7754), TzHaar-Xil (7755), Library assistant (7756), TzHaar-Hur-Brekt (7757), TzHaar-Hur-Brekt (7758), TzHaar-Ket-Jok (7759), TzHaar-Ket-Jok (7760), TzHaar-Xil-Mor (7761), TzHaar-Xil-Mor (7762), TzHaar-Mej-Kol (7763), TzHaar-Mej-Kol (7764), TzHaar-Hur-Klag (7765), TzHaar-Hur-Klag (7766), TzHaar-Hur (7767), TzHaar-Hur (7768), TzHaar-Hur (7769) + +Base: 2046 +Linked animations: [9264, 9265, 9266, 9267, 9268, 9269] +Linked NPCs: Ket-Zek (2743), Ket-Zek (2744) + +Base: 2047 +Linked animations: [9239, 9240, 9241, 9242, 9243, 9245] +Linked NPCs: Tok-Xil (2631), Tok-Xil (2632), Tok-Xil (2739), Tok-Xil (2740), Tok-Xil (3592) +Linked objects: Tok-Xil (13377) + +Base: 2048 +Linked animations: [9258] +Linked graphics: 1617 + +Base: 2049 +Linked animations: [9244] +Linked graphics: 1616 + +Base: 2050 +Linked animations: [9270, 9271, 9272] +Linked graphics: 1622, 1623, 1624 + +Base: 2051 +Linked animations: [9301, 9302] +Linked graphics: 1626, 1627 + +Base: 2052 +Linked animations: [9303, 9348] +Linked objects: null (31177), null (31178), null (31179), null (31180), null (31181), null (31182), null (31183), null (31184), null (31185), null (31186), null (31187), null (31188), null (31189), null (31190), null (31191), null (31192), null (31193), null (31194), null (31195), null (31196), Stepping stone (31214), Stepping stone (31215), Stepping stone (31216), Stepping stone (31217), Stepping stone (31218), Stepping stone (31219), Stepping stone (31220) + +Base: 2053 +Linked animations: [9259] +Linked graphics: 1618 + +Base: 2054 +Linked animations: [9275, 10497] +Linked graphics: 1625, 1834 + +Base: 2055 +Linked animations: [9261, 9262] +Linked graphics: 1619, 1620 + +Base: 2056 +Linked animations: [9263] +Linked graphics: 1621 + +Base: 2057 +Linked animations: [9327, 9330] +Linked objects: Rock (31257) + +Base: 2058 +Linked animations: [9328, 9329] +Linked objects: Pillar (31250) + +Base: 2059 +Linked animations: [9331, 9332, 9333, 9334, 9335, 9336] +Linked NPCs: TokTz-Ket-Dill (7770), TokTz-Ket-Dill (7771) + +Base: 2060 +Linked animations: [9341, 9342, 9343, 9344] +Linked NPCs: Fire monster (7773) + +Base: 2061 +Linked animations: [9337, 9338, 9339, 9340] +Linked NPCs: Lava monster (7772) + +Base: 2062 +Linked animations: [9346] +Linked graphics: 1629 + +Base: 2063 +Linked animations: [9347] +Linked objects: null (31285) + +Base: 2064 +Linked animations: [9351] +Linked objects: Signpost (31296) + +Base: 2065 + +Base: 2066 +Linked animations: [9352] +Linked graphics: 1630, 1631, 1632 + +Base: 2067 +Linked animations: [1716, 9353, 9354, 9355, 9356, 9357] +Linked graphics: 312, 1633, 1634, 1635, 1636, 1637 + +Base: 2068 + +Base: 2069 +Linked animations: [9369, 9370, 9371, 9372] +Linked objects: Broken door (31336), Broken door (31337), Broken door (31338), Broken door (31339) + +Base: 2070 +Linked animations: [9397] + +Base: 2071 +Linked animations: [9388, 9389] +Linked objects: Sticks (31306) + +Base: 2072 +Linked animations: [9390, 9391] + +Base: 2073 +Linked animations: [9426, 9427] + +Base: 2074 +Linked animations: [9424, 9425] +Linked objects: Wavering mystic barrier (31314), Wavering mystic barrier (31315) + +Base: 2075 +Linked animations: [9520] +Linked objects: Bucket rope (31316) + +Base: 2076 +Linked animations: [9518, 9519] +Linked objects: Mystic barrier (31435), Mystic barrier (31436) + +Base: 2077 +Linked animations: [9408] +Linked objects: Subterranean spring (31421) + +Base: 2078 +Linked animations: [9383, 9384] +Linked objects: Pulsing markings (31363) + +Base: 2079 +Linked animations: [9377, 9423] +Linked graphics: 1640 +Linked objects: Flames (31317) + +Base: 2080 +Linked animations: [9373] +Linked graphics: 1638, 1639 + +Base: 2081 +Linked animations: [9404] +Linked graphics: 1651 + +Base: 2082 +Linked animations: [9399, 9400, 9401] +Linked graphics: 1647, 1648, 1649 + +Base: 2083 +Linked animations: [9530, 9531, 9532] +Linked graphics: 1662, 1663, 1664 + +Base: 2084 +Linked animations: [9420, 9421, 9422] +Linked graphics: 1653, 1654, 1655 + +Base: 2085 +Linked animations: [9385] +Linked graphics: 1644 + +Base: 2086 +Linked animations: [9379, 9380, 9381] +Linked graphics: 1641, 1642, 1643 + +Base: 2087 +Linked animations: [9517] +Linked graphics: 1659 + +Base: 2088 +Linked animations: [9403] +Linked graphics: 1650 + +Base: 2089 +Linked animations: [1553, 9396] +Linked graphics: 1646, 2274 + +Base: 2090 +Linked animations: [9393, 9394] +Linked graphics: 1645 + +Base: 2091 +Linked animations: [265, 266, 267, 268, 298, 9414, 9415, 9416, 9417, 9418, 9419] +Linked NPCs: Cave crawler (1600), Cave crawler (1601), Cave crawler (1602), Cave crawler (1603), Cave crawler (7787), Monstrous cave crawler (7798), Cave crawler (7812), Cave crawler (10695) + +Base: 2092 +Linked animations: [1532, 1533, 9454, 9455, 9456, 9457, 9458, 10423, 10428, 10429, 10450] +Linked NPCs: Gargoyle (1610), Sharathteerk (8165), null (8166), Sharathteerk (8167), null (8184), Gargoyle (9087) +Linked objects: Statue (5116), Statue (5117) + +Base: 2093 +Linked animations: [9375, 9409, 9410, 9411, 9413, 9471, 9472, 9473, 9474, 9475, 9476, 9477, 9478, 9479, 9480, 9481, 9482, 9483, 9484, 9485, 9486] +Linked NPCs: Swarming turoth (1611), Turoth (1622), Turoth (1623), Turoth (1626), Turoth (1627), Turoth (1628), Turoth (1629), Turoth (1630), Mightiest turoth (7800), Turoth (7814) +Linked graphics: 1656 + +Base: 2094 +Linked animations: [260, 261, 262, 263, 264, 9533, 11218] +Linked NPCs: Basilisk (1616), Basilisk (1617), Basilisk boss (7799), Basilisk (7813), Baby basilisk (8621), Baby basilisk (9248) + +Base: 2095 +Linked animations: [9466, 9467, 9468, 9469, 9470, 12519] +Linked NPCs: Aberrant spectre (1604), Aberrant spectre (1605), Aberrant spectre (1606), Aberrant spectre (1607), Aberrant spectre (7801), Aberrant spectre (7802), Aberrant spectre (7803), Aberrant spectre (7804), Aberrant Spectre Champion (8987) + +Base: 2096 +Linked animations: [9459, 9460, 9461, 9462, 9463, 9464] +Linked NPCs: Death spawn (1614), Death spawn (10703) + +Base: 2097 +Linked animations: [9465] +Linked graphics: 827 + +Base: 2098 +Linked animations: [9374, 9412, 9439, 9440, 9441, 9442, 9443] +Linked NPCs: Kurask (1608), Kurask (1609), Kurask overlord (7797), Kurask minion (7805), Kurask (7811) + +Base: 2099 +Linked animations: [5498, 9378, 9382, 9449, 9450, 9451, 9452, 9453] +Linked NPCs: Banshee (1612), Mighty banshee (7786), Banshee mistress (7793), Banshee mistress (7794), Banshee (7810), Banshee Champion (8986) + +Base: 2100 +Linked animations: [299, 300, 301, 302, 1417] +Linked NPCs: Waterfiend (5361), Waterfiend (9054), Waterfiend (9056), Waterfiend (9057), Waterfiend (9058), Waterfiend (9059), Waterfiend (9061), Waterfiend (9062), Waterfiend (9063), Waterfiend (9064), Waterfiend (9077) + +Base: 2101 +Linked animations: [9513] + +Base: 2102 +Linked animations: [9574] + +Base: 2103 +Linked animations: [9564] +Linked objects: Pipes (31538) + +Base: 2104 +Linked animations: [9563] +Linked objects: Perch rock (31559), Perch rock (31560), Perch rock (31561), null (31691) + +Base: 2105 +Linked animations: [9538, 9539, 9540, 9541] +Linked NPCs: Karamthulhu (7826), Karamthulhu (7827), null (7858) + +Base: 2106 +Linked animations: [9546] +Linked NPCs: Young Ralph (7832), Young Ralph (7833), Young Ralph (7834), Young Ralph (7835), Young Ralph (7836), null (7859) + +Base: 2107 +Linked animations: [9543] + +Base: 2108 +Linked animations: [9582] + +Base: 2109 +Linked animations: [9569] +Linked graphics: 1668 + +Base: 2110 +Linked animations: [9559] +Linked graphics: 1666 + +Base: 2111 +Linked animations: [9545] +Linked graphics: 1672 + +Base: 2112 +Linked animations: [9578] +Linked graphics: 1670 + +Base: 2113 +Linked animations: [9580] +Linked graphics: 1671 + +Base: 2114 +Linked animations: [9550] +Linked graphics: 1674 + +Base: 2115 +Linked animations: [9548] +Linked graphics: 1673 + +Base: 2116 +Linked animations: [9567] +Linked graphics: 1667 + +Base: 2117 +Linked animations: [9556] +Linked graphics: 1665 + +Base: 2118 +Linked animations: [9660] +Linked objects: Carved fountain (35469), Fountain (47747) + +Base: 2119 +Linked animations: [9659] +Linked objects: Gem Stall (6162), Gem stall (34385), null (35436), Gem stall (35437) + +Base: 2120 +Linked animations: [9661] +Linked objects: null (35440), null (35443), null (35445), null (42334), null (43439), null (43441), null (43444) + +Base: 2121 +Linked animations: [9871, 9982] +Linked objects: Organ (36979) + +Base: 2122 +Linked animations: [9881, 9909] + +Base: 2123 +Linked animations: [9867] +Linked objects: Standard (851), Standard (11614), Standard (32295), Standard (36924), Standard (38808), Standard (41372), Standard (45324) + +Base: 2124 +Linked animations: [9910, 9979, 9980, 12905] +Linked objects: Flag (37335), Flag (37504) + +Base: 2125 +Linked animations: [9644] +Linked objects: null (33740), null (33741), null (33742), null (33743), null (34725), null (34726), null (34727), null (34728), null (39960), null (39961), null (39962), null (39963) + +Base: 2126 +Linked animations: [9643] +Linked objects: null (33669), null (34656), null (39885) + +Base: 2127 +Linked animations: [4856] +Linked objects: Bell (36977) + +Base: 2128 + +Base: 2129 +Linked animations: [9642] +Linked objects: null (8720), null (33758), null (33759), null (33760), null (34351), null (34352), null (36548), null (36549), null (36550), null (36551), Standard (36925), Standard (36926), Standard (41373), Standard (41374), Flag (45182), Flag (45183), Flag (45184), Flag (45185), null (45454) + +Base: 2130 +Linked animations: [9645, 9646, 10991, 12214, 12215] +Linked NPCs: Fishing spot (233), Fishing spot (234), Fishing spot (235), Fishing spot (236), Fishing spot (309), Fishing spot (310), Fishing spot (311), Fishing spot (312), Fishing spot (313), Fishing spot (314), Fishing spot (315), Fishing spot (316), Fishing spot (317), Fishing spot (318), Fishing spot (319), Fishing spot (320), Fishing spot (321), Fishing spot (322), Fishing spot (323), Fishing spot (324), Fishing spot (325), Fishing spot (326), Fishing spot (327), Fishing spot (328), Fishing spot (329), Fishing spot (330), Fishing spot (331), Fishing spot (332), Fishing spot (333), Fishing spot (334), Fishing spot (800), Fishing spot (927), Fishing spot (952), Fishing spot (1174), Fishing spot (1175), Fishing spot (1176), Fishing spot (1177), Fishing spot (1178), Fishing spot (1189), Fishing spot (1190), Fishing spot (1191), Fishing spot (1236), Fishing spot (1237), Fishing spot (1238), Fishing spot (1331), Fishing spot (1332), Fishing spot (1333), Fishing spot (1399), Fishing spot (1405), Fishing spot (1406), Fishing spot (2722), Fishing spot (2724), Fishing spot (2859), Fishing spot (3019), Fishing spot (3574), Fishing spot (3575), Fishing spot (3804), Fishing spot (3848), Fishing spot (4908), Fishing spot (5470), Fishing spot (5471), Fishing spot (6267), Fishing spot (6996), Fishing spot (7044), Fishing spot (7045), Fishing spot (7046), Fishing spot (7862), Fishing spot (7863), Fishing spot (7864), Fishing spot (8647), Cavefish shoal (8841), Rocktail shoal (8842) +Linked objects: Water (43), Fishing spot (2026), Panning point (2363), Fishing spot (3032), Fishing spot (8986), Ominous Fishing Spot (10087), Ominous Fishing Spot (10088), Ominous Fishing Spot (10089), Aquarium (10091), Fishing spot (14938), null (14939), Fishing spot (49561), Fishing spot (49562), Fishing spot (49563), Heim crabs (49923), Red-eye (49924), Dusk eels (49925), Giant flatfish (49926), Short-finned eels (49927), Web snippers (49928), Bouldabass (49929), Salve eels (49930), Blue crabs (49931), Cave morays (49932), Fishing spot (54298) + +Base: 2131 + +Base: 2132 + +Base: 2133 +Linked animations: [9663] +Linked objects: null (37211) + +Base: 2134 + +Base: 2135 +Linked animations: [687, 9665] +Linked objects: null (526), Waterfall (2228), null (16302), null (21579), Waterfall (34915), null (34916), null (37212), null (37213), null (37214), null (37215), null (37216), null (37217), null (37218), null (37219), null (37220), null (37221), null (37222), null (37223), null (37224), null (37225), null (37226), null (37227), null (37228), null (37229), null (37230), null (37231), null (37232), null (37233), null (37234), null (37235), null (37236), null (37237), null (37238), null (37239), null (37240), null (37241), null (37242), null (37243), null (37244), Door (37247), null (37456) + +Base: 2136 + +Base: 2137 +Linked animations: [452] + +Base: 2138 +Linked animations: [9590] +Linked objects: Obelisk of Fire (2153) + +Base: 2139 +Linked animations: [1521, 1525, 1713, 7537, 9593, 11854, 11855, 11856, 11857, 12157, 12158, 12522] +Linked NPCs: Astrid's pyre ship (9311), Brand's pyre ship (9312) +Linked graphics: 2135, 2136, 2189 +Linked objects: Fire Wall (2908), Fire Wall (2909), null (13880), Fire (13881), null (14887), null (14888), null (14889), null (14890), null (15253), null (15254), null (15255), null (15491), null (33394), null (33395), null (43778), null (43779), null (43795), null (47079), null (47081) + +Base: 2140 +Linked animations: [9616] +Linked graphics: 1685 + +Base: 2141 +Linked animations: [9618] +Linked graphics: 1687 + +Base: 2142 +Linked animations: [9619] +Linked graphics: 1688 + +Base: 2143 +Linked animations: [9612] +Linked graphics: 1681 + +Base: 2144 +Linked animations: [9614] +Linked graphics: 1683 + +Base: 2145 +Linked animations: [9617] +Linked graphics: 1686 + +Base: 2146 +Linked animations: [9613] +Linked graphics: 1682 + +Base: 2147 +Linked animations: [9621] +Linked graphics: 1690 + +Base: 2148 +Linked animations: [9620] +Linked graphics: 1689 + +Base: 2149 +Linked animations: [9615] +Linked graphics: 1684 + +Base: 2150 +Linked animations: [665, 666, 667, 9624, 9626, 9628, 9630, 9632, 9634, 9636] +Linked graphics: 111, 112, 113, 763, 764, 1675, 1676, 1691, 1692, 1693, 1694, 1695, 1696, 1697, 1698, 1699, 1727, 1728, 1729, 1730 + +Base: 2151 + +Base: 2152 +Linked animations: [9594] +Linked graphics: 1677, 1955 + +Base: 2153 +Linked animations: [9638] +Linked graphics: 1700 + +Base: 2154 +Linked animations: [9641] +Linked objects: Bridge (15856), Bridge (15857), Bridge (15882), Bridge (15883), Bridge (15944) + +Base: 2155 +Linked animations: [9662] +Linked objects: null (36068), null (36071), null (36072), null (36073), null (36074), null (36075), null (36076), null (36077), null (36078), null (36081), null (36082), null (36083), null (36086), null (36087), null (36250) + +Base: 2156 +Linked animations: [9655] +Linked objects: Catapult (4904), Catapult (4905) + +Base: 2157 +Linked animations: [9657] +Linked objects: Rocks (4437) + +Base: 2158 +Linked animations: [9654, 9658] +Linked NPCs: Barricade (1532), Barricade (1533), Barricade (1534), Barricade (1535), Barricade (8600), Barricade (8601), Barricade (8618) + +Base: 2159 +Linked animations: [9651, 9652, 11219] +Linked objects: Energy barrier (4469), Energy barrier (4470), Door (20199), Door (20200), Door (20201), Door (20202), Door (20203), Door (20204), Door (20205), Door (20206), Door (20207), Door (20208), Door (20209), Blue barrier (42013), Blue barrier (42014), Blue barrier (42015), Red barrier (42016), Red barrier (42017), Red barrier (42018), Neutral barrier (42019), Neutral barrier (42020), Blue barrier (42029), Red barrier (42030), Blue barrier (42276), Red barrier (42277), Energy barrier (47236), Auto-matching barrier (52221), Challenge barrier (52245) + +Base: 2160 +Linked animations: [9653] +Linked objects: Portal (2273), Portal (2274), Portal (2468), Portal (2475), Portal (2503), Portal (2504), Portal (2505), Portal (2506), Portal (2507), Portal (3826), Saradomin portal (4387), Zamorak portal (4388), Exit portal (4389), Exit portal (4390), Exit portal (4406), Exit portal (4407), Guthix portal (4408), Portal (5138), Exit portal (11368), Exit portal (11369), Exit portal (11371), Exit portal (11373), Balance portal (42031), Exit portal (45803) + +Base: 2161 +Linked animations: [9656] +Linked objects: Climbing rope (36312) + +Base: 2162 +Linked animations: [7262] +Linked objects: Chair (36726) + +Base: 2163 +Linked animations: [1896, 6440, 6441, 9666, 9667, 9668, 9669, 9670, 9671, 9672, 9673, 9674, 9675] +Linked NPCs: Camel (80), Ugthanki (840), Ali the Camel (1873), Al the Camel (2809), Elly the Camel (2810), Ollie the Camel (2811), Cam the Camel (2812), null (2813), Alice the Camel (2814), Neferti the Camel (2815), Camel display (5977), Louis the Camel (9368), Louis the Camel (9406) +Linked objects: Cart Camel (36748) + +Base: 2164 + +Base: 2165 +Linked animations: [9740, 9741, 9742, 9743, 9744, 9745, 9746, 9747, 9748, 9749, 9750, 9751, 9752, 9753, 9757, 9758, 9759, 9760, 9761, 9762, 9763, 9764, 9765, 9766, 9767, 9768, 9769, 9770, 9771, 9772, 9773, 9774, 9775, 9776, 9777, 9778, 9779, 9780, 9781, 9782, 9783, 9784, 9785, 9786, 9787, 9788, 9789, 9790, 9791, 9792, 9793, 9794, 9795, 9796, 9797, 9798, 9799, 9800, 9801, 9802, 9803, 9804, 9805, 9806, 9807, 9808, 9809, 9810, 9811, 9812, 9813, 9814, 9815, 9816, 9817, 9818, 9819, 9820, 9821, 9822, 9823, 9824, 9825, 9826, 9827, 9828, 9829, 9830, 9831, 9832, 9833, 9834, 9835, 9836, 9837, 9838, 9839, 9840, 9841, 9842, 9843, 9844, 9845, 9846, 9847, 9848, 9849, 9850, 9851, 9852, 9853, 9854, 9855, 9856, 9857, 9858, 9859, 9860, 9861, 9862, 9863, 9864, 9865, 9866, 9877, 9878, 10083, 10479, 11009, 12411, 12554, 12648, 12649, 12650, 13656, 14004, 14005, 14006, 14007, 14079] + +Base: 2166 +Linked animations: [9969] +Linked graphics: 1719, 1720, 1721, 1722, 1723 + +Base: 2168 +Linked animations: [9887, 9888, 9889, 9890, 9891, 9892, 9893, 9894, 9895, 9896, 9897, 9898, 9899, 9900, 9901, 9902, 9903, 9904, 9905, 9906] + +Base: 2169 +Linked animations: [9720] +Linked graphics: 1702 + +Base: 2170 +Linked animations: [4277] +Linked graphics: 712 + +Base: 2171 + +Base: 2172 + +Base: 2173 + +Base: 2174 + +Base: 2175 + +Base: 2176 +Linked animations: [497, 11943] + +Base: 2177 +Linked animations: [9975] +Linked graphics: 1726 + +Base: 2178 +Linked animations: [5314] +Linked graphics: 967 + +Base: 2179 +Linked animations: [10024, 10488] + +Base: 2180 +Linked animations: [114, 115, 116, 117, 118, 137, 138, 139, 140, 141, 321, 322, 323, 324, 325, 326, 327] +Linked graphics: 775, 800, 801, 802, 803, 804, 1703, 1704, 1705, 1706, 1707, 1708, 1709, 1710, 1711, 1712, 1713 + +Base: 2181 +Linked animations: [4854] +Linked graphics: 148, 1716 + +Base: 2182 +Linked animations: [9967] +Linked graphics: 1717 + +Base: 2183 +Linked animations: [9970] +Linked objects: Water barrel (37585), Puddle (37598), Puddle (37599), Puddle (37600), Puddle (37601), Puddle (37602), null (37603), Puddle (37964), Puddle (37965), Puddle (37966), null (47039), null (47040) + +Base: 2185 +Linked animations: [9971, 9974, 9981] +Linked objects: Mine entrance (37632), null (37635) + +Base: 2186 +Linked animations: [9972, 9973] +Linked objects: Rock column (37657) + +Base: 2187 + +Base: 2188 +Linked animations: [9991] +Linked graphics: 1734 + +Base: 2189 +Linked animations: [9985, 9987] +Linked graphics: 1731, 1732 + +Base: 2190 +Linked animations: [9989] +Linked graphics: 1733 + +Base: 2191 +Linked animations: [10051, 10052] + +Base: 2192 +Linked animations: [10053, 10055, 10056, 10057, 10058, 10059, 10064, 10065, 10066, 10378, 10379, 10384, 10385, 10386, 10388, 10389, 10400, 10405, 10409, 10410, 10496] +Linked NPCs: Spirit Beast (7995), Spirit Beast (7996), Spirit Beast (7997), Spirit Beast (8128), Spirit Beast (8129), Spirit Beast (8130), Spirit Beast (8131), Spirit Beast (8132), Corporeal Beast (8133) + +Base: 2193 + +Base: 2194 +Linked animations: [7385, 10404] +Linked graphics: 1822 +Linked objects: Fire pit (38827), Fire pit (38828) + +Base: 2195 +Linked animations: [10039, 10040] +Linked objects: null (37840), null (37841) + +Base: 2196 +Linked animations: [10025, 10026, 10027, 10028, 10029, 10030, 10031, 10043] +Linked NPCs: Spirit (7976), Spirit (7977), Spirit (7978), Spirit (7979), Spirit (7980) + +Base: 2197 +Linked animations: [10042] +Linked objects: Portal (37924), Portal (37925), null (37926), null (37927), null (38011), Portal (38843) + +Base: 2198 +Linked animations: [10034] +Linked objects: Hollow log (37831) + +Base: 2199 +Linked animations: [10068] +Linked graphics: 1742 + +Base: 2200 +Linked animations: [7393, 10375] +Linked graphics: 1273, 1804, 1809 + +Base: 2201 +Linked animations: [10061] +Linked graphics: 1741 + +Base: 2202 +Linked animations: [10380] +Linked graphics: 1805, 1806, 1807, 1808 + +Base: 2203 +Linked animations: [10060] +Linked graphics: 1740 + +Base: 2204 +Linked animations: [10062, 10063] +Linked graphics: 1743, 1744 + +Base: 2205 +Linked animations: [10048] +Linked graphics: 1736 + +Base: 2206 +Linked animations: [10376] +Linked graphics: 1272 + +Base: 2207 +Linked animations: [10035] +Linked graphics: 1735 + +Base: 2208 +Linked animations: [10396, 10397, 10398, 10399, 10401, 10402, 10403, 10406, 10407, 10408, 13401, 13402, 13403, 13404] +Linked graphics: 1813, 1814, 1815, 1816, 1817, 1818, 1819, 1820, 1821, 1823, 1824, 1825, 2512, 2513, 2514, 2515 + +Base: 2209 +Linked animations: [10054] +Linked graphics: 1737 + +Base: 2210 +Linked animations: [7391, 10395] +Linked objects: Entrance (38814) + +Base: 2211 +Linked animations: [10047] + +Base: 2212 +Linked animations: [10046] +Linked objects: Altar (37902), Altar (37903), Altar (37904), Altar (37905), Altar (37906), Altar (37907), Altar (37908), Altar (37909), Altar (37910), Altar (37911), Altar (37912), null (37913) + +Base: 2213 +Linked animations: [10381, 10382, 10383] +Linked graphics: 1810, 1811, 1812 + +Base: 2214 +Linked animations: [10095, 10096] + +Base: 2215 +Linked animations: [10086, 10087, 10097] +Linked graphics: 1745, 1746, 1747 + +Base: 2216 +Linked animations: [10091] +Linked graphics: 1748 + +Base: 2217 +Linked animations: [10098, 10099] +Linked objects: Portal (38150) + +Base: 2218 +Linked animations: [10090] +Linked NPCs: Roger (8018) + +Base: 2219 +Linked animations: [10088, 10089] +Linked objects: Basket (38121), Basket (38122) + +Base: 2220 +Linked animations: [10085] +Linked objects: Barrier (38144), Barrier (38145), Barrier. (38146), Barrier. (38147), Barrier. (38148), Barrier. (38149) + +Base: 2221 +Linked animations: [10092, 10093, 10094] + +Base: 2222 +Linked animations: [10118, 10750, 10769, 10874, 10875, 13976] +Linked graphics: 1954, 1958, 2631 +Linked objects: Mysterious stone (41160), Mysterious stone (41161), Stone of Jas (41162), Stone of Jas (41163), Stone of Jas (41164) + +Base: 2223 +Linked animations: [10125, 10126, 10204, 10205, 10206, 10207, 10208, 10209] +Linked NPCs: Wizard Korvak (8029), Wizard Vief (8030), Wizard Elriss (8032) + +Base: 2224 +Linked animations: [10135, 10136, 10137, 10138, 10192, 10193, 10194, 10195, 10196, 10197, 10198, 10199] +Linked NPCs: null (8021), Yellow orb (8022), Yellow orb (8023), Yellow orb (8024), null (8025), Green orb (8026), Green orb (8027), Green orb (8028) +Linked objects: Switch (20222), Switch (20223), Tube (38325), Tube (38326), Containment unit (38327), Storage unit (38328), Runestone accelerator (38329), Tube (48170), Tube (48171) + +Base: 2225 +Linked animations: [10188, 10189] +Linked NPCs: Wizard Acantha (8031) + +Base: 2226 +Linked animations: [10139, 10140, 10141, 10142, 10143, 10144, 10145, 10146, 10147, 10148, 10149, 10150, 10151, 10152, 10153, 10154, 10155, 10156, 10157, 10158, 10159, 10160, 10161, 10162, 10163, 10164, 10165, 10166, 10167, 10168, 10169, 10170, 10171, 10216, 10217, 10218, 10219, 10220] + +Base: 2227 +Linked animations: [10191] + +Base: 2228 +Linked animations: [10214] +Linked graphics: 1774 + +Base: 2229 +Linked animations: [10179, 10181, 12782] +Linked graphics: 1771, 1772, 2309 + +Base: 2230 +Linked animations: [10190] +Linked objects: Portal (3078), Portal (20224), Portal (20225), Portal (20244), Portal (20248), Portal (38279) + +Base: 2231 +Linked animations: [10183, 10185, 10187] +Linked graphics: 1749, 1750, 1751, 1752 +Linked objects: Barrier (38377), Barrier (38378) + +Base: 2232 +Linked animations: [10130, 10131, 10133, 10174, 10175] +Linked graphics: 1753, 1754, 1755, 1756, 1757, 1758, 1759, 1760, 1761, 1762, 1763, 1764, 1765, 1766, 1767, 1768, 1769, 1770 + +Base: 2233 +Linked animations: [10203] +Linked graphics: 1773 + +Base: 2234 +Linked animations: [10134, 10176, 10177, 10178] +Linked NPCs: Portal (8019), Portal (8020) + +Base: 2235 +Linked animations: [10215] +Linked objects: null (38336), null (38337), null (38338) + +Base: 2236 +Linked animations: [10123, 10124] +Linked objects: null (38396), null (38397), null (38398), null (38399), null (38400), null (38401), null (38403), null (38404), null (38405), null (38406), null (38407), null (38408) + +Base: 2237 +Linked animations: [10128, 10129] +Linked objects: Glass spheres (38331) + +Base: 2238 +Linked animations: [10201] +Linked objects: Bookcase (539), null (38333), Workbench (42211) + +Base: 2239 +Linked animations: [10127, 10200] +Linked objects: Gyroscope (38330), Gyroscope (48172) + +Base: 2240 +Linked animations: [10221] + +Base: 2241 +Linked animations: [10229] + +Base: 2242 +Linked animations: [10244, 10245] +Linked graphics: 1779, 1780 + +Base: 2243 +Linked animations: [10238, 10239] +Linked graphics: 1775, 1776 + +Base: 2244 +Linked animations: [10356, 10357, 10358, 10359, 10360, 10361, 10362, 10363, 10364, 10365, 10366, 10367, 10563, 11002, 11003, 11004, 11005, 11006] +Linked NPCs: Snowman (4662), Pumpkin (8077), Barrel (8104), Bush (8105), Bush (8106), Cactus (8107), Crate (8108), Rock (8109), Toadstool (8110), Cactus (8502), Cactus (8503), Bush (8504), Toadstool (8505), Barrel (8506), Bush (8507), Crate (8508), Bush (8509), Rock (8510), Bush (8511) + +Base: 2245 +Linked animations: [10322, 10323, 10324, 10325, 10326, 10327, 10328, 10329, 10330, 10331] +Linked objects: Rat (level 10 approx.) (38649), Cat (level 20 approx.) (38650), Penguin (level 40 approx.) (38652), Ork (level 50 approx.) (38653) + +Base: 2246 +Linked animations: [10332, 10333, 10334] +Linked objects: Armour (level 60 approx.) (38654), Stool (level 70 approx.) (38655), Dumb-bells (level 80 approx.) (38656), Assistant (level 90 approx.) (38657), Anvil (level 99 approx.) (38658) + +Base: 2247 +Linked animations: [10259] +Linked objects: null (38505), Target (38506), Target (38507), Target (38508), Target (38509), Target (38510), Target (38511), Target (38512), Target (38513), Target (38514), Target (38515), Target (38516), Target (38517), Target (38518), Target (38519), Target (38520), Target (38521), Target (38522) + +Base: 2248 +Linked animations: [10319, 10320, 10321] +Linked NPCs: Ticket vendor (8088) + +Base: 2249 +Linked animations: [10315, 10316] + +Base: 2250 +Linked animations: [10314, 10317, 10318] +Linked NPCs: Ringmaster (8085) + +Base: 2251 +Linked animations: [10272] +Linked graphics: 1803 + +Base: 2252 +Linked animations: [10310, 10311] +Linked graphics: 1799, 1800 + +Base: 2253 +Linked animations: [10302, 10304, 10306, 10309] +Linked graphics: 1781, 1782, 1783, 1784, 1787, 1788, 1789, 1790, 1791, 1792, 1793, 1794, 1795, 1796, 1797, 1798 + +Base: 2254 +Linked animations: [10307, 10308] +Linked graphics: 1785, 1786 + +Base: 2255 +Linked animations: [10282, 10283, 10284] +Linked objects: The audience (38576), The audience (38577), The audience (38578), The audience (38579), The audience (38580), The audience (38581) + +Base: 2256 +Linked animations: [10285, 10286, 10287] +Linked objects: The audience (38582), The audience (38583), The audience (38584), The audience (38585), The audience (38586), The audience (38587) + +Base: 2257 +Linked animations: [10276, 10277, 10278] +Linked objects: The audience (38558), The audience (38559), The audience (38560), The audience (38561), The audience (38562), The audience (38563) + +Base: 2258 +Linked animations: [10273, 10274, 10275] +Linked objects: The audience (38570), The audience (38571), The audience (38572), The audience (38573), The audience (38574), The audience (38575) + +Base: 2259 +Linked animations: [10279, 10280, 10281] +Linked objects: The audience (38564), The audience (38565), The audience (38566), The audience (38567), The audience (38568), The audience (38569) + +Base: 2260 +Linked animations: [10352, 10354] +Linked NPCs: Star sprite (8091) + +Base: 2261 +Linked animations: [10350] + +Base: 2262 +Linked animations: [10349, 10351, 10353] +Linked objects: null (38659), Crashed star (38661), Crashed star (38662), Crashed star (38663), Crashed star (38664), Crashed star (38665), Crashed star (38666), Crashed star (38667), Crashed star (38668) + +Base: 2263 +Linked animations: [10368, 10369, 10370, 10371] + +Base: 2264 +Linked animations: [7382, 12723, 12735] +Linked objects: Non-combat zone (38692), Force field (39489), Force field (39490), Force field (39491), Force field (39492), Force field (39493), Force field (39494), Barrier door (39639), Barrier door (39640), Barrier door (39641), Barrier door (39642), Barrier door (39643), Barrier door (39644), Barrier door (39645), Barrier door (39646), Barrier door (39647), Barrier door (39648), Barrier door (39649), Barrier door (39650), Barrier door (39651), Barrier door (39652), Barrier door (39653), Barrier door (39654), Barrier door (39655), Barrier door (39656), Barrier door (39657), Barrier door (39658), Barrier door (39659), Barrier door (39660), Barrier door (39661), Barrier door (39662), Barrier door (39663), Barrier door (39664), Barrier door (39665), Barrier door (39666), Barrier door (39667), Barrier door (39668), Barrier door (39689), Barrier door (39690), Barrier door (39691), Barrier door (39692), Barrier door (39693), Barrier door (39694), Barrier door (39695), Barrier door (39696), Barrier door (39697), Barrier door (39698), Barrier door (39699), Barrier door (39700), Barrier door (39701), Barrier door (39702), Barrier door (39703), Barrier door (39704), Barrier door (39705), Barrier door (39706), Barrier door (39707), Barrier door (39708), Barrier door (39709), Barrier door (39710), Barrier door (39711), Barrier door (39712), Barrier door (39713), Barrier door (39714), Barrier door (39715), Barrier door (39716), Barrier door (39717), Barrier door (39718), Barrier door (39719), Barrier door (39720), null (39766), null (39767), null (39768), null (39769), null (39778), null (39779), null (39780), null (39781), null (39790), null (39791), null (39792), null (39793), null (39802), null (39803), null (39804), null (39805), null (39814), null (39815), null (39816), null (39817), null (39826), null (39827), null (39828), null (39829), Arcane doorway (47974), Arcane doorway (47975), Arcane doorway (47976), Arcane doorway (47981), Arcane doorway (47982), Arcane doorway (47983) + +Base: 2265 +Linked animations: [10586] +Linked objects: Entry portal (39515) + +Base: 2266 +Linked animations: [10387, 10390, 10391, 10392, 10393, 10394] +Linked NPCs: Dark energy core (8126), Dark energy core (8127) +Linked graphics: 1826, 1827, 1828 +Linked objects: Hole (37967) + +Base: 2267 +Linked animations: [10411] +Linked graphics: 1829 + +Base: 2268 +Linked animations: [10412] +Linked graphics: 1830 + +Base: 2269 +Linked animations: [10413, 10414] + +Base: 2270 +Linked animations: [10489] + +Base: 2271 +Linked animations: [10481] + +Base: 2272 +Linked animations: [10424] +Linked objects: Red mist (39214) + +Base: 2273 +Linked animations: [10426, 10427] +Linked NPCs: Fish (8176), Fish (8177) + +Base: 2274 +Linked animations: [10432, 10433, 10441, 10451] +Linked NPCs: Zemouregal (8146), null (8147), Zemouregal (8148), null (8183) + +Base: 2275 +Linked animations: [10460, 10461, 10462, 10463] +Linked objects: null (39208), null (39209), null (39210), null (39211) + +Base: 2276 +Linked animations: [10425, 10431] +Linked objects: The Sacred Forge (39207) + +Base: 2277 + +Base: 2278 +Linked animations: [10419] + +Base: 2279 +Linked animations: [10472] +Linked graphics: 1833 + +Base: 2280 +Linked animations: [10421] +Linked graphics: 1831 + +Base: 2281 +Linked animations: [10422, 14505] +Linked graphics: 1832, 2753 + +Base: 2282 +Linked animations: [10444, 10445] + +Base: 2283 +Linked animations: [10437, 10438, 10439, 10440, 10442, 10443] + +Base: 2284 +Linked animations: [10447, 10448] + +Base: 2285 +Linked animations: [10430] + +Base: 2286 +Linked animations: [10486, 10487] + +Base: 2287 +Linked animations: [10529] +Linked graphics: 1857, 1858, 1859, 1860, 1861, 1862 + +Base: 2288 +Linked animations: [10510] +Linked graphics: 1844, 2000 + +Base: 2289 +Linked animations: [10522, 10523] +Linked graphics: 1853, 1854 + +Base: 2290 +Linked animations: [10509] +Linked graphics: 1837 + +Base: 2291 +Linked animations: [10506, 10507, 10508] +Linked graphics: 1841, 1842, 1843 + +Base: 2292 +Linked animations: [10511, 10512, 10514] +Linked graphics: 1845, 1846, 1847 + +Base: 2293 +Linked animations: [10519, 10520, 10521] +Linked graphics: 1850, 1851, 1852 + +Base: 2294 +Linked animations: [10515, 10517] +Linked graphics: 1848, 1849 + +Base: 2295 +Linked animations: [10500] +Linked graphics: 1839 + +Base: 2296 +Linked animations: [1542, 1543, 1873, 2877, 10525, 10526, 10527, 10528, 10965, 11243, 11253, 11923, 12032, 12192, 13173] +Linked graphics: 347, 479, 1835, 1836, 1838, 1840, 1950, 2008, 2100, 2118, 2144, 2272, 2273, 2439 + +Base: 2297 +Linked animations: [10531] +Linked graphics: 1864 + +Base: 2298 +Linked animations: [10536] +Linked graphics: 1865 + +Base: 2299 +Linked animations: [10533] +Linked graphics: 1866 + +Base: 2300 +Linked animations: [10539, 10540] +Linked graphics: 1867, 1868 + +Base: 2301 +Linked animations: [14212] +Linked graphics: 457 + +Base: 2302 +Linked animations: [2789, 10559] + +Base: 2303 +Linked animations: [14213, 14218] +Linked graphics: 458, 459, 460, 461, 462, 463, 464, 1863, 2699, 2700 + +Base: 2304 +Linked animations: [10561] +Linked objects: Hat stand (39245), Light (39246) + +Base: 2305 +Linked animations: [10541] +Linked objects: null (39228) + +Base: 2306 +Linked animations: [10560] +Linked objects: Caravan (39237) + +Base: 2307 +Linked animations: [10557, 10558, 12894, 12895, 12896] +Linked NPCs: Corpse Spider (7914), Bat (8208), Rat (8209), Lizard (8210), Blackbird (8211), Spider (8212), Snail (8213), null (8219), null (8220), null (8221), null (8222), null (8223), null (8224), null (8225) + +Base: 2308 +Linked animations: [10547, 10548, 10549] +Linked objects: null (39238), null (39239), Hitching post (39240), null (40192) + +Base: 2309 +Linked animations: [10585] +Linked graphics: 1869, 1870, 1871 + +Base: 2310 +Linked animations: [10598] +Linked graphics: 1882 + +Base: 2311 +Linked animations: [10624] +Linked objects: Post (39762) + +Base: 2312 +Linked animations: [10582] +Linked objects: Pool (class 5) (39562), Pool (class 4) (39563), Pool (class 3) (39564), Pool (class 2) (39565), Pool (class 5) (39566), Pool (class 4) (39567), Pool (class 3) (39568), Pool (class 2) (39569), Pool (empty) (39570), Pool (empty) (39571), Pool (empty) (39572), Pool (empty) (39573) + +Base: 2313 +Linked animations: [10599, 10600] +Linked objects: null (39598), null (39599), null (39601) + +Base: 2314 +Linked animations: [10601] +Linked objects: null (39600) + +Base: 2315 +Linked animations: [10581] +Linked objects: Swarm (class 5) (39574), Swarm (class 4) (39575), Swarm (class 3) (39576), Swarm (class 2) (39577), Swarm (class 5) (39578), Swarm (class 4) (39579), Swarm (class 3) (39580), Swarm (class 2) (39581), Swarm (empty) (39582), Swarm (empty) (39583), Swarm (empty) (39584), Swarm (empty) (39585) + +Base: 2316 +Linked animations: [10591, 10592, 10593, 10594, 10595, 10596, 10597] +Linked NPCs: Clay familiar (class 1) (8240), Clay familiar (class 1) (8241), Clay familiar (class 2) (8242), Clay familiar (class 2) (8243), Clay familiar (class 3) (8244), Clay familiar (class 3) (8245), Clay familiar (class 4) (8246), Clay familiar (class 4) (8247), Clay familiar (class 5) (8248), Clay familiar (class 5) (8249) + +Base: 2317 +Linked animations: [10746] + +Base: 2318 +Linked animations: [10966] +Linked objects: Vine flower (40889) + +Base: 2319 +Linked animations: [10648, 10649] +Linked objects: Rocks (41041), Rocks (41042) + +Base: 2320 +Linked animations: [5084, 5085, 5087, 10751] +Linked graphics: 873, 874, 875 +Linked objects: Treasure pile (40951) + +Base: 2321 +Linked animations: [10761] +Linked objects: null (40203) + +Base: 2322 +Linked animations: [10702, 10703] +Linked objects: Stairs (40956) + +Base: 2323 +Linked animations: [10765] + +Base: 2324 +Linked animations: [10877, 10878, 10879, 10880] + +Base: 2325 +Linked animations: [10908, 10909] +Linked objects: Floor wire (40914), Floor wire (40915), Floor wire (40916), null (41307), null (41308), null (41309), null (41310), null (41311), null (41312), null (41313), null (41314), null (41315), null (41316), null (41317), null (41318), null (41319), null (41320), null (41321), null (41322), null (41323), null (41324), null (41325), null (41326), null (41327), null (41328), null (41329), null (41330), null (41331), null (41332), null (41333), null (41334) + +Base: 2326 +Linked animations: [10893] + +Base: 2327 +Linked animations: [10890, 10891, 10892] +Linked objects: Dolmen (40871), Dolmen (40872), Dolmen (40873), Dolmen (40874), Dolmen (40875), Dolmen (40876), Dolmen (40877), Dolmen (40878), Dolmen (40879), Dolmen (40880), Dolmen (40881), Dolmen (40882), Dolmen (40883), Dolmen (40884), Dolmen (40885), Dolmen (40886) + +Base: 2328 +Linked animations: [10862, 10863, 10864] +Linked objects: null (41346), null (41347), null (41348) + +Base: 2329 + +Base: 2330 +Linked animations: [10826, 10827] + +Base: 2331 +Linked animations: [10821] + +Base: 2332 +Linked animations: [10754] + +Base: 2333 +Linked animations: [10894] + +Base: 2334 +Linked animations: [10708, 10712] + +Base: 2335 +Linked animations: [10785, 10786] +Linked objects: Statue (40828) + +Base: 2336 +Linked animations: [10789, 10790] +Linked objects: Statue (40829) + +Base: 2337 +Linked animations: [10787, 10788] +Linked objects: Statue (40834) + +Base: 2338 +Linked animations: [10804, 10805] +Linked objects: Statue (40839) + +Base: 2339 +Linked animations: [10808, 10809] +Linked objects: Statue (40835) + +Base: 2340 +Linked animations: [10806, 10807] +Linked objects: Statue (40836) + +Base: 2341 +Linked animations: [10779, 10780] +Linked objects: Statue (40833) + +Base: 2342 +Linked animations: [10783, 10784] +Linked objects: Statue (40831) + +Base: 2343 +Linked animations: [10781, 10782] +Linked objects: Statue (40827) + +Base: 2344 +Linked animations: [10791, 10792] +Linked objects: Statue (40838) + +Base: 2345 +Linked animations: [10810, 10811] +Linked objects: Statue (40830) + +Base: 2346 +Linked animations: [10802, 10803] +Linked objects: Statue (40837) + +Base: 2347 +Linked animations: [10777, 10778] +Linked objects: Statue (40832) + +Base: 2348 +Linked animations: [10760] +Linked objects: Dragon head (40204), Dragon head (40699) + +Base: 2349 + +Base: 2350 +Linked animations: [10766, 10767, 10907] +Linked NPCs: Dragon head (8426), Dragon head (8427) +Linked objects: Brazier (41035), Brazier (41036) + +Base: 2351 +Linked animations: [10967] +Linked objects: null (41335) + +Base: 2352 + +Base: 2353 +Linked animations: [10682, 10683, 10684] +Linked graphics: 1936, 1937, 1938 + +Base: 2354 +Linked animations: [10837] +Linked graphics: 1913, 1914 + +Base: 2355 +Linked animations: [10774, 11370] +Linked graphics: 1899, 2001 + +Base: 2356 +Linked animations: [10629] +Linked graphics: 1906, 2632, 2633 + +Base: 2357 +Linked animations: [10925, 10929] +Linked graphics: 1887, 1888 + +Base: 2358 +Linked animations: [10723] +Linked graphics: 1949 + +Base: 2359 +Linked animations: [10840] +Linked graphics: 1915 + +Base: 2360 +Linked animations: [10984, 10985] +Linked graphics: 1952, 1953 + +Base: 2361 +Linked animations: [10838, 10839] + +Base: 2362 +Linked animations: [10748] +Linked graphics: 1892 + +Base: 2363 +Linked animations: [10834, 10835] +Linked NPCs: Hazelmere's hat (8496) +Linked graphics: 1928 + +Base: 2364 +Linked animations: [10685, 10686, 10687] +Linked graphics: 1939, 1940, 1941 + +Base: 2365 +Linked animations: [10928] +Linked graphics: 1886 + +Base: 2366 +Linked animations: [10643, 10645] +Linked graphics: 1909, 1910 + +Base: 2367 +Linked animations: [10630, 10631] +Linked graphics: 1907, 1908 + +Base: 2368 +Linked animations: [10860] +Linked graphics: 1919 + +Base: 2369 + +Base: 2370 +Linked animations: [10628] +Linked graphics: 1905 + +Base: 2371 +Linked animations: [10884] +Linked graphics: 1929 + +Base: 2372 +Linked animations: [10927] +Linked graphics: 1885 + +Base: 2373 +Linked animations: [10906] +Linked graphics: 1934 + +Base: 2374 + +Base: 2375 +Linked animations: [10831, 10832] +Linked graphics: 1920, 1921, 1922, 1923, 1924, 1925, 1926 + +Base: 2376 +Linked animations: [10714] +Linked graphics: 1890 + +Base: 2377 +Linked animations: [10888, 10889] +Linked graphics: 1930, 1931 + +Base: 2378 +Linked animations: [10736, 11932] +Linked graphics: 1891, 2102 + +Base: 2379 +Linked animations: [10904] +Linked graphics: 1889 + +Base: 2380 +Linked animations: [10861] +Linked graphics: 1916 + +Base: 2381 +Linked animations: [10652, 10655] +Linked graphics: 1911, 1912 + +Base: 2382 +Linked animations: [10691, 10694, 10695, 10696, 10699, 10700] +Linked graphics: 1942, 1943, 1944, 1945, 1946, 1947 + +Base: 2383 +Linked animations: [10859] +Linked graphics: 1917 + +Base: 2384 + +Base: 2385 +Linked animations: [10833] +Linked graphics: 1927 + +Base: 2386 +Linked animations: [10773, 10775, 10902] +Linked graphics: 1898, 1900 + +Base: 2387 +Linked animations: [10757] +Linked graphics: 1903 +Linked objects: Gas cloud (41166) + +Base: 2388 +Linked animations: [10926] +Linked graphics: 1884 + +Base: 2389 +Linked animations: [10752] +Linked graphics: 1894, 1895 + +Base: 2390 +Linked animations: [10820] +Linked graphics: 1902 + +Base: 2391 +Linked animations: [10701] +Linked graphics: 1948 + +Base: 2392 + +Base: 2393 +Linked animations: [10776] +Linked graphics: 1901 + +Base: 2394 +Linked animations: [10771, 10897] +Linked graphics: 1896, 1897 + +Base: 2395 +Linked animations: [10912] +Linked graphics: 1935 + +Base: 2396 +Linked animations: [10759] +Linked graphics: 1893 + +Base: 2397 +Linked animations: [10664, 10665, 10666, 10667, 10668, 10669, 10670, 10671, 10672, 10673, 10674, 10675, 10676, 10677, 10678, 10679, 10680, 10681, 10688, 10689, 10690, 10692, 10693, 10697, 10698, 10882] +Linked NPCs: Balance Elemental (8281), Balance Elemental (8282), Balance Elemental (8283), Balance Elemental (8284), Balance Elemental (8546) + +Base: 2398 +Linked animations: [10632, 10633, 10634, 10635, 10636, 10637, 10638, 10639, 10640, 10641, 10656, 10657, 10658, 10659, 10660, 10661] +Linked NPCs: Undead hero (8286), Undead hero (8287), Undead hero (8288), Undead hero (8289), Undead hero (8290), Undead hero (8291), Undead hero (8292), Undead hero (8293), Undead hero (8294), Undead hero (8295), Undead hero (8296), Undead hero (8297) + +Base: 2399 +Linked animations: [10713, 10762, 10763, 10764, 10770, 10772, 10828, 10829, 10896, 10900, 10901, 10903, 10910, 10911, 10983, 10986, 10989] +Linked NPCs: Lucien (8443), Lucien (8497) + +Base: 2400 +Linked animations: [10812, 10813, 10814, 10815, 10816, 10817, 10818, 10819, 13624, 13628, 13631, 13635, 13636, 13785, 13786, 13787, 13788, 13789, 13790, 13791, 13792, 13793, 13794, 13795, 13796, 13832, 13833, 13836] +Linked NPCs: Undead troll (8377), Undead troll (8378), Undead troll (8379), Undead troll (8380), Undead troll (8381), Undead troll (8382), Undead troll (8383), Undead troll (8384), Undead troll (8385), Undead troll (8386), Undead troll (8387), Undead troll (8388), Undead troll (8389), Undead troll (8390), Undead troll (8391), Undead troll (8392), Easta Buni (9689), Icy Bones (10040), Icy Bones (10041), Icy Bones (10042), Icy Bones (10043), Icy Bones (10044), Icy Bones (10045), Icy Bones (10046), Icy Bones (10047), Icy Bones (10048), Icy Bones (10049), Icy Bones (10050), Icy Bones (10051), Icy Bones (10052), Icy Bones (10053), Icy Bones (10054), Icy Bones (10055), Icy Bones (10056), Icy Bones (10057), Ice troll (10782), Ice troll (10783), Ice troll (10784), Ice troll (10785), Ice troll (10786), Ice troll (10787), Ice troll (10788), Ice troll (10789), Ice troll (10790), Thrower troll (10791), Thrower troll (10792), Thrower troll (10793), Thrower troll (10794), Thrower troll (10795), Thrower troll (10796), Kolodion (11301), River troll (11454) + +Base: 2401 +Linked animations: [10642, 10644, 10917, 10918, 10919, 10920, 10921, 10922, 10923, 10924] +Linked NPCs: Tormented demon (8349), Tormented demon (8350), Tormented demon (8351), Tormented demon (8352), Tormented demon (8353), Tormented demon (8354), Tormented demon (8355), Tormented demon (8356), Tormented demon (8357), Tormented demon (8358), Tormented demon (8359), Tormented demon (8360), Tormented demon (8361), Tormented demon (8362), Tormented demon (8363), Tormented demon (8364), Tormented demon (8365), Tormented demon (8366) + +Base: 2402 +Linked animations: [10931, 10932] + +Base: 2403 +Linked animations: [10933, 10934, 10935] + +Base: 2404 +Linked animations: [10930, 10936] +Linked objects: null (10812) + +Base: 2405 +Linked animations: [10979, 11668, 11669, 11670] +Linked NPCs: Lazy Khazard Guard (7524), Lazy Khazard Guard (7525), Lazy Khazard Guard (7526), Lazy Khazard Guard (7527) +Linked objects: Lazy Khazard Guard (41494), Lazy Khazard Guard (41495), Lazy Khazard Guard (41496), Lazy Khazard Guard (41497) + +Base: 2406 +Linked animations: [10996, 10997, 10998, 10999, 11000, 11001] +Linked NPCs: Turkey (8501), Turkey (9039) + +Base: 2407 +Linked animations: [11017, 11018] +Linked graphics: 1965, 1966 + +Base: 2408 +Linked animations: [11014, 11015, 11016] +Linked graphics: 1959, 1960, 1961, 1962, 1963, 1964 + +Base: 2409 +Linked animations: [11050] +Linked graphics: 1970 + +Base: 2410 +Linked animations: [11049, 11058] +Linked graphics: 1969, 1972 + +Base: 2411 +Linked animations: [11045, 13634] +Linked graphics: 1973, 2597 + +Base: 2412 +Linked animations: [11034] +Linked graphics: 1967 + +Base: 2413 +Linked animations: [11046, 11047, 12686] +Linked NPCs: Santa Claus (8540), Santa Claus (9400) +Linked objects: Santa (47857) + +Base: 2414 +Linked animations: [11054, 11055, 11056] +Linked objects: Reindeer (41725), Reindeer (41726), Reindeer (41727), Reindeer (41728), Reindeer (41729), Reindeer (41730), Reindeer (41731), Reindeer (41732), Sleigh (41735), Sleigh (41736), Sleigh (41737), Sleigh (41738), Sleigh (41739), Sleigh (41740), Sleigh (41741), Sleigh (41742), Sleigh (41743), Sleigh (41744) + +Base: 2415 +Linked animations: [11035] +Linked graphics: 1968 + +Base: 2416 +Linked animations: [8946, 8947, 8948, 8949, 8951, 8952, 8965, 8966, 8967, 8968, 11027, 11036, 11037, 11038, 11039, 11040] +Linked NPCs: Nial Swiftfling (5188), Yeti (7379), Yeti (7380), Prince Vargas (7388), Nial Swiftfling (7391), null (7403), Yeti (8515), Yeti (8516) +Linked graphics: 1579 +Linked objects: Yeti (41685) + +Base: 2417 +Linked animations: [11032] + +Base: 2418 +Linked animations: [11105, 11106, 11109] +Linked graphics: 1982, 1983, 1984 + +Base: 2419 +Linked animations: [11080] +Linked graphics: 1978 + +Base: 2420 +Linked animations: [11128] +Linked graphics: 1988 + +Base: 2421 +Linked animations: [11127] +Linked graphics: 1986 + +Base: 2422 +Linked animations: [11086] +Linked graphics: 1974 + +Base: 2423 +Linked animations: [11101, 11102, 11103, 11222] +Linked graphics: 1979, 1980, 1981, 1998 + +Base: 2424 +Linked animations: [11134, 11135] +Linked graphics: 1990, 1991 + +Base: 2425 +Linked animations: [11137] +Linked graphics: 1992 + +Base: 2426 +Linked animations: [11126] +Linked graphics: 1987, 1989 + +Base: 2427 +Linked animations: [11110] +Linked graphics: 1985 + +Base: 2428 +Linked animations: [11098, 11099, 11100] +Linked graphics: 1975, 1976, 1977 + +Base: 2429 +Linked animations: [11090, 11129] +Linked objects: Pyre (41909), Pyre (41910) + +Base: 2430 +Linked animations: [11072, 11073, 11074, 11075, 11076, 11077, 11078, 11079, 11081, 11092, 11093, 11094, 11095, 11096, 11097, 11104, 11107, 11108] +Linked NPCs: Wounded phoenix (8547), Phoenix (8548), Phoenix (8549), Phoenix (8575), Phoenix (8576), Guardian (8906), Guardian (9724) + +Base: 2431 +Linked animations: [11085] +Linked NPCs: Large egg (8552) + +Base: 2432 +Linked animations: [11111, 11112, 11113, 11114, 11115, 11116, 11117, 11118, 11119, 11120, 11121, 11122, 11123, 11124, 11125, 11130, 11131, 11132, 11133, 11136] +Linked NPCs: Lesser reborn warrior (8557), Lesser reborn warrior (8558), Greater reborn warrior (8559), Greater reborn warrior (8560), Lesser reborn ranger (8561), Lesser reborn ranger (8562), Greater reborn ranger (8563), Greater reborn ranger (8564), Lesser reborn mage (8565), Lesser reborn mage (8566), Greater reborn mage (8567), Greater reborn mage (8568), Lesser reborn warrior (8569), Greater reborn warrior (8570), Lesser reborn ranger (8571), Greater reborn ranger (8572), Lesser reborn mage (8573), Greater reborn mage (8574) + +Base: 2433 +Linked animations: [11082, 11083, 11084, 11087, 11138, 11139, 11140] +Linked NPCs: Phoenix eggling (8550), Phoenix eggling (8551), Phoenix eggling (8577), Phoenix eggling (8578), Phoenix eggling (9189), Phoenix eggling (9255) + +Base: 2434 +Linked animations: [11149] +Linked graphics: 788 + +Base: 2435 +Linked animations: [11205] +Linked objects: Soul obelisk (42010), Soul obelisk (42011), Soul obelisk (42012), null (42273), Soul obelisk (42274), Soul obelisk (42275) + +Base: 2436 +Linked animations: [11200, 11201, 11202, 11203, 11204, 12731] +Linked NPCs: Avatar of Creation (8597), Avatar of Creation (8614), Decaying avatar (9437) + +Base: 2437 +Linked animations: [11195, 11196, 11197, 11198, 11199] +Linked NPCs: Avatar of Destruction (8596), Avatar of Destruction (8615) + +Base: 2438 +Linked animations: [11212, 11213, 11214, 11215, 11216, 11217] +Linked NPCs: Baby kurask (8622), Baby kurask (9249) + +Base: 2439 +Linked animations: [11206, 11207, 11208, 11209] +Linked graphics: 1993, 1994, 1995, 1996 + +Base: 2440 +Linked animations: [11223] +Linked graphics: 1999 + +Base: 2441 + +Base: 2442 + +Base: 2443 +Linked animations: [1714] +Linked graphics: 313 + +Base: 2444 +Linked animations: [1712] +Linked graphics: 319 + +Base: 2445 +Linked animations: [1134, 1674, 1675, 1676, 1677, 1678, 1679, 1680, 1681, 1682, 1683, 1684, 1685, 1686, 1687, 1688, 1689, 1690, 1691, 1692, 1693, 1699, 1700, 1701, 1702, 1703, 1704, 1706, 1707, 1715] +Linked objects: Evil tree (11434), Evil tree (11435), Evil tree (11436), Evil oak tree (11437), Evil oak tree (11438), Evil oak tree (11439), Evil willow tree (11440), Evil willow tree (11441), Evil willow tree (11442), Evil maple tree (11443), Evil maple tree (11444), Evil maple tree (11915), Evil yew tree (11916), Evil yew tree (11917), Evil yew tree (11918), Evil magic tree (11919), Evil magic tree (11920), Evil magic tree (11921), Elder evil tree (11922), Elder evil tree (11923), Elder evil tree (11924), null (11925), null (11926), null (11927), null (11928), null (11929), null (12711), null (12712), null (14846), null (14847), null (14848), null (14849), null (14883), null (14884), null (14885) + +Base: 2446 +Linked animations: [1694, 1695, 1696, 1697, 1698] +Linked objects: Seedling (11391), Sapling (11392), Sapling (11393), Young tree (11394), Young tree (11395) + +Base: 2447 +Linked animations: [353, 354, 355, 644, 1708] +Linked graphics: 314 +Linked objects: Evil root (11426), Evil root (11427), Evil root (11428), Evil root (11429), Evil root (11430), Evil root (11431), Evil root (11432), Evil root (11433), Root (47961), Root (47962), Root (47963), Root (47964), Root (47965), Root (47966), Root (47967) + +Base: 2448 +Linked animations: [643, 1709, 1710, 1711] +Linked graphics: 315, 316, 317, 318 + +Base: 2449 +Linked animations: [11514] +Linked objects: Egg-painting machine (30120), Egg-painting machine (49143) + +Base: 2450 +Linked animations: [11376, 11377] +Linked objects: Glyph (18980) + +Base: 2451 +Linked animations: [11333, 11334, 11335, 11336] +Linked objects: Portal (16577), Portal (42611) + +Base: 2452 +Linked animations: [11286, 11287] +Linked objects: Hole (18977) + +Base: 2453 +Linked animations: [175, 11284] +Linked objects: Dirty plates (18975) + +Base: 2454 +Linked animations: [11318, 11319, 11384, 11385] + +Base: 2455 +Linked animations: [11339, 11340] +Linked objects: Spear (42623) + +Base: 2456 +Linked animations: [11311, 11312, 11317] + +Base: 2457 +Linked animations: [11292, 11305, 11483] +Linked objects: Statue with bowl (42602) + +Base: 2458 +Linked animations: [11315, 11316] + +Base: 2459 +Linked animations: [11313, 11314] + +Base: 2460 +Linked animations: [1719, 1720, 1721, 1741, 1742] +Linked objects: Ur-taal (18987), Ur-meg (18988), Ur-lun (18989), Ur-pel (18990), Ur-zek (19956), Ur-vass (21251), Ur-tag (21252) + +Base: 2461 +Linked animations: [11343, 11344, 11345, 11346, 11347, 11348, 11349, 11350] +Linked objects: Rocks (42584) + +Base: 2462 +Linked animations: [11249, 11250] +Linked graphics: 2012, 2013 + +Base: 2463 +Linked animations: [11389] +Linked graphics: 2005 + +Base: 2464 +Linked animations: [11276, 11379] +Linked graphics: 2002, 2014 + +Base: 2465 +Linked animations: [11366] +Linked graphics: 580 + +Base: 2466 +Linked animations: [11277] +Linked graphics: 2015 + +Base: 2467 +Linked animations: [11280, 11281, 11282] +Linked graphics: 2016, 2017, 2018 + +Base: 2468 +Linked animations: [11257] +Linked graphics: 2007 + +Base: 2469 +Linked animations: [11360, 11369] +Linked graphics: 665, 1714 + +Base: 2470 +Linked animations: [11322, 11323, 11324, 11325, 11326] +Linked graphics: 320, 321, 322, 323, 402 + +Base: 2471 +Linked animations: [11246, 11247, 11248] +Linked graphics: 2009, 2010, 2011 + +Base: 2472 +Linked animations: [11351, 11352, 11353, 11354, 11355, 11356] +Linked objects: Fighters (16579), Fighters (16580), Fighters (16581), Fighters (16582), Fighters (16583), Fighters (16584), Fighters (17383) + +Base: 2473 +Linked animations: [11239, 11240, 11241, 11242, 11244, 11245, 11251, 11252, 11254, 11255, 11256, 11300] +Linked NPCs: Bandos avatar (4540), Bandos avatar (5460), Bandos avatar (5461) + +Base: 2474 +Linked animations: [11412] +Linked objects: null (42630) + +Base: 2475 +Linked animations: [11414, 11464, 11465, 11466, 11467, 11468, 11469, 11470, 11471, 11472, 11473, 11474, 11475, 11476, 11477, 11478, 11479, 11480] +Linked NPCs: Ogre chieftain (852), null (5175), Ogre shaman (5176), Ogre shaman (5177), null (5180), Ogre shaman (5181), null (5183), Ogre shaman (5184), null (5186), Ogre shaman (5187), null (5189), Ogre shaman (5190), null (5192), Ogre shaman (5193), Ogre chieftain (8660) + +Base: 2476 +Linked animations: [9882, 11429, 11430, 11440] +Linked graphics: 588, 2022, 2023, 2024 + +Base: 2477 +Linked animations: [2088] +Linked graphics: 2019 + +Base: 2478 +Linked animations: [2099] +Linked graphics: 2021 + +Base: 2479 +Linked animations: [2089] +Linked graphics: 2020 + +Base: 2480 +Linked animations: [11506, 11520, 11522] +Linked graphics: 2034, 2035 +Linked objects: null (30078), null (30079) + +Base: 2481 +Linked animations: [11554] +Linked graphics: 2038 + +Base: 2482 +Linked animations: [11517, 11526] +Linked graphics: 2032, 2033 + +Base: 2483 +Linked animations: [11523] +Linked graphics: 2036 + +Base: 2484 +Linked animations: [11555] +Linked graphics: 2039 + +Base: 2485 +Linked animations: [11538] +Linked graphics: 2037 + +Base: 2486 +Linked animations: [11533, 11534, 11535] +Linked objects: Nut machine (30124), Nut machine (30125), Nut machine (30126), Nut machine (49148), Nut machine (49149) + +Base: 2487 +Linked animations: [11537] +Linked objects: Clock (42725), Clock (49243) + +Base: 2488 +Linked animations: [11527, 11528, 11529] +Linked objects: Nut machine (30121), Nut machine (30122), Nut machine (30123), Nut machine (49145), Nut machine (49146) + +Base: 2489 +Linked animations: [11512] +Linked objects: Egg-painting machine (30118), Egg-painting machine (49138) + +Base: 2490 +Linked animations: [11530, 11531, 11532] +Linked objects: Nut machine (30127), Nut machine (30128), Nut machine (30129), Nut machine (49151), Nut machine (49152) + +Base: 2491 +Linked animations: [11548, 11549] +Linked objects: Wheel (30084), Wheel (30085), null (49110) + +Base: 2492 +Linked animations: [11507, 11508, 11509, 11539] +Linked objects: Easter Bird (30086), Easter Bird (30087), Easter Bird (30088), null (49111) + +Base: 2493 +Linked animations: [11501, 11502, 11503, 11504, 11505, 11510, 11516, 11518, 11519, 11521, 11525] +Linked NPCs: Easter Bunny (7407), Easter Bunny (7408), Easter Bunny (7409), Easter Bunny Jr (7410), Easter Bunny Jr (7411), Easter Bunny Jr (7412), Easter Bunny (9687) + +Base: 2494 +Linked animations: [11583, 11584, 11585] +Linked objects: null (42882), null (42883), null (42884) + +Base: 2495 +Linked animations: [11616] +Linked objects: null (42752), null (42753), null (42767) + +Base: 2496 +Linked animations: [11559, 11560, 11561, 11580, 11581] +Linked objects: Ice block (42805), Ice block (42806), Ice block (42807), Ice (42809), Ice (42811), Ice (42813), Ice (42815), Ice (42817), Ice (42819), Ice (42821), Ice (42823), Ice (42825), Ice (42827), Ice (42829), Ice (42831), Ice (42832), Ice (42833), Ice (42834), Ice (42835), Ice (42836), Ice (42837), Ice (42838), Ice (42839), Ice (42840), Ice (42841), Ice (42842), Ice (42843), Ice block (42879), Ice block (42880) + +Base: 2497 +Linked animations: [11565, 11566] +Linked objects: Blocked icy stream (42799) + +Base: 2498 +Linked animations: [11494] +Linked objects: Crumbling statue (42852) + +Base: 2499 +Linked animations: [11497, 11720, 11721, 11722] +Linked objects: null (42765), Fish (43201), Fish (43202), Fish (43203) + +Base: 2500 +Linked animations: [11591, 11592] +Linked graphics: 2045, 2046 + +Base: 2501 +Linked animations: [11563, 11564] +Linked graphics: 2030, 2031 + +Base: 2502 +Linked animations: [11582] +Linked graphics: 2040, 2041, 2042, 2043, 2044 + +Base: 2503 +Linked animations: [11575, 11576] + +Base: 2504 +Linked animations: [11586, 11587] +Linked NPCs: null (7457), Natural historian (7458) + +Base: 2505 +Linked animations: [11498, 11499, 11500, 11593] +Linked NPCs: null (7454), Muspah (7455) +Linked graphics: 2029 + +Base: 2506 +Linked animations: [11496, 11570] +Linked NPCs: Fire raft (7452), Fire raft (7453) + +Base: 2507 + +Base: 2508 +Linked animations: [11621] +Linked objects: Rubble (32719) + +Base: 2509 +Linked animations: [11624] +Linked graphics: 2047 + +Base: 2510 +Linked animations: [11645] +Linked objects: Blue block (42939), Red block (42940), Green block (42941), Yellow block (42942) + +Base: 2511 +Linked animations: [11626, 11627, 11628, 11629, 11630, 11643] +Linked NPCs: Tumeken's shadow (7475), Tumeken's shadow (7476), Tumeken's shadow (7477), Tumeken's shadow (7479), Tumeken's shadow (7480) + +Base: 2512 +Linked animations: [11638, 11639, 11640, 11641, 11642] +Linked NPCs: Golem guard (7497), Ice elemental (10460), Ice elemental (10461), Ice elemental (10462), Ice elemental (10463), Ice elemental (10464), Ice elemental (10465), Ice elemental (10466), Ice elemental (10467), Ice elemental (10468) + +Base: 2513 +Linked animations: [11653] +Linked objects: Enchanted sconce (42990) + +Base: 2514 +Linked animations: [11654, 11655] + +Base: 2515 +Linked animations: [11652] +Linked objects: Tumeken's image (42986) + +Base: 2516 +Linked animations: [11644] + +Base: 2517 +Linked animations: [11646, 11647, 11648, 11649, 11650, 11651] +Linked objects: Amascut (42974), Apmeken (42975), Crondis (42976), Het (42977), Icthlarin (42978), Scabaras (42979) + +Base: 2518 +Linked animations: [3046, 3047, 5480, 11688] +Linked objects: Cage (9091) + +Base: 2519 +Linked animations: [11706, 11716] +Linked objects: null (43066) + +Base: 2520 +Linked animations: [11707, 11708, 11709] + +Base: 2521 +Linked animations: [11725] +Linked objects: null (43425) + +Base: 2522 +Linked animations: [11723] +Linked objects: Tickertape machine (43406) + +Base: 2523 +Linked animations: [11717, 11718, 11719] +Linked objects: Engine (43159), Engine (43163), Broken engine (43164) + +Base: 2524 +Linked animations: [11713] +Linked objects: null (43094), null (43095), null (43096), null (43097), null (43098), null (43099), Well (43100), Well (43101), Well (43102), Well (43103), Well (43104), Well (43105) + +Base: 2525 +Linked animations: [11749] +Linked graphics: 2049 + +Base: 2526 +Linked animations: [11759, 11760, 11761, 11762, 11763, 11764, 11765] + +Base: 2527 +Linked animations: [11766] + +Base: 2528 +Linked animations: [11767, 11768, 11769, 11770] + +Base: 2529 +Linked animations: [11711, 11712] +Linked NPCs: null (8674), Polar bear (8675), Jim (8676) + +Base: 2530 +Linked animations: [11714] +Linked NPCs: Chuck (8679) + +Base: 2531 +Linked animations: [11715] +Linked objects: Chuck (43424) + +Base: 2532 +Linked animations: [11734, 11740, 11741] +Linked NPCs: Larry (7578), Larry (7579) + +Base: 2533 + +Base: 2534 +Linked animations: [11808] +Linked NPCs: Snake (1875) +Linked objects: Snake basket (21249) + +Base: 2535 +Linked animations: [7525, 7526, 11819, 11820] +Linked objects: Spring device (43587) + +Base: 2536 +Linked animations: [7527] + +Base: 2537 +Linked animations: [11872, 11874, 11886] +Linked graphics: 2060, 2061, 2062 + +Base: 2538 +Linked animations: [11858] +Linked graphics: 2057 + +Base: 2539 +Linked animations: [11884, 11888, 11889, 11890, 11891] +Linked graphics: 2063, 2064, 2065, 2066, 2067 + +Base: 2540 +Linked animations: [11824, 11853] +Linked graphics: 2051, 2056 + +Base: 2541 +Linked animations: [11877] +Linked objects: null (43691), null (43692), null (43693), null (43694), null (43695), null (43696), null (43697), null (43698), Green command tent (43791), Blue command tent (43792), Yellow command tent (43793), Red command tent (43794), null (43839), null (43840) + +Base: 2542 +Linked animations: [11876] +Linked objects: Huge flag (43768), null (43769), null (43770) + +Base: 2543 +Linked animations: [11847, 11894] +Linked objects: null (43827), null (43828), Map table (43829), Map table (43830) + +Base: 2544 +Linked animations: [11859, 11860] +Linked objects: Castle turret (43730), Castle turret (43731), Castle turret (43732) + +Base: 2545 +Linked animations: [11875] +Linked objects: Cave entrance (43666) + +Base: 2546 +Linked animations: [11887] +Linked objects: Pile of wood (43748), Pile of wheels (43749), Pile of metal (43750), Pile of ropes (43751), Pile of rocks (43752), null (43763), null (43764), null (43765), null (43766) + +Base: 2547 +Linked animations: [11861, 11862] + +Base: 2548 +Linked animations: [11882, 11883] +Linked objects: Catapult (43744) + +Base: 2549 +Linked animations: [11849, 11850, 11851, 11852] +Linked graphics: 2052, 2053, 2054, 2055 + +Base: 2550 +Linked animations: [11892] +Linked objects: null (43736) + +Base: 2551 +Linked animations: [11863, 11864] +Linked graphics: 2058, 2059 + +Base: 2552 +Linked animations: [11823] +Linked graphics: 1280 + +Base: 2553 +Linked animations: [11822] +Linked graphics: 1275 + +Base: 2554 +Linked animations: [11825, 11826, 11827, 11828, 11829, 11830, 11831, 11832, 11833, 11834, 11835, 11836, 11837, 11838, 11839, 11840, 11841, 11842, 11843, 11844, 11845, 11846] +Linked NPCs: Dwarf squad (light) (red) (8729), Elf squad (light) (red) (8730), Goblin squad (light) (red) (8731), Dwarf squad (light) (blue) (8732), Elf squad (light) (blue) (8733), Goblin squad (light) (blue) (8734), null (8735), null (8740), null (8745), null (8750), null (8755), null (8760), null (8765), null (8770), null (8775), null (8780), null (8785), null (8790), null (8875), null (8880), null (8885), null (8890), null (8895), null (8900), null (8905), null (8910), Dwarf squad (red) (8931), null (9050), null (9055), null (9060), null (9065) +Linked objects: Rescued TzHaar (43635), Rescued TzHaar (43636), Rescued TzHaar (43637), Rescued TzHaar (43638), Rescued TzHaar (43639), Rescued TzHaar (43640), Rescued TzHaar (43641), Rescued TzHaar (43642), Rescued TzHaar (43643) + +Base: 2555 +Linked animations: [2587, 11821] +Linked objects: TzHaar (43661) + +Base: 2556 +Linked animations: [11865, 11866, 11867, 11868, 11869, 11870] +Linked NPCs: null (8942), Dwarven recruiter (8943), null (8944), Elven recruiter (8945), null (8946), Goblin recruiter (8947), Banker (8948) + +Base: 2557 +Linked animations: [11895, 11896, 11897, 11898, 11899] +Linked NPCs: Sphinx (1990), Sphinx (2637) + +Base: 2558 +Linked animations: [11905, 11906, 11907, 11912, 11913, 11914] +Linked NPCs: Marker plant (9150), Marker plant (S) (9151), Marker plant (NE) (9152), Marker plant (NW) (9153), Marker plant (N) (9154), Marker plant (SE) (9155), Marker plant (SW) (9156), Marker plant (E) (9157), Marker plant (W) (9158) + +Base: 2559 +Linked animations: [11915, 11916, 11917, 11918] +Linked graphics: 2068, 2069, 2070, 2071, 2072, 2073, 2074, 2075, 2076, 2077, 2078, 2079, 2080, 2081, 2082, 2083, 2084, 2085, 2086, 2087, 2088, 2089, 2090, 2091, 2092, 2093, 2094, 2095, 2096, 2097, 2098, 2099 + +Base: 2560 +Linked animations: [11925] +Linked objects: Fire trap (44221) + +Base: 2561 +Linked animations: [11928] +Linked objects: Human detection spell (44220) + +Base: 2562 +Linked animations: [11927] +Linked objects: null (44237), Pedestal (44238), Pedestal (44239) + +Base: 2563 +Linked animations: [11934] +Linked objects: Puddle (44097) + +Base: 2564 +Linked animations: [11926] +Linked objects: Rubble (44199) + +Base: 2565 +Linked animations: [11935, 11936, 11937, 11938, 11939, 11940, 11941] +Linked NPCs: Killerwatt (3201), Killerwatt (3202), Elemental creature (9432) +Linked objects: Cage (44244) + +Base: 2566 +Linked animations: [11930] +Linked graphics: 2101 + +Base: 2567 +Linked animations: [11929] +Linked graphics: 2103 + +Base: 2568 +Linked animations: [917, 14287, 14288] +Linked objects: Entrance (3108), Entrance (3111), Entrance (3112), Entrance (3113), Entrance (3114), null (6254), Human flag (10541), Human flag (10542), Dwarf flag (10543), Dwarf flag (10544), Elf flag (10545), Elf flag (10546), Gnome flag (10547), Gnome flag (10548), Werewolf flag (10549), Werewolf flag (10550), TzHaar flag (10551), TzHaar flag (10552), Entrance (27688), Entrance (27690) + +Base: 2569 +Linked animations: [3483, 4539, 7069, 11996, 11997, 11998] +Linked graphics: 1221, 2104, 2105, 2110, 2111, 2112 + +Base: 2570 +Linked animations: [408, 11962] +Linked objects: Geoff (44341), Geoff (44342) + +Base: 2571 +Linked animations: [411] + +Base: 2572 +Linked animations: [11953, 11954, 11955, 11959] +Linked graphics: 2106, 2107 +Linked objects: Dartboard (44301) + +Base: 2573 +Linked animations: [1669, 11972] +Linked graphics: 341, 2108 + +Base: 2574 +Linked animations: [12043, 12044, 12045, 12046, 13437] +Linked graphics: 2119, 2120, 2121, 2122, 2386 + +Base: 2575 +Linked animations: [12037, 12038, 12039, 12040, 12041, 12042] +Linked NPCs: Aquanite (9172) + +Base: 2576 +Linked animations: [12047] +Linked graphics: 2123 + +Base: 2577 +Linked animations: [12056, 12058] +Linked graphics: 2133, 2134 + +Base: 2578 +Linked animations: [12082, 12083, 12084, 12085, 12086, 12087] +Linked graphics: 2124, 2125, 2126, 2127, 2128, 2129 + +Base: 2579 +Linked animations: [12060, 12061, 12062, 12063, 12064, 12065, 12066, 12067, 12068, 12069, 12070, 12071, 12072, 12073, 12074, 12075, 12076, 12077, 12078, 12079, 12080, 12081, 12104, 12105] +Linked NPCs: Skeletal horror (9176), Skeletal horror (9177), Skeletal horror (9178), Skeletal horror (9179), Skeletal horror (9180) + +Base: 2580 +Linked animations: [12048, 12049, 12050, 12051, 12052, 12053, 12054] +Linked NPCs: Odd Old Man (9173), Odd Old Man (9174) + +Base: 2581 +Linked animations: [12099, 12100, 12101, 12102, 12103] +Linked NPCs: Tail (9183) +Linked graphics: 2132 + +Base: 2582 +Linked animations: [12089, 12090, 12091, 12092, 12093, 12094, 12095, 12096, 12097, 12098] +Linked NPCs: Right hand (9181), Left hand (9182) +Linked graphics: 2130, 2131 + +Base: 2583 +Linked animations: [12113] + +Base: 2584 +Linked animations: [12116, 12117] + +Base: 2585 +Linked animations: [12135, 12136, 12137, 12138] +Linked objects: Machine (7193), Machine (44979), null (44980) + +Base: 2586 +Linked animations: [12123, 12124, 12125, 12130] +Linked objects: Sorting machine (45028), Sorting machine (45034) + +Base: 2587 +Linked animations: [2314, 12111] + +Base: 2588 +Linked animations: [12166] +Linked objects: Bowl (45055) + +Base: 2589 +Linked animations: [12165, 12167, 12168] +Linked objects: Fire pit (45056), Rod (45057) + +Base: 2590 +Linked animations: [12112] + +Base: 2591 +Linked animations: [12146, 12147, 12148, 12149, 12150, 12151] +Linked NPCs: Chaos dwogre (8771) + +Base: 2592 +Linked animations: [12178] +Linked graphics: 2142 + +Base: 2593 +Linked animations: [12182] +Linked graphics: 2143 + +Base: 2594 +Linked animations: [12172] +Linked graphics: 2140 + +Base: 2595 +Linked animations: [12159, 12160, 12176] +Linked graphics: 2137, 2138, 2141 + +Base: 2596 +Linked animations: [12225] + +Base: 2597 +Linked animations: [12218, 12219, 12223] +Linked objects: Collapsed mineral deposit (5990), Collapsed mineral deposit (45075) + +Base: 2598 +Linked animations: [12224] + +Base: 2599 +Linked animations: [12213] +Linked objects: Pulley lift (45079) + +Base: 2600 +Linked animations: [12293] +Linked objects: Blacksmith working the bellows (45311) + +Base: 2601 +Linked animations: [1561] +Linked graphics: 2275, 2276 + +Base: 2602 +Linked animations: [12304] +Linked objects: Weather vane (46020) + +Base: 2603 +Linked animations: [12262, 12273, 12924] + +Base: 2604 +Linked animations: [12275] +Linked objects: Ladder (45786) + +Base: 2605 +Linked animations: [12240, 12241, 12242, 12243] +Linked objects: Wooden pillar (45569), Wooden pillar (45570) + +Base: 2606 +Linked animations: [12281] +Linked objects: Roots (45599) + +Base: 2607 +Linked animations: [12279] +Linked objects: Rock (45596) + +Base: 2608 +Linked animations: [12286, 12287] + +Base: 2609 +Linked animations: [5502, 12271, 13736, 13737] +Linked graphics: 2148, 2183, 2614, 2615 + +Base: 2610 +Linked animations: [12236] +Linked graphics: 2151 + +Base: 2611 + +Base: 2612 + +Base: 2613 +Linked animations: [12244, 12245] +Linked graphics: 2149, 2150, 2271 + +Base: 2614 +Linked animations: [8843, 8844, 12170, 12193, 12194, 12195, 12196, 12197, 12198, 12199, 12200, 12201, 12202, 12203, 12204, 12205, 12206, 12207, 12208, 12209, 12210, 12220, 12221, 12222] +Linked NPCs: Living rock protector (8832), Living rock striker (8833), Living rock patriarch (8834), Living rock remains (8837), Living rock remains (8838), Living rock remains (8839), Rock critter (8840), Pit rock protector (11564), Pit rock protector (11588), Pit rock protector (11589) +Linked graphics: 1565, 2139 +Linked objects: Pit rock protector (39262), Pit rock protector (41605) + +Base: 2615 +Linked animations: [12298] +Linked objects: null (3181), null (3193), null (3198), null (3201), null (4140), null (27662), null (27671), null (27674), null (27675), null (27678), null (27679), null (27680), null (27681), null (27683), Staircase (27866), null (27875), null (27876), null (27883), null (45630), null (45631), null (45632), Candlestand (46551), null (46552), Table (46564), Candlestand (46807), Candlestand (46808), Candlestand (46809), Candlestand (46831), Candlestand (46832), Candlestand (46833), Staircase (47364), null (47451), null (47452), null (47457), null (47458), null (47462), null (47463), null (47591), null (47592), null (47593), null (47647), null (47653), null (47658), null (47659), Table (47677), Table (47681), Table (47684), Table (47685), Table (47686), null (47711), null (47860), null (47861), Candlestand (47872), Table (47873), null (47874), null (47875), null (53261), null (53262), null (53263), null (54693) + +Base: 2616 +Linked animations: [12294, 12295, 12296] +Linked NPCs: Lumbridge Sage (2244) + +Base: 2617 + +Base: 2618 +Linked animations: [3336, 9428, 12599, 12600] +Linked objects: Open chest (49896), Open chest (49897), Locked chest (49900), Open chest (49908), Open chest (49909), Open chest (49920), Open chest (49921), Open chest (53821), Open chest (53822) + +Base: 2619 +Linked animations: [12359, 12360] +Linked objects: Ivy (46318), Ivy stump (46319), Ivy (46320), Ivy stump (46321), Ivy (46322), Ivy stump (46323), Ivy (46324), Ivy stump (46325) + +Base: 2620 +Linked animations: [12385, 12386, 12387, 12388, 12389, 12390, 12391, 12392, 12393] +Linked graphics: 2157, 2158, 2159, 2160, 2161, 2162, 2163, 2164 + +Base: 2621 +Linked animations: [12351, 12352, 12353, 12354, 12355, 12356, 12357] +Linked graphics: 2, 3 +Linked objects: Woodcutting stump (21305), Stump (46328) + +Base: 2622 +Linked animations: [12399, 12401, 12402] +Linked objects: Conveyor belt hopper (46304) + +Base: 2623 +Linked animations: [12374] +Linked graphics: 2156 + +Base: 2624 +Linked animations: [12369, 12370, 12371, 12372] +Linked graphics: 2152, 2153, 2154, 2155 + +Base: 2625 +Linked animations: [12358] +Linked graphics: 0 + +Base: 2626 +Linked animations: [163, 164, 165, 167, 2958, 4784, 12403, 12404, 12405, 12406, 12407, 12408, 12409, 12410, 12984, 12985, 12986, 12987, 12988, 12989, 12990, 12991, 12992, 12997, 14621] +Linked NPCs: Hobgoblin (122), Hobgoblin (123), Hobgoblin (2685), Hobgoblin (2686), Hobgoblin (2687), Hobgoblin (2688), Hobgoblin Champion (3061), Hobgoblin (3583), Hobgoblin (4898), Hobgoblin (6275), Hobgoblin Geomancer (10059), Hobgoblin Geomancer (10060), Hobgoblin Geomancer (10061), Hobgoblin Geomancer (10062), Hobgoblin Geomancer (10063), Hobgoblin Geomancer (10064), Hobgoblin Geomancer (10065), Hobgoblin Geomancer (10066), Hobgoblin Geomancer (10067), Hobgoblin Geomancer (10068), Hobgoblin Geomancer (10069), Hobgoblin Geomancer (10070), Hobgoblin Geomancer (10071), Hobgoblin Geomancer (10072), Hobgoblin (10236), Hobgoblin (10237), Hobgoblin (10238), Hobgoblin (10239), Hobgoblin (10240), Hobgoblin (10241), Hobgoblin (10242), Hobgoblin (10243), Hobgoblin (10244), Hobgoblin (10245) +Linked graphics: 2777 +Linked objects: Hobgoblin (13368) + +Base: 2627 +Linked animations: [12412] +Linked objects: Waterlily (1175), Waterlily (1176), Waterlily (1177) + +Base: 2628 +Linked animations: [12417] + +Base: 2629 +Linked animations: [12416] +Linked graphics: 2165 + +Base: 2630 +Linked animations: [12432] + +Base: 2631 +Linked animations: [12434] +Linked objects: null (46501), null (46502), null (46503), null (46504), Light receiver (46505), Light receiver (46506), Light receiver (46507), Light receiver (46508) + +Base: 2632 +Linked animations: [12433] + +Base: 2633 +Linked animations: [12427] +Linked NPCs: Crystal core (8960), Crystal core (8961), Crystal core (8963), Crystal core (8965) + +Base: 2634 +Linked animations: [12426] +Linked graphics: 2170 + +Base: 2635 +Linked animations: [12424] +Linked objects: Energised pillar (46519) + +Base: 2636 +Linked animations: [12428] +Linked graphics: 2167, 2168 + +Base: 2637 +Linked animations: [12425, 12430] +Linked graphics: 2166, 2169 + +Base: 2638 +Linked animations: [12439, 12440, 12447, 12448] +Linked graphics: 761, 762, 2174, 2175 + +Base: 2639 +Linked animations: [12443, 12444, 12451, 12452] +Linked graphics: 2172, 2173, 2176, 2177 + +Base: 2640 +Linked animations: [12501, 12502, 12503] + +Base: 2641 +Linked animations: [12485, 12488] +Linked objects: Portal (46933), Portal (46934) + +Base: 2642 +Linked animations: [12483, 12484] +Linked NPCs: Grim Reaper (8977) + +Base: 2643 +Linked animations: [12486, 12487] +Linked NPCs: Spider herald (8976) + +Base: 2644 +Linked animations: [12498] +Linked NPCs: Spider (8979) + +Base: 2645 +Linked animations: [12499, 12500] +Linked NPCs: Spider Queen (8975) + +Base: 2646 +Linked animations: [12491, 12497, 12506] +Linked graphics: 2178, 2179, 2180 + +Base: 2647 +Linked animations: [12508] +Linked objects: null (27884), null (47590) + +Base: 2648 +Linked animations: [1545, 1547] +Linked objects: Armour (47408) + +Base: 2650 +Linked animations: [12523, 12524, 12525, 12527, 12528] +Linked NPCs: Imp (8994), Banner carrier (8995), Banner carrier (8996), Banner carrier (8997), Banner carrier (8998), Banner carrier (8999), Banner carrier (9002), Banner carrier (9003), Banner carrier (9004), Banner carrier (9005), Banner carrier (9006), Banner carrier (9007), Banner carrier (9008), Banner carrier (9009), Banner carrier (9012), Banner carrier (9013), Banner carrier (9014), Banner carrier (9015), Banner carrier (9016), Banner carrier (9017), Banner carrier (9018), Banner carrier (9019), Banner carrier (9022), Banner carrier (9023), Banner carrier (9024), Banner carrier (9025), Banner carrier (9026), Banner carrier (9027), Banner carrier (9028), Banner carrier (9029), Banner carrier (9032), Banner carrier (9033) + +Base: 2651 +Linked animations: [5500, 12520] +Linked graphics: 2182, 2188 + +Base: 2652 +Linked animations: [5494, 12521] +Linked graphics: 2181, 2187 + +Base: 2653 +Linked animations: [2934] +Linked graphics: 2192, 2194, 2196, 2198 + +Base: 2654 +Linked animations: [1116] +Linked graphics: 2191, 2193, 2195, 2197, 2283 + +Base: 2655 +Linked animations: [9639] +Linked objects: null (47119), Altar of Zaros (47120), PLACEHOLDER: Runecrafting Altar (50034) + +Base: 2656 +Linked animations: [7535] +Linked objects: Communion portal (47077) + +Base: 2657 +Linked animations: [7536] +Linked NPCs: Altar (9053) +Linked objects: Smashed pedestal (47198), Smashed pedestal (47199) + +Base: 2658 +Linked animations: [12561, 12562] +Linked objects: Trapdoor (4575), Trapdoor (4576) + +Base: 2659 +Linked animations: [2981, 7206, 12533, 12534, 12535, 12536, 12537, 12538] +Linked objects: Ice block (47131), Ice block (47132), Ice block (47165), Ice block (47167) + +Base: 2660 +Linked animations: [12555] +Linked objects: Radiant pedestal (47136), Radiant pedestal (47175), Radiant pedestal (47187), Radiant pedestal (47188), Radiant pedestal (47189), Radiant pedestal (47190), Radiant pedestal (47191), Radiant pedestal (47192), Radiant pedestal (47193), Radiant pedestal (47194), Radiant pedestal (47195) + +Base: 2661 +Linked animations: [2975, 2977, 2978, 2979, 2980, 12556, 12559] +Linked NPCs: Ice demon (9052) + +Base: 2662 +Linked animations: [12550] + +Base: 2663 +Linked animations: [2944, 2962, 2966, 2971, 2973, 2974] +Linked graphics: 1701, 2199, 2200, 2201, 2202, 2203 + +Base: 2664 +Linked animations: [12557, 12558] +Linked graphics: 2210, 2211 + +Base: 2665 +Linked animations: [12560] +Linked graphics: 2212 + +Base: 2666 +Linked animations: [12545, 12546] +Linked graphics: 2208, 2209 + +Base: 2667 +Linked animations: [12530] +Linked graphics: 2204 + +Base: 2668 +Linked animations: [12566] +Linked graphics: 2226 + +Base: 2669 +Linked animations: [12574] +Linked graphics: 2227, 2228, 2229, 2230 + +Base: 2670 +Linked animations: [12576, 12577, 12578, 12579] +Linked graphics: 2231, 2232, 2233, 2234, 2235, 2236, 2237, 2238, 2239, 2240, 2241, 2242, 2243, 2244, 2245, 2246, 2247, 2248, 2249, 2250, 2251, 2252, 2253, 2254, 2255, 2256, 2257, 2258 + +Base: 2671 + +Base: 2672 +Linked animations: [12553, 12590] +Linked graphics: 2266 + +Base: 2673 +Linked animations: [12570, 12571, 12572] +Linked graphics: 2214, 2215, 2216, 2217, 2218, 2219, 2220, 2221, 2222, 2223, 2224, 2225 + +Base: 2674 +Linked animations: [12585, 12586, 12587, 12588] +Linked graphics: 2262, 2263, 2264, 2265 + +Base: 2675 +Linked animations: [12580, 12581, 12582] +Linked graphics: 2259, 2260, 2261 + +Base: 2676 +Linked animations: [12568] +Linked graphics: 2213 + +Base: 2677 +Linked animations: [12540, 12541] +Linked graphics: 2206, 2207 + +Base: 2678 +Linked animations: [1512, 1513] + +Base: 2679 +Linked animations: [1519] +Linked objects: Mast (47340) + +Base: 2680 +Linked animations: [1520] +Linked objects: null (47270) + +Base: 2681 +Linked animations: [1524] +Linked graphics: 2270 + +Base: 2682 +Linked animations: [1522, 1523] +Linked graphics: 333, 2269 + +Base: 2683 +Linked animations: [1526] + +Base: 2684 +Linked animations: [12624] +Linked objects: Sign (14869) + +Base: 2685 +Linked animations: [12623] +Linked objects: Card table (12975) + +Base: 2686 +Linked animations: [72, 3113, 3114, 12617, 12630, 12631] +Linked objects: Sword case (12983) + +Base: 2687 +Linked animations: [12612] +Linked objects: Magic field (12990), Magic field (12991), Magic field (12992), null (14874) + +Base: 2688 +Linked animations: [1568, 2990, 3111, 3112, 3322, 3323, 3328, 3330, 3331, 3332, 3333, 12604] +Linked NPCs: Count Draynor (9356), Count Draynor (9357) +Linked objects: Coffin (158), Coffin (159), Coffin (162) + +Base: 2689 +Linked animations: [12605] +Linked graphics: 567 + +Base: 2690 +Linked animations: [12607, 12613] +Linked graphics: 778 +Linked objects: null (12971), null (12973) + +Base: 2691 +Linked animations: [12622, 12646] +Linked graphics: 779, 2277 + +Base: 2692 +Linked animations: [4608, 4609] + +Base: 2693 +Linked animations: [12660] +Linked objects: Scourge's grave (47785) + +Base: 2694 +Linked animations: [12666, 12687, 12688] + +Base: 2695 +Linked animations: [12644, 12679, 12680, 12681, 12682, 12683] +Linked NPCs: Ebenezer Scourge (9363), null (9369), Ebenezer Scourge (9371) +Linked objects: Scourge's bed (47856) + +Base: 2696 + +Base: 2697 +Linked animations: [12639, 12656, 12684, 12685] +Linked NPCs: Tiny Thom (9366), Tiny Thom (9402), Tiny Thom (9422) + +Base: 2698 +Linked animations: [12659] +Linked graphics: 780 + +Base: 2699 +Linked animations: [12634, 12635, 12636] +Linked graphics: 5 +Linked objects: General Wartface (47790), General Wartface (47791), General Bentnoze (47793), General Bentnoze (47794), Sir Amik Varze (47796), Sir Amik Varze (47797), Cook (47799), Cook (47800), Partygoer (47802), Partygoer (47803), Tiny Thom (47805), Tiny Thom (47806) + +Base: 2700 + +Base: 2701 +Linked animations: [4628] +Linked graphics: 4 + +Base: 2702 +Linked animations: [12705, 12706, 12707, 12708, 12709, 12710] +Linked objects: Doorway (47921), Doorway (47922), null (47923), Doorway (47924), Doorway (47925), null (47926), Doorway (47940), Doorway (47941), null (47942), Doorway (47943), Doorway (47944), null (47945), Doorway (47955), Doorway (47956), null (47957), Doorway (47958), Doorway (47959), null (47960), Doorway (47994), Doorway (47995), null (47996), Doorway (47997), Doorway (47998), null (47999), null (48131), null (48132), null (48133), null (48134), null (48135), null (48136), null (48137), null (48138), null (48139), null (48140), null (48141), null (48142), null (48143), null (48144), null (48145), null (48146), null (48147), null (48148), null (48149), null (48150), null (48151), null (48152), null (48153), null (48154), null (48155), null (48156), null (48157), null (48158), null (48159), null (48160), null (48161), null (48162), null (48163), null (48164), null (48165), null (48166) + +Base: 2703 +Linked animations: [12732, 12733] +Linked objects: Lever (47931), Lever (47932) + +Base: 2704 +Linked animations: [12711, 12712, 12713, 12714, 12715, 12716, 12753] +Linked objects: Empty channel (41715), Full channel (41716), Empty channel (41722), Empty channel (47910), Full channel (47911), Full channel (47912), Full channel (47914), Full channel (47915), Empty channel (47918), Empty channel (47919), Waterfall (48027), Rubble (54130), Rubble (54131), Rubble (54132), Rubble (54133), null (54146), null (54147), null (54148), null (54149), null (54154), null (54155), null (54156), null (54157) + +Base: 2705 +Linked animations: [12734, 12736, 12744] +Linked objects: Drips (47946), Waterfall (47947), null (47948), Full reservoir (48030), null (48031), null (48032), Full reservoir (48033) + +Base: 2706 +Linked animations: [12751, 12752] +Linked objects: Strange device (47934), Broken device (47935), Strange device (47949), Strange device (47950), Strange device (47971), Broken device (47972), Strange device (48000), Broken device (48001) + +Base: 2707 +Linked animations: [12719, 12726, 12727, 12728] +Linked graphics: 2280, 2281 +Linked objects: Soul energy (47979) + +Base: 2708 +Linked animations: [2287, 2723, 9500, 9501, 9505, 9514] +Linked NPCs: Corruption beast (9455) + +Base: 2709 +Linked animations: [9515, 12692, 12693, 12694, 12695, 12696, 12697, 12698, 12699, 12700, 12701, 12702, 12703, 12704, 12729, 12730, 12750] +Linked NPCs: Nomad (8528), Nomad (8529), Nomad (8530), Nomad (8531), Nomad (8532) +Linked objects: Nomad (48072), Nomad's throne (48073), null (48074), null (48075), null (48076), null (48077), null (48078) + +Base: 2710 +Linked animations: [12720, 12721, 12722] +Linked NPCs: Flame vortex (9441) + +Base: 2711 +Linked animations: [12717, 12718] +Linked graphics: 1657, 1658 + +Base: 2712 +Linked animations: [12763] +Linked graphics: 2284, 2285, 2286, 2287, 2288, 2289, 2290, 2291, 2292, 2293, 2294, 2295, 2296, 2297, 2298 + +Base: 2713 +Linked animations: [5390, 5391, 5406, 5427] +Linked graphics: 2303, 2304, 2305, 2306 + +Base: 2714 +Linked animations: [12775, 12779, 12783] +Linked graphics: 2308, 2346, 2347, 2348, 2349, 2350, 2351, 2352, 2353, 2354, 2355, 2356, 2357, 2358, 2359 +Linked objects: Animation table (547), Animation table (20220), Animation table (20221) + +Base: 2715 +Linked animations: [12778] +Linked graphics: 2307 + +Base: 2716 +Linked animations: [12788, 12789, 12790, 12791, 12792, 12793, 12794, 12795, 12796] +Linked NPCs: Mound (9462), Ice strykewyrm (9463), Mound (9464), Desert strykewyrm (9465), Mound (9466), Jungle strykewyrm (9467) + +Base: 2717 +Linked animations: [12805] +Linked graphics: 2319, 2320 + +Base: 2718 +Linked animations: [12799, 12800] +Linked graphics: 2312, 2313 + +Base: 2719 +Linked animations: [12797, 12798, 12802, 12803] +Linked graphics: 2310, 2311, 2315, 2316, 2317, 2318 + +Base: 2720 +Linked animations: [12801] +Linked graphics: 2314 + +Base: 2721 +Linked animations: [12808, 12809] +Linked graphics: 2322, 2323 + +Base: 2722 +Linked animations: [12811, 12812, 12813] +Linked graphics: 2324, 2325, 2326 + +Base: 2723 +Linked animations: [12807, 12815] +Linked NPCs: Raw shards (9494), null (9495), null (9496), null (9497), null (9498), null (9499), null (9500), null (9501), null (9502), null (9503), null (9504), null (9505), null (9506), null (9507), null (9508), null (9509), null (9510), null (9511), null (9512), null (9513), null (9514), null (9515), null (9516), null (9517), null (9518), null (9519), null (9520), null (9521), null (9522), null (9523), null (9524), null (9525), null (9526), null (9527), null (9528), null (9529), null (9530), null (9531), null (9532), null (9533), null (9534), null (9535), null (9536), null (9537), null (9538), null (9539), null (9540), null (9541), null (9542), null (9543), null (9544), null (9545), null (9546), null (9547), null (9548), null (9549), null (9550), null (9551), null (9552), null (9553), null (9554), null (9555), null (9556), null (9557), null (9558) +Linked graphics: 2321 + +Base: 2724 +Linked animations: [13385, 13386, 13387, 13388, 13389, 13390, 13391, 13392, 13393, 13394] +Linked objects: null (48382), null (48383), null (48386), null (48401), null (48402), null (48403), Tent (48404), null (48405), null (48406), null (48595), null (48596), null (48597), null (48599) + +Base: 2725 +Linked animations: [13178] +Linked objects: Fremennik ship (48579) + +Base: 2726 +Linked animations: [6607] + +Base: 2727 +Linked animations: [12836, 12838] +Linked objects: Statue of Dahmaroc (48660) + +Base: 2728 +Linked animations: [12898, 12899] +Linked objects: Jade demon statuette (48665), Topaz demon statuette (48667), Sapphire demon statuette (48669), Emerald demon statuette (48671), Ruby demon statuette (48673), Diamond demon statuette (48675), Diamond demon statuette (48676) + +Base: 2729 +Linked animations: [12888] + +Base: 2730 +Linked animations: [12901, 12902, 12903] +Linked graphics: 2344, 2345 +Linked objects: Tomb (48686) + +Base: 2731 +Linked animations: [12897] +Linked objects: Stairs (48687) + +Base: 2732 +Linked animations: [12886, 12887] +Linked objects: Tomb door (48786), Tomb door (48787), Tomb door (48795), Tomb door (48796) + +Base: 2733 +Linked animations: [12839, 12841, 12844, 12847, 12861, 12862, 12863, 12864, 12865, 12866, 12867, 12868, 12869, 12870, 12871, 12872, 12873, 12874, 12883, 12884, 12885, 12889, 12890, 12891, 12892, 12893, 12904] +Linked NPCs: Crawling corpse torso (7916), Crawling corpse torso (7917), Crawling corpse torso (7918), Crawling corpse torso (7919), Skeleton (7921), Corpse archer (7923), Corpse archer (7924), Corpse archer (7925), Corpse archer (7926), Corpse archer (7927), Corpse archer (7928), Corpse archer (9607), Corpse archer (9608), Corpse archer (9609), Corpse archer (9610), Corpse mage (9612), Corpse mage (9613), Corpse mage (9614), Corpse mage (9615), Corpse mage (9616), Corpse mage (9617), Corpse mage (9618), Corpse mage (9619), Corpse mage (9620), Corpse mage (9621), Dragith Nurn (9622), Dragith Nurn (9641) + +Base: 2734 +Linked animations: [12845, 12846] +Linked graphics: 2341, 2342 + +Base: 2735 +Linked animations: [12848] +Linked graphics: 2343 + +Base: 2736 +Linked animations: [12840] +Linked graphics: 392 + +Base: 2737 +Linked animations: [12842, 12843] +Linked graphics: 2339, 2340 + +Base: 2738 +Linked animations: [12922] +Linked objects: Row boat (49053) + +Base: 2739 +Linked animations: [12918] + +Base: 2740 +Linked animations: [439] +Linked graphics: 2360, 2361, 2362, 2363, 2364, 2365, 2366 + +Base: 2741 +Linked animations: [12925, 12926, 12927, 12928, 12929, 12930, 12931, 12932, 12933, 12934, 12935, 12936, 12937, 12938, 12939, 12940, 12941, 12942, 12943, 12944, 12945, 12946, 12947, 12948, 12949, 12950, 12951, 12952, 12953, 12954, 12955, 12956, 12957, 12958, 12959, 12960, 12961, 12962, 12963, 12964, 12965, 12966, 12967, 12968, 12969, 12970, 12971, 12972, 12973, 12974, 12975, 12976, 12977, 12978, 12979] + +Base: 2742 +Linked animations: [12980] +Linked objects: null (49260), null (49261), null (49262), null (49263), null (49264), null (53248), null (53249), null (53250), null (53251), null (53252), null (53253), null (54427), null (54428), null (54429) + +Base: 2743 +Linked animations: [13408, 13409] +Linked objects: null (48407), null (48408) + +Base: 2744 +Linked animations: [13527] +Linked objects: null (52277), null (52278), null (52279), null (52280), null (52281) + +Base: 2745 +Linked animations: [13765] +Linked objects: Guardian door (50345), Guardian door (50346), Guardian door (50347), Guardian door (50348), Guardian door (53949) + +Base: 2746 +Linked animations: [13542, 13589, 13590, 13593, 13595, 13596] +Linked objects: Strange wall (49695), Ladder (49696), Strange wall (49697), Ladder (49698), Strange wall (49699), Ladder (49700), Strange wall (53747), Ladder (53748) + +Base: 2747 +Linked animations: [13411] +Linked objects: null (48392) + +Base: 2748 +Linked animations: [13661, 13663, 13664] +Linked objects: Runecrafting altar (50035), Runecrafting altar (50036), Runecrafting altar (50037), Runecrafting altar (53844) + +Base: 2750 +Linked animations: [13327, 13328, 13329, 13330, 13331, 13332] +Linked graphics: 2518, 2519, 2520, 2521, 2522, 2523 + +Base: 2751 +Linked animations: [13757] +Linked objects: Rocky debris (49615), Rocky debris (49616), Rocky debris (49617), Rocky debris (49618) + +Base: 2752 +Linked animations: [13529, 13530, 13531, 13532, 13533, 13644, 13645] +Linked objects: Inactive lodestone (49270), Inactive lodestone (49271), Activated lodestone (49319), Blue crystal (49468), Blue crystal (49469), Blue crystal (49470), Red crystal (49477), Red crystal (49478), Red crystal (49479), Green crystal (49486), Green crystal (49487), Green crystal (49488), Yellow crystal (49495), Yellow crystal (49496), Yellow crystal (49497), Large crystal (49510), Large crystal (49511), Large crystal (49512), Large crystal (49513), Large crystal (49514), Large crystal (49515), Active lodestone (49573), Activated lodestone (50785), Activated lodestone (51053), Activated lodestone (51099), Activated lodestone (51601), Activated lodestone (51647), Blue crystal (54262), Red crystal (54265), Green crystal (54268), Yellow crystal (54271), Large crystal (54276), Large crystal (54277) + +Base: 2753 +Linked animations: [13312, 13313, 13314, 13315, 13319, 13519] +Linked objects: Hole (49549), Hole (49550), Hole (49551), Hole (49552), Hole (49553), Hole (49554), Hole (54294), Hole (54295) + +Base: 2754 +Linked animations: [13515, 13516, 13517, 13534, 13535, 13536] +Linked NPCs: Barrel (11072), Barrel (11073), Barrel (11074), Barrel (11075) + +Base: 2755 +Linked animations: [13781, 13782, 13783, 13784] +Linked objects: Tile (49634), Tile (49635), Tile (49636), Tile (49637), Green tile (49638), Green tile (49639), Green tile (49640), Yellow tile (49641), Yellow tile (49642), Yellow tile (49643), Green tile (54065), Yellow tile (54066) + +Base: 2756 +Linked animations: [13069, 13070, 13071, 13072] +Linked NPCs: Monolith (10978), Monolith (10979), Monolith (10980), Monolith (12176) + +Base: 2757 +Linked animations: [13641, 13642, 13643] + +Base: 2758 +Linked animations: [13722] + +Base: 2759 +Linked animations: [13723] +Linked objects: Fountain (49355), Fountain (49357), Fountain (49359), Fountain (54411) + +Base: 2760 +Linked animations: [13224] +Linked objects: Furnace (50191), Furnace (50192), Furnace (50193), Furnace (54884) + +Base: 2761 +Linked animations: [13414] +Linked objects: Skillcape stand (50547) + +Base: 2762 +Linked animations: [13730] + +Base: 2763 +Linked animations: [13545, 13546, 13588] +Linked graphics: 2411, 2412 +Linked objects: Locked door (50287), Locked door (50288), Locked door (50289), Locked door (53956) + +Base: 2764 +Linked animations: [13571, 13572] + +Base: 2765 +Linked animations: [13561, 13562, 13563] +Linked objects: Flammable debris (50314), Flammable debris (50315), Flammable debris (50316), Flammable debris (53965) + +Base: 2766 +Linked animations: [13578, 13579, 13580, 13581] +Linked objects: Liquid lock door (50335), Liquid lock door (50336), Liquid lock door (50337), Door (50338), Door (50339), Door (50340), Liquid lock door (53972), Door (53973) + +Base: 2767 +Linked animations: [13549, 13550, 13551, 13586, 13594] +Linked objects: Orange triangle door (50208), Orange diamond door (50209), Orange rectangle door (50210), Orange pentagon door (50211), Orange corner door (50212), Orange crescent door (50213), Orange wedge door (50214), Orange shield door (50215), Silver triangle door (50216), Silver diamond door (50217), Silver rectangle door (50218), Silver pentagon door (50219), Silver corner door (50220), Silver crescent door (50221), Silver wedge door (50222), Silver shield door (50223), Yellow triangle door (50224), Yellow diamond door (50225), Yellow rectangle door (50226), Yellow pentagon door (50227), Yellow corner door (50228), Yellow crescent door (50229), Yellow wedge door (50230), Yellow shield door (50231), Green triangle door (50232), Green diamond door (50233), Green rectangle door (50234), Green pentagon door (50235), Green corner door (50236), Green crescent door (50237), Green wedge door (50238), Green shield door (50239), Blue triangle door (50240), Blue diamond door (50241), Blue rectangle door (50242), Blue pentagon door (50243), Blue corner door (50244), Blue crescent door (50245), Blue wedge door (50246), Blue shield door (50247), Purple triangle door (50248), Purple diamond door (50249), Purple rectangle door (50250), Purple pentagon door (50251), Purple corner door (50252), Purple crescent door (50253), Purple wedge door (50254), Purple shield door (50255), Crimson triangle door (50256), Crimson diamond door (50257), Crimson rectangle door (50258), Crimson pentagon door (50259), Crimson corner door (50260), Crimson crescent door (50261), Crimson wedge door (50262), Crimson shield door (50263), Gold triangle door (50264), Gold diamond door (50265), Gold rectangle door (50266), Gold pentagon door (50267), Gold corner door (50268), Gold crescent door (50269), Gold wedge door (50270), Gold shield door (50271), Magical barrier (50329), Magical barrier (50330), Magical barrier (50331), Magical barrier (53970) + +Base: 2768 +Linked animations: [13558, 13559] +Linked objects: Pile of rocks (50305), Pile of rocks (50306), Pile of rocks (50307), Pile of rocks (53962) + +Base: 2769 +Linked animations: [13555, 13556, 13557] +Linked objects: Dark spirit (50332), Dark spirit (50333), Dark spirit (50334), Dark spirit (53971) + +Base: 2770 +Linked animations: [13552, 13553, 13554] +Linked objects: Runed door (50278), Runed door (50279), Runed door (50280), Runed door (53953) + +Base: 2771 +Linked animations: [13566, 13567, 13587] +Linked objects: Barred door (50272), Barred door (50273), Barred door (50274), Door (50275), Door (50276), Door (50277), Barred door (53951), Door (53952) + +Base: 2772 +Linked animations: [13374, 13574, 13575, 13576, 13577, 13591, 13592] +Linked objects: Suspicious grooves (49442), Padlocked door (50293), Padlocked door (50294), Padlocked door (50295), Padlocked door (53958) + +Base: 2773 +Linked animations: [13582, 13583] +Linked objects: Wooden barricade (50317), Wooden barricade (50318), Wooden barricade (50319), Wooden barricade (53966) + +Base: 2774 +Linked animations: [13712, 13713, 13714, 13715, 13716, 13717, 13718, 13719, 13720, 13721] +Linked NPCs: Gluttonous behemoth (9948), Gluttonous behemoth (9949), Gluttonous behemoth (9950), Gluttonous behemoth (9951), Gluttonous behemoth (9952), Gluttonous behemoth (9953), Gluttonous behemoth (9954), Gluttonous behemoth (9955), Gluttonous behemoth (9956), Gluttonous behemoth (9957), Gluttonous behemoth (9958), Gluttonous behemoth (9959), Gluttonous behemoth (9960), Gluttonous behemoth (9961), Gluttonous behemoth (9962), Gluttonous behemoth (9963), Gluttonous behemoth (9964) + +Base: 2775 +Linked animations: [12998, 12999, 13000, 13001, 13002, 13003, 13004, 13005, 13006, 13007] +Linked NPCs: Bulwark beast (10073), Bulwark beast (10074), Bulwark beast (10075), Bulwark beast (10076), Bulwark beast (10077), Bulwark beast (10078), Bulwark beast (10079), Bulwark beast (10080), Bulwark beast (10081), Bulwark beast (10082), Bulwark beast (10083), Bulwark beast (10084), Bulwark beast (10085), Bulwark beast (10086), Bulwark beast (10087), Bulwark beast (10088), Bulwark beast (10089), Bulwark beast (10090), Bulwark beast (10091), Bulwark beast (10092), Bulwark beast (10093), Bulwark beast (10094), Bulwark beast (10095), Bulwark beast (10096), Bulwark beast (10097), Bulwark beast (10098), Bulwark beast (10099), Bulwark beast (10100), Bulwark beast (10101), Bulwark beast (10102), Bulwark beast (10103), Bulwark beast (10104), Bulwark beast (10105), Bulwark beast (10106), Bulwark beast (10107), Bulwark beast (10108), Bulwark beast (10109), Bulwark beast (10110), Behemoth (11244) + +Base: 2776 +Linked animations: [13073] +Linked graphics: 2383 + +Base: 2777 +Linked animations: [13487, 13488, 13489, 13490, 13491, 13492] +Linked NPCs: Guardian sphere (11009) +Linked graphics: 2435, 2436, 2437 + +Base: 2778 +Linked animations: [13445, 13446, 13447, 13448, 13449, 13450, 13451, 13459, 13460, 13461, 13507, 13508, 13509, 13510, 13511] +Linked NPCs: Stomp (9782), Stomp (9783), Stomp (9784), Stomp (9785), Stomp (9786), Stomp (9787), Stomp (9788), Stomp (9789), Stomp (9790), Stomp (9791), Stomp (9792), Stomp (9793), Stomp (9794), Stomp (9795), Stomp (9796), Stomp (9797), Stomp (9798), Stomp (9799), Stomp (9800), Stomp (9801), Stomp (9802), Stomp (9803), Stomp (9804), Stomp (9805), Stomp (9806), Stomp (9807), Stomp (9808), Stomp (9809), Stomp (9810), Stomp (9811), Stomp (9812), Stomp (9813), Stomp (9814), Stomp (9815), Stomp (9816), Stomp (9817), Stomp (9818), Stomp (9819), Stomp (9820), Stomp (9821), Stomp (9822), Stomp (9823), Stomp (9824), Stomp (9825), Stomp (9826), Stomp (9827), Stomp (9828), Stomp (9829), Stomp (9830), Stomp (9831), Stomp (9832), Stomp (9833), Stomp (9834), Stomp (9835), Stomp (9836), Stomp (9837), Stomp (9838), Stomp (9839), Stomp (9840), Stomp (9841) + +Base: 2779 +Linked animations: [13255, 13256, 13257, 13258, 13259, 13260, 13261, 13262, 13264, 13349] +Linked NPCs: Protomastyx (11086), Submastyx (11087), Paramastyx (11088), Archaemastyx (11089), Dromomastyx (11090), Spinomastyx (11091), Gallimastyx (11092), Stegomastyx (11093), Megamastyx (11094), Tyrannomastyx (11095), Protomastyx corpse (11096), Submastyx corpse (11097), Paramastyx corpse (11098), Archaemastyx corpse (11099), Dromomastyx corpse (11100), Spinomastyx corpse (11101), Gallimastyx corpse (11102), Stegomastyx corpse (11103), Megamastyx corpse (11104), Tyrannomastyx corpse (11105), Bovimastyx (11230) + +Base: 2780 +Linked animations: [13158, 13159, 13160, 13161, 13162, 13163, 13164] +Linked NPCs: Iron dragon (10776), Iron dragon (10777), Iron dragon (10778), Iron dragon (10779), Iron dragon (10780), Iron dragon (10781) + +Base: 2781 +Linked animations: [13151, 13152, 13153, 13154, 13155, 13156, 13157] +Linked NPCs: Frost dragon (51), Black dragon (10219), Black dragon (10220), Black dragon (10221), Black dragon (10222), Black dragon (10223), Black dragon (10224), Green dragon (10604), Green dragon (10605), Green dragon (10606), Green dragon (10607), Green dragon (10608), Green dragon (10609), Frost dragon (10770), Frost dragon (10771), Frost dragon (10772), Frost dragon (10773), Frost dragon (10774), Frost dragon (10775), Red dragon (10815), Red dragon (10816), Red dragon (10817), Red dragon (10818), Red dragon (10819), Red dragon (10820), Frost dragon (11633), Frost dragon (11634), Frost dragon (11635), Frost dragon (11636) + +Base: 2782 +Linked animations: [13731, 13732, 13733, 13734, 13735, 13738, 13739] +Linked NPCs: Edimmu (10704) + +Base: 2783 +Linked animations: [13057, 13058, 13059, 13060, 13061, 13062, 13063, 13064, 13167, 13168, 13169, 13170, 13171, 13172, 13175, 13176, 13415, 13416, 13639, 13696, 13697, 13698, 13699, 13700, 13701, 13702, 13703, 13704, 13705, 13706, 13707, 14620] +Linked NPCs: Rammernaut (9767), Rammernaut (9768), Rammernaut (9769), Rammernaut (9770), Rammernaut (9771), Rammernaut (9772), Rammernaut (9773), Rammernaut (9774), Rammernaut (9775), Rammernaut (9776), Rammernaut (9777), Rammernaut (9778), Rammernaut (9779), Rammernaut (9780), Unholy cursebearer (10111), Unholy cursebearer (10112), Unholy cursebearer (10113), Unholy cursebearer (10114), Unholy cursebearer (10115), Unholy cursebearer (10116), Unholy cursebearer (10117), Unholy cursebearer (10118), Unholy cursebearer (10119), Unholy cursebearer (10120), Unholy cursebearer (10121), Unholy cursebearer (10122), Unholy cursebearer (10123), Unholy cursebearer (10124), Unholy cursebearer (10125), Unholy cursebearer (10126), Unholy cursebearer (10127), Brute (10797), Brute (10798), Brute (10799), Brute (10800), Brute (10801), Brute (10802), Brute (10803), Brute (10804), Brute (10805), Brute (10806), Brute (10807), Brute (10808), Brute (10809), Brute (10810), Brute (10811), Brute (10812), Brute (10813), Brute (10814), Guard (10915), Guard (10916), Guard (10917), Guard (10918), Guard (10919), Guard (10920), Guard (10921), Guard (10922), Guard (10923), Guard (10924), Guard (10925), Guard (10926), Guard (10927), Guard (10928), Guard (10929), Guard (10930), Guard (10931), Guard (10932), Magic construct (11006), Guardian (11231), Brute (11441), Brute (11442), Brute (11443), Brute (11444), Brute (11445), Brute (11446), Brute (11447), Brute (11448), Brute (11449) +Linked graphics: 2780 + +Base: 2784 +Linked animations: [13198, 13200, 13202, 13203, 13206, 13207, 13208, 13209, 13213, 13214, 13289, 13290, 13613, 13614, 13615, 13617, 13618, 13619, 13620, 13665, 13666, 13667, 13668, 13669, 13670, 13671, 13672, 13673, 13674, 13675, 13676, 13677, 13678, 13679, 13680, 13681, 13682, 13683, 13684, 13685] +Linked NPCs: Divine skinweaver (10058), Enigmatic hoardstalker (11011), Cub bloodrager (11106), Cub bloodrager (11107), Little bloodrager (11108), Little bloodrager (11109), Na￯ve bloodrager (11110), Na￯ve bloodrager (11111), Keen bloodrager (11112), Keen bloodrager (11113), Brave bloodrager (11114), Brave bloodrager (11115), Brah bloodrager (11116), Brah bloodrager (11117), Naabe bloodrager (11118), Naabe bloodrager (11119), Wise bloodrager (11120), Wise bloodrager (11121), Adept bloodrager (11122), Adept bloodrager (11123), Sachem bloodrager (11124), Sachem bloodrager (11125), Cub stormbringer (11126), Cub stormbringer (11127), Little stormbringer (11128), Little stormbringer (11129), Na￯ve stormbringer (11130), Na￯ve stormbringer (11131), Keen stormbringer (11132), Keen stormbringer (11133), Brave stormbringer (11134), Brave stormbringer (11135), Brah stormbringer (11136), Brah stormbringer (11137), Naabe stormbringer (11138), Naabe stormbringer (11139), Wise stormbringer (11140), Wise stormbringer (11141), Adept stormbringer (11142), Adept stormbringer (11143), Sachem stormbringer (11144), Sachem stormbringer (11145), Cub hoardstalker (11146), Cub hoardstalker (11147), Little hoardstalker (11148), Little hoardstalker (11149), Na￯ve hoardstalker (11150), Na￯ve hoardstalker (11151), Keen hoardstalker (11152), Keen hoardstalker (11153), Brave hoardstalker (11154), Brave hoardstalker (11155), Brah hoardstalker (11156), Brah hoardstalker (11157), Naabe hoardstalker (11158), Naabe hoardstalker (11159), Wise hoardstalker (11160), Wise hoardstalker (11161), Adept hoardstalker (11162), Adept hoardstalker (11163), Sachem hoardstalker (11164), Sachem hoardstalker (11165), Cub skinweaver (11166), Cub skinweaver (11167), Little skinweaver (11168), Little skinweaver (11169), Na￯ve skinweaver (11170), Na￯ve skinweaver (11171), Keen skinweaver (11172), Keen skinweaver (11173), Brave skinweaver (11174), Brave skinweaver (11175), Brah skinweaver (11176), Brah skinweaver (11177), Naabe skinweaver (11178), Naabe skinweaver (11179), Wise skinweaver (11180), Wise skinweaver (11181), Adept skinweaver (11182), Adept skinweaver (11183), Sachem skinweaver (11184), Sachem skinweaver (11185), Cub worldbearer (11186), Cub worldbearer (11187), Little worldbearer (11188), Little worldbearer (11189), Na￯ve worldbearer (11190), Na￯ve worldbearer (11191), Keen worldbearer (11192), Keen worldbearer (11193), Brave worldbearer (11194), Brave worldbearer (11195), Brah worldbearer (11196), Brah worldbearer (11197), Naabe worldbearer (11198), Naabe worldbearer (11199), Wise worldbearer (11200), Wise worldbearer (11201), Adept worldbearer (11202), Adept worldbearer (11203), Sachem worldbearer (11204), Sachem worldbearer (11205), Cub deathslinger (11206), Cub deathslinger (11207), Little deathslinger (11208), Little deathslinger (11209), Na￯ve deathslinger (11210), Na￯ve deathslinger (11211), Keen deathslinger (11212), Keen deathslinger (11213), Brave deathslinger (11214), Brave deathslinger (11215), Brah deathslinger (11216), Brah deathslinger (11217), Naabe deathslinger (11218), Naabe deathslinger (11219), Wise deathslinger (11220), Wise deathslinger (11221), Adept deathslinger (11222), Adept deathslinger (11223), Sachem deathslinger (11224), Sachem deathslinger (11225) +Linked objects: Ramokee exile (50326), Ramokee exile (50327), Ramokee exile (50328), Ramokee exile (53969) + +Base: 2785 +Linked animations: [13302, 13303, 13304, 13305, 13306, 13307, 13308, 13309, 13310, 13316, 13317, 13318, 13518, 13797, 14517, 14518] +Linked NPCs: Ferret (11007), Ferret (11010), Ferret (12157), Ferret (12158), Ferret (12159), Ferret (12160), Ferret (12161), Ferret (12165), Ferret (12166), Ferret (12167), Ferret (12168), Ferret (12169), Ferret (12170), Ferret (12171), Ferret (12172), Ferret (12173), Ferret (12174) + +Base: 2786 +Linked animations: [13333, 13334, 13335, 13336, 13337, 13338, 13352] +Linked NPCs: Luminescent icefiend (9912), Luminescent icefiend (9913), Luminescent icefiend (9914), Luminescent icefiend (9915), Luminescent icefiend (9916), Luminescent icefiend (9917), Luminescent icefiend (9918), Luminescent icefiend (9919), Luminescent icefiend (9920), Luminescent icefiend (9921), Luminescent icefiend (9922), Luminescent icefiend (9923), Luminescent icefiend (9924), Luminescent icefiend (9925), Luminescent icefiend (9926), Luminescent icefiend (9927), Luminescent icefiend (9928) + +Base: 2787 +Linked animations: [13465, 13466, 13467, 13468, 13469, 13470, 13471, 13472, 13499, 13500] +Linked NPCs: Lexicus Runewright (9842), Lexicus Runewright (9843), Lexicus Runewright (9844), Lexicus Runewright (9845), Lexicus Runewright (9846), Lexicus Runewright (9847), Lexicus Runewright (9848), Lexicus Runewright (9849), Lexicus Runewright (9850), Lexicus Runewright (9851), Lexicus Runewright (9852), Lexicus Runewright (9853), Lexicus Runewright (9854), Lexicus Runewright (9855) + +Base: 2788 +Linked animations: [13476, 13477, 13478, 13479, 13480, 13481, 13482, 13483, 13484, 13495, 13501, 13502, 13503, 13506, 14435, 14436, 14437, 14439, 14440, 14441] +Linked NPCs: Tome of Strength (9856), Tome of Ranging (9857), Tome of Magic (9858), Tome of Strength (9859), Tome of Ranging (9860), Tome of Magic (9861), Tome of Strength (9862), Tome of Ranging (9863), Tome of Magic (9864), Tome of Strength (9865), Tome of Ranging (9866), Tome of Magic (9867), Tome of Strength (9868), Tome of Ranging (9869), Tome of Magic (9870), Tome of Strength (9871), Tome of Ranging (9872), Tome of Magic (9873), Tome of Strength (9874), Tome of Ranging (9875), Tome of Magic (9876), Tome of Strength (9877), Tome of Ranging (9878), Tome of Magic (9879), Tome of Strength (9880), Tome of Ranging (9881), Tome of Magic (9882), Tome of Strength (9883), Tome of Ranging (9884), Tome of Magic (9885), Tome of Strength (9886), Tome of Ranging (9887), Tome of Magic (9888), Tome of Strength (9889), Tome of Ranging (9890), Tome of Magic (9891), Tome of Strength (9892), Tome of Ranging (9893), Tome of Magic (9894), Tome of Strength (9895), Tome of Ranging (9896), Tome of Magic (9897) +Linked graphics: 139, 140, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 2421, 2422, 2423 + +Base: 2789 +Linked animations: [13291, 13292, 13293, 13294, 13295, 13296, 13297] +Linked NPCs: Seeker spawn (10933), Seeker spawn (10934), Seeker spawn (10935), Seeker spawn (10936), Seeker spawn (10937), Seeker spawn (10938), Seeker spawn (10939), Seeker spawn (10940) + +Base: 2790 +Linked animations: [13298, 13299, 13767, 13768, 13769, 13770, 13771, 13772, 13773, 13774, 13775, 13779] +Linked NPCs: Plane-freezer Lakhrahnaz (9929), Plane-freezer Lakhrahnaz (9930), Plane-freezer Lakhrahnaz (9931), Plane-freezer Lakhrahnaz (9932), Plane-freezer Lakhrahnaz (9933), Plane-freezer Lakhrahnaz (9934), Plane-freezer Lakhrahnaz (9935), Plane-freezer Lakhrahnaz (9936), Plane-freezer Lakhrahnaz (9937), Plane-freezer Lakhrahnaz (9938), Plane-freezer Lakhrahnaz (9939), Plane-freezer Lakhrahnaz (9940), Plane-freezer Lakhrahnaz (9941), Plane-freezer Lakhrahnaz (9942), Plane-freezer Lakhrahnaz (9943), Plane-freezer Lakhrahnaz (9944), Plane-freezer Lakhrahnaz (9945), Plane-freezer Lakhrahnaz (9946), Plane-freezer Lakhrahnaz (9947), Seeker (10701), Soulgazer (10705), Seeker sentinel (10941) + +Base: 2791 +Linked animations: [14468, 14469, 14470, 14471, 14472] +Linked NPCs: Flesh-Spoiler Haasghenahk (11895), Flesh-Spoiler Haasghenahk (11896), Flesh-Spoiler Haasghenahk (11897), Flesh-Spoiler Haasghenahk (11898), Flesh-Spoiler Haasghenahk (11899), Flesh-Spoiler Haasghenahk (11900), Flesh-Spoiler Haasghenahk (11901), Flesh-Spoiler Haasghenahk (11902), Flesh-Spoiler Haasghenahk (11903), Flesh-Spoiler Haasghenahk (11904), Flesh-Spoiler Haasghenahk (11905), Flesh-Spoiler Haasghenahk (11906), Flesh-Spoiler Haasghenahk (11907), Flesh-Spoiler Haasghenahk (11908), Flesh-Spoiler Haasghenahk (11909) + +Base: 2792 +Linked animations: [13320, 14463, 14464, 14465, 14466, 14467, 14483, 14484, 14485] +Linked NPCs: Flesh-Spoiler Haasghenahk (11925), Flesh-Spoiler Haasghenahk (11926), Flesh-Spoiler Haasghenahk (11927), Flesh-Spoiler Haasghenahk (11928), Flesh-Spoiler Haasghenahk (11929), Flesh-Spoiler Haasghenahk (11930), Flesh-Spoiler Haasghenahk (11931), Flesh-Spoiler Haasghenahk (11932), Flesh-Spoiler Haasghenahk (11933), Flesh-Spoiler Haasghenahk (11934), Flesh-Spoiler Haasghenahk (11935), Flesh-Spoiler Haasghenahk (11936), Flesh-Spoiler Haasghenahk (11937), Flesh-Spoiler Haasghenahk (11938), Flesh-Spoiler Haasghenahk (11939) + +Base: 2793 +Linked animations: [14474, 14475, 14476, 14477, 14478, 14479, 14480, 14481, 14482, 14487, 14618] +Linked NPCs: Flesh-Spoiler spawn (11910), Flesh-Spoiler spawn (11911), Flesh-Spoiler spawn (11912), Flesh-Spoiler spawn (11913), Flesh-Spoiler spawn (11914), Flesh-Spoiler spawn (11915), Flesh-Spoiler spawn (11916), Flesh-Spoiler spawn (11917), Flesh-Spoiler spawn (11918), Flesh-Spoiler spawn (11919), Flesh-Spoiler spawn (11920), Flesh-Spoiler spawn (11921), Flesh-Spoiler spawn (11922), Flesh-Spoiler spawn (11923), Flesh-Spoiler spawn (11924) +Linked graphics: 2765, 2779 + +Base: 2794 +Linked animations: [13015, 13016, 13017, 13018, 13019, 13025, 13029, 13030, 13033, 13528] +Linked NPCs: Shadow-Forger Ihlakhizan (10143), Shadow-Forger Ihlakhizan (10144), Shadow-Forger Ihlakhizan (10145), Shadow-Forger Ihlakhizan (10146), Shadow-Forger Ihlakhizan (10147), Shadow-Forger Ihlakhizan (10148), Shadow-Forger Ihlakhizan (10149), Shadow-Forger Ihlakhizan (10150), Shadow-Forger Ihlakhizan (10151), Shadow-Forger Ihlakhizan (10152), Shadow-Forger Ihlakhizan (10153), Shadow-Forger Ihlakhizan (10154), Shadow-Forger Ihlakhizan (10155), Shadow-Forger Ihlakhizan (10156) +Linked objects: null (49299), null (49300), Pillar (51110) + +Base: 2795 +Linked animations: [13418, 13419, 13420, 13421, 13422, 13423, 13424, 13425, 13426, 13427, 13428, 13429, 13430, 13431, 13432, 13433, 13434, 13496, 13764] +Linked NPCs: Night-gazer Khighorahk (9725), Night-gazer Khighorahk (9726), Night-gazer Khighorahk (9727), Night-gazer Khighorahk (9728), Night-gazer Khighorahk (9729), Night-gazer Khighorahk (9730), Night-gazer Khighorahk (9731), Night-gazer Khighorahk (9732), Night-gazer Khighorahk (9733), Night-gazer Khighorahk (9734), Night-gazer Khighorahk (9735), Night-gazer Khighorahk (9736), Night-gazer Khighorahk (9737), Night-gazer Khighorahk (9738), Night-gazer Khighorahk (9739), Night-gazer Khighorahk (9740), Night-gazer Khighorahk (9741), Night-gazer Khighorahk (9742), Night-gazer Khighorahk (9743), Night-gazer Khighorahk (9744), Night-gazer Khighorahk (9745), Night-gazer Khighorahk (9746), Night-gazer Khighorahk (9747), Night-gazer Khighorahk (9748), Night-gazer Khighorahk (9749), Night-gazer Khighorahk (9750), Night-gazer Khighorahk (9751), Night-gazer Khighorahk (9752) + +Base: 2796 +Linked animations: [12981, 13443, 13444, 13505] +Linked graphics: 2146, 2392, 2393, 2427 + +Base: 2797 +Linked animations: [13056] +Linked graphics: 2379, 2381 + +Base: 2798 +Linked animations: [13011, 13012, 13013] +Linked graphics: 2397, 2398, 2399 + +Base: 2799 +Linked animations: [13008, 13009, 13010] +Linked graphics: 2394, 2395, 2396 + +Base: 2800 +Linked animations: [13014, 13485, 13486, 13520, 13521, 13522, 13523, 13524, 13525, 13526, 13570, 13638] +Linked graphics: 2400, 2420, 2428, 2429, 2430, 2431, 2432, 2433, 2434, 2438, 2599 +Linked objects: Debris (49268) + +Base: 2801 +Linked animations: [13728, 13729] +Linked graphics: 2612, 2613 + +Base: 2802 +Linked animations: [13455, 13456, 13457, 13458, 13497, 13498, 14434] +Linked graphics: 2404, 2405, 2406, 2407, 2413, 2414, 2415, 2416, 2417, 2772, 2773, 2774, 2775 + +Base: 2803 +Linked animations: [13452, 13453, 13454] +Linked graphics: 2401, 2402, 2403 + +Base: 2804 +Linked animations: [13263, 13265, 13311] +Linked graphics: 2551, 2552, 2553, 2554, 2555, 2556, 2557, 2558, 2559, 2560, 2561, 2562, 2563, 2564, 2565, 2566, 2567, 2568, 2569, 2570 + +Base: 2805 +Linked animations: [13688, 13689] +Linked graphics: 2577, 2578 + +Base: 2806 +Linked animations: [13776, 13777, 13778] +Linked graphics: 2574, 2575, 2576 + +Base: 2807 +Linked animations: [13653, 13655] +Linked graphics: 2602, 2603 + +Base: 2808 +Linked animations: [13609, 13610, 14451] +Linked graphics: 132, 133, 2587, 2588 + +Base: 2809 +Linked animations: [13607, 13608] +Linked graphics: 2579, 2580 + +Base: 2810 +Linked animations: [13690, 13780] +Linked graphics: 2581, 2582, 2583, 2584, 2585, 2586 + +Base: 2811 +Linked animations: [13165] +Linked graphics: 2464 + +Base: 2812 +Linked animations: [13166] +Linked graphics: 2465 + +Base: 2813 +Linked animations: [13640] +Linked graphics: 2601 + +Base: 2814 +Linked animations: [13708, 13709] +Linked graphics: 2604, 2605 + +Base: 2815 +Linked animations: [13215, 13216, 13686, 13687] +Linked graphics: 2452, 2453, 2455, 2456, 2572, 2573 + +Base: 2816 +Linked animations: [13195, 13196, 13199, 13201, 14291] +Linked graphics: 93, 2443, 2445, 2446, 2454, 2457, 2458, 2459, 2460, 2461, 2462, 2463 + +Base: 2817 +Linked animations: [13210, 13211, 13212, 13621, 13622, 13623] +Linked graphics: 2449, 2450, 2451, 2591, 2592, 2593 + +Base: 2818 +Linked animations: [13197, 13204] +Linked graphics: 2444, 2447 + +Base: 2819 +Linked animations: [13205, 13616] +Linked graphics: 2448, 2590 + +Base: 2820 +Linked animations: [13279, 13280, 13281, 13284, 13348] +Linked NPCs: Frozen adventurer (10022), Frozen adventurer (10023) +Linked graphics: 2545, 2546, 2547, 2548, 2550 + +Base: 2821 +Linked animations: [13277, 13282] +Linked graphics: 2544, 2549 + +Base: 2822 +Linked animations: [13286, 13287] +Linked graphics: 2516, 2517 + +Base: 2823 +Linked animations: [13067, 13399, 13400] +Linked graphics: 2382, 2510, 2511 + +Base: 2824 +Linked animations: [12993, 12994, 12995] +Linked graphics: 2147, 2367, 2368 + +Base: 2825 +Linked animations: [12996] +Linked graphics: 2369 + +Base: 2826 +Linked animations: [13341, 13346] +Linked graphics: 2526, 2531 + +Base: 2827 +Linked animations: [13339, 13340, 13345, 13347, 13726, 13727] +Linked graphics: 2524, 2525, 2530, 2543, 2610, 2611 + +Base: 2828 +Linked animations: [13343, 13344] +Linked graphics: 2528, 2529 + +Base: 2829 +Linked animations: [13342] +Linked graphics: 2527 + +Base: 2830 +Linked animations: [13021, 13022, 13023, 13024] +Linked graphics: 2371, 2372, 2373, 2374 + +Base: 2831 +Linked animations: [13020] +Linked graphics: 2370 + +Base: 2832 +Linked animations: [13031] +Linked graphics: 2600 + +Base: 2833 +Linked animations: [13027, 13028] +Linked graphics: 2376, 2377 + +Base: 2834 +Linked animations: [13026] +Linked graphics: 2375 + +Base: 2835 +Linked animations: [13504] +Linked graphics: 2425 + +Base: 2836 +Linked animations: [13473, 13474, 13475] +Linked graphics: 2408, 2409, 2410, 2424, 2426 + +Base: 2837 +Linked animations: [13266, 13267, 13268, 14290] +Linked graphics: 2538, 2541 + +Base: 2838 +Linked animations: [13269, 13272, 13273, 13274, 13275, 14619] +Linked graphics: 2532, 2533, 2534, 2535, 2536, 2537, 2539, 2540, 2542, 2687, 2781 + +Base: 2839 +Linked animations: [13435, 13436] +Linked graphics: 2384, 2385, 2418, 2419 + +Base: 2840 +Linked animations: [13441, 13442, 14486] +Linked graphics: 2390, 2391, 2764 + +Base: 2841 +Linked animations: [13438, 13439, 13440] +Linked graphics: 2387, 2388, 2389 + +Base: 2842 +Linked animations: [13174] +Linked graphics: 2440 + +Base: 2843 +Linked animations: [13725] +Linked graphics: 2607, 2608, 2609 + +Base: 2844 +Linked animations: [13724, 13741] +Linked graphics: 2606, 2616 + +Base: 2845 +Linked animations: [13629, 13630] +Linked graphics: 2594, 2595 + +Base: 2846 +Linked animations: [13632] +Linked graphics: 2596 + +Base: 2847 +Linked animations: [13637] +Linked graphics: 2598 + +Base: 2848 +Linked animations: [13625, 13626, 13627] +Linked objects: Stalagmite (52285), Stalagmite (52286), Stalagmite (52287) + +Base: 2849 +Linked animations: [13660] +Linked graphics: 2571 + +Base: 2850 +Linked animations: [13191, 14292, 14624] +Linked graphics: 2442, 2783 + +Base: 2851 +Linked animations: [13032] +Linked graphics: 2378 + +Base: 2852 +Linked animations: [13321, 13322, 13323, 13324] + +Base: 2853 +Linked animations: [14278, 14280] +Linked objects: Group gatestone portal (7528), Group gatestone portal (53124), Group gatestone portal (53125), Group gatestone portal (53126), null (53410), null (53414), null (53420) + +Base: 2854 +Linked animations: [13300] + +Base: 2855 +Linked animations: [13539, 14452] +Linked objects: null (54692), null (54709) + +Base: 2856 +Linked animations: [13766] + +Base: 2857 +Linked animations: [13815, 13816, 13817] +Linked objects: Ornate cuckoo clock (51661), Ornate cuckoo clock (51662) + +Base: 2858 +Linked animations: [13814] + +Base: 2859 +Linked animations: [13826, 13827] +Linked NPCs: Flagstaff of Festivities (11300) + +Base: 2860 +Linked animations: [13834, 13835] +Linked graphics: 2617, 2618, 2619, 2620, 2621, 2622 + +Base: 2861 +Linked animations: [13894] +Linked objects: Fountain (52568) + +Base: 2862 +Linked animations: [13881, 13882, 13883, 13884, 13885, 13886, 13887, 13888, 13891, 13892, 13893, 13908, 13909, 13913, 13914, 13915, 13916, 13917, 13918, 13919, 13923, 13924, 13925, 13926, 13930, 13931, 13932, 13933, 13934, 13935, 13946, 13950, 13951, 13952, 13953, 13961, 13962, 13984, 13985, 13993, 14000, 14001, 14002, 14013, 14019, 14020, 14021, 14022, 14023, 14024, 14025, 14026, 14027, 14028, 14029, 14030, 14031, 14032, 14033, 14034, 14035, 14036, 14037, 14038, 14039, 14040, 14041, 14084, 14085, 14097] +Linked NPCs: Ork (4456), Ork (4457), Ork (4458), Ork (4459), Ork (6271), Ork (6272), Ork (6273), Ork (6274), General Gromblod (11312), General Shredflesh (11314), General Shredflesh (11315), General Shredflesh (11316), General Bre'egth (11318), K'Chunk (11320), K'Chunk (11321), General Gromblod (11329), General Gromblod (11330), General Shredflesh (11331), General Bre'egth (11332), null (11333), Ivory Shredflesh (11334), Ivory Shredflesh (11335), null (11336), Ivory Gromblod (11337), Ivory Gromblod (11338), null (11339), Ivory Bre'egth (11340), Ivory Bre'egth (11341), General Gromblod (11342), General Gromblod (11343), General Shredflesh (11344), General Bre'egth (11345), Ork warrior (11348), Ork warrior (11349), Ork warrior (11350), Ork warrior (11351), Ivory Shredflesh (cursed) (11352), Ivory Gromblod (cursed) (11353), Ivory Bre'egth (cursed) (11354), Ork (11355), Ork (11356), Ork (11357), Ork (11358), Ork warrior (11359), Ork warrior (11360), Ork warrior (11361), Ork warrior (11362), Ivory Shredflesh (cursed) (11371), Ivory Gromblod (cursed) (11372), Ivory Bre'egth (cursed) (11373), Ork (11423), Ork (11424) + +Base: 2863 +Linked animations: [793, 3250, 3251, 3267, 4317, 4328, 11012, 13846, 13847, 13848, 13849, 13850, 13851, 13852, 13853, 13854, 13855, 13856, 13857, 13858, 13859, 13860, 13861, 13862, 13863, 13864, 13865, 13905, 13910, 13968, 13969, 13970, 13971, 13972, 13975, 13977, 13982, 13983, 13989, 13992, 14017, 14018, 14044, 14060, 14068, 14091] +Linked NPCs: Fairy (57), Banker (498), Fairy shopkeeper (534), Fairy shop assistant (535), Jukat (564), Lunderwin (565), Fairy (567), Fairy Queen (653), Banker (909), Fairy Very Wise (910), Chaeldar (1598), Co-ordinator (3302), Fairy Nuff (3303), Fairy Godfather (3304), Fat Rocco (3305), Slim Louie (3306), null (3314), null (3315), null (3316), null (3317), Fairy chef (3322), Treasure fairy (3954), null (4422), null (4423), null (4426), null (4427), null (4428), null (4429), null (4430), null (4431), null (4432), Fairy Godfather (4433), Fairy Nuff (4434), null (4435), null (4436), Fairy Queen (4437), Fairy Very Wise (4442), Fairy (4443), Fairy (4444), Fairy (4445), Fairy (4446), Fairy Fixit (4455), Fairy (5165), Fairy Aeryka (6072), Circus barker (8079), Circus barker (8080), Circus barker (8081), Agility assistant (8082), Magic assistant (8083), Ranged assistant (8084), Agility assistant (8726), Magic assistant (8727), Ranged assistant (8728), Fairy Godfather (11323), Fairy Godfather (11324), Fairy Godfather (11325), Fairy Godfather (11326), Fairy Godfather (11327), Fairy Godfather (11328), Fairy Godfather (11346), Fairy Godfather (11347), Slim Louie (11363), Fat Rocco (11364), Fairy tooth hunter (11366), Fairy stitcher (11367), Fairy stitcher (11368), Fairy doctor (11369), Fairy tooth farmer (11370), Tooth Fairy (11376), null (11379), Fairy Queen (11380), Fairy Queen (11381), Fairy builder (11382), null (11415), null (11416), null (11417), null (11418), null (11419), null (11420), null (11421), null (11422), Fairy (11427), Fairy (11428), Fairy (11429), Fairy (11430), Fairy (11431), Fairy (11432), Fairy (11433), Fairy (11434), Fairy Very Wise (11435), Fairy Queen (11436) +Linked graphics: 2658 + +Base: 2864 +Linked animations: [13895, 13896] +Linked NPCs: Gatekeeper (3307), null (3318), Gatekeeper (3321) + +Base: 2865 +Linked animations: [14092, 14093, 14094, 14095, 14096] +Linked NPCs: Otherworldly being (126), Irksol (566) + +Base: 2866 +Linked animations: [13866, 13867, 13868, 13869, 13870, 13871, 13872, 13873, 13874, 13875, 13876, 13877, 13878, 13879, 13880] +Linked NPCs: Tanglefoot (3313), Baby tanglefoot (3319), Baby tanglefoot (3320) + +Base: 2867 +Linked animations: [13927, 13928, 13929, 13997, 13998, 13999] +Linked graphics: 2626, 2627, 2628, 2643, 2644, 2645 + +Base: 2868 +Linked animations: [13978, 13979] +Linked graphics: 2655, 2656, 2657 + +Base: 2869 +Linked animations: [13920, 13921, 13922, 13994, 13995, 13996] +Linked graphics: 2623, 2624, 2625, 2640, 2641, 2642 + +Base: 2870 +Linked animations: [13960, 13966, 13967] + +Base: 2871 +Linked animations: [13958, 13959, 13963, 13964] + +Base: 2872 +Linked animations: [13965, 14083] + +Base: 2873 +Linked animations: [13939] + +Base: 2874 +Linked animations: [13940] + +Base: 2875 +Linked animations: [13954, 13955, 13956, 14012] +Linked objects: null (52646), null (52647), null (52648), Projector screen (52650), Projector screen (52651) + +Base: 2876 +Linked animations: [14048, 14049, 14050, 14051, 14053, 14054, 14058] +Linked objects: Rift (52733) + +Base: 2877 +Linked animations: [14059] +Linked objects: null (52732) + +Base: 2878 +Linked animations: [14088] +Linked objects: null (52737) + +Base: 2879 +Linked animations: [14052, 14055, 14056, 14057] +Linked objects: null (52745), null (52746), null (52747), null (52748), null (52749), null (52750), null (52751), null (52752), null (52753), null (52754) + +Base: 2880 +Linked animations: [13973] + +Base: 2881 +Linked animations: [13906, 13907] +Linked NPCs: Extractor fairies (11322) + +Base: 2882 +Linked animations: [13900, 13901, 13902, 13903, 13904, 14011, 14065] +Linked NPCs: Gnarly (11309), Gnarly (11310), Gnarly (11409), Gnarly (11410), Milk tooth creature (11411), Milk tooth creature (11412), Tooth creature (healthy) (11413), Tooth creature (decayed) (11414), Wisdom tooth creature (healthy) (11425), Wisdom tooth creature (decayed) (11426) + +Base: 2883 +Linked animations: [13990, 13991, 14008, 14009] +Linked graphics: 2637, 2638, 2639 + +Base: 2884 +Linked animations: [14062] +Linked graphics: 2659 + +Base: 2885 +Linked animations: [14064] +Linked graphics: 2660 + +Base: 2886 +Linked animations: [13911, 13912, 14003] +Linked graphics: 6, 7, 2646 + +Base: 2887 +Linked animations: [14069, 14070, 14071, 14072, 14073, 14086] +Linked graphics: 2669 +Linked objects: Medical table (52701), Wounded fairy (52702) + +Base: 2888 +Linked animations: [3252, 3253] +Linked graphics: 2670, 2671 + +Base: 2889 +Linked animations: [14045] +Linked graphics: 2652 + +Base: 2890 +Linked animations: [13947, 13949, 14014, 14015, 14016] +Linked graphics: 2629, 2630, 2647, 2648, 2649 + +Base: 2891 +Linked animations: [14042, 14043] +Linked graphics: 2650, 2651 + +Base: 2892 +Linked animations: [14046, 14047] +Linked graphics: 2653, 2654 + +Base: 2893 +Linked animations: [14087] +Linked graphics: 189 + +Base: 2894 +Linked animations: [14067] +Linked graphics: 2663, 2664, 2665, 2666, 2667, 2668 + +Base: 2895 +Linked animations: [13986, 13987, 13988] +Linked graphics: 2634, 2635, 2636 + +Base: 2896 +Linked animations: [14066] +Linked graphics: 2661, 2662 + +Base: 2897 +Linked animations: [13897] + +Base: 2898 +Linked animations: [13898] + +Base: 2899 +Linked animations: [14074, 14075, 14076, 14077, 14078] + +Base: 2900 +Linked animations: [13957, 13981] +Linked objects: Rift (52676) + +Base: 2901 +Linked animations: [14099, 14100] +Linked objects: Low mechanism slider (12027), Low mechanism slider (12028), Mid mechanism slider (12037), Mid mechanism slider (12040), Tall mechanism slider (12044), Tall mechanism slider (12065), Drive mechanism (12070), Mechanism (12073), Mechanism (12075), Mechanism (12077), Mechanism (12079), Mechanism (12081) + +Base: 2902 +Linked animations: [14121, 14122, 14129, 14130, 14131, 14132, 14133, 14134, 14135, 14136, 14137, 14138, 14139, 14140, 14141, 14142, 14143, 14144, 14145, 14146, 14147, 14148] +Linked objects: Counter (14158), Counter (16182), Counter (16183), Counter (16188), Counter (16198), Counter (16199), Counter (16204), Counter (16205), Counter (16206), Counter (16207), Counter (16208), Counter (16209), Counter (16279), Counter (16281), Counter (16285), Counter (16287), Counter (16295), Counter (16296), Counter (16308), Counter (16309), Counter (16310), Counter (16311), Counter (16313), Counter (16314), Counter (16323), Counter (16324), Counter (16325), Counter (16326), Counter (16327), Counter (16328), Counter (16329), Counter (16330), Counter (16332), Counter (16333), Counter (16334), Counter (16335), Counter (16336), Counter (16337), Counter (16338), Counter (16339), Counter (16340), Counter (16341) + +Base: 2903 +Linked animations: [1038] + +Base: 2904 +Linked animations: [14104, 14105, 14106, 14112, 14113, 14114, 14115, 14116, 14117, 14123, 14124] +Linked objects: Machine (12109), Machine (14124), Machine (14139), Powered machine (14157) + +Base: 2905 +Linked animations: [14101, 14102] + +Base: 2906 +Linked animations: [14107, 14108, 14109, 14118, 14119, 14120] +Linked graphics: 2672, 2673, 2674, 2680, 2681, 2682 + +Base: 2907 +Linked animations: [14110, 14111] +Linked graphics: 2675, 2676, 2677, 2678, 2679 + +Base: 2908 +Linked animations: [1656, 2129] +Linked objects: Catapult (4381), Catapult (4382), Catapult (4385), Catapult (4386) + +Base: 2909 +Linked animations: [4891, 4911] +Linked graphics: 303, 2690 + +Base: 2910 +Linked animations: [4910] +Linked graphics: 2688, 2689 + +Base: 2911 +Linked animations: [14178] +Linked graphics: 2692 + +Base: 2912 +Linked animations: [14187, 14188] +Linked objects: Memory energy (4477), Memory energy (4478), Memory energy (4479) + +Base: 2913 +Linked animations: [14202, 14203, 14204, 14205, 14206] +Linked objects: Toll booth (4453), Toll booth (36471), Toll booth (36472) + +Base: 2914 + +Base: 2915 +Linked animations: [14201] +Linked graphics: 2698 + +Base: 2916 +Linked animations: [14208] + +Base: 2917 +Linked animations: [14215, 14216, 14219] +Linked graphics: 2713, 2714, 2715, 2716, 2717, 2718, 2719, 2720, 2721, 2722, 2723, 2724, 2725, 2726, 2727 + +Base: 2918 +Linked animations: [2792, 14210, 14217, 14623] +Linked graphics: 2728, 2729, 2730, 2731, 2732, 2733, 2734, 2735, 2736, 2737, 2738, 2739, 2740, 2741, 2782 + +Base: 2919 +Linked animations: [14211] +Linked graphics: 2701, 2702 + +Base: 2920 +Linked animations: [10562, 14214] +Linked graphics: 2703, 2704, 2705, 2706, 2707, 2708, 2709, 2710, 2711, 2712 + +Base: 2921 +Linked animations: [14225, 14226, 14227, 14229] +Linked graphics: 2742 +Linked objects: Minor pit trap (39266), Minor pit trap (39267), Major pit trap (39268), Major pit trap (39269), Superior pit trap (39270), Superior pit trap (39271), null (39347), null (39348), null (41571), Fire (52767) + +Base: 2922 +Linked animations: [1641, 14230, 14231] +Linked NPCs: null (11596) + +Base: 2923 +Linked animations: [14241] +Linked objects: Mabel in a sack (52837) + +Base: 2924 +Linked animations: [14267, 14268, 14269, 14270, 14271] +Linked NPCs: Baby blue dragon (52), Baby red dragon (1589), Baby black dragon (3376), Baby blue dragon (4665), Baby blue dragon (4666), Baby red dragon (4667), Baby red dragon (4668) + +Base: 2925 +Linked animations: [14272, 14273] + +Base: 2926 +Linked animations: [3643, 4940, 4971, 14261, 14262, 14263, 14264, 14265] +Linked NPCs: Revenant dragon (6998), Revenant dragon (6999) + +Base: 2927 +Linked animations: [14274, 14275] + +Base: 2928 +Linked animations: [1643, 14246, 14247, 14248, 14249, 14250, 14251, 14252] +Linked NPCs: Bronze dragon (1590), Iron dragon (1591), Steel dragon (1592), Mithril dragon (5363), Mithril dragon (8424), Pit iron dragon (11567), Pit iron dragon (11594), Pit iron dragon (11595) +Linked objects: Pit iron dragon (39265), Pit iron dragon (41608) + +Base: 2929 +Linked animations: [14295, 14296, 14297] +Linked graphics: 95, 96, 97, 98, 99, 100, 121, 122, 123, 124, 125, 126 + +Base: 2930 +Linked animations: [14294] +Linked graphics: 94 + +Base: 2931 +Linked animations: [14303] +Linked graphics: 101, 117, 118, 119, 120 + +Base: 2932 +Linked animations: [14311, 14312, 14313, 14314, 14315, 14316, 14317] +Linked NPCs: Meerkats (11640) + +Base: 2933 +Linked animations: [14354, 14355] +Linked objects: Boxes (53695) + +Base: 2934 +Linked animations: [14343, 14345] +Linked objects: Machinery (53677), Machinery (53678) + +Base: 2935 +Linked animations: [14321, 14322, 14323, 14324, 14325, 14326, 14327, 14328, 14329, 14330, 14331, 14332, 14333, 14334, 14335, 14336] +Linked objects: Component box (53282), Furnace (53283), Furnace vent (53392), Furnace vent (53393), Furnace vent (53394), Flywheel (53395), Flywheel brake (53396), Flywheel brake (53397), Flywheel brake (53398), Sample hopper (53399), Sample reagent (solid) (53403), Sample reagent (powder) (53404), Sample reagent (liquid) (53405), Sample reagent (gaseous) (53406) + +Base: 2936 +Linked animations: [14344] +Linked objects: Pest cage (53680) + +Base: 2937 +Linked animations: [14348] +Linked objects: Cracked wall (53642), Cracked wall (53643), null (53645), null (53646) + +Base: 2938 +Linked animations: [14337] +Linked graphics: 131 + +Base: 2939 +Linked animations: [14342] +Linked graphics: 130 + +Base: 2940 +Linked animations: [14349] + +Base: 2941 +Linked animations: [14521, 14523, 14627] +Linked objects: Unfinished bridge (54009), Unfinished bridge (54010), Unfinished bridge (54011), Unfinished bridge (54012), null (54013), null (54014), null (54015), null (54016) + +Base: 2942 +Linked animations: [14559, 14562, 14563] + +Base: 2943 +Linked animations: [14561] + +Base: 2944 +Linked animations: [14516] +Linked objects: Red pressure plate (54365), Red pressure plate (54367), Red pressure plate (54369), Red pressure plate (54371), Blue pressure plate (54373), Blue pressure plate (54375), Blue pressure plate (54377), Blue pressure plate (54379), Green pressure plate (54381), Green pressure plate (54383), Green pressure plate (54385), Green pressure plate (54387), Yellow pressure plate (54389), Yellow pressure plate (54391), Yellow pressure plate (54393), Yellow pressure plate (54395), Orange pressure plate (54397), Orange pressure plate (54399), Orange pressure plate (54401), Orange pressure plate (54403) + +Base: 2945 +Linked animations: [14542, 14543] +Linked objects: Rubble (54138), Rubble (54139), Rubble (54140), Rubble (54141), Rubble (54142), Rubble (54143), Rubble (54144), Rubble (54145), null (54150), null (54151), null (54152), null (54153), null (54158), null (54159), null (54160), null (54161) + +Base: 2946 +Linked animations: [14449, 14498, 14544] +Linked objects: Pedestal (54110), Pedestal (54111), Pedestal (54112), Pedestal (54113), Pedestal (54114), Pedestal (54115), Pedestal (54116), Pedestal (54117) + +Base: 2947 +Linked animations: [14552, 14553, 14556, 14626] +Linked objects: Tightrope (54241), Tightrope (54242), Tightrope (54243), Tightrope (54244), Tightrope (54245), Tightrope (54246), Tightrope (54247), Tightrope (54248) + +Base: 2948 +Linked animations: [14514, 14515] +Linked objects: Tomb (54439), Tomb (54441), Tomb (54445), Tomb (54447), Tomb (54451), Tomb (54453), Tomb (54455) + +Base: 2949 +Linked animations: [14446, 14447, 14448] +Linked objects: Crystal of the Warrior (Active) (53977), Crystal of the Mage (Active) (53978), Crystal of the Ranger (Active) (53979), Crystal of the Warrior (Inactive) (53980), Crystal of the Mage (Inactive) (53981), Crystal of the Ranger (Inactive) (53982) + +Base: 2950 +Linked animations: [14438] + +Base: 2951 +Linked animations: [14488, 14489, 14490, 14491, 14492, 14493, 14494, 14495, 14496, 14497] +Linked objects: null (54462), null (54463), null (54464), null (54465), null (54466), null (54467), null (54468), null (54469), null (54470), null (54471), null (54472), null (54473), null (54474), null (54475), null (54476), null (54477) + +Base: 2952 +Linked animations: [14414, 14415] + +Base: 2953 +Linked animations: [14410, 14625] +Linked objects: Damaged bridge (54186), Damaged bridge (54187), Damaged bridge (54188), Damaged bridge (54189), null (54190), null (54191), null (54192), null (54193) + +Base: 2954 +Linked animations: [14528, 14529, 14530, 14531, 14532, 14533, 14534] + +Base: 2955 +Linked animations: [14570] +Linked objects: null (54722), null (54727), null (54728), null (54729), null (54730) + +Base: 2956 +Linked animations: [14453, 14454, 14455, 14456, 14457, 14458, 14459, 14460] + +Base: 2957 +Linked animations: [14420, 14421, 14422, 14423, 14424, 14425, 14426, 14427, 14428, 14429, 14430] +Linked NPCs: Runebound behemoth (11752), Runebound behemoth (11753), Runebound behemoth (11754), Runebound behemoth (11755), Runebound behemoth (11756), Runebound behemoth (11757), Runebound behemoth (11758), Runebound behemoth (11759), Runebound behemoth (11760), Runebound behemoth (11761), Runebound behemoth (11762), Runebound behemoth (11763), Runebound behemoth (11764), Runebound behemoth (11765), Runebound behemoth (11766), Runebound behemoth (11767), Runebound behemoth (11768), Runebound behemoth (11769), Runebound behemoth (11770), Runebound behemoth (11771), Runebound behemoth (11772), Runebound behemoth (11773), Runebound behemoth (11774), Runebound behemoth (11775), Runebound behemoth (11776), Runebound behemoth (11777), Runebound behemoth (11778), Runebound behemoth (11779), Runebound behemoth (11780), Runebound behemoth (11781), Runebound behemoth (11782), Runebound behemoth (11783), Runebound behemoth (11784), Runebound behemoth (11785), Runebound behemoth (11786), Runebound behemoth (11787), Runebound behemoth (11788), Runebound behemoth (11789), Runebound behemoth (11790), Runebound behemoth (11791), Runebound behemoth (11792), Runebound behemoth (11793), Runebound behemoth (11794), Runebound behemoth (11795), Runebound behemoth (11796), Runebound behemoth (11797), Runebound behemoth (11798), Runebound behemoth (11799), Runebound behemoth (11800), Runebound behemoth (11801), Runebound behemoth (11802), Runebound behemoth (11803), Runebound behemoth (11804), Runebound behemoth (11805), Runebound behemoth (11806), Runebound behemoth (11807), Runebound behemoth (11808), Runebound behemoth (11809), Runebound behemoth (11810), Runebound behemoth (11811), Runebound behemoth (11812), Runebound behemoth (11813), Runebound behemoth (11814), Runebound behemoth (11815), Runebound behemoth (11816), Runebound behemoth (11817), Runebound behemoth (11818), Runebound behemoth (11819), Runebound behemoth (11820), Runebound behemoth (11821), Runebound behemoth (11822), Runebound behemoth (11823), Runebound behemoth (11824), Runebound behemoth (11825), Runebound behemoth (11826), Runebound behemoth (11827), Runebound behemoth (11828), Runebound behemoth (11829), Runebound behemoth (11830), Runebound behemoth (11831), Runebound behemoth (11832), Runebound behemoth (11833), Runebound behemoth (11834), Runebound behemoth (11835), Runebound behemoth (11836), Runebound behemoth (11837), Runebound behemoth (11838), Runebound behemoth (11839), Runebound behemoth (11840), Runebound behemoth (11841), Runebound behemoth (11842), Runebound behemoth (11843), Runebound behemoth (11844), Runebound behemoth (11845), Runebound behemoth (11846), Runebound behemoth (11847), Runebound behemoth (11848), Runebound behemoth (11849), Runebound behemoth (11850), Runebound behemoth (11851), Runebound behemoth (11852), Runebound behemoth (11853), Runebound behemoth (11854), Runebound behemoth (11855), Runebound behemoth (11856), Runebound behemoth (11857), Runebound behemoth (11858), Runebound behemoth (11859), Runebound behemoth (11860), Runebound behemoth (11861), Runebound behemoth (11862), Runebound behemoth (11863), Runebound behemoth (11864), Runebound behemoth (11865), Runebound behemoth (11866), Runebound behemoth (11867), Runebound behemoth (11868), Runebound behemoth (11869), Runebound behemoth (11870), Runebound behemoth (11871) + +Base: 2958 +Linked animations: [14405, 14406, 14407, 14408] +Linked NPCs: Pondskater (12089), Pondskater (12090), Pondskater (12091), Pondskater (12092), Pondskater (12093) + +Base: 2959 +Linked animations: [14473] +Linked graphics: 2766 + +Base: 2960 + +Base: 2961 +Linked animations: [14511] +Linked graphics: 2750 + +Base: 2962 +Linked animations: [14512, 14513] +Linked graphics: 2751, 2752 + +Base: 2963 +Linked animations: [14510] +Linked graphics: 301 + +Base: 2964 +Linked animations: [14508] +Linked graphics: 175 + +Base: 2965 +Linked animations: [14431, 14432, 14433] +Linked graphics: 2769, 2770, 2771 + +Base: 2966 +Linked animations: [14540, 14541] + +Base: 2967 +Linked animations: [14402, 14403, 14404] + +Base: 2968 +Linked animations: [14444, 14445] +Linked graphics: 165, 166 + +Base: 2969 +Linked animations: [14411] +Linked graphics: 2776 + +Base: 2970 +Linked animations: [14389, 14391] +Linked graphics: 2767, 2768 + +Base: 2971 +Linked animations: [14526, 14527] +Linked graphics: 2754, 2755 + +Base: 2972 +Linked animations: [14535, 14536] +Linked graphics: 2756, 2757, 2758, 2759, 2760, 2761, 2762, 2763 + +Base: 2973 +Linked animations: [14369, 14370, 14371, 14372, 14373, 14374, 14375, 14376, 14377, 14378, 14379, 14380, 14381, 14382, 14383, 14384, 14385, 14390, 14392, 14393, 14395, 14396, 14397, 14398, 14412, 14416, 14417, 14418, 14442, 14443, 14450, 14525, 14537, 14538, 14539] +Linked NPCs: Yk'Lagor the Thunderous (11872), Yk'Lagor the Thunderous (11873), Yk'Lagor the Thunderous (11874), Yk'Lagor the Thunderous (11875), Yk'Lagor the Thunderous (11876), Yk'Lagor the Thunderous (11877), Yk'Lagor the Thunderous (11878), Yk'Lagor the Thunderous (11879), Yk'Lagor the Thunderous (11880), Yk'Lagor the Thunderous (11881), Yk'Lagor the Thunderous (11882), Yk'Lagor the Thunderous (11883), Yk'Lagor the Thunderous (11884), Yk'Lagor the Thunderous (11885), Yk'Lagor the Thunderous (11886) + +Base: 2974 +Linked animations: [14399, 14400, 14401] + +Base: 2975 +Linked animations: [14394] + +Base: 2976 +Linked animations: [14461, 14462] + +Base: 2977 +Linked animations: [14546, 14547, 14548] +Linked graphics: 134, 135, 136 + +Base: 2978 +Linked animations: [14551, 14558] +Linked graphics: 137, 138 + +Base: 2979 +Linked animations: [14587] + +Base: 2980 +Linked animations: [14622] +Linked graphics: 2778 + diff --git a/dumps/530/animations b/dumps/530/animations new file mode 100644 index 0000000..93aed80 --- /dev/null +++ b/dumps/530/animations @@ -0,0 +1,2755 @@ +anim 3 - Look side to side +anim 5 - Cooking on range +anim 13 - Old ghost walk +anim 15 - Old ghost stand +anim 37 - Hammering object +anim 38 - Mending Burst Pipe (Artisan’s Workshop) +anim 39 - Hammering object (advanced) +anim 40 - Hammering ground +anim 41 - Standing with hammer +anim 42 - Hammering object +anim 45 - Joining bonfire, then leaving. +anim 70 - Walking with right arm down and leaning slightly. +anim 71 - Holding onto something, pushing, or leaning on something while breathing hard. +anim 72 - Mining with Gilded Rune Pickaxe +anim 74 - Mining with Gilded Bronze Pickaxe +anim 75 - Mining with Gilded Steel Pickaxe +anim 76 - Mining with Gilded Iron Pickaxe +anim 77 - Mining with Gilded Mithril Pickaxe +anim 78 - Mining with Gilded Adamant Pickaxe +anim 87 - Border Guard Holding Axe +anim 88 - Border Guard Lifts Axe +anim 108 - Mining and struggling with Gilded Dragon Pickaxe +anim 111 - Mining and struggling with Gilded Rune Pickaxe +animGFX 122 1471 - Classic Cape (emote) (e) +anim 132 - Mining and struggling with Gilded Bronze Pickaxe +anim 133 - Mining and struggling with Gilded Steel Pickaxe +anim 134 - Mining and struggling with Gilded Iron Pickaxe +anim 135 - Mining and struggling with Gilded Mithril Pickaxe +anim 148 - Mining and struggling with Gilded Rune Pickaxe +anim 151 - Pulling Christmas Cracker +anim 157 - Mining and struggling with Gilded Dragon Pickaxe +anim 158 - One Hammer hit +anim 159 - One Hammer hit +anim 160 - One Sacred Clay hammer hit +anim 161 - One Sacred Clay hammer hit +anim 173 - Use Bull-Roarer (Legend’s Quest) +anim 210 - One Sacred Clay Hammer hit +anim 226 - On floor holding legs as if hurt +anim 227 - Limping (DR-1622) +anim 228 - Limping walk (DR-1622) +anim 230 - One Sacred Clay hammer hit +anim 231 - One Golden hammer hit +anim 233 - One Golden hammer hit +anim 234 - Rock Mining and struggling with Gilded Bronze Pickaxe +anim 235 - Rock Mining and struggling with Gilded Steel Pickaxe +anim 236 - Rock Mining and struggling with Gilded Iron Pickaxe +anim 237 - Rock Mining and struggling with Gilded Adamant Pickaxe +anim 238 - Rock Mining and struggling with Gilded Mithril Pickaxe +anim 249 - Rock Mining and struggling with Gilded Rune Pickaxe +anim 250 - Rock Mining and struggling with Gilded Dragon Pickaxe +anim 251 - Rock Mining and struggling with Gilded Bronze Pickaxe +anim 252 - Rock Mining and struggling with Gilded Steel Pickaxe +anim 253 - Rock Mining and struggling with Gilded Iron Pickaxe +anim 269 - Rock Mining and struggling with Gilded Mithril Pickaxe +anim 270 - Rock Mining and struggling with Gilded Adamant Pickaxe +anim 271 - Rock Mining and struggling with Gilded Rune Pickaxe +anim 272 - Rock Mining and struggling with Gilded Dragon Pickaxe +anim 273 - Mining and struggling with Gilded Rune Pickaxe +anim 282 - Mining and struggling with Gilded Bronze Pickaxe +anim 294 - Mining and struggling with Gilded Steel Pickaxe +anim 295 - Mining and struggling with Gilded Iron Pickaxe +anim 297 - Mining and struggling with Gilded Adamant Pickaxe +anim 308 - Mining and struggling with Gilded Mithril Pickaxe +anim 316 - Idle Animation (DR-2025) +anim 317 - Duellist Cap Brag (Version One) (T1) +anim 318 - Duellist Cap Brag (Version Two) (T2) +anim 329 - Salty Claws Hat Dance (e) +anim 330 - Magic Carpet flight +anim 331 - Magic Carpet landing +anim 346 - Sitting with hands behind back +anim 347 - Sitting while casting a spell +animGFX 352 1446 - Veteran’s Cape Emote (5 Years) +animGFX 356 307 - Completionist Cape (Begin) (Turn into Dragon) (NPC-ID: 1830) +animGFX 361 122 - Wildstalker Helmet Brag (Version Three) +anim 363 - Mix potion +anim 364 - Pestle mortar +anim 365 - Potion explosion (Glitched on RS3) +anim 376 - Attack +anim 377 - Attack +anim 378 - Defend +anim 380 - Attack +anim 381 - Stab Attack +anim 382 - Stab Attack +anim 383 - Defend +anim 385 - Tramp Throw Rotten Tomato (Projectile GFX 29) (Tile GFX 31) +anim 386 - Stab attack +anim 387 - Defend +anim 388 - Defend +anim 389 - Ice Warrior Defend +anim 390 - Attack +anim 391 - Ice Warrior Attack (transparent) +anim 393 - Auto Attack with Claws (Legacy) +anim 394 - Attack transparent +anim 395 - Attack +anim 396 - Dagger attack +anim 397 - Defend With Claws (Legacy) +anim 398 - Defend +anim 399 - Defend transparent +anim 400 - Attack +anim 401 - Mace Auto Attack (Legacy) +anim 403 - Defend with Mace (Legacy) +anim 404 - Defend with Mace and Shield +anim 406 - Attack with 2H Sword +anim 409 - Marion Polishing Her Trophy at the Bar +anim 410 - Attack with 2H Sword +animGFX 412 121 - Wildstalker Helmet Brag (Version Two) +anim 413 - Moving arms to the side while holding staff? +anim 414 - Attack with Staff (IE Mourner in West Ardy) +anim 415 - Defend Holding Staff (IE Mourner in West Ardy) +anim 416 - Sticking arm out, as if holding a staff for a few seconds +anim 419 - Attack with staff? +anim 420 - Defend +anim 421 - Lunge attack (or rolling a ball?) +anim 422 - Punch +anim 423 - Kick +anim 424 - Defend unarmed +anim 425 - Defend +anim 426 - Fire bow +anim 428 - Attack with Spear +anim 429 - Attack melee with Spear +anim 430 - Defend with 2H Spear +anim 431 - Defend with Spear +anim 433 - Attack +anim 434 - Defend +anim 435 - Defend +anim 436 - Candle Seller Idle (NPC-ID 1834) (DR-1978) +anim 437 - Attack +anim 438 - Attack +anim 440 - Attack +animGFX 442 23 - Climbing Falador Wall With Grapple +animGFX 445 56 - Spread ashes +anim 451 - Pick something off ground +anim 471 - Holding arm out (Border guard?) +anim 473 - Finish Monkey bars +anim 482 - Climb onto monkey bar +anim 483 - Climb across monkey bar +anim 484 - Fire crossbow +anim 487 - Fletch something? +animGFX 507 91 - Duellist Cap Brag (Version Two) (T1) +animGFX 508 91 - Duellist Cap Brag (Version Two) (T2) +animGFX 509 91 - Duellist Cap Brag (Version Two) (T3) +animGFX 510 91 - Duellist Cap Brag (Version Two) (T4) +animGFX 511 91 - Duellist Cap Brag (Version Two) (T5) +animGFX 512 92 - Duellist Cap Brag (Version Three) (T1) +animGFX 513 92 - Duellist Cap Brag (Version Three) (T2) +anim 528 - Whirlpool +anim 529 - Cover head with hands +animGFX 530 92 - Duellist Cap Brag (Version Three) (T3) +animGFX 531 92 - Duellist Cap Brag (Version Three) (T4) +animGFX 532 92 - Duellist Cap Brag (Version Three) (T5) +animGFX 533 92 - Duellist Cap Brag (Version Three) (T6) +anim 534 - Wildstalker Helmet Brag (Version One) +anim 535 - Open PoH Wardrobe +anim 536 - Open Chest +anim 537 - Putting Object on Table +anim 538 - Take something from chest +anim 539 - Close chest +anim 540 - Crawl into Lumbridge Swamp Dungeon Tree +anim 541 - Close Wardrobe +anim 542 - Open Wardrobe +anim 545 - Open Wardrobe +anim 546 - Estocada Idle (DR-683) (NPC-ID 3670) +anim 547 - Dagger attack? +anim 550 - Dagger attack? +anim 551 - Dagger attack? +anim 552 - Mr. Ex Idle (DR-689) (NPC-ID 3709) +anim 553 - Swipe attack +anim 582 - Throw dart +anim 618 - Harpoon fishing +anim 619 - Lobster cage fishing +anim 620 - Net fishing +anim 621 - Net fishing +anim 622 - Rod Fishing +anim 623 - Rod fishing +anim 624 - Mining with Rune Pickaxe +anim 625 - Mining with Bronze Pickaxe +anim 626 - Mining with Iron Pickaxe +anim 627 - Mining with Steel Pickaxe +anim 628 - Mining with Adamant Pickaxe +anim 629 - Mining with Mithril Pickaxe +anim 642 - Step back startled +anim 645 - Praying at altar/gravestone +anim 654 - Getting on magic carpet +anim 661 - Hands Together [Banker Idle (DR-2026) (NPC-ID 4456)] +anim 691 - Banker Idle (DR-2026) (NPC-ID 4456) +anim 692 - Banker Idle (DR-2028) (NPC-ID 4458) +anim 707 - Cast Spell? +anim 708 - Iban staff +anim 709 - Hands Together +anim 710 - Cast Spell (Wise Old Man uses it) +anim 711 - Cast Spell +animGFX 711 108 - Casting Spell +anim 712 - Old Low Alchemy +anim 713 - Old High Alchemy +animGFX 716 102 - Casting Weaken +anim 717 - Cast Spell +anim 718 - Cast Spell +anim 719 - Raise one hand in air, raise other to the side (Enchant Jewelry?) +anim 720 - Raise one hand in air, raise other to the side (Enchant Jewelry?) +anim 721 - Raise one hand in air, raise other to the side (Enchant Jewelry?) +anim 722 - Raise one hand in air, raise other to the side (Enchant Jewelry?) +anim 723 - Stick both arms in air, pointing upwards +anim 724 - Cast spell/push +anim 727 - Idle (Brushing knees) +anim 728 - Cast a spell +anim 729 - Cast a spell +anim 733 - Tinderbox +anim 734 - Thrown back (Like with the Fire Wall in Legends Quest) +anim 735 - In air while being thrown back (Like with the Fire Wall in Legends Quest) +anim 736 - Land on bottom (Like with the Fire Wall in Legends Quest) +anim 737 - Climbing wall +anim 738 - Climbing wall +anim 739 - Climbing down wall +anim 740 - Climbing down wall +anim 741 - Jump short gap (Has sound effect) +anim 742 - Jump up to grab monkey bars +anim 743 - Finish crossing monkey bars +anim 744 - Crossing monkey bars +anim 745 - Holding on to monkey bar +anim 746 - Idle +anim 748 - Run +anim 749 - Walk +anim 751 - Rope Swing +anim 752 - Move to cross wall obstacle +anim 753 - Move to cross wall obstacle +anim 754 - Crossing wall obstacle +anim 755 - On wall obstacle +anim 756 - Crossing wall obstacle +anim 757 - On wall obstacle +anim 758 - Finish crossing wall obstacle +anim 759 - Finish crossing wall obstacle +anim 760 - Fall onto floor face down +anim 761 - Fall onto floor face down +anim 762 - Crossing log obstacle +anim 763 - Standing on log obstacle +anim 764 - Falling off log +anim 765 - Drowning +anim 766 - Falling +anim 767 - Landing on stomach +anim 768 - Falling After Failing Plank Obstacle (Brimhaven Agility) +anim 769 - Jump Bridge +anim 770 - Lose Balance and Fall +anim 771 - Lose Balance and Fall +anim 772 - Swim (DR-188) +anim 773 - Swim Idle (DR-188) +anim 774 - Idle (leaning forward) +anim 775 - Summon rope swing +anim 776 - Crossing low water +anim 777 - Standing in low water +anim 778 - Tackle Gnomeballer +anim 779 - Hurt foot/knee +anim 780 - Bend forward +anim 782 - Cheer and then move hands together +anim 783 - Throw Gnome Ball +anim 784 - Nod head, twirl, dance +anim 787 - Plop on belly and fade away +anim 789 - Throw Bolas? +anim 791 - Old runecrafting +anim 792 - Standing holding something with both hands while boat rocks? +anim 794 - Stomp on balloon? +anim 795 - Start to fall but then catch self +anim 796 - one frame of catching self? +anim 797 - Holding on to edge, then going into a crawl +anim 798 - Pull lever? +anim 799 - Stab with cattle prod +anim 800 - On knees, playing game? +anim 802 - Flappy cheer +anim 803 - Grow from nothing +anim 804 - Shrink into nothing +anim 805 - Move hand as if opening slidey door lock +anim 806 - Idle standing, looking and limping +anim 807 - Jump obstacle (in air for several frames) +anim 808 - Standard Idle (Used in Many Default Renders) +anim 809 - Idle (looks tense) +anim 810 - Push open Compost Bin +anim 811 - Cast Spell (Nature Spirit) +anim 812 - Walk +anim 813 - Idle +anim 814 - Invisible +anim 815 - Crawling (tiny) +anim 816 - Crawling pose idle (tiny) +anim 817 - Fill bucket +anim 818 - Old Dance Emote +anim 819 - Standard Walk (Used in Many Default Renders) +anim 820 - Standard Walking Backwards (Used in Many Default Renders) +anim 821 - Standard Side Step A (Used in Many Default Renders) +anim 822 - Standard Side Step B (Used in Many Default Renders) +anim 823 - Standard Turning (Used in Many Default Renders) +anim 824 - Standard Run (Used in Many Default Renders) +anim 825 - Holding weapon +anim 826 - Walking with weapon +anim 827 - Multi-Use “Bend Over†+anim 828 - Use ladder +anim 829 - Eat (old) +anim 830 - Dig with spade +anim 831 - Dig with spade (loop) +anim 832 - Multi-Use “Take†+anim 833 - Multi-Use “Put†+anim 834 - Move forward and grab something? +anim 835 - Move forward and grab something? +anim 836 - Death +anim 837 - Fall on Back and Die +anim 838 - On Back Dead +anim 839 - Climb Over Object +anim 840 - Reading map +anim 841 - Transparent walking +anim 842 - Transparent standing +anim 843 - Ice Warrior Death +anim 844 - Crawling +anim 845 - Crawl to enter Plain of Mud cave +anim 846 - Startled step back +anim 847 - Stand holding weapon +anim 848 - Mind controlled/dizzy +anim 854 - Alternate looking at both hands in confused manner, looped +anim 855 - Nod head +anim 856 - Shake head no +anim 857 - Think +anim 858 - Bow +anim 859 - Angry +anim 860 - Cry +anim 861 - Laugh +anim 862 - Cheer +anim 863 - Wave Emote +anim 864 - Beckon +anim 865 - Clap +anim 866 - Dance +anim 867 - Woodcutting with Rune hatchet +anim 869 - Woodcutting with Adamant hatchet +anim 870 - Woodcutting with Dragon hatchet +anim 871 - Woodcutting with Mithril hatchet +anim 872 - Woodcutting with Rune hatchet +anim 873 - Woodcutting with Black hatchet +anim 874 - Woodcutting with Adamant hatchet +anim 875 - Woodcutting with Steel hatchet +anim 876 - Woodcutting with Mithril hatchet +anim 877 - Woodcutting with Iron hatchet +anim 878 - Woodcutting with Black hatchet +anim 879 - Woodcutting with Bronze hatchet +anim 880 - Woodcutting with Steel hatchet +anim 881 - Pick pocket +anim 883 - Spin Potter's Wheel +anim 884 - Glass blowing +anim 885 - Cut Dragonstone +anim 886 - Cut Diamond +anim 887 - Cut Ruby +anim 888 - Cut Sapphire +anim 889 - Cut Emerald +anim 890 - Cut Opal +anim 891 - Cut Jade +anim 892 - Cut Topaz +anim 893 - Shearing sheep +anim 894 - NPC standing at bar drinking and turning around +anim 895 - Fill bucket with sand +anim 896 - Old cooking on range animation +anim 897 - Old cooking on fire +anim 898 - Smithing with Hammer +anim 899 - Old Furnace animation +anim 902 - Sidestep with weapon +anim 903 - Sidestep with weapon +anim 904 - Walking backwards with weapon +anim 908 - Use bullroarer (Legends Quest) +anim 909 - Write something +anim 910 - Machete +anim 911 - Cut Spider Web +anim 915 - Look over duel arena +anim 916 - Overlooking duel arena +anim 918 - Brown Toy Horse +anim 919 - White Toy Horse +anim 920 - Black Toy Horse +anim 921 - Grey Toy Horse +anim 923 - Big attack +anim 929 - Throw something (slowly) +anim 931 - Holding something (shakes hand like a salt shaker?) +anim 1017 - Stuck in mud +anim 1024 - Ogre bellows +anim 1025 - On back dead +anim 1032 - Idle +anim 1033 - Walk +anim 1034 - Pull Lever (Elemental Workshop III) +anim 1035 - Pull Lever (Elemental Workshop III) +anim 1036 - Pull lever +anim 1037 - Pull lever +anim 1056 - Dragon Battleaxe special attack? +anim 1057 - Old excalibur +anim 1058 - Walk backwards +anim 1059 - Walk with weapon +animGFX 1060 251 - Dragon Mace Special Attack +animGFX 1062 252 H92 - Dragon Dagger Special [EoC] +anim 1064 - Tiptoe +anim 1065 - Walk +anim 1067 - Big lunge attack +anim 1074 - Fire bow (sound effect sounds like two arrows are being fired) +anim 1077 - Use Bucket on Coffin (Priest in Peril) +anim 1078 - Tiptoe backwards +anim 1079 - Tiptoe run +anim 1080 - Idle +anim 1081 - Walk slowly +anim 1082 - Walk slowly (backwards) +anim 1083 - Run slowly +animGFX 1084 1009 H30 - Surok Casts Spell +anim 1100 - Silver sickle +anim 1105 - Fail agility obstacle and fall +anim 1106 - Try to climb wall obstacle but fail +anim 1110 - Brimhaven Agility Course Darts “Matrix†+anim 1115 - Pressure Pads Brimhaven Agility +anim 1117 - Handholds +anim 1118 - Handholds +anim 1119 - Fail handholds +anim 1120 - Finish handholds +anim 1121 - Crossing handholds +anim 1122 - Crossing handholds +anim 1123 - Fail handholds +anim 1124 - Finish handholds +anim 1125 - Step forward, then step back +anim 1128 - Glass wall (emote) (e) +anim 1129 - Lean (emote) (e) +anim 1130 - Climb Rope (emote) (e) +anim 1131 - Glass box (emote) (e) +anim 1133 - Jump belly first to cross obstacle +anim 1137 - Standing (facing other way) +anim 1138 - Walking backwards +anim 1142 - Idle +anim 1144 - Standing (below ground) +anim 1145 - Shake fist (below ground) +anim 1146 - Walk (choppy) +anim 1147 - Lean back (below ground) +anim 1148 - Walk backwards then climb down wall +anim 1156 - Defend While Holding 1H Weapon and Shield (Legacy) +anim 1157 - Electrocute? +anim 1161 - Cast spell +anim 1162 - Walk +anim 1163 - Cast spell +anim 1164 - Cast spell +anim 1165 - Cast spell +anim 1166 - Cast spell +anim 1167 - Cast spell +anim 1168 - Cast spell +anim 1169 - Cast spell +animGFX 1174 1443 - Completionist Cape Emote (Middle) (As Dragon) (NPC-ID: 1830) +anim 1175 - Completionist Cape Emote (End) (Turn Back From Being Dragon) +anim 1177 - Walk backwards +anim 1179 - Max Cape Emote (Step One) +anim 1180 - Max Cape Emote (Step Two) (Inferno adze and Saw) +anim 1181 - Max Cape Emote (Step Three) (Crystal Pick) +anim 1182 - Max Cape Emote (Step Four) (Hatchet and Watering Can) +anim 1191 - Running +anim 1192 - Slice banana +anim 1193 - Fishing with Karambwan Vessel +anim 1194 - Drink Karamja Rum +anim 1195 - Use Banana with Karamja Rum +anim 1196 - Cough repeating +anim 1198 - Side step +anim 1201 - Side step +anim 1203 - Attack with weapon +anim 1205 - Walk +anim 1206 - Walk backwards +anim 1207 - Side step +anim 1208 - Side step +anim 1209 - Shake hips cutely +anim 1210 - Running +anim 1217 - Idle with hands together in front of hips, standing in one square ahead +anim 1233 - Scratch hips (part of same idle as 1217) +anim 1236 - Cross tripwire? +anim 1237 - Walk, the turn to dodge something, then continue walking +anim 1238 - Mining with gilded rune pickaxe +anim 1239 - Mining with gilded bronze pickaxe +anim 1240 - Step back and wave arm +anim 1241 - Invisible +anim 1248 - Fletch logs +anim 1249 - Craft leather +anim 1250 - Max Cape Emote (Step Five) (Smithing and Crafting) +animGFX 1251 4253 - Max Cape Emote (Step Six) (Prepare For Battle) +anim 1252 - Climb Over obstacle +anim 1254 - Mining with gilded iron pickaxe +anim 1256 - Mining with gilded steel pickaxe +anim 1258 - Plop on belly, get on knees (choppy) +anim 1259 - Mining with gilded adamant pickaxe +anim 1263 - Try to push open lock? +anim 1264 - Throw something forward? +anim 1267 - Cover head with hands irritated? +anim 1275 - Two frames of limping stance +anim 1280 - Craft something? +animGFX 1291 1505 1686 - Max Cape Emote (Step Seven) (Fighting) +anim 1306 - Walking with both hands out forward +anim 1307 - Bend back slightly +anim 1309 - Craft something +anim 1316 - Mining with gilded mithril pickaxe +anim 1318 - Hold lyre +anim 1319 - Hold lyre +anim 1320 - Play lyre +anim 1321 - Play lyre +anim 1322 - Hold tankard of beer +anim 1323 - Walk with tankard of beer +anim 1324 - Walk backwards with tankard of beer +anim 1325 - Side step with tankard of beer +anim 1326 - Side step with tankard of beer +anim 1327 - Drink beer +anim 1328 - Mining with gilded dragon pickaxe +anim 1329 - Sitting on ground, pretzel position +anim 1330 - Drink keg of beer +anim 1331 - Get on knees as if showing respect +anim 1332 - Getting off knees +anim 1333 - Petting rock +anim 1334 - Idle, hand on hip, +anim 1335 - Preach White book +anim 1336 - Preach Red book +anim 1337 - Preach Green book +anim 1350 - Read book +anim 1351 - Sit on stool +anim 1352 - Scratch head on stool +anim 1353 - Cover mouth on stool +anim 1354 - Move hand sitting on stool +anim 1363 - Eat +anim 1364 - Sitting (no chair or stool appears) +anim 1365 - Daemonheim Wilderness Guard +anim 1366 - Daemonheim Wilderness Guard Letting Player Pass +anim 1367 - Craft Dramen Staff +anim 1368 - Running with weapon +animGFX 1374 1702 - Blow Kiss (emote) (e) +anim 1376 - Linza Smithing? +anim 1379 - Electrocute, then go on knees? +anim 1406 - Bucket +anim 1407 - On knees in dead position +anim 1408 - Lying dead stretched out +anim 1409 - Getting up from Lying dead stretched out +anim 1421 - Idle +anim 1422 - Walk +anim 1423 - Walk backwards +anim 1424 - Side step +anim 1425 - Side step +anim 1426 - Walk +anim 1427 - Run +anim 1428 - Attack +anim 1429 - Defend +anim 1441 - Startled step back +anim 1457 - Yo-yo +anim 1458 - Yo-yo +anim 1459 - Yo-yo +anim 1460 - Yo-yo +anim 1461 - Sitting on sled +anim 1462 - Riding sled +anim 1463 - Riding sled +anim 1464 - Crash on sled? +anim 1465 - Get off sled? +anim 1466 - Defend on sled? +anim 1467 - Riding sled +anim 1468 - Walking on sled +anim 1469 - Eat on sled +anim 1470 - Wax sled +anim 1479 - Walk, looking side to side +anim 1481 - Shake fist on sled +anim 1482 - Cheer on sled +anim 1483 - Wave on sled +anim 1484 - Beckon on sled +anim 1485 - Clap on sled +anim 1486 - Pick Trollweiss Flower (A) +anim 1487 - Pick Trollweiss Flower (B) +anim 1493 - Sweep broom? +anim 1494 - Walk sweeping broom? +anim 1504 - Blood Runs Deep Wedding Kiss (A) +anim 1505 - Blood Runs Deep Wedding Kiss (B) +anim 1506 - Floating (glitched) +anim 1507 - Lunar Floating +anim 1508 - Lunar Floating +anim 1509 - Lunar Floating Eat? +anim 1510 - Lunar Floating Attack? +anim 1511 - Mining with Bronze Pickaxe +anim 1514 - Headache on floor +anim 1531 - Barbarian Cheering (Gunnar’s Ground) +anim 1544 - Lunar Floating Climb Rope? +anim 1548 - Pull Lever on Wall +anim 1551 - Idle +anim 1552 - Climb out of ground +anim 1560 - Climb Stile +anim 1563 - Use Spinning Wheel +anim 1565 - Drunk? +anim 1567 - Idle (turned around) +anim 1572 - Bend knees and cover ears +anim 1575 - Stick arm out +anim 1601 - Werewolf Agility Zipline +anim 1602 - Zipline +anim 1603 - Jump obstacle (Werewolf Agility) +anim 1604 - Jump short obstacle (Werewolf Agility) +anim 1605 - Cheering +anim 1606 - Kick skull ball +anim 1633 - Use extended brush (Creature of Fenkenstrain) +anim 1638 - Bend over to use something? +anim 1648 - Turning Wheel (Ectofuntus) +anim 1649 - Fill Hopper with Bones (Ectofuntus) +anim 1650 - Fill Pot With Bonemeal +anim 1651 - Ectofuntus Praying +animGFX 1652 2685 - Electrocute (Elemental Workshop III) +anim 1653 - Spasms +anim 1658 - Throw weapon? +anim 1659 - Defend (spazzy) +anim 1660 - Walk +anim 1661 - Run +anim 1662 - Hold weapon +anim 1663 - Walk with weapon +anim 1664 - Run with weapon +animGFX 1665 340 - Maul Swipe Attack +anim 1666 - Defend with Maul +anim 1667 - Attack with Maul +anim 1669 - Idle +anim 1670 - Old Angry Emote +anim 1671 - Old Cheer Emote +anim 1672 - Old Beckon Emote +anim 1673 - Walk +anim 1705 - Idle (Turned Around) +anim 1722 - Old Home Teleport Start +anim 1723 - Old Home Teleport Half-Turn +anim 1724 - Old Home Teleport Next Half-Turn +anim 1728 - Digging with rock pick +anim 1735 - Tower of Life “The Guns†lifting weight +anim 1736 - Sitting in seat with hands in lap +anim 1739 - Walking with arms behind back +anim 1740 - Standing with arms behind back +anim 1743 - Angry +anim 1744 - Angry +anim 1745 - Angry stomping +anim 1746 - Angry fists in air then kicking +anim 1755 - Hit with hammer +anim 1765 - Look to the side +anim 1766 - Pole jumping (Mountain Daughter) +anim 1767 - Pick something off ground +anim 1768 - Doing something to object on ground +anim 1772 - Looking to the side +anim 1774 - Looking to the side and pointing +anim 1775 - Idle +anim 1776 - Idle +anim 1777 - On floor on back +anim 1778 - Place hand on pocket and then realize you’ve been pickpocketed +anim 1779 - Look behind you (has a sound effect that sounds like photo being taken) +anim 1780 - Looking at map in hand (item in hand can’t be seen) (same sound effect as above) +anim 1787 - Smithing then showing off weapon +anim 1809 - hands out bend (glitchy) +anim 1810 - Head being held by swamp monster? +anim 1811 - Single frame (glitchy) +anim 1816 - Old shrink and rise up teleport +anim 1818 - Clap and raise fist in air +animGFX 1819 108 H92 - Zaff Seals Varrock Palace Library (What Lies Below) +anim 1820 - Looks same as above +anim 1823 - Festive Mistletoe Kiss +anim 1830 - Walking +anim 1831 - Balancing +anim 1832 - Standing +anim 1833 - Rubber chicken +anim 1834 - Rubber chicken +anim 1835 - Chicken dance +anim 1836 - Skipping (DR-594) +anim 1837 - Idle (DR-594) +anim 1850 - Stand +anim 1851 - Superman flying +anim 1852 - Flying land +anim 1871 - Defend? +anim 1872 - Give a dog a bone +anim 1873 - Linza Idle (DR-2111) (Looks like checking to see if wrist is broken) +anim 1877 - Snake charm +anim 1878 - Snake charm +anim 1879 - Snake charm (below ground) +anim 1880 - Hold weapon? +anim 1882 - Attack +anim 1884 - Attack +anim 1894 - Look side to side while looking at lectern? +anim 1895 - Look side to side while looking at lectern? +anim 1897 - Crawling position +anim 1902 - Spinning plate +anim 1903 - Net fishing +anim 1904 - Plate +anim 1905 - Woodcutting with Sacred Clay hatchet +anim 1906 - Drop Plate +anim 1907 - Woodcutting with Volatile Clay hatchet +anim 1910 - Walk with 2H weapon +anim 1911 - Walk backwards with 2H weapon +anim 1914 - Desert Treasure Vampire +anim 1917 - Sidestep with 2H weapon +anim 1919 - Walk +anim 1920 - Sidestep with 2H weapon +anim 1925 - Run with 2h weapon +anim 1926 - Defend with 2H weapon +anim 1936 - Ozan Idle (DR-2114) +anim 1950 - Fall down trapdoor +anim 1952 - Facing sideways +anim 1953 - Facing the other way +anim 1954 - Facing sideways +anim 1955 - Holding knee +anim 1968 - Ozan Walk (DR-2114) +anim 1978 - Cast spell? +anim 1979 - Cast spell? +anim 1988 - Running +anim 1989 - Cutting chocolate bar +anim 1992 - Jump down something +anim 1993 - Climb up something +anim 1994 - Jump down and fading away +anim 1995 - Running (OSRS Style) +anim 1996 - Come out portal? Face first on stomach +anim 2009 - Bucket and knife (Tree wax?) +anim 2010 - Bucket +anim 2033 - Sitting +anim 2034 - Sitting +anim 2036 - Get up from sitting on floor +anim 2037 - Standing +anim 2040 - Hold bowl +anim 2041 - Walk with ToG Bowl +anim 2043 - Fill ToG bowl +anim 2044 - Finish filling from ToG +anim 2045 - Drink from bowl +anim 2046 - Light Creature +anim 2047 - End Light Creature +anim 2049 - Climb up wall +anim 2050 - Climb down wall +anim 2060 - Walk +anim 2061 - Idle +anim 2062 - Attack +anim 2063 - Defend +anim 2064 - Walk with Weapon +anim 2065 - Idle with Weapon +anim 2066 - Attack with Two Handed Axe +anim 2067 - Attack +anim 2068 - Attack with both hands alternating +anim 2074 - Stand holding weapon +anim 2076 - Walk holding weapon +anim 2077 - Run holding weapon +anim 2078 - Attack? +anim 2079 - Defend? +anim 2080 - Attack? +anim 2081 - Attack? +anim 2082 - Attack +anim 2094 - Search for Snake Weed (Jungle Potion) +anim 2096 - Arms out +anim 2097 - Arms out as if trying to solve puzzle? +anim 2098 - Open Cell Door (Fight Arena) +anim 2105 - Panic +anim 2106 - Jig Emote +anim 2107 - Twirl +anim 2108 - Headbang Emote +anim 2109 - Jump for joy +anim 2110 - Raspberry +anim 2111 - Yawn +anim 2112 - Salute +anim 2113 - Shrug +anim 2118 - Climb stairs +anim 2119 - Turn valve +anim 2120 - Turn valve +anim 2127 - Goblin Bow (emote) (e) +anim 2128 - Goblin Salute (emote) (e) +anim 2136 - Put something in pocket? +anim 2139 - Pull Up Lever +anim 2140 - Pull Down Lever +anim 2141 - Pull Lever +anim 2142 - Bend and pick something on ground? +anim 2143 - Bend and pick something on ground? +anim 2144 - Dwarven Battle-Axe +anim 2145 - Dwarven Battle-Axe +anim 2146 - Climb up something then climb down? +anim 2148 - Ride Minecart +anim 2149 - Chanting spell? +anim 2161 - Pet Red Pet Rock +anim 2162 - Pet Green Pet Rock +anim 2163 - Walk then stand holding broom thing? (glitchy) +anim 2164 - Walk +anim 2171 - Look Through Telescope in WoM’s House +anim 2206 - Pet Blue Pet Rock +anim 2213 - Pet Yellow Pet Rock +anim 2214 - Pet Rock Fetch +anim 2215 - Green Pet Rock Fetch +anim 2216 - Blue Pet Rock Fetch +anim 2217 - Yellow Pet Rock Fetch +animGFX 2231 370 - Activate Aura +animGFX 2238 358 - Breathe Fire (emote) (e) (LP) +anim 2239 - Jump up high teleport +anim 2240 - Duck under obstacle? +anim 2241 - Fall on ground and die +anim 2242 - Thrown back and fall on back +anim 2243 - Clap (glitchy) +anim 2244 - Clean something on ground? +anim 2246 - Trying to open door? +anim 2247 - Cracking safe? +anim 2248 - Cracking safe? +anim 2249 - Pickpocket safe? +anim 2251 - Running one arm out +anim 2252 - Cat Fight (emote) (e) (LP) +anim 2253 - Standing one arm out +anim 2254 - Face-Palm (emote) (e) (LP) +anim 2255 - Sitting in chair +anim 2256 - Standing Arms Crossed +anim 2257 - Standing one arm out +anim 2258 - Walking one arm out +anim 2259 - Pour vial +anim 2261 - Death +anim 2262 - Walking and looking back and forth +anim 2267 - Touch something up high? +anim 2269 - Cut Watermelon +anim 2270 - Pulling rope? +anim 2271 - Trowel (loop) +anim 2272 - Gardening trowel +anim 2273 - Rake +anim 2274 - Secutars +anim 2275 - Secutars +anim 2276 - Secutars +anim 2277 - Secutars +anim 2278 - Secutars +anim 2279 - Secutars +anim 2280 - Pick from fruit tree +anim 2281 - Pick from fruit tree +anim 2282 - Pick something up from ground +anim 2283 - Pour bucket over ground +anim 2284 - Fill Calquat Keg +anim 2285 - Fill Beer Glass +anim 2286 - Bend on ground and pick something +anim 2288 - Pour Plant Cure +anim 2289 - Drink From Calquat Keg +anim 2290 - Carve Calquat Keg +anim 2291 - Seed Dibber +anim 2292 - Bend and pick something +anim 2293 - Watering Can +anim 2295 - Pick something up high +anim 2303 - Shake Hands (emote) (e) (LP) +anim 2304 - Death +anim 2305 - Milking Cow +anim 2306 - Jumping on Apple Mush +anim 2311 - Fall into trapdoor +anim 2312 - High Five (emote) (e) (LP) +anim 2313 - Trying to open door? +anim 2316 - Holding something with both hands? +anim 2317 - Walk holding something with both hands +anim 2318 - Walk backwards something with both hands +anim 2319 - Side step +anim 2320 - Side step +anim 2321 - Walk +anim 2322 - Run holding one arm up +anim 2323 - Attack holding thing (kick) +anim 2324 - Defend +anim 2326 - Lose balance holding thing? +anim 2327 - Levitate (emote) (e) (LP) +anim 2332 - Tickling with feather +anim 2333 - Ghost Walk +anim 2334 - Ghost Idle +anim 2338 - On Knees +anim 2339 - Sitting on Stool with Beer Glass +anim 2340 - Fall backwards on stool +anim 2343 - Raise beer glass +anim 2347 - ROFL (Male) (emote) (e) (LP) +anim 2359 - ROFL (Female) (emote) (e) (LP) +anim 2360 - Surrender (emote) (e) (LP) +anim 2376 - About to jump +anim 2377 - Get into frog position +anim 2378 - Sitting in Therapist Chair (from Random Event) +anim 2382 - Swipe with machete (Tai Bwo Wannai Cleanup) +anim 2383 - Accidentally disturb jungle (Tai Bwo Wannai Cleanup) +anim 2384 - Repairing fence (Tai Bwo Wannai Cleanup) +anim 2385 - Repairing fence (Tai Bwo Wannai Cleanup) +anim 2386 - Finish repairing fence (Tai Bwo Wannai Cleanup) +anim 2387 - Successfully cut dense jungle (Tai Bwo Wannai Cleanup) +anim 2388 - Exhausted (Tai Bwo Wannai Cleanup) +anim 2389 - Make skewer (Tai Bwo Wannai Cleanup) +anim 2390 - Knocked back from disturbing jungle (Tai Bwo Wannai Cleanup) +anim 2394 - Stab +anim 2400 - Broodoo Victim Cheering +anim 2401 - Idle +anim 2403 - Defend +anim 2406 - Chillin’ (Teplin Macagan Idle (DR-2406)) [NPC ID-3404] +anim 2407 - Teplin Macagan Walk (DR-2406) [NPC ID-3404] +anim 2409 - Craft Broodoo Shield (White) +anim 2410 - Craft Broodoo Shield (Green) +anim 2411 - Craft Broodoo Shield (Orange) +anim 2413 - Climb out of ladder in Draynor Sewer +animGFX 2414 1537 - Original Air Guitar (emote) (e) +anim 2416 - Talk to the Hand (emote) (e) (LP) +animGFX 2417 364 - Snow (emote) (e) (LP) +anim 2420 - Using Thatch Spar Medium with Opal Machete +anim 2421 - Opal Machete Tai Bwo Wannai Cleanup +anim 2422 - Opal Machete Tai Bwo Wannai Cleanup End +anim 2423 - Jade Machete Tai Bwo Wannai Cleanup End +anim 2424 - Jade Machete +anim 2425 - Jade Machete +anim 2426 - Red Topaz Machete +anim 2427 - Red Topaz Machete +anim 2428 - End Red Topaz Machete +anim 2429 - Opal Machete +anim 2430 - Jade Machete +anim 2431 - Red Topaz Machete +anim 2432 - Pulling Machine (Blast Furnace) +anim 2433 - Using Bike Machine (Blast Furnace) +anim 2441 - Use Spade (Blast Furnace) +anim 2442 - Use Spadeful of Coke (Blast Furnace) +anim 2443 - Use Spade (Blast Furnace) +anim 2450 - Use Bucket +animGFX 2553 432 - Elemental Wizard Death +anim 2554 - Elemental Wizard Death GFX +anim 2556 - Thrown Back, land on knees +anim 2557 - On knees +anim 2561 - Hold Weapon +anim 2562 - Walk with Weapon +animGFX 2563 365 - Storm (emote) (e) (LP) +anim 2566 - Muscle-man Pose (emote) (e) (LP) +anim 2569 - Using Compost Potion on Compost Bin +anim 2570 - Use Secuatars +anim 2572 - Push +anim 2573 - Laugh +anim 2574 - Pushing something +anim 2577 - Head to side, using something +anim 2578 - Hands Together Idle +anim 2579 - Grab something +anim 2580 - Gesture head backwards +anim 2581 - Fall off log +anim 2582 - Fall off log +anim 2583 - Jump forward and land on stomach +anim 2584 - Alison Elmshaper Idle (Taverly Fletching Tutor) +anim 2585 - Climb up something +anim 2586 - Jump off ledge (begin) +anim 2588 - Jump off ledge (end) +anim 2589 - Crawl under wall (a) +anim 2590 - Crawl under wall (b) +anim 2591 - Crawl under wall (c) +anim 2592 - Get stuck Start +anim 2593 - Get stuck +anim 2594 - Balancing ledge disappear (begin) +anim 2595 - Balancing ledge disappear (end) +anim 2607 - look to the side, thrown back and die +anim 2608 - Arm to the side, (looks like you’re cutting your wrist) +anim 2609 - Put arm in front of yourself +anim 2610 - Rub the ground +anim 2612 - Jump back scared +anim 2613 - Pestle and Mortar +anim 2614 - Attack +anim 2616 - Doing an “A-OK†pose? +anim 2617 - Ozan Playing Guitar (DR-2113) (NPC-ID-13962) +anim 2624 - Push something +anim 2625 - Pull something back +anim 2633 - Floating +anim 2637 - Going insane then floating +anim 2638 - Floating +anim 2639 - Being thrown around like a puppet +anim 2644 - Throw something +anim 2645 - Death falling on back +anim 2646 - Death idle on back +anim 2647 - Standing then being pulled up into air +anim 2648 - Ozan Walk Animation (DR-2113) (NPC-ID-13962) +anim 2649 - Ozan Idle Animation (DR-2115) (NPC-ID 13967) +anim 2651 - Floating and almost landing, but floating again +anim 2654 - Jump up and attack, then walk down stairs +anim 2658 - On knees fiddling with something/looking through telescope? +anim 2659 - Get up off knees +anim 2661 - Attack +anim 2664 - Floating +anim 2665 - Fall on knees about to die +anim 2673 - On knees about to die +anim 2692 - Very slowly bending to pick something +anim 2693 - Fall on knees +anim 2694 - On knees +anim 2695 - Clip with shears +anim 2696 - Old Death Emote +anim 2697 - Pick something up +anim 2700 - bending backwards (glitched) +anim 2701 - Old Beckon Emote +anim 2702 - Old Cry Emote +anim 2709 - On knees +anim 2710 - Roll ball/attack? +anim 2712 - Standing +anim 2713 - Stand (below ground) +anim 2716 - Sit down, legs out +anim 2717 - Chisel onyx +anim 2720 - Stick arm up and out +anim 2721 - Commorb Scan +anim 2724 - Get on knees to grovel +anim 2726 - Get on knees to grovel +anim 2727 - Old Teletab Teleport +anim 2728 - Hands out +anim 2735 - Push something +anim 2741 - Attack +anim 2745 - Attack +anim 2749 - Up in air in scarecrow pose +anim 2755 - Disappear +anim 2757 - Appear +anim 2762 - Push Ups from Drill Demon Event +anim 2763 - Sit Ups from Drill Demon Event +anim 2764 - Running in Place from Drill Demon Event +anim 2765 - Stand +anim 2766 - Normal Walk +anim 2769 - Dizzy Walk +anim 2770 - Dizzy +anim 2771 - Pour Bucket +anim 2773 - Normal Run +anim 2779 - Attack +anim 2780 - Play with fishbowl +anim 2781 - Feeding fishbowl +anim 2782 - Nodding at fishbowl +anim 2783 - Play with fishbowl +anim 2784 - Feed pet fish +anim 2785 - Fish bowl +anim 2786 - Fish bowl +anim 2787 - Fish bowl +anim 2788 - Talk to Fish +anim 2789 - Dwarven Army Axe +anim 2790 - Bend on ground +animGFX 2791 2728 - Cast Fire Spell +anim 2793 - Churn butter +anim 2794 - Dwarven army axe +anim 2795 - The Raptor Attack with Flail +anim 2796 - Crawling +anim 2797 - Stand +anim 2798 - Cast Old Home Teleport +anim 2799 - Cast Old Home Teleport +anim 2800 - Cast Old Home Teleport +anim 2810 - Holy Wrench +anim 2811 - Holy Wrench +anim 2813 - Catch Karamthulhu (Pirate Quest) +anim 2815 - Walk (below ground) +anim 2816 - Glitched frame (below ground) +anim 2817 - Slash +anim 2818 - Walking (below ground) +anim 2819 - Flatten disappear (below ground) +anim 2820 - Raptor Attack +anim 2821 - Combo Attack +anim 2822 - Sir Owen Idle? +anim 2828 - Defend +anim 2829 - Floating +anim 2830 - Look around +anim 2831 - Dwarven Army Axe +anim 2832 - Walk +anim 2833 - Dwarven Army Axe +anim 2834 - Idle +anim 2835 - Put hands next to head +anim 2836 - Scared (emote) (e) +anim 2837 - Dwarven Army Axe +anim 2838 - Dwarven Army Axe +anim 2839 - Dwarven Army Axe +anim 2840 - Zombie Head “Alas!†+anim 2844 - Zombie Head +anim 2845 - Take something and look at it? +anim 2846 - Dragon Hatchet +anim 2847 - Iron Hatchet +anim 2875 - Walk +animGFX 2876 479 - Dragon Hatchet Special Attack (c-SA) +anim 2879 - Demonic Sigil (i) (e) (Shadow of the Storm) +anim 2880 - Demonic Sigil (i) (e) (Shadow of the Storm) +anim 2888 - Old Shrink Teleport +animGFX 2890 483 - Darklight Special +anim 2891 - Stick hand out +anim 2902 - Smouldering Pot +anim 2903 - Snake Charm +anim 2909 - Walking, bent back +anim 2910 - Wrangling rope +anim 2911 - Idle +anim 2912 - Walk +anim 2913 - Fix Torn Robe Top (Spirits of The Elid) +anim 2914 - Fix Torn Robe Bottom (Spirits of The Elid) +anim 2920 - On floor listening to music +anim 2921 - Getting up off the floor +anim 2922 - Running Across the Board Obstacle on the Advanced Gnome Agility Course +anim 2923 - Jumping over Barrier Obstacle on the Advanced Gnome Agility Course +anim 2924 - Come out Other End of the Barrier Pipe from Advanced Gnome Course +anim 2925 - Kick +anim 2926 - Shake Snowglobe +anim 2927 - On knees +anim 2928 - Pushed back +anim 2929 - Running Across the Signpost from Advanced Gnome Course +anim 2930 - Silverlight attack? +anim 2934 - Standing +anim 2936 - Use Magnifying Glass Emote +anim 2937 - Throw thing? +anim 2938 - Defend +anim 2939 - Sitting +anim 2940 - Sitting (faced other way) +anim 2944 - Walking +anim 2953 - Put hands in front of face +anim 2967 - Throw thing? +anim 2968 - Throw thing? +anim 2972 - Open thing? +anim 2984 - Holding weapon? +anim 2985 - Standing +anim 2986 - Defend +anim 2987 - Walking +anim 2988 - Bend onto ground +anim 2991 - Pushing Open Count Draynor’s Coffin +anim 2992 - Missing the Stake in Count Draynor +anim 2993 - Idle Holding Crate? +anim 2994 - Walking Holding Crate? +anim 2999 - Mithril 2H Sword +anim 3000 - Standing leaned against wall +anim 3001 - Run with Bolas +anim 3002 - Walk with Bolas +animGFX 3003 507 - Red Marionette Jump +animGFX 3003 511 - Blue Marionette Jump +animGFX 3003 515 - Green Marionette Jump +animGFX 3004 508 - Red Marionette Walk +animGFX 3004 512 - Blue Marionette Walk +animGFX 3004 516 - Green Marionette Walk +animGFX 3005 509 - Red Marionette Bow +animGFX 3005 513 - Blue Marionette Bow +animGFX 3005 517 - Green Marionette Bow +animGFX 3006 510 - Red Marionette Dance +animGFX 3006 514 - Blue Marionette Dance no +animGFX 3006 518 - Green Marionette Dance +anim 3007 - Cutting Hardened Straight Root +anim 3032 - Attack something on table? +anim 3036 - Looking around with hand shielding face from sun (Turned around) +anim 3039 - Drunk Walk While Holding Beer (DR-290) +anim 3040 - Drunk stand While Holding Beer (DR-290) +anim 3041 - Old Shrink Teleport +anim 3042 - Walking holding something +anim 3043 - Holding something idle +anim 3044 - Finish reading scroll +anim 3045 - Attack with dagger? +anim 3053 - Climbing right and hanging (begin) +anim 3054 - Covering head and shaking in fear, as if about to be hit, +anim 3055 - Climbing right and hanging (fail) +anim 3056 - Climbing left and hanging (fail) +anim 3057 - Climbing left and hanging (begin) +anim 3058 - Climbing left and hanging (end) +anim 3059 - Climbing right, moving +anim 3060 - Climbing left, moving +anim 3061 - Scrubbing something on side? +anim 3062 - Scrubbing something on side? +anim 3063 - Climbing Up Something then Climb Down +anim 3064 - Falling and flailing on butt +anim 3067 - Jumping over something +anim 3068 - Jumping over something and failing, then falling +anim 3069 - Falling off beam +anim 3071 - Stick arms out and put them together +anim 3079 - Look down and check wrist held close to body +anim 3080 - Checking wrist held close to body +anim 3081 - Lowering arm as if lowering sword +anim 3082 - lift arm as if holding sword +anim 3083 - Walk looking side to side +anim 3084 - Idle, hold hips and look around +anim 3085 - seated, arms in lap +anim 3086 - looking down, touching head, cape blown back idle +anim 3087 - lift arm up as if holding sword +anim 3090 - raise fists in air +anim 3091 - flap +anim 3094 - lean forward and begin to fall forward (into rabbit hole?) +anim 3097 - walking +anim 3102 - on knees using chisel upward +anim 3103 - on ground, get up, rub wrist +anim 3108 - Count Draynor Knocking you Back +anim 3109 - On Floor After Being Knocked Down +anim 3110 - get up while holding stomach +anim 3113 - take something out of pocket and use/enchant it +anim 3114 - bending down to squat then getting up +anim 3115 - idle +anim 3116 - run +anim 3119 - walk +anim 3128 - throw +anim 3130 - swing across obstacle? +anim 3131 - swing across zipine thing? +anim 3132 - lean forward and hands up grabbing thing +anim 3133 - Canister (Cabin Fever) +anim 3134 - Cannonball (Cabin Fever) +anim 3135 - Grab thing +anim 3136 - Use Ramrod +anim 3137 - hit with repair plank +anim 3140 - Read book +anim 3141 - Turn page in book +anim 3150 - lift hand +anim 3151 - hands out grabbing something (or using furnace) +anim 3153 - Linza Smithing? +anim 3158 - Linza Smithing? +anim 3170 - flicker fade in combat stance +anim 3171 - electrocute +anim 3175 - idle +anim 3176 - defend +anim 3177 - walk +anim 3178 - run +anim 3181 - bend forward, do thing +anim 3182 - bend, do thing +anim 3184 - sit then look to side +anim 3185 - do thing with hands +anim 3186 - bend back and shake thing with hands +anim 3187 - Removing Sewer Grate (Plague City) +anim 3191 - Tie Rope to Sewer Grate (Plague City) +anim 3192 - Attempt to Remove Sewer Grate (Plague City) +anim 3195 - sitting legs crossed with stick +anim 3218 - linza smithing? +anim 3219 - Ancient teleport? +anim 3235 - Wiggle straight jadinko root +anim 3236 - throw attack +anim 3238 - defend +anim 3239 - defend +anim 3240 - Barbarian Defend +anim 3243 - use furnace? +anim 3248 - teleport +animGFX 3254 2670 - Fairy Ring Leave +animGFX 3255 2671 - Fairy Ring Arrive +anim 3256 - one knee forward hand on it, other knee bend backwards, then get up +anim 3257 - idle, lift hands up to cast spell? +anim 3260 - Woodcutting dragon hatchet +anim 3261 - woodcutting rune hatchet +anim 3262 - woodcutting adamant hatchet +anim 3263 - woodcutting mithril hatchet +anim 3265 - stand then ghostly fade +anim 3266 - ghostly appear fade +anim 3269 - idle holding weapon +anim 3270 - walk holding weapon +anim 3271 - sidestep +anim 3272 - sidestep +anim 3274 - finish agility obstacle? +anim 3275 - finish agility obstacle? +anim 3276 - start agility obstacle? +anim 3277 - start agility obstacle? +anim 3278 - start agility obstacle? +anim 3279 - start agility obstacle? +anim 3280 - on knees face down +anim 3281 - lying back reclined idle? +anim 3283 - mix potion on hand +anim 3284 - woodcutting with black hatchet +anim 3292 - woodcutting with steel hatchet +anim 3296 - woodcutting? +anim 3297 - noose wand +anim 3301 - hands forward do something +anim 3303 - climb obstacle +anim 3307 - juju hunter potion +anim 3323 - woodcutting with iron hatchet +anim 3324 - woodcutting with bronze hatchet +anim 3325 - Woodcutting with inferno adze +anim 3326 - Woodcutting with sacred clay hatchet +anim 3327 - Dr. Harlow Hitting his Head with Hand +anim 3334 - Opening Chest +anim 3335 - Closing Chest +anim 3337 - Pruning with Magic Secuatars +anim 3338 - Pruning with Magic Secuatars +anim 3339 - Pruning with Magic Secuatars +anim 3340 - Pruning with Magic Secuatars +anim 3341 - Pruning with Magic Secuatars +anim 3342 - Pruning with Magic Secuatars +anim 3345 - Grab thing? +anim 3348 - Brulee +anim 3353 - Do thing with hands? +anim 3361 - Seated shrug clap +anim 3362 - Frozen seated arms shrug +anim 3364 - Jump out of ground into air in t pose with one knee bent +anim 3365 - In air in t pose 1 knee bent +anim 3366 - land on ground +anim 3367 - seated getting up jump stuck in air +anim 3370 - Get out of seated place hands on hip +anim 3371 - Freeze frame hand on hip +anim 3373 - seated, collapse on chair +anim 3374 - seated, collapse on chair +anim 3377 - climb up over thing +anim 3378 - climb up onto thing +anim 3381 - climb up onto thing +anim 3382 - climb up over thing jump down +anim 3386 - climb, jump to next thing, climb more +anim 3389 - climb over thing, jump down +anim 3393 - punch climb thing +anim 3394 - Woodcutting sacred clay hatchet +anim 3396 - seated +anim 3399 - Touching Dwarven Rock Cake, it’s so hot to handle +anim 3414 - Climb into Vine (Jadinko Habitat) +anim 3415 - Swimming underwater Diving +anim 3416 - Land from swimming +anim 3417 - Float back up swimming diving +anim 3418 - Swimming underwater +anim 3419 - float up swimming underwater +anim 3420 - grab underwater rock (RFD) +anim 3421 - Ascend from swimming underwater +anim 3422 - Descend swimming under water +anim 3423 - Jump +anim 3439 - Lunar teleport squeezing +anim 3450 - Squat, get up, do brag poses? +anim 3451 - Squat, get up do bragging strongman poses +anim 3452 - Squat, get up, do brag poses? +anim 3461 - Idle holding heavy weapon +anim 3463 - Climb up thing +anim 3464 - Climb down thing +anim 3465 - Climb under obstacle +anim 3466 - Climb under obstacle +anim 3471 - step back swirl crank? +anim 3475 - Teleport +anim 3480 - Lunar Floating +anim 3482 - Sad Lunar Floating +anim 3526 - Teleport +anim 3527 - Jump into hole (Jadino Habitat) +anim 3533 - Begin to climb Vine (Jadinko Habitat) +anim 3536 - Hardened straight root +anim 3543 - Zombie Dance (emote) (e) +anim 3544 - Zombie Walk (emote) (e) +anim 3547 - twirling +anim 3550 - twitching +anim 3551 - flailing as if arms been grabbed +anim 3552 - stop flailing +anim 3553 - lift hand up +anim 3554 - NPC teleport +anim 3555 - Teleport +anim 3557 - idle +anim 3563 - fall over into push up pose +anim 3564 - use empty pot +animGFX 3566 609 - Silvthril Rod Enchant +anim 3572 - touch thing +anim 3589 - limping hurt walk +anim 3592 - get up from underground +anim 3593 - idle hands to side holding thing +anim 3594 - standing up holding thing +anim 3595 - attack standing above ground +anim 3596 - defend standing above ground +anim 3597 - fall down on butt, legs out +anim 3598 - standing up, jumping +anim 3599 - climbing up on +anim 3600 - standing up +anim 3602 - hoop +anim 3603 - hand out +anim 3605 - defend/idle +anim 3606 - walk holding thing +anim 3607 - Will (Lumberyard Worker) +anim 3610 - Lunar floating spell attack +anim 3611 - Pull Lever (PoH) +anim 3614 - Lunar floating attack +anim 3622 - Grab and holding onto something big? +anim 3623 - Let go of something big? +anim 3624 - Climb past obstacle (GWD Rock?) +anim 3625 - Kettle +anim 3626 - Spell/defend? +anim 3627 - Jump something +anim 3630 - MWAH hands up then cry +anim 3634 - Hands out wide shrug +anim 3635 - Jittery laugh +anim 3636 - Jittery laugh loop +anim 3639 - Walk and then fall on butt and get up +anim 3640 - Fall down from sky on butt +anim 3641 - Fall down from sky into water +anim 3645 - Hands up then together +anim 3649 - Telescope (PoH) +anim 3651 - Lunar floating attack +anim 3652 - Read Lectern (PoH) +anim 3653 - Thinking hmmm +anim 3654 - Churn? (Pluming stand?) +anim 3655 - Red Paintbrush +anim 3657 - Rusty sword +anim 3658 - Tinderbox +anim 3659 - Using object in Poh*? +anim 3660 - Filling beer glass from tap +anim 3661 - Filling beer mug from tap +anim 3662 - Filling Asgarnian Ale +anim 3663 - Filling Greenman's ale +anim 3664 - Filling Dragon’s Bitter +anim 3665 - Filling Moonlight Mead +anim 3666 - Filling Cider +anim 3667 - Take something drunk? +anim 3668 - Take something drunk? +animGFX 3669 530 - Sir Owen Teleports Away +anim 3670 - Preen option to check self in mirror (PoH) +anim 3671 - Lunar Sad Floating Down +anim 3672 - Lunar Sad Floating Up +anim 3674 - Play Instrument in Chapel (PoH) +anim 3675 - Play Bells in Chapel (PoH) +anim 3676 - Build with hammer +anim 3677 - Boxing Stance (PoH) (DR-1386) +anim 3678 - Boxing Punch +anim 3679 - Boxing Defend +anim 3680 - Boxing Walk (DR-1386) +anim 3683 - Hit floor with hammer +anim 3684 - Build with hammer fast +anim 3685 - Remove Furniture (PoH) +anim 3686 - Sit in chair and raise fist +anim 3687 - Use tinderbox +anim 3688 - Jump over boxing ring fence +anim 3689 - Jump over boxing ring fence with red gloves +anim 3690 - Jump over boxing ring fence with blue gloves +animGFX 3691 531 - Lunar Teleport +anim 3692 - Trying to open lock? +anim 3693 - Trying to open lock by banging fist? +anim 3694 - Swimming, trying to open lock +anim 3695 - Swimming, trying to open lock by banging +anim 3696 - Get on knees and lift hands up, (emote ends short) +anim 3697 - One frame of standing +anim 3702 - Drinking tea from yellow cup +anim 3703 - Drinking tea from white cup +anim 3704 - Drinking tea from Porcelain cup +anim 3705 - Making tele tab? +anim 3715 - Getting seated in citadel chair +anim 3719 - Sitting in seat sideways +anim 3725 - Lifting GWD Rock +anim 3734 - Poking swamp with branch (Temple Trekking) +anim 3735 - Falling into swamp +anim 3739 - Wrangling rope (Temple Trekking) +anim 3740 - Checking rope (Temple Trekking) +anim 3741 - Cutting tree branches temple trekking? +anim 3745 - Pulling rope thing? +anim 3747 - Cut with knife +animGFX 3804 630 - Get Angry In Tolna’s Rift +anim 3807 - Tolna Awakens From Nightmare +anim 3838 - Crawl Into Tolna’s Rift +anim 3844 - Side Step to Crawl Through McGrubor’s Woods Fence +anim 3845 - Fiddling with thing sideways, slightly below ground +anim 3846 - Holding swamp lizard? (Frozen frame) +anim 3855 - Turning into bunny? (Easter) +anim 3857 - Growing from being small/tiny +anim 3859 - Chicken Suit Flap (emote) (e) +anim 3860 - Roll Blue easter egg +anim 3861 - Roll Yellow easter egg +anim 3862 - Roll Green easter egg +anim 3863 - Roll Red easter egg +anim 3864 - Take item from table +anim 3865 - Running wide holding something +anim 3866 - Standing shaking head holding something idle +anim 3868 - Walking holding something +anim 3869 - Running holding something? +anim 3870 - Attack +anim 3873 - Attack then cheer? +anim 3875 - Defend? +anim 3876 - Attack? +anim 3877 - Hit with hammer +anim 3896 - Sidestep +anim 3900 - Sidestep +anim 3923 - Hit with sacred clay hammer +anim 3931 - hit with hammer +anim 3934 - Climb Up Obstacle (Clan Battlefield) +anim 3940 - Attack +anim 3943 - Smithing with Volatile Clay Hammer +anim 3945 - Climb Down Obstacle (Clan Battlefield) +anim 3950 - Milkmaid Idle? +anim 3970 - One frame dead +anim 3971 - Hitting with hammer up high and down low +anim 3972 - Trying to lift open something on ground (like a grate?) +anim 3973 - Doing something on ground (like washing laundry?) +anim 3979 - Clan Battlefield Frame Bar Obstacle (A) +anim 3980 - Clan Battlefield Frame Bar Obstacle (B) +anim 3981 - Clan Battlefield Frame Swing Obstacle (A) +anim 3982 - Clan Battlefield Frame Swing Obstacle (B) +anim 3985 - Slipping backwards +anim 3986 - Smash wall with elbow? +anim 3988 - Big Kick +anim 3996 - Standing +anim 3997 - Milkmaid walk? +anim 3999 - Evil Twin being held by claw? +animGFX 4001 666 - Claw Picks You Up (Old Random Event) +animGFX 4003 667 - Claw Drops You +anim 4004 - move forward to grab? +anim 4008 - hit with Dragon hatchet +anim 4011 - hit with Rune Hatchet +anim 4012 - Hit with Adamant Hatchet +anim 4017 - Hit with Mithril hatchet +anim 4018 - Restless Ghost Ascends +anim 4019 - Restless Ghost Awakens +anim 4023 - Rise up from below ground +anim 4024 - Sink below ground +anim 4028 - Look down, cape goes up +anim 4029 - Trying to run on treadmill but fall down? +anim 4030 - Hit with golden hammer +anim 4031 - Hit with Steel Hatchet +anim 4036 - Hit with Iron Hatchet +anim 4043 - Staff of Air +anim 4044 - Staff of Air +anim 4045 - Staff of Earth +anim 4046 - Staff of Earth +anim 4047 - Staff of Water +anim 4048 - Staff of Water +anim 4049 - Staff of Fire +anim 4050 - Staff of FIre +anim 4051 - Air Battlestaff +anim 4052 - Air Battlestaff +anim 4053 - Earth Battlestaff +anim 4054 - Earth Battlestaff +anim 4055 - Water Battlestaff +anim 4056 - Water Battlestaff +anim 4057 - Fire Battlestaff +anim 4058 - Fire Battlestaff +anim 4059 - Mystic Air Staff +anim 4060 - Mystic Air Staff +anim 4061 - Mystic Earth Staff +anim 4062 - Mystic Earth Staff +anim 4063 - Mystic Water Staff +anim 4064 - Mystic Water Staff +anim 4065 - Mystic Fire Staff +anim 4066 - Mystic Fire Staff +anim 4067 - Investigate Ancient Effigy Without Proper Skills +anim 4068 - Investigate Ancient Effigy +anim 4069 - Break Spell Tablet (a) +anim 4070 - Break Spell Tablet (b) +anim 4071 - Teletab +anim 4073 - Sitting in crude chair +anim 4074 - Sitting in crude chair +anim 4075 - Sitting in chair +anim 4076 - Sitting in chair +anim 4077 - Hit with Bronze hatchet +anim 4078 - Hit with Sacred clay hatchet +anim 4079 - Rocking chair +anim 4080 - Rocking chair +anim 4081 - Oak chair +anim 4082 - Oak chair +anim 4083 - Oak chair +anim 4084 - Oak chair +anim 4085 - Teak Chair +anim 4086 - Teak Chair +anim 4087 - Mahogany Chair +anim 4088 - Mahogany chair +anim 4089 - Bench +anim 4090 - Shake fist sitting on bench +anim 4091 - Oak bench +anim 4092 - Shake fist sitting on oak bench +anim 4093 - Sit on Carved Oak Bench +anim 4094 - Shake fist sitting on Carved Oak Bench +anim 4095 - Sitting on Teak Bench +anim 4096 - Shake fist sitting on Teak Bench +anim 4097 - Sitting on Carved Teak Bench +anim 4098 - Shake fist sitting on Carved Teak Bench +anim 4099 - Sitting on Mahogany Bench +anim 4100 - Shake fist sitting on Mahogany Bench +anim 4101 - SItting on Gilded Mahogany Bench +anim 4102 - Shake Fist Sitting on Gilded Mahogany Bench +anim 4103 - Sitting Down on PoH Workbench +anim 4104 - Sitting down? +anim 4105 - Getting out of seat +anim 4106 - Sitting down? +anim 4107 - Sitting at PoH workbench +anim 4108 - Sitting at PoH Workbench Oak Stool +anim 4109 - Crafting at PoH Workbench +anim 4110 - Crafting at PoH Workbench Oak Stool +anim 4111 - Sitting in Throne +anim 4112 - Sitting in Throne (B) +anim 4113 - Sitting in Throne (C) +anim 4114 - SItting in Throne (D) +anim 4115 - Sitting in Skeleton Throne +anim 4116 - Sitting in Crystal Throne +anim 4117 - Sitting in Demonic Throne +anim 4136 - Pouch Repair? +anim 4137 - Hit with Volatile Clay Hatchet +anim 4141 - Shake fist in crude chair +anim 4142 - Shake fist in crude chair (angle) +anim 4143 - Shake fist in chair +anim 4144 - Shake fist in chair (angle) +anim 4145 - Shake fist in rocking chair +anim 4146 - Shake fist in rocking chair (angle) +anim 4147 - Shake fist in oak chair +anim 4148 - Shake fist in oak chair (angle) +anim 4149 - Shake fist in nice oak chair +anim 4150 - Shake fist in nice oak chair (angle) +anim 4151 - Shake fist in teak chair +anim 4152 - Shake fist in teak chair (angle) +anim 4153 - Shake fist in mahogany chair +anim 4154 - Shake fist in mahogany chair (angle) +anim 4158 - Thinking leaning forward +anim 4159 - Sitting sideways +anim 4160 - Sitting sideways, looking head right and left +anim 4162 - Sitting sideways, lifting hand +anim 4166 - Dead face down, then getting up +anim 4167 - Dying (pretend) +anim 4168 - Move head to listen on door? +anim 4169 - bend down on knees, hand in front of face +anim 4170 - Stretching, knee forward +anim 4171 - Covering head with hands +anim 4172 - Fall back on butt +anim 4173 - Fall down on back, knees bent +anim 4174 - Bending/bowing in pain? +anim 4175 - Bending on knees in pain? +anim 4176 - Hitting ground with sacred clay hammer +anim 4177 - Fist out punch? +anim 4178 - Walking drunk +anim 4179 - Drunk idle +anim 4180 - Slowly bending on knees arms flap +anim 4181 - hit with Dragon Pickaxe +anim 4182 - Hit with rune pickaxe +anim 4183 - hit with adamant pickaxe +anim 4184 - Bend and cover face with hands +anim 4185 - Pulling rope? +anim 4188 - Trying to open door with elbows? +anim 4189 - Fire Spring Device (Barbarian Advanced) +anim 4190 - Hammering (Repairing Fence Dwarf Cannon Quest) +anim 4191 - Get Up From Being Face Down on Floor (Dragon Slayer) +anim 4192 - Duck under obstacle to cross? +anim 4193 - Holding crate +anim 4194 - Walking with crate +anim 4195 - On ground listening to door? +anim 4197 - Get up from listening to door? +anim 4199 - Fire crossbow +anim 4200 - Death +anim 4208 - Idle holding? +anim 4209 - Thing holding? +anim 4223 - Spider climb on ceiling? +anim 4226 - Walk +anim 4227 - Walk backwards +anim 4228 - Run +anim 4230 - Fire crossbow +anim 4238 - Touch something +anim 4243 - Hit with Mithril Pickaxe +anim 4250 - Pull lever? +anim 4254 - Pull something (loop) +anim 4255 - Use bucket +anim 4256 - Walk shaking head +anim 4257 - Idle +anim 4258 - Poke with torch +anim 4275 - Slap Head (emote) (e) +animGFX 4276 712 - Idea (emote) (e) +animGFX 4278 713 - Stomp (emote) (e) +anim 4280 - Flap (emote) (e) +anim 4285 - Wizard Mizgog Collects Beads (Imp Catcher) +anim 4292 - Teleport Impious Urn +anim 4293 - Stand arms like chicken then do stretches and thing (idle?) +anim 4316 - Grab something off ground? +anim 4321 - hit with steel pickaxe +anim 4326 - Balance +anim 4327 - Balance walk +anim 4329 - hit with iron pickaxe +anim 4330 - hit with bronze pickaxe +anim 4340 - bend to get something (lift leg up) +anim 4341 - Jump up and hit +anim 4342 - bend forward, then lift hand up in victory +anim 4343 - Mining Strike Gilded Dragon Pickaxe +anim 4344 - Pushing +anim 4345 - Pushing +anim 4348 - Combining Dye Colors +anim 4349 - Combining Dye Colors +anim 4350 - Combining Dye Colors +anim 4352 - Aggie Mixing Dye in Cauldron +anim 4362 - Mining Strike Gilded Rune Pickaxe +anim 4365 - Float thrown up in air +anim 4366 - Fall down in floor +anim 4367 - Fall down face down +anim 4368 - Emerald Lantern +anim 4369 - Using Emerald Lantern (Lunar Diplomacy) +anim 4370 - Mining Strike Gilded Adamant Pickaxe +anim 4371 - Lunar Floating Watering Plants +anim 4373 - Mining Strike Gilded Mithril Pickaxe +anim 4376 - Mining Strike Gilded Steel Pickaxe +anim 4378 - Mining Strike Gilded Iron Pickaxe +anim 4379 - Mining Strike Gilded Bronze Pickaxe +anim 4380 - Jump up float over obstacle +anim 4381 - Jump up over obstacle but get electrocuted +anim 4382 - Lunar Diplomacy Electrocute +anim 4400 - Mining Strike Sacred Clay Pickaxe +anim 4401 - Mining Strike Volatile Clay Pickaxe +anim 4402 - Mining Strike Inferno Adze +anim 4405 - Mining Strike Dwarven Army Axe +anim 4406 - Hit with Dramen Staff +anim 4409 - Heal Group +animGFX 4410 726 - Vengeance Self +anim 4411 - Vengeance Other +anim 4412 - Superglass Make +anim 4413 - Fertile Soil +anim 4424 - Lunar Floating +anim 4426 - Lunar Floating +anim 4427 - Lunar Floating +anim 4428 - Lunar Floating +anim 4429 - Lunar Floating +anim 4430 - Panic +anim 4432 - Cure Plant +anim 4433 - Fletch Logs +anim 4434 - Banshee without earmuffs? +anim 4435 - Scaling Cliff Wall +anim 4436 - Bronze Crossbow Limbs +anim 4437 - Blurite Crossbow limbs +anim 4438 - Iron Crossbow Limbs +anim 4439 - Steel Crossbow Limbs +anim 4440 - Mithril Crossbow Limbs +anim 4441 - Adamant Crossbow Limbs +anim 4442 - Rune Crossbow Limbs +animGFX 4454 761 - Ardougne Cloak Farm Teleport (leave) +anim 4455 - Fire Steel Crossbow to Climb Wall +anim 4460 - Fire Crossbow +anim 4462 - Craft and enchant a thing? +anim 4464 - Pull self through water +anim 4465 - Pull self through water +anim 4466 - Pull self through water +anim 4467 - Pull self through water +anim 4468 - Pull self through water +anim 4470 - Chisel Oyster Pearl +anim 4471 - Fill bucket +anim 4479 - Low Alch on Chair +anim 4480 - High Alch on Chair +anim 4481 - Low Alch on Chair (angle) +anim 4482 - High Alch on Chair (angle) +anim 4483 - Low Alch on Chair +anim 4484 - High Alch on Chair +anim 4485 - Low Alch on Chair (angle) +anim 4486 - High Alch on Chair (angle) +anim 4487 - Low Alch on Chair +anim 4488 - High Alch on Chair +anim 4489 - Low Alch on Chair (angle) +anim 4490 - High Alch on Chair (angle) +anim 4491 - Low Alch on Oak Chair +anim 4492 - High Alch on Oak Chair +anim 4493 - Low Alch on Oak Chair (angle) +anim 4494 - High Alch on Oak Chair (angle) +anim 4495 - Low Alch on Oak Chair +anim 4496 - High Alch on Oak Chair +anim 4497 - Low Alch on Oak Chair (angle) +anim 4498 - High Alch on Oak Chair (angle) +anim 4499 - Low Alch on Teak Chair +anim 4500 - High Alch on Teak Chair +anim 4501 - Low Alch on Teak Chair (angle) +anim 4502 - High Alch on Teak Chair (angle) +anim 4503 - Alch Workbench Stool +anim 4504 - Alch on Teak Chair +anim 4505 - Alch on Teak Chair (Angle) +anim 4506 - Alch on Teak Chair (Angle) +anim 4507 - Alch on Bench +anim 4508 - Alch on Bench +anim 4509 - Alch on Bench +anim 4510 - Alch on Bench +anim 4511 - Alch on Bench +anim 4512 - Alch on Bench +anim 4513 - Alch on Bench +anim 4514 - Alch on Bench +anim 4515 - Alch on Bench +anim 4516 - Alch on Bench +anim 4517 - Alch on Bench +anim 4518 - Alch on Bench +anim 4519 - Alch on Bench +anim 4520 - Alch on Bench +anim 4521 - Alch in throne +anim 4522 - Alch in throne +anim 4523 - Alch in throne +anim 4524 - Alch in throne +anim 4525 - Alch in throne +anim 4526 - Alch in throne +anim 4527 - Alch in throne +anim 4528 - Alch in throne +anim 4529 - Low Alch in Skeleton throne +anim 4530 - High Alch in Skeleton Throne +anim 4531 - Low Alch in Crystal Throne +anim 4532 - High Alch in Crystal throne +anim 4533 - Low Alch in Demonic Throne +anim 4534 - High Alch in Demonic Throne +anim 4540 - Take thing out of pocket and give it +anim 4541 - Teleport Accursed Urn +anim 4542 - Teleport Infernal Urn +anim 4544 - Look down then get tense/agitated +anim 4546 - Tense/agitated +anim 4547 - Use Grand Seed Pod +anim 4549 - Read note while shaking head +anim 4551 - Burn note +anim 4552 - Crouched hiding position +anim 4553 - Put hand out +anim 4558 - Swirl Crystal Bowl? +anim 4567 - Put rune on Impious Urn +anim 4569 - Put rune on Accursed urn +anim 4578 - Put rune on Infernal prayer urn +anim 4580 - Teleport Cracked Smelting Urn +anim 4581 - Bend forward touch +anim 4586 - Hazelmere Memory Meld? +anim 4591 - Idle +anim 4592 - Hit floor with rock pick +anim 4593 - Panning tray +anim 4594 - Look at tray river +anim 4597 - Lift Open Varrock Sewer Manhole +anim 4602 - Lift big thing, cast epll with it? +anim 4603 - Three combo attack +anim 4611 - Grab take thing with left hand +anim 4612 - Look down to the left +anim 4613 - Look back forward +anim 4614 - Look down to the right +anim 4615 - Look back forward +anim 4617 - Cast praying spell thing +anim 4622 - Ozan idle? +anim 4634 - Sideways take thing +anim 4636 - Sideways arm out (border guard?) +anim 4640 - Sideways move are back (border guard?) +anim 4641 - Idle like thing? +anim 4643 - Old home teleport read book +anim 4644 - Seated +anim 4645 - Old home teleport piece +anim 4646 - Old home teleport piece +anim 4647 - Get out of seat +anim 4648 - Idle +anim 4709 - Weak attack/woodcutting? +anim 4712 - Huddling in fetal position +anim 4713 - Look up to the sky with hand shield eyes +anim 4718 - Jump up and fall onto back (a bit blocky) +anim 4719 - On back, getting up (a bit blocky) +anim 4721 - Jump obstacle +anim 4722 - Jump up and climb thing +anim 4723 - Climb thing, turn to look back +anim 4724 - Bend backwards and jump obstacle? +anim 4725 - Look up, then look down and do “motorboat†with face? +anim 4727 - Climb two things +anim 4728 - Jump obstacle and slide down +anim 4731 - Teletab teleport? +anim 4733 - Teleport? +anim 4750 - Stamp twice (with cracking/breaking sound effect) +anim 4757 - Use hammer to repair thing? +anim 4760 - Mining with rune pickaxe +anim 4761 - Mining with bronze pickaxe +anim 4762 - Mining with iron pickaxe +anim 4763 - Mining with steel pickaxe +anim 4764 - Mining with adamant pickaxe +anim 4765 - Mining with mithril pickaxe +anim 4766 - Mining with dragon pickaxe +anim 4771 - Getting slightly irritated +anim 4772 - walking balancing +anim 4779 - walking dizzy/drunk +anim 4780 - stand moving leg back and forth on ground (slightly below ground) +anim 4785 - Climb up ladder but fail and fall down +anim 4786 - On knees looking/stretching, then turn around +anim 4787 - bend onto knees +anim 4788 - On one knee (turned around) +anim 4790 - On one knee, get up +anim 4791 - Holding unlit torch, looking side to side +anim 4793 - Poke ground with torch +anim 4794 - Using volatile clay hammer +anim 4795 - bend slightly forward and look around +anim 4797 - fiddle with door like thing? +anim 4804 - kick +anim 4807 - lift hand up then throw something on ground and step on it +anim 4809 - take something and put it on ground, then turn wheel, then pick it off ground +anim 4823 - Hands on ears like doing telekinetic attack, bending forward +anim 4824 - walking with slight limp +anim 4825 - looking up slightly dizzy/drunk +anim 4826 - hurt knee +anim 4834 - take thing out of pocket and use it with something in front of you +anim 4835 - step back startled +anim 4838 - hammer floor with volatile clay hammer +anim 4839 - Commorb v2 Scan +anim 4841 - Look behind you, jump up and spin +anim 4847 - sitting on floor +anim 4848 - sitting on floor +anim 4849 - Sitting legs pretzel +anim 4850 - Sitting legs pretzel +anim 4851 - sit on floor disappearing (A) +anim 4852 - sit on floor disappearing (B) +anim 4853 - Crawl over Low Wall +anim 4855 - Go into Obstacle Pipe +anim 4857 - idle +anim 4858 - walk +anim 4859 - idle, with glassblowing? +anim 4861 - Turn Water Wheel (Elemental Workshop) +anim 4862 - Using a Stone Bowl With Lava Trough (Elemental Workshop) +anim 4863 - Fixing Bellows With Needle (Elemental Workshop) +anim 4873 - take thing +anim 4874 - throw flare (Castle Wars?) +animGFX 4884 807 - Using Extractor Hat Chair (Elemental Workshop II) (GFX on delay) +animGFX 4885 808 - Improperly Using Extractor Hat Electric Chair (Elemental Workshop II) +anim 4905 - Pull Corkscrew Lever (Elemental Workshop II) +anim 4909 - Pull Lever (Elemental Workshop II) +animGFX 4937 812 - Fletching Cape Emote +animGFX 4939 813 - Magic Cape Emote +animGFX 4941 814 - Mining Cape Emote +animGFX 4943 815 - Smithing Cape Emote +animGFX 4945 816 - Quest Cape Emote +animGFX 4947 817 - RuneCrafting Cape Emote +animGFX 4949 818 - Crafting Cape Emote +animGFX 4951 819 - Fishing Cape Emote +animGFX 4953 820 - Construction Cape Emote +animGFX 4955 821 - Cooking Cape Emote +animGFX 4957 822 - Woodcutting Cape Emote +animGFX 4959 823 - Attack Cape Emote +animGFX 4961 824 - Defence Cape Emote +animGFX 4963 825 - Farming Cape Emote +animGFX 4965 826 - Thieving Cape Emote +animGFX 4967 1656 - Slayer Cape Emote +animGFX 4969 835 - Herblore Cape Emote +animGFX 4973 832 - Ranged Cape Emote +animGFX 4975 831 - Firemaking Cape Emote +animGFX 4977 830 - Agility Cape Emote +animGFX 4979 829 - Prayer Cape Emote +animGFX 4981 828 - Strength Cape Emote +anim 5006 - Place object on table? +anim 5015 - Move forward and do thing with wall up and down +anim 5037 - Try to pull open door? +anim 5038 - Climb over thing +anim 5039 - Jump on hang things and climb up +anim 5040 - Climb down +anim 5043 - Jump on hanging over thing +anim 5046 - Jump obstacle, hurt leg +anim 5047 - Jump on obstacle, but lose balance and fall back +anim 5048 - Try to jump but hit head? +anim 5049 - Jump +anim 5050 - Holding barrel +anim 5052 - Put +anim 5054 - Untying thing? +anim 5056 - On back, get up, brush self +anim 5059 - Reindeer Hat emote? +anim 5063 - Throw Snowball +anim 5067 - Create snowball +anim 5074 - Agile Pickpocket +anim 5075 - Agile Pickpocket +anim 5078 - Agile Pickpocket +anim 5080 - Catch Barehanded Butterfly and Release +anim 5083 - Try to catch Barehanded Butterfly +anim 5088 - Writing/crafting thing? +anim 5108 - Fishing with barb tail harpoon +anim 5140 - Crafting Bongos (Cold War) +anim 5142 - Letting Origami Balloon Fly +anim 5146 - Cheering with one fist? +anim 5147 - Cheering with one fist? +anim 5148 - Cheering with one fist? +anim 5149 - Angry mob? +anim 5150 - Angry mob walk? +anim 5151 - Angry mob walk? +anim 5152 - Angry mob walk? +anim 5153 - Angry mob walk? +anim 5155 - Using sandbag (Enlightened Journey) +animGFX 5158 907 - Hunter Cape Emote +anim 5160 - Idle +anim 5161 - Walk +anim 5162 - Attack? +anim 5163 - Defend +anim 5164 - Walk +anim 5165 - Walk backwards +anim 5166 - Sidestep +anim 5167 - Sidestep +anim 5168 - Running +anim 5206 - Step back +anim 5207 - Step forward and do thing +anim 5208 - Set up hunter trap +anim 5210 - Wrangling Eagle with Rope +anim 5211 - Flying Behind Eagle (Cutscene) +anim 5212 - Dismantle hunter trap +anim 5213 - Release butterfly from jar +anim 5215 - Setting up net trap? +anim 5216 - Inspect Burrow +anim 5236 - Poke with teasing stick +anim 5243 - Craft with needle +anim 5244 - Craft with knife +anim 5245 - Walk holding salamander? +anim 5246 - Idle holding salamander +anim 5247 - Attack with salamander +anim 5249 - Mix with mortar and pestle +anim 5250 - Walk +anim 5251 - walk backwards +anim 5252 - walk +anim 5253 - run +anim 5254 - Idle +anim 5255 - Use noose wand +anim 5256 - Catch Polar Kebbit with Noose Wand +anim 5257 - Catch Kebbit with Noose Wand +anim 5258 - Catch Kebbit with Noose Wand +anim 5259 - Catch Kebbit with Noose Wand +anim 5293 - Walk backwards then fall +anim 5298 - Fall onto butt and get up +anim 5299 - Fall onto butt and get up +anim 5311 - Walk pushing something forward +anim 5312 - Pantaloons Bow (emote) (e) +animGFX 5313 967 - Sleeping Cap Yawn (emote) (e) +anim 5315 - Powdered Wig Angry (emote) (e) +anim 5316 - Flared Trousers Dance (emote) (e) +anim 5349 - Barbed Kebbit Noose wand +anim 5352 - Climb jump up +anim 5354 - Reading scroll (displaced) (Watch Tower) +anim 5355 - Jump obstacle +anim 5361 - Pouring Magic Ogre Potion (Watch Tower) +anim 5362 - Get up off knees +anim 5363 - Holding Undead Chicken +anim 5364 - Walking with Undead Chicken +anim 5365 - Making Iron Magnet (Animal Magnetism) +anim 5366 - Blessed Mithril Hatchet Bounces Off Draynor Manor Tree (Animal Magnetism) +anim 5367 - Adamant Hatchet Bounces Off Draynor Manor Tree +anim 5368 - Rune Hatchet Bounces Off Draynor Manor Tree +anim 5369 - Dragon Hatchet Bounces Off Draynor Manor Tree +anim 5370 - Alice’s Husband Idle +anim 5371 - Alice’s Husband Idle (Chasing Chicken) +anim 5372 - Alice’s Husband Walk (Chasing Chicken) +anim 5373 - Alice’s Husband Walk +animGFX 5376 973 - Alice’s Husband Catches Chicken +anim 5377 - Alice’s Husband Tries to Catch Chicken (Animal Magnetism) +anim 5378 - Alice’s Husband Tries to Catch Chicken (Animal Magnetism) +anim 5383 - Blessed Mithril Hatchet +anim 5384 - Blessed Mithril Hatchet +anim 5400 - Filling Healing Vial (Barbarian Assault) +anim 5407 - Pick stuff off ground +anim 5416 - Hammer ground +anim 5417 - Hammer medium height +anim 5418 - Kick, smash attack, smash attack kick +anim 5419 - Take thing, bend down, use it +anim 5428 - Push thing downwards +anim 5429 - Idle +anim 5436 - Listen/hold on to thing? +anim 5438 - Walk with chicken bag +anim 5439 - hit with chicken bag +anim 5441 - defend +anim 5474 - bend forward touch knees +anim 5562 - Clan Citadel Loom +anim 5602 - walk +anim 5606 - walk dejected (below ground) +anim 5607 - stand dejected/scratch head (below ground) +anim 5608 - bend backwards, then throw something or hit? +anim 5609 - Lift hands up +anim 5611 - Tarn grow big to turn into monster? +anim 5620 - appear on knees, cock head, and get it +animGFX 5633 1006 - Zaff Saves the King (What Lies Below) +anim 5637 - Lift hands up (enchant salve amulet e?) +anim 5713 - Sit down into resting legs crossed pretzel +animGFX 5714 1015 - Shrunk into Penguin Suit +animGFX 5716 1016 - Exit Penguin Suit +anim 5718 - Scared +anim 5732 - Sitting/resting knees crossed pretzel +anim 5739 - Walking +anim 5746 - Building Hide-Out (Cold War) +anim 5748 - Get up from resting knees crossed +anim 5749 - seated, looking sideways +anim 5752 - one frame sitting down legs out +anim 5754 - Hammer thing in hand +anim 5756 - cut thing with knife in hand +animGFX 5759 1020 - Juggling (Fremennik Isles) +anim 5760 - Dance a jolly jig +anim 5761 - Skipping +anim 5762 - Jester Staff +anim 5763 - Pie self in face +anim 5776 - bend down on ground +anim 5777 - Troll king head? +anim 5778 - Troll king head? +anim 5783 - Cast spell and throw it +anim 5796 - Drink water from fountain? (Sorcerer’s Garden) +anim 5798 - Collapse and die +anim 5799 - Walk holding broom? +anim 5800 - Clan Citadel Obelisk? (this animation keeps showing up everywhere) +anim 5805 - Defend +anim 5812 - Attack with severed leg (Shadow of Khazard) +anim 5814 - ‘Bonafide’ Resting on ground (Tower of Life) +anim 5815 - ‘No Fingers’ Leaning against building (Tower of Life) +anim 5816 - ‘Gummy’ Paddycake (Tower of Life) +anim 5817 - ‘Black Eye’ Paddycake (Tower of Life) +anim 5818 - ‘The Guns’ Military Press with Log (Tower of Life) +anim 5819 - Hands drooping doing thing +anim 5822 - Walk +anim 5823 - Stamp, scratch head +anim 5827 - Tea Flask (Tower of Life) +anim 5836 - Stand with back leaning backwards +anim 5845 - Builder Outfit Beckon (Tower of Life) +anim 5846 - Building (Tower of Life) +anim 5860 - Trying to pull something (statue?) that is really heavy +anim 5862 - Choking on Toxic Gas and Collapse (Great Brain Robbery) +anim 5863 - Blowing Wolf Whistle (i) (Great Brain Robbery) +anim 5864 - Saradomin Prayer Book Cure Poison (i) (e) (Great Brain Robbery) +anim 5865 - Swinging Barrelchest Anchor +anim 5866 - Defend with anchor +anim 5867 - walk with anchor +anim 5868 - Running with anchor +anim 5869 - Idle holding anchor +animGFX 5870 1027 - Barrelchest Anchor Special Attack (c-SA) +anim 5907 - Hammering +anim 5968 - Walking slowly dejectedly +animGFX 6064 1034 - Moving Over Distance Sphere Goblin Teleport +anim 6067 - Swing with crossbow (Bandos Throne Room?) +anim 6068 - Use Crossbow to cross obstacle +anim 6075 - Shaking thing in hand +anim 6076 - Walking holding thing +anim 6083 - Ring Molanisk Slayer Bell +anim 6085 - Swing with opal machete +anim 6086 - Swing with Jade Machete +anim 6087 - Swing with Red Topaz Machete +anim 6095 - Stab attack +animGFX 6096 1037 H5 - Surok Destroys Letter (What Lies Below) +anim 6098 - Surok is Defeated +animGFX 6099 1008 H30 - Evil King Roald is Defeated +anim 6100 - Evil King Roald Defend +anim 6101 - Evil King Roald Attack +anim 6102 - Excavating Saradomin Statue (What Lies Below) +anim 6103 - bend on ground, arms out +animGFX 6104 1038 - Enchant Runecrafting Wand (What Lies Below) +anim 6106 - Sitting (rotates sideway) +anim 6109 - Look behind you twice then sit down +anim 6111 - Bunny Hop (emote) (e) +anim 6112 - limp walk +anim 6113 - limp idle +anim 6122 - Scratch head as if itchy +anim 6124 - Fall off bridge (Olaf’s Quest?) +anim 6128 - Attack +anim 6129 - Defend +anim 6130 - Slide thing with hands (like door?) +anim 6131 - Push cheer walk thing? +anim 6132 - Jump over obstacle +anim 6133 - Throw Wood Chips Into Furnace (Clan Citadel) +anim 6134 - Throw Wood Chips Into Furnace (Clan Citadel) +anim 6135 - Throw Wood Chips Into Furnace (Clan Citadel) +anim 6143 - Firing Bow? +animGFX 6147 1052 - Bandos Mace Special Attack +anim 6194 - Throw Wood Chips Into Furnace (Clan Citadel) +anim 6197 - Sit and turn around? +anim 6198 - Get up from sit and turn around +anim 6217 - Clean specimen with brush? +anim 6281 - Cyrisus on Ground +anim 6282 - Cyrisus on Ground +anim 6283 - Cyrisus on Ground +anim 6285 - Touch something +anim 6287 - Checking yourself (Cyrisus Dream Mentor) +anim 6289 - Helping Cyrisus on the ground? +anim 6290 - Helping Cyrisus when he’s on the ground +anim 6291 S30 - Getting/Giving Item To/From NPC +animGFX 6292 2964 - Anniversary Cake +animGFX 6293 1060 - Stat Spy +animGFX 6294 1061 - Humidify +animGFX 6294 3298 - Humidify (Summer Storm) +anim 6295 - Dream Spell +anim 6296 - Sleeping (Dream Spell) +anim 6297 - Get up from Sleeping (Dream Spell) +animGFX 6298 1063 - Plank Make +animGFX 6299 1062 - Spellbook Swap +anim 6300 - bend to touch something on ground +animGFX 6303 1074 - Make Hunter Kit +anim 6304 - Land from T pose +anim 6305 - Lift hand up and out +anim 6362 - Cooling Molten Bar (Clan Citadel) +anim 6364 - Chop Log black axe +anim 6367 - Bars Into Hatch (Clan Citadel) +anim 6380 - Teleport Fragile Smelting Urn +anim 6381 - Teleport Smelting Urn +anim 6382 - Teleport Strong Smelting Urn +anim 6383 - hands on hips looking at ground +anim 6384 - Put Rune on Cracked Smelting Urn +anim 6385 - Put Rune on Fragile Smelting Urn +anim 6386 - Put Rune on Smelting Urn +anim 6387 - Put Rune on Strong Smelting Urn +anim 6388 - walking with hands behind back +anim 6389 - hands behind back +anim 6390 - hands behind back, facing sideways +anim 6391 - hands behind back sideways, do a motion +anim 6392 - hands behind back sideways, do a motion +anim 6393 - hands on hip +anim 6394 - Teleport Cracked Fishing Urn +anim 6395 - Spunky walk +anim 6396 - bird pose jumping jacks thing? +anim 6397 - weird jump side to side? +anim 6398 - bury head in sand and flail? +anim 6399 - weird animal dance? +anim 6400 - Turkey dance +anim 6401 - slither on ground like snake +anim 6402 - weird animal dance? +anim 6403 - downward dog yoga? +anim 6404 - Birdman pose +anim 6405 - Get on ground and slither like a snake +anim 6406 - Get on ground and slither like a snake +anim 6408 - head twist yoga? +anim 6409 - woodpecker dance? +anim 6424 - Digsite Workman Picking up and Throwing Rocks +anim 6425 - Digsite Workman Idle (DR-537) +anim 6446 - Clan Citadel Cooled Bars Into Hatch +anim 6459 - Digsite Cleaning Varrock Museum +anim 6462 - Pushing Button in Varrock Natural History Museum +anim 6463 - Teleport Fragile Fishing Urn +anim 6464 - Hands behind back +anim 6465 - Hands behind back, shake head +anim 6468 - Walk +anim 6469 - Stand +anim 6471 - Teleport Fishing Urn +anim 6472 - Teleport Strong Fishing Urn +anim 6473 - Teleport Decorated Fishing Urn +anim 6474 - Put Rune on Cracked Fishing Urn +anim 6475 - Put Rune on Fragile Fishing Urn +anim 6478 - Rocking in chair +anim 6480 - Clan Citadel Cooled Bars Into Hatch +anim 6483 - Clan Citadel Cooled Bars Into Hatch +anim 6486 - Walk +anim 6487 - Holding thing +anim 6488 - Defend +anim 6489 - Attack +anim 6490 - Death +anim 6525 - Drinking Shrink Me Quick at wrong time +anim 6526 - Cheering Thing? +anim 6527 - Open door +anim 6528 - Kick +anim 6529 - Shrink Me Quick +anim 6530 - Regrowing +anim 6531 - walk +anim 6532 - walk +anim 6554 - Canifis NPC turning into Werewolf +anim 6584 - Seed dibber +anim 6587 - Shoveling Gold Into Furnace (Clan Citadel) +animGFX 6592 1117 - Jar Generator (i) (e) +anim 6593 - Walk through the grass impetuous impulses +anim 6594 - Walk through the grass +anim 6595 - Walk through the grass +anim 6600 - Throw dart +animGFX 6601 1118 - Puro Puro Crop Circle +anim 6603 - Swimming +anim 6605 - Swing butterfly net +anim 6606 - Catch impling +anim 6608 - Catch impling +anim 6609 - Sidestep +anim 6610 - Sidestep +anim 6611 - Sidestep +anim 6616 - Put on statue piece +anim 6631 - Shoveling Gold Ore Into Furnace (Clan Citadel) +anim 6632 - Shoveling Silver Ore Into Furnace (Clan Citadel)l +anim 6633 - Shoveling Ore Into Furnace (Clan Citadel) +anim 6642 - Lift hand up in air +anim 6649 - Cabin Boy Jenkins Panic +anim 6650 - Melzar the Mad Crazy +anim 6651 - Melzar the Mad Stumble +anim 6654 - Taking off Elvarg’s Head +anim 6655 - Elvarg’s head +anim 6657 - hold thing? +anim 6658 - walk while hold thing? +anim 6659 - walk backwards holding thing? +anim 6660 - run +anim 6661 - step step +anim 6662 - side step +anim 6663 - side step +anim 6664 - Pet rock fetch +anim 6671 - Fletch bow +anim 6672 - Fletch bow +anim 6673 - Fletch bow +anim 6674 - Fletch bow +anim 6675 - Fletch bow +anim 6676 - Fletch bow +anim 6677 - Fletch bow +anim 6678 - Fletch Shortbow +anim 6679 - Fletch Oak Shortbow +anim 6680 - Fletch Willow Shortbow +anim 6681 - Fletch Maple Shortbow +anim 6682 - Fletch Yew Shortbow +anim 6683 - Fletch Magic Shortbow +anim 6684 - Fletch Shieldbow +anim 6685 - Fletch Oak Shieldbow +anim 6686 - Fletch Willow Shieldbow +anim 6687 - Fletch Maple Shieldbow +anim 6688 - Fletch Yew Shieldbow +anim 6689 - Fletch Magic Shieldbow +anim 6700 - Dragonfire Shield +anim 6702 - Cut thing +anim 6703 - Jump Over Wilderness Wall +anim 6704 - Clan Citadel Chopping Board +anim 6705 - Bare Hand Shark +anim 6706 - Bare Hand Shark +anim 6707 - Bare Hand Swordfish +anim 6708 - Bare Hand Swordfish +anim 6709 - Reassuring Dororan While Listening In On Longhall (Gunnar’s Ground) +anim 6710 - Bare Hand Tuna +anim 6711 - Bare Hand Tuna +anim 6712 - Hammer +anim 6713 - Light fire with bow +anim 6714 - Light fire with bow +anim 6715 - light fire with bow +anim 6716 - light fire with bow +anim 6717 - light fire with bow +anim 6718 - light fire with bow +anim 6719 - light fire with magic bow +anim 6720 - light fire with bow +anim 6723 - Jump into Ancient Cavern Whirlpool +anim 6724 - Ghost spirit ascending? +anim 6738 - Rune hatchet +anim 6739 - Adamant hatchet +anim 6740 - Mithril hatchet +anim 6741 - Black Hatchet +anim 6742 - Steel hatchet +anim 6743 - Iron Hatchet +anim 6744 - Bronze Hatchet +anim 6745 - Dragon Hatchet +anim 6746 - Rune Pickaxe +anim 6747 - Bronze Pickaxe +anim 6748 - Iron Pickaxe +anim 6749 - Steel Pickaxe +anim 6750 - Adamant Pickaxe +anim 6751 - Mithril Pickaxe +anim 6752 - Rune Pickaxe +anim 6753 - Mine With Bronze Pickaxe +anim 6754 - Iron Pickaxe +anim 6755 - Steel Pickaxe +anim 6756 - Adamant Pickaxe +anim 6757 - Mithril Pickaxe +anim 6758 - Dragon Pickaxe +anim 6769 - Put Rune on Fishing Urn +anim 6770 - Put Rune on Strong Fishing Urn +anim 6784 - Clan Citadel Grill with Spatula +anim 6786 - Clan Citadel Stew +anim 6788 - Seated +anim 6789 - Put Rune on Decorated Fishing Urn +anim 6794 - Teleport Cracked Cooking Urn +anim 6795 - Teleport Fragile Cooking Urn +anim 6814 - slide off seat +anim 6816 - Sit down +anim 6820 - Sitting +anim 6838 - attack +anim 6840 - Searching Crates +anim 6841 - Observatory Assistant Idle +anim 6842 - Get up from sitting +anim 6843 - Grab a Seat +anim 6844 - Observatory Professor Scratches Head +anim 6845 - Observatory Professor Fixes Telescope +anim 6846 - Sitting +anim 6847 - Observatory Professor Fixes Telescope +anim 6848 - Observatory Professor Fixes Telescope +anim 6849 - Looking Through Observatory Telescope +anim 6863 - Town Crier Scratches Head +anim 6864 - Stand +anim 6865 - Town Crier Ring Bell +animGFX 6866 1178 - Town Crier Gives Player a Book +anim 6867 - Walk +anim 6887 - Holding chest in pain +anim 6896 - Throw something +anim 6897 - Collapse on ground +anim 6912 - Lean against wall +anim 6913 - Lean against wall, arms crossed +anim 6914 - Lean against wall +anim 6915 - Hands out and up, as if banging on door +anim 6918 - Banging on door? +anim 6919 - Walking arms tied behind back +anim 6922 - About to teleport, lift hand up in protest? +anim 6923 - Shield self with elbow +anim 6926 - Walk hand covering head +anim 6927 - Stand breathing heavily +anim 6928 - Walking heavily +anim 6929 - Defend +anim 6933 - Pull switch? +anim 6935 - Mining +anim 6939 - Disappear +anim 6941 - Appear +anim 6978 - Lift really heavy rock +anim 6979 - Lift really heavy rock +anim 6988 - Swimming +anim 6999 - Dive jump +anim 7002 - Hit with hammer +anim 7003 - Sitting on floor in pain +anim 7023 - Crawling +anim 7039 - Run Holding 2H Sword (Legacy) (DR-124) +anim 7040 - Turning Holding 2H Sword (Legacy) (DR-124) +anim 7041 - Auto-Attack with 2H Sword +anim 7042 - Attack with weapon +anim 7043 - Side Step Holding 2H Sword (Legacy) (DR-124) +anim 7044 - Side Step Holding 2H Sword (Legacy) (DR-124) +anim 7045 - Back Step Holding 2H Sword (Legacy) (DR-124) +anim 7046 - Walk Holding 2H Sword (Legacy) (DR-124) +anim 7047 - Idle Holding 2H Sword (Legacy) (DR-124) +anim 7048 - Attack with 2H Sword +anim 7049 - Attack +anim 7050 - Defend with 2H Sword (Legacy) +anim 7056 - Get up from seat +anim 7057 - Sitting +animGFX 7070 1221 - Zamorak Godsword Special (Ice Cleave) [gfx 2104 on Target] +anim 7071 - Clan Citadel Dance +anim 7076 - Rope swing +animGFX 7078 1225 - Dragon 2H Sword Special (Power Stab) +anim 7081 - Swing Across Crossbow +anim 7082 - Old Spirit Tree Teleport (Leave) +anim 7084 - Old Spirit tree Teleport Arrive) +anim 7095 - Flailing around +anim 7096 - Covering face with elbow +anim 7126 - Teleport Cooking urn +anim 7133 - Teleport Strong Cooking urn +anim 7139 - Glouphrie Bowl +anim 7151 - Hammering Ground +anim 7152 - Stomp on balloon +anim 7159 - Clan Citadel Dance +anim 7161 - Clan Citadel Dance Walk +anim 7162 - Clan Citadel Dance Run +anim 7181 - Attack +anim 7182 - Pirate Attack With Hook Arm +anim 7183 - Punch +anim 7185 - Death +anim 7186 - Defend +anim 7187 - Defend +anim 7188 - Hands on hip, shake head +anim 7189 - limpy walk +anim 7190 - limpy walk +anim 7191 - walk +anim 7192 - back step +anim 7193 - side step +anim 7194 - side step +anim 7197 - Death +anim 7198 - Defend +anim 7199 - Idle +anim 7200 - Walk +anim 7201 - Back step +anim 7202 - Side step +anim 7203 - Side step +anim 7211 - Cut magic logs +anim 7212 - Pull something back with secateurs? +anim 7227 - Secutars +anim 7228 - Magic Secateurs +anim 7230 - Defend (snake sounds) +anim 7232 - Do weird thing +anim 7253 - Bend over backwards getting bitten by Snake Tree +anim 7255 - Climb up something then teleport (Clan Portal HW event 2011?) +anim 7261 - Fishing? +anim 7264 - Attack +anim 7265 - Stand idle +anim 7266 - Swimming (under ground) +anim 7267 - Wading through water (under ground) +anim 7268 - Jump over +anim 7269 - Jump into water +anim 7270 - Pick something off ground +anim 7271 - Step forward, then jump back +anim 7272 - Zombie Hand (emote) (e) +anim 7273 - Climb up out of water? +anim 7274 - Slide +anim 7275 - Walk through Spider Web +anim 7277 - Crazy (or shake some bowl?) +animGFX 7299 1247 - Request Assistance +anim 7301 - Defend with hands together above head +anim 7302 - Lower hands from above emote +anim 7307 - Twist something +animGFX 7312 538 - Clan Vexillum Teleport (arrive) +animGFX 7312 1767 - World Window Teleport (arrive) +anim 7321 - Open Strange Box on Yubuisk +anim 7363 - Look over wall? +anim 7364 - Fiddling with thing idle? +anim 7365 - Hands crossed shaking head idle +anim 7366 - Idle +anim 7368 - Idle +anim 7369 - Idle +anim 7376 - Walk and disappear +anim 7377 - Walk and appear +anim 7383 - Inferno Adze +animGFX 7389 537 - Clan Vexillum Teleport (leave) +animGFX 7389 1767 - World Window Teleport (leave) +anim 7392 - Lift hand and thing (electric sounds) +anim 7425 - Stand idle, then do thing put sideways +anim 7477 - Grab thing then roll it to other side +anim 7491 - Take thing pull back (or climb rope) +anim 7493 - Climb up rope +anim 7525 - Walk on Clan Citadel Dance Floor +anim 7526 - Run on Clan Citadel Dance Floor +animGFX 7528 1284 - Snowglobe (e) (item) +anim 7529 - Collect snow +anim 7530 - Throw Snowball +anim 7531 - Snowman Dance (emote) (e) +anim 7532 - Do thing +anim 7533 - Do thing pull +anim 7534 - Defend laugh then teleport +anim 7578 - Sitting on ground +anim 7579 - Sitting on knees +anim 7597 - Balance walk +anim 7599 - Get up brush self +anim 7628 - Pull switch? +anim 7629 - Hand up dizzy +anim 7633 - Step forward, open thing with hands (like window shades?) +anim 7640 - Climb up over obstacle +anim 7641 - Hands up casting spell (like Dungeoneering RuneCrafting) +anim 7643 - Walk +anim 7644 - Stand +anim 7645 - Antsy +anim 7650 - Walk +anim 7651 - Stand +anim 7652 - “FAIRY GOD PARENTS!†+anim 7660 - Cast familiar scroll +anim 7664 - Clan Citadel Guard Lowers Axe to Block Entry +anim 7665 - Clan Citadel Guard Lowers Axe to Block Entry +anim 7666 - Clan Citadel Guard Idle +anim 7672 - Clan Citadel Guard Lifts Axe to Allow Player Entry +anim 7700 - Raise fist high in pride +anim 7717 - Clan Citadel Guard Lifts Axe to Allow Player Entry +anim 7731 - Clan Citadel Guard Idle +anim 7745 - Take thing throw it up in air? +anim 7756 - Pouch Repair +anim 7774 - Bucket +anim 7823 - Disruption Shield +anim 7892 - Glitchy bucket +anim 7898 - Make Lunar Lumber +anim 7918 - Reading big open book lectern? +anim 7959 - Pick box up? +anim 8055 - Teleport lunar npc +anim 8107 - Lunar Farm Npc Defend +animGFX 8137 2006 - Exit Portal from Bandos Throne Room +anim 8165 - Lunar Floating Kick +anim 8170 - Stab lunge attack? +anim 8177 - Pull switch thing? +anim 8178 - Pull lever? +anim 8227 - Run +anim 8232 - Walk +anim 8239 - Walk +anim 8242 - Sidestep +anim 8263 - Sidestep +anim 8264 - Stand +anim 8289 - Pull lever? +anim 8323 - Pull lever up +anim 8371 - Force palm? +anim 8407 - Make speech (loop) +anim 8408 - Sit and nod +anim 8409 - Sit and cheer +anim 8410 - Sit and whistle +anim 8495 - Sit and point +anim 8496 - Walk +anim 8497 - Stand looking at the ground +anim 8499 - Shiver in fear (Wolf Whistle) +anim 8500 - Infuse Summoning Pouch +anim 8501 - Do something on knees? +animGFX 8502 1517 - Recharge Summoning Points (Old) +anim 8503 - “ACK!â€â€ +animGFX 8525 1515 - Summoning Skillcape Emote +anim 8528 - Using Some machine? +anim 8562 - stand idle +anim 8591 - attack +anim 8592 - walk +anim 8593 - stand idle +anim 8594 - Some sort of teleport? +anim 8595 - Same as above +anim 8629 - Teleport Decorated Cooking Urn +anim 8649 - Put Rune on Cracked Cooking Urn +anim 8651 - Put Rune on Fragile Cooking Urn +anim 8652 - Put Rune on Cooking Urn +anim 8654 - Put Rune on Strong Cooking Urn +anim 8681 - Walk holding hand in air +anim 8682 - Stand holding hand in air +anim 8683 - Stand +anim 8684 - Walk +anim 8685 - Run +anim 8686 - Lift hands up +anim 8687 - Get on knees +anim 8688 - Do something on knees +anim 8690 - Run hand in air +anim 8691 - Put Rune on Decorated Cooking Urn +anim 8694 - Get out of water +anim 8695 - In water +anim 8698 - Jump in water +anim 8699 - In water +anim 8701 - Turn crank around and around? +anim 8702 - Lift Big boulder? +anim 8704 - Hammer L shaped block +anim 8705 - Zombie dazed? +anim 8707 - Wipe head and do excercise +animGFX 8709 1543 - Digging in Vinesweeper +anim 8710 - Investigating ground (Dungeoneering Spike puzzle room) +animGFX 8711 1541 - VineSweeper Place Flag +anim 8713 - Teleport Cracked Woodcutting Urn +anim 8727 - Teleport Fragile Woodcutting Urn +anim 8729 - Teleport Woodcutting Urn +anim 8730 - Teleport Strong woodcutting Urn +anim 8736 - Flash and shrink from being large +anim 8758 - Stand +anim 8765 - Kick +animGFX 8767 1546 - Dagon’Hai Monk Magic Attack +anim 8768 - Look back scared +animGFX 8770 1553 - Safety First (emote) (e) +anim 8804 - Pull door thing? +anim 8805 - Push door thing? +anim 8820 - “No no no no no†+anim 8821 - “No no no, of course not...†+anim 8829 - Combat pose? +anim 8830 - Defend/pull lever? +anim 8831 - Run +anim 8832 - Crouch +anim 8833 - Crouch sit +anim 8834 - Lift hands up and arrange shelf? +anim 8835 - Lean forward and look to see if coast is clear +anim 8836 - Mining with Bronze Pickaxe +anim 8837 - Mining with Iron Pickaxe +anim 8838 - Mining with Steel Pickaxe +anim 8839 - Mining with Adamant Pickaxe +anim 8840 - Mining with Mithril Pickaxe +anim 8841 - Mining with Rune Pickaxe +anim 8842 - Walking backwards +animGFX 8847 1557 - Electrocution +animGFX 8848 1557 - Electrocution +anim 8849 - Throw snowball? +anim 8858 - Walk and fade +anim 8859 - Fade and walk +anim 8860 - Idle hands behind back +anim 8861 - Hammer ground +anim 8862 - Walking drunk +anim 8863 - Stand drunk +anim 8864 - Sacred clay hammer ground +anim 8865 - Sacred clay hammer +anim 8866 - Wipe head, drunk collapse onto knees +anim 8868 - Drunk banging head +anim 8869 - Drunk, trying to keep balance +anim 8870 - Drunk reaching arm out +anim 8871 - Drunk reaching arm out +anim 8872 - Drunk fall over on knees and catch balance +anim 8873 - Stand up get drunk +anim 8874 - Drunk attack +anim 8875 - Walking holding anchor? +anim 8877 - On knees +anim 8878 - Standing holding anchor? +anim 8887 - Golden hammer +anim 8888 - Golden hammer +anim 8889 - Sacred Clay hammer +anim 8890 - Sacred Clay hammer +anim 8891 - Golden hammer +anim 8893 - Regular hammer +animGFX 8901 1567 - Turn into Rabbit (Easter Event) +anim 8902 - Turn back from rabbit +animGFX 8903 1566 - Chocatrice Cape Emote +anim 8904 - Reach up to something on high shelf? +anim 8905 - Bucket +anim 8906 - Chocatrice egg +anim 8907 - Shake chocatrice egg +anim 8908 - Bend over to ground +anim 8909 - Bucket +animGFX 8939 1864 - Drakan’s Medallion Teleport (t-L) +animGFX 8941 1864 - Drakan’s Medallion Teleport (t-A) +animGFX 8939 1678 - Ectofuntus Green Teleport (t-L) +animGFX 8941 1679 - Ectofuntus Green Teleport (t-A) +animGFX 8939 1576 - Standard Teleport (t-L) +animGFX 8941 1577 - Standard Teleport (t-A) +anim 8943 - Sacred clay hammer up high +anim 8950 - Volatile clay hammer up high +anim 8953 - Invisible, appear as if teleport +anim 8973 - Raise hand in air +anim 8975 - Raise hand in air +anim 8976 - Raise hand in air +anim 8977 - Idle +anim 8979 - Walk +anim 8980 - Idle +anim 8981 - Idle +anim 8982 - Walk +anim 8983 - Side step +anim 8984 - Side step +anim 8985 - Back step +anim 8986 - Run +anim 8987 - Balance slightly +anim 8988 - Defend +anim 8989 - Punch +anim 8990 - Fly Kite +anim 8991 - Kick +anim 8996 - Strong pose +anim 8997 - Walk holding FoG bowl? +anim 8998 - Idle holding FoG bowl +anim 8999 - Defend holding FoG bowl +anim 9000 - Balance holding Fog bowl +anim 9001 - Back step holding FoG bowl +anim 9002 - Side step holding FoG bowl +anim 9003 - Side step holding FoG bowl +anim 9004 - Run holding FoG bowl +anim 9012 - Throw teleorb on ground (Fist of Guthix) +anim 9013 - Appear +anim 9016 - Disappear holding FoG bowl +anim 9018 - Appear holding FoG bowl +anim 9021 - Emerald sickle bloom (Legacy of Seergaze) +anim 9022 - Hammer up high Golden Hammer +anim 9024 - Shake head spazzy and get off knees +anim 9025 - Get on knees +anim 9031 - Use saw to open door? +anim 9039 - Walk dejected +anim 9040 - Dejected idle +anim 9044 - Dejected pull rope? +anim 9046 - Lean forward and touch thing +anim 9047 - Attack with Ivandis Flail +anim 9049 - Idle +anim 9050 - Run +anim 9051 - Walk +anim 9052 - back walk +anim 9053 - Side step +anim 9054 - Side step +anim 9055 - Throw thing +anim 9057 - Throw thing +anim 9058 - hands on hip nodding +anim 9059 - Touch things then moves arms back +anim 9060 - Turn to side and cock head +anim 9061 - Opening thing with hand sideways? +anim 9062 - Finish opening thing +anim 9063 - hands out +anim 9064 - put sickle on ground +anim 9065 - emerald sickle on ground +anim 9067 - hands out +anim 9069 - leaning sideways with hands on stomach +anim 9070 - walking dejected +anim 9072 - get hit with hands on stomach +anim 9075 - lift into air and BLECK +anim 9076 - in air BLECK +anim 9077 - Bleck then relax +anim 9078 - Take damage from failing Gnome Course Board +anim 9085 - Get off ground +anim 9086 - Pull rope on knees? +anim 9087 - Pull rope on knees +anim 9091 - move to the side to duck obstacle? +anim 9092 - move to the side to duck obstacle? +anim 9096 - Keg Cannon +anim 9097 - Use Ivandis Flail +anim 9098 - Lift arms up (bloom?) +anim 9099 - In pain +anim 9100 - Bend in pain +anim 9104 - Enchant silver sickle +anim 9105 - Knock on Door (Priest in Peril) +anim 9107 - Fall plop down on belly +anim 9109 - Idle, thinking +anim 9110 - Idle nodding head +anim 9111 - Idle clapping +anim 9116 - Keg Cannon +anim 9119 - shaking head +anim 9121 - Defend +anim 9136 - Move forward to climb up ladder +anim 9141 - attack +anim 9151 - Saw +anim 9164 - leaning forward +anim 9174 - Listen to Glimmering Shell +anim 9176 - Listen to Shimmering shell +anim 9195 - Trying to open door/chest +anim 9204 - Trying to open thing +anim 9211 - Trying to open thing, snap off lever +anim 9214 - Gertrude Shaking Player’s Hand +anim 9215 - Getting Hand Shaked By Gertrude +anim 9218 - Will (Lumber Yard Employee) +anim 9220 - Enter Lumber Yard +anim 9221 - Enter Lumber Yard +anim 9224 - Stroking Kitten +anim 9227 - Tapping toe and dance +anim 9304 - Put up planks +anim 9305 - Put plank +anim 9306 - Jolly run +anim 9307 - Defend/attack +anim 9308 - barge attack +anim 9309 - Step forward do pose +anim 9310 - Jump over obstacle +anim 9350 - Hammer thing +anim 9359 - Fall onto back +anim 9360 - Hit With Bronze Pickaxe +anim 9361 - hit with Iron Pickaxe +anim 9362 - Hit with steel pickaxe +anim 9363 - hit with mithril Pickaxe +anim 9364 - Hit with adamant pickaxe +anim 9365 - Hit with rune pickaxe +anim 9367 - walk then shrink and disappear +anim 9429 - Opening Drawers +anim 9497 - Pull open +anim 9499 - Defend/do whittle diddle +animGFX 9502 327 - Salt Shaker on Rock Slugs +anim 9504 - Using charcoal +anim 9516 - Walk, bending back +anim 9519 - Collapse +anim 9523 - Look around you as if there’s bugs or stuff bothering you +anim 9526 - Crazy thing blowing into hands +anim 9534 - Sitting laid back in chair +anim 9536 - Idle +anim 9537 - Limp walk +anim 9542 - Tin Cup +anim 9544 - Attack +anim 9547 - rub ground +anim 9549 - Lever +anim 9551 - Walk holding thing +anim 9552 - back walk +anim 9553 - Hold thing +anim 9554 - Side step hold thing +anim 9555 - Side step hold thing +anim 9557 - Dive off Prison Island Pier (Rocking Out) +anim 9558 - Lift hands up then down +anim 9561 - Rub thing on knees +anim 9562 - hitting thing +anim 9564 - On ground collapsed +anim 9565 - Playing accordion (Rocking Out) +anim 9566 - Accordion (Rocking Out) +animGFX 9568 1668 - Resurrect Ex-Ex Parrot +anim 9570 - walk +anim 9571 - idle +anim 9573 - uproot/pull thing +anim 9575 - Fall on back +anim 9579 - Fiddling with Accordion (Rocking Out) (June 2008) +anim 9591 - crouched on knees +anim 9595 - Get in seat +anim 9596 - Teleport +animGFX 9597 1680 - Tele Tab +anim 9598 - Arrive from teleport +animGFX 9599 1681 - Ancient Teleport +animGFX 9600 1682 - Lyre teleport +animGFX 9601 1683 - Skull Scepter Teleport +animGFX 9602 1690 - Wilderness Obelisk Teleport +animGFX 9603 1684 - Jewelry Teleport +anim 9604 - Blue Rum bottle +anim 9605 - Red rum bottle +anim 9606 - Lunar tele +anim 9607 - Zamorak Mage Teleports You to Abyss +animGFX 9609 1688 - Ectophial Teleport +anim 9610 - Teleport +anim 9633 - Alch with staff +anim 9640 - Look +anim 9648 - Pick cabbage +anim 9649 - Push rock +anim 9663 - Shy +anim 9664 - Shy +anim 9668 - Shy +anim 9676 - walking +anim 9677 - idle, pull up +anim 9678 - limping walk +anim 9679 - Standing arms out fiddling hitting something +anim 9680 - hunched limp walk +anim 9705 - throw something +anim 9709 - take/touch something +anim 9710 - arms out looking through something? +anim 9711 - take/touch something +anim 9712 - looking at something, questioning it, then look again +anim 9713 - teleport +anim 9714 - take something out of pocket and put it on ground +anim 9715 - throw something on ground? +anim 9716 - Death +anim 9717 - On floor +anim 9718 - Get off floor \ No newline at end of file diff --git a/dumps/530/condata.txt b/dumps/530/condata.txt new file mode 100644 index 0000000..df7763a --- /dev/null +++ b/dumps/530/condata.txt @@ -0,0 +1,227 @@ +/* +item=Gazebo, id=8192, option=[null, null, null, null, drop] +item=Small fountain, id=8193, option=[null, null, null, null, drop] +item=Large fountain, id=8194, option=[null, null, null, null, drop] +item=Posh fountain, id=8195, option=[null, null, null, null, drop] +item=Boundary stones, id=8196, option=[null, null, null, null, drop] +item=Wooden fence, id=8197, option=[null, null, null, null, drop] +item=Stone wall, id=8198, option=[null, null, null, null, drop] +item=Iron railings, id=8199, option=[null, null, null, null, drop] +item=Picket fence, id=8200, option=[null, null, null, null, drop] +item=Garden fence, id=8201, option=[null, null, null, null, drop] +item=Marble wall, id=8202, option=[null, null, null, null, drop] +item=Thorny hedge, id=8203, option=[null, null, null, null, drop] +item=Nice hedge, id=8204, option=[null, null, null, null, drop] +item=Small box hedge, id=8205, option=[null, null, null, null, drop] +item=Topiary hedge, id=8206, option=[null, null, null, null, drop] +item=Fancy hedge, id=8207, option=[null, null, null, null, drop] +item=Tall fancy hedge, id=8208, option=[null, null, null, null, drop] +item=Tall box hedge, id=8209, option=[null, null, null, null, drop] +item=Rosemary, id=8210, option=[null, null, null, null, drop] +item=Daffodils, id=8211, option=[null, null, null, null, drop] +item=Bluebells, id=8212, option=[null, null, null, null, drop] +item=Sunflower, id=8213, option=[null, null, null, null, drop] +item=Marigolds, id=8214, option=[null, null, null, null, drop] +item=Roses, id=8215, option=[null, null, null, null, drop] +item=Firepit, id=8216, option=[null, null, null, null, drop] +item=Firepit with hook, id=8217, option=[null, null, null, null, drop] +item=Firepit with pot, id=8218, option=[null, null, null, null, drop] +item=Small oven, id=8219, option=[null, null, null, null, drop] +item=Large oven, id=8220, option=[null, null, null, null, drop] +item=Steel range, id=8221, option=[null, null, null, null, drop] +item=Fancy range, id=8222, option=[null, null, null, null, drop] +item=Wooden shelves 1, id=8223, option=[null, null, null, null, drop] +item=Wooden shelves 2, id=8224, option=[null, null, null, null, drop] +item=Wooden shelves 3, id=8225, option=[null, null, null, null, drop] +item=Oak shelves 1, id=8226, option=[null, null, null, null, drop] +item=Oak shelves 2, id=8227, option=[null, null, null, null, drop] +item=Teak shelves 1, id=8228, option=[null, null, null, null, drop] +item=Teak shelves 2, id=8229, option=[null, null, null, null, drop] +item=Pump and drain, id=8230, option=[null, null, null, null, drop] +item=Pump and tub, id=8231, option=[null, null, null, null, drop] +item=Sink, id=8232, option=[null, null, null, null, drop] +item=Wooden larder, id=8233, option=[null, null, null, null, drop] +item=Oak larder, id=8234, option=[null, null, null, null, drop] +item=Teak larder, id=8235, option=[null, null, null, null, drop] +item=Cat blanket, id=8236, option=[null, null, null, null, drop] +item=Cat basket, id=8237, option=[null, null, null, null, drop] +item=Cushioned basket, id=8238, option=[null, null, null, null, drop] +item=Beer barrel, id=8239, option=[null, null, null, null, drop] +item=Cider barrel, id=8240, option=[null, null, null, null, drop] +item=Asgarnian ale, id=8241, option=[null, null, null, null, drop] +item=Greenman's ale, id=8242, option=[null, null, null, null, drop] +item=Dragon bitter, id=8243, option=[null, null, null, null, drop] +item=Chef's delight, id=8244, option=[null, null, null, null, drop] +item=Blank poh entity, id=8245, option=[null, null, null, null, drop] +item=Wood kitchen table, id=8246, option=[null, null, null, null, drop] +item=Oak kitchen table, id=8247, option=[null, null, null, null, drop] +item=Teak kitchen table, id=8248, option=[null, null, null, null, drop] +item=Oak staircase, id=8249, option=[null, null, null, null, drop] +item=Oak staircase, id=8250, option=[null, null, null, null, drop] +item=Oak staircase, id=8251, option=[null, null, null, null, drop] +item=Teak staircase, id=8252, option=[null, null, null, null, drop] +item=Teak staircase, id=8253, option=[null, null, null, null, drop] +item=Teak staircase, id=8254, option=[null, null, null, null, drop] +item=Marble staircase, id=8255, option=[null, null, null, null, drop] +item=Marble staircase, id=8256, option=[null, null, null, null, drop] +item=Marble staircase, id=8257, option=[null, null, null, null, drop] +item=Spiral staircase, id=8258, option=[null, null, null, null, drop] +item=Marble spiral, id=8259, option=[null, null, null, null, drop] +item=Crawling hand, id=8260, option=[null, null, null, null, drop] +item=Cockatrice head, id=8261, option=[null, null, null, null, drop] +item=Basilisk head, id=8262, option=[null, null, null, null, drop] +item=Kurask head, id=8263, option=[null, null, null, null, drop] +item=Abyssal head, id=8264, option=[null, null, null, null, drop] +item=Kbd heads, id=8265, option=[null, null, null, null, drop] +item=Kq head, id=8266, option=[null, null, null, null, drop] +item=Mounted bass, id=8267, option=[null, null, null, null, drop] +item=Mounted swordfish, id=8268, option=[null, null, null, null, drop] +item=Mounted shark, id=8269, option=[null, null, null, null, drop] +item=Mithril armour, id=8270, option=[null, null, null, null, drop] +item=Adamantite armour, id=8271, option=[null, null, null, null, drop] +item=Runite armour, id=8272, option=[null, null, null, null, drop] +item=Cw armour 1, id=8273, option=[null, null, null, null, drop] +item=Cw armour 2, id=8274, option=[null, null, null, null, drop] +item=Cw armour 3, id=8275, option=[null, null, null, null, drop] +item=Rune case 1, id=8276, option=[null, null, null, null, drop] +item=Rune case 2, id=8277, option=[null, null, null, null, drop] +item=Rune case 3, id=8278, option=[null, null, null, null, drop] +item=Silverlight, id=8279, option=[null, null, null, null, drop] +item=Excalibur, id=8280, option=[null, null, null, null, drop] +item=Darklight, id=8281, option=[null, null, null, null, drop] +item=Anti-dragon shield, id=8282, option=[null, null, null, null, drop] +item=Amulet of glory, id=8283, option=[null, null, null, null, drop] +item=Cape of legends, id=8284, option=[null, null, null, null, drop] +item=King arthur, id=8285, option=[null, null, null, null, drop] +item=Elena, id=8286, option=[null, null, null, null, drop] +item=Giant dwarf, id=8287, option=[null, null, null, null, drop] +item=Miscellanians, id=8288, option=[null, null, null, null, drop] +item=Lumbridge, id=8289, option=[null, null, null, null, drop] +item=The desert, id=8290, option=[null, null, null, null, drop] +item=Morytania, id=8291, option=[null, null, null, null, drop] +item=Karamja, id=8292, option=[null, null, null, null, drop] +item=Isafdar, id=8293, option=[null, null, null, null, drop] +item=Small map, id=8294, option=[null, null, null, null, drop] +item=Medium map, id=8295, option=[null, null, null, null, drop] +item=Large map, id=8296, option=[null, null, null, null, drop] +item=Oak cage, id=8297, option=[null, null, null, null, drop] +item=Oak and steel cage, id=8298, option=[null, null, null, null, drop] +item=Steel cage, id=8299, option=[null, null, null, null, drop] +item=Spiked cage, id=8300, option=[null, null, null, null, drop] +item=Bone cage, id=8301, option=[null, null, null, null, drop] +item=Spikes, id=8302, option=[null, null, null, null, drop] +item=Tentacle pool, id=8303, option=[null, null, null, null, drop] +item=Flame pit, id=8304, option=[null, null, null, null, drop] +item=Rocnar, id=8305, option=[null, null, null, null, drop] +item=Oak ladder, id=8306, option=[null, null, null, null, drop] +item=Teak ladder, id=8307, option=[null, null, null, null, drop] +item=Mahogany ladder, id=8308, option=[null, null, null, null, drop] +item=Crude wooden chair, id=8309, option=[null, null, null, null, drop] +item=Wooden chair, id=8310, option=[null, null, null, null, drop] +item=Rocking chair, id=8311, option=[null, null, null, null, drop] +item=Oak chair, id=8312, option=[null, null, null, null, drop] +item=Oak armchair, id=8313, option=[null, null, null, null, drop] +item=Teak armchair, id=8314, option=[null, null, null, null, drop] +item=Mahogany armchair, id=8315, option=[null, null, null, null, drop] +item=Brown rug, id=8316, option=[null, null, null, null, drop] +item=Rug, id=8317, option=[null, null, null, null, drop] +item=Opulent rug, id=8318, option=[null, null, null, null, drop] +item=Wooden bookcase, id=8319, option=[null, null, null, null, drop] +item=Oak bookcase, id=8320, option=[null, null, null, null, drop] +item=Mahogany b'kcase, id=8321, option=[null, null, null, null, drop] +item=Torn curtains, id=8322, option=[null, null, null, null, drop] +item=Curtains, id=8323, option=[null, null, null, null, drop] +item=Opulent curtains, id=8324, option=[null, null, null, null, drop] +item=Clay fireplace, id=8325, option=[null, null, null, null, drop] +item=Stone fireplace, id=8326, option=[null, null, null, null, drop] +item=Marble fireplace, id=8327, option=[null, null, null, null, drop] +item=Teak portal, id=8328, option=[null, null, null, null, drop] +item=Mahogany portal, id=8329, option=[null, null, null, null, drop] +item=Marble portal, id=8330, option=[null, null, null, null, drop] +item=Teleport focus, id=8331, option=[null, null, null, null, drop] +item=Greater focus, id=8332, option=[null, null, null, null, drop] +item=Scrying pool, id=8333, option=[null, null, null, null, drop] +item=Oak lectern, id=8334, option=[null, null, null, null, drop] +item=Eagle lectern, id=8335, option=[null, null, null, null, drop] +item=Demon lectern, id=8336, option=[null, null, null, null, drop] +item=Teak eagle lectern, id=8337, option=[null, null, null, null, drop] +item=Teak demon lectern, id=8338, option=[null, null, null, null, drop] +item=Mahogany eagle, id=8339, option=[null, null, null, null, drop] +item=Mahogany demon, id=8340, option=[null, null, null, null, drop] +item=Globe, id=8341, option=[null, null, null, null, drop] +item=Ornamental globe, id=8342, option=[null, null, null, null, drop] +item=Lunar globe, id=8343, option=[null, null, null, null, drop] +item=Celestial globe, id=8344, option=[null, null, null, null, drop] +item=Armillary sphere, id=8345, option=[null, null, null, null, drop] +item=Small orrery, id=8346, option=[null, null, null, null, drop] +item=Large orrery, id=8347, option=[null, null, null, null, drop] +item=Wooden telescope, id=8348, option=[null, null, null, null, drop] +item=Teak telescope, id=8349, option=[null, null, null, null, drop] +item=Mahogany 'scope, id=8350, option=[null, null, null, null, drop] +item=Crystal ball, id=8351, option=[null, null, null, null, drop] +item=Elemental sphere, id=8352, option=[null, null, null, null, drop] +item=Crystal of power, id=8353, option=[null, null, null, null, drop] +item=Alchemical chart, id=8354, option=[null, null, null, null, drop] +item=Astronomical chart, id=8355, option=[null, null, null, null, drop] +item=Infernal chart, id=8356, option=[null, null, null, null, drop] +item=Oak throne, id=8357, option=[null, null, null, null, drop] +item=Teak throne, id=8358, option=[null, null, null, null, drop] +item=Mahogany throne, id=8359, option=[null, null, null, null, drop] +item=Gilded throne, id=8360, option=[null, null, null, null, drop] +item=Skeleton throne, id=8361, option=[null, null, null, null, drop] +item=Crystal throne, id=8362, option=[null, null, null, null, drop] +item=Demonic throne, id=8363, option=[null, null, null, null, drop] +item=Oak lever, id=8364, option=[null, null, null, null, drop] +item=Teak lever, id=8365, option=[null, null, null, null, drop] +item=Mahogany lever, id=8366, option=[null, null, null, null, drop] +item=Trapdoor, id=8367, option=[null, null, null, null, drop] +item=Trapdoor, id=8368, option=[null, null, null, null, drop] +item=Trapdoor, id=8369, option=[null, null, null, null, drop] +item=Floor decoration, id=8370, option=[null, null, null, null, drop] +item=Steel cage, id=8371, option=[null, null, null, null, drop] +item=Trapdoor, id=8372, option=[null, null, null, null, drop] +item=Lesser magic cage, id=8373, option=[null, null, null, null, drop] +item=Greater magic cage, id=8374, option=[null, null, null, null, drop] +item=Wooden workbench, id=8375, option=[null, null, null, null, drop] +item=Oak workbench, id=8376, option=[null, null, null, null, drop] +item=Steel framed bench, id=8377, option=[null, null, null, null, drop] +item=Bench with vice, id=8378, option=[null, null, null, null, drop] +item=Bench with lathe, id=8379, option=[null, null, null, null, drop] +item=Crafting table 1, id=8380, option=[null, null, null, null, drop] +item=Crafting table 2, id=8381, option=[null, null, null, null, drop] +item=Crafting table 3, id=8382, option=[null, null, null, null, drop] +item=Crafting table 4, id=8383, option=[null, null, null, null, drop] +item=Tool store 1, id=8384, option=[null, null, null, null, drop] +item=Tool store 2, id=8385, option=[null, null, null, null, drop] +item=Tool store 3, id=8386, option=[null, null, null, null, drop] +item=Tool store 4, id=8387, option=[null, null, null, null, drop] +item=Tool store 5, id=8388, option=[null, null, null, null, drop] +item=Repair bench, id=8389, option=[null, null, null, null, drop] +item=Whetstone, id=8390, option=[null, null, null, null, drop] +item=Armour stand, id=8391, option=[null, null, null, null, drop] +item=Pluming stand, id=8392, option=[null, null, null, null, drop] +item=Shield easel, id=8393, option=[null, null, null, null, drop] +item=Banner easel, id=8394, option=[null, null, null, null, drop] +item=Parlour, id=8395, option=[null, null, null, null, drop] +item=Kitchen, id=8396, option=[null, null, null, null, drop] +item=Dining room, id=8397, option=[null, null, null, null, drop] +item=Bedroom, id=8398, option=[null, null, null, null, drop] +item=Games room, id=8399, option=[null, null, null, null, drop] +item=Combat room, id=8400, option=[null, null, null, null, drop] +item=Hall, id=8401, option=[null, null, null, null, drop] +item=Hall, id=8402, option=[null, null, null, null, drop] +item=Hall, id=8403, option=[null, null, null, null, drop] +item=Hall, id=8404, option=[null, null, null, null, drop] +item=Chapel, id=8405, option=[null, null, null, null, drop] +item=Workshop, id=8406, option=[null, null, null, null, drop] +item=Study, id=8407, option=[null, null, null, null, drop] +item=Portal chamber, id=8408, option=[null, null, null, null, drop] +item=Throne room, id=8409, option=[null, null, null, null, drop] +item=Oubliette, id=8410, option=[null, null, null, null, drop] +item=Dungeon corridor, id=8411, option=[null, null, null, null, drop] +item=Dungeon cross, id=8412, option=[null, null, null, null, drop] +item=Dungeon stairs, id=8413, option=[null, null, null, null, drop] +item=Treasure room, id=8414, option=[null, null, null, null, drop] +item=Garden, id=8415, option=[null, null, null, null, drop] +item=Formal garden, id=8416, option=[null, null, null, null, drop] + */ \ No newline at end of file diff --git a/dumps/530/falador_npc_scripts.txt b/dumps/530/falador_npc_scripts.txt new file mode 100644 index 0000000..6968477 --- /dev/null +++ b/dumps/530/falador_npc_scripts.txt @@ -0,0 +1,841 @@ +Cassie - Cassie's Shield Shop + +Consists of + +10 of each +Wooden shield(20), Bronze sq shield(48), bronze kiteshield(68) +iron sq shield(168), iron kiteshield(238), steel sq shield(600) +steel kiteshield(850), mithril sq shield(1560) + +---------------------------------------------------------------- + +Cassie + +I buy and sell shields; do you want to trade? + + +---- +Options + +Yes, please. + +No, thank you. + +____________________________________________________________________________ + + +Emily (bartender, Falador) + +--- +Options + +What would you like to say? + +What ales are you serving? + +What can you tell me about dwarves and ale? [QUEST] P2P + +- - - +Emily + +Well, we've got Asgarnian Ale, Wizard's Mind Bomb and Dwarven Stout, all for 3 coins. + +--- +Options + +One Asgarnian Ale, please. +I'll try the Mind Bomb. +Can I have a Dwarven Stout? +I don't feel like any of those. +What can you tell me about dwarves and ale [Quest] P2P + + +Thanks, Emily. + +{ + +Kaylee/ Tina into is + + + +Hi! What can I get you? + +} + + +________________________________ + + +Drunken Man + + +--- +Hello. + +- - - + +... whassup? + +--- +Are you alright? (confuse) + +- - - +... see... two of you... why there two of you? + +--- +There's only one of me, friend. (confused) + +- - - +... no, two of you... you can't count... + ...maybe you drunk too much... + +--- +Whatever you say, friend. (laughter) + +- - - +... giant hairy cabbages...(shocked) + +[END] + +___________________________________________________ + +HairDresser (Has a mullet) + +Good afternoon, (madam/sir). Are you interested in a new haircut? + + +--- +Yes, please. + +No, thank you. + + + +____________________________________________________ +Herquin (Jewelry) + +--- +Do you wish to trade? + +Sorry, I don't want to talk to you, actually. + +- - - +Why, yes, this is a jewel shop after all. + + + + +Herqiuin's Gems { + +0 of each +Uncut Sapphire(25) Emerald(50) Ruby(100) +Diamond(200) Sapphire(250) Emerald(500) +Ruby(1000) Diamond(2000) + +} + +________________________________________________________ +Wayne + +Welcome to Wayne's Chains, Do you wanna buy or sell some chainmail? + +--- + +Yes, please. +No, thanks. + +Wayne's Chains - Chainmail Specialist { + +10 of each + +Chainbody +bronze(60), iron(210), steel(750), +black(1440), mithril(1950), adamant(4800) + +} + +________________________________________________________ + +Falador Gardener(s) + +--- +Hello. + +- - - + +(pissed) +Oi'm Busy. If tha' wants owt, tha' can go find Wyson. He's + ta boss 'round here. And KEEP YER TRAMPIN' FEET ORFF +MA' FLOWERS + +--- +Right... (surprised) +_________________________________________________________ + +Wyson the gardener + + +I'm the head gardener around here. +If you're looking for woad leaves, or if you need help with +owt, I'm yer man. + + +--- +Yes please, I need woad leaves. +Sorry, but I'm not interested. + +- - - +How much are you willing to pay? (Shady shaking) + +--- +{ +How about 5 coins? +How about 10 coins? + + +No no, that's far too little. Woad leaves are hard to get. I +used to have plenty but someone kept stealing them of +me. + +} +How about 15 coins? { +Mmmm... ok, that sounds fair. + +--- +Thanks. +- - - +I'll be around if you have any more gardening needs. + +} +How about 20 coins? +{ +(Boner) +Ok that's more than fair. + +Here, have two, you're a generous person. +--- +Thanks. +} + +______________________________ + + + +Dwarfe (mining guild, gold shield) && without + +- - - +Welcome to the mining guild. +Can I help you with anything? + +--- + +What have you got in the Guild? + +What do you dwarves do with the ore you mine? + +No thanks, I'm fine. + +- - - +1) +Ooh, it's WONDERFUL! There are lots of coal rocks, +and even a few mithril rocks in the guild, +all exclusively for people with at least 60 mining +There's no better mining site anywhere near here. + +--- + +It's a good thing I have level - mining. (excited) +//Find low persons response + - - - + +Yes, that's pretty good. Did you want anything else?(smiley) + +--- + + +What do you dwarves do with the ore you mine? (smiley) + + +No thanks, I'm fine. + + +- - - +1) +What do you think? We smelt it into bars, smith the metal + to make armour and weapons, then we exchange them for +goods and services. (hahaha) + +--- + +I don't see many dwarves +sellin armour or weapons here. (shady shaking) + +- - - +No, this is only a mining outpost. We dwarves don't much +like to settle in human cities. Most of the ore is carted off +to Keldagrim, the great dwarven city. They've got a + special blast furnace up there - it makes smelting the ore + +so much easier. There are plenty of dwarven traders +working in Keldagrim. Anyway, can I help you with anything +else? + +(smiley) + +//FINISHed + +Mining cape dwarfe + +Can you tell me about your skillcape? (confused) { + Sure, this is a Skillcape of Mining. It shows my stature as + a master minger! It has all sorts of uses including a skill + boost to my mining skill. When you get to level 99 come + and talk to me and I'll sell you one. Is there anything else I + + > + can help you with? + + --- + Yes. { + (happy_ + So what can I help you with, then? + } + No. + +} +_____________________________ + +Man (blue cap - between fally castle and garden) + + +PISSED + +What are you doing in my house? + +--- + +I was just exploring. (happy) + +- - - + +You're exploring my house? (up and down confused thinking) + +--- +You don't mind, do you? + +- - - + +But... why are you exploring in my house? + +--- + +Oh, I don't know. I just wandered in, saw you and thought +It'd be fun to speak to you. + +- - - +... you are very strange... + +--- +Perhaps I should go now. + +- - - +Yes, please go away now. (sad) + + +_____________________________________________________________________ + +Permit Officer/Real estage agent + +Can't you see I'm busy? (grind teeth) + +__________________________________________ + + +Flynn's Mace Market + +Mace { +10 of each + +Bronze(18), iron(63), Steel(225) +Mithril(585), Adamant(1440) +} + +- - - +Hello. Do you want to buy or sell any maces? (friendly) + +--- + +No, thanks. +Well, I'll have a look, at least. + + +___________________________________________ +Gen store + +Can I help you at all? + +--- +Yes, please. What are you selling? + +How should I use your shop? { + +I'm glad you ask! You can buy as many of the items + stocked as you wish. You can also sell most items to the +shop. + +} + +No, thanks. + + +______________________________________________________ + + + +Squire Asrol (sounds like ass role) + +Hello. I am the squire to Sir Vyvin. (calm) + +--- +And how is life as a squire? { +Well, Sir Vyvin is a good guy to work for, however, I'm in + a spot of trouble today. I've gone and lost Sir Vyvin's sword! (depressed) + + --- +Do you know where you lost it? { + (confused) + Well now, if I knew THAT it wouldn't be lost, now would it? +} + +I can make a new sword if you like.. + + Is he angry? { + He doesn't know yet. I was hoping I could think of +something to do before he does find out, But I find myself +at a loss.(Depressed) + +} + + =========================================================================== + Well, do you know the VAGUE AREA you lost it? { + (Depressed) + No, I was carrying it for him all the way from where he + had it stored in Lumbridge. It must have slipped from my + pack during the trip, and you know what people are like +these days... + +> + +Someone will have just picked it up and kept it for +themselves. + } + + I can make a new sword if you like... { + //TODO knights sword + } + + + + Well, the kingdom is fairly abundant with swords... { + Yes. You can get bronze swords anywhere, But THIS isn't + any old sword. + > + The thing is, this sword is a family heirloom. It has been + passed down through Vyvin's family for five generations! + It was originally made by the Imcando dwarves, who were + > + a particularly skilled tribe of dwarven smiths. I doubt + anyone could make it in the style they do. + } + + Well, I hope you find it soon. { + Yes, me too. I'm not looking forward to telling Vyvin I've + lost it. He's going to want it for the parade next week as + well. + [END] + } + + } + +} + +Wouldn't you prefer to be a squire for me? { + +No, sorry, I'm loyal to Sir Vyvin. (fine) + +} + +________________________________________________________ + +Silif + +Who are you? + +- - - +Who, me? Oh, no one, I assure you. No one that you want + to tangle with. +[end] + +_________________________________________________________ +Akrisae + +Hello, adventurer. + +--- + +Hello, cleric. (joyous) + [END] + + +___________________________________________________________ +Ambassador Spanfipple + +- - - + +It's all very white round here, isn't it? + +--- + +Well, it is the White Knight's Castle. + +- - - + +I think it would all look better in pink. At least then I + wouldn't be squinting all the time. +--- + +Yes, but then they'd have to become the Pink Knights. I + think they'd have some problems recruiting then. +- - - + +You're probably right. Maybe brown, then. + +--- + +I think that may be worse... +- - - + +Bah, humans have no sense of style... +[END] + +____________________________________________________________ + + +Sir Vyvin + +--- +Hello. + +- - - +Greetings traveller. + +--- + +Do you have anything to trade? { + + No, I'm sorry. + +} + +Why are there so many knights in this city? { + + We are the White Knights of Falador. We are the most + powerful order of knights in the land. We are helping the + king Valliance rule the kingdom as he is getting old and + tired. +} + +Can I just distract you for a minute? { + + Can I just talk to you very slowly for a few minutes, while + I distract you, so that my friend over there can do + something while you're busy being distracted by me? + + - - - + ... ...what? (confused) + + > + + I'm... not sure what you're asking me... you want to join + the White Knights? + + --- + + Nope. I'm just trying to distract you. (happy) + + - - - + + ... ...you are very odd. + + --- + + So can I distract you some more? + - - - + + ... ...I don't think I want to talk to you anymore. + --- + + Ok. My work here is done. 'Bye! + + [END] +} + +______________________________________________________________________ + +Sir Amik Varze + + +--- + +I seek a quest! + +I don't, I'm just looking around. + +Do you know anything about the seige of Falador? { + + +Ah yes, the Kinshra siege was a close-run thing indeed. (astonishment) + +> + +All hope seemed lost. Then she returned - Kara-Meir - with + Sir Theodore at her side. (happy talk) + +--- + +Sir Theodore? I haven't seen anyone of that name around here.(confused) +- - - + +No, you wouldn't have. He is...no longer with us. (remorsful bowing) + +--- + +Oh, I'm sorry. (sad) + +- - - +So am I, young man. So am I. +[END] + +_______________________________________________________________________ + +Woman (red head green skirt pink blouse) + +Hello. + +- - - + +Greetings! Have you come to gaze in rapture at the + natural beauty of Falador's parkland? (happy) +--- +Um, yes, very nice. Lots of... trees and stuff. + +- - - +Trees! I do so love trees! And flowers! And squirrels! + +--- + +Sorry, I have a strange urge to be somewhere else. (confused) + +- - - + +|force walk south of garden| + +Come back to me soon and we can talk about trees!(sad) + +--- + +...[END] + +____________________________________________________________________ +Ikis Krum + +--- + +Hello. + +- - - + +Good day, sir. What brings you to this end of town? (confused) + +--- + +Well, what is there to do around here? + +- - - + +If you're into Mining, plenty!! The dwarves have on of the +largest mines in the world just under our feet. There's an +entrance in the building just north-east of my house. + +> + +If you're one of these young, loud, hipster sorts you could + visit the Party Room, just north of here. That blasted + Pete parties all night and I never get any sleep!(pissed) + +--- + +Thanks. (confused) + + +______________________________________________________________________ +Town crier + +Hear ye!Hear ye! Player Moderators massive help to + RuneSc + +> + Oh, hello citizen. Are you here to find out about Player + Moderators? Or perhaps would you like to know about the + laws of the land? + +--- + +Tell me about Player Moderators. (confused) { + Of course. What would you like to know?(happy) + + --- (confused questions) + What is a Player Moderator? { + + Player Moderators are the normal players of the game, just + like you. However, since they have shown themselves to be + trustworthy and active reporters, they have been invited + by Jagex to monitor the game and take appropriate + + > + + action when they see rule breaking. You can spot a Player + Moderator in game by looking at the chat screen - when a + Player Moderator speaks, a silver crown appears to the + left of their name. Remember, if there's no silver crown + + > + + there, they are not a Player Moderator! You can check + out the website if you'd like more information. + + --- + Thanks!(happy) + }//fuck + + What can Player Moderators do? { + Player Moderators, or 'P-mods', have the ability to mute + rule breakers and Jagex view their reports as a priority so + that action is taken as quickly as possible. P-Mods also + have access to the Player Moderator Centre. Within the + + > + + Centre are tools to help them Moderate RuneScape. + These tools include dedicated forums, the Player + Moderator Guidelines and the Player Moderator Code of + Conduct. + --- + Thanks!(happy) + + } //not bad + + How do I become a Player Moderator? { + Jagex picks players who spend their time and effort to + help better the RuneScape community. To increase your + chances of becomming a Player Moderator: + > + + Keep your account secure! This is very important, as a + player with poor security will never be a P-Mod. Read our + Security Tips for more information. + + > + + Play by the rules! The rules of RuneScape are enforced + for a reason, to make the game a fair and enjoyable + environment for all. + + > + + Report accurately! When Jagex consider an account for + review they look for quality, not quantity. Ensure your + reports are of a high qualit by following the report + guidelines. + + > + + Be excellent to each Other! Treat others as you would + want to be treated yourself. Respect your fellow player. + More information can be found on the website. + + + --- + Thanks!(happy) + }//jesus christ + + What can Player Moderators not do? { + + P-Mods cannot ban your account - they can only report + offences. Jagex then take action based on the evidence + received. If you lose your password or get scammed by + another player, P-Mods cannot help you get your account + + > + + back. All they can do is recommend you to go to Player + Support. They cannot retrieve any items you may have lost + and they certainly do not recieve any free items + from Jagex for moderating the game. They are players + + > + + who give their all to help the community, out of the + goodness of their hearts! P-mods do not work for Jagex + and so cannot make you a Moderator, or recommend + other accounts to become Moderators. If you wish to + + > + + become a Moderator, feel free to ask me! + + + --- + Thanks!(happy) + }//$#%%^%%$^ Diabeetus + Something else. + + Is there anything else you'd like to know? (confused) + + Tell me about Player Moderators. + + Tell me about something else. + + No thanks. + +} + +Tell me about the Rules of RuneScape. (happy) +{ +At once. Take a look at my book here. +|does animation with book outward| +|player reads book| + + +} + +Can you give me a handy tip please? (happy) +{ +Did you know you burn food less often on the range in + Lumbridge castle than other ranges? + +Be careful when fighting wizards! Wearing heavy armour + can lower your magic resistance! + +Don't use your RuneScape password on other sites. Keep + your account safe! + +There are no cheats in RuneScape! Never visit websites + promising otherwise! + +Melee armour actually gives you disadvantages when using +magic attacks. It may be better to take off your armour + entirely! + + +} \ No newline at end of file diff --git a/dumps/530/gfxs.txt b/dumps/530/gfxs.txt new file mode 100644 index 0000000..dbdcb76 --- /dev/null +++ b/dumps/530/gfxs.txt @@ -0,0 +1,1700 @@ +0: Green blob shattering +1: single dragon breath +2: steel pickaxe +3: lumber +4: delright when defeated +5: Cyan/blue/green flames +6: rainbow ring goes upwards +7: spiraling rainbow +8: vines like at draynor manner ( they atk you ) +9: Iron arrow on ground +10: Bronze arrow on ground +11: Steel arrow on ground +12: Mithril arrow on ground +13: Adamant arrow on ground +14: Mithril Grapple +15: Rune arrow on ground +16: Ice arrow on ground +17: Fire arrow on ground +18: Iron arrows draw back +19: Bronze arrow draw back +20: Steel arrow draw back +21: Mith arrow draw back +22: Addy arrow draw back +23: Mithril Grapple +24: Rune arrow draw back +25: Ice arrow draw back +26: Fire arrow draw +27: Some type of bolt on ground +28: Puff of smoke +29: rotten tomatoe - projectile +30: rotten tomatoe - throw +31: rotten tomatoe - contact with target/White splash +32: Tiny rock +33: Tiny Rock +34: Black dart on ground +35: Iron throw axe +36: Bronze throw axe +37: Steel throwing axe +38: Mith throwing axe +39: Addy throwing axe +40: Puff of red smoke +41: Rune throwing axe +42: Iron throwing axe +43: Bronze throwing axe +44: Steel throwing axe +45: Mithril throwing axe +46: Adamant throwing axe +47: Green puff of smoke +48: Rune throwing axe +49: Spinning Vial +50: Moving Vial +51: Spinning exploding vial? +52: Moving exploding vial? +53: Boulder/stone +54: Giant orange blast +55: Gnome ball projectile +56: Yellow puff of smoke +57: Rope +58: Ball of lava +59: Nothing +60: Falling rocks +61: Nothing +62: Nothing +63: Nothing +64: Nothing +65: Spinning blue circles +66: Spinning brown circles +67: Rope going across river/long rope/pole shooting +68: huge water splash +69: huge water splash +70: Grey boulder/stone +71: Earth blast +72: Seagull/bird flying over you +73: Mud particles? +74: Random event/puff of smoke +75: Purple spikes +76: Saradomin strike +77: Claws of Guthix +78: Flames of Zamorak +79: 3 green blobs floating up +0: 'stun' birdies above head +81: bull roarer ( from legends quest ) +82: two purple squiggles in front of you, like what the spinners do in pest control +83: giant tentical - blood red +84: stars around you - monks healing +85: magic spell splash +86: puff of smoke, whan a random appears \ disapears +87: Iban's blast +88: iban blast - projectile skull +89: iban blast - contact with target +90: Weird tiny rocks (citadel teaser?) +91: Tier 3 Duelist Cap (blue skulls) +92: Tier 6 Duelist Cap (blue skulls/ghost) +93: Blue spirals +94: Blue spirals with yellow sparkles/stars +95: Guthix Arrow drawback +96: Saradomin Arrow drawback +97: Zamorak Arrow drawback +98: Guthix Arrow projectile +99: Saradomin Arrow projectile +100: Zamorak Arrow projecile +101: Bat staff emote +102: confuse cast +103: confuse projectile +104: confuse impact +105: Weaken cast +106: Weaken projectile +107: Weaken impact +108: Curse cast +109: Curse projectile +110: Curse impact +111: Brown spiral +112: Low alchemy +114: enchant low level necklace +115: enchant medium level necklace +116: enchant high level necklace +117: Cat staff emote +118: Dragon staff emote +119: Penguin staff emote +120: Wolf staff emote +121: Windstalker tier 5 (duelist stuff) +122: Windstalker tier 6 +123: Blue stuff +124: Double Guthix Arrow drawback +125: Double Saradomin Arrow drawback +126: Double Zamorak Arrow drawback +127: Green points spiraling upwards (Guthix) +128: Blue points spiraling upwards (Saradomin) +129: Red points spiraling upwards (Zamorak) +130: Shaking and breaking mysterious box (quest box from Falador) +131: Shaking mysterious box (quest box from Falador) +132: Clan citadel falling rock teaser +133: Lot of purple/pink circles that glow +134: Lightening and a purple/pink circle +135: Projectile for purple/pink circle thing +136: Lightening and a purple/pink circle +137: Rope +138: Rope +139: Prayer book +140: Prayer book projectile +141: Bones to Bananas +142: Telegrab cast +143: Telegrab projectile +144: Telegrab impact +145: Crumble Undead cast +146: Crumble Undead projectile +147: Crumble Undead impact +148: Super heat +149: Powering water orb +150: Powering air orb +151: Powering earth orb +152: Powering fire orb +153: Enchant necklace - 1 glow +154: Enchant necklace - 2 glow +155: Gold star sparkles +156: Prayer book +157: Prayer book projectile +158: Blue sparkles/puff of smoke, delay of about 4-5 secs +159: Prayer book +160: Prayer book projectile +161: Continuous splashes of sparkles/puffs of smoke, looks like water +162: Prayer book +163: Prayer book projectile +164: Blue sparkles/puff of smoke +165: Blue sphear with lightening? +166: Blue sphear with lightening, eventually popping +167: Vulnerability cast +168: Vulnerability projectile +169: Vulnerability impact +170: Enfeeble cast +171: Enfeeble projectile +172: Enfeeble impact +173: Stun cast +174: Stun projectile +175: Tiny rock/stone splitting/breaking +176: Vial with red thing? +177: Bind/Snare/Entangle cast +178: Bind/Snare/Entangle projectile +179: Entangle impact +180: Snare impact +181: Bind impact +182: Spear projectile - giant gnome cross-bow +183: Spear shattering - giant gnome cross-bow +184: Puff of smoke +185: Shooting star +186: runecrafting graphic +187: claws of guthix - yellow o.O +188: big puff of smoke, fatter lol +189: small puff of smoke, old detail +190: Blues splashes of something +191: massive teleport above head, round +192: enchanted vial - projectile +193: enchanted vial - pre-launch +194: BLACK SPELL - pre-launch +195: BLACK SPELL - projectile +196: BLACK SPELL - contact +197: Purple fire with orange flames +198: big blue and white wave spell contact +199: Fireworks ( when a lvl is gained ) +200: Bronze Javalin +201: Iron Javalin on ground +202: Steel Javalin on ground +203: Mithril Javalin on ground +204: Adamant Javalin on ground +205: Rune Javalin on ground +206: Bronze Javalin throw +207: Iron Javalin throw +208: Steel Javalin throw +209: Mithril Javalin throw +210: Adamant Javalin throw +211: Rune Javalin throw +212: Bronze knife on ground +213: Iron knife on ground +214: Steek knife on ground +215: black knife on ground +216: Mithril knife on ground +217: Adamant knife on ground +218: Rune knife on ground +219: Nothing +220: Nothing +221: Nothing +222: Nothing +223: Nothing +224: Nothing +225: Nothing +226: Bronze dart on ground +232-237: throwing darts graphics +238: enchant ring +239: barrel falling apart +240: exploding toad +241: filling toad with bellows +243: giant ogre arrow - draw back +244: elemental shield appearing +245: birdies above head +246: Dragon Battle Axe special (Original Animation) +247: blue purple glow - sara - Excaliber Special +248: Dragon Longsword SPECIAL +250: Magic Longbow SPECIAL +251: Dragon Mace SPECIAL +252: Dragon Dagger SPECIAL +253: Dragon Spear SPECIAL +254: Stun birdies again, from dragon spear special +255: green protection graphic - from morytania swamps +256: Magic Shortbow SPECIAL +257: steel throwing axe - different attack mode +258: Throwing Axe SPECIAL +259: same as 255 +263: smalls stars - silver sickle(b) +264: smalls stars 2 - silver sickle(b) +265: white ghost flys in air - ghasts - morytania swamps +266: big green blast - ghasts - morytania swamps +267: bright green puff of stuff +268: projectile - ghast atk's and you have a pouch - pouch attacks +269: first contact - goes with above +270: karamja agility course - poison darts +271: karamja agility course - falling rocks +274: Rune Claw SPECIAL +275: big rock flying away? o.O +277: "Zzz" l0l above your head +278: huge blue jaws in front - like bug jaws +279: small blue jaws above head - like bug +280: small white star projectile - like weaken ( instead of purple its white ) +281: small white star contact - same as above +282: Dragon Halberd SPECIAL - in front +283: Dragon Halberd SPECIAL - behind you o.O +284: Dragon Halberd SPECIAL - to your left +285: Dragon Halberd SPECIAL - to your right +286: big tar barrel - steaming +287: big tar barrel - EXPLOSION - awsomenesssss +291: more birdies +292: dim'ish flames of zammy +293: white ghost body - goes spread eagle - fades away +301: light teleport graphic +302: rocks falling on head +303: medium sized stone falling down on head +305: dark grey and greenish blast - ew +306: Dragon Dagger SPECIAL - in PURPLE - pimp +307: Completionist cape start +308: teleport graphic +309: spinning steel pickaxe +310: dust cloud around head +311: two blood red orbs go up then combine, almost like bones to bananas +325: broad arrow drawback +327: white stuff *looks like dandrif* falls out of air +328: slayer dart - projectile +329: slayer dart - contact +330: slayer dart - projectile - slightly better looking +331: slayer dart - contact - same as above - slight color change +332: Purple portal glow +333: redish looking special att thing that is all around you and rises into the air? +334: small green glow +335: medium green glow +336: large green glow +337: white bar or something goes through you? +338: stick goes in air and falls +339: big splash - magic spell failure +340: Granite Maul special +341: Abyssal Whip SPECIAL +342: Teleother - person accepts teleport +343: Teleother - person casts on another player +344: Teleblock - Projectile +345: Teleblock - Contact on target +346: um.. fire blast with a ring around it? +347: Dragon Scimitar SPECIAL +348: once again.. birdies +349: "Zzz" tired thing +350: Flock of black birds +351: zombie jumps in the air and lands and looks forward +352: zombie laying down - jumps up - lands and looks forward +353: white transparent cylinder above head +354: two puffs of smoke above head, join together and go down body +358: Breathe fire +359: huge air wave - contact +360-361: Ancients - Ice Rush +362-363: Ancients - Ice Burst +364: Snow emote +365: Storm emote +366-368: Ancients - Ice Blitz +369: Ancients - Ice barrage (normal) +370: Ancients - Ice barrage (huge) +373-377: Ancients - Blood Spells +378-382: Ancients - Shadow Spells +383-391: Ancients - Smoke Spells +392: Ancients - Teleport +393: KBD: red projectile +394: KBD: green projectile +395: KBD: white projectile +396: KBD: blue projectile +398: Guthan Special +399: Torags Special +400: Ahrims Special +401: Karils Special +402: green puff of smoke +405: dark green rocks falling +406: Huge rock falls on you +409: Abyssal demons teleport +410: small water drops +412: Big Apple barrel lol +413: Big Rotten Apple barrel +414: Big Apple barrel turns turns to mush +415: Big rotten apple barrel turns to much +416: Toad floating and spinning +417: toad exploding +418: blue toad floading a spinning +419: blue toad exploding +420: red toad spinning +421: red toad exploding +422: yellow toad spinning +423: yellow toad exploding +424: green toad spinning +425: green toad exploding +426: Stars spinning around head +427: something exploding, small peices +429: small bright green spell contact? +430: small bright red spell contact +431: small white spell contact +432: skeleton dying - bank robbery vid +433: old mans spell - bank robbery vid +434: old mans spell - same as above +435: old mans spell - same as above +436: Redemption prayer +437: Retribution prayer +438: miniature dragon fire breath - sprays on your buttocks +439: miniature dragon fire breath - originates from groin area +440: KBD - Big red ball +441: Retribution - going upward +442: Toktz-xil-ul( obby rings ) - projectile +444: Healing graphic from a monster in fight pits +445: 3 small fire gets shotting backward +446: fire coming down from sky ( not as exciting as you think ) +447: another fire from groin area effect +448: meteorite shotting forward +449: smaller fireball directed forward +450: even smaller fireball going forward +451: big meteorite crashing down on you +452: Onyx Ammy Enchanting? +453: fire +454: scanning area - from that quest +455: Ancients - Backwards Teleport +456: small splash +457-464: Butter churns lol +465: Huge North star-looking thing blinks above head +466: zombie (splitting in half) +467: zombie (head falls off) +468: releasing inner zombie +469: steam out of ears +470: small puddle thing +472: Bow special - WHITE? +473: Sparkling spinning arrow tip +474: colorless fireworks heading towards ground? +479: Dragon Hatchet special +480: big north star thing again +481: awsome red shock wave under +482: red rings around you +483: Dark Light special +486: bunny? +492: red starts spinning under you +497: two balls of fire on each side of you +498: big ball of fire under you +500: projectile water blast +502: water bolt contact +503: graphic from abyss thing +504: same as above +505: pink blast under you +506: bones to bananas graphic i think +507: Jump marionette: red +508: Walk marionette: red +509: Bow marionette: red +510: Dance marionette: red +511: Jump marionette: blue +512: Walk marionette: blue +513: Bow marionette: blue +514: Dance marionette: blue +515: Jump marionette: green +516: Walk marionette: green +517: Bow marionette: green +518: Dance marionette: green +519: in a door way +520: bones drop on you +524: white spikey ball under you? +521: Same As 520 Dif Color Bones +522: Same As 520, 521 Dif Color Bones +523: Same As 520, 521, 522, Dif Color Bones +524: White Spike Ball Pops +536: entering clan citadel blue portal +537: Smoke Projectile +538: Smoke Rize +539: Ice Block +540: Smoke Rize?? +541: Green Splash +542: Explosion +545: Barrow With A Lit Fuze +546: Fuze Lit +547: Barrow Explode +548: tiny white feather? +549: tiny white feather? +550: Green Balls... +551: Green Balls Spin +552: Green Balls Sonicly Explode +553: Red 550 +554: Red Flying +555: Nothing +556: MultiColors +557: MultiColors 2 +558: MultiColors 3 +559: Blood Spell Finish // dragon 2h special +560: Skeleton Chained Up? +563: Roasting Chicken On Rotater Over Fire +566: Roasting Pig Same As 563 +567: Smoke Cloud +568: Flowers above head +569: Flowers Around Player +570: Rolling Rock +571: Buncha Smoke Brown Colored +572: Hole opens In Ground +573: 572 shorter +574: Heart +575: Blue Sparkles Everywhere +576: Black Sparkles Everywhere +577: Mushroom Dude +578: Huge Mushroom Dude +579: Weired Fire Ball +580: Imp Teleport +581: Couldren Spinning +582: Explosion +583: Egg? Crack Open? +584: Egg? Lid Fall Off +585: egg +586: Egg lid +587: explosion +588: Huge Arrow? +589: bunch of arrows stuck into you? +590: Perminit Book +591: Perminit Book Vanish +592: Scroll? +593: Flowers +594: Jellow??? +595: IceCream Shake? +596: Yellow Whimsical Thing... +599: Bowl Of Food? +600: Nothing +601: White Rings +602: Cake? +603: White puff coming up +604: Grey swivels +605: Blue swivels +606: A bit like collecting fist of guthix things +607: Ghost flys upwards +608: Man turns to ash +609: Er, lantern? +610: Jester box opening (house) +611: Jester box closing (house) +612: Hoops (house) +613: white puffy slash? +614: white balls come together +615: Spike trap coming up (house) +616: Snare trap coming up (house) +617: Plant trap coming up (house) +618: Plant trap going down (house) +619: Plant trap struggle (house) +620: Marbles? (lol) +621: Marbles? (lol) +622: Splah from falling into swamp (house) +623: Sparkles from jester? Dunno +624: Using bones on an altar (prayer) +625: Puddle? +626: Flashing portal/glow +627: Yellow blob +628: Nothing? +629: Splash +630: Nothing? +631: Demon head lol +632: Kenith dying (rift in varrock) +633: Nothing? +634: Nothing? +635: Nothing? +636: Nothing? +637: Nothing? +638: Nothing? +639: Nothing? +640: Nothing? +641: Nothing? +642: Nothing? +643: Nothing? +644: Nothing? +645: Nothing? +646: Nothing? +647: Nothing? +648: Nothing? +649: Nothing? +650: Nothing? +651: Nothing? +652: Nothing? +653: Nothing? +654: Nothing? +655: Nothing? +656: Nothing? +657: Sepia line +658: Turmoil?? +659: Explosion +660: Explosion wire projectile +661: wilderness obelisk teleport +662: bubbles? +663: black dots? +664: pot with lid, explodes +665: lightning? +666: Molly machine grabber +667: Nothing +668: swirley grey smoke +669: rope splitting?? +670: rope closing?? +671: glow +672: rock falls +673: rock falls +674: rock falls +675: rock falls +676: green blob +677: very quick black and red thing +678: blue glow +679: spikey ball from warriors guild catapult +680: anvil from warriors guild catapult +681: blades from warriors guild catapult +682: orange ball from warriors guild catapult +683: blue bubbles +684: Kegs falling from failing the keg thing in warriors guild +685: Kegs falling from failing the keg thing in warriors guild +686: Kegs falling from failing the keg thing in warriors guild +687: Kegs falling from failing the keg thing in warriors guild +688: Kegs falling from failing the keg thing in warriors guild +689: tiny puff of smoke +690: rock. +691: H.A.M member fading out +692: bowl breaking +693: zanik shooting from crate +694: zanik's crossbow +695: cloak with bones? +696: bone bolt +697: bone bolt +698: bone bolt +699: purple spinning balls +700: brown spinning balls +707: very weird smoke +709: red monkey +710: blue monkey +712: light bulb/idea emote +713: stomp emote +715: white box with brown beads (teleport) +721: bubble maker +723: brain in a jar +725: white vengeance skull +726: red vengeance skull +731: puff of smoke +735: grapple +738: vecnas skull +739: explosion +757: hole with zombies hands? +760: mithril grapple +761: clan tree marker thing disappearing +762: clan tree marker thing appearing +763: low alchemy by hand +764: high alchemy by hand +767: cactus plant thing comes up over you (teleport) +768: grand tree pod (teleport) +769: cactus plant thing comes up over you (teleport) +780: dramatic point emote +785: dark meyer quest thing, blood +799: communicator/telecom orb thing? +800: Home teleport circle drawing +801: Home teleport circle finished +802: Grab book +803: Start Teleporting +804: Outer rim of home port final step +805: CRASHS CLIENT - UNKNOWN +806: Training Bow Arrow pullback +807: Electric chair +808: Electric chair +809: Elemental Shield, pulse brown +810: Elemental Helmet, don't know brown +811: Elemental Helmet, don't know purple +812: Fletching Skillcape +813: Magic Skillcape +814: Mining Skillcape +815: Smithing Skillcape +816: Quest cape +817: Runecrafting Skillcape +818: Crafting Skillcape +819: Fishing Skillcape +820: Construction Skillcape +821: Cooking Skillcape +822: Woodcutting Skillcape +823: Attack Skillcape +824: Defence Skillcape +825: Farming Skillcape +826: Thieving Skillcape +827: Slayer Skillcape +828: Strength Skillcape +829: Prayer Skillcape +830: Agility Skillcape +831: Firemaking Skillcape +832: Ranged Skillcape +833: Hitpoint Skillcape (male) +834: Hitpoint Skillcape (female) +835: Herblore Skillcape +836: Dragonplatelegs drop model +837: Walking Troll +838: Running Troll +839: Spinning Vines/Bush - Tai bwo wanni cleanup maybe +840: Spinning Rake head +841: Dropping dirt +842: Handing over a(n) 'Vial' +843: Hold up, then put to side 'Vial' +844: Dump 'Vial' contents on floor +845: Hold up the empty 'Vial' +846: Rake, then break the rake top, hold stick up +847: Rake Stick, moves forward +848: Flies, flying around head +849: Bucket, scoops something, then vanishes +850: Throwing Troll rock throw? +851: Drunken Dwarf, Backflip +852: Drunken Dwarf Backflip cont. +853: Beer drop model +854: Kebab drop model +855: Dirt flies into the air +856: Rolling boulder +857: Boulder toss +858: Small white water splash +859: Rhudolf red nose (EMOTE GFX) +860: Falling snow +861: undescribable +862: Snow crushes and falls +863: Penance Healers poison smog attack +864: Penance Healers healing smog attack +865: Penance Rangers hit gfx/endgfx +866: Penance Rangers projectile +867: Green Egg explosion +868: Red Egg explosion +869: Blue Egg explosion +870: Penance Queens attack projectile, purple ring +871: Penance Queens hit gfx/endgfx +872: Penance Queen hit gfx/endgfx cont. +873: Green Egg splurt, when bad pickup for collector +874: Red Egg splurt, when bad pickup for collector +875: Blue Egg splurt, when bad pickup for collector +876: Green Egg Explosion / Same as 867 +877: Hot Air Balloon, letting it float away, let it go +878: Hot Air Balloon, flying +879: Hot Air Balloon on fire, and falls +880: Hot Air Balloon fly upwards +881: Hot Air Balloon floating +882: Hot Air Balloon flying, then bursts into fire and falls +883: Yellow Hot Air Balloon fly upwards +884: Yellow Hot Air Balloon floating +885: Yellow Hot Air Balloon flying, then bursts into fire and falls +886: Blue Hot Air Balloon fly upwards +887: Blue Hot Air Balloon floating +888: Blue Hot Air Balloon flying, then bursts into fire and falls +889: Red Hot Air Balloon fly upwards +890: Red Hot Air Balloon floating +891: Red Hot Air Balloon flying, then bursts into fire and falls +892: Orange Hot Air Balloon fly upwards +893: Orange Hot Air Balloon floating +894: Orange Hot Air Balloon flying, then bursts into fire and falls +895: Green Hot Air Balloon fly upwards +896: Green Hot Air Balloon floating +897: Green Hot Air Balloon flying, then bursts into fire and falls +898: Purple Hot Air Balloon fly upwards +899: Purple Hot Air Balloon floating +900: Purple Hot Air Balloon flying, then bursts into fire and falls +901: Pink Hot Air Balloon fly upwards +902: Pink Hot Air Balloon floating +903: Pink Hot Air Balloon flying, then bursts into fire and falls +904: Black Hot Air Balloon fly upwards +905: Black Hot Air Balloon floating +906: Black Hot Air Balloon flying, then bursts into fire and falls +907: Hunter Skillcape Emote +908: Regular Chinchompa projectile range +909: Red Chinchompa projectile range +910: Using/Releasing a butterfly - Black w/ swirling vortex +911: Using/Releasing a butterfly - White w/ swirling vortex +912: Using/Releasing a butterfly - Blue w/ swirling vortex +913: Using/Releasing a butterfly - Red w/ swirling vortex +914: Using/Releasing a butterfly - Black no vortex +915: Using/Releasing a butterfly - White no vortex +916: Using/Releasing a butterfly - Blue no vortex +917: Using/Releasing a butterfly - Red no vortex +918: Falconry - bird float off a bit +919: Falconry - bird float off a bit +920: Falconry - bird float off a bit +921: Falconry - bird float off a bit +922: Falconry - bird flying projectile +923: Falconry - bird landing after good catch +924: Falconry - bird landing after failed catch +925: Falconry - bird landing after failed catch +926: Falconry - bird landing after failed catch +927: Falconry - bird landing after failed catch +928: Brown hopping kebbit body +929: Black hopping kebbit body +930: Tan hopping kebbit body +931: White puff of smoke fly upwards +932: Imp getting caught by imp trap +933: Pitfall trap +934: Pitfall trap +935: Pitfall trap +936: Pitfall trap +937: Polar sabre tooth falling into pitfall +938: Polar sabre tooth jumping over pitfall +939: Larupia falling into pitfall +940: Larupia jumping over pitfall +941: Graahk falling into pitfall +942: Graahk jumping over pitfall +943: Rabbit walking/running +944: Rabbit caught by rabbit snare +945: Rabbit caught by rabbit snare +946: Rabbit caught by rabbit snare +947: Brown hopping kebbit body +948: Brown hopping kebbit body +949: Polar kebbit hopping body +950: Yellow/tan kebbit hopping body +951: Spiked kebbit hopping body +952: Dragon Fire Breath / regular +953: Dragon Fire Breath / darker color +954: exploding, star looking, dragon, breath +955: Crossbow bolt shooting +956: Bird statue +957: Bird statue +958: Bird statue +959: Bird statue +960: Bird above your head, looks like smaller version of statue +961: Bird statue +962: Bird statue, facing South, positioned south +963: Bird statue, facing North, positioned north +964: Bird statue, facing North, positioned south +965: Giant kebbit, hopping, brown +966: Giant kebbit, standing, brown +967: Sleeping, zZzZzZ, Sleeping cap +968: UNKNOWN - looks like a rolling pink diamond looking thing +969: Big blue orb, shrinks downwards +970: Green projectile +971: Green projectile endGfx, hit, explosion +972: Hold up Ghost Speak amulet, then looks like wield it +973: Hold up undead chicken (green, sick looking) +974: Puff of black smoke, looks like Egg Exploding in Barbarian Assault +975: Cool looking implosion, unknown (Maybe Omega egg explosion) +976: Yellow spike projectile, has a smoke trail +977: Green Egg projectile, spinning +978: Red Egg projectile, spinning +979: Blue Egg projectile, spinning +980: Omage Egg Projectile, spinning +981: Confused Birds above head +982: Looks like a 'bolt of lightning'(it's black) hitting the ground +983: Looks like, "low alch" but the GFX is black +984: Black Vortex above head, Spiked black stars floating downwards +985: Black explosion, looks like a bolt spell hit/endGFX +986: Black Spiked Star falling +987: Scared Swarm floating upwards / Harbie bugs +988: Scared Swarm/Harpie Bugs, GIANT swarm float upwards and expand +989: Scared Swarm/Harpie Bugs, regular swarm float upwards and expand +990: Scared Swarm/Harpie Bugs, regular swarm float downwards and shrink +991: Scared Swarm/Harpie Bugs, GIANT swarm float downwards and shrink +992: Scared Swarm/Harpie Bugs, float downwards +993: Small bug/orb float and disappear +994: Giant Arrow Throw/shot +995: Giant Arrow projectile +996: brown gfx, orb looking, unknown +997: red gfx, orb looking, unknown +998: Stun/Vulnerability/Enfeeble, player start GFX +999: Green orb(s), big, they fly inwards and shrink +1000: Green orb(s), big, they just stay there +1001: Green orb(s), big, looks like it hits a wall? +1002: Giant red orb with red tentacles coming out ot it +1003: 2 red orbs on both hand sides, with tentacles coming out of it +1004: BORK, growing +1005: BORK, looks like a statue of him breaking +1006: Yellow orb(s), big, they fly inwards and shrink +1007: Yellow orb(s), big, they just stay there +1008: Yellow orb(s), big, looks like it hits a wall? +1009: 2 purple orbs on both hand sides, with tentacles coming out of it +1010: Giant purple orb with tentacles coming out of it +1011: Giant purple orb with tentacles, expands and disapears +1012: Enchanting a necklace, ISN'T the original one +1013: Giant red orb with tentacles coming out of it +1014: Falling Ice shard, penguin quest/island +1015: Enter clockwork penguin suit +1016: Leave clockworkpenguin suit +1017: 2 Ice shard projectiles +1018: Snow chunks flipping +1019: Snow particles flipping, looks like someone digging and tossing snow +1020: Juggling 3 balls, one red, one blue, one green (jester controls, neitiznot quest, fremmy isles) +1021: UNKNOWN +1022: Throwing a giant ice ball? +1023: CRASHS CLIENT - UNKNOWN +1024: Flying human leg, spinning - Soul's Bane +1025: UNKNOWN - looks like a pulsating web +1026: Circular water puddle below feet, pulsating, water drops floating upwards +1027: Barrelchest Anchor special GFX +1028: Explosion, with a puff of smoke +1029: Insects outer body shedding, like Kalphite Queens first form +1030: An animal, looks like it dies, UNKNOWN +1031: An animal, looks like it dies, UNKNOWN +1032: An animal, looks like it dies, UNKNOWN +1033: An animal, looks like it dies, UNKNOWN +1034: Dorgshenkan Teleporting, breaking a teleport ORB +1035: Bouncing red, ball looking thing +1036: Mithril Grapple, about to shoot +1037: Yellow Orb, with spiky trail, shoots into a piece of paper your holding +1038: Yellow Orb, runes show above it, then get sucked into it, then disapears +1039: Rabbit, floats upward slowly, then disapears (Rabbit egg?) +1040: Blue Easter egg breaks open +1041: Blue Easter egg breaks open +1042: Green Easter egg breaks open +1043: Red Easter egg breaks open +1044: Pink/Purple Easter egg breaks open +1045: Yellow Easter egg breaks open +1046: UNKNOWN - Can't see it +1047: Easter Basket by your side +1048: Brine Sabre, special attack GFX +1049: Arrow shoots into the ground form a high height, then disapears +1050: Arrow with purple feathers, pullback GFX +1051: Arrow with purple feathers, projectile +1052: Ancient Mace, special attack GFX +1053: Arrow with purple feathers, UNKNOWN +1054: Transparent brown orb forms infront of you +1055: Kalphite Queen first form, outer shell breaking, after death +1056: Sleeping, zZzZzZzZ +1057: A snow hole forms below you, looks like a burrow +1058: A snow hole forms below you, looks like a burrow +1059: Stat Spy GFX +1060: Stat Spy GFX +1061: Humidify GFX +1062: Spellbook Swap GFX +1063: Plankmake GFX +1064: Transparent purple slime falls, then forms The Inadequacy +1065: Transparent purple slime expands, and pulses, then forms The Inadequacy +1066: The Inadequacy magic Attack +1067: The Inadequacy magic projectile +1068: The Inadequacy Death GFX +1069: A Doubt - It's spawning GFX +1070: A Doubt - when it teleports +1071: Transparent slime, forms into The Everlasting +1072: The Everlasting Death GFX +1073: The Illusive Death GFX +1074: Make Hunter Kit +1075: UNKNOWN +1076: UNKNOWN +1077: Brown hole forming below you +1078: A beat spinning +1079: Werewolf transformation +1080: Werewolf transformation +1081: Werewolf transformation +1082: Werewolf transformation +1083: Werewolf transformation +1084: Werewolf transformation +1085: Werewolf transformation +1086: Werewolf transformation +1087: Werewolf transformation +1088: Werewolf transformation +1089: Werewolf transformation +1090: Werewolf transformation +1091: Werewolf transformation +1092: Werewolf transformation +1093: Werewolf transformation +1094: Werewolf transformation +1095: Werewolf transformation +1096: Werewolf transformation +1097: Werewolf transformation +1098: Werewolf transformation +1099: Dark Bow dragon arrow special attack GFX +1100: Dark Bow arrow impact small black explosion, endGFX/hit +1101: Dark Bow arrow smoke trail +1102: Dark Bow arrow smoke trail +1103: Dark Bow arrow impact smoke hit, endGFX/hit +1104: Double Arrow pullback - Bronze Arrows +1105: Double Arrow pullback - Iron Arrows +1106: Double Arrow pullback - Steel Arrows +1107: Double Arrow pullback - Mithril Arrows +1108: Double Arrow pullback - Adamant Arrows +1109: Double Arrow pullback - Rune Arrows +1110: Double Arrow pullback - Ice Arrows +1111: Double Arrow pullback - Dragon Arrows +1112: Double Arrow pullback - Broad Arrows +1113: Double Arrow pullback - Fire Arrows or something +1114: Double Arrow pullback - Fire Arrows or something +1115: CLIENT CRASH - UNKNOWN +1116: Single Arrow pullback - Dragon Arrow +1117: Sachel emote +1118: Teleport to Impetuous Implings Minigame - Wheat Field beam +1119: Impling teleporting to a different location GFX - White smoke puff +1120: Dragon Arrow w/ Fire projectile +1121: Dragon Arrow w/ Fire projectile +1122: UNKNOWN - makes character turn invisible for a second +1123: Dragon Dart throwing +1124: Impling jar breaking w/ impling inside +1125: Impling jar breaking w/ impling inside +1126: Impling jar breaking w/ impling inside +1127: Impling jar breaking w/ impling inside +1128: Impling jar breaking w/ impling inside +1129: Impling jar breaking w/ impling inside +1130: Impling jar breaking w/ impling inside +1131: Impling jar breaking w/ impling inside +1132: Impling jar breaking w/ impling inside +1133: Impling jar breaking w/ impling inside +1134: Exchanging an impling jar w/ impling inside +1135: Exchanging an impling jar w/ impling inside +1136: Exchanging an impling jar w/ impling inside +1137: Exchanging an impling jar w/ impling inside +1138: Exchanging an impling jar w/ impling inside +1139: Exchanging an impling jar w/ impling inside +1140: Exchanging an impling jar w/ impling inside +1141: Exchanging an impling jar w/ impling inside +1142: Exchanging an impling jar w/ impling inside +1143: Exchanging an impling jar w/ impling inside +1144: Spinning impling jar w/ impling inside +1145: Spinning impling jar w/ impling inside +1146: Spinning impling jar w/ impling inside +1147: Spinning impling jar w/ impling inside +1148: Spinning impling jar w/ impling inside +1149: Spinning impling jar w/ impling inside +1150: Spinning impling jar w/ impling inside +1151: Spinning impling jar w/ impling inside +1152: Spinning impling jar w/ impling inside +1153: Spinning impling jar w/ impling inside +1154: Burst of Fire below your feet - looks amazing! +1155: Fireball GFX +1156: Pet Rock - +1157: Pet Rock - Throw Stick +1158: Throwing the Stick projectile +1159: Stick falling and hitting the ground GFX, disapears +1160: Dragonfire Shield - swirling fire around the shield, looks like its charging +1161: Dragonfire Shield - swirling fire around the shield, looks like its charging +1162: Dragonfire Shield - swirling fire around the shield, looks like its charging +1163: Dragonfire Shield - swirling fire around the shield, looks like its charging +1164: Dragonfire Shield - swirling fire around the shield, looks like its charging +1165: Dragonfire Shield - Sucking in fire, getting ready to shoot projectile +1166: Dragonfire Shield - projectile +1167: Dragonfire Shield - burst from the shield +1168: Dragonfire Shield - small swirling fire +1169: Lighting a log with a stick and some rope, log lights on fire (barbarian firemaking) +1170: Some bouncing red looking thing, circular LOOKS like a cupcake +1171: Wierd green vines doing a, very, buggy looking animation +1172: Picks up 2 parts of a 'bowl' and throws it behind yourself +1173: Fire erupts from the ground upwards, till above the character +1174: Completionist cape, middle +1175: Completionist cape, end +1176: Red swirling GFX encircles the character +1177: Green swirling GFX encircles the chacracter +1178: Broken Pest Control Barricades +1179: Green something like glass, falls downwards +1180: Giant circle of white smoke, like something vanished +1181: Changing character clothes, dressing room falls downward +1182: Changing character clothes, dressing room stays still +1183: Changing character clothes, dressing room disappears +1184: Saradomin: Minion: Growler: Start of it's magic attack GFX +1185: Saradomin: Minion: Growler: Projectile +1186: Saradomin: Minion: Growler: endGFX/hit GFX +1187: Yellow 'Guthix Claws' grab below your feet +1188: Saradomin: Minion: Bree: Ranging Projectile +1189: Zamorak: Minion: Lava spot opens below you, and fire spews upwards +1190: Armadyl: Minion: Aviansie javelin projectile +1191: Armadyl: Minion: Aviansie throwing-axe projectile +1192: Armadyl: Minion: Aviansie Dual Javelins, look like on fire +1193: Looks like a brown fog around your head +1194: Saradomin: Zilyana: Magic based: Lightning GFX - Sarasword GFX +1195: Bandos Minion: Ranger: Throwing axe projectile +1196: Armadyl: Kree'ara: Blue/lightning spinning tornado +1197: Armadyl: Kree'ara: Brown/white spinning tornado +1198: Armadyl: Kree'ara: Blue spinning tornado +1199: Armadyl: Minion: UNKNOWN +1200: Bandos: Graardor: Ranging projectile +1201: Nex stuff +1202: Bandos: Minion: Magic start GFX +1203: Bandos: Minion: Magic projectile +1204: Nex stuff +1205: Bandos: Minion: Ranger minion GFX, looks like the NPC +1206: Bandos: Minion: Throwing axe projectile +1207: Wierd lightning pattern +1208: Like something slid in the snow +1209: Rolling snowball +1210: Zamorak: K'ril: Ranging start GFX +1211: Zamorak: K'ril: Ranging projectile +1212: Zamorak: Minion: Mage start GFX +1213: Zamorak: Minion: Mage projectile +1214: Blue sword uppercut, looks like saradomin special, but isn't +1215: Nex stuff +1216: Nex stuff +1217: Nex stuff +1218: Bandos: Graardor: smash, small +1219: Bandos: Graardor: smash, big +1220: Saradomin Godsword special attack +1221: Zamorak Godsword special attack +1222: Armadyl Godsword special attack +1223: Bandos Godsword special attack +1224: Saradomin Sword special attack, PLAYER +1225: Looks like Dragon 2h special, small red smash into the ground +1226: Crossbow bolt shot, plays it 2 times +1227: 4 white rings, pulse, looks like Growlers mage attack +1228: Teleporting with the Grand Tree GFX Start +1229: Teleporting with the Grand Tree GFX End +1230: Teleporting using a Grand Tree Pod Start +1231: 2 Spheres, white, look like lightning // Looks random +1232: Teleporting using a Grand Tree Pod End +1234: Throwing Dart - Bronze +1235: Throwing Dart - Iron +1236: Throwing Dart - Steel +1237: Throwing Dart - Black +1238: Throwing Dart - Mithril +1239: Throwing Dart - Adamant +1240: Throwing Dart - Rune +1241: Spinning green looking thing, projectile //Looks random +1242: Throwing Dart - Dragon +1243: An explosion, makes a greenish white sphere, and a spikey looking explosion +1244: Zombie Hand - Emote Tab +1245: A Fish, flys downwards, then flys back upwards +1246: Green circular ring forms below you +1247: Assist Levels +1248: Goblin sprouting up +1249: Goblin sprouting up +1250: Goblin sprouting up +1251: Goblin sprouting up +1252: Goblin sprouting up +1253: Goblin sprouting up +1254: Goblin sprouting down +1255: Goblin sprouting down +1256: Goblin sprouting down +1257: Goblin sprouting down +1258: Goblin sprouting down +1259: Goblin sprouting down +1260: White rings with yellow lines pouring down +1261: White rings with yellow lines pouring down +1262: White rings spinning +1263: Tiny white lines beneath feet +1264: Red lines hit and form a target +1265: Blue circle above you and rains down +1266: Blue lines +1267: White and green lines forming a bow +1268: Green arrow +1269: White scattering ash? +1270: White brushes? +1271: Cloud of smoke +1272: White explosion +1273: White sparkly ball flying +1274: Beams of light (rabbit hole area), Gravestone repair graphic. +1275: Blue squiggles form a dragon shape figure +1276: Puff of grey +1277: Puff of dark grey +1278: Bit of water +1279: Ice and topples over +1280: Gnome glider crashing (possibly MA) +1281: Short white blast +1282: Pelted snow melting off +1283: 2010 Snowman spinning +1284: Snow falling from snow globe +1285: snow globe continued +1286: snow globe continued +1287: Seal of approval white smoke +1288: Air spell +1289: Air spell +1290: White sword thing? +1291: White thing +1292: Snow going upwards +1293: Iron arrow +1294: Nothing +1295: White Familiar graphic +1296: Blue Familiar graphic +1297: White Familiar graphic +1298: White Familiar graphic +1299: Orange Familiar graphic +1300: White Familiar graphic +1301: White Familiar graphic +1302: Bronze Familiar graphic +1303: White Familiar graphic +1304: White Familiar graphic +1305: White Familiar graphic +1306: White Familiar graphic +1307: Orange Familiar graphic +1308: Green Familiar graphic +1309: Pink Familiar graphic +1310: Yellow Familiar graphic +1311: Brown Familiar graphic +1312: Brown smoke and a spade +1313: White Familiar graphic +1314: Small Blue summon familiar graphic +1315: Big Blue summon familiar graphic +1316: Fruit bat special +1317: Silver stars float down? +1318: Silver lines +1319: Small Blue summon familiar graphic +1320: Green orbs and lines +1322: Stars floating up +1333: Tornado +1334: Tornado Continued +1341: Confetti (for the confetti item) +1349: Gold Tornado +1350: Gold tornado, continued +1351: White ice stuff in circle on ground +1352: Two blackthingies projectiles +1353: Something "electric" in head, can't exactly see +1355: Purple ball rolling, projectile +1356: electric ball over head +1357: White ball at feet, projectile +1358: Light beams in different directions +1359: Stack of Green Squares spinning +1360: Green blocks smashing into something, wierd o.0 +1361: Light green ball slowly raising into air +1364: Shadow Sword Special :P +1365: Ice Beast next to you +1366: Ice Beast next to you +1367: "" similar to above +1368: Blue thingy comes from ground to surrond you +1369: Ice beast attacking +1384: Making cheese wheel +1390: Fire works blow around you? +1391: Invoke spring +1393: Raining Fire on you +1414: Spinning Turtle Shell then goes flying +1415: Smaller turtle shell projectile +1443: Some Titan (summoning) +1450: Flashing big skeleton thing? +1458: Beaver Cutting Down tree +1459: "" same as above +1463: Raining Flames +1466: Classic Cape +1447: Classic Cape +1471: Classic Cape +1499: Pest Control Portal +1500: Portal +1501: pest control creature +1502: Portal +1503: Portal +1504: Summoning, big +1512: tele into mini? +1515: Summoning skillcape emote +1516: Fairy rings teleport +1521: white seagals +1524: dug hole +1525: dug hole +1529: platypus thing diving and retrieving a chest +1530: platypus thing diving and retrieving an oyster +1523: baby platypus thing diving and retrieving a chest +1530: platypus thing diving and retrieving an oyster +1533: Safety first emote +1537: Air guitar +1541: Farming minigame (minesweeper) placing flag +1544: Zombie hand +1545: Zombie hand +1549: loads of tiny blue squares surround you +1551: Crack +1552: Fairy rings teleport +1554: safety first emote +1566: Chocatrice cape easter egg emote +1567: Player transforms into a rabbit/bunny +1576: Normal teleport, upwards +1577: Normal teleport, downwards +1578: King (yeti guy) growing +1579: Yeti (king guy) growing +1584: Fists of guthix, earning point rings +1585: Taking damage in fist of guthix +1587: Big ice block breaks +1594: Mime spotlight +1586: Winning fist of guthix +1604: Sickle Enchantment +1605: Imp relocation +1606: Pink spotlight +1607: White bead being picked up and thrown +1608: Green/white spotlight +1609: White bead being picked up and thrown +1610: Cat being lifted and moved +1611: Cat being lifted and moved +1612: Cat being lifted and moved +1613: Cat being lifted and moved +1614: Cat being lifted and moved +1615: Cat being lifted and moved +1616: Rocks pulled together? +1617: Lava rock +1618: Circle of fire and flames burst up +1619: Red to orange bubbles +1620: Red to orange bubbles +1621: Pelting stars? +1622: jad fight caves 360 atk +1623: Tzhaar +1624: Tzhaar +1625: Jad stomp +1626: Jad rock +1627: Jad rock +1628: Jad something lol +1629: Rocks shattering +1630: Small blue rocket speeding across floor (New level 99 graphics) +1631: Bigger blue rocket speeding across floor (New level 99 graphics) +1632: Blue Rocket speeding across floor (New level 99 graphics) +1633: Blue rocket flying upwards (New level 99 graphics) +1634: Sparkly blue rocket flying upwards (New level 99 graphics) +1635: Sparkles (New level 99 graphics) +1636: Sparkles and confetti (New level 99 graphics) +1637: Sparkles and falling stars (New level 99 graphics) +1638: Big red circle thing/pit curse +1639: Smaller red circle thing +1640: Fire and a burnt cockroach thing (those things in desert) +1641: Red thing +1642: Red thing +1643: Red thing +1644: Banshee head being used on red wall +1645: Coffin opening and shutting +1678: Green tele up +1679: Green tele down +1680: Tablet teleport +1681: Ancients teleport +1682: Lyre Teleport +1683: Skull Sceptre teleport +1684: Dueling Ring teleport +1685: Lunar teleport +1687: teleport +1688: Ectofungus teleport +1689: Monkey Madness teleport +1691: alch +1692: low alchemy +1693: high alchemy +1694: Crude Wood Chair (alch) +1695: Crude Wood Chair (alch) +1694: Wooden Chair (alch) +1695: Wooden Chair (alch) +1695: Rocking Chair (alch) +1694: Oak Chair (alch) +1695: Oak Chair (alch) +1694: Oak ArmChair (alch) +1695: Oak ArmChair (alch) +1694: Teak Chair (alch) +1695: Teak Chair (alch) +1694: Mahogany ArmChair (alch) +1695: Mahogany ArmChair (alch) +1694: Wooden Dining Bench (alch) +1694: Oak Dining Bench (alch) +1694: Carved Oak Dining Bench (alch) +1694: Carved Teak Dining Bench (alch) +1694: Mahogany Dining Bench (alch) +1694: Gilded Mahogany Dining Bench (alch) +1694: Oak Throne (alch) +1694: Teak Throne (alch) +1694: Mahogany Throne (alch) +1694: Gilded mahogany Throne (alch) +1694: Skeleton Throne (alch) +1694: Crystal Throne (alch) +1694: Demonic Throne (alch) +1702: Kiss emote (original) +1729: korasi special attack +1731: Cabbage teleport (explorer's ring) +1732: Cabbage teleport (explorer's ring) +1733: Recharge run +1734: Explore emote +1735: Explore emote +1737: energy ball floats to you, disappears when close +1738: corporal beast eats summoning creature +1740: thunder thingy +1744: cage made of light +1745: purple bolts and white rings (teleport) +1746: ring around you floats up +1747: purple teleport ring thingy +1760: Puff of smoke, leaves a black aura (disappear emote) +1761: Head in sand emote +1762: Ghost emote +1763: Red aura thing +1764: Green aura thing +1765: Fireworks (deathcon) +1766: Living on borrowed time emote +1768: entering deathcon red portal +1767: coming out of deathcon red portal +1774: Runes floating around +1778: summoning bird going to find fruit or whatever +1781: Jugging balls +1782: Juggling balls fail +1783: Juggling knives +1784: Juggling knives fail +1785: Juggling torches +1786: Juggling torches fail +1787: Juggling cannonballs +1788: Juggling cannonballs fail +1789: Juggling plates +1790: Juggling plates fail +1791: Juggling soap +1792: Juggling soap fail +1793: Juggling spades +1794: Juggling spades fail +1795: Juggling tuna +1796: Juggling tuna fail +1797: Juggling eggs +1798: Juggling eggs fail +1799: Juggling chinchompas +1800: Juggling chinchompas fail +1801: Bronze arrow +1802: Nothing +1803: Tearing circus ticket +1817: coming out of deathcon red portal +1834: corp stomp +1835: Vesta's Spear +1836: Morrigan's javelin +1837: Morrigan's javelin projectile +1838: Morrigan's throwing axe +1840: Statius's warhammer +1847: purple, red and more around you? +1845: Miasmic Spell? +1847: Miasmic Spell? +1848: Puff of red smoke up and down +1849: Puff of red smoke up and down +1853: Miasmic Barrage +1854: Some Spell +1855: Morrigans javelin drawback +1856: Morrigans throwing axe +1864: Scare emote +1866: Dust broom emote +1890: Wierd black Thing +1896: Black Wierd thing comes down on you? +1897: Black Wierd thing comes down on you? +1898: Death/Black skull swirl? +1901: dark energy +1918: Balance Elemental Range drawback +1932: While Guthix Sleeps/lummy caves strange light npc +1933: While Guthix Sleeps/lummy caves strange light creature/npc +1935: dark energy +1936: Balance Elemental rock drawback +1937: Balance Elemental rock projectile +1938: Balance Elemental rock impact +1939: Balance Elemental Magic drawback +1940: Balance Elemental Magic projectile +1941: Balance Elemental Magic impact +1943: balanced elemental +1944: Balance Elemental Battle entrance? +1946: Balance Elemental Death? +1950: dragon claw special +1964: falador shield pray restore +1965: falador shield 3 emote +1966: falador shield 1 emote +1973: Freeze emote +2000: Blue swirl +2001: Blue and White Swirling at feet, spell? +2002: Breaking Glass ball (Dorguushun teleport) +2003: Dorguushun teleport +2004: Dorguushun teleport +2006: electric portal +2007: bluish spike thingy +2008: corp stomp on wall +2009: wind blowing round you +2011: wind blowing round you +2015: blue shield with blue oval bouble +2018: broken black bouble thing +2019: black explosion +2021: black tele thing that opens up +2029: sand/bug type monster +2035: bunny take head off +2036: giant Easter egg +2037: Around the world in eggty days +2039: raining fire +2040: light portal comes up +2044: same as 2040 +2045: black spiral spike thingy falls down +2047: giant saws falling (skeletons?) +2048: Sleeping, zzz +2049: Penguin head floating +2050: Penguin sliding on ice +2051: explosion from beneath +2052: cannon +2053: cannon +2054: cannon +2059: giant chin(mb) +2060: Multi Color Squirl, then Puff of smoke +2061: Multi Color Squirl, then Puff of smoke +2062: tiny puff of smoke +2063: black dot? +2064: falling rocks? +2065: falling rocks? +2066: falling rocks? +2067: falling rocks? +2068: Dice +2069: Dice +2070: Dice +2071: Dice +2072: Dice +2073: Dice +2074: Dice +2075: Dice +2076: Dice +2077: Dice +2078: Dice +2079: Dice +2080: Dice +2081: Dice +2082: Dice +2083: Dice +2084: Dice +2085: Dice +2086: Dice +2087: Dice +2088: Dice +2089: Dice +2090: Dice +2091: Dice +2092: Dice +2093: Dice +2094: Dice +2095: Dice +2096: Dice +2097: Dice +2098: Dice +2099: Dice +2100: white slash +2101: purple lightening ball +2102: electrical shock and puff of smoke +2103: mithril grapple +2104: zamorak godsword ice special +2105: zamorak godsword ice special attack +2106: tiny arrow? +2107: arrow +2108: old abyssal whip special, red rings +2109: saradomin godsword special attack +2110: null +2111: null +2112: null +2113: armadyl godsword special attack +2114: bandos godsword special attack +2115: saradomin sword special attack +2116: zamorak spear/zamorakian spear special attack +2117: dragon sword special attack +2118: some sort of dragon special, idk +2119: icey colored magic projectile +2120: very quick icey colored ball +2121: very quick icey colored ball +2122: icey coloured splash +2123: sparks from an anvil +2124: nothing? +2125: nothing? +2126: white and black swirley ball? +2127: white swirley ball? +2128: white and black rings/spiral +2129: null +2130: white and black things +2131: white thing +2132: white thing +2133: hole appears with a hand dragging you in (teleport) +2134: hole appears with hand pushing you out (teleport) +2135: fire +2136: fire +2140: hand cannon explode +2141: hand cannon explode +2143: Hand cannon ball projectile +2144: red slash with explosion? +2145: Squirrel Ears (holiday reward item) +2146: ice +2147: puff of smoke +2148: fireball on floor +2149: rocks falling +2150: rocks falling +2151: guard turns to ash and falls +2152: null +2153: null +2154: null +2155: null +2156: weird stuff +2157: wooden planks +2158: wooden planks +2159: wooden planks +2160: wooden planks +2161: wooden planks +2162: wooden planks +2163: wooden planks +2164: wooden planks +2165: weird rainbowy/white thing +2166: streaks of light float upwards? +2167: colorful little balls with 2 big white balls +2168: colorful little balls with 1 big white ball +2169: streaks of light flush towards you? +2170: purple roots? +2171: null +2172: Ardougne Cape teleport +2173: ardougne cape teleport return +2174: Grand Tree teleport +2175: Grand tree return +2176: Ardougne Cape teleport +2177: ardougne cape teleport return +2177: null +2178: eek the spider +2179: eek the spider +2180: Throwing Eek the spider +2181: fire ball? +2182: purple ball +2183: purple spikey ball +2184: small flash of light +2185: medium flash of light +2186: large flash of light +2187: fire? +2188: purple fire? +2189: quick purple flames +2190: purple puff of smoke +2191: null +2192: null +2193: null +2194: null +2195: null +2196: null +2197: null +2198: null +2199: fire surge +2200: null +2201: fire surge +2202: fire surge +2203: fire surge +2204: fire rings +2205: yellow floating guy (explorer or something near piscatoris) +2213: Protect Item +2214: Sap Warrior Shoot +2215: Sap Warrior Projectile +2216: Sap Warrior Impact +2217: Sap Ranged Shoot +2218: Sap Ranged Projectile +2219: Sap Ranged Impact +2220: Sap Mage Shoot +2221: Sap Mage Projectile +2222: Sap Mage Impact +2223: Sap Spirit Shoot +2224: Sap Spirit Projectile +2225: Sap Spirit Impact +2226: turmoil +2227: Deflect Summoning +2228: Deflect Magic +2229: Deflect Ranged +2230: deflect melee +2231: Leech Attack Projectile +2232: Leech Attack Impact +2233: Leech Attack Impact +2236: Leech Range Projectile +2237: Leech Range Impact +2238: Leech Range Impact +2240: Leech Magic Projectile +2241: Leech Magic Impact +2242: Leech Magic Impact +2244: Leech Defence Projectile +2245: Leech Defence Impact +2246: Leech Defence Impact +2248: Leech Strength Projectile +2249: Leech Strength Impact +2250: Leech Strength Impact +2252: Leech Energy Projectile +2253: Leech Energy Impact +2254: Leech Energy Impact +2256: Leech Special Projectile +2257: Leech Special Impact +2258: Leech Special Impact +2263: Soulsplit Projectile +2264: Soulsplit Impact +2266: Berserker +2280: Green twirley vines? +2281: Green twirley vines? +2282: Green blast +2283: White mage projectile +2284: Barbarian assault defender icon +2285: Barbarian assault attacker icon +2286: Barbarian assault healer icon +2287: Barbarian assault collector icon +2288: Barbarian assault attacker and collector icon +2289: Barbarian assault defender and attacker icon +2290: Barbarian assault defender and collector icon +2291: Barbarian assault defender and healer icon +2292: Barbarian assault attacker and healer icon +2293: Barbarian assault collector and healer icon +2294: Barbarian assault collector, attacker and healer icon +2295: Barbarian assault collector, defender and healer icon +2296: Barbarian assault attacker, healer and defender icon +2297: Barbarian assault collector, attacker and defender icon +2298: Barbarian assault collector, attacker, healer and defender icon +2299: butterfly? +2300: butterfly? +2301: butterfly? +2302: butterfly? +2303: rock golem? +2304: rock golem? +2305: rock golem? +2306: rock golem? +2307: purple bubbles/sparkles +2308: rock golem pet? +2319: staff of light special +2320: staff of light special? +2321: Staff of light +2345: red stuff like blood barrage +2350: rune guardian +2391: blue spinning thingy that explodes +2393: crystals around ur legs +2436: orange explosion +2437: orange explosion +2437: white explosion +2442: Dungeoneering skillcape +2451: lighting around you +2400+: dungeoneering +2517: To Player Return (Dungoneernig teleport) +2516: To Player(Dungeoneering teleport) +2584: dungeoneering poison dropping +2602: Home (Dungeoneering teleport) +2603: Home Return (Dungoneering teleport) +2688: red castle wars smoke +2689: blue castle wars smoke +2691: teletab? +2692: effigy +2693: Void stares back ghost +2694: Void stares back ghost +2695: Void stares back ghost +2696: Void stares back ghost +2697: Void stares back ghost +2701: Water +2702: Water +2728: Fire +2713: Earth +2714: Earth +2715: Earth +2716: Earth +2717: Earth +2743: wise old man walking +2744: very large summoning graphic +2745: constitution skillcape male +2746: constitution skillcape female +2777: master dungeoneering cape +2778: master dungeoneering cape +2779: master dungeoneering cape +2780: master dungeoneering cape +2781: master dungeoneering cape +2782: master dungeoneering cape +2783: master dungeoneering cape +2792: leveling up to 99? +2795: korasi special attack +2837: Puppet master +2838: bone brooch +2845: blue light +2846: grey explode +2898: jadinko +2899: jadinko +2900: jadinko +2901: jadinko +2902: jadinko +2903: jadinko +2904: jadinko +2905: jadinko +2906: jadinko +2907: jadinko +2908: jadinko +2909: jadinko +2910: jadinko +2911: jadinko +2912: jadinko +2913: jadinko +2914: jadinko +2915: jadinko +2916: jadinko +2917: jadinko +2918: jadinko +2919: jadinko +2920: jadinko +2930: Task master emote +2931: magic carpet taking off +2932: magic carpet flying +2933: magic carpet landing +2952: golden cracker +2953: golden hammer twirl +2964: 10th anniversary cake +2969: Rope +2970: Rope +2971: Grand tree pod \ No newline at end of file diff --git a/dumps/530/music_location_unlocks.txt b/dumps/530/music_location_unlocks.txt new file mode 100644 index 0000000..902d9bf --- /dev/null +++ b/dumps/530/music_location_unlocks.txt @@ -0,0 +1,633 @@ +TrackDefinition [arrayId=0, trackset=Trackset: Varrock, , fileId=177, name=Adventure, unlock=at Varrock Palace.] +TrackDefinition [arrayId=1, trackset=Trackset: Kharidian, , fileId=50, name=Al Kharid, unlock=at Al Kharid.] +TrackDefinition [arrayId=2, trackset=Trackset: "Only defined", , fileId=102, name=Alone, unlock=at the Clock Tower Dungeon.] +TrackDefinition [arrayId=3, trackset=Trackset: Jungle, , fileId=90, name=Ambient Jungle, unlock=at Shilo Village.] +TrackDefinition [arrayId=4, trackset=Trackset: Kharidian, , fileId=36, name=Arabian, unlock=in the Kharidian Desert.] +TrackDefinition [arrayId=5, trackset=Trackset: Kharidian, , fileId=123, name=Arabian2, unlock=at Al Kharid mine.] +TrackDefinition [arrayId=6, trackset=Trackset: Kharidian, , fileId=124, name=Arabian3, unlock=at the desert entrance to the Kalphite Lair.] +TrackDefinition [arrayId=7, trackset=Trackset: Cave, , fileId=19, name=Arabique, unlock=at the hellhounds in Taverley Dungeon.] +TrackDefinition [arrayId=8, trackset=Trackset: Wilderness, , fileId=160, name=Army of Darkness, unlock=at the Dark Warrior's Fortress.] +TrackDefinition [arrayId=9, trackset=Trackset: Falador, , fileId=186, name=Arrival, unlock=at the gem trader in Falador.] +TrackDefinition [arrayId=10, trackset=Trackset: Castle wars, , fileId=24, name=Attack1, unlock=at the Battlefield north of Tree Gnome Village.] +TrackDefinition [arrayId=11, trackset=Trackset: Castle wars, , fileId=25, name=Attack2, unlock=at Elvarg's lair or during Grand Tree Quest.] +TrackDefinition [arrayId=12, trackset=Trackset: Castle wars, , fileId=26, name=Attack3, unlock=to the north of the Lava Maze.] +TrackDefinition [arrayId=13, trackset=Trackset: Castle wars, , fileId=27, name=Attack4, unlock=at the Fight Arena.] +TrackDefinition [arrayId=14, trackset=Trackset: Castle wars, , fileId=28, name=Attack5, unlock=at the King Black Dragon.] +TrackDefinition [arrayId=15, trackset=Trackset: Castle wars, , fileId=29, name=Attack6, unlock=at Gu'Tanoth Ogre Enclave.] +TrackDefinition [arrayId=16, trackset=Trackset: Falador, , fileId=180, name=Attention, unlock=at the coastline below Rimmington.] +TrackDefinition [arrayId=17, trackset=Trackset: Lumbridge, , fileId=2, name=Autumn Voyage, unlock=at Lumbridge farm.] +TrackDefinition [arrayId=18, trackset=Trackset: Falador, , fileId=324, name=Background, unlock=on Entrana.] +TrackDefinition [arrayId=19, trackset=Trackset: Eastern ardougne, , fileId=152, name=Ballad of Enchantment, unlock=at the Monastery.] +TrackDefinition [arrayId=20, trackset=Trackset: Eastern ardougne, , fileId=99, name=Baroque, unlock=in Ardougne.] +TrackDefinition [arrayId=21, trackset=Trackset: Dwarf, , fileId=100, name=Beyond, unlock=at the ice dungeon under Wolf Mountain.] +TrackDefinition [arrayId=22, trackset=Trackset: Yanille(?) , , fileId=83, name=Big Chords, unlock=to the west of Yanille.] +TrackDefinition [arrayId=23, trackset=Trackset: Lumbridge, , fileId=64, name=Book of Spells, unlock=at Lumbridge Swamp.] +TrackDefinition [arrayId=24, trackset=Trackset: Seers Village & Camelot, , fileId=104, name=Camelot, unlock=at Camelot Castle.] +TrackDefinition [arrayId=25, trackset=Trackset: Dwarf, , fileId=325, name=Cave Background, unlock=at the Dwarven Mine.] +TrackDefinition [arrayId=26, trackset=Trackset: Cave, , fileId=68, name=Cavern, unlock=at Yanille Agility Dungeon.] +TrackDefinition [arrayId=27, trackset=Trackset: Cave, , fileId=63, name=Chain of Command, unlock=during Temple of Ikov.] +TrackDefinition [arrayId=28, trackset=Trackset: Zanaris, , fileId=181, name=Crystal Cave, unlock=at Zanaris market.] +TrackDefinition [arrayId=29, trackset=Trackset: Wilderness, , fileId=169, name=Crystal Sword, unlock=at the Wilderness, north of Varrock.] +TrackDefinition [arrayId=30, trackset=Trackset: Wilderness, , fileId=182, name=Dangerous, unlock=to the north of Edgeville.] +TrackDefinition [arrayId=31, trackset=Trackset: Wilderness, , fileId=326, name=Dark, unlock=in the south-east of the Wilderness.] +TrackDefinition [arrayId=32, trackset=Trackset: Wilderness, , fileId=37, name=Deep Wildy, unlock=in the north-west of the Wilderness.] +TrackDefinition [arrayId=33, trackset=Trackset: Kharidian, , fileId=174, name=Desert Voyage, unlock=around the Desert Mining Camp.] +TrackDefinition [arrayId=34, trackset=Trackset: Wilderness, , fileId=56, name=Doorways, unlock=to the north of the Grand Exchange.] +TrackDefinition [arrayId=35, trackset=Trackset: Lumbridge, , fileId=327, name=Dream, unlock=on the path between Lumbridge and Draynor.] +TrackDefinition [arrayId=36, trackset=Trackset: "Only defined", , fileId=173, name=Dunjun, unlock=in Taverley Dungeon.] +TrackDefinition [arrayId=37, trackset=Trackset: Kharidian, , fileId=69, name=Egypt, unlock=at Shantay Pass.] +TrackDefinition [arrayId=38, trackset=Trackset: Tree Gnome Stronghold, , fileId=148, name=Emotion, unlock=in the Tree Gnome Village maze.] +TrackDefinition [arrayId=39, trackset=Trackset: Falador, , fileId=138, name=Emperor, unlock=in Melzar's Maze.] +TrackDefinition [arrayId=40, trackset=Trackset: Varrock, , fileId=106, name=Expanse, unlock=at the stone circle in Varrock.] +TrackDefinition [arrayId=41, trackset=Trackset: Yanille(?) , , fileId=41, name=Expecting, unlock=at the unholy altar north of the Observatory.] +TrackDefinition [arrayId=42, trackset=Trackset: Cave, , fileId=153, name=Expedition, unlock=in the caverns below the Observatory.] +TrackDefinition [arrayId=43, trackset=Trackset: Zanaris, , fileId=118, name=Faerie, unlock=at Zanaris.] +TrackDefinition [arrayId=44, trackset=Trackset: Falador, , fileId=72, name=Fanfare, unlock=at Falador Castle.] +TrackDefinition [arrayId=45, trackset=Trackset: Port, , fileId=167, name=Fanfare3, unlock=at Port Khazard.] +TrackDefinition [arrayId=46, trackset=Trackset: Seers Village & Camelot, , fileId=119, name=Fishing, unlock=at Catherby beach.] +TrackDefinition [arrayId=47, trackset=Trackset: Lumbridge, , fileId=163, name=Flute Salad, unlock=at the Lumbridge windmill area.] +TrackDefinition [arrayId=48, trackset=Trackset: Varrock, , fileId=98, name=Forever, unlock=at Edgeville.] +TrackDefinition [arrayId=49, trackset=Trackset: Feldip hills, , fileId=159, name=Gaol, unlock=to the north of the Bandit Camp in the Wilderness.] +TrackDefinition [arrayId=50, trackset=Trackset: Varrock, , fileId=125, name=Garden, unlock=at Varrock city centre.] +TrackDefinition [arrayId=51, trackset=Trackset: Tree Gnome Stronghold, , fileId=22, name=Gnome King, unlock=at the Tree Gnome Stronghold.] +TrackDefinition [arrayId=52, trackset=Trackset: "Only defined", , fileId=310, name=Dwarf Theme, unlock=at the Dwarven Mine.] +TrackDefinition [arrayId=53, trackset=Trackset: Tree Gnome Stronghold, , fileId=33, name=Gnome Village, unlock=at the Tree Gnome Stronghold's Agility Training Area.] +TrackDefinition [arrayId=54, trackset=Trackset: Tree Gnome Stronghold, , fileId=101, name=Gnome Village2, unlock=to the south-west of the Tree Gnome Stronghold.] +TrackDefinition [arrayId=55, trackset=Trackset: "Only defined", , fileId=313, name=Goblin Village, unlock=at Goblin Village.] +TrackDefinition [arrayId=56, trackset=Trackset: Tree Gnome Stronghold, , fileId=112, name=Gnomeball, unlock=at the Gnome Ball Field.] +TrackDefinition [arrayId=57, trackset=Trackset: Varrock, , fileId=116, name=Greatness, unlock=at the Champions' Guild.] +TrackDefinition [arrayId=58, trackset=Trackset: Lumbridge, , fileId=76, name=Harmony, unlock=at Lumbridge Castle.] +TrackDefinition [arrayId=59, trackset=Trackset: Port, , fileId=55, name=High Seas, unlock=at Brimhaven.] +TrackDefinition [arrayId=60, trackset=Trackset: Falador, , fileId=18, name=Horizon, unlock=in Taverley.] +TrackDefinition [arrayId=61, trackset=Trackset: "Only defined", , fileId=1, name=Iban, unlock=at Iban's lair in the Underground Pass.] +TrackDefinition [arrayId=62, trackset=Trackset: Yanille(?) , , fileId=188, name=In the Manor, unlock=at the ogre island, west of Yanille.] +TrackDefinition [arrayId=63, trackset=Trackset: Wilderness, , fileId=96, name=Inspiration, unlock=at the area north of the Black Knights' Fortress.] +TrackDefinition [arrayId=64, trackset=Trackset: Cave, , fileId=95, name=Intrepid, unlock=in the Underground Pass caverns.] +TrackDefinition [arrayId=65, trackset=Trackset: Port, , fileId=6, name=Jolly-R, unlock=at the north dock of Brimhaven.] +TrackDefinition [arrayId=66, trackset=Trackset: Jungle, , fileId=172, name=Jungle Island, unlock=on Karamja.] +TrackDefinition [arrayId=67, trackset=Trackset: Jungle, , fileId=114, name=Jungly1, unlock=at Cairn Isle.] +TrackDefinition [arrayId=68, trackset=Trackset: Jungle, , fileId=115, name=Jungly2, unlock=to the north-west of Brimhaven.] +TrackDefinition [arrayId=69, trackset=Trackset: Jungle, , fileId=117, name=Jungly3, unlock=at Tai Bwo Wannai Village.] +TrackDefinition [arrayId=70, trackset=Trackset: Eastern ardougne, , fileId=191, name=Knightly, unlock=at Ardougne Castle.] +TrackDefinition [arrayId=71, trackset=Trackset: Seers Village & Camelot, , fileId=60, name=Lasting, unlock=at Hemenster.] +TrackDefinition [arrayId=72, trackset=Trackset: Fremennik, , fileId=66, name=Legion, unlock=at the Barbarian Outpost.] +TrackDefinition [arrayId=73, trackset=Trackset: Wilderness, , fileId=113, name=Lightness, unlock=to the north of Edgeville.] +TrackDefinition [arrayId=74, trackset=Trackset: Seers Village & Camelot, , fileId=74, name=Lightwalk, unlock=at Keep Le Faye.] +TrackDefinition [arrayId=75, trackset=Trackset: Yanille(?) , , fileId=161, name=Long Ago, unlock=at the Fishing Platform.] +TrackDefinition [arrayId=76, trackset=Trackset: Falador, , fileId=12, name=Long Way Home, unlock=at Rimmington] +TrackDefinition [arrayId=77, trackset=Trackset: Seers Village & Camelot, , fileId=20, name=Lullaby, unlock=at the area south-west of Rellekka.] +TrackDefinition [arrayId=78, trackset=Trackset: Wilderness, , fileId=13, name=Mage Arena, unlock=at the Mage Arena.] +TrackDefinition [arrayId=79, trackset=Trackset: Yanille(?) , , fileId=185, name=Magic Dance, unlock=in the east of Yanille.] +TrackDefinition [arrayId=80, trackset=Trackset: Seers Village & Camelot, , fileId=184, name=Magical Journey, unlock=at the Sorcerer's Tower.] +TrackDefinition [arrayId=81, trackset=Trackset: Northwest Ardougne, , fileId=328, name=March, unlock=at King Lathas's Combat Training Camp.] +TrackDefinition [arrayId=82, trackset=Trackset: Varrock, , fileId=157, name=Medieval, unlock=to the west of the Dig Site.] +TrackDefinition [arrayId=83, trackset=Trackset: Waterfall (?), , fileId=193, name=Mellow, unlock=at the Fishing Guild.] +TrackDefinition [arrayId=84, trackset=Trackset: Falador, , fileId=107, name=Miles Away, unlock=at the Crafting Guild.] +TrackDefinition [arrayId=85, trackset=, fileId=65, name=Miracle Dance, unlock=at the Mind Altar.] +TrackDefinition [arrayId=86, trackset=Trackset: Seers Village & Camelot, , fileId=21, name=Monarch Waltz, unlock=at the Sinclair Mansion.] +TrackDefinition [arrayId=87, trackset=Trackset: Northwest Ardougne, , fileId=10, name=Moody, unlock=at the entrance to the Underground Pass.] +TrackDefinition [arrayId=88, trackset=Trackset: Tree Gnome Stronghold, , fileId=155, name=Neverland, unlock=to the south of Tree Gnome Village.] +TrackDefinition [arrayId=89, trackset=Trackset: Lumbridge, , fileId=62, name=Newbie Melody, unlock=on Tutorial Island.] +TrackDefinition [arrayId=90, trackset=Trackset: Falador, , fileId=127, name=Nightfall, unlock=at the north of Rimmington] +TrackDefinition [arrayId=91, trackset=Trackset: Cave, , fileId=103, name=Oriental, unlock=in the Waterfall Dungeon, East of Shilo Village.] +TrackDefinition [arrayId=92, trackset=Trackset: Seers Village & Camelot, , fileId=7, name=Overture, unlock=at Seers' Village.] +TrackDefinition [arrayId=93, trackset=Trackset: Varrock, , fileId=93, name=Parade, unlock=at the Jolly Boar Inn.] +TrackDefinition [arrayId=94, trackset=, fileId=158, name=Quest, unlock=at the Fire Altar.] +TrackDefinition [arrayId=95, trackset=Trackset: Wilderness, , fileId=329, name=Regal, unlock=at the Rogues' Castle.] +TrackDefinition [arrayId=96, trackset=Trackset: Jungle, , fileId=78, name=Reggae, unlock=to the south-east of the Kharazi Jungle.] +TrackDefinition [arrayId=97, trackset=Trackset: Jungle, , fileId=89, name=Reggae2, unlock=to the east of Karamja Jungle.] +TrackDefinition [arrayId=98, trackset=Trackset: Elven, , fileId=91, name=Riverside, unlock=to the west of Tyras Camp.] +TrackDefinition [arrayId=99, trackset=Trackset: Cave, , fileId=53, name=Royale, unlock=at the Black Knight base in Taverley Dungeon.] +TrackDefinition [arrayId=100, trackset=, fileId=57, name=Rune Essence, unlock=at the rune essence mine.] +TrackDefinition [arrayId=101, trackset=Trackset: Northwest Ardougne, , fileId=5, name=Sad Meadow, unlock=at West Ardougne.] +TrackDefinition [arrayId=102, trackset=Trackset: Cave, , fileId=144, name=Scape Cave, unlock=during the Lumbridge Tutorial and in Varrock Sewers.] +TrackDefinition [arrayId=103, trackset=Trackset: "Only defined", , fileId=400, name=Scape Original, unlock=automatically.] +TrackDefinition [arrayId=104, trackset=Trackset: Wilderness, , fileId=331, name=Scape Sad, unlock=at the Demonic Ruins in the Wilderness.] +TrackDefinition [arrayId=105, trackset=Trackset: Wilderness, , fileId=332, name=Scape Wild, unlock=in the Wilderness.] +TrackDefinition [arrayId=106, trackset=Trackset: Port, , fileId=92, name=Sea Shanty, unlock=at Karamja port.] +TrackDefinition [arrayId=107, trackset=Trackset: Port, , fileId=35, name=Sea Shanty2, unlock=at Port Sarim] +TrackDefinition [arrayId=108, trackset=Trackset: Yanille(?) , , fileId=110, name=Serenade, unlock=at the Observatory.] +TrackDefinition [arrayId=109, trackset=, fileId=52, name=Serene, unlock=at the Air Altar.] +TrackDefinition [arrayId=110, trackset=Trackset: Varrock, , fileId=122, name=Shine, unlock=at the Duel Arena hospital.] +TrackDefinition [arrayId=111, trackset=Trackset: Cave, , fileId=80, name=Soundscape, unlock=at the Feldip Hills glider area.] +TrackDefinition [arrayId=112, trackset=Trackset: Varrock, , fileId=175, name=Spirit, unlock=at the Cooks' Guild.] +TrackDefinition [arrayId=113, trackset=Trackset: Falador, , fileId=77, name=Splendour, unlock=at the Heroes' Guild.] +TrackDefinition [arrayId=114, trackset=Trackset: Spooky, , fileId=333, name=Spooky, unlock=at Draynor Manor.] +TrackDefinition [arrayId=115, trackset=Trackset: Jungle, , fileId=129, name=Spookyjungle, unlock=to the north-east of Karamja.] +TrackDefinition [arrayId=116, trackset=Trackset: Iceberg/Asgarnian ice dungeon/muspah's tomb, , fileId=108, name=Starlight, unlock=at the Asgarnian Ice Dungeon north of Mudskipper Point.] +TrackDefinition [arrayId=117, trackset=Trackset: Lumbridge, , fileId=151, name=Start, unlock=at Draynor Village.] +TrackDefinition [arrayId=118, trackset=Trackset: Varrock, , fileId=111, name=Still Night, unlock=at the Mining area south-east of Varrock.] +TrackDefinition [arrayId=119, trackset=Trackset: Seers Village & Camelot, , fileId=140, name=Talking Forest, unlock=at McGrubor's Wood.] +TrackDefinition [arrayId=120, trackset=Trackset: Kharidian, , fileId=79, name=The Desert, unlock=to the west of the Kharidian Desert.] +TrackDefinition [arrayId=121, trackset=Trackset: "Only defined", , fileId=170, name=The Shadow, unlock=on Crandor.] +TrackDefinition [arrayId=122, trackset=Trackset: Northwest Ardougne, , fileId=133, name=The Tower, unlock=to the north-west of Ardougne.] +TrackDefinition [arrayId=123, trackset=Trackset: Seers Village & Camelot, , fileId=109, name=Theme, unlock=at the Coal Trucks.] +TrackDefinition [arrayId=124, trackset=Trackset: Port, , fileId=38, name=Trawler, unlock=during the Fishing Trawler minigame.] +TrackDefinition [arrayId=125, trackset=Trackset: Port, , fileId=51, name=Trawler Minor, unlock=during the Fishing Trawler minigame.] +TrackDefinition [arrayId=126, trackset=Trackset: Tree Gnome Stronghold, , fileId=130, name=Tree Spirits, unlock=to the west of the Tree Gnome Stronghold.] +TrackDefinition [arrayId=127, trackset=Trackset: Jungle, , fileId=162, name=Tribal Background, unlock=in the south-east Kharazi Jungle.] +TrackDefinition [arrayId=128, trackset=Trackset: Jungle, , fileId=165, name=Tribal, unlock=to the east of Tai Bwo Wannai Village.] +TrackDefinition [arrayId=129, trackset=Trackset: Jungle, , fileId=94, name=Tribal2, unlock=at the gnome glider on Karamja.] +TrackDefinition [arrayId=130, trackset=Trackset: Eastern ardougne, , fileId=192, name=Trinity, unlock=at the Legends' Guild.] +TrackDefinition [arrayId=131, trackset=Trackset: Wilderness, , fileId=183, name=Troubled, unlock=to the west of the Bandit Camp in the Wilderness.] +TrackDefinition [arrayId=132, trackset=Trackset: Cave, , fileId=179, name=Underground, unlock=at the dramen tree in Entrana Dungeon.] +TrackDefinition [arrayId=133, trackset=Trackset: Lumbridge, , fileId=3, name=Unknown Land, unlock=at Draynor Market.] +TrackDefinition [arrayId=134, trackset=Trackset: Cave, , fileId=323, name=Underground Pass, unlock=during Underground Pass.] +TrackDefinition [arrayId=135, trackset=Trackset: Eastern ardougne, , fileId=70, name=Upcoming, unlock=at the tower of the Necromancer.] +TrackDefinition [arrayId=136, trackset=Trackset: Varrock, , fileId=75, name=Venture, unlock=at the Dig Site.] +TrackDefinition [arrayId=137, trackset=Trackset: Lumbridge, , fileId=85, name=Vision, unlock=at the Wizards' Tower.] +TrackDefinition [arrayId=138, trackset=Trackset: "Only defined", , fileId=30, name=Voodoo Cult, unlock=at the cave under the Kharazi Jungle.] +TrackDefinition [arrayId=139, trackset=Trackset: Waterfall (?), , fileId=32, name=Voyage, unlock=at the top of Baxtorian Falls.] +TrackDefinition [arrayId=140, trackset=Trackset: Falador, , fileId=49, name=Wander, unlock=at the farm area south of Falador.] +TrackDefinition [arrayId=141, trackset=Trackset: Waterfall (?), , fileId=82, name=Waterfall, unlock=at Baxtorian Falls.] +TrackDefinition [arrayId=142, trackset=Trackset: Wilderness, , fileId=435, name=Wilderness, unlock=in the Wilderness.] +TrackDefinition [arrayId=143, trackset=Trackset: Wilderness, , fileId=42, name=Wilderness2, unlock=to the south of the Lava Maze in the Wilderness.] +TrackDefinition [arrayId=144, trackset=Trackset: Wilderness, , fileId=43, name=Wilderness3, unlock=to the west of Bounty Hunter in the Wilderness.] +TrackDefinition [arrayId=145, trackset=Trackset: Wilderness, , fileId=14, name=Witching, unlock=on the east side of the Wilderness.] +TrackDefinition [arrayId=146, trackset=Trackset: Wilderness, , fileId=34, name=Wonder, unlock=to the north-west of the Black Knights' Fortress.] +TrackDefinition [arrayId=147, trackset=Trackset: Eastern ardougne, , fileId=81, name=Wonderous, unlock=near the Legends' Guild.] +TrackDefinition [arrayId=148, trackset=Trackset: Falador, , fileId=15, name=Workshop, unlock=at the Mining Guild in Falador.] +TrackDefinition [arrayId=149, trackset=Trackset: Cave, , fileId=168, name=Lonesome, unlock=at the Desert Mining Camp.] +TrackDefinition [arrayId=150, trackset=Trackset: "Only defined", , fileId=16, name=Scape Main, unlock=automatically.] +TrackDefinition [arrayId=151, trackset=Trackset: "Only defined", , fileId=466, name=Ground Scape, unlock=automatically.] +TrackDefinition [arrayId=152, trackset=Trackset: "Only defined", , fileId=321, name=Scape Scared, unlock=automatically.] +TrackDefinition [arrayId=153, trackset=Trackset: Christmas, , fileId=547, name=Scape Santa, unlock=automatically.] +TrackDefinition [arrayId=154, trackset=Trackset: Christmas, , fileId=189, name=Land of Snow, unlock=during or after the Christmas 2007 holiday event.] +TrackDefinition [arrayId=155, trackset=Trackset: "Only defined", , fileId=468, name=Shaping Up, unlock=during As a First Resort...] +TrackDefinition [arrayId=156, trackset=Trackset: "Only defined", , fileId=492, name=Exam Conditions, unlock=at the Stronghold of Player Safety.] +TrackDefinition [arrayId=157, trackset=Trackset: Jungle, , fileId=429, name=Roots and Flutes, unlock=during Back to my Roots.] +TrackDefinition [arrayId=158, trackset=Trackset: "Only defined", , fileId=494, name=Incarceration, unlock=at the Stronghold of Player Safety.] +TrackDefinition [arrayId=159, trackset=Trackset: Falador, , fileId=54, name=Scape Soft, unlock=to the north of Falador.] +TrackDefinition [arrayId=160, trackset=Trackset: Wilderness, , fileId=120, name=Shining, unlock=in the Wilderness north of the Graveyard.] +TrackDefinition [arrayId=161, trackset=Trackset: Lumbridge, , fileId=145, name=Yesteryear, unlock=to the east of Lumbridge Swamp.] +TrackDefinition [arrayId=162, trackset=Trackset: Port, , fileId=166, name=Fanfare2, unlock=at the Shipyard on Karamja.] +TrackDefinition [arrayId=163, trackset=Trackset: Falador, , fileId=105, name=Tomorrow, unlock=at the coastline south of Port Sarim.] +TrackDefinition [arrayId=164, trackset=Trackset: "Only defined", , fileId=47, name=Duel Arena, unlock=at the Duel Arena.] +TrackDefinition [arrayId=165, trackset=Trackset: "Only defined", , fileId=87, name=Ice Melody, unlock=at White Wolf Mountain.] +TrackDefinition [arrayId=166, trackset=Trackset: Wilderness, , fileId=449, name=Wild Isle, unlock=to the south of Red Dragon Isle in the Wilderness.] +TrackDefinition [arrayId=167, trackset=Trackset: Lumbridge, , fileId=46, name=Harmony2, unlock=in Lumbridge Castle's basement.] +TrackDefinition [arrayId=168, trackset=Trackset: Varrock, , fileId=45, name=Venture2, unlock=during Dig Site.] +TrackDefinition [arrayId=169, trackset=Trackset: Port, , fileId=164, name=Landlubber, unlock=to the west of Brimhaven.] +TrackDefinition [arrayId=170, trackset=Trackset: Wilderness, , fileId=176, name=Undercurrent, unlock=in the south-east of the Wilderness.] +TrackDefinition [arrayId=171, trackset=Trackset: Kharidian, , fileId=58, name=Nomad, unlock=to the east of the Bedabin Camp.] +TrackDefinition [arrayId=172, trackset=, fileId=146, name=Zealot, unlock=at the Water Altar.] +TrackDefinition [arrayId=173, trackset=Trackset: Cave, , fileId=330, name=Cellar Song, unlock=at the bank vault west of Varrock.] +TrackDefinition [arrayId=174, trackset=, fileId=190, name=Heart and Mind, unlock=at the Body Altar.] +TrackDefinition [arrayId=175, trackset=Trackset: Wilderness, , fileId=67, name=Close Quarters, unlock=at the entrance to Bounty Hunter in the Wilderness.] +TrackDefinition [arrayId=176, trackset=Trackset: Cave, , fileId=17, name=Escape, unlock=at the perfect gold mine under Ardougne.] +TrackDefinition [arrayId=177, trackset=Trackset: Feldip hills, , fileId=128, name=Grumpy, unlock=at the swamp toad pond in the Feldip Hills.] +TrackDefinition [arrayId=178, trackset=Trackset: Feldip hills, , fileId=71, name=Chompy Hunt, unlock=at the chompy hunt area near Rantz the ogre.] +TrackDefinition [arrayId=179, trackset=Trackset: "Only defined", , fileId=88, name=Twilight, unlock=during Elemental Workshop.] +TrackDefinition [arrayId=180, trackset=Trackset: Morytania, , fileId=48, name=Morytania, unlock=to the east of Paterdomus.] +TrackDefinition [arrayId=181, trackset=Trackset: Morytania, , fileId=84, name=Dead Quiet, unlock=to the north of the Mort Myre area.] +TrackDefinition [arrayId=182, trackset=Trackset: Morytania, , fileId=61, name=Village, unlock=at Canifis in Morytania.] +TrackDefinition [arrayId=183, trackset=Trackset: Feldip hills, , fileId=154, name=Bone Dance, unlock=to the west of Mort'ton.] +TrackDefinition [arrayId=184, trackset=Trackset: Morytania, , fileId=156, name=Mausoleum, unlock=under Paterdomus.] +TrackDefinition [arrayId=185, trackset=Trackset: Wilderness, , fileId=121, name=Forbidden, unlock=to the north of the Lumber Yard.] +TrackDefinition [arrayId=186, trackset=Trackset: Cave, , fileId=59, name=Cursed, unlock=during Underground Pass.] +TrackDefinition [arrayId=187, trackset=, fileId=131, name=Understanding, unlock=at the Nature Altar.] +TrackDefinition [arrayId=188, trackset=Trackset: Falador, , fileId=149, name=Principality, unlock=at Burthorpe's training ground.] +TrackDefinition [arrayId=189, trackset=Trackset: Ogre, , fileId=187, name=Tremble, unlock=during Death Plateau.] +TrackDefinition [arrayId=190, trackset=Trackset: Ogre, , fileId=9, name=Kingdom, unlock=on the way to Death Plateau.] +TrackDefinition [arrayId=191, trackset=Trackset: Ogre, , fileId=97, name=Hermit, unlock=at the hermit's cave north-west of Burthorpe.] +TrackDefinition [arrayId=192, trackset=, fileId=134, name=La Mort, unlock=at the Death Altar.] +TrackDefinition [arrayId=193, trackset=Trackset: Morytania, , fileId=241, name=Stagnant, unlock=at the Hollows in the Mort Myre Swamp.] +TrackDefinition [arrayId=194, trackset=Trackset: Elven, , fileId=132, name=Breeze, unlock=at Isafdar near the Underground Pass.] +TrackDefinition [arrayId=195, trackset=, fileId=243, name=Stratosphere, unlock=at the Cosmic Altar.] +TrackDefinition [arrayId=196, trackset=Trackset: "Only defined", , fileId=242, name=Time Out, unlock=during the Maze random event.] +TrackDefinition [arrayId=197, trackset=Trackset: Morytania, , fileId=245, name=Natural, unlock=at the nature spirit's island in Mort Myre Swamp.] +TrackDefinition [arrayId=198, trackset=Trackset: Cave, , fileId=246, name=Grotto, unlock=at the nature spirit's grotto in Mort Myre Swamp.] +TrackDefinition [arrayId=199, trackset=Trackset: Morytania, , fileId=244, name=Waterlogged, unlock=to the south of Canifis.] +TrackDefinition [arrayId=200, trackset=Trackset: "Only defined", , fileId=247, name=Artistry, unlock=during the Mime random event.] +TrackDefinition [arrayId=201, trackset=Trackset: Kharidian, , fileId=248, name=Aztec, unlock=at the Brimhaven Agility Arena.] +TrackDefinition [arrayId=202, trackset=Trackset: Elven, , fileId=252, name=Elven Mist, unlock=at the exit of the Underground Pass.] +TrackDefinition [arrayId=203, trackset=Trackset: Elven, , fileId=251, name=Forest, unlock=to the south-east of Isafdar.] +TrackDefinition [arrayId=204, trackset=Trackset: Tirannwn, , fileId=253, name=Lost Soul, unlock=at the Poison Waste in south Isafdar.] +TrackDefinition [arrayId=205, trackset=Trackset: Elven, , fileId=254, name=Meridian, unlock=at the area around Tyras Camp in Isafdar.] +TrackDefinition [arrayId=206, trackset=Trackset: Elven, , fileId=255, name=Woodland, unlock=at the Elf Camp in Tirannwn.] +TrackDefinition [arrayId=207, trackset=Trackset: Elven, , fileId=256, name=Overpass, unlock=at Arandar, east of Tirannwn.] +TrackDefinition [arrayId=208, trackset=Trackset: Ogre, , fileId=258, name=Contest, unlock=in Trollheim.] +TrackDefinition [arrayId=209, trackset=Trackset: Ogre, , fileId=257, name=Sojourn, unlock=at the troll champion arena.] +TrackDefinition [arrayId=210, trackset=Trackset: Elven, , fileId=259, name=Crystal Castle, unlock=to the south-east of Prifddinas.] +TrackDefinition [arrayId=211, trackset=Trackset: Ogre, , fileId=261, name=Marzipan, unlock=at the Trollheim cave.] +TrackDefinition [arrayId=212, trackset=Trackset: "Only defined", , fileId=260, name=Insect Queen, unlock=at the Kalphite Queen.] +TrackDefinition [arrayId=213, trackset=Trackset: "Only defined", , fileId=264, name=Mad Eadgar, unlock=at Eadgar's cave atop Trollheim.] +TrackDefinition [arrayId=214, trackset=Trackset: Kharidian, , fileId=263, name=Bandit Camp, unlock=at the Bandit Camp in the Kharidian Desert.] +TrackDefinition [arrayId=215, trackset=Trackset: Kharidian, , fileId=267, name=Sunburn, unlock=in the desert north of Jaldraocht Pyramid.] +TrackDefinition [arrayId=216, trackset=Trackset: Kharidian, , fileId=266, name=Bone Dry, unlock=in the smoky well near Pollnivneach.] +TrackDefinition [arrayId=217, trackset=Trackset: "Only defined", , fileId=269, name=Competition, unlock=at Burthorpe Games Room.] +TrackDefinition [arrayId=218, trackset=Trackset: Spooky, , fileId=11, name=Spooky2, unlock=at the entrance to the Haunted Mine.] +TrackDefinition [arrayId=219, trackset=Trackset: Elven, , fileId=268, name=Everywhere, unlock=to the south-west of Prifddinas.] +TrackDefinition [arrayId=220, trackset=Trackset: Tirannwn, , fileId=270, name=Exposed, unlock=to the south of Tyras Camp in Isafdar.] +TrackDefinition [arrayId=221, trackset=Trackset: Tirannwn, , fileId=271, name=Well of Voyage, unlock=in the passage between Iban's Temple and Isafdar.] +TrackDefinition [arrayId=222, trackset=Trackset: "Only defined", , fileId=277, name=Haunted Mine, unlock=at the boss area of the Haunted Mine.] +TrackDefinition [arrayId=223, trackset=, fileId=262, name=Righteousness, unlock=at the Law Altar.] +TrackDefinition [arrayId=224, trackset=Trackset: Cave, , fileId=278, name=Deep Down, unlock=on the bottom floor of the Haunted Mine.] +TrackDefinition [arrayId=225, trackset=Trackset: Cave, , fileId=282, name=Chamber, unlock=on the middle floor of the Haunted Mine.] +TrackDefinition [arrayId=226, trackset=Trackset: Miscellania, , fileId=284, name=Miscellania, unlock=on Miscellania.] +TrackDefinition [arrayId=227, trackset=Trackset: Miscellania, , fileId=285, name=Etcetera, unlock=on Etceteria.] +TrackDefinition [arrayId=228, trackset=Trackset: Morytania, , fileId=286, name=Shadowland, unlock=to the east of Mort'ton.] +TrackDefinition [arrayId=229, trackset=Trackset: Cave, , fileId=287, name=Lair, unlock=at the shade catacombs below Mort'ton.] +TrackDefinition [arrayId=230, trackset=Trackset: Morytania, , fileId=288, name=Deadlands, unlock=at the Haunted Woods of Morytania.] +TrackDefinition [arrayId=231, trackset=Trackset: Fremennik, , fileId=289, name=Rellekka, unlock=at Rellekka.] +TrackDefinition [arrayId=232, trackset=Trackset: Fremennik, , fileId=290, name=Saga, unlock=to the south of Rellekka.] +TrackDefinition [arrayId=233, trackset=Trackset: Fremennik, , fileId=291, name=Borderland, unlock=to the east of Rellekka.] +TrackDefinition [arrayId=234, trackset=Trackset: Unknown. Troll?, , fileId=292, name=Stranded, unlock=at the gate to the Ice Path, north of Trollheim.] +TrackDefinition [arrayId=235, trackset=Trackset: Fremennik, , fileId=293, name=Legend, unlock=to the south-east of Rellekka.] +TrackDefinition [arrayId=236, trackset=Trackset: Unknown. Troll?, , fileId=294, name=Frostbite, unlock=at the Ice Path north of Trollheim.] +TrackDefinition [arrayId=237, trackset=Trackset: Cave, , fileId=295, name=Warrior, unlock=during Fremennik Trials.] +TrackDefinition [arrayId=238, trackset=Trackset: "Only defined", , fileId=296, name=Technology, unlock=at the gnome glider hanger.] +TrackDefinition [arrayId=239, trackset=Trackset: Jungle, , fileId=303, name=Monkey Madness, unlock=on Ape Atoll.] +TrackDefinition [arrayId=240, trackset=Trackset: Jungle, , fileId=305, name=Anywhere, unlock=at Marim's main gate.] +TrackDefinition [arrayId=241, trackset=Trackset: Jungle, , fileId=304, name=Marooned, unlock=on Crash Island during Monkey Madness.] +TrackDefinition [arrayId=242, trackset=Trackset: Jungle, , fileId=306, name=Island Life, unlock=at the southern part of Ape Atoll.] +TrackDefinition [arrayId=243, trackset=Trackset: Cave, , fileId=307, name=Temple, unlock=on Ape Atoll.] +TrackDefinition [arrayId=244, trackset=Trackset: "Only defined", , fileId=308, name=Suspicious, unlock=during Monkey Madness.] +TrackDefinition [arrayId=245, trackset=Trackset: "Only defined", , fileId=311, name=Showdown, unlock=during the boss fight in Monkey Madness.] +TrackDefinition [arrayId=246, trackset=Trackset: Cave, , fileId=312, name=Find My Way, unlock=at the gnome tunnel in Monkey Madness.] +TrackDefinition [arrayId=247, trackset=Trackset: "Only defined", , fileId=314, name=Castlewars, unlock=during the Castle Wars minigame.] +TrackDefinition [arrayId=248, trackset=Trackset: Yanille(?) , , fileId=317, name=Melodrama, unlock=during the Castle Wars minigame.] +TrackDefinition [arrayId=249, trackset=Trackset: Castle wars, , fileId=318, name=Ready For Battle, unlock=during the Castle Wars minigame.] +TrackDefinition [arrayId=250, trackset=Trackset: Cave, , fileId=319, name=Stillness, unlock=at the Myreque area under Mort Myre.] +TrackDefinition [arrayId=251, trackset=Trackset: "Only defined", , fileId=320, name=Lighthouse, unlock=at the Lighthouse.] +TrackDefinition [arrayId=252, trackset=Trackset: Goblin, , fileId=346, name=Goblin Game, unlock=at the goblin cave near the Fishing Guild.] +TrackDefinition [arrayId=253, trackset=Trackset: "Only defined", , fileId=322, name=Out of the Deep, unlock=at the dagannoth cave under the Lighthouse.] +TrackDefinition [arrayId=254, trackset=Trackset: Unknown. Troll?, , fileId=4, name=Hell's Bells, unlock=during the Troll Romance quest.] +TrackDefinition [arrayId=255, trackset=Trackset: Fremennik, , fileId=316, name=The Navigator, unlock=during Fremennik Trials.] +TrackDefinition [arrayId=256, trackset=Trackset: Wilderness, , fileId=8, name=Wildwood, unlock=to the south of Bounty Hunter.] +TrackDefinition [arrayId=257, trackset=Trackset: Fremennik, , fileId=141, name=Barbarianism, unlock=at Barbarian Village.] +TrackDefinition [arrayId=258, trackset=, fileId=142, name=Complication, unlock=at the Chaos Altar.] +TrackDefinition [arrayId=259, trackset=, fileId=143, name=Down to Earth, unlock=at the Earth Altar.] +TrackDefinition [arrayId=260, trackset=Trackset: Cave, , fileId=178, name=Courage, unlock=at Taverley Dungeon.] +TrackDefinition [arrayId=261, trackset=Trackset: Cave, , fileId=265, name=Superstition, unlock=at the cave below the Kharazi Jungle.] +TrackDefinition [arrayId=262, trackset=Trackset: Port, , fileId=334, name=Pirates of Peril, unlock=at the Pirates' Hideout in the Wilderness.] +TrackDefinition [arrayId=263, trackset=Trackset: Cave, , fileId=336, name=Dangerous Road, unlock=at the caves below Crandor.] +TrackDefinition [arrayId=264, trackset=Trackset: Unknown. Troll?, , fileId=335, name=Romancing the Crone, unlock=during the Troll Romance quest.] +TrackDefinition [arrayId=265, trackset=Trackset: Wilderness, , fileId=337, name=Faithless, unlock=at the Chaos Temple in the Wilderness.] +TrackDefinition [arrayId=266, trackset=Trackset: Cave, , fileId=338, name=Tiptoe, unlock=at Draynor Manor's cellar.] +TrackDefinition [arrayId=267, trackset=Trackset: Morytania, , fileId=339, name=The Terrible Tower, unlock=at the Slayer Tower.] +TrackDefinition [arrayId=268, trackset=Trackset: Cave, , fileId=340, name=Masquerade, unlock=on the west side of the Fremennik Slayer Dungeon.] +TrackDefinition [arrayId=269, trackset=Trackset: Cave, , fileId=341, name=The Slayer, unlock=on the east side of the Fremennik Slayer Dungeon.] +TrackDefinition [arrayId=270, trackset=Trackset: Morytania, , fileId=342, name=Body Parts, unlock=at the dungeon south-east of Fenkenstrain's Castle.] +TrackDefinition [arrayId=271, trackset=Trackset: Morytania, , fileId=344, name=Fenkenstrain's Refrain, unlock=at Fenkenstrain's Castle.] +TrackDefinition [arrayId=272, trackset=Trackset: "Only defined", , fileId=343, name=Monster Melee, unlock=at the H.A.M. cave.] +TrackDefinition [arrayId=273, trackset=Trackset: Port, , fileId=347, name=Fruits de Mer, unlock=at the Fishing Platform.] +TrackDefinition [arrayId=274, trackset=Trackset: "Only defined", , fileId=345, name=Barking Mad, unlock=at the Werewolf Agility Course.] +TrackDefinition [arrayId=275, trackset=Trackset: Kharidian, , fileId=351, name=Dynasty, unlock=at the town of Pollnivneach.] +TrackDefinition [arrayId=276, trackset=Trackset: Port, , fileId=353, name=Shipwrecked, unlock=at the shipwreck on the north coast of Morytania.] +TrackDefinition [arrayId=277, trackset=Trackset: Morytania, , fileId=354, name=Phasmatys, unlock=at the pool of ectoplasm underneath the Ectofuntus.] +TrackDefinition [arrayId=278, trackset=Trackset: Morytania, , fileId=355, name=The Other Side, unlock=at Port Phasmatys.] +TrackDefinition [arrayId=279, trackset=Trackset: Fremennik, , fileId=356, name=Settlement, unlock=at the Mountain Camp.] +TrackDefinition [arrayId=280, trackset=Trackset: "Only defined", , fileId=357, name=Cave of Beasts, unlock=during Mountain Daughter.] +TrackDefinition [arrayId=281, trackset=Trackset: Port, , fileId=358, name=Dragontooth Island, unlock=on Dragontooth Island.] +TrackDefinition [arrayId=282, trackset=Trackset: Kharidian, , fileId=352, name=Scarab, unlock=at Jaldraocht, the pyramid visited in Desert Treasure.] +TrackDefinition [arrayId=283, trackset=Trackset: Kharidian, , fileId=359, name=Sarcophagus, unlock=inside Jaldraocht, the pyramid visited in Desert Treasure.] +TrackDefinition [arrayId=284, trackset=Trackset: Cave, , fileId=361, name=Down Below, unlock=at the dungeon below Draynor Village.] +TrackDefinition [arrayId=285, trackset=Trackset: Cave, , fileId=363, name=7th Realm, unlock=at Brimhaven Dungeon.] +TrackDefinition [arrayId=286, trackset=Trackset: Jungle, , fileId=362, name=Karamja Jam, unlock=at the dragon area of Brimhaven Dungeon.] +TrackDefinition [arrayId=287, trackset=Trackset: Cave, , fileId=364, name=Pathways, unlock=at Brimhaven Dungeon's entrance.] +TrackDefinition [arrayId=288, trackset=Trackset: Hunter (?), , fileId=366, name=Eagle Peak, unlock=during Eagles' Peak.] +TrackDefinition [arrayId=289, trackset=Trackset: Dwarf, , fileId=369, name=Time to Mine, unlock=during Between a Rock...] +TrackDefinition [arrayId=290, trackset=Trackset: "Only defined", , fileId=370, name=In Between, unlock=during Between a Rock...] +TrackDefinition [arrayId=291, trackset=Trackset: "Only defined", , fileId=373, name=Claustrophobia, unlock=during Between a Rock...] +TrackDefinition [arrayId=292, trackset=Trackset: Elven, , fileId=372, name=Far Away, unlock=at Lletya.] +TrackDefinition [arrayId=293, trackset=Trackset: Cave, , fileId=375, name=Fight or Flight, unlock=at the slave mine under West Ardougne.] +TrackDefinition [arrayId=294, trackset=Trackset: Zanaris, , fileId=376, name=Temple of Light, unlock=during Mourning's Ends Part II.] +TrackDefinition [arrayId=295, trackset=Trackset: Kharidian, , fileId=377, name=The Golem, unlock=at the Ruins of Uzer.] +TrackDefinition [arrayId=296, trackset=Trackset: "Only defined", , fileId=378, name=Forgotten, unlock=during the Golem.] +TrackDefinition [arrayId=297, trackset=Trackset: "Only defined", , fileId=379, name=Throne of the Demon, unlock=during Shadow of the Storm.] +TrackDefinition [arrayId=298, trackset=Trackset: Morytania, , fileId=380, name=Dance of the Undead, unlock=at the Barrows.] +TrackDefinition [arrayId=299, trackset=Trackset: Morytania, , fileId=381, name=Dangerous Way, unlock=beneath the Barrows.] +TrackDefinition [arrayId=300, trackset=Trackset: Kharidian, , fileId=383, name=City of the Dead, unlock=to the north of (and at) Menaphos.] +TrackDefinition [arrayId=301, trackset=Trackset: "Only defined", , fileId=384, name=Hypnotized, unlock=during Icthlarin's Little Helper.] +TrackDefinition [arrayId=302, trackset=Trackset: Kharidian, , fileId=387, name=Sphinx, unlock=to the north of Sophanem.] +TrackDefinition [arrayId=303, trackset=Trackset: Kharidian, , fileId=388, name=Mirage, unlock=during Icthlarin's Little Helper.] +TrackDefinition [arrayId=304, trackset=Trackset: Goblin, , fileId=389, name=Cave of the Goblins, unlock=at the caves beneath Lumbridge Swamp.] +TrackDefinition [arrayId=305, trackset=Trackset: "Only defined", , fileId=474, name=Bish Bash Bosh, unlock=during As a First Resort...] +TrackDefinition [arrayId=306, trackset=Trackset: Feldip hills, , fileId=392, name=Zogre Dance, unlock=at the zogre area.] +TrackDefinition [arrayId=307, trackset=Trackset: Cave, , fileId=393, name=Path of Peril, unlock=in Damis's Shadow Dungeon.] +TrackDefinition [arrayId=308, trackset=Trackset: Cave, , fileId=394, name=Wayward, unlock=at the zogre dungeon.] +TrackDefinition [arrayId=309, trackset=Trackset: Dwarf, , fileId=395, name=Tale of Keldagrim, unlock=on the east side of Keldagrim.] +TrackDefinition [arrayId=310, trackset=Trackset: Dwarf, , fileId=396, name=Land of the Dwarves, unlock=on the west side of Keldagrim.] +TrackDefinition [arrayId=311, trackset=Trackset: "Only defined", , fileId=397, name=Tears of Guthix, unlock=during Tears of Guthix.] +TrackDefinition [arrayId=312, trackset=Trackset: Feldip hills, , fileId=390, name=Romper Chomper, unlock=at the ogre area south of Castle Wars.] +TrackDefinition [arrayId=313, trackset=Trackset: "Only defined", , fileId=402, name=The Rogues' Den, unlock=at the Rogues' Den.] +TrackDefinition [arrayId=314, trackset=Trackset: "Only defined", , fileId=403, name=The Far Side, unlock=at the Rogues' Den training area.] +TrackDefinition [arrayId=315, trackset=Trackset: Goblin, , fileId=407, name=The Lost Melody, unlock=at the Dorgesh-Kaan mine.] +TrackDefinition [arrayId=316, trackset=Trackset: "Only defined", , fileId=411, name=Evil Bob's Island, unlock=during the Evil Bob random event.] +TrackDefinition [arrayId=317, trackset=Trackset: Abyss, , fileId=412, name=Into the Abyss, unlock=in abyssal space.] +TrackDefinition [arrayId=318, trackset=Trackset: "Only defined", , fileId=413, name=The Quiz Master, unlock=during the Quiz Master random event.] +TrackDefinition [arrayId=319, trackset=Trackset: "Only defined", , fileId=398, name=The Power of Tears, unlock=during the Tears of Guthix quest.] +TrackDefinition [arrayId=320, trackset=, fileId=147, name= , unlock=default info] +TrackDefinition [arrayId=321, trackset=Trackset: "Only defined", , fileId=419, name=Pheasant Peasant, unlock=during the Freaky Forester random event.] +TrackDefinition [arrayId=322, trackset=Trackset: Goblin, , fileId=420, name=The Lost Tribe, unlock=at the goblin mines under Lumbridge.] +TrackDefinition [arrayId=323, trackset=Trackset: "Only defined", , fileId=418, name=Corporal Punishment, unlock=during the Drill Demon random event.] +TrackDefinition [arrayId=324, trackset=Trackset: "Only defined", , fileId=425, name=The Chosen, unlock=during Recruitment Drive.] +TrackDefinition [arrayId=325, trackset=Trackset: Dwarf, , fileId=434, name=Have a Blast, unlock=during the Blast Furnace minigame.] +TrackDefinition [arrayId=326, trackset=Trackset: Dwarf, , fileId=436, name=Forgettable Melody, unlock=during Forgettable Tale...] +TrackDefinition [arrayId=327, trackset=Trackset: Dwarf, , fileId=44, name=Right On Track, unlock=during Forgettable Tale...] +TrackDefinition [arrayId=328, trackset=Trackset: Kharidian, , fileId=447, name=Over To Nardah, unlock=at Nardah.] +TrackDefinition [arrayId=329, trackset=Trackset: "Only defined", , fileId=448, name=The Monsters Below, unlock=in Waterbirth Island Dungeon.] +TrackDefinition [arrayId=330, trackset=Trackset: Miscellania, , fileId=461, name=The Desolate Isle, unlock=on Waterbirth Island.] +TrackDefinition [arrayId=331, trackset=Trackset: Kharidian, , fileId=462, name=Spirits of Elid, unlock=during the Spirits of Elid.] +TrackDefinition [arrayId=332, trackset=Trackset: "Only defined", , fileId=464, name=The Genie, unlock=at the genie's cave west of Nardah.] +TrackDefinition [arrayId=333, trackset=Trackset: Kharidian, , fileId=465, name=Desert Heat, unlock=in the desert north of Nardah.] +TrackDefinition [arrayId=334, trackset=Trackset: TzHaar, , fileId=463, name=Fire and Brimstone, unlock=in the TzHaar Fight Pit minigame.] +TrackDefinition [arrayId=335, trackset=Trackset: TzHaar, , fileId=469, name=In the Pits, unlock=in TzHaar.] +TrackDefinition [arrayId=336, trackset=Trackset: "Only defined", , fileId=409, name=Frogland, unlock=during the Frog random event.] +TrackDefinition [arrayId=337, trackset=Trackset: "Only defined", , fileId=470, name=Strange Place, unlock=during the Tale of Two Cats.] +TrackDefinition [arrayId=338, trackset=Trackset: "Only defined", , fileId=471, name=Brew Hoo Hoo, unlock=at Port Phasmatys brewery.] +TrackDefinition [arrayId=339, trackset=Trackset: TzHaar, , fileId=473, name=TzHaar!, unlock=in the TzHaar Fight Cave minigame.] +TrackDefinition [arrayId=340, trackset=Trackset: Wilderness, , fileId=475, name=Wild Side, unlock=to the north of the Lava Maze in the Wilderness.] +TrackDefinition [arrayId=341, trackset=Trackset: Wilderness, , fileId=476, name=Dead Can Dance, unlock=to the east of Bounty Hunter.] +TrackDefinition [arrayId=342, trackset=Trackset: "Only defined", , fileId=478, name=The Cellar Dwellers, unlock=during the Hazeel Cult.] +TrackDefinition [arrayId=343, trackset=Trackset: Jungle, , fileId=479, name=Jungle Troubles, unlock=in the jungle of north-east Karamja.] +TrackDefinition [arrayId=344, trackset=Trackset: "Only defined", , fileId=481, name=Catch Me If You Can, unlock=at the Ardougne Rat Pits.] +TrackDefinition [arrayId=345, trackset=Trackset: "Only defined", , fileId=482, name=Rat a Tat Tat, unlock=at the Varrock Rat Pits.] +TrackDefinition [arrayId=346, trackset=Trackset: "Only defined", , fileId=485, name=The Noble Rodent, unlock=during Rat Catchers.] +TrackDefinition [arrayId=347, trackset=Trackset: "Only defined", , fileId=489, name=Bubble and Squeak, unlock=at the Keldagrim Rat Pits.] +TrackDefinition [arrayId=348, trackset=Trackset: "Only defined", , fileId=490, name=Sarim's Vermin, unlock=at Port Sarim Rat Pits.] +TrackDefinition [arrayId=349, trackset=Trackset: "Only defined", , fileId=491, name=Rat Hunt, unlock=during Rat Catchers.] +TrackDefinition [arrayId=350, trackset=Trackset: "Only defined", , fileId=621, name=Homescape, unlock=automatically.] +TrackDefinition [arrayId=351, trackset=Trackset: Port, , fileId=497, name=Aye Car Rum Ba, unlock=on Braindeath Island.] +TrackDefinition [arrayId=352, trackset=Trackset: Port, , fileId=498, name=Blistering Barnacles, unlock=on Braindeath Island's mountain.] +TrackDefinition [arrayId=353, trackset=Trackset: Morytania, , fileId=501, name=Distant Land, unlock=at Burgh de Rott.] +TrackDefinition [arrayId=354, trackset=Trackset: "Only defined", , fileId=504, name=Fangs For the Memory, unlock=during In Aid of the Myreque.] +TrackDefinition [arrayId=355, trackset=Trackset: "Only defined", , fileId=505, name=Pharaoh's Tomb, unlock=at the Agility Pyramid.] +TrackDefinition [arrayId=356, trackset=Trackset: "Only defined", , fileId=506, name=Land Down Under, unlock=during Royal Trouble.] +TrackDefinition [arrayId=357, trackset=Trackset: "Only defined", , fileId=508, name=Meddling Kids, unlock=during Royal Trouble.] +TrackDefinition [arrayId=358, trackset=Trackset: "Only defined", , fileId=509, name=Corridors of Power, unlock=during Royal Trouble.] +TrackDefinition [arrayId=359, trackset=Trackset: "Only defined", , fileId=510, name=Slither and Thither, unlock=at the sea snake cave in Royal Trouble.] +TrackDefinition [arrayId=360, trackset=Trackset: "Only defined", , fileId=511, name=In the Clink, unlock=during the Prison Pete random event.] +TrackDefinition [arrayId=361, trackset=Trackset: Port, , fileId=515, name=Mudskipper Melody, unlock=at Mudskipper Point.] +TrackDefinition [arrayId=362, trackset=Trackset: "Only defined", , fileId=517, name=Subterranea, unlock=in Waterbirth Island Dungeon.] +TrackDefinition [arrayId=363, trackset=Trackset: Cave, , fileId=519, name=Incantation, unlock=during Shadow of the Storm.] +TrackDefinition [arrayId=364, trackset=Trackset: "Only defined", , fileId=520, name=Grip of the Talon, unlock=during Shadow of the Storm.] +TrackDefinition [arrayId=365, trackset=Trackset: "Only defined", , fileId=198, name=Dagannoth Dawn, unlock=in Waterbirth Island Dungeon.] +TrackDefinition [arrayId=366, trackset=Trackset: "Only defined", , fileId=524, name=Xenophobe, unlock=in Waterbirth Island Dungeon.] +TrackDefinition [arrayId=367, trackset=Trackset: "Only defined", , fileId=525, name=Title Fight, unlock=at the Champion's Challenge underground area.] +TrackDefinition [arrayId=368, trackset=Trackset: "Only defined", , fileId=528, name=Victory is Mine, unlock=at the Champion's Challenge arena.] +TrackDefinition [arrayId=369, trackset=Trackset: "Only defined", , fileId=529, name=Woe of the Wyvern, unlock=at the Asgarnian Ice Dungeon's wyvern area.] +TrackDefinition [arrayId=370, trackset=Trackset: Port, , fileId=530, name=In the Brine, unlock=on Mos Le'Harmless.] +TrackDefinition [arrayId=371, trackset=Trackset: Christmas, , fileId=532, name=Diango's Little Helpers, unlock=at Diango's Christmas workshop.] +TrackDefinition [arrayId=372, trackset=Trackset: "Only defined", , fileId=533, name=Roll the Bones, unlock=at the Mage Training Arena's Creature Graveyard.] +TrackDefinition [arrayId=373, trackset=Trackset: "Only defined", , fileId=534, name=Mind Over Matter, unlock=at the Mage Training Arena's Telekinetic Theatre.] +TrackDefinition [arrayId=374, trackset=Trackset: "Only defined", , fileId=535, name=Golden Touch, unlock=at the Mage Training Arena's Alchemists' Playground.] +TrackDefinition [arrayId=375, trackset=, fileId=147, name= , unlock=default info] +TrackDefinition [arrayId=376, trackset=Trackset: "Only defined", , fileId=541, name=The Enchanter, unlock=at the Mage Training Arena's Enchanting Chamber.] +TrackDefinition [arrayId=377, trackset=Trackset: "Only defined", , fileId=207, name=Scape Hunter, unlock=automatically.] +TrackDefinition [arrayId=378, trackset=Trackset: Hunter (?), , fileId=544, name=Making Waves, unlock=during Swan Song.] +TrackDefinition [arrayId=379, trackset=Trackset: Port, , fileId=545, name=Cabin Fever, unlock=during Cabin Fever.] +TrackDefinition [arrayId=380, trackset=Trackset: "Only defined", , fileId=546, name=Last Stand, unlock=during Swan Song.] +TrackDefinition [arrayId=381, trackset=Trackset: "Only defined", , fileId=542, name=Lament, unlock=during Enakhra's Lament.] +TrackDefinition [arrayId=382, trackset=Trackset: Unknown. Troll?, , fileId=548, name=Poles Apart, unlock=at the Trollweiss and Rellekka Hunter area.] +TrackDefinition [arrayId=383, trackset=Trackset: "Only defined", , fileId=455, name=Scarabaeoidea, unlock=during Dealing with Scabaras.] +TrackDefinition [arrayId=384, trackset=Trackset: Hunter (?), , fileId=453, name=Jungle Hunt, unlock=at the Feldip Hunter area.] +TrackDefinition [arrayId=385, trackset=Trackset: Construction, , fileId=454, name=Home Sweet Home, unlock=at your player-owned house.] +TrackDefinition [arrayId=386, trackset=Trackset: Hunter (?), , fileId=460, name=Joy of the Hunt, unlock=at the Feldip Hunter area cave.] +TrackDefinition [arrayId=387, trackset=Trackset: Cave, , fileId=537, name=Dogs of War, unlock=at the Vault of War in the Stronghold of Security.] +TrackDefinition [arrayId=388, trackset=Trackset: "Only defined", , fileId=558, name=Food For Thought, unlock=at the Catacomb of Famine in the Stronghold of Security.] +TrackDefinition [arrayId=389, trackset=Trackset: "Only defined", , fileId=559, name=Malady, unlock=at the Pit of Pestilence in the Stronghold of Security.] +TrackDefinition [arrayId=390, trackset=Trackset: "Only defined", , fileId=560, name=Dance of Death, unlock=at the Sepulchre of Death in the Stronghold of Security.] +TrackDefinition [arrayId=391, trackset=Trackset: "Only defined", , fileId=565, name=Wrath and Ruin, unlock=at the anger room of Tolna's rift.] +TrackDefinition [arrayId=392, trackset=Trackset: "Only defined", , fileId=568, name=Storm Brew, unlock=at the killerwatt plane.] +TrackDefinition [arrayId=393, trackset=Trackset: "Only defined", , fileId=573, name=The Mad Mole, unlock=at Falador Mole Lair.] +TrackDefinition [arrayId=394, trackset=Trackset: Port, , fileId=576, name=Davy Jones's Locker, unlock=during Recipe for Disaster.] +TrackDefinition [arrayId=395, trackset=Trackset: "Only defined", , fileId=575, name=Chickened Out, unlock=at the Evil Chicken's lair.] +TrackDefinition [arrayId=396, trackset=Trackset: Kharidian, , fileId=477, name=Hot 'n' Bothered, unlock=during As a First Resort...] +TrackDefinition [arrayId=397, trackset=Trackset: "Only defined", , fileId=577, name=Mastermindless, unlock=during Recipe for Disaster.] +TrackDefinition [arrayId=398, trackset=Trackset: "Only defined", , fileId=582, name=Too Many Cooks..., unlock=during Recipe for Disaster.] +TrackDefinition [arrayId=399, trackset=Trackset: "Only defined", , fileId=583, name=Chef Surprize, unlock=during Recipe for Disaster.] +TrackDefinition [arrayId=400, trackset=Trackset: "Only defined", , fileId=587, name=Null and Void, unlock=at the Pest Control minigame landing area.] +TrackDefinition [arrayId=401, trackset=Trackset: "Only defined", , fileId=588, name=Pest Control, unlock=during the Pest Control minigame.] +TrackDefinition [arrayId=402, trackset=Trackset: Kharidian, , fileId=591, name=Tomb Raider, unlock=during the Pyramid Plunder minigame.] +TrackDefinition [arrayId=403, trackset=Trackset: "Only defined", , fileId=594, name=No Way Out, unlock=at the hopelessness room of Tolna's rift area.] +TrackDefinition [arrayId=404, trackset=Trackset: "Only defined", , fileId=600, name=Method of Madness, unlock=at the confusion room of Tolna's rift area.] +TrackDefinition [arrayId=405, trackset=Trackset: "Only defined", , fileId=602, name=Fear and Loathing, unlock=at the fear room of Tolna's rift area.] +TrackDefinition [arrayId=406, trackset=Trackset: Easter, , fileId=603, name=Funny Bunnies, unlock=during or after the Easter 2006 holiday event.] +TrackDefinition [arrayId=407, trackset=Trackset: "Only defined", , fileId=604, name=Assault and Battery, unlock=during the Barbarian Assault minigame.] +TrackDefinition [arrayId=408, trackset=Trackset: "Only defined", , fileId=606, name=The Depths, unlock=during Contact!] +TrackDefinition [arrayId=409, trackset=Trackset: Port, , fileId=610, name=Distillery Hilarity, unlock=at Trouble Brewing's distillery.] +TrackDefinition [arrayId=410, trackset=Trackset: Port, , fileId=611, name=Trouble Brewing, unlock=during the Trouble Brewing minigame.] +TrackDefinition [arrayId=411, trackset=Trackset: "Only defined", , fileId=612, name=Head to Head, unlock=during the Evil Twin random event.] +TrackDefinition [arrayId=412, trackset=Trackset: "Only defined", , fileId=614, name=Pinball Wizard, unlock=during the Pinball random event.] +TrackDefinition [arrayId=413, trackset=Trackset: "Only defined", , fileId=615, name=Beetle Juice, unlock=during Contact!] +TrackDefinition [arrayId=414, trackset=Trackset: Kharidian, , fileId=616, name=Back to Life, unlock=during Contact!] +TrackDefinition [arrayId=415, trackset=Trackset: Cave, , fileId=213, name=Labyrinth, unlock=during Contact!] +TrackDefinition [arrayId=416, trackset=Trackset: Cave, , fileId=493, name=Safety in Numbers, unlock=at the Stronghold of Player Safety.] +TrackDefinition [arrayId=417, trackset=Trackset: Wilderness, , fileId=586, name=Everlasting Fire, unlock=in the north-east corner of the Wilderness.] +TrackDefinition [arrayId=418, trackset=Trackset: Miscellania, , fileId=622, name=Waking Dream, unlock=during your dream in Lunar Diplomacy.] +TrackDefinition [arrayId=419, trackset=Trackset: Miscellania, , fileId=623, name=Dreamstate, unlock=during your dream in Lunar Diplomacy.] +TrackDefinition [arrayId=420, trackset=Trackset: Miscellania, , fileId=625, name=The Lunar Isle, unlock=at Lunar Isle.] +TrackDefinition [arrayId=421, trackset=Trackset: Miscellania, , fileId=627, name=Isle of Everywhere, unlock=on the east coast of Lunar Isle.] +TrackDefinition [arrayId=422, trackset=Trackset: Miscellania, , fileId=626, name=Way of the Enchanter, unlock=in the dungeon beneath Lunar Isle.] +TrackDefinition [arrayId=423, trackset=Trackset: "Only defined", , fileId=634, name=Warriors' Guild, unlock=at the Warriors' Guild.] +TrackDefinition [arrayId=424, trackset=Trackset: Port, , fileId=631, name=Life's a Beach!, unlock=at the coastal area of Mos Le'Harmless.] +TrackDefinition [arrayId=425, trackset=Trackset: Hunter (?), , fileId=633, name=On the Wing, unlock=during Fairy Tale Part II.] +TrackDefinition [arrayId=426, trackset=Trackset: "Only defined", , fileId=632, name=Little Cave of Horrors, unlock=in the cave horror dungeon beneath Mos Le'Harmless.] +TrackDefinition [arrayId=427, trackset=Trackset: "Only defined", , fileId=200, name=The Mollusc Menace, unlock=during Slug Menace.] +TrackDefinition [arrayId=428, trackset=Trackset: Port, , fileId=630, name=The Galleon, unlock=during Lunar Diplomacy.] +TrackDefinition [arrayId=429, trackset=Trackset: "Only defined", , fileId=638, name=H.A.M. Fisted, unlock=during Death to the Dorgeshuun.] +TrackDefinition [arrayId=430, trackset=Trackset: Morytania, , fileId=197, name=Lament of Meiyerditch, unlock=during the Darkness of Hallowvale.] +TrackDefinition [arrayId=431, trackset=Trackset: "Only defined", , fileId=640, name=Sigmund's Showdown, unlock=during Death to the Dorgeshuun.] +TrackDefinition [arrayId=432, trackset=Trackset: Port, , fileId=643, name=The Last Shanty, unlock=during the Darkness of Hallowvale.] +TrackDefinition [arrayId=433, trackset=Trackset: Morytania, , fileId=646, name=Night of the Vampyre, unlock=during the Darkness of Hallowvale.] +TrackDefinition [arrayId=434, trackset=Trackset: Zanaris, , fileId=126, name=We are the Fairies, unlock=on the cosmic entity plane during Fairy Tale Part II.] +TrackDefinition [arrayId=435, trackset=Trackset: "Only defined", , fileId=86, name=Dimension X, unlock=on the gorak plane in Fairy Tale Part II.] +TrackDefinition [arrayId=436, trackset=Trackset: Zanaris, , fileId=73, name=All's Fairy in Love and War, unlock=at the fairy resistance hideout in Fairy Tale Part II.] +TrackDefinition [arrayId=437, trackset=Trackset: "Only defined", , fileId=222, name=Major Miner, unlock=during Fremennik Isles.] +TrackDefinition [arrayId=438, trackset=Trackset: "Only defined", , fileId=221, name=Jester Minute, unlock=during Fremennik Isles.] +TrackDefinition [arrayId=439, trackset=Trackset: Fremennik Isles, , fileId=223, name=Norse Code, unlock=during Fremennik Isles.] +TrackDefinition [arrayId=440, trackset=Trackset: Fremennik Isles, , fileId=225, name=Volcanic Vikings, unlock=during Fremennik Isles.] +TrackDefinition [arrayId=441, trackset=Trackset: Ogre, , fileId=220, name=Island of the Trolls, unlock=during Fremennik Isles.] +TrackDefinition [arrayId=442, trackset=Trackset: "Only defined", , fileId=211, name=Pirates of Penance, unlock=during the Barbarian Assault minigame.] +TrackDefinition [arrayId=443, trackset=Trackset: "Only defined", , fileId=194, name=Brimstail's Scales, unlock=at Brimstail's cave.] +TrackDefinition [arrayId=444, trackset=Trackset: Port, , fileId=203, name=My Arm's Journey, unlock=during My Arm's Big Adventure.] +TrackDefinition [arrayId=445, trackset=Trackset: "Only defined", , fileId=201, name=Slug a Bug Ball, unlock=during the Slug Menace Quest.] +TrackDefinition [arrayId=446, trackset=Trackset: "Only defined", , fileId=202, name=Prime Time, unlock=during Elemental Workshop II.] +TrackDefinition [arrayId=447, trackset=Trackset: "Only defined", , fileId=274, name=Rising Damp, unlock=during Olaf's Quest.] +TrackDefinition [arrayId=448, trackset=Trackset: "Only defined", , fileId=620, name=Where Eagles Lair, unlock=during Eagles' Peak.] +TrackDefinition [arrayId=449, trackset=Trackset: Ogre, , fileId=224, name=Ogre the Top, unlock=during Fremennik Isles.] +TrackDefinition [arrayId=450, trackset=Trackset: "Only defined", , fileId=237, name=Work Work Work, unlock=during Tower of Life.] +TrackDefinition [arrayId=451, trackset=Trackset: "Only defined", , fileId=235, name=Magic Magic Magic, unlock=during Tower of Life.] +TrackDefinition [arrayId=452, trackset=Trackset: "Only defined", , fileId=236, name=Mutant Medley, unlock=during Tower of Life.] +TrackDefinition [arrayId=453, trackset=Trackset: "Only defined", , fileId=240, name=Dorgeshuun City, unlock=at Dorgesh-Kaan.] +TrackDefinition [arrayId=454, trackset=Trackset: Goblin, , fileId=249, name=Dorgeshuun Deep, unlock=at the Dorgesh-Kaan caves.] +TrackDefinition [arrayId=455, trackset=Trackset: "Only defined", , fileId=206, name=Floating Free, unlock=during An Enlightened Journey.] +TrackDefinition [arrayId=456, trackset=Trackset: "Only defined", , fileId=204, name=Roc and Roll, unlock=during My Arm's Big Adventure.] +TrackDefinition [arrayId=457, trackset=Trackset: Halloween, , fileId=205, name=High Spirits, unlock=during or after the Halloween 2006 holiday event.] +TrackDefinition [arrayId=458, trackset=Trackset: "Only defined", , fileId=309, name=Looking Back, unlock=at Varrock Museum.] +TrackDefinition [arrayId=459, trackset=Trackset: Christmas, , fileId=208, name=Jungle Island XMAS, unlock=during or after the Christmas 2006 holiday event.] +TrackDefinition [arrayId=460, trackset=Trackset: Christmas, , fileId=210, name=Sea Shanty XMAS, unlock=during or after the Christmas 2006 holiday event.] +TrackDefinition [arrayId=461, trackset=Trackset: Christmas, , fileId=209, name=Jungle Bells, unlock=during or after the Christmas 2006 holiday event.] +TrackDefinition [arrayId=462, trackset=, fileId=230, name=Garden of Summer, unlock=during the Sorceress's Garden minigame.] +TrackDefinition [arrayId=463, trackset=, fileId=229, name=Garden of Spring, unlock=during the Sorceress's Garden minigame.] +TrackDefinition [arrayId=464, trackset=, fileId=231, name=Garden of Winter, unlock=during the Sorceress's Garden minigame.] +TrackDefinition [arrayId=465, trackset=, fileId=228, name=Garden of Autumn, unlock=during the Sorceress's Garden minigame.] +TrackDefinition [arrayId=466, trackset=Trackset: Iceberg/Asgarnian ice dungeon/muspah's tomb, , fileId=217, name=Have an Ice Day, unlock=during Cold War.] +TrackDefinition [arrayId=467, trackset=Trackset: "Only defined", , fileId=238, name=Zombiism, unlock=during The Great Brain Robbery.] +TrackDefinition [arrayId=468, trackset=Trackset: "Only defined", , fileId=234, name=Creature Cruelty, unlock=during Tower of Life.] +TrackDefinition [arrayId=469, trackset=Trackset: Cave, , fileId=272, name=Alternative Root, unlock=during What Lies Below.] +TrackDefinition [arrayId=470, trackset=Trackset: "Only defined", , fileId=216, name=Espionage, unlock=during Cold War.] +TrackDefinition [arrayId=471, trackset=Trackset: "Only defined", , fileId=214, name=Undead Dungeon, unlock=in Tarn's Lair.] +TrackDefinition [arrayId=472, trackset=Trackset: "Only defined", , fileId=275, name=Slice of Station, unlock=during Another Slice of H.A.M..] +TrackDefinition [arrayId=473, trackset=Trackset: "Only defined", , fileId=367, name=Barb Wire, unlock=while learning barbarian skills.] +TrackDefinition [arrayId=474, trackset=Trackset: "Only defined", , fileId=349, name=Impetuous, unlock=during the Impetuous Impulses minigame.] +TrackDefinition [arrayId=475, trackset=Trackset: Easter, , fileId=273, name=Easter Jig, unlock=during or after the Easter 2007 holiday event.] +TrackDefinition [arrayId=476, trackset=, fileId=279, name=Ham Attack, unlock=during Another Slice of H.A.M..] +TrackDefinition [arrayId=477, trackset=Trackset: "Only defined", , fileId=281, name=Slice of Silent Movie, unlock=during Another Slice of H.A.M..] +TrackDefinition [arrayId=478, trackset=Trackset: "Only defined", , fileId=276, name=Ham and Seek, unlock=during Another Slice of H.A.M..] +TrackDefinition [arrayId=479, trackset=Trackset: Wilderness, , fileId=450, name=Venomous, unlock=at the Scorpion Pit in the Wilderness.] +TrackDefinition [arrayId=480, trackset=Trackset: "Only defined", , fileId=150, name=Mouse Trap, unlock=during Grim Tales.] +TrackDefinition [arrayId=481, trackset=Trackset: "Only defined", , fileId=23, name=Fe Fi Fo Fum, unlock=during Grim Tales.] +TrackDefinition [arrayId=482, trackset=Trackset: "Only defined", , fileId=371, name=School's Out, unlock=during the Pattern Recognition random event.] +TrackDefinition [arrayId=483, trackset=Trackset: "Only defined", , fileId=299, name=Inadequacy, unlock=during Dream Mentor.] +TrackDefinition [arrayId=484, trackset=Trackset: "Only defined", , fileId=298, name=Illusive, unlock=during Dream Mentor.] +TrackDefinition [arrayId=485, trackset=Trackset: "Only defined", , fileId=283, name=Everlasting, unlock=during Dream Mentor.] +TrackDefinition [arrayId=486, trackset=Trackset: "Only defined", , fileId=300, name=Untouchable, unlock=during Dream Mentor.] +TrackDefinition [arrayId=487, trackset=Trackset: "Only defined", , fileId=301, name=Down and Out, unlock=during Dream Mentor.] +TrackDefinition [arrayId=488, trackset=Trackset: "Only defined", , fileId=302, name=On the Up, unlock=during Dream Mentor.] +TrackDefinition [arrayId=489, trackset=Trackset: "Only defined", , fileId=365, name=Melzar's Maze, unlock=during Dragon Slayer.] +TrackDefinition [arrayId=490, trackset=Trackset: "Only defined", , fileId=391, name=Zamorak Zoo, unlock=in the God Wars Dungeon.] +TrackDefinition [arrayId=491, trackset=Trackset: "Only defined", , fileId=408, name=Strength of Saradomin, unlock=in the God Wars Dungeon.] +TrackDefinition [arrayId=492, trackset=Trackset: "Only defined", , fileId=386, name=Bandos Battalion, unlock=in the God Wars Dungeon.] +TrackDefinition [arrayId=493, trackset=Trackset: "Only defined", , fileId=404, name=Armadyl Alliance, unlock=in the God Wars Dungeon.] +TrackDefinition [arrayId=494, trackset=Trackset: "Only defined", , fileId=399, name=Armageddon, unlock=in the God Wars Dungeon.] +TrackDefinition [arrayId=495, trackset=Trackset: "Only defined", , fileId=421, name=Storeroom Shuffle, unlock=during Path of Glouphrie.] +TrackDefinition [arrayId=496, trackset=Trackset: Tirannwn, , fileId=414, name=The Longramble Scramble, unlock=during Path of Glouphrie.] +TrackDefinition [arrayId=497, trackset=Trackset: Tirannwn, , fileId=426, name=Waste Defaced, unlock=during Path of Glouphrie.] +TrackDefinition [arrayId=498, trackset=Trackset: "Only defined", , fileId=374, name=Knightmare, unlock=at the Black Knights' Fortress.] +TrackDefinition [arrayId=499, trackset=Trackset: "Only defined", , fileId=382, name=Lore and Order, unlock=during King's Ransom.] +TrackDefinition [arrayId=500, trackset=Trackset: "Only defined", , fileId=417, name=Terrorbird Tussle, unlock=during Path of Glouphrie.] +TrackDefinition [arrayId=501, trackset=Trackset: "Only defined", , fileId=428, name=Altar Ego, unlock=at Ourania Altar.] +TrackDefinition [arrayId=502, trackset=Trackset: "Only defined", , fileId=427, name=Bolrie's Diary, unlock=during Path of Glouphrie.] +TrackDefinition [arrayId=503, trackset=Trackset: "Only defined", , fileId=416, name=Healin' Feelin', unlock=during Path of Glouphrie.] +TrackDefinition [arrayId=504, trackset=, fileId=456, name=Animal Apogee, unlock=during Wolf Whistle.] +TrackDefinition [arrayId=505, trackset=Trackset: "Only defined", , fileId=440, name=Temple of Tribes, unlock=during Land of the Goblins.] +TrackDefinition [arrayId=506, trackset=Trackset: "Only defined", , fileId=439, name=Catacombs and Tombs, unlock=during Land of the Goblins.] +TrackDefinition [arrayId=507, trackset=Trackset: "Only defined", , fileId=437, name=Zanik's Theme, unlock=during Land of the Goblins.] +TrackDefinition [arrayId=508, trackset=Trackset: "Only defined", , fileId=433, name=Dusk in Yu'biusk, unlock=during Land of the Goblins.] +TrackDefinition [arrayId=509, trackset=Trackset: "Only defined", , fileId=432, name=Grimly Fiendish, unlock=during or after the Halloween 2007 holiday event.] +TrackDefinition [arrayId=510, trackset=Trackset: "Only defined", , fileId=451, name=Tune from the Dune, unlock=during Dealing with Scabaras.] +TrackDefinition [arrayId=511, trackset=Trackset: "Only defined", , fileId=472, name=Spa Bizarre, unlock=during As a First Resort...] +TrackDefinition [arrayId=512, trackset=Trackset: "Only defined", , fileId=452, name=Copris Lunaris, unlock=during Dealing with Scabaras.] +TrackDefinition [arrayId=513, trackset=Trackset: Tree Gnome Stronghold, , fileId=348, name=Narnode's Theme, unlock=beneath the Grand Tree.] +TrackDefinition [arrayId=514, trackset=Trackset: "Only defined", , fileId=441, name=Tournament!, unlock=during a Duel Arena Tournament.] +TrackDefinition [arrayId=515, trackset=Trackset: "Only defined", , fileId=442, name=Clan Wars, unlock=during the Clan Wars minigame.] +TrackDefinition [arrayId=516, trackset=Trackset: "Only defined", , fileId=487, name=Charmin' Farmin', unlock=during the Vinesweeper minigame.] +TrackDefinition [arrayId=517, trackset=Trackset: "Only defined", , fileId=444, name=Bounty Hunter Level 1, unlock=while playing Bounty Hunter.] +TrackDefinition [arrayId=518, trackset=Trackset: "Only defined", , fileId=443, name=Bounty Hunter Level 2, unlock=while playing Bounty Hunter.] +TrackDefinition [arrayId=519, trackset=Trackset: "Only defined", , fileId=445, name=Bounty Hunter Level 3, unlock=while playing Bounty Hunter.] +TrackDefinition [arrayId=520, trackset=Trackset: "Only defined", , fileId=401, name=The Adventurer, unlock=automatically.] +TrackDefinition [arrayId=521, trackset=Trackset: "Only defined", , fileId=499, name=Creepy, unlock=during Kennith's Concerns.] +TrackDefinition [arrayId=522, trackset=Trackset: "Only defined", , fileId=500, name=A New Menace, unlock=during Kennith's Concerns.] +TrackDefinition [arrayId=523, trackset=Trackset: "Only defined", , fileId=147, name= , unlock=automatically.] +TrackDefinition [arrayId=524, trackset=Trackset: "Only defined", , fileId=350, name= , unlock=not unlockable!] +TrackDefinition [arrayId=525, trackset=Trackset: "Only defined", , fileId=360, name= , unlock=not unlockable!] +TrackDefinition [arrayId=526, trackset=Trackset: "Only defined", , fileId=195, name= , unlock=not unlockable!] +TrackDefinition [arrayId=527, trackset=Trackset: "Only defined", , fileId=219, name= , unlock=not unlockable!] +TrackDefinition [arrayId=528, trackset=Trackset: "Only defined", , fileId=218, name= , unlock=not unlockable!] +TrackDefinition [arrayId=529, trackset=Trackset: "Only defined", , fileId=227, name= , unlock=not unlockable!] +TrackDefinition [arrayId=530, trackset=Trackset: "Only defined", , fileId=196, name= , unlock=not unlockable!] +TrackDefinition [arrayId=531, trackset=Trackset: Jungle, , fileId=431, name= , unlock=not unlockable!] +TrackDefinition [arrayId=532, trackset=Trackset: "Only defined", , fileId=574, name= , unlock=not unlockable!] +TrackDefinition [arrayId=533, trackset=Trackset: "Only defined", , fileId=239, name=Brain Battle, unlock=on completion of The Great Brain Robbery.] +TrackDefinition [arrayId=534, trackset=Trackset: "Only defined", , fileId=406, name= , unlock=not unlockable!] +TrackDefinition [arrayId=535, trackset=Trackset: "Only defined", , fileId=226, name= , unlock=not unlockable!] +TrackDefinition [arrayId=536, trackset=Trackset: "Only defined", , fileId=250, name=Surok's Theme, unlock=on completion of What Lies Below.] +TrackDefinition [arrayId=537, trackset=Trackset: "Only defined", , fileId=233, name= , unlock=not unlockable!] +TrackDefinition [arrayId=538, trackset=Trackset: "Only defined", , fileId=215, name= , unlock=not unlockable!] +TrackDefinition [arrayId=539, trackset=Trackset: "Only defined", , fileId=315, name= , unlock=not unlockable!] +TrackDefinition [arrayId=540, trackset=Trackset: "Only defined", , fileId=410, name= , unlock=not unlockable!] +TrackDefinition [arrayId=541, trackset=Trackset: "Only defined", , fileId=405, name= , unlock=not unlockable!] +TrackDefinition [arrayId=542, trackset=Trackset: "Only defined", , fileId=484, name= , unlock=not unlockable!] +TrackDefinition [arrayId=543, trackset=Trackset: "Only defined", , fileId=199, name= , unlock=not unlockable!] +TrackDefinition [arrayId=544, trackset=Trackset: "Only defined", , fileId=212, name= , unlock=not unlockable!] +TrackDefinition [arrayId=545, trackset=Trackset: "Only defined", , fileId=297, name= , unlock=not unlockable!] +TrackDefinition [arrayId=546, trackset=Trackset: "Only defined", , fileId=480, name= , unlock=not unlockable!] +TrackDefinition [arrayId=547, trackset=Trackset: Track 547, , fileId=232, name= , unlock=not unlockable!] +TrackDefinition [arrayId=548, trackset=Trackset: "Only defined", , fileId=368, name= , unlock=not unlockable!] +TrackDefinition [arrayId=549, trackset=Trackset: "Only defined", , fileId=458, name= , unlock=not unlockable!] +TrackDefinition [arrayId=550, trackset=Trackset: "Only defined", , fileId=430, name= , unlock=not unlockable!] +TrackDefinition [arrayId=551, trackset=Trackset: "Only defined", , fileId=422, name= , unlock=not unlockable!] +TrackDefinition [arrayId=552, trackset=Trackset: "Only defined", , fileId=423, name= , unlock=not unlockable!] +TrackDefinition [arrayId=553, trackset=Trackset: "Only defined", , fileId=424, name= , unlock=not unlockable!] +TrackDefinition [arrayId=554, trackset=Trackset: "Only defined", , fileId=446, name= , unlock=not unlockable!] +TrackDefinition [arrayId=555, trackset=Trackset: Varrock, , fileId=496, name=The Trade Parade, unlock=at the Grand Exchange.] +TrackDefinition [arrayId=556, trackset=Trackset: Jungle, , fileId=483, name=Jungle Community, unlock=to the north of Tai Bwo Wannai Village.] +TrackDefinition [arrayId=557, trackset=Trackset: "Only defined", , fileId=495, name= , unlock=not unlockable!] +TrackDefinition [arrayId=558, trackset=Trackset: "Only defined", , fileId=523, name=Icy Trouble Ahead, unlock=during the Perils of Ice Mountain.] +TrackDefinition [arrayId=559, trackset=Trackset: "Only defined", , fileId=522, name=Icy a Worried Gnome, unlock=during the Perils of Ice Mountain.] +TrackDefinition [arrayId=560, trackset=Trackset: "Only defined", , fileId=385, name= , unlock=not unlockable!] +TrackDefinition [arrayId=561, trackset=Trackset: "Only defined", , fileId=39, name= , unlock=not unlockable!] +TrackDefinition [arrayId=562, trackset=Trackset: "Only defined", , fileId=40, name= , unlock=not unlockable!] +TrackDefinition [arrayId=563, trackset=Trackset: "Only defined", , fileId=79, name= , unlock=not unlockable!] +TrackDefinition [arrayId=564, trackset=Trackset: "Only defined", , fileId=332, name= , unlock=not unlockable!] +TrackDefinition [arrayId=565, trackset=Trackset: "Only defined", , fileId=260, name= , unlock=not unlockable!] +TrackDefinition [arrayId=566, trackset=Trackset: "Only defined", , fileId=288, name= , unlock=not unlockable!] +TrackDefinition [arrayId=567, trackset=Trackset: "Only defined", , fileId=174, name= , unlock=not unlockable!] +TrackDefinition [arrayId=568, trackset=Trackset: "Only defined", , fileId=573, name= , unlock=not unlockable!] +TrackDefinition [arrayId=569, trackset=Trackset: "Only defined", , fileId=165, name= , unlock=not unlockable!] +TrackDefinition [arrayId=570, trackset=Trackset: "Only defined", , fileId=548, name= , unlock=not unlockable!] +TrackDefinition [arrayId=571, trackset=Trackset: "Only defined", , fileId=347, name= , unlock=not unlockable!] +TrackDefinition [arrayId=572, trackset=Trackset: "Only defined", , fileId=529, name= , unlock=not unlockable!] +TrackDefinition [arrayId=573, trackset=Trackset: "Only defined", , fileId=241, name= , unlock=not unlockable!] +TrackDefinition [arrayId=574, trackset=Trackset: "Only defined", , fileId=172, name= , unlock=not unlockable!] +TrackDefinition [arrayId=575, trackset=Trackset: "Only defined", , fileId=33, name= , unlock=not unlockable!] +TrackDefinition [arrayId=576, trackset=Trackset: "Only defined", , fileId=24, name= , unlock=not unlockable!] +TrackDefinition [arrayId=577, trackset=Trackset: "Only defined", , fileId=501, name=Distant Land, unlock=not unlockable!] +TrackDefinition [arrayId=578, trackset=Trackset: "Only defined", , fileId=314, name=Castle Wars, unlock=not unlockable!] +TrackDefinition [arrayId=579, trackset=Trackset: "Only defined", , fileId=588, name=Pest Control, unlock=not unlockable!] +TrackDefinition [arrayId=580, trackset=Trackset: "Only defined", , fileId=269, name=Competition, unlock=not unlockable!] +TrackDefinition [arrayId=581, trackset=Trackset: "Only defined", , fileId=548, name=Poles Apart, unlock=not unlockable!] +TrackDefinition [arrayId=582, trackset=Trackset: "Only defined", , fileId=372, name=Far Away, unlock=not unlockable!] +TrackDefinition [arrayId=583, trackset=Trackset: "Only defined", , fileId=4, name=Hell's Bells, unlock=not unlockable!] +TrackDefinition [arrayId=584, trackset=, fileId=512, name=Bloodbath, unlock=at the Blood Altar.] +TrackDefinition [arrayId=585, trackset=Trackset: Cave, , fileId=459, name=The Route of All Evil, unlock=in the Chaos Tunnels.] +TrackDefinition [arrayId=586, trackset=Trackset: Cave, , fileId=467, name=The Route of the Problem, unlock=in the Chaos Tunnels.] +TrackDefinition [arrayId=587, trackset=Trackset: "Only defined", , fileId=488, name=The Wrong Path, unlock=in the Chaos Tunnels.] +TrackDefinition [arrayId=588, trackset=, fileId=514, name=The Columbarium, unlock=during Myreque Part IV.] +TrackDefinition [arrayId=589, trackset=Trackset: "Only defined", , fileId=518, name=The Terrible Tunnels, unlock=during Myreque Part IV.] +TrackDefinition [arrayId=590, trackset=Trackset: Cave, , fileId=521, name=The Terrible Caverns, unlock=during Myreque Part IV.] +TrackDefinition [arrayId=591, trackset=Trackset: "Only defined", , fileId=527, name=Dillo-gence is Key, unlock=during TokTz-Ket-Dill.] +TrackDefinition [arrayId=592, trackset=Trackset: "Only defined", , fileId=526, name=Arma Gonna Get You, unlock=during TokTz-Ket-Dill.] +TrackDefinition [arrayId=593, trackset=Trackset: "Only defined", , fileId=531, name=TokTz-Ket-Ek-Mack, unlock=during TokTz-Ket-Dill.] +TrackDefinition [arrayId=594, trackset=Trackset: Port, , fileId=549, name=Jailbird, unlock=during Rocking Out.] +TrackDefinition [arrayId=595, trackset=Trackset: "Only defined", , fileId=502, name=Bittersweet Bunny, unlock=during or after the Easter 2008 holiday event.] +TrackDefinition [arrayId=596, trackset=Trackset: Port, , fileId=550, name=Something Fishy, unlock=during Rocking Out.] +TrackDefinition [arrayId=597, trackset=Trackset: "Only defined", , fileId=539, name=Under the Sand, unlock=during Smoking Kills.] +TrackDefinition [arrayId=598, trackset=Trackset: "Only defined", , fileId=540, name=Desert Smoke, unlock=during Smoking Kills.] +TrackDefinition [arrayId=599, trackset=Trackset: "Only defined", , fileId=551, name=A Pirate's Life for Me, unlock=during Rocking Out.] +TrackDefinition [arrayId=600, trackset=Trackset: "Only defined", , fileId=513, name=Conspiracy: Part 1, unlock=during Myreque Part IV.] +TrackDefinition [arrayId=601, trackset=Trackset: "Only defined", , fileId=516, name=Conspiracy: Part 2, unlock=during Myreque Part IV.] +TrackDefinition [arrayId=602, trackset=Trackset: "Only defined", , fileId=457, name=Scape Summon, unlock=automatically.] +TrackDefinition [arrayId=603, trackset=Trackset: "Only defined", , fileId=507, name=Guthix's Hunter, unlock=during the Fist of Guthix minigame.] +TrackDefinition [arrayId=604, trackset=Trackset: "Only defined", , fileId=503, name=Waiting for the Hunt, unlock=in the Fist of Guthix minigame waiting room.] +TrackDefinition [arrayId=605, trackset=Trackset: "Only defined", , fileId=536, name=Cool for Ali Cats, unlock=during Smoking Kills.] +TrackDefinition [arrayId=606, trackset=Trackset: "Only defined", , fileId=561, name=Second Vision, unlock=at the Runecrafting Guild.] +TrackDefinition [arrayId=607, trackset=Trackset: "Only defined", , fileId=569, name=Undead Army, unlock=during Defender of Varrock.] +TrackDefinition [arrayId=608, trackset=Trackset: "Only defined", , fileId=566, name=Zombie Invasion, unlock=during Defender of Varrock.] +TrackDefinition [arrayId=609, trackset=Trackset: "Only defined", , fileId=570, name=The Ruins of Camdozaal, unlock=during Defender of Varrock.] +TrackDefinition [arrayId=610, trackset=Trackset: "Only defined", , fileId=567, name=Dream Theatre, unlock=during Defender of Varrock.] +TrackDefinition [arrayId=611, trackset=Trackset: "Only defined", , fileId=552, name=The Mentor, unlock=automatically.] +TrackDefinition [arrayId=612, trackset=Trackset: "Only defined", , fileId=543, name=Slain to Waste, unlock=during Smoking Kills.] +TrackDefinition [arrayId=613, trackset=Trackset: "Only defined", , fileId=555, name=Ardougne Ago, unlock=during Meeting History.] +TrackDefinition [arrayId=614, trackset=Trackset: "Only defined", , fileId=556, name=Sarah's Lullaby, unlock=not unlockable!] +TrackDefinition [arrayId=615, trackset=Trackset: "Only defined", , fileId=553, name=Shining Spirit, unlock=during Spirit of Summer.] +TrackDefinition [arrayId=616, trackset=Trackset: "Only defined", , fileId=554, name=Troubled Spirit, unlock=during Spirit of Summer.] +TrackDefinition [arrayId=617, trackset=Trackset: "Only defined", , fileId=564, name=Bane of Summer, unlock=during Summer's End.] +TrackDefinition [arrayId=618, trackset=Trackset: "Only defined", , fileId=563, name=The Vacant Abyss, unlock=during Summer's End.] +TrackDefinition [arrayId=619, trackset=Trackset: "Only defined", , fileId=557, name=Historic Memories, unlock=not unlockable!] +TrackDefinition [arrayId=620, trackset=Trackset: "Only defined", , fileId=578, name=Stealing Creation, unlock=during the Stealing Creation minigame.] +TrackDefinition [arrayId=621, trackset=Trackset: "Only defined", , fileId=562, name=Circus, unlock=during the Circus minigame.] +TrackDefinition [arrayId=622, trackset=Trackset: "Only defined", , fileId=579, name=Dangerous Logic, unlock=during the While Guthix Sleeps Quest.] +TrackDefinition [arrayId=623, trackset=Trackset: "Only defined", , fileId=585, name=Black of Knight, unlock=during the While Guthix Sleeps Quest.] +TrackDefinition [arrayId=624, trackset=, fileId=571, name=The Art of Hocus-Pocus, unlock=during or after the Halloween 2008 holiday event.] +TrackDefinition [arrayId=625, trackset=Trackset: "Only defined", , fileId=572, name=Magic and Mystery, unlock=during or after the Halloween 2008 holiday event.] +TrackDefinition [arrayId=626, trackset=Trackset: "Only defined", , fileId=589, name=The Sound of Guthix, unlock=during the While Guthix Sleeps Quest.] +TrackDefinition [arrayId=627, trackset=, fileId=580, name= , unlock=not unlockable!] +TrackDefinition [arrayId=628, trackset=Trackset: "Only defined", , fileId=584, name=Temple Desecrated, unlock=during the While Guthix Sleeps Quest.] +TrackDefinition [arrayId=629, trackset=, fileId=147, name= , unlock=default info] +TrackDefinition [arrayId=630, trackset=Trackset: "Only defined", , fileId=596, name=The Phoenix, unlock=during the In Pyre Need quest.] +TrackDefinition [arrayId=631, trackset=, fileId=147, name= , unlock=default info] +TrackDefinition [arrayId=632, trackset=Trackset: "Only defined", , fileId=581, name=The Evil Within, unlock=during the While Guthix Sleeps Quest.] \ No newline at end of file diff --git a/dumps/530/quest_configs_script.txt b/dumps/530/quest_configs_script.txt new file mode 100644 index 0000000..e5a5f85 --- /dev/null +++ b/dumps/530/quest_configs_script.txt @@ -0,0 +1,491 @@ +(Thanks to Cjay0091 on Rune-server) +(May work with our revision have to implement to test) + +All available quests: +/* + * Script decompiled by jagdecs2 v3.5 + * Decompiler opts: + * -------------- + * t1LocalAnalyzer:true + * t2LocalAnalyzer:true + * beautifier:true + * -------------- + * Made by mgi125 ;) + */ + + +int script_2193(int a0) { + switch (a0) { + case 147: + return script_2157(vars['cfg1295'], 1000); + case 159: + return script_2157(vars['cfg3820'].bitcfg19966, 170); + case 1: + return script_2157(vars['cfg2492'], 2); + case 2: + return script_2157(vars['cfg3518'].bitcfg17841, 9); + case 4: + return script_2157(vars['cfg2268'], 10); + case 5: + return script_2157(vars['cfg2183'], 3); + case 6: + return script_2157(vars['cfg2137'].bitcfg9363, 6); + case 7: + return script_2157(vars['cfg2669'], 2); + case 8: + return script_2157(vars['cfg2547'], 7); + case 9: + return script_2157(vars['cfg2227'], 4); + case 11: + return script_2157(vars['cfg2324'], 5); + case 13: + return script_2157(vars['cfg2689'], 6); + case 15: + return script_2159(vars['cfg2738'], 7, vars['cfg2739'], 4); + case 16: + return script_2157(vars['cfg2170'].bitcfg9655, 3); + case 18: + return script_2157(vars['cfg2409'].bitcfg11411, 240); + case 19: + return script_2157(vars['cfg2598'].bitcfg12797, 110); + case 20: + return script_2157(vars['cfg2772'], 65); + case 21: + return script_2157(vars['cfg2535'], 16); + case 22: + return script_2157(vars['cfg2326'], 140); + case 23: + return script_2157(vars['cfg2197'], 8); + case 24: + return script_2157(vars['cfg2260'].bitcfg10292, 130); + case 25: + return script_2157(vars['cfg2272'].bitcfg10448, 14); + case 26: + if (vars['cfg2615'] > 6) + return 2; + if (vars['cfg2615'] == 0 && vars['cfg2616'].bitcfg12894 == 0) + return 0; + return 1; + case 27: + return script_2157(vars['cfg2250'].bitcfg10204, 320); + case 28: + return script_2157(vars['cfg2422'].bitcfg11533, 13); + case 29: + if (vars['cfg2339'] >= 80) + return 2; + return script_2157(vars['cfg2337'].bitcfg10848, 65); + case 30: + return script_2157(vars['cfg2151'].bitcfg9482, 15); + case 31: + return script_2157(vars['cfg2453'].bitcfg11914, 80); + case 32: + return script_2157(vars['cfg2205'], 9); + case 33: + if (vars['cfg2695'] >= 4) + return 2; + return script_2157(vars['cfg2694'].bitcfg13366, 8); + case 34: + return script_2157(vars['cfg2732'], 11); + case 35: + return script_2157(vars['cfg2549'], 110); + case 36: + return script_2157(vars['cfg2785'].bitcfg13931, 40); + case 37: + if (_testbit(vars['cfg2675'], 20) == 1) + return 2; + if (_testbit(vars['cfg2675'], 1) == 0) + return 0; + return 1; + case 38: + return script_2157(vars['cfg2744'].bitcfg13674, 11); + case 39: + return script_2157(vars['cfg2187'].bitcfg9740, 70); + case 40: + return script_2157(vars['cfg2541'].bitcfg12529, 200); + case 41: + return script_2157(vars['cfg2599'].bitcfg12813, 60); + case 42: + return script_2157(vars['cfg2680'].bitcfg13286, 90); + case 43: + return script_2157(vars['cfg2474'].bitcfg12056, 90); + case 44: + return script_2157(vars['cfg2663'], 11); + case 45: + return script_2157(vars['cfg2181'].bitcfg9712, 28); + case 46: + return script_2157(vars['cfg2595'], 14); + case 47: + return script_2157(vars['cfg2331'], 5); + case 48: + return script_2157(vars['cfg2454'].bitcfg11917, 140); + case 49: + return script_2157(vars['cfg2262'], 10); + case 50: + return script_2157(vars['cfg2353'], 10); + case 51: + return script_2157(vars['cfg2703'].bitcfg13397, 60); + case 52: + return script_2157(vars['cfg2175'], 6); + case 53: + return script_2157(vars['cfg2715'].bitcfg13497, 8); + case 54: + return script_2157(vars['cfg2676'].bitcfg13266, 50); + case 55: + return script_2157(vars['cfg2728'].bitcfg13639, 10); + case 56: + return script_2157(vars['cfg2740'], 160); + case 57: + return script_2157(vars['cfg2799'].bitcfg14030, 160); + case 58: + return script_2157(vars['cfg2201'], 11); + case 59: + return script_2157(vars['cfg2592'], 9); + case 60: + return script_2157(vars['cfg2618'], 15); + case 61: + return script_2157(vars['cfg2330'], 10); + case 62: + return script_2157(vars['cfg2411'].bitcfg11413, 10); + case 63: + return script_2157(vars['cfg2357'].bitcfg10987, 26); + case 64: + return script_2157(vars['cfg2417'].bitcfg11498, 430); + case 65: + return script_2157(vars['cfg2696'], 105); + case 66: + return script_2157(vars['cfg2484'], 12); + case 67: + return script_2157(vars['cfg2265'], 75); + case 68: + return script_2157(vars['cfg2551'], 6); + case 69: + return script_2157(vars['cfg2787'].bitcfg13963, 11); + case 70: + return script_2157(vars['cfg2253'].bitcfg10236, 190); + case 71: + return script_2157(vars['cfg2173'].bitcfg9664, 4); + case 72: + return script_2157(vars['cfg2178'], 7); + case 73: + return script_2158(vars['cfg2762'], 1, 9); + case 74: + return script_2157(vars['cfg2370'], 80); + case 75: + return script_2157(vars['cfg2690'].bitcfg13349, 70); + case 76: + return script_2157(vars['cfg2777'], 8); + case 77: + return script_2158(vars['cfg2303'].bitcfg10560, 9, 60); + case 78: + return script_2157(vars['cfg2364'], 2); + case 79: + return script_2157(vars['cfg2230'].bitcfg9987, 320); + case 80: + return script_2157(vars['cfg2355'], 110); + case 81: + return script_2157(vars['cfg2796'], 7); + case 82: + return script_2157(vars['cfg2671'], 280); + case 83: + return script_2157(vars['cfg2386'], 29); + case 84: + return script_2157(vars['cfg2171'], 60); + case 85: + return script_2157(vars['cfg2612'].bitcfg12837, 4); + case 86: + return script_2157(vars['cfg2460'].bitcfg11975, 127); + case 87: + return script_2157(vars['cfg2579'].bitcfg12708, 5); + case 88: + return script_2157(vars['cfg2508'].bitcfg12355, 2); + case 89: + return script_2157(vars['cfg2102'], 15); + case 90: + return script_2157(vars['cfg2286'], 6); + case 91: + return script_2157(vars['cfg2515'].bitcfg12425, 30); + case 92: + return script_2157(vars['cfg2100'], 19); + case 93: + return script_2157(vars['cfg2747'], 6); + case 94: + return script_2157(vars['cfg2700'], 12); + case 95: + return script_2157(vars['cfg2554'].bitcfg12626, 14); + case 96: + return script_2157(vars['cfg2620'], 85); + case 97: + return script_2157(vars['cfg2290'].bitcfg10495, 125); + case 98: + return script_2157(vars['cfg2274'], 3); + case 99: + return script_2157(vars['cfg2793'], 15); + case 100: + return script_2157(vars['cfg2511'].bitcfg12392, 13); + case 101: + return script_2157(vars['cfg2548'].bitcfg12609, 60); + case 102: + return script_2157(vars['cfg2390'].bitcfg11269, 200); + case 103: + return script_2158(vars['cfg2523'], 3, 6); + case 104: + return script_2157(vars['cfg2369'].bitcfg11085, 70); + case 105: + return script_2157(vars['cfg1573'].bitcfg4909, 2); + case 106: + return script_2157(vars['cfg2148'], 80); + case 107: + return script_2157(vars['cfg2236'], 100); + case 108: + return script_2157(vars['cfg2501'], 30); + case 109: + return script_2157(vars['cfg2276'], 7); + case 110: + return script_2157(vars['cfg2661'], 9); + case 111: + return script_2157(vars['cfg2783'], 5); + case 112: + return script_2157(vars['cfg2135'], 45); + case 113: + return script_2157(vars['cfg2347'], 50); + case 114: + if (vars['cfg2426'] == 10) + return 2; + if (_testbit(vars['cfg2427'], 11) == 0) + return 0; + return 1; + case 115: + return script_2157(vars['cfg2628'].bitcfg12923, 11); + case 116: + return script_2157(vars['cfg2397'], 13); + case 117: + return script_2157(vars['cfg2270'].bitcfg10430, 135); + case 118: + return script_2157(vars['cfg2666'].bitcfg13178, 340); + case 119: + return script_2157(vars['cfg2190'].bitcfg9803, 18); + case 120: + return script_2157(vars['cfg2082'], 130); + case 121: + return script_2157(vars['cfg2352'].bitcfg10939, 150); + case 122: + return script_2157(vars['cfg2419'].bitcfg11517, 80); + case 123: + return script_2157(vars['cfg2729'].bitcfg13650, 11); + case 124: + return script_2157(vars['cfg2155'].bitcfg9530, 28); + case 125: + return script_2157(vars['cfg2726'].bitcfg13606, 60); + case 126: + return script_2157(vars['cfg2392'].bitcfg11298, 90); + case 127: + return script_2157(vars['cfg2277'].bitcfg10474, 200); + case 128: + return script_2157(vars['cfg2670'].bitcfg13194, 65); + case 129: + return script_2157(vars['cfg2682'].bitcfg13322, 18); + case 130: + return script_2157(vars['cfg2706'].bitcfg13430, 700); + case 131: + if (vars['cfg2507'].bitcfg12349 >= 110) + return 2; + return script_2157(vars['cfg2506'].bitcfg12334, 35); + case 132: + return script_2158(vars['cfg2802'].bitcfg14041, 10, 200); + case 133: + return script_2157(vars['cfg2494'].bitcfg12210, 60); + case 134: + return script_2157(vars['cfg2395'].bitcfg11334, 100); + case 135: + return script_2157(vars['cfg2788'].bitcfg13978, 500); + case 136: + return script_2157(vars['cfg2371'].bitcfg11095, 150); + case 137: + return script_2157(vars['cfg2407'].bitcfg11386, 63); + case 138: + return script_2157(vars['cfg2091'].bitcfg9054, 250); + case 139: + return script_2157(vars['cfg2531'].bitcfg12462, 100); + case 140: + return script_2157(vars['cfg2470'].bitcfg12013, 80); + case 141: + return script_2157(vars['cfg2749'].bitcfg13718, 20); + case 142: + return script_2157(vars['cfg2719'].bitcfg13518, 90); + case 143: + return script_2157(vars['cfg2412'].bitcfg11428, 35); + case 144: + return script_2157(vars['cfg2485'].bitcfg12163, 250); + case 145: + return script_2157(vars['cfg2441'].bitcfg11858, 910); + case 146: + return script_2157(vars['cfg2248'].bitcfg10188, 30); + case 148: + return script_2157(vars['cfg2774'].bitcfg13876, 60); + case 149: + return script_2158(vars['cfg2627'].bitcfg12906, 3, 45); + case 150: + return script_2158(vars['cfg2383'].bitcfg11228, 10, 250); + case 155: + return script_2157(vars['cfg2379'].bitcfg11167, 60); + case 156: + return script_2157(vars['cfg2377'].bitcfg11151, 240); + case 157: + return script_2157(vars['cfg2372'].bitcfg11105, 90); + case 151: + return script_2158(vars['cfg2759'].bitcfg13734, 2, 140); + case 152: + return script_2157(vars['cfg2107'].bitcfg9136, 110); + case 153: + return script_2157(vars['cfg2198'].bitcfg9847, 50); + case 154: + return script_2158(vars['cfg2612'].bitcfg9902, 2, 5); + case 158: + return script_2158(vars['cfg2214'].bitcfg9928, 10, 180); + case 160: + return script_2157(vars['cfg2300'].bitcfg10544, 90); + case 161: + return script_2157(vars['cfg2297'].bitcfg10506, 46); + case 162: + return script_2157(vars['cfg2243'].bitcfg10095, 12); + case 163: + return script_2158(vars['cfg2342'].bitcfg10871, 3, 147); + case 165: + return script_2157(vars['cfg2349'].bitcfg10919, 35); + case 167: + return script_2157(vars['cfg2085'].bitcfg9023, 30); + case 168: + return script_2157(vars['cfg2543'].bitcfg12598, 150); + case 170: + return script_2157(vars['cfg2334'].bitcfg10826, 60); + case 171: + return script_2157(vars['cfg2635'].bitcfg13034, 90); + case 172: + return script_2157(vars['cfg2539'].bitcfg12504, 5); + case 173: + return script_2158(vars['cfg2638'].bitcfg13080, 2, 63); + case 14: + return script_2157(vars['cfg2780'].bitcfg13904, 90); + case 174: + return script_2157(vars['cfg2657'].bitcfg13118, 40); + case 17: + return script_2157(vars['cfg2111'].bitcfg9188, 100); + case 176: + return script_2157(vars['cfg2430'].bitcfg11610, 400); + case 179: + return script_2158(vars['cfg2130'].bitcfg9324, 10, 315); + case 12: + return script_2157(vars['cfg2160'].bitcfg9547, 120); + case 180: + return script_2157(vars['cfg2487'].bitcfg12170, 9); + case 181: + return script_2158(vars['cfg2165'].bitcfg9602, 10, 210); + case 182: + return script_2157(vars['cfg2124'].bitcfg9212, 50); + case 183: + return script_2158(vars['cfg2112'].bitcfg9199, 5, 250); + case 184: + return script_2157(vars['cfg2360'].bitcfg11020, 170); + case 187: + return script_2157(vars['cfg2498'].bitcfg12258, 100); + case 188: + return script_2157(vars['cfg2674'].bitcfg13240, 40); + case 190: + return script_2157(vars['cfg2095'].bitcfg9091, 170); + case 191: + return script_2157(vars['cfg2437'].bitcfg11683, 270); + case 178: + return script_2158(vars['cfg2632'].bitcfg12989, 5, 100); + case 164: + return 2; + case 192: + return script_2157(vars['cfg2570'].bitcfg12689, 75); + case 193: + return script_2158(vars['cfg2141'].bitcfg9391, 5, 175); + case 175: + return script_2157(vars['cfg2449'].bitcfg11870, 105); + case 177: + return script_2157(vars['cfg2449'].bitcfg9429, 120); + case 3: + return script_2158(vars['cfg2231'].bitcfg9998, 4, 55); + case 194: + return script_2157(vars['cfg3294'].bitcfg16863, 170); + case 195: + return script_2157(vars['cfg3289'].bitcfg16834, 120); + case 196: + return script_2157(vars['cfg3299'].bitcfg16905, 225); + case 197: + return script_2157(vars['cfg3527'].bitcfg18021, 250); + case 198: + return script_2157(vars['cfg3631'].bitcfg18565, 75); + case 199: + return script_2157(vars['cfg3872'].bitcfg20561, 300); + case 200: + return script_2157(vars['cfg3885'].bitcfg20621, 100); + case 201: + return script_2157(vars['cfg4170'].bitcfg21714, 190); + case 10: + return script_2158(vars['cfg4260'].bitcfg21841, 5, 175); + case 202: + return script_2157(vars['cfg4390'].bitcfg22270, 100); + case 203: + return script_2157(vars['cfg4484'].bitcfg4291, 200); + case 204: + return script_2157(vars['cfg4670'].bitcfg23198, 400); + case 205: + return script_2157(vars['cfg4854'].bitcfg25561, 50); + case 206: + return script_2158(vars['cfg5015'].bitcfg26245, 10, 200); + case 207: + return script_2157(vars['cfg5114'].bitcfg27012, 120); + case 208: + return script_2158(vars['cfg5157'].bitcfg27209, 5, 50); + case 209: + return script_2158(vars['cfg5157'].bitcfg27209, 5, 40); + case 210: + return script_2158(vars['cfg5159'].bitcfg27264, 5, 15); + case 211: + return script_2158(vars['cfg5160'].bitcfg27272, 5, 70); + case 212: + return script_2158(vars['cfg5161'].bitcfg27284, 5, 45); + case 213: + return script_2158(vars['cfg5162'].bitcfg27291, 5, 110); + case 214: + return script_2157(vars['cfg5743'].bitcfg28509, 105); + case 215: + return script_2157(vars['cfg5840'].bitcfg29077, 120); + case 216: + return script_2157(vars['cfg5869'].bitcfg29424, 250); + case 217: + return script_2157(vars['cfg5892'].bitcfg20929, 200); + case 218: + return script_2157(vars['cfg5952'].bitcfg30071, 200); + case 219: + return script_2157(vars['cfg6120'].bitcfg30520, 170); + } + return 0; +} + + + +Test Bit Code: + + + public void sendTestBit(int shift, int var, int value) { + for (int id = VarbitDef.size() - 1; id >= 0; id--) { + VarbitDef def = VarbitDef.get(id); + + if (def.baseVar == var && def.startBit == shift && def.endBit == shift) { + sendVarBit(id, value); + return; + } + } + + sendVar(var, getValue(var) ^ (1 << shift)); // This just inverts the bit. + } + + +Var values and what they represent: +0 - Unstarted +1 - Started +2 - Completed \ No newline at end of file diff --git a/dumps/530/quest_prefix_internal_names.txt b/dumps/530/quest_prefix_internal_names.txt new file mode 100644 index 0000000..56424c6 --- /dev/null +++ b/dumps/530/quest_prefix_internal_names.txt @@ -0,0 +1,313 @@ +This is an exhaustive list of internal names/quests up to RS3. +530 came out Feb 2009, so check for quests up to there if you're looking for a name. +You'll notice some of the earlier reworked quests have been renamed in RS3... +follow the "pre-rework" column instead and check the RS wiki to see what it was originally. + +Year Quest Name Quest Prefix Formerly (eg pre-rework) +2001 Cook's Assistant cook + Demon Slayer dslay demonslayer or demon + The Restless Ghost priest + Sheep Shearer sheep + Shield of Arrav phoenixgang blackarmgang + Ernest the Chicken haunted + Vampyre Slayer vampire + Imp Catcher imp + Stolen Hearts ozan1 prince + Diamond in the Rough ozan2 + What's Mine Is Yours pnr doric + Witch's Potion hetty + The Knight's Sword squire + Goblin Diplomacy gobdip + Pirate's Treasure hunt + Dragon Slayer dragon +2002 Druidic Ritual druid_quest_2 druid + Lost City zanaris + Witch's House ball + Merlin's Crystal arthur + Heroes' Quest hero + Bar Crawl barcrawl + Scorpion Catcher scorpcatcher + Family Crest crest + Tribal Totem totem + Fishing Contest fishingcompo + Monk's Friend drunkmonk + Temple of Ikov ikov + Clock Tower cog + Holy Grail grail + Tree Gnome Village tree + Fight Arena arena + Hazeel Cult hazeelcult + Sheep Herder sheepherder + Plague City elena + Sea Slug seaslug + Waterfall Quest waterfall + Biohazard biohazard + Jungle Potion junglepotion + The Grand Tree grandtree +2003 Shilo Village zombiequeen + Underground Pass upass + Observatory Quest itgronigen + The Tourist Trap desertrescue + Watch Tower itwatchtower + Dwarf Cannon mcannon + Murder Mystery murder + The Dig Site itexam + Gertrude's Cat fluffs + Legends' Quest legends + Rune Mysteries ariane1 runemysteries + Rune Memories ariane2 +2004 Big Chompy Bird Hunting chompybird + Elemental Workshop I elemental_workshop + Priest in Peril priest + Nature Spirit druidspirit + Death Plateau death + Troll Stronghold troll + Tai Bwo Wannai Trio tbwt + Regicide regicide + Eadgar's Ruse eadgar + Shades of Mort'ton morttonquest + The Fremennik Trials viking + Horror from the Deep horror + Throne of Miscellania misc + Monkey Madness mm + Haunted Mine hauntedmine +2005 Troll Romance troll_love + In Search of the Myreque route + Creature of Fenkenstrain fenk + Roving Elves roving_elves + Ghosts Ahoy ahoy + One Small Favour onesmallfavour + Mountain Daughter mdaughter + Between a Rock� dwarfrock + The Feud feud + The Golem golem + Desert Treasure deserttreasure + Icthlarin's Little Helper ics + Tears of Guthix tog + Zogre Flesh Eaters zogre + The Lost Tribe lost_tribe + Giant Dwarf giantdwarf + Enter the Abyss abyss + Recruitment Drive rd + Mourning's End mourning + Forgettable Tale of a Drunken Dwarf forget + The Curse of Zaros secret_ghost + Garden of Tranquillity garden + A Tail of Two Cats twocats + Wanted! wanted + Mourning's End Part II mourning + Rum Deal deal + Shadow of the Storm agrith + Making History makinghistory + Rat Catchers ratcatch + Spirits of the Elid elid + Devious Minds devious +2006 Hand in the Sand handsand + Enakhra's Lament enakh + Cabin Fever fever + A Fairy Tale I - Growing Pains fairy + Recipe for Disaster hundred + Recipe for Disaster: Freeing the Mountain Dwahundred_dwarf + Recipe for Disaster: Freeing the Goblin Gener100goblin + Recipe for Disaster: Freeing Pirate Pete 100_pirate + Recipe for Disaster: Freeing the Lumbridge Sa100guide + Recipe for Disaster: Freeing Evil Dave hundred_dave + Recipe for Disaster: Freeing Skrach Uglogwee 100_ogre + Recipe for Disaster: Freeing Sir Amik Varze chicken + Recipe for Disaster: Freeing King Awowogei hundred_ilm + In Aid of the Myreque myreque_2 + A Soul's Bane soulbane + Rag and Bone Man rag + Swan Song swansong + Royal Trouble royal + Death to the Dorgeshuun dttd + A Fairy Tale II - Cure a Queen fairy2 + Lunar Diplomacy lunar + The Eyes of Glouphrie eyeglo + The Darkness of Hallowvale myq3 + The Slug Menace slug2 + Elemental Workshop II elemental_quest_2 + My Arm's Big Adventure myarm + Enlightened Journey zep + Eagles' Peak eaglepeak + Animal Magnetism anma +2007 Contact! contact + Lair of Tarn Razorlor lotr + Cold War peng + The Fremennik Isles fris + The General's Shadow shadow_maj + Tower of Life tol + The Great Brain Robbery brain + What Lies Below surok + The Hunt for Surok dsd + Olaf's Quest olaf + Another Slice of H.A.M. slice + Dream Mentor dream + Grim Tales grim + King's Ransom kr + The Path of Glouphrie pog + Back to my Roots roots + One Foot in the Grave handsand2 + Land of the Goblins lotg + Hopespear's Will hopespears_will +2008 Dealing with Scabaras scab + Wolf Whistle wolf_quest_2 wolf + As a First Resort afr + Catapult Construction catcon + Kennith's Concerns ken + Legacy of Seergaze myq4 + Perils of Ice Mountain icemt + TokTz-Ket-Dill dillo + Smoking Kills smki + Desert Slayer Dungeon smki_miniquest + Rocking Out rocko + Spirit of Summer sum1 + Meeting History hist + All Fired Up firedup + Summer's End sum2 + Defender of Varrock zemo + Swept Away swept + Purple Cat swept_cat + While Guthix Sleeps luc2 + Myths of the White Lands motwl +2009 In Pyre Need phoenix + The Chosen Commander chosen + Glorious Memories glomem + The Tale of the Muspah mah1 + Missing My Mummy mom2 + Hunt for Red Raktuber peng_rak + The Curse of Arrav mah3 + Fur 'n Seek rag2 + Forgiveness of a Chaos Dwarf ra3 + Within the Light wtl + The Temple at Senntisten mah4 + Blood Runs Deep evq (Epic Viking Quest) +2010 Nomad's Requiem nom + Rune Mechanics rm + Blood Pact lumbcat + Buyers and Cellars thigui (Thieves' Guild) + From Tiny Acorns caper_acorns + Lost Her Marbles caper_marbles + A Guild of Our Own caper_ourown + A Fairy Tale III - Battle at Ork's Rift ft3 + Elemental Workshop III elem_3 + Quiet Before the Swarm vkq1 + Love Story love + A Void Dance vkq2 + Gunnar's Ground romcom + The Void Stares Back vkq3 + Do No Evil apmeken +2011 King of the Dwarves ra4 + The Prisoner of Glouphrie glo3 + Elemental Workshop IV elem_4 + A Clockwork Syringe acs + Three's Company fremsaga_signature + Vengeance fremsaga_vengeance + Thok It To 'Em fremsaga_thok + Deadliest Catch deadly + Salt in the Wound slug3 + The Branches of Darkmeyer myq5 + Ritual of the Mahjarrat mah5 + One Piercing Note opn +2012 The Firemaker's Curse fmc + Let Them Eat Pie ltep + The Elder Kiln tzhaar2 + Nadir fremsaga_bilrach + Thok Your Block Off fremsaga_thok2 + Song from the Depths qbd1 + Carnillean Rising carni + Some Like It Cold peng_pow + Doric's Task I pnr_artisan_task + Doric's Task II pnr_denulth_task + Doric's Task III pnr_goblin_task + Doric's Task IV pnr_artisan_task2 + Doric's Task V pnr_gnome_task + Doric's Task VI pnr_skulgrimen_task + Doric's Task VII pnr_santiri_task + Doric's Task VIII pnr_monkey_task + Boric's Task I pnr_boric_coal_task + Boric's Task II pnr_boric_ore_task + Boric's Task III pnr_boric_guild_task + The Brink of Extinction tzhaar3 + Wandering Ga'al tzhaar3_eegg +2013 Koschei's Troubles kharshai + The World Wakes tsd (The Sleeping Dog) + Bringing Home the Bacon bacon + The Death of Chivalry owen1 spy + Birthright of the Dwarves ra5 + Missing, Presumed Death sliske1 +2014 One of a Kind ooak + Mahjarrat Memories mahmem + Fate of the Gods tpr (The Purple Rose) + A Shadow over Ashdale ash1 + The Mighty Fall tmf + Plague's End me3 (Mourning's End Part III) + Broken Home house + Heart of Stone egq (Elder God Quest) +2015 Dishonour among Thieves sliske2 + Dimension of Disaster q200 + Dimension of Disaster: Shield of Arrav q200_soa + Dimension of Disaster: Demon Slayer q200_ds + Dimension of Disaster: Defender of Varrock q200_dov + Dimension of Disaster: Curse of Arrav q200_coa + Hero's Welcome dov (Death of V) + The Light Within seren (Seren quest) + The Lord of Vampyrium myq6 + Call of the Ancestors goebie1 + Beneath Cursed Tides tutisland +2016 Nomad's Elegy nomel + Tales of the God Wars gwd2_miniquest + Benedict's World Tour nxtwt (NXT World Tour) + In Memory of the Myreque myq7_memorial + The Lost Toys myq7_lost_toys + River of Blood myq7 + Kindred Spirits sister (Barrows Sister quest) + Gower Quest gower + Tales of Nomad nomel_pq + Children of Mah fotg2 + Impressing the Locals elr0 + Flag Fall elr1_minq_flag + Head of the Family elr1_minq_head + Spiritual Enlightenment elr1_minq_slayer + Jed Hunter elr1_minq_jed + Eye for an Eye elr2_minq_cyclosis + Harbinger elr2_minq_harbinger + Tuai Leit's Own elr2_minq_tuaileit + Ghosts from the Past elr2_minq_exturtles + Damage Control elr2_minq_goshima + Final Destination elr2_minq_finale + Sliske's Endgame endgame +2017 Back to the Freezer peng_bttf + The Jack of Spades ozan3 + Crocodile Tears crondis + Our Man in the North het + 'Phite Club pharoah + Evil Dave's Big Day Out dave +2018 Pieces of Hate piratefinale + Rebuilding Edgeville mah5_edge + You Are It trail + The Needle Skips tns + Violet is Blue xmas18 +2019 Chef's Assistant cheesecake + Curse of the Black Stone elitedungeons + Desperate Times charos + Helping Laniakea dino_laniakea_fetch + Father and Son dino_hunter_master +2020 Once Upon a Slime valentines2020 + Desperate Measures dm + Sins of the Father kerapac_dnd + Raksha, the Shadow Colossus dino_boss + Violet is Blue Too vib2 +2021 The Vault of Shadows trindine + Foreshadowing out1 + Tortle Combat tortle_combat + Heartstealer heartstealer + Azzanadra's Quest azzanadra + Flashback out2 + Battle of the Monolith egwd_prerelease + City of Senntisten senntisten + Fortunes out3 + Finale out4 + Once Upon a Time in Gielinor out0 +2022 Eye of Het I duel_arena_removal + Eye of Het II duel_arena_removal_part2 diff --git a/dumps/562/562_interface_configs.txt b/dumps/562/562_interface_configs.txt new file mode 100644 index 0000000..c2c78bf --- /dev/null +++ b/dumps/562/562_interface_configs.txt @@ -0,0 +1,45832 @@ +INTERFACE:0 +Hidden child:1 +Hidden child:3 +Hidden child:5 +Hidden child:7 +Hidden child:9 +INTERFACE:1 +Hidden child:1 +Hidden child:2 +Hidden child:3 +Hidden child:4 +Hidden child:5 +Hidden child:6 +INTERFACE:2 +INTERFACE:3 +Hidden child:2 +Hidden child:3 +Hidden child:4 +Hidden child:5 +Hidden child:6 +INTERFACE:4 +Found:Related BITconfig:ID:449, bitoffs:12, length:20 +Found:Related BITconfig:ID:449, bitoffs:7, length:11 +INTERFACE:5 +Found:Related BITconfig:ID:309, bitoffs:2, length:2 +INTERFACE:6 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:7 +INTERFACE:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:9 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:10 +INTERFACE:11 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Indirect-related config:115 +INTERFACE:12 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:13 +Found:Related GlobalIntVar(ButtonGraphics):98 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:563, bitoffs:0, length:2 +INTERFACE:14 +Found:Related GlobalIntVar(ButtonGraphics):98 +Found:Related GlobalStringVar(InfoString):344 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:13 +Hidden child:18 +Hidden child:19 +Hidden child:20 +Hidden child:29 +Hidden child:31 +INTERFACE:15 +Found:Related GlobalIntVar(ButtonGraphics):816 +Found:Related GlobalIntVar(ButtonGraphics):817 +Found:Related BITconfig:ID:1436, bitoffs:0, length:9 +Found:Related GlobalIntVar(ButtonGraphics):818 +Found:Related GlobalIntVar(ButtonGraphics):819 +Found:Related GlobalIntVar(ButtonGraphics):820 +INTERFACE:16 +Found:Related GlobalIntVar(ButtonGraphics):1514 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Hidden child:1 +Hidden child:4 +Hidden child:18 +Hidden child:37 +Hidden child:52 +Hidden child:59 +Hidden child:64 +Hidden child:76 +INTERFACE:17 +Found:Indirect-related BITconfig:ID:1747, bitoffs:24, length:25 +Found:Indirect-related BITconfig:ID:1747, bitoffs:26, length:28 +Found:Indirect-related BITconfig:ID:1747, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1747, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1747, bitoffs:6, length:11 +Found:Indirect-related BITconfig:ID:1747, bitoffs:12, length:17 +Found:Indirect-related BITconfig:ID:1747, bitoffs:18, length:23 +Found:Indirect-related GlobalStringVar(InfoString):351 +Found:Indirect-related GlobalStringVar(InfoString):352 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:24 +Hidden child:27 +Hidden child:28 +INTERFACE:18 +Found:Indirect-related config:105 +Found:Indirect-related BITconfig:ID:1747, bitoffs:26, length:28 +Found:Indirect-related BITconfig:ID:1747, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1747, bitoffs:6, length:11 +Found:Indirect-related BITconfig:ID:1747, bitoffs:12, length:17 +Found:Indirect-related BITconfig:ID:1747, bitoffs:18, length:23 +Found:Indirect-related BITconfig:ID:1737, bitoffs:0, length:3 +Found:Indirect-related BITconfig:ID:496, bitoffs:22, length:22 +Found:Indirect-related BITconfig:ID:1050, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1600, bitoffs:30, length:30 +Found:Indirect-related BITconfig:ID:1747, bitoffs:29, length:31 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:18 +Hidden child:26 +Hidden child:42 +Hidden child:46 +INTERFACE:19 +Found:Related config:2174 +Found:Related BITconfig:ID:2174, bitoffs:7, length:9 +Found:Related BITconfig:ID:2174, bitoffs:0, length:6 +Found:Related BITconfig:ID:2174, bitoffs:10, length:15 +Found:Related GlobalIntVar(ButtonGraphics):1497 +Hidden child:41 +INTERFACE:20 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Related BITconfig:ID:2172, bitoffs:0, length:15 +Found:Related BITconfig:ID:2172, bitoffs:16, length:31 +Found:Related BITconfig:ID:2173, bitoffs:0, length:15 +Found:Related BITconfig:ID:2173, bitoffs:16, length:31 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Hidden child:117 +INTERFACE:21 +Found:Indirect-related config:2185 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1520 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1521 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1522 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1524 +Found:Indirect-related GlobalStringVar(InfoString):127 +Found:Related GlobalIntVar(ButtonGraphics):1519 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:22 +Found:Related config:2201 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Related config:2202 +Found:Related config:2203 +Hidden child:34 +Hidden child:44 +Hidden child:45 +Hidden child:58 +Hidden child:68 +Hidden child:69 +Hidden child:90 +Hidden child:100 +Hidden child:101 +INTERFACE:23 +Found:Indirect-related config:2192 +Hidden child:15 +INTERFACE:24 +Found:Related BITconfig:ID:453, bitoffs:0, length:0 +Found:Related BITconfig:ID:453, bitoffs:1, length:1 +Found:Related BITconfig:ID:453, bitoffs:2, length:2 +Found:Related BITconfig:ID:453, bitoffs:3, length:3 +Found:Related BITconfig:ID:453, bitoffs:4, length:4 +Found:Related BITconfig:ID:453, bitoffs:5, length:5 +Found:Related BITconfig:ID:2221, bitoffs:0, length:0 +Found:Related BITconfig:ID:453, bitoffs:17, length:31 +Found:Related GlobalIntVar(ButtonGraphics):1043 +INTERFACE:25 +INTERFACE:26 +INTERFACE:27 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:28 +Found:Related BITconfig:ID:547, bitoffs:0, length:7 +Found:Related BITconfig:ID:543, bitoffs:12, length:29 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related BITconfig:ID:545, bitoffs:0, length:7 +Found:Related BITconfig:ID:545, bitoffs:8, length:15 +Found:Related BITconfig:ID:545, bitoffs:16, length:23 +Found:Related BITconfig:ID:545, bitoffs:24, length:31 +Found:Related BITconfig:ID:546, bitoffs:0, length:7 +Found:Related BITconfig:ID:546, bitoffs:8, length:15 +Found:Related BITconfig:ID:546, bitoffs:24, length:31 +Found:Related BITconfig:ID:546, bitoffs:16, length:23 +Found:Related BITconfig:ID:549, bitoffs:8, length:15 +Hidden child:53 +INTERFACE:29 +INTERFACE:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:31 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:32 +Found:Related GlobalStringVar(InfoString):130 +Found:Related GlobalStringVar(InfoString):142 +Found:Related GlobalStringVar(InfoString):147 +Found:Related GlobalStringVar(InfoString):146 +Found:Related GlobalStringVar(InfoString):143 +Found:Related GlobalStringVar(InfoString):144 +Found:Related GlobalStringVar(InfoString):145 +Found:Related GlobalIntVar(ButtonGraphics):809 +Found:Related GlobalIntVar(ButtonGraphics):810 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related GlobalIntVar(ButtonGraphics):811 +Hidden child:13 +INTERFACE:33 +Found:Related GlobalIntVar(ButtonGraphics):1534 +INTERFACE:34 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Related GlobalStringVar(InfoString):149 +Found:Related GlobalStringVar(InfoString):150 +Found:Related GlobalStringVar(InfoString):151 +Found:Related GlobalStringVar(InfoString):152 +Found:Related GlobalStringVar(InfoString):153 +Found:Related GlobalStringVar(InfoString):154 +Found:Related GlobalStringVar(InfoString):155 +Found:Related GlobalStringVar(InfoString):156 +Found:Related GlobalStringVar(InfoString):157 +Found:Related GlobalStringVar(InfoString):158 +Found:Related GlobalStringVar(InfoString):159 +Found:Related GlobalStringVar(InfoString):160 +Found:Related GlobalStringVar(InfoString):161 +Found:Related GlobalStringVar(InfoString):162 +Found:Related GlobalStringVar(InfoString):163 +Found:Related GlobalStringVar(InfoString):164 +Found:Related GlobalStringVar(InfoString):165 +Found:Related GlobalStringVar(InfoString):166 +Found:Related GlobalStringVar(InfoString):167 +Found:Related GlobalStringVar(InfoString):168 +Found:Related GlobalStringVar(InfoString):169 +Found:Related GlobalStringVar(InfoString):170 +Found:Related GlobalStringVar(InfoString):171 +Found:Related GlobalStringVar(InfoString):172 +Found:Related GlobalStringVar(InfoString):173 +Found:Related GlobalStringVar(InfoString):174 +Found:Related GlobalStringVar(InfoString):175 +Found:Related GlobalStringVar(InfoString):176 +Found:Related GlobalStringVar(InfoString):177 +Found:Related GlobalStringVar(InfoString):178 +Hidden child:3 +Hidden child:10 +Hidden child:12 +Hidden child:13 +Hidden child:14 +Hidden child:16 +Hidden child:44 +INTERFACE:35 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:36 +Found:Related GlobalStringVar(InfoString):130 +Found:Related GlobalStringVar(InfoString):142 +Found:Related GlobalStringVar(InfoString):146 +Found:Related GlobalStringVar(InfoString):147 +Found:Related GlobalStringVar(InfoString):143 +Found:Related GlobalStringVar(InfoString):144 +Found:Related GlobalStringVar(InfoString):145 +Found:Related GlobalIntVar(ButtonGraphics):809 +Found:Related GlobalIntVar(ButtonGraphics):810 +Found:Related GlobalIntVar(ButtonGraphics):811 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:43 +INTERFACE:37 +Found:Related GlobalIntVar(ButtonGraphics):834 +Found:Related GlobalIntVar(ButtonGraphics):835 +Found:Related GlobalIntVar(ButtonGraphics):836 +Found:Related GlobalIntVar(ButtonGraphics):833 +Found:Related BITconfig:ID:1450, bitoffs:13, length:17 +Found:Related BITconfig:ID:1451, bitoffs:15, length:18 +Found:Related BITconfig:ID:1451, bitoffs:19, length:21 +Found:Related BITconfig:ID:1451, bitoffs:15, length:15 +Found:Related BITconfig:ID:1451, bitoffs:17, length:17 +Found:Related BITconfig:ID:1451, bitoffs:18, length:18 +Found:Related BITconfig:ID:1451, bitoffs:16, length:16 +Found:Related BITconfig:ID:1453, bitoffs:0, length:5 +Hidden child:21 +Hidden child:44 +Hidden child:49 +INTERFACE:38 +INTERFACE:39 +Found:Related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Indirect-related GlobalIntVar(ButtonGraphics):917 +Found:Related GlobalIntVar(ButtonGraphics):927 +Found:Indirect-related GlobalIntVar(ButtonGraphics):915 +Found:Related GlobalIntVar(ButtonGraphics):925 +Found:Indirect-related GlobalIntVar(ButtonGraphics):916 +Found:Related GlobalIntVar(ButtonGraphics):926 +Found:Indirect-related GlobalIntVar(ButtonGraphics):914 +Found:Related GlobalIntVar(ButtonGraphics):924 +Found:Indirect-related GlobalIntVar(ButtonGraphics):913 +Found:Related GlobalIntVar(ButtonGraphics):923 +Found:Indirect-related GlobalIntVar(ButtonGraphics):911 +Found:Related GlobalIntVar(ButtonGraphics):921 +Found:Indirect-related GlobalIntVar(ButtonGraphics):912 +Found:Related GlobalIntVar(ButtonGraphics):922 +Found:Indirect-related GlobalIntVar(ButtonGraphics):910 +Found:Related GlobalIntVar(ButtonGraphics):920 +Found:Indirect-related GlobalIntVar(ButtonGraphics):909 +Found:Related GlobalIntVar(ButtonGraphics):919 +Found:Indirect-related GlobalIntVar(ButtonGraphics):908 +Found:Related GlobalIntVar(ButtonGraphics):918 +INTERFACE:40 +Found:Related GlobalStringVar(InfoString):130 +Found:Related GlobalStringVar(InfoString):142 +Found:Related GlobalStringVar(InfoString):146 +Found:Related GlobalStringVar(InfoString):147 +Found:Related GlobalStringVar(InfoString):143 +Found:Related GlobalStringVar(InfoString):144 +Found:Related GlobalStringVar(InfoString):145 +Found:Related GlobalIntVar(ButtonGraphics):809 +Found:Related GlobalIntVar(ButtonGraphics):810 +Found:Related GlobalIntVar(ButtonGraphics):811 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:302 +INTERFACE:41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related config:1448 +Found:Related GlobalIntVar(ButtonGraphics):875 +INTERFACE:42 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:43 +Found:Related GlobalStringVar(InfoString):143 +Found:Related GlobalStringVar(InfoString):144 +Found:Related GlobalStringVar(InfoString):145 +Found:Related GlobalStringVar(InfoString):218 +Found:Related GlobalStringVar(InfoString):130 +Found:Related GlobalStringVar(InfoString):142 +Found:Related GlobalIntVar(ButtonGraphics):809 +Found:Related GlobalIntVar(ButtonGraphics):810 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related BITconfig:ID:646, bitoffs:0, length:0 +Found:Related BITconfig:ID:646, bitoffs:1, length:1 +Found:Related BITconfig:ID:646, bitoffs:2, length:2 +Found:Related BITconfig:ID:646, bitoffs:3, length:3 +Found:Related BITconfig:ID:646, bitoffs:4, length:4 +Found:Related BITconfig:ID:646, bitoffs:5, length:5 +Found:Related BITconfig:ID:646, bitoffs:6, length:6 +Found:Related BITconfig:ID:646, bitoffs:7, length:7 +Found:Related BITconfig:ID:646, bitoffs:8, length:8 +Found:Related BITconfig:ID:646, bitoffs:9, length:9 +Found:Related BITconfig:ID:646, bitoffs:10, length:10 +Found:Related BITconfig:ID:646, bitoffs:11, length:11 +Found:Related BITconfig:ID:646, bitoffs:12, length:12 +Found:Related BITconfig:ID:646, bitoffs:13, length:13 +Found:Related BITconfig:ID:646, bitoffs:14, length:14 +Found:Related BITconfig:ID:646, bitoffs:15, length:15 +Found:Related BITconfig:ID:646, bitoffs:16, length:16 +Found:Related BITconfig:ID:646, bitoffs:17, length:17 +Found:Related BITconfig:ID:646, bitoffs:18, length:18 +Found:Related BITconfig:ID:646, bitoffs:19, length:19 +Found:Related BITconfig:ID:646, bitoffs:20, length:20 +Found:Related BITconfig:ID:646, bitoffs:21, length:21 +Found:Related BITconfig:ID:646, bitoffs:22, length:22 +Found:Related BITconfig:ID:646, bitoffs:23, length:23 +Found:Related BITconfig:ID:646, bitoffs:24, length:24 +Found:Related BITconfig:ID:646, bitoffs:25, length:25 +Found:Related BITconfig:ID:646, bitoffs:26, length:26 +Found:Related BITconfig:ID:646, bitoffs:27, length:27 +Found:Related BITconfig:ID:646, bitoffs:28, length:28 +Found:Related BITconfig:ID:646, bitoffs:29, length:29 +Found:Related BITconfig:ID:646, bitoffs:30, length:30 +Found:Related BITconfig:ID:646, bitoffs:31, length:31 +Found:Related BITconfig:ID:647, bitoffs:0, length:0 +Found:Related BITconfig:ID:647, bitoffs:1, length:1 +Found:Related BITconfig:ID:647, bitoffs:2, length:2 +Found:Related BITconfig:ID:647, bitoffs:3, length:3 +Found:Related BITconfig:ID:647, bitoffs:4, length:4 +Found:Related BITconfig:ID:647, bitoffs:5, length:5 +Found:Related BITconfig:ID:647, bitoffs:6, length:6 +Found:Related BITconfig:ID:647, bitoffs:7, length:7 +Found:Related BITconfig:ID:647, bitoffs:8, length:8 +Found:Related BITconfig:ID:647, bitoffs:9, length:9 +Found:Related BITconfig:ID:647, bitoffs:10, length:10 +Found:Related BITconfig:ID:647, bitoffs:11, length:11 +Found:Related BITconfig:ID:647, bitoffs:12, length:12 +Found:Related BITconfig:ID:647, bitoffs:13, length:13 +Found:Related BITconfig:ID:647, bitoffs:14, length:14 +Found:Related BITconfig:ID:647, bitoffs:15, length:15 +Found:Related BITconfig:ID:647, bitoffs:16, length:16 +Found:Related BITconfig:ID:647, bitoffs:17, length:17 +Found:Related BITconfig:ID:647, bitoffs:18, length:18 +Found:Related BITconfig:ID:647, bitoffs:19, length:19 +Found:Related BITconfig:ID:647, bitoffs:20, length:20 +Found:Related BITconfig:ID:647, bitoffs:21, length:21 +Found:Related BITconfig:ID:647, bitoffs:22, length:22 +Found:Related BITconfig:ID:647, bitoffs:23, length:23 +Found:Related BITconfig:ID:644, bitoffs:0, length:0 +Found:Related BITconfig:ID:644, bitoffs:1, length:1 +Found:Related BITconfig:ID:644, bitoffs:2, length:2 +Found:Related BITconfig:ID:644, bitoffs:3, length:3 +Found:Related BITconfig:ID:644, bitoffs:4, length:4 +Found:Related BITconfig:ID:644, bitoffs:5, length:5 +Found:Related BITconfig:ID:644, bitoffs:6, length:6 +Found:Related BITconfig:ID:644, bitoffs:7, length:7 +Found:Related BITconfig:ID:644, bitoffs:8, length:8 +Found:Related BITconfig:ID:644, bitoffs:9, length:9 +Found:Related BITconfig:ID:644, bitoffs:10, length:10 +Found:Related BITconfig:ID:644, bitoffs:11, length:11 +Found:Related BITconfig:ID:644, bitoffs:12, length:12 +Found:Related BITconfig:ID:644, bitoffs:13, length:13 +Found:Related BITconfig:ID:644, bitoffs:14, length:14 +Found:Related BITconfig:ID:644, bitoffs:15, length:15 +Found:Related BITconfig:ID:644, bitoffs:16, length:16 +Found:Related BITconfig:ID:644, bitoffs:17, length:17 +Found:Related BITconfig:ID:644, bitoffs:18, length:18 +Found:Related BITconfig:ID:644, bitoffs:19, length:19 +Found:Related BITconfig:ID:644, bitoffs:20, length:20 +Found:Related BITconfig:ID:644, bitoffs:21, length:21 +Found:Related BITconfig:ID:644, bitoffs:22, length:22 +Found:Related BITconfig:ID:644, bitoffs:23, length:23 +Found:Related BITconfig:ID:644, bitoffs:24, length:24 +Found:Related BITconfig:ID:644, bitoffs:25, length:25 +Found:Related BITconfig:ID:644, bitoffs:26, length:26 +Found:Related BITconfig:ID:644, bitoffs:27, length:27 +Found:Related BITconfig:ID:644, bitoffs:28, length:28 +Found:Related BITconfig:ID:644, bitoffs:29, length:29 +Found:Related BITconfig:ID:644, bitoffs:30, length:30 +Found:Related BITconfig:ID:644, bitoffs:31, length:31 +Found:Related BITconfig:ID:645, bitoffs:0, length:0 +Found:Related BITconfig:ID:645, bitoffs:1, length:1 +Found:Related BITconfig:ID:645, bitoffs:2, length:2 +Found:Related BITconfig:ID:645, bitoffs:3, length:3 +Found:Related BITconfig:ID:645, bitoffs:4, length:4 +Found:Related BITconfig:ID:645, bitoffs:5, length:5 +Found:Related BITconfig:ID:645, bitoffs:6, length:6 +Found:Related BITconfig:ID:645, bitoffs:7, length:7 +Found:Related BITconfig:ID:645, bitoffs:8, length:8 +Found:Related BITconfig:ID:645, bitoffs:9, length:9 +Found:Related BITconfig:ID:645, bitoffs:10, length:10 +Found:Related BITconfig:ID:645, bitoffs:11, length:11 +Found:Related BITconfig:ID:645, bitoffs:12, length:12 +Found:Related BITconfig:ID:645, bitoffs:13, length:13 +Found:Related BITconfig:ID:645, bitoffs:14, length:14 +Found:Related BITconfig:ID:645, bitoffs:15, length:15 +Found:Related BITconfig:ID:645, bitoffs:16, length:16 +Found:Related BITconfig:ID:645, bitoffs:17, length:17 +Found:Related BITconfig:ID:645, bitoffs:18, length:18 +Found:Related BITconfig:ID:645, bitoffs:19, length:19 +Found:Related BITconfig:ID:645, bitoffs:20, length:20 +Found:Related BITconfig:ID:645, bitoffs:21, length:21 +Found:Related BITconfig:ID:645, bitoffs:22, length:22 +Found:Related BITconfig:ID:645, bitoffs:23, length:23 +INTERFACE:44 +Found:Related GlobalStringVar(InfoString):143 +Found:Related GlobalStringVar(InfoString):144 +Found:Related GlobalStringVar(InfoString):145 +Found:Related GlobalStringVar(InfoString):130 +Found:Related GlobalStringVar(InfoString):142 +Found:Related GlobalStringVar(InfoString):146 +Found:Related GlobalStringVar(InfoString):147 +Found:Related GlobalIntVar(ButtonGraphics):809 +Found:Related GlobalIntVar(ButtonGraphics):810 +Found:Related GlobalIntVar(ButtonGraphics):811 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:139 +Hidden child:141 +INTERFACE:45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):837 +Found:Related BITconfig:ID:1444, bitoffs:17, length:20 +Found:Indirect-related config:1447 +INTERFACE:46 +INTERFACE:47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:49 +INTERFACE:50 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:51 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:28 +Hidden child:29 +INTERFACE:52 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:2 +Hidden child:3 +Hidden child:5 +Hidden child:12 +INTERFACE:53 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:15 +Hidden child:16 +Hidden child:17 +Hidden child:19 +Hidden child:21 +Hidden child:22 +Hidden child:23 +Hidden child:24 +Hidden child:25 +Hidden child:30 +INTERFACE:54 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related GlobalIntVar(ButtonGraphics):1280 +Found:Related GlobalIntVar(ButtonGraphics):1278 +Found:Related BITconfig:ID:379, bitoffs:5, length:9 +Found:Related BITconfig:ID:379, bitoffs:0, length:4 +INTERFACE:55 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:56 +INTERFACE:57 +Found:Related config:380 +INTERFACE:58 +Found:Related config:380 +Found:Related BITconfig:ID:377, bitoffs:24, length:31 +Found:Related BITconfig:ID:378, bitoffs:24, length:31 +Found:Related BITconfig:ID:378, bitoffs:0, length:6 +Found:Related BITconfig:ID:378, bitoffs:21, length:22 +Found:Related BITconfig:ID:377, bitoffs:21, length:22 +Found:Related BITconfig:ID:378, bitoffs:7, length:7 +Found:Related BITconfig:ID:378, bitoffs:8, length:8 +Found:Related BITconfig:ID:378, bitoffs:9, length:9 +Found:Related BITconfig:ID:378, bitoffs:10, length:10 +INTERFACE:59 +Found:Related config:380 +Found:Related BITconfig:ID:377, bitoffs:24, length:31 +Found:Related BITconfig:ID:378, bitoffs:24, length:31 +Found:Related BITconfig:ID:377, bitoffs:0, length:6 +Found:Related BITconfig:ID:378, bitoffs:21, length:22 +Found:Related BITconfig:ID:377, bitoffs:21, length:22 +Found:Related BITconfig:ID:377, bitoffs:7, length:7 +Found:Related BITconfig:ID:377, bitoffs:8, length:8 +Found:Related BITconfig:ID:377, bitoffs:9, length:9 +Found:Related BITconfig:ID:377, bitoffs:10, length:10 +INTERFACE:60 +Found:Related GlobalIntVar(ButtonGraphics):1279 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:14 +Hidden child:17 +Hidden child:46 +Hidden child:87 +INTERFACE:61 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:40 +INTERFACE:62 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:63 +Found:Related config:620 +Found:Related config:621 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:64 +INTERFACE:65 +INTERFACE:66 +INTERFACE:67 +INTERFACE:68 +INTERFACE:69 +INTERFACE:70 +INTERFACE:71 +INTERFACE:72 +Found:Related BITconfig:ID:1934, bitoffs:0, length:0 +Found:Related BITconfig:ID:1934, bitoffs:7, length:7 +Found:Related BITconfig:ID:1934, bitoffs:8, length:8 +Found:Related BITconfig:ID:1934, bitoffs:9, length:9 +Found:Related BITconfig:ID:1934, bitoffs:5, length:5 +Found:Related BITconfig:ID:1934, bitoffs:1, length:1 +Found:Related BITconfig:ID:1934, bitoffs:2, length:2 +Found:Related BITconfig:ID:1934, bitoffs:4, length:4 +Found:Related BITconfig:ID:1934, bitoffs:3, length:3 +Found:Related BITconfig:ID:1934, bitoffs:6, length:6 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:1 +Hidden child:2 +Hidden child:3 +Hidden child:4 +Hidden child:5 +Hidden child:6 +Hidden child:7 +Hidden child:8 +Hidden child:9 +Hidden child:10 +Hidden child:11 +Hidden child:12 +Hidden child:13 +Hidden child:14 +Hidden child:15 +Hidden child:16 +Hidden child:17 +Hidden child:18 +Hidden child:19 +Hidden child:20 +Hidden child:21 +Hidden child:22 +Hidden child:23 +Hidden child:24 +Hidden child:25 +Hidden child:26 +Hidden child:27 +Hidden child:28 +Hidden child:29 +Hidden child:30 +Hidden child:58 +INTERFACE:73 +Found:Related GlobalIntVar(ButtonGraphics):1406 +INTERFACE:74 +INTERFACE:75 +INTERFACE:76 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:2 +INTERFACE:77 +Found:Related BITconfig:ID:1775, bitoffs:16, length:19 +Found:Related GlobalIntVar(ButtonGraphics):1233 +Found:Related GlobalStringVar(InfoString):315 +Hidden child:0 +Hidden child:1 +Hidden child:2 +Hidden child:19 +INTERFACE:78 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Related config:448 +INTERFACE:79 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Related config:448 +Found:Related BITconfig:ID:1493, bitoffs:4, length:4 +INTERFACE:80 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +INTERFACE:81 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +INTERFACE:82 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +INTERFACE:83 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +INTERFACE:84 +Found:Indirect-related BITconfig:ID:1572, bitoffs:27, length:31 +Found:Indirect-related BITconfig:ID:1573, bitoffs:26, length:31 +Found:Indirect-related config:617 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:85 +INTERFACE:86 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:87 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1040 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1041 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1042 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related config:359 +Found:Indirect-related config:492 +Found:Indirect-related BITconfig:ID:635, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:1330, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:445, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1348, bitoffs:0, length:1 +Found:Indirect-related BITconfig:ID:1003, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1348, bitoffs:28, length:28 +Found:Indirect-related BITconfig:ID:968, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1420, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:2088, bitoffs:18, length:21 +INTERFACE:89 +INTERFACE:90 +INTERFACE:91 +INTERFACE:92 +INTERFACE:93 +INTERFACE:94 +INTERFACE:95 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:96 +INTERFACE:97 +INTERFACE:98 +INTERFACE:99 +Found:Related GlobalStringVar(InfoString):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:9 +Hidden child:11 +INTERFACE:100 +INTERFACE:101 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:102 +Found:Indirect-related BITconfig:ID:2187, bitoffs:5, length:10 +Found:Indirect-related BITconfig:ID:2187, bitoffs:11, length:14 +Found:Related GlobalIntVar(ButtonGraphics):1526 +Found:Related GlobalIntVar(ButtonGraphics):1527 +Found:Related GlobalIntVar(ButtonGraphics):1528 +Found:Related GlobalIntVar(ButtonGraphics):1529 +Found:Related GlobalIntVar(ButtonGraphics):1530 +Found:Related GlobalIntVar(ButtonGraphics):1531 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:14 +Hidden child:15 +Hidden child:16 +Hidden child:17 +Hidden child:18 +Hidden child:19 +Hidden child:56 +Hidden child:61 +Hidden child:66 +Hidden child:67 +Hidden child:70 +Hidden child:80 +INTERFACE:103 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:104 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:105 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related config:1112 +Found:Indirect-related config:1113 +Found:Indirect-related config:1109 +Found:Indirect-related config:1111 +Found:Indirect-related config:1110 +Found:Indirect-related GlobalIntVar(ButtonGraphics):83 +Found:Indirect-related GlobalIntVar(ButtonGraphics):82 +Found:Indirect-related config:1118 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related config:1114 +Found:Indirect-related GlobalIntVar(ButtonGraphics):84 +Found:Indirect-related GlobalIntVar(ButtonGraphics):85 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Hidden child:20 +Hidden child:36 +Hidden child:52 +Hidden child:67 +Hidden child:71 +Hidden child:86 +Hidden child:90 +Hidden child:105 +Hidden child:109 +Hidden child:124 +Hidden child:127 +Hidden child:154 +Hidden child:188 +Hidden child:193 +Hidden child:197 +INTERFACE:106 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related config:1108 +Hidden child:19 +Hidden child:33 +Hidden child:47 +Hidden child:60 +Hidden child:64 +Hidden child:77 +Hidden child:81 +Hidden child:94 +Hidden child:98 +Hidden child:111 +Hidden child:126 +Hidden child:131 +Hidden child:140 +INTERFACE:107 +INTERFACE:108 +INTERFACE:109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related config:1267 +Found:Indirect-related config:1269 +Hidden child:45 +INTERFACE:110 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related config:1108 +INTERFACE:111 +INTERFACE:112 +Hidden child:6 +INTERFACE:113 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:9 +INTERFACE:114 +Found:Related config:261 +Found:Related BITconfig:ID:433, bitoffs:13, length:13 +Found:Related config:262 +Found:Related config:263 +Found:Related config:264 +Found:Related config:265 +Found:Related config:266 +INTERFACE:115 +INTERFACE:116 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:117 +INTERFACE:118 +INTERFACE:119 +INTERFACE:120 +Found:Related BITconfig:ID:425, bitoffs:1, length:2 +INTERFACE:121 +INTERFACE:122 +INTERFACE:123 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:125 +Found:Related BITconfig:ID:615, bitoffs:0, length:0 +Found:Related BITconfig:ID:615, bitoffs:1, length:1 +Found:Related BITconfig:ID:615, bitoffs:2, length:2 +Found:Related BITconfig:ID:615, bitoffs:8, length:8 +Found:Related BITconfig:ID:1357, bitoffs:3, length:5 +Found:Related BITconfig:ID:615, bitoffs:9, length:13 +Found:Related BITconfig:ID:615, bitoffs:14, length:21 +Found:Related BITconfig:ID:615, bitoffs:22, length:29 +Found:Related BITconfig:ID:615, bitoffs:3, length:3 +Found:Related BITconfig:ID:615, bitoffs:30, length:30 +Found:Related BITconfig:ID:615, bitoffs:4, length:7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:126 +INTERFACE:127 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:128 +Found:Related BITconfig:ID:525, bitoffs:6, length:13 +Found:Related BITconfig:ID:525, bitoffs:14, length:21 +Found:Related BITconfig:ID:524, bitoffs:0, length:1 +Found:Related BITconfig:ID:524, bitoffs:2, length:3 +Found:Related BITconfig:ID:524, bitoffs:4, length:5 +Found:Related BITconfig:ID:524, bitoffs:6, length:7 +Found:Related BITconfig:ID:524, bitoffs:8, length:9 +Found:Related BITconfig:ID:524, bitoffs:10, length:11 +Found:Related BITconfig:ID:524, bitoffs:12, length:13 +Found:Related BITconfig:ID:524, bitoffs:14, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:129 +Found:Related BITconfig:ID:525, bitoffs:6, length:13 +Found:Related BITconfig:ID:525, bitoffs:14, length:21 +Found:Related BITconfig:ID:524, bitoffs:0, length:1 +Found:Related BITconfig:ID:524, bitoffs:2, length:3 +Found:Related BITconfig:ID:524, bitoffs:4, length:5 +Found:Related BITconfig:ID:524, bitoffs:6, length:7 +Found:Related BITconfig:ID:524, bitoffs:8, length:9 +Found:Related BITconfig:ID:524, bitoffs:10, length:11 +Found:Related BITconfig:ID:524, bitoffs:12, length:13 +Found:Related BITconfig:ID:524, bitoffs:14, length:15 +Found:Related BITconfig:ID:524, bitoffs:16, length:17 +Found:Related BITconfig:ID:524, bitoffs:18, length:19 +Found:Related BITconfig:ID:524, bitoffs:20, length:21 +Found:Related BITconfig:ID:524, bitoffs:22, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:130 +Found:Related BITconfig:ID:525, bitoffs:6, length:13 +Found:Related BITconfig:ID:525, bitoffs:14, length:21 +Found:Related BITconfig:ID:524, bitoffs:0, length:1 +Found:Related BITconfig:ID:524, bitoffs:2, length:3 +Found:Related BITconfig:ID:524, bitoffs:4, length:5 +Found:Related BITconfig:ID:524, bitoffs:6, length:7 +Found:Related BITconfig:ID:524, bitoffs:8, length:9 +Found:Related BITconfig:ID:524, bitoffs:10, length:11 +Found:Related BITconfig:ID:524, bitoffs:12, length:13 +Found:Related BITconfig:ID:524, bitoffs:14, length:15 +Found:Related BITconfig:ID:524, bitoffs:16, length:17 +Found:Related BITconfig:ID:524, bitoffs:18, length:19 +Found:Related BITconfig:ID:524, bitoffs:20, length:21 +Found:Related BITconfig:ID:524, bitoffs:22, length:23 +Found:Related BITconfig:ID:524, bitoffs:24, length:25 +Found:Related BITconfig:ID:524, bitoffs:26, length:27 +Found:Related BITconfig:ID:524, bitoffs:28, length:29 +Found:Related BITconfig:ID:524, bitoffs:30, length:31 +Found:Related BITconfig:ID:525, bitoffs:0, length:1 +Found:Related BITconfig:ID:525, bitoffs:2, length:3 +Found:Related BITconfig:ID:525, bitoffs:4, length:5 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:131 +INTERFACE:132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:133 +INTERFACE:134 +Found:Related BITconfig:ID:1476, bitoffs:0, length:2 +Found:Related BITconfig:ID:1476, bitoffs:22, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related BITconfig:ID:1476, bitoffs:24, length:27 +Hidden child:10 +Hidden child:11 +Hidden child:12 +Hidden child:13 +Hidden child:45 +Hidden child:49 +Hidden child:52 +Hidden child:55 +Hidden child:58 +Hidden child:61 +Hidden child:65 +Hidden child:66 +Hidden child:67 +Hidden child:68 +Hidden child:69 +Hidden child:70 +Hidden child:71 +Hidden child:72 +Hidden child:73 +Hidden child:76 +Hidden child:79 +INTERFACE:135 +Found:Related GlobalIntVar(ButtonGraphics):179 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:136 +INTERFACE:137 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related GlobalIntVar(ButtonGraphics):43 +Found:Related GlobalIntVar(ButtonGraphics):3 +Found:Related GlobalIntVar(ButtonGraphics):4 +Found:Related GlobalStringVar(InfoString):2 +Found:Related GlobalStringVar(InfoString):3 +Found:Related GlobalStringVar(InfoString):4 +Found:Related GlobalStringVar(InfoString):5 +Found:Related GlobalStringVar(InfoString):6 +Found:Related GlobalStringVar(InfoString):7 +Found:Related GlobalStringVar(InfoString):8 +Found:Related GlobalStringVar(InfoString):9 +Found:Related GlobalStringVar(InfoString):10 +Found:Related GlobalStringVar(InfoString):11 +Found:Related GlobalStringVar(InfoString):12 +Found:Related GlobalStringVar(InfoString):13 +Found:Related GlobalStringVar(InfoString):14 +Found:Related GlobalStringVar(InfoString):15 +Found:Related GlobalStringVar(InfoString):16 +Found:Related GlobalStringVar(InfoString):17 +Found:Related GlobalStringVar(InfoString):18 +Found:Related GlobalStringVar(InfoString):19 +Found:Related GlobalStringVar(InfoString):20 +Found:Related GlobalStringVar(InfoString):21 +Found:Indirect-related GlobalIntVar(ButtonGraphics):126 +Found:Indirect-related GlobalIntVar(ButtonGraphics):127 +Found:Indirect-related GlobalStringVar(InfoString):27 +Found:Indirect-related BITconfig:ID:1231, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1231, bitoffs:8, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):128 +Found:Indirect-related GlobalIntVar(ButtonGraphics):11 +Found:Indirect-related GlobalIntVar(ButtonGraphics):5 +Found:Indirect-related GlobalStringVar(InfoString):23 +Found:Related GlobalStringVar(InfoString):24 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1029 +Found:Indirect-related GlobalStringVar(InfoString):22 +Hidden child:0 +Hidden child:3 +Hidden child:7 +Hidden child:9 +Hidden child:13 +Hidden child:56 +Hidden child:60 +Hidden child:68 +Hidden child:69 +Hidden child:70 +Hidden child:74 +Hidden child:75 +Hidden child:76 +Hidden child:77 +Hidden child:78 +Hidden child:79 +Hidden child:80 +Hidden child:81 +Hidden child:82 +Hidden child:167 +INTERFACE:138 +Found:Indirect-related BITconfig:ID:2046, bitoffs:0, length:6 +Found:Related config:153 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:28 +Hidden child:29 +Hidden child:30 +Hidden child:31 +Hidden child:32 +Hidden child:33 +Hidden child:34 +Hidden child:35 +Hidden child:36 +Hidden child:37 +Hidden child:38 +Hidden child:39 +Hidden child:40 +Hidden child:41 +INTERFACE:139 +Found:Related config:143 +INTERFACE:140 +INTERFACE:141 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:142 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:10 +INTERFACE:143 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:144 +Found:Related config:383 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:171 +Hidden child:173 +Hidden child:175 +Hidden child:179 +Hidden child:181 +Hidden child:182 +Hidden child:184 +INTERFACE:145 +Found:Related BITconfig:ID:681, bitoffs:0, length:10 +Found:Related BITconfig:ID:679, bitoffs:9, length:14 +Found:Related BITconfig:ID:683, bitoffs:0, length:11 +Found:Related BITconfig:ID:683, bitoffs:12, length:15 +Found:Related BITconfig:ID:680, bitoffs:0, length:2 +Found:Related BITconfig:ID:684, bitoffs:19, length:25 +Found:Related BITconfig:ID:684, bitoffs:3, length:10 +Found:Related BITconfig:ID:685, bitoffs:0, length:6 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:146 +INTERFACE:147 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:148 +INTERFACE:149 +Hidden child:185 +Hidden child:186 +Hidden child:187 +Hidden child:188 +Hidden child:189 +Hidden child:190 +Hidden child:191 +Hidden child:192 +Hidden child:193 +Hidden child:194 +Hidden child:195 +Hidden child:196 +Hidden child:197 +Hidden child:198 +Hidden child:199 +Hidden child:200 +Hidden child:201 +Hidden child:202 +Hidden child:203 +Hidden child:204 +Hidden child:205 +Hidden child:206 +Hidden child:207 +Hidden child:221 +Hidden child:233 +Hidden child:254 +INTERFACE:150 +INTERFACE:151 +Hidden child:1 +Hidden child:2 +Hidden child:3 +Hidden child:4 +Hidden child:5 +Hidden child:6 +Hidden child:7 +Hidden child:8 +Hidden child:9 +INTERFACE:152 +Hidden child:0 +Hidden child:1 +Hidden child:2 +Hidden child:3 +Hidden child:4 +Hidden child:5 +Hidden child:6 +INTERFACE:153 +Found:Indirect-related config:2189 +Found:Indirect-related BITconfig:ID:2188, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:2188, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:2188, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:2188, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:2188, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:2188, bitoffs:4, length:4 +Found:Related config:2192 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:1 +Hidden child:2 +Hidden child:4 +Hidden child:5 +Hidden child:7 +Hidden child:8 +Hidden child:10 +Hidden child:11 +Hidden child:13 +Hidden child:14 +Hidden child:16 +Hidden child:20 +Hidden child:64 +Hidden child:102 +Hidden child:115 +Hidden child:128 +Hidden child:141 +Hidden child:143 +Hidden child:155 +Hidden child:157 +Hidden child:169 +Hidden child:171 +INTERFACE:154 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:155 +INTERFACE:156 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related GlobalStringVar(InfoString):211 +INTERFACE:157 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related GlobalIntVar(ButtonGraphics):155 +Found:Related BITconfig:ID:1231, bitoffs:18, length:19 +Hidden child:17 +Hidden child:35 +INTERFACE:158 +INTERFACE:159 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:18 +Hidden child:31 +Hidden child:32 +Hidden child:33 +Hidden child:34 +Hidden child:35 +INTERFACE:160 +INTERFACE:161 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +INTERFACE:162 +INTERFACE:163 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +INTERFACE:164 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +INTERFACE:165 +INTERFACE:166 +INTERFACE:167 +INTERFACE:168 +INTERFACE:169 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Related BITconfig:ID:1018, bitoffs:0, length:7 +INTERFACE:170 +Found:Related BITconfig:ID:425, bitoffs:1, length:2 +INTERFACE:171 +INTERFACE:172 +Found:Related config:850 +Found:Related BITconfig:ID:845, bitoffs:0, length:5 +Found:Related BITconfig:ID:848, bitoffs:6, length:11 +Found:Related config:851 +Found:Related config:852 +Found:Related BITconfig:ID:845, bitoffs:6, length:11 +Found:Related BITconfig:ID:848, bitoffs:12, length:18 +Found:Related config:853 +Found:Related config:854 +Found:Related config:855 +Found:Related BITconfig:ID:845, bitoffs:12, length:17 +Found:Related BITconfig:ID:848, bitoffs:19, length:25 +Found:Related config:856 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:173 +Found:Indirect-related config:2194 +Found:Indirect-related BITconfig:ID:2193, bitoffs:24, length:27 +Found:Related BITconfig:ID:2187, bitoffs:5, length:10 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:1 +Hidden child:2 +Hidden child:3 +Hidden child:4 +Hidden child:8 +Hidden child:83 +INTERFACE:174 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:175 +INTERFACE:176 +INTERFACE:177 +INTERFACE:178 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related BITconfig:ID:1502, bitoffs:29, length:29 +Hidden child:4 +Hidden child:28 +Hidden child:58 +Hidden child:63 +Hidden child:65 +INTERFACE:179 +INTERFACE:180 +Hidden child:1 +INTERFACE:181 +Found:Related GlobalIntVar(ButtonGraphics):180 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:182 +Hidden child:8 +Hidden child:14 +INTERFACE:183 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:14 +Hidden child:15 +Hidden child:38 +Hidden child:42 +Hidden child:46 +Hidden child:49 +INTERFACE:184 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related BITconfig:ID:807, bitoffs:2, length:5 +Found:Related BITconfig:ID:807, bitoffs:6, length:9 +Found:Related BITconfig:ID:807, bitoffs:12, length:15 +Found:Related BITconfig:ID:807, bitoffs:19, length:22 +Found:Related BITconfig:ID:807, bitoffs:10, length:11 +Found:Related BITconfig:ID:807, bitoffs:26, length:29 +Found:Related BITconfig:ID:807, bitoffs:16, length:18 +Found:Related BITconfig:ID:807, bitoffs:23, length:25 +Found:Related BITconfig:ID:807, bitoffs:30, length:31 +INTERFACE:185 +Found:Related BITconfig:ID:809, bitoffs:0, length:1 +Found:Related BITconfig:ID:809, bitoffs:2, length:5 +Found:Related BITconfig:ID:809, bitoffs:6, length:7 +Found:Related BITconfig:ID:809, bitoffs:8, length:11 +Found:Related BITconfig:ID:809, bitoffs:12, length:13 +Found:Related BITconfig:ID:809, bitoffs:14, length:17 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:186 +Found:Related GlobalIntVar(ButtonGraphics):679 +INTERFACE:187 +Found:Indirect-related BITconfig:ID:1621, bitoffs:0, length:14 //musics +Found:Indirect-related GlobalIntVar(ButtonGraphics):1077 //swich palay list +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related BITconfig:ID:1621, bitoffs:15, length:29 +Found:Indirect-related BITconfig:ID:1622, bitoffs:0, length:14 +Found:Indirect-related BITconfig:ID:1622, bitoffs:15, length:29 +Found:Indirect-related BITconfig:ID:1623, bitoffs:0, length:14 +Found:Indirect-related BITconfig:ID:1623, bitoffs:15, length:29 +Found:Indirect-related BITconfig:ID:1624, bitoffs:0, length:14 +Found:Indirect-related BITconfig:ID:1624, bitoffs:15, length:29 +Found:Indirect-related BITconfig:ID:1625, bitoffs:0, length:14 +Found:Indirect-related BITconfig:ID:1625, bitoffs:15, length:29 +Found:Indirect-related BITconfig:ID:1626, bitoffs:0, length:14 +Found:Indirect-related BITconfig:ID:1626, bitoffs:15, length:29 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Indirect-related GlobalStringVar(InfoString):196 +Found:Indirect-related GlobalIntVar(ButtonGraphics):5 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related config:20 +Found:Indirect-related config:21 +Found:Indirect-related config:22 +Found:Indirect-related config:23 +Found:Indirect-related config:24 +Found:Indirect-related config:25 +Found:Indirect-related config:298 +Found:Indirect-related config:311 +Found:Indirect-related config:346 +Found:Indirect-related config:414 +Found:Indirect-related config:464 +Found:Indirect-related config:598 +Found:Indirect-related config:662 +Found:Indirect-related config:721 +Found:Indirect-related config:906 +Found:Indirect-related config:1009 +Found:Indirect-related config:1104 +Found:Indirect-related config:1136 +Found:Indirect-related config:1180 +Found:Indirect-related config:1202 +Found:Indirect-related config:1381 +Found:Indirect-related config:1394 +Found:Indirect-related config:1434 +Found:Indirect-related config:1596 +Found:Indirect-related config:1618 +Found:Indirect-related config:1619 +Found:Indirect-related config:1620 +Found:Indirect-related config:1864 +Found:Indirect-related config:1865 +Found:Indirect-related config:2019 +Found:Indirect-related config:2246 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1189, bitoffs:0, length:14 +Found:Indirect-related BITconfig:ID:1621, bitoffs:30, length:30 +Found:Related GlobalIntVar(ButtonGraphics):89 +Found:Related BITconfig:ID:297, bitoffs:1, length:1 +Found:Related BITconfig:ID:1621, bitoffs:31, length:31 +Found:Indirect-related GlobalIntVar(ButtonGraphics):11 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1029 +Found:Indirect-related GlobalStringVar(InfoString):22 +INTERFACE:188 +INTERFACE:189 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:190 +Found:Indirect-related BITconfig:ID:1384, bitoffs:5, length:8 +Found:Indirect-related BITconfig:ID:1384, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:1384, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:1384, bitoffs:9, length:9 +Found:Indirect-related GlobalIntVar(ButtonGraphics):693 +Found:Indirect-related GlobalIntVar(ButtonGraphics):694 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1103 +Found:Indirect-related GlobalIntVar(ButtonGraphics):692 +Found:Indirect-related GlobalIntVar(ButtonGraphics):272 +Found:Indirect-related GlobalIntVar(ButtonGraphics):273 +Found:Indirect-related config:281 +Found:Indirect-related config:130 +Found:Indirect-related config:29 +Found:Indirect-related config:31 +Found:Indirect-related config:176 +Found:Indirect-related config:32 +Found:Indirect-related config:160 +Found:Indirect-related config:122 +Found:Indirect-related config:71 +Found:Indirect-related config:273 +Found:Indirect-related config:107 +Found:Indirect-related config:63 +Found:Indirect-related config:145 +Found:Indirect-related config:146 +Found:Indirect-related config:293 +Found:Indirect-related config:68 +Found:Indirect-related config:655 +Found:Indirect-related config:10 +Found:Indirect-related config:399 +Found:Indirect-related config:314 +Found:Indirect-related config:131 +Found:Indirect-related config:80 +Found:Indirect-related config:0 +Found:Indirect-related config:335 +Found:Indirect-related config:299 +Found:Indirect-related config:148 +Found:Indirect-related config:17 +Found:Indirect-related config:11 +Found:Indirect-related config:347 +Found:Indirect-related config:65 +Found:Indirect-related config:180 +Found:Indirect-related config:150 +Found:Indirect-related config:382 +Found:Indirect-related config:223 +Found:Indirect-related config:188 +Found:Indirect-related config:5 +Found:Indirect-related config:387 +Found:Indirect-related config:175 +Found:Indirect-related config:139 +Found:Indirect-related config:147 +Found:Indirect-related config:14 +Found:Indirect-related config:365 +Found:Indirect-related config:30 +Found:Indirect-related config:517 +Found:Indirect-related config:192 +Found:Indirect-related config:307 +Found:Indirect-related config:112 +Found:Indirect-related config:416 +Found:Indirect-related config:165 +Found:Indirect-related config:302 +Found:Indirect-related config:328 +Found:Indirect-related config:402 +Found:Indirect-related config:600 +Found:Indirect-related config:76 +Found:Indirect-related config:159 +Found:Indirect-related config:339 +Found:Indirect-related config:60 +Found:Indirect-related config:116 +Found:Indirect-related config:320 +Found:Indirect-related config:26 +Found:Indirect-related config:359 +Found:Indirect-related config:197 +Found:Indirect-related config:226 +Found:Indirect-related config:111 +Found:Indirect-related config:200 +Found:Indirect-related config:385 +Found:Indirect-related config:317 +Found:Indirect-related config:161 +Found:Indirect-related config:162 +Found:Indirect-related config:212 +Found:Indirect-related config:980 +Found:Indirect-related BITconfig:ID:222, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:62, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:178, bitoffs:0, length:1 +Found:Indirect-related BITconfig:ID:939, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:433, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:964, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:455, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:400, bitoffs:23, length:23 +Found:Indirect-related BITconfig:ID:869, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:794, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:440, bitoffs:0, length:14 +Found:Indirect-related BITconfig:ID:622, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:934, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:896, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:641, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:912, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:844, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:671, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:810, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:435, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:521, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:553, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:408, bitoffs:28, length:31 +Found:Indirect-related BITconfig:ID:482, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:437, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:635, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:351, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:445, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:705, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:465, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:823, bitoffs:0, length:19 +Found:Indirect-related BITconfig:ID:604, bitoffs:0, length:2 +Found:Indirect-related BITconfig:ID:423, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:574, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:905, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:714, bitoffs:0, length:2 +Found:Indirect-related BITconfig:ID:607, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:678, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:496, bitoffs:0, length:2 +Found:Indirect-related BITconfig:ID:730, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:874, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:602, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:709, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:616, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:723, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:568, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:449, bitoffs:0, length:1 +Found:Indirect-related BITconfig:ID:571, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:968, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:970, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:977, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:992, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:994, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:997, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:1003, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1016, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1049, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1063, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:1077, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1094, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1165, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:1178, bitoffs:1, length:10 +Found:Indirect-related BITconfig:ID:1184, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:1190, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1204, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1218, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:1225, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1227, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1232, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1236, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:1271, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:1274, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1282, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:1306, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1311, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1330, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:1370, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1365, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:1403, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1407, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:1415, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1475, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1577, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:1420, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1390, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1327, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:714, bitoffs:3, length:6 +Found:Indirect-related BITconfig:ID:1819, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:1498, bitoffs:0, length:15 +Found:Indirect-related BITconfig:ID:1558, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:1600, bitoffs:0, length:3 +Found:Indirect-related BITconfig:ID:1588, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1610, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1811, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1849, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1646, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1844, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1834, bitoffs:28, length:31 +Found:Indirect-related BITconfig:ID:1861, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:2037, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1906, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1889, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:2217, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:2020, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:2046, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:2051, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:2079, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:2208, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:2234, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:2376, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1593, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:1402, bitoffs:4, length:13 +Found:Indirect-related GlobalIntVar(ButtonGraphics):698 +Found:Indirect-related GlobalIntVar(ButtonGraphics):699 +Found:Indirect-related GlobalIntVar(ButtonGraphics):695 +Found:Indirect-related BITconfig:ID:1255, bitoffs:0, length:1 +Found:Indirect-related config:101 +Found:Indirect-related BITconfig:ID:533, bitoffs:21, length:23 +Found:Indirect-related BITconfig:ID:1011, bitoffs:21, length:22 +Found:Indirect-related BITconfig:ID:1181, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:318, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:683, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1010, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:1050, bitoffs:1, length:4 +Found:Indirect-related BITconfig:ID:1377, bitoffs:28, length:28 +Found:Indirect-related BITconfig:ID:1377, bitoffs:24, length:24 +Found:Indirect-related BITconfig:ID:1359, bitoffs:13, length:13 +Found:Indirect-related BITconfig:ID:684, bitoffs:19, length:25 +Found:Indirect-related BITconfig:ID:1844, bitoffs:21, length:21 +Found:Indirect-related BITconfig:ID:1874, bitoffs:26, length:26 +Found:Indirect-related BITconfig:ID:685, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:1950, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1958, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1415, bitoffs:6, length:7 +Found:Indirect-related BITconfig:ID:1415, bitoffs:8, length:11 +Found:Indirect-related BITconfig:ID:1415, bitoffs:12, length:13 +Found:Indirect-related BITconfig:ID:1415, bitoffs:14, length:15 +Found:Indirect-related BITconfig:ID:1415, bitoffs:16, length:16 +Found:Indirect-related BITconfig:ID:1415, bitoffs:17, length:17 +Found:Indirect-related BITconfig:ID:1415, bitoffs:18, length:18 +Found:Indirect-related BITconfig:ID:1415, bitoffs:19, length:19 +Found:Indirect-related BITconfig:ID:1415, bitoffs:20, length:21 +Found:Indirect-related BITconfig:ID:1415, bitoffs:22, length:23 +Found:Indirect-related BITconfig:ID:1415, bitoffs:24, length:26 +Found:Indirect-related BITconfig:ID:1415, bitoffs:27, length:28 +Found:Indirect-related BITconfig:ID:1415, bitoffs:29, length:30 +Found:Indirect-related BITconfig:ID:1417, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:1417, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1417, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:1417, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1417, bitoffs:5, length:5 +Found:Related config:904 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Hidden child:14 +Hidden child:15 +INTERFACE:191 +INTERFACE:192 +Found:Indirect-related BITconfig:ID:108, bitoffs:1, length:31 +Found:Indirect-related BITconfig:ID:439, bitoffs:0, length:1 +Found:Indirect-related BITconfig:ID:1510, bitoffs:5, length:13 +Found:Indirect-related BITconfig:ID:108, bitoffs:0, length:0 +Found:Related BITconfig:ID:439, bitoffs:8, length:8 +Found:Related GlobalIntVar(ButtonGraphics):993 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Related BITconfig:ID:1376, bitoffs:9, length:9 +Found:Related BITconfig:ID:1376, bitoffs:12, length:12 +Found:Related BITconfig:ID:1376, bitoffs:11, length:11 +Found:Related BITconfig:ID:1376, bitoffs:10, length:10 +Found:Related BITconfig:ID:1376, bitoffs:13, length:13 +Found:Related BITconfig:ID:1376, bitoffs:14, length:14 +Found:Related BITconfig:ID:1376, bitoffs:15, length:15 +Found:Related BITconfig:ID:1376, bitoffs:16, length:16 +Found:Related BITconfig:ID:1376, bitoffs:17, length:17 +Found:Related BITconfig:ID:1376, bitoffs:21, length:21 +Found:Related BITconfig:ID:1376, bitoffs:24, length:24 +Found:Related BITconfig:ID:1376, bitoffs:23, length:23 +Found:Related BITconfig:ID:1376, bitoffs:22, length:22 +Found:Related GlobalIntVar(ButtonGraphics):988 +Found:Related GlobalIntVar(ButtonGraphics):989 +Found:Related GlobalIntVar(ButtonGraphics):990 +Found:Related GlobalIntVar(ButtonGraphics):991 +Found:Related GlobalIntVar(ButtonGraphics):631 +Found:Indirect-related BITconfig:ID:1376, bitoffs:0, length:2 +Found:Indirect-related BITconfig:ID:1376, bitoffs:3, length:5 +Found:Indirect-related BITconfig:ID:1376, bitoffs:6, length:8 +Found:Indirect-related BITconfig:ID:1376, bitoffs:18, length:20 +Found:Indirect-related config:1092 +Found:Indirect-related BITconfig:ID:2089, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1087, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1209, bitoffs:6, length:7 +Found:Indirect-related BITconfig:ID:1331, bitoffs:0, length:2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1334 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1335 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1402 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1403 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1234 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1235 +Found:Related GlobalIntVar(ButtonGraphics):1024 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related GlobalIntVar(ButtonGraphics):992 +Hidden child:92 +Hidden child:93 +INTERFACE:193 +Found:Indirect-related BITconfig:ID:108, bitoffs:1, length:31 +Found:Indirect-related BITconfig:ID:439, bitoffs:0, length:1 +Found:Indirect-related BITconfig:ID:1510, bitoffs:5, length:13 +Found:Indirect-related BITconfig:ID:108, bitoffs:0, length:0 +Found:Related BITconfig:ID:1376, bitoffs:9, length:9 +Found:Related BITconfig:ID:1376, bitoffs:12, length:12 +Found:Related BITconfig:ID:1376, bitoffs:11, length:11 +Found:Related BITconfig:ID:1376, bitoffs:10, length:10 +Found:Related BITconfig:ID:1376, bitoffs:13, length:13 +Found:Related BITconfig:ID:1376, bitoffs:14, length:14 +Found:Related BITconfig:ID:1376, bitoffs:15, length:15 +Found:Related BITconfig:ID:1376, bitoffs:16, length:16 +Found:Related BITconfig:ID:1376, bitoffs:17, length:17 +Found:Related BITconfig:ID:1376, bitoffs:21, length:21 +Found:Related BITconfig:ID:1376, bitoffs:24, length:24 +Found:Related BITconfig:ID:1376, bitoffs:23, length:23 +Found:Related BITconfig:ID:1376, bitoffs:22, length:22 +Found:Related GlobalIntVar(ButtonGraphics):988 +Found:Related GlobalIntVar(ButtonGraphics):989 +Found:Related GlobalIntVar(ButtonGraphics):990 +Found:Related GlobalIntVar(ButtonGraphics):991 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Related GlobalIntVar(ButtonGraphics):631 +Found:Indirect-related BITconfig:ID:1376, bitoffs:0, length:2 +Found:Indirect-related BITconfig:ID:1376, bitoffs:3, length:5 +Found:Indirect-related BITconfig:ID:1376, bitoffs:6, length:8 +Found:Indirect-related BITconfig:ID:1376, bitoffs:18, length:20 +Found:Related BITconfig:ID:439, bitoffs:8, length:8 +Found:Related GlobalIntVar(ButtonGraphics):993 +Found:Indirect-related config:1092 +Found:Indirect-related BITconfig:ID:2089, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1087, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1209, bitoffs:6, length:7 +Found:Indirect-related BITconfig:ID:1331, bitoffs:0, length:2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1334 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1335 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1402 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1403 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1234 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1235 +Found:Related GlobalIntVar(ButtonGraphics):992 +Hidden child:49 +Hidden child:50 +INTERFACE:194 +Hidden child:14 +Hidden child:15 +Hidden child:16 +Hidden child:17 +Hidden child:18 +INTERFACE:195 +Hidden child:1 +Hidden child:2 +Hidden child:3 +Hidden child:4 +INTERFACE:196 +INTERFACE:197 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related BITconfig:ID:624, bitoffs:0, length:12 +Found:Related BITconfig:ID:625, bitoffs:15, length:27 +Found:Related BITconfig:ID:625, bitoffs:0, length:14 +Found:Related BITconfig:ID:624, bitoffs:13, length:26 +INTERFACE:198 +INTERFACE:199 +INTERFACE:200 +Found:Related config:170 +Found:Related GlobalStringVar(InfoString):320 +Found:Related GlobalStringVar(InfoString):319 +INTERFACE:201 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1383, bitoffs:0, length:2 +Found:Indirect-related BITconfig:ID:1383, bitoffs:3, length:4 +Found:Indirect-related BITconfig:ID:1383, bitoffs:5, length:7 +Found:Indirect-related BITconfig:ID:1383, bitoffs:8, length:9 +Found:Indirect-related BITconfig:ID:1383, bitoffs:10, length:11 +Found:Indirect-related BITconfig:ID:900, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:903, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:900, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:900, bitoffs:7, length:7 +Found:Indirect-related BITconfig:ID:900, bitoffs:8, length:8 +Found:Indirect-related BITconfig:ID:900, bitoffs:9, length:9 +INTERFACE:202 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:27 +INTERFACE:203 +Found:Related GlobalIntVar(ButtonGraphics):1007 +INTERFACE:204 +Hidden child:26 +Hidden child:27 +Hidden child:28 +Hidden child:77 +Hidden child:86 +Hidden child:87 +Hidden child:89 +Hidden child:98 +Hidden child:99 +Hidden child:101 +Hidden child:110 +Hidden child:111 +Hidden child:113 +INTERFACE:205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:27 +INTERFACE:206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):728 +Found:Indirect-related GlobalIntVar(ButtonGraphics):700 +Found:Indirect-related GlobalIntVar(ButtonGraphics):701 +Found:Indirect-related GlobalIntVar(ButtonGraphics):702 +Found:Indirect-related GlobalIntVar(ButtonGraphics):703 +Found:Indirect-related GlobalIntVar(ButtonGraphics):704 +Found:Indirect-related GlobalIntVar(ButtonGraphics):705 +Found:Indirect-related GlobalIntVar(ButtonGraphics):706 +Found:Indirect-related GlobalIntVar(ButtonGraphics):707 +Found:Indirect-related GlobalIntVar(ButtonGraphics):708 +Found:Indirect-related GlobalIntVar(ButtonGraphics):709 +Found:Indirect-related GlobalIntVar(ButtonGraphics):710 +Found:Indirect-related GlobalIntVar(ButtonGraphics):711 +Found:Indirect-related GlobalIntVar(ButtonGraphics):712 +Found:Indirect-related GlobalIntVar(ButtonGraphics):713 +Found:Indirect-related GlobalIntVar(ButtonGraphics):714 +Found:Indirect-related GlobalIntVar(ButtonGraphics):715 +Found:Indirect-related GlobalIntVar(ButtonGraphics):716 +Found:Indirect-related GlobalIntVar(ButtonGraphics):717 +Found:Indirect-related GlobalIntVar(ButtonGraphics):718 +Found:Indirect-related GlobalIntVar(ButtonGraphics):719 +Found:Indirect-related GlobalIntVar(ButtonGraphics):720 +Found:Indirect-related GlobalIntVar(ButtonGraphics):721 +Found:Indirect-related GlobalIntVar(ButtonGraphics):722 +Found:Indirect-related GlobalIntVar(ButtonGraphics):723 +Found:Indirect-related GlobalIntVar(ButtonGraphics):724 +Found:Indirect-related GlobalIntVar(ButtonGraphics):725 +Found:Indirect-related GlobalIntVar(ButtonGraphics):726 +Found:Indirect-related GlobalIntVar(ButtonGraphics):727 +INTERFACE:207 +INTERFACE:208 +INTERFACE:209 +Found:Related config:531 +INTERFACE:210 +INTERFACE:211 +INTERFACE:212 +INTERFACE:213 +INTERFACE:214 +INTERFACE:215 +INTERFACE:216 +INTERFACE:217 +INTERFACE:218 +INTERFACE:219 +INTERFACE:220 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:221 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:222 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:223 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +INTERFACE:224 +INTERFACE:225 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:15 +INTERFACE:226 +Found:Indirect-related BITconfig:ID:425, bitoffs:1, length:2 +INTERFACE:227 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:55 +INTERFACE:228 +Hidden child:9 +INTERFACE:229 +Hidden child:9 +INTERFACE:230 +Hidden child:10 +INTERFACE:231 +Hidden child:10 +INTERFACE:232 +Hidden child:9 +INTERFACE:233 +Hidden child:9 +INTERFACE:234 +Hidden child:10 +INTERFACE:235 +Hidden child:10 +INTERFACE:236 +Hidden child:6 +INTERFACE:237 +Hidden child:8 +INTERFACE:238 +Hidden child:9 +INTERFACE:239 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:8 +INTERFACE:240 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:7 +Hidden child:12 +Hidden child:17 +Hidden child:22 +Hidden child:26 +INTERFACE:241 +INTERFACE:242 +INTERFACE:243 +INTERFACE:244 +INTERFACE:245 +INTERFACE:246 +INTERFACE:247 +INTERFACE:248 +INTERFACE:249 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:250 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:251 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:252 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:2 +INTERFACE:253 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:254 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:3 +INTERFACE:255 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:2 +INTERFACE:256 +INTERFACE:257 +INTERFACE:258 +INTERFACE:259 +Found:Related GlobalIntVar(ButtonGraphics):1525 +INTERFACE:260 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:47 +INTERFACE:261 +Found:Indirect-related config:170 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related config:171 +Found:Indirect-related config:427 +Found:Indirect-related BITconfig:ID:1438, bitoffs:5, length:5 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +INTERFACE:262 +Found:Related BITconfig:ID:898, bitoffs:6, length:8 +Found:Related GlobalIntVar(ButtonGraphics):163 +Found:Related GlobalIntVar(ButtonGraphics):164 +Found:Related GlobalIntVar(ButtonGraphics):162 +Found:Related GlobalIntVar(ButtonGraphics):165 +Found:Related GlobalIntVar(ButtonGraphics):166 +Found:Related GlobalIntVar(ButtonGraphics):167 +Found:Related BITconfig:ID:898, bitoffs:9, length:13 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:5 +Hidden child:6 +Hidden child:7 +Hidden child:8 +Hidden child:9 +Hidden child:10 +Hidden child:11 +Hidden child:12 +Hidden child:13 +Hidden child:14 +Hidden child:15 +Hidden child:16 +Hidden child:17 +Hidden child:18 +Hidden child:19 +INTERFACE:263 +Found:Related BITconfig:ID:727, bitoffs:9, length:18 +INTERFACE:264 +Found:Related BITconfig:ID:518, bitoffs:16, length:18 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:265 +Found:Related BITconfig:ID:1305, bitoffs:9, length:9 +Found:Indirect-related GlobalIntVar(ButtonGraphics):267 +Found:Indirect-related GlobalStringVar(InfoString):38 +Found:Indirect-related GlobalStringVar(InfoString):39 +Found:Related GlobalIntVar(ButtonGraphics):266 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1029 +Found:Indirect-related GlobalStringVar(InfoString):22 +Found:Related GlobalIntVar(ButtonGraphics):5 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related config:287 +Found:Indirect-related config:1054 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:266 +Found:Related BITconfig:ID:1146, bitoffs:5, length:31 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:267 +Found:Related config:261 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:268 +INTERFACE:269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):105 +Found:Related GlobalIntVar(ButtonGraphics):106 +Found:Related GlobalIntVar(ButtonGraphics):99 +Found:Related GlobalIntVar(ButtonGraphics):100 +Found:Related GlobalIntVar(ButtonGraphics):101 +Found:Related GlobalIntVar(ButtonGraphics):104 +Found:Related GlobalIntVar(ButtonGraphics):102 +Found:Indirect-related BITconfig:ID:1161, bitoffs:5, length:18 +Found:Indirect-related GlobalIntVar(ButtonGraphics):103 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Related config:1163 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related config:1164 +Found:Related BITconfig:ID:1161, bitoffs:19, length:25 +INTERFACE:270 +Found:Related config:106 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:271 +Found:Indirect-related BITconfig:ID:2382, bitoffs:0, length:14 +Found:Indirect-related GlobalIntVar(ButtonGraphics):181 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1052 +Found:Related GlobalIntVar(ButtonGraphics):1063 +Found:Indirect-related BITconfig:ID:1510, bitoffs:5, length:13 +Found:Indirect-related BITconfig:ID:1587, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:1587, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:1587, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1587, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:1587, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1587, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1587, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:1587, bitoffs:7, length:7 +Found:Indirect-related BITconfig:ID:1587, bitoffs:8, length:8 +Found:Indirect-related BITconfig:ID:1587, bitoffs:9, length:9 +Found:Indirect-related BITconfig:ID:1587, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:1587, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:1587, bitoffs:12, length:12 +Found:Indirect-related BITconfig:ID:1587, bitoffs:13, length:13 +Found:Indirect-related BITconfig:ID:1587, bitoffs:14, length:14 +Found:Indirect-related BITconfig:ID:1587, bitoffs:15, length:15 +Found:Indirect-related BITconfig:ID:1587, bitoffs:16, length:16 +Found:Indirect-related BITconfig:ID:1587, bitoffs:17, length:17 +Found:Indirect-related BITconfig:ID:1587, bitoffs:18, length:18 +Found:Indirect-related BITconfig:ID:1587, bitoffs:19, length:19 +Found:Indirect-related BITconfig:ID:1397, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:1397, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:1397, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1397, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:1397, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1397, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1397, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:1397, bitoffs:7, length:7 +Found:Indirect-related BITconfig:ID:1397, bitoffs:8, length:8 +Found:Indirect-related BITconfig:ID:1397, bitoffs:9, length:9 +Found:Indirect-related BITconfig:ID:1397, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:1397, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:1397, bitoffs:12, length:12 +Found:Indirect-related BITconfig:ID:1397, bitoffs:13, length:13 +Found:Indirect-related BITconfig:ID:1397, bitoffs:14, length:14 +Found:Indirect-related BITconfig:ID:1397, bitoffs:15, length:15 +Found:Indirect-related BITconfig:ID:1397, bitoffs:16, length:16 +Found:Indirect-related BITconfig:ID:1397, bitoffs:17, length:17 +Found:Indirect-related BITconfig:ID:1397, bitoffs:18, length:18 +Found:Indirect-related BITconfig:ID:1397, bitoffs:19, length:19 +Found:Indirect-related BITconfig:ID:1397, bitoffs:20, length:20 +Found:Indirect-related BITconfig:ID:1397, bitoffs:21, length:21 +Found:Indirect-related BITconfig:ID:1397, bitoffs:22, length:22 +Found:Indirect-related BITconfig:ID:1397, bitoffs:23, length:23 +Found:Indirect-related BITconfig:ID:1397, bitoffs:24, length:24 +Found:Indirect-related BITconfig:ID:1397, bitoffs:25, length:25 +Found:Indirect-related BITconfig:ID:1397, bitoffs:27, length:27 +Found:Indirect-related BITconfig:ID:1397, bitoffs:26, length:26 +Found:Indirect-related BITconfig:ID:1397, bitoffs:28, length:28 +Found:Indirect-related BITconfig:ID:1397, bitoffs:29, length:29 +Hidden child:24 +Hidden child:42 +INTERFACE:272 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:273 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:274 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:275 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Related GlobalIntVar(ButtonGraphics):771 +Hidden child:15 +Hidden child:316 +INTERFACE:276 +Found:Related BITconfig:ID:1377, bitoffs:2, length:17 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:78 +Hidden child:79 +INTERFACE:277 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:278 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:279 +Found:Related GlobalStringVar(InfoString):207 +Found:Related GlobalStringVar(InfoString):208 +INTERFACE:280 +INTERFACE:281 +Hidden child:7 +INTERFACE:282 +Found:Related BITconfig:ID:607, bitoffs:13, length:18 +Found:Related BITconfig:ID:607, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:283 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:284 +INTERFACE:285 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:286 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related config:331 +Found:Related config:330 +INTERFACE:287 +Found:Related GlobalIntVar(ButtonGraphics):1032 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:31 +INTERFACE:288 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:289 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:290 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:291 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related GlobalIntVar(ButtonGraphics):838 +Found:Related GlobalStringVar(InfoString):180 +Found:Related GlobalStringVar(InfoString):181 +Found:Related GlobalIntVar(ButtonGraphics):837 +Hidden child:55 +Hidden child:56 +Hidden child:57 +Hidden child:58 +INTERFACE:292 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1455, bitoffs:20, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):930 +Found:Indirect-related GlobalIntVar(ButtonGraphics):931 +Found:Indirect-related GlobalIntVar(ButtonGraphics):932 +Found:Indirect-related GlobalIntVar(ButtonGraphics):933 +Found:Indirect-related GlobalIntVar(ButtonGraphics):934 +Found:Indirect-related GlobalIntVar(ButtonGraphics):935 +Found:Indirect-related GlobalIntVar(ButtonGraphics):936 +Found:Indirect-related GlobalIntVar(ButtonGraphics):937 +Found:Indirect-related GlobalIntVar(ButtonGraphics):938 +Found:Indirect-related GlobalIntVar(ButtonGraphics):939 +Found:Indirect-related GlobalIntVar(ButtonGraphics):929 +Found:Indirect-related BITconfig:ID:1454, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:1454, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:1454, bitoffs:12, length:12 +Found:Indirect-related BITconfig:ID:1454, bitoffs:13, length:13 +Found:Indirect-related BITconfig:ID:1454, bitoffs:14, length:14 +Found:Indirect-related BITconfig:ID:1454, bitoffs:15, length:15 +Found:Indirect-related BITconfig:ID:1454, bitoffs:16, length:16 +Found:Indirect-related BITconfig:ID:1454, bitoffs:17, length:17 +Found:Indirect-related BITconfig:ID:1454, bitoffs:18, length:18 +Found:Indirect-related BITconfig:ID:1454, bitoffs:19, length:19 +Found:Indirect-related BITconfig:ID:1445, bitoffs:0, length:18 +Found:Indirect-related GlobalIntVar(ButtonGraphics):928 +Found:Indirect-related BITconfig:ID:1453, bitoffs:10, length:11 +Found:Indirect-related BITconfig:ID:1453, bitoffs:12, length:13 +Found:Indirect-related BITconfig:ID:1453, bitoffs:14, length:15 +Found:Indirect-related BITconfig:ID:1453, bitoffs:16, length:17 +Found:Indirect-related BITconfig:ID:1453, bitoffs:18, length:19 +Found:Indirect-related BITconfig:ID:1453, bitoffs:20, length:21 +Found:Indirect-related BITconfig:ID:1453, bitoffs:22, length:23 +Found:Indirect-related BITconfig:ID:1453, bitoffs:24, length:25 +Found:Indirect-related BITconfig:ID:1453, bitoffs:26, length:27 +Found:Indirect-related BITconfig:ID:1453, bitoffs:28, length:29 +Found:Indirect-related BITconfig:ID:1454, bitoffs:20, length:20 +Found:Indirect-related BITconfig:ID:1454, bitoffs:21, length:21 +Found:Indirect-related BITconfig:ID:1454, bitoffs:22, length:22 +Found:Indirect-related BITconfig:ID:1454, bitoffs:23, length:23 +Found:Indirect-related BITconfig:ID:1454, bitoffs:24, length:24 +Found:Indirect-related BITconfig:ID:1454, bitoffs:25, length:25 +Found:Indirect-related BITconfig:ID:1454, bitoffs:26, length:26 +Found:Indirect-related BITconfig:ID:1454, bitoffs:27, length:27 +Found:Indirect-related BITconfig:ID:1454, bitoffs:28, length:28 +Found:Indirect-related BITconfig:ID:1454, bitoffs:29, length:29 +Hidden child:130 +INTERFACE:293 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:294 +INTERFACE:295 +INTERFACE:296 +INTERFACE:297 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:23 +INTERFACE:298 +Found:Indirect-related GlobalIntVar(ButtonGraphics):618 +Found:Indirect-related GlobalIntVar(ButtonGraphics):619 +Found:Indirect-related GlobalIntVar(ButtonGraphics):620 +Found:Indirect-related GlobalIntVar(ButtonGraphics):621 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:299 +Found:Related config:75 +Hidden child:32 +Hidden child:33 +Hidden child:34 +Hidden child:35 +Hidden child:36 +Hidden child:37 +Hidden child:38 +Hidden child:39 +Hidden child:40 +Hidden child:41 +Hidden child:42 +Hidden child:43 +Hidden child:44 +Hidden child:45 +Hidden child:46 +Hidden child:47 +Hidden child:55 +Hidden child:71 +Hidden child:72 +INTERFACE:300 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:65 +Hidden child:81 +Hidden child:89 +Hidden child:97 +Hidden child:161 +Hidden child:169 +Hidden child:209 +Hidden child:249 +Hidden child:266 +INTERFACE:301 +Found:Indirect-related BITconfig:ID:1087, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:1087, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1087, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:1087, bitoffs:8, length:8 +Found:Indirect-related BITconfig:ID:1087, bitoffs:9, length:9 +Found:Indirect-related BITconfig:ID:1087, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:1087, bitoffs:13, length:13 +Found:Indirect-related BITconfig:ID:1087, bitoffs:14, length:14 +Found:Indirect-related BITconfig:ID:1087, bitoffs:15, length:15 +Found:Related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related BITconfig:ID:1088, bitoffs:0, length:18 +Found:Related GlobalIntVar(ButtonGraphics):54 +Found:Related GlobalIntVar(ButtonGraphics):55 +Found:Related GlobalIntVar(ButtonGraphics):57 +Found:Related GlobalIntVar(ButtonGraphics):58 +Found:Related GlobalIntVar(ButtonGraphics):60 +Found:Related GlobalIntVar(ButtonGraphics):61 +Found:Related GlobalIntVar(ButtonGraphics):64 +Found:Related GlobalIntVar(ButtonGraphics):66 +Found:Related GlobalIntVar(ButtonGraphics):62 +Hidden child:13 +Hidden child:15 +Hidden child:17 +Hidden child:19 +Hidden child:21 +Hidden child:23 +Hidden child:25 +Hidden child:27 +Hidden child:29 +INTERFACE:302 +Found:Related GlobalIntVar(ButtonGraphics):1536 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Related BITconfig:ID:2208, bitoffs:15, length:18 +Found:Related BITconfig:ID:2209, bitoffs:9, length:12 +Found:Related GlobalIntVar(ButtonGraphics):1535 +INTERFACE:303 +INTERFACE:304 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:305 +INTERFACE:306 +Found:Related GlobalIntVar(ButtonGraphics):767 +Found:Related GlobalIntVar(ButtonGraphics):761 +Found:Related GlobalIntVar(ButtonGraphics):762 +Found:Related GlobalIntVar(ButtonGraphics):763 +Found:Related GlobalIntVar(ButtonGraphics):764 +Found:Related GlobalIntVar(ButtonGraphics):765 +Found:Related GlobalIntVar(ButtonGraphics):766 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:12 +Hidden child:13 +Hidden child:14 +Hidden child:15 +Hidden child:16 +Hidden child:17 +Hidden child:25 +Hidden child:27 +INTERFACE:307 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:308 +Found:Related BITconfig:ID:1393, bitoffs:19, length:21 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:2 +Hidden child:3 +Hidden child:4 +Hidden child:5 +Hidden child:6 +Hidden child:7 +Hidden child:8 +Hidden child:9 +Hidden child:10 +Hidden child:11 +Hidden child:12 +Hidden child:13 +Hidden child:14 +Hidden child:15 +Hidden child:19 +Hidden child:20 +Hidden child:21 +Hidden child:22 +Hidden child:23 +Hidden child:24 +Hidden child:25 +Hidden child:26 +Hidden child:27 +Hidden child:28 +Hidden child:29 +Hidden child:30 +Hidden child:31 +Hidden child:32 +INTERFACE:309 +Found:Indirect-related GlobalIntVar(ButtonGraphics):779 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1008 +Found:Indirect-related GlobalIntVar(ButtonGraphics):774 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1009 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1015 +Found:Related BITconfig:ID:1057, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:11 +Hidden child:17 +INTERFACE:310 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1606 +Found:Indirect-related GlobalStringVar(InfoString):139 +Found:Indirect-related GlobalStringVar(InfoString):141 +Found:Indirect-related GlobalStringVar(InfoString):191 +Found:Indirect-related GlobalStringVar(InfoString):192 +Found:Indirect-related GlobalStringVar(InfoString):193 +Found:Indirect-related GlobalStringVar(InfoString):289 +Found:Indirect-related GlobalStringVar(InfoString):290 +Found:Indirect-related GlobalStringVar(InfoString):291 +Found:Indirect-related GlobalStringVar(InfoString):297 +Found:Indirect-related GlobalStringVar(InfoString):298 +Found:Indirect-related GlobalStringVar(InfoString):299 +Found:Indirect-related GlobalStringVar(InfoString):300 +Found:Indirect-related GlobalStringVar(InfoString):301 +Found:Indirect-related GlobalStringVar(InfoString):302 +Found:Indirect-related GlobalStringVar(InfoString):303 +INTERFACE:311 +Found:Related BITconfig:ID:1934, bitoffs:0, length:0 +Found:Related BITconfig:ID:1934, bitoffs:2, length:2 +Found:Related BITconfig:ID:1934, bitoffs:4, length:4 +Found:Related BITconfig:ID:1934, bitoffs:6, length:6 +Found:Related BITconfig:ID:1934, bitoffs:1, length:1 +Found:Related BITconfig:ID:1934, bitoffs:9, length:9 +Found:Related BITconfig:ID:1934, bitoffs:5, length:5 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:2 +Hidden child:3 +Hidden child:6 +Hidden child:7 +Hidden child:10 +Hidden child:11 +Hidden child:14 +Hidden child:15 +Hidden child:18 +Hidden child:19 +Hidden child:22 +Hidden child:23 +Hidden child:26 +INTERFACE:312 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:313 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Related config:850 +Found:Related config:855 +Found:Related GlobalIntVar(ButtonGraphics):1437 +Found:Related GlobalIntVar(ButtonGraphics):1438 +Found:Related GlobalIntVar(ButtonGraphics):1439 +Found:Related GlobalIntVar(ButtonGraphics):1440 +Found:Related GlobalIntVar(ButtonGraphics):1449 +Found:Related config:851 +Found:Related config:852 +Found:Related GlobalIntVar(ButtonGraphics):1441 +Found:Related GlobalIntVar(ButtonGraphics):1442 +Found:Related GlobalIntVar(ButtonGraphics):1443 +Found:Related GlobalIntVar(ButtonGraphics):1444 +Found:Related GlobalIntVar(ButtonGraphics):1450 +Found:Related config:853 +Found:Related config:854 +Found:Related GlobalIntVar(ButtonGraphics):1445 +Found:Related GlobalIntVar(ButtonGraphics):1446 +Found:Related GlobalIntVar(ButtonGraphics):1447 +Found:Related GlobalIntVar(ButtonGraphics):1448 +Found:Related GlobalIntVar(ButtonGraphics):1451 +Found:Related config:856 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:56 +Hidden child:57 +Hidden child:58 +Hidden child:59 +Hidden child:60 +Hidden child:61 +Hidden child:62 +Hidden child:63 +Hidden child:65 +Hidden child:66 +Hidden child:69 +Hidden child:78 +Hidden child:81 +Hidden child:132 +Hidden child:133 +Hidden child:134 +Hidden child:135 +Hidden child:136 +Hidden child:137 +Hidden child:138 +Hidden child:139 +Hidden child:142 +Hidden child:143 +Hidden child:146 +Hidden child:155 +Hidden child:158 +Hidden child:209 +Hidden child:210 +Hidden child:211 +Hidden child:212 +Hidden child:213 +Hidden child:214 +Hidden child:215 +Hidden child:216 +Hidden child:218 +Hidden child:219 +Hidden child:222 +Hidden child:231 +Hidden child:234 +INTERFACE:314 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related BITconfig:ID:2212, bitoffs:0, length:0 +Found:Related BITconfig:ID:2212, bitoffs:1, length:1 +Found:Related BITconfig:ID:2212, bitoffs:2, length:2 +Found:Related BITconfig:ID:2212, bitoffs:3, length:3 +Found:Related BITconfig:ID:2212, bitoffs:4, length:4 +Found:Related BITconfig:ID:2212, bitoffs:5, length:5 +Found:Related BITconfig:ID:2212, bitoffs:6, length:6 +Found:Related BITconfig:ID:2212, bitoffs:7, length:7 +Found:Related BITconfig:ID:2212, bitoffs:8, length:8 +Found:Related BITconfig:ID:2212, bitoffs:9, length:9 +Found:Related BITconfig:ID:2212, bitoffs:10, length:10 +Found:Related BITconfig:ID:2212, bitoffs:11, length:11 +Found:Related BITconfig:ID:2212, bitoffs:12, length:12 +Found:Related BITconfig:ID:2212, bitoffs:13, length:13 +Found:Related BITconfig:ID:2212, bitoffs:14, length:14 +Found:Related BITconfig:ID:2212, bitoffs:15, length:15 +Found:Related BITconfig:ID:2212, bitoffs:16, length:16 +Found:Related BITconfig:ID:2212, bitoffs:17, length:17 +Found:Related BITconfig:ID:2212, bitoffs:18, length:18 +Found:Related BITconfig:ID:2212, bitoffs:19, length:19 +Found:Related BITconfig:ID:2212, bitoffs:20, length:20 +Found:Related BITconfig:ID:2212, bitoffs:21, length:21 +Found:Related BITconfig:ID:2212, bitoffs:22, length:22 +Found:Related BITconfig:ID:2212, bitoffs:23, length:23 +Found:Related BITconfig:ID:2212, bitoffs:24, length:24 +Found:Related BITconfig:ID:2212, bitoffs:25, length:25 +Found:Related BITconfig:ID:2212, bitoffs:26, length:26 +INTERFACE:315 +INTERFACE:316 +Found:Related BITconfig:ID:639, bitoffs:0, length:5 +Hidden child:1 +Hidden child:2 +INTERFACE:317 +INTERFACE:318 +INTERFACE:319 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1607 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1608 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1609 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1610 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1611 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1612 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1613 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1614 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1615 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1616 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1617 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1618 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1619 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1620 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1621 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1622 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1623 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1624 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1625 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1626 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1627 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1628 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1629 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1630 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1631 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1632 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1633 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1634 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1635 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1636 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1637 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1638 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1639 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1640 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1641 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1642 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1643 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1644 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1645 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1646 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1647 +Hidden child:4 +Hidden child:53 +Hidden child:68 +INTERFACE:320 +Found:Indirect-related BITconfig:ID:1179, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:1179, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:1179, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1179, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:1179, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1179, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1179, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:1179, bitoffs:7, length:7 +Found:Indirect-related BITconfig:ID:1179, bitoffs:8, length:8 +Found:Indirect-related BITconfig:ID:1179, bitoffs:9, length:9 +Found:Indirect-related BITconfig:ID:1179, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:1179, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:1179, bitoffs:12, length:12 +Found:Indirect-related BITconfig:ID:1179, bitoffs:13, length:13 +Found:Indirect-related BITconfig:ID:1179, bitoffs:14, length:14 +Found:Indirect-related BITconfig:ID:1179, bitoffs:15, length:15 +Found:Indirect-related BITconfig:ID:1179, bitoffs:16, length:16 +Found:Indirect-related BITconfig:ID:1179, bitoffs:17, length:17 +Found:Indirect-related BITconfig:ID:1179, bitoffs:18, length:18 +Found:Indirect-related BITconfig:ID:1179, bitoffs:19, length:19 +Found:Indirect-related BITconfig:ID:1179, bitoffs:20, length:20 +Found:Indirect-related BITconfig:ID:1179, bitoffs:21, length:21 +Found:Indirect-related BITconfig:ID:1179, bitoffs:22, length:22 +Found:Indirect-related BITconfig:ID:1179, bitoffs:23, length:23 +Found:Indirect-related BITconfig:ID:1179, bitoffs:24, length:24 +Found:Related GlobalIntVar(ButtonGraphics):80 +Found:Indirect-related config:1966 +Found:Indirect-related config:1968 +Found:Indirect-related config:1969 +Found:Indirect-related config:1970 +Found:Indirect-related config:1971 +Found:Indirect-related config:1972 +Found:Indirect-related config:1973 +Found:Indirect-related config:1974 +Found:Indirect-related config:1975 +Found:Indirect-related config:1976 +Found:Indirect-related config:1977 +Found:Indirect-related config:1978 +Found:Indirect-related config:1979 +Found:Indirect-related config:1980 +Found:Indirect-related config:1981 +Found:Indirect-related config:1982 +Found:Indirect-related config:1983 +Found:Indirect-related config:1984 +Found:Indirect-related config:1985 +Found:Indirect-related config:1986 +Found:Indirect-related config:1987 +Found:Indirect-related config:1988 +Found:Indirect-related config:1989 +Found:Indirect-related config:1990 +Found:Indirect-related config:1991 +Found:Indirect-related config:1992 +Found:Indirect-related config:1993 +Found:Indirect-related config:1994 +Found:Indirect-related config:1995 +Found:Indirect-related config:1996 +Found:Indirect-related config:1997 +Found:Indirect-related config:1998 +Found:Indirect-related config:1999 +Found:Indirect-related config:2000 +Found:Indirect-related config:2001 +Found:Indirect-related config:2002 +Found:Indirect-related config:2003 +Found:Indirect-related config:2004 +Found:Indirect-related config:2005 +Found:Indirect-related config:2006 +Found:Indirect-related config:2007 +Found:Indirect-related config:2008 +Found:Indirect-related config:2009 +Found:Indirect-related config:2010 +Found:Indirect-related config:2011 +Found:Indirect-related config:2012 +Found:Indirect-related config:2013 +Found:Indirect-related config:2014 +Found:Indirect-related config:2015 +Found:Indirect-related config:2016 +Found:Indirect-related config:2017 +Found:Indirect-related config:2018 +Hidden child:203 +INTERFACE:321 +INTERFACE:322 +INTERFACE:323 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:324 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):617 +INTERFACE:325 +Found:Related config:158 +Found:Related config:156 +Found:Related config:157 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:2 +Hidden child:3 +Hidden child:4 +Hidden child:5 +Hidden child:6 +Hidden child:7 +Hidden child:8 +Hidden child:9 +Hidden child:10 +Hidden child:11 +Hidden child:12 +Hidden child:22 +Hidden child:23 +Hidden child:24 +Hidden child:25 +Hidden child:26 +Hidden child:27 +Hidden child:28 +Hidden child:29 +Hidden child:30 +Hidden child:31 +INTERFACE:326 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:327 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1045, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1045, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1045, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1045, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1045, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1045, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1045, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1045, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1045, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1045, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1046, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1046, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1046, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1046, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1046, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1046, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1046, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1046, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1046, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1045, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1047, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1047, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1047, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1047, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1047, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1047, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1047, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1047, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1501, bitoffs:0, length:2 +Hidden child:19 +INTERFACE:328 +Found:Related config:343 +Found:Related config:344 +Found:Related config:345 +INTERFACE:329 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +INTERFACE:330 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:331 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:332 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +INTERFACE:333 +INTERFACE:334 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):12 +Found:Indirect-related GlobalIntVar(ButtonGraphics):13 +Found:Indirect-related GlobalIntVar(ButtonGraphics):14 +Found:Indirect-related GlobalIntVar(ButtonGraphics):15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):16 +Found:Indirect-related GlobalIntVar(ButtonGraphics):17 +Found:Indirect-related GlobalIntVar(ButtonGraphics):18 +Found:Indirect-related GlobalIntVar(ButtonGraphics):19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):20 +Found:Indirect-related GlobalIntVar(ButtonGraphics):21 +Found:Indirect-related GlobalIntVar(ButtonGraphics):22 +Found:Indirect-related GlobalIntVar(ButtonGraphics):23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):24 +Found:Indirect-related GlobalIntVar(ButtonGraphics):25 +Found:Indirect-related GlobalIntVar(ButtonGraphics):26 +Found:Indirect-related GlobalIntVar(ButtonGraphics):27 +Found:Indirect-related GlobalIntVar(ButtonGraphics):28 +Found:Indirect-related GlobalIntVar(ButtonGraphics):29 +Found:Indirect-related GlobalIntVar(ButtonGraphics):30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):31 +Found:Indirect-related GlobalIntVar(ButtonGraphics):32 +Found:Indirect-related GlobalIntVar(ButtonGraphics):33 +Found:Indirect-related GlobalIntVar(ButtonGraphics):34 +Found:Indirect-related GlobalIntVar(ButtonGraphics):35 +Found:Indirect-related GlobalIntVar(ButtonGraphics):36 +Found:Indirect-related GlobalIntVar(ButtonGraphics):37 +Found:Indirect-related GlobalIntVar(ButtonGraphics):38 +Found:Indirect-related GlobalIntVar(ButtonGraphics):39 +Found:Indirect-related GlobalIntVar(ButtonGraphics):212 +Found:Related GlobalStringVar(InfoString):203 +Hidden child:48 +Hidden child:51 +Hidden child:55 +INTERFACE:335 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related GlobalIntVar(ButtonGraphics):12 +Found:Related GlobalIntVar(ButtonGraphics):13 +Found:Related GlobalIntVar(ButtonGraphics):14 +Found:Related GlobalIntVar(ButtonGraphics):15 +Found:Related GlobalIntVar(ButtonGraphics):16 +Found:Related GlobalIntVar(ButtonGraphics):17 +Found:Related GlobalIntVar(ButtonGraphics):18 +Found:Related GlobalIntVar(ButtonGraphics):19 +Found:Related GlobalIntVar(ButtonGraphics):20 +Found:Related GlobalIntVar(ButtonGraphics):21 +Found:Related GlobalIntVar(ButtonGraphics):22 +Found:Related GlobalIntVar(ButtonGraphics):23 +Found:Related GlobalIntVar(ButtonGraphics):24 +Found:Related GlobalIntVar(ButtonGraphics):25 +Found:Related GlobalIntVar(ButtonGraphics):26 +Found:Related GlobalIntVar(ButtonGraphics):27 +Found:Related GlobalIntVar(ButtonGraphics):28 +Found:Related GlobalIntVar(ButtonGraphics):29 +Found:Related GlobalIntVar(ButtonGraphics):30 +Found:Related GlobalIntVar(ButtonGraphics):31 +Found:Related GlobalIntVar(ButtonGraphics):32 +Found:Related GlobalIntVar(ButtonGraphics):33 +Found:Related GlobalIntVar(ButtonGraphics):34 +Found:Related GlobalIntVar(ButtonGraphics):35 +Found:Related GlobalIntVar(ButtonGraphics):36 +Found:Related GlobalIntVar(ButtonGraphics):37 +Found:Related GlobalIntVar(ButtonGraphics):38 +Found:Related GlobalIntVar(ButtonGraphics):39 +Found:Related GlobalIntVar(ButtonGraphics):212 +Found:Related config:1042 +Found:Related config:1043 +Found:Related GlobalStringVar(InfoString):203 +Found:Related GlobalIntVar(ButtonGraphics):729 +Found:Related GlobalIntVar(ButtonGraphics):697 +Found:Indirect-related BITconfig:ID:259, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:259, bitoffs:7, length:13 +Hidden child:38 +Hidden child:39 +Hidden child:40 +Hidden child:46 +INTERFACE:336 +INTERFACE:337 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:338 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:339 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:340 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:341 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:342 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:343 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:344 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:345 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:346 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:347 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:348 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:349 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:350 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:351 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:352 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:353 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:354 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:355 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:356 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:357 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:358 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:359 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:360 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:361 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:362 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:363 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:5 +INTERFACE:364 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:5 +INTERFACE:365 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:14 +INTERFACE:366 +Found:Related config:391 +INTERFACE:367 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:368 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:369 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:370 +Found:Indirect-related config:294 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:371 +Found:Related config:406 +INTERFACE:372 +INTERFACE:373 +Found:Related config:560 +INTERFACE:374 +INTERFACE:375 +INTERFACE:376 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:10 +INTERFACE:377 +Found:Related BITconfig:ID:535, bitoffs:2, length:11 +INTERFACE:378 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +INTERFACE:379 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:380 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:381 +Found:Related BITconfig:ID:1410, bitoffs:0, length:5 +Hidden child:3 +Hidden child:6 +INTERFACE:382 +Found:Indirect-related BITconfig:ID:1045, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1045, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1045, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1045, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1045, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1045, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1045, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1045, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1045, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1045, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1046, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1046, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1046, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1046, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1046, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1046, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1046, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1046, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1046, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1045, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1047, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1047, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1047, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1047, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1047, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1047, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1047, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1047, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1501, bitoffs:0, length:2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:31 +INTERFACE:383 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:6 +Hidden child:9 +Hidden child:12 +Hidden child:15 +Hidden child:18 +INTERFACE:384 +Found:Related BITconfig:ID:425, bitoffs:1, length:2 +INTERFACE:385 +INTERFACE:386 +INTERFACE:387 +INTERFACE:388 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Indirect-related BITconfig:ID:1734, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:2387, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:2387, bitoffs:26, length:31 +Hidden child:17 +Hidden child:30 +Hidden child:43 +Hidden child:56 +Hidden child:69 +Hidden child:90 +Hidden child:107 +Hidden child:121 +Hidden child:135 +Hidden child:148 +Hidden child:163 +Hidden child:177 +Hidden child:191 +Hidden child:205 +INTERFACE:389 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:0 +INTERFACE:390 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:3 +INTERFACE:391 +Found:Related config:1888 +Found:Related BITconfig:ID:730, bitoffs:0, length:9 +Found:Related BITconfig:ID:362, bitoffs:0, length:26 +Found:Related BITconfig:ID:363, bitoffs:8, length:11 +Found:Related BITconfig:ID:363, bitoffs:12, length:15 +Found:Related BITconfig:ID:363, bitoffs:4, length:7 +Found:Related BITconfig:ID:363, bitoffs:0, length:3 +Found:Related BITconfig:ID:729, bitoffs:0, length:3 +Found:Related BITconfig:ID:729, bitoffs:4, length:7 +Found:Related BITconfig:ID:729, bitoffs:10, length:10 +Found:Related BITconfig:ID:729, bitoffs:8, length:9 +Found:Related BITconfig:ID:362, bitoffs:27, length:27 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:22 +Hidden child:24 +Hidden child:28 +Hidden child:32 +INTERFACE:392 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:393 +INTERFACE:394 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related config:1485 +Found:Related config:1486 +Found:Related config:1487 +Found:Related config:1488 +Found:Related config:1489 +Found:Related config:1490 +Found:Related config:1491 +INTERFACE:395 +INTERFACE:396 +Found:Related config:1485 +Found:Related config:1486 +Found:Related config:1487 +Found:Related config:1488 +Found:Related config:1489 +Found:Related config:1490 +Found:Related config:1491 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:397 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:398 +Found:Related BITconfig:ID:740, bitoffs:10, length:10 +Found:Related GlobalIntVar(ButtonGraphics):944 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related BITconfig:ID:738, bitoffs:29, length:29 +INTERFACE:399 +INTERFACE:400 +Found:Related GlobalIntVar(ButtonGraphics):943 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:401 +Found:Related GlobalStringVar(InfoString):220 +Found:Related GlobalStringVar(InfoString):221 +Found:Related GlobalStringVar(InfoString):222 +Found:Related GlobalStringVar(InfoString):223 +INTERFACE:402 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:403 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:50 +INTERFACE:404 +INTERFACE:405 +INTERFACE:406 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +INTERFACE:407 +INTERFACE:408 +INTERFACE:409 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:410 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:411 +INTERFACE:412 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:413 +Found:Related BITconfig:ID:425, bitoffs:1, length:2 +INTERFACE:414 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:415 +Found:Related GlobalIntVar(ButtonGraphics):219 +Found:Related GlobalIntVar(ButtonGraphics):218 +Found:Related GlobalIntVar(ButtonGraphics):220 +Found:Related GlobalIntVar(ButtonGraphics):228 +Found:Related GlobalIntVar(ButtonGraphics):229 +Found:Related GlobalIntVar(ButtonGraphics):230 +Found:Related GlobalIntVar(ButtonGraphics):223 +Found:Related GlobalIntVar(ButtonGraphics):224 +Found:Related GlobalIntVar(ButtonGraphics):226 +Found:Related GlobalIntVar(ButtonGraphics):227 +Found:Related GlobalIntVar(ButtonGraphics):225 +Found:Related GlobalIntVar(ButtonGraphics):221 +Found:Related GlobalIntVar(ButtonGraphics):222 +Found:Related GlobalIntVar(ButtonGraphics):231 +Hidden child:7 +Hidden child:8 +Hidden child:9 +Hidden child:21 +Hidden child:23 +Hidden child:25 +Hidden child:27 +Hidden child:29 +INTERFACE:416 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:5 +Hidden child:6 +Hidden child:7 +INTERFACE:417 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:418 +INTERFACE:419 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:24 +Hidden child:25 +Hidden child:26 +Hidden child:30 +Hidden child:36 +Hidden child:41 +Hidden child:46 +Hidden child:51 +Hidden child:56 +Hidden child:62 +Hidden child:68 +Hidden child:73 +Hidden child:78 +Hidden child:83 +Hidden child:91 +Hidden child:96 +Hidden child:101 +Hidden child:107 +Hidden child:112 +Hidden child:117 +Hidden child:122 +Hidden child:127 +Hidden child:132 +Hidden child:137 +Hidden child:142 +Hidden child:148 +Hidden child:153 +Hidden child:158 +Hidden child:163 +Hidden child:168 +Hidden child:173 +INTERFACE:420 +Found:Indirect-related BITconfig:ID:805, bitoffs:0, length:2 +Found:Indirect-related BITconfig:ID:805, bitoffs:3, length:5 +Found:Indirect-related BITconfig:ID:805, bitoffs:6, length:8 +Found:Indirect-related BITconfig:ID:805, bitoffs:9, length:11 +Found:Indirect-related BITconfig:ID:805, bitoffs:12, length:14 +Found:Indirect-related BITconfig:ID:805, bitoffs:15, length:17 +Found:Indirect-related BITconfig:ID:805, bitoffs:18, length:20 +Found:Indirect-related BITconfig:ID:805, bitoffs:21, length:23 +Found:Related GlobalIntVar(ButtonGraphics):681 +Found:Related GlobalIntVar(ButtonGraphics):684 +Found:Related GlobalIntVar(ButtonGraphics):687 +Found:Related GlobalIntVar(ButtonGraphics):690 +Found:Related GlobalIntVar(ButtonGraphics):680 +Found:Related GlobalIntVar(ButtonGraphics):682 +Found:Related GlobalIntVar(ButtonGraphics):683 +Found:Related GlobalIntVar(ButtonGraphics):685 +Found:Related GlobalIntVar(ButtonGraphics):686 +Found:Related GlobalIntVar(ButtonGraphics):688 +Found:Related GlobalIntVar(ButtonGraphics):689 +Found:Related GlobalIntVar(ButtonGraphics):691 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:421 +INTERFACE:422 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:77 +Hidden child:79 +Hidden child:81 +Hidden child:83 +Hidden child:85 +Hidden child:87 +Hidden child:89 +Hidden child:91 +Hidden child:93 +Hidden child:95 +Hidden child:97 +Hidden child:99 +Hidden child:101 +Hidden child:103 +Hidden child:105 +Hidden child:107 +Hidden child:109 +Hidden child:111 +Hidden child:113 +Hidden child:115 +Hidden child:117 +Hidden child:119 +Hidden child:121 +Hidden child:123 +Hidden child:125 +Hidden child:127 +Hidden child:129 +Hidden child:131 +Hidden child:133 +Hidden child:135 +INTERFACE:423 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:424 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:425 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:426 +INTERFACE:427 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:428 +Found:Related BITconfig:ID:822, bitoffs:9, length:12 +Found:Related BITconfig:ID:822, bitoffs:0, length:8 +Found:Related BITconfig:ID:821, bitoffs:22, length:31 +INTERFACE:429 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:16 +Hidden child:20 +Hidden child:26 +Hidden child:34 +Hidden child:50 +INTERFACE:430 +Found:Related BITconfig:ID:1376, bitoffs:9, length:9 +Found:Related BITconfig:ID:1376, bitoffs:12, length:12 +Found:Related BITconfig:ID:1376, bitoffs:11, length:11 +Found:Related BITconfig:ID:1376, bitoffs:10, length:10 +Found:Related BITconfig:ID:1376, bitoffs:13, length:13 +Found:Related BITconfig:ID:1376, bitoffs:14, length:14 +Found:Related BITconfig:ID:1376, bitoffs:15, length:15 +Found:Related BITconfig:ID:1376, bitoffs:16, length:16 +Found:Related BITconfig:ID:1376, bitoffs:17, length:17 +Found:Related BITconfig:ID:1376, bitoffs:21, length:21 +Found:Related BITconfig:ID:1376, bitoffs:24, length:24 +Found:Related BITconfig:ID:1376, bitoffs:23, length:23 +Found:Related BITconfig:ID:1376, bitoffs:22, length:22 +Found:Related GlobalIntVar(ButtonGraphics):988 +Found:Related GlobalIntVar(ButtonGraphics):989 +Found:Related GlobalIntVar(ButtonGraphics):990 +Found:Related GlobalIntVar(ButtonGraphics):991 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Related BITconfig:ID:439, bitoffs:0, length:1 +Found:Related GlobalIntVar(ButtonGraphics):631 +Found:Indirect-related BITconfig:ID:1376, bitoffs:0, length:2 +Found:Indirect-related BITconfig:ID:1376, bitoffs:3, length:5 +Found:Indirect-related BITconfig:ID:1376, bitoffs:6, length:8 +Found:Indirect-related BITconfig:ID:1376, bitoffs:18, length:20 +Found:Indirect-related BITconfig:ID:108, bitoffs:1, length:31 +Found:Indirect-related BITconfig:ID:1510, bitoffs:5, length:13 +Found:Indirect-related BITconfig:ID:108, bitoffs:0, length:0 +Found:Related BITconfig:ID:439, bitoffs:8, length:8 +Found:Related GlobalIntVar(ButtonGraphics):993 +Found:Indirect-related config:1092 +Found:Indirect-related BITconfig:ID:2089, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1087, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1209, bitoffs:6, length:7 +Found:Indirect-related BITconfig:ID:1331, bitoffs:0, length:2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1334 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1335 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1402 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1403 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1234 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1235 +Found:Related BITconfig:ID:2375, bitoffs:30, length:30 +Found:Related BITconfig:ID:2375, bitoffs:29, length:29 +Hidden child:78 +Hidden child:79 +INTERFACE:431 +INTERFACE:432 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related config:1092 +Found:Related BITconfig:ID:1087, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1209, bitoffs:6, length:7 +Found:Indirect-related BITconfig:ID:1331, bitoffs:0, length:2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1334 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1335 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1402 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1403 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1234 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1235 +INTERFACE:433 +Found:Related BITconfig:ID:834, bitoffs:0, length:7 +Found:Related BITconfig:ID:834, bitoffs:8, length:15 +Found:Related BITconfig:ID:835, bitoffs:0, length:7 +Found:Related BITconfig:ID:835, bitoffs:8, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:434 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:13 +Hidden child:24 +Hidden child:33 +Hidden child:46 +Hidden child:53 +INTERFACE:435 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:11 +Hidden child:20 +Hidden child:33 +Hidden child:40 +INTERFACE:436 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:15 +Hidden child:22 +Hidden child:31 +Hidden child:40 +Hidden child:49 +Hidden child:60 +Hidden child:73 +INTERFACE:437 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:9 +Hidden child:16 +Hidden child:25 +Hidden child:32 +INTERFACE:438 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related config:1093 +Found:Related BITconfig:ID:1087, bitoffs:2, length:2 +Hidden child:19 +Hidden child:26 +Hidden child:33 +Hidden child:40 +Hidden child:47 +Hidden child:55 +Hidden child:62 +Hidden child:69 +Hidden child:77 +INTERFACE:439 +INTERFACE:440 +Found:Related GlobalStringVar(InfoString):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:441 +Found:Related GlobalStringVar(InfoString):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:442 +Found:Related config:856 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:443 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:444 +Found:Related GlobalStringVar(InfoString):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:445 +INTERFACE:446 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:46 +INTERFACE:447 +Found:Related BITconfig:ID:2215, bitoffs:0, length:4 +Found:Related GlobalIntVar(ButtonGraphics):1537 +Found:Related GlobalIntVar(ButtonGraphics):1538 +Found:Related GlobalIntVar(ButtonGraphics):1539 +Hidden child:14 +Hidden child:15 +INTERFACE:448 +INTERFACE:449 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Related GlobalIntVar(ButtonGraphics):10 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related config:1109 +Found:Indirect-related config:1111 +Found:Indirect-related config:1110 +Found:Indirect-related GlobalIntVar(ButtonGraphics):742 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1241 +Found:Indirect-related GlobalIntVar(ButtonGraphics):743 +Found:Indirect-related GlobalIntVar(ButtonGraphics):744 +Found:Indirect-related GlobalIntVar(ButtonGraphics):741 +Found:Indirect-related GlobalStringVar(InfoString):25 +Found:Indirect-related GlobalStringVar(InfoString):26 +Found:Indirect-related GlobalStringVar(InfoString):34 +Found:Indirect-related GlobalStringVar(InfoString):35 +Found:Indirect-related GlobalStringVar(InfoString):36 +Found:Indirect-related GlobalStringVar(InfoString):52 +Found:Indirect-related GlobalIntVar(ButtonGraphics):746 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1242 +Found:Indirect-related BITconfig:ID:678, bitoffs:11, length:20 +Found:Indirect-related BITconfig:ID:1023, bitoffs:15, length:16 +Found:Indirect-related BITconfig:ID:1181, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:705, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:678, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:997, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:2051, bitoffs:0, length:8 +Found:Indirect-related config:281 +Found:Indirect-related config:130 +Found:Indirect-related config:29 +Found:Indirect-related config:31 +Found:Indirect-related config:176 +Found:Indirect-related config:32 +Found:Indirect-related config:160 +Found:Indirect-related config:122 +Found:Indirect-related config:71 +Found:Indirect-related config:273 +Found:Indirect-related config:107 +Found:Indirect-related config:63 +Found:Indirect-related config:145 +Found:Indirect-related config:146 +Found:Indirect-related config:293 +Found:Indirect-related config:68 +Found:Indirect-related config:655 +Found:Indirect-related config:10 +Found:Indirect-related config:399 +Found:Indirect-related config:314 +Found:Indirect-related config:131 +Found:Indirect-related config:80 +Found:Indirect-related config:0 +Found:Indirect-related config:335 +Found:Indirect-related config:299 +Found:Indirect-related config:148 +Found:Indirect-related config:17 +Found:Indirect-related config:11 +Found:Indirect-related config:347 +Found:Indirect-related config:65 +Found:Indirect-related config:180 +Found:Indirect-related config:150 +Found:Indirect-related config:382 +Found:Indirect-related config:223 +Found:Indirect-related config:188 +Found:Indirect-related config:5 +Found:Indirect-related config:387 +Found:Indirect-related config:175 +Found:Indirect-related config:139 +Found:Indirect-related config:147 +Found:Indirect-related config:14 +Found:Indirect-related config:365 +Found:Indirect-related config:30 +Found:Indirect-related config:517 +Found:Indirect-related config:192 +Found:Indirect-related config:307 +Found:Indirect-related config:112 +Found:Indirect-related config:416 +Found:Indirect-related config:165 +Found:Indirect-related config:302 +Found:Indirect-related config:328 +Found:Indirect-related config:402 +Found:Indirect-related config:600 +Found:Indirect-related config:76 +Found:Indirect-related config:159 +Found:Indirect-related config:339 +Found:Indirect-related config:60 +Found:Indirect-related config:116 +Found:Indirect-related config:320 +Found:Indirect-related config:26 +Found:Indirect-related config:359 +Found:Indirect-related config:197 +Found:Indirect-related config:226 +Found:Indirect-related config:111 +Found:Indirect-related config:200 +Found:Indirect-related config:385 +Found:Indirect-related config:317 +Found:Indirect-related config:161 +Found:Indirect-related config:162 +Found:Indirect-related config:212 +Found:Indirect-related config:980 +Found:Indirect-related BITconfig:ID:222, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:62, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:178, bitoffs:0, length:1 +Found:Indirect-related BITconfig:ID:939, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:433, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:964, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:455, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:400, bitoffs:23, length:23 +Found:Indirect-related BITconfig:ID:869, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:794, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:440, bitoffs:0, length:14 +Found:Indirect-related BITconfig:ID:622, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:934, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:896, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:641, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:912, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:844, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:671, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:810, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:435, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:521, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:553, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:408, bitoffs:28, length:31 +Found:Indirect-related BITconfig:ID:482, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:437, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:635, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:351, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:445, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:465, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:823, bitoffs:0, length:19 +Found:Indirect-related BITconfig:ID:604, bitoffs:0, length:2 +Found:Indirect-related BITconfig:ID:423, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:574, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:905, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:714, bitoffs:0, length:2 +Found:Indirect-related BITconfig:ID:607, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:496, bitoffs:0, length:2 +Found:Indirect-related BITconfig:ID:730, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:874, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:602, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:709, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:616, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:723, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:568, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:449, bitoffs:0, length:1 +Found:Indirect-related BITconfig:ID:571, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:968, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:970, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:977, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:992, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:994, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:1003, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1016, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1049, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1063, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:1077, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1094, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1165, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:1178, bitoffs:1, length:10 +Found:Indirect-related BITconfig:ID:1184, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:1190, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1204, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1218, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:1225, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1227, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1232, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1236, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:1271, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:1274, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1282, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:1306, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1311, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1330, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:1370, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1365, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:1403, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1407, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:1415, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1475, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1577, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:1420, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1390, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1327, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:714, bitoffs:3, length:6 +Found:Indirect-related BITconfig:ID:1819, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:1498, bitoffs:0, length:15 +Found:Indirect-related BITconfig:ID:1558, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:1600, bitoffs:0, length:3 +Found:Indirect-related BITconfig:ID:1588, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1610, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1811, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1849, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1646, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1844, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1834, bitoffs:28, length:31 +Found:Indirect-related BITconfig:ID:1861, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:2037, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1906, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1889, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:2217, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:2020, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:2046, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:2079, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:2208, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:2234, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:2376, bitoffs:0, length:7 +Found:Indirect-related config:322 +Hidden child:15 +INTERFACE:450 +INTERFACE:451 +Hidden child:7 +INTERFACE:452 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:453 +INTERFACE:454 +INTERFACE:455 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:456 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:457 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:458 +Hidden child:9 +INTERFACE:459 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related GlobalIntVar(ButtonGraphics):1404 +Found:Related GlobalIntVar(ButtonGraphics):1405 +INTERFACE:460 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:2 +Hidden child:4 +Hidden child:6 +Hidden child:8 +Hidden child:10 +Hidden child:12 +Hidden child:14 +Hidden child:17 +INTERFACE:461 +Hidden child:5 +Hidden child:6 +Hidden child:7 +Hidden child:8 +Hidden child:9 +INTERFACE:462 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +INTERFACE:463 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:464 +Found:Related BITconfig:ID:802, bitoffs:0, length:0 +Found:Related BITconfig:ID:802, bitoffs:1, length:1 +Found:Related BITconfig:ID:802, bitoffs:2, length:2 +Found:Related BITconfig:ID:802, bitoffs:3, length:3 +Found:Related BITconfig:ID:465, bitoffs:0, length:10 +Found:Related BITconfig:ID:313, bitoffs:0, length:0 +Found:Related BITconfig:ID:313, bitoffs:1, length:1 +Found:Related BITconfig:ID:313, bitoffs:2, length:2 +Found:Related BITconfig:ID:313, bitoffs:3, length:3 +Found:Related BITconfig:ID:313, bitoffs:4, length:4 +Found:Related BITconfig:ID:313, bitoffs:5, length:5 +Found:Related BITconfig:ID:313, bitoffs:6, length:6 +Found:Related BITconfig:ID:313, bitoffs:7, length:7 +Found:Related BITconfig:ID:313, bitoffs:8, length:8 +Found:Related BITconfig:ID:1085, bitoffs:0, length:3 +Found:Related BITconfig:ID:313, bitoffs:9, length:9 +Found:Related BITconfig:ID:313, bitoffs:10, length:10 +Found:Related BITconfig:ID:313, bitoffs:11, length:11 +Found:Related BITconfig:ID:313, bitoffs:12, length:12 +Found:Related BITconfig:ID:313, bitoffs:13, length:13 +Found:Related BITconfig:ID:313, bitoffs:15, length:15 +Found:Related BITconfig:ID:313, bitoffs:14, length:14 +Found:Related BITconfig:ID:1404, bitoffs:0, length:6 +Found:Related BITconfig:ID:1669, bitoffs:0, length:5 +Found:Related BITconfig:ID:1597, bitoffs:24, length:24 +Found:Related BITconfig:ID:1842, bitoffs:5, length:5 +Found:Related BITconfig:ID:1921, bitoffs:0, length:4 +Found:Related BITconfig:ID:2033, bitoffs:26, length:26 +Found:Related BITconfig:ID:1958, bitoffs:0, length:11 +Found:Related BITconfig:ID:2169, bitoffs:18, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +INTERFACE:465 +INTERFACE:466 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:467 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:77 +Hidden child:79 +Hidden child:81 +Hidden child:83 +Hidden child:85 +Hidden child:87 +Hidden child:89 +Hidden child:91 +Hidden child:93 +Hidden child:95 +Hidden child:97 +Hidden child:99 +Hidden child:101 +Hidden child:103 +Hidden child:105 +Hidden child:107 +Hidden child:109 +Hidden child:111 +Hidden child:113 +Hidden child:115 +Hidden child:117 +Hidden child:119 +Hidden child:121 +Hidden child:123 +Hidden child:125 +Hidden child:127 +Hidden child:129 +Hidden child:131 +Hidden child:133 +Hidden child:135 +INTERFACE:468 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:469 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:12 +Hidden child:20 +Hidden child:21 +Hidden child:22 +Hidden child:23 +Hidden child:24 +Hidden child:25 +INTERFACE:470 +INTERFACE:471 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Related BITconfig:ID:913, bitoffs:0, length:3 +Found:Related BITconfig:ID:913, bitoffs:4, length:7 +INTERFACE:472 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:4 +INTERFACE:473 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related BITconfig:ID:946, bitoffs:28, length:30 +Found:Related BITconfig:ID:947, bitoffs:9, length:17 +Found:Related BITconfig:ID:947, bitoffs:0, length:2 +Found:Related BITconfig:ID:948, bitoffs:19, length:27 +Found:Related BITconfig:ID:947, bitoffs:3, length:5 +Found:Related BITconfig:ID:948, bitoffs:0, length:8 +Found:Related BITconfig:ID:947, bitoffs:6, length:8 +Found:Related BITconfig:ID:948, bitoffs:9, length:18 +Found:Related BITconfig:ID:945, bitoffs:29, length:29 +Found:Related BITconfig:ID:1605, bitoffs:26, length:26 +Found:Related BITconfig:ID:1605, bitoffs:28, length:28 +Found:Related BITconfig:ID:1605, bitoffs:25, length:25 +Found:Related BITconfig:ID:1605, bitoffs:27, length:27 +Hidden child:37 +Hidden child:39 +Hidden child:131 +Hidden child:176 +Hidden child:222 +Hidden child:225 +INTERFACE:474 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:10 +INTERFACE:475 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1281 +Found:Related GlobalIntVar(ButtonGraphics):1069 +Found:Related GlobalIntVar(ButtonGraphics):1070 +Found:Related GlobalIntVar(ButtonGraphics):1071 +Found:Related GlobalIntVar(ButtonGraphics):1072 +Found:Related GlobalIntVar(ButtonGraphics):1073 +Found:Related GlobalIntVar(ButtonGraphics):1074 +Found:Related GlobalIntVar(ButtonGraphics):1282 +Found:Related GlobalIntVar(ButtonGraphics):1075 +Found:Related GlobalIntVar(ButtonGraphics):1076 +Hidden child:2 +Hidden child:7 +Hidden child:33 +Hidden child:54 +Hidden child:56 +Hidden child:58 +Hidden child:100 +INTERFACE:476 +Found:Related BITconfig:ID:1633, bitoffs:6, length:21 +Found:Related GlobalIntVar(ButtonGraphics):1078 +Found:Related GlobalIntVar(ButtonGraphics):1086 +Found:Related BITconfig:ID:1629, bitoffs:2, length:5 +Found:Related GlobalIntVar(ButtonGraphics):1079 +Found:Related config:1632 +Found:Related GlobalIntVar(ButtonGraphics):1080 +Found:Related GlobalIntVar(ButtonGraphics):1081 +Found:Related GlobalIntVar(ButtonGraphics):1082 +Found:Related GlobalIntVar(ButtonGraphics):1083 +Found:Related GlobalIntVar(ButtonGraphics):1084 +Found:Related GlobalIntVar(ButtonGraphics):1085 +Found:Related BITconfig:ID:1628, bitoffs:0, length:5 +Hidden child:2 +Hidden child:3 +Hidden child:4 +Hidden child:17 +Hidden child:58 +INTERFACE:477 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:478 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:479 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:480 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:21 +Hidden child:22 +Hidden child:23 +Hidden child:24 +Hidden child:25 +Hidden child:26 +Hidden child:27 +Hidden child:28 +Hidden child:29 +INTERFACE:481 +Found:Related GlobalIntVar(ButtonGraphics):1494 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Related BITconfig:ID:2077, bitoffs:0, length:3 +Hidden child:23 +Hidden child:37 +Hidden child:51 +Hidden child:65 +Hidden child:79 +INTERFACE:482 +INTERFACE:483 +INTERFACE:484 +INTERFACE:485 +INTERFACE:486 +INTERFACE:487 +INTERFACE:488 +Found:Related GlobalStringVar(InfoString):212 +Found:Related GlobalStringVar(InfoString):213 +Found:Related GlobalStringVar(InfoString):214 +Found:Related GlobalStringVar(InfoString):215 +Found:Related GlobalStringVar(InfoString):216 +Hidden child:5 +Hidden child:10 +Hidden child:15 +Hidden child:20 +INTERFACE:489 +Hidden child:12 +Hidden child:13 +Hidden child:14 +Hidden child:15 +Hidden child:16 +INTERFACE:490 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:491 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:492 +Found:Related GlobalStringVar(InfoString):212 +Found:Related GlobalStringVar(InfoString):213 +Found:Related GlobalStringVar(InfoString):214 +Found:Related GlobalStringVar(InfoString):215 +Found:Related GlobalStringVar(InfoString):216 +INTERFACE:493 +Found:Related GlobalStringVar(InfoString):212 +Found:Related GlobalStringVar(InfoString):213 +Found:Related GlobalStringVar(InfoString):214 +Found:Related GlobalStringVar(InfoString):215 +Found:Related GlobalStringVar(InfoString):216 +Hidden child:19 +Hidden child:20 +Hidden child:52 +Hidden child:53 +Hidden child:54 +INTERFACE:494 +INTERFACE:495 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:8 +Hidden child:9 +Hidden child:10 +Hidden child:21 +Hidden child:22 +Hidden child:23 +Hidden child:34 +Hidden child:35 +Hidden child:36 +Hidden child:47 +Hidden child:48 +Hidden child:49 +Hidden child:55 +INTERFACE:496 +Found:Related BITconfig:ID:948, bitoffs:28, length:31 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:497 +Hidden child:61 +Hidden child:62 +Hidden child:72 +Hidden child:84 +INTERFACE:498 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:4 +INTERFACE:499 +Found:Indirect-related BITconfig:ID:965, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:965, bitoffs:10, length:14 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:500 +Found:Related GlobalIntVar(ButtonGraphics):1548 +Hidden child:0 +Hidden child:1 +Hidden child:10 +Hidden child:51 +INTERFACE:501 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:8 +Hidden child:9 +Hidden child:10 +Hidden child:11 +Hidden child:12 +INTERFACE:502 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:8 +Hidden child:9 +Hidden child:10 +Hidden child:11 +Hidden child:12 +INTERFACE:503 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:504 +Hidden child:1 +INTERFACE:505 +INTERFACE:506 +INTERFACE:507 +INTERFACE:508 +Hidden child:9 +Hidden child:11 +Hidden child:13 +Hidden child:15 +Hidden child:17 +Hidden child:19 +Hidden child:21 +Hidden child:23 +Hidden child:25 +Hidden child:27 +Hidden child:29 +Hidden child:31 +Hidden child:33 +Hidden child:35 +INTERFACE:509 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:3 +Hidden child:4 +Hidden child:6 +Hidden child:7 +Hidden child:10 +Hidden child:12 +Hidden child:14 +Hidden child:20 +Hidden child:22 +Hidden child:26 +Hidden child:28 +INTERFACE:510 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:6 +Hidden child:11 +Hidden child:27 +Hidden child:29 +Hidden child:31 +Hidden child:33 +Hidden child:35 +Hidden child:37 +Hidden child:38 +Hidden child:40 +Hidden child:41 +Hidden child:43 +Hidden child:44 +Hidden child:46 +Hidden child:47 +Hidden child:50 +Hidden child:52 +Hidden child:53 +Hidden child:55 +Hidden child:57 +Hidden child:60 +Hidden child:64 +Hidden child:66 +Hidden child:68 +Hidden child:70 +Hidden child:74 +Hidden child:75 +Hidden child:76 +Hidden child:77 +Hidden child:78 +Hidden child:81 +Hidden child:90 +Hidden child:91 +Hidden child:94 +Hidden child:95 +INTERFACE:511 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:11 +Hidden child:16 +Hidden child:18 +Hidden child:20 +Hidden child:22 +INTERFACE:512 +INTERFACE:513 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related BITconfig:ID:1935, bitoffs:0, length:4 +Found:Related BITconfig:ID:1935, bitoffs:5, length:9 +Found:Related BITconfig:ID:1935, bitoffs:20, length:24 +Found:Related BITconfig:ID:1935, bitoffs:15, length:19 +Found:Related BITconfig:ID:1935, bitoffs:25, length:29 +Found:Related BITconfig:ID:1935, bitoffs:10, length:14 +INTERFACE:514 +INTERFACE:515 +INTERFACE:516 +INTERFACE:517 +INTERFACE:518 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +INTERFACE:519 +INTERFACE:520 +Hidden child:0 +Hidden child:2 +Hidden child:4 +Hidden child:6 +Hidden child:8 +Hidden child:10 +Hidden child:12 +Hidden child:14 +Hidden child:16 +Hidden child:18 +INTERFACE:521 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:15 +Hidden child:72 +Hidden child:74 +Hidden child:76 +INTERFACE:522 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:7 +INTERFACE:523 +Found:Related GlobalStringVar(InfoString):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:524 +Found:Related GlobalIntVar(ButtonGraphics):1007 +Hidden child:1 +INTERFACE:525 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:526 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:527 +INTERFACE:528 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:529 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:530 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:5 +INTERFACE:531 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:532 +Found:Related BITconfig:ID:1010, bitoffs:0, length:10 +INTERFACE:533 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:26 +Hidden child:27 +INTERFACE:534 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:65 +INTERFACE:535 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:3 +Hidden child:22 +Hidden child:23 +INTERFACE:536 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:537 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:538 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:539 +INTERFACE:540 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related GlobalIntVar(ButtonGraphics):1087 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Hidden child:21 +Hidden child:23 +Hidden child:25 +Hidden child:27 +Hidden child:28 +Hidden child:29 +Hidden child:30 +Hidden child:31 +Hidden child:60 +Hidden child:61 +Hidden child:62 +Hidden child:63 +INTERFACE:541 +INTERFACE:542 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1452 +INTERFACE:543 +INTERFACE:544 +INTERFACE:545 +INTERFACE:546 +INTERFACE:547 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:548 +Found:Related BITconfig:ID:1644, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1243 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1244 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1245 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1246 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1247 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1248 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1249 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1250 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1251 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1252 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1253 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1254 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1255 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1256 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1257 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1258 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1259 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1260 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1261 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1262 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1263 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1264 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1265 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1266 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1267 +Found:Indirect-related config:1878 +Found:Indirect-related BITconfig:ID:1644, bitoffs:1, length:31 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:1255, bitoffs:0, length:1 +Found:Related GlobalIntVar(ButtonGraphics):173 +Found:Related GlobalStringVar(InfoString):148 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Related GlobalIntVar(ButtonGraphics):616 +Found:Related GlobalIntVar(ButtonGraphics):1 +Found:Indirect-related config:2044 +Found:Related config:1801 +Found:Related GlobalIntVar(ButtonGraphics):1602 +Found:Related GlobalIntVar(ButtonGraphics):1427 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Related GlobalIntVar(ButtonGraphics):10 +Found:Related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related GlobalIntVar(ButtonGraphics):232 +Found:Indirect-related GlobalIntVar(ButtonGraphics):822 +Found:Indirect-related GlobalIntVar(ButtonGraphics):233 +Found:Indirect-related GlobalIntVar(ButtonGraphics):234 +Found:Indirect-related GlobalIntVar(ButtonGraphics):235 +Found:Indirect-related GlobalIntVar(ButtonGraphics):236 +Found:Indirect-related GlobalIntVar(ButtonGraphics):237 +Found:Indirect-related GlobalIntVar(ButtonGraphics):238 +Found:Indirect-related GlobalIntVar(ButtonGraphics):823 +Found:Indirect-related GlobalIntVar(ButtonGraphics):240 +Found:Indirect-related GlobalIntVar(ButtonGraphics):241 +Found:Indirect-related GlobalIntVar(ButtonGraphics):242 +Found:Indirect-related GlobalIntVar(ButtonGraphics):243 +Found:Indirect-related GlobalIntVar(ButtonGraphics):244 +Found:Indirect-related GlobalIntVar(ButtonGraphics):245 +Found:Indirect-related GlobalIntVar(ButtonGraphics):824 +Found:Indirect-related BITconfig:ID:1021, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Related config:1159 +Found:Related BITconfig:ID:638, bitoffs:30, length:31 +Found:Related GlobalIntVar(ButtonGraphics):814 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1034 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1027 +Found:Indirect-related GlobalStringVar(InfoString):202 +Hidden child:1 +Hidden child:12 +Hidden child:13 +Hidden child:15 +Hidden child:19 +Hidden child:21 +Hidden child:23 +Hidden child:39 +Hidden child:41 +Hidden child:53 +Hidden child:68 +Hidden child:106 +Hidden child:114 +Hidden child:162 +Hidden child:188 +Hidden child:190 +Hidden child:193 +Hidden child:195 +Hidden child:199 +Hidden child:201 +Hidden child:202 +Hidden child:203 +Hidden child:204 +Hidden child:205 +Hidden child:206 +Hidden child:208 +Hidden child:209 +Hidden child:210 +Hidden child:211 +Hidden child:212 +Hidden child:213 +Hidden child:214 +Hidden child:215 +Hidden child:216 +Hidden child:217 +Hidden child:218 +Hidden child:219 +Hidden child:220 +Hidden child:221 +Hidden child:236 +Hidden child:239 +INTERFACE:549 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:15 +INTERFACE:550 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1036 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1029 +Found:Indirect-related GlobalStringVar(InfoString):22 +Found:Related GlobalIntVar(ButtonGraphics):1413 +Found:Related GlobalIntVar(ButtonGraphics):11 +Found:Related GlobalIntVar(ButtonGraphics):5 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related config:287 +Found:Indirect-related config:1054 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Hidden child:0 +Hidden child:2 +Hidden child:7 +Hidden child:10 +Hidden child:14 +Hidden child:30 +Hidden child:46 +Hidden child:50 +INTERFACE:551 +Found:Related BITconfig:ID:2216, bitoffs:4, length:13 +Found:Related GlobalIntVar(ButtonGraphics):1549 +Found:Related GlobalIntVar(ButtonGraphics):1550 +Found:Related GlobalIntVar(ButtonGraphics):1551 +Found:Related GlobalIntVar(ButtonGraphics):1552 +Hidden child:18 +Hidden child:19 +Hidden child:20 +Hidden child:23 +Hidden child:44 +Hidden child:45 +Hidden child:46 +Hidden child:58 +Hidden child:59 +Hidden child:60 +Hidden child:72 +Hidden child:73 +Hidden child:74 +INTERFACE:552 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:553 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:1 +Hidden child:3 +Hidden child:5 +Hidden child:7 +Hidden child:9 +Hidden child:11 +Hidden child:13 +Hidden child:15 +Hidden child:17 +Hidden child:19 +Hidden child:21 +Hidden child:23 +Hidden child:25 +Hidden child:27 +Hidden child:29 +Hidden child:31 +Hidden child:33 +Hidden child:35 +Hidden child:37 +Hidden child:39 +Hidden child:41 +Hidden child:43 +Hidden child:45 +Hidden child:47 +Hidden child:49 +Hidden child:51 +Hidden child:53 +Hidden child:55 +Hidden child:57 +Hidden child:59 +INTERFACE:554 +INTERFACE:555 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:0 +Hidden child:1 +Hidden child:48 +INTERFACE:556 +INTERFACE:557 +Hidden child:9 +INTERFACE:558 +Found:Related GlobalIntVar(ButtonGraphics):769 +INTERFACE:559 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related BITconfig:ID:1037, bitoffs:0, length:0 +Found:Related BITconfig:ID:1037, bitoffs:1, length:1 +Found:Related BITconfig:ID:1037, bitoffs:2, length:2 +Found:Related BITconfig:ID:1037, bitoffs:3, length:3 +Found:Related BITconfig:ID:1037, bitoffs:4, length:4 +Found:Related BITconfig:ID:1037, bitoffs:5, length:5 +Found:Related BITconfig:ID:1037, bitoffs:6, length:6 +Found:Related BITconfig:ID:1037, bitoffs:7, length:7 +Found:Related BITconfig:ID:1037, bitoffs:8, length:8 +Found:Related BITconfig:ID:1037, bitoffs:9, length:9 +Found:Related BITconfig:ID:1037, bitoffs:10, length:10 +Found:Related BITconfig:ID:1037, bitoffs:11, length:11 +Found:Related BITconfig:ID:1037, bitoffs:12, length:12 +Found:Related BITconfig:ID:1037, bitoffs:13, length:13 +Found:Related BITconfig:ID:1037, bitoffs:14, length:14 +INTERFACE:560 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1045, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1045, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1045, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1045, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1045, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1045, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1045, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1045, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1045, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1045, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1046, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1046, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1046, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1046, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1046, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1046, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1046, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1046, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1046, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1045, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1047, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1047, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1047, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1047, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1047, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1047, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1047, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1047, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1501, bitoffs:0, length:2 +Hidden child:21 +INTERFACE:561 +Found:Related GlobalStringVar(InfoString):343 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:562 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1045, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1045, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1045, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1045, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1045, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1045, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1045, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1045, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1045, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1045, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1046, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1046, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1046, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1046, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1046, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1046, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1046, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1046, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1046, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1045, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1047, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1047, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1047, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1047, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1047, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1047, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1047, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1047, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1501, bitoffs:0, length:2 +Hidden child:21 +INTERFACE:563 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1045, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1045, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1045, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1045, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1045, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1045, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1045, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1045, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1045, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1045, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1046, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1046, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1046, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1046, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1046, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1046, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1046, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1046, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1046, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1045, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1047, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1047, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1047, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1047, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1047, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1047, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1047, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1047, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1501, bitoffs:0, length:2 +Hidden child:21 +INTERFACE:564 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1045, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1045, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1045, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1045, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1045, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1045, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1045, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1045, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1045, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1045, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1046, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1046, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1046, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1046, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1046, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1046, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1046, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1046, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1046, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1045, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1047, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1047, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1047, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1047, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1047, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1047, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1047, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1047, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1501, bitoffs:0, length:2 +Hidden child:21 +INTERFACE:565 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1045, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1045, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1045, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1045, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1045, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1045, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1045, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1045, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1045, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1045, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1046, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1046, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1046, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1046, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1046, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1046, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1046, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1046, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1046, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1045, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1047, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1047, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1047, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1047, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1047, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1047, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1047, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1047, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1501, bitoffs:0, length:2 +Hidden child:21 +INTERFACE:566 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1045, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1045, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1045, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1045, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1045, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1045, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1045, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1045, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1045, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1045, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1046, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1046, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1046, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1046, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1046, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1046, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1046, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1046, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1046, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1045, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1047, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1047, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1047, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1047, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1047, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1047, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1047, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1047, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1501, bitoffs:0, length:2 +Hidden child:21 +INTERFACE:567 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1045, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1045, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1045, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1045, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1045, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1045, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1045, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1045, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1045, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1045, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1046, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1046, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1046, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1046, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1046, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1046, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1046, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1046, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1046, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1045, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1047, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1047, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1047, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1047, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1047, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1047, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1047, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1047, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1501, bitoffs:0, length:2 +Hidden child:21 +INTERFACE:568 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1045, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1045, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1045, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1045, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1045, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1045, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1045, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1045, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1045, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1045, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1046, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1046, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1046, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1046, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1046, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1046, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1046, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1046, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1046, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1045, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1047, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1047, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1047, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1047, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1047, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1047, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1047, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1047, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1501, bitoffs:0, length:2 +Hidden child:21 +INTERFACE:569 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1045, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1045, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1045, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1045, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1045, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1045, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1045, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1045, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1045, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1045, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1046, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1046, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1046, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1046, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1046, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1046, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1046, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1046, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1046, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1045, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1047, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1047, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1047, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1047, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1047, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1047, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1047, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1047, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1501, bitoffs:0, length:2 +Hidden child:21 +INTERFACE:570 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1045, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1045, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1045, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1045, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1045, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1045, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1045, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1045, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1045, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1045, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1046, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1046, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1046, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1046, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1046, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1046, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1046, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1046, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1046, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1045, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1047, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1047, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1047, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1047, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1047, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1047, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1047, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1047, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1501, bitoffs:0, length:2 +Hidden child:21 +INTERFACE:571 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1045, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1045, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1045, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1045, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1045, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1045, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1045, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1045, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1045, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1045, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1046, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1046, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1046, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1046, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1046, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1046, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1046, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1046, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1046, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1045, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1047, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1047, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1047, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1047, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1047, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1047, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1047, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1047, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1501, bitoffs:0, length:2 +Hidden child:21 +INTERFACE:572 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1045, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1045, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1045, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1045, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1045, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1045, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1045, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1045, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1045, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1045, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1046, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1046, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1046, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1046, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1046, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1046, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1046, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1046, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1046, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1045, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1047, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1047, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1047, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1047, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1047, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1047, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1047, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1047, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1501, bitoffs:0, length:2 +Hidden child:21 +INTERFACE:573 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1045, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1045, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1045, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1045, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1045, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1045, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1045, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1045, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1045, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1045, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1046, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1046, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1046, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1046, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1046, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1046, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1046, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1046, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1046, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1045, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1047, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1047, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1047, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1047, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1047, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1047, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1047, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1047, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1501, bitoffs:0, length:2 +Hidden child:21 +INTERFACE:574 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1045, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1045, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1045, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1045, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1045, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1045, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1045, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1045, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1045, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1045, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1046, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1046, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1046, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1046, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1046, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1046, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1046, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1046, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1046, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1045, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1047, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1047, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1047, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1047, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1047, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1047, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1047, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1047, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1501, bitoffs:0, length:2 +Hidden child:21 +INTERFACE:575 +Found:Indirect-related BITconfig:ID:1283, bitoffs:0, length:2 +Found:Indirect-related BITconfig:ID:1283, bitoffs:3, length:5 +Found:Indirect-related BITconfig:ID:1283, bitoffs:6, length:8 +Found:Indirect-related BITconfig:ID:1283, bitoffs:9, length:11 +Found:Indirect-related BITconfig:ID:1283, bitoffs:12, length:14 +Found:Indirect-related BITconfig:ID:1283, bitoffs:15, length:17 +Found:Indirect-related BITconfig:ID:1283, bitoffs:18, length:20 +Found:Indirect-related BITconfig:ID:1283, bitoffs:21, length:23 +Found:Indirect-related BITconfig:ID:1283, bitoffs:24, length:26 +Found:Indirect-related BITconfig:ID:1288, bitoffs:0, length:2 +Found:Indirect-related BITconfig:ID:1288, bitoffs:3, length:5 +Found:Indirect-related BITconfig:ID:1288, bitoffs:6, length:8 +Found:Indirect-related BITconfig:ID:1288, bitoffs:9, length:11 +Found:Indirect-related BITconfig:ID:1288, bitoffs:12, length:14 +Found:Related BITconfig:ID:1283, bitoffs:28, length:31 +Found:Related BITconfig:ID:1282, bitoffs:17, length:17 +Found:Related BITconfig:ID:1282, bitoffs:18, length:18 +Found:Related BITconfig:ID:1282, bitoffs:19, length:19 +Found:Related BITconfig:ID:1282, bitoffs:20, length:20 +Found:Related BITconfig:ID:1282, bitoffs:21, length:21 +Found:Related BITconfig:ID:1282, bitoffs:22, length:22 +Found:Related BITconfig:ID:1282, bitoffs:23, length:23 +Found:Related BITconfig:ID:1282, bitoffs:24, length:24 +Found:Related BITconfig:ID:1282, bitoffs:25, length:25 +Found:Related BITconfig:ID:1282, bitoffs:26, length:26 +Found:Related BITconfig:ID:1282, bitoffs:27, length:27 +Found:Related BITconfig:ID:1282, bitoffs:28, length:28 +Found:Related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:17 +Hidden child:18 +Hidden child:19 +Hidden child:20 +Hidden child:21 +Hidden child:22 +Hidden child:23 +Hidden child:24 +Hidden child:25 +Hidden child:26 +Hidden child:27 +Hidden child:28 +Hidden child:29 +Hidden child:30 +INTERFACE:576 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1045, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1045, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1045, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1045, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1045, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1045, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1045, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1045, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1045, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1045, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1046, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1046, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1046, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1046, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1046, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1046, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1046, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1046, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1046, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1045, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1047, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1047, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1047, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1047, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1047, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1047, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1047, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1047, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1501, bitoffs:0, length:2 +Hidden child:21 +INTERFACE:577 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1045, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1045, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1045, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1045, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1045, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1045, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1045, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1045, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1045, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1045, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1046, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1046, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1046, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1046, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1046, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1046, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1046, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1046, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1046, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1045, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1047, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1047, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1047, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1047, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1047, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1047, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1047, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1047, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1501, bitoffs:0, length:2 +Hidden child:21 +INTERFACE:578 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1045, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1045, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1045, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1045, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1045, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1045, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1045, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1045, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1045, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1045, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1046, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1046, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1046, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1046, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1046, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1046, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1046, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1046, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1046, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1045, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1047, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1047, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1047, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1047, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1047, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1047, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1047, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1047, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1501, bitoffs:0, length:2 +Hidden child:21 +INTERFACE:579 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1045, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1045, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1045, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1045, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1045, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1045, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1045, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1045, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1045, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1045, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1046, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1046, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1046, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1046, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1046, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1046, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1046, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1046, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1046, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1045, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1047, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1047, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1047, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1047, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1047, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1047, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1047, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1047, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1501, bitoffs:0, length:2 +Hidden child:21 +INTERFACE:580 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1045, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1045, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1045, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1045, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1045, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1045, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1045, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1045, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1045, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1045, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1046, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1046, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1046, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1046, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1046, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1046, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1046, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1046, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1046, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1045, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1047, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1047, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1047, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1047, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1047, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1047, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1047, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1047, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1501, bitoffs:0, length:2 +Hidden child:21 +INTERFACE:581 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1045, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1045, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1045, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1045, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1045, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1045, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1045, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1045, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1045, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1045, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1046, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1046, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1046, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1046, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1046, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1046, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1046, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1046, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1046, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1045, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1047, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1047, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1047, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1047, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1047, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1047, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1047, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1047, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1501, bitoffs:0, length:2 +Hidden child:19 +INTERFACE:582 +Found:Related GlobalIntVar(ButtonGraphics):769 +INTERFACE:583 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1045, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1045, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1045, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1045, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1045, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1045, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1045, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1045, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1045, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1045, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1046, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1046, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1046, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1046, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1046, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1046, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1046, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1046, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1046, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1045, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1047, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1047, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1047, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1047, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1047, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1047, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1047, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1047, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1501, bitoffs:0, length:2 +INTERFACE:584 +INTERFACE:585 +INTERFACE:586 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:587 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:588 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related BITconfig:ID:1051, bitoffs:12, length:14 +Found:Related BITconfig:ID:1051, bitoffs:0, length:2 +Found:Related BITconfig:ID:1051, bitoffs:3, length:5 +Found:Related BITconfig:ID:1051, bitoffs:6, length:8 +Found:Related BITconfig:ID:1051, bitoffs:9, length:11 +INTERFACE:589 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Indirect-related GlobalIntVar(ButtonGraphics):6 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1094 +Found:Indirect-related GlobalStringVar(InfoString):279 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1097 +Found:Indirect-related GlobalStringVar(InfoString):277 +Found:Indirect-related GlobalStringVar(InfoString):278 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):349 +Hidden child:4 +Hidden child:28 +Hidden child:34 +Hidden child:50 +Hidden child:54 +INTERFACE:590 +Found:Indirect-related config:2230 +Found:Indirect-related BITconfig:ID:313, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:313, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:313, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:313, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:313, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:802, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:802, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:802, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:802, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:313, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:313, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:313, bitoffs:7, length:7 +Found:Indirect-related BITconfig:ID:313, bitoffs:8, length:8 +Found:Indirect-related BITconfig:ID:1085, bitoffs:0, length:3 +Found:Indirect-related BITconfig:ID:313, bitoffs:9, length:9 +Found:Indirect-related BITconfig:ID:313, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:313, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:313, bitoffs:12, length:12 +Found:Indirect-related BITconfig:ID:313, bitoffs:13, length:13 +Found:Indirect-related BITconfig:ID:313, bitoffs:15, length:15 +Found:Indirect-related BITconfig:ID:313, bitoffs:14, length:14 +Found:Indirect-related BITconfig:ID:1597, bitoffs:24, length:24 +Found:Indirect-related BITconfig:ID:1842, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1921, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:2033, bitoffs:26, length:26 +Found:Indirect-related BITconfig:ID:1958, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:465, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:1404, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:1669, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:2169, bitoffs:0, length:0 +Found:Related config:281 +Hidden child:12 +Hidden child:13 +Hidden child:15 +Hidden child:16 +Hidden child:17 +INTERFACE:591 +Found:Related BITconfig:ID:1410, bitoffs:0, length:5 +INTERFACE:592 +Found:Related BITconfig:ID:1018, bitoffs:22, length:24 +Found:Related BITconfig:ID:1018, bitoffs:12, length:12 +Found:Related BITconfig:ID:1018, bitoffs:25, length:31 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:593 +Hidden child:8 +Hidden child:45 +Hidden child:48 +Hidden child:57 +Hidden child:59 +Hidden child:97 +Hidden child:110 +INTERFACE:594 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):790 +Found:Indirect-related GlobalStringVar(InfoString):24 +Found:Related GlobalIntVar(ButtonGraphics):6 +Found:Indirect-related GlobalIntVar(ButtonGraphics):11 +Found:Indirect-related GlobalIntVar(ButtonGraphics):5 +Found:Indirect-related GlobalStringVar(InfoString):22 +Found:Related GlobalIntVar(ButtonGraphics):792 +Found:Related GlobalIntVar(ButtonGraphics):799 +Found:Related GlobalIntVar(ButtonGraphics):798 +Hidden child:8 +Hidden child:34 +Hidden child:49 +Hidden child:52 +Hidden child:62 +Hidden child:66 +Hidden child:104 +Hidden child:117 +Hidden child:120 +Hidden child:121 +Hidden child:148 +Hidden child:149 +Hidden child:150 +Hidden child:151 +Hidden child:165 +Hidden child:166 +Hidden child:210 +Hidden child:212 +INTERFACE:595 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:596 +Found:Related GlobalIntVar(ButtonGraphics):174 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1100 +Found:Indirect-related GlobalIntVar(ButtonGraphics):547 +Found:Indirect-related GlobalIntVar(ButtonGraphics):200 +Found:Indirect-related GlobalIntVar(ButtonGraphics):201 +Found:Indirect-related GlobalStringVar(InfoString):32 +Found:Indirect-related GlobalStringVar(InfoString):33 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1099 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1089 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1092 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1414 +Found:Indirect-related GlobalIntVar(ButtonGraphics):175 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1090 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1091 +Found:Indirect-related GlobalStringVar(InfoString):122 +Found:Indirect-related GlobalStringVar(InfoString):124 +Found:Indirect-related GlobalStringVar(InfoString):125 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1277 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1240 +Found:Indirect-related GlobalIntVar(ButtonGraphics):986 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1411 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1407 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1408 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1101 +Found:Indirect-related GlobalStringVar(InfoString):326 +Found:Indirect-related GlobalStringVar(InfoString):123 +Found:Indirect-related GlobalStringVar(InfoString):327 +Found:Indirect-related GlobalStringVar(InfoString):328 +Found:Indirect-related GlobalStringVar(InfoString):329 +Found:Indirect-related GlobalIntVar(ButtonGraphics):987 +Found:Indirect-related GlobalIntVar(ButtonGraphics):178 +Found:Related GlobalIntVar(ButtonGraphics):1088 +Hidden child:7 +Hidden child:9 +Hidden child:15 +Hidden child:63 +Hidden child:74 +Hidden child:80 +INTERFACE:597 +Found:Indirect-related BITconfig:ID:2040, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1048, bitoffs:19, length:30 +Found:Indirect-related BITconfig:ID:1058, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1048, bitoffs:7, length:18 +Found:Indirect-related BITconfig:ID:1058, bitoffs:12, length:23 +Found:Related GlobalIntVar(ButtonGraphics):1435 +INTERFACE:598 +Found:Indirect-related BITconfig:ID:2040, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1048, bitoffs:19, length:30 +Found:Indirect-related BITconfig:ID:1058, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1048, bitoffs:7, length:18 +Found:Indirect-related BITconfig:ID:1058, bitoffs:12, length:23 +Found:Related GlobalIntVar(ButtonGraphics):1435 +INTERFACE:599 +Found:Indirect-related BITconfig:ID:2040, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1048, bitoffs:19, length:30 +Found:Indirect-related BITconfig:ID:1058, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1048, bitoffs:7, length:18 +Found:Indirect-related BITconfig:ID:1058, bitoffs:12, length:23 +Found:Related GlobalIntVar(ButtonGraphics):1435 +INTERFACE:600 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1045, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1045, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1045, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1045, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1045, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1045, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1045, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1045, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1045, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1045, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1046, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1046, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1046, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1046, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1046, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1046, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1046, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1046, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1046, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1045, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1047, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1047, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1047, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1047, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1047, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1047, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1047, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1047, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1501, bitoffs:0, length:2 +Hidden child:21 +INTERFACE:601 +Found:Indirect-related BITconfig:ID:2040, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1048, bitoffs:19, length:30 +Found:Indirect-related BITconfig:ID:1058, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1048, bitoffs:7, length:18 +Found:Indirect-related BITconfig:ID:1058, bitoffs:12, length:23 +Found:Related GlobalIntVar(ButtonGraphics):1435 +INTERFACE:602 +INTERFACE:603 +INTERFACE:604 +INTERFACE:605 +Found:Related GlobalIntVar(ButtonGraphics):51 +INTERFACE:606 +INTERFACE:607 +INTERFACE:608 +INTERFACE:609 +INTERFACE:610 +Found:Related GlobalIntVar(ButtonGraphics):51 +INTERFACE:611 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:612 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:613 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Related config:1068 +Found:Related config:1069 +Found:Related config:1070 +Found:Related config:1065 +Found:Related config:1066 +Found:Related config:1067 +Found:Related config:856 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:14 +INTERFACE:614 +INTERFACE:615 +Found:Related GlobalIntVar(ButtonGraphics):51 +Found:Related GlobalIntVar(ButtonGraphics):50 +Found:Related GlobalIntVar(ButtonGraphics):52 +INTERFACE:616 +INTERFACE:617 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:618 +INTERFACE:619 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Hidden child:45 +Hidden child:46 +Hidden child:47 +Hidden child:48 +Hidden child:49 +Hidden child:50 +Hidden child:51 +Hidden child:52 +Hidden child:53 +Hidden child:54 +Hidden child:55 +Hidden child:56 +Hidden child:57 +Hidden child:58 +INTERFACE:620 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Indirect-related config:532 +Found:Related config:118 +Found:Related config:1496 +Found:Indirect-related BITconfig:ID:678, bitoffs:11, length:20 +Found:Indirect-related BITconfig:ID:1023, bitoffs:15, length:16 +Found:Indirect-related BITconfig:ID:1181, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:705, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:678, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:997, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:2051, bitoffs:0, length:8 +Found:Indirect-related config:130 +Found:Indirect-related config:29 +Found:Indirect-related config:31 +Found:Indirect-related config:176 +Found:Indirect-related config:32 +Found:Indirect-related config:160 +Found:Indirect-related config:122 +Found:Indirect-related config:71 +Found:Indirect-related config:273 +Found:Indirect-related config:107 +Found:Indirect-related config:63 +Found:Indirect-related config:145 +Found:Indirect-related config:146 +Found:Indirect-related config:293 +Found:Indirect-related config:68 +Found:Indirect-related config:655 +Found:Indirect-related config:10 +Found:Indirect-related config:399 +Found:Indirect-related config:314 +Found:Indirect-related config:131 +Found:Indirect-related config:80 +Found:Indirect-related config:0 +Found:Indirect-related config:335 +Found:Indirect-related config:299 +Found:Indirect-related config:148 +Found:Indirect-related config:17 +Found:Indirect-related config:11 +Found:Indirect-related config:347 +Found:Indirect-related config:65 +Found:Indirect-related config:180 +Found:Indirect-related config:150 +Found:Indirect-related config:382 +Found:Indirect-related config:223 +Found:Indirect-related config:188 +Found:Indirect-related config:5 +Found:Indirect-related config:387 +Found:Indirect-related config:175 +Found:Indirect-related config:139 +Found:Indirect-related config:147 +Found:Indirect-related config:14 +Found:Indirect-related config:365 +Found:Indirect-related config:30 +Found:Indirect-related config:517 +Found:Indirect-related config:192 +Found:Indirect-related config:307 +Found:Indirect-related config:112 +Found:Indirect-related config:416 +Found:Indirect-related config:165 +Found:Indirect-related config:302 +Found:Indirect-related config:328 +Found:Indirect-related config:402 +Found:Indirect-related config:600 +Found:Indirect-related config:76 +Found:Indirect-related config:159 +Found:Indirect-related config:339 +Found:Indirect-related config:60 +Found:Indirect-related config:116 +Found:Indirect-related config:320 +Found:Indirect-related config:26 +Found:Indirect-related config:359 +Found:Indirect-related config:197 +Found:Indirect-related config:226 +Found:Indirect-related config:111 +Found:Indirect-related config:200 +Found:Indirect-related config:385 +Found:Indirect-related config:317 +Found:Indirect-related config:161 +Found:Indirect-related config:162 +Found:Indirect-related config:212 +Found:Indirect-related config:980 +Found:Indirect-related BITconfig:ID:222, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:62, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:178, bitoffs:0, length:1 +Found:Indirect-related BITconfig:ID:939, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:433, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:964, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:455, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:400, bitoffs:23, length:23 +Found:Indirect-related BITconfig:ID:869, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:794, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:440, bitoffs:0, length:14 +Found:Indirect-related BITconfig:ID:622, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:934, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:896, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:641, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:912, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:844, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:671, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:810, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:435, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:521, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:553, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:408, bitoffs:28, length:31 +Found:Indirect-related BITconfig:ID:482, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:437, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:635, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:351, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:445, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:465, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:823, bitoffs:0, length:19 +Found:Indirect-related BITconfig:ID:604, bitoffs:0, length:2 +Found:Indirect-related BITconfig:ID:423, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:574, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:905, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:714, bitoffs:0, length:2 +Found:Indirect-related BITconfig:ID:607, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:496, bitoffs:0, length:2 +Found:Indirect-related BITconfig:ID:730, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:874, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:602, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:709, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:616, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:723, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:568, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:449, bitoffs:0, length:1 +Found:Indirect-related BITconfig:ID:571, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:968, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:970, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:977, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:992, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:994, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:1003, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1016, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1049, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1063, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:1077, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1094, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1165, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:1178, bitoffs:1, length:10 +Found:Indirect-related BITconfig:ID:1184, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:1190, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1204, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1218, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:1225, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1227, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1232, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1236, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:1271, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:1274, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1282, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:1306, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1311, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1330, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:1370, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1365, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:1403, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1407, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:1415, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1475, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1577, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:1420, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1390, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1327, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:714, bitoffs:3, length:6 +Found:Indirect-related BITconfig:ID:1819, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:1498, bitoffs:0, length:15 +Found:Indirect-related BITconfig:ID:1558, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:1600, bitoffs:0, length:3 +Found:Indirect-related BITconfig:ID:1588, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1610, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1811, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1849, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1646, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1844, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1834, bitoffs:28, length:31 +Found:Indirect-related BITconfig:ID:1861, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:2037, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1906, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1889, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:2217, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:2020, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:2046, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:2079, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:2208, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:2234, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:2376, bitoffs:0, length:7 +Found:Indirect-related config:322 +Found:Indirect-related GlobalIntVar(ButtonGraphics):946 +Found:Indirect-related GlobalIntVar(ButtonGraphics):947 +Found:Indirect-related GlobalIntVar(ButtonGraphics):948 +Found:Indirect-related GlobalIntVar(ButtonGraphics):949 +Found:Indirect-related GlobalIntVar(ButtonGraphics):950 +Found:Indirect-related GlobalIntVar(ButtonGraphics):951 +Found:Indirect-related GlobalIntVar(ButtonGraphics):952 +Found:Indirect-related GlobalIntVar(ButtonGraphics):953 +Found:Indirect-related GlobalIntVar(ButtonGraphics):954 +Found:Indirect-related GlobalIntVar(ButtonGraphics):955 +Found:Indirect-related GlobalIntVar(ButtonGraphics):956 +Found:Indirect-related GlobalIntVar(ButtonGraphics):957 +Found:Indirect-related GlobalIntVar(ButtonGraphics):958 +Found:Indirect-related GlobalIntVar(ButtonGraphics):959 +Found:Indirect-related GlobalIntVar(ButtonGraphics):960 +Found:Indirect-related GlobalIntVar(ButtonGraphics):961 +Found:Indirect-related GlobalIntVar(ButtonGraphics):962 +Found:Indirect-related GlobalIntVar(ButtonGraphics):963 +Found:Indirect-related GlobalIntVar(ButtonGraphics):964 +Found:Indirect-related GlobalIntVar(ButtonGraphics):965 +Found:Indirect-related GlobalIntVar(ButtonGraphics):966 +Found:Indirect-related GlobalIntVar(ButtonGraphics):967 +Found:Indirect-related GlobalIntVar(ButtonGraphics):968 +Found:Indirect-related GlobalIntVar(ButtonGraphics):969 +Found:Indirect-related GlobalIntVar(ButtonGraphics):970 +Found:Indirect-related GlobalIntVar(ButtonGraphics):971 +Found:Indirect-related GlobalIntVar(ButtonGraphics):972 +Found:Indirect-related GlobalIntVar(ButtonGraphics):973 +Found:Indirect-related GlobalIntVar(ButtonGraphics):974 +Found:Indirect-related GlobalIntVar(ButtonGraphics):975 +Found:Indirect-related GlobalIntVar(ButtonGraphics):976 +Found:Indirect-related GlobalIntVar(ButtonGraphics):977 +Found:Indirect-related GlobalIntVar(ButtonGraphics):978 +Found:Indirect-related GlobalIntVar(ButtonGraphics):979 +Found:Indirect-related GlobalIntVar(ButtonGraphics):980 +Found:Indirect-related GlobalIntVar(ButtonGraphics):981 +Found:Indirect-related GlobalIntVar(ButtonGraphics):982 +Found:Indirect-related GlobalIntVar(ButtonGraphics):983 +Found:Indirect-related GlobalIntVar(ButtonGraphics):984 +Found:Indirect-related GlobalIntVar(ButtonGraphics):985 +Hidden child:19 +Hidden child:21 +Hidden child:22 +Hidden child:23 +Hidden child:27 +Hidden child:28 +Hidden child:29 +Hidden child:30 +Hidden child:31 +INTERFACE:621 +INTERFACE:622 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:6 +Hidden child:7 +Hidden child:8 +Hidden child:9 +INTERFACE:623 +INTERFACE:624 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related BITconfig:ID:1094, bitoffs:8, length:11 +Found:Related BITconfig:ID:1094, bitoffs:12, length:15 +Found:Related BITconfig:ID:1094, bitoffs:16, length:19 +Hidden child:35 +Hidden child:37 +Hidden child:39 +Hidden child:48 +Hidden child:50 +Hidden child:52 +Hidden child:54 +Hidden child:56 +Hidden child:58 +INTERFACE:625 +Found:Related BITconfig:ID:1095, bitoffs:11, length:13 +Found:Related GlobalIntVar(ButtonGraphics):773 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:626 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related BITconfig:ID:286, bitoffs:14, length:27 +Found:Related BITconfig:ID:286, bitoffs:9, length:9 +Found:Related BITconfig:ID:286, bitoffs:0, length:0 +Found:Related BITconfig:ID:286, bitoffs:1, length:1 +Found:Related BITconfig:ID:286, bitoffs:28, length:28 +Found:Related BITconfig:ID:286, bitoffs:4, length:4 +Found:Related BITconfig:ID:286, bitoffs:5, length:5 +Found:Related BITconfig:ID:286, bitoffs:6, length:6 +Found:Related BITconfig:ID:286, bitoffs:13, length:13 +Found:Related BITconfig:ID:286, bitoffs:12, length:12 +Found:Related BITconfig:ID:286, bitoffs:7, length:7 +Found:Related BITconfig:ID:286, bitoffs:8, length:8 +Found:Related BITconfig:ID:286, bitoffs:10, length:10 +Found:Related GlobalIntVar(ButtonGraphics):1453 +Found:Related GlobalIntVar(ButtonGraphics):1454 +Found:Related GlobalIntVar(ButtonGraphics):1464 +Found:Related GlobalIntVar(ButtonGraphics):1455 +Found:Related GlobalIntVar(ButtonGraphics):1456 +Found:Related GlobalIntVar(ButtonGraphics):1457 +Found:Related GlobalIntVar(ButtonGraphics):1463 +Found:Related GlobalIntVar(ButtonGraphics):1462 +Found:Related GlobalIntVar(ButtonGraphics):1458 +Found:Related GlobalIntVar(ButtonGraphics):1459 +Found:Related GlobalIntVar(ButtonGraphics):1460 +Found:Related GlobalIntVar(ButtonGraphics):1461 +Found:Related GlobalIntVar(ButtonGraphics):1465 +Found:Related GlobalIntVar(ButtonGraphics):1466 +Found:Related GlobalIntVar(ButtonGraphics):1467 +Found:Related GlobalIntVar(ButtonGraphics):740 +Found:Related GlobalIntVar(ButtonGraphics):745 +Found:Related GlobalIntVar(ButtonGraphics):780 +Found:Related GlobalIntVar(ButtonGraphics):781 +Found:Related GlobalIntVar(ButtonGraphics):782 +Found:Related GlobalIntVar(ButtonGraphics):789 +Found:Related GlobalIntVar(ButtonGraphics):1409 +Found:Related GlobalIntVar(ButtonGraphics):1410 +Hidden child:30 +Hidden child:34 +INTERFACE:627 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1045, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1045, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1045, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1045, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1045, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1045, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1045, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1045, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1045, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1045, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1046, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1046, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1046, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1046, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1046, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1046, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1046, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1046, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1046, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1045, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1047, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1047, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1047, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1047, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1047, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1047, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1047, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1047, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1501, bitoffs:0, length:2 +Hidden child:19 +INTERFACE:628 +INTERFACE:629 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:14 +Hidden child:27 +Hidden child:40 +Hidden child:53 +INTERFACE:630 +Found:Related config:856 +Found:Related config:849 +Found:Related BITconfig:ID:844, bitoffs:26, length:31 +Found:Related BITconfig:ID:848, bitoffs:0, length:5 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:631 +Found:Related GlobalIntVar(ButtonGraphics):12 +Found:Related GlobalIntVar(ButtonGraphics):13 +Found:Related GlobalIntVar(ButtonGraphics):14 +Found:Related GlobalIntVar(ButtonGraphics):15 +Found:Related GlobalIntVar(ButtonGraphics):16 +Found:Related GlobalIntVar(ButtonGraphics):17 +Found:Related GlobalIntVar(ButtonGraphics):18 +Found:Related GlobalIntVar(ButtonGraphics):19 +Found:Related GlobalIntVar(ButtonGraphics):20 +Found:Related GlobalIntVar(ButtonGraphics):21 +Found:Related GlobalIntVar(ButtonGraphics):22 +Found:Related GlobalIntVar(ButtonGraphics):23 +Found:Related GlobalIntVar(ButtonGraphics):24 +Found:Related GlobalIntVar(ButtonGraphics):25 +Found:Related GlobalIntVar(ButtonGraphics):26 +Found:Related GlobalIntVar(ButtonGraphics):27 +Found:Related GlobalIntVar(ButtonGraphics):28 +Found:Related GlobalIntVar(ButtonGraphics):29 +Found:Related GlobalIntVar(ButtonGraphics):30 +Found:Related GlobalIntVar(ButtonGraphics):31 +Found:Related GlobalIntVar(ButtonGraphics):32 +Found:Related GlobalIntVar(ButtonGraphics):33 +Found:Related GlobalIntVar(ButtonGraphics):34 +Found:Related GlobalIntVar(ButtonGraphics):35 +Found:Related GlobalIntVar(ButtonGraphics):36 +Found:Related GlobalIntVar(ButtonGraphics):37 +Found:Related GlobalIntVar(ButtonGraphics):38 +Found:Related GlobalIntVar(ButtonGraphics):39 +Found:Related GlobalIntVar(ButtonGraphics):212 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1465 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1466 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1467 +Found:Indirect-related GlobalIntVar(ButtonGraphics):740 +Found:Indirect-related GlobalIntVar(ButtonGraphics):745 +Found:Indirect-related GlobalIntVar(ButtonGraphics):780 +Found:Indirect-related GlobalIntVar(ButtonGraphics):781 +Found:Indirect-related GlobalIntVar(ButtonGraphics):782 +Found:Indirect-related GlobalIntVar(ButtonGraphics):789 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1409 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1410 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1453 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1454 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1455 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1456 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1457 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1458 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1459 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1460 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1461 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1462 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1463 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1464 +Found:Indirect-related BITconfig:ID:286, bitoffs:14, length:27 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related GlobalStringVar(InfoString):274 +Found:Indirect-related config:286 +INTERFACE:632 +Found:Related GlobalStringVar(InfoString):224 +Found:Related GlobalStringVar(InfoString):225 +Found:Related GlobalStringVar(InfoString):226 +Found:Related GlobalStringVar(InfoString):227 +Found:Related GlobalStringVar(InfoString):228 +Found:Related GlobalStringVar(InfoString):229 +Found:Related GlobalStringVar(InfoString):230 +Found:Related GlobalStringVar(InfoString):231 +Found:Related GlobalStringVar(InfoString):232 +Found:Related GlobalStringVar(InfoString):233 +Found:Related GlobalStringVar(InfoString):234 +Found:Related GlobalStringVar(InfoString):235 +Found:Related GlobalStringVar(InfoString):236 +Found:Related GlobalStringVar(InfoString):237 +Found:Related GlobalStringVar(InfoString):238 +Found:Related GlobalStringVar(InfoString):239 +Found:Related GlobalStringVar(InfoString):240 +Found:Related GlobalStringVar(InfoString):241 +Found:Related GlobalStringVar(InfoString):242 +Found:Related GlobalStringVar(InfoString):243 +Found:Related GlobalStringVar(InfoString):244 +Found:Related GlobalStringVar(InfoString):245 +Found:Related GlobalStringVar(InfoString):246 +Found:Related GlobalStringVar(InfoString):247 +Found:Related GlobalStringVar(InfoString):248 +Found:Related GlobalStringVar(InfoString):249 +Found:Related GlobalStringVar(InfoString):250 +Found:Related GlobalStringVar(InfoString):251 +Found:Related GlobalStringVar(InfoString):252 +Found:Related GlobalStringVar(InfoString):253 +Found:Related GlobalStringVar(InfoString):254 +Found:Related GlobalStringVar(InfoString):255 +Found:Related GlobalStringVar(InfoString):256 +Found:Related GlobalStringVar(InfoString):257 +Found:Related GlobalStringVar(InfoString):258 +Found:Related GlobalStringVar(InfoString):259 +Found:Related GlobalStringVar(InfoString):260 +Found:Related GlobalStringVar(InfoString):261 +Found:Related GlobalStringVar(InfoString):262 +Found:Related GlobalStringVar(InfoString):263 +Found:Related GlobalStringVar(InfoString):264 +Found:Related GlobalStringVar(InfoString):265 +Found:Related GlobalStringVar(InfoString):266 +Found:Related GlobalStringVar(InfoString):267 +Found:Related GlobalStringVar(InfoString):268 +Found:Related GlobalStringVar(InfoString):269 +Found:Related GlobalStringVar(InfoString):270 +Found:Related GlobalStringVar(InfoString):271 +Found:Related GlobalStringVar(InfoString):272 +Found:Related GlobalStringVar(InfoString):273 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:633 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related GlobalStringVar(InfoString):274 +Hidden child:26 +INTERFACE:634 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related GlobalStringVar(InfoString):274 +Hidden child:27 +INTERFACE:635 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Related BITconfig:ID:285, bitoffs:0, length:20 +Found:Related BITconfig:ID:1561, bitoffs:0, length:4 +Found:Related BITconfig:ID:286, bitoffs:7, length:12 +Found:Related BITconfig:ID:286, bitoffs:13, length:13 +Found:Related BITconfig:ID:286, bitoffs:14, length:14 +Found:Related BITconfig:ID:286, bitoffs:15, length:15 +Found:Related BITconfig:ID:286, bitoffs:16, length:16 +Found:Related BITconfig:ID:286, bitoffs:20, length:20 +Found:Related BITconfig:ID:286, bitoffs:21, length:21 +Found:Related BITconfig:ID:286, bitoffs:22, length:22 +Found:Related BITconfig:ID:286, bitoffs:17, length:17 +Found:Related BITconfig:ID:286, bitoffs:18, length:18 +Found:Related BITconfig:ID:286, bitoffs:19, length:19 +Found:Related BITconfig:ID:1561, bitoffs:5, length:7 +Found:Related config:1105 +Hidden child:2 +Hidden child:3 +Hidden child:4 +Hidden child:5 +Hidden child:6 +Hidden child:7 +Hidden child:8 +Hidden child:9 +Hidden child:10 +Hidden child:11 +INTERFACE:636 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:13 +Hidden child:25 +Hidden child:42 +Hidden child:56 +INTERFACE:637 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related GlobalStringVar(InfoString):274 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1465 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1466 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1467 +Found:Indirect-related GlobalIntVar(ButtonGraphics):740 +Found:Indirect-related GlobalIntVar(ButtonGraphics):745 +Found:Indirect-related GlobalIntVar(ButtonGraphics):780 +Found:Indirect-related GlobalIntVar(ButtonGraphics):781 +Found:Indirect-related GlobalIntVar(ButtonGraphics):782 +Found:Indirect-related GlobalIntVar(ButtonGraphics):789 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1409 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1410 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1453 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1454 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1455 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1456 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1457 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1458 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1459 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1460 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1461 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1462 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1463 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1464 +Found:Indirect-related config:286 +Found:Indirect-related BITconfig:ID:286, bitoffs:14, length:27 +INTERFACE:638 +INTERFACE:639 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related BITconfig:ID:286, bitoffs:14, length:27 +Found:Related BITconfig:ID:286, bitoffs:9, length:9 +Found:Related BITconfig:ID:286, bitoffs:0, length:0 +Found:Related BITconfig:ID:286, bitoffs:1, length:1 +Found:Related BITconfig:ID:286, bitoffs:28, length:28 +Found:Related BITconfig:ID:286, bitoffs:4, length:4 +Found:Related BITconfig:ID:286, bitoffs:5, length:5 +Found:Related BITconfig:ID:286, bitoffs:6, length:6 +Found:Related BITconfig:ID:286, bitoffs:13, length:13 +Found:Related BITconfig:ID:286, bitoffs:12, length:12 +Found:Related BITconfig:ID:286, bitoffs:7, length:7 +Found:Related BITconfig:ID:286, bitoffs:8, length:8 +Found:Related BITconfig:ID:286, bitoffs:10, length:10 +Found:Related GlobalIntVar(ButtonGraphics):1453 +Found:Related GlobalIntVar(ButtonGraphics):1454 +Found:Related GlobalIntVar(ButtonGraphics):1464 +Found:Related GlobalIntVar(ButtonGraphics):1455 +Found:Related GlobalIntVar(ButtonGraphics):1456 +Found:Related GlobalIntVar(ButtonGraphics):1457 +Found:Related GlobalIntVar(ButtonGraphics):1463 +Found:Related GlobalIntVar(ButtonGraphics):1462 +Found:Related GlobalIntVar(ButtonGraphics):1458 +Found:Related GlobalIntVar(ButtonGraphics):1459 +Found:Related GlobalIntVar(ButtonGraphics):1460 +Found:Related GlobalIntVar(ButtonGraphics):1461 +Found:Related GlobalIntVar(ButtonGraphics):1465 +Found:Related GlobalIntVar(ButtonGraphics):1466 +Found:Related GlobalIntVar(ButtonGraphics):1467 +Found:Related GlobalIntVar(ButtonGraphics):740 +Found:Related GlobalIntVar(ButtonGraphics):745 +Found:Related GlobalIntVar(ButtonGraphics):780 +Found:Related GlobalIntVar(ButtonGraphics):781 +Found:Related GlobalIntVar(ButtonGraphics):782 +Found:Related GlobalIntVar(ButtonGraphics):789 +Found:Related GlobalIntVar(ButtonGraphics):1409 +Found:Related GlobalIntVar(ButtonGraphics):1410 +Hidden child:18 +Hidden child:22 +INTERFACE:640 +Found:Related BITconfig:ID:283, bitoffs:26, length:29 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:641 +Found:Related config:1105 +Found:Related GlobalStringVar(InfoString):274 +Found:Related BITconfig:ID:286, bitoffs:7, length:12 +Found:Related BITconfig:ID:286, bitoffs:13, length:13 +Found:Related BITconfig:ID:286, bitoffs:14, length:14 +Found:Related BITconfig:ID:286, bitoffs:15, length:15 +Found:Related BITconfig:ID:286, bitoffs:16, length:16 +Found:Related BITconfig:ID:286, bitoffs:20, length:20 +Found:Related BITconfig:ID:286, bitoffs:21, length:21 +Found:Related BITconfig:ID:286, bitoffs:22, length:22 +Found:Related BITconfig:ID:286, bitoffs:17, length:17 +Found:Related BITconfig:ID:286, bitoffs:18, length:18 +Found:Related BITconfig:ID:286, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Hidden child:12 +Hidden child:13 +Hidden child:14 +Hidden child:15 +Hidden child:16 +Hidden child:17 +Hidden child:18 +Hidden child:19 +Hidden child:20 +Hidden child:21 +Hidden child:37 +INTERFACE:642 +Found:Related config:2243 +Found:Related config:2244 +Found:Related config:2245 +Hidden child:16 +Hidden child:19 +Hidden child:20 +Hidden child:22 +Hidden child:23 +Hidden child:57 +Hidden child:70 +Hidden child:81 +Hidden child:94 +Hidden child:113 +Hidden child:122 +Hidden child:139 +Hidden child:146 +Hidden child:149 +Hidden child:150 +Hidden child:151 +Hidden child:159 +Hidden child:193 +Hidden child:194 +Hidden child:202 +INTERFACE:643 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:644 +INTERFACE:645 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:646 +INTERFACE:647 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:648 +INTERFACE:649 +Found:Related GlobalIntVar(ButtonGraphics):269 +INTERFACE:650 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1045, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1045, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1045, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1045, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1045, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1045, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1045, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1045, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1045, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1045, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1046, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1046, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1046, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1046, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1046, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1046, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1046, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1046, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1046, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1045, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1047, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1047, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1047, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1047, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1047, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1047, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1047, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1047, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1501, bitoffs:0, length:2 +Hidden child:21 +INTERFACE:651 +INTERFACE:652 +Found:Indirect-related BITconfig:ID:1146, bitoffs:0, length:4 +Found:Related BITconfig:ID:1146, bitoffs:5, length:31 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:653 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related GlobalStringVar(InfoString):184 +Found:Related GlobalStringVar(InfoString):185 +Found:Related GlobalStringVar(InfoString):186 +Found:Related GlobalStringVar(InfoString):187 +Found:Related GlobalStringVar(InfoString):188 +Found:Related GlobalStringVar(InfoString):189 +Found:Related BITconfig:ID:1452, bitoffs:0, length:19 +INTERFACE:654 +Found:Related GlobalIntVar(ButtonGraphics):852 +Found:Related GlobalIntVar(ButtonGraphics):853 +Found:Related GlobalIntVar(ButtonGraphics):854 +Found:Related GlobalIntVar(ButtonGraphics):855 +Found:Related GlobalIntVar(ButtonGraphics):856 +Found:Related GlobalIntVar(ButtonGraphics):847 +Found:Related GlobalIntVar(ButtonGraphics):848 +Found:Related GlobalIntVar(ButtonGraphics):849 +Found:Related GlobalIntVar(ButtonGraphics):850 +Found:Related GlobalIntVar(ButtonGraphics):851 +Found:Related GlobalIntVar(ButtonGraphics):839 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1451, bitoffs:3, length:5 +Found:Indirect-related BITconfig:ID:1451, bitoffs:9, length:11 +Found:Indirect-related BITconfig:ID:1451, bitoffs:12, length:14 +Found:Indirect-related BITconfig:ID:1451, bitoffs:0, length:2 +Found:Indirect-related BITconfig:ID:1451, bitoffs:6, length:8 +Found:Indirect-related BITconfig:ID:1445, bitoffs:0, length:18 +INTERFACE:655 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1444, bitoffs:3, length:7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):838 +Found:Indirect-related GlobalIntVar(ButtonGraphics):882 +Found:Indirect-related GlobalIntVar(ButtonGraphics):887 +Found:Indirect-related GlobalIntVar(ButtonGraphics):892 +Found:Indirect-related GlobalIntVar(ButtonGraphics):897 +INTERFACE:656 +INTERFACE:657 +Found:Indirect-related GlobalIntVar(ButtonGraphics):840 +Found:Indirect-related config:1447 +Found:Related GlobalIntVar(ButtonGraphics):839 +Found:Related BITconfig:ID:1445, bitoffs:0, length:18 +Found:Related BITconfig:ID:1455, bitoffs:0, length:14 +INTERFACE:658 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:53 +INTERFACE:659 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:660 +INTERFACE:661 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:662 +Found:Indirect-related BITconfig:ID:1493, bitoffs:0, length:3 +Found:Related config:1174 +Found:Related config:448 +Found:Related BITconfig:ID:1160, bitoffs:25, length:31 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Related config:1177 +Found:Related BITconfig:ID:1176, bitoffs:7, length:31 +Found:Related BITconfig:ID:1176, bitoffs:6, length:6 +Found:Related BITconfig:ID:1175, bitoffs:9, length:16 +Found:Related BITconfig:ID:1175, bitoffs:1, length:8 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related GlobalStringVar(InfoString):204 +Found:Indirect-related GlobalStringVar(InfoString):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1436 +Found:Indirect-related BITconfig:ID:1175, bitoffs:23, length:27 +Found:Indirect-related BITconfig:ID:1209, bitoffs:6, length:7 +Found:Indirect-related BITconfig:ID:1331, bitoffs:0, length:2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1334 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1335 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1402 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1403 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1234 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1235 +Hidden child:71 +Hidden child:72 +INTERFACE:663 +Found:Indirect-related BITconfig:ID:569, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:569, bitoffs:5, length:9 +Found:Indirect-related BITconfig:ID:569, bitoffs:10, length:14 +Found:Indirect-related BITconfig:ID:569, bitoffs:15, length:19 +Found:Indirect-related BITconfig:ID:569, bitoffs:20, length:24 +Found:Indirect-related BITconfig:ID:569, bitoffs:25, length:29 +Found:Related config:1174 +Found:Related config:448 +Found:Related BITconfig:ID:569, bitoffs:30, length:30 +Found:Related BITconfig:ID:1160, bitoffs:25, length:31 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Related BITconfig:ID:1175, bitoffs:9, length:16 +Found:Related BITconfig:ID:1175, bitoffs:1, length:8 +INTERFACE:664 +Hidden child:25 +Hidden child:37 +Hidden child:56 +INTERFACE:665 +INTERFACE:666 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Related config:448 +INTERFACE:667 +Found:Indirect-related GlobalIntVar(ButtonGraphics):779 +Found:Indirect-related GlobalStringVar(InfoString):321 +Found:Indirect-related GlobalStringVar(InfoString):322 +Found:Indirect-related GlobalStringVar(InfoString):323 +Found:Indirect-related GlobalStringVar(InfoString):324 +Found:Indirect-related GlobalStringVar(InfoString):325 +Found:Related BITconfig:ID:1248, bitoffs:31, length:31 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related config:287 +Found:Indirect-related config:1054 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Hidden child:49 +Hidden child:52 +INTERFACE:668 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +INTERFACE:669 +Hidden child:13 +INTERFACE:670 +Hidden child:1 +INTERFACE:671 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +INTERFACE:672 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Related config:448 +INTERFACE:673 +Found:Related GlobalIntVar(ButtonGraphics):1411 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1100 +Found:Indirect-related GlobalIntVar(ButtonGraphics):547 +Found:Indirect-related GlobalIntVar(ButtonGraphics):174 +Found:Indirect-related GlobalIntVar(ButtonGraphics):200 +Found:Indirect-related GlobalIntVar(ButtonGraphics):201 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1089 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1092 +Found:Indirect-related GlobalIntVar(ButtonGraphics):175 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1090 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1091 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1099 +Found:Indirect-related GlobalStringVar(InfoString):122 +Found:Indirect-related GlobalStringVar(InfoString):32 +Found:Indirect-related GlobalStringVar(InfoString):124 +Found:Indirect-related GlobalStringVar(InfoString):33 +Found:Indirect-related GlobalStringVar(InfoString):125 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1277 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1240 +Found:Indirect-related GlobalIntVar(ButtonGraphics):986 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1407 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1408 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1101 +Found:Indirect-related GlobalStringVar(InfoString):326 +Found:Indirect-related GlobalStringVar(InfoString):123 +Found:Indirect-related GlobalStringVar(InfoString):327 +Found:Indirect-related GlobalStringVar(InfoString):328 +Found:Indirect-related GlobalStringVar(InfoString):329 +Found:Indirect-related GlobalIntVar(ButtonGraphics):987 +Found:Indirect-related GlobalIntVar(ButtonGraphics):178 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1414 +Hidden child:31 +Hidden child:58 +Hidden child:79 +Hidden child:82 +Hidden child:89 +Hidden child:92 +Hidden child:99 +Hidden child:101 +Hidden child:118 +Hidden child:121 +Hidden child:125 +Hidden child:127 +Hidden child:137 +Hidden child:138 +Hidden child:139 +Hidden child:140 +Hidden child:141 +INTERFACE:674 +Found:Related GlobalIntVar(ButtonGraphics):737 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:5 +Hidden child:11 +Hidden child:18 +INTERFACE:675 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:676 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1045, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1045, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1045, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1045, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1045, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1045, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1045, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1045, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1045, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1045, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1046, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1046, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1046, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1046, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1046, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1046, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1046, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1046, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1046, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1045, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1047, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1047, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1047, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1047, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1047, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1047, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1047, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1047, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1501, bitoffs:0, length:2 +Hidden child:21 +INTERFACE:677 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1045, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1045, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1045, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1045, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1045, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1045, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1045, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1045, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1045, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1045, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1046, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1046, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1046, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1046, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1046, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1046, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1046, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1046, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1046, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1045, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1047, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1047, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1047, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1047, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1047, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1047, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1047, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1047, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1501, bitoffs:0, length:2 +Hidden child:21 +INTERFACE:678 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1045, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1045, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1045, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1045, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1045, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1045, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1045, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1045, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1045, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1045, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1046, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1046, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1046, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1046, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1046, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1046, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1046, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1046, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1046, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1045, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1047, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1047, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1047, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1047, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1047, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1047, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1047, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1047, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1501, bitoffs:0, length:2 +Hidden child:21 +INTERFACE:679 +Found:Related GlobalIntVar(ButtonGraphics):1031 +Found:Indirect-related BITconfig:ID:1560, bitoffs:14, length:14 +INTERFACE:680 +Found:Related GlobalIntVar(ButtonGraphics):217 +Found:Related GlobalIntVar(ButtonGraphics):216 +Found:Related GlobalIntVar(ButtonGraphics):215 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:681 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Hidden child:9 +Hidden child:16 +Hidden child:17 +Hidden child:18 +Hidden child:19 +Hidden child:20 +Hidden child:21 +Hidden child:22 +Hidden child:23 +Hidden child:24 +Hidden child:25 +Hidden child:26 +Hidden child:27 +Hidden child:28 +Hidden child:29 +Hidden child:30 +Hidden child:31 +Hidden child:32 +Hidden child:33 +Hidden child:34 +Hidden child:35 +Hidden child:37 +Hidden child:38 +Hidden child:39 +Hidden child:40 +Hidden child:41 +Hidden child:42 +Hidden child:43 +Hidden child:44 +Hidden child:45 +Hidden child:46 +Hidden child:47 +Hidden child:48 +Hidden child:49 +Hidden child:50 +Hidden child:51 +Hidden child:52 +Hidden child:53 +Hidden child:54 +Hidden child:55 +Hidden child:107 +Hidden child:108 +Hidden child:109 +INTERFACE:682 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Hidden child:29 +Hidden child:31 +INTERFACE:683 +Found:Related BITconfig:ID:1190, bitoffs:7, length:10 +Found:Indirect-related BITconfig:ID:1190, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:1190, bitoffs:22, length:22 +Found:Indirect-related BITconfig:ID:1190, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1191, bitoffs:12, length:12 +Found:Indirect-related BITconfig:ID:1191, bitoffs:23, length:23 +Found:Indirect-related BITconfig:ID:1192, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1192, bitoffs:13, length:13 +Found:Indirect-related BITconfig:ID:1192, bitoffs:24, length:24 +Found:Indirect-related BITconfig:ID:1192, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1193, bitoffs:14, length:14 +Found:Indirect-related BITconfig:ID:1193, bitoffs:25, length:25 +Found:Indirect-related BITconfig:ID:1190, bitoffs:12, length:15 +Found:Indirect-related BITconfig:ID:1190, bitoffs:23, length:26 +Found:Indirect-related BITconfig:ID:1191, bitoffs:2, length:5 +Found:Indirect-related BITconfig:ID:1191, bitoffs:13, length:16 +Found:Indirect-related BITconfig:ID:1191, bitoffs:24, length:27 +Found:Indirect-related BITconfig:ID:1192, bitoffs:3, length:6 +Found:Indirect-related BITconfig:ID:1192, bitoffs:14, length:17 +Found:Indirect-related BITconfig:ID:1192, bitoffs:25, length:28 +Found:Indirect-related BITconfig:ID:1193, bitoffs:4, length:7 +Found:Indirect-related BITconfig:ID:1193, bitoffs:15, length:18 +Found:Indirect-related BITconfig:ID:1190, bitoffs:16, length:19 +Found:Indirect-related BITconfig:ID:1190, bitoffs:27, length:30 +Found:Indirect-related BITconfig:ID:1191, bitoffs:6, length:9 +Found:Indirect-related BITconfig:ID:1191, bitoffs:17, length:20 +Found:Indirect-related BITconfig:ID:1191, bitoffs:28, length:31 +Found:Indirect-related BITconfig:ID:1192, bitoffs:7, length:10 +Found:Indirect-related BITconfig:ID:1192, bitoffs:18, length:21 +Found:Indirect-related BITconfig:ID:1193, bitoffs:0, length:3 +Found:Indirect-related BITconfig:ID:1193, bitoffs:8, length:11 +Found:Indirect-related BITconfig:ID:1193, bitoffs:19, length:22 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Hidden child:24 +Hidden child:25 +Hidden child:26 +Hidden child:27 +Hidden child:28 +Hidden child:29 +Hidden child:30 +Hidden child:31 +Hidden child:32 +Hidden child:33 +Hidden child:43 +INTERFACE:684 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:685 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:686 +Found:Indirect-related BITconfig:ID:1195, bitoffs:6, length:31 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:7 +Hidden child:9 +INTERFACE:687 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:688 +Found:Related BITconfig:ID:1195, bitoffs:6, length:31 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:689 +Found:Related BITconfig:ID:1195, bitoffs:6, length:31 +INTERFACE:690 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:691 +INTERFACE:692 +INTERFACE:693 +INTERFACE:694 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:15 +Hidden child:16 +Hidden child:40 +INTERFACE:695 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:696 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:20 +Hidden child:31 +Hidden child:34 +INTERFACE:697 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:26 +Hidden child:37 +Hidden child:40 +Hidden child:43 +INTERFACE:698 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:699 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:20 +Hidden child:31 +Hidden child:34 +INTERFACE:700 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:701 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:702 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:703 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:704 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:26 +Hidden child:37 +Hidden child:40 +Hidden child:43 +INTERFACE:705 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:26 +Hidden child:37 +Hidden child:40 +Hidden child:43 +INTERFACE:706 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:707 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:20 +Hidden child:31 +Hidden child:35 +INTERFACE:708 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:29 +Hidden child:40 +Hidden child:43 +INTERFACE:709 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:18 +INTERFACE:710 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:20 +Hidden child:31 +Hidden child:34 +INTERFACE:711 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:712 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:6 +INTERFACE:713 +INTERFACE:714 +Hidden child:0 +Hidden child:2 +Hidden child:4 +Hidden child:6 +INTERFACE:715 +Found:Related BITconfig:ID:1010, bitoffs:0, length:10 +Found:Related BITconfig:ID:2250, bitoffs:4, length:20 +INTERFACE:716 +Found:Related GlobalIntVar(ButtonGraphics):116 +Found:Related GlobalIntVar(ButtonGraphics):117 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Hidden child:39 +INTERFACE:717 +Found:Indirect-related BITconfig:ID:1201, bitoffs:22, length:25 +Found:Indirect-related BITconfig:ID:1201, bitoffs:18, length:21 +Found:Related BITconfig:ID:1205, bitoffs:18, length:22 +Found:Related BITconfig:ID:1205, bitoffs:0, length:7 +Found:Related GlobalIntVar(ButtonGraphics):111 +Found:Related GlobalIntVar(ButtonGraphics):112 +Found:Related GlobalIntVar(ButtonGraphics):114 +Found:Related GlobalIntVar(ButtonGraphics):113 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:21 +Hidden child:33 +Hidden child:35 +INTERFACE:718 +INTERFACE:719 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:720 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:721 +Found:Related BITconfig:ID:1201, bitoffs:28, length:28 +Found:Related GlobalIntVar(ButtonGraphics):118 +INTERFACE:722 +INTERFACE:723 +Found:Related BITconfig:ID:1407, bitoffs:0, length:9 +Found:Related BITconfig:ID:1415, bitoffs:0, length:5 +Found:Related BITconfig:ID:1475, bitoffs:0, length:7 +Found:Related BITconfig:ID:1577, bitoffs:0, length:6 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:724 +INTERFACE:725 +Found:Indirect-related GlobalIntVar(ButtonGraphics):783 +Found:Related GlobalIntVar(ButtonGraphics):785 +Found:Related GlobalIntVar(ButtonGraphics):784 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:86 +INTERFACE:726 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:5 +Hidden child:6 +Hidden child:7 +Hidden child:8 +Hidden child:9 +Hidden child:10 +Hidden child:11 +Hidden child:12 +Hidden child:13 +Hidden child:14 +Hidden child:15 +Hidden child:16 +Hidden child:17 +Hidden child:18 +Hidden child:19 +Hidden child:20 +Hidden child:21 +Hidden child:22 +Hidden child:23 +Hidden child:24 +Hidden child:25 +Hidden child:26 +Hidden child:27 +Hidden child:28 +Hidden child:29 +Hidden child:30 +Hidden child:31 +Hidden child:32 +Hidden child:33 +Hidden child:34 +Hidden child:35 +Hidden child:36 +Hidden child:37 +Hidden child:38 +Hidden child:39 +Hidden child:40 +Hidden child:41 +Hidden child:42 +Hidden child:43 +Hidden child:44 +Hidden child:45 +Hidden child:47 +Hidden child:48 +Hidden child:49 +Hidden child:50 +Hidden child:51 +Hidden child:52 +Hidden child:53 +Hidden child:54 +Hidden child:55 +Hidden child:56 +Hidden child:57 +Hidden child:58 +Hidden child:59 +Hidden child:60 +Hidden child:61 +Hidden child:62 +Hidden child:63 +Hidden child:64 +Hidden child:65 +Hidden child:66 +Hidden child:67 +Hidden child:68 +Hidden child:69 +Hidden child:70 +Hidden child:71 +INTERFACE:727 +Hidden child:13 +Hidden child:15 +INTERFACE:728 +Found:Indirect-related GlobalIntVar(ButtonGraphics):779 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1014 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1018 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:8 +Hidden child:13 +INTERFACE:729 +Found:Indirect-related GlobalIntVar(ButtonGraphics):779 +Found:Indirect-related GlobalIntVar(ButtonGraphics):778 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1010 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1016 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1011 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1012 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1013 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1017 +Found:Related BITconfig:ID:1057, bitoffs:23, length:24 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:13 +Hidden child:18 +INTERFACE:730 +Found:Related BITconfig:ID:1209, bitoffs:6, length:7 +Found:Related GlobalStringVar(InfoString):217 +Found:Related BITconfig:ID:1215, bitoffs:0, length:9 +Hidden child:20 +INTERFACE:731 +INTERFACE:732 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:733 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:734 +Found:Related BITconfig:ID:816, bitoffs:0, length:2 +Found:Related BITconfig:ID:816, bitoffs:3, length:5 +Found:Related BITconfig:ID:816, bitoffs:6, length:8 +Found:Related GlobalIntVar(ButtonGraphics):122 +Found:Related GlobalIntVar(ButtonGraphics):123 +Found:Related GlobalIntVar(ButtonGraphics):124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):125 +Found:Related GlobalIntVar(ButtonGraphics):156 +Found:Related GlobalIntVar(ButtonGraphics):157 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:22 +INTERFACE:735 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Related BITconfig:ID:816, bitoffs:19, length:20 +INTERFACE:736 +INTERFACE:737 +INTERFACE:738 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:739 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:740 +Found:Related BITconfig:ID:1179, bitoffs:26, length:31 +INTERFACE:741 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1230, bitoffs:3, length:8 +Found:Indirect-related BITconfig:ID:1230, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1230, bitoffs:27, length:31 +Found:Indirect-related BITconfig:ID:1230, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:1230, bitoffs:23, length:26 +Found:Indirect-related BITconfig:ID:1230, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1469 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1470 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1471 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1472 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1473 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1474 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1475 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1476 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1477 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1478 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1479 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1480 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1481 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1482 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1483 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1484 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1485 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1486 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1487 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1488 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1489 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1490 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1491 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1492 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1493 +Found:Indirect-related config:122 +Found:Indirect-related config:293 +Found:Indirect-related config:655 +Found:Indirect-related config:399 +Found:Indirect-related config:131 +Found:Indirect-related config:335 +Found:Indirect-related config:299 +Found:Indirect-related config:148 +Found:Indirect-related config:11 +Found:Indirect-related config:347 +Found:Indirect-related config:150 +Found:Indirect-related config:382 +Found:Indirect-related config:188 +Found:Indirect-related config:175 +Found:Indirect-related config:139 +Found:Indirect-related config:147 +Found:Indirect-related config:517 +Found:Indirect-related config:387 +Found:Indirect-related config:307 +Found:Indirect-related config:416 +Found:Indirect-related config:328 +Found:Indirect-related config:76 +Found:Indirect-related config:159 +Found:Indirect-related config:339 +Found:Indirect-related config:116 +Found:Indirect-related config:320 +Found:Indirect-related config:26 +Found:Indirect-related config:197 +Found:Indirect-related config:200 +Found:Indirect-related config:385 +Found:Indirect-related config:317 +Found:Indirect-related config:161 +Found:Indirect-related config:212 +Found:Indirect-related config:5 +Found:Indirect-related config:980 +Found:Indirect-related config:600 +Found:Indirect-related BITconfig:ID:997, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:433, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:869, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:440, bitoffs:0, length:14 +Found:Indirect-related BITconfig:ID:622, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:934, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:641, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:810, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:521, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:553, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:408, bitoffs:28, length:31 +Found:Indirect-related BITconfig:ID:482, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:437, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:635, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:351, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:705, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:465, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:823, bitoffs:0, length:19 +Found:Indirect-related BITconfig:ID:604, bitoffs:0, length:2 +Found:Indirect-related BITconfig:ID:435, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:423, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:905, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:730, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:602, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:616, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:723, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:449, bitoffs:0, length:1 +Found:Indirect-related BITconfig:ID:844, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:794, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:939, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:896, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:912, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:874, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:968, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:970, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:977, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:992, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:994, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:1016, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1049, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1063, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:1077, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1094, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:678, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:683, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:683, bitoffs:12, length:15 +Found:Indirect-related BITconfig:ID:680, bitoffs:0, length:2 +Found:Indirect-related BITconfig:ID:684, bitoffs:3, length:10 +Found:Indirect-related BITconfig:ID:685, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:1184, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:1204, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1190, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1165, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:1218, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:1227, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1225, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1232, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1236, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:1271, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:1282, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:1306, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1311, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1330, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:1370, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1390, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1403, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1407, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:1415, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1420, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1498, bitoffs:0, length:15 +Found:Indirect-related BITconfig:ID:1558, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:1577, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:1588, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1600, bitoffs:0, length:3 +Found:Indirect-related BITconfig:ID:1610, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1811, bitoffs:11, length:14 +Found:Indirect-related BITconfig:ID:1811, bitoffs:15, length:16 +Found:Indirect-related BITconfig:ID:1811, bitoffs:17, length:21 +Found:Indirect-related BITconfig:ID:1819, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:1834, bitoffs:28, length:31 +Found:Indirect-related BITconfig:ID:1844, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1849, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1861, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1906, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:2037, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:2046, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:2051, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:2079, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:2208, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:2234, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:2376, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:2217, bitoffs:0, length:8 +INTERFACE:742 +Found:Indirect-related GlobalIntVar(ButtonGraphics):178 +Hidden child:20 +INTERFACE:743 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +INTERFACE:744 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1394 +Found:Indirect-related GlobalIntVar(ButtonGraphics):996 +Found:Indirect-related GlobalIntVar(ButtonGraphics):997 +Found:Indirect-related GlobalIntVar(ButtonGraphics):998 +Found:Indirect-related GlobalIntVar(ButtonGraphics):999 +Found:Indirect-related GlobalIntVar(ButtonGraphics):176 +Found:Indirect-related GlobalIntVar(ButtonGraphics):547 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1093 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1090 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1091 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1240 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1273 +Found:Indirect-related GlobalStringVar(InfoString):32 +Found:Indirect-related GlobalStringVar(InfoString):33 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1414 +Found:Indirect-related GlobalIntVar(ButtonGraphics):994 +Found:Indirect-related GlobalIntVar(ButtonGraphics):986 +Found:Indirect-related GlobalIntVar(ButtonGraphics):177 +Found:Indirect-related GlobalIntVar(ButtonGraphics):987 +Found:Indirect-related GlobalIntVar(ButtonGraphics):175 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Indirect-related GlobalIntVar(ButtonGraphics):174 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1099 +Found:Indirect-related GlobalStringVar(InfoString):122 +Found:Indirect-related GlobalStringVar(InfoString):124 +Found:Indirect-related GlobalStringVar(InfoString):125 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1277 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1089 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1411 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1407 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1408 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1101 +Found:Indirect-related GlobalStringVar(InfoString):326 +Found:Indirect-related GlobalStringVar(InfoString):123 +Found:Indirect-related GlobalStringVar(InfoString):327 +Found:Indirect-related GlobalStringVar(InfoString):328 +Found:Indirect-related GlobalStringVar(InfoString):329 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1100 +Found:Indirect-related GlobalIntVar(ButtonGraphics):200 +Found:Indirect-related GlobalIntVar(ButtonGraphics):201 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1092 +Found:Indirect-related GlobalIntVar(ButtonGraphics):178 +Found:Indirect-related GlobalIntVar(ButtonGraphics):533 +Found:Indirect-related GlobalIntVar(ButtonGraphics):523 +Found:Indirect-related GlobalIntVar(ButtonGraphics):534 +Found:Indirect-related GlobalIntVar(ButtonGraphics):524 +Found:Indirect-related GlobalIntVar(ButtonGraphics):535 +Found:Indirect-related GlobalIntVar(ButtonGraphics):525 +Found:Indirect-related GlobalIntVar(ButtonGraphics):536 +Found:Indirect-related GlobalIntVar(ButtonGraphics):526 +Found:Indirect-related GlobalIntVar(ButtonGraphics):537 +Found:Indirect-related GlobalIntVar(ButtonGraphics):527 +Found:Indirect-related GlobalIntVar(ButtonGraphics):538 +Found:Indirect-related GlobalIntVar(ButtonGraphics):528 +Found:Indirect-related GlobalIntVar(ButtonGraphics):539 +Found:Indirect-related GlobalIntVar(ButtonGraphics):529 +Found:Indirect-related GlobalIntVar(ButtonGraphics):540 +Found:Indirect-related GlobalIntVar(ButtonGraphics):530 +Found:Indirect-related GlobalIntVar(ButtonGraphics):541 +Found:Indirect-related GlobalIntVar(ButtonGraphics):531 +Found:Indirect-related GlobalIntVar(ButtonGraphics):542 +Found:Indirect-related GlobalIntVar(ButtonGraphics):532 +Hidden child:18 +Hidden child:20 +Hidden child:24 +Hidden child:25 +Hidden child:26 +Hidden child:27 +Hidden child:28 +Hidden child:48 +Hidden child:49 +Hidden child:50 +Hidden child:51 +Hidden child:52 +Hidden child:77 +Hidden child:85 +Hidden child:86 +Hidden child:87 +Hidden child:88 +Hidden child:89 +Hidden child:90 +Hidden child:91 +Hidden child:92 +Hidden child:93 +Hidden child:94 +Hidden child:95 +Hidden child:103 +Hidden child:104 +Hidden child:117 +Hidden child:118 +Hidden child:119 +Hidden child:120 +Hidden child:121 +Hidden child:122 +Hidden child:123 +Hidden child:124 +INTERFACE:745 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Related GlobalIntVar(ButtonGraphics):616 +Found:Related GlobalIntVar(ButtonGraphics):1 +Found:Related config:1414 +Found:Related GlobalIntVar(ButtonGraphics):548 +Hidden child:1 +Hidden child:2 +Hidden child:3 +Hidden child:4 +Hidden child:5 +Hidden child:6 +INTERFACE:746 +Found:Related GlobalIntVar(ButtonGraphics):173 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:1255, bitoffs:0, length:1 +Found:Related config:1241 +Found:Related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1021, bitoffs:0, length:4 +Found:Indirect-related GlobalIntVar(ButtonGraphics):232 +Found:Indirect-related GlobalIntVar(ButtonGraphics):822 +Found:Indirect-related GlobalIntVar(ButtonGraphics):233 +Found:Indirect-related GlobalIntVar(ButtonGraphics):234 +Found:Indirect-related GlobalIntVar(ButtonGraphics):235 +Found:Indirect-related GlobalIntVar(ButtonGraphics):236 +Found:Indirect-related GlobalIntVar(ButtonGraphics):237 +Found:Indirect-related GlobalIntVar(ButtonGraphics):238 +Found:Indirect-related GlobalIntVar(ButtonGraphics):823 +Found:Indirect-related GlobalIntVar(ButtonGraphics):240 +Found:Indirect-related GlobalIntVar(ButtonGraphics):241 +Found:Indirect-related GlobalIntVar(ButtonGraphics):242 +Found:Indirect-related GlobalIntVar(ButtonGraphics):243 +Found:Indirect-related GlobalIntVar(ButtonGraphics):244 +Found:Indirect-related GlobalIntVar(ButtonGraphics):245 +Found:Indirect-related GlobalIntVar(ButtonGraphics):824 +Found:Related GlobalIntVar(ButtonGraphics):10 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1034 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1027 +Found:Indirect-related GlobalStringVar(InfoString):202 +Found:Related GlobalIntVar(ButtonGraphics):814 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Related GlobalIntVar(ButtonGraphics):616 +Found:Related GlobalIntVar(ButtonGraphics):1 +Found:Related config:1159 +Found:Related BITconfig:ID:638, bitoffs:30, length:31 +Found:Indirect-related config:2044 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1243 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1244 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1245 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1246 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1247 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1248 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1249 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1250 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1251 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1252 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1253 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1254 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1255 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1256 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1257 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1258 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1259 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1260 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1261 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1262 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1263 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1264 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1265 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1266 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1267 +Found:Related config:1801 +Found:Related GlobalIntVar(ButtonGraphics):1602 +Found:Indirect-related BITconfig:ID:1644, bitoffs:0, length:0 +Found:Indirect-related config:1878 +Found:Indirect-related BITconfig:ID:1644, bitoffs:1, length:31 +Hidden child:15 +Hidden child:30 +Hidden child:76 +Hidden child:80 +Hidden child:81 +Hidden child:85 +Hidden child:87 +Hidden child:89 +Hidden child:90 +Hidden child:91 +Hidden child:92 +Hidden child:94 +Hidden child:95 +Hidden child:96 +Hidden child:97 +Hidden child:98 +Hidden child:99 +Hidden child:100 +Hidden child:101 +Hidden child:102 +Hidden child:103 +Hidden child:104 +Hidden child:105 +Hidden child:106 +Hidden child:107 +Hidden child:167 +Hidden child:168 +Hidden child:183 +Hidden child:184 +Hidden child:186 +Hidden child:202 +Hidden child:216 +Hidden child:227 +Hidden child:229 +Hidden child:241 +Hidden child:244 +INTERFACE:747 +Found:Indirect-related BITconfig:ID:2382, bitoffs:0, length:14 +Found:Indirect-related BITconfig:ID:1493, bitoffs:0, length:3 +Found:Related config:1174 +Found:Related config:448 +Found:Related BITconfig:ID:1160, bitoffs:25, length:31 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Related GlobalIntVar(ButtonGraphics):10 +Found:Related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related GlobalStringVar(InfoString):204 +Found:Indirect-related GlobalStringVar(InfoString):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1436 +Found:Indirect-related BITconfig:ID:1175, bitoffs:23, length:27 +Found:Indirect-related BITconfig:ID:1209, bitoffs:6, length:7 +Found:Indirect-related BITconfig:ID:1331, bitoffs:0, length:2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1334 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1335 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1402 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1403 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1234 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1235 +Hidden child:8 +Hidden child:18 +Hidden child:19 +Hidden child:20 +Hidden child:21 +Hidden child:22 +Hidden child:23 +Hidden child:24 +Hidden child:26 +INTERFACE:748 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1533 +Found:Related config:102 +Found:Related config:456 +Found:Related BITconfig:ID:1240, bitoffs:1, length:15 +Found:Indirect-related config:281 +Found:Indirect-related config:1647 +Found:Indirect-related BITconfig:ID:1510, bitoffs:5, length:13 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1025 +Found:Indirect-related GlobalIntVar(ButtonGraphics):94 +Found:Related GlobalIntVar(ButtonGraphics):615 +INTERFACE:749 +Found:Indirect-related BITconfig:ID:2382, bitoffs:0, length:14 +Found:Related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Related GlobalIntVar(ButtonGraphics):181 +Found:Related config:1397 +INTERFACE:750 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Related config:173 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related BITconfig:ID:2382, bitoffs:0, length:14 +INTERFACE:751 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Related GlobalStringVar(InfoString):24 +INTERFACE:752 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Hidden child:3 +Hidden child:6 +Hidden child:7 +INTERFACE:753 +Hidden child:2 +Hidden child:3 +Hidden child:4 +Hidden child:5 +Hidden child:6 +Hidden child:7 +Hidden child:8 +Hidden child:9 +Hidden child:10 +Hidden child:11 +Hidden child:12 +Hidden child:13 +Hidden child:14 +Hidden child:15 +Hidden child:16 +Hidden child:17 +Hidden child:18 +Hidden child:19 +Hidden child:20 +Hidden child:21 +Hidden child:22 +Hidden child:23 +Hidden child:24 +Hidden child:25 +Hidden child:26 +Hidden child:27 +Hidden child:28 +Hidden child:29 +Hidden child:30 +Hidden child:31 +Hidden child:32 +Hidden child:33 +Hidden child:35 +INTERFACE:754 +INTERFACE:755 +Found:Indirect-related config:281 +Found:Indirect-related GlobalIntVar(ButtonGraphics):172 +Found:Related BITconfig:ID:463, bitoffs:0, length:1 +Found:Related BITconfig:ID:463, bitoffs:3, length:3 +Found:Related GlobalIntVar(ButtonGraphics):622 +Found:Related GlobalStringVar(InfoString):31 +Found:Indirect-related config:1159 +Found:Indirect-related BITconfig:ID:463, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:463, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:463, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):623 +Found:Indirect-related GlobalIntVar(ButtonGraphics):624 +Found:Indirect-related GlobalIntVar(ButtonGraphics):625 +Found:Indirect-related GlobalIntVar(ButtonGraphics):626 +Found:Indirect-related GlobalIntVar(ButtonGraphics):627 +Found:Indirect-related GlobalIntVar(ButtonGraphics):628 +Found:Indirect-related GlobalIntVar(ButtonGraphics):629 +Found:Indirect-related GlobalIntVar(ButtonGraphics):630 +Found:Indirect-related GlobalIntVar(ButtonGraphics):940 +Found:Indirect-related GlobalIntVar(ButtonGraphics):941 +Found:Indirect-related GlobalIntVar(ButtonGraphics):674 +Found:Related GlobalStringVar(InfoString):53 +Found:Related GlobalStringVar(InfoString):54 +Found:Related GlobalStringVar(InfoString):55 +Found:Related GlobalStringVar(InfoString):56 +Found:Related GlobalStringVar(InfoString):190 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:31 +Hidden child:45 +INTERFACE:756 +Found:Indirect-related BITconfig:ID:355, bitoffs:0, length:1 +Found:Indirect-related BITconfig:ID:355, bitoffs:2, length:5 +Found:Indirect-related BITconfig:ID:356, bitoffs:15, length:15 +Found:Related BITconfig:ID:1431, bitoffs:0, length:2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:4 +Hidden child:6 +Hidden child:8 +INTERFACE:757 +INTERFACE:758 +INTERFACE:759 +Found:Indirect-related BITconfig:ID:563, bitoffs:0, length:2 +INTERFACE:760 +INTERFACE:761 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1255, bitoffs:0, length:1 +Found:Indirect-related BITconfig:ID:1253, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1253, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1253, bitoffs:11, length:15 +Found:Indirect-related BITconfig:ID:1253, bitoffs:16, length:20 +Found:Indirect-related BITconfig:ID:1254, bitoffs:12, length:16 +Found:Indirect-related BITconfig:ID:1254, bitoffs:17, length:21 +INTERFACE:762 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related config:304 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Indirect-related GlobalIntVar(ButtonGraphics):188 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalStringVar(InfoString):138 +Found:Related GlobalIntVar(ButtonGraphics):190 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):5 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1246, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:1246, bitoffs:10, length:19 +Found:Indirect-related BITconfig:ID:1246, bitoffs:20, length:29 +Found:Indirect-related BITconfig:ID:1247, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:1247, bitoffs:10, length:19 +Found:Indirect-related BITconfig:ID:1247, bitoffs:20, length:29 +Found:Indirect-related BITconfig:ID:1248, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:1248, bitoffs:10, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):11 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1029 +Found:Indirect-related GlobalStringVar(InfoString):22 +Found:Indirect-related config:115 +Found:Related GlobalIntVar(ButtonGraphics):169 +Found:Indirect-related config:1249 +Hidden child:22 +Hidden child:23 +Hidden child:40 +Hidden child:41 +Hidden child:42 +Hidden child:46 +Hidden child:74 +Hidden child:75 +Hidden child:84 +Hidden child:85 +Hidden child:86 +Hidden child:87 +Hidden child:88 +Hidden child:89 +Hidden child:90 +Hidden child:91 +Hidden child:92 +Hidden child:115 +Hidden child:116 +INTERFACE:763 +Found:Indirect-related config:1249 +Found:Indirect-related GlobalIntVar(ButtonGraphics):96 +Found:Indirect-related GlobalIntVar(ButtonGraphics):95 +Hidden child:1 +Hidden child:3 +INTERFACE:764 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:765 +Found:Related BITconfig:ID:1420, bitoffs:0, length:7 +Found:Related BITconfig:ID:1422, bitoffs:8, length:11 +Found:Related GlobalIntVar(ButtonGraphics):806 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Related GlobalIntVar(ButtonGraphics):805 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:4 +Hidden child:6 +Hidden child:7 +Hidden child:19 +INTERFACE:766 +Found:Related BITconfig:ID:1554, bitoffs:31, length:31 +Found:Related BITconfig:ID:1554, bitoffs:0, length:5 +Found:Related BITconfig:ID:1553, bitoffs:0, length:3 +Found:Related BITconfig:ID:1554, bitoffs:6, length:11 +Found:Related BITconfig:ID:1553, bitoffs:4, length:7 +Found:Related BITconfig:ID:1554, bitoffs:12, length:18 +Found:Related BITconfig:ID:1553, bitoffs:8, length:11 +Found:Related BITconfig:ID:1554, bitoffs:19, length:24 +Found:Related BITconfig:ID:1553, bitoffs:12, length:15 +Found:Related BITconfig:ID:1554, bitoffs:25, length:30 +Found:Related BITconfig:ID:1553, bitoffs:16, length:19 +Found:Related BITconfig:ID:1555, bitoffs:0, length:5 +Found:Related BITconfig:ID:1553, bitoffs:20, length:23 +Hidden child:45 +Hidden child:55 +Hidden child:65 +Hidden child:75 +Hidden child:85 +Hidden child:95 +INTERFACE:767 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1038 +Found:Indirect-related GlobalIntVar(ButtonGraphics):192 +Found:Indirect-related BITconfig:ID:638, bitoffs:17, length:17 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1324 +Hidden child:26 +Hidden child:34 +Hidden child:45 +Hidden child:46 +Hidden child:47 +Hidden child:76 +INTERFACE:768 +Found:Related config:354 +Found:Related config:353 +Found:Related config:648 +Found:Related config:649 +Found:Related GlobalIntVar(ButtonGraphics):808 +Hidden child:1 +Hidden child:2 +Hidden child:3 +Hidden child:4 +INTERFACE:769 +Found:Related GlobalStringVar(InfoString):130 +Found:Related GlobalStringVar(InfoString):142 +Found:Related GlobalStringVar(InfoString):146 +Found:Related GlobalStringVar(InfoString):143 +Found:Related GlobalStringVar(InfoString):144 +Found:Related GlobalStringVar(InfoString):145 +Found:Related GlobalStringVar(InfoString):218 +Found:Related GlobalIntVar(ButtonGraphics):809 +Found:Related GlobalIntVar(ButtonGraphics):810 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:16 +Hidden child:18 +Hidden child:26 +Hidden child:27 +Hidden child:28 +Hidden child:32 +Hidden child:33 +Hidden child:34 +INTERFACE:770 +INTERFACE:771 +INTERFACE:772 +Found:Indirect-related BITconfig:ID:2052, bitoffs:16, length:17 +Found:Indirect-related BITconfig:ID:2052, bitoffs:18, length:19 +Found:Indirect-related BITconfig:ID:2052, bitoffs:20, length:21 +Found:Indirect-related BITconfig:ID:2052, bitoffs:22, length:23 +Found:Indirect-related BITconfig:ID:2052, bitoffs:24, length:25 +Found:Indirect-related BITconfig:ID:2052, bitoffs:26, length:27 +Found:Indirect-related BITconfig:ID:2052, bitoffs:28, length:29 +Found:Indirect-related BITconfig:ID:2052, bitoffs:30, length:31 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:773 +Hidden child:6 +INTERFACE:774 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:775 +Found:Related BITconfig:ID:1271, bitoffs:0, length:6 +Found:Related BITconfig:ID:1306, bitoffs:0, length:5 +INTERFACE:776 +INTERFACE:777 +INTERFACE:778 +INTERFACE:779 +Found:Related config:1278 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:4 +Hidden child:136 +INTERFACE:780 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:781 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Related BITconfig:ID:1495, bitoffs:0, length:9 +Found:Related BITconfig:ID:1276, bitoffs:7, length:9 +Hidden child:1 +Hidden child:13 +Hidden child:14 +INTERFACE:782 +INTERFACE:783 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):232 +Found:Indirect-related GlobalIntVar(ButtonGraphics):822 +Found:Indirect-related GlobalIntVar(ButtonGraphics):233 +Found:Indirect-related GlobalIntVar(ButtonGraphics):234 +Found:Indirect-related GlobalIntVar(ButtonGraphics):235 +Found:Indirect-related GlobalIntVar(ButtonGraphics):236 +Found:Indirect-related GlobalIntVar(ButtonGraphics):237 +Found:Indirect-related GlobalIntVar(ButtonGraphics):238 +Found:Indirect-related GlobalIntVar(ButtonGraphics):823 +Found:Indirect-related GlobalIntVar(ButtonGraphics):240 +Found:Indirect-related GlobalIntVar(ButtonGraphics):241 +Found:Indirect-related GlobalIntVar(ButtonGraphics):242 +Found:Indirect-related GlobalIntVar(ButtonGraphics):243 +Found:Indirect-related GlobalIntVar(ButtonGraphics):244 +Found:Indirect-related GlobalIntVar(ButtonGraphics):245 +Found:Indirect-related GlobalIntVar(ButtonGraphics):824 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +INTERFACE:784 +INTERFACE:785 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:786 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:787 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:788 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:789 +Found:Indirect-related GlobalIntVar(ButtonGraphics):267 +Found:Indirect-related GlobalStringVar(InfoString):38 +Found:Indirect-related GlobalStringVar(InfoString):39 +Found:Related GlobalIntVar(ButtonGraphics):266 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1029 +Found:Indirect-related GlobalStringVar(InfoString):22 +Found:Related GlobalIntVar(ButtonGraphics):5 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related config:287 +Found:Indirect-related config:1054 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:790 +Found:Related GlobalIntVar(ButtonGraphics):268 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:791 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):252 +Found:Indirect-related GlobalIntVar(ButtonGraphics):253 +Found:Related GlobalIntVar(ButtonGraphics):246 +Found:Related GlobalIntVar(ButtonGraphics):247 +Found:Related GlobalIntVar(ButtonGraphics):248 +Found:Related GlobalIntVar(ButtonGraphics):249 +Found:Related GlobalIntVar(ButtonGraphics):250 +Found:Related GlobalIntVar(ButtonGraphics):251 +Found:Related GlobalIntVar(ButtonGraphics):254 +Found:Related GlobalIntVar(ButtonGraphics):255 +Found:Related GlobalIntVar(ButtonGraphics):256 +Found:Related GlobalIntVar(ButtonGraphics):257 +Found:Related GlobalIntVar(ButtonGraphics):258 +Found:Related GlobalIntVar(ButtonGraphics):259 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related config:1149 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Hidden child:114 +INTERFACE:792 +Found:Indirect-related GlobalIntVar(ButtonGraphics):248 +Found:Indirect-related GlobalIntVar(ButtonGraphics):246 +Found:Indirect-related GlobalIntVar(ButtonGraphics):247 +Found:Indirect-related GlobalIntVar(ButtonGraphics):249 +Found:Indirect-related GlobalIntVar(ButtonGraphics):250 +Found:Indirect-related GlobalIntVar(ButtonGraphics):252 +Found:Indirect-related GlobalIntVar(ButtonGraphics):251 +Found:Indirect-related GlobalIntVar(ButtonGraphics):256 +Found:Indirect-related GlobalIntVar(ButtonGraphics):253 +Found:Indirect-related GlobalIntVar(ButtonGraphics):254 +Found:Indirect-related GlobalIntVar(ButtonGraphics):255 +Found:Indirect-related GlobalIntVar(ButtonGraphics):257 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +INTERFACE:793 +Found:Indirect-related BITconfig:ID:1147, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1046, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1045, bitoffs:31, length:31 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:794 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related BITconfig:ID:1311, bitoffs:14, length:15 +INTERFACE:795 +INTERFACE:796 +Found:Related BITconfig:ID:1311, bitoffs:10, length:13 +Hidden child:5 +Hidden child:7 +Hidden child:9 +Hidden child:16 +Hidden child:38 +INTERFACE:797 +Found:Related BITconfig:ID:2387, bitoffs:0, length:9 +Hidden child:14 +Hidden child:31 +Hidden child:45 +Hidden child:59 +Hidden child:72 +Hidden child:87 +Hidden child:101 +Hidden child:115 +Hidden child:129 +INTERFACE:798 +INTERFACE:799 +Found:Related BITconfig:ID:1328, bitoffs:11, length:13 +Found:Related BITconfig:ID:1328, bitoffs:14, length:16 +Found:Related BITconfig:ID:1328, bitoffs:17, length:19 +Found:Related BITconfig:ID:1328, bitoffs:20, length:22 +Found:Related BITconfig:ID:1328, bitoffs:23, length:25 +Found:Related BITconfig:ID:1328, bitoffs:26, length:28 +Found:Related BITconfig:ID:1328, bitoffs:29, length:31 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:800 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +INTERFACE:801 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:802 +Found:Related config:1332 +Found:Related config:1334 +Found:Related config:1337 +Found:Related config:1333 +Found:Related config:1335 +Found:Related GlobalIntVar(ButtonGraphics):581 +Found:Related GlobalStringVar(InfoString):43 +Hidden child:19 +INTERFACE:803 +INTERFACE:804 +Hidden child:2 +INTERFACE:805 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related config:1042 +Found:Related config:1043 +Found:Related GlobalStringVar(InfoString):219 +Found:Related GlobalIntVar(ButtonGraphics):12 +Found:Related GlobalIntVar(ButtonGraphics):13 +Found:Related GlobalIntVar(ButtonGraphics):14 +Found:Related GlobalIntVar(ButtonGraphics):15 +Found:Related GlobalIntVar(ButtonGraphics):16 +Found:Related GlobalIntVar(ButtonGraphics):17 +Found:Related GlobalIntVar(ButtonGraphics):18 +Found:Related GlobalIntVar(ButtonGraphics):19 +Found:Related GlobalIntVar(ButtonGraphics):20 +Found:Related GlobalIntVar(ButtonGraphics):21 +Found:Related GlobalIntVar(ButtonGraphics):22 +Found:Related GlobalIntVar(ButtonGraphics):23 +Found:Related GlobalIntVar(ButtonGraphics):24 +Found:Related GlobalIntVar(ButtonGraphics):25 +Found:Related GlobalIntVar(ButtonGraphics):26 +Found:Related GlobalIntVar(ButtonGraphics):27 +Found:Related GlobalIntVar(ButtonGraphics):28 +Found:Related GlobalIntVar(ButtonGraphics):29 +Found:Related GlobalIntVar(ButtonGraphics):30 +Found:Related GlobalIntVar(ButtonGraphics):31 +Found:Related GlobalIntVar(ButtonGraphics):32 +Found:Related GlobalIntVar(ButtonGraphics):33 +Found:Related GlobalIntVar(ButtonGraphics):34 +Found:Related GlobalIntVar(ButtonGraphics):35 +Found:Related GlobalIntVar(ButtonGraphics):36 +Found:Related GlobalIntVar(ButtonGraphics):37 +Found:Related GlobalIntVar(ButtonGraphics):38 +Found:Related GlobalIntVar(ButtonGraphics):39 +Found:Related GlobalIntVar(ButtonGraphics):212 +Hidden child:34 +INTERFACE:806 +Found:Related GlobalIntVar(ButtonGraphics):583 +Found:Related GlobalIntVar(ButtonGraphics):584 +Found:Related GlobalIntVar(ButtonGraphics):585 +Found:Related GlobalIntVar(ButtonGraphics):586 +Found:Related GlobalIntVar(ButtonGraphics):587 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Hidden child:122 +INTERFACE:807 +INTERFACE:808 +INTERFACE:809 +Found:Related GlobalIntVar(ButtonGraphics):556 +Found:Related GlobalIntVar(ButtonGraphics):559 +Found:Related GlobalIntVar(ButtonGraphics):560 +Found:Related GlobalIntVar(ButtonGraphics):561 +Found:Related GlobalIntVar(ButtonGraphics):562 +Found:Related config:1332 +Found:Related config:1334 +Found:Related config:1337 +Found:Related config:1333 +Found:Related config:1335 +Found:Related GlobalIntVar(ButtonGraphics):557 +Found:Related GlobalIntVar(ButtonGraphics):558 +Hidden child:18 +INTERFACE:810 +Found:Related GlobalIntVar(ButtonGraphics):600 +Found:Related GlobalIntVar(ButtonGraphics):603 +Found:Related GlobalIntVar(ButtonGraphics):589 +Found:Related GlobalIntVar(ButtonGraphics):588 +Found:Related GlobalIntVar(ButtonGraphics):597 +Found:Related GlobalIntVar(ButtonGraphics):598 +Found:Related GlobalIntVar(ButtonGraphics):590 +Found:Related GlobalIntVar(ButtonGraphics):591 +Found:Related GlobalIntVar(ButtonGraphics):592 +Found:Related GlobalIntVar(ButtonGraphics):593 +Found:Related GlobalIntVar(ButtonGraphics):594 +Found:Related GlobalIntVar(ButtonGraphics):595 +Found:Related GlobalIntVar(ButtonGraphics):596 +Found:Related GlobalIntVar(ButtonGraphics):599 +Found:Related GlobalIntVar(ButtonGraphics):601 +Found:Related GlobalIntVar(ButtonGraphics):602 +Found:Related GlobalIntVar(ButtonGraphics):604 +Found:Related GlobalIntVar(ButtonGraphics):605 +Found:Related GlobalIntVar(ButtonGraphics):606 +Found:Related GlobalIntVar(ButtonGraphics):607 +Found:Related GlobalIntVar(ButtonGraphics):608 +Found:Related GlobalIntVar(ButtonGraphics):609 +Found:Related GlobalIntVar(ButtonGraphics):610 +Found:Related GlobalIntVar(ButtonGraphics):611 +Found:Related GlobalIntVar(ButtonGraphics):612 +Found:Related GlobalIntVar(ButtonGraphics):613 +Found:Related GlobalIntVar(ButtonGraphics):614 +Found:Related GlobalStringVar(InfoString):44 +Found:Related GlobalStringVar(InfoString):45 +Found:Related GlobalStringVar(InfoString):46 +Found:Related GlobalStringVar(InfoString):47 +Found:Related GlobalStringVar(InfoString):48 +Found:Related GlobalStringVar(InfoString):49 +Found:Related GlobalStringVar(InfoString):50 +Found:Related GlobalStringVar(InfoString):51 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:85 +Hidden child:144 +INTERFACE:811 +Found:Related GlobalIntVar(ButtonGraphics):544 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Related GlobalIntVar(ButtonGraphics):549 +Hidden child:3 +Hidden child:4 +Hidden child:38 +Hidden child:52 +Hidden child:67 +Hidden child:81 +Hidden child:95 +Hidden child:110 +INTERFACE:812 +Found:Related GlobalIntVar(ButtonGraphics):551 +Found:Related GlobalIntVar(ButtonGraphics):552 +Found:Related GlobalIntVar(ButtonGraphics):553 +Found:Related GlobalStringVar(InfoString):40 +Found:Related GlobalStringVar(InfoString):41 +Found:Related GlobalStringVar(InfoString):42 +INTERFACE:813 +Found:Related GlobalIntVar(ButtonGraphics):582 +Found:Indirect-related GlobalIntVar(ButtonGraphics):583 +Found:Indirect-related GlobalIntVar(ButtonGraphics):584 +Found:Indirect-related GlobalIntVar(ButtonGraphics):585 +Found:Indirect-related GlobalIntVar(ButtonGraphics):586 +Found:Indirect-related GlobalIntVar(ButtonGraphics):587 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:16 +Hidden child:17 +Hidden child:18 +Hidden child:19 +Hidden child:75 +Hidden child:77 +Hidden child:78 +Hidden child:79 +Hidden child:98 +Hidden child:100 +Hidden child:102 +Hidden child:104 +Hidden child:106 +INTERFACE:814 +Found:Related BITconfig:ID:425, bitoffs:1, length:2 +INTERFACE:815 +INTERFACE:816 +INTERFACE:817 +INTERFACE:818 +Found:Related BITconfig:ID:425, bitoffs:1, length:2 +Found:Related GlobalIntVar(ButtonGraphics):97 +Hidden child:0 +INTERFACE:819 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:820 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:821 +INTERFACE:822 +Found:Related BITconfig:ID:425, bitoffs:1, length:2 +INTERFACE:823 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Hidden child:8 +Hidden child:25 +Hidden child:36 +INTERFACE:824 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Indirect-related BITconfig:ID:2387, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:2387, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:2387, bitoffs:12, length:12 +Found:Indirect-related BITconfig:ID:2387, bitoffs:13, length:13 +Found:Related BITconfig:ID:2387, bitoffs:14, length:16 +Found:Related BITconfig:ID:2387, bitoffs:17, length:19 +Found:Related BITconfig:ID:2387, bitoffs:20, length:22 +Found:Related BITconfig:ID:2387, bitoffs:23, length:25 +Hidden child:8 +Hidden child:9 +Hidden child:10 +Hidden child:11 +Hidden child:44 +Hidden child:51 +Hidden child:60 +Hidden child:102 +Hidden child:112 +Hidden child:121 +Hidden child:155 +Hidden child:165 +Hidden child:174 +Hidden child:192 +Hidden child:202 +Hidden child:211 +INTERFACE:825 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:68 +Hidden child:70 +Hidden child:90 +INTERFACE:826 +Found:Related BITconfig:ID:425, bitoffs:1, length:2 +INTERFACE:827 +INTERFACE:828 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:829 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:830 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:831 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:832 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:833 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:834 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Related GlobalIntVar(ButtonGraphics):642 +Found:Related GlobalIntVar(ButtonGraphics):645 +Found:Related GlobalIntVar(ButtonGraphics):654 +Found:Related config:1380 +Found:Related GlobalIntVar(ButtonGraphics):655 +Hidden child:46 +Hidden child:48 +Hidden child:52 +Hidden child:56 +Hidden child:60 +Hidden child:61 +Hidden child:62 +Hidden child:63 +Hidden child:67 +Hidden child:68 +INTERFACE:835 +INTERFACE:836 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Related BITconfig:ID:1377, bitoffs:29, length:29 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Related GlobalIntVar(ButtonGraphics):643 +Found:Related GlobalIntVar(ButtonGraphics):639 +Found:Related GlobalIntVar(ButtonGraphics):641 +Found:Related GlobalIntVar(ButtonGraphics):644 +Found:Related GlobalIntVar(ButtonGraphics):640 +Found:Related GlobalIntVar(ButtonGraphics):642 +Found:Related GlobalIntVar(ButtonGraphics):636 +Found:Related GlobalIntVar(ButtonGraphics):645 +Found:Related GlobalIntVar(ButtonGraphics):649 +Found:Related GlobalIntVar(ButtonGraphics):647 +Found:Related config:1380 +Found:Related GlobalIntVar(ButtonGraphics):655 +Hidden child:47 +Hidden child:49 +Hidden child:50 +INTERFACE:837 +Found:Related GlobalIntVar(ButtonGraphics):632 +Found:Related GlobalIntVar(ButtonGraphics):633 +Found:Related GlobalIntVar(ButtonGraphics):637 +Found:Related GlobalIntVar(ButtonGraphics):634 +Found:Related GlobalIntVar(ButtonGraphics):638 +Found:Related GlobalIntVar(ButtonGraphics):635 +Found:Related GlobalIntVar(ButtonGraphics):636 +INTERFACE:838 +Found:Indirect-related GlobalIntVar(ButtonGraphics):656 +Found:Indirect-related GlobalIntVar(ButtonGraphics):657 +Found:Indirect-related GlobalIntVar(ButtonGraphics):658 +Found:Indirect-related GlobalIntVar(ButtonGraphics):659 +Found:Indirect-related GlobalIntVar(ButtonGraphics):660 +Found:Indirect-related GlobalIntVar(ButtonGraphics):661 +Found:Indirect-related GlobalIntVar(ButtonGraphics):662 +Found:Indirect-related GlobalIntVar(ButtonGraphics):663 +Found:Indirect-related GlobalIntVar(ButtonGraphics):664 +Found:Indirect-related GlobalIntVar(ButtonGraphics):665 +Found:Indirect-related GlobalIntVar(ButtonGraphics):666 +Found:Indirect-related GlobalIntVar(ButtonGraphics):667 +Found:Indirect-related GlobalIntVar(ButtonGraphics):668 +Found:Indirect-related GlobalIntVar(ButtonGraphics):669 +Found:Indirect-related GlobalIntVar(ButtonGraphics):670 +Found:Indirect-related GlobalIntVar(ButtonGraphics):672 +Found:Indirect-related GlobalIntVar(ButtonGraphics):673 +Found:Indirect-related GlobalIntVar(ButtonGraphics):671 +Found:Indirect-related GlobalStringVar(InfoString):73 +Found:Indirect-related GlobalStringVar(InfoString):74 +Found:Indirect-related GlobalStringVar(InfoString):75 +Found:Indirect-related GlobalStringVar(InfoString):76 +Found:Indirect-related GlobalStringVar(InfoString):77 +Found:Indirect-related GlobalStringVar(InfoString):78 +Found:Indirect-related GlobalStringVar(InfoString):79 +Found:Indirect-related GlobalStringVar(InfoString):80 +Found:Indirect-related GlobalStringVar(InfoString):81 +Found:Indirect-related GlobalStringVar(InfoString):82 +Found:Indirect-related GlobalStringVar(InfoString):83 +Found:Indirect-related GlobalStringVar(InfoString):84 +Found:Indirect-related GlobalStringVar(InfoString):85 +Found:Indirect-related GlobalStringVar(InfoString):86 +Found:Indirect-related GlobalStringVar(InfoString):87 +Found:Indirect-related GlobalStringVar(InfoString):88 +Found:Indirect-related GlobalStringVar(InfoString):89 +Found:Indirect-related GlobalStringVar(InfoString):90 +Found:Indirect-related GlobalStringVar(InfoString):91 +Found:Indirect-related GlobalStringVar(InfoString):92 +Found:Indirect-related GlobalStringVar(InfoString):93 +Found:Indirect-related GlobalStringVar(InfoString):94 +Found:Indirect-related GlobalStringVar(InfoString):95 +Found:Indirect-related GlobalStringVar(InfoString):96 +Found:Indirect-related GlobalStringVar(InfoString):97 +Found:Indirect-related GlobalStringVar(InfoString):98 +Found:Indirect-related GlobalStringVar(InfoString):99 +Found:Indirect-related GlobalStringVar(InfoString):100 +Found:Indirect-related GlobalStringVar(InfoString):101 +Found:Indirect-related GlobalStringVar(InfoString):102 +Found:Indirect-related GlobalStringVar(InfoString):103 +Found:Indirect-related GlobalStringVar(InfoString):104 +Found:Indirect-related GlobalStringVar(InfoString):105 +Found:Indirect-related GlobalStringVar(InfoString):106 +Found:Indirect-related GlobalStringVar(InfoString):107 +Found:Indirect-related GlobalStringVar(InfoString):108 +Found:Indirect-related GlobalStringVar(InfoString):109 +Found:Indirect-related GlobalStringVar(InfoString):110 +Found:Indirect-related GlobalStringVar(InfoString):111 +Found:Indirect-related GlobalStringVar(InfoString):112 +Found:Indirect-related GlobalStringVar(InfoString):113 +Found:Indirect-related GlobalStringVar(InfoString):114 +Found:Indirect-related GlobalStringVar(InfoString):115 +Found:Indirect-related GlobalStringVar(InfoString):116 +Found:Indirect-related GlobalStringVar(InfoString):117 +Found:Indirect-related GlobalStringVar(InfoString):118 +Found:Indirect-related GlobalStringVar(InfoString):119 +Found:Indirect-related GlobalStringVar(InfoString):120 +Found:Indirect-related GlobalStringVar(InfoString):121 +Found:Indirect-related GlobalStringVar(InfoString):57 +Found:Indirect-related GlobalStringVar(InfoString):58 +Found:Indirect-related GlobalStringVar(InfoString):59 +Found:Indirect-related GlobalStringVar(InfoString):60 +Found:Indirect-related GlobalStringVar(InfoString):61 +Found:Indirect-related GlobalStringVar(InfoString):62 +Found:Indirect-related GlobalStringVar(InfoString):63 +Found:Indirect-related GlobalStringVar(InfoString):64 +Found:Indirect-related GlobalStringVar(InfoString):65 +Found:Indirect-related GlobalStringVar(InfoString):66 +Found:Indirect-related GlobalStringVar(InfoString):67 +Found:Indirect-related GlobalStringVar(InfoString):68 +Found:Indirect-related GlobalStringVar(InfoString):69 +Found:Indirect-related GlobalStringVar(InfoString):70 +Found:Indirect-related GlobalStringVar(InfoString):71 +Found:Indirect-related GlobalStringVar(InfoString):72 +INTERFACE:839 +INTERFACE:840 +Found:Indirect-related GlobalIntVar(ButtonGraphics):906 +Found:Indirect-related GlobalIntVar(ButtonGraphics):907 +Found:Related BITconfig:ID:1450, bitoffs:13, length:17 +Found:Indirect-related GlobalIntVar(ButtonGraphics):904 +Hidden child:4 +INTERFACE:841 +INTERFACE:842 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related GlobalIntVar(ButtonGraphics):857 +Found:Related GlobalIntVar(ButtonGraphics):858 +Found:Related GlobalIntVar(ButtonGraphics):859 +Found:Related GlobalIntVar(ButtonGraphics):860 +Found:Related GlobalIntVar(ButtonGraphics):861 +Found:Related GlobalIntVar(ButtonGraphics):862 +Found:Related GlobalIntVar(ButtonGraphics):863 +Found:Related GlobalIntVar(ButtonGraphics):864 +Found:Related GlobalIntVar(ButtonGraphics):865 +Found:Related GlobalIntVar(ButtonGraphics):866 +Found:Related GlobalIntVar(ButtonGraphics):867 +Found:Related GlobalIntVar(ButtonGraphics):868 +Found:Related GlobalIntVar(ButtonGraphics):869 +Found:Related GlobalIntVar(ButtonGraphics):870 +Found:Related GlobalIntVar(ButtonGraphics):871 +Found:Related GlobalIntVar(ButtonGraphics):872 +Found:Related GlobalIntVar(ButtonGraphics):873 +Found:Related GlobalIntVar(ButtonGraphics):874 +INTERFACE:843 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related GlobalIntVar(ButtonGraphics):945 +Found:Related GlobalStringVar(InfoString):182 +Found:Related GlobalStringVar(InfoString):183 +INTERFACE:844 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):826 +Found:Indirect-related GlobalIntVar(ButtonGraphics):827 +INTERFACE:845 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related GlobalIntVar(ButtonGraphics):828 +Found:Related GlobalIntVar(ButtonGraphics):829 +Found:Related GlobalIntVar(ButtonGraphics):830 +Found:Related GlobalIntVar(ButtonGraphics):831 +Found:Related GlobalIntVar(ButtonGraphics):832 +INTERFACE:846 +INTERFACE:847 +INTERFACE:848 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related GlobalIntVar(ButtonGraphics):875 +Found:Related GlobalIntVar(ButtonGraphics):876 +Found:Related GlobalIntVar(ButtonGraphics):877 +Found:Related GlobalIntVar(ButtonGraphics):878 +Found:Related GlobalIntVar(ButtonGraphics):879 +Found:Related GlobalIntVar(ButtonGraphics):880 +Found:Related BITconfig:ID:1451, bitoffs:27, length:27 +Found:Related BITconfig:ID:1451, bitoffs:28, length:28 +Found:Related BITconfig:ID:1451, bitoffs:29, length:29 +Found:Related BITconfig:ID:1451, bitoffs:30, length:30 +Found:Related BITconfig:ID:1451, bitoffs:31, length:31 +INTERFACE:849 +Found:Related GlobalIntVar(ButtonGraphics):837 +Hidden child:54 +INTERFACE:850 +Found:Related BITconfig:ID:1445, bitoffs:19, length:21 +Found:Related GlobalStringVar(InfoString):179 +Hidden child:1 +INTERFACE:851 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:852 +Found:Indirect-related config:1447 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related GlobalIntVar(ButtonGraphics):838 +Found:Related GlobalStringVar(InfoString):180 +Found:Related GlobalStringVar(InfoString):181 +Found:Indirect-related GlobalIntVar(ButtonGraphics):840 +Found:Related GlobalIntVar(ButtonGraphics):839 +Found:Related BITconfig:ID:1445, bitoffs:0, length:18 +Found:Related BITconfig:ID:1455, bitoffs:0, length:14 +Hidden child:80 +INTERFACE:853 +Found:Related GlobalIntVar(ButtonGraphics):834 +Found:Related GlobalIntVar(ButtonGraphics):835 +Found:Related GlobalIntVar(ButtonGraphics):836 +Found:Related GlobalIntVar(ButtonGraphics):833 +Found:Related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +INTERFACE:854 +Found:Related BITconfig:ID:1444, bitoffs:8, length:13 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:855 +Found:Related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +INTERFACE:856 +INTERFACE:857 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:2 +INTERFACE:858 +INTERFACE:859 +Found:Related BITconfig:ID:1450, bitoffs:13, length:17 +Found:Indirect-related GlobalIntVar(ButtonGraphics):906 +Found:Indirect-related GlobalIntVar(ButtonGraphics):907 +Found:Indirect-related GlobalIntVar(ButtonGraphics):904 +Found:Indirect-related GlobalIntVar(ButtonGraphics):905 +Found:Related GlobalIntVar(ButtonGraphics):902 +Found:Related GlobalIntVar(ButtonGraphics):903 +Hidden child:3 +Hidden child:4 +Hidden child:5 +Hidden child:18 +Hidden child:19 +INTERFACE:860 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):842 +INTERFACE:861 +INTERFACE:862 +Found:Related BITconfig:ID:1452, bitoffs:0, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related GlobalStringVar(InfoString):184 +Found:Related GlobalStringVar(InfoString):185 +Found:Related GlobalStringVar(InfoString):186 +Found:Related GlobalStringVar(InfoString):187 +Found:Related GlobalStringVar(InfoString):188 +Found:Related GlobalStringVar(InfoString):189 +Hidden child:30 +INTERFACE:863 +Found:Indirect-related BITconfig:ID:1452, bitoffs:0, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):846 +Found:Indirect-related GlobalIntVar(ButtonGraphics):839 +Found:Related BITconfig:ID:1445, bitoffs:0, length:18 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related GlobalIntVar(ButtonGraphics):844 +Found:Related GlobalIntVar(ButtonGraphics):845 +INTERFACE:864 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related config:1469 +Found:Indirect-related BITconfig:ID:507, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:507, bitoffs:8, length:13 +Found:Indirect-related BITconfig:ID:507, bitoffs:16, length:21 +Found:Indirect-related BITconfig:ID:1063, bitoffs:14, length:16 +INTERFACE:865 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related config:1442 +INTERFACE:866 +Found:Related BITconfig:ID:1476, bitoffs:0, length:2 +Found:Related BITconfig:ID:1476, bitoffs:22, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related BITconfig:ID:1476, bitoffs:24, length:27 +Hidden child:10 +Hidden child:11 +Hidden child:12 +Hidden child:13 +Hidden child:45 +Hidden child:49 +Hidden child:52 +Hidden child:55 +Hidden child:58 +Hidden child:61 +Hidden child:65 +Hidden child:66 +Hidden child:67 +Hidden child:68 +Hidden child:69 +Hidden child:70 +Hidden child:71 +Hidden child:72 +Hidden child:73 +Hidden child:76 +Hidden child:79 +INTERFACE:867 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:868 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:869 +INTERFACE:870 +INTERFACE:871 +Found:Related BITconfig:ID:425, bitoffs:1, length:2 +INTERFACE:872 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:873 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:874 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:875 +INTERFACE:876 +Found:Related BITconfig:ID:1476, bitoffs:19, length:21 +Found:Related BITconfig:ID:1475, bitoffs:8, length:11 +Hidden child:3 +INTERFACE:877 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:878 +INTERFACE:879 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:880 +Found:Related BITconfig:ID:1494, bitoffs:0, length:3 +INTERFACE:881 +INTERFACE:882 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1394 +Hidden child:5 +Hidden child:23 +INTERFACE:883 +INTERFACE:884 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1000 +Found:Related config:300 +Found:Related config:301 +Found:Related config:172 +Found:Related config:43 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +INTERFACE:885 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related GlobalIntVar(ButtonGraphics):1001 +INTERFACE:886 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1002 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:887 +Found:Related BITconfig:ID:1498, bitoffs:0, length:15 +Found:Related BITconfig:ID:1498, bitoffs:27, length:28 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:888 +INTERFACE:889 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:890 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1099 +Found:Related GlobalIntVar(ButtonGraphics):1412 +Found:Related GlobalStringVar(InfoString):330 +Found:Indirect-related GlobalIntVar(ButtonGraphics):174 +Found:Indirect-related GlobalIntVar(ButtonGraphics):175 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1407 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1408 +Found:Indirect-related GlobalStringVar(InfoString):122 +Found:Indirect-related GlobalStringVar(InfoString):326 +Found:Indirect-related GlobalStringVar(InfoString):124 +Found:Indirect-related GlobalStringVar(InfoString):125 +Found:Indirect-related GlobalStringVar(InfoString):123 +Found:Indirect-related GlobalStringVar(InfoString):327 +Found:Indirect-related GlobalStringVar(InfoString):328 +Found:Indirect-related GlobalStringVar(InfoString):329 +Hidden child:35 +Hidden child:43 +Hidden child:54 +Hidden child:61 +INTERFACE:891 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:0 +Hidden child:1 +Hidden child:61 +Hidden child:62 +Hidden child:63 +Hidden child:64 +Hidden child:65 +INTERFACE:892 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1045, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1045, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1045, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1045, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1045, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1045, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1045, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1045, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1045, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1045, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:1, length:3 +Found:Indirect-related BITconfig:ID:1046, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1046, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1046, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1046, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1046, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1046, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1046, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1046, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1046, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1045, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1047, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1047, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1047, bitoffs:13, length:15 +Found:Indirect-related BITconfig:ID:1047, bitoffs:16, length:18 +Found:Indirect-related BITconfig:ID:1047, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1047, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1047, bitoffs:25, length:27 +Found:Indirect-related BITconfig:ID:1047, bitoffs:28, length:30 +Found:Indirect-related BITconfig:ID:1046, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1501, bitoffs:0, length:2 +Hidden child:21 +INTERFACE:893 +Found:Related GlobalStringVar(InfoString):197 +Found:Related GlobalStringVar(InfoString):198 +Found:Related GlobalStringVar(InfoString):199 +Found:Related GlobalStringVar(InfoString):200 +Hidden child:13 +INTERFACE:894 +Found:Related GlobalStringVar(InfoString):197 +Found:Related GlobalStringVar(InfoString):198 +Found:Related GlobalStringVar(InfoString):199 +Found:Related GlobalStringVar(InfoString):200 +INTERFACE:895 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:896 +Found:Related config:281 +Found:Related config:170 +Found:Related BITconfig:ID:1805, bitoffs:2, length:2 +Found:Related GlobalIntVar(ButtonGraphics):1003 +Found:Related GlobalIntVar(ButtonGraphics):1004 +Found:Related GlobalIntVar(ButtonGraphics):1005 +Found:Related GlobalIntVar(ButtonGraphics):1006 +Found:Related GlobalStringVar(InfoString):194 +Found:Related GlobalStringVar(InfoString):195 +Hidden child:4 +INTERFACE:897 +Found:Related config:281 +Hidden child:2 +Hidden child:3 +Hidden child:4 +Hidden child:5 +INTERFACE:898 +INTERFACE:899 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1007 +INTERFACE:900 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related BITconfig:ID:1057, bitoffs:0, length:0 +Found:Related BITconfig:ID:1057, bitoffs:1, length:4 +Hidden child:32 +INTERFACE:901 +Hidden child:30 +Hidden child:31 +Hidden child:39 +Hidden child:40 +INTERFACE:902 +INTERFACE:903 +Hidden child:0 +INTERFACE:904 +Found:Related GlobalStringVar(InfoString):130 +Found:Related GlobalStringVar(InfoString):142 +Found:Related GlobalStringVar(InfoString):146 +Found:Related GlobalStringVar(InfoString):147 +Found:Related GlobalStringVar(InfoString):143 +Found:Related GlobalStringVar(InfoString):144 +Found:Related GlobalStringVar(InfoString):145 +Found:Related GlobalIntVar(ButtonGraphics):809 +Found:Related GlobalIntVar(ButtonGraphics):810 +Found:Related GlobalIntVar(ButtonGraphics):811 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:44 +INTERFACE:905 +Found:Indirect-related GlobalIntVar(ButtonGraphics):754 +Found:Indirect-related BITconfig:ID:1363, bitoffs:26, length:31 +Found:Indirect-related BITconfig:ID:1363, bitoffs:20, length:25 +Found:Indirect-related GlobalIntVar(ButtonGraphics):93 +Found:Related GlobalIntVar(ButtonGraphics):92 +Found:Related GlobalIntVar(ButtonGraphics):755 +Found:Related GlobalIntVar(ButtonGraphics):756 +Found:Related GlobalIntVar(ButtonGraphics):757 +Found:Related GlobalIntVar(ButtonGraphics):758 +Found:Related GlobalIntVar(ButtonGraphics):759 +Found:Related GlobalIntVar(ButtonGraphics):760 +Found:Related GlobalIntVar(ButtonGraphics):1139 +Found:Related GlobalIntVar(ButtonGraphics):1140 +Found:Related GlobalIntVar(ButtonGraphics):1141 +Found:Related GlobalIntVar(ButtonGraphics):1142 +Found:Related GlobalIntVar(ButtonGraphics):120 +Found:Related GlobalIntVar(ButtonGraphics):185 +Found:Related GlobalIntVar(ButtonGraphics):87 +Found:Related GlobalIntVar(ButtonGraphics):90 +Found:Related GlobalStringVar(InfoString):132 +Found:Related GlobalStringVar(InfoString):133 +Found:Related GlobalStringVar(InfoString):134 +Found:Related GlobalStringVar(InfoString):135 +Found:Related GlobalStringVar(InfoString):136 +Found:Related GlobalStringVar(InfoString):137 +Found:Related GlobalStringVar(InfoString):280 +Found:Related GlobalStringVar(InfoString):281 +Found:Related GlobalStringVar(InfoString):282 +Found:Related GlobalStringVar(InfoString):283 +Found:Related GlobalStringVar(InfoString):275 +Found:Related GlobalStringVar(InfoString):316 +Found:Related GlobalStringVar(InfoString):317 +Found:Related GlobalStringVar(InfoString):318 +Hidden child:28 +INTERFACE:906 +Found:Related GlobalIntVar(ButtonGraphics):1100 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1414 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1322 +Found:Indirect-related GlobalIntVar(ButtonGraphics):200 +Found:Indirect-related GlobalIntVar(ButtonGraphics):547 +Found:Indirect-related GlobalStringVar(InfoString):32 +Found:Indirect-related GlobalStringVar(InfoString):277 +Found:Indirect-related GlobalIntVar(ButtonGraphics):994 +Found:Indirect-related GlobalIntVar(ButtonGraphics):986 +Found:Indirect-related GlobalIntVar(ButtonGraphics):177 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1092 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1510 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1276 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1275 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1315 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1316 +Found:Indirect-related GlobalIntVar(ButtonGraphics):998 +Found:Indirect-related GlobalIntVar(ButtonGraphics):999 +Found:Indirect-related GlobalStringVar(InfoString):278 +Found:Indirect-related GlobalStringVar(InfoString):349 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1098 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1507 +Found:Indirect-related GlobalIntVar(ButtonGraphics):178 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1508 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1509 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1125 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1123 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1274 +Found:Indirect-related GlobalIntVar(ButtonGraphics):176 +Found:Indirect-related GlobalIntVar(ButtonGraphics):533 +Found:Indirect-related GlobalIntVar(ButtonGraphics):523 +Found:Indirect-related GlobalIntVar(ButtonGraphics):534 +Found:Indirect-related GlobalIntVar(ButtonGraphics):524 +Found:Indirect-related GlobalIntVar(ButtonGraphics):535 +Found:Indirect-related GlobalIntVar(ButtonGraphics):525 +Found:Indirect-related GlobalIntVar(ButtonGraphics):536 +Found:Indirect-related GlobalIntVar(ButtonGraphics):526 +Found:Indirect-related GlobalIntVar(ButtonGraphics):537 +Found:Indirect-related GlobalIntVar(ButtonGraphics):527 +Found:Indirect-related GlobalIntVar(ButtonGraphics):538 +Found:Indirect-related GlobalIntVar(ButtonGraphics):528 +Found:Indirect-related GlobalIntVar(ButtonGraphics):539 +Found:Indirect-related GlobalIntVar(ButtonGraphics):529 +Found:Indirect-related GlobalIntVar(ButtonGraphics):540 +Found:Indirect-related GlobalIntVar(ButtonGraphics):530 +Found:Indirect-related GlobalIntVar(ButtonGraphics):541 +Found:Indirect-related GlobalIntVar(ButtonGraphics):531 +Found:Indirect-related GlobalIntVar(ButtonGraphics):542 +Found:Indirect-related GlobalIntVar(ButtonGraphics):532 +Hidden child:24 +Hidden child:25 +Hidden child:26 +Hidden child:29 +Hidden child:30 +Hidden child:40 +Hidden child:41 +Hidden child:42 +Hidden child:43 +Hidden child:44 +Hidden child:45 +Hidden child:46 +Hidden child:55 +Hidden child:56 +Hidden child:152 +Hidden child:185 +Hidden child:186 +Hidden child:187 +Hidden child:188 +Hidden child:189 +Hidden child:190 +Hidden child:220 +Hidden child:236 +Hidden child:242 +INTERFACE:907 +Hidden child:12 +Hidden child:13 +Hidden child:24 +Hidden child:25 +Hidden child:36 +Hidden child:37 +Hidden child:50 +Hidden child:51 +INTERFACE:908 +Hidden child:2 +Hidden child:3 +Hidden child:4 +Hidden child:5 +Hidden child:6 +Hidden child:7 +Hidden child:8 +Hidden child:9 +Hidden child:15 +Hidden child:30 +Hidden child:34 +Hidden child:36 +INTERFACE:909 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1097 +Found:Indirect-related GlobalStringVar(InfoString):277 +Found:Indirect-related GlobalStringVar(InfoString):278 +Found:Indirect-related GlobalStringVar(InfoString):349 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):6 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1094 +Found:Indirect-related GlobalStringVar(InfoString):279 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Hidden child:32 +Hidden child:43 +Hidden child:80 +Hidden child:85 +INTERFACE:910 +Hidden child:13 +Hidden child:14 +Hidden child:19 +Hidden child:65 +Hidden child:66 +Hidden child:67 +INTERFACE:911 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1394 +Hidden child:3 +Hidden child:23 +Hidden child:50 +Hidden child:59 +INTERFACE:912 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Indirect-related GlobalIntVar(ButtonGraphics):6 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1094 +Found:Indirect-related GlobalStringVar(InfoString):279 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1097 +Found:Indirect-related GlobalStringVar(InfoString):277 +Found:Indirect-related GlobalStringVar(InfoString):278 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Hidden child:2 +Hidden child:26 +Hidden child:31 +Hidden child:44 +Hidden child:48 +INTERFACE:913 +Found:Related GlobalIntVar(ButtonGraphics):1094 +Found:Related GlobalStringVar(InfoString):279 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1097 +Found:Indirect-related GlobalStringVar(InfoString):277 +Found:Indirect-related GlobalStringVar(InfoString):278 +Found:Indirect-related GlobalStringVar(InfoString):349 +Hidden child:2 +INTERFACE:914 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1094 +Found:Indirect-related GlobalStringVar(InfoString):277 +Found:Indirect-related GlobalStringVar(InfoString):278 +Found:Related GlobalIntVar(ButtonGraphics):6 +Hidden child:21 +Hidden child:28 +INTERFACE:915 +Found:Indirect-related GlobalIntVar(ButtonGraphics):6 +Found:Indirect-related GlobalStringVar(InfoString):279 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1094 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1097 +Found:Indirect-related GlobalStringVar(InfoString):277 +Found:Indirect-related GlobalStringVar(InfoString):278 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):349 +Hidden child:102 +INTERFACE:916 +Hidden child:5 +Hidden child:6 +Hidden child:7 +Hidden child:8 +INTERFACE:917 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1419 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1418 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1420 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1960, bitoffs:25, length:25 +Found:Indirect-related BITconfig:ID:1960, bitoffs:27, length:27 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1429 +Found:Indirect-related BITconfig:ID:2083, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:1958, bitoffs:0, length:11 +Found:Related BITconfig:ID:1961, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:1960, bitoffs:0, length:6 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1422 +Found:Indirect-related BITconfig:ID:1960, bitoffs:7, length:18 +Found:Indirect-related BITconfig:ID:1562, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:1562, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1562, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:1562, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1562, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1562, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:1562, bitoffs:7, length:7 +Found:Indirect-related BITconfig:ID:1562, bitoffs:8, length:8 +Found:Indirect-related BITconfig:ID:1562, bitoffs:9, length:9 +Found:Indirect-related BITconfig:ID:1562, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:1562, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:1562, bitoffs:12, length:12 +Found:Indirect-related BITconfig:ID:1562, bitoffs:13, length:13 +Found:Indirect-related BITconfig:ID:1562, bitoffs:14, length:14 +Found:Indirect-related BITconfig:ID:1562, bitoffs:15, length:15 +Found:Indirect-related BITconfig:ID:1562, bitoffs:16, length:16 +Found:Indirect-related BITconfig:ID:1562, bitoffs:17, length:17 +Found:Indirect-related BITconfig:ID:1562, bitoffs:18, length:18 +Found:Indirect-related BITconfig:ID:1562, bitoffs:19, length:19 +Found:Indirect-related BITconfig:ID:1562, bitoffs:20, length:20 +Found:Indirect-related BITconfig:ID:1562, bitoffs:21, length:21 +Found:Indirect-related BITconfig:ID:1562, bitoffs:22, length:22 +Found:Indirect-related BITconfig:ID:1562, bitoffs:23, length:23 +Found:Indirect-related BITconfig:ID:1563, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:1563, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:1563, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1563, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:1563, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1563, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1563, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:1563, bitoffs:7, length:7 +Found:Indirect-related BITconfig:ID:1563, bitoffs:8, length:8 +Found:Indirect-related BITconfig:ID:1563, bitoffs:9, length:9 +Found:Indirect-related BITconfig:ID:1563, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:1563, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:1563, bitoffs:12, length:12 +Found:Indirect-related BITconfig:ID:1563, bitoffs:13, length:13 +Found:Indirect-related BITconfig:ID:1563, bitoffs:14, length:14 +Found:Indirect-related BITconfig:ID:1563, bitoffs:15, length:15 +Found:Indirect-related BITconfig:ID:1564, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:1564, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:1564, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1564, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:1564, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1564, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1564, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:1564, bitoffs:7, length:7 +Found:Indirect-related BITconfig:ID:1564, bitoffs:8, length:8 +Found:Indirect-related BITconfig:ID:1564, bitoffs:9, length:9 +Found:Indirect-related BITconfig:ID:1564, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:1564, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:1564, bitoffs:12, length:12 +Found:Indirect-related BITconfig:ID:1564, bitoffs:13, length:13 +Found:Indirect-related BITconfig:ID:1564, bitoffs:14, length:14 +Found:Indirect-related BITconfig:ID:1564, bitoffs:15, length:15 +Found:Indirect-related BITconfig:ID:1564, bitoffs:16, length:16 +Found:Indirect-related BITconfig:ID:1565, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:1565, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1565, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:1565, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1565, bitoffs:5, length:10 +Found:Indirect-related BITconfig:ID:1256, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:1256, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:1256, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1256, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:1256, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1256, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1256, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:1256, bitoffs:7, length:7 +Found:Indirect-related BITconfig:ID:1256, bitoffs:8, length:8 +Found:Indirect-related BITconfig:ID:1256, bitoffs:9, length:9 +Found:Indirect-related BITconfig:ID:1256, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:1256, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:1256, bitoffs:12, length:12 +Found:Indirect-related BITconfig:ID:1256, bitoffs:13, length:13 +Found:Indirect-related BITconfig:ID:1256, bitoffs:14, length:14 +Found:Indirect-related BITconfig:ID:1256, bitoffs:15, length:15 +Found:Indirect-related BITconfig:ID:1256, bitoffs:16, length:16 +Found:Indirect-related BITconfig:ID:1256, bitoffs:17, length:17 +Found:Indirect-related BITconfig:ID:1256, bitoffs:18, length:18 +Found:Indirect-related BITconfig:ID:1256, bitoffs:19, length:19 +Found:Indirect-related BITconfig:ID:1256, bitoffs:20, length:20 +Found:Indirect-related BITconfig:ID:1256, bitoffs:21, length:21 +Found:Indirect-related BITconfig:ID:1256, bitoffs:22, length:22 +Found:Indirect-related BITconfig:ID:1257, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:1257, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:1257, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1257, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:1257, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1257, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1257, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:1257, bitoffs:7, length:7 +Found:Indirect-related BITconfig:ID:1257, bitoffs:8, length:8 +Found:Indirect-related BITconfig:ID:1257, bitoffs:9, length:9 +Found:Indirect-related BITconfig:ID:1257, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:1257, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:1257, bitoffs:12, length:12 +Found:Indirect-related BITconfig:ID:1257, bitoffs:13, length:13 +Found:Indirect-related BITconfig:ID:1257, bitoffs:14, length:14 +Found:Indirect-related BITconfig:ID:1257, bitoffs:15, length:15 +Found:Indirect-related BITconfig:ID:1257, bitoffs:16, length:16 +Found:Indirect-related BITconfig:ID:1257, bitoffs:17, length:17 +Found:Indirect-related BITconfig:ID:1257, bitoffs:19, length:19 +Found:Indirect-related BITconfig:ID:1258, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:1258, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:1258, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1258, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:1258, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1258, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1258, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:1258, bitoffs:7, length:7 +Found:Indirect-related BITconfig:ID:1258, bitoffs:8, length:8 +Found:Indirect-related BITconfig:ID:1258, bitoffs:9, length:9 +Found:Indirect-related BITconfig:ID:1258, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:1258, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:1886, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:1886, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:1886, bitoffs:8, length:8 +Found:Indirect-related BITconfig:ID:1886, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:1886, bitoffs:12, length:12 +Found:Indirect-related BITconfig:ID:1886, bitoffs:13, length:13 +Found:Indirect-related BITconfig:ID:1886, bitoffs:14, length:14 +Found:Indirect-related BITconfig:ID:1360, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1360, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1360, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:1360, bitoffs:7, length:7 +Found:Indirect-related BITconfig:ID:1360, bitoffs:8, length:8 +Found:Indirect-related BITconfig:ID:1360, bitoffs:9, length:9 +Found:Indirect-related BITconfig:ID:1360, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:1360, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:1360, bitoffs:12, length:12 +Found:Indirect-related BITconfig:ID:1360, bitoffs:13, length:13 +Found:Indirect-related BITconfig:ID:1360, bitoffs:14, length:14 +Found:Indirect-related BITconfig:ID:1360, bitoffs:15, length:15 +Found:Indirect-related BITconfig:ID:1360, bitoffs:16, length:16 +Found:Indirect-related BITconfig:ID:1360, bitoffs:17, length:17 +Found:Indirect-related BITconfig:ID:1360, bitoffs:18, length:19 +Found:Indirect-related BITconfig:ID:1360, bitoffs:20, length:20 +Found:Indirect-related BITconfig:ID:1360, bitoffs:21, length:21 +Found:Indirect-related BITconfig:ID:1361, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:1360, bitoffs:23, length:24 +Found:Indirect-related BITconfig:ID:1360, bitoffs:25, length:25 +Found:Indirect-related BITconfig:ID:1360, bitoffs:26, length:26 +Found:Indirect-related BITconfig:ID:1360, bitoffs:27, length:27 +Found:Indirect-related BITconfig:ID:1360, bitoffs:28, length:28 +Found:Indirect-related BITconfig:ID:1360, bitoffs:29, length:29 +Found:Indirect-related BITconfig:ID:1360, bitoffs:30, length:30 +Found:Indirect-related BITconfig:ID:1360, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1361, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:1361, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:1361, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1361, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:1361, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1361, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1360, bitoffs:22, length:22 +Found:Indirect-related BITconfig:ID:1361, bitoffs:7, length:7 +Found:Indirect-related BITconfig:ID:1361, bitoffs:8, length:8 +Found:Indirect-related BITconfig:ID:1361, bitoffs:9, length:9 +Found:Indirect-related BITconfig:ID:1361, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:1361, bitoffs:19, length:19 +Found:Indirect-related BITconfig:ID:1361, bitoffs:20, length:20 +Found:Indirect-related BITconfig:ID:1361, bitoffs:21, length:21 +Found:Indirect-related BITconfig:ID:1361, bitoffs:22, length:22 +Found:Indirect-related BITconfig:ID:1361, bitoffs:23, length:23 +Found:Indirect-related BITconfig:ID:1361, bitoffs:24, length:24 +Found:Indirect-related BITconfig:ID:1361, bitoffs:25, length:25 +Found:Indirect-related BITconfig:ID:1358, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:1358, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:1358, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1358, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:1358, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1358, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1358, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:1358, bitoffs:7, length:7 +Found:Indirect-related BITconfig:ID:1358, bitoffs:8, length:8 +Found:Indirect-related BITconfig:ID:1358, bitoffs:9, length:9 +Found:Indirect-related BITconfig:ID:1358, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:1358, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:1358, bitoffs:12, length:12 +Found:Indirect-related BITconfig:ID:1358, bitoffs:13, length:13 +Found:Indirect-related BITconfig:ID:1358, bitoffs:14, length:14 +Found:Indirect-related BITconfig:ID:1358, bitoffs:15, length:15 +Found:Indirect-related BITconfig:ID:1358, bitoffs:16, length:16 +Found:Indirect-related BITconfig:ID:1358, bitoffs:17, length:17 +Found:Indirect-related BITconfig:ID:1358, bitoffs:18, length:18 +Found:Indirect-related BITconfig:ID:1358, bitoffs:19, length:19 +Found:Indirect-related BITconfig:ID:1358, bitoffs:20, length:20 +Found:Indirect-related BITconfig:ID:1358, bitoffs:21, length:21 +Found:Indirect-related BITconfig:ID:1358, bitoffs:22, length:22 +Found:Indirect-related BITconfig:ID:1358, bitoffs:23, length:23 +Found:Indirect-related BITconfig:ID:1358, bitoffs:24, length:24 +Found:Indirect-related BITconfig:ID:1358, bitoffs:25, length:25 +Found:Indirect-related BITconfig:ID:1358, bitoffs:26, length:26 +Found:Indirect-related BITconfig:ID:1358, bitoffs:27, length:27 +Found:Indirect-related BITconfig:ID:1358, bitoffs:28, length:28 +Found:Indirect-related BITconfig:ID:1358, bitoffs:29, length:29 +Found:Indirect-related BITconfig:ID:2088, bitoffs:18, length:21 +Found:Indirect-related BITconfig:ID:1359, bitoffs:18, length:18 +Found:Indirect-related BITconfig:ID:1359, bitoffs:19, length:19 +Found:Indirect-related BITconfig:ID:1359, bitoffs:20, length:20 +Found:Indirect-related BITconfig:ID:1359, bitoffs:21, length:21 +Found:Indirect-related BITconfig:ID:1359, bitoffs:22, length:22 +Found:Indirect-related BITconfig:ID:1359, bitoffs:23, length:23 +Found:Indirect-related BITconfig:ID:1359, bitoffs:24, length:24 +Found:Indirect-related BITconfig:ID:1359, bitoffs:25, length:25 +Found:Indirect-related BITconfig:ID:1359, bitoffs:26, length:26 +Found:Indirect-related BITconfig:ID:1000, bitoffs:0, length:2 +Found:Indirect-related BITconfig:ID:1000, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:1000, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1000, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1000, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:1000, bitoffs:7, length:7 +Found:Indirect-related BITconfig:ID:1000, bitoffs:8, length:8 +Found:Indirect-related BITconfig:ID:1000, bitoffs:9, length:11 +Found:Indirect-related BITconfig:ID:1000, bitoffs:12, length:12 +Found:Indirect-related BITconfig:ID:1000, bitoffs:13, length:13 +Found:Indirect-related BITconfig:ID:1001, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:1001, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:1001, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1001, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:1001, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1001, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1001, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:1001, bitoffs:7, length:7 +Found:Indirect-related BITconfig:ID:1001, bitoffs:8, length:8 +Found:Indirect-related BITconfig:ID:1001, bitoffs:9, length:9 +Found:Indirect-related BITconfig:ID:1001, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:1001, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:1001, bitoffs:12, length:12 +Found:Indirect-related BITconfig:ID:1001, bitoffs:13, length:13 +Found:Indirect-related BITconfig:ID:1001, bitoffs:14, length:14 +Found:Indirect-related BITconfig:ID:1001, bitoffs:15, length:15 +Found:Indirect-related BITconfig:ID:1001, bitoffs:16, length:16 +Found:Indirect-related BITconfig:ID:1001, bitoffs:17, length:17 +Found:Indirect-related BITconfig:ID:1001, bitoffs:18, length:18 +Found:Indirect-related BITconfig:ID:1002, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:1002, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:1002, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1002, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:1002, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1002, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1002, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:1002, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1002, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:1002, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:1000, bitoffs:14, length:14 +Found:Indirect-related BITconfig:ID:1000, bitoffs:15, length:15 +Found:Indirect-related BITconfig:ID:1000, bitoffs:16, length:16 +Found:Indirect-related BITconfig:ID:1000, bitoffs:17, length:17 +Found:Indirect-related BITconfig:ID:1000, bitoffs:18, length:18 +Found:Indirect-related BITconfig:ID:1000, bitoffs:19, length:19 +Found:Indirect-related BITconfig:ID:1000, bitoffs:20, length:20 +Found:Indirect-related BITconfig:ID:1000, bitoffs:21, length:21 +Found:Indirect-related BITconfig:ID:1372, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1372, bitoffs:7, length:8 +Found:Indirect-related BITconfig:ID:1372, bitoffs:9, length:9 +Found:Indirect-related BITconfig:ID:1372, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:1372, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:1372, bitoffs:12, length:14 +Found:Indirect-related BITconfig:ID:1372, bitoffs:15, length:17 +Found:Indirect-related BITconfig:ID:1372, bitoffs:18, length:20 +Found:Indirect-related BITconfig:ID:1372, bitoffs:21, length:21 +Found:Indirect-related BITconfig:ID:1372, bitoffs:22, length:22 +Found:Indirect-related BITconfig:ID:1372, bitoffs:23, length:23 +Found:Indirect-related BITconfig:ID:1372, bitoffs:24, length:24 +Found:Indirect-related BITconfig:ID:1372, bitoffs:29, length:29 +Found:Indirect-related BITconfig:ID:1372, bitoffs:30, length:30 +Found:Indirect-related BITconfig:ID:1372, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1373, bitoffs:0, length:3 +Found:Indirect-related BITconfig:ID:1373, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1373, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1373, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:1373, bitoffs:7, length:7 +Found:Indirect-related BITconfig:ID:1373, bitoffs:8, length:8 +Found:Indirect-related BITconfig:ID:1373, bitoffs:9, length:9 +Found:Indirect-related BITconfig:ID:1373, bitoffs:10, length:11 +Found:Indirect-related BITconfig:ID:1373, bitoffs:12, length:15 +Found:Indirect-related BITconfig:ID:1373, bitoffs:16, length:16 +Found:Indirect-related BITconfig:ID:1373, bitoffs:17, length:19 +Found:Indirect-related BITconfig:ID:1373, bitoffs:20, length:20 +Found:Indirect-related BITconfig:ID:1373, bitoffs:21, length:21 +Found:Indirect-related BITconfig:ID:1373, bitoffs:26, length:26 +Found:Indirect-related BITconfig:ID:1373, bitoffs:27, length:27 +Found:Indirect-related BITconfig:ID:1373, bitoffs:28, length:28 +Found:Indirect-related BITconfig:ID:1373, bitoffs:29, length:29 +Found:Indirect-related BITconfig:ID:1374, bitoffs:0, length:2 +Found:Indirect-related BITconfig:ID:1374, bitoffs:3, length:5 +Found:Indirect-related BITconfig:ID:1374, bitoffs:6, length:8 +Found:Indirect-related BITconfig:ID:1887, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:1887, bitoffs:7, length:7 +Found:Indirect-related BITconfig:ID:1887, bitoffs:12, length:12 +Found:Indirect-related BITconfig:ID:1887, bitoffs:16, length:16 +Found:Indirect-related BITconfig:ID:1887, bitoffs:19, length:19 +Found:Indirect-related BITconfig:ID:1071, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:1071, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:1071, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1071, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:1071, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1071, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1071, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:1071, bitoffs:7, length:7 +Found:Indirect-related BITconfig:ID:1071, bitoffs:8, length:8 +Found:Indirect-related BITconfig:ID:1071, bitoffs:9, length:9 +Found:Indirect-related BITconfig:ID:1071, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:1071, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:1071, bitoffs:12, length:12 +Found:Indirect-related BITconfig:ID:1071, bitoffs:13, length:13 +Found:Indirect-related BITconfig:ID:1071, bitoffs:14, length:14 +Found:Indirect-related BITconfig:ID:1071, bitoffs:15, length:15 +Found:Indirect-related BITconfig:ID:1071, bitoffs:16, length:16 +Found:Indirect-related BITconfig:ID:1071, bitoffs:18, length:18 +Found:Indirect-related BITconfig:ID:1071, bitoffs:19, length:19 +Found:Indirect-related BITconfig:ID:1071, bitoffs:17, length:17 +Found:Indirect-related BITconfig:ID:1072, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1072, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:1072, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1072, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1072, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:1072, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1072, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:1072, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:1072, bitoffs:12, length:12 +Found:Indirect-related BITconfig:ID:1072, bitoffs:13, length:13 +Found:Indirect-related BITconfig:ID:1072, bitoffs:14, length:14 +Found:Indirect-related BITconfig:ID:1072, bitoffs:15, length:15 +Found:Indirect-related BITconfig:ID:1072, bitoffs:16, length:16 +Found:Indirect-related BITconfig:ID:1072, bitoffs:17, length:17 +Found:Indirect-related BITconfig:ID:1072, bitoffs:18, length:18 +Found:Indirect-related BITconfig:ID:1072, bitoffs:19, length:19 +Found:Indirect-related BITconfig:ID:1072, bitoffs:20, length:20 +Found:Indirect-related BITconfig:ID:1072, bitoffs:21, length:21 +Found:Indirect-related BITconfig:ID:1072, bitoffs:22, length:22 +Found:Indirect-related BITconfig:ID:1072, bitoffs:23, length:23 +Found:Indirect-related BITconfig:ID:1073, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:1073, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:1073, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1073, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:1073, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1073, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1073, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:1073, bitoffs:7, length:7 +Found:Indirect-related BITconfig:ID:1073, bitoffs:8, length:8 +Found:Indirect-related BITconfig:ID:1073, bitoffs:9, length:9 +Found:Indirect-related BITconfig:ID:1073, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:1073, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:1073, bitoffs:12, length:12 +Found:Indirect-related BITconfig:ID:1073, bitoffs:13, length:13 +Found:Indirect-related BITconfig:ID:1073, bitoffs:14, length:14 +Found:Indirect-related BITconfig:ID:1073, bitoffs:15, length:15 +Found:Indirect-related BITconfig:ID:1073, bitoffs:16, length:16 +Found:Indirect-related BITconfig:ID:1073, bitoffs:17, length:17 +Found:Indirect-related BITconfig:ID:1073, bitoffs:18, length:18 +Found:Indirect-related BITconfig:ID:1073, bitoffs:22, length:22 +Found:Indirect-related BITconfig:ID:1073, bitoffs:23, length:23 +Found:Indirect-related BITconfig:ID:1073, bitoffs:25, length:25 +Found:Indirect-related BITconfig:ID:1956, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:1956, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:1956, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1956, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:1956, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1956, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1956, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:1956, bitoffs:8, length:8 +Found:Indirect-related BITconfig:ID:1956, bitoffs:9, length:9 +Found:Indirect-related BITconfig:ID:1956, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:1956, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:1956, bitoffs:12, length:12 +Found:Indirect-related BITconfig:ID:1956, bitoffs:13, length:13 +Found:Indirect-related BITconfig:ID:1956, bitoffs:14, length:14 +Found:Indirect-related BITconfig:ID:1956, bitoffs:15, length:15 +Found:Indirect-related BITconfig:ID:1956, bitoffs:16, length:16 +Found:Indirect-related BITconfig:ID:1956, bitoffs:17, length:17 +Found:Indirect-related BITconfig:ID:1956, bitoffs:18, length:18 +Found:Indirect-related BITconfig:ID:1956, bitoffs:19, length:19 +Found:Indirect-related BITconfig:ID:1956, bitoffs:20, length:20 +Found:Indirect-related BITconfig:ID:1956, bitoffs:21, length:21 +Found:Indirect-related BITconfig:ID:1956, bitoffs:22, length:22 +Found:Indirect-related BITconfig:ID:1956, bitoffs:23, length:23 +Found:Indirect-related BITconfig:ID:1956, bitoffs:24, length:24 +Found:Indirect-related BITconfig:ID:1956, bitoffs:25, length:25 +Found:Indirect-related BITconfig:ID:1956, bitoffs:26, length:26 +Found:Indirect-related BITconfig:ID:1956, bitoffs:27, length:27 +Found:Indirect-related BITconfig:ID:1956, bitoffs:28, length:28 +Found:Indirect-related BITconfig:ID:1956, bitoffs:29, length:29 +Found:Indirect-related BITconfig:ID:1956, bitoffs:30, length:30 +Found:Indirect-related BITconfig:ID:1956, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1957, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:1957, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:1957, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1957, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:1957, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1957, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1957, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:1957, bitoffs:7, length:7 +Found:Indirect-related BITconfig:ID:1957, bitoffs:8, length:8 +Found:Indirect-related BITconfig:ID:1957, bitoffs:9, length:9 +Found:Indirect-related BITconfig:ID:1957, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:1957, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:1957, bitoffs:12, length:12 +Found:Indirect-related BITconfig:ID:1957, bitoffs:25, length:25 +Found:Indirect-related BITconfig:ID:1957, bitoffs:26, length:26 +Found:Indirect-related BITconfig:ID:1957, bitoffs:13, length:13 +Found:Indirect-related BITconfig:ID:1957, bitoffs:14, length:14 +Found:Indirect-related BITconfig:ID:1957, bitoffs:15, length:15 +Found:Indirect-related BITconfig:ID:1957, bitoffs:16, length:16 +Found:Indirect-related BITconfig:ID:1957, bitoffs:17, length:17 +Found:Indirect-related BITconfig:ID:1957, bitoffs:18, length:18 +Found:Indirect-related BITconfig:ID:1957, bitoffs:19, length:19 +Found:Indirect-related BITconfig:ID:1957, bitoffs:20, length:20 +Found:Indirect-related BITconfig:ID:1957, bitoffs:21, length:21 +Found:Indirect-related BITconfig:ID:1957, bitoffs:22, length:22 +Found:Indirect-related BITconfig:ID:1957, bitoffs:23, length:23 +Found:Indirect-related BITconfig:ID:1957, bitoffs:24, length:24 +Found:Indirect-related BITconfig:ID:1957, bitoffs:27, length:27 +Found:Indirect-related BITconfig:ID:1261, bitoffs:0, length:2 +Found:Indirect-related BITconfig:ID:2082, bitoffs:5, length:6 +Found:Indirect-related BITconfig:ID:2082, bitoffs:9, length:9 +Found:Indirect-related BITconfig:ID:2082, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:2082, bitoffs:13, length:13 +Found:Indirect-related BITconfig:ID:2082, bitoffs:14, length:14 +Found:Indirect-related BITconfig:ID:2082, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:2082, bitoffs:2, length:3 +Found:Indirect-related BITconfig:ID:2082, bitoffs:15, length:15 +Found:Indirect-related BITconfig:ID:2082, bitoffs:22, length:22 +Found:Indirect-related BITconfig:ID:2082, bitoffs:16, length:16 +Found:Indirect-related BITconfig:ID:2082, bitoffs:17, length:17 +Found:Indirect-related BITconfig:ID:2082, bitoffs:18, length:18 +Found:Indirect-related BITconfig:ID:2082, bitoffs:19, length:19 +Found:Indirect-related BITconfig:ID:2082, bitoffs:20, length:20 +Found:Indirect-related BITconfig:ID:2082, bitoffs:21, length:21 +Found:Indirect-related BITconfig:ID:1957, bitoffs:28, length:28 +Found:Indirect-related BITconfig:ID:1957, bitoffs:29, length:29 +Found:Indirect-related BITconfig:ID:1957, bitoffs:30, length:30 +Found:Indirect-related BITconfig:ID:1957, bitoffs:31, length:31 +Found:Indirect-related config:63 +Found:Indirect-related config:165 +Found:Indirect-related config:68 +Found:Indirect-related config:180 +Found:Indirect-related config:30 +Found:Indirect-related config:212 +Found:Indirect-related config:159 +Found:Indirect-related config:139 +Found:Indirect-related config:365 +Found:Indirect-related config:492 +Found:Indirect-related config:107 +Found:Indirect-related config:29 +Found:Indirect-related config:176 +Found:Indirect-related config:122 +Found:Indirect-related config:347 +Found:Indirect-related config:76 +Found:Indirect-related config:116 +Found:Indirect-related config:175 +Found:Indirect-related config:320 +Found:Indirect-related config:150 +Found:Indirect-related config:192 +Found:Indirect-related config:416 +Found:Indirect-related config:148 +Found:Indirect-related config:101 +Found:Indirect-related config:111 +Found:Indirect-related config:451 +Found:Indirect-related config:1199 +Found:Indirect-related config:302 +Found:Indirect-related config:339 +Found:Indirect-related config:273 +Found:Indirect-related BITconfig:ID:977, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1303, bitoffs:21, length:21 +Found:Indirect-related BITconfig:ID:1178, bitoffs:1, length:10 +Found:Indirect-related BITconfig:ID:810, bitoffs:9, length:9 +Found:Indirect-related BITconfig:ID:1204, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:912, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:635, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:1274, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:823, bitoffs:0, length:19 +Found:Indirect-related BITconfig:ID:1077, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:313, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:1190, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:177, bitoffs:15, length:15 +Found:Indirect-related BITconfig:ID:553, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:571, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:607, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:496, bitoffs:0, length:2 +Found:Indirect-related BITconfig:ID:874, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1577, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:77, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:1023, bitoffs:17, length:18 +Found:Indirect-related BITconfig:ID:1023, bitoffs:0, length:1 +Found:Indirect-related BITconfig:ID:730, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:1023, bitoffs:15, length:16 +Found:Indirect-related BITconfig:ID:1023, bitoffs:11, length:12 +Found:Indirect-related BITconfig:ID:1588, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1330, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:299, bitoffs:20, length:20 +Found:Indirect-related BITconfig:ID:1050, bitoffs:1, length:4 +Found:Indirect-related BITconfig:ID:992, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:802, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:802, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:802, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:802, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:709, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1010, bitoffs:12, length:12 +Found:Indirect-related BITconfig:ID:440, bitoffs:0, length:14 +Found:Indirect-related BITconfig:ID:1600, bitoffs:0, length:3 +Found:Indirect-related BITconfig:ID:1282, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:449, bitoffs:22, length:31 +Found:Indirect-related BITconfig:ID:1303, bitoffs:16, length:19 +Found:Indirect-related BITconfig:ID:1303, bitoffs:10, length:15 +Found:Indirect-related BITconfig:ID:1386, bitoffs:18, length:19 +Found:Indirect-related BITconfig:ID:1289, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:1289, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:1289, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:714, bitoffs:3, length:6 +Found:Indirect-related BITconfig:ID:1242, bitoffs:1, length:31 +Found:Indirect-related BITconfig:ID:1049, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1261, bitoffs:3, length:4 +Found:Indirect-related config:131 +Found:Indirect-related config:223 +Found:Indirect-related config:14 +Found:Indirect-related config:112 +Found:Indirect-related config:145 +Found:Indirect-related config:146 +Found:Indirect-related config:26 +Found:Indirect-related BITconfig:ID:1311, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:222, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1403, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:705, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:604, bitoffs:0, length:2 +Found:Indirect-related BITconfig:ID:568, bitoffs:0, length:6 +Found:Indirect-related config:2068 +Found:Indirect-related config:450 +Found:Indirect-related config:130 +Found:Indirect-related config:31 +Found:Indirect-related config:32 +Found:Indirect-related config:160 +Found:Indirect-related config:71 +Found:Indirect-related config:293 +Found:Indirect-related config:655 +Found:Indirect-related config:10 +Found:Indirect-related config:399 +Found:Indirect-related config:314 +Found:Indirect-related config:80 +Found:Indirect-related config:0 +Found:Indirect-related config:335 +Found:Indirect-related config:299 +Found:Indirect-related config:17 +Found:Indirect-related config:11 +Found:Indirect-related config:65 +Found:Indirect-related config:382 +Found:Indirect-related config:188 +Found:Indirect-related config:5 +Found:Indirect-related config:387 +Found:Indirect-related config:147 +Found:Indirect-related config:517 +Found:Indirect-related config:307 +Found:Indirect-related config:328 +Found:Indirect-related config:402 +Found:Indirect-related config:600 +Found:Indirect-related config:60 +Found:Indirect-related config:359 +Found:Indirect-related config:197 +Found:Indirect-related config:226 +Found:Indirect-related config:200 +Found:Indirect-related config:385 +Found:Indirect-related config:317 +Found:Indirect-related config:161 +Found:Indirect-related config:162 +Found:Indirect-related config:980 +Found:Indirect-related BITconfig:ID:62, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:178, bitoffs:0, length:1 +Found:Indirect-related BITconfig:ID:939, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:433, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:964, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:455, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:400, bitoffs:23, length:23 +Found:Indirect-related BITconfig:ID:869, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:794, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:622, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:934, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:896, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:641, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:844, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:671, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:810, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:435, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:521, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:408, bitoffs:28, length:31 +Found:Indirect-related BITconfig:ID:482, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:437, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:351, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:445, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:465, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:423, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:574, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:905, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:714, bitoffs:0, length:2 +Found:Indirect-related BITconfig:ID:678, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:602, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:616, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:723, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:449, bitoffs:0, length:1 +Found:Indirect-related BITconfig:ID:968, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:970, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:994, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:997, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:1003, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1016, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1063, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:1094, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1165, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:1184, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:1218, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:1225, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1227, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1232, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1236, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:1271, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:1306, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1370, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1365, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:1407, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:1415, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1475, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1420, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1390, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1327, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1819, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:1498, bitoffs:0, length:15 +Found:Indirect-related BITconfig:ID:1558, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:1610, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1811, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1849, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1646, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1844, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1834, bitoffs:28, length:31 +Found:Indirect-related BITconfig:ID:1861, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:2037, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1906, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1889, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:2217, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:2020, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:2046, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:2051, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:2079, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:2208, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:2234, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:2376, bitoffs:0, length:7 +Found:Related GlobalIntVar(ButtonGraphics):1423 +Found:Related GlobalIntVar(ButtonGraphics):1424 +Hidden child:82 +Hidden child:83 +Hidden child:84 +Hidden child:86 +Hidden child:92 +Hidden child:102 +Hidden child:119 +INTERFACE:918 +Found:Related config:1652 +Found:Related config:1653 +Found:Related config:1654 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:919 +INTERFACE:920 +Found:Indirect-related BITconfig:ID:1661, bitoffs:4, length:8 +Found:Indirect-related BITconfig:ID:1661, bitoffs:9, length:13 +Found:Indirect-related BITconfig:ID:1661, bitoffs:14, length:18 +Found:Indirect-related BITconfig:ID:1661, bitoffs:19, length:23 +Found:Indirect-related BITconfig:ID:1661, bitoffs:24, length:28 +Found:Indirect-related BITconfig:ID:1660, bitoffs:18, length:21 +Found:Indirect-related BITconfig:ID:1664, bitoffs:20, length:23 +Found:Indirect-related BITconfig:ID:1661, bitoffs:0, length:3 +Found:Indirect-related BITconfig:ID:1660, bitoffs:12, length:14 +Found:Indirect-related BITconfig:ID:1660, bitoffs:15, length:17 +Found:Indirect-related BITconfig:ID:1662, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:1662, bitoffs:10, length:19 +Found:Indirect-related BITconfig:ID:1662, bitoffs:20, length:29 +Found:Indirect-related BITconfig:ID:1661, bitoffs:29, length:31 +INTERFACE:921 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:922 +Hidden child:10 +Hidden child:106 +Hidden child:110 +INTERFACE:923 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1111 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1112 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1113 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1114 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1115 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1116 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1117 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +INTERFACE:924 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:925 +Found:Related BITconfig:ID:1658, bitoffs:0, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:926 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:927 +Found:Related config:1674 +Found:Related config:1688 +Found:Related config:1687 +Found:Related config:1686 +Found:Related config:1681 +Found:Related BITconfig:ID:1669, bitoffs:7, length:7 +Found:Related BITconfig:ID:1669, bitoffs:8, length:8 +Found:Related BITconfig:ID:1669, bitoffs:9, length:9 +Found:Related BITconfig:ID:1670, bitoffs:0, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related BITconfig:ID:946, bitoffs:28, length:30 +Found:Related BITconfig:ID:947, bitoffs:9, length:17 +Found:Related BITconfig:ID:947, bitoffs:0, length:2 +Found:Related BITconfig:ID:948, bitoffs:19, length:27 +Found:Related BITconfig:ID:947, bitoffs:3, length:5 +Found:Related BITconfig:ID:948, bitoffs:0, length:8 +Found:Related BITconfig:ID:947, bitoffs:6, length:8 +Found:Related BITconfig:ID:948, bitoffs:9, length:18 +Found:Related BITconfig:ID:945, bitoffs:29, length:29 +Found:Related BITconfig:ID:1605, bitoffs:26, length:26 +Found:Related BITconfig:ID:1605, bitoffs:28, length:28 +Found:Related BITconfig:ID:1605, bitoffs:25, length:25 +Found:Related BITconfig:ID:1605, bitoffs:27, length:27 +INTERFACE:928 +INTERFACE:929 +Found:Related config:1693 +Found:Related config:1687 +Found:Related config:1692 +Found:Related config:1686 +Found:Related config:1694 +Found:Related config:1688 +Found:Related config:1695 +Found:Related config:1689 +Found:Related config:1697 +Found:Related config:1690 +Found:Related config:1696 +Found:Related config:1691 +Found:Related config:1698 +Found:Related BITconfig:ID:1669, bitoffs:7, length:7 +Found:Related BITconfig:ID:1669, bitoffs:8, length:8 +Found:Related BITconfig:ID:1669, bitoffs:9, length:9 +Found:Related GlobalIntVar(ButtonGraphics):1135 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related BITconfig:ID:946, bitoffs:28, length:30 +Found:Related BITconfig:ID:947, bitoffs:9, length:17 +Found:Related BITconfig:ID:947, bitoffs:0, length:2 +Found:Related BITconfig:ID:948, bitoffs:19, length:27 +Found:Related BITconfig:ID:947, bitoffs:3, length:5 +Found:Related BITconfig:ID:948, bitoffs:0, length:8 +Found:Related BITconfig:ID:947, bitoffs:6, length:8 +Found:Related BITconfig:ID:948, bitoffs:9, length:18 +Found:Related BITconfig:ID:945, bitoffs:29, length:29 +Found:Related BITconfig:ID:1605, bitoffs:26, length:26 +Found:Related BITconfig:ID:1605, bitoffs:28, length:28 +Found:Related BITconfig:ID:1605, bitoffs:25, length:25 +Found:Related BITconfig:ID:1605, bitoffs:27, length:27 +INTERFACE:930 +INTERFACE:931 +Found:Indirect-related config:1687 +Found:Indirect-related config:1688 +Found:Indirect-related config:1686 +Found:Indirect-related config:1689 +Found:Indirect-related config:1690 +Found:Indirect-related config:1691 +Found:Indirect-related config:1674 +Found:Indirect-related BITconfig:ID:1669, bitoffs:7, length:7 +Found:Indirect-related BITconfig:ID:1669, bitoffs:9, length:9 +Found:Indirect-related BITconfig:ID:1669, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1126 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1127 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1128 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1129 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1131 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1130 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1135 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1134 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1133 +Found:Related config:1675 +Found:Related config:1676 +Found:Related config:1677 +Found:Related config:1678 +Found:Related config:1680 +Found:Related config:1679 +Found:Related config:1682 +Found:Related config:1684 +Found:Related config:1683 +Found:Related config:1681 +Found:Indirect-related config:1685 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +INTERFACE:932 +Found:Related GlobalIntVar(ButtonGraphics):767 +Found:Related GlobalIntVar(ButtonGraphics):761 +Found:Related GlobalIntVar(ButtonGraphics):762 +Found:Related GlobalIntVar(ButtonGraphics):763 +Found:Related GlobalIntVar(ButtonGraphics):764 +Found:Related GlobalIntVar(ButtonGraphics):765 +Found:Related GlobalIntVar(ButtonGraphics):766 +Found:Related config:1700 +Found:Related GlobalIntVar(ButtonGraphics):1137 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:6 +Hidden child:7 +Hidden child:8 +Hidden child:9 +Hidden child:10 +Hidden child:11 +Hidden child:12 +Hidden child:13 +Hidden child:20 +Hidden child:22 +INTERFACE:933 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1198 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1208 +Found:Indirect-related GlobalStringVar(InfoString):310 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1199 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1212 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1213 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1214 +Found:Indirect-related GlobalStringVar(InfoString):311 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1200 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1215 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1216 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1217 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1218 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1219 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1220 +Found:Indirect-related GlobalStringVar(InfoString):312 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1201 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1221 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1222 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1223 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1224 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1225 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1226 +Found:Indirect-related GlobalStringVar(InfoString):313 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1202 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1227 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1228 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1229 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1230 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1231 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1232 +Found:Indirect-related GlobalStringVar(InfoString):314 +Found:Related GlobalIntVar(ButtonGraphics):1184 +Found:Related GlobalIntVar(ButtonGraphics):1185 +Found:Related GlobalIntVar(ButtonGraphics):1186 +Found:Related GlobalIntVar(ButtonGraphics):1189 +Found:Related GlobalIntVar(ButtonGraphics):1190 +Found:Related GlobalIntVar(ButtonGraphics):1397 +Found:Related GlobalIntVar(ButtonGraphics):1398 +Found:Related GlobalIntVar(ButtonGraphics):1399 +Found:Related GlobalIntVar(ButtonGraphics):1400 +Found:Related GlobalIntVar(ButtonGraphics):1401 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1191 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1320 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1196 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1188 +Found:Indirect-related BITconfig:ID:1775, bitoffs:16, length:19 +Found:Related config:1780 +Found:Related BITconfig:ID:1775, bitoffs:0, length:5 +Found:Related BITconfig:ID:1775, bitoffs:6, length:11 +Found:Related GlobalIntVar(ButtonGraphics):1195 +Found:Related GlobalIntVar(ButtonGraphics):1192 +Found:Related GlobalIntVar(ButtonGraphics):1187 +Found:Related GlobalIntVar(ButtonGraphics):1319 +Found:Related GlobalIntVar(ButtonGraphics):1270 +Found:Related GlobalIntVar(ButtonGraphics):1237 +Found:Related GlobalIntVar(ButtonGraphics):1238 +Found:Related GlobalIntVar(ButtonGraphics):1239 +Found:Related GlobalIntVar(ButtonGraphics):1236 +Found:Related GlobalIntVar(ButtonGraphics):1321 +Hidden child:84 +Hidden child:274 +Hidden child:284 +Hidden child:294 +Hidden child:297 +Hidden child:300 +Hidden child:316 +INTERFACE:934 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:1 +INTERFACE:935 +Hidden child:22 +Hidden child:26 +INTERFACE:936 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:937 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related GlobalIntVar(ButtonGraphics):1186 +Hidden child:44 +Hidden child:45 +Hidden child:46 +Hidden child:47 +Hidden child:48 +Hidden child:49 +Hidden child:50 +Hidden child:51 +Hidden child:52 +Hidden child:53 +Hidden child:54 +Hidden child:55 +Hidden child:56 +Hidden child:57 +Hidden child:58 +Hidden child:59 +Hidden child:60 +Hidden child:61 +Hidden child:62 +Hidden child:63 +Hidden child:64 +Hidden child:65 +Hidden child:68 +INTERFACE:938 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:57 +Hidden child:62 +Hidden child:67 +Hidden child:72 +Hidden child:77 +Hidden child:82 +INTERFACE:939 +Found:Related GlobalStringVar(InfoString):292 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1175 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Related GlobalStringVar(InfoString):293 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1176 +Found:Related GlobalStringVar(InfoString):294 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1177 +Found:Related GlobalStringVar(InfoString):295 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1178 +Found:Related GlobalStringVar(InfoString):296 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1179 +Found:Related GlobalIntVar(ButtonGraphics):1181 +Found:Related GlobalIntVar(ButtonGraphics):1182 +Found:Related GlobalIntVar(ButtonGraphics):1183 +Found:Related GlobalIntVar(ButtonGraphics):1180 +Hidden child:31 +Hidden child:34 +Hidden child:37 +Hidden child:38 +Hidden child:39 +Hidden child:59 +Hidden child:60 +Hidden child:62 +Hidden child:63 +Hidden child:65 +Hidden child:66 +Hidden child:68 +Hidden child:69 +Hidden child:71 +Hidden child:72 +Hidden child:88 +Hidden child:93 +INTERFACE:940 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:41 +Hidden child:42 +Hidden child:43 +Hidden child:44 +Hidden child:49 +Hidden child:67 +Hidden child:68 +INTERFACE:941 +INTERFACE:942 +Found:Related GlobalIntVar(ButtonGraphics):1149 +Found:Related GlobalIntVar(ButtonGraphics):1150 +Found:Related GlobalIntVar(ButtonGraphics):1151 +Found:Related GlobalIntVar(ButtonGraphics):1152 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:943 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:944 +Found:Related GlobalIntVar(ButtonGraphics):754 +Found:Related config:170 +Found:Related GlobalStringVar(InfoString):131 +Found:Related GlobalIntVar(ButtonGraphics):755 +Found:Related GlobalIntVar(ButtonGraphics):756 +Found:Related GlobalIntVar(ButtonGraphics):757 +Found:Related GlobalIntVar(ButtonGraphics):758 +Found:Related GlobalIntVar(ButtonGraphics):759 +Found:Related GlobalIntVar(ButtonGraphics):760 +Found:Related GlobalIntVar(ButtonGraphics):1139 +Found:Related GlobalIntVar(ButtonGraphics):1140 +Found:Related GlobalIntVar(ButtonGraphics):1141 +Found:Related GlobalIntVar(ButtonGraphics):1142 +Found:Related GlobalStringVar(InfoString):132 +Found:Related GlobalStringVar(InfoString):133 +Found:Related GlobalStringVar(InfoString):134 +Found:Related GlobalStringVar(InfoString):135 +Found:Related GlobalStringVar(InfoString):136 +Found:Related GlobalStringVar(InfoString):137 +Found:Related GlobalStringVar(InfoString):280 +Found:Related GlobalStringVar(InfoString):281 +Found:Related GlobalStringVar(InfoString):282 +Found:Related GlobalStringVar(InfoString):283 +INTERFACE:945 +Found:Related BITconfig:ID:1775, bitoffs:16, length:19 +Found:Related GlobalIntVar(ButtonGraphics):1233 +Found:Related GlobalStringVar(InfoString):315 +Hidden child:2 +INTERFACE:946 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:4 +INTERFACE:947 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:48 +Hidden child:49 +Hidden child:50 +Hidden child:51 +Hidden child:52 +Hidden child:53 +Hidden child:54 +Hidden child:55 +Hidden child:56 +Hidden child:57 +Hidden child:58 +Hidden child:59 +Hidden child:60 +Hidden child:61 +Hidden child:62 +Hidden child:63 +Hidden child:64 +Hidden child:65 +Hidden child:66 +Hidden child:67 +Hidden child:68 +Hidden child:69 +Hidden child:70 +Hidden child:71 +Hidden child:72 +Hidden child:73 +Hidden child:74 +Hidden child:75 +Hidden child:76 +Hidden child:77 +Hidden child:78 +Hidden child:79 +Hidden child:80 +Hidden child:81 +Hidden child:82 +Hidden child:83 +Hidden child:84 +Hidden child:85 +Hidden child:86 +Hidden child:87 +Hidden child:88 +Hidden child:89 +Hidden child:90 +Hidden child:91 +Hidden child:92 +Hidden child:93 +Hidden child:94 +Hidden child:95 +Hidden child:96 +Hidden child:97 +Hidden child:98 +Hidden child:99 +Hidden child:100 +Hidden child:101 +Hidden child:102 +Hidden child:103 +Hidden child:104 +Hidden child:105 +Hidden child:106 +Hidden child:107 +Hidden child:120 +Hidden child:121 +Hidden child:122 +Hidden child:123 +Hidden child:124 +Hidden child:125 +Hidden child:126 +Hidden child:127 +Hidden child:128 +Hidden child:129 +Hidden child:130 +Hidden child:131 +Hidden child:132 +Hidden child:133 +Hidden child:134 +Hidden child:135 +Hidden child:136 +Hidden child:137 +Hidden child:138 +Hidden child:139 +Hidden child:140 +Hidden child:141 +Hidden child:142 +Hidden child:143 +Hidden child:144 +Hidden child:145 +Hidden child:146 +Hidden child:147 +Hidden child:148 +Hidden child:149 +Hidden child:150 +Hidden child:151 +Hidden child:152 +Hidden child:153 +Hidden child:154 +Hidden child:155 +Hidden child:156 +Hidden child:157 +Hidden child:158 +Hidden child:159 +Hidden child:160 +Hidden child:161 +Hidden child:162 +Hidden child:163 +Hidden child:164 +Hidden child:165 +Hidden child:166 +Hidden child:167 +Hidden child:168 +Hidden child:169 +Hidden child:170 +Hidden child:171 +Hidden child:172 +Hidden child:173 +Hidden child:174 +Hidden child:175 +Hidden child:176 +Hidden child:177 +Hidden child:178 +Hidden child:179 +Hidden child:181 +Hidden child:182 +Hidden child:183 +Hidden child:184 +Hidden child:185 +Hidden child:186 +Hidden child:187 +Hidden child:188 +Hidden child:189 +Hidden child:190 +Hidden child:191 +Hidden child:192 +Hidden child:193 +Hidden child:194 +Hidden child:195 +Hidden child:196 +Hidden child:197 +Hidden child:198 +Hidden child:199 +Hidden child:200 +Hidden child:201 +Hidden child:202 +Hidden child:203 +Hidden child:204 +Hidden child:205 +Hidden child:206 +Hidden child:207 +Hidden child:208 +Hidden child:209 +Hidden child:210 +Hidden child:211 +Hidden child:212 +Hidden child:213 +Hidden child:214 +Hidden child:215 +Hidden child:216 +Hidden child:217 +Hidden child:218 +Hidden child:219 +Hidden child:220 +Hidden child:221 +Hidden child:222 +Hidden child:223 +Hidden child:224 +Hidden child:225 +Hidden child:226 +Hidden child:227 +Hidden child:228 +Hidden child:229 +Hidden child:230 +Hidden child:231 +Hidden child:232 +Hidden child:233 +Hidden child:234 +Hidden child:235 +Hidden child:236 +Hidden child:237 +Hidden child:238 +Hidden child:239 +Hidden child:240 +Hidden child:242 +Hidden child:243 +Hidden child:244 +Hidden child:245 +Hidden child:246 +Hidden child:247 +Hidden child:248 +Hidden child:249 +Hidden child:250 +Hidden child:251 +Hidden child:252 +Hidden child:253 +Hidden child:254 +Hidden child:255 +Hidden child:256 +Hidden child:257 +Hidden child:258 +Hidden child:259 +Hidden child:260 +Hidden child:261 +Hidden child:262 +Hidden child:263 +Hidden child:264 +Hidden child:265 +Hidden child:266 +Hidden child:267 +Hidden child:268 +Hidden child:269 +Hidden child:270 +Hidden child:271 +Hidden child:272 +Hidden child:273 +Hidden child:274 +Hidden child:275 +Hidden child:276 +Hidden child:277 +Hidden child:278 +Hidden child:279 +Hidden child:280 +Hidden child:281 +Hidden child:282 +Hidden child:283 +Hidden child:284 +Hidden child:285 +Hidden child:286 +Hidden child:287 +Hidden child:288 +Hidden child:289 +Hidden child:290 +Hidden child:291 +Hidden child:292 +Hidden child:293 +Hidden child:294 +Hidden child:295 +Hidden child:296 +Hidden child:297 +Hidden child:298 +Hidden child:299 +Hidden child:300 +Hidden child:301 +Hidden child:303 +Hidden child:304 +Hidden child:305 +Hidden child:306 +Hidden child:307 +Hidden child:308 +Hidden child:309 +Hidden child:310 +Hidden child:311 +Hidden child:312 +Hidden child:313 +Hidden child:314 +Hidden child:315 +Hidden child:316 +Hidden child:317 +Hidden child:318 +Hidden child:319 +Hidden child:320 +Hidden child:321 +Hidden child:322 +Hidden child:323 +Hidden child:324 +Hidden child:325 +Hidden child:326 +Hidden child:327 +Hidden child:328 +Hidden child:329 +Hidden child:330 +Hidden child:331 +Hidden child:332 +Hidden child:333 +Hidden child:334 +Hidden child:335 +Hidden child:336 +Hidden child:337 +Hidden child:338 +Hidden child:339 +Hidden child:340 +Hidden child:341 +Hidden child:342 +Hidden child:343 +Hidden child:344 +Hidden child:345 +Hidden child:346 +Hidden child:347 +Hidden child:348 +Hidden child:349 +Hidden child:350 +Hidden child:351 +Hidden child:352 +Hidden child:353 +Hidden child:354 +Hidden child:355 +Hidden child:356 +Hidden child:357 +Hidden child:358 +Hidden child:359 +Hidden child:360 +Hidden child:361 +Hidden child:362 +Hidden child:364 +Hidden child:365 +Hidden child:366 +Hidden child:367 +Hidden child:368 +Hidden child:369 +Hidden child:370 +Hidden child:371 +Hidden child:372 +Hidden child:373 +Hidden child:374 +Hidden child:375 +Hidden child:376 +Hidden child:377 +Hidden child:378 +Hidden child:379 +Hidden child:380 +Hidden child:381 +Hidden child:382 +Hidden child:383 +Hidden child:384 +Hidden child:385 +Hidden child:386 +Hidden child:387 +Hidden child:388 +Hidden child:389 +Hidden child:390 +Hidden child:391 +Hidden child:392 +Hidden child:393 +Hidden child:394 +Hidden child:395 +Hidden child:396 +Hidden child:397 +Hidden child:398 +Hidden child:399 +Hidden child:400 +Hidden child:401 +Hidden child:402 +Hidden child:403 +Hidden child:404 +Hidden child:405 +Hidden child:406 +Hidden child:407 +Hidden child:408 +Hidden child:409 +Hidden child:410 +Hidden child:411 +Hidden child:412 +Hidden child:413 +Hidden child:414 +Hidden child:415 +Hidden child:416 +Hidden child:417 +Hidden child:418 +Hidden child:419 +Hidden child:420 +Hidden child:421 +Hidden child:422 +Hidden child:423 +Hidden child:425 +Hidden child:426 +Hidden child:427 +Hidden child:428 +Hidden child:429 +Hidden child:430 +Hidden child:431 +Hidden child:432 +Hidden child:433 +Hidden child:434 +Hidden child:435 +Hidden child:436 +Hidden child:437 +Hidden child:438 +Hidden child:439 +Hidden child:440 +Hidden child:441 +Hidden child:442 +Hidden child:443 +Hidden child:444 +Hidden child:445 +Hidden child:446 +Hidden child:447 +Hidden child:448 +Hidden child:449 +Hidden child:450 +Hidden child:451 +Hidden child:452 +Hidden child:453 +Hidden child:454 +Hidden child:455 +Hidden child:456 +Hidden child:457 +Hidden child:458 +Hidden child:459 +Hidden child:460 +Hidden child:461 +Hidden child:462 +Hidden child:463 +Hidden child:464 +Hidden child:465 +Hidden child:466 +Hidden child:467 +Hidden child:468 +Hidden child:469 +Hidden child:470 +Hidden child:471 +Hidden child:472 +Hidden child:473 +Hidden child:474 +Hidden child:475 +Hidden child:476 +Hidden child:477 +Hidden child:478 +Hidden child:479 +Hidden child:480 +Hidden child:481 +Hidden child:482 +Hidden child:483 +Hidden child:484 +Hidden child:486 +Hidden child:487 +Hidden child:488 +Hidden child:489 +Hidden child:490 +Hidden child:491 +Hidden child:492 +Hidden child:493 +Hidden child:494 +Hidden child:495 +Hidden child:496 +Hidden child:497 +Hidden child:498 +Hidden child:499 +Hidden child:500 +Hidden child:501 +Hidden child:502 +Hidden child:503 +Hidden child:504 +Hidden child:505 +Hidden child:506 +Hidden child:507 +Hidden child:508 +Hidden child:509 +Hidden child:510 +Hidden child:511 +Hidden child:512 +Hidden child:513 +Hidden child:514 +Hidden child:515 +Hidden child:516 +Hidden child:517 +Hidden child:518 +Hidden child:519 +Hidden child:520 +Hidden child:521 +Hidden child:522 +Hidden child:523 +Hidden child:524 +Hidden child:525 +Hidden child:526 +Hidden child:527 +Hidden child:528 +Hidden child:529 +Hidden child:530 +Hidden child:531 +Hidden child:532 +Hidden child:533 +Hidden child:534 +Hidden child:535 +Hidden child:536 +Hidden child:537 +Hidden child:538 +Hidden child:539 +Hidden child:540 +Hidden child:541 +Hidden child:542 +Hidden child:543 +Hidden child:544 +Hidden child:545 +Hidden child:547 +Hidden child:548 +Hidden child:549 +Hidden child:550 +Hidden child:551 +Hidden child:552 +Hidden child:553 +Hidden child:554 +Hidden child:555 +Hidden child:556 +Hidden child:557 +Hidden child:558 +Hidden child:559 +Hidden child:560 +Hidden child:561 +Hidden child:562 +Hidden child:563 +Hidden child:564 +Hidden child:565 +Hidden child:566 +Hidden child:567 +Hidden child:568 +Hidden child:569 +Hidden child:570 +Hidden child:571 +Hidden child:572 +Hidden child:573 +Hidden child:574 +Hidden child:575 +Hidden child:576 +Hidden child:577 +Hidden child:578 +Hidden child:579 +Hidden child:580 +Hidden child:581 +Hidden child:582 +Hidden child:583 +Hidden child:584 +Hidden child:585 +Hidden child:586 +Hidden child:587 +Hidden child:588 +Hidden child:589 +Hidden child:590 +Hidden child:591 +Hidden child:592 +Hidden child:593 +Hidden child:594 +Hidden child:595 +Hidden child:596 +Hidden child:597 +Hidden child:598 +Hidden child:599 +Hidden child:600 +Hidden child:601 +Hidden child:602 +Hidden child:603 +Hidden child:604 +Hidden child:605 +Hidden child:606 +Hidden child:608 +Hidden child:609 +Hidden child:610 +Hidden child:611 +Hidden child:612 +Hidden child:613 +Hidden child:614 +Hidden child:615 +Hidden child:616 +Hidden child:617 +Hidden child:618 +Hidden child:619 +Hidden child:620 +Hidden child:621 +Hidden child:622 +Hidden child:623 +Hidden child:624 +Hidden child:625 +Hidden child:626 +Hidden child:627 +Hidden child:628 +Hidden child:629 +Hidden child:630 +Hidden child:631 +Hidden child:632 +Hidden child:633 +Hidden child:634 +Hidden child:635 +Hidden child:636 +Hidden child:637 +Hidden child:638 +Hidden child:639 +Hidden child:640 +Hidden child:641 +Hidden child:642 +Hidden child:643 +Hidden child:644 +Hidden child:645 +Hidden child:646 +Hidden child:647 +Hidden child:648 +Hidden child:649 +Hidden child:650 +Hidden child:651 +Hidden child:652 +Hidden child:653 +Hidden child:654 +Hidden child:655 +Hidden child:656 +Hidden child:657 +Hidden child:658 +Hidden child:659 +Hidden child:660 +Hidden child:661 +Hidden child:662 +Hidden child:663 +Hidden child:664 +Hidden child:665 +Hidden child:666 +Hidden child:667 +Hidden child:669 +Hidden child:670 +Hidden child:671 +Hidden child:672 +Hidden child:673 +Hidden child:674 +Hidden child:675 +Hidden child:676 +Hidden child:677 +Hidden child:678 +Hidden child:679 +Hidden child:680 +Hidden child:681 +Hidden child:682 +Hidden child:683 +Hidden child:684 +Hidden child:685 +Hidden child:686 +Hidden child:687 +Hidden child:688 +Hidden child:689 +Hidden child:690 +Hidden child:691 +Hidden child:692 +Hidden child:693 +Hidden child:694 +Hidden child:695 +Hidden child:696 +Hidden child:697 +Hidden child:698 +Hidden child:699 +Hidden child:700 +Hidden child:701 +Hidden child:702 +Hidden child:703 +Hidden child:704 +Hidden child:705 +Hidden child:706 +Hidden child:707 +Hidden child:708 +Hidden child:709 +Hidden child:710 +Hidden child:711 +Hidden child:712 +Hidden child:713 +Hidden child:714 +Hidden child:715 +Hidden child:716 +Hidden child:717 +Hidden child:718 +Hidden child:719 +Hidden child:720 +Hidden child:721 +Hidden child:722 +Hidden child:723 +Hidden child:724 +Hidden child:725 +Hidden child:726 +Hidden child:727 +Hidden child:728 +INTERFACE:948 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:109 +Hidden child:110 +Hidden child:111 +Hidden child:112 +Hidden child:113 +Hidden child:114 +Hidden child:115 +Hidden child:116 +Hidden child:117 +Hidden child:118 +Hidden child:119 +Hidden child:120 +Hidden child:121 +Hidden child:122 +Hidden child:123 +Hidden child:124 +Hidden child:157 +Hidden child:158 +Hidden child:159 +Hidden child:160 +Hidden child:161 +Hidden child:174 +Hidden child:175 +Hidden child:176 +Hidden child:177 +Hidden child:178 +Hidden child:191 +Hidden child:192 +Hidden child:193 +Hidden child:194 +Hidden child:195 +Hidden child:208 +Hidden child:209 +Hidden child:210 +Hidden child:211 +Hidden child:212 +Hidden child:213 +Hidden child:214 +Hidden child:215 +Hidden child:234 +Hidden child:235 +Hidden child:236 +Hidden child:237 +Hidden child:238 +Hidden child:239 +Hidden child:240 +Hidden child:241 +Hidden child:242 +Hidden child:243 +Hidden child:244 +Hidden child:245 +Hidden child:246 +Hidden child:247 +Hidden child:248 +Hidden child:249 +Hidden child:250 +Hidden child:251 +Hidden child:252 +Hidden child:253 +Hidden child:254 +Hidden child:255 +Hidden child:256 +Hidden child:257 +Hidden child:258 +Hidden child:259 +Hidden child:260 +Hidden child:261 +Hidden child:262 +Hidden child:263 +Hidden child:264 +Hidden child:265 +Hidden child:338 +Hidden child:341 +Hidden child:344 +Hidden child:349 +Hidden child:352 +Hidden child:355 +INTERFACE:949 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related GlobalStringVar(InfoString):284 +Found:Related GlobalIntVar(ButtonGraphics):1153 +Found:Related GlobalIntVar(ButtonGraphics):1158 +Found:Related GlobalIntVar(ButtonGraphics):1163 +Found:Related GlobalIntVar(ButtonGraphics):1168 +Found:Related GlobalStringVar(InfoString):285 +Found:Related GlobalIntVar(ButtonGraphics):1154 +Found:Related GlobalIntVar(ButtonGraphics):1159 +Found:Related GlobalIntVar(ButtonGraphics):1164 +Found:Related GlobalIntVar(ButtonGraphics):1169 +Found:Related GlobalStringVar(InfoString):286 +Found:Related GlobalIntVar(ButtonGraphics):1155 +Found:Related GlobalIntVar(ButtonGraphics):1160 +Found:Related GlobalIntVar(ButtonGraphics):1165 +Found:Related GlobalIntVar(ButtonGraphics):1170 +Found:Related GlobalStringVar(InfoString):287 +Found:Related GlobalIntVar(ButtonGraphics):1156 +Found:Related GlobalIntVar(ButtonGraphics):1161 +Found:Related GlobalIntVar(ButtonGraphics):1166 +Found:Related GlobalIntVar(ButtonGraphics):1171 +Found:Related GlobalStringVar(InfoString):288 +Found:Related GlobalIntVar(ButtonGraphics):1157 +Found:Related GlobalIntVar(ButtonGraphics):1162 +Found:Related GlobalIntVar(ButtonGraphics):1167 +Found:Related GlobalIntVar(ButtonGraphics):1172 +Found:Related GlobalIntVar(ButtonGraphics):1174 +Found:Related GlobalIntVar(ButtonGraphics):1173 +Hidden child:66 +INTERFACE:950 +Found:Indirect-related BITconfig:ID:108, bitoffs:1, length:31 +Found:Indirect-related BITconfig:ID:439, bitoffs:0, length:1 +Found:Indirect-related BITconfig:ID:1510, bitoffs:5, length:13 +Found:Indirect-related BITconfig:ID:108, bitoffs:0, length:0 +Found:Related BITconfig:ID:439, bitoffs:8, length:8 +Found:Related GlobalIntVar(ButtonGraphics):993 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Related BITconfig:ID:1376, bitoffs:9, length:9 +Found:Related BITconfig:ID:1376, bitoffs:12, length:12 +Found:Related BITconfig:ID:1376, bitoffs:11, length:11 +Found:Related BITconfig:ID:1376, bitoffs:10, length:10 +Found:Related BITconfig:ID:1376, bitoffs:13, length:13 +Found:Related BITconfig:ID:1376, bitoffs:14, length:14 +Found:Related BITconfig:ID:1376, bitoffs:15, length:15 +Found:Related BITconfig:ID:1376, bitoffs:16, length:16 +Found:Related BITconfig:ID:1376, bitoffs:17, length:17 +Found:Related BITconfig:ID:1376, bitoffs:21, length:21 +Found:Related BITconfig:ID:1376, bitoffs:24, length:24 +Found:Related BITconfig:ID:1376, bitoffs:23, length:23 +Found:Related BITconfig:ID:1376, bitoffs:22, length:22 +Found:Related GlobalIntVar(ButtonGraphics):988 +Found:Related GlobalIntVar(ButtonGraphics):989 +Found:Related GlobalIntVar(ButtonGraphics):990 +Found:Related GlobalIntVar(ButtonGraphics):991 +Found:Related GlobalIntVar(ButtonGraphics):631 +Found:Indirect-related BITconfig:ID:1376, bitoffs:0, length:2 +Found:Indirect-related BITconfig:ID:1376, bitoffs:3, length:5 +Found:Indirect-related BITconfig:ID:1376, bitoffs:6, length:8 +Found:Indirect-related BITconfig:ID:1376, bitoffs:18, length:20 +Found:Indirect-related config:1092 +Found:Indirect-related BITconfig:ID:2089, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1087, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1209, bitoffs:6, length:7 +Found:Indirect-related BITconfig:ID:1331, bitoffs:0, length:2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1334 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1335 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1402 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1403 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1234 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1235 +Found:Indirect-related config:1795 +Found:Related GlobalIntVar(ButtonGraphics):992 +Hidden child:68 +Hidden child:69 +INTERFACE:951 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1191 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1320 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1196 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1188 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1198 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1199 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1200 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1201 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1202 +Found:Related config:1780 +Found:Related BITconfig:ID:1775, bitoffs:16, length:19 +Found:Related BITconfig:ID:1775, bitoffs:0, length:5 +Found:Related BITconfig:ID:1775, bitoffs:6, length:11 +Found:Related GlobalIntVar(ButtonGraphics):1186 +Found:Related GlobalIntVar(ButtonGraphics):1185 +Found:Related GlobalIntVar(ButtonGraphics):1195 +Found:Related GlobalIntVar(ButtonGraphics):1187 +Found:Related GlobalIntVar(ButtonGraphics):1319 +Found:Related GlobalIntVar(ButtonGraphics):1237 +Found:Related GlobalIntVar(ButtonGraphics):1238 +Found:Related GlobalIntVar(ButtonGraphics):1239 +Found:Related GlobalIntVar(ButtonGraphics):1236 +Found:Related GlobalIntVar(ButtonGraphics):1321 +Found:Related GlobalIntVar(ButtonGraphics):1184 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1208 +Found:Indirect-related GlobalStringVar(InfoString):310 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1212 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1213 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1214 +Found:Indirect-related GlobalStringVar(InfoString):311 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1215 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1216 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1217 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1218 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1219 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1220 +Found:Indirect-related GlobalStringVar(InfoString):312 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1221 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1222 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1223 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1224 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1225 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1226 +Found:Indirect-related GlobalStringVar(InfoString):313 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1227 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1228 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1229 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1230 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1231 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1232 +Found:Indirect-related GlobalStringVar(InfoString):314 +Hidden child:222 +Hidden child:223 +Hidden child:224 +Hidden child:225 +Hidden child:226 +Hidden child:227 +Hidden child:228 +Hidden child:229 +Hidden child:230 +Hidden child:231 +INTERFACE:952 +INTERFACE:953 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:954 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:7 +INTERFACE:955 +INTERFACE:956 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related GlobalIntVar(ButtonGraphics):1320 +Hidden child:20 +Hidden child:21 +Hidden child:22 +INTERFACE:957 +INTERFACE:958 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:39 +Hidden child:40 +Hidden child:41 +Hidden child:42 +Hidden child:43 +Hidden child:44 +Hidden child:45 +Hidden child:46 +Hidden child:47 +Hidden child:48 +Hidden child:49 +Hidden child:50 +Hidden child:51 +Hidden child:52 +Hidden child:53 +Hidden child:54 +Hidden child:55 +Hidden child:56 +Hidden child:57 +Hidden child:58 +Hidden child:59 +Hidden child:60 +Hidden child:61 +Hidden child:62 +Hidden child:63 +Hidden child:64 +Hidden child:65 +Hidden child:66 +Hidden child:67 +Hidden child:68 +INTERFACE:959 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:6 +Hidden child:7 +Hidden child:8 +Hidden child:9 +Hidden child:10 +Hidden child:11 +Hidden child:12 +Hidden child:13 +Hidden child:14 +Hidden child:15 +Hidden child:16 +Hidden child:17 +Hidden child:18 +Hidden child:19 +Hidden child:20 +Hidden child:21 +Hidden child:22 +Hidden child:23 +Hidden child:24 +Hidden child:25 +Hidden child:26 +Hidden child:27 +INTERFACE:960 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:0 +Hidden child:1 +Hidden child:2 +Hidden child:3 +Hidden child:4 +Hidden child:5 +Hidden child:6 +Hidden child:7 +Hidden child:8 +Hidden child:9 +Hidden child:10 +Hidden child:11 +Hidden child:12 +Hidden child:13 +Hidden child:14 +Hidden child:15 +Hidden child:16 +Hidden child:17 +Hidden child:18 +Hidden child:19 +Hidden child:20 +Hidden child:21 +Hidden child:22 +Hidden child:23 +Hidden child:24 +Hidden child:25 +Hidden child:26 +Hidden child:27 +Hidden child:28 +Hidden child:29 +Hidden child:31 +INTERFACE:961 +Found:Related BITconfig:ID:1819, bitoffs:17, length:18 +INTERFACE:962 +Found:Related BITconfig:ID:1819, bitoffs:17, length:18 +INTERFACE:963 +Found:Related BITconfig:ID:1819, bitoffs:17, length:18 +INTERFACE:964 +Found:Related BITconfig:ID:1819, bitoffs:17, length:18 +INTERFACE:965 +INTERFACE:966 +Found:Related BITconfig:ID:1819, bitoffs:17, length:18 +INTERFACE:967 +Found:Related BITconfig:ID:1819, bitoffs:17, length:18 +INTERFACE:968 +Found:Related BITconfig:ID:1819, bitoffs:17, length:18 +INTERFACE:969 +INTERFACE:970 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:4 +Hidden child:5 +Hidden child:6 +Hidden child:7 +INTERFACE:971 +Found:Related BITconfig:ID:1819, bitoffs:17, length:18 +INTERFACE:972 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:4 +Hidden child:5 +Hidden child:6 +Hidden child:7 +INTERFACE:973 +INTERFACE:974 +Found:Related BITconfig:ID:1819, bitoffs:17, length:18 +INTERFACE:975 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1100 +Found:Indirect-related GlobalIntVar(ButtonGraphics):547 +Found:Indirect-related GlobalIntVar(ButtonGraphics):174 +Found:Indirect-related GlobalIntVar(ButtonGraphics):200 +Found:Indirect-related GlobalIntVar(ButtonGraphics):201 +Found:Indirect-related GlobalStringVar(InfoString):32 +Found:Indirect-related GlobalStringVar(InfoString):33 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1099 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1089 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1092 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1414 +Hidden child:1 +Hidden child:5 +Hidden child:6 +Hidden child:26 +INTERFACE:976 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1240 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1277 +Found:Indirect-related GlobalIntVar(ButtonGraphics):178 +Found:Indirect-related GlobalIntVar(ButtonGraphics):175 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Indirect-related GlobalIntVar(ButtonGraphics):174 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1090 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1091 +Found:Indirect-related GlobalIntVar(ButtonGraphics):547 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1099 +Found:Indirect-related GlobalStringVar(InfoString):122 +Found:Indirect-related GlobalStringVar(InfoString):32 +Found:Indirect-related GlobalStringVar(InfoString):124 +Found:Indirect-related GlobalStringVar(InfoString):33 +Found:Indirect-related GlobalStringVar(InfoString):125 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1089 +Found:Indirect-related GlobalIntVar(ButtonGraphics):986 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1411 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1407 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1408 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1101 +Found:Indirect-related GlobalStringVar(InfoString):326 +Found:Indirect-related GlobalStringVar(InfoString):123 +Found:Indirect-related GlobalStringVar(InfoString):327 +Found:Indirect-related GlobalStringVar(InfoString):328 +Found:Indirect-related GlobalStringVar(InfoString):329 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1100 +Found:Indirect-related GlobalIntVar(ButtonGraphics):200 +Found:Indirect-related GlobalIntVar(ButtonGraphics):201 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1092 +Found:Indirect-related GlobalIntVar(ButtonGraphics):987 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1414 +Found:Related GlobalIntVar(ButtonGraphics):1273 +INTERFACE:977 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1394 +INTERFACE:978 +INTERFACE:979 +Found:Related GlobalIntVar(ButtonGraphics):6 +Found:Indirect-related GlobalStringVar(InfoString):278 +Hidden child:7 +Hidden child:43 +INTERFACE:980 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:981 +INTERFACE:982 +Found:Indirect-related GlobalIntVar(ButtonGraphics):91 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related config:287 +Hidden child:15 +Hidden child:40 +Hidden child:43 +Hidden child:45 +Hidden child:67 +Hidden child:70 +Hidden child:95 +INTERFACE:983 +INTERFACE:984 +INTERFACE:985 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:26 +Hidden child:30 +Hidden child:33 +Hidden child:36 +Hidden child:39 +INTERFACE:986 +Found:Related BITconfig:ID:1841, bitoffs:10, length:10 +Found:Related BITconfig:ID:1840, bitoffs:20, length:20 +Found:Related BITconfig:ID:1840, bitoffs:9, length:12 +Found:Related BITconfig:ID:1840, bitoffs:13, length:14 +Found:Related BITconfig:ID:1841, bitoffs:0, length:4 +Found:Related BITconfig:ID:1841, bitoffs:17, length:17 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:5 +INTERFACE:987 +Found:Related BITconfig:ID:1840, bitoffs:15, length:18 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +INTERFACE:988 +INTERFACE:989 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:990 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1007 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1065 +Hidden child:1 +Hidden child:4 +INTERFACE:991 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1317 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1318 +Found:Indirect-related BITconfig:ID:1506, bitoffs:0, length:1 +Found:Indirect-related BITconfig:ID:1506, bitoffs:2, length:3 +Found:Indirect-related BITconfig:ID:1506, bitoffs:4, length:5 +Found:Indirect-related BITconfig:ID:1506, bitoffs:6, length:7 +Found:Indirect-related BITconfig:ID:1506, bitoffs:8, length:9 +Found:Indirect-related BITconfig:ID:1506, bitoffs:10, length:11 +Found:Indirect-related BITconfig:ID:1506, bitoffs:12, length:13 +Found:Indirect-related BITconfig:ID:1506, bitoffs:14, length:15 +Found:Indirect-related BITconfig:ID:1506, bitoffs:16, length:17 +Found:Indirect-related BITconfig:ID:1506, bitoffs:18, length:19 +Found:Indirect-related BITconfig:ID:1506, bitoffs:20, length:21 +Found:Indirect-related BITconfig:ID:1506, bitoffs:22, length:23 +Found:Indirect-related BITconfig:ID:1506, bitoffs:24, length:25 +Found:Indirect-related BITconfig:ID:1506, bitoffs:26, length:27 +Found:Indirect-related BITconfig:ID:1506, bitoffs:28, length:29 +Found:Indirect-related BITconfig:ID:1506, bitoffs:30, length:31 +Found:Indirect-related BITconfig:ID:1507, bitoffs:0, length:1 +Found:Indirect-related BITconfig:ID:1507, bitoffs:2, length:3 +Found:Indirect-related BITconfig:ID:1507, bitoffs:4, length:5 +Found:Indirect-related BITconfig:ID:1507, bitoffs:6, length:7 +Found:Indirect-related BITconfig:ID:1507, bitoffs:8, length:9 +Found:Indirect-related BITconfig:ID:1507, bitoffs:10, length:11 +Found:Indirect-related BITconfig:ID:1507, bitoffs:12, length:13 +Found:Indirect-related BITconfig:ID:1507, bitoffs:14, length:15 +Found:Indirect-related BITconfig:ID:1507, bitoffs:16, length:17 +Found:Indirect-related BITconfig:ID:1507, bitoffs:18, length:19 +Found:Indirect-related BITconfig:ID:1507, bitoffs:20, length:21 +Found:Indirect-related BITconfig:ID:1507, bitoffs:22, length:23 +Found:Indirect-related BITconfig:ID:1507, bitoffs:24, length:25 +Found:Indirect-related BITconfig:ID:1507, bitoffs:26, length:27 +Found:Indirect-related BITconfig:ID:1507, bitoffs:28, length:29 +Found:Indirect-related BITconfig:ID:1507, bitoffs:30, length:31 +Found:Indirect-related BITconfig:ID:1508, bitoffs:0, length:1 +Found:Indirect-related BITconfig:ID:1508, bitoffs:2, length:3 +Found:Indirect-related BITconfig:ID:1508, bitoffs:4, length:5 +Found:Indirect-related BITconfig:ID:1508, bitoffs:6, length:7 +Found:Indirect-related BITconfig:ID:1508, bitoffs:8, length:9 +Found:Indirect-related BITconfig:ID:1508, bitoffs:10, length:11 +Found:Indirect-related BITconfig:ID:1508, bitoffs:12, length:13 +Found:Indirect-related BITconfig:ID:1508, bitoffs:14, length:15 +Found:Indirect-related BITconfig:ID:1508, bitoffs:16, length:17 +Found:Indirect-related BITconfig:ID:1508, bitoffs:18, length:19 +Found:Indirect-related BITconfig:ID:1508, bitoffs:20, length:21 +Found:Indirect-related BITconfig:ID:1508, bitoffs:22, length:23 +Found:Indirect-related BITconfig:ID:1508, bitoffs:24, length:25 +Found:Indirect-related BITconfig:ID:1508, bitoffs:26, length:27 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:992 +Hidden child:7 +INTERFACE:993 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Related BITconfig:ID:1776, bitoffs:16, length:19 +Found:Related BITconfig:ID:1776, bitoffs:20, length:23 +Found:Related BITconfig:ID:1776, bitoffs:24, length:27 +Found:Related BITconfig:ID:1776, bitoffs:28, length:31 +Found:Related BITconfig:ID:1851, bitoffs:0, length:3 +Found:Related BITconfig:ID:1851, bitoffs:4, length:7 +Found:Related BITconfig:ID:1851, bitoffs:8, length:11 +Found:Related BITconfig:ID:1851, bitoffs:12, length:15 +Found:Related BITconfig:ID:1851, bitoffs:16, length:19 +Found:Related BITconfig:ID:1851, bitoffs:20, length:23 +Found:Related BITconfig:ID:1851, bitoffs:24, length:27 +Found:Related BITconfig:ID:1851, bitoffs:28, length:31 +Found:Related GlobalIntVar(ButtonGraphics):1184 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Related GlobalIntVar(ButtonGraphics):1186 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related BITconfig:ID:1779, bitoffs:3, length:6 +Hidden child:23 +Hidden child:44 +Hidden child:86 +Hidden child:137 +Hidden child:191 +Hidden child:261 +INTERFACE:994 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:41 +Hidden child:43 +Hidden child:45 +Hidden child:47 +Hidden child:49 +Hidden child:51 +Hidden child:53 +Hidden child:55 +Hidden child:57 +Hidden child:59 +Hidden child:61 +Hidden child:63 +Hidden child:65 +Hidden child:67 +Hidden child:69 +Hidden child:71 +INTERFACE:995 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:39 +Hidden child:57 +Hidden child:73 +Hidden child:90 +Hidden child:107 +Hidden child:125 +INTERFACE:996 +Hidden child:0 +Hidden child:4 +INTERFACE:997 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:7 +INTERFACE:998 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:7 +INTERFACE:999 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:8 +Hidden child:16 +Hidden child:21 +Hidden child:27 +Hidden child:32 +Hidden child:37 +INTERFACE:1000 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1038 +Found:Indirect-related GlobalIntVar(ButtonGraphics):192 +Found:Indirect-related BITconfig:ID:638, bitoffs:17, length:17 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1324 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1856, bitoffs:25, length:31 +Found:Indirect-related BITconfig:ID:1856, bitoffs:5, length:9 +Found:Indirect-related BITconfig:ID:1856, bitoffs:15, length:19 +Found:Indirect-related BITconfig:ID:1856, bitoffs:10, length:14 +Found:Related BITconfig:ID:1856, bitoffs:0, length:4 +Hidden child:150 +INTERFACE:1001 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1038 +Found:Indirect-related GlobalIntVar(ButtonGraphics):192 +Found:Indirect-related BITconfig:ID:638, bitoffs:17, length:17 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1324 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1856, bitoffs:25, length:31 +Found:Indirect-related BITconfig:ID:1856, bitoffs:5, length:9 +Found:Indirect-related BITconfig:ID:1856, bitoffs:10, length:14 +Found:Indirect-related BITconfig:ID:1856, bitoffs:15, length:19 +Found:Related BITconfig:ID:1856, bitoffs:0, length:4 +Hidden child:146 +INTERFACE:1002 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1038 +Found:Indirect-related GlobalIntVar(ButtonGraphics):192 +Found:Indirect-related BITconfig:ID:638, bitoffs:17, length:17 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1324 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1856, bitoffs:25, length:31 +Found:Indirect-related BITconfig:ID:1856, bitoffs:5, length:9 +Found:Indirect-related BITconfig:ID:1856, bitoffs:10, length:14 +Found:Indirect-related BITconfig:ID:1856, bitoffs:15, length:19 +Found:Related BITconfig:ID:1856, bitoffs:0, length:4 +Hidden child:142 +INTERFACE:1003 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1038 +Found:Indirect-related GlobalIntVar(ButtonGraphics):192 +Found:Indirect-related BITconfig:ID:638, bitoffs:17, length:17 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1324 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1856, bitoffs:25, length:31 +Found:Indirect-related BITconfig:ID:1856, bitoffs:15, length:19 +Found:Indirect-related BITconfig:ID:1856, bitoffs:10, length:14 +Found:Indirect-related BITconfig:ID:1856, bitoffs:5, length:9 +Found:Related BITconfig:ID:1856, bitoffs:0, length:4 +Hidden child:154 +INTERFACE:1004 +Found:Related GlobalIntVar(ButtonGraphics):1327 +Found:Related GlobalIntVar(ButtonGraphics):1326 +Found:Related GlobalIntVar(ButtonGraphics):1330 +Found:Related GlobalIntVar(ButtonGraphics):1325 +Found:Related GlobalIntVar(ButtonGraphics):1328 +Found:Related GlobalIntVar(ButtonGraphics):1329 +Found:Related GlobalIntVar(ButtonGraphics):1331 +Hidden child:63 +Hidden child:64 +Hidden child:65 +Hidden child:66 +Hidden child:75 +INTERFACE:1005 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:1006 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Related GlobalIntVar(ButtonGraphics):1336 +Found:Related GlobalIntVar(ButtonGraphics):1337 +Found:Related GlobalIntVar(ButtonGraphics):1338 +Found:Related GlobalIntVar(ButtonGraphics):1339 +Found:Related GlobalIntVar(ButtonGraphics):1340 +Found:Related GlobalIntVar(ButtonGraphics):1341 +Found:Related GlobalIntVar(ButtonGraphics):1342 +Found:Related GlobalIntVar(ButtonGraphics):1343 +Found:Related GlobalIntVar(ButtonGraphics):1344 +Found:Related GlobalIntVar(ButtonGraphics):1345 +Found:Related GlobalIntVar(ButtonGraphics):1346 +Found:Related GlobalIntVar(ButtonGraphics):1347 +Found:Related GlobalIntVar(ButtonGraphics):1348 +Found:Related GlobalIntVar(ButtonGraphics):1349 +Found:Related GlobalIntVar(ButtonGraphics):1350 +Found:Related GlobalIntVar(ButtonGraphics):1605 +Found:Related GlobalIntVar(ButtonGraphics):1351 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +INTERFACE:1007 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related GlobalIntVar(ButtonGraphics):1352 +INTERFACE:1008 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related BITconfig:ID:1874, bitoffs:7, length:7 +INTERFACE:1009 +Found:Related config:1875 +INTERFACE:1010 +Found:Related BITconfig:ID:1870, bitoffs:1, length:1 +Found:Related BITconfig:ID:1870, bitoffs:2, length:2 +Found:Related GlobalIntVar(ButtonGraphics):1361 +Found:Related GlobalIntVar(ButtonGraphics):1363 +Found:Related GlobalIntVar(ButtonGraphics):1391 +Found:Related GlobalIntVar(ButtonGraphics):1364 +Hidden child:7 +Hidden child:24 +Hidden child:32 +Hidden child:33 +INTERFACE:1011 +Found:Related config:1875 +Found:Related BITconfig:ID:719, bitoffs:0, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related BITconfig:ID:1178, bitoffs:1, length:10 +Hidden child:48 +Hidden child:69 +Hidden child:70 +Hidden child:71 +Hidden child:386 +INTERFACE:1012 +Found:Related GlobalIntVar(ButtonGraphics):1372 +Found:Related GlobalIntVar(ButtonGraphics):1373 +Found:Related GlobalIntVar(ButtonGraphics):1374 +Found:Related GlobalIntVar(ButtonGraphics):1375 +Found:Related GlobalIntVar(ButtonGraphics):1376 +Found:Related GlobalIntVar(ButtonGraphics):1377 +Found:Related GlobalIntVar(ButtonGraphics):1367 +Found:Related GlobalIntVar(ButtonGraphics):1368 +Found:Related GlobalIntVar(ButtonGraphics):1369 +Found:Related GlobalIntVar(ButtonGraphics):1370 +Found:Related GlobalIntVar(ButtonGraphics):1371 +Hidden child:7 +Hidden child:14 +Hidden child:20 +Hidden child:30 +INTERFACE:1013 +Found:Related GlobalIntVar(ButtonGraphics):1353 +Found:Related GlobalIntVar(ButtonGraphics):1359 +Found:Related GlobalIntVar(ButtonGraphics):1360 +Found:Related GlobalIntVar(ButtonGraphics):1354 +Found:Related GlobalIntVar(ButtonGraphics):1357 +Found:Related GlobalIntVar(ButtonGraphics):1358 +Found:Related GlobalIntVar(ButtonGraphics):1355 +Found:Related GlobalIntVar(ButtonGraphics):1356 +Found:Related BITconfig:ID:1870, bitoffs:1, length:1 +Found:Related GlobalIntVar(ButtonGraphics):1363 +Found:Related GlobalIntVar(ButtonGraphics):1389 +Found:Related GlobalIntVar(ButtonGraphics):1390 +Found:Related BITconfig:ID:1870, bitoffs:2, length:2 +Found:Related GlobalIntVar(ButtonGraphics):1362 +Hidden child:14 +Hidden child:15 +Hidden child:16 +Hidden child:17 +Hidden child:18 +Hidden child:19 +Hidden child:20 +Hidden child:21 +Hidden child:22 +INTERFACE:1014 +INTERFACE:1015 +Found:Related BITconfig:ID:1870, bitoffs:9, length:18 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related BITconfig:ID:1870, bitoffs:29, length:31 +Found:Related BITconfig:ID:1874, bitoffs:9, length:12 +Found:Related BITconfig:ID:1874, bitoffs:13, length:16 +Found:Related BITconfig:ID:1874, bitoffs:17, length:20 +Found:Related BITconfig:ID:1874, bitoffs:21, length:24 +Found:Indirect-related BITconfig:ID:1870, bitoffs:1, length:1 +Found:Related BITconfig:ID:1870, bitoffs:5, length:8 +Found:Related BITconfig:ID:1871, bitoffs:24, length:27 +Found:Related BITconfig:ID:1871, bitoffs:28, length:31 +Found:Related BITconfig:ID:1872, bitoffs:24, length:27 +Found:Related BITconfig:ID:1872, bitoffs:28, length:31 +Found:Related BITconfig:ID:1873, bitoffs:12, length:15 +Found:Related BITconfig:ID:1873, bitoffs:16, length:19 +Found:Related BITconfig:ID:1873, bitoffs:20, length:23 +Found:Related BITconfig:ID:1873, bitoffs:24, length:27 +Found:Related BITconfig:ID:1873, bitoffs:28, length:31 +Found:Related BITconfig:ID:1874, bitoffs:0, length:3 +Hidden child:23 +Hidden child:33 +Hidden child:48 +Hidden child:49 +Hidden child:55 +Hidden child:78 +Hidden child:84 +Hidden child:90 +Hidden child:96 +Hidden child:115 +Hidden child:116 +INTERFACE:1016 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related BITconfig:ID:1877, bitoffs:7, length:9 +INTERFACE:1017 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related BITconfig:ID:1871, bitoffs:24, length:27 +Found:Indirect-related BITconfig:ID:1871, bitoffs:28, length:31 +Found:Indirect-related BITconfig:ID:1872, bitoffs:24, length:27 +Found:Indirect-related BITconfig:ID:1872, bitoffs:28, length:31 +Found:Indirect-related BITconfig:ID:1873, bitoffs:12, length:15 +Found:Indirect-related BITconfig:ID:1873, bitoffs:16, length:19 +Found:Indirect-related BITconfig:ID:1873, bitoffs:20, length:23 +Found:Indirect-related BITconfig:ID:1873, bitoffs:24, length:27 +Found:Indirect-related BITconfig:ID:1873, bitoffs:28, length:31 +Found:Indirect-related BITconfig:ID:1874, bitoffs:0, length:3 +Found:Related BITconfig:ID:1871, bitoffs:0, length:5 +Found:Related BITconfig:ID:1871, bitoffs:6, length:11 +Found:Related BITconfig:ID:1871, bitoffs:12, length:17 +Found:Related BITconfig:ID:1871, bitoffs:18, length:23 +Found:Related BITconfig:ID:1872, bitoffs:0, length:5 +Found:Related BITconfig:ID:1872, bitoffs:6, length:11 +Found:Related BITconfig:ID:1872, bitoffs:12, length:17 +Found:Related BITconfig:ID:1872, bitoffs:18, length:23 +Found:Related BITconfig:ID:1873, bitoffs:0, length:5 +Found:Related BITconfig:ID:1873, bitoffs:6, length:11 +Found:Related GlobalIntVar(ButtonGraphics):1387 +Found:Indirect-related BITconfig:ID:1870, bitoffs:1, length:1 +Hidden child:19 +Hidden child:226 +INTERFACE:1018 +INTERFACE:1019 +Found:Related BITconfig:ID:1874, bitoffs:7, length:7 +Hidden child:14 +INTERFACE:1020 +INTERFACE:1021 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related BITconfig:ID:1877, bitoffs:7, length:9 +INTERFACE:1022 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related BITconfig:ID:1877, bitoffs:7, length:9 +Hidden child:31 +INTERFACE:1023 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related BITconfig:ID:1877, bitoffs:7, length:9 +Hidden child:12 +Hidden child:19 +Hidden child:33 +INTERFACE:1024 +Found:Related BITconfig:ID:1874, bitoffs:9, length:12 +Found:Related BITconfig:ID:1874, bitoffs:13, length:16 +Found:Related BITconfig:ID:1874, bitoffs:17, length:20 +Found:Related BITconfig:ID:1874, bitoffs:21, length:24 +Found:Related BITconfig:ID:1870, bitoffs:19, length:28 +Found:Related GlobalIntVar(ButtonGraphics):1388 +Found:Related GlobalIntVar(ButtonGraphics):1378 +Found:Related GlobalIntVar(ButtonGraphics):1379 +Found:Related GlobalIntVar(ButtonGraphics):1380 +Found:Related GlobalIntVar(ButtonGraphics):1386 +Found:Related GlobalIntVar(ButtonGraphics):1381 +Found:Related GlobalIntVar(ButtonGraphics):1383 +Found:Related GlobalIntVar(ButtonGraphics):1384 +Found:Related GlobalIntVar(ButtonGraphics):1385 +Found:Related GlobalIntVar(ButtonGraphics):1382 +Hidden child:2 +Hidden child:12 +Hidden child:28 +Hidden child:29 +Hidden child:30 +Hidden child:45 +Hidden child:46 +Hidden child:47 +Hidden child:62 +Hidden child:63 +Hidden child:64 +Hidden child:79 +Hidden child:80 +Hidden child:81 +Hidden child:85 +INTERFACE:1025 +Found:Related GlobalIntVar(ButtonGraphics):1387 +INTERFACE:1026 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related BITconfig:ID:1870, bitoffs:0, length:0 +INTERFACE:1027 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related GlobalIntVar(ButtonGraphics):1365 +Found:Related GlobalIntVar(ButtonGraphics):1366 +INTERFACE:1028 +Found:Indirect-related BITconfig:ID:1158, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1363, bitoffs:13, length:13 +Found:Indirect-related GlobalIntVar(ButtonGraphics):543 +Found:Indirect-related GlobalIntVar(ButtonGraphics):196 +Found:Indirect-related GlobalIntVar(ButtonGraphics):197 +Found:Related BITconfig:ID:1363, bitoffs:12, length:12 +Found:Related BITconfig:ID:1158, bitoffs:0, length:4 +Found:Related BITconfig:ID:1363, bitoffs:0, length:2 +Found:Related BITconfig:ID:1363, bitoffs:6, length:8 +Found:Related GlobalIntVar(ButtonGraphics):86 +Found:Related GlobalIntVar(ButtonGraphics):1020 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1019 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1008 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1015 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1009 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1010 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1016 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1013 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1017 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1014 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1018 +Found:Indirect-related GlobalIntVar(ButtonGraphics):773 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):174 +Found:Indirect-related GlobalIntVar(ButtonGraphics):175 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1099 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1407 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1408 +Found:Indirect-related GlobalStringVar(InfoString):122 +Found:Indirect-related GlobalStringVar(InfoString):326 +Found:Indirect-related GlobalStringVar(InfoString):124 +Found:Indirect-related GlobalStringVar(InfoString):125 +Found:Indirect-related GlobalStringVar(InfoString):123 +Found:Indirect-related GlobalStringVar(InfoString):327 +Found:Indirect-related GlobalStringVar(InfoString):328 +Found:Indirect-related GlobalStringVar(InfoString):329 +Hidden child:37 +Hidden child:48 +Hidden child:49 +Hidden child:50 +Hidden child:51 +Hidden child:52 +Hidden child:53 +Hidden child:54 +Hidden child:55 +Hidden child:56 +Hidden child:57 +Hidden child:58 +Hidden child:59 +Hidden child:60 +Hidden child:61 +Hidden child:62 +Hidden child:63 +Hidden child:64 +Hidden child:65 +Hidden child:66 +Hidden child:67 +Hidden child:68 +Hidden child:69 +Hidden child:70 +Hidden child:71 +Hidden child:83 +Hidden child:84 +Hidden child:85 +Hidden child:86 +Hidden child:87 +Hidden child:88 +Hidden child:89 +Hidden child:90 +Hidden child:115 +Hidden child:116 +Hidden child:117 +Hidden child:125 +Hidden child:156 +Hidden child:164 +Hidden child:176 +Hidden child:183 +INTERFACE:1029 +INTERFACE:1030 +INTERFACE:1031 +INTERFACE:1032 +INTERFACE:1033 +INTERFACE:1034 +INTERFACE:1035 +INTERFACE:1036 +INTERFACE:1037 +INTERFACE:1038 +INTERFACE:1039 +INTERFACE:1040 +INTERFACE:1041 +INTERFACE:1042 +INTERFACE:1043 +INTERFACE:1044 +INTERFACE:1045 +INTERFACE:1046 +INTERFACE:1047 +INTERFACE:1048 +INTERFACE:1049 +INTERFACE:1050 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related config:532 +Found:Related config:118 +Found:Indirect-related BITconfig:ID:1073, bitoffs:27, length:27 +Found:Indirect-related BITconfig:ID:1081, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1073, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1072, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1071, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:678, bitoffs:11, length:20 +Found:Indirect-related BITconfig:ID:1023, bitoffs:15, length:16 +Found:Indirect-related BITconfig:ID:1181, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:705, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:678, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:997, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:2051, bitoffs:0, length:8 +Found:Indirect-related config:130 +Found:Indirect-related config:29 +Found:Indirect-related config:31 +Found:Indirect-related config:176 +Found:Indirect-related config:32 +Found:Indirect-related config:160 +Found:Indirect-related config:122 +Found:Indirect-related config:71 +Found:Indirect-related config:273 +Found:Indirect-related config:107 +Found:Indirect-related config:63 +Found:Indirect-related config:145 +Found:Indirect-related config:146 +Found:Indirect-related config:293 +Found:Indirect-related config:68 +Found:Indirect-related config:655 +Found:Indirect-related config:10 +Found:Indirect-related config:399 +Found:Indirect-related config:314 +Found:Indirect-related config:131 +Found:Indirect-related config:80 +Found:Indirect-related config:0 +Found:Indirect-related config:335 +Found:Indirect-related config:299 +Found:Indirect-related config:148 +Found:Indirect-related config:17 +Found:Indirect-related config:11 +Found:Indirect-related config:347 +Found:Indirect-related config:65 +Found:Indirect-related config:180 +Found:Indirect-related config:150 +Found:Indirect-related config:382 +Found:Indirect-related config:223 +Found:Indirect-related config:188 +Found:Indirect-related config:5 +Found:Indirect-related config:387 +Found:Indirect-related config:175 +Found:Indirect-related config:139 +Found:Indirect-related config:147 +Found:Indirect-related config:14 +Found:Indirect-related config:365 +Found:Indirect-related config:30 +Found:Indirect-related config:517 +Found:Indirect-related config:192 +Found:Indirect-related config:307 +Found:Indirect-related config:112 +Found:Indirect-related config:416 +Found:Indirect-related config:165 +Found:Indirect-related config:302 +Found:Indirect-related config:328 +Found:Indirect-related config:402 +Found:Indirect-related config:600 +Found:Indirect-related config:76 +Found:Indirect-related config:159 +Found:Indirect-related config:339 +Found:Indirect-related config:60 +Found:Indirect-related config:116 +Found:Indirect-related config:320 +Found:Indirect-related config:26 +Found:Indirect-related config:359 +Found:Indirect-related config:197 +Found:Indirect-related config:226 +Found:Indirect-related config:111 +Found:Indirect-related config:200 +Found:Indirect-related config:385 +Found:Indirect-related config:317 +Found:Indirect-related config:161 +Found:Indirect-related config:162 +Found:Indirect-related config:212 +Found:Indirect-related config:980 +Found:Indirect-related BITconfig:ID:222, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:62, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:178, bitoffs:0, length:1 +Found:Indirect-related BITconfig:ID:939, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:433, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:964, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:455, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:400, bitoffs:23, length:23 +Found:Indirect-related BITconfig:ID:869, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:794, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:440, bitoffs:0, length:14 +Found:Indirect-related BITconfig:ID:622, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:934, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:896, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:641, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:912, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:844, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:671, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:810, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:435, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:521, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:553, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:408, bitoffs:28, length:31 +Found:Indirect-related BITconfig:ID:482, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:437, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:635, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:351, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:445, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:465, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:823, bitoffs:0, length:19 +Found:Indirect-related BITconfig:ID:604, bitoffs:0, length:2 +Found:Indirect-related BITconfig:ID:423, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:574, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:905, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:714, bitoffs:0, length:2 +Found:Indirect-related BITconfig:ID:607, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:496, bitoffs:0, length:2 +Found:Indirect-related BITconfig:ID:730, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:874, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:602, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:709, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:616, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:723, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:568, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:449, bitoffs:0, length:1 +Found:Indirect-related BITconfig:ID:571, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:968, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:970, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:977, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:992, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:994, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:1003, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1016, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1049, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1063, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:1077, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1094, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1165, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:1178, bitoffs:1, length:10 +Found:Indirect-related BITconfig:ID:1184, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:1190, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1204, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1218, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:1225, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1227, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1232, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1236, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:1271, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:1274, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1282, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:1306, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1311, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1330, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:1370, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1365, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:1403, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1407, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:1415, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1475, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1577, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:1420, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1390, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1327, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:714, bitoffs:3, length:6 +Found:Indirect-related BITconfig:ID:1819, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:1498, bitoffs:0, length:15 +Found:Indirect-related BITconfig:ID:1558, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:1600, bitoffs:0, length:3 +Found:Indirect-related BITconfig:ID:1588, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1610, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1811, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1849, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1646, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1844, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1834, bitoffs:28, length:31 +Found:Indirect-related BITconfig:ID:1861, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:2037, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1906, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1889, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:2217, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:2020, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:2046, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:2079, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:2208, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:2234, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:2376, bitoffs:0, length:7 +Found:Indirect-related config:322 +Found:Indirect-related GlobalIntVar(ButtonGraphics):946 +Found:Indirect-related GlobalIntVar(ButtonGraphics):947 +Found:Indirect-related GlobalIntVar(ButtonGraphics):948 +Found:Indirect-related GlobalIntVar(ButtonGraphics):949 +Found:Indirect-related GlobalIntVar(ButtonGraphics):950 +Found:Indirect-related GlobalIntVar(ButtonGraphics):951 +Found:Indirect-related GlobalIntVar(ButtonGraphics):952 +Found:Indirect-related GlobalIntVar(ButtonGraphics):953 +Found:Indirect-related GlobalIntVar(ButtonGraphics):954 +Found:Indirect-related GlobalIntVar(ButtonGraphics):955 +Found:Indirect-related GlobalIntVar(ButtonGraphics):956 +Found:Indirect-related GlobalIntVar(ButtonGraphics):957 +Found:Indirect-related GlobalIntVar(ButtonGraphics):958 +Found:Indirect-related GlobalIntVar(ButtonGraphics):959 +Found:Indirect-related GlobalIntVar(ButtonGraphics):960 +Found:Indirect-related GlobalIntVar(ButtonGraphics):961 +Found:Indirect-related GlobalIntVar(ButtonGraphics):962 +Found:Indirect-related GlobalIntVar(ButtonGraphics):963 +Found:Indirect-related GlobalIntVar(ButtonGraphics):964 +Found:Indirect-related GlobalIntVar(ButtonGraphics):965 +Found:Indirect-related GlobalIntVar(ButtonGraphics):966 +Found:Indirect-related GlobalIntVar(ButtonGraphics):967 +Found:Indirect-related GlobalIntVar(ButtonGraphics):968 +Found:Indirect-related GlobalIntVar(ButtonGraphics):969 +Found:Indirect-related GlobalIntVar(ButtonGraphics):970 +Found:Indirect-related GlobalIntVar(ButtonGraphics):971 +Found:Indirect-related GlobalIntVar(ButtonGraphics):972 +Found:Indirect-related GlobalIntVar(ButtonGraphics):973 +Found:Indirect-related GlobalIntVar(ButtonGraphics):974 +Found:Indirect-related GlobalIntVar(ButtonGraphics):975 +Found:Indirect-related GlobalIntVar(ButtonGraphics):976 +Found:Indirect-related GlobalIntVar(ButtonGraphics):977 +Found:Indirect-related GlobalIntVar(ButtonGraphics):978 +Found:Indirect-related GlobalIntVar(ButtonGraphics):979 +Found:Indirect-related GlobalIntVar(ButtonGraphics):980 +Found:Indirect-related GlobalIntVar(ButtonGraphics):981 +Found:Indirect-related GlobalIntVar(ButtonGraphics):982 +Found:Indirect-related GlobalIntVar(ButtonGraphics):983 +Found:Indirect-related GlobalIntVar(ButtonGraphics):984 +Found:Indirect-related GlobalIntVar(ButtonGraphics):985 +Hidden child:20 +Hidden child:21 +INTERFACE:1051 +Found:Related config:1652 +Found:Related config:1653 +Found:Related config:1654 +INTERFACE:1052 +Found:Related config:1893 +Found:Related config:1890 +Found:Related config:1891 +Found:Related config:1892 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:122 +Hidden child:123 +Hidden child:124 +Hidden child:125 +Hidden child:126 +Hidden child:127 +Hidden child:128 +Hidden child:129 +Hidden child:130 +Hidden child:131 +Hidden child:132 +Hidden child:133 +INTERFACE:1053 +Found:Related config:1893 +Found:Related config:1890 +Found:Related config:1891 +Found:Related config:1892 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:70 +Hidden child:71 +Hidden child:72 +Hidden child:73 +Hidden child:74 +Hidden child:75 +Hidden child:76 +Hidden child:77 +Hidden child:78 +Hidden child:79 +Hidden child:80 +Hidden child:81 +Hidden child:93 +INTERFACE:1054 +Hidden child:46 +Hidden child:47 +Hidden child:48 +Hidden child:49 +Hidden child:50 +Hidden child:51 +Hidden child:52 +Hidden child:53 +INTERFACE:1055 +Found:Related GlobalIntVar(ButtonGraphics):1427 +Found:Related config:281 +Found:Related GlobalIntVar(ButtonGraphics):1429 +Found:Related GlobalIntVar(ButtonGraphics):1425 +Found:Related GlobalIntVar(ButtonGraphics):1426 +Hidden child:1 +Hidden child:12 +INTERFACE:1056 +Found:Related config:281 +Found:Related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Indirect-related BITconfig:ID:1960, bitoffs:19, length:21 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Related BITconfig:ID:1960, bitoffs:0, length:6 +Found:Related BITconfig:ID:1963, bitoffs:12, length:24 +Found:Related BITconfig:ID:1964, bitoffs:0, length:11 +Found:Related BITconfig:ID:1964, bitoffs:12, length:24 +Found:Related BITconfig:ID:1965, bitoffs:0, length:11 +Found:Related BITconfig:ID:1965, bitoffs:12, length:24 +Found:Related BITconfig:ID:1255, bitoffs:0, length:1 +Found:Related BITconfig:ID:1261, bitoffs:0, length:2 +Found:Related BITconfig:ID:1960, bitoffs:7, length:18 +Found:Indirect-related BITconfig:ID:1562, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:1562, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1562, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:1562, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1562, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1562, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:1562, bitoffs:7, length:7 +Found:Indirect-related BITconfig:ID:1562, bitoffs:8, length:8 +Found:Indirect-related BITconfig:ID:1562, bitoffs:9, length:9 +Found:Indirect-related BITconfig:ID:1562, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:1562, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:1562, bitoffs:12, length:12 +Found:Indirect-related BITconfig:ID:1562, bitoffs:13, length:13 +Found:Indirect-related BITconfig:ID:1562, bitoffs:14, length:14 +Found:Indirect-related BITconfig:ID:1562, bitoffs:15, length:15 +Found:Indirect-related BITconfig:ID:1562, bitoffs:16, length:16 +Found:Indirect-related BITconfig:ID:1562, bitoffs:17, length:17 +Found:Indirect-related BITconfig:ID:1562, bitoffs:18, length:18 +Found:Indirect-related BITconfig:ID:1562, bitoffs:19, length:19 +Found:Indirect-related BITconfig:ID:1562, bitoffs:20, length:20 +Found:Indirect-related BITconfig:ID:1562, bitoffs:21, length:21 +Found:Indirect-related BITconfig:ID:1562, bitoffs:22, length:22 +Found:Indirect-related BITconfig:ID:1562, bitoffs:23, length:23 +Found:Indirect-related BITconfig:ID:1563, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:1563, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:1563, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1563, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:1563, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1563, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1563, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:1563, bitoffs:7, length:7 +Found:Indirect-related BITconfig:ID:1563, bitoffs:8, length:8 +Found:Indirect-related BITconfig:ID:1563, bitoffs:9, length:9 +Found:Indirect-related BITconfig:ID:1563, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:1563, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:1563, bitoffs:12, length:12 +Found:Indirect-related BITconfig:ID:1563, bitoffs:13, length:13 +Found:Indirect-related BITconfig:ID:1563, bitoffs:14, length:14 +Found:Indirect-related BITconfig:ID:1563, bitoffs:15, length:15 +Found:Indirect-related BITconfig:ID:1564, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:1564, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:1564, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1564, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:1564, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1564, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1564, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:1564, bitoffs:7, length:7 +Found:Indirect-related BITconfig:ID:1564, bitoffs:8, length:8 +Found:Indirect-related BITconfig:ID:1564, bitoffs:9, length:9 +Found:Indirect-related BITconfig:ID:1564, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:1564, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:1564, bitoffs:12, length:12 +Found:Indirect-related BITconfig:ID:1564, bitoffs:13, length:13 +Found:Indirect-related BITconfig:ID:1564, bitoffs:14, length:14 +Found:Indirect-related BITconfig:ID:1564, bitoffs:15, length:15 +Found:Indirect-related BITconfig:ID:1564, bitoffs:16, length:16 +Found:Indirect-related BITconfig:ID:1565, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:1565, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1565, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:1565, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1565, bitoffs:5, length:10 +Found:Indirect-related BITconfig:ID:1256, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:1256, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:1256, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1256, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:1256, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1256, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1256, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:1256, bitoffs:7, length:7 +Found:Indirect-related BITconfig:ID:1256, bitoffs:8, length:8 +Found:Indirect-related BITconfig:ID:1256, bitoffs:9, length:9 +Found:Indirect-related BITconfig:ID:1256, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:1256, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:1256, bitoffs:12, length:12 +Found:Indirect-related BITconfig:ID:1256, bitoffs:13, length:13 +Found:Indirect-related BITconfig:ID:1256, bitoffs:14, length:14 +Found:Indirect-related BITconfig:ID:1256, bitoffs:15, length:15 +Found:Indirect-related BITconfig:ID:1256, bitoffs:16, length:16 +Found:Indirect-related BITconfig:ID:1256, bitoffs:17, length:17 +Found:Indirect-related BITconfig:ID:1256, bitoffs:18, length:18 +Found:Indirect-related BITconfig:ID:1256, bitoffs:19, length:19 +Found:Indirect-related BITconfig:ID:1256, bitoffs:20, length:20 +Found:Indirect-related BITconfig:ID:1256, bitoffs:21, length:21 +Found:Indirect-related BITconfig:ID:1256, bitoffs:22, length:22 +Found:Indirect-related BITconfig:ID:1257, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:1257, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:1257, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1257, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:1257, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1257, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1257, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:1257, bitoffs:7, length:7 +Found:Indirect-related BITconfig:ID:1257, bitoffs:8, length:8 +Found:Indirect-related BITconfig:ID:1257, bitoffs:9, length:9 +Found:Indirect-related BITconfig:ID:1257, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:1257, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:1257, bitoffs:12, length:12 +Found:Indirect-related BITconfig:ID:1257, bitoffs:13, length:13 +Found:Indirect-related BITconfig:ID:1257, bitoffs:14, length:14 +Found:Indirect-related BITconfig:ID:1257, bitoffs:15, length:15 +Found:Indirect-related BITconfig:ID:1257, bitoffs:16, length:16 +Found:Indirect-related BITconfig:ID:1257, bitoffs:17, length:17 +Found:Indirect-related BITconfig:ID:1257, bitoffs:19, length:19 +Found:Indirect-related BITconfig:ID:1258, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:1258, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:1258, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1258, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:1258, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1258, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1258, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:1258, bitoffs:7, length:7 +Found:Indirect-related BITconfig:ID:1258, bitoffs:8, length:8 +Found:Indirect-related BITconfig:ID:1258, bitoffs:9, length:9 +Found:Indirect-related BITconfig:ID:1258, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:1258, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:1886, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:1886, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:1886, bitoffs:8, length:8 +Found:Indirect-related BITconfig:ID:1886, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:1886, bitoffs:12, length:12 +Found:Indirect-related BITconfig:ID:1886, bitoffs:13, length:13 +Found:Indirect-related BITconfig:ID:1886, bitoffs:14, length:14 +Found:Indirect-related BITconfig:ID:1360, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1360, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1360, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:1360, bitoffs:7, length:7 +Found:Indirect-related BITconfig:ID:1360, bitoffs:8, length:8 +Found:Indirect-related BITconfig:ID:1360, bitoffs:9, length:9 +Found:Indirect-related BITconfig:ID:1360, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:1360, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:1360, bitoffs:12, length:12 +Found:Indirect-related BITconfig:ID:1360, bitoffs:13, length:13 +Found:Indirect-related BITconfig:ID:1360, bitoffs:14, length:14 +Found:Indirect-related BITconfig:ID:1360, bitoffs:15, length:15 +Found:Indirect-related BITconfig:ID:1360, bitoffs:16, length:16 +Found:Indirect-related BITconfig:ID:1360, bitoffs:17, length:17 +Found:Indirect-related BITconfig:ID:1360, bitoffs:18, length:19 +Found:Indirect-related BITconfig:ID:1360, bitoffs:20, length:20 +Found:Indirect-related BITconfig:ID:1360, bitoffs:21, length:21 +Found:Indirect-related BITconfig:ID:1361, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:1360, bitoffs:23, length:24 +Found:Indirect-related BITconfig:ID:1360, bitoffs:25, length:25 +Found:Indirect-related BITconfig:ID:1360, bitoffs:26, length:26 +Found:Indirect-related BITconfig:ID:1360, bitoffs:27, length:27 +Found:Indirect-related BITconfig:ID:1360, bitoffs:28, length:28 +Found:Indirect-related BITconfig:ID:1360, bitoffs:29, length:29 +Found:Indirect-related BITconfig:ID:1360, bitoffs:30, length:30 +Found:Indirect-related BITconfig:ID:1360, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1361, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:1361, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:1361, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1361, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:1361, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1361, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1360, bitoffs:22, length:22 +Found:Indirect-related BITconfig:ID:1361, bitoffs:7, length:7 +Found:Indirect-related BITconfig:ID:1361, bitoffs:8, length:8 +Found:Indirect-related BITconfig:ID:1361, bitoffs:9, length:9 +Found:Indirect-related BITconfig:ID:1361, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:1361, bitoffs:19, length:19 +Found:Indirect-related BITconfig:ID:1361, bitoffs:20, length:20 +Found:Indirect-related BITconfig:ID:1361, bitoffs:21, length:21 +Found:Indirect-related BITconfig:ID:1361, bitoffs:22, length:22 +Found:Indirect-related BITconfig:ID:1361, bitoffs:23, length:23 +Found:Indirect-related BITconfig:ID:1361, bitoffs:24, length:24 +Found:Indirect-related BITconfig:ID:1361, bitoffs:25, length:25 +Found:Indirect-related BITconfig:ID:1358, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:1358, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:1358, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1358, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:1358, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1358, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1358, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:1358, bitoffs:7, length:7 +Found:Indirect-related BITconfig:ID:1358, bitoffs:8, length:8 +Found:Indirect-related BITconfig:ID:1358, bitoffs:9, length:9 +Found:Indirect-related BITconfig:ID:1358, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:1358, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:1358, bitoffs:12, length:12 +Found:Indirect-related BITconfig:ID:1358, bitoffs:13, length:13 +Found:Indirect-related BITconfig:ID:1358, bitoffs:14, length:14 +Found:Indirect-related BITconfig:ID:1358, bitoffs:15, length:15 +Found:Indirect-related BITconfig:ID:1358, bitoffs:16, length:16 +Found:Indirect-related BITconfig:ID:1358, bitoffs:17, length:17 +Found:Indirect-related BITconfig:ID:1358, bitoffs:18, length:18 +Found:Indirect-related BITconfig:ID:1358, bitoffs:19, length:19 +Found:Indirect-related BITconfig:ID:1358, bitoffs:20, length:20 +Found:Indirect-related BITconfig:ID:1358, bitoffs:21, length:21 +Found:Indirect-related BITconfig:ID:1358, bitoffs:22, length:22 +Found:Indirect-related BITconfig:ID:1358, bitoffs:23, length:23 +Found:Indirect-related BITconfig:ID:1358, bitoffs:24, length:24 +Found:Indirect-related BITconfig:ID:1358, bitoffs:25, length:25 +Found:Indirect-related BITconfig:ID:1358, bitoffs:26, length:26 +Found:Indirect-related BITconfig:ID:1358, bitoffs:27, length:27 +Found:Indirect-related BITconfig:ID:1358, bitoffs:28, length:28 +Found:Indirect-related BITconfig:ID:1358, bitoffs:29, length:29 +Found:Indirect-related BITconfig:ID:2088, bitoffs:18, length:21 +Found:Indirect-related BITconfig:ID:1359, bitoffs:18, length:18 +Found:Indirect-related BITconfig:ID:1359, bitoffs:19, length:19 +Found:Indirect-related BITconfig:ID:1359, bitoffs:20, length:20 +Found:Indirect-related BITconfig:ID:1359, bitoffs:21, length:21 +Found:Indirect-related BITconfig:ID:1359, bitoffs:22, length:22 +Found:Indirect-related BITconfig:ID:1359, bitoffs:23, length:23 +Found:Indirect-related BITconfig:ID:1359, bitoffs:24, length:24 +Found:Indirect-related BITconfig:ID:1359, bitoffs:25, length:25 +Found:Indirect-related BITconfig:ID:1359, bitoffs:26, length:26 +Found:Indirect-related BITconfig:ID:1000, bitoffs:0, length:2 +Found:Indirect-related BITconfig:ID:1000, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:1000, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1000, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1000, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:1000, bitoffs:7, length:7 +Found:Indirect-related BITconfig:ID:1000, bitoffs:8, length:8 +Found:Indirect-related BITconfig:ID:1000, bitoffs:9, length:11 +Found:Indirect-related BITconfig:ID:1000, bitoffs:12, length:12 +Found:Indirect-related BITconfig:ID:1000, bitoffs:13, length:13 +Found:Indirect-related BITconfig:ID:1001, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:1001, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:1001, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1001, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:1001, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1001, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1001, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:1001, bitoffs:7, length:7 +Found:Indirect-related BITconfig:ID:1001, bitoffs:8, length:8 +Found:Indirect-related BITconfig:ID:1001, bitoffs:9, length:9 +Found:Indirect-related BITconfig:ID:1001, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:1001, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:1001, bitoffs:12, length:12 +Found:Indirect-related BITconfig:ID:1001, bitoffs:13, length:13 +Found:Indirect-related BITconfig:ID:1001, bitoffs:14, length:14 +Found:Indirect-related BITconfig:ID:1001, bitoffs:15, length:15 +Found:Indirect-related BITconfig:ID:1001, bitoffs:16, length:16 +Found:Indirect-related BITconfig:ID:1001, bitoffs:17, length:17 +Found:Indirect-related BITconfig:ID:1001, bitoffs:18, length:18 +Found:Indirect-related BITconfig:ID:1002, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:1002, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:1002, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1002, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:1002, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1002, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1002, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:1002, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1002, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:1002, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:1000, bitoffs:14, length:14 +Found:Indirect-related BITconfig:ID:1000, bitoffs:15, length:15 +Found:Indirect-related BITconfig:ID:1000, bitoffs:16, length:16 +Found:Indirect-related BITconfig:ID:1000, bitoffs:17, length:17 +Found:Indirect-related BITconfig:ID:1000, bitoffs:18, length:18 +Found:Indirect-related BITconfig:ID:1000, bitoffs:19, length:19 +Found:Indirect-related BITconfig:ID:1000, bitoffs:20, length:20 +Found:Indirect-related BITconfig:ID:1000, bitoffs:21, length:21 +Found:Indirect-related BITconfig:ID:1372, bitoffs:4, length:6 +Found:Indirect-related BITconfig:ID:1372, bitoffs:7, length:8 +Found:Indirect-related BITconfig:ID:1372, bitoffs:9, length:9 +Found:Indirect-related BITconfig:ID:1372, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:1372, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:1372, bitoffs:12, length:14 +Found:Indirect-related BITconfig:ID:1372, bitoffs:15, length:17 +Found:Indirect-related BITconfig:ID:1372, bitoffs:18, length:20 +Found:Indirect-related BITconfig:ID:1372, bitoffs:21, length:21 +Found:Indirect-related BITconfig:ID:1372, bitoffs:22, length:22 +Found:Indirect-related BITconfig:ID:1372, bitoffs:23, length:23 +Found:Indirect-related BITconfig:ID:1372, bitoffs:24, length:24 +Found:Indirect-related BITconfig:ID:1372, bitoffs:29, length:29 +Found:Indirect-related BITconfig:ID:1372, bitoffs:30, length:30 +Found:Indirect-related BITconfig:ID:1372, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1373, bitoffs:0, length:3 +Found:Indirect-related BITconfig:ID:1373, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1373, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1373, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:1373, bitoffs:7, length:7 +Found:Indirect-related BITconfig:ID:1373, bitoffs:8, length:8 +Found:Indirect-related BITconfig:ID:1373, bitoffs:9, length:9 +Found:Indirect-related BITconfig:ID:1373, bitoffs:10, length:11 +Found:Indirect-related BITconfig:ID:1373, bitoffs:12, length:15 +Found:Indirect-related BITconfig:ID:1373, bitoffs:16, length:16 +Found:Indirect-related BITconfig:ID:1373, bitoffs:17, length:19 +Found:Indirect-related BITconfig:ID:1373, bitoffs:20, length:20 +Found:Indirect-related BITconfig:ID:1373, bitoffs:21, length:21 +Found:Indirect-related BITconfig:ID:1373, bitoffs:26, length:26 +Found:Indirect-related BITconfig:ID:1373, bitoffs:27, length:27 +Found:Indirect-related BITconfig:ID:1373, bitoffs:28, length:28 +Found:Indirect-related BITconfig:ID:1373, bitoffs:29, length:29 +Found:Indirect-related BITconfig:ID:1374, bitoffs:0, length:2 +Found:Indirect-related BITconfig:ID:1374, bitoffs:3, length:5 +Found:Indirect-related BITconfig:ID:1374, bitoffs:6, length:8 +Found:Indirect-related BITconfig:ID:1887, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:1887, bitoffs:7, length:7 +Found:Indirect-related BITconfig:ID:1887, bitoffs:12, length:12 +Found:Indirect-related BITconfig:ID:1887, bitoffs:16, length:16 +Found:Indirect-related BITconfig:ID:1887, bitoffs:19, length:19 +Found:Indirect-related BITconfig:ID:1071, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:1071, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:1071, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1071, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:1071, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1071, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1071, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:1071, bitoffs:7, length:7 +Found:Indirect-related BITconfig:ID:1071, bitoffs:8, length:8 +Found:Indirect-related BITconfig:ID:1071, bitoffs:9, length:9 +Found:Indirect-related BITconfig:ID:1071, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:1071, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:1071, bitoffs:12, length:12 +Found:Indirect-related BITconfig:ID:1071, bitoffs:13, length:13 +Found:Indirect-related BITconfig:ID:1071, bitoffs:14, length:14 +Found:Indirect-related BITconfig:ID:1071, bitoffs:15, length:15 +Found:Indirect-related BITconfig:ID:1071, bitoffs:16, length:16 +Found:Indirect-related BITconfig:ID:1071, bitoffs:18, length:18 +Found:Indirect-related BITconfig:ID:1071, bitoffs:19, length:19 +Found:Indirect-related BITconfig:ID:1071, bitoffs:17, length:17 +Found:Indirect-related BITconfig:ID:1072, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1072, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:1072, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1072, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1072, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:1072, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:1072, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:1072, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:1072, bitoffs:12, length:12 +Found:Indirect-related BITconfig:ID:1072, bitoffs:13, length:13 +Found:Indirect-related BITconfig:ID:1072, bitoffs:14, length:14 +Found:Indirect-related BITconfig:ID:1072, bitoffs:15, length:15 +Found:Indirect-related BITconfig:ID:1072, bitoffs:16, length:16 +Found:Indirect-related BITconfig:ID:1072, bitoffs:17, length:17 +Found:Indirect-related BITconfig:ID:1072, bitoffs:18, length:18 +Found:Indirect-related BITconfig:ID:1072, bitoffs:19, length:19 +Found:Indirect-related BITconfig:ID:1072, bitoffs:20, length:20 +Found:Indirect-related BITconfig:ID:1072, bitoffs:21, length:21 +Found:Indirect-related BITconfig:ID:1072, bitoffs:22, length:22 +Found:Indirect-related BITconfig:ID:1072, bitoffs:23, length:23 +Found:Indirect-related BITconfig:ID:1073, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:1073, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:1073, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1073, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:1073, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1073, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1073, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:1073, bitoffs:7, length:7 +Found:Indirect-related BITconfig:ID:1073, bitoffs:8, length:8 +Found:Indirect-related BITconfig:ID:1073, bitoffs:9, length:9 +Found:Indirect-related BITconfig:ID:1073, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:1073, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:1073, bitoffs:12, length:12 +Found:Indirect-related BITconfig:ID:1073, bitoffs:13, length:13 +Found:Indirect-related BITconfig:ID:1073, bitoffs:14, length:14 +Found:Indirect-related BITconfig:ID:1073, bitoffs:15, length:15 +Found:Indirect-related BITconfig:ID:1073, bitoffs:16, length:16 +Found:Indirect-related BITconfig:ID:1073, bitoffs:17, length:17 +Found:Indirect-related BITconfig:ID:1073, bitoffs:18, length:18 +Found:Indirect-related BITconfig:ID:1073, bitoffs:22, length:22 +Found:Indirect-related BITconfig:ID:1073, bitoffs:23, length:23 +Found:Indirect-related BITconfig:ID:1073, bitoffs:25, length:25 +Found:Indirect-related BITconfig:ID:1956, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:1956, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:1956, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1956, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:1956, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1956, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1956, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:1956, bitoffs:8, length:8 +Found:Indirect-related BITconfig:ID:1956, bitoffs:9, length:9 +Found:Indirect-related BITconfig:ID:1956, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:1956, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:1956, bitoffs:12, length:12 +Found:Indirect-related BITconfig:ID:1956, bitoffs:13, length:13 +Found:Indirect-related BITconfig:ID:1956, bitoffs:14, length:14 +Found:Indirect-related BITconfig:ID:1956, bitoffs:15, length:15 +Found:Indirect-related BITconfig:ID:1956, bitoffs:16, length:16 +Found:Indirect-related BITconfig:ID:1956, bitoffs:17, length:17 +Found:Indirect-related BITconfig:ID:1956, bitoffs:18, length:18 +Found:Indirect-related BITconfig:ID:1956, bitoffs:19, length:19 +Found:Indirect-related BITconfig:ID:1956, bitoffs:20, length:20 +Found:Indirect-related BITconfig:ID:1956, bitoffs:21, length:21 +Found:Indirect-related BITconfig:ID:1956, bitoffs:22, length:22 +Found:Indirect-related BITconfig:ID:1956, bitoffs:23, length:23 +Found:Indirect-related BITconfig:ID:1956, bitoffs:24, length:24 +Found:Indirect-related BITconfig:ID:1956, bitoffs:25, length:25 +Found:Indirect-related BITconfig:ID:1956, bitoffs:26, length:26 +Found:Indirect-related BITconfig:ID:1956, bitoffs:27, length:27 +Found:Indirect-related BITconfig:ID:1956, bitoffs:28, length:28 +Found:Indirect-related BITconfig:ID:1956, bitoffs:29, length:29 +Found:Indirect-related BITconfig:ID:1956, bitoffs:30, length:30 +Found:Indirect-related BITconfig:ID:1956, bitoffs:31, length:31 +Found:Indirect-related BITconfig:ID:1957, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:1957, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:1957, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1957, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:1957, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:1957, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:1957, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:1957, bitoffs:7, length:7 +Found:Indirect-related BITconfig:ID:1957, bitoffs:8, length:8 +Found:Indirect-related BITconfig:ID:1957, bitoffs:9, length:9 +Found:Indirect-related BITconfig:ID:1957, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:1957, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:1957, bitoffs:12, length:12 +Found:Indirect-related BITconfig:ID:1957, bitoffs:25, length:25 +Found:Indirect-related BITconfig:ID:1957, bitoffs:26, length:26 +Found:Indirect-related BITconfig:ID:1957, bitoffs:13, length:13 +Found:Indirect-related BITconfig:ID:1957, bitoffs:14, length:14 +Found:Indirect-related BITconfig:ID:1957, bitoffs:15, length:15 +Found:Indirect-related BITconfig:ID:1957, bitoffs:16, length:16 +Found:Indirect-related BITconfig:ID:1957, bitoffs:17, length:17 +Found:Indirect-related BITconfig:ID:1957, bitoffs:18, length:18 +Found:Indirect-related BITconfig:ID:1957, bitoffs:19, length:19 +Found:Indirect-related BITconfig:ID:1957, bitoffs:20, length:20 +Found:Indirect-related BITconfig:ID:1957, bitoffs:21, length:21 +Found:Indirect-related BITconfig:ID:1957, bitoffs:22, length:22 +Found:Indirect-related BITconfig:ID:1957, bitoffs:23, length:23 +Found:Indirect-related BITconfig:ID:1957, bitoffs:24, length:24 +Found:Indirect-related BITconfig:ID:1957, bitoffs:27, length:27 +Found:Indirect-related BITconfig:ID:2082, bitoffs:5, length:6 +Found:Indirect-related BITconfig:ID:2082, bitoffs:9, length:9 +Found:Indirect-related BITconfig:ID:2082, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:2082, bitoffs:13, length:13 +Found:Indirect-related BITconfig:ID:2082, bitoffs:14, length:14 +Found:Indirect-related BITconfig:ID:2082, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:2082, bitoffs:2, length:3 +Found:Indirect-related BITconfig:ID:2082, bitoffs:15, length:15 +Found:Indirect-related BITconfig:ID:2082, bitoffs:22, length:22 +Found:Indirect-related BITconfig:ID:2082, bitoffs:16, length:16 +Found:Indirect-related BITconfig:ID:2082, bitoffs:17, length:17 +Found:Indirect-related BITconfig:ID:2082, bitoffs:18, length:18 +Found:Indirect-related BITconfig:ID:2082, bitoffs:19, length:19 +Found:Indirect-related BITconfig:ID:2082, bitoffs:20, length:20 +Found:Indirect-related BITconfig:ID:2082, bitoffs:21, length:21 +Found:Indirect-related BITconfig:ID:1957, bitoffs:28, length:28 +Found:Indirect-related BITconfig:ID:1957, bitoffs:29, length:29 +Found:Indirect-related BITconfig:ID:1957, bitoffs:30, length:30 +Found:Indirect-related BITconfig:ID:1957, bitoffs:31, length:31 +Found:Indirect-related config:63 +Found:Indirect-related config:165 +Found:Indirect-related config:68 +Found:Indirect-related config:180 +Found:Indirect-related config:30 +Found:Indirect-related config:212 +Found:Indirect-related config:159 +Found:Indirect-related config:139 +Found:Indirect-related config:365 +Found:Indirect-related config:492 +Found:Indirect-related config:107 +Found:Indirect-related config:29 +Found:Indirect-related config:176 +Found:Indirect-related config:122 +Found:Indirect-related config:347 +Found:Indirect-related config:76 +Found:Indirect-related config:116 +Found:Indirect-related config:175 +Found:Indirect-related config:320 +Found:Indirect-related config:150 +Found:Indirect-related config:192 +Found:Indirect-related config:416 +Found:Indirect-related config:148 +Found:Indirect-related config:101 +Found:Indirect-related config:111 +Found:Indirect-related config:451 +Found:Indirect-related config:1199 +Found:Indirect-related config:302 +Found:Indirect-related config:339 +Found:Indirect-related config:273 +Found:Indirect-related BITconfig:ID:977, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1303, bitoffs:21, length:21 +Found:Indirect-related BITconfig:ID:1178, bitoffs:1, length:10 +Found:Indirect-related BITconfig:ID:810, bitoffs:9, length:9 +Found:Indirect-related BITconfig:ID:1204, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:912, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:635, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:1274, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:823, bitoffs:0, length:19 +Found:Indirect-related BITconfig:ID:1077, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:313, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:1190, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:177, bitoffs:15, length:15 +Found:Indirect-related BITconfig:ID:553, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:571, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:607, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:496, bitoffs:0, length:2 +Found:Indirect-related BITconfig:ID:874, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1577, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:77, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:1023, bitoffs:17, length:18 +Found:Indirect-related BITconfig:ID:1023, bitoffs:0, length:1 +Found:Indirect-related BITconfig:ID:730, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:1023, bitoffs:15, length:16 +Found:Indirect-related BITconfig:ID:1023, bitoffs:11, length:12 +Found:Indirect-related BITconfig:ID:1588, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1330, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:299, bitoffs:20, length:20 +Found:Indirect-related BITconfig:ID:1050, bitoffs:1, length:4 +Found:Indirect-related BITconfig:ID:992, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:802, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:802, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:802, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:802, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:709, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1010, bitoffs:12, length:12 +Found:Indirect-related BITconfig:ID:440, bitoffs:0, length:14 +Found:Indirect-related BITconfig:ID:1600, bitoffs:0, length:3 +Found:Indirect-related BITconfig:ID:1282, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:449, bitoffs:22, length:31 +Found:Indirect-related BITconfig:ID:1303, bitoffs:16, length:19 +Found:Indirect-related BITconfig:ID:1303, bitoffs:10, length:15 +Found:Indirect-related BITconfig:ID:1386, bitoffs:18, length:19 +Found:Indirect-related BITconfig:ID:1289, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:1289, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:1289, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:714, bitoffs:3, length:6 +Found:Indirect-related BITconfig:ID:1242, bitoffs:1, length:31 +Found:Indirect-related BITconfig:ID:1049, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1261, bitoffs:3, length:4 +Found:Indirect-related config:131 +Found:Indirect-related config:223 +Found:Indirect-related config:14 +Found:Indirect-related config:112 +Found:Indirect-related config:145 +Found:Indirect-related config:146 +Found:Indirect-related config:26 +Found:Indirect-related BITconfig:ID:1311, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:222, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1403, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:705, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:604, bitoffs:0, length:2 +Found:Indirect-related BITconfig:ID:568, bitoffs:0, length:6 +Found:Indirect-related config:2068 +Found:Indirect-related config:450 +Found:Indirect-related config:130 +Found:Indirect-related config:31 +Found:Indirect-related config:32 +Found:Indirect-related config:160 +Found:Indirect-related config:71 +Found:Indirect-related config:293 +Found:Indirect-related config:655 +Found:Indirect-related config:10 +Found:Indirect-related config:399 +Found:Indirect-related config:314 +Found:Indirect-related config:80 +Found:Indirect-related config:0 +Found:Indirect-related config:335 +Found:Indirect-related config:299 +Found:Indirect-related config:17 +Found:Indirect-related config:11 +Found:Indirect-related config:65 +Found:Indirect-related config:382 +Found:Indirect-related config:188 +Found:Indirect-related config:5 +Found:Indirect-related config:387 +Found:Indirect-related config:147 +Found:Indirect-related config:517 +Found:Indirect-related config:307 +Found:Indirect-related config:328 +Found:Indirect-related config:402 +Found:Indirect-related config:600 +Found:Indirect-related config:60 +Found:Indirect-related config:359 +Found:Indirect-related config:197 +Found:Indirect-related config:226 +Found:Indirect-related config:200 +Found:Indirect-related config:385 +Found:Indirect-related config:317 +Found:Indirect-related config:161 +Found:Indirect-related config:162 +Found:Indirect-related config:980 +Found:Indirect-related BITconfig:ID:62, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:178, bitoffs:0, length:1 +Found:Indirect-related BITconfig:ID:939, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:433, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:964, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:455, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:400, bitoffs:23, length:23 +Found:Indirect-related BITconfig:ID:869, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:794, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:622, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:934, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:896, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:641, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:844, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:671, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:810, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:435, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:521, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:408, bitoffs:28, length:31 +Found:Indirect-related BITconfig:ID:482, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:437, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:351, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:445, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:465, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:423, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:574, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:905, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:714, bitoffs:0, length:2 +Found:Indirect-related BITconfig:ID:678, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:602, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:616, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:723, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:449, bitoffs:0, length:1 +Found:Indirect-related BITconfig:ID:968, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:970, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:994, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:997, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:1003, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1016, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1063, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:1094, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1165, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:1184, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:1218, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:1225, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1227, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1232, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1236, bitoffs:0, length:10 +Found:Indirect-related BITconfig:ID:1271, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:1306, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1370, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1365, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:1407, bitoffs:0, length:9 +Found:Indirect-related BITconfig:ID:1415, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1475, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1420, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1390, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1327, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1819, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:1498, bitoffs:0, length:15 +Found:Indirect-related BITconfig:ID:1558, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:1610, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1811, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1849, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1646, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1844, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1834, bitoffs:28, length:31 +Found:Indirect-related BITconfig:ID:1861, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:2037, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1906, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1889, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:2217, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:2020, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:2046, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:2051, bitoffs:0, length:8 +Found:Indirect-related BITconfig:ID:2079, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:2208, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:2234, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:2376, bitoffs:0, length:7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1425 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1421 +Found:Related GlobalIntVar(ButtonGraphics):1428 +Found:Indirect-related BITconfig:ID:1958, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1958, bitoffs:12, length:23 +Found:Indirect-related BITconfig:ID:2083, bitoffs:7, length:7 +Found:Indirect-related BITconfig:ID:1960, bitoffs:22, length:24 +Found:Indirect-related BITconfig:ID:1962, bitoffs:11, length:22 +Found:Related BITconfig:ID:2083, bitoffs:0, length:6 +Found:Related GlobalIntVar(ButtonGraphics):1424 +Found:Related GlobalIntVar(ButtonGraphics):1423 +Hidden child:92 +Hidden child:94 +Hidden child:103 +Hidden child:122 +Hidden child:125 +Hidden child:130 +Hidden child:171 +INTERFACE:1057 +Found:Related BITconfig:ID:2030, bitoffs:16, length:31 +Found:Related BITconfig:ID:788, bitoffs:16, length:31 +Found:Related BITconfig:ID:2030, bitoffs:0, length:15 +Found:Related BITconfig:ID:787, bitoffs:0, length:15 +Found:Related BITconfig:ID:787, bitoffs:16, length:31 +Found:Related BITconfig:ID:788, bitoffs:13, length:15 +Found:Related BITconfig:ID:793, bitoffs:5, length:7 +Found:Related BITconfig:ID:793, bitoffs:8, length:10 +Found:Related BITconfig:ID:793, bitoffs:11, length:13 +Found:Related BITconfig:ID:793, bitoffs:14, length:16 +Found:Related BITconfig:ID:793, bitoffs:17, length:19 +Found:Related BITconfig:ID:793, bitoffs:24, length:24 +Found:Related BITconfig:ID:793, bitoffs:25, length:25 +Found:Related BITconfig:ID:793, bitoffs:26, length:26 +Found:Related BITconfig:ID:793, bitoffs:27, length:27 +Found:Related BITconfig:ID:793, bitoffs:28, length:28 +Hidden child:12 +Hidden child:15 +Hidden child:18 +Hidden child:21 +Hidden child:24 +Hidden child:34 +Hidden child:35 +Hidden child:36 +Hidden child:37 +Hidden child:38 +Hidden child:39 +INTERFACE:1058 +Found:Indirect-related BITconfig:ID:788, bitoffs:16, length:31 +Found:Indirect-related BITconfig:ID:787, bitoffs:0, length:15 +Found:Indirect-related BITconfig:ID:787, bitoffs:16, length:31 +Found:Indirect-related BITconfig:ID:2030, bitoffs:0, length:15 +Found:Indirect-related BITconfig:ID:2030, bitoffs:16, length:31 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1432 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1431 +Found:Related BITconfig:ID:791, bitoffs:4, length:4 +Found:Related BITconfig:ID:791, bitoffs:1, length:3 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:9 +Hidden child:10 +Hidden child:31 +Hidden child:35 +Hidden child:39 +INTERFACE:1059 +Found:Related GlobalIntVar(ButtonGraphics):1433 +INTERFACE:1060 +INTERFACE:1061 +INTERFACE:1062 +INTERFACE:1063 +Hidden child:2 +Hidden child:3 +Hidden child:4 +Hidden child:5 +INTERFACE:1064 +Found:Related BITconfig:ID:2034, bitoffs:23, length:27 +INTERFACE:1065 +Found:Related GlobalIntVar(ButtonGraphics):1434 +INTERFACE:1066 +INTERFACE:1067 +INTERFACE:1068 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:1069 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:1070 +INTERFACE:1071 +INTERFACE:1072 +Found:Related BITconfig:ID:2064, bitoffs:5, length:9 +Found:Related BITconfig:ID:2064, bitoffs:3, length:4 +Found:Related BITconfig:ID:2060, bitoffs:20, length:31 +Found:Related BITconfig:ID:2063, bitoffs:0, length:12 +Found:Related BITconfig:ID:2061, bitoffs:17, length:28 +Found:Related BITconfig:ID:2062, bitoffs:0, length:11 +Found:Related BITconfig:ID:2062, bitoffs:12, length:24 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:77 +Hidden child:85 +Hidden child:90 +Hidden child:229 +Hidden child:241 +Hidden child:253 +INTERFACE:1073 +INTERFACE:1074 +Found:Related BITconfig:ID:2067, bitoffs:0, length:0 +Found:Related BITconfig:ID:2067, bitoffs:1, length:1 +Found:Related BITconfig:ID:2067, bitoffs:2, length:2 +Found:Related BITconfig:ID:2067, bitoffs:3, length:3 +Found:Related BITconfig:ID:2067, bitoffs:4, length:4 +Found:Related BITconfig:ID:2067, bitoffs:5, length:5 +Found:Related BITconfig:ID:2067, bitoffs:6, length:6 +Found:Related BITconfig:ID:2067, bitoffs:7, length:7 +Found:Related BITconfig:ID:2067, bitoffs:8, length:8 +Found:Related BITconfig:ID:2067, bitoffs:9, length:9 +Found:Related BITconfig:ID:2067, bitoffs:10, length:10 +Found:Related BITconfig:ID:2067, bitoffs:11, length:11 +Found:Related BITconfig:ID:2067, bitoffs:12, length:12 +Found:Related BITconfig:ID:2067, bitoffs:13, length:13 +Found:Related BITconfig:ID:2067, bitoffs:14, length:14 +Found:Related BITconfig:ID:2067, bitoffs:15, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:1075 +Found:Related GlobalIntVar(ButtonGraphics):1468 +INTERFACE:1076 +Hidden child:44 +Hidden child:59 +Hidden child:72 +Hidden child:85 +Hidden child:98 +INTERFACE:1077 +Hidden child:11 +Hidden child:18 +Hidden child:24 +Hidden child:30 +Hidden child:36 +INTERFACE:1078 +Found:Related BITconfig:ID:2077, bitoffs:0, length:3 +Found:Related BITconfig:ID:2077, bitoffs:4, length:6 +Found:Related GlobalIntVar(ButtonGraphics):1495 +Hidden child:21 +Hidden child:43 +INTERFACE:1079 +Found:Related config:281 +Hidden child:2 +Hidden child:3 +Hidden child:4 +Hidden child:5 +INTERFACE:1080 +INTERFACE:1081 +INTERFACE:1082 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:40 +Hidden child:61 +Hidden child:78 +Hidden child:87 +Hidden child:96 +Hidden child:103 +Hidden child:112 +Hidden child:113 +Hidden child:114 +Hidden child:179 +INTERFACE:1083 +Found:Related BITconfig:ID:2088, bitoffs:18, length:21 +Found:Indirect-related BITconfig:ID:2088, bitoffs:0, length:16 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:12 +Hidden child:17 +Hidden child:22 +Hidden child:27 +Hidden child:32 +Hidden child:37 +Hidden child:42 +Hidden child:47 +Hidden child:52 +Hidden child:57 +Hidden child:62 +Hidden child:67 +Hidden child:72 +Hidden child:95 +Hidden child:96 +Hidden child:97 +Hidden child:98 +Hidden child:99 +Hidden child:100 +Hidden child:101 +Hidden child:102 +Hidden child:103 +Hidden child:104 +Hidden child:105 +Hidden child:106 +Hidden child:107 +Hidden child:157 +Hidden child:158 +Hidden child:159 +Hidden child:160 +Hidden child:161 +Hidden child:164 +Hidden child:165 +Hidden child:385 +Hidden child:431 +Hidden child:442 +Hidden child:453 +Hidden child:460 +Hidden child:470 +Hidden child:480 +Hidden child:493 +Hidden child:502 +Hidden child:512 +Hidden child:518 +Hidden child:528 +Hidden child:538 +Hidden child:552 +Hidden child:558 +INTERFACE:1084 +Hidden child:105 +INTERFACE:1085 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:1086 +Hidden child:30 +Hidden child:42 +INTERFACE:1087 +Hidden child:24 +INTERFACE:1088 +INTERFACE:1089 +Hidden child:33 +INTERFACE:1090 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:1091 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:1092 +Found:Indirect-related BITconfig:ID:2256, bitoffs:20, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Related BITconfig:ID:2256, bitoffs:3, length:8 +Found:Indirect-related BITconfig:ID:2256, bitoffs:15, length:18 +Found:Indirect-related BITconfig:ID:2260, bitoffs:0, length:1 +Found:Indirect-related BITconfig:ID:2262, bitoffs:15, length:22 +Found:Indirect-related BITconfig:ID:2264, bitoffs:15, length:22 +Found:Indirect-related BITconfig:ID:2266, bitoffs:15, length:22 +Found:Indirect-related BITconfig:ID:2261, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:2261, bitoffs:20, length:21 +Found:Indirect-related BITconfig:ID:2263, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:2263, bitoffs:20, length:21 +Found:Indirect-related BITconfig:ID:2265, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:2265, bitoffs:20, length:21 +Found:Indirect-related BITconfig:ID:2261, bitoffs:8, length:9 +Found:Indirect-related BITconfig:ID:2263, bitoffs:8, length:9 +Found:Indirect-related BITconfig:ID:2265, bitoffs:8, length:9 +Found:Indirect-related BITconfig:ID:2260, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:2260, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:2260, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:2262, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:2262, bitoffs:5, length:9 +Found:Indirect-related BITconfig:ID:2262, bitoffs:10, length:14 +Found:Indirect-related BITconfig:ID:2264, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:2264, bitoffs:5, length:9 +Found:Indirect-related BITconfig:ID:2264, bitoffs:10, length:14 +Found:Indirect-related BITconfig:ID:2266, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:2266, bitoffs:5, length:9 +Found:Indirect-related BITconfig:ID:2266, bitoffs:10, length:14 +Found:Indirect-related BITconfig:ID:2256, bitoffs:0, length:2 +Found:Indirect-related BITconfig:ID:2256, bitoffs:19, length:19 +Found:Indirect-related BITconfig:ID:2261, bitoffs:16, length:17 +Found:Indirect-related BITconfig:ID:2263, bitoffs:16, length:17 +Found:Indirect-related BITconfig:ID:2265, bitoffs:16, length:17 +Found:Related GlobalIntVar(ButtonGraphics):1557 +Found:Related GlobalIntVar(ButtonGraphics):1558 +Found:Related GlobalIntVar(ButtonGraphics):1559 +Hidden child:42 +Hidden child:43 +Hidden child:45 +Hidden child:46 +Hidden child:48 +Hidden child:49 +Hidden child:51 +Hidden child:52 +Hidden child:55 +Hidden child:58 +Hidden child:60 +Hidden child:61 +Hidden child:69 +Hidden child:71 +Hidden child:73 +Hidden child:75 +Hidden child:77 +Hidden child:79 +Hidden child:81 +Hidden child:83 +Hidden child:85 +Hidden child:87 +Hidden child:88 +Hidden child:209 +Hidden child:212 +Hidden child:216 +Hidden child:217 +Hidden child:234 +Hidden child:236 +Hidden child:238 +Hidden child:256 +Hidden child:259 +Hidden child:260 +Hidden child:271 +Hidden child:276 +Hidden child:289 +Hidden child:302 +Hidden child:303 +Hidden child:304 +Hidden child:313 +Hidden child:436 +Hidden child:445 +Hidden child:453 +Hidden child:461 +Hidden child:559 +Hidden child:566 +Hidden child:573 +Hidden child:580 +Hidden child:590 +Hidden child:600 +Hidden child:602 +Hidden child:652 +Hidden child:702 +Hidden child:743 +Hidden child:754 +Hidden child:765 +Hidden child:776 +Hidden child:787 +Hidden child:798 +Hidden child:809 +Hidden child:820 +Hidden child:831 +Hidden child:843 +Hidden child:847 +Hidden child:986 +Hidden child:1053 +Hidden child:1069 +Hidden child:1072 +Hidden child:1133 +Hidden child:1149 +Hidden child:1207 +Hidden child:1223 +Hidden child:1254 +Hidden child:1255 +Hidden child:1273 +Hidden child:1280 +Hidden child:1287 +Hidden child:1294 +Hidden child:1301 +Hidden child:1308 +Hidden child:1315 +Hidden child:1322 +Hidden child:1329 +Hidden child:1336 +Hidden child:1343 +Hidden child:1350 +Hidden child:1357 +Hidden child:1364 +Hidden child:1371 +Hidden child:1378 +Hidden child:1384 +Hidden child:1390 +Hidden child:1396 +Hidden child:1402 +Hidden child:1408 +Hidden child:1415 +Hidden child:1421 +Hidden child:1427 +Hidden child:1433 +Hidden child:1439 +Hidden child:1445 +Hidden child:1451 +Hidden child:1457 +Hidden child:1463 +Hidden child:1469 +Hidden child:1475 +Hidden child:1481 +Hidden child:1487 +Hidden child:1495 +Hidden child:1503 +Hidden child:1511 +Hidden child:1519 +Hidden child:1527 +Hidden child:1535 +Hidden child:1543 +Hidden child:1551 +Hidden child:1559 +Hidden child:1567 +Hidden child:1575 +Hidden child:1583 +Hidden child:1591 +Hidden child:1599 +Hidden child:1772 +Hidden child:1792 +Hidden child:1804 +Hidden child:1816 +Hidden child:1818 +Hidden child:1819 +Hidden child:1820 +Hidden child:1821 +Hidden child:1822 +Hidden child:1823 +Hidden child:1824 +Hidden child:1825 +Hidden child:1826 +INTERFACE:1093 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:1094 +Found:Indirect-related GlobalStringVar(InfoString):348 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:13 +Hidden child:18 +Hidden child:20 +Hidden child:42 +INTERFACE:1095 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:92 +INTERFACE:1096 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1500 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1568 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1565 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1566 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1567 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1564 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1501 +Found:Indirect-related GlobalStringVar(InfoString):347 +Found:Indirect-related BITconfig:ID:2143, bitoffs:10, length:10 +Found:Indirect-related BITconfig:ID:2143, bitoffs:12, length:12 +Found:Indirect-related BITconfig:ID:2143, bitoffs:11, length:11 +Found:Indirect-related BITconfig:ID:2143, bitoffs:13, length:13 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Related GlobalIntVar(ButtonGraphics):1516 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1572 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1574 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1576 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1577 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1578 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1579 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1580 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1581 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1582 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1583 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1584 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1585 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1586 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1587 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1588 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1589 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1590 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1569 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1571 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1570 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1573 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1575 +Hidden child:13 +Hidden child:14 +Hidden child:15 +Hidden child:16 +Hidden child:17 +Hidden child:18 +Hidden child:19 +Hidden child:20 +Hidden child:21 +Hidden child:22 +Hidden child:61 +Hidden child:62 +Hidden child:68 +Hidden child:81 +Hidden child:82 +Hidden child:84 +Hidden child:100 +Hidden child:114 +Hidden child:126 +Hidden child:137 +Hidden child:169 +Hidden child:196 +Hidden child:201 +Hidden child:209 +Hidden child:224 +Hidden child:242 +Hidden child:264 +Hidden child:278 +Hidden child:292 +Hidden child:310 +Hidden child:328 +Hidden child:340 +Hidden child:357 +Hidden child:361 +Hidden child:362 +Hidden child:373 +Hidden child:385 +Hidden child:397 +Hidden child:402 +Hidden child:409 +Hidden child:416 +Hidden child:424 +Hidden child:432 +Hidden child:440 +Hidden child:448 +Hidden child:456 +Hidden child:464 +Hidden child:472 +Hidden child:480 +Hidden child:488 +Hidden child:496 +Hidden child:506 +Hidden child:556 +Hidden child:569 +Hidden child:580 +Hidden child:592 +Hidden child:603 +Hidden child:614 +Hidden child:625 +Hidden child:636 +Hidden child:647 +Hidden child:658 +Hidden child:670 +Hidden child:681 +Hidden child:693 +Hidden child:706 +Hidden child:718 +Hidden child:730 +Hidden child:742 +Hidden child:761 +Hidden child:774 +Hidden child:804 +INTERFACE:1097 +Found:Related BITconfig:ID:2138, bitoffs:0, length:5 +Found:Related BITconfig:ID:2138, bitoffs:6, length:15 +Found:Related BITconfig:ID:2138, bitoffs:16, length:21 +Found:Related BITconfig:ID:2138, bitoffs:22, length:31 +Found:Related BITconfig:ID:2139, bitoffs:0, length:5 +Found:Related BITconfig:ID:2139, bitoffs:6, length:15 +Found:Related BITconfig:ID:2139, bitoffs:16, length:21 +Found:Related BITconfig:ID:2139, bitoffs:22, length:31 +Found:Related BITconfig:ID:2140, bitoffs:0, length:5 +Found:Related BITconfig:ID:2140, bitoffs:6, length:15 +Found:Related BITconfig:ID:2140, bitoffs:16, length:21 +Found:Related BITconfig:ID:2140, bitoffs:22, length:31 +Found:Related BITconfig:ID:2141, bitoffs:0, length:5 +Found:Related BITconfig:ID:2141, bitoffs:6, length:15 +Found:Related BITconfig:ID:2141, bitoffs:16, length:21 +Found:Related BITconfig:ID:2141, bitoffs:22, length:31 +Found:Related BITconfig:ID:2142, bitoffs:0, length:5 +Found:Related BITconfig:ID:2142, bitoffs:6, length:15 +Found:Related BITconfig:ID:2142, bitoffs:16, length:21 +Found:Related BITconfig:ID:2142, bitoffs:22, length:31 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related config:2136 +Hidden child:22 +Hidden child:54 +Hidden child:66 +Hidden child:205 +Hidden child:230 +INTERFACE:1098 +Found:Indirect-related config:2128 +Found:Indirect-related BITconfig:ID:2111, bitoffs:8, length:11 +Found:Indirect-related BITconfig:ID:2111, bitoffs:13, length:13 +Found:Indirect-related BITconfig:ID:2111, bitoffs:14, length:14 +Found:Indirect-related BITconfig:ID:2111, bitoffs:15, length:15 +Found:Indirect-related BITconfig:ID:2111, bitoffs:16, length:16 +Found:Indirect-related BITconfig:ID:2111, bitoffs:17, length:17 +Found:Indirect-related BITconfig:ID:2111, bitoffs:18, length:18 +Found:Indirect-related BITconfig:ID:2111, bitoffs:19, length:19 +Found:Indirect-related BITconfig:ID:2111, bitoffs:20, length:20 +Found:Indirect-related BITconfig:ID:2099, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:2099, bitoffs:8, length:15 +Found:Indirect-related BITconfig:ID:2099, bitoffs:16, length:23 +Found:Indirect-related BITconfig:ID:2099, bitoffs:24, length:31 +Found:Indirect-related BITconfig:ID:2100, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:2100, bitoffs:8, length:15 +Found:Indirect-related BITconfig:ID:2100, bitoffs:16, length:23 +Found:Indirect-related BITconfig:ID:2100, bitoffs:24, length:31 +Found:Indirect-related BITconfig:ID:2116, bitoffs:0, length:15 +Found:Indirect-related BITconfig:ID:2116, bitoffs:16, length:31 +Found:Indirect-related BITconfig:ID:2117, bitoffs:0, length:15 +Found:Indirect-related BITconfig:ID:2117, bitoffs:16, length:31 +Found:Indirect-related BITconfig:ID:2118, bitoffs:0, length:15 +Found:Indirect-related BITconfig:ID:2118, bitoffs:16, length:31 +Found:Indirect-related BITconfig:ID:2119, bitoffs:0, length:15 +Found:Indirect-related BITconfig:ID:2119, bitoffs:16, length:31 +Found:Related config:2120 +Found:Related config:2121 +Found:Related config:2122 +Found:Related config:2123 +Found:Related config:2124 +Found:Related config:2125 +Found:Related config:2126 +Found:Related config:2127 +Found:Related BITconfig:ID:2111, bitoffs:12, length:12 +Found:Related BITconfig:ID:2107, bitoffs:0, length:15 +Found:Related BITconfig:ID:2112, bitoffs:0, length:11 +Found:Related BITconfig:ID:2105, bitoffs:0, length:7 +Found:Related BITconfig:ID:2101, bitoffs:0, length:15 +Found:Related BITconfig:ID:2107, bitoffs:16, length:31 +Found:Related BITconfig:ID:2112, bitoffs:12, length:23 +Found:Related BITconfig:ID:2105, bitoffs:8, length:15 +Found:Related BITconfig:ID:2101, bitoffs:16, length:31 +Found:Related BITconfig:ID:2108, bitoffs:0, length:15 +Found:Related BITconfig:ID:2113, bitoffs:0, length:11 +Found:Related BITconfig:ID:2105, bitoffs:16, length:23 +Found:Related BITconfig:ID:2102, bitoffs:0, length:15 +Found:Related BITconfig:ID:2108, bitoffs:16, length:31 +Found:Related BITconfig:ID:2113, bitoffs:12, length:23 +Found:Related BITconfig:ID:2105, bitoffs:24, length:31 +Found:Related BITconfig:ID:2102, bitoffs:16, length:31 +Found:Related BITconfig:ID:2109, bitoffs:0, length:15 +Found:Related BITconfig:ID:2114, bitoffs:0, length:11 +Found:Related BITconfig:ID:2106, bitoffs:0, length:7 +Found:Related BITconfig:ID:2103, bitoffs:0, length:15 +Found:Related BITconfig:ID:2109, bitoffs:16, length:31 +Found:Related BITconfig:ID:2114, bitoffs:12, length:23 +Found:Related BITconfig:ID:2106, bitoffs:8, length:15 +Found:Related BITconfig:ID:2103, bitoffs:16, length:31 +Found:Related BITconfig:ID:2110, bitoffs:0, length:15 +Found:Related BITconfig:ID:2115, bitoffs:0, length:11 +Found:Related BITconfig:ID:2106, bitoffs:16, length:23 +Found:Related BITconfig:ID:2104, bitoffs:0, length:15 +Found:Related BITconfig:ID:2110, bitoffs:16, length:31 +Found:Related BITconfig:ID:2115, bitoffs:12, length:23 +Found:Related BITconfig:ID:2106, bitoffs:24, length:31 +Found:Related BITconfig:ID:2104, bitoffs:16, length:31 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:64 +Hidden child:76 +Hidden child:89 +Hidden child:102 +Hidden child:149 +Hidden child:164 +Hidden child:179 +Hidden child:205 +Hidden child:212 +Hidden child:224 +Hidden child:238 +Hidden child:261 +Hidden child:263 +Hidden child:272 +Hidden child:281 +Hidden child:290 +Hidden child:299 +Hidden child:308 +Hidden child:317 +Hidden child:326 +Hidden child:335 +Hidden child:347 +INTERFACE:1099 +Found:Indirect-related config:2128 +Found:Indirect-related BITconfig:ID:2175, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:2175, bitoffs:1, length:1 +Found:Indirect-related BITconfig:ID:2175, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:2175, bitoffs:3, length:3 +Found:Indirect-related BITconfig:ID:2175, bitoffs:4, length:4 +Found:Indirect-related BITconfig:ID:2175, bitoffs:5, length:5 +Found:Indirect-related BITconfig:ID:2175, bitoffs:6, length:6 +Found:Indirect-related BITconfig:ID:2175, bitoffs:7, length:7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:108 +Hidden child:110 +Hidden child:156 +Hidden child:168 +INTERFACE:1100 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related GlobalIntVar(ButtonGraphics):1498 +Found:Related GlobalStringVar(InfoString):346 +Hidden child:4 +Hidden child:6 +Hidden child:28 +Hidden child:29 +Hidden child:30 +Hidden child:31 +Hidden child:32 +Hidden child:33 +Hidden child:34 +Hidden child:35 +Hidden child:39 +Hidden child:54 +Hidden child:66 +Hidden child:78 +INTERFACE:1101 +Found:Related config:2134 +Found:Related BITconfig:ID:2133, bitoffs:0, length:0 +Found:Related BITconfig:ID:2133, bitoffs:14, length:18 +Found:Related BITconfig:ID:2132, bitoffs:0, length:12 +Found:Related BITconfig:ID:2132, bitoffs:13, length:25 +Found:Related GlobalIntVar(ButtonGraphics):1499 +Hidden child:32 +Hidden child:53 +INTERFACE:1102 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:2 +Hidden child:48 +Hidden child:57 +Hidden child:70 +INTERFACE:1103 +Found:Indirect-related GlobalStringVar(InfoString):345 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:13 +Hidden child:17 +Hidden child:19 +Hidden child:41 +INTERFACE:1104 +Found:Related GlobalIntVar(ButtonGraphics):1007 +INTERFACE:1105 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Related config:2094 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Related config:2097 +Found:Related config:2095 +Found:Related config:2096 +Found:Indirect-related BITconfig:ID:2093, bitoffs:0, length:15 +Found:Indirect-related BITconfig:ID:2093, bitoffs:16, length:31 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:126 +INTERFACE:1106 +Found:Indirect-related config:2347 +Found:Indirect-related BITconfig:ID:2347, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:2347, bitoffs:0, length:6 +Found:Related GlobalIntVar(ButtonGraphics):1592 +Found:Related GlobalIntVar(ButtonGraphics):1593 +Found:Indirect-related BITconfig:ID:2347, bitoffs:10, length:15 +Found:Related GlobalIntVar(ButtonGraphics):1591 +Hidden child:41 +INTERFACE:1107 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:80 +Hidden child:149 +Hidden child:164 +Hidden child:188 +INTERFACE:1108 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related BITconfig:ID:1083, bitoffs:18, length:18 +Hidden child:34 +INTERFACE:1109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1505 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Related BITconfig:ID:1083, bitoffs:1, length:1 +Found:Related BITconfig:ID:1083, bitoffs:2, length:2 +Found:Related BITconfig:ID:1083, bitoffs:0, length:0 +Found:Related BITconfig:ID:1083, bitoffs:17, length:17 +Found:Related GlobalIntVar(ButtonGraphics):53 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1029 +Found:Indirect-related GlobalStringVar(InfoString):22 +Found:Related GlobalIntVar(ButtonGraphics):1413 +Found:Related GlobalIntVar(ButtonGraphics):11 +Found:Related GlobalIntVar(ButtonGraphics):5 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related config:287 +Found:Indirect-related config:1054 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1027 +Found:Indirect-related GlobalStringVar(InfoString):202 +Hidden child:0 +Hidden child:4 +Hidden child:11 +Hidden child:20 +Hidden child:22 +INTERFACE:1110 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1512 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1035 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1518 +Found:Indirect-related GlobalStringVar(InfoString):126 +Found:Related GlobalIntVar(ButtonGraphics):53 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1513 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1506 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1029 +Found:Indirect-related GlobalStringVar(InfoString):22 +Found:Related GlobalIntVar(ButtonGraphics):1413 +Found:Related GlobalIntVar(ButtonGraphics):11 +Found:Related GlobalIntVar(ButtonGraphics):5 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related config:287 +Found:Indirect-related config:1054 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Hidden child:4 +Hidden child:10 +Hidden child:12 +Hidden child:13 +Hidden child:23 +Hidden child:27 +Hidden child:29 +Hidden child:35 +Hidden child:36 +Hidden child:38 +Hidden child:45 +Hidden child:55 +Hidden child:59 +INTERFACE:1111 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1396 +Found:Indirect-related GlobalIntVar(ButtonGraphics):768 +Found:Indirect-related BITconfig:ID:1736, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:1736, bitoffs:8, length:15 +Found:Indirect-related BITconfig:ID:1736, bitoffs:16, length:23 +Found:Indirect-related BITconfig:ID:1736, bitoffs:24, length:31 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Hidden child:1 +Hidden child:21 +INTERFACE:1112 +Found:Indirect-related BITconfig:ID:1735, bitoffs:0, length:1 +Found:Indirect-related BITconfig:ID:1736, bitoffs:0, length:1 +Found:Indirect-related BITconfig:ID:1736, bitoffs:2, length:5 +Found:Indirect-related BITconfig:ID:1735, bitoffs:2, length:17 +Found:Indirect-related BITconfig:ID:1736, bitoffs:6, length:9 +Found:Indirect-related BITconfig:ID:1736, bitoffs:23, length:24 +Found:Indirect-related BITconfig:ID:1736, bitoffs:10, length:12 +Found:Indirect-related GlobalIntVar(ButtonGraphics):788 +Found:Indirect-related GlobalIntVar(ButtonGraphics):786 +Found:Indirect-related GlobalIntVar(ButtonGraphics):787 +Found:Indirect-related GlobalIntVar(ButtonGraphics):995 +Found:Indirect-related GlobalIntVar(ButtonGraphics):267 +Found:Indirect-related GlobalStringVar(InfoString):38 +Found:Indirect-related GlobalStringVar(InfoString):39 +Found:Related GlobalIntVar(ButtonGraphics):266 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1029 +Found:Indirect-related GlobalStringVar(InfoString):22 +Found:Related GlobalIntVar(ButtonGraphics):5 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related config:287 +Found:Indirect-related config:1054 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:1113 +Found:Indirect-related BITconfig:ID:1260, bitoffs:0, length:2 +Found:Indirect-related BITconfig:ID:1735, bitoffs:0, length:1 +Found:Indirect-related GlobalStringVar(InfoString):129 +INTERFACE:1114 +Found:Indirect-related BITconfig:ID:1260, bitoffs:0, length:2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1095 +Found:Indirect-related GlobalStringVar(InfoString):129 +Found:Related BITconfig:ID:1734, bitoffs:0, length:2 +Found:Indirect-related BITconfig:ID:1736, bitoffs:29, length:30 +Found:Indirect-related BITconfig:ID:1736, bitoffs:25, length:25 +Found:Indirect-related BITconfig:ID:1736, bitoffs:26, length:26 +Found:Indirect-related BITconfig:ID:1736, bitoffs:23, length:24 +Found:Indirect-related BITconfig:ID:1736, bitoffs:0, length:1 +Found:Indirect-related BITconfig:ID:1736, bitoffs:2, length:5 +Found:Indirect-related BITconfig:ID:1736, bitoffs:6, length:9 +Found:Indirect-related BITconfig:ID:1736, bitoffs:10, length:12 +Found:Indirect-related BITconfig:ID:1736, bitoffs:13, length:14 +Found:Indirect-related BITconfig:ID:1736, bitoffs:15, length:15 +Found:Indirect-related BITconfig:ID:1736, bitoffs:16, length:16 +Found:Indirect-related BITconfig:ID:1736, bitoffs:17, length:18 +Found:Indirect-related BITconfig:ID:1736, bitoffs:19, length:19 +Found:Indirect-related BITconfig:ID:1736, bitoffs:20, length:20 +Found:Indirect-related BITconfig:ID:1736, bitoffs:21, length:21 +Found:Indirect-related BITconfig:ID:1736, bitoffs:22, length:22 +Found:Indirect-related BITconfig:ID:1736, bitoffs:27, length:27 +Found:Indirect-related BITconfig:ID:1736, bitoffs:28, length:28 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Hidden child:28 +INTERFACE:1115 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1561 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1562 +Hidden child:0 +Hidden child:2 +Hidden child:9 +Hidden child:27 +Hidden child:33 +Hidden child:34 +Hidden child:42 +Hidden child:46 +Hidden child:48 +Hidden child:50 +Hidden child:61 +Hidden child:80 +Hidden child:83 +Hidden child:87 +Hidden child:91 +Hidden child:118 +Hidden child:171 +Hidden child:183 +INTERFACE:1116 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Indirect-related config:2317 +Found:Indirect-related config:2307 +Found:Indirect-related config:2308 +Found:Indirect-related config:2309 +Found:Indirect-related config:2310 +Found:Indirect-related config:2311 +Found:Indirect-related config:2312 +Found:Indirect-related config:2313 +Found:Indirect-related config:2314 +Found:Indirect-related config:2315 +Hidden child:3 +Hidden child:4 +Hidden child:35 +Hidden child:40 +Hidden child:136 +Hidden child:145 +Hidden child:163 +Hidden child:212 +Hidden child:261 +Hidden child:310 +Hidden child:359 +Hidden child:408 +Hidden child:457 +Hidden child:506 +INTERFACE:1117 +Hidden child:5 +Hidden child:6 +Hidden child:7 +Hidden child:8 +Hidden child:9 +Hidden child:10 +Hidden child:13 +Hidden child:15 +Hidden child:27 +INTERFACE:1118 +Found:Related GlobalIntVar(ButtonGraphics):1007 +INTERFACE:1119 +Found:Indirect-related BITconfig:ID:1734, bitoffs:3, length:9 +Found:Indirect-related GlobalIntVar(ButtonGraphics):777 +Found:Indirect-related GlobalIntVar(ButtonGraphics):696 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:1120 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:6 +INTERFACE:1121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:65 +Hidden child:86 +Hidden child:107 +Hidden child:128 +Hidden child:149 +Hidden child:170 +Hidden child:191 +Hidden child:212 +Hidden child:233 +Hidden child:254 +Hidden child:275 +Hidden child:296 +Hidden child:317 +Hidden child:338 +Hidden child:359 +Hidden child:380 +Hidden child:382 +Hidden child:417 +Hidden child:424 +Hidden child:505 +Hidden child:509 +Hidden child:642 +Hidden child:646 +Hidden child:650 +Hidden child:665 +INTERFACE:1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Related BITconfig:ID:2356, bitoffs:0, length:15 +Found:Related BITconfig:ID:2356, bitoffs:16, length:31 +Found:Related BITconfig:ID:2357, bitoffs:0, length:15 +Found:Indirect-related BITconfig:ID:2357, bitoffs:16, length:19 +Found:Indirect-related BITconfig:ID:2357, bitoffs:20, length:23 +Found:Indirect-related BITconfig:ID:2349, bitoffs:0, length:3 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1597 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1598 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1599 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1600 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1601 +Found:Indirect-related config:2347 +Found:Indirect-related BITconfig:ID:2347, bitoffs:10, length:15 +Found:Indirect-related BITconfig:ID:2347, bitoffs:7, length:9 +Found:Indirect-related BITconfig:ID:2347, bitoffs:0, length:6 +Found:Indirect-related config:145 +Found:Indirect-related config:146 +Found:Indirect-related config:122 +Found:Indirect-related config:130 +Found:Indirect-related config:176 +Found:Indirect-related BITconfig:ID:1646, bitoffs:0, length:5 +Found:Indirect-related BITconfig:ID:1365, bitoffs:0, length:6 +Found:Indirect-related BITconfig:ID:178, bitoffs:0, length:1 +Found:Indirect-related BITconfig:ID:1889, bitoffs:0, length:7 +Found:Indirect-related BITconfig:ID:222, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:62, bitoffs:0, length:5 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1594 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:61 +Hidden child:72 +Hidden child:87 +Hidden child:129 +Hidden child:233 +Hidden child:242 +Hidden child:252 +Hidden child:264 +Hidden child:276 +Hidden child:288 +Hidden child:367 +INTERFACE:1123 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:8 +Hidden child:21 +Hidden child:44 +INTERFACE:1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:81 +Hidden child:82 +Hidden child:83 +Hidden child:86 +Hidden child:89 +INTERFACE:1125 +INTERFACE:1126 +Found:Related BITconfig:ID:984, bitoffs:28, length:31 +Found:Related GlobalIntVar(ButtonGraphics):1186 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Related GlobalIntVar(ButtonGraphics):1184 +Hidden child:47 +Hidden child:80 +Hidden child:108 +Hidden child:121 +Hidden child:139 +Hidden child:161 +Hidden child:194 +Hidden child:196 +INTERFACE:1127 +Found:Related config:2373 +Found:Indirect-related BITconfig:ID:1734, bitoffs:3, length:9 +Found:Indirect-related GlobalIntVar(ButtonGraphics):777 +Found:Indirect-related GlobalIntVar(ButtonGraphics):696 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:9 +Hidden child:10 +Hidden child:11 +Hidden child:30 +Hidden child:43 +Hidden child:56 +Hidden child:61 +Hidden child:62 +Hidden child:63 +Hidden child:64 +Hidden child:65 +Hidden child:66 +Hidden child:67 +Hidden child:68 +Hidden child:69 +Hidden child:70 +Hidden child:71 +Hidden child:72 +INTERFACE:1128 +Found:Indirect-related BITconfig:ID:1343, bitoffs:1, length:31 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:59 +Hidden child:101 +Hidden child:131 +Hidden child:169 +Hidden child:206 +Hidden child:243 +Hidden child:280 +Hidden child:317 +INTERFACE:1129 +INTERFACE:1130 +INTERFACE:1131 +INTERFACE:1132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Hidden child:22 +Hidden child:23 +Hidden child:27 +Hidden child:28 +INTERFACE:1133 +Found:Related BITconfig:ID:2376, bitoffs:13, length:19 +Found:Related BITconfig:ID:2377, bitoffs:4, length:10 +INTERFACE:1134 +INTERFACE:1135 +INTERFACE:1136 +INTERFACE:1137 +Found:Related BITconfig:ID:1733, bitoffs:14, length:31 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:5 +Hidden child:7 +Hidden child:16 +Hidden child:17 +INTERFACE:1138 +Found:Related BITconfig:ID:2385, bitoffs:30, length:31 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:1139 +Found:Related config:261 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1 +Found:Related config:80 +Found:Related BITconfig:ID:1178, bitoffs:1, length:10 +Found:Related BITconfig:ID:738, bitoffs:0, length:4 +Hidden child:4 +Hidden child:5 +Hidden child:6 +Hidden child:7 +Hidden child:8 +Hidden child:9 +Hidden child:10 +Hidden child:11 +Hidden child:12 +Hidden child:13 +Hidden child:14 +Hidden child:15 +Hidden child:16 +Hidden child:17 +Hidden child:18 +Hidden child:19 +Hidden child:20 +Hidden child:21 +Hidden child:22 +Hidden child:23 +Hidden child:24 +Hidden child:25 +Hidden child:26 +Hidden child:27 +Hidden child:28 +INTERFACE:1140 +INTERFACE:1141 +Found:Related BITconfig:ID:1476, bitoffs:0, length:2 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +Hidden child:4 +INTERFACE:1142 +Found:Indirect-related GlobalIntVar(ButtonGraphics):199 +Found:Indirect-related config:281 +Found:Indirect-related BITconfig:ID:466, bitoffs:0, length:0 +Found:Indirect-related BITconfig:ID:466, bitoffs:2, length:2 +Found:Indirect-related BITconfig:ID:1160, bitoffs:23, length:23 +Found:Indirect-related GlobalIntVar(ButtonGraphics):41 +Found:Indirect-related GlobalIntVar(ButtonGraphics):168 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1028 +Found:Indirect-related GlobalStringVar(InfoString):1 +Found:Indirect-related BITconfig:ID:1438, bitoffs:0, length:4 +Found:Indirect-related BITconfig:ID:1438, bitoffs:6, length:10 +Found:Indirect-related BITconfig:ID:1438, bitoffs:11, length:15 +Found:Indirect-related GlobalIntVar(ButtonGraphics):7 +Found:Indirect-related GlobalIntVar(ButtonGraphics):8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):132 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1269 +Found:Indirect-related GlobalIntVar(ButtonGraphics):133 +Found:Indirect-related GlobalStringVar(InfoString):29 +Found:Indirect-related GlobalStringVar(InfoString):276 +Found:Indirect-related BITconfig:ID:2083, bitoffs:8, length:8 +Found:Indirect-related GlobalIntVar(ButtonGraphics):42 +Found:Indirect-related config:287 +Found:Indirect-related BITconfig:ID:638, bitoffs:19, length:19 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1037 +Found:Indirect-related GlobalIntVar(ButtonGraphics):193 +Found:Indirect-related BITconfig:ID:1584, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):182 +Found:Indirect-related GlobalIntVar(ButtonGraphics):119 +Found:Indirect-related GlobalIntVar(ButtonGraphics):44 +Found:Indirect-related GlobalIntVar(ButtonGraphics):45 +Found:Indirect-related GlobalIntVar(ButtonGraphics):46 +Found:Indirect-related GlobalIntVar(ButtonGraphics):47 +Found:Indirect-related GlobalIntVar(ButtonGraphics):48 +Found:Indirect-related GlobalIntVar(ButtonGraphics):49 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1511 +Found:Indirect-related config:2159 +Found:Indirect-related config:1055 +Found:Indirect-related config:1054 +Found:Indirect-related BITconfig:ID:1056, bitoffs:0, length:0 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1413 +Found:Indirect-related BITconfig:ID:1963, bitoffs:0, length:11 +Found:Indirect-related BITconfig:ID:1248, bitoffs:27, length:30 +Found:Indirect-related GlobalIntVar(ButtonGraphics):109 +Found:Indirect-related GlobalIntVar(ButtonGraphics):121 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1122 +Found:Indirect-related GlobalIntVar(ButtonGraphics):1124 +Found:Indirect-related GlobalIntVar(ButtonGraphics):88 +Found:Indirect-related GlobalIntVar(ButtonGraphics):203 +Found:Indirect-related GlobalIntVar(ButtonGraphics):204 +Found:Indirect-related GlobalIntVar(ButtonGraphics):205 +Found:Indirect-related GlobalIntVar(ButtonGraphics):206 +Found:Indirect-related GlobalIntVar(ButtonGraphics):207 +Found:Indirect-related GlobalIntVar(ButtonGraphics):208 +Found:Indirect-related GlobalIntVar(ButtonGraphics):209 +Found:Indirect-related GlobalIntVar(ButtonGraphics):210 +Found:Indirect-related GlobalIntVar(ButtonGraphics):211 +Found:Indirect-related GlobalIntVar(ButtonGraphics):160 +Found:Indirect-related GlobalStringVar(InfoString):0 +INTERFACE:1143 +Found:Indirect-related config:2391 +Found:Indirect-related config:2392 +Found:Indirect-related config:2393 +Found:Indirect-related config:2394 +Found:Indirect-related BITconfig:ID:2226, bitoffs:0, length:3 +Found:Indirect-related config:2229 +Found:Indirect-related config:2230 +Found:Indirect-related config:2231 +Found:Indirect-related config:2232 +Found:Related GlobalIntVar(ButtonGraphics):1648 +Hidden child:24 +Hidden child:25 +Hidden child:26 +Hidden child:50 +Hidden child:146 +Hidden child:167 \ No newline at end of file diff --git a/dumps/scripts/0.cs2 b/dumps/scripts/0.cs2 new file mode 100644 index 0000000..90a48ca --- /dev/null +++ b/dumps/scripts/0.cs2 @@ -0,0 +1,32 @@ +void script_0(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + ivar3 = divide(add(arg1, arg2), 2); + ivar4 = globalarray_0[ivar3]; + globalarray_0[ivar3] = globalarray_0[arg2]; + globalarray_0[arg2] = ivar4; + ivar5 = arg1; + ivar6 = arg1; + ivar7 = -1; + while (ivar6 < arg2) { + if (stringMethod4107(lower(getWidgetText(new WidgetPointer(globalarray_0[ivar6]))), lower(getWidgetText(new WidgetPointer(ivar4)))) < bitAnd(ivar6, 1)) { + ivar7 = globalarray_0[ivar6]; + globalarray_0[ivar6] = globalarray_0[ivar5]; + globalarray_0[ivar5] = ivar7; + ivar5 = add(ivar5, 1); + } + ivar6 = add(ivar6, 1); + } + globalarray_0[arg2] = globalarray_0[ivar5]; + globalarray_0[ivar5] = ivar4; + if (arg1 < subtract(ivar5, 1)) { + script_0(0, arg1, subtract(ivar5, 1)); + } + if (add(ivar5, 1) < arg2) { + script_0(0, add(ivar5, 1), arg2); + } + return; +} diff --git a/dumps/scripts/1.cs2 b/dumps/scripts/1.cs2 new file mode 100644 index 0000000..69e3289 --- /dev/null +++ b/dumps/scripts/1.cs2 @@ -0,0 +1,6 @@ +int script_1(int arg0,int arg1) { + if (isMembersItem(arg1) && isMember()) { + return 0; + } + return getItemAmtInContainer(arg0, arg1); +} diff --git a/dumps/scripts/10.cs2 b/dumps/scripts/10.cs2 new file mode 100644 index 0000000..20b0de2 --- /dev/null +++ b/dumps/scripts/10.cs2 @@ -0,0 +1,135 @@ +void script_10(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,string arg11,string arg12) { + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + deleteAllExtraChilds(new WidgetPointer(arg1)); + ivar11 = add(2, multiply(13, getLineCount(177, 495, "Level " + intToStr(arg2) + ": " + arg11))); + ivar12 = add(2, multiply(13, getLineCount(177, 494, arg12))); + ivar13 = add(add(add(add(add(2, ivar11), ivar12), 32), 14), 2); + if (arg3 == -1) { + ivar13 = subtract(subtract(ivar13, 32), 14); + } + ivar14 = 5; + if (getWidgetActualY(new WidgetPointer(arg0)) < 130) { + ivar14 = subtract(subtract(261, ivar13), 5); + } + createExtraChild(new WidgetPointer(arg1), 3, 0); + setWidgetPosition(5, ivar14, 0, 0); + setWidgetSize(180, ivar13, 0, 0); + setWidgetFilled(1); + setWidgetRGB(new Color(0, 0, 0)); + cs2method2103(42); + createExtraChild(new WidgetPointer(arg1), 3, 1); + setWidgetPosition(6, add(ivar14, 1), 0, 0); + setWidgetSize(179, subtract(ivar13, 1), 0, 0); + setWidgetFilled(0); + setWidgetRGB(new Color(46, 43, 35)); + createExtraChild(new WidgetPointer(arg1), 3, 2); + setWidgetPosition(5, ivar14, 0, 0); + setWidgetSize(179, subtract(ivar13, 1), 0, 0); + setWidgetFilled(0); + setWidgetRGB(new Color(114, 100, 81)); + createExtraChild(new WidgetPointer(arg1), 4, 3); + setWidgetPosition(7, add(ivar14, 2), 0, 0); + setWidgetSize(177, ivar11, 0, 0); + setWidgetTextAlignment(1, 1, 0); + setWidgetFont(495); + setWidgetRGB(new Color(255, 152, 31)); + setWidgetUnknownBoolean(false); + setWidgetText("Level " + intToStr(arg2) + ": " + arg11); + createExtraChild(new WidgetPointer(arg1), 4, 4); + setWidgetPosition(7, add(add(ivar14, 2), ivar11), 0, 0); + setWidgetSize(177, ivar12, 0, 0); + setWidgetTextAlignment(1, 1, 0); + setWidgetFont(494); + setWidgetRGB(new Color(175, 106, 26)); + setWidgetUnknownBoolean(false); + setWidgetText(arg12); + ivar15 = 1; + if (arg5 != -1) { + ivar15 = 2; + } + if (arg7 != -1) { + ivar15 = 3; + } + if (arg9 != -1) { + ivar15 = 4; + } + ivar16 = divide(subtract(190, multiply(ivar15, 35)), add(ivar15, 1)); + if (arg3 != -1) { + createExtraChild(new WidgetPointer(arg1), 5, 5); + setWidgetPosition(ivar16, add(add(add(ivar14, 2), ivar11), ivar12), 0, 0); + setWidgetSize(35, 32, 0, 0); + setItemOnWidgetMethod1200(arg3, -1); + createExtraChild(new WidgetPointer(arg1), 4, 6); + setWidgetPosition(ivar16, add(add(add(add(ivar14, 2), ivar11), ivar12), 32), 0, 0); + setWidgetSize(35, 14, 0, 0); + setWidgetTextAlignment(1, 1, 0); + setWidgetFont(494); + if (script_19(arg3, arg0) >= arg4) { + setWidgetRGB(new Color(0, 255, 0)); + } else { + setWidgetRGB(new Color(255, 0, 0)); + } + setWidgetUnknownBoolean(false); + setWidgetText(script_20(script_19(arg3, arg0)) + "/" + intToStr(arg4)); + } + if (arg5 != -1) { + createExtraChild(new WidgetPointer(arg1), 5, 7); + setWidgetPosition(add(multiply(ivar16, 2), 35), add(add(add(ivar14, 2), ivar11), ivar12), 0, 0); + setWidgetSize(35, 32, 0, 0); + setItemOnWidgetMethod1200(arg5, -1); + createExtraChild(new WidgetPointer(arg1), 4, 8); + setWidgetPosition(add(multiply(ivar16, 2), 35), add(add(add(add(ivar14, 2), ivar11), ivar12), 32), 0, 0); + setWidgetSize(35, 14, 0, 0); + setWidgetTextAlignment(1, 1, 0); + setWidgetFont(494); + if (script_19(arg5, arg0) >= arg6) { + setWidgetRGB(new Color(0, 255, 0)); + } else { + setWidgetRGB(new Color(255, 0, 0)); + } + setWidgetUnknownBoolean(false); + setWidgetText(script_20(script_19(arg5, arg0)) + "/" + intToStr(arg6)); + } + if (arg7 != -1) { + createExtraChild(new WidgetPointer(arg1), 5, 9); + setWidgetPosition(add(multiply(ivar16, 3), 70), add(add(add(ivar14, 2), ivar11), ivar12), 0, 0); + setWidgetSize(35, 32, 0, 0); + setItemOnWidgetMethod1200(arg7, -1); + createExtraChild(new WidgetPointer(arg1), 4, 10); + setWidgetPosition(add(multiply(ivar16, 3), 70), add(add(add(add(ivar14, 2), ivar11), ivar12), 32), 0, 0); + setWidgetSize(35, 14, 0, 0); + setWidgetTextAlignment(1, 1, 0); + setWidgetFont(494); + if (script_19(arg7, arg0) >= arg8) { + setWidgetRGB(new Color(0, 255, 0)); + } else { + setWidgetRGB(new Color(255, 0, 0)); + } + setWidgetUnknownBoolean(false); + setWidgetText(script_20(script_19(arg7, arg0)) + "/" + intToStr(arg8)); + } + if (arg9 != -1) { + createExtraChild(new WidgetPointer(arg1), 5, 11); + setWidgetPosition(add(multiply(ivar16, 4), 105), add(add(add(ivar14, 2), ivar11), ivar12), 0, 0); + setWidgetSize(35, 32, 0, 0); + setItemOnWidgetMethod1200(arg9, -1); + createExtraChild(new WidgetPointer(arg1), 4, 12); + setWidgetPosition(add(multiply(ivar16, 4), 105), add(add(add(add(ivar14, 2), ivar11), ivar12), 32), 0, 0); + setWidgetSize(35, 14, 0, 0); + setWidgetTextAlignment(1, 1, 0); + setWidgetFont(494); + if (script_19(arg9, arg0) >= arg10) { + setWidgetRGB(new Color(0, 255, 0)); + } else { + setWidgetRGB(new Color(255, 0, 0)); + } + setWidgetUnknownBoolean(false); + setWidgetText(script_20(script_19(arg9, arg0)) + "/" + intToStr(arg10)); + } + return; +} diff --git a/dumps/scripts/100.cs2 b/dumps/scripts/100.cs2 new file mode 100644 index 0000000..17f416e --- /dev/null +++ b/dumps/scripts/100.cs2 @@ -0,0 +1,4 @@ +void script_100(int arg0) { + script_559(arg0); + return; +} diff --git a/dumps/scripts/1000.cs2 b/dumps/scripts/1000.cs2 new file mode 100644 index 0000000..09c2034 --- /dev/null +++ b/dumps/scripts/1000.cs2 @@ -0,0 +1,716 @@ +cs2func_script_1000_struct(2,2,0) script_1000(int arg0,int arg1) { + switch (arg0) { + flow_1: + case 0: + switch (arg1) { + case 0: + return newstruct cs2func_script_1000_struct(10, 3224, "Members: Cloth", "Members can now weave " + "" + "cloth" + "" + " on a loom."); + case 1: + return newstruct cs2func_script_1000_struct(10, 20754, "Members: Milestone cape (10)", "Members can now weave a " + "" + "Milestone cape (10)" + "" + " on a loom."); + case 2: + return newstruct cs2func_script_1000_struct(20, 20755, "Members: Milestone cape (20)", "Members can now weave a " + "" + "Milestone cape (20)" + "" + " on a loom."); + case 3: + return newstruct cs2func_script_1000_struct(21, 5418, "Members: Vegetable sack", "Members can now weave " + "" + "vegetable sacks" + "" + " on a loom."); + case 4: + return newstruct cs2func_script_1000_struct(30, 20756, "Members: Milestone cape (30)", "Members can now weave a " + "" + "Milestone cape (30)" + "" + " on a loom."); + case 5: + return newstruct cs2func_script_1000_struct(36, 5376, "Members: Fruit basket", "Members can now weave " + "" + "fruit baskets" + "" + " on a loom."); + case 6: + return newstruct cs2func_script_1000_struct(40, 20757, "Members: Milestone cape (40)", "Members can now weave a " + "" + "Milestone cape (40)" + "" + " on a loom."); + case 7: + return newstruct cs2func_script_1000_struct(50, 20758, "Members: Milestone cape (50)", "Members can now weave a " + "" + "Milestone cape (50)" + "" + " on a loom."); + case 8: + return newstruct cs2func_script_1000_struct(52, 14859, "Members: Seaweed net", "Members can now weave " + "" + "seaweed nets" + "" + " on a loom."); + case 9: + return newstruct cs2func_script_1000_struct(60, 20759, "Members: Milestone cape (60)", "Members can now weave a " + "" + "Milestone cape (60)" + "" + " on a loom."); + case 10: + return newstruct cs2func_script_1000_struct(70, 20760, "Members: Milestone cape (70)", "Members can now weave a " + "" + "Milestone cape (70)" + "" + " on a loom."); + case 11: + return newstruct cs2func_script_1000_struct(80, 20761, "Members: Milestone cape (80)", "Members can now weave a " + "" + "Milestone cape (80)" + "" + " on a loom."); + case 12: + return newstruct cs2func_script_1000_struct(90, 20762, "Members: Milestone cape (90)", "Members can now weave a " + "" + "Milestone cape (90)" + "" + " on a loom."); + } + break; + case 1: + switch (arg1) { + case 0: + return newstruct cs2func_script_1000_struct(1, 1059, "Leather gloves", "You can now craft " + "" + "leather gloves" + "" + "."); + case 1: + return newstruct cs2func_script_1000_struct(7, 1061, "Leather boots", "You can now craft " + "" + "leather boots" + "" + "."); + case 2: + return newstruct cs2func_script_1000_struct(9, 1167, "Leather cowl", "You can now craft " + "" + "leather cowls" + "" + "."); + case 3: + return newstruct cs2func_script_1000_struct(11, 1063, "Leather vambraces", "You can now craft " + "" + "leather vambraces" + "" + "."); + case 4: + return newstruct cs2func_script_1000_struct(14, 1129, "Leather body", "You can now craft " + "" + "leather bodies" + "" + "."); + case 5: + return newstruct cs2func_script_1000_struct(15, 3327, "Members: Snail helmet", "Members can now craft " + "" + "snail helmets" + "" + "."); + case 6: + return newstruct cs2func_script_1000_struct(15, 7539, "Members: Crab shell armour", "Members can now craft " + "" + "crab shell armour" + "" + "."); + case 7: + return newstruct cs2func_script_1000_struct(18, 1095, "Leather chaps", "You can now craft " + "" + "leather chaps" + "" + "."); + case 8: + return newstruct cs2func_script_1000_struct(28, 1131, "Hard leather body", "You can now craft " + "" + "hard leather bodies" + "" + "."); + case 9: + return newstruct cs2func_script_1000_struct(32, 10077, "Members: Spiked vambraces", "Members can now craft " + "" + "spiked vambraces" + "" + "."); + case 10: + return newstruct cs2func_script_1000_struct(35, 6259, "Members: Broodoo shield", "Members can now craft " + "" + "broodoo shields" + "" + "."); + case 11: + return newstruct cs2func_script_1000_struct(38, 1169, "Members: Coif", "Members can now craft " + "" + "coifs" + "" + "."); + case 12: + return newstruct cs2func_script_1000_struct(41, 1133, "Members: Studded body", "Members can now craft " + "" + "studded bodies" + "" + "."); + case 13: + return newstruct cs2func_script_1000_struct(43, 10824, "Members: Yak-hide leg armour", "Members can now craft " + "" + "yak-hide leg armour" + "" + "."); + case 14: + return newstruct cs2func_script_1000_struct(44, 1097, "Members: Studded chaps", "Members can now craft " + "" + "studded chaps" + "" + "."); + case 15: + return newstruct cs2func_script_1000_struct(45, 6328, "Members: Snakeskin boots", "Members can now craft " + "" + "snakeskin boots" + "" + "."); + case 16: + return newstruct cs2func_script_1000_struct(46, 10822, "Members: Yak-hide body armour", "Members can now craft " + "" + "yak-hide body armour" + "" + "."); + case 17: + return newstruct cs2func_script_1000_struct(47, 6330, "Members: Snakeskin vambraces", "Members can now craft " + "" + "snakeskin vambraces" + "" + "."); + case 18: + return newstruct cs2func_script_1000_struct(48, 6326, "Members: Snakeskin bandana", "Members can now craft " + "" + "snakeskin bandanas" + "" + "."); + case 19: + return newstruct cs2func_script_1000_struct(51, 6324, "Members: Snakeskin chaps", "Members can now craft " + "" + "snakeskin chaps" + "" + "."); + case 20: + return newstruct cs2func_script_1000_struct(53, 6322, "Members: Snakeskin body", "Members can now craft " + "" + "snakeskin bodies" + "" + "."); + case 21: + return newstruct cs2func_script_1000_struct(55, 13263, "Members: Slayer helmet" + "
" + " (after Smoking Kills)", "Members can now craft " + "" + "Slayer helmets" + "" + " (after Smoking Kills)."); + case 22: + return newstruct cs2func_script_1000_struct(57, 1065, "Members: Green dragonhide vambraces", "Members can now craft " + "" + "green dragonhide vambraces" + "" + "."); + case 23: + return newstruct cs2func_script_1000_struct(60, 1099, "Members: Green dragonhide chaps", "Members can now craft " + "" + "green dragonhide chaps" + "" + "."); + case 24: + return newstruct cs2func_script_1000_struct(63, 1135, "Members: Green dragonhide body", "Members can now craft " + "" + "green dragonhide bodies" + "" + "."); + case 25: + return newstruct cs2func_script_1000_struct(64, 10075, "Members: Repairing gloves of silence", "Members can now repair " + "" + "gloves of silence" + "" + " with dark kebbit fur."); + case 26: + return newstruct cs2func_script_1000_struct(66, 2487, "Members: Blue dragonhide vambraces", "Members can now craft " + "" + "blue dragonhide vambraces" + "" + "."); + case 27: + return newstruct cs2func_script_1000_struct(68, 2493, "Members: Blue dragonhide chaps", "Members can now craft " + "" + "blue dragonhide chaps" + "" + "."); + case 28: + return newstruct cs2func_script_1000_struct(71, 2499, "Members: Blue dragonhide body", "Members can now craft " + "" + "blue dragonhide bodies" + "" + "."); + case 29: + return newstruct cs2func_script_1000_struct(73, 2489, "Members: Red dragonhide vambraces", "Members can now craft " + "" + "red dragonhide vambraces" + "" + "."); + case 30: + return newstruct cs2func_script_1000_struct(75, 2495, "Members: Red dragonhide chaps", "Members can now craft " + "" + "red dragonhide chaps" + "" + "."); + case 31: + return newstruct cs2func_script_1000_struct(77, 2501, "Members: Red dragonhide body", "Members can now craft " + "" + "red dragonhide bodies" + "" + "."); + case 32: + return newstruct cs2func_script_1000_struct(79, 12210, "Members: Feathered headdress", "Members can now craft " + "" + "feathered headdresses" + "" + "."); + case 33: + return newstruct cs2func_script_1000_struct(79, 2491, "Members: Black dragonhide vambraces", "Members can now craft " + "" + "black dragonhide vambraces" + "" + "."); + case 34: + return newstruct cs2func_script_1000_struct(82, 2497, "Members: Black dragonhide chaps", "Members can now craft " + "" + "black dragonhide chaps" + "" + "."); + case 35: + return newstruct cs2func_script_1000_struct(84, 2503, "Members: Black dragonhide body", "Members can now craft " + "" + "black dragonhide bodies" + "" + "."); + case 36: + return newstruct cs2func_script_1000_struct(85, 21508, "Members: Necromancer robes", "Members can now craft " + "" + "necromancer robes" + "" + " by using necromancer kits on Dagon'hai robes."); + } + break; + case 2: + switch (arg1) { + case 0: + return newstruct cs2func_script_1000_struct(1, 1759, "Wool", "You can now spin wool from a sheep into " + "" + "balls of wool" + "" + "."); + case 1: + return newstruct cs2func_script_1000_struct(10, 1777, "Members: Flax into bow strings", "Members can now spin flax into " + "" + "bow strings" + "" + "."); + case 2: + return newstruct cs2func_script_1000_struct(10, 9438, "Members: Sinew into crossbow strings", "Members can now spin sinew into " + "" + "crossbow strings" + "" + "."); + case 3: + return newstruct cs2func_script_1000_struct(19, 6038, "Members: Magic tree roots into magic strings", "Members can now spin magic tree roots into " + "" + "magic strings" + "" + "."); + case 4: + return newstruct cs2func_script_1000_struct(30, 954, "Members: Yak hair into rope", "Members can now spin yak hair into " + "" + "rope."); + } + break; + case 3: + switch (arg1) { + case 0: + return newstruct cs2func_script_1000_struct(1, 1931, "Pot", "You can now craft and fire " + "" + "clay pots" + "" + "."); + case 1: + return newstruct cs2func_script_1000_struct(1, 20382, "Cracked mining urn", "You can now craft, fire and attach runes to " + "" + "cracked mining urns" + "" + "."); + case 2: + return newstruct cs2func_script_1000_struct(2, 20352, "Cracked cooking urn", "You can now craft, fire and attach runes to " + "" + "cracked cooking urns" + "" + "."); + case 3: + return newstruct cs2func_script_1000_struct(2, 20322, "Cracked fishing urn", "You can now craft, fire and attach runes to " + "" + "cracked fishing urns" + "" + "."); + case 4: + return newstruct cs2func_script_1000_struct(2, 20412, "Impious urn", "You can now craft, fire and attach runes to " + "" + "impious urns" + "" + "."); + case 5: + return newstruct cs2func_script_1000_struct(4, 20053, "Clay ring", "You can now craft and fire " + "" + "clay rings" + "" + "."); + case 6: + return newstruct cs2func_script_1000_struct(4, 20298, "Cracked woodcutting urn", "You can now craft, fire and attach runes to " + "" + "cracked woodcutting urns" + "" + "."); + case 7: + return newstruct cs2func_script_1000_struct(4, 20274, "Cracked smelting urn", "You can now craft, fire and attach runes to " + "" + "cracked smelting urns" + "" + "."); + case 8: + return newstruct cs2func_script_1000_struct(7, 2313, "Pie dish", "You can now craft and fire " + "" + "clay pie dishes" + "" + "."); + case 9: + return newstruct cs2func_script_1000_struct(8, 1923, "Bowl", "You can now craft and fire " + "" + "clay bowls" + "" + "."); + case 10: + return newstruct cs2func_script_1000_struct(12, 20358, "Fragile cooking urn", "You can now craft, fire and attach runes to " + "" + "fragile cooking urns" + "" + "."); + case 11: + return newstruct cs2func_script_1000_struct(15, 20328, "Fragile fishing urn", "You can now craft, fire and attach runes to " + "" + "fragile fishing urns" + "" + "."); + case 12: + return newstruct cs2func_script_1000_struct(15, 20304, "Fragile woodcutting urn", "You can now craft, fire and attach runes to " + "" + "fragile woodcutting urns" + "" + "."); + case 13: + return newstruct cs2func_script_1000_struct(17, 20388, "Fragile mining urn", "You can now craft, fire and attach runes to " + "" + "fragile mining urns" + "" + "."); + case 14: + return newstruct cs2func_script_1000_struct(17, 20280, "Fragile smelting urn", "You can now craft, fire and attach runes to " + "" + "fragile smelting urns" + "" + "."); + case 15: + return newstruct cs2func_script_1000_struct(19, 5350, "Members: Plant pot", "Members can now craft and fire " + "" + "clay plant pots" + "" + "."); + case 16: + return newstruct cs2func_script_1000_struct(25, 4440, "Members: Pot lid" + "
" + " (after starting One Small Favour)", "Members can now craft and fire " + "" + "clay pot lids" + "" + " (after starting One Small Favour.)"); + case 17: + return newstruct cs2func_script_1000_struct(26, 20418, "Accursed urn", "You can now craft, fire and attach runes to " + "" + "accursed urns" + "" + "."); + case 18: + return newstruct cs2func_script_1000_struct(32, 20394, "Mining urn", "You can now craft, fire and attach runes to " + "" + "mining urns" + "" + "."); + case 19: + return newstruct cs2func_script_1000_struct(35, 20286, "Smelting urn", "You can now craft, fire and attach runes to " + "" + "smelting urns" + "" + "."); + case 20: + return newstruct cs2func_script_1000_struct(36, 20364, "Cooking urn", "You can now craft, fire and attach runes to " + "" + "cooking urns" + "" + "."); + case 21: + return newstruct cs2func_script_1000_struct(41, 20334, "Fishing urn", "You can now craft, fire and attach runes to " + "" + "fishing urns" + "" + "."); + case 22: + return newstruct cs2func_script_1000_struct(44, 20310, "Woodcutting urn", "You can now craft, fire and attach runes to " + "" + "woodcutting urns" + "" + "."); + case 23: + return newstruct cs2func_script_1000_struct(48, 20400, "Members: Strong mining urn", "Members can now craft, fire and attach runes to " + "" + "strong mining urns" + "" + "."); + case 24: + return newstruct cs2func_script_1000_struct(49, 20292, "Members: Strong smelting urn", "Members can now craft, fire and attach runes to " + "" + "strong smelting urns" + "" + "."); + case 25: + return newstruct cs2func_script_1000_struct(51, 20370, "Members: Strong cooking urn", "Members can now craft, fire and attach runes to " + "" + "strong cooking urns" + "" + "."); + case 26: + return newstruct cs2func_script_1000_struct(53, 20340, "Members: Strong fishing urn", "Members can now craft, fire and attach runes to " + "" + "strong fishing urns" + "" + "."); + case 27: + return newstruct cs2func_script_1000_struct(59, 20406, "Members: Decorated mining urn", "Members can now craft, fire and attach runes to " + "" + "decorated mining urns" + "" + "."); + case 28: + return newstruct cs2func_script_1000_struct(61, 20316, "Members: Strong woodcutting urn", "Members can now craft, fire and attach runes to " + "" + "strong woodcutting urns" + "" + "."); + case 29: + return newstruct cs2func_script_1000_struct(62, 20424, "Members: Infernal urn", "Members can now craft, fire and attach runes to " + "" + "infernal urns" + "" + "."); + case 30: + return newstruct cs2func_script_1000_struct(76, 20346, "Members: Decorated fishing urn", "Members can now craft, fire and attach runes to " + "" + "decorated fishing urns" + "" + "."); + case 31: + return newstruct cs2func_script_1000_struct(81, 20376, "Members: Decorated cooking urn", "Members can now craft, fire and attach runes to " + "" + "decorated cooking urns" + "" + "."); + } + break; + case 4: + switch (arg1) { + case 0: + return newstruct cs2func_script_1000_struct(1, 1919, "Members: Beer glass", "Members can now craft " + "" + "beer glasses" + "" + "."); + case 1: + return newstruct cs2func_script_1000_struct(4, 4527, "Members: Candle lantern", "Members can now craft " + "" + "candle lanterns" + "" + "."); + case 2: + return newstruct cs2func_script_1000_struct(12, 4525, "Members: Oil lamp", "Members can now craft " + "" + "oil lamps" + "" + "."); + case 3: + return newstruct cs2func_script_1000_struct(26, 4535, "Members: Oil lantern", "Members can now craft " + "" + "oil lanterns" + "" + "."); + case 4: + return newstruct cs2func_script_1000_struct(33, 229, "Members: Vial", "Members can now craft " + "" + "vials" + "" + "."); + case 5: + return newstruct cs2func_script_1000_struct(42, 6667, "Members: Fishbowl", "Members can now craft " + "" + "fishbowls" + "" + "."); + case 6: + return newstruct cs2func_script_1000_struct(46, 567, "Members: Glass orb", "Members can now craft " + "" + "glass orbs" + "" + "."); + case 7: + return newstruct cs2func_script_1000_struct(49, 4542, "Members: Bullseye lantern lens", "Members can now craft " + "" + "bullseye lantern lenses" + "" + "."); + case 8: + return newstruct cs2func_script_1000_struct(87, 10973, "Members: Dorgeshuun light orb", "Members can now craft " + "" + "Dorgeshuun light orbs" + "" + "."); + } + break; + case 5: + switch (arg1) { + case 0: + return newstruct cs2func_script_1000_struct(1, 21347, "Members: Lapis lazuli brooch", "Members can now craft a " + "" + "lapis lazuli brooch" + "" + "."); + case 1: + return newstruct cs2func_script_1000_struct(1, 1609, "Members: Cut opal", "Members can now cut " + "" + "opals" + "" + "."); + case 2: + return newstruct cs2func_script_1000_struct(3, 10496, "Polished buttons", "You can now craft " + "" + "polished buttons" + "" + "."); + case 3: + return newstruct cs2func_script_1000_struct(5, 1635, "Gold ring", "You can now craft " + "" + "gold rings" + "" + "."); + case 4: + return newstruct cs2func_script_1000_struct(6, 1654, "Gold necklace", "You can now craft " + "" + "gold necklaces" + "" + "."); + case 5: + return newstruct cs2func_script_1000_struct(7, 11069, "Members: Gold bracelet", "Members can now craft " + "" + "gold bracelets" + "" + "."); + case 6: + return newstruct cs2func_script_1000_struct(8, 1692, "Gold amulet", "You can now craft " + "" + "gold amulets" + "" + "."); + case 7: + return newstruct cs2func_script_1000_struct(13, 1611, "Members: Cut jade", "Members can now cut " + "" + "jade" + "" + "."); + case 8: + return newstruct cs2func_script_1000_struct(16, 1716, "Holy symbol", "You can now craft " + "" + "holy symbols" + "" + "."); + case 9: + return newstruct cs2func_script_1000_struct(16, 1613, "Members: Cut red topaz", "Members can now cut " + "" + "red topaz" + "" + "."); + case 10: + return newstruct cs2func_script_1000_struct(17, 1722, "Members: Unholy symbol", "Members can now craft " + "" + "unholy symbols" + "" + "."); + case 11: + return newstruct cs2func_script_1000_struct(20, 1607, "Cut sapphire", "You can now craft " + "" + "sapphires" + "" + "."); + case 12: + return newstruct cs2func_script_1000_struct(20, 1637, "Sapphire ring", "You can now craft " + "" + "sapphire rings" + "" + "."); + case 13: + return newstruct cs2func_script_1000_struct(22, 1656, "Sapphire necklace", "You can now craft " + "" + "sapphire necklaces" + "" + "."); + case 14: + return newstruct cs2func_script_1000_struct(23, 5525, "Tiara", "You can now craft " + "" + "tiaras" + "" + "."); + case 15: + return newstruct cs2func_script_1000_struct(23, 11072, "Members: Sapphire bracelet", "Members can now craft " + "" + "sapphire bracelets" + "" + "."); + case 16: + return newstruct cs2func_script_1000_struct(24, 1694, "Sapphire amulet", "You can now craft " + "" + "sapphire amulets" + "" + "."); + case 17: + return newstruct cs2func_script_1000_struct(27, 1605, "Cut emerald", "You can now cut " + "" + "emeralds" + "" + "."); + case 18: + return newstruct cs2func_script_1000_struct(27, 1639, "Emerald ring", "You can now craft " + "" + "emerald rings" + "" + "."); + case 19: + return newstruct cs2func_script_1000_struct(29, 1658, "Emerald necklace", "You can now craft " + "" + "emerald necklaces" + "" + "."); + case 20: + return newstruct cs2func_script_1000_struct(30, 11076, "Members: Emerald bracelet", "Members can now craft " + "" + "emerald bracelets" + "" + "."); + case 21: + return newstruct cs2func_script_1000_struct(31, 1696, "Emerald amulet", "You can now craft " + "" + "emerald amulets" + "" + "."); + case 22: + return newstruct cs2func_script_1000_struct(34, 1603, "Cut ruby", "You can now cut " + "" + "rubies" + "" + "."); + case 23: + return newstruct cs2func_script_1000_struct(34, 1641, "Ruby ring", "You can now craft " + "" + "ruby rings" + "" + "."); + case 24: + return newstruct cs2func_script_1000_struct(37, 10132, "Members: Rabbit-foot necklaces", "Members can now craft " + "" + "rabbit-foot necklaces" + "" + "."); + case 25: + return newstruct cs2func_script_1000_struct(40, 1660, "Ruby necklace", "You can now craft " + "" + "ruby necklaces" + "" + "."); + case 26: + return newstruct cs2func_script_1000_struct(42, 11085, "Members: Ruby bracelet", "Members can now craft " + "" + "ruby bracelets" + "" + "."); + case 27: + return newstruct cs2func_script_1000_struct(43, 1601, "Cut diamond", "You can now cut " + "" + "diamonds" + "" + "."); + case 28: + return newstruct cs2func_script_1000_struct(43, 1643, "Diamond ring", "You can now craft " + "" + "diamond rings" + "" + "."); + case 29: + return newstruct cs2func_script_1000_struct(50, 1698, "Ruby amulet", "You can now craft " + "" + "ruby amulets" + "" + "."); + case 30: + return newstruct cs2func_script_1000_struct(55, 1615, "Members: Cut dragonstone", "Members can now cut " + "" + "dragonstones" + "" + "."); + case 31: + return newstruct cs2func_script_1000_struct(55, 1645, "Members: Dragonstone ring", "Members can now craft " + "" + "dragonstone rings" + "" + "."); + case 32: + return newstruct cs2func_script_1000_struct(56, 1662, "Diamond necklace", "You can now craft " + "" + "diamond necklaces" + "" + "."); + case 33: + return newstruct cs2func_script_1000_struct(58, 11092, "Members: Diamond bracelet", "Members can now craft " + "" + "diamond bracelets" + "" + "."); + case 34: + return newstruct cs2func_script_1000_struct(67, 6573, "Members: Cut onyx", "Members can now cut " + "" + "onyx" + "" + "."); + case 35: + return newstruct cs2func_script_1000_struct(67, 6575, "Members: Onyx ring", "Members can now craft " + "" + "onyx rings" + "" + "."); + case 36: + return newstruct cs2func_script_1000_struct(70, 1700, "Diamond amulet", "You can now craft " + "" + "diamond amulets" + "" + "."); + case 37: + return newstruct cs2func_script_1000_struct(72, 1664, "Members: Dragonstone necklace", "Members can now craft " + "" + "dragonstone necklaces" + "" + "."); + case 38: + return newstruct cs2func_script_1000_struct(74, 11115, "Members: Dragonstone bracelet", "Members can now craft " + "" + "dragonstone bracelets" + "" + "."); + case 39: + return newstruct cs2func_script_1000_struct(75, 13281, "Members: Ring of slaying" + "
" + " (after Smoking Kills)", "Members can now craft " + "" + "rings of slaying" + "" + " (after Smoking Kills)."); + case 40: + return newstruct cs2func_script_1000_struct(80, 1702, "Members: Dragonstone amulet", "Members can now craft " + "" + "dragonstone amulets" + "" + "."); + case 41: + return newstruct cs2func_script_1000_struct(82, 6577, "Members: Onyx necklace", "Members can now craft " + "" + "onyx necklaces" + "" + "."); + case 42: + return newstruct cs2func_script_1000_struct(84, 11130, "Members: Onyx bracelet", "Members can now craft " + "" + "onyx bracelets" + "" + "."); + case 43: + return newstruct cs2func_script_1000_struct(90, 6581, "Members: Onyx amulet", "Members can now craft " + "" + "onyx amulets" + "" + "."); + case 44: + return newstruct cs2func_script_1000_struct(91, 21526, "Members: Shark's tooth necklace", "Members can now craft " + "" + "shark's tooth necklaces" + "" + "."); + } + break; + case 6: + switch (arg1) { + case 0: + return newstruct cs2func_script_1000_struct(18, 2961, "Members: Silver sickle", "Members can now craft silver sickles."); + case 1: + return newstruct cs2func_script_1000_struct(21, 9145, "Silver crossbow bolt", "Members can now craft " + "" + "silver crossbow bolts" + "" + "."); + case 2: + return newstruct cs2func_script_1000_struct(54, 1395, "Members: Water battlestaff", "Members can now craft " + "" + "water battlestaves" + "" + "."); + case 3: + return newstruct cs2func_script_1000_struct(58, 1399, "Members: Earth battlestaff", "Members can now craft " + "" + "earth battlestaves" + "" + "."); + case 4: + return newstruct cs2func_script_1000_struct(62, 1393, "Members: Fire battlestaff", "Members can now craft " + "" + "fire battlestaves" + "" + "."); + case 5: + return newstruct cs2func_script_1000_struct(66, 1397, "Members: Air battlestaff", "Members can now craft " + "" + "air battlestaves" + "" + "."); + case 6: + return newstruct cs2func_script_1000_struct(77, 21777, "Members: Armadyl battlestaff" + "
" + " (after Ritual of the Mahjarrat)", "Members can now craft " + "" + "Armadyl battlestaves" + "" + " (after Ritual of the Mahjarrat)."); + case 7: + return newstruct cs2func_script_1000_struct(85, 21490, "Members: Skeletal and Necromancer Staves", "Members can now use shade skulls to create " + "" + "skeletal" + "" + " and " + "" + "necromancer staves" + "" + " from Shades of Mort'ton."); + } + break; + case 7: + switch (arg1) { + case 0: + return newstruct cs2func_script_1000_struct(-1, 7620, "To start Firemaking in the manner of the barbarians, talk to Otto Godblessed when you have level 35 Firemaking or higher. Pyre ships can only be constructed and burnt where the ground is charred around the lake next to Otto's hut.", ""); + case 1: + return newstruct cs2func_script_1000_struct(11, 1511, "Members: Wood" + "
" + " (with 11 Firemaking)", "Members versed in the art of barbarian firemaking now have the Crafting level required to make " + "" + "wood pyre ships" + "" + ". (They also need level 11 Firemaking.)"); + case 2: + return newstruct cs2func_script_1000_struct(11, 2862, "Members: Achey" + "
" + " (with 11 Firemaking)", "Members versed in the art of barbarian firemaking now have the Crafting level required to make " + "" + "achey log pyre ships" + "" + ". (They also need level 11 Firemaking.)"); + case 3: + return newstruct cs2func_script_1000_struct(25, 1521, "Members: Oak" + "
" + " (with 25 Firemaking)", "Members versed in the art of barbarian firemaking now have the Crafting level required to make " + "" + "oak pyre ships" + "" + ". (They also need level 25 Firemaking.)"); + case 4: + return newstruct cs2func_script_1000_struct(40, 1519, "Members: Willow" + "
" + " (with 40 Firemaking)", "Members versed in the art of barbarian firemaking now have the Crafting level required to make " + "" + "willow pyre ships" + "" + ". (They also need level 40 Firemaking.)"); + case 5: + return newstruct cs2func_script_1000_struct(45, 6333, "Members: Teak" + "
" + " (with 45 Firemaking)", "Members versed in the art of barbarian firemaking now have the Crafting level required to make " + "" + "teak pyre ships" + "" + ". (They also need level 45 Firemaking.)"); + case 6: + return newstruct cs2func_script_1000_struct(52, 10810, "Members: Arctic pine" + "
" + " (with 52 Firemaking)", "Members versed in the art of barbarian firemaking now have the Crafting level required to make " + "" + "arctic pine pyre ships" + "" + ". (They also need level 52 Firemaking.)"); + case 7: + return newstruct cs2func_script_1000_struct(55, 1517, "Members: Maple" + "
" + " (with 55 Firemaking)", "Members versed in the art of barbarian firemaking now have the Crafting level required to make " + "" + "maple pyre ships" + "" + ". (They also need level 55 Firemaking.)"); + case 8: + return newstruct cs2func_script_1000_struct(60, 6332, "Members: Mahogany" + "
" + " (with 60 Firemaking)", "Members versed in the art of barbarian firemaking now have the Crafting level required to make " + "" + "mahogany pyre ships" + "" + ". (They also need level 60 Firemaking.)"); + case 9: + return newstruct cs2func_script_1000_struct(68, 12581, "Members: Eucalyptus" + "
" + " (with 68 Firemaking)", "Members versed in the art of barbarian firemaking now have the Crafting level required to make " + "" + "eucalyptus pyre ships" + "" + ". (They also need level 68 Firemaking.)"); + case 10: + return newstruct cs2func_script_1000_struct(70, 1515, "Members: Yew" + "
" + " (with 70 Firemaking)", "Members versed in the art of barbarian firemaking now have the Crafting level required to make " + "" + "yew pyre ships" + "" + ". (They also need level 70 Firemaking.)"); + case 11: + return newstruct cs2func_script_1000_struct(85, 1513, "Members: Magic" + "
" + " (with 85 Firemaking)", "Members versed in the art of barbarian firemaking now have the Crafting level required to make " + "" + "magic log pyre ships" + "" + ". (They also need level 85 Firemaking.)"); + } + break; + case 8: + switch (arg1) { + case 0: + return newstruct cs2func_script_1000_struct(8, 8792, "Members: Clockwork mechanism", "Members can now craft " + "" + "clockwork mechanisms" + "" + " in the workshop of their player-owned house."); + case 1: + return newstruct cs2func_script_1000_struct(10, 2522, "Members: Toy horsey", "Members can now craft " + "" + "toy horseys" + "" + " in the workshop of their player-owned house."); + case 2: + return newstruct cs2func_script_1000_struct(13, 7761, "Members: Clockwork soldier", "Members can now craft " + "" + "clockwork soldiers" + "" + " in the workshop of their player-owned house."); + case 3: + return newstruct cs2func_script_1000_struct(18, 7765, "Members: Clockwork doll", "Members can now craft " + "" + "clockwork dolls" + "" + " in the workshop of their player-owned house."); + case 4: + return newstruct cs2func_script_1000_struct(20, 4201, "Members: Conductor" + "
" + " (after starting Creature of Fenkenstrain)", "Members can now make " + "" + "lightning conductors" + "" + " (after starting Creature of Fenkenstrain)."); + case 5: + return newstruct cs2func_script_1000_struct(23, 2574, "Members: Sextant", "Members can now craft " + "" + "sextants" + "" + " in the workshop of their player-owned house."); + case 6: + return newstruct cs2func_script_1000_struct(25, 18338, "Gem bag" + "
" + " (with 25 Dungeoneering)", "You can now use " + "" + "gem bags" + "" + ". (You also need level 25 Dungeoneering.)"); + case 7: + return newstruct cs2func_script_1000_struct(28, 2575, "Members: Watch", "Members can now craft " + "" + "watches" + "" + " in the workshop of their player-owned house."); + case 8: + return newstruct cs2func_script_1000_struct(30, 10595, "Members: Clockwork penguins", "Members can now craft " + "" + "clockwork penguins" + "" + " in the workshop of their player-owned house."); + case 9: + return newstruct cs2func_script_1000_struct(33, 7769, "Members: Clockwork mouse", "Members can now craft " + "" + "clockwork mice" + "" + " in the workshop of their player-owned house."); + case 10: + return newstruct cs2func_script_1000_struct(43, 13246, "Members: Pillar" + "
" + " (after starting TokTz-Ket-Dill)", "Members can now make " + "" + "pillars" + "" + " (after starting TokTz-Ket-Dill)."); + case 11: + return newstruct cs2func_script_1000_struct(85, 7771, "Members: Clockwork cat", "Members can now craft " + "" + "clockwork cats" + "" + " in the workshop of their player-owned house."); + } + break; + case 9: + switch (arg1) { + case 0: + return newstruct cs2func_script_1000_struct(60, 20704, "Members: access to the Livid Farm (with 70 Magic, 60 Agility, 60 Farming, 50 Construction and Lunar Diplomacy)", "Members can access " + "" + "Livid Farm" + "" + " (with 70 Magic, 60 Agility, 60 Farming, 50 Construction and Lunar Diplomacy)."); + case 1: + return newstruct cs2func_script_1000_struct(91, 18778, "Members: Starved ancient effigies", "Members can now investigate " + "" + "starved ancient effigies" + "" + " using their knowledge of Crafting."); + case 2: + return newstruct cs2func_script_1000_struct(93, 18779, "Members: Nourished ancient effigies", "Members can now investigate " + "" + "nourished ancient effigies" + "" + " using their knowledge of Crafting."); + case 3: + return newstruct cs2func_script_1000_struct(95, 18780, "Members: Sated ancient effigies", "Members can now investigate " + "" + "sated ancient effigies" + "" + " using their knowledge of Crafting."); + case 4: + return newstruct cs2func_script_1000_struct(97, 18781, "Members: Gorged ancient effigies", "Members can now investigate " + "" + "gorged ancient effigies" + "" + " using their knowledge of Crafting."); + } + break; + case 10: + switch (arg1) { + case 0: + return newstruct cs2func_script_1000_struct(1, 14152, "Members: Stealing Creation - class 1 butterfly net", "Members can now craft " + "" + "class 1 butterfly nets" + "" + " in Stealing Creation."); + case 1: + return newstruct cs2func_script_1000_struct(1, 14142, "Members: Stealing Creation - class 1 harpoon", "Members can now craft " + "" + "class 1 harpoons" + "" + " in Stealing Creation."); + case 2: + return newstruct cs2func_script_1000_struct(1, 14377, "Members: Stealing Creation - class 1 staff", "Members can now craft " + "" + "class 1 staves" + "" + " in Stealing Creation."); + case 3: + return newstruct cs2func_script_1000_struct(1, 14391, "Members: Stealing Creation - class 1 leather body", "Members can now craft " + "" + "class 1 leather bodies" + "" + " in Stealing Creation."); + case 4: + return newstruct cs2func_script_1000_struct(1, 14401, "Members: Stealing Creation - class 1 chaps", "Members can now craft " + "" + "class 1 chaps" + "" + " in Stealing Creation."); + case 5: + return newstruct cs2func_script_1000_struct(1, 14411, "Members: Stealing Creation - class 1 coif", "Members can now craft " + "" + "class 1 coifs" + "" + " in Stealing Creation."); + case 6: + return newstruct cs2func_script_1000_struct(1, 14317, "Members: Stealing Creation - class 1 robe top", "Members can now craft " + "" + "class 1 robe tops" + "" + " in Stealing Creation."); + case 7: + return newstruct cs2func_script_1000_struct(1, 14327, "Members: Stealing Creation - class 1 robe bottom", "Members can now craft " + "" + "class 1 robe bottoms" + "" + " in Stealing Creation."); + case 8: + return newstruct cs2func_script_1000_struct(1, 14337, "Members: Stealing Creation - class 1 hat", "Members can now craft " + "" + "class 1 hats" + "" + " in Stealing Creation."); + case 9: + return newstruct cs2func_script_1000_struct(20, 14154, "Members: Stealing Creation - class 2 butterfly net", "Members can now craft " + "" + "class 2 butterfly nets" + "" + " in Stealing Creation."); + case 10: + return newstruct cs2func_script_1000_struct(20, 14144, "Members: Stealing Creation - class 2 harpoon", "Members can now craft " + "" + "class 2 harpoons" + "" + " in Stealing Creation."); + case 11: + return newstruct cs2func_script_1000_struct(20, 14379, "Members: Stealing Creation - class 2 staff", "Members can now craft " + "" + "class 2 staves" + "" + " in Stealing Creation."); + case 12: + return newstruct cs2func_script_1000_struct(20, 14393, "Members: Stealing Creation - class 2 leather body", "Members can now craft " + "" + "class 2 leather bodies" + "" + " in Stealing Creation."); + case 13: + return newstruct cs2func_script_1000_struct(20, 14403, "Members: Stealing Creation - class 2 chaps", "Members can now craft " + "" + "class 2 chaps" + "" + " in Stealing Creation."); + case 14: + return newstruct cs2func_script_1000_struct(20, 14413, "Members: Stealing Creation - class 2 coif", "Members can now craft " + "" + "class 2 coifs" + "" + " in Stealing Creation."); + case 15: + return newstruct cs2func_script_1000_struct(20, 14319, "Members: Stealing Creation - class 2 robe top", "Members can now craft " + "" + "class 2 robe tops" + "" + " in Stealing Creation."); + case 16: + return newstruct cs2func_script_1000_struct(20, 14329, "Members: Stealing Creation - class 2 robe bottom", "Members can now craft " + "" + "class 2 robe bottoms" + "" + " in Stealing Creation."); + case 17: + return newstruct cs2func_script_1000_struct(20, 14339, "Members: Stealing Creation - class 2 hat", "Members can now craft " + "" + "class 2 hats" + "" + " in Stealing Creation."); + case 18: + return newstruct cs2func_script_1000_struct(40, 14156, "Members: Stealing Creation - class 3 butterfly net", "Members can now craft " + "" + "class 3 butterfly nets" + "" + " in Stealing Creation."); + case 19: + return newstruct cs2func_script_1000_struct(40, 14146, "Members: Stealing Creation - class 3 harpoon", "Members can now craft " + "" + "class 3 harpoons" + "" + " in Stealing Creation."); + case 20: + return newstruct cs2func_script_1000_struct(40, 14381, "Members: Stealing Creation - class 3 staff", "Members can now craft " + "" + "class 3 staves" + "" + " in Stealing Creation."); + case 21: + return newstruct cs2func_script_1000_struct(40, 14395, "Members: Stealing Creation - class 3 leather body", "Members can now craft " + "" + "class 3 leather bodies" + "" + " in Stealing Creation."); + case 22: + return newstruct cs2func_script_1000_struct(40, 14405, "Members: Stealing Creation - class 3 chaps", "Members can now craft " + "" + "class 3 chaps" + "" + " in Stealing Creation."); + case 23: + return newstruct cs2func_script_1000_struct(40, 14415, "Members: Stealing Creation - class 3 coif", "Members can now craft " + "" + "class 3 coifs" + "" + " in Stealing Creation."); + case 24: + return newstruct cs2func_script_1000_struct(40, 14321, "Members: Stealing Creation - class 3 robe top", "Members can now craft " + "" + "class 3 robe tops" + "" + " in Stealing Creation."); + case 25: + return newstruct cs2func_script_1000_struct(40, 14331, "Members: Stealing Creation - class 3 robe bottom", "Members can now craft " + "" + "class 3 robe bottoms" + "" + " in Stealing Creation."); + case 26: + return newstruct cs2func_script_1000_struct(40, 14341, "Members: Stealing Creation - class 3 hat", "Members can now craft " + "" + "class 3 hats" + "" + " in Stealing Creation."); + case 27: + return newstruct cs2func_script_1000_struct(52, 14619, "Members: Phoenix lair - funeral pyre", "Members can now craft the phoenix's " + "" + "funeral pyre" + "" + " in the phoenix lair."); + case 28: + return newstruct cs2func_script_1000_struct(60, 14158, "Members: Stealing Creation - class 4 butterfly net", "Members can now craft " + "" + "class 4 butterfly nets" + "" + " in Stealing Creation."); + case 29: + return newstruct cs2func_script_1000_struct(60, 14148, "Members: Stealing Creation - class 4 harpoon", "Members can now craft " + "" + "class 4 harpoons" + "" + " in Stealing Creation."); + case 30: + return newstruct cs2func_script_1000_struct(60, 14383, "Members: Stealing Creation - class 4 staff", "Members can now craft " + "" + "class 4 staves" + "" + " in Stealing Creation."); + case 31: + return newstruct cs2func_script_1000_struct(60, 14397, "Members: Stealing Creation - class 4 leather body", "Members can now craft " + "" + "class 4 leather bodies" + "" + " in Stealing Creation."); + case 32: + return newstruct cs2func_script_1000_struct(60, 14407, "Members: Stealing Creation - class 4 chaps", "Members can now craft " + "" + "class 4 chaps" + "" + " in Stealing Creation."); + case 33: + return newstruct cs2func_script_1000_struct(60, 14417, "Members: Stealing Creation - class 4 coif", "Members can now craft " + "" + "class 4 coifs" + "" + " in Stealing Creation."); + case 34: + return newstruct cs2func_script_1000_struct(60, 14323, "Members: Stealing Creation - class 4 robe top", "Members can now craft " + "" + "class 4 robe tops" + "" + " in Stealing Creation."); + case 35: + return newstruct cs2func_script_1000_struct(60, 14333, "Members: Stealing Creation - class 4 robe bottom", "Members can now craft " + "" + "class 4 robe bottoms" + "" + " in Stealing Creation."); + case 36: + return newstruct cs2func_script_1000_struct(60, 14343, "Members: Stealing Creation - class 4 hat", "Members can now craft " + "" + "class 4 hats" + "" + " in Stealing Creation."); + case 37: + return newstruct cs2func_script_1000_struct(80, 14160, "Members: Stealing Creation - class 5 butterfly net", "Members can now craft " + "" + "class 5 butterfly nets" + "" + " in Stealing Creation."); + case 38: + return newstruct cs2func_script_1000_struct(80, 14150, "Members: Stealing Creation - class 5 harpoon", "Members can now craft " + "" + "class 5 harpoons" + "" + " in Stealing Creation."); + case 39: + return newstruct cs2func_script_1000_struct(80, 14385, "Members: Stealing Creation - class 5 staff", "Members can now craft " + "" + "class 5 staves" + "" + " in Stealing Creation."); + case 40: + return newstruct cs2func_script_1000_struct(80, 14399, "Members: Stealing Creation - class 5 leather body", "Members can now craft " + "" + "class 5 leather bodies" + "" + " in Stealing Creation."); + case 41: + return newstruct cs2func_script_1000_struct(80, 14409, "Members: Stealing Creation - class 5 chaps", "Members can now craft " + "" + "class 5 chaps" + "" + " in Stealing Creation."); + case 42: + return newstruct cs2func_script_1000_struct(80, 14419, "Members: Stealing Creation - class 5 coif", "Members can now craft " + "" + "class 5 coifs" + "" + " in Stealing Creation."); + case 43: + return newstruct cs2func_script_1000_struct(80, 14325, "Members: Stealing Creation - class 5 robe top", "Members can now craft " + "" + "class 5 robe tops" + "" + " in Stealing Creation."); + case 44: + return newstruct cs2func_script_1000_struct(80, 14335, "Members: Stealing Creation - class 5 robe bottom", "Members can now craft " + "" + "class 5 robe bottoms" + "" + " in Stealing Creation."); + case 45: + return newstruct cs2func_script_1000_struct(80, 14345, "Members: Stealing Creation - class 5 hat", "Members can now craft " + "" + "class 5 hats" + "" + " in Stealing Creation."); + } + break; + case 11: + switch (arg1) { + case 0: + return newstruct cs2func_script_1000_struct(-1, 15707, "Dungeoneering skill tasks (Levels 1-99)" + "
" + "As your Crafting level increases, you will be able to attempt higher-level crafting tasks within Daemonheim. You will also be more likely to succeed when attempting crafting tasks within Daemonheim.", ""); + case 1: + return newstruct cs2func_script_1000_struct(1, 17151, "Salve gloves (Tier 1)", "You can now craft " + "" + "salve gloves" + "" + " within Daemonheim."); + case 2: + return newstruct cs2func_script_1000_struct(1, 17195, "Protoleather vambraces (Tier 1)", "You can now craft " + "" + "protoleather vambraces" + "" + " within Daemonheim."); + case 3: + return newstruct cs2func_script_1000_struct(2, 16911, "Salve shoes (Tier 1)", "You can now craft " + "" + "salve shoes" + "" + " within Daemonheim."); + case 4: + return newstruct cs2func_script_1000_struct(3, 17297, "Protoleather boots (Tier 1)", "You can now craft " + "" + "protoleather boots" + "" + " within Daemonheim."); + case 5: + return newstruct cs2func_script_1000_struct(4, 16735, "Salve hood (Tier 1)", "You can now craft " + "" + "salve hoods" + "" + " within Daemonheim."); + case 6: + return newstruct cs2func_script_1000_struct(5, 17041, "Protoleather coif (Tier 1)", "You can now craft " + "" + "protoleather coifs" + "" + " within Daemonheim."); + case 7: + return newstruct cs2func_script_1000_struct(6, 16845, "Salve robe bottom (Tier 1)", "You can now craft " + "" + "salve robe bottoms" + "" + " within Daemonheim."); + case 8: + return newstruct cs2func_script_1000_struct(7, 17319, "Protoleather chaps (Tier 1)", "You can now craft " + "" + "protoleather chaps" + "" + " within Daemonheim."); + case 9: + return newstruct cs2func_script_1000_struct(8, 17217, "Salve robe top (Tier 1)", "You can now craft " + "" + "salve robe tops" + "" + " within Daemonheim."); + case 10: + return newstruct cs2func_script_1000_struct(9, 17173, "Protoleather body (Tier 1)", "You can now craft " + "" + "protoleather bodies" + "" + " within Daemonheim."); + case 11: + return newstruct cs2func_script_1000_struct(10, 17153, "Wildercress gloves (Tier 2)", "You can now craft " + "" + "wildercress gloves" + "" + " within Daemonheim."); + case 12: + return newstruct cs2func_script_1000_struct(11, 17197, "Subleather vambraces (Tier 2)", "You can now craft " + "" + "subleather vambraces" + "" + " within Daemonheim."); + case 13: + return newstruct cs2func_script_1000_struct(12, 16913, "Wildercress shoes (Tier 2)", "You can now craft " + "" + "wildercress shoes" + "" + " within Daemonheim."); + case 14: + return newstruct cs2func_script_1000_struct(13, 17299, "Subleather boots (Tier 2)", "You can now craft " + "" + "subleather boots" + "" + " within Daemonheim."); + case 15: + return newstruct cs2func_script_1000_struct(14, 16737, "Wildercress hood (Tier 2)", "You can now craft " + "" + "wildercress hoods" + "" + " within Daemonheim."); + case 16: + return newstruct cs2func_script_1000_struct(15, 17043, "Subleather coif (Tier 2)", "You can now craft " + "" + "subleather coifs" + "" + " within Daemonheim."); + case 17: + return newstruct cs2func_script_1000_struct(16, 16847, "Wildercress robe bottom (Tier 2)", "You can now craft " + "" + "wildercress robe bottoms" + "" + " within Daemonheim."); + case 18: + return newstruct cs2func_script_1000_struct(17, 17321, "Subleather chaps (Tier 2)", "You can now craft " + "" + "subleather chaps" + "" + " within Daemonheim."); + case 19: + return newstruct cs2func_script_1000_struct(18, 17219, "Wildercress robe top (Tier 2)", "You can now craft " + "" + "wildercress robe tops" + "" + " within Daemonheim."); + case 20: + return newstruct cs2func_script_1000_struct(19, 17175, "Subleather body (Tier 2)", "You can now craft " + "" + "subleather bodies" + "" + " within Daemonheim."); + case 21: + return newstruct cs2func_script_1000_struct(20, 17155, "Blightleaf gloves (Tier 3)", "You can now craft " + "" + "blightleaf gloves" + "" + " within Daemonheim."); + case 22: + return newstruct cs2func_script_1000_struct(21, 17199, "Paraleather vambraces (Tier 3)", "You can now craft " + "" + "paraleather vambraces" + "" + " within Daemonheim."); + case 23: + return newstruct cs2func_script_1000_struct(22, 16915, "Blightleaf shoes (Tier 3)", "You can now craft " + "" + "blightleaf shoes" + "" + " within Daemonheim."); + case 24: + return newstruct cs2func_script_1000_struct(23, 17301, "Paraleather boots (Tier 3)", "You can now craft " + "" + "paraleather boots" + "" + " within Daemonheim."); + case 25: + return newstruct cs2func_script_1000_struct(24, 16739, "Blightleaf hood (Tier 3)", "You can now craft " + "" + "blightleaf hoods" + "" + " within Daemonheim."); + case 26: + return newstruct cs2func_script_1000_struct(25, 17045, "Paraleather coif (Tier 3)", "You can now craft " + "" + "paraleather coifs" + "" + " within Daemonheim."); + case 27: + return newstruct cs2func_script_1000_struct(26, 16849, "Blightleaf robe bottom (Tier 3)", "You can now craft " + "" + "blightleaf robe bottoms" + "" + " within Daemonheim."); + case 28: + return newstruct cs2func_script_1000_struct(27, 17323, "Paraleather chaps (Tier 3)", "You can now craft " + "" + "paraleather chaps" + "" + " within Daemonheim."); + case 29: + return newstruct cs2func_script_1000_struct(28, 17221, "Blightleaf robe top (Tier 3)", "You can now craft " + "" + "blightleaf robe tops" + "" + " within Daemonheim."); + case 30: + return newstruct cs2func_script_1000_struct(29, 17177, "Paraleather body (Tier 3)", "You can now craft " + "" + "paraleather bodies" + "" + " within Daemonheim."); + case 31: + return newstruct cs2func_script_1000_struct(30, 17157, "Roseblood gloves (Tier 4)", "You can now craft " + "" + "roseblood gloves" + "" + " within Daemonheim."); + case 32: + return newstruct cs2func_script_1000_struct(31, 17201, "Archleather vambraces (Tier 4)", "You can now craft " + "" + "archleather vambraces" + "" + " within Daemonheim."); + case 33: + return newstruct cs2func_script_1000_struct(32, 16917, "Roseblood shoes (Tier 4)", "You can now craft " + "" + "roseblood shoes" + "" + " within Daemonheim."); + case 34: + return newstruct cs2func_script_1000_struct(33, 17303, "Archleather boots (Tier 4)", "You can now craft " + "" + "archleather boots" + "" + " within Daemonheim."); + case 35: + return newstruct cs2func_script_1000_struct(34, 16741, "Roseblood hood (Tier 4)", "You can now craft " + "" + "roseblood hoods" + "" + " within Daemonheim."); + case 36: + return newstruct cs2func_script_1000_struct(35, 17047, "Archleather coif (Tier 4)", "You can now craft " + "" + "archleather coifs" + "" + " within Daemonheim."); + case 37: + return newstruct cs2func_script_1000_struct(36, 16851, "Roseblood robe bottom (Tier 4)", "You can now craft " + "" + "roseblood robe bottoms" + "" + " within Daemonheim."); + case 38: + return newstruct cs2func_script_1000_struct(37, 17325, "Archleather chaps (Tier 4)", "You can now craft " + "" + "archleather chaps" + "" + " within Daemonheim."); + case 39: + return newstruct cs2func_script_1000_struct(38, 17223, "Roseblood robe top (Tier 4)", "You can now craft " + "" + "roseblood robe tops" + "" + " within Daemonheim."); + case 40: + return newstruct cs2func_script_1000_struct(39, 17179, "Archleather body (Tier 4)", "You can now craft " + "" + "archleather bodies" + "" + " within Daemonheim."); + case 41: + return newstruct cs2func_script_1000_struct(40, 17159, "Bryll gloves (Tier 5)", "You can now craft " + "" + "bryll gloves" + "" + " within Daemonheim."); + case 42: + return newstruct cs2func_script_1000_struct(41, 17203, "Dromoleather vambraces (Tier 5)", "You can now craft " + "" + "dromoleather vambraces" + "" + " within Daemonheim."); + case 43: + return newstruct cs2func_script_1000_struct(42, 16919, "Bryll shoes (Tier 5)", "You can now craft " + "" + "bryll shoes" + "" + " within Daemonheim."); + case 44: + return newstruct cs2func_script_1000_struct(43, 17305, "Dromoleather boots (Tier 5)", "You can now craft " + "" + "dromoleather boots" + "" + " within Daemonheim."); + case 45: + return newstruct cs2func_script_1000_struct(44, 16743, "Bryll hood (Tier 5)", "You can now craft " + "" + "bryll hoods" + "" + " within Daemonheim."); + case 46: + return newstruct cs2func_script_1000_struct(45, 17049, "Dromoleather coif (Tier 5)", "You can now craft " + "" + "dromoleather coifs" + "" + " within Daemonheim."); + case 47: + return newstruct cs2func_script_1000_struct(46, 16853, "Bryll robe bottom (Tier 5)", "You can now craft " + "" + "bryll robe bottoms" + "" + " within Daemonheim."); + case 48: + return newstruct cs2func_script_1000_struct(47, 17327, "Dromoleather chaps (Tier 5)", "You can now craft " + "" + "dromoleather chaps" + "" + " within Daemonheim."); + case 49: + return newstruct cs2func_script_1000_struct(48, 17225, "Bryll robe top (Tier 5)", "You can now craft " + "" + "bryll robe tops" + "" + " within Daemonheim."); + case 50: + return newstruct cs2func_script_1000_struct(49, 17181, "Dromoleather body (Tier 5)", "You can now craft " + "" + "dromoleather bodies" + "" + " within Daemonheim."); + case 51: + return newstruct cs2func_script_1000_struct(50, 17161, "Members: Duskweed gloves (Tier 6)", "Members can now craft " + "" + "duskweed gloves" + "" + " within Daemonheim."); + case 52: + return newstruct cs2func_script_1000_struct(51, 17205, "Members: Spinoleather vambraces (Tier 6)", "Members can now craft " + "" + "spinoleather vambraces" + "" + " within Daemonheim."); + case 53: + return newstruct cs2func_script_1000_struct(52, 16921, "Members: Duskweed shoes (Tier 6)", "Members can now craft " + "" + "duskweed shoes" + "" + " within Daemonheim."); + case 54: + return newstruct cs2func_script_1000_struct(53, 17307, "Members: Spinoleather boots (Tier 6)", "Members can now craft " + "" + "spinoleather boots" + "" + " within Daemonheim."); + case 55: + return newstruct cs2func_script_1000_struct(54, 16745, "Members: Duskweed hood (Tier 6)", "Members can now craft " + "" + "duskweed hoods" + "" + " within Daemonheim."); + case 56: + return newstruct cs2func_script_1000_struct(55, 17051, "Members: Spinoleather coif (Tier 6)", "Members can now craft " + "" + "spinoleather coifs" + "" + " within Daemonheim."); + case 57: + return newstruct cs2func_script_1000_struct(56, 16855, "Members: Duskweed robe bottom (Tier 6)", "Members can now craft " + "" + "duskweed robe bottoms" + "" + " within Daemonheim."); + case 58: + return newstruct cs2func_script_1000_struct(57, 17329, "Members: Spinoleather chaps (Tier 6)", "Members can now craft " + "" + "spinoleather chaps" + "" + " within Daemonheim."); + case 59: + return newstruct cs2func_script_1000_struct(58, 17227, "Members: Duskweed robe top (Tier 6)", "Members can now craft " + "" + "duskweed robe tops" + "" + " within Daemonheim."); + case 60: + return newstruct cs2func_script_1000_struct(59, 17183, "Members: Spinoleather body (Tier 6)", "Members can now craft " + "" + "spinoleather bodies" + "" + " within Daemonheim."); + case 61: + return newstruct cs2func_script_1000_struct(60, 17163, "Members: Soulbell gloves (Tier 7)", "Members can now craft " + "" + "soulbell gloves" + "" + " within Daemonheim."); + case 62: + return newstruct cs2func_script_1000_struct(61, 17207, "Members: Gallileather vambraces (Tier 7)", "Members can now craft " + "" + "gallileather vambraces" + "" + " within Daemonheim."); + case 63: + return newstruct cs2func_script_1000_struct(62, 16923, "Members: Soulbell shoes (Tier 7)", "Members can now craft " + "" + "soulbell shoes" + "" + " within Daemonheim."); + case 64: + return newstruct cs2func_script_1000_struct(63, 17309, "Members: Gallileather boots (Tier 7)", "Members can now craft " + "" + "gallileather boots" + "" + " within Daemonheim."); + case 65: + return newstruct cs2func_script_1000_struct(64, 16747, "Members: Soulbell hood (Tier 7)", "Members can now craft " + "" + "soulbell hoods" + "" + " within Daemonheim."); + case 66: + return newstruct cs2func_script_1000_struct(65, 17053, "Members: Gallileather coif (Tier 7)", "Members can now craft " + "" + "gallileather coifs" + "" + " within Daemonheim."); + case 67: + return newstruct cs2func_script_1000_struct(66, 16857, "Members: Soulbell robe bottom (Tier 7)", "Members can now craft " + "" + "soulbell robe bottoms" + "" + " within Daemonheim."); + case 68: + return newstruct cs2func_script_1000_struct(67, 17331, "Members: Gallileather chaps (Tier 7)", "Members can now craft " + "" + "gallileather chaps" + "" + " within Daemonheim."); + case 69: + return newstruct cs2func_script_1000_struct(68, 17229, "Members: Soulbell robe top (Tier 7)", "Members can now craft " + "" + "soulbell robe tops" + "" + " within Daemonheim."); + case 70: + return newstruct cs2func_script_1000_struct(69, 17185, "Members: Gallileather body (Tier 7)", "Members can now craft " + "" + "gallileather bodies" + "" + " within Daemonheim."); + case 71: + return newstruct cs2func_script_1000_struct(70, 17165, "Members: Ectogloves (Tier 8)", "Members can now craft " + "" + "ectogloves" + "" + " within Daemonheim."); + case 72: + return newstruct cs2func_script_1000_struct(71, 17209, "Members: Stegoleather vambraces (Tier 8)", "Members can now craft " + "" + "stegoleather vambraces" + "" + " within Daemonheim."); + case 73: + return newstruct cs2func_script_1000_struct(72, 16925, "Members: Ectoshoes (Tier 8)", "Members can now craft " + "" + "ectoshoes" + "" + " within Daemonheim."); + case 74: + return newstruct cs2func_script_1000_struct(73, 17311, "Members: Stegoleather boots (Tier 8)", "Members can now craft " + "" + "stegoleather boots" + "" + " within Daemonheim."); + case 75: + return newstruct cs2func_script_1000_struct(74, 16749, "Members: Ectohood (Tier 8)", "Members can now craft " + "" + "ectohoods" + "" + " within Daemonheim."); + case 76: + return newstruct cs2func_script_1000_struct(75, 17055, "Members: Stegoleather coif (Tier 8)", "Members can now craft " + "" + "stegoleather coifs" + "" + " within Daemonheim."); + case 77: + return newstruct cs2func_script_1000_struct(76, 16859, "Members: Ectorobe bottom (Tier 8)", "Members can now craft " + "" + "ectorobe bottoms" + "" + " within Daemonheim."); + case 78: + return newstruct cs2func_script_1000_struct(77, 17333, "Members: Stegoleather chaps (Tier 8)", "Members can now craft " + "" + "stegoleather chaps" + "" + " within Daemonheim."); + case 79: + return newstruct cs2func_script_1000_struct(78, 17231, "Members: Ectorobe top (Tier 8)", "Members can now craft " + "" + "ectorobe tops" + "" + " within Daemonheim."); + case 80: + return newstruct cs2func_script_1000_struct(79, 17187, "Members: Stegoleather body (Tier 8)", "Members can now craft " + "" + "stegoleather bodies" + "" + " within Daemonheim."); + case 81: + return newstruct cs2func_script_1000_struct(80, 17167, "Members: Runic gloves (Tier 9)", "Members can now craft " + "" + "runic gloves" + "" + " within Daemonheim."); + case 82: + return newstruct cs2func_script_1000_struct(81, 17211, "Members: Megaleather vambraces (Tier 9)", "Members can now craft " + "" + "megaleather vambraces" + "" + " within Daemonheim."); + case 83: + return newstruct cs2func_script_1000_struct(82, 16927, "Members: Runic shoes (Tier 9)", "Members can now craft " + "" + "runic shoes" + "" + " within Daemonheim."); + case 84: + return newstruct cs2func_script_1000_struct(83, 17313, "Members: Megaleather boots (Tier 9)", "Members can now craft " + "" + "megaleather boots" + "" + " within Daemonheim."); + case 85: + return newstruct cs2func_script_1000_struct(84, 16751, "Members: Runic hood (Tier 9)", "Members can now craft " + "" + "runic hoods" + "" + " within Daemonheim."); + case 86: + return newstruct cs2func_script_1000_struct(85, 17057, "Members: Megaleather coif (Tier 9)", "Members can now craft " + "" + "megaleather coifs" + "" + " within Daemonheim."); + case 87: + return newstruct cs2func_script_1000_struct(86, 16861, "Members: Runic robe bottom (Tier 9)", "Members can now craft " + "" + "runic robe bottoms" + "" + " within Daemonheim."); + case 88: + return newstruct cs2func_script_1000_struct(87, 17335, "Members: Megaleather chaps (Tier 9)", "Members can now craft " + "" + "megaleather chaps" + "" + " within Daemonheim."); + case 89: + return newstruct cs2func_script_1000_struct(88, 17233, "Members: Runic robe top (Tier 9)", "Members can now craft " + "" + "runic robe tops" + "" + " within Daemonheim."); + case 90: + return newstruct cs2func_script_1000_struct(89, 17189, "Members: Megaleather body (Tier 9)", "Members can now craft " + "" + "megaleather bodies" + "" + " within Daemonheim."); + case 91: + return newstruct cs2func_script_1000_struct(90, 17169, "Members: Spiritbloom gloves (Tier 10)", "Members can now craft " + "" + "spiritbloom gloves" + "" + " within Daemonheim."); + case 92: + return newstruct cs2func_script_1000_struct(91, 17213, "Members: Tyrannoleather vambraces (Tier 10)", "Members can now craft " + "" + "tyrannoleather vambraces" + "" + " within Daemonheim."); + case 93: + return newstruct cs2func_script_1000_struct(92, 16929, "Members: Spiritbloom shoes (Tier 10)", "Members can now craft " + "" + "spiritbloom shoes" + "" + " within Daemonheim."); + case 94: + return newstruct cs2func_script_1000_struct(93, 17315, "Members: Tyrannoleather boots (Tier 10)", "Members can now craft " + "" + "tyrannoleather boots" + "" + " within Daemonheim."); + case 95: + return newstruct cs2func_script_1000_struct(94, 16753, "Members: Spiritbloom hood (Tier 10)", "Members can now craft " + "" + "spiritbloom hoods" + "" + " within Daemonheim."); + case 96: + return newstruct cs2func_script_1000_struct(95, 17059, "Members: Tyrannoleather coif (Tier 10)", "Members can now craft " + "" + "tyrannoleather coifs" + "" + " within Daemonheim."); + case 97: + return newstruct cs2func_script_1000_struct(96, 16863, "Members: Spiritbloom robe bottom (Tier 10)", "Members can now craft " + "" + "spiritbloom robe bottoms" + "" + " within Daemonheim."); + case 98: + return newstruct cs2func_script_1000_struct(97, 17337, "Members: Tyrannoleather chaps (Tier 10)", "Members can now craft " + "" + "tyrannoleather chaps" + "" + " within Daemonheim."); + case 99: + return newstruct cs2func_script_1000_struct(98, 17235, "Members: Spiritbloom robe top (Tier 10)", "Members can now craft " + "" + "spiritbloom robe tops" + "" + " within Daemonheim."); + case 100: + return newstruct cs2func_script_1000_struct(99, 17191, "Members: Tyrannoleather body (Tier 10)", "Members can now craft " + "" + "tyrannoleather bodies" + "" + " within Daemonheim."); + } + break; + case 12: + SWITCH (arg1) { + case 0: + GOTO flow_351 + case 1: + GOTO flow_352 + } + break; + flow_351: + return newstruct cs2func_script_1000_struct(40, 1757, "Crafting Guild", "You can now enter the " + "" + "Crafting Guild" + "" + "."); + flow_352: + return newstruct cs2func_script_1000_struct(99, 9780, "Skill mastery", "" + "Congratulations! You are now a master of " + "" + "Crafting" + "" + ". Members can visit the " + "" + "Master Craftsman" + "" + " at the " + "" + "Crafting Guild" + "" + ". He has something special that is only available to true masters of the " + "" + "Crafting" + "" + " skill!"); + } + return newstruct cs2func_script_1000_struct(0, -1, "", ""); +} diff --git a/dumps/scripts/1001.cs2 b/dumps/scripts/1001.cs2 new file mode 100644 index 0000000..73f2c08 --- /dev/null +++ b/dumps/scripts/1001.cs2 @@ -0,0 +1,21 @@ +cs2func_script_1001_struct(1,1,0) script_1001(int arg0) { + switch (arg0) { + case 0: + return newstruct cs2func_script_1001_struct(1, "Potions"); + case 1: + return newstruct cs2func_script_1001_struct(1, "Herbs"); + case 2: + return newstruct cs2func_script_1001_struct(1, "Barbarian potions"); + case 3: + return newstruct cs2func_script_1001_struct(1, "Equipment"); + case 4: + return newstruct cs2func_script_1001_struct(1, "Other"); + case 5: + return newstruct cs2func_script_1001_struct(1, "Minigames"); + case 6: + return newstruct cs2func_script_1001_struct(1, "Dungeoneering"); + case 7: + return newstruct cs2func_script_1001_struct(1, "Milestones"); + } + return newstruct cs2func_script_1001_struct(-1, ""); +} diff --git a/dumps/scripts/1002.cs2 b/dumps/scripts/1002.cs2 new file mode 100644 index 0000000..f7775ae --- /dev/null +++ b/dumps/scripts/1002.cs2 @@ -0,0 +1,385 @@ +cs2func_script_1002_struct(2,2,0) script_1002(int arg0,int arg1) { + switch (arg0) { + case 0: + switch (arg1) { + case 0: + return newstruct cs2func_script_1002_struct(-1, 7620, "You must complete Druidic Ritual before you can use Herblore.", ""); + case 1: + return newstruct cs2func_script_1002_struct(3, 121, "Attack potion" + "
" + "Guam & eye of newt", "You can now make " + "" + "attack potions" + "" + "."); + case 2: + return newstruct cs2func_script_1002_struct(5, 175, "Anti-poison" + "
" + "Marrentill & ground unicorn horn", "You can now make " + "" + "anti-poison" + "" + "."); + case 3: + return newstruct cs2func_script_1002_struct(8, 4844, "Relicym's balm" + "
" + "Rogue's Purse and snake weed (after starting Zogre Flesh Eaters)", "You now have the Herblore level required to make " + "" + "Relicym's balms" + "" + " (after starting Zogre Flesh Eaters)."); + case 4: + return newstruct cs2func_script_1002_struct(12, 115, "Strength potion" + "
" + "Tarromin & limpwurt root", "You can now make " + "" + "strength potions" + "" + "."); + case 5: + return newstruct cs2func_script_1002_struct(19, 10142, "Guam tar" + "
" + "Guam & swamp tar", "You can now make " + "" + "guam tar" + "" + "."); + case 6: + return newstruct cs2func_script_1002_struct(22, 127, "Stat restore potion" + "
" + "Harralander & red spiders' eggs", "You can now make " + "" + "stat restore potions" + "" + "."); + case 7: + return newstruct cs2func_script_1002_struct(22, 7662, "Guthix Balance potion" + "
" + "Harralander, red spiders' eggs, garlic and silver dust", "You can now make " + "" + "Guthix balance potions" + "" + "."); + case 8: + return newstruct cs2func_script_1002_struct(25, 1582, "Blamish oil" + "
" + "Harralander & blamish snail slime", "You can now make " + "" + "blamish oil" + "" + "."); + case 9: + return newstruct cs2func_script_1002_struct(26, 3010, "Energy potion" + "
" + "Harralander & chocolate dust", "You can now make " + "" + "energy potions" + "" + "."); + case 10: + return newstruct cs2func_script_1002_struct(30, 133, "Defence potion" + "
" + "Ranarr & white berries", "You can now make " + "" + "defence potions" + "" + "."); + case 11: + return newstruct cs2func_script_1002_struct(31, 10143, "Marrentill tar" + "
" + "Marrentill & swamp tar", "You can now make " + "" + "marrentill tar" + "" + "."); + case 12: + return newstruct cs2func_script_1002_struct(31, 12633, "Super fishing explosive" + "
" + "Guam & rubium (after Kennith's Concerns)", "You now have the Herblore level required to make " + "" + "super fishing explosives" + "" + " (after Kennith's Concerns)."); + case 13: + return newstruct cs2func_script_1002_struct(34, 3034, "Agility potion" + "
" + "Toadflax & toad legs", "You can now make " + "" + "agility potions" + "" + "."); + case 14: + return newstruct cs2func_script_1002_struct(36, 9741, "Combat potion" + "
" + "Harralander & ground desert goat horn", "You can now make " + "" + "combat potions" + "" + "."); + case 15: + return newstruct cs2func_script_1002_struct(38, 139, "Prayer restore potion" + "
" + "Ranarr & snape grass", "You can now make " + "" + "prayer restore potions" + "" + "."); + case 16: + return newstruct cs2func_script_1002_struct(39, 10144, "Tarromin tar" + "
" + "Tarromin & swamp tar", "You can now make " + "" + "tarromin tar" + "" + "."); + case 17: + return newstruct cs2func_script_1002_struct(40, 12142, "Summoning Potion" + "
" + "Spirit weed & cockatrice egg", "You can now make " + "" + "summoning potions" + "" + "."); + case 18: + return newstruct cs2func_script_1002_struct(42, 14840, "Crafting potion" + "
" + "Wergali & giant frogspawn", "You can now make " + "" + "crafting potions" + "" + "."); + case 19: + return newstruct cs2func_script_1002_struct(44, 10145, "Harralander tar" + "
" + "Harralander & swamp tar", "You can now make " + "" + "harralander tar" + "" + "."); + case 20: + return newstruct cs2func_script_1002_struct(45, 145, "Super Attack potion" + "
" + "Irit & eye of newt", "You can now make " + "" + "super attack potions" + "" + "."); + case 21: + return newstruct cs2func_script_1002_struct(46, 18662, "Vial of stench" + "
" + "Irit & chopped onion (after starting Buyers & Cellars: A Guild of our Own)", "You can now make " + "" + "a vial of stench" + "" + " with Robin's help (after starting Buyers & Cellars: A Guild of our Own)."); + case 22: + return newstruct cs2func_script_1002_struct(48, 181, "Super anti-poison" + "
" + "Irit & ground unicorn horn", "You can now make " + "" + "super anti-poison" + "" + "."); + case 23: + return newstruct cs2func_script_1002_struct(50, 151, "Fishing potion" + "
" + "Avantoe & snape grass", "You can now make " + "" + "fishing potions" + "" + "."); + case 24: + return newstruct cs2func_script_1002_struct(52, 3018, "Super energy potion" + "
" + "Avantoe & Mort Myre fungi", "You can now make " + "" + "super energy potions" + "" + "."); + case 25: + return newstruct cs2func_script_1002_struct(53, 10000, "Hunter potion - Avantoe & ground sabre-toothed kebbit teeth", "You can now make " + "" + "hunter potions" + "" + "."); + case 26: + return newstruct cs2func_script_1002_struct(54, 20024, "Juju hunter potion" + "
" + "Erzille & corrupt vine", "You can now make " + "" + "juju hunter potions" + "" + "."); + case 27: + return newstruct cs2func_script_1002_struct(55, 157, "Super Strength potion" + "
" + "Kwuarm & limpwurt root", "You can now make " + "" + "super strength potions" + "" + "."); + case 28: + return newstruct cs2func_script_1002_struct(57, 9022, "Magic essence potion" + "
" + "Starflower & ground gorak claw", "You can now make " + "" + "magic essence potions" + "" + "."); + case 29: + return newstruct cs2func_script_1002_struct(58, 14848, "Fletching potion" + "
" + "Wergali & wimpy bird feather", "You can now make " + "" + "fletching potions" + "" + "."); + case 30: + return newstruct cs2func_script_1002_struct(59, 20028, "Scentless potion" + "
" + "Argway & shadow vine", "You can now make " + "" + "scentless potions" + "" + "."); + case 31: + return newstruct cs2func_script_1002_struct(60, 187, "Weapon poison" + "
" + "Kwuarm & ground blue dragon scale", "You can now make " + "" + "weapon poisons" + "" + "."); + case 32: + return newstruct cs2func_script_1002_struct(63, 3026, "Super restore potion" + "
" + "Snapdragon & red spiders' eggs", "You can now make " + "" + "super restore potions" + "" + "."); + case 33: + return newstruct cs2func_script_1002_struct(64, 20012, "Juju farming potion" + "
" + "Ugune & marble vine", "You can now make " + "" + "juju farming potions" + "" + "."); + case 34: + return newstruct cs2func_script_1002_struct(65, 10927, "Sanfew Serum" + "
" + "Super restore potion, snake weed, ground unicorn horn and nail beast nails.", "You can now make " + "" + "Sanfew serums" + "" + "."); + case 35: + return newstruct cs2func_script_1002_struct(66, 163, "Super Defence potion" + "
" + "Cadantine & white berries", "You can now make " + "" + "super defence potions" + "" + "."); + case 36: + return newstruct cs2func_script_1002_struct(67, 20008, "Juju cooking potion" + "
" + "Shengo & plant teeth", "You can now make " + "" + "juju cooking potions" + "" + "."); + case 37: + return newstruct cs2func_script_1002_struct(68, 5945, "Anti-poison+" + "
" + "Coconut milk, toadflax & yew roots", "You can now make " + "" + "anti-poison+ potions" + "" + "."); + case 38: + return newstruct cs2func_script_1002_struct(69, 2454, "Anti fire-breath potion" + "
" + "Lantadyme & ground blue dragon scale", "You can now make " + "" + "anti fire-breath potions" + "" + "."); + case 39: + return newstruct cs2func_script_1002_struct(70, 20020, "Juju fishing potion" + "
" + "Shengo & aquatic vine", "You can now make " + "" + "juju fishing potions" + "" + "."); + case 40: + return newstruct cs2func_script_1002_struct(71, 20016, "Juju woodcutting potion" + "
" + "Samaden & oily vine", "You can now make " + "" + "juju woodcutting potions" + "" + "."); + case 41: + return newstruct cs2func_script_1002_struct(72, 169, "Ranging potion" + "
" + "Dwarf weed & wine of Zamorak", "You can now make " + "" + "ranging potions" + "" + "."); + case 42: + return newstruct cs2func_script_1002_struct(73, 5937, "Weapon poison+" + "
" + "Coconut milk, cactus spine & red spiders' eggs", "You can now make " + "" + "weapon poison+ potions" + "" + "."); + case 43: + return newstruct cs2func_script_1002_struct(74, 20004, "Juju mining potion" + "
" + "Samaden & draconic vine", "You can now make " + "" + "juju mining potions" + "" + "."); + case 44: + return newstruct cs2func_script_1002_struct(75, 20032, "Saradomin's blessing" + "
" + "Samaden & Saradomin vine", "You can now make " + "" + "Saradomin's blessings" + "" + "."); + case 45: + return newstruct cs2func_script_1002_struct(75, 20036, "Guthix's gift" + "
" + "Samaden & Guthix vine", "You can now make " + "" + "Guthix's gifts" + "" + "."); + case 46: + return newstruct cs2func_script_1002_struct(75, 20040, "Zamorak's favour" + "
" + "Samaden & Zamorak vine", "You can now make " + "" + "Zamorak's favours" + "" + "."); + case 47: + return newstruct cs2func_script_1002_struct(76, 3042, "Magic potion" + "
" + "Lantadyme & potato cactus", "You can now make " + "" + "magic potions" + "" + "."); + case 48: + return newstruct cs2func_script_1002_struct(78, 189, "Zamorak brew" + "
" + "Torstol & jangerberries", "You can now make " + "" + "Zamorak brews" + "" + "."); + case 49: + return newstruct cs2func_script_1002_struct(79, 5954, "Anti-poison++" + "
" + "Coconut milk, irit & magic tree roots", "You can now make " + "" + "anti-poison++ potions" + "" + "."); + case 50: + return newstruct cs2func_script_1002_struct(81, 6687, "Saradomin Brew" + "
" + "Toadflax & crushed bird nest", "You can now make " + "" + "Saradomin brews" + "" + "."); + case 51: + return newstruct cs2func_script_1002_struct(82, 5940, "Weapon poison++" + "
" + "Coconut milk, nightshade & poison ivy berries", "You can now make " + "" + "weapon poison++ potions" + "" + "."); + case 52: + return newstruct cs2func_script_1002_struct(84, 15301, "Recover special" + "
" + "Super energy potion & papaya", "You can now make " + "" + "recover special potions" + "" + "."); + case 53: + return newstruct cs2func_script_1002_struct(85, 15305, "Super antifire" + "
" + "Antifire potion & desert phoenix feather", "You can now make " + "" + "super antifire potions" + "" + "."); + case 54: + return newstruct cs2func_script_1002_struct(88, 15309, "Extreme attack" + "
" + "Super attack potion & avantoe", "You can now make " + "" + "extreme attack potions" + "" + "."); + case 55: + return newstruct cs2func_script_1002_struct(89, 15313, "Extreme strength" + "
" + "Super strength potion & dwarf weed", "You can now make " + "" + "extreme strength potions" + "" + "."); + case 56: + return newstruct cs2func_script_1002_struct(90, 15317, "Extreme defence" + "
" + "Super defence potion & lantadyme", "You can now make " + "" + "extreme defence potions" + "" + "."); + case 57: + return newstruct cs2func_script_1002_struct(91, 15321, "Extreme magic" + "
" + "Magic potion & ground mud runes", "You can now make " + "" + "extreme magic potions" + "" + "."); + case 58: + return newstruct cs2func_script_1002_struct(92, 15325, "Extreme ranging" + "
" + "Ranging potion & 5 grenwall spikes", "You can now make " + "" + "extreme ranging potions" + "" + "."); + case 59: + return newstruct cs2func_script_1002_struct(94, 15329, "Super prayer restore" + "
" + "Prayer restore potion & wyvern bonemeal", "You can now make " + "" + "super prayer potions" + "" + "."); + case 60: + return newstruct cs2func_script_1002_struct(94, 21632, "Prayer renewal" + "
" + "Fellstalk & morchella mushroom", "You can now make " + "" + "prayer renewal potions" + "" + "."); + case 61: + return newstruct cs2func_script_1002_struct(96, 15333, "Overload" + "
" + "Extreme attack, extreme strength, extreme defence, extreme magic, extreme ranging potions & torstol", "You can now make " + "" + "overload potions" + "" + "."); + } + break; + case 1: + switch (arg1) { + case 0: + return newstruct cs2func_script_1002_struct(-1, 7620, "You must complete Druidic Ritual before you can use Herblore", ""); + case 1: + return newstruct cs2func_script_1002_struct(3, 249, "Guam leaf", "You can now clean " + "" + "guam" + "" + "."); + case 2: + return newstruct cs2func_script_1002_struct(3, 1534, "Rogue's purse", "You can now clean " + "" + "rogue's purse" + "" + "."); + case 3: + return newstruct cs2func_script_1002_struct(3, 1526, "Snake weed", "You can now clean " + "" + "snake weed" + "" + "."); + case 4: + return newstruct cs2func_script_1002_struct(5, 251, "Marrentill", "You can now clean " + "" + "marrentill" + "" + "."); + case 5: + return newstruct cs2func_script_1002_struct(11, 253, "Tarromin", "You can now clean " + "" + "tarromin" + "" + "."); + case 6: + return newstruct cs2func_script_1002_struct(20, 255, "Harralander", "You can now clean " + "" + "harralander" + "" + "."); + case 7: + return newstruct cs2func_script_1002_struct(25, 257, "Ranarr", "You can now clean " + "" + "ranarr" + "" + "."); + case 8: + return newstruct cs2func_script_1002_struct(30, 2998, "Toadflax", "You can now clean " + "" + "toadflax" + "" + "."); + case 9: + return newstruct cs2func_script_1002_struct(35, 12172, "Spirit weed", "You can now clean " + "" + "spirit weed" + "" + "."); + case 10: + return newstruct cs2func_script_1002_struct(40, 259, "Irit leaf", "You can now clean " + "" + "irit leaf" + "" + "."); + case 11: + return newstruct cs2func_script_1002_struct(41, 14854, "Wergali", "You can now clean " + "" + "wergali" + "" + "."); + case 12: + return newstruct cs2func_script_1002_struct(48, 261, "Avantoe", "You can now clean " + "" + "avantoe" + "" + "."); + case 13: + return newstruct cs2func_script_1002_struct(54, 263, "Kwuarm", "You can now clean " + "" + "kwuarm" + "" + "."); + case 14: + return newstruct cs2func_script_1002_struct(54, 19989, "Erzille", "You can now clean " + "" + "erzille" + "" + "."); + case 15: + return newstruct cs2func_script_1002_struct(56, 19991, "Ugune", "You can now clean " + "" + "ugune" + "" + "."); + case 16: + return newstruct cs2func_script_1002_struct(57, 19990, "Argway", "You can now clean " + "" + "argway" + "" + "."); + case 17: + return newstruct cs2func_script_1002_struct(58, 19992, "Shengo", "You can now clean " + "" + "shengo" + "" + "."); + case 18: + return newstruct cs2func_script_1002_struct(59, 3000, "Snapdragon", "You can now clean " + "" + "snapdragon" + "" + "."); + case 19: + return newstruct cs2func_script_1002_struct(59, 19993, "Samaden", "You can now clean " + "" + "samaden" + "" + "."); + case 20: + return newstruct cs2func_script_1002_struct(65, 265, "Cadantine", "You can now clean " + "" + "cadantine" + "" + "."); + case 21: + return newstruct cs2func_script_1002_struct(67, 2481, "Lantadyme", "You can now clean " + "" + "lantadyme" + "" + "."); + case 22: + return newstruct cs2func_script_1002_struct(70, 267, "Dwarf weed", "You can now clean " + "" + "dwarf weed" + "" + "."); + case 23: + return newstruct cs2func_script_1002_struct(75, 269, "Torstol", "You can now clean " + "" + "torstol" + "" + "."); + case 24: + return newstruct cs2func_script_1002_struct(91, 21624, "Fellstalk", "You can now clean " + "" + "fellstalk" + "" + "."); + } + break; + case 2: + switch (arg1) { + case 0: + return newstruct cs2func_script_1002_struct(-1, 7620, "You must complete barbarian Herblore training before you can make these potions.", " "); + case 1: + return newstruct cs2func_script_1002_struct(4, 11429, "Attack mix", "You can now make " + "" + "attack mixes" + "" + "."); + case 2: + return newstruct cs2func_script_1002_struct(6, 11433, "Anti-poison mix", "You can now make " + "" + "anti-poison mixes" + "" + "."); + case 3: + return newstruct cs2func_script_1002_struct(9, 11437, "Relicym's Balm mix", "You can now make " + "" + "Relicym's balm mixes" + "" + "."); + case 4: + return newstruct cs2func_script_1002_struct(14, 11443, "Strength mix", "You can now make " + "" + "strength mixes" + "" + "."); + case 5: + return newstruct cs2func_script_1002_struct(24, 11449, "Stat restore mix", "You can now make " + "" + "stat restore mixes" + "" + "."); + case 6: + return newstruct cs2func_script_1002_struct(29, 11453, "Energy mix", "You can now make " + "" + "energy mixes" + "" + "."); + case 7: + return newstruct cs2func_script_1002_struct(33, 11457, "Defence mix", "You can now make " + "" + "defence mixes" + "" + "."); + case 8: + return newstruct cs2func_script_1002_struct(37, 11461, "Agility mix", "You can now make " + "" + "agility mixes" + "" + "."); + case 9: + return newstruct cs2func_script_1002_struct(40, 11445, "Combat mix", "You can now make " + "" + "combat mixes" + "" + "."); + case 10: + return newstruct cs2func_script_1002_struct(42, 11465, "Prayer restore mix", "You can now make " + "" + "prayer restore mixes" + "" + "."); + case 11: + return newstruct cs2func_script_1002_struct(47, 11469, "Super Attack mix", "You can now make " + "" + "super attack mixes" + "" + "."); + case 12: + return newstruct cs2func_script_1002_struct(51, 11473, "Super anti-poison mix", "You can now make " + "" + "super anti-poison mixes" + "" + "."); + case 13: + return newstruct cs2func_script_1002_struct(53, 11477, "Fishing mix", "You can now make " + "" + "fishing mixes" + "" + "."); + case 14: + return newstruct cs2func_script_1002_struct(56, 11481, "Super energy mix", "You can now make " + "" + "super energy mixes" + "" + "."); + case 15: + return newstruct cs2func_script_1002_struct(58, 11517, "Hunter mix", "You can now make " + "" + "hunter mixes" + "" + "."); + case 16: + return newstruct cs2func_script_1002_struct(59, 11485, "Super Strength mix", "You can now make " + "" + "super strength mixes" + "" + "."); + case 17: + return newstruct cs2func_script_1002_struct(61, 11489, "Magic essence mix", "You can now make " + "" + "magic essence mixes" + "" + "."); + case 18: + return newstruct cs2func_script_1002_struct(67, 11493, "Super restore mix", "You can now make " + "" + "super restore mix" + "" + "."); + case 19: + return newstruct cs2func_script_1002_struct(71, 11497, "Super Defence mix", "You can now make " + "" + "super defence mix" + "" + "."); + case 20: + return newstruct cs2func_script_1002_struct(74, 11501, "Anti-poison+ mix", "You can now make " + "" + "anti-poison+ mix" + "" + "."); + case 21: + return newstruct cs2func_script_1002_struct(75, 11505, "Anti fire-breath mix", "You can now make " + "" + "anti fire-breath mix" + "" + "."); + case 22: + return newstruct cs2func_script_1002_struct(80, 11509, "Ranging mix", "You can now make " + "" + "ranging mix" + "" + "."); + case 23: + return newstruct cs2func_script_1002_struct(83, 11513, "Magic mix", "You can now make " + "" + "magic mix" + "" + "."); + case 24: + return newstruct cs2func_script_1002_struct(85, 11521, "Zamorak mix", "You can now make " + "" + "Zamorak mix" + "" + "."); + } + break; + case 3: + switch (arg1) { + case 0: + return newstruct cs2func_script_1002_struct(21, 19675, "Members: Herbicide" + "
" + " (with 21 Dungeoneering)", "Members can now use " + "" + "herbicide" + "" + ". (They also need level 21 Dungeoneering.)"); + case 1: + return newstruct cs2func_script_1002_struct(50, 12856, "Irit gloves", "You can now wear " + "" + "irit gloves."); + case 2: + return newstruct cs2func_script_1002_struct(60, 12857, "Avantoe gloves", "You can now wear " + "" + "avantoe gloves."); + case 3: + return newstruct cs2func_script_1002_struct(70, 12858, "Kwuarm gloves", "You can now wear " + "" + "kwuarm gloves."); + case 4: + return newstruct cs2func_script_1002_struct(70, 18340, "Members: Anti-poison totem" + "
" + " (with 60 Defence and 60 Dungeoneering)", "Members can now wield " + "" + "anti-poison totems" + "" + ". (They also need level 60 Defence and level 60 Dungeoneering.)"); + case 5: + return newstruct cs2func_script_1002_struct(80, 12859, "Cadantine gloves", "You can now wear " + "" + "cadantine gloves."); + } + break; + case 4: + switch (arg1) { + case 0: + return newstruct cs2func_script_1002_struct(49, 19890, "Scroll of Cleansing" + "
" + " (with 49 Dungeoneering)", "You can now use the " + "" + "Scroll of cleansing" + "" + ". (You also need level 49 Dungeoneering.)"); + case 1: + return newstruct cs2func_script_1002_struct(91, 18778, "Starved ancient effigies", "You can now investigate " + "" + "starved ancient effigies" + "" + " using your knowledge of Herblore."); + case 2: + return newstruct cs2func_script_1002_struct(93, 18779, "Nourished ancient effigies", "You can now investigate " + "" + "nourished ancient effigies" + "" + " using your knowledge of Herblore."); + case 3: + return newstruct cs2func_script_1002_struct(95, 18780, "Sated ancient effigies", "You can now investigate " + "" + "sated ancient effigies" + "" + " using your knowledge of Herblore."); + case 4: + return newstruct cs2func_script_1002_struct(97, 18781, "Gorged ancient effigies", "You can now investigate " + "" + "gorged ancient effigies" + "" + " using your knowledge of Herblore."); + } + break; + case 5: + switch (arg1) { + case 0: + return newstruct cs2func_script_1002_struct(1, 14215, "Stealing Creation - class 1 sacred clay", "Members can now make " + "" + "1-dose potions out of class 1 sacred clay" + "" + " in Stealing Creation."); + case 1: + return newstruct cs2func_script_1002_struct(20, 14213, "Stealing Creation - class 2 sacred clay", "Members can now make " + "" + "2-dose potions out of class 2 sacred clay" + "" + " in Stealing Creation."); + case 2: + return newstruct cs2func_script_1002_struct(40, 14211, "Stealing Creation - class 3 sacred clay", "Members can now make " + "" + "3-dose potions out of class 3 sacred clay" + "" + " in Stealing Creation."); + case 3: + return newstruct cs2func_script_1002_struct(60, 14209, "Stealing Creation - class 4 sacred clay", "Members can now make " + "" + "4-dose potions out of class 4 sacred clay" + "" + " in Stealing Creation."); + case 4: + return newstruct cs2func_script_1002_struct(80, 14207, "Stealing Creation - class 5 sacred clay", "Members can now make " + "" + "5-dose potions out of class 5 sacred clay" + "" + " in Stealing Creation."); + } + break; + case 6: + switch (arg1) { + case 0: + return newstruct cs2func_script_1002_struct(-1, 15707, "Dungeoneering skill tasks" + "
" + "As your Herblore level increases, you will be able to attempt higher-level herblore tasks within Daemonheim. You will also be more likely to succeed when attempting herblore tasks within Daemonheim.", ""); + case 1: + return newstruct cs2func_script_1002_struct(3, 17556, "Weak magic potion" + "
" + " Sagewort & void dust", "You can now make " + "" + "weak magic potions" + "" + " within Daemonheim."); + case 2: + return newstruct cs2func_script_1002_struct(3, 17512, "Sagewort", "You can now clean " + "" + "sagewort" + "" + " within Daemonheim."); + case 3: + return newstruct cs2func_script_1002_struct(4, 17514, "Valerian", "You can now clean " + "" + "valerian" + "" + " within Daemonheim."); + case 4: + return newstruct cs2func_script_1002_struct(5, 17558, "Weak ranged potion" + "
" + " Valerian & void dust", "You can now make " + "" + "weak ranged potions" + "" + " within Daemonheim."); + case 5: + return newstruct cs2func_script_1002_struct(7, 17560, "Weak melee potion" + "
" + " Valerian & misshapen claw", "You can now make " + "" + "weak melee potions" + "" + " within Daemonheim."); + case 6: + return newstruct cs2func_script_1002_struct(8, 17516, "Aloe", "You can now clean " + "" + "aloe" + "" + " within Daemonheim."); + case 7: + return newstruct cs2func_script_1002_struct(9, 17562, "Weak defence potion" + "
" + " Aloe & void dust", "You can now make " + "" + "weak defence potions" + "" + " within Daemonheim."); + case 8: + return newstruct cs2func_script_1002_struct(12, 17564, "Weak stat restore potion" + "
" + " Aloe & red moss", "You can now make " + "" + "weak stat restore potions" + "" + " within Daemonheim."); + case 9: + return newstruct cs2func_script_1002_struct(15, 17568, "Weak cure potion" + "
" + " Aloe & firebreath whiskey", "You can now make " + "" + "weak cure potions" + "" + " within Daemonheim."); + case 10: + return newstruct cs2func_script_1002_struct(18, 17570, "Weak rejuvenation potion" + "
" + " Aloe & misshapen claw", "You can now make " + "" + "weak rejuvenation potions" + "" + " within Daemonheim."); + case 11: + return newstruct cs2func_script_1002_struct(21, 17572, "Weak poison" + "
" + " Sagewort & firebreath whiskey", "You can now make " + "" + "weak poisons" + "" + " within Daemonheim."); + case 12: + return newstruct cs2func_script_1002_struct(24, 17574, "Weak gatherer's potion" + "
" + " Sagewort & red moss", "You can now make " + "" + "weak gatherer's potions" + "" + " within Daemonheim."); + case 13: + return newstruct cs2func_script_1002_struct(27, 17576, "Weak artisan's potion" + "
" + " Valerian & red moss", "You can now make " + "" + "weak artisan's potions" + "" + " within Daemonheim."); + case 14: + return newstruct cs2func_script_1002_struct(30, 17578, "Weak naturalist's potion" + "
" + " Sagewort & misshapen claw", "You can now make " + "" + "weak naturalist's potions" + "" + " within Daemonheim."); + case 15: + return newstruct cs2func_script_1002_struct(33, 17580, "Weak survivalist's potion" + "
" + " Valerian and firebreath whiskey", "You can now make " + "" + "weak survivalist's potions" + "" + " within Daemonheim."); + case 16: + return newstruct cs2func_script_1002_struct(34, 17518, "Wormwood leaf", "You can now clean " + "" + "wormwood leaf" + "" + " within Daemonheim."); + case 17: + return newstruct cs2func_script_1002_struct(36, 17582, "Magic potion" + "
" + " Wormwood leaf & void dust", "You can now make " + "" + "magic potions" + "" + " within Daemonheim."); + case 18: + return newstruct cs2func_script_1002_struct(37, 17520, "Magebane", "You can now clean " + "" + "magebane" + "" + " within Daemonheim."); + case 19: + return newstruct cs2func_script_1002_struct(38, 17584, "Ranged potion" + "
" + " Magebane & void dust", "You can now make " + "" + "ranged potions" + "" + " within Daemonheim."); + case 20: + return newstruct cs2func_script_1002_struct(40, 17586, "Melee potion" + "
" + " Magebane & misshapen claw", "You can now make " + "" + "melee potions" + "" + " within Daemonheim."); + case 21: + return newstruct cs2func_script_1002_struct(41, 17522, "Featherfoil", "You can now clean " + "" + "featherfoil" + "" + " within Daemonheim."); + case 22: + return newstruct cs2func_script_1002_struct(42, 17588, "Defence potion" + "
" + " Featherfoil & void dust", "You can now make " + "" + "defence potions" + "" + " within Daemonheim."); + case 23: + return newstruct cs2func_script_1002_struct(45, 17590, "Stat restore potion" + "
" + " Featherfoil & red moss", "You can now make " + "" + "stat restore potions" + "" + " within Daemonheim."); + case 24: + return newstruct cs2func_script_1002_struct(48, 17592, "Cure potion" + "
" + " Featherfoil & firebreath whiskey", "You can now make " + "" + "cure potions" + "" + " within Daemonheim."); + case 25: + return newstruct cs2func_script_1002_struct(51, 17594, "Rejuvenation potion" + "
" + " Featherfoil & misshapen claw", "You can now make " + "" + "rejuvenation potions" + "" + " within Daemonheim."); + case 26: + return newstruct cs2func_script_1002_struct(54, 17596, "Poison" + "
" + " Wormwood leaf & firebreath whiskey", "You can now make " + "" + "poisons" + "" + " within Daemonheim."); + case 27: + return newstruct cs2func_script_1002_struct(57, 17598, "Gatherer's potion" + "
" + " Wormwood leaf & red moss", "You can now make " + "" + "gatherer's potions" + "" + " within Daemonheim."); + case 28: + return newstruct cs2func_script_1002_struct(60, 17600, "Artisan's potion" + "
" + " Magebane & red moss", "You can now make " + "" + "artisan's potions" + "" + " within Daemonheim."); + case 29: + return newstruct cs2func_script_1002_struct(63, 17602, "Naturalist's potion" + "
" + " Wormwood leaf & misshapen claw", "You can now make " + "" + "naturalist's potions" + "" + " within Daemonheim."); + case 30: + return newstruct cs2func_script_1002_struct(66, 17604, "Survivalist's potion" + "
" + " Magebane & firebreath whiskey", "You can now make " + "" + "survivalist's potions" + "" + " within Daemonheim."); + case 31: + return newstruct cs2func_script_1002_struct(67, 17524, "Winter's Grip", "You can now clean " + "" + "winter's grip" + "" + " within Daemonheim."); + case 32: + return newstruct cs2func_script_1002_struct(69, 17606, "Strong magic potion" + "
" + " Winter's grip & void dust", "You can now make " + "" + "strong magic potions" + "" + " within Daemonheim."); + case 33: + return newstruct cs2func_script_1002_struct(70, 17526, "Lycopus", "You can now clean " + "" + "lycopus" + "" + " within Daemonheim."); + case 34: + return newstruct cs2func_script_1002_struct(71, 17608, "Strong ranged potion" + "
" + " Lycopus & void dust", "You can now make " + "" + "strong ranged potions" + "" + " within Daemonheim."); + case 35: + return newstruct cs2func_script_1002_struct(73, 17610, "Strong melee potion" + "
" + " Lycopus & misshapen claw", "You can now make " + "" + "strong melee potions" + "" + " within Daemonheim."); + case 36: + return newstruct cs2func_script_1002_struct(74, 17528, "Buckthorn", "You can now clean " + "" + "buckthorn" + "" + " within Daemonheim."); + case 37: + return newstruct cs2func_script_1002_struct(75, 17612, "Strong defence potion" + "
" + " Buckthorn & void dust", "You can now make " + "" + "strong defence potions" + "" + " within Daemonheim."); + case 38: + return newstruct cs2func_script_1002_struct(78, 17614, "Strong stat restore potion" + "
" + " Buckthorn & red moss", "You can now make " + "" + "strong stat restore potions" + "" + " within Daemonheim."); + case 39: + return newstruct cs2func_script_1002_struct(81, 17616, "Strong cure potion" + "
" + " Buckthorn & firebreath whiskey", "You can now make " + "" + "strong cure potions" + "" + " within Daemonheim."); + case 40: + return newstruct cs2func_script_1002_struct(84, 17618, "Strong rejuvenation potion" + "
" + " Buckthorn & misshapen claw", "You can now make " + "" + "strong rejuvenation potions" + "" + " within Daemonheim."); + case 41: + return newstruct cs2func_script_1002_struct(87, 17620, "Strong poison" + "
" + " Winter's grip & firebreath whiskey", "You can now make " + "" + "strong poisons" + "" + " within Daemonheim."); + case 42: + return newstruct cs2func_script_1002_struct(90, 17622, "Strong gatherer's potion" + "
" + " Winter's grip & red moss", "You can now make " + "" + "strong gatherer's potions" + "" + " within Daemonheim."); + case 43: + return newstruct cs2func_script_1002_struct(93, 17624, "Strong artisan's potion" + "
" + " Lycopus & red moss", "You can now make " + "" + "strong artisan's potions" + "" + " within Daemonheim."); + case 44: + return newstruct cs2func_script_1002_struct(96, 17626, "Strong naturalist's potion" + "
" + " Winter's grip & misshapen claw", "You can now make " + "" + "strong naturalist's potions" + "" + " within Daemonheim."); + case 45: + return newstruct cs2func_script_1002_struct(99, 17628, "Strong survivalist's potion" + "
" + " Lycopus & firebreath whiskey", "You can now make " + "" + "strong survivalist's potions" + "" + " within Daemonheim."); + } + break; + case 7: + if (((boolean)arg1)) { + return newstruct cs2func_script_1002_struct(99, 9774, "Skill mastery", "" + "Congratulations! You are now a master of " + "" + "Herblore" + "" + ". Why not visit " + "" + "Kaqemeex" + "" + ", near " + "" + "Taverley" + "" + "? He has something special that is only available to true masters of the " + "" + "Herblore" + "" + " skill!"); + } + } + return newstruct cs2func_script_1002_struct(0, -1, "", ""); +} diff --git a/dumps/scripts/1003.cs2 b/dumps/scripts/1003.cs2 new file mode 100644 index 0000000..76f821e --- /dev/null +++ b/dumps/scripts/1003.cs2 @@ -0,0 +1,13 @@ +cs2func_script_1003_struct(1,1,0) script_1003(int arg0) { + switch (arg0) { + case 0: + return newstruct cs2func_script_1003_struct(0, "Prayers"); + case 1: + return newstruct cs2func_script_1003_struct(1, "Equipment"); + case 2: + return newstruct cs2func_script_1003_struct(0, "Dungeoneering"); + case 3: + return newstruct cs2func_script_1003_struct(0, "Milestones"); + } + return newstruct cs2func_script_1003_struct(-1, ""); +} diff --git a/dumps/scripts/1004.cs2 b/dumps/scripts/1004.cs2 new file mode 100644 index 0000000..aca55c5 --- /dev/null +++ b/dumps/scripts/1004.cs2 @@ -0,0 +1,214 @@ +cs2func_script_1004_struct(2,2,0) script_1004(int arg0,int arg1) { + switch (arg0) { + flow_1: + case 1: + switch (arg1) { + case 0: + return newstruct cs2func_script_1004_struct(10, 5574, "Members: Initiate sallet" + "
" + " (after Recruitment Drive and with 20 Defence)", "Members now have the Prayer level required to wear " + "" + "initiate sallets" + "" + " (after Recruitment Drive, with level 20 Defence)."); + case 1: + return newstruct cs2func_script_1004_struct(10, 5575, "Members: Initiate hauberk" + "
" + " (after Recruitment Drive and with 20 Defence)", "Members now have the Prayer level required to wear " + "" + "initiate hauberks" + "" + " (after Recruitment Drive, with level 20 Defence)."); + case 2: + return newstruct cs2func_script_1004_struct(10, 5576, "Members: Initiate cuisse" + "
" + " (after Recruitment Drive and with 20 Defence)", "Members now have the Prayer level required to wear " + "" + "initiate cuisses" + "" + " (after Recruitment Drive, with level 20 Defence)."); + case 3: + return newstruct cs2func_script_1004_struct(20, 9672, "Members: Proselyte sallet" + "
" + " (after Slug Menace and with 30 Defence)", "Members now have the Prayer level required to wear " + "" + "proselyte sallets" + "" + " (after Slug Menace, with level 30 Defence)."); + case 4: + return newstruct cs2func_script_1004_struct(20, 9674, "Members: Proselyte hauberk" + "
" + " (after Slug Menace and with 30 Defence)", "Members now have the Prayer level required to wear " + "" + "proselyte hauberks" + "" + " (after Slug Menace, with level 30 Defence)."); + case 5: + return newstruct cs2func_script_1004_struct(20, 9676, "Members: Proselyte cuisse" + "
" + " (after Slug Menace and with 30 Defence)", "Members now have the Prayer level required to wear " + "" + "proselyte cuisses" + "" + " (after Slug Menace, with level 30 Defence)."); + case 6: + return newstruct cs2func_script_1004_struct(20, 9678, "Members: Proselyte plateskirt" + "
" + " (after Slug Menace and with 30 Defence)", "Members now have the Prayer level required to wear " + "" + "proselyte plateskirts" + "" + " (after Slug Menace, with level 30 Defence)."); + case 7: + return newstruct cs2func_script_1004_struct(20, 10462, "Members: Guthix robe top", "Members can now wear " + "" + "Guthix robe tops" + "" + "."); + case 8: + return newstruct cs2func_script_1004_struct(20, 10466, "Members: Guthix robe legs", "Members can now wear " + "" + "Guthix robe legs" + "" + "."); + case 9: + return newstruct cs2func_script_1004_struct(20, 10458, "Members: Saradomin robe top", "Members can now wear " + "" + "Saradomin robe tops" + "" + "."); + case 10: + return newstruct cs2func_script_1004_struct(20, 10464, "Members: Saradomin robe legs", "Members can now wear " + "" + "Saradomin robe legs" + "" + "."); + case 11: + return newstruct cs2func_script_1004_struct(20, 10460, "Members: Zamorak robe top", "Members can now wear " + "" + "Zamorak robe tops" + "" + "."); + case 12: + return newstruct cs2func_script_1004_struct(20, 10468, "Members: Zamorak robe legs", "Members can now wear " + "" + "Zamorak robe legs" + "" + "."); + case 13: + return newstruct cs2func_script_1004_struct(20, 19380, "Members: Armadyl robe top", "Members can now wear " + "" + "Armadyl robe tops" + "" + "."); + case 14: + return newstruct cs2func_script_1004_struct(20, 19386, "Members: Armadyl robe legs", "Members can now wear " + "" + "Armadyl robe legs" + "" + "."); + case 15: + return newstruct cs2func_script_1004_struct(20, 19384, "Members: Bandos robe top", "Members can now wear " + "" + "Bandos robe tops" + "" + "."); + case 16: + return newstruct cs2func_script_1004_struct(20, 19388, "Members: Bandos robe legs", "Members can now wear " + "" + "Bandos robe legs" + "" + "."); + case 17: + return newstruct cs2func_script_1004_struct(20, 19382, "Members: Ancient robe top", "Members can now wear " + "" + "Ancient robe tops" + "" + "."); + case 18: + return newstruct cs2func_script_1004_struct(20, 19390, "Members: Ancient robe legs", "Members can now wear " + "" + "Ancient robe legs" + "" + "."); + case 19: + return newstruct cs2func_script_1004_struct(21, 18337, "Members: Bonecrusher" + "
" + " (with 21 Dungeoneering)", "Members can now use " + "" + "bonecrushers" + "" + ". (They also need level 21 Dungeoneering.)"); + case 20: + return newstruct cs2func_script_1004_struct(22, 11665, "Members: Void melee helm", "Members now have the Prayer level required to wear " + "" + "Void melee helms" + "" + "."); + case 21: + return newstruct cs2func_script_1004_struct(22, 11664, "Members: Void ranger helm", "Members now have the Prayer level required to wear " + "" + "Void ranger helms" + "" + "."); + case 22: + return newstruct cs2func_script_1004_struct(22, 11663, "Members: Void mage helm", "Members now have the Prayer level required to wear " + "" + "Void mage helms" + "" + "."); + case 23: + return newstruct cs2func_script_1004_struct(22, 8839, "Members: Void knight top", "Members now have the Prayer level required to wear " + "" + "Void knight tops" + "" + "."); + case 24: + return newstruct cs2func_script_1004_struct(22, 8840, "Members: Void knight robe", "Members now have the Prayer level required to wear " + "" + "Void knight robes" + "" + "."); + case 25: + return newstruct cs2func_script_1004_struct(22, 8842, "Members: Void knight gloves", "Members now have the Prayer level required to wear " + "" + "Void knight gloves" + "" + "."); + case 26: + return newstruct cs2func_script_1004_struct(22, 19712, "Members: Void knight deflector", "Members now have the Prayer level required to wear " + "" + "Void knight deflectors" + "" + "."); + case 27: + return newstruct cs2func_script_1004_struct(22, 8841, "Members: Void knight mace", "Members now have the Prayer level required to wield " + "" + "Void knight maces" + "" + "."); + case 28: + return newstruct cs2func_script_1004_struct(22, 7620, "Void knight equipment requires 42 Attack, Defence, Strength, Ranged, Magic and Constitution and 22 Prayer.", "" + "Void knight equipment" + "" + " requires 42 Attack, Defence, Strength, Ranged, Magic and Constitution and 22 Prayer."); + case 29: + return newstruct cs2func_script_1004_struct(25, 11061, "Members: Ancient Mace" + "
" + " (after Another Slice of H.A.M., with 15 Attack)", "Members now have the Prayer level required to wield the " + "" + "Ancient Mace" + "" + " (after Another Slice of H.A.M. with level 15 Attack)."); + case 30: + return newstruct cs2func_script_1004_struct(30, 19886, "Twisted bird skull necklace" + "
" + " (with 30 Dungeoneering)", "You now have the Prayer level required to wear " + "" + "Twisted bird skull necklaces" + "" + ". (You also need level 30 Dungeoneering.)"); + case 31: + return newstruct cs2func_script_1004_struct(40, 10448, "Members: Guthix cloak", "Members can now wear " + "" + "Guthix cloaks" + "" + "."); + case 32: + return newstruct cs2func_script_1004_struct(40, 10454, "Members: Guthix mitre" + "
" + " (with 40 Magic)", "Members now have the Prayer level required to wear " + "" + "Guthix mitres" + "" + ". (They also need level 40 Magic.)"); + case 33: + return newstruct cs2func_script_1004_struct(40, 10446, "Members: Saradomin cloak", "Members can now wear " + "" + "Saradomin cloaks" + "" + "."); + case 34: + return newstruct cs2func_script_1004_struct(40, 10452, "Members: Saradomin mitre" + "
" + " (with 40 Magic)", "Members now have the Prayer level required to wear " + "" + "Saradomin mitres" + "" + ". (They also need level 40 Magic.)"); + case 35: + return newstruct cs2func_script_1004_struct(40, 10450, "Members: Zamorak cloak", "Members can now wear " + "" + "Zamorak cloaks" + "" + "."); + case 36: + return newstruct cs2func_script_1004_struct(40, 10456, "Members: Zamorak mitre" + "
" + " (with 40 Magic)", "Members now have the Prayer level required to wear " + "" + "Zamorak mitres" + "" + ". (They also need level 40 Magic.)"); + case 37: + return newstruct cs2func_script_1004_struct(40, 19368, "Members: Armadyl cloak", "Members can now wear " + "" + "Armadyl cloaks" + "" + "."); + case 38: + return newstruct cs2func_script_1004_struct(40, 19374, "Members: Armadyl mitre" + "
" + " (with 40 Magic)", "Members now have the Prayer level required to wear " + "" + "Armadyl mitres" + "" + ". (They also need level 40 Magic.)"); + case 39: + return newstruct cs2func_script_1004_struct(40, 19370, "Members: Bandos cloak", "Members can now wear " + "" + "Bandos cloaks" + "" + "."); + case 40: + return newstruct cs2func_script_1004_struct(40, 19376, "Members: Bandos mitre" + "
" + " (with 40 Magic)", "Members now have the Prayer level required to wear " + "" + "Bandos mitres" + "" + ". (They also need level 40 Magic.)"); + case 41: + return newstruct cs2func_script_1004_struct(40, 19372, "Members: Ancient cloak", "Members can now wear " + "" + "Ancient cloaks" + "" + "."); + case 42: + return newstruct cs2func_script_1004_struct(40, 19378, "Members: Ancient mitre" + "
" + " (with 40 Magic)", "Members now have the Prayer level required to wear " + "" + "Ancient mitres" + "" + ". (They also need level 40 Magic.)"); + case 43: + return newstruct cs2func_script_1004_struct(48, 19892, "Amulet of zealots" + "
" + " (with 48 Dungeoneering)", "You now have the Prayer level required to wear " + "" + "Amulets of zealots" + "" + ". (You also need level 48 Dungeoneering.)"); + case 44: + return newstruct cs2func_script_1004_struct(50, 1716, "Members: Use completed Prayer books" + "
" + "to bless holy and unholy symbols" + "
" + " (after Horror from the Deep)", "Members now have the Prayer level required to use completed prayer books to bless " + "" + "holy" + "" + " and " + "" + "unholy symbols" + "" + " (after Horror from the Deep)."); + case 45: + return newstruct cs2func_script_1004_struct(55, 13734, "Members: Spirit shield" + "
" + " (after Summer's End and with 40 Defence)", "Members now have the Prayer level required to wield " + "" + "spirit shields" + "" + " (after Summer's End, with level 40 Defence)."); + case 46: + return newstruct cs2func_script_1004_struct(60, 10472, "Members: Guthix stole", "Members can now wear " + "" + "Guthix stoles" + "" + "."); + case 47: + return newstruct cs2func_script_1004_struct(60, 10442, "Members: Guthix crozier", "Members can now wield " + "" + "Guthix croziers" + "" + "."); + case 48: + return newstruct cs2func_script_1004_struct(60, 10470, "Members: Saradomin stole", "Members can now wear " + "" + "Saradomin stoles" + "" + "."); + case 49: + return newstruct cs2func_script_1004_struct(60, 10440, "Members: Saradomin crozier", "Members can now wield " + "" + "Saradomin croziers" + "" + "."); + case 50: + return newstruct cs2func_script_1004_struct(60, 10474, "Members: Zamorak stole", "Members can now wear " + "" + "Zamorak stoles" + "" + "."); + case 51: + return newstruct cs2func_script_1004_struct(60, 10444, "Members: Zamorak crozier", "Members can now wield " + "" + "Zamorak croziers" + "" + "."); + case 52: + return newstruct cs2func_script_1004_struct(60, 19392, "Members: Armadyl stole", "Members can now wear " + "" + "Armadyl stoles" + "" + "."); + case 53: + return newstruct cs2func_script_1004_struct(60, 19362, "Members: Armadyl crozier", "Members can now wield " + "" + "Armadyl croziers" + "" + "."); + case 54: + return newstruct cs2func_script_1004_struct(60, 19394, "Members: Bandos stole", "Members can now wear " + "" + "Bandos stoles" + "" + "."); + case 55: + return newstruct cs2func_script_1004_struct(60, 19364, "Members: Bandos crozier", "Members can now wield " + "" + "Bandos croziers" + "" + "."); + case 56: + return newstruct cs2func_script_1004_struct(60, 19396, "Members: Ancient stole", "Members can now wear " + "" + "Ancient stoles" + "" + "."); + case 57: + return newstruct cs2func_script_1004_struct(60, 19366, "Members: Ancient crozier", "Members can now wield " + "" + "Ancient croziers" + "" + "."); + case 58: + return newstruct cs2func_script_1004_struct(60, 19323, "Members: Dragon staff" + "
" + " (with 40 Magic, 40 Attack and 20 Defence)", "Members now have the Prayer level required to wield " + "" + "dragon staves" + "" + ". (They also need level 40 Magic, level 40 Attack and level 20 Defence.)"); + case 59: + return newstruct cs2func_script_1004_struct(60, 19325, "Members: Penguin staff" + "
" + " (with 40 Magic, 40 Attack and 20 Defence)", "Members now have the Prayer level required to wield " + "" + "penguin staves" + "" + ". (They also need level 40 Magic, level 40 Attack and level 20 Defence.)"); + case 60: + return newstruct cs2func_script_1004_struct(60, 19327, "Members: Bat staff" + "
" + " (with 40 Magic, 40 Attack and 20 Defence)", "Members now have the Prayer level required to wield " + "" + "bat staves" + "" + ". (They also need level 40 Magic, level 40 Attack and level 20 Defence.)"); + case 61: + return newstruct cs2func_script_1004_struct(60, 19329, "Members: Wolf staff" + "
" + " (with 40 Magic, 40 Attack and 20 Defence)", "Members now have the Prayer level required to wield " + "" + "wolf staves" + "" + ". (They also need level 40 Magic, level 40 Attack and level 20 Defence.)"); + case 62: + return newstruct cs2func_script_1004_struct(60, 19331, "Members: Cat staff" + "
" + " (with 40 Magic, 40 Attack and 20 Defence)", "Members now have the Prayer level required to wield " + "" + "cat staves" + "" + ". (They also need level 40 Magic, level 40 Attack and level 20 Defence.)"); + case 63: + return newstruct cs2func_script_1004_struct(60, 13736, "Members: Blessed spirit shield" + "
" + " (after Summer's End and with 70 Defence)", "Members now have the Prayer level required to wield " + "" + "blessed spirit shields" + "" + " (after Summer's End, with level 70 Defence)."); + case 64: + return newstruct cs2func_script_1004_struct(60, 19887, "Members: Split dragon tooth necklace" + "
" + " (with 60 Dungeoneering)", "Members now have the Prayer level required to wear " + "" + "Split dragon tooth necklaces" + "" + ". (They also need level 60 Dungeoneering.)"); + case 65: + return newstruct cs2func_script_1004_struct(65, 19308, "Members: Third-Age druidic staff", "Members can now wield " + "" + "Third-Age druidic staves" + "" + "."); + case 66: + return newstruct cs2func_script_1004_struct(65, 19311, "Members: Third-Age druidic cloak", "Members can now wear " + "" + "Third-Age druidic cloaks" + "" + "."); + case 67: + return newstruct cs2func_script_1004_struct(65, 19314, "Members: Third-Age druidic wreath", "Members can now wear " + "" + "Third-Age druidic wreaths" + "" + "."); + case 68: + return newstruct cs2func_script_1004_struct(65, 19317, "Members: Third-Age Druidic robe top", "Members can now wear " + "" + "Third-Age druidic robe tops" + "" + "."); + case 69: + return newstruct cs2func_script_1004_struct(65, 19320, "Members: Third-Age Druidic robe bottoms", "Members can now wear " + "" + "Third-Age druidic bottoms" + "" + "."); + case 70: + return newstruct cs2func_script_1004_struct(70, 13738, "Members: Arcane spirit shield" + "
" + " (after Summer's End and with 65 Magic and 75 Defence)", "Members now have the Prayer level required to wield " + "" + "arcane spirit shields" + "" + " (after Summer's End, with level 65 Magic and 75 Defence)."); + case 71: + return newstruct cs2func_script_1004_struct(70, 13744, "Members: Spectral spirit shield" + "
" + " (after Summer's End and with 65 Magic and 75 Defence)", "Members now have the Prayer level required to wield " + "" + "spectral spirit shields" + "" + " (after Summer's End, with level 65 Magic and 75 Defence)."); + case 72: + return newstruct cs2func_script_1004_struct(70, 21736, "Members: Akrisae's hood" + "
" + " (after Ritual of the Mahjarrat and with level 70 Defence and 70 Magic)", "Members now have the Prayer level required to wear " + "" + "Akrisae's hood" + "" + " (after Ritual of the Mahjarrat and with level 70 Defence and 70 Magic)."); + case 73: + return newstruct cs2func_script_1004_struct(70, 21752, "Members: Akrisae's robe top" + "
" + " (after Ritual of the Mahjarrat and with level 70 Defence and 70 Magic)", "Members now have the Prayer level required to wear " + "" + "Akrisae's robe top" + "" + " (after Ritual of the Mahjarrat and with level 70 Defence and 70 Magic)."); + case 74: + return newstruct cs2func_script_1004_struct(70, 21760, "Members: Akrisae's robe skirt" + "
" + " (after Ritual of the Mahjarrat and with level 70 Defence and 70 Magic)", "Members now have the Prayer level required to wear " + "" + "Akrisae's robe skirt" + "" + " (after Ritual of the Mahjarrat and with level 70 Defence and 70 Magic)."); + case 75: + return newstruct cs2func_script_1004_struct(70, 21744, "Members: Akrisae's war mace" + "
" + " (after Ritual of the Mahjarrat and with level 70 Attack and 70 Magic)", "Members now have the Prayer level required to use " + "" + "Akrisae's war mace" + "" + " (after Ritual of the Mahjarrat and with level 70 Defence and 70 Magic)."); + case 76: + return newstruct cs2func_script_1004_struct(75, 13740, "Members: Divine spirit shield" + "
" + " (after Summer's End and with 75 Defence)", "Members now have the Prayer level required to wield " + "" + "divine spirit shields" + "" + " (after Summer's End, with level 75 Defence)."); + case 77: + return newstruct cs2func_script_1004_struct(75, 13742, "Members: Elysian spirit shield" + "
" + " (after Summer's End and with 75 Defence)", "Members now have the Prayer level required to wield " + "" + "elysian spirit shields" + "" + " (after Summer's End, with level 75 Defence)."); + case 78: + return newstruct cs2func_script_1004_struct(90, 19888, "Members: Demon horn necklace" + "
" + " (with 90 Dungeoneering)", "Members now have the Prayer level required to wear " + "" + "Demon horn necklaces" + "" + ". (They also need level 90 Dungeoneering.)"); + } + break; + case 2: + switch (arg1) { + case 0: + return newstruct cs2func_script_1004_struct(-1, 15707, "Dungeoneering skill tasks" + "
" + "As your Prayer level increases, you will be able to attempt higher-level prayer tasks within Daemonheim. You will also be more likely to succeed when attempting prayer tasks within Daemonheim.", ""); + } + break; + case 3: + SWITCH (arg1) { + case 0: + GOTO flow_86 + case 1: + GOTO flow_87 + case 2: + GOTO flow_88 + case 3: + GOTO flow_89 + case 4: + GOTO flow_90 + case 5: + GOTO flow_91 + case 6: + GOTO flow_92 + case 7: + GOTO flow_93 + case 8: + GOTO flow_94 + } + break; + flow_86: + return newstruct cs2func_script_1004_struct(2, 11948, "Repair somebody else's gravestone", "You can now " + "" + "repair" + "" + " somebody else's " + "" + "gravestone" + "" + "!"); + flow_87: + return newstruct cs2func_script_1004_struct(31, 13253, "Monastery", "Abbot Langley will now let you enter the " + "" + "Monastery" + "" + " west of " + "" + "Edgeville" + "" + "."); + flow_88: + return newstruct cs2func_script_1004_struct(70, 11948, "Bless somebody else's gravestone", "You can now " + "" + "bless somebody else's " + "" + "gravestone" + "" + "!"); + flow_89: + return newstruct cs2func_script_1004_struct(85, 13754, "Members: Bless spirit shields" + "
" + " (after Summer's End)", "Members can now " + "" + "bless spirit shields" + "" + " (after Summer's End)."); + flow_90: + return newstruct cs2func_script_1004_struct(90, 13746, "Members: Create arcane spirit shields" + "
" + " (after Summer's End and with 85 Smithing)", "Members can now create " + "" + "arcane spirit shields" + "" + " (after Summer's End, with level 85 Smithing)."); + flow_91: + return newstruct cs2func_script_1004_struct(90, 13748, "Members: Create divine spirit shields" + "
" + " (after Summer's End and with 85 Smithing)", "Members can now create " + "" + "divine spirit shields" + "" + " (after Summer's End, with level 85 Smithing)."); + flow_92: + return newstruct cs2func_script_1004_struct(90, 13750, "Members: Create elysian spirit shields" + "
" + " (after Summer's End and with 85 Smithing)", "Members can now create " + "" + "elysian spirit shields" + "" + " (after Summer's End, with level 85 Smithing)."); + flow_93: + return newstruct cs2func_script_1004_struct(90, 13752, "Members: Create spectral spirit shields" + "
" + " (after Summer's End and with 85 Smithing)", "Members can now create " + "" + "spectral spirit shields" + "" + " (after Summer's End, with level 85 Smithing)."); + flow_94: + return newstruct cs2func_script_1004_struct(99, 9759, "Skill mastery", "" + "Congratulations! You are now a master of " + "" + "Prayer" + "" + ". Members can visit " + "" + "Brother Jared" + "" + " upstairs at the " + "" + "Monastery" + "" + ". He has something special that is only available to true masters of the " + "" + "Prayer" + "" + " skill!"); + } + return newstruct cs2func_script_1004_struct(0, -1, "", ""); +} diff --git a/dumps/scripts/1005.cs2 b/dumps/scripts/1005.cs2 new file mode 100644 index 0000000..d93303a --- /dev/null +++ b/dumps/scripts/1005.cs2 @@ -0,0 +1,37 @@ +cs2func_script_1005_struct(1,1,0) script_1005(int arg0) { + switch (arg0) { + case 0: + return newstruct cs2func_script_1005_struct(1, "Traps"); + case 1: + return newstruct cs2func_script_1005_struct(1, "Tracking"); + case 2: + return newstruct cs2func_script_1005_struct(1, "Birds"); + case 3: + return newstruct cs2func_script_1005_struct(1, "Butterfly net"); + case 4: + return newstruct cs2func_script_1005_struct(1, "Deadfall"); + case 5: + return newstruct cs2func_script_1005_struct(1, "Box trap"); + case 6: + return newstruct cs2func_script_1005_struct(1, "Net trap"); + case 7: + return newstruct cs2func_script_1005_struct(1, "Pitfalls"); + case 8: + return newstruct cs2func_script_1005_struct(1, "Falconry"); + case 9: + return newstruct cs2func_script_1005_struct(1, "Imp box"); + case 10: + return newstruct cs2func_script_1005_struct(1, "Other"); + case 11: + return newstruct cs2func_script_1005_struct(1, "Clothing"); + case 12: + return newstruct cs2func_script_1005_struct(1, "Barehanded"); + case 13: + return newstruct cs2func_script_1005_struct(1, "Minigames"); + case 14: + return newstruct cs2func_script_1005_struct(1, "Dungeoneering"); + case 15: + return newstruct cs2func_script_1005_struct(1, "Milestones"); + } + return newstruct cs2func_script_1005_struct(-1, ""); +} diff --git a/dumps/scripts/1006.cs2 b/dumps/scripts/1006.cs2 new file mode 100644 index 0000000..193b2a6 --- /dev/null +++ b/dumps/scripts/1006.cs2 @@ -0,0 +1,382 @@ +cs2func_script_1006_struct(2,2,0) script_1006(int arg0,int arg1) { + switch (arg0) { + case 0: + switch (arg1) { + case 0: + return newstruct cs2func_script_1006_struct(1, 9951, "Lay 1 trap at a time", "You can now lay " + "" + "1 trap" + "" + " at a time."); + case 1: + return newstruct cs2func_script_1006_struct(1, 10006, "Bird snare setting", "You can now set " + "" + "bird snares" + "" + "."); + case 2: + return newstruct cs2func_script_1006_struct(1, 10150, "Noose wand", "You can now use a " + "" + "noose wand" + "" + " when tracking."); + case 3: + return newstruct cs2func_script_1006_struct(15, 10010, "Butterfly netting", "You can now use a " + "" + "butterfly net" + "" + " and " + "" + "butterfly jar" + "" + " to catch " + "" + "butterflies" + "" + "."); + case 4: + return newstruct cs2func_script_1006_struct(20, 9951, "Lay up to 2 traps at a time", "You can now lay up to " + "" + "2 traps" + "" + " at a time."); + case 5: + return newstruct cs2func_script_1006_struct(23, 1511, "Set a deadfall trap (limit of 1)", "You can now set a " + "" + "deadfall trap" + "" + " up to a limit of 1."); + case 6: + return newstruct cs2func_script_1006_struct(27, 10008, "Set a box trap", "You can now set a " + "" + "box trap" + "" + "."); + case 7: + return newstruct cs2func_script_1006_struct(27, 10031, "Set a rabbit snare", "You can now set a " + "" + "rabbit snare" + "" + "."); + case 8: + return newstruct cs2func_script_1006_struct(29, 303, "Set a net trap", "You can now set a " + "" + "net trap" + "" + "."); + case 9: + return newstruct cs2func_script_1006_struct(31, 10029, "Set a pitfall trap", "You can now set a " + "" + "pitfall trap" + "" + "."); + case 10: + return newstruct cs2func_script_1006_struct(39, 594, "Use smoke to mask the scent on a trap", "You can now use " + "" + "smoke" + "" + " to mask the scent on a trap."); + case 11: + return newstruct cs2func_script_1006_struct(40, 9951, "Lay up to 3 traps at a time", "You can now lay up to " + "" + "3 traps" + "" + " at a time."); + case 12: + return newstruct cs2func_script_1006_struct(40, 14110, "Sacred clay butterfly net", "You can now use " + "" + "sacred clay butterfly nets" + ""); + case 13: + return newstruct cs2func_script_1006_struct(40, 14102, "Volatile butterfly net", "You can now use " + "" + "volatile butterfly nets" + ""); + case 14: + return newstruct cs2func_script_1006_struct(43, 10023, "Hunt with a falcon", "You can now hunt with a " + "" + "falcon" + "" + "."); + case 15: + return newstruct cs2func_script_1006_struct(60, 9951, "Lay up to 4 traps at a time", "You can now lay up to " + "" + "4 traps" + "" + " at a time."); + case 16: + return newstruct cs2func_script_1006_struct(70, 19965, "Marasamaw plants (herblore habitat)", "You can now set a " + "" + "marasamaw plant" + "" + " trap."); + case 17: + return newstruct cs2func_script_1006_struct(71, 10025, "Magical imp box", "You can now set a " + "" + "magical imp box" + "" + " trap."); + case 18: + return newstruct cs2func_script_1006_struct(80, 9951, "Lay up to 5 traps at a time", "You can now lay up to " + "" + " 5 traps" + "" + " at a time."); + } + break; + case 1: + switch (arg1) { + case 0: + return newstruct cs2func_script_1006_struct(1, 9953, "Polar kebbit (polar)", "You can now track " + "" + "polar kebbits" + "" + "."); + case 1: + return newstruct cs2func_script_1006_struct(3, 9954, "Common kebbit (woodland)", "You can now track " + "" + "common kebbits" + "" + "."); + case 2: + return newstruct cs2func_script_1006_struct(7, 9955, "Feldip weasel (jungle)", "You can now track " + "" + "feldip weasels" + "" + "."); + case 3: + return newstruct cs2func_script_1006_struct(13, 9956, "Desert devil (desert)", "You can now track " + "" + "desert devils" + "" + "."); + case 4: + return newstruct cs2func_script_1006_struct(45, 14832, "Penguins (polar)" + "
" + " (after Hunt for Red Raktuber)", "You can now track " + "" + "penguins" + "" + " (after Hunt for Red Raktuber)."); + case 5: + return newstruct cs2func_script_1006_struct(49, 9961, "Razor-backed kebbit (woodland)", "You can now track " + "" + "razor-backed kebbits" + "" + "."); + case 6: + return newstruct cs2func_script_1006_struct(71, 19954, "Shadow jadinko (herblore habitat)", "You can now track " + "" + "shadow jadinkos" + "" + "."); + case 7: + return newstruct cs2func_script_1006_struct(78, 19958, "Diseased jadinko (herblore habitat)", "You can now track " + "" + "diseased jadinkos" + "" + "."); + case 8: + return newstruct cs2func_script_1006_struct(79, 19955, "Camouflaged jadinko (herblore habitat)", "You can now track " + "" + "camouflaged jadinkos" + "" + "."); + } + break; + case 2: + switch (arg1) { + case 0: + return newstruct cs2func_script_1006_struct(1, 9965, "Crimson swift (jungle)", "You can now trap " + "" + "crimson swifts" + "" + "."); + case 1: + return newstruct cs2func_script_1006_struct(5, 9968, "Golden warbler (desert)", "You can now trap " + "" + "golden warblers" + "" + "."); + case 2: + return newstruct cs2func_script_1006_struct(9, 9966, "Copper longtail (woodland)", "You can now trap " + "" + "copper longtails" + "" + "."); + case 3: + return newstruct cs2func_script_1006_struct(11, 9967, "Cerulean twitch (polar)", "You can now trap " + "" + "cerulean twitches" + "" + "."); + case 4: + return newstruct cs2func_script_1006_struct(19, 9969, "Tropical wagtail (jungle)", "You can now trap " + "" + "tropical wagtails" + "" + "."); + case 5: + return newstruct cs2func_script_1006_struct(39, 12586, "Wimpy bird (jungle)" + "
" + " (after starting As a First Resort...)" + "
" + " Required lure: smouldering tansymum", "You can now trap " + "" + "wimpy birds" + "" + " (after starting As a First Resort...)."); + } + break; + case 3: + switch (arg1) { + case 0: + return newstruct cs2func_script_1006_struct(15, 9970, "Ruby harvest butterfly (woodland)", "You can now net " + "" + "ruby harvest butterflies" + "" + "."); + case 1: + return newstruct cs2func_script_1006_struct(17, 11238, "Baby impling", "You can now net " + "" + "baby implings" + "" + "."); + case 2: + return newstruct cs2func_script_1006_struct(22, 11240, "Young impling", "You can now net " + "" + "young implings" + "" + "."); + case 3: + return newstruct cs2func_script_1006_struct(25, 9971, "Sapphire glacialis butterfly (polar)", "You can now net " + "" + "sapphire glacialis butterflies" + "" + "."); + case 4: + return newstruct cs2func_script_1006_struct(28, 11242, "Gourmet impling", "You can now net " + "" + "gourmet implings" + "" + "."); + case 5: + return newstruct cs2func_script_1006_struct(35, 9972, "Snowy knight butterfly (polar)", "You can now net " + "" + "snowy knight butterflies" + "" + "."); + case 6: + return newstruct cs2func_script_1006_struct(36, 11244, "Earth impling", "You can now net " + "" + "earth implings" + "" + "."); + case 7: + return newstruct cs2func_script_1006_struct(42, 11246, "Essence impling", "You can now net " + "" + "essence implings" + "" + "."); + case 8: + return newstruct cs2func_script_1006_struct(45, 9973, "Black warlock butterfly (jungle)", "You can now net " + "" + "black warlock butterflies" + "" + "."); + case 9: + return newstruct cs2func_script_1006_struct(50, 11248, "Eclectic impling", "You can now net " + "" + "eclectic implings" + "" + "."); + case 10: + return newstruct cs2func_script_1006_struct(54, 15513, "Spirit impling", "You can now net " + "" + "spirit implings" + "" + "."); + case 11: + return newstruct cs2func_script_1006_struct(58, 11250, "Nature impling", "You can now net " + "" + "nature implings" + "" + "."); + case 12: + return newstruct cs2func_script_1006_struct(65, 11252, "Magpie impling", "You can now net " + "" + "magpie implings" + "" + "."); + case 13: + return newstruct cs2func_script_1006_struct(74, 11254, "Ninja impling", "You can now net " + "" + "ninja implings" + "" + "."); + case 14: + return newstruct cs2func_script_1006_struct(76, 13337, "Pirate impling" + "
" + " (after Rocking Out)", "You can now net " + "" + "pirate implings" + "" + " (after Rocking Out)."); + case 15: + return newstruct cs2func_script_1006_struct(83, 11256, "Dragon impling", "You can now net " + "" + "dragon implings" + "" + "."); + case 16: + return newstruct cs2func_script_1006_struct(87, 15515, "Zombie impling", "You can now net " + "" + "zombie implings" + "" + "."); + case 17: + return newstruct cs2func_script_1006_struct(91, 15517, "Kingly impling", "You can now net " + "" + "kingly implings" + "" + "."); + } + break; + case 4: + switch (arg1) { + case 0: + return newstruct cs2func_script_1006_struct(23, 9962, "Wild kebbit (woodland)" + "
" + " Preferred bait: Raw meat", "You can now use deadfall traps to hunt " + "" + "wild kebbits" + "" + "."); + case 1: + return newstruct cs2func_script_1006_struct(33, 9958, "Barb-tailed kebbit (jungle)" + "
" + " Preferred bait: Raw rainbow fish", "You can now use deadfall traps to hunt " + "" + "barb-tailed kebbits" + "" + "."); + case 2: + return newstruct cs2func_script_1006_struct(37, 9957, "Prickly kebbit (northern woodland)" + "
" + " Preferred bait: Barley", "You can now use deadfall traps to hunt " + "" + "prickly kebbits" + "" + "."); + case 3: + return newstruct cs2func_script_1006_struct(44, 12587, "Diseased kebbit (jungle)" + "
" + " (after starting As a First Resort...)" + "
" + " Required lure: smouldering fever grass", "You now have the Hunter level required to use deadfall traps to hunt " + "" + "diseased kebbits" + "" + " (after starting As a First Resort...)."); + case 4: + return newstruct cs2func_script_1006_struct(51, 9959, "Sabre-toothed kebbit (polar)" + "
" + " Preferred bait: Raw meat", "You can now use deadfall traps to hunt " + "" + "sabre-toothed kebbits" + "" + "."); + case 5: + return newstruct cs2func_script_1006_struct(51, 14832, "Penguins (polar)" + "
" + " (after Hunt for Red Raktuber)" + "
" + " Preferred bait: Raw cod", "You can now use deadfall traps to hunt " + "" + "penguins" + "" + " (after Hunt for Red Raktuber)."); + } + break; + case 5: + switch (arg1) { + case 0: + return newstruct cs2func_script_1006_struct(27, 10092, "Ferret (woodland)" + "
" + " (after Eagles' Peak)", "You can now catch " + "" + "ferrets" + "" + " with box traps (after Eagles' Peak)."); + case 1: + return newstruct cs2func_script_1006_struct(27, 12184, "Gecko" + "
" + " (with 10 Summoning)", "You now have the Hunter level required to catch " + "" + "geckos" + "" + " with box traps. (You also need level 10 Summoning.)"); + case 2: + return newstruct cs2func_script_1006_struct(27, 12199, "Raccoon" + "
" + " (with 80 Summoning)", "You now have the Hunter level required to catch " + "" + "raccoons" + "" + " with box traps. (You also need level 80 Summoning.)"); + case 3: + return newstruct cs2func_script_1006_struct(27, 12201, "Monkey" + "
" + " (with 95 Summoning)" + "
" + " Preferred bait: Bananas", "You now have the Hunter level required to catch " + "" + "monkeys" + "" + " with box traps. (You also need level 95 Summoning.)"); + case 4: + return newstruct cs2func_script_1006_struct(48, 12585, "Platypus (jungle)" + "
" + " (with 10 Summoning)" + "
" + " (after starting As a First Resort...)" + "
" + " Required lure: Smouldering lavender", "You now have the Hunter level required to catch " + "" + "platypodes" + "" + " with box traps (after As a First Resort... and with level 10 Summoning)."); + case 5: + return newstruct cs2func_script_1006_struct(53, 9976, "Chinchompa (woodland)" + "
" + " Preferred bait: Spicy chopped tomatoes", "You can now catch " + "" + "chinchompas" + "" + " with box traps."); + case 6: + return newstruct cs2func_script_1006_struct(56, 14832, "Penguin (polar)" + "
" + " (after Hunt for Red Raktuber)" + "
" + " Preferred bait: Raw cod", "You can now catch " + "" + "penguins" + "" + " with box traps (after Hunt for Red Raktuber)."); + case 7: + return newstruct cs2func_script_1006_struct(63, 9977, "Red chinchompa (jungle)" + "
" + " Preferred bait: Spicy minced meat", "You can now catch " + "" + "red chinchompas" + "" + " with box traps."); + case 8: + return newstruct cs2func_script_1006_struct(66, 12544, "Pawya (Isafdar)" + "
" + " Required bait: Papaya fruit", "You can now catch " + "" + "pawyas" + "" + " with box traps."); + case 9: + return newstruct cs2func_script_1006_struct(70, 19951, "Common jadinko (using marasamaw plants)" + "
" + " Preferred bait: Withered vines", "You can now catch " + "" + "common jadinkos" + "" + " with marasamaw plants."); + case 10: + return newstruct cs2func_script_1006_struct(74, 19957, "Igneous jadinko (using marasamaw plants)" + "
" + " Preferred bait: Withered vines", "You can now catch " + "" + "igneous jadinkos" + "" + " with marasamaw plants."); + case 11: + return newstruct cs2func_script_1006_struct(75, 19960, "Cannibal jadinko (using marasamaw plants)" + "
" + " Preferred bait: Withered vines", "You can now catch " + "" + "cannibal jadinkos" + "" + " with marasamaw plants."); + case 12: + return newstruct cs2func_script_1006_struct(76, 19953, "Aquatic jadinko (using marasamaw plants)" + "
" + " Preferred bait: Withered vines", "You can now catch " + "" + "aquatic jadinkos" + "" + " with marasamaw plants."); + case 13: + return newstruct cs2func_script_1006_struct(77, 19952, "Amphibious jadinko (using marasamaw plants)" + "
" + " Preferred bait: Withered vines", "You can now catch " + "" + "amphibious jadinkos" + "" + " with marasamaw plants."); + case 14: + return newstruct cs2func_script_1006_struct(77, 12537, "Grenwall (Isafdar)" + "
" + " Required bait: Raw pawya meat", "You can now catch " + "" + "grenwall" + "" + " with box traps."); + case 15: + return newstruct cs2func_script_1006_struct(78, 19959, "Carrion jadinko (using marasamaw plants)" + "
" + " Preferred bait: Withered vines", "You can now catch " + "" + "carrion jadinkos" + "" + " with marasamaw plants."); + case 16: + return newstruct cs2func_script_1006_struct(80, 19956, "Draconic jadinko (using marasamaw plants)" + "
" + " Preferred bait: Withered vines", "You can now catch " + "" + "draconic jadinkos" + "" + " with marasamaw plants."); + case 17: + return newstruct cs2func_script_1006_struct(81, 19961, "Saradomin, Guthix and Zamorak jadinko (using marasamaw plants)" + "
" + " Preferred bait: Withered vines", "You can now catch " + "" + "Saradomin, Guthix and Zamorak jadinkos" + "" + " with marasamaw plants."); + } + break; + case 6: + switch (arg1) { + case 0: + return newstruct cs2func_script_1006_struct(29, 10149, "Swamp lizard (swamp)" + "
" + " Preferred bait: Guam tar", "You can now catch " + "" + "swamp lizards" + "" + " with net traps."); + case 1: + return newstruct cs2func_script_1006_struct(29, 12200, "Squirrel" + "
" + " (with 60 Summoning)" + "
" + " Preferred bait: Nuts", "You now have the Hunter level required to catch " + "" + "squirrels" + "" + " with net traps. (You also need level 60 Summoning.)"); + case 2: + return newstruct cs2func_script_1006_struct(47, 10146, "Orange salamander (desert)" + "
" + " Preferred bait: Marrentill tar", "You can now catch " + "" + "orange salamanders" + "" + " with net traps."); + case 3: + return newstruct cs2func_script_1006_struct(50, 14832, "Penguin (polar)" + "
" + " (after Hunt for Red Raktuber)", "You can now catch " + "" + "penguins" + "" + " with net traps (after Hunt for Red Raktuber)."); + case 4: + return newstruct cs2func_script_1006_struct(59, 10147, "Red salamander (lava)" + "
" + " Preferred bait: Tarromin tar", "You can now catch " + "" + "red salamanders" + "" + " with net traps."); + case 5: + return newstruct cs2func_script_1006_struct(67, 10148, "Black salamander (lava)" + "
" + " Preferred bait: Harralander tar", "You can now catch " + "" + "black salamanders" + "" + " with net traps."); + } + break; + case 7: + if (((boolean)arg1)) { + return newstruct cs2func_script_1006_struct(31, 10045, "Spined larupia (jungle)", "You can now catch " + "" + "spined larupias" + "" + " with pit traps."); + } + if (((boolean)arg1)) { + return newstruct cs2func_script_1006_struct(41, 10051, "Horned graahk (Karamja)", "You can now catch " + "" + "horned graahks" + "" + " with pit traps."); + } + if (arg1 == 2) { + return newstruct cs2func_script_1006_struct(55, 10039, "Sabre-toothed kyatt (polar)", "You can now catch " + "" + "sabre-toothed kyatts" + "" + " with pit traps."); + } + break; + case 8: + if (((boolean)arg1)) { + return newstruct cs2func_script_1006_struct(43, 9960, "Spotted kebbit (woodland)", "You can now hunt " + "" + "spotted kebbits" + "" + " with a falcon."); + } + if (((boolean)arg1)) { + return newstruct cs2func_script_1006_struct(57, 9963, "Dark kebbit (woodland)", "You can now hunt " + "" + "dark kebbits" + "" + " with a falcon."); + } + if (arg1 == 2) { + return newstruct cs2func_script_1006_struct(69, 9964, "Dashing kebbit (woodland)", "You can now hunt " + "" + "dashing kebbits" + "" + " with a falcon."); + } + break; + case 9: + if (((boolean)arg1)) { + return newstruct cs2func_script_1006_struct(71, 9952, "Imp (worldwide)" + "
" + " Preferred bait: Magical beads", "You can now catch " + "" + "imps" + "" + " in " + "" + "imp boxes" + "" + "."); + } + break; + case 10: + switch (arg1) { + case 0: + return newstruct cs2func_script_1006_struct(27, 9975, "White rabbit (woodland)" + "
" + " Use a ferret to flush the rabbit out of its hole" + "
" + " (after Eagles' Peak)", "You now have the Hunter level required to use a " + "" + "ferret" + "" + " to hunt " + "" + "white rabbits" + "" + " (after Eagles' Peak)."); + case 1: + return newstruct cs2func_script_1006_struct(27, 9974, "Giant eagle (various)" + "
" + " (after Eagles' Peak)", "You now have the Hunter level required to lasso " + "" + "giant eagles" + "" + " (after Eagles' Peak)."); + case 2: + return newstruct cs2func_script_1006_struct(72, 19808, "Charm sprites (south of the Tree Gnome Stronghold)" + "
" + " Use Hunter skill to catch charm sprites and gain Summoning charms", "You now have the Hunter level required to transmute " + "" + "charm sprites" + "" + " into Summoning charm slices."); + case 3: + return newstruct cs2func_script_1006_struct(91, 18778, "Starved ancient effigies", "You can now investigate " + "" + "starved ancient effigies" + "" + " using your knowledge of Hunter."); + case 4: + return newstruct cs2func_script_1006_struct(93, 18779, "Nourished ancient effigies", "You can now investigate " + "" + "nourished ancient effigies" + "" + " using your knowledge of Hunter."); + case 5: + return newstruct cs2func_script_1006_struct(95, 18780, "Sated ancient effigies", "You can now investigate " + "" + "sated ancient effigies" + "" + " using your knowledge of Hunter."); + case 6: + return newstruct cs2func_script_1006_struct(97, 18781, "Gorged ancient effigies", "You can now investigate " + "" + "gorged ancient effigies" + "" + " using your knowledge of Hunter."); + } + break; + case 11: + switch (arg1) { + case 0: + return newstruct cs2func_script_1006_struct(1, 10065, "Polar kebbit fur clothing (polar)", "You can now wear " + "" + "polar kebbit fur clothing" + "" + "."); + case 1: + return newstruct cs2func_script_1006_struct(1, 10053, "Common kebbit fur clothing (woodland)", "You can now wear " + "" + "common kebbit fur clothing" + "" + "."); + case 2: + return newstruct cs2func_script_1006_struct(4, 10057, "Feldip weasel fur clothing (jungle)", "You can now wear " + "" + "feldip weasel fur clothing" + "" + "."); + case 3: + return newstruct cs2func_script_1006_struct(10, 10061, "Desert devil fur clothing (desert)", "You can now wear " + "" + "desert devil fur clothing" + "" + "."); + case 4: + return newstruct cs2func_script_1006_struct(24, 10132, "Lucky rabbit's foot", "You can now wear a " + "" + "lucky rabbit's foot" + "" + "."); + case 5: + return newstruct cs2func_script_1006_struct(28, 10045, "Larupia fur clothing", "You can now wear " + "" + "larupia fur clothing" + "" + "."); + case 6: + return newstruct cs2func_script_1006_struct(38, 10051, "Graahk-hide clothing", "You can now wear " + "" + "graahk-hide clothing" + "" + "."); + case 7: + return newstruct cs2func_script_1006_struct(40, 10069, "Spotted capes", "You can now wear " + "" + "spotted capes" + "" + "."); + case 8: + return newstruct cs2func_script_1006_struct(52, 10039, "Kyatt fur clothing", "You can now wear " + "" + "kyatt fur clothing" + "" + "."); + case 9: + return newstruct cs2func_script_1006_struct(54, 10075, "Gloves of silence", "You can now wear " + "" + "gloves of silence" + "" + "."); + case 10: + return newstruct cs2func_script_1006_struct(66, 10071, "Spottier capes", "You can now wear " + "" + "spottier capes" + "" + "."); + case 11: + return newstruct cs2func_script_1006_struct(70, 20046, "Witchdoctor clothing", "You can now wear " + "" + "witchdoctor clothing" + "" + "."); + } + break; + case 12: + switch (arg1) { + case 0: + return newstruct cs2func_script_1006_struct(17, 11238, "Baby impling", "You can now catch " + "" + "baby implings" + "" + " barehanded."); + case 1: + return newstruct cs2func_script_1006_struct(22, 11240, "Young impling", "You can now catch " + "" + "young implings" + "" + " barehanded."); + case 2: + return newstruct cs2func_script_1006_struct(28, 11242, "Gourmet impling", "You can now catch " + "" + "gourmet implings" + "" + " barehanded."); + case 3: + return newstruct cs2func_script_1006_struct(36, 11244, "Earth impling", "You can now catch " + "" + "earth implings" + "" + " barehanded."); + case 4: + return newstruct cs2func_script_1006_struct(42, 11246, "Essence impling", "You can now catch " + "" + "essence implings" + "" + " barehanded."); + case 5: + return newstruct cs2func_script_1006_struct(50, 11248, "Eclectic impling", "You can now catch " + "" + "eclectic implings" + "" + " barehanded."); + case 6: + return newstruct cs2func_script_1006_struct(54, 15513, "Spirit impling", "You can now catch " + "" + "spirit implings" + "" + " barehanded."); + case 7: + return newstruct cs2func_script_1006_struct(58, 11250, "Nature impling", "You can now catch " + "" + "nature implings" + "" + " barehanded."); + case 8: + return newstruct cs2func_script_1006_struct(65, 11252, "Magpie impling", "You can now catch " + "" + "magpie implings" + "" + " barehanded."); + case 9: + return newstruct cs2func_script_1006_struct(74, 11254, "Ninja impling", "You can now catch " + "" + "ninja implings" + "" + " barehanded."); + case 10: + return newstruct cs2func_script_1006_struct(76, 13337, "Pirate impling" + "
" + " (after Rocking Out)", "You can now catch " + "" + "pirate implings" + "" + " barehanded (after Rocking Out)."); + case 11: + return newstruct cs2func_script_1006_struct(80, 9970, "Catch ruby harvest butterfly barehanded (woodland)" + "
" + " (with 75 Agility)", "You now have the Hunter level to catch " + "" + "ruby harvest butterflies" + "" + " barehanded. This feat will give you Hunter and Agility experience upon a successful catch. (You also need level 75 Agility.)"); + case 12: + return newstruct cs2func_script_1006_struct(83, 11256, "Dragon impling", "You can now catch " + "" + "dragon implings" + "" + " barehanded."); + case 13: + return newstruct cs2func_script_1006_struct(85, 9971, "Catch sapphire glacialis butterfly barehanded (polar)" + "
" + " (with 80 Agility)", "You now have the Hunter level to catch " + "" + "sapphire glacialis butterflies" + "" + " barehanded. This feat will give you Hunter and Agility experience upon a successful catch. (You also need level 80 Agility.)"); + case 14: + return newstruct cs2func_script_1006_struct(87, 15515, "Zombie impling", "You can now catch " + "" + "zombie implings" + "" + " barehanded."); + case 15: + return newstruct cs2func_script_1006_struct(90, 9972, "Catch snowy knight butterfly barehanded (polar)" + "
" + " (with 85 Agility)", "You now have the Hunter level to catch " + "" + "snowy knight butterflies" + "" + " barehanded. This feat will give you Hunter and Agility experience upon a successful catch. (You also need level 85 Agility.)"); + case 16: + return newstruct cs2func_script_1006_struct(91, 15517, "Kingly impling", "You can now catch " + "" + "kingly implings" + "" + " barehanded."); + case 17: + return newstruct cs2func_script_1006_struct(95, 9973, "Catch black warlock butterfly barehanded (jungle)" + "
" + " (with 90 Agility)", "You now have the Hunter level to catch " + "" + "black warlock butterflies" + "" + " barehanded. This feat will give you Hunter and Agility experience upon a successful catch. (You also need level 90 Agility.)"); + } + break; + case 13: + switch (arg1) { + case 0: + return newstruct cs2func_script_1006_struct(1, 14152, "Stealing Creation - class 1 butterfly net", "Members can now use " + "" + "class 1 butterfly nets" + "" + " in Stealing Creation."); + case 1: + return newstruct cs2func_script_1006_struct(20, 14184, "Stealing Creation - net class 2 sacred clay", "Members can now net " + "" + "class 2 sacred clay" + "" + " in Stealing Creation."); + case 2: + return newstruct cs2func_script_1006_struct(20, 14154, "Stealing Creation - class 2 butterfly net", "Members can now use " + "" + "class 2 butterfly nets" + "" + " in Stealing Creation."); + case 3: + return newstruct cs2func_script_1006_struct(40, 14186, "Stealing Creation - net class 3 sacred clay", "Members can now net " + "" + "class 3 sacred clay" + "" + " in Stealing Creation."); + case 4: + return newstruct cs2func_script_1006_struct(40, 14156, "Stealing Creation - class 3 butterfly net", "Members can now use " + "" + "class 3 butterfly nets" + "" + " in Stealing Creation."); + case 5: + return newstruct cs2func_script_1006_struct(60, 14188, "Stealing Creation - net class 4 sacred clay", "Members can now net " + "" + "class 4 sacred clay" + "" + " in Stealing Creation."); + case 6: + return newstruct cs2func_script_1006_struct(60, 14158, "Stealing Creation - class 4 butterfly net", "Members can now use " + "" + "class 4 butterfly nets" + "" + " in Stealing Creation."); + case 7: + return newstruct cs2func_script_1006_struct(80, 14190, "Stealing Creation - net class 5 sacred clay", "Members can now net " + "" + "class 5 sacred clay" + "" + " in Stealing Creation."); + case 8: + return newstruct cs2func_script_1006_struct(80, 14160, "Stealing Creation - class 5 butterfly net", "Members can now use " + "" + "class 5 butterfly nets" + "" + " in Stealing Creation."); + } + break; + case 14: + switch (arg1) { + case 0: + return newstruct cs2func_script_1006_struct(-1, 15707, "Dungeoneering skill tasks" + "
" + "As your Hunter level increases, you will be able to attempt higher-level hunter tasks within Daemonheim. You will also be more likely to succeed when attempting hunter tasks within Daemonheim.", ""); + case 1: + return newstruct cs2func_script_1006_struct(1, 17756, "Tangle gum trap (Tier 1)", "You can now place " + "" + "tangle gum traps" + "" + " within Daemonheim."); + case 2: + return newstruct cs2func_script_1006_struct(1, 17424, "Protomastyx hide (Tier 1)", "You can now gain " + "" + "protomastyx hides" + "" + " from protomastyx carcasses within Daemonheim."); + case 3: + return newstruct cs2func_script_1006_struct(10, 17758, "Seeping elm trap (Tier 2)", "You can now place " + "" + "seeping elm traps" + "" + " within Daemonheim."); + case 4: + return newstruct cs2func_script_1006_struct(10, 17426, "Submastyx hide (Tier 2)", "You can now gain " + "" + "submastyx hides" + "" + " from submastyx carcasses within Daemonheim."); + case 5: + return newstruct cs2func_script_1006_struct(20, 17760, "Blood spindle trap (Tier 3)", "You can now place " + "" + "blood spindle traps" + "" + " within Daemonheim."); + case 6: + return newstruct cs2func_script_1006_struct(20, 17428, "Paramastyx hide (Tier 3)", "You can now gain " + "" + "paramastyx hides" + "" + " from paramastyx carcasses within Daemonheim."); + case 7: + return newstruct cs2func_script_1006_struct(30, 17762, "Utuku trap (Tier 4)", "You can now place " + "" + "utuku traps" + "" + " within Daemonheim."); + case 8: + return newstruct cs2func_script_1006_struct(30, 17430, "Archaemastyx hide (Tier 4)", "You can now gain " + "" + "archaemastyx hides" + "" + " from archaemastyx carcasses within Daemonheim."); + case 9: + return newstruct cs2func_script_1006_struct(40, 17764, "Spinebeam trap (Tier 5)", "You can now place " + "" + "spinebeam traps" + "" + " within Daemonheim."); + case 10: + return newstruct cs2func_script_1006_struct(40, 17432, "Dromomastyx hide (Tier 5)", "You can now gain " + "" + "dromomastyx hides" + "" + " from dromomastyx carcasses within Daemonheim."); + case 11: + return newstruct cs2func_script_1006_struct(50, 17766, "Bovistrangler trap (Tier 6)", "You can now place " + "" + "bovistrangler traps" + "" + " within Daemonheim."); + case 12: + return newstruct cs2func_script_1006_struct(50, 17434, "Spinomastyx hide (Tier 6)", "You can now gain " + "" + "spinomastyx hides" + "" + " from spinomastyx carcasses within Daemonheim."); + case 13: + return newstruct cs2func_script_1006_struct(60, 17768, "Thigat trap (Tier 7)", "You can now place " + "" + "thigat traps" + "" + " within Daemonheim."); + case 14: + return newstruct cs2func_script_1006_struct(60, 17436, "Gallimastyx hide (Tier 7)", "You can now gain " + "" + "gallimastyx hides" + "" + " from gallimastyx carcasses within Daemonheim."); + case 15: + return newstruct cs2func_script_1006_struct(70, 17770, "Corpsethorn trap (Tier 8)", "You can now place " + "" + "corpsethorn traps" + "" + " within Daemonheim."); + case 16: + return newstruct cs2func_script_1006_struct(70, 17438, "Stegomastyx hide (Tier 8)", "You can now gain " + "" + "stegomastyx hides" + "" + " from stegomastyx carcasses within Daemonheim."); + case 17: + return newstruct cs2func_script_1006_struct(80, 17772, "Entgallow trap (Tier 9)", "You can now place " + "" + "entgallow traps" + "" + " within Daemonheim."); + case 18: + return newstruct cs2func_script_1006_struct(80, 17440, "Megamastyx hide (Tier 9)", "You can now gain " + "" + "megamastyx hides" + "" + " from megamastyx carcasses within Daemonheim."); + case 19: + return newstruct cs2func_script_1006_struct(90, 17774, "Grave creeper trap (Tier 10)", "You can now place " + "" + "grave creeper traps" + "" + " within Daemonheim."); + case 20: + return newstruct cs2func_script_1006_struct(90, 17442, "Tyrannomastyx hide (Tier 10)", "You can now gain " + "" + "tyrannomastyx hides" + "" + " from tyrannomastyx carcasses within Daemonheim."); + } + break; + case 15: + if (((boolean)arg1)) { + return newstruct cs2func_script_1006_struct(99, 9948, "Skill mastery", "" + "Congratulations! You are now a master " + "" + "Hunter" + "" + ". Why not visit the " + "" + "Hunter Expert" + "" + ", south of the " + "" + "Feldip Hills" + "" + "? She has something special that is only available to true masters of the " + "" + "Hunter" + "" + " skill!"); + } + } + return newstruct cs2func_script_1006_struct(0, -1, "", ""); +} diff --git a/dumps/scripts/1007.cs2 b/dumps/scripts/1007.cs2 new file mode 100644 index 0000000..3406f73 --- /dev/null +++ b/dumps/scripts/1007.cs2 @@ -0,0 +1,25 @@ +cs2func_script_1007_struct(1,1,0) script_1007(int arg0) { + switch (arg0) { + case 0: + return newstruct cs2func_script_1007_struct(1, "Courses"); + case 1: + return newstruct cs2func_script_1007_struct(1, "Areas"); + case 2: + return newstruct cs2func_script_1007_struct(1, "Shortcuts"); + case 3: + return newstruct cs2func_script_1007_struct(1, "Barbarian"); + case 4: + return newstruct cs2func_script_1007_struct(1, "Multiple Catch"); + case 5: + return newstruct cs2func_script_1007_struct(1, "Multiple Pickpocket"); + case 6: + return newstruct cs2func_script_1007_struct(1, "Barehanded"); + case 7: + return newstruct cs2func_script_1007_struct(1, "Other"); + case 8: + return newstruct cs2func_script_1007_struct(1, "Dungeoneering"); + case 9: + return newstruct cs2func_script_1007_struct(1, "Milestones"); + } + return newstruct cs2func_script_1007_struct(-1, ""); +} diff --git a/dumps/scripts/1008.cs2 b/dumps/scripts/1008.cs2 new file mode 100644 index 0000000..3efe38b --- /dev/null +++ b/dumps/scripts/1008.cs2 @@ -0,0 +1,342 @@ +cs2func_script_1008_struct(2,2,0) script_1008(int arg0,int arg1) { + switch (arg0) { + case 0: + switch (arg1) { + case 0: + return newstruct cs2func_script_1008_struct(1, 2150, "Gnome Stronghold Agility Course", "You can now use the " + "" + "Gnome Stronghold Agility Course" + "" + "."); + case 1: + return newstruct cs2func_script_1008_struct(1, 751, "Gnome Ball", "You can now play " + "" + "Gnome Ball" + "" + " at the " + "" + "Tree Gnome Stronghold" + "" + "."); + case 2: + return newstruct cs2func_script_1008_struct(1, 2996, "Low-level Agility arena obstacles", "You can now attempt " + "" + "low-level Agility arena obstacles" + "" + "."); + case 3: + return newstruct cs2func_script_1008_struct(20, 2996, "Medium-level Agility arena obstacles", "You can now attempt " + "" + "medium-level Agility arena obstacles" + "" + "."); + case 4: + return newstruct cs2func_script_1008_struct(25, 1061, "Werewolf skullball game" + "
" + " (after Creature of Fenkenstrain)", "You can now play " + "" + "werewolf skullball" + "" + " at the " + "" + "skullball course" + "" + " east of " + "" + "Canifis" + "" + " (after Creature of Fenkenstrain)."); + case 5: + return newstruct cs2func_script_1008_struct(30, 6970, "Agility Pyramid", "You can now enter the " + "" + "Agility Pyramid" + "" + "."); + case 6: + return newstruct cs2func_script_1008_struct(30, 10595, "Penguin Agility Course" + "
" + " (after starting Cold War)", "You can now use the " + "" + "Penguin Agility Course" + "" + " (after starting Cold War)."); + case 7: + return newstruct cs2func_script_1008_struct(35, 1365, "Barbarian Outpost Agility Course", "You can now use the " + "" + "Barbarian Outpost Agility Course" + "" + "."); + case 8: + return newstruct cs2func_script_1008_struct(40, 2996, "High-level Agility arena obstacles", "You can now attempt" + "" + " high-level Agility arena obstacles" + "" + "."); + case 9: + return newstruct cs2func_script_1008_struct(48, 4024, "Ape Atoll Agility Course" + "
" + " (after Monkey Madness)", "You can now use the " + "" + "Ape Atoll Agility Course" + "" + " (after Monkey Madness)."); + case 10: + return newstruct cs2func_script_1008_struct(52, 964, "Wilderness Agility Course", "You can now use the " + "" + "Wilderness Agility Course" + "" + "."); + case 11: + return newstruct cs2func_script_1008_struct(60, 4179, "Werewolf Agility Course" + "
" + " (after Creature of Fenkenstrain)", "You can now use the " + "" + "Werewolf Agility Course" + "" + " (after Creature of Fenkenstrain)."); + case 12: + return newstruct cs2func_script_1008_struct(60, 14683, "Statues in Bandos's Throne Room" + "
" + " (after The Chosen Commander)", "You can now use the " + "" + "statues in Bandos's throne room" + "" + " (after The Chosen Commander)."); + case 13: + return newstruct cs2func_script_1008_struct(80, 4550, "Dorgesh-Kaan Agility Course" + "
" + " (after Death to the Dorgeshuun)", "You can now use the " + "" + "Dorgesh-Kaan Agility Course" + "" + " (after Death to the Dorgeshuun)."); + case 14: + return newstruct cs2func_script_1008_struct(85, 2150, "Advanced Gnome Stronghold Course", "You can now use the " + "" + "Advanced Gnome Stronghold Course" + "" + "."); + case 15: + return newstruct cs2func_script_1008_struct(90, 1365, "Advanced Barbarian Outpost Course", "You can now use the " + "" + "Advanced Barbarian Outpost Course" + "" + "."); + } + break; + case 1: + switch (arg1) { + case 0: + return newstruct cs2func_script_1008_struct(10, 6518, "Moss Giant Island rope swing", "You can now use the " + "" + "Moss Giant Island rope-swing" + "" + "."); + case 1: + return newstruct cs2func_script_1008_struct(12, 6518, "Karamja Dungeon stepping stones", "You can now cross the " + "" + "Karamja Dungeon stepping stones" + "" + "."); + case 2: + return newstruct cs2func_script_1008_struct(15, 6518, "Edgeville Dungeon monkey bars", "You can now use the " + "" + "Edgeville Dungeon monkey bars" + "" + "."); + case 3: + return newstruct cs2func_script_1008_struct(18, 6521, "Watchtower wall climb", "You can now use the " + "" + "Watchtower wall climb" + "" + "."); + case 4: + return newstruct cs2func_script_1008_struct(22, 6520, "Karamja Dungeon pipe contortion", "You can now squeeze through the " + "" + "Karamja Dungeon pipe contortion" + "" + "."); + case 5: + return newstruct cs2func_script_1008_struct(30, 6518, "South-east Karamja stepping stones", "You can now cross the " + "" + "south-east Karamja stepping stones" + "" + "."); + case 6: + return newstruct cs2func_script_1008_struct(34, 6520, "Karamja Dungeon pipe contortion", "You can now squeeze through the " + "" + "Karamja Dungeon pipe contortion" + "" + "."); + case 7: + return newstruct cs2func_script_1008_struct(45, 6519, "Isafdar log balance", "You can now cross the " + "" + "Isafdar log balance" + "" + "."); + case 8: + return newstruct cs2func_script_1008_struct(49, 6520, "Yanille Dungeon contortion", "You can now squeeze through the " + "" + "Yanille Dungeon contortion" + "" + "."); + case 9: + return newstruct cs2func_script_1008_struct(50, 6518, "Rogues' Den" + "
" + " (with 50 Thieving)", "You now have the Agility level required to attempt the " + "" + "Rogues' Den" + "" + ", located below the Toad and Chicken pub in Burthorpe. (You also need level 50 Thieving.)"); + case 10: + return newstruct cs2func_script_1008_struct(60, 6520, "God Wars Dungeon access", "You can now use the " + "" + "God Wars Dungeon access" + "" + "."); + case 11: + return newstruct cs2func_script_1008_struct(67, 6521, "Yanille Dungeon rubble climb", "You can now attempt the " + "" + "Yanille Dungeon rubble climb" + "" + "."); + case 12: + return newstruct cs2func_script_1008_struct(70, 6521, "Saradomin Encampment rope descent", "You can now use the " + "" + "Saradomin Encampment rope descent" + "" + " in the " + "" + "God Wars Dungeon" + "" + "."); + } + break; + case 2: + switch (arg1) { + case 0: + return newstruct cs2func_script_1008_struct(5, 6517, "Falador Agility shortcut", "You can now use the Falador Agility shortcut" + "" + "."); + case 1: + return newstruct cs2func_script_1008_struct(8, 6515, "River crossing to Al Kharid" + "
" + " (with 37 Ranged and 19 Strength)", "You now have the Agility level required to use the " + "" + "river crossing to Al Kharid" + "" + ". (You also need level 37 Ranged and level 19 Strength.)"); + case 2: + return newstruct cs2func_script_1008_struct(11, 6517, "Falador wall" + "
" + " (with 19 Ranged and 37 Strength)", "You now have the Agility level required to scale " + "" + "Falador wall" + "" + ". (You also need level 19 Ranged and level 37 Strength.)"); + case 3: + return newstruct cs2func_script_1008_struct(13, 6514, "Varrock south fence jump", "You can now use the " + "" + "Varrock south fence jump" + "" + "."); + case 4: + return newstruct cs2func_script_1008_struct(16, 6516, "Yanille Agility shortcut", "You can now use the " + "" + "Yanille Agility shortcut" + "" + "."); + case 5: + return newstruct cs2func_script_1008_struct(20, 6515, "Coal truck log balance", "You can now use the " + "" + "coal truck log balance" + "" + "."); + case 6: + return newstruct cs2func_script_1008_struct(21, 6516, "Varrock Agility shortcut", "You can now use the " + "" + "Varrock Agility shortcut" + "" + "."); + case 7: + return newstruct cs2func_script_1008_struct(25, 6517, "Eagles' Peak Agility shortcut", "You can now use the " + "" + "Eagles' Peak Agility shortcut" + "" + "."); + case 8: + return newstruct cs2func_script_1008_struct(26, 6516, "Falador wall crawl", "You can now use the " + "" + "Falador Agility shortcut" + "" + "."); + case 9: + return newstruct cs2func_script_1008_struct(28, 6516, "Draynor Manor broken railing", "You can now fit through the " + "" + "Draynor Manor broken railing" + "" + "."); + case 10: + return newstruct cs2func_script_1008_struct(29, 6516, "Oo'glog Agility shortcut", "You can now use the " + "" + "Oo'glog Agility shortcut" + "" + "."); + case 11: + return newstruct cs2func_script_1008_struct(31, 6515, "Draynor Manor stones to the Champions' Guild", "You can now use the " + "" + "Draynor Manor stones to the Champions' Guild" + "" + "."); + case 12: + return newstruct cs2func_script_1008_struct(32, 6517, "Catherby cliff" + "
" + " (after Fishing Contest, with 35 Strength and 35 Ranged)", "You now have the Agility level required to scale the " + "" + "Catherby cliff" + "" + ". (You must have completed Fishing Contest and have level 35 Strength and level 35 Ranged.)"); + case 13: + return newstruct cs2func_script_1008_struct(33, 6515, "Ardougne log balance shortcut", "You can now use the " + "" + "Ardougne log balance shortcut" + "" + "."); + case 14: + return newstruct cs2func_script_1008_struct(36, 6517, "Water Obelisk Island escape" + "
" + " (with 39 Ranged and 22 Strength)", "You now have the Agility level required to use the " + "" + "Water Obelisk Island escape" + "" + ". (You also need level 39 Ranged and level 22 Strength.)"); + case 15: + return newstruct cs2func_script_1008_struct(37, 6517, "Gnome Stronghold shortcut", "You can now use the " + "" + "Gnome Stronghold shortcut" + "" + "."); + case 16: + return newstruct cs2func_script_1008_struct(38, 6517, "Al Kharid mining pit cliffside scramble", "You can now manage the " + "" + "Al Kharid mining pit cliffside scramble" + "" + "."); + case 17: + return newstruct cs2func_script_1008_struct(39, 6517, "Yanille wall" + "
" + " (with 21 Ranged and 38 Strength)", "You now have the Agility level required to scale " + "" + "Yanille wall" + "" + ". (You also need level 21 Ranged and level 38 Strength.)"); + case 18: + return newstruct cs2func_script_1008_struct(40, 6517, "Rope climb south-east of the Agility Pyramid", "You can now use the " + "" + "rope climb south-east of the Agility Pyramid" + "" + "."); + case 19: + return newstruct cs2func_script_1008_struct(41, 6517, "Trollheim easy cliffside scramble", "You can now manage the " + "" + "Trollheim easy cliffside scramble" + "" + "."); + case 20: + return newstruct cs2func_script_1008_struct(42, 6516, "Dwarven Mine narrow crevice", "You can now manage the " + "" + "Dwarven Mine narrow crevice" + "" + "."); + case 21: + return newstruct cs2func_script_1008_struct(43, 6517, "Trollheim medium cliffside scramble", "You can now manage the " + "" + "Trollheim medium cliffside scramble" + "" + "."); + case 22: + return newstruct cs2func_script_1008_struct(44, 6517, "Trollheim advanced cliffside scramble", "You can now manage the " + "" + "Trollheim advanced cliffside scramble" + "" + "."); + case 23: + return newstruct cs2func_script_1008_struct(46, 6516, "Cosmic Temple medium narrow walkway", "You can now use the " + "" + "Cosmic Temple medium narrow walkway" + "" + "."); + case 24: + return newstruct cs2func_script_1008_struct(47, 6517, "Trollheim hard cliffside scramble", "You can now manage the " + "" + "Trollheim hard cliffside scramble" + "" + "."); + case 25: + return newstruct cs2func_script_1008_struct(48, 6515, "Log balance to the Fremennik Province", "You can now use the " + "" + "log balance to the Fremennik Province" + "" + "."); + case 26: + return newstruct cs2func_script_1008_struct(51, 6516, "Edgeville Dungeon to Varrock Sewers pipe", "You can now use the " + "" + "Edgeville Dungeon to Varrock Sewers pipe" + "" + "."); + case 27: + return newstruct cs2func_script_1008_struct(53, 6517, "Karamja crossing, south of the volcano" + "
" + " (with 42 Ranged and 21 Strength)", "You now have the Agility level required to manage the " + "" + "Karamja crossing, south of the volcano" + "" + ". (You also need level 42 Ranged and level 21 Strength)."); + case 28: + return newstruct cs2func_script_1008_struct(58, 6517, "Port Phasmatys ectopool shortcut", "You can now use the " + "" + "Port Phasmatys ectopool shortcut" + "" + "."); + case 29: + return newstruct cs2func_script_1008_struct(59, 6517, "Elven overpass easy cliffside scramble", "You can now manage the " + "" + "Elven Overpass easy cliffside scramble" + "" + "."); + case 30: + return newstruct cs2func_script_1008_struct(60, 6517, "God Wars temple escape to the Wilderness", "You can now manage the " + "" + "God Wars temple escape to the Wilderness" + "" + "."); + case 31: + return newstruct cs2func_script_1008_struct(61, 6517, "Slayer Tower medium spiked chain climb", "You can now manage the " + "" + "Slayer Tower medium spiked chain climb" + "" + "."); + case 32: + return newstruct cs2func_script_1008_struct(62, 6516, "Slayer Dungeon narrow crevice", "You can now manage the " + "" + "Slayer Dungeon narrow crevice" + "" + "."); + case 33: + return newstruct cs2func_script_1008_struct(64, 6517, "Trollheim Wilderness route", "You can now use the " + "" + "Trollheim Wilderness route" + "" + "."); + case 34: + return newstruct cs2func_script_1008_struct(65, 6517, "Paterdomus Temple to Morytania shortcut", "You can now use the " + "" + "Paterdomus Temple to Morytania shortcut" + "" + "."); + case 35: + return newstruct cs2func_script_1008_struct(66, 6516, "Cosmic Temple advanced narrow walkway", "You can now use the " + "" + "Cosmic Temple advanced narrow walkway" + "" + "."); + case 36: + return newstruct cs2func_script_1008_struct(68, 6517, "Elven overpass medium cliffside scramble", "You can now manage the " + "" + "elven overpass medium cliffside scramble" + "" + "."); + case 37: + return newstruct cs2func_script_1008_struct(70, 6516, "Taverley Dungeon pipe squeeze", "You can now use the " + "" + "Taverley Dungeon pipe squeeze" + "" + " to the blue dragons."); + case 38: + return newstruct cs2func_script_1008_struct(71, 6517, "Slayer Tower advanced spiked chain climb", "You can now manage the " + "" + "Slayer Tower advanced spiked chain climb" + "" + "."); + case 39: + return newstruct cs2func_script_1008_struct(74, 6514, "Shilo Village stepping stone", "You can now use the " + "" + "Shilo Village stepping stone" + "" + "."); + case 40: + return newstruct cs2func_script_1008_struct(80, 6515, "Cross cave, south of Dorgesh-Kaan " + "
" + " (with 80 Ranged and 80 Strength)", "You now have the Agility level required to cross the " + "" + "cave south of Dorgesh-Kaan" + "" + ". (You also need level 80 Ranged and 80 Strength."); + case 41: + return newstruct cs2func_script_1008_struct(80, 6514, "Taverley Dungeon spiked blade jump", "You can now manage the " + "" + "Taverley Dungeon spiked blade jump" + "" + "."); + case 42: + return newstruct cs2func_script_1008_struct(81, 6514, "Slayer Dungeon chasm jump", "You can now manage the " + "" + "Slayer Dungeon chasm jump" + "" + "."); + case 43: + return newstruct cs2func_script_1008_struct(85, 6517, "Elven overpass advanced cliffside scramble", "You can now manage the " + "" + "elven Overpass advanced cliffside scramble" + "" + "."); + case 44: + return newstruct cs2func_script_1008_struct(86, 6517, "Kuradal's Dungeon wall climb", "You can now manage the " + "" + "wall climb in Kuradal's Slayer Dungeon" + "" + "."); + case 45: + return newstruct cs2func_script_1008_struct(90, 6514, "Kuradal's Dungeon wall run", "You can now manage the " + "" + "wall run in Kuradal's Slayer Dungeon" + "" + "."); + } + break; + case 3: + switch (arg1) { + case 0: + return newstruct cs2func_script_1008_struct(-1, 7620, "To start Fishing like a barbarian, talk to Otto Godblessed when you have at least level 48 Fishing and level 15 Strength.", ""); + case 1: + return newstruct cs2func_script_1008_struct(15, 11323, "Heavy rod" + "
" + " (with 48 Fishing and 15 Strength)", "You now have the Agility level required to fish with a " + "" + "heavy rod" + "" + ". (You also need level 48 Fishing and level 15 Strength.)"); + case 2: + return newstruct cs2func_script_1008_struct(15, 11328, "Leaping trout" + "
" + " (with 48 Fishing and 15 Strength)", "You now have the Agility level required to catch " + "" + "leaping trout" + "" + ". (You also need level 48 Fishing and level 15 Strength.)"); + case 3: + return newstruct cs2func_script_1008_struct(30, 11330, "Leaping salmon" + "
" + " (with 58 Fishing and 30 Strength)", "You now have the Agility level required to catch " + "" + "leaping salmon" + "" + ". (You also need level 58 Fishing and level 30 Strength.)"); + case 4: + return newstruct cs2func_script_1008_struct(45, 11332, "Leaping sturgeon" + "
" + " (with 70 Fishing and 45 Strength)", "You now have the Agility level required to catch " + "" + "leaping sturgeon" + "" + ". (You also need level 70 Fishing and level 45 Strength.)"); + } + break; + case 4: + switch (arg1) { + case 0: + return newstruct cs2func_script_1008_struct(35, 359, "Possibility of catching two tuna in one fishing attempt" + "
" + " (with 35 Fishing)", "You now have the Agility level required to potentially catch two " + "" + "tuna" + "" + " in one fishing attempt. (You also need level 35 Fishing.)"); + case 1: + return newstruct cs2func_script_1008_struct(50, 371, "Possibility of catching two swordfish in one fishing attempt" + "
" + " (with 50 Fishing)", "You now have the Agility level required to potentially catch two " + "" + "swordfish" + "" + " in one fishing attempt. (You also need level 50 Fishing.)"); + case 2: + return newstruct cs2func_script_1008_struct(76, 383, "Possibility of catching two sharks in one fishing attempt" + "
" + " (with 76 Fishing)", "You now have the Agility level required to potentially catch two " + "" + "sharks" + "" + " in one fishing attempt. (You also need level 76 Fishing.)"); + } + break; + case 5: + switch (arg1) { + case 0: + return newstruct cs2func_script_1008_struct(1, 3241, "Possibility of stealing double loot from a man" + "
" + " (with 11 Thieving)", "You now have the Agility level required to potentially steal double loot from " + "" + "men" + "" + " and " + "" + "women" + "" + ". (You also need level 11 Thieving.)"); + case 1: + return newstruct cs2func_script_1008_struct(10, 3243, "Possibility of stealing double loot from a farmer" + "
" + " (with 20 Thieving)", "You now have the Agility level required to potentially steal double loot from " + "" + "farmers" + "" + ". (You also need level 20 Thieving.)"); + case 2: + return newstruct cs2func_script_1008_struct(11, 3241, "Possibility of stealing triple loot from a man" + "
" + " (with 21 Thieving)", "You now have the Agility level required to potentially steal triple loot from " + "" + "men" + "" + " and " + "" + "women" + "" + ". (You also need level 21 Thieving.)"); + case 3: + return newstruct cs2func_script_1008_struct(15, 4295, "Possibility of stealing double loot from a female H.A.M.follower" + "
" + " (with 25 Thieving)", "You now have the Agility level required to potentially steal double loot from " + "" + "female H.A.M. followers" + "" + ". (You also need level 25 Thieving.)"); + case 4: + return newstruct cs2func_script_1008_struct(20, 3243, "Possibility of stealing triple loot from a farmer" + "
" + " (with 30 Thieving)", "You now have the Agility level required to potentially steal triple loot from " + "" + "farmers" + "" + ". (You also need level 30 Thieving.)"); + case 5: + return newstruct cs2func_script_1008_struct(20, 4297, "Possibility of stealing double loot from a male H.A.M. follower" + "
" + " (with 30 Thieving)", "You now have the Agility level required to potentially steal double loot from " + "" + "male H.A.M. followers" + "" + ". (You also need level 30 Thieving.)"); + case 6: + return newstruct cs2func_script_1008_struct(21, 3241, "Possibility of stealing quadruple loot from a man" + "
" + " (with 31 Thieving)", "You now have the Agility level required to potentially steal quadruple loot from " + "" + "men" + "" + " and " + "" + "women" + "" + ". (You also need level 31 Thieving.)"); + case 7: + return newstruct cs2func_script_1008_struct(25, 4295, "Possibility of stealing triple loot from a female H.A.M.follower" + "
" + " (with 35 Thieving)", "You now have the Agility level required to potentially steal triple loot from " + "" + "female H.A.M. followers" + "" + ". (You also need level 35 Thieving.)"); + case 8: + return newstruct cs2func_script_1008_struct(25, 3245, "Possibility of stealing double loot from a warrior" + "
" + " (with 35 Thieving)", "You now have the Agility level required to potentially steal double loot from " + "" + "warriors" + "" + ". (You also need level 35 Thieving.)"); + case 9: + return newstruct cs2func_script_1008_struct(30, 3243, "Possibility of stealing quadruple loot from a farmer" + "
" + " (with 40 Thieving)", "You now have the Agility level required to potentially steal quadruple loot from " + "" + "farmers" + "" + ". (You also need level 40 Thieving.)"); + case 10: + return newstruct cs2func_script_1008_struct(30, 4297, "Possibility of stealing triple loot from a male H.A.M. follower" + "
" + " (with 40 Thieving)", "You now have the Agility level required to potentially steal triple loot from " + "" + "male H.A.M. followers" + "" + ". (You also need level 40 Thieving.)"); + case 11: + return newstruct cs2func_script_1008_struct(32, 3247, "Possibility of stealing double loot from a rogue" + "
" + " (with 42 Thieving)", "You now have the Agility level required to potentially steal double loot from " + "" + "rogues" + "" + ". (You also need level 42 Thieving.)"); + case 12: + return newstruct cs2func_script_1008_struct(35, 4295, "Possibility of stealing quadruple loot from a female H.A.M. follower" + "
" + " (with 45 Thieving)", "You now have the Agility level required to potentially steal quadruple loot from " + "" + "female H.A.M. followers" + "" + ". (You also need level 45 Thieving.)"); + case 13: + return newstruct cs2func_script_1008_struct(35, 3245, "Possibility of stealing triple loot from a warrior" + "
" + " (with 45 Thieving)", "You now have the Agility level required to potentially steal triple loot from " + "" + "warriors" + "" + ". (You also need level 45 Thieving.)"); + case 14: + return newstruct cs2func_script_1008_struct(36, 10998, "Possibility of stealing double loot from a cave goblin" + "
" + " (with 46 Thieving)", "You now have the Agility level required to potentially steal double loot from " + "" + "cave goblins" + "" + ". (You also need level 46 Thieving.)"); + case 15: + return newstruct cs2func_script_1008_struct(38, 5068, "Possibility of stealing double loot from a master farmer" + "
" + " (with 48 Thieving)", "You now have the Agility level required to potentially steal double loot from " + "" + "master farmers" + "" + ". (You also need level 48 Thieving.)"); + case 16: + return newstruct cs2func_script_1008_struct(40, 4297, "Possibility of stealing quadruple loot from a male H.A.M. follower" + "
" + " (with 50 Thieving)", "You now have the Agility level required to potentially steal quadruple loot from " + "" + "male H.A.M. followers" + "" + ". (You also need level 50 Thieving.)"); + case 17: + return newstruct cs2func_script_1008_struct(40, 3249, "Possibility of stealing double loot from a guard" + "
" + " (with 50 Thieving)", "You now have the Agility level required to potentially steal double loot from " + "" + "guards" + "" + ". (You also need level 50 Thieving.)"); + case 18: + return newstruct cs2func_script_1008_struct(42, 3247, "Possibility of stealing triple loot from a rogue" + "
" + " (with 52 Thieving)", "You now have the Agility level required to potentially steal triple loot from " + "" + "rogues" + "" + ". (You also need level 52 Thieving.)"); + case 19: + return newstruct cs2func_script_1008_struct(45, 3245, "Possibility of stealing quadruple loot from a warrior" + "
" + " (with 55 Thieving)", "You now have the Agility level required to potentially steal quadruple loot from " + "" + "warriors" + "" + ". (You also need level 55 Thieving.)"); + case 20: + return newstruct cs2func_script_1008_struct(45, 3686, "Possibility of stealing double loot from a Fremennik citizen" + "
" + " (with 55 Thieving)", "You now have the Agility level required to potentially steal double loot from " + "" + "Fremennik citizens" + "" + ". (You also need level 55 Thieving.)"); + case 21: + return newstruct cs2func_script_1008_struct(45, 6782, "Possibility of stealing double loot from a bearded Pollnivnian bandit" + "
" + " (with 55 Thieving)", "You now have the Agility level required to potentially steal double loot from " + "" + "bearded Pollnivnian bandits" + "" + ". (You also need level 55 Thieving.)"); + case 22: + return newstruct cs2func_script_1008_struct(46, 10998, "Possibility of stealing triple loot from a cave goblin" + "
" + " (with 56 Thieving)", "You now have the Agility level required to potentially steal triple loot from " + "" + "cave goblins" + "" + ". (You also need level 56 Thieving.)"); + case 23: + return newstruct cs2func_script_1008_struct(48, 5068, "Possibility of stealing triple loot from a master farmer" + "
" + " (with 58 Thieving)", "You now have the Agility level required to potentially steal triple loot from " + "" + "master farmers" + "" + ". (You also need level 58 Thieving.)"); + case 24: + return newstruct cs2func_script_1008_struct(50, 3249, "Possibility of stealing triple loot from a guard" + "
" + " (with 60 Thieving)", "You now have the Agility level required to potentially steal triple loot from " + "" + "guards" + "" + ". (You also need level 60 Thieving.)"); + case 25: + return newstruct cs2func_script_1008_struct(52, 3247, "Possibility of stealing quadruple loot from a rogue" + "
" + " (with 62 Thieving)", "You now have the Agility level required to potentially steal quadruple loot from " + "" + "rogues" + "" + ". (You also need level 62 Thieving.)"); + case 26: + return newstruct cs2func_script_1008_struct(53, 4625, "Possibility of stealing double loot from a desert bandit" + "
" + " (with 63 Thieving)", "You now have the Agility level required to potentially steal double loot from " + "" + "desert bandits" + "" + ". (You also need level 63 Thieving.)"); + case 27: + return newstruct cs2func_script_1008_struct(55, 3686, "Possibility of stealing triple loot from a Fremennik citizen" + "
" + " (with 65 Thieving)", "You now have the Agility level required to potentially steal triple loot from " + "" + "Fremennik citizens" + "" + ". (You also need level 65 Thieving.)"); + case 28: + return newstruct cs2func_script_1008_struct(55, 6782, "Possibility of stealing triple loot from a Bearded Pollnivnian bandit" + "
" + " (with 65 Thieving)", "You now have the Agility level required to potentially steal triple loot from " + "" + "bearded Pollnivnian bandits" + "" + ". (You also need level 65 Thieving.)"); + case 29: + return newstruct cs2func_script_1008_struct(55, 3251, "Possibility of stealing double loot from a knight" + "
" + " (with 65 Thieving)", "You now have the Agility level required to potentially steal double loot from " + "" + "knights" + "" + ". (You also need level 65 Thieving.)"); + case 30: + return newstruct cs2func_script_1008_struct(55, 6781, "Possibility of stealing double loot from a Pollnivnian bandit" + "
" + " (with 65 Thieving)", "You now have the Agility level required to potentially steal double loot from " + "" + "Pollnivnian bandits" + "" + ". (You also need level 65 Thieving.)"); + case 31: + return newstruct cs2func_script_1008_struct(56, 10998, "Possibility of stealing quadruple loot from a cave goblin" + "
" + " (with 66 Thieving)", "You now have the Agility level required to potentially steal quadruple loot from " + "" + "cave goblins" + "" + ". (You also need level 66 Thieving.)"); + case 32: + return newstruct cs2func_script_1008_struct(58, 5068, "Possibility of stealing quadruple loot from a master farmer" + "
" + " (with 68 Thieving)", "You now have the Agility level required to potentially steal quadruple loot from " + "" + "master farmers" + "" + ". (You also need level 68 Thieving.)"); + case 33: + return newstruct cs2func_script_1008_struct(60, 3249, "Possibility of stealing quadruple loot from a guard" + "
" + " (with 70 Thieving)", "You now have the Agility level required to potentially steal quadruple loot from " + "" + "guards" + "" + ". (You also need level 70 Thieving.)"); + case 34: + return newstruct cs2func_script_1008_struct(63, 4625, "Possibility of stealing triple loot from a desert bandit" + "
" + " (with 73 Thieving)", "You now have the Agility level required to potentially steal triple loot from " + "" + "desert bandits" + "" + ". (You also need level 73 Thieving.)"); + case 35: + return newstruct cs2func_script_1008_struct(65, 3686, "Possibility of stealing quadruple loot from a Fremennik citizen" + "
" + " (with 75 Thieving)", "You now have the Agility level required to potentially steal quadruple loot from " + "" + "Fremennik citizens" + "" + ". (You also need level 75 Thieving.)"); + case 36: + return newstruct cs2func_script_1008_struct(65, 6782, "Possibility of stealing quadruple loot from a bearded Pollnivnian bandit" + "
" + " (with 75 Thieving)", "You now have the Agility level required to potentially steal quadruple loot from " + "" + "bearded Pollnivnian bandits" + "" + ". (You also need level 75 Thieving.)"); + case 37: + return newstruct cs2func_script_1008_struct(65, 3251, "Possibility of stealing triple loot from a knight" + "
" + " (with 75 Thieving)", "You now have the Agility level required to potentially steal triple loot from " + "" + "knights" + "" + ". (You also need level 75 Thieving.)"); + case 38: + return newstruct cs2func_script_1008_struct(65, 6781, "Possibility of stealing triple loot from a Pollnivnian bandit" + "
" + " (with 75 Thieving)", "You now have the Agility level required to potentially steal triple loot from " + "" + "Pollnivnian bandits" + "" + ". (You also need level 75 Thieving.)"); + case 39: + return newstruct cs2func_script_1008_struct(65, 3253, "Possibility of stealing double loot from a watchman" + "
" + " (with 75 Thieving)", "You now have the Agility level required to potentially steal double loot from " + "" + "watchmen" + "" + ". (You also need level 75 Thieving.)"); + case 40: + return newstruct cs2func_script_1008_struct(65, 6780, "Possibility of stealing double loot from a Menaphite thug" + "
" + " (with 75 Thieving)", "You now have the Agility level required to potentially steal double loot from " + "" + "Menaphite thugs" + "" + ". (You also need level 75 Thieving.)"); + case 41: + return newstruct cs2func_script_1008_struct(70, 3255, "Possibility of stealing double loot from a paladin" + "
" + " (with 80 Thieving)", "You now have the Agility level required to potentially steal double loot from " + "" + "paladins" + "" + ". (You also need level 80 Thieving.)"); + case 42: + return newstruct cs2func_script_1008_struct(73, 4625, "Possibility of stealing quadruple loot from a desert bandit" + "
" + " (with 83 Thieving)", "You now have the Agility level required to potentially steal quadruple loot from " + "" + "desert bandits" + "" + ". (You also need level 83 Thieving.)"); + case 43: + return newstruct cs2func_script_1008_struct(75, 3251, "Possibility of stealing quadruple loot from a knight" + "
" + " (with 85 Thieving)", "You now have the Agility level required to potentially steal quadruple loot from " + "" + "knights" + "" + ". (You also need level 85 Thieving.)"); + case 44: + return newstruct cs2func_script_1008_struct(75, 6781, "Possibility of stealing quadruple loot from a Pollnivnian bandit" + "
" + " (with 85 Thieving)", "You now have the Agility level required to potentially steal quadruple loot from " + "" + "Pollnivnian bandits" + "" + ". (You also need level 85 Thieving.)"); + case 45: + return newstruct cs2func_script_1008_struct(75, 3253, "Possibility of stealing triple loot from a watchman" + "
" + " (with 85 Thieving)", "You now have the Agility level required to potentially steal triple loot from " + "" + "watchmen" + "" + ". (You also need level 85 Thieving.)"); + case 46: + return newstruct cs2func_script_1008_struct(75, 6780, "Possibility of stealing triple loot from a Menaphite thug" + "
" + " (with 85 Thieving)", "You now have the Agility level required to potentially steal triple loot from " + "" + "Menaphite thugs" + "" + ". (You also need level 85 Thieving.)"); + case 47: + return newstruct cs2func_script_1008_struct(75, 3257, "Possibility of stealing double loot from a gnome" + "
" + " (with 85 Thieving)", "You now have the Agility level required to potentially steal double loot from " + "" + "gnomes" + "" + ". (You also need level 85 Thieving.)"); + case 48: + return newstruct cs2func_script_1008_struct(80, 3255, "Possibility of stealing triple loot from a paladin" + "
" + " (with 90 Thieving)", "You now have the Agility level required to potentially steal triple loot from " + "" + "paladins" + "" + ". (You also need level 90 Thieving.)"); + case 49: + return newstruct cs2func_script_1008_struct(80, 3259, "Possibility of stealing double loot from a hero" + "
" + " (with 90 Thieving)", "You now have the Agility level required to potentially steal double loot from " + "" + "heroes" + "" + ". (You also need level 90 Thieving.)"); + case 50: + return newstruct cs2func_script_1008_struct(85, 3253, "Possibility of stealing quadruple loot from a watchman" + "
" + " (with 95 Thieving)", "You now have the Agility level required to potentially steal quadruple loot from " + "" + "watchmen" + "" + ". (You also need level 95 Thieving.)"); + case 51: + return newstruct cs2func_script_1008_struct(85, 6780, "Possibility of stealing quadruple loot from a Menaphite thug" + "
" + " (with 95 Thieving)", "You now have the Agility level required to potentially steal quadruple loot from " + "" + "Menaphite thugs" + "" + ". (You also need level 95 Thieving.)"); + case 52: + return newstruct cs2func_script_1008_struct(85, 3257, "Possibility of stealing triple loot from a gnome" + "
" + " (with 95 Thieving)", "You now have the Agility level required to potentially steal triple loot from " + "" + "gnomes" + "" + ". (You also need level 95 Thieving.)"); + case 53: + return newstruct cs2func_script_1008_struct(85, 6105, "Possibility of stealing double loot from an elf" + "
" + " (with 95 Thieving)", "You now have the Agility level required to potentially steal double loot from " + "" + "elves" + "" + ". (You also need level 95 Thieving.)"); + } + break; + case 6: + switch (arg1) { + case 0: + return newstruct cs2func_script_1008_struct(75, 9970, "Catch ruby harvest barehanded (woodland)" + "
" + " (with 80 Hunter)", "You now have the Agility level to catch " + "" + "ruby harvest butterflies" + "" + " barehanded. This feat will give you Hunter and Agility experience upon a successful catch. (You also need level 80 Hunter.)"); + case 1: + return newstruct cs2func_script_1008_struct(80, 9971, "Catch sapphire glacialis barehanded (polar)" + "
" + " (with 85 Hunter)", "You now have the Agility level to catch " + "" + "sapphire glacialis butterflies" + "" + " barehanded. This feat will give you Hunter and Agility experience upon a successful catch. (You also need level 85 Hunter.)"); + case 2: + return newstruct cs2func_script_1008_struct(85, 9972, "Catch snowy knights barehanded (polar)" + "
" + " (with 90 Hunter)", "You now have the Agility level to catch " + "" + "snowy knight butterflies" + "" + " barehanded. This feat will give you Hunter and Agility experience upon a successful catch. (You also need level 90 Hunter.)"); + case 3: + return newstruct cs2func_script_1008_struct(90, 9973, "Catch black warlocks barehanded (jungle)" + "
" + " (with 95 Hunter)", "You now have the Agility level to catch " + "" + "black warlock butterflies" + "" + " barehanded. This feat will give you Hunter and Agility experience upon a succesful catch. (You also need level 95 Hunter.)"); + } + break; + case 7: + switch (arg1) { + case 0: + return newstruct cs2func_script_1008_struct(60, 20704, "Members: access to the Livid Farm (with 70 Magic, 60 Crafting, 60 Farming, 50 Construction and Lunar Diplomacy)", "Members can access the " + "" + "Livid Farm" + "" + " (with 70 Magic, 60 Crafting, 60 Farming, 50 Construction and Lunar Diplomacy)."); + case 1: + return newstruct cs2func_script_1008_struct(91, 18778, "Starved ancient effigies", "You can now investigate " + "" + "starved ancient effigies" + "" + " using your knowledge of Agility."); + case 2: + return newstruct cs2func_script_1008_struct(93, 18779, "Nourished ancient effigies", "You can now investigate " + "" + "nourished ancient effigies" + "" + " using your knowledge of Agility."); + case 3: + return newstruct cs2func_script_1008_struct(95, 18780, "Sated ancient effigies", "You can now investigate " + "" + "sated ancient effigies" + "" + " using your knowledge of Agility."); + case 4: + return newstruct cs2func_script_1008_struct(97, 18781, "Gorged ancient effigies", "You can now investigate " + "" + "gorged ancient effigies" + "" + " using your knowledge of Agility."); + } + break; + case 8: + switch (arg1) { + case 0: + return newstruct cs2func_script_1008_struct(-1, 15707, "Dungeoneering skill tasks" + "
" + "As your Agility level increases, you will be able to attempt higher-level Agility tasks within Daemonheim. You will also be more likely to succeed when attempting Agility tasks within Daemonheim.", ""); + } + break; + case 9: + if (((boolean)arg1)) { + return newstruct cs2func_script_1008_struct(50, 4211, "Crystal equipment", "You now have the Agility level required to use " + "" + "crystal equipment" + "" + ". (You may need further requirements.)"); + } + if (((boolean)arg1)) { + return newstruct cs2func_script_1008_struct(99, 9771, "Skill mastery", "" + "Congratulations! You are now a master of " + "" + "Agility" + "" + ". Why not visit " + "" + "Cap'n Izzy No-beard" + "" + " at the " + "" + "Brimhaven Agility Arena" + "" + "? He has something special that is only available to true masters of the " + "" + "Agility" + "" + " skill!"); + } + } + return newstruct cs2func_script_1008_struct(0, -1, "", ""); +} diff --git a/dumps/scripts/1009.cs2 b/dumps/scripts/1009.cs2 new file mode 100644 index 0000000..f7b55eb --- /dev/null +++ b/dumps/scripts/1009.cs2 @@ -0,0 +1,27 @@ +cs2func_script_1009_struct(1,1,0) script_1009(int arg0) { + switch (arg0) { + case 0: + return newstruct cs2func_script_1009_struct(0, "Bows"); + case 1: + return newstruct cs2func_script_1009_struct(1, "Thrown"); + case 2: + return newstruct cs2func_script_1009_struct(0, "Armour"); + case 3: + return newstruct cs2func_script_1009_struct(0, "Crossbows"); + case 4: + return newstruct cs2func_script_1009_struct(1, "Shortcuts"); + case 5: + return newstruct cs2func_script_1009_struct(1, "Salamanders"); + case 6: + return newstruct cs2func_script_1009_struct(1, "Areas"); + case 7: + return newstruct cs2func_script_1009_struct(0, "Other"); + case 8: + return newstruct cs2func_script_1009_struct(1, "Minigames"); + case 9: + return newstruct cs2func_script_1009_struct(0, "Dungeoneering"); + case 10: + return newstruct cs2func_script_1009_struct(0, "Milestones"); + } + return newstruct cs2func_script_1009_struct(-1, ""); +} diff --git a/dumps/scripts/101.cs2 b/dumps/scripts/101.cs2 new file mode 100644 index 0000000..d623c1e --- /dev/null +++ b/dumps/scripts/101.cs2 @@ -0,0 +1,4 @@ +void script_101() { + script_1548(0); + return; +} diff --git a/dumps/scripts/1010.cs2 b/dumps/scripts/1010.cs2 new file mode 100644 index 0000000..d31b0a9 --- /dev/null +++ b/dumps/scripts/1010.cs2 @@ -0,0 +1,635 @@ +cs2func_script_1010_struct(2,2,0) script_1010(int arg0,int arg1) { + switch (arg0) { + flow_1: + case 0: + switch (arg1) { + case 0: + return newstruct cs2func_script_1010_struct(1, 841, "Standard bow" + "
" + " Ammo: Arrows up to iron", "You can now use " + "" + "standard bows" + "" + "."); + case 1: + return newstruct cs2func_script_1010_struct(5, 843, "Oak bow" + "
" + " Ammo: Arrows up to steel", "You can now use " + "" + "oak bows" + "" + "."); + case 2: + return newstruct cs2func_script_1010_struct(20, 849, "Willow bow" + "
" + " Ammo: Arrows up to mithril", "You can now use " + "" + "willow bows" + "" + "."); + case 3: + return newstruct cs2func_script_1010_struct(30, 853, "Maple bow" + "
" + " Ammo: Arrows up to adamant", "You can now use " + "" + "maple bows" + "" + "."); + case 4: + return newstruct cs2func_script_1010_struct(30, 2883, "Members: Ogre bow (after Big Chompy Bird Hunting)" + "
" + " Ammo: Ogre arrows", "Members now have the Ranged level to use " + "" + "ogre bows" + "" + " (after Big Chompy Bird Hunting)."); + case 5: + return newstruct cs2func_script_1010_struct(30, 4827, "Members: Ogre composite bow (after Zogre Flesh Eaters)" + "
" + " Ammo: 'Brutal' arrows up to rune", "Members now have the Ranged level to use " + "" + "ogre composite bows" + "" + " (after Zogre Flesh Eaters)."); + case 6: + return newstruct cs2func_script_1010_struct(40, 857, "Members: Yew bow" + "
" + " Ammo: Arrows up to rune", "Members can now use " + "" + "yew bows" + "" + "."); + case 7: + return newstruct cs2func_script_1010_struct(40, 14121, "Members: Sacred clay bow" + "
" + " Ammo: Arrows up to rune", "Members can now wield " + "" + "sacred clay bows" + "" + "."); + case 8: + return newstruct cs2func_script_1010_struct(45, 18331, "Maple longbow (focused)" + "
" + " Ammo: Arrows up to rune" + "
" + " (with 45 Dungeoneering)", "You can now use " + "" + "maple longbows (focused)" + "" + ". (You also need level 45 Dungeoneering.)"); + case 9: + return newstruct cs2func_script_1010_struct(45, 18373, "Gravite shortbow" + "
" + " Ammo: Arrows up to rune" + "
" + " (with 45 Dungeoneering)", "You can now wield " + "" + "gravite shortbows" + "" + ". (You also need level 45 Dungeoneering.)"); + case 10: + return newstruct cs2func_script_1010_struct(50, 861, "Members: Magic bow" + "
" + " Ammo: Arrows up to rune", "Members can now use " + "" + "magic bows" + "" + "."); + case 11: + return newstruct cs2func_script_1010_struct(50, 6724, "Members: Seercull" + "
" + " Ammo: Arrows up to rune", "Members can now use the " + "" + "Seercull" + "" + "."); + case 12: + return newstruct cs2func_script_1010_struct(55, 18332, "Members: Magic longbow (focused)" + "
" + " Ammo: Arrows up to rune" + "
" + " (with 45 Dungeoneering)", "Members can now use " + "" + "magic longbows (focused)" + "" + ". (They also need level 45 Dungeoneering.)"); + case 13: + return newstruct cs2func_script_1010_struct(55, 19143, "Members: Saradomin bow" + "
" + " Ammo: Arrows up to rune", "Members can now wield " + "" + "Saradomin bows" + "" + "."); + case 14: + return newstruct cs2func_script_1010_struct(55, 19146, "Members: Guthix bow" + "
" + " Ammo: Arrows up to rune", "Members can now wield " + "" + "Guthix bows" + "" + "."); + case 15: + return newstruct cs2func_script_1010_struct(55, 19149, "Members: Zamorak bow" + "
" + " Ammo: Arrows up to rune", "Members can now wield " + "" + "Zamorak bows" + "" + "."); + case 16: + return newstruct cs2func_script_1010_struct(60, 11235, "Members: Dark bow" + "
" + " Ammo: Arrows up to dragon", "Members can now use " + "" + "dark bows" + "" + "."); + case 17: + return newstruct cs2func_script_1010_struct(70, 4212, "Members: Crystal bow (after Roving Elves and with 50 Agility)" + "
" + " Ammo: None", "Members now have the Ranged level to use " + "" + "crystal bows" + "" + " (after Roving Elves, with level 50 Agility)."); + case 18: + return newstruct cs2func_script_1010_struct(80, 20171, "Members: Zaryte bow" + "
" + " Ammo: None", "Members now have the Ranged level to use " + "" + "Zaryte bows" + "" + "."); + } + break; + case 1: + switch (arg1) { + case 0: + return newstruct cs2func_script_1010_struct(1, 806, "Members: Bronze dart", "Members can now throw " + "" + "bronze darts" + "" + "."); + case 1: + return newstruct cs2func_script_1010_struct(1, 825, "Members: Bronze javelin", "Members can now throw " + "" + "bronze javelins" + "" + "."); + case 2: + return newstruct cs2func_script_1010_struct(1, 800, "Members: Bronze throwing axe", "Members can now throw " + "" + "bronze throwing axes" + "" + "."); + case 3: + return newstruct cs2func_script_1010_struct(1, 864, "Members: Bronze throwing knife", "Members can now throw " + "" + "bronze throwing knives" + "" + "."); + case 4: + return newstruct cs2func_script_1010_struct(1, 807, "Members: Iron dart", "Members can now throw " + "" + "iron darts" + "" + "."); + case 5: + return newstruct cs2func_script_1010_struct(1, 826, "Members: Iron javelin", "Members can now throw " + "" + "iron javelins" + "" + "."); + case 6: + return newstruct cs2func_script_1010_struct(1, 801, "Members: Iron throwing axe", "Members can now throw " + "" + "iron throwing axes" + "" + "."); + case 7: + return newstruct cs2func_script_1010_struct(1, 863, "Members: Iron throwing knife", "Members can now throw " + "" + "iron throwing knives" + "" + "."); + case 8: + return newstruct cs2func_script_1010_struct(5, 808, "Members: Steel dart", "Members can now throw " + "" + "steel darts" + "" + "."); + case 9: + return newstruct cs2func_script_1010_struct(5, 827, "Members: Steel javelin", "Members can now throw " + "" + "steel javelins" + "" + "."); + case 10: + return newstruct cs2func_script_1010_struct(5, 802, "Members: Steel throwing axe", "Members can now throw " + "" + "steel throwing axes" + "" + "."); + case 11: + return newstruct cs2func_script_1010_struct(5, 865, "Members: Steel throwing knife", "Members can now throw " + "" + "steel throwing knives" + "" + "."); + case 12: + return newstruct cs2func_script_1010_struct(10, 3093, "Members: Black dart", "Members can now throw " + "" + "black darts" + "" + "."); + case 13: + return newstruct cs2func_script_1010_struct(10, 869, "Members: Black throwing knife", "Members can now throw " + "" + "black throwing knives" + "" + "."); + case 14: + return newstruct cs2func_script_1010_struct(20, 809, "Members: Mithril dart", "Members can now throw " + "" + "mithril darts" + "" + "."); + case 15: + return newstruct cs2func_script_1010_struct(20, 828, "Members: Mithril javelin", "Members can now throw " + "" + "mithril javelins" + "" + "."); + case 16: + return newstruct cs2func_script_1010_struct(20, 803, "Members: Mithril throwing axe", "Members can now throw " + "" + "mithril throwing axes" + "" + "."); + case 17: + return newstruct cs2func_script_1010_struct(20, 866, "Members: Mithril throwing knife", "Members can now throw " + "" + "mithril throwing knives" + "" + "."); + case 18: + return newstruct cs2func_script_1010_struct(20, 13953, "Members: Corrupt Morrigan's javelin", "Members can now throw " + "" + "corrupt Morrigan's javelin" + "" + "."); + case 19: + return newstruct cs2func_script_1010_struct(20, 13957, "Members: Corrupt Morrigan's throwing axe", "Members can now throw " + "" + "corrupt Morrigan's throwing axe" + "" + "."); + case 20: + return newstruct cs2func_script_1010_struct(30, 810, "Members: Adamant dart", "Members can now throw " + "" + "adamant darts."); + case 21: + return newstruct cs2func_script_1010_struct(30, 829, "Members: Adamant javelin", "Members can now throw " + "" + "adamant javelins" + "" + "."); + case 22: + return newstruct cs2func_script_1010_struct(30, 804, "Members: Adamant throwing axe", "Members can now throw " + "" + "adamant throwing axes" + "" + "."); + case 23: + return newstruct cs2func_script_1010_struct(30, 867, "Members: Adamant throwing knife", "Members can now throw " + "" + "adamant throwing knives" + "" + "."); + case 24: + return newstruct cs2func_script_1010_struct(40, 811, "Members: Rune dart", "Members can now throw " + "" + "rune darts" + "" + "."); + case 25: + return newstruct cs2func_script_1010_struct(40, 830, "Members: Rune javelin", "Members can now throw " + "" + "rune javelins" + "" + "."); + case 26: + return newstruct cs2func_script_1010_struct(40, 805, "Members: Rune throwing axe", "Members can now throw " + "" + "rune throwing axes" + "" + "."); + case 27: + return newstruct cs2func_script_1010_struct(40, 868, "Members: Rune throwing knife", "Members can now throw " + "" + "rune throwing knives" + "" + "."); + case 28: + return newstruct cs2func_script_1010_struct(45, 10033, "Members: Chinchompa", "Members can now throw " + "" + "chinchompas" + "" + "."); + case 29: + return newstruct cs2func_script_1010_struct(55, 10034, "Members: Red chinchompa", "Members can now throw " + "" + "red chinchompas" + "" + "."); + case 30: + return newstruct cs2func_script_1010_struct(60, 11230, "Members: Dragon dart", "Members can now throw " + "" + "dragon darts" + "" + "."); + case 31: + return newstruct cs2func_script_1010_struct(60, 6522, "Members: Toktz-Xil-Ul", "Members can now throw " + "" + "Toktz-Xil-Ul" + "" + "."); + case 32: + return newstruct cs2func_script_1010_struct(70, 21581, "Members: Blisterwood stake (after The Branches of Darkmeyer)", "Members can now throw " + "" + "blisterwood stakes" + "" + " (after The Branches of Darkmeyer)."); + case 33: + return newstruct cs2func_script_1010_struct(72, 21364, "Members: Sagaie", "Members can now throw " + "" + "sagaies" + "" + "."); + case 34: + return newstruct cs2func_script_1010_struct(76, 21365, "Members: Bolas", "Members can now throw " + "" + "bolas" + "" + "."); + case 35: + return newstruct cs2func_script_1010_struct(78, 13879, "Members: Morrigan's javelin", "Members can now throw " + "" + "Morrigan's javelin" + "" + "."); + case 36: + return newstruct cs2func_script_1010_struct(78, 13883, "Members: Morrigan's throwing axe", "Members can now throw " + "" + "Morrigan's throwing axe" + "" + "."); + } + break; + case 2: + switch (arg1) { + case 0: + return newstruct cs2func_script_1010_struct(1, 1129, "Plain leather items", "You can now wear " + "" + "plain leather" + "" + " items."); + case 1: + return newstruct cs2func_script_1010_struct(1, 1131, "Hard leather body" + "
" + " (with 10 Defence)", "You now have the Ranged level required to wear " + "" + "hard leather" + "" + " bodies. (You also need level 10 Defence.)"); + case 2: + return newstruct cs2func_script_1010_struct(1, 6143, "Members: Spined boots", "Members can now wear " + "" + "spined boots" + "" + "."); + case 3: + return newstruct cs2func_script_1010_struct(1, 6149, "Members: Spined gloves", "Members can now wear " + "" + "spined gloves" + "" + "."); + case 4: + return newstruct cs2func_script_1010_struct(1, 3749, "Members: Archer helm (after Fremennik Trials and with 45 Defence)", "Members now have the Ranged level required to wear " + "" + "archer helms" + "" + " (after Fremennik Trials and with level 45 Defence)."); + case 5: + return newstruct cs2func_script_1010_struct(20, 1133, "Studded leather body" + "
" + " (with 20 Defence)", "You now have the Ranged level required to wear " + "" + "studded leather bodies" + "" + ". (You also need level 20 Defence.)"); + case 6: + return newstruct cs2func_script_1010_struct(20, 1097, "Studded leather chaps", "You can now wear " + "" + "studded leather chaps" + "" + "."); + case 7: + return newstruct cs2func_script_1010_struct(20, 1169, "Coif", "You can now wear " + "" + "coifs" + "" + "."); + case 8: + return newstruct cs2func_script_1010_struct(20, 13950, "Members: Corrupt Morrigan's coif" + "
" + " (with 20 Defence)", "Members now have the Ranged level required to wield " + "" + "corrupt Morrigan's coif" + "" + ". (They also need level 20 Defence)"); + case 9: + return newstruct cs2func_script_1010_struct(20, 13944, "Members: Corrupt Morrigan's leather body" + "
" + " (with 20 Defence)", "Members now have the Ranged level required to wield " + "" + "corrupt Morrigan's leather body" + "" + ". (They also need level 20 Defence)"); + case 10: + return newstruct cs2func_script_1010_struct(20, 13947, "Members: Corrupt Morrigan's leather chaps" + "
" + " (with 20 Defence)", "Members now have the Ranged level required to wield " + "" + "corrupt Morrigan's leather chaps" + "" + ". (They also need level 20 Defence)"); + case 11: + return newstruct cs2func_script_1010_struct(20, 15490, "Members: Focus sight" + "
" + " (with 10 Defence)", "Members can now wear " + "" + "focus sights" + "" + "."); + case 12: + return newstruct cs2func_script_1010_struct(20, 15492, "Members: Full Slayer helmet" + "
" + " (after Smoking Kills with 10 Defence, 20 Magic and Strength)", "Members can now wear " + "" + "full slayer helmets" + "" + " (after Smoking Kills with 10 Defence, 20 Magic and Strength)."); + case 13: + return newstruct cs2func_script_1010_struct(25, 10954, "Members: Frog-leather body" + "
" + " (with 25 Defence)", "Members now have the Ranged level required to wear " + "" + "frog-leather bodies" + "" + ". (They also need level 25 Defence.)"); + case 14: + return newstruct cs2func_script_1010_struct(25, 10956, "Members: Frog-leather chaps" + "
" + " (with 25 Defence)", "Members now have the Ranged level required to wear " + "" + "frog-leather chaps" + "" + ". (They also need level 25 Defence.)"); + case 15: + return newstruct cs2func_script_1010_struct(25, 10958, "Members: Frog-leather boots" + "
" + " (with 25 Defence)", "Members now have the Ranged level required to wear " + "" + "frog-leather boots" + "" + ". (They also need level 25 Defence.)."); + case 16: + return newstruct cs2func_script_1010_struct(30, 6322, "Members: Snakeskin body" + "
" + " (with 30 Defence)", "Members now have the Ranged level required to wear " + "" + "snakeskin bodies" + "" + ". (They also need level 30 Defence.)"); + case 17: + return newstruct cs2func_script_1010_struct(30, 6324, "Members: Snakeskin chaps" + "
" + " (with 30 Defence)", "Members now have the Ranged level required to wear " + "" + "snakeskin chaps" + "" + ". (They also need level 30 Defence.)"); + case 18: + return newstruct cs2func_script_1010_struct(30, 6330, "Members: Snakeskin vambraces" + "
" + " (with 30 Defence)", "Members now have the Ranged level required to wear " + "" + "snakeskin vambraces" + "" + ". (They also need level 30 Defence.)"); + case 19: + return newstruct cs2func_script_1010_struct(30, 6326, "Members: Snakeskin bandana" + "
" + " (with 30 Defence)", "Members now have the Ranged level required to wear " + "" + "snakeskin bandanas" + "" + ". (They also need level 30 Defence.)"); + case 20: + return newstruct cs2func_script_1010_struct(30, 6328, "Members: Snakeskin boots" + "
" + " (with 30 Defence)", "Members now have the Ranged level required to wear " + "" + "snakeskin boots" + "" + ". (They also need level 30 Defence.)"); + case 21: + return newstruct cs2func_script_1010_struct(40, 2577, "Members: Ranger boots", "Members can now wear " + "" + "ranger boots" + "" + "."); + case 22: + return newstruct cs2func_script_1010_struct(40, 2581, "Members: Robin Hood hat", "Members can now wear " + "" + "Robin Hood hats" + "" + "."); + case 23: + return newstruct cs2func_script_1010_struct(40, 1065, "Green dragonhide vambraces", "You can now wear " + "" + "green dragonhide vambraces" + "" + "."); + case 24: + return newstruct cs2func_script_1010_struct(40, 1099, "Green dragonhide chaps", "You can now wear " + "" + "green dragonhide chaps" + "" + "."); + case 25: + return newstruct cs2func_script_1010_struct(40, 1135, "Green dragonhide body" + "
" + " (after Dragon Slayer and with 40 Defence)", "You now have the Ranged level required to wear " + "" + "green dragonhide bodies" + "" + ". (You also need to have completed Dragon Slayer and have level 40 Defence.)"); + case 26: + return newstruct cs2func_script_1010_struct(40, 12936, "Green dragonhide coif" + "
" + " (with 40 Defence)", "You now have the Ranged level required to wear " + "" + "green dragonhide coifs" + "" + ". (You also need level 40 Defence.)"); + case 27: + return newstruct cs2func_script_1010_struct(40, 6133, "Members: Spined body" + "
" + " (after Fremennik Trials and with 40 Defence)", "Members now have the Ranged level required to wear " + "" + "spined bodies" + "" + " (after Fremennik Trials, with level 40 Defence)."); + case 28: + return newstruct cs2func_script_1010_struct(40, 6135, "Members: Spined chaps" + "
" + " (after Fremennik Trials and with 40 Defence)", "Members now have the Ranged level required to wear " + "" + "spined chaps" + "" + " (after Fremennik Trials, with level 40 Defence)."); + case 29: + return newstruct cs2func_script_1010_struct(40, 6131, "Members: Spined helm" + "
" + " (after Fremennik Trials and with 40 Defence)", "Members now have the Ranged level required to wear " + "" + "spined helms" + "" + " (after Fremennik Trials, with level 40 Defence)."); + case 30: + return newstruct cs2func_script_1010_struct(40, 14120, "Members: Sacred clay coif" + "
" + " (with 40 Defence)", "Members now have the Ranged level required to wear " + "" + "sacred clay coifs" + "" + ". (They also need level 40 Defence.)"); + case 31: + return newstruct cs2func_script_1010_struct(40, 14118, "Members: Sacred clay body" + "
" + " (with 40 Defence)", "Members now have the Ranged level required to wear " + "" + "sacred clay bodies" + "" + ". (They also need level 40 Defence.)"); + case 32: + return newstruct cs2func_script_1010_struct(40, 14119, "Members: Sacred clay chaps" + "
" + " (with 40 Defence)", "Members now have the Ranged level required to wear " + "" + "sacred clay chaps" + "" + ". (They also need level 40 Defence.)"); + case 33: + return newstruct cs2func_script_1010_struct(42, 11665, "Members: Void melee helm", "Members now have the Ranged level required to wear " + "" + "Void melee helms" + "" + "."); + case 34: + return newstruct cs2func_script_1010_struct(42, 11664, "Members: Void ranger helm", "Members now have the Ranged level required to wear " + "" + "Void ranger helms" + "" + "."); + case 35: + return newstruct cs2func_script_1010_struct(42, 11663, "Members: Void mage helm", "Members now have the Ranged level required to wear " + "" + "Void mage helms" + "" + "."); + case 36: + return newstruct cs2func_script_1010_struct(42, 8839, "Members: Void knight top", "Members now have the Ranged level required to wear " + "" + "Void knight tops" + "" + "."); + case 37: + return newstruct cs2func_script_1010_struct(42, 8840, "Members: Void knight robe", "Members now have the Ranged level required to wear " + "" + "Void knight robes" + "" + "."); + case 38: + return newstruct cs2func_script_1010_struct(42, 8842, "Members: Void knight gloves", "Members now have the Ranged level required to wear " + "" + "Void knight gloves" + "" + "."); + case 39: + return newstruct cs2func_script_1010_struct(42, 19712, "Members: Void knight deflector", "Members now have the Ranged level required to wear " + "" + "Void knight deflectors" + "" + "."); + case 40: + return newstruct cs2func_script_1010_struct(42, 7620, "Void knight equipment requires 42 Attack, Defence, Strength, Ranged, Magic and Constitution and 22 Prayer.", "" + "Void knight equipment" + "" + " requires 42 Attack, Defence, Strength, Ranged, Magic and Constitution and 22 Prayer."); + case 41: + return newstruct cs2func_script_1010_struct(50, 2487, "Members: Blue dragonhide vambraces", "Members can now wear " + "" + "blue dragonhide vambraces" + "" + "."); + case 42: + return newstruct cs2func_script_1010_struct(50, 2493, "Members: Blue dragonhide chaps", "Members can now wear " + "" + "blue dragonhide chaps" + "" + "."); + case 43: + return newstruct cs2func_script_1010_struct(50, 2499, "Members: Blue dragonhide body" + "
" + " (with 40 Defence)", "Members now have the Ranged level required to wear " + "" + "blue dragonhide bodies" + "" + ". (They also need level 40 Defence.)"); + case 44: + return newstruct cs2func_script_1010_struct(50, 12943, "Members: Blue dragonhide coif" + "
" + " (with 40 Defence)", "Members now have the Ranged level required to wear " + "" + "blue dragonhide coifs" + "" + ". (They also need level 40 Defence.)"); + case 45: + return newstruct cs2func_script_1010_struct(60, 2489, "Members: Red dragonhide vambraces", "Members can now wear " + "" + "red dragonhide vambraces" + "" + "."); + case 46: + return newstruct cs2func_script_1010_struct(60, 2495, "Members: Red dragonhide chaps", "Members can now wear " + "" + "red dragonhide chaps" + "" + "."); + case 47: + return newstruct cs2func_script_1010_struct(60, 2501, "Members: Red dragonhide body" + "
" + " (with 40 Defence)", "Members now have the Ranged level required to wear " + "" + "red dragonhide bodies" + "" + ". (They also need level 40 Defence.)"); + case 48: + return newstruct cs2func_script_1010_struct(60, 12950, "Members: Red dragonhide coif" + "
" + " (with 40 Defence)", "Members now have the Ranged level required to wear " + "" + "red dragonhide coifs" + "" + ". (They also need level 40 Defence.)"); + case 49: + return newstruct cs2func_script_1010_struct(65, 10334, "Members: Third-Age range coif" + "
" + " (with 45 Defence)", "Members now have the Ranged level required to wear " + "" + "Third-Age range coifs" + "" + ". (They also need level 45 Defence.)"); + case 50: + return newstruct cs2func_script_1010_struct(65, 10330, "Members: Third-Age range top" + "
" + " (with 45 Defence)", "Members now have the Ranged level required to wear " + "" + "Third-Age range tops" + "" + ". (They also need level 45 Defence.)"); + case 51: + return newstruct cs2func_script_1010_struct(65, 10332, "Members: Third-Age range legs" + "
" + " (with 45 Defence)", "Members now have the Ranged level required to wear " + "" + "Third-Age range legs" + "" + ". (They also need level 45 Defence.)"); + case 52: + return newstruct cs2func_script_1010_struct(65, 10336, "Members: Third-Age range vambraces" + "
" + " (with 45 Defence)", "Members now have the Ranged level required to wear " + "" + "Third-Age range vambraces" + "" + ". (They also need level 45 Defence.)"); + case 53: + return newstruct cs2func_script_1010_struct(70, 2491, "Members: Black dragonhide vambraces", "Members can now wear " + "" + "black dragonhide vambraces" + "" + "."); + case 54: + return newstruct cs2func_script_1010_struct(70, 2497, "Members: Black dragonhide chaps", "Members can now wear " + "" + "black dragonhide chaps" + "" + "."); + case 55: + return newstruct cs2func_script_1010_struct(70, 2503, "Members: Black dragonhide body" + "
" + " (with 40 Defence)", "Members now have the Ranged level required to wear " + "" + "black dragonhide bodies" + "" + ". (They also need level 40 Defence.)"); + case 56: + return newstruct cs2func_script_1010_struct(70, 12957, "Members: Black dragonhide coif" + "
" + " (with 40 Defence)", "Members now have the Ranged level required to wear " + "" + "black dragonhide coifs" + "" + ". (They also need level 40 Defence.)"); + case 57: + return newstruct cs2func_script_1010_struct(70, 10374, "Members: Blessed dragonhide coif" + "
" + " (with 40 Defence)", "Members now have the Ranged level required to wear " + "" + "blessed dragonhide coifs" + "" + ". (They also need level 40 Defence.)"); + case 58: + return newstruct cs2func_script_1010_struct(70, 4732, "Members: Karil's coif" + "
" + " (with 70 Defence)", "Members now have the Ranged level required to wear " + "" + "Karil's Coif" + "" + ". (They also need level 70 Defence.)"); + case 59: + return newstruct cs2func_script_1010_struct(70, 4736, "Members: Karil's leather top" + "
" + " (with 70 Defence)", "Members now have the Ranged level required to wear " + "" + "Karil's leather top" + "" + ". (They also need level 70 Defence.)"); + case 60: + return newstruct cs2func_script_1010_struct(70, 4738, "Members: Karil's leather skirt" + "
" + " (with 70 Defence)", "Members now have the Ranged level required to wear " + "" + "Karil's leather skirt" + "" + ". (They also need level 70 Defence.)"); + case 61: + return newstruct cs2func_script_1010_struct(70, 11718, "Members: Armadyl helmet" + "
" + " (with 70 Defence)", "Members now have the Ranged level required to wear Armadyl helmets. (They also need level 70 Defence.)"); + case 62: + return newstruct cs2func_script_1010_struct(70, 11720, "Members: Armadyl chestplate" + "
" + " (with 70 Defence)", "Members now have the Ranged level required to wear Armadyl chestplates. (They also need level 70 Defence.)"); + case 63: + return newstruct cs2func_script_1010_struct(70, 11722, "Members: Armadyl chainskirt" + "
" + " (with 70 Defence)", "Members now have the Ranged level required to wear Armadyl chainskirts. (They also need level 70 Defence.)"); + case 64: + return newstruct cs2func_script_1010_struct(73, 18347, "Members: Mercenary's gloves" + "
" + " (with 73 Dungeoneering)", "Members can now wear " + "" + "mercenary's gloves" + "" + ". (They also need level 73 Dungeoneering.)"); + case 65: + return newstruct cs2func_script_1010_struct(75, 21790, "Members: Glaiven boots" + "
" + " (with 75 Defence)", "Members now have the Ranged level required to wear " + "" + "glaiven boots" + "" + " (with 75 Defence)."); + case 66: + return newstruct cs2func_script_1010_struct(78, 13876, "Members: Morrigan's coif" + "
" + " (with 78 Defence)", "Members now have the Ranged level required to wield " + "" + "Morrigan's coif" + "" + ". (They also need level 78 Defence)"); + case 67: + return newstruct cs2func_script_1010_struct(78, 13870, "Members: Morrigan's leather body" + "
" + " (with 78 Defence)", "Members now have the Ranged level required to wield " + "" + "Morrigan's leather body" + "" + ". (They also need level 78 Defence)"); + case 68: + return newstruct cs2func_script_1010_struct(78, 13873, "Members: Morrigan's leather chaps" + "
" + " (with 78 Defence)", "Members now have the Ranged level required to wield " + "" + "Morrigan's leather chaps" + "" + ". (They also need level 78 Defence)"); + case 69: + return newstruct cs2func_script_1010_struct(80, 20147, "Members: Pernix cowl" + "
" + " (with 80 Defence and Constitution)", "Members can now wear " + "" + "pernix cowls" + "" + ". (They also need level 80 Defence and Constitution.)"); + case 70: + return newstruct cs2func_script_1010_struct(80, 20151, "Members: Pernix body" + "
" + " (with 80 Defence and Constitution)", "Members can now wear " + "" + "pernix bodies" + "" + ". (They also need level 80 Defence and Constitution.)"); + case 71: + return newstruct cs2func_script_1010_struct(80, 20155, "Members: Pernix chaps" + "
" + " (with 80 Defence and Constitution)", "Members can now wear " + "" + "pernix chaps" + "" + ". (They also need level 80 Defence and Constitution.)"); + } + break; + case 3: + switch (arg1) { + case 0: + return newstruct cs2func_script_1010_struct(1, 837, "Crossbow" + "
" + " Ammo: Bronze crossbow bolts", "You can now " + "" + "fire crossbows" + "" + "."); + case 1: + return newstruct cs2func_script_1010_struct(1, 767, "Phoenix crossbow" + "
" + " Ammo: Bronze crossbow bolts", "You can now fire " + "" + "phoenix crossbows" + "" + "."); + case 2: + return newstruct cs2func_script_1010_struct(1, 9174, "Members: Bronze crossbow" + "
" + " Ammo: Bronze crossbow bolts", "Members can now fire " + "" + "bronze crossbows" + "" + "."); + case 3: + return newstruct cs2func_script_1010_struct(16, 9176, "Members: Blurite crossbow" + "
" + " Ammo: Bolts up to blurite", "Members can now fire " + "" + "blurite crossbows" + "" + "."); + case 4: + return newstruct cs2func_script_1010_struct(26, 9177, "Members: Iron crossbow" + "
" + " Ammo: Bolts up to iron", "Members can now fire " + "" + "iron crossbows" + "" + "."); + case 5: + return newstruct cs2func_script_1010_struct(28, 8880, "Members: Dorgeshuun crossbow" + "
" + " Ammo: Bolts up to iron", "Members can now fire " + "" + "Dorgeshuun crossbows" + "" + "."); + case 6: + return newstruct cs2func_script_1010_struct(31, 9179, "Members: Steel crossbow" + "
" + " Ammo: Bolts up to steel", "Members can now fire " + "" + "steel crossbows" + "" + "."); + case 7: + return newstruct cs2func_script_1010_struct(33, 13081, "Members: Black crossbow" + "
" + " Ammo: Bolts up to black", "Members can now fire " + "" + "black crossbows" + "" + "."); + case 8: + return newstruct cs2func_script_1010_struct(36, 9181, "Members: Mithril crossbow" + "
" + " Ammo: Bolts up to mithril", "Members can now fire " + "" + "mithril crossbows" + "" + "."); + case 9: + return newstruct cs2func_script_1010_struct(46, 9183, "Members: Adamant crossbow" + "
" + " Ammo: Bolts up to adamant", "Members can now fire " + "" + "adamant crossbows" + "" + "."); + case 10: + return newstruct cs2func_script_1010_struct(48, 14684, "Members: Zanik's crossbow (after The Chosen Commander)" + "
" + " Ammo: Bolts up to adamant", "Members can now fire " + "" + "Zanik's crossbow" + "" + " (after The Chosen Commander)."); + case 11: + return newstruct cs2func_script_1010_struct(50, 10156, "Members: Hunters' crossbow" + "
" + " Ammo: Kebbit and long kebbit bolts", "Members can now fire " + "" + "hunters' crossbows" + "" + "."); + case 12: + return newstruct cs2func_script_1010_struct(61, 9185, "Members: Runite crossbow" + "
" + " Ammo: Bolts up to rune", "Members can now fire " + "" + "runite crossbows" + "" + "."); + case 13: + return newstruct cs2func_script_1010_struct(70, 4734, "Members: Karil's crossbow" + "
" + " Ammo: Bolt racks", "Members can now use " + "" + "Karil's crossbow" + "" + "."); + case 14: + return newstruct cs2func_script_1010_struct(80, 18358, "Members: Chaotic crossbow" + "
" + " Ammo: Bolts up to rune" + "
" + " (with 80 Dungeoneering)", "Members can now wield " + "" + "chaotic crossbows" + "" + ". (They also need level 80 Dungeoneering.)"); + } + break; + case 4: + switch (arg1) { + case 0: + return newstruct cs2func_script_1010_struct(19, 6517, "Members: Falador wall" + "
" + " (with 11 Agility and 37 Strength)", "Members now have the Ranged level required to scale the " + "" + "Falador wall" + "" + ". (They also need level 11 Agility and level 37 Strength.)"); + case 1: + return newstruct cs2func_script_1010_struct(21, 6517, "Members: Yanille wall " + "
" + " (with 39 Agility and 38 Strength)", "Members now have the Ranged level required to scale the " + "" + "Yanille wall" + "" + ". (You also need level 39 Agility and level 38 Strength.)"); + case 2: + return newstruct cs2func_script_1010_struct(35, 6517, "Members: Catherby cliff " + "
" + " (after Fishing Contest, with 32 Agility and 35 Strength)", "Members now have the Ranged level required to scale the " + "" + "Catherby cliff" + "" + " (after Fishing Contest, with level 32 Agility and 35 Strength)."); + case 3: + return newstruct cs2func_script_1010_struct(37, 6515, "Members: River crossing to Al Kharid " + "
" + " (with 8 Agility and 19 Strength)", "Members now have the Ranged level required to cross the " + "" + "River Lum" + "" + " to " + "" + "Al Kharid" + "" + ". (You also need level 8 Agility and level 19 Strength.)"); + case 4: + return newstruct cs2func_script_1010_struct(39, 6515, "Members: Water Obelisk Island escape " + "
" + " (with 36 Agility and 22 Strength)", "Members now have the Ranged level required to complete the " + "" + "Water Obelisk Island escape" + "" + ". (You also need level 36 Agility and level 22 Strength)."); + case 5: + return newstruct cs2func_script_1010_struct(42, 6515, "Members: Karamja crossing, south of the volcano " + "
" + " (with 53 Agility and 21 Strength)", "Members now have the Ranged level required to use the " + "" + "Karamja Agility shortcut" + "" + ". (You also need level 53 Agility and level 21 Strength.)"); + case 6: + return newstruct cs2func_script_1010_struct(60, 6515, "Members: Cross Bandos's throne room " + "
" + " (after The Chosen Commander and with 60 Agility and 60 Strength)", "Members now have the Ranged level required to cross " + "" + "Bandos's throne room" + "" + " (after The Chosen Commander and with 60 Agility and 60 Strength."); + case 7: + return newstruct cs2func_script_1010_struct(80, 6515, "Members: Cross cave, south of Dorgesh-Kaan " + "
" + " (with 80 Agility and 80 Strength)", "Members now have the Ranged level required to cross the " + "" + "cave south of Dorgesh-Kaan" + "" + ". (You also need level 80 Agility and 80 Strength."); + } + break; + case 5: + switch (arg1) { + case 0: + return newstruct cs2func_script_1010_struct(30, 10149, "Members: Swamp lizard" + "
" + " (with 30 Attack and 30 Magic)", "Members now have the Ranged level required to use " + "" + "swamp lizards" + "" + ". (They also need level 30 Attack and level 30 Magic.)"); + case 1: + return newstruct cs2func_script_1010_struct(50, 10146, "Members: Orange salamander" + "
" + " (with 50 Attack and 50 Magic)", "Members now have the Ranged level required to use " + "" + "orange salamanders" + "" + ". (They also need level 50 Attack and level 50 Magic.)"); + case 2: + return newstruct cs2func_script_1010_struct(60, 10147, "Members: Red salamander" + "
" + " (with 60 Attack and 60 Magic)", "Members now have the Ranged level required to use " + "" + "red salamanders" + "" + ". (They also need level 60 Attack and level 60 Magic.)"); + case 3: + return newstruct cs2func_script_1010_struct(70, 10148, "Members: Black salamander" + "
" + " (with 70 Attack and 70 Magic)", "Members now have the Ranged level required to use " + "" + "black salamanders" + "" + ". (They also need level 70 Attack and level 70 Magic.)"); + } + break; + case 6: + if (((boolean)arg1)) { + return newstruct cs2func_script_1010_struct(70, 9419, "Members: Armadyl's Eyrie in the God Wars Dungeon", "Members can now enter " + "" + "Armadyl's Eyrie" + "" + " in the " + "" + "God Wars Dungeon" + "" + "."); + } + break; + case 7: + switch (arg1) { + case 0: + return newstruct cs2func_script_1010_struct(1, 19830, "Sling" + "
" + " Ammo: None needed", "You can now use a " + "" + "sling" + "" + "."); + case 1: + return newstruct cs2func_script_1010_struct(1, 15597, "Kayle's sling (after The Blood Pact)" + "
" + " Ammo: None needed", "You can now use " + "" + "Kayle's sling" + "" + " (after The Blood Pact)."); + case 2: + return newstruct cs2func_script_1010_struct(30, 10498, "Members: Ava's Attractor (after Animal Magnetism)", "Members now have the Ranged level required to use " + "" + "Ava's Attractor" + "" + " (after Animal Magnetism)."); + case 3: + return newstruct cs2func_script_1010_struct(42, 8841, "Members: Void knight mace", "Members now have the Ranged level required to wield " + "" + "Void knight maces" + "" + "."); + case 4: + return newstruct cs2func_script_1010_struct(45, 18330, "Longbow sight" + "
" + " (with 45 Dungeoneering)", "You can now use " + "" + "longbow sights" + "" + ". (You also need level 45 Dungeoneering.)"); + case 5: + return newstruct cs2func_script_1010_struct(50, 10499, "Members: Ava's Accumulator (after Animal Magnetism)", "Members now have the Ranged level required to use " + "" + "Ava's Accumulator" + "" + " (after Animal Magnetism)."); + case 6: + return newstruct cs2func_script_1010_struct(50, 20068, "Members: Ava's Alerter (after Do No Evil)", "Members now have the Ranged level required to use " + "" + "Ava's Alerter" + "" + " (after Do No Evil)."); + case 7: + return newstruct cs2func_script_1010_struct(50, 4150, "Members: Broad arrows" + "
" + " (with 55 Slayer)", "Members now have the Ranged level required to shoot " + "" + "broad arrows" + "" + ", Ranged weapons used for killing turoth and kurask. (You also need level 55 Slayer.)"); + case 8: + return newstruct cs2func_script_1010_struct(50, 13280, "Members: Broad-tipped bolts" + "
" + " (with 55 Slayer)", "Members now have the Ranged level required to shoot " + "" + "broad-tipped bolts" + "" + ", Ranged weapons used for killing turoth and kurask. (You also need level 55 Slayer.)"); + case 9: + return newstruct cs2func_script_1010_struct(50, 21640, "Members: Bane arrows" + "
" + " (after Ritual of the Mahjarrat)", "Members now have the Ranged level required to shoot " + "" + "bane arrows" + "" + ", Ranged weapons used for effectively killing specific creatures. (after Ritual of the Mahjarrat.)"); + case 10: + return newstruct cs2func_script_1010_struct(50, 21660, "Members: Bane bolts" + "
" + " (after Ritual of the Mahjarrat)", "Members now have the Ranged level required to shoot " + "" + "bane bolts" + "" + ", Ranged weapons used for effectively killing specific creatures. (after Ritual of the Mahjarrat.)"); + case 11: + return newstruct cs2func_script_1010_struct(75, 15241, "Members: Chaos dwarf hand cannon" + "
" + " (with 61 Firemaking and after Forgiveness of a Chaos Dwarf)", "Members now have the Ranged level required to fire the " + "" + "chaos dwarf hand cannon" + "" + " (after Forgiveness of a Chaos Dwarf and with 61 Firemaking)."); + } + break; + case 8: + switch (arg1) { + case 0: + return newstruct cs2func_script_1010_struct(1, 14192, "Members: Stealing Creation - class 1 bow", "Members can now wield " + "" + "class 1 bows" + "" + " in Stealing Creation."); + case 1: + return newstruct cs2func_script_1010_struct(1, 14411, "Members: Stealing Creation - class 1 coif", "Members can now wear " + "" + "class 1 coifs" + "" + " in Stealing Creation."); + case 2: + return newstruct cs2func_script_1010_struct(1, 14391, "Members: Stealing Creation - class 1 leather body", "Members can now wear " + "" + "class 1 leather bodies" + "" + " in Stealing Creation."); + case 3: + return newstruct cs2func_script_1010_struct(1, 14401, "Members: Stealing Creation - class 1 chaps", "Members can now wear " + "" + "class 1 chaps" + "" + " in Stealing Creation."); + case 4: + return newstruct cs2func_script_1010_struct(20, 14194, "Members: Stealing Creation - class 2 bow", "Members can now wield " + "" + "class 2 bows" + "" + " in Stealing Creation."); + case 5: + return newstruct cs2func_script_1010_struct(20, 14413, "Members: Stealing Creation - class 2 coif", "Members can now wear " + "" + "class 2 coifs" + "" + " in Stealing Creation."); + case 6: + return newstruct cs2func_script_1010_struct(20, 14393, "Members: Stealing Creation - class 2 leather body", "Members can now wear " + "" + "class 2 leather bodies" + "" + " in Stealing Creation."); + case 7: + return newstruct cs2func_script_1010_struct(20, 14403, "Members: Stealing Creation - class 2 chaps", "Members can now wear " + "" + "class 2 chaps" + "" + " in Stealing Creation."); + case 8: + return newstruct cs2func_script_1010_struct(40, 14196, "Members: Stealing Creation - class 3 bow", "Members can now wield " + "" + "class 3 bows" + "" + " in Stealing Creation."); + case 9: + return newstruct cs2func_script_1010_struct(40, 14415, "Members: Stealing Creation - class 3 coif", "Members can now wear " + "" + "class 3 coifs" + "" + " in Stealing Creation."); + case 10: + return newstruct cs2func_script_1010_struct(40, 14395, "Members: Stealing Creation - class 3 leather body", "Members can now wear " + "" + "class 3 leather bodies" + "" + " in Stealing Creation."); + case 11: + return newstruct cs2func_script_1010_struct(40, 14405, "Members: Stealing Creation - class 3 chaps", "Members can now wear " + "" + "class 3 chaps" + "" + " in Stealing Creation."); + case 12: + return newstruct cs2func_script_1010_struct(60, 14198, "Members: Stealing Creation - class 4 bow", "Members can now wield " + "" + "class 4 bows" + "" + " in Stealing Creation."); + case 13: + return newstruct cs2func_script_1010_struct(60, 14417, "Members: Stealing Creation - class 4 coif", "Members can now wear " + "" + "class 4 coifs" + "" + " in Stealing Creation."); + case 14: + return newstruct cs2func_script_1010_struct(60, 14397, "Members: Stealing Creation - class 4 leather body", "Members can now wear " + "" + "class 4 leather bodies" + "" + " in Stealing Creation."); + case 15: + return newstruct cs2func_script_1010_struct(60, 14407, "Members: Stealing Creation - class 4 chaps", "Members can now wear " + "" + "class 4 chaps" + "" + " in Stealing Creation."); + case 16: + return newstruct cs2func_script_1010_struct(80, 14200, "Members: Stealing Creation - class 5 bow", "Members can now wield " + "" + "class 5 bows" + "" + " in Stealing Creation."); + case 17: + return newstruct cs2func_script_1010_struct(80, 14419, "Members: Stealing Creation - class 5 coif", "Members can now wear " + "" + "class 5 coifs" + "" + " in Stealing Creation."); + case 18: + return newstruct cs2func_script_1010_struct(80, 14399, "Members: Stealing Creation - class 5 leather body", "Members can now wear " + "" + "class 5 leather bodies" + "" + " in Stealing Creation."); + case 19: + return newstruct cs2func_script_1010_struct(80, 14409, "Members: Stealing Creation - class 5 chaps", "Members can now wear " + "" + "class 5 chaps" + "" + " in Stealing Creation."); + case 20: + return newstruct cs2func_script_1010_struct(85, 21547, "Members: Trickster hood" + "
" + " (with 85 Defence and 85 Magic)", "Members now have the Ranged requirement to wear " + "" + "Trickster hoods" + "" + ". (They also need level 85 Defence and level 85 Magic)"); + case 21: + return newstruct cs2func_script_1010_struct(85, 21549, "Members: Trickster robe" + "
" + " (with 85 Defence and 85 Magic)", "Members now have the Ranged requirement to wear " + "" + "Trickster robes" + "" + ". (They also need level 85 Defence and level 85 Magic)"); + case 22: + return newstruct cs2func_script_1010_struct(85, 21551, "Members: Trickster legs" + "
" + " (with 85 Defence and 85 Magic)", "Members now have the Ranged requirement to wear " + "" + "Trickster legs" + "" + ". (They also need level 85 Defence and level 85 Magic)"); + case 23: + return newstruct cs2func_script_1010_struct(85, 21553, "Members: Trickster gloves" + "
" + " (with 85 Defence and 85 Magic)", "Members now have the Ranged requirement to wear " + "" + "Trickster gloves" + "" + ". (They also need level 85 Defence and level 85 Magic)"); + case 24: + return newstruct cs2func_script_1010_struct(85, 21555, "Members: Trickster boots" + "
" + " (with 85 Defence and 85 Magic)", "Members now have the Ranged requirement to wear " + "" + "Trickster boots" + "" + ". (They also need level 85 Defence and level 85 Magic)"); + case 25: + return newstruct cs2func_script_1010_struct(85, 21557, "Members: Vanguard helm" + "
" + " (with 85 Defence and 85 Strength)", "Members now have the Ranged requirement to wear " + "" + "Vanguard helms" + "" + ". (They also need level 85 Defence and level 85 Strength.)"); + case 26: + return newstruct cs2func_script_1010_struct(85, 21559, "Members: Vanguard body" + "
" + " (with 85 Defence and 85 Strength)", "Members now have the Ranged requirement to wear " + "" + "Vanguard body armour" + "" + ". (They also need level 85 Defence and level 85 Strength.)"); + case 27: + return newstruct cs2func_script_1010_struct(85, 21561, "Members: Vanguard legs" + "
" + " (with 85 Defence and 85 Strength)", "Members now have the Ranged requirement to wear " + "" + "Vanguard leg armour" + "" + ". (They also need level 85 Defence and level 85 Strength.)"); + case 28: + return newstruct cs2func_script_1010_struct(85, 21563, "Members: Vanguard gloves" + "
" + " (with 85 Defence and 85 Strength)", "Members now have the Ranged requirement to wear " + "" + "Vanguard gloves" + "" + ". (They also need level 85 Defence and level 85 Strength.)"); + case 29: + return newstruct cs2func_script_1010_struct(85, 21565, "Members: Vanguard boots" + "
" + " (with 85 Defence and 85 Strength)", "Members now have the Ranged requirement to wear " + "" + "Vanguard boots" + "" + ". (They also need level 85 Defence and level 85 Strength.)"); + } + break; + case 9: + switch (arg1) { + case 0: + return newstruct cs2func_script_1010_struct(-1, 15707, "Dungeoneering skill tasks" + "
" + "As your Ranged level increases, you will be able to attempt higher-level ranged tasks within Daemonheim. You will also be more likely to succeed when attempting ranged tasks within Daemonheim.", ""); + case 1: + return newstruct cs2func_script_1010_struct(1, 16867, "Tangle gum shortbow (Tier 1)", "You can now wield " + "" + "tangle gum shortbows" + "" + " within Daemonheim."); + case 2: + return newstruct cs2func_script_1010_struct(1, 16317, "Tangle gum longbow (Tier 1)", "You can now wield " + "" + "tangle gum shortbows" + "" + " within Daemonheim."); + case 3: + return newstruct cs2func_script_1010_struct(1, 16427, "Novite arrows (Tier 1)", "You can now use " + "" + "novite arrows" + "" + " within Daemonheim."); + case 4: + return newstruct cs2func_script_1010_struct(1, 17041, "Protoleather coifs (Tier 1)" + "
" + " (with 1 Defence)", "You can now wear " + "" + "protoleather coif" + "" + " within Daemonheim. (You also need level 1 Defence.)"); + case 5: + return newstruct cs2func_script_1010_struct(1, 17173, "Protoleather body (Tier 1)" + "
" + " (with 1 Defence)", "You can now wear " + "" + "protoleather bodies" + "" + " within Daemonheim. (You also need level 1 Defence)."); + case 6: + return newstruct cs2func_script_1010_struct(1, 17319, "Protoleather chaps (Tier 1)" + "
" + " (with 1 Defence)", "You can now wear " + "" + "protoleather chaps" + "" + " within Daemonheim. (You also need level 1 Defence)."); + case 7: + return newstruct cs2func_script_1010_struct(1, 17195, "Protoleather vambraces (Tier 1)" + "
" + " (with 1 Defence)", "You can now wear " + "" + "protoleather vambraces" + "" + " within Daemonheim. (You also need level 1 Defence)."); + case 8: + return newstruct cs2func_script_1010_struct(1, 17297, "Protoleather boots (Tier 1)" + "
" + " (with 1 Defence)", "You can now wear " + "" + "protoleather boots" + "" + " within Daemonheim. (You also need level 1 Defence)."); + case 9: + return newstruct cs2func_script_1010_struct(10, 16869, "Seeping elm shortbow (Tier 2)", "You can now wield " + "" + "seeping elm shortbows" + "" + " within Daemonheim."); + case 10: + return newstruct cs2func_script_1010_struct(10, 16319, "Seeping elm longbow (Tier 2)", "You can now wield " + "" + "seeping elm longbows" + "" + " within Daemonheim."); + case 11: + return newstruct cs2func_script_1010_struct(10, 16432, "Bathus arrows (Tier 2)", "You can now use " + "" + "bathus arrows" + "" + " within Daemonheim."); + case 12: + return newstruct cs2func_script_1010_struct(10, 17043, "Subleather coifs (Tier 2)" + "
" + " (with 10 Defence)", "You can now wear " + "" + "subleather coif" + "" + " within Daemonheim. (You also need level 10 Defence)."); + case 13: + return newstruct cs2func_script_1010_struct(10, 17175, "Subleather body (Tier 2)" + "
" + " (with 10 Defence)", "You can now wear " + "" + "subleather bodies" + "" + " within Daemonheim. (You also need level 10 Defence)."); + case 14: + return newstruct cs2func_script_1010_struct(10, 17321, "Subleather chaps (Tier 2)" + "
" + " (with 10 Defence)", "You can now wear " + "" + "subleather chaps" + "" + " within Daemonheim. (You also need level 10 Defence)."); + case 15: + return newstruct cs2func_script_1010_struct(10, 17197, "Subleather vambraces (Tier 2)" + "
" + " (with 10 Defence)", "You can now wear " + "" + "subleather vambraces" + "" + " within Daemonheim. (You also need level 10 Defence)."); + case 16: + return newstruct cs2func_script_1010_struct(10, 17299, "Subleather boots (Tier 2)" + "
" + " (with 10 Defence)", "You can now wear " + "" + "subleather boots" + "" + " within Daemonheim. (You also need level 10 Defence)."); + case 17: + return newstruct cs2func_script_1010_struct(20, 16871, "Blood spindle shortbow (Tier 3)", "You can now wield " + "" + "blood spindle shortbows" + "" + " within Daemonheim."); + case 18: + return newstruct cs2func_script_1010_struct(20, 16321, "Blood spindle longbow (Tier 3)", "You can now wield " + "" + "blood spindle longbows" + "" + " within Daemonheim."); + case 19: + return newstruct cs2func_script_1010_struct(20, 16437, "Marmaros arrows (Tier 3)", "You can now use " + "" + "marmaros arrows" + "" + " within Daemonheim."); + case 20: + return newstruct cs2func_script_1010_struct(20, 17045, "Paraleather coif (Tier 3)" + "
" + " (with 20 Defence)", "You can now wear " + "" + "paraleather coifs" + "" + " within Daemonheim. (You also need level 20 Defence)."); + case 21: + return newstruct cs2func_script_1010_struct(20, 17177, "Paraleather body (Tier 3)" + "
" + " (with 20 Defence)", "You can now wear " + "" + "paraleather bodies" + "" + " within Daemonheim. (You also need level 20 Defence)."); + case 22: + return newstruct cs2func_script_1010_struct(20, 17323, "Paraleather chaps (Tier 3)" + "
" + " (with 20 Defence)", "You can now wear " + "" + "paraleather chaps" + "" + " within Daemonheim. (You also need level 20 Defence)."); + case 23: + return newstruct cs2func_script_1010_struct(20, 17199, "Paraleather vambraces (Tier 3)" + "
" + " (with 20 Defence)", "You can now wear " + "" + "paraleather vambraces" + "" + " within Daemonheim. (You also need level 20 Defence)."); + case 24: + return newstruct cs2func_script_1010_struct(20, 17301, "Paraleather boots (Tier 3)" + "
" + " (with 20 Defence)", "You can now wear " + "" + "paraleather boots" + "" + " within Daemonheim. (You also need level 20 Defence)."); + case 25: + return newstruct cs2func_script_1010_struct(30, 16873, "Utuku shortbow (Tier 4)", "You can now wield " + "" + "utuku shortbows" + "" + " within Daemonheim."); + case 26: + return newstruct cs2func_script_1010_struct(30, 16323, "Utuku longbow (Tier 4)", "You can now wield " + "" + "utuku longbows" + "" + " within Daemonheim."); + case 27: + return newstruct cs2func_script_1010_struct(30, 16442, "Kratonite arrows (Tier 4)", "You can now use " + "" + "kratonite arrows" + "" + " within Daemonheim."); + case 28: + return newstruct cs2func_script_1010_struct(30, 17047, "Archleather coif (Tier 4)" + "
" + " (with 30 Defence)", "You can now wear " + "" + "archleather coifs" + "" + " within Daemonheim. (You also need level 30 Defence)."); + case 29: + return newstruct cs2func_script_1010_struct(30, 17179, "Archleather body (Tier 4)" + "
" + " (with 30 Defence)", "You can now wear " + "" + "archleather bodies" + "" + " within Daemonheim. (You also need level 30 Defence)."); + case 30: + return newstruct cs2func_script_1010_struct(30, 17325, "Archleather chaps (Tier 4)" + "
" + " (with 30 Defence)", "You can now wear " + "" + "archleather chaps" + "" + " within Daemonheim. (You also need level 30 Defence)."); + case 31: + return newstruct cs2func_script_1010_struct(30, 17201, "Archleather vambraces (Tier 4)" + "
" + " (with 30 Defence)", "You can now wear " + "" + "archleather vambraces" + "" + " within Daemonheim. (You also need level 30 Defence)."); + case 32: + return newstruct cs2func_script_1010_struct(30, 17303, "Archleather boots (Tier 4)" + "
" + " (with 30 Defence)", "You can now wear " + "" + "archleather boots" + "" + " within Daemonheim. (You also need level 30 Defence)."); + case 33: + return newstruct cs2func_script_1010_struct(40, 16875, "Spinebeam shortbow (Tier 5)", "You can now wield " + "" + "spinebeam shortbows" + "" + " within Daemonheim."); + case 34: + return newstruct cs2func_script_1010_struct(40, 16325, "Spinebeam longbow (Tier 5)", "You can now wield " + "" + "spinebeam longbows" + "" + " within Daemonheim."); + case 35: + return newstruct cs2func_script_1010_struct(40, 16447, "Fractite arrows (Tier 5)", "You can now use " + "" + "fractite arrows" + "" + " within Daemonheim."); + case 36: + return newstruct cs2func_script_1010_struct(40, 17049, "Dromoleather coif (Tier 5)" + "
" + " (with 40 Defence)", "You can now wear " + "" + "dromoleather coifs" + "" + " within Daemonheim. (You also need level 40 Defence)."); + case 37: + return newstruct cs2func_script_1010_struct(40, 17181, "Dromoleather body (Tier 5)" + "
" + " (with 40 Defence)", "You can now wear " + "" + "dromoleather bodies" + "" + " within Daemonheim. (You also need level 40 Defence)."); + case 38: + return newstruct cs2func_script_1010_struct(40, 17327, "Dromoleather chaps (Tier 5)" + "
" + " (with 40 Defence)", "You can now wear " + "" + "dromoleather chaps" + "" + " within Daemonheim. (You also need level 40 Defence)."); + case 39: + return newstruct cs2func_script_1010_struct(40, 17203, "Dromoleather vambraces (Tier 5)" + "
" + " (with 40 Defence)", "You can now wear " + "" + "dromoleather vambraces" + "" + " within Daemonheim. (You also need level 40 Defence)."); + case 40: + return newstruct cs2func_script_1010_struct(40, 17305, "Dromoleather boots (Tier 5)" + "
" + " (with 40 Defence)", "You can now wear " + "" + "dromoleather boots" + "" + " within Daemonheim. (You also need level 40 Defence)."); + case 41: + return newstruct cs2func_script_1010_struct(50, 16877, "Members: Bovistrangler shortbow (Tier 6)", "Members can now wield " + "" + "bovistrangler shortbows" + "" + " within Daemonheim."); + case 42: + return newstruct cs2func_script_1010_struct(50, 16327, "Members: Bovistrangler longbow (Tier 6)", "Members can now wield " + "" + "bovistrangler longbows" + "" + " within Daemonheim."); + case 43: + return newstruct cs2func_script_1010_struct(50, 16452, "Members: Zephyrium arrows (Tier 6)", "Members can now use " + "" + "zephyrium arrows" + "" + " within Daemonheim."); + case 44: + return newstruct cs2func_script_1010_struct(50, 17051, "Members: Spinoleather coif (Tier 6)" + "
" + " (with 50 Defence)", "Members can now wear " + "" + "spinoleather coifs" + "" + " within Daemonheim. (They also need level 50 Defence)."); + case 45: + return newstruct cs2func_script_1010_struct(50, 17183, "Members: Spinoleather body (Tier 6)" + "
" + " (with 50 Defence)", "Members can now wear " + "" + "spinoleather bodies" + "" + " within Daemonheim. (They also need level 50 Defence)."); + case 46: + return newstruct cs2func_script_1010_struct(50, 17329, "Members: Spinoleather chaps (Tier 6)" + "
" + " (with 50 Defence)", "Members can now wear " + "" + "spinoleather chaps" + "" + " within Daemonheim. (They also need level 50 Defence)."); + case 47: + return newstruct cs2func_script_1010_struct(50, 17205, "Members: Spinoleather vambraces (Tier 6)" + "
" + " (with 50 Defence)", "Members can now wear " + "" + "spinoleather vambraces" + "" + " within Daemonheim. (They also need level 50 Defence)."); + case 48: + return newstruct cs2func_script_1010_struct(50, 17307, "Members: Spinoleather boots (Tier 6)" + "
" + " (with 50 Defence)", "Members can now wear " + "" + "spinoleather boots" + "" + " within Daemonheim. (They also need level 50 Defence)."); + case 49: + return newstruct cs2func_script_1010_struct(60, 16879, "Members: Thigat shortbow (Tier 7)", "Members can now wield " + "" + "thigat shortbows" + "" + " within Daemonheim."); + case 50: + return newstruct cs2func_script_1010_struct(60, 16329, "Members: Thigat longbow (Tier 7)", "Members can now wield " + "" + "thigat longbows" + "" + " within Daemonheim."); + case 51: + return newstruct cs2func_script_1010_struct(60, 16457, "Members: Argonite arrows (Tier 7)", "Members can now use " + "" + "argonite arrows" + "" + " within Daemonheim."); + case 52: + return newstruct cs2func_script_1010_struct(60, 17053, "Members: Gallileather coif (Tier 7)" + "
" + " (with 60 Defence)", "Members can now wear " + "" + "gallileather coifs" + "" + " within Daemonheim. (They also need level 60 Defence)."); + case 53: + return newstruct cs2func_script_1010_struct(60, 17185, "Members: Gallileather body (Tier 7)" + "
" + " (with 60 Defence)", "Members can now wear " + "" + "gallileather bodies" + "" + " within Daemonheim. (They also need level 60 Defence)."); + case 54: + return newstruct cs2func_script_1010_struct(60, 17331, "Members: Gallileather chaps (Tier 7)" + "
" + " (with 60 Defence)", "Members can now wear " + "" + "gallileather chaps" + "" + " within Daemonheim. (They also need level 60 Defence)."); + case 55: + return newstruct cs2func_script_1010_struct(60, 17207, "Members: Gallileather vambraces (Tier 7)" + "
" + " (with 60 Defence)", "Members can now wear " + "" + "gallileather vambraces" + "" + " within Daemonheim. (They also need level 60 Defence)."); + case 56: + return newstruct cs2func_script_1010_struct(60, 17309, "Members: Gallileather boots (Tier 7)" + "
" + " (with 60 Defence)", "Members can now wear " + "" + "gallileather boots" + "" + " within Daemonheim. (They also need level 60 Defence)."); + case 57: + return newstruct cs2func_script_1010_struct(70, 16881, "Members: Corpsethorn shortbow (Tier 8)", "Members can now wield " + "" + "corpsethorn shortbows" + "" + " within Daemonheim."); + case 58: + return newstruct cs2func_script_1010_struct(70, 16331, "Members: Corpsethorn longbow (Tier 8)", "Members can now wield " + "" + "corpsethorn longbows" + "" + " within Daemonheim."); + case 59: + return newstruct cs2func_script_1010_struct(70, 16462, "Members: Katagon arrows (Tier 8)", "Members can now use " + "" + "katagon arrows" + "" + " within Daemonheim."); + case 60: + return newstruct cs2func_script_1010_struct(70, 17055, "Members: Stegoleather coif (Tier 8)" + "
" + " (with 70 Defence)", "Members can now wear " + "" + "stegoleather coifs" + "" + " within Daemonheim. (They also need level 70 Defence)."); + case 61: + return newstruct cs2func_script_1010_struct(70, 17187, "Members: Stegoleather body (Tier 8)" + "
" + " (with 70 Defence)", "Members can now wear " + "" + "stegoleather bodies" + "" + " within Daemonheim. (They also need level 70 Defence)."); + case 62: + return newstruct cs2func_script_1010_struct(70, 17333, "Members: Stegoleather chaps (Tier 8)" + "
" + " (with 70 Defence)", "Members can now wear " + "" + "stegoleather chaps" + "" + " within Daemonheim. (They also need level 70 Defence)."); + case 63: + return newstruct cs2func_script_1010_struct(70, 17209, "Members: Stegoleather vambraces (Tier 8)" + "
" + " (with 70 Defence)", "Members can now wear " + "" + "stegoleather vambraces" + "" + " within Daemonheim. (They also need level 70 Defence)."); + case 64: + return newstruct cs2func_script_1010_struct(70, 17311, "Members: Stegoleather boots (Tier 8)" + "
" + " (with 70 Defence)", "Members can now wear " + "" + "stegoleather boots" + "" + " within Daemonheim. (They also need level 70 Defence)."); + case 65: + return newstruct cs2func_script_1010_struct(80, 16883, "Members: Entgallow shortbow (Tier 9)", "Members can now wield " + "" + "entgallow shortbows" + "" + " within Daemonheim."); + case 66: + return newstruct cs2func_script_1010_struct(80, 16333, "Members: Entgallow longbow (Tier 9)", "Members can now wield " + "" + "entgallow longbows" + "" + " within Daemonheim."); + case 67: + return newstruct cs2func_script_1010_struct(80, 16467, "Members: Gorgonite arrows (Tier 9)", "Members can now use " + "" + "gorgonite arrows" + "" + " within Daemonheim."); + case 68: + return newstruct cs2func_script_1010_struct(80, 17057, "Members: Megaleather coif (Tier 9)" + "
" + " (with 80 Defence)", "Members can now wear " + "" + "megaleather coifs" + "" + " within Daemonheim. (They also need level 80 Defence)."); + case 69: + return newstruct cs2func_script_1010_struct(80, 17189, "Members: Megaleather body (Tier 9)" + "
" + " (with 80 Defence)", "Members can now wear " + "" + "megaleather bodies" + "" + " within Daemonheim. (They also need level 80 Defence)."); + case 70: + return newstruct cs2func_script_1010_struct(80, 17335, "Members: Megaleather chaps (Tier 9)" + "
" + " (with 80 Defence)", "Members can now wear " + "" + "megaleather chaps" + "" + " within Daemonheim. (They also need level 80 Defence)."); + case 71: + return newstruct cs2func_script_1010_struct(80, 17211, "Members: Megaleather vambraces (Tier 9)" + "
" + " (with 80 Defence)", "Members can now wear " + "" + "megaleather vambraces" + "" + " within Daemonheim. (They also need level 80 Defence)."); + case 72: + return newstruct cs2func_script_1010_struct(80, 17313, "Members: Megaleather boots (Tier 9)" + "
" + " (with 80 Defence)", "Members can now wear " + "" + "megaleather boots" + "" + " within Daemonheim. (They also need level 80 Defence)."); + case 73: + return newstruct cs2func_script_1010_struct(83, 17283, "Members: Grounding boots" + "
" + " (with 83 Defence)", "Members can now wear " + "" + "grounding boots" + "" + " within Daemonheim. (They also need level 83 Defence.)"); + case 74: + return newstruct cs2func_script_1010_struct(90, 16885, "Members: Grave creeper shortbow (Tier 10)", "Members can now wield " + "" + "grave creeper shortbows" + "" + " within Daemonheim."); + case 75: + return newstruct cs2func_script_1010_struct(90, 16335, "Members: Grave creeper longbow (Tier 10)", "Members can now wield " + "" + "grave creeper longbows" + "" + " within Daemonheim."); + case 76: + return newstruct cs2func_script_1010_struct(90, 16472, "Members: Promethium arrows (Tier 10)", "Members can now use " + "" + "promethium arrows" + "" + " within Daemonheim."); + case 77: + return newstruct cs2func_script_1010_struct(90, 17059, "Members: Tyrannoleather coif (Tier 10)" + "
" + " (with 90 Defence)", "Members can now wear " + "" + "tyrannoleather coifs" + "" + " within Daemonheim. (They also need level 90 Defence)."); + case 78: + return newstruct cs2func_script_1010_struct(90, 17191, "Members: Tyrannoleather body (Tier 10)" + "
" + " (with 90 Defence)", "Members can now wear " + "" + "tyrannoleather bodies" + "" + " within Daemonheim. (They also need level 90 Defence)."); + case 79: + return newstruct cs2func_script_1010_struct(90, 17337, "Members: Tyrannoleather chaps (Tier 10)" + "
" + " (with 90 Defence)", "Members can now wear " + "" + "tyrannoleather chaps" + "" + " within Daemonheim. (They also need level 90 Defence)."); + case 80: + return newstruct cs2func_script_1010_struct(90, 17213, "Members: Tyrannoleather vambraces (Tier 10)" + "
" + " (with 90 Defence)", "Members can now wear " + "" + "tyrannoleather vambraces" + "" + " within Daemonheim. (They also need level 90 Defence)."); + case 81: + return newstruct cs2func_script_1010_struct(90, 17315, "Members: Tyrannoleather boots (Tier 10)" + "
" + " (with 90 Defence)", "Members can now wear " + "" + "tyrannoleather boots" + "" + " within Daemonheim. (They also need level 90 Defence)."); + case 82: + return newstruct cs2func_script_1010_struct(98, 17295, "Members: Hexhunter bow", "Members can now wield " + "" + "hexhunter shortbows" + "" + " within Daemonheim."); + case 83: + return newstruct cs2func_script_1010_struct(99, 16887, "Members: Sagittarian shortbow (Tier 11)", "Members can now wield " + "" + "sagittarian shortbows" + "" + " within Daemonheim."); + case 84: + return newstruct cs2func_script_1010_struct(99, 16337, "Members: Sagittarian longbow (Tier 11)", "Members can now wield " + "" + "sagittarian longbows" + "" + " within Daemonheim."); + case 85: + return newstruct cs2func_script_1010_struct(99, 16477, "Members: Sagittarian arrows (Tier 11)", "Members can now use " + "" + "sagittarian arrows" + "" + " within Daemonheim."); + case 86: + return newstruct cs2func_script_1010_struct(99, 17061, "Members: Sagittarian coif (Tier 11)" + "
" + " (with 99 Defence)", "Members can now wear " + "" + "sagittarian coifs" + "" + " within Daemonheim. (They also need level 99 Defence)."); + case 87: + return newstruct cs2func_script_1010_struct(99, 17193, "Members: Sagittarian body (Tier 11)" + "
" + " (with 99 Defence)", "Members can now wear " + "" + "sagittarian bodies" + "" + " within Daemonheim. (They also need level 99 Defence)."); + case 88: + return newstruct cs2func_script_1010_struct(99, 17339, "Members: Sagittarian chaps (Tier 11)" + "
" + " (with 99 Defence)", "Members can now wear " + "" + "sagittarian chaps" + "" + " within Daemonheim. (They also need level 99 Defence)."); + case 89: + return newstruct cs2func_script_1010_struct(99, 17215, "Members: Sagittarian vambraces (Tier 11)" + "
" + " (with 99 Defence)", "Members can now wear " + "" + "sagittarian vambraces" + "" + " within Daemonheim. (They also need level 99 Defence)."); + case 90: + return newstruct cs2func_script_1010_struct(99, 17317, "Members: Sagittarian boots (Tier 11)" + "
" + " (with 99 Defence)", "Members can now wear " + "" + "sagittarian boots" + "" + " within Daemonheim. (They also need level 99 Defence)."); + } + break; + case 10: + SWITCH (arg1) { + case 0: + GOTO flow_311 + case 1: + GOTO flow_312 + } + break; + flow_311: + return newstruct cs2func_script_1010_struct(40, 8164, "Members: Ranging Guild", "Members can now enter the prestigious " + "" + "Ranging Guild" + "" + " in Hemenster and play the " + "" + "Target Practice" + "" + " game there."); + flow_312: + return newstruct cs2func_script_1010_struct(99, 9756, "Skill mastery", "" + "Congratulations! You are now a master of " + "" + "Ranged" + "" + ". Members can visit the " + "" + "armour salesman" + "" + " at the " + "" + "Ranging Guild" + "" + ". He has something special only available to true masters of the " + "" + "Ranged" + "" + " skill!"); + } + return newstruct cs2func_script_1010_struct(0, -1, "", ""); +} diff --git a/dumps/scripts/1011.cs2 b/dumps/scripts/1011.cs2 new file mode 100644 index 0000000..3cd01a9 --- /dev/null +++ b/dumps/scripts/1011.cs2 @@ -0,0 +1,19 @@ +cs2func_script_1011_struct(1,1,0) script_1011(int arg0) { + switch (arg0) { + case 0: + return newstruct cs2func_script_1011_struct(0, "Runes"); + case 1: + return newstruct cs2func_script_1011_struct(0, "Multiple Runes"); + case 2: + return newstruct cs2func_script_1011_struct(0, "Equipment"); + case 3: + return newstruct cs2func_script_1011_struct(0, "Other"); + case 4: + return newstruct cs2func_script_1011_struct(0, "Minigames"); + case 5: + return newstruct cs2func_script_1011_struct(0, "Dungeoneering"); + case 6: + return newstruct cs2func_script_1011_struct(0, "Milestones"); + } + return newstruct cs2func_script_1011_struct(-1, ""); +} diff --git a/dumps/scripts/1012.cs2 b/dumps/scripts/1012.cs2 new file mode 100644 index 0000000..410e835 --- /dev/null +++ b/dumps/scripts/1012.cs2 @@ -0,0 +1,220 @@ +cs2func_script_1012_struct(2,2,0) script_1012(int arg0,int arg1) { + switch (arg0) { + flow_1: + case 0: + switch (arg1) { + case 0: + return newstruct cs2func_script_1012_struct(-1, 7620, "To mine rune essence, you must have started Rune Mysteries.", ""); + case 1: + return newstruct cs2func_script_1012_struct(1, 556, "Air runes", "You can now craft " + "" + "air runes" + "" + "."); + case 2: + return newstruct cs2func_script_1012_struct(2, 558, "Mind runes", "You can now craft " + "" + "mind runes" + "" + "."); + case 3: + return newstruct cs2func_script_1012_struct(5, 555, "Water runes", "You can now craft " + "" + "water runes" + "" + "."); + case 4: + return newstruct cs2func_script_1012_struct(6, 4695, "Members: Mist runes", "Members can now craft " + "" + "mist runes" + "" + "."); + case 5: + return newstruct cs2func_script_1012_struct(9, 557, "Earth runes", "You can now craft " + "" + "earth runes" + "" + "."); + case 6: + return newstruct cs2func_script_1012_struct(10, 4696, "Members: Dust runes", "Members can now craft " + "" + "dust runes" + "" + "."); + case 7: + return newstruct cs2func_script_1012_struct(13, 4698, "Members: Mud runes", "Members can now craft " + "" + "mud runes" + "" + "."); + case 8: + return newstruct cs2func_script_1012_struct(14, 554, "Fire runes", "You can now craft " + "" + "fire runes" + "" + "."); + case 9: + return newstruct cs2func_script_1012_struct(15, 4697, "Members: Smoke runes", "Members can now craft " + "" + "smoke runes" + "" + "."); + case 10: + return newstruct cs2func_script_1012_struct(19, 4694, "Members: Steam runes", "Members can now craft " + "" + "steam runes" + "" + "."); + case 11: + return newstruct cs2func_script_1012_struct(20, 559, "Body runes", "You can now craft " + "" + "body runes" + "" + "."); + case 12: + return newstruct cs2func_script_1012_struct(23, 4699, "Members: Lava runes", "Members can now craft " + "" + "lava runes" + "" + "."); + case 13: + return newstruct cs2func_script_1012_struct(27, 564, "Members: Cosmic runes", "Members can now craft " + "" + "cosmic runes" + "" + "."); + case 14: + return newstruct cs2func_script_1012_struct(35, 562, "Members: Chaos runes", "Members can now craft " + "" + "chaos runes" + "" + "."); + case 15: + return newstruct cs2func_script_1012_struct(40, 9075, "Members: Astral runes" + "
" + " (after Lunar Diplomacy)", "Members now have the Runecrafting level required to craft " + "" + "astral runes" + "" + " (after Lunar Diplomacy, or when in Daemonheim)."); + case 16: + return newstruct cs2func_script_1012_struct(44, 561, "Members: Nature runes", "Members can now craft " + "" + "nature runes" + "" + "."); + case 17: + return newstruct cs2func_script_1012_struct(54, 563, "Members: Law runes", "Members can now craft " + "" + "law runes" + "" + "."); + case 18: + return newstruct cs2func_script_1012_struct(65, 560, "Members: Death runes" + "
" + " (after Mourning's Ends Part II)", "Members now have the Runecrafting level required to craft " + "" + "death runes" + "" + " (after Mourning's Ends Part II, or when in Daemonheim)."); + case 19: + return newstruct cs2func_script_1012_struct(72, 21773, "Members: Armadyl runes" + "
" + " (after Ritual of the Mahjarrat)", "Members can now craft " + "" + "Armadyl runes" + "" + " (after Ritual of the Mahjarrat)."); + case 20: + return newstruct cs2func_script_1012_struct(77, 565, "Members: Blood runes" + "
" + " (after Legacy of Seergaze)", "Members now have the Runecrafting level required to craft " + "" + "blood runes" + "" + " (after Legacy of Seergaze, or when in Daemonheim)."); + } + break; + case 1: + switch (arg1) { + case 0: + return newstruct cs2func_script_1012_struct(-1, 7620, "As your Runecrafting skill develops, you will be able to craft multiple runes from one piece of essence. You only receive experience for each piece of essence crafted, not each rune crafted.", " "); + case 1: + return newstruct cs2func_script_1012_struct(11, 556, "2 Air runes per essence", "You can now craft " + "" + "2 air runes" + "" + " from one piece of essence."); + case 2: + return newstruct cs2func_script_1012_struct(14, 558, "2 Mind runes per essence", "You can now craft " + "" + "2 mind runes" + "" + " from one piece of essence."); + case 3: + return newstruct cs2func_script_1012_struct(19, 555, "2 Water runes per essence", "You can now craft " + "" + "2 water runes" + "" + " from one piece of essence."); + case 4: + return newstruct cs2func_script_1012_struct(22, 556, "3 Air runes per essence", "You can now craft " + "" + "3 air runes" + "" + " from one piece of essence."); + case 5: + return newstruct cs2func_script_1012_struct(26, 557, "2 Earth runes per essence", "You can now craft " + "" + "2 earth runes" + "" + " from one piece of essence."); + case 6: + return newstruct cs2func_script_1012_struct(28, 558, "3 Mind runes per essence", "You can now craft " + "" + "3 mind runes" + "" + " from one piece of essence."); + case 7: + return newstruct cs2func_script_1012_struct(33, 556, "4 Air runes per essence", "You can now craft " + "" + "4 air runes" + "" + " from one piece of essence."); + case 8: + return newstruct cs2func_script_1012_struct(35, 554, "2 Fire runes per essence", "You can now craft " + "" + "2 fire runes" + "" + " from one piece of essence."); + case 9: + return newstruct cs2func_script_1012_struct(38, 555, "3 Water runes per essence", "You can now craft " + "" + "3 water runes" + "" + " from one piece of essence."); + case 10: + return newstruct cs2func_script_1012_struct(42, 558, "4 Mind runes per essence", "You can now craft " + "" + "4 mind runes" + "" + " from one piece of essence."); + case 11: + return newstruct cs2func_script_1012_struct(44, 556, "5 Air runes per essence", "You can now craft " + "" + "5 air runes" + "" + " from one piece of essence."); + case 12: + return newstruct cs2func_script_1012_struct(46, 559, "2 Body runes per essence", "You can now craft " + "" + "2 body runes" + "" + " from one piece of essence."); + case 13: + return newstruct cs2func_script_1012_struct(52, 557, "3 Earth runes per essence", "You can now craft " + "" + "3 earth runes" + "" + " from one piece of essence."); + case 14: + return newstruct cs2func_script_1012_struct(55, 556, "6 Air runes per essence", "You can now craft " + "" + "6 air runes" + "" + " from one piece of essence."); + case 15: + return newstruct cs2func_script_1012_struct(56, 558, "5 Mind runes per essence", "You can now craft " + "" + "5 mind runes" + "" + " from one piece of essence."); + case 16: + return newstruct cs2func_script_1012_struct(57, 555, "4 Water runes per essence", "You can now craft " + "" + "4 water runes" + "" + " from one piece of essence."); + case 17: + return newstruct cs2func_script_1012_struct(59, 564, "Members: 2 Cosmic runes per essence", "Members can now craft " + "" + "2 cosmic runes" + "" + " from one piece of essence."); + case 18: + return newstruct cs2func_script_1012_struct(66, 556, "7 Air runes per essence", "You can now craft " + "" + "7 air runes" + "" + " from one piece of essence."); + case 19: + return newstruct cs2func_script_1012_struct(70, 558, "6 Mind runes per essence", "You can now craft " + "" + "6 mind runes" + "" + " from one piece of essence."); + case 20: + return newstruct cs2func_script_1012_struct(70, 554, "3 Fire runes per essence", "You can now craft " + "" + "3 fire runes" + "" + " from one piece of essence."); + case 21: + return newstruct cs2func_script_1012_struct(74, 562, "Members: 2 Chaos runes per essence", "Members can now craft " + "" + "2 chaos runes" + "" + " from one piece of essence."); + case 22: + return newstruct cs2func_script_1012_struct(76, 555, "5 Water runes per essence", "You can now craft " + "" + "5 water runes" + "" + " from one piece of essence."); + case 23: + return newstruct cs2func_script_1012_struct(77, 556, "8 Air runes per essence", "You can now craft " + "" + "8 air runes" + "" + " from one piece of essence."); + case 24: + return newstruct cs2func_script_1012_struct(78, 557, "4 Earth runes per essence", "You can now craft " + "" + "4 earth runes" + "" + " from one piece of essence."); + case 25: + return newstruct cs2func_script_1012_struct(82, 9075, "Members: 2 Astral runes per essence", "Members can now craft " + "" + "2 astral runes" + "" + " from one piece of essence."); + case 26: + return newstruct cs2func_script_1012_struct(84, 558, "7 Mind runes per essence", "You can now craft " + "" + "7 mind runes" + "" + " from one piece of essence."); + case 27: + return newstruct cs2func_script_1012_struct(88, 556, "9 Air runes per essence", "You can now craft " + "" + "9 air runes" + "" + " from one piece of essence."); + case 28: + return newstruct cs2func_script_1012_struct(91, 561, "Members: 2 Nature runes per essence", "Members can now craft " + "" + "2 nature runes" + "" + " from one piece of essence."); + case 29: + return newstruct cs2func_script_1012_struct(92, 559, "3 Body runes per essence", "You can now craft " + "" + "3 body runes" + "" + " from one piece of essence."); + case 30: + return newstruct cs2func_script_1012_struct(95, 555, "6 Water runes per essence", "You can now craft " + "" + "6 water runes" + "" + " from one piece of essence."); + case 31: + return newstruct cs2func_script_1012_struct(98, 558, "8 Mind runes per essence", "You can now craft " + "" + "8 mind runes" + "" + " from one piece of essence."); + case 32: + return newstruct cs2func_script_1012_struct(99, 556, "10 Air runes per essence", "You can now craft " + "" + "10 air runes" + "" + " from one piece of essence."); + } + break; + case 2: + switch (arg1) { + case 0: + return newstruct cs2func_script_1012_struct(-1, 7620, "Pouches allow you to carry extra essence in them and they come in various sizes. As you use the pouches, they degrade and store less essence. Speak to the Dark Mage at the centre of the Abyss to restore them.", ""); + case 1: + return newstruct cs2func_script_1012_struct(1, 5509, "Members: Small pouch" + "
" + "Holds 3 extra essence", "Members can now use " + "" + "small pouches" + "" + " to store 3 essence."); + case 2: + return newstruct cs2func_script_1012_struct(10, 12863, "Air rune crafting gloves", "You can now wear " + "" + "air rune crafting gloves" + "" + "."); + case 3: + return newstruct cs2func_script_1012_struct(20, 12864, "Water rune crafting gloves", "You can now wear " + "" + "water rune crafting gloves" + "" + "."); + case 4: + return newstruct cs2func_script_1012_struct(25, 5510, "Members: Medium pouch" + "
" + "Holds 6 extra essence", "Members can now use " + "" + "medium pouches" + "" + " to store 6 essence."); + case 5: + return newstruct cs2func_script_1012_struct(30, 12865, "Earth rune crafting gloves", "You can now wear " + "" + "earth rune crafting gloves" + "" + "."); + case 6: + return newstruct cs2func_script_1012_struct(35, 19671, "Magical blastbox" + "
" + " (with 30 Dungeoneering and 30 Magic)", "You can now use " + "" + "magical blastboxes" + "" + ". (You also need level 30 Dungeoneering and 30 Magic.)"); + case 7: + return newstruct cs2func_script_1012_struct(50, 5512, "Members: Large pouch" + "
" + "Holds 9 extra essence", "Members can now use " + "" + "large pouches" + "" + " to store 9 essence."); + case 8: + return newstruct cs2func_script_1012_struct(50, 21517, "Members: Master Runecrafter hat", "Members can now wear " + "" + "Master Runecrafter hats" + "" + "."); + case 9: + return newstruct cs2func_script_1012_struct(50, 21516, "Members: Master Runecrafter robe", "Members can now wear " + "" + "Master Runecrafter robes" + "" + "."); + case 10: + return newstruct cs2func_script_1012_struct(50, 21518, "Members: Master Runecrafter legs", "Members can now wear " + "" + "Master Runecrafter legs" + "" + "."); + case 11: + return newstruct cs2func_script_1012_struct(50, 21519, "Members: Master Runecrafter boots", "Members can now wear " + "" + "Master Runecrafter boots" + "" + "."); + case 12: + return newstruct cs2func_script_1012_struct(70, 19889, "Members: Celestial surgebox" + "
" + " (with 70 Magic and 70 Dungeoneering)", "Members can now use " + "" + "celestial surgeboxes" + "" + ". (They also need level 70 Magic and level 70 Dungeoneering.)"); + case 13: + return newstruct cs2func_script_1012_struct(75, 5514, "Members: Giant pouch" + "
" + "Holds 12 extra essence", "Members can now use " + "" + "giant pouches" + "" + " to store 12 essence."); + } + break; + case 3: + switch (arg1) { + case 0: + return newstruct cs2func_script_1012_struct(91, 18778, "Members: Starved ancient effigies", "Members can now investigate " + "" + "starved ancient effigies" + "" + " using their knowledge of Runecrafting."); + case 1: + return newstruct cs2func_script_1012_struct(93, 18779, "Members: Nourished ancient effigies", "Members can now investigate " + "" + "nourished ancient effigies" + "" + " using their knowledge of Runecrafting."); + case 2: + return newstruct cs2func_script_1012_struct(95, 18780, "Members: Sated ancient effigies", "Members can now investigate " + "" + "sated ancient effigies" + "" + " using their knowledge of Runecrafting."); + case 3: + return newstruct cs2func_script_1012_struct(97, 18781, "Members: Gorged ancient effigies", "Members can now investigate " + "" + "gorged ancient effigies" + "" + " using their knowledge of Runecrafting."); + } + break; + case 4: + switch (arg1) { + case 0: + return newstruct cs2func_script_1012_struct(1, 12851, "Members: Stealing Creation - class 1 sacred clay", "Members can now craft runes from class 1 sacred clay in Stealing Creation."); + case 1: + return newstruct cs2func_script_1012_struct(20, 12851, "Members: Stealing Creation - class 2 sacred clay", "Members can now craft runes from class 2 sacred clay in Stealing Creation."); + case 2: + return newstruct cs2func_script_1012_struct(40, 12851, "Members: Stealing Creation - class 3 sacred clay", "Members can now craft runes from class 3 sacred clay in Stealing Creation."); + case 3: + return newstruct cs2func_script_1012_struct(60, 12851, "Members: Stealing Creation - class 4 sacred clay", "Members can now craft runes from class 4 sacred clay in Stealing Creation."); + case 4: + return newstruct cs2func_script_1012_struct(75, 21536, "Members: Pyramid Plunder - Engraved Sarcophagus", "Members can now open the engraved sarcophagus in Pyramid Plunder."); + case 5: + return newstruct cs2func_script_1012_struct(80, 12851, "Members: Stealing Creation - class 5 sacred clay", "Members can now craft runes from class 5 sacred clay in Stealing Creation."); + } + break; + case 5: + switch (arg1) { + case 0: + return newstruct cs2func_script_1012_struct(-1, 15707, "Dungeoneering skill tasks" + "
" + "As your Runecrafting level increases, you will be able to attempt higher-level runecrafting tasks within Daemonheim. You will also be more likely to succeed when attempting runecrafting tasks within Daemonheim.", ""); + case 1: + return newstruct cs2func_script_1012_struct(10, 16997, "Water staff", "You can now craft " + "" + "water staves" + "" + " within Daemonheim."); + case 2: + return newstruct cs2func_script_1012_struct(20, 17001, "Earth staff", "You can now craft " + "" + "earth staves" + "" + " within Daemonheim."); + case 3: + return newstruct cs2func_script_1012_struct(30, 17005, "Fire staff", "You can now craft " + "" + "fire staves" + "" + " within Daemonheim."); + case 4: + return newstruct cs2func_script_1012_struct(40, 17009, "Air staff", "You can now craft " + "" + "air staves" + "" + " within Daemonheim."); + case 5: + return newstruct cs2func_script_1012_struct(50, 17013, "Catalytic staff", "You can now craft " + "" + "catalytic staves" + "" + " within Daemonheim."); + case 6: + return newstruct cs2func_script_1012_struct(60, 16999, "Members: Empowered water staff", "Members can now craft " + "" + "empowered water staves" + "" + " within Daemonheim."); + case 7: + return newstruct cs2func_script_1012_struct(70, 17003, "Members: Empowered earth staff", "Members can now craft " + "" + "empowered earth staves" + "" + " within Daemonheim."); + case 8: + return newstruct cs2func_script_1012_struct(80, 17007, "Members: Empowered fire staff", "Members can now craft " + "" + "empowered fire staves" + "" + " within Daemonheim."); + case 9: + return newstruct cs2func_script_1012_struct(90, 17011, "Members: Empowered air staff", "Members can now craft " + "" + "empowered air staves" + "" + " within Daemonheim."); + case 10: + return newstruct cs2func_script_1012_struct(99, 17015, "Members: Empowered catalytic staff", "Members can now craft " + "" + "empowered catalytic staves" + "" + " within Daemonheim."); + } + break; + case 6: + SWITCH (arg1) { + case 0: + GOTO flow_103 + case 1: + GOTO flow_104 + } + break; + flow_103: + return newstruct cs2func_script_1012_struct(50, 13625, "Runecrafting Guild", "You can now enter the prestigious " + "" + "Runecrafting Guild" + "" + " and play the " + "" + "Great Orb Project" + "" + "."); + flow_104: + return newstruct cs2func_script_1012_struct(99, 9765, "Skill mastery", "" + "Congratulations! You are now a master of " + "" + "Runecrafting" + "" + ". Members can visit " + "" + "Larriar" + "" + " in the " + "" + "Runecrafting Guild" + "" + ". She has something special that is only available to true masters of the " + "" + "Runecrafting" + "" + " skill!"); + } + return newstruct cs2func_script_1012_struct(0, -1, "", ""); +} diff --git a/dumps/scripts/1013.cs2 b/dumps/scripts/1013.cs2 new file mode 100644 index 0000000..75851b2 --- /dev/null +++ b/dumps/scripts/1013.cs2 @@ -0,0 +1,31 @@ +cs2func_script_1013_struct(1,1,0) script_1013(int arg0) { + switch (arg0) { + case 0: + return newstruct cs2func_script_1013_struct(1, "Allotments"); + case 1: + return newstruct cs2func_script_1013_struct(1, "Hops"); + case 2: + return newstruct cs2func_script_1013_struct(1, "Trees"); + case 3: + return newstruct cs2func_script_1013_struct(1, "Fruit Trees"); + case 4: + return newstruct cs2func_script_1013_struct(1, "Bushes"); + case 5: + return newstruct cs2func_script_1013_struct(1, "Flowers"); + case 6: + return newstruct cs2func_script_1013_struct(1, "Herbs"); + case 7: + return newstruct cs2func_script_1013_struct(1, "Special"); + case 8: + return newstruct cs2func_script_1013_struct(1, "Equipment"); + case 9: + return newstruct cs2func_script_1013_struct(1, "Other"); + case 10: + return newstruct cs2func_script_1013_struct(1, "Minigames"); + case 11: + return newstruct cs2func_script_1013_struct(1, "Dungeoneering"); + case 12: + return newstruct cs2func_script_1013_struct(1, "Milestones"); + } + return newstruct cs2func_script_1013_struct(-1, ""); +} diff --git a/dumps/scripts/1014.cs2 b/dumps/scripts/1014.cs2 new file mode 100644 index 0000000..8f75a1a --- /dev/null +++ b/dumps/scripts/1014.cs2 @@ -0,0 +1,291 @@ +cs2func_script_1014_struct(2,2,0) script_1014(int arg0,int arg1) { + switch (arg0) { + case 0: + switch (arg1) { + case 0: + return newstruct cs2func_script_1014_struct(1, 1942, "Potato", "You can now plant " + "" + "potatoes" + "" + "."); + case 1: + return newstruct cs2func_script_1014_struct(5, 1957, "Onion", "You can now plant " + "" + "onions" + "" + "."); + case 2: + return newstruct cs2func_script_1014_struct(7, 1965, "Cabbage", "You can now plant " + "" + "cabbages" + "" + "."); + case 3: + return newstruct cs2func_script_1014_struct(12, 1982, "Tomato", "You can now plant " + "" + "tomatoes" + "" + "."); + case 4: + return newstruct cs2func_script_1014_struct(20, 5986, "Sweetcorn", "You can now plant " + "" + "sweetcorn" + "" + "."); + case 5: + return newstruct cs2func_script_1014_struct(31, 5504, "Strawberry", "You can now plant " + "" + "strawberries" + "" + "."); + case 6: + return newstruct cs2func_script_1014_struct(47, 5982, "Watermelon", "You can now plant " + "" + "watermelons" + "" + "."); + } + break; + case 1: + switch (arg1) { + case 0: + return newstruct cs2func_script_1014_struct(3, 6006, "Barley", "You can now plant " + "" + "barley" + "" + "."); + case 1: + return newstruct cs2func_script_1014_struct(4, 5994, "Hammerstone hop", "You can now plant " + "" + "hammerstone hops" + "" + "."); + case 2: + return newstruct cs2func_script_1014_struct(8, 5996, "Asgarnian hop", "You can now plant " + "" + "Asgarnian hops" + "" + "."); + case 3: + return newstruct cs2func_script_1014_struct(13, 5931, "Jute plant", "You can now plant " + "" + "jute plants" + "" + "."); + case 4: + return newstruct cs2func_script_1014_struct(16, 5998, "Yanillian hop", "You can now plant " + "" + "Yanillian hops" + "" + "."); + case 5: + return newstruct cs2func_script_1014_struct(21, 6000, "Krandorian hop", "You can now plant " + "" + "Krandorian hops" + "" + "."); + case 6: + return newstruct cs2func_script_1014_struct(28, 6002, "Wildblood hop", "You can now plant " + "" + "wildblood hops" + "" + "."); + } + break; + case 2: + switch (arg1) { + case 0: + return newstruct cs2func_script_1014_struct(15, 1521, "Oak tree", "You can now plant " + "" + "oak trees" + "" + "."); + case 1: + return newstruct cs2func_script_1014_struct(30, 1519, "Willow tree", "You can now plant " + "" + "willow trees" + "" + "."); + case 2: + return newstruct cs2func_script_1014_struct(45, 1517, "Maple tree", "You can now plant " + "" + "maple trees" + "" + "."); + case 3: + return newstruct cs2func_script_1014_struct(60, 1515, "Yew tree", "You can now plant " + "" + "yew trees" + "" + "."); + case 4: + return newstruct cs2func_script_1014_struct(75, 1513, "Magic tree", "You can now plant " + "" + "magic trees" + "" + "."); + } + break; + case 3: + switch (arg1) { + case 0: + return newstruct cs2func_script_1014_struct(27, 1955, "Apple tree", "You can now plant " + "" + "apple trees" + "" + "."); + case 1: + return newstruct cs2func_script_1014_struct(33, 1963, "Banana tree", "You can now plant " + "" + "banana trees" + "" + "."); + case 2: + return newstruct cs2func_script_1014_struct(39, 2108, "Orange tree", "You can now plant " + "" + "orange trees" + "" + "."); + case 3: + return newstruct cs2func_script_1014_struct(42, 5970, "Curry tree", "You can now plant " + "" + "curry trees" + "" + "."); + case 4: + return newstruct cs2func_script_1014_struct(51, 2114, "Pineapple plant", "You can now plant " + "" + "pineapple plants" + "" + "."); + case 5: + return newstruct cs2func_script_1014_struct(57, 5972, "Papaya tree", "You can now plant " + "" + "papaya trees" + "" + "."); + case 6: + return newstruct cs2func_script_1014_struct(68, 5974, "Palm tree", "You can now plant " + "" + "palm trees" + "" + "."); + } + break; + case 4: + switch (arg1) { + case 0: + return newstruct cs2func_script_1014_struct(10, 1951, "Redberry bush", "You can now plant " + "" + "redberry bushes" + "" + "."); + case 1: + return newstruct cs2func_script_1014_struct(22, 753, "Cadavaberry bush", "You can now plant " + "" + "cadavaberry bushes" + "" + "."); + case 2: + return newstruct cs2func_script_1014_struct(36, 2126, "Dwellberry bush", "You can now plant " + "" + "dwellberry bushes" + "" + "."); + case 3: + return newstruct cs2func_script_1014_struct(48, 247, "Jangerberry bush", "You can now plant " + "" + "jangerberry bushes" + "" + "."); + case 4: + return newstruct cs2func_script_1014_struct(59, 239, "White berry bush", "You can now plant " + "" + "white berry bushes" + "" + "."); + case 5: + return newstruct cs2func_script_1014_struct(70, 6018, "Poison ivy bush", "You can now plant " + "" + "poison ivy bushes" + "" + "."); + } + break; + case 5: + switch (arg1) { + case 0: + return newstruct cs2func_script_1014_struct(2, 6010, "Marigold" + "
" + " Protects onions, tomatoes and potatoes from disease", "You can now " + "" + "plant marigolds" + "" + "."); + case 1: + return newstruct cs2func_script_1014_struct(11, 6014, "Rosemary" + "
" + " Protects cabbages from disease", "You can now plant " + "" + "rosemary" + "" + "."); + case 2: + return newstruct cs2func_script_1014_struct(24, 6012, "Nasturtium" + "
" + " Protects watermelons from disease", "You can now plant " + "" + "nasturtiums" + "" + "."); + case 3: + return newstruct cs2func_script_1014_struct(25, 5738, "Woad", "You can now plant " + "" + "woad" + "" + "."); + case 4: + return newstruct cs2func_script_1014_struct(26, 225, "Limpwurt", "You can now plant " + "" + "limpwurt" + "" + "."); + case 5: + return newstruct cs2func_script_1014_struct(52, 14583, "White lily" + "
" + " Protects all neighbouring fruit and vegetables from disease", "You can now plant " + "" + "white lilies" + "" + "."); + } + break; + case 6: + switch (arg1) { + case 0: + return newstruct cs2func_script_1014_struct(9, 249, "Guam", "You can now plant " + "" + "guam" + "" + "."); + case 1: + return newstruct cs2func_script_1014_struct(14, 251, "Marrentill", "You can now plant " + "" + "marrentill" + "" + "."); + case 2: + return newstruct cs2func_script_1014_struct(19, 253, "Tarromin", "You can now plant " + "" + "tarromin" + "" + "."); + case 3: + return newstruct cs2func_script_1014_struct(26, 255, "Harralander", "You can now plant " + "" + "harralander" + "" + "."); + case 4: + return newstruct cs2func_script_1014_struct(29, 3261, "Goutweed" + "
" + " (after Eadgar's Ruse)", "You now have the Farming level required to plant " + "" + "goutweed" + "" + " (after Eadgar's Ruse)."); + case 5: + return newstruct cs2func_script_1014_struct(32, 257, "Ranarr", "You can now plant " + "" + "ranarr" + "" + "."); + case 6: + return newstruct cs2func_script_1014_struct(36, 12172, "Spirit weed", "You can now plant " + "" + "spirit weed" + "" + "."); + case 7: + return newstruct cs2func_script_1014_struct(38, 2998, "Toadflax", "You can now plant " + "" + "toadflax" + "" + "."); + case 8: + return newstruct cs2func_script_1014_struct(44, 259, "Irit", "You can now plant " + "" + "irit" + "" + "."); + case 9: + return newstruct cs2func_script_1014_struct(46, 14854, "Wergali", "You can now plant " + "" + "wergali" + "" + "."); + case 10: + return newstruct cs2func_script_1014_struct(50, 261, "Avantoe", "You can now plant " + "" + "avantoe" + "" + "."); + case 11: + return newstruct cs2func_script_1014_struct(56, 263, "Kwuarm", "You can now plant " + "" + "kwuarm" + "" + "."); + case 12: + return newstruct cs2func_script_1014_struct(58, 19989, "Erzille", "You can now plant " + "" + "erzille" + "" + " (in a vine herb patch)."); + case 13: + return newstruct cs2func_script_1014_struct(62, 3000, "Snapdragon", "You can now plant " + "" + "snapdragon" + "" + "."); + case 14: + return newstruct cs2func_script_1014_struct(65, 19990, "Argway", "You can now plant " + "" + "argway" + "" + " (in a vine herb patch)."); + case 15: + return newstruct cs2func_script_1014_struct(67, 265, "Cadantine", "You can now plant " + "" + "cadantine" + "" + "."); + case 16: + return newstruct cs2func_script_1014_struct(70, 19991, "Ugune", "You can now plant " + "" + "ugune" + "" + " (in a vine herb patch)."); + case 17: + return newstruct cs2func_script_1014_struct(73, 2481, "Lantadyme", "You can now plant " + "" + "lantadyme" + "" + "."); + case 18: + return newstruct cs2func_script_1014_struct(76, 19992, "Shengo", "You can now plant " + "" + "shengo" + "" + " (in a vine herb patch)."); + case 19: + return newstruct cs2func_script_1014_struct(79, 267, "Dwarf weed", "You can now plant " + "" + "dwarf weed" + "" + "."); + case 20: + return newstruct cs2func_script_1014_struct(80, 19993, "Samaden", "You can now plant " + "" + "samaden" + "" + " (in a vine herb patch)."); + case 21: + return newstruct cs2func_script_1014_struct(85, 269, "Torstol", "You can now plant " + "" + "torstol" + "" + "."); + case 22: + return newstruct cs2func_script_1014_struct(91, 21624, "Fellstalk", "You can now plant fellstalk" + "" + "."); + } + break; + case 7: + switch (arg1) { + case 0: + return newstruct cs2func_script_1014_struct(42, 12134, "Evil turnip", "You can now plant " + "" + "evil turnips" + "" + "."); + case 1: + return newstruct cs2func_script_1014_struct(53, 6004, "Bittercap mushroom", "You can now plant " + "" + "bittercap mushrooms" + "" + "."); + case 2: + return newstruct cs2func_script_1014_struct(53, 11779, "Jade vine" + "
" + " (after Back to My Roots)", "You now have the Farming level required to plant " + "" + "jade vines" + "" + " (after Back to my Roots)."); + case 3: + return newstruct cs2func_script_1014_struct(54, 19962, "Vine blossoms", "You can now plant " + "" + "vine blossoms" + "" + " (in a vine flower patch)."); + case 4: + return newstruct cs2func_script_1014_struct(55, 6016, "Cactus", "You can now plant " + "" + "cacti" + "" + "."); + case 5: + return newstruct cs2func_script_1014_struct(61, 19969, "Lergberry bush", "You can now plant " + "" + "lergberry bushes" + "" + " (in a vine bush patch)."); + case 6: + return newstruct cs2func_script_1014_struct(63, 2398, "Belladonna", "You can now plant " + "" + "belladonna" + "" + "."); + case 7: + return newstruct cs2func_script_1014_struct(72, 5980, "Calquat tree", "You can now plant " + "" + "calquat trees" + "" + "."); + case 8: + return newstruct cs2func_script_1014_struct(74, 21622, "Morchella mushroom", "You can now plant " + "" + "morchella mushrooms" + "" + "."); + case 9: + return newstruct cs2func_script_1014_struct(77, 19970, "Kalferberry bush", "You can now plant " + "" + "kalferberry bushes" + "" + " (in a vine bush patch)."); + case 10: + return newstruct cs2func_script_1014_struct(83, 6063, "Spirit tree" + "
" + " (only 1 planted at a time)", "You can now plant " + "" + "spirit trees" + "" + "."); + case 11: + return newstruct cs2func_script_1014_struct(86, 6063, "Spirit tree" + "
" + " (only 2 planted at a time, after Prisoner of Glouphrie)", "You now have the Farming level required to plant " + "" + "2 spirit trees" + "" + " (after Prisoner of Glouphrie)."); + } + break; + case 8: + switch (arg1) { + case 0: + return newstruct cs2func_script_1014_struct(23, 6059, "Able to make and place a scarecrow", "You now have the ability to make and place a " + "" + "scarecrow" + "" + "."); + case 1: + return newstruct cs2func_script_1014_struct(-1, 7620, "Scarecrows help to stop sweetcorn from being attacked by birds, while also helping to prevent disease.", ""); + case 2: + return newstruct cs2func_script_1014_struct(-1, 7620, "How to make a scarecrow:", ""); + case 3: + return newstruct cs2func_script_1014_struct(-1, 7620, "1. Fill an empty sack with straw from a haystack.", ""); + case 4: + return newstruct cs2func_script_1014_struct(-1, 7620, "2. Drive the hay sack onto a bronze spear.", ""); + case 5: + return newstruct cs2func_script_1014_struct(-1, 7620, "3. Place a watermelon at the very top as a head.", ""); + case 6: + return newstruct cs2func_script_1014_struct(-1, 7620, "4. Stand the scarecrow in an empty flower patch.", ""); + case 7: + return newstruct cs2func_script_1014_struct(25, 18336, "Scroll of life" + "
" + " (with 25 Dungeoneering)", "You can now use the " + "" + "scroll of life" + "" + ". (You also need level 25 Dungeoneering.)"); + } + break; + case 9: + switch (arg1) { + case 0: + return newstruct cs2func_script_1014_struct(60, 20704, "Members: access to the Livid Farm (with 70 Magic, 60 Agility, 60 Crafting, 50 Construction and Lunar Diplomacy)", "Members can access the " + "" + "Livid Farm" + "" + " (with 70 Magic, 60 Agility, 60 Crafting, 50 Construction and Lunar Diplomacy)."); + case 1: + return newstruct cs2func_script_1014_struct(91, 18778, "Starved ancient effigies", "You can now investigate " + "" + "starved ancient effigies" + "" + " using your knowledge of Farming."); + case 2: + return newstruct cs2func_script_1014_struct(93, 18779, "Nourished ancient effigies", "You can now investigate " + "" + "nourished ancient effigies" + "" + " using your knowledge of Farming."); + case 3: + return newstruct cs2func_script_1014_struct(95, 18780, "Sated ancient effigies", "You can now investigate " + "" + "sated ancient effigies" + "" + " using your knowledge of Farming."); + case 4: + return newstruct cs2func_script_1014_struct(97, 18781, "Gorged ancient effigies", "You can now investigate " + "" + "gorged ancient effigies" + "" + " using your knowledge of Farming."); + } + break; + case 10: + switch (arg1) { + case 0: + return newstruct cs2func_script_1014_struct(1, 12625, "Vinesweeper", "You can now play " + "" + "Vinesweeper" + "" + "."); + case 1: + return newstruct cs2func_script_1014_struct(1, 14667, "Nurture basic evil tree saplings", "You can now nurture " + "" + "basic evil tree saplings" + "" + "."); + case 2: + return newstruct cs2func_script_1014_struct(7, 14667, "Nurture evil oak tree saplings", "You can now nurture " + "" + "evil oak tree saplings" + "" + "."); + case 3: + return newstruct cs2func_script_1014_struct(15, 14667, "Nurture evil willow tree saplings", "You can now nurture " + "" + "evil willow tree saplings" + "" + "."); + case 4: + return newstruct cs2func_script_1014_struct(22, 14667, "Nurture evil maple tree saplings", "You can now nurture " + "" + "evil maple tree saplings" + "" + "."); + case 5: + return newstruct cs2func_script_1014_struct(30, 14667, "Nurture evil yew tree saplings", "You can now nurture " + "" + "evil yew tree saplings" + "" + "."); + case 6: + return newstruct cs2func_script_1014_struct(37, 14667, "Nurture evil magic tree saplings", "You can now nurture " + "" + "evil magic tree saplings" + "" + "."); + case 7: + return newstruct cs2func_script_1014_struct(42, 14667, "Nurture elder evil tree saplings", "You can now nurture " + "" + "elder evil tree saplings" + "" + "."); + } + break; + case 11: + switch (arg1) { + case 0: + return newstruct cs2func_script_1014_struct(-1, 15707, "Dungeoneering skill tasks" + "
" + "As your Farming level increases, you will be able to attempt higher-level farming tasks within Daemonheim. You will also be more likely to succeed when attempting farming tasks within Daemonheim.", ""); + case 1: + return newstruct cs2func_script_1014_struct(1, 17448, "Salve nettles", "You can now harvest " + "" + "salve nettles" + "" + " within Daemonheim."); + case 2: + return newstruct cs2func_script_1014_struct(1, 17823, "Cave potato", "You can now plant " + "" + "cave potatoes" + "" + " within Daemonheim."); + case 3: + return newstruct cs2func_script_1014_struct(7, 17826, "Sagewort", "You can now plant " + "" + "sagewort" + "" + " within Daemonheim."); + case 4: + return newstruct cs2func_script_1014_struct(10, 17450, "Wildercress", "You can now harvest " + "" + "wildercress" + "" + " within Daemonheim."); + case 5: + return newstruct cs2func_script_1014_struct(18, 17827, "Valerian", "You can now plant " + "" + "valerian" + "" + " within Daemonheim."); + case 6: + return newstruct cs2func_script_1014_struct(20, 17452, "Blightleaf", "You can now harvest " + "" + "blightleaves" + "" + " within Daemonheim."); + case 7: + return newstruct cs2func_script_1014_struct(29, 17828, "Aloe", "You can now plant " + "" + "aloe" + "" + " within Daemonheim."); + case 8: + return newstruct cs2func_script_1014_struct(30, 17454, "Roseblood", "You can now harvest " + "" + "roseblood" + "" + " within Daemonheim."); + case 9: + return newstruct cs2func_script_1014_struct(34, 17824, "Gissel mushroom", "You can now plant " + "" + "gissel mushrooms" + "" + " within Daemonheim."); + case 10: + return newstruct cs2func_script_1014_struct(40, 17829, "Wormwood", "You can now plant " + "" + "wormwood" + "" + " within Daemonheim."); + case 11: + return newstruct cs2func_script_1014_struct(40, 17456, "Bryll", "You can now harvest " + "" + "bryll" + "" + " within Daemonheim."); + case 12: + return newstruct cs2func_script_1014_struct(50, 17458, "Duskweed", "You can now plant " + "" + "duskweed" + "" + " within Daemonheim."); + case 13: + return newstruct cs2func_script_1014_struct(51, 17830, "Magebane", "You can now plant " + "" + "magebane" + "" + " within Daemonheim."); + case 14: + return newstruct cs2func_script_1014_struct(60, 17460, "Soulbell", "You can now harvest " + "" + "soulbells" + "" + " within Daemonheim."); + case 15: + return newstruct cs2func_script_1014_struct(62, 17831, "Featherfoil", "You can now plant " + "" + "featherfoil" + "" + " within Daemonheim."); + case 16: + return newstruct cs2func_script_1014_struct(68, 17825, "Edicap mushroom", "You can now plant " + "" + "edicap mushrooms" + "" + " within Daemonheim."); + case 17: + return newstruct cs2func_script_1014_struct(70, 17462, "Ectograss", "You can now harvest " + "" + "ectograss" + "" + " within Daemonheim."); + case 18: + return newstruct cs2func_script_1014_struct(73, 17832, "Winter's grip", "You can now plant " + "" + "winter's grip" + "" + " within Daemonheim."); + case 19: + return newstruct cs2func_script_1014_struct(80, 17464, "Runeleaf", "You can now harvest " + "" + "runeleaves" + "" + " within Daemonheim."); + case 20: + return newstruct cs2func_script_1014_struct(84, 17833, "Lycopus", "You can now plant " + "" + "lycopus" + "" + " within Daemonheim."); + case 21: + return newstruct cs2func_script_1014_struct(90, 17466, "Spiritbloom", "You can now harvest " + "" + "spiritbloom" + "" + " within Daemonheim."); + case 22: + return newstruct cs2func_script_1014_struct(95, 17834, "Buckthorn", "You can now plant " + "" + "buckthorn" + "" + " within Daemonheim."); + } + break; + case 12: + if (((boolean)arg1)) { + return newstruct cs2func_script_1014_struct(99, 9810, "Skill mastery", "" + "Congratulations! You are now a master of " + "" + "Farming" + "" + ". Why not visit " + "" + "Martin the Master Gardener" + "" + " in " + "" + "Draynor Village" + "" + "? He has something special that is only available to true masters of the " + "" + "Farming" + "" + " skill!"); + } + } + return newstruct cs2func_script_1014_struct(0, -1, "", ""); +} diff --git a/dumps/scripts/1015.cs2 b/dumps/scripts/1015.cs2 new file mode 100644 index 0000000..ac94c61 --- /dev/null +++ b/dumps/scripts/1015.cs2 @@ -0,0 +1,19 @@ +cs2func_script_1015_struct(1,1,0) script_1015(int arg0) { + switch (arg0) { + case 0: + return newstruct cs2func_script_1015_struct(0, "Ores"); + case 1: + return newstruct cs2func_script_1015_struct(0, "Equipment"); + case 2: + return newstruct cs2func_script_1015_struct(0, "Other"); + case 3: + return newstruct cs2func_script_1015_struct(1, "Shooting Stars"); + case 4: + return newstruct cs2func_script_1015_struct(1, "Minigames"); + case 5: + return newstruct cs2func_script_1015_struct(0, "Dungeoneering"); + case 6: + return newstruct cs2func_script_1015_struct(0, "Milestones"); + } + return newstruct cs2func_script_1015_struct(-1, ""); +} diff --git a/dumps/scripts/1016.cs2 b/dumps/scripts/1016.cs2 new file mode 100644 index 0000000..d27558e --- /dev/null +++ b/dumps/scripts/1016.cs2 @@ -0,0 +1,202 @@ +cs2func_script_1016_struct(2,2,0) script_1016(int arg0,int arg1) { + switch (arg0) { + flow_1: + case 0: + switch (arg1) { + case 0: + return newstruct cs2func_script_1016_struct(1, 1436, "Rune essence" + "
" + " (after Rune Mysteries)", "You now have the Mining level required to mine " + "" + "rune essence" + "" + " (after Rune Mysteries)."); + case 1: + return newstruct cs2func_script_1016_struct(1, 434, "Clay", "You can now mine " + "" + "clay" + "" + "."); + case 2: + return newstruct cs2func_script_1016_struct(1, 436, "Copper ore", "You can now mine " + "" + "copper ore" + "" + "."); + case 3: + return newstruct cs2func_script_1016_struct(1, 438, "Tin ore", "You can now mine " + "" + "tin ore" + "" + "."); + case 4: + return newstruct cs2func_script_1016_struct(10, 3211, "Members: Limestone", "Members can now mine " + "" + "limestone" + "" + "."); + case 5: + return newstruct cs2func_script_1016_struct(10, 668, "Blurite ore", "You can now mine " + "" + "blurite ore" + "" + "."); + case 6: + return newstruct cs2func_script_1016_struct(15, 440, "Iron ore", "You can now mine " + "" + "iron ore" + "" + "."); + case 7: + return newstruct cs2func_script_1016_struct(20, 2892, "Members: Elemental ore" + "
" + " (after starting Elemental Workshop)", "Members now have the Mining level required to mine " + "" + "elemental ore" + "" + " (after starting Elemental Workshop)."); + case 8: + return newstruct cs2func_script_1016_struct(20, 442, "Silver ore", "You can now mine " + "" + "silver ore" + "" + "."); + case 9: + return newstruct cs2func_script_1016_struct(30, 453, "Coal", "You can now mine " + "" + "coal" + "" + "."); + case 10: + return newstruct cs2func_script_1016_struct(30, 7936, "Members: Pure essence" + "
" + " (after Rune Mysteries)", "Members now have the Mining level required to mine " + "" + "pure essence" + "" + " (after Rune Mysteries)."); + case 11: + return newstruct cs2func_script_1016_struct(35, 6977, "Members: Sandstone", "Members can now mine " + "" + "sandstone" + "" + "."); + case 12: + return newstruct cs2func_script_1016_struct(40, 444, "Gold", "You can now mine " + "" + "gold" + "" + "."); + case 13: + return newstruct cs2func_script_1016_struct(45, 6983, "Members: Granite", "Members can now mine " + "" + "granite."); + case 14: + return newstruct cs2func_script_1016_struct(46, 12630, "Members: Rubium ore" + "
" + " (after Kennith's Concerns)", "Members can now mine " + "" + "rubium ore" + "" + " (after Kennith's Concerns)."); + case 15: + return newstruct cs2func_script_1016_struct(55, 447, "Mithril ore", "You can now mine " + "" + "mithril ore" + "" + "."); + case 16: + return newstruct cs2func_script_1016_struct(70, 449, "Adamantite ore", "You can now mine " + "" + "adamantite ore" + "" + "."); + case 17: + return newstruct cs2func_script_1016_struct(77, 21778, "Members: Bane ore" + "
" + " (after Ritual of the Mahjarrat)", "Members can now mine " + "" + "bane ore" + "" + " (after Ritual of the Mahjarrat)."); + case 18: + return newstruct cs2func_script_1016_struct(85, 451, "Runite ore", "You can now mine " + "" + "runite ore" + "" + "."); + } + break; + case 1: + switch (arg1) { + case 0: + return newstruct cs2func_script_1016_struct(1, 21340, "Members: Dwarven Army Axe", "Members can now use a " + "" + "Dwarven Army Axe" + "" + "."); + case 1: + return newstruct cs2func_script_1016_struct(1, 1265, "Bronze pickaxe", "You can now use " + "" + "bronze pickaxes" + "" + "."); + case 2: + return newstruct cs2func_script_1016_struct(1, 1267, "Iron pickaxe", "You can now use " + "" + "iron pickaxes" + "" + "."); + case 3: + return newstruct cs2func_script_1016_struct(6, 1269, "Steel pickaxe", "You can now use " + "" + "steel pickaxes" + "" + "."); + case 4: + return newstruct cs2func_script_1016_struct(21, 1273, "Mithril pickaxe", "You can now use " + "" + "mithril pickaxes" + "" + "."); + case 5: + return newstruct cs2func_script_1016_struct(31, 1271, "Adamant pickaxe", "You can now use " + "" + "adamant pickaxes" + "" + "."); + case 6: + return newstruct cs2func_script_1016_struct(35, 18339, "Coal bag" + "
" + " (with 35 Dungeoneering)", "You can now use " + "" + "coal bags" + "" + ". (You also need level 35 Dungeoneering.)"); + case 7: + return newstruct cs2func_script_1016_struct(40, 14107, "Members: Sacred clay pickaxe", "Members can now use " + "" + "sacred clay pickaxes" + "" + "."); + case 8: + return newstruct cs2func_script_1016_struct(40, 14099, "Members: Volatile pickaxe", "Members can now use " + "" + "volatile pickaxes" + "" + "."); + case 9: + return newstruct cs2func_script_1016_struct(41, 1275, "Rune pickaxe", "You can now use " + "" + "rune pickaxes" + "" + "."); + case 10: + return newstruct cs2func_script_1016_struct(41, 13661, "Members: Inferno Adze" + "
" + " (after All Fired Up, with 92 Firemaking)", "Members can now use the " + "" + "Inferno Adze" + "" + " to mine with (after All Fired Up and with level 92 Firemaking)."); + case 11: + return newstruct cs2func_script_1016_struct(61, 15259, "Members: Dragon pickaxe", "Members can now use " + "" + "dragon pickaxes" + "" + "."); + } + break; + case 2: + switch (arg1) { + case 0: + return newstruct cs2func_script_1016_struct(40, 1603, "Members: Gem rocks" + "
" + " (after Shilo Village)", "Members now have the Mining level required to mine " + "" + "gem rocks" + "" + " (after Shilo Village)."); + case 1: + return newstruct cs2func_script_1016_struct(41, 13245, "Members: Stone slab" + "
" + " (with rune pickaxe, after starting TokTz-Ket-Dill)", "Members now have the Mining level required to mine " + "" + "stone slabs" + "" + " with rune pickaxes (after starting TokTz-Ket-Dill)."); + case 2: + return newstruct cs2func_script_1016_struct(73, 15263, "Members: Living rock remains", "Members now have the Mining level required to mine " + "" + "living rock remains" + "" + "."); + case 3: + return newstruct cs2func_script_1016_struct(77, 453, "Members: Concentrated coal deposits", "Members now have the Mining level required to mine " + "" + "concentrated coal deposits" + "" + "."); + case 4: + return newstruct cs2func_script_1016_struct(80, 444, "Members: Concentrated gold deposits", "Members now have the Mining level required to mine " + "" + "concentrated gold deposits" + "" + "."); + case 5: + return newstruct cs2func_script_1016_struct(91, 18778, "Members: Starved ancient effigies", "Members can now investigate " + "" + "starved ancient effigies" + "" + " using their knowledge of Mining."); + case 6: + return newstruct cs2func_script_1016_struct(93, 18779, "Members: Nourished ancient effigies", "Members can now investigate " + "" + "nourished ancient effigies" + "" + " using their knowledge of Mining."); + case 7: + return newstruct cs2func_script_1016_struct(95, 18780, "Members: Sated ancient effigies", "Members can now investigate " + "" + "sated ancient effigies" + "" + " using their knowledge of Mining."); + case 8: + return newstruct cs2func_script_1016_struct(97, 18781, "Members: Gorged ancient effigies", "Members can now investigate " + "" + "gorged ancient effigies" + "" + " using their knowledge of Mining."); + } + break; + case 3: + switch (arg1) { + case 0: + return newstruct cs2func_script_1016_struct(10, 13727, "Members: Size-1 stars", "Members can now mine size-1 " + "" + "crashed stars" + "" + "."); + case 1: + return newstruct cs2func_script_1016_struct(20, 13727, "Members: Size-2 stars", "Members can now mine size-2 " + "" + "crashed stars" + "" + "."); + case 2: + return newstruct cs2func_script_1016_struct(30, 13727, "Members: Size-3 stars", "Members can now mine size-3 " + "" + "crashed stars" + "" + "."); + case 3: + return newstruct cs2func_script_1016_struct(40, 13727, "Members: Size-4 stars", "Members can now mine size-4 " + "" + "crashed stars" + "" + "."); + case 4: + return newstruct cs2func_script_1016_struct(50, 13727, "Members: Size-5 stars", "Members can now mine size-5 " + "" + "crashed stars" + "" + "."); + case 5: + return newstruct cs2func_script_1016_struct(60, 13727, "Members: Size-6 stars", "Members can now mine size-6 " + "" + "crashed stars" + "" + "."); + case 6: + return newstruct cs2func_script_1016_struct(70, 13727, "Members: Size-7 stars", "Members can now mine size-7 " + "" + "crashed stars" + "" + "."); + case 7: + return newstruct cs2func_script_1016_struct(80, 13727, "Members: Size-8 stars", "Members can now mine size-8 " + "" + "crashed stars" + "" + "."); + case 8: + return newstruct cs2func_script_1016_struct(90, 13727, "Members: Size-9 stars", "Members can now mine size-9 " + "" + "crashed stars" + "" + "."); + } + break; + case 4: + switch (arg1) { + case 0: + return newstruct cs2func_script_1016_struct(1, 14122, "Members: Stealing Creation - class 1 pickaxe", "Members can now use " + "" + "class 1 pickaxes" + "" + " in Stealing Creation."); + case 1: + return newstruct cs2func_script_1016_struct(20, 14184, "Members: Stealing Creation - mine class 2 sacred clay", "Members can now mine " + "" + "class 2 sacred clay" + "" + " in Stealing Creation."); + case 2: + return newstruct cs2func_script_1016_struct(20, 14124, "Members: Stealing Creation - class 2 pickaxe", "Members can now use " + "" + "class 2 pickaxes" + "" + " in Stealing Creation."); + case 3: + return newstruct cs2func_script_1016_struct(40, 14186, "Members: Stealing Creation - mine class 3 sacred clay", "Members can now mine " + "" + "class 3 sacred clay" + "" + " in Stealing Creation."); + case 4: + return newstruct cs2func_script_1016_struct(40, 14126, "Members: Stealing Creation - class 3 pickaxe", "Members can now use " + "" + "class 3 pickaxes" + "" + " in Stealing Creation."); + case 5: + return newstruct cs2func_script_1016_struct(60, 14188, "Members: Stealing Creation - mine class 4 sacred clay", "Members can now mine " + "" + "class 4 sacred clay" + "" + " in Stealing Creation."); + case 6: + return newstruct cs2func_script_1016_struct(60, 14128, "Members: Stealing Creation - class 4 pickaxe", "Members can now use " + "" + "class 4 pickaxes" + "" + " in Stealing Creation."); + case 7: + return newstruct cs2func_script_1016_struct(80, 14190, "Members: Stealing Creation - mine class 5 sacred clay", "Members can now mine " + "" + "class 5 sacred clay" + "" + " in Stealing Creation."); + case 8: + return newstruct cs2func_script_1016_struct(80, 14130, "Members: Stealing Creation - class 5 pickaxe", "Members can now use " + "" + "class 5 pickaxes" + "" + " in Stealing Creation."); + } + break; + case 5: + switch (arg1) { + case 0: + return newstruct cs2func_script_1016_struct(-1, 15707, "Dungeoneering skill tasks" + "
" + "As your Mining level increases, you will be able to attempt higher-level mining tasks within Daemonheim. You will also be more likely to succeed when attempting mining tasks within Daemonheim.", ""); + case 1: + return newstruct cs2func_script_1016_struct(1, 17630, "Novite ore (Tier 1)", "You can now mine " + "" + "novite ore" + "" + " within Daemonheim."); + case 2: + return newstruct cs2func_script_1016_struct(1, 16295, "Novite pickaxe (Tier 1)", "You can now use " + "" + "novite pickaxes" + "" + " within Daemonheim."); + case 3: + return newstruct cs2func_script_1016_struct(10, 17632, "Bathus ore (Tier 2)", "You can now mine " + "" + "bathus ore" + "" + " within Daemonheim."); + case 4: + return newstruct cs2func_script_1016_struct(10, 16297, "Bathus pickaxe (Tier 2)", "You can now use " + "" + "bathus pickaxes" + "" + " within Daemonheim."); + case 5: + return newstruct cs2func_script_1016_struct(20, 17634, "Marmaros ore (Tier 3)", "You can now mine " + "" + "marmaros ore" + "" + " within Daemonheim."); + case 6: + return newstruct cs2func_script_1016_struct(20, 16299, "Marmaros pickaxe (Tier 3)", "You can now use " + "" + "marmaros pickaxes" + "" + " within Daemonheim."); + case 7: + return newstruct cs2func_script_1016_struct(30, 17636, "Kratonium ore (Tier 4)", "You can now mine " + "" + "kratonite ore" + "" + " within Daemonheim."); + case 8: + return newstruct cs2func_script_1016_struct(30, 16301, "Kratonite pickaxe (Tier 4)", "You can now use " + "" + "kratonite pickaxes" + "" + " within Daemonheim."); + case 9: + return newstruct cs2func_script_1016_struct(40, 17638, "Fractite ore (Tier 5)", "You can now mine " + "" + "fractite ore" + "" + " within Daemonheim."); + case 10: + return newstruct cs2func_script_1016_struct(40, 16303, "Fractite pickaxe (Tier 5)", "You can now use " + "" + "fractite pickaxes" + "" + " within Daemonheim."); + case 11: + return newstruct cs2func_script_1016_struct(50, 17640, "Members: Zephyrium ore (Tier 6)", "Members can now mine " + "" + "zephyrium ore" + "" + " within Daemonheim."); + case 12: + return newstruct cs2func_script_1016_struct(50, 16305, "Members: Zephyrium pickaxe (Tier 6)", "Members can now use " + "" + "zephyrium pickaxes" + "" + " within Daemonheim."); + case 13: + return newstruct cs2func_script_1016_struct(60, 17642, "Members: Argonite ore (Tier 7)", "Members can now mine " + "" + "argonite ore" + "" + " within Daemonheim."); + case 14: + return newstruct cs2func_script_1016_struct(60, 16307, "Members: Argonite pickaxe (Tier 7)", "Members can now use " + "" + "argonite pickaxes" + "" + " within Daemonheim."); + case 15: + return newstruct cs2func_script_1016_struct(70, 17644, "Members: Katagon ore (Tier 8)", "Members can now mine " + "" + "katagon ore" + "" + " within Daemonheim."); + case 16: + return newstruct cs2func_script_1016_struct(70, 16309, "Members: Katagon pickaxe (Tier 8)", "Members can now use " + "" + "katagon pickaxes" + "" + " within Daemonheim."); + case 17: + return newstruct cs2func_script_1016_struct(80, 17646, "Members: Gorgonite ore (Tier 9)", "Members can now mine " + "" + "gorgonite ore" + "" + " within Daemonheim."); + case 18: + return newstruct cs2func_script_1016_struct(80, 16311, "Members: Gorgonite pickaxe (Tier 9)", "Members can now use " + "" + "gorgonite pickaxes" + "" + " within Daemonheim."); + case 19: + return newstruct cs2func_script_1016_struct(90, 17648, "Members: Promethium ore (Tier 10)", "Members can now mine " + "" + "promethium ore" + "" + " within Daemonheim."); + case 20: + return newstruct cs2func_script_1016_struct(90, 16313, "Members: Promethium pickaxe (Tier 10)", "Members can now use " + "" + "promethium pickaxes" + "" + " within Daemonheim."); + case 21: + return newstruct cs2func_script_1016_struct(99, 16315, "Members: Primal pickaxe (Tier 11)", "Members can now use primal pickaxes" + "" + " within Daemonheim."); + } + break; + case 6: + SWITCH (arg1) { + case 0: + GOTO flow_94 + case 1: + GOTO flow_95 + } + break; + flow_94: + return newstruct cs2func_script_1016_struct(60, 447, "Mining Guild", "You can now enter the world-famous " + "" + "Mining Guild" + "" + "."); + flow_95: + return newstruct cs2func_script_1016_struct(99, 9792, "Skill mastery", "" + "Congratulations! You are now a master miner. Members can visit the " + "" + "dwarf" + "" + " who guards the entrance to the " + "" + "Mining Guild" + "" + ". He has something special that is only available to true masters of the " + "" + "Mining" + "" + " skill!"); + } + return newstruct cs2func_script_1016_struct(0, -1, "", ""); +} diff --git a/dumps/scripts/1017.cs2 b/dumps/scripts/1017.cs2 new file mode 100644 index 0000000..01e1e60 --- /dev/null +++ b/dumps/scripts/1017.cs2 @@ -0,0 +1,37 @@ +cs2func_script_1017_struct(1,1,0) script_1017(int arg0) { + switch (arg0) { + case 0: + return newstruct cs2func_script_1017_struct(0, "Meats"); + case 1: + return newstruct cs2func_script_1017_struct(0, "Bread"); + case 2: + return newstruct cs2func_script_1017_struct(0, "Pies"); + case 3: + return newstruct cs2func_script_1017_struct(0, "Stews"); + case 4: + return newstruct cs2func_script_1017_struct(0, "Pizzas"); + case 5: + return newstruct cs2func_script_1017_struct(0, "Cakes"); + case 6: + return newstruct cs2func_script_1017_struct(0, "Wine"); + case 7: + return newstruct cs2func_script_1017_struct(1, "Hot Drinks"); + case 8: + return newstruct cs2func_script_1017_struct(1, "Brewing"); + case 9: + return newstruct cs2func_script_1017_struct(1, "Potatoes & Toppings"); + case 10: + return newstruct cs2func_script_1017_struct(1, "Dairy"); + case 11: + return newstruct cs2func_script_1017_struct(1, "Gnome"); + case 12: + return newstruct cs2func_script_1017_struct(0, "Other"); + case 13: + return newstruct cs2func_script_1017_struct(1, "Minigames"); + case 14: + return newstruct cs2func_script_1017_struct(0, "Dungeoneering"); + case 15: + return newstruct cs2func_script_1017_struct(0, "Milestones"); + } + return newstruct cs2func_script_1017_struct(-1, ""); +} diff --git a/dumps/scripts/1018.cs2 b/dumps/scripts/1018.cs2 new file mode 100644 index 0000000..f129f78 --- /dev/null +++ b/dumps/scripts/1018.cs2 @@ -0,0 +1,514 @@ +cs2func_script_1018_struct(2,2,0) script_1018(int arg0,int arg1) { + switch (arg0) { + flow_1: + case 0: + switch (arg1) { + case 0: + return newstruct cs2func_script_1018_struct(1, 2142, "Meat", "You can now cook " + "" + "meat" + "" + "."); + case 1: + return newstruct cs2func_script_1018_struct(1, 9436, "Members: Sinew", "You can now make " + "" + "sinew" + "" + " by drying beef or bear meat on a range."); + case 2: + return newstruct cs2func_script_1018_struct(1, 315, "Shrimp", "You can now cook " + "" + "shrimp" + "" + "."); + case 3: + return newstruct cs2func_script_1018_struct(1, 13433, "Crayfish", "You can now cook " + "" + "crayfish" + "" + "."); + case 4: + return newstruct cs2func_script_1018_struct(1, 2140, "Chicken", "You can now cook " + "" + "chicken" + "" + "."); + case 5: + return newstruct cs2func_script_1018_struct(1, 3228, "Members: Rabbit", "Members can now cook " + "" + "rabbits" + "" + "."); + case 6: + return newstruct cs2func_script_1018_struct(1, 319, "Anchovies", "You can now cook " + "" + "anchovies" + "" + "."); + case 7: + return newstruct cs2func_script_1018_struct(1, 325, "Sardine", "You can now cook " + "" + "sardines" + "" + "."); + case 8: + return newstruct cs2func_script_1018_struct(1, 3151, "Members: Karambwanji", "Members can now cook " + "" + "karambwanji" + "" + "."); + case 9: + return newstruct cs2func_script_1018_struct(1, 3146, "Members: Karambwan", "Members can now cook " + "" + "karambwan" + "" + "."); + case 10: + return newstruct cs2func_script_1018_struct(1, 1885, "Members: Ugthanki kebab", "Members can now cook " + "" + "ugthanki kebabs" + "" + "."); + case 11: + return newstruct cs2func_script_1018_struct(5, 347, "Herring", "You can now cook " + "" + "herring" + "" + "."); + case 12: + return newstruct cs2func_script_1018_struct(10, 355, "Members: Mackerel", "Members can now cook " + "" + "mackerel" + "" + "."); + case 13: + return newstruct cs2func_script_1018_struct(11, 9980, "Members: Roasted bird meat", "Members can now roast " + "" + "bird meat" + "" + " on an iron spit."); + case 14: + return newstruct cs2func_script_1018_struct(12, 3369, "Members: Thin snail", "Members can now cook " + "" + "thin snails" + "" + "."); + case 15: + return newstruct cs2func_script_1018_struct(15, 333, "Trout", "You can now cook " + "" + "trout" + "" + "."); + case 16: + return newstruct cs2func_script_1018_struct(16, 6297, "Members: Spider", "Members can now cook " + "" + "spiders" + "" + "."); + case 17: + return newstruct cs2func_script_1018_struct(16, 7223, "Members: Roasted rabbit", "Members can now roast " + "" + "rabbits" + "" + " on a spit."); + case 18: + return newstruct cs2func_script_1018_struct(17, 3371, "Members: Lean snail", "Members can now cook " + "" + "lean snails" + "" + "."); + case 19: + return newstruct cs2func_script_1018_struct(18, 339, "Members: Cod", "Members can now cook " + "" + "cod" + "" + "."); + case 20: + return newstruct cs2func_script_1018_struct(20, 351, "Pike", "You can now cook " + "" + "pike" + "" + "."); + case 21: + return newstruct cs2func_script_1018_struct(21, 9988, "Members: Roasted beast meat", "Members can now roast " + "" + "beast meat" + "" + " on a spit."); + case 22: + return newstruct cs2func_script_1018_struct(21, 7521, "Members: Giant crab meat", "Members can now cook " + "" + "giant crab meat" + "" + "."); + case 23: + return newstruct cs2func_script_1018_struct(22, 3373, "Members: Fat snail", "Members can now cook " + "" + "fat snails" + "" + "."); + case 24: + return newstruct cs2func_script_1018_struct(25, 329, "Salmon", "You can now cook " + "" + "salmon" + "" + "."); + case 25: + return newstruct cs2func_script_1018_struct(28, 3381, "Members: Slimy eel", "Members can now cook " + "" + "slimy eels" + "" + "."); + case 26: + return newstruct cs2func_script_1018_struct(30, 361, "Tuna", "You can now cook " + "" + "tuna" + "" + "."); + case 27: + return newstruct cs2func_script_1018_struct(30, 2878, "Members: Roasted chompy", "Members can now roast " + "" + "chompies" + "" + " on a spit."); + case 28: + return newstruct cs2func_script_1018_struct(31, 7530, "Members: Fishcake", "Members can now cook " + "" + "fishcakes" + "" + "."); + case 29: + return newstruct cs2func_script_1018_struct(35, 10136, "Members: Rainbow fish", "Members can now cook " + "" + "rainbow fish" + "" + "."); + case 30: + return newstruct cs2func_script_1018_struct(38, 5003, "Members: Cave eel", "Members can now cook " + "" + "cave eels" + "" + "."); + case 31: + return newstruct cs2func_script_1018_struct(40, 379, "Lobster", "You can now cook " + "" + "lobsters" + "" + "."); + case 32: + return newstruct cs2func_script_1018_struct(41, 7568, "Members: Jubbly", "Members can now cook " + "" + "jubblies" + "" + "."); + case 33: + return newstruct cs2func_script_1018_struct(43, 365, "Members: Bass", "Members can now cook " + "" + "bass" + "" + "."); + case 34: + return newstruct cs2func_script_1018_struct(45, 373, "Swordfish", "You can now cook " + "" + "swordfish" + "" + "."); + case 35: + return newstruct cs2func_script_1018_struct(50, 2343, "Members: Oomlie wrap", "Members can now cook " + "" + "oomlie wraps" + "" + "."); + case 36: + return newstruct cs2func_script_1018_struct(53, 2149, "Members: Lava eel", "Members can now cook " + "" + "lava eels" + "" + "."); + case 37: + return newstruct cs2func_script_1018_struct(62, 7946, "Members: Monkfish", "Members can now cook " + "" + "monkfish" + "" + "."); + case 38: + return newstruct cs2func_script_1018_struct(80, 385, "Members: Shark", "Members can now cook " + "" + "sharks" + "" + "."); + case 39: + return newstruct cs2func_script_1018_struct(82, 397, "Members: Sea turtle", "Members can now cook " + "" + "sea turtles" + "" + "."); + case 40: + return newstruct cs2func_script_1018_struct(88, 15266, "Members: Cavefish", "Members can now cook " + "" + "cavefish" + "" + "."); + case 41: + return newstruct cs2func_script_1018_struct(91, 391, "Members: Manta ray", "Members can now cook " + "" + "manta rays" + "" + "."); + case 42: + return newstruct cs2func_script_1018_struct(93, 15272, "Members: Rocktail", "Members can now cook " + "" + "rocktails" + "" + "."); + case 43: + return newstruct cs2func_script_1018_struct(95, 21521, "Members: Tiger shark", "Members can now cook " + "" + "tiger sharks" + "" + "."); + } + break; + case 1: + switch (arg1) { + case 0: + return newstruct cs2func_script_1018_struct(1, 2309, "Bread", "You can now bake " + "" + "bread" + "" + "."); + case 1: + return newstruct cs2func_script_1018_struct(58, 1865, "Members: Pitta bread", "Members can now bake " + "" + "pitta bread" + "" + "."); + case 2: + return newstruct cs2func_script_1018_struct(-1, 7620, "To make bread:", ""); + case 3: + return newstruct cs2func_script_1018_struct(-1, 7620, "1. Pick some grain and take it to a windmill to make flour.", ""); + case 4: + return newstruct cs2func_script_1018_struct(-1, 7620, "2. Use a pot to collect the flour you have made.", ""); + case 5: + return newstruct cs2func_script_1018_struct(-1, 7620, "3. Fill a bucket or jug with water from a sink or fountain.", ""); + case 6: + return newstruct cs2func_script_1018_struct(-1, 7620, "4. Mix the flour and water to make some bread dough.", ""); + case 7: + return newstruct cs2func_script_1018_struct(-1, 7620, "5. Cook the dough by using it with a stove.", ""); + } + break; + case 2: + switch (arg1) { + case 0: + return newstruct cs2func_script_1018_struct(10, 2325, "Redberry pie", "You can now bake " + "" + "redberry pies" + "" + "."); + case 1: + return newstruct cs2func_script_1018_struct(20, 2327, "Meat pie", "You can now bake " + "" + "meat pies" + "" + "."); + case 2: + return newstruct cs2func_script_1018_struct(29, 7170, "Members: Mud pie", "Members can now bake " + "" + "mud pies" + "" + "."); + case 3: + return newstruct cs2func_script_1018_struct(30, 2323, "Apple pie", "You can now bake " + "" + "apple pies" + "" + "."); + case 4: + return newstruct cs2func_script_1018_struct(34, 7178, "Members: Garden pie", "Members can now bake " + "" + "garden pies" + "" + "."); + case 5: + return newstruct cs2func_script_1018_struct(47, 7188, "Members: Fish pie", "Members can now bake " + "" + "fish pies" + "" + "."); + case 6: + return newstruct cs2func_script_1018_struct(70, 7198, "Members: Admiral pie", "Members can now bake " + "" + "admiral pies" + "" + "."); + case 7: + return newstruct cs2func_script_1018_struct(85, 7208, "Members: Wild pie", "Members can now bake " + "" + "wild pies" + "" + "."); + case 8: + return newstruct cs2func_script_1018_struct(95, 7218, "Members: Summer pie", "Members can now bake " + "" + "summer pies" + "" + "."); + case 9: + return newstruct cs2func_script_1018_struct(-1, 7620, "To make a pie:", ""); + case 10: + return newstruct cs2func_script_1018_struct(-1, 7620, "1. Mix flour and water to make pastry dough.", ""); + case 11: + return newstruct cs2func_script_1018_struct(-1, 7620, "2. Place the dough in an empty pie dish.", ""); + case 12: + return newstruct cs2func_script_1018_struct(-1, 7620, "3. Use your choice of filling with the empty pie (refer to pie recipe book).", ""); + case 13: + return newstruct cs2func_script_1018_struct(-1, 7620, "4. Cook the pie by using it with a stove.", ""); + } + break; + case 3: + switch (arg1) { + case 0: + return newstruct cs2func_script_1018_struct(25, 2003, "Stew", "You can now make " + "" + "stews" + "" + "."); + case 1: + return newstruct cs2func_script_1018_struct(60, 2011, "Members: Curry", "Members can now make " + "" + "curries" + "" + "."); + case 2: + return newstruct cs2func_script_1018_struct(-1, 7620, "To make stew:", ""); + case 3: + return newstruct cs2func_script_1018_struct(-1, 7620, "1. Obtain a bowl and fill it with water from a sink or fountain.", ""); + case 4: + return newstruct cs2func_script_1018_struct(-1, 7620, "2. Pick a potato and place it in the bowl.", ""); + case 5: + return newstruct cs2func_script_1018_struct(-1, 7620, "3. Cook some meat and place it in the bowl.", ""); + case 6: + return newstruct cs2func_script_1018_struct(-1, 7620, "4. Cook the stew by using it with a stove or fire.", ""); + case 7: + return newstruct cs2func_script_1018_struct(-1, 7620, "After completing Evil Dave's subquest from Recipe for Disaster, I can add spices to cooked stew.", ""); + case 8: + return newstruct cs2func_script_1018_struct(-1, 7620, "To make curry: make uncooked stew as above. Before cooking, add some spices or 3 curry leaves.", ""); + } + break; + case 4: + switch (arg1) { + case 0: + return newstruct cs2func_script_1018_struct(35, 2289, "Plain pizza", "You can now cook " + "" + "plain pizzas" + "" + "."); + case 1: + return newstruct cs2func_script_1018_struct(45, 2293, "Meat pizza", "You can now cook " + "" + "meat pizzas" + "" + "."); + case 2: + return newstruct cs2func_script_1018_struct(55, 2297, "Anchovy pizza", "You can now cook " + "" + "anchovy pizzas" + "" + "."); + case 3: + return newstruct cs2func_script_1018_struct(65, 2301, "Members: Pineapple pizza", "Members can now make " + "" + "pineapple pizzas" + "" + "."); + case 4: + return newstruct cs2func_script_1018_struct(-1, 7620, "To make a pizza:", ""); + case 5: + return newstruct cs2func_script_1018_struct(-1, 7620, "1. Mix flour and water to make a pizza base.", ""); + case 6: + return newstruct cs2func_script_1018_struct(-1, 7620, "2. Add a tomato to the pizza.", ""); + case 7: + return newstruct cs2func_script_1018_struct(-1, 7620, "3. Add some cheese to the pizza.", ""); + case 8: + return newstruct cs2func_script_1018_struct(-1, 7620, "4. Cook the pizza by using it with a stove.", ""); + case 9: + return newstruct cs2func_script_1018_struct(-1, 7620, "5. Add your choice of topping to the pizza.", ""); + } + break; + case 5: + switch (arg1) { + case 0: + return newstruct cs2func_script_1018_struct(40, 1891, "Cake", "You can now bake " + "" + "cakes" + "" + "."); + case 1: + return newstruct cs2func_script_1018_struct(50, 1897, "Chocolate cake", "You can now bake " + "" + "chocolate cakes" + "" + "."); + case 2: + return newstruct cs2func_script_1018_struct(-1, 7620, "To make a cake:", ""); + case 3: + return newstruct cs2func_script_1018_struct(-1, 7620, "1. Mix flour, eggs and milk together in a cake tin.", ""); + case 4: + return newstruct cs2func_script_1018_struct(-1, 7620, "2. Cook the cake by using it with a stove.", ""); + case 5: + return newstruct cs2func_script_1018_struct(-1, 7620, "3. Optional: Buy some chocolate and add it to the cake to make a chocolate cake.", ""); + } + break; + case 6: + switch (arg1) { + case 0: + return newstruct cs2func_script_1018_struct(35, 1993, "Wine", "You can now ferment " + "" + "wine" + "" + "."); + case 1: + return newstruct cs2func_script_1018_struct(-1, 7620, "To make wine:", ""); + case 2: + return newstruct cs2func_script_1018_struct(-1, 7620, "1. Fill a jug with water.", ""); + case 3: + return newstruct cs2func_script_1018_struct(-1, 7620, "2. Use grapes with the jug of water.", ""); + case 4: + return newstruct cs2func_script_1018_struct(-1, 7620, "3. Wait until the wine ferments.", ""); + case 5: + return newstruct cs2func_script_1018_struct(-1, 7620, "The wine will ferment while left in your inventory or the bank.", ""); + } + break; + case 7: + switch (arg1) { + case 0: + return newstruct cs2func_script_1018_struct(20, 4242, "Nettle tea", "Members can now make " + "" + "nettle tea" + "" + "."); + case 1: + return newstruct cs2func_script_1018_struct(-1, 7620, "To make nettle tea:", ""); + case 2: + return newstruct cs2func_script_1018_struct(-1, 7620, "1. Fill a bowl with water.", ""); + case 3: + return newstruct cs2func_script_1018_struct(-1, 7620, "2. Put some picked nettles into the bowl of water.", ""); + case 4: + return newstruct cs2func_script_1018_struct(-1, 7620, "3. Boil the nettle-water by using it with a range or a fire.", ""); + case 5: + return newstruct cs2func_script_1018_struct(-1, 7620, "4. Use the bowl of nettle tea with a cup.", ""); + case 6: + return newstruct cs2func_script_1018_struct(-1, 7620, "5. If you take milk, use a bucket of milk on the nettle tea.", ""); + } + break; + case 8: + switch (arg1) { + case 0: + return newstruct cs2func_script_1018_struct(14, 5763, "Members: Cider" + "
" + "4 Apple mush", "Members can now make " + "" + "apple mush" + "" + "."); + case 1: + return newstruct cs2func_script_1018_struct(19, 1913, "Members: Dwarven Stout" + "
" + "4 Hammerstone hops", "Members can now brew " + "" + "Dwarven Stout" + "" + "."); + case 2: + return newstruct cs2func_script_1018_struct(24, 1905, "Members: Asgarnian Ale" + "
" + "4 Asgarnian hops", "Members can now brew " + "" + "Asgarnian Ale" + "" + "."); + case 3: + return newstruct cs2func_script_1018_struct(29, 1909, "Members: Greenman's Ale" + "
" + "4 Harralander leaves", "Members can now brew " + "" + "Greenman's Ale" + "" + "."); + case 4: + return newstruct cs2func_script_1018_struct(34, 1907, "Members: Wizard's mind bomb" + "
" + "4 Yanillian hops", "Members can now brew " + "" + "Wizard's Mind Bomb" + "" + "."); + case 5: + return newstruct cs2func_script_1018_struct(39, 1911, "Members: Dragon Bitter" + "
" + "4 Krandorian hops", "Members can now brew " + "" + "Dragon Bitter" + "" + "."); + case 6: + return newstruct cs2func_script_1018_struct(44, 2955, "Members: Moonlight Mead" + "
" + "4 Bittercap mushrooms", "Members can now brew " + "" + "Moonlight Mead" + "" + "."); + case 7: + return newstruct cs2func_script_1018_struct(49, 5751, "Members: Axeman's folly" + "
" + "1 Oak root", "Members can now brew " + "" + "Axeman's Folly" + "" + "."); + case 8: + return newstruct cs2func_script_1018_struct(54, 5755, "Members: Chef's Delight" + "
" + "4 Portions of chocolate dust", "Members can now brew " + "" + "Chef's Delight" + "" + "."); + case 9: + return newstruct cs2func_script_1018_struct(59, 5759, "Members: Slayer's Respite" + "
" + "4 Wildblood hops", "Members can now brew " + "" + "Slayer's Respite" + "" + "."); + } + break; + case 9: + switch (arg1) { + case 0: + return newstruct cs2func_script_1018_struct(7, 6701, "Members: Baked potato", "Members can now cook " + "" + "baked potatoes" + "" + "."); + case 1: + return newstruct cs2func_script_1018_struct(9, 7072, "Members: Spicy sauce (topping ingredient)", "Members can now make " + "" + "spicy sauce" + "" + " toppings."); + case 2: + return newstruct cs2func_script_1018_struct(11, 7062, "Members: Chilli con carne (topping)", "Members can now make " + "" + "chilli con carne" + "" + " toppings."); + case 3: + return newstruct cs2func_script_1018_struct(13, 7078, "Members: Scrambled egg (topping ingredient)", "Members can now make " + "" + "scrambled egg" + "" + " toppings."); + case 4: + return newstruct cs2func_script_1018_struct(23, 7064, "Members: Scrambled egg and tomato (topping)", "Members can now make " + "" + "scrambled egg and tomato" + "" + " toppings."); + case 5: + return newstruct cs2func_script_1018_struct(28, 5988, "Members: Sweetcorn", "Members can now cook " + "" + "sweetcorn" + "" + "."); + case 6: + return newstruct cs2func_script_1018_struct(39, 6703, "Members: Baked potato with butter", "Members can now cook " + "" + "baked potatoes with butter" + "" + "."); + case 7: + return newstruct cs2func_script_1018_struct(41, 7054, "Members: Baked potato with chilli con carne", "Members can now cook " + "" + "baked potatoes with chilli con carne" + "" + "."); + case 8: + return newstruct cs2func_script_1018_struct(42, 7084, "Members: Fried onion (topping ingredient)", "Members can now make " + "" + "fried onion" + "" + " toppings."); + case 9: + return newstruct cs2func_script_1018_struct(46, 7082, "Members: Fried mushroom (topping ingredient)", "Members can now make " + "" + "fried mushroom" + "" + " toppings."); + case 10: + return newstruct cs2func_script_1018_struct(47, 6705, "Members: Baked potato with butter and cheese", "Members can now cook " + "" + "baked potatoes with butter and cheese" + "" + "."); + case 11: + return newstruct cs2func_script_1018_struct(51, 7056, "Members: Baked potato with egg and tomato", "Members can now cook " + "" + "baked potatoes with egg and tomato" + "" + "."); + case 12: + return newstruct cs2func_script_1018_struct(57, 7066, "Members: Fried mushroom and onion (topping)", "Members can now make " + "" + "fried mushroom and onion" + "" + " toppings."); + case 13: + return newstruct cs2func_script_1018_struct(64, 7058, "Members: Baked potato with mushroom and onion", "Members can now cook " + "" + "baked potatoes with mushroom and onion" + "" + "."); + case 14: + return newstruct cs2func_script_1018_struct(67, 7068, "Members: Tuna and sweetcorn (topping)", "Members can now make " + "" + "tuna and sweetcorn" + "" + " toppings."); + case 15: + return newstruct cs2func_script_1018_struct(68, 7060, "Members: Baked potato with tuna and sweetcorn", "Members can now cook " + "" + "baked potatoes with tuna and sweetcorn" + "" + "."); + case 16: + return newstruct cs2func_script_1018_struct(-1, 7620, "To make baked potatoes with toppings:", ""); + case 17: + return newstruct cs2func_script_1018_struct(-1, 7620, "1. Bake the potato on a range.", ""); + case 18: + return newstruct cs2func_script_1018_struct(-1, 7620, "2. Add some butter.", ""); + case 19: + return newstruct cs2func_script_1018_struct(-1, 7620, "3. If needed, combine topping ingredients by chopping them into a bowl.", ""); + case 20: + return newstruct cs2func_script_1018_struct(-1, 7620, "Ingredients for toppings:", ""); + case 21: + return newstruct cs2func_script_1018_struct(-1, 7620, "1. Chilli con carne: meat and spicy sauce (made from garlic and gnome spice)", ""); + case 22: + return newstruct cs2func_script_1018_struct(-1, 7620, "2. Egg and tomato: scrambled egg and tomato", ""); + case 23: + return newstruct cs2func_script_1018_struct(-1, 7620, "3. Mushroom and onion: fried bittercap mushroom and fried onion", ""); + case 24: + return newstruct cs2func_script_1018_struct(-1, 7620, "4. Tuna and sweetcorn: tuna and cooked sweetcorn", ""); + } + break; + case 10: + switch (arg1) { + case 0: + return newstruct cs2func_script_1018_struct(4, 1977, "Members: Chocolate milk", "Members can now make " + "" + "chocolate milk" + "" + "."); + case 1: + return newstruct cs2func_script_1018_struct(21, 2130, "Members: Cream", "Members can now churn " + "" + "cream" + "" + "."); + case 2: + return newstruct cs2func_script_1018_struct(38, 6697, "Members: Butter", "Members can now churn " + "" + "butter" + "" + "."); + case 3: + return newstruct cs2func_script_1018_struct(48, 1985, "Members: Cheese", "Members can now churn " + "" + "cheese" + "" + "."); + case 4: + return newstruct cs2func_script_1018_struct(-1, 7620, "To make churned dairy products:", " "); + case 5: + return newstruct cs2func_script_1018_struct(-1, 7620, "1. Get a bucket of milk, a pot of cream or a pot of butter.", " "); + case 6: + return newstruct cs2func_script_1018_struct(-1, 7620, "2. Use the milk, cream or butter in a churn.", " "); + case 7: + return newstruct cs2func_script_1018_struct(-1, 7620, "3. Milk can be churned into cream, then into butter, then into cheese.", " "); + } + break; + case 11: + switch (arg1) { + case 0: + return newstruct cs2func_script_1018_struct(6, 2084, "Members: Fruit Blast", "Members can now mix " + "" + "Fruit Blasts" + "" + "."); + case 1: + return newstruct cs2func_script_1018_struct(8, 2048, "Members: Pineapple punch", "Members can now mix " + "" + "pineapple punch" + "" + "."); + case 2: + return newstruct cs2func_script_1018_struct(10, 2217, "Members: Toad crunchies", "Members can now cook " + "" + "toad crunchies" + "" + "."); + case 3: + return newstruct cs2func_script_1018_struct(12, 2213, "Members: Spicy crunchies", "Members can now cook " + "" + "spicy crunchies" + "" + "."); + case 4: + return newstruct cs2func_script_1018_struct(14, 2205, "Members: Worm crunchies", "Members can now cook " + "" + "worm crunchies" + "" + "."); + case 5: + return newstruct cs2func_script_1018_struct(16, 2209, "Members: Chocolate chip crunchies", "Members can now cook " + "" + "chocolate chip crunchies" + "" + "."); + case 6: + return newstruct cs2func_script_1018_struct(18, 2054, "Members: Wizard Blizzard", "Members can now mix " + "" + "Wizard Blizzards" + "" + "."); + case 7: + return newstruct cs2func_script_1018_struct(20, 2080, "Members: Short Green Guy (SGG)", "Members can now mix " + "" + "Short Green Guys" + "" + "."); + case 8: + return newstruct cs2func_script_1018_struct(25, 2277, "Members: Fruit batta", "Members can now cook " + "" + "fruit battas" + "" + "."); + case 9: + return newstruct cs2func_script_1018_struct(26, 2255, "Members: Toad batta", "Members can now cook " + "" + "toad battas" + "" + "."); + case 10: + return newstruct cs2func_script_1018_struct(27, 2253, "Members: Worm batta", "Members can now cook " + "" + "worm battas" + "" + "."); + case 11: + return newstruct cs2func_script_1018_struct(28, 2281, "Members: Vegetable batta", "Members can now cook " + "" + "vegetable battas" + "" + "."); + case 12: + return newstruct cs2func_script_1018_struct(29, 2259, "Members: Cheese and tomato batta", "Members can now cook " + "" + "cheese and tomato battas" + "" + "."); + case 13: + return newstruct cs2func_script_1018_struct(30, 2191, "Members: Worm hole", "Members can now cook " + "" + "worm holes" + "" + "."); + case 14: + return newstruct cs2func_script_1018_struct(32, 2092, "Members: Drunk Dragon", "Members can now mix " + "" + "Drunk Dragons" + "" + "."); + case 15: + return newstruct cs2func_script_1018_struct(33, 2074, "Members: Chocolate Saturday", "Members can now mix " + "" + "Chocolate Saturdays" + "" + "."); + case 16: + return newstruct cs2func_script_1018_struct(35, 2195, "Members: Vegetable ball", "Members can now cook " + "" + "vegetable balls" + "" + "."); + case 17: + return newstruct cs2func_script_1018_struct(37, 2064, "Members: Blurberry Special", "Members can now mix " + "" + "Blurberry Specials" + "" + "."); + case 18: + return newstruct cs2func_script_1018_struct(40, 2187, "Members: Tangled toads' legs", "Members can now cook " + "" + "tangled toads' legs" + "" + "."); + case 19: + return newstruct cs2func_script_1018_struct(42, 2185, "Members: Chocolate bomb", "Members can now cook " + "" + "chocolate bombs" + "" + "."); + } + break; + case 12: + switch (arg1) { + case 0: + return newstruct cs2func_script_1018_struct(91, 18778, "Members: Starved ancient effigies", "Members can now investigate " + "" + "starved ancient effigies" + "" + " using their knowledge of Cooking."); + case 1: + return newstruct cs2func_script_1018_struct(93, 18779, "Members: Nourished ancient effigies", "Members can now investigate " + "" + "nourished ancient effigies" + "" + " using their knowledge of Cooking." + "" + "."); + case 2: + return newstruct cs2func_script_1018_struct(95, 18780, "Members: Sated ancient effigies", "Members can now investigate " + "" + "sated ancient effigies" + "" + " using their knowledge of Cooking." + "" + "."); + case 3: + return newstruct cs2func_script_1018_struct(97, 18781, "Members: Gorged ancient effigies", "Members can now investigate " + "" + "gorged ancient effigies" + "" + " using their knowledge of Cooking." + "" + "."); + } + break; + case 13: + switch (arg1) { + case 0: + return newstruct cs2func_script_1018_struct(1, 14162, "Members: Stealing Creation - class 1 food", "Members can now cook " + "" + "class 1 food" + "" + " in Stealing Creation."); + case 1: + return newstruct cs2func_script_1018_struct(20, 14164, "Members: Stealing Creation - class 2 food", "Members can now cook " + "" + "class 2 food" + "" + " in Stealing Creation."); + case 2: + return newstruct cs2func_script_1018_struct(40, 14166, "Members: Stealing Creation - class 3 food", "Members can now cook " + "" + "class 3 food" + "" + " in Stealing Creation."); + case 3: + return newstruct cs2func_script_1018_struct(60, 14168, "Members: Stealing Creation - class 4 food", "Members can now cook " + "" + "class 4 food" + "" + " in Stealing Creation."); + case 4: + return newstruct cs2func_script_1018_struct(80, 14170, "Members: Stealing Creation - class 5 food", "Members can now cook " + "" + "class 5 food" + "" + " in Stealing Creation."); + } + break; + case 14: + switch (arg1) { + case 0: + return newstruct cs2func_script_1018_struct(-1, 15707, "Dungeoneering skill tasks" + "
" + "As your Cooking level increases, you will be able to attempt higher-level cooking tasks within Daemonheim. You will also be more likely to succeed when attempting cooking tasks within Daemonheim.", ""); + case 1: + return newstruct cs2func_script_1018_struct(1, 18093, "Members: Cave potato", "Members can now cook " + "" + "cave potatoes" + "" + " within Daemonheim."); + case 2: + return newstruct cs2func_script_1018_struct(1, 18159, "Heim crab (Tier 1)", "You can now cook " + "" + "heim crabs" + "" + " within Daemonheim."); + case 3: + return newstruct cs2func_script_1018_struct(3, 18099, "Members: Heim crab potato (Tier 1)", "Members can now cook " + "" + "heim crab potatoes" + "" + " within Daemonheim."); + case 4: + return newstruct cs2func_script_1018_struct(6, 18119, "Members: Heim crab & gissel potato (Tier 1)", "Members can now cook " + "" + "heim crab & gissel potatoes" + "" + " within Daemonheim."); + case 5: + return newstruct cs2func_script_1018_struct(9, 18139, "Members: Heim crab & edicap potato (Tier 1)", "Members can now cook " + "" + "heim crab & edicap potatoes" + "" + " within Daemonheim."); + case 6: + return newstruct cs2func_script_1018_struct(10, 18161, "Red-eye (Tier 2)", "You can now cook " + "" + "red-eyes" + "" + " within Daemonheim."); + case 7: + return newstruct cs2func_script_1018_struct(13, 18101, "Members: Red-eye potato (Tier 2)", "Members can now cook " + "" + "red-eye potatoes" + "" + " within Daemonheim."); + case 8: + return newstruct cs2func_script_1018_struct(16, 18121, "Members: Red-eye & gissel potato (Tier 2)", "Members can now cook " + "" + "red-eye & gissel potatoes" + "" + " within Daemonheim."); + case 9: + return newstruct cs2func_script_1018_struct(19, 18141, "Members: Red-eye & edicap potato (Tier 2)", "Members can now cook " + "" + "red-eye & edicap potatoes" + "" + " within Daemonheim."); + case 10: + return newstruct cs2func_script_1018_struct(20, 18163, "Dusk eel (Tier 3)", "You can now cook " + "" + "dusk eels" + "" + " within Daemonheim."); + case 11: + return newstruct cs2func_script_1018_struct(23, 18103, "Members: Dusk eel potato (Tier 3)", "Members can now cook " + "" + "dusk eel potatoes" + "" + " within Daemonheim."); + case 12: + return newstruct cs2func_script_1018_struct(26, 18123, "Members: Dusk eel & gissel potato (Tier 3)", "Members can now cook " + "" + "dusk eel & gissel potatoes" + "" + " within Daemonheim."); + case 13: + return newstruct cs2func_script_1018_struct(29, 18143, "Members: Dusk eel & edicap potato (Tier 3)", "Members can now cook " + "" + "dusk eel & edicap potatoes" + "" + " within Daemonheim."); + case 14: + return newstruct cs2func_script_1018_struct(30, 18165, "Giant flatfish (Tier 4)", "You can now cook " + "" + "giant flatfish" + "" + " within Daemonheim."); + case 15: + return newstruct cs2func_script_1018_struct(33, 18105, "Members: Flatfish potato (Tier 4)", "Members can now cook " + "" + "flatfish potatoes" + "" + " within Daemonheim."); + case 16: + return newstruct cs2func_script_1018_struct(36, 18125, "Members: Flatfish & gissel potato (Tier 4)", "Members can now cook " + "" + "flatfish & gissel potatoes" + "" + " within Daemonheim."); + case 17: + return newstruct cs2func_script_1018_struct(39, 18145, "Members: Flatfish & edicap potato (Tier 4)", "Members can now cook " + "" + "flatfish & edicap potatoes" + "" + " within Daemonheim."); + case 18: + return newstruct cs2func_script_1018_struct(40, 18167, "Short-finned eel (Tier 5)", "You can now cook " + "" + "short-finned eels" + "" + " within Daemonheim."); + case 19: + return newstruct cs2func_script_1018_struct(43, 18107, "Members: Short-fin potato (Tier 5)", "Members can now cook " + "" + "short-fin potatoes" + "" + " within Daemonheim."); + case 20: + return newstruct cs2func_script_1018_struct(46, 18127, "Members: Short-fin & gissel potato (Tier 5)", "Members can now cook " + "" + "short-fin & gissel potatoes" + "" + " within Daemonheim."); + case 21: + return newstruct cs2func_script_1018_struct(49, 18147, "Members: Short-fin & edicap potato (Tier 5)", "Members can now cook " + "" + "short-fin & edicap potatoes" + "" + " within Daemonheim."); + case 22: + return newstruct cs2func_script_1018_struct(50, 18169, "Members: Web snipper (Tier 6)", "Members can now cook " + "" + "web snippers" + "" + " within Daemonheim."); + case 23: + return newstruct cs2func_script_1018_struct(53, 18109, "Members: Snipper potato (Tier 6)", "Members can now cook " + "" + "spinner potatoes" + "" + " within Daemonheim."); + case 24: + return newstruct cs2func_script_1018_struct(56, 18129, "Members: Snipper & gissel potato (Tier 6)", "Members can now cook " + "" + "snipper & gissel potatoes" + "" + " within Daemonheim."); + case 25: + return newstruct cs2func_script_1018_struct(59, 18149, "Members: Snipper & edicap potato (Tier 6)", "Members can now cook " + "" + "snipper & edicap potatoes" + "" + " within Daemonheim."); + case 26: + return newstruct cs2func_script_1018_struct(60, 18171, "Members: Bouldabass (Tier 7)", "Members can now cook " + "" + "bouldabass" + "" + " within Daemonheim."); + case 27: + return newstruct cs2func_script_1018_struct(63, 18111, "Members: Bouldabass potato (Tier 7)", "Members can now cook " + "" + "bouldabass potatoes" + "" + " within Daemonheim."); + case 28: + return newstruct cs2func_script_1018_struct(66, 18131, "Members: Bouldabass & gissel potato (Tier 7)", "Members can now cook " + "" + "bouldabass & gissel potatoes" + "" + " within Daemonheim."); + case 29: + return newstruct cs2func_script_1018_struct(69, 18151, "Members: Bouldabass & edicap potato (Tier 7)", "Members can now cook " + "" + "bouldabass & edicap potatoes" + "" + " within Daemonheim."); + case 30: + return newstruct cs2func_script_1018_struct(70, 18173, "Members: Salve eel (Tier 8)", "Members can now cook " + "" + "salve eels" + "" + " within Daemonheim."); + case 31: + return newstruct cs2func_script_1018_struct(73, 18113, "Members: Salve eel potato (Tier 8)", "Members can now cook " + "" + "salve eel potatoes" + "" + " within Daemonheim."); + case 32: + return newstruct cs2func_script_1018_struct(76, 18133, "Members: Salve eel & gissel potato (Tier 8)", "Members can now cook " + "" + "salve eel & gissel potatoes" + "" + " within Daemonheim."); + case 33: + return newstruct cs2func_script_1018_struct(79, 18153, "Members: Salve eel & edicap potato (Tier 8)", "Members can now cook " + "" + "salve eel & edicap potatoes" + "" + " within Daemonheim."); + case 34: + return newstruct cs2func_script_1018_struct(80, 18175, "Members: Blue crab (Tier 9)", "Members can now cook " + "" + "blue crabs" + "" + " within Daemonheim."); + case 35: + return newstruct cs2func_script_1018_struct(83, 18115, "Members: Blue crab potato (Tier 9)", "Members can now cook " + "" + "blue crab potatoes" + "" + " within Daemonheim."); + case 36: + return newstruct cs2func_script_1018_struct(86, 18135, "Members: Blue crab & gissel potato (Tier 9)", "Members can now cook " + "" + "blue crab & gissel potatoes" + "" + " within Daemonheim."); + case 37: + return newstruct cs2func_script_1018_struct(89, 18155, "Members: Blue crab & edicap potato (Tier 9)", "Members can now cook " + "" + "blue crab & edicap potatoes" + "" + " within Daemonheim."); + case 38: + return newstruct cs2func_script_1018_struct(90, 18177, "Members: Cave moray (Tier 10)", "Members can now cook " + "" + "cave morays" + "" + " within Daemonheim."); + case 39: + return newstruct cs2func_script_1018_struct(93, 18117, "Members: Moray potato (Tier 10)", "Members can now cook " + "" + "moray potatoes" + "" + " within Daemonheim."); + case 40: + return newstruct cs2func_script_1018_struct(96, 18137, "Members: Moray & gissel potato (Tier 10)", "Members can now cook " + "" + "moray & gissel potatoes" + "" + " within Daemonheim."); + case 41: + return newstruct cs2func_script_1018_struct(99, 18157, "Members: Moray & edicap potato (Tier 10)", "Members can now cook " + "" + "moray & edicap potatoes" + "" + " within Daemonheim."); + } + break; + case 15: + SWITCH (arg1) { + case 0: + GOTO flow_250 + case 1: + GOTO flow_251 + } + break; + flow_250: + return newstruct cs2func_script_1018_struct(32, 1949, "Chefs' Guild", "You are now qualified to enter the prestigious " + "" + "Chefs' Guild" + "" + "."); + flow_251: + return newstruct cs2func_script_1018_struct(99, 9801, "Skill mastery", "" + "Congratulations! You are now a master of " + "" + "Cooking" + "" + ". Members can visit the " + "" + "head chef" + "" + " at the " + "" + "Cooking Guild" + "" + ". He has something special that is only available to true masters of the " + "" + "Cooking" + "" + " skill!"); + } + return newstruct cs2func_script_1018_struct(0, -1, "", ""); +} diff --git a/dumps/scripts/1019.cs2 b/dumps/scripts/1019.cs2 new file mode 100644 index 0000000..009f505 --- /dev/null +++ b/dumps/scripts/1019.cs2 @@ -0,0 +1,21 @@ +cs2func_script_1019_struct(1,1,0) script_1019(int arg0) { + switch (arg0) { + case 0: + return newstruct cs2func_script_1019_struct(1, "Familiars"); + case 1: + return newstruct cs2func_script_1019_struct(1, "Summoning Scrolls"); + case 2: + return newstruct cs2func_script_1019_struct(1, "Pets"); + case 3: + return newstruct cs2func_script_1019_struct(1, "Equipment"); + case 4: + return newstruct cs2func_script_1019_struct(1, "Other"); + case 5: + return newstruct cs2func_script_1019_struct(1, "Minigames"); + case 6: + return newstruct cs2func_script_1019_struct(1, "Dungeoneering"); + case 7: + return newstruct cs2func_script_1019_struct(1, "Milestones"); + } + return newstruct cs2func_script_1019_struct(-1, ""); +} diff --git a/dumps/scripts/102.cs2 b/dumps/scripts/102.cs2 new file mode 100644 index 0000000..70f212c --- /dev/null +++ b/dumps/scripts/102.cs2 @@ -0,0 +1,31 @@ +void script_102(string arg0) { + if (globalint_5 > 1) { + return; + } + if (getDisplayMode() >= 2) { + setWidgetIsHidden(false, new WidgetPointer(746,73)); + } + setWidgetFont(497, new WidgetPointer(752,4)); + setWidgetFont(497, new WidgetPointer(752,5)); + setWidgetSize(0, 20, 1, 1, new WidgetPointer(752,4)); + setWidgetSize(0, 20, 1, 0, new WidgetPointer(752,5)); + setWidgetPosition(0, 0, 1, 0, new WidgetPointer(752,4)); + setWidgetPosition(0, 0, 1, 2, new WidgetPointer(752,5)); + setWidgetIsHidden(false, new WidgetPointer(752,3)); + setWidgetIsHidden(true, new WidgetPointer(752,7)); + setWidgetIsHidden(true, new WidgetPointer(752,8)); + setWidgetText(new WidgetPointer(752,4), arg0); + setWidgetText(new WidgetPointer(752,5), "Click here to continue"); + globalint_5 = 1; + setScriptCallOnMousePressed(101, "", new WidgetPointer(752,3)); + setScriptCallOnKeyPress(-1, "", new WidgetPointer(752,5)); + setWidgetRGB(new Color(0, 0, 128), new WidgetPointer(752,5)); + setScriptCallOnMouseOver(45, new WidgetPointer(-32768,3), 16777215, "Ii", new WidgetPointer(752,5)); + setScriptCallOnMouseExit(45, new WidgetPointer(-32768,3), 128, "Ii", new WidgetPointer(752,5)); + script_1188(); + setWidgetIsHidden(true, new WidgetPointer(752,6)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(752,5)); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(752,5)); + setScriptCallOnAnyWidgetOpenAndClose(3450, 1, "i", new WidgetPointer(752,5)); + return; +} diff --git a/dumps/scripts/1020.cs2 b/dumps/scripts/1020.cs2 new file mode 100644 index 0000000..25aa563 --- /dev/null +++ b/dumps/scripts/1020.cs2 @@ -0,0 +1,691 @@ +cs2func_script_1020_struct(2,2,0) script_1020(int arg0,int arg1) { + switch (arg0) { + case 0: + switch (arg1) { + case 0: + return newstruct cs2func_script_1020_struct(1, 12047, "Spirit wolf - Attack XP" + "
" + "Gold charm, wolf bones, 7 shards", "You can now infuse " + "" + "spirit wolf pouches" + "" + "."); + case 1: + return newstruct cs2func_script_1020_struct(4, 12043, "Dreadfowl - Magic XP" + "
" + "Gold charm, raw chicken, 8 shards", "You can now infuse " + "" + "dreadfowl pouches" + "" + "."); + case 2: + return newstruct cs2func_script_1020_struct(4, 19622, "Meerkats" + "
" + "Obtained from Treasure Trails.", "You can now summon " + "" + "meerkats" + "" + "."); + case 3: + return newstruct cs2func_script_1020_struct(10, 12059, "Spirit spider - Controlled XP" + "
" + "Gold charm, spider carcass, 8 shards", "You can now infuse " + "" + "spirit spider pouches" + "" + "."); + case 4: + return newstruct cs2func_script_1020_struct(13, 12019, "Thorny snail - Ranged XP" + "
" + "Gold charm, raw thin snail, 9 shards", "You can now infuse " + "" + "thorny snail pouches" + "" + "."); + case 5: + return newstruct cs2func_script_1020_struct(16, 12009, "Granite crab - Defence XP" + "
" + "Gold charm, iron ore, 7 shards", "You can now infuse " + "" + "granite crab pouches" + "" + "."); + case 6: + return newstruct cs2func_script_1020_struct(17, 12778, "Spirit mosquito - Attack XP" + "
" + "Gold charm, proboscis, 1 shard", "You can now infuse " + "" + "spirit mosquito pouches" + "" + "."); + case 7: + return newstruct cs2func_script_1020_struct(18, 12049, "Desert wyrm - Strength XP" + "
" + "Green charm, bucket of sand, 45 shards", "You can now infuse " + "" + "desert wyrm pouches" + "" + "."); + case 8: + return newstruct cs2func_script_1020_struct(19, 12055, "Spirit scorpion - Controlled XP" + "
" + "Crimson charm, bronze claws, 57 shards", "You can now infuse " + "" + "spirit scorpion pouches" + "" + "."); + case 9: + return newstruct cs2func_script_1020_struct(22, 12808, "Spirit Tz-Kih - Magic XP" + "
" + "Crimson charm, obsidian charm, 64 shards", "You can now infuse " + "" + "spirit Tz-Kih pouches" + "" + "."); + case 10: + return newstruct cs2func_script_1020_struct(23, 12067, "Albino rat - Attack XP" + "
" + "Blue charm, raw rat meat, 75 shards", "You can now infuse " + "" + "albino rat pouches" + "" + "."); + case 11: + return newstruct cs2func_script_1020_struct(25, 12063, "Spirit kalphite - Defence XP" + "
" + "Blue charm, potato cactus, 51 shards", "You can now infuse " + "" + "spirit kalphite pouches" + "" + "."); + case 12: + return newstruct cs2func_script_1020_struct(28, 12091, "Compost mound - Strength XP" + "
" + "Green charm, compost, 47 shards", "You can now infuse " + "" + "compost mound pouches" + "" + "."); + case 13: + return newstruct cs2func_script_1020_struct(29, 12800, "Giant chinchompa - Ranged XP" + "
" + "Blue charm, chinchompa, 84 shards", "You can now infuse " + "" + "giant chinchompa pouches" + "" + "."); + case 14: + return newstruct cs2func_script_1020_struct(31, 12053, "Vampyre bat - Controlled XP" + "
" + "Crimson charm, vampyre dust, 81 shards", "You can now infuse " + "" + "vampyre bat pouches" + "" + "."); + case 15: + return newstruct cs2func_script_1020_struct(32, 12065, "Honey badger - Strength XP" + "
" + "Crimson charm, honeycomb, 84 shards", "You can now infuse " + "" + "honey badger pouches" + "" + "."); + case 16: + return newstruct cs2func_script_1020_struct(33, 12021, "Beaver" + "
" + "Green charm, willow logs, 72 shards", "You can now infuse " + "" + "beaver pouches" + "" + "."); + case 17: + return newstruct cs2func_script_1020_struct(34, 12818, "Void ravager - Strength XP" + "
" + "Green charm, ravager charm, 74 shards", "You can now infuse " + "" + "void ravager pouches" + "" + "."); + case 18: + return newstruct cs2func_script_1020_struct(34, 12780, "Void spinner - Defence XP" + "
" + "Blue charm, spinner charm, 74 shards", "You can now infuse " + "" + "void spinner pouches" + "" + "."); + case 19: + return newstruct cs2func_script_1020_struct(34, 12798, "Void torcher - Magic XP" + "
" + "Blue charm, torcher charm, 74 shards", "You can now infuse " + "" + "void torcher pouches" + "" + "."); + case 20: + return newstruct cs2func_script_1020_struct(34, 12814, "Void shifter - Attack XP" + "
" + "Blue charm, shifter charm, 74 shards", "You can now infuse " + "" + "void shifter pouches" + "" + "."); + case 21: + return newstruct cs2func_script_1020_struct(36, 12073, "Bronze minotaur - Defence XP" + "
" + "Blue charm, bronze bar, 102 shards", "You can now infuse " + "" + "bronze minotaur pouches" + "" + "."); + case 22: + return newstruct cs2func_script_1020_struct(40, 12087, "Bull ant - Controlled XP" + "
" + "Gold charm, marigolds, 11 shards", "You can now infuse " + "" + "bull ant pouches" + "" + "."); + case 23: + return newstruct cs2func_script_1020_struct(41, 12071, "Macaw" + "
" + "Green charm, guam, 78 shards", "You can now infuse " + "" + "macaw pouches" + "" + "."); + case 24: + return newstruct cs2func_script_1020_struct(42, 12051, "Evil turnip - Ranged XP" + "
" + "Crimson charm, carved turnip, 104 shards", "You can now infuse " + "" + "evil turnip pouches" + "" + "."); + case 25: + return newstruct cs2func_script_1020_struct(43, 12095, "Spirit cockatrice - Magic XP" + "
" + "Green charm, cockatrice egg, 88 shards", "You can now infuse " + "" + "spirit cockatrice pouches" + "" + "."); + case 26: + return newstruct cs2func_script_1020_struct(43, 12097, "Spirit guthatrice - Magic XP" + "
" + "Green charm, guthatrice egg, 88 shards", "You can now infuse " + "" + "spirit guthatrice pouches" + "" + "."); + case 27: + return newstruct cs2func_script_1020_struct(43, 12099, "Spirit saratrice - Magic XP" + "
" + "Green charm, saratrice egg, 88 shards", "You can now infuse " + "" + "spirit saratrice pouches" + "" + "."); + case 28: + return newstruct cs2func_script_1020_struct(43, 12101, "Spirit zamatrice - Magic XP" + "
" + "Green charm, zamatrice egg, 88 shards", "You can now infuse " + "" + "spirit zamatrice pouches" + "" + "."); + case 29: + return newstruct cs2func_script_1020_struct(43, 12103, "Spirit pengatrice - Magic XP" + "
" + "Green charm, pengatrice egg, 88 shards", "You can now infuse " + "" + "spirit pengatrice pouches" + "" + "."); + case 30: + return newstruct cs2func_script_1020_struct(43, 12105, "Spirit coraxatrice - Magic XP" + "
" + "Green charm, coraxatrice egg, 88 shards", "You can now infuse " + "" + "spirit coraxatrice pouches" + "" + "."); + case 31: + return newstruct cs2func_script_1020_struct(43, 12107, "Spirit vulatrice - Magic XP" + "
" + "Green charm, vulatrice egg, 88 shards", "You can now infuse " + "" + "spirit vulatrice pouches" + "" + "."); + case 32: + return newstruct cs2func_script_1020_struct(46, 12075, "Iron minotaur - Defence XP" + "
" + "Blue charm, iron bar, 125 shards", "You can now infuse " + "" + "iron minotaur pouches" + "" + "."); + case 33: + return newstruct cs2func_script_1020_struct(46, 12816, "Pyrelord - Strength XP" + "
" + "Crimson charm, tinderbox, 111 shards", "You can now infuse " + "" + "pyrelord" + "" + " pouches."); + case 34: + return newstruct cs2func_script_1020_struct(47, 12041, "Magpie" + "
" + "Green charm, gold ring, 88 shards", "You can now infuse " + "" + "magpie pouches" + "" + "."); + case 35: + return newstruct cs2func_script_1020_struct(49, 12061, "Bloated leech - Attack XP" + "
" + "Crimson charm, raw beef, 117 shards", "You can now infuse " + "" + "bloated leech pouches" + "" + "."); + case 36: + return newstruct cs2func_script_1020_struct(52, 12007, "Spirit terrorbird - Controlled XP" + "
" + "Gold charm, raw bird meat, 12 shards", "You can now infuse " + "" + "spirit terrorbird pouches" + "" + "."); + case 37: + return newstruct cs2func_script_1020_struct(54, 12035, "Abyssal parasite - Magic XP" + "
" + "Green charm, abyssal charm, 106 shards", "You can now infuse " + "" + "abyssal parasite pouches" + "" + "."); + case 38: + return newstruct cs2func_script_1020_struct(55, 12027, "Spirit jelly - Strength XP" + "
" + "Blue charm, jug of water, 151 shards", "You can now infuse " + "" + "spirit jelly pouches" + "" + "."); + case 39: + return newstruct cs2func_script_1020_struct(56, 12077, "Steel minotaur - Defence XP" + "
" + "Blue charm, steel bar, 141 shards", "You can now infuse " + "" + "steel minotaur pouches" + "" + "."); + case 40: + return newstruct cs2func_script_1020_struct(56, 12531, "Ibis" + "
" + "Green charm, harpoon, 109 shards", "You can now infuse " + "" + "ibis pouches" + "" + "."); + case 41: + return newstruct cs2func_script_1020_struct(57, 12812, "Spirit kyatt - Attack XP" + "
" + "Blue charm, kyatt fur, 153 shards", "You can now infuse " + "" + "spirit kyatt pouches" + "" + "."); + case 42: + return newstruct cs2func_script_1020_struct(57, 12784, "Spirit larupia - Controlled XP" + "
" + "Blue charm, larupia fur, 155 shards", "You can now infuse " + "" + "spirit larupia pouches" + "" + "."); + case 43: + return newstruct cs2func_script_1020_struct(57, 12810, "Spirit graahk - Strength XP" + "
" + "Blue charm, graahk fur, 154 shards", "You can now infuse " + "" + "spirit graahk pouches" + "" + "."); + case 44: + return newstruct cs2func_script_1020_struct(58, 12023, "Karamthulhu overlord - Ranged XP" + "
" + "Blue charm, empty fishbowl, 144 shards", "You can now infuse " + "" + "karamthulhu overlord pouches" + "" + "."); + case 45: + return newstruct cs2func_script_1020_struct(61, 12085, "Smoke devil - Magic XP" + "
" + "Crimson charm, goat's horn dust, 141 shards", "You can now infuse " + "" + "smoke devil pouches" + "" + "."); + case 46: + return newstruct cs2func_script_1020_struct(62, 12037, "Abyssal lurker - Controlled XP" + "
" + "Green charm, abyssal charm, 119 shards", "You can now infuse " + "" + "abyssal lurker pouches" + "" + "."); + case 47: + return newstruct cs2func_script_1020_struct(63, 12015, "Spirit cobra - Attack XP" + "
" + "Crimson charm, snake hide, 116 shards", "You can now infuse " + "" + "spirit cobra pouches" + "" + "."); + case 48: + return newstruct cs2func_script_1020_struct(64, 12045, "Stranger plant - Controlled XP" + "
" + "Crimson charm, bagged plant, 128 shards", "You can now infuse " + "" + "stranger plant pouches" + "" + "."); + case 49: + return newstruct cs2func_script_1020_struct(66, 12079, "Mithril minotaur - Defence XP" + "
" + "Blue charm, mithril bar, 152 shards", "You can now infuse " + "" + "mithril minotaur pouches" + "" + "."); + case 50: + return newstruct cs2func_script_1020_struct(66, 12123, "Barker toad - Strength XP" + "
" + "Gold charm, swamp toad, 11 shards", "You can now infuse " + "" + "barker toad pouches" + "" + "."); + case 51: + return newstruct cs2func_script_1020_struct(67, 12031, "War tortoise - Defence XP" + "
" + "Gold charm, tortoise shell, 1 shard", "You can now infuse " + "" + "war tortoise pouches" + "" + "."); + case 52: + return newstruct cs2func_script_1020_struct(68, 12029, "Bunyip - Attack XP" + "
" + "Green charm, raw shark, 110 shards", "You can now infuse " + "" + "bunyip pouches" + "" + "."); + case 53: + return newstruct cs2func_script_1020_struct(69, 12033, "Fruit bat" + "
" + "Green charm, banana, 130 shards", "You can now infuse " + "" + "fruit bat pouches" + "" + "."); + case 54: + return newstruct cs2func_script_1020_struct(70, 12820, "Ravenous locust - Attack XP" + "
" + "Crimson charm, pot of flour, 79 shards", "You can now infuse " + "" + "ravenous locust pouches" + "" + "."); + case 55: + return newstruct cs2func_script_1020_struct(71, 12057, "Arctic bear - Controlled XP" + "
" + "Gold charm, polar kebbit fur, 14 shards", "You can now infuse " + "" + "arctic bear pouches" + "" + "."); + case 56: + return newstruct cs2func_script_1020_struct(72, 14623, "Phoenix - Magic XP" + "
" + "Crimson charm, phoenix quill, 165 shards (after In Pyre Need)", "You can now infuse " + "" + "phoenix pouches" + "" + " (after In Pyre Need)" + "" + "."); + case 57: + return newstruct cs2func_script_1020_struct(73, 12792, "Obsidian golem - Strength XP" + "
" + "Blue charm, obsidian charm, 195 shards", "You can now infuse " + "" + "obsidian golem pouches" + "" + "."); + case 58: + return newstruct cs2func_script_1020_struct(74, 12069, "Granite lobster - Defence XP" + "
" + "Crimson charm, granite (500g, 2kg or 5kg), 166 shards", "You can now infuse " + "" + "granite lobster pouches" + "" + "."); + case 59: + return newstruct cs2func_script_1020_struct(75, 12011, "Praying mantis - Attack XP" + "
" + "Crimson charm, flowers (any except black or white), 168 shards", "You can now infuse " + "" + "praying mantis pouches" + "" + "."); + case 60: + return newstruct cs2func_script_1020_struct(76, 12782, "Forge regent - Ranged XP" + "
" + "Green charm, ruby harvest, 141 shards", "You can now infuse " + "" + "forge regent pouches" + "" + "."); + case 61: + return newstruct cs2func_script_1020_struct(76, 12081, "Adamant minotaur - Defence XP" + "
" + "Blue charm, adamant bar, 144 shards", "You can now infuse " + "" + "adamant minotaur pouches" + "" + "."); + case 62: + return newstruct cs2func_script_1020_struct(77, 12794, "Talon beast - Strength XP" + "
" + "Crimson charm, talon beast charm, 174 shards", "You can now infuse " + "" + "talon beast pouches" + "" + "."); + case 63: + return newstruct cs2func_script_1020_struct(78, 12013, "Giant ent - Controlled XP" + "
" + "Green charm, willow branch, 124 shards", "You can now infuse " + "" + "giant ent pouches" + "" + "."); + case 64: + return newstruct cs2func_script_1020_struct(79, 12802, "Fire titan - Magic XP" + "
" + "Blue charm, fire talisman, 198 shards", "You can now infuse " + "" + "fire titan pouches" + "" + "."); + case 65: + return newstruct cs2func_script_1020_struct(79, 12804, "Moss titan - Strength XP" + "
" + "Blue charm, earth talisman, 202 shards", "You can now infuse " + "" + "moss titan pouches" + "" + "."); + case 66: + return newstruct cs2func_script_1020_struct(79, 12806, "Ice titan - Attack XP" + "
" + "Blue charm, air talisman, water talisman, 198 shards", "You can now infuse " + "" + "ice titan pouches" + "" + "."); + case 67: + return newstruct cs2func_script_1020_struct(80, 12025, "Hydra - Ranged XP" + "
" + "Green charm, water orb, 128 shards", "You can now infuse " + "" + "hydra pouches" + "" + "."); + case 68: + return newstruct cs2func_script_1020_struct(83, 12017, "Spirit dagannoth - Controlled XP" + "
" + "Crimson charm, dagannoth hide, 1 shard", "You can now infuse " + "" + "spirit dagannoth pouches" + "" + "."); + case 69: + return newstruct cs2func_script_1020_struct(83, 12788, "Lava titan - Strength XP" + "
" + "Blue charm, obsidian charm, 219 shards", "You can now infuse " + "" + "lava titan pouches" + "" + "."); + case 70: + return newstruct cs2func_script_1020_struct(85, 12776, "Swamp titan - Attack XP" + "
" + "Crimson charm, swamp lizard, 150 shards", "You can now infuse " + "" + "swamp titan pouches" + "" + "."); + case 71: + return newstruct cs2func_script_1020_struct(86, 12083, "Rune minotaur - Defence XP" + "
" + "Blue charm, rune bar, 1 shard", "You can now infuse " + "" + "rune minotaur pouches" + "" + "."); + case 72: + return newstruct cs2func_script_1020_struct(88, 12039, "Unicorn stallion - Controlled XP" + "
" + "Green charm, unicorn horn, 140 shards", "You can now infuse " + "" + "unicorn stallion pouches" + "" + "."); + case 73: + return newstruct cs2func_script_1020_struct(89, 12786, "Geyser titan - Ranged XP" + "
" + "Blue charm, water talisman, 222 shards", "You can now infuse " + "" + "geyser titan pouches" + "" + "."); + case 74: + return newstruct cs2func_script_1020_struct(92, 12089, "Wolpertinger - Magic XP" + "
" + "Crimson charm, raw rabbit, wolf bones, 203 shards", "You can now infuse " + "" + "wolpertinger pouches" + "" + "."); + case 75: + return newstruct cs2func_script_1020_struct(93, 12796, "Abyssal titan - Attack XP" + "
" + "Green charm, abyssal charm, 113 shards", "You can now infuse " + "" + "abyssal titan pouches" + "" + "."); + case 76: + return newstruct cs2func_script_1020_struct(95, 12822, "Iron titan - Defence XP" + "
" + "Crimson charm, iron platebody, 198 shards", "You can now infuse " + "" + "iron titan pouches" + "" + "."); + case 77: + return newstruct cs2func_script_1020_struct(96, 12093, "Pack yak - Strength XP" + "
" + "Crimson charm, yak hide, 211 shards", "You can now infuse " + "" + "pack yak pouches" + "" + "."); + case 78: + return newstruct cs2func_script_1020_struct(99, 12790, "Steel titan - Ranged XP" + "
" + "Crimson charm, steel platebody, 178 shards", "You can now infuse " + "" + "steel titan pouches" + "" + "."); + } + break; + case 1: + switch (arg1) { + case 0: + return newstruct cs2func_script_1020_struct(1, 12425, "Howl", "You can now use " + "" + "Howl scrolls" + "" + "."); + case 1: + return newstruct cs2func_script_1020_struct(4, 12445, "Dreadfowl Strike", "You can now use " + "" + "Dreadfowl Strike scrolls" + "" + "."); + case 2: + return newstruct cs2func_script_1020_struct(4, 19621, "Fetch Casket", "You can now use " + "" + "Fetch Casket scrolls" + "" + "."); + case 3: + return newstruct cs2func_script_1020_struct(10, 12428, "Egg Spawn", "You can now use " + "" + "Egg Spawn scrolls" + "" + "."); + case 4: + return newstruct cs2func_script_1020_struct(13, 12459, "Slime Spray", "You can now use " + "" + "Slime Spray scrolls" + "" + "."); + case 5: + return newstruct cs2func_script_1020_struct(16, 12533, "Stony Shell", "You can now use " + "" + "Stony Shell scrolls" + "" + "."); + case 6: + return newstruct cs2func_script_1020_struct(17, 12838, "Pester", "You can now use " + "" + "Pester scrolls" + "" + "."); + case 7: + return newstruct cs2func_script_1020_struct(18, 12460, "Electric Lash", "You can now use " + "" + "Electric Lash scrolls" + "" + "."); + case 8: + return newstruct cs2func_script_1020_struct(19, 12432, "Venom Shot", "You can now use " + "" + "Venom Shot scrolls" + "" + "."); + case 9: + return newstruct cs2func_script_1020_struct(22, 12839, "Fireball Assault", "You can now use " + "" + "Fireball Assault scrolls" + "" + "."); + case 10: + return newstruct cs2func_script_1020_struct(23, 12430, "Cheese Feast", "You can now use " + "" + "Cheese Feast scrolls" + "" + "."); + case 11: + return newstruct cs2func_script_1020_struct(25, 12446, "Sandstorm", "You can now use " + "" + "Sandstorm scrolls" + "" + "."); + case 12: + return newstruct cs2func_script_1020_struct(28, 12440, "Generate Compost", "You can now use " + "" + "Generate Compost scrolls" + "" + "."); + case 13: + return newstruct cs2func_script_1020_struct(29, 12834, "Explode", "You can now use " + "" + "Explode scrolls" + "" + "."); + case 14: + return newstruct cs2func_script_1020_struct(31, 12447, "Vampyre Touch", "You can now use " + "" + "Vampyre Touch scrolls" + "" + "."); + case 15: + return newstruct cs2func_script_1020_struct(32, 12433, "Insane Ferocity", "You can now use " + "" + "Insane Ferocity scrolls" + "" + "."); + case 16: + return newstruct cs2func_script_1020_struct(33, 12429, "Multichop", "You can now use " + "" + "Multichop scrolls" + "" + "."); + case 17: + return newstruct cs2func_script_1020_struct(34, 12443, "Call to Arms", "You can now use " + "" + "Call to Arms scrolls" + "" + "."); + case 18: + return newstruct cs2func_script_1020_struct(36, 12461, "Bronze Bull Rush", "You can now use " + "" + "Bronze Bull Rush scrolls" + "" + "."); + case 19: + return newstruct cs2func_script_1020_struct(40, 12431, "Unburden", "You can now use " + "" + "Unburden scrolls" + "" + "."); + case 20: + return newstruct cs2func_script_1020_struct(41, 12422, "Herbcall", "You can now use " + "" + "Herbcall scrolls" + "" + "."); + case 21: + return newstruct cs2func_script_1020_struct(42, 12448, "Evil Flames", "You can now use " + "" + "Evil Flames scrolls" + "" + "."); + case 22: + return newstruct cs2func_script_1020_struct(43, 12458, "Petrifying Gaze", "You can now use " + "" + "Petrifying Gaze scrolls" + "" + "."); + case 23: + return newstruct cs2func_script_1020_struct(46, 12462, "Iron Bull Rush", "You can now use " + "" + "Iron Bull Rush scrolls" + "" + "."); + case 24: + return newstruct cs2func_script_1020_struct(46, 12829, "Immense Heat", "You can now use " + "" + "Immense Heat scrolls" + "" + "."); + case 25: + return newstruct cs2func_script_1020_struct(47, 12426, "Thieving Fingers", "You can now use " + "" + "Thieving Fingers scrolls" + "" + "."); + case 26: + return newstruct cs2func_script_1020_struct(49, 12444, "Blood Drain", "You can now use " + "" + "Blood Drain scrolls" + "" + "."); + case 27: + return newstruct cs2func_script_1020_struct(52, 12441, "Tireless Run", "You can now use " + "" + "Tireless Run scrolls" + "" + "."); + case 28: + return newstruct cs2func_script_1020_struct(54, 12454, "Abyssal Drain", "You can now use " + "" + "Abyssal Drain scrolls" + "" + "."); + case 29: + return newstruct cs2func_script_1020_struct(55, 12453, "Dissolve", "You can now use " + "" + "Dissolve scrolls" + "" + "."); + case 30: + return newstruct cs2func_script_1020_struct(56, 12463, "Steel Bull Rush", "You can now use " + "" + "Steel Bull Rush scrolls" + "" + "."); + case 31: + return newstruct cs2func_script_1020_struct(56, 12424, "Fish Rain", "You can now use " + "" + "Fish Rain scrolls" + "" + "."); + case 32: + return newstruct cs2func_script_1020_struct(57, 12836, "Ambush", "You can now use " + "" + "Ambush scrolls" + "" + "."); + case 33: + return newstruct cs2func_script_1020_struct(57, 12840, "Rending", "You can now use " + "" + "Rending scrolls" + "" + "."); + case 34: + return newstruct cs2func_script_1020_struct(57, 12835, "Goad", "You can now use " + "" + "Goad scrolls" + "" + "."); + case 35: + return newstruct cs2func_script_1020_struct(58, 12455, "Doomsphere Device", "You can now use " + "" + "Doomsphere Device scrolls" + "" + "."); + case 36: + return newstruct cs2func_script_1020_struct(61, 12468, "Dust Cloud", "You can now use " + "" + "Dust Cloud scrolls" + "" + "."); + case 37: + return newstruct cs2func_script_1020_struct(62, 12427, "Abyssal Stealth", "You can now use " + "" + "Abyssal Stealth scrolls" + "" + "."); + case 38: + return newstruct cs2func_script_1020_struct(63, 12436, "Ophidian Incubation", "You can now use " + "" + "Ophidian Incubation scrolls" + "" + "."); + case 39: + return newstruct cs2func_script_1020_struct(64, 12467, "Poisonous Blast", "You can now use " + "" + "Poisonous Blast scrolls" + "" + "."); + case 40: + return newstruct cs2func_script_1020_struct(66, 12464, "Mithril Bull Rush", "You can now use " + "" + "Mithril Bull Rush scrolls" + "" + "."); + case 41: + return newstruct cs2func_script_1020_struct(66, 12452, "Toad Bark", "You can now use " + "" + "Toad Bark scrolls" + "" + "."); + case 42: + return newstruct cs2func_script_1020_struct(67, 12439, "Testudo", "You can now use " + "" + "Testudo scrolls" + "" + "."); + case 43: + return newstruct cs2func_script_1020_struct(68, 12438, "Swallow Whole", "You can now use " + "" + "Swallow Whole scrolls" + "" + "."); + case 44: + return newstruct cs2func_script_1020_struct(69, 12423, "Fruitfall", "You can now use " + "" + "Fruitfall scrolls" + "" + "."); + case 45: + return newstruct cs2func_script_1020_struct(70, 12830, "Famine", "You can now use " + "" + "Famine scrolls" + "" + "."); + case 46: + return newstruct cs2func_script_1020_struct(71, 12451, "Arctic Blast", "You can now use " + "" + "Arctic Blast scrolls" + "" + "."); + case 47: + return newstruct cs2func_script_1020_struct(72, 14622, "Rise from the Ashes (after In Pyre Need)", "You can now use " + "" + "Rise from the Ashes scrolls" + "" + " (after In Pyre Need)."); + case 48: + return newstruct cs2func_script_1020_struct(73, 12826, "Volcanic Strength", "You can now use " + "" + "Volcanic Strength scrolls" + "" + "."); + case 49: + return newstruct cs2func_script_1020_struct(74, 12449, "Crushing Claw", "You can now use " + "" + "Crushing Claw scrolls" + "" + "."); + case 50: + return newstruct cs2func_script_1020_struct(75, 12450, "Mantis Strike", "You can now use " + "" + "Mantis Strike scrolls" + "" + "."); + case 51: + return newstruct cs2func_script_1020_struct(76, 12841, "Inferno", "You can now use " + "" + "Inferno scrolls" + "" + "."); + case 52: + return newstruct cs2func_script_1020_struct(76, 12465, "Adamant Bull Rush", "You can now use " + "" + "Adamant Bull Rush scrolls" + "" + "."); + case 53: + return newstruct cs2func_script_1020_struct(77, 12831, "Deadly Claw", "You can now use " + "" + "Deadly Claw scrolls" + "" + "."); + case 54: + return newstruct cs2func_script_1020_struct(78, 12457, "Acorn Missile", "You can now use " + "" + "Acorn Missile scrolls" + "" + "."); + case 55: + return newstruct cs2func_script_1020_struct(79, 12824, "Titan's Constitution", "You can now use " + "" + "Titan's Constitution scrolls" + "" + "."); + case 56: + return newstruct cs2func_script_1020_struct(80, 12442, "Regrowth", "You can now use " + "" + "Regrowth scrolls" + "" + "."); + case 57: + return newstruct cs2func_script_1020_struct(83, 12456, "Spike Shot", "You can now use " + "" + "Spike Shot scrolls" + "" + "."); + case 58: + return newstruct cs2func_script_1020_struct(83, 12837, "Ebon Thunder", "You can now use " + "" + "Ebon Thunder scrolls" + "" + "."); + case 59: + return newstruct cs2func_script_1020_struct(85, 12832, "Swamp Plague", "You can now use " + "" + "Swamp Plague scrolls" + "" + "."); + case 60: + return newstruct cs2func_script_1020_struct(86, 12466, "Rune Bull Rush", "You can now use " + "" + "Rune Bull Rush scrolls" + "" + "."); + case 61: + return newstruct cs2func_script_1020_struct(88, 12434, "Healing Aura", "You can now use " + "" + "Healing Aura scrolls" + "" + "."); + case 62: + return newstruct cs2func_script_1020_struct(89, 12833, "Boil", "You can now use " + "" + "Boil scrolls" + "" + "."); + case 63: + return newstruct cs2func_script_1020_struct(92, 12437, "Magic Focus", "You can now use " + "" + "Magic Focus scrolls" + "" + "."); + case 64: + return newstruct cs2func_script_1020_struct(93, 12827, "Essence Shipment", "You can now use " + "" + "Essence Shipment scrolls" + "" + "."); + case 65: + return newstruct cs2func_script_1020_struct(95, 12828, "Iron Within", "You can now use " + "" + "Iron Within scrolls" + "" + "."); + case 66: + return newstruct cs2func_script_1020_struct(96, 12435, "Winter Storage", "You can now use " + "" + "Winter Storage scrolls" + "" + "."); + case 67: + return newstruct cs2func_script_1020_struct(99, 12825, "Steel of Legends", "You can now use " + "" + "Steel of Legends scrolls" + "" + "."); + } + break; + case 2: + switch (arg1) { + case 0: + return newstruct cs2func_script_1020_struct(4, 12196, "Bulldog", "You can now raise " + "" + "bulldogs" + "" + "."); + case 1: + return newstruct cs2func_script_1020_struct(4, 12194, "Dalmatian", "You can now raise " + "" + "dalmatians" + "" + "."); + case 2: + return newstruct cs2func_script_1020_struct(4, 12192, "Greyhound", "You can now raise " + "" + "greyhounds" + "" + "."); + case 3: + return newstruct cs2func_script_1020_struct(4, 12193, "Labrador", "You can now raise " + "" + "labradors" + "" + "."); + case 4: + return newstruct cs2func_script_1020_struct(4, 12195, "Sheepdog", "You can now raise " + "" + "sheepdogs" + "" + "."); + case 5: + return newstruct cs2func_script_1020_struct(4, 12191, "Terrier", "You can now raise " + "" + "terriers" + "" + "."); + case 6: + return newstruct cs2func_script_1020_struct(4, 14652, "Creeping hand", "You can now keep " + "" + "creeping hands" + "" + "."); + case 7: + return newstruct cs2func_script_1020_struct(4, 14653, "Minitrice", "You can now keep " + "" + "minitrices" + "" + "."); + case 8: + return newstruct cs2func_script_1020_struct(4, 14654, "Baby basilisk", "You can now keep " + "" + "baby basilisks" + "" + "."); + case 9: + return newstruct cs2func_script_1020_struct(4, 14655, "Baby kurask", "You can now keep " + "" + "baby kurasks" + "" + "."); + case 10: + return newstruct cs2func_script_1020_struct(4, 14651, "Abyssal minion", "You can now keep " + "" + "abyssal minions" + "" + "."); + case 11: + return newstruct cs2func_script_1020_struct(4, 15483, "Rune guardian" + "
" + " (after Rune Mechanics)", "You can now keep " + "" + "rune guardians" + "" + " (after Rune Mechanics)"); + case 12: + return newstruct cs2func_script_1020_struct(10, 12488, "Gecko", "You can now raise " + "" + "geckos" + "" + "."); + case 13: + return newstruct cs2func_script_1020_struct(10, 12547, "Platypus" + "
" + " (after As a First Resort...)", "You can now raise " + "" + "platypodes" + "" + " (after As a First Resort...)."); + case 14: + return newstruct cs2func_script_1020_struct(23, 14533, "Broav" + "
" + " (after While Guthix Sleeps...)", "You can now raise " + "" + "broavs" + "" + " " + "
" + " (after While Guthix Sleeps...)."); + case 15: + return newstruct cs2func_script_1020_struct(30, 12188, "Penguin", "You can now raise " + "" + "penguins" + "" + "."); + case 16: + return newstruct cs2func_script_1020_struct(37, 18668, "Tooth pet", "You can now raise " + "" + "tooth pets" + "" + "."); + case 17: + return newstruct cs2func_script_1020_struct(40, 12198, "Giant crab", "You can now raise " + "" + "giant crabs" + "" + "."); + case 18: + return newstruct cs2func_script_1020_struct(50, 12485, "Raven", "You can now raise " + "" + "ravens" + "" + "."); + case 19: + return newstruct cs2func_script_1020_struct(60, 12200, "Squirrel", "You can now raise " + "" + "squirrels" + "" + "."); + case 20: + return newstruct cs2func_script_1020_struct(70, 12185, "Saradomin owl", "You can now raise " + "" + "Saradomin owls" + "" + "."); + case 21: + return newstruct cs2func_script_1020_struct(70, 12187, "Guthix raptor", "You can now raise " + "" + "Guthix raptors" + "" + "."); + case 22: + return newstruct cs2func_script_1020_struct(70, 12186, "Zamorak hawk", "You can now raise " + "" + "Zamorak hawks" + "" + "."); + case 23: + return newstruct cs2func_script_1020_struct(71, 13336, "Ex-ex-parrot" + "
" + " (after Rocking Out)", "You can now raise " + "" + "ex-ex-parrots" + "" + " (after Rocking Out)."); + case 24: + return newstruct cs2func_script_1020_struct(72, 14627, "Cute phoenix eggling" + "
" + " (after In Pyre Need)", "You can now raise " + "" + "cute phoenix egglings" + "" + " (after In Pyre Need)."); + case 25: + return newstruct cs2func_script_1020_struct(72, 14626, "Mean phoenix eggling" + "
" + " (after In Pyre Need)", "You can now raise " + "" + "mean phoenix egglings" + "" + " (after In Pyre Need)."); + case 26: + return newstruct cs2func_script_1020_struct(80, 12199, "Raccoon", "You can now raise " + "" + "raccoons" + "" + "."); + case 27: + return newstruct cs2func_script_1020_struct(80, 19894, "Sneakerpeeper" + "
" + " (with 80 Dungeoneering)", "You can now raise " + "" + "sneakerpeepers" + "" + ". (You also need level 80 Dungeoneering.)"); + case 28: + return newstruct cs2func_script_1020_struct(85, 12190, "Vulture", "You can now raise " + "" + "vultures" + "" + "."); + case 29: + return newstruct cs2func_script_1020_struct(90, 12203, "Chameleon", "You can now raise " + "" + "chameleons" + "" + "."); + case 30: + return newstruct cs2func_script_1020_struct(95, 12201, "Monkey", "You can now raise " + "" + "monkeys" + "" + "."); + case 31: + return newstruct cs2func_script_1020_struct(99, 12197, "Dragon", "You can now raise " + "" + "dragons" + "" + "."); + case 32: + return newstruct cs2func_script_1020_struct(99, 21512, "TzRek Jad", "You can now keep " + "" + "TzRek Jad" + "" + "."); + } + break; + case 3: + switch (arg1) { + case 0: + return newstruct cs2func_script_1020_struct(10, 12204, "Antlers", "You can now use " + "" + "antlers" + "" + "."); + case 1: + return newstruct cs2func_script_1020_struct(20, 1161, "Adamant full helm" + "
" + " (with 30 Defence)", "You can now have " + "" + "adamant full helms" + "" + " enchanted to hold Summoning scrolls. (You also need level 30 Defence)."); + case 2: + return newstruct cs2func_script_1020_struct(20, 6326, "Snakeskin bandana" + "
" + " (with 30 Defence and 30 Ranged)", "You can now have " + "" + "snakeskin bandanas" + "" + " enchanted to hold Summoning scrolls. (You also need level 30 Defence and level 30 Ranged)."); + case 3: + return newstruct cs2func_script_1020_struct(20, 14636, "Slayer helmet" + "
" + " (with 10 Defence)", "You can now have " + "" + "Slayer helmets" + "" + " enchanted to hold Summoning scrolls. (You also need level 10 Defence)."); + case 4: + return newstruct cs2func_script_1020_struct(30, 12207, "Lizard skull", "You can now use " + "" + "lizard skulls" + "" + "."); + case 5: + return newstruct cs2func_script_1020_struct(30, 3385, "Splitbark helm" + "
" + " (with 40 Defence and 40 Magic)", "You can now have " + "" + "splitbark helms" + "" + " enchanted to hold Summoning scrolls. (You also need level 40 Defence and level 40 Magic)."); + case 6: + return newstruct cs2func_script_1020_struct(30, 1163, "Rune full helm" + "
" + " (with 40 Defence)", "You can now have " + "" + "rune full helms" + "" + " enchanted to hold Summoning scrolls. (You also need level 40 Defence)."); + case 7: + return newstruct cs2func_script_1020_struct(35, 3751, "Berserker helm" + "
" + " (after Fremennik Trials with 45 Defence)", "You can now have " + "" + "Berserker helms" + "" + " enchanted to hold Summoning scrolls. (After Fremennik Trials and with level 45 Defence)."); + case 8: + return newstruct cs2func_script_1020_struct(35, 3755, "Farseer helm" + "
" + " (after Fremennik Trials with 45 Defence)", "You can now have " + "" + "Farseer helms" + "" + " enchanted to hold Summoning scrolls. (After Fremennik Trials and with level 45 Defence)."); + case 9: + return newstruct cs2func_script_1020_struct(35, 3749, "Archer helm" + "
" + " (after Fremennik Trials with 45 Defence)", "You can now have " + "" + "Archer helms" + "" + " enchanted to hold Summoning scrolls. (After Fremennik Trials and with level 45 Defence)."); + case 10: + return newstruct cs2func_script_1020_struct(35, 3753, "Warrior helm" + "
" + " (after Fremennik Trials with 45 Defence)", "You can now have " + "" + "Warrior helms" + "" + " enchanted to hold Summoning scrolls. (After Fremennik Trials and with level 45 Defence)."); + case 11: + return newstruct cs2func_script_1020_struct(45, 10828, "Helm of Neitiznot" + "
" + " (after Fremennik Isles)", "You can now have the " + "" + "Helm of Neitiznot" + "" + " enchanted to hold Summoning scrolls (after Fremennik Isles)."); + case 12: + return newstruct cs2func_script_1020_struct(50, 12210, "Feather headdress", "You can now use " + "" + "feather headdresses" + "" + ". (You also need Level 79 Crafting to make feather headdresses)."); + case 13: + return newstruct cs2func_script_1020_struct(50, 1149, "Dragon medium helm" + "
" + " (with 60 Defence)", "You can now have " + "" + "dragon medium helms" + "" + " enchanted to hold Summoning scrolls. (You also need level 60 Defence.)"); + case 14: + return newstruct cs2func_script_1020_struct(50, 19893, "Spirit cape" + "
" + " (with 50 Defence and 50 Dungeoneering)", "You can now wear " + "" + "spirit capes" + "" + ". (You also need level 50 Defence and 50 Dungeoneering.)"); + case 15: + return newstruct cs2func_script_1020_struct(55, 9096, "Lunar helm" + "
" + " (with 40 Defence and 65 Magic)", "You can now have " + "" + "lunar helms" + "" + " enchanted to hold Summoning scrolls. (You also need level 40 Defence and level 65 Magic.)"); + case 16: + return newstruct cs2func_script_1020_struct(60, 11718, "Armadyl helm" + "
" + " (with 70 Defence and 70 Ranged)", "You can now have " + "" + "Armadyl helms" + "" + " enchanted to hold Summoning scrolls. (You also need level 70 Defence and level 70 Ranged.)"); + } + break; + case 4: + switch (arg1) { + case 0: + return newstruct cs2func_script_1020_struct(91, 18778, "Starved ancient effigies", "You can now investigate " + "" + "starved ancient effigies" + "" + " using your knowledge of Summoning."); + case 1: + return newstruct cs2func_script_1020_struct(93, 18779, "Nourished ancient effigies", "You can now investigate " + "" + "nourished ancient effigies" + "" + " using your knowledge of Summoning."); + case 2: + return newstruct cs2func_script_1020_struct(95, 18780, "Sated ancient effigies", "You can now investigate " + "" + "sated ancient effigies" + "" + " using your knowledge of Summoning."); + case 3: + return newstruct cs2func_script_1020_struct(97, 18781, "Gorged ancient effigies", "You can now investigate " + "" + "gorged ancient effigies" + "" + " using your knowledge of Summoning."); + } + break; + case 5: + switch (arg1) { + case 0: + return newstruct cs2func_script_1020_struct(1, 14422, "Stealing Creation - class 1 clay being - Strength XP", "You can now summon " + "" + "class 1 clay beings" + "" + " in Stealing Creation."); + case 1: + return newstruct cs2func_script_1020_struct(20, 14424, "Stealing Creation - class 2 clay being - Strength XP", "You can now summon " + "" + "class 2 clay beings" + "" + " in Stealing Creation."); + case 2: + return newstruct cs2func_script_1020_struct(40, 14426, "Stealing Creation - class 3 clay being - Strength XP", "You can now summon " + "" + "class 3 clay beings" + "" + " in Stealing Creation."); + case 3: + return newstruct cs2func_script_1020_struct(60, 14428, "Stealing Creation - class 4 clay being - Strength XP", "You can now summon " + "" + "class 4 clay beings" + "" + " in Stealing Creation."); + case 4: + return newstruct cs2func_script_1020_struct(80, 14430, "Stealing Creation - class 5 clay being - Strength XP", "You can now summon " + "" + "class 5 clay beings" + "" + " in Stealing Creation."); + } + break; + case 6: + switch (arg1) { + case 0: + return newstruct cs2func_script_1020_struct(-1, 15707, "Dungeoneering skill tasks" + "
" + "As your Summoning level increases, you will be able to attempt higher-level summoning tasks within Daemonheim. You will also be more likely to succeed when attempting summoning tasks within Daemonheim.", ""); + case 1: + return newstruct cs2func_script_1020_struct(1, 17935, "Cub bloodrager (Melee, tier 1)" + "
" + "Gold charm, novite ore", "You can now infuse " + "" + "cub bloodrager pouches" + "" + " within Daemonheim."); + case 2: + return newstruct cs2func_script_1020_struct(1, 18027, "Sundering Strike (Tier 1) scroll", "You can now use " + "" + "Sundering Strike (Tier 1) scrolls" + "" + " within Daemonheim."); + case 3: + return newstruct cs2func_script_1020_struct(2, 17985, "Cub deathslinger (Ranged, tier 1)" + "
" + "Gold charm, tangle gum branches", "You can now infuse " + "" + "cub deathslinger pouches" + "" + " within Daemonheim."); + case 4: + return newstruct cs2func_script_1020_struct(2, 18037, "Poisonous Shot (Tier 1) scroll", "You can now use " + "" + " Poisonous Shot (Tier 1) scrolls" + "" + " within Daemonheim."); + case 5: + return newstruct cs2func_script_1020_struct(3, 17945, "Cub stormbringer (Magic, tier 1)" + "
" + "Gold charm, salve nettles", "You can now infuse " + "" + "cub stormbringer pouches" + "" + " within Daemonheim."); + case 6: + return newstruct cs2func_script_1020_struct(3, 18047, "Snaring Wave (Tier 1) scroll", "You can now use " + "" + " Snaring Wave (Tier 1) scrolls" + "" + " within Daemonheim."); + case 7: + return newstruct cs2func_script_1020_struct(5, 17955, "Cub hoardstalker (Forager, tier 1)" + "
" + "Gold charm, protomastyx hide", "You can now infuse " + "" + "cub hoardstalker pouches" + "" + " within Daemonheim."); + case 8: + return newstruct cs2func_script_1020_struct(5, 18057, "Aptitude (Tier 1) scroll", "You can now use " + "" + " Aptitude (Tier 1) scrolls" + "" + " within Daemonheim."); + case 9: + return newstruct cs2func_script_1020_struct(7, 17975, "Cub worldbearer (Beast of burden, tier 1)" + "
" + "Gold charm, protoleather torn bag", "You can now infuse " + "" + "cub worldbearer pouches" + "" + " within Daemonheim."); + case 10: + return newstruct cs2func_script_1020_struct(7, 18067, "Second Wind (Tier 1) scroll", "You can now use " + "" + " Second Wind (Tier 1) scrolls" + "" + " within Daemonheim."); + case 11: + return newstruct cs2func_script_1020_struct(9, 17965, "Cub skinweaver (Healer, tier 1)" + "
" + "Gold charm, 2 cooked heim crabs", "You can now infuse " + "" + "cub skinweaver pouches" + "" + " within Daemonheim."); + case 12: + return newstruct cs2func_script_1020_struct(9, 18077, "Glimmer of Light (Tier 1) scroll", "You can now use " + "" + " Glimmer of Light (Tier 1) scrolls" + "" + " within Daemonheim."); + case 13: + return newstruct cs2func_script_1020_struct(11, 17936, "Little bloodrager (Melee, tier 2)" + "
" + "Gold charm, bathus ore", "You can now infuse " + "" + "little bloodrager pouches" + "" + " within Daemonheim."); + case 14: + return newstruct cs2func_script_1020_struct(11, 18028, "Sundering Strike (Tier 2) scroll", "You can now use " + "" + " Sundering Strike (Tier 2) scrolls" + "" + " within Daemonheim."); + case 15: + return newstruct cs2func_script_1020_struct(12, 17986, "Little deathslinger (Ranged, tier 2)" + "
" + "Gold charm, seeping elm branches", "You can now infuse " + "" + "little deathslinger pouches" + "" + " within Daemonheim."); + case 16: + return newstruct cs2func_script_1020_struct(12, 18038, "Poisonous Shot (Tier 2) scroll", "You can now use " + "" + " Poisonous Shot (Tier 2) scrolls" + "" + " within Daemonheim."); + case 17: + return newstruct cs2func_script_1020_struct(13, 17946, "Little stormbringer (Magic, tier 2)" + "
" + "Gold charm, wildercress stems", "You can now infuse " + "" + "little stormbringer pouches" + "" + " within Daemonheim."); + case 18: + return newstruct cs2func_script_1020_struct(13, 18048, "Snaring Wave (Tier 2) scroll", "You can now use " + "" + " Snaring Wave (Tier 2) scrolls" + "" + " within Daemonheim."); + case 19: + return newstruct cs2func_script_1020_struct(15, 17956, "Little hoardstalker (Forager, tier 2)" + "
" + "Gold charm, submastyx hide", "You can now infuse " + "" + "little hoardstalker pouches" + "" + " within Daemonheim."); + case 20: + return newstruct cs2func_script_1020_struct(15, 18058, "Aptitude (Tier 2) scroll", "You can now use " + "" + " Aptitude (Tier 2) scrolls" + "" + " within Daemonheim."); + case 21: + return newstruct cs2func_script_1020_struct(17, 17976, "Little worldbearer (Beast of burden, tier 2)" + "
" + "Gold charm, subleather torn bag", "You can now infuse " + "" + "little worldbearer pouches" + "" + " within Daemonheim."); + case 22: + return newstruct cs2func_script_1020_struct(17, 18068, "Second Wind (Tier 2) scroll", "You can now use " + "" + " Second Wind (Tier 2) scrolls" + "" + " within Daemonheim."); + case 23: + return newstruct cs2func_script_1020_struct(19, 17966, "Little skinweaver (Healer, tier 2)" + "
" + "Gold charm, 2 cooked red-eye", "You can now infuse " + "" + "little skinweaver pouches" + "" + " within Daemonheim."); + case 24: + return newstruct cs2func_script_1020_struct(19, 18078, "Glimmer of Light (Tier 2) scroll", "You can now use " + "" + " Glimmer of Light (Tier 2) scrolls" + "" + " within Daemonheim."); + case 25: + return newstruct cs2func_script_1020_struct(21, 17937, "Na\u00efve bloodrager (Melee, tier 3)" + "
" + "Gold charm, marmaros ore", "You can now infuse " + "" + "na\u00efve bloodrager pouches" + "" + " within Daemonheim."); + case 26: + return newstruct cs2func_script_1020_struct(21, 18029, "Sundering Strike (Tier 3) scroll", "You can now use " + "" + " Sundering Strike (Tier 3) scrolls" + "" + " within Daemonheim."); + case 27: + return newstruct cs2func_script_1020_struct(22, 17987, "Na\u00efve deathslinger (Ranged, tier 3)" + "
" + "Gold charm, blood spindle branches", "You can now infuse " + "" + "na\u00efve deathslinger pouches" + "" + " within Daemonheim."); + case 28: + return newstruct cs2func_script_1020_struct(22, 18039, "Poisonous Shot (Tier 3) scroll", "You can now use " + "" + " Poisonous Shot (Tier 3) scrolls" + "" + " within Daemonheim."); + case 29: + return newstruct cs2func_script_1020_struct(23, 17947, "Na\u00efve stormbringer (Magic, tier 3)" + "
" + "Gold charm, blightleaf gauze", "You can now infuse " + "" + "na\u00efve stormbringer pouches" + "" + " within Daemonheim."); + case 30: + return newstruct cs2func_script_1020_struct(23, 18049, "Snaring Wave (Tier 3) scroll", "You can now use " + "" + " Snaring Wave (Tier 3) scrolls" + "" + " within Daemonheim."); + case 31: + return newstruct cs2func_script_1020_struct(25, 17957, "Na\u00efve hoardstalker (Forager, tier 3)" + "
" + "Gold charm, paramastyx hide", "You can now infuse " + "" + "na\u00efve hoardstalker pouches" + "" + " within Daemonheim."); + case 32: + return newstruct cs2func_script_1020_struct(25, 18059, "Aptitude (Tier 3) scroll", "You can now use " + "" + " Aptitude (Tier 3) scrolls" + "" + " within Daemonheim."); + case 33: + return newstruct cs2func_script_1020_struct(27, 17977, "Na\u00efve worldbearer (Beast of burden, tier 3)" + "
" + "Gold charm, paraleather torn bag", "You can now infuse " + "" + "na\u00efve worldbearer pouches" + "" + " within Daemonheim."); + case 34: + return newstruct cs2func_script_1020_struct(27, 18069, "Second Wind (Tier 3) scroll", "You can now use " + "" + " Second Wind (Tier 3) scrolls" + "" + " within Daemonheim."); + case 35: + return newstruct cs2func_script_1020_struct(29, 17967, "Na\u00efve skinweaver (Healer, tier 3)" + "
" + "Gold charm, 2 cooked dusk eels", "You can now infuse " + "" + "na\u00efve skinweaver pouches" + "" + " within Daemonheim."); + case 36: + return newstruct cs2func_script_1020_struct(29, 18079, "Glimmer of Light (Tier 3) scroll", "You can now use " + "" + " Glimmer of Light (Tier 3) scrolls" + "" + " within Daemonheim."); + case 37: + return newstruct cs2func_script_1020_struct(31, 17938, "Keen bloodrager (Melee, tier 4)" + "
" + "Green charm, kratonite ore", "You can now infuse " + "" + "keen bloodrager pouches" + "" + " within Daemonheim."); + case 38: + return newstruct cs2func_script_1020_struct(31, 18030, "Sundering Strike (Tier 4) scroll", "You can now use " + "" + " Sundering Strike (Tier 4) scrolls" + "" + " within Daemonheim."); + case 39: + return newstruct cs2func_script_1020_struct(32, 17988, "Keen deathslinger (Ranged, tier 4)" + "
" + "Green charm, utuku branches", "You can now infuse " + "" + "keen deathslinger pouches" + "" + " within Daemonheim."); + case 40: + return newstruct cs2func_script_1020_struct(32, 18040, "Poisonous Shot (Tier 4) scroll", "You can now use " + "" + " Poisonous Shot (Tier 4) scrolls" + "" + " within Daemonheim."); + case 41: + return newstruct cs2func_script_1020_struct(33, 17948, "Keen stormbringer (Magic, tier 4)" + "
" + "Green charm, roseblood stems", "You can now infuse " + "" + "keen stormbringer pouches" + "" + " within Daemonheim."); + case 42: + return newstruct cs2func_script_1020_struct(33, 18050, "Snaring Wave (Tier 4) scroll", "You can now use " + "" + " Snaring Wave (Tier 4) scrolls" + "" + " within Daemonheim."); + case 43: + return newstruct cs2func_script_1020_struct(35, 17958, "Keen hoardstalker (Forager, tier 4)" + "
" + "Green charm, archaemastyx hide", "You can now infuse " + "" + "keen hoardstalker pouches" + "" + " within Daemonheim."); + case 44: + return newstruct cs2func_script_1020_struct(35, 18060, "Aptitude (Tier 4) scroll", "You can now use " + "" + " Aptitude (Tier 4) scrolls" + "" + " within Daemonheim."); + case 45: + return newstruct cs2func_script_1020_struct(37, 17978, "Keen worldbearer (Beast of burden, tier 4)" + "
" + "Green charm, archleather torn bag", "You can now infuse " + "" + "keen worldbearer pouches" + "" + " within Daemonheim."); + case 46: + return newstruct cs2func_script_1020_struct(37, 18070, "Second Wind (Tier 4) scroll", "You can now use " + "" + " Second Wind (Tier 4) scrolls" + "" + " within Daemonheim."); + case 47: + return newstruct cs2func_script_1020_struct(39, 17968, "Keen skinweaver (Healer, tier 4)" + "
" + "Green charm, 2 cooked giant flatfish", "You can now infuse " + "" + "keen skinweaver pouches" + "" + " within Daemonheim."); + case 48: + return newstruct cs2func_script_1020_struct(39, 18080, "Glimmer of Light (Tier 4) scroll", "You can now use " + "" + " Glimmer of Light (Tier 4) scrolls" + "" + " within Daemonheim."); + case 49: + return newstruct cs2func_script_1020_struct(41, 17939, "Brave bloodrager (Melee, tier 5)" + "
" + "Green charm, fractite ore", "You can now infuse " + "" + "brave bloodrager pouches" + "" + " within Daemonheim."); + case 50: + return newstruct cs2func_script_1020_struct(41, 18031, "Sundering Strike (Tier 5) scroll", "You can now use " + "" + " Sundering Strike (Tier 5) scrolls" + "" + " within Daemonheim."); + case 51: + return newstruct cs2func_script_1020_struct(42, 17989, "Brave deathslinger (Ranged, tier 5)" + "
" + "Green charm, spinebeam branches", "You can now infuse " + "" + "brave deathslinger pouches" + "" + " within Daemonheim."); + case 52: + return newstruct cs2func_script_1020_struct(42, 18041, "Poisonous Shot (Tier 5) scroll", "You can now use " + "" + " Poisonous Shot (Tier 5) scrolls" + "" + " within Daemonheim."); + case 53: + return newstruct cs2func_script_1020_struct(43, 17949, "Brave stormbringer (Magic, tier 5)" + "
" + "Green charm, bryll reeds", "You can now infuse " + "" + "brave stormbringer pouches" + "" + " within Daemonheim."); + case 54: + return newstruct cs2func_script_1020_struct(43, 18051, "Snaring Wave (Tier 5) scroll", "You can now use " + "" + " Snaring Wave (Tier 5) scrolls" + "" + " within Daemonheim."); + case 55: + return newstruct cs2func_script_1020_struct(45, 17959, "Brave hoardstalker (Forager, tier 5)" + "
" + "Green charm, dromomastyx hide", "You can now infuse " + "" + "brave hoardstalker pouches" + "" + " within Daemonheim."); + case 56: + return newstruct cs2func_script_1020_struct(45, 18061, "Aptitude (Tier 5) scroll", "You can now use " + "" + " Aptitude (Tier 5) scrolls" + "" + " within Daemonheim."); + case 57: + return newstruct cs2func_script_1020_struct(47, 17979, "Brave worldbearer (Beast of burden, tier 5)" + "
" + "Green charm, dromoleather torn bag", "You can now infuse " + "" + "brave worldbearer pouches" + "" + " within Daemonheim."); + case 58: + return newstruct cs2func_script_1020_struct(47, 18071, "Second Wind (Tier 5) scroll", "You can now use " + "" + " Second Wind (Tier 5) scrolls" + "" + " within Daemonheim."); + case 59: + return newstruct cs2func_script_1020_struct(49, 17969, "Brave skinweaver (Healer, tier 5)" + "
" + "Green charm, 2 cooked short-finned eels", "You can now infuse " + "" + "brave skinweaver pouches" + "" + " within Daemonheim."); + case 60: + return newstruct cs2func_script_1020_struct(49, 18081, "Glimmer of Light (Tier 5) scroll", "You can now use " + "" + " Glimmer of Light (Tier 5) scrolls" + "" + " within Daemonheim."); + case 61: + return newstruct cs2func_script_1020_struct(51, 17940, "Brah bloodrager (Melee, tier 6)" + "
" + "Green charm, zephyrium ore", "You can now infuse " + "" + "brah bloodrager pouches" + "" + " within Daemonheim."); + case 62: + return newstruct cs2func_script_1020_struct(51, 18032, "Sundering Strike (Tier 6) scroll", "You can now use " + "" + " Sundering Strike (Tier 6) scrolls" + "" + " within Daemonheim."); + case 63: + return newstruct cs2func_script_1020_struct(52, 17990, "Brah deathslinger (Ranged, tier 6)" + "
" + "Green charm, bovistrangler branches", "You can now infuse " + "" + "brah deathslinger pouches" + "" + " within Daemonheim."); + case 64: + return newstruct cs2func_script_1020_struct(52, 18042, "Poisonous Shot (Tier 6) scroll", "You can now use " + "" + " Poisonous Shot (Tier 6) scrolls" + "" + " within Daemonheim."); + case 65: + return newstruct cs2func_script_1020_struct(53, 17950, "Brah stormbringer (Magic, tier 6)" + "
" + "Green charm, duskweed sproutings", "You can now infuse " + "" + "brah stormbringer pouches" + "" + " within Daemonheim."); + case 66: + return newstruct cs2func_script_1020_struct(53, 18052, "Snaring Wave (Tier 6) scroll", "You can now use " + "" + " Snaring Wave (Tier 6) scrolls" + "" + " within Daemonheim."); + case 67: + return newstruct cs2func_script_1020_struct(55, 17960, "Brah hoardstalker (Forager, tier 6)" + "
" + "Green charm, spinomastyx hide", "You can now infuse " + "" + "brah hoardstalker pouches" + "" + " within Daemonheim."); + case 68: + return newstruct cs2func_script_1020_struct(55, 18062, "Aptitude (Tier 6) scroll", "You can now use " + "" + " Aptitude (Tier 6) scrolls" + "" + " within Daemonheim."); + case 69: + return newstruct cs2func_script_1020_struct(57, 17980, "Brah worldbearer (Beast of burden, tier 6)" + "
" + "Green charm, spinoleather torn bag", "You can now infuse " + "" + "brah worldbearer pouches" + "" + " within Daemonheim."); + case 70: + return newstruct cs2func_script_1020_struct(57, 18072, "Second Wind (Tier 6) scroll", "You can now use " + "" + " Second Wind (Tier 6) scrolls" + "" + " within Daemonheim."); + case 71: + return newstruct cs2func_script_1020_struct(59, 17970, "Brah skinweaver (Healer, tier 6)" + "
" + "Green charm, 2 cooked web snippers", "You can now infuse " + "" + "brah skinweaver pouches" + "" + " within Daemonheim."); + case 72: + return newstruct cs2func_script_1020_struct(59, 18082, "Glimmer of Light (Tier 6) scroll", "You can now use " + "" + " Glimmer of Light (Tier 6) scrolls" + "" + " within Daemonheim."); + case 73: + return newstruct cs2func_script_1020_struct(61, 17941, "Naabe bloodrager (Melee, tier 7)" + "
" + "Crimson charm, argonite ore", "You can now infuse " + "" + "naabe bloodrager pouches" + "" + " within Daemonheim."); + case 74: + return newstruct cs2func_script_1020_struct(61, 18033, "Sundering Strike (Tier 7) scroll", "You can now use " + "" + " Sundering Strike (Tier 7) scrolls" + "" + " within Daemonheim."); + case 75: + return newstruct cs2func_script_1020_struct(62, 17991, "Naabe deathslinger (Ranged, tier 7)" + "
" + "Crimson charm, thigat branches", "You can now infuse " + "" + "naabe deathslinger pouches" + "" + " within Daemonheim."); + case 76: + return newstruct cs2func_script_1020_struct(62, 18043, "Poisonous Shot (Tier 7) scroll", "You can now use " + "" + " Poisonous Shot (Tier 7) scrolls" + "" + " within Daemonheim."); + case 77: + return newstruct cs2func_script_1020_struct(63, 17951, "Naabe stormbringer (Magic, tier 7)" + "
" + "Crimson charm, soulbell roots", "You can now infuse " + "" + "naabe stormbringer pouches" + "" + " within Daemonheim."); + case 78: + return newstruct cs2func_script_1020_struct(63, 18053, "Snaring Wave (Tier 7) scroll", "You can now use " + "" + " Snaring Wave (Tier 7) scrolls" + "" + " within Daemonheim."); + case 79: + return newstruct cs2func_script_1020_struct(65, 17961, "Naabe hoardstalker (Forager, tier 7)" + "
" + "Crimson charm, gallimastyx hide", "You can now infuse " + "" + "naabe hoardstalker pouches" + "" + " within Daemonheim."); + case 80: + return newstruct cs2func_script_1020_struct(65, 18063, "Aptitude (Tier 7) scroll", "You can now use " + "" + " Aptitude (Tier 7) scrolls" + "" + " within Daemonheim."); + case 81: + return newstruct cs2func_script_1020_struct(67, 17981, "Naabe worldbearer (Beast of burden, tier 7)" + "
" + "Crimson charm, gallileather torn bag", "You can now infuse " + "" + "naabe worldbearer pouches" + "" + " within Daemonheim."); + case 82: + return newstruct cs2func_script_1020_struct(67, 18073, "Second Wind (Tier 7) scroll", "You can now use " + "" + " Second Wind (Tier 7) scrolls" + "" + " within Daemonheim."); + case 83: + return newstruct cs2func_script_1020_struct(69, 17971, "Naabe skinweaver (Healer, tier 7)" + "
" + "Crimson charm, 2 cooked bouldabass", "You can now infuse " + "" + "naabe skinweaver pouches" + "" + " within Daemonheim."); + case 84: + return newstruct cs2func_script_1020_struct(69, 18083, "Glimmer of Light (Tier 7) scroll", "You can now use " + "" + " Glimmer of Light (Tier 7) scrolls" + "" + " within Daemonheim."); + case 85: + return newstruct cs2func_script_1020_struct(71, 17942, "Wise bloodrager (Melee, tier 8)" + "
" + "Crimson charm, katagon ore", "You can now infuse " + "" + "wise bloodrager pouches" + "" + " within Daemonheim."); + case 86: + return newstruct cs2func_script_1020_struct(71, 18034, "Sundering Strike (Tier 8) scroll", "You can now use " + "" + " Sundering Strike (Tier 8) scrolls" + "" + " within Daemonheim."); + case 87: + return newstruct cs2func_script_1020_struct(72, 17992, "Wise deathslinger (Ranged, tier 8)" + "
" + "Crimson charm, corpsethorn branches", "You can now infuse " + "" + "wise deathslinger pouches" + "" + " within Daemonheim."); + case 88: + return newstruct cs2func_script_1020_struct(72, 18044, "Poisonous Shot (Tier 8) scroll", "You can now use " + "" + " Poisonous Shot (Tier 8) scrolls" + "" + " within Daemonheim."); + case 89: + return newstruct cs2func_script_1020_struct(73, 17952, "Wise stormbringer (Magic, tier 8)" + "
" + "Crimson charm, ectograss blades", "You can now infuse " + "" + "wise stormbringer pouches" + "" + " within Daemonheim."); + case 90: + return newstruct cs2func_script_1020_struct(73, 18054, "Snaring Wave (Tier 8) scroll", "You can now use " + "" + " Snaring Wave (Tier 8) scrolls" + "" + " within Daemonheim."); + case 91: + return newstruct cs2func_script_1020_struct(75, 17962, "Wise hoardstalker (Forager, tier 8)" + "
" + "Crimson charm, stegomastyx hide", "You can now infuse " + "" + "wise hoardstalker pouches" + "" + " within Daemonheim."); + case 92: + return newstruct cs2func_script_1020_struct(75, 18064, "Aptitude (Tier 8) scroll", "You can now use " + "" + " Aptitude (Tier 8) scrolls" + "" + " within Daemonheim."); + case 93: + return newstruct cs2func_script_1020_struct(77, 17982, "Wise worldbearer (Beast of burden, tier 8)" + "
" + "Crimson charm, stegoleather torn bag", "You can now infuse " + "" + "wise worldbearer pouches" + "" + " within Daemonheim."); + case 94: + return newstruct cs2func_script_1020_struct(77, 18074, "Second Wind (Tier 8) scroll", "You can now use " + "" + " Second Wind (Tier 8) scrolls" + "" + " within Daemonheim."); + case 95: + return newstruct cs2func_script_1020_struct(79, 17972, "Wise skinweaver (Healer, tier 8)" + "
" + "Crimson charm, 2 cooked salve eels", "You can now infuse " + "" + "wise skinweaver pouches" + "" + " within Daemonheim."); + case 96: + return newstruct cs2func_script_1020_struct(79, 18084, "Glimmer of Light (Tier 8) scroll", "You can now use " + "" + " Glimmer of Light (Tier 8) scrolls" + "" + " within Daemonheim."); + case 97: + return newstruct cs2func_script_1020_struct(81, 17943, "Adept bloodrager (Melee, tier 9)" + "
" + "Blue charm, gorgonite ore", "You can now infuse " + "" + "adept bloodrager pouches" + "" + " within Daemonheim."); + case 98: + return newstruct cs2func_script_1020_struct(81, 18035, "Sundering Strike (Tier 9) scroll", "You can now use " + "" + " Sundering Strike (Tier 9) scrolls" + "" + " within Daemonheim."); + case 99: + return newstruct cs2func_script_1020_struct(82, 17993, "Adept deathslinger (Ranged, tier 9)" + "
" + "Blue charm, entgallow branches", "You can now infuse " + "" + "adept deathslinger pouches" + "" + " within Daemonheim."); + case 100: + return newstruct cs2func_script_1020_struct(82, 18045, "Poisonous Shot (Tier 9) scroll", "You can now use " + "" + " Poisonous Shot (Tier 9) scrolls" + "" + " within Daemonheim."); + case 101: + return newstruct cs2func_script_1020_struct(83, 17953, "Adept stormbringer (Magic, tier 9)" + "
" + "Blue charm, runeleaf fibres", "You can now infuse " + "" + "adept stormbringer pouches" + "" + " within Daemonheim."); + case 102: + return newstruct cs2func_script_1020_struct(83, 18055, "Snaring Wave (Tier 9) scroll", "You can now use " + "" + " Snaring Wave (Tier 9) scrolls" + "" + " within Daemonheim."); + case 103: + return newstruct cs2func_script_1020_struct(85, 17963, "Adept hoardstalker (Forager, tier 9)" + "
" + "Blue charm, megamastyx hide", "You can now infuse " + "" + "adept hoardstalker pouches" + "" + " within Daemonheim."); + case 104: + return newstruct cs2func_script_1020_struct(85, 18065, "Aptitude (Tier 9) scroll", "You can now use " + "" + " Aptitude (Tier 9) scrolls" + "" + " within Daemonheim."); + case 105: + return newstruct cs2func_script_1020_struct(87, 17983, "Adept worldbearer (Beast of burden, tier 9)" + "
" + "Blue charm, megaleather torn bag", "You can now infuse " + "" + "adept worldbearer pouches" + "" + " within Daemonheim."); + case 106: + return newstruct cs2func_script_1020_struct(87, 18075, "Second Wind (Tier 9) scroll", "You can now use " + "" + " Second Wind (Tier 9) scrolls" + "" + " within Daemonheim."); + case 107: + return newstruct cs2func_script_1020_struct(89, 17973, "Adept skinweaver (Healer, tier 9)" + "
" + "Blue charm, 2 cooked blue crabs", "You can now infuse " + "" + "adept skinweaver pouches" + "" + " within Daemonheim."); + case 108: + return newstruct cs2func_script_1020_struct(89, 18085, "Glimmer of Light (Tier 9) scroll", "You can now use " + "" + " Glimmer of Light (Tier 9) scrolls" + "" + " within Daemonheim."); + case 109: + return newstruct cs2func_script_1020_struct(91, 17944, "Sachem bloodrager (Melee, tier 10)" + "
" + "Blue charm, promethium ore", "You can now infuse " + "" + "sachem bloodrager pouches" + "" + " within Daemonheim."); + case 110: + return newstruct cs2func_script_1020_struct(91, 18036, "Sundering Strike (Tier 10) scroll", "You can now use " + "" + " Sundering Strike (Tier 10) scrolls" + "" + " within Daemonheim."); + case 111: + return newstruct cs2func_script_1020_struct(92, 17994, "Sachem deathslinger (Ranged, tier 10)" + "
" + "Blue charm, grave creeper branches", "You can now infuse " + "" + "sachem deathslinger pouches" + "" + " within Daemonheim."); + case 112: + return newstruct cs2func_script_1020_struct(92, 18046, "Poisonous Shot (Tier 10) scroll", "You can now use " + "" + " Poisonous Shot (Tier 10) scrolls" + "" + " within Daemonheim."); + case 113: + return newstruct cs2func_script_1020_struct(93, 17954, "Sachem stormbringer (Magic, tier 10)" + "
" + "Blue charm, spiritbloom fibres", "You can now infuse " + "" + "sachem stormbringer pouches" + "" + " within Daemonheim."); + case 114: + return newstruct cs2func_script_1020_struct(93, 18056, "Snaring Wave (Tier 10) scroll", "You can now use " + "" + " Snaring Wave (Tier 10) scrolls" + "" + " within Daemonheim."); + case 115: + return newstruct cs2func_script_1020_struct(95, 17964, "Sachem hoardstalker (Forager, tier 10)" + "
" + "Blue charm, tyrannomastyx hide", "You can now infuse " + "" + "sachem hoardstalker pouches" + "" + " within Daemonheim."); + case 116: + return newstruct cs2func_script_1020_struct(95, 18066, "Aptitude (Tier 10) scroll", "You can now use " + "" + " Aptitude (Tier 10) scrolls" + "" + " within Daemonheim."); + case 117: + return newstruct cs2func_script_1020_struct(97, 17984, "Sachem worldbearer (Beast of burden, tier 10)" + "
" + "Blue charm, tyrannoleather torn bag", "You can now infuse " + "" + "sachem worldbearer pouches" + "" + " within Daemonheim."); + case 118: + return newstruct cs2func_script_1020_struct(97, 18076, "Second Wind (Tier 10) scroll", "You can now use " + "" + " Second Wind (Tier 10) scrolls" + "" + " within Daemonheim."); + case 119: + return newstruct cs2func_script_1020_struct(99, 17974, "Sachem skinweaver (Healer, tier 10)" + "
" + "Blue charm, 2 cooked cave morays", "You can now infuse " + "" + "sachem skinweaver pouches" + "" + " within Daemonheim."); + case 120: + return newstruct cs2func_script_1020_struct(99, 18086, "Glimmer of Light (Tier 10) scroll", "You can now use " + "" + " Glimmer of Light (Tier 10) scrolls" + "" + " within Daemonheim."); + } + break; + case 7: + if (((boolean)arg1)) { + return newstruct cs2func_script_1020_struct(99, 12169, "Skill mastery", "" + "Congratulations! You are now a master of " + "" + "Summoning" + "" + ". Why not visit " + "" + "Pikkupstix" + "" + " in " + "" + "Taverley" + "" + "? He has something special only available to true masters of the " + "" + "Summoning" + "" + " skill!"); + } + } + return newstruct cs2func_script_1020_struct(0, -1, "", ""); +} diff --git a/dumps/scripts/1021.cs2 b/dumps/scripts/1021.cs2 new file mode 100644 index 0000000..8c99d2e --- /dev/null +++ b/dumps/scripts/1021.cs2 @@ -0,0 +1,37 @@ +cs2func_script_1021_struct(1,1,0) script_1021(int arg0) { + switch (arg0) { + case 0: + return newstruct cs2func_script_1021_struct(0, "Smelting"); + case 1: + return newstruct cs2func_script_1021_struct(0, "Bronze"); + case 2: + return newstruct cs2func_script_1021_struct(1, "Blurite"); + case 3: + return newstruct cs2func_script_1021_struct(0, "Iron"); + case 4: + return newstruct cs2func_script_1021_struct(0, "Steel"); + case 5: + return newstruct cs2func_script_1021_struct(0, "Mithril"); + case 6: + return newstruct cs2func_script_1021_struct(0, "Adamantite"); + case 7: + return newstruct cs2func_script_1021_struct(0, "Rune"); + case 8: + return newstruct cs2func_script_1021_struct(1, "Gold"); + case 9: + return newstruct cs2func_script_1021_struct(1, "Elemental"); + case 10: + return newstruct cs2func_script_1021_struct(1, "Bane"); + case 11: + return newstruct cs2func_script_1021_struct(0, "Artisan Workshop"); + case 12: + return newstruct cs2func_script_1021_struct(0, "Other"); + case 13: + return newstruct cs2func_script_1021_struct(1, "Minigames"); + case 14: + return newstruct cs2func_script_1021_struct(0, "Dungeoneering"); + case 15: + return newstruct cs2func_script_1021_struct(0, "Milestones"); + } + return newstruct cs2func_script_1021_struct(-1, ""); +} diff --git a/dumps/scripts/1022.cs2 b/dumps/scripts/1022.cs2 new file mode 100644 index 0000000..93915a8 --- /dev/null +++ b/dumps/scripts/1022.cs2 @@ -0,0 +1,1113 @@ +cs2func_script_1022_struct(2,2,0) script_1022(int arg0,int arg1) { + switch (arg0) { + flow_1: + case 0: + switch (arg1) { + case 0: + return newstruct cs2func_script_1022_struct(1, 2349, "Bronze" + "
" + " 1 tin ore and 1 copper ore", "You can now smelt " + "" + "bronze" + "" + "."); + case 1: + return newstruct cs2func_script_1022_struct(8, 9467, "Blurite" + "
" + " (after The Knight's Sword)", "You now have the Smithing level required to smelt " + "" + "blurite" + "" + " (after The Knight's Sword)."); + case 2: + return newstruct cs2func_script_1022_struct(15, 2351, "Iron" + "
" + " 50% chance of success, rising until level 45", "You can now smelt " + "" + "iron" + "" + "."); + case 3: + return newstruct cs2func_script_1022_struct(20, 2893, "Members: Elemental metal" + "
" + " (after Elemental Workshop)", "Members now have the Smithing level required to smelt " + "" + "elemental metal" + "" + " (after Elemental Workshop)."); + case 4: + return newstruct cs2func_script_1022_struct(20, 2355, "Silver", "You can now smelt " + "" + "silver" + "" + "."); + case 5: + return newstruct cs2func_script_1022_struct(30, 2353, "Steel" + "
" + " 2 coal and 1 iron ore", "You can now smelt " + "" + "steel" + "" + "."); + case 6: + return newstruct cs2func_script_1022_struct(40, 2357, "Gold", "You can now smelt " + "" + "gold" + "" + "."); + case 7: + return newstruct cs2func_script_1022_struct(45, 2351, "Iron" + "
" + " 80% chance of success", "Your chance of successfully smelting " + "" + "iron" + "" + " has reached its maximum."); + case 8: + return newstruct cs2func_script_1022_struct(50, 2359, "Mithril" + "
" + " 4 coal and 1 mithril ore", "You can now smelt " + "" + "mithril" + "" + "."); + case 9: + return newstruct cs2func_script_1022_struct(70, 2361, "Adamant" + "
" + " 6 coal and 1 adamantite ore", "You can now smelt " + "" + "adamantite" + "" + "."); + case 10: + return newstruct cs2func_script_1022_struct(77, 21778, "Members: Bane ore" + "
" + " (after Ritual of the Mahjarrat)", "Members now have the Smithing level required to smelt " + "" + "bane ore" + "" + " (after Ritual of the Mahjarrat)."); + case 11: + return newstruct cs2func_script_1022_struct(85, 2363, "Rune" + "
" + " 8 coal and 1 runite ore", "You can now smelt " + "" + "runite" + "" + "."); + } + break; + case 1: + switch (arg1) { + case 0: + return newstruct cs2func_script_1022_struct(1, 1205, "Bronze dagger" + "
" + " 1 bar", "You can now smith " + "" + "bronze daggers" + "" + "."); + case 1: + return newstruct cs2func_script_1022_struct(1, 1351, "Bronze hatchet" + "
" + " 1 bar", "You can now smith " + "" + "bronze hatchets" + "" + "."); + case 2: + return newstruct cs2func_script_1022_struct(2, 1422, "Bronze mace" + "
" + " 1 bar", "You can now smith " + "" + "bronze maces" + "" + "."); + case 3: + return newstruct cs2func_script_1022_struct(3, 1139, "Bronze medium helm" + "
" + " 1 bar", "You can now smith " + "" + "bronze medium helms" + "" + "."); + case 4: + return newstruct cs2func_script_1022_struct(3, 9375, "Members: Bronze crossbow bolt" + "
" + " 1 bar makes 10", "Members can now smith " + "" + "bronze crossbow bolts" + "" + "."); + case 5: + return newstruct cs2func_script_1022_struct(4, 1277, "Bronze sword" + "
" + " 1 bar", "You can now smith " + "" + "bronze swords" + "" + "."); + case 6: + return newstruct cs2func_script_1022_struct(4, 819, "Members: Bronze dart tip" + "
" + " (after Tourist Trap)" + "
" + " 1 bar makes 10", "Members now have the Smithing level required to smith bronze dart tips" + "" + " (after Tourist Trap)."); + case 7: + return newstruct cs2func_script_1022_struct(4, 1794, "Members: Bronze wire" + "
" + " 1 bar", "Members can now smith " + "" + "bronze wire" + "" + "."); + case 8: + return newstruct cs2func_script_1022_struct(4, 4819, "Members: Bronze nails" + "
" + " 1 bar makes 15", "Members can now smith " + "" + "bronze nails" + "" + "."); + case 9: + return newstruct cs2func_script_1022_struct(5, 1321, "Bronze scimitar" + "
" + " 2 bars", "You can now smith " + "" + "bronze scimitars" + "" + "."); + case 10: + return newstruct cs2func_script_1022_struct(5, 1237, "Members: Bronze spear" + "
" + " (after Tai Bwo Wannai Trio and learning barbarian smithing)" + "
" + " 1 bar, 1 log", "Members who are versed in the art of barbarian smithing now have the Smithing level required to smith " + "" + "bronze spears" + "" + " (after Tai Bwo Wannai Trio)."); + case 11: + return newstruct cs2func_script_1022_struct(5, 11367, "Members: Bronze hasta" + "
" + " (after Tai Bwo Wannai Trio and learning barbarian smithing)" + "
" + " 1 bar, 1 log", "Members who are versed in the art of barbarian smithing now have the Smithing level required to smith " + "" + "bronze hastae" + "" + " (after Tai Bwo Wannai Trio)."); + case 12: + return newstruct cs2func_script_1022_struct(5, 39, "Members: Bronze arrowhead" + "
" + " 1 bar makes 15", "Members can now smith " + "" + "bronze arrowheads" + "" + "."); + case 13: + return newstruct cs2func_script_1022_struct(5, 1265, "Members: Bronze pickaxe" + "
" + " (after Perils of Ice Mountain)" + "
" + " 2 bars", "Members now have the Smithing level required to smith bronze " + "" + "pickaxes" + "" + " (after Perils of Ice Mountain)."); + case 14: + return newstruct cs2func_script_1022_struct(6, 9420, "Members: Bronze crossbow limbs" + "
" + " 1 bar", "Members can now smith " + "" + "bronze crossbow limbs" + "" + "."); + case 15: + return newstruct cs2func_script_1022_struct(6, 1291, "Bronze longsword" + "
" + " 2 bars", "You can now smith " + "" + "bronze longswords" + "" + "."); + case 16: + return newstruct cs2func_script_1022_struct(7, 1155, "Bronze full helm" + "
" + " 2 bars", "You can now smith " + "" + "bronze full helms" + "" + "."); + case 17: + return newstruct cs2func_script_1022_struct(7, 864, "Members: Bronze throwing knife" + "
" + " 1 bar makes 5", "Members can now smith " + "" + "bronze throwing knives" + "" + "."); + case 18: + return newstruct cs2func_script_1022_struct(8, 1173, "Bronze square shield" + "
" + " 2 bars", "You can now smith " + "" + "bronze square shields" + "" + "."); + case 19: + return newstruct cs2func_script_1022_struct(9, 1337, "Bronze warhammer" + "
" + " 3 bars", "You can now smith " + "" + "bronze warhammers" + "" + "."); + case 20: + return newstruct cs2func_script_1022_struct(10, 1375, "Bronze battleaxe" + "
" + " 3 bars", "You can now smith " + "" + "bronze battleaxes" + "" + "."); + case 21: + return newstruct cs2func_script_1022_struct(11, 1103, "Bronze chainbody" + "
" + " 3 bars", "You can now smith " + "" + "bronze chainbodies" + "" + "."); + case 22: + return newstruct cs2func_script_1022_struct(12, 1189, "Bronze kiteshield" + "
" + " 3 bars", "You can now smith " + "" + "bronze kiteshields" + "" + "."); + case 23: + return newstruct cs2func_script_1022_struct(13, 3095, "Members: Bronze claws" + "
" + " (after Death Plateau)" + "
" + " 2 bars", "Members now have the Smithing level required to smith " + "" + "bronze claws" + "" + " (after Death Plateau)."); + case 24: + return newstruct cs2func_script_1022_struct(14, 1307, "Bronze two-handed sword" + "
" + " 3 bars", "You can now smith " + "" + "bronze two-handed swords" + "" + "."); + case 25: + return newstruct cs2func_script_1022_struct(16, 1075, "Bronze platelegs" + "
" + " 3 bars", "You can now smith " + "" + "bronze platelegs" + "" + "."); + case 26: + return newstruct cs2func_script_1022_struct(16, 1087, "Bronze plateskirt" + "
" + " 3 bars", "You can now smith " + "" + "bronze plateskirts" + "" + "."); + case 27: + return newstruct cs2func_script_1022_struct(18, 1117, "Bronze platebody" + "
" + " 5 bars", "You can now smith " + "" + "bronze platebodies" + "" + "."); + } + break; + case 2: + if (((boolean)arg1)) { + return newstruct cs2func_script_1022_struct(-1, 7620, "You will not be able to smith blurite until you have completed The Knight's Sword.", ""); + } + if (((boolean)arg1)) { + return newstruct cs2func_script_1022_struct(8, 9376, "Blurite crossbow bolts" + "
" + " 1 bar makes 10", "Members now have the Smithing level required to smith " + "" + "blurite crossbow bolts" + "" + " (after the Knight's Sword)."); + } + if (arg1 == 2) { + return newstruct cs2func_script_1022_struct(13, 9422, "Blurite crossbow limbs" + "
" + " 1 bar", "Members now have the Smithing level required to smith " + "" + "blurite crossbow limbs" + "" + " (after The Knight's Sword)."); + } + break; + case 3: + switch (arg1) { + case 0: + return newstruct cs2func_script_1022_struct(15, 1203, "Iron dagger" + "
" + " 1 bar", "You can now smith " + "" + "iron daggers" + "" + "."); + case 1: + return newstruct cs2func_script_1022_struct(16, 1349, "Iron hatchet" + "
" + " 1 bar", "You can now smith " + "" + "iron hatchets" + "" + "."); + case 2: + return newstruct cs2func_script_1022_struct(17, 1420, "Iron mace" + "
" + " 1 bar", "You can now smith " + "" + "iron maces" + "" + "."); + case 3: + return newstruct cs2func_script_1022_struct(17, 7225, "Members: Iron spit" + "
" + " 1 bar", "Members can now smith " + "" + "iron spits" + "" + "."); + case 4: + return newstruct cs2func_script_1022_struct(18, 1137, "Iron medium helm" + "
" + " 1 bar", "You can now smith " + "" + "iron medium helms" + "" + "."); + case 5: + return newstruct cs2func_script_1022_struct(18, 9377, "Members: Iron crossbow bolt" + "
" + " 1 bar makes 10", "Members can now smith " + "" + "iron crossbow bolts" + "" + "."); + case 6: + return newstruct cs2func_script_1022_struct(19, 1279, "Iron sword" + "
" + " 1 bar", "You can now smith " + "" + "iron swords" + "" + "."); + case 7: + return newstruct cs2func_script_1022_struct(19, 820, "Members: Iron dart tip" + "
" + " (after Tourist Trap)" + "
" + " 1 bar makes 10", "Members now have the Smithing level required to smith " + "" + "iron dart tips" + "" + " (after Tourist Trap)."); + case 8: + return newstruct cs2func_script_1022_struct(19, 4820, "Members: Iron nails" + "
" + " 1 bar makes 15", "Members can now smith " + "" + "iron nails" + "" + "."); + case 9: + return newstruct cs2func_script_1022_struct(20, 1323, "Iron scimitar" + "
" + " 2 bars", "You can now smith " + "" + "iron scimitars" + "" + "."); + case 10: + return newstruct cs2func_script_1022_struct(20, 1239, "Members: Iron spear" + "
" + " (after Tai Bwo Wannai Trio and learning barbarian smithing)" + "
" + " 1 bar, 1 oak log", "Members who are versed in the art of barbarian smithing now have the Smithing level required to smith " + "" + "iron spears" + "" + " (after Tai Bwo Wannai Trio)."); + case 11: + return newstruct cs2func_script_1022_struct(20, 11369, "Members: Iron hasta" + "
" + " (after Tai Bwo Wannai Trio and learning barbarian smithing)" + "
" + " 1 bar, 1 oak log", "Members who are versed in the art of barbarian smithing now have the Smithing level required to smith " + "" + "iron hastae" + "" + " (after Tai Bwo Wannai Trio)."); + case 12: + return newstruct cs2func_script_1022_struct(20, 40, "Members: Iron arrowhead" + "
" + " 1 bar makes 15", "Members can now smith " + "" + "iron arrowheads" + "" + "."); + case 13: + return newstruct cs2func_script_1022_struct(20, 1267, "Members: Iron pickaxe" + "
" + " (after Perils of Ice Mountain)" + "
" + " 2 bars", "Members now have the Smithing level required to smith " + "" + "iron pickaxes" + "" + " (after Perils of Ice Mountain)."); + case 14: + return newstruct cs2func_script_1022_struct(21, 1293, "Iron longsword" + "
" + " 2 bars", "You can now smith " + "" + "iron longswords" + "" + "."); + case 15: + return newstruct cs2func_script_1022_struct(22, 1153, "Iron full helm" + "
" + " 2 bars", "You can now smith " + "" + "iron full helms" + "" + "."); + case 16: + return newstruct cs2func_script_1022_struct(22, 863, "Members: Iron throwing knife" + "
" + " 1 bar makes 5", "Members can now smith " + "" + "iron throwing knives" + "" + "."); + case 17: + return newstruct cs2func_script_1022_struct(23, 1175, "Iron square shield" + "
" + " 2 bars", "You can now smith " + "" + "iron square shields" + "" + "."); + case 18: + return newstruct cs2func_script_1022_struct(23, 9423, "Members: Iron crossbow limbs" + "
" + " 1 bar", "Members can now smith " + "" + "iron crossbow limbs" + "" + "."); + case 19: + return newstruct cs2func_script_1022_struct(24, 1335, "Iron warhammer" + "
" + " 3 bars", "You can now smith " + "" + "iron warhammers" + "" + "."); + case 20: + return newstruct cs2func_script_1022_struct(25, 1363, "Iron battleaxe" + "
" + " 3 bars", "You can now smith " + "" + "iron battleaxes" + "" + "."); + case 21: + return newstruct cs2func_script_1022_struct(26, 1101, "Iron chainbody" + "
" + " 3 bars", "You can now smith " + "" + "iron chainbodies" + "" + "."); + case 22: + return newstruct cs2func_script_1022_struct(26, 4540, "Members: Oil lantern frame" + "
" + " 1 bar", "Members can now smith " + "" + "oil lantern frames" + "" + "."); + case 23: + return newstruct cs2func_script_1022_struct(27, 1191, "Iron kiteshield" + "
" + " 3 bars", "You can now smith " + "" + "iron kiteshields" + "" + "."); + case 24: + return newstruct cs2func_script_1022_struct(28, 3096, "Members: Iron claws" + "
" + " (after Death Plateau)" + "
" + " 2 bars", "Members now have the Smithing level required to smith " + "" + "iron claws" + "" + " (after Death Plateau)."); + case 25: + return newstruct cs2func_script_1022_struct(29, 1309, "Iron two-handed sword" + "
" + " 3 bars", "You can now smith " + "" + "iron two-handed swords" + "" + "."); + case 26: + return newstruct cs2func_script_1022_struct(31, 1067, "Iron platelegs" + "
" + " 3 bars", "You can now smith " + "" + "iron platelegs" + "" + "."); + case 27: + return newstruct cs2func_script_1022_struct(31, 1081, "Iron plateskirt" + "
" + " 3 bars", "You can now smith " + "" + "iron plateskirts" + "" + "."); + case 28: + return newstruct cs2func_script_1022_struct(33, 1115, "Iron platebody" + "
" + " 5 bars", "You can now smith " + "" + "iron platebodies" + "" + "."); + } + break; + case 4: + switch (arg1) { + case 0: + return newstruct cs2func_script_1022_struct(30, 1207, "Steel dagger" + "
" + " 1 bar", "You can now smith " + "" + "steel daggers" + "" + "."); + case 1: + return newstruct cs2func_script_1022_struct(31, 1353, "Steel hatchet" + "
" + " 1 bar", "You can now smith " + "" + "steel hatchets" + "" + "."); + case 2: + return newstruct cs2func_script_1022_struct(32, 1424, "Steel mace" + "
" + " 1 bar", "You can now smith " + "" + "steel maces" + "" + "."); + case 3: + return newstruct cs2func_script_1022_struct(33, 1141, "Steel medium helm" + "
" + " 1 bar", "You can now smith " + "" + "steel medium helms" + "" + "."); + case 4: + return newstruct cs2func_script_1022_struct(33, 9378, "Members: Steel crossbow bolt" + "
" + " 1 bar makes 10", "Members can now smith " + "" + "steel crossbow bolts" + "" + "."); + case 5: + return newstruct cs2func_script_1022_struct(34, 1281, "Steel sword" + "
" + " 1 bar", "You can now smith " + "" + "steel swords" + "" + "."); + case 6: + return newstruct cs2func_script_1022_struct(34, 1539, "Steel nails" + "
" + " 1 bar makes 15", "You can now smith " + "" + "steel nails" + "" + "."); + case 7: + return newstruct cs2func_script_1022_struct(34, 821, "Members: Steel dart tip" + "
" + " (after Tourist Trap)" + "
" + " 1 bar makes 10", "Members now have the Smithing level required to smith " + "" + "steel dart tips" + "" + " (after Tourist Trap)."); + case 8: + return newstruct cs2func_script_1022_struct(35, 1325, "Steel scimitar" + "
" + " 2 bars", "You can now smith " + "" + "steel scimitars" + "" + "."); + case 9: + return newstruct cs2func_script_1022_struct(35, 1241, "Members: Steel spear" + "
" + " (after Tai Bwo Wannai Trio and learning barbarian smithing)" + "
" + " 1 bar, 1 willow log", "Members who are versed in the art of barbarian smithing now have the Smithing level required to smith " + "" + "steel spears" + "" + " (after Tai Bwo Wannai Trio)."); + case 10: + return newstruct cs2func_script_1022_struct(35, 11371, "Members: Steel hasta" + "
" + " (after Tai Bwo Wannai Trio and learning barbarian smithing)" + "
" + " 1 bar, 1 willow log", "Members who are versed in the art of barbarian smithing now have the Smithing level required to smith " + "" + "steel hastae" + "" + " (after Tai Bwo Wannai Trio)."); + case 11: + return newstruct cs2func_script_1022_struct(35, 41, "Members: Steel arrowhead" + "
" + " 1 bar makes 15", "Members can now smith " + "" + "steel arrowheads" + "" + "."); + case 12: + return newstruct cs2func_script_1022_struct(35, 2, "Members: Cannonball" + "
" + " (after Dwarf Cannon)" + "
" + " 1 bar makes 4", "Members now have the Smithing level required to smith " + "" + "steel cannonballs" + "" + " (after Dwarf Cannon)."); + case 13: + return newstruct cs2func_script_1022_struct(35, 1269, "Members: Steel pickaxe" + "
" + " (after Perils of Ice Mountain)" + "
" + " 2 bars", "Members now have the Smithing level required to smith " + "" + "steel pickaxes" + "" + " (after Perils of Ice Mountain)."); + case 14: + return newstruct cs2func_script_1022_struct(36, 9425, "Members: Steel crossbow limbs" + "
" + " 1 bar", "Members can now smith " + "" + "steel crossbow limbs" + "" + "."); + case 15: + return newstruct cs2func_script_1022_struct(36, 1295, "Steel longsword" + "
" + " 2 bars", "You can now smith " + "" + "steel longswords" + "" + "."); + case 16: + return newstruct cs2func_script_1022_struct(36, 2370, "Members: Steel studs" + "
" + " 1 bar", "Members can now smith " + "" + "steel studs" + "" + "."); + case 17: + return newstruct cs2func_script_1022_struct(37, 1157, "Steel full helm" + "
" + " 2 bars", "You can now smith " + "" + "steel full helms" + "" + "."); + case 18: + return newstruct cs2func_script_1022_struct(37, 865, "Members: Steel throwing knife" + "
" + " 1 bar makes 5", "Members can now smith " + "" + "steel throwing knives" + "" + "."); + case 19: + return newstruct cs2func_script_1022_struct(38, 1177, "Steel square shield" + "
" + " 2 bars", "You can now smith " + "" + "steel square shields" + "" + "."); + case 20: + return newstruct cs2func_script_1022_struct(39, 1339, "Steel warhammer" + "
" + " 3 bars", "You can now smith " + "" + "steel warhammers" + "" + "."); + case 21: + return newstruct cs2func_script_1022_struct(40, 1365, "Steel battleaxe" + "
" + " 3 bars", "You can now smith " + "" + "steel battleaxes" + "" + "."); + case 22: + return newstruct cs2func_script_1022_struct(41, 1105, "Steel chainbody" + "
" + " 3 bars", "You can now smith " + "" + "steel chainbodies" + "" + "."); + case 23: + return newstruct cs2func_script_1022_struct(42, 1193, "Steel kiteshield" + "
" + " 3 bars", "You can now smith " + "" + "steel kiteshields" + "" + "."); + case 24: + return newstruct cs2func_script_1022_struct(43, 3097, "Members: Steel claws" + "
" + " (after Death Plateau)" + "
" + " 2 bars", "Members now have the Smithing level required to smith " + "" + "steel claws" + "" + " (after Death Plateau)."); + case 25: + return newstruct cs2func_script_1022_struct(44, 1311, "Steel two-handed sword" + "
" + " 3 bars", "You can now smith " + "" + "steel two-handed swords" + "" + "."); + case 26: + return newstruct cs2func_script_1022_struct(46, 1069, "Steel platelegs" + "
" + " 3 bars", "You can now smith " + "" + "steel platelegs" + "" + "."); + case 27: + return newstruct cs2func_script_1022_struct(46, 1083, "Steel plateskirt" + "
" + " 3 bars", "You can now smith " + "" + "steel plateskirts" + "" + "."); + case 28: + return newstruct cs2func_script_1022_struct(48, 1119, "Steel platebody" + "
" + " 5 bars", "You can now smith " + "" + "steel platebodies" + "" + "."); + case 29: + return newstruct cs2func_script_1022_struct(49, 4544, "Members: Bullseye lantern frame" + "
" + " 1 bar", "Members can now smith " + "" + "bullseye lantern frames" + "" + "."); + } + break; + case 5: + switch (arg1) { + case 0: + return newstruct cs2func_script_1022_struct(50, 1209, "Mithril dagger" + "
" + " 1 bar", "You can now smith " + "" + "mithril daggers" + "" + "."); + case 1: + return newstruct cs2func_script_1022_struct(51, 1355, "Mithril hatchet" + "
" + " 1 bar", "You can now smith " + "" + "mithril hatchets" + "" + "."); + case 2: + return newstruct cs2func_script_1022_struct(52, 1428, "Mithril mace" + "
" + " 1 bar", "You can now smith " + "" + "mithril maces" + "" + "."); + case 3: + return newstruct cs2func_script_1022_struct(53, 1143, "Mithril medium helm" + "
" + " 1 bar", "You can now smith " + "" + "mithril medium helms" + "" + "."); + case 4: + return newstruct cs2func_script_1022_struct(53, 9379, "Members: Mithril crossbow bolt" + "
" + " 1 bar makes 10", "Members can now smith " + "" + "mithril crossbow bolts" + "" + "."); + case 5: + return newstruct cs2func_script_1022_struct(54, 1285, "Mithril sword" + "
" + " 1 bar", "You can now smith " + "" + "mithril swords" + "" + "."); + case 6: + return newstruct cs2func_script_1022_struct(54, 822, "Members: Mithril dart tip" + "
" + " (after Tourist Trap)" + "
" + " 1 bar makes 10", "Members now have the Smithing level required to smith " + "" + "mithril dart tips" + "" + " (after Tourist Trap)."); + case 7: + return newstruct cs2func_script_1022_struct(54, 4822, "Members: Mithril nail" + "
" + " 1 bar makes 15", "Members can now smith " + "" + "mithril nails" + "" + "."); + case 8: + return newstruct cs2func_script_1022_struct(55, 1329, "Mithril scimitar" + "
" + " 2 bars", "You can now smith " + "" + "mithril scimitars" + "" + "."); + case 9: + return newstruct cs2func_script_1022_struct(55, 1243, "Members: Mithril spear" + "
" + " (after Tai Bwo Wannai Trio and learning barbarian smithing)" + "
" + " 1 bar, 1 maple log", "Members who are versed in the art of barbarian smithing now have the Smithing level required to smith " + "" + "mithril spears" + "" + " (after Tai Bwo Wannai Trio)."); + case 10: + return newstruct cs2func_script_1022_struct(55, 11373, "Members: Mithril hasta" + "
" + " (after Tai Bwo Wannai Trio and learning barbarian smithing)" + "
" + " 1 bar, 1 maple log", "Members who are versed in the art of barbarian smithing now have the Smithing level required to smith " + "" + "mithril hastae" + "" + " (after Tai Bwo Wannai Trio)."); + case 11: + return newstruct cs2func_script_1022_struct(55, 42, "Members: Mithril arrowhead" + "
" + " 1 bar makes 15", "Members can now smith " + "" + "mithril arrowheads" + "" + "."); + case 12: + return newstruct cs2func_script_1022_struct(55, 1273, "Members: Mithril pickaxe" + "
" + " (after Perils of Ice Mountain)" + "
" + " 2 bars", "Members now have the Smithing level required to smith " + "" + "mithril pickaxes" + "" + " (after Perils of Ice Mountain)."); + case 13: + return newstruct cs2func_script_1022_struct(56, 9427, "Members: Mithril crossbow limbs" + "
" + " 1 bar", "Members can now smith " + "" + "mithril crossbow limbs" + "" + "."); + case 14: + return newstruct cs2func_script_1022_struct(56, 1299, "Mithril longsword" + "
" + " 2 bars", "You can now smith " + "" + "mithril longswords" + "" + "."); + case 15: + return newstruct cs2func_script_1022_struct(57, 1159, "Mithril full helm" + "
" + " 2 bars", "You can now smith " + "" + "mithril full helms" + "" + "."); + case 16: + return newstruct cs2func_script_1022_struct(57, 866, "Members: Mithril throwing knife" + "
" + " 1 bar makes 5", "Members can now smith " + "" + "mithril throwing knives" + "" + "."); + case 17: + return newstruct cs2func_script_1022_struct(58, 1181, "Mithril square shield" + "
" + " 2 bars", "You can now smith " + "" + "mithril square shields" + "" + "."); + case 18: + return newstruct cs2func_script_1022_struct(59, 1343, "Mithril warhammer" + "
" + " 3 bars", "You can now smith " + "" + "mithril warhammers" + "" + "."); + case 19: + return newstruct cs2func_script_1022_struct(59, 9416, "Members: Mithril crossbow grapple tip" + "
" + " 1 bar", "Members can now smith " + "" + "mithril crossbow grapple tips" + "" + "."); + case 20: + return newstruct cs2func_script_1022_struct(60, 1369, "Mithril battleaxe" + "
" + " 3 bars", "You can now smith " + "" + "mithril battleaxes" + "" + "."); + case 21: + return newstruct cs2func_script_1022_struct(61, 1109, "Mithril chainbody" + "
" + " 3 bars", "You can now smith" + "" + " mithril chainbodies" + "" + "."); + case 22: + return newstruct cs2func_script_1022_struct(62, 1197, "Mithril kiteshield" + "
" + " 3 bars", "You can now smith " + "" + "mithril kiteshields" + "" + "."); + case 23: + return newstruct cs2func_script_1022_struct(63, 3099, "Members: Mithril claws" + "
" + " (after Death Plateau)" + "
" + " 2 bars", "Members now have the Smithing level required to smith " + "" + "mithril claws" + "" + " (after Death Plateau)."); + case 24: + return newstruct cs2func_script_1022_struct(64, 1315, "Mithril two-handed sword" + "
" + " 3 bars", "You can now smith " + "" + "mithril two-handed swords" + "" + "."); + case 25: + return newstruct cs2func_script_1022_struct(66, 1071, "Mithril platelegs" + "
" + " 3 bars", "You can now smith " + "" + "mithril platelegs" + "" + "."); + case 26: + return newstruct cs2func_script_1022_struct(66, 1085, "Mithril plateskirt" + "
" + " 3 bars", "You can now smith " + "" + "mithril plateskirts" + "" + "."); + case 27: + return newstruct cs2func_script_1022_struct(68, 1121, "Mithril platebody" + "
" + " 5 bars", "You can now smith " + "" + "mithril platebodies" + "" + "."); + } + break; + case 6: + switch (arg1) { + case 0: + return newstruct cs2func_script_1022_struct(70, 1211, "Adamant dagger" + "
" + " 1 bar", "You can now smith " + "" + "adamant daggers" + "" + "."); + case 1: + return newstruct cs2func_script_1022_struct(71, 1357, "Adamant hatchet" + "
" + " 1 bar", "You can now smith " + "" + "adamant hatchets" + "" + "."); + case 2: + return newstruct cs2func_script_1022_struct(72, 1430, "Adamant mace" + "
" + " 1 bar", "You can now smith " + "" + "adamant maces" + "" + "."); + case 3: + return newstruct cs2func_script_1022_struct(73, 1145, "Adamant medium helm" + "
" + " 1 bar", "You can now smith " + "" + "adamant medium helms" + "" + "."); + case 4: + return newstruct cs2func_script_1022_struct(73, 9380, "Members: Adamant crossbow bolt" + "
" + " 1 bar makes 10", "Members can now smith " + "" + "adamant crossbow bolts" + "" + "."); + case 5: + return newstruct cs2func_script_1022_struct(74, 1287, "Adamant sword" + "
" + " 1 bar", "You can now smith " + "" + "adamant swords" + "" + "."); + case 6: + return newstruct cs2func_script_1022_struct(74, 823, "Members: Adamant dart tip" + "
" + " (after Tourist Trap)" + "
" + " 1 bar makes 10", "Members now have the Smithing level required to smith " + "" + "adamant dart tips" + "" + " (after Tourist Trap)."); + case 7: + return newstruct cs2func_script_1022_struct(74, 4823, "Members: Adamant nail" + "
" + " 1 bar makes 15", "Members can now smith " + "" + "adamant nails" + "" + "."); + case 8: + return newstruct cs2func_script_1022_struct(75, 1331, "Adamant scimitar" + "
" + " 2 bars", "You can now smith " + "" + "adamant scimitars" + "" + "."); + case 9: + return newstruct cs2func_script_1022_struct(75, 1245, "Members: Adamant spear" + "
" + " (after Tai Bwo Wannai Trio and learning barbarian smithing)" + "
" + " 1 bar, 1 yew log", "Members who are versed in the art of barbarian smithing now have the Smithing level required to smith " + "" + "adamant spears" + "" + " (after Tai Bwo Wannai Trio)."); + case 10: + return newstruct cs2func_script_1022_struct(75, 11375, "Members: Adamant hasta" + "
" + " (after Tai Bwo Wannai Trio and learning barbarian smithing)" + "
" + " 1 bar, 1 yew log", "Members who are versed in the art of barbarian smithing now have the Smithing level required to smith " + "" + "adamant hastae" + "" + " (after Tai Bwo Wannai Trio)."); + case 11: + return newstruct cs2func_script_1022_struct(75, 43, "Members: Adamant arrowhead" + "
" + " 1 bar makes 15", "Members can now smith " + "" + "adamant arrowheads" + "" + "."); + case 12: + return newstruct cs2func_script_1022_struct(75, 1271, "Members: Adamant pickaxe" + "
" + " (after Perils of Ice Mountain)" + "
" + " 2 bars", "Members now have the Smithing level required to smith " + "" + "adamant pickaxes" + "" + " (after Perils of Ice Mountain)."); + case 13: + return newstruct cs2func_script_1022_struct(76, 9429, "Members: Adamant crossbow limbs" + "
" + " 1 bar", "Members can now smith " + "" + "adamant crossbow limbs" + "" + "."); + case 14: + return newstruct cs2func_script_1022_struct(76, 1301, "Adamant longsword" + "
" + " 2 bars", "You can now smith " + "" + "adamant longswords" + "" + "."); + case 15: + return newstruct cs2func_script_1022_struct(77, 1161, "Adamant full helm" + "
" + " 2 bars", "You can now smith " + "" + "adamant full helms" + "" + "."); + case 16: + return newstruct cs2func_script_1022_struct(77, 867, "Member: Adamant throwing knives" + "
" + " 1 bar makes 5", "Members can now smith " + "" + "adamant throwing knives" + "" + "."); + case 17: + return newstruct cs2func_script_1022_struct(78, 1183, "Adamant square shield" + "
" + " 2 bars", "You can now smith " + "" + "adamant square shields" + "" + "."); + case 18: + return newstruct cs2func_script_1022_struct(79, 1345, "Adamant warhammer" + "
" + " 3 bars", "You can now smith " + "" + "adamant warhammers" + "" + "."); + case 19: + return newstruct cs2func_script_1022_struct(80, 1371, "Adamant battleaxe" + "
" + " 3 bars", "You can now smith " + "" + "adamant battleaxes" + "" + "."); + case 20: + return newstruct cs2func_script_1022_struct(81, 1111, "Adamant chainbody" + "
" + " 3 bars", "You can now smith " + "" + "adamant chainbodies" + "" + "."); + case 21: + return newstruct cs2func_script_1022_struct(82, 1199, "Adamant kiteshield" + "
" + " 3 bars", "You can now smith " + "" + "adamant kiteshields" + "" + "."); + case 22: + return newstruct cs2func_script_1022_struct(83, 3100, "Members: Adamant claws" + "
" + " (after Death Plateau)" + "
" + " 2 bars", "Members now have the Smithing level required to smith " + "" + "adamant claws" + "" + " (after Death Plateau)."); + case 23: + return newstruct cs2func_script_1022_struct(84, 1317, "Adamant two-handed sword" + "
" + " 3 bars", "You can now smith " + "" + "adamant two-handed swords" + "" + "."); + case 24: + return newstruct cs2func_script_1022_struct(86, 1073, "Adamant platelegs" + "
" + " 3 bars", "You can now smith " + "" + "adamant platelegs" + "" + "."); + case 25: + return newstruct cs2func_script_1022_struct(86, 1091, "Adamant plateskirt" + "
" + " 3 bars", "You can now smith " + "" + "adamant plateskirts" + "" + "."); + case 26: + return newstruct cs2func_script_1022_struct(88, 1123, "Adamant platebody" + "
" + " 5 bars", "You can now smith " + "" + "adamant platebodies" + "" + "."); + } + break; + case 7: + switch (arg1) { + case 0: + return newstruct cs2func_script_1022_struct(85, 1213, "Rune dagger" + "
" + " 1 bar", "You can now smith " + "" + "rune daggers" + "" + "."); + case 1: + return newstruct cs2func_script_1022_struct(86, 1359, "Rune hatchet" + "
" + " 1 bar", "You can now smith " + "" + "rune hatchets" + "" + "."); + case 2: + return newstruct cs2func_script_1022_struct(87, 1432, "Rune mace" + "
" + " 1 bar", "You can now smith " + "" + "rune maces" + "" + "."); + case 3: + return newstruct cs2func_script_1022_struct(88, 1147, "Rune medium helm" + "
" + " 1 bar", "You can now smith " + "" + "rune medium helms" + "" + "."); + case 4: + return newstruct cs2func_script_1022_struct(88, 9381, "Members: Rune crossbow bolt" + "
" + " 1 bar makes 10", "Members can now smith " + "" + "rune crossbow bolts" + "" + "."); + case 5: + return newstruct cs2func_script_1022_struct(89, 1289, "Rune sword" + "
" + " 1 bar", "You can now smith " + "" + "rune swords" + "" + "."); + case 6: + return newstruct cs2func_script_1022_struct(89, 824, "Members: Rune dart tip " + "
" + " (after Tourist Trap)" + "
" + " 1 bar makes 10", "Members now have the Smithing level required to smith " + "" + "rune dart tips" + "" + " (after Tourist Trap)."); + case 7: + return newstruct cs2func_script_1022_struct(89, 4824, "Members: Rune nails" + "
" + " 1 bar makes 15", "Members can now smith " + "" + "rune nails" + "" + "."); + case 8: + return newstruct cs2func_script_1022_struct(90, 1333, "Rune scimitar" + "
" + " 2 bars", "You can now smith " + "" + "rune scimitars" + "" + "."); + case 9: + return newstruct cs2func_script_1022_struct(90, 1247, "Members: Rune spear" + "
" + " (after Tai Bwo Wannai Trio and learning barbarian smithing)" + "
" + " 1 bar, 1 magic log", "Members who are versed in the art of barbarian smithing now have the Smithing level required to smith " + "" + "rune spears" + "" + " (after Tai Bwo Wannai Trio)."); + case 10: + return newstruct cs2func_script_1022_struct(90, 11377, "Members: Rune hasta" + "
" + " (after Tai Bwo Wannai Trio and learning barbarian smithing)" + "
" + " 1 bar, 1 magic log", "Members who are versed in the art of barbarian smithing now have the Smithing level required to smith " + "" + "rune hastae" + "" + " (after Tai Bwo Wannai Trio)."); + case 11: + return newstruct cs2func_script_1022_struct(90, 44, "Members: Rune arrowhead" + "
" + " 1 bar makes 15", "Members can now smith " + "" + "rune arrowheads" + "" + "."); + case 12: + return newstruct cs2func_script_1022_struct(90, 1275, "Members: Rune pickaxe" + "
" + " (after Perils of Ice Mountain)" + "
" + " 2 bars", "Members now have the Smithing level required to smith " + "" + "rune pickaxes" + "" + " (after Perils of Ice Mountain)."); + case 13: + return newstruct cs2func_script_1022_struct(91, 9431, "Members: Rune crossbow limbs" + "
" + " 1 bar", "Members can now smith " + "" + "rune crossbow limbs" + "" + "."); + case 14: + return newstruct cs2func_script_1022_struct(91, 1303, "Rune longsword" + "
" + " 2 bars", "You can now smith " + "" + "rune longswords" + "" + "."); + case 15: + return newstruct cs2func_script_1022_struct(92, 1163, "Rune full helm" + "
" + " 2 bars", "You can now smith " + "" + "rune full helms" + "" + "."); + case 16: + return newstruct cs2func_script_1022_struct(92, 868, "Members: Rune throwing knife" + "
" + " 1 bar makes 5", "Members can now smith " + "" + "rune throwing knives" + "" + "."); + case 17: + return newstruct cs2func_script_1022_struct(93, 1185, "Rune square shield" + "
" + " 2 bars", "You can now smith " + "" + "rune square shields" + "" + "."); + case 18: + return newstruct cs2func_script_1022_struct(94, 1347, "Rune warhammer" + "
" + " 3 bars", "You can now smith " + "" + "rune warhammers" + "" + "."); + case 19: + return newstruct cs2func_script_1022_struct(95, 1373, "Rune battleaxe" + "
" + " 3 bars", "You can now smith " + "" + "rune battleaxes" + "" + "."); + case 20: + return newstruct cs2func_script_1022_struct(96, 1113, "Rune chainbody" + "
" + " 3 bars", "You can now smith " + "" + "rune chainbodies" + "" + "."); + case 21: + return newstruct cs2func_script_1022_struct(97, 1201, "Rune kiteshield" + "
" + " 3 bars", "You can now smith " + "" + "rune kiteshields" + "" + "."); + case 22: + return newstruct cs2func_script_1022_struct(98, 3101, "Members: Rune claws" + "
" + " (after Death Plateau)" + "
" + " 2 bars", "Members now have the Smithing level required to smith " + "" + "rune claws" + "" + " (after Death Plateau)."); + case 23: + return newstruct cs2func_script_1022_struct(99, 1319, "Rune two-handed sword" + "
" + " 3 bars", "You can now smith " + "" + "rune two-handed swords" + "" + "."); + case 24: + return newstruct cs2func_script_1022_struct(99, 1079, "Rune platelegs" + "
" + " 3 bars", "You can now smith " + "" + "rune platelegs" + "" + "."); + case 25: + return newstruct cs2func_script_1022_struct(99, 1093, "Rune plateskirt" + "
" + " 3 bars", "You can now smith " + "" + "rune plateskirts" + "" + "."); + case 26: + return newstruct cs2func_script_1022_struct(99, 1127, "Rune platebody" + "
" + " 5 bars", "You can now smith " + "" + "rune platebodies" + "" + "."); + } + break; + case 8: + if (((boolean)arg1)) { + return newstruct cs2func_script_1022_struct(50, 721, "Members: Gold bowl" + "
" + " (after starting Legends' Quest)", "Members now have the Smithing level required to smith " + "" + "gold bowls" + "" + " (after starting Legends' Quest)."); + } + if (((boolean)arg1)) { + return newstruct cs2func_script_1022_struct(50, 4567, "Members: Gold helmet" + "
" + " (after starting Between a Rock...)", "Members now have the Smithing level required to smith " + "" + "gold helmets" + "" + " (after starting Between a Rock...)."); + } + break; + case 9: + switch (arg1) { + case 0: + return newstruct cs2func_script_1022_struct(20, 2890, "Members: Elemental shield" + "
" + " (after Elemental Workshop I)", "Members now have the Smithing level required to smith " + "" + "elemental shields" + "" + " (after Elemental Workshop I)."); + case 1: + return newstruct cs2func_script_1022_struct(30, 9729, "Members: Elemental helmet" + "
" + " (after Elemental Workshop II)", "Members now have the Smithing level required to smith " + "" + "elemental helms" + "" + " (after Elemental Workshop II)."); + case 2: + return newstruct cs2func_script_1022_struct(30, 9731, "Members: Mind shield" + "
" + " (after Elemental Workshop II)", "Members now have the Smithing level required to smith " + "" + "mind shields" + "" + " (after Elemental Workshop II)."); + case 3: + return newstruct cs2func_script_1022_struct(30, 9733, "Members: Mind helmet" + "
" + " (after Elemental Workshop II)", "Members now have the Smithing level required to smith " + "" + "mind helmets" + "" + " (after Elemental Workshop II)."); + case 4: + return newstruct cs2func_script_1022_struct(33, 18691, "Members: Body shield" + "
" + " (after Elemental Workshop III)", "Members now have the Smithing level required to smith " + "" + "body shields" + "" + " (after Elemental Workshop III)."); + case 5: + return newstruct cs2func_script_1022_struct(33, 18693, "Members: Body helmet" + "
" + " (after Elemental Workshop III)", "Members now have the Smithing level required to smith " + "" + "body helmets" + "" + " (after Elemental Workshop III)."); + case 6: + return newstruct cs2func_script_1022_struct(33, 18699, "Members: Elemental body" + "
" + " (after Elemental Workshop III)", "Members now have the Smithing level required to smith " + "" + "elemental bodies" + "" + " (after Elemental Workshop III)."); + case 7: + return newstruct cs2func_script_1022_struct(33, 18697, "Members: Mind body" + "
" + " (after Elemental Workshop III)", "Members now have the Smithing level required to smith " + "" + "mind bodies" + "" + " (after Elemental Workshop III)."); + case 8: + return newstruct cs2func_script_1022_struct(33, 18695, "Members: Body body" + "
" + " (after Elemental Workshop III)", "Members now have the Smithing level required to smith " + "" + "body bodies" + "" + " (after Elemental Workshop III)."); + case 9: + return newstruct cs2func_script_1022_struct(38, 20458, "Members: Elemental gloves" + "
" + " (after Elemental Workshop IV)", "Members now have the Smithing level required to smith " + "" + "elemental gloves" + "" + " (after Elemental Workshop IV)."); + case 10: + return newstruct cs2func_script_1022_struct(38, 20460, "Members: Mind gloves" + "
" + " (after Elemental Workshop IV)", "Members now have the Smithing level required to smith " + "" + "mind gloves" + "" + " (after Elemental Workshop IV)."); + case 11: + return newstruct cs2func_script_1022_struct(38, 20462, "Members: Body gloves" + "
" + " (after Elemental Workshop IV)", "Members now have the Smithing level required to smith " + "" + "body gloves" + "" + " (after Elemental Workshop IV)."); + case 12: + return newstruct cs2func_script_1022_struct(38, 20436, "Members: Cosmic shield" + "
" + " (after Elemental Workshop IV)", "Members now have the Smithing level required to smith " + "" + "cosmic shields" + "" + " (after Elemental Workshop IV)."); + case 13: + return newstruct cs2func_script_1022_struct(38, 20440, "Members: Cosmic helmet" + "
" + " (after Elemental Workshop IV)", "Members now have the Smithing level required to smith " + "" + "cosmic helmets" + "" + " (after Elemental Workshop IV)."); + case 14: + return newstruct cs2func_script_1022_struct(38, 20444, "Members: Cosmic body" + "
" + " (after Elemental Workshop IV)", "Members now have the Smithing level required to smith " + "" + "cosmic bodies" + "" + " (after Elemental Workshop IV)."); + case 15: + return newstruct cs2func_script_1022_struct(38, 20464, "Members: Cosmic gloves" + "
" + " (after Elemental Workshop IV)", "Members now have the Smithing level required to smith " + "" + "cosmic gloves" + "" + " (after Elemental Workshop IV)."); + case 16: + return newstruct cs2func_script_1022_struct(42, 20448, "Members: Elemental boots" + "
" + " (after Elemental Workshop IV)", "Members now have the Smithing level required to smith " + "" + "elemental boots" + "" + " (after Elemental Workshop IV)."); + case 17: + return newstruct cs2func_script_1022_struct(42, 20450, "Members: Mind boots" + "
" + " (after Elemental Workshop IV)", "Members now have the Smithing level required to smith " + "" + "mind boots" + "" + " (after Elemental Workshop IV)."); + case 18: + return newstruct cs2func_script_1022_struct(42, 20452, "Members: Body boots" + "
" + " (after Elemental Workshop IV)", "Members now have the Smithing level required to smith " + "" + "body boots" + "" + " (after Elemental Workshop IV)."); + case 19: + return newstruct cs2func_script_1022_struct(42, 20454, "Members: Cosmic boots" + "
" + " (after Elemental Workshop IV)", "Members now have the Smithing level required to smith " + "" + "cosmic boots" + "" + " (after Elemental Workshop IV)."); + case 20: + return newstruct cs2func_script_1022_struct(42, 20438, "Members: Chaos shield" + "
" + " (after Elemental Workshop IV)", "Members now have the Smithing level required to smith " + "" + "chaos shields" + "" + " (after Elemental Workshop IV)."); + case 21: + return newstruct cs2func_script_1022_struct(42, 20442, "Members: Chaos helmet" + "
" + " (after Elemental Workshop IV)", "Members now have the Smithing level required to smith " + "" + "chaos helmets" + "" + " (after Elemental Workshop IV)."); + case 22: + return newstruct cs2func_script_1022_struct(42, 20446, "Members: Chaos body" + "
" + " (after Elemental Workshop IV)", "Members now have the Smithing level required to smith " + "" + "chaos bodies" + "" + " (after Elemental Workshop IV)."); + case 23: + return newstruct cs2func_script_1022_struct(42, 20466, "Members: Chaos gloves" + "
" + " (after Elemental Workshop IV)", "Members now have the Smithing level required to smith " + "" + "chaos gloves" + "" + " (after Elemental Workshop IV)."); + case 24: + return newstruct cs2func_script_1022_struct(42, 20456, "Members: Chaos boots" + "
" + " (after Elemental Workshop IV)", "Members now have the Smithing level required to smith " + "" + "chaos boots" + "" + " (after Elemental Workshop IV)."); + } + break; + case 10: + switch (arg1) { + case 0: + return newstruct cs2func_script_1022_struct(80, 21823, "Members: Dragonbane arrowtips (after Ritual of the Mahjarrat)", "Members now have the Smithing level required to smith " + "" + "dragonbane arrowtips" + "" + " (after Ritual of the Mahjarrat)."); + case 1: + return newstruct cs2func_script_1022_struct(80, 21828, "Members: Wallasalkibane arrowtips (after Ritual of the Mahjarrat)", "Members now have the Smithing level required to smith " + "" + "wallasalkibane arrowtips" + "" + " (after Ritual of the Mahjarrat)."); + case 2: + return newstruct cs2func_script_1022_struct(80, 21833, "Members: Basiliskbane arrowtips (after Ritual of the Mahjarrat)", "Members now have the Smithing level required to smith " + "" + "basiliskbane arrowtips" + "" + " (after Ritual of the Mahjarrat)."); + case 3: + return newstruct cs2func_script_1022_struct(80, 21838, "Members: Abyssalbane arrowtips (after Ritual of the Mahjarrat)", "Members now have the Smithing level required to smith " + "" + "abyssalbane arrowtips" + "" + " (after Ritual of the Mahjarrat)."); + case 4: + return newstruct cs2func_script_1022_struct(82, 21843, "Members: Dragonbane bolts (unf) (after Ritual of the Mahjarrat)", "Members now have the Smithing level required to smith " + "" + "dragonbane bolts" + "" + " (after Ritual of the Mahjarrat)."); + case 5: + return newstruct cs2func_script_1022_struct(82, 21853, "Members: Wallasalkibane bolts (unf) (after Ritual of the Mahjarrat)", "Members now have the Smithing level required to smith " + "" + "wallasalkibane bolts" + "" + " (after Ritual of the Mahjarrat)."); + case 6: + return newstruct cs2func_script_1022_struct(82, 21848, "Members: Basiliskbane bolts (unf) (after Ritual of the Mahjarrat)", "Members now have the Smithing level required to smith " + "" + "basiliskbane bolts" + "" + " (after Ritual of the Mahjarrat)."); + case 7: + return newstruct cs2func_script_1022_struct(82, 21858, "Members: Abyssalbane bolts (unf) (after Ritual of the Mahjarrat)", "Members now have the Smithing level required to smith " + "" + "abyssalbane bolts" + "" + " (after Ritual of the Mahjarrat)."); + } + break; + case 11: + switch (arg1) { + case 0: + return newstruct cs2func_script_1022_struct(1, 20506, "Bronze rails", "You can now smith " + "" + "bronze rails" + "" + "."); + case 1: + return newstruct cs2func_script_1022_struct(2, 20507, "Bronze base plate", "You can now smith " + "" + "bronze base plates" + "" + "."); + case 2: + return newstruct cs2func_script_1022_struct(3, 20511, "Bronze track (40% complete)", "You can now combine bronze rails with bronze base plates to make " + "" + "bronze track (40% complete)" + "" + "."); + case 3: + return newstruct cs2func_script_1022_struct(5, 20508, "Bronze spikes", "You can now smith " + "" + "bronze spikes" + "" + "."); + case 4: + return newstruct cs2func_script_1022_struct(6, 20512, "Bronze track (60% complete)", "You can now combine bronze track (40% complete) with bronze spikes to make " + "" + "bronze track (60% complete)" + "" + "."); + case 5: + return newstruct cs2func_script_1022_struct(8, 20509, "Bronze joint", "You can now smith " + "" + "bronze joints" + "" + "."); + case 6: + return newstruct cs2func_script_1022_struct(9, 20513, "Bronze track (80% complete)", "You can now combine bronze track (60% complete) with a bronze joint to make " + "" + "bronze track (80% complete)" + "" + "."); + case 7: + return newstruct cs2func_script_1022_struct(11, 20510, "Bronze ties", "You can now smith " + "" + "bronze ties" + "" + "."); + case 8: + return newstruct cs2func_script_1022_struct(12, 20514, "Bronze track (100% complete)", "You can now combine bronze track (80% complete) with bronze ties to make " + "" + "bronze track (100% complete)" + "" + "."); + case 9: + return newstruct cs2func_script_1022_struct(15, 20515, "Iron rails", "You can now smith " + "" + "iron rails" + "" + "."); + case 10: + return newstruct cs2func_script_1022_struct(19, 20516, "Iron base plate", "You can now smith " + "" + "iron base plates" + "" + "."); + case 11: + return newstruct cs2func_script_1022_struct(20, 20525, "Iron track (40% complete)", "You can now combine iron rails with iron base plates to make " + "" + "iron track (40% complete)" + "" + "."); + case 12: + return newstruct cs2func_script_1022_struct(24, 20517, "Iron spikes", "You can now smith " + "" + "iron spikes" + "" + "."); + case 13: + return newstruct cs2func_script_1022_struct(25, 20526, "Iron track (60% complete)", "You can now combine iron track (40% complete) with iron spikes to make " + "" + "iron track (60% complete)" + "" + "."); + case 14: + return newstruct cs2func_script_1022_struct(29, 20518, "Iron joint", "You can now smith " + "" + "iron joints" + "" + "."); + case 15: + return newstruct cs2func_script_1022_struct(30, 20572, "Iron burial armour", "You can now smith iron burial armour for miners, warriors and smiths."); + case 16: + return newstruct cs2func_script_1022_struct(30, 20527, "Iron track (80% complete)", "You can now combine iron track (60% complete) with an iron joint to make " + "" + "iron track (80% complete)" + "" + "."); + case 17: + return newstruct cs2func_script_1022_struct(34, 20519, "Iron ties", "You can now smith " + "" + "iron ties" + "" + "."); + case 18: + return newstruct cs2func_script_1022_struct(35, 20528, "Iron track (100% complete)", "You can now combine iron track (80% complete) with iron ties to make " + "" + "iron track (100% complete)" + "" + "."); + case 19: + return newstruct cs2func_script_1022_struct(39, 20520, "Members: Steel rails", "Members can now smith " + "" + "steel rails" + "" + "."); + case 20: + return newstruct cs2func_script_1022_struct(44, 20521, "Members: Steel base plate", "Members can now smith " + "" + "steel base plates" + "" + "."); + case 21: + return newstruct cs2func_script_1022_struct(45, 20573, "Steel burial armour", "You can now smith steel burial armour for miners, warriors and smiths."); + case 22: + return newstruct cs2func_script_1022_struct(45, 20529, "Members: Steel track (40% complete)", "Members can now combine steel rails with steel base plates to make " + "" + "steel track (40% complete)" + "" + "."); + case 23: + return newstruct cs2func_script_1022_struct(49, 20522, "Members: Steel spikes", "Members can now smith " + "" + "steel spikes" + "" + "."); + case 24: + return newstruct cs2func_script_1022_struct(50, 2347, "Members: Fix pipes", "Members can now fix burst pipes in the Artisans Workshop."); + case 25: + return newstruct cs2func_script_1022_struct(50, 20530, "Members: Steel track (60% complete)", "Members can now combine steel track (40% complete) with steel spikes to make " + "" + "steel track (60% complete)" + "" + "."); + case 26: + return newstruct cs2func_script_1022_struct(54, 20523, "Members: Steel joint", "Members can now smith " + "" + "steel joints" + "" + "."); + case 27: + return newstruct cs2func_script_1022_struct(55, 20531, "Members: Steel track (80% complete)", "Members can now combine steel track (60% complete) with a steel joint to make " + "" + "steel track (80% complete)" + "" + "."); + case 28: + return newstruct cs2func_script_1022_struct(59, 20524, "Members: Steel ties", "Members can now smith " + "" + "steel ties" + "" + "."); + case 29: + return newstruct cs2func_script_1022_struct(60, 20574, "Members: Mithril burial armour", "Members can now smith mithril burial armour for miners, warriors and smiths."); + case 30: + return newstruct cs2func_script_1022_struct(60, 20532, "Members: Steel track (100% complete)", "Members can now combine steel track (80% complete) with steel ties to make " + "" + "steel track (100% complete)" + "" + "."); + case 31: + return newstruct cs2func_script_1022_struct(62, 20480, "Members: Cannon repair", "Members can now repair cannons in the cannon repair workshop."); + case 32: + return newstruct cs2func_script_1022_struct(70, 20560, "Members: Iron ceremonial swords", "Members can now smith iron ceremonial swords."); + case 33: + return newstruct cs2func_script_1022_struct(70, 20575, "Members: Adamant burial armour", "Members can now smith adamant burial armour for miners, warriors and smiths."); + case 34: + return newstruct cs2func_script_1022_struct(75, 20561, "Members: Steel ceremonial swords", "Members can now smith steel ceremonial swords."); + case 35: + return newstruct cs2func_script_1022_struct(78, 2347, "Members: Greater precision", "Members will now smith ceremonial swords more precisely, hitting fewer 0s and generally being more precise."); + case 36: + return newstruct cs2func_script_1022_struct(80, 20562, "Members: Mithril ceremonial swords", "Members can now smith mithril ceremonial swords."); + case 37: + return newstruct cs2func_script_1022_struct(83, 2347, "Members: Greater precision", "Members will now smith ceremonial swords more precisely, hitting fewer 0s and generally being more precise."); + case 38: + return newstruct cs2func_script_1022_struct(85, 20563, "Members: Adamant ceremonial swords", "Members can now smith adamant ceremonial swords."); + case 39: + return newstruct cs2func_script_1022_struct(88, 2347, "Members: Greater precision", "Members will now smith ceremonial swords more precisely, hitting fewer 0s and generally being more precise."); + case 40: + return newstruct cs2func_script_1022_struct(90, 20576, "Members: Rune burial armour", "Members can now smith rune burial armour for miners, warriors and smiths."); + case 41: + return newstruct cs2func_script_1022_struct(90, 20564, "Members: Rune ceremonial swords", "Members can now smith rune ceremonial swords"); + case 42: + return newstruct cs2func_script_1022_struct(93, 2347, "Members: Greater precision", "Members will now smith ceremonial swords more precisely, hitting fewer 0s and generally being more precise."); + case 43: + return newstruct cs2func_script_1022_struct(97, 2347, "Members: Greater precision", "Members will now smith ceremonial swords more precisely, hitting fewer 0s and generally being more precise."); + case 44: + return newstruct cs2func_script_1022_struct(99, 2347, "Members: Greater precision", "Members will now smith ceremonial swords more precisely, hitting fewer 0s and generally being more precise."); + } + break; + case 12: + switch (arg1) { + case 0: + return newstruct cs2func_script_1022_struct(55, 19670, "Scroll of efficiency" + "
" + " (with 55 Dungeoneering)", "You can now use " + "" + "scrolls of efficiency" + "" + ". (You also need level 55 Dungeoneering.)"); + case 1: + return newstruct cs2func_script_1022_struct(60, 1187, "Members: Dragon square shield", "Members can now make " + "" + "dragon square shields" + "" + "."); + case 2: + return newstruct cs2func_script_1022_struct(80, 11690, "Members: Godsword blade", "Members can now make " + "" + "godsword blades" + "" + "."); + case 3: + return newstruct cs2func_script_1022_struct(85, 13746, "Members: Arcane spirit shields" + "
" + " (after Summer's End and with 90 Prayer)", "Members can now create " + "" + "arcane spirit shields" + "" + " (after Summer's End, with level 90 Prayer)."); + case 4: + return newstruct cs2func_script_1022_struct(85, 13748, "Members: Divine spirit shields" + "
" + " (after Summer's End and with 90 Prayer)", "Members can now create " + "" + "divine spirit shields" + "" + " (after Summer's End, with level 90 Prayer)."); + case 5: + return newstruct cs2func_script_1022_struct(85, 13750, "Members: Elysian spirit shields" + "
" + " (after Summer's End and with 90 Prayer)", "Members can now create " + "" + "elysian spirit shields" + "" + " (after Summer's End, with level 90 Prayer)."); + case 6: + return newstruct cs2func_script_1022_struct(85, 13752, "Members: Spectral spirit shields" + "
" + " (after Summer's End and with 90 Prayer)", "Members can now create " + "" + "spectral spirit shields" + "" + " (after Summer's End, with level 90 Prayer)."); + case 7: + return newstruct cs2func_script_1022_struct(90, 11283, "Members: Dragonfire shield", "Members can now make " + "" + "dragonfire shields" + "" + " from anti-dragonbreath shields and draconic visages."); + case 8: + return newstruct cs2func_script_1022_struct(91, 18778, "Members: Starved ancient effigies", "Members can now investigate " + "" + "starved ancient effigies" + "" + " using their knowledge of Smithing."); + case 9: + return newstruct cs2func_script_1022_struct(92, 14479, "Members: Repair dragon platebody", "Members can now repair " + "" + "dragon platebodies" + "" + " (after While Guthix Sleeps)."); + case 10: + return newstruct cs2func_script_1022_struct(93, 18779, "Members: Nourished ancient effigies", "Members can now investigate " + "" + "nourished ancient effigies" + "" + " using their knowledge of Smithing."); + case 11: + return newstruct cs2func_script_1022_struct(95, 18780, "Members: Sated ancient effigies", "Members can now investigate " + "" + "sated ancient effigies" + "" + " using their knowledge of Smithing."); + case 12: + return newstruct cs2func_script_1022_struct(97, 18781, "Members: Gorged ancient effigies", "Members can now investigate " + "" + "gorged ancient effigies" + "" + " using their knowledge of Smithing."); + } + break; + case 13: + switch (arg1) { + case 0: + return newstruct cs2func_script_1022_struct(1, 14297, "Members: Stealing Creation - class 1 dagger", "Members can now make " + "" + "class 1 daggers" + "" + " in Stealing Creation."); + case 1: + return newstruct cs2func_script_1022_struct(1, 14132, "Members: Stealing Creation - class 1 hatchet", "Members can now make " + "" + "class 1 hatchets" + "" + " in Stealing Creation."); + case 2: + return newstruct cs2func_script_1022_struct(1, 14367, "Members: Stealing Creation - class 1 helmet", "Members can now make " + "" + "class 1 helmets" + "" + " in Stealing Creation."); + case 3: + return newstruct cs2func_script_1022_struct(1, 14287, "Members: Stealing Creation - class 1 scimitar", "Members can now make " + "" + "class 1 scimitars" + "" + " in Stealing Creation."); + case 4: + return newstruct cs2func_script_1022_struct(1, 14122, "Members: Stealing Creation - class 1 pickaxe", "Members can now make " + "" + "class 1 pickaxes" + "" + " in Stealing Creation."); + case 5: + return newstruct cs2func_script_1022_struct(1, 14307, "Members: Stealing Creation - class 1 warhammer", "Members can now make " + "" + "class 1 warhammers" + "" + " in Stealing Creation."); + case 6: + return newstruct cs2func_script_1022_struct(1, 14357, "Members: Stealing Creation - class 1 platelegs", "Members can now make " + "" + "class 1 platelegs" + "" + " in Stealing Creation."); + case 7: + return newstruct cs2func_script_1022_struct(1, 14347, "Members: Stealing Creation - class 1 platebody", "Members can now make " + "" + "class 1 platebodies" + "" + " in Stealing Creation."); + case 8: + return newstruct cs2func_script_1022_struct(20, 14299, "Members: Stealing Creation - class 2 dagger", "Members can now make " + "" + "class 2 daggers" + "" + " in Stealing Creation."); + case 9: + return newstruct cs2func_script_1022_struct(20, 14134, "Members: Stealing Creation - class 2 hatchet", "Members can now make " + "" + "class 2 hatchets" + "" + " in Stealing Creation."); + case 10: + return newstruct cs2func_script_1022_struct(20, 14369, "Members: Stealing Creation - class 2 helmet", "Members can now make " + "" + "class 2 helmets" + "" + " in Stealing Creation."); + case 11: + return newstruct cs2func_script_1022_struct(20, 14289, "Members: Stealing Creation - class 2 scimitar", "Members can now make " + "" + "class 2 scimitars" + "" + " in Stealing Creation."); + case 12: + return newstruct cs2func_script_1022_struct(20, 14124, "Members: Stealing Creation - class 2 pickaxe", "Members can now make " + "" + "class 2 pickaxes" + "" + " in Stealing Creation."); + case 13: + return newstruct cs2func_script_1022_struct(20, 14309, "Members: Stealing Creation - class 2 warhammer", "Members can now make " + "" + "class 2 warhammers" + "" + " in Stealing Creation."); + case 14: + return newstruct cs2func_script_1022_struct(20, 14359, "Members: Stealing Creation - class 2 platelegs", "Members can now make " + "" + "class 2 platelegs" + "" + " in Stealing Creation."); + case 15: + return newstruct cs2func_script_1022_struct(20, 14349, "Members: Stealing Creation - class 2 platebody", "Members can now make " + "" + "class 2 platebodies" + "" + " in Stealing Creation."); + case 16: + return newstruct cs2func_script_1022_struct(40, 14301, "Members: Stealing Creation - class 3 dagger", "Members can now make " + "" + "class 3 daggers" + "" + " in Stealing Creation."); + case 17: + return newstruct cs2func_script_1022_struct(40, 14136, "Members: Stealing Creation - class 3 hatchet", "Members can now make " + "" + "class 3 hatchets" + "" + " in Stealing Creation."); + case 18: + return newstruct cs2func_script_1022_struct(40, 14371, "Members: Stealing Creation - class 3 helmet", "Members can now make " + "" + "class 3 helmets" + "" + " in Stealing Creation."); + case 19: + return newstruct cs2func_script_1022_struct(40, 14291, "Members: Stealing Creation - class 3 scimitar", "Members can now make " + "" + "class 3 scimitars" + "" + " in Stealing Creation."); + case 20: + return newstruct cs2func_script_1022_struct(40, 14126, "Members: Stealing Creation - class 3 pickaxe", "Members can now make " + "" + "class 3 pickaxes" + "" + " in Stealing Creation."); + case 21: + return newstruct cs2func_script_1022_struct(40, 14311, "Members: Stealing Creation - class 3 warhammer", "Members can now make " + "" + "class 3 warhammers" + "" + " in Stealing Creation."); + case 22: + return newstruct cs2func_script_1022_struct(40, 14361, "Members: Stealing Creation - class 3 platelegs", "Members can now make " + "" + "class 3 platelegs" + "" + " in Stealing Creation."); + case 23: + return newstruct cs2func_script_1022_struct(40, 14351, "Members: Stealing Creation - class 3 platebody", "Members can now make " + "" + "class 3 platebodies" + "" + " in Stealing Creation."); + case 24: + return newstruct cs2func_script_1022_struct(60, 13256, "Members: Blast Furnace - Anvils", "Members can now use the " + "" + "anvils" + "" + " at the Blast Furnace."); + case 25: + return newstruct cs2func_script_1022_struct(60, 14303, "Members: Stealing Creation - class 4 dagger", "Members can now make " + "" + "class 4 daggers" + "" + " in Stealing Creation."); + case 26: + return newstruct cs2func_script_1022_struct(60, 14138, "Members: Stealing Creation - class 4 hatchet", "Members can now make " + "" + "class 4 hatchets" + "" + " in Stealing Creation."); + case 27: + return newstruct cs2func_script_1022_struct(60, 14373, "Members: Stealing Creation - class 4 helmet", "Members can now make " + "" + "class 4 helmets" + "" + " in Stealing Creation."); + case 28: + return newstruct cs2func_script_1022_struct(60, 14293, "Members: Stealing Creation - class 4 scimitar", "Members can now make " + "" + "class 4 scimitars" + "" + " in Stealing Creation."); + case 29: + return newstruct cs2func_script_1022_struct(60, 14128, "Members: Stealing Creation - class 4 pickaxe", "Members can now make " + "" + "class 4 pickaxes" + "" + " in Stealing Creation."); + case 30: + return newstruct cs2func_script_1022_struct(60, 14313, "Members: Stealing Creation - class 4 warhammer", "Members can now make " + "" + "class 4 warhammers" + "" + " in Stealing Creation."); + case 31: + return newstruct cs2func_script_1022_struct(60, 14363, "Members: Stealing Creation - class 4 platelegs", "Members can now make " + "" + "class 4 platelegs" + "" + " in Stealing Creation."); + case 32: + return newstruct cs2func_script_1022_struct(60, 14353, "Members: Stealing Creation - class 4 platebody", "Members can now make " + "" + "class 4 platebodies" + "" + " in Stealing Creation."); + case 33: + return newstruct cs2func_script_1022_struct(80, 14305, "Members: Stealing Creation - class 5 dagger", "Members can now make " + "" + "class 5 daggers" + "" + " in Stealing Creation."); + case 34: + return newstruct cs2func_script_1022_struct(80, 14140, "Members: Stealing Creation - class 5 hatchet", "Members can now make " + "" + "class 5 hatchets" + "" + " in Stealing Creation."); + case 35: + return newstruct cs2func_script_1022_struct(80, 14375, "Members: Stealing Creation - class 5 helmet", "Members can now make " + "" + "class 5 helmets" + "" + " in Stealing Creation."); + case 36: + return newstruct cs2func_script_1022_struct(80, 14295, "Members: Stealing Creation - class 5 scimitar", "Members can now make " + "" + "class 5 scimitars" + "" + " in Stealing Creation."); + case 37: + return newstruct cs2func_script_1022_struct(80, 14130, "Members: Stealing Creation - class 5 pickaxe", "Members can now make " + "" + "class 5 pickaxes" + "" + " in Stealing Creation."); + case 38: + return newstruct cs2func_script_1022_struct(80, 14315, "Members: Stealing Creation - class 5 warhammer", "Members can now make " + "" + "class 5 warhammers" + "" + " in Stealing Creation."); + case 39: + return newstruct cs2func_script_1022_struct(80, 14365, "Members: Stealing Creation - class 5 platelegs", "Members can now make " + "" + "class 5 platelegs" + "" + " in Stealing Creation."); + case 40: + return newstruct cs2func_script_1022_struct(80, 14355, "Members: Stealing Creation - class 5 platebody", "Members can now make " + "" + "class 5 platebodies" + "" + " in Stealing Creation."); + } + break; + case 14: + switch (arg1) { + case 0: + return newstruct cs2func_script_1022_struct(-1, 15707, "Dungeoneering skill tasks" + "
" + "As your Smithing level increases, you will be able to attempt higher-level smithing tasks within Daemonheim. You will also be more likely to succeed when attempting smithing tasks within Daemonheim.", ""); + case 1: + return newstruct cs2func_script_1022_struct(1, 17650, "Novite (Tier 1)", "You can now smelt " + "" + "novite" + "" + " within Daemonheim."); + case 2: + return newstruct cs2func_script_1022_struct(1, 17885, "Novite arrowheads (Tier 1) (15)" + "
" + " 1 bar", "You can now smith " + "" + "novite arrowheads" + "" + " within Daemonheim."); + case 3: + return newstruct cs2func_script_1022_struct(1, 16757, "Novite dagger (Tier 1)" + "
" + " 1 bar", "You can now smith " + "" + "novite daggers" + "" + " within Daemonheim."); + case 4: + return newstruct cs2func_script_1022_struct(1, 16339, "Novite boots (Tier 1)" + "
" + " 1 bar", "You can now smith " + "" + "novite boots" + "" + " within Daemonheim."); + case 5: + return newstruct cs2func_script_1022_struct(1, 16273, "Novite gauntlets (Tier 1)" + "
" + " 1 bar", "You can now smith " + "" + "novite gauntlets" + "" + " within Daemonheim."); + case 6: + return newstruct cs2func_script_1022_struct(2, 16361, "Novite hatchet (Tier 1)" + "
" + " 1 bar", "You can now smith " + "" + "novite hatchets" + "" + " within Daemonheim."); + case 7: + return newstruct cs2func_script_1022_struct(2, 16295, "Novite pickaxe (Tier 1)" + "
" + " 1 bar", "You can now smith " + "" + "novite pickaxes" + "" + " within Daemonheim."); + case 8: + return newstruct cs2func_script_1022_struct(3, 17019, "Novite warhammer (Tier 1)" + "
" + " 2 bars", "You can now smith " + "" + "novite warhammers" + "" + " within Daemonheim."); + case 9: + return newstruct cs2func_script_1022_struct(3, 16935, "Novite rapier (Tier 1)" + "
" + " 2 bars", "You can now smith " + "" + "novite rapiers" + "" + " within Daemonheim."); + case 10: + return newstruct cs2func_script_1022_struct(4, 16383, "Novite longsword (Tier 1)" + "
" + " 2 bars", "You can now smith " + "" + "novite longswords" + "" + " within Daemonheim."); + case 11: + return newstruct cs2func_script_1022_struct(5, 16691, "Novite full helm (Tier 1)" + "
" + " 2 bars", "You can now smith " + "" + "novite full helms" + "" + " within Daemonheim."); + case 12: + return newstruct cs2func_script_1022_struct(5, 15753, "Novite battleaxe (Tier 1)" + "
" + " 2 bars", "You can now smith " + "" + "novite battleaxes" + "" + " within Daemonheim."); + case 13: + return newstruct cs2func_script_1022_struct(6, 17341, "Novite kiteshield (Tier 1)" + "
" + " 3 bars", "You can now smith " + "" + "novite kiteshields" + "" + " within Daemonheim."); + case 14: + return newstruct cs2func_script_1022_struct(6, 16713, "Novite chainbody (Tier 1)" + "
" + " 3 bars", "You can now smith " + "" + "novite chainbodies" + "" + " within Daemonheim."); + case 15: + return newstruct cs2func_script_1022_struct(7, 16669, "Novite platelegs (Tier 1)" + "
" + " 3 bars", "You can now smith " + "" + "novite platelegs" + "" + " within Daemonheim."); + case 16: + return newstruct cs2func_script_1022_struct(7, 16647, "Novite plateskirt (Tier 1)" + "
" + " 3 bars", "You can now smith " + "" + "novite plateskirts" + "" + " within Daemonheim."); + case 17: + return newstruct cs2func_script_1022_struct(7, 17063, "Novite spear (Tier 1)" + "
" + " 4 bars", "You can now smith " + "" + "novite spears" + "" + " within Daemonheim."); + case 18: + return newstruct cs2func_script_1022_struct(8, 16405, "Novite maul (Tier 1)" + "
" + " 4 bars", "You can now smith " + "" + "novite mauls" + "" + " within Daemonheim."); + case 19: + return newstruct cs2func_script_1022_struct(8, 16889, "Novite 2h sword (Tier 1)" + "
" + " 4 bars", "You can now smith " + "" + "novite 2h swords" + "" + " within Daemonheim."); + case 20: + return newstruct cs2func_script_1022_struct(9, 17239, "Novite platebody (Tier 1)" + "
" + " 5 bars", "You can now smith " + "" + "novite platebodies" + "" + " within Daemonheim."); + case 21: + return newstruct cs2func_script_1022_struct(10, 17652, "Bathus (Tier 2)", "You can now smelt " + "" + "bathus" + "" + " within Daemonheim."); + case 22: + return newstruct cs2func_script_1022_struct(10, 17890, "Bathus arrowheads (Tier 2) (15)" + "
" + " 1 bar", "You can now smith " + "" + "bathus arrowheads" + "" + " within Daemonheim."); + case 23: + return newstruct cs2func_script_1022_struct(10, 16765, "Bathus dagger (Tier 2)" + "
" + " 1 bar", "You can now smith " + "" + "bathus daggers" + "" + " within Daemonheim."); + case 24: + return newstruct cs2func_script_1022_struct(11, 16341, "Bathus boots (Tier 2)" + "
" + " 1 bar", "You can now smith " + "" + "bathus boots" + "" + " within Daemonheim."); + case 25: + return newstruct cs2func_script_1022_struct(11, 16275, "Bathus gauntlets (Tier 2)" + "
" + " 1 bar", "You can now smith " + "" + "bathus gauntlets" + "" + " within Daemonheim."); + case 26: + return newstruct cs2func_script_1022_struct(12, 16363, "Bathus hatchet (Tier 2)" + "
" + " 1 bar", "You can now smith " + "" + "bathus hatchets" + "" + " within Daemonheim."); + case 27: + return newstruct cs2func_script_1022_struct(12, 16297, "Bathus pickaxe (Tier 2)" + "
" + " 1 bar", "You can now smith " + "" + "bathus pickaxes" + "" + " within Daemonheim."); + case 28: + return newstruct cs2func_script_1022_struct(13, 17021, "Bathus warhammer (Tier 2)" + "
" + " 2 bars", "You can now smith " + "" + "bathus warhammers" + "" + " within Daemonheim."); + case 29: + return newstruct cs2func_script_1022_struct(13, 16937, "Bathus rapier (Tier 2)" + "
" + " 2 bars", "You can now smith " + "" + "bathus rapiers" + "" + " within Daemonheim."); + case 30: + return newstruct cs2func_script_1022_struct(14, 16385, "Bathus longsword (Tier 2)" + "
" + " 2 bars", "You can now smith " + "" + "bathus longswords" + "" + " within Daemonheim."); + case 31: + return newstruct cs2func_script_1022_struct(15, 16693, "Bathus full helm (Tier 2)" + "
" + " 2 bars", "You can now smith " + "" + "bathus full helms" + "" + " within Daemonheim."); + case 32: + return newstruct cs2func_script_1022_struct(15, 15755, "Bathus battleaxe (Tier 2)" + "
" + " 2 bars", "You can now smith " + "" + "bathus battleaxes" + "" + " within Daemonheim."); + case 33: + return newstruct cs2func_script_1022_struct(16, 17343, "Bathus kiteshield (Tier 2)" + "
" + " 3 bars", "You can now smith " + "" + "bathus kiteshields" + "" + " within Daemonheim."); + case 34: + return newstruct cs2func_script_1022_struct(16, 16715, "Bathus chainbody (Tier 2)" + "
" + " 3 bars", "You can now smith " + "" + "bathus chainbodies" + "" + " within Daemonheim."); + case 35: + return newstruct cs2func_script_1022_struct(17, 16671, "Bathus platelegs (Tier 2)" + "
" + " 3 bars", "You can now smith " + "" + "bathus platelegs" + "" + " within Daemonheim."); + case 36: + return newstruct cs2func_script_1022_struct(17, 16649, "Bathus plateskirt (Tier 2)" + "
" + " 3 bars", "You can now smith " + "" + "bathus plateskirts" + "" + " within Daemonheim."); + case 37: + return newstruct cs2func_script_1022_struct(17, 17071, "Bathus spear (Tier 2)" + "
" + " 4 bars", "You can now smith " + "" + "bathus spears" + "" + " within Daemonheim."); + case 38: + return newstruct cs2func_script_1022_struct(18, 16407, "Bathus maul (Tier 2)" + "
" + " 4 bars", "You can now smith " + "" + "bathus mauls" + "" + " within Daemonheim."); + case 39: + return newstruct cs2func_script_1022_struct(18, 16891, "Bathus 2h sword (Tier 2)" + "
" + " 4 bars", "You can now smith " + "" + "bathus 2h swords" + "" + " within Daemonheim."); + case 40: + return newstruct cs2func_script_1022_struct(19, 17241, "Bathus platebody (Tier 2)" + "
" + " 5 bars", "You can now smith " + "" + "bathus platebodies" + "" + " within Daemonheim."); + case 41: + return newstruct cs2func_script_1022_struct(20, 17654, "Marmaros (Tier 3)", "You can now smelt " + "" + "marmaros" + "" + " within Daemonheim."); + case 42: + return newstruct cs2func_script_1022_struct(20, 17895, "Marmaros arrowheads (Tier 3) (15)" + "
" + " 1 bar", "You can now smith " + "" + "marmaros arrowheads" + "" + " within Daemonheim."); + case 43: + return newstruct cs2func_script_1022_struct(20, 16773, "Marmaros dagger (Tier 3)" + "
" + " 1 bar", "You can now smith " + "" + "marmaros daggers" + "" + " within Daemonheim."); + case 44: + return newstruct cs2func_script_1022_struct(21, 16343, "Marmaros boots (Tier 3)" + "
" + " 1 bar", "You can now smith " + "" + "marmaros boots" + "" + " within Daemonheim."); + case 45: + return newstruct cs2func_script_1022_struct(21, 16277, "Marmaros gauntlets (Tier 3)" + "
" + " 1 bar", "You can now smith " + "" + "marmaros gauntlets" + "" + " within Daemonheim."); + case 46: + return newstruct cs2func_script_1022_struct(22, 16365, "Marmaros hatchet (Tier 3)" + "
" + " 1 bar", "You can now smith " + "" + "marmaros hatchets" + "" + " within Daemonheim."); + case 47: + return newstruct cs2func_script_1022_struct(22, 16299, "Marmaros pickaxe (Tier 3)" + "
" + " 1 bar", "You can now smith " + "" + "marmaros pickaxes" + "" + " within Daemonheim."); + case 48: + return newstruct cs2func_script_1022_struct(23, 17023, "Marmaros warhammer (Tier 3)" + "
" + " 2 bars", "You can now smith " + "" + "marmaros warhammers" + "" + " within Daemonheim."); + case 49: + return newstruct cs2func_script_1022_struct(23, 16939, "Marmaros rapier (Tier 3)" + "
" + " 2 bars", "You can now smith " + "" + "marmaros rapiers" + "" + " within Daemonheim."); + case 50: + return newstruct cs2func_script_1022_struct(24, 16387, "Marmaros longsword (Tier 3)" + "
" + " 2 bars", "You can now smith " + "" + "marmaros longswords" + "" + " within Daemonheim."); + case 51: + return newstruct cs2func_script_1022_struct(25, 16695, "Marmaros full helm (Tier 3)" + "
" + " 2 bars", "You can now smith " + "" + "marmaros full helms" + "" + " within Daemonheim."); + case 52: + return newstruct cs2func_script_1022_struct(25, 15757, "Marmaros battleaxe (Tier 3)" + "
" + " 2 bars", "You can now smith " + "" + "marmaros battleaxes" + "" + " within Daemonheim."); + case 53: + return newstruct cs2func_script_1022_struct(26, 17345, "Marmaros kiteshield (Tier 3)" + "
" + " 3 bars", "You can now smith " + "" + "marmaros kiteshields" + "" + " within Daemonheim."); + case 54: + return newstruct cs2func_script_1022_struct(26, 16717, "Marmaros chainbody (Tier 3)" + "
" + " 3 bars", "You can now smith " + "" + "marmaros chainbodies" + "" + " within Daemonheim."); + case 55: + return newstruct cs2func_script_1022_struct(27, 16673, "Marmaros platelegs (Tier 3)" + "
" + " 3 bars", "You can now smith " + "" + "marmaros platelegs" + "" + " within Daemonheim."); + case 56: + return newstruct cs2func_script_1022_struct(27, 16651, "Marmaros plateskirt (Tier 3)" + "
" + " 3 bars", "You can now smith " + "" + "marmaros plateskirts" + "" + " within Daemonheim."); + case 57: + return newstruct cs2func_script_1022_struct(27, 17079, "Marmaros spear (Tier 3)" + "
" + " 4 bars", "You can now smith " + "" + "marmaros spears" + "" + " within Daemonheim."); + case 58: + return newstruct cs2func_script_1022_struct(28, 16409, "Marmaros maul (Tier 3)" + "
" + " 4 bars", "You can now smith " + "" + "marmaros mauls" + "" + " within Daemonheim."); + case 59: + return newstruct cs2func_script_1022_struct(28, 16893, "Marmaros 2h sword (Tier 3)" + "
" + " 4 bars", "You can now smith " + "" + "marmaros 2h swords" + "" + " within Daemonheim."); + case 60: + return newstruct cs2func_script_1022_struct(29, 17243, "Marmaros platebody (Tier 3)" + "
" + " 5 bars", "You can now smith " + "" + "marmaros platebodies" + "" + " within Daemonheim."); + case 61: + return newstruct cs2func_script_1022_struct(30, 17656, "Kratonite (Tier 4)", "You can now smelt " + "" + "kratonite" + "" + " within Daemonheim."); + case 62: + return newstruct cs2func_script_1022_struct(30, 17900, "Kratonite arrowheads (Tier 4) (15)" + "
" + " 1 bar", "You can now smith " + "" + "kratonite arrowheads" + "" + " within Daemonheim."); + case 63: + return newstruct cs2func_script_1022_struct(30, 16781, "Kratonite dagger (Tier 4)" + "
" + " 1 bar", "You can now smith " + "" + "kratonite daggers" + "" + " within Daemonheim."); + case 64: + return newstruct cs2func_script_1022_struct(31, 16345, "Kratonite boots (Tier 4)" + "
" + " 1 bar", "You can now smith " + "" + "kratonite boots" + "" + " within Daemonheim."); + case 65: + return newstruct cs2func_script_1022_struct(31, 16279, "Kratonite gauntlets (Tier 4)" + "
" + " 1 bar", "You can now smith " + "" + "kratonite gauntlets" + "" + " within Daemonheim."); + case 66: + return newstruct cs2func_script_1022_struct(32, 16367, "Kratonite hatchet (Tier 4)" + "
" + " 1 bar", "You can now smith " + "" + "kratonite hatchets" + "" + " within Daemonheim."); + case 67: + return newstruct cs2func_script_1022_struct(32, 16301, "Kratonite pickaxe (Tier 4)" + "
" + " 1 bar", "You can now smith " + "" + "kratonite pickaxes" + "" + " within Daemonheim."); + case 68: + return newstruct cs2func_script_1022_struct(33, 17025, "Kratonite warhammer (Tier 4)" + "
" + " 2 bars", "You can now smith " + "" + "kratonite warhammers" + "" + " within Daemonheim."); + case 69: + return newstruct cs2func_script_1022_struct(33, 16941, "Kratonite rapier (Tier 4)" + "
" + " 2 bars", "You can now smith " + "" + "kratonite rapiers" + "" + " within Daemonheim."); + case 70: + return newstruct cs2func_script_1022_struct(34, 16389, "Kratonite longsword (Tier 4)" + "
" + " 2 bars", "You can now smith " + "" + "kratonite longswords" + "" + " within Daemonheim."); + case 71: + return newstruct cs2func_script_1022_struct(35, 16697, "Kratonite full helm (Tier 4)" + "
" + " 2 bars", "You can now smith " + "" + "kratonite full helms" + "" + " within Daemonheim."); + case 72: + return newstruct cs2func_script_1022_struct(35, 15759, "Kratonite battleaxe (Tier 4)" + "
" + " 2 bars", "You can now smith " + "" + "kratonite battleaxes" + "" + " within Daemonheim."); + case 73: + return newstruct cs2func_script_1022_struct(36, 17347, "Kratonite kiteshield (Tier 4)" + "
" + " 3 bars", "You can now smith " + "" + "kratonite kiteshields" + "" + " within Daemonheim."); + case 74: + return newstruct cs2func_script_1022_struct(36, 16719, "Kratonite chainbody (Tier 4)" + "
" + " 3 bars", "You can now smith " + "" + "kratonite chainbodies" + "" + " within Daemonheim."); + case 75: + return newstruct cs2func_script_1022_struct(37, 16675, "Kratonite platelegs (Tier 4)" + "
" + " 3 bars", "You can now smith " + "" + "kratonite platelegs" + "" + " within Daemonheim."); + case 76: + return newstruct cs2func_script_1022_struct(37, 16653, "Kratonite plateskirt (Tier 4)" + "
" + " 3 bars", "You can now smith " + "" + "kratonite plateskirts" + "" + " within Daemonheim."); + case 77: + return newstruct cs2func_script_1022_struct(37, 17087, "Kratonite spear (Tier 4)" + "
" + " 4 bars", "You can now smith " + "" + "kratonite spears" + "" + " within Daemonheim."); + case 78: + return newstruct cs2func_script_1022_struct(38, 16411, "Kratonite maul (Tier 4)" + "
" + " 4 bars", "You can now smith " + "" + "kratonite mauls" + "" + " within Daemonheim."); + case 79: + return newstruct cs2func_script_1022_struct(38, 16895, "Kratonite 2h sword (Tier 4)" + "
" + " 4 bars", "You can now smith " + "" + "kratonite 2h swords" + "" + " within Daemonheim."); + case 80: + return newstruct cs2func_script_1022_struct(39, 17245, "Kratonite platebody (Tier 4)" + "
" + " 5 bars", "You can now smith " + "" + "kratonite platebodies" + "" + " within Daemonheim."); + case 81: + return newstruct cs2func_script_1022_struct(40, 17658, "Fractite (Tier 5)", "You can now smelt " + "" + "fractite" + "" + " within Daemonheim."); + case 82: + return newstruct cs2func_script_1022_struct(40, 17905, "Fractite arrowheads (Tier 5) (15)" + "
" + " 1 bar", "You can now smith " + "" + "fractite arrowheads" + "" + " within Daemonheim."); + case 83: + return newstruct cs2func_script_1022_struct(40, 16789, "Fractite dagger (Tier 5)" + "
" + " 1 bar", "You can now smith " + "" + "fractite daggers" + "" + " within Daemonheim."); + case 84: + return newstruct cs2func_script_1022_struct(41, 16347, "Fractite boots (Tier 5)" + "
" + " 1 bar", "You can now smith " + "" + "fractite boots" + "" + " within Daemonheim."); + case 85: + return newstruct cs2func_script_1022_struct(41, 16281, "Fractite gauntlets (Tier 5)" + "
" + " 1 bar", "You can now smith " + "" + "fractite gauntlets" + "" + " within Daemonheim."); + case 86: + return newstruct cs2func_script_1022_struct(42, 16369, "Fractite hatchet (Tier 5)" + "
" + " 1 bar", "You can now smith " + "" + "fractite hatchets" + "" + " within Daemonheim."); + case 87: + return newstruct cs2func_script_1022_struct(42, 16303, "Fractite pickaxe (Tier 5)" + "
" + " 1 bar", "You can now smith " + "" + "fractite pickaxes" + "" + " within Daemonheim."); + case 88: + return newstruct cs2func_script_1022_struct(43, 17027, "Fractite warhammer (Tier 5)" + "
" + " 2 bars", "You can now smith " + "" + "fractite warhammers" + "" + " within Daemonheim."); + case 89: + return newstruct cs2func_script_1022_struct(43, 16943, "Fractite rapier (Tier 5)" + "
" + " 2 bars", "You can now smith " + "" + "fractite rapiers" + "" + " within Daemonheim."); + case 90: + return newstruct cs2func_script_1022_struct(44, 16391, "Fractite longsword (Tier 5)" + "
" + " 2 bars", "You can now smith " + "" + "fractite longswords" + "" + " within Daemonheim."); + case 91: + return newstruct cs2func_script_1022_struct(45, 16699, "Fractite full helm (Tier 5)" + "
" + " 2 bars", "You can now smith " + "" + "fractite full helms" + "" + " within Daemonheim."); + case 92: + return newstruct cs2func_script_1022_struct(45, 15761, "Fractite battleaxe (Tier 5)" + "
" + " 2 bars", "You can now smith " + "" + "fractite battleaxes" + "" + " within Daemonheim."); + case 93: + return newstruct cs2func_script_1022_struct(46, 17349, "Fractite kiteshield (Tier 5)" + "
" + " 3 bars", "You can now smith " + "" + "fractite kiteshields" + "" + " within Daemonheim."); + case 94: + return newstruct cs2func_script_1022_struct(46, 16721, "Fractite chainbody (Tier 5)" + "
" + " 3 bars", "You can now smith " + "" + "fractite chainbodies" + "" + " within Daemonheim."); + case 95: + return newstruct cs2func_script_1022_struct(47, 16677, "Fractite platelegs (Tier 5)" + "
" + " 3 bars", "You can now smith " + "" + "fractite platelegs" + "" + " within Daemonheim."); + case 96: + return newstruct cs2func_script_1022_struct(47, 16655, "Fractite plateskirt (Tier 5)" + "
" + " 3 bars", "You can now smith " + "" + "fractite plateskirts" + "" + " within Daemonheim."); + case 97: + return newstruct cs2func_script_1022_struct(47, 17095, "Fractite spear (Tier 5)" + "
" + " 4 bars", "You can now smith " + "" + "fractite spears" + "" + " within Daemonheim."); + case 98: + return newstruct cs2func_script_1022_struct(48, 16413, "Fractite maul (Tier 5)" + "
" + " 4 bars", "You can now smith " + "" + "fractite mauls" + "" + " within Daemonheim."); + case 99: + return newstruct cs2func_script_1022_struct(48, 16897, "Fractite 2h sword (Tier 5)" + "
" + " 4 bars", "You can now smith " + "" + "fractite 2h swords" + "" + " within Daemonheim."); + case 100: + return newstruct cs2func_script_1022_struct(49, 17247, "Fractite platebody (Tier 5)" + "
" + " 5 bars", "You can now smith " + "" + "fractite platebodies" + "" + " within Daemonheim."); + case 101: + return newstruct cs2func_script_1022_struct(50, 17660, "Members: Zephyrium (Tier 6)", "Members can now smelt " + "" + "zephyrium" + "" + " within Daemonheim."); + case 102: + return newstruct cs2func_script_1022_struct(50, 17910, "Members: Zephyrium arrowheads (Tier 6) (15)" + "
" + " 1 bar", "Members can now smith " + "" + "zephyrium arrowheads" + "" + " within Daemonheim."); + case 103: + return newstruct cs2func_script_1022_struct(50, 16797, "Members: Zephyrium dagger (Tier 6)" + "
" + " 1 bar", "Members can now smith " + "" + "zephyrium daggers" + "" + " within Daemonheim."); + case 104: + return newstruct cs2func_script_1022_struct(51, 16349, "Members: Zephyrium boots (Tier 6)" + "
" + " 1 bar", "Members can now smith " + "" + "zephyrium boots" + "" + " within Daemonheim."); + case 105: + return newstruct cs2func_script_1022_struct(51, 16283, "Members: Zephyrium gauntlets (Tier 6)" + "
" + " 1 bar", "Members can now smith " + "" + "zephyrium gauntlets" + "" + " within Daemonheim."); + case 106: + return newstruct cs2func_script_1022_struct(52, 16371, "Members: Zephyrium hatchet (Tier 6)" + "
" + " 1 bar", "Members can now smith " + "" + "zephyrium hatchets" + "" + " within Daemonheim."); + case 107: + return newstruct cs2func_script_1022_struct(52, 16305, "Members: Zephyrium pickaxe (Tier 6)" + "
" + " 1 bar", "Members can now smith " + "" + "zephyrium pickaxes" + "" + " within Daemonheim."); + case 108: + return newstruct cs2func_script_1022_struct(53, 17029, "Members: Zephyrium warhammer (Tier 6)" + "
" + " 2 bars", "Members can now smith " + "" + "zephyrium warhammers" + "" + " within Daemonheim."); + case 109: + return newstruct cs2func_script_1022_struct(53, 16945, "Members: Zephyrium rapier (Tier 6)" + "
" + " 2 bars", "Members can now smith " + "" + "zephyrium rapiers" + "" + " within Daemonheim."); + case 110: + return newstruct cs2func_script_1022_struct(54, 16393, "Members: Zephyrium longsword (Tier 6)" + "
" + " 2 bars", "Members can now smith " + "" + "zephyrium longswords" + "" + " within Daemonheim."); + case 111: + return newstruct cs2func_script_1022_struct(55, 16701, "Members: Zephyrium full helm (Tier 6)" + "
" + " 2 bars", "Members can now smith " + "" + "zephyrium full helms" + "" + " within Daemonheim."); + case 112: + return newstruct cs2func_script_1022_struct(55, 15763, "Members: Zephyrium battleaxe (Tier 6)" + "
" + " 2 bars", "Members can now smith " + "" + "zephyrium battleaxes" + "" + " within Daemonheim."); + case 113: + return newstruct cs2func_script_1022_struct(56, 17351, "Members: Zephyrium kiteshield (Tier 6)" + "
" + " 3 bars", "Members can now smith " + "" + "zephyrium kiteshields" + "" + " within Daemonheim."); + case 114: + return newstruct cs2func_script_1022_struct(56, 16723, "Members: Zephyrium chainbody (Tier 6)" + "
" + " 3 bars", "Members can now smith " + "" + "zephyrium chainbodies" + "" + " within Daemonheim."); + case 115: + return newstruct cs2func_script_1022_struct(57, 16679, "Members: Zephyrium platelegs (Tier 6)" + "
" + " 3 bars", "Members can now smith " + "" + "zephyrium platelegs" + "" + " within Daemonheim."); + case 116: + return newstruct cs2func_script_1022_struct(57, 16657, "Members: Zephyrium plateskirt (Tier 6)" + "
" + " 3 bars", "Members can now smith " + "" + "zephyrium plateskirts" + "" + " within Daemonheim."); + case 117: + return newstruct cs2func_script_1022_struct(57, 17103, "Members: Zephyrium spear (Tier 6)" + "
" + " 4 bars", "Members can now smith " + "" + "zephyrium spears" + "" + " within Daemonheim."); + case 118: + return newstruct cs2func_script_1022_struct(58, 16415, "Members: Zephyrium maul (Tier 6)" + "
" + " 4 bars", "Members can now smith " + "" + "zephyrium mauls" + "" + " within Daemonheim."); + case 119: + return newstruct cs2func_script_1022_struct(58, 16899, "Members: Zephyrium 2h sword (Tier 6)" + "
" + " 4 bars", "Members can now smith " + "" + "zephyrium 2h swords" + "" + " within Daemonheim."); + case 120: + return newstruct cs2func_script_1022_struct(59, 17249, "Members: Zephyrium platebody (Tier 6)" + "
" + " 5 bars", "Members can now smith " + "" + "zephyrium platebodies" + "" + " within Daemonheim."); + case 121: + return newstruct cs2func_script_1022_struct(60, 17662, "Members: Argonite (Tier 7)", "Members can now smelt " + "" + "argonite" + "" + " within Daemonheim."); + case 122: + return newstruct cs2func_script_1022_struct(60, 17915, "Members: Argonite arrowheads (Tier 7) (15)" + "
" + " 1 bar", "Members can now smith " + "" + "argonite arrowheads" + "" + " within Daemonheim."); + case 123: + return newstruct cs2func_script_1022_struct(60, 16805, "Members: Argonite dagger (Tier 7)" + "
" + " 1 bar", "Members can now smith " + "" + "argonite daggers" + "" + " within Daemonheim."); + case 124: + return newstruct cs2func_script_1022_struct(61, 16351, "Members: Argonite boots (Tier 7)" + "
" + " 1 bar", "Members can now smith " + "" + "argonite boots" + "" + " within Daemonheim."); + case 125: + return newstruct cs2func_script_1022_struct(61, 16285, "Members: Argonite gauntlets (Tier 7)" + "
" + " 1 bar", "Members can now smith " + "" + "argonite gauntlets" + "" + " within Daemonheim."); + case 126: + return newstruct cs2func_script_1022_struct(62, 16373, "Members: Argonite hatchet (Tier 7)" + "
" + " 1 bar", "Members can now smith " + "" + "argonite hatchets" + "" + " within Daemonheim."); + case 127: + return newstruct cs2func_script_1022_struct(62, 16307, "Members: Argonite pickaxe (Tier 7)" + "
" + " 1 bar", "Members can now smith " + "" + "argonite pickaxes" + "" + " within Daemonheim."); + case 128: + return newstruct cs2func_script_1022_struct(63, 17031, "Members: Argonite warhammer (Tier 7)" + "
" + " 2 bars", "Members can now smith " + "" + "argonite warhammers" + "" + " within Daemonheim."); + case 129: + return newstruct cs2func_script_1022_struct(63, 16947, "Members: Argonite rapier (Tier 7)" + "
" + " 2 bars", "Members can now smith " + "" + "argonite rapiers" + "" + " within Daemonheim."); + case 130: + return newstruct cs2func_script_1022_struct(64, 16395, "Members: Argonite longsword (Tier 7)" + "
" + " 2 bars", "Members can now smith " + "" + "argonite longswords" + "" + " within Daemonheim."); + case 131: + return newstruct cs2func_script_1022_struct(65, 16703, "Members: Argonite full helm (Tier 7)" + "
" + " 2 bars", "Members can now smith " + "" + "argonite full helms" + "" + " within Daemonheim."); + case 132: + return newstruct cs2func_script_1022_struct(65, 15765, "Members: Argonite battleaxe (Tier 7)" + "
" + " 2 bars", "Members can now smith " + "" + "argonite battleaxes" + "" + " within Daemonheim."); + case 133: + return newstruct cs2func_script_1022_struct(66, 17353, "Members: Argonite kiteshield (Tier 7)" + "
" + " 3 bars", "Members can now smith " + "" + "argonite kiteshields" + "" + " within Daemonheim."); + case 134: + return newstruct cs2func_script_1022_struct(66, 16725, "Members: Argonite chainbody (Tier 7)" + "
" + " 3 bars", "Members can now smith " + "" + "argonite chainbodies" + "" + " within Daemonheim."); + case 135: + return newstruct cs2func_script_1022_struct(67, 16681, "Members: Argonite platelegs (Tier 7)" + "
" + " 3 bars", "Members can now smith " + "" + "argonite platelegs" + "" + " within Daemonheim."); + case 136: + return newstruct cs2func_script_1022_struct(67, 16659, "Members: Argonite plateskirt (Tier 7)" + "
" + " 3 bars", "Members can now smith " + "" + "argonite plateskirts" + "" + " within Daemonheim."); + case 137: + return newstruct cs2func_script_1022_struct(67, 17111, "Members: Argonite spear (Tier 7)" + "
" + " 4 bars", "Members can now smith " + "" + "argonite spears" + "" + " within Daemonheim."); + case 138: + return newstruct cs2func_script_1022_struct(68, 16417, "Members: Argonite maul (Tier 7)" + "
" + " 4 bars", "Members can now smith " + "" + "argonite mauls" + "" + " within Daemonheim."); + case 139: + return newstruct cs2func_script_1022_struct(68, 16901, "Members: Argonite 2h sword (Tier 7)" + "
" + " 4 bars", "Members can now smith " + "" + "argonite 2h swords" + "" + " within Daemonheim."); + case 140: + return newstruct cs2func_script_1022_struct(69, 17251, "Members: Argonite platebody (Tier 7)" + "
" + " 5 bars", "Members can now smith " + "" + "argonite platebodies" + "" + " within Daemonheim."); + case 141: + return newstruct cs2func_script_1022_struct(70, 17664, "Members: Katagon (Tier 8)", "Members can now smelt " + "" + "katagon" + "" + " within Daemonheim."); + case 142: + return newstruct cs2func_script_1022_struct(70, 17920, "Members: Katagon arrowheads (Tier 8) (15)" + "
" + " 1 bar", "Members can now smith " + "" + "katagon arrowheads" + "" + " within Daemonheim."); + case 143: + return newstruct cs2func_script_1022_struct(70, 16813, "Members: Katagon dagger (Tier 8)" + "
" + " 1 bar", "Members can now smith " + "" + "katagon daggers" + "" + " within Daemonheim."); + case 144: + return newstruct cs2func_script_1022_struct(71, 16353, "Members: Katagon boots (Tier 8)" + "
" + " 1 bar", "Members can now smith " + "" + "katagon boots" + "" + " within Daemonheim."); + case 145: + return newstruct cs2func_script_1022_struct(71, 16287, "Members: Katagon gauntlets (Tier 8)" + "
" + " 1 bar", "Members can now smith " + "" + "katagon gauntlets" + "" + " within Daemonheim."); + case 146: + return newstruct cs2func_script_1022_struct(72, 16375, "Members: Katagon hatchet (Tier 8)" + "
" + " 1 bar", "Members can now smith " + "" + "katagon hatchets" + "" + " within Daemonheim."); + case 147: + return newstruct cs2func_script_1022_struct(72, 16309, "Members: Katagon pickaxe (Tier 8)" + "
" + " 1 bar", "Members can now smith " + "" + "katagon pickaxes" + "" + " within Daemonheim."); + case 148: + return newstruct cs2func_script_1022_struct(73, 17033, "Members: Katagon warhammer (Tier 8)" + "
" + " 2 bars", "Members can now smith " + "" + "katagon warhammers" + "" + " within Daemonheim."); + case 149: + return newstruct cs2func_script_1022_struct(73, 16949, "Members: Katagon rapier (Tier 8)" + "
" + " 2 bars", "Members can now smith " + "" + "katagon rapiers" + "" + " within Daemonheim."); + case 150: + return newstruct cs2func_script_1022_struct(74, 16397, "Members: Katagon longsword (Tier 8)" + "
" + " 2 bars", "Members can now smith " + "" + "katagon longswords" + "" + " within Daemonheim."); + case 151: + return newstruct cs2func_script_1022_struct(75, 16705, "Members: Katagon full helm (Tier 8)" + "
" + " 2 bars", "Members can now smith " + "" + "katagon full helms" + "" + " within Daemonheim."); + case 152: + return newstruct cs2func_script_1022_struct(75, 15767, "Members: Katagon battleaxe (Tier 8)" + "
" + " 2 bars", "Members can now smith " + "" + "katagon battleaxes" + "" + " within Daemonheim."); + case 153: + return newstruct cs2func_script_1022_struct(76, 17355, "Members: Katagon kiteshield (Tier 8)" + "
" + " 3 bars", "Members can now smith " + "" + "katagon kiteshields" + "" + " within Daemonheim."); + case 154: + return newstruct cs2func_script_1022_struct(76, 16727, "Members: Katagon chainbody (Tier 8)" + "
" + " 3 bars", "Members can now smith " + "" + "katagon chainbodies" + "" + " within Daemonheim."); + case 155: + return newstruct cs2func_script_1022_struct(77, 16683, "Members: Katagon platelegs (Tier 8)" + "
" + " 3 bars", "Members can now smith " + "" + "katagon platelegs" + "" + " within Daemonheim."); + case 156: + return newstruct cs2func_script_1022_struct(77, 16661, "Members: Katagon plateskirt (Tier 8)" + "
" + " 3 bars", "Members can now smith " + "" + "katagon plateskirts" + "" + " within Daemonheim."); + case 157: + return newstruct cs2func_script_1022_struct(77, 17119, "Members: Katagon spear (Tier 8)" + "
" + " 4 bars", "Members can now smith " + "" + "katagon spears" + "" + " within Daemonheim."); + case 158: + return newstruct cs2func_script_1022_struct(78, 16419, "Members: Katagon maul (Tier 8)" + "
" + " 4 bars", "Members can now smith " + "" + "katagon mauls" + "" + " within Daemonheim."); + case 159: + return newstruct cs2func_script_1022_struct(78, 16903, "Members: Katagon 2h sword (Tier 8)" + "
" + " 4 bars", "Members can now smith " + "" + "katagon 2h swords" + "" + " within Daemonheim."); + case 160: + return newstruct cs2func_script_1022_struct(79, 17253, "Members: Katagon platebody (Tier 8)" + "
" + " 5 bars", "Members can now smith " + "" + "katagon platebodies" + "" + " within Daemonheim."); + case 161: + return newstruct cs2func_script_1022_struct(80, 17666, "Members: Gorgonite (Tier 9)", "Members can now smelt " + "" + "gorgonite" + "" + " within Daemonheim."); + case 162: + return newstruct cs2func_script_1022_struct(80, 17925, "Members: Gorgonite arrowheads (Tier 9) (15)" + "
" + " 1 bar", "Members can now smith " + "" + "gorgonite arrowheads" + "" + " within Daemonheim."); + case 163: + return newstruct cs2func_script_1022_struct(80, 16821, "Members: Gorgonite dagger (Tier 9)" + "
" + " 1 bar", "Members can now smith " + "" + "gorgonite daggers" + "" + " within Daemonheim."); + case 164: + return newstruct cs2func_script_1022_struct(81, 16355, "Members: Gorgonite boots (Tier 9)" + "
" + " 1 bar", "Members can now smith " + "" + "gorgonite boots" + "" + " within Daemonheim."); + case 165: + return newstruct cs2func_script_1022_struct(81, 16289, "Members: Gorgonite gauntlets (Tier 9)" + "
" + " 1 bar", "Members can now smith " + "" + "gorgonite gauntlets" + "" + " within Daemonheim."); + case 166: + return newstruct cs2func_script_1022_struct(82, 16377, "Members: Gorgonite hatchet (Tier 9)" + "
" + " 1 bar", "Members can now smith " + "" + "gorgonite hatchets" + "" + " within Daemonheim."); + case 167: + return newstruct cs2func_script_1022_struct(82, 16311, "Members: Gorgonite pickaxe (Tier 9)" + "
" + " 1 bar", "Members can now smith " + "" + "gorgonite pickaxes" + "" + " within Daemonheim."); + case 168: + return newstruct cs2func_script_1022_struct(83, 17035, "Members: Gorgonite warhammer (Tier 9)" + "
" + " 2 bars", "Members can now smith " + "" + "gorgonite warhammers" + "" + " within Daemonheim."); + case 169: + return newstruct cs2func_script_1022_struct(83, 16951, "Members: Gorgonite rapier (Tier 9)" + "
" + " 2 bars", "Members can now smith " + "" + "gorgonite rapiers" + "" + " within Daemonheim."); + case 170: + return newstruct cs2func_script_1022_struct(84, 16399, "Members: Gorgonite longsword (Tier 9)" + "
" + " 2 bars", "Members can now smith " + "" + "gorgonite longswords" + "" + " within Daemonheim."); + case 171: + return newstruct cs2func_script_1022_struct(85, 16707, "Members: Gorgonite full helm (Tier 9)" + "
" + " 2 bars", "Members can now smith " + "" + "gorgonite full helms" + "" + " within Daemonheim."); + case 172: + return newstruct cs2func_script_1022_struct(85, 15769, "Members: Gorgonite battleaxe (Tier 9)" + "
" + " 2 bars", "Members can now smith " + "" + "gorgonite battleaxes" + "" + " within Daemonheim."); + case 173: + return newstruct cs2func_script_1022_struct(86, 17357, "Members: Gorgonite kiteshield (Tier 9)" + "
" + " 3 bars", "Members can now smith " + "" + "gorgonite kiteshields" + "" + " within Daemonheim."); + case 174: + return newstruct cs2func_script_1022_struct(86, 16729, "Members: Gorgonite chainbody (Tier 9)" + "
" + " 3 bars", "Members can now smith " + "" + "gorgonite chainbodies" + "" + " within Daemonheim."); + case 175: + return newstruct cs2func_script_1022_struct(87, 16685, "Members: Gorgonite platelegs (Tier 9)" + "
" + " 3 bars", "Members can now smith " + "" + "gorgonite platelegs" + "" + " within Daemonheim."); + case 176: + return newstruct cs2func_script_1022_struct(87, 16663, "Members: Gorgonite plateskirt (Tier 9)" + "
" + " 3 bars", "Members can now smith " + "" + "gorgonite plateskirts" + "" + " within Daemonheim."); + case 177: + return newstruct cs2func_script_1022_struct(87, 17127, "Members: Gorgonite spear (Tier 9)" + "
" + " 4 bars", "Members can now smith " + "" + "gorgonite spears" + "" + " within Daemonheim."); + case 178: + return newstruct cs2func_script_1022_struct(88, 16421, "Members: Gorgonite maul (Tier 9)" + "
" + " 4 bars", "Members can now smith " + "" + "gorgonite mauls" + "" + " within Daemonheim."); + case 179: + return newstruct cs2func_script_1022_struct(88, 16905, "Members: Gorgonite 2h sword (Tier 9)" + "
" + " 4 bars", "Members can now smith " + "" + "gorgonite 2h swords" + "" + " within Daemonheim."); + case 180: + return newstruct cs2func_script_1022_struct(89, 17255, "Members: Gorgonite platebody (Tier 9)" + "
" + " 5 bars", "Members can now smith " + "" + "gorgonite platebodies" + "" + " within Daemonheim."); + case 181: + return newstruct cs2func_script_1022_struct(90, 17668, "Members: Promethium (Tier 10)", "Members can now smelt " + "" + "Promethium" + "" + " within Daemonheim."); + case 182: + return newstruct cs2func_script_1022_struct(90, 17930, "Members: Promethium arrowheads (Tier 10) (15)" + "
" + " 1 bar", "Members can now smith " + "" + "promethium arrowheads" + "" + " within Daemonheim."); + case 183: + return newstruct cs2func_script_1022_struct(90, 16829, "Members: Promethium dagger (Tier 10)" + "
" + " 1 bar", "Members can now smith " + "" + "promethium daggers" + "" + " within Daemonheim."); + case 184: + return newstruct cs2func_script_1022_struct(91, 16357, "Members: Promethium boots (Tier 10)" + "
" + " 1 bar", "Members can now smith " + "" + "promethium boots" + "" + " within Daemonheim."); + case 185: + return newstruct cs2func_script_1022_struct(91, 16291, "Members: Promethium gauntlets (Tier 10)" + "
" + " 1 bar", "Members can now smith " + "" + "promethium gauntlets" + "" + " within Daemonheim."); + case 186: + return newstruct cs2func_script_1022_struct(92, 16379, "Members: Promethium hatchet (Tier 10)" + "
" + " 1 bar", "Members can now smith " + "" + "promethium hatchets" + "" + " within Daemonheim."); + case 187: + return newstruct cs2func_script_1022_struct(92, 16313, "Members: Promethium pickaxe (Tier 10)" + "
" + " 1 bar", "Members can now smith " + "" + "promethium pickaxes" + "" + " within Daemonheim."); + case 188: + return newstruct cs2func_script_1022_struct(93, 17037, "Members: Promethium warhammer (Tier 10)" + "
" + " 2 bars", "Members can now smith " + "" + "promethium warhammers" + "" + " within Daemonheim."); + case 189: + return newstruct cs2func_script_1022_struct(93, 16953, "Members: Promethium rapier (Tier 10)" + "
" + " 2 bars", "Members can now smith " + "" + "promethium rapiers" + "" + " within Daemonheim."); + case 190: + return newstruct cs2func_script_1022_struct(94, 16401, "Members: Promethium longsword (Tier 10)" + "
" + " 2 bars", "Members can now smith " + "" + "promethium longswords" + "" + " within Daemonheim."); + case 191: + return newstruct cs2func_script_1022_struct(95, 16709, "Members: Promethium full helm (Tier 10)" + "
" + " 2 bars", "Members can now smith " + "" + "promethium full helms" + "" + " within Daemonheim."); + case 192: + return newstruct cs2func_script_1022_struct(95, 15771, "Members: Promethium battleaxe (Tier 10)" + "
" + " 2 bars", "Members can now smith " + "" + "promethium battleaxes" + "" + " within Daemonheim."); + case 193: + return newstruct cs2func_script_1022_struct(96, 17359, "Members: Promethium kiteshield (Tier 10)" + "
" + " 3 bars", "Members can now smith " + "" + "promethium kiteshields" + "" + " within Daemonheim."); + case 194: + return newstruct cs2func_script_1022_struct(96, 16731, "Members: Promethium chainbody (Tier 10)" + "
" + " 3 bars", "Members can now smith " + "" + "promethium chainbodies" + "" + " within Daemonheim."); + case 195: + return newstruct cs2func_script_1022_struct(97, 16687, "Members: Promethium platelegs (Tier 10)" + "
" + " 3 bars", "Members can now smith " + "" + "promethium platelegs" + "" + " within Daemonheim."); + case 196: + return newstruct cs2func_script_1022_struct(97, 16665, "Members: Promethium plateskirt (Tier 10)" + "
" + " 3 bars", "Members can now smith " + "" + "promethium plateskirts" + "" + " within Daemonheim."); + case 197: + return newstruct cs2func_script_1022_struct(97, 17135, "Members: Promethium spear (Tier 10)" + "
" + " 4 bars", "Members can now smith " + "" + "promethium spears" + "" + " within Daemonheim."); + case 198: + return newstruct cs2func_script_1022_struct(98, 16423, "Members: Promethium maul (Tier 10)" + "
" + " 4 bars", "Members can now smith " + "" + "promethium mauls" + "" + " within Daemonheim."); + case 199: + return newstruct cs2func_script_1022_struct(98, 16907, "Members: Promethium 2h sword (Tier 10)" + "
" + " 4 bars", "Members can now smith " + "" + "promethium 2h swords" + "" + " within Daemonheim."); + case 200: + return newstruct cs2func_script_1022_struct(99, 17257, "Members: Promethium platebody (Tier 10)" + "
" + " 5 bars", "Members can now smith " + "" + "promethium platebodies" + "" + " within Daemonheim."); + } + break; + case 15: + SWITCH (arg1) { + case 0: + GOTO flow_554 + } + break; + flow_554: + return newstruct cs2func_script_1022_struct(99, 9795, "Skill mastery", "" + "Congratulations! You are now a master smith. Members can visit " + "" + "Thurgo" + "" + ", who lives near " + "" + "Mudskipper Point" + "" + ". He has something special that is only available to true masters of the " + "" + "Smithing" + "" + " skill!"); + } + return newstruct cs2func_script_1022_struct(0, -1, "", ""); +} diff --git a/dumps/scripts/1023.cs2 b/dumps/scripts/1023.cs2 new file mode 100644 index 0000000..20bea90 --- /dev/null +++ b/dumps/scripts/1023.cs2 @@ -0,0 +1,4603 @@ +cs2func_script_1023_struct(2,1,0) script_1023(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + string svar0; + int stack_dump0; + int stack_dump1; + int stack_dump2; + cs2func_script_1025_struct(2,1,0) structdump_3; + cs2func_script_1025_struct(2,1,0) structdump_4; + cs2func_script_1025_struct(2,1,0) structdump_5; + cs2func_script_1025_struct(2,1,0) structdump_6; + cs2func_script_1025_struct(2,1,0) structdump_7; + cs2func_script_1025_struct(2,1,0) structdump_8; + cs2func_script_1025_struct(2,1,0) structdump_9; + cs2func_script_1025_struct(2,1,0) structdump_10; + cs2func_script_1025_struct(2,1,0) structdump_11; + cs2func_script_1025_struct(2,1,0) structdump_12; + cs2func_script_1025_struct(2,1,0) structdump_13; + cs2func_script_1025_struct(2,1,0) structdump_14; + cs2func_script_1025_struct(2,1,0) structdump_15; + cs2func_script_1025_struct(2,1,0) structdump_16; + cs2func_script_1025_struct(2,1,0) structdump_17; + cs2func_script_1025_struct(2,1,0) structdump_18; + cs2func_script_1025_struct(2,1,0) structdump_19; + cs2func_script_1025_struct(2,1,0) structdump_20; + cs2func_script_1025_struct(2,1,0) structdump_21; + cs2func_script_1025_struct(2,1,0) structdump_22; + cs2func_script_1025_struct(2,1,0) structdump_23; + cs2func_script_1025_struct(2,1,0) structdump_24; + cs2func_script_1025_struct(2,1,0) structdump_25; + cs2func_script_1025_struct(2,1,0) structdump_26; + cs2func_script_1025_struct(2,1,0) structdump_27; + cs2func_script_1025_struct(2,1,0) structdump_28; + cs2func_script_1025_struct(2,1,0) structdump_29; + cs2func_script_1025_struct(2,1,0) structdump_30; + cs2func_script_1025_struct(2,1,0) structdump_31; + cs2func_script_1025_struct(2,1,0) structdump_32; + cs2func_script_1025_struct(2,1,0) structdump_33; + cs2func_script_1025_struct(2,1,0) structdump_34; + cs2func_script_1025_struct(2,1,0) structdump_35; + cs2func_script_1025_struct(2,1,0) structdump_36; + cs2func_script_1025_struct(2,1,0) structdump_37; + cs2func_script_1025_struct(2,1,0) structdump_38; + cs2func_script_1025_struct(2,1,0) structdump_39; + cs2func_script_1025_struct(2,1,0) structdump_40; + cs2func_script_1025_struct(2,1,0) structdump_41; + cs2func_script_1025_struct(2,1,0) structdump_42; + cs2func_script_1025_struct(2,1,0) structdump_43; + cs2func_script_1025_struct(2,1,0) structdump_44; + cs2func_script_1025_struct(2,1,0) structdump_45; + cs2func_script_1025_struct(2,1,0) structdump_46; + cs2func_script_1025_struct(2,1,0) structdump_47; + cs2func_script_1025_struct(2,1,0) structdump_48; + cs2func_script_1025_struct(2,1,0) structdump_49; + cs2func_script_1025_struct(2,1,0) structdump_50; + cs2func_script_1025_struct(2,1,0) structdump_51; + cs2func_script_1025_struct(2,1,0) structdump_52; + cs2func_script_1025_struct(2,1,0) structdump_53; + cs2func_script_1025_struct(2,1,0) structdump_54; + cs2func_script_1025_struct(2,1,0) structdump_55; + cs2func_script_1025_struct(2,1,0) structdump_56; + cs2func_script_1025_struct(2,1,0) structdump_57; + cs2func_script_1025_struct(2,1,0) structdump_58; + cs2func_script_1025_struct(2,1,0) structdump_59; + cs2func_script_1025_struct(2,1,0) structdump_60; + cs2func_script_1025_struct(2,1,0) structdump_61; + cs2func_script_1025_struct(2,1,0) structdump_62; + cs2func_script_1025_struct(2,1,0) structdump_63; + cs2func_script_1025_struct(2,1,0) structdump_64; + cs2func_script_1025_struct(2,1,0) structdump_65; + cs2func_script_1025_struct(2,1,0) structdump_66; + cs2func_script_1025_struct(2,1,0) structdump_67; + cs2func_script_1025_struct(2,1,0) structdump_68; + cs2func_script_1025_struct(2,1,0) structdump_69; + cs2func_script_1025_struct(2,1,0) structdump_70; + cs2func_script_1025_struct(2,1,0) structdump_71; + cs2func_script_1025_struct(2,1,0) structdump_72; + cs2func_script_1025_struct(2,1,0) structdump_73; + cs2func_script_1025_struct(2,1,0) structdump_74; + cs2func_script_1025_struct(2,1,0) structdump_75; + cs2func_script_1025_struct(2,1,0) structdump_76; + cs2func_script_1025_struct(2,1,0) structdump_77; + cs2func_script_1025_struct(2,1,0) structdump_78; + cs2func_script_1025_struct(2,1,0) structdump_79; + cs2func_script_1025_struct(2,1,0) structdump_80; + cs2func_script_1025_struct(2,1,0) structdump_81; + cs2func_script_1025_struct(2,1,0) structdump_82; + cs2func_script_1025_struct(2,1,0) structdump_83; + cs2func_script_1025_struct(2,1,0) structdump_84; + cs2func_script_1025_struct(2,1,0) structdump_85; + cs2func_script_1025_struct(2,1,0) structdump_86; + cs2func_script_1025_struct(2,1,0) structdump_87; + cs2func_script_1025_struct(2,1,0) structdump_88; + cs2func_script_1025_struct(2,1,0) structdump_89; + cs2func_script_1025_struct(2,1,0) structdump_90; + cs2func_script_1025_struct(2,1,0) structdump_91; + cs2func_script_1025_struct(2,1,0) structdump_92; + cs2func_script_1025_struct(2,1,0) structdump_93; + cs2func_script_1025_struct(2,1,0) structdump_94; + cs2func_script_1025_struct(2,1,0) structdump_95; + cs2func_script_1025_struct(2,1,0) structdump_96; + cs2func_script_1025_struct(2,1,0) structdump_97; + cs2func_script_1025_struct(2,1,0) structdump_98; + cs2func_script_1025_struct(2,1,0) structdump_99; + cs2func_script_1025_struct(2,1,0) structdump_100; + cs2func_script_1025_struct(2,1,0) structdump_101; + cs2func_script_1025_struct(2,1,0) structdump_102; + cs2func_script_1025_struct(2,1,0) structdump_103; + cs2func_script_1025_struct(2,1,0) structdump_104; + cs2func_script_1025_struct(2,1,0) structdump_105; + cs2func_script_1025_struct(2,1,0) structdump_106; + cs2func_script_1025_struct(2,1,0) structdump_107; + cs2func_script_1025_struct(2,1,0) structdump_108; + cs2func_script_1025_struct(2,1,0) structdump_109; + cs2func_script_1025_struct(2,1,0) structdump_110; + cs2func_script_1025_struct(2,1,0) structdump_111; + cs2func_script_1025_struct(2,1,0) structdump_112; + cs2func_script_1025_struct(2,1,0) structdump_113; + cs2func_script_1025_struct(2,1,0) structdump_114; + cs2func_script_1025_struct(2,1,0) structdump_115; + cs2func_script_1025_struct(2,1,0) structdump_116; + cs2func_script_1025_struct(2,1,0) structdump_117; + cs2func_script_1025_struct(2,1,0) structdump_118; + cs2func_script_1025_struct(2,1,0) structdump_119; + cs2func_script_1025_struct(2,1,0) structdump_120; + cs2func_script_1025_struct(2,1,0) structdump_121; + cs2func_script_1025_struct(2,1,0) structdump_122; + cs2func_script_1025_struct(2,1,0) structdump_123; + cs2func_script_1025_struct(2,1,0) structdump_124; + cs2func_script_1025_struct(2,1,0) structdump_125; + cs2func_script_1025_struct(2,1,0) structdump_126; + cs2func_script_1025_struct(2,1,0) structdump_127; + cs2func_script_1025_struct(2,1,0) structdump_128; + cs2func_script_1025_struct(2,1,0) structdump_129; + cs2func_script_1025_struct(2,1,0) structdump_130; + cs2func_script_1025_struct(2,1,0) structdump_131; + cs2func_script_1025_struct(2,1,0) structdump_132; + cs2func_script_1025_struct(2,1,0) structdump_133; + cs2func_script_1025_struct(2,1,0) structdump_134; + cs2func_script_1025_struct(2,1,0) structdump_135; + cs2func_script_1025_struct(2,1,0) structdump_136; + cs2func_script_1025_struct(2,1,0) structdump_137; + cs2func_script_1025_struct(2,1,0) structdump_138; + cs2func_script_1025_struct(2,1,0) structdump_139; + cs2func_script_1025_struct(2,1,0) structdump_140; + cs2func_script_1025_struct(2,1,0) structdump_141; + cs2func_script_1025_struct(2,1,0) structdump_142; + cs2func_script_1025_struct(2,1,0) structdump_143; + cs2func_script_1025_struct(2,1,0) structdump_144; + cs2func_script_1025_struct(2,1,0) structdump_145; + cs2func_script_1025_struct(2,1,0) structdump_146; + cs2func_script_1025_struct(2,1,0) structdump_147; + cs2func_script_1025_struct(2,1,0) structdump_148; + cs2func_script_1025_struct(2,1,0) structdump_149; + cs2func_script_1025_struct(2,1,0) structdump_150; + cs2func_script_1025_struct(2,1,0) structdump_151; + cs2func_script_1025_struct(2,1,0) structdump_152; + cs2func_script_1025_struct(2,1,0) structdump_153; + cs2func_script_1025_struct(2,1,0) structdump_154; + cs2func_script_1025_struct(2,1,0) structdump_155; + cs2func_script_1025_struct(2,1,0) structdump_156; + cs2func_script_1025_struct(2,1,0) structdump_157; + cs2func_script_1025_struct(2,1,0) structdump_158; + cs2func_script_1025_struct(2,1,0) structdump_159; + cs2func_script_1025_struct(2,1,0) structdump_160; + cs2func_script_1025_struct(2,1,0) structdump_161; + cs2func_script_1025_struct(2,1,0) structdump_162; + cs2func_script_1025_struct(2,1,0) structdump_163; + cs2func_script_1025_struct(2,1,0) structdump_164; + cs2func_script_1025_struct(2,1,0) structdump_165; + cs2func_script_1025_struct(2,1,0) structdump_166; + cs2func_script_1025_struct(2,1,0) structdump_167; + cs2func_script_1025_struct(2,1,0) structdump_168; + cs2func_script_1025_struct(2,1,0) structdump_169; + cs2func_script_1025_struct(2,1,0) structdump_170; + cs2func_script_1025_struct(2,1,0) structdump_171; + cs2func_script_1025_struct(2,1,0) structdump_172; + cs2func_script_1025_struct(2,1,0) structdump_173; + cs2func_script_1025_struct(2,1,0) structdump_174; + cs2func_script_1025_struct(2,1,0) structdump_175; + cs2func_script_1025_struct(2,1,0) structdump_176; + cs2func_script_1025_struct(2,1,0) structdump_177; + cs2func_script_1025_struct(2,1,0) structdump_178; + cs2func_script_1025_struct(2,1,0) structdump_179; + cs2func_script_1025_struct(2,1,0) structdump_180; + cs2func_script_1025_struct(2,1,0) structdump_181; + cs2func_script_1025_struct(2,1,0) structdump_182; + cs2func_script_1025_struct(2,1,0) structdump_183; + cs2func_script_1025_struct(2,1,0) structdump_184; + cs2func_script_1025_struct(2,1,0) structdump_185; + cs2func_script_1025_struct(2,1,0) structdump_186; + cs2func_script_1025_struct(2,1,0) structdump_187; + cs2func_script_1025_struct(2,1,0) structdump_188; + cs2func_script_1025_struct(2,1,0) structdump_189; + cs2func_script_1025_struct(2,1,0) structdump_190; + cs2func_script_1025_struct(2,1,0) structdump_191; + cs2func_script_1025_struct(2,1,0) structdump_192; + cs2func_script_1025_struct(2,1,0) structdump_193; + cs2func_script_1025_struct(2,1,0) structdump_194; + cs2func_script_1025_struct(2,1,0) structdump_195; + cs2func_script_1025_struct(2,1,0) structdump_196; + cs2func_script_1025_struct(2,1,0) structdump_197; + cs2func_script_1025_struct(2,1,0) structdump_198; + cs2func_script_1025_struct(2,1,0) structdump_199; + cs2func_script_1025_struct(2,1,0) structdump_200; + cs2func_script_1025_struct(2,1,0) structdump_201; + cs2func_script_1025_struct(2,1,0) structdump_202; + cs2func_script_1025_struct(2,1,0) structdump_203; + cs2func_script_1025_struct(2,1,0) structdump_204; + cs2func_script_1025_struct(2,1,0) structdump_205; + cs2func_script_1025_struct(2,1,0) structdump_206; + cs2func_script_1025_struct(2,1,0) structdump_207; + cs2func_script_1025_struct(2,1,0) structdump_208; + cs2func_script_1025_struct(2,1,0) structdump_209; + cs2func_script_1025_struct(2,1,0) structdump_210; + cs2func_script_1025_struct(2,1,0) structdump_211; + cs2func_script_1025_struct(2,1,0) structdump_212; + cs2func_script_1025_struct(2,1,0) structdump_213; + cs2func_script_1025_struct(2,1,0) structdump_214; + cs2func_script_1025_struct(2,1,0) structdump_215; + cs2func_script_1025_struct(2,1,0) structdump_216; + cs2func_script_1025_struct(2,1,0) structdump_217; + cs2func_script_1025_struct(2,1,0) structdump_218; + cs2func_script_1025_struct(2,1,0) structdump_219; + cs2func_script_1025_struct(2,1,0) structdump_220; + cs2func_script_1025_struct(2,1,0) structdump_221; + cs2func_script_1025_struct(2,1,0) structdump_222; + cs2func_script_1025_struct(2,1,0) structdump_223; + cs2func_script_1025_struct(2,1,0) structdump_224; + cs2func_script_1025_struct(2,1,0) structdump_225; + cs2func_script_1025_struct(2,1,0) structdump_226; + cs2func_script_1025_struct(2,1,0) structdump_227; + cs2func_script_1025_struct(2,1,0) structdump_228; + cs2func_script_1025_struct(2,1,0) structdump_229; + cs2func_script_1025_struct(2,1,0) structdump_230; + cs2func_script_1025_struct(2,1,0) structdump_231; + cs2func_script_1025_struct(2,1,0) structdump_232; + cs2func_script_1025_struct(2,1,0) structdump_233; + cs2func_script_1025_struct(2,1,0) structdump_234; + cs2func_script_1025_struct(2,1,0) structdump_235; + cs2func_script_1025_struct(2,1,0) structdump_236; + cs2func_script_1025_struct(2,1,0) structdump_237; + cs2func_script_1025_struct(2,1,0) structdump_238; + cs2func_script_1025_struct(2,1,0) structdump_239; + cs2func_script_1025_struct(2,1,0) structdump_240; + cs2func_script_1025_struct(2,1,0) structdump_241; + cs2func_script_1025_struct(2,1,0) structdump_242; + cs2func_script_1025_struct(2,1,0) structdump_243; + cs2func_script_1025_struct(2,1,0) structdump_244; + cs2func_script_1025_struct(2,1,0) structdump_245; + cs2func_script_1025_struct(2,1,0) structdump_246; + cs2func_script_1025_struct(2,1,0) structdump_247; + cs2func_script_1025_struct(2,1,0) structdump_248; + cs2func_script_1025_struct(2,1,0) structdump_249; + cs2func_script_1025_struct(2,1,0) structdump_250; + cs2func_script_1025_struct(2,1,0) structdump_251; + cs2func_script_1025_struct(2,1,0) structdump_252; + cs2func_script_1025_struct(2,1,0) structdump_253; + cs2func_script_1025_struct(2,1,0) structdump_254; + cs2func_script_1025_struct(2,1,0) structdump_255; + cs2func_script_1025_struct(2,1,0) structdump_256; + cs2func_script_1025_struct(2,1,0) structdump_257; + cs2func_script_1025_struct(2,1,0) structdump_258; + cs2func_script_1025_struct(2,1,0) structdump_259; + cs2func_script_1025_struct(2,1,0) structdump_260; + cs2func_script_1025_struct(2,1,0) structdump_261; + cs2func_script_1025_struct(2,1,0) structdump_262; + cs2func_script_1025_struct(2,1,0) structdump_263; + cs2func_script_1025_struct(2,1,0) structdump_264; + cs2func_script_1025_struct(2,1,0) structdump_265; + cs2func_script_1025_struct(2,1,0) structdump_266; + cs2func_script_1025_struct(2,1,0) structdump_267; + cs2func_script_1025_struct(2,1,0) structdump_268; + cs2func_script_1025_struct(2,1,0) structdump_269; + cs2func_script_1025_struct(2,1,0) structdump_270; + cs2func_script_1025_struct(2,1,0) structdump_271; + cs2func_script_1025_struct(2,1,0) structdump_272; + cs2func_script_1025_struct(2,1,0) structdump_273; + cs2func_script_1025_struct(2,1,0) structdump_274; + cs2func_script_1025_struct(2,1,0) structdump_275; + cs2func_script_1025_struct(2,1,0) structdump_276; + cs2func_script_2042_struct(2,1,0) structdump_277; + cs2func_script_1025_struct(2,1,0) structdump_278; + cs2func_script_1025_struct(2,1,0) structdump_279; + cs2func_script_1025_struct(2,1,0) structdump_280; + cs2func_script_1025_struct(2,1,0) structdump_281; + cs2func_script_1025_struct(2,1,0) structdump_282; + cs2func_script_1025_struct(2,1,0) structdump_283; + cs2func_script_1025_struct(2,1,0) structdump_284; + cs2func_script_1025_struct(2,1,0) structdump_285; + cs2func_script_1025_struct(2,1,0) structdump_286; + cs2func_script_1025_struct(2,1,0) structdump_287; + cs2func_script_1025_struct(2,1,0) structdump_288; + cs2func_script_1025_struct(2,1,0) structdump_289; + cs2func_script_1025_struct(2,1,0) structdump_290; + cs2func_script_1025_struct(2,1,0) structdump_291; + cs2func_script_1025_struct(2,1,0) structdump_292; + cs2func_script_1025_struct(2,1,0) structdump_293; + cs2func_script_1025_struct(2,1,0) structdump_294; + cs2func_script_1025_struct(2,1,0) structdump_295; + cs2func_script_1025_struct(2,1,0) structdump_296; + cs2func_script_1025_struct(2,1,0) structdump_297; + cs2func_script_1025_struct(2,1,0) structdump_298; + cs2func_script_1025_struct(2,1,0) structdump_299; + cs2func_script_1025_struct(2,1,0) structdump_300; + cs2func_script_1025_struct(2,1,0) structdump_301; + cs2func_script_1025_struct(2,1,0) structdump_302; + cs2func_script_1025_struct(2,1,0) structdump_303; + cs2func_script_1025_struct(2,1,0) structdump_304; + cs2func_script_1025_struct(2,1,0) structdump_305; + cs2func_script_1025_struct(2,1,0) structdump_306; + cs2func_script_1025_struct(2,1,0) structdump_307; + cs2func_script_1025_struct(2,1,0) structdump_308; + cs2func_script_1025_struct(2,1,0) structdump_309; + cs2func_script_1025_struct(2,1,0) structdump_310; + cs2func_script_1025_struct(2,1,0) structdump_311; + cs2func_script_1025_struct(2,1,0) structdump_312; + cs2func_script_1025_struct(2,1,0) structdump_313; + cs2func_script_1025_struct(2,1,0) structdump_314; + cs2func_script_1025_struct(2,1,0) structdump_315; + cs2func_script_1025_struct(2,1,0) structdump_316; + cs2func_script_1025_struct(2,1,0) structdump_317; + cs2func_script_1025_struct(2,1,0) structdump_318; + cs2func_script_1025_struct(2,1,0) structdump_319; + cs2func_script_1025_struct(2,1,0) structdump_320; + cs2func_script_1025_struct(2,1,0) structdump_321; + cs2func_script_1025_struct(2,1,0) structdump_322; + cs2func_script_1025_struct(2,1,0) structdump_323; + cs2func_script_1025_struct(2,1,0) structdump_324; + cs2func_script_1025_struct(2,1,0) structdump_325; + cs2func_script_1025_struct(2,1,0) structdump_326; + cs2func_script_1025_struct(2,1,0) structdump_327; + cs2func_script_1025_struct(2,1,0) structdump_328; + cs2func_script_1025_struct(2,1,0) structdump_329; + cs2func_script_1025_struct(2,1,0) structdump_330; + cs2func_script_1025_struct(2,1,0) structdump_331; + cs2func_script_1025_struct(2,1,0) structdump_332; + cs2func_script_1025_struct(2,1,0) structdump_333; + cs2func_script_1025_struct(2,1,0) structdump_334; + cs2func_script_1025_struct(2,1,0) structdump_335; + cs2func_script_1025_struct(2,1,0) structdump_336; + cs2func_script_1025_struct(2,1,0) structdump_337; + cs2func_script_1025_struct(2,1,0) structdump_338; + cs2func_script_1025_struct(2,1,0) structdump_339; + cs2func_script_1025_struct(2,1,0) structdump_340; + cs2func_script_1025_struct(2,1,0) structdump_341; + cs2func_script_1025_struct(2,1,0) structdump_342; + cs2func_script_1025_struct(2,1,0) structdump_343; + cs2func_script_1025_struct(2,1,0) structdump_344; + cs2func_script_1025_struct(2,1,0) structdump_345; + cs2func_script_1025_struct(2,1,0) structdump_346; + cs2func_script_1025_struct(2,1,0) structdump_347; + cs2func_script_1025_struct(2,1,0) structdump_348; + cs2func_script_1025_struct(2,1,0) structdump_349; + cs2func_script_1025_struct(2,1,0) structdump_350; + cs2func_script_1025_struct(2,1,0) structdump_351; + cs2func_script_1025_struct(2,1,0) structdump_352; + cs2func_script_1025_struct(2,1,0) structdump_353; + cs2func_script_1025_struct(2,1,0) structdump_354; + cs2func_script_1025_struct(2,1,0) structdump_355; + cs2func_script_1025_struct(2,1,0) structdump_356; + cs2func_script_1025_struct(2,1,0) structdump_357; + cs2func_script_1025_struct(2,1,0) structdump_358; + cs2func_script_1025_struct(2,1,0) structdump_359; + cs2func_script_1025_struct(2,1,0) structdump_360; + cs2func_script_1025_struct(2,1,0) structdump_361; + cs2func_script_1025_struct(2,1,0) structdump_362; + cs2func_script_1025_struct(2,1,0) structdump_363; + cs2func_script_1025_struct(2,1,0) structdump_364; + cs2func_script_1025_struct(2,1,0) structdump_365; + cs2func_script_1025_struct(2,1,0) structdump_366; + cs2func_script_1025_struct(2,1,0) structdump_367; + cs2func_script_1025_struct(2,1,0) structdump_368; + cs2func_script_1025_struct(2,1,0) structdump_369; + cs2func_script_1025_struct(2,1,0) structdump_370; + cs2func_script_1025_struct(2,1,0) structdump_371; + cs2func_script_1025_struct(2,1,0) structdump_372; + cs2func_script_1025_struct(2,1,0) structdump_373; + cs2func_script_1025_struct(2,1,0) structdump_374; + cs2func_script_1025_struct(2,1,0) structdump_375; + cs2func_script_1025_struct(2,1,0) structdump_376; + cs2func_script_1025_struct(2,1,0) structdump_377; + cs2func_script_1025_struct(2,1,0) structdump_378; + cs2func_script_1025_struct(2,1,0) structdump_379; + cs2func_script_1025_struct(2,1,0) structdump_380; + cs2func_script_1025_struct(2,1,0) structdump_381; + cs2func_script_1025_struct(2,1,0) structdump_382; + cs2func_script_1025_struct(2,1,0) structdump_383; + cs2func_script_1025_struct(2,1,0) structdump_384; + cs2func_script_1025_struct(2,1,0) structdump_385; + cs2func_script_1025_struct(2,1,0) structdump_386; + cs2func_script_1025_struct(2,1,0) structdump_387; + cs2func_script_1025_struct(2,1,0) structdump_388; + cs2func_script_1025_struct(2,1,0) structdump_389; + cs2func_script_1025_struct(2,1,0) structdump_390; + cs2func_script_1025_struct(2,1,0) structdump_391; + cs2func_script_1025_struct(2,1,0) structdump_392; + cs2func_script_1025_struct(2,1,0) structdump_393; + cs2func_script_1025_struct(2,1,0) structdump_394; + cs2func_script_1025_struct(2,1,0) structdump_395; + cs2func_script_1025_struct(2,1,0) structdump_396; + ivar2 = getSkillActualLvl(arg0); + svar0 = "null"; + ivar3 = -1; + ivar4 = 0; + switch (arg1) { + case 0: + if ((arg0 == 14) && (getSkillActualLvl(arg0) == 10)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_3 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_3.intpart_1; + ivar3 = structdump_3.intpart_0; + svar0 = structdump_3.stringpart_0; + } + if (standart_config_122 == 7) { + ivar4 = 0; + } + break; + case 1: + if (((boolean)arg0) && (getSkillActualLvl(arg0) == 15)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_4 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_4.intpart_1; + ivar3 = structdump_4.intpart_0; + svar0 = structdump_4.stringpart_0; + } + if ((arg0 == 5) && (getSkillActualLvl(arg0) == 25)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_5 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_5.intpart_1; + ivar3 = structdump_5.intpart_0; + svar0 = structdump_5.stringpart_0; + } + if (bitconfig_3550 == 11) { + ivar4 = 0; + } + break; + case 2: + if (((boolean)arg0) && (getSkillActualLvl(arg0) == 30)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_6 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_6.intpart_1; + ivar3 = structdump_6.intpart_0; + svar0 = structdump_6.stringpart_0; + } + if ((arg0 == 14) && (getSkillActualLvl(arg0) == 40)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_7 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_7.intpart_1; + ivar3 = structdump_7.intpart_0; + svar0 = structdump_7.stringpart_0; + } + if ((arg0 == 13) && (getSkillActualLvl(arg0) == 50)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_8 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_8.intpart_1; + ivar3 = structdump_8.intpart_0; + svar0 = structdump_8.stringpart_0; + } + if (bitconfig_299 > 109) { + ivar4 = 0; + } + break; + case 3: + if ((arg0 == 7) && (getSkillActualLvl(arg0) == 30)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_9 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_9.intpart_1; + ivar3 = structdump_9.intpart_0; + svar0 = structdump_9.stringpart_0; + } + if ((arg0 == 9) && (getSkillActualLvl(arg0) == 5)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_10 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_10.intpart_1; + ivar3 = structdump_10.intpart_0; + svar0 = structdump_10.stringpart_0; + } + if ((arg0 == 4) && (getSkillActualLvl(arg0) == 30)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_11 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_11.intpart_1; + ivar3 = structdump_11.intpart_0; + svar0 = structdump_11.stringpart_0; + } + if (standart_config_293 == 65) { + ivar4 = 0; + } + break; + case 4: + if ((arg0 == 16) && (getSkillActualLvl(arg0) == 42)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_12 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_12.intpart_1; + ivar3 = structdump_12.intpart_0; + svar0 = structdump_12.stringpart_0; + } + if ((arg0 == 12) && (getSkillActualLvl(arg0) == 45)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_13 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_13.intpart_1; + ivar3 = structdump_13.intpart_0; + svar0 = structdump_13.stringpart_0; + } + if ((arg0 == 4) && (getSkillActualLvl(arg0) == 40)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_14 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_14.intpart_1; + ivar3 = structdump_14.intpart_0; + svar0 = structdump_14.stringpart_0; + } + if ((arg0 == 13) && (getSkillActualLvl(arg0) == 50)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_15 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_15.intpart_1; + ivar3 = structdump_15.intpart_0; + svar0 = structdump_15.stringpart_0; + } + if (standart_config_655 > 130) { + ivar4 = 0; + } + break; + case 5: + if ((arg0 == 12) && (getSkillActualLvl(arg0) == 20)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_16 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_16.intpart_1; + ivar3 = structdump_16.intpart_0; + svar0 = structdump_16.stringpart_0; + } + if ((arg0 == 17) && (getSkillActualLvl(arg0) == 25)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_17 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_17.intpart_1; + ivar3 = structdump_17.intpart_0; + svar0 = structdump_17.stringpart_0; + } + if (standart_config_399 > 6) { + ivar4 = 0; + } + break; + case 6: + if ((arg0 == 16) && (getSkillActualLvl(arg0) == 26)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_18 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_18.intpart_1; + ivar3 = structdump_18.intpart_0; + svar0 = structdump_18.stringpart_0; + } + if ((arg0 == 22) && (getSkillActualLvl(arg0) == 5)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_19 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_19.intpart_1; + ivar3 = structdump_19.intpart_0; + svar0 = structdump_19.stringpart_0; + } + if ((arg0 == 12) && (getSkillActualLvl(arg0) == 32)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_20 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_20.intpart_1; + ivar3 = structdump_20.intpart_0; + svar0 = structdump_20.stringpart_0; + } + if ((arg0 == 6) && (getSkillActualLvl(arg0) == 33)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_21 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_21.intpart_1; + ivar3 = structdump_21.intpart_0; + svar0 = structdump_21.stringpart_0; + } + if ((arg0 == 14) && (getSkillActualLvl(arg0) == 20)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_22 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_22.intpart_1; + ivar3 = structdump_22.intpart_0; + svar0 = structdump_22.stringpart_0; + } + if ((arg0 == 2) && (getSkillActualLvl(arg0) == 40)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_23 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_23.intpart_1; + ivar3 = structdump_23.intpart_0; + svar0 = structdump_23.stringpart_0; + } + if ((arg0 == 17) && (getSkillActualLvl(arg0) == 22)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_24 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_24.intpart_1; + ivar3 = structdump_24.intpart_0; + svar0 = structdump_24.stringpart_0; + } + if (bitconfig_2573 == 320) { + ivar4 = 0; + } + break; + case 7: + if ((arg0 == 11) && (getSkillActualLvl(arg0) == 50)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_25 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_25.intpart_1; + ivar3 = structdump_25.intpart_0; + svar0 = structdump_25.stringpart_0; + } + if ((arg0 == 6) && (getSkillActualLvl(arg0) == 50)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_26 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_26.intpart_1; + ivar3 = structdump_26.intpart_0; + svar0 = structdump_26.stringpart_0; + } + if ((arg0 == 18) && (getSkillActualLvl(arg0) == 10)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_27 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_27.intpart_1; + ivar3 = structdump_27.intpart_0; + svar0 = structdump_27.stringpart_0; + } + if ((arg0 == 17) && (getSkillActualLvl(arg0) == 53)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_28 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_28.intpart_1; + ivar3 = structdump_28.intpart_0; + svar0 = structdump_28.stringpart_0; + } + if (bitconfig_358 == 15) { + ivar4 = 0; + } + break; + case 8: + if ((arg0 == 9) && (getSkillActualLvl(arg0) == 50)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_29 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_29.intpart_1; + ivar3 = structdump_29.intpart_0; + svar0 = structdump_29.stringpart_0; + } + if ((arg0 == 20) && (getSkillActualLvl(arg0) == 50)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_30 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_30.intpart_1; + ivar3 = structdump_30.intpart_0; + svar0 = structdump_30.stringpart_0; + } + if ((arg0 == 13) && (getSkillActualLvl(arg0) == 65)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_31 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_31.intpart_1; + ivar3 = structdump_31.intpart_0; + svar0 = structdump_31.stringpart_0; + } + if (bitconfig_1465 == 80) { + ivar4 = 0; + } + break; + case 9: + if ((arg0 == 15) && (getSkillActualLvl(arg0) == 10)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_32 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_32.intpart_1; + ivar3 = structdump_32.intpart_0; + svar0 = structdump_32.stringpart_0; + } + if ((arg0 == 16) && (getSkillActualLvl(arg0) == 10)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_33 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_33.intpart_1; + ivar3 = structdump_33.intpart_0; + svar0 = structdump_33.stringpart_0; + } + if ((arg0 == 17) && (getSkillActualLvl(arg0) == 25)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_34 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_34.intpart_1; + ivar3 = structdump_34.intpart_0; + svar0 = structdump_34.stringpart_0; + } + if (standart_config_131 == 9) { + ivar4 = 0; + } + break; + case 10: + if ((arg0 == 15) && (getSkillActualLvl(arg0) == 31)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_35 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_35.intpart_1; + ivar3 = structdump_35.intpart_0; + svar0 = structdump_35.stringpart_0; + } + if (standart_config_335 == 110) { + ivar4 = 0; + } + break; + case 11: + if ((arg0 == 21) && (getSkillActualLvl(arg0) == 27)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_36 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_36.intpart_1; + ivar3 = structdump_36.intpart_0; + svar0 = structdump_36.stringpart_0; + } + if (bitconfig_2780 == 40) { + ivar4 = 0; + } + break; + case 12: + if ((arg0 == 12) && (getSkillActualLvl(arg0) == 20)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_37 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_37.intpart_1; + ivar3 = structdump_37.intpart_0; + svar0 = structdump_37.stringpart_0; + } + if ((arg0 == 14) && (getSkillActualLvl(arg0) == 20)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_38 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_38.intpart_1; + ivar3 = structdump_38.intpart_0; + svar0 = structdump_38.stringpart_0; + } + if ((arg0 == 13) && (getSkillActualLvl(arg0) == 20)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_39 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_39.intpart_1; + ivar3 = structdump_39.intpart_0; + svar0 = structdump_39.stringpart_0; + } + if (isBitFlagged(standart_config_299, 20)) { + ivar4 = 0; + } + break; + case 13: + if ((arg0 == 12) && (getSkillActualLvl(arg0) == 50)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_40 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_40.intpart_1; + ivar3 = structdump_40.intpart_0; + svar0 = structdump_40.stringpart_0; + } + if ((arg0 == 11) && (getSkillActualLvl(arg0) == 45)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_41 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_41.intpart_1; + ivar3 = structdump_41.intpart_0; + svar0 = structdump_41.stringpart_0; + } + if ((arg0 == 6) && (getSkillActualLvl(arg0) == 39)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_42 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_42.intpart_1; + ivar3 = structdump_42.intpart_0; + svar0 = structdump_42.stringpart_0; + } + if ((arg0 == 5) && (getSkillActualLvl(arg0) == 43)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_43 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_43.intpart_1; + ivar3 = structdump_43.intpart_0; + svar0 = structdump_43.stringpart_0; + } + if (bitconfig_1560 > 69) { + ivar4 = 0; + } + break; + case 14: + if ((arg0 == 19) && (getSkillActualLvl(arg0) == 49)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_44 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_44.intpart_1; + ivar3 = structdump_44.intpart_0; + svar0 = structdump_44.stringpart_0; + } + if ((arg0 == 15) && (getSkillActualLvl(arg0) == 57)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_45 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_45.intpart_1; + ivar3 = structdump_45.intpart_0; + svar0 = structdump_45.stringpart_0; + } + if ((arg0 == 17) && (getSkillActualLvl(arg0) == 40)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_46 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_46.intpart_1; + ivar3 = structdump_46.intpart_0; + svar0 = structdump_46.stringpart_0; + } + if (bitconfig_2326 > 80) { + ivar4 = 0; + } + break; + case 15: + if ((arg0 == 12) && (getSkillActualLvl(arg0) == 40)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_47 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_47.intpart_1; + ivar3 = structdump_47.intpart_0; + svar0 = structdump_47.stringpart_0; + } + if ((arg0 == 6) && (getSkillActualLvl(arg0) == 59)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_48 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_48.intpart_1; + ivar3 = structdump_48.intpart_0; + svar0 = structdump_48.stringpart_0; + } + if ((arg0 == 14) && (getSkillActualLvl(arg0) == 40)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_49 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_49.intpart_1; + ivar3 = structdump_49.intpart_0; + svar0 = structdump_49.stringpart_0; + } + if ((arg0 == 13) && (getSkillActualLvl(arg0) == 40)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_50 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_50.intpart_1; + ivar3 = structdump_50.intpart_0; + svar0 = structdump_50.stringpart_0; + } + if (standart_config_148 == 11) { + ivar4 = 0; + } + break; + case 16: + if ((arg0 == 10) && (getSkillActualLvl(arg0) == 10)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_51 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_51.intpart_1; + ivar3 = structdump_51.intpart_0; + svar0 = structdump_51.stringpart_0; + } + if (standart_config_11 == 5) { + ivar4 = 0; + } + break; + case 17: + if ((arg0 == 7) && (getSkillActualLvl(arg0) == 22)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_52 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_52.intpart_1; + ivar3 = structdump_52.intpart_0; + svar0 = structdump_52.stringpart_0; + } + if ((arg0 == 19) && (getSkillActualLvl(arg0) == 17)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_53 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_53.intpart_1; + ivar3 = structdump_53.intpart_0; + svar0 = structdump_53.stringpart_0; + } + if (bitconfig_822 >= 140) { + ivar4 = 0; + } + break; + case 18: + if ((arg0 == 12) && (getSkillActualLvl(arg0) == 40)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_54 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_54.intpart_1; + ivar3 = structdump_54.intpart_0; + svar0 = structdump_54.stringpart_0; + } + if ((arg0 == 9) && (getSkillActualLvl(arg0) == 25)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_55 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_55.intpart_1; + ivar3 = structdump_55.intpart_0; + svar0 = structdump_55.stringpart_0; + } + if ((arg0 == 8) && (getSkillActualLvl(arg0) == 40)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_56 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_56.intpart_1; + ivar3 = structdump_56.intpart_0; + svar0 = structdump_56.stringpart_0; + } + if (standart_config_347 > 9) { + ivar4 = 0; + } + break; + case 19: + if ((arg0 == 19) && (getSkillActualLvl(arg0) == 25)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_57 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_57.intpart_1; + ivar3 = structdump_57.intpart_0; + svar0 = structdump_57.stringpart_0; + } + if (bitconfig_961 == 60) { + ivar4 = 0; + } + break; + case 20: + if ((arg0 == 16) && (getSkillActualLvl(arg0) == 25)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_58 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_58.intpart_1; + ivar3 = structdump_58.intpart_0; + svar0 = structdump_58.stringpart_0; + } + if ((arg0 == 7) && (getSkillActualLvl(arg0) == 20)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_59 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_59.intpart_1; + ivar3 = structdump_59.intpart_0; + svar0 = structdump_59.stringpart_0; + } + if (bitconfig_217 > 7) { + ivar4 = 0; + } + break; + case 21: + if ((arg0 == 12) && (getSkillActualLvl(arg0) == 12)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_60 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_60.intpart_1; + ivar3 = structdump_60.intpart_0; + svar0 = structdump_60.stringpart_0; + } + if ((arg0 == 11) && (getSkillActualLvl(arg0) == 16)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_61 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_61.intpart_1; + ivar3 = structdump_61.intpart_0; + svar0 = structdump_61.stringpart_0; + } + if ((arg0 == 6) && (getSkillActualLvl(arg0) == 33)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_62 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_62.intpart_1; + ivar3 = structdump_62.intpart_0; + svar0 = structdump_62.stringpart_0; + } + if ((arg0 == 17) && (getSkillActualLvl(arg0) == 14)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_63 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_63.intpart_1; + ivar3 = structdump_63.intpart_0; + svar0 = structdump_63.stringpart_0; + } + if (bitconfig_571 > 49) { + ivar4 = 0; + } + break; + case 22: + if ((arg0 == 12) && (getSkillActualLvl(arg0) == 20)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_64 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_64.intpart_1; + ivar3 = structdump_64.intpart_0; + svar0 = structdump_64.stringpart_0; + } + if ((arg0 == 17) && (getSkillActualLvl(arg0) == 25)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_65 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_65.intpart_1; + ivar3 = structdump_65.intpart_0; + svar0 = structdump_65.stringpart_0; + } + if (bitconfig_346 > 9) { + ivar4 = 0; + } + break; + case 23: + if ((arg0 == 16) && (getSkillActualLvl(arg0) == 25)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_66 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_66.intpart_1; + ivar3 = structdump_66.intpart_0; + svar0 = structdump_66.stringpart_0; + } + if (standart_config_150 >= 160) { + ivar4 = 0; + } + break; + case 24: + if ((arg0 == 12) && (getSkillActualLvl(arg0) == 49)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_67 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_67.intpart_1; + ivar3 = structdump_67.intpart_0; + svar0 = structdump_67.stringpart_0; + } + if ((arg0 == 17) && (getSkillActualLvl(arg0) == 17)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_68 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_68.intpart_1; + ivar3 = structdump_68.intpart_0; + svar0 = structdump_68.stringpart_0; + } + if (bitconfig_1527 > 159) { + ivar4 = 0; + } + break; + case 25: + if ((arg0 == 16) && (getSkillActualLvl(arg0) == 15)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_69 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_69.intpart_1; + ivar3 = structdump_69.intpart_0; + svar0 = structdump_69.stringpart_0; + } + if ((arg0 == 12) && (getSkillActualLvl(arg0) == 35)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_70 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_70.intpart_1; + ivar3 = structdump_70.intpart_0; + svar0 = structdump_70.stringpart_0; + } + if (standart_config_382 == 11) { + ivar4 = 0; + } + break; + case 26: + if ((arg0 == 7) && (getSkillActualLvl(arg0) == 53)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_71 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_71.intpart_1; + ivar3 = structdump_71.intpart_0; + svar0 = structdump_71.stringpart_0; + } + if ((arg0 == 10) && (getSkillActualLvl(arg0) == 53)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_72 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_72.intpart_1; + ivar3 = structdump_72.intpart_0; + svar0 = structdump_72.stringpart_0; + } + if ((arg0 == 15) && (getSkillActualLvl(arg0) == 25)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_73 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_73.intpart_1; + ivar3 = structdump_73.intpart_0; + svar0 = structdump_73.stringpart_0; + } + if ((arg0 == 14) && (getSkillActualLvl(arg0) == 50)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_74 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_74.intpart_1; + ivar3 = structdump_74.intpart_0; + svar0 = structdump_74.stringpart_0; + } + if (standart_config_188 == 15) { + ivar4 = 0; + } + break; + case 27: + if ((arg0 == 16) && (getSkillActualLvl(arg0) == 35)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_75 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_75.intpart_1; + ivar3 = structdump_75.intpart_0; + svar0 = structdump_75.stringpart_0; + } + if (bitconfig_34 > 9) { + ivar4 = 0; + } + break; + case 28: + if ((arg0 == 12) && (getSkillActualLvl(arg0) == 25)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_76 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_76.intpart_1; + ivar3 = structdump_76.intpart_0; + svar0 = structdump_76.stringpart_0; + } + if ((arg0 == 6) && (getSkillActualLvl(arg0) == 7)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_77 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_77.intpart_1; + ivar3 = structdump_77.intpart_0; + svar0 = structdump_77.stringpart_0; + } + if ((arg0 == 14) && (getSkillActualLvl(arg0) == 15)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_78 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_78.intpart_1; + ivar3 = structdump_78.intpart_0; + svar0 = structdump_78.stringpart_0; + } + if (bitconfig_1990 > 420) { + ivar4 = 0; + } + break; + case 29: + if ((arg0 == 15) && (getSkillActualLvl(arg0) == 3)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_79 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_79.intpart_1; + ivar3 = structdump_79.intpart_0; + svar0 = structdump_79.stringpart_0; + } + if (standart_config_175 > 11) { + ivar4 = 0; + } + break; + case 30: + if ((arg0 == 16) && (getSkillActualLvl(arg0) == 50)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_80 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_80.intpart_1; + ivar3 = structdump_80.intpart_0; + svar0 = structdump_80.stringpart_0; + } + if ((arg0 == 12) && (getSkillActualLvl(arg0) == 50)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_81 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_81.intpart_1; + ivar3 = structdump_81.intpart_0; + svar0 = structdump_81.stringpart_0; + } + if ((arg0 == 15) && (getSkillActualLvl(arg0) == 45)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_82 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_82.intpart_1; + ivar3 = structdump_82.intpart_0; + svar0 = structdump_82.stringpart_0; + } + if ((arg0 == 6) && (getSkillActualLvl(arg0) == 56)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_83 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_83.intpart_1; + ivar3 = structdump_83.intpart_0; + svar0 = structdump_83.stringpart_0; + } + if ((arg0 == 14) && (getSkillActualLvl(arg0) == 52)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_84 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_84.intpart_1; + ivar3 = structdump_84.intpart_0; + svar0 = structdump_84.stringpart_0; + } + if ((arg0 == 5) && (getSkillActualLvl(arg0) == 42)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_85 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_85.intpart_1; + ivar3 = structdump_85.intpart_0; + svar0 = structdump_85.stringpart_0; + } + if ((arg0 == 13) && (getSkillActualLvl(arg0) == 50)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_86 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_86.intpart_1; + ivar3 = structdump_86.intpart_0; + svar0 = structdump_86.stringpart_0; + } + if ((arg0 == 2) && (getSkillActualLvl(arg0) == 50)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_87 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_87.intpart_1; + ivar3 = structdump_87.intpart_0; + svar0 = structdump_87.stringpart_0; + } + if ((arg0 == 17) && (getSkillActualLvl(arg0) == 50)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_88 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_88.intpart_1; + ivar3 = structdump_88.intpart_0; + svar0 = structdump_88.stringpart_0; + } + if ((arg0 == 8) && (getSkillActualLvl(arg0) == 50)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_89 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_89.intpart_1; + ivar3 = structdump_89.intpart_0; + svar0 = structdump_89.stringpart_0; + } + if (standart_config_139 == 75) { + ivar4 = 0; + } + break; + case 31: + if ((arg0 == 12) && (getSkillActualLvl(arg0) == 31)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_90 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_90.intpart_1; + ivar3 = structdump_90.intpart_0; + svar0 = structdump_90.stringpart_0; + } + if ((arg0 == 8) && (getSkillActualLvl(arg0) == 36)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_91 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_91.intpart_1; + ivar3 = structdump_91.intpart_0; + svar0 = structdump_91.stringpart_0; + } + if (standart_config_147 == 6) { + ivar4 = 0; + } + break; + case 32: + if ((arg0 == 16) && (getSkillActualLvl(arg0) == 13)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_92 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_92.intpart_1; + ivar3 = structdump_92.intpart_0; + svar0 = structdump_92.stringpart_0; + } + if ((arg0 == 14) && (getSkillActualLvl(arg0) == 17)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_93 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_93.intpart_1; + ivar3 = structdump_93.intpart_0; + svar0 = structdump_93.stringpart_0; + } + if ((arg0 == 17) && (getSkillActualLvl(arg0) == 13)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_94 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_94.intpart_1; + ivar3 = structdump_94.intpart_0; + svar0 = structdump_94.stringpart_0; + } + if (bitconfig_532 > 10) { + ivar4 = 0; + } + break; + case 33: + if ((arg0 == 12) && (getSkillActualLvl(arg0) == 61)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_95 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_95.intpart_1; + ivar3 = structdump_95.intpart_0; + svar0 = structdump_95.stringpart_0; + } + if (((boolean)arg0) && (getSkillActualLvl(arg0) == 40)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_96 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_96.intpart_1; + ivar3 = structdump_96.intpart_0; + svar0 = structdump_96.stringpart_0; + } + if ((arg0 == 11) && (getSkillActualLvl(arg0) == 49)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_97 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_97.intpart_1; + ivar3 = structdump_97.intpart_0; + svar0 = structdump_97.stringpart_0; + } + if ((arg0 == 15) && (getSkillActualLvl(arg0) == 5)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_98 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_98.intpart_1; + ivar3 = structdump_98.intpart_0; + svar0 = structdump_98.stringpart_0; + } + if ((arg0 == 6) && (getSkillActualLvl(arg0) == 65)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_99 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_99.intpart_1; + ivar3 = structdump_99.intpart_0; + svar0 = structdump_99.stringpart_0; + } + if ((arg0 == 14) && (getSkillActualLvl(arg0) == 60)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_100 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_100.intpart_1; + ivar3 = structdump_100.intpart_0; + svar0 = structdump_100.stringpart_0; + } + if ((arg0 == 8) && (getSkillActualLvl(arg0) == 55)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_101 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_101.intpart_1; + ivar3 = structdump_101.intpart_0; + svar0 = structdump_101.stringpart_0; + } + if (bitconfig_2448 == 190) { + ivar4 = 0; + } + break; + case 34: + if ((arg0 == 12) && (getSkillActualLvl(arg0) == 20)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_102 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_102.intpart_1; + ivar3 = structdump_102.intpart_0; + svar0 = structdump_102.stringpart_0; + } + if ((arg0 == 6) && (getSkillActualLvl(arg0) == 7)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_103 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_103.intpart_1; + ivar3 = structdump_103.intpart_0; + svar0 = structdump_103.stringpart_0; + } + if ((arg0 == 13) && (getSkillActualLvl(arg0) == 40)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_104 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_104.intpart_1; + ivar3 = structdump_104.intpart_0; + svar0 = structdump_104.stringpart_0; + } + if (bitconfig_1383 > 3) { + ivar4 = 0; + } + break; + case 35: + if ((arg0 == 17) && (getSkillActualLvl(arg0) == 30)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_105 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_105.intpart_1; + ivar3 = structdump_105.intpart_0; + svar0 = structdump_105.stringpart_0; + } + if (bitconfig_334 > 27) { + ivar4 = 0; + } + break; + case 36: + if ((arg0 == 16) && (getSkillActualLvl(arg0) == 20)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_106 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_106.intpart_1; + ivar3 = structdump_106.intpart_0; + svar0 = structdump_106.stringpart_0; + } + if (bitconfig_260 > 69) { + ivar4 = 0; + } + break; + case 37: + if ((arg0 == 4) && (getSkillActualLvl(arg0) == 60)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_107 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_107.intpart_1; + ivar3 = structdump_107.intpart_0; + svar0 = structdump_107.stringpart_0; + } + if ((arg0 == 17) && (getSkillActualLvl(arg0) == 50)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_108 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_108.intpart_1; + ivar3 = structdump_108.intpart_0; + svar0 = structdump_108.stringpart_0; + } + if (standart_config_517 > 7) { + ivar4 = 0; + } + break; + case 38: + if ((arg0 == 16) && (getSkillActualLvl(arg0) == 25)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_109 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_109.intpart_1; + ivar3 = structdump_109.intpart_0; + svar0 = structdump_109.stringpart_0; + } + if (standart_config_387 > 100) { + ivar4 = 0; + } + break; + case 39: + if ((arg0 == 19) && (getSkillActualLvl(arg0) == 29)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_110 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_110.intpart_1; + ivar3 = structdump_110.intpart_0; + svar0 = structdump_110.stringpart_0; + } + if ((arg0 == 8) && (getSkillActualLvl(arg0) == 10)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_111 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_111.intpart_1; + ivar3 = structdump_111.intpart_0; + svar0 = structdump_111.stringpart_0; + } + if (bitconfig_2790 > 310) { + ivar4 = 0; + } + break; + case 40: + if ((arg0 == 12) && (getSkillActualLvl(arg0) == 18)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_112 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_112.intpart_1; + ivar3 = structdump_112.intpart_0; + svar0 = structdump_112.stringpart_0; + } + if (standart_config_307 == 110) { + ivar4 = 0; + } + break; + case 41: + if ((arg0 == 16) && (getSkillActualLvl(arg0) == 36)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_113 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_113.intpart_1; + ivar3 = structdump_113.intpart_0; + svar0 = structdump_113.stringpart_0; + } + if ((arg0 == 12) && (getSkillActualLvl(arg0) == 25)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_114 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_114.intpart_1; + ivar3 = structdump_114.intpart_0; + svar0 = structdump_114.stringpart_0; + } + if ((arg0 == 15) && (getSkillActualLvl(arg0) == 18)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_115 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_115.intpart_1; + ivar3 = structdump_115.intpart_0; + svar0 = structdump_115.stringpart_0; + } + if ((arg0 == 13) && (getSkillActualLvl(arg0) == 30)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_116 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_116.intpart_1; + ivar3 = structdump_116.intpart_0; + svar0 = structdump_116.stringpart_0; + } + if (standart_config_416 > 275) { + ivar4 = 0; + } + break; + case 42: + if ((arg0 == 16) && (getSkillActualLvl(arg0) == 56)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_117 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_117.intpart_1; + ivar3 = structdump_117.intpart_0; + svar0 = structdump_117.stringpart_0; + } + if (standart_config_328 > 14) { + ivar4 = 0; + } + break; + case 43: + if ((arg0 == 16) && (getSkillActualLvl(arg0) == 40)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_118 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_118.intpart_1; + ivar3 = structdump_118.intpart_0; + svar0 = structdump_118.stringpart_0; + } + if ((arg0 == 18) && (getSkillActualLvl(arg0) == 40)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_119 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_119.intpart_1; + ivar3 = structdump_119.intpart_0; + svar0 = structdump_119.stringpart_0; + } + if (bitconfig_2140 > 20) { + ivar4 = 0; + } + break; + case 44: + if ((arg0 == 5) && (getSkillActualLvl(arg0) == 31)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_120 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_120.intpart_1; + ivar3 = structdump_120.intpart_0; + svar0 = structdump_120.stringpart_0; + } + if (standart_config_76 == 6) { + ivar4 = 0; + } + break; + case 45: + if ((arg0 == 11) && (getSkillActualLvl(arg0) == 30)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_121 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_121.intpart_1; + ivar3 = structdump_121.intpart_0; + svar0 = structdump_121.stringpart_0; + } + if (standart_config_159 >= 12) { + ivar4 = 0; + } + break; + case 46: + if ((arg0 == 12) && (getSkillActualLvl(arg0) == 20)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_122 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_122.intpart_1; + ivar3 = structdump_122.intpart_0; + svar0 = structdump_122.stringpart_0; + } + if ((arg0 == 15) && (getSkillActualLvl(arg0) == 15)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_123 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_123.intpart_1; + ivar3 = structdump_123.intpart_0; + svar0 = structdump_123.stringpart_0; + } + if (standart_config_339 == 85) { + ivar4 = 0; + } + break; + case 47: + if ((arg0 == 12) && (getSkillActualLvl(arg0) == 30)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_124 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_124.intpart_1; + ivar3 = structdump_124.intpart_0; + svar0 = structdump_124.stringpart_0; + } + if (bitconfig_1372 > 124) { + ivar4 = 0; + } + break; + case 48: + if ((arg0 == 16) && (getSkillActualLvl(arg0) == 32)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_125 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_125.intpart_1; + ivar3 = structdump_125.intpart_0; + svar0 = structdump_125.stringpart_0; + } + if ((arg0 == 12) && (getSkillActualLvl(arg0) == 20)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_126 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_126.intpart_1; + ivar3 = structdump_126.intpart_0; + svar0 = structdump_126.stringpart_0; + } + if (standart_config_116 > 14) { + ivar4 = 0; + } + break; + case 49: + if ((arg0 == 6) && (getSkillActualLvl(arg0) == 33)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_127 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_127.intpart_1; + ivar3 = structdump_127.intpart_0; + svar0 = structdump_127.stringpart_0; + } + if ((arg0 == 14) && (getSkillActualLvl(arg0) == 37)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_128 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_128.intpart_1; + ivar3 = structdump_128.intpart_0; + svar0 = structdump_128.stringpart_0; + } + if ((arg0 == 4) && (getSkillActualLvl(arg0) == 37)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_129 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_129.intpart_1; + ivar3 = structdump_129.intpart_0; + svar0 = structdump_129.stringpart_0; + } + if ((arg0 == 17) && (getSkillActualLvl(arg0) == 37)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_130 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_130.intpart_1; + ivar3 = structdump_130.intpart_0; + svar0 = structdump_130.stringpart_0; + } + if (bitconfig_1444 > 59) { + ivar4 = 0; + } + break; + case 50: + if ((arg0 == 7) && (getSkillActualLvl(arg0) == 62)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_131 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_131.intpart_1; + ivar3 = structdump_131.intpart_0; + svar0 = structdump_131.stringpart_0; + } + if ((arg0 == 12) && (getSkillActualLvl(arg0) == 40)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_132 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_132.intpart_1; + ivar3 = structdump_132.intpart_0; + svar0 = structdump_132.stringpart_0; + } + if ((arg0 == 11) && (getSkillActualLvl(arg0) == 42)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_133 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_133.intpart_1; + ivar3 = structdump_133.intpart_0; + svar0 = structdump_133.stringpart_0; + } + if ((arg0 == 10) && (getSkillActualLvl(arg0) == 62)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_134 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_134.intpart_1; + ivar3 = structdump_134.intpart_0; + svar0 = structdump_134.stringpart_0; + } + if ((arg0 == 6) && (getSkillActualLvl(arg0) == 66)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_135 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_135.intpart_1; + ivar3 = structdump_135.intpart_0; + svar0 = structdump_135.stringpart_0; + } + if ((arg0 == 13) && (getSkillActualLvl(arg0) == 45)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_136 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_136.intpart_1; + ivar3 = structdump_136.intpart_0; + svar0 = structdump_136.stringpart_0; + } + if (bitconfig_2098 >= 200) { + ivar4 = 0; + } + break; + case 51: + if ((arg0 == 16) && (getSkillActualLvl(arg0) == 15)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_137 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_137.intpart_1; + ivar3 = structdump_137.intpart_0; + svar0 = structdump_137.stringpart_0; + } + if ((arg0 == 7) && (getSkillActualLvl(arg0) == 30)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_138 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_138.intpart_1; + ivar3 = structdump_138.intpart_0; + svar0 = structdump_138.stringpart_0; + } + if ((arg0 == 10) && (getSkillActualLvl(arg0) == 5)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_139 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_139.intpart_1; + ivar3 = structdump_139.intpart_0; + svar0 = structdump_139.stringpart_0; + } + if (standart_config_320 == 6) { + ivar4 = 0; + } + break; + case 52: + if ((arg0 == 12) && (getSkillActualLvl(arg0) == 20)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_140 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_140.intpart_1; + ivar3 = structdump_140.intpart_0; + svar0 = structdump_140.stringpart_0; + } + if ((arg0 == 11) && (getSkillActualLvl(arg0) == 49)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_141 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_141.intpart_1; + ivar3 = structdump_141.intpart_0; + svar0 = structdump_141.stringpart_0; + } + if ((arg0 == 14) && (getSkillActualLvl(arg0) == 20)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_142 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_142.intpart_1; + ivar3 = structdump_142.intpart_0; + svar0 = structdump_142.stringpart_0; + } + if (bitconfig_451 > 1) { + ivar4 = 0; + } + break; + case 53: + if ((arg0 == 4) && (getSkillActualLvl(arg0) == 40)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_143 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_143.intpart_1; + ivar3 = structdump_143.intpart_0; + svar0 = structdump_143.stringpart_0; + } + if ((arg0 == 17) && (getSkillActualLvl(arg0) == 42)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_144 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_144.intpart_1; + ivar3 = structdump_144.intpart_0; + svar0 = structdump_144.stringpart_0; + } + if ((standart_config_26 == 80) || (standart_config_26 == 90)) { + ivar4 = 0; + } + break; + case 54: + if ((arg0 == 9) && (getSkillActualLvl(arg0) == 10)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_145 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_145.intpart_1; + ivar3 = structdump_145.intpart_0; + svar0 = structdump_145.stringpart_0; + } + if ((arg0 == 13) && (getSkillActualLvl(arg0) == 20)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_146 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_146.intpart_1; + ivar3 = structdump_146.intpart_0; + svar0 = structdump_146.stringpart_0; + } + if (standart_config_197 == 30) { + ivar4 = 0; + } + break; + case 55: + if ((arg0 == 17) && (getSkillActualLvl(arg0) == 21)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_147 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_147.intpart_1; + ivar3 = structdump_147.intpart_0; + svar0 = structdump_147.stringpart_0; + } + if (standart_config_200 == 5) { + ivar4 = 0; + } + break; + case 56: + if ((arg0 == 16) && (getSkillActualLvl(arg0) == 28)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_148 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_148.intpart_1; + ivar3 = structdump_148.intpart_0; + svar0 = structdump_148.stringpart_0; + } + if (standart_config_385 > 44) { + ivar4 = 0; + } + break; + case 57: + if ((arg0 == 16) && (getSkillActualLvl(arg0) == 15)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_149 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_149.intpart_1; + ivar3 = structdump_149.intpart_0; + svar0 = structdump_149.stringpart_0; + } + if (standart_config_317 == 50) { + ivar4 = 0; + } + break; + case 58: + if ((arg0 == 4) && (getSkillActualLvl(arg0) == 25)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_150 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_150.intpart_1; + ivar3 = structdump_150.intpart_0; + svar0 = structdump_150.stringpart_0; + } + if (standart_config_161 == 10) { + ivar4 = 0; + } + break; + case 59: + if ((arg0 == 16) && (getSkillActualLvl(arg0) == 25)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_151 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_151.intpart_1; + ivar3 = structdump_151.intpart_0; + svar0 = structdump_151.stringpart_0; + } + if ((arg0 == 15) && (getSkillActualLvl(arg0) == 14)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_152 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_152.intpart_1; + ivar3 = structdump_152.intpart_0; + svar0 = structdump_152.stringpart_0; + } + if ((arg0 == 6) && (getSkillActualLvl(arg0) == 14)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_153 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_153.intpart_1; + ivar3 = structdump_153.intpart_0; + svar0 = structdump_153.stringpart_0; + } + if ((arg0 == 14) && (getSkillActualLvl(arg0) == 40)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_154 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_154.intpart_1; + ivar3 = structdump_154.intpart_0; + svar0 = structdump_154.stringpart_0; + } + if ((arg0 == 17) && (getSkillActualLvl(arg0) == 15)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_155 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_155.intpart_1; + ivar3 = structdump_155.intpart_0; + svar0 = structdump_155.stringpart_0; + } + if (standart_config_212 > 12) { + ivar4 = 0; + } + break; + case 60: + if (((boolean)arg0) && (getSkillActualLvl(arg0) == 20)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_156 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_156.intpart_1; + ivar3 = structdump_156.intpart_0; + svar0 = structdump_156.stringpart_0; + } + if (standart_config_5 == 10) { + ivar4 = 0; + } + break; + case 61: + if ((arg0 == 22) && (getSkillActualLvl(arg0) == 5)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_157 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_157.intpart_1; + ivar3 = structdump_157.intpart_0; + svar0 = structdump_157.stringpart_0; + } + if ((arg0 == 6) && (getSkillActualLvl(arg0) == 46)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_158 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_158.intpart_1; + ivar3 = structdump_158.intpart_0; + svar0 = structdump_158.stringpart_0; + } + if (bitconfig_2497 == 60) { + ivar4 = 0; + } + break; + case 62: + if ((arg0 == 16) && (getSkillActualLvl(arg0) == 23)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_159 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_159.intpart_1; + ivar3 = structdump_159.intpart_0; + svar0 = structdump_159.stringpart_0; + } + if ((arg0 == 17) && (getSkillActualLvl(arg0) == 23)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_160 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_160.intpart_1; + ivar3 = structdump_160.intpart_0; + svar0 = structdump_160.stringpart_0; + } + if (bitconfig_2258 == 13) { + ivar4 = 0; + } + break; + case 63: + if ((arg0 == 12) && (getSkillActualLvl(arg0) == 19)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_161 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_161.intpart_1; + ivar3 = structdump_161.intpart_0; + svar0 = structdump_161.stringpart_0; + } + if ((arg0 == 4) && (getSkillActualLvl(arg0) == 30)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_162 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_162.intpart_1; + ivar3 = structdump_162.intpart_0; + svar0 = structdump_162.stringpart_0; + } + if ((arg0 == 18) && (getSkillActualLvl(arg0) == 18)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_163 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_163.intpart_1; + ivar3 = structdump_163.intpart_0; + svar0 = structdump_163.stringpart_0; + } + if ((arg0 == 8) && (getSkillActualLvl(arg0) == 35)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_164 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_164.intpart_1; + ivar3 = structdump_164.intpart_0; + svar0 = structdump_164.stringpart_0; + } + if (bitconfig_3185 == 240) { + ivar4 = 0; + } + break; + case 64: + if ((arg0 == 6) && (getSkillActualLvl(arg0) == 20)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_165 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_165.intpart_1; + ivar3 = structdump_165.intpart_0; + svar0 = structdump_165.stringpart_0; + } + if ((arg0 == 13) && (getSkillActualLvl(arg0) == 30)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_166 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_166.intpart_1; + ivar3 = structdump_166.intpart_0; + svar0 = structdump_166.stringpart_0; + } + if (bitconfig_2639 == 11) { + ivar4 = 0; + } + break; + case 65: + if ((arg0 == 12) && (getSkillActualLvl(arg0) == 36)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_167 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_167.intpart_1; + ivar3 = structdump_167.intpart_0; + svar0 = structdump_167.stringpart_0; + } + if ((arg0 == 19) && (getSkillActualLvl(arg0) == 30)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_168 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_168.intpart_1; + ivar3 = structdump_168.intpart_0; + svar0 = structdump_168.stringpart_0; + } + if ((arg0 == 11) && (getSkillActualLvl(arg0) == 20)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_169 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_169.intpart_1; + ivar3 = structdump_169.intpart_0; + svar0 = structdump_169.stringpart_0; + } + if (bitconfig_2866 == 200) { + ivar4 = 0; + } + break; + case 66: + if ((arg0 == 22) && (getSkillActualLvl(arg0) == 30)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_170 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_170.intpart_1; + ivar3 = structdump_170.intpart_0; + svar0 = structdump_170.stringpart_0; + } + if ((arg0 == 12) && (getSkillActualLvl(arg0) == 16)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_171 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_171.intpart_1; + ivar3 = structdump_171.intpart_0; + svar0 = structdump_171.stringpart_0; + } + if ((arg0 == 5) && (getSkillActualLvl(arg0) == 50)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_172 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_172.intpart_1; + ivar3 = structdump_172.intpart_0; + svar0 = structdump_172.stringpart_0; + } + if (standart_config_980 > 129) { + ivar4 = 0; + } + break; + case 67: + if ((arg0 == 12) && (getSkillActualLvl(arg0) == 30)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_173 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_173.intpart_1; + ivar3 = structdump_173.intpart_0; + svar0 = structdump_173.stringpart_0; + } + if ((arg0 == 20) && (getSkillActualLvl(arg0) == 30)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_174 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_174.intpart_1; + ivar3 = structdump_174.intpart_0; + svar0 = structdump_174.stringpart_0; + } + if ((arg0 == 18) && (getSkillActualLvl(arg0) == 30)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_175 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_175.intpart_1; + ivar3 = structdump_175.intpart_0; + svar0 = structdump_175.stringpart_0; + } + if ((arg0 == 17) && (getSkillActualLvl(arg0) == 30)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_176 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_176.intpart_1; + ivar3 = structdump_176.intpart_0; + svar0 = structdump_176.stringpart_0; + } + if (bitconfig_2610 >= 14) { + ivar4 = 0; + } + break; + case 68: + if ((arg0 == 16) && (getSkillActualLvl(arg0) == 30)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_177 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_177.intpart_1; + ivar3 = structdump_177.intpart_0; + svar0 = structdump_177.stringpart_0; + } + if ((arg0 == 22) && (getSkillActualLvl(arg0) == 34)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_178 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_178.intpart_1; + ivar3 = structdump_178.intpart_0; + svar0 = structdump_178.stringpart_0; + } + if ((arg0 == 12) && (getSkillActualLvl(arg0) == 30)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_179 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_179.intpart_1; + ivar3 = structdump_179.intpart_0; + svar0 = structdump_179.stringpart_0; + } + if ((arg0 == 21) && (getSkillActualLvl(arg0) == 10)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_180 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_180.intpart_1; + ivar3 = structdump_180.intpart_0; + svar0 = structdump_180.stringpart_0; + } + if (bitconfig_3293 == 135) { + ivar4 = 0; + } + break; + case 69: + if ((arg0 == 16) && (getSkillActualLvl(arg0) == 40)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_181 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_181.intpart_1; + ivar3 = structdump_181.intpart_0; + svar0 = structdump_181.stringpart_0; + } + if ((arg0 == 22) && (getSkillActualLvl(arg0) == 20)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_182 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_182.intpart_1; + ivar3 = structdump_182.intpart_0; + svar0 = structdump_182.stringpart_0; + } + if ((arg0 == 12) && (getSkillActualLvl(arg0) == 46)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_183 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_183.intpart_1; + ivar3 = structdump_183.intpart_0; + svar0 = structdump_183.stringpart_0; + } + if ((arg0 == 8) && (getSkillActualLvl(arg0) == 56)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_184 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_184.intpart_1; + ivar3 = structdump_184.intpart_0; + svar0 = structdump_184.stringpart_0; + } + if (bitconfig_3311 == 340) { + ivar4 = 0; + } + break; + case 70: + if ((arg0 == 22) && (getSkillActualLvl(arg0) == 10)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_185 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_185.intpart_1; + ivar3 = structdump_185.intpart_0; + svar0 = structdump_185.stringpart_0; + } + if (bitconfig_3337 == 18) { + ivar4 = 0; + } + break; + case 71: + if ((arg0 == 20) && (getSkillActualLvl(arg0) == 35)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_186 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_186.intpart_1; + ivar3 = structdump_186.intpart_0; + svar0 = structdump_186.stringpart_0; + } + if (bitconfig_3523 > 149) { + ivar4 = 0; + } + break; + case 72: + if ((arg0 == 11) && (getSkillActualLvl(arg0) == 40)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_187 = script_1025(stack_dump0, stack_dump1, stack_dump2); + stack_dump0 = structdump_187.intpart_0; + stack_dump1 = structdump_187.intpart_1; + structdump_187.stringpart_0; + stack_dump0 = stack_dump0; + stack_dump1; + stack_dump0; + } + if ((arg0 == 8) && (getSkillActualLvl(arg0) == 50)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_188 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_188.intpart_1; + ivar3 = structdump_188.intpart_0; + svar0 = structdump_188.stringpart_0; + } + if (bitconfig_3534 == 80) { + ivar4 = 0; + } + break; + case 73: + if ((arg0 == 16) && (getSkillActualLvl(arg0) == 59)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_189 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_189.intpart_1; + ivar3 = structdump_189.intpart_0; + svar0 = structdump_189.stringpart_0; + } + if ((arg0 == 19) && (getSkillActualLvl(arg0) == 45)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_190 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_190.intpart_1; + ivar3 = structdump_190.intpart_0; + svar0 = structdump_190.stringpart_0; + } + if ((arg0 == 15) && (getSkillActualLvl(arg0) == 52)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_191 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_191.intpart_1; + ivar3 = structdump_191.intpart_0; + svar0 = structdump_191.stringpart_0; + } + if ((arg0 == 17) && (getSkillActualLvl(arg0) == 58)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_192 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_192.intpart_1; + ivar3 = structdump_192.intpart_0; + svar0 = structdump_192.stringpart_0; + } + if ((arg0 == 8) && (getSkillActualLvl(arg0) == 71)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_193 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_193.intpart_1; + ivar3 = structdump_193.intpart_0; + svar0 = structdump_193.stringpart_0; + } + if (bitconfig_2783 == 60) { + ivar4 = 0; + } + break; + case 74: + if ((arg0 == 6) && (getSkillActualLvl(arg0) == 45)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_194 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_194.intpart_1; + ivar3 = structdump_194.intpart_0; + svar0 = structdump_194.stringpart_0; + } + if (((boolean)arg0) && (getSkillActualLvl(arg0) == 65)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_195 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_195.intpart_1; + ivar3 = structdump_195.intpart_0; + svar0 = structdump_195.stringpart_0; + } + if (bitconfig_3888 == 90) { + ivar4 = 0; + } + break; + case 75: + if ((arg0 == 16) && (getSkillActualLvl(arg0) == 45)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_196 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_196.intpart_1; + ivar3 = structdump_196.intpart_0; + svar0 = structdump_196.stringpart_0; + } + if ((arg0 == 4) && (getSkillActualLvl(arg0) == 47)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_197 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_197.intpart_1; + ivar3 = structdump_197.intpart_0; + svar0 = structdump_197.stringpart_0; + } + if ((arg0 == 18) && (getSkillActualLvl(arg0) == 56)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_198 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_198.intpart_1; + ivar3 = structdump_198.intpart_0; + svar0 = structdump_198.stringpart_0; + } + if ((arg0 == 17) && (getSkillActualLvl(arg0) == 56)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_199 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_199.intpart_1; + ivar3 = structdump_199.intpart_0; + svar0 = structdump_199.stringpart_0; + } + if ((arg0 == 2) && (getSkillActualLvl(arg0) == 60)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_200 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_200.intpart_1; + ivar3 = structdump_200.intpart_0; + svar0 = structdump_200.stringpart_0; + } + if (bitconfig_3954 == 200) { + ivar4 = 0; + } + break; + case 76: + if ((arg0 == 16) && (getSkillActualLvl(arg0) == 55)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_201 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_201.intpart_1; + ivar3 = structdump_201.intpart_0; + svar0 = structdump_201.stringpart_0; + } + if ((arg0 == 19) && (getSkillActualLvl(arg0) == 53)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_202 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_202.intpart_1; + ivar3 = structdump_202.intpart_0; + svar0 = structdump_202.stringpart_0; + } + if ((arg0 == 18) && (getSkillActualLvl(arg0) == 59)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_203 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_203.intpart_1; + ivar3 = structdump_203.intpart_0; + svar0 = structdump_203.stringpart_0; + } + if ((arg0 == 8) && (getSkillActualLvl(arg0) == 72)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_204 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_204.intpart_1; + ivar3 = structdump_204.intpart_0; + svar0 = structdump_204.stringpart_0; + } + if (bitconfig_4055 == 65) { + ivar4 = 0; + } + break; + case 77: + if ((arg0 == 5) && (getSkillActualLvl(arg0) == 30)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_205 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_205.intpart_1; + ivar3 = structdump_205.intpart_0; + svar0 = structdump_205.stringpart_0; + } + if ((arg0 == 16) && (getSkillActualLvl(arg0) == 36)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_206 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_206.intpart_1; + ivar3 = structdump_206.intpart_0; + svar0 = structdump_206.stringpart_0; + } + if ((arg0 == 17) && (getSkillActualLvl(arg0) == 36)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_207 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_207.intpart_1; + ivar3 = structdump_207.intpart_0; + svar0 = structdump_207.stringpart_0; + } + if ((arg0 == 10) && (getSkillActualLvl(arg0) == 36)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_208 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_208.intpart_1; + ivar3 = structdump_208.intpart_0; + svar0 = structdump_208.stringpart_0; + } + if ((arg0 == 15) && (getSkillActualLvl(arg0) == 37)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_209 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_209.intpart_1; + ivar3 = structdump_209.intpart_0; + svar0 = structdump_209.stringpart_0; + } + if (bitconfig_4105 == 18) { + ivar4 = 0; + } + break; + case 78: + if ((arg0 == 7) && (getSkillActualLvl(arg0) == 10)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_210 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_210.intpart_1; + ivar3 = structdump_210.intpart_0; + svar0 = structdump_210.stringpart_0; + } + if (((boolean)bitconfig_1850)) { + ivar4 = 0; + } + break; + case 79: + if ((arg0 == 7) && (getSkillActualLvl(arg0) == 31)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_211 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_211.intpart_1; + ivar3 = structdump_211.intpart_0; + svar0 = structdump_211.stringpart_0; + } + if (bitconfig_1895 == 110) { + ivar4 = 0; + } + break; + case 80: + if ((arg0 == 7) && (getSkillActualLvl(arg0) == 40)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_212 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_212.intpart_1; + ivar3 = structdump_212.intpart_0; + svar0 = structdump_212.stringpart_0; + } + if (bitconfig_1896 == 5) { + ivar4 = 0; + } + break; + case 81: + if ((arg0 == 7) && (getSkillActualLvl(arg0) == 25)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_213 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_213.intpart_1; + ivar3 = structdump_213.intpart_0; + svar0 = structdump_213.stringpart_0; + } + if (bitconfig_1878 == 5) { + ivar4 = 0; + } + break; + case 82: + if ((arg0 == 7) && (getSkillActualLvl(arg0) == 41)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_214 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_214.intpart_1; + ivar3 = structdump_214.intpart_0; + svar0 = structdump_214.stringpart_0; + } + if ((arg0 == 11) && (getSkillActualLvl(arg0) == 20)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_215 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_215.intpart_1; + ivar3 = structdump_215.intpart_0; + svar0 = structdump_215.stringpart_0; + } + if (bitconfig_1904 == 170) { + ivar4 = 0; + } + break; + case 83: + if ((arg0 == 7) && (getSkillActualLvl(arg0) == 70)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_216 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_216.intpart_1; + ivar3 = structdump_216.intpart_0; + svar0 = structdump_216.stringpart_0; + } + if ((arg0 == 16) && (getSkillActualLvl(arg0) == 48)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_217 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_217.intpart_1; + ivar3 = structdump_217.intpart_0; + svar0 = structdump_217.stringpart_0; + } + if (bitconfig_1914 == 50) { + ivar4 = 0; + } + break; + case 84: + if ((arg0 == 21) && (getSkillActualLvl(arg0) == 48)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_218 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_218.intpart_1; + ivar3 = structdump_218.intpart_0; + svar0 = structdump_218.stringpart_0; + } + if ((arg0 == 11) && (getSkillActualLvl(arg0) == 51)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_219 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_219.intpart_1; + ivar3 = structdump_219.intpart_0; + svar0 = structdump_219.stringpart_0; + } + if ((arg0 == 8) && (getSkillActualLvl(arg0) == 58)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_220 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_220.intpart_1; + ivar3 = structdump_220.intpart_0; + svar0 = structdump_220.stringpart_0; + } + if (bitconfig_4321 == 200) { + ivar4 = 0; + } + break; + case 85: + if ((arg0 == 14) && (getSkillActualLvl(arg0) == 46)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_221 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_221.intpart_1; + ivar3 = structdump_221.intpart_0; + svar0 = structdump_221.stringpart_0; + } + if (bitconfig_4505 == 100) { + ivar4 = 0; + } + break; + case 86: + if ((arg0 == 22) && (getSkillActualLvl(arg0) == 44)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_222 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_222.intpart_1; + ivar3 = structdump_222.intpart_0; + svar0 = structdump_222.stringpart_0; + } + if ((arg0 == 9) && (getSkillActualLvl(arg0) == 42)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_223 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_223.intpart_1; + ivar3 = structdump_223.intpart_0; + svar0 = structdump_223.stringpart_0; + } + if (bitconfig_4396 == 60) { + ivar4 = 0; + } + break; + case 87: + if ((arg0 == 16) && (getSkillActualLvl(arg0) == 50)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_224 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_224.intpart_1; + ivar3 = structdump_224.intpart_0; + svar0 = structdump_224.stringpart_0; + } + if ((arg0 == 11) && (getSkillActualLvl(arg0) == 21)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_225 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_225.intpart_1; + ivar3 = structdump_225.intpart_0; + svar0 = structdump_225.stringpart_0; + } + if ((arg0 == 17) && (getSkillActualLvl(arg0) == 60)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_226 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_226.intpart_1; + ivar3 = structdump_226.intpart_0; + svar0 = structdump_226.stringpart_0; + } + if ((arg0 == 2) && (getSkillActualLvl(arg0) == 60)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_227 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_227.intpart_1; + ivar3 = structdump_227.intpart_0; + svar0 = structdump_227.stringpart_0; + } + if (bitconfig_4230 == 700) { + ivar4 = 0; + } + break; + case 88: + if ((arg0 == 12) && (getSkillActualLvl(arg0) == 42)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_228 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_228.intpart_1; + ivar3 = structdump_228.intpart_0; + svar0 = structdump_228.stringpart_0; + } + if ((arg0 == 19) && (getSkillActualLvl(arg0) == 40)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_229 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_229.intpart_1; + ivar3 = structdump_229.intpart_0; + svar0 = structdump_229.stringpart_0; + } + if ((arg0 == 10) && (getSkillActualLvl(arg0) == 50)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_230 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_230.intpart_1; + ivar3 = structdump_230.intpart_0; + svar0 = structdump_230.stringpart_0; + } + if ((arg0 == 5) && (getSkillActualLvl(arg0) == 47)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_231 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_231.intpart_1; + ivar3 = structdump_231.intpart_0; + svar0 = structdump_231.stringpart_0; + } + if ((arg0 == 18) && (getSkillActualLvl(arg0) == 42)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_232 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_232.intpart_1; + ivar3 = structdump_232.intpart_0; + svar0 = structdump_232.stringpart_0; + } + if (standart_config_600 > 18) { + ivar4 = 0; + } + break; + case 89: + if ((arg0 == 22) && (getSkillActualLvl(arg0) == 20)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_233 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_233.intpart_1; + ivar3 = structdump_233.intpart_0; + svar0 = structdump_233.stringpart_0; + } + if ((arg0 == 16) && (getSkillActualLvl(arg0) == 29)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_234 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_234.intpart_1; + ivar3 = structdump_234.intpart_0; + svar0 = structdump_234.stringpart_0; + } + if ((arg0 == 12) && (getSkillActualLvl(arg0) == 47)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_235 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_235.intpart_1; + ivar3 = structdump_235.intpart_0; + svar0 = structdump_235.stringpart_0; + } + if ((arg0 == 6) && (getSkillActualLvl(arg0) == 49)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_236 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_236.intpart_1; + ivar3 = structdump_236.intpart_0; + svar0 = structdump_236.stringpart_0; + } + if ((arg0 == 14) && (getSkillActualLvl(arg0) == 35)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_237 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_237.intpart_1; + ivar3 = structdump_237.intpart_0; + svar0 = structdump_237.stringpart_0; + } + if ((arg0 == 18) && (getSkillActualLvl(arg0) == 31)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_238 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_238.intpart_1; + ivar3 = structdump_238.intpart_0; + svar0 = structdump_238.stringpart_0; + } + if ((arg0 == 11) && (getSkillActualLvl(arg0) == 40)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_239 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_239.intpart_1; + ivar3 = structdump_239.intpart_0; + svar0 = structdump_239.stringpart_0; + } + if (bitconfig_4569 == 500) { + ivar4 = 0; + } + break; + case 90: + if (((boolean)arg0) && (getSkillActualLvl(arg0) == 40)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_240 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_240.intpart_1; + ivar3 = structdump_240.intpart_0; + svar0 = structdump_240.stringpart_0; + } + if ((arg0 == 14) && (getSkillActualLvl(arg0) == 41)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_241 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_241.intpart_1; + ivar3 = structdump_241.intpart_0; + svar0 = structdump_241.stringpart_0; + } + if ((arg0 == 12) && (getSkillActualLvl(arg0) == 43)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_242 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_242.intpart_1; + ivar3 = structdump_242.intpart_0; + svar0 = structdump_242.stringpart_0; + } + if ((arg0 == 2) && (getSkillActualLvl(arg0) == 45)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_243 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_243.intpart_1; + ivar3 = structdump_243.intpart_0; + svar0 = structdump_243.stringpart_0; + } + if ((arg0 == 22) && (getSkillActualLvl(arg0) == 50)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_244 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_244.intpart_1; + ivar3 = structdump_244.intpart_0; + svar0 = structdump_244.stringpart_0; + } + if (bitconfig_4700 == 63) { + ivar4 = 0; + } + break; + case 91: + if ((arg0 == 22) && (getSkillActualLvl(arg0) == 10)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_245 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_245.intpart_1; + ivar3 = structdump_245.intpart_0; + svar0 = structdump_245.stringpart_0; + } + if ((arg0 == 19) && (getSkillActualLvl(arg0) == 10)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_246 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_246.intpart_1; + ivar3 = structdump_246.intpart_0; + svar0 = structdump_246.stringpart_0; + } + if ((arg0 == 21) && (getSkillActualLvl(arg0) == 10)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_247 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_247.intpart_1; + ivar3 = structdump_247.intpart_0; + svar0 = structdump_247.stringpart_0; + } + if ((arg0 == 17) && (getSkillActualLvl(arg0) == 11)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_248 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_248.intpart_1; + ivar3 = structdump_248.intpart_0; + svar0 = structdump_248.stringpart_0; + } + if (bitconfig_4684 == 150) { + ivar4 = 0; + } + break; + case 92: + if ((arg0 == 18) && (getSkillActualLvl(arg0) == 35)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_249 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_249.intpart_1; + ivar3 = structdump_249.intpart_0; + svar0 = structdump_249.stringpart_0; + } + if ((arg0 == 12) && (getSkillActualLvl(arg0) == 25)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_250 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_250.intpart_1; + ivar3 = structdump_250.intpart_0; + svar0 = structdump_250.stringpart_0; + } + if (bitconfig_4764 == 250) { + ivar4 = 0; + } + break; + case 93: + if ((arg0 == 16) && (getSkillActualLvl(arg0) == 60)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_251 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_251.intpart_1; + ivar3 = structdump_251.intpart_0; + svar0 = structdump_251.stringpart_0; + } + if ((arg0 == 17) && (getSkillActualLvl(arg0) == 63)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_252 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_252.intpart_1; + ivar3 = structdump_252.intpart_0; + svar0 = structdump_252.stringpart_0; + } + if ((arg0 == 12) && (getSkillActualLvl(arg0) == 66)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_253 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_253.intpart_1; + ivar3 = structdump_253.intpart_0; + svar0 = structdump_253.stringpart_0; + } + if ((arg0 == 13) && (getSkillActualLvl(arg0) == 69)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_254 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_254.intpart_1; + ivar3 = structdump_254.intpart_0; + svar0 = structdump_254.stringpart_0; + } + if (bitconfig_4797 == 100) { + ivar4 = 0; + } + break; + case 94: + if ((arg0 == 22) && (getSkillActualLvl(arg0) == 40)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_255 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_255.intpart_1; + ivar3 = structdump_255.intpart_0; + svar0 = structdump_255.stringpart_0; + } + if ((arg0 == 19) && (getSkillActualLvl(arg0) == 26)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_256 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_256.intpart_1; + ivar3 = structdump_256.intpart_0; + svar0 = structdump_256.stringpart_0; + } + if ((arg0 == 5) && (getSkillActualLvl(arg0) == 35)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_257 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_257.intpart_1; + ivar3 = structdump_257.intpart_0; + svar0 = structdump_257.stringpart_0; + } + if ((arg0 == 23) && (getSkillActualLvl(arg0) == 19)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_258 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_258.intpart_1; + ivar3 = structdump_258.intpart_0; + svar0 = structdump_258.stringpart_0; + } + if (bitconfig_5032 == 80) { + ivar4 = 0; + } + break; + case 95: + if ((arg0 == 11) && (getSkillActualLvl(arg0) == 43)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_259 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_259.intpart_1; + ivar3 = structdump_259.intpart_0; + svar0 = structdump_259.stringpart_0; + } + if (bitconfig_5133 >= 90) { + ivar4 = 0; + } + break; + case 96: + if ((arg0 == 11) && (getSkillActualLvl(arg0) == 47)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_260 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_260.intpart_1; + ivar3 = structdump_260.intpart_0; + svar0 = structdump_260.stringpart_0; + } + if ((arg0 == 21) && (getSkillActualLvl(arg0) == 35)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_261 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_261.intpart_1; + ivar3 = structdump_261.intpart_0; + svar0 = structdump_261.stringpart_0; + } + if ((arg0 == 14) && (getSkillActualLvl(arg0) == 45)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_262 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_262.intpart_1; + ivar3 = structdump_262.intpart_0; + svar0 = structdump_262.stringpart_0; + } + if ((arg0 == 5) && (getSkillActualLvl(arg0) == 55)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_263 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_263.intpart_1; + ivar3 = structdump_263.intpart_0; + svar0 = structdump_263.stringpart_0; + } + if ((arg0 == 23) && (getSkillActualLvl(arg0) == 23)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_264 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_264.intpart_1; + ivar3 = structdump_264.intpart_0; + svar0 = structdump_264.stringpart_0; + } + if ((arg0 == 8) && (getSkillActualLvl(arg0) == 37)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_265 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_265.intpart_1; + ivar3 = structdump_265.intpart_0; + svar0 = structdump_265.stringpart_0; + } + if (bitconfig_5331 == 35) { + ivar4 = 0; + } + break; + case 97: + if ((arg0 == 21) && (getSkillActualLvl(arg0) == 51)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_266 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_266.intpart_1; + ivar3 = structdump_266.intpart_0; + svar0 = structdump_266.stringpart_0; + } + if ((arg0 == 16) && (getSkillActualLvl(arg0) == 51)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_267 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_267.intpart_1; + ivar3 = structdump_267.intpart_0; + svar0 = structdump_267.stringpart_0; + } + if ((arg0 == 13) && (getSkillActualLvl(arg0) == 54)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_268 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_268.intpart_1; + ivar3 = structdump_268.intpart_0; + svar0 = structdump_268.stringpart_0; + } + if ((arg0 == 14) && (getSkillActualLvl(arg0) == 59)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_269 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_269.intpart_1; + ivar3 = structdump_269.intpart_0; + svar0 = structdump_269.stringpart_0; + } + if (bitconfig_5387 >= 250) { + ivar4 = 0; + } + break; + case 98: + if (((boolean)arg0) && (getSkillActualLvl(arg0) == 65)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_270 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_270.intpart_1; + ivar3 = structdump_270.intpart_0; + svar0 = structdump_270.stringpart_0; + } + if ((arg0 == 6) && (getSkillActualLvl(arg0) == 75)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_271 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_271.intpart_1; + ivar3 = structdump_271.intpart_0; + svar0 = structdump_271.stringpart_0; + } + if ((arg0 == 15) && (getSkillActualLvl(arg0) == 65)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_272 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_272.intpart_1; + ivar3 = structdump_272.intpart_0; + svar0 = structdump_272.stringpart_0; + } + if ((arg0 == 17) && (getSkillActualLvl(arg0) == 60)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_273 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_273.intpart_1; + ivar3 = structdump_273.intpart_0; + svar0 = structdump_273.stringpart_0; + } + if ((arg0 == 21) && (getSkillActualLvl(arg0) == 55)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_274 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_274.intpart_1; + ivar3 = structdump_274.intpart_0; + svar0 = structdump_274.stringpart_0; + } + if ((arg0 == 19) && (getSkillActualLvl(arg0) == 65)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_275 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_275.intpart_1; + ivar3 = structdump_275.intpart_0; + svar0 = structdump_275.stringpart_0; + } + if ((arg0 == 23) && (getSkillActualLvl(arg0) == 23)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_276 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_276.intpart_1; + ivar3 = structdump_276.intpart_0; + svar0 = structdump_276.stringpart_0; + } + if (((boolean)script_395()) && ((arg0 == 2) || ((boolean)arg0))) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_277 = script_2042(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_277.intpart_1; + ivar3 = structdump_277.intpart_0; + svar0 = structdump_277.stringpart_0; + } + if (bitconfig_5491 >= 910) { + ivar4 = 0; + } + break; + case 99: + if ((arg0 == 11) && (getSkillActualLvl(arg0) == 55)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_278 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_278.intpart_1; + ivar3 = structdump_278.intpart_0; + svar0 = structdump_278.stringpart_0; + } + if ((arg0 == 12) && (getSkillActualLvl(arg0) == 52)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_279 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_279.intpart_1; + ivar3 = structdump_279.intpart_0; + svar0 = structdump_279.stringpart_0; + } + if ((arg0 == 9) && (getSkillActualLvl(arg0) == 53)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_280 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_280.intpart_1; + ivar3 = structdump_280.intpart_0; + svar0 = structdump_280.stringpart_0; + } + if (bitconfig_5761 == 30) { + ivar4 = 0; + } + break; + case 100: + if ((arg0 == 17) && (getSkillActualLvl(arg0) == 46)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_281 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_281.intpart_1; + ivar3 = structdump_281.intpart_0; + svar0 = structdump_281.stringpart_0; + } + if ((arg0 == 16) && (getSkillActualLvl(arg0) == 46)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_282 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_282.intpart_1; + ivar3 = structdump_282.intpart_0; + svar0 = structdump_282.stringpart_0; + } + if ((arg0 == 2) && (getSkillActualLvl(arg0) == 46)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_283 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_283.intpart_1; + ivar3 = structdump_283.intpart_0; + svar0 = structdump_283.stringpart_0; + } + if (bitconfig_1938 >= 110) { + ivar4 = 0; + } + break; + case 101: + if ((arg0 == 21) && (getSkillActualLvl(arg0) == 41)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_284 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_284.intpart_1; + ivar3 = structdump_284.intpart_0; + svar0 = structdump_284.stringpart_0; + } + if ((arg0 == 16) && (getSkillActualLvl(arg0) == 50)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_285 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_285.intpart_1; + ivar3 = structdump_285.intpart_0; + svar0 = structdump_285.stringpart_0; + } + if ((arg0 == 6) && (getSkillActualLvl(arg0) == 57)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_286 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_286.intpart_1; + ivar3 = structdump_286.intpart_0; + svar0 = structdump_286.stringpart_0; + } + if ((arg0 == 15) && (getSkillActualLvl(arg0) == 43)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_287 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_287.intpart_1; + ivar3 = structdump_287.intpart_0; + svar0 = structdump_287.stringpart_0; + } + if (bitconfig_6001 >= 45) { + ivar4 = 0; + } + break; + case 102: + if ((arg0 == 14) && (getSkillActualLvl(arg0) == 8)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_288 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_288.intpart_1; + ivar3 = structdump_288.intpart_0; + svar0 = structdump_288.stringpart_0; + } + if ((arg0 == 6) && (getSkillActualLvl(arg0) == 10)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_289 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_289.intpart_1; + ivar3 = structdump_289.intpart_0; + svar0 = structdump_289.stringpart_0; + } + if ((arg0 == 11) && (getSkillActualLvl(arg0) == 6)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_290 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_290.intpart_1; + ivar3 = structdump_290.intpart_0; + svar0 = structdump_290.stringpart_0; + } + if ((arg0 == 8) && (getSkillActualLvl(arg0) == 10)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_291 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_291.intpart_1; + ivar3 = structdump_291.intpart_0; + svar0 = structdump_291.stringpart_0; + } + if (bitconfig_6048 == 250) { + ivar4 = 0; + } + break; + case 103: + if ((arg0 == 22) && (getSkillActualLvl(arg0) == 35)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_292 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_292.intpart_1; + ivar3 = structdump_292.intpart_0; + svar0 = structdump_292.stringpart_0; + } + if ((arg0 == 7) && (getSkillActualLvl(arg0) == 35)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_293 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_293.intpart_1; + ivar3 = structdump_293.intpart_0; + svar0 = structdump_293.stringpart_0; + } + if ((arg0 == 12) && (getSkillActualLvl(arg0) == 35)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_294 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_294.intpart_1; + ivar3 = structdump_294.intpart_0; + svar0 = structdump_294.stringpart_0; + } + if ((arg0 == 5) && (getSkillActualLvl(arg0) == 35)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_295 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_295.intpart_1; + ivar3 = structdump_295.intpart_0; + svar0 = structdump_295.stringpart_0; + } + if ((arg0 == 6) && (getSkillActualLvl(arg0) == 35)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_296 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_296.intpart_1; + ivar3 = structdump_296.intpart_0; + svar0 = structdump_296.stringpart_0; + } + if (bitconfig_6112 == 60) { + ivar4 = 0; + } + break; + case 104: + if ((arg0 == 17) && (getSkillActualLvl(arg0) == 38)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_297 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_297.intpart_1; + ivar3 = structdump_297.intpart_0; + svar0 = structdump_297.stringpart_0; + } + if ((arg0 == 22) && (getSkillActualLvl(arg0) == 45)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_298 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_298.intpart_1; + ivar3 = structdump_298.intpart_0; + svar0 = structdump_298.stringpart_0; + } + if ((arg0 == 21) && (getSkillActualLvl(arg0) == 45)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_299 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_299.intpart_1; + ivar3 = structdump_299.intpart_0; + svar0 = structdump_299.stringpart_0; + } + if (bitconfig_6180 == 140) { + ivar4 = 0; + } + break; + case 105: + if ((arg0 == 23) && (getSkillActualLvl(arg0) == 41)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_300 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_300.intpart_1; + ivar3 = structdump_300.intpart_0; + svar0 = structdump_300.stringpart_0; + } + if ((arg0 == 14) && (getSkillActualLvl(arg0) == 64)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_301 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_301.intpart_1; + ivar3 = structdump_301.intpart_0; + svar0 = structdump_301.stringpart_0; + } + if ((arg0 == 18) && (getSkillActualLvl(arg0) == 37)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_302 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_302.intpart_1; + ivar3 = structdump_302.intpart_0; + svar0 = structdump_302.stringpart_0; + } + if ((arg0 == 16) && (getSkillActualLvl(arg0) == 61)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_303 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_303.intpart_1; + ivar3 = structdump_303.intpart_0; + svar0 = structdump_303.stringpart_0; + } + if ((arg0 == 2) && (getSkillActualLvl(arg0) == 64)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_304 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_304.intpart_1; + ivar3 = structdump_304.intpart_0; + svar0 = structdump_304.stringpart_0; + } + if ((arg0 == 4) && (getSkillActualLvl(arg0) == 64)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_305 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_305.intpart_1; + ivar3 = structdump_305.intpart_0; + svar0 = structdump_305.stringpart_0; + } + if ((arg0 == 17) && (getSkillActualLvl(arg0) == 66)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_306 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_306.intpart_1; + ivar3 = structdump_306.intpart_0; + svar0 = structdump_306.stringpart_0; + } + break; + case 106: + if ((arg0 == 21) && (getSkillActualLvl(arg0) == 61)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_307 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_307.intpart_1; + ivar3 = structdump_307.intpart_0; + svar0 = structdump_307.stringpart_0; + } + if ((arg0 == 11) && (getSkillActualLvl(arg0) == 61)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_308 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_308.intpart_1; + ivar3 = structdump_308.intpart_0; + svar0 = structdump_308.stringpart_0; + } + if ((arg0 == 2) && (getSkillActualLvl(arg0) == 69)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_309 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_309.intpart_1; + ivar3 = structdump_309.intpart_0; + svar0 = structdump_309.stringpart_0; + } + if (bitconfig_6471 == 90) { + ivar4 = 0; + } + break; + case 107: + if ((arg0 == 16) && (getSkillActualLvl(arg0) == 69)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_310 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_310.intpart_1; + ivar3 = structdump_310.intpart_0; + svar0 = structdump_310.stringpart_0; + } + if ((arg0 == 9) && (getSkillActualLvl(arg0) == 70)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_311 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_311.intpart_1; + ivar3 = structdump_311.intpart_0; + svar0 = structdump_311.stringpart_0; + } + if ((arg0 == 4) && (getSkillActualLvl(arg0) == 75)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_312 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_312.intpart_1; + ivar3 = structdump_312.intpart_0; + svar0 = structdump_312.stringpart_0; + } + if ((arg0 == 8) && (getSkillActualLvl(arg0) == 75)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_313 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_313.intpart_1; + ivar3 = structdump_313.intpart_0; + svar0 = structdump_313.stringpart_0; + } + if (bitconfig_6553 == 46) { + ivar4 = 0; + } + break; + case 108: + if ((arg0 == 5) && (getSkillActualLvl(arg0) == 50)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_314 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_314.intpart_1; + ivar3 = structdump_314.intpart_0; + svar0 = structdump_314.stringpart_0; + } + if (bitconfig_6775 == 90) { + ivar4 = 0; + } + break; + case 109: + if (((boolean)arg0) && (getSkillActualLvl(arg0) == 75)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_315 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_315.intpart_1; + ivar3 = structdump_315.intpart_0; + svar0 = structdump_315.stringpart_0; + } + if ((arg0 == 2) && (getSkillActualLvl(arg0) == 75)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_316 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_316.intpart_1; + ivar3 = structdump_316.intpart_0; + svar0 = structdump_316.stringpart_0; + } + if ((arg0 == 18) && (getSkillActualLvl(arg0) == 65)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_317 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_317.intpart_1; + ivar3 = structdump_317.intpart_0; + svar0 = structdump_317.stringpart_0; + } + if (bitconfig_6883 >= 147) { + ivar4 = 0; + } + break; + case 110: + if ((arg0 == 6) && (getSkillActualLvl(arg0) == 75)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_318 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_318.intpart_1; + ivar3 = structdump_318.intpart_0; + svar0 = structdump_318.stringpart_0; + } + if ((arg0 == 5) && (getSkillActualLvl(arg0) == 70)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_319 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_319.intpart_1; + ivar3 = structdump_319.intpart_0; + svar0 = structdump_319.stringpart_0; + } + if ((arg0 == 14) && (getSkillActualLvl(arg0) == 66)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_320 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_320.intpart_1; + ivar3 = structdump_320.intpart_0; + svar0 = structdump_320.stringpart_0; + } + if ((arg0 == 21) && (getSkillActualLvl(arg0) == 65)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_321 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_321.intpart_1; + ivar3 = structdump_321.intpart_0; + svar0 = structdump_321.stringpart_0; + } + if ((arg0 == 22) && (getSkillActualLvl(arg0) == 60)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_322 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_322.intpart_1; + ivar3 = structdump_322.intpart_0; + svar0 = structdump_322.stringpart_0; + } + if (bitconfig_6962 == 12) { + ivar4 = 0; + } + break; + case 111: + if ((arg0 == 6) && (getSkillActualLvl(arg0) == 27)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_323 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_323.intpart_1; + ivar3 = structdump_323.intpart_0; + svar0 = structdump_323.stringpart_0; + } + if ((arg0 == 20) && (getSkillActualLvl(arg0) == 20)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_324 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_324.intpart_1; + ivar3 = structdump_324.intpart_0; + svar0 = structdump_324.stringpart_0; + } + if ((arg0 == 22) && (getSkillActualLvl(arg0) == 25)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_325 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_325.intpart_1; + ivar3 = structdump_325.intpart_0; + svar0 = structdump_325.stringpart_0; + } + if (bitconfig_7050 == 35) { + ivar4 = 0; + } + break; + case 112: + if ((arg0 == 17) && (getSkillActualLvl(arg0) == 24)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_326 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_326.intpart_1; + ivar3 = structdump_326.intpart_0; + svar0 = structdump_326.stringpart_0; + } + if (bitconfig_7794 == 15) { + ivar4 = 0; + } + break; + case 113: + if ((arg0 == 17) && (getSkillActualLvl(arg0) == 41)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_327 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_327.intpart_1; + ivar3 = structdump_327.intpart_0; + svar0 = structdump_327.stringpart_0; + } + if (bitconfig_7795 == 2) { + ivar4 = 0; + } + break; + case 114: + if ((arg0 == 17) && (getSkillActualLvl(arg0) == 62)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_328 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_328.intpart_1; + ivar3 = structdump_328.intpart_0; + svar0 = structdump_328.stringpart_0; + } + if ((arg0 == 15) && (getSkillActualLvl(arg0) == 46)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_329 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_329.intpart_1; + ivar3 = structdump_329.intpart_0; + svar0 = structdump_329.stringpart_0; + } + if ((arg0 == 16) && (getSkillActualLvl(arg0) == 40)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_330 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_330.intpart_1; + ivar3 = structdump_330.intpart_0; + svar0 = structdump_330.stringpart_0; + } + if (bitconfig_7796 == 30) { + ivar4 = 0; + } + break; + case 115: + if ((arg0 == 19) && (getSkillActualLvl(arg0) == 54)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_331 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_331.intpart_1; + ivar3 = structdump_331.intpart_0; + svar0 = structdump_331.stringpart_0; + } + if ((arg0 == 17) && (getSkillActualLvl(arg0) == 51)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_332 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_332.intpart_1; + ivar3 = structdump_332.intpart_0; + svar0 = structdump_332.stringpart_0; + } + if ((arg0 == 6) && (getSkillActualLvl(arg0) == 59)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_333 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_333.intpart_1; + ivar3 = structdump_333.intpart_0; + svar0 = structdump_333.stringpart_0; + } + if ((arg0 == 23) && (getSkillActualLvl(arg0) == 37)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_334 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_334.intpart_1; + ivar3 = structdump_334.intpart_0; + svar0 = structdump_334.stringpart_0; + } + if ((arg0 == 12) && (getSkillActualLvl(arg0) == 36)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_335 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_335.intpart_1; + ivar3 = structdump_335.intpart_0; + svar0 = structdump_335.stringpart_0; + } + if (bitconfig_7826 > 170) { + ivar4 = 0; + } + break; + case 116: + if (((boolean)arg0) && (getSkillActualLvl(arg0) == 33)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_336 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_336.intpart_1; + ivar3 = structdump_336.intpart_0; + svar0 = structdump_336.stringpart_0; + } + if ((arg0 == 13) && (getSkillActualLvl(arg0) == 33)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_337 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_337.intpart_1; + ivar3 = structdump_337.intpart_0; + svar0 = structdump_337.stringpart_0; + } + if (bitconfig_7871 == 11) { + ivar4 = 0; + } + break; + case 117: + if ((arg0 == 2) && (getSkillActualLvl(arg0) == 42)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_338 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_338.intpart_1; + ivar3 = structdump_338.intpart_0; + svar0 = structdump_338.stringpart_0; + } + if (((boolean)arg0) && (getSkillActualLvl(arg0) == 35)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_339 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_339.intpart_1; + ivar3 = structdump_339.intpart_0; + svar0 = structdump_339.stringpart_0; + } + if (bitconfig_7958 == 90) { + ivar4 = 0; + } + break; + case 118: + if ((arg0 == 6) && (getSkillActualLvl(arg0) == 77)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_340 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_340.intpart_1; + ivar3 = structdump_340.intpart_0; + svar0 = structdump_340.stringpart_0; + } + if ((arg0 == 22) && (getSkillActualLvl(arg0) == 68)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_341 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_341.intpart_1; + ivar3 = structdump_341.intpart_0; + svar0 = structdump_341.stringpart_0; + } + if ((arg0 == 13) && (getSkillActualLvl(arg0) == 68)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_342 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_342.intpart_1; + ivar3 = structdump_342.intpart_0; + svar0 = structdump_342.stringpart_0; + } + if ((arg0 == 12) && (getSkillActualLvl(arg0) == 67)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_343 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_343.intpart_1; + ivar3 = structdump_343.intpart_0; + svar0 = structdump_343.stringpart_0; + } + if (bitconfig_8045 >= 150) { + ivar4 = 0; + } + break; + case 119: + if ((arg0 == 22) && (getSkillActualLvl(arg0) == 47)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_344 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_344.intpart_1; + ivar3 = structdump_344.intpart_0; + svar0 = structdump_344.stringpart_0; + } + if ((arg0 == 15) && (getSkillActualLvl(arg0) == 49)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_345 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_345.intpart_1; + ivar3 = structdump_345.intpart_0; + svar0 = structdump_345.stringpart_0; + } + if ((arg0 == 21) && (getSkillActualLvl(arg0) == 46)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_346 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_346.intpart_1; + ivar3 = structdump_346.intpart_0; + svar0 = structdump_346.stringpart_0; + } + if ((arg0 == 14) && (getSkillActualLvl(arg0) == 47)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_347 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_347.intpart_1; + ivar3 = structdump_347.intpart_0; + svar0 = structdump_347.stringpart_0; + } + if ((arg0 == 23) && (getSkillActualLvl(arg0) == 48)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_348 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_348.intpart_1; + ivar3 = structdump_348.intpart_0; + svar0 = structdump_348.stringpart_0; + } + if ((arg0 == 17) && (getSkillActualLvl(arg0) == 54)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_349 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_349.intpart_1; + ivar3 = structdump_349.intpart_0; + svar0 = structdump_349.stringpart_0; + } + if ((arg0 == 8) && (getSkillActualLvl(arg0) == 52)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_350 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_350.intpart_1; + ivar3 = structdump_350.intpart_0; + svar0 = structdump_350.stringpart_0; + } + if (bitconfig_7451 == 63) { + ivar4 = 0; + } + break; + case 120: + if (((boolean)arg0) && (getSkillActualLvl(arg0) == 78)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_351 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_351.intpart_1; + ivar3 = structdump_351.intpart_0; + svar0 = structdump_351.stringpart_0; + } + if ((arg0 == 22) && (getSkillActualLvl(arg0) == 70)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_352 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_352.intpart_1; + ivar3 = structdump_352.intpart_0; + svar0 = structdump_352.stringpart_0; + } + if ((arg0 == 12) && (getSkillActualLvl(arg0) == 70)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_353 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_353.intpart_1; + ivar3 = structdump_353.intpart_0; + svar0 = structdump_353.stringpart_0; + } + if ((arg0 == 11) && (getSkillActualLvl(arg0) == 71)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_354 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_354.intpart_1; + ivar3 = structdump_354.intpart_0; + svar0 = structdump_354.stringpart_0; + } + if ((arg0 == 6) && (getSkillActualLvl(arg0) == 80)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_355 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_355.intpart_1; + ivar3 = structdump_355.intpart_0; + svar0 = structdump_355.stringpart_0; + } + if ((arg0 == 13) && (getSkillActualLvl(arg0) == 70)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_356 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_356.intpart_1; + ivar3 = structdump_356.intpart_0; + svar0 = structdump_356.stringpart_0; + } + if ((arg0 == 2) && (getSkillActualLvl(arg0) == 78)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_357 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_357.intpart_1; + ivar3 = structdump_357.intpart_0; + svar0 = structdump_357.stringpart_0; + } + if ((arg0 == 23) && (getSkillActualLvl(arg0) == 55)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_358 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_358.intpart_1; + ivar3 = structdump_358.intpart_0; + svar0 = structdump_358.stringpart_0; + } + if (((boolean)arg0) && (getSkillActualLvl(arg0) == 10)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_359 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_359.intpart_1; + ivar3 = structdump_359.intpart_0; + svar0 = structdump_359.stringpart_0; + } + if (bitconfig_8248 == 40) { + ivar4 = 0; + } + break; + case 121: + if ((arg0 == 2) && (getSkillActualLvl(arg0) == 77)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_360 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_360.intpart_1; + ivar3 = structdump_360.intpart_0; + svar0 = structdump_360.stringpart_0; + } + if ((arg0 == 13) && (getSkillActualLvl(arg0) == 70)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_361 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_361.intpart_1; + ivar3 = structdump_361.intpart_0; + svar0 = structdump_361.stringpart_0; + } + if ((arg0 == 14) && (getSkillActualLvl(arg0) == 68)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_362 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_362.intpart_1; + ivar3 = structdump_362.intpart_0; + svar0 = structdump_362.stringpart_0; + } + if (bitconfig_8704 == 90) { + ivar4 = 0; + } + break; + case 122: + if ((arg0 == 16) && (getSkillActualLvl(arg0) == 64)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_363 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_363.intpart_1; + ivar3 = structdump_363.intpart_0; + svar0 = structdump_363.stringpart_0; + } + if ((arg0 == 17) && (getSkillActualLvl(arg0) == 64)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_364 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_364.intpart_1; + ivar3 = structdump_364.intpart_0; + svar0 = structdump_364.stringpart_0; + } + if ((arg0 == 22) && (getSkillActualLvl(arg0) == 62)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_365 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_365.intpart_1; + ivar3 = structdump_365.intpart_0; + svar0 = structdump_365.stringpart_0; + } + if ((arg0 == 20) && (getSkillActualLvl(arg0) == 61)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_366 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_366.intpart_1; + ivar3 = structdump_366.intpart_0; + svar0 = structdump_366.stringpart_0; + } + if (bitconfig_5332 >= 120) { + ivar4 = 0; + } + break; + case 123: + if (((boolean)arg0) && (getSkillActualLvl(arg0) == 40)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_367 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_367.intpart_1; + ivar3 = structdump_367.intpart_0; + svar0 = structdump_367.stringpart_0; + } + if ((arg0 == 12) && (getSkillActualLvl(arg0) == 41)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_368 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_368.intpart_1; + ivar3 = structdump_368.intpart_0; + svar0 = structdump_368.stringpart_0; + } + if ((arg0 == 20) && (getSkillActualLvl(arg0) == 39)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_369 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_369.intpart_1; + ivar3 = structdump_369.intpart_0; + svar0 = structdump_369.stringpart_0; + } + if ((arg0 == 13) && (getSkillActualLvl(arg0) == 42)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_370 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_370.intpart_1; + ivar3 = structdump_370.intpart_0; + svar0 = structdump_370.stringpart_0; + } + if ((arg0 == 17) && (getSkillActualLvl(arg0) == 39)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_371 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_371.intpart_1; + ivar3 = structdump_371.intpart_0; + svar0 = structdump_371.stringpart_0; + } + if (bitconfig_998 >= 9) { + ivar4 = 0; + } + break; + case 124: + if ((arg0 == 22) && (getSkillActualLvl(arg0) == 62)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_372 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_372.intpart_1; + ivar3 = structdump_372.intpart_0; + svar0 = structdump_372.stringpart_0; + } + if ((arg0 == 24) && (getSkillActualLvl(arg0) == 50)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_373 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_373.intpart_1; + ivar3 = structdump_373.intpart_0; + svar0 = structdump_373.stringpart_0; + } + if ((arg0 == 18) && (getSkillActualLvl(arg0) == 61)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_374 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_374.intpart_1; + ivar3 = structdump_374.intpart_0; + svar0 = structdump_374.stringpart_0; + } + if ((arg0 == 23) && (getSkillActualLvl(arg0) == 65)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_375 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_375.intpart_1; + ivar3 = structdump_375.intpart_0; + svar0 = structdump_375.stringpart_0; + } + if ((arg0 == 13) && (getSkillActualLvl(arg0) == 74)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_376 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_376.intpart_1; + ivar3 = structdump_376.intpart_0; + svar0 = structdump_376.stringpart_0; + } + if (((boolean)arg0) && (getSkillActualLvl(arg0) == 76)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_377 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_377.intpart_1; + ivar3 = structdump_377.intpart_0; + svar0 = structdump_377.stringpart_0; + } + if ((arg0 == 17) && (getSkillActualLvl(arg0) == 74)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_378 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_378.intpart_1; + ivar3 = structdump_378.intpart_0; + svar0 = structdump_378.stringpart_0; + } + if (bitconfig_8961 >= 200) { + ivar4 = 0; + } + break; + case 125: + if ((arg0 == 10) && (getSkillActualLvl(arg0) == 70)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_379 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_379.intpart_1; + ivar3 = structdump_379.intpart_0; + svar0 = structdump_379.stringpart_0; + } + if ((arg0 == 21) && (getSkillActualLvl(arg0) == 67)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_380 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_380.intpart_1; + ivar3 = structdump_380.intpart_0; + svar0 = structdump_380.stringpart_0; + } + if ((arg0 == 17) && (getSkillActualLvl(arg0) == 70)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_381 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_381.intpart_1; + ivar3 = structdump_381.intpart_0; + svar0 = structdump_381.stringpart_0; + } + if (bitconfig_9369 == 50) { + ivar4 = 0; + } + break; + case 126: + if (((boolean)arg0) && (getSkillActualLvl(arg0) == 60)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_382 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_382.intpart_1; + ivar3 = structdump_382.intpart_0; + svar0 = structdump_382.stringpart_0; + } + if ((arg0 == 3) && (getSkillActualLvl(arg0) == 50)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_383 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_383.intpart_1; + ivar3 = structdump_383.intpart_0; + svar0 = structdump_383.stringpart_0; + } + if ((arg0 == 15) && (getSkillActualLvl(arg0) == 47)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_384 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_384.intpart_1; + ivar3 = structdump_384.intpart_0; + svar0 = structdump_384.stringpart_0; + } + if ((arg0 == 23) && (getSkillActualLvl(arg0) == 45)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_385 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_385.intpart_1; + ivar3 = structdump_385.intpart_0; + svar0 = structdump_385.stringpart_0; + } + if ((arg0 == 24) && (getSkillActualLvl(arg0) == 35)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_386 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_386.intpart_1; + ivar3 = structdump_386.intpart_0; + svar0 = structdump_386.stringpart_0; + } + if (bitconfig_9491 == 250) { + ivar4 = 0; + } + break; + case 127: + if ((arg0 == 16) && (getSkillActualLvl(arg0) == 63)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_387 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_387.intpart_1; + ivar3 = structdump_387.intpart_0; + svar0 = structdump_387.stringpart_0; + } + if ((arg0 == 8) && (getSkillActualLvl(arg0) == 76)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_388 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_388.intpart_1; + ivar3 = structdump_388.intpart_0; + svar0 = structdump_388.stringpart_0; + } + if ((arg0 == 19) && (getSkillActualLvl(arg0) == 63)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_389 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_389.intpart_1; + ivar3 = structdump_389.intpart_0; + svar0 = structdump_389.stringpart_0; + } + if ((arg0 == 9) && (getSkillActualLvl(arg0) == 70)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_390 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_390.intpart_1; + ivar3 = structdump_390.intpart_0; + svar0 = structdump_390.stringpart_0; + } + if ((arg0 == 12) && (getSkillActualLvl(arg0) == 64)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_391 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_391.intpart_1; + ivar3 = structdump_391.intpart_0; + svar0 = structdump_391.stringpart_0; + } + if ((arg0 == 18) && (getSkillActualLvl(arg0) == 67)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_392 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_392.intpart_1; + ivar3 = structdump_392.intpart_0; + svar0 = structdump_392.stringpart_0; + } + if ((arg0 == 6) && (getSkillActualLvl(arg0) == 70)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_393 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_393.intpart_1; + ivar3 = structdump_393.intpart_0; + svar0 = structdump_393.stringpart_0; + } + if (bitconfig_9757 == 170) { + ivar4 = 0; + } + break; + case 128: + if ((arg0 == 16) && (getSkillActualLvl(arg0) == 77)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_394 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_394.intpart_1; + ivar3 = structdump_394.intpart_0; + svar0 = structdump_394.stringpart_0; + } + if ((arg0 == 12) && (getSkillActualLvl(arg0) == 76)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_395 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_395.intpart_1; + ivar3 = structdump_395.intpart_0; + svar0 = structdump_395.stringpart_0; + } + if ((arg0 == 14) && (getSkillActualLvl(arg0) == 76)) { + stack_dump0 = arg0; + stack_dump1 = ivar2; + stack_dump2 = arg1; + structdump_396 = script_1025(stack_dump0, stack_dump1, stack_dump2); + ivar4 = structdump_396.intpart_1; + ivar3 = structdump_396.intpart_0; + svar0 = structdump_396.stringpart_0; + } + if (bitconfig_9829 == 400) { + ivar4 = 0; + } + break; + default: + ivar4 = -1; + } + return newstruct cs2func_script_1023_struct(ivar3, ivar4, svar0); +} diff --git a/dumps/scripts/1024.cs2 b/dumps/scripts/1024.cs2 new file mode 100644 index 0000000..4ed9f4a --- /dev/null +++ b/dumps/scripts/1024.cs2 @@ -0,0 +1,652 @@ +int script_1024(int arg0) { + switch (arg0) { + case 0: + if (getSkillActualLvl(14) >= 10) { + return 1; + } + break; + case 1: + if ((getSkillActualLvl(0) >= 15) && (getSkillActualLvl(5) >= 25)) { + return 1; + } + break; + case 2: + if (((getSkillActualLvl(1) >= 30) && (getSkillActualLvl(14) >= 40)) && (getSkillActualLvl(13) >= 50)) { + return 1; + } + break; + case 3: + if (((getSkillActualLvl(7) >= 30) && (getSkillActualLvl(9) >= 5)) && (getSkillActualLvl(4) >= 30)) { + return 1; + } + break; + case 4: + if (((getSkillActualLvl(16) >= 42) && (getSkillActualLvl(12) >= 45)) && ((getSkillActualLvl(4) >= 40) && (getSkillActualLvl(13) >= 50))) { + return 1; + } + break; + case 5: + if ((getSkillActualLvl(12) >= 20) && (getSkillActualLvl(17) >= 25)) { + return 1; + } + break; + case 6: + if ((((getSkillActualLvl(16) >= 26) && (getSkillActualLvl(22) >= 5)) && ((getSkillActualLvl(12) >= 32) && (getSkillActualLvl(6) >= 33))) && (((getSkillActualLvl(14) >= 20) && (getSkillActualLvl(2) >= 40)) && (getSkillActualLvl(17) >= 22))) { + return 1; + } + break; + case 7: + if (((getSkillActualLvl(11) >= 50) && (getSkillActualLvl(6) >= 50)) && ((getSkillActualLvl(18) >= 10) && (getSkillActualLvl(17) >= 53))) { + return 1; + } + break; + case 8: + if (((getSkillActualLvl(9) >= 50) && (getSkillActualLvl(20) >= 50)) && (getSkillActualLvl(13) >= 65)) { + return 1; + } + break; + case 9: + if (((getSkillActualLvl(16) >= 10) && (getSkillActualLvl(15) >= 10)) && (getSkillActualLvl(17) >= 25)) { + return 1; + } + break; + case 10: + if (getSkillActualLvl(15) >= 31) { + return 1; + } + break; + case 11: + if (getSkillActualLvl(21) >= 27) { + return 1; + } + break; + case 12: + if (((getSkillActualLvl(12) >= 20) && (getSkillActualLvl(14) >= 20)) && (getSkillActualLvl(13) >= 20)) { + return 1; + } + break; + case 13: + if (((getSkillActualLvl(12) >= 50) && (getSkillActualLvl(11) >= 45)) && ((getSkillActualLvl(6) >= 39) && (getSkillActualLvl(5) >= 43))) { + return 1; + } + break; + case 14: + if (((getSkillActualLvl(19) >= 49) && (getSkillActualLvl(15) >= 57)) && (getSkillActualLvl(17) >= 40)) { + return 1; + } + break; + case 15: + if (((getSkillActualLvl(12) >= 40) && (getSkillActualLvl(6) >= 59)) && ((getSkillActualLvl(14) >= 40) && (getSkillActualLvl(13) >= 40))) { + return 1; + } + break; + case 16: + if (getSkillActualLvl(10) >= 10) { + return 1; + } + break; + case 17: + if ((getSkillActualLvl(7) >= 22) && (getSkillActualLvl(19) >= 17)) { + return 1; + } + break; + case 18: + if (((getSkillActualLvl(12) >= 40) && (getSkillActualLvl(9) >= 25)) && (getSkillActualLvl(8) >= 40)) { + return 1; + } + break; + case 19: + if (getSkillActualLvl(19) >= 25) { + return 1; + } + break; + case 20: + if ((getSkillActualLvl(16) >= 25) && (getSkillActualLvl(7) >= 20)) { + return 1; + } + break; + case 21: + if (((getSkillActualLvl(12) >= 12) && (getSkillActualLvl(11) >= 16)) && ((getSkillActualLvl(6) >= 33) && (getSkillActualLvl(17) >= 14))) { + return 1; + } + break; + case 22: + if ((getSkillActualLvl(12) >= 20) && (getSkillActualLvl(17) >= 25)) { + return 1; + } + break; + case 23: + if (getSkillActualLvl(16) >= 25) { + return 1; + } + break; + case 24: + if ((getSkillActualLvl(12) >= 49) && (getSkillActualLvl(17) >= 17)) { + return 1; + } + break; + case 25: + if ((getSkillActualLvl(16) >= 15) && (getSkillActualLvl(12) >= 35)) { + return 1; + } + break; + case 26: + if (((getSkillActualLvl(7) >= 53) && (getSkillActualLvl(10) >= 53)) && ((getSkillActualLvl(15) >= 25) && (getSkillActualLvl(14) >= 50))) { + return 1; + } + break; + case 27: + if (getSkillActualLvl(16) >= 35) { + return 1; + } + break; + case 28: + if (((getSkillActualLvl(12) >= 25) && (getSkillActualLvl(6) >= 7)) && (getSkillActualLvl(14) >= 15)) { + return 1; + } + break; + case 29: + if (getSkillActualLvl(15) >= 3) { + return 1; + } + break; + case 30: + if (((((getSkillActualLvl(16) >= 50) && (getSkillActualLvl(12) >= 50)) && ((getSkillActualLvl(15) >= 45) && (getSkillActualLvl(6) >= 56))) && (((getSkillActualLvl(14) >= 52) && (getSkillActualLvl(5) >= 42)) && ((getSkillActualLvl(13) >= 50) && (getSkillActualLvl(2) >= 50)))) && ((getSkillActualLvl(17) >= 50) && (getSkillActualLvl(8) >= 50))) { + return 1; + } + break; + case 31: + if ((getSkillActualLvl(12) >= 31) && (getSkillActualLvl(8) >= 36)) { + return 1; + } + break; + case 32: + if (((getSkillActualLvl(16) >= 13) && (getSkillActualLvl(14) >= 17)) && (getSkillActualLvl(17) >= 13)) { + return 1; + } + break; + case 33: + if ((((getSkillActualLvl(12) >= 61) && (getSkillActualLvl(1) >= 40)) && ((getSkillActualLvl(11) >= 49) && (getSkillActualLvl(15) >= 5))) && (((getSkillActualLvl(6) >= 65) && (getSkillActualLvl(14) >= 60)) && (getSkillActualLvl(8) >= 55))) { + return 1; + } + break; + case 34: + if (((getSkillActualLvl(12) >= 20) && (getSkillActualLvl(6) >= 7)) && (getSkillActualLvl(13) >= 40)) { + return 1; + } + break; + case 35: + if (getSkillActualLvl(17) >= 30) { + return 1; + } + break; + case 36: + if (getSkillActualLvl(16) >= 20) { + return 1; + } + break; + case 37: + if ((getSkillActualLvl(4) >= 60) && (getSkillActualLvl(17) >= 50)) { + return 1; + } + break; + case 38: + if (getSkillActualLvl(16) >= 25) { + return 1; + } + break; + case 39: + if ((getSkillActualLvl(19) >= 29) && (getSkillActualLvl(8) >= 10)) { + return 1; + } + break; + case 40: + if (getSkillActualLvl(12) >= 18) { + return 1; + } + break; + case 41: + if (((getSkillActualLvl(16) >= 36) && (getSkillActualLvl(12) >= 25)) && ((getSkillActualLvl(15) >= 18) && (getSkillActualLvl(13) >= 30))) { + return 1; + } + break; + case 42: + if (getSkillActualLvl(16) >= 56) { + return 1; + } + break; + case 43: + if ((getSkillActualLvl(16) >= 40) && (getSkillActualLvl(18) >= 40)) { + return 1; + } + break; + case 44: + if (getSkillActualLvl(5) >= 31) { + return 1; + } + break; + case 45: + if (getSkillActualLvl(11) >= 30) { + return 1; + } + break; + case 46: + if ((getSkillActualLvl(12) >= 20) && (getSkillActualLvl(15) >= 15)) { + return 1; + } + break; + case 47: + if (getSkillActualLvl(12) >= 30) { + return 1; + } + break; + case 48: + if ((getSkillActualLvl(16) >= 32) && (getSkillActualLvl(12) >= 20)) { + return 1; + } + break; + case 49: + if (((getSkillActualLvl(6) >= 33) && (getSkillActualLvl(14) >= 37)) && ((getSkillActualLvl(4) >= 37) && (getSkillActualLvl(17) >= 37))) { + return 1; + } + break; + case 50: + if ((((getSkillActualLvl(7) >= 62) && (getSkillActualLvl(12) >= 40)) && ((getSkillActualLvl(11) >= 42) && (getSkillActualLvl(10) >= 62))) && ((getSkillActualLvl(6) >= 66) && (getSkillActualLvl(13) >= 45))) { + return 1; + } + break; + case 51: + if (((getSkillActualLvl(16) >= 15) && (getSkillActualLvl(7) >= 30)) && (getSkillActualLvl(10) >= 5)) { + return 1; + } + break; + case 52: + if (((getSkillActualLvl(12) >= 20) && (getSkillActualLvl(11) >= 49)) && (getSkillActualLvl(14) >= 20)) { + return 1; + } + break; + case 53: + if ((getSkillActualLvl(4) >= 40) && (getSkillActualLvl(17) >= 42)) { + return 1; + } + break; + case 54: + if ((getSkillActualLvl(9) >= 10) && (getSkillActualLvl(13) >= 20)) { + return 1; + } + break; + case 55: + if (getSkillActualLvl(17) >= 21) { + return 1; + } + break; + case 56: + if (getSkillActualLvl(16) >= 28) { + return 1; + } + break; + case 57: + if (getSkillActualLvl(16) >= 15) { + return 1; + } + break; + case 58: + if (getSkillActualLvl(4) >= 25) { + return 1; + } + break; + case 59: + if ((((getSkillActualLvl(16) >= 25) && (getSkillActualLvl(15) >= 14)) && ((getSkillActualLvl(6) >= 14) && (getSkillActualLvl(14) >= 40))) && (getSkillActualLvl(17) >= 15)) { + return 1; + } + break; + case 60: + if (getSkillActualLvl(0) >= 20) { + return 1; + } + break; + case 61: + if ((getSkillActualLvl(22) >= 5) && (getSkillActualLvl(6) >= 46)) { + return 1; + } + break; + case 62: + if ((getSkillActualLvl(16) >= 23) && (getSkillActualLvl(17) >= 23)) { + return 1; + } + break; + case 63: + if (((getSkillActualLvl(12) >= 19) && (getSkillActualLvl(4) >= 30)) && ((getSkillActualLvl(18) >= 18) && (getSkillActualLvl(8) >= 35))) { + return 1; + } + break; + case 64: + if ((getSkillActualLvl(6) >= 20) && (getSkillActualLvl(13) >= 30)) { + return 1; + } + break; + case 65: + if (((getSkillActualLvl(12) >= 36) && (getSkillActualLvl(19) >= 30)) && (getSkillActualLvl(11) >= 20)) { + return 1; + } + break; + case 66: + if (((getSkillActualLvl(22) >= 30) && (getSkillActualLvl(12) >= 16)) && (getSkillActualLvl(5) >= 50)) { + return 1; + } + break; + case 67: + if (((getSkillActualLvl(12) >= 30) && (getSkillActualLvl(20) >= 30)) && ((getSkillActualLvl(18) >= 30) && (getSkillActualLvl(17) >= 30))) { + return 1; + } + break; + case 68: + if (((getSkillActualLvl(16) >= 30) && (getSkillActualLvl(22) >= 34)) && ((getSkillActualLvl(12) >= 30) && (getSkillActualLvl(21) >= 10))) { + return 1; + } + break; + case 69: + if (((getSkillActualLvl(16) >= 40) && (getSkillActualLvl(22) >= 20)) && ((getSkillActualLvl(12) >= 46) && (getSkillActualLvl(8) >= 56))) { + return 1; + } + break; + case 70: + if (getSkillActualLvl(22) >= 10) { + return 1; + } + break; + case 71: + if (getSkillActualLvl(20) >= 35) { + return 1; + } + break; + case 72: + if ((getSkillActualLvl(11) >= 40) && (getSkillActualLvl(8) >= 50)) { + return 1; + } + break; + case 73: + if ((((getSkillActualLvl(16) >= 59) && (getSkillActualLvl(19) >= 45)) && ((getSkillActualLvl(15) >= 52) && (getSkillActualLvl(17) >= 58))) && (getSkillActualLvl(8) >= 71)) { + return 1; + } + break; + case 74: + if ((getSkillActualLvl(6) >= 45) && (getSkillActualLvl(1) >= 65)) { + return 1; + } + break; + case 75: + if ((((getSkillActualLvl(16) >= 45) && (getSkillActualLvl(4) >= 47)) && ((getSkillActualLvl(18) >= 56) && (getSkillActualLvl(17) >= 56))) && (getSkillActualLvl(2) >= 60)) { + return 1; + } + break; + case 76: + if (((getSkillActualLvl(16) >= 55) && (getSkillActualLvl(19) >= 53)) && ((getSkillActualLvl(18) >= 59) && (getSkillActualLvl(8) >= 72))) { + return 1; + } + break; + case 77: + if ((((getSkillActualLvl(5) >= 30) && (getSkillActualLvl(16) >= 36)) && ((getSkillActualLvl(17) >= 36) && (getSkillActualLvl(10) >= 36))) && (getSkillActualLvl(15) >= 37)) { + return 1; + } + break; + case 78: + if (getSkillActualLvl(7) >= 10) { + return 1; + } + break; + case 79: + if (getSkillActualLvl(7) >= 31) { + return 1; + } + break; + case 80: + if (getSkillActualLvl(7) >= 40) { + return 1; + } + break; + case 81: + if (getSkillActualLvl(7) >= 25) { + return 1; + } + break; + case 82: + if ((getSkillActualLvl(7) >= 41) && (getSkillActualLvl(11) >= 20)) { + return 1; + } + break; + case 83: + if ((getSkillActualLvl(7) >= 70) && (getSkillActualLvl(16) >= 48)) { + return 1; + } + break; + case 84: + if (((getSkillActualLvl(21) >= 48) && (getSkillActualLvl(11) >= 51)) && (getSkillActualLvl(8) >= 58)) { + return 1; + } + break; + case 85: + if (getSkillActualLvl(14) >= 46) { + return 1; + } + break; + case 86: + if ((getSkillActualLvl(22) >= 44) && (getSkillActualLvl(9) >= 42)) { + return 1; + } + break; + case 87: + if (((getSkillActualLvl(16) >= 50) && (getSkillActualLvl(11) >= 21)) && ((getSkillActualLvl(17) >= 60) && (getSkillActualLvl(2) >= 60))) { + return 1; + } + break; + case 88: + if ((((getSkillActualLvl(12) >= 42) && (getSkillActualLvl(19) >= 40)) && ((getSkillActualLvl(10) >= 50) && (getSkillActualLvl(5) >= 47))) && (getSkillActualLvl(18) >= 42)) { + return 1; + } + break; + case 89: + if ((((getSkillActualLvl(22) >= 20) && (getSkillActualLvl(16) >= 29)) && ((getSkillActualLvl(12) >= 47) && (getSkillActualLvl(6) >= 49))) && (((getSkillActualLvl(14) >= 35) && (getSkillActualLvl(18) >= 31)) && (getSkillActualLvl(11) >= 40))) { + return 1; + } + break; + case 90: + if ((((getSkillActualLvl(0) >= 40) && (getSkillActualLvl(14) >= 41)) && ((getSkillActualLvl(12) >= 43) && (getSkillActualLvl(2) >= 45))) && (getSkillActualLvl(22) >= 50)) { + return 1; + } + break; + case 91: + if (((getSkillActualLvl(22) >= 10) && (getSkillActualLvl(19) >= 10)) && ((getSkillActualLvl(21) >= 10) && (getSkillActualLvl(17) >= 11))) { + return 1; + } + break; + case 92: + if (((getSkillActualLvl(18) >= 35) && (getSkillActualLvl(12) >= 25)) && (script_1432() >= 85)) { + return 1; + } + break; + case 93: + if (((getSkillActualLvl(16) >= 60) && (getSkillActualLvl(17) >= 63)) && ((getSkillActualLvl(12) >= 66) && (getSkillActualLvl(13) >= 69))) { + return 1; + } + break; + case 94: + if (((getSkillActualLvl(22) >= 40) && (getSkillActualLvl(19) >= 26)) && ((getSkillActualLvl(5) >= 35) && (getSkillActualLvl(23) >= 19))) { + return 1; + } + break; + case 95: + if (getSkillActualLvl(11) >= 43) { + return 1; + } + break; + case 96: + if ((((getSkillActualLvl(11) >= 47) && (getSkillActualLvl(21) >= 35)) && ((getSkillActualLvl(14) >= 45) && (getSkillActualLvl(5) >= 55))) && ((getSkillActualLvl(23) >= 23) && (getSkillActualLvl(8) >= 37))) { + return 1; + } + break; + case 97: + if (((getSkillActualLvl(21) >= 51) && (getSkillActualLvl(16) >= 51)) && ((getSkillActualLvl(13) >= 54) && (getSkillActualLvl(14) >= 59))) { + return 1; + } + break; + case 98: + if ((((getSkillActualLvl(1) >= 65) && (getSkillActualLvl(6) >= 75)) && ((getSkillActualLvl(15) >= 65) && (getSkillActualLvl(17) >= 60))) && (((getSkillActualLvl(21) >= 55) && (getSkillActualLvl(19) >= 65)) && ((getSkillActualLvl(23) >= 23) && ((boolean)script_395())))) { + return 1; + } + break; + case 99: + if (((getSkillActualLvl(11) >= 55) && (getSkillActualLvl(9) >= 53)) && (getSkillActualLvl(12) >= 52)) { + return 1; + } + break; + case 100: + if (((getSkillActualLvl(17) >= 46) && (getSkillActualLvl(16) >= 46)) && (getSkillActualLvl(2) >= 46)) { + return 1; + } + break; + case 101: + if (((getSkillActualLvl(21) >= 41) && (getSkillActualLvl(16) >= 50)) && ((getSkillActualLvl(6) >= 57) && (getSkillActualLvl(15) >= 43))) { + return 1; + } + break; + case 102: + if (((getSkillActualLvl(8) >= 10) && (getSkillActualLvl(6) >= 10)) && ((getSkillActualLvl(14) >= 8) && (getSkillActualLvl(11) >= 6))) { + return 1; + } + break; + case 103: + if ((((getSkillActualLvl(22) >= 35) && (getSkillActualLvl(7) >= 35)) && ((getSkillActualLvl(12) >= 35) && (getSkillActualLvl(5) >= 35))) && (getSkillActualLvl(6) >= 35)) { + return 1; + } + break; + case 104: + if (((getSkillActualLvl(17) >= 38) && (getSkillActualLvl(22) >= 45)) && (getSkillActualLvl(21) >= 45)) { + return 1; + } + break; + case 105: + if ((((getSkillActualLvl(23) >= 41) && (getSkillActualLvl(14) >= 64)) && ((getSkillActualLvl(18) >= 37) && (getSkillActualLvl(16) >= 61))) && (((getSkillActualLvl(2) >= 64) && (getSkillActualLvl(4) >= 64)) && (getSkillActualLvl(17) >= 66))) { + return 1; + } + break; + case 106: + if (((getSkillActualLvl(21) >= 61) && (getSkillActualLvl(11) >= 61)) && (getSkillActualLvl(2) >= 69)) { + return 1; + } + break; + case 107: + if (((getSkillActualLvl(16) >= 69) && (getSkillActualLvl(9) >= 70)) && ((getSkillActualLvl(4) >= 75) && (getSkillActualLvl(8) >= 75))) { + return 1; + } + break; + case 108: + if (getSkillActualLvl(5) >= 50) { + return 1; + } + break; + case 109: + if (((getSkillActualLvl(0) >= 75) && (getSkillActualLvl(2) >= 75)) && (getSkillActualLvl(18) >= 65)) { + return 1; + } + break; + case 110: + if ((((getSkillActualLvl(6) >= 75) && (getSkillActualLvl(5) >= 70)) && ((getSkillActualLvl(14) >= 66) && (getSkillActualLvl(21) >= 65))) && (getSkillActualLvl(22) >= 60)) { + return 1; + } + break; + case 111: + if (((getSkillActualLvl(6) >= 27) && (getSkillActualLvl(20) >= 20)) && (getSkillActualLvl(22) >= 25)) { + return 1; + } + break; + case 112: + if (getSkillActualLvl(17) >= 24) { + return 1; + } + break; + case 113: + if (getSkillActualLvl(17) >= 41) { + return 1; + } + break; + case 114: + if (((getSkillActualLvl(17) >= 62) && (getSkillActualLvl(15) >= 45)) && (getSkillActualLvl(16) >= 40)) { + return 1; + } + break; + case 115: + if ((((getSkillActualLvl(19) >= 54) && (getSkillActualLvl(17) >= 51)) && ((getSkillActualLvl(6) >= 59) && (getSkillActualLvl(23) >= 37))) && (getSkillActualLvl(12) >= 36)) { + return 1; + } + break; + case 116: + if ((getSkillActualLvl(1) >= 33) && (getSkillActualLvl(13) >= 33)) { + return 1; + } + break; + case 117: + if ((getSkillActualLvl(2) >= 42) && (getSkillActualLvl(0) >= 35)) { + return 1; + } + break; + case 118: + if (((getSkillActualLvl(6) >= 77) && (getSkillActualLvl(22) >= 68)) && ((getSkillActualLvl(13) >= 68) && (getSkillActualLvl(12) >= 67))) { + return 1; + } + break; + case 119: + if ((((getSkillActualLvl(22) >= 47) && (getSkillActualLvl(15) >= 49)) && ((getSkillActualLvl(21) >= 46) && (getSkillActualLvl(14) >= 47))) && (((getSkillActualLvl(23) >= 48) && (getSkillActualLvl(17) >= 54)) && (getSkillActualLvl(8) >= 52))) { + return 1; + } + break; + case 120: + if (((((getSkillActualLvl(0) >= 78) && (getSkillActualLvl(22) >= 70)) && ((getSkillActualLvl(12) >= 70) && (getSkillActualLvl(11) >= 71))) && (((getSkillActualLvl(6) >= 80) && (getSkillActualLvl(13) >= 70)) && ((getSkillActualLvl(2) >= 78) && (getSkillActualLvl(23) >= 55)))) && (getSkillActualLvl(1) >= 10)) { + return 1; + } + break; + case 121: + if (((getSkillActualLvl(2) >= 77) && (getSkillActualLvl(13) >= 70)) && (getSkillActualLvl(14) >= 68)) { + return 1; + } + break; + case 122: + if (((getSkillActualLvl(16) >= 64) && (getSkillActualLvl(17) >= 64)) && ((getSkillActualLvl(22) >= 62) && (getSkillActualLvl(20) >= 61))) { + return 1; + } + break; + case 123: + if ((((getSkillActualLvl(1) >= 40) && (getSkillActualLvl(12) >= 41)) && ((getSkillActualLvl(20) >= 39) && (getSkillActualLvl(13) >= 42))) && (getSkillActualLvl(17) >= 39)) { + return 1; + } + break; + case 124: + if ((((getSkillActualLvl(22) >= 62) && (getSkillActualLvl(24) >= 50)) && ((getSkillActualLvl(18) >= 61) && (getSkillActualLvl(23) >= 65))) && (((getSkillActualLvl(13) >= 74) && (getSkillActualLvl(1) >= 76)) && (getSkillActualLvl(17) >= 74))) { + return 1; + } + break; + case 125: + if (((getSkillActualLvl(10) >= 70) && (getSkillActualLvl(21) >= 67)) && (getSkillActualLvl(17) >= 70)) { + return 1; + } + break; + case 126: + if ((((getSkillActualLvl(1) >= 60) && (getSkillActualLvl(3) >= 50)) && ((getSkillActualLvl(15) >= 47) && (getSkillActualLvl(23) >= 45))) && (getSkillActualLvl(24) >= 35)) { + return 1; + } + break; + case 127: + if ((((getSkillActualLvl(16) >= 63) && (getSkillActualLvl(8) >= 76)) && ((getSkillActualLvl(19) >= 63) && (getSkillActualLvl(9) >= 70))) && (((getSkillActualLvl(12) >= 64) && (getSkillActualLvl(18) >= 67)) && (getSkillActualLvl(6) == 70))) { + return 1; + } + break; + case 128: + if (((getSkillActualLvl(16) >= 77) && (getSkillActualLvl(14) >= 76)) && (getSkillActualLvl(12) >= 76)) { + return 1; + } + break; + default: + return 0; + } + return 0; +} diff --git a/dumps/scripts/1025.cs2 b/dumps/scripts/1025.cs2 new file mode 100644 index 0000000..33f9228 --- /dev/null +++ b/dumps/scripts/1025.cs2 @@ -0,0 +1,17 @@ +cs2func_script_1025_struct(2,1,0) script_1025(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + string svar0; + svar0 = "null"; + ivar3 = -1; + ivar4 = 1; + if (((boolean)script_1024(arg2))) { + svar0 = "" + "Level " + intToStr(arg1) + " " + "" + getCommonString(680, arg0) + "" + " is one of the requirements for " + "" + getCommonString(1481, arg2) + "" + "."; + } else { + svar0 = "" + "You now have all the levels you need to complete " + "" + getCommonString(1481, arg2) + "" + "."; + } + if (ivar3 == -1) { + ivar3 = 6513; + } + return newstruct cs2func_script_1025_struct(ivar3, ivar4, svar0); +} diff --git a/dumps/scripts/1026.cs2 b/dumps/scripts/1026.cs2 new file mode 100644 index 0000000..628f5d1 --- /dev/null +++ b/dumps/scripts/1026.cs2 @@ -0,0 +1,4 @@ +void script_1026() { + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(157,30)); + return; +} diff --git a/dumps/scripts/1027.cs2 b/dumps/scripts/1027.cs2 new file mode 100644 index 0000000..e057437 --- /dev/null +++ b/dumps/scripts/1027.cs2 @@ -0,0 +1,4 @@ +void script_1027() { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(157,30)); + return; +} diff --git a/dumps/scripts/1028.cs2 b/dumps/scripts/1028.cs2 new file mode 100644 index 0000000..afc14b0 --- /dev/null +++ b/dumps/scripts/1028.cs2 @@ -0,0 +1,4 @@ +void script_1028() { + script_1029(1484, 9); + return; +} diff --git a/dumps/scripts/1029.cs2 b/dumps/scripts/1029.cs2 new file mode 100644 index 0000000..47c1405 --- /dev/null +++ b/dumps/scripts/1029.cs2 @@ -0,0 +1,48 @@ +void script_1029(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + string svar0; + deleteAllExtraChilds(new WidgetPointer(157,23)); + deleteAllExtraChilds(new WidgetPointer(157,25)); + setWidgetText(new WidgetPointer(157,14), "Quick-chat - Shortcut Reference"); + setWidgetIsHidden(false, new WidgetPointer(157,35)); + setWidgetIsHidden(true, new WidgetPointer(157,17)); + setScriptCallOnMousePressed(784, 1486, 0, 7, "gii", new WidgetPointer(157,30)); + setWidgetText(new WidgetPointer(157,30), "User Guide"); + ivar2 = 0; + ivar3 = 20; + ivar4 = 0; + ivar5 = 0; + ivar6 = 0; + svar0 = ""; + createExtraChild(new WidgetPointer(157,25), 5, ivar4); + setWidgetSprite(1074); + setWidgetPosition(35, subtract(ivar3, 22), 0, 0); + setWidgetSize(400, 32, 0, 0); + ivar4 = add(ivar4, 1); + while (ivar2 < arg1) { + ivar2 = add(ivar2, 1); + script_1034(ivar4, 35, ivar3, 400, 100, 16776960, cs2method_3408(105, 115, arg0, ivar5)); + ivar4 = add(ivar4, 1); + ivar5 = add(ivar5, 1); + svar0 = cs2method_3408(105, 115, arg0, ivar5); + ivar6 = multiply(getLineCount(300, 495, svar0), 12); + script_1034(ivar4, 150, ivar3, 300, ivar6, 16777215, svar0); + ivar4 = add(ivar4, 1); + ivar5 = add(ivar5, 1); + ivar3 = add(add(ivar3, ivar6), 10); + createExtraChild(new WidgetPointer(157,25), 5, ivar4); + setWidgetSprite(1074); + setWidgetPosition(35, subtract(ivar3, 20), 0, 0); + setWidgetSize(400, 32, 0, 0); + ivar4 = add(ivar4, 1); + } + if (ivar3 > getWidgetActualHeight(new WidgetPointer(157,25))) { + setWidgetScrollMax(0, ivar3, new WidgetPointer(157,25)); + script_31(10289176, 10289177, 792, 789, 790, 791, 773, 788); + } + return; +} diff --git a/dumps/scripts/103.cs2 b/dumps/scripts/103.cs2 new file mode 100644 index 0000000..e4b4407 --- /dev/null +++ b/dumps/scripts/103.cs2 @@ -0,0 +1,22 @@ +void script_103() { + if (((boolean)globalint_1413)) { + return; + } + if (((boolean)globalint_11)) { + script_675(); + } + if (getDisplayMode() >= 2) { + setWidgetIsHidden(false, new WidgetPointer(746,73)); + } + setWidgetIsHidden(false, new WidgetPointer(752,3)); + setWidgetIsHidden(true, new WidgetPointer(752,7)); + setWidgetIsHidden(true, new WidgetPointer(752,8)); + setWidgetText(new WidgetPointer(752,4), "Enter name of friend to add to list"); + globalint_5 = 2; + script_1564(""); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(752,3)); + script_2026(); + setScriptCallOnKeyPress(112, -2147483640, false, "iz", new WidgetPointer(752,5)); + script_1188(); + return; +} diff --git a/dumps/scripts/1030.cs2 b/dumps/scripts/1030.cs2 new file mode 100644 index 0000000..8125b25 --- /dev/null +++ b/dumps/scripts/1030.cs2 @@ -0,0 +1,10 @@ +void script_1030(int arg0) { + setWidgetIsHidden(true, new WidgetPointer(157,17)); + setWidgetIsHidden(false, new WidgetPointer(157,35)); + deleteAllExtraChilds(new WidgetPointer(157,23)); + deleteAllExtraChilds(new WidgetPointer(157,25)); + setScriptCallOnMousePressed(1031, "", new WidgetPointer(157,30)); + setWidgetText(new WidgetPointer(157,30), "Safety Guide"); + script_1033(cs2method_3408(105, 115, 1485, 0)); + return; +} diff --git a/dumps/scripts/1031.cs2 b/dumps/scripts/1031.cs2 new file mode 100644 index 0000000..96e41ca --- /dev/null +++ b/dumps/scripts/1031.cs2 @@ -0,0 +1,4 @@ +void script_1031() { + cs2method5400(0, "www", "kbase/viewcategory.ws?cat_id=827"); + return; +} diff --git a/dumps/scripts/1032.cs2 b/dumps/scripts/1032.cs2 new file mode 100644 index 0000000..e31186d --- /dev/null +++ b/dumps/scripts/1032.cs2 @@ -0,0 +1,31 @@ +void script_1032(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + cs2method2100(0, 0, new WidgetPointer(157,25)); + deleteAllExtraChilds(new WidgetPointer(157,24)); + setWidgetIsHidden(false, new WidgetPointer(157,17)); + setWidgetIsHidden(false, new WidgetPointer(157,35)); + setScriptCallOnMousePressed(1028, "", new WidgetPointer(157,30)); + setWidgetText(new WidgetPointer(157,30), "Shortcut keys"); + deleteAllExtraChilds(new WidgetPointer(157,23)); + deleteAllExtraChilds(new WidgetPointer(157,25)); + script_1033(cs2method_3408(105, 115, arg0, arg1)); + setWidgetText(new WidgetPointer(157,20), "Page " + intToStr(add(arg1, 1)) + " of " + intToStr(arg2)); + ivar3 = add(arg1, 1); + ivar4 = subtract(arg1, 1); + if (arg1 != subtract(arg2, 1)) { + setScriptCallOnMousePressed(784, arg0, ivar3, arg2, "gii", new WidgetPointer(157,21)); + cs2method2103(0, new WidgetPointer(157,21)); + } else { + setScriptCallOnMousePressed(-1, "", new WidgetPointer(157,21)); + cs2method2103(200, new WidgetPointer(157,21)); + } + if (arg1 != 0) { + setScriptCallOnMousePressed(784, arg0, ivar4, arg2, "gii", new WidgetPointer(157,22)); + cs2method2103(0, new WidgetPointer(157,22)); + } else { + setScriptCallOnMousePressed(-1, "", new WidgetPointer(157,22)); + cs2method2103(200, new WidgetPointer(157,22)); + } + return; +} diff --git a/dumps/scripts/1033.cs2 b/dumps/scripts/1033.cs2 new file mode 100644 index 0000000..e0e9c28 --- /dev/null +++ b/dumps/scripts/1033.cs2 @@ -0,0 +1,30 @@ +void script_1033(string arg0) { + int ivar0; + int ivar1; + int ivar2; + string svar1; + svar1 = ""; + ivar0 = 0; + ivar0 = strIndexof(0, arg0, "|"); + if (ivar0 != -1) { + svar1 = substr(add(ivar0, 1), strLength(arg0), arg0); + } else { + svar1 = arg0; + } + setWidgetText(new WidgetPointer(157,14), substr(0, ivar0, arg0)); + ivar1 = 0; + ivar2 = 0; + ivar1 = multiply(getLineCount(400, 495, svar1), 12); + ivar2 = getWidgetActualHeight(new WidgetPointer(157,25)); + ivar2 = subtract(divide(getWidgetActualHeight(new WidgetPointer(157,25)), 2), divide(ivar1, 2)); + script_1034(0, 35, ivar2, 400, 100, 16777215, svar1); + createExtraChild(new WidgetPointer(157,25), 5, 1); + setWidgetSprite(1074); + setWidgetPosition(35, subtract(ivar2, 25), 0, 0); + setWidgetSize(400, 32, 0, 0); + createExtraChild(new WidgetPointer(157,25), 5, 2); + setWidgetSprite(1074); + setWidgetPosition(35, add(ivar2, ivar1), 0, 0); + setWidgetSize(400, 32, 0, 0); + return; +} diff --git a/dumps/scripts/1034.cs2 b/dumps/scripts/1034.cs2 new file mode 100644 index 0000000..dcfb4a6 --- /dev/null +++ b/dumps/scripts/1034.cs2 @@ -0,0 +1,10 @@ +void script_1034(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,string arg6) { + createExtraChild(new WidgetPointer(157,25), 4, arg0); + setWidgetPosition(arg1, arg2, 0, 0); + setWidgetSize(arg3, arg4, 0, 0); + setWidgetRGB(new Color(arg5)); + setWidgetUnknownBoolean(true); + setWidgetFont(495); + setWidgetText(arg6); + return; +} diff --git a/dumps/scripts/1035.cs2 b/dumps/scripts/1035.cs2 new file mode 100644 index 0000000..5a03df4 --- /dev/null +++ b/dumps/scripts/1035.cs2 @@ -0,0 +1,65 @@ +void script_1035(int arg0,int arg1,int arg2,int arg3,string arg4) { + int ivar4; + ivar4 = 0; + createExtraChild(new WidgetPointer(157,23), 5, ivar4); + setWidgetSprite(846); + setWidgetPosition(arg0, arg1, 0, 0); + setWidgetSize(32, 32, 0, 0); + ivar4 = add(ivar4, 1); + createExtraChild(new WidgetPointer(157,23), 5, ivar4); + setWidgetSprite(828); + setWidgetPosition(arg0, subtract(arg1, 14), 0, 0); + setWidgetSize(arg2, 32, 0, 0); + ivar4 = add(ivar4, 1); + createExtraChild(new WidgetPointer(157,23), 5, ivar4); + setWidgetSprite(847); + setWidgetPosition(subtract(add(arg2, arg0), 32), arg1, 0, 0); + setWidgetSize(32, 32, 0, 0); + ivar4 = add(ivar4, 1); + createExtraChild(new WidgetPointer(157,23), 5, ivar4); + setWidgetSprite(841); + setWidgetPosition(subtract(arg0, 14), arg1, 0, 0); + setWidgetSize(32, arg3, 0, 0); + ivar4 = add(ivar4, 1); + createExtraChild(new WidgetPointer(157,23), 5, ivar4); + setWidgetSprite(841); + setWidgetPosition(subtract(add(arg0, arg2), 20), arg1, 0, 0); + setWidgetSize(32, arg3, 0, 0); + ivar4 = add(ivar4, 1); + createExtraChild(new WidgetPointer(157,23), 5, ivar4); + setWidgetSprite(848); + setWidgetPosition(arg0, subtract(add(arg1, arg3), 32), 0, 0); + setWidgetSize(32, 32, 0, 0); + ivar4 = add(ivar4, 1); + createExtraChild(new WidgetPointer(157,23), 5, ivar4); + setWidgetSprite(849); + setWidgetPosition(subtract(add(arg0, arg2), 32), subtract(add(arg1, arg3), 32), 0, 0); + setWidgetSize(32, 32, 0, 0); + ivar4 = add(ivar4, 1); + createExtraChild(new WidgetPointer(157,23), 5, ivar4); + setWidgetSprite(828); + setWidgetPosition(arg0, subtract(add(arg1, arg3), 20), 0, 0); + setWidgetSize(arg2, 32, 0, 0); + ivar4 = add(ivar4, 1); + createExtraChild(new WidgetPointer(157,23), 3, ivar4); + setWidgetPosition(add(arg0, 6), add(arg1, 6), 0, 0); + setWidgetSize(subtract(arg2, 12), subtract(arg3, 12), 0, 0); + setWidgetRGB(new Color(131, 118, 94)); + setWidgetFilled(1); + ivar4 = add(ivar4, 1); + createExtraChild(new WidgetPointer(157,23), 3, ivar4); + setWidgetPosition(add(arg0, 3), add(arg1, 3), 0, 0); + setWidgetSize(arg2, arg3, 0, 0); + setWidgetRGB(new Color(0, 0, 0)); + setWidgetFilled(1); + cs2method2103(200); + ivar4 = add(ivar4, 1); + createExtraChild(new WidgetPointer(157,23), 4, ivar4); + setWidgetPosition(10, 10, 0, 0); + setWidgetSize(400, 50, 0, 0); + setWidgetRGB(new Color(255, 255, 255)); + setWidgetUnknownBoolean(true); + setWidgetFont(495); + setWidgetText(arg4); + return; +} diff --git a/dumps/scripts/1036.cs2 b/dumps/scripts/1036.cs2 new file mode 100644 index 0000000..67bb58e --- /dev/null +++ b/dumps/scripts/1036.cs2 @@ -0,0 +1,11 @@ +int script_1036() { + int ivar0; + ivar0 = -1; + if (cs2method_3408(105, 105, 1548, bitconfig_4758) > 0) { + ivar0 = cs2method_3408(105, 107, 1549, bitconfig_4758); + if (ivar0 != -1) { + return ivar0; + } + } + return cs2method_3408(105, 107, 1483, bitconfig_4759); +} diff --git a/dumps/scripts/1037.cs2 b/dumps/scripts/1037.cs2 new file mode 100644 index 0000000..bdd5871 --- /dev/null +++ b/dumps/scripts/1037.cs2 @@ -0,0 +1,43 @@ +void script_1037(int arg0,int arg1) { + string svar0; + globalint_161 = arg1; + globalint_128 = -1; + globalint_129 = 0; + globalstring_30 = ""; + svar0 = cs2method5055(arg0); + if (((boolean)globalint_126)) { + svar0 = "To " + globalstring_27 + ": " + "" + svar0; + } else if (globalint_126 == 2) { + svar0 = "[" + "" + cs2method3611() + "" + "]: " + "" + svar0; + } else if (globalint_126 == 8) { + if (cs2method3751()) { + svar0 = "[" + "" + cs2method3752() + "" + "]: " + "" + svar0; + } + } else if (globalint_126 == 10) { + if (cs2method3750()) { + svar0 = "[" + "" + cs2method3752() + "" + "]: " + "" + svar0; + } + } else { + svar0 = "" + svar0; + } + setWidgetIsHidden(true, new WidgetPointer(137,50)); + setScriptCallOnKeyPress(-1, "", new WidgetPointer(137,56)); + setWidgetIsHidden(false, new WidgetPointer(137,0)); + setWidgetIsHidden(true, new WidgetPointer(137,7)); + setWidgetIsHidden(true, new WidgetPointer(137,9)); + setWidgetIsHidden(false, new WidgetPointer(137,13)); + setWidgetIsHidden(true, new WidgetPointer(137,17)); + setWidgetIsHidden(true, new WidgetPointer(137,1)); + setWidgetIsHidden(false, new WidgetPointer(137,3)); + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(137,3)); + setWidgetFont(495, new WidgetPointer(137,3)); + setWidgetTextAlignment(0, 1, 0, new WidgetPointer(137,3)); + setWidgetText(new WidgetPointer(137,3), svar0); + setWidgetUnknownBoolean(false, new WidgetPointer(137,3)); + deleteAllExtraChilds(new WidgetPointer(137,16)); + setWidgetText(new WidgetPointer(137,14), "Search for: *"); + setScriptCallOnKeyPress(1038, -2147483640, false, new WidgetPointer(137,1), new WidgetPointer(137,14), new WidgetPointer(137,16), new WidgetPointer(137,15), arg0, 0, "izIIIIei", new WidgetPointer(137,13)); + setWidgetScrollMax(0, 0, new WidgetPointer(137,16)); + script_72(8978447, 8978448, 0); + return; +} diff --git a/dumps/scripts/1038.cs2 b/dumps/scripts/1038.cs2 new file mode 100644 index 0000000..e29555c --- /dev/null +++ b/dumps/scripts/1038.cs2 @@ -0,0 +1,117 @@ +void script_1038(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7) { + int ivar8; + int ivar9; + int ivar10; + int ivar11; + if (arg0 == 104) { + if (((boolean)arg7)) { + return; + } + if (globalint_128 <= 0) { + globalint_128 = subtract(arg7, 1); + } else { + globalint_128 = subtract(globalint_128, 1); + } + if (setWidgetRegister(new WidgetPointer(arg4), add(globalint_128, 1))) { + if (setWidgetRegister(new WidgetPointer(arg4), 0)) { + setWidgetPosition(getWidgetActualX(), getWidgetActualY(), 0, 0); + setWidgetSize(getWidgetActualWidth(), getWidgetActualHeight(), 0, 0); + setWidgetRGB(new Color(87, 126, 69)); + setWidgetFilled(1); + } + if (getWidgetActualY() < cs2method2601(new WidgetPointer(arg4))) { + script_72(arg5, arg4, subtract(cs2method2601(new WidgetPointer(arg4)), getWidgetActualHeight())); + } else { + if (add(getWidgetActualY(), getWidgetActualHeight()) > add(getWidgetActualHeight(new WidgetPointer(arg4)), cs2method2601(new WidgetPointer(arg4)))) { + script_72(arg5, arg4, getWidgetScrollMaxV(new WidgetPointer(arg4))); + } + } + } + return; + } + if (arg0 == 105) { + if (((boolean)arg7)) { + return; + } + if (globalint_128 == subtract(arg7, 1)) { + globalint_128 = 0; + } else { + globalint_128 = add(globalint_128, 1); + } + if (setWidgetRegister(new WidgetPointer(arg4), add(globalint_128, 1))) { + if (setWidgetRegister(new WidgetPointer(arg4), 0)) { + setWidgetPosition(getWidgetActualX(), getWidgetActualY(), 0, 0); + setWidgetSize(getWidgetActualWidth(), getWidgetActualHeight(), 0, 0); + setWidgetRGB(new Color(87, 126, 69)); + setWidgetFilled(1); + } + if (add(getWidgetActualY(), getWidgetActualHeight()) > add(getWidgetActualHeight(new WidgetPointer(arg4)), cs2method2601(new WidgetPointer(arg4)))) { + script_72(arg5, arg4, add(cs2method2601(new WidgetPointer(arg4)), getWidgetActualHeight())); + } else { + if (getWidgetActualY() < cs2method2601(new WidgetPointer(arg4))) { + script_72(arg5, arg4, 0); + } + } + } + return; + } + if (arg0 == 102) { + script_1050(globalint_126, globalstring_27); + return; + } + if (arg0 == 13) { + script_1054(); + return; + } + ivar8 = strLength(globalstring_30); + ivar9 = cs2method4210(globalint_161, globalstring_30); + ivar10 = 0; + ivar11 = -1; + if (arg0 == 84) { + if (globalint_128 < 0) { + if (ivar8 > 0) { + globalint_129 = 0; + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg3)); + script_1041(arg2, arg4, arg5, arg6); + } else { + script_1054(); + } + } else { + if (((ivar9 > 0) && setWidgetRegister(new WidgetPointer(arg4), add(globalint_128, 1))) && (ivar10 < ivar9)) { + while (true) { + ivar11 = cs2method4211(); + if (((boolean)stringMethod4107(getWidgetText(), getItemName(ivar11)))) { + script_1076(arg2, arg6, ivar11); + return; + } + ivar10 = add(ivar10, 1); + } + } + } + return; + } + if (arg0 == 85) { + if (ivar8 > 0) { + globalstring_30 = substr(0, subtract(ivar8, 1), globalstring_30); + } else if (((boolean)globalint_127)) { + script_1054(); + } else { + globalint_128 = -1; + setWidgetIsHidden(true, new WidgetPointer(137,7)); + setWidgetIsHidden(true, new WidgetPointer(137,9)); + setWidgetIsHidden(true, new WidgetPointer(137,13)); + setWidgetIsHidden(false, new WidgetPointer(137,17)); + setWidgetIsHidden(false, new WidgetPointer(137,1)); + setWidgetIsHidden(true, new WidgetPointer(137,3)); + return; + } + } else if (isValidChar(((char)arg1)) && (ivar8 < 80)) { + globalstring_30 = strRemoveEntities(concatChar(((char)arg1), globalstring_30)); + } else { + return; + } + setWidgetText(new WidgetPointer(arg3), "Search for: " + globalstring_30 + "*"); + globalint_129 = 50; + setScriptCallOnGameloop(1040, new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), arg6, "IIIIe", new WidgetPointer(arg3)); + return; +} diff --git a/dumps/scripts/1039.cs2 b/dumps/scripts/1039.cs2 new file mode 100644 index 0000000..4d40087 --- /dev/null +++ b/dumps/scripts/1039.cs2 @@ -0,0 +1,75 @@ +void script_1039(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + string svar0; + globalint_128 = -1; + ivar4 = cs2method4210(globalint_161, globalstring_30); + ivar5 = getWidgetActualWidth(new WidgetPointer(arg1)); + ivar6 = subtract(ivar5, 8); + if (ivar4 == -1) { + createExtraChild(new WidgetPointer(arg1), 4, 0); + setWidgetPosition(0, 48, 0, 0); + setWidgetSize(ivar5, 14, 0, 0); + setWidgetFont(495); + setWidgetText("Too many results. Please refine your search."); + setWidgetTextAlignment(1, 1, 0); + setWidgetRGB(new Color(0, 0, 0)); + setWidgetUnknownBoolean(false); + setWidgetScrollMax(0, 0, new WidgetPointer(arg1)); + script_1042(arg1, arg2); + return; + } + if (((boolean)ivar4)) { + createExtraChild(new WidgetPointer(arg1), 4, 0); + setWidgetPosition(0, 48, 0, 0); + setWidgetSize(ivar5, 14, 0, 0); + setWidgetFont(495); + setWidgetText("No matching items found."); + setWidgetTextAlignment(1, 1, 0); + setWidgetRGB(new Color(0, 0, 0)); + setWidgetUnknownBoolean(false); + setWidgetScrollMax(0, 0, new WidgetPointer(arg1)); + script_1042(arg1, arg2); + return; + } + ivar7 = 1; + ivar8 = cs2method4211(); + svar0 = ""; + createExtraChild(new WidgetPointer(arg1), 3, 0); + while (ivar8 != -1) { + if (((stringMethod4107(svar0, getItemName(ivar8)) != 0) && ((boolean)cs2method_3408(111, 105, 1547, ivar8))) && (stringMethod4107(lower(getItemName(ivar8)), "null") != 0)) { + svar0 = getItemName(ivar8); + createExtraChild(new WidgetPointer(arg1), 4, ivar7); + setWidgetPosition(4, multiply(14, subtract(ivar7, 1)), 0, 0); + setWidgetSize(ivar6, 14, 0, 0); + setWidgetRGB(new Color(0, 0, 0)); + setWidgetText(getItemName(ivar8)); + setWidgetFont(495); + setWidgetUnknownBoolean(false); + setScriptCallOnMouseEntered(1043, ivar7, new WidgetPointer(arg1), "iI"); + setScriptCallOnMousePressed(1075, new WidgetPointer(arg0), arg3, ivar8, "Ieo"); + ivar7 = add(ivar7, 1); + } + ivar8 = cs2method4211(); + } + if (((boolean)ivar7)) { + createExtraChild(new WidgetPointer(arg1), 4, 0); + setWidgetPosition(0, 48, 0, 0); + setWidgetSize(ivar5, 14, 0, 0); + setWidgetFont(495); + setWidgetText("No matching items found."); + setWidgetTextAlignment(1, 1, 0); + setWidgetRGB(new Color(0, 0, 0)); + setWidgetUnknownBoolean(false); + setWidgetScrollMax(0, 0, new WidgetPointer(arg1)); + script_1042(arg1, arg2); + return; + } + setScriptCallOnKeyPress(1038, -2147483640, false, new WidgetPointer(137,1), new WidgetPointer(137,14), new WidgetPointer(137,16), new WidgetPointer(137,15), arg3, subtract(ivar7, 1), "izIIIIei", new WidgetPointer(137,13)); + setWidgetScrollMax(0, multiply(14, subtract(ivar7, 1)), new WidgetPointer(arg1)); + script_1042(arg1, arg2); + return; +} diff --git a/dumps/scripts/104.cs2 b/dumps/scripts/104.cs2 new file mode 100644 index 0000000..c994d38 --- /dev/null +++ b/dumps/scripts/104.cs2 @@ -0,0 +1,22 @@ +void script_104() { + if (((boolean)globalint_1413)) { + return; + } + if (((boolean)globalint_11)) { + script_675(); + } + if (getDisplayMode() >= 2) { + setWidgetIsHidden(false, new WidgetPointer(746,73)); + } + setWidgetIsHidden(false, new WidgetPointer(752,3)); + setWidgetIsHidden(true, new WidgetPointer(752,7)); + setWidgetIsHidden(true, new WidgetPointer(752,8)); + setWidgetText(new WidgetPointer(752,4), "Enter name of friend to delete from list"); + globalint_5 = 3; + script_1564(""); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(752,3)); + script_2026(); + setScriptCallOnKeyPress(112, -2147483640, false, "iz", new WidgetPointer(752,5)); + script_1188(); + return; +} diff --git a/dumps/scripts/1040.cs2 b/dumps/scripts/1040.cs2 new file mode 100644 index 0000000..6c4acd9 --- /dev/null +++ b/dumps/scripts/1040.cs2 @@ -0,0 +1,9 @@ +void script_1040(int arg0,int arg1,int arg2,int arg3,int arg4) { + globalint_129 = subtract(globalint_129, 1); + if (globalint_129 > 0) { + return; + } + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg1)); + script_1041(arg0, arg2, arg3, arg4); + return; +} diff --git a/dumps/scripts/1041.cs2 b/dumps/scripts/1041.cs2 new file mode 100644 index 0000000..d1ffae9 --- /dev/null +++ b/dumps/scripts/1041.cs2 @@ -0,0 +1,10 @@ +void script_1041(int arg0,int arg1,int arg2,int arg3) { + deleteAllExtraChilds(new WidgetPointer(arg1)); + if (strLength(globalstring_30) > 0) { + script_1039(arg0, arg1, arg2, arg3); + } else { + setWidgetScrollMax(0, 0, new WidgetPointer(arg1)); + script_1042(arg1, arg2); + } + return; +} diff --git a/dumps/scripts/1042.cs2 b/dumps/scripts/1042.cs2 new file mode 100644 index 0000000..6aa23a5 --- /dev/null +++ b/dumps/scripts/1042.cs2 @@ -0,0 +1,19 @@ +void script_1042(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + ivar2 = getWidgetActualHeight(new WidgetPointer(arg0)); + ivar3 = getWidgetScrollMaxV(new WidgetPointer(arg0)); + ivar4 = subtract(ivar3, ivar2); + if (ivar4 < 0) { + ivar4 = 0; + } + ivar5 = cs2method2601(new WidgetPointer(arg0)); + if (ivar5 > ivar4) { + ivar5 = ivar4; + } + script_31(arg1, arg0, 792, 789, 790, 791, 773, 788); + script_72(arg1, arg0, ivar5); + return; +} diff --git a/dumps/scripts/1043.cs2 b/dumps/scripts/1043.cs2 new file mode 100644 index 0000000..f56b3a1 --- /dev/null +++ b/dumps/scripts/1043.cs2 @@ -0,0 +1,12 @@ +void script_1043(int arg0,int arg1) { + if (setWidgetRegister(new WidgetPointer(arg1), arg0)) { + globalint_128 = subtract(arg0, 1); + if (setWidgetRegister(new WidgetPointer(arg1), 0)) { + setWidgetPosition(getWidgetActualX(), getWidgetActualY(), 0, 0); + setWidgetSize(getWidgetActualWidth(), getWidgetActualHeight(), 0, 0); + setWidgetRGB(new Color(87, 126, 69)); + setWidgetFilled(1); + } + } + return; +} diff --git a/dumps/scripts/1044.cs2 b/dumps/scripts/1044.cs2 new file mode 100644 index 0000000..321b681 --- /dev/null +++ b/dumps/scripts/1044.cs2 @@ -0,0 +1,87 @@ +void script_1044(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + string svar0; + globalint_128 = -1; + svar0 = cs2method5055(arg0); + if (((boolean)globalint_126)) { + svar0 = "To " + globalstring_27 + ": " + "" + svar0; + } else if (globalint_126 == 2) { + svar0 = "[" + "" + cs2method3611() + "" + "]: " + "" + svar0; + } else if (globalint_126 == 8) { + if (cs2method3751()) { + svar0 = "[" + "" + cs2method3752() + "" + "]: " + "" + svar0; + } + } else if (globalint_126 == 10) { + if (cs2method3750()) { + svar0 = "[" + "" + cs2method3752() + "" + "]: " + "" + svar0; + } + } else { + svar0 = "" + svar0; + } + setWidgetIsHidden(true, new WidgetPointer(137,50)); + setScriptCallOnKeyPress(-1, "", new WidgetPointer(137,56)); + setWidgetIsHidden(false, new WidgetPointer(137,0)); + setWidgetIsHidden(true, new WidgetPointer(137,7)); + setWidgetIsHidden(false, new WidgetPointer(137,9)); + setWidgetIsHidden(true, new WidgetPointer(137,13)); + setWidgetIsHidden(true, new WidgetPointer(137,17)); + setWidgetIsHidden(true, new WidgetPointer(137,1)); + setWidgetIsHidden(false, new WidgetPointer(137,3)); + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(137,3)); + setWidgetFont(495, new WidgetPointer(137,3)); + setWidgetTextAlignment(0, 1, 0, new WidgetPointer(137,3)); + setWidgetText(new WidgetPointer(137,3), svar0); + setWidgetUnknownBoolean(false, new WidgetPointer(137,3)); + deleteAllExtraChilds(new WidgetPointer(137,12)); + ivar1 = cs2method5070(arg0, globalint_134, 0); + createExtraChild(new WidgetPointer(137,12), 3, 0); + ivar2 = getWidgetActualWidth(new WidgetPointer(137,12)); + ivar3 = subtract(ivar2, 8); + ivar4 = 1; + ivar5 = 0; + globalarray_0 = new int[250]; + ivar6 = 0; + svar0 = cs2method_3408(105, 115, ivar1, 0); + while ((stringMethod4107("", svar0) != 0) && (ivar4 < 250)) { + createExtraChild(new WidgetPointer(137,12), 4, ivar4); + setWidgetPosition(4, multiply(14, ivar5), 0, 0); + setWidgetSize(ivar3, 14, 0, 0); + setWidgetRGB(new Color(0, 0, 0)); + setWidgetText(svar0); + setWidgetFont(495); + setWidgetUnknownBoolean(false); + setScriptCallOnMouseEntered(1045, ivar4, new WidgetPointer(137,12), ivar5, "iIi"); + setScriptCallOnMousePressed(1073, new WidgetPointer(137,1), arg0, subtract(ivar4, 1), "Iei"); + globalarray_0[ivar5] = ivar5; + svar0 = cs2method_3408(105, 115, ivar1, ivar4); + ivar4 = add(ivar4, 1); + ivar5 = add(ivar5, 1); + } + ivar6 = subtract(ivar5, 1); + if (stringMethod4107(cs2method_3408(105, 115, ivar1, 1000), "non-alpha") != 0) { + script_520(0, 0, ivar6, ivar1); + ivar5 = 0; + while (ivar5 <= ivar6) { + if (setWidgetRegister(new WidgetPointer(137,12), add(globalarray_0[ivar5], 1))) { + setWidgetPosition(4, multiply(14, ivar5), 0, 0); + setScriptCallOnMouseEntered(1045, add(globalarray_0[ivar5], 1), new WidgetPointer(137,12), ivar5, "iIi"); + } + ivar5 = add(ivar5, 1); + } + } + ivar5 = 0; + while (ivar5 < 250) { + script_1384(ivar5, globalarray_0[ivar5]); + ivar5 = add(ivar5, 1); + } + setScriptCallOnKeyPress(1046, -2147483640, false, new WidgetPointer(137,1), new WidgetPointer(137,12), new WidgetPointer(137,11), arg0, subtract(ivar4, 1), "izIIIei", new WidgetPointer(137,12)); + setWidgetScrollMax(0, multiply(14, subtract(ivar4, 1)), new WidgetPointer(137,12)); + script_31(8978443, 8978444, 792, 789, 790, 791, 773, 788); + script_72(8978443, 8978444, 0); + return; +} diff --git a/dumps/scripts/1045.cs2 b/dumps/scripts/1045.cs2 new file mode 100644 index 0000000..37b7540 --- /dev/null +++ b/dumps/scripts/1045.cs2 @@ -0,0 +1,12 @@ +void script_1045(int arg0,int arg1,int arg2) { + if (setWidgetRegister(new WidgetPointer(arg1), arg0)) { + globalint_128 = arg2; + if (setWidgetRegister(new WidgetPointer(arg1), 0)) { + setWidgetPosition(getWidgetActualX(), getWidgetActualY(), 0, 0); + setWidgetSize(getWidgetActualWidth(), getWidgetActualHeight(), 0, 0); + setWidgetRGB(new Color(87, 126, 69)); + setWidgetFilled(1); + } + } + return; +} diff --git a/dumps/scripts/1046.cs2 b/dumps/scripts/1046.cs2 new file mode 100644 index 0000000..cc9b968 --- /dev/null +++ b/dumps/scripts/1046.cs2 @@ -0,0 +1,114 @@ +void script_1046(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6) { + int ivar7; + int ivar8; + int ivar9; + int ivar10; + ivar7 = 1; + ivar8 = 0; + ivar9 = 1000; + ivar10 = -1; + if (isAlphaNumeric(((char)arg1))) { + while (ivar8 < arg6) { + if ((setWidgetRegister(new WidgetPointer(arg3), add(script_1844(ivar8), 1)) && ((boolean)strIndexof(((char)lower(((char)arg1))), 0, lower(getWidgetText())))) && setWidgetRegister(new WidgetPointer(arg3), 0)) { + setWidgetPosition(getWidgetActualX(), getWidgetActualY(), 0, 0); + setWidgetSize(getWidgetActualWidth(), getWidgetActualHeight(), 0, 0); + setWidgetRGB(new Color(87, 126, 69)); + setWidgetFilled(1); + if (ivar8 < globalint_128) { + if (getWidgetActualY() < cs2method2601(new WidgetPointer(arg3))) { + script_72(arg4, arg3, getWidgetActualY()); + } + } else { + if ((ivar8 > globalint_128) && (add(getWidgetActualY(), getWidgetActualHeight()) > add(getWidgetActualHeight(new WidgetPointer(arg3)), cs2method2601(new WidgetPointer(arg3))))) { + script_72(arg4, arg3, subtract(add(getWidgetActualY(), getWidgetActualHeight()), getWidgetActualHeight(new WidgetPointer(arg3)))); + } + } + globalint_128 = ivar8; + return; + } + ivar8 = add(ivar8, 1); + } + return; + } + if (arg0 == 104) { + if (((boolean)arg6)) { + return; + } + if (globalint_128 <= 0) { + globalint_128 = subtract(arg6, 1); + } else { + globalint_128 = subtract(globalint_128, 1); + } + if (setWidgetRegister(new WidgetPointer(arg3), add(script_1844(globalint_128), 1))) { + if (setWidgetRegister(new WidgetPointer(arg3), 0)) { + setWidgetPosition(getWidgetActualX(), getWidgetActualY(), 0, 0); + setWidgetSize(getWidgetActualWidth(), getWidgetActualHeight(), 0, 0); + setWidgetRGB(new Color(87, 126, 69)); + setWidgetFilled(1); + } + if (getWidgetActualY() < cs2method2601(new WidgetPointer(arg3))) { + script_72(arg4, arg3, subtract(cs2method2601(new WidgetPointer(arg3)), getWidgetActualHeight())); + } else { + if (add(getWidgetActualY(), getWidgetActualHeight()) > add(getWidgetActualHeight(new WidgetPointer(arg3)), cs2method2601(new WidgetPointer(arg3)))) { + script_72(arg4, arg3, getWidgetScrollMaxV(new WidgetPointer(arg3))); + } + } + } + return; + } + if (arg0 == 105) { + if (((boolean)arg6)) { + return; + } + if (globalint_128 == subtract(arg6, 1)) { + globalint_128 = 0; + } else { + globalint_128 = add(globalint_128, 1); + } + if (setWidgetRegister(new WidgetPointer(arg3), add(script_1844(globalint_128), 1))) { + if (setWidgetRegister(new WidgetPointer(arg3), 0)) { + setWidgetPosition(getWidgetActualX(), getWidgetActualY(), 0, 0); + setWidgetSize(getWidgetActualWidth(), getWidgetActualHeight(), 0, 0); + setWidgetRGB(new Color(87, 126, 69)); + setWidgetFilled(1); + } + if (add(getWidgetActualY(), getWidgetActualHeight()) > add(getWidgetActualHeight(new WidgetPointer(arg3)), cs2method2601(new WidgetPointer(arg3)))) { + script_72(arg4, arg3, add(cs2method2601(new WidgetPointer(arg3)), getWidgetActualHeight())); + } else { + if (getWidgetActualY() < cs2method2601(new WidgetPointer(arg3))) { + script_72(arg4, arg3, 0); + } + } + } + return; + } + if (arg0 == 102) { + script_1050(globalint_126, globalstring_27); + return; + } + if (arg0 == 13) { + script_1054(); + return; + } + if (arg0 == 84) { + if ((globalint_128 >= 0) && setWidgetRegister(new WidgetPointer(arg3), add(globalint_128, 1))) { + script_1074(arg2, arg5, script_1844(globalint_128)); + } + return; + } + if (arg0 == 85) { + if (((boolean)globalint_127)) { + script_1054(); + } else { + globalint_128 = -1; + setWidgetIsHidden(true, new WidgetPointer(137,7)); + setWidgetIsHidden(true, new WidgetPointer(137,9)); + setWidgetIsHidden(true, new WidgetPointer(137,13)); + setWidgetIsHidden(false, new WidgetPointer(137,17)); + setWidgetIsHidden(false, new WidgetPointer(137,1)); + setWidgetIsHidden(true, new WidgetPointer(137,3)); + } + return; + } + return; +} diff --git a/dumps/scripts/1047.cs2 b/dumps/scripts/1047.cs2 new file mode 100644 index 0000000..3157e4d --- /dev/null +++ b/dumps/scripts/1047.cs2 @@ -0,0 +1,38 @@ +void script_1047(int arg0) { + string svar0; + globalint_129 = 0; + svar0 = cs2method5055(arg0); + if (((boolean)globalint_126)) { + svar0 = "To " + globalstring_27 + ": " + "" + svar0; + } else if (globalint_126 == 2) { + svar0 = "[" + "" + cs2method3611() + "" + "]: " + "" + svar0; + } else if (globalint_126 == 8) { + if (cs2method3751()) { + svar0 = "[" + "" + cs2method3752() + "" + "]: " + "" + svar0; + } + } else if (globalint_126 == 10) { + if (cs2method3750()) { + svar0 = "[" + "" + cs2method3752() + "" + "]: " + "" + svar0; + } + } else { + svar0 = "" + svar0; + } + setWidgetIsHidden(true, new WidgetPointer(137,50)); + setScriptCallOnKeyPress(-1, "", new WidgetPointer(137,56)); + setWidgetIsHidden(false, new WidgetPointer(137,0)); + setWidgetIsHidden(false, new WidgetPointer(137,7)); + setWidgetIsHidden(true, new WidgetPointer(137,9)); + setWidgetIsHidden(true, new WidgetPointer(137,13)); + setWidgetIsHidden(true, new WidgetPointer(137,17)); + setWidgetIsHidden(true, new WidgetPointer(137,1)); + setWidgetIsHidden(false, new WidgetPointer(137,3)); + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(137,3)); + setWidgetFont(495, new WidgetPointer(137,3)); + setWidgetTextAlignment(0, 1, 0, new WidgetPointer(137,3)); + setWidgetText(new WidgetPointer(137,3), svar0); + setWidgetUnknownBoolean(false, new WidgetPointer(137,3)); + deleteAllExtraChilds(new WidgetPointer(137,7)); + setWidgetText(new WidgetPointer(137,8), "Please enter a value: *"); + setScriptCallOnKeyPress(1048, -2147483640, false, new WidgetPointer(137,1), new WidgetPointer(137,8), arg0, "izIIe", new WidgetPointer(137,7)); + return; +} diff --git a/dumps/scripts/1048.cs2 b/dumps/scripts/1048.cs2 new file mode 100644 index 0000000..64f402b --- /dev/null +++ b/dumps/scripts/1048.cs2 @@ -0,0 +1,47 @@ +void script_1048(int arg0,int arg1,int arg2,int arg3,int arg4) { + int ivar5; + int ivar6; + if (arg0 == 13) { + script_1054(); + return; + } + if (arg0 == 102) { + script_1050(globalint_126, globalstring_27); + return; + } + ivar5 = strLength(intToStr(globalint_129)); + ivar6 = strIndexof(((char)arg1), 0, "0123456789"); + if (arg0 == 84) { + if (ivar5 > 0) { + script_1074(arg2, arg4, globalint_129); + } else { + script_1054(); + } + return; + } + if (arg0 == 85) { + if (ivar5 > 0) { + globalint_129 = divide(globalint_129, 10); + } else if (((boolean)globalint_127)) { + script_1054(); + } else { + setWidgetIsHidden(true, new WidgetPointer(137,7)); + setWidgetIsHidden(true, new WidgetPointer(137,9)); + setWidgetIsHidden(true, new WidgetPointer(137,13)); + setWidgetIsHidden(false, new WidgetPointer(137,17)); + setWidgetIsHidden(false, new WidgetPointer(137,1)); + setWidgetIsHidden(true, new WidgetPointer(137,3)); + return; + } + } else { + if (((ivar6 >= 0) && (ivar5 < 10)) && (add(multiply(globalint_129, 10), ivar6) > 0)) { + globalint_129 = add(multiply(globalint_129, 10), ivar6); + } + } + if (globalint_129 > 0) { + setWidgetText(new WidgetPointer(arg3), "Please enter a value: " + intToStr(globalint_129) + "*"); + } else { + setWidgetText(new WidgetPointer(arg3), "Please enter a value: *"); + } + return; +} diff --git a/dumps/scripts/1049.cs2 b/dumps/scripts/1049.cs2 new file mode 100644 index 0000000..e3b5d40 --- /dev/null +++ b/dumps/scripts/1049.cs2 @@ -0,0 +1,98 @@ +void script_1049(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + cs2func_script_4590_struct(6,0,0) structdump_0; + ivar1 = -1; + ivar2 = -1; + ivar3 = -1; + ivar4 = -1; + ivar5 = -1; + ivar6 = -1; + structdump_0 = script_4590(); + ivar6 = structdump_0.intpart_5; + ivar5 = structdump_0.intpart_4; + ivar4 = structdump_0.intpart_3; + ivar3 = structdump_0.intpart_2; + ivar2 = structdump_0.intpart_1; + ivar1 = structdump_0.intpart_0; + if (((boolean)arg0)) { + globalint_1651 = 0; + cs2method5006(0); + script_1558(0); + return; + } + if (arg0 == 2) { + script_1050(0, ""); + } else if (arg0 == 4) { + if (cs2method3612() > 0) { + script_1050(2, ""); + } else { + globalint_41 = 0; + script_181(0); + script_178(); + script_84(); + script_89(); + messageType0("You aren't in a Friends Chat channel."); + return; + } + } else if (arg0 == 6) { + if (ivar1 >= 0) { + if (ivar2 >= ivar3) { + script_1050(8, ""); + } else { + message(43, 0, "Your rank is not high enough to chat in the Clan Chat."); + return; + } + } else { + globalint_41 = 0; + script_181(0); + script_178(); + script_84(); + script_89(); + messageType0("You aren't in a Clan Chat channel."); + return; + } + } else { + if (arg0 == 7) { + globalint_1651 = 3; + cs2method5006(3); + script_1558(0); + return; + } + if (arg0 == 8) { + if (ivar4 >= 0) { + if (ivar5 >= ivar6) { + script_1050(10, ""); + } else { + message(43, 0, "Guests cannot chat in this visited Clan channel."); + return; + } + } else { + globalint_41 = 0; + script_181(0); + script_178(); + script_84(); + script_89(); + messageType0("You aren't a guest in a Clan Chat channel."); + return; + } + } + } + if (arg0 == 3) { + globalint_1651 = 1; + cs2method5006(1); + script_1558(0); + return; + } + if (arg0 == 5) { + globalint_1651 = 2; + cs2method5006(2); + script_1558(0); + return; + } + return; +} diff --git a/dumps/scripts/105.cs2 b/dumps/scripts/105.cs2 new file mode 100644 index 0000000..88271a6 --- /dev/null +++ b/dumps/scripts/105.cs2 @@ -0,0 +1,22 @@ +void script_105() { + if (((boolean)globalint_1413)) { + return; + } + if (((boolean)globalint_11)) { + script_675(); + } + if (getDisplayMode() >= 2) { + setWidgetIsHidden(false, new WidgetPointer(746,73)); + } + setWidgetIsHidden(false, new WidgetPointer(752,3)); + setWidgetIsHidden(true, new WidgetPointer(752,7)); + setWidgetIsHidden(true, new WidgetPointer(752,8)); + setWidgetText(new WidgetPointer(752,4), "Enter name of player to add to list"); + globalint_5 = 4; + script_1564(""); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(752,3)); + script_2026(); + setScriptCallOnKeyPress(112, -2147483640, false, "iz", new WidgetPointer(752,5)); + script_1188(); + return; +} diff --git a/dumps/scripts/1050.cs2 b/dumps/scripts/1050.cs2 new file mode 100644 index 0000000..730afb5 --- /dev/null +++ b/dumps/scripts/1050.cs2 @@ -0,0 +1,51 @@ +void script_1050(int arg0,string arg1) { + int ivar1; + int ivar2; + int ivar3; + if (((boolean)globalint_1413)) { + return; + } + if ((arg0 == 2) && ((boolean)stringMethod4107("", cs2method3611()))) { + messageType0("You need to be in a Friends Chat channel to use Friends Channel Quick Chat."); + return; + } + if ((arg0 == 8) && cs2method3751()) { + messageType0("You need to be in a Clan to use Clan Channel Quick Chat."); + return; + } + if ((arg0 == 10) && cs2method3750()) { + messageType0("You need to be a guest in a Clan Channel to use Guest Clan Quick Chat."); + return; + } + if (getDisplayMode() >= 2) { + setWidgetSprite(1017, new WidgetPointer(752,1)); + cs2method2122(0, 49283073); + setWidgetIsHidden(false, new WidgetPointer(752,1)); + setWidgetIsHidden(false, new WidgetPointer(752,2)); + script_1652(0); + setWidgetIsHidden(true, new WidgetPointer(746,75)); + } + setWidgetIsHidden(true, new WidgetPointer(137,50)); + setScriptCallOnKeyPress(-1, "", new WidgetPointer(137,56)); + setWidgetIsHidden(false, new WidgetPointer(137,0)); + setWidgetIsHidden(true, new WidgetPointer(137,7)); + setWidgetIsHidden(true, new WidgetPointer(137,9)); + setWidgetIsHidden(true, new WidgetPointer(137,13)); + setWidgetIsHidden(false, new WidgetPointer(137,17)); + setWidgetIsHidden(false, new WidgetPointer(137,1)); + setWidgetIsHidden(true, new WidgetPointer(137,3)); + cs2method2100(0, 0, new WidgetPointer(137,17)); + ivar1 = 85; + ivar2 = script_1036(); + ivar3 = 1; + if (arg0 == 3) { + ivar1 = 32769; + ivar2 = -1; + ivar3 = 0; + } + globalint_126 = arg0; + globalstring_27 = arg1; + globalint_127 = 1; + script_1062(8978433, 0, ivar1, ivar2, ivar3); + return; +} diff --git a/dumps/scripts/1051.cs2 b/dumps/scripts/1051.cs2 new file mode 100644 index 0000000..64509b6 --- /dev/null +++ b/dumps/scripts/1051.cs2 @@ -0,0 +1,25 @@ +void script_1051(int arg0,string arg1) { + globalint_126 = arg0; + globalstring_27 = arg1; + globalint_127 = 1; + if (getDisplayMode() >= 2) { + setWidgetSprite(1017, new WidgetPointer(752,1)); + cs2method2122(0, 49283073); + setWidgetIsHidden(false, new WidgetPointer(752,1)); + setWidgetIsHidden(false, new WidgetPointer(752,2)); + script_1652(0); + setWidgetIsHidden(true, new WidgetPointer(746,75)); + } + setWidgetIsHidden(true, new WidgetPointer(137,50)); + setScriptCallOnKeyPress(-1, "", new WidgetPointer(137,56)); + setWidgetIsHidden(false, new WidgetPointer(137,0)); + setWidgetIsHidden(true, new WidgetPointer(137,7)); + setWidgetIsHidden(true, new WidgetPointer(137,9)); + setWidgetIsHidden(true, new WidgetPointer(137,13)); + setWidgetIsHidden(false, new WidgetPointer(137,17)); + setWidgetIsHidden(false, new WidgetPointer(137,1)); + setWidgetIsHidden(true, new WidgetPointer(137,3)); + cs2method2100(0, 0, new WidgetPointer(137,17)); + script_1062(8978433, 0, script_1036(), -1, 0); + return; +} diff --git a/dumps/scripts/1052.cs2 b/dumps/scripts/1052.cs2 new file mode 100644 index 0000000..bd74794 --- /dev/null +++ b/dumps/scripts/1052.cs2 @@ -0,0 +1,28 @@ +void script_1052(int arg0,int arg1,string arg2) { + if ((arg1 == -1) || ((boolean)cs2method5056(arg1))) { + return; + } + globalint_126 = arg0; + globalstring_27 = arg2; + globalint_127 = 1; + if (getDisplayMode() >= 2) { + setWidgetSprite(1017, new WidgetPointer(752,1)); + cs2method2122(0, 49283073); + setWidgetIsHidden(false, new WidgetPointer(752,1)); + setWidgetIsHidden(false, new WidgetPointer(752,2)); + script_1652(0); + setWidgetIsHidden(true, new WidgetPointer(746,75)); + } + setWidgetIsHidden(true, new WidgetPointer(137,50)); + setScriptCallOnKeyPress(-1, "", new WidgetPointer(137,56)); + setWidgetIsHidden(false, new WidgetPointer(137,0)); + setWidgetIsHidden(true, new WidgetPointer(137,7)); + setWidgetIsHidden(true, new WidgetPointer(137,9)); + setWidgetIsHidden(true, new WidgetPointer(137,13)); + setWidgetIsHidden(false, new WidgetPointer(137,17)); + setWidgetIsHidden(false, new WidgetPointer(137,1)); + setWidgetIsHidden(true, new WidgetPointer(137,3)); + cs2method2100(0, 0, new WidgetPointer(137,17)); + script_1063(8978433, arg1); + return; +} diff --git a/dumps/scripts/1053.cs2 b/dumps/scripts/1053.cs2 new file mode 100644 index 0000000..b26629b --- /dev/null +++ b/dumps/scripts/1053.cs2 @@ -0,0 +1,4 @@ +void script_1053() { + script_1054(); + return; +} diff --git a/dumps/scripts/1054.cs2 b/dumps/scripts/1054.cs2 new file mode 100644 index 0000000..9e9824f --- /dev/null +++ b/dumps/scripts/1054.cs2 @@ -0,0 +1,15 @@ +void script_1054() { + int ivar0; + setWidgetIsHidden(false, new WidgetPointer(137,50)); + setScriptCallOnKeyPress(73, -2147483640, false, "iz", new WidgetPointer(137,56)); + setWidgetIsHidden(true, new WidgetPointer(137,0)); + ivar0 = 0; + while (((int)cs2method_3408(105, 73, 1550, ivar0)) != -1) { + setScriptCallOnKeyPress(-1, "", cs2method_3408(105, 73, 1550, ivar0)); + ivar0 = add(ivar0, 1); + } + if (getDisplayMode() >= 2) { + script_1364(); + } + return; +} diff --git a/dumps/scripts/1055.cs2 b/dumps/scripts/1055.cs2 new file mode 100644 index 0000000..d70fc9a --- /dev/null +++ b/dumps/scripts/1055.cs2 @@ -0,0 +1,4 @@ +void script_1055(int arg0) { + setWidgetSprite(416, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1056.cs2 b/dumps/scripts/1056.cs2 new file mode 100644 index 0000000..5aa25d2 --- /dev/null +++ b/dumps/scripts/1056.cs2 @@ -0,0 +1,4 @@ +void script_1056(int arg0) { + setWidgetSprite(415, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1057.cs2 b/dumps/scripts/1057.cs2 new file mode 100644 index 0000000..8c93e98 --- /dev/null +++ b/dumps/scripts/1057.cs2 @@ -0,0 +1,4 @@ +void script_1057(int arg0) { + setWidgetSprite(418, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1058.cs2 b/dumps/scripts/1058.cs2 new file mode 100644 index 0000000..120efee --- /dev/null +++ b/dumps/scripts/1058.cs2 @@ -0,0 +1,4 @@ +void script_1058(int arg0) { + setWidgetSprite(417, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1059.cs2 b/dumps/scripts/1059.cs2 new file mode 100644 index 0000000..7750fea --- /dev/null +++ b/dumps/scripts/1059.cs2 @@ -0,0 +1,141 @@ +void script_1059(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6) { + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + if (isWidgetHidden(cs2method_3408(105, 73, 1550, add(arg3, 1)))) { + return; + } + ivar7 = ((int)cs2method_3408(105, 73, 1551, arg3)); + if (arg0 == 104) { + if (((boolean)arg6)) { + return; + } + if (setWidgetRegister(new WidgetPointer(ivar7), globalint_128)) { + setWidgetHidden(1); + } + if (globalint_128 <= 0) { + globalint_128 = subtract(arg6, 1); + } else { + globalint_128 = subtract(globalint_128, 1); + } + if (setWidgetRegister(new WidgetPointer(ivar7), globalint_128) && isWidgetHidden()) { + setWidgetHidden(0); + setWidgetRGB(new Color(87, 126, 69)); + } + return; + } + if (arg0 == 105) { + if (((boolean)arg6)) { + return; + } + if (setWidgetRegister(new WidgetPointer(ivar7), globalint_128)) { + setWidgetHidden(1); + } + if (globalint_128 == subtract(arg6, 1)) { + globalint_128 = 0; + } else { + globalint_128 = add(globalint_128, 1); + } + if (setWidgetRegister(new WidgetPointer(ivar7), globalint_128) && isWidgetHidden()) { + setWidgetHidden(0); + setWidgetRGB(new Color(87, 126, 69)); + } + return; + } + ivar8 = 0; + ivar9 = 0; + if (arg0 == 84) { + if (globalint_128 < 0) { + if ((arg4 != 32769) && ((boolean)arg3)) { + script_1900(((int)cs2method_3408(105, 73, 1550, arg3)), ((int)cs2method_3408(105, 73, 1551, arg3)), globalint_128, add(arg3, 1)); + } + } else if (arg4 != -1) { + ivar8 = cs2method5051(arg4); + ivar9 = cs2method5053(arg4); + if (globalint_128 == add(ivar8, ivar9)) { + if ((((boolean)arg3) && (script_1036() != -1)) && setWidgetRegister(cs2method_3408(105, 73, 1550, arg3), globalint_128)) { + script_1061(((int)cs2method_3408(105, 73, 1550, arg3)), ((int)cs2method_3408(105, 73, 1551, arg3)), globalint_128, arg2, add(arg3, 1), script_1036()); + } + } else if (globalint_128 < ivar8) { + script_1061(((int)cs2method_3408(105, 73, 1550, arg3)), ((int)cs2method_3408(105, 73, 1551, arg3)), globalint_128, arg2, add(arg3, 1), cs2method5052(arg4, globalint_128)); + } else if (globalint_128 < add(ivar8, ivar9)) { + script_1071(arg2, cs2method5054(arg4, subtract(globalint_128, ivar8)), arg3); + } else { + script_1900(((int)cs2method_3408(105, 73, 1550, arg3)), ((int)cs2method_3408(105, 73, 1551, arg3)), globalint_128, add(arg3, 1)); + } + } else { + if (arg5 != -1) { + ivar8 = 0; + ivar9 = cs2method5056(arg5); + script_1071(arg2, cs2method5057(arg5, globalint_128), arg3); + } + } + return; + } + if (arg0 == 102) { + script_1050(globalint_126, globalstring_27); + return; + } + if (arg0 == 13) { + script_1054(); + return; + } + if ((arg0 == 85) && (arg3 > 0)) { + script_1068(arg2, subtract(arg3, 1)); + return; + } + if (isAlphaNumeric(((char)arg1))) { + return; + } + arg1 = upper(((char)arg1)); + ivar10 = 0; + ivar11 = 0; + ivar12 = -1; + if (arg4 != -1) { + ivar8 = cs2method5051(arg4); + ivar9 = cs2method5053(arg4); + if ((((boolean)arg3) && ((boolean)stringMethod4107("X", concatChar(((char)arg1), "")))) && (script_1036() != -1)) { + ivar10 = add(ivar8, ivar9); + if (setWidgetRegister(cs2method_3408(105, 73, 1550, arg3), ivar10)) { + script_1061(((int)cs2method_3408(105, 73, 1550, arg3)), ((int)cs2method_3408(105, 73, 1551, arg3)), ivar10, arg2, add(arg3, 1), script_1036()); + } + return; + } + ivar10 = 0; + while (ivar11 < ivar8) { + ivar12 = upper(((char)cs2method5062(arg4, ivar11))); + if (ivar12 == arg1) { + script_1061(((int)cs2method_3408(105, 73, 1550, arg3)), ((int)cs2method_3408(105, 73, 1551, arg3)), ivar10, arg2, add(arg3, 1), cs2method5052(arg4, ivar10)); + return; + } + ivar10 = add(ivar10, 1); + ivar11 = add(ivar11, 1); + } + } else { + ivar8 = 0; + ivar9 = cs2method5056(arg5); + } + if (isDigit(((char)arg1))) { + return; + } + ivar13 = strIndexof(((char)arg1), 0, "0123456789"); + if (((boolean)ivar13)) { + ivar13 = 10; + } + if (ivar13 > ivar9) { + return; + } + ivar10 = subtract(ivar13, 1); + if (arg4 != -1) { + script_1071(arg2, cs2method5054(arg4, ivar10), arg3); + } else { + if (arg5 != -1) { + script_1071(arg2, cs2method5057(arg5, ivar10), arg3); + } + } + return; +} diff --git a/dumps/scripts/106.cs2 b/dumps/scripts/106.cs2 new file mode 100644 index 0000000..1a7c804 --- /dev/null +++ b/dumps/scripts/106.cs2 @@ -0,0 +1,48 @@ +void script_106(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + if (arg2 != 1) { + return; + } + ivar3 = 0; + ivar4 = 0; + ivar5 = 0; + ivar6 = 0; + ivar7 = 0; + while (ivar3 < getItemContainerLength(140)) { + if (setWidgetRegister(new WidgetPointer(arg0), ivar3) && isWidgetHidden()) { + ivar4 = ivar3; + } + ivar3 = add(ivar3, 1); + } + ivar6 = divide(arg1, 5); + ivar5 = subtract(arg1, multiply(ivar6, 5)); + if (((ivar4 == subtract(arg1, 1)) && (ivar5 > 0)) && (setWidgetRegister(new WidgetPointer(arg0), arg1) && setWidgetRegister(new WidgetPointer(arg0), ivar4))) { + playSoundEffect(1859, 1, 0); + setWidgetPosition(multiply(56, subtract(ivar5, 1)), multiply(56, ivar6), 0, 0); + setWidgetPosition(multiply(56, ivar5), multiply(56, ivar6), 0, 0); + return; + } + if (((ivar4 == add(arg1, 1)) && (ivar5 < 5)) && (setWidgetRegister(new WidgetPointer(arg0), arg1) && setWidgetRegister(new WidgetPointer(arg0), ivar4))) { + playSoundEffect(1859, 1, 0); + setWidgetPosition(multiply(56, add(ivar5, 1)), multiply(56, ivar6), 0, 0); + setWidgetPosition(multiply(56, ivar5), multiply(56, ivar6), 0, 0); + return; + } + if (((ivar4 == subtract(arg1, 5)) && (ivar6 > 0)) && (setWidgetRegister(new WidgetPointer(arg0), arg1) && setWidgetRegister(new WidgetPointer(arg0), ivar4))) { + playSoundEffect(1859, 1, 0); + setWidgetPosition(multiply(56, ivar5), multiply(56, subtract(ivar6, 1)), 0, 0); + setWidgetPosition(multiply(56, ivar5), multiply(56, ivar6), 0, 0); + return; + } + if (((ivar4 == add(arg1, 5)) && (ivar6 < 5)) && (setWidgetRegister(new WidgetPointer(arg0), arg1) && setWidgetRegister(new WidgetPointer(arg0), ivar4))) { + playSoundEffect(1859, 1, 0); + setWidgetPosition(multiply(56, ivar5), multiply(56, add(ivar6, 1)), 0, 0); + setWidgetPosition(multiply(56, ivar5), multiply(56, ivar6), 0, 0); + return; + } + return; +} diff --git a/dumps/scripts/1060.cs2 b/dumps/scripts/1060.cs2 new file mode 100644 index 0000000..4e362ea --- /dev/null +++ b/dumps/scripts/1060.cs2 @@ -0,0 +1,4 @@ +void script_1060(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + script_1061(arg0, arg1, arg2, arg3, arg4, arg5); + return; +} diff --git a/dumps/scripts/1061.cs2 b/dumps/scripts/1061.cs2 new file mode 100644 index 0000000..60e8d2a --- /dev/null +++ b/dumps/scripts/1061.cs2 @@ -0,0 +1,25 @@ +void script_1061(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + int ivar6; + globalint_159 = 0; + globalint_158 = 0; + ivar6 = 0; + while (setWidgetRegister(new WidgetPointer(arg0), ivar6)) { + if (ivar6 == arg2) { + setScriptCallOnMouseEntered(-1, ""); + setScriptCallOnMouseExit(-1, ""); + if (setWidgetRegister(new WidgetPointer(arg1), ivar6)) { + setWidgetHidden(0); + setWidgetRGB(new Color(150, 151, 119)); + } + } else { + setScriptCallOnMouseEntered(1082, subtract(arg4, 1), new WidgetPointer(arg1), ivar6, "iIi"); + setScriptCallOnMouseExit(1083, subtract(arg4, 1), new WidgetPointer(arg1), ivar6, "iIi"); + if (setWidgetRegister(new WidgetPointer(arg1), ivar6)) { + setWidgetHidden(1); + } + } + ivar6 = add(ivar6, 1); + } + script_1062(arg3, arg4, arg5, -1, 0); + return; +} diff --git a/dumps/scripts/1062.cs2 b/dumps/scripts/1062.cs2 new file mode 100644 index 0000000..a51ee3d --- /dev/null +++ b/dumps/scripts/1062.cs2 @@ -0,0 +1,186 @@ +void script_1062(int arg0,int arg1,int arg2,int arg3,int arg4) { + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + string svar0; + ivar5 = ((int)cs2method_3408(105, 73, 1550, arg1)); + ivar6 = ((int)cs2method_3408(105, 73, 1551, arg1)); + deleteAllExtraChilds(new WidgetPointer(ivar5)); + deleteAllExtraChilds(new WidgetPointer(ivar6)); + if (ivar5 == -1) { + return; + } + createExtraChild(new WidgetPointer(arg0), 4, arg1); + setWidgetRGB(new Color(0, 0, 0)); + setWidgetFont(495); + setWidgetTextAlignment(1, 1, 0); + svar0 = cs2method5050(arg2); + cs2method1305(svar0); + setScriptCallOnClickContextMenu(1067, new WidgetPointer(arg0), arg1, "Ii"); + setWidgetContextMenuOption(1, "Return to: "); + if (arg1 > 0) { + svar0 = " " + "" + svar0 + " " + ""; + } else if (((boolean)globalint_126)) { + svar0 = " To " + globalstring_27 + ": " + "" + svar0 + " " + ""; + } else if (globalint_126 == 2) { + svar0 = " [" + "" + cs2method3611() + "" + "]: " + "" + svar0 + " " + ""; + } else if (globalint_126 == 8) { + if (cs2method3751()) { + svar0 = " [" + "" + cs2method3752() + "" + "]: " + "" + svar0 + " " + ""; + } + } else if (globalint_126 == 10) { + if (cs2method3750()) { + svar0 = " [" + "" + cs2method3752() + "" + "]: " + "" + svar0 + " " + ""; + } + } else { + svar0 = " " + "" + svar0 + " " + ""; + } + setWidgetText(svar0); + setWidgetUnknownBoolean(false); + setWidgetSize(add(getMaxLineWidth(getWidgetActualWidth(new WidgetPointer(arg0)), 495, svar0), 4), getWidgetActualHeight(new WidgetPointer(arg0)), 0, 0); + setScriptCallOnMouseEntered(1080, new WidgetPointer(137,2), arg1, "Ii"); + setScriptCallOnMouseExit(1081, new WidgetPointer(137,2), arg1, "Ii"); + createExtraChild(new WidgetPointer(137,2), 3, arg1); + setWidgetSize(getWidgetActualWidth(), getWidgetActualHeight(), 0, 0); + setWidgetRGB(new Color(87, 126, 69)); + setWidgetFilled(1); + setWidgetHidden(1); + setWidgetIsHidden(false, new WidgetPointer(ivar5)); + ivar7 = cs2method5051(arg2); + ivar8 = cs2method5053(arg2); + ivar9 = 0; + ivar10 = 0; + ivar11 = 0; + ivar12 = 0; + ivar13 = -1; + ivar14 = -1; + ivar15 = -1; + ivar16 = 0; + while (ivar9 < ivar7) { + createExtraChild(new WidgetPointer(ivar5), 4, ivar10); + setWidgetRGB(new Color(0, 0, 0)); + setWidgetFont(495); + setWidgetTextAlignment(0, 1, 0); + ivar13 = cs2method5052(arg2, ivar9); + svar0 = cs2method5050(ivar13); + setScriptCallOnClickContextMenu(1060, new WidgetPointer(ivar5), new WidgetPointer(ivar6), ivar10, new WidgetPointer(arg0), add(arg1, 1), ivar13, "IIiIik"); + cs2method1305(svar0); + setWidgetContextMenuOption(1, "Select: "); + setScriptCallOnMouseEntered(1082, arg1, new WidgetPointer(ivar6), ivar10, "iIi"); + setScriptCallOnMouseExit(1083, arg1, new WidgetPointer(ivar6), ivar10, "iIi"); + ivar15 = upper(((char)cs2method5062(arg2, ivar9))); + if (isAlphaNumeric(((char)ivar15))) { + svar0 = "" + concatChar(((char)ivar15), "") + ". " + "" + svar0 + " " + ""; + } else { + svar0 = svar0 + " " + ""; + } + setWidgetText(svar0); + setWidgetUnknownBoolean(false); + ivar11 = getMaxLineWidth(getWidgetActualWidth(new WidgetPointer(arg0)), 495, svar0); + if (ivar11 > ivar12) { + ivar12 = ivar11; + } + ivar9 = add(ivar9, 1); + ivar10 = add(ivar10, 1); + } + ivar9 = 0; + while (ivar9 < ivar8) { + createExtraChild(new WidgetPointer(ivar5), 4, ivar10); + setWidgetRGB(new Color(0, 0, 0)); + setWidgetFont(495); + setWidgetTextAlignment(0, 1, 0); + ivar14 = cs2method5054(arg2, ivar9); + svar0 = cs2method5055(ivar14); + setScriptCallOnClickContextMenu(1070, new WidgetPointer(arg0), ivar14, arg1, "Iei"); + cs2method1305(svar0); + setWidgetContextMenuOption(1, "Send: "); + setScriptCallOnMouseEntered(1082, arg1, new WidgetPointer(ivar6), ivar10, "iIi"); + setScriptCallOnMouseExit(1083, arg1, new WidgetPointer(ivar6), ivar10, "iIi"); + if (ivar9 < 10) { + svar0 = "" + intToStr(mod(add(ivar9, 1), 10)) + ". " + "" + svar0; + } + setWidgetText(svar0); + setWidgetUnknownBoolean(false); + ivar11 = getMaxLineWidth(getWidgetActualWidth(new WidgetPointer(arg0)), 495, svar0); + if (ivar11 > ivar12) { + ivar12 = ivar11; + } + ivar9 = add(ivar9, 1); + ivar10 = add(ivar10, 1); + } + if (arg3 != -1) { + createExtraChild(new WidgetPointer(ivar5), 4, ivar10); + setWidgetRGB(new Color(0, 0, 0)); + setWidgetFont(495); + setWidgetTextAlignment(0, 1, 0); + svar0 = cs2method5050(arg3); + setScriptCallOnClickContextMenu(1060, new WidgetPointer(ivar5), new WidgetPointer(ivar6), ivar10, new WidgetPointer(arg0), add(arg1, 1), arg3, "IIiIik"); + cs2method1305(svar0); + setWidgetContextMenuOption(1, "Select: "); + setScriptCallOnMouseEntered(1082, arg1, new WidgetPointer(ivar6), ivar10, "iIi"); + setScriptCallOnMouseExit(1083, arg1, new WidgetPointer(ivar6), ivar10, "iIi"); + svar0 = "" + "X. " + "" + svar0 + " " + ""; + setWidgetText(svar0); + setWidgetUnknownBoolean(false); + ivar11 = getMaxLineWidth(getWidgetActualWidth(new WidgetPointer(arg0)), 495, svar0); + if (ivar11 > ivar12) { + ivar12 = ivar11; + } + ivar10 = add(ivar10, 1); + } + if (((boolean)arg4)) { + createExtraChild(new WidgetPointer(ivar5), 4, ivar10); + setWidgetRGB(new Color(0, 0, 0)); + setWidgetFont(495); + setWidgetTextAlignment(0, 1, 0); + setScriptCallOnClickContextMenu(1877, new WidgetPointer(ivar5), new WidgetPointer(ivar6), ivar10, arg1, "IIii"); + cs2method1305("Search phrases"); + setWidgetContextMenuOption(1, "Select: "); + setScriptCallOnMouseEntered(1082, arg1, new WidgetPointer(ivar6), ivar10, "iIi"); + setScriptCallOnMouseExit(1083, arg1, new WidgetPointer(ivar6), ivar10, "iIi"); + setWidgetText("" + "Enter. " + "" + "Search " + ""); + setWidgetUnknownBoolean(false); + ivar11 = getMaxLineWidth(getWidgetActualWidth(new WidgetPointer(arg0)), 495, svar0); + if (ivar11 > ivar12) { + ivar12 = ivar11; + } + ivar10 = add(ivar10, 1); + } + setScriptCallOnKeyPress(1059, -2147483640, false, new WidgetPointer(arg0), arg1, arg2, -1, ivar10, "izIikei", new WidgetPointer(ivar5)); + ivar9 = 0; + ivar17 = 0; + while (setWidgetRegister(new WidgetPointer(ivar5), ivar9)) { + if (add(multiply(ivar16, 14), 14) > getWidgetActualHeight(new WidgetPointer(ivar5))) { + ivar17 = add(add(ivar17, ivar12), 4); + ivar16 = 0; + } + setWidgetSize(ivar12, 14, 0, 0); + setWidgetPosition(add(ivar17, 2), multiply(ivar16, 14), 0, 0); + createExtraChild(new WidgetPointer(ivar6), 3, ivar9); + setWidgetSize(add(getWidgetActualWidth(), 4), getWidgetActualHeight(), 0, 0); + setWidgetPosition(subtract(getWidgetActualX(), 2), getWidgetActualY(), 0, 0); + setWidgetRGB(new Color(87, 126, 69)); + setWidgetFilled(1); + setWidgetHidden(1); + ivar9 = add(ivar9, 1); + ivar16 = add(ivar16, 1); + } + ivar17 = add(add(ivar17, ivar12), 4); + ivar18 = getWidgetParentId(new WidgetPointer(ivar5)); + setWidgetSize(ivar17, getWidgetActualHeight(new WidgetPointer(ivar18)), 0, 0, new WidgetPointer(ivar5)); + setWidgetSize(ivar17, getWidgetActualHeight(new WidgetPointer(ivar18)), 0, 0, new WidgetPointer(ivar6)); + setWidgetPosition(add(getWidgetActualX(new WidgetPointer(ivar5)), ivar17), 0, 0, 0, cs2method_3408(105, 73, 1550, add(arg1, 1))); + script_1068(arg0, arg1); + return; +} diff --git a/dumps/scripts/1063.cs2 b/dumps/scripts/1063.cs2 new file mode 100644 index 0000000..366d47a --- /dev/null +++ b/dumps/scripts/1063.cs2 @@ -0,0 +1,99 @@ +void script_1063(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + string svar0; + ivar2 = ((int)cs2method_3408(105, 73, 1550, 0)); + ivar3 = ((int)cs2method_3408(105, 73, 1551, 0)); + deleteAllExtraChilds(new WidgetPointer(ivar2)); + deleteAllExtraChilds(new WidgetPointer(ivar3)); + createExtraChild(new WidgetPointer(arg0), 4, 0); + setWidgetRGB(new Color(0, 0, 0)); + setWidgetFont(495); + setWidgetTextAlignment(0, 1, 0); + setWidgetPosition(0, 0, 0, 0); + svar0 = cs2method5055(arg1); + if (((boolean)globalint_126)) { + svar0 = "From " + globalstring_27 + ": " + "" + svar0; + } else if (globalint_126 == 2) { + svar0 = "[" + "" + cs2method3611() + "" + "] " + globalstring_27 + ": " + "" + svar0; + } else if (globalint_126 == 8) { + if (cs2method3751()) { + svar0 = "[" + "" + cs2method3752() + "" + "] " + globalstring_27 + ": " + "" + svar0; + } + } else if (globalint_126 == 10) { + if (cs2method3750()) { + svar0 = "[" + "" + cs2method3752() + "" + "] " + globalstring_27 + ": " + "" + svar0; + } + } else { + svar0 = globalstring_27 + ": " + "" + svar0; + } + setWidgetText(svar0); + setWidgetUnknownBoolean(false); + setWidgetSize(getMaxLineWidth(getWidgetActualWidth(new WidgetPointer(arg0)), 495, svar0), getWidgetActualHeight(new WidgetPointer(arg0)), 0, 0); + setWidgetIsHidden(false, new WidgetPointer(ivar2)); + ivar4 = cs2method5056(arg1); + ivar5 = 0; + ivar6 = 0; + ivar7 = 0; + ivar8 = 0; + ivar9 = -1; + ivar10 = 0; + while (ivar5 < ivar4) { + createExtraChild(new WidgetPointer(ivar2), 4, ivar6); + setWidgetRGB(new Color(0, 0, 0)); + setWidgetFont(495); + setWidgetTextAlignment(0, 1, 0); + ivar9 = cs2method5057(arg1, ivar5); + svar0 = cs2method5055(ivar9); + setScriptCallOnClickContextMenu(1070, new WidgetPointer(arg0), ivar9, 0, "Iei"); + cs2method1305(svar0); + setWidgetContextMenuOption(1, "Send: "); + setScriptCallOnMouseEntered(1082, 0, new WidgetPointer(ivar3), ivar6, "iIi"); + setScriptCallOnMouseExit(1083, 0, new WidgetPointer(ivar3), ivar6, "iIi"); + if (ivar5 < 10) { + svar0 = "" + intToStr(mod(add(ivar5, 1), 10)) + ". " + "" + svar0; + } + setWidgetText(svar0); + setWidgetUnknownBoolean(false); + ivar7 = getMaxLineWidth(getWidgetActualWidth(new WidgetPointer(arg0)), 495, svar0); + if (ivar7 > ivar8) { + ivar8 = ivar7; + } + ivar5 = add(ivar5, 1); + ivar6 = add(ivar6, 1); + } + setScriptCallOnKeyPress(1059, -2147483640, false, new WidgetPointer(arg0), 0, -1, arg1, ivar6, "izIikei", new WidgetPointer(ivar2)); + ivar5 = 0; + ivar11 = 0; + while (setWidgetRegister(new WidgetPointer(ivar2), ivar5)) { + if (add(multiply(ivar10, 14), 14) > getWidgetActualHeight(new WidgetPointer(ivar2))) { + ivar11 = add(add(ivar11, ivar8), 4); + ivar10 = 0; + } + setWidgetSize(ivar8, 14, 0, 0); + setWidgetPosition(add(ivar11, 2), multiply(ivar10, 14), 0, 0); + createExtraChild(new WidgetPointer(ivar3), 3, ivar5); + setWidgetSize(add(getWidgetActualWidth(), 4), getWidgetActualHeight(), 0, 0); + setWidgetPosition(subtract(getWidgetActualX(), 2), getWidgetActualY(), 0, 0); + setWidgetRGB(new Color(87, 126, 69)); + setWidgetFilled(1); + setWidgetHidden(1); + ivar5 = add(ivar5, 1); + ivar10 = add(ivar10, 1); + } + ivar11 = add(add(ivar11, ivar8), 4); + ivar12 = getWidgetParentId(new WidgetPointer(ivar2)); + setWidgetSize(ivar11, getWidgetActualHeight(new WidgetPointer(ivar12)), 0, 0, new WidgetPointer(ivar2)); + setWidgetSize(ivar11, getWidgetActualHeight(new WidgetPointer(ivar12)), 0, 0, new WidgetPointer(ivar3)); + script_1068(arg0, 0); + return; +} diff --git a/dumps/scripts/1064.cs2 b/dumps/scripts/1064.cs2 new file mode 100644 index 0000000..da39f5b --- /dev/null +++ b/dumps/scripts/1064.cs2 @@ -0,0 +1,29 @@ +void script_1064(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + ivar1 = ((int)cs2method_3408(105, 73, 1550, arg0)); + ivar2 = getWidgetParentId(new WidgetPointer(ivar1)); + if (((boolean)getWidgetScrollMaxH(new WidgetPointer(ivar2)))) { + setWidgetScrollMax(getWidgetActualWidth(new WidgetPointer(ivar2)), 0, new WidgetPointer(ivar2)); + } + ivar3 = getWidgetActualWidth(new WidgetPointer(ivar1)); + ivar4 = getWidgetActualX(new WidgetPointer(ivar1)); + while (arg0 > 0) { + arg0 = subtract(arg0, 1); + ivar1 = ((int)cs2method_3408(105, 73, 1550, arg0)); + if (isWidgetHidden(new WidgetPointer(ivar1)) && (add(ivar3, getWidgetActualWidth(new WidgetPointer(ivar1))) <= getWidgetActualWidth(new WidgetPointer(ivar2)))) { + ivar3 = add(ivar3, getWidgetActualWidth(new WidgetPointer(ivar1))); + ivar4 = getWidgetActualX(new WidgetPointer(ivar1)); + } else { + arg0 = -1; + } + } + if (cs2method2600(new WidgetPointer(ivar2)) == ivar4) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(ivar2)); + } else { + setScriptCallOnGameloop(1065, new WidgetPointer(ivar2), ivar4, "Ii", new WidgetPointer(ivar2)); + } + return; +} diff --git a/dumps/scripts/1065.cs2 b/dumps/scripts/1065.cs2 new file mode 100644 index 0000000..9376210 --- /dev/null +++ b/dumps/scripts/1065.cs2 @@ -0,0 +1,25 @@ +void script_1065(int arg0,int arg1) { + if (cs2method2600(new WidgetPointer(arg0)) > arg1) { + setWidgetScrollMax(subtract(getWidgetScrollMaxH(new WidgetPointer(arg0)), 10), 0, new WidgetPointer(arg0)); + cs2method2100(subtract(cs2method2600(new WidgetPointer(arg0)), 10), 0, new WidgetPointer(arg0)); + if (cs2method2600(new WidgetPointer(arg0)) < arg1) { + setWidgetScrollMax(add(arg1, getWidgetActualWidth(new WidgetPointer(arg0))), 0, new WidgetPointer(arg0)); + cs2method2100(arg1, 0, new WidgetPointer(arg0)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + return; + } + } else if (cs2method2600(new WidgetPointer(arg0)) < arg1) { + setWidgetScrollMax(add(getWidgetScrollMaxH(new WidgetPointer(arg0)), 10), 0, new WidgetPointer(arg0)); + cs2method2100(add(cs2method2600(new WidgetPointer(arg0)), 10), 0, new WidgetPointer(arg0)); + if (cs2method2600(new WidgetPointer(arg0)) > arg1) { + setWidgetScrollMax(add(arg1, getWidgetActualWidth(new WidgetPointer(arg0))), 0, new WidgetPointer(arg0)); + cs2method2100(arg1, 0, new WidgetPointer(arg0)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + return; + } + } else { + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + return; + } + return; +} diff --git a/dumps/scripts/1066.cs2 b/dumps/scripts/1066.cs2 new file mode 100644 index 0000000..8ba7608 --- /dev/null +++ b/dumps/scripts/1066.cs2 @@ -0,0 +1,80 @@ +void script_1066(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + ivar2 = getWidgetActualWidth(new WidgetPointer(arg0)); + ivar3 = 0; + ivar4 = 0; + ivar5 = 0; + while (setWidgetRegister(new WidgetPointer(arg0), ivar4)) { + ivar3 = add(ivar3, getWidgetActualWidth()); + ivar4 = add(ivar4, 1); + } + if (ivar3 <= ivar2) { + ivar4 = 0; + ivar5 = 0; + while (setWidgetRegister(new WidgetPointer(arg0), ivar4)) { + setWidgetHidden(0); + setWidgetPosition(ivar5, 0, 0, 0); + if (setWidgetRegister(new WidgetPointer(137,2), ivar4)) { + setWidgetPosition(getWidgetActualX(), getWidgetActualY(), 0, 0); + } + ivar5 = add(ivar5, getWidgetActualWidth()); + ivar4 = add(ivar4, 1); + } + return; + } + createExtraChild(new WidgetPointer(arg0), 4, add(arg1, 1)); + setWidgetRGB(new Color(0, 0, 0)); + setWidgetFont(495); + setWidgetTextAlignment(0, 1, 0); + setWidgetText(" ... " + ""); + setWidgetUnknownBoolean(false); + setWidgetSize(getMaxLineWidth(ivar2, 495, " ... " + ""), getWidgetActualHeight(new WidgetPointer(arg0)), 0, 0); + ivar3 = getWidgetActualWidth(); + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + ivar3 = add(ivar3, getWidgetActualWidth()); + } + ivar4 = 0; + while (ivar4 < arg1) { + if (setWidgetRegister(new WidgetPointer(arg0), ivar4)) { + if (add(ivar3, getWidgetActualWidth()) <= ivar2) { + setWidgetHidden(0); + ivar3 = add(ivar3, getWidgetActualWidth()); + } else { + setWidgetHidden(1); + } + } + ivar4 = add(ivar4, 1); + } + ivar4 = 0; + ivar5 = 0; + while (ivar4 < arg1) { + if (setWidgetRegister(new WidgetPointer(arg0), ivar4)) { + if (isWidgetHidden()) { + setWidgetPosition(ivar5, 0, 0, 0); + if (setWidgetRegister(new WidgetPointer(137,2), ivar4)) { + setWidgetPosition(getWidgetActualX(), getWidgetActualY(), 0, 0); + } + ivar5 = add(ivar5, getWidgetActualWidth()); + } else { + if (setWidgetRegister(new WidgetPointer(137,2), ivar4)) { + setWidgetHidden(1); + } + } + } + ivar4 = add(ivar4, 1); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(arg1, 1))) { + setWidgetPosition(ivar5, 0, 0, 0); + ivar5 = add(ivar5, getWidgetActualWidth()); + } + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetPosition(ivar5, 0, 0, 0); + if (setWidgetRegister(new WidgetPointer(137,2), ivar4)) { + setWidgetPosition(getWidgetActualX(), getWidgetActualY(), 0, 0); + } + } + return; +} diff --git a/dumps/scripts/1067.cs2 b/dumps/scripts/1067.cs2 new file mode 100644 index 0000000..378a56b --- /dev/null +++ b/dumps/scripts/1067.cs2 @@ -0,0 +1,4 @@ +void script_1067(int arg0,int arg1) { + script_1068(arg0, arg1); + return; +} diff --git a/dumps/scripts/1068.cs2 b/dumps/scripts/1068.cs2 new file mode 100644 index 0000000..1aac1c9 --- /dev/null +++ b/dumps/scripts/1068.cs2 @@ -0,0 +1,40 @@ +void script_1068(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + ivar2 = add(arg1, 1); + ivar3 = ((int)cs2method_3408(105, 73, 1550, ivar2)); + ivar4 = ((int)cs2method_3408(105, 73, 1551, ivar2)); + while (ivar3 != -1) { + deleteAllExtraChilds(new WidgetPointer(ivar3)); + deleteAllExtraChilds(new WidgetPointer(ivar4)); + setWidgetIsHidden(true, new WidgetPointer(ivar3)); + setScriptCallOnKeyPress(-1, "", new WidgetPointer(ivar3)); + ivar3 = ((int)cs2method_3408(105, 73, 1550, ivar2)); + ivar4 = ((int)cs2method_3408(105, 73, 1551, ivar2)); + ivar2 = add(ivar2, 1); + } + ivar2 = add(arg1, 1); + while (setWidgetRegister(new WidgetPointer(arg0), ivar2)) { + deleteExtraChild(); + if (setWidgetRegister(new WidgetPointer(137,2), ivar2)) { + deleteExtraChild(); + } + ivar2 = add(ivar2, 1); + } + ivar2 = 0; + ivar3 = ((int)cs2method_3408(105, 73, 1550, arg1)); + ivar4 = ((int)cs2method_3408(105, 73, 1551, arg1)); + while (setWidgetRegister(new WidgetPointer(ivar3), ivar2)) { + setScriptCallOnMouseEntered(1082, arg1, new WidgetPointer(ivar4), ivar2, "iIi"); + setScriptCallOnMouseExit(1083, arg1, new WidgetPointer(ivar4), ivar2, "iIi"); + if (setWidgetRegister(new WidgetPointer(ivar4), ivar2)) { + setWidgetHidden(1); + } + ivar2 = add(ivar2, 1); + } + globalint_128 = -1; + script_1064(arg1); + script_1066(arg0, arg1); + return; +} diff --git a/dumps/scripts/1069.cs2 b/dumps/scripts/1069.cs2 new file mode 100644 index 0000000..0df720e --- /dev/null +++ b/dumps/scripts/1069.cs2 @@ -0,0 +1,25 @@ +void script_1069() { + globalint_126 = globalint_131; + globalstring_27 = globalstring_28; + globalint_127 = 0; + if (isWidgetHidden(new WidgetPointer(137,0))) { + if (getDisplayMode() >= 2) { + setWidgetSprite(1017, new WidgetPointer(752,1)); + cs2method2122(0, 49283073); + setWidgetIsHidden(false, new WidgetPointer(752,1)); + setWidgetIsHidden(false, new WidgetPointer(752,2)); + } + setWidgetIsHidden(true, new WidgetPointer(137,50)); + setScriptCallOnKeyPress(-1, "", new WidgetPointer(137,56)); + setWidgetIsHidden(false, new WidgetPointer(137,0)); + setWidgetIsHidden(true, new WidgetPointer(137,7)); + setWidgetIsHidden(true, new WidgetPointer(137,9)); + setWidgetIsHidden(true, new WidgetPointer(137,13)); + setWidgetIsHidden(false, new WidgetPointer(137,17)); + setWidgetIsHidden(false, new WidgetPointer(137,1)); + setWidgetIsHidden(true, new WidgetPointer(137,3)); + cs2method2100(0, 0, new WidgetPointer(137,17)); + } + script_1071(8978433, globalint_130, -1); + return; +} diff --git a/dumps/scripts/107.cs2 b/dumps/scripts/107.cs2 new file mode 100644 index 0000000..2ecc1bd --- /dev/null +++ b/dumps/scripts/107.cs2 @@ -0,0 +1,24 @@ +void script_107(string arg0) { + if (((boolean)globalint_1413)) { + return; + } + if (((boolean)globalint_11)) { + messageType0("You can't do that while you're reporting abuse."); + return; + } + if (getDisplayMode() >= 2) { + setWidgetIsHidden(false, new WidgetPointer(746,73)); + } + globalstring_23 = arg0; + setWidgetIsHidden(false, new WidgetPointer(752,3)); + setWidgetIsHidden(true, new WidgetPointer(752,7)); + setWidgetIsHidden(true, new WidgetPointer(752,8)); + setWidgetText(new WidgetPointer(752,4), "Enter message to send to " + globalstring_23); + globalint_5 = 6; + script_1564(""); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(752,3)); + script_2026(); + setScriptCallOnKeyPress(112, -2147483640, false, "iz", new WidgetPointer(752,5)); + script_1188(); + return; +} diff --git a/dumps/scripts/1070.cs2 b/dumps/scripts/1070.cs2 new file mode 100644 index 0000000..41629e9 --- /dev/null +++ b/dumps/scripts/1070.cs2 @@ -0,0 +1,4 @@ +void script_1070(int arg0,int arg1,int arg2) { + script_1071(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/1071.cs2 b/dumps/scripts/1071.cs2 new file mode 100644 index 0000000..e97b93d --- /dev/null +++ b/dumps/scripts/1071.cs2 @@ -0,0 +1,12 @@ +void script_1071(int arg0,int arg1,int arg2) { + if (arg2 >= 0) { + script_1068(arg0, arg2); + } + globalint_134 = 0; + if (cs2method5066(arg1) > 0) { + script_1072(arg0, arg1); + } else { + script_1077(arg1); + } + return; +} diff --git a/dumps/scripts/1072.cs2 b/dumps/scripts/1072.cs2 new file mode 100644 index 0000000..fe7a07b --- /dev/null +++ b/dumps/scripts/1072.cs2 @@ -0,0 +1,38 @@ +void script_1072(int arg0,int arg1) { + int ivar2; + int ivar3; + flow_0: + ivar2 = cs2method5066(arg1); + ivar3 = 0; + IF ((ivar2 > 0) && (globalint_134 < ivar2)) + GOTO flow_2 + GOTO flow_12 + flow_1: + flow_2: + IF (globalint_134 < 10) + GOTO flow_3 + GOTO flow_12 + flow_3: + ivar3 = cs2method5067(arg1, globalint_134); + if (((boolean)ivar3)) { + script_1044(arg1); + return; + } + if (((boolean)ivar3)) { + script_1037(arg1, 0); + return; + } + if (ivar3 == 10) { + script_1037(arg1, 1); + return; + } + if (ivar3 == 2) { + script_1047(arg1); + return; + } + globalint_134 = add(globalint_134, 1); + GOTO flow_1 + flow_12: + script_1077(arg1); + return; +} diff --git a/dumps/scripts/1073.cs2 b/dumps/scripts/1073.cs2 new file mode 100644 index 0000000..bca4fe8 --- /dev/null +++ b/dumps/scripts/1073.cs2 @@ -0,0 +1,4 @@ +void script_1073(int arg0,int arg1,int arg2) { + script_1074(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/1074.cs2 b/dumps/scripts/1074.cs2 new file mode 100644 index 0000000..c748f8d --- /dev/null +++ b/dumps/scripts/1074.cs2 @@ -0,0 +1,36 @@ +void script_1074(int arg0,int arg1,int arg2) { + switch (globalint_134) { + case 0: + globalint_135 = arg2; + break; + case 1: + globalint_136 = arg2; + break; + case 2: + globalint_137 = arg2; + break; + case 3: + globalint_138 = arg2; + break; + case 4: + globalint_139 = arg2; + break; + case 5: + globalint_140 = arg2; + break; + case 6: + globalint_141 = arg2; + break; + case 7: + globalint_142 = arg2; + break; + case 8: + globalint_143 = arg2; + break; + case 9: + globalint_144 = arg2; + } + globalint_134 = add(globalint_134, 1); + script_1072(arg0, arg1); + return; +} diff --git a/dumps/scripts/1075.cs2 b/dumps/scripts/1075.cs2 new file mode 100644 index 0000000..9908993 --- /dev/null +++ b/dumps/scripts/1075.cs2 @@ -0,0 +1,4 @@ +void script_1075(int arg0,int arg1,int arg2) { + script_1076(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/1076.cs2 b/dumps/scripts/1076.cs2 new file mode 100644 index 0000000..80735fb --- /dev/null +++ b/dumps/scripts/1076.cs2 @@ -0,0 +1,36 @@ +void script_1076(int arg0,int arg1,int arg2) { + switch (globalint_134) { + case 0: + globalint_145 = arg2; + break; + case 1: + globalint_146 = arg2; + break; + case 2: + globalint_147 = arg2; + break; + case 3: + globalint_148 = arg2; + break; + case 4: + globalint_149 = arg2; + break; + case 5: + globalint_150 = arg2; + break; + case 6: + globalint_151 = arg2; + break; + case 7: + globalint_152 = arg2; + break; + case 8: + globalint_153 = arg2; + break; + case 9: + globalint_154 = arg2; + } + globalint_134 = add(globalint_134, 1); + script_1072(arg0, arg1); + return; +} diff --git a/dumps/scripts/1077.cs2 b/dumps/scripts/1077.cs2 new file mode 100644 index 0000000..f5c7b3a --- /dev/null +++ b/dumps/scripts/1077.cs2 @@ -0,0 +1,105 @@ +void script_1077(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + flow_0: + ivar1 = arg0; + if (arg0 == 105) { + if (bitconfig_7774 != 0) { + arg0 = 1021; + } else { + if (((boolean)standart_config_394)) { + arg0 = 561; + } + } + } + cs2method5058(arg0); + ivar2 = 0; + ivar3 = cs2method5066(arg0); + ivar4 = -1; + while ((ivar2 < ivar3) && (ivar2 < 10)) { + switch (cs2method5067(arg0, ivar2)) { + case 0: + script_1078(ivar2); + break; + case 1: + script_1079(ivar2); + break; + case 10: + script_1079(ivar2); + break; + case 2: + script_1078(ivar2); + } + ivar2 = add(ivar2, 1); + } + IF (((boolean)globalint_126) || (globalint_126 == 4)) + GOTO flow_15 + GOTO flow_16 + flow_15: + cs2method5059(); + GOTO flow_36 + flow_16: + IF (((boolean)globalint_126)) + GOTO flow_17 + GOTO flow_23 + flow_17: + ivar4 = script_1090(globalstring_27); + if (((boolean)ivar4)) { + cs2method5060(strRemoveEntities(globalstring_27)); + script_1089(); + } else if (ivar4 == -1) { + messageType0("Sorry, this user is not on your Friends List."); + } else { + messageType0("Sorry, your friend is no longer playing RuneScape."); + } + GOTO flow_36 + flow_23: + IF (globalint_126 == 5) + GOTO flow_24 + GOTO flow_25 + flow_24: + cs2method5060(strRemoveEntities(globalstring_27)); + script_1089(); + GOTO flow_36 + flow_25: + IF ((globalint_126 == 3) || (globalint_126 == 7)) + GOTO flow_26 + GOTO flow_27 + flow_26: + cs2method5060(strRemoveEntities(globalstring_27)); + script_1089(); + GOTO flow_36 + flow_27: + IF ((globalint_126 == 2) || (globalint_126 == 6)) + GOTO flow_28 + GOTO flow_29 + flow_28: + cs2method5061(); + GOTO flow_36 + flow_29: + IF ((globalint_126 == 8) || (globalint_126 == 9)) + GOTO flow_30 + GOTO flow_33 + flow_30: + if (cs2method3751()) { + cs2method5074(); + } + GOTO flow_36 + flow_33: + IF (globalint_126 == 10) + GOTO flow_34 + IF ((globalint_126 == 11) && cs2method3750()) + GOTO flow_35 + GOTO flow_36 + flow_34: + flow_35: + cs2method5075(); + flow_36: + globalint_130 = ivar1; + globalint_131 = globalint_126; + globalstring_28 = globalstring_27; + script_1054(); + return; +} diff --git a/dumps/scripts/1078.cs2 b/dumps/scripts/1078.cs2 new file mode 100644 index 0000000..04d665b --- /dev/null +++ b/dumps/scripts/1078.cs2 @@ -0,0 +1,34 @@ +void script_1078(int arg0) { + switch (arg0) { + case 0: + cs2method5068(0, globalint_135); + break; + case 1: + cs2method5068(1, globalint_136); + break; + case 2: + cs2method5068(2, globalint_137); + break; + case 3: + cs2method5068(3, globalint_138); + break; + case 4: + cs2method5068(4, globalint_139); + break; + case 5: + cs2method5068(5, globalint_140); + break; + case 6: + cs2method5068(6, globalint_141); + break; + case 7: + cs2method5068(7, globalint_142); + break; + case 8: + cs2method5068(8, globalint_143); + break; + case 9: + cs2method5068(9, globalint_144); + } + return; +} diff --git a/dumps/scripts/1079.cs2 b/dumps/scripts/1079.cs2 new file mode 100644 index 0000000..16ae40e --- /dev/null +++ b/dumps/scripts/1079.cs2 @@ -0,0 +1,34 @@ +void script_1079(int arg0) { + switch (arg0) { + case 0: + cs2method5069(0, globalint_145); + break; + case 1: + cs2method5069(1, globalint_146); + break; + case 2: + cs2method5069(2, globalint_147); + break; + case 3: + cs2method5069(3, globalint_148); + break; + case 4: + cs2method5069(4, globalint_149); + break; + case 5: + cs2method5069(5, globalint_150); + break; + case 6: + cs2method5069(6, globalint_151); + break; + case 7: + cs2method5069(7, globalint_152); + break; + case 8: + cs2method5069(8, globalint_153); + break; + case 9: + cs2method5069(9, globalint_154); + } + return; +} diff --git a/dumps/scripts/108.cs2 b/dumps/scripts/108.cs2 new file mode 100644 index 0000000..e5d3ef5 --- /dev/null +++ b/dumps/scripts/108.cs2 @@ -0,0 +1,17 @@ +void script_108(string arg0) { + if (getDisplayMode() >= 2) { + setWidgetIsHidden(false, new WidgetPointer(746,73)); + } + setWidgetIsHidden(false, new WidgetPointer(752,3)); + setWidgetIsHidden(true, new WidgetPointer(752,7)); + setWidgetIsHidden(true, new WidgetPointer(752,8)); + setWidgetText(new WidgetPointer(752,4), arg0); + globalint_5 = 7; + script_1564(""); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(752,3)); + script_2026(); + setScriptCallOnKeyPress(112, -2147483640, false, "iz", new WidgetPointer(752,5)); + setScriptCallOnWindowPaneRefresh(138, "", new WidgetPointer(752,5)); + script_1188(); + return; +} diff --git a/dumps/scripts/1080.cs2 b/dumps/scripts/1080.cs2 new file mode 100644 index 0000000..3650395 --- /dev/null +++ b/dumps/scripts/1080.cs2 @@ -0,0 +1,7 @@ +void script_1080(int arg0,int arg1) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetHidden(0); + setWidgetRGB(new Color(87, 126, 69)); + } + return; +} diff --git a/dumps/scripts/1081.cs2 b/dumps/scripts/1081.cs2 new file mode 100644 index 0000000..ce5207d --- /dev/null +++ b/dumps/scripts/1081.cs2 @@ -0,0 +1,6 @@ +void script_1081(int arg0,int arg1) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetHidden(1); + } + return; +} diff --git a/dumps/scripts/1082.cs2 b/dumps/scripts/1082.cs2 new file mode 100644 index 0000000..20e1866 --- /dev/null +++ b/dumps/scripts/1082.cs2 @@ -0,0 +1,35 @@ +void script_1082(int arg0,int arg1,int arg2) { + int ivar3; + ivar3 = add(arg0, 1); + if (isWidgetHidden(cs2method_3408(105, 73, 1550, ivar3))) { + if (setWidgetRegister(new WidgetPointer(arg1), arg2)) { + setWidgetHidden(0); + setWidgetRGB(new Color(150, 151, 119)); + } + if (globalint_128 >= 0) { + ivar3 = add(ivar3, 1); + while (isWidgetHidden(cs2method_3408(105, 73, 1550, ivar3))) { + ivar3 = add(ivar3, 1); + } + if (setWidgetRegister(cs2method_3408(105, 73, 1551, subtract(ivar3, 1)), globalint_128)) { + setWidgetHidden(1); + } + globalint_128 = -1; + } + return; + } + if (globalint_128 == arg2) { + return; + } + if ((globalint_128 >= 0) && setWidgetRegister(new WidgetPointer(arg1), globalint_128)) { + setWidgetHidden(1); + } + if (setWidgetRegister(new WidgetPointer(arg1), arg2)) { + if (isWidgetHidden()) { + setWidgetHidden(0); + setWidgetRGB(new Color(87, 126, 69)); + } + globalint_128 = arg2; + } + return; +} diff --git a/dumps/scripts/1083.cs2 b/dumps/scripts/1083.cs2 new file mode 100644 index 0000000..a52d438 --- /dev/null +++ b/dumps/scripts/1083.cs2 @@ -0,0 +1,4 @@ +void script_1083(int arg0,int arg1,int arg2) { + script_1084(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/1084.cs2 b/dumps/scripts/1084.cs2 new file mode 100644 index 0000000..9a66443 --- /dev/null +++ b/dumps/scripts/1084.cs2 @@ -0,0 +1,9 @@ +void script_1084(int arg0,int arg1,int arg2) { + if (isWidgetHidden(cs2method_3408(105, 73, 1550, add(arg0, 1)))) { + return; + } + if (setWidgetRegister(new WidgetPointer(arg1), arg2)) { + setWidgetHidden(1); + } + return; +} diff --git a/dumps/scripts/1085.cs2 b/dumps/scripts/1085.cs2 new file mode 100644 index 0000000..91ea5ee --- /dev/null +++ b/dumps/scripts/1085.cs2 @@ -0,0 +1,4 @@ +void script_1085(int arg0,int arg1,int arg2,int arg3) { + script_1086(arg0, arg1, arg2, arg3); + return; +} diff --git a/dumps/scripts/1086.cs2 b/dumps/scripts/1086.cs2 new file mode 100644 index 0000000..fba9321 --- /dev/null +++ b/dumps/scripts/1086.cs2 @@ -0,0 +1,60 @@ +void script_1086(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + int ivar6; + deleteAllExtraChilds(new WidgetPointer(arg0)); + ivar4 = getWidgetActualWidth(new WidgetPointer(arg0)); + ivar5 = getWidgetActualHeight(new WidgetPointer(arg0)); + ivar6 = 0; + if (arg1 > 0) { + createExtraChild(new WidgetPointer(arg0), 5, ivar6); + setWidgetPosition(0, arg1, 0, 0); + setWidgetSize(ivar4, 32, 0, 0); + setWidgetSprite(1076); + cs2method1107(1); + ivar6 = add(ivar6, 1); + } + if (arg2 > 0) { + createExtraChild(new WidgetPointer(arg0), 5, ivar6); + setWidgetPosition(0, arg2, 0, 0); + setWidgetSize(ivar4, 32, 0, 0); + setWidgetSprite(1076); + cs2method1107(1); + ivar6 = add(ivar6, 1); + } + if (arg3 > 0) { + createExtraChild(new WidgetPointer(arg0), 5, ivar6); + setWidgetPosition(0, arg3, 0, 0); + setWidgetSize(ivar4, 32, 0, 0); + setWidgetSprite(1076); + cs2method1107(1); + ivar6 = add(ivar6, 1); + } + createExtraChild(new WidgetPointer(arg0), 5, ivar6); + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(ivar4, 32, 0, 0); + setWidgetSprite(1076); + cs2method1107(1); + ivar6 = add(ivar6, 1); + createExtraChild(new WidgetPointer(arg0), 5, ivar6); + setWidgetPosition(0, subtract(ivar5, 32), 0, 0); + setWidgetSize(ivar4, 32, 0, 0); + setWidgetSprite(1076); + cs2method1107(1); + setWidgetVFlip(1); + ivar6 = add(ivar6, 1); + createExtraChild(new WidgetPointer(arg0), 5, ivar6); + setWidgetPosition(0, 1, 0, 0); + setWidgetSize(32, subtract(ivar5, 2), 0, 0); + setWidgetSprite(1077); + cs2method1107(1); + ivar6 = add(ivar6, 1); + createExtraChild(new WidgetPointer(arg0), 5, ivar6); + setWidgetPosition(subtract(ivar4, 32), 1, 0, 0); + setWidgetSize(32, subtract(ivar5, 2), 0, 0); + setWidgetSprite(1077); + cs2method1107(1); + setWidgetHFlip(1); + ivar6 = add(ivar6, 1); + return; +} diff --git a/dumps/scripts/1087.cs2 b/dumps/scripts/1087.cs2 new file mode 100644 index 0000000..191ee09 --- /dev/null +++ b/dumps/scripts/1087.cs2 @@ -0,0 +1,4 @@ +void script_1087(int arg0,int arg1) { + script_1088(arg0, arg1); + return; +} diff --git a/dumps/scripts/1088.cs2 b/dumps/scripts/1088.cs2 new file mode 100644 index 0000000..0b4c0a7 --- /dev/null +++ b/dumps/scripts/1088.cs2 @@ -0,0 +1,71 @@ +void script_1088(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + ivar2 = getWidgetActualWidth(new WidgetPointer(arg0)); + ivar3 = getWidgetActualHeight(new WidgetPointer(arg0)); + ivar4 = getExtraChildGap(new WidgetPointer(arg0)); + createExtraChild(new WidgetPointer(arg0), 5, ivar4); + setWidgetPosition(0, -13, 1, 0); + setWidgetSize(4, 32, 1, 0); + setWidgetSprite(820); + cs2method1107(1); + ivar4 = add(ivar4, 1); + createExtraChild(new WidgetPointer(arg0), 5, ivar4); + setWidgetPosition(0, -12, 1, 2); + setWidgetSize(4, 32, 1, 0); + setWidgetSprite(822); + cs2method1107(1); + ivar4 = add(ivar4, 1); + createExtraChild(new WidgetPointer(arg0), 5, ivar4); + setWidgetPosition(-13, 0, 0, 1); + setWidgetSize(32, 4, 0, 1); + setWidgetSprite(821); + cs2method1107(1); + ivar4 = add(ivar4, 1); + createExtraChild(new WidgetPointer(arg0), 5, ivar4); + setWidgetPosition(-12, 0, 2, 1); + setWidgetSize(32, 4, 0, 1); + setWidgetSprite(823); + cs2method1107(1); + ivar4 = add(ivar4, 1); + createExtraChild(new WidgetPointer(arg0), 5, ivar4); + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(32, 32, 0, 0); + setWidgetSprite(824); + ivar4 = add(ivar4, 1); + createExtraChild(new WidgetPointer(arg0), 5, ivar4); + setWidgetPosition(0, 0, 2, 0); + setWidgetSize(32, 32, 0, 0); + setWidgetSprite(825); + ivar4 = add(ivar4, 1); + createExtraChild(new WidgetPointer(arg0), 5, ivar4); + setWidgetPosition(0, 0, 0, 2); + setWidgetSize(32, 32, 0, 0); + setWidgetSprite(826); + ivar4 = add(ivar4, 1); + createExtraChild(new WidgetPointer(arg0), 5, ivar4); + setWidgetPosition(0, 0, 2, 2); + setWidgetSize(32, 32, 0, 0); + setWidgetSprite(827); + ivar4 = add(ivar4, 1); + if (arg1 > 0) { + createExtraChild(new WidgetPointer(arg0), 5, ivar4); + setWidgetPosition(0, subtract(arg1, 5), 1, 0); + setWidgetSize(4, 32, 1, 0); + setWidgetSprite(828); + cs2method1107(1); + ivar4 = add(ivar4, 1); + createExtraChild(new WidgetPointer(arg0), 5, ivar4); + setWidgetPosition(0, subtract(arg1, 3), 0, 0); + setWidgetSize(32, 32, 0, 0); + setWidgetSprite(829); + ivar4 = add(ivar4, 1); + createExtraChild(new WidgetPointer(arg0), 5, ivar4); + setWidgetPosition(0, subtract(arg1, 3), 2, 0); + setWidgetSize(32, 32, 0, 0); + setWidgetSprite(830); + ivar4 = add(ivar4, 1); + } + return; +} diff --git a/dumps/scripts/1089.cs2 b/dumps/scripts/1089.cs2 new file mode 100644 index 0000000..0ede81f --- /dev/null +++ b/dumps/scripts/1089.cs2 @@ -0,0 +1,9 @@ +void script_1089() { + if (cs2method5005() == 2) { + cs2method5001(cs2method5000(), 1, cs2method5016()); + script_178(); + script_84(); + script_89(); + } + return; +} diff --git a/dumps/scripts/109.cs2 b/dumps/scripts/109.cs2 new file mode 100644 index 0000000..7573f41 --- /dev/null +++ b/dumps/scripts/109.cs2 @@ -0,0 +1,28 @@ +void script_109(string arg0) { + if (getDisplayMode() >= 2) { + setWidgetIsHidden(false, new WidgetPointer(746,73)); + } + setWidgetIsHidden(false, new WidgetPointer(752,3)); + setWidgetIsHidden(true, new WidgetPointer(752,7)); + setWidgetIsHidden(true, new WidgetPointer(752,8)); + setWidgetText(new WidgetPointer(752,4), arg0); + globalint_5 = 8; + script_1564(""); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(752,3)); + script_2026(); + setScriptCallOnKeyPress(112, -2147483640, false, "iz", new WidgetPointer(752,5)); + setScriptCallOnWindowPaneRefresh(138, "", new WidgetPointer(752,5)); + if (((boolean)globalint_1026) && (strLength(globalstring_201) > 0)) { + createExtraChild(new WidgetPointer(752,3), 4, 0); + script_2752(); + setWidgetText("Last name entered: " + globalstring_201); + setWidgetContextMenuOption(1, "Use:"); + cs2method1305("" + strRemoveEntities(globalstring_201) + ""); + setScriptCallOnClickContextMenu(2753, globalint_5, -2147483644, new WidgetPointer(-32768,3), -2147483643, globalstring_201, "iiIis"); + } else { + globalstring_201 = ""; + globalint_1026 = 1; + } + script_1188(); + return; +} diff --git a/dumps/scripts/1090.cs2 b/dumps/scripts/1090.cs2 new file mode 100644 index 0000000..cb159c1 --- /dev/null +++ b/dumps/scripts/1090.cs2 @@ -0,0 +1,14 @@ +int script_1090(string arg0) { + int ivar0; + ivar0 = cs2method3628(arg0); + if (ivar0 == -1) { + return -1; + } + if (((boolean)getFriendWorld(ivar0))) { + return 0; + } + if (cs2method3627(ivar0)) { + return 1; + } + return 2; +} diff --git a/dumps/scripts/1091.cs2 b/dumps/scripts/1091.cs2 new file mode 100644 index 0000000..3b3d578 --- /dev/null +++ b/dumps/scripts/1091.cs2 @@ -0,0 +1,4 @@ +void script_1091(int arg0,int arg1) { + setWidgetText(new WidgetPointer(arg0), intToStr(getItemAmtInContainer(93, arg1))); + return; +} diff --git a/dumps/scripts/1092.cs2 b/dumps/scripts/1092.cs2 new file mode 100644 index 0000000..5232d0f --- /dev/null +++ b/dumps/scripts/1092.cs2 @@ -0,0 +1,70 @@ +void script_1092(int arg0) { + if (((boolean)arg0)) { + if (bitconfig_1892 == 60) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(145,2)); + } else if (((boolean)bitconfig_1892)) { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(145,2)); + } else { + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(145,2)); + } + } else if (arg0 == 2) { + if (bitconfig_1867 == 40) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(145,3)); + } else if (((boolean)bitconfig_1867)) { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(145,3)); + } else { + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(145,3)); + } + } else if (arg0 == 3) { + if (bitconfig_1895 == 110) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(145,4)); + } else if (((boolean)bitconfig_1895)) { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(145,4)); + } else { + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(145,4)); + } + } else if (arg0 == 4) { + if (bitconfig_1896 == 5) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(145,5)); + } else if (((boolean)bitconfig_1896)) { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(145,5)); + } else { + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(145,5)); + } + } else if (arg0 == 5) { + if (bitconfig_1878 == 5) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(145,6)); + } else if (((boolean)bitconfig_1878)) { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(145,6)); + } else { + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(145,6)); + } + } else if (arg0 == 6) { + if (bitconfig_1910 == 20) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(145,7)); + } else if (((boolean)bitconfig_1910)) { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(145,7)); + } else { + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(145,7)); + } + } else if (arg0 == 7) { + if (bitconfig_1904 == 170) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(145,8)); + } else if (((boolean)bitconfig_1904)) { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(145,8)); + } else { + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(145,8)); + } + } else { + if (arg0 == 8) { + if (bitconfig_1914 == 50) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(145,9)); + } else if (((boolean)bitconfig_1914)) { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(145,9)); + } else { + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(145,9)); + } + } + } + return; +} diff --git a/dumps/scripts/1093.cs2 b/dumps/scripts/1093.cs2 new file mode 100644 index 0000000..f64a5e5 --- /dev/null +++ b/dumps/scripts/1093.cs2 @@ -0,0 +1,4 @@ +void script_1093(int arg0,int arg1) { + setWidgetSprite(arg1, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1094.cs2 b/dumps/scripts/1094.cs2 new file mode 100644 index 0000000..2b6a4a2 --- /dev/null +++ b/dumps/scripts/1094.cs2 @@ -0,0 +1,8 @@ +void script_1094() { + if (((boolean)standart_config_1241)) { + script_1095(); + } else { + script_1096(); + } + return; +} diff --git a/dumps/scripts/1095.cs2 b/dumps/scripts/1095.cs2 new file mode 100644 index 0000000..1ff60a6 --- /dev/null +++ b/dumps/scripts/1095.cs2 @@ -0,0 +1,7 @@ +void script_1095() { + opcStruct6203(2,0,0) structdump_0; + script_1097(); + structdump_0 = cs2method6203(); + setWidgetSize(structdump_0.intpart_0, structdump_0.intpart_1, 0, 0, new WidgetPointer(746,9)); + return; +} diff --git a/dumps/scripts/1096.cs2 b/dumps/scripts/1096.cs2 new file mode 100644 index 0000000..ed256bb --- /dev/null +++ b/dumps/scripts/1096.cs2 @@ -0,0 +1,7 @@ +void script_1096() { + opcStruct6203(2,0,0) structdump_0; + script_1098(); + structdump_0 = cs2method6203(); + setWidgetSize(structdump_0.intpart_0, structdump_0.intpart_1, 0, 0, new WidgetPointer(746,9)); + return; +} diff --git a/dumps/scripts/1097.cs2 b/dumps/scripts/1097.cs2 new file mode 100644 index 0000000..ff98982 --- /dev/null +++ b/dumps/scripts/1097.cs2 @@ -0,0 +1,6 @@ +void script_1097() { + cs2method6200(256, 256); + cs2method6201(256, 256); + cs2method6202(256, 256, 256, 256); + return; +} diff --git a/dumps/scripts/1098.cs2 b/dumps/scripts/1098.cs2 new file mode 100644 index 0000000..d8db0f0 --- /dev/null +++ b/dumps/scripts/1098.cs2 @@ -0,0 +1,6 @@ +void script_1098() { + cs2method6200(0, 0); + cs2method6201(0, 0); + cs2method6202(0, 0, 0, 0); + return; +} diff --git a/dumps/scripts/1099.cs2 b/dumps/scripts/1099.cs2 new file mode 100644 index 0000000..458a684 --- /dev/null +++ b/dumps/scripts/1099.cs2 @@ -0,0 +1,4 @@ +void script_1099() { + script_1264(); + return; +} diff --git a/dumps/scripts/11.cs2 b/dumps/scripts/11.cs2 new file mode 100644 index 0000000..e4b4669 --- /dev/null +++ b/dumps/scripts/11.cs2 @@ -0,0 +1,4 @@ +void script_11(int arg0) { + deleteAllExtraChilds(new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/110.cs2 b/dumps/scripts/110.cs2 new file mode 100644 index 0000000..d481370 --- /dev/null +++ b/dumps/scripts/110.cs2 @@ -0,0 +1,37 @@ +void script_110(string arg0) { + if (getDisplayMode() >= 2) { + setWidgetIsHidden(false, new WidgetPointer(746,73)); + } + setWidgetIsHidden(false, new WidgetPointer(752,3)); + setWidgetIsHidden(true, new WidgetPointer(752,7)); + setWidgetIsHidden(true, new WidgetPointer(752,8)); + setWidgetText(new WidgetPointer(752,4), arg0); + globalint_5 = 9; + if (((boolean)stringMethod4107("null", globalstring_350))) { + globalstring_350 = ""; + } + if (stringMethod4107("", globalstring_350) != 0) { + script_1564(globalstring_350); + globalstring_350 = ""; + } else { + script_1564(""); + } + if (((boolean)stringMethod4107("null", globalstring_354))) { + globalstring_354 = ""; + } + setScriptCallOnMousePressed(-1, "", new WidgetPointer(752,3)); + script_2026(); + setScriptCallOnKeyPress(112, -2147483640, false, "iz", new WidgetPointer(752,5)); + setScriptCallOnWindowPaneRefresh(138, "", new WidgetPointer(752,5)); + if (stringMethod4107(globalstring_354, "") != 0) { + createExtraChild(new WidgetPointer(752,3), 4, 0); + script_2752(); + setWidgetText("Last entered: " + globalstring_354); + setWidgetContextMenuOption(1, "Use:"); + cs2method1305("" + strRemoveEntities(globalstring_354) + ""); + setScriptCallOnClickContextMenu(2753, globalint_5, -2147483644, new WidgetPointer(-32768,3), -2147483643, globalstring_354, "iiIis"); + globalstring_354 = ""; + } + script_1188(); + return; +} diff --git a/dumps/scripts/1100.cs2 b/dumps/scripts/1100.cs2 new file mode 100644 index 0000000..255f9eb --- /dev/null +++ b/dumps/scripts/1100.cs2 @@ -0,0 +1,15 @@ +int script_1100() { + int ivar0; + ivar0 = 0; + ivar0 = add(ivar0, bitconfig_3600); + ivar0 = add(ivar0, bitconfig_3601); + ivar0 = add(ivar0, bitconfig_3602); + ivar0 = add(ivar0, bitconfig_3603); + ivar0 = add(ivar0, bitconfig_3604); + ivar0 = add(ivar0, bitconfig_3605); + ivar0 = add(ivar0, bitconfig_3606); + ivar0 = add(ivar0, bitconfig_3607); + ivar0 = add(ivar0, bitconfig_3608); + ivar0 = add(ivar0, bitconfig_3609); + return ivar0; +} diff --git a/dumps/scripts/1101.cs2 b/dumps/scripts/1101.cs2 new file mode 100644 index 0000000..6ed1a15 --- /dev/null +++ b/dumps/scripts/1101.cs2 @@ -0,0 +1,4 @@ +void script_1101() { + script_1265(); + return; +} diff --git a/dumps/scripts/1102.cs2 b/dumps/scripts/1102.cs2 new file mode 100644 index 0000000..ffd32ea --- /dev/null +++ b/dumps/scripts/1102.cs2 @@ -0,0 +1,4 @@ +void script_1102() { + setWidgetText(new WidgetPointer(377,4), intToStr(bitconfig_907) + "%"); + return; +} diff --git a/dumps/scripts/1103.cs2 b/dumps/scripts/1103.cs2 new file mode 100644 index 0000000..38e7bcd --- /dev/null +++ b/dumps/scripts/1103.cs2 @@ -0,0 +1,12 @@ +int script_1103() { + if (((boolean)globalint_754)) { + return 0; + } + if (globalint_754 == 9) { + return 0; + } + if (globalint_754 == 12) { + return 0; + } + return 1; +} diff --git a/dumps/scripts/1104.cs2 b/dumps/scripts/1104.cs2 new file mode 100644 index 0000000..0a62931 --- /dev/null +++ b/dumps/scripts/1104.cs2 @@ -0,0 +1,16 @@ +void script_1104() { + if (((boolean)cs2method5420())) { + setWidgetText(new WidgetPointer(182,1), "When you have finished playing" + "
" + "RuneScape, always use a" + "
" + "button below to exit the game and logout safely."); + setWidgetText(new WidgetPointer(182,6), "Exit to Lobby"); + setWidgetContextMenuOption(1, new WidgetPointer(182,6), "Exit to Lobby"); + setWidgetIsHidden(false, new WidgetPointer(182,7)); + setWidgetText(new WidgetPointer(182,13), "Exit to Login"); + setWidgetContextMenuOption(1, new WidgetPointer(182,13), "Exit to Login"); + } else { + setWidgetText(new WidgetPointer(182,1), "When you have finished playing" + "
" + "RuneScape, always use the" + "
" + "button below to exit the game and logout safely."); + setWidgetText(new WidgetPointer(182,6), "Click here to log out"); + setWidgetContextMenuOption(1, new WidgetPointer(182,6), "Logout"); + setWidgetIsHidden(true, new WidgetPointer(182,7)); + } + return; +} diff --git a/dumps/scripts/1105.cs2 b/dumps/scripts/1105.cs2 new file mode 100644 index 0000000..bebf121 --- /dev/null +++ b/dumps/scripts/1105.cs2 @@ -0,0 +1,4 @@ +void script_1105() { + script_1269(); + return; +} diff --git a/dumps/scripts/1106.cs2 b/dumps/scripts/1106.cs2 new file mode 100644 index 0000000..5dc274f --- /dev/null +++ b/dumps/scripts/1106.cs2 @@ -0,0 +1,15 @@ +int script_1106() { + int ivar0; + ivar0 = 0; + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 5); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + return ivar0; +} diff --git a/dumps/scripts/1107.cs2 b/dumps/scripts/1107.cs2 new file mode 100644 index 0000000..fa9566f --- /dev/null +++ b/dumps/scripts/1107.cs2 @@ -0,0 +1,4 @@ +void script_1107() { + script_1271(1); + return; +} diff --git a/dumps/scripts/1108.cs2 b/dumps/scripts/1108.cs2 new file mode 100644 index 0000000..81d0455 --- /dev/null +++ b/dumps/scripts/1108.cs2 @@ -0,0 +1,24 @@ +int script_1108() { + int ivar0; + ivar0 = 0; + ivar0 = add(ivar0, bitconfig_3986); + ivar0 = add(ivar0, bitconfig_3987); + ivar0 = add(ivar0, bitconfig_3988); + ivar0 = add(ivar0, bitconfig_3989); + ivar0 = add(ivar0, bitconfig_3990); + ivar0 = add(ivar0, bitconfig_3991); + ivar0 = add(ivar0, bitconfig_3992); + ivar0 = add(ivar0, bitconfig_3993); + ivar0 = add(ivar0, bitconfig_3994); + ivar0 = add(ivar0, bitconfig_3995); + ivar0 = add(ivar0, bitconfig_3996); + ivar0 = add(ivar0, bitconfig_3997); + ivar0 = add(ivar0, bitconfig_3998); + ivar0 = add(ivar0, bitconfig_3999); + ivar0 = add(ivar0, bitconfig_4000); + ivar0 = add(ivar0, bitconfig_4001); + ivar0 = add(ivar0, bitconfig_4002); + ivar0 = add(ivar0, bitconfig_4005); + ivar0 = add(ivar0, bitconfig_4004); + return ivar0; +} diff --git a/dumps/scripts/1109.cs2 b/dumps/scripts/1109.cs2 new file mode 100644 index 0000000..c5d0553 --- /dev/null +++ b/dumps/scripts/1109.cs2 @@ -0,0 +1,4 @@ +void script_1109() { + script_1271(0); + return; +} diff --git a/dumps/scripts/111.cs2 b/dumps/scripts/111.cs2 new file mode 100644 index 0000000..d634aa3 --- /dev/null +++ b/dumps/scripts/111.cs2 @@ -0,0 +1,34 @@ +void script_111() { + if (((boolean)globalint_1413)) { + return; + } + if (((boolean)globalint_11)) { + script_675(); + } + if (getDisplayMode() >= 2) { + setWidgetIsHidden(false, new WidgetPointer(746,73)); + } + setWidgetIsHidden(false, new WidgetPointer(752,3)); + setWidgetIsHidden(true, new WidgetPointer(752,7)); + setWidgetIsHidden(true, new WidgetPointer(752,8)); + setWidgetText(new WidgetPointer(752,4), "Enter the player name whose channel you wish to join:"); + globalint_5 = 10; + script_1564(""); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(752,3)); + script_2026(); + setScriptCallOnKeyPress(112, -2147483640, false, "iz", new WidgetPointer(752,5)); + createExtraChild(new WidgetPointer(752,3), 4, 0); + script_2752(); + if (((boolean)globalint_1027) && (strLength(globalstring_202) > 0)) { + setWidgetText("Last name entered: " + globalstring_202); + } else { + globalstring_202 = strRemoveEntities(cs2method5015()); + globalint_1027 = 1; + setWidgetText("Your name: " + globalstring_202); + } + setWidgetContextMenuOption(1, "Use:"); + cs2method1305("" + strRemoveEntities(globalstring_202) + ""); + setScriptCallOnClickContextMenu(2753, globalint_5, -2147483644, new WidgetPointer(-32768,3), -2147483643, globalstring_202, "iiIis"); + script_1188(); + return; +} diff --git a/dumps/scripts/1110.cs2 b/dumps/scripts/1110.cs2 new file mode 100644 index 0000000..6728faa --- /dev/null +++ b/dumps/scripts/1110.cs2 @@ -0,0 +1,9 @@ +void script_1110(int arg0) { + if (arg0 != 1) { + return; + } + bitconfig_1010 = min(add(bitconfig_1010, 1), 3); + playSoundEffect(1041, 1, 0); + script_1271(1); + return; +} diff --git a/dumps/scripts/1111.cs2 b/dumps/scripts/1111.cs2 new file mode 100644 index 0000000..d57961d --- /dev/null +++ b/dumps/scripts/1111.cs2 @@ -0,0 +1,86 @@ +string script_1111() { + switch (globalint_754) { + case 0: + case 9: + if (((boolean)script_1103()) && (bitconfig_8095 >= bitconfig_8094)) { + return "Make All"; + } + return "Make " + intToStr(bitconfig_8095); + case 1: + if (((boolean)bitconfig_8095)) { + return "Make 1 set"; + } + return "Make " + intToStr(bitconfig_8095) + " sets"; + case 2: + if (((boolean)script_1103()) && (bitconfig_8095 >= bitconfig_8094)) { + return "Cook All"; + } + return "Cook " + intToStr(bitconfig_8095); + case 3: + if (((boolean)script_1103()) && (bitconfig_8095 >= bitconfig_8094)) { + return "Roast All"; + } + return "Roast " + intToStr(bitconfig_8095); + case 4: + if (((boolean)script_1103()) && (bitconfig_8095 >= bitconfig_8094)) { + return "Offer All"; + } + return "Offer " + intToStr(bitconfig_8095); + case 5: + if (((boolean)script_1103()) && (bitconfig_8095 >= bitconfig_8094)) { + return "Sell All"; + } + return "Sell " + intToStr(bitconfig_8095); + case 6: + if (((boolean)script_1103()) && (bitconfig_8095 >= bitconfig_8094)) { + return "Bake All"; + } + return "Bake " + intToStr(bitconfig_8095); + case 7: + if (((boolean)script_1103()) && (bitconfig_8095 >= bitconfig_8094)) { + return "Cut All"; + } + return "Cut " + intToStr(bitconfig_8095); + case 8: + if (((boolean)script_1103()) && (bitconfig_8095 >= bitconfig_8094)) { + return "Deposit All"; + } + return "Deposit " + intToStr(bitconfig_8095); + case 10: + if (((boolean)script_1103()) && (bitconfig_8095 >= bitconfig_8094)) { + return "Teleport All"; + } + return "Teleport " + intToStr(bitconfig_8095); + case 11: + if (((boolean)script_1103()) && (bitconfig_8095 >= bitconfig_8094)) { + return "Select All"; + } + break; + case 12: + if (((boolean)bitconfig_8095)) { + return "Make 1 set"; + } + return "Make " + intToStr(bitconfig_8095) + " sets"; + case 13: + if (((boolean)script_1103()) && (bitconfig_8095 >= bitconfig_8094)) { + return "Take All"; + } + return "Take " + intToStr(bitconfig_8095); + case 14: + if (((boolean)script_1103()) && (bitconfig_8095 >= bitconfig_8094)) { + return "Return All"; + } + return "Return " + intToStr(bitconfig_8095); + case 15: + if (((boolean)script_1103()) && (bitconfig_8095 >= bitconfig_8094)) { + return "Heat All"; + } + return "Heat " + intToStr(bitconfig_8095); + case 16: + if (((boolean)script_1103()) && (bitconfig_8095 >= bitconfig_8094)) { + return "Add All"; + } + return "Add " + intToStr(bitconfig_8095); + } + return "Select"; +} diff --git a/dumps/scripts/1112.cs2 b/dumps/scripts/1112.cs2 new file mode 100644 index 0000000..adb034f --- /dev/null +++ b/dumps/scripts/1112.cs2 @@ -0,0 +1,24 @@ +int script_1112() { + int ivar0; + ivar0 = 0; + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + return ivar0; +} diff --git a/dumps/scripts/1113.cs2 b/dumps/scripts/1113.cs2 new file mode 100644 index 0000000..597b493 --- /dev/null +++ b/dumps/scripts/1113.cs2 @@ -0,0 +1,26 @@ +int script_1113() { + int ivar0; + ivar0 = 0; + ivar0 = add(ivar0, bitconfig_4003); + ivar0 = add(ivar0, bitconfig_4007); + ivar0 = add(ivar0, bitconfig_4008); + ivar0 = add(ivar0, bitconfig_4009); + ivar0 = add(ivar0, bitconfig_4010); + ivar0 = add(ivar0, bitconfig_4011); + ivar0 = add(ivar0, bitconfig_4012); + ivar0 = add(ivar0, bitconfig_4013); + ivar0 = add(ivar0, bitconfig_4014); + ivar0 = add(ivar0, bitconfig_4015); + ivar0 = add(ivar0, bitconfig_4016); + ivar0 = add(ivar0, bitconfig_4017); + ivar0 = add(ivar0, bitconfig_4018); + ivar0 = add(ivar0, bitconfig_4019); + ivar0 = add(ivar0, bitconfig_4020); + ivar0 = add(ivar0, bitconfig_4021); + ivar0 = add(ivar0, bitconfig_4022); + ivar0 = add(ivar0, bitconfig_4023); + ivar0 = add(ivar0, bitconfig_4024); + ivar0 = add(ivar0, bitconfig_4025); + ivar0 = add(ivar0, bitconfig_4026); + return ivar0; +} diff --git a/dumps/scripts/1114.cs2 b/dumps/scripts/1114.cs2 new file mode 100644 index 0000000..98e35e0 --- /dev/null +++ b/dumps/scripts/1114.cs2 @@ -0,0 +1,26 @@ +int script_1114() { + int ivar0; + ivar0 = 0; + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 4); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + return ivar0; +} diff --git a/dumps/scripts/1115.cs2 b/dumps/scripts/1115.cs2 new file mode 100644 index 0000000..a8d98d6 --- /dev/null +++ b/dumps/scripts/1115.cs2 @@ -0,0 +1,18 @@ +int script_1115() { + int ivar0; + ivar0 = 0; + ivar0 = add(ivar0, bitconfig_4028); + ivar0 = add(ivar0, bitconfig_4027); + ivar0 = add(ivar0, bitconfig_4029); + ivar0 = add(ivar0, bitconfig_4030); + ivar0 = add(ivar0, bitconfig_4031); + ivar0 = add(ivar0, bitconfig_4032); + ivar0 = add(ivar0, bitconfig_4033); + ivar0 = add(ivar0, bitconfig_4034); + ivar0 = add(ivar0, bitconfig_4035); + ivar0 = add(ivar0, bitconfig_4036); + ivar0 = add(ivar0, bitconfig_4037); + ivar0 = add(ivar0, bitconfig_4038); + ivar0 = add(ivar0, bitconfig_4039); + return ivar0; +} diff --git a/dumps/scripts/1116.cs2 b/dumps/scripts/1116.cs2 new file mode 100644 index 0000000..041ab1c --- /dev/null +++ b/dumps/scripts/1116.cs2 @@ -0,0 +1,18 @@ +int script_1116() { + int ivar0; + ivar0 = 0; + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + return ivar0; +} diff --git a/dumps/scripts/1117.cs2 b/dumps/scripts/1117.cs2 new file mode 100644 index 0000000..3592226 --- /dev/null +++ b/dumps/scripts/1117.cs2 @@ -0,0 +1,116 @@ +void script_1117(int arg0) { + int ivar1; + string svar0; + ivar1 = -1; + svar0 = ""; + switch (arg0) { + case 12582919: + if (((boolean)bitconfig_6459)) { + svar0 = "Hide combat spells."; + } else { + svar0 = "Show combat spells."; + } + ivar1 = 12583008; + break; + case 12582921: + if (((boolean)bitconfig_6462)) { + svar0 = "Hide teleport spells."; + } else { + svar0 = "Show teleport spells."; + } + ivar1 = 12583008; + break; + case 12582923: + if (((boolean)bitconfig_6461)) { + svar0 = "Hide miscellaneous spells."; + } else { + svar0 = "Show miscellaneous spells."; + } + ivar1 = 12583008; + break; + case 12582925: + if (((boolean)bitconfig_6460)) { + svar0 = "Hide skill spells."; + } else { + svar0 = "Show skill spells."; + } + ivar1 = 12583008; + break; + case 28180485: + if (((boolean)bitconfig_6463)) { + svar0 = "Hide combat spells."; + } else { + svar0 = "Show combat spells."; + } + ivar1 = 28180545; + break; + case 28180489: + if (((boolean)bitconfig_6464)) { + svar0 = "Hide miscellaneous spells."; + } else { + svar0 = "Show miscellaneous spells."; + } + ivar1 = 28180545; + break; + case 28180487: + if (((boolean)bitconfig_6465)) { + svar0 = "Hide teleport spells."; + } else { + svar0 = "Show teleport spells."; + } + ivar1 = 28180545; + break; + case 12648453: + if (((boolean)bitconfig_6466)) { + svar0 = "Hide combat spells."; + } else { + svar0 = "Show combat spells."; + } + ivar1 = 12648501; + break; + case 12648455: + if (((boolean)bitconfig_6467)) { + svar0 = "Hide teleport spells."; + } else { + svar0 = "Show teleport spells."; + } + ivar1 = 12648501; + break; + case 62259207: + if (((boolean)bitconfig_7348)) { + svar0 = "Hide combat spells."; + } else { + svar0 = "Show combat spells."; + } + ivar1 = 62259272; + break; + case 62259209: + if (((boolean)bitconfig_7351)) { + svar0 = "Hide teleport spells."; + } else { + svar0 = "Show teleport spells."; + } + ivar1 = 62259272; + break; + case 62259211: + if (((boolean)bitconfig_7350)) { + svar0 = "Hide miscellaneous spells."; + } else { + svar0 = "Show miscellaneous spells."; + } + ivar1 = 62259272; + break; + case 62259213: + if (((boolean)bitconfig_7349)) { + svar0 = "Hide skill spells."; + } else { + svar0 = "Show skill spells."; + } + ivar1 = 62259272; + break; + default: + return; + } + script_39(arg0, ivar1, 25, getWidgetActualWidth(new WidgetPointer(getWidgetParentId(new WidgetPointer(ivar1)))), svar0); + return; +} diff --git a/dumps/scripts/1118.cs2 b/dumps/scripts/1118.cs2 new file mode 100644 index 0000000..8cf5e34 --- /dev/null +++ b/dumps/scripts/1118.cs2 @@ -0,0 +1,121 @@ +void script_1118(int arg0) { + switch (arg0) { + case 12582919: + if (((boolean)bitconfig_6459)) { + setWidgetSprite(1703, new WidgetPointer(arg0)); + } else if (((boolean)globalint_988)) { + setWidgetSprite(1702, new WidgetPointer(arg0)); + } else { + setWidgetSprite(1701, new WidgetPointer(arg0)); + } + break; + case 12582921: + if (((boolean)bitconfig_6462)) { + setWidgetSprite(1703, new WidgetPointer(arg0)); + } else if (((boolean)globalint_989)) { + setWidgetSprite(1702, new WidgetPointer(arg0)); + } else { + setWidgetSprite(1701, new WidgetPointer(arg0)); + } + break; + case 12582923: + if (((boolean)bitconfig_6461)) { + setWidgetSprite(1703, new WidgetPointer(arg0)); + } else if (((boolean)globalint_990)) { + setWidgetSprite(1702, new WidgetPointer(arg0)); + } else { + setWidgetSprite(1701, new WidgetPointer(arg0)); + } + break; + case 12582925: + if (((boolean)bitconfig_6460)) { + setWidgetSprite(1703, new WidgetPointer(arg0)); + } else if (((boolean)globalint_991)) { + setWidgetSprite(1702, new WidgetPointer(arg0)); + } else { + setWidgetSprite(1701, new WidgetPointer(arg0)); + } + break; + case 28180485: + if (((boolean)bitconfig_6463)) { + setWidgetSprite(1703, new WidgetPointer(arg0)); + } else if (((boolean)globalint_988)) { + setWidgetSprite(1702, new WidgetPointer(arg0)); + } else { + setWidgetSprite(1701, new WidgetPointer(arg0)); + } + break; + case 28180489: + if (((boolean)bitconfig_6464)) { + setWidgetSprite(1703, new WidgetPointer(arg0)); + } else if (((boolean)globalint_990)) { + setWidgetSprite(1702, new WidgetPointer(arg0)); + } else { + setWidgetSprite(1701, new WidgetPointer(arg0)); + } + break; + case 28180487: + if (((boolean)bitconfig_6465)) { + setWidgetSprite(1703, new WidgetPointer(arg0)); + } else if (((boolean)globalint_989)) { + setWidgetSprite(1702, new WidgetPointer(arg0)); + } else { + setWidgetSprite(1701, new WidgetPointer(arg0)); + } + break; + case 12648453: + if (((boolean)bitconfig_6466)) { + setWidgetSprite(1703, new WidgetPointer(arg0)); + } else if (((boolean)globalint_988)) { + setWidgetSprite(1702, new WidgetPointer(arg0)); + } else { + setWidgetSprite(1701, new WidgetPointer(arg0)); + } + break; + case 12648455: + if (((boolean)bitconfig_6467)) { + setWidgetSprite(1703, new WidgetPointer(arg0)); + } else if (((boolean)globalint_989)) { + setWidgetSprite(1702, new WidgetPointer(arg0)); + } else { + setWidgetSprite(1701, new WidgetPointer(arg0)); + } + break; + case 62259207: + if (((boolean)bitconfig_7348)) { + setWidgetSprite(1703, new WidgetPointer(arg0)); + } else if (((boolean)globalint_988)) { + setWidgetSprite(1702, new WidgetPointer(arg0)); + } else { + setWidgetSprite(1701, new WidgetPointer(arg0)); + } + break; + case 62259209: + if (((boolean)bitconfig_7351)) { + setWidgetSprite(1703, new WidgetPointer(arg0)); + } else if (((boolean)globalint_989)) { + setWidgetSprite(1702, new WidgetPointer(arg0)); + } else { + setWidgetSprite(1701, new WidgetPointer(arg0)); + } + break; + case 62259211: + if (((boolean)bitconfig_7350)) { + setWidgetSprite(1703, new WidgetPointer(arg0)); + } else if (((boolean)globalint_990)) { + setWidgetSprite(1702, new WidgetPointer(arg0)); + } else { + setWidgetSprite(1701, new WidgetPointer(arg0)); + } + break; + case 62259213: + if (((boolean)bitconfig_7349)) { + setWidgetSprite(1703, new WidgetPointer(arg0)); + } else if (((boolean)globalint_991)) { + setWidgetSprite(1702, new WidgetPointer(arg0)); + } else { + setWidgetSprite(1701, new WidgetPointer(arg0)); + } + } + return; +} diff --git a/dumps/scripts/1119.cs2 b/dumps/scripts/1119.cs2 new file mode 100644 index 0000000..202c423 --- /dev/null +++ b/dumps/scripts/1119.cs2 @@ -0,0 +1,92 @@ +int script_1119() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + ivar0 = cs2method_3408(105, 74, 2162, bitconfig_357); + ivar1 = 0; + globalarray_0 = new int[4]; + switch (bitconfig_357) { + case 0: + ivar1 = bitconfig_5822; + globalarray_0[0] = bitconfig_6459; + globalarray_0[1] = bitconfig_6460; + globalarray_0[2] = bitconfig_6461; + globalarray_0[3] = bitconfig_6462; + break; + case 1: + ivar1 = bitconfig_5823; + globalarray_0[0] = bitconfig_6466; + globalarray_0[1] = 0; + globalarray_0[2] = 0; + globalarray_0[3] = bitconfig_6467; + break; + case 2: + ivar1 = bitconfig_5824; + globalarray_0[0] = bitconfig_6463; + globalarray_0[1] = 0; + globalarray_0[2] = bitconfig_6464; + globalarray_0[3] = bitconfig_6465; + break; + case 3: + ivar1 = bitconfig_7347; + globalarray_0[0] = bitconfig_7348; + globalarray_0[1] = bitconfig_7349; + globalarray_0[2] = bitconfig_7350; + globalarray_0[3] = bitconfig_7351; + } + ivar2 = cs2method_3408(105, 103, getOtherCommonData(ivar0, 662), ivar1); + ivar3 = getOtherCommonData(ivar0, 654); + ivar4 = getOtherCommonData(ivar0, 655); + ivar5 = getCommonDefinitionSize(ivar2); + ivar6 = 0; + ivar7 = 0; + ivar8 = -1; + ivar9 = 0; + ivar10 = 0; + ivar11 = 0; + ivar12 = -1; + ivar13 = -1; + while (ivar7 < ivar5) { + ivar8 = cs2method_3408(105, 103, ivar2, ivar7); + if (ivar8 != -1) { + ivar6 = getCommonDefinitionSize(ivar8); + ivar9 = 0; + ivar11 = 0; + while (ivar9 < ivar6) { + ivar12 = ((int)cs2method_3408(105, 73, ivar8, ivar11)); + if (ivar12 != -1) { + ivar9 = add(ivar9, 1); + ivar13 = cs2method_3408(73, 105, 727, ivar12); + if ((ivar13 == -1) || (((boolean)globalarray_0[ivar13]) && (isMember() || ((boolean)cs2method_3408(73, 105, 743, ivar12))))) { + ivar10 = add(ivar10, 1); + ivar4 = add(ivar4, add(getOtherCommonData(ivar0, 657), getOtherCommonData(ivar0, 658))); + if (((boolean)mod(ivar10, getOtherCommonData(ivar0, 660)))) { + ivar3 = add(ivar3, add(getOtherCommonData(ivar0, 656), getOtherCommonData(ivar0, 659))); + ivar4 = getOtherCommonData(ivar0, 655); + } + } + } + ivar11 = add(ivar11, 1); + if (ivar11 > 997) { + return 1; + } + } + } + ivar7 = add(ivar7, 1); + } + if (add(ivar3, getOtherCommonData(ivar0, 656)) >= 229) { + return 1; + } + return 0; +} diff --git a/dumps/scripts/112.cs2 b/dumps/scripts/112.cs2 new file mode 100644 index 0000000..c07983c --- /dev/null +++ b/dumps/scripts/112.cs2 @@ -0,0 +1,204 @@ +void script_112(int arg0,int arg1) { + int stack_dump0; + int stack_dump1; + int stack_dump2; + int stack_dump3; + string stack_dump4; + cs2func_script_802_struct(1,1,0) structdump_5; + cs2func_script_802_struct(1,1,0) structdump_6; + cs2func_script_802_struct(1,1,0) structdump_7; + cs2func_script_802_struct(1,1,0) structdump_8; + cs2func_script_802_struct(1,1,0) structdump_9; + switch (arg0) { + flow_1: + case 84: + if (globalint_5 == 12) { + script_1806(globalstring_22); + return; + } + IF (strLength(globalstring_22) > 0) + GOTO flow_4 + GOTO flow_51 + flow_4: + if (globalint_5 == 13) { + sendStringInput(globalstring_22); + } else if ((globalint_5 == 4) || (globalint_5 == 5)) { + if (getIgnoreCount() < 0) { + messageType0("Unable to update Ignore List: system busy"); + } else if (globalint_5 == 4) { + cs2method3607(globalstring_22); + } else { + if (globalint_5 == 5) { + if (cs2method3623(script_4591(globalstring_22))) { + cs2method3608(script_4591(globalstring_22)); + } else { + messageType0("That player is not on your ignore list."); + } + } + } + } else if (globalint_5 < 7) { + if (getFriendlistSize() < 0) { + messageType0("Unable to complete action - system busy"); + } else if (globalint_5 == 2) { + cs2method3605(globalstring_22); + } else if (globalint_5 == 3) { + if (isFriend(script_4591(globalstring_22))) { + cs2method3606(script_4591(globalstring_22)); + } else { + messageType0("That player is not on your friends list."); + } + } else { + if (globalint_5 == 6) { + if (cs2method5005() == 2) { + cs2method5001(cs2method5000(), 1, cs2method5016()); + script_178(); + script_84(); + script_89(); + } + cs2method5009(globalstring_23, globalstring_22); + } + } + } else if (globalint_5 == 11) { + script_1478(); + } else if (globalint_5 == 7) { + globalstring_22 = script_2332(globalstring_22, "K", "000"); + globalstring_22 = script_2332(globalstring_22, "k", "000"); + globalstring_22 = script_2332(globalstring_22, "M", "000000"); + globalstring_22 = script_2332(globalstring_22, "m", "000000"); + if (((boolean)getLanguage())) { + globalstring_22 = script_2332(globalstring_22, "T", "000"); + globalstring_22 = script_2332(globalstring_22, "t", "000"); + } + sendIntegerInput(globalstring_22); + } else if (globalint_5 == 8) { + globalstring_201 = replaceLtGt(globalstring_22); + globalint_1026 = 1; + sendNameInput(globalstring_22); + } else if (globalint_5 == 9) { + if (stringMethod4107(lower(globalstring_22), lower(globalstring_33)) != 0) { + sendStringInput(globalstring_22); + } else { + messageType0("Please do not enter your password here!"); + } + } else if (globalint_5 == 10) { + globalstring_202 = replaceLtGt(globalstring_22); + globalint_1027 = 1; + sendUnknownFriendPacketMethod3619(globalstring_22); + } else if (globalint_5 == 15) { + script_1633(globalstring_22); + } else { + if (globalint_5 == 16) { + script_4465(globalstring_22); + } + } + GOTO flow_54 + flow_51: + if (globalint_5 == 14) { + script_3683(); + return; + } + IF (globalint_5 == 7) + GOTO flow_54 + GOTO flow_54 + flow_54: + setWidgetIsHidden(true, new WidgetPointer(752,3)); + setWidgetIsHidden(true, new WidgetPointer(752,7)); + setWidgetIsHidden(false, new WidgetPointer(752,8)); + globalint_5 = 0; + if (getDisplayMode() >= 2) { + script_1364(); + } + return; + case 13: + if (globalint_5 == 12) { + script_1806(globalstring_38); + script_1548(0); + } else { + if (globalint_5 == 14) { + script_3683(); + } + } + return; + case 102: + case 103: + case 98: + case 99: + case 96: + case 97: + if (isHoldingCtrl()) { + return; + } + globalint_1029 = script_1553(arg0, globalint_1029, globalstring_22); + break; + default: + switch (globalint_5) { + case 9: + case 11: + case 6: + stack_dump0 = globalint_1029; + stack_dump1 = 0; + stack_dump2 = arg0; + stack_dump3 = arg1; + stack_dump4 = globalstring_22; + structdump_5 = script_802(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + stack_dump4 = structdump_5.stringpart_0; + globalint_1029 = structdump_5.intpart_0; + globalstring_22 = stack_dump4; + break; + case 7: + stack_dump0 = globalint_1029; + stack_dump1 = 6; + stack_dump2 = arg0; + stack_dump3 = arg1; + stack_dump4 = globalstring_22; + structdump_6 = script_802(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + stack_dump4 = structdump_6.stringpart_0; + globalint_1029 = structdump_6.intpart_0; + globalstring_22 = stack_dump4; + break; + case 13: + stack_dump0 = globalint_1029; + stack_dump1 = 5; + stack_dump2 = arg0; + stack_dump3 = arg1; + stack_dump4 = globalstring_22; + structdump_7 = script_802(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + stack_dump4 = structdump_7.stringpart_0; + globalint_1029 = structdump_7.intpart_0; + globalstring_22 = stack_dump4; + break; + case 14: + stack_dump0 = globalint_1029; + stack_dump1 = 4; + stack_dump2 = arg0; + stack_dump3 = arg1; + stack_dump4 = globalstring_22; + structdump_8 = script_802(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + stack_dump4 = structdump_8.stringpart_0; + globalint_1029 = structdump_8.intpart_0; + globalstring_22 = stack_dump4; + break; + } + stack_dump0 = globalint_1029; + stack_dump1 = 2; + stack_dump2 = arg0; + stack_dump3 = arg1; + stack_dump4 = globalstring_22; + structdump_9 = script_802(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + stack_dump4 = structdump_9.stringpart_0; + globalint_1029 = structdump_9.intpart_0; + globalstring_22 = stack_dump4; + } + setWidgetText(new WidgetPointer(752,5), replaceLtGt(globalstring_22)); + script_1557(); + if (globalint_5 == 11) { + script_1475(); + } else { + if (globalint_5 == 14) { + globalstring_196 = lower(globalstring_22); + globalint_89 = 1; + script_3680(); + } + } + return; +} diff --git a/dumps/scripts/1120.cs2 b/dumps/scripts/1120.cs2 new file mode 100644 index 0000000..9f0a693 --- /dev/null +++ b/dumps/scripts/1120.cs2 @@ -0,0 +1,4 @@ +void script_1120() { + script_1121(); + return; +} diff --git a/dumps/scripts/1121.cs2 b/dumps/scripts/1121.cs2 new file mode 100644 index 0000000..b8db800 --- /dev/null +++ b/dumps/scripts/1121.cs2 @@ -0,0 +1,49 @@ +void script_1121() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + ivar0 = ((int)cs2method_3408(105, 73, 729, bitconfig_276)); + ivar1 = 0; + ivar2 = 0; + ivar3 = -1; + ivar4 = -1; + switch (bitconfig_357) { + case 0: + ivar3 = 12583005; + ivar4 = 12583004; + break; + case 1: + ivar3 = 12648498; + ivar4 = 12648497; + break; + case 3: + ivar3 = 62259269; + ivar4 = 62259268; + break; + default: + return; + } + if (((boolean)bitconfig_276)) { + if (bitconfig_6521 == 3) { + script_948(); + } else { + if (bitconfig_6521 == 28) { + script_1331(); + } + } + } + if ((ivar0 != -1) && ((boolean)bitconfig_275)) { + ivar1 = subtract(getWidgetActualX(new WidgetPointer(ivar0)), 2); + ivar2 = subtract(getWidgetActualY(new WidgetPointer(ivar0)), 2); + setWidgetPosition(ivar1, ivar2, 0, 0, new WidgetPointer(ivar3)); + setWidgetPosition(ivar1, ivar2, 0, 0, new WidgetPointer(ivar4)); + setWidgetIsHidden(false, new WidgetPointer(ivar3)); + setWidgetIsHidden(false, new WidgetPointer(ivar4)); + return; + } + setWidgetIsHidden(true, new WidgetPointer(ivar3)); + setWidgetIsHidden(true, new WidgetPointer(ivar4)); + return; +} diff --git a/dumps/scripts/1122.cs2 b/dumps/scripts/1122.cs2 new file mode 100644 index 0000000..d5f7015 --- /dev/null +++ b/dumps/scripts/1122.cs2 @@ -0,0 +1,4 @@ +void script_1122() { + script_1952(); + return; +} diff --git a/dumps/scripts/1123.cs2 b/dumps/scripts/1123.cs2 new file mode 100644 index 0000000..9044046 --- /dev/null +++ b/dumps/scripts/1123.cs2 @@ -0,0 +1,19 @@ +void script_1123(int arg0) { + switch (bitconfig_804) { + case 1: + setItemOnWidgetMethod2200(6090, 300, new WidgetPointer(arg0)); + break; + case 2: + setItemOnWidgetMethod2200(6092, 300, new WidgetPointer(arg0)); + break; + case 3: + setItemOnWidgetMethod2200(6089, 300, new WidgetPointer(arg0)); + break; + case 4: + setItemOnWidgetMethod2200(6091, 300, new WidgetPointer(arg0)); + break; + default: + setItemOnWidgetMethod2200(-1, 300, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/1124.cs2 b/dumps/scripts/1124.cs2 new file mode 100644 index 0000000..5d85109 --- /dev/null +++ b/dumps/scripts/1124.cs2 @@ -0,0 +1,24 @@ +void script_1124(int arg0) { + int ivar1; + ivar1 = getWidgetShadeColor(new WidgetPointer(arg0)); + if (((boolean)globalint_992)) { + ivar1 = add(ivar1, 1); + if (ivar1 >= 255) { + globalint_992 = 0; + } + } else { + ivar1 = subtract(ivar1, 1); + if (ivar1 <= 0) { + globalint_992 = 1; + } + } + if (ivar1 > 255) { + ivar1 = 255; + } else { + if (ivar1 < 0) { + ivar1 = 0; + } + } + cs2method2103(ivar1, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1125.cs2 b/dumps/scripts/1125.cs2 new file mode 100644 index 0000000..7aacff2 --- /dev/null +++ b/dumps/scripts/1125.cs2 @@ -0,0 +1,7 @@ +void script_1125(int arg0) { + globalint_993 = 1; + if (((boolean)bitconfig_2668)) { + setWidgetSprite(1702, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/1126.cs2 b/dumps/scripts/1126.cs2 new file mode 100644 index 0000000..31a6a6e --- /dev/null +++ b/dumps/scripts/1126.cs2 @@ -0,0 +1,29 @@ +void script_1126(int arg0) { + globalint_993 = 0; + switch (arg0) { + case 12582914: + script_41(12583008); + if (((boolean)bitconfig_2668)) { + setWidgetSprite(1701, new WidgetPointer(arg0)); + } + break; + case 12648466: + script_41(12648501); + if (((boolean)bitconfig_2668)) { + setWidgetSprite(1701, new WidgetPointer(arg0)); + } + break; + case 28180500: + script_41(28180545); + if (((boolean)bitconfig_2668)) { + setWidgetSprite(1701, new WidgetPointer(arg0)); + } + break; + case 62259202: + script_41(62259272); + if (((boolean)bitconfig_2668)) { + setWidgetSprite(1701, new WidgetPointer(arg0)); + } + } + return; +} diff --git a/dumps/scripts/1127.cs2 b/dumps/scripts/1127.cs2 new file mode 100644 index 0000000..eff5c18 --- /dev/null +++ b/dumps/scripts/1127.cs2 @@ -0,0 +1,25 @@ +void script_1127(int arg0) { + int ivar1; + string svar0; + ivar1 = -1; + svar0 = ""; + switch (arg0) { + case 12582914: + svar0 = "Toggle defensive casting."; + ivar1 = 12583008; + break; + case 12648466: + svar0 = "Toggle defensive casting."; + ivar1 = 12648501; + break; + case 28180500: + svar0 = "Toggle defensive casting."; + ivar1 = 28180545; + break; + case 62259202: + svar0 = "Toggle defensive casting."; + ivar1 = 62259272; + } + script_39(arg0, ivar1, 25, getWidgetActualWidth(new WidgetPointer(getWidgetParentId(new WidgetPointer(ivar1)))), svar0); + return; +} diff --git a/dumps/scripts/1128.cs2 b/dumps/scripts/1128.cs2 new file mode 100644 index 0000000..6be3904 --- /dev/null +++ b/dumps/scripts/1128.cs2 @@ -0,0 +1,10 @@ +void script_1128(int arg0) { + if (((boolean)bitconfig_2668)) { + setWidgetSprite(1703, new WidgetPointer(arg0)); + } else if (((boolean)globalint_993)) { + setWidgetSprite(1702, new WidgetPointer(arg0)); + } else { + setWidgetSprite(1701, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/1129.cs2 b/dumps/scripts/1129.cs2 new file mode 100644 index 0000000..9b1b3b4 --- /dev/null +++ b/dumps/scripts/1129.cs2 @@ -0,0 +1,11 @@ +void script_1129() { + cs2method5426(36, 41); + cs2method5427(46, -1); + if (((boolean)globalint_987) || ((boolean)globalint_987)) { + cs2method6028(((boolean)globalint_987)); + } else { + globalint_987 = 1; + cs2method6028(((boolean)globalint_987)); + } + return; +} diff --git a/dumps/scripts/113.cs2 b/dumps/scripts/113.cs2 new file mode 100644 index 0000000..cdd19bb --- /dev/null +++ b/dumps/scripts/113.cs2 @@ -0,0 +1,22 @@ +void script_113(int arg0) { + int ivar1; + int ivar2; + ivar1 = 0; + ivar2 = 0; + if (((boolean)rndExcl(2))) { + ivar1 = add(5, rndExcl(12)); + } else { + ivar1 = subtract(-5, rndExcl(12)); + } + if (((boolean)rndExcl(2))) { + ivar2 = add(5, rndExcl(12)); + } else { + ivar2 = subtract(-5, rndExcl(12)); + } + if (((boolean)rndExcl(2))) { + setScriptCallOnGameloop(66, ivar1, ivar2, 0, new WidgetPointer(arg0), "iiiI", new WidgetPointer(arg0)); + } else { + setScriptCallOnGameloop(66, ivar1, 0, ivar2, new WidgetPointer(arg0), "iiiI", new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/1130.cs2 b/dumps/scripts/1130.cs2 new file mode 100644 index 0000000..53decda --- /dev/null +++ b/dumps/scripts/1130.cs2 @@ -0,0 +1,4 @@ +void script_1130(int arg0) { + script_1131(arg0); + return; +} diff --git a/dumps/scripts/1131.cs2 b/dumps/scripts/1131.cs2 new file mode 100644 index 0000000..4a6857c --- /dev/null +++ b/dumps/scripts/1131.cs2 @@ -0,0 +1,8 @@ +void script_1131(int arg0) { + if (globalint_1000 > getMyCombat()) { + setWidgetText(new WidgetPointer(arg0), "Combat Lvl: " + intToStr(getMyCombat()) + "+" + intToStr(subtract(globalint_1000, getMyCombat()))); + } else { + setWidgetText(new WidgetPointer(arg0), "Combat Lvl: " + intToStr(getMyCombat())); + } + return; +} diff --git a/dumps/scripts/1132.cs2 b/dumps/scripts/1132.cs2 new file mode 100644 index 0000000..843f7b6 --- /dev/null +++ b/dumps/scripts/1132.cs2 @@ -0,0 +1,4 @@ +void script_1132(int arg0) { + script_1133(arg0); + return; +} diff --git a/dumps/scripts/1133.cs2 b/dumps/scripts/1133.cs2 new file mode 100644 index 0000000..43f4742 --- /dev/null +++ b/dumps/scripts/1133.cs2 @@ -0,0 +1,10 @@ +void script_1133(int arg0) { + int ivar1; + ivar1 = getItemIdInSlot(94, 3); + if ((ivar1 != -1) && (isMembersItem(ivar1) || isMember())) { + setWidgetText(new WidgetPointer(arg0), getItemName(ivar1)); + } else { + setWidgetText(new WidgetPointer(arg0), "Unarmed"); + } + return; +} diff --git a/dumps/scripts/1134.cs2 b/dumps/scripts/1134.cs2 new file mode 100644 index 0000000..b319707 --- /dev/null +++ b/dumps/scripts/1134.cs2 @@ -0,0 +1,8 @@ +void script_1134(int arg0,int arg1) { + if (standart_config_43 == arg1) { + setWidgetSprite(654, new WidgetPointer(arg0)); + } else { + setWidgetSprite(653, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/1135.cs2 b/dumps/scripts/1135.cs2 new file mode 100644 index 0000000..816e322 --- /dev/null +++ b/dumps/scripts/1135.cs2 @@ -0,0 +1,94 @@ +void script_1135(int arg0) { + int ivar1; + flow_0: + ivar1 = script_284(getMyPositionHash()); + SWITCH (globalint_1007) { + case 1: + GOTO flow_1 + case 2: + GOTO flow_2 + case 3: + GOTO flow_3 + case 4: + GOTO flow_4 + case 5: + GOTO flow_8 + case 6: + GOTO flow_12 + case 7: + GOTO flow_16 + case 8: + GOTO flow_20 + } + deleteAllExtraChilds(new WidgetPointer(arg0)); + cs2method5512(); + GOTO flow_21 + flow_1: + script_2766(16777215, 50, arg0); + playSoundEffect(3641, 1, 0); + GOTO flow_21 + flow_2: + cs2method5405(0, 2); + cs2method5405(1, 2); + cs2method5406(0, 0, script_1145(25, 25, ivar1), 750, script_1145(25, 25, ivar1), 750, 0); + cs2method5406(0, 1, script_1145(25, 26, ivar1), 750, script_1145(25, 26, ivar1), 750, 0); + cs2method5406(1, 0, script_1145(25, 29, ivar1), 600, script_1145(25, 29, ivar1), 600, 0); + cs2method5406(1, 1, script_1145(25, 30, ivar1), 600, script_1145(25, 30, ivar1), 600, 0); + cameraMethod5502(0, 0, 100, 0, 1, 0); + script_2768(45, arg0); + playSoundEffect(3641, 1, 0); + GOTO flow_21 + flow_3: + cs2method5405(0, 7); + cs2method5405(1, 7); + cs2method5406(0, 0, script_1145(25, 26, ivar1), 750, script_1145(25, 26, ivar1), 1200, 0); + cs2method5406(0, 1, script_1145(16, 9, ivar1), 2175, script_1145(18, 11, ivar1), 2175, 0); + cs2method5406(0, 2, script_1145(31, 9, ivar1), 2275, script_1145(31, 9, ivar1), 2450, 0); + cs2method5406(0, 3, script_1145(39, 20, ivar1), 1950, script_1145(39, 20, ivar1), 1950, 0); + cs2method5406(0, 4, script_1145(40, 34, ivar1), 1550, script_1145(40, 34, ivar1), 1550, 0); + cs2method5406(0, 5, script_1145(31, 40, ivar1), 1125, script_1145(31, 40, ivar1), 1125, 0); + cs2method5406(0, 6, script_1145(24, 38, ivar1), 900, script_1145(24, 38, ivar1), 900, 0); + cs2method5406(1, 0, script_1145(25, 30, ivar1), 600, script_1145(25, 30, ivar1), 600, 0); + cs2method5406(1, 1, script_1145(25, 23, ivar1), 1150, script_1145(25, 23, ivar1), 1150, 0); + cs2method5406(1, 2, script_1145(25, 23, ivar1), 1150, script_1145(25, 23, ivar1), 1150, 0); + cs2method5406(1, 3, script_1145(25, 23, ivar1), 950, script_1145(25, 23, ivar1), 950, 0); + cs2method5406(1, 4, script_1145(25, 23, ivar1), 950, script_1145(25, 23, ivar1), 950, 0); + cs2method5406(1, 5, script_1145(25, 23, ivar1), 850, script_1145(25, 23, ivar1), 850, 0); + cs2method5406(1, 6, script_1145(26, 23, ivar1), 725, script_1145(26, 23, ivar1), 725, 0); + cameraMethod5502(0, 0, 800, 400, 1, 0); + GOTO flow_21 + flow_4: + if (cs2method5407(0) == 7) { + cameraMethod5502(0, 1, 400, 400, 1, 1); + } else { + cs2method5512(); + } + GOTO flow_21 + flow_8: + if (cs2method5407(0) == 7) { + cameraMethod5502(0, 2, 400, 400, 1, 2); + } else { + cs2method5512(); + } + GOTO flow_21 + flow_12: + if (cs2method5407(0) == 7) { + cameraMethod5502(0, 3, 400, 400, 1, 3); + } else { + cs2method5512(); + } + GOTO flow_21 + flow_16: + if (cs2method5407(0) == 7) { + cameraMethod5502(0, 4, 400, 600, 1, 4); + setScriptCallOnMinimapRelatedSetting3(1144, new WidgetPointer(arg0), "I", new WidgetPointer(arg0)); + } else { + cs2method5512(); + } + GOTO flow_21 + flow_20: + script_2768(50, arg0); + playSoundEffect(3641, 1, 0); + flow_21: + return; +} diff --git a/dumps/scripts/1136.cs2 b/dumps/scripts/1136.cs2 new file mode 100644 index 0000000..4f4e1c6 --- /dev/null +++ b/dumps/scripts/1136.cs2 @@ -0,0 +1,9 @@ +void script_1136(int arg0) { + if (isMember() && (getItemHashmapData(getItemIdInSlot(94, 3), 687) != 0)) { + setWidgetIsHidden(false, new WidgetPointer(arg0)); + return; + } + setWidgetIsHidden(true, new WidgetPointer(arg0)); + script_41(57933843); + return; +} diff --git a/dumps/scripts/1137.cs2 b/dumps/scripts/1137.cs2 new file mode 100644 index 0000000..59f0519 --- /dev/null +++ b/dumps/scripts/1137.cs2 @@ -0,0 +1,5 @@ +void script_1137(int arg0,int arg1) { + setWidgetSize(multiplyDivide(standart_config_300, 1000, 143), 13, 0, 0, new WidgetPointer(arg0)); + setWidgetText(new WidgetPointer(arg1), "Special Attack (" + intToStr(divide(standart_config_300, 10)) + "%)"); + return; +} diff --git a/dumps/scripts/1138.cs2 b/dumps/scripts/1138.cs2 new file mode 100644 index 0000000..bedc788 --- /dev/null +++ b/dumps/scripts/1138.cs2 @@ -0,0 +1,8 @@ +void script_1138(int arg0) { + if (standart_config_301 > 0) { + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(arg0)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/1139.cs2 b/dumps/scripts/1139.cs2 new file mode 100644 index 0000000..b21eeaa --- /dev/null +++ b/dumps/scripts/1139.cs2 @@ -0,0 +1,8 @@ +void script_1139(int arg0) { + if (((boolean)standart_config_172)) { + setWidgetText(new WidgetPointer(arg0), "Auto Retaliate " + "
" + "(Off)"); + } else { + setWidgetText(new WidgetPointer(arg0), "Auto Retaliate " + "
" + "(On)"); + } + return; +} diff --git a/dumps/scripts/114.cs2 b/dumps/scripts/114.cs2 new file mode 100644 index 0000000..d22fafe --- /dev/null +++ b/dumps/scripts/114.cs2 @@ -0,0 +1,13 @@ +void script_114() { + setScriptCallOnGlobalConfigChange(1302, 168, 747, 2, "Y", new WidgetPointer(548,195)); + setScriptCallOnGlobalConfigChange(1302, 168, 747, 2, "Y", new WidgetPointer(746,79)); + if (getDisplayMode() >= 2) { + setScriptCallOnConfigChange(117, 1021, 1, "Y", new WidgetPointer(746,22)); + script_1309(1); + } else { + setScriptCallOnConfigChange(117, 1021, 1, "Y", new WidgetPointer(548,128)); + script_2756(); + script_1312(1); + } + return; +} diff --git a/dumps/scripts/1140.cs2 b/dumps/scripts/1140.cs2 new file mode 100644 index 0000000..9e0f69a --- /dev/null +++ b/dumps/scripts/1140.cs2 @@ -0,0 +1,8 @@ +void script_1140(int arg0) { + if (((boolean)standart_config_172)) { + setWidgetSprite(1409, new WidgetPointer(arg0)); + } else { + setWidgetSprite(656, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/1141.cs2 b/dumps/scripts/1141.cs2 new file mode 100644 index 0000000..7bf2552 --- /dev/null +++ b/dumps/scripts/1141.cs2 @@ -0,0 +1,10 @@ +void script_1141() { + if (((boolean)script_1431())) { + if (getDisplayMode() < 2) { + setScriptCallOnGameloop(1175, "", new WidgetPointer(548,10)); + } else { + setScriptCallOnGameloop(1175, "", new WidgetPointer(746,17)); + } + } + return; +} diff --git a/dumps/scripts/1142.cs2 b/dumps/scripts/1142.cs2 new file mode 100644 index 0000000..7f8919e --- /dev/null +++ b/dumps/scripts/1142.cs2 @@ -0,0 +1,94 @@ +void script_1142() { + int ivar0; + int ivar1; + ivar0 = getItemIdInSlot(94, 3); + if ((ivar0 == -1) || (isMembersItem(ivar0) && isMember())) { + script_1143(247, 248, 249, -1, "Punch", "Accurate" + "
" + "Crush" + "
" + "Attack XP", "Kick", "Aggressive" + "
" + "Crush" + "
" + "Strength XP", "Block", "Defensive" + "
" + "Crush" + "
" + "Defence XP", "", ""); + return; + } + ivar1 = getItemHashmapData(ivar0, 686); + switch (ivar1) { + case 1: + script_1143(266, 267, 252, -1, "Bash", "Accurate" + "
" + "Crush" + "
" + "Attack XP", "Pound", "Aggressive" + "
" + "Crush" + "
" + "Strength XP", "Focus", "Defensive" + "
" + "Crush" + "
" + "Defence XP", "", ""); + break; + case 23: + script_1143(266, 267, 252, -1, "Slash", "Accurate" + "
" + "Slash" + "
" + "Attack XP", "Crush", "Aggressive" + "
" + "Crush" + "
" + "Strength XP", "Slash", "Defensive" + "
" + "Slash" + "
" + "Defence XP", "", ""); + break; + case 2: + script_1143(234, 235, 236, 233, "Chop", "Accurate" + "
" + "Slash" + "
" + "Attack XP", "Hack", "Aggressive" + "
" + "Slash" + "
" + "Strength XP", "Smash", "Aggressive" + "
" + "Crush" + "
" + "Strength XP", "Block", "Defensive" + "
" + "Slash" + "
" + "Defence XP"); + break; + case 3: + script_1143(266, 267, 252, -1, "Bash", "Accurate" + "
" + "Crush" + "
" + "Attack XP", "Pound", "Aggressive" + "
" + "Crush" + "
" + "Strength XP", "Block", "Defensive" + "
" + "Crush" + "
" + "Defence XP", "", ""); + break; + case 4: + script_1143(274, 276, 275, 273, "Spike", "Accurate" + "
" + "Stab" + "
" + "Attack XP", "Impale", "Aggressive" + "
" + "Stab" + "
" + "Strength XP", "Smash", "Aggressive" + "
" + "Crush" + "
" + "Strength XP", "Block", "Defensive" + "
" + "Stab" + "
" + "Defence XP"); + break; + case 5: + script_1143(240, 239, 238, 237, "Stab", "Accurate" + "
" + "Stab" + "
" + "Attack XP", "Lunge", "Aggressive" + "
" + "Stab" + "
" + "Strength XP", "Slash", "Aggressive" + "
" + "Slash" + "
" + "Strength XP", "Block", "Defensive" + "
" + "Stab" + "
" + "Defence XP"); + break; + case 6: + script_1143(239, 238, 240, 237, "Chop", "Accurate" + "
" + "Slash" + "
" + "Attack XP", "Slash", "Aggressive" + "
" + "Slash" + "
" + "Strength XP", "Lunge", "Controlled" + "
" + "Stab" + "
" + "Shared XP", "Block", "Defensive" + "
" + "Slash" + "
" + "Defence XP"); + break; + case 7: + script_1143(239, 238, 238, 237, "Chop", "Accurate" + "
" + "Slash" + "
" + "Attack XP", "Slash", "Aggressive" + "
" + "Slash" + "
" + "Strength XP", "Smash", "Aggressive" + "
" + "Crush" + "
" + "Strength XP", "Block", "Defensive" + "
" + "Slash" + "
" + "Defence XP"); + break; + case 8: + script_1143(246, 244, 245, 243, "Pound", "Accurate" + "
" + "Crush" + "
" + "Attack XP", "Pummel", "Aggressive" + "
" + "Crush" + "
" + "Strength XP", "Spike", "Controlled" + "
" + "Stab" + "
" + "Shared XP", "Block", "Defensive" + "
" + "Crush" + "
" + "Defence XP"); + break; + case 9: + script_1143(279, 278, 277, 280, "Chop", "Accurate" + "
" + "Slash" + "
" + "Attack XP", "Slash", "Aggressive" + "
" + "Slash" + "
" + "Strength XP", "Lunge", "Controlled" + "
" + "Stab" + "
" + "Shared XP", "Block", "Defensive" + "
" + "Slash" + "
" + "Defence XP"); + break; + case 10: + script_1143(255, 256, 253, -1, "Pound", "Accurate" + "
" + "Crush" + "
" + "Attack XP", "Pummel", "Aggressive" + "
" + "Crush" + "
" + "Strength XP", "Block", "Defensive" + "
" + "Crush" + "
" + "Defence XP", "", ""); + break; + case 11: + script_1143(286, 287, 286, -1, "Flick", "Accurate" + "
" + "Slash" + "
" + "Attack XP", "Lash", "Controlled" + "
" + "Slash" + "
" + "Shared XP", "Deflect", "Defensive" + "
" + "Slash" + "
" + "Defence XP", "", ""); + break; + case 12: + script_1143(255, 256, 253, -1, "Pound", "Accurate" + "
" + "Crush" + "
" + "Attack XP", "Pummel", "Aggressive" + "
" + "Crush" + "
" + "Strength XP", "Block", "Defensive" + "
" + "Crush" + "
" + "Defence XP", "", ""); + break; + case 13: + script_1143(263, 264, 265, -1, "Accurate", "Accurate" + "
" + "Ranged XP", "Rapid", "Rapid" + "
" + "Ranged XP", "Long range", "Long range" + "
" + "Ranged XP" + "
" + "Defence XP", "", ""); + break; + case 14: + script_1143(241, 251, 242, 250, "Lunge", "Controlled" + "
" + "Stab" + "
" + "Shared XP", "Swipe", "Controlled" + "
" + "Slash" + "
" + "Shared XP", "Pound", "Controlled" + "
" + "Crush" + "
" + "Shared XP", "Block", "Defensive" + "
" + "Stab" + "
" + "Defence XP"); + break; + case 15: + script_1143(284, 285, 283, -1, "Jab", "Controlled" + "
" + "Stab" + "
" + "Shared XP", "Swipe", "Aggressive" + "
" + "Slash" + "
" + "Strength XP", "Fend", "Defensive" + "
" + "Stab" + "
" + "Defence XP", "", ""); + break; + case 16: + script_1143(268, 269, 270, -1, "Accurate", "Accurate" + "
" + "Ranged XP", "Rapid", "Rapid" + "
" + "Ranged XP", "Long range", "Long range" + "
" + "Ranged XP" + "
" + "Defence XP", "", ""); + break; + case 17: + script_1143(258, 259, 260, -1, "Accurate", "Accurate" + "
" + "Ranged XP", "Rapid", "Rapid" + "
" + "Ranged XP", "Long range", "Long range" + "
" + "Ranged XP" + "
" + "Defence XP", "", ""); + break; + case 18: + script_1143(263, 264, 265, -1, "Accurate", "Accurate" + "
" + "Ranged XP", "Rapid", "Rapid" + "
" + "Ranged XP", "Long range", "Long range" + "
" + "Ranged XP" + "
" + "Defence XP", "", ""); + break; + case 19: + script_1143(288, 282, 281, -1, "Short fuse", "Short fuse" + "
" + "Ranged XP", "Medium fuse", "Medium fuse" + "
" + "Ranged XP", "Long fuse", "Long fuse" + "
" + "Ranged XP" + "
" + "Defence XP", "", ""); + break; + case 20: + script_1143(128, 248, -1, -1, "Aim and fire", "Aim and fire", "Kick", "Aggressive" + "
" + "Crush" + "
" + "Strength XP", "", "", "", ""); + break; + case 21: + script_1143(289, 290, 291, -1, "Scorch", "Aggressive" + "
" + "Slash" + "
" + "Strength XP", "Flare", "Accurate" + "
" + "Ranged" + "
" + "Ranged XP", "Blaze", "Defensive" + "
" + "Magic" + "
" + "Magic XP", "", ""); + break; + case 22: + script_1143(272, 262, 271, 261, "Reap", "Accurate" + "
" + "Slash" + "
" + "Attack XP", "Chop", "Aggressive" + "
" + "Stab" + "
" + "Strength XP", "Jab", "Aggressive" + "
" + "Crush" + "
" + "Strength XP", "Block", "Defensive" + "
" + "Slash" + "
" + "Defence XP"); + break; + case 24: + script_1143(263, 264, 265, -1, "Sling", "Accurate" + "
" + "Ranged XP", "Chuck", "Rapid" + "
" + "Ranged XP", "Lob", "Long range" + "
" + "Ranged XP" + "
" + "Defence XP", "", ""); + break; + case 25: + case 26: + script_1143(266, 267, 252, -1, "Jab", "Accurate" + "
" + "Stab" + "
" + "Attack XP", "Swipe", "Aggressive" + "
" + "Slash" + "
" + "Strength XP", "Fend", "Defensive" + "
" + "Crush" + "
" + "Defence XP", "", ""); + break; + case 27: + script_1143(234, 235, 236, -1, "Hack!", "Controlled" + "
" + "Slash" + "
" + "Shared XP", "Gouge!", "Controlled" + "
" + "Stab" + "
" + "Shared XP", "Smash!", "Controlled" + "
" + "Crush" + "
" + "Shared XP", "", ""); + break; + default: + script_1143(247, 248, 249, -1, "Punch", "Accurate" + "
" + "Crush" + "
" + "Attack XP", "Kick", "Aggressive" + "
" + "Crush" + "
" + "Strength XP", "Block", "Defensive" + "
" + "Crush" + "
" + "Defence XP", "", ""); + } + return; +} diff --git a/dumps/scripts/1143.cs2 b/dumps/scripts/1143.cs2 new file mode 100644 index 0000000..ec805e1 --- /dev/null +++ b/dumps/scripts/1143.cs2 @@ -0,0 +1,54 @@ +void script_1143(int arg0,int arg1,int arg2,int arg3,string arg4,string arg5,string arg6,string arg7,string arg8,string arg9,string arg10,string arg11) { + string svar8; + if ((stringMethod4107(arg4, "") != 0) && (arg0 != -1)) { + setWidgetSprite(arg0, new WidgetPointer(884,30)); + setWidgetText(new WidgetPointer(884,31), arg4); + setWidgetIsHidden(false, new WidgetPointer(884,11)); + setWidgetContextMenuOption(1, new WidgetPointer(884,11), arg4); + setScriptCallOnMouseOver(38, new WidgetPointer(884,11), new WidgetPointer(884,19), arg5, 25, 190, "IIsii", new WidgetPointer(884,11)); + setScriptCallOnMouseExit(40, new WidgetPointer(884,19), "I", new WidgetPointer(884,11)); + } else { + setWidgetNoOptions(new WidgetPointer(884,11)); + setWidgetIsHidden(true, new WidgetPointer(884,11)); + } + if ((stringMethod4107(arg6, "") != 0) && (arg1 != -1)) { + setWidgetSprite(arg1, new WidgetPointer(884,28)); + setWidgetText(new WidgetPointer(884,27), arg6); + setWidgetIsHidden(false, new WidgetPointer(884,12)); + setWidgetContextMenuOption(1, new WidgetPointer(884,12), arg6); + setScriptCallOnMouseOver(38, new WidgetPointer(884,12), new WidgetPointer(884,19), arg7, 25, 190, "IIsii", new WidgetPointer(884,12)); + setScriptCallOnMouseExit(40, new WidgetPointer(884,19), "I", new WidgetPointer(884,12)); + } else { + setWidgetNoOptions(new WidgetPointer(884,12)); + setWidgetIsHidden(true, new WidgetPointer(884,12)); + } + if ((stringMethod4107(arg8, "") != 0) && (arg2 != -1)) { + setWidgetSprite(arg2, new WidgetPointer(884,24)); + setWidgetText(new WidgetPointer(884,25), arg8); + setWidgetIsHidden(false, new WidgetPointer(884,13)); + setWidgetContextMenuOption(1, new WidgetPointer(884,13), arg8); + setScriptCallOnMouseOver(38, new WidgetPointer(884,13), new WidgetPointer(884,19), arg9, 25, 190, "IIsii", new WidgetPointer(884,13)); + setScriptCallOnMouseExit(40, new WidgetPointer(884,19), "I", new WidgetPointer(884,13)); + } else { + setWidgetNoOptions(new WidgetPointer(884,13)); + setWidgetIsHidden(true, new WidgetPointer(884,13)); + } + if ((stringMethod4107(arg10, "") != 0) && (arg3 != -1)) { + setWidgetSprite(arg3, new WidgetPointer(884,21)); + setWidgetText(new WidgetPointer(884,22), arg10); + setWidgetIsHidden(false, new WidgetPointer(884,14)); + setWidgetContextMenuOption(1, new WidgetPointer(884,14), arg10); + setScriptCallOnMouseOver(38, new WidgetPointer(884,14), new WidgetPointer(884,19), arg11, 25, 190, "IIsii", new WidgetPointer(884,14)); + setScriptCallOnMouseExit(40, new WidgetPointer(884,19), "I", new WidgetPointer(884,14)); + } else { + setWidgetNoOptions(new WidgetPointer(884,14)); + setWidgetIsHidden(true, new WidgetPointer(884,14)); + } + svar8 = "When active, you will automatically fight back if attacked."; + setScriptCallOnMouseOver(38, new WidgetPointer(884,15), new WidgetPointer(884,19), svar8, 25, 190, "IIsii", new WidgetPointer(884,15)); + setScriptCallOnMouseExit(40, new WidgetPointer(884,19), "I", new WidgetPointer(884,15)); + svar8 = "Select to perform a special attack."; + setScriptCallOnMouseOver(38, new WidgetPointer(884,3), new WidgetPointer(884,19), svar8, 25, 190, "IIsii", new WidgetPointer(884,3)); + setScriptCallOnMouseExit(40, new WidgetPointer(884,19), "I", new WidgetPointer(884,3)); + return; +} diff --git a/dumps/scripts/1144.cs2 b/dumps/scripts/1144.cs2 new file mode 100644 index 0000000..f416570 --- /dev/null +++ b/dumps/scripts/1144.cs2 @@ -0,0 +1,7 @@ +void script_1144(int arg0) { + if (cs2method5407(0) == 7) { + cameraMethod5502(0, 5, 600, 400, 1, 5); + } + setScriptCallOnMinimapRelatedSetting3(-1, "", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1145.cs2 b/dumps/scripts/1145.cs2 new file mode 100644 index 0000000..867ae1c --- /dev/null +++ b/dumps/scripts/1145.cs2 @@ -0,0 +1,3 @@ +int script_1145(int arg0,int arg1,int arg2) { + return addToCoordinate(arg2, arg0, 2, arg1); +} diff --git a/dumps/scripts/1146.cs2 b/dumps/scripts/1146.cs2 new file mode 100644 index 0000000..3b3dce4 --- /dev/null +++ b/dumps/scripts/1146.cs2 @@ -0,0 +1,9 @@ +int script_1146(int arg0) { + if (arg0 >= 10000000) { + return 65408; + } + if (arg0 >= 100000) { + return 16777215; + } + return 16776960; +} diff --git a/dumps/scripts/1147.cs2 b/dumps/scripts/1147.cs2 new file mode 100644 index 0000000..fbebb30 --- /dev/null +++ b/dumps/scripts/1147.cs2 @@ -0,0 +1,112 @@ +void script_1147(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + int ivar6; + int ivar7; + ivar6 = -1; + ivar7 = -1; + if (arg1 == arg0) { + setWidgetSize(106, 27, 0, 0, new WidgetPointer(arg3)); + switch (arg0) { + flow_2: + case 0: + ivar6 = 3095; + break; + case 2: + SWITCH (getLanguage()) { + case 1: + GOTO flow_4 + case 2: + GOTO flow_5 + case 3: + GOTO flow_6 + } + ivar6 = 3098; + GOTO flow_7 + flow_4: + ivar6 = 3104; + GOTO flow_7 + flow_5: + ivar6 = 3110; + GOTO flow_7 + flow_6: + ivar6 = 3098; + flow_7: + break; + case 1: + ivar6 = 3119; + break; + case 3: + ivar6 = 3122; + } + setWidgetSprite(ivar6, new WidgetPointer(arg4)); + setScriptCallOnMouseEntered(-1, "", new WidgetPointer(arg3)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg3)); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(arg3)); + } else { + setWidgetSize(106, 27, 0, 0, new WidgetPointer(arg3)); + switch (arg0) { + flow_12: + case 0: + SWITCH (getLanguage()) { + case 1: + GOTO flow_13 + case 2: + GOTO flow_14 + case 3: + GOTO flow_15 + } + ivar6 = 3093; + ivar7 = 3094; + GOTO flow_16 + flow_13: + ivar6 = 3099; + ivar7 = 3100; + GOTO flow_16 + flow_14: + ivar6 = 3105; + ivar7 = 3106; + GOTO flow_16 + flow_15: + ivar6 = 3111; + ivar7 = 3112; + flow_16: + break; + case 2: + SWITCH (getLanguage()) { + case 1: + GOTO flow_18 + case 2: + GOTO flow_19 + case 3: + GOTO flow_20 + } + ivar6 = 3096; + ivar7 = 3097; + GOTO flow_21 + flow_18: + ivar6 = 3102; + ivar7 = 3103; + GOTO flow_21 + flow_19: + ivar6 = 3108; + ivar7 = 3109; + GOTO flow_21 + flow_20: + ivar6 = 3096; + ivar7 = 3097; + flow_21: + break; + case 1: + ivar6 = 3117; + ivar7 = 3118; + break; + case 3: + ivar6 = 3120; + ivar7 = 3121; + } + setWidgetSprite(ivar6, new WidgetPointer(arg4)); + setScriptCallOnMouseEntered(1148, arg0, new WidgetPointer(arg4), ivar6, ivar7, 1, "iIdd1", new WidgetPointer(arg3)); + setScriptCallOnMouseExit(1148, arg0, new WidgetPointer(arg4), ivar6, ivar7, 0, "iIdd1", new WidgetPointer(arg3)); + setScriptCallOnMousePressed(2697, arg0, arg5, "ii", new WidgetPointer(arg3)); + } + return; +} diff --git a/dumps/scripts/1148.cs2 b/dumps/scripts/1148.cs2 new file mode 100644 index 0000000..0cf6352 --- /dev/null +++ b/dumps/scripts/1148.cs2 @@ -0,0 +1,8 @@ +void script_1148(int arg0,int arg1,int arg2,int arg3,int arg4) { + if (((boolean)arg4)) { + setWidgetSprite(arg3, new WidgetPointer(arg1)); + } else { + setWidgetSprite(arg2, new WidgetPointer(arg1)); + } + return; +} diff --git a/dumps/scripts/1149.cs2 b/dumps/scripts/1149.cs2 new file mode 100644 index 0000000..e27e79f --- /dev/null +++ b/dumps/scripts/1149.cs2 @@ -0,0 +1,16 @@ +void script_1149(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8) { + if (arg1 == arg0) { + setWidgetRGB(new Color(235, 224, 188), new WidgetPointer(arg4)); + setWidgetSprite(cs2method_3408(105, 100, 736, arg0), new WidgetPointer(arg3)); + setScriptCallOnMouseEntered(3933, new WidgetPointer(arg4), 15458492, 1, arg0, new WidgetPointer(arg3), arg1, "Ii1iIi", new WidgetPointer(arg2)); + setScriptCallOnMouseExit(3933, new WidgetPointer(arg4), 11709087, 0, arg0, new WidgetPointer(arg3), arg1, "Ii1iIi", new WidgetPointer(arg2)); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(arg2)); + } else { + setWidgetRGB(new Color(178, 170, 159), new WidgetPointer(arg4)); + setWidgetSprite(cs2method_3408(105, 100, 735, arg0), new WidgetPointer(arg3)); + setScriptCallOnMouseEntered(3933, new WidgetPointer(arg4), 15458492, 1, arg0, new WidgetPointer(arg3), arg1, "Ii1iIi", new WidgetPointer(arg2)); + setScriptCallOnMouseExit(3933, new WidgetPointer(arg4), 11709087, 0, arg0, new WidgetPointer(arg3), arg1, "Ii1iIi", new WidgetPointer(arg2)); + setScriptCallOnMousePressed(2698, arg0, arg5, arg6, arg7, arg8, "iiiii", new WidgetPointer(arg2)); + } + return; +} diff --git a/dumps/scripts/115.cs2 b/dumps/scripts/115.cs2 new file mode 100644 index 0000000..1248da9 --- /dev/null +++ b/dumps/scripts/115.cs2 @@ -0,0 +1,5 @@ +void script_115(int arg0) { + globalint_10 = 0; + script_71(arg0); + return; +} diff --git a/dumps/scripts/1150.cs2 b/dumps/scripts/1150.cs2 new file mode 100644 index 0000000..4812998 --- /dev/null +++ b/dumps/scripts/1150.cs2 @@ -0,0 +1,4 @@ +void script_1150(int arg0) { + script_1151(arg0); + return; +} diff --git a/dumps/scripts/1151.cs2 b/dumps/scripts/1151.cs2 new file mode 100644 index 0000000..1c5d970 --- /dev/null +++ b/dumps/scripts/1151.cs2 @@ -0,0 +1,47 @@ +void script_1151(int arg0) { + deleteAllExtraChilds(new WidgetPointer(arg0)); + createExtraChild(new WidgetPointer(arg0), 3, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 1, 1); + setWidgetSize(4, 4, 1, 1); + setWidgetRGB(new Color(83, 72, 58)); + setWidgetFilled(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 1, 0); + setWidgetSize(4, 4, 1, 0); + setWidgetSprite(2231); + cs2method1107(0); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 1, 2); + setWidgetSize(4, 4, 1, 0); + setWidgetSprite(2232); + cs2method1107(0); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 0, 1); + setWidgetSize(3, 4, 0, 1); + setWidgetSprite(2235); + cs2method1107(0); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 2, 1); + setWidgetSize(3, 4, 0, 1); + setWidgetSprite(2236); + cs2method1107(0); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(9, 9, 0, 0); + setWidgetSprite(2239); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 2, 0); + setWidgetSize(9, 9, 0, 0); + setWidgetSprite(2239); + setWidgetHFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 0, 2); + setWidgetSize(9, 9, 0, 0); + setWidgetSprite(2240); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 2, 2); + setWidgetSize(9, 9, 0, 0); + setWidgetSprite(2240); + setWidgetHFlip(1); + return; +} diff --git a/dumps/scripts/1152.cs2 b/dumps/scripts/1152.cs2 new file mode 100644 index 0000000..860947b --- /dev/null +++ b/dumps/scripts/1152.cs2 @@ -0,0 +1,4 @@ +void script_1152(int arg0) { + script_1166(arg0); + return; +} diff --git a/dumps/scripts/1153.cs2 b/dumps/scripts/1153.cs2 new file mode 100644 index 0000000..9ec3582 --- /dev/null +++ b/dumps/scripts/1153.cs2 @@ -0,0 +1,5 @@ +void script_1153() { + cs2method6017(false); + script_1156(); + return; +} diff --git a/dumps/scripts/1154.cs2 b/dumps/scripts/1154.cs2 new file mode 100644 index 0000000..b5502a5 --- /dev/null +++ b/dumps/scripts/1154.cs2 @@ -0,0 +1,5 @@ +void script_1154() { + cs2method6017(true); + script_1156(); + return; +} diff --git a/dumps/scripts/1155.cs2 b/dumps/scripts/1155.cs2 new file mode 100644 index 0000000..f4b1973 --- /dev/null +++ b/dumps/scripts/1155.cs2 @@ -0,0 +1,4 @@ +void script_1155() { + script_1156(); + return; +} diff --git a/dumps/scripts/1156.cs2 b/dumps/scripts/1156.cs2 new file mode 100644 index 0000000..0bec086 --- /dev/null +++ b/dumps/scripts/1156.cs2 @@ -0,0 +1,10 @@ +void script_1156() { + if (cs2method6117()) { + setWidgetSprite(1134, new WidgetPointer(743,51)); + setWidgetSprite(1135, new WidgetPointer(743,49)); + } else { + setWidgetSprite(1134, new WidgetPointer(743,49)); + setWidgetSprite(1135, new WidgetPointer(743,51)); + } + return; +} diff --git a/dumps/scripts/1157.cs2 b/dumps/scripts/1157.cs2 new file mode 100644 index 0000000..ff2abf9 --- /dev/null +++ b/dumps/scripts/1157.cs2 @@ -0,0 +1,28 @@ +void script_1157(int arg0) { + if (arg0 != 1) { + return; + } + if (getDisplayMode() >= 2) { + setWidgetIsHidden(false, new WidgetPointer(746,73)); + } + setWidgetIsHidden(false, new WidgetPointer(752,3)); + setWidgetIsHidden(true, new WidgetPointer(752,7)); + setWidgetIsHidden(true, new WidgetPointer(752,8)); + if (((boolean)script_42(globalint_266))) { + globalstring_38 = ""; + globalstring_39 = ""; + globalint_266 = 1; + } + if (strLength(globalstring_38) > 0) { + setWidgetText(new WidgetPointer(752,4), "Edit the name of your caller:" + "
" + "(Delete it to disable this feature.)"); + } else { + setWidgetText(new WidgetPointer(752,4), "Enter the name of your caller:"); + } + globalint_5 = 12; + script_1564(globalstring_38); + setScriptCallOnMousePressed(1805, "", new WidgetPointer(752,3)); + script_2026(); + setScriptCallOnKeyPress(112, -2147483640, false, "iz", new WidgetPointer(752,5)); + script_1188(); + return; +} diff --git a/dumps/scripts/1158.cs2 b/dumps/scripts/1158.cs2 new file mode 100644 index 0000000..eb2fa3e --- /dev/null +++ b/dumps/scripts/1158.cs2 @@ -0,0 +1,4 @@ +void script_1158() { + script_1159(); + return; +} diff --git a/dumps/scripts/1159.cs2 b/dumps/scripts/1159.cs2 new file mode 100644 index 0000000..ffe6d41 --- /dev/null +++ b/dumps/scripts/1159.cs2 @@ -0,0 +1,8 @@ +void script_1159() { + int ivar0; + int ivar1; + ivar0 = subtract(getWidgetActualWidth(new WidgetPointer(743,30)), getWidgetActualWidth(new WidgetPointer(743,9))); + ivar1 = multiplyDivide(cs2method6119(), 255, ivar0); + setWidgetPosition(ivar1, 0, 0, 0, new WidgetPointer(743,9)); + return; +} diff --git a/dumps/scripts/116.cs2 b/dumps/scripts/116.cs2 new file mode 100644 index 0000000..e94f8e7 --- /dev/null +++ b/dumps/scripts/116.cs2 @@ -0,0 +1,4 @@ +void script_116() { + setWidgetText(new WidgetPointer(209,4), intToStr(standart_config_531) + " %"); + return; +} diff --git a/dumps/scripts/1160.cs2 b/dumps/scripts/1160.cs2 new file mode 100644 index 0000000..ecce0d5 --- /dev/null +++ b/dumps/scripts/1160.cs2 @@ -0,0 +1,4 @@ +void script_1160(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5) { + script_1163(arg0, arg1, arg2, arg3, arg4, arg5); + return; +} diff --git a/dumps/scripts/1161.cs2 b/dumps/scripts/1161.cs2 new file mode 100644 index 0000000..9ef4243 --- /dev/null +++ b/dumps/scripts/1161.cs2 @@ -0,0 +1,4 @@ +void script_1161() { + script_1162(); + return; +} diff --git a/dumps/scripts/1162.cs2 b/dumps/scripts/1162.cs2 new file mode 100644 index 0000000..4256cfb --- /dev/null +++ b/dumps/scripts/1162.cs2 @@ -0,0 +1,8 @@ +void script_1162() { + int ivar0; + int ivar1; + ivar0 = subtract(getWidgetActualWidth(new WidgetPointer(743,48)), getWidgetActualWidth(new WidgetPointer(743,7))); + ivar1 = multiplyDivide(cs2method6120(), 127, ivar0); + setWidgetPosition(ivar1, 0, 0, 0, new WidgetPointer(743,7)); + return; +} diff --git a/dumps/scripts/1163.cs2 b/dumps/scripts/1163.cs2 new file mode 100644 index 0000000..7785a3d --- /dev/null +++ b/dumps/scripts/1163.cs2 @@ -0,0 +1,99 @@ +void script_1163(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5) { + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + flow_0: + ivar5 = 0; + ivar6 = 0; + ivar7 = 0; + ivar8 = 0; + ivar9 = 0; + ivar10 = 0; + ivar11 = 0; + ivar12 = 0; + ivar13 = -1; + ivar14 = 0; + IF (arg1 == -1) + GOTO flow_1 + GOTO flow_2 + flow_1: + IF (setWidgetRegister(new WidgetPointer(arg0))) + GOTO flow_3 + flow_2: + IF (setWidgetRegister(new WidgetPointer(arg0), arg1)) + GOTO flow_3 + GOTO flow_24 + flow_3: + if (((boolean)script_4761(arg3))) { + return; + } + if (globalint_2 != 1) { + ivar5 = add(script_1743(), 5); + ivar14 = script_1744(); + ivar6 = add(add(ivar14, getWidgetActualHeight()), 5); + ivar13 = getWidgetParentId(new WidgetPointer(arg2)); + if ((ivar13 != -1) && (arg4 >= getWidgetActualWidth(new WidgetPointer(ivar13)))) { + arg4 = getWidgetActualWidth(new WidgetPointer(ivar13)); + } + ivar11 = add(4, getMaxLineWidth(subtract(arg4, 4), 495, arg5)); + ivar12 = add(add(4, multiply(13, getLineCount(subtract(arg4, 4), 495, arg5))), 3); + if (ivar13 != -1) { + ivar7 = subtract(ivar5, cs2method2600(new WidgetPointer(ivar13))); + ivar8 = subtract(ivar6, cs2method2601(new WidgetPointer(ivar13))); + if (ivar7 < 0) { + ivar5 = cs2method2600(new WidgetPointer(ivar13)); + ivar7 = 0; + } + if (ivar8 < 0) { + ivar6 = cs2method2601(new WidgetPointer(ivar13)); + ivar8 = 0; + } + if (ivar7 > 0) { + ivar9 = add(subtract(ivar7, getWidgetActualWidth(new WidgetPointer(ivar13))), ivar11); + if (ivar9 > 0) { + ivar5 = subtract(ivar5, ivar9); + } + } + if (ivar8 > 0) { + ivar10 = add(subtract(ivar8, getWidgetActualHeight(new WidgetPointer(ivar13))), ivar12); + if (ivar10 > 0) { + if ((ivar14 > ivar12) && (getWidgetActualHeight() < ivar12)) { + ivar6 = subtract(ivar14, ivar12); + } else { + ivar6 = subtract(subtract(subtract(ivar6, ivar10), getWidgetActualHeight()), 10); + } + } + } + } + ivar5 = max(ivar5, 0); + ivar6 = max(ivar6, 0); + setWidgetSize(ivar11, ivar12, 0, 0, new WidgetPointer(arg2)); + setWidgetPosition(ivar5, ivar6, 0, 0, new WidgetPointer(arg2)); + deleteAllExtraChilds(new WidgetPointer(arg2)); + createExtraChild(new WidgetPointer(arg2), 3, 0); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg2)), getWidgetActualHeight(new WidgetPointer(arg2)), 0, 0); + setWidgetFilled(1); + setWidgetRGB(new Color(255, 255, 160)); + createExtraChild(new WidgetPointer(arg2), 3, 1); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg2)), getWidgetActualHeight(new WidgetPointer(arg2)), 0, 0); + setWidgetFilled(0); + setWidgetRGB(new Color(0, 0, 0)); + createExtraChild(new WidgetPointer(arg2), 4, 2); + setWidgetSize(subtract(arg4, 4), getWidgetActualHeight(new WidgetPointer(arg2)), 0, 0); + setWidgetPosition(2, 0, 0, 0); + setWidgetText(arg5); + setWidgetTextAlignment(0, 1, 0); + setWidgetFont(495); + setWidgetRGB(new Color(0, 0, 0)); + globalint_2 = 1; + } + flow_24: + return; +} diff --git a/dumps/scripts/1164.cs2 b/dumps/scripts/1164.cs2 new file mode 100644 index 0000000..ab24272 --- /dev/null +++ b/dumps/scripts/1164.cs2 @@ -0,0 +1,4 @@ +void script_1164() { + script_1165(); + return; +} diff --git a/dumps/scripts/1165.cs2 b/dumps/scripts/1165.cs2 new file mode 100644 index 0000000..2dff9ea --- /dev/null +++ b/dumps/scripts/1165.cs2 @@ -0,0 +1,8 @@ +void script_1165() { + int ivar0; + int ivar1; + ivar0 = subtract(getWidgetActualWidth(new WidgetPointer(743,39)), getWidgetActualWidth(new WidgetPointer(743,8))); + ivar1 = multiplyDivide(cs2method6118(), 127, ivar0); + setWidgetPosition(ivar1, 0, 0, 0, new WidgetPointer(743,8)); + return; +} diff --git a/dumps/scripts/1166.cs2 b/dumps/scripts/1166.cs2 new file mode 100644 index 0000000..2f89c25 --- /dev/null +++ b/dumps/scripts/1166.cs2 @@ -0,0 +1,47 @@ +void script_1166(int arg0) { + deleteAllExtraChilds(new WidgetPointer(arg0)); + createExtraChild(new WidgetPointer(arg0), 3, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 1, 1); + setWidgetSize(4, 4, 1, 1); + setWidgetRGB(new Color(60, 52, 40)); + setWidgetFilled(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 1, 0); + setWidgetSize(4, 4, 1, 0); + setWidgetSprite(2233); + cs2method1107(0); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 1, 2); + setWidgetSize(4, 4, 1, 0); + setWidgetSprite(2234); + cs2method1107(0); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 0, 1); + setWidgetSize(3, 4, 0, 1); + setWidgetSprite(2237); + cs2method1107(0); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 2, 1); + setWidgetSize(3, 4, 0, 1); + setWidgetSprite(2238); + cs2method1107(0); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(9, 9, 0, 0); + setWidgetSprite(2241); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 2, 0); + setWidgetSize(9, 9, 0, 0); + setWidgetSprite(2241); + setWidgetHFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 0, 2); + setWidgetSize(9, 9, 0, 0); + setWidgetSprite(2242); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 2, 2); + setWidgetSize(9, 9, 0, 0); + setWidgetSprite(2242); + setWidgetHFlip(1); + return; +} diff --git a/dumps/scripts/1167.cs2 b/dumps/scripts/1167.cs2 new file mode 100644 index 0000000..c2bf521 --- /dev/null +++ b/dumps/scripts/1167.cs2 @@ -0,0 +1,84 @@ +void script_1167() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + ivar0 = -1; + switch (globalint_1001) { + case 1: + ivar0 = 738; + break; + case 2: + ivar0 = 739; + break; + case 3: + ivar0 = 740; + break; + case 4: + ivar0 = 741; + break; + case 5: + ivar0 = 742; + break; + default: + return; + } + setWidgetText(new WidgetPointer(885,14), cs2method_3408(105, 115, 205, globalint_1001)); + ivar1 = 0; + ivar2 = 0; + ivar3 = 16; + ivar4 = 16; + ivar5 = 56; + ivar6 = 50; + ivar7 = getCommonDefinitionSize(ivar0); + ivar8 = 5; + ivar9 = -1; + deleteAllExtraChilds(new WidgetPointer(885,16)); + while (ivar1 < ivar7) { + ivar9 = cs2method_3408(105, 111, ivar0, ivar1); + if (ivar9 != -1) { + createExtraChild(new WidgetPointer(885,16), 5, ivar2); + setWidgetSize(36, 32, 0, 0); + setItemOnWidgetMethod1208(cs2method_3408(105, 111, ivar0, ivar1), -1); + setWidgetPosition(add(11, add(ivar3, multiply(add(36, ivar5), mod(ivar1, ivar8)))), add(6, add(ivar4, multiply(divide(ivar1, ivar8), add(32, ivar6)))), 0, 0); + setWidgetContextMenuOption(1, "Examine"); + cs2method1305("" + getItemName(ivar9)); + createExtraChild(new WidgetPointer(885,16), 4, add(ivar2, 1)); + setWidgetSize(56, 10, 0, 0); + setWidgetFont(494); + setWidgetRGB(new Color(204, 153, 0)); + setWidgetUnknownBoolean(true); + setWidgetTextAlignment(1, 0, 0); + if (((boolean)stringMethod4107(getWidgetText(), ""))) { + setWidgetText("Getting data..."); + } + setWidgetPosition(add(ivar3, multiply(add(ivar5, 36), mod(ivar1, ivar8))), add(47, add(ivar4, multiply(divide(ivar1, ivar8), add(32, ivar6)))), 0, 0); + setWidgetIsHidden(false, cs2method_3408(105, 73, 737, ivar1)); + setWidgetPosition(add(ivar3, multiply(add(36, ivar5), mod(ivar1, ivar8))), add(ivar4, multiply(divide(ivar1, ivar8), add(32, ivar6))), 0, 0, cs2method_3408(105, 73, 737, ivar1)); + ivar2 = add(ivar2, 2); + } + ivar1 = add(ivar1, 1); + } + while (ivar1 < getCommonDefinitionSize(737)) { + setWidgetIsHidden(true, cs2method_3408(105, 73, 737, ivar1)); + ivar1 = add(ivar1, 1); + } + if (ivar7 <= 15) { + cs2method2100(0, 0, new WidgetPointer(885,16)); + setWidgetScrollMax(0, 0, new WidgetPointer(885,16)); + deleteAllExtraChilds(new WidgetPointer(885,48)); + setWidgetIsHidden(true, new WidgetPointer(885,48)); + } else { + setWidgetIsHidden(false, new WidgetPointer(885,48)); + cs2method2100(0, 0, new WidgetPointer(885,16)); + setWidgetScrollMax(getWidgetActualWidth(new WidgetPointer(885,16)), add(60, add(ivar4, multiply(divide(ivar7, ivar8), add(32, ivar6)))), new WidgetPointer(885,16)); + script_31(57999408, 57999376, 792, 789, 790, 791, 773, 788); + } + return; +} diff --git a/dumps/scripts/1168.cs2 b/dumps/scripts/1168.cs2 new file mode 100644 index 0000000..54ce48d --- /dev/null +++ b/dumps/scripts/1168.cs2 @@ -0,0 +1,9 @@ +void script_1168(int arg0,int arg1,string arg2) { + if (mod(getClientCycle(), 50) != 0) { + return; + } + if (setWidgetRegister(new WidgetPointer(885,16), arg0)) { + setWidgetText(arg2); + } + return; +} diff --git a/dumps/scripts/1169.cs2 b/dumps/scripts/1169.cs2 new file mode 100644 index 0000000..bfb5571 --- /dev/null +++ b/dumps/scripts/1169.cs2 @@ -0,0 +1,6 @@ +void script_1169(int arg0,int arg1,string arg2) { + int ivar2; + ivar2 = ((int)cs2method_3408(105, 73, 737, arg1)); + setScriptCallOnGameloop(1168, arg0, arg2, new WidgetPointer(ivar2), "isI", new WidgetPointer(ivar2)); + return; +} diff --git a/dumps/scripts/117.cs2 b/dumps/scripts/117.cs2 new file mode 100644 index 0000000..cc4454d --- /dev/null +++ b/dumps/scripts/117.cs2 @@ -0,0 +1,13 @@ +void script_117() { + if (((bitconfig_3756 < 1) || (bitconfig_3756 > 20)) || ((boolean)script_1314(subtract(bitconfig_3756, 1)))) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(746,22)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(548,128)); + script_736(-1, -1, -1, -1); + script_1364(); + return; + } + script_2756(); + setScriptCallOnGameloop(1420, "", new WidgetPointer(746,22)); + setScriptCallOnGameloop(1420, "", new WidgetPointer(548,128)); + return; +} diff --git a/dumps/scripts/1170.cs2 b/dumps/scripts/1170.cs2 new file mode 100644 index 0000000..b5a5eb6 --- /dev/null +++ b/dumps/scripts/1170.cs2 @@ -0,0 +1,8 @@ +void script_1170() { + if (getWidgetShadeColor(new WidgetPointer(601,1)) > globalint_1435) { + cs2method2103(max(50, subtract(getWidgetShadeColor(new WidgetPointer(601,1)), 1)), new WidgetPointer(601,1)); + } else { + cs2method2103(min(255, add(getWidgetShadeColor(new WidgetPointer(601,1)), 1)), new WidgetPointer(601,1)); + } + return; +} diff --git a/dumps/scripts/1171.cs2 b/dumps/scripts/1171.cs2 new file mode 100644 index 0000000..9c23934 --- /dev/null +++ b/dumps/scripts/1171.cs2 @@ -0,0 +1,4 @@ +void script_1171() { + setWidgetSize(100, 90, 0, 0, new WidgetPointer(601,0)); + return; +} diff --git a/dumps/scripts/1172.cs2 b/dumps/scripts/1172.cs2 new file mode 100644 index 0000000..e1fa924 --- /dev/null +++ b/dumps/scripts/1172.cs2 @@ -0,0 +1,5 @@ +void script_1172(int arg0,int arg1,int arg2) { + script_25(); + script_2708(arg0, arg1, arg2, 57802828, 57802830, 57802829); + return; +} diff --git a/dumps/scripts/1173.cs2 b/dumps/scripts/1173.cs2 new file mode 100644 index 0000000..fdfb504 --- /dev/null +++ b/dumps/scripts/1173.cs2 @@ -0,0 +1,4 @@ +void script_1173(int arg0) { + script_1174(arg0); + return; +} diff --git a/dumps/scripts/1174.cs2 b/dumps/scripts/1174.cs2 new file mode 100644 index 0000000..b802a98 --- /dev/null +++ b/dumps/scripts/1174.cs2 @@ -0,0 +1,4 @@ +void script_1174(int arg0) { + script_3239(arg0, 0, 0); + return; +} diff --git a/dumps/scripts/1175.cs2 b/dumps/scripts/1175.cs2 new file mode 100644 index 0000000..6145c38 --- /dev/null +++ b/dumps/scripts/1175.cs2 @@ -0,0 +1,68 @@ +void script_1175() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + if (mod(getClientCycle(), 10) != 0) { + return; + } + ivar0 = 0; + ivar1 = extractY(getMyPositionHash()); + ivar2 = extractX(getMyPositionHash()); + if (((ivar1 > 9919) && (ivar1 < 10368)) && ((ivar2 > 3007) && (ivar2 < 3136))) { + ivar0 = add(divide(subtract(ivar1, 9920), 8), 1); + } else { + if ((((ivar1 > 3524) && (ivar1 < 3968)) && ((ivar2 > 2943) && (ivar2 < 3393))) && ((boolean)bitconfig_5447)) { + ivar0 = add(divide(subtract(ivar1, 3520), 8), 1); + } + } + if (ivar0 < 0) { + ivar0 = 0; + } else { + if (ivar0 > 60) { + ivar0 = 60; + } + } + ivar3 = getMyCombat(); + ivar4 = 0; + ivar5 = 0; + if (((boolean)script_208())) { + ivar4 = subtract(ivar3, ivar0); + if (ivar4 < 20) { + ivar4 = 20; + } + ivar5 = add(ivar3, ivar0); + if (ivar5 > 138) { + ivar5 = 138; + } + if (ivar4 == ivar5) { + if (getDisplayMode() < 2) { + setWidgetText(new WidgetPointer(548,10), " "); + } else { + setWidgetText(new WidgetPointer(746,17), " "); + } + return; + } + } else { + ivar4 = subtract(ivar3, add(ivar0, add(5, divide(ivar3, 10)))); + if (ivar4 < 20) { + ivar4 = 20; + } + ivar5 = add(ivar3, add(ivar0, add(5, divide(ivar3, 10)))); + if (ivar5 > 138) { + ivar5 = 138; + } + while ((ivar5 < 139) && (subtract(ivar5, add(ivar0, add(5, divide(ivar5, 10)))) <= ivar3)) { + ivar5 = add(ivar5, 1); + } + ivar5 = subtract(ivar5, 1); + } + if (getDisplayMode() < 2) { + setWidgetText(new WidgetPointer(548,10), intToStr(ivar4) + " - " + intToStr(ivar5)); + } else { + setWidgetText(new WidgetPointer(746,17), intToStr(ivar4) + " - " + intToStr(ivar5)); + } + return; +} diff --git a/dumps/scripts/1176.cs2 b/dumps/scripts/1176.cs2 new file mode 100644 index 0000000..5d22be5 --- /dev/null +++ b/dumps/scripts/1176.cs2 @@ -0,0 +1,22 @@ +void script_1176(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10) { + if (arg1 < add(arg7, multiplyDivide(1, 3, arg9))) { + if (arg2 < add(arg8, multiplyDivide(1, 3, arg10))) { + setWidget3DRotation(0, 0, 512, 768, 0, 1000, new WidgetPointer(arg0)); + setWidgetSize(50, 50, 0, 0, new WidgetPointer(arg0)); + setWidgetPosition(max(add(arg5, arg3), 0), max(add(arg6, arg4), 22), 0, 0, new WidgetPointer(arg0)); + } else { + setWidget3DRotation(0, 0, 512, 256, 0, 1000, new WidgetPointer(arg0)); + setWidgetSize(50, 50, 0, 0, new WidgetPointer(arg0)); + setWidgetPosition(max(add(arg5, arg3), 0), subtract(min(arg6, arg10), getWidgetActualHeight(new WidgetPointer(arg0))), 0, 0, new WidgetPointer(arg0)); + } + } else if (arg2 < add(arg8, multiplyDivide(1, 3, arg10))) { + setWidget3DRotation(0, 0, 512, 1280, 0, 1000, new WidgetPointer(arg0)); + setWidgetSize(50, 50, 0, 0, new WidgetPointer(arg0)); + setWidgetPosition(min(subtract(arg5, getWidgetActualWidth(new WidgetPointer(arg0))), arg9), max(add(arg6, arg4), 22), 0, 0, new WidgetPointer(arg0)); + } else { + setWidget3DRotation(0, 0, 512, 1792, 0, 1000, new WidgetPointer(arg0)); + setWidgetSize(50, 50, 0, 0, new WidgetPointer(arg0)); + setWidgetPosition(min(subtract(arg5, getWidgetActualWidth(new WidgetPointer(arg0))), arg9), subtract(min(arg6, arg10), getWidgetActualHeight(new WidgetPointer(arg0))), 0, 0, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/1177.cs2 b/dumps/scripts/1177.cs2 new file mode 100644 index 0000000..03b4481 --- /dev/null +++ b/dumps/scripts/1177.cs2 @@ -0,0 +1,9 @@ +void script_1177() { + if (((boolean)standart_config_1414)) { + return; + } + globalint_548 = 540; + setWidgetText(new WidgetPointer(745,5), "10"); + setScriptCallOnGameloop(1178, "", new WidgetPointer(745,5)); + return; +} diff --git a/dumps/scripts/1178.cs2 b/dumps/scripts/1178.cs2 new file mode 100644 index 0000000..87c5675 --- /dev/null +++ b/dumps/scripts/1178.cs2 @@ -0,0 +1,8 @@ +void script_1178() { + globalint_548 = max(0, subtract(globalint_548, 1)); + setWidgetText(new WidgetPointer(745,5), intToStr(divide(multiply(globalint_548, 2), 100))); + if (globalint_548 <= 0) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(745,5)); + } + return; +} diff --git a/dumps/scripts/1179.cs2 b/dumps/scripts/1179.cs2 new file mode 100644 index 0000000..7b15283 --- /dev/null +++ b/dumps/scripts/1179.cs2 @@ -0,0 +1,18 @@ +void script_1179() { + if (((boolean)bitconfig_7232)) { + if (((boolean)getLanguage())) { + setWidgetSprite(5571, new WidgetPointer(548,0)); + setWidgetSprite(5571, new WidgetPointer(746,229)); + } else { + setWidgetSprite(5569, new WidgetPointer(548,0)); + setWidgetSprite(5569, new WidgetPointer(746,229)); + } + } else if (((boolean)getLanguage())) { + setWidgetSprite(2715, new WidgetPointer(548,0)); + setWidgetSprite(2715, new WidgetPointer(746,229)); + } else { + setWidgetSprite(2731, new WidgetPointer(548,0)); + setWidgetSprite(2731, new WidgetPointer(746,229)); + } + return; +} diff --git a/dumps/scripts/118.cs2 b/dumps/scripts/118.cs2 new file mode 100644 index 0000000..dae0449 --- /dev/null +++ b/dumps/scripts/118.cs2 @@ -0,0 +1,4 @@ +void script_118() { + script_1667(); + return; +} diff --git a/dumps/scripts/1180.cs2 b/dumps/scripts/1180.cs2 new file mode 100644 index 0000000..711beeb --- /dev/null +++ b/dumps/scripts/1180.cs2 @@ -0,0 +1,18 @@ +void script_1180() { + if (((boolean)bitconfig_7232)) { + if (((boolean)getLanguage())) { + setWidgetSprite(5570, new WidgetPointer(548,0)); + setWidgetSprite(5570, new WidgetPointer(746,229)); + } else { + setWidgetSprite(5568, new WidgetPointer(548,0)); + setWidgetSprite(5568, new WidgetPointer(746,229)); + } + } else if (((boolean)getLanguage())) { + setWidgetSprite(2714, new WidgetPointer(548,0)); + setWidgetSprite(2714, new WidgetPointer(746,229)); + } else { + setWidgetSprite(2730, new WidgetPointer(548,0)); + setWidgetSprite(2730, new WidgetPointer(746,229)); + } + return; +} diff --git a/dumps/scripts/1181.cs2 b/dumps/scripts/1181.cs2 new file mode 100644 index 0000000..2a831cd --- /dev/null +++ b/dumps/scripts/1181.cs2 @@ -0,0 +1,4 @@ +void script_1181(int arg0) { + script_1182(arg0); + return; +} diff --git a/dumps/scripts/1182.cs2 b/dumps/scripts/1182.cs2 new file mode 100644 index 0000000..c8d0a7f --- /dev/null +++ b/dumps/scripts/1182.cs2 @@ -0,0 +1,37 @@ +void script_1182(int arg0) { + int ivar1; + int ivar2; + string svar0; + string svar1; + int stack_dump0; + opcStruct6506(4,3,0) structdump_1; + if (cs2method6500()) { + setScriptCallOnGameloop(1181, arg0, "i", new WidgetPointer(909,14)); + return; + } + setScriptCallOnGameloop(-1, "", new WidgetPointer(909,14)); + ivar1 = 0; + svar0 = ""; + ivar2 = 0; + svar1 = ""; + stack_dump0 = arg0; + structdump_1 = cs2method6506(stack_dump0); + svar1 = structdump_1.stringpart_2; + ivar1 = structdump_1.intpart_3; + ivar1 = structdump_1.intpart_2; + svar0 = structdump_1.stringpart_1; + ivar1 = structdump_1.intpart_1; + svar0 = structdump_1.stringpart_0; + ivar2 = structdump_1.intpart_0; + if (ivar2 == -1) { + messageType0("Sorry, you can't join that person."); + } else if (setWorldHost(arg0, svar1)) { + globalint_547 = 0; + script_3143(0, "Switched to game world " + intToStr(arg0)); + script_3062(59375787); + } else { + script_3143(1, "Sorry, we couldn't contact world " + intToStr(arg0) + "." + "
" + "Please choose a different world."); + messageType0("Sorry, we couldn't contact world " + intToStr(arg0) + ". Please choose a different world."); + } + return; +} diff --git a/dumps/scripts/1183.cs2 b/dumps/scripts/1183.cs2 new file mode 100644 index 0000000..eba6470 --- /dev/null +++ b/dumps/scripts/1183.cs2 @@ -0,0 +1,44 @@ +void script_1183(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + switch (globalint_808) { + case 1: + setWidgetIsHidden(true, new WidgetPointer(arg3)); + setWidgetIsHidden(true, new WidgetPointer(arg4)); + setWidgetIsHidden(true, new WidgetPointer(arg5)); + setWidgetIsHidden(false, new WidgetPointer(arg2)); + setWidgetText(new WidgetPointer(arg0), "Draughts"); + setWidgetText(new WidgetPointer(arg1), intToStr(standart_config_354)); + break; + case 2: + setWidgetIsHidden(true, new WidgetPointer(arg2)); + setWidgetIsHidden(true, new WidgetPointer(arg4)); + setWidgetIsHidden(true, new WidgetPointer(arg5)); + setWidgetIsHidden(false, new WidgetPointer(arg3)); + setWidgetText(new WidgetPointer(arg0), "Runelink"); + setWidgetText(new WidgetPointer(arg1), intToStr(standart_config_353)); + break; + case 3: + setWidgetIsHidden(true, new WidgetPointer(arg2)); + setWidgetIsHidden(true, new WidgetPointer(arg3)); + setWidgetIsHidden(true, new WidgetPointer(arg5)); + setWidgetIsHidden(false, new WidgetPointer(arg4)); + setWidgetText(new WidgetPointer(arg0), "Runesquares"); + setWidgetText(new WidgetPointer(arg1), intToStr(standart_config_648)); + break; + case 4: + setWidgetIsHidden(true, new WidgetPointer(arg2)); + setWidgetIsHidden(true, new WidgetPointer(arg3)); + setWidgetIsHidden(true, new WidgetPointer(arg4)); + setWidgetIsHidden(false, new WidgetPointer(arg5)); + setWidgetText(new WidgetPointer(arg0), "Runeversi"); + setWidgetText(new WidgetPointer(arg1), intToStr(standart_config_649)); + break; + default: + setWidgetIsHidden(true, new WidgetPointer(arg3)); + setWidgetIsHidden(true, new WidgetPointer(arg4)); + setWidgetIsHidden(true, new WidgetPointer(arg5)); + setWidgetIsHidden(true, new WidgetPointer(arg2)); + setWidgetText(new WidgetPointer(arg0), ""); + setWidgetText(new WidgetPointer(arg1), ""); + } + return; +} diff --git a/dumps/scripts/1184.cs2 b/dumps/scripts/1184.cs2 new file mode 100644 index 0000000..6d4dfca --- /dev/null +++ b/dumps/scripts/1184.cs2 @@ -0,0 +1,5 @@ +void script_1184(int arg0) { + setWidgetRGB(new Color(script_806()), new WidgetPointer(arg0)); + setWidgetText(new WidgetPointer(arg0), intToStr(getRunEnergy())); + return; +} diff --git a/dumps/scripts/1185.cs2 b/dumps/scripts/1185.cs2 new file mode 100644 index 0000000..4c49557 --- /dev/null +++ b/dumps/scripts/1185.cs2 @@ -0,0 +1,6 @@ +void script_1185(int arg0,int arg1) { + int ivar2; + ivar2 = subtract(getWidgetActualWidth(new WidgetPointer(arg0)), getWidgetActualWidth(new WidgetPointer(arg1))); + setWidgetPosition(multiply(subtract(cs2method6101(), 1), divide(ivar2, 3)), 0, 0, 0, new WidgetPointer(arg1)); + return; +} diff --git a/dumps/scripts/1186.cs2 b/dumps/scripts/1186.cs2 new file mode 100644 index 0000000..748f3cf --- /dev/null +++ b/dumps/scripts/1186.cs2 @@ -0,0 +1,62 @@ +void script_1186() { + int ivar0; + if (getDisplayMode() >= 2) { + if (isWidgetOpen(new WidgetPointer(752,13))) { + setWidgetIsHidden(false, new WidgetPointer(752,1)); + cs2method2122(1, 49283073); + if (((boolean)bitconfig_542)) { + setWidgetSprite(1204, new WidgetPointer(752,1)); + setWidgetIsHidden(false, new WidgetPointer(752,2)); + } else { + setWidgetSprite(1205, new WidgetPointer(752,1)); + setWidgetIsHidden(true, new WidgetPointer(752,2)); + } + } else if (isWidgetOpen(new WidgetPointer(752,12))) { + setWidgetIsHidden(false, new WidgetPointer(752,1)); + cs2method2122(1, 49283073); + if (((boolean)bitconfig_542)) { + setWidgetSprite(1204, new WidgetPointer(752,1)); + setWidgetIsHidden(false, new WidgetPointer(752,2)); + } else { + setWidgetSprite(1205, new WidgetPointer(752,1)); + setWidgetIsHidden(true, new WidgetPointer(752,2)); + } + } else if (isWidgetOpen(new WidgetPointer(752,11))) { + setWidgetIsHidden(false, new WidgetPointer(752,1)); + cs2method2122(1, 49283073); + if (((boolean)bitconfig_542)) { + setWidgetSprite(1204, new WidgetPointer(752,1)); + setWidgetIsHidden(false, new WidgetPointer(752,2)); + } else { + setWidgetSprite(1205, new WidgetPointer(752,1)); + setWidgetIsHidden(true, new WidgetPointer(752,2)); + } + } else { + if (isWidgetOpen(new WidgetPointer(752,10))) { + setWidgetIsHidden(false, new WidgetPointer(752,1)); + cs2method2122(1, 49283073); + if (((boolean)bitconfig_542)) { + setWidgetSprite(1204, new WidgetPointer(752,1)); + setWidgetIsHidden(false, new WidgetPointer(752,2)); + } else { + setWidgetSprite(1205, new WidgetPointer(752,1)); + setWidgetIsHidden(true, new WidgetPointer(752,2)); + } + } + } + } + ivar0 = script_734(bitconfig_6448); + setWidgetIsHidden(((boolean)ivar0), new WidgetPointer(548,15)); + setWidgetIsHidden(((boolean)ivar0), new WidgetPointer(548,10)); + setWidgetIsHidden(((boolean)ivar0), new WidgetPointer(746,15)); + setWidgetIsHidden(((boolean)ivar0), new WidgetPointer(746,17)); + if (((boolean)script_1569())) { + setWidgetIsHidden(((boolean)ivar0), new WidgetPointer(746,71)); + setWidgetIsHidden(((boolean)ivar0), new WidgetPointer(746,79)); + } else { + setWidgetIsHidden(true, new WidgetPointer(746,71)); + setWidgetIsHidden(false, new WidgetPointer(746,79)); + } + setWidgetIsHidden(((boolean)ivar0), new WidgetPointer(746,20)); + return; +} diff --git a/dumps/scripts/1187.cs2 b/dumps/scripts/1187.cs2 new file mode 100644 index 0000000..869e932 --- /dev/null +++ b/dumps/scripts/1187.cs2 @@ -0,0 +1,4 @@ +void script_1187() { + sendCloseWidgetPacket(); + return; +} diff --git a/dumps/scripts/1188.cs2 b/dumps/scripts/1188.cs2 new file mode 100644 index 0000000..84e4d10 --- /dev/null +++ b/dumps/scripts/1188.cs2 @@ -0,0 +1,11 @@ +void script_1188() { + if (getDisplayMode() >= 2) { + setWidgetSprite(1017, new WidgetPointer(752,1)); + cs2method2122(1, 49283073); + setWidgetIsHidden(false, new WidgetPointer(752,1)); + setWidgetIsHidden(false, new WidgetPointer(752,2)); + script_1652(0); + setWidgetIsHidden(true, new WidgetPointer(746,75)); + } + return; +} diff --git a/dumps/scripts/1189.cs2 b/dumps/scripts/1189.cs2 new file mode 100644 index 0000000..6da395b --- /dev/null +++ b/dumps/scripts/1189.cs2 @@ -0,0 +1,4 @@ +void script_1189(int arg0,int arg1) { + setWidgetIsHidden(((boolean)arg1), new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/119.cs2 b/dumps/scripts/119.cs2 new file mode 100644 index 0000000..068225a --- /dev/null +++ b/dumps/scripts/119.cs2 @@ -0,0 +1,4 @@ +void script_119(int arg0) { + script_1365(arg0); + return; +} diff --git a/dumps/scripts/1190.cs2 b/dumps/scripts/1190.cs2 new file mode 100644 index 0000000..a5029ed --- /dev/null +++ b/dumps/scripts/1190.cs2 @@ -0,0 +1,25 @@ +void script_1190() { + int ivar0; + int ivar1; + int ivar2; + ivar0 = 0; + ivar1 = 0; + ivar2 = 0; + while (ivar0 < getItemContainerLength(482)) { + createExtraChild(new WidgetPointer(477,26), 5, ivar0); + setWidgetSize(36, 32, 0, 0); + ivar1 = script_1425(ivar0); + ivar2 = script_1426(ivar0); + setWidgetPosition(ivar1, ivar2, 0, 0); + if (getItemIdInSlot(482, ivar0) != -1) { + setItemOnWidgetMethod1200(getItemIdInSlot(482, ivar0), getItemAmtInSlot(482, ivar0)); + cs2method1305(getItemName(getItemIdInSlot(482, ivar0))); + setWidgetContextMenuOption(1, "Value"); + setWidgetContextMenuOption(2, "Buy 1"); + setWidgetContextMenuOption(3, "Buy 5"); + setWidgetContextMenuOption(4, "Buy 10"); + } + ivar0 = add(ivar0, 1); + } + return; +} diff --git a/dumps/scripts/1191.cs2 b/dumps/scripts/1191.cs2 new file mode 100644 index 0000000..9ecb43b --- /dev/null +++ b/dumps/scripts/1191.cs2 @@ -0,0 +1,6 @@ +void script_1191(int arg0,int arg1) { + if (getLanguage() != 0) { + setWidgetFont(arg1, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/1192.cs2 b/dumps/scripts/1192.cs2 new file mode 100644 index 0000000..40a5b07 --- /dev/null +++ b/dumps/scripts/1192.cs2 @@ -0,0 +1,7 @@ +void script_1192(int arg0,int arg1) { + setWidgetSize(add(getMaxLineWidth(512, 495, getWidgetText(new WidgetPointer(arg1))), 34), getWidgetActualHeight(new WidgetPointer(arg0)), 0, 0, new WidgetPointer(arg0)); + setScriptCallOnGlobalConfigChange(1193, 1, 1002, 1, "1Y", new WidgetPointer(arg0)); + setScriptCallOnGameloop(1193, 0, "1", new WidgetPointer(arg0)); + script_1194(); + return; +} diff --git a/dumps/scripts/1193.cs2 b/dumps/scripts/1193.cs2 new file mode 100644 index 0000000..a21769c --- /dev/null +++ b/dumps/scripts/1193.cs2 @@ -0,0 +1,6 @@ +void script_1193(int arg0) { + if (((boolean)arg0) || ((boolean)mod(getClientCycle(), 50))) { + script_1194(); + } + return; +} diff --git a/dumps/scripts/1194.cs2 b/dumps/scripts/1194.cs2 new file mode 100644 index 0000000..eda9e62 --- /dev/null +++ b/dumps/scripts/1194.cs2 @@ -0,0 +1,17 @@ +void script_1194() { + int ivar0; + int ivar1; + if (globalint_1002 == -1) { + return; + } + ivar0 = subtract(extractX(globalint_1002), extractX(getMyPositionHash())); + if ((ivar0 > 10) || (ivar0 < -10)) { + return; + } + ivar1 = subtract(extractY(globalint_1002), extractY(getMyPositionHash())); + if ((ivar1 > 10) || (ivar1 < -10)) { + return; + } + cameraMethod5511(globalint_1002); + return; +} diff --git a/dumps/scripts/1195.cs2 b/dumps/scripts/1195.cs2 new file mode 100644 index 0000000..2979609 --- /dev/null +++ b/dumps/scripts/1195.cs2 @@ -0,0 +1,20 @@ +void script_1195() { + cs2method5405(0, 7); + cs2method5405(1, 7); + cs2method5406(0, 0, 46295015, 858, 46278629, 858, 0); + cs2method5406(1, 0, 46327781, 690, 46295013, 690, 0); + cs2method5406(0, 1, 46311394, 858, 46360545, 858, 0); + cs2method5406(1, 1, 46327780, 690, 46344164, 690, 0); + cs2method5406(0, 2, 46475237, 1400, 46573541, 1445, 0); + cs2method5406(1, 2, 46557155, 530, 46622690, 530, 0); + cs2method5406(0, 3, 46737378, 1075, 46786527, 830, 0); + cs2method5406(1, 3, 46786524, 290, 46819288, 290, 0); + cs2method5406(0, 4, 46770130, 875, 46770125, 885, 0); + cs2method5406(1, 4, 46819275, 410, 46819271, 410, 0); + cs2method5406(0, 5, 46852037, 915, 46901187, 905, 0); + cs2method5406(1, 5, 46950339, 585, 46983106, 695, 0); + cs2method5406(0, 6, 47081411, 900, 47130563, 835, 0); + cs2method5406(1, 6, 47130563, 750, 47163331, 740, 0); + script_1197(0); + return; +} diff --git a/dumps/scripts/1196.cs2 b/dumps/scripts/1196.cs2 new file mode 100644 index 0000000..a9940c9 --- /dev/null +++ b/dumps/scripts/1196.cs2 @@ -0,0 +1,6 @@ +void script_1196(int arg0,int arg1) { + if (getClientCycle() > add(arg1, 50)) { + script_1197(arg0); + } + return; +} diff --git a/dumps/scripts/1197.cs2 b/dumps/scripts/1197.cs2 new file mode 100644 index 0000000..7079286 --- /dev/null +++ b/dumps/scripts/1197.cs2 @@ -0,0 +1,16 @@ +void script_1197(int arg0) { + if (arg0 >= 6) { + return; + } + if (((boolean)arg0)) { + cameraMethod5502(0, arg0, 100, 400, 1, arg0); + setScriptCallOnMinimapRelatedSetting3(1196, add(arg0, 1), getClientCycle(), "ii", new WidgetPointer(888,0)); + } else if (arg0 == 5) { + cameraMethod5502(0, arg0, 400, 10, 1, arg0); + setScriptCallOnMinimapRelatedSetting3(1196, add(arg0, 1), getClientCycle(), "ii", new WidgetPointer(888,0)); + } else { + cameraMethod5502(0, arg0, 400, 400, 1, arg0); + setScriptCallOnMinimapRelatedSetting3(1196, add(arg0, 1), getClientCycle(), "ii", new WidgetPointer(888,0)); + } + return; +} diff --git a/dumps/scripts/1198.cs2 b/dumps/scripts/1198.cs2 new file mode 100644 index 0000000..93eeb37 --- /dev/null +++ b/dumps/scripts/1198.cs2 @@ -0,0 +1,38 @@ +void script_1198() { + if (((getItemAmtInContainer(93, 15249) > 0) || (getItemAmtInContainer(95, 15249) > 0)) || (bitconfig_6471 >= 44)) { + setWidgetIsHidden(true, new WidgetPointer(887,5)); + } else { + setWidgetIsHidden(false, new WidgetPointer(887,5)); + } + if ((getItemAmtInContainer(93, 15253) > 0) || (getItemAmtInContainer(95, 15253) > 0)) { + setWidgetIsHidden(true, new WidgetPointer(887,6)); + } else { + setWidgetIsHidden(false, new WidgetPointer(887,6)); + } + if (((getItemAmtInContainer(93, 15248) > 0) || (getItemAmtInContainer(95, 15248) > 0)) || (bitconfig_6471 == 42)) { + setWidgetIsHidden(true, new WidgetPointer(887,2)); + } else { + setWidgetIsHidden(false, new WidgetPointer(887,2)); + } + if ((getItemAmtInContainer(93, 15247) > 0) || (getItemAmtInContainer(95, 15247) > 0)) { + setWidgetIsHidden(true, new WidgetPointer(887,4)); + } else { + setWidgetIsHidden(false, new WidgetPointer(887,4)); + } + if ((((getItemAmtInContainer(93, 15251) > 0) || (getItemAmtInContainer(95, 15251) > 0)) || (bitconfig_6471 >= 52)) || ((boolean)bitconfig_6481)) { + setWidgetIsHidden(true, new WidgetPointer(887,8)); + } else { + setWidgetIsHidden(false, new WidgetPointer(887,8)); + } + if ((((getItemAmtInContainer(93, 15250) > 0) || (getItemAmtInContainer(95, 15250) > 0)) || (bitconfig_6471 >= 52)) || (bitconfig_6481 == 2)) { + setWidgetIsHidden(true, new WidgetPointer(887,7)); + } else { + setWidgetIsHidden(false, new WidgetPointer(887,7)); + } + if ((getItemAmtInContainer(93, 15252) > 0) || (getItemAmtInContainer(95, 15252) > 0)) { + setWidgetIsHidden(true, new WidgetPointer(887,3)); + } else { + setWidgetIsHidden(false, new WidgetPointer(887,3)); + } + return; +} diff --git a/dumps/scripts/1199.cs2 b/dumps/scripts/1199.cs2 new file mode 100644 index 0000000..73079ba --- /dev/null +++ b/dumps/scripts/1199.cs2 @@ -0,0 +1,13 @@ +void script_1199() { + switch (globalint_1401) { + case 0: + setWidgetRGB(new Color(255, 180, 0), new WidgetPointer(933,327)); + break; + case 1: + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(933,327)); + break; + case 2: + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(933,327)); + } + return; +} diff --git a/dumps/scripts/12.cs2 b/dumps/scripts/12.cs2 new file mode 100644 index 0000000..9f86f3a --- /dev/null +++ b/dumps/scripts/12.cs2 @@ -0,0 +1,55 @@ +cs2func_script_12_struct(1,1,0) script_12(int arg0) { + switch (arg0) { + case 1: + return newstruct cs2func_script_12_struct(15, "Attack"); + case 2: + return newstruct cs2func_script_12_struct(8, "Strength"); + case 5: + return newstruct cs2func_script_12_struct(15, "Defence"); + case 3: + return newstruct cs2func_script_12_struct(11, "Ranged"); + case 7: + return newstruct cs2func_script_12_struct(4, "Prayer"); + case 4: + return newstruct cs2func_script_12_struct(11, "Magic"); + case 6: + return newstruct cs2func_script_12_struct(3, "Constitution"); + case 8: + return newstruct cs2func_script_12_struct(10, "Agility"); + case 9: + return newstruct cs2func_script_12_struct(8, "Herblore"); + case 10: + return newstruct cs2func_script_12_struct(9, "Thieving"); + case 11: + return newstruct cs2func_script_12_struct(13, "Crafting"); + case 19: + return newstruct cs2func_script_12_struct(9, "Fletching"); + case 13: + return newstruct cs2func_script_12_struct(7, "Mining"); + case 14: + return newstruct cs2func_script_12_struct(16, "Smithing"); + case 15: + return newstruct cs2func_script_12_struct(8, "Fishing"); + case 16: + return newstruct cs2func_script_12_struct(16, "Cooking"); + case 17: + return newstruct cs2func_script_12_struct(9, "Firemaking"); + case 18: + return newstruct cs2func_script_12_struct(8, "Woodcutting"); + case 12: + return newstruct cs2func_script_12_struct(7, "Runecrafting"); + case 20: + return newstruct cs2func_script_12_struct(5, "Slayer"); + case 21: + return newstruct cs2func_script_12_struct(13, "Farming"); + case 22: + return newstruct cs2func_script_12_struct(16, "Construction"); + case 23: + return newstruct cs2func_script_12_struct(16, "Hunter"); + case 24: + return newstruct cs2func_script_12_struct(8, "Summoning"); + case 25: + return newstruct cs2func_script_12_struct(6, "Dungeoneering"); + } + return newstruct cs2func_script_12_struct(-1, ""); +} diff --git a/dumps/scripts/120.cs2 b/dumps/scripts/120.cs2 new file mode 100644 index 0000000..a3a2ee7 --- /dev/null +++ b/dumps/scripts/120.cs2 @@ -0,0 +1,8 @@ +void script_120(int arg0) { + int ivar1; + int ivar2; + ivar1 = add(rnd(25), 10); + ivar2 = add(rnd(25), 20); + setScriptCallOnGameloop(66, ivar1, ivar2, 0, new WidgetPointer(arg0), "iiiI", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1200.cs2 b/dumps/scripts/1200.cs2 new file mode 100644 index 0000000..9434aaa --- /dev/null +++ b/dumps/scripts/1200.cs2 @@ -0,0 +1,7 @@ +void script_1200(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + ivar4 = 100; + globalint_1186 = mod(add(globalint_1186, 1), 360); + setWidget3DRotation(cs2method2610(new WidgetPointer(arg0)), cs2method2611(new WidgetPointer(arg0)), arg1, mod(add(arg2, multiplyDivide(ivar4, 10000, cs2method_3408(105, 105, 3384, globalint_1186))), 2048), mod(add(arg3, multiplyDivide(ivar4, 10000, cs2method_3408(105, 105, 3385, globalint_1186))), 2048), getWidget3DDistance(new WidgetPointer(arg0)), new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1201.cs2 b/dumps/scripts/1201.cs2 new file mode 100644 index 0000000..8dd9ae7 --- /dev/null +++ b/dumps/scripts/1201.cs2 @@ -0,0 +1,5 @@ +void script_1201(int arg0,int arg1,int arg2,int arg3,int arg4) { + globalint_1186 = mod(add(globalint_1186, 1), 360); + setWidget3DRotation(cs2method2610(new WidgetPointer(arg0)), cs2method2611(new WidgetPointer(arg0)), arg1, mod(add(arg2, multiplyDivide(arg4, 10000, cs2method_3408(105, 105, 3384, globalint_1186))), 2048), mod(add(arg3, multiplyDivide(arg4, 10000, cs2method_3408(105, 105, 3385, globalint_1186))), 2048), getWidget3DDistance(new WidgetPointer(arg0)), new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1202.cs2 b/dumps/scripts/1202.cs2 new file mode 100644 index 0000000..f7760eb --- /dev/null +++ b/dumps/scripts/1202.cs2 @@ -0,0 +1,7 @@ +void script_1202(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + ivar4 = 100; + globalint_1186 = mod(add(globalint_1186, 1), 360); + setWidget3DRotation(cs2method2610(new WidgetPointer(arg0)), cs2method2611(new WidgetPointer(arg0)), arg1, mod(add(arg2, multiplyDivide(ivar4, 10000, cs2method_3408(105, 105, 3384, globalint_1186))), 2048), mod(add(arg3, multiplyDivide(ivar4, 10000, cs2method_3408(105, 105, 3385, globalint_1186))), 2048), getWidget3DDistance(new WidgetPointer(arg0)), new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1203.cs2 b/dumps/scripts/1203.cs2 new file mode 100644 index 0000000..8d9edd9 --- /dev/null +++ b/dumps/scripts/1203.cs2 @@ -0,0 +1,5 @@ +void script_1203(int arg0,int arg1,int arg2,int arg3,int arg4) { + globalint_1186 = mod(add(globalint_1186, 1), 360); + setWidget3DRotation(cs2method2610(new WidgetPointer(arg0)), cs2method2611(new WidgetPointer(arg0)), arg1, mod(add(arg2, multiplyDivide(arg4, 10000, cs2method_3408(105, 105, 3384, globalint_1186))), 2048), mod(add(arg3, multiplyDivide(arg4, 10000, cs2method_3408(105, 105, 3385, globalint_1186))), 2048), getWidget3DDistance(new WidgetPointer(arg0)), new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1204.cs2 b/dumps/scripts/1204.cs2 new file mode 100644 index 0000000..e9e7578 --- /dev/null +++ b/dumps/scripts/1204.cs2 @@ -0,0 +1,7 @@ +void script_1204(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + ivar4 = 100; + globalint_1186 = mod(add(globalint_1186, 1), 360); + setWidget3DRotation(cs2method2610(new WidgetPointer(arg0)), cs2method2611(new WidgetPointer(arg0)), arg1, mod(add(arg2, multiplyDivide(ivar4, 10000, cs2method_3408(105, 105, 3384, globalint_1186))), 2048), mod(add(arg3, multiplyDivide(ivar4, 10000, cs2method_3408(105, 105, 3385, globalint_1186))), 2048), getWidget3DDistance(new WidgetPointer(arg0)), new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1205.cs2 b/dumps/scripts/1205.cs2 new file mode 100644 index 0000000..f254407 --- /dev/null +++ b/dumps/scripts/1205.cs2 @@ -0,0 +1,4 @@ +void script_1205(int arg0,int arg1,int arg2,int arg3) { + script_1298(arg0, arg1, arg2, arg3); + return; +} diff --git a/dumps/scripts/1206.cs2 b/dumps/scripts/1206.cs2 new file mode 100644 index 0000000..898f27b --- /dev/null +++ b/dumps/scripts/1206.cs2 @@ -0,0 +1,5 @@ +void script_1206(int arg0,int arg1,int arg2,int arg3,int arg4) { + globalint_1186 = mod(add(globalint_1186, 1), 360); + setWidget3DRotation(cs2method2610(new WidgetPointer(arg0)), cs2method2611(new WidgetPointer(arg0)), arg1, mod(add(arg2, multiplyDivide(arg4, 10000, cs2method_3408(105, 105, 3384, globalint_1186))), 2048), mod(add(arg3, multiplyDivide(arg4, 10000, cs2method_3408(105, 105, 3385, globalint_1186))), 2048), getWidget3DDistance(new WidgetPointer(arg0)), new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1207.cs2 b/dumps/scripts/1207.cs2 new file mode 100644 index 0000000..a25c663 --- /dev/null +++ b/dumps/scripts/1207.cs2 @@ -0,0 +1,12 @@ +void script_1207(int arg0,int arg1) { + if (arg0 <= 11) { + setWidgetScrollMax(404, 215, new WidgetPointer(275,6)); + script_72(18022407, 18022406, 0); + } else if (((boolean)arg1)) { + script_72(18022407, 18022406, 0); + } else { + script_72(18022407, 18022406, subtract(multiply(arg0, 20), 180)); + } + setWidgetScrollMax(404, multiply(arg0, 20), new WidgetPointer(275,6)); + return; +} diff --git a/dumps/scripts/1208.cs2 b/dumps/scripts/1208.cs2 new file mode 100644 index 0000000..e4c1aca --- /dev/null +++ b/dumps/scripts/1208.cs2 @@ -0,0 +1,9 @@ +void script_1208(int arg0,int arg1,int arg2,int arg3) { + if (((boolean)arg3)) { + setWidgetScrollMax(0, add(arg2, getWidgetActualHeight(new WidgetPointer(arg1))), new WidgetPointer(arg1)); + } else { + setWidgetScrollMax(0, arg2, new WidgetPointer(arg1)); + } + script_72(arg0, arg1, cs2method2601(new WidgetPointer(arg1))); + return; +} diff --git a/dumps/scripts/1209.cs2 b/dumps/scripts/1209.cs2 new file mode 100644 index 0000000..1eba003 --- /dev/null +++ b/dumps/scripts/1209.cs2 @@ -0,0 +1,5 @@ +void script_1209(int arg0,int arg1) { + script_1540(arg0); + script_2739(arg1, -1); + return; +} diff --git a/dumps/scripts/121.cs2 b/dumps/scripts/121.cs2 new file mode 100644 index 0000000..61fb6b8 --- /dev/null +++ b/dumps/scripts/121.cs2 @@ -0,0 +1,44 @@ +int script_121(int arg0) { + if (getDisplayMode() >= 2) { + return script_1742(arg0); + } + switch (arg0) { + case 0: + return 35913866; + case 1: + return 35913867; + case 2: + return 35913868; + case 3: + return 35913869; + case 4: + return 35913870; + case 5: + return 35913871; + case 6: + return 35913872; + case 7: + return 35913873; + case 8: + return 35913835; + case 9: + return 35913836; + case 10: + return 35913837; + case 11: + return 35913838; + case 12: + return 35913839; + case 13: + return 35913840; + case 14: + return 35913841; + case 15: + return 35913842; + case 95: + return 48955400; + case 99: + return 35913910; + } + return -1; +} diff --git a/dumps/scripts/1210.cs2 b/dumps/scripts/1210.cs2 new file mode 100644 index 0000000..d6cede8 --- /dev/null +++ b/dumps/scripts/1210.cs2 @@ -0,0 +1,15 @@ +int script_1210(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + int ivar6; + ivar4 = mod(subtract(add(getClientCycle(), arg3), arg2), arg1); + ivar5 = divide(arg1, 2); + ivar6 = subtract(ivar5, ivar4); + if (((boolean)ivar6)) { + return arg0; + } + if (ivar6 > 0) { + return subtract(arg0, multiplyDivide(ivar6, ivar5, arg0)); + } + return add(arg0, multiplyDivide(ivar6, ivar5, arg0)); +} diff --git a/dumps/scripts/1211.cs2 b/dumps/scripts/1211.cs2 new file mode 100644 index 0000000..cbd216e --- /dev/null +++ b/dumps/scripts/1211.cs2 @@ -0,0 +1,5 @@ +void script_1211() { + setScriptCallOnGameloop(1213, "", new WidgetPointer(894,5)); + setWidgetIsHidden(false, new WidgetPointer(894,7)); + return; +} diff --git a/dumps/scripts/1212.cs2 b/dumps/scripts/1212.cs2 new file mode 100644 index 0000000..29531bc --- /dev/null +++ b/dumps/scripts/1212.cs2 @@ -0,0 +1,4 @@ +void script_1212() { + script_948(); + return; +} diff --git a/dumps/scripts/1213.cs2 b/dumps/scripts/1213.cs2 new file mode 100644 index 0000000..0ef4e8a --- /dev/null +++ b/dumps/scripts/1213.cs2 @@ -0,0 +1,12 @@ +void script_1213() { + if (script_1305() == 7) { + setWidgetText(new WidgetPointer(894,7), "To cast Wind Strike, click on the flashing spell icon, then click on a chicken. You can hover over spell icons to read a brief description of the spell and the runes required to cast it."); + setWidgetText(new WidgetPointer(894,6), ""); + setWidgetSprite(15, new WidgetPointer(894,4)); + } else { + setWidgetText(new WidgetPointer(894,7), "Click on the Magic icon to open your magic spellbook."); + setWidgetText(new WidgetPointer(894,6), ""); + setWidgetSprite(1824, new WidgetPointer(894,4)); + } + return; +} diff --git a/dumps/scripts/1214.cs2 b/dumps/scripts/1214.cs2 new file mode 100644 index 0000000..477ac77 --- /dev/null +++ b/dumps/scripts/1214.cs2 @@ -0,0 +1,4 @@ +void script_1214(int arg0,int arg1,int arg2,int arg3) { + script_2005(arg0, arg1, arg2, arg3); + return; +} diff --git a/dumps/scripts/1215.cs2 b/dumps/scripts/1215.cs2 new file mode 100644 index 0000000..022f248 --- /dev/null +++ b/dumps/scripts/1215.cs2 @@ -0,0 +1,27 @@ +void script_1215(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + ivar4 = max(subtract(getWidgetActualWidth(new WidgetPointer(arg0)), getWidgetActualWidth(new WidgetPointer(arg1))), 1); + arg2 = min(max(arg2, 0), ivar4); + switch (arg3) { + case 0: + cs2method6018(multiplyDivide(arg2, ivar4, 127)); + script_1217(arg0, arg1); + break; + case 1: + cs2method6019(multiplyDivide(arg2, ivar4, 255)); + script_1216(arg0, arg1); + break; + case 2: + cs2method6020(multiplyDivide(arg2, ivar4, 127)); + script_1218(arg0, arg1); + break; + case 3: + cs2method6001(add(min(multiplyDivide(arg2, ivar4, 4), 3), 1)); + script_1185(arg0, arg1); + break; + case 4: + cs2method6038(multiplyDivide(arg2, ivar4, 255)); + script_2007(arg0, arg1, 1, 1); + } + return; +} diff --git a/dumps/scripts/1216.cs2 b/dumps/scripts/1216.cs2 new file mode 100644 index 0000000..0861ade --- /dev/null +++ b/dumps/scripts/1216.cs2 @@ -0,0 +1,9 @@ +void script_1216(int arg0,int arg1) { + int ivar2; + int ivar3; + cs2method2301(arg0, -1, new WidgetPointer(arg1)); + ivar2 = subtract(getWidgetActualWidth(new WidgetPointer(arg0)), getWidgetActualWidth(new WidgetPointer(arg1))); + ivar3 = multiplyDivide(cs2method6119(), 255, ivar2); + setWidgetPosition(ivar3, 0, 0, 0, new WidgetPointer(arg1)); + return; +} diff --git a/dumps/scripts/1217.cs2 b/dumps/scripts/1217.cs2 new file mode 100644 index 0000000..f08087a --- /dev/null +++ b/dumps/scripts/1217.cs2 @@ -0,0 +1,9 @@ +void script_1217(int arg0,int arg1) { + int ivar2; + int ivar3; + cs2method2301(arg0, -1, new WidgetPointer(arg1)); + ivar2 = subtract(getWidgetActualWidth(new WidgetPointer(arg0)), getWidgetActualWidth(new WidgetPointer(arg1))); + ivar3 = multiplyDivide(cs2method6118(), 127, ivar2); + setWidgetPosition(ivar3, 0, 0, 0, new WidgetPointer(arg1)); + return; +} diff --git a/dumps/scripts/1218.cs2 b/dumps/scripts/1218.cs2 new file mode 100644 index 0000000..3f9fa25 --- /dev/null +++ b/dumps/scripts/1218.cs2 @@ -0,0 +1,9 @@ +void script_1218(int arg0,int arg1) { + int ivar2; + int ivar3; + cs2method2301(arg0, -1, new WidgetPointer(arg1)); + ivar2 = subtract(getWidgetActualWidth(new WidgetPointer(arg0)), getWidgetActualWidth(new WidgetPointer(arg1))); + ivar3 = multiplyDivide(cs2method6120(), 127, ivar2); + setWidgetPosition(ivar3, 0, 0, 0, new WidgetPointer(arg1)); + return; +} diff --git a/dumps/scripts/1219.cs2 b/dumps/scripts/1219.cs2 new file mode 100644 index 0000000..3a6404d --- /dev/null +++ b/dumps/scripts/1219.cs2 @@ -0,0 +1,5 @@ +void script_1219(int arg0,int arg1,int arg2) { + cs2method6017(((boolean)arg0)); + script_1220(arg1, arg2); + return; +} diff --git a/dumps/scripts/122.cs2 b/dumps/scripts/122.cs2 new file mode 100644 index 0000000..8bf91e8 --- /dev/null +++ b/dumps/scripts/122.cs2 @@ -0,0 +1,11 @@ +void script_122(int arg0) { + int ivar1; + ivar1 = 0; + ivar1 = mod(getClientCycle(), 100); + if (ivar1 > 50) { + ivar1 = subtract(100, ivar1); + } + ivar1 = subtract(255, ivar1); + cs2method2103(ivar1, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1220.cs2 b/dumps/scripts/1220.cs2 new file mode 100644 index 0000000..c24a256 --- /dev/null +++ b/dumps/scripts/1220.cs2 @@ -0,0 +1,10 @@ +void script_1220(int arg0,int arg1) { + if (cs2method6117()) { + setWidgetSprite(4086, new WidgetPointer(arg1)); + setWidgetSprite(4084, new WidgetPointer(arg0)); + } else { + setWidgetSprite(4086, new WidgetPointer(arg0)); + setWidgetSprite(4084, new WidgetPointer(arg1)); + } + return; +} diff --git a/dumps/scripts/1221.cs2 b/dumps/scripts/1221.cs2 new file mode 100644 index 0000000..04344d8 --- /dev/null +++ b/dumps/scripts/1221.cs2 @@ -0,0 +1,178 @@ +void script_1221(int arg0,int arg1) { + int ivar2; + int stack_dump0; + int stack_dump1; + int stack_dump2; + int stack_dump3; + string stack_dump4; + cs2func_script_802_struct(1,1,0) structdump_5; + cs2func_script_802_struct(1,1,0) structdump_6; + if (globalint_174 == 11) { + return; + } + ivar2 = script_2948(); + switch (globalint_174) { + flow_3: + case 12: + if (arg0 == 13) { + script_2936(0); + return; + } + return; + case 2: + switch (ivar2) { + case 21: + case 1: + case -3: + return; + } + if (arg0 == 13) { + script_1174(11); + return; + } + return; + case 3: + switch (ivar2) { + case 21: + case 1: + case -3: + return; + } + switch (arg0) { + case 13: + script_1174(11); + return; + case 84: + case 80: + if (globalint_175 >= getClientCycle()) { + return; + } + globalint_174 = 4; + globalint_175 = getClientCycle(); + globalint_1099 = strLength(script_2949(globalstring_33)); + script_3237(39059534, 39059535, 39059536, 4, script_2949(globalstring_33)); + return; + case 102: + case 103: + case 98: + case 99: + case 96: + case 97: + globalint_1099 = script_1553(arg0, globalint_1099, globalstring_32); + script_3237(39059528, 39059529, 39059530, 3, globalstring_32); + return; + } + IF ((strLength(globalstring_32) >= 320) && (arg0 != 85)) + GOTO flow_21 + GOTO flow_22 + flow_21: + IF (arg0 != 101) + GOTO flow_23 + flow_22: + IF (((boolean)strLength(strRemoveEntities(concatChar(((char)arg1), ""))))) + GOTO flow_23 + GOTO flow_24 + flow_23: + return; + flow_24: + stack_dump0 = globalint_1099; + stack_dump1 = 0; + stack_dump2 = arg0; + stack_dump3 = arg1; + stack_dump4 = globalstring_32; + structdump_5 = script_802(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + stack_dump4 = structdump_5.stringpart_0; + globalint_1099 = structdump_5.intpart_0; + globalstring_32 = stack_dump4; + setWidgetText(new WidgetPointer(596,73), globalstring_32); + script_3237(39059528, 39059529, 39059530, 3, globalstring_32); + return; + case 4: + switch (ivar2) { + case 21: + case 1: + case -3: + return; + } + switch (arg0) { + case 13: + script_1174(11); + return; + case 84: + case 80: + if (globalint_175 >= getClientCycle()) { + return; + } + if ((arg0 == 84) && (strLength(globalstring_32) > 0)) { + script_2945(); + return; + } + globalint_174 = 3; + globalint_175 = getClientCycle(); + globalint_1099 = strLength(globalstring_32); + script_3237(39059528, 39059529, 39059530, 3, globalstring_32); + return; + case 102: + case 103: + case 98: + case 99: + case 96: + case 97: + globalint_1099 = script_1553(arg0, globalint_1099, script_2949(globalstring_33)); + script_3237(39059534, 39059535, 39059536, 4, script_2949(globalstring_33)); + return; + } + if (((strLength(globalstring_33) >= 20) && (arg0 != 85)) && (arg0 != 101)) { + return; + } + stack_dump0 = globalint_1099; + stack_dump1 = 0; + stack_dump2 = arg0; + stack_dump3 = arg1; + stack_dump4 = globalstring_33; + structdump_6 = script_802(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + stack_dump4 = structdump_6.stringpart_0; + globalint_1099 = structdump_6.intpart_0; + globalstring_33 = stack_dump4; + setWidgetText(new WidgetPointer(596,79), script_2949(globalstring_33)); + script_3237(39059534, 39059535, 39059536, 4, script_2949(globalstring_33)); + return; + case 5: + switch (ivar2) { + case -3: + case 1: + return; + } + if ((ivar2 == 21) && (arg0 == 13)) { + script_3235(); + return; + } + if (arg0 == 13) { + script_2954(); + return; + } + return; + case 10: + script_2222(arg0); + return; + case 6: + case 7: + case 8: + case 14: + case 15: + script_3216(arg0, arg1); + return; + case 13: + if (arg0 == 13) { + script_1174(globalint_1091); + return; + } + return; + case 17: + if (arg0 == 84) { + script_2206(); + } + return; + } + return; +} diff --git a/dumps/scripts/1222.cs2 b/dumps/scripts/1222.cs2 new file mode 100644 index 0000000..7fa3926 --- /dev/null +++ b/dumps/scripts/1222.cs2 @@ -0,0 +1,5 @@ +void script_1222() { + setScriptCallOnGameloop(1329, "", new WidgetPointer(894,5)); + setWidgetIsHidden(false, new WidgetPointer(894,7)); + return; +} diff --git a/dumps/scripts/1223.cs2 b/dumps/scripts/1223.cs2 new file mode 100644 index 0000000..e541d46 --- /dev/null +++ b/dumps/scripts/1223.cs2 @@ -0,0 +1,34 @@ +void script_1223() { + if (IsFemale()) { + setWidgetIsHidden(false, new WidgetPointer(308,20)); + setWidgetIsHidden(false, new WidgetPointer(308,22)); + setWidgetIsHidden(false, new WidgetPointer(308,24)); + setWidgetIsHidden(false, new WidgetPointer(308,26)); + setWidgetIsHidden(false, new WidgetPointer(308,28)); + setWidgetIsHidden(false, new WidgetPointer(308,30)); + setWidgetIsHidden(false, new WidgetPointer(308,32)); + setWidgetIsHidden(true, new WidgetPointer(308,19)); + setWidgetIsHidden(true, new WidgetPointer(308,21)); + setWidgetIsHidden(true, new WidgetPointer(308,23)); + setWidgetIsHidden(true, new WidgetPointer(308,25)); + setWidgetIsHidden(true, new WidgetPointer(308,27)); + setWidgetIsHidden(true, new WidgetPointer(308,29)); + setWidgetIsHidden(true, new WidgetPointer(308,31)); + } else { + setWidgetIsHidden(true, new WidgetPointer(308,20)); + setWidgetIsHidden(true, new WidgetPointer(308,22)); + setWidgetIsHidden(true, new WidgetPointer(308,24)); + setWidgetIsHidden(true, new WidgetPointer(308,26)); + setWidgetIsHidden(true, new WidgetPointer(308,28)); + setWidgetIsHidden(true, new WidgetPointer(308,30)); + setWidgetIsHidden(true, new WidgetPointer(308,32)); + setWidgetIsHidden(false, new WidgetPointer(308,19)); + setWidgetIsHidden(false, new WidgetPointer(308,21)); + setWidgetIsHidden(false, new WidgetPointer(308,23)); + setWidgetIsHidden(false, new WidgetPointer(308,25)); + setWidgetIsHidden(false, new WidgetPointer(308,27)); + setWidgetIsHidden(false, new WidgetPointer(308,29)); + setWidgetIsHidden(false, new WidgetPointer(308,31)); + } + return; +} diff --git a/dumps/scripts/1224.cs2 b/dumps/scripts/1224.cs2 new file mode 100644 index 0000000..82105b4 --- /dev/null +++ b/dumps/scripts/1224.cs2 @@ -0,0 +1,4 @@ +void script_1224(int arg0) { + script_1226(arg0); + return; +} diff --git a/dumps/scripts/1225.cs2 b/dumps/scripts/1225.cs2 new file mode 100644 index 0000000..589521a --- /dev/null +++ b/dumps/scripts/1225.cs2 @@ -0,0 +1,4 @@ +void script_1225() { + script_1226(bitconfig_5939); + return; +} diff --git a/dumps/scripts/1226.cs2 b/dumps/scripts/1226.cs2 new file mode 100644 index 0000000..17f421d --- /dev/null +++ b/dumps/scripts/1226.cs2 @@ -0,0 +1,116 @@ +void script_1226(int arg0) { + setWidgetIsHidden(true, new WidgetPointer(308,15)); + setWidgetIsHidden(true, new WidgetPointer(308,14)); + setWidgetSprite(1134, new WidgetPointer(308,35)); + setWidgetIsHidden(true, new WidgetPointer(308,13)); + setWidgetIsHidden(true, new WidgetPointer(308,12)); + setWidgetSprite(1134, new WidgetPointer(308,34)); + setWidgetIsHidden(true, new WidgetPointer(308,11)); + setWidgetIsHidden(true, new WidgetPointer(308,10)); + setWidgetSprite(1134, new WidgetPointer(308,33)); + setWidgetIsHidden(true, new WidgetPointer(308,9)); + setWidgetIsHidden(true, new WidgetPointer(308,8)); + setWidgetSprite(1134, new WidgetPointer(308,39)); + setWidgetIsHidden(true, new WidgetPointer(308,7)); + setWidgetIsHidden(true, new WidgetPointer(308,6)); + setWidgetSprite(1134, new WidgetPointer(308,37)); + setWidgetIsHidden(true, new WidgetPointer(308,5)); + setWidgetIsHidden(true, new WidgetPointer(308,4)); + setWidgetSprite(1134, new WidgetPointer(308,36)); + setWidgetIsHidden(true, new WidgetPointer(308,3)); + setWidgetIsHidden(true, new WidgetPointer(308,2)); + setWidgetSprite(1134, new WidgetPointer(308,38)); + if (IsFemale()) { + switch (arg0) { + case 0: + setWidgetIsHidden(false, new WidgetPointer(308,15)); + setWidgetSprite(1135, new WidgetPointer(308,35)); + break; + case 1: + setWidgetIsHidden(false, new WidgetPointer(308,13)); + setWidgetSprite(1135, new WidgetPointer(308,34)); + break; + case 2: + setWidgetIsHidden(false, new WidgetPointer(308,11)); + setWidgetSprite(1135, new WidgetPointer(308,33)); + break; + case 3: + setWidgetIsHidden(false, new WidgetPointer(308,9)); + setWidgetSprite(1135, new WidgetPointer(308,39)); + break; + case 4: + setWidgetIsHidden(false, new WidgetPointer(308,7)); + setWidgetSprite(1135, new WidgetPointer(308,37)); + break; + case 5: + setWidgetIsHidden(false, new WidgetPointer(308,5)); + setWidgetSprite(1135, new WidgetPointer(308,36)); + break; + case 6: + setWidgetIsHidden(false, new WidgetPointer(308,3)); + setWidgetSprite(1135, new WidgetPointer(308,38)); + } + } else { + switch (arg0) { + case 0: + setWidgetIsHidden(false, new WidgetPointer(308,14)); + setWidgetSprite(1135, new WidgetPointer(308,35)); + break; + case 1: + setWidgetIsHidden(false, new WidgetPointer(308,12)); + setWidgetSprite(1135, new WidgetPointer(308,34)); + break; + case 2: + setWidgetIsHidden(false, new WidgetPointer(308,10)); + setWidgetSprite(1135, new WidgetPointer(308,33)); + break; + case 3: + setWidgetIsHidden(false, new WidgetPointer(308,8)); + setWidgetSprite(1135, new WidgetPointer(308,39)); + break; + case 4: + setWidgetIsHidden(false, new WidgetPointer(308,6)); + setWidgetSprite(1135, new WidgetPointer(308,37)); + break; + case 5: + setWidgetIsHidden(false, new WidgetPointer(308,4)); + setWidgetSprite(1135, new WidgetPointer(308,36)); + break; + case 6: + setWidgetIsHidden(false, new WidgetPointer(308,2)); + setWidgetSprite(1135, new WidgetPointer(308,38)); + } + } + if (IsFemale()) { + setWidgetIsHidden(false, new WidgetPointer(308,20)); + setWidgetIsHidden(false, new WidgetPointer(308,22)); + setWidgetIsHidden(false, new WidgetPointer(308,24)); + setWidgetIsHidden(false, new WidgetPointer(308,26)); + setWidgetIsHidden(false, new WidgetPointer(308,28)); + setWidgetIsHidden(false, new WidgetPointer(308,30)); + setWidgetIsHidden(false, new WidgetPointer(308,32)); + setWidgetIsHidden(true, new WidgetPointer(308,19)); + setWidgetIsHidden(true, new WidgetPointer(308,21)); + setWidgetIsHidden(true, new WidgetPointer(308,23)); + setWidgetIsHidden(true, new WidgetPointer(308,25)); + setWidgetIsHidden(true, new WidgetPointer(308,27)); + setWidgetIsHidden(true, new WidgetPointer(308,29)); + setWidgetIsHidden(true, new WidgetPointer(308,31)); + } else { + setWidgetIsHidden(true, new WidgetPointer(308,20)); + setWidgetIsHidden(true, new WidgetPointer(308,22)); + setWidgetIsHidden(true, new WidgetPointer(308,24)); + setWidgetIsHidden(true, new WidgetPointer(308,26)); + setWidgetIsHidden(true, new WidgetPointer(308,28)); + setWidgetIsHidden(true, new WidgetPointer(308,30)); + setWidgetIsHidden(true, new WidgetPointer(308,32)); + setWidgetIsHidden(false, new WidgetPointer(308,19)); + setWidgetIsHidden(false, new WidgetPointer(308,21)); + setWidgetIsHidden(false, new WidgetPointer(308,23)); + setWidgetIsHidden(false, new WidgetPointer(308,25)); + setWidgetIsHidden(false, new WidgetPointer(308,27)); + setWidgetIsHidden(false, new WidgetPointer(308,29)); + setWidgetIsHidden(false, new WidgetPointer(308,31)); + } + return; +} diff --git a/dumps/scripts/1227.cs2 b/dumps/scripts/1227.cs2 new file mode 100644 index 0000000..ca2494a --- /dev/null +++ b/dumps/scripts/1227.cs2 @@ -0,0 +1,22 @@ +void script_1227(int arg0,int arg1,int arg2) { + int ivar3; + if ((bitconfig_1549 < 1) || (bitconfig_1549 > 63)) { + setWidgetIsHidden(true, new WidgetPointer(arg1)); + setWidgetIsHidden(true, new WidgetPointer(arg2)); + return; + } + if (bitconfig_1549 == 63) { + setWidgetText(new WidgetPointer(arg2), "Final" + "
" + "Challenge"); + } else { + setWidgetText(new WidgetPointer(arg2), "Wave " + intToStr(bitconfig_1549)); + } + ivar3 = subtract(0, getWidgetActualHeight(new WidgetPointer(arg0))); + setWidgetPosition(0, ivar3, 1, 1, new WidgetPointer(arg1)); + setWidgetPosition(0, ivar3, 1, 1, new WidgetPointer(arg2)); + setWidgetIsHidden(false, new WidgetPointer(arg1)); + setWidgetIsHidden(false, new WidgetPointer(arg2)); + setScriptCallOnGameloop(1228, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), getClientCycle(), "IIIi", new WidgetPointer(arg0)); + setWidgetContextMenuOption(1, new WidgetPointer(arg1), "Dismiss"); + setScriptCallOnClickContextMenu(1229, -2147483644, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), "iIII", new WidgetPointer(arg1)); + return; +} diff --git a/dumps/scripts/1228.cs2 b/dumps/scripts/1228.cs2 new file mode 100644 index 0000000..8b325ca --- /dev/null +++ b/dumps/scripts/1228.cs2 @@ -0,0 +1,35 @@ +void script_1228(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + int ivar6; + ivar4 = getWidgetActualHeight(new WidgetPointer(arg0)); + ivar5 = subtract(getClientCycle(), arg3); + ivar6 = 0; + if (ivar5 <= 30) { + if (ivar5 == 5) { + playSoundEffect(2871, 1, 0); + } + ivar6 = subtract(multiplyDivide(ivar5, 30, ivar4), ivar4); + setWidgetPosition(0, ivar6, 1, 1, new WidgetPointer(arg1)); + setWidgetPosition(0, ivar6, 1, 1, new WidgetPointer(arg2)); + return; + } + if (ivar5 < 170) { + return; + } + if (ivar5 < 200) { + if (ivar5 == 170) { + playSoundEffect(2871, 1, 0); + } + ivar6 = subtract(0, multiplyDivide(subtract(ivar5, 170), 30, ivar4)); + setWidgetPosition(0, ivar6, 1, 1, new WidgetPointer(arg1)); + setWidgetPosition(0, ivar6, 1, 1, new WidgetPointer(arg2)); + return; + } + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + setWidgetNoOptions(new WidgetPointer(arg1)); + setWidgetIsHidden(true, new WidgetPointer(arg1)); + setWidgetIsHidden(true, new WidgetPointer(arg2)); + setWidgetIsHidden(true, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1229.cs2 b/dumps/scripts/1229.cs2 new file mode 100644 index 0000000..31ccdcd --- /dev/null +++ b/dumps/scripts/1229.cs2 @@ -0,0 +1,12 @@ +void script_1229(int arg0,int arg1,int arg2,int arg3) { + if (arg0 != 1) { + return; + } + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(arg2)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg1)); + setWidgetNoOptions(new WidgetPointer(arg2)); + setWidgetIsHidden(true, new WidgetPointer(arg2)); + setWidgetIsHidden(true, new WidgetPointer(arg3)); + setWidgetIsHidden(true, new WidgetPointer(arg1)); + return; +} diff --git a/dumps/scripts/123.cs2 b/dumps/scripts/123.cs2 new file mode 100644 index 0000000..9570999 --- /dev/null +++ b/dumps/scripts/123.cs2 @@ -0,0 +1,4 @@ +void script_123() { + script_4552(); + return; +} diff --git a/dumps/scripts/1230.cs2 b/dumps/scripts/1230.cs2 new file mode 100644 index 0000000..fddad32 --- /dev/null +++ b/dumps/scripts/1230.cs2 @@ -0,0 +1,56 @@ +void script_1230() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + ivar0 = -1; + ivar1 = -1; + ivar2 = -1; + ivar3 = 0; + while (ivar3 < 16) { + flow_1: + ivar0 = getItemIdInSlot(308, ivar3); + switch (ivar0) { + case 6422: + case 556: + ivar1 = 8975; + break; + case 6424: + case 555: + ivar1 = 8987; + break; + case 6426: + case 557: + ivar1 = 8979; + break; + case 554: + case 6428: + ivar1 = 8980; + break; + default: + ivar1 = -1; + } + ivar2 = ((int)cs2method_3408(105, 73, 2273, ivar3)); + IF (setWidgetRegister(new WidgetPointer(ivar2))) + GOTO flow_9 + GOTO flow_10 + flow_9: + setWidgetModel(ivar1); + GOTO flow_10 + flow_10: + IF (((((ivar0 == 6422) || (ivar0 == 6422)) || (ivar0 == 6424)) || (ivar0 == 6426)) || (ivar0 == 6428)) + GOTO flow_11 + GOTO flow_13 + flow_11: + ivar2 = ((int)cs2method_3408(105, 73, 2276, ivar3)); + IF (setWidgetRegister(new WidgetPointer(ivar2))) + GOTO flow_12 + GOTO flow_13 + flow_12: + setWidgetRGB(new Color(68, 0, 0)); + GOTO flow_13 + flow_13: + ivar3 = add(ivar3, 1); + } + return; +} diff --git a/dumps/scripts/1231.cs2 b/dumps/scripts/1231.cs2 new file mode 100644 index 0000000..aed35ce --- /dev/null +++ b/dumps/scripts/1231.cs2 @@ -0,0 +1,76 @@ +void script_1231() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + ivar0 = -1; + ivar1 = -1; + ivar2 = -1; + ivar3 = 0; + while (ivar3 < 81) { + flow_1: + ivar0 = getItemIdInSlot(308, ivar3); + switch (ivar0) { + case 556: + case 6422: + ivar1 = 8975; + break; + case 555: + case 6424: + ivar1 = 8987; + break; + case 557: + case 6426: + ivar1 = 8979; + break; + case 554: + case 6428: + ivar1 = 8980; + break; + case 6436: + case 558: + ivar1 = 8982; + break; + case 6438: + case 559: + ivar1 = 8976; + break; + case 6432: + case 560: + ivar1 = 8978; + break; + case 562: + case 6430: + ivar1 = 8977; + break; + case 6434: + case 563: + ivar1 = 8981; + break; + default: + ivar1 = -1; + } + ivar2 = ((int)cs2method_3408(105, 73, 2274, ivar3)); + IF (setWidgetRegister(new WidgetPointer(ivar2))) + GOTO flow_14 + GOTO flow_15 + flow_14: + setWidgetModel(ivar1); + GOTO flow_15 + flow_15: + IF ((((((((((ivar0 == 6422) || (ivar0 == 6422)) || (ivar0 == 6424)) || (ivar0 == 6426)) || (ivar0 == 6428)) || (ivar0 == 6436)) || (ivar0 == 6438)) || (ivar0 == 6432)) || (ivar0 == 6430)) || (ivar0 == 6434)) + GOTO flow_16 + GOTO flow_18 + flow_16: + ivar2 = ((int)cs2method_3408(105, 73, 2275, ivar3)); + IF (setWidgetRegister(new WidgetPointer(ivar2))) + GOTO flow_17 + GOTO flow_18 + flow_17: + setWidgetRGB(new Color(68, 0, 0)); + GOTO flow_18 + flow_18: + ivar3 = add(ivar3, 1); + } + return; +} diff --git a/dumps/scripts/1232.cs2 b/dumps/scripts/1232.cs2 new file mode 100644 index 0000000..d7fc0d9 --- /dev/null +++ b/dumps/scripts/1232.cs2 @@ -0,0 +1,32 @@ +void script_1232(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg2)), add(multiply(getLineCount(getWidgetActualWidth(new WidgetPointer(arg2)), 494, getWidgetText(new WidgetPointer(arg2))), 12), 3), 0, 0, new WidgetPointer(arg2)); + deleteAllExtraChilds(new WidgetPointer(arg0)); + ivar3 = divide(subtract(getWidgetActualWidth(new WidgetPointer(arg0)), multiply(36, 8)), 7); + ivar4 = divide(subtract(getWidgetActualHeight(new WidgetPointer(arg0)), multiply(32, 5)), 4); + ivar5 = 0; + while (ivar5 < getItemContainerLength(0)) { + createExtraChild(new WidgetPointer(arg0), 5, ivar5); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(multiply(add(36, ivar3), mod(ivar5, 8)), multiply(divide(ivar5, 8), add(32, ivar4)), 0, 0); + setWidgetHidden(0); + if (getItemIdInSlot(0, ivar5) != -1) { + setItemOnWidgetMethod1200(getItemIdInSlot(0, ivar5), getItemAmtInSlot(0, ivar5)); + cs2method1305("" + getItemName(getItemIdInSlot(0, ivar5))); + setWidgetContextMenuOption(1, "Withdraw" + ""); + setWidgetContextMenuOption(2, "Withdraw-All" + ""); + setWidgetContextMenuOption(10, "Examine" + ""); + cs2method1303(5); + cs2method1304(10); + setWidgetShadowColor(new Color(51, 51, 51)); + setWidgetBorderThickness(1); + setScriptCallOnMouseDragReleased(1233, new WidgetPointer(arg0), -2147483643, new WidgetPointer(-32768,6), -2147483641, new WidgetPointer(arg1), new WidgetPointer(arg2), "IiIiII"); + } else { + setItemOnWidgetMethod1205(-1, 0); + } + ivar5 = add(ivar5, 1); + } + return; +} diff --git a/dumps/scripts/1233.cs2 b/dumps/scripts/1233.cs2 new file mode 100644 index 0000000..3affd7d --- /dev/null +++ b/dumps/scripts/1233.cs2 @@ -0,0 +1,25 @@ +void script_1233(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + int ivar6; + int ivar7; + int stack_dump0; + ivar6 = 0; + ivar7 = 0; + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + if (arg2 == arg0) { + if (setWidgetRegister(new WidgetPointer(arg2), arg3)) { + stack_dump0 = getWidgetActualX(); + ivar7 = getWidgetActualY(); + ivar6 = stack_dump0; + setWidgetPosition(getWidgetActualX(), getWidgetActualY(), 0, 0); + setWidgetPosition(ivar6, ivar7, 0, 0); + } + return; + } + if ((arg2 == arg4) || (arg2 == arg5)) { + setWidgetHidden(1); + return; + } + setWidgetPosition(getWidgetActualX(), getWidgetActualY(), 0, 0); + } + return; +} diff --git a/dumps/scripts/1234.cs2 b/dumps/scripts/1234.cs2 new file mode 100644 index 0000000..ef7ca28 --- /dev/null +++ b/dumps/scripts/1234.cs2 @@ -0,0 +1,21 @@ +void script_1234(int arg0) { + if (isHoldingCtrl()) { + return; + } + if (globalint_173 != 1) { + switch (arg0) { + case 1: + cs2method5507(); + break; + case 2: + cs2method5508(); + break; + case 3: + cs2method5509(); + break; + case 4: + cs2method5510(); + } + } + return; +} diff --git a/dumps/scripts/1235.cs2 b/dumps/scripts/1235.cs2 new file mode 100644 index 0000000..9359e33 --- /dev/null +++ b/dumps/scripts/1235.cs2 @@ -0,0 +1,26 @@ +void script_1235(int arg0) { + setWidgetIsHidden(false, new WidgetPointer(181,1)); + switch (globalint_180) { + case 1: + setWidget3DRotation(0, 0, 510, 762, 0, 410, new WidgetPointer(arg0)); + break; + case 2: + setWidget3DRotation(0, 0, 514, 1241, 0, 410, new WidgetPointer(arg0)); + break; + case 3: + setWidget3DRotation(0, 0, 512, 1536, 1250, 410, new WidgetPointer(arg0)); + break; + case 4: + setWidget3DRotation(0, 0, 512, 0, 1250, 410, new WidgetPointer(arg0)); + break; + case 5: + setWidget3DRotation(0, 0, 512, 512, 1250, 410, new WidgetPointer(arg0)); + break; + case 6: + setWidget3DRotation(0, 0, 512, 1024, 1250, 410, new WidgetPointer(arg0)); + break; + default: + setWidgetIsHidden(true, new WidgetPointer(181,1)); + } + return; +} diff --git a/dumps/scripts/1236.cs2 b/dumps/scripts/1236.cs2 new file mode 100644 index 0000000..77fba73 --- /dev/null +++ b/dumps/scripts/1236.cs2 @@ -0,0 +1,9 @@ +void script_1236() { + globalint_1063 = -1; + setScriptCallOnConfigChange(1716, 1584, 1, "Y", new WidgetPointer(271,8)); + setScriptCallOnSkillChange(1705, 0, 2, 1, 4, 6, 5, "Y", new WidgetPointer(271,8)); + script_1717(); + deleteAllExtraChilds(new WidgetPointer(271,6)); + script_1704(); + return; +} diff --git a/dumps/scripts/1237.cs2 b/dumps/scripts/1237.cs2 new file mode 100644 index 0000000..46db0d3 --- /dev/null +++ b/dumps/scripts/1237.cs2 @@ -0,0 +1,81 @@ +void script_1237(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + string svar0; + deleteAllExtraChilds(new WidgetPointer(arg0)); + ivar1 = 5; + ivar2 = 30; + ivar3 = 30; + ivar4 = 0; + ivar5 = 8; + ivar6 = ivar5; + ivar7 = 6; + ivar8 = add(30, 7); + if (((boolean)globalint_1052) && ((boolean)bitconfig_6840)) { + ivar5 = 5; + ivar6 = ivar5; + ivar8 = add(30, 4); + } + ivar9 = add(30, 6); + if (((boolean)globalint_181)) { + ivar5 = 8; + ivar6 = ivar5; + ivar7 = 30; + ivar8 = add(30, 7); + ivar9 = add(30, 5); + } + ivar10 = -1; + ivar11 = -1; + ivar12 = -1; + svar0 = ""; + ivar13 = 0; + ivar14 = 30; + if (((boolean)bitconfig_6840)) { + ivar14 = 20; + } + while (ivar4 < ivar14) { + ivar10 = cs2method_3408(105, 74, 2279, ivar4); + if (((boolean)bitconfig_6840)) { + ivar10 = cs2method_3408(105, 74, 863, ivar4); + } + ivar12 = getOtherCommonData(ivar10, 736); + ivar11 = getOtherCommonData(ivar10, 735); + svar0 = getOtherCommonData(ivar10, 734); + ivar13 = getOtherCommonData(ivar10, 737); + createExtraChild(new WidgetPointer(arg0), 5, ivar4); + setWidgetSize(ivar2, ivar3, 0, 0); + setWidgetPosition(ivar6, ivar7, 0, 0); + setWidgetSprite(ivar12); + doWidgetType21Task(0); + if (((boolean)globalint_181)) { + setWidgetContextMenuOption(1, "Activate" + ""); + setScriptCallOnConfigChange(49, new WidgetPointer(-32768,3), new WidgetPointer(271,7), ivar4, 1395, 1582, 2, "IIiY"); + setScriptCallOnMouseOver(1160, new WidgetPointer(-32768,3), -2147483643, new WidgetPointer(271,49), svar0, 25, 190, "IiIsii"); + if (((boolean)ivar4) && (bitconfig_6521 == 10)) { + setScriptCallOnGlobalConfigChange(1428, new WidgetPointer(-32768,3), -2147483643, 1024, 1, "IiY"); + } + } + setScriptCallOnSkillChange(52, ivar13, ivar12, ivar11, new WidgetPointer(-32768,3), -2147483643, 5, 1, "iddIiY"); + setScriptCallOnMouseExit(40, new WidgetPointer(271,49), "I"); + ivar4 = add(ivar4, 1); + if (((boolean)mod(ivar4, ivar1))) { + ivar6 = ivar5; + ivar7 = add(ivar7, ivar9); + } else { + ivar6 = add(ivar6, ivar8); + } + } + return; +} diff --git a/dumps/scripts/1238.cs2 b/dumps/scripts/1238.cs2 new file mode 100644 index 0000000..728ccc2 --- /dev/null +++ b/dumps/scripts/1238.cs2 @@ -0,0 +1,4 @@ +void script_1238(int arg0) { + script_1293(arg0); + return; +} diff --git a/dumps/scripts/1239.cs2 b/dumps/scripts/1239.cs2 new file mode 100644 index 0000000..44248e3 --- /dev/null +++ b/dumps/scripts/1239.cs2 @@ -0,0 +1,51 @@ +cs2func_script_1239_struct(2,0,0) script_1239(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int stack_dump0; + cs2func_script_3415_struct(2,0,0) structdump_1; + cs2func_script_3371_struct(2,0,0) structdump_2; + cs2func_script_3372_struct(2,0,0) structdump_3; + cs2func_script_3373_struct(2,0,0) structdump_4; + cs2func_script_3374_struct(2,0,0) structdump_5; + ivar1 = divide(globalint_176, 10); + if (ivar1 > 5) { + ivar1 = 1; + globalint_176 = multiply(ivar1, 10); + } + ivar2 = -1; + ivar3 = 0; + switch (ivar1) { + case 0: + case 1: + stack_dump0 = arg0; + structdump_1 = script_3415(stack_dump0); + ivar3 = structdump_1.intpart_1; + ivar2 = structdump_1.intpart_0; + break; + case 2: + stack_dump0 = arg0; + structdump_2 = script_3371(stack_dump0); + ivar3 = structdump_2.intpart_1; + ivar2 = structdump_2.intpart_0; + break; + case 3: + stack_dump0 = arg0; + structdump_3 = script_3372(stack_dump0); + ivar3 = structdump_3.intpart_1; + ivar2 = structdump_3.intpart_0; + break; + case 4: + stack_dump0 = arg0; + structdump_4 = script_3373(stack_dump0); + ivar3 = structdump_4.intpart_1; + ivar2 = structdump_4.intpart_0; + break; + case 5: + stack_dump0 = arg0; + structdump_5 = script_3374(stack_dump0); + ivar3 = structdump_5.intpart_1; + ivar2 = structdump_5.intpart_0; + } + return newstruct cs2func_script_1239_struct(ivar2, ivar3); +} diff --git a/dumps/scripts/124.cs2 b/dumps/scripts/124.cs2 new file mode 100644 index 0000000..dceb67c --- /dev/null +++ b/dumps/scripts/124.cs2 @@ -0,0 +1,4 @@ +void script_124() { + script_125(globalint_1036); + return; +} diff --git a/dumps/scripts/1240.cs2 b/dumps/scripts/1240.cs2 new file mode 100644 index 0000000..3dfcfb0 --- /dev/null +++ b/dumps/scripts/1240.cs2 @@ -0,0 +1,24 @@ +cs2func_script_1240_struct(2,0,0) script_1240(int arg0) { + if (((boolean)arg0)) { + cs2method5405(0, 6); + cs2method5405(1, 6); + cs2method5406(0, 0, 40930087, 800, 40930082, 810, 0); + cs2method5406(1, 0, 41110311, 120, 41110307, 120, 0); + cs2method5406(0, 1, 41175822, 1310, 41470726, 1210, 0); + cs2method5406(1, 1, 41388823, -120, 41634581, -120, 0); + script_1899(0, 100, 150); + cs2method5406(0, 2, 41798417, 1235, 41896725, 1235, 0); + cs2method5406(1, 2, 41749278, 120, 41749278, 120, 0); + script_1899(1, 100, 150); + cs2method5406(0, 3, 41945893, 1190, 41913134, 1190, 0); + cs2method5406(1, 3, 41749280, 120, 41749280, 120, 0); + script_1899(2, 100, 150); + cs2method5406(0, 4, 41503520, 1000, 41470733, 975, 0); + cs2method5406(1, 4, 41716512, 120, 41716512, 120, 0); + script_1899(3, 100, 150); + cs2method5406(0, 5, 41470732, 1000, 41470732, 975, 0); + cs2method5406(1, 5, 41716511, 200, 41716511, 200, 0); + script_1899(4, 100, 150); + } + return newstruct cs2func_script_1240_struct(41437980, 1250324); +} diff --git a/dumps/scripts/1241.cs2 b/dumps/scripts/1241.cs2 new file mode 100644 index 0000000..dadd639 --- /dev/null +++ b/dumps/scripts/1241.cs2 @@ -0,0 +1,21 @@ +cs2func_script_1241_struct(2,0,0) script_1241(int arg0) { + if (((boolean)arg0)) { + cs2method5405(0, 5); + cs2method5405(1, 5); + cs2method5406(0, 0, 54299787, 1300, 54185099, 1300, 0); + cs2method5406(1, 0, 54185096, 425, 54004874, 425, 0); + cs2method5406(0, 1, 54119572, 1250, 54103191, 1240, 0); + cs2method5406(1, 1, 53972124, 425, 53988515, 425, 0); + script_1899(0, 100, 150); + cs2method5406(0, 2, 54185119, 1025, 54234274, 870, 0); + cs2method5406(1, 2, 54168747, 425, 54234286, 425, 0); + script_1899(1, 100, 150); + cs2method5406(0, 3, 54299810, 640, 54299810, 480, 0); + cs2method5406(1, 3, 54299829, 185, 54299834, 120, 0); + script_1899(2, 100, 150); + cs2method5406(0, 4, 54299819, 500, 54299819, 495, 0); + cs2method5406(1, 4, 54299835, 185, 54299835, 115, 0); + script_1899(3, 100, 150); + } + return newstruct cs2func_script_1241_struct(54299813, 1250324); +} diff --git a/dumps/scripts/1242.cs2 b/dumps/scripts/1242.cs2 new file mode 100644 index 0000000..057c2c5 --- /dev/null +++ b/dumps/scripts/1242.cs2 @@ -0,0 +1,10 @@ +void script_1242(int arg0) { + int ivar1; + setWidgetSprite(3152, new WidgetPointer(arg0)); + setScriptCallOnMousePressed(1950, new WidgetPointer(-32768,3), "I", new WidgetPointer(arg0)); + ivar1 = addToCoordinate(0, add(subtract(extractX(getMyPositionHash()), mod(extractX(getMyPositionHash()), 64)), 13), 0, add(subtract(extractY(getMyPositionHash()), mod(extractY(getMyPositionHash()), 64)), 23)); + cameraMethod5511(ivar1); + cameraPointAt(ivar1, 25, 100, 10); + cameraMoveTo(addToCoordinate(ivar1, 11, 0, 0), 2600, 100, 10); + return; +} diff --git a/dumps/scripts/1243.cs2 b/dumps/scripts/1243.cs2 new file mode 100644 index 0000000..4166b8f --- /dev/null +++ b/dumps/scripts/1243.cs2 @@ -0,0 +1,33 @@ +cs2func_script_1243_struct(2,0,0) script_1243(int arg0) { + if (((boolean)arg0)) { + cs2method5405(0, 9); + cs2method5405(1, 9); + cs2method5406(0, 0, 61934340, 1600, 62065411, 1580, 0); + cs2method5406(1, 0, 62032653, 470, 62065419, 460, 0); + cs2method5406(0, 1, 62491394, 1215, 62622468, 1095, 0); + cs2method5406(1, 1, 62507787, 375, 62606095, 360, 0); + script_1899(0, 100, 150); + cs2method5406(0, 2, 62786321, 965, 62819097, 940, 0); + cs2method5406(1, 2, 62638873, 350, 62638879, 330, 0); + script_1899(1, 100, 150); + cs2method5406(0, 3, 62671661, 970, 62491442, 985, 0); + cs2method5406(1, 3, 62524197, 330, 62425893, 330, 0); + script_1899(2, 100, 150); + cs2method5406(0, 4, 62163741, 950, 62147342, 980, 0); + cs2method5406(1, 4, 62442266, 240, 62507800, 195, 0); + script_1899(3, 100, 150); + cs2method5406(0, 5, 62556943, 1445, 62720791, 1420, 0); + cs2method5406(1, 5, 62573344, 190, 62589733, 160, 0); + script_1899(4, 100, 150); + cs2method5406(0, 6, 62524203, 1070, 62393138, 1070, 0); + cs2method5406(1, 6, 62475056, 100, 62376759, 65, 0); + script_1899(5, 100, 150); + cs2method5406(0, 7, 62278449, 1115, 62278449, 1115, 0); + cs2method5406(1, 7, 62212916, 45, 62212916, 45, 0); + script_1899(6, 100, 150); + cs2method5406(0, 8, 62032690, 1420, 62032690, 1395, 0); + cs2method5406(1, 8, 62212916, -245, 62212916, -245, 0); + script_1899(7, 100, 150); + } + return newstruct cs2func_script_1243_struct(62343961, 1250324); +} diff --git a/dumps/scripts/1244.cs2 b/dumps/scripts/1244.cs2 new file mode 100644 index 0000000..7236296 --- /dev/null +++ b/dumps/scripts/1244.cs2 @@ -0,0 +1,27 @@ +cs2func_script_1244_struct(2,0,0) script_1244(int arg0) { + if (((boolean)arg0)) { + cs2method5405(0, 7); + cs2method5405(1, 7); + cs2method5406(0, 0, 47468174, 1500, 47533710, 1500, 0); + cs2method5406(1, 0, 47746712, 500, 47828637, 500, 0); + cs2method5406(0, 1, 47648414, 1400, 47648429, 1400, 0); + cs2method5406(1, 1, 47828643, 400, 47828643, 400, 0); + script_1899(0, 100, 150); + cs2method5406(0, 2, 47861423, 1300, 47959727, 1300, 0); + cs2method5406(1, 2, 47828643, 390, 47828643, 395, 0); + script_1899(1, 100, 150); + cs2method5406(0, 3, 48008869, 1200, 48008866, 1200, 0); + cs2method5406(1, 3, 47828643, 395, 47828643, 395, 0); + script_1899(2, 100, 150); + cs2method5406(0, 4, 47861404, 1100, 47763100, 1100, 0); + cs2method5406(1, 4, 47828643, 395, 47828643, 395, 0); + script_1899(3, 100, 150); + cs2method5406(0, 5, 47763107, 1000, 47763110, 1000, 0); + cs2method5406(1, 5, 47828643, 395, 47828643, 395, 0); + script_1899(4, 100, 150); + cs2method5406(0, 6, 47877796, 698, 47910560, 698, 0); + cs2method5406(1, 6, 47828643, 395, 47828643, 395, 0); + script_1899(5, 100, 150); + } + return newstruct cs2func_script_1244_struct(47648414, 1250324); +} diff --git a/dumps/scripts/1245.cs2 b/dumps/scripts/1245.cs2 new file mode 100644 index 0000000..b0dcd8f --- /dev/null +++ b/dumps/scripts/1245.cs2 @@ -0,0 +1,24 @@ +cs2func_script_1245_struct(2,0,0) script_1245(int arg0) { + if (((boolean)arg0)) { + cs2method5405(0, 6); + cs2method5405(1, 6); + cs2method5406(0, 0, 44111061, 1500, 44143822, 1450, 0); + cs2method5406(1, 0, 44274901, 250, 44274894, 250, 0); + cs2method5406(0, 1, 44291266, 1400, 44405952, 1350, 0); + cs2method5406(1, 1, 44405963, 250, 44487882, 250, 0); + script_1899(0, 100, 150); + cs2method5406(0, 2, 44733639, 1300, 44831951, 1250, 0); + cs2method5406(1, 2, 44553428, 250, 44553433, 250, 0); + script_1899(1, 100, 150); + cs2method5406(0, 3, 44618971, 900, 44569824, 900, 0); + cs2method5406(1, 3, 44569833, 250, 44586224, 250, 0); + script_1899(2, 100, 150); + cs2method5406(0, 4, 44586225, 700, 44586228, 700, 0); + cs2method5406(1, 4, 44586233, 250, 44586234, 250, 0); + script_1899(3, 100, 150); + cs2method5406(0, 5, 44586231, 700, 44586231, 700, 0); + cs2method5406(1, 5, 44586236, 250, 44586236, 250, 0); + script_1899(4, 100, 150); + } + return newstruct cs2func_script_1245_struct(44405978, 1250324); +} diff --git a/dumps/scripts/1246.cs2 b/dumps/scripts/1246.cs2 new file mode 100644 index 0000000..fafdf2f --- /dev/null +++ b/dumps/scripts/1246.cs2 @@ -0,0 +1,27 @@ +cs2func_script_1246_struct(2,0,0) script_1246(int arg0) { + if (((boolean)arg0)) { + cs2method5405(0, 7); + cs2method5405(1, 7); + cs2method5406(0, 0, 59172405, 900, 59172403, 900, 0); + cs2method5406(1, 0, 59139632, 350, 59123243, 300, 0); + cs2method5406(0, 1, 59205161, 800, 59254307, 800, 0); + cs2method5406(1, 1, 59237922, 350, 59303454, 300, 0); + script_1899(0, 100, 150); + cs2method5406(0, 2, 59401754, 800, 59418132, 800, 0); + cs2method5406(1, 2, 59319831, 300, 59319827, 300, 0); + script_1899(1, 100, 150); + cs2method5406(0, 3, 59287050, 800, 59188742, 800, 0); + cs2method5406(1, 3, 59123212, 300, 58975755, 300, 0); + script_1899(2, 100, 150); + cs2method5406(0, 4, 58877450, 945, 58811918, 1130, 0); + cs2method5406(1, 4, 58942991, 300, 58942991, 300, 0); + script_1899(3, 100, 150); + cs2method5406(0, 5, 58828309, 1355, 58844696, 1355, 0); + cs2method5406(1, 5, 58942991, 300, 58942991, 300, 0); + script_1899(4, 100, 150); + cs2method5406(0, 6, 58959386, 1355, 59024922, 1355, 0); + cs2method5406(1, 6, 58942991, 300, 58942991, 300, 0); + script_1899(5, 100, 150); + } + return newstruct cs2func_script_1246_struct(59090457, 1250324); +} diff --git a/dumps/scripts/1247.cs2 b/dumps/scripts/1247.cs2 new file mode 100644 index 0000000..6471820 --- /dev/null +++ b/dumps/scripts/1247.cs2 @@ -0,0 +1,24 @@ +cs2func_script_1247_struct(2,0,0) script_1247(int arg0) { + if (((boolean)arg0)) { + cs2method5405(0, 6); + cs2method5405(1, 6); + cs2method5406(0, 0, 52546917, 900, 52546914, 900, 0); + cs2method5406(1, 0, 52645221, 300, 52645221, 300, 0); + cs2method5406(0, 1, 52645215, 900, 52694367, 900, 0); + cs2method5406(1, 1, 52645221, 300, 52645221, 300, 0); + script_1899(0, 100, 150); + cs2method5406(0, 2, 52743525, 900, 52743528, 900, 0); + cs2method5406(1, 2, 52645221, 300, 52645221, 300, 0); + script_1899(1, 100, 150); + cs2method5406(0, 3, 52645227, 900, 52596075, 900, 0); + cs2method5406(1, 3, 52645221, 300, 52645221, 300, 0); + script_1899(2, 100, 150); + cs2method5406(0, 4, 52546917, 900, 52546914, 900, 0); + cs2method5406(1, 4, 52645221, 300, 52645221, 300, 0); + script_1899(3, 100, 150); + cs2method5406(0, 5, 52645215, 900, 52694367, 900, 0); + cs2method5406(1, 5, 52645221, 300, 52645221, 300, 0); + script_1899(4, 100, 150); + } + return newstruct cs2func_script_1247_struct(52890976, 1250324); +} diff --git a/dumps/scripts/1248.cs2 b/dumps/scripts/1248.cs2 new file mode 100644 index 0000000..5a662c5 --- /dev/null +++ b/dumps/scripts/1248.cs2 @@ -0,0 +1,6 @@ +void script_1248() { + setScriptCallOnGameloop(-1, "", new WidgetPointer(894,5)); + setWidgetIsHidden(true, new WidgetPointer(894,7)); + setWidgetSprite(-1, new WidgetPointer(894,4)); + return; +} diff --git a/dumps/scripts/1249.cs2 b/dumps/scripts/1249.cs2 new file mode 100644 index 0000000..12e58a3 --- /dev/null +++ b/dumps/scripts/1249.cs2 @@ -0,0 +1,41 @@ +void script_1249(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + int stack_dump0; + cs2func_script_1239_struct(2,0,0) structdump_1; + cs2func_script_1239_struct(2,0,0) structdump_2; + if (getClientCycle() < globalint_177) { + return; + } + ivar3 = mod(globalint_176, 10); + ivar4 = -1; + ivar5 = 0; + if (((boolean)ivar3)) { + setWidgetIsHidden(false, new WidgetPointer(arg2)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg2)); + cs2method2103(0, new WidgetPointer(arg2)); + stack_dump0 = 0; + structdump_1 = script_1239(stack_dump0); + ivar5 = structdump_1.intpart_1; + ivar4 = structdump_1.intpart_0; + cameraMoveTo(ivar4, 1000, 100, 100); + cameraPointAt(ivar4, 0, 100, 100); + globalint_177 = add(getClientCycle(), 30); + globalint_176 = add(globalint_176, 2); + } else { + if (ivar3 == 2) { + if (isWidgetHidden(new WidgetPointer(arg1))) { + setScriptCallOnGameloop(1252, new WidgetPointer(arg1), 3, "Ii", new WidgetPointer(arg1)); + } + setScriptCallOnGameloop(1252, new WidgetPointer(arg2), 1, "Ii", new WidgetPointer(arg2)); + stack_dump0 = 1; + structdump_2 = script_1239(stack_dump0); + ivar5 = structdump_2.intpart_1; + ivar4 = structdump_2.intpart_0; + script_1251(0, arg0, arg1, arg2, ivar5); + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + } + } + return; +} diff --git a/dumps/scripts/125.cs2 b/dumps/scripts/125.cs2 new file mode 100644 index 0000000..1d54f20 --- /dev/null +++ b/dumps/scripts/125.cs2 @@ -0,0 +1,252 @@ +void script_125(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + int ivar22; + int ivar23; + int ivar24; + int ivar25; + int ivar26; + int ivar27; + int ivar28; + int ivar29; + int ivar30; + string svar0; + string svar1; + string svar2; + string svar3; + string svar4; + string svar5; + int stack_dump0; + previousAndCurrentName(0,2,0) structdump_1; + ivar1 = 36044806; + ivar2 = 36044853; + ivar3 = 36044805; + ivar4 = 36044801; + ivar5 = 36044811; + ivar6 = 36044812; + ivar7 = 36044818; + ivar8 = 36044846; + ivar9 = 36044814; + ivar10 = 36044813; + ivar11 = 36044800; + ivar12 = getWidgetActualWidth(new WidgetPointer(ivar9)); + if (arg0 <= -1) { + arg0 = getWidgetActualX(new WidgetPointer(ivar9)); + } + arg0 = max(min(arg0, subtract(getWidgetActualWidth(new WidgetPointer(ivar10)), ivar12)), 0); + globalint_1036 = arg0; + setWidgetPosition(arg0, 0, 0, 1, new WidgetPointer(ivar9)); + deleteAllExtraChilds(new WidgetPointer(ivar1)); + deleteAllExtraChilds(new WidgetPointer(ivar2)); + deleteAllExtraChilds(new WidgetPointer(ivar3)); + deleteAllExtraChilds(new WidgetPointer(ivar4)); + ivar13 = getFriendlistSize(); + if (ivar13 == -2) { + setWidgetText(new WidgetPointer(ivar8), "Loading Friends List." + "
" + "Please wait."); + setWidgetIsHidden(false, new WidgetPointer(ivar8)); + setWidgetIsHidden(true, new WidgetPointer(ivar9)); + setWidgetIsHidden(true, new WidgetPointer(ivar7)); + return; + } + if (ivar13 == -1) { + setWidgetText(new WidgetPointer(ivar8), "Connecting to Friend Server." + "
" + "Please wait."); + setWidgetIsHidden(false, new WidgetPointer(ivar8)); + setWidgetIsHidden(true, new WidgetPointer(ivar9)); + setWidgetIsHidden(true, new WidgetPointer(ivar7)); + return; + } + setWidgetIsHidden(false, new WidgetPointer(ivar9)); + cs2method2314(149, new WidgetPointer(ivar9)); + setWidgetText(new WidgetPointer(ivar8), ""); + setWidgetIsHidden(true, new WidgetPointer(ivar8)); + setWidgetIsHidden(false, new WidgetPointer(ivar7)); + setWidgetText(new WidgetPointer(ivar7), intToStr(ivar13) + " / " + intToStr(200)); + ivar14 = 0; + ivar15 = getWidgetActualWidth(new WidgetPointer(ivar1)); + ivar16 = add(arg0, subtract(script_3365(ivar10), script_3365(ivar1))); + ivar17 = subtract(ivar15, add(ivar16, ivar12)); + svar0 = ""; + svar1 = ""; + svar2 = ""; + ivar18 = 0; + svar3 = ""; + ivar19 = 0; + ivar20 = 0; + svar4 = ""; + ivar21 = 0; + ivar22 = 0; + ivar23 = 15; + ivar24 = 5; + ivar25 = 10787197; + ivar26 = 0; + ivar27 = 0; + ivar28 = 0; + ivar29 = 0; + svar5 = ""; + while (ivar14 < ivar13) { + ivar21 = add(multiply(ivar14, ivar23), ivar24); + stack_dump0 = ivar14; + structdump_1 = getFriendName(stack_dump0); + svar3 = structdump_1.stringpart_1; + svar0 = structdump_1.stringpart_0; + if (stringMethod4107(svar3, "") != 0) { + ivar19 = 1; + } else { + ivar19 = 0; + } + if (((boolean)ivar19)) { + svar1 = " " + svar0; + } else { + svar1 = svar0; + } + ivar20 = getFriendWorld(ivar14); + if (cs2method3634(ivar14)) { + ivar25 = 8961267; + createExtraChild(new WidgetPointer(ivar1), 5, getExtraChildGap(new WidgetPointer(ivar1))); + setWidgetSize(9, 9, 0, 0); + setWidgetPosition(93, add(ivar21, 3), 0, 0); + setWidgetSprite(6980); + } else { + ivar25 = 10787197; + } + createExtraChild(new WidgetPointer(ivar1), 4, getExtraChildGap(new WidgetPointer(ivar1))); + setWidgetSize(ivar16, ivar23, 0, 0); + setWidgetPosition(0, ivar21, 0, 0); + setWidgetRGB(new Color(ivar25)); + setWidgetFont(3793); + setWidgetUnknownBoolean(true); + cs2method1305("" + svar0); + setWidgetTextAlignment(0, 0, 0); + if (ivar20 != 0) { + if (isMuteRelatedMethod3329() && cs2method6900()) { + setWidgetContextMenuOption(1, "Message"); + } + setWidgetContextMenuOption(2, "Quick Message"); + } else { + if (isMuteRelatedMethod3329() && cs2method6900()) { + setWidgetContextMenuOption(3, "Message"); + } + setWidgetContextMenuOption(4, "Quick Message"); + } + setWidgetContextMenuOption(5, "Delete"); + setScriptCallOnClickContextMenu(126, -2147483644, "event_opbase", ivar14, "isi"); + if (getTextWidth(3793, svar1) > ivar16) { + while ((getTextWidth(3793, svar1 + "...") > ivar16) && (strLength(svar1) > 0)) { + svar1 = substr(0, subtract(strLength(svar1), 1), svar1); + } + setWidgetText(svar1 + "..."); + if (((boolean)ivar19)) { + if (getLineCount(subtract(ivar15, 8), 3793, "Last known as: " + svar3) > 1) { + svar2 = svar0 + "
" + "Last known as:" + "
" + svar3; + } else { + svar2 = svar0 + "
" + "Last known as: " + svar3; + } + } else { + svar2 = svar0; + } + setScriptCallOnMouseOver(1594, new WidgetPointer(550,52), new WidgetPointer(-32768,3), -2147483643, svar2, -2147483647, -2147483646, "IIisii"); + setScriptCallOnMouseExit(40, new WidgetPointer(550,52), "I"); + } else { + setWidgetText(svar1); + if (((boolean)ivar19)) { + if (getLineCount(subtract(ivar15, 8), 3793, "Last known as: " + svar3) > 1) { + svar2 = "Last known as:" + "
" + svar3; + } else { + svar2 = "Last known as: " + svar3; + } + setScriptCallOnMouseOver(1594, new WidgetPointer(550,52), new WidgetPointer(-32768,3), -2147483643, svar2, -2147483647, -2147483646, "IIisii"); + setScriptCallOnMouseExit(40, new WidgetPointer(550,52), "I"); + } + } + createExtraChild(new WidgetPointer(ivar2), 5, getExtraChildGap(new WidgetPointer(ivar2))); + setWidgetSprite(2313); + setWidgetSize(14, 14, 0, 0); + setWidgetPosition(0, ivar21, 0, 0); + if (((boolean)ivar19)) { + setWidgetHidden(1); + } + setWidgetSize(ivar17, 0, 0, 1, new WidgetPointer(ivar3)); + setWidgetSize(ivar17, 0, 0, 1, new WidgetPointer(ivar4)); + if (((boolean)ivar20)) { + svar4 = "Offline"; + svar5 = "Offline"; + ivar29 = 0; + } else if (strIndexof(0, cs2method3610(ivar14), "RuneScape") != -1) { + svar4 = intToStr(ivar20); + svar5 = cs2method3610(ivar14); + ivar29 = add(add(2, 24), 2); + } else { + svar4 = cs2method3610(ivar14); + svar5 = svar4; + ivar29 = 0; + } + ivar26 = getTextWidth(3793, svar4); + if (ivar17 >= add(ivar26, ivar29)) { + if (ivar29 > 0) { + createExtraChild(new WidgetPointer(ivar4), 5, getExtraChildGap(new WidgetPointer(ivar4))); + setWidgetSprite(2173); + setWidgetSize(24, 12, 0, 0); + setWidgetPosition(2, add(ivar21, 1), 0, 0); + ivar27 = 0; + } + } else { + ivar27 = 1; + ivar29 = 0; + } + if (ivar17 >= ivar26) { + } else { + setScriptCallOnMouseOver(1594, new WidgetPointer(550,52), new WidgetPointer(-32768,3), -2147483643, svar5, -2147483647, -2147483646, "IIisii"); + setScriptCallOnMouseExit(40, new WidgetPointer(550,52), "I"); + svar4 = "..."; + } + createExtraChild(new WidgetPointer(ivar3), 4, getExtraChildGap(new WidgetPointer(ivar3))); + setWidgetSize(ivar17, ivar23, 0, 0); + setWidgetPosition(add(ivar29, 2), ivar21, 0, 0); + setWidgetFont(3793); + setWidgetUnknownBoolean(true); + setWidgetTextAlignment(0, 0, 0); + setWidgetText(svar4); + if (((boolean)ivar20)) { + setWidgetRGB(new Color(221, 92, 62)); + } else if (ivar20 == getWorldId()) { + setWidgetRGB(new Color(60, 183, 30)); + } else { + setWidgetRGB(new Color(255, 255, 100)); + } + setScriptCallOnMouseOver(1594, new WidgetPointer(550,52), new WidgetPointer(-32768,3), -2147483643, svar5, -2147483647, -2147483646, "IIisii"); + setScriptCallOnMouseExit(40, new WidgetPointer(550,52), "I"); + ivar14 = add(ivar14, 1); + } + ivar21 = add(add(ivar21, 15), 5); + ivar30 = 0; + if (ivar21 > getWidgetActualHeight(new WidgetPointer(ivar5))) { + ivar30 = min(cs2method2601(new WidgetPointer(ivar5)), ivar21); + setWidgetScrollMax(getWidgetActualWidth(new WidgetPointer(ivar5)), ivar21, new WidgetPointer(ivar5)); + script_72(ivar6, ivar5, ivar30); + } else { + setWidgetScrollMax(0, 0, new WidgetPointer(ivar5)); + setWidgetSize(0, 0, 1, 1, new WidgetPointer(ivar11)); + cs2method2100(0, 0, new WidgetPointer(ivar5)); + script_72(ivar6, ivar5, 0); + } + return; +} diff --git a/dumps/scripts/1250.cs2 b/dumps/scripts/1250.cs2 new file mode 100644 index 0000000..4c01bdd --- /dev/null +++ b/dumps/scripts/1250.cs2 @@ -0,0 +1,4 @@ +void script_1250(int arg0,int arg1,int arg2,int arg3,int arg4) { + script_1251(arg0, arg1, arg2, arg3, arg4); + return; +} diff --git a/dumps/scripts/1251.cs2 b/dumps/scripts/1251.cs2 new file mode 100644 index 0000000..f515082 --- /dev/null +++ b/dumps/scripts/1251.cs2 @@ -0,0 +1,28 @@ +void script_1251(int arg0,int arg1,int arg2,int arg3,int arg4) { + int stack_dump0; + int stack_dump1; + int stack_dump2; + cs2func_script_1898_struct(2,0,0) structdump_3; + stack_dump0 = 0; + stack_dump1 = arg0; + stack_dump2 = arg0; + structdump_3 = script_1898(stack_dump2); + cameraMethod5502(stack_dump0, stack_dump1, structdump_3.intpart_0, structdump_3.intpart_1, 1, arg0); + if (cs2method5407(0) <= add(arg0, 2)) { + setWidgetRGB(new Color(arg4), new WidgetPointer(arg3)); + cs2method2103(255, new WidgetPointer(arg3)); + setWidgetIsHidden(false, new WidgetPointer(arg3)); + setScriptCallOnGameloop(1253, new WidgetPointer(arg3), "I", new WidgetPointer(arg3)); + setScriptCallOnGameloop(1249, new WidgetPointer(arg1), new WidgetPointer(arg2), new WidgetPointer(arg3), "III", new WidgetPointer(arg1)); + setScriptCallOnMinimapRelatedSetting3(-1, "", new WidgetPointer(arg1)); + if (globalint_176 == 2) { + globalint_176 = add(add(globalint_176, 8), multiply(10, add(rndExcl(subtract(5, 1)), 1))); + } else { + globalint_176 = add(globalint_176, 8); + } + globalint_177 = add(getClientCycle(), 30); + return; + } + setScriptCallOnMinimapRelatedSetting3(1250, add(arg0, 1), new WidgetPointer(arg1), new WidgetPointer(arg2), new WidgetPointer(arg3), arg4, "iIIIi", new WidgetPointer(arg1)); + return; +} diff --git a/dumps/scripts/1252.cs2 b/dumps/scripts/1252.cs2 new file mode 100644 index 0000000..af0fe9a --- /dev/null +++ b/dumps/scripts/1252.cs2 @@ -0,0 +1,12 @@ +void script_1252(int arg0,int arg1) { + int ivar2; + ivar2 = getWidgetShadeColor(new WidgetPointer(arg0)); + ivar2 = min(add(ivar2, divide(multiply(255, arg1), 30)), 255); + cs2method2103(ivar2, new WidgetPointer(arg0)); + if (ivar2 >= 255) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(arg0)); + return; + } + return; +} diff --git a/dumps/scripts/1253.cs2 b/dumps/scripts/1253.cs2 new file mode 100644 index 0000000..0adb8da --- /dev/null +++ b/dumps/scripts/1253.cs2 @@ -0,0 +1,11 @@ +void script_1253(int arg0) { + int ivar1; + ivar1 = getWidgetShadeColor(new WidgetPointer(arg0)); + ivar1 = max(subtract(ivar1, divide(255, 30)), 0); + cs2method2103(ivar1, new WidgetPointer(arg0)); + if (ivar1 <= 0) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + return; + } + return; +} diff --git a/dumps/scripts/1254.cs2 b/dumps/scripts/1254.cs2 new file mode 100644 index 0000000..e7c5ccc --- /dev/null +++ b/dumps/scripts/1254.cs2 @@ -0,0 +1,6 @@ +void script_1254() { + setWidgetText(new WidgetPointer(328,1), intToStr(standart_config_343)); + setWidgetText(new WidgetPointer(328,3), intToStr(standart_config_344)); + setWidgetText(new WidgetPointer(328,5), intToStr(standart_config_345)); + return; +} diff --git a/dumps/scripts/1255.cs2 b/dumps/scripts/1255.cs2 new file mode 100644 index 0000000..fbd75b3 --- /dev/null +++ b/dumps/scripts/1255.cs2 @@ -0,0 +1,11 @@ +void script_1255() { + if (((boolean)bitconfig_305)) { + return; + } + if (((boolean)standart_config_261)) { + setWidgetSprite(180, new WidgetPointer(114,24)); + } else { + setWidgetSprite(181, new WidgetPointer(114,24)); + } + return; +} diff --git a/dumps/scripts/1256.cs2 b/dumps/scripts/1256.cs2 new file mode 100644 index 0000000..507d945 --- /dev/null +++ b/dumps/scripts/1256.cs2 @@ -0,0 +1,11 @@ +void script_1256() { + if (((boolean)bitconfig_305)) { + return; + } + if (((boolean)standart_config_262)) { + setWidgetSprite(180, new WidgetPointer(114,25)); + } else { + setWidgetSprite(181, new WidgetPointer(114,25)); + } + return; +} diff --git a/dumps/scripts/1257.cs2 b/dumps/scripts/1257.cs2 new file mode 100644 index 0000000..49e2e54 --- /dev/null +++ b/dumps/scripts/1257.cs2 @@ -0,0 +1,11 @@ +void script_1257() { + if (((boolean)bitconfig_305)) { + return; + } + if (((boolean)standart_config_263)) { + setWidgetSprite(180, new WidgetPointer(114,26)); + } else { + setWidgetSprite(181, new WidgetPointer(114,26)); + } + return; +} diff --git a/dumps/scripts/1258.cs2 b/dumps/scripts/1258.cs2 new file mode 100644 index 0000000..890faec --- /dev/null +++ b/dumps/scripts/1258.cs2 @@ -0,0 +1,11 @@ +void script_1258() { + if (((boolean)bitconfig_305)) { + return; + } + if (((boolean)standart_config_264)) { + setWidgetSprite(180, new WidgetPointer(114,27)); + } else { + setWidgetSprite(181, new WidgetPointer(114,27)); + } + return; +} diff --git a/dumps/scripts/1259.cs2 b/dumps/scripts/1259.cs2 new file mode 100644 index 0000000..7189ee4 --- /dev/null +++ b/dumps/scripts/1259.cs2 @@ -0,0 +1,11 @@ +void script_1259() { + if (((boolean)bitconfig_305)) { + return; + } + if (((boolean)standart_config_265)) { + setWidgetSprite(180, new WidgetPointer(114,28)); + } else { + setWidgetSprite(181, new WidgetPointer(114,28)); + } + return; +} diff --git a/dumps/scripts/126.cs2 b/dumps/scripts/126.cs2 new file mode 100644 index 0000000..1af982d --- /dev/null +++ b/dumps/scripts/126.cs2 @@ -0,0 +1,28 @@ +void script_126(int arg0,int arg1,string arg2) { + string svar1; + if (((boolean)globalint_1413)) { + return; + } + svar1 = strRemoveEntities(arg2); + switch (arg0) { + case 1: + globalint_1650 = 1; + globalstring_23 = svar1; + script_1558(0); + return; + case 2: + if (cs2method3627(arg1)) { + script_1050(1, svar1); + } else { + script_1050(3, svar1); + } + break; + case 3: + case 4: + messageType0("That player is currently offline."); + break; + case 5: + cs2method3606(svar1); + } + return; +} diff --git a/dumps/scripts/1260.cs2 b/dumps/scripts/1260.cs2 new file mode 100644 index 0000000..8c7b35d --- /dev/null +++ b/dumps/scripts/1260.cs2 @@ -0,0 +1,11 @@ +void script_1260() { + if (((boolean)bitconfig_305)) { + return; + } + if (((boolean)standart_config_266)) { + setWidgetSprite(180, new WidgetPointer(114,29)); + } else { + setWidgetSprite(181, new WidgetPointer(114,29)); + } + return; +} diff --git a/dumps/scripts/1261.cs2 b/dumps/scripts/1261.cs2 new file mode 100644 index 0000000..0bfb99c --- /dev/null +++ b/dumps/scripts/1261.cs2 @@ -0,0 +1,5 @@ +void script_1261() { + setWidgetText(new WidgetPointer(471,14), intToStr(bitconfig_2880)); + setWidgetText(new WidgetPointer(471,6), intToStr(bitconfig_2881)); + return; +} diff --git a/dumps/scripts/1262.cs2 b/dumps/scripts/1262.cs2 new file mode 100644 index 0000000..a3d3e9e --- /dev/null +++ b/dumps/scripts/1262.cs2 @@ -0,0 +1,7 @@ +void script_1262(int arg0,int arg1) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(arg0)); + if (arg1 != -1) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(arg1)); + } + return; +} diff --git a/dumps/scripts/1263.cs2 b/dumps/scripts/1263.cs2 new file mode 100644 index 0000000..b854a2b --- /dev/null +++ b/dumps/scripts/1263.cs2 @@ -0,0 +1,7 @@ +void script_1263(int arg0,int arg1) { + setWidgetRGB(new Color(45, 36, 6), new WidgetPointer(arg0)); + if (arg1 != -1) { + setWidgetRGB(new Color(45, 36, 6), new WidgetPointer(arg1)); + } + return; +} diff --git a/dumps/scripts/1264.cs2 b/dumps/scripts/1264.cs2 new file mode 100644 index 0000000..0ac2607 --- /dev/null +++ b/dumps/scripts/1264.cs2 @@ -0,0 +1,17 @@ +void script_1264() { + string svar0; + svar0 = "null"; + if (((boolean)standart_config_170)) { + setWidgetSprite(762, new WidgetPointer(261,6)); + svar0 = "Mouse buttons" + "
" + "(currently 2)"; + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(261,22), svar0, 25, 180, "IIsii", new WidgetPointer(261,6)); + } else { + if (((boolean)standart_config_170)) { + setWidgetSprite(761, new WidgetPointer(261,6)); + svar0 = "Mouse buttons" + "
" + "(currently 1)"; + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(261,22), svar0, 25, 180, "IIsii", new WidgetPointer(261,6)); + } + } + globalint_2 = 0; + return; +} diff --git a/dumps/scripts/1265.cs2 b/dumps/scripts/1265.cs2 new file mode 100644 index 0000000..c9ea564 --- /dev/null +++ b/dumps/scripts/1265.cs2 @@ -0,0 +1,18 @@ +void script_1265() { + string svar0; + svar0 = "null"; + if (((boolean)standart_config_171)) { + setWidgetSprite(761, new WidgetPointer(261,4)); + svar0 = "Chat effects" + "
" + "(currently off)"; + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(261,22), svar0, 25, 180, "IIsii", new WidgetPointer(261,4)); + globalint_2 = 0; + } else { + if (((boolean)standart_config_171)) { + setWidgetSprite(762, new WidgetPointer(261,4)); + svar0 = "Chat effects" + "
" + "(currently on)"; + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(261,22), svar0, 25, 180, "IIsii", new WidgetPointer(261,4)); + globalint_2 = 0; + } + } + return; +} diff --git a/dumps/scripts/1266.cs2 b/dumps/scripts/1266.cs2 new file mode 100644 index 0000000..f9d24ed --- /dev/null +++ b/dumps/scripts/1266.cs2 @@ -0,0 +1,4 @@ +void script_1266() { + script_1407(); + return; +} diff --git a/dumps/scripts/1267.cs2 b/dumps/scripts/1267.cs2 new file mode 100644 index 0000000..f7328b7 --- /dev/null +++ b/dumps/scripts/1267.cs2 @@ -0,0 +1,47 @@ +void script_1267() { + string svar0; + deleteAllExtraChilds(new WidgetPointer(309,1)); + script_1088(20250625, 22); + deleteAllExtraChilds(new WidgetPointer(309,9)); + script_333(20250633, 4734771, 3156258, 0, 0); + script_2647(20250633); + deleteAllExtraChilds(new WidgetPointer(309,12)); + script_333(20250636, 4734771, 3156258, 0, 0); + script_1516(20250636, 380, 100); + script_2647(20250636); + svar0 = "Choose a hairstyle"; + if (IsFemale()) { + setWidgetSize(getWidgetActualWidth(new WidgetPointer(309,8)), getWidgetActualHeight(new WidgetPointer(309,13)), 0, 0, new WidgetPointer(309,13)); + setWidgetIsHidden(true, new WidgetPointer(309,5)); + setScriptCallOnGlobalConfigChange(2789, 1008, 1015, 2, "Y", new WidgetPointer(309,1)); + setScriptCallOnConfigChange(-1, "", new WidgetPointer(309,1)); + } else { + setWidgetSize(subtract(getWidgetActualWidth(new WidgetPointer(309,8)), add(getWidgetActualWidth(new WidgetPointer(309,5)), 5)), getWidgetActualHeight(new WidgetPointer(309,13)), 0, 0, new WidgetPointer(309,13)); + setWidgetIsHidden(false, new WidgetPointer(309,5)); + globalint_774 = script_734(bitconfig_6084); + setWidgetSprite(1048, new WidgetPointer(309,6)); + setWidgetSprite(1055, new WidgetPointer(309,7)); + setScriptCallOnClickContextMenu(2830, -2147483644, 0, "i1", new WidgetPointer(309,6)); + setScriptCallOnClickContextMenu(2830, -2147483644, 1, "i1", new WidgetPointer(309,7)); + setScriptCallOnMouseOver(1160, new WidgetPointer(-32768,3), -1, new WidgetPointer(309,22), svar0, 25, 512, "IiIsii", new WidgetPointer(309,6)); + setScriptCallOnMouseExit(40, new WidgetPointer(309,22), "I", new WidgetPointer(309,6)); + svar0 = "Choose your facial hair"; + setScriptCallOnMouseOver(1160, new WidgetPointer(-32768,3), -1, new WidgetPointer(309,22), svar0, 25, 512, "IiIsii", new WidgetPointer(309,7)); + setScriptCallOnMouseExit(40, new WidgetPointer(309,22), "I", new WidgetPointer(309,7)); + setScriptCallOnGlobalConfigChange(2789, 1008, 1009, 1015, 3, "Y", new WidgetPointer(309,1)); + setScriptCallOnConfigChange(2736, 1057, 1, "Y", new WidgetPointer(309,1)); + } + deleteAllExtraChilds(new WidgetPointer(309,13)); + script_333(20250637, 4734771, 3156258, 0, 0); + createExtraChild(new WidgetPointer(309,13), 6, getExtraChildGap(new WidgetPointer(309,13))); + setWidgetSize(0, 0, 1, 1); + setWidgetPosition(0, 0, 1, 1); + cs2method1202(); + setWidget3DRotation(5, 15, 40, 1870, 0, 2400); + setWidgetAnimation(9804); + script_2647(20250637); + deleteAllExtraChilds(new WidgetPointer(309,15)); + script_2647(20250639); + script_2790(); + return; +} diff --git a/dumps/scripts/1268.cs2 b/dumps/scripts/1268.cs2 new file mode 100644 index 0000000..2f88c18 --- /dev/null +++ b/dumps/scripts/1268.cs2 @@ -0,0 +1,4 @@ +void script_1268() { + script_1408(); + return; +} diff --git a/dumps/scripts/1269.cs2 b/dumps/scripts/1269.cs2 new file mode 100644 index 0000000..1c22e85 --- /dev/null +++ b/dumps/scripts/1269.cs2 @@ -0,0 +1,18 @@ +void script_1269() { + string svar0; + svar0 = "null"; + if (((boolean)standart_config_427)) { + setWidgetSprite(761, new WidgetPointer(261,7)); + svar0 = "Accept aid" + "
" + "(currently off)"; + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(261,22), svar0, 25, 180, "IIsii", new WidgetPointer(261,7)); + globalint_2 = 0; + } else { + if (((boolean)standart_config_427)) { + setWidgetSprite(762, new WidgetPointer(261,7)); + svar0 = "Accept aid" + "
" + "(currently on)"; + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(261,22), svar0, 25, 180, "IIsii", new WidgetPointer(261,7)); + globalint_2 = 0; + } + } + return; +} diff --git a/dumps/scripts/127.cs2 b/dumps/scripts/127.cs2 new file mode 100644 index 0000000..e38178a --- /dev/null +++ b/dumps/scripts/127.cs2 @@ -0,0 +1,4 @@ +void script_127() { + script_4551(); + return; +} diff --git a/dumps/scripts/1270.cs2 b/dumps/scripts/1270.cs2 new file mode 100644 index 0000000..46cf8a3 --- /dev/null +++ b/dumps/scripts/1270.cs2 @@ -0,0 +1,4 @@ +void script_1270() { + script_1409(); + return; +} diff --git a/dumps/scripts/1271.cs2 b/dumps/scripts/1271.cs2 new file mode 100644 index 0000000..5ea21df --- /dev/null +++ b/dumps/scripts/1271.cs2 @@ -0,0 +1,119 @@ +void script_1271(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int stack_dump0; + ivar1 = 1; + ivar2 = 0; + switch (bitconfig_1010) { + case 0: + setWidgetText(new WidgetPointer(13,28), "First click the FIRST digit."); + setWidgetText(new WidgetPointer(13,1), "?"); + setWidgetText(new WidgetPointer(13,2), "?"); + setWidgetText(new WidgetPointer(13,3), "?"); + setWidgetText(new WidgetPointer(13,4), "?"); + break; + case 1: + setWidgetText(new WidgetPointer(13,28), "Now click the SECOND digit."); + setWidgetText(new WidgetPointer(13,1), "*"); + setWidgetText(new WidgetPointer(13,2), "?"); + setWidgetText(new WidgetPointer(13,3), "?"); + setWidgetText(new WidgetPointer(13,4), "?"); + break; + case 2: + setWidgetText(new WidgetPointer(13,28), "Time for the THIRD digit."); + setWidgetText(new WidgetPointer(13,1), "*"); + setWidgetText(new WidgetPointer(13,2), "*"); + setWidgetText(new WidgetPointer(13,3), "?"); + setWidgetText(new WidgetPointer(13,4), "?"); + break; + case 3: + setWidgetText(new WidgetPointer(13,28), "Finally, the FOURTH digit."); + setWidgetText(new WidgetPointer(13,1), "*"); + setWidgetText(new WidgetPointer(13,2), "*"); + setWidgetText(new WidgetPointer(13,3), "*"); + setWidgetText(new WidgetPointer(13,4), "?"); + stack_dump0 = 0; + ivar2 = 1; + ivar1 = stack_dump0; + break; + default: + setWidgetText(new WidgetPointer(13,28), "Please wait..."); + setWidgetText(new WidgetPointer(13,1), "*"); + setWidgetText(new WidgetPointer(13,2), "*"); + setWidgetText(new WidgetPointer(13,3), "*"); + setWidgetText(new WidgetPointer(13,4), "*"); + stack_dump0 = 1; + ivar2 = 1; + ivar1 = stack_dump0; + } + ivar3 = 0; + if (((boolean)arg0)) { + while (ivar3 < 10) { + setWidgetIsHidden(((boolean)ivar1), cs2method_3408(105, 73, 3555, ivar3)); + setWidgetIsHidden(((boolean)ivar2), cs2method_3408(105, 73, 3554, ivar3)); + ivar3 = add(ivar3, 1); + } + return; + } + ivar4 = rndExcl(10); + globalarray_0 = new int[10]; + globalarray_0[0] = ivar4; + globalarray_0[1] = mod(add(ivar4, 1), 10); + globalarray_0[2] = mod(add(ivar4, 2), 10); + globalarray_0[3] = mod(add(ivar4, 3), 10); + globalarray_0[4] = mod(add(ivar4, 4), 10); + globalarray_0[5] = mod(add(ivar4, 5), 10); + globalarray_0[6] = mod(add(ivar4, 6), 10); + globalarray_0[7] = mod(add(ivar4, 7), 10); + globalarray_0[8] = mod(add(ivar4, 8), 10); + globalarray_0[9] = mod(add(ivar4, 9), 10); + ivar5 = 0; + while (ivar3 < 10) { + ivar5 = rndExcl(9); + ivar4 = globalarray_0[9]; + globalarray_0[9] = globalarray_0[ivar5]; + globalarray_0[ivar5] = ivar4; + setWidgetPosition(subtract(25, rnd(50)), subtract(20, rnd(40)), 1, 1, cs2method_3408(105, 73, 3557, ivar3)); + setWidgetIsHidden(((boolean)ivar1), cs2method_3408(105, 73, 3555, ivar3)); + setWidgetIsHidden(((boolean)ivar2), cs2method_3408(105, 73, 3554, ivar3)); + ivar3 = add(ivar3, 1); + } + ivar6 = getWidgetActualWidth(new WidgetPointer(13,6)); + ivar7 = getWidgetActualHeight(new WidgetPointer(13,6)); + ivar8 = divide(subtract(getWidgetActualWidth(new WidgetPointer(13,5)), ivar6), 3); + ivar9 = divide(subtract(getWidgetActualHeight(new WidgetPointer(13,5)), ivar7), 2); + ivar10 = multiply(ivar8, 2); + ivar11 = multiply(ivar9, 2); + ivar12 = multiply(ivar8, 3); + setWidgetPosition(0, 0, 0, 0, cs2method_3408(105, 73, 3556, globalarray_0[0])); + setWidgetPosition(0, 0, 0, 0, cs2method_3408(105, 73, 3555, globalarray_0[0])); + setWidgetPosition(ivar8, 0, 0, 0, cs2method_3408(105, 73, 3556, globalarray_0[1])); + setWidgetPosition(ivar8, 0, 0, 0, cs2method_3408(105, 73, 3555, globalarray_0[1])); + setWidgetPosition(ivar10, 0, 0, 0, cs2method_3408(105, 73, 3556, globalarray_0[2])); + setWidgetPosition(ivar10, 0, 0, 0, cs2method_3408(105, 73, 3555, globalarray_0[2])); + setWidgetPosition(ivar12, 0, 0, 0, cs2method_3408(105, 73, 3556, globalarray_0[3])); + setWidgetPosition(ivar12, 0, 0, 0, cs2method_3408(105, 73, 3555, globalarray_0[3])); + setWidgetPosition(0, ivar9, 0, 0, cs2method_3408(105, 73, 3556, globalarray_0[4])); + setWidgetPosition(0, ivar9, 0, 0, cs2method_3408(105, 73, 3555, globalarray_0[4])); + setWidgetPosition(ivar8, ivar9, 0, 0, cs2method_3408(105, 73, 3556, globalarray_0[5])); + setWidgetPosition(ivar8, ivar9, 0, 0, cs2method_3408(105, 73, 3555, globalarray_0[5])); + setWidgetPosition(ivar10, ivar9, 0, 0, cs2method_3408(105, 73, 3556, globalarray_0[6])); + setWidgetPosition(ivar10, ivar9, 0, 0, cs2method_3408(105, 73, 3555, globalarray_0[6])); + setWidgetPosition(0, ivar11, 0, 0, cs2method_3408(105, 73, 3556, globalarray_0[7])); + setWidgetPosition(0, ivar11, 0, 0, cs2method_3408(105, 73, 3555, globalarray_0[7])); + setWidgetPosition(ivar8, ivar11, 0, 0, cs2method_3408(105, 73, 3556, globalarray_0[8])); + setWidgetPosition(ivar8, ivar11, 0, 0, cs2method_3408(105, 73, 3555, globalarray_0[8])); + setWidgetPosition(ivar10, ivar11, 0, 0, cs2method_3408(105, 73, 3556, globalarray_0[9])); + setWidgetPosition(ivar10, ivar11, 0, 0, cs2method_3408(105, 73, 3555, globalarray_0[9])); + return; +} diff --git a/dumps/scripts/1272.cs2 b/dumps/scripts/1272.cs2 new file mode 100644 index 0000000..cdc037b --- /dev/null +++ b/dumps/scripts/1272.cs2 @@ -0,0 +1,8 @@ +void script_1272() { + string svar0; + svar0 = "null"; + svar0 = "House options"; + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(261,22), svar0, 25, 180, "IIsii", new WidgetPointer(261,8)); + globalint_2 = 0; + return; +} diff --git a/dumps/scripts/1273.cs2 b/dumps/scripts/1273.cs2 new file mode 100644 index 0000000..bffd13a --- /dev/null +++ b/dumps/scripts/1273.cs2 @@ -0,0 +1,5 @@ +void script_1273(int arg0) { + script_2410(getItemDefOpcode129Or130Method4209(arg0, 1), getItemDefOpcode129Or130Method4209(arg0, 2), getItemDefOpcode129Or130Method4209(arg0, 3), -1, getItemDefOpcode129Or130Method4209(arg0, 5), getItemOption(arg0, 1), getItemOption(arg0, 2), getItemOption(arg0, 3), "", getItemOption(arg0, 5), getItemName(arg0)); + setScriptCallOnConfigChange(-1, ""); + return; +} diff --git a/dumps/scripts/1274.cs2 b/dumps/scripts/1274.cs2 new file mode 100644 index 0000000..d8cf8e6 --- /dev/null +++ b/dumps/scripts/1274.cs2 @@ -0,0 +1,4 @@ +void script_1274(int arg0) { + setItemOnWidgetMethod2200(14854, 0, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1275.cs2 b/dumps/scripts/1275.cs2 new file mode 100644 index 0000000..2902cef --- /dev/null +++ b/dumps/scripts/1275.cs2 @@ -0,0 +1,4 @@ +void script_1275(int arg0) { + setScriptCallOnGameloop(1410, new WidgetPointer(arg0), "I", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1276.cs2 b/dumps/scripts/1276.cs2 new file mode 100644 index 0000000..5732102 --- /dev/null +++ b/dumps/scripts/1276.cs2 @@ -0,0 +1,5 @@ +void script_1276(int arg0) { + globalint_814 = 0; + cs2method2103(255, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1277.cs2 b/dumps/scripts/1277.cs2 new file mode 100644 index 0000000..0a93720 --- /dev/null +++ b/dumps/scripts/1277.cs2 @@ -0,0 +1,5 @@ +void script_1277(int arg0,int arg1,int arg2,int arg3) { + script_1279(arg0, arg1, arg2, arg3); + setScriptCallOnItemContainerUpdate(1278, new WidgetPointer(arg0), arg1, arg2, arg3, arg1, 1, "IviiY", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1278.cs2 b/dumps/scripts/1278.cs2 new file mode 100644 index 0000000..aa3bb1b --- /dev/null +++ b/dumps/scripts/1278.cs2 @@ -0,0 +1,4 @@ +void script_1278(int arg0,int arg1,int arg2,int arg3) { + script_1279(arg0, arg1, arg2, arg3); + return; +} diff --git a/dumps/scripts/1279.cs2 b/dumps/scripts/1279.cs2 new file mode 100644 index 0000000..8d9ac0b --- /dev/null +++ b/dumps/scripts/1279.cs2 @@ -0,0 +1,19 @@ +void script_1279(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + int ivar6; + deleteAllExtraChilds(new WidgetPointer(arg0)); + ivar4 = 0; + ivar5 = 0; + ivar4 = divide(subtract(getWidgetActualWidth(new WidgetPointer(arg0)), multiply(36, arg2)), subtract(arg2, 1)); + ivar5 = divide(subtract(getWidgetActualHeight(new WidgetPointer(arg0)), multiply(32, arg3)), subtract(arg3, 1)); + ivar6 = 0; + while (ivar6 <= multiply(arg2, arg3)) { + createExtraChild(new WidgetPointer(arg0), 5, ivar6); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(multiply(add(36, ivar4), mod(ivar6, arg2)), multiply(divide(ivar6, arg2), add(32, ivar5)), 0, 0); + script_1280(arg1, ivar6, arg0, ivar6); + ivar6 = add(ivar6, 1); + } + return; +} diff --git a/dumps/scripts/128.cs2 b/dumps/scripts/128.cs2 new file mode 100644 index 0000000..8711f2c --- /dev/null +++ b/dumps/scripts/128.cs2 @@ -0,0 +1,4 @@ +void script_128() { + script_129(); + return; +} diff --git a/dumps/scripts/1280.cs2 b/dumps/scripts/1280.cs2 new file mode 100644 index 0000000..34e4000 --- /dev/null +++ b/dumps/scripts/1280.cs2 @@ -0,0 +1,23 @@ +void script_1280(int arg0,int arg1,int arg2,int arg3) { + string svar0; + svar0 = ""; + if (setWidgetRegister(new WidgetPointer(arg2), arg3)) { + if (getItemIdInSlot(arg0, arg1) != -1) { + svar0 = "" + getItemName(getItemIdInSlot(arg0, arg1)); + setItemOnWidgetMethod1200(getItemIdInSlot(arg0, arg1), getItemAmtInSlot(arg0, arg1)); + cs2method1305(svar0); + setWidgetContextMenuOption(10, "Examine" + ""); + cs2method1303(5); + cs2method1304(10); + setWidgetShadowColor(new Color(51, 51, 51)); + setWidgetBorderThickness(1); + } else { + setWidgetModel(-1); + setWidgetNoOptions(); + cs2method1303(0); + cs2method1304(0); + setScriptCallOnMouseDragReleased(-1, ""); + } + } + return; +} diff --git a/dumps/scripts/1281.cs2 b/dumps/scripts/1281.cs2 new file mode 100644 index 0000000..ff1ae6c --- /dev/null +++ b/dumps/scripts/1281.cs2 @@ -0,0 +1,9 @@ +void script_1281(int arg0,int arg1,int arg2,int arg3) { + if (arg2 == -1) { + script_1280(arg0, arg1, arg3, arg1); + return; + } + script_1280(arg0, arg1, arg3, arg2); + script_1280(arg0, arg2, arg3, arg1); + return; +} diff --git a/dumps/scripts/1282.cs2 b/dumps/scripts/1282.cs2 new file mode 100644 index 0000000..b14cc25 --- /dev/null +++ b/dumps/scripts/1282.cs2 @@ -0,0 +1,5 @@ +void script_1282(int arg0) { + script_1284(); + setWidgetIsHidden(false, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1283.cs2 b/dumps/scripts/1283.cs2 new file mode 100644 index 0000000..f944582 --- /dev/null +++ b/dumps/scripts/1283.cs2 @@ -0,0 +1,4 @@ +void script_1283() { + script_1284(); + return; +} diff --git a/dumps/scripts/1284.cs2 b/dumps/scripts/1284.cs2 new file mode 100644 index 0000000..15dcdd2 --- /dev/null +++ b/dumps/scripts/1284.cs2 @@ -0,0 +1,8 @@ +void script_1284() { + setWidgetIsHidden(true, new WidgetPointer(501,8)); + setWidgetIsHidden(true, new WidgetPointer(501,9)); + setWidgetIsHidden(true, new WidgetPointer(501,10)); + setWidgetIsHidden(true, new WidgetPointer(501,11)); + setWidgetIsHidden(true, new WidgetPointer(501,12)); + return; +} diff --git a/dumps/scripts/1285.cs2 b/dumps/scripts/1285.cs2 new file mode 100644 index 0000000..d4ca67b --- /dev/null +++ b/dumps/scripts/1285.cs2 @@ -0,0 +1,5 @@ +void script_1285(int arg0) { + script_1287(); + setWidgetIsHidden(false, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1286.cs2 b/dumps/scripts/1286.cs2 new file mode 100644 index 0000000..57eb460 --- /dev/null +++ b/dumps/scripts/1286.cs2 @@ -0,0 +1,4 @@ +void script_1286() { + script_1287(); + return; +} diff --git a/dumps/scripts/1287.cs2 b/dumps/scripts/1287.cs2 new file mode 100644 index 0000000..e66020e --- /dev/null +++ b/dumps/scripts/1287.cs2 @@ -0,0 +1,8 @@ +void script_1287() { + setWidgetIsHidden(true, new WidgetPointer(502,8)); + setWidgetIsHidden(true, new WidgetPointer(502,9)); + setWidgetIsHidden(true, new WidgetPointer(502,10)); + setWidgetIsHidden(true, new WidgetPointer(502,11)); + setWidgetIsHidden(true, new WidgetPointer(502,12)); + return; +} diff --git a/dumps/scripts/1288.cs2 b/dumps/scripts/1288.cs2 new file mode 100644 index 0000000..27ecaf5 --- /dev/null +++ b/dumps/scripts/1288.cs2 @@ -0,0 +1,109 @@ +void script_1288() { + setWidgetText(new WidgetPointer(128,37), intToStr(bitconfig_861)); + setWidgetText(new WidgetPointer(128,38), intToStr(bitconfig_862)); + if (bitconfig_842 == 2) { + setWidgetModel(8398, new WidgetPointer(128,1)); + setWidgetModel(8399, new WidgetPointer(128,2)); + setWidgetModel(8430, new WidgetPointer(128,19)); + } else if (((boolean)bitconfig_842)) { + setWidgetModel(8397, new WidgetPointer(128,1)); + setWidgetModel(8400, new WidgetPointer(128,2)); + setWidgetModel(8429, new WidgetPointer(128,19)); + } else { + setWidgetModel(-1, new WidgetPointer(128,19)); + setWidgetModel(8398, new WidgetPointer(128,1)); + setWidgetModel(8400, new WidgetPointer(128,2)); + } + if (bitconfig_843 == 2) { + setWidgetModel(8402, new WidgetPointer(128,3)); + setWidgetModel(8403, new WidgetPointer(128,4)); + setWidgetModel(8430, new WidgetPointer(128,20)); + } else if (((boolean)bitconfig_843)) { + setWidgetModel(8401, new WidgetPointer(128,3)); + setWidgetModel(8404, new WidgetPointer(128,4)); + setWidgetModel(8429, new WidgetPointer(128,20)); + } else { + setWidgetModel(-1, new WidgetPointer(128,20)); + setWidgetModel(8402, new WidgetPointer(128,3)); + setWidgetModel(8404, new WidgetPointer(128,4)); + } + if (bitconfig_844 == 2) { + setWidgetModel(8406, new WidgetPointer(128,5)); + setWidgetModel(8407, new WidgetPointer(128,6)); + setWidgetModel(8430, new WidgetPointer(128,21)); + } else if (((boolean)bitconfig_844)) { + setWidgetModel(8405, new WidgetPointer(128,5)); + setWidgetModel(8408, new WidgetPointer(128,6)); + setWidgetModel(8429, new WidgetPointer(128,21)); + } else { + setWidgetModel(-1, new WidgetPointer(128,21)); + setWidgetModel(8406, new WidgetPointer(128,5)); + setWidgetModel(8408, new WidgetPointer(128,6)); + } + if (bitconfig_845 == 2) { + setWidgetModel(8410, new WidgetPointer(128,7)); + setWidgetModel(8411, new WidgetPointer(128,8)); + setWidgetModel(8430, new WidgetPointer(128,22)); + } else if (((boolean)bitconfig_845)) { + setWidgetModel(8409, new WidgetPointer(128,7)); + setWidgetModel(8412, new WidgetPointer(128,8)); + setWidgetModel(8429, new WidgetPointer(128,22)); + } else { + setWidgetModel(-1, new WidgetPointer(128,22)); + setWidgetModel(8410, new WidgetPointer(128,7)); + setWidgetModel(8412, new WidgetPointer(128,8)); + } + if (bitconfig_846 == 2) { + setWidgetModel(8414, new WidgetPointer(128,9)); + setWidgetModel(8415, new WidgetPointer(128,10)); + setWidgetModel(8430, new WidgetPointer(128,23)); + } else if (((boolean)bitconfig_846)) { + setWidgetModel(8413, new WidgetPointer(128,9)); + setWidgetModel(8416, new WidgetPointer(128,10)); + setWidgetModel(8429, new WidgetPointer(128,23)); + } else { + setWidgetModel(-1, new WidgetPointer(128,23)); + setWidgetModel(8414, new WidgetPointer(128,9)); + setWidgetModel(8416, new WidgetPointer(128,10)); + } + if (bitconfig_847 == 2) { + setWidgetModel(8418, new WidgetPointer(128,11)); + setWidgetModel(8419, new WidgetPointer(128,12)); + setWidgetModel(8430, new WidgetPointer(128,24)); + } else if (((boolean)bitconfig_847)) { + setWidgetModel(8417, new WidgetPointer(128,11)); + setWidgetModel(8420, new WidgetPointer(128,12)); + setWidgetModel(8429, new WidgetPointer(128,24)); + } else { + setWidgetModel(-1, new WidgetPointer(128,24)); + setWidgetModel(8418, new WidgetPointer(128,11)); + setWidgetModel(8420, new WidgetPointer(128,12)); + } + if (bitconfig_848 == 2) { + setWidgetModel(8422, new WidgetPointer(128,13)); + setWidgetModel(8423, new WidgetPointer(128,14)); + setWidgetModel(8430, new WidgetPointer(128,25)); + } else if (((boolean)bitconfig_848)) { + setWidgetModel(8421, new WidgetPointer(128,13)); + setWidgetModel(8424, new WidgetPointer(128,14)); + setWidgetModel(8429, new WidgetPointer(128,25)); + } else { + setWidgetModel(-1, new WidgetPointer(128,25)); + setWidgetModel(8422, new WidgetPointer(128,13)); + setWidgetModel(8424, new WidgetPointer(128,14)); + } + if (bitconfig_849 == 2) { + setWidgetModel(8426, new WidgetPointer(128,15)); + setWidgetModel(8427, new WidgetPointer(128,16)); + setWidgetModel(8430, new WidgetPointer(128,26)); + } else if (((boolean)bitconfig_849)) { + setWidgetModel(8425, new WidgetPointer(128,15)); + setWidgetModel(8428, new WidgetPointer(128,16)); + setWidgetModel(8429, new WidgetPointer(128,26)); + } else { + setWidgetModel(-1, new WidgetPointer(128,26)); + setWidgetModel(8426, new WidgetPointer(128,15)); + setWidgetModel(8428, new WidgetPointer(128,16)); + } + return; +} diff --git a/dumps/scripts/1289.cs2 b/dumps/scripts/1289.cs2 new file mode 100644 index 0000000..d37b7e6 --- /dev/null +++ b/dumps/scripts/1289.cs2 @@ -0,0 +1,161 @@ +void script_1289() { + setWidgetText(new WidgetPointer(129,52), intToStr(bitconfig_861)); + setWidgetText(new WidgetPointer(129,53), intToStr(bitconfig_862)); + if (bitconfig_842 == 2) { + setWidgetModel(8448, new WidgetPointer(129,0)); + setWidgetModel(8449, new WidgetPointer(129,1)); + setWidgetModel(8496, new WidgetPointer(129,26)); + } else if (((boolean)bitconfig_842)) { + setWidgetModel(8447, new WidgetPointer(129,0)); + setWidgetModel(8450, new WidgetPointer(129,1)); + setWidgetModel(8495, new WidgetPointer(129,26)); + } else { + setWidgetModel(-1, new WidgetPointer(129,26)); + setWidgetModel(8448, new WidgetPointer(129,0)); + setWidgetModel(8450, new WidgetPointer(129,1)); + } + if (bitconfig_843 == 2) { + setWidgetModel(8452, new WidgetPointer(129,2)); + setWidgetModel(8453, new WidgetPointer(129,3)); + setWidgetModel(8498, new WidgetPointer(129,27)); + } else if (((boolean)bitconfig_843)) { + setWidgetModel(8451, new WidgetPointer(129,2)); + setWidgetModel(8454, new WidgetPointer(129,3)); + setWidgetModel(8497, new WidgetPointer(129,27)); + } else { + setWidgetModel(-1, new WidgetPointer(129,27)); + setWidgetModel(8452, new WidgetPointer(129,2)); + setWidgetModel(8454, new WidgetPointer(129,3)); + } + if (bitconfig_844 == 2) { + setWidgetModel(8456, new WidgetPointer(129,4)); + setWidgetModel(8457, new WidgetPointer(129,5)); + setWidgetModel(8500, new WidgetPointer(129,28)); + } else if (((boolean)bitconfig_844)) { + setWidgetModel(8455, new WidgetPointer(129,4)); + setWidgetModel(8458, new WidgetPointer(129,5)); + setWidgetModel(8499, new WidgetPointer(129,28)); + } else { + setWidgetModel(-1, new WidgetPointer(129,28)); + setWidgetModel(8456, new WidgetPointer(129,4)); + setWidgetModel(8458, new WidgetPointer(129,5)); + } + if (bitconfig_845 == 2) { + setWidgetModel(8460, new WidgetPointer(129,6)); + setWidgetModel(8461, new WidgetPointer(129,7)); + setWidgetModel(8502, new WidgetPointer(129,29)); + } else if (((boolean)bitconfig_845)) { + setWidgetModel(8459, new WidgetPointer(129,6)); + setWidgetModel(8462, new WidgetPointer(129,7)); + setWidgetModel(8501, new WidgetPointer(129,29)); + } else { + setWidgetModel(-1, new WidgetPointer(129,29)); + setWidgetModel(8460, new WidgetPointer(129,6)); + setWidgetModel(8462, new WidgetPointer(129,7)); + } + if (bitconfig_846 == 2) { + setWidgetModel(8464, new WidgetPointer(129,8)); + setWidgetModel(8465, new WidgetPointer(129,9)); + setWidgetModel(8504, new WidgetPointer(129,30)); + } else if (((boolean)bitconfig_846)) { + setWidgetModel(8463, new WidgetPointer(129,8)); + setWidgetModel(8466, new WidgetPointer(129,9)); + setWidgetModel(8503, new WidgetPointer(129,30)); + } else { + setWidgetModel(-1, new WidgetPointer(129,30)); + setWidgetModel(8464, new WidgetPointer(129,8)); + setWidgetModel(8466, new WidgetPointer(129,9)); + } + if (bitconfig_847 == 2) { + setWidgetModel(8468, new WidgetPointer(129,10)); + setWidgetModel(8469, new WidgetPointer(129,11)); + setWidgetModel(8506, new WidgetPointer(129,31)); + } else if (((boolean)bitconfig_847)) { + setWidgetModel(8467, new WidgetPointer(129,10)); + setWidgetModel(8470, new WidgetPointer(129,11)); + setWidgetModel(8505, new WidgetPointer(129,31)); + } else { + setWidgetModel(-1, new WidgetPointer(129,31)); + setWidgetModel(8468, new WidgetPointer(129,10)); + setWidgetModel(8470, new WidgetPointer(129,11)); + } + if (bitconfig_848 == 2) { + setWidgetModel(8472, new WidgetPointer(129,12)); + setWidgetModel(8473, new WidgetPointer(129,13)); + setWidgetModel(8508, new WidgetPointer(129,32)); + } else if (((boolean)bitconfig_848)) { + setWidgetModel(8471, new WidgetPointer(129,12)); + setWidgetModel(8474, new WidgetPointer(129,13)); + setWidgetModel(8507, new WidgetPointer(129,32)); + } else { + setWidgetModel(-1, new WidgetPointer(129,32)); + setWidgetModel(8472, new WidgetPointer(129,12)); + setWidgetModel(8474, new WidgetPointer(129,13)); + } + if (bitconfig_849 == 2) { + setWidgetModel(8476, new WidgetPointer(129,14)); + setWidgetModel(8477, new WidgetPointer(129,15)); + setWidgetModel(8510, new WidgetPointer(129,33)); + } else if (((boolean)bitconfig_849)) { + setWidgetModel(8475, new WidgetPointer(129,14)); + setWidgetModel(8478, new WidgetPointer(129,15)); + setWidgetModel(8509, new WidgetPointer(129,33)); + } else { + setWidgetModel(-1, new WidgetPointer(129,33)); + setWidgetModel(8476, new WidgetPointer(129,14)); + setWidgetModel(8478, new WidgetPointer(129,15)); + } + if (bitconfig_850 == 2) { + setWidgetModel(8480, new WidgetPointer(129,16)); + setWidgetModel(8481, new WidgetPointer(129,17)); + setWidgetModel(8512, new WidgetPointer(129,34)); + } else if (((boolean)bitconfig_850)) { + setWidgetModel(8479, new WidgetPointer(129,16)); + setWidgetModel(8482, new WidgetPointer(129,17)); + setWidgetModel(8511, new WidgetPointer(129,34)); + } else { + setWidgetModel(-1, new WidgetPointer(129,34)); + setWidgetModel(8480, new WidgetPointer(129,16)); + setWidgetModel(8482, new WidgetPointer(129,17)); + } + if (bitconfig_851 == 2) { + setWidgetModel(8484, new WidgetPointer(129,18)); + setWidgetModel(8485, new WidgetPointer(129,19)); + setWidgetModel(8514, new WidgetPointer(129,35)); + } else if (((boolean)bitconfig_851)) { + setWidgetModel(8483, new WidgetPointer(129,18)); + setWidgetModel(8486, new WidgetPointer(129,19)); + setWidgetModel(8513, new WidgetPointer(129,35)); + } else { + setWidgetModel(-1, new WidgetPointer(129,35)); + setWidgetModel(8484, new WidgetPointer(129,18)); + setWidgetModel(8486, new WidgetPointer(129,19)); + } + if (bitconfig_852 == 2) { + setWidgetModel(8488, new WidgetPointer(129,20)); + setWidgetModel(8489, new WidgetPointer(129,21)); + setWidgetModel(8516, new WidgetPointer(129,36)); + } else if (((boolean)bitconfig_852)) { + setWidgetModel(8487, new WidgetPointer(129,20)); + setWidgetModel(8490, new WidgetPointer(129,21)); + setWidgetModel(8515, new WidgetPointer(129,36)); + } else { + setWidgetModel(-1, new WidgetPointer(129,36)); + setWidgetModel(8488, new WidgetPointer(129,20)); + setWidgetModel(8490, new WidgetPointer(129,21)); + } + if (bitconfig_853 == 2) { + setWidgetModel(8492, new WidgetPointer(129,22)); + setWidgetModel(8493, new WidgetPointer(129,23)); + setWidgetModel(8518, new WidgetPointer(129,37)); + } else if (((boolean)bitconfig_853)) { + setWidgetModel(8491, new WidgetPointer(129,22)); + setWidgetModel(8494, new WidgetPointer(129,23)); + setWidgetModel(8517, new WidgetPointer(129,37)); + } else { + setWidgetModel(-1, new WidgetPointer(129,37)); + setWidgetModel(8492, new WidgetPointer(129,22)); + setWidgetModel(8494, new WidgetPointer(129,23)); + } + return; +} diff --git a/dumps/scripts/129.cs2 b/dumps/scripts/129.cs2 new file mode 100644 index 0000000..331dfd4 --- /dev/null +++ b/dumps/scripts/129.cs2 @@ -0,0 +1,132 @@ +void script_129() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + string svar0; + string svar1; + string svar2; + string svar3; + int stack_dump0; + opcStruct3622(0,2,0) structdump_1; + deleteAllExtraChilds(new WidgetPointer(550,4)); + ivar0 = getIgnoreCount(); + if (ivar0 < 0) { + setWidgetText(new WidgetPointer(550,46), "Loading Ignore List." + "
" + "Please wait."); + setWidgetIsHidden(false, new WidgetPointer(550,46)); + setWidgetText(new WidgetPointer(550,35), ""); + return; + } + setWidgetText(new WidgetPointer(550,35), intToStr(ivar0) + " / " + intToStr(100)); + setWidgetText(new WidgetPointer(550,46), ""); + setWidgetIsHidden(true, new WidgetPointer(550,46)); + ivar1 = 36044804; + ivar2 = 36044802; + ivar3 = 36044803; + ivar4 = 36044831; + ivar5 = 0; + svar0 = ""; + svar1 = ""; + svar2 = ""; + ivar6 = 0; + ivar7 = 0; + svar3 = ""; + ivar8 = 0; + ivar9 = 0; + ivar10 = 15; + ivar11 = divide(getWidgetActualHeight(new WidgetPointer(ivar3)), ivar10); + deleteAllExtraChilds(new WidgetPointer(ivar1)); + deleteAllExtraChilds(new WidgetPointer(ivar2)); + while (ivar5 < ivar0) { + ivar8 = multiply(ivar5, 2); + ivar9 = multiply(ivar5, ivar10); + stack_dump0 = ivar5; + structdump_1 = cs2method3622(stack_dump0); + svar1 = structdump_1.stringpart_1; + svar0 = structdump_1.stringpart_0; + if (stringMethod4107(svar1, "") != 0) { + ivar6 = 1; + } else { + ivar6 = 0; + } + if (((boolean)ivar6)) { + svar2 = " " + svar0; + } else { + svar2 = svar0; + } + createExtraChild(new WidgetPointer(550,4), 4, ivar8); + setWidgetSize(168, ivar10, 0, 0); + setWidgetPosition(0, ivar9, 0, 0); + setWidgetRGB(new Color(164, 153, 125)); + setWidgetFont(3793); + setWidgetUnknownBoolean(true); + setWidgetTextAlignment(0, 0, 0); + if (((boolean)ivar6)) { + setWidgetText(" " + svar2); + } else { + setWidgetText(svar2); + } + setWidgetText(svar2); + cs2method1305("" + svar0); + setWidgetContextMenuOption(1, "Remove"); + setScriptCallOnClickContextMenu(130, cs2method3633(ivar5), "s"); + if (((boolean)ivar6)) { + ivar7 = add(getTextWidth(3793, "Last known as: " + svar1), 8); + if (ivar7 > getWidgetActualWidth(new WidgetPointer(550,4))) { + svar3 = "Last known as:" + "
" + svar1; + } else { + svar3 = "Last known as: " + svar1; + } + setScriptCallOnMouseOver(1594, new WidgetPointer(550,52), new WidgetPointer(-32768,3), -2147483643, svar3, -2147483647, -2147483646, "IIisii"); + setScriptCallOnMouseExit(40, new WidgetPointer(550,52), "I"); + } + createExtraChild(new WidgetPointer(550,4), 5, add(ivar8, 1)); + setWidgetSprite(2313); + setWidgetSize(14, 14, 0, 0); + setWidgetPosition(0, ivar9, 0, 0); + if (((boolean)ivar6)) { + setWidgetHidden(1); + } + if (mod(ivar5, 2) != 0) { + createExtraChild(new WidgetPointer(550,2), 3, getExtraChildGap(new WidgetPointer(ivar2))); + setWidgetSize(16384, ivar10, 2, 0); + setWidgetPosition(0, ivar9, 0, 0); + setWidgetRGB(new Color(35, 34, 32)); + setWidgetFilled(1); + cs2method2103(128); + } + ivar5 = add(ivar5, 1); + } + while (ivar5 < ivar11) { + ivar9 = multiply(ivar5, ivar10); + if (mod(ivar5, 2) != 0) { + createExtraChild(new WidgetPointer(550,2), 3, getExtraChildGap(new WidgetPointer(ivar2))); + setWidgetSize(16384, ivar10, 2, 0); + setWidgetPosition(0, ivar9, 0, 0); + setWidgetRGB(new Color(35, 34, 32)); + setWidgetFilled(1); + cs2method2103(128); + } + ivar5 = add(ivar5, 1); + } + ivar12 = 0; + ivar13 = 0; + ivar12 = cs2method2601(new WidgetPointer(ivar3)); + ivar13 = multiply(ivar5, ivar10); + setWidgetScrollMax(getWidgetActualWidth(new WidgetPointer(ivar3)), ivar13, new WidgetPointer(ivar3)); + if (ivar12 > ivar13) { + ivar12 = ivar13; + } + script_72(ivar4, ivar3, ivar12); + return; +} diff --git a/dumps/scripts/1290.cs2 b/dumps/scripts/1290.cs2 new file mode 100644 index 0000000..ca5e037 --- /dev/null +++ b/dumps/scripts/1290.cs2 @@ -0,0 +1,252 @@ +void script_1290() { + setWidgetText(new WidgetPointer(130,81), intToStr(bitconfig_861)); + setWidgetText(new WidgetPointer(130,80), intToStr(bitconfig_862)); + if (bitconfig_842 == 2) { + setWidgetModel(8522, new WidgetPointer(130,0)); + setWidgetModel(8523, new WidgetPointer(130,1)); + setWidgetModel(8598, new WidgetPointer(130,40)); + } else if (((boolean)bitconfig_842)) { + setWidgetModel(8521, new WidgetPointer(130,0)); + setWidgetModel(8524, new WidgetPointer(130,1)); + setWidgetModel(8597, new WidgetPointer(130,40)); + } else { + setWidgetModel(-1, new WidgetPointer(130,40)); + setWidgetModel(8522, new WidgetPointer(130,0)); + setWidgetModel(8524, new WidgetPointer(130,1)); + } + if (bitconfig_843 == 2) { + setWidgetModel(8526, new WidgetPointer(130,2)); + setWidgetModel(8527, new WidgetPointer(130,3)); + setWidgetModel(8600, new WidgetPointer(130,41)); + } else if (((boolean)bitconfig_843)) { + setWidgetModel(8525, new WidgetPointer(130,2)); + setWidgetModel(8528, new WidgetPointer(130,3)); + setWidgetModel(8599, new WidgetPointer(130,41)); + } else { + setWidgetModel(-1, new WidgetPointer(130,41)); + setWidgetModel(8526, new WidgetPointer(130,2)); + setWidgetModel(8528, new WidgetPointer(130,3)); + } + if (bitconfig_844 == 2) { + setWidgetModel(8530, new WidgetPointer(130,4)); + setWidgetModel(8531, new WidgetPointer(130,5)); + setWidgetModel(8602, new WidgetPointer(130,42)); + } else if (((boolean)bitconfig_844)) { + setWidgetModel(8529, new WidgetPointer(130,4)); + setWidgetModel(8532, new WidgetPointer(130,5)); + setWidgetModel(8601, new WidgetPointer(130,42)); + } else { + setWidgetModel(-1, new WidgetPointer(130,42)); + setWidgetModel(8530, new WidgetPointer(130,4)); + setWidgetModel(8532, new WidgetPointer(130,5)); + } + if (bitconfig_845 == 2) { + setWidgetModel(8534, new WidgetPointer(130,6)); + setWidgetModel(8535, new WidgetPointer(130,7)); + setWidgetModel(8604, new WidgetPointer(130,43)); + } else if (((boolean)bitconfig_845)) { + setWidgetModel(8533, new WidgetPointer(130,6)); + setWidgetModel(8536, new WidgetPointer(130,7)); + setWidgetModel(8603, new WidgetPointer(130,43)); + } else { + setWidgetModel(-1, new WidgetPointer(130,43)); + setWidgetModel(8534, new WidgetPointer(130,6)); + setWidgetModel(8536, new WidgetPointer(130,7)); + } + if (bitconfig_846 == 2) { + setWidgetModel(8538, new WidgetPointer(130,8)); + setWidgetModel(8539, new WidgetPointer(130,9)); + setWidgetModel(8606, new WidgetPointer(130,44)); + } else if (((boolean)bitconfig_846)) { + setWidgetModel(8537, new WidgetPointer(130,8)); + setWidgetModel(8540, new WidgetPointer(130,9)); + setWidgetModel(8605, new WidgetPointer(130,44)); + } else { + setWidgetModel(-1, new WidgetPointer(130,44)); + setWidgetModel(8538, new WidgetPointer(130,8)); + setWidgetModel(8540, new WidgetPointer(130,9)); + } + if (bitconfig_847 == 2) { + setWidgetModel(8542, new WidgetPointer(130,10)); + setWidgetModel(8543, new WidgetPointer(130,11)); + setWidgetModel(8608, new WidgetPointer(130,45)); + } else if (((boolean)bitconfig_847)) { + setWidgetModel(8541, new WidgetPointer(130,10)); + setWidgetModel(8544, new WidgetPointer(130,11)); + setWidgetModel(8607, new WidgetPointer(130,45)); + } else { + setWidgetModel(-1, new WidgetPointer(130,45)); + setWidgetModel(8542, new WidgetPointer(130,10)); + setWidgetModel(8544, new WidgetPointer(130,11)); + } + if (bitconfig_848 == 2) { + setWidgetModel(8546, new WidgetPointer(130,12)); + setWidgetModel(8547, new WidgetPointer(130,13)); + setWidgetModel(8610, new WidgetPointer(130,46)); + } else if (((boolean)bitconfig_848)) { + setWidgetModel(8545, new WidgetPointer(130,12)); + setWidgetModel(8548, new WidgetPointer(130,13)); + setWidgetModel(8609, new WidgetPointer(130,46)); + } else { + setWidgetModel(-1, new WidgetPointer(130,46)); + setWidgetModel(8546, new WidgetPointer(130,12)); + setWidgetModel(8548, new WidgetPointer(130,13)); + } + if (bitconfig_849 == 2) { + setWidgetModel(8550, new WidgetPointer(130,14)); + setWidgetModel(8551, new WidgetPointer(130,15)); + setWidgetModel(8612, new WidgetPointer(130,47)); + } else if (((boolean)bitconfig_849)) { + setWidgetModel(8549, new WidgetPointer(130,14)); + setWidgetModel(8552, new WidgetPointer(130,15)); + setWidgetModel(8611, new WidgetPointer(130,47)); + } else { + setWidgetModel(-1, new WidgetPointer(130,47)); + setWidgetModel(8550, new WidgetPointer(130,14)); + setWidgetModel(8552, new WidgetPointer(130,15)); + } + if (bitconfig_850 == 2) { + setWidgetModel(8554, new WidgetPointer(130,16)); + setWidgetModel(8555, new WidgetPointer(130,17)); + setWidgetModel(8614, new WidgetPointer(130,48)); + } else if (((boolean)bitconfig_850)) { + setWidgetModel(8553, new WidgetPointer(130,16)); + setWidgetModel(8556, new WidgetPointer(130,17)); + setWidgetModel(8613, new WidgetPointer(130,48)); + } else { + setWidgetModel(-1, new WidgetPointer(130,48)); + setWidgetModel(8554, new WidgetPointer(130,16)); + setWidgetModel(8556, new WidgetPointer(130,17)); + } + if (bitconfig_851 == 2) { + setWidgetModel(8558, new WidgetPointer(130,18)); + setWidgetModel(8559, new WidgetPointer(130,19)); + setWidgetModel(8616, new WidgetPointer(130,49)); + } else if (((boolean)bitconfig_851)) { + setWidgetModel(8557, new WidgetPointer(130,18)); + setWidgetModel(8560, new WidgetPointer(130,19)); + setWidgetModel(8615, new WidgetPointer(130,49)); + } else { + setWidgetModel(-1, new WidgetPointer(130,49)); + setWidgetModel(8558, new WidgetPointer(130,18)); + setWidgetModel(8560, new WidgetPointer(130,19)); + } + if (bitconfig_852 == 2) { + setWidgetModel(8562, new WidgetPointer(130,20)); + setWidgetModel(8563, new WidgetPointer(130,21)); + setWidgetModel(8618, new WidgetPointer(130,50)); + } else if (((boolean)bitconfig_852)) { + setWidgetModel(8561, new WidgetPointer(130,20)); + setWidgetModel(8564, new WidgetPointer(130,21)); + setWidgetModel(8617, new WidgetPointer(130,50)); + } else { + setWidgetModel(-1, new WidgetPointer(130,50)); + setWidgetModel(8562, new WidgetPointer(130,20)); + setWidgetModel(8564, new WidgetPointer(130,21)); + } + if (bitconfig_853 == 2) { + setWidgetModel(8566, new WidgetPointer(130,22)); + setWidgetModel(8567, new WidgetPointer(130,23)); + setWidgetModel(8620, new WidgetPointer(130,51)); + } else if (((boolean)bitconfig_853)) { + setWidgetModel(8565, new WidgetPointer(130,22)); + setWidgetModel(8568, new WidgetPointer(130,23)); + setWidgetModel(8619, new WidgetPointer(130,51)); + } else { + setWidgetModel(-1, new WidgetPointer(130,51)); + setWidgetModel(8566, new WidgetPointer(130,22)); + setWidgetModel(8568, new WidgetPointer(130,23)); + } + if (bitconfig_854 == 2) { + setWidgetModel(8570, new WidgetPointer(130,24)); + setWidgetModel(8571, new WidgetPointer(130,25)); + setWidgetModel(8622, new WidgetPointer(130,52)); + } else if (((boolean)bitconfig_854)) { + setWidgetModel(8569, new WidgetPointer(130,24)); + setWidgetModel(8572, new WidgetPointer(130,25)); + setWidgetModel(8621, new WidgetPointer(130,52)); + } else { + setWidgetModel(-1, new WidgetPointer(130,52)); + setWidgetModel(8570, new WidgetPointer(130,24)); + setWidgetModel(8572, new WidgetPointer(130,25)); + } + if (bitconfig_855 == 2) { + setWidgetModel(8574, new WidgetPointer(130,26)); + setWidgetModel(8575, new WidgetPointer(130,27)); + setWidgetModel(8624, new WidgetPointer(130,53)); + } else if (((boolean)bitconfig_855)) { + setWidgetModel(8573, new WidgetPointer(130,26)); + setWidgetModel(8576, new WidgetPointer(130,27)); + setWidgetModel(8623, new WidgetPointer(130,53)); + } else { + setWidgetModel(-1, new WidgetPointer(130,53)); + setWidgetModel(8574, new WidgetPointer(130,26)); + setWidgetModel(8576, new WidgetPointer(130,27)); + } + if (bitconfig_856 == 2) { + setWidgetModel(8578, new WidgetPointer(130,28)); + setWidgetModel(8579, new WidgetPointer(130,29)); + setWidgetModel(8626, new WidgetPointer(130,54)); + } else if (((boolean)bitconfig_856)) { + setWidgetModel(8577, new WidgetPointer(130,28)); + setWidgetModel(8580, new WidgetPointer(130,29)); + setWidgetModel(8625, new WidgetPointer(130,54)); + } else { + setWidgetModel(-1, new WidgetPointer(130,54)); + setWidgetModel(8578, new WidgetPointer(130,28)); + setWidgetModel(8580, new WidgetPointer(130,29)); + } + if (bitconfig_857 == 2) { + setWidgetModel(8582, new WidgetPointer(130,30)); + setWidgetModel(8583, new WidgetPointer(130,31)); + setWidgetModel(8628, new WidgetPointer(130,55)); + } else if (((boolean)bitconfig_857)) { + setWidgetModel(8581, new WidgetPointer(130,30)); + setWidgetModel(8584, new WidgetPointer(130,31)); + setWidgetModel(8627, new WidgetPointer(130,55)); + } else { + setWidgetModel(-1, new WidgetPointer(130,55)); + setWidgetModel(8582, new WidgetPointer(130,30)); + setWidgetModel(8584, new WidgetPointer(130,31)); + } + if (bitconfig_858 == 2) { + setWidgetModel(8586, new WidgetPointer(130,32)); + setWidgetModel(8587, new WidgetPointer(130,33)); + setWidgetModel(8630, new WidgetPointer(130,56)); + } else if (((boolean)bitconfig_858)) { + setWidgetModel(8585, new WidgetPointer(130,32)); + setWidgetModel(8588, new WidgetPointer(130,33)); + setWidgetModel(8629, new WidgetPointer(130,56)); + } else { + setWidgetModel(-1, new WidgetPointer(130,56)); + setWidgetModel(8586, new WidgetPointer(130,32)); + setWidgetModel(8588, new WidgetPointer(130,33)); + } + if (bitconfig_859 == 2) { + setWidgetModel(8590, new WidgetPointer(130,34)); + setWidgetModel(8591, new WidgetPointer(130,35)); + setWidgetModel(8632, new WidgetPointer(130,57)); + } else if (((boolean)bitconfig_859)) { + setWidgetModel(8589, new WidgetPointer(130,34)); + setWidgetModel(8592, new WidgetPointer(130,35)); + setWidgetModel(8631, new WidgetPointer(130,57)); + } else { + setWidgetModel(-1, new WidgetPointer(130,57)); + setWidgetModel(8590, new WidgetPointer(130,34)); + setWidgetModel(8592, new WidgetPointer(130,35)); + } + if (bitconfig_860 == 2) { + setWidgetModel(8594, new WidgetPointer(130,36)); + setWidgetModel(8595, new WidgetPointer(130,37)); + setWidgetModel(8634, new WidgetPointer(130,58)); + } else if (((boolean)bitconfig_860)) { + setWidgetModel(8593, new WidgetPointer(130,36)); + setWidgetModel(8596, new WidgetPointer(130,37)); + setWidgetModel(8633, new WidgetPointer(130,58)); + } else { + setWidgetModel(-1, new WidgetPointer(130,58)); + setWidgetModel(8594, new WidgetPointer(130,36)); + setWidgetModel(8596, new WidgetPointer(130,37)); + } + return; +} diff --git a/dumps/scripts/1291.cs2 b/dumps/scripts/1291.cs2 new file mode 100644 index 0000000..c14e78a --- /dev/null +++ b/dumps/scripts/1291.cs2 @@ -0,0 +1,121 @@ +void script_1291(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + ivar4 = getWidgetParentId(new WidgetPointer(arg0)); + ivar5 = 0; + switch (arg1) { + case 5341: + ivar5 = bitconfig_1435; + setWidgetText(new WidgetPointer(arg3), getItemName(arg1) + "
" + "(" + intToStr(ivar5) + "/" + intToStr(arg2) + ")"); + break; + case 5343: + ivar5 = bitconfig_1436; + setWidgetText(new WidgetPointer(arg3), "Dibber" + "
" + "(" + intToStr(ivar5) + "/" + intToStr(arg2) + ")"); + break; + case 952: + ivar5 = bitconfig_1437; + setWidgetText(new WidgetPointer(arg3), getItemName(arg1) + "
" + "(" + intToStr(ivar5) + "/" + intToStr(arg2) + ")"); + break; + case 5325: + ivar5 = bitconfig_1440; + setWidgetText(new WidgetPointer(arg3), "Trowel" + "
" + "(" + intToStr(ivar5) + "/" + intToStr(arg2) + ")"); + break; + case 6059: + ivar5 = bitconfig_1778; + setWidgetText(new WidgetPointer(arg3), getItemName(arg1) + "
" + "(" + intToStr(ivar5) + "/" + intToStr(arg2) + ")"); + break; + case 1925: + ivar5 = bitconfig_1441; + setWidgetText(new WidgetPointer(arg3), getItemName(arg1) + "
" + "(" + intToStr(ivar5) + "/" + intToStr(arg2) + ")"); + break; + case 6032: + ivar5 = bitconfig_1442; + setWidgetText(new WidgetPointer(arg3), getItemName(arg1) + "
" + "(" + intToStr(ivar5) + "/" + intToStr(arg2) + ")"); + break; + case 6034: + ivar5 = bitconfig_1443; + setWidgetText(new WidgetPointer(arg3), getItemName(arg1) + "
" + "(" + intToStr(ivar5) + "/" + intToStr(arg2) + ")"); + break; + case 5329: + ivar5 = bitconfig_1438; + setWidgetText(new WidgetPointer(arg3), getItemName(arg1) + "
" + "(" + intToStr(ivar5) + "/" + intToStr(arg2) + ")"); + if (((boolean)bitconfig_1848)) { + arg1 = 7409; + } + break; + case 6797: + switch (bitconfig_1439) { + case 10: + arg1 = 18682; + ivar5 = 1; + setWidgetText(new WidgetPointer(arg3), "Magic watering can" + "
" + "(1/1)"); + cs2method2305(new WidgetPointer(arg0), "" + "Magic watering can"); + break; + case 9: + arg1 = 5340; + ivar5 = 1; + setWidgetText(new WidgetPointer(arg3), "Watering can (8)" + "
" + "(1/1)"); + cs2method2305(new WidgetPointer(arg0), "" + "Watering can (8)"); + break; + case 8: + arg1 = 5339; + ivar5 = 1; + setWidgetText(new WidgetPointer(arg3), "Watering can (7)" + "
" + "(1/1)"); + cs2method2305(new WidgetPointer(arg0), "" + "Watering can (7)"); + break; + case 7: + arg1 = 5338; + ivar5 = 1; + setWidgetText(new WidgetPointer(arg3), "Watering can (6)" + "
" + "(1/1)"); + cs2method2305(new WidgetPointer(arg0), "" + "Watering can (6)"); + break; + case 6: + arg1 = 5337; + ivar5 = 1; + setWidgetText(new WidgetPointer(arg3), "Watering can (5)" + "
" + "(1/1)"); + cs2method2305(new WidgetPointer(arg0), "" + "Watering can (5)"); + break; + case 5: + arg1 = 5336; + ivar5 = 1; + setWidgetText(new WidgetPointer(arg3), "Watering can (4)" + "
" + "(1/1)"); + cs2method2305(new WidgetPointer(arg0), "" + "Watering can (4)"); + break; + case 4: + arg1 = 5335; + ivar5 = 1; + setWidgetText(new WidgetPointer(arg3), "Watering can (3)" + "
" + "(1/1)"); + cs2method2305(new WidgetPointer(arg0), "" + "Watering can (3)"); + break; + case 3: + arg1 = 5334; + ivar5 = 1; + setWidgetText(new WidgetPointer(arg3), "Watering can (2)" + "
" + "(1/1)"); + cs2method2305(new WidgetPointer(arg0), "" + "Watering can (2)"); + break; + case 2: + arg1 = 5333; + ivar5 = 1; + setWidgetText(new WidgetPointer(arg3), "Watering can (1)" + "
" + "(1/1)"); + cs2method2305(new WidgetPointer(arg0), "" + "Watering can (1)"); + break; + case 1: + arg1 = 5331; + ivar5 = 1; + setWidgetText(new WidgetPointer(arg3), "Watering can (0)" + "
" + "(1/1)"); + cs2method2305(new WidgetPointer(arg0), "" + "Watering can (0)"); + break; + } + ivar5 = 0; + setWidgetText(new WidgetPointer(arg3), "Watering can" + "
" + "(0/1)"); + cs2method2305(new WidgetPointer(arg0), "" + "Watering can"); + } + setItemOnWidgetMethod2205(arg1, -1, new WidgetPointer(arg0)); + setWidgetBorderThickness(1, new WidgetPointer(arg0)); + if (ivar5 > 0) { + setWidgetRGB(new Color(125, 215, 100), new WidgetPointer(arg3)); + } else { + setWidgetRGB(new Color(135, 35, 0), new WidgetPointer(arg3)); + } + return; +} diff --git a/dumps/scripts/1292.cs2 b/dumps/scripts/1292.cs2 new file mode 100644 index 0000000..c58a367 --- /dev/null +++ b/dumps/scripts/1292.cs2 @@ -0,0 +1,76 @@ +void script_1292(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + ivar3 = getWidgetParentId(new WidgetPointer(arg0)); + if (arg1 == 5329) { + if (getItemAmtInContainer(93, 7409) > 0) { + arg1 = 7409; + } + } else { + if (arg1 == 6797) { + if (getItemAmtInContainer(93, 18682) > 0) { + arg1 = 18682; + cs2method2305(new WidgetPointer(arg0), "" + "Magic watering can"); + } else if (getItemAmtInContainer(93, 5340) > 0) { + arg1 = 5340; + cs2method2305(new WidgetPointer(arg0), "" + "Watering can (8)"); + } else if (getItemAmtInContainer(93, 5339) > 0) { + arg1 = 5339; + cs2method2305(new WidgetPointer(arg0), "" + "Watering can (7)"); + } else if (getItemAmtInContainer(93, 5338) > 0) { + arg1 = 5338; + cs2method2305(new WidgetPointer(arg0), "" + "Watering can (6)"); + } else if (getItemAmtInContainer(93, 5337) > 0) { + arg1 = 5337; + cs2method2305(new WidgetPointer(arg0), "" + "Watering can (5)"); + } else if (getItemAmtInContainer(93, 5336) > 0) { + arg1 = 5336; + cs2method2305(new WidgetPointer(arg0), "" + "Watering can (4)"); + } else if (getItemAmtInContainer(93, 5335) > 0) { + arg1 = 5335; + cs2method2305(new WidgetPointer(arg0), "" + "Watering can (3)"); + } else if (getItemAmtInContainer(93, 5334) > 0) { + arg1 = 5334; + cs2method2305(new WidgetPointer(arg0), "" + "Watering can (2)"); + } else if (getItemAmtInContainer(93, 5333) > 0) { + arg1 = 5333; + cs2method2305(new WidgetPointer(arg0), "" + "Watering can (1)"); + } else if (getItemAmtInContainer(93, 5331) > 0) { + arg1 = 5331; + cs2method2305(new WidgetPointer(arg0), "" + "Watering can (0)"); + } else { + cs2method2305(new WidgetPointer(arg0), "" + "Watering can"); + } + } + } + ivar4 = 0; + switch (arg1) { + case 5329: + case 7409: + ivar4 = add(getItemAmtInContainer(93, 5329), getItemAmtInContainer(93, 7409)); + break; + case 5333: + case 6797: + case 5335: + case 5334: + case 5331: + case 5340: + case 5337: + case 5336: + case 5339: + case 5338: + ivar4 = add(add(add(add(add(add(add(add(add(getItemAmtInContainer(93, 18682), getItemAmtInContainer(93, 5340)), getItemAmtInContainer(93, 5339)), getItemAmtInContainer(93, 5338)), getItemAmtInContainer(93, 5337)), getItemAmtInContainer(93, 5336)), getItemAmtInContainer(93, 5335)), getItemAmtInContainer(93, 5334)), getItemAmtInContainer(93, 5333)), getItemAmtInContainer(93, 5331)); + break; + default: + ivar4 = getItemAmtInContainer(93, arg1); + } + if (ivar4 > 0) { + setWidgetRGB(new Color(125, 215, 100), new WidgetPointer(arg2)); + setItemOnWidgetMethod2200(arg1, ivar4, new WidgetPointer(arg0)); + } else { + setWidgetRGB(new Color(135, 35, 0), new WidgetPointer(arg2)); + setItemOnWidgetMethod2200(arg1, -1, new WidgetPointer(arg0)); + } + setWidgetBorderThickness(1, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1293.cs2 b/dumps/scripts/1293.cs2 new file mode 100644 index 0000000..eb38b33 --- /dev/null +++ b/dumps/scripts/1293.cs2 @@ -0,0 +1,51 @@ +void script_1293(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + deleteAllExtraChilds(new WidgetPointer(arg0)); + ivar1 = 5; + ivar2 = 34; + ivar3 = 34; + ivar4 = 0; + ivar5 = 6; + ivar6 = ivar5; + ivar7 = 3; + ivar8 = add(34, 3); + if (((boolean)globalint_1052) && ((boolean)bitconfig_6840)) { + ivar5 = 3; + ivar6 = ivar5; + ivar8 = add(34, 0); + } + ivar9 = add(34, 2); + if (((boolean)globalint_181)) { + ivar5 = 6; + ivar6 = ivar5; + ivar7 = 28; + ivar8 = add(34, 5); + ivar9 = add(34, 3); + } + ivar10 = 30; + if (((boolean)bitconfig_6840)) { + ivar10 = 20; + } + while (ivar4 < ivar10) { + createExtraChild(new WidgetPointer(arg0), 5, ivar4); + setWidgetSize(ivar2, ivar3, 0, 0); + setWidgetPosition(ivar6, ivar7, 0, 0); + ivar4 = add(ivar4, 1); + if (((boolean)mod(ivar4, ivar1))) { + ivar6 = ivar5; + ivar7 = add(ivar7, ivar9); + } else { + ivar6 = add(ivar6, ivar8); + } + } + return; +} diff --git a/dumps/scripts/1294.cs2 b/dumps/scripts/1294.cs2 new file mode 100644 index 0000000..9c228f5 --- /dev/null +++ b/dumps/scripts/1294.cs2 @@ -0,0 +1,59 @@ +void script_1294() { + if (isBitFlagged(standart_config_383, 1)) { + setWidgetModel(4912, new WidgetPointer(144,134)); + } + if (isBitFlagged(standart_config_383, 2)) { + setWidgetModel(4912, new WidgetPointer(144,135)); + } + if (isBitFlagged(standart_config_383, 3)) { + setWidgetModel(4913, new WidgetPointer(144,136)); + } + if (isBitFlagged(standart_config_383, 4)) { + setWidgetModel(4912, new WidgetPointer(144,137)); + } + if (isBitFlagged(standart_config_383, 5)) { + setWidgetModel(4912, new WidgetPointer(144,138)); + } + if (isBitFlagged(standart_config_383, 6)) { + setWidgetModel(4913, new WidgetPointer(144,139)); + } + if (isBitFlagged(standart_config_383, 7)) { + setWidgetModel(4913, new WidgetPointer(144,140)); + } + if (isBitFlagged(standart_config_383, 8)) { + setWidgetModel(4912, new WidgetPointer(144,141)); + } + if (standart_config_383 > 8191) { + setWidgetIsHidden(true, new WidgetPointer(144,186)); + setWidgetSprite(296, new WidgetPointer(144,146)); + } + if (isBitFlagged(standart_config_383, 14)) { + setWidgetModel(4910, new WidgetPointer(144,174)); + setWidgetAnimation(1456, new WidgetPointer(144,174)); + } + if (isBitFlagged(standart_config_383, 15)) { + setWidgetModel(4910, new WidgetPointer(144,172)); + setWidgetAnimation(1456, new WidgetPointer(144,172)); + } + if (isBitFlagged(standart_config_383, 16)) { + setWidgetModel(4910, new WidgetPointer(144,176)); + setWidgetAnimation(1456, new WidgetPointer(144,176)); + } + if (isBitFlagged(standart_config_383, 17)) { + setWidgetModel(4910, new WidgetPointer(144,178)); + setWidgetAnimation(1455, new WidgetPointer(144,178)); + } + if (isBitFlagged(standart_config_383, 18)) { + setWidgetModel(4910, new WidgetPointer(144,180)); + setWidgetAnimation(1455, new WidgetPointer(144,180)); + } + if (isBitFlagged(standart_config_383, 19)) { + setWidgetModel(4910, new WidgetPointer(144,183)); + setWidgetAnimation(1453, new WidgetPointer(144,183)); + } + if (isBitFlagged(standart_config_383, 20)) { + setWidgetModel(4910, new WidgetPointer(144,185)); + setWidgetAnimation(1453, new WidgetPointer(144,185)); + } + return; +} diff --git a/dumps/scripts/1295.cs2 b/dumps/scripts/1295.cs2 new file mode 100644 index 0000000..da59cf9 --- /dev/null +++ b/dumps/scripts/1295.cs2 @@ -0,0 +1,8 @@ +void script_1295() { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(144,147)); + setScriptCallOnMouseExit(45, new WidgetPointer(-32768,3), 16711680, "Ii", new WidgetPointer(144,147)); + setWidgetIsHidden(true, new WidgetPointer(144,186)); + setWidgetModel(4910, new WidgetPointer(144,187)); + setWidgetAnimation(1453, new WidgetPointer(144,187)); + return; +} diff --git a/dumps/scripts/1296.cs2 b/dumps/scripts/1296.cs2 new file mode 100644 index 0000000..392620b --- /dev/null +++ b/dumps/scripts/1296.cs2 @@ -0,0 +1,7 @@ +void script_1296() { + if (getDisplayMode() >= 2) { + setWidget3DRotation(0, 0, 89, 67, 0, 300, new WidgetPointer(584,2)); + setWidget3DRotation(0, 0, 89, 67, 0, 300, new WidgetPointer(584,1)); + } + return; +} diff --git a/dumps/scripts/1297.cs2 b/dumps/scripts/1297.cs2 new file mode 100644 index 0000000..e7afa6e --- /dev/null +++ b/dumps/scripts/1297.cs2 @@ -0,0 +1,8 @@ +void script_1297() { + script_1264(); + script_1265(); + script_1269(); + script_1272(); + script_4143(); + return; +} diff --git a/dumps/scripts/1298.cs2 b/dumps/scripts/1298.cs2 new file mode 100644 index 0000000..82f24d1 --- /dev/null +++ b/dumps/scripts/1298.cs2 @@ -0,0 +1,5 @@ +void script_1298(int arg0,int arg1,int arg2,int arg3) { + deleteAllExtraChilds(new WidgetPointer(arg0)); + script_2786(arg0, arg1, arg2, arg3); + return; +} diff --git a/dumps/scripts/1299.cs2 b/dumps/scripts/1299.cs2 new file mode 100644 index 0000000..2b3f29c --- /dev/null +++ b/dumps/scripts/1299.cs2 @@ -0,0 +1,86 @@ +void script_1299(int arg0,int arg1) { + int ivar2; + string svar0; + flow_0: + if (((boolean)arg1)) { + script_2710(59375640, 59375641, 59375642, 59703312, 59703318, 59703317); + } + setWidgetSprite(4140, new WidgetPointer(906,248)); + setWidgetSprite(4139, new WidgetPointer(906,249)); + setWidgetSprite(4141, new WidgetPointer(906,250)); + setWidgetSprite(4142, new WidgetPointer(906,251)); + setWidgetSprite(4144, new WidgetPointer(906,252)); + setWidgetSprite(4143, new WidgetPointer(906,253)); + setWidgetSprite(4145, new WidgetPointer(906,254)); + setWidgetSprite(4146, new WidgetPointer(906,255)); + setWidgetSprite(4129, new WidgetPointer(906,257)); + setWidgetSprite(4129, new WidgetPointer(906,259)); + setWidgetSprite(4129, new WidgetPointer(906,262)); + setWidgetSprite(4065, new WidgetPointer(906,226)); + setWidgetVFlip(1, new WidgetPointer(906,226)); + setWidgetHFlip(1, new WidgetPointer(906,226)); + setWidgetSprite(4065, new WidgetPointer(906,230)); + setWidgetVFlip(1, new WidgetPointer(906,230)); + setWidgetHFlip(0, new WidgetPointer(906,230)); + setWidgetSprite(4065, new WidgetPointer(906,227)); + setWidgetVFlip(0, new WidgetPointer(906,227)); + setWidgetHFlip(1, new WidgetPointer(906,227)); + setWidgetSprite(4065, new WidgetPointer(906,231)); + setWidgetVFlip(0, new WidgetPointer(906,231)); + setWidgetHFlip(0, new WidgetPointer(906,231)); + setScriptCallOnWidgetResize(4040, "", new WidgetPointer(906,23)); + ivar2 = strIndexof(0, globalstring_32, "@"); + if (ivar2 == -1) { + globalint_1414 = 1; + } else { + globalint_1414 = 2; + } + IF (((boolean)cs2method6912())) + GOTO flow_6 + IF (((boolean)stringMethod4107(substr(0, 1, cs2method5020()), "#")) && ((boolean)arg0)) + GOTO flow_7 + GOTO flow_12 + flow_6: + flow_7: + globalint_1322 = 1; + globalint_200 = 0; + script_3093(-3, 0, 1, -1, 0, -1, 0, "Logging In - Please Wait", "", "", "", ""); + globalint_1100 = -3; + if (arg1 < 50) { + arg1 = add(arg1, 1); + setScriptCallOnGameloop(3057, 0, arg1, "1i", new WidgetPointer(906,23)); + return; + } + if (cs2method6500()) { + setScriptCallOnGameloop(3057, 0, arg1, "1i", new WidgetPointer(906,23)); + return; + } + setScriptCallOnGameloop(-1, "", new WidgetPointer(906,23)); + cs2method5612(0); + setScriptCallOnGameloop(3063, new WidgetPointer(906,23), getWorldId(), "Ii", new WidgetPointer(906,23)); + return; + flow_12: + setWidgetIsHidden(false, new WidgetPointer(906,27)); + setWidgetIsHidden(true, new WidgetPointer(906,41)); + script_3097(); + script_3058(); + script_3060(0); + script_3064(1); + globalstring_277 = ""; + globalint_547 = 0; + messageType0("Welcome to the RuneScape Lobby."); + message(43, 0, "Welcome to the RuneScape Lobby."); + if (cs2method6900()) { + messageType0("Users restricted to quick-chat cannot send messages from the Lobby."); + message(43, 0, "Users restricted to quick-chat cannot send messages from the Lobby."); + } + script_51(); + setScriptCallOnKeyPress(1328, -2147483640, "i", new WidgetPointer(906,23)); + svar0 = script_2781(); + if (strLength(svar0) > 0) { + script_2779(-3000, 0, 0, 2607, 1, 0, 1, 350, svar0 + "
" + " ", "Re-Subscribe Now", "Re-Subscribe Now", "Close", "Close"); + } + setScriptCallOnGameloop(1868, new WidgetPointer(906,28), "I", new WidgetPointer(906,28)); + script_4041(); + return; +} diff --git a/dumps/scripts/13.cs2 b/dumps/scripts/13.cs2 new file mode 100644 index 0000000..494cb5c --- /dev/null +++ b/dumps/scripts/13.cs2 @@ -0,0 +1,131 @@ +cs2func_script_13_struct(1,1,0) script_13(int arg0,int arg1) { + int stack_dump0; + cs2func_script_981_struct(1,1,0) structdump_1; + cs2func_script_983_struct(1,1,0) structdump_2; + cs2func_script_977_struct(1,1,0) structdump_3; + cs2func_script_1009_struct(1,1,0) structdump_4; + cs2func_script_1003_struct(1,1,0) structdump_5; + cs2func_script_995_struct(1,1,0) structdump_6; + cs2func_script_993_struct(1,1,0) structdump_7; + cs2func_script_1007_struct(1,1,0) structdump_8; + cs2func_script_1001_struct(1,1,0) structdump_9; + cs2func_script_991_struct(1,1,0) structdump_10; + cs2func_script_999_struct(1,1,0) structdump_11; + cs2func_script_979_struct(1,1,0) structdump_12; + cs2func_script_1015_struct(1,1,0) structdump_13; + cs2func_script_1021_struct(1,1,0) structdump_14; + cs2func_script_997_struct(1,1,0) structdump_15; + cs2func_script_1017_struct(1,1,0) structdump_16; + cs2func_script_985_struct(1,1,0) structdump_17; + cs2func_script_989_struct(1,1,0) structdump_18; + cs2func_script_1011_struct(1,1,0) structdump_19; + cs2func_script_987_struct(1,1,0) structdump_20; + cs2func_script_1013_struct(1,1,0) structdump_21; + cs2func_script_2_struct(1,1,0) structdump_22; + cs2func_script_1005_struct(1,1,0) structdump_23; + cs2func_script_1019_struct(1,1,0) structdump_24; + cs2func_script_3354_struct(1,1,0) structdump_25; + switch (arg0) { + case 1: + stack_dump0 = arg1; + structdump_1 = script_981(stack_dump0); + return newstruct cs2func_script_13_struct(structdump_1.intpart_0, structdump_1.stringpart_0); + case 2: + stack_dump0 = arg1; + structdump_2 = script_983(stack_dump0); + return newstruct cs2func_script_13_struct(structdump_2.intpart_0, structdump_2.stringpart_0); + case 5: + stack_dump0 = arg1; + structdump_3 = script_977(stack_dump0); + return newstruct cs2func_script_13_struct(structdump_3.intpart_0, structdump_3.stringpart_0); + case 3: + stack_dump0 = arg1; + structdump_4 = script_1009(stack_dump0); + return newstruct cs2func_script_13_struct(structdump_4.intpart_0, structdump_4.stringpart_0); + case 7: + stack_dump0 = arg1; + structdump_5 = script_1003(stack_dump0); + return newstruct cs2func_script_13_struct(structdump_5.intpart_0, structdump_5.stringpart_0); + case 4: + stack_dump0 = arg1; + structdump_6 = script_995(stack_dump0); + return newstruct cs2func_script_13_struct(structdump_6.intpart_0, structdump_6.stringpart_0); + case 6: + stack_dump0 = arg1; + structdump_7 = script_993(stack_dump0); + return newstruct cs2func_script_13_struct(structdump_7.intpart_0, structdump_7.stringpart_0); + case 8: + stack_dump0 = arg1; + structdump_8 = script_1007(stack_dump0); + return newstruct cs2func_script_13_struct(structdump_8.intpart_0, structdump_8.stringpart_0); + case 9: + stack_dump0 = arg1; + structdump_9 = script_1001(stack_dump0); + return newstruct cs2func_script_13_struct(structdump_9.intpart_0, structdump_9.stringpart_0); + case 10: + stack_dump0 = arg1; + structdump_10 = script_991(stack_dump0); + return newstruct cs2func_script_13_struct(structdump_10.intpart_0, structdump_10.stringpart_0); + case 11: + stack_dump0 = arg1; + structdump_11 = script_999(stack_dump0); + return newstruct cs2func_script_13_struct(structdump_11.intpart_0, structdump_11.stringpart_0); + case 19: + stack_dump0 = arg1; + structdump_12 = script_979(stack_dump0); + return newstruct cs2func_script_13_struct(structdump_12.intpart_0, structdump_12.stringpart_0); + case 13: + stack_dump0 = arg1; + structdump_13 = script_1015(stack_dump0); + return newstruct cs2func_script_13_struct(structdump_13.intpart_0, structdump_13.stringpart_0); + case 14: + stack_dump0 = arg1; + structdump_14 = script_1021(stack_dump0); + return newstruct cs2func_script_13_struct(structdump_14.intpart_0, structdump_14.stringpart_0); + case 15: + stack_dump0 = arg1; + structdump_15 = script_997(stack_dump0); + return newstruct cs2func_script_13_struct(structdump_15.intpart_0, structdump_15.stringpart_0); + case 16: + stack_dump0 = arg1; + structdump_16 = script_1017(stack_dump0); + return newstruct cs2func_script_13_struct(structdump_16.intpart_0, structdump_16.stringpart_0); + case 17: + stack_dump0 = arg1; + structdump_17 = script_985(stack_dump0); + return newstruct cs2func_script_13_struct(structdump_17.intpart_0, structdump_17.stringpart_0); + case 18: + stack_dump0 = arg1; + structdump_18 = script_989(stack_dump0); + return newstruct cs2func_script_13_struct(structdump_18.intpart_0, structdump_18.stringpart_0); + case 12: + stack_dump0 = arg1; + structdump_19 = script_1011(stack_dump0); + return newstruct cs2func_script_13_struct(structdump_19.intpart_0, structdump_19.stringpart_0); + case 20: + stack_dump0 = arg1; + structdump_20 = script_987(stack_dump0); + return newstruct cs2func_script_13_struct(structdump_20.intpart_0, structdump_20.stringpart_0); + case 21: + stack_dump0 = arg1; + structdump_21 = script_1013(stack_dump0); + return newstruct cs2func_script_13_struct(structdump_21.intpart_0, structdump_21.stringpart_0); + case 22: + stack_dump0 = arg1; + structdump_22 = script_2(stack_dump0); + return newstruct cs2func_script_13_struct(structdump_22.intpart_0, structdump_22.stringpart_0); + case 23: + stack_dump0 = arg1; + structdump_23 = script_1005(stack_dump0); + return newstruct cs2func_script_13_struct(structdump_23.intpart_0, structdump_23.stringpart_0); + case 24: + stack_dump0 = arg1; + structdump_24 = script_1019(stack_dump0); + return newstruct cs2func_script_13_struct(structdump_24.intpart_0, structdump_24.stringpart_0); + case 25: + stack_dump0 = arg1; + structdump_25 = script_3354(stack_dump0); + return newstruct cs2func_script_13_struct(structdump_25.intpart_0, structdump_25.stringpart_0); + } + return newstruct cs2func_script_13_struct(-1, ""); +} diff --git a/dumps/scripts/130.cs2 b/dumps/scripts/130.cs2 new file mode 100644 index 0000000..4bcd9dd --- /dev/null +++ b/dumps/scripts/130.cs2 @@ -0,0 +1,4 @@ +void script_130(string arg0) { + cs2method3608(strRemoveEntities(arg0)); + return; +} diff --git a/dumps/scripts/1300.cs2 b/dumps/scripts/1300.cs2 new file mode 100644 index 0000000..a621703 --- /dev/null +++ b/dumps/scripts/1300.cs2 @@ -0,0 +1,4 @@ +void script_1300(int arg0,int arg1) { + script_1301(arg0, arg1); + return; +} diff --git a/dumps/scripts/1301.cs2 b/dumps/scripts/1301.cs2 new file mode 100644 index 0000000..6e39efe --- /dev/null +++ b/dumps/scripts/1301.cs2 @@ -0,0 +1,22 @@ +void script_1301(int arg0,int arg1) { + int ivar2; + ivar2 = 0; + if (getDisplayMode() >= 2) { + script_31(arg0, arg1, 883, 802, 881, 882, 641, 642); + while (ivar2 < getExtraChildGap(new WidgetPointer(arg0))) { + if (setWidgetRegister(new WidgetPointer(arg0), ivar2)) { + cs2method1122(1); + } + ivar2 = add(ivar2, 1); + } + } else { + script_31(arg0, arg1, 792, 789, 790, 791, 773, 788); + while (ivar2 < getExtraChildGap(new WidgetPointer(arg0))) { + if (setWidgetRegister(new WidgetPointer(arg0), ivar2)) { + cs2method1122(0); + } + ivar2 = add(ivar2, 1); + } + } + return; +} diff --git a/dumps/scripts/1302.cs2 b/dumps/scripts/1302.cs2 new file mode 100644 index 0000000..e9f9028 --- /dev/null +++ b/dumps/scripts/1302.cs2 @@ -0,0 +1,4 @@ +void script_1302() { + script_71(globalint_168); + return; +} diff --git a/dumps/scripts/1303.cs2 b/dumps/scripts/1303.cs2 new file mode 100644 index 0000000..d034d3c --- /dev/null +++ b/dumps/scripts/1303.cs2 @@ -0,0 +1,10 @@ +void script_1303(int arg0) { + globalint_10 = 0; + script_1304(arg0); + if (globalint_168 == arg0) { + globalint_168 = -1; + } else { + globalint_168 = arg0; + } + return; +} diff --git a/dumps/scripts/1304.cs2 b/dumps/scripts/1304.cs2 new file mode 100644 index 0000000..e37441e --- /dev/null +++ b/dumps/scripts/1304.cs2 @@ -0,0 +1,27 @@ +void script_1304(int arg0) { + int ivar1; + ivar1 = script_1305(); + if (((boolean)script_2709()) && (((arg0 == 9) || (arg0 == 11)) || (arg0 == 10))) { + return; + } + if ((arg0 == ivar1) && ((boolean)bitconfig_9030)) { + arg0 = 1; + script_4089(); + } + if (ivar1 > -1) { + if (ivar1 == arg0) { + if ((getDisplayMode() >= 2) && ((boolean)bitconfig_9030)) { + script_1306(); + } else { + return; + } + } else { + script_1306(); + script_1387(arg0); + } + } else { + script_1306(); + script_1387(arg0); + } + return; +} diff --git a/dumps/scripts/1305.cs2 b/dumps/scripts/1305.cs2 new file mode 100644 index 0000000..8ca17f8 --- /dev/null +++ b/dumps/scripts/1305.cs2 @@ -0,0 +1,20 @@ +int script_1305() { + int ivar0; + ivar0 = 0; + if (((boolean)script_1314(99))) { + return 99; + } + if (((boolean)script_1314(95))) { + return 95; + } + if (((boolean)script_1314(98))) { + return 98; + } + while (ivar0 < 16) { + if (((boolean)script_1314(ivar0))) { + return ivar0; + } + ivar0 = add(ivar0, 1); + } + return -1; +} diff --git a/dumps/scripts/1306.cs2 b/dumps/scripts/1306.cs2 new file mode 100644 index 0000000..6a80992 --- /dev/null +++ b/dumps/scripts/1306.cs2 @@ -0,0 +1,8 @@ +void script_1306() { + if (getDisplayMode() >= 2) { + script_1385(); + } else { + script_1386(); + } + return; +} diff --git a/dumps/scripts/1307.cs2 b/dumps/scripts/1307.cs2 new file mode 100644 index 0000000..6369721 --- /dev/null +++ b/dumps/scripts/1307.cs2 @@ -0,0 +1,6 @@ +void script_1307(int arg0) { + if (((boolean)bitconfig_7912) || (((bitconfig_7904 == 8) && ((boolean)bitconfig_7921)) && ((boolean)bitconfig_7916))) { + setWidgetModel(getWidgetModelId(new WidgetPointer(arg0)), new WidgetPointer(986,3)); + } + return; +} diff --git a/dumps/scripts/1308.cs2 b/dumps/scripts/1308.cs2 new file mode 100644 index 0000000..e5604e5 --- /dev/null +++ b/dumps/scripts/1308.cs2 @@ -0,0 +1,23 @@ +void script_1308() { + setWidgetIsHidden(true, new WidgetPointer(746,90)); + setWidgetIsHidden(true, new WidgetPointer(746,91)); + setWidgetIsHidden(true, new WidgetPointer(746,92)); + setWidgetIsHidden(true, new WidgetPointer(746,93)); + setWidgetIsHidden(true, new WidgetPointer(746,94)); + setWidgetIsHidden(true, new WidgetPointer(746,95)); + setWidgetIsHidden(true, new WidgetPointer(746,96)); + setWidgetIsHidden(true, new WidgetPointer(746,97)); + setWidgetIsHidden(true, new WidgetPointer(746,98)); + setWidgetIsHidden(true, new WidgetPointer(746,99)); + setWidgetIsHidden(true, new WidgetPointer(746,100)); + setWidgetIsHidden(true, new WidgetPointer(746,101)); + setWidgetIsHidden(true, new WidgetPointer(746,102)); + setWidgetIsHidden(true, new WidgetPointer(746,103)); + setWidgetIsHidden(true, new WidgetPointer(746,104)); + setWidgetIsHidden(true, new WidgetPointer(746,105)); + setWidgetIsHidden(true, new WidgetPointer(746,107)); + setWidgetIsHidden(true, new WidgetPointer(746,108)); + setWidgetIsHidden(true, new WidgetPointer(746,86)); + setWidgetIsHidden(true, new WidgetPointer(746,88)); + return; +} diff --git a/dumps/scripts/1309.cs2 b/dumps/scripts/1309.cs2 new file mode 100644 index 0000000..a741e56 --- /dev/null +++ b/dumps/scripts/1309.cs2 @@ -0,0 +1,136 @@ +void script_1309(int arg0) { + int ivar1; + ivar1 = script_1305(); + if (((boolean)arg0)) { + if (ivar1 != 0) { + setWidgetSprite(-1, new WidgetPointer(746,39)); + setWidgetSprite(-1, new WidgetPointer(746,132)); + setWidgetSprite(-1, new WidgetPointer(746,133)); + } + if (ivar1 != 2) { + setWidgetSprite(-1, new WidgetPointer(746,40)); + setWidgetSprite(-1, new WidgetPointer(746,134)); + setWidgetSprite(-1, new WidgetPointer(746,135)); + } + if (ivar1 != 3) { + setWidgetSprite(-1, new WidgetPointer(746,41)); + setWidgetSprite(-1, new WidgetPointer(746,136)); + setWidgetSprite(-1, new WidgetPointer(746,137)); + } + if (ivar1 != 1) { + setWidgetSprite(-1, new WidgetPointer(746,42)); + setWidgetSprite(-1, new WidgetPointer(746,138)); + setWidgetSprite(-1, new WidgetPointer(746,139)); + } + if (ivar1 != 4) { + setWidgetSprite(-1, new WidgetPointer(746,43)); + setWidgetSprite(-1, new WidgetPointer(746,140)); + setWidgetSprite(-1, new WidgetPointer(746,141)); + } + if (ivar1 != 5) { + setWidgetSprite(-1, new WidgetPointer(746,44)); + setWidgetSprite(-1, new WidgetPointer(746,142)); + setWidgetSprite(-1, new WidgetPointer(746,143)); + } + if (ivar1 != 6) { + setWidgetSprite(-1, new WidgetPointer(746,45)); + setWidgetSprite(-1, new WidgetPointer(746,144)); + setWidgetSprite(-1, new WidgetPointer(746,145)); + } + if (ivar1 != 7) { + setWidgetSprite(-1, new WidgetPointer(746,46)); + setWidgetSprite(-1, new WidgetPointer(746,146)); + setWidgetSprite(-1, new WidgetPointer(746,147)); + } + if (ivar1 != 8) { + setWidgetSprite(-1, new WidgetPointer(746,47)); + setWidgetSprite(-1, new WidgetPointer(746,148)); + setWidgetSprite(-1, new WidgetPointer(746,149)); + } + if (ivar1 != 9) { + setWidgetSprite(-1, new WidgetPointer(746,48)); + setWidgetSprite(-1, new WidgetPointer(746,150)); + setWidgetSprite(-1, new WidgetPointer(746,151)); + } + if (ivar1 != 10) { + setWidgetSprite(-1, new WidgetPointer(746,49)); + setWidgetSprite(-1, new WidgetPointer(746,152)); + setWidgetSprite(-1, new WidgetPointer(746,153)); + } + if (ivar1 != 11) { + setWidgetSprite(-1, new WidgetPointer(746,50)); + setWidgetSprite(-1, new WidgetPointer(746,154)); + setWidgetSprite(-1, new WidgetPointer(746,155)); + } + if (ivar1 != 12) { + setWidgetSprite(-1, new WidgetPointer(746,51)); + setWidgetSprite(-1, new WidgetPointer(746,156)); + setWidgetSprite(-1, new WidgetPointer(746,157)); + } + if (ivar1 != 13) { + setWidgetSprite(-1, new WidgetPointer(746,52)); + setWidgetSprite(-1, new WidgetPointer(746,158)); + setWidgetSprite(-1, new WidgetPointer(746,159)); + } + if (ivar1 != 14) { + setWidgetSprite(-1, new WidgetPointer(746,53)); + setWidgetSprite(-1, new WidgetPointer(746,160)); + setWidgetSprite(-1, new WidgetPointer(746,161)); + } + if (ivar1 != 15) { + setWidgetSprite(-1, new WidgetPointer(746,54)); + setWidgetSprite(-1, new WidgetPointer(746,162)); + setWidgetSprite(-1, new WidgetPointer(746,163)); + } + } else { + setWidgetSprite(-1, new WidgetPointer(746,39)); + setWidgetSprite(-1, new WidgetPointer(746,132)); + setWidgetSprite(-1, new WidgetPointer(746,133)); + setWidgetSprite(-1, new WidgetPointer(746,40)); + setWidgetSprite(-1, new WidgetPointer(746,134)); + setWidgetSprite(-1, new WidgetPointer(746,135)); + setWidgetSprite(-1, new WidgetPointer(746,41)); + setWidgetSprite(-1, new WidgetPointer(746,136)); + setWidgetSprite(-1, new WidgetPointer(746,137)); + setWidgetSprite(-1, new WidgetPointer(746,42)); + setWidgetSprite(-1, new WidgetPointer(746,138)); + setWidgetSprite(-1, new WidgetPointer(746,139)); + setWidgetSprite(-1, new WidgetPointer(746,43)); + setWidgetSprite(-1, new WidgetPointer(746,140)); + setWidgetSprite(-1, new WidgetPointer(746,141)); + setWidgetSprite(-1, new WidgetPointer(746,44)); + setWidgetSprite(-1, new WidgetPointer(746,142)); + setWidgetSprite(-1, new WidgetPointer(746,143)); + setWidgetSprite(-1, new WidgetPointer(746,45)); + setWidgetSprite(-1, new WidgetPointer(746,144)); + setWidgetSprite(-1, new WidgetPointer(746,145)); + setWidgetSprite(-1, new WidgetPointer(746,46)); + setWidgetSprite(-1, new WidgetPointer(746,146)); + setWidgetSprite(-1, new WidgetPointer(746,147)); + setWidgetSprite(-1, new WidgetPointer(746,47)); + setWidgetSprite(-1, new WidgetPointer(746,148)); + setWidgetSprite(-1, new WidgetPointer(746,149)); + setWidgetSprite(-1, new WidgetPointer(746,48)); + setWidgetSprite(-1, new WidgetPointer(746,150)); + setWidgetSprite(-1, new WidgetPointer(746,151)); + setWidgetSprite(-1, new WidgetPointer(746,49)); + setWidgetSprite(-1, new WidgetPointer(746,152)); + setWidgetSprite(-1, new WidgetPointer(746,153)); + setWidgetSprite(-1, new WidgetPointer(746,50)); + setWidgetSprite(-1, new WidgetPointer(746,154)); + setWidgetSprite(-1, new WidgetPointer(746,155)); + setWidgetSprite(-1, new WidgetPointer(746,51)); + setWidgetSprite(-1, new WidgetPointer(746,156)); + setWidgetSprite(-1, new WidgetPointer(746,157)); + setWidgetSprite(-1, new WidgetPointer(746,52)); + setWidgetSprite(-1, new WidgetPointer(746,158)); + setWidgetSprite(-1, new WidgetPointer(746,159)); + setWidgetSprite(-1, new WidgetPointer(746,53)); + setWidgetSprite(-1, new WidgetPointer(746,160)); + setWidgetSprite(-1, new WidgetPointer(746,161)); + setWidgetSprite(-1, new WidgetPointer(746,54)); + setWidgetSprite(-1, new WidgetPointer(746,162)); + setWidgetSprite(-1, new WidgetPointer(746,163)); + } + return; +} diff --git a/dumps/scripts/131.cs2 b/dumps/scripts/131.cs2 new file mode 100644 index 0000000..af791ae --- /dev/null +++ b/dumps/scripts/131.cs2 @@ -0,0 +1,4 @@ +void script_131(string arg0) { + globalstring_24 = arg0; + return; +} diff --git a/dumps/scripts/1310.cs2 b/dumps/scripts/1310.cs2 new file mode 100644 index 0000000..b15cc26 --- /dev/null +++ b/dumps/scripts/1310.cs2 @@ -0,0 +1,37 @@ +void script_1310(int arg0) { + switch (arg0) { + case 21561344: + if (setWidgetRegister(new WidgetPointer(329,2))) { + setWidgetSprite(6364); + } + if (setWidgetRegister(new WidgetPointer(329,3))) { + setWidgetSprite(6365); + } + if (setWidgetRegister(new WidgetPointer(329,4))) { + setWidgetSprite(6366); + } + break; + case 33947660: + if (setWidgetRegister(new WidgetPointer(518,0))) { + setWidgetSprite(6364); + } + if (setWidgetRegister(new WidgetPointer(518,1))) { + setWidgetSprite(6365); + } + if (setWidgetRegister(new WidgetPointer(518,2))) { + setWidgetSprite(6366); + } + break; + case 21561345: + if (setWidgetRegister(new WidgetPointer(329,40))) { + setWidgetSprite(6364); + } + if (setWidgetRegister(new WidgetPointer(329,41))) { + setWidgetSprite(6365); + } + if (setWidgetRegister(new WidgetPointer(329,42))) { + setWidgetSprite(6366); + } + } + return; +} diff --git a/dumps/scripts/1311.cs2 b/dumps/scripts/1311.cs2 new file mode 100644 index 0000000..0025b13 --- /dev/null +++ b/dumps/scripts/1311.cs2 @@ -0,0 +1,22 @@ +void script_1311() { + setWidgetIsHidden(true, new WidgetPointer(548,204)); + setWidgetIsHidden(true, new WidgetPointer(548,205)); + setWidgetIsHidden(true, new WidgetPointer(548,206)); + setWidgetIsHidden(true, new WidgetPointer(548,207)); + setWidgetIsHidden(true, new WidgetPointer(548,208)); + setWidgetIsHidden(true, new WidgetPointer(548,209)); + setWidgetIsHidden(true, new WidgetPointer(548,210)); + setWidgetIsHidden(true, new WidgetPointer(548,211)); + setWidgetIsHidden(true, new WidgetPointer(548,212)); + setWidgetIsHidden(true, new WidgetPointer(548,213)); + setWidgetIsHidden(true, new WidgetPointer(548,214)); + setWidgetIsHidden(true, new WidgetPointer(548,215)); + setWidgetIsHidden(true, new WidgetPointer(548,216)); + setWidgetIsHidden(true, new WidgetPointer(548,217)); + setWidgetIsHidden(true, new WidgetPointer(548,218)); + setWidgetIsHidden(true, new WidgetPointer(548,219)); + setWidgetIsHidden(true, new WidgetPointer(548,221)); + setWidgetIsHidden(true, new WidgetPointer(548,222)); + setWidgetIsHidden(true, new WidgetPointer(548,200)); + return; +} diff --git a/dumps/scripts/1312.cs2 b/dumps/scripts/1312.cs2 new file mode 100644 index 0000000..a391d5f --- /dev/null +++ b/dumps/scripts/1312.cs2 @@ -0,0 +1,136 @@ +void script_1312(int arg0) { + int ivar1; + ivar1 = script_1305(); + if (((boolean)arg0)) { + if (ivar1 != 0) { + setWidgetSprite(-1, new WidgetPointer(548,129)); + setWidgetSprite(-1, new WidgetPointer(548,147)); + setWidgetSprite(-1, new WidgetPointer(548,148)); + } + if (ivar1 != 2) { + setWidgetSprite(-1, new WidgetPointer(548,130)); + setWidgetSprite(-1, new WidgetPointer(548,149)); + setWidgetSprite(-1, new WidgetPointer(548,150)); + } + if (ivar1 != 3) { + setWidgetSprite(-1, new WidgetPointer(548,131)); + setWidgetSprite(-1, new WidgetPointer(548,151)); + setWidgetSprite(-1, new WidgetPointer(548,152)); + } + if (ivar1 != 1) { + setWidgetSprite(-1, new WidgetPointer(548,132)); + setWidgetSprite(-1, new WidgetPointer(548,153)); + setWidgetSprite(-1, new WidgetPointer(548,154)); + } + if (ivar1 != 4) { + setWidgetSprite(-1, new WidgetPointer(548,133)); + setWidgetSprite(-1, new WidgetPointer(548,155)); + setWidgetSprite(-1, new WidgetPointer(548,156)); + } + if (ivar1 != 5) { + setWidgetSprite(-1, new WidgetPointer(548,134)); + setWidgetSprite(-1, new WidgetPointer(548,157)); + setWidgetSprite(-1, new WidgetPointer(548,158)); + } + if (ivar1 != 6) { + setWidgetSprite(-1, new WidgetPointer(548,135)); + setWidgetSprite(-1, new WidgetPointer(548,159)); + setWidgetSprite(-1, new WidgetPointer(548,160)); + } + if (ivar1 != 7) { + setWidgetSprite(-1, new WidgetPointer(548,136)); + setWidgetSprite(-1, new WidgetPointer(548,161)); + setWidgetSprite(-1, new WidgetPointer(548,162)); + } + if (ivar1 != 8) { + setWidgetSprite(-1, new WidgetPointer(548,99)); + setWidgetSprite(-1, new WidgetPointer(548,83)); + setWidgetSprite(-1, new WidgetPointer(548,84)); + } + if (ivar1 != 9) { + setWidgetSprite(-1, new WidgetPointer(548,100)); + setWidgetSprite(-1, new WidgetPointer(548,85)); + setWidgetSprite(-1, new WidgetPointer(548,86)); + } + if (ivar1 != 10) { + setWidgetSprite(-1, new WidgetPointer(548,101)); + setWidgetSprite(-1, new WidgetPointer(548,87)); + setWidgetSprite(-1, new WidgetPointer(548,88)); + } + if (ivar1 != 11) { + setWidgetSprite(-1, new WidgetPointer(548,102)); + setWidgetSprite(-1, new WidgetPointer(548,89)); + setWidgetSprite(-1, new WidgetPointer(548,90)); + } + if (ivar1 != 12) { + setWidgetSprite(-1, new WidgetPointer(548,103)); + setWidgetSprite(-1, new WidgetPointer(548,91)); + setWidgetSprite(-1, new WidgetPointer(548,92)); + } + if (ivar1 != 13) { + setWidgetSprite(-1, new WidgetPointer(548,104)); + setWidgetSprite(-1, new WidgetPointer(548,93)); + setWidgetSprite(-1, new WidgetPointer(548,94)); + } + if (ivar1 != 14) { + setWidgetSprite(-1, new WidgetPointer(548,105)); + setWidgetSprite(-1, new WidgetPointer(548,95)); + setWidgetSprite(-1, new WidgetPointer(548,96)); + } + if (ivar1 != 15) { + setWidgetSprite(-1, new WidgetPointer(548,106)); + setWidgetSprite(-1, new WidgetPointer(548,97)); + setWidgetSprite(-1, new WidgetPointer(548,98)); + } + } else { + setWidgetSprite(-1, new WidgetPointer(548,129)); + setWidgetSprite(-1, new WidgetPointer(548,147)); + setWidgetSprite(-1, new WidgetPointer(548,148)); + setWidgetSprite(-1, new WidgetPointer(548,130)); + setWidgetSprite(-1, new WidgetPointer(548,149)); + setWidgetSprite(-1, new WidgetPointer(548,150)); + setWidgetSprite(-1, new WidgetPointer(548,131)); + setWidgetSprite(-1, new WidgetPointer(548,151)); + setWidgetSprite(-1, new WidgetPointer(548,152)); + setWidgetSprite(-1, new WidgetPointer(548,132)); + setWidgetSprite(-1, new WidgetPointer(548,153)); + setWidgetSprite(-1, new WidgetPointer(548,154)); + setWidgetSprite(-1, new WidgetPointer(548,133)); + setWidgetSprite(-1, new WidgetPointer(548,155)); + setWidgetSprite(-1, new WidgetPointer(548,156)); + setWidgetSprite(-1, new WidgetPointer(548,134)); + setWidgetSprite(-1, new WidgetPointer(548,157)); + setWidgetSprite(-1, new WidgetPointer(548,158)); + setWidgetSprite(-1, new WidgetPointer(548,135)); + setWidgetSprite(-1, new WidgetPointer(548,159)); + setWidgetSprite(-1, new WidgetPointer(548,160)); + setWidgetSprite(-1, new WidgetPointer(548,136)); + setWidgetSprite(-1, new WidgetPointer(548,161)); + setWidgetSprite(-1, new WidgetPointer(548,162)); + setWidgetSprite(-1, new WidgetPointer(548,99)); + setWidgetSprite(-1, new WidgetPointer(548,83)); + setWidgetSprite(-1, new WidgetPointer(548,84)); + setWidgetSprite(-1, new WidgetPointer(548,100)); + setWidgetSprite(-1, new WidgetPointer(548,85)); + setWidgetSprite(-1, new WidgetPointer(548,86)); + setWidgetSprite(-1, new WidgetPointer(548,101)); + setWidgetSprite(-1, new WidgetPointer(548,87)); + setWidgetSprite(-1, new WidgetPointer(548,88)); + setWidgetSprite(-1, new WidgetPointer(548,102)); + setWidgetSprite(-1, new WidgetPointer(548,89)); + setWidgetSprite(-1, new WidgetPointer(548,90)); + setWidgetSprite(-1, new WidgetPointer(548,103)); + setWidgetSprite(-1, new WidgetPointer(548,91)); + setWidgetSprite(-1, new WidgetPointer(548,92)); + setWidgetSprite(-1, new WidgetPointer(548,104)); + setWidgetSprite(-1, new WidgetPointer(548,93)); + setWidgetSprite(-1, new WidgetPointer(548,94)); + setWidgetSprite(-1, new WidgetPointer(548,105)); + setWidgetSprite(-1, new WidgetPointer(548,95)); + setWidgetSprite(-1, new WidgetPointer(548,96)); + setWidgetSprite(-1, new WidgetPointer(548,106)); + setWidgetSprite(-1, new WidgetPointer(548,97)); + setWidgetSprite(-1, new WidgetPointer(548,98)); + } + return; +} diff --git a/dumps/scripts/1313.cs2 b/dumps/scripts/1313.cs2 new file mode 100644 index 0000000..90d9e2e --- /dev/null +++ b/dumps/scripts/1313.cs2 @@ -0,0 +1,11 @@ +void script_1313() { + script_2654(); + setWidgetSprite(1207, new WidgetPointer(747,2)); + setWidgetPosition(25, 1, 0, 0, new WidgetPointer(747,3)); + setWidgetPosition(25, 1, 0, 0, new WidgetPointer(747,4)); + setWidgetPosition(3, 15, 0, 0, new WidgetPointer(747,5)); + setWidgetPosition(31, 7, 0, 0, new WidgetPointer(747,6)); + script_2303(); + script_1741(49152001); + return; +} diff --git a/dumps/scripts/1314.cs2 b/dumps/scripts/1314.cs2 new file mode 100644 index 0000000..4b540d0 --- /dev/null +++ b/dumps/scripts/1314.cs2 @@ -0,0 +1,92 @@ +int script_1314(int arg0) { + if (getDisplayMode() >= 2) { + switch (arg0) { + case 0: + return isWidgetHidden(new WidgetPointer(746,90)); + case 1: + return isWidgetHidden(new WidgetPointer(746,91)); + case 2: + return isWidgetHidden(new WidgetPointer(746,92)); + case 3: + return isWidgetHidden(new WidgetPointer(746,93)); + case 4: + return isWidgetHidden(new WidgetPointer(746,94)); + case 5: + return isWidgetHidden(new WidgetPointer(746,95)); + case 6: + return isWidgetHidden(new WidgetPointer(746,96)); + case 7: + return isWidgetHidden(new WidgetPointer(746,97)); + case 8: + return isWidgetHidden(new WidgetPointer(746,98)); + case 9: + return isWidgetHidden(new WidgetPointer(746,99)); + case 10: + return isWidgetHidden(new WidgetPointer(746,100)); + case 11: + return isWidgetHidden(new WidgetPointer(746,101)); + case 12: + return isWidgetHidden(new WidgetPointer(746,102)); + case 13: + return isWidgetHidden(new WidgetPointer(746,103)); + case 14: + return isWidgetHidden(new WidgetPointer(746,104)); + case 15: + return isWidgetHidden(new WidgetPointer(746,105)); + case 95: + return isWidgetHidden(new WidgetPointer(746,107)); + case 99: + return isWidgetHidden(new WidgetPointer(746,108)); + case 98: + if (isWidgetOpen(new WidgetPointer(746,88))) { + return isWidgetHidden(new WidgetPointer(746,88)); + } + return 1; + } + } else { + switch (arg0) { + case 0: + return isWidgetHidden(new WidgetPointer(548,204)); + case 1: + return isWidgetHidden(new WidgetPointer(548,205)); + case 2: + return isWidgetHidden(new WidgetPointer(548,206)); + case 3: + return isWidgetHidden(new WidgetPointer(548,207)); + case 4: + return isWidgetHidden(new WidgetPointer(548,208)); + case 5: + return isWidgetHidden(new WidgetPointer(548,209)); + case 6: + return isWidgetHidden(new WidgetPointer(548,210)); + case 7: + return isWidgetHidden(new WidgetPointer(548,211)); + case 8: + return isWidgetHidden(new WidgetPointer(548,212)); + case 9: + return isWidgetHidden(new WidgetPointer(548,213)); + case 10: + return isWidgetHidden(new WidgetPointer(548,214)); + case 11: + return isWidgetHidden(new WidgetPointer(548,215)); + case 12: + return isWidgetHidden(new WidgetPointer(548,216)); + case 13: + return isWidgetHidden(new WidgetPointer(548,217)); + case 14: + return isWidgetHidden(new WidgetPointer(548,218)); + case 15: + return isWidgetHidden(new WidgetPointer(548,219)); + case 95: + return isWidgetHidden(new WidgetPointer(548,221)); + case 99: + return isWidgetHidden(new WidgetPointer(548,222)); + case 98: + if (isWidgetOpen(new WidgetPointer(548,200))) { + return isWidgetHidden(new WidgetPointer(548,200)); + } + return 1; + } + } + return -1; +} diff --git a/dumps/scripts/1315.cs2 b/dumps/scripts/1315.cs2 new file mode 100644 index 0000000..71f401d --- /dev/null +++ b/dumps/scripts/1315.cs2 @@ -0,0 +1,9 @@ +void script_1315(int arg0) { + globalint_119 = standart_config_173; + setScriptCallOnConfigChange(1316, new WidgetPointer(arg0), 173, 1, "IY", new WidgetPointer(arg0)); + setScriptCallOnMouseOver(1533, new WidgetPointer(arg0), "I", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(2307, new WidgetPointer(arg0), "I", new WidgetPointer(arg0)); + setScriptCallOnClickContextMenu(1534, new WidgetPointer(arg0), -2147483644, "Ii", new WidgetPointer(arg0)); + script_1741(arg0); + return; +} diff --git a/dumps/scripts/1316.cs2 b/dumps/scripts/1316.cs2 new file mode 100644 index 0000000..860c6a1 --- /dev/null +++ b/dumps/scripts/1316.cs2 @@ -0,0 +1,5 @@ +void script_1316(int arg0) { + globalint_119 = standart_config_173; + script_1741(arg0); + return; +} diff --git a/dumps/scripts/1317.cs2 b/dumps/scripts/1317.cs2 new file mode 100644 index 0000000..cee4775 --- /dev/null +++ b/dumps/scripts/1317.cs2 @@ -0,0 +1,15 @@ +void script_1317() { + setWidgetModel(18789, new WidgetPointer(262,0)); + setWidgetModel(18813, new WidgetPointer(262,28)); + setWidgetModel(18814, new WidgetPointer(262,29)); + if (bitconfig_4835 < 1) { + setWidgetModel(-1, new WidgetPointer(262,29)); + } + if (bitconfig_4835 < 2) { + setWidgetModel(-1, new WidgetPointer(262,28)); + } + if (bitconfig_4835 < 3) { + setWidgetModel(-1, new WidgetPointer(262,0)); + } + return; +} diff --git a/dumps/scripts/1318.cs2 b/dumps/scripts/1318.cs2 new file mode 100644 index 0000000..3863952 --- /dev/null +++ b/dumps/scripts/1318.cs2 @@ -0,0 +1,54 @@ +void script_1318(int arg0) { + if (arg0 == 17170456) { + if (((boolean)globalint_163)) { + setWidgetModel(18796, new WidgetPointer(262,24)); + globalint_163 = 1; + } else { + setWidgetModel(18794, new WidgetPointer(262,24)); + globalint_163 = 0; + } + } else if (arg0 == 17170457) { + if (((boolean)globalint_164)) { + setWidgetModel(18796, new WidgetPointer(262,25)); + globalint_164 = 1; + } else { + setWidgetModel(18794, new WidgetPointer(262,25)); + globalint_164 = 0; + } + } else if (arg0 == 17170452) { + if (((boolean)globalint_162)) { + setWidgetModel(18796, new WidgetPointer(262,20)); + globalint_162 = 1; + } else { + setWidgetModel(18794, new WidgetPointer(262,20)); + globalint_162 = 0; + } + } else if (arg0 == 17170453) { + if (((boolean)globalint_165)) { + setWidgetModel(18792, new WidgetPointer(262,21)); + globalint_165 = 1; + } else { + setWidgetModel(18790, new WidgetPointer(262,21)); + globalint_165 = 0; + } + } else if (arg0 == 17170454) { + if (((boolean)globalint_166)) { + setWidgetModel(18792, new WidgetPointer(262,22)); + globalint_166 = 1; + } else { + setWidgetModel(18790, new WidgetPointer(262,22)); + globalint_166 = 0; + } + } else { + if (arg0 == 17170455) { + if (((boolean)globalint_167)) { + setWidgetModel(18792, new WidgetPointer(262,23)); + globalint_167 = 1; + } else { + setWidgetModel(18790, new WidgetPointer(262,23)); + globalint_167 = 0; + } + } + } + return; +} diff --git a/dumps/scripts/1319.cs2 b/dumps/scripts/1319.cs2 new file mode 100644 index 0000000..94531b0 --- /dev/null +++ b/dumps/scripts/1319.cs2 @@ -0,0 +1,45 @@ +void script_1319() { + if (((boolean)bitconfig_4834)) { + setWidgetModel(18796, new WidgetPointer(262,24)); + globalint_163 = 1; + } else { + setWidgetModel(18794, new WidgetPointer(262,24)); + globalint_163 = 0; + } + if (bitconfig_4834 == 2) { + setWidgetModel(18796, new WidgetPointer(262,25)); + globalint_164 = 1; + } else { + setWidgetModel(18794, new WidgetPointer(262,25)); + globalint_164 = 0; + } + if (bitconfig_4834 == 3) { + setWidgetModel(18796, new WidgetPointer(262,20)); + globalint_162 = 1; + } else { + setWidgetModel(18794, new WidgetPointer(262,20)); + globalint_162 = 0; + } + if (bitconfig_4834 == 4) { + setWidgetModel(18792, new WidgetPointer(262,21)); + globalint_165 = 1; + } else { + setWidgetModel(18790, new WidgetPointer(262,21)); + globalint_165 = 0; + } + if (bitconfig_4834 == 5) { + setWidgetModel(18792, new WidgetPointer(262,22)); + globalint_166 = 1; + } else { + setWidgetModel(18790, new WidgetPointer(262,22)); + globalint_166 = 0; + } + if (bitconfig_4834 == 6) { + setWidgetModel(18792, new WidgetPointer(262,23)); + globalint_167 = 1; + } else { + setWidgetModel(18790, new WidgetPointer(262,23)); + globalint_167 = 0; + } + return; +} diff --git a/dumps/scripts/132.cs2 b/dumps/scripts/132.cs2 new file mode 100644 index 0000000..b98f872 --- /dev/null +++ b/dumps/scripts/132.cs2 @@ -0,0 +1,4 @@ +void script_132() { + setScriptCallOnKeyPress(73, -2147483640, false, "iz", new WidgetPointer(137,56)); + return; +} diff --git a/dumps/scripts/1320.cs2 b/dumps/scripts/1320.cs2 new file mode 100644 index 0000000..d629fb4 --- /dev/null +++ b/dumps/scripts/1320.cs2 @@ -0,0 +1,8 @@ +void script_1320(int arg0,int arg1) { + if (((boolean)arg1)) { + setWidgetSprite(181, new WidgetPointer(arg0)); + } else { + setWidgetSprite(180, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/1321.cs2 b/dumps/scripts/1321.cs2 new file mode 100644 index 0000000..37be66c --- /dev/null +++ b/dumps/scripts/1321.cs2 @@ -0,0 +1,8 @@ +void script_1321(int arg0,int arg1) { + if (((boolean)arg1)) { + setWidgetSprite(181, new WidgetPointer(arg0)); + } else { + setWidgetSprite(180, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/1322.cs2 b/dumps/scripts/1322.cs2 new file mode 100644 index 0000000..0407427 --- /dev/null +++ b/dumps/scripts/1322.cs2 @@ -0,0 +1,24 @@ +void script_1322(int arg0,int arg1,int arg2) { + if (getItemIdInSlot(438, 0) != -1) { + setWidgetIsHidden(false, new WidgetPointer(arg0)); + setItemOnWidgetMethod2205(getItemIdInSlot(438, 0), 1, new WidgetPointer(arg0)); + cs2method2305(new WidgetPointer(arg0), "" + getItemName(getItemIdInSlot(438, 0))); + } else { + setWidgetIsHidden(true, new WidgetPointer(arg0)); + } + if (getItemIdInSlot(438, 1) != -1) { + setWidgetIsHidden(false, new WidgetPointer(arg1)); + setItemOnWidgetMethod2205(getItemIdInSlot(438, 1), 1, new WidgetPointer(arg1)); + cs2method2305(new WidgetPointer(arg1), "" + getItemName(getItemIdInSlot(438, 1))); + } else { + setWidgetIsHidden(true, new WidgetPointer(arg1)); + } + if (getItemIdInSlot(438, 2) != -1) { + setWidgetIsHidden(false, new WidgetPointer(arg2)); + setItemOnWidgetMethod2205(getItemIdInSlot(438, 2), 1, new WidgetPointer(arg2)); + cs2method2305(new WidgetPointer(arg2), "" + getItemName(getItemIdInSlot(438, 2))); + } else { + setWidgetIsHidden(true, new WidgetPointer(arg2)); + } + return; +} diff --git a/dumps/scripts/1323.cs2 b/dumps/scripts/1323.cs2 new file mode 100644 index 0000000..37481d0 --- /dev/null +++ b/dumps/scripts/1323.cs2 @@ -0,0 +1,31 @@ +void script_1323(int arg0,int arg1,int arg2,int arg3) { + if (getItemIdInSlot(439, 0) != -1) { + setWidgetIsHidden(false, new WidgetPointer(arg0)); + setItemOnWidgetMethod2205(getItemIdInSlot(439, 0), 1, new WidgetPointer(arg0)); + cs2method2305(new WidgetPointer(arg0), "" + getItemName(getItemIdInSlot(439, 0))); + } else { + setWidgetIsHidden(true, new WidgetPointer(arg0)); + } + if (getItemIdInSlot(439, 1) != -1) { + setWidgetIsHidden(false, new WidgetPointer(arg1)); + setItemOnWidgetMethod2205(getItemIdInSlot(439, 1), 1, new WidgetPointer(arg1)); + cs2method2305(new WidgetPointer(arg1), "" + getItemName(getItemIdInSlot(439, 1))); + } else { + setWidgetIsHidden(true, new WidgetPointer(arg1)); + } + if (getItemIdInSlot(439, 2) != -1) { + setWidgetIsHidden(false, new WidgetPointer(arg2)); + setItemOnWidgetMethod2205(getItemIdInSlot(439, 2), 1, new WidgetPointer(arg2)); + cs2method2305(new WidgetPointer(arg2), "" + getItemName(getItemIdInSlot(439, 2))); + } else { + setWidgetIsHidden(true, new WidgetPointer(arg2)); + } + if (getItemIdInSlot(439, 3) != -1) { + setWidgetIsHidden(false, new WidgetPointer(arg3)); + setItemOnWidgetMethod2205(getItemIdInSlot(439, 3), 1, new WidgetPointer(arg3)); + cs2method2305(new WidgetPointer(arg3), "" + getItemName(getItemIdInSlot(439, 3))); + } else { + setWidgetIsHidden(true, new WidgetPointer(arg3)); + } + return; +} diff --git a/dumps/scripts/1324.cs2 b/dumps/scripts/1324.cs2 new file mode 100644 index 0000000..a4d3e60 --- /dev/null +++ b/dumps/scripts/1324.cs2 @@ -0,0 +1,27 @@ +void script_1324(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + setWidgetModel(cs2method_3408(105, 109, 1595, divide(bitconfig_2510, 10)), new WidgetPointer(arg0)); + setWidgetModel(cs2method_3408(105, 109, 1595, mod(bitconfig_2510, 10)), new WidgetPointer(arg1)); + setItemOnWidgetMethod2205(standart_config_849, 1, new WidgetPointer(arg5)); + if (((boolean)bitconfig_2539)) { + setWidgetModel(17219, new WidgetPointer(arg3)); + setWidgetModel(-1, new WidgetPointer(arg2)); + setWidgetModel(-1, new WidgetPointer(arg4)); + return; + } + if (bitconfig_2539 > bitconfig_2510) { + setWidgetModel(17219, new WidgetPointer(arg3)); + setWidgetModel(17221, new WidgetPointer(arg2)); + setWidgetModel(17217, new WidgetPointer(arg4)); + return; + } + if (bitconfig_2539 < bitconfig_2510) { + setWidgetModel(17219, new WidgetPointer(arg3)); + setWidgetModel(17220, new WidgetPointer(arg2)); + setWidgetModel(17218, new WidgetPointer(arg4)); + return; + } + setWidgetModel(17216, new WidgetPointer(arg3)); + setWidgetModel(-1, new WidgetPointer(arg2)); + setWidgetModel(-1, new WidgetPointer(arg4)); + return; +} diff --git a/dumps/scripts/1325.cs2 b/dumps/scripts/1325.cs2 new file mode 100644 index 0000000..10667f9 --- /dev/null +++ b/dumps/scripts/1325.cs2 @@ -0,0 +1,27 @@ +void script_1325(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + setWidgetModel(cs2method_3408(105, 109, 1595, divide(bitconfig_2511, 10)), new WidgetPointer(arg0)); + setWidgetModel(cs2method_3408(105, 109, 1595, mod(bitconfig_2511, 10)), new WidgetPointer(arg1)); + setItemOnWidgetMethod2205(standart_config_850, 1, new WidgetPointer(arg5)); + if (((boolean)bitconfig_2540)) { + setWidgetModel(17219, new WidgetPointer(arg3)); + setWidgetModel(-1, new WidgetPointer(arg2)); + setWidgetModel(-1, new WidgetPointer(arg4)); + return; + } + if (bitconfig_2540 > bitconfig_2511) { + setWidgetModel(17219, new WidgetPointer(arg3)); + setWidgetModel(17221, new WidgetPointer(arg2)); + setWidgetModel(17217, new WidgetPointer(arg4)); + return; + } + if (bitconfig_2540 < bitconfig_2511) { + setWidgetModel(17219, new WidgetPointer(arg3)); + setWidgetModel(17220, new WidgetPointer(arg2)); + setWidgetModel(17218, new WidgetPointer(arg4)); + return; + } + setWidgetModel(17216, new WidgetPointer(arg3)); + setWidgetModel(-1, new WidgetPointer(arg2)); + setWidgetModel(-1, new WidgetPointer(arg4)); + return; +} diff --git a/dumps/scripts/1326.cs2 b/dumps/scripts/1326.cs2 new file mode 100644 index 0000000..2d44ff0 --- /dev/null +++ b/dumps/scripts/1326.cs2 @@ -0,0 +1,28 @@ +void script_1326(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6) { + setWidgetModel(cs2method_3408(105, 109, 1595, divide(bitconfig_2512, 10)), new WidgetPointer(arg0)); + setWidgetModel(cs2method_3408(105, 109, 1595, mod(bitconfig_2512, 10)), new WidgetPointer(arg1)); + setItemOnWidgetMethod2205(standart_config_851, 1, new WidgetPointer(arg5)); + setItemOnWidgetMethod2205(standart_config_852, 1, new WidgetPointer(arg6)); + if (((boolean)bitconfig_2541)) { + setWidgetModel(17219, new WidgetPointer(arg3)); + setWidgetModel(-1, new WidgetPointer(arg2)); + setWidgetModel(-1, new WidgetPointer(arg4)); + return; + } + if (bitconfig_2541 > bitconfig_2512) { + setWidgetModel(17219, new WidgetPointer(arg3)); + setWidgetModel(17221, new WidgetPointer(arg2)); + setWidgetModel(17217, new WidgetPointer(arg4)); + return; + } + if (bitconfig_2541 < bitconfig_2512) { + setWidgetModel(17219, new WidgetPointer(arg3)); + setWidgetModel(17220, new WidgetPointer(arg2)); + setWidgetModel(17218, new WidgetPointer(arg4)); + return; + } + setWidgetModel(17216, new WidgetPointer(arg3)); + setWidgetModel(-1, new WidgetPointer(arg2)); + setWidgetModel(-1, new WidgetPointer(arg4)); + return; +} diff --git a/dumps/scripts/1327.cs2 b/dumps/scripts/1327.cs2 new file mode 100644 index 0000000..2eafcfa --- /dev/null +++ b/dumps/scripts/1327.cs2 @@ -0,0 +1,29 @@ +void script_1327(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7) { + setWidgetModel(cs2method_3408(105, 109, 1595, divide(bitconfig_2513, 10)), new WidgetPointer(arg0)); + setWidgetModel(cs2method_3408(105, 109, 1595, mod(bitconfig_2513, 10)), new WidgetPointer(arg1)); + setItemOnWidgetMethod2205(standart_config_853, 1, new WidgetPointer(arg5)); + setItemOnWidgetMethod2205(standart_config_854, 1, new WidgetPointer(arg6)); + setItemOnWidgetMethod2205(standart_config_855, 1, new WidgetPointer(arg7)); + if (((boolean)bitconfig_2542)) { + setWidgetModel(17219, new WidgetPointer(arg3)); + setWidgetModel(-1, new WidgetPointer(arg2)); + setWidgetModel(-1, new WidgetPointer(arg4)); + return; + } + if (bitconfig_2542 > bitconfig_2513) { + setWidgetModel(17219, new WidgetPointer(arg3)); + setWidgetModel(17221, new WidgetPointer(arg2)); + setWidgetModel(17217, new WidgetPointer(arg4)); + return; + } + if (bitconfig_2542 < bitconfig_2513) { + setWidgetModel(17219, new WidgetPointer(arg3)); + setWidgetModel(17220, new WidgetPointer(arg2)); + setWidgetModel(17218, new WidgetPointer(arg4)); + return; + } + setWidgetModel(17216, new WidgetPointer(arg3)); + setWidgetModel(-1, new WidgetPointer(arg2)); + setWidgetModel(-1, new WidgetPointer(arg4)); + return; +} diff --git a/dumps/scripts/1328.cs2 b/dumps/scripts/1328.cs2 new file mode 100644 index 0000000..797ff8f --- /dev/null +++ b/dumps/scripts/1328.cs2 @@ -0,0 +1,107 @@ +void script_1328(int arg0) { + int ivar1; + int ivar2; + string svar0; + string svar1; + int stack_dump0; + previousAndCurrentName(0,2,0) structdump_1; + if ((((((isWidgetHidden(new WidgetPointer(906,41)) || isWidgetHidden(new WidgetPointer(906,42))) || isWidgetHidden(new WidgetPointer(906,43))) || isWidgetHidden(new WidgetPointer(906,29))) || isWidgetHidden(new WidgetPointer(906,45))) || isWidgetHidden(new WidgetPointer(906,55))) || isWidgetHidden(new WidgetPointer(906,56))) { + return; + } + ivar1 = -1; + if (arg0 == 80) { + if (isWidgetHidden(new WidgetPointer(906,185))) { + ivar1 = 0; + } + if (isWidgetHidden(new WidgetPointer(906,186))) { + ivar1 = 1; + } + if (isWidgetHidden(new WidgetPointer(906,187))) { + ivar1 = 2; + } + if (isWidgetHidden(new WidgetPointer(906,188))) { + ivar1 = 3; + } + if (isWidgetHidden(new WidgetPointer(906,189))) { + ivar1 = 5; + } + if (isWidgetHidden(new WidgetPointer(906,190))) { + ivar1 = 4; + } + if (isHoldingCtrl()) { + switch (ivar1) { + case 0: + script_3060(1); + return; + case 1: + script_3060(2); + return; + case 2: + script_3060(3); + return; + case 3: + script_3060(5); + return; + case 5: + script_3060(4); + return; + case 4: + script_3060(0); + return; + } + script_3060(0); + return; + } + switch (ivar1) { + case 0: + script_3060(4); + return; + case 1: + script_3060(0); + return; + case 2: + script_3060(1); + return; + case 3: + script_3060(2); + return; + case 5: + script_3060(3); + return; + case 4: + script_3060(5); + return; + } + script_3060(0); + return; + } + ivar2 = 0; + svar0 = ""; + svar1 = ""; + if ((arg0 == 84) && isWidgetHidden(new WidgetPointer(906,187))) { + if (strLength(globalstring_276) > 0) { + ivar2 = cs2method3628(globalstring_276); + if ((ivar2 != -1) && cs2method6900()) { + stack_dump0 = ivar2; + structdump_1 = getFriendName(stack_dump0); + svar1 = structdump_1.stringpart_1; + svar0 = structdump_1.stringpart_0; + script_3015(0, "Send message to " + svar0, "", globalstring_276, ""); + return; + } + if (globalint_1271 > subtract(getClientCycle(), 100)) { + return; + } + messageType0("That player is not on your Friends list."); + globalint_1271 = getClientCycle(); + return; + } + if (globalint_1271 > subtract(getClientCycle(), 100)) { + return; + } + messageType0("You haven't received any messages to which you can reply."); + globalint_1271 = getClientCycle(); + return; + } + return; +} diff --git a/dumps/scripts/1329.cs2 b/dumps/scripts/1329.cs2 new file mode 100644 index 0000000..bb22c25 --- /dev/null +++ b/dumps/scripts/1329.cs2 @@ -0,0 +1,14 @@ +void script_1329() { + if (script_1305() == 6) { + if (((boolean)bitconfig_6522)) { + setWidgetText(new WidgetPointer(894,7), "Click the flashing Prayer icon to activate the Thick Skin prayer. This prayer increases your Defence by 5%, which can be seen if you hover your mouse over the flashing Prayer icon."); + setWidgetText(new WidgetPointer(894,6), ""); + setWidgetSprite(115, new WidgetPointer(894,4)); + } + } else { + setWidgetText(new WidgetPointer(894,7), "Click on the stone with the Prayer icon to open the Prayer side interface."); + setWidgetText(new WidgetPointer(894,6), ""); + setWidgetSprite(1823, new WidgetPointer(894,4)); + } + return; +} diff --git a/dumps/scripts/133.cs2 b/dumps/scripts/133.cs2 new file mode 100644 index 0000000..7e26ed4 --- /dev/null +++ b/dumps/scripts/133.cs2 @@ -0,0 +1,6 @@ +int script_133(int arg0,int arg1,int arg2) { + if ((((extractX(arg2) >= min(extractX(arg0), extractX(arg1))) && (extractY(arg2) >= min(extractY(arg0), extractY(arg1)))) && ((extractZ(arg2) >= min(extractZ(arg0), extractZ(arg1))) && (extractX(arg2) <= max(extractX(arg0), extractX(arg1))))) && ((extractY(arg2) <= max(extractY(arg0), extractY(arg1))) && (extractZ(arg2) <= max(extractZ(arg0), extractZ(arg1))))) { + return 1; + } + return 0; +} diff --git a/dumps/scripts/1330.cs2 b/dumps/scripts/1330.cs2 new file mode 100644 index 0000000..0b5e41e --- /dev/null +++ b/dumps/scripts/1330.cs2 @@ -0,0 +1,5 @@ +void script_1330() { + setScriptCallOnGameloop(1332, "", new WidgetPointer(894,5)); + setWidgetIsHidden(false, new WidgetPointer(894,7)); + return; +} diff --git a/dumps/scripts/1331.cs2 b/dumps/scripts/1331.cs2 new file mode 100644 index 0000000..a6336fc --- /dev/null +++ b/dumps/scripts/1331.cs2 @@ -0,0 +1,6 @@ +void script_1331() { + setScriptCallOnGameloop(-1, "", new WidgetPointer(894,5)); + setWidgetIsHidden(true, new WidgetPointer(894,7)); + setWidgetSprite(-1, new WidgetPointer(894,4)); + return; +} diff --git a/dumps/scripts/1332.cs2 b/dumps/scripts/1332.cs2 new file mode 100644 index 0000000..f8efa4f --- /dev/null +++ b/dumps/scripts/1332.cs2 @@ -0,0 +1,16 @@ +void script_1332() { + if (((boolean)bitconfig_275)) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(894,5)); + setWidgetIsHidden(true, new WidgetPointer(894,7)); + setWidgetSprite(-1, new WidgetPointer(894,4)); + } else if (script_1305() == 7) { + setWidgetText(new WidgetPointer(894,7), "To set Wind Rush to auto-cast, click on the flashing spell icon. You can hover over spell icons to read a brief description of the spell and the runes required to cast it."); + setWidgetText(new WidgetPointer(894,6), ""); + setWidgetSprite(3759, new WidgetPointer(894,4)); + } else { + setWidgetText(new WidgetPointer(894,7), "Click on the Magic icon to open your magic spellbook."); + setWidgetText(new WidgetPointer(894,6), ""); + setWidgetSprite(1824, new WidgetPointer(894,4)); + } + return; +} diff --git a/dumps/scripts/1333.cs2 b/dumps/scripts/1333.cs2 new file mode 100644 index 0000000..fb9d18c --- /dev/null +++ b/dumps/scripts/1333.cs2 @@ -0,0 +1,4 @@ +void script_1333(int arg0,int arg1,string arg2) { + script_1334(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/1334.cs2 b/dumps/scripts/1334.cs2 new file mode 100644 index 0000000..ff18349 --- /dev/null +++ b/dumps/scripts/1334.cs2 @@ -0,0 +1,12 @@ +void script_1334(int arg0,int arg1,string arg2) { + if (arg0 != -1) { + if (((boolean)arg1)) { + setWidgetText(new WidgetPointer(arg0), "" + arg2 + ""); + setWidgetRGB(new Color(145, 177, 244), new WidgetPointer(arg0)); + } else { + setWidgetText(new WidgetPointer(arg0), "" + arg2 + ""); + setWidgetRGB(new Color(44, 111, 248), new WidgetPointer(arg0)); + } + } + return; +} diff --git a/dumps/scripts/1335.cs2 b/dumps/scripts/1335.cs2 new file mode 100644 index 0000000..4c76088 --- /dev/null +++ b/dumps/scripts/1335.cs2 @@ -0,0 +1,5 @@ +void script_1335(int arg0,int arg1,int arg2) { + globalint_1098 = script_1401(arg0, 494, getWidgetActualX(new WidgetPointer(arg1)), globalstring_278); + script_1390(arg1, arg2, globalstring_278); + return; +} diff --git a/dumps/scripts/1336.cs2 b/dumps/scripts/1336.cs2 new file mode 100644 index 0000000..2bce8d9 --- /dev/null +++ b/dumps/scripts/1336.cs2 @@ -0,0 +1,5 @@ +void script_1336() { + setWidgetScrollMax(400, 1810, new WidgetPointer(156,2)); + script_31(10223617, 10223618, 792, 789, 790, 791, 773, 788); + return; +} diff --git a/dumps/scripts/1337.cs2 b/dumps/scripts/1337.cs2 new file mode 100644 index 0000000..94c1fc1 --- /dev/null +++ b/dumps/scripts/1337.cs2 @@ -0,0 +1,11 @@ +void script_1337() { + script_2654(); + setWidgetSprite(1206, new WidgetPointer(747,2)); + setWidgetPosition(1, 1, 0, 0, new WidgetPointer(747,3)); + setWidgetPosition(1, 1, 0, 0, new WidgetPointer(747,4)); + setWidgetPosition(31, 15, 0, 0, new WidgetPointer(747,5)); + setWidgetPosition(7, 7, 0, 0, new WidgetPointer(747,6)); + script_2303(); + script_1741(49152001); + return; +} diff --git a/dumps/scripts/1338.cs2 b/dumps/scripts/1338.cs2 new file mode 100644 index 0000000..4f3dac8 --- /dev/null +++ b/dumps/scripts/1338.cs2 @@ -0,0 +1,4 @@ +void script_1338(int arg0,string arg1,string arg2) { + cs2method5400(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/1339.cs2 b/dumps/scripts/1339.cs2 new file mode 100644 index 0000000..0ed669a --- /dev/null +++ b/dumps/scripts/1339.cs2 @@ -0,0 +1,4 @@ +void script_1339(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6) { + script_1346(arg0, arg1, arg2, arg3, arg4, arg5, arg6, 897, 788, 788, 1040, 16777215, 16776960, 494, 792, 789, 790, 791, 773, 788); + return; +} diff --git a/dumps/scripts/134.cs2 b/dumps/scripts/134.cs2 new file mode 100644 index 0000000..c614ee7 --- /dev/null +++ b/dumps/scripts/134.cs2 @@ -0,0 +1,26 @@ +void script_134() { + if ((getBlackmarks() == 5) || (getBlackmarks() == 6)) { + setWidgetText(new WidgetPointer(594,83), "Suggest to mute this player for 48 hours"); + setWidgetText(new WidgetPointer(594,10), "Suggest to mute this player for 48 hours"); + setWidgetText(new WidgetPointer(594,60), "Suggest to mute this player for 48 hours"); + } else { + setWidgetText(new WidgetPointer(594,83), "Mute this player for 48 hours"); + setWidgetText(new WidgetPointer(594,10), "Mute this player for 48 hours"); + setWidgetText(new WidgetPointer(594,60), "Mute this player for 48 hours"); + } + if (((boolean)globalint_6)) { + globalint_6 = 0; + } else { + globalint_6 = 1; + } + if (((boolean)globalint_6)) { + setWidgetSprite(1768, new WidgetPointer(594,82)); + setWidgetSprite(1768, new WidgetPointer(594,9)); + setWidgetSprite(1768, new WidgetPointer(594,59)); + } else { + setWidgetSprite(1770, new WidgetPointer(594,82)); + setWidgetSprite(1770, new WidgetPointer(594,9)); + setWidgetSprite(1770, new WidgetPointer(594,59)); + } + return; +} diff --git a/dumps/scripts/1340.cs2 b/dumps/scripts/1340.cs2 new file mode 100644 index 0000000..cdea78b --- /dev/null +++ b/dumps/scripts/1340.cs2 @@ -0,0 +1,4 @@ +void script_1340(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12) { + script_1346(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg8, arg9, arg10, arg11, arg12, 792, 789, 790, 791, 773, 788); + return; +} diff --git a/dumps/scripts/1341.cs2 b/dumps/scripts/1341.cs2 new file mode 100644 index 0000000..08e73f1 --- /dev/null +++ b/dumps/scripts/1341.cs2 @@ -0,0 +1,4 @@ +void script_1341(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12,int arg13,int arg14,int arg15,int arg16,int arg17,int arg18) { + script_1346(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18); + return; +} diff --git a/dumps/scripts/1342.cs2 b/dumps/scripts/1342.cs2 new file mode 100644 index 0000000..d17d773 --- /dev/null +++ b/dumps/scripts/1342.cs2 @@ -0,0 +1,4 @@ +void script_1342(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + script_1346(arg0, 0, arg1, arg2, arg3, arg4, arg5, 897, 788, 788, 1040, 16777215, 16776960, 494, 792, 789, 790, 791, 773, 788); + return; +} diff --git a/dumps/scripts/1343.cs2 b/dumps/scripts/1343.cs2 new file mode 100644 index 0000000..e3b5575 --- /dev/null +++ b/dumps/scripts/1343.cs2 @@ -0,0 +1,4 @@ +void script_1343(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11) { + script_1346(arg0, 0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg7, arg8, arg9, arg10, arg11, 792, 789, 790, 791, 773, 788); + return; +} diff --git a/dumps/scripts/1344.cs2 b/dumps/scripts/1344.cs2 new file mode 100644 index 0000000..91051e4 --- /dev/null +++ b/dumps/scripts/1344.cs2 @@ -0,0 +1,4 @@ +void script_1344(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12,int arg13,int arg14,int arg15,int arg16,int arg17) { + script_1346(arg0, 0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17); + return; +} diff --git a/dumps/scripts/1345.cs2 b/dumps/scripts/1345.cs2 new file mode 100644 index 0000000..203ba08 --- /dev/null +++ b/dumps/scripts/1345.cs2 @@ -0,0 +1,5 @@ +int script_1345(int arg0,int arg1) { + int ivar2; + ivar2 = divide(add(arg0, cs2method2601(new WidgetPointer(arg1))), 15); + return ivar2; +} diff --git a/dumps/scripts/1346.cs2 b/dumps/scripts/1346.cs2 new file mode 100644 index 0000000..8bbf4d4 --- /dev/null +++ b/dumps/scripts/1346.cs2 @@ -0,0 +1,4 @@ +void script_1346(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12,int arg13,int arg14,int arg15,int arg16,int arg17,int arg18,int arg19) { + script_1436(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19); + return; +} diff --git a/dumps/scripts/1347.cs2 b/dumps/scripts/1347.cs2 new file mode 100644 index 0000000..3db3f04 --- /dev/null +++ b/dumps/scripts/1347.cs2 @@ -0,0 +1,9 @@ +void script_1347(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12,int arg13,int arg14,int arg15,int arg16,int arg17,int arg18) { + if (isWidgetHidden(new WidgetPointer(arg2))) { + cs2method2100(0, 0, new WidgetPointer(arg4)); + script_1348(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18); + } else { + script_1349(arg6, arg2, arg4, arg5, arg12); + } + return; +} diff --git a/dumps/scripts/1348.cs2 b/dumps/scripts/1348.cs2 new file mode 100644 index 0000000..0839317 --- /dev/null +++ b/dumps/scripts/1348.cs2 @@ -0,0 +1,50 @@ +void script_1348(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12,int arg13,int arg14,int arg15,int arg16,int arg17,int arg18) { + int ivar19; + int ivar20; + string svar0; + if (setWidgetRegister(new WidgetPointer(arg6), arg12)) { + setWidgetVFlip(1); + } + createExtraChild(new WidgetPointer(arg2), 5, getExtraChildGap(new WidgetPointer(arg2))); + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg2)), getWidgetActualHeight(new WidgetPointer(arg2)), 0, 0); + setWidgetSprite(arg3); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg2), 3, getExtraChildGap(new WidgetPointer(arg2))); + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg2)), getWidgetActualHeight(new WidgetPointer(arg2)), 0, 0); + setWidgetRGB(new Color(0, 0, 0)); + setWidgetScrollMax(getWidgetActualWidth(new WidgetPointer(arg4)), multiply(arg1, 15), new WidgetPointer(arg4)); + ivar19 = 0; + ivar20 = -1; + svar0 = ""; + while (ivar19 <= arg1) { + ivar20 = getExtraChildGap(new WidgetPointer(arg4)); + svar0 = cs2method_3408(105, 115, arg0, ivar19); + createExtraChild(new WidgetPointer(arg4), 4, ivar20); + setWidgetText(svar0); + setWidgetTextAlignment(0, 1, 0); + setWidgetPosition(5, multiply(ivar19, 15), 0, 0); + setWidgetSize(subtract(getWidgetActualWidth(new WidgetPointer(arg4)), 16), 15, 0, 0); + setWidgetUnknownBoolean(false); + setWidgetFont(arg10); + if (ivar19 >= arg1) { + setWidgetRGB(new Color(arg8)); + setScriptCallOnMouseExit(1354, new WidgetPointer(arg4), ivar20, arg8, "Iii"); + setScriptCallOnMousePressed(1350, new WidgetPointer(arg2), new WidgetPointer(arg4), new WidgetPointer(arg5), new WidgetPointer(arg6), arg11, arg12, svar0, arg8, "IIIIiisi"); + } else { + setWidgetRGB(new Color(arg7)); + setScriptCallOnMouseExit(1354, new WidgetPointer(arg4), ivar20, arg7, "Iii"); + setScriptCallOnMousePressed(1350, new WidgetPointer(arg2), new WidgetPointer(arg4), new WidgetPointer(arg5), new WidgetPointer(arg6), arg11, arg12, svar0, arg7, "IIIIiisi"); + } + setScriptCallOnMouseEntered(1353, new WidgetPointer(arg4), ivar20, arg9, "Iii"); + ivar19 = add(ivar19, 1); + } + if (arg5 != -1) { + script_31(arg5, arg4, arg13, arg14, arg15, arg16, arg17, arg18); + setWidgetIsHidden(false, new WidgetPointer(arg5)); + } + setWidgetIsHidden(false, new WidgetPointer(arg2)); + setWidgetIsHidden(false, new WidgetPointer(arg4)); + return; +} diff --git a/dumps/scripts/1349.cs2 b/dumps/scripts/1349.cs2 new file mode 100644 index 0000000..b6c3451 --- /dev/null +++ b/dumps/scripts/1349.cs2 @@ -0,0 +1,16 @@ +void script_1349(int arg0,int arg1,int arg2,int arg3,int arg4) { + if (setWidgetRegister(new WidgetPointer(arg0), arg4)) { + setWidgetVFlip(0); + } + setWidgetIsHidden(true, new WidgetPointer(arg1)); + setWidgetIsHidden(true, new WidgetPointer(arg2)); + if (arg3 != -1) { + setWidgetIsHidden(true, new WidgetPointer(arg3)); + } + deleteAllExtraChilds(new WidgetPointer(arg1)); + deleteAllExtraChilds(new WidgetPointer(arg2)); + if (arg3 != -1) { + deleteAllExtraChilds(new WidgetPointer(arg3)); + } + return; +} diff --git a/dumps/scripts/135.cs2 b/dumps/scripts/135.cs2 new file mode 100644 index 0000000..95deddf --- /dev/null +++ b/dumps/scripts/135.cs2 @@ -0,0 +1,17 @@ +void script_135(int arg0) { + int ivar1; + ivar1 = -1; + if (strLength(globalstring_24) > 0) { + cs2method5002(arg0, globalint_6, globalstring_24, ""); + } + if (((boolean)stringMethod4107(globalstring_24, cs2method5015()))) { + script_675(); + return; + } + if (cs2method3623(globalstring_24) && (stringMethod4107(globalstring_24, cs2method5015()) != 0)) { + script_221(); + } else { + script_675(); + } + return; +} diff --git a/dumps/scripts/1350.cs2 b/dumps/scripts/1350.cs2 new file mode 100644 index 0000000..2e9dadf --- /dev/null +++ b/dumps/scripts/1350.cs2 @@ -0,0 +1,9 @@ +void script_1350(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,string arg7) { + if (setWidgetRegister(new WidgetPointer(arg3), arg4)) { + setWidgetText(arg7); + setWidgetRGB(new Color(arg6)); + setScriptCallOnMouseExit(1354, new WidgetPointer(arg3), arg4, arg6, "Iii"); + } + script_1349(arg3, arg0, arg1, arg2, arg5); + return; +} diff --git a/dumps/scripts/1351.cs2 b/dumps/scripts/1351.cs2 new file mode 100644 index 0000000..92abce8 --- /dev/null +++ b/dumps/scripts/1351.cs2 @@ -0,0 +1,6 @@ +void script_1351(int arg0,int arg1,int arg2) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetSprite(arg2); + } + return; +} diff --git a/dumps/scripts/1352.cs2 b/dumps/scripts/1352.cs2 new file mode 100644 index 0000000..e3b14fa --- /dev/null +++ b/dumps/scripts/1352.cs2 @@ -0,0 +1,6 @@ +void script_1352(int arg0,int arg1,int arg2) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetSprite(arg2); + } + return; +} diff --git a/dumps/scripts/1353.cs2 b/dumps/scripts/1353.cs2 new file mode 100644 index 0000000..edc53c5 --- /dev/null +++ b/dumps/scripts/1353.cs2 @@ -0,0 +1,6 @@ +void script_1353(int arg0,int arg1,int arg2) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetRGB(new Color(arg2)); + } + return; +} diff --git a/dumps/scripts/1354.cs2 b/dumps/scripts/1354.cs2 new file mode 100644 index 0000000..3a57f06 --- /dev/null +++ b/dumps/scripts/1354.cs2 @@ -0,0 +1,6 @@ +void script_1354(int arg0,int arg1,int arg2) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetRGB(new Color(arg2)); + } + return; +} diff --git a/dumps/scripts/1355.cs2 b/dumps/scripts/1355.cs2 new file mode 100644 index 0000000..a8d0bea --- /dev/null +++ b/dumps/scripts/1355.cs2 @@ -0,0 +1,26 @@ +void script_1355(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,string arg7) { + deleteAllExtraChilds(new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(arg1)); + setWidgetIsHidden(true, new WidgetPointer(arg2)); + if (arg3 != -1) { + setWidgetIsHidden(true, new WidgetPointer(arg3)); + } + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg0)), getWidgetActualHeight(new WidgetPointer(arg0)), 0, 0); + setWidgetSprite(arg4); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg0), 3, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg0)), getWidgetActualHeight(new WidgetPointer(arg0)), 0, 0); + setWidgetRGB(new Color(0, 0, 0)); + createExtraChild(new WidgetPointer(arg0), 4, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetText(arg7); + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg0)), getWidgetActualHeight(new WidgetPointer(arg0)), 0, 0); + setWidgetUnknownBoolean(false); + setWidgetFont(arg6); + setWidgetTextAlignment(1, 1, 0); + setWidgetRGB(new Color(arg5)); + return; +} diff --git a/dumps/scripts/1356.cs2 b/dumps/scripts/1356.cs2 new file mode 100644 index 0000000..723b797 --- /dev/null +++ b/dumps/scripts/1356.cs2 @@ -0,0 +1,6 @@ +void script_1356(int arg0,int arg1,int arg2) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetRGB(new Color(arg2)); + } + return; +} diff --git a/dumps/scripts/1357.cs2 b/dumps/scripts/1357.cs2 new file mode 100644 index 0000000..64b1355 --- /dev/null +++ b/dumps/scripts/1357.cs2 @@ -0,0 +1,4 @@ +void script_1357(int arg0,int arg1) { + cs2method2103(arg1, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1358.cs2 b/dumps/scripts/1358.cs2 new file mode 100644 index 0000000..13b0d45 --- /dev/null +++ b/dumps/scripts/1358.cs2 @@ -0,0 +1,6 @@ +void script_1358(int arg0,int arg1) { + deleteAllExtraChilds(new WidgetPointer(arg0)); + globalint_2 = 0; + script_680(arg1); + return; +} diff --git a/dumps/scripts/1359.cs2 b/dumps/scripts/1359.cs2 new file mode 100644 index 0000000..ddb6f8d --- /dev/null +++ b/dumps/scripts/1359.cs2 @@ -0,0 +1,16 @@ +void script_1359(int arg0) { + if ((globalint_1024 == bitconfig_6521) && (globalint_1024 != 0)) { + if ((arg0 == 12582937) || (arg0 == 12583010)) { + if (globalint_1024 == 28) { + setScriptCallOnGameloop(1427, new WidgetPointer(arg0), "I", new WidgetPointer(192,98)); + } else { + setScriptCallOnGameloop(1427, new WidgetPointer(arg0), "I", new WidgetPointer(192,25)); + } + } else { + setScriptCallOnGameloop(1427, new WidgetPointer(arg0), "I", new WidgetPointer(arg0)); + } + } else { + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/136.cs2 b/dumps/scripts/136.cs2 new file mode 100644 index 0000000..1f6e0b5 --- /dev/null +++ b/dumps/scripts/136.cs2 @@ -0,0 +1,24 @@ +void script_136(int arg0) { + string svar0; + svar0 = ""; + if (arg0 == 40173583) { + svar0 = getItemName(standart_config_1068); + if (standart_config_1068 == -1) { + svar0 = "Empty"; + } + } else if (arg0 == 40173584) { + svar0 = getItemName(standart_config_1069); + if (standart_config_1069 == -1) { + svar0 = "Empty"; + } + } else { + if (arg0 == 40173585) { + svar0 = getItemName(standart_config_1070); + if (standart_config_1070 == -1) { + svar0 = "Empty"; + } + } + } + script_39(arg0, 40173591, 25, 199, svar0); + return; +} diff --git a/dumps/scripts/1360.cs2 b/dumps/scripts/1360.cs2 new file mode 100644 index 0000000..bdff813 --- /dev/null +++ b/dumps/scripts/1360.cs2 @@ -0,0 +1,30 @@ +void script_1360(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + deleteAllExtraChilds(new WidgetPointer(arg0)); + ivar1 = getWidgetActualWidth(new WidgetPointer(arg0)); + ivar2 = getWidgetActualHeight(new WidgetPointer(arg0)); + ivar3 = subtract(ivar1, 9); + ivar4 = subtract(ivar2, 9); + ivar5 = subtract(ivar1, 18); + ivar6 = subtract(ivar2, 18); + createExtraChild(new WidgetPointer(arg0), 3, 0); + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(ivar1, ivar2, 0, 0); + setWidgetFilled(1); + setWidgetRGB(new Color(48, 32, 28)); + cs2method2103(200); + script_98(arg0, 1, 921, 0, 0, 9, 9); + script_98(arg0, 2, 922, ivar3, 0, 9, 9); + script_98(arg0, 3, 923, 0, ivar4, 9, 9); + script_98(arg0, 4, 924, ivar3, ivar4, 9, 9); + script_98(arg0, 5, 925, 0, 9, 9, ivar6); + script_98(arg0, 6, 926, 9, 0, ivar5, 9); + script_98(arg0, 7, 927, ivar3, 9, 9, ivar6); + script_98(arg0, 8, 928, 9, ivar4, ivar5, 9); + return; +} diff --git a/dumps/scripts/1361.cs2 b/dumps/scripts/1361.cs2 new file mode 100644 index 0000000..2e2d648 --- /dev/null +++ b/dumps/scripts/1361.cs2 @@ -0,0 +1,25 @@ +void script_1361(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + deleteAllExtraChilds(new WidgetPointer(arg0)); + ivar1 = getWidgetActualWidth(new WidgetPointer(arg0)); + ivar2 = getWidgetActualHeight(new WidgetPointer(arg0)); + ivar3 = subtract(ivar1, 9); + ivar4 = subtract(ivar2, 9); + ivar5 = subtract(ivar1, 18); + ivar6 = subtract(ivar2, 18); + script_98(arg0, 0, 897, 0, 0, ivar1, ivar2); + script_98(arg0, 1, 921, 0, 0, 9, 9); + script_98(arg0, 2, 922, ivar3, 0, 9, 9); + script_98(arg0, 3, 923, 0, ivar4, 9, 9); + script_98(arg0, 4, 924, ivar3, ivar4, 9, 9); + script_98(arg0, 5, 925, 0, 9, 9, ivar6); + script_98(arg0, 6, 926, 9, 0, ivar5, 9); + script_98(arg0, 7, 927, ivar3, 9, 9, ivar6); + script_98(arg0, 8, 928, 9, ivar4, ivar5, 9); + return; +} diff --git a/dumps/scripts/1362.cs2 b/dumps/scripts/1362.cs2 new file mode 100644 index 0000000..dc7f00f --- /dev/null +++ b/dumps/scripts/1362.cs2 @@ -0,0 +1,64 @@ +void script_1362() { + int ivar0; + ivar0 = 0; + setScriptCallOnKeyPress(73, -2147483640, false, "iz", new WidgetPointer(137,56)); + setScriptCallOnMessage(81, 1, "1", new WidgetPointer(751,0)); + setScriptCallOnClanListChange(81, 1, "1", new WidgetPointer(751,0)); + setScriptCallOnFriendListChange(81, 0, "1", new WidgetPointer(751,0)); + setScriptCallOnGeneralDataChange(82, "", new WidgetPointer(751,0)); + setScriptCallOnGlobalStringChange(710, 0, 1, "Y", new WidgetPointer(751,0)); + globalstring_1 = ""; + globalint_1028 = 0; + globalint_42 = -1; + globalint_41 = 0; + globalint_43 = cs2method5017(); + globalint_3 = -1; + globalint_4 = 0; + globalstring_2 = ""; + globalstring_3 = ""; + globalstring_4 = ""; + globalstring_5 = ""; + globalstring_6 = ""; + globalstring_7 = ""; + globalstring_8 = ""; + globalstring_9 = ""; + globalstring_10 = ""; + globalstring_11 = ""; + globalstring_12 = ""; + globalstring_13 = ""; + globalstring_14 = ""; + globalstring_15 = ""; + globalstring_16 = ""; + globalstring_17 = ""; + globalstring_18 = ""; + globalstring_19 = ""; + globalstring_20 = ""; + globalstring_21 = ""; + globalstring_276 = ""; + script_1558(1); + setWidgetIsHidden(false, new WidgetPointer(137,56)); + if (getDisplayMode() >= 2) { + setWidgetIsHidden(true, new WidgetPointer(752,2)); + setWidgetSprite(1247, new WidgetPointer(752,1)); + cs2method2122(1, 49283073); + setWidgetIsHidden(false, new WidgetPointer(752,1)); + setWidgetIsHidden(true, new WidgetPointer(137,51)); + setWidgetIsHidden(false, new WidgetPointer(137,52)); + setWidgetIsHidden(false, new WidgetPointer(137,53)); + setWidgetUnknownBoolean(true, new WidgetPointer(137,56)); + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(137,56)); + } else { + setWidgetSprite(1017, new WidgetPointer(752,1)); + setWidgetIsHidden(false, new WidgetPointer(752,1)); + setWidgetIsHidden(false, new WidgetPointer(752,2)); + setWidgetIsHidden(false, new WidgetPointer(137,51)); + setWidgetIsHidden(true, new WidgetPointer(137,52)); + setWidgetIsHidden(true, new WidgetPointer(137,53)); + setWidgetUnknownBoolean(false, new WidgetPointer(137,56)); + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(137,56)); + } + globalint_7 = getWidgetActualHeight(new WidgetPointer(137,58)); + script_178(); + globalstring_0 = ""; + return; +} diff --git a/dumps/scripts/1363.cs2 b/dumps/scripts/1363.cs2 new file mode 100644 index 0000000..84d0ea5 --- /dev/null +++ b/dumps/scripts/1363.cs2 @@ -0,0 +1,30 @@ +void script_1363(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + deleteAllExtraChilds(new WidgetPointer(arg0)); + ivar1 = getWidgetActualWidth(new WidgetPointer(arg0)); + ivar2 = getWidgetActualHeight(new WidgetPointer(arg0)); + ivar3 = subtract(ivar1, 9); + ivar4 = subtract(ivar2, 9); + ivar5 = subtract(ivar1, 18); + ivar6 = subtract(ivar2, 18); + createExtraChild(new WidgetPointer(arg0), 3, 0); + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(ivar1, ivar2, 0, 0); + setWidgetFilled(1); + setWidgetRGB(new Color(255, 255, 255)); + cs2method2103(240); + script_98(arg0, 1, 929, 0, 0, 9, 9); + script_98(arg0, 2, 930, ivar3, 0, 9, 9); + script_98(arg0, 3, 931, 0, ivar4, 9, 9); + script_98(arg0, 4, 932, ivar3, ivar4, 9, 9); + script_98(arg0, 5, 933, 0, 9, 9, ivar6); + script_98(arg0, 6, 934, 9, 0, ivar5, 9); + script_98(arg0, 7, 935, ivar3, 9, 9, ivar6); + script_98(arg0, 8, 936, 9, ivar4, ivar5, 9); + return; +} diff --git a/dumps/scripts/1364.cs2 b/dumps/scripts/1364.cs2 new file mode 100644 index 0000000..d404b1d --- /dev/null +++ b/dumps/scripts/1364.cs2 @@ -0,0 +1,359 @@ +void script_1364() { + int ivar0; + ivar0 = 0; + if (getDisplayMode() >= 2) { + flow_1: + if (isWidgetHidden(new WidgetPointer(752,8)) && (isWidgetHidden(new WidgetPointer(752,3)) || isWidgetHidden(new WidgetPointer(752,7)))) { + setWidgetIsHidden(false, new WidgetPointer(746,73)); + setWidgetSprite(1017, new WidgetPointer(752,1)); + setWidgetIsHidden(false, new WidgetPointer(752,1)); + setWidgetIsHidden(false, new WidgetPointer(752,2)); + cs2method2122(0, 49283073); + } else if (isWidgetOpen(new WidgetPointer(752,13))) { + setWidgetIsHidden(false, new WidgetPointer(746,73)); + setWidgetIsHidden(false, new WidgetPointer(752,13)); + setWidgetIsHidden(true, new WidgetPointer(752,12)); + setWidgetIsHidden(true, new WidgetPointer(752,11)); + setWidgetIsHidden(true, new WidgetPointer(752,10)); + setWidgetIsHidden(true, new WidgetPointer(752,9)); + setWidgetIsHidden(false, new WidgetPointer(752,1)); + cs2method2122(1, 49283073); + if (((boolean)bitconfig_542)) { + setWidgetSprite(1204, new WidgetPointer(752,1)); + setWidgetIsHidden(false, new WidgetPointer(752,2)); + } else { + setWidgetSprite(1205, new WidgetPointer(752,1)); + setWidgetIsHidden(true, new WidgetPointer(752,2)); + } + } else if (isWidgetOpen(new WidgetPointer(752,12))) { + setWidgetIsHidden(false, new WidgetPointer(746,73)); + setWidgetIsHidden(true, new WidgetPointer(752,13)); + setWidgetIsHidden(false, new WidgetPointer(752,12)); + setWidgetIsHidden(true, new WidgetPointer(752,11)); + setWidgetIsHidden(true, new WidgetPointer(752,10)); + setWidgetIsHidden(true, new WidgetPointer(752,9)); + setWidgetIsHidden(false, new WidgetPointer(752,1)); + cs2method2122(1, 49283073); + if (((boolean)bitconfig_542)) { + setWidgetSprite(1204, new WidgetPointer(752,1)); + setWidgetIsHidden(false, new WidgetPointer(752,2)); + } else { + setWidgetSprite(1205, new WidgetPointer(752,1)); + setWidgetIsHidden(true, new WidgetPointer(752,2)); + } + } else if (isWidgetOpen(new WidgetPointer(752,11))) { + setWidgetIsHidden(false, new WidgetPointer(746,73)); + setWidgetIsHidden(true, new WidgetPointer(752,13)); + setWidgetIsHidden(true, new WidgetPointer(752,12)); + setWidgetIsHidden(false, new WidgetPointer(752,11)); + setWidgetIsHidden(true, new WidgetPointer(752,10)); + setWidgetIsHidden(true, new WidgetPointer(752,9)); + setWidgetIsHidden(false, new WidgetPointer(752,1)); + cs2method2122(1, 49283073); + if (((boolean)bitconfig_542)) { + setWidgetSprite(1204, new WidgetPointer(752,1)); + setWidgetIsHidden(false, new WidgetPointer(752,2)); + } else { + setWidgetSprite(1205, new WidgetPointer(752,1)); + setWidgetIsHidden(true, new WidgetPointer(752,2)); + } + } else if (isWidgetOpen(new WidgetPointer(752,10))) { + setWidgetIsHidden(false, new WidgetPointer(746,73)); + setWidgetIsHidden(true, new WidgetPointer(752,13)); + setWidgetIsHidden(true, new WidgetPointer(752,12)); + setWidgetIsHidden(true, new WidgetPointer(752,11)); + setWidgetIsHidden(false, new WidgetPointer(752,10)); + setWidgetIsHidden(true, new WidgetPointer(752,9)); + setWidgetIsHidden(false, new WidgetPointer(752,1)); + cs2method2122(1, 49283073); + if (((boolean)bitconfig_542)) { + setWidgetSprite(1204, new WidgetPointer(752,1)); + setWidgetIsHidden(false, new WidgetPointer(752,2)); + } else { + setWidgetSprite(1205, new WidgetPointer(752,1)); + setWidgetIsHidden(true, new WidgetPointer(752,2)); + } + } else { + if (isWidgetOpen(new WidgetPointer(752,9))) { + if (globalint_41 == -1) { + setWidgetIsHidden(true, new WidgetPointer(746,73)); + setWidgetIsHidden(true, new WidgetPointer(746,75)); + } else { + setWidgetIsHidden(false, new WidgetPointer(746,73)); + setWidgetIsHidden(false, new WidgetPointer(746,75)); + } + setWidgetIsHidden(true, new WidgetPointer(752,13)); + setWidgetIsHidden(true, new WidgetPointer(752,12)); + setWidgetIsHidden(true, new WidgetPointer(752,11)); + setWidgetIsHidden(true, new WidgetPointer(752,10)); + setWidgetIsHidden(false, new WidgetPointer(752,9)); + setWidgetIsHidden(false, new WidgetPointer(752,1)); + if (isWidgetHidden(new WidgetPointer(137,0))) { + setWidgetSprite(1017, new WidgetPointer(752,1)); + cs2method2122(0, 49283073); + setWidgetIsHidden(false, new WidgetPointer(752,2)); + } else { + setWidgetIsHidden(true, new WidgetPointer(752,2)); + setWidgetSprite(1247, new WidgetPointer(752,1)); + cs2method2122(1, 49283073); + cs2method2107(0, new WidgetPointer(752,1)); + setWidgetIsHidden(true, new WidgetPointer(137,51)); + setWidgetIsHidden(false, new WidgetPointer(137,52)); + setWidgetIsHidden(false, new WidgetPointer(137,53)); + script_1301(8978491, 8978490); + setWidgetUnknownBoolean(true, new WidgetPointer(137,56)); + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(137,56)); + script_1558(0); + script_84(); + } + } + } + if (isWidgetOpen(new WidgetPointer(746,87))) { + setWidgetIsHidden(true, new WidgetPointer(746,22)); + setWidgetIsHidden(true, new WidgetPointer(746,23)); + setWidgetIsHidden(true, new WidgetPointer(746,71)); + setWidgetIsHidden(false, new WidgetPointer(746,87)); + setWidgetIsHidden(true, new WidgetPointer(746,88)); + setWidgetIsHidden(false, new WidgetPointer(746,86)); + setWidgetIsHidden(true, new WidgetPointer(746,89)); + setWidgetIsHidden(true, new WidgetPointer(746,176)); + } else { + setWidgetIsHidden(false, new WidgetPointer(746,22)); + setWidgetIsHidden(false, new WidgetPointer(746,23)); + if (((boolean)bitconfig_6448)) { + setWidgetIsHidden(false, new WidgetPointer(746,71)); + } + setWidgetIsHidden(false, new WidgetPointer(746,89)); + setWidgetIsHidden(false, new WidgetPointer(746,176)); + if (isWidgetOpen(new WidgetPointer(746,88))) { + setWidgetIsHidden(true, new WidgetPointer(746,87)); + } + script_71(globalint_168); + if (((((((((((((((((isWidgetHidden(new WidgetPointer(746,90)) || isWidgetHidden(new WidgetPointer(746,91))) || isWidgetHidden(new WidgetPointer(746,92))) || isWidgetHidden(new WidgetPointer(746,93))) || isWidgetHidden(new WidgetPointer(746,94))) || isWidgetHidden(new WidgetPointer(746,95))) || isWidgetHidden(new WidgetPointer(746,96))) || isWidgetHidden(new WidgetPointer(746,97))) || isWidgetHidden(new WidgetPointer(746,98))) || isWidgetHidden(new WidgetPointer(746,99))) || isWidgetHidden(new WidgetPointer(746,100))) || isWidgetHidden(new WidgetPointer(746,101))) || isWidgetHidden(new WidgetPointer(746,102))) || isWidgetHidden(new WidgetPointer(746,103))) || isWidgetHidden(new WidgetPointer(746,104))) || isWidgetHidden(new WidgetPointer(746,105))) || isWidgetHidden(new WidgetPointer(746,107))) || isWidgetHidden(new WidgetPointer(746,108))) { + setWidgetIsHidden(false, new WidgetPointer(746,86)); + } else { + setWidgetIsHidden(true, new WidgetPointer(746,86)); + } + setScriptCallOnGameloop(2464, getClientCycle(), new WidgetPointer(-32768,3), "iI", new WidgetPointer(746,73)); + } + setWidgetIsHidden(true, new WidgetPointer(548,200)); + ivar0 = 0; + while (ivar0 <= 15) { + if (isWidgetOpen(new WidgetPointer(script_8(ivar0)))) { + setWidgetIsHidden(false, new WidgetPointer(script_121(ivar0))); + setWidgetIsHidden(false, new WidgetPointer(script_2458(ivar0))); + } else { + setWidgetIsHidden(true, new WidgetPointer(script_121(ivar0))); + setWidgetIsHidden(true, new WidgetPointer(script_2458(ivar0))); + } + ivar0 = add(ivar0, 1); + } + if (isWidgetOpen(new WidgetPointer(script_8(95))) && ((boolean)bitconfig_4280)) { + setWidgetIsHidden(false, new WidgetPointer(747,8)); + } else { + setWidgetIsHidden(true, new WidgetPointer(747,8)); + } + ivar0 = 0; + IF (isWidgetHidden(new WidgetPointer(746,23))) + GOTO flow_52 + GOTO flow_55 + flow_52: + IF (ivar0 <= 15) + GOTO flow_53 + GOTO flow_54 + flow_53: + setScriptCallOnMouseEntered(-1, "", new WidgetPointer(script_2459(ivar0))); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(script_2459(ivar0))); + setWidgetSprite(1835, new WidgetPointer(script_2459(ivar0))); + ivar0 = add(ivar0, 1); + GOTO flow_52 + flow_54: + GOTO flow_60 + flow_55: + IF (ivar0 <= 15) + GOTO flow_56 + GOTO flow_60 + flow_56: + if (isWidgetHidden(new WidgetPointer(script_121(ivar0)))) { + setScriptCallOnMouseEntered(-1, "", new WidgetPointer(script_2459(ivar0))); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(script_2459(ivar0))); + setWidgetSprite(1835, new WidgetPointer(script_2459(ivar0))); + } else { + setScriptCallOnMouseEntered(2462, new WidgetPointer(-32768,3), 1, "I1", new WidgetPointer(script_2459(ivar0))); + setScriptCallOnMouseExit(2462, new WidgetPointer(-32768,3), 0, "I1", new WidgetPointer(script_2459(ivar0))); + } + ivar0 = add(ivar0, 1); + GOTO flow_55 + flow_60: + script_1313(); + setWidgetPosition(0, 0, 0, 0, new WidgetPointer(745,0)); + setWidgetSize(115, 35, 0, 0, new WidgetPointer(745,0)); + setWidgetPosition(80, 0, 0, 0, new WidgetPointer(745,1)); + setWidgetPosition(40, 0, 0, 0, new WidgetPointer(745,2)); + setWidgetPosition(0, 0, 0, 0, new WidgetPointer(745,3)); + setWidgetPosition(0, 0, 0, 0, new WidgetPointer(745,4)); + setWidgetPosition(0, 0, 0, 0, new WidgetPointer(745,5)); + setWidgetPosition(0, 0, 0, 0, new WidgetPointer(745,6)); + setWidgetSize(35, 35, 0, 0, new WidgetPointer(745,1)); + setWidgetSize(35, 35, 0, 0, new WidgetPointer(745,2)); + setWidgetSize(35, 35, 0, 0, new WidgetPointer(745,3)); + setWidgetSize(35, 35, 0, 0, new WidgetPointer(745,4)); + setWidgetSize(35, 35, 0, 0, new WidgetPointer(745,5)); + setWidgetSize(35, 35, 0, 0, new WidgetPointer(745,6)); + setWidgetSprite(1563, new WidgetPointer(745,1)); + setWidgetSprite(1562, new WidgetPointer(745,2)); + setWidgetSprite(1579, new WidgetPointer(745,3)); + setWidgetSprite(1580, new WidgetPointer(745,4)); + setWidgetSprite(1581, new WidgetPointer(745,6)); + } else { + flow_61: + if ((globalint_41 == -1) && (standart_config_281 >= 1000)) { + globalint_41 = 0; + script_181(0); + script_178(); + script_84(); + script_89(); + } + setWidgetSprite(1017, new WidgetPointer(752,1)); + setWidgetIsHidden(false, new WidgetPointer(752,1)); + setWidgetIsHidden(false, new WidgetPointer(752,2)); + cs2method2122(0, 49283073); + cs2method2107(1, new WidgetPointer(752,1)); + if (isWidgetOpen(new WidgetPointer(752,13))) { + setWidgetIsHidden(false, new WidgetPointer(752,13)); + setWidgetIsHidden(true, new WidgetPointer(752,12)); + setWidgetIsHidden(true, new WidgetPointer(752,11)); + setWidgetIsHidden(true, new WidgetPointer(752,10)); + setWidgetIsHidden(true, new WidgetPointer(752,9)); + } else if (isWidgetOpen(new WidgetPointer(752,12))) { + setWidgetIsHidden(true, new WidgetPointer(752,13)); + setWidgetIsHidden(false, new WidgetPointer(752,12)); + setWidgetIsHidden(true, new WidgetPointer(752,11)); + setWidgetIsHidden(true, new WidgetPointer(752,10)); + setWidgetIsHidden(true, new WidgetPointer(752,9)); + } else if (isWidgetOpen(new WidgetPointer(752,11))) { + setWidgetIsHidden(true, new WidgetPointer(752,13)); + setWidgetIsHidden(true, new WidgetPointer(752,12)); + setWidgetIsHidden(false, new WidgetPointer(752,11)); + setWidgetIsHidden(true, new WidgetPointer(752,10)); + setWidgetIsHidden(true, new WidgetPointer(752,9)); + } else if (isWidgetOpen(new WidgetPointer(752,10))) { + setWidgetIsHidden(true, new WidgetPointer(752,13)); + setWidgetIsHidden(true, new WidgetPointer(752,12)); + setWidgetIsHidden(true, new WidgetPointer(752,11)); + setWidgetIsHidden(false, new WidgetPointer(752,10)); + setWidgetIsHidden(true, new WidgetPointer(752,9)); + } else { + if (isWidgetOpen(new WidgetPointer(752,9))) { + setWidgetIsHidden(true, new WidgetPointer(752,13)); + setWidgetIsHidden(true, new WidgetPointer(752,12)); + setWidgetIsHidden(true, new WidgetPointer(752,11)); + setWidgetIsHidden(true, new WidgetPointer(752,10)); + setWidgetIsHidden(false, new WidgetPointer(752,9)); + setWidgetIsHidden(false, new WidgetPointer(137,51)); + setWidgetIsHidden(true, new WidgetPointer(137,52)); + setWidgetIsHidden(true, new WidgetPointer(137,53)); + script_1301(8978491, 8978490); + setWidgetUnknownBoolean(false, new WidgetPointer(137,56)); + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(137,56)); + script_1558(0); + script_84(); + } + } + if (isWidgetOpen(new WidgetPointer(548,199))) { + setWidgetIsHidden(true, new WidgetPointer(548,81)); + setWidgetIsHidden(true, new WidgetPointer(548,82)); + setWidgetIsHidden(true, new WidgetPointer(548,128)); + setWidgetIsHidden(true, new WidgetPointer(548,146)); + setWidgetIsHidden(false, new WidgetPointer(548,199)); + setWidgetIsHidden(true, new WidgetPointer(548,200)); + setWidgetIsHidden(true, new WidgetPointer(548,201)); + setWidgetIsHidden(true, new WidgetPointer(548,182)); + } else { + setWidgetIsHidden(false, new WidgetPointer(548,81)); + setWidgetIsHidden(false, new WidgetPointer(548,82)); + setWidgetIsHidden(false, new WidgetPointer(548,128)); + setWidgetIsHidden(false, new WidgetPointer(548,146)); + setWidgetIsHidden(false, new WidgetPointer(548,201)); + setWidgetIsHidden(false, new WidgetPointer(548,182)); + setWidgetIsHidden(true, new WidgetPointer(746,87)); + if (isWidgetOpen(new WidgetPointer(548,200))) { + setWidgetIsHidden(true, new WidgetPointer(548,200)); + } + script_71(globalint_168); + setScriptCallOnGameloop(2464, getClientCycle(), new WidgetPointer(-32768,3), "iI", new WidgetPointer(548,193)); + } + ivar0 = 0; + while (ivar0 <= 15) { + if (isWidgetOpen(new WidgetPointer(script_8(ivar0)))) { + setWidgetIsHidden(false, new WidgetPointer(script_121(ivar0))); + setWidgetIsHidden(false, new WidgetPointer(script_2458(ivar0))); + } else { + setWidgetIsHidden(true, new WidgetPointer(script_121(ivar0))); + setWidgetIsHidden(true, new WidgetPointer(script_2458(ivar0))); + } + ivar0 = add(ivar0, 1); + } + if (isWidgetOpen(new WidgetPointer(script_8(95))) && ((boolean)bitconfig_4280)) { + setWidgetIsHidden(false, new WidgetPointer(747,8)); + } else { + setWidgetIsHidden(true, new WidgetPointer(747,8)); + } + ivar0 = 0; + IF (isWidgetHidden(new WidgetPointer(548,81)) && isWidgetHidden(new WidgetPointer(548,128))) + GOTO flow_91 + GOTO flow_94 + flow_91: + IF (ivar0 <= 15) + GOTO flow_92 + GOTO flow_93 + flow_92: + setScriptCallOnMouseEntered(-1, "", new WidgetPointer(script_2459(ivar0))); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(script_2459(ivar0))); + setWidgetSprite(1835, new WidgetPointer(script_2459(ivar0))); + ivar0 = add(ivar0, 1); + GOTO flow_91 + flow_93: + GOTO flow_99 + flow_94: + IF (ivar0 <= 15) + GOTO flow_95 + GOTO flow_99 + flow_95: + if (isWidgetHidden(new WidgetPointer(script_121(ivar0)))) { + setScriptCallOnMouseEntered(-1, "", new WidgetPointer(script_2459(ivar0))); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(script_2459(ivar0))); + setWidgetSprite(1835, new WidgetPointer(script_2459(ivar0))); + } else { + setScriptCallOnMouseEntered(2462, new WidgetPointer(-32768,3), 1, "I1", new WidgetPointer(script_2459(ivar0))); + setScriptCallOnMouseExit(2462, new WidgetPointer(-32768,3), 0, "I1", new WidgetPointer(script_2459(ivar0))); + } + ivar0 = add(ivar0, 1); + GOTO flow_94 + flow_99: + script_1658(); + script_1337(); + setWidgetPosition(0, 0, 0, 0, new WidgetPointer(745,0)); + setWidgetSize(82, 25, 0, 0, new WidgetPointer(745,0)); + setWidgetPosition(57, 0, 0, 0, new WidgetPointer(745,1)); + setWidgetPosition(28, 0, 0, 0, new WidgetPointer(745,2)); + setWidgetPosition(0, 0, 0, 0, new WidgetPointer(745,3)); + setWidgetPosition(0, 0, 0, 0, new WidgetPointer(745,4)); + setWidgetPosition(0, 0, 0, 0, new WidgetPointer(745,5)); + setWidgetPosition(0, 0, 0, 0, new WidgetPointer(745,6)); + setWidgetSize(25, 25, 0, 0, new WidgetPointer(745,1)); + setWidgetSize(25, 25, 0, 0, new WidgetPointer(745,2)); + setWidgetSize(25, 25, 0, 0, new WidgetPointer(745,3)); + setWidgetSize(25, 25, 0, 0, new WidgetPointer(745,4)); + setWidgetSize(25, 25, 0, 0, new WidgetPointer(745,5)); + setWidgetSize(25, 25, 0, 0, new WidgetPointer(745,6)); + setWidgetSprite(442, new WidgetPointer(745,1)); + setWidgetSprite(1073, new WidgetPointer(745,2)); + setWidgetSprite(1576, new WidgetPointer(745,3)); + setWidgetSprite(1578, new WidgetPointer(745,4)); + setWidgetSprite(1577, new WidgetPointer(745,6)); + } + script_5341(); + script_722(); + return; +} diff --git a/dumps/scripts/1365.cs2 b/dumps/scripts/1365.cs2 new file mode 100644 index 0000000..7b343a1 --- /dev/null +++ b/dumps/scripts/1365.cs2 @@ -0,0 +1,5 @@ +void script_1365(int arg0) { + setWidgetIsHidden(false, new WidgetPointer(arg0)); + setScriptCallOnGameloop(122, new WidgetPointer(arg0), "I", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1366.cs2 b/dumps/scripts/1366.cs2 new file mode 100644 index 0000000..e922f42 --- /dev/null +++ b/dumps/scripts/1366.cs2 @@ -0,0 +1,10 @@ +void script_1366() { + if (standart_config_380 == 25) { + setWidgetText(new WidgetPointer(57,0), "Time until next game starts: 0"); + } else if (standart_config_380 > 0) { + setWidgetText(new WidgetPointer(57,0), "Time until next game starts: " + intToStr(standart_config_380)); + } else { + setWidgetText(new WidgetPointer(57,0), "Waiting for players to join the other team."); + } + return; +} diff --git a/dumps/scripts/1367.cs2 b/dumps/scripts/1367.cs2 new file mode 100644 index 0000000..ac9b73e --- /dev/null +++ b/dumps/scripts/1367.cs2 @@ -0,0 +1,72 @@ +void script_1367() { + setWidgetText(new WidgetPointer(58,0), "Zamorak = " + intToStr(bitconfig_155)); + setWidgetText(new WidgetPointer(58,1), intToStr(bitconfig_145) + " = Saradomin"); + setWidgetText(new WidgetPointer(58,6), intToStr(standart_config_380) + " Min"); + if (((boolean)bitconfig_136)) { + setWidgetText(new WidgetPointer(58,9), "Health: " + intToStr(bitconfig_136) + "%"); + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(58,9)); + } else { + setWidgetText(new WidgetPointer(58,9), "Health " + intToStr(bitconfig_136) + "%"); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(58,9)); + } + if (((boolean)bitconfig_143)) { + setWidgetText(new WidgetPointer(58,2), "Safe"); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(58,2)); + } else if (((boolean)bitconfig_143)) { + setWidgetText(new WidgetPointer(58,2), "Taken"); + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(58,2)); + } else { + if (bitconfig_143 == 2) { + setWidgetText(new WidgetPointer(58,2), "Dropped"); + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(58,2)); + } + } + if (((boolean)bitconfig_153)) { + setWidgetText(new WidgetPointer(58,3), "Safe"); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(58,3)); + } else if (((boolean)bitconfig_153)) { + setWidgetText(new WidgetPointer(58,3), "Taken"); + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(58,3)); + } else { + if (bitconfig_153 == 2) { + setWidgetText(new WidgetPointer(58,3), "Dropped"); + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(58,3)); + } + } + if (((boolean)bitconfig_137)) { + setWidgetText(new WidgetPointer(58,10), "Unlocked"); + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(58,10)); + } else { + setWidgetText(new WidgetPointer(58,10), "Locked"); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(58,10)); + } + if (((boolean)bitconfig_138)) { + setWidgetText(new WidgetPointer(58,11), "Cleared"); + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(58,11)); + } else { + setWidgetText(new WidgetPointer(58,11), "Collapsed"); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(58,11)); + } + if (((boolean)bitconfig_139)) { + setWidgetText(new WidgetPointer(58,12), "Cleared"); + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(58,12)); + } else { + setWidgetText(new WidgetPointer(58,12), "Collapsed"); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(58,12)); + } + if (((boolean)bitconfig_140)) { + setWidgetText(new WidgetPointer(58,13), "Destroyed"); + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(58,13)); + } else { + setWidgetText(new WidgetPointer(58,13), "Operational"); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(58,13)); + } + setItemOnWidgetMethod2200(18748, -1, new WidgetPointer(58,4)); + setItemOnWidgetMethod2200(18749, -1, new WidgetPointer(58,5)); + setItemOnWidgetMethod2200(18750, -1, new WidgetPointer(58,14)); + setItemOnWidgetMethod2200(18751, -1, new WidgetPointer(58,15)); + setItemOnWidgetMethod2200(18752, -1, new WidgetPointer(58,16)); + setItemOnWidgetMethod2200(18753, -1, new WidgetPointer(58,17)); + setItemOnWidgetMethod2200(18754, -1, new WidgetPointer(58,18)); + return; +} diff --git a/dumps/scripts/1368.cs2 b/dumps/scripts/1368.cs2 new file mode 100644 index 0000000..16b2b4c --- /dev/null +++ b/dumps/scripts/1368.cs2 @@ -0,0 +1,72 @@ +void script_1368() { + setWidgetText(new WidgetPointer(59,0), "Zamorak = " + intToStr(bitconfig_155)); + setWidgetText(new WidgetPointer(59,1), intToStr(bitconfig_145) + " = Saradomin"); + setWidgetText(new WidgetPointer(59,6), intToStr(standart_config_380) + " min"); + if (((boolean)bitconfig_146)) { + setWidgetText(new WidgetPointer(59,9), "Health: " + intToStr(bitconfig_146) + "%"); + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(59,9)); + } else { + setWidgetText(new WidgetPointer(59,9), "Health " + intToStr(bitconfig_146) + "%"); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(59,9)); + } + if (((boolean)bitconfig_143)) { + setWidgetText(new WidgetPointer(59,2), "Safe"); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(59,2)); + } else if (((boolean)bitconfig_143)) { + setWidgetText(new WidgetPointer(59,2), "Taken"); + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(59,2)); + } else { + if (bitconfig_143 == 2) { + setWidgetText(new WidgetPointer(59,2), "Dropped"); + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(59,2)); + } + } + if (((boolean)bitconfig_153)) { + setWidgetText(new WidgetPointer(59,3), "Safe"); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(59,3)); + } else if (((boolean)bitconfig_153)) { + setWidgetText(new WidgetPointer(59,3), "Taken"); + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(59,3)); + } else { + if (bitconfig_153 == 2) { + setWidgetText(new WidgetPointer(59,3), "Dropped"); + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(59,3)); + } + } + if (((boolean)bitconfig_147)) { + setWidgetText(new WidgetPointer(59,10), "Unlocked"); + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(59,10)); + } else { + setWidgetText(new WidgetPointer(59,10), "Locked"); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(59,10)); + } + if (((boolean)bitconfig_148)) { + setWidgetText(new WidgetPointer(59,11), "Cleared"); + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(59,11)); + } else { + setWidgetText(new WidgetPointer(59,11), "Collapsed"); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(59,11)); + } + if (((boolean)bitconfig_149)) { + setWidgetText(new WidgetPointer(59,12), "Cleared"); + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(59,12)); + } else { + setWidgetText(new WidgetPointer(59,12), "Collapsed"); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(59,12)); + } + if (((boolean)bitconfig_150)) { + setWidgetText(new WidgetPointer(59,13), "Destroyed"); + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(59,13)); + } else { + setWidgetText(new WidgetPointer(59,13), "Operational"); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(59,13)); + } + setItemOnWidgetMethod2200(18748, -1, new WidgetPointer(59,4)); + setItemOnWidgetMethod2200(18749, -1, new WidgetPointer(59,5)); + setItemOnWidgetMethod2200(18750, -1, new WidgetPointer(59,14)); + setItemOnWidgetMethod2200(18751, -1, new WidgetPointer(59,15)); + setItemOnWidgetMethod2200(18752, -1, new WidgetPointer(59,16)); + setItemOnWidgetMethod2200(18753, -1, new WidgetPointer(59,17)); + setItemOnWidgetMethod2200(18754, -1, new WidgetPointer(59,18)); + return; +} diff --git a/dumps/scripts/1369.cs2 b/dumps/scripts/1369.cs2 new file mode 100644 index 0000000..ca9eb04 --- /dev/null +++ b/dumps/scripts/1369.cs2 @@ -0,0 +1,62 @@ +void script_1369(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9) { + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int stack_dump0; + opcStruct5224(2,0,0) structdump_1; + opcStruct5224(2,0,0) structdump_2; + opcStruct5224(2,0,0) structdump_3; + script_1088(arg0, 0); + ivar10 = -1; + if (globalint_622 != -1) { + ivar10 = getDungeonmap(globalint_622); + if (ivar10 == -1) { + ivar10 = 28; + } + } + ivar10 = script_2785(ivar10); + if (dungeonmapContains(globalint_622, ivar10)) { + cs2method5227(ivar10, globalint_622); + } else { + loadDungeonmap(ivar10); + } + globalint_172 = cs2method5218(ivar10); + script_1372(); + script_1374(0); + script_1376(0, arg5, arg9); + script_291(0, arg6, arg7, arg8, arg4, arg5); + script_1839(bitconfig_5367, arg1, arg2, arg3); + setScriptCallOnGlobalConfigChange(1369, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), new WidgetPointer(arg6), new WidgetPointer(arg7), new WidgetPointer(arg8), new WidgetPointer(arg9), 622, 1, "IIIIIIIIIIY", new WidgetPointer(arg0)); + setScriptCallOnConfigChange(1404, new WidgetPointer(arg1), new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg5), new WidgetPointer(arg0), bitconfig_6175, 463, 1159, 2, "IIIIIiY", new WidgetPointer(arg0)); + setScriptCallOnKeyPress(1382, -2147483640, false, new WidgetPointer(arg4), -1, "izIc", new WidgetPointer(arg4)); + globalstring_31 = ""; + ivar11 = 0; + ivar12 = 0; + ivar13 = globalint_622; + if (ivar13 != -1) { + stack_dump0 = ivar13; + structdump_1 = cs2method5224(stack_dump0); + ivar12 = structdump_1.intpart_1; + ivar11 = structdump_1.intpart_0; + if ((ivar11 < 0) || (ivar12 < 0)) { + ivar13 = addToCoordinate(0, extractX(ivar13), script_686(subtract(extractZ(ivar13), 1), 4), extractY(ivar13)); + stack_dump0 = ivar13; + structdump_2 = cs2method5224(stack_dump0); + ivar12 = structdump_2.intpart_1; + ivar11 = structdump_2.intpart_0; + if ((ivar11 < 0) || (ivar12 < 0)) { + ivar13 = addToCoordinate(0, extractX(ivar13), script_686(subtract(extractZ(ivar13), 1), 4), extractY(ivar13)); + stack_dump0 = ivar13; + structdump_3 = cs2method5224(stack_dump0); + ivar12 = structdump_3.intpart_1; + ivar11 = structdump_3.intpart_0; + if ((ivar11 < 0) || (ivar12 < 0)) { + return; + } + } + } + setScriptCallOnGameloop(2054, add(getClientCycle(), 4), new WidgetPointer(arg0), ivar13, "iIc", new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/137.cs2 b/dumps/scripts/137.cs2 new file mode 100644 index 0000000..edbbedf --- /dev/null +++ b/dumps/scripts/137.cs2 @@ -0,0 +1,5 @@ +void script_137(int arg0,int arg1) { + setScriptCallOnGameloop(250, new WidgetPointer(arg1), "I", new WidgetPointer(arg0)); + script_251(arg1); + return; +} diff --git a/dumps/scripts/1370.cs2 b/dumps/scripts/1370.cs2 new file mode 100644 index 0000000..0abb477 --- /dev/null +++ b/dumps/scripts/1370.cs2 @@ -0,0 +1,93 @@ +void script_1370(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + opcStruct5208(2,0,0) structdump_0; + int stack_dump1; + opcStruct5209(2,0,0) structdump_2; + if (cs2method5220()) { + return; + } + ivar4 = 1; + ivar5 = 0; + ivar6 = 0; + ivar7 = 0; + ivar8 = 0; + ivar9 = 0; + ivar10 = 0; + ivar11 = 0; + ivar12 = 0; + ivar13 = 0; + ivar14 = 0; + ivar15 = globalint_172; + if (arg2 > 0) { + switch (globalint_172) { + case 50: + globalint_172 = 37; + break; + case 75: + globalint_172 = 50; + break; + case 100: + globalint_172 = 75; + break; + case 200: + globalint_172 = 100; + break; + default: + globalint_172 = 37; + ivar4 = 0; + } + } else { + switch (globalint_172) { + case 37: + globalint_172 = 50; + break; + case 50: + globalint_172 = 75; + break; + case 75: + globalint_172 = 100; + break; + case 100: + globalint_172 = 200; + break; + default: + globalint_172 = 200; + ivar4 = 0; + } + if (((boolean)arg3) && (ivar15 < 200)) { + structdump_0 = cs2method5208(); + ivar6 = structdump_0.intpart_1; + ivar5 = structdump_0.intpart_0; + stack_dump1 = getWidgetActualWidth(new WidgetPointer(arg1)); + ivar10 = getWidgetActualHeight(new WidgetPointer(arg1)); + ivar9 = stack_dump1; + if ((ivar5 > 0) && (ivar6 > 0)) { + structdump_2 = cs2method5209(); + ivar8 = structdump_2.intpart_1; + ivar7 = structdump_2.intpart_0; + ivar11 = subtract(subtract(getLastMouseY(), script_3365(arg1)), divide(ivar9, 2)); + ivar12 = subtract(subtract(getLastMouseX(), script_3366(arg1)), divide(ivar10, 2)); + stack_dump1 = multiplyDivide(ivar5, ivar9, ivar11); + ivar14 = multiplyDivide(ivar6, ivar10, ivar12); + ivar13 = stack_dump1; + ivar7 = add(ivar7, ivar13); + ivar8 = subtract(ivar8, ivar14); + setScriptCallOnGameloop(2054, add(getClientCycle(), 1), new WidgetPointer(arg0), addToCoordinate(0, ivar7, 0, ivar8), "iIc", new WidgetPointer(arg0)); + } + } + } + script_1372(); + script_305(ivar4); + return; +} diff --git a/dumps/scripts/1371.cs2 b/dumps/scripts/1371.cs2 new file mode 100644 index 0000000..17653c8 --- /dev/null +++ b/dumps/scripts/1371.cs2 @@ -0,0 +1,53 @@ +void script_1371() { + if (((boolean)bitconfig_7520)) { + setWidgetRGB(new Color(88, 80, 66), new WidgetPointer(1017,156)); + } else { + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(1017,156)); + } + if (((boolean)bitconfig_7521)) { + setWidgetRGB(new Color(88, 80, 66), new WidgetPointer(1017,157)); + } else { + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(1017,157)); + } + if (((boolean)bitconfig_7526)) { + setWidgetRGB(new Color(88, 80, 66), new WidgetPointer(1017,158)); + } else { + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(1017,158)); + } + if (((boolean)bitconfig_7527)) { + setWidgetRGB(new Color(88, 80, 66), new WidgetPointer(1017,159)); + } else { + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(1017,159)); + } + if (((boolean)bitconfig_7530)) { + setWidgetRGB(new Color(88, 80, 66), new WidgetPointer(1017,160)); + } else { + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(1017,160)); + } + if (((boolean)bitconfig_7531)) { + setWidgetRGB(new Color(88, 80, 66), new WidgetPointer(1017,161)); + } else { + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(1017,161)); + } + if (((boolean)bitconfig_7532)) { + setWidgetRGB(new Color(88, 80, 66), new WidgetPointer(1017,162)); + } else { + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(1017,162)); + } + if (((boolean)bitconfig_7533)) { + setWidgetRGB(new Color(88, 80, 66), new WidgetPointer(1017,163)); + } else { + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(1017,163)); + } + if (((boolean)bitconfig_7534)) { + setWidgetRGB(new Color(88, 80, 66), new WidgetPointer(1017,164)); + } else { + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(1017,164)); + } + if (((boolean)bitconfig_7535)) { + setWidgetRGB(new Color(88, 80, 66), new WidgetPointer(1017,165)); + } else { + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(1017,165)); + } + return; +} diff --git a/dumps/scripts/1372.cs2 b/dumps/scripts/1372.cs2 new file mode 100644 index 0000000..bc8c6cd --- /dev/null +++ b/dumps/scripts/1372.cs2 @@ -0,0 +1,5 @@ +void script_1372() { + setWorldmapZoom(globalint_172); + setWidgetText(new WidgetPointer(755,14), intToStr(globalint_172) + "%"); + return; +} diff --git a/dumps/scripts/1373.cs2 b/dumps/scripts/1373.cs2 new file mode 100644 index 0000000..1dc9f71 --- /dev/null +++ b/dumps/scripts/1373.cs2 @@ -0,0 +1,8 @@ +void script_1373() { + if (isWidgetHidden(new WidgetPointer(755,46))) { + script_1374(1); + } else { + script_1374(0); + } + return; +} diff --git a/dumps/scripts/1374.cs2 b/dumps/scripts/1374.cs2 new file mode 100644 index 0000000..7529b59 --- /dev/null +++ b/dumps/scripts/1374.cs2 @@ -0,0 +1,11 @@ +void script_1374(int arg0) { + if (((boolean)arg0)) { + setWidgetIsHidden(false, new WidgetPointer(755,46)); + setWidgetContextMenuOption(1, new WidgetPointer(755,6), "Hide overview"); + } else { + setWidgetIsHidden(true, new WidgetPointer(755,46)); + setWidgetContextMenuOption(1, new WidgetPointer(755,6), "Show overview"); + } + setScriptCallOnClickContextMenu(1373, "", new WidgetPointer(755,6)); + return; +} diff --git a/dumps/scripts/1375.cs2 b/dumps/scripts/1375.cs2 new file mode 100644 index 0000000..e115158 --- /dev/null +++ b/dumps/scripts/1375.cs2 @@ -0,0 +1,8 @@ +void script_1375(int arg0,int arg1) { + if (isWidgetHidden(new WidgetPointer(755,47))) { + script_1376(1, arg0, arg1); + } else { + script_1376(0, arg0, arg1); + } + return; +} diff --git a/dumps/scripts/1376.cs2 b/dumps/scripts/1376.cs2 new file mode 100644 index 0000000..4283ae7 --- /dev/null +++ b/dumps/scripts/1376.cs2 @@ -0,0 +1,14 @@ +void script_1376(int arg0,int arg1,int arg2) { + if (((boolean)arg0)) { + setWidgetIsHidden(false, new WidgetPointer(755,47)); + setWidgetContextMenuOption(1, new WidgetPointer(755,5), "Hide key"); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(755,47)), 0, 1, 1, new WidgetPointer(arg1)); + } else { + setWidgetIsHidden(true, new WidgetPointer(755,47)); + setWidgetContextMenuOption(1, new WidgetPointer(755,5), "Show key"); + setWidgetSize(0, 0, 1, 1, new WidgetPointer(arg1)); + } + script_2046(arg1); + setScriptCallOnClickContextMenu(1375, new WidgetPointer(arg1), new WidgetPointer(arg2), "II", new WidgetPointer(755,5)); + return; +} diff --git a/dumps/scripts/1377.cs2 b/dumps/scripts/1377.cs2 new file mode 100644 index 0000000..7c39409 --- /dev/null +++ b/dumps/scripts/1377.cs2 @@ -0,0 +1,33 @@ +void script_1377(int arg0,int arg1) { + int ivar2; + ivar2 = -1; + if (bitconfig_7516 == arg1) { + ivar2 = script_486(bitconfig_7520); + } else if (bitconfig_7517 == arg1) { + ivar2 = script_486(bitconfig_7521); + } else if (bitconfig_7518 == arg1) { + ivar2 = script_486(bitconfig_7526); + } else if (bitconfig_7519 == arg1) { + ivar2 = script_486(bitconfig_7527); + } else if (bitconfig_7522 == arg1) { + ivar2 = script_486(bitconfig_7530); + } else if (bitconfig_7523 == arg1) { + ivar2 = script_486(bitconfig_7531); + } else if (bitconfig_7524 == arg1) { + ivar2 = script_486(bitconfig_7532); + } else if (bitconfig_7525 == arg1) { + ivar2 = script_486(bitconfig_7533); + } else if (bitconfig_7528 == arg1) { + ivar2 = script_486(bitconfig_7534); + } else { + if (bitconfig_7529 == arg1) { + ivar2 = script_486(bitconfig_7535); + } + } + if (ivar2 != -1) { + setWidgetText(new WidgetPointer(arg0), getNpcNodemapData(ivar2, 1140)); + } else { + setWidgetText(new WidgetPointer(arg0), ""); + } + return; +} diff --git a/dumps/scripts/1378.cs2 b/dumps/scripts/1378.cs2 new file mode 100644 index 0000000..14920f9 --- /dev/null +++ b/dumps/scripts/1378.cs2 @@ -0,0 +1,138 @@ +void script_1378(int arg0,int arg1) { + string svar0; + string svar1; + svar0 = getWidgetText(new WidgetPointer(arg0)); + svar1 = ""; + if (strLength(svar0) > 0) { + flow_1: + SWITCH (arg1) { + case 66650279: + GOTO flow_2 + case 66650278: + GOTO flow_2 + case 66650281: + GOTO flow_2 + case 66650280: + GOTO flow_2 + case 66650283: + GOTO flow_2 + case 66650282: + GOTO flow_2 + case 66650285: + GOTO flow_2 + case 66650284: + GOTO flow_2 + case 66650287: + GOTO flow_2 + case 66650286: + GOTO flow_2 + case 66650288: + GOTO flow_2 + case 66650289: + GOTO flow_2 + case 66650290: + GOTO flow_2 + case 66650291: + GOTO flow_2 + case 66650292: + GOTO flow_2 + case 66650293: + GOTO flow_2 + case 66650294: + GOTO flow_2 + case 66650295: + GOTO flow_2 + case 66650296: + GOTO flow_2 + case 66650297: + GOTO flow_2 + case 66650298: + GOTO flow_2 + case 66650299: + GOTO flow_2 + case 66650300: + GOTO flow_2 + case 66650301: + GOTO flow_2 + case 66650302: + GOTO flow_2 + case 66650303: + GOTO flow_2 + case 66650337: + GOTO flow_2 + case 66650336: + GOTO flow_2 + case 66650311: + GOTO flow_2 + case 66650310: + GOTO flow_2 + case 66650309: + GOTO flow_2 + case 66650308: + GOTO flow_2 + case 66650307: + GOTO flow_2 + case 66650306: + GOTO flow_2 + case 66650305: + GOTO flow_2 + case 66650304: + GOTO flow_2 + case 66650319: + GOTO flow_2 + case 66650318: + GOTO flow_2 + case 66650317: + GOTO flow_2 + case 66650316: + GOTO flow_2 + case 66650315: + GOTO flow_2 + case 66650314: + GOTO flow_2 + case 66650313: + GOTO flow_2 + case 66650312: + GOTO flow_2 + case 66650326: + GOTO flow_2 + case 66650327: + GOTO flow_2 + case 66650324: + GOTO flow_2 + case 66650325: + GOTO flow_2 + case 66650322: + GOTO flow_2 + case 66650323: + GOTO flow_2 + case 66650320: + GOTO flow_2 + case 66650321: + GOTO flow_2 + case 66650334: + GOTO flow_2 + case 66650335: + GOTO flow_2 + case 66650332: + GOTO flow_2 + case 66650333: + GOTO flow_2 + case 66650330: + GOTO flow_2 + case 66650331: + GOTO flow_2 + case 66650328: + GOTO flow_2 + case 66650329: + GOTO flow_2 + } + return; + flow_2: + svar1 = getWidgetText(new WidgetPointer(arg1)); + setWidgetText(new WidgetPointer(arg1), svar0); + setWidgetText(new WidgetPointer(arg0), svar1); + globalint_1387 = 1; + } + return; +} diff --git a/dumps/scripts/1379.cs2 b/dumps/scripts/1379.cs2 new file mode 100644 index 0000000..062108f --- /dev/null +++ b/dumps/scripts/1379.cs2 @@ -0,0 +1,34 @@ +void script_1379() { + switch (bitconfig_5389) { + case 1: + setWidgetAnimation(10439, new WidgetPointer(796,10)); + break; + case 2: + setWidgetIsHidden(true, new WidgetPointer(796,11)); + setWidgetIsHidden(false, new WidgetPointer(796,7)); + break; + case 3: + setWidgetAnimation(10439, new WidgetPointer(796,6)); + break; + case 4: + setWidgetIsHidden(true, new WidgetPointer(796,7)); + setWidgetIsHidden(false, new WidgetPointer(796,9)); + break; + case 5: + setWidgetAnimation(10443, new WidgetPointer(796,8)); + break; + case 6: + setWidgetIsHidden(true, new WidgetPointer(796,9)); + setWidgetIsHidden(false, new WidgetPointer(796,5)); + break; + case 7: + setWidgetAnimation(10437, new WidgetPointer(796,4)); + break; + case 8: + setWidgetIsHidden(true, new WidgetPointer(796,5)); + setWidgetIsHidden(true, new WidgetPointer(796,3)); + setWidgetIsHidden(false, new WidgetPointer(796,30)); + setWidgetIsHidden(false, new WidgetPointer(796,1)); + } + return; +} diff --git a/dumps/scripts/138.cs2 b/dumps/scripts/138.cs2 new file mode 100644 index 0000000..504bcfb --- /dev/null +++ b/dumps/scripts/138.cs2 @@ -0,0 +1,21 @@ +void script_138() { + switch (globalint_5) { + case 7: + script_1548(7); + break; + case 8: + script_1548(8); + break; + case 9: + script_1548(9); + break; + case 13: + script_1548(13); + break; + default: + if (getDisplayMode() >= 2) { + script_1364(); + } + } + return; +} diff --git a/dumps/scripts/1380.cs2 b/dumps/scripts/1380.cs2 new file mode 100644 index 0000000..2e406b1 --- /dev/null +++ b/dumps/scripts/1380.cs2 @@ -0,0 +1,4 @@ +void script_1380(int arg0) { + setScriptCallOnGameloop(709, new WidgetPointer(arg0), "I", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1381.cs2 b/dumps/scripts/1381.cs2 new file mode 100644 index 0000000..295f923 --- /dev/null +++ b/dumps/scripts/1381.cs2 @@ -0,0 +1,57 @@ +void script_1381() { + int ivar0; + int ivar1; + ivar0 = 0; + ivar1 = 0; + if (((boolean)bitconfig_7520)) { + ivar1 = script_1416(66650268, ivar1); + } else { + ivar0 = script_1403(66650268, ivar0); + } + if (((boolean)bitconfig_7521)) { + ivar1 = script_1416(66650269, ivar1); + } else { + ivar0 = script_1403(66650269, ivar0); + } + if (((boolean)bitconfig_7526)) { + ivar1 = script_1416(66650270, ivar1); + } else { + ivar0 = script_1403(66650270, ivar0); + } + if (((boolean)bitconfig_7527)) { + ivar1 = script_1416(66650271, ivar1); + } else { + ivar0 = script_1403(66650271, ivar0); + } + if (((boolean)bitconfig_7530)) { + ivar1 = script_1416(66650272, ivar1); + } else { + ivar0 = script_1403(66650272, ivar0); + } + if (((boolean)bitconfig_7531)) { + ivar1 = script_1416(66650273, ivar1); + } else { + ivar0 = script_1403(66650273, ivar0); + } + if (((boolean)bitconfig_7532)) { + ivar1 = script_1416(66650274, ivar1); + } else { + ivar0 = script_1403(66650274, ivar0); + } + if (((boolean)bitconfig_7533)) { + ivar1 = script_1416(66650275, ivar1); + } else { + ivar0 = script_1403(66650275, ivar0); + } + if (((boolean)bitconfig_7534)) { + ivar1 = script_1416(66650276, ivar1); + } else { + ivar0 = script_1403(66650276, ivar0); + } + if (((boolean)bitconfig_7535)) { + ivar1 = script_1416(66650277, ivar1); + } else { + ivar0 = script_1403(66650277, ivar0); + } + return; +} diff --git a/dumps/scripts/1382.cs2 b/dumps/scripts/1382.cs2 new file mode 100644 index 0000000..cec7bf6 --- /dev/null +++ b/dumps/scripts/1382.cs2 @@ -0,0 +1,101 @@ +void script_1382(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + string svar0; + string svar1; + opcStruct5212(2,0,0) structdump_0; + string stack_dump1; + int stack_dump2; + opcStruct5213(2,0,0) structdump_3; + switch (arg0) { + case 84: + if (arg3 != -1) { + cs2method5221(arg3); + } + globalstring_31 = ""; + script_308(arg2); + return; + case 96: + script_1603(-1, 0); + return; + case 97: + script_1603(1, 0); + return; + case 98: + script_1603(0, 1); + return; + case 99: + script_1603(0, -1); + return; + } + svar0 = strRemoveEntities(script_74(4, arg0, arg1, globalstring_31)); + if (strIndexof(0, svar0, " ") != -1) { + return; + } + if (((boolean)stringMethod4107(svar0, " "))) { + return; + } + if (getLineCount(getWidgetActualWidth(new WidgetPointer(arg2)), 494, svar0) > 1) { + return; + } + globalstring_31 = lower(svar0); + ivar4 = strLength(globalstring_31); + if (ivar4 <= 0) { + script_308(arg2); + return; + } + ivar5 = -1; + ivar6 = -1; + ivar7 = -1; + ivar8 = 0; + svar1 = ""; + ivar9 = -1; + ivar10 = 2147483647; + ivar11 = 2147483647; + structdump_0 = cs2method5212(); + ivar6 = structdump_0.intpart_1; + ivar5 = structdump_0.intpart_0; + while (ivar5 != -1) { + svar0 = strRemoveEntities(script_2332(getWorldmapLabelName(ivar5), "
", " ")); + ivar7 = strIndexof(0, lower(svar0), globalstring_31); + if ((ivar7 != -1) && (ivar7 <= ivar10)) { + ivar8 = strLength(svar0); + if (ivar8 < ivar11) { + stack_dump1 = svar0; + ivar9 = ivar6; + svar1 = stack_dump1; + stack_dump2 = ivar7; + ivar11 = ivar8; + ivar10 = stack_dump2; + } + } + structdump_3 = cs2method5213(); + ivar6 = structdump_3.intpart_1; + ivar5 = structdump_3.intpart_0; + } + if (ivar9 == -1) { + setScriptCallOnKeyPress(1382, -2147483640, false, new WidgetPointer(arg2), -1, "izIc", new WidgetPointer(arg2)); + if (getMaxLineWidth(getWidgetActualWidth(new WidgetPointer(arg2)), 494, globalstring_31) > getWidgetActualWidth(new WidgetPointer(arg2))) { + setWidgetTextAlignment(2, 1, 0, new WidgetPointer(arg2)); + } else { + setWidgetTextAlignment(0, 1, 0, new WidgetPointer(arg2)); + } + setWidgetText(new WidgetPointer(arg2), "" + globalstring_31 + ""); + return; + } + svar0 = ""; + if (ivar10 > 0) { + svar0 = substr(0, ivar10, svar1); + } + svar0 = concat(svar0, "" + substr(ivar10, add(ivar10, ivar4), svar1) + ""); + svar0 = concat(svar0, substr(add(ivar10, ivar4), strLength(svar1), svar1)); + setWidgetText(new WidgetPointer(arg2), svar0); + setScriptCallOnKeyPress(1382, -2147483640, false, new WidgetPointer(arg2), ivar9, "izIc", new WidgetPointer(arg2)); + return; +} diff --git a/dumps/scripts/1383.cs2 b/dumps/scripts/1383.cs2 new file mode 100644 index 0000000..1e51170 --- /dev/null +++ b/dumps/scripts/1383.cs2 @@ -0,0 +1,27 @@ +void script_1383() { + if (((boolean)bitconfig_5390)) { + setWidgetText(new WidgetPointer(794,5), "" + "Varrock Census - year 160" + "
" + "" + "Citizen's name" + "
" + "Gryff Aldock" + "
" + "Raminme Altrodor" + "
" + "Layte Aubury" + "
" + "Ingald Belger" + "
" + "Asyff Bymajique" + "
" + "Baraek Brigson" + "
" + "Brugsen Bursen" + "
" + "Jeremy Clerksin" + "
" + "Daerig Clod" + "
" + "Phillipa DeMarne" + "
" + "Trista Donaldson" + "
" + "Straven Enroy" + "
" + "Gertrude Fairweather" + "
" + "Shilop Fairweather" + "
" + "Walter Fairweather" + "
" + "Wilough Fairweather"); + setWidgetText(new WidgetPointer(794,4), "
" + "
" + "" + "Profession" + "
" + "Town crier" + "
" + "Cook" + "
" + "Rune seller" + "
" + "Apothecary" + "
" + "Fancy dress store owner" + "
" + "Fur seller" + "
" + "Economist" + "
" + "Cart expert" + "
" + "Unemployed" + "
" + "Minor noble" + "
" + "Banker" + "
" + "Legitimate businessman" + "
" + "Housewife" + "
" + "Baby" + "
" + "Travelling merchant" + "
" + "Baby"); + setWidgetIsHidden(true, new WidgetPointer(794,3)); + setWidgetIsHidden(false, new WidgetPointer(794,2)); + } + if (((boolean)bitconfig_5390)) { + setWidgetText(new WidgetPointer(794,5), "" + "Varrock Census - year 160" + "
" + "" + "Citizen's name" + "
" + "Dimintheis Fitzharmon" + "
" + "Eustace Forthwright" + "
" + "Everard Grafham" + "
" + "Matthew Grey" + "
" + "Grimesquit Grime" + "
" + "Phingspet Grime" + "
" + "Benny Gutenberg" + "
" + "Haig Halen" + "
" + "Ritchard Haring" + "
" + "Randulf Harlow" + "
" + "Tobias Hills" + "
" + "Louisiana Jones" + "
" + "Lawrence Lambare" + "
" + "Wimock Landsdown" + "
" + "Stuart Lea" + "
" + "Draul Leptoc"); + setWidgetText(new WidgetPointer(794,4), "
" + "
" + "" + "Profession" + "
" + "Former Noble" + "
" + "Guard" + "
" + "Natural Historian" + "
" + "Sailor" + "
" + "Profession Withheld" + "
" + "Profession Withheld" + "
" + "Journalist" + "
" + "Curator" + "
" + "Dietician" + "
" + "Vampyre Hunter" + "
" + "Guard" + "
" + "Student" + "
" + "Priest" + "
" + "Teacher" + "
" + "Playwright" + "
" + "Lord"); + setWidgetIsHidden(false, new WidgetPointer(794,3)); + setWidgetIsHidden(false, new WidgetPointer(794,2)); + } + if (bitconfig_5390 == 2) { + setWidgetText(new WidgetPointer(794,5), "" + "Varrock Census - year 160" + "
" + "" + "Citizen's name" + "
" + "Phearthee Levalsyx" + "
" + "Charles Lyeman" + "
" + "Surok Magis" + "
" + "Gaffit Malore" + "
" + "Mabel Malore" + "
" + "Alfi Marino" + "
" + "Aris Maye" + "
" + "Iffie Nitter" + "
" + "Thessalia Nitter" + "
" + "Elsie Parks" + "
" + "Fred Parks" + "
" + "Ethel Prim" + "
" + "Hartwin Prim" + "
" + "Enhtor Prysin" + "
" + "Idonea Ramlock" + "
" + "Trevick Ramlock"); + setWidgetText(new WidgetPointer(794,4), "
" + "
" + "" + "Profession" + "
" + "Mugger" + "
" + "Unemployed" + "
" + "Mage" + "
" + "Librarian" + "
" + "Information Clerk" + "
" + "Chef" + "
" + "Gypsy" + "
" + "Retired" + "
" + "Clothes Shop Owner" + "
" + "Retired" + "
" + "Retired" + "
" + "Servant" + "
" + "Student" + "
" + "Knight" + "
" + "Teacher" + "
" + "Banker"); + setWidgetIsHidden(false, new WidgetPointer(794,2)); + setWidgetIsHidden(false, new WidgetPointer(794,3)); + } + if (bitconfig_5390 == 3) { + setWidgetText(new WidgetPointer(794,5), "" + "Varrock Census - year 160" + "
" + "" + "Citizen's name" + "
" + "Aeonisig Raispher" + "
" + "Katrine Raven" + "
" + "Horvik Ravitz" + "
" + "Roald Remanis" + "
" + "Milo Rovin" + "
" + "Martina Scorsby" + "
" + "Stephan Scorsby" + "
" + "Sani Semiv" + "
" + "Herbert Spiccanspan" + "
" + "Brana Talvoy" + "
" + "Launa Talvoy" + "
" + "Reldo Trimmly" + "
" + "Jack Tylner" + "
" + "Romily Weeklax" + "
" + "Treznor Withings"); + setWidgetText(new WidgetPointer(794,4), "
" + "
" + "" + "Profession" + "
" + "Royal Advisor" + "
" + "Wallet Relocator" + "
" + "Apprentice Blacksmith" + "
" + "Our Glorious King" + "
" + "Captain of the guard" + "
" + "Washerwoman" + "
" + "Guard" + "
" + "Master Smith" + "
" + "Street Cleaner" + "
" + "Farmer" + "
" + "Farmer" + "
" + "Assistant Librarian" + "
" + "Rat Exterminator" + "
" + "Pie Salesman" + "
" + "Kitchen Boy"); + setWidgetIsHidden(true, new WidgetPointer(794,2)); + setWidgetIsHidden(false, new WidgetPointer(794,3)); + } + return; +} diff --git a/dumps/scripts/1384.cs2 b/dumps/scripts/1384.cs2 new file mode 100644 index 0000000..705ef70 --- /dev/null +++ b/dumps/scripts/1384.cs2 @@ -0,0 +1,754 @@ +void script_1384(int arg0,int arg1) { + switch (arg0) { + case 0: + globalint_0 = arg1; + break; + case 1: + globalint_274 = arg1; + break; + case 2: + globalint_275 = arg1; + break; + case 3: + globalint_276 = arg1; + break; + case 4: + globalint_277 = arg1; + break; + case 5: + globalint_278 = arg1; + break; + case 6: + globalint_279 = arg1; + break; + case 7: + globalint_280 = arg1; + break; + case 8: + globalint_281 = arg1; + break; + case 9: + globalint_282 = arg1; + break; + case 10: + globalint_283 = arg1; + break; + case 11: + globalint_284 = arg1; + break; + case 12: + globalint_285 = arg1; + break; + case 13: + globalint_286 = arg1; + break; + case 14: + globalint_287 = arg1; + break; + case 15: + globalint_288 = arg1; + break; + case 16: + globalint_289 = arg1; + break; + case 17: + globalint_290 = arg1; + break; + case 18: + globalint_291 = arg1; + break; + case 19: + globalint_292 = arg1; + break; + case 20: + globalint_293 = arg1; + break; + case 21: + globalint_294 = arg1; + break; + case 22: + globalint_295 = arg1; + break; + case 23: + globalint_296 = arg1; + break; + case 24: + globalint_297 = arg1; + break; + case 25: + globalint_298 = arg1; + break; + case 26: + globalint_299 = arg1; + break; + case 27: + globalint_300 = arg1; + break; + case 28: + globalint_301 = arg1; + break; + case 29: + globalint_302 = arg1; + break; + case 30: + globalint_303 = arg1; + break; + case 31: + globalint_304 = arg1; + break; + case 32: + globalint_305 = arg1; + break; + case 33: + globalint_306 = arg1; + break; + case 34: + globalint_307 = arg1; + break; + case 35: + globalint_308 = arg1; + break; + case 36: + globalint_309 = arg1; + break; + case 37: + globalint_310 = arg1; + break; + case 38: + globalint_311 = arg1; + break; + case 39: + globalint_312 = arg1; + break; + case 40: + globalint_313 = arg1; + break; + case 41: + globalint_314 = arg1; + break; + case 42: + globalint_315 = arg1; + break; + case 43: + globalint_316 = arg1; + break; + case 44: + globalint_317 = arg1; + break; + case 45: + globalint_318 = arg1; + break; + case 46: + globalint_319 = arg1; + break; + case 47: + globalint_320 = arg1; + break; + case 48: + globalint_321 = arg1; + break; + case 49: + globalint_322 = arg1; + break; + case 50: + globalint_323 = arg1; + break; + case 51: + globalint_324 = arg1; + break; + case 52: + globalint_325 = arg1; + break; + case 53: + globalint_326 = arg1; + break; + case 54: + globalint_327 = arg1; + break; + case 55: + globalint_328 = arg1; + break; + case 56: + globalint_329 = arg1; + break; + case 57: + globalint_330 = arg1; + break; + case 58: + globalint_331 = arg1; + break; + case 59: + globalint_332 = arg1; + break; + case 60: + globalint_333 = arg1; + break; + case 61: + globalint_334 = arg1; + break; + case 62: + globalint_335 = arg1; + break; + case 63: + globalint_336 = arg1; + break; + case 64: + globalint_337 = arg1; + break; + case 65: + globalint_338 = arg1; + break; + case 66: + globalint_339 = arg1; + break; + case 67: + globalint_340 = arg1; + break; + case 68: + globalint_341 = arg1; + break; + case 69: + globalint_342 = arg1; + break; + case 70: + globalint_343 = arg1; + break; + case 71: + globalint_344 = arg1; + break; + case 72: + globalint_345 = arg1; + break; + case 73: + globalint_346 = arg1; + break; + case 74: + globalint_347 = arg1; + break; + case 75: + globalint_348 = arg1; + break; + case 76: + globalint_349 = arg1; + break; + case 77: + globalint_350 = arg1; + break; + case 78: + globalint_351 = arg1; + break; + case 79: + globalint_352 = arg1; + break; + case 80: + globalint_353 = arg1; + break; + case 81: + globalint_354 = arg1; + break; + case 82: + globalint_355 = arg1; + break; + case 83: + globalint_356 = arg1; + break; + case 84: + globalint_357 = arg1; + break; + case 85: + globalint_358 = arg1; + break; + case 86: + globalint_359 = arg1; + break; + case 87: + globalint_360 = arg1; + break; + case 88: + globalint_361 = arg1; + break; + case 89: + globalint_362 = arg1; + break; + case 90: + globalint_363 = arg1; + break; + case 91: + globalint_364 = arg1; + break; + case 92: + globalint_365 = arg1; + break; + case 93: + globalint_366 = arg1; + break; + case 94: + globalint_367 = arg1; + break; + case 95: + globalint_368 = arg1; + break; + case 96: + globalint_369 = arg1; + break; + case 97: + globalint_370 = arg1; + break; + case 98: + globalint_371 = arg1; + break; + case 99: + globalint_372 = arg1; + break; + case 100: + globalint_373 = arg1; + break; + case 101: + globalint_374 = arg1; + break; + case 102: + globalint_375 = arg1; + break; + case 103: + globalint_376 = arg1; + break; + case 104: + globalint_377 = arg1; + break; + case 105: + globalint_378 = arg1; + break; + case 106: + globalint_379 = arg1; + break; + case 107: + globalint_380 = arg1; + break; + case 108: + globalint_381 = arg1; + break; + case 109: + globalint_382 = arg1; + break; + case 110: + globalint_383 = arg1; + break; + case 111: + globalint_384 = arg1; + break; + case 112: + globalint_385 = arg1; + break; + case 113: + globalint_386 = arg1; + break; + case 114: + globalint_387 = arg1; + break; + case 115: + globalint_388 = arg1; + break; + case 116: + globalint_389 = arg1; + break; + case 117: + globalint_390 = arg1; + break; + case 118: + globalint_391 = arg1; + break; + case 119: + globalint_392 = arg1; + break; + case 120: + globalint_393 = arg1; + break; + case 121: + globalint_394 = arg1; + break; + case 122: + globalint_395 = arg1; + break; + case 123: + globalint_396 = arg1; + break; + case 124: + globalint_397 = arg1; + break; + case 125: + globalint_398 = arg1; + break; + case 126: + globalint_399 = arg1; + break; + case 127: + globalint_400 = arg1; + break; + case 128: + globalint_401 = arg1; + break; + case 129: + globalint_402 = arg1; + break; + case 130: + globalint_403 = arg1; + break; + case 131: + globalint_404 = arg1; + break; + case 132: + globalint_405 = arg1; + break; + case 133: + globalint_406 = arg1; + break; + case 134: + globalint_407 = arg1; + break; + case 135: + globalint_408 = arg1; + break; + case 136: + globalint_409 = arg1; + break; + case 137: + globalint_410 = arg1; + break; + case 138: + globalint_411 = arg1; + break; + case 139: + globalint_412 = arg1; + break; + case 140: + globalint_413 = arg1; + break; + case 141: + globalint_414 = arg1; + break; + case 142: + globalint_415 = arg1; + break; + case 143: + globalint_416 = arg1; + break; + case 144: + globalint_417 = arg1; + break; + case 145: + globalint_418 = arg1; + break; + case 146: + globalint_419 = arg1; + break; + case 147: + globalint_420 = arg1; + break; + case 148: + globalint_421 = arg1; + break; + case 149: + globalint_422 = arg1; + break; + case 150: + globalint_423 = arg1; + break; + case 151: + globalint_424 = arg1; + break; + case 152: + globalint_425 = arg1; + break; + case 153: + globalint_426 = arg1; + break; + case 154: + globalint_427 = arg1; + break; + case 155: + globalint_428 = arg1; + break; + case 156: + globalint_429 = arg1; + break; + case 157: + globalint_430 = arg1; + break; + case 158: + globalint_431 = arg1; + break; + case 159: + globalint_432 = arg1; + break; + case 160: + globalint_433 = arg1; + break; + case 161: + globalint_434 = arg1; + break; + case 162: + globalint_435 = arg1; + break; + case 163: + globalint_436 = arg1; + break; + case 164: + globalint_437 = arg1; + break; + case 165: + globalint_438 = arg1; + break; + case 166: + globalint_439 = arg1; + break; + case 167: + globalint_440 = arg1; + break; + case 168: + globalint_441 = arg1; + break; + case 169: + globalint_442 = arg1; + break; + case 170: + globalint_443 = arg1; + break; + case 171: + globalint_444 = arg1; + break; + case 172: + globalint_445 = arg1; + break; + case 173: + globalint_446 = arg1; + break; + case 174: + globalint_447 = arg1; + break; + case 175: + globalint_448 = arg1; + break; + case 176: + globalint_449 = arg1; + break; + case 177: + globalint_450 = arg1; + break; + case 178: + globalint_451 = arg1; + break; + case 179: + globalint_452 = arg1; + break; + case 180: + globalint_453 = arg1; + break; + case 181: + globalint_454 = arg1; + break; + case 182: + globalint_455 = arg1; + break; + case 183: + globalint_456 = arg1; + break; + case 184: + globalint_457 = arg1; + break; + case 185: + globalint_458 = arg1; + break; + case 186: + globalint_459 = arg1; + break; + case 187: + globalint_460 = arg1; + break; + case 188: + globalint_461 = arg1; + break; + case 189: + globalint_462 = arg1; + break; + case 190: + globalint_463 = arg1; + break; + case 191: + globalint_464 = arg1; + break; + case 192: + globalint_465 = arg1; + break; + case 193: + globalint_466 = arg1; + break; + case 194: + globalint_467 = arg1; + break; + case 195: + globalint_468 = arg1; + break; + case 196: + globalint_469 = arg1; + break; + case 197: + globalint_470 = arg1; + break; + case 198: + globalint_471 = arg1; + break; + case 199: + globalint_472 = arg1; + break; + case 200: + globalint_473 = arg1; + break; + case 201: + globalint_474 = arg1; + break; + case 202: + globalint_475 = arg1; + break; + case 203: + globalint_476 = arg1; + break; + case 204: + globalint_477 = arg1; + break; + case 205: + globalint_478 = arg1; + break; + case 206: + globalint_479 = arg1; + break; + case 207: + globalint_480 = arg1; + break; + case 208: + globalint_481 = arg1; + break; + case 209: + globalint_482 = arg1; + break; + case 210: + globalint_483 = arg1; + break; + case 211: + globalint_484 = arg1; + break; + case 212: + globalint_485 = arg1; + break; + case 213: + globalint_486 = arg1; + break; + case 214: + globalint_487 = arg1; + break; + case 215: + globalint_488 = arg1; + break; + case 216: + globalint_489 = arg1; + break; + case 217: + globalint_490 = arg1; + break; + case 218: + globalint_491 = arg1; + break; + case 219: + globalint_492 = arg1; + break; + case 220: + globalint_493 = arg1; + break; + case 221: + globalint_494 = arg1; + break; + case 222: + globalint_495 = arg1; + break; + case 223: + globalint_496 = arg1; + break; + case 224: + globalint_497 = arg1; + break; + case 225: + globalint_498 = arg1; + break; + case 226: + globalint_499 = arg1; + break; + case 227: + globalint_500 = arg1; + break; + case 228: + globalint_501 = arg1; + break; + case 229: + globalint_502 = arg1; + break; + case 230: + globalint_503 = arg1; + break; + case 231: + globalint_504 = arg1; + break; + case 232: + globalint_505 = arg1; + break; + case 233: + globalint_506 = arg1; + break; + case 234: + globalint_507 = arg1; + break; + case 235: + globalint_508 = arg1; + break; + case 236: + globalint_509 = arg1; + break; + case 237: + globalint_510 = arg1; + break; + case 238: + globalint_511 = arg1; + break; + case 239: + globalint_512 = arg1; + break; + case 240: + globalint_513 = arg1; + break; + case 241: + globalint_514 = arg1; + break; + case 242: + globalint_515 = arg1; + break; + case 243: + globalint_516 = arg1; + break; + case 244: + globalint_517 = arg1; + break; + case 245: + globalint_518 = arg1; + break; + case 246: + globalint_519 = arg1; + break; + case 247: + globalint_520 = arg1; + break; + case 248: + globalint_521 = arg1; + break; + case 249: + globalint_522 = arg1; + } + return; +} diff --git a/dumps/scripts/1385.cs2 b/dumps/scripts/1385.cs2 new file mode 100644 index 0000000..b0e4987 --- /dev/null +++ b/dumps/scripts/1385.cs2 @@ -0,0 +1,6 @@ +void script_1385() { + script_1309(0); + setWidgetSprite(2201, new WidgetPointer(746,176)); + script_1308(); + return; +} diff --git a/dumps/scripts/1386.cs2 b/dumps/scripts/1386.cs2 new file mode 100644 index 0000000..1d84e07 --- /dev/null +++ b/dumps/scripts/1386.cs2 @@ -0,0 +1,6 @@ +void script_1386() { + script_1312(0); + setWidgetSprite(2201, new WidgetPointer(548,182)); + script_1311(); + return; +} diff --git a/dumps/scripts/1387.cs2 b/dumps/scripts/1387.cs2 new file mode 100644 index 0000000..9fdb998 --- /dev/null +++ b/dumps/scripts/1387.cs2 @@ -0,0 +1,274 @@ +void script_1387(int arg0) { + if (((boolean)globalint_1413) && (arg0 != 99)) { + return; + } + script_4249(arg0); + if (getDisplayMode() >= 2) { + if (isWidgetOpen(new WidgetPointer(746,87))) { + if ((arg0 != 98) || isWidgetOpen(new WidgetPointer(746,88))) { + setWidgetIsHidden(false, new WidgetPointer(746,87)); + setWidgetIsHidden(true, new WidgetPointer(746,88)); + setWidgetIsHidden(false, new WidgetPointer(746,86)); + setWidgetIsHidden(true, new WidgetPointer(746,89)); + } else { + setWidgetIsHidden(true, new WidgetPointer(746,87)); + setWidgetIsHidden(false, new WidgetPointer(746,88)); + setWidgetIsHidden(false, new WidgetPointer(746,86)); + setWidgetIsHidden(true, new WidgetPointer(746,89)); + } + } else { + setWidgetIsHidden(true, new WidgetPointer(746,87)); + setWidgetIsHidden(false, new WidgetPointer(746,89)); + if (arg0 != 2) { + script_1659(); + } + switch (arg0) { + case 0: + setWidgetSprite(1836, new WidgetPointer(746,39)); + setWidgetIsHidden(false, new WidgetPointer(746,90)); + setWidgetSprite(1841, new WidgetPointer(746,132)); + setWidgetSprite(1840, new WidgetPointer(746,133)); + setWidgetIsHidden(false, new WidgetPointer(746,86)); + break; + case 1: + setWidgetSprite(1836, new WidgetPointer(746,40)); + setWidgetIsHidden(false, new WidgetPointer(746,91)); + setWidgetSprite(1841, new WidgetPointer(746,134)); + setWidgetSprite(1840, new WidgetPointer(746,135)); + setWidgetIsHidden(false, new WidgetPointer(746,86)); + break; + case 2: + setWidgetSprite(1836, new WidgetPointer(746,41)); + setWidgetSprite(1841, new WidgetPointer(746,136)); + setWidgetSprite(1840, new WidgetPointer(746,137)); + setWidgetIsHidden(false, new WidgetPointer(746,92)); + setWidgetIsHidden(false, new WidgetPointer(746,86)); + script_1658(); + break; + case 3: + setWidgetSprite(1836, new WidgetPointer(746,42)); + setWidgetSprite(1841, new WidgetPointer(746,138)); + setWidgetSprite(1840, new WidgetPointer(746,139)); + setWidgetIsHidden(false, new WidgetPointer(746,93)); + setWidgetIsHidden(false, new WidgetPointer(746,86)); + break; + case 4: + setWidgetSprite(1836, new WidgetPointer(746,43)); + setWidgetSprite(1841, new WidgetPointer(746,140)); + setWidgetSprite(1840, new WidgetPointer(746,141)); + setWidgetIsHidden(false, new WidgetPointer(746,94)); + setWidgetIsHidden(false, new WidgetPointer(746,86)); + break; + case 5: + setWidgetSprite(1836, new WidgetPointer(746,44)); + setWidgetSprite(1841, new WidgetPointer(746,142)); + setWidgetSprite(1840, new WidgetPointer(746,143)); + setWidgetIsHidden(false, new WidgetPointer(746,95)); + setWidgetIsHidden(false, new WidgetPointer(746,86)); + break; + case 6: + setWidgetSprite(1836, new WidgetPointer(746,45)); + setWidgetSprite(1841, new WidgetPointer(746,144)); + setWidgetSprite(1840, new WidgetPointer(746,145)); + setWidgetIsHidden(false, new WidgetPointer(746,96)); + setWidgetIsHidden(false, new WidgetPointer(746,86)); + break; + case 7: + setWidgetSprite(1836, new WidgetPointer(746,46)); + setWidgetSprite(1841, new WidgetPointer(746,146)); + setWidgetSprite(1840, new WidgetPointer(746,147)); + setWidgetIsHidden(false, new WidgetPointer(746,97)); + setWidgetIsHidden(false, new WidgetPointer(746,86)); + break; + case 8: + setWidgetSprite(1836, new WidgetPointer(746,47)); + setWidgetSprite(1841, new WidgetPointer(746,148)); + setWidgetSprite(1840, new WidgetPointer(746,149)); + setWidgetIsHidden(false, new WidgetPointer(746,98)); + setWidgetIsHidden(false, new WidgetPointer(746,86)); + break; + case 9: + setWidgetSprite(1836, new WidgetPointer(746,48)); + setWidgetSprite(1841, new WidgetPointer(746,150)); + setWidgetSprite(1840, new WidgetPointer(746,151)); + setWidgetIsHidden(false, new WidgetPointer(746,99)); + setWidgetIsHidden(false, new WidgetPointer(746,86)); + break; + case 10: + setWidgetSprite(1836, new WidgetPointer(746,49)); + setWidgetSprite(1841, new WidgetPointer(746,152)); + setWidgetSprite(1840, new WidgetPointer(746,153)); + setWidgetIsHidden(false, new WidgetPointer(746,100)); + setWidgetIsHidden(false, new WidgetPointer(746,86)); + break; + case 11: + setWidgetSprite(1836, new WidgetPointer(746,50)); + setWidgetSprite(1841, new WidgetPointer(746,154)); + setWidgetSprite(1840, new WidgetPointer(746,155)); + setWidgetIsHidden(false, new WidgetPointer(746,101)); + setWidgetIsHidden(false, new WidgetPointer(746,86)); + break; + case 12: + setWidgetSprite(1836, new WidgetPointer(746,51)); + setWidgetSprite(1841, new WidgetPointer(746,156)); + setWidgetSprite(1840, new WidgetPointer(746,157)); + setWidgetIsHidden(false, new WidgetPointer(746,102)); + setWidgetIsHidden(false, new WidgetPointer(746,86)); + break; + case 13: + setWidgetSprite(1836, new WidgetPointer(746,52)); + setWidgetSprite(1841, new WidgetPointer(746,158)); + setWidgetSprite(1840, new WidgetPointer(746,159)); + setWidgetIsHidden(false, new WidgetPointer(746,103)); + setWidgetIsHidden(false, new WidgetPointer(746,86)); + break; + case 14: + setWidgetSprite(1836, new WidgetPointer(746,53)); + setWidgetSprite(1841, new WidgetPointer(746,160)); + setWidgetSprite(1840, new WidgetPointer(746,161)); + setWidgetIsHidden(false, new WidgetPointer(746,104)); + setWidgetIsHidden(false, new WidgetPointer(746,86)); + break; + case 15: + setWidgetSprite(1836, new WidgetPointer(746,54)); + setWidgetSprite(1841, new WidgetPointer(746,162)); + setWidgetSprite(1840, new WidgetPointer(746,163)); + setWidgetIsHidden(false, new WidgetPointer(746,105)); + setWidgetIsHidden(false, new WidgetPointer(746,86)); + break; + case 98: + setWidgetIsHidden(false, new WidgetPointer(746,88)); + setWidgetIsHidden(false, new WidgetPointer(746,86)); + break; + case 95: + setWidgetIsHidden(false, new WidgetPointer(746,107)); + setWidgetIsHidden(false, new WidgetPointer(746,86)); + break; + case 99: + setWidgetIsHidden(false, new WidgetPointer(746,108)); + setWidgetIsHidden(false, new WidgetPointer(746,86)); + } + } + } else if (isWidgetOpen(new WidgetPointer(548,199))) { + if ((arg0 != 98) || isWidgetOpen(new WidgetPointer(548,200))) { + setWidgetIsHidden(false, new WidgetPointer(548,199)); + setWidgetIsHidden(true, new WidgetPointer(548,200)); + setWidgetIsHidden(true, new WidgetPointer(548,201)); + } else { + setWidgetIsHidden(true, new WidgetPointer(548,199)); + setWidgetIsHidden(false, new WidgetPointer(548,200)); + setWidgetIsHidden(true, new WidgetPointer(548,201)); + } + } else { + setWidgetIsHidden(true, new WidgetPointer(548,199)); + setWidgetIsHidden(false, new WidgetPointer(548,201)); + switch (arg0) { + case 0: + setWidgetSprite(1836, new WidgetPointer(548,129)); + setWidgetSprite(1841, new WidgetPointer(548,147)); + setWidgetSprite(1840, new WidgetPointer(548,148)); + setWidgetIsHidden(false, new WidgetPointer(548,204)); + break; + case 1: + setWidgetSprite(1836, new WidgetPointer(548,130)); + setWidgetSprite(1841, new WidgetPointer(548,149)); + setWidgetSprite(1840, new WidgetPointer(548,150)); + setWidgetIsHidden(false, new WidgetPointer(548,205)); + break; + case 2: + setWidgetSprite(1836, new WidgetPointer(548,131)); + setWidgetSprite(1841, new WidgetPointer(548,151)); + setWidgetSprite(1840, new WidgetPointer(548,152)); + setWidgetIsHidden(false, new WidgetPointer(548,206)); + script_1659(); + break; + case 3: + setWidgetSprite(1836, new WidgetPointer(548,132)); + setWidgetSprite(1841, new WidgetPointer(548,153)); + setWidgetSprite(1840, new WidgetPointer(548,154)); + setWidgetIsHidden(false, new WidgetPointer(548,207)); + break; + case 4: + setWidgetSprite(1836, new WidgetPointer(548,133)); + setWidgetSprite(1841, new WidgetPointer(548,155)); + setWidgetSprite(1840, new WidgetPointer(548,156)); + setWidgetIsHidden(false, new WidgetPointer(548,208)); + break; + case 5: + setWidgetSprite(1836, new WidgetPointer(548,134)); + setWidgetSprite(1841, new WidgetPointer(548,157)); + setWidgetSprite(1840, new WidgetPointer(548,158)); + setWidgetIsHidden(false, new WidgetPointer(548,209)); + break; + case 6: + setWidgetSprite(1836, new WidgetPointer(548,135)); + setWidgetSprite(1841, new WidgetPointer(548,159)); + setWidgetSprite(1840, new WidgetPointer(548,160)); + setWidgetIsHidden(false, new WidgetPointer(548,210)); + break; + case 7: + setWidgetSprite(1836, new WidgetPointer(548,136)); + setWidgetSprite(1841, new WidgetPointer(548,161)); + setWidgetSprite(1840, new WidgetPointer(548,162)); + setWidgetIsHidden(false, new WidgetPointer(548,211)); + break; + case 8: + setWidgetSprite(1836, new WidgetPointer(548,99)); + setWidgetSprite(1841, new WidgetPointer(548,83)); + setWidgetSprite(1840, new WidgetPointer(548,84)); + setWidgetIsHidden(false, new WidgetPointer(548,212)); + break; + case 9: + setWidgetSprite(1836, new WidgetPointer(548,100)); + setWidgetSprite(1841, new WidgetPointer(548,85)); + setWidgetSprite(1840, new WidgetPointer(548,86)); + setWidgetIsHidden(false, new WidgetPointer(548,213)); + break; + case 10: + setWidgetSprite(1836, new WidgetPointer(548,101)); + setWidgetSprite(1841, new WidgetPointer(548,87)); + setWidgetSprite(1840, new WidgetPointer(548,88)); + setWidgetIsHidden(false, new WidgetPointer(548,214)); + break; + case 11: + setWidgetSprite(1836, new WidgetPointer(548,102)); + setWidgetSprite(1841, new WidgetPointer(548,89)); + setWidgetSprite(1840, new WidgetPointer(548,90)); + setWidgetIsHidden(false, new WidgetPointer(548,215)); + break; + case 12: + setWidgetSprite(1836, new WidgetPointer(548,103)); + setWidgetSprite(1841, new WidgetPointer(548,91)); + setWidgetSprite(1840, new WidgetPointer(548,92)); + setWidgetIsHidden(false, new WidgetPointer(548,216)); + break; + case 13: + setWidgetSprite(1836, new WidgetPointer(548,104)); + setWidgetSprite(1841, new WidgetPointer(548,93)); + setWidgetSprite(1840, new WidgetPointer(548,94)); + setWidgetIsHidden(false, new WidgetPointer(548,217)); + break; + case 14: + setWidgetSprite(1836, new WidgetPointer(548,105)); + setWidgetSprite(1841, new WidgetPointer(548,95)); + setWidgetSprite(1840, new WidgetPointer(548,96)); + setWidgetIsHidden(false, new WidgetPointer(548,218)); + break; + case 15: + setWidgetSprite(1836, new WidgetPointer(548,106)); + setWidgetSprite(1841, new WidgetPointer(548,97)); + setWidgetSprite(1840, new WidgetPointer(548,98)); + setWidgetIsHidden(false, new WidgetPointer(548,219)); + break; + case 98: + setWidgetIsHidden(false, new WidgetPointer(548,200)); + break; + case 95: + setWidgetIsHidden(false, new WidgetPointer(548,221)); + break; + case 99: + setWidgetIsHidden(false, new WidgetPointer(548,222)); + } + } + return; +} diff --git a/dumps/scripts/1388.cs2 b/dumps/scripts/1388.cs2 new file mode 100644 index 0000000..6756fd4 --- /dev/null +++ b/dumps/scripts/1388.cs2 @@ -0,0 +1,44 @@ +void script_1388(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + deleteAllExtraChilds(new WidgetPointer(arg0)); + deleteAllExtraChilds(new WidgetPointer(271,6)); + ivar1 = 5; + ivar2 = 15; + ivar3 = 15; + ivar4 = 0; + ivar5 = 6; + ivar6 = 28; + ivar7 = 30; + if (((boolean)bitconfig_6840)) { + ivar7 = 20; + } + while (ivar4 < ivar7) { + createExtraChild(new WidgetPointer(arg0), 5, ivar4); + setWidgetSize(ivar2, ivar3, 0, 0); + cs2method1107(1); + setWidgetPosition(ivar5, ivar6, 0, 0); + if (((boolean)script_2297(ivar4))) { + setWidgetContextMenuOption(1, "Select" + ""); + setWidgetSprite(180); + } else { + setWidgetContextMenuOption(1, "Deselect" + ""); + setWidgetSprite(181); + } + setScriptCallOnClickContextMenu(2290, new WidgetPointer(-32768,3), -2147483643, "Ii"); + setScriptCallOnConfigChange(2291, new WidgetPointer(-32768,3), -2147483643, 1397, 1587, 2, "IiY"); + ivar4 = add(ivar4, 1); + if (((boolean)mod(ivar4, ivar1))) { + ivar5 = 6; + ivar6 = add(ivar6, 35); + } else { + ivar5 = add(ivar5, 37); + } + } + return; +} diff --git a/dumps/scripts/1389.cs2 b/dumps/scripts/1389.cs2 new file mode 100644 index 0000000..fc86f25 --- /dev/null +++ b/dumps/scripts/1389.cs2 @@ -0,0 +1,4 @@ +void script_1389() { + script_1186(); + return; +} diff --git a/dumps/scripts/139.cs2 b/dumps/scripts/139.cs2 new file mode 100644 index 0000000..3abbf81 --- /dev/null +++ b/dumps/scripts/139.cs2 @@ -0,0 +1,5 @@ +void script_139(int arg0) { + setScriptCallOnAnyWidgetOpenAndClose(140, "", new WidgetPointer(arg0)); + script_1364(); + return; +} diff --git a/dumps/scripts/1390.cs2 b/dumps/scripts/1390.cs2 new file mode 100644 index 0000000..d0b6706 --- /dev/null +++ b/dumps/scripts/1390.cs2 @@ -0,0 +1,10 @@ +void script_1390(int arg0,int arg1,string arg2) { + setWidgetPosition(script_1551(globalint_1098, 494, getWidgetActualX(new WidgetPointer(arg0)), arg2), 1, 0, 1, new WidgetPointer(arg1)); + if (hasWindowFocus()) { + setWidgetIsHidden(false, new WidgetPointer(arg1)); + } else { + setWidgetIsHidden(true, new WidgetPointer(arg1)); + } + setScriptCallOnGameloop(1391, getClientCycle(), new WidgetPointer(arg1), "iI", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1391.cs2 b/dumps/scripts/1391.cs2 new file mode 100644 index 0000000..687c600 --- /dev/null +++ b/dumps/scripts/1391.cs2 @@ -0,0 +1,13 @@ +void script_1391(int arg0,int arg1) { + if (cs2method3751()) { + setWidgetText(new WidgetPointer(912,24), ""); + setWidgetIsHidden(true, new WidgetPointer(arg1)); + return; + } + if ((mod(subtract(getClientCycle(), arg0), 40) < 20) && hasWindowFocus()) { + setWidgetIsHidden(false, new WidgetPointer(arg1)); + } else { + setWidgetIsHidden(true, new WidgetPointer(arg1)); + } + return; +} diff --git a/dumps/scripts/1392.cs2 b/dumps/scripts/1392.cs2 new file mode 100644 index 0000000..b079c54 --- /dev/null +++ b/dumps/scripts/1392.cs2 @@ -0,0 +1,49 @@ +void script_1392() { + int ivar0; + ivar0 = rndExcl(4); + if (((boolean)ivar0)) { + setWidgetPosition(59, 9, 0, 0, new WidgetPointer(188,2)); + setWidgetPosition(59, 50, 0, 0, new WidgetPointer(188,3)); + setWidgetPosition(139, 9, 0, 0, new WidgetPointer(188,4)); + setWidgetPosition(139, 50, 0, 0, new WidgetPointer(188,5)); + setWidgetPosition(219, 9, 0, 0, new WidgetPointer(188,6)); + setWidgetPosition(219, 50, 0, 0, new WidgetPointer(188,7)); + setWidgetPosition(319, 9, 0, 0, new WidgetPointer(188,8)); + setWidgetPosition(319, 50, 0, 0, new WidgetPointer(188,9)); + return; + } + if (((boolean)ivar0)) { + setWidgetPosition(59, 9, 0, 0, new WidgetPointer(188,3)); + setWidgetPosition(59, 50, 0, 0, new WidgetPointer(188,4)); + setWidgetPosition(139, 9, 0, 0, new WidgetPointer(188,5)); + setWidgetPosition(139, 50, 0, 0, new WidgetPointer(188,2)); + setWidgetPosition(219, 9, 0, 0, new WidgetPointer(188,7)); + setWidgetPosition(219, 50, 0, 0, new WidgetPointer(188,8)); + setWidgetPosition(319, 9, 0, 0, new WidgetPointer(188,9)); + setWidgetPosition(319, 50, 0, 0, new WidgetPointer(188,6)); + return; + } + if (ivar0 == 2) { + setWidgetPosition(59, 9, 0, 0, new WidgetPointer(188,4)); + setWidgetPosition(59, 50, 0, 0, new WidgetPointer(188,5)); + setWidgetPosition(139, 9, 0, 0, new WidgetPointer(188,2)); + setWidgetPosition(139, 50, 0, 0, new WidgetPointer(188,3)); + setWidgetPosition(219, 9, 0, 0, new WidgetPointer(188,8)); + setWidgetPosition(219, 50, 0, 0, new WidgetPointer(188,9)); + setWidgetPosition(319, 9, 0, 0, new WidgetPointer(188,6)); + setWidgetPosition(319, 50, 0, 0, new WidgetPointer(188,7)); + return; + } + if (ivar0 == 3) { + setWidgetPosition(59, 9, 0, 0, new WidgetPointer(188,5)); + setWidgetPosition(59, 50, 0, 0, new WidgetPointer(188,2)); + setWidgetPosition(139, 9, 0, 0, new WidgetPointer(188,3)); + setWidgetPosition(139, 50, 0, 0, new WidgetPointer(188,4)); + setWidgetPosition(219, 9, 0, 0, new WidgetPointer(188,9)); + setWidgetPosition(219, 50, 0, 0, new WidgetPointer(188,6)); + setWidgetPosition(319, 9, 0, 0, new WidgetPointer(188,7)); + setWidgetPosition(319, 50, 0, 0, new WidgetPointer(188,8)); + return; + } + return; +} diff --git a/dumps/scripts/1393.cs2 b/dumps/scripts/1393.cs2 new file mode 100644 index 0000000..cff71d8 --- /dev/null +++ b/dumps/scripts/1393.cs2 @@ -0,0 +1,16 @@ +int script_1393(int arg0) { + int ivar1; + if (arg0 <= 0) { + return -1; + } + arg0 = subtract(arg0, 1); + ivar1 = getItemContainerLength(94); + if (arg0 < ivar1) { + return getItemAmtInSlot(94, arg0); + } + arg0 = subtract(arg0, ivar1); + if (arg0 < getItemContainerLength(93)) { + return getItemAmtInSlot(93, arg0); + } + return -1; +} diff --git a/dumps/scripts/1394.cs2 b/dumps/scripts/1394.cs2 new file mode 100644 index 0000000..53a82f0 --- /dev/null +++ b/dumps/scripts/1394.cs2 @@ -0,0 +1,53 @@ +void script_1394() { + int ivar0; + int ivar1; + int ivar2; + string svar0; + svar0 = ""; + ivar0 = 0; + ivar1 = 0; + if (((boolean)bitconfig_457)) { + svar0 = concat(svar0, "Ahrim" + "
"); + ivar0 = add(ivar0, 1); + ivar1 = add(ivar1, 1); + } + if (((boolean)bitconfig_458)) { + svar0 = concat(svar0, "Dharok" + "
"); + ivar0 = add(ivar0, 1); + ivar1 = add(ivar1, 1); + } + if (((boolean)bitconfig_459)) { + svar0 = concat(svar0, "Guthan" + "
"); + ivar0 = add(ivar0, 1); + ivar1 = add(ivar1, 1); + } + if (((boolean)bitconfig_460)) { + svar0 = concat(svar0, "Karil" + "
"); + ivar0 = add(ivar0, 1); + ivar1 = add(ivar1, 1); + } + if (((boolean)bitconfig_461)) { + svar0 = concat(svar0, "Torag" + "
"); + ivar0 = add(ivar0, 1); + ivar1 = add(ivar1, 1); + } + if (((boolean)bitconfig_462)) { + svar0 = concat(svar0, "Verac" + "
"); + ivar0 = add(ivar0, 1); + ivar1 = add(ivar1, 1); + } + if (((boolean)bitconfig_9873)) { + svar0 = concat(svar0, "Akrisae" + "
"); + ivar0 = add(ivar0, 1); + ivar1 = add(ivar1, 1); + } + if (((boolean)stringMethod4107(svar0, ""))) { + svar0 = "None"; + ivar0 = 1; + } + ivar2 = add(52, multiply(ivar0, 12)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(24,1)), ivar2, 0, 0, new WidgetPointer(24,1)); + setWidgetText(new WidgetPointer(24,3), svar0); + setWidgetText(new WidgetPointer(24,6), intToStr(max(0, subtract(bitconfig_464, ivar1)))); + return; +} diff --git a/dumps/scripts/1395.cs2 b/dumps/scripts/1395.cs2 new file mode 100644 index 0000000..b99b5be --- /dev/null +++ b/dumps/scripts/1395.cs2 @@ -0,0 +1,411 @@ +void script_1395() { + if (bitconfig_2140 >= 30) { + setWidgetIsHidden(false, new WidgetPointer(391,22)); + setWidgetIsHidden(false, new WidgetPointer(391,24)); + } else { + setWidgetIsHidden(true, new WidgetPointer(391,22)); + setWidgetIsHidden(true, new WidgetPointer(391,24)); + } + setWidgetText(new WidgetPointer(391,115), intToStr(bitconfig_74)); + if (bitconfig_83 > 0) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,87)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,87)); + } + if (bitconfig_83 > 1) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,88)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,88)); + } + if (bitconfig_83 > 2) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,89)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,89)); + } + if (bitconfig_83 > 3) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,91)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,91)); + } + if (bitconfig_83 > 4) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,92)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,92)); + } + if (bitconfig_83 > 5) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,93)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,93)); + } + if (bitconfig_83 > 6) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,94)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,94)); + } + if (bitconfig_83 > 7) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,95)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,95)); + } + if (bitconfig_83 > 8) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,96)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,96)); + } + if (bitconfig_83 > 9) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,97)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,97)); + } + if (bitconfig_84 > 0) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,44)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,44)); + } + if (bitconfig_84 > 1) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,45)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,45)); + } + if (bitconfig_84 > 2) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,46)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,46)); + } + if (bitconfig_84 > 3) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,47)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,47)); + } + if (bitconfig_84 > 4) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,48)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,48)); + } + if (bitconfig_84 > 5) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,49)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,49)); + } + if (bitconfig_84 > 6) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,50)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,50)); + } + if (bitconfig_84 > 7) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,51)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,51)); + } + if (bitconfig_84 > 8) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,52)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,52)); + } + if (bitconfig_84 > 9) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,53)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,53)); + } + if (bitconfig_82 > 0) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,74)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,74)); + } + if (bitconfig_82 > 1) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,75)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,75)); + } + if (bitconfig_82 > 2) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,76)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,76)); + } + if (bitconfig_82 > 3) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,77)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,77)); + } + if (bitconfig_82 > 4) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,78)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,78)); + } + if (bitconfig_82 > 5) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,79)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,79)); + } + if (bitconfig_82 > 6) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,80)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,80)); + } + if (bitconfig_82 > 7) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,81)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,81)); + } + if (bitconfig_82 > 8) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,82)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,82)); + } + if (bitconfig_82 > 9) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,83)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,83)); + } + if (bitconfig_81 > 0) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,58)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,58)); + } + if (bitconfig_81 > 1) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,59)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,59)); + } + if (bitconfig_81 > 2) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,60)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,60)); + } + if (bitconfig_81 > 3) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,61)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,61)); + } + if (bitconfig_81 > 4) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,62)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,62)); + } + if (bitconfig_81 > 5) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,63)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,63)); + } + if (bitconfig_81 > 6) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,64)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,64)); + } + if (bitconfig_81 > 7) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,65)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,65)); + } + if (bitconfig_81 > 8) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,66)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,66)); + } + if (bitconfig_81 > 9) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,70)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,70)); + } + if (bitconfig_2131 > 0) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,124)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,124)); + } + if (bitconfig_2131 > 1) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,125)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,125)); + } + if (bitconfig_2131 > 2) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,126)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,126)); + } + if (bitconfig_2131 > 3) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,127)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,127)); + } + if (bitconfig_2131 > 4) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,128)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,128)); + } + if (bitconfig_2131 > 5) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,129)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,129)); + } + if (bitconfig_2131 > 6) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,130)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,130)); + } + if (bitconfig_2131 > 7) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,131)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,131)); + } + if (bitconfig_2131 > 8) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,132)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,132)); + } + if (bitconfig_2131 > 9) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,133)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,133)); + } + if (bitconfig_2132 > 0) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,145)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,145)); + } + if (bitconfig_2132 > 1) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,146)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,146)); + } + if (bitconfig_2132 > 2) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,147)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,147)); + } + if (bitconfig_2132 > 3) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,148)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,148)); + } + if (bitconfig_2132 > 4) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,149)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,149)); + } + if (bitconfig_2132 > 5) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,150)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,150)); + } + if (bitconfig_2132 > 6) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,151)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,151)); + } + if (bitconfig_2132 > 7) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,152)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,152)); + } + if (bitconfig_2132 > 8) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,153)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,153)); + } + if (bitconfig_2132 > 9) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,154)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,154)); + } + if (standart_config_1888 > 0) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,98)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,98)); + } + if (standart_config_1888 > 1) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,99)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,99)); + } + if (standart_config_1888 > 2) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,100)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,100)); + } + if (standart_config_1888 > 3) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,101)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,101)); + } + if (standart_config_1888 > 4) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,104)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,104)); + } + if (standart_config_1888 > 5) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,105)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,105)); + } + if (standart_config_1888 > 6) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,106)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,106)); + } + if (standart_config_1888 > 7) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,107)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,107)); + } + if (standart_config_1888 > 8) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,108)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,108)); + } + if (standart_config_1888 > 9) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,109)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,109)); + } + if (standart_config_1888 > 10) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,110)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,110)); + } + if (standart_config_1888 > 11) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,111)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,111)); + } + if (standart_config_1888 > 12) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,112)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,112)); + } + if (standart_config_1888 > 13) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,113)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,113)); + } + if (standart_config_1888 > 14) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(391,114)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(391,114)); + } + if (((boolean)bitconfig_2134)) { + setWidgetSprite(180, new WidgetPointer(391,155)); + setWidgetSprite(181, new WidgetPointer(391,157)); + } else { + setWidgetSprite(181, new WidgetPointer(391,155)); + setWidgetSprite(180, new WidgetPointer(391,157)); + } + if (((boolean)bitconfig_2133)) { + setWidgetSprite(181, new WidgetPointer(391,134)); + setWidgetSprite(180, new WidgetPointer(391,135)); + setWidgetSprite(180, new WidgetPointer(391,136)); + } else if (((boolean)bitconfig_2133)) { + setWidgetSprite(180, new WidgetPointer(391,134)); + setWidgetSprite(181, new WidgetPointer(391,135)); + setWidgetSprite(180, new WidgetPointer(391,136)); + } else { + setWidgetSprite(180, new WidgetPointer(391,134)); + setWidgetSprite(180, new WidgetPointer(391,135)); + setWidgetSprite(181, new WidgetPointer(391,136)); + } + if (((boolean)bitconfig_135)) { + setWidgetSprite(180, new WidgetPointer(391,120)); + } else { + setWidgetSprite(181, new WidgetPointer(391,120)); + } + return; +} diff --git a/dumps/scripts/1396.cs2 b/dumps/scripts/1396.cs2 new file mode 100644 index 0000000..2598636 --- /dev/null +++ b/dumps/scripts/1396.cs2 @@ -0,0 +1,4 @@ +void script_1396(int arg0,string arg1,string arg2) { + setScriptCallOnMousePressed(1338, arg1, arg2, arg0, "ss1", new WidgetPointer(445,2)); + return; +} diff --git a/dumps/scripts/1397.cs2 b/dumps/scripts/1397.cs2 new file mode 100644 index 0000000..608ca95 --- /dev/null +++ b/dumps/scripts/1397.cs2 @@ -0,0 +1,48 @@ +void script_1397() { + if (((boolean)bitconfig_1412)) { + setWidgetModel(10112, new WidgetPointer(282,19)); + } else { + setWidgetModel(10111, new WidgetPointer(282,19)); + } + if (bitconfig_1412 == 24) { + setWidgetModel(10114, new WidgetPointer(282,20)); + } else { + setWidgetModel(10113, new WidgetPointer(282,20)); + } + if (bitconfig_1412 == 32) { + setWidgetModel(10110, new WidgetPointer(282,18)); + } else { + setWidgetModel(10109, new WidgetPointer(282,18)); + } + if (bitconfig_1412 == 48) { + setWidgetModel(10108, new WidgetPointer(282,17)); + } else { + setWidgetModel(10107, new WidgetPointer(282,17)); + } + if (bitconfig_1412 == 56) { + setWidgetModel(10106, new WidgetPointer(282,16)); + } else { + setWidgetModel(10105, new WidgetPointer(282,16)); + } + if (bitconfig_1412 == 60) { + setWidgetModel(10104, new WidgetPointer(282,15)); + } else { + setWidgetModel(10103, new WidgetPointer(282,15)); + } + if (bitconfig_1412 == 62) { + setWidgetModel(10102, new WidgetPointer(282,14)); + } else { + setWidgetModel(10101, new WidgetPointer(282,14)); + } + if (bitconfig_1412 == 63) { + setWidgetModel(10100, new WidgetPointer(282,13)); + } else { + setWidgetModel(10099, new WidgetPointer(282,13)); + } + if (((boolean)bitconfig_1413)) { + setWidgetModel(10116, new WidgetPointer(282,12)); + } else { + setWidgetModel(10115, new WidgetPointer(282,12)); + } + return; +} diff --git a/dumps/scripts/1398.cs2 b/dumps/scripts/1398.cs2 new file mode 100644 index 0000000..557e439 --- /dev/null +++ b/dumps/scripts/1398.cs2 @@ -0,0 +1,12 @@ +void script_1398(int arg0,int arg1) { + setWidgetModel(10111, new WidgetPointer(282,19)); + setWidgetModel(10113, new WidgetPointer(282,20)); + setWidgetModel(10109, new WidgetPointer(282,18)); + setWidgetModel(10107, new WidgetPointer(282,17)); + setWidgetModel(10105, new WidgetPointer(282,16)); + setWidgetModel(10103, new WidgetPointer(282,15)); + setWidgetModel(10101, new WidgetPointer(282,14)); + setWidgetModel(10099, new WidgetPointer(282,13)); + setWidgetModel(arg1, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1399.cs2 b/dumps/scripts/1399.cs2 new file mode 100644 index 0000000..6315a18 --- /dev/null +++ b/dumps/scripts/1399.cs2 @@ -0,0 +1,4 @@ +void script_1399(int arg0,int arg1) { + setWidgetModel(arg1, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/14.cs2 b/dumps/scripts/14.cs2 new file mode 100644 index 0000000..7c750cf --- /dev/null +++ b/dumps/scripts/14.cs2 @@ -0,0 +1,157 @@ +cs2func_script_14_struct(2,2,0) script_14(int arg0,int arg1,int arg2) { + int stack_dump0; + int stack_dump1; + cs2func_script_982_struct(2,2,0) structdump_2; + cs2func_script_984_struct(2,2,0) structdump_3; + cs2func_script_978_struct(2,2,0) structdump_4; + cs2func_script_1010_struct(2,2,0) structdump_5; + cs2func_script_1004_struct(2,2,0) structdump_6; + cs2func_script_996_struct(2,2,0) structdump_7; + cs2func_script_994_struct(2,2,0) structdump_8; + cs2func_script_1008_struct(2,2,0) structdump_9; + cs2func_script_1002_struct(2,2,0) structdump_10; + cs2func_script_992_struct(2,2,0) structdump_11; + cs2func_script_1000_struct(2,2,0) structdump_12; + cs2func_script_980_struct(2,2,0) structdump_13; + cs2func_script_1016_struct(2,2,0) structdump_14; + cs2func_script_1022_struct(2,2,0) structdump_15; + cs2func_script_998_struct(2,2,0) structdump_16; + cs2func_script_1018_struct(2,2,0) structdump_17; + cs2func_script_986_struct(2,2,0) structdump_18; + cs2func_script_990_struct(2,2,0) structdump_19; + cs2func_script_1012_struct(2,2,0) structdump_20; + cs2func_script_988_struct(2,2,0) structdump_21; + cs2func_script_1014_struct(2,2,0) structdump_22; + cs2func_script_3_struct(2,2,0) structdump_23; + cs2func_script_1006_struct(2,2,0) structdump_24; + cs2func_script_1020_struct(2,2,0) structdump_25; + cs2func_script_3355_struct(2,2,0) structdump_26; + switch (arg0) { + case 1: + stack_dump0 = arg1; + stack_dump1 = arg2; + structdump_2 = script_982(stack_dump0, stack_dump1); + return newstruct cs2func_script_14_struct(structdump_2.intpart_0, structdump_2.intpart_1, structdump_2.stringpart_0, structdump_2.stringpart_1); + case 2: + stack_dump0 = arg1; + stack_dump1 = arg2; + structdump_3 = script_984(stack_dump0, stack_dump1); + return newstruct cs2func_script_14_struct(structdump_3.intpart_0, structdump_3.intpart_1, structdump_3.stringpart_0, structdump_3.stringpart_1); + case 5: + stack_dump0 = arg1; + stack_dump1 = arg2; + structdump_4 = script_978(stack_dump0, stack_dump1); + return newstruct cs2func_script_14_struct(structdump_4.intpart_0, structdump_4.intpart_1, structdump_4.stringpart_0, structdump_4.stringpart_1); + case 3: + stack_dump0 = arg1; + stack_dump1 = arg2; + structdump_5 = script_1010(stack_dump0, stack_dump1); + return newstruct cs2func_script_14_struct(structdump_5.intpart_0, structdump_5.intpart_1, structdump_5.stringpart_0, structdump_5.stringpart_1); + case 7: + stack_dump0 = arg1; + stack_dump1 = arg2; + structdump_6 = script_1004(stack_dump0, stack_dump1); + return newstruct cs2func_script_14_struct(structdump_6.intpart_0, structdump_6.intpart_1, structdump_6.stringpart_0, structdump_6.stringpart_1); + case 4: + stack_dump0 = arg1; + stack_dump1 = arg2; + structdump_7 = script_996(stack_dump0, stack_dump1); + return newstruct cs2func_script_14_struct(structdump_7.intpart_0, structdump_7.intpart_1, structdump_7.stringpart_0, structdump_7.stringpart_1); + case 6: + stack_dump0 = arg1; + stack_dump1 = arg2; + structdump_8 = script_994(stack_dump0, stack_dump1); + return newstruct cs2func_script_14_struct(structdump_8.intpart_0, structdump_8.intpart_1, structdump_8.stringpart_0, structdump_8.stringpart_1); + case 8: + stack_dump0 = arg1; + stack_dump1 = arg2; + structdump_9 = script_1008(stack_dump0, stack_dump1); + return newstruct cs2func_script_14_struct(structdump_9.intpart_0, structdump_9.intpart_1, structdump_9.stringpart_0, structdump_9.stringpart_1); + case 9: + stack_dump0 = arg1; + stack_dump1 = arg2; + structdump_10 = script_1002(stack_dump0, stack_dump1); + return newstruct cs2func_script_14_struct(structdump_10.intpart_0, structdump_10.intpart_1, structdump_10.stringpart_0, structdump_10.stringpart_1); + case 10: + stack_dump0 = arg1; + stack_dump1 = arg2; + structdump_11 = script_992(stack_dump0, stack_dump1); + return newstruct cs2func_script_14_struct(structdump_11.intpart_0, structdump_11.intpart_1, structdump_11.stringpart_0, structdump_11.stringpart_1); + case 11: + stack_dump0 = arg1; + stack_dump1 = arg2; + structdump_12 = script_1000(stack_dump0, stack_dump1); + return newstruct cs2func_script_14_struct(structdump_12.intpart_0, structdump_12.intpart_1, structdump_12.stringpart_0, structdump_12.stringpart_1); + case 19: + stack_dump0 = arg1; + stack_dump1 = arg2; + structdump_13 = script_980(stack_dump0, stack_dump1); + return newstruct cs2func_script_14_struct(structdump_13.intpart_0, structdump_13.intpart_1, structdump_13.stringpart_0, structdump_13.stringpart_1); + case 13: + stack_dump0 = arg1; + stack_dump1 = arg2; + structdump_14 = script_1016(stack_dump0, stack_dump1); + return newstruct cs2func_script_14_struct(structdump_14.intpart_0, structdump_14.intpart_1, structdump_14.stringpart_0, structdump_14.stringpart_1); + case 14: + stack_dump0 = arg1; + stack_dump1 = arg2; + structdump_15 = script_1022(stack_dump0, stack_dump1); + return newstruct cs2func_script_14_struct(structdump_15.intpart_0, structdump_15.intpart_1, structdump_15.stringpart_0, structdump_15.stringpart_1); + case 15: + stack_dump0 = arg1; + stack_dump1 = arg2; + structdump_16 = script_998(stack_dump0, stack_dump1); + return newstruct cs2func_script_14_struct(structdump_16.intpart_0, structdump_16.intpart_1, structdump_16.stringpart_0, structdump_16.stringpart_1); + case 16: + stack_dump0 = arg1; + stack_dump1 = arg2; + structdump_17 = script_1018(stack_dump0, stack_dump1); + return newstruct cs2func_script_14_struct(structdump_17.intpart_0, structdump_17.intpart_1, structdump_17.stringpart_0, structdump_17.stringpart_1); + case 17: + stack_dump0 = arg1; + stack_dump1 = arg2; + structdump_18 = script_986(stack_dump0, stack_dump1); + return newstruct cs2func_script_14_struct(structdump_18.intpart_0, structdump_18.intpart_1, structdump_18.stringpart_0, structdump_18.stringpart_1); + case 18: + stack_dump0 = arg1; + stack_dump1 = arg2; + structdump_19 = script_990(stack_dump0, stack_dump1); + return newstruct cs2func_script_14_struct(structdump_19.intpart_0, structdump_19.intpart_1, structdump_19.stringpart_0, structdump_19.stringpart_1); + case 12: + stack_dump0 = arg1; + stack_dump1 = arg2; + structdump_20 = script_1012(stack_dump0, stack_dump1); + return newstruct cs2func_script_14_struct(structdump_20.intpart_0, structdump_20.intpart_1, structdump_20.stringpart_0, structdump_20.stringpart_1); + case 20: + stack_dump0 = arg1; + stack_dump1 = arg2; + structdump_21 = script_988(stack_dump0, stack_dump1); + return newstruct cs2func_script_14_struct(structdump_21.intpart_0, structdump_21.intpart_1, structdump_21.stringpart_0, structdump_21.stringpart_1); + case 21: + stack_dump0 = arg1; + stack_dump1 = arg2; + structdump_22 = script_1014(stack_dump0, stack_dump1); + return newstruct cs2func_script_14_struct(structdump_22.intpart_0, structdump_22.intpart_1, structdump_22.stringpart_0, structdump_22.stringpart_1); + case 22: + stack_dump0 = arg1; + stack_dump1 = arg2; + structdump_23 = script_3(stack_dump0, stack_dump1); + return newstruct cs2func_script_14_struct(structdump_23.intpart_0, structdump_23.intpart_1, structdump_23.stringpart_0, structdump_23.stringpart_1); + case 23: + stack_dump0 = arg1; + stack_dump1 = arg2; + structdump_24 = script_1006(stack_dump0, stack_dump1); + return newstruct cs2func_script_14_struct(structdump_24.intpart_0, structdump_24.intpart_1, structdump_24.stringpart_0, structdump_24.stringpart_1); + case 24: + stack_dump0 = arg1; + stack_dump1 = arg2; + structdump_25 = script_1020(stack_dump0, stack_dump1); + return newstruct cs2func_script_14_struct(structdump_25.intpart_0, structdump_25.intpart_1, structdump_25.stringpart_0, structdump_25.stringpart_1); + case 25: + stack_dump0 = arg1; + stack_dump1 = arg2; + structdump_26 = script_3355(stack_dump0, stack_dump1); + return newstruct cs2func_script_14_struct(structdump_26.intpart_0, structdump_26.intpart_1, structdump_26.stringpart_0, structdump_26.stringpart_1); + } + return newstruct cs2func_script_14_struct(0, -1, "", ""); +} diff --git a/dumps/scripts/140.cs2 b/dumps/scripts/140.cs2 new file mode 100644 index 0000000..258e4c9 --- /dev/null +++ b/dumps/scripts/140.cs2 @@ -0,0 +1,4 @@ +void script_140() { + script_1364(); + return; +} diff --git a/dumps/scripts/1400.cs2 b/dumps/scripts/1400.cs2 new file mode 100644 index 0000000..446fa8c --- /dev/null +++ b/dumps/scripts/1400.cs2 @@ -0,0 +1,8 @@ +void script_1400(int arg0,int arg1) { + if ((mod(subtract(getClientCycle(), arg0), 40) < 20) && hasWindowFocus()) { + setWidgetIsHidden(false, new WidgetPointer(arg1)); + } else { + setWidgetIsHidden(true, new WidgetPointer(arg1)); + } + return; +} diff --git a/dumps/scripts/1401.cs2 b/dumps/scripts/1401.cs2 new file mode 100644 index 0000000..3ad30c5 --- /dev/null +++ b/dumps/scripts/1401.cs2 @@ -0,0 +1,53 @@ +int script_1401(int arg0,int arg1,int arg2,string arg3) { + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int stack_dump0; + arg3 = script_1602(arg3); + ivar3 = strLength(arg3); + arg0 = subtract(arg0, arg2); + if (arg0 <= 0) { + return 0; + } + if (arg0 >= getTextWidth(arg1, arg3)) { + return ivar3; + } + ivar4 = 0; + ivar5 = strLength(arg3); + ivar6 = -1; + ivar7 = 0; + ivar8 = 0; + while (ivar4 != ivar5) { + ivar6 = add(divide(subtract(ivar5, ivar4), 2), ivar4); + if (ivar6 == ivar4) { + ivar7 = getTextWidth(arg1, substr(0, ivar5, arg3)); + if (ivar5 > 1) { + ivar8 = getTextWidth(arg1, substr(0, subtract(ivar5, 1), arg3)); + } + if (subtract(ivar7, arg0) < subtract(arg0, ivar8)) { + return ivar5; + } + return subtract(ivar5, 1); + } + if (arg0 <= getTextWidth(arg1, substr(0, ivar6, arg3))) { + stack_dump0 = ivar4; + ivar5 = ivar6; + ivar4 = stack_dump0; + } else { + stack_dump0 = ivar6; + ivar5 = ivar5; + ivar4 = stack_dump0; + } + } + ivar7 = getTextWidth(arg1, substr(0, ivar5, arg3)); + if (ivar5 > 1) { + ivar8 = getTextWidth(arg1, substr(0, subtract(ivar5, 1), arg3)); + } + if (subtract(ivar7, arg0) < subtract(arg0, ivar8)) { + return ivar5; + } + return subtract(ivar5, 1); +} diff --git a/dumps/scripts/1402.cs2 b/dumps/scripts/1402.cs2 new file mode 100644 index 0000000..61e451e --- /dev/null +++ b/dumps/scripts/1402.cs2 @@ -0,0 +1,135 @@ +void script_1402() { + if (standart_config_106 == -1) { + return; + } + if (((boolean)standart_config_106)) { + setWidgetModel(3062, new WidgetPointer(270,5)); + setWidgetAnimation(646, new WidgetPointer(270,5)); + } else if (((boolean)standart_config_106)) { + setWidgetModel(3062, new WidgetPointer(270,6)); + setWidgetAnimation(646, new WidgetPointer(270,6)); + } else if (standart_config_106 == 2) { + setWidgetModel(3062, new WidgetPointer(270,7)); + setWidgetAnimation(646, new WidgetPointer(270,7)); + } else if (standart_config_106 == 3) { + setWidgetModel(3062, new WidgetPointer(270,8)); + setWidgetAnimation(646, new WidgetPointer(270,8)); + } else if (standart_config_106 == 4) { + setWidgetModel(3062, new WidgetPointer(270,9)); + setWidgetAnimation(646, new WidgetPointer(270,9)); + } else if (standart_config_106 == 5) { + setWidgetModel(3062, new WidgetPointer(270,10)); + setWidgetAnimation(646, new WidgetPointer(270,10)); + } else if (standart_config_106 == 6) { + setWidgetModel(3062, new WidgetPointer(270,11)); + setWidgetAnimation(646, new WidgetPointer(270,11)); + } else if (standart_config_106 == 7) { + setWidgetModel(3062, new WidgetPointer(270,12)); + setWidgetAnimation(646, new WidgetPointer(270,12)); + } else if (standart_config_106 == 8) { + setWidgetModel(3062, new WidgetPointer(270,13)); + setWidgetAnimation(646, new WidgetPointer(270,13)); + } else if (standart_config_106 == 9) { + setWidgetModel(3062, new WidgetPointer(270,14)); + setWidgetAnimation(646, new WidgetPointer(270,14)); + } else if (standart_config_106 == 10) { + setWidgetModel(3062, new WidgetPointer(270,15)); + setWidgetAnimation(646, new WidgetPointer(270,15)); + } else if (standart_config_106 == 11) { + setWidgetModel(3062, new WidgetPointer(270,16)); + setWidgetAnimation(646, new WidgetPointer(270,16)); + } else if (standart_config_106 == 12) { + setWidgetModel(3062, new WidgetPointer(270,17)); + setWidgetAnimation(646, new WidgetPointer(270,17)); + } else if (standart_config_106 == 13) { + setWidgetModel(3062, new WidgetPointer(270,18)); + setWidgetAnimation(646, new WidgetPointer(270,18)); + } else if (standart_config_106 == 14) { + setWidgetModel(3062, new WidgetPointer(270,19)); + setWidgetAnimation(646, new WidgetPointer(270,19)); + } else if (standart_config_106 == 15) { + setWidgetModel(3062, new WidgetPointer(270,20)); + setWidgetAnimation(646, new WidgetPointer(270,20)); + } else if (standart_config_106 == 16) { + setWidgetModel(3062, new WidgetPointer(270,21)); + setWidgetAnimation(646, new WidgetPointer(270,21)); + } else if (standart_config_106 == 17) { + setWidgetModel(3062, new WidgetPointer(270,22)); + setWidgetAnimation(646, new WidgetPointer(270,22)); + } else if (standart_config_106 == 18) { + setWidgetModel(3062, new WidgetPointer(270,23)); + setWidgetAnimation(646, new WidgetPointer(270,23)); + } else if (standart_config_106 == 19) { + setWidgetModel(3062, new WidgetPointer(270,24)); + setWidgetAnimation(646, new WidgetPointer(270,24)); + } else if (standart_config_106 == 20) { + setWidgetModel(3062, new WidgetPointer(270,25)); + setWidgetAnimation(646, new WidgetPointer(270,25)); + } else if (standart_config_106 == 21) { + setWidgetModel(3062, new WidgetPointer(270,26)); + setWidgetAnimation(646, new WidgetPointer(270,26)); + } else if (standart_config_106 == 22) { + setWidgetModel(3062, new WidgetPointer(270,27)); + setWidgetAnimation(646, new WidgetPointer(270,27)); + } else if (standart_config_106 == 23) { + setWidgetModel(3062, new WidgetPointer(270,28)); + setWidgetAnimation(646, new WidgetPointer(270,28)); + } else if (standart_config_106 == 24) { + setWidgetModel(3062, new WidgetPointer(270,29)); + setWidgetAnimation(646, new WidgetPointer(270,29)); + } else if (standart_config_106 == 25) { + setWidgetModel(3062, new WidgetPointer(270,30)); + setWidgetAnimation(646, new WidgetPointer(270,30)); + } else if (standart_config_106 == 26) { + setWidgetModel(3062, new WidgetPointer(270,31)); + setWidgetAnimation(646, new WidgetPointer(270,31)); + } else if (standart_config_106 == 27) { + setWidgetModel(3062, new WidgetPointer(270,32)); + setWidgetAnimation(646, new WidgetPointer(270,32)); + } else if (standart_config_106 == 28) { + setWidgetModel(3062, new WidgetPointer(270,33)); + setWidgetAnimation(646, new WidgetPointer(270,33)); + } else if (standart_config_106 == 29) { + setWidgetModel(3062, new WidgetPointer(270,34)); + setWidgetAnimation(646, new WidgetPointer(270,34)); + } else if (standart_config_106 == 30) { + setWidgetModel(3062, new WidgetPointer(270,35)); + setWidgetAnimation(646, new WidgetPointer(270,35)); + } else if (standart_config_106 == 31) { + setWidgetModel(3062, new WidgetPointer(270,36)); + setWidgetAnimation(646, new WidgetPointer(270,36)); + } else if (standart_config_106 == 32) { + setWidgetModel(3062, new WidgetPointer(270,37)); + setWidgetAnimation(646, new WidgetPointer(270,37)); + } else if (standart_config_106 == 33) { + setWidgetModel(3062, new WidgetPointer(270,38)); + setWidgetAnimation(646, new WidgetPointer(270,38)); + } else if (standart_config_106 == 34) { + setWidgetModel(3062, new WidgetPointer(270,39)); + setWidgetAnimation(646, new WidgetPointer(270,39)); + } else if (standart_config_106 == 35) { + setWidgetModel(3062, new WidgetPointer(270,40)); + setWidgetAnimation(646, new WidgetPointer(270,40)); + } else if (standart_config_106 == 36) { + setWidgetModel(3062, new WidgetPointer(270,41)); + setWidgetAnimation(646, new WidgetPointer(270,41)); + } else if (standart_config_106 == 37) { + setWidgetModel(3062, new WidgetPointer(270,42)); + setWidgetAnimation(646, new WidgetPointer(270,42)); + } else if (standart_config_106 == 38) { + setWidgetModel(3062, new WidgetPointer(270,43)); + setWidgetAnimation(646, new WidgetPointer(270,43)); + } else if (standart_config_106 == 39) { + setWidgetModel(3062, new WidgetPointer(270,44)); + setWidgetAnimation(646, new WidgetPointer(270,44)); + } else if (standart_config_106 == 40) { + setWidgetModel(3062, new WidgetPointer(270,45)); + setWidgetAnimation(646, new WidgetPointer(270,45)); + } else { + if (standart_config_106 == 41) { + setWidgetModel(3062, new WidgetPointer(270,46)); + setWidgetAnimation(646, new WidgetPointer(270,46)); + } + } + return; +} diff --git a/dumps/scripts/1403.cs2 b/dumps/scripts/1403.cs2 new file mode 100644 index 0000000..311e44f --- /dev/null +++ b/dumps/scripts/1403.cs2 @@ -0,0 +1,5 @@ +int script_1403(int arg0,int arg1) { + setWidgetPosition(getWidgetActualX(new WidgetPointer(arg0)), multiply(arg1, getWidgetActualHeight(new WidgetPointer(arg0))), 0, 0, new WidgetPointer(arg0)); + arg1 = add(arg1, 1); + return arg1; +} diff --git a/dumps/scripts/1404.cs2 b/dumps/scripts/1404.cs2 new file mode 100644 index 0000000..7619928 --- /dev/null +++ b/dumps/scripts/1404.cs2 @@ -0,0 +1,9 @@ +void script_1404(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + script_1839(bitconfig_5367, arg0, arg1, arg2); + if (arg5 != bitconfig_6175) { + setScriptCallOnConfigChange(1404, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), bitconfig_6175, 463, 1, "IIIIIiY", new WidgetPointer(arg4)); + script_2046(arg3); + } + script_307(); + return; +} diff --git a/dumps/scripts/1405.cs2 b/dumps/scripts/1405.cs2 new file mode 100644 index 0000000..1374a9a --- /dev/null +++ b/dumps/scripts/1405.cs2 @@ -0,0 +1,21 @@ +void script_1405() { + if (((boolean)bitconfig_61)) { + setWidgetText(new WidgetPointer(756,10), "Draughts: Options"); + script_1406(49545219); + } else if (bitconfig_61 == 2) { + setWidgetText(new WidgetPointer(756,10), "Runelink: Options"); + script_1406(49545220); + } else if (bitconfig_61 == 3) { + setWidgetText(new WidgetPointer(756,10), "Runesquares: Options"); + script_1406(49545224); + } else { + if (bitconfig_61 == 4) { + setWidgetText(new WidgetPointer(756,10), "Runeversi: Options"); + script_1406(49545222); + } + } + script_1407(); + script_1408(); + script_1409(); + return; +} diff --git a/dumps/scripts/1406.cs2 b/dumps/scripts/1406.cs2 new file mode 100644 index 0000000..e633322 --- /dev/null +++ b/dumps/scripts/1406.cs2 @@ -0,0 +1,8 @@ +void script_1406(int arg0) { + setWidgetIsHidden(true, new WidgetPointer(756,3)); + setWidgetIsHidden(true, new WidgetPointer(756,4)); + setWidgetIsHidden(true, new WidgetPointer(756,6)); + setWidgetIsHidden(true, new WidgetPointer(756,8)); + setWidgetIsHidden(false, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1407.cs2 b/dumps/scripts/1407.cs2 new file mode 100644 index 0000000..c583d57 --- /dev/null +++ b/dumps/scripts/1407.cs2 @@ -0,0 +1,8 @@ +void script_1407() { + if (((boolean)bitconfig_68)) { + setWidgetSprite(181, new WidgetPointer(756,50)); + } else { + setWidgetSprite(180, new WidgetPointer(756,50)); + } + return; +} diff --git a/dumps/scripts/1408.cs2 b/dumps/scripts/1408.cs2 new file mode 100644 index 0000000..fbef8d7 --- /dev/null +++ b/dumps/scripts/1408.cs2 @@ -0,0 +1,18 @@ +void script_1408() { + setWidgetSprite(180, new WidgetPointer(756,12)); + setWidgetSprite(180, new WidgetPointer(756,13)); + setWidgetSprite(180, new WidgetPointer(756,15)); + setWidgetSprite(180, new WidgetPointer(756,16)); + if (((boolean)bitconfig_49)) { + setWidgetSprite(181, new WidgetPointer(756,12)); + } else if (((boolean)bitconfig_49)) { + setWidgetSprite(181, new WidgetPointer(756,13)); + } else if (bitconfig_49 == 2) { + setWidgetSprite(181, new WidgetPointer(756,15)); + } else { + if (bitconfig_49 == 3) { + setWidgetSprite(181, new WidgetPointer(756,16)); + } + } + return; +} diff --git a/dumps/scripts/1409.cs2 b/dumps/scripts/1409.cs2 new file mode 100644 index 0000000..30422f4 --- /dev/null +++ b/dumps/scripts/1409.cs2 @@ -0,0 +1,42 @@ +void script_1409() { + setWidgetSprite(180, new WidgetPointer(756,36)); + setWidgetSprite(180, new WidgetPointer(756,37)); + setWidgetSprite(180, new WidgetPointer(756,38)); + setWidgetSprite(180, new WidgetPointer(756,39)); + setWidgetSprite(180, new WidgetPointer(756,40)); + setWidgetSprite(180, new WidgetPointer(756,41)); + setWidgetSprite(180, new WidgetPointer(756,42)); + setWidgetSprite(180, new WidgetPointer(756,43)); + setWidgetSprite(180, new WidgetPointer(756,44)); + setWidgetSprite(180, new WidgetPointer(756,45)); + setWidgetSprite(180, new WidgetPointer(756,46)); + setWidgetSprite(180, new WidgetPointer(756,47)); + if (((boolean)bitconfig_50)) { + setWidgetSprite(181, new WidgetPointer(756,36)); + } else if (bitconfig_50 == 2) { + setWidgetSprite(181, new WidgetPointer(756,37)); + } else if (bitconfig_50 == 3) { + setWidgetSprite(181, new WidgetPointer(756,38)); + } else if (bitconfig_50 == 4) { + setWidgetSprite(181, new WidgetPointer(756,39)); + } else if (bitconfig_50 == 5) { + setWidgetSprite(181, new WidgetPointer(756,40)); + } else if (bitconfig_50 == 6) { + setWidgetSprite(181, new WidgetPointer(756,41)); + } else if (bitconfig_50 == 7) { + setWidgetSprite(181, new WidgetPointer(756,42)); + } else if (bitconfig_50 == 8) { + setWidgetSprite(181, new WidgetPointer(756,43)); + } else if (bitconfig_50 == 9) { + setWidgetSprite(181, new WidgetPointer(756,44)); + } else if (bitconfig_50 == 10) { + setWidgetSprite(181, new WidgetPointer(756,45)); + } else if (bitconfig_50 == 11) { + setWidgetSprite(181, new WidgetPointer(756,46)); + } else { + if (bitconfig_50 == 12) { + setWidgetSprite(181, new WidgetPointer(756,47)); + } + } + return; +} diff --git a/dumps/scripts/141.cs2 b/dumps/scripts/141.cs2 new file mode 100644 index 0000000..3f824f7 --- /dev/null +++ b/dumps/scripts/141.cs2 @@ -0,0 +1,9 @@ +void script_141() { + if (((boolean)standart_config_1042)) { + setWidgetIsHidden(false, new WidgetPointer(335,39)); + } + if (((boolean)standart_config_1043)) { + setWidgetIsHidden(false, new WidgetPointer(335,40)); + } + return; +} diff --git a/dumps/scripts/1410.cs2 b/dumps/scripts/1410.cs2 new file mode 100644 index 0000000..8de44a9 --- /dev/null +++ b/dumps/scripts/1410.cs2 @@ -0,0 +1,26 @@ +void script_1410(int arg0) { + int ivar1; + int ivar2; + ivar1 = 255; + ivar2 = 0; + if (globalint_814 < 256) { + ivar1 = subtract(255, globalint_814); + } else if (globalint_814 < 510) { + ivar1 = mod(globalint_814, 255); + } else { + ivar1 = 255; + } + if (globalint_119 == 4) { + ivar2 = 8; + } else if (globalint_119 == 3) { + ivar2 = 4; + } else { + ivar1 = 255; + } + cs2method2103(ivar1, new WidgetPointer(arg0)); + globalint_814 = add(globalint_814, ivar2); + if (globalint_814 > 510) { + globalint_814 = 0; + } + return; +} diff --git a/dumps/scripts/1411.cs2 b/dumps/scripts/1411.cs2 new file mode 100644 index 0000000..ab9420b --- /dev/null +++ b/dumps/scripts/1411.cs2 @@ -0,0 +1,11 @@ +void script_1411() { + int ivar0; + ivar0 = 20054022; + globalint_761 = cs2method_3408(105, 109, 208, rndExcl(getCommonDefinitionSize(208))); + if (globalint_761 != -1) { + setWidgetModel(globalint_761, new WidgetPointer(ivar0)); + } + setWidgetPosition(subtract(0, getWidgetActualWidth(new WidgetPointer(ivar0))), 120, 0, 0, new WidgetPointer(ivar0)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(306,19)); + return; +} diff --git a/dumps/scripts/1412.cs2 b/dumps/scripts/1412.cs2 new file mode 100644 index 0000000..782b4a1 --- /dev/null +++ b/dumps/scripts/1412.cs2 @@ -0,0 +1,25 @@ +void script_1412(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + deleteAllExtraChilds(new WidgetPointer(arg0)); + ivar1 = getWidgetActualWidth(new WidgetPointer(arg0)); + ivar2 = getWidgetActualHeight(new WidgetPointer(arg0)); + ivar3 = subtract(ivar1, 9); + ivar4 = subtract(ivar2, 9); + ivar5 = subtract(ivar1, 18); + ivar6 = subtract(ivar2, 18); + script_98(arg0, 0, 297, 0, 0, ivar1, ivar2); + script_98(arg0, 1, 1259, 0, 0, 9, 9); + script_98(arg0, 2, 1260, ivar3, 0, 9, 9); + script_98(arg0, 3, 1261, 0, ivar4, 9, 9); + script_98(arg0, 4, 1262, ivar3, ivar4, 9, 9); + script_98(arg0, 5, 1263, 0, 9, 9, ivar6); + script_98(arg0, 6, 1264, 9, 0, ivar5, 9); + script_98(arg0, 7, 1265, ivar3, 9, 9, ivar6); + script_98(arg0, 8, 1266, 9, ivar4, ivar5, 9); + return; +} diff --git a/dumps/scripts/1413.cs2 b/dumps/scripts/1413.cs2 new file mode 100644 index 0000000..a950df4 --- /dev/null +++ b/dumps/scripts/1413.cs2 @@ -0,0 +1,25 @@ +void script_1413(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + deleteAllExtraChilds(new WidgetPointer(arg0)); + ivar1 = getWidgetActualWidth(new WidgetPointer(arg0)); + ivar2 = getWidgetActualHeight(new WidgetPointer(arg0)); + ivar3 = subtract(ivar1, 9); + ivar4 = subtract(ivar2, 9); + ivar5 = subtract(ivar1, 18); + ivar6 = subtract(ivar2, 18); + script_98(arg0, 0, 897, 0, 0, ivar1, ivar2); + script_98(arg0, 1, 1267, 0, 0, 9, 9); + script_98(arg0, 2, 1268, ivar3, 0, 9, 9); + script_98(arg0, 3, 1269, 0, ivar4, 9, 9); + script_98(arg0, 4, 1270, ivar3, ivar4, 9, 9); + script_98(arg0, 5, 1271, 0, 9, 9, ivar6); + script_98(arg0, 6, 1272, 9, 0, ivar5, 9); + script_98(arg0, 7, 1273, ivar3, 9, 9, ivar6); + script_98(arg0, 8, 1274, 9, ivar4, ivar5, 9); + return; +} diff --git a/dumps/scripts/1414.cs2 b/dumps/scripts/1414.cs2 new file mode 100644 index 0000000..d8ffb79 --- /dev/null +++ b/dumps/scripts/1414.cs2 @@ -0,0 +1,25 @@ +void script_1414(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + deleteAllExtraChilds(new WidgetPointer(arg0)); + ivar1 = getWidgetActualWidth(new WidgetPointer(arg0)); + ivar2 = getWidgetActualHeight(new WidgetPointer(arg0)); + ivar3 = subtract(ivar1, 9); + ivar4 = subtract(ivar2, 9); + ivar5 = subtract(ivar1, 18); + ivar6 = subtract(ivar2, 18); + script_98(arg0, 0, 1040, 0, 0, ivar1, ivar2); + script_98(arg0, 1, 1275, 0, 0, 9, 9); + script_98(arg0, 2, 1276, ivar3, 0, 9, 9); + script_98(arg0, 3, 1277, 0, ivar4, 9, 9); + script_98(arg0, 4, 1278, ivar3, ivar4, 9, 9); + script_98(arg0, 5, 1279, 0, 9, 9, ivar6); + script_98(arg0, 6, 1280, 9, 0, ivar5, 9); + script_98(arg0, 7, 1281, ivar3, 9, 9, ivar6); + script_98(arg0, 8, 1282, 9, ivar4, ivar5, 9); + return; +} diff --git a/dumps/scripts/1415.cs2 b/dumps/scripts/1415.cs2 new file mode 100644 index 0000000..6ed988e --- /dev/null +++ b/dumps/scripts/1415.cs2 @@ -0,0 +1,30 @@ +void script_1415() { + int ivar0; + int ivar1; + int ivar2; + ivar0 = 0; + ivar1 = 0; + ivar2 = 0; + while (ivar0 <= getItemContainerLength(93)) { + createExtraChild(new WidgetPointer(323,5), 5, ivar0); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(add(5, multiply(40, ivar1)), multiply(40, ivar2), 0, 0); + if (getItemIdInSlot(93, ivar0) != -1) { + setItemOnWidgetMethod1200(getItemIdInSlot(93, ivar0), getItemAmtInSlot(93, ivar0)); + cs2method1305("" + getItemName(getItemIdInSlot(93, ivar0))); + setWidgetContextMenuOption(1, "" + "Value"); + setWidgetContextMenuOption(2, "Pack " + "" + "1"); + setWidgetContextMenuOption(3, "Pack " + "" + "5"); + setWidgetContextMenuOption(4, "Pack " + "" + "All"); + setWidgetContextMenuOption(5, "Pack " + "" + "X"); + setWidgetContextMenuOption(10, "Examine"); + } + ivar0 = add(ivar0, 1); + ivar1 = add(ivar1, 1); + if (ivar1 > 6) { + ivar1 = 0; + ivar2 = add(ivar2, 1); + } + } + return; +} diff --git a/dumps/scripts/1416.cs2 b/dumps/scripts/1416.cs2 new file mode 100644 index 0000000..037555c --- /dev/null +++ b/dumps/scripts/1416.cs2 @@ -0,0 +1,5 @@ +int script_1416(int arg0,int arg1) { + setWidgetPosition(getWidgetActualX(new WidgetPointer(arg0)), subtract(225, multiply(arg1, getWidgetActualHeight(new WidgetPointer(arg0)))), 0, 0, new WidgetPointer(arg0)); + arg1 = add(arg1, 1); + return arg1; +} diff --git a/dumps/scripts/1417.cs2 b/dumps/scripts/1417.cs2 new file mode 100644 index 0000000..73d9635 --- /dev/null +++ b/dumps/scripts/1417.cs2 @@ -0,0 +1,50 @@ +void script_1417(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + if (((boolean)globalint_1387)) { + return; + } + ivar1 = script_1502(arg0); + ivar2 = -1; + ivar3 = getWidgetActualX(new WidgetPointer(arg0)); + ivar4 = getWidgetActualY(new WidgetPointer(arg0)); + if (bitconfig_7516 == ivar1) { + ivar2 = script_486(bitconfig_7520); + } else if (bitconfig_7517 == ivar1) { + ivar2 = script_486(bitconfig_7521); + } else if (bitconfig_7518 == ivar1) { + ivar2 = script_486(bitconfig_7526); + } else if (bitconfig_7519 == ivar1) { + ivar2 = script_486(bitconfig_7527); + } else if (bitconfig_7522 == ivar1) { + ivar2 = script_486(bitconfig_7530); + } else if (bitconfig_7523 == ivar1) { + ivar2 = script_486(bitconfig_7531); + } else if (bitconfig_7524 == ivar1) { + ivar2 = script_486(bitconfig_7532); + } else if (bitconfig_7525 == ivar1) { + ivar2 = script_486(bitconfig_7533); + } else if (bitconfig_7528 == ivar1) { + ivar2 = script_486(bitconfig_7534); + } else { + if (bitconfig_7529 == ivar1) { + ivar2 = script_486(bitconfig_7535); + } + } + if (ivar2 != -1) { + setWidgetText(new WidgetPointer(1017,241), getNpcNodemapData(ivar2, 1139)); + setWidgetSize(add(getTextWidth(2710, getNpcNodemapData(ivar2, 1139)), 10), getWidgetActualHeight(new WidgetPointer(1017,226)), 0, 0, new WidgetPointer(1017,226)); + ivar3 = subtract(add(ivar3, getWidgetActualWidth(new WidgetPointer(arg0))), 3); + ivar4 = subtract(ivar4, getWidgetActualHeight(new WidgetPointer(arg0))); + if (add(ivar3, getWidgetActualWidth(new WidgetPointer(1017,226))) >= add(getWidgetActualX(new WidgetPointer(1017,31)), getWidgetActualWidth(new WidgetPointer(1017,31)))) { + ivar3 = add(subtract(getWidgetActualX(new WidgetPointer(arg0)), getWidgetActualWidth(new WidgetPointer(1017,226))), 3); + } + setWidgetPosition(ivar3, ivar4, 0, 0, new WidgetPointer(1017,226)); + setWidgetIsHidden(false, new WidgetPointer(1017,226)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1017,226)); + } + return; +} diff --git a/dumps/scripts/1418.cs2 b/dumps/scripts/1418.cs2 new file mode 100644 index 0000000..aa24c0e --- /dev/null +++ b/dumps/scripts/1418.cs2 @@ -0,0 +1,4 @@ +void script_1418() { + setWidgetIsHidden(true, new WidgetPointer(1017,226)); + return; +} diff --git a/dumps/scripts/1419.cs2 b/dumps/scripts/1419.cs2 new file mode 100644 index 0000000..58826f2 --- /dev/null +++ b/dumps/scripts/1419.cs2 @@ -0,0 +1,22 @@ +void script_1419() { + if (((boolean)globalint_1413)) { + return; + } + if (((boolean)globalint_11)) { + script_675(); + } + if (getDisplayMode() >= 2) { + setWidgetIsHidden(false, new WidgetPointer(746,73)); + } + setWidgetIsHidden(false, new WidgetPointer(752,3)); + setWidgetIsHidden(true, new WidgetPointer(752,7)); + setWidgetIsHidden(true, new WidgetPointer(752,8)); + setWidgetText(new WidgetPointer(752,4), "Enter name of player to delete from list"); + globalint_5 = 5; + script_1564(""); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(752,3)); + script_2026(); + setScriptCallOnKeyPress(112, -2147483640, false, "iz", new WidgetPointer(752,5)); + script_1188(); + return; +} diff --git a/dumps/scripts/142.cs2 b/dumps/scripts/142.cs2 new file mode 100644 index 0000000..7d8b73e --- /dev/null +++ b/dumps/scripts/142.cs2 @@ -0,0 +1,203 @@ +void script_142() { + int ivar0; + int ivar1; + int ivar2; + if (((boolean)getLanguage())) { + setWidgetFont(495, new WidgetPointer(334,50)); + setWidgetFont(495, new WidgetPointer(334,52)); + setWidgetTextAlignment(1, 1, 17, new WidgetPointer(334,50)); + setWidgetTextAlignment(1, 1, 17, new WidgetPointer(334,52)); + } else { + setWidgetFont(494, new WidgetPointer(334,50)); + setWidgetFont(494, new WidgetPointer(334,52)); + setWidgetTextAlignment(1, 1, 0, new WidgetPointer(334,50)); + setWidgetTextAlignment(1, 1, 0, new WidgetPointer(334,52)); + } + deleteAllExtraChilds(new WidgetPointer(334,38)); + deleteAllExtraChilds(new WidgetPointer(334,39)); + deleteAllExtraChilds(new WidgetPointer(334,40)); + ivar0 = 0; + ivar1 = -1; + if ((((((((((((((getItemIdInSlot(90, 14) != -1) || (getItemIdInSlot(90, 15) != -1)) || (getItemIdInSlot(90, 16) != -1)) || (getItemIdInSlot(90, 17) != -1)) || (getItemIdInSlot(90, 18) != -1)) || (getItemIdInSlot(90, 19) != -1)) || (getItemIdInSlot(90, 20) != -1)) || (getItemIdInSlot(90, 21) != -1)) || (getItemIdInSlot(90, 22) != -1)) || (getItemIdInSlot(90, 23) != -1)) || (getItemIdInSlot(90, 24) != -1)) || (getItemIdInSlot(90, 25) != -1)) || (getItemIdInSlot(90, 26) != -1)) || (getItemIdInSlot(90, 27) != -1)) { + setWidgetIsHidden(false, new WidgetPointer(334,39)); + setWidgetIsHidden(false, new WidgetPointer(334,40)); + setWidgetIsHidden(false, new WidgetPointer(334,41)); + while (ivar0 < 14) { + ivar1 = getItemIdInSlot(90, ivar0); + if (ivar1 != -1) { + createExtraChild(new WidgetPointer(334,39), 4, getExtraChildGap(new WidgetPointer(334,39))); + setWidgetPosition(0, multiply(ivar0, 12), 1, 0); + setWidgetSize(0, 12, 1, 0); + setWidgetTextAlignment(0, 0, 0); + setWidgetFont(495); + setWidgetRGB(new Color(255, 255, 255)); + setWidgetUnknownBoolean(true); + setWidgetText(script_4107(ivar1, getItemAmtInSlot(90, ivar0))); + } + ivar0 = add(ivar0, 1); + } + while (ivar0 < 28) { + ivar1 = getItemIdInSlot(90, ivar0); + if (ivar1 != -1) { + createExtraChild(new WidgetPointer(334,40), 4, getExtraChildGap(new WidgetPointer(334,40))); + setWidgetPosition(0, multiply(subtract(ivar0, 14), 12), 1, 0); + setWidgetSize(0, 12, 1, 0); + setWidgetTextAlignment(0, 0, 0); + setWidgetFont(495); + setWidgetRGB(new Color(255, 255, 255)); + setWidgetUnknownBoolean(true); + setWidgetText(script_4107(ivar1, getItemAmtInSlot(90, ivar0))); + } + ivar0 = add(ivar0, 1); + } + script_4109(114, 21889062, 21889063, 21889064, 21889065, 21889066); + setScriptCallOnMouseDragged(4108, -2147483647, new WidgetPointer(334,38), new WidgetPointer(334,39), new WidgetPointer(334,40), new WidgetPointer(334,41), new WidgetPointer(334,42), "iIIIII", new WidgetPointer(334,42)); + setScriptCallOnMouseDragReleased(4108, -2147483647, new WidgetPointer(334,38), new WidgetPointer(334,39), new WidgetPointer(334,40), new WidgetPointer(334,41), new WidgetPointer(334,42), "iIIIII", new WidgetPointer(334,42)); + cs2method2314(149, new WidgetPointer(334,42)); + } else { + setWidgetIsHidden(true, new WidgetPointer(334,39)); + setWidgetIsHidden(true, new WidgetPointer(334,40)); + setWidgetIsHidden(true, new WidgetPointer(334,41)); + while (ivar0 < 14) { + ivar1 = getItemIdInSlot(90, ivar0); + if (ivar1 != -1) { + createExtraChild(new WidgetPointer(334,38), 4, getExtraChildGap(new WidgetPointer(334,38))); + setWidgetPosition(0, multiply(ivar0, 12), 1, 0); + setWidgetSize(0, 12, 1, 0); + setWidgetTextAlignment(1, 0, 0); + setWidgetFont(496); + setWidgetRGB(new Color(255, 255, 255)); + setWidgetUnknownBoolean(true); + setWidgetText(script_4107(ivar1, getItemAmtInSlot(90, ivar0))); + } + ivar0 = add(ivar0, 1); + } + } + deleteAllExtraChilds(new WidgetPointer(334,49)); + deleteAllExtraChilds(new WidgetPointer(334,58)); + deleteAllExtraChilds(new WidgetPointer(334,59)); + ivar0 = 0; + ivar2 = 0; + if ((((((((((((((getItemIdInSlotSplit(90, 14) != -1) || (getItemIdInSlotSplit(90, 15) != -1)) || (getItemIdInSlotSplit(90, 16) != -1)) || (getItemIdInSlotSplit(90, 17) != -1)) || (getItemIdInSlotSplit(90, 18) != -1)) || (getItemIdInSlotSplit(90, 19) != -1)) || (getItemIdInSlotSplit(90, 20) != -1)) || (getItemIdInSlotSplit(90, 21) != -1)) || (getItemIdInSlotSplit(90, 22) != -1)) || (getItemIdInSlotSplit(90, 23) != -1)) || (getItemIdInSlotSplit(90, 24) != -1)) || (getItemIdInSlotSplit(90, 25) != -1)) || (getItemIdInSlotSplit(90, 26) != -1)) || (getItemIdInSlotSplit(90, 27) != -1)) { + setWidgetIsHidden(false, new WidgetPointer(334,58)); + setWidgetIsHidden(false, new WidgetPointer(334,59)); + setWidgetIsHidden(false, new WidgetPointer(334,60)); + while (ivar0 < 14) { + ivar2 = script_148(ivar0); + if ((ivar2 > 0) && (ivar2 > subtract(getClientCycle(), 750))) { + setWidgetIsHidden(false, new WidgetPointer(334,55)); + createExtraChild(new WidgetPointer(334,58), 3, getExtraChildGap(new WidgetPointer(334,58))); + createExtraChild(new WidgetPointer(334,58), 3, getExtraChildGap(new WidgetPointer(334,58))); + setWidgetPosition(0, multiply(ivar0, 12), 1, 0); + setWidgetPosition(0, multiply(ivar0, 12), 1, 0); + setWidgetSize(0, 13, 1, 0); + setWidgetSize(0, 13, 1, 0); + setWidgetRGB(new Color(255, 0, 0)); + setWidgetRGB(new Color(153, 0, 0)); + setWidgetFilled(1); + setWidgetFilled(0); + setScriptCallOnGameloop(144, new WidgetPointer(-32768,3), -2147483643, ivar2, add(ivar2, 750), "Iiii"); + setScriptCallOnGameloop(144, new WidgetPointer(-32768,3), -2147483643, ivar2, add(ivar2, 750), "Iiii"); + } + ivar1 = getItemIdInSlotSplit(90, ivar0); + if (ivar1 != -1) { + createExtraChild(new WidgetPointer(334,58), 4, getExtraChildGap(new WidgetPointer(334,58))); + setWidgetPosition(0, multiply(ivar0, 12), 1, 0); + setWidgetSize(0, 12, 1, 0); + setWidgetTextAlignment(0, 0, 0); + setWidgetFont(495); + setWidgetRGB(new Color(255, 255, 255)); + setWidgetUnknownBoolean(true); + setWidgetText(script_4107(ivar1, getItemAmtInSlotSplit(90, ivar0))); + } + ivar0 = add(ivar0, 1); + } + while (ivar0 < 28) { + ivar2 = script_148(ivar0); + if ((ivar2 > 0) && (ivar2 > subtract(getClientCycle(), 750))) { + setWidgetIsHidden(false, new WidgetPointer(334,55)); + createExtraChild(new WidgetPointer(334,59), 3, getExtraChildGap(new WidgetPointer(334,59))); + createExtraChild(new WidgetPointer(334,59), 3, getExtraChildGap(new WidgetPointer(334,59))); + setWidgetPosition(0, multiply(subtract(ivar0, 14), 12), 1, 0); + setWidgetPosition(0, multiply(subtract(ivar0, 14), 12), 1, 0); + setWidgetSize(0, 13, 1, 0); + setWidgetSize(0, 13, 1, 0); + setWidgetRGB(new Color(255, 0, 0)); + setWidgetRGB(new Color(153, 0, 0)); + setWidgetFilled(1); + setWidgetFilled(0); + setScriptCallOnGameloop(144, new WidgetPointer(-32768,3), -2147483643, ivar2, add(ivar2, 750), "Iiii"); + setScriptCallOnGameloop(144, new WidgetPointer(-32768,3), -2147483643, ivar2, add(ivar2, 750), "Iiii"); + } + ivar1 = getItemIdInSlotSplit(90, ivar0); + if (ivar1 != -1) { + createExtraChild(new WidgetPointer(334,59), 4, getExtraChildGap(new WidgetPointer(334,59))); + setWidgetPosition(0, multiply(subtract(ivar0, 14), 12), 1, 0); + setWidgetSize(0, 12, 1, 0); + setWidgetTextAlignment(0, 0, 0); + setWidgetFont(495); + setWidgetRGB(new Color(255, 255, 255)); + setWidgetUnknownBoolean(true); + setWidgetText(script_4107(ivar1, getItemAmtInSlotSplit(90, ivar0))); + } + ivar0 = add(ivar0, 1); + } + script_4109(114, 21889073, 21889082, 21889083, 21889084, 21889085); + setScriptCallOnMouseDragged(4108, -2147483647, new WidgetPointer(334,49), new WidgetPointer(334,58), new WidgetPointer(334,59), new WidgetPointer(334,60), new WidgetPointer(334,61), "iIIIII", new WidgetPointer(334,61)); + setScriptCallOnMouseDragReleased(4108, -2147483647, new WidgetPointer(334,49), new WidgetPointer(334,58), new WidgetPointer(334,59), new WidgetPointer(334,60), new WidgetPointer(334,61), "iIIIII", new WidgetPointer(334,61)); + cs2method2314(149, new WidgetPointer(334,61)); + } else { + setWidgetIsHidden(true, new WidgetPointer(334,58)); + setWidgetIsHidden(true, new WidgetPointer(334,59)); + setWidgetIsHidden(true, new WidgetPointer(334,60)); + while (ivar0 < 14) { + ivar2 = script_148(ivar0); + if ((ivar2 > 0) && (ivar2 > subtract(getClientCycle(), 750))) { + setWidgetIsHidden(false, new WidgetPointer(334,55)); + createExtraChild(new WidgetPointer(334,49), 3, getExtraChildGap(new WidgetPointer(334,49))); + createExtraChild(new WidgetPointer(334,49), 3, getExtraChildGap(new WidgetPointer(334,49))); + setWidgetPosition(0, multiply(ivar0, 12), 1, 0); + setWidgetPosition(0, multiply(ivar0, 12), 1, 0); + setWidgetSize(0, 13, 1, 0); + setWidgetSize(0, 13, 1, 0); + setWidgetRGB(new Color(255, 0, 0)); + setWidgetRGB(new Color(153, 0, 0)); + setWidgetFilled(1); + setWidgetFilled(0); + setScriptCallOnGameloop(144, new WidgetPointer(-32768,3), -2147483643, ivar2, add(ivar2, 750), "Iiii"); + setScriptCallOnGameloop(144, new WidgetPointer(-32768,3), -2147483643, ivar2, add(ivar2, 750), "Iiii"); + } + ivar1 = getItemIdInSlotSplit(90, ivar0); + if (ivar1 != -1) { + createExtraChild(new WidgetPointer(334,49), 4, getExtraChildGap(new WidgetPointer(334,49))); + setWidgetPosition(0, multiply(ivar0, 12), 1, 0); + setWidgetSize(0, 12, 1, 0); + setWidgetTextAlignment(1, 0, 0); + setWidgetFont(496); + setWidgetRGB(new Color(255, 255, 255)); + setWidgetUnknownBoolean(true); + setWidgetText(script_4107(ivar1, getItemAmtInSlotSplit(90, ivar0))); + } + ivar0 = add(ivar0, 1); + } + } + ivar2 = script_148(-1); + if (ivar2 > 0) { + setWidgetIsHidden(false, new WidgetPointer(334,55)); + createExtraChild(new WidgetPointer(334,51), 3, 0); + setWidgetHidden(0); + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(0, 0, 1, 1); + setWidgetRGB(new Color(255, 0, 0)); + setWidgetFilled(1); + setScriptCallOnGameloop(144, new WidgetPointer(-32768,3), -2147483643, ivar2, add(ivar2, 750), "Iiii"); + createExtraChild(new WidgetPointer(334,51), 3, 1); + setWidgetHidden(0); + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(0, 0, 1, 1); + setWidgetRGB(new Color(153, 0, 0)); + setWidgetFilled(0); + setScriptCallOnGameloop(144, new WidgetPointer(-32768,3), -2147483643, ivar2, add(ivar2, 750), "Iiii"); + } + return; +} diff --git a/dumps/scripts/1420.cs2 b/dumps/scripts/1420.cs2 new file mode 100644 index 0000000..cf953a5 --- /dev/null +++ b/dumps/scripts/1420.cs2 @@ -0,0 +1,15 @@ +void script_1420() { + int ivar0; + ivar0 = script_121(subtract(bitconfig_3756, 1)); + if (ivar0 != -1) { + if (mod(getClientCycle(), 40) > 20) { + setWidgetIsHidden(false, new WidgetPointer(ivar0)); + if (mod(getClientCycle(), 40) == 21) { + playSoundEffect(5009, 1, 0); + } + } else { + setWidgetIsHidden(true, new WidgetPointer(ivar0)); + } + } + return; +} diff --git a/dumps/scripts/1421.cs2 b/dumps/scripts/1421.cs2 new file mode 100644 index 0000000..92d5786 --- /dev/null +++ b/dumps/scripts/1421.cs2 @@ -0,0 +1,63 @@ +void script_1421(int arg0) { + string svar0; + svar0 = ""; + switch (arg0) { + case 1: + svar0 = cs2method_3408(105, 115, 1697, bitconfig_5146); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(575,2), svar0, 25, 130, "IIsii", new WidgetPointer(575,3)); + break; + case 2: + svar0 = cs2method_3408(105, 115, 1698, bitconfig_5147); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(575,2), svar0, 25, 160, "IIsii", new WidgetPointer(575,4)); + break; + case 3: + svar0 = cs2method_3408(105, 115, 1699, bitconfig_5148); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(575,2), svar0, 25, 200, "IIsii", new WidgetPointer(575,5)); + break; + case 4: + svar0 = cs2method_3408(105, 115, 1700, bitconfig_5149); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(575,2), svar0, 25, 200, "IIsii", new WidgetPointer(575,6)); + break; + case 5: + svar0 = cs2method_3408(105, 115, 1701, bitconfig_5150); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(575,2), svar0, 25, 200, "IIsii", new WidgetPointer(575,7)); + break; + case 6: + svar0 = cs2method_3408(105, 115, 1702, bitconfig_5151); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(575,2), svar0, 25, 200, "IIsii", new WidgetPointer(575,8)); + break; + case 7: + svar0 = cs2method_3408(105, 115, 1703, bitconfig_5152); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(575,2), svar0, 25, 200, "IIsii", new WidgetPointer(575,9)); + break; + case 8: + svar0 = cs2method_3408(105, 115, 1704, bitconfig_5153); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(575,2), svar0, 25, 200, "IIsii", new WidgetPointer(575,10)); + break; + case 9: + svar0 = cs2method_3408(105, 115, 1705, bitconfig_5154); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(575,2), svar0, 25, 200, "IIsii", new WidgetPointer(575,11)); + break; + case 10: + svar0 = cs2method_3408(105, 115, 1706, bitconfig_5155); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(575,2), svar0, 25, 200, "IIsii", new WidgetPointer(575,12)); + break; + case 11: + svar0 = cs2method_3408(105, 115, 1707, bitconfig_5156); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(575,2), svar0, 25, 200, "IIsii", new WidgetPointer(575,13)); + break; + case 12: + svar0 = cs2method_3408(105, 115, 1708, bitconfig_5157); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(575,2), svar0, 25, 200, "IIsii", new WidgetPointer(575,14)); + break; + case 13: + svar0 = cs2method_3408(105, 115, 1709, bitconfig_5158); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(575,2), svar0, 25, 200, "IIsii", new WidgetPointer(575,15)); + break; + case 14: + svar0 = cs2method_3408(105, 115, 1710, bitconfig_5159); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(575,2), svar0, 25, 200, "IIsii", new WidgetPointer(575,16)); + } + globalint_2 = 0; + return; +} diff --git a/dumps/scripts/1422.cs2 b/dumps/scripts/1422.cs2 new file mode 100644 index 0000000..8266a89 --- /dev/null +++ b/dumps/scripts/1422.cs2 @@ -0,0 +1,7 @@ +void script_1422(int arg0,int arg1,int arg2,int arg3) { + setWidgetSprite(181, new WidgetPointer(arg0)); + setWidgetSprite(180, new WidgetPointer(arg1)); + setWidgetSprite(180, new WidgetPointer(arg2)); + setWidgetSprite(180, new WidgetPointer(arg3)); + return; +} diff --git a/dumps/scripts/1423.cs2 b/dumps/scripts/1423.cs2 new file mode 100644 index 0000000..83add84 --- /dev/null +++ b/dumps/scripts/1423.cs2 @@ -0,0 +1,15 @@ +void script_1423(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11) { + setWidgetSprite(181, new WidgetPointer(arg0)); + setWidgetSprite(180, new WidgetPointer(arg1)); + setWidgetSprite(180, new WidgetPointer(arg2)); + setWidgetSprite(180, new WidgetPointer(arg3)); + setWidgetSprite(180, new WidgetPointer(arg4)); + setWidgetSprite(180, new WidgetPointer(arg5)); + setWidgetSprite(180, new WidgetPointer(arg6)); + setWidgetSprite(180, new WidgetPointer(arg7)); + setWidgetSprite(180, new WidgetPointer(arg8)); + setWidgetSprite(180, new WidgetPointer(arg9)); + setWidgetSprite(180, new WidgetPointer(arg10)); + setWidgetSprite(180, new WidgetPointer(arg11)); + return; +} diff --git a/dumps/scripts/1424.cs2 b/dumps/scripts/1424.cs2 new file mode 100644 index 0000000..dd3ae3a --- /dev/null +++ b/dumps/scripts/1424.cs2 @@ -0,0 +1,10 @@ +void script_1424() { + if (((boolean)bitconfig_4456)) { + setWidgetRGB(new Color(0, 35, 0), new WidgetPointer(5,3)); + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(5,2)); + } else { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(5,3)); + setWidgetRGB(new Color(35, 0, 0), new WidgetPointer(5,2)); + } + return; +} diff --git a/dumps/scripts/1425.cs2 b/dumps/scripts/1425.cs2 new file mode 100644 index 0000000..117b0e1 --- /dev/null +++ b/dumps/scripts/1425.cs2 @@ -0,0 +1,63 @@ +int script_1425(int arg0) { + if (((boolean)arg0)) { + return 14; + } + if (((boolean)arg0)) { + return 58; + } + if (arg0 == 2) { + return 138; + } + if (arg0 == 3) { + return 172; + } + if (arg0 == 4) { + return 262; + } + if (arg0 == 5) { + return 296; + } + if (arg0 == 6) { + return 376; + } + if (arg0 == 7) { + return 410; + } + if (arg0 == 8) { + return 48; + } + if (arg0 == 9) { + return 216; + } + if (arg0 == 10) { + return 14; + } + if (arg0 == 11) { + return 48; + } + if (arg0 == 12) { + return 82; + } + if (arg0 == 13) { + return 172; + } + if (arg0 == 14) { + return 216; + } + if (arg0 == 15) { + return 250; + } + if (arg0 == 16) { + return 345; + } + if (arg0 == 17) { + return 379; + } + if (arg0 == 18) { + return 409; + } + if (arg0 == 19) { + return 379; + } + return 0; +} diff --git a/dumps/scripts/1426.cs2 b/dumps/scripts/1426.cs2 new file mode 100644 index 0000000..74d60c4 --- /dev/null +++ b/dumps/scripts/1426.cs2 @@ -0,0 +1,63 @@ +int script_1426(int arg0) { + if (((boolean)arg0)) { + return 10; + } + if (((boolean)arg0)) { + return 10; + } + if (arg0 == 2) { + return 10; + } + if (arg0 == 3) { + return 10; + } + if (arg0 == 4) { + return 10; + } + if (arg0 == 5) { + return 10; + } + if (arg0 == 6) { + return 10; + } + if (arg0 == 7) { + return 10; + } + if (arg0 == 8) { + return 160; + } + if (arg0 == 9) { + return 160; + } + if (arg0 == 10) { + return 90; + } + if (arg0 == 11) { + return 90; + } + if (arg0 == 12) { + return 90; + } + if (arg0 == 13) { + return 90; + } + if (arg0 == 14) { + return 90; + } + if (arg0 == 15) { + return 90; + } + if (arg0 == 16) { + return 90; + } + if (arg0 == 17) { + return 90; + } + if (arg0 == 18) { + return 90; + } + if (arg0 == 19) { + return 160; + } + return 0; +} diff --git a/dumps/scripts/1427.cs2 b/dumps/scripts/1427.cs2 new file mode 100644 index 0000000..612f958 --- /dev/null +++ b/dumps/scripts/1427.cs2 @@ -0,0 +1,20 @@ +void script_1427(int arg0) { + int ivar1; + ivar1 = mod(getClientCycle(), 32); + if ((globalint_1024 == bitconfig_6521) && (globalint_1024 != 0)) { + if (ivar1 < 8) { + cs2method2103(0, new WidgetPointer(arg0)); + } else if (ivar1 < 16) { + cs2method2103(85, new WidgetPointer(arg0)); + } else if (ivar1 < 24) { + cs2method2103(255, new WidgetPointer(arg0)); + } else { + cs2method2103(85, new WidgetPointer(arg0)); + } + } else if (getWidgetShadeColor(new WidgetPointer(arg0)) != 0) { + cs2method2103(0, new WidgetPointer(arg0)); + } else { + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/1428.cs2 b/dumps/scripts/1428.cs2 new file mode 100644 index 0000000..f8982d4 --- /dev/null +++ b/dumps/scripts/1428.cs2 @@ -0,0 +1,11 @@ +void script_1428(int arg0,int arg1) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + if ((globalint_1024 == bitconfig_6521) && (globalint_1024 != 0)) { + setScriptCallOnGameloop(1429, new WidgetPointer(arg0), arg1, "Ii"); + } else { + setScriptCallOnGameloop(-1, ""); + cs2method2103(0); + } + } + return; +} diff --git a/dumps/scripts/1429.cs2 b/dumps/scripts/1429.cs2 new file mode 100644 index 0000000..2cfaea1 --- /dev/null +++ b/dumps/scripts/1429.cs2 @@ -0,0 +1,21 @@ +void script_1429(int arg0,int arg1) { + int ivar2; + ivar2 = mod(getClientCycle(), 32); + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + if ((globalint_1024 == bitconfig_6521) && (globalint_1024 != 0)) { + if (ivar2 < 8) { + cs2method2103(0); + } else if (ivar2 < 16) { + cs2method2103(85); + } else if (ivar2 < 24) { + cs2method2103(255); + } else { + cs2method2103(85); + } + } else { + setScriptCallOnGameloop(-1, ""); + cs2method2103(0); + } + } + return; +} diff --git a/dumps/scripts/143.cs2 b/dumps/scripts/143.cs2 new file mode 100644 index 0000000..997d120 --- /dev/null +++ b/dumps/scripts/143.cs2 @@ -0,0 +1,27 @@ +void script_143(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + int ivar6; + int ivar7; + ivar4 = 0; + ivar5 = 0; + ivar6 = 0; + ivar7 = 0; + if (getWidgetScrollMaxH(new WidgetPointer(arg0)) > 0) { + ivar6 = divide(subtract(getWidgetScrollMaxH(new WidgetPointer(arg0)), multiply(36, arg1)), subtract(arg1, 1)); + } else { + ivar6 = divide(subtract(getWidgetActualWidth(new WidgetPointer(arg0)), multiply(36, arg1)), subtract(arg1, 1)); + } + if (getWidgetScrollMaxV(new WidgetPointer(arg0)) > 0) { + ivar7 = divide(subtract(getWidgetScrollMaxV(new WidgetPointer(arg0)), multiply(32, arg2)), subtract(arg2, 1)); + } else { + ivar7 = divide(subtract(getWidgetActualHeight(new WidgetPointer(arg0)), multiply(32, arg2)), subtract(arg2, 1)); + } + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSprite(937); + setWidgetSize(10, 32, 0, 0); + setWidgetPosition(add(multiply(add(36, ivar6), mod(arg3, arg1)), 13), multiply(divide(arg3, arg1), add(32, ivar7)), 0, 0); + setWidgetHidden(0); + setScriptCallOnGameloop(144, new WidgetPointer(arg0), -2147483643, getClientCycle(), add(getClientCycle(), 750), "Iiii"); + return; +} diff --git a/dumps/scripts/1430.cs2 b/dumps/scripts/1430.cs2 new file mode 100644 index 0000000..c79fd68 --- /dev/null +++ b/dumps/scripts/1430.cs2 @@ -0,0 +1,27 @@ +cs2func_script_1430_struct(2,0,0) script_1430(int arg0) { + if (((boolean)arg0)) { + cs2method5405(0, 7); + cs2method5405(1, 7); + cs2method5406(0, 0, 41716938, 740, 41569480, 740, 0); + cs2method5406(1, 0, 41766092, 460, 41733324, 460, 0); + cs2method5406(0, 1, 41192647, 985, 40996042, 980, 0); + cs2method5406(1, 1, 41307341, 460, 41192655, 450, 0); + script_1899(0, 100, 150); + cs2method5406(0, 2, 40946906, 945, 40946910, 930, 0); + cs2method5406(1, 2, 41110746, 470, 41094368, 465, 0); + script_1899(1, 100, 150); + cs2method5406(0, 3, 41110760, 980, 41274607, 955, 0); + cs2method5406(1, 3, 41290988, 195, 41405680, 185, 0); + script_1899(2, 100, 150); + cs2method5406(0, 4, 41618664, 705, 41667815, 665, 0); + cs2method5406(1, 4, 41667821, 405, 41749739, 390, 0); + script_1899(3, 100, 150); + cs2method5406(0, 5, 41848036, 640, 41946339, 625, 0); + cs2method5406(1, 5, 41913572, 375, 41929956, 370, 0); + script_1899(4, 100, 150); + cs2method5406(0, 6, 41946339, 370, 41946339, 370, 0); + cs2method5406(1, 6, 41946340, 314, 41946340, 314, 0); + script_1899(5, 100, 150); + } + return newstruct cs2func_script_1430_struct(41716978, 1250324); +} diff --git a/dumps/scripts/1431.cs2 b/dumps/scripts/1431.cs2 new file mode 100644 index 0000000..b6529d4 --- /dev/null +++ b/dumps/scripts/1431.cs2 @@ -0,0 +1,3 @@ +int script_1431() { + return 0; +} diff --git a/dumps/scripts/1432.cs2 b/dumps/scripts/1432.cs2 new file mode 100644 index 0000000..81f9d8a --- /dev/null +++ b/dumps/scripts/1432.cs2 @@ -0,0 +1,23 @@ +int script_1432() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + ivar0 = add(getSkillActualLvl(0), getSkillActualLvl(2)); + ivar1 = divide(multiply(getSkillActualLvl(4), 3), 2); + ivar2 = divide(multiply(getSkillActualLvl(6), 3), 2); + ivar3 = ivar0; + if (ivar1 > ivar3) { + ivar3 = ivar1; + } + if (ivar2 > ivar3) { + ivar3 = ivar2; + } + ivar3 = divide(multiply(ivar3, 13), 10); + if (isMember()) { + ivar3 = divide(add(add(add(add(ivar3, getSkillActualLvl(1)), getSkillActualLvl(3)), divide(getSkillActualLvl(5), 2)), divide(getSkillActualLvl(23), 2)), 4); + } else { + ivar3 = divide(add(add(add(ivar3, getSkillActualLvl(1)), getSkillActualLvl(3)), divide(getSkillActualLvl(5), 2)), 4); + } + return ivar3; +} diff --git a/dumps/scripts/1433.cs2 b/dumps/scripts/1433.cs2 new file mode 100644 index 0000000..dd88604 --- /dev/null +++ b/dumps/scripts/1433.cs2 @@ -0,0 +1,17 @@ +void script_1433() { + if (getDisplayMode() >= 1) { + setScriptCallOnGlobalConfigChange(1434, 184, 1, "Y", new WidgetPointer(746,9)); + setScriptCallOnGlobalConfigChange(1434, 184, 1, "Y", new WidgetPointer(548,2)); + } + setScriptCallOnGlobalConfigChange(1547, 5, 1, "Y", new WidgetPointer(752,3)); + setScriptCallOnWidgetResize(721, "", new WidgetPointer(746,3)); + if (getDisplayMode() >= 2) { + setScriptCallOnConfigChange(1850, new WidgetPointer(746,175), 281, 1255, 2, "IY", new WidgetPointer(746,13)); + script_1886(48890031); + } else { + setScriptCallOnConfigChange(1850, new WidgetPointer(548,184), 281, 1255, 2, "IY", new WidgetPointer(548,66)); + script_1886(35913912); + } + script_51(); + return; +} diff --git a/dumps/scripts/1434.cs2 b/dumps/scripts/1434.cs2 new file mode 100644 index 0000000..662965a --- /dev/null +++ b/dumps/scripts/1434.cs2 @@ -0,0 +1,4 @@ +void script_1434() { + cs2method6200(globalint_184, globalint_184); + return; +} diff --git a/dumps/scripts/1435.cs2 b/dumps/scripts/1435.cs2 new file mode 100644 index 0000000..51b8895 --- /dev/null +++ b/dumps/scripts/1435.cs2 @@ -0,0 +1,4 @@ +void script_1435(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12,int arg13,int arg14,int arg15,int arg16,int arg17,int arg18,int arg19,int arg20) { + script_1436(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19, arg20); + return; +} diff --git a/dumps/scripts/1436.cs2 b/dumps/scripts/1436.cs2 new file mode 100644 index 0000000..e8dd8a9 --- /dev/null +++ b/dumps/scripts/1436.cs2 @@ -0,0 +1,41 @@ +void script_1436(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12,int arg13,int arg14,int arg15,int arg16,int arg17,int arg18,int arg19,int arg20) { + int ivar21; + int ivar22; + deleteAllExtraChilds(new WidgetPointer(arg3)); + createExtraChild(new WidgetPointer(arg3), 5, 0); + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg3)), getWidgetActualHeight(new WidgetPointer(arg3)), 0, 0); + setWidgetSprite(arg7); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg3), 3, getExtraChildGap(new WidgetPointer(arg3))); + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg3)), getWidgetActualHeight(new WidgetPointer(arg3)), 0, 0); + setWidgetRGB(new Color(0, 0, 0)); + ivar21 = 1; + createExtraChild(new WidgetPointer(arg3), 5, ivar21); + setWidgetPosition(subtract(getWidgetActualWidth(new WidgetPointer(arg3)), 16), 0, 0, 0); + setWidgetSize(16, getWidgetActualHeight(new WidgetPointer(arg3)), 0, 0); + setWidgetSprite(arg8); + cs2method1107(0); + setScriptCallOnMouseEntered(1351, new WidgetPointer(arg3), ivar21, arg9, "Iid"); + setScriptCallOnMouseExit(1352, new WidgetPointer(arg3), ivar21, arg8, "Iid"); + ivar22 = getExtraChildGap(new WidgetPointer(arg3)); + setScriptCallOnMousePressed(1347, arg0, arg2, new WidgetPointer(arg4), arg10, new WidgetPointer(arg5), new WidgetPointer(arg6), new WidgetPointer(arg3), arg11, arg12, arg13, arg14, ivar22, ivar21, arg15, arg16, arg17, arg18, arg19, arg20, "giIdIIIiiidiidddddd"); + createExtraChild(new WidgetPointer(arg3), 4, ivar22); + setWidgetText(cs2method_3408(105, 115, arg0, arg1)); + setWidgetPosition(5, 0, 0, 0); + setWidgetSize(subtract(getWidgetActualWidth(new WidgetPointer(arg3)), 22), getWidgetActualHeight(new WidgetPointer(arg3)), 0, 0); + setWidgetUnknownBoolean(false); + setWidgetFont(arg14); + setWidgetTextAlignment(0, 1, 0); + if (arg1 >= arg2) { + setWidgetRGB(new Color(arg12)); + setScriptCallOnMouseExit(1354, new WidgetPointer(arg3), ivar22, arg12, "Iii"); + } else { + setWidgetRGB(new Color(arg11)); + setScriptCallOnMouseExit(1354, new WidgetPointer(arg3), ivar22, arg11, "Iii"); + } + setScriptCallOnMouseEntered(1353, new WidgetPointer(arg3), ivar22, arg13, "Iii"); + setScriptCallOnMousePressed(1347, arg0, arg2, new WidgetPointer(arg4), arg10, new WidgetPointer(arg5), new WidgetPointer(arg6), new WidgetPointer(arg3), arg11, arg12, arg13, arg14, ivar22, ivar21, arg15, arg16, arg17, arg18, arg19, arg20, "giIdIIIiiidiidddddd"); + return; +} diff --git a/dumps/scripts/1437.cs2 b/dumps/scripts/1437.cs2 new file mode 100644 index 0000000..ea07ba2 --- /dev/null +++ b/dumps/scripts/1437.cs2 @@ -0,0 +1,103 @@ +void script_1437() { + if (standart_config_406 > 1) { + setWidgetRGB(new Color(128, 128, 255), new WidgetPointer(371,5)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(371,5)); + } + if (standart_config_406 > 2) { + setWidgetRGB(new Color(128, 128, 255), new WidgetPointer(371,6)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(371,6)); + } + if (standart_config_406 > 3) { + setWidgetRGB(new Color(128, 128, 255), new WidgetPointer(371,7)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(371,7)); + } + if (standart_config_406 > 4) { + setWidgetRGB(new Color(128, 128, 255), new WidgetPointer(371,8)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(371,8)); + } + if (standart_config_406 > 5) { + setWidgetRGB(new Color(128, 128, 255), new WidgetPointer(371,9)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(371,9)); + } + if (standart_config_406 > 6) { + setWidgetRGB(new Color(128, 128, 255), new WidgetPointer(371,10)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(371,10)); + } + if (standart_config_406 > 7) { + setWidgetRGB(new Color(128, 128, 255), new WidgetPointer(371,11)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(371,11)); + } + if (standart_config_406 > 8) { + setWidgetRGB(new Color(128, 128, 255), new WidgetPointer(371,12)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(371,12)); + } + if (standart_config_406 > 9) { + setWidgetRGB(new Color(128, 128, 255), new WidgetPointer(371,13)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(371,13)); + } + if (standart_config_406 > 10) { + setWidgetRGB(new Color(128, 128, 255), new WidgetPointer(371,14)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(371,14)); + } + if (standart_config_406 > 11) { + setWidgetRGB(new Color(128, 128, 255), new WidgetPointer(371,15)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(371,15)); + } + if (standart_config_406 > 12) { + setWidgetRGB(new Color(128, 128, 255), new WidgetPointer(371,16)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(371,16)); + } + if (standart_config_406 > 13) { + setWidgetRGB(new Color(128, 128, 255), new WidgetPointer(371,17)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(371,17)); + } + if (standart_config_406 > 14) { + setWidgetRGB(new Color(128, 128, 255), new WidgetPointer(371,18)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(371,18)); + } + if (standart_config_406 > 15) { + setWidgetRGB(new Color(128, 128, 255), new WidgetPointer(371,19)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(371,19)); + } + if (standart_config_406 > 16) { + setWidgetRGB(new Color(128, 128, 255), new WidgetPointer(371,20)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(371,20)); + } + if (standart_config_406 > 17) { + setWidgetRGB(new Color(128, 128, 255), new WidgetPointer(371,21)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(371,21)); + } + if (standart_config_406 > 18) { + setWidgetRGB(new Color(128, 128, 255), new WidgetPointer(371,22)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(371,22)); + } + if (standart_config_406 > 19) { + setWidgetRGB(new Color(128, 128, 255), new WidgetPointer(371,23)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(371,23)); + } + if (standart_config_406 > 20) { + setWidgetRGB(new Color(128, 128, 255), new WidgetPointer(371,24)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(371,24)); + } + return; +} diff --git a/dumps/scripts/1438.cs2 b/dumps/scripts/1438.cs2 new file mode 100644 index 0000000..59aef36 --- /dev/null +++ b/dumps/scripts/1438.cs2 @@ -0,0 +1,7 @@ +void script_1438(int arg0,int arg1,int arg2) { + if (globalint_657 <= 0) { + return; + } + script_1439(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/1439.cs2 b/dumps/scripts/1439.cs2 new file mode 100644 index 0000000..512494c --- /dev/null +++ b/dumps/scripts/1439.cs2 @@ -0,0 +1,279 @@ +void script_1439(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + string svar0; + deleteAllExtraChilds(new WidgetPointer(arg0)); + deleteAllExtraChilds(new WidgetPointer(arg1)); + deleteAllExtraChilds(new WidgetPointer(arg2)); + globalint_656 = min(globalint_656, subtract(globalint_657, 1)); + ivar3 = 0; + if ((((((((((((((((globalint_658 > 0) || (globalint_659 > 0)) || (globalint_660 > 0)) || (globalint_661 > 0)) || (globalint_662 > 0)) || (globalint_663 > 0)) || (globalint_664 > 0)) || (globalint_665 > 0)) || (globalint_666 > 0)) || (globalint_667 > 0)) || (globalint_668 > 0)) || (globalint_669 > 0)) || (globalint_670 > 0)) || (globalint_658 > 13)) || (globalint_672 > 0)) || (globalint_673 > 0)) { + ivar3 = 1; + } + if (((boolean)ivar3) || (globalint_656 > 0)) { + createExtraChild(new WidgetPointer(arg2), 4, getExtraChildGap(new WidgetPointer(arg2))); + setWidgetSize(2, 14, 1, 0); + setWidgetPosition(0, 0, 1, 2); + setWidgetTextAlignment(1, 1, 0); + setWidgetFont(494); + setWidgetRGB(new Color(255, 152, 31)); + if (((boolean)ivar3)) { + setWidgetText(intToStr(add(globalint_656, 1)) + " / " + intToStr(globalint_657)); + } else { + setWidgetText(intToStr(globalint_656) + " / " + intToStr(subtract(globalint_657, 1))); + } + } + if (globalint_656 > 0) { + createExtraChild(new WidgetPointer(arg2), 4, getExtraChildGap(new WidgetPointer(arg2))); + setWidgetSize(2, 17, 1, 1); + setWidgetPosition(0, 1, 1, 0); + setWidgetTextAlignment(0, 0, 0); + setWidgetFont(495); + setWidgetRGB(new Color(255, 152, 31)); + switch (globalint_656) { + case 1: + setWidgetText(globalstring_73); + break; + case 2: + setWidgetText(globalstring_74); + break; + case 3: + setWidgetText(globalstring_75); + break; + case 4: + setWidgetText(globalstring_76); + break; + case 5: + setWidgetText(globalstring_77); + break; + case 6: + setWidgetText(globalstring_78); + break; + case 7: + setWidgetText(globalstring_79); + break; + case 8: + setWidgetText(globalstring_80); + break; + case 9: + setWidgetText(globalstring_81); + break; + case 10: + setWidgetText(globalstring_82); + break; + case 11: + setWidgetText(globalstring_83); + break; + case 12: + setWidgetText(globalstring_84); + break; + case 13: + setWidgetText(globalstring_85); + break; + case 14: + setWidgetText(globalstring_86); + break; + case 15: + setWidgetText(globalstring_87); + break; + case 16: + setWidgetText(globalstring_88); + break; + case 17: + setWidgetText(globalstring_89); + break; + case 18: + setWidgetText(globalstring_90); + break; + case 19: + setWidgetText(globalstring_91); + break; + case 20: + setWidgetText(globalstring_92); + break; + case 21: + setWidgetText(globalstring_93); + break; + case 22: + setWidgetText(globalstring_94); + break; + case 23: + setWidgetText(globalstring_95); + break; + case 24: + setWidgetText(globalstring_96); + break; + case 25: + setWidgetText(globalstring_97); + break; + case 26: + setWidgetText(globalstring_98); + break; + case 27: + setWidgetText(globalstring_99); + break; + case 28: + setWidgetText(globalstring_100); + break; + case 29: + setWidgetText(globalstring_101); + break; + case 30: + setWidgetText(globalstring_102); + break; + case 31: + setWidgetText(globalstring_103); + break; + case 32: + setWidgetText(globalstring_104); + break; + case 33: + setWidgetText(globalstring_105); + break; + case 34: + setWidgetText(globalstring_106); + break; + case 35: + setWidgetText(globalstring_107); + break; + case 36: + setWidgetText(globalstring_108); + break; + case 37: + setWidgetText(globalstring_109); + break; + case 38: + setWidgetText(globalstring_110); + break; + case 39: + setWidgetText(globalstring_111); + break; + case 40: + setWidgetText(globalstring_112); + break; + case 41: + setWidgetText(globalstring_113); + break; + case 42: + setWidgetText(globalstring_114); + break; + case 43: + setWidgetText(globalstring_115); + break; + case 44: + setWidgetText(globalstring_116); + break; + case 45: + setWidgetText(globalstring_117); + break; + case 46: + setWidgetText(globalstring_118); + break; + case 47: + setWidgetText(globalstring_119); + break; + case 48: + setWidgetText(globalstring_120); + break; + case 49: + setWidgetText(globalstring_121); + } + return; + } + ivar4 = 0; + svar0 = ""; + ivar5 = 0; + while (ivar4 < 16) { + switch (ivar4) { + case 0: + svar0 = globalstring_57; + ivar5 = globalint_658; + break; + case 1: + svar0 = globalstring_58; + ivar5 = globalint_659; + break; + case 2: + svar0 = globalstring_59; + ivar5 = globalint_660; + break; + case 3: + svar0 = globalstring_60; + ivar5 = globalint_661; + break; + case 4: + svar0 = globalstring_61; + ivar5 = globalint_662; + break; + case 5: + svar0 = globalstring_62; + ivar5 = globalint_663; + break; + case 6: + svar0 = globalstring_63; + ivar5 = globalint_664; + break; + case 7: + svar0 = globalstring_64; + ivar5 = globalint_665; + break; + case 8: + svar0 = globalstring_65; + ivar5 = globalint_666; + break; + case 9: + svar0 = globalstring_66; + ivar5 = globalint_667; + break; + case 10: + svar0 = globalstring_67; + ivar5 = globalint_668; + break; + case 11: + svar0 = globalstring_68; + ivar5 = globalint_669; + break; + case 12: + svar0 = globalstring_69; + ivar5 = globalint_670; + break; + case 13: + svar0 = globalstring_70; + ivar5 = globalint_671; + break; + case 14: + svar0 = globalstring_71; + ivar5 = globalint_672; + break; + case 15: + svar0 = globalstring_72; + ivar5 = globalint_673; + break; + default: + svar0 = ""; + ivar5 = 0; + } + if (strLength(svar0) > 0) { + createExtraChild(new WidgetPointer(arg2), 4, getExtraChildGap(new WidgetPointer(arg2))); + if (ivar4 == subtract(16, 1)) { + setWidgetSize(6, 17, 1, 0); + } else { + setWidgetSize(2, 12, 1, 0); + } + setWidgetPosition(0, add(multiply(ivar4, 12), 1), 1, 0); + setWidgetTextAlignment(0, 0, 0); + setWidgetFont(495); + setWidgetRGB(new Color(255, 152, 31)); + setWidgetText(svar0); + if (ivar5 > 0) { + setWidgetContextMenuOption(1, "Go"); + setScriptCallOnClickContextMenu(2065, -2147483644, ivar5, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), "iiIII"); + setScriptCallOnMouseEntered(1356, new WidgetPointer(-32768,3), -2147483643, 16777215, "Iii"); + setScriptCallOnMouseExit(1356, new WidgetPointer(-32768,3), -2147483643, 16750623, "Iii"); + } + } + ivar4 = add(ivar4, 1); + } + return; +} diff --git a/dumps/scripts/144.cs2 b/dumps/scripts/144.cs2 new file mode 100644 index 0000000..e4e02bd --- /dev/null +++ b/dumps/scripts/144.cs2 @@ -0,0 +1,19 @@ +void script_144(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + ivar4 = 0; + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + if (getClientCycle() >= arg3) { + deleteExtraChild(); + return; + } + if (mod(getClientCycle(), 40) < 20) { + ivar4 = subtract(getClientCycle(), arg2); + ivar4 = multiply(ivar4, 255); + ivar4 = divide(ivar4, subtract(arg3, arg2)); + cs2method2103(ivar4); + } else { + cs2method2103(255); + } + } + return; +} diff --git a/dumps/scripts/1440.cs2 b/dumps/scripts/1440.cs2 new file mode 100644 index 0000000..79ac6dd --- /dev/null +++ b/dumps/scripts/1440.cs2 @@ -0,0 +1,25 @@ +void script_1440(int arg0) { + switch (arg0) { + case 40173583: + setItemOnWidgetMethod2205(standart_config_1068, 1, new WidgetPointer(613,15)); + break; + case 40173584: + setItemOnWidgetMethod2205(standart_config_1069, 1, new WidgetPointer(613,16)); + break; + case 40173585: + setItemOnWidgetMethod2205(standart_config_1070, 1, new WidgetPointer(613,17)); + break; + case 40173577: + setItemOnWidgetMethod2205(standart_config_1065, 1, new WidgetPointer(613,9)); + break; + case 40173578: + setItemOnWidgetMethod2205(standart_config_1066, 1, new WidgetPointer(613,10)); + break; + case 40173579: + setItemOnWidgetMethod2205(standart_config_1067, 1, new WidgetPointer(613,11)); + break; + case 40173580: + setItemOnWidgetMethod2205(standart_config_856, 1, new WidgetPointer(613,12)); + } + return; +} diff --git a/dumps/scripts/1441.cs2 b/dumps/scripts/1441.cs2 new file mode 100644 index 0000000..814bca1 --- /dev/null +++ b/dumps/scripts/1441.cs2 @@ -0,0 +1,19 @@ +void script_1441() { + setWidgetIsHidden(true, new WidgetPointer(299,32)); + setWidgetIsHidden(true, new WidgetPointer(299,33)); + setWidgetIsHidden(true, new WidgetPointer(299,34)); + setWidgetIsHidden(true, new WidgetPointer(299,35)); + setWidgetIsHidden(true, new WidgetPointer(299,36)); + setWidgetIsHidden(true, new WidgetPointer(299,40)); + setWidgetIsHidden(true, new WidgetPointer(299,41)); + setWidgetIsHidden(true, new WidgetPointer(299,42)); + setWidgetIsHidden(true, new WidgetPointer(299,43)); + setWidgetIsHidden(true, new WidgetPointer(299,44)); + setWidgetIsHidden(true, new WidgetPointer(299,45)); + setWidgetIsHidden(true, new WidgetPointer(299,46)); + setWidgetIsHidden(true, new WidgetPointer(299,55)); + setWidgetIsHidden(true, new WidgetPointer(299,47)); + setWidgetIsHidden(true, new WidgetPointer(299,32)); + setWidgetIsHidden(true, new WidgetPointer(299,33)); + return; +} diff --git a/dumps/scripts/1442.cs2 b/dumps/scripts/1442.cs2 new file mode 100644 index 0000000..aaed070 --- /dev/null +++ b/dumps/scripts/1442.cs2 @@ -0,0 +1,66 @@ +void script_1442() { + switch (standart_config_75) { + case 0: + return; + case 1: + setWidgetIsHidden(false, new WidgetPointer(299,55)); + setWidgetAnimation(632, new WidgetPointer(299,54)); + break; + case 2: + setWidgetIsHidden(false, new WidgetPointer(299,47)); + setWidgetAnimation(633, new WidgetPointer(299,53)); + break; + case 3: + setWidgetIsHidden(false, new WidgetPointer(299,45)); + setWidgetAnimation(630, new WidgetPointer(299,56)); + break; + case 5: + setWidgetIsHidden(false, new WidgetPointer(299,44)); + setWidgetAnimation(634, new WidgetPointer(299,58)); + break; + case 6: + setWidgetIsHidden(false, new WidgetPointer(299,43)); + setWidgetAnimation(635, new WidgetPointer(299,59)); + break; + case 7: + setWidgetIsHidden(false, new WidgetPointer(299,42)); + setWidgetAnimation(636, new WidgetPointer(299,60)); + break; + case 8: + setWidgetIsHidden(false, new WidgetPointer(299,41)); + setWidgetAnimation(637, new WidgetPointer(299,61)); + break; + case 10: + setWidgetIsHidden(false, new WidgetPointer(299,39)); + setWidgetAnimation(638, new WidgetPointer(299,63)); + break; + case 11: + setWidgetIsHidden(false, new WidgetPointer(299,38)); + setWidgetAnimation(639, new WidgetPointer(299,64)); + break; + case 12: + setWidgetIsHidden(false, new WidgetPointer(299,37)); + setWidgetAnimation(640, new WidgetPointer(299,65)); + break; + case 13: + setWidgetIsHidden(false, new WidgetPointer(299,36)); + setWidgetAnimation(641, new WidgetPointer(299,66)); + break; + case 14: + setWidgetIsHidden(false, new WidgetPointer(299,35)); + setWidgetAnimation(3545, new WidgetPointer(299,67)); + break; + case 15: + setWidgetIsHidden(false, new WidgetPointer(299,34)); + setWidgetAnimation(3546, new WidgetPointer(299,68)); + break; + case 16: + setWidgetIsHidden(false, new WidgetPointer(299,33)); + setWidgetAnimation(3476, new WidgetPointer(299,69)); + break; + case 17: + setWidgetIsHidden(false, new WidgetPointer(299,32)); + setWidgetAnimation(3477, new WidgetPointer(299,52)); + } + return; +} diff --git a/dumps/scripts/1443.cs2 b/dumps/scripts/1443.cs2 new file mode 100644 index 0000000..6c07a5c --- /dev/null +++ b/dumps/scripts/1443.cs2 @@ -0,0 +1,50 @@ +void script_1443() { + setWidgetText(new WidgetPointer(4,8), intToStr(bitconfig_455)); + if (((boolean)bitconfig_455)) { + setWidgetModel(-1, new WidgetPointer(4,4)); + } else if (((boolean)bitconfig_455)) { + setWidgetModel(6545, new WidgetPointer(4,4)); + } else if (bitconfig_455 < 4) { + setWidgetModel(6547, new WidgetPointer(4,4)); + } else if (bitconfig_455 < 7) { + setWidgetModel(6548, new WidgetPointer(4,4)); + } else if (bitconfig_455 < 11) { + setWidgetModel(6549, new WidgetPointer(4,4)); + } else if (bitconfig_455 < 16) { + setWidgetModel(6550, new WidgetPointer(4,4)); + } else if (bitconfig_455 < 22) { + setWidgetModel(6551, new WidgetPointer(4,4)); + } else if (bitconfig_455 < 29) { + setWidgetModel(6552, new WidgetPointer(4,4)); + } else if (bitconfig_455 < 37) { + setWidgetModel(6553, new WidgetPointer(4,4)); + } else if (bitconfig_455 < 46) { + setWidgetModel(6554, new WidgetPointer(4,4)); + } else { + setWidgetModel(6546, new WidgetPointer(4,4)); + } + if (((boolean)bitconfig_454)) { + setWidgetModel(-1, new WidgetPointer(4,2)); + } else if (((boolean)bitconfig_454)) { + setWidgetModel(6557, new WidgetPointer(4,2)); + } else if (bitconfig_454 == 2) { + setWidgetModel(6559, new WidgetPointer(4,2)); + } else if (bitconfig_454 == 3) { + setWidgetModel(6560, new WidgetPointer(4,2)); + } else if (bitconfig_454 == 4) { + setWidgetModel(6561, new WidgetPointer(4,2)); + } else if (bitconfig_454 == 5) { + setWidgetModel(6562, new WidgetPointer(4,2)); + } else if (bitconfig_454 == 6) { + setWidgetModel(6563, new WidgetPointer(4,2)); + } else if (bitconfig_454 == 7) { + setWidgetModel(6564, new WidgetPointer(4,2)); + } else if (bitconfig_454 == 8) { + setWidgetModel(6565, new WidgetPointer(4,2)); + } else if (bitconfig_454 == 9) { + setWidgetModel(6566, new WidgetPointer(4,2)); + } else { + setWidgetModel(6558, new WidgetPointer(4,2)); + } + return; +} diff --git a/dumps/scripts/1444.cs2 b/dumps/scripts/1444.cs2 new file mode 100644 index 0000000..82b5004 --- /dev/null +++ b/dumps/scripts/1444.cs2 @@ -0,0 +1,9 @@ +void script_1444() { + script_1447(0); + script_1665(50266153, 50266154, 50266155, 50266156); + script_2957(50266164); + setScriptCallOnGlobalConfigChange(1445, new WidgetPointer(767,41), new WidgetPointer(767,42), new WidgetPointer(767,43), new WidgetPointer(767,44), 192, 1038, 1324, 3, "IIIIY", new WidgetPointer(767,13)); + setScriptCallOnConfigChange(1655, 638, 1, "Y", new WidgetPointer(767,13)); + script_1656(); + return; +} diff --git a/dumps/scripts/1445.cs2 b/dumps/scripts/1445.cs2 new file mode 100644 index 0000000..fb26484 --- /dev/null +++ b/dumps/scripts/1445.cs2 @@ -0,0 +1,4 @@ +void script_1445(int arg0,int arg1,int arg2,int arg3) { + script_1665(arg0, arg1, arg2, arg3); + return; +} diff --git a/dumps/scripts/1446.cs2 b/dumps/scripts/1446.cs2 new file mode 100644 index 0000000..17c89b5 --- /dev/null +++ b/dumps/scripts/1446.cs2 @@ -0,0 +1,4 @@ +void script_1446(int arg0) { + script_1447(arg0); + return; +} diff --git a/dumps/scripts/1447.cs2 b/dumps/scripts/1447.cs2 new file mode 100644 index 0000000..98fa264 --- /dev/null +++ b/dumps/scripts/1447.cs2 @@ -0,0 +1,31 @@ +void script_1447(int arg0) { + int ivar1; + int ivar2; + ivar1 = 0; + ivar2 = ((int)cs2method_3408(105, 73, 1617, ivar1)); + while (ivar2 != -1) { + if (ivar1 == arg0) { + setWidgetIsHidden(false, new WidgetPointer(ivar2)); + } else { + setWidgetIsHidden(true, new WidgetPointer(ivar2)); + } + ivar1 = add(ivar1, 1); + ivar2 = ((int)cs2method_3408(105, 73, 1617, ivar1)); + } + if (arg0 > 0) { + setScriptCallOnClickContextMenu(1446, subtract(arg0, 1), "i", new WidgetPointer(767,64)); + cs2method2103(0, new WidgetPointer(767,64)); + } else { + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(767,64)); + cs2method2103(200, new WidgetPointer(767,64)); + } + if (arg0 < subtract(ivar1, 1)) { + setScriptCallOnClickContextMenu(1446, add(arg0, 1), "i", new WidgetPointer(767,63)); + cs2method2103(0, new WidgetPointer(767,63)); + } else { + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(767,63)); + cs2method2103(200, new WidgetPointer(767,63)); + } + setWidgetText(new WidgetPointer(767,62), "Page " + intToStr(add(arg0, 1)) + " of " + intToStr(ivar1)); + return; +} diff --git a/dumps/scripts/1448.cs2 b/dumps/scripts/1448.cs2 new file mode 100644 index 0000000..9082226 --- /dev/null +++ b/dumps/scripts/1448.cs2 @@ -0,0 +1,4 @@ +void script_1448(int arg0) { + script_1540(arg0); + return; +} diff --git a/dumps/scripts/1449.cs2 b/dumps/scripts/1449.cs2 new file mode 100644 index 0000000..200be2d --- /dev/null +++ b/dumps/scripts/1449.cs2 @@ -0,0 +1,15 @@ +void script_1449() { + globalint_188 = 0; + script_1487(); + script_1490(); + script_1450(); + script_1464(); + script_1455(); + script_1459(); + script_1463(bitconfig_4893); + setScriptCallOnGlobalConfigChange(1472, 190, 1, "Y", new WidgetPointer(762,17)); + setScriptCallOnGlobalConfigChange(1465, 192, 1038, 1324, 3, "Y", new WidgetPointer(762,21)); + cs2method2100(0, script_704(bitconfig_4893), new WidgetPointer(762,93)); + script_157(49938546, 49938525, cs2method2601(new WidgetPointer(762,93)), 1); + return; +} diff --git a/dumps/scripts/145.cs2 b/dumps/scripts/145.cs2 new file mode 100644 index 0000000..eac3b29 --- /dev/null +++ b/dumps/scripts/145.cs2 @@ -0,0 +1,7 @@ +void script_145(int arg0,int arg1) { + if (getClientCycle() >= arg1) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/1450.cs2 b/dumps/scripts/1450.cs2 new file mode 100644 index 0000000..77b4834 --- /dev/null +++ b/dumps/scripts/1450.cs2 @@ -0,0 +1,21 @@ +void script_1450() { + int ivar0; + int ivar1; + ivar0 = 0; + ivar1 = getItemContainerLength(95); + while (ivar0 < ivar1) { + createExtraChild(new WidgetPointer(762,93), 5, ivar0); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(0, 0, 0, 0); + setWidgetHidden(1); + if (getItemIdInSlot(95, ivar0) != -1) { + script_1453(ivar0); + } + setWidgetBorderThickness(1); + setWidgetShadowColor(new Color(51, 51, 51)); + setScriptCallOnMouseOver(1480, new WidgetPointer(762,93), ivar0, "Ii"); + setScriptCallOnMouseExit(40, new WidgetPointer(762,97), "I"); + ivar0 = add(ivar0, 1); + } + return; +} diff --git a/dumps/scripts/1451.cs2 b/dumps/scripts/1451.cs2 new file mode 100644 index 0000000..4d0f717 --- /dev/null +++ b/dumps/scripts/1451.cs2 @@ -0,0 +1,4 @@ +void script_1451() { + script_1654(); + return; +} diff --git a/dumps/scripts/1452.cs2 b/dumps/scripts/1452.cs2 new file mode 100644 index 0000000..5efc972 --- /dev/null +++ b/dumps/scripts/1452.cs2 @@ -0,0 +1,4 @@ +void script_1452(int arg0) { + script_1664(arg0); + return; +} diff --git a/dumps/scripts/1453.cs2 b/dumps/scripts/1453.cs2 new file mode 100644 index 0000000..91bf8e6 --- /dev/null +++ b/dumps/scripts/1453.cs2 @@ -0,0 +1,20 @@ +void script_1453(int arg0) { + int ivar1; + ivar1 = getItemIdInSlot(95, arg0); + setItemOnWidgetMethod1200(ivar1, getItemAmtInSlot(95, arg0)); + cs2method1305("" + getItemName(getItemIdInSlot(95, arg0))); + setWidgetContextMenuOption(1, "Withdraw-1"); + setWidgetContextMenuOption(2, "Withdraw-5"); + setWidgetContextMenuOption(3, "Withdraw-10"); + setWidgetContextMenuOption(4, "Withdraw-" + intToStr(standart_config_1249)); + setWidgetContextMenuOption(5, "Withdraw-X"); + setWidgetContextMenuOption(6, "Withdraw-All"); + setWidgetContextMenuOption(7, "Withdraw-All but one"); + setWidgetContextMenuOption(10, "Examine" + ""); + cs2method1301(49938432, -1); + cs2method1303(5); + cs2method1304(5); + setScriptCallOnMouseDragged(1454, -2147483646, "i"); + setScriptCallOnMouseDragReleased(1482, new WidgetPointer(-32768,6), "I"); + return; +} diff --git a/dumps/scripts/1454.cs2 b/dumps/scripts/1454.cs2 new file mode 100644 index 0000000..d3becbd --- /dev/null +++ b/dumps/scripts/1454.cs2 @@ -0,0 +1,22 @@ +void script_1454(int arg0) { + int ivar1; + int ivar2; + int ivar3; + ivar1 = 0; + ivar2 = subtract(getWidgetActualY(new WidgetPointer(762,93)), 25); + ivar3 = subtract(add(getWidgetActualY(new WidgetPointer(762,93)), getWidgetActualHeight(new WidgetPointer(762,93))), 16); + if ((arg0 > ivar2) && (arg0 < add(ivar2, 25))) { + ivar1 = -4; + } else if ((arg0 < ivar3) && (arg0 > subtract(ivar3, 30))) { + ivar1 = 4; + } else { + globalint_189 = 0; + return; + } + globalint_189 = add(globalint_189, 1); + if (globalint_189 > 5) { + script_705(bitconfig_4893, add(cs2method2601(new WidgetPointer(762,93)), ivar1)); + script_157(49938546, 49938525, add(cs2method2601(new WidgetPointer(762,93)), ivar1), 1); + } + return; +} diff --git a/dumps/scripts/1455.cs2 b/dumps/scripts/1455.cs2 new file mode 100644 index 0000000..d712da5 --- /dev/null +++ b/dumps/scripts/1455.cs2 @@ -0,0 +1,12 @@ +void script_1455() { + int ivar0; + ivar0 = 0; + while (ivar0 < getItemContainerLength(95)) { + if (setWidgetRegister(new WidgetPointer(762,93), ivar0)) { + setWidgetHidden(1); + setWidgetPosition(0, 0, 0, 0); + } + ivar0 = add(ivar0, 1); + } + return; +} diff --git a/dumps/scripts/1456.cs2 b/dumps/scripts/1456.cs2 new file mode 100644 index 0000000..07503c9 --- /dev/null +++ b/dumps/scripts/1456.cs2 @@ -0,0 +1,79 @@ +void script_1456() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int stack_dump0; + cs2func_script_1467_struct(2,0,0) structdump_1; + cs2func_script_1467_struct(2,0,0) structdump_2; + ivar0 = 0; + ivar1 = 0; + ivar2 = 0; + ivar3 = 8; + ivar4 = 5; + ivar5 = 0; + ivar6 = getItemContainerLength(95); + script_1464(); + stack_dump0 = ivar5; + structdump_1 = script_1467(stack_dump0); + ivar2 = structdump_1.intpart_1; + ivar1 = structdump_1.intpart_0; + while (ivar5 <= 9) { + ivar0 = ivar1; + if (ivar5 != 0) { + setWidgetIsHidden(false, cs2method_3408(105, 73, 1611, ivar5)); + setWidgetPosition(subtract(ivar3, 2), subtract(ivar4, 2), 0, 0, cs2method_3408(105, 73, 1611, ivar5)); + } + while (ivar0 < ivar2) { + if (setWidgetRegister(new WidgetPointer(762,93), ivar0)) { + if (getItemAmtInSlot(95, ivar0) != 0) { + setWidgetPosition(ivar3, ivar4, 0, 0); + setWidgetHidden(0); + ivar3 = add(ivar3, 44); + if (ivar3 >= multiply(44, 10)) { + ivar3 = 8; + ivar4 = add(ivar4, 44); + } + } else { + ivar0 = 1000; + } + } + ivar0 = add(ivar0, 1); + } + if (ivar3 != 8) { + setWidgetPosition(ivar3, ivar4, 0, 0, cs2method_3408(105, 73, 1612, ivar5)); + setWidgetSize(subtract(multiply(44, 10), ivar3), 32, 0, 0, cs2method_3408(105, 73, 1612, ivar5)); + setWidgetIsHidden(false, cs2method_3408(105, 73, 1612, ivar5)); + ivar4 = add(ivar4, 44); + } + if (((boolean)ivar5)) { + ivar5 = 2; + } else { + ivar5 = add(ivar5, 1); + } + stack_dump0 = ivar5; + structdump_2 = script_1467(stack_dump0); + ivar2 = structdump_2.intpart_1; + ivar1 = structdump_2.intpart_0; + if (ivar1 == ivar2) { + ivar5 = 100; + } + if (((int)cs2method_3408(105, 73, 1610, ivar5)) != -1) { + setWidgetIsHidden(false, cs2method_3408(105, 73, 1610, ivar5)); + setWidgetPosition(0, ivar4, 0, 0, cs2method_3408(105, 73, 1610, ivar5)); + ivar4 = add(ivar4, 15); + ivar3 = 0; + } + } + setWidgetScrollMax(getWidgetActualWidth(new WidgetPointer(762,93)), ivar4, new WidgetPointer(762,93)); + cs2method2100(0, globalint_203, new WidgetPointer(762,93)); + deleteAllExtraChilds(new WidgetPointer(762,114)); + if (ivar4 > getWidgetActualHeight(new WidgetPointer(762,93))) { + script_31(49938546, 49938525, 792, 789, 790, 791, 773, 788); + script_157(49938546, 49938525, cs2method2601(new WidgetPointer(762,93)), 1); + } + return; +} diff --git a/dumps/scripts/1457.cs2 b/dumps/scripts/1457.cs2 new file mode 100644 index 0000000..d882a82 --- /dev/null +++ b/dumps/scripts/1457.cs2 @@ -0,0 +1,19 @@ +void script_1457(int arg0,int arg1) { + int ivar2; + int ivar3; + ivar2 = 0; + ivar3 = arg0; + while (ivar3 < arg1) { + if (setWidgetRegister(new WidgetPointer(762,93), ivar3)) { + setWidgetPosition(add(multiply(44, mod(ivar2, 10)), 8), add(multiply(divide(ivar2, 10), 44), 5), 0, 0); + setWidgetHidden(0); + ivar2 = add(ivar2, 1); + } + ivar3 = add(ivar3, 1); + } + script_1464(); + setWidgetIsHidden(false, new WidgetPointer(762,84)); + setWidgetPosition(subtract(8, 2), subtract(5, 2), 0, 0, new WidgetPointer(762,84)); + script_1458(ivar2); + return; +} diff --git a/dumps/scripts/1458.cs2 b/dumps/scripts/1458.cs2 new file mode 100644 index 0000000..b01b1f2 --- /dev/null +++ b/dumps/scripts/1458.cs2 @@ -0,0 +1,14 @@ +void script_1458(int arg0) { + int ivar1; + ivar1 = multiply(divide(arg0, 10), 44); + if (mod(arg0, 10) != 0) { + ivar1 = add(ivar1, 44); + } + setWidgetScrollMax(getWidgetActualWidth(new WidgetPointer(762,93)), ivar1, new WidgetPointer(762,93)); + deleteAllExtraChilds(new WidgetPointer(762,114)); + if (ivar1 > getWidgetActualHeight(new WidgetPointer(762,93))) { + script_31(49938546, 49938525, 792, 789, 790, 791, 773, 788); + } + script_157(49938546, 49938525, cs2method2601(new WidgetPointer(762,93)), 1); + return; +} diff --git a/dumps/scripts/1459.cs2 b/dumps/scripts/1459.cs2 new file mode 100644 index 0000000..ee8494f --- /dev/null +++ b/dumps/scripts/1459.cs2 @@ -0,0 +1,46 @@ +void script_1459() { + int ivar0; + int ivar1; + int ivar2; + ivar0 = 2; + ivar1 = 0; + ivar2 = 0; + while (ivar0 <= 9) { + switch (ivar0) { + case 2: + ivar1 = bitconfig_4885; + break; + case 3: + ivar1 = bitconfig_4886; + break; + case 4: + ivar1 = bitconfig_4887; + break; + case 5: + ivar1 = bitconfig_4888; + break; + case 6: + ivar1 = bitconfig_4889; + break; + case 7: + ivar1 = bitconfig_4890; + break; + case 8: + ivar1 = bitconfig_4891; + break; + case 9: + ivar1 = bitconfig_4892; + } + if (ivar1 > 0) { + script_1460(ivar0, script_1470(ivar0)); + } else if (((boolean)ivar2)) { + script_1461(ivar0); + ivar2 = 1; + } else { + script_1462(ivar0); + } + ivar0 = add(ivar0, 1); + } + script_1463(bitconfig_4893); + return; +} diff --git a/dumps/scripts/146.cs2 b/dumps/scripts/146.cs2 new file mode 100644 index 0000000..8c4b570 --- /dev/null +++ b/dumps/scripts/146.cs2 @@ -0,0 +1,4 @@ +void script_146(int arg0) { + script_147(arg0, getClientCycle()); + return; +} diff --git a/dumps/scripts/1460.cs2 b/dumps/scripts/1460.cs2 new file mode 100644 index 0000000..d40673d --- /dev/null +++ b/dumps/scripts/1460.cs2 @@ -0,0 +1,20 @@ +void script_1460(int arg0,int arg1) { + int ivar2; + int ivar3; + string svar0; + ivar2 = ((int)cs2method_3408(105, 73, 1614, arg0)); + ivar3 = ((int)cs2method_3408(105, 73, 1615, arg0)); + setWidgetIsHidden(false, new WidgetPointer(ivar2)); + setWidgetIsHidden(false, new WidgetPointer(ivar3)); + setItemOnWidgetMethod2205(getItemIdInSlot(95, arg1), getItemAmtInSlot(95, arg1), new WidgetPointer(ivar3)); + setWidgetBorderThickness(1, new WidgetPointer(ivar3)); + setWidgetShadowColor(new Color(51, 51, 51), new WidgetPointer(ivar3)); + setWidgetNoOptions(new WidgetPointer(ivar2)); + setWidgetContextMenuOption(1, new WidgetPointer(ivar2), "View tab " + intToStr(arg0)); + setWidgetContextMenuOption(2, new WidgetPointer(ivar2), "Collapse tab " + intToStr(arg0)); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(ivar2)); + svar0 = "Click here to select tab " + intToStr(arg0); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(762,119), svar0, 25, 150, "IIsii", new WidgetPointer(ivar2)); + setScriptCallOnMouseExit(40, new WidgetPointer(762,119), "I", new WidgetPointer(ivar2)); + return; +} diff --git a/dumps/scripts/1461.cs2 b/dumps/scripts/1461.cs2 new file mode 100644 index 0000000..8191739 --- /dev/null +++ b/dumps/scripts/1461.cs2 @@ -0,0 +1,19 @@ +void script_1461(int arg0) { + int ivar1; + int ivar2; + string svar0; + ivar1 = ((int)cs2method_3408(105, 73, 1614, arg0)); + ivar2 = ((int)cs2method_3408(105, 73, 1615, arg0)); + setWidgetIsHidden(false, new WidgetPointer(ivar1)); + setWidgetIsHidden(false, new WidgetPointer(ivar2)); + setItemOnWidgetMethod2200(-1, -1, new WidgetPointer(ivar2)); + setWidgetSprite(1435, new WidgetPointer(ivar2)); + setWidgetBorderThickness(0, new WidgetPointer(ivar2)); + setWidgetShadowColor(new Color(0, 0, 0), new WidgetPointer(ivar2)); + setWidgetNoOptions(new WidgetPointer(ivar1)); + setScriptCallOnMousePressed(1481, "", new WidgetPointer(ivar1)); + svar0 = "Drag an item here to create a new tab"; + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(762,119), svar0, 25, 150, "IIsii", new WidgetPointer(ivar1)); + setScriptCallOnMouseExit(40, new WidgetPointer(762,119), "I", new WidgetPointer(ivar1)); + return; +} diff --git a/dumps/scripts/1462.cs2 b/dumps/scripts/1462.cs2 new file mode 100644 index 0000000..b168d3b --- /dev/null +++ b/dumps/scripts/1462.cs2 @@ -0,0 +1,5 @@ +void script_1462(int arg0) { + setWidgetIsHidden(true, cs2method_3408(105, 73, 1614, arg0)); + setWidgetIsHidden(true, cs2method_3408(105, 73, 1615, arg0)); + return; +} diff --git a/dumps/scripts/1463.cs2 b/dumps/scripts/1463.cs2 new file mode 100644 index 0000000..62e15af --- /dev/null +++ b/dumps/scripts/1463.cs2 @@ -0,0 +1,40 @@ +void script_1463(int arg0) { + setWidgetSprite(1421, new WidgetPointer(762,62)); + setWidgetSprite(1421, new WidgetPointer(762,60)); + setWidgetSprite(1421, new WidgetPointer(762,58)); + setWidgetSprite(1421, new WidgetPointer(762,56)); + setWidgetSprite(1421, new WidgetPointer(762,54)); + setWidgetSprite(1421, new WidgetPointer(762,52)); + setWidgetSprite(1421, new WidgetPointer(762,50)); + setWidgetSprite(1421, new WidgetPointer(762,48)); + setWidgetSprite(1421, new WidgetPointer(762,46)); + switch (arg0) { + case 1: + setWidgetSprite(1419, new WidgetPointer(762,62)); + break; + case 2: + setWidgetSprite(1419, new WidgetPointer(762,60)); + break; + case 3: + setWidgetSprite(1419, new WidgetPointer(762,58)); + break; + case 4: + setWidgetSprite(1419, new WidgetPointer(762,56)); + break; + case 5: + setWidgetSprite(1419, new WidgetPointer(762,54)); + break; + case 6: + setWidgetSprite(1419, new WidgetPointer(762,52)); + break; + case 7: + setWidgetSprite(1419, new WidgetPointer(762,50)); + break; + case 8: + setWidgetSprite(1419, new WidgetPointer(762,48)); + break; + case 9: + setWidgetSprite(1419, new WidgetPointer(762,46)); + } + return; +} diff --git a/dumps/scripts/1464.cs2 b/dumps/scripts/1464.cs2 new file mode 100644 index 0000000..586f3c6 --- /dev/null +++ b/dumps/scripts/1464.cs2 @@ -0,0 +1,31 @@ +void script_1464() { + setWidgetIsHidden(true, new WidgetPointer(762,64)); + setWidgetIsHidden(true, new WidgetPointer(762,65)); + setWidgetIsHidden(true, new WidgetPointer(762,66)); + setWidgetIsHidden(true, new WidgetPointer(762,67)); + setWidgetIsHidden(true, new WidgetPointer(762,68)); + setWidgetIsHidden(true, new WidgetPointer(762,69)); + setWidgetIsHidden(true, new WidgetPointer(762,70)); + setWidgetIsHidden(true, new WidgetPointer(762,71)); + setWidgetIsHidden(true, new WidgetPointer(762,72)); + setWidgetIsHidden(true, new WidgetPointer(762,73)); + setWidgetIsHidden(true, new WidgetPointer(762,74)); + setWidgetIsHidden(true, new WidgetPointer(762,75)); + setWidgetIsHidden(true, new WidgetPointer(762,76)); + setWidgetIsHidden(true, new WidgetPointer(762,77)); + setWidgetIsHidden(true, new WidgetPointer(762,78)); + setWidgetIsHidden(true, new WidgetPointer(762,79)); + setWidgetIsHidden(true, new WidgetPointer(762,80)); + setWidgetIsHidden(true, new WidgetPointer(762,81)); + setWidgetIsHidden(true, new WidgetPointer(762,82)); + setWidgetIsHidden(true, new WidgetPointer(762,84)); + setWidgetIsHidden(true, new WidgetPointer(762,85)); + setWidgetIsHidden(true, new WidgetPointer(762,86)); + setWidgetIsHidden(true, new WidgetPointer(762,87)); + setWidgetIsHidden(true, new WidgetPointer(762,88)); + setWidgetIsHidden(true, new WidgetPointer(762,89)); + setWidgetIsHidden(true, new WidgetPointer(762,90)); + setWidgetIsHidden(true, new WidgetPointer(762,91)); + setWidgetIsHidden(true, new WidgetPointer(762,92)); + return; +} diff --git a/dumps/scripts/1465.cs2 b/dumps/scripts/1465.cs2 new file mode 100644 index 0000000..f17c011 --- /dev/null +++ b/dumps/scripts/1465.cs2 @@ -0,0 +1,57 @@ +void script_1465() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + string svar0; + string svar1; + string svar2; + svar0 = "Total number of " + "" + "free" + "" + " bank slots used"; + svar1 = "Total number of " + "" + "member" + "" + " bank slots used"; + svar2 = "Total number of " + "" + "demo" + "" + " bank slots used"; + ivar0 = 0; + ivar1 = 0; + if (((boolean)script_3287())) { + ivar0 = add(subtract(516, 439), 1); + ivar1 = subtract(516, ivar0); + } else { + ivar0 = subtract(add(subtract(516, 439), 1), 10); + ivar1 = subtract(subtract(516, 10), ivar0); + } + ivar2 = globalint_1038; + ivar3 = subtract(globalint_192, ivar2); + ivar4 = multiply(subtract(ivar0, ivar2), -1); + ivar5 = subtract(ivar3, subtract(439, 1)); + setWidgetIsHidden(false, new WidgetPointer(762,22)); + setWidgetIsHidden(true, new WidgetPointer(762,23)); + if (ivar5 > 0) { + ivar2 = add(ivar2, ivar5); + ivar3 = subtract(439, 1); + if (((boolean)ivar5)) { + svar0 = "Total number of " + "" + "free" + "" + " bank slots used" + "
" + "" + "Note: this includes an overflow of 1 member item" + ""; + } else { + svar0 = "Total number of " + "" + "free" + "" + " bank slots used" + "
" + "" + "Note: this includes an overflow of " + intToStr(ivar5) + " member items" + ""; + } + svar1 = "Total number of " + "" + "member" + "" + " bank slots used"; + } else { + if (ivar4 > 0) { + ivar3 = add(ivar3, ivar4); + ivar2 = ivar0; + svar0 = "Total number of " + "" + "free" + "" + " bank slots used"; + if (((boolean)ivar4)) { + svar1 = "Total number of " + "" + "member" + "" + " bank slots used" + "
" + "" + "Note: this includes an overflow of 1 free item" + ""; + } else { + svar1 = "Total number of " + "" + "member" + "" + " bank slots used" + "
" + "" + "Note: this includes an overflow of " + intToStr(ivar4) + " free items" + ""; + } + } + } + setWidgetText(new WidgetPointer(762,29), intToStr(ivar2)); + setWidgetText(new WidgetPointer(762,31), intToStr(ivar3)); + setScriptCallOnMouseOver(1160, new WidgetPointer(-32768,3), -1, new WidgetPointer(762,119), svar0, 25, 150, "IiIsii", new WidgetPointer(762,29)); + setScriptCallOnMouseOver(1160, new WidgetPointer(-32768,3), -1, new WidgetPointer(762,119), svar1, 25, 150, "IiIsii", new WidgetPointer(762,31)); + setWidgetText(new WidgetPointer(762,30), intToStr(ivar0)); + setWidgetText(new WidgetPointer(762,32), intToStr(ivar1)); + return; +} diff --git a/dumps/scripts/1466.cs2 b/dumps/scripts/1466.cs2 new file mode 100644 index 0000000..2fe754b --- /dev/null +++ b/dumps/scripts/1466.cs2 @@ -0,0 +1,12 @@ +int script_1466() { + if (isSiteSettingsMembers()) { + if (((boolean)script_3287())) { + return 516; + } + return subtract(516, 10); + } + if (((boolean)script_3287())) { + return add(subtract(516, 439), 1); + } + return subtract(add(subtract(516, 439), 1), 10); +} diff --git a/dumps/scripts/1467.cs2 b/dumps/scripts/1467.cs2 new file mode 100644 index 0000000..2df587e --- /dev/null +++ b/dumps/scripts/1467.cs2 @@ -0,0 +1,57 @@ +cs2func_script_1467_struct(2,0,0) script_1467(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int stack_dump0; + cs2func_script_1467_struct(2,0,0) structdump_1; + cs2func_script_1467_struct(2,0,0) structdump_2; + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + if (((boolean)arg0)) { + stack_dump0 = 9; + structdump_1 = script_1467(stack_dump0); + ivar2 = structdump_1.intpart_1; + ivar1 = structdump_1.intpart_0; + ivar1 = ivar2; + stack_dump0 = 1; + structdump_2 = script_1467(stack_dump0); + ivar2 = structdump_2.intpart_1; + ivar3 = structdump_2.intpart_0; + return newstruct cs2func_script_1467_struct(ivar1, ivar2); + } + if (((boolean)arg0)) { + return newstruct cs2func_script_1467_struct(0, 516); + } + ivar1 = 0; + ivar2 = bitconfig_4885; + if (arg0 >= 3) { + ivar1 = ivar2; + ivar2 = add(ivar1, bitconfig_4886); + } + if (arg0 >= 4) { + ivar1 = ivar2; + ivar2 = add(ivar1, bitconfig_4887); + } + if (arg0 >= 5) { + ivar1 = ivar2; + ivar2 = add(ivar1, bitconfig_4888); + } + if (arg0 >= 6) { + ivar1 = ivar2; + ivar2 = add(ivar1, bitconfig_4889); + } + if (arg0 >= 7) { + ivar1 = ivar2; + ivar2 = add(ivar1, bitconfig_4890); + } + if (arg0 >= 8) { + ivar1 = ivar2; + ivar2 = add(ivar1, bitconfig_4891); + } + if (arg0 >= 9) { + ivar1 = ivar2; + ivar2 = add(ivar1, bitconfig_4892); + } + return newstruct cs2func_script_1467_struct(ivar1, ivar2); +} diff --git a/dumps/scripts/1468.cs2 b/dumps/scripts/1468.cs2 new file mode 100644 index 0000000..ef3be34 --- /dev/null +++ b/dumps/scripts/1468.cs2 @@ -0,0 +1,28 @@ +int script_1468(int arg0) { + arg0 = add(arg0, 1); + if (arg0 <= bitconfig_4885) { + return 2; + } + if (arg0 <= add(bitconfig_4885, bitconfig_4886)) { + return 3; + } + if (arg0 <= add(add(bitconfig_4885, bitconfig_4886), bitconfig_4887)) { + return 4; + } + if (arg0 <= add(add(add(bitconfig_4885, bitconfig_4886), bitconfig_4887), bitconfig_4888)) { + return 5; + } + if (arg0 <= add(add(add(add(bitconfig_4885, bitconfig_4886), bitconfig_4887), bitconfig_4888), bitconfig_4889)) { + return 6; + } + if (arg0 <= add(add(add(add(add(bitconfig_4885, bitconfig_4886), bitconfig_4887), bitconfig_4888), bitconfig_4889), bitconfig_4890)) { + return 7; + } + if (arg0 <= add(add(add(add(add(add(bitconfig_4885, bitconfig_4886), bitconfig_4887), bitconfig_4888), bitconfig_4889), bitconfig_4890), bitconfig_4891)) { + return 8; + } + if (arg0 <= add(add(add(add(add(add(add(bitconfig_4885, bitconfig_4886), bitconfig_4887), bitconfig_4888), bitconfig_4889), bitconfig_4890), bitconfig_4891), bitconfig_4892)) { + return 9; + } + return 1; +} diff --git a/dumps/scripts/1469.cs2 b/dumps/scripts/1469.cs2 new file mode 100644 index 0000000..03ca91c --- /dev/null +++ b/dumps/scripts/1469.cs2 @@ -0,0 +1,27 @@ +int script_1469() { + if (((boolean)bitconfig_4885)) { + return 2; + } + if (((boolean)bitconfig_4886)) { + return 3; + } + if (((boolean)bitconfig_4887)) { + return 4; + } + if (((boolean)bitconfig_4888)) { + return 5; + } + if (((boolean)bitconfig_4889)) { + return 6; + } + if (((boolean)bitconfig_4890)) { + return 7; + } + if (((boolean)bitconfig_4891)) { + return 8; + } + if (((boolean)bitconfig_4892)) { + return 9; + } + return -1; +} diff --git a/dumps/scripts/147.cs2 b/dumps/scripts/147.cs2 new file mode 100644 index 0000000..11e54b5 --- /dev/null +++ b/dumps/scripts/147.cs2 @@ -0,0 +1,91 @@ +void script_147(int arg0,int arg1) { + switch (arg0) { + case 0: + globalint_12 = arg1; + break; + case 1: + globalint_13 = arg1; + break; + case 2: + globalint_14 = arg1; + break; + case 3: + globalint_15 = arg1; + break; + case 4: + globalint_16 = arg1; + break; + case 5: + globalint_17 = arg1; + break; + case 6: + globalint_18 = arg1; + break; + case 7: + globalint_19 = arg1; + break; + case 8: + globalint_20 = arg1; + break; + case 9: + globalint_21 = arg1; + break; + case 10: + globalint_22 = arg1; + break; + case 11: + globalint_23 = arg1; + break; + case 12: + globalint_24 = arg1; + break; + case 13: + globalint_25 = arg1; + break; + case 14: + globalint_26 = arg1; + break; + case 15: + globalint_27 = arg1; + break; + case 16: + globalint_28 = arg1; + break; + case 17: + globalint_29 = arg1; + break; + case 18: + globalint_30 = arg1; + break; + case 19: + globalint_31 = arg1; + break; + case 20: + globalint_32 = arg1; + break; + case 21: + globalint_33 = arg1; + break; + case 22: + globalint_34 = arg1; + break; + case 23: + globalint_35 = arg1; + break; + case 24: + globalint_36 = arg1; + break; + case 25: + globalint_37 = arg1; + break; + case 26: + globalint_38 = arg1; + break; + case 27: + globalint_39 = arg1; + break; + case -1: + globalint_212 = arg1; + } + return; +} diff --git a/dumps/scripts/1470.cs2 b/dumps/scripts/1470.cs2 new file mode 100644 index 0000000..6e30451 --- /dev/null +++ b/dumps/scripts/1470.cs2 @@ -0,0 +1,21 @@ +int script_1470(int arg0) { + switch (arg0) { + case 2: + return 0; + case 3: + return bitconfig_4885; + case 4: + return add(bitconfig_4885, bitconfig_4886); + case 5: + return add(add(bitconfig_4885, bitconfig_4886), bitconfig_4887); + case 6: + return add(add(add(bitconfig_4885, bitconfig_4886), bitconfig_4887), bitconfig_4888); + case 7: + return add(add(add(add(bitconfig_4885, bitconfig_4886), bitconfig_4887), bitconfig_4888), bitconfig_4889); + case 8: + return add(add(add(add(add(bitconfig_4885, bitconfig_4886), bitconfig_4887), bitconfig_4888), bitconfig_4889), bitconfig_4890); + case 9: + return add(add(add(add(add(add(bitconfig_4885, bitconfig_4886), bitconfig_4887), bitconfig_4888), bitconfig_4889), bitconfig_4890), bitconfig_4891); + } + return 0; +} diff --git a/dumps/scripts/1471.cs2 b/dumps/scripts/1471.cs2 new file mode 100644 index 0000000..9a15958 --- /dev/null +++ b/dumps/scripts/1471.cs2 @@ -0,0 +1,13 @@ +void script_1471() { + setWidgetNoOptions(new WidgetPointer(762,17)); + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(762,17)); + globalint_190 = 0; + if (((boolean)globalint_188)) { + bitconfig_4893 = 0; + script_1473(); + } else { + bitconfig_4893 = 1; + script_1474(); + } + return; +} diff --git a/dumps/scripts/1472.cs2 b/dumps/scripts/1472.cs2 new file mode 100644 index 0000000..ad93b82 --- /dev/null +++ b/dumps/scripts/1472.cs2 @@ -0,0 +1,7 @@ +void script_1472() { + if (((boolean)globalint_190)) { + setWidgetContextMenuOption(1, new WidgetPointer(762,17), "Search"); + setScriptCallOnClickContextMenu(1471, "", new WidgetPointer(762,17)); + } + return; +} diff --git a/dumps/scripts/1473.cs2 b/dumps/scripts/1473.cs2 new file mode 100644 index 0000000..7a6b123 --- /dev/null +++ b/dumps/scripts/1473.cs2 @@ -0,0 +1,9 @@ +void script_1473() { + setWidgetSprite(1424, new WidgetPointer(762,18)); + setWidgetSprite(1433, new WidgetPointer(762,17)); + script_1463(0); + script_1456(); + script_1549(); + globalint_188 = 1; + return; +} diff --git a/dumps/scripts/1474.cs2 b/dumps/scripts/1474.cs2 new file mode 100644 index 0000000..75739de --- /dev/null +++ b/dumps/scripts/1474.cs2 @@ -0,0 +1,16 @@ +void script_1474() { + setWidgetIsHidden(true, new WidgetPointer(762,115)); + setWidgetIsHidden(true, new WidgetPointer(762,116)); + setWidgetSprite(1423, new WidgetPointer(762,18)); + setWidgetSprite(1431, new WidgetPointer(762,17)); + if (((boolean)bitconfig_4893)) { + script_1456(); + } + script_1463(1); + globalstring_138 = ""; + script_1548(11); + globalint_188 = 0; + setWidgetText(new WidgetPointer(762,45), "Bank of RuneScape"); + setScriptCallOnGameloop(-1, "", new WidgetPointer(762,17)); + return; +} diff --git a/dumps/scripts/1475.cs2 b/dumps/scripts/1475.cs2 new file mode 100644 index 0000000..5389199 --- /dev/null +++ b/dumps/scripts/1475.cs2 @@ -0,0 +1,11 @@ +void script_1475() { + globalstring_138 = globalstring_22; + if (getClientCycle() > globalint_191) { + script_1479(globalstring_138); + setScriptCallOnGameloop(-1, "", new WidgetPointer(762,17)); + globalint_191 = add(getClientCycle(), 10); + } else { + setScriptCallOnGameloop(1476, globalint_191, "i", new WidgetPointer(762,17)); + } + return; +} diff --git a/dumps/scripts/1476.cs2 b/dumps/scripts/1476.cs2 new file mode 100644 index 0000000..ff031d4 --- /dev/null +++ b/dumps/scripts/1476.cs2 @@ -0,0 +1,9 @@ +void script_1476(int arg0) { + if (getClientCycle() >= arg0) { + if (globalint_5 == 11) { + script_1479(globalstring_138); + } + setScriptCallOnGameloop(-1, "", new WidgetPointer(762,17)); + } + return; +} diff --git a/dumps/scripts/1477.cs2 b/dumps/scripts/1477.cs2 new file mode 100644 index 0000000..30acc07 --- /dev/null +++ b/dumps/scripts/1477.cs2 @@ -0,0 +1,20 @@ +void script_1477() { + if (((boolean)bitconfig_5007)) { + setWidgetText(new WidgetPointer(766,36), "Quick task:"); + } else { + setWidgetText(new WidgetPointer(766,36), "Large task:"); + } + setWidgetText(new WidgetPointer(766,100), intToStr(bitconfig_4216)); + setWidgetText(new WidgetPointer(766,102), intToStr(multiply(add(bitconfig_4208, 1), 5))); + setWidgetText(new WidgetPointer(766,91), intToStr(bitconfig_4217)); + setWidgetText(new WidgetPointer(766,93), intToStr(multiply(add(bitconfig_4209, 1), 5))); + setWidgetText(new WidgetPointer(766,81), intToStr(bitconfig_4218)); + setWidgetText(new WidgetPointer(766,83), intToStr(multiply(add(bitconfig_4210, 1), 5))); + setWidgetText(new WidgetPointer(766,71), intToStr(bitconfig_4219)); + setWidgetText(new WidgetPointer(766,73), intToStr(multiply(add(bitconfig_4211, 1), 5))); + setWidgetText(new WidgetPointer(766,61), intToStr(bitconfig_4220)); + setWidgetText(new WidgetPointer(766,63), intToStr(multiply(add(bitconfig_4212, 1), 5))); + setWidgetText(new WidgetPointer(766,51), intToStr(bitconfig_5008)); + setWidgetText(new WidgetPointer(766,53), intToStr(multiply(add(bitconfig_4213, 1), 5))); + return; +} diff --git a/dumps/scripts/1478.cs2 b/dumps/scripts/1478.cs2 new file mode 100644 index 0000000..ae7c6cf --- /dev/null +++ b/dumps/scripts/1478.cs2 @@ -0,0 +1,13 @@ +void script_1478() { + int ivar0; + globalstring_138 = globalstring_22; + ivar0 = script_1479(globalstring_138); + if (ivar0 > 1) { + messageType0("Search for '" + replaceLtGt(globalstring_138) + "' returned " + intToStr(ivar0) + " results."); + } else if (((boolean)ivar0)) { + messageType0("Search for '" + replaceLtGt(globalstring_138) + "' returned " + intToStr(ivar0) + " result."); + } else { + messageType0("Search for '" + replaceLtGt(globalstring_138) + "' returned 0 results."); + } + return; +} diff --git a/dumps/scripts/1479.cs2 b/dumps/scripts/1479.cs2 new file mode 100644 index 0000000..abf0744 --- /dev/null +++ b/dumps/scripts/1479.cs2 @@ -0,0 +1,42 @@ +int script_1479(string arg0) { + int ivar0; + int ivar1; + int ivar2; + arg0 = replaceLtGt(arg0); + script_41(49938529); + globalint_1 = 0; + script_1464(); + setWidgetIsHidden(true, new WidgetPointer(762,115)); + if (((boolean)strLength(arg0))) { + setWidgetText(new WidgetPointer(762,45), "Bank of RuneScape (no search entered)"); + setWidgetIsHidden(false, new WidgetPointer(762,116)); + script_1455(); + return 0; + } + setWidgetText(new WidgetPointer(762,45), "Bank of RuneScape (search: '" + arg0 + "')"); + setWidgetIsHidden(true, new WidgetPointer(762,116)); + ivar0 = getItemContainerLength(95); + ivar1 = 0; + ivar2 = 0; + cs2method2100(0, 0, new WidgetPointer(762,93)); + while (ivar1 < ivar0) { + if (strIndexof(0, lower(getItemName(getItemIdInSlot(95, ivar1))), lower(arg0)) != -1) { + if (setWidgetRegister(new WidgetPointer(762,93), ivar1)) { + setWidgetPosition(add(multiply(44, mod(ivar2, 10)), 8), add(multiply(divide(ivar2, 10), 44), 5), 0, 0); + setWidgetHidden(0); + ivar2 = add(ivar2, 1); + } + } else { + if (setWidgetRegister(new WidgetPointer(762,93), ivar1)) { + setWidgetPosition(0, 0, 0, 0); + setWidgetHidden(1); + } + } + ivar1 = add(ivar1, 1); + } + if (((boolean)ivar2)) { + setWidgetIsHidden(false, new WidgetPointer(762,115)); + } + script_1458(ivar2); + return ivar2; +} diff --git a/dumps/scripts/148.cs2 b/dumps/scripts/148.cs2 new file mode 100644 index 0000000..8f8d68c --- /dev/null +++ b/dumps/scripts/148.cs2 @@ -0,0 +1,63 @@ +int script_148(int arg0) { + switch (arg0) { + case 0: + return globalint_12; + case 1: + return globalint_13; + case 2: + return globalint_14; + case 3: + return globalint_15; + case 4: + return globalint_16; + case 5: + return globalint_17; + case 6: + return globalint_18; + case 7: + return globalint_19; + case 8: + return globalint_20; + case 9: + return globalint_21; + case 10: + return globalint_22; + case 11: + return globalint_23; + case 12: + return globalint_24; + case 13: + return globalint_25; + case 14: + return globalint_26; + case 15: + return globalint_27; + case 16: + return globalint_28; + case 17: + return globalint_29; + case 18: + return globalint_30; + case 19: + return globalint_31; + case 20: + return globalint_32; + case 21: + return globalint_33; + case 22: + return globalint_34; + case 23: + return globalint_35; + case 24: + return globalint_36; + case 25: + return globalint_37; + case 26: + return globalint_38; + case 27: + return globalint_39; + case -1: + return globalint_212; + } + return 0; +} diff --git a/dumps/scripts/1480.cs2 b/dumps/scripts/1480.cs2 new file mode 100644 index 0000000..f752fb4 --- /dev/null +++ b/dumps/scripts/1480.cs2 @@ -0,0 +1,8 @@ +void script_1480(int arg0,int arg1) { + if (((boolean)globalint_188)) { + script_41(49938529); + return; + } + script_569(arg0, arg1, 49938529, 25, 150, "Item is in tab " + intToStr(script_1468(arg1))); + return; +} diff --git a/dumps/scripts/1481.cs2 b/dumps/scripts/1481.cs2 new file mode 100644 index 0000000..6ec8236 --- /dev/null +++ b/dumps/scripts/1481.cs2 @@ -0,0 +1,4 @@ +void script_1481() { + messageType0("Please drag an item here to create a new tab."); + return; +} diff --git a/dumps/scripts/1482.cs2 b/dumps/scripts/1482.cs2 new file mode 100644 index 0000000..bba0706 --- /dev/null +++ b/dumps/scripts/1482.cs2 @@ -0,0 +1,9 @@ +void script_1482(int arg0) { + int ivar1; + ivar1 = cs2method_3408(73, 105, 1613, arg0); + if ((ivar1 != -1) && (ivar1 != bitconfig_4893)) { + script_1463(ivar1); + setScriptCallOnGameloop(1483, add(getClientCycle(), 15), new WidgetPointer(-32768,3), "iI", new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/1483.cs2 b/dumps/scripts/1483.cs2 new file mode 100644 index 0000000..f5fd99c --- /dev/null +++ b/dumps/scripts/1483.cs2 @@ -0,0 +1,7 @@ +void script_1483(int arg0,int arg1) { + if (getClientCycle() >= arg0) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg1)); + script_1463(bitconfig_4893); + } + return; +} diff --git a/dumps/scripts/1484.cs2 b/dumps/scripts/1484.cs2 new file mode 100644 index 0000000..4778bf0 --- /dev/null +++ b/dumps/scripts/1484.cs2 @@ -0,0 +1,7 @@ +void script_1484() { + if (((boolean)globalint_188)) { + script_1474(); + } + script_675(); + return; +} diff --git a/dumps/scripts/1485.cs2 b/dumps/scripts/1485.cs2 new file mode 100644 index 0000000..3a2f0c4 --- /dev/null +++ b/dumps/scripts/1485.cs2 @@ -0,0 +1,9 @@ +void script_1485() { + if (((boolean)standart_config_115)) { + standart_config_115 = 1; + } else { + standart_config_115 = 0; + } + script_1487(); + return; +} diff --git a/dumps/scripts/1486.cs2 b/dumps/scripts/1486.cs2 new file mode 100644 index 0000000..8b4e2c4 --- /dev/null +++ b/dumps/scripts/1486.cs2 @@ -0,0 +1,4 @@ +void script_1486() { + script_1487(); + return; +} diff --git a/dumps/scripts/1487.cs2 b/dumps/scripts/1487.cs2 new file mode 100644 index 0000000..a870490 --- /dev/null +++ b/dumps/scripts/1487.cs2 @@ -0,0 +1,16 @@ +void script_1487() { + string svar0; + svar0 = ""; + if (((boolean)standart_config_115)) { + setWidgetSprite(1431, new WidgetPointer(762,19)); + setWidgetSprite(1427, new WidgetPointer(762,20)); + svar0 = "Switch to note withdrawal mode"; + } else { + setWidgetSprite(1433, new WidgetPointer(762,19)); + setWidgetSprite(1428, new WidgetPointer(762,20)); + svar0 = "Switch to item withdrawal mode"; + } + setWidgetContextMenuOption(1, new WidgetPointer(762,19), svar0); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(762,119), svar0, 25, 150, "IIsii", new WidgetPointer(762,19)); + return; +} diff --git a/dumps/scripts/1488.cs2 b/dumps/scripts/1488.cs2 new file mode 100644 index 0000000..d43278f --- /dev/null +++ b/dumps/scripts/1488.cs2 @@ -0,0 +1,9 @@ +void script_1488() { + if (((boolean)standart_config_304)) { + standart_config_304 = 1; + } else { + standart_config_304 = 0; + } + script_1490(); + return; +} diff --git a/dumps/scripts/1489.cs2 b/dumps/scripts/1489.cs2 new file mode 100644 index 0000000..21e0cc0 --- /dev/null +++ b/dumps/scripts/1489.cs2 @@ -0,0 +1,4 @@ +void script_1489() { + script_1490(); + return; +} diff --git a/dumps/scripts/149.cs2 b/dumps/scripts/149.cs2 new file mode 100644 index 0000000..e830b22 --- /dev/null +++ b/dumps/scripts/149.cs2 @@ -0,0 +1,5 @@ +void script_149(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,string arg6,string arg7,string arg8,string arg9,string arg10) { + script_153(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, "null", "null", "null", "null"); + setScriptCallOnItemContainerUpdate(151, new WidgetPointer(arg0), arg1, arg2, arg3, arg4, new WidgetPointer(arg5), arg6, arg7, arg8, arg9, arg10, "null", "null", "null", "null", arg1, 1, "IviiiIsssssssssY", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1490.cs2 b/dumps/scripts/1490.cs2 new file mode 100644 index 0000000..657309a --- /dev/null +++ b/dumps/scripts/1490.cs2 @@ -0,0 +1,16 @@ +void script_1490() { + string svar0; + svar0 = ""; + if (((boolean)standart_config_304)) { + setWidgetSprite(1431, new WidgetPointer(762,15)); + setWidgetSprite(1425, new WidgetPointer(762,16)); + svar0 = "Switch to insert items mode"; + } else { + setWidgetSprite(1433, new WidgetPointer(762,15)); + setWidgetSprite(1426, new WidgetPointer(762,16)); + svar0 = "Switch to swap items mode"; + } + setWidgetContextMenuOption(1, new WidgetPointer(762,15), svar0); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(762,119), svar0, 25, 150, "IIsii", new WidgetPointer(762,15)); + return; +} diff --git a/dumps/scripts/1491.cs2 b/dumps/scripts/1491.cs2 new file mode 100644 index 0000000..7fb36c1 --- /dev/null +++ b/dumps/scripts/1491.cs2 @@ -0,0 +1,8 @@ +void script_1491(int arg0) { + script_1455(); + script_1456(); + script_1463(1); + script_1474(); + bitconfig_4893 = 1; + return; +} diff --git a/dumps/scripts/1492.cs2 b/dumps/scripts/1492.cs2 new file mode 100644 index 0000000..8afede9 --- /dev/null +++ b/dumps/scripts/1492.cs2 @@ -0,0 +1,4 @@ +void script_1492(int arg0) { + script_1500(arg0, 2); + return; +} diff --git a/dumps/scripts/1493.cs2 b/dumps/scripts/1493.cs2 new file mode 100644 index 0000000..367d07e --- /dev/null +++ b/dumps/scripts/1493.cs2 @@ -0,0 +1,4 @@ +void script_1493(int arg0) { + script_1500(arg0, 3); + return; +} diff --git a/dumps/scripts/1494.cs2 b/dumps/scripts/1494.cs2 new file mode 100644 index 0000000..6fd61a8 --- /dev/null +++ b/dumps/scripts/1494.cs2 @@ -0,0 +1,4 @@ +void script_1494(int arg0) { + script_1500(arg0, 4); + return; +} diff --git a/dumps/scripts/1495.cs2 b/dumps/scripts/1495.cs2 new file mode 100644 index 0000000..2938240 --- /dev/null +++ b/dumps/scripts/1495.cs2 @@ -0,0 +1,4 @@ +void script_1495(int arg0) { + script_1500(arg0, 5); + return; +} diff --git a/dumps/scripts/1496.cs2 b/dumps/scripts/1496.cs2 new file mode 100644 index 0000000..365e1ee --- /dev/null +++ b/dumps/scripts/1496.cs2 @@ -0,0 +1,4 @@ +void script_1496(int arg0) { + script_1500(arg0, 6); + return; +} diff --git a/dumps/scripts/1497.cs2 b/dumps/scripts/1497.cs2 new file mode 100644 index 0000000..23e54ec --- /dev/null +++ b/dumps/scripts/1497.cs2 @@ -0,0 +1,4 @@ +void script_1497(int arg0) { + script_1500(arg0, 7); + return; +} diff --git a/dumps/scripts/1498.cs2 b/dumps/scripts/1498.cs2 new file mode 100644 index 0000000..ba755b4 --- /dev/null +++ b/dumps/scripts/1498.cs2 @@ -0,0 +1,4 @@ +void script_1498(int arg0) { + script_1500(arg0, 8); + return; +} diff --git a/dumps/scripts/1499.cs2 b/dumps/scripts/1499.cs2 new file mode 100644 index 0000000..e7276ff --- /dev/null +++ b/dumps/scripts/1499.cs2 @@ -0,0 +1,4 @@ +void script_1499(int arg0) { + script_1500(arg0, 9); + return; +} diff --git a/dumps/scripts/15.cs2 b/dumps/scripts/15.cs2 new file mode 100644 index 0000000..c409e2e --- /dev/null +++ b/dumps/scripts/15.cs2 @@ -0,0 +1,4 @@ +void script_15() { + globalint_155 = 0; + return; +} diff --git a/dumps/scripts/150.cs2 b/dumps/scripts/150.cs2 new file mode 100644 index 0000000..b610bd4 --- /dev/null +++ b/dumps/scripts/150.cs2 @@ -0,0 +1,5 @@ +void script_150(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,string arg6,string arg7,string arg8,string arg9,string arg10,string arg11,string arg12,string arg13,string arg14) { + script_153(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + setScriptCallOnItemContainerUpdate(151, new WidgetPointer(arg0), arg1, arg2, arg3, arg4, new WidgetPointer(arg5), arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg1, 1, "IviiiIsssssssssY", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1500.cs2 b/dumps/scripts/1500.cs2 new file mode 100644 index 0000000..27178d6 --- /dev/null +++ b/dumps/scripts/1500.cs2 @@ -0,0 +1,47 @@ +void script_1500(int arg0,int arg1) { + int stack_dump0; + cs2func_script_1467_struct(2,0,0) structdump_1; + if (script_706(arg1) > 0) { + if (((boolean)arg0)) { + if (((boolean)globalint_188)) { + script_1474(); + } + script_1455(); + stack_dump0 = arg1; + structdump_1 = script_1467(stack_dump0); + script_1457(structdump_1.intpart_0, structdump_1.intpart_1); + script_1463(arg1); + cs2method2100(0, script_704(arg1), new WidgetPointer(762,93)); + script_157(49938546, 49938525, cs2method2601(new WidgetPointer(762,93)), 1); + bitconfig_4893 = arg1; + } else { + if (arg0 == 2) { + if (arg1 == 2) { + globalint_204 = globalint_205; + } + if (arg1 <= 3) { + globalint_205 = globalint_206; + } + if (arg1 <= 4) { + globalint_206 = globalint_207; + } + if (arg1 <= 5) { + globalint_207 = globalint_208; + } + if (arg1 <= 6) { + globalint_208 = globalint_209; + } + if (arg1 <= 7) { + globalint_209 = globalint_210; + } + if (arg1 <= 8) { + globalint_210 = globalint_211; + } + if (arg1 <= 9) { + globalint_211 = 0; + } + } + } + } + return; +} diff --git a/dumps/scripts/1501.cs2 b/dumps/scripts/1501.cs2 new file mode 100644 index 0000000..a5a532d --- /dev/null +++ b/dumps/scripts/1501.cs2 @@ -0,0 +1,5 @@ +void script_1501(int arg0,int arg1) { + script_41(arg1); + cs2method2103(0, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1502.cs2 b/dumps/scripts/1502.cs2 new file mode 100644 index 0000000..be86b54 --- /dev/null +++ b/dumps/scripts/1502.cs2 @@ -0,0 +1,246 @@ +int script_1502(int arg0) { + flow_0: + SWITCH (arg0) { + case 66650278: + GOTO flow_1 + case 66650279: + GOTO flow_2 + case 66650280: + GOTO flow_3 + case 66650281: + GOTO flow_4 + case 66650282: + GOTO flow_5 + case 66650283: + GOTO flow_6 + case 66650284: + GOTO flow_7 + case 66650285: + GOTO flow_8 + case 66650286: + GOTO flow_9 + case 66650287: + GOTO flow_10 + case 66650288: + GOTO flow_11 + case 66650289: + GOTO flow_12 + case 66650290: + GOTO flow_13 + case 66650291: + GOTO flow_14 + case 66650292: + GOTO flow_15 + case 66650293: + GOTO flow_16 + case 66650294: + GOTO flow_17 + case 66650295: + GOTO flow_18 + case 66650296: + GOTO flow_19 + case 66650297: + GOTO flow_20 + case 66650298: + GOTO flow_21 + case 66650299: + GOTO flow_22 + case 66650300: + GOTO flow_23 + case 66650301: + GOTO flow_24 + case 66650302: + GOTO flow_25 + case 66650303: + GOTO flow_26 + case 66650304: + GOTO flow_27 + case 66650305: + GOTO flow_28 + case 66650306: + GOTO flow_29 + case 66650307: + GOTO flow_30 + case 66650308: + GOTO flow_31 + case 66650309: + GOTO flow_32 + case 66650310: + GOTO flow_33 + case 66650311: + GOTO flow_34 + case 66650312: + GOTO flow_35 + case 66650313: + GOTO flow_36 + case 66650314: + GOTO flow_37 + case 66650315: + GOTO flow_38 + case 66650316: + GOTO flow_39 + case 66650317: + GOTO flow_40 + case 66650318: + GOTO flow_41 + case 66650319: + GOTO flow_42 + case 66650320: + GOTO flow_43 + case 66650321: + GOTO flow_44 + case 66650322: + GOTO flow_45 + case 66650323: + GOTO flow_46 + case 66650324: + GOTO flow_47 + case 66650325: + GOTO flow_48 + case 66650326: + GOTO flow_49 + case 66650327: + GOTO flow_50 + case 66650328: + GOTO flow_51 + case 66650329: + GOTO flow_52 + case 66650330: + GOTO flow_53 + case 66650331: + GOTO flow_54 + case 66650332: + GOTO flow_55 + case 66650333: + GOTO flow_56 + case 66650334: + GOTO flow_57 + case 66650335: + GOTO flow_58 + case 66650336: + GOTO flow_59 + case 66650337: + GOTO flow_60 + } + return -1; + flow_1: + return 1; + flow_2: + return 2; + flow_3: + return 3; + flow_4: + return 4; + flow_5: + return 5; + flow_6: + return 6; + flow_7: + return 7; + flow_8: + return 8; + flow_9: + return 9; + flow_10: + return 10; + flow_11: + return 11; + flow_12: + return 12; + flow_13: + return 13; + flow_14: + return 14; + flow_15: + return 15; + flow_16: + return 16; + flow_17: + return 17; + flow_18: + return 18; + flow_19: + return 19; + flow_20: + return 20; + flow_21: + return 21; + flow_22: + return 22; + flow_23: + return 23; + flow_24: + return 24; + flow_25: + return 25; + flow_26: + return 26; + flow_27: + return 27; + flow_28: + return 28; + flow_29: + return 29; + flow_30: + return 30; + flow_31: + return 31; + flow_32: + return 32; + flow_33: + return 33; + flow_34: + return 34; + flow_35: + return 35; + flow_36: + return 36; + flow_37: + return 37; + flow_38: + return 38; + flow_39: + return 39; + flow_40: + return 40; + flow_41: + return 41; + flow_42: + return 42; + flow_43: + return 43; + flow_44: + return 44; + flow_45: + return 45; + flow_46: + return 46; + flow_47: + return 47; + flow_48: + return 48; + flow_49: + return 49; + flow_50: + return 50; + flow_51: + return 51; + flow_52: + return 52; + flow_53: + return 53; + flow_54: + return 54; + flow_55: + return 55; + flow_56: + return 56; + flow_57: + return 57; + flow_58: + return 58; + flow_59: + return 59; + flow_60: + return 60; +} diff --git a/dumps/scripts/1503.cs2 b/dumps/scripts/1503.cs2 new file mode 100644 index 0000000..472a21a --- /dev/null +++ b/dumps/scripts/1503.cs2 @@ -0,0 +1,16 @@ +void script_1503() { + deleteAllExtraChilds(new WidgetPointer(728,1)); + script_1088(47710209, 22); + deleteAllExtraChilds(new WidgetPointer(728,6)); + script_333(47710214, 4734771, 3156258, 0, 0); + script_2647(47710214); + deleteAllExtraChilds(new WidgetPointer(728,9)); + script_333(47710217, 4734771, 3156258, 0, 0); + script_1516(47710217, 380, 100); + script_2647(47710217); + deleteAllExtraChilds(new WidgetPointer(728,11)); + script_2647(47710219); + script_1506(); + setScriptCallOnGlobalConfigChange(1505, 1014, 1018, 2, "Y", new WidgetPointer(728,1)); + return; +} diff --git a/dumps/scripts/1504.cs2 b/dumps/scripts/1504.cs2 new file mode 100644 index 0000000..bde22d7 --- /dev/null +++ b/dumps/scripts/1504.cs2 @@ -0,0 +1,9 @@ +int script_1504(int arg0,int arg1,int arg2,int arg3,string arg4) { + int ivar4; + ivar4 = 0; + if (setWidgetRegister(new WidgetPointer(arg2), arg3) || ((arg3 == -1) && setWidgetRegister(new WidgetPointer(arg2)))) { + ivar4 = divide(subtract(getWidgetActualWidth(), getTextWidth(arg1, script_1602(arg4))), 2); + return script_1401(arg0, arg1, ivar4, arg4); + } + return strLength(arg4); +} diff --git a/dumps/scripts/1505.cs2 b/dumps/scripts/1505.cs2 new file mode 100644 index 0000000..1a1a42e --- /dev/null +++ b/dumps/scripts/1505.cs2 @@ -0,0 +1,4 @@ +void script_1505() { + script_1506(); + return; +} diff --git a/dumps/scripts/1506.cs2 b/dumps/scripts/1506.cs2 new file mode 100644 index 0000000..d6237d3 --- /dev/null +++ b/dumps/scripts/1506.cs2 @@ -0,0 +1,146 @@ +void script_1506() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + string svar0; + ivar0 = -1; + ivar1 = -1; + if (IsFemale()) { + ivar0 = 1137; + ivar1 = 3294; + } else { + ivar0 = 1136; + ivar1 = 3291; + } + deleteAllExtraChilds(new WidgetPointer(728,7)); + ivar2 = 0; + ivar3 = getCommonDefinitionSize(ivar0); + ivar4 = -1; + svar0 = ""; + ivar5 = 0; + ivar6 = 0; + while (ivar2 < ivar3) { + ivar4 = cs2method_3408(105, 75, ivar0, ivar2); + svar0 = cs2method_3408(105, 115, ivar1, ivar2); + createExtraChild(new WidgetPointer(728,7), 5, getExtraChildGap(new WidgetPointer(728,7))); + setWidgetSize(17, 17, 0, 0); + setWidgetPosition(0, add(ivar5, 1), 0, 0); + createExtraChild(new WidgetPointer(728,7), 4, getExtraChildGap(new WidgetPointer(728,7))); + setWidgetSize(20, 19, 1, 0); + setWidgetPosition(0, ivar5, 2, 0); + setWidgetTextAlignment(0, 1, 0); + setWidgetRGB(new Color(255, 152, 31)); + setWidgetFont(495); + setWidgetText(svar0); + if (ivar4 == globalint_1014) { + setWidgetSprite(699); + ivar6 = ivar5; + } else { + setWidgetSprite(697); + setScriptCallOnMouseEntered(1356, new WidgetPointer(-32768,3), getWidgetCustomChildArrayIndex(), 16777215, "Iii"); + setScriptCallOnMouseExit(1356, new WidgetPointer(-32768,3), getWidgetCustomChildArrayIndex(), 16750623, "Iii"); + setScriptCallOnMouseEntered(1356, new WidgetPointer(-32768,3), getWidgetCustomChildArrayIndex(), 16777215, "Iii"); + setScriptCallOnMouseExit(1356, new WidgetPointer(-32768,3), getWidgetCustomChildArrayIndex(), 16750623, "Iii"); + setWidgetContextMenuOption(1, svar0); + setWidgetContextMenuOption(1, svar0); + setScriptCallOnClickContextMenu(1507, -2147483644, ivar4, "iK"); + setScriptCallOnClickContextMenu(1507, -2147483644, ivar4, "iK"); + } + ivar2 = add(ivar2, 1); + ivar5 = add(ivar5, 19); + } + if (ivar5 > getWidgetActualHeight(new WidgetPointer(728,7))) { + setWidgetSize(20, 4, 1, 1, new WidgetPointer(728,7)); + setWidgetScrollMax(0, ivar5, new WidgetPointer(728,7)); + if (ivar6 < cs2method2601(new WidgetPointer(728,7))) { + cs2method2100(0, subtract(ivar6, 5), new WidgetPointer(728,7)); + } else { + if (add(ivar6, 19) >= add(cs2method2601(new WidgetPointer(728,7)), getWidgetActualHeight(new WidgetPointer(728,7)))) { + cs2method2100(0, subtract(add(ivar6, 25), getWidgetActualHeight(new WidgetPointer(728,7))), new WidgetPointer(728,7)); + } + } + setWidgetIsHidden(false, new WidgetPointer(728,8)); + script_31(47710216, 47710215, 792, 789, 790, 791, 773, 788); + } else { + setWidgetSize(4, 4, 1, 1, new WidgetPointer(728,7)); + setWidgetScrollMax(0, 0, new WidgetPointer(728,7)); + cs2method2100(0, 0, new WidgetPointer(728,7)); + deleteAllExtraChilds(new WidgetPointer(728,8)); + setWidgetIsHidden(true, new WidgetPointer(728,8)); + } + deleteAllExtraChilds(new WidgetPointer(728,12)); + ivar3 = getCommonDefinitionSize(3297); + ivar7 = 6; + if (multiply(add(divide(subtract(ivar3, 1), ivar7), 1), 21) > getWidgetActualHeight(new WidgetPointer(728,12))) { + ivar7 = 5; + } + ivar2 = 0; + ivar5 = 0; + ivar8 = 0; + ivar9 = -1; + ivar10 = 0; + while (ivar2 < ivar3) { + svar0 = cs2method_3408(105, 115, 3296, ivar2); + ivar10 = cs2method_3408(105, 105, 3297, ivar2); + createExtraChild(new WidgetPointer(728,12), 3, getExtraChildGap(new WidgetPointer(728,12))); + setWidgetSize(21, 21, 0, 0); + setWidgetFilled(1); + setWidgetPosition(multiply(ivar8, getWidgetActualWidth()), ivar5, 0, 0); + setWidgetRGB(new Color(cs2method_3408(105, 105, 753, ivar2))); + setScriptCallOnMouseOver(1160, new WidgetPointer(-32768,3), -2147483643, new WidgetPointer(728,18), svar0, 0, 512, "IiIsii"); + setScriptCallOnMouseExit(40, new WidgetPointer(728,18), "I"); + createExtraChild(new WidgetPointer(728,12), 5, getExtraChildGap(new WidgetPointer(728,12))); + setWidgetSize(getWidgetActualWidth(), getWidgetActualHeight(), 0, 0); + setWidgetPosition(getWidgetActualX(), getWidgetActualY(), 0, 0); + if (ivar10 == globalint_1018) { + setWidgetSprite(1043); + ivar6 = ivar5; + } else { + ivar9 = 1041; + setWidgetSprite(ivar9); + setScriptCallOnMouseExit(688, new WidgetPointer(-32768,3), getWidgetCustomChildArrayIndex(), ivar9, "Iid"); + ivar9 = 1042; + setScriptCallOnMouseEntered(688, new WidgetPointer(-32768,3), getWidgetCustomChildArrayIndex(), ivar9, "Iid"); + setWidgetContextMenuOption(1, svar0); + setScriptCallOnClickContextMenu(1508, -2147483644, ivar10, "ii"); + } + ivar2 = add(ivar2, 1); + if (ivar8 < subtract(ivar7, 1)) { + ivar8 = add(ivar8, 1); + } else { + ivar8 = 0; + ivar5 = add(ivar5, getWidgetActualHeight()); + } + } + if (ivar8 != 0) { + ivar5 = add(ivar5, 21); + } + if ((ivar5 > getWidgetActualHeight(new WidgetPointer(728,12))) || (ivar7 < 6)) { + setWidgetSize(20, 4, 1, 1, new WidgetPointer(728,12)); + setWidgetScrollMax(0, ivar5, new WidgetPointer(728,12)); + if (ivar6 < cs2method2601(new WidgetPointer(728,12))) { + cs2method2100(0, subtract(ivar6, 5), new WidgetPointer(728,12)); + } else { + if (add(ivar6, 21) >= add(cs2method2601(new WidgetPointer(728,12)), getWidgetActualHeight(new WidgetPointer(728,12)))) { + cs2method2100(0, subtract(add(ivar6, 25), getWidgetActualHeight(new WidgetPointer(728,12))), new WidgetPointer(728,12)); + } + } + setWidgetIsHidden(false, new WidgetPointer(728,13)); + script_31(47710221, 47710220, 792, 789, 790, 791, 773, 788); + } else { + setWidgetSize(4, 4, 1, 1, new WidgetPointer(728,12)); + setWidgetScrollMax(0, 0, new WidgetPointer(728,12)); + cs2method2100(0, 0, new WidgetPointer(728,12)); + deleteAllExtraChilds(new WidgetPointer(728,13)); + setWidgetIsHidden(true, new WidgetPointer(728,13)); + } + return; +} diff --git a/dumps/scripts/1507.cs2 b/dumps/scripts/1507.cs2 new file mode 100644 index 0000000..b43cec1 --- /dev/null +++ b/dumps/scripts/1507.cs2 @@ -0,0 +1,13 @@ +void script_1507(int arg0,int arg1) { + if (arg0 != 1) { + return; + } + if (IsFemale()) { + cs2method403(13, arg1); + } else { + cs2method403(6, arg1); + } + globalint_1014 = arg1; + script_1506(); + return; +} diff --git a/dumps/scripts/1508.cs2 b/dumps/scripts/1508.cs2 new file mode 100644 index 0000000..8ca781d --- /dev/null +++ b/dumps/scripts/1508.cs2 @@ -0,0 +1,9 @@ +void script_1508(int arg0,int arg1) { + if (arg0 != 1) { + return; + } + cs2method404(3, arg1); + globalint_1018 = arg1; + script_1506(); + return; +} diff --git a/dumps/scripts/1509.cs2 b/dumps/scripts/1509.cs2 new file mode 100644 index 0000000..c2c8c17 --- /dev/null +++ b/dumps/scripts/1509.cs2 @@ -0,0 +1,35 @@ +void script_1509() { + string svar0; + deleteAllExtraChilds(new WidgetPointer(729,1)); + script_1088(47775745, 22); + deleteAllExtraChilds(new WidgetPointer(729,11)); + script_333(47775755, 4734771, 3156258, 0, 0); + script_2647(47775755); + deleteAllExtraChilds(new WidgetPointer(729,14)); + script_333(47775758, 4734771, 3156258, 0, 0); + script_1516(47775758, 380, 100); + script_2647(47775758); + deleteAllExtraChilds(new WidgetPointer(729,16)); + script_2647(47775760); + globalint_778 = bitconfig_6091; + script_1513(); + setScriptCallOnConfigChange(1510, 1057, 1, "Y", new WidgetPointer(729,1)); + setScriptCallOnGlobalConfigChange(1511, 1010, 1011, 1012, 1013, 1016, 1017, 6, "Y", new WidgetPointer(729,1)); + setScriptCallOnClickContextMenu(1512, -2147483644, 0, "ii", new WidgetPointer(729,6)); + setScriptCallOnClickContextMenu(1512, -2147483644, 1, "ii", new WidgetPointer(729,7)); + setScriptCallOnClickContextMenu(1512, -2147483644, 2, "ii", new WidgetPointer(729,8)); + setScriptCallOnClickContextMenu(1512, -2147483644, 3, "ii", new WidgetPointer(729,9)); + svar0 = "Choose a top"; + setScriptCallOnMouseOver(1160, new WidgetPointer(-32768,3), -1, new WidgetPointer(729,23), svar0, 25, 512, "IiIsii", new WidgetPointer(729,6)); + setScriptCallOnMouseExit(40, new WidgetPointer(729,23), "I", new WidgetPointer(729,6)); + svar0 = "Choose some sleeves"; + setScriptCallOnMouseOver(1160, new WidgetPointer(-32768,3), -1, new WidgetPointer(729,23), svar0, 25, 512, "IiIsii", new WidgetPointer(729,7)); + setScriptCallOnMouseExit(40, new WidgetPointer(729,23), "I", new WidgetPointer(729,7)); + svar0 = "Decorate your wrists"; + setScriptCallOnMouseOver(1160, new WidgetPointer(-32768,3), -1, new WidgetPointer(729,23), svar0, 25, 512, "IiIsii", new WidgetPointer(729,8)); + setScriptCallOnMouseExit(40, new WidgetPointer(729,23), "I", new WidgetPointer(729,8)); + svar0 = "Choose some leggings"; + setScriptCallOnMouseOver(1160, new WidgetPointer(-32768,3), -1, new WidgetPointer(729,23), svar0, 25, 512, "IiIsii", new WidgetPointer(729,9)); + setScriptCallOnMouseExit(40, new WidgetPointer(729,23), "I", new WidgetPointer(729,9)); + return; +} diff --git a/dumps/scripts/151.cs2 b/dumps/scripts/151.cs2 new file mode 100644 index 0000000..8830c21 --- /dev/null +++ b/dumps/scripts/151.cs2 @@ -0,0 +1,4 @@ +void script_151(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,string arg6,string arg7,string arg8,string arg9,string arg10,string arg11,string arg12,string arg13,string arg14) { + script_153(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + return; +} diff --git a/dumps/scripts/1510.cs2 b/dumps/scripts/1510.cs2 new file mode 100644 index 0000000..95edbb3 --- /dev/null +++ b/dumps/scripts/1510.cs2 @@ -0,0 +1,7 @@ +void script_1510() { + if (bitconfig_6091 != globalint_778) { + globalint_778 = bitconfig_6091; + script_1513(); + } + return; +} diff --git a/dumps/scripts/1511.cs2 b/dumps/scripts/1511.cs2 new file mode 100644 index 0000000..d8e10db --- /dev/null +++ b/dumps/scripts/1511.cs2 @@ -0,0 +1,4 @@ +void script_1511() { + script_1513(); + return; +} diff --git a/dumps/scripts/1512.cs2 b/dumps/scripts/1512.cs2 new file mode 100644 index 0000000..23842fd --- /dev/null +++ b/dumps/scripts/1512.cs2 @@ -0,0 +1,15 @@ +void script_1512(int arg0,int arg1) { + if (arg0 != 1) { + return; + } + switch (arg1) { + case 1: + case 2: + if (script_361(globalint_1010, 3) != -1) { + return; + } + } + globalint_778 = arg1; + script_1513(); + return; +} diff --git a/dumps/scripts/1513.cs2 b/dumps/scripts/1513.cs2 new file mode 100644 index 0000000..55549a4 --- /dev/null +++ b/dumps/scripts/1513.cs2 @@ -0,0 +1,262 @@ +void script_1513() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + string svar0; + int stack_dump0; + flow_0: + ivar0 = -1; + ivar1 = -1; + ivar2 = -1; + ivar3 = -1; + ivar4 = -1; + ivar5 = -1; + ivar6 = -1; + ivar7 = -1; + ivar8 = -1; + SWITCH (globalint_778) { + case 1: + GOTO flow_4 + case 2: + GOTO flow_8 + case 3: + GOTO flow_12 + } + globalint_778 = 0; + setWidgetSprite(1044, new WidgetPointer(729,6)); + setWidgetSprite(1053, new WidgetPointer(729,7)); + setWidgetSprite(1057, new WidgetPointer(729,8)); + setWidgetSprite(1054, new WidgetPointer(729,9)); + if (IsFemale()) { + stack_dump0 = 1591; + ivar2 = 9; + ivar0 = stack_dump0; + ivar1 = 1590; + } else { + stack_dump0 = 690; + ivar2 = 2; + ivar0 = stack_dump0; + ivar1 = 689; + } + flow_3: + ivar3 = globalint_1010; + ivar4 = 3282; + ivar5 = 2347; + ivar6 = 2348; + ivar7 = 1; + ivar8 = globalint_1016; + GOTO flow_16 + flow_4: + setWidgetSprite(1052, new WidgetPointer(729,6)); + setWidgetSprite(1045, new WidgetPointer(729,7)); + setWidgetSprite(1057, new WidgetPointer(729,8)); + setWidgetSprite(1054, new WidgetPointer(729,9)); + if (IsFemale()) { + stack_dump0 = 693; + ivar2 = 10; + ivar0 = stack_dump0; + ivar1 = 1593; + } else { + stack_dump0 = 711; + ivar2 = 3; + ivar0 = stack_dump0; + ivar1 = 702; + } + ivar3 = globalint_1011; + ivar4 = 3282; + ivar5 = 2347; + ivar6 = 2348; + ivar7 = 1; + ivar8 = globalint_1016; + GOTO flow_16 + flow_8: + setWidgetSprite(1052, new WidgetPointer(729,6)); + setWidgetSprite(1053, new WidgetPointer(729,7)); + setWidgetSprite(1049, new WidgetPointer(729,8)); + setWidgetSprite(1054, new WidgetPointer(729,9)); + if (IsFemale()) { + stack_dump0 = 751; + ivar2 = 11; + ivar0 = stack_dump0; + } else { + stack_dump0 = 749; + ivar2 = 4; + ivar0 = stack_dump0; + } + ivar1 = 750; + ivar3 = globalint_1012; + GOTO flow_16 + flow_12: + setWidgetSprite(1052, new WidgetPointer(729,6)); + setWidgetSprite(1053, new WidgetPointer(729,7)); + setWidgetSprite(1057, new WidgetPointer(729,8)); + setWidgetSprite(1046, new WidgetPointer(729,9)); + if (IsFemale()) { + stack_dump0 = 1607; + ivar2 = 12; + ivar0 = stack_dump0; + ivar1 = 1606; + } else { + stack_dump0 = 1586; + ivar2 = 5; + ivar0 = stack_dump0; + ivar1 = 1585; + } + ivar3 = globalint_1013; + ivar4 = 3284; + ivar5 = 2347; + ivar6 = 2348; + ivar7 = 2; + ivar8 = globalint_1017; + flow_16: + deleteAllExtraChilds(new WidgetPointer(729,12)); + ivar9 = 0; + ivar10 = getCommonDefinitionSize(ivar0); + ivar11 = -1; + svar0 = ""; + ivar12 = 0; + ivar13 = 0; + while (ivar9 < ivar10) { + ivar11 = cs2method_3408(105, 75, ivar0, ivar9); + svar0 = cs2method_3408(105, 115, ivar1, ivar9); + createExtraChild(new WidgetPointer(729,12), 5, getExtraChildGap(new WidgetPointer(729,12))); + setWidgetSize(17, 17, 0, 0); + setWidgetPosition(0, add(ivar12, 1), 0, 0); + createExtraChild(new WidgetPointer(729,12), 4, getExtraChildGap(new WidgetPointer(729,12))); + setWidgetSize(20, 19, 1, 0); + setWidgetPosition(0, ivar12, 2, 0); + setWidgetTextAlignment(0, 1, 0); + setWidgetRGB(new Color(255, 152, 31)); + setWidgetFont(495); + setWidgetText(svar0); + if (ivar11 == ivar3) { + setWidgetSprite(699); + ivar13 = ivar12; + } else { + setWidgetSprite(697); + setScriptCallOnMouseEntered(1356, new WidgetPointer(-32768,3), getWidgetCustomChildArrayIndex(), 16777215, "Iii"); + setScriptCallOnMouseExit(1356, new WidgetPointer(-32768,3), getWidgetCustomChildArrayIndex(), 16750623, "Iii"); + setScriptCallOnMouseEntered(1356, new WidgetPointer(-32768,3), getWidgetCustomChildArrayIndex(), 16777215, "Iii"); + setScriptCallOnMouseExit(1356, new WidgetPointer(-32768,3), getWidgetCustomChildArrayIndex(), 16750623, "Iii"); + setWidgetContextMenuOption(1, svar0); + setWidgetContextMenuOption(1, svar0); + setScriptCallOnClickContextMenu(1514, -2147483644, ivar11, ivar2, "iKi"); + setScriptCallOnClickContextMenu(1514, -2147483644, ivar11, ivar2, "iKi"); + } + ivar9 = add(ivar9, 1); + ivar12 = add(ivar12, 19); + } + if (ivar12 > getWidgetActualHeight(new WidgetPointer(729,12))) { + setWidgetSize(20, 4, 1, 1, new WidgetPointer(729,12)); + setWidgetScrollMax(0, ivar12, new WidgetPointer(729,12)); + if (ivar13 < cs2method2601(new WidgetPointer(729,12))) { + cs2method2100(0, subtract(ivar13, 5), new WidgetPointer(729,12)); + } else { + if (add(ivar13, 19) >= add(cs2method2601(new WidgetPointer(729,12)), getWidgetActualHeight(new WidgetPointer(729,12)))) { + cs2method2100(0, subtract(add(ivar13, 25), getWidgetActualHeight(new WidgetPointer(729,12))), new WidgetPointer(729,12)); + } + } + setWidgetIsHidden(false, new WidgetPointer(729,13)); + script_31(47775757, 47775756, 792, 789, 790, 791, 773, 788); + } else { + setWidgetSize(4, 4, 1, 1, new WidgetPointer(729,12)); + setWidgetScrollMax(0, 0, new WidgetPointer(729,12)); + cs2method2100(0, 0, new WidgetPointer(729,12)); + deleteAllExtraChilds(new WidgetPointer(729,13)); + setWidgetIsHidden(true, new WidgetPointer(729,13)); + } + deleteAllExtraChilds(new WidgetPointer(729,17)); + if (ivar5 == -1) { + setWidgetSize(4, 4, 1, 1, new WidgetPointer(729,17)); + setWidgetScrollMax(0, 0, new WidgetPointer(729,17)); + cs2method2100(0, 0, new WidgetPointer(729,17)); + deleteAllExtraChilds(new WidgetPointer(729,18)); + setWidgetIsHidden(true, new WidgetPointer(729,18)); + return; + } + ivar10 = getCommonDefinitionSize(ivar5); + ivar14 = 5; + ivar15 = 0; + if (multiply(add(divide(subtract(ivar10, 1), ivar14), 1), 21) > getWidgetActualHeight(new WidgetPointer(729,17))) { + stack_dump0 = 4; + ivar15 = 2; + ivar14 = stack_dump0; + } + ivar9 = 0; + ivar12 = 0; + ivar16 = 0; + ivar17 = -1; + ivar18 = 0; + while (ivar9 < ivar10) { + ivar18 = cs2method_3408(105, 105, ivar4, ivar9); + svar0 = cs2method_3408(105, 115, ivar6, ivar9); + createExtraChild(new WidgetPointer(729,17), 3, getExtraChildGap(new WidgetPointer(729,17))); + setWidgetSize(21, 21, 0, 0); + setWidgetFilled(1); + setWidgetPosition(add(multiply(ivar16, getWidgetActualWidth()), ivar15), ivar12, 0, 0); + setWidgetRGB(new Color(cs2method_3408(105, 105, ivar5, ivar9))); + setScriptCallOnMouseOver(1160, new WidgetPointer(-32768,3), -2147483643, new WidgetPointer(729,23), svar0, 0, 512, "IiIsii"); + setScriptCallOnMouseExit(40, new WidgetPointer(729,23), "I"); + createExtraChild(new WidgetPointer(729,17), 5, getExtraChildGap(new WidgetPointer(729,17))); + setWidgetSize(getWidgetActualWidth(), getWidgetActualHeight(), 0, 0); + setWidgetPosition(getWidgetActualX(), getWidgetActualY(), 0, 0); + if (ivar18 == ivar8) { + setWidgetSprite(1043); + ivar13 = ivar12; + } else { + ivar17 = 1041; + setWidgetSprite(ivar17); + setScriptCallOnMouseExit(688, new WidgetPointer(-32768,3), getWidgetCustomChildArrayIndex(), ivar17, "Iid"); + ivar17 = 1042; + setScriptCallOnMouseEntered(688, new WidgetPointer(-32768,3), getWidgetCustomChildArrayIndex(), ivar17, "Iid"); + setWidgetContextMenuOption(1, svar0); + setScriptCallOnClickContextMenu(1515, -2147483644, ivar18, ivar7, "iii"); + } + ivar9 = add(ivar9, 1); + if (ivar16 < subtract(ivar14, 1)) { + ivar16 = add(ivar16, 1); + } else { + ivar16 = 0; + ivar12 = add(ivar12, getWidgetActualHeight()); + } + } + if (ivar16 != 0) { + ivar12 = add(ivar12, 21); + } + if ((ivar12 > getWidgetActualHeight(new WidgetPointer(729,17))) || (ivar14 < 5)) { + setWidgetSize(20, 4, 1, 1, new WidgetPointer(729,17)); + setWidgetScrollMax(0, ivar12, new WidgetPointer(729,17)); + if (ivar13 < cs2method2601(new WidgetPointer(729,17))) { + cs2method2100(0, subtract(ivar13, 5), new WidgetPointer(729,17)); + } else { + if (add(ivar13, 21) >= add(cs2method2601(new WidgetPointer(729,17)), getWidgetActualHeight(new WidgetPointer(729,17)))) { + cs2method2100(0, subtract(add(ivar13, 25), getWidgetActualHeight(new WidgetPointer(729,17))), new WidgetPointer(729,17)); + } + } + setWidgetIsHidden(false, new WidgetPointer(729,18)); + script_31(47775762, 47775761, 792, 789, 790, 791, 773, 788); + } else { + setWidgetSize(4, 4, 1, 1, new WidgetPointer(729,17)); + setWidgetScrollMax(0, 0, new WidgetPointer(729,17)); + cs2method2100(0, 0, new WidgetPointer(729,17)); + deleteAllExtraChilds(new WidgetPointer(729,18)); + setWidgetIsHidden(true, new WidgetPointer(729,18)); + } + return; +} diff --git a/dumps/scripts/1514.cs2 b/dumps/scripts/1514.cs2 new file mode 100644 index 0000000..457ef9f --- /dev/null +++ b/dumps/scripts/1514.cs2 @@ -0,0 +1,80 @@ +void script_1514(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int stack_dump0; + int stack_dump1; + if (arg0 != 1) { + return; + } + ivar3 = -1; + ivar4 = 2; + ivar5 = 3; + ivar6 = 4; + if (IsFemale()) { + stack_dump0 = 9; + stack_dump1 = 10; + ivar6 = 11; + stack_dump0 = stack_dump0; + ivar5 = stack_dump1; + ivar4 = stack_dump0; + } + ivar7 = -1; + switch (arg2) { + case 2: + case 9: + ivar3 = script_361(arg1, 3); + if (ivar3 != -1) { + globalint_1010 = getOtherCommonData(ivar3, 1182); + cs2method403(ivar4, globalint_1010); + globalint_1011 = getOtherCommonData(ivar3, 1183); + cs2method403(ivar5, globalint_1011); + globalint_1012 = getOtherCommonData(ivar3, 1184); + cs2method403(ivar6, globalint_1012); + } else { + cs2method403(arg2, arg1); + globalint_1010 = arg1; + if ((globalint_1011 == -1) || (script_361(globalint_1011, 4) != -1)) { + if (IsFemale()) { + ivar7 = 61; + } else { + ivar7 = 26; + } + cs2method403(ivar5, ivar7); + globalint_1011 = ivar7; + } + if ((globalint_1012 == -1) || (script_361(globalint_1012, 5) != -1)) { + if (IsFemale()) { + ivar7 = 68; + } else { + ivar7 = 34; + } + cs2method403(ivar6, ivar7); + globalint_1012 = ivar7; + } + } + break; + case 3: + case 10: + if (script_361(globalint_1010, 3) == -1) { + cs2method403(arg2, arg1); + globalint_1011 = arg1; + } + break; + case 4: + case 11: + if (script_361(globalint_1010, 3) == -1) { + cs2method403(arg2, arg1); + globalint_1012 = arg1; + } + break; + case 5: + case 12: + cs2method403(arg2, arg1); + globalint_1013 = arg1; + } + script_1513(); + return; +} diff --git a/dumps/scripts/1515.cs2 b/dumps/scripts/1515.cs2 new file mode 100644 index 0000000..02ff591 --- /dev/null +++ b/dumps/scripts/1515.cs2 @@ -0,0 +1,16 @@ +void script_1515(int arg0,int arg1,int arg2) { + if (arg0 != 1) { + return; + } + if (((boolean)arg2)) { + cs2method404(1, arg1); + globalint_1016 = arg1; + } else { + if (arg2 == 2) { + cs2method404(2, arg1); + globalint_1017 = arg1; + } + } + script_1513(); + return; +} diff --git a/dumps/scripts/1516.cs2 b/dumps/scripts/1516.cs2 new file mode 100644 index 0000000..8938551 --- /dev/null +++ b/dumps/scripts/1516.cs2 @@ -0,0 +1,15 @@ +void script_1516(int arg0,int arg1,int arg2) { + createExtraChild(new WidgetPointer(arg0), 6, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(0, 0, 1, 1); + setWidgetPosition(0, 0, 1, 1); + setWidgetSelfFull(); + setWidget3DRotation(0, arg2, 0, 0, 0, arg1); + if (globalint_779 != -1) { + setWidgetAnimation(getRenderEmoteMaxSomethingMethod4600(globalint_779)); + } else { + setWidgetAnimation(getRenderEmoteMaxSomethingMethod4600(1426)); + } + setScriptCallOnGlobalConfigChange(1517, new WidgetPointer(-32768,3), -2147483643, 779, 1, "IiY"); + setScriptCallOnMousePressed(347, new WidgetPointer(-32768,3), -2147483643, -2147483647, "Iii"); + return; +} diff --git a/dumps/scripts/1517.cs2 b/dumps/scripts/1517.cs2 new file mode 100644 index 0000000..3f09e10 --- /dev/null +++ b/dumps/scripts/1517.cs2 @@ -0,0 +1,10 @@ +void script_1517(int arg0,int arg1) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + if (globalint_779 != -1) { + setWidgetAnimation(getRenderEmoteMaxSomethingMethod4600(globalint_779)); + } else { + setWidgetAnimation(getRenderEmoteMaxSomethingMethod4600(1426)); + } + } + return; +} diff --git a/dumps/scripts/1518.cs2 b/dumps/scripts/1518.cs2 new file mode 100644 index 0000000..6b922c7 --- /dev/null +++ b/dumps/scripts/1518.cs2 @@ -0,0 +1,25 @@ +void script_1518(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + ivar3 = 0; + ivar4 = 0; + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + if (arg2 > 0) { + setWidget3DRotation(cs2method1610(), cs2method1611(), getWidgetRotateX(), script_686(subtract(getWidgetRotateY(), 10), 2048), cs2method1607(), getWidget3DDistance()); + } else if (arg2 < 0) { + setWidget3DRotation(cs2method1610(), cs2method1611(), getWidgetRotateX(), mod(add(getWidgetRotateY(), 10), 2048), cs2method1607(), getWidget3DDistance()); + } else if (ivar3 > 1024) { + ivar4 = add(ivar3, 15); + if (ivar4 >= 2048) { + ivar4 = 0; + } + setWidget3DRotation(cs2method1610(), cs2method1611(), getWidgetRotateX(), ivar4, cs2method1607(), getWidget3DDistance()); + } else if (ivar3 > 0) { + setWidget3DRotation(cs2method1610(), cs2method1611(), getWidgetRotateX(), max(subtract(ivar3, 15), 0), cs2method1607(), getWidget3DDistance()); + } else { + setScriptCallOnGameloop(-1, ""); + } + ivar3 = getWidgetRotateY(); + } + return; +} diff --git a/dumps/scripts/1519.cs2 b/dumps/scripts/1519.cs2 new file mode 100644 index 0000000..26e7ce4 --- /dev/null +++ b/dumps/scripts/1519.cs2 @@ -0,0 +1,9 @@ +int script_1519() { + int ivar0; + ivar0 = 0; + ivar0 = add(add(add(bitconfig_6658, bitconfig_6659), bitconfig_6660), bitconfig_6661); + if (bitconfig_6662 == 63) { + ivar0 = add(ivar0, 1); + } + return ivar0; +} diff --git a/dumps/scripts/152.cs2 b/dumps/scripts/152.cs2 new file mode 100644 index 0000000..762dc51 --- /dev/null +++ b/dumps/scripts/152.cs2 @@ -0,0 +1,31 @@ +void script_152(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,string arg6,string arg7,string arg8,string arg9,string arg10) { + int ivar6; + int ivar7; + int ivar8; + deleteAllExtraChilds(new WidgetPointer(arg0)); + ivar6 = 0; + ivar7 = 0; + if (arg2 > 1) { + if (getWidgetScrollMaxH(new WidgetPointer(arg0)) > 0) { + ivar6 = divide(subtract(getWidgetScrollMaxH(new WidgetPointer(arg0)), multiply(36, arg2)), subtract(arg2, 1)); + } else { + ivar6 = divide(subtract(getWidgetActualWidth(new WidgetPointer(arg0)), multiply(36, arg2)), subtract(arg2, 1)); + } + } + if (arg3 > 1) { + if (getWidgetScrollMaxV(new WidgetPointer(arg0)) > 0) { + ivar7 = divide(subtract(getWidgetScrollMaxV(new WidgetPointer(arg0)), multiply(32, arg3)), subtract(arg3, 1)); + } else { + ivar7 = divide(subtract(getWidgetActualHeight(new WidgetPointer(arg0)), multiply(32, arg3)), subtract(arg3, 1)); + } + } + ivar8 = 0; + while (ivar8 <= multiply(arg2, arg3)) { + createExtraChild(new WidgetPointer(arg0), 5, ivar8); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(multiply(add(36, ivar6), mod(ivar8, arg2)), multiply(divide(ivar8, arg2), add(32, ivar7)), 0, 0); + script_154(arg1, ivar8, arg0, ivar8, arg4, arg5, arg6, arg7, arg8, arg9, arg10, "null", "null", "null", "null"); + ivar8 = add(ivar8, 1); + } + return; +} diff --git a/dumps/scripts/1520.cs2 b/dumps/scripts/1520.cs2 new file mode 100644 index 0000000..39e22fe --- /dev/null +++ b/dumps/scripts/1520.cs2 @@ -0,0 +1,12 @@ +void script_1520() { + script_1522(49872906); + script_1522(49872907); + script_1522(49872908); + script_1522(49872909); + script_1522(49872910); + script_1522(49872911); + script_1522(49872915); + script_1522(49872916); + script_1522(49872917); + return; +} diff --git a/dumps/scripts/1521.cs2 b/dumps/scripts/1521.cs2 new file mode 100644 index 0000000..c975e79 --- /dev/null +++ b/dumps/scripts/1521.cs2 @@ -0,0 +1,4 @@ +void script_1521(int arg0) { + script_1522(arg0); + return; +} diff --git a/dumps/scripts/1522.cs2 b/dumps/scripts/1522.cs2 new file mode 100644 index 0000000..9ba2ca7 --- /dev/null +++ b/dumps/scripts/1522.cs2 @@ -0,0 +1,96 @@ +void script_1522(int arg0) { + if (bitconfig_4895 != 2) { + return; + } + if (standart_config_281 == 1000) { + setWidgetRGB(new Color(153, 255, 0), new WidgetPointer(arg0)); + return; + } + if (((boolean)standart_config_281)) { + setWidgetRGB(new Color(255, 30, 30), new WidgetPointer(arg0)); + return; + } + switch (arg0) { + case 49872906: + if (standart_config_281 >= 90) { + setWidgetRGB(new Color(153, 255, 0), new WidgetPointer(arg0)); + } else if (((boolean)standart_config_281)) { + setWidgetRGB(new Color(255, 30, 30), new WidgetPointer(arg0)); + } else { + setWidgetRGB(new Color(255, 255, 102), new WidgetPointer(arg0)); + } + break; + case 49872907: + if (standart_config_281 >= 180) { + setWidgetRGB(new Color(153, 255, 0), new WidgetPointer(arg0)); + } else if (standart_config_281 < 100) { + setWidgetRGB(new Color(255, 30, 30), new WidgetPointer(arg0)); + } else { + setWidgetRGB(new Color(255, 255, 102), new WidgetPointer(arg0)); + } + break; + case 49872908: + if (bitconfig_4926 >= 50) { + setWidgetRGB(new Color(153, 255, 0), new WidgetPointer(arg0)); + } else if (((boolean)bitconfig_4926)) { + setWidgetRGB(new Color(255, 30, 30), new WidgetPointer(arg0)); + } else { + setWidgetRGB(new Color(255, 255, 102), new WidgetPointer(arg0)); + } + break; + case 49872909: + if (bitconfig_4927 >= 20) { + setWidgetRGB(new Color(153, 255, 0), new WidgetPointer(arg0)); + } else if (((boolean)bitconfig_4927)) { + setWidgetRGB(new Color(255, 30, 30), new WidgetPointer(arg0)); + } else { + setWidgetRGB(new Color(255, 255, 102), new WidgetPointer(arg0)); + } + break; + case 49872910: + if (bitconfig_4928 >= 25) { + setWidgetRGB(new Color(153, 255, 0), new WidgetPointer(arg0)); + } else if (((boolean)bitconfig_4928)) { + setWidgetRGB(new Color(255, 30, 30), new WidgetPointer(arg0)); + } else { + setWidgetRGB(new Color(255, 255, 102), new WidgetPointer(arg0)); + } + break; + case 49872911: + if (bitconfig_4929 >= 25) { + setWidgetRGB(new Color(153, 255, 0), new WidgetPointer(arg0)); + } else if (((boolean)bitconfig_4929)) { + setWidgetRGB(new Color(255, 30, 30), new WidgetPointer(arg0)); + } else { + setWidgetRGB(new Color(255, 255, 102), new WidgetPointer(arg0)); + } + break; + case 49872915: + if (bitconfig_4935 >= 15) { + setWidgetRGB(new Color(153, 255, 0), new WidgetPointer(arg0)); + } else if (((boolean)bitconfig_4935)) { + setWidgetRGB(new Color(255, 30, 30), new WidgetPointer(arg0)); + } else { + setWidgetRGB(new Color(255, 255, 102), new WidgetPointer(arg0)); + } + break; + case 49872916: + if (bitconfig_4936 >= 20) { + setWidgetRGB(new Color(153, 255, 0), new WidgetPointer(arg0)); + } else if (((boolean)bitconfig_4936)) { + setWidgetRGB(new Color(255, 30, 30), new WidgetPointer(arg0)); + } else { + setWidgetRGB(new Color(255, 255, 102), new WidgetPointer(arg0)); + } + break; + case 49872917: + if (standart_config_281 == 1000) { + setWidgetRGB(new Color(153, 255, 0), new WidgetPointer(arg0)); + } else if (standart_config_281 < 190) { + setWidgetRGB(new Color(255, 30, 30), new WidgetPointer(arg0)); + } else { + setWidgetRGB(new Color(255, 255, 102), new WidgetPointer(arg0)); + } + } + return; +} diff --git a/dumps/scripts/1523.cs2 b/dumps/scripts/1523.cs2 new file mode 100644 index 0000000..783175d --- /dev/null +++ b/dumps/scripts/1523.cs2 @@ -0,0 +1,16 @@ +void script_1523() { + if (bitconfig_4895 == 2) { + createExtraChild(new WidgetPointer(275,9), 4, 0); + setWidgetPosition(0, -2, 0, 0); + setWidgetSize(102, 23, 0, 0); + setWidgetFont(645); + setWidgetTextAlignment(0, 1, 0); + setWidgetText("Back"); + setWidgetRGB(new Color(70, 50, 10)); + setWidgetUnknownBoolean(false); + setScriptCallOnMouseEntered(1356, new WidgetPointer(-32768,3), -2147483643, 16777215, "Iii"); + setScriptCallOnMouseExit(1356, new WidgetPointer(-32768,3), -2147483643, 4600330, "Iii"); + setWidgetContextMenuOption(1, new WidgetPointer(275,9), "Back to Index"); + } + return; +} diff --git a/dumps/scripts/1524.cs2 b/dumps/scripts/1524.cs2 new file mode 100644 index 0000000..8750ff7 --- /dev/null +++ b/dumps/scripts/1524.cs2 @@ -0,0 +1,7 @@ +void script_1524() { + if (setWidgetRegister(new WidgetPointer(275,9), 0)) { + deleteAllExtraChilds(new WidgetPointer(275,9)); + setWidgetContextMenuOption(1, new WidgetPointer(275,9), "null"); + } + return; +} diff --git a/dumps/scripts/1525.cs2 b/dumps/scripts/1525.cs2 new file mode 100644 index 0000000..e2985dc --- /dev/null +++ b/dumps/scripts/1525.cs2 @@ -0,0 +1,9 @@ +int script_1525() { + int ivar0; + ivar0 = 0; + ivar0 = add(add(add(add(add(add(add(add(add(add(add(add(add(bitconfig_5691, bitconfig_5692), bitconfig_5693), bitconfig_5694), bitconfig_5695), bitconfig_5696), bitconfig_5697), bitconfig_5698), bitconfig_5699), bitconfig_5700), bitconfig_5701), bitconfig_5702), bitconfig_5703), bitconfig_5704); + if (bitconfig_5705 == 3) { + ivar0 = add(ivar0, 1); + } + return ivar0; +} diff --git a/dumps/scripts/1526.cs2 b/dumps/scripts/1526.cs2 new file mode 100644 index 0000000..2220c04 --- /dev/null +++ b/dumps/scripts/1526.cs2 @@ -0,0 +1,9 @@ +int script_1526() { + int ivar0; + ivar0 = 0; + ivar0 = add(add(add(add(add(add(add(add(add(add(bitconfig_5706, bitconfig_5707), bitconfig_5723), bitconfig_5710), bitconfig_5711), bitconfig_5712), bitconfig_5713), bitconfig_5714), bitconfig_5715), bitconfig_5716), bitconfig_5717); + if (bitconfig_5709 == 3) { + ivar0 = add(ivar0, 1); + } + return ivar0; +} diff --git a/dumps/scripts/1527.cs2 b/dumps/scripts/1527.cs2 new file mode 100644 index 0000000..e1c3c6d --- /dev/null +++ b/dumps/scripts/1527.cs2 @@ -0,0 +1,3 @@ +int script_1527() { + return add(add(add(add(add(add(bitconfig_8114, bitconfig_8115), bitconfig_8116), bitconfig_8117), bitconfig_8118), bitconfig_8119), bitconfig_8120); +} diff --git a/dumps/scripts/1528.cs2 b/dumps/scripts/1528.cs2 new file mode 100644 index 0000000..57c648b --- /dev/null +++ b/dumps/scripts/1528.cs2 @@ -0,0 +1,12 @@ +int script_1528() { + int ivar0; + ivar0 = 0; + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + return ivar0; +} diff --git a/dumps/scripts/1529.cs2 b/dumps/scripts/1529.cs2 new file mode 100644 index 0000000..e5d8c1b --- /dev/null +++ b/dumps/scripts/1529.cs2 @@ -0,0 +1,12 @@ +int script_1529() { + int ivar0; + ivar0 = 0; + ivar0 = add(add(add(add(add(add(add(bitconfig_3567, bitconfig_3568), bitconfig_3569), bitconfig_3570), bitconfig_3571), bitconfig_3572), bitconfig_3574), bitconfig_3575); + if (bitconfig_3566 == 5) { + ivar0 = add(ivar0, 1); + } + if (bitconfig_3573 == 5) { + ivar0 = add(ivar0, 1); + } + return ivar0; +} diff --git a/dumps/scripts/153.cs2 b/dumps/scripts/153.cs2 new file mode 100644 index 0000000..1763fdd --- /dev/null +++ b/dumps/scripts/153.cs2 @@ -0,0 +1,31 @@ +void script_153(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,string arg6,string arg7,string arg8,string arg9,string arg10,string arg11,string arg12,string arg13,string arg14) { + int ivar6; + int ivar7; + int ivar8; + deleteAllExtraChilds(new WidgetPointer(arg0)); + ivar6 = 0; + ivar7 = 0; + if (arg2 > 1) { + if (getWidgetScrollMaxH(new WidgetPointer(arg0)) > 0) { + ivar6 = divide(subtract(getWidgetScrollMaxH(new WidgetPointer(arg0)), multiply(36, arg2)), subtract(arg2, 1)); + } else { + ivar6 = divide(subtract(getWidgetActualWidth(new WidgetPointer(arg0)), multiply(36, arg2)), subtract(arg2, 1)); + } + } + if (arg3 > 1) { + if (getWidgetScrollMaxV(new WidgetPointer(arg0)) > 0) { + ivar7 = divide(subtract(getWidgetScrollMaxV(new WidgetPointer(arg0)), multiply(32, arg3)), subtract(arg3, 1)); + } else { + ivar7 = divide(subtract(getWidgetActualHeight(new WidgetPointer(arg0)), multiply(32, arg3)), subtract(arg3, 1)); + } + } + ivar8 = 0; + while (ivar8 <= multiply(arg2, arg3)) { + createExtraChild(new WidgetPointer(arg0), 5, ivar8); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(multiply(add(36, ivar6), mod(ivar8, arg2)), multiply(divide(ivar8, arg2), add(32, ivar7)), 0, 0); + script_154(arg1, ivar8, arg0, ivar8, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + ivar8 = add(ivar8, 1); + } + return; +} diff --git a/dumps/scripts/1530.cs2 b/dumps/scripts/1530.cs2 new file mode 100644 index 0000000..c2b2fa0 --- /dev/null +++ b/dumps/scripts/1530.cs2 @@ -0,0 +1,9 @@ +int script_1530() { + int ivar0; + ivar0 = 0; + ivar0 = add(add(add(add(add(add(add(add(bitconfig_3600, bitconfig_3601), bitconfig_3602), bitconfig_3603), bitconfig_3604), bitconfig_3605), bitconfig_3606), bitconfig_3608), bitconfig_3609); + if (bitconfig_3607 == 5) { + ivar0 = add(ivar0, 1); + } + return ivar0; +} diff --git a/dumps/scripts/1531.cs2 b/dumps/scripts/1531.cs2 new file mode 100644 index 0000000..d128023 --- /dev/null +++ b/dumps/scripts/1531.cs2 @@ -0,0 +1,13 @@ +int script_1531() { + int ivar0; + ivar0 = 0; + ivar0 = add(ivar0, bitconfig_8121); + ivar0 = add(ivar0, bitconfig_8122); + ivar0 = add(ivar0, bitconfig_8123); + ivar0 = add(ivar0, bitconfig_8124); + ivar0 = add(ivar0, bitconfig_8125); + ivar0 = add(ivar0, bitconfig_8126); + ivar0 = add(ivar0, bitconfig_8127); + ivar0 = add(ivar0, bitconfig_8128); + return ivar0; +} diff --git a/dumps/scripts/1532.cs2 b/dumps/scripts/1532.cs2 new file mode 100644 index 0000000..838b346 --- /dev/null +++ b/dumps/scripts/1532.cs2 @@ -0,0 +1,13 @@ +int script_1532() { + int ivar0; + ivar0 = 0; + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + return ivar0; +} diff --git a/dumps/scripts/1533.cs2 b/dumps/scripts/1533.cs2 new file mode 100644 index 0000000..5300c0e --- /dev/null +++ b/dumps/scripts/1533.cs2 @@ -0,0 +1,4 @@ +void script_1533(int arg0) { + script_2308(arg0, globalint_119); + return; +} diff --git a/dumps/scripts/1534.cs2 b/dumps/scripts/1534.cs2 new file mode 100644 index 0000000..c9e935a --- /dev/null +++ b/dumps/scripts/1534.cs2 @@ -0,0 +1,15 @@ +void script_1534(int arg0,int arg1) { + if (arg1 != 1) { + return; + } + if (((boolean)globalint_1413)) { + return; + } + if (((boolean)globalint_119)) { + globalint_119 = 0; + } else { + globalint_119 = 1; + } + script_1741(arg0); + return; +} diff --git a/dumps/scripts/1535.cs2 b/dumps/scripts/1535.cs2 new file mode 100644 index 0000000..ede060f --- /dev/null +++ b/dumps/scripts/1535.cs2 @@ -0,0 +1,16 @@ +void script_1535(int arg0,int arg1) { + switch (arg0) { + case 0: + bitconfig_9222 = arg1; + break; + case 1: + bitconfig_9223 = arg1; + break; + case 2: + bitconfig_9224 = arg1; + break; + case 3: + bitconfig_9225 = arg1; + } + return; +} diff --git a/dumps/scripts/1536.cs2 b/dumps/scripts/1536.cs2 new file mode 100644 index 0000000..5cf3211 --- /dev/null +++ b/dumps/scripts/1536.cs2 @@ -0,0 +1,8 @@ +void script_1536(int arg0) { + setScriptCallOnConfigChange(1537, 1747, 1, "Y", new WidgetPointer(arg0)); + setScriptCallOnItemContainerUpdate(1538, 93, 94, 530, 3, "Y", new WidgetPointer(arg0)); + setScriptCallOnGlobalStringChange(1539, 352, 1, "Y", new WidgetPointer(arg0)); + script_4592(); + script_4597(); + return; +} diff --git a/dumps/scripts/1537.cs2 b/dumps/scripts/1537.cs2 new file mode 100644 index 0000000..9c56683 --- /dev/null +++ b/dumps/scripts/1537.cs2 @@ -0,0 +1,5 @@ +void script_1537() { + script_4592(); + script_4597(); + return; +} diff --git a/dumps/scripts/1538.cs2 b/dumps/scripts/1538.cs2 new file mode 100644 index 0000000..6d0ee9d --- /dev/null +++ b/dumps/scripts/1538.cs2 @@ -0,0 +1,4 @@ +void script_1538() { + script_4592(); + return; +} diff --git a/dumps/scripts/1539.cs2 b/dumps/scripts/1539.cs2 new file mode 100644 index 0000000..2d626d5 --- /dev/null +++ b/dumps/scripts/1539.cs2 @@ -0,0 +1,4 @@ +void script_1539() { + script_4597(); + return; +} diff --git a/dumps/scripts/154.cs2 b/dumps/scripts/154.cs2 new file mode 100644 index 0000000..bc2907b --- /dev/null +++ b/dumps/scripts/154.cs2 @@ -0,0 +1,46 @@ +void script_154(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,string arg6,string arg7,string arg8,string arg9,string arg10,string arg11,string arg12,string arg13,string arg14) { + string svar9; + svar9 = ""; + if (setWidgetRegister(new WidgetPointer(arg2), arg3)) { + if (getItemIdInSlot(arg0, arg1) != -1) { + svar9 = "" + getItemName(getItemIdInSlot(arg0, arg1)); + setItemOnWidgetMethod1200(getItemIdInSlot(arg0, arg1), getItemAmtInSlot(arg0, arg1)); + cs2method1305(svar9); + setWidgetContextMenuOption(1, arg6); + setWidgetContextMenuOption(2, arg7); + setWidgetContextMenuOption(3, arg8); + setWidgetContextMenuOption(4, arg9); + setWidgetContextMenuOption(5, arg10); + setWidgetContextMenuOption(6, arg11); + setWidgetContextMenuOption(7, arg12); + setWidgetContextMenuOption(8, arg13); + setWidgetContextMenuOption(9, arg14); + setWidgetContextMenuOption(10, "Examine" + ""); + if (arg4 > 0) { + cs2method1303(5); + cs2method1304(10); + } + if (((boolean)arg4)) { + setScriptCallOnMouseDragReleased(155, arg0, -2147483643, -2147483641, new WidgetPointer(-32768,3), arg4, new WidgetPointer(arg5), arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, "viiIiIsssssssss"); + } else { + if (arg4 == 2) { + setScriptCallOnMouseDragReleased(156, arg0, -2147483643, -2147483641, new WidgetPointer(-32768,3), arg4, new WidgetPointer(arg5), arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, "viiIiIsssssssss"); + } + } + if ((arg4 != 0) && (arg5 != -1)) { + setScriptCallOnMouseDragged(162, arg1, new WidgetPointer(arg2), new WidgetPointer(arg5), -2147483646, "iIIi"); + } + setWidgetShadowColor(new Color(48, 32, 32)); + setWidgetBorderThickness(1); + } else { + setItemOnWidgetMethod1205(-1, 0); + setWidgetNoOptions(); + if (arg4 > 0) { + cs2method1303(0); + cs2method1304(0); + } + setScriptCallOnMouseDragReleased(-1, ""); + } + } + return; +} diff --git a/dumps/scripts/1540.cs2 b/dumps/scripts/1540.cs2 new file mode 100644 index 0000000..1e7098c --- /dev/null +++ b/dumps/scripts/1540.cs2 @@ -0,0 +1,60 @@ +void script_1540(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + string svar0; + string svar1; + string stack_dump0; + int stack_dump1; + deleteAllExtraChilds(new WidgetPointer(arg0)); + ivar1 = 0; + ivar2 = 0; + ivar1 = divide(subtract(getWidgetActualWidth(new WidgetPointer(arg0)), multiply(36, 4)), 3); + ivar2 = divide(subtract(getWidgetActualHeight(new WidgetPointer(arg0)), multiply(32, 7)), 6); + ivar3 = 0; + ivar4 = getItemContainerLength(93); + ivar5 = -1; + ivar6 = 0; + svar0 = ""; + svar1 = ""; + while (ivar3 < ivar4) { + createExtraChild(new WidgetPointer(arg0), 5, ivar3); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(multiply(add(36, ivar1), mod(ivar3, 4)), multiply(divide(ivar3, 4), add(32, ivar2)), 0, 0); + ivar5 = getItemIdInSlot(93, ivar3); + if (ivar5 != -1) { + ivar6 = getItemAmtInContainer(93, ivar5); + stack_dump0 = getItemHashmapData(ivar5, 1264); + svar1 = getItemHashmapData(ivar5, 1265); + svar0 = stack_dump0; + if (strLength(svar0) <= 0) { + if (isBitFlagged(globalint_96, ivar3)) { + svar0 = getItemOption(ivar5, 2); + } else { + if (isBitFlagged(globalint_95, ivar3)) { + svar0 = "Eat"; + } + } + } + } else { + stack_dump1 = 0; + stack_dump0 = ""; + svar1 = ""; + stack_dump1 = stack_dump1; + svar0 = stack_dump0; + ivar6 = stack_dump1; + } + if (ivar6 > 5) { + script_154(93, ivar3, arg0, ivar3, 1, -1, "Deposit-1", "Deposit-5", "Deposit-10", "Deposit-" + intToStr(standart_config_1249), "Deposit-X", "Deposit-All", "", svar0, svar1); + } else if (ivar6 > 1) { + script_154(93, ivar3, arg0, ivar3, 1, -1, "Deposit-1", "Deposit-5", "", "Deposit-" + intToStr(standart_config_1249), "Deposit-X", "Deposit-All", "", svar0, svar1); + } else { + script_154(93, ivar3, arg0, ivar3, 1, -1, "Deposit", "", "", "", "", "", "", svar0, svar1); + } + ivar3 = add(ivar3, 1); + } + return; +} diff --git a/dumps/scripts/1541.cs2 b/dumps/scripts/1541.cs2 new file mode 100644 index 0000000..c6ba593 --- /dev/null +++ b/dumps/scripts/1541.cs2 @@ -0,0 +1,28 @@ +int script_1541() { + int ivar0; + ivar0 = 0; + ivar0 = add(ivar0, bitconfig_4949); + ivar0 = add(ivar0, bitconfig_4950); + ivar0 = add(ivar0, bitconfig_4951); + ivar0 = add(ivar0, bitconfig_4952); + ivar0 = add(ivar0, bitconfig_4953); + ivar0 = add(ivar0, bitconfig_4954); + ivar0 = add(ivar0, bitconfig_4955); + ivar0 = add(ivar0, bitconfig_4956); + ivar0 = add(ivar0, bitconfig_4957); + ivar0 = add(ivar0, bitconfig_4958); + ivar0 = add(ivar0, bitconfig_4959); + ivar0 = add(ivar0, bitconfig_4960); + ivar0 = add(ivar0, bitconfig_4961); + ivar0 = add(ivar0, bitconfig_4962); + ivar0 = add(ivar0, bitconfig_4963); + ivar0 = add(ivar0, bitconfig_4964); + ivar0 = add(ivar0, bitconfig_4965); + ivar0 = add(ivar0, bitconfig_4966); + ivar0 = add(ivar0, bitconfig_4967); + ivar0 = add(ivar0, bitconfig_4968); + ivar0 = add(ivar0, bitconfig_4969); + ivar0 = add(ivar0, bitconfig_4970); + ivar0 = add(ivar0, bitconfig_4971); + return ivar0; +} diff --git a/dumps/scripts/1542.cs2 b/dumps/scripts/1542.cs2 new file mode 100644 index 0000000..7e51c37 --- /dev/null +++ b/dumps/scripts/1542.cs2 @@ -0,0 +1,28 @@ +int script_1542() { + int ivar0; + ivar0 = 0; + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + return ivar0; +} diff --git a/dumps/scripts/1543.cs2 b/dumps/scripts/1543.cs2 new file mode 100644 index 0000000..bbcd09e --- /dev/null +++ b/dumps/scripts/1543.cs2 @@ -0,0 +1,24 @@ +int script_1543() { + int ivar0; + ivar0 = 0; + ivar0 = add(ivar0, bitconfig_4972); + ivar0 = add(ivar0, bitconfig_4973); + ivar0 = add(ivar0, bitconfig_4974); + ivar0 = add(ivar0, bitconfig_4975); + ivar0 = add(ivar0, bitconfig_4976); + ivar0 = add(ivar0, bitconfig_4977); + ivar0 = add(ivar0, bitconfig_4978); + ivar0 = add(ivar0, bitconfig_4979); + ivar0 = add(ivar0, bitconfig_4980); + ivar0 = add(ivar0, bitconfig_4981); + ivar0 = add(ivar0, bitconfig_4982); + ivar0 = add(ivar0, bitconfig_4983); + ivar0 = add(ivar0, bitconfig_4984); + ivar0 = add(ivar0, bitconfig_4985); + ivar0 = add(ivar0, bitconfig_4986); + ivar0 = add(ivar0, bitconfig_4987); + ivar0 = add(ivar0, bitconfig_4988); + ivar0 = add(ivar0, bitconfig_4989); + ivar0 = add(ivar0, bitconfig_4991); + return ivar0; +} diff --git a/dumps/scripts/1544.cs2 b/dumps/scripts/1544.cs2 new file mode 100644 index 0000000..d3bdf15 --- /dev/null +++ b/dumps/scripts/1544.cs2 @@ -0,0 +1,24 @@ +int script_1544() { + int ivar0; + ivar0 = 0; + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + return ivar0; +} diff --git a/dumps/scripts/1545.cs2 b/dumps/scripts/1545.cs2 new file mode 100644 index 0000000..ac85130 --- /dev/null +++ b/dumps/scripts/1545.cs2 @@ -0,0 +1,17 @@ +int script_1545() { + int ivar0; + ivar0 = 0; + ivar0 = add(ivar0, bitconfig_4992); + ivar0 = add(ivar0, bitconfig_4993); + ivar0 = add(ivar0, bitconfig_4994); + ivar0 = add(ivar0, bitconfig_4995); + ivar0 = add(ivar0, bitconfig_4996); + ivar0 = add(ivar0, bitconfig_4997); + ivar0 = add(ivar0, bitconfig_4998); + ivar0 = add(ivar0, bitconfig_4999); + ivar0 = add(ivar0, bitconfig_5998); + ivar0 = add(ivar0, bitconfig_5001); + ivar0 = add(ivar0, bitconfig_5002); + ivar0 = add(ivar0, bitconfig_5003); + return ivar0; +} diff --git a/dumps/scripts/1546.cs2 b/dumps/scripts/1546.cs2 new file mode 100644 index 0000000..24a0319 --- /dev/null +++ b/dumps/scripts/1546.cs2 @@ -0,0 +1,17 @@ +int script_1546() { + int ivar0; + ivar0 = 0; + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + return ivar0; +} diff --git a/dumps/scripts/1547.cs2 b/dumps/scripts/1547.cs2 new file mode 100644 index 0000000..e31bb22 --- /dev/null +++ b/dumps/scripts/1547.cs2 @@ -0,0 +1,6 @@ +void script_1547() { + if (((boolean)globalint_5)) { + script_1548(0); + } + return; +} diff --git a/dumps/scripts/1548.cs2 b/dumps/scripts/1548.cs2 new file mode 100644 index 0000000..0c14841 --- /dev/null +++ b/dumps/scripts/1548.cs2 @@ -0,0 +1,13 @@ +void script_1548(int arg0) { + if (((boolean)arg0) || (arg0 == globalint_5)) { + setWidgetIsHidden(true, new WidgetPointer(752,3)); + setWidgetIsHidden(true, new WidgetPointer(752,7)); + setWidgetIsHidden(false, new WidgetPointer(752,8)); + script_2026(); + globalint_5 = 0; + } + if (getDisplayMode() >= 2) { + script_1364(); + } + return; +} diff --git a/dumps/scripts/1549.cs2 b/dumps/scripts/1549.cs2 new file mode 100644 index 0000000..34ead91 --- /dev/null +++ b/dumps/scripts/1549.cs2 @@ -0,0 +1,19 @@ +void script_1549() { + if (((boolean)globalint_11)) { + script_675(); + } + if (getDisplayMode() >= 2) { + setWidgetIsHidden(false, new WidgetPointer(746,73)); + } + setWidgetIsHidden(false, new WidgetPointer(752,3)); + setWidgetIsHidden(true, new WidgetPointer(752,7)); + setWidgetIsHidden(true, new WidgetPointer(752,8)); + setWidgetText(new WidgetPointer(752,4), "Enter the name of the item you wish to search for:"); + globalint_5 = 11; + script_1564(""); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(752,3)); + script_2026(); + setScriptCallOnKeyPress(112, -2147483640, false, "iz", new WidgetPointer(752,5)); + script_1188(); + return; +} diff --git a/dumps/scripts/155.cs2 b/dumps/scripts/155.cs2 new file mode 100644 index 0000000..9834ab4 --- /dev/null +++ b/dumps/scripts/155.cs2 @@ -0,0 +1,9 @@ +void script_155(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,string arg6,string arg7,string arg8,string arg9,string arg10,string arg11,string arg12,string arg13,string arg14) { + if (arg2 == -1) { + script_154(arg0, arg1, arg3, arg1, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + return; + } + script_154(arg0, arg1, arg3, arg2, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + script_154(arg0, arg2, arg3, arg1, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + return; +} diff --git a/dumps/scripts/1550.cs2 b/dumps/scripts/1550.cs2 new file mode 100644 index 0000000..66d12c1 --- /dev/null +++ b/dumps/scripts/1550.cs2 @@ -0,0 +1,11 @@ +void script_1550(int arg0) { + if (getWidgetActualX(new WidgetPointer(arg0)) < subtract(getWidgetActualWidth(new WidgetPointer(306,1)), 1)) { + if (getWidgetActualX(new WidgetPointer(arg0)) == add(140, getWidgetActualWidth(new WidgetPointer(arg0)))) { + setScriptCallOnGameloop(2321, new WidgetPointer(306,8), "I", new WidgetPointer(306,21)); + } + setWidgetPosition(add(1, getWidgetActualX(new WidgetPointer(arg0))), getWidgetActualY(new WidgetPointer(arg0)), 0, 0, new WidgetPointer(arg0)); + } else { + script_2056(); + } + return; +} diff --git a/dumps/scripts/1551.cs2 b/dumps/scripts/1551.cs2 new file mode 100644 index 0000000..4852622 --- /dev/null +++ b/dumps/scripts/1551.cs2 @@ -0,0 +1,8 @@ +int script_1551(int arg0,int arg1,int arg2,string arg3) { + arg3 = script_1602(arg3); + arg0 = min(strLength(arg3), arg0); + if (arg0 <= 0) { + return arg2; + } + return add(getTextWidth(arg1, substr(0, arg0, arg3)), arg2); +} diff --git a/dumps/scripts/1552.cs2 b/dumps/scripts/1552.cs2 new file mode 100644 index 0000000..bacc66d --- /dev/null +++ b/dumps/scripts/1552.cs2 @@ -0,0 +1,10 @@ +int script_1552(int arg0,int arg1,int arg2,int arg3,string arg4) { + int ivar4; + ivar4 = 0; + if (setWidgetRegister(new WidgetPointer(arg2), arg3) || ((arg3 == -1) && setWidgetRegister(new WidgetPointer(arg2)))) { + ivar4 = add(getWidgetActualX(), divide(getWidgetActualWidth(), 2)); + } else { + return 0; + } + return script_1551(arg0, arg1, subtract(ivar4, divide(getTextWidth(arg1, script_1602(arg4)), 2)), arg4); +} diff --git a/dumps/scripts/1553.cs2 b/dumps/scripts/1553.cs2 new file mode 100644 index 0000000..e9faa27 --- /dev/null +++ b/dumps/scripts/1553.cs2 @@ -0,0 +1,46 @@ +int script_1553(int arg0,int arg1,string arg2) { + int ivar2; + int ivar3; + int ivar4; + ivar2 = 0; + ivar3 = 0; + ivar4 = 0; + switch (arg0) { + case 96: + return max(subtract(arg1, 1), 0); + case 97: + return min(add(arg1, 1), strLength(arg2)); + case 98: + ivar2 = subtract(arg1, 1); + if ((arg1 > 0) && (strIndexof(ivar2, arg2, " ") == ivar2)) { + return ivar2; + } + ivar2 = -1; + ivar3 = -1; + while (ivar4 != 1) { + ivar2 = strIndexof(add(ivar2, 1), arg2, " "); + if ((ivar2 == -1) || (ivar2 >= subtract(arg1, 1))) { + ivar4 = 1; + } else { + ivar3 = ivar2; + } + } + return min(add(ivar3, 1), strLength(arg2)); + case 99: + if (strIndexof(arg1, arg2, " ") == arg1) { + return min(add(arg1, 1), strLength(arg2)); + } + ivar2 = strLength(arg2); + if (arg1 < ivar2) { + ivar3 = strIndexof(add(arg1, 1), arg2, " "); + if (ivar3 != -1) { + return ivar3; + } + return ivar2; + } + break; + case 102: + return 0; + } + return strLength(arg2); +} diff --git a/dumps/scripts/1554.cs2 b/dumps/scripts/1554.cs2 new file mode 100644 index 0000000..68c2678 --- /dev/null +++ b/dumps/scripts/1554.cs2 @@ -0,0 +1,5 @@ +void script_1554(int arg0,int arg1) { + globalint_1028 = script_1401(arg0, 495, arg1, globalstring_1); + script_1555(arg1); + return; +} diff --git a/dumps/scripts/1555.cs2 b/dumps/scripts/1555.cs2 new file mode 100644 index 0000000..08a618c --- /dev/null +++ b/dumps/scripts/1555.cs2 @@ -0,0 +1,32 @@ +void script_1555(int arg0) { + int ivar1; + int ivar2; + int ivar3; + string svar0; + setWidgetPosition(script_1551(globalint_1028, 495, arg0, globalstring_1), getWidgetActualY(new WidgetPointer(137,57)), 0, 0, new WidgetPointer(137,57)); + ivar1 = getWidgetActualWidth(new WidgetPointer(137,55)); + ivar2 = strLength(globalstring_1); + svar0 = ""; + if (globalint_1028 > 0) { + svar0 = substr(0, min(globalint_1028, ivar2), globalstring_1); + } + ivar3 = subtract(getTextWidth(495, svar0), ivar1); + setWidgetPosition(0, 0, 0, 2, new WidgetPointer(137,56)); + setWidgetSize(max(getTextWidth(495, getWidgetText(new WidgetPointer(137,56))), ivar1), getWidgetActualHeight(new WidgetPointer(137,56)), 0, 0, new WidgetPointer(137,56)); + if (ivar3 > 0) { + setWidgetPosition(subtract(getWidgetActualX(new WidgetPointer(137,56)), ivar3), 0, 0, 2, new WidgetPointer(137,56)); + setWidgetPosition(subtract(getWidgetActualX(new WidgetPointer(137,57)), ivar3), 0, 0, 1, new WidgetPointer(137,57)); + } + if (strLength(globalstring_1) <= 0) { + setWidgetIsHidden(true, new WidgetPointer(137,57)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(137,56)); + } else { + if (hasWindowFocus()) { + setWidgetIsHidden(false, new WidgetPointer(137,57)); + } else { + setWidgetIsHidden(true, new WidgetPointer(137,57)); + } + setScriptCallOnGameloop(1400, getClientCycle(), new WidgetPointer(137,57), "iI", new WidgetPointer(137,56)); + } + return; +} diff --git a/dumps/scripts/1556.cs2 b/dumps/scripts/1556.cs2 new file mode 100644 index 0000000..d672646 --- /dev/null +++ b/dumps/scripts/1556.cs2 @@ -0,0 +1,5 @@ +void script_1556(int arg0,int arg1,int arg2) { + globalint_1029 = script_1504(arg0, 496, arg1, arg2, globalstring_22); + script_1557(); + return; +} diff --git a/dumps/scripts/1557.cs2 b/dumps/scripts/1557.cs2 new file mode 100644 index 0000000..3f5b179 --- /dev/null +++ b/dumps/scripts/1557.cs2 @@ -0,0 +1,10 @@ +void script_1557() { + setWidgetPosition(script_1552(globalint_1029, 496, 49283077, -1, globalstring_22), getWidgetActualY(new WidgetPointer(752,6)), 0, 0, new WidgetPointer(752,6)); + if (hasWindowFocus()) { + setWidgetIsHidden(false, new WidgetPointer(752,6)); + } else { + setWidgetIsHidden(true, new WidgetPointer(752,6)); + } + setScriptCallOnGameloop(1400, getClientCycle(), new WidgetPointer(752,6), "iI", new WidgetPointer(752,5)); + return; +} diff --git a/dumps/scripts/1558.cs2 b/dumps/scripts/1558.cs2 new file mode 100644 index 0000000..4417ebe --- /dev/null +++ b/dumps/scripts/1558.cs2 @@ -0,0 +1,68 @@ +void script_1558(int arg0) { + if (((boolean)script_2709()) && (standart_config_281 == 1000)) { + setWidgetText(new WidgetPointer(137,56), ""); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(137,56)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(137,56)); + setWidgetIsHidden(true, new WidgetPointer(137,57)); + setWidgetPosition(0, 72, 0, 0, new WidgetPointer(137,58)); + setWidgetSize(488, 72, 0, 1, new WidgetPointer(137,58)); + setWidgetPosition(0, 72, 2, 0, new WidgetPointer(137,59)); + setWidgetSize(16, 72, 0, 1, new WidgetPointer(137,59)); + setWidgetIsHidden(true, new WidgetPointer(137,51)); + setWidgetIsHidden(true, new WidgetPointer(137,52)); + setWidgetIsHidden(true, new WidgetPointer(137,53)); + setWidgetIsHidden(true, new WidgetPointer(137,56)); + setWidgetIsHidden(false, new WidgetPointer(137,60)); + return; + } + setWidgetIsHidden(false, new WidgetPointer(137,57)); + setWidgetPosition(0, 0, 0, 0, new WidgetPointer(137,58)); + setWidgetSize(488, 18, 0, 1, new WidgetPointer(137,58)); + setWidgetPosition(0, 0, 2, 0, new WidgetPointer(137,59)); + setWidgetSize(16, 18, 0, 1, new WidgetPointer(137,59)); + setWidgetIsHidden(false, new WidgetPointer(137,51)); + setWidgetIsHidden(false, new WidgetPointer(137,52)); + setWidgetIsHidden(false, new WidgetPointer(137,53)); + setWidgetIsHidden(false, new WidgetPointer(137,56)); + setWidgetIsHidden(true, new WidgetPointer(137,60)); + if (((boolean)arg0) && (cs2method6900() || isMuteRelatedMethod3329())) { + setWidgetText(new WidgetPointer(137,56), "Left-click here to enter Public Quick Chat or right-click for Friends Channel Quick Chat."); + setWidgetPosition(0, 0, 1, 1, new WidgetPointer(137,54)); + setWidgetSize(0, 0, 1, 1, new WidgetPointer(137,54)); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(137,56)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(137,56)); + setWidgetIsHidden(true, new WidgetPointer(137,57)); + return; + } + if (((boolean)globalint_1650)) { + setWidgetText(new WidgetPointer(137,54), "To " + globalstring_23 + ":"); + } else if (globalint_1651 == 2) { + setWidgetText(new WidgetPointer(137,54), "Clan Chat" + "" + ":"); + } else if (globalint_1651 == 3) { + setWidgetText(new WidgetPointer(137,54), "Guest Clan Chat" + "" + ":"); + } else if (((boolean)globalint_1651)) { + setWidgetText(new WidgetPointer(137,54), "Friends Chat" + "" + ":"); + } else { + setWidgetText(new WidgetPointer(137,54), cs2method5015() + "" + ":"); + } + if (getDisplayMode() >= 2) { + setWidgetRGB(new Color(127, 169, 255), new WidgetPointer(137,56)); + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(137,54)); + } else { + setWidgetRGB(new Color(0, 0, 255), new WidgetPointer(137,56)); + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(137,54)); + } + setWidgetText(new WidgetPointer(137,56), replaceLtGt(globalstring_1)); + setWidgetSize(getTextWidth(495, getWidgetText(new WidgetPointer(137,54))), getWidgetActualHeight(new WidgetPointer(137,54)), 0, 0, new WidgetPointer(137,54)); + setWidgetPosition(add(add(getWidgetActualX(new WidgetPointer(137,54)), getWidgetActualWidth(new WidgetPointer(137,54))), 2), 0, 0, 2, new WidgetPointer(137,55)); + setWidgetSize(subtract(subtract(getWidgetActualWidth(new WidgetPointer(137,50)), getWidgetActualX(new WidgetPointer(137,55))), 5), getWidgetActualHeight(new WidgetPointer(137,55)), 0, 0, new WidgetPointer(137,55)); + setScriptCallOnMousePressed(1554, -2147483647, 0, "ii", new WidgetPointer(137,56)); + globalint_1028 = max(min(globalint_1028, strLength(replaceLtGt(globalstring_1))), 0); + script_1555(0); + if (strLength(cs2method5015()) > 0) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(137,58)); + } else { + setScriptCallOnGameloop(4308, arg0, "1", new WidgetPointer(137,58)); + } + return; +} diff --git a/dumps/scripts/1559.cs2 b/dumps/scripts/1559.cs2 new file mode 100644 index 0000000..511821f --- /dev/null +++ b/dumps/scripts/1559.cs2 @@ -0,0 +1,8 @@ +void script_1559(int arg0) { + if (cs2method5428(49283081, -1)) { + return; + } + setScriptCallOnGameloop(-1, "", new WidgetPointer(752,9)); + script_1560(arg0); + return; +} diff --git a/dumps/scripts/156.cs2 b/dumps/scripts/156.cs2 new file mode 100644 index 0000000..63011eb --- /dev/null +++ b/dumps/scripts/156.cs2 @@ -0,0 +1,21 @@ +void script_156(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,string arg6,string arg7,string arg8,string arg9,string arg10,string arg11,string arg12,string arg13,string arg14) { + int ivar6; + if (arg2 == -1) { + script_154(arg0, arg1, arg3, arg1, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + return; + } + ivar6 = arg1; + while (ivar6 != arg2) { + if (ivar6 > arg2) { + script_154(arg0, subtract(ivar6, 1), arg3, ivar6, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + ivar6 = subtract(ivar6, 1); + } else { + if (ivar6 < arg2) { + script_154(arg0, add(ivar6, 1), arg3, ivar6, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + ivar6 = add(ivar6, 1); + } + } + } + script_154(arg0, arg1, arg3, arg2, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + return; +} diff --git a/dumps/scripts/1560.cs2 b/dumps/scripts/1560.cs2 new file mode 100644 index 0000000..6d7ef87 --- /dev/null +++ b/dumps/scripts/1560.cs2 @@ -0,0 +1,10 @@ +void script_1560(int arg0) { + if ((((boolean)arg0) && (isWidgetOpen(new WidgetPointer(752,10)) || isWidgetOpen(new WidgetPointer(752,11)))) && (((((((((boolean)cs2method5004(0)) || (cs2method5004(0) == 4)) || (cs2method5004(0) == 27)) || (cs2method5004(0) == 28)) || (cs2method5004(0) == 29)) || (cs2method5004(0) == 26)) || (cs2method5004(0) == 30)) || (cs2method5004(0) == 31))) { + script_1561(); + } + script_84(); + script_89(); + script_192(); + script_178(); + return; +} diff --git a/dumps/scripts/1561.cs2 b/dumps/scripts/1561.cs2 new file mode 100644 index 0000000..69ea716 --- /dev/null +++ b/dumps/scripts/1561.cs2 @@ -0,0 +1,25 @@ +void script_1561() { + int ivar0; + int ivar1; + string svar0; + string svar1; + svar0 = cs2method5003(0); + ivar0 = 1; + ivar1 = 0; + svar1 = ""; + while (((boolean)ivar1) && (ivar0 < cs2method5017())) { + svar1 = cs2method5003(ivar0); + if ((((cs2method5004(ivar0) != 0) && (cs2method5004(ivar0) != 4)) && ((cs2method5004(ivar0) != 27) && (cs2method5004(ivar0) != 28))) && (((cs2method5004(ivar0) != 29) && (cs2method5004(ivar0) != 26)) && ((cs2method5004(ivar0) != 30) && (cs2method5004(ivar0) != 31)))) { + ivar1 = 1; + } else if (cs2method5024(ivar0) <= globalint_1269) { + ivar1 = 1; + } else if (strLength(strRemoveEntities(svar1)) > 0) { + svar0 = concat(concat(svar1, "
"), svar0); + } else { + svar0 = concat("
", svar0); + } + ivar0 = add(ivar0, 1); + } + script_102(svar0); + return; +} diff --git a/dumps/scripts/1562.cs2 b/dumps/scripts/1562.cs2 new file mode 100644 index 0000000..5487a79 --- /dev/null +++ b/dumps/scripts/1562.cs2 @@ -0,0 +1,8 @@ +void script_1562() { + if (cs2method5428(49414144, -1)) { + return; + } + setScriptCallOnGameloop(-1, "", new WidgetPointer(754,0)); + script_89(); + return; +} diff --git a/dumps/scripts/1563.cs2 b/dumps/scripts/1563.cs2 new file mode 100644 index 0000000..ce681f2 --- /dev/null +++ b/dumps/scripts/1563.cs2 @@ -0,0 +1,76 @@ +int script_1563(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10) { + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int stack_dump0; + int stack_dump1; + int stack_dump2; + int stack_dump3; + int stack_dump4; + int stack_dump5; + int stack_dump6; + cs2func_script_296_struct(2,0,0) structdump_7; + cs2func_script_296_struct(2,0,0) structdump_8; + ivar11 = 0; + ivar12 = 0; + stack_dump0 = arg0; + stack_dump1 = arg2; + stack_dump2 = arg5; + stack_dump3 = arg6; + stack_dump4 = arg7; + stack_dump5 = arg8; + stack_dump6 = arg9; + structdump_7 = script_296(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4, stack_dump5, stack_dump6); + ivar12 = structdump_7.intpart_1; + ivar11 = structdump_7.intpart_0; + ivar13 = 0; + ivar14 = 0; + stack_dump0 = arg1; + stack_dump1 = arg2; + stack_dump2 = arg5; + stack_dump3 = arg6; + stack_dump4 = arg7; + stack_dump5 = arg8; + stack_dump6 = arg9; + structdump_8 = script_296(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4, stack_dump5, stack_dump6); + ivar14 = structdump_8.intpart_1; + ivar13 = structdump_8.intpart_0; + ivar15 = add(ivar11, divide(subtract(ivar13, ivar11), 2)); + ivar16 = add(ivar12, divide(subtract(ivar14, ivar12), 2)); + ivar17 = subtract(ivar13, ivar11); + ivar18 = subtract(ivar14, ivar12); + stack_dump0 = max(ivar17, subtract(0, ivar17)); + ivar18 = max(ivar18, subtract(0, ivar18)); + ivar17 = stack_dump0; + if (setWidgetRegister(new WidgetPointer(arg5), arg10)) { + setWidgetPosition(ivar15, ivar16, 1, 1); + setWidgetSize(ivar17, ivar18, 0, 0); + } else { + createExtraChild(new WidgetPointer(arg5), 3, arg10); + setWidgetPosition(ivar15, ivar16, 1, 1); + setWidgetSize(ivar17, ivar18, 0, 0); + setWidgetRGB(new Color(arg3)); + setWidgetFilled(0); + cs2method2103(0); + } + arg10 = add(arg10, 1); + ivar17 = add(ivar17, multiply(2, arg4)); + ivar18 = add(ivar18, multiply(2, arg4)); + if (setWidgetRegister(new WidgetPointer(arg5), arg10)) { + setWidgetPosition(ivar15, ivar16, 1, 1); + setWidgetSize(ivar17, ivar18, 0, 0); + } else { + createExtraChild(new WidgetPointer(arg5), 3, arg10); + setWidgetPosition(ivar15, ivar16, 1, 1); + setWidgetSize(ivar17, ivar18, 0, 0); + setWidgetRGB(new Color(arg3)); + setWidgetFilled(0); + cs2method2103(0); + } + return add(arg10, 1); +} diff --git a/dumps/scripts/1564.cs2 b/dumps/scripts/1564.cs2 new file mode 100644 index 0000000..1108c7a --- /dev/null +++ b/dumps/scripts/1564.cs2 @@ -0,0 +1,8 @@ +void script_1564(string arg0) { + setWidgetText(new WidgetPointer(752,5), replaceLtGt(arg0)); + globalstring_22 = arg0; + globalint_1029 = strLength(arg0); + setScriptCallOnMousePressed(1556, -2147483647, new WidgetPointer(-32768,3), -2147483643, "iIi", new WidgetPointer(752,5)); + script_1557(); + return; +} diff --git a/dumps/scripts/1565.cs2 b/dumps/scripts/1565.cs2 new file mode 100644 index 0000000..be9baaa --- /dev/null +++ b/dumps/scripts/1565.cs2 @@ -0,0 +1,18 @@ +void script_1565() { + setWidgetFont(307, new WidgetPointer(210,1)); + setWidgetFont(307, new WidgetPointer(211,1)); + setWidgetFont(307, new WidgetPointer(211,2)); + setWidgetFont(307, new WidgetPointer(212,1)); + setWidgetFont(307, new WidgetPointer(212,2)); + setWidgetFont(307, new WidgetPointer(212,3)); + setWidgetFont(307, new WidgetPointer(213,1)); + setWidgetFont(307, new WidgetPointer(213,2)); + setWidgetFont(307, new WidgetPointer(213,3)); + setWidgetFont(307, new WidgetPointer(213,4)); + setWidgetFont(307, new WidgetPointer(214,1)); + setWidgetFont(307, new WidgetPointer(214,2)); + setWidgetFont(307, new WidgetPointer(214,3)); + setWidgetFont(307, new WidgetPointer(214,4)); + setWidgetFont(307, new WidgetPointer(214,5)); + return; +} diff --git a/dumps/scripts/1566.cs2 b/dumps/scripts/1566.cs2 new file mode 100644 index 0000000..93509d7 --- /dev/null +++ b/dumps/scripts/1566.cs2 @@ -0,0 +1,14 @@ +int script_1566(int arg0,int arg1) { + if ((arg0 == 7) && ((boolean)arg1)) { + return 1; + } + if (arg0 == 4) { + switch (arg1) { + case 0: + case 1: + case 2: + return 1; + } + } + return 0; +} diff --git a/dumps/scripts/1567.cs2 b/dumps/scripts/1567.cs2 new file mode 100644 index 0000000..7199697 --- /dev/null +++ b/dumps/scripts/1567.cs2 @@ -0,0 +1,19 @@ +cs2func_script_1567_struct(2,2,0) script_1567(int arg0,int arg1,int arg2) { + int stack_dump0; + int stack_dump1; + cs2func_script_2788_struct(2,2,0) structdump_2; + cs2func_script_2787_struct(2,2,0) structdump_3; + if (arg0 == 7) { + stack_dump0 = arg1; + stack_dump1 = arg2; + structdump_2 = script_2788(stack_dump0, stack_dump1); + return newstruct cs2func_script_1567_struct(structdump_2.intpart_0, structdump_2.intpart_1, structdump_2.stringpart_0, structdump_2.stringpart_1); + } + if (arg0 == 4) { + stack_dump0 = arg1; + stack_dump1 = arg2; + structdump_3 = script_2787(stack_dump0, stack_dump1); + return newstruct cs2func_script_1567_struct(structdump_3.intpart_0, structdump_3.intpart_1, structdump_3.stringpart_0, structdump_3.stringpart_1); + } + return newstruct cs2func_script_1567_struct(0, -1, "", ""); +} diff --git a/dumps/scripts/1568.cs2 b/dumps/scripts/1568.cs2 new file mode 100644 index 0000000..363b334 --- /dev/null +++ b/dumps/scripts/1568.cs2 @@ -0,0 +1,8 @@ +void script_1568(int arg0) { + if (((boolean)getLanguage())) { + setWidgetSprite(2295, new WidgetPointer(arg0)); + } else { + setWidgetSprite(2281, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/1569.cs2 b/dumps/scripts/1569.cs2 new file mode 100644 index 0000000..6b25147 --- /dev/null +++ b/dumps/scripts/1569.cs2 @@ -0,0 +1,12 @@ +int script_1569() { + if (getDisplayMode() >= 2) { + if (isWidgetOpen(new WidgetPointer(746,87))) { + return 1; + } + } else { + if (isWidgetOpen(new WidgetPointer(548,199))) { + return 1; + } + } + return 0; +} diff --git a/dumps/scripts/157.cs2 b/dumps/scripts/157.cs2 new file mode 100644 index 0000000..a6e8373 --- /dev/null +++ b/dumps/scripts/157.cs2 @@ -0,0 +1,27 @@ +void script_157(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + ivar4 = subtract(getWidgetScrollMaxV(new WidgetPointer(arg1)), getWidgetActualHeight(new WidgetPointer(arg1))); + if (((boolean)ivar4)) { + ivar4 = 1; + } + if (arg2 < 0) { + arg2 = 0; + } + if (arg2 > ivar4) { + arg2 = ivar4; + } + cs2method2100(0, arg2, new WidgetPointer(arg1)); + ivar5 = 0; + if (setWidgetRegister(new WidgetPointer(arg0), 1) && ((boolean)arg3)) { + ivar5 = subtract(subtract(getWidgetActualHeight(new WidgetPointer(arg0)), 32), getWidgetActualHeight()); + setWidgetPosition(0, add(16, divide(multiply(ivar5, arg2), ivar4)), 0, 0); + if (setWidgetRegister(new WidgetPointer(arg0), 2)) { + setWidgetPosition(0, getWidgetActualY(), 0, 0); + } + if (setWidgetRegister(new WidgetPointer(arg0), 3)) { + setWidgetPosition(0, subtract(add(getWidgetActualY(), getWidgetActualHeight()), 5), 0, 0); + } + } + return; +} diff --git a/dumps/scripts/1570.cs2 b/dumps/scripts/1570.cs2 new file mode 100644 index 0000000..c814bfa --- /dev/null +++ b/dumps/scripts/1570.cs2 @@ -0,0 +1,4 @@ +void script_1570(int arg0,int arg1) { + cs2method2103(arg0, new WidgetPointer(arg1)); + return; +} diff --git a/dumps/scripts/1571.cs2 b/dumps/scripts/1571.cs2 new file mode 100644 index 0000000..af59525 --- /dev/null +++ b/dumps/scripts/1571.cs2 @@ -0,0 +1,19 @@ +void script_1571(int arg0,int arg1,int arg2) { + int ivar3; + string svar0; + svar0 = globalstring_203; + ivar3 = getWidgetActualWidth(new WidgetPointer(arg0)); + if (getMaxLineWidth(ivar3, arg2, svar0 + " ") > ivar3) { + while (getTextWidth(arg2, svar0 + "... ") > ivar3) { + svar0 = substr(0, subtract(strLength(svar0), 1), svar0); + } + svar0 = svar0 + "..."; + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(arg1), globalstring_203, 25, 5000, "IIsii", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(40, new WidgetPointer(arg1), "I", new WidgetPointer(arg0)); + } else { + setScriptCallOnMouseOver(-1, "", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg0)); + } + setWidgetText(new WidgetPointer(arg0), svar0); + return; +} diff --git a/dumps/scripts/1572.cs2 b/dumps/scripts/1572.cs2 new file mode 100644 index 0000000..d10bbbe --- /dev/null +++ b/dumps/scripts/1572.cs2 @@ -0,0 +1,19 @@ +void script_1572(int arg0,int arg1) { + int ivar2; + string svar0; + svar0 = globalstring_206; + ivar2 = getWidgetActualWidth(new WidgetPointer(arg0)); + if (getMaxLineWidth(2147483647, 496, svar0) > ivar2) { + while (getMaxLineWidth(2147483647, 496, svar0 + "...") > ivar2) { + svar0 = substr(0, subtract(strLength(svar0), 1), svar0); + } + svar0 = svar0 + "..."; + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(arg1), globalstring_206, 25, 5000, "IIsii", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(40, new WidgetPointer(arg1), "I", new WidgetPointer(arg0)); + } else { + setScriptCallOnMouseOver(-1, "", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg0)); + } + setWidgetText(new WidgetPointer(arg0), svar0); + return; +} diff --git a/dumps/scripts/1573.cs2 b/dumps/scripts/1573.cs2 new file mode 100644 index 0000000..fd5cfb5 --- /dev/null +++ b/dumps/scripts/1573.cs2 @@ -0,0 +1,4 @@ +void script_1573(int arg0,int arg1) { + script_1575(arg0, arg1, globalstring_207); + return; +} diff --git a/dumps/scripts/1574.cs2 b/dumps/scripts/1574.cs2 new file mode 100644 index 0000000..6a8332a --- /dev/null +++ b/dumps/scripts/1574.cs2 @@ -0,0 +1,4 @@ +void script_1574(int arg0,int arg1) { + script_1575(arg0, arg1, globalstring_208); + return; +} diff --git a/dumps/scripts/1575.cs2 b/dumps/scripts/1575.cs2 new file mode 100644 index 0000000..b1b2034 --- /dev/null +++ b/dumps/scripts/1575.cs2 @@ -0,0 +1,19 @@ +void script_1575(int arg0,int arg1,string arg2) { + int ivar2; + string svar1; + svar1 = arg2; + ivar2 = getWidgetActualWidth(new WidgetPointer(arg0)); + if (getMaxLineWidth(2147483647, 497, svar1) > ivar2) { + while (getMaxLineWidth(2147483647, 497, svar1 + "...") > ivar2) { + svar1 = substr(0, subtract(strLength(svar1), 1), svar1); + } + svar1 = svar1 + "..."; + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(arg1), arg2, 25, 5000, "IIsii", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(40, new WidgetPointer(arg1), "I", new WidgetPointer(arg0)); + } else { + setScriptCallOnMouseOver(-1, "", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg0)); + } + setWidgetText(new WidgetPointer(arg0), svar1); + return; +} diff --git a/dumps/scripts/1576.cs2 b/dumps/scripts/1576.cs2 new file mode 100644 index 0000000..164f798 --- /dev/null +++ b/dumps/scripts/1576.cs2 @@ -0,0 +1,19 @@ +void script_1576(int arg0,int arg1) { + int ivar2; + string svar0; + svar0 = globalstring_209; + ivar2 = getWidgetActualWidth(new WidgetPointer(arg0)); + if (getMaxLineWidth(2147483647, 497, svar0) > ivar2) { + while (getMaxLineWidth(2147483647, 497, svar0 + "...") > ivar2) { + svar0 = substr(0, subtract(strLength(svar0), 1), svar0); + } + svar0 = svar0 + "..."; + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(arg1), globalstring_209, 25, 5000, "IIsii", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(40, new WidgetPointer(arg1), "I", new WidgetPointer(arg0)); + } else { + setScriptCallOnMouseOver(-1, "", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg0)); + } + setWidgetText(new WidgetPointer(arg0), svar0); + return; +} diff --git a/dumps/scripts/1577.cs2 b/dumps/scripts/1577.cs2 new file mode 100644 index 0000000..ab60e4d --- /dev/null +++ b/dumps/scripts/1577.cs2 @@ -0,0 +1,19 @@ +void script_1577(int arg0,int arg1) { + int ivar2; + string svar0; + svar0 = globalstring_210; + ivar2 = getWidgetActualWidth(new WidgetPointer(arg0)); + if (getMaxLineWidth(ivar2, 497, svar0) > ivar2) { + while (getMaxLineWidth(2147483647, 497, svar0 + "...") > ivar2) { + svar0 = substr(0, subtract(strLength(svar0), 1), svar0); + } + svar0 = svar0 + "..."; + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(arg1), globalstring_210, 25, 5000, "IIsii", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(40, new WidgetPointer(arg1), "I", new WidgetPointer(arg0)); + } else { + setScriptCallOnMouseOver(-1, "", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg0)); + } + setWidgetText(new WidgetPointer(arg0), svar0); + return; +} diff --git a/dumps/scripts/1578.cs2 b/dumps/scripts/1578.cs2 new file mode 100644 index 0000000..2608afd --- /dev/null +++ b/dumps/scripts/1578.cs2 @@ -0,0 +1,19 @@ +void script_1578(int arg0,int arg1) { + int ivar2; + string svar0; + svar0 = globalstring_211; + ivar2 = getWidgetActualWidth(new WidgetPointer(arg0)); + if (getMaxLineWidth(2147483647, 645, svar0) > ivar2) { + while (getMaxLineWidth(2147483647, 645, svar0 + "...") > ivar2) { + svar0 = substr(0, subtract(strLength(svar0), 1), svar0); + } + svar0 = svar0 + "..."; + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(arg1), globalstring_211, 25, 5000, "IIsii", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(40, new WidgetPointer(arg1), "I", new WidgetPointer(arg0)); + } else { + setScriptCallOnMouseOver(-1, "", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg0)); + } + setWidgetText(new WidgetPointer(arg0), svar0); + return; +} diff --git a/dumps/scripts/1579.cs2 b/dumps/scripts/1579.cs2 new file mode 100644 index 0000000..34f6c1f --- /dev/null +++ b/dumps/scripts/1579.cs2 @@ -0,0 +1,4 @@ +void script_1579(int arg0) { + script_125(arg0); + return; +} diff --git a/dumps/scripts/158.cs2 b/dumps/scripts/158.cs2 new file mode 100644 index 0000000..3b15b56 --- /dev/null +++ b/dumps/scripts/158.cs2 @@ -0,0 +1,5 @@ +void script_158(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,string arg6,string arg7,string arg8,string arg9,string arg10) { + script_160(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, "null", "null", "null", "null"); + setScriptCallOnItemContainerUpdate(159, new WidgetPointer(arg0), arg1, arg2, arg3, arg4, new WidgetPointer(arg5), arg6, arg7, arg8, arg9, arg10, "null", "null", "null", "null", arg1, 1, "IviiiIsssssssssY", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1580.cs2 b/dumps/scripts/1580.cs2 new file mode 100644 index 0000000..d55ab67 --- /dev/null +++ b/dumps/scripts/1580.cs2 @@ -0,0 +1,13 @@ +void script_1580() { + setWidgetText(new WidgetPointer(972,29), "Bre'egth: " + "
" + "
" + "Aggressive female ork found patrolling Zanaris near the windmill." + "
" + "
" + " Intelligence leads us to believe that a recent fist fight with a subordinate left Bre'egth with one less tooth in her head, and one subordinate"); + setWidgetText(new WidgetPointer(972,30), "permanently relocated somewhere else. " + "
" + "
" + "Her bragging is well known throughout Zanaris, however, she is important to 'Bad Daddy's' plans. Without her, the ork warrior grunts would simply be fighting each other and their superiors. She keeps them in check." + "
" + " " + "
" + "Suggest first talking to Bre'egth - she's likely to recount the entire story to you if you ask. The trouble might be in getting away again afterwards."); + setWidgetText(new WidgetPointer(972,23), "Gromblod: " + "
" + "
" + "Mango-mad ork found in the Enchanted Valley. " + "
" + "
" + "His teeth are so rotten that he can only eat soft fruit, hence his preference for mangos."); + setWidgetText(new WidgetPointer(972,24), "According to reports, he's creating a bit of a nuisance of himself in the Enchanted Valley. " + "
" + "
" + "The locals don't want to give him the secret to where the magic mango tree is. " + "
" + "
" + "They're afraid he'll consume the entire harvest and they're probably right." + "
" + "
" + " Fairy ring code: BKQ."); + setWidgetText(new WidgetPointer(972,18), "Shredflesh: " + "
" + "
" + "A complete brute to look at, but suspect he's a real teddy bear inside. " + "
" + "
" + "Last reports place him in a cavern in the Gu'Tanoth region. He's searching for herbs to control his excruciating toothache."); + setWidgetText(new WidgetPointer(972,19), "He needs a dentist, so you may be able to convince him that it's the right thing to do." + "
" + "
" + "Fairy ring code: ALP."); + setWidgetText(new WidgetPointer(972,13), "Fairy Godfather " + "
" + "Code name: 'Bad Daddy':" + "
" + "The main villain; he needs to be stopped." + "
" + "
" + " Located in a separated off section of Zanaris, he's discovered a weakness in the interplanar fabric. This is really bad news for us!"); + setWidgetText(new WidgetPointer(972,14), "'Bad Daddy' has used his magic and the magic of the Fairy Queen to make a rift between this plane and another seemingly filled with orks. He's using the rift to transport orks through to use as henchmen." + "
" + "
" + "The Godfather is invulnerable to any standard attack. His magic is somehow linked to orks, so we suspect some sort of weakness there."); + setWidgetText(new WidgetPointer(972,9), "Ork teeth: Crude and brutal, these masticating marvels convey a feeling of basic primal energy." + "
" + "
" + "What they lack in quality, they more than make up for in their wonderfully coarse, brutal and businesslike functionality."); + setWidgetText(new WidgetPointer(972,10), "In the host's early years, the tooth comes to an excessively tantalising point! " + "
" + "
" + "As the host grazes most of the time, this quickly gets worn down. " + "
" + "
" + "Opinion is divided, but many believe the more interesting teeth come from those orks more accustomed to combat. A broken tooth sometimes creates a sublime 'organic' structure - smooth and discoloured, but dense."); + return; +} diff --git a/dumps/scripts/1581.cs2 b/dumps/scripts/1581.cs2 new file mode 100644 index 0000000..386817f --- /dev/null +++ b/dumps/scripts/1581.cs2 @@ -0,0 +1,89 @@ +void script_1581(int arg0) { + int ivar1; + int ivar2; + int ivar3; + string svar0; + string svar1; + svar0 = ""; + ivar1 = 494; + ivar2 = 32243761; + switch (arg0) { + case 32243727: + case 32309275: + case 31981571: + svar0 = globalstring_212; + break; + case 32309276: + case 31981576: + case 32243728: + svar0 = globalstring_213; + break; + case 32309277: + case 31981581: + case 32243729: + svar0 = globalstring_214; + break; + case 32309278: + case 31981586: + case 32243730: + svar0 = globalstring_215; + break; + case 32309279: + case 32243731: + svar0 = globalstring_216; + } + switch (arg0) { + case 32309278: + case 32309279: + case 32309276: + case 32309277: + case 32309275: + ivar1 = 495; + ivar2 = 32309304; + break; + case 31981576: + case 31981581: + case 31981586: + case 31981571: + ivar1 = 495; + ivar2 = 31981595; + } + svar1 = svar0; + ivar3 = getWidgetActualWidth(new WidgetPointer(arg0)); + if (getMaxLineWidth(2147483647, ivar1, svar1 + " ") > ivar3) { + while (getMaxLineWidth(2147483647, ivar1, svar1 + "... ") > ivar3) { + svar1 = substr(0, subtract(strLength(svar1), 1), svar1); + } + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(ivar2), svar0, 25, 5000, "IIsii", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(40, new WidgetPointer(ivar2), "I", new WidgetPointer(arg0)); + svar0 = svar1 + "..."; + } else { + setScriptCallOnMouseOver(-1, "", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg0)); + } + switch (arg0) { + case 32309278: + case 32243727: + case 32309279: + case 32309276: + case 32309277: + case 32309275: + case 32243731: + case 32243730: + case 32243729: + case 32243728: + if (((boolean)stringMethod4107(svar0, "")) || ((boolean)stringMethod4107(svar0, "null"))) { + svar0 = "none set"; + } + break; + case 31981576: + case 31981581: + case 31981571: + case 31981586: + if (((boolean)stringMethod4107(svar0, "")) || ((boolean)stringMethod4107(svar0, "null"))) { + svar0 = "---"; + } + } + setWidgetText(new WidgetPointer(arg0), svar0); + return; +} diff --git a/dumps/scripts/1582.cs2 b/dumps/scripts/1582.cs2 new file mode 100644 index 0000000..d2534a6 --- /dev/null +++ b/dumps/scripts/1582.cs2 @@ -0,0 +1,19 @@ +void script_1582(int arg0,int arg1) { + int ivar2; + string svar0; + svar0 = globalstring_217; + ivar2 = getWidgetActualWidth(new WidgetPointer(arg0)); + if (getMaxLineWidth(2147483647, 495, svar0 + " ") > ivar2) { + while (getMaxLineWidth(2147483647, 495, svar0 + "... ") > ivar2) { + svar0 = substr(0, subtract(strLength(svar0), 1), svar0); + } + svar0 = svar0 + "..."; + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(arg1), globalstring_217, 25, 5000, "IIsii", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(40, new WidgetPointer(arg1), "I", new WidgetPointer(arg0)); + } else { + setScriptCallOnMouseOver(-1, "", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg0)); + } + setWidgetText(new WidgetPointer(arg0), svar0); + return; +} diff --git a/dumps/scripts/1583.cs2 b/dumps/scripts/1583.cs2 new file mode 100644 index 0000000..f06318a --- /dev/null +++ b/dumps/scripts/1583.cs2 @@ -0,0 +1,19 @@ +void script_1583(int arg0,int arg1,string arg2) { + int ivar2; + string svar1; + svar1 = arg2; + ivar2 = getWidgetActualWidth(new WidgetPointer(arg0)); + if (getMaxLineWidth(ivar2, 495, svar1 + " ") > ivar2) { + while (getMaxLineWidth(2147483647, 495, svar1 + "... ") > ivar2) { + svar1 = substr(0, subtract(strLength(svar1), 1), svar1); + } + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(arg1), arg2, 25, 5000, "IIsii", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(40, new WidgetPointer(arg1), "I", new WidgetPointer(arg0)); + arg2 = svar1 + "..."; + } else { + setScriptCallOnMouseOver(-1, "", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg0)); + } + setWidgetText(new WidgetPointer(arg0), arg2); + return; +} diff --git a/dumps/scripts/1584.cs2 b/dumps/scripts/1584.cs2 new file mode 100644 index 0000000..beec7c3 --- /dev/null +++ b/dumps/scripts/1584.cs2 @@ -0,0 +1,4 @@ +void script_1584(int arg0,int arg1) { + script_1585(arg0, arg1, globalstring_218); + return; +} diff --git a/dumps/scripts/1585.cs2 b/dumps/scripts/1585.cs2 new file mode 100644 index 0000000..025b284 --- /dev/null +++ b/dumps/scripts/1585.cs2 @@ -0,0 +1,19 @@ +void script_1585(int arg0,int arg1,string arg2) { + int ivar2; + string svar1; + svar1 = arg2; + ivar2 = getWidgetActualWidth(new WidgetPointer(arg0)); + if (getMaxLineWidth(ivar2, 496, svar1 + " ") > ivar2) { + while (getMaxLineWidth(2147483647, 496, svar1 + "... ") > ivar2) { + svar1 = substr(0, subtract(strLength(svar1), 1), svar1); + } + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(arg1), arg2, 25, 5000, "IIsii", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(40, new WidgetPointer(arg1), "I", new WidgetPointer(arg0)); + svar1 = svar1 + "..."; + } else { + setScriptCallOnMouseOver(-1, "", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg0)); + } + setWidgetText(new WidgetPointer(arg0), svar1); + return; +} diff --git a/dumps/scripts/1586.cs2 b/dumps/scripts/1586.cs2 new file mode 100644 index 0000000..3c5a891 --- /dev/null +++ b/dumps/scripts/1586.cs2 @@ -0,0 +1,4 @@ +void script_1586(int arg0,int arg1,int arg2) { + script_1587(arg0, arg1, arg2, globalstring_219); + return; +} diff --git a/dumps/scripts/1587.cs2 b/dumps/scripts/1587.cs2 new file mode 100644 index 0000000..db44cbb --- /dev/null +++ b/dumps/scripts/1587.cs2 @@ -0,0 +1,19 @@ +void script_1587(int arg0,int arg1,int arg2,string arg3) { + int ivar3; + string svar1; + svar1 = arg3; + ivar3 = getWidgetActualWidth(new WidgetPointer(arg0)); + if (getMaxLineWidth(ivar3, arg2, svar1 + " ") > ivar3) { + while (getMaxLineWidth(2147483647, arg2, svar1 + "... ") > ivar3) { + svar1 = substr(0, subtract(strLength(svar1), 1), svar1); + } + svar1 = svar1 + "..."; + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(arg1), arg3, 25, 5000, "IIsii", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(40, new WidgetPointer(arg1), "I", new WidgetPointer(arg0)); + } else { + setScriptCallOnMouseOver(-1, "", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg0)); + } + setWidgetText(new WidgetPointer(arg0), svar1); + return; +} diff --git a/dumps/scripts/1588.cs2 b/dumps/scripts/1588.cs2 new file mode 100644 index 0000000..65d0847 --- /dev/null +++ b/dumps/scripts/1588.cs2 @@ -0,0 +1,4 @@ +void script_1588() { + script_1592(26279942, 26279960, globalstring_220); + return; +} diff --git a/dumps/scripts/1589.cs2 b/dumps/scripts/1589.cs2 new file mode 100644 index 0000000..4fc9526 --- /dev/null +++ b/dumps/scripts/1589.cs2 @@ -0,0 +1,4 @@ +void script_1589() { + script_1592(26279943, 26279960, globalstring_221); + return; +} diff --git a/dumps/scripts/159.cs2 b/dumps/scripts/159.cs2 new file mode 100644 index 0000000..80a855d --- /dev/null +++ b/dumps/scripts/159.cs2 @@ -0,0 +1,4 @@ +void script_159(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,string arg6,string arg7,string arg8,string arg9,string arg10,string arg11,string arg12,string arg13,string arg14) { + script_160(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + return; +} diff --git a/dumps/scripts/1590.cs2 b/dumps/scripts/1590.cs2 new file mode 100644 index 0000000..6bd0c0e --- /dev/null +++ b/dumps/scripts/1590.cs2 @@ -0,0 +1,4 @@ +void script_1590() { + script_1592(26279944, 26279960, globalstring_222); + return; +} diff --git a/dumps/scripts/1591.cs2 b/dumps/scripts/1591.cs2 new file mode 100644 index 0000000..f57e051 --- /dev/null +++ b/dumps/scripts/1591.cs2 @@ -0,0 +1,4 @@ +void script_1591() { + script_1592(26279945, 26279960, globalstring_223); + return; +} diff --git a/dumps/scripts/1592.cs2 b/dumps/scripts/1592.cs2 new file mode 100644 index 0000000..6380c12 --- /dev/null +++ b/dumps/scripts/1592.cs2 @@ -0,0 +1,19 @@ +void script_1592(int arg0,int arg1,string arg2) { + int ivar2; + string svar1; + svar1 = arg2; + ivar2 = getWidgetActualWidth(new WidgetPointer(arg0)); + if (getMaxLineWidth(2147483647, 495, svar1) > ivar2) { + while (getMaxLineWidth(2147483647, 495, svar1 + "...") > ivar2) { + svar1 = substr(0, subtract(strLength(svar1), 1), svar1); + } + svar1 = svar1 + "..."; + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(arg1), arg2, 25, 5000, "IIsii", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(40, new WidgetPointer(arg1), "I", new WidgetPointer(arg0)); + } else { + setScriptCallOnMouseOver(-1, "", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg0)); + } + setWidgetText(new WidgetPointer(arg0), svar1); + return; +} diff --git a/dumps/scripts/1593.cs2 b/dumps/scripts/1593.cs2 new file mode 100644 index 0000000..fa48d4d --- /dev/null +++ b/dumps/scripts/1593.cs2 @@ -0,0 +1,218 @@ +void script_1593(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + int ivar22; + int ivar23; + int ivar24; + int ivar25; + int ivar26; + int ivar27; + string svar0; + string svar1; + string svar2; + string svar3; + string svar4; + ivar1 = 72679435; + ivar2 = 72679434; + ivar3 = 72679429; + ivar4 = 72679430; + ivar5 = 72679432; + ivar6 = 72679431; + ivar7 = 72679428; + ivar8 = 72679427; + ivar9 = 72679433; + ivar10 = getWidgetActualWidth(new WidgetPointer(ivar1)); + if (arg0 <= -1) { + arg0 = getWidgetActualX(new WidgetPointer(ivar1)); + } + arg0 = max(min(arg0, subtract(getWidgetActualWidth(new WidgetPointer(ivar2)), ivar10)), 0); + globalint_1505 = arg0; + setWidgetPosition(arg0, 0, 0, 1, new WidgetPointer(ivar1)); + cs2method2314(149, new WidgetPointer(ivar1)); + deleteAllExtraChilds(new WidgetPointer(ivar3)); + deleteAllExtraChilds(new WidgetPointer(ivar4)); + deleteAllExtraChilds(new WidgetPointer(ivar5)); + deleteAllExtraChilds(new WidgetPointer(ivar6)); + ivar11 = 0; + ivar12 = script_3365(ivar2); + ivar13 = add(arg0, subtract(ivar12, script_3365(ivar3))); + ivar14 = subtract(getWidgetActualWidth(new WidgetPointer(ivar5)), add(add(arg0, subtract(ivar12, script_3365(ivar5))), ivar10)); + svar0 = ""; + ivar15 = 0; + ivar16 = 0; + svar1 = ""; + svar2 = ""; + ivar17 = 19; + svar3 = ""; + svar4 = ""; + ivar18 = 0; + ivar19 = 0; + ivar20 = 0; + ivar21 = 0; + ivar22 = 0; + ivar23 = divide(getWidgetActualHeight(new WidgetPointer(ivar8)), ivar17); + ivar24 = 0; + ivar25 = cs2method3612(); + if (ivar25 > 0) { + setWidgetIsHidden(true, new WidgetPointer(1109,15)); + while (ivar11 < ivar25) { + ivar16 = ivar11; + ivar22 = multiply(ivar11, ivar17); + svar1 = cs2method3613(ivar11); + svar2 = cs2method3632(ivar11); + ivar20 = cs2method3614(ivar11); + ivar21 = cs2method3615(ivar11); + createExtraChild(new WidgetPointer(ivar3), 4, ivar11); + setWidgetTextAlignment(0, 1, 0); + setWidgetPosition(0, ivar22, 0, 0); + setWidgetSize(ivar13, ivar17, 0, 0); + setWidgetRGB(new Color(164, 153, 125)); + setWidgetFont(3793); + setWidgetUnknownBoolean(false); + setScriptCallOnClickContextMenu(202, svar1, svar2, -2147483644, ivar11, "ssii"); + svar0 = "\u00a0\u00a0" + svar1; + if (getTextWidth(3793, svar0) > ivar13) { + while ((getTextWidth(3793, svar0 + "...") > ivar13) && (strLength(svar0) > 0)) { + svar0 = substr(0, subtract(strLength(svar0), 1), svar0); + } + svar0 = svar0 + "..."; + setScriptCallOnMouseOver(1594, new WidgetPointer(1109,36), new WidgetPointer(-32768,3), -2147483643, svar1, -2147483647, -2147483646, "IIisii"); + setScriptCallOnMouseExit(40, new WidgetPointer(1109,36), "I"); + } + setWidgetText(svar0); + script_1595(ivar11, svar1, svar2); + setWidgetSize(ivar14, 0, 0, 1, new WidgetPointer(ivar5)); + setWidgetSize(ivar14, 0, 0, 1, new WidgetPointer(ivar6)); + createExtraChild(new WidgetPointer(ivar5), 4, getExtraChildGap(new WidgetPointer(ivar5))); + setWidgetFont(3793); + setWidgetPosition(0, ivar22, 2, 0); + setWidgetSize(ivar14, ivar17, 0, 0); + setWidgetUnknownBoolean(true); + if (ivar20 == getWorldId()) { + setWidgetRGB(new Color(60, 183, 30)); + } else { + setWidgetRGB(new Color(255, 255, 100)); + } + setWidgetUnknownBoolean(false); + if ((ivar20 >= 1100) && (ivar20 < 5001)) { + svar3 = "Lobby"; + svar4 = "Lobby"; + ivar18 = 0; + } else if ((ivar20 >= 5001) && (ivar20 < 6000)) { + svar3 = "Classic " + intToStr(subtract(ivar20, 5000)); + svar4 = "Classic " + intToStr(subtract(ivar20, 5000)); + ivar18 = 0; + } else { + svar3 = intToStr(ivar20); + svar4 = "World " + intToStr(ivar20); + ivar18 = add(add(2, 24), 2); + } + ivar19 = getTextWidth(3793, svar3); + if (ivar14 >= add(ivar19, ivar18)) { + if (ivar18 > 0) { + createExtraChild(new WidgetPointer(ivar6), 5, getExtraChildGap(new WidgetPointer(ivar6))); + setWidgetSprite(2173); + setWidgetSize(24, 12, 0, 0); + setWidgetPosition(2, add(ivar22, 3), 0, 0); + setScriptCallOnMouseOver(1594, new WidgetPointer(1109,36), new WidgetPointer(-32768,3), -2147483643, svar4, -2147483647, -2147483646, "IIisii"); + setScriptCallOnMouseExit(40, new WidgetPointer(1109,36), "I"); + } + } else { + ivar18 = 0; + } + if (ivar14 >= ivar19) { + } else { + setScriptCallOnMouseOver(1594, new WidgetPointer(1109,36), new WidgetPointer(-32768,3), -2147483643, svar4, -2147483647, -2147483646, "IIisii"); + setScriptCallOnMouseExit(40, new WidgetPointer(1109,36), "I"); + svar3 = "..."; + } + createExtraChild(new WidgetPointer(ivar5), 4, getExtraChildGap(new WidgetPointer(ivar5))); + setWidgetSize(ivar14, ivar17, 0, 0); + setWidgetPosition(add(ivar18, 2), add(ivar22, 1), 0, 0); + setWidgetFont(3793); + setWidgetUnknownBoolean(false); + setWidgetTextAlignment(0, 0, 0); + setWidgetText(svar3); + if (((boolean)ivar20)) { + setWidgetRGB(new Color(221, 92, 62)); + } else if (ivar20 == getWorldId()) { + setWidgetRGB(new Color(60, 183, 30)); + } else { + setWidgetRGB(new Color(255, 255, 100)); + } + setScriptCallOnMouseOver(1594, new WidgetPointer(1109,36), new WidgetPointer(-32768,3), -2147483643, svar4, -2147483647, -2147483646, "IIisii"); + setScriptCallOnMouseExit(40, new WidgetPointer(1109,36), "I"); + createExtraChild(new WidgetPointer(ivar4), 5, getExtraChildGap(new WidgetPointer(ivar4))); + setWidgetPosition(1, add(multiply(ivar11, ivar17), 5), 0, 0); + setWidgetSize(9, 9, 0, 0); + setWidgetSprite(script_1599(ivar21)); + ivar11 = add(ivar11, 1); + } + svar3 = "Talking in: " + "" + cs2method3611(); + svar1 = "Owner: " + "" + cs2method3625(); + ivar12 = getWidgetActualWidth(new WidgetPointer(1109,1)); + if (getTextWidth(494, svar3) > ivar12) { + while ((getTextWidth(494, svar3 + "...") > ivar12) && (strLength(svar3) > 0)) { + svar3 = substr(0, subtract(strLength(svar3), 1), svar3); + ivar24 = 1; + } + svar3 = svar3 + "..."; + } + if (getTextWidth(494, svar1) > ivar12) { + while ((getTextWidth(494, svar1) > ivar12) && (strLength(svar1) > 0)) { + svar1 = substr(0, subtract(strLength(svar1), 1), svar1 + "..."); + ivar24 = 1; + } + svar1 = svar1 + "..."; + } + setWidgetText(new WidgetPointer(1109,1), svar3 + "
" + svar1); + if (((boolean)ivar24)) { + svar3 = "Talking in: " + cs2method3611() + "
" + "Owner: " + cs2method3625(); + setScriptCallOnMouseOver(4538, new WidgetPointer(1109,36), new WidgetPointer(-32768,3), -1, svar3, 120, 3793, 3793, 16777215, 13, 4, 2, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1109,1)); + setScriptCallOnMouseExit(40, new WidgetPointer(1109,36), "I", new WidgetPointer(1109,1)); + } else { + setScriptCallOnMouseOver(-1, "", new WidgetPointer(1109,1)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(1109,1)); + } + setWidgetContextMenuOption(1, new WidgetPointer(1109,27), "Leave chat"); + setWidgetSprite(6243, new WidgetPointer(1109,28)); + setWidgetIsHidden(false, new WidgetPointer(ivar1)); + } else { + setWidgetIsHidden(false, new WidgetPointer(1109,15)); + setWidgetText(new WidgetPointer(1109,1), "Talking in: Not in chat"); + setWidgetContextMenuOption(1, new WidgetPointer(1109,27), "Join chat"); + setWidgetSprite(6242, new WidgetPointer(1109,28)); + setWidgetIsHidden(true, new WidgetPointer(ivar1)); + setWidgetNoOptions(new WidgetPointer(ivar1)); + setScriptCallOnMouseOver(-1, "", new WidgetPointer(1109,1)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(1109,1)); + } + ivar26 = cs2method2601(new WidgetPointer(ivar8)); + ivar27 = multiply(max(ivar11, ivar23), ivar17); + setWidgetScrollMax(getWidgetActualWidth(new WidgetPointer(ivar8)), ivar27, new WidgetPointer(ivar8)); + if (ivar26 > ivar27) { + ivar26 = ivar27; + } + cs2method2100(0, ivar26, new WidgetPointer(ivar8)); + script_31(ivar9, ivar8, 5666, 5663, 5664, 5665, 5686, 5685); + return; +} diff --git a/dumps/scripts/1594.cs2 b/dumps/scripts/1594.cs2 new file mode 100644 index 0000000..52b18e2 --- /dev/null +++ b/dumps/scripts/1594.cs2 @@ -0,0 +1,10 @@ +void script_1594(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5) { + if (setWidgetRegister(new WidgetPointer(arg1), arg2) || ((arg2 == -1) && setWidgetRegister(new WidgetPointer(arg1)))) { + if (script_1744() < multiplyDivide(3, 5, 261)) { + script_4539(arg0, arg1, arg2, 120, 3793, 3793, 16777215, 13, 4, 2, arg3, arg4, arg5); + } else { + script_4539(arg0, arg1, arg2, 120, 3793, 3793, 16777215, 13, 4, 0, arg3, arg4, arg5); + } + } + return; +} diff --git a/dumps/scripts/1595.cs2 b/dumps/scripts/1595.cs2 new file mode 100644 index 0000000..b83599b --- /dev/null +++ b/dumps/scripts/1595.cs2 @@ -0,0 +1,17 @@ +void script_1595(int arg0,string arg1,string arg2) { + if (cs2method3624(arg0)) { + if (isFriend(arg2)) { + setWidgetContextMenuOption(5, "Message " + arg1); + setWidgetContextMenuOption(7, "Remove friend " + arg1); + } else if (cs2method3623(arg2)) { + setWidgetContextMenuOption(8, "Remove ignore " + arg1); + } else { + setWidgetContextMenuOption(5, "Add friend " + arg1); + setWidgetContextMenuOption(6, "Add ignore " + arg1); + } + } + if ((cs2method3618() >= cs2method3616()) && (cs2method3618() > cs2method3615(arg0))) { + setWidgetContextMenuOption(9, "Kick/ban user " + arg1); + } + return; +} diff --git a/dumps/scripts/1596.cs2 b/dumps/scripts/1596.cs2 new file mode 100644 index 0000000..5a36671 --- /dev/null +++ b/dumps/scripts/1596.cs2 @@ -0,0 +1,7 @@ +void script_1596(int arg0,int arg1) { + if (arg0 != 1) { + return; + } + setWidgetSprite(1071, new WidgetPointer(arg1)); + return; +} diff --git a/dumps/scripts/1597.cs2 b/dumps/scripts/1597.cs2 new file mode 100644 index 0000000..cd787b4 --- /dev/null +++ b/dumps/scripts/1597.cs2 @@ -0,0 +1,14 @@ +void script_1597(int arg0) { + if (((boolean)bitconfig_4072) || ((boolean)bitconfig_4073)) { + setWidgetSprite(1071, new WidgetPointer(arg0)); + } else if (((boolean)bitconfig_4071)) { + if (((boolean)bitconfig_4465)) { + setWidgetSprite(306, new WidgetPointer(arg0)); + } else { + setWidgetSprite(1069, new WidgetPointer(arg0)); + } + } else { + setWidgetSprite(1070, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/1598.cs2 b/dumps/scripts/1598.cs2 new file mode 100644 index 0000000..33d3a75 --- /dev/null +++ b/dumps/scripts/1598.cs2 @@ -0,0 +1,17 @@ +void script_1598(int arg0) { + if (globalint_53 < getClientCycle()) { + if (((boolean)bitconfig_4072) || ((boolean)bitconfig_4073)) { + setWidgetSprite(1071, new WidgetPointer(arg0)); + } else if (((boolean)bitconfig_4071)) { + if (((boolean)bitconfig_4465)) { + setWidgetSprite(306, new WidgetPointer(arg0)); + } else { + setWidgetSprite(1069, new WidgetPointer(arg0)); + } + } else { + setWidgetSprite(1070, new WidgetPointer(arg0)); + } + globalint_53 = add(getClientCycle(), 500); + } + return; +} diff --git a/dumps/scripts/1599.cs2 b/dumps/scripts/1599.cs2 new file mode 100644 index 0000000..9da11cf --- /dev/null +++ b/dumps/scripts/1599.cs2 @@ -0,0 +1,23 @@ +int script_1599(int arg0) { + switch (arg0) { + case 0: + return 1004; + case 1: + return 6226; + case 2: + return 6225; + case 3: + return 6224; + case 4: + return 6232; + case 5: + return 6233; + case 6: + return 6231; + case 7: + return 6227; + case 127: + return 1005; + } + return -1; +} diff --git a/dumps/scripts/16.cs2 b/dumps/scripts/16.cs2 new file mode 100644 index 0000000..7d0e5ef --- /dev/null +++ b/dumps/scripts/16.cs2 @@ -0,0 +1,4 @@ +void script_16(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12) { + script_21(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); + return; +} diff --git a/dumps/scripts/160.cs2 b/dumps/scripts/160.cs2 new file mode 100644 index 0000000..6a6bb50 --- /dev/null +++ b/dumps/scripts/160.cs2 @@ -0,0 +1,27 @@ +void script_160(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,string arg6,string arg7,string arg8,string arg9,string arg10,string arg11,string arg12,string arg13,string arg14) { + int ivar6; + int ivar7; + int ivar8; + deleteAllExtraChilds(new WidgetPointer(arg0)); + ivar6 = 0; + ivar7 = 0; + if (getWidgetScrollMaxH(new WidgetPointer(arg0)) > 0) { + ivar6 = divide(subtract(getWidgetScrollMaxH(new WidgetPointer(arg0)), multiply(36, arg2)), subtract(arg2, 1)); + } else { + ivar6 = divide(subtract(getWidgetActualWidth(new WidgetPointer(arg0)), multiply(36, arg2)), subtract(arg2, 1)); + } + if (getWidgetScrollMaxV(new WidgetPointer(arg0)) > 0) { + ivar7 = divide(subtract(getWidgetScrollMaxV(new WidgetPointer(arg0)), multiply(32, arg3)), subtract(arg3, 1)); + } else { + ivar7 = divide(subtract(getWidgetActualHeight(new WidgetPointer(arg0)), multiply(32, arg3)), subtract(arg3, 1)); + } + ivar8 = 0; + while (ivar8 <= multiply(arg2, arg3)) { + createExtraChild(new WidgetPointer(arg0), 5, ivar8); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(multiply(add(36, ivar6), mod(ivar8, arg2)), multiply(divide(ivar8, arg2), add(32, ivar7)), 0, 0); + script_161(arg1, ivar8, arg0, ivar8, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + ivar8 = add(ivar8, 1); + } + return; +} diff --git a/dumps/scripts/1600.cs2 b/dumps/scripts/1600.cs2 new file mode 100644 index 0000000..c96c246 --- /dev/null +++ b/dumps/scripts/1600.cs2 @@ -0,0 +1,14 @@ +void script_1600() { + int ivar0; + int ivar1; + ivar0 = 0; + ivar1 = 0; + if (((boolean)script_1891())) { + setWidgetIsHidden(false, new WidgetPointer(1109,20)); + ivar0 = getWidgetActualY(new WidgetPointer(1109,18)); + setWidgetPosition(134, ivar0, 0, 0, new WidgetPointer(1109,18)); + return; + } + script_1632(); + return; +} diff --git a/dumps/scripts/1601.cs2 b/dumps/scripts/1601.cs2 new file mode 100644 index 0000000..bbed376 --- /dev/null +++ b/dumps/scripts/1601.cs2 @@ -0,0 +1,55 @@ +void script_1601(int arg0) { + int ivar1; + int ivar2; + ivar1 = -1; + ivar2 = -1; + switch (rnd(2)) { + case 0: + playSoundEffect(7813, 1, 0); + break; + case 1: + playSoundEffect(7817, 1, 0); + break; + case 2: + playSoundEffect(7818, 1, 0); + } + switch (arg0) { + case 63701023: + ivar1 = 63700995; + ivar2 = 63700996; + break; + case 63701017: + ivar1 = 63700996; + ivar2 = 63700997; + break; + case 63701012: + ivar1 = 63700997; + ivar2 = 63700998; + break; + case 63701007: + ivar1 = 63700998; + ivar2 = 63700999; + break; + case 63701003: + ivar1 = 63700999; + ivar2 = 63700998; + break; + case 63701008: + ivar1 = 63700998; + ivar2 = 63700997; + break; + case 63701013: + ivar1 = 63700997; + ivar2 = 63700996; + break; + case 63701018: + ivar1 = 63700996; + ivar2 = 63700995; + break; + default: + script_675(); + } + setWidgetIsHidden(true, new WidgetPointer(ivar1)); + setWidgetIsHidden(false, new WidgetPointer(ivar2)); + return; +} diff --git a/dumps/scripts/1602.cs2 b/dumps/scripts/1602.cs2 new file mode 100644 index 0000000..b6bcc91 --- /dev/null +++ b/dumps/scripts/1602.cs2 @@ -0,0 +1,3 @@ +string script_1602(string arg0) { + return script_2332(arg0, substr(0, 1, ""), ">"); +} diff --git a/dumps/scripts/1603.cs2 b/dumps/scripts/1603.cs2 new file mode 100644 index 0000000..cb2dd30 --- /dev/null +++ b/dumps/scripts/1603.cs2 @@ -0,0 +1,31 @@ +void script_1603(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + opcStruct5209(2,0,0) structdump_0; + if (cs2method5220()) { + return; + } + ivar2 = add(15, max(subtract(globalint_1030, getClientCycle()), 0)); + globalint_1030 = min(max(add(globalint_1030, 2), add(getClientCycle(), 2)), add(getClientCycle(), 25)); + switch (globalint_172) { + case 37: + ivar2 = multiply(ivar2, 5); + break; + case 50: + ivar2 = multiply(ivar2, 4); + break; + case 75: + ivar2 = multiply(ivar2, 3); + break; + case 100: + ivar2 = multiply(ivar2, 2); + } + ivar3 = 0; + ivar4 = 0; + structdump_0 = cs2method5209(); + ivar4 = structdump_0.intpart_1; + ivar3 = structdump_0.intpart_0; + cs2method5221(addToCoordinate(0, max(add(ivar3, multiply(arg0, ivar2)), 0), 0, max(add(ivar4, multiply(arg1, ivar2)), 0))); + return; +} diff --git a/dumps/scripts/1604.cs2 b/dumps/scripts/1604.cs2 new file mode 100644 index 0000000..96bc7ec --- /dev/null +++ b/dumps/scripts/1604.cs2 @@ -0,0 +1,196 @@ +void script_1604() { + int ivar0; + int stack_dump0; + int stack_dump1; + int stack_dump2; + cs2func_script_788_struct(2,0,0) structdump_3; + cs2func_script_788_struct(2,0,0) structdump_4; + cs2func_script_788_struct(2,0,0) structdump_5; + cs2func_script_788_struct(2,0,0) structdump_6; + cs2func_script_788_struct(2,0,0) structdump_7; + cs2func_script_788_struct(2,0,0) structdump_8; + cs2func_script_788_struct(2,0,0) structdump_9; + cs2func_script_788_struct(2,0,0) structdump_10; + cs2func_script_788_struct(2,0,0) structdump_11; + cs2func_script_788_struct(2,0,0) structdump_12; + cs2func_script_788_struct(2,0,0) structdump_13; + cs2func_script_788_struct(2,0,0) structdump_14; + cs2func_script_788_struct(2,0,0) structdump_15; + cs2func_script_788_struct(2,0,0) structdump_16; + cs2func_script_788_struct(2,0,0) structdump_17; + cs2func_script_788_struct(2,0,0) structdump_18; + cs2func_script_788_struct(2,0,0) structdump_19; + cs2func_script_788_struct(2,0,0) structdump_20; + cs2func_script_788_struct(2,0,0) structdump_21; + cs2func_script_788_struct(2,0,0) structdump_22; + cs2func_script_788_struct(2,0,0) structdump_23; + cs2func_script_788_struct(2,0,0) structdump_24; + deleteAllExtraChilds(new WidgetPointer(549,110)); + setWidgetIsHidden(true, new WidgetPointer(549,15)); + ivar0 = 0; + while (ivar0 < 14) { + createExtraChild(new WidgetPointer(549,110), 5, ivar0); + if (((ivar0 != 6) && (ivar0 != 8)) && (ivar0 != 11)) { + if (getItemIdInSlot(94, ivar0) != -1) { + setWidgetSize(36, 32, 0, 0); + if (((boolean)ivar0)) { + stack_dump0 = 35979380; + stack_dump1 = 2; + stack_dump2 = 2; + structdump_3 = script_788(stack_dump0, stack_dump1, stack_dump2); + setWidgetPosition(structdump_3.intpart_0, structdump_3.intpart_1, 0, 0); + } else if (((boolean)ivar0)) { + stack_dump0 = 35979381; + stack_dump1 = 2; + stack_dump2 = 2; + structdump_4 = script_788(stack_dump0, stack_dump1, stack_dump2); + setWidgetPosition(structdump_4.intpart_0, structdump_4.intpart_1, 0, 0); + } else if (ivar0 == 2) { + stack_dump0 = 35979382; + stack_dump1 = 2; + stack_dump2 = 2; + structdump_5 = script_788(stack_dump0, stack_dump1, stack_dump2); + setWidgetPosition(structdump_5.intpart_0, structdump_5.intpart_1, 0, 0); + } else if (ivar0 == 3) { + stack_dump0 = 35979384; + stack_dump1 = 2; + stack_dump2 = 2; + structdump_6 = script_788(stack_dump0, stack_dump1, stack_dump2); + setWidgetPosition(structdump_6.intpart_0, structdump_6.intpart_1, 0, 0); + } else if (ivar0 == 4) { + stack_dump0 = 35979385; + stack_dump1 = 2; + stack_dump2 = 2; + structdump_7 = script_788(stack_dump0, stack_dump1, stack_dump2); + setWidgetPosition(structdump_7.intpart_0, structdump_7.intpart_1, 0, 0); + } else if (ivar0 == 5) { + stack_dump0 = 35979386; + stack_dump1 = 2; + stack_dump2 = 2; + structdump_8 = script_788(stack_dump0, stack_dump1, stack_dump2); + setWidgetPosition(structdump_8.intpart_0, structdump_8.intpart_1, 0, 0); + } else if (ivar0 == 7) { + stack_dump0 = 35979387; + stack_dump1 = 2; + stack_dump2 = 2; + structdump_9 = script_788(stack_dump0, stack_dump1, stack_dump2); + setWidgetPosition(structdump_9.intpart_0, structdump_9.intpart_1, 0, 0); + } else if (ivar0 == 9) { + stack_dump0 = 35979389; + stack_dump1 = 2; + stack_dump2 = 2; + structdump_10 = script_788(stack_dump0, stack_dump1, stack_dump2); + setWidgetPosition(structdump_10.intpart_0, structdump_10.intpart_1, 0, 0); + } else if (ivar0 == 10) { + stack_dump0 = 35979388; + stack_dump1 = 2; + stack_dump2 = 2; + structdump_11 = script_788(stack_dump0, stack_dump1, stack_dump2); + setWidgetPosition(structdump_11.intpart_0, structdump_11.intpart_1, 0, 0); + } else if (ivar0 == 12) { + stack_dump0 = 35979390; + stack_dump1 = 2; + stack_dump2 = 2; + structdump_12 = script_788(stack_dump0, stack_dump1, stack_dump2); + setWidgetPosition(structdump_12.intpart_0, structdump_12.intpart_1, 0, 0); + } else { + if (ivar0 == 13) { + stack_dump0 = 35979383; + stack_dump1 = 2; + stack_dump2 = 2; + structdump_13 = script_788(stack_dump0, stack_dump1, stack_dump2); + setWidgetPosition(structdump_13.intpart_0, structdump_13.intpart_1, 0, 0); + } + } + setItemOnWidgetMethod1200(getItemIdInSlot(94, ivar0), getItemAmtInSlot(94, ivar0)); + cs2method1305(getItemName(getItemIdInSlot(94, ivar0))); + setWidgetContextMenuOption(1, "Remove" + ""); + setWidgetContextMenuOption(10, "Examine" + ""); + setWidgetShadowColor(new Color(17, 17, 17)); + setWidgetBorderThickness(1); + } else if (((boolean)ivar0)) { + stack_dump0 = 35979380; + stack_dump1 = 2; + stack_dump2 = 2; + structdump_14 = script_788(stack_dump0, stack_dump1, stack_dump2); + setWidgetPosition(structdump_14.intpart_0, structdump_14.intpart_1, 0, 0); + setWidgetSprite(156); + } else if (((boolean)ivar0)) { + stack_dump0 = 35979381; + stack_dump1 = 2; + stack_dump2 = 2; + structdump_15 = script_788(stack_dump0, stack_dump1, stack_dump2); + setWidgetPosition(structdump_15.intpart_0, structdump_15.intpart_1, 0, 0); + setWidgetSprite(157); + } else if (ivar0 == 2) { + stack_dump0 = 35979382; + stack_dump1 = 2; + stack_dump2 = 2; + structdump_16 = script_788(stack_dump0, stack_dump1, stack_dump2); + setWidgetPosition(structdump_16.intpart_0, structdump_16.intpart_1, 0, 0); + setWidgetSprite(158); + } else if (ivar0 == 3) { + stack_dump0 = 35979384; + stack_dump1 = 2; + stack_dump2 = 2; + structdump_17 = script_788(stack_dump0, stack_dump1, stack_dump2); + setWidgetPosition(structdump_17.intpart_0, structdump_17.intpart_1, 0, 0); + setWidgetSprite(159); + } else if (ivar0 == 4) { + stack_dump0 = 35979385; + stack_dump1 = 2; + stack_dump2 = 2; + structdump_18 = script_788(stack_dump0, stack_dump1, stack_dump2); + setWidgetPosition(structdump_18.intpart_0, structdump_18.intpart_1, 0, 0); + setWidgetSprite(161); + } else if (ivar0 == 5) { + stack_dump0 = 35979386; + stack_dump1 = 2; + stack_dump2 = 2; + structdump_19 = script_788(stack_dump0, stack_dump1, stack_dump2); + setWidgetPosition(structdump_19.intpart_0, structdump_19.intpart_1, 0, 0); + setWidgetSprite(162); + } else if (ivar0 == 7) { + stack_dump0 = 35979387; + stack_dump1 = 2; + stack_dump2 = 2; + structdump_20 = script_788(stack_dump0, stack_dump1, stack_dump2); + setWidgetPosition(structdump_20.intpart_0, structdump_20.intpart_1, 0, 0); + setWidgetSprite(163); + } else if (ivar0 == 9) { + stack_dump0 = 35979389; + stack_dump1 = 2; + stack_dump2 = 2; + structdump_21 = script_788(stack_dump0, stack_dump1, stack_dump2); + setWidgetPosition(structdump_21.intpart_0, structdump_21.intpart_1, 0, 0); + setWidgetSprite(164); + } else if (ivar0 == 10) { + stack_dump0 = 35979388; + stack_dump1 = 2; + stack_dump2 = 2; + structdump_22 = script_788(stack_dump0, stack_dump1, stack_dump2); + setWidgetPosition(structdump_22.intpart_0, structdump_22.intpart_1, 0, 0); + setWidgetSprite(165); + } else if (ivar0 == 12) { + stack_dump0 = 35979390; + stack_dump1 = 2; + stack_dump2 = 2; + structdump_23 = script_788(stack_dump0, stack_dump1, stack_dump2); + setWidgetPosition(structdump_23.intpart_0, structdump_23.intpart_1, 0, 0); + setWidgetSprite(160); + } else { + if (ivar0 == 13) { + stack_dump0 = 35979383; + stack_dump1 = 2; + stack_dump2 = 2; + structdump_24 = script_788(stack_dump0, stack_dump1, stack_dump2); + setWidgetPosition(structdump_24.intpart_0, structdump_24.intpart_1, 0, 0); + setWidgetSprite(166); + } + } + setWidgetSize(32, 32, 0, 0); + } + ivar0 = add(ivar0, 1); + } + return; +} diff --git a/dumps/scripts/1605.cs2 b/dumps/scripts/1605.cs2 new file mode 100644 index 0000000..ecf1937 --- /dev/null +++ b/dumps/scripts/1605.cs2 @@ -0,0 +1,4 @@ +void script_1605() { + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(549,127)); + return; +} diff --git a/dumps/scripts/1606.cs2 b/dumps/scripts/1606.cs2 new file mode 100644 index 0000000..9d14210 --- /dev/null +++ b/dumps/scripts/1606.cs2 @@ -0,0 +1,4 @@ +void script_1606() { + setWidgetRGB(new Color(201, 128, 13), new WidgetPointer(549,127)); + return; +} diff --git a/dumps/scripts/1607.cs2 b/dumps/scripts/1607.cs2 new file mode 100644 index 0000000..7c31ea4 --- /dev/null +++ b/dumps/scripts/1607.cs2 @@ -0,0 +1,7 @@ +void script_1607() { + int ivar0; + ivar0 = 12411; + setWidgetAnimation(ivar0, new WidgetPointer(549,54)); + cs2method2202(new WidgetPointer(549,54)); + return; +} diff --git a/dumps/scripts/1608.cs2 b/dumps/scripts/1608.cs2 new file mode 100644 index 0000000..30e6dcd --- /dev/null +++ b/dumps/scripts/1608.cs2 @@ -0,0 +1,7 @@ +void script_1608() { + int ivar0; + ivar0 = getRenderEmoteMaxSomethingMethod4600(getItemHashmapData(getItemIdInSlot(94, 3), 644)); + setWidgetAnimation(ivar0, new WidgetPointer(549,82)); + setWidgetSelfFull(new WidgetPointer(549,82)); + return; +} diff --git a/dumps/scripts/1609.cs2 b/dumps/scripts/1609.cs2 new file mode 100644 index 0000000..da1c8a3 --- /dev/null +++ b/dumps/scripts/1609.cs2 @@ -0,0 +1,4 @@ +void script_1609() { + setWidgetIsHidden(true, new WidgetPointer(549,15)); + return; +} diff --git a/dumps/scripts/161.cs2 b/dumps/scripts/161.cs2 new file mode 100644 index 0000000..71db97f --- /dev/null +++ b/dumps/scripts/161.cs2 @@ -0,0 +1,50 @@ +void script_161(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,string arg6,string arg7,string arg8,string arg9,string arg10,string arg11,string arg12,string arg13,string arg14) { + if (setWidgetRegister(new WidgetPointer(arg2), arg3)) { + if (getItemIdInSlotSplit(arg0, arg1) != -1) { + setItemOnWidgetMethod1200(getItemIdInSlotSplit(arg0, arg1), getItemAmtInSlotSplit(arg0, arg1)); + cs2method1305(getItemName(getItemIdInSlotSplit(arg0, arg1))); + setWidgetContextMenuOption(1, arg6); + setWidgetContextMenuOption(2, arg7); + setWidgetContextMenuOption(3, arg8); + setWidgetContextMenuOption(4, arg9); + setWidgetContextMenuOption(5, arg10); + setWidgetContextMenuOption(6, arg11); + setWidgetContextMenuOption(7, arg12); + setWidgetContextMenuOption(8, arg13); + setWidgetContextMenuOption(9, arg14); + setWidgetContextMenuOption(10, "Examine" + ""); + if (arg4 > 0) { + cs2method1303(5); + cs2method1304(10); + } + if (((boolean)arg4)) { + setScriptCallOnMouseDragReleased(155, arg0, -2147483643, -2147483641, new WidgetPointer(-32768,3), arg4, new WidgetPointer(arg5), arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, "viiIiIsssssssss"); + } else { + if (arg4 == 2) { + setScriptCallOnMouseDragReleased(156, arg0, -2147483643, -2147483641, new WidgetPointer(-32768,3), arg4, new WidgetPointer(arg5), arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, "viiIiIsssssssss"); + } + } + setWidgetShadowColor(new Color(51, 51, 51)); + setWidgetBorderThickness(1); + } else { + setItemOnWidgetMethod1200(-1, 0); + cs2method1305(""); + setWidgetContextMenuOption(1, ""); + setWidgetContextMenuOption(2, ""); + setWidgetContextMenuOption(3, ""); + setWidgetContextMenuOption(4, ""); + setWidgetContextMenuOption(5, ""); + setWidgetContextMenuOption(6, ""); + setWidgetContextMenuOption(7, ""); + setWidgetContextMenuOption(8, ""); + setWidgetContextMenuOption(9, ""); + setWidgetContextMenuOption(10, ""); + if (arg4 > 0) { + cs2method1303(0); + cs2method1304(0); + } + setScriptCallOnMouseDragReleased(-1, ""); + } + } + return; +} diff --git a/dumps/scripts/1610.cs2 b/dumps/scripts/1610.cs2 new file mode 100644 index 0000000..8af1f53 --- /dev/null +++ b/dumps/scripts/1610.cs2 @@ -0,0 +1,5 @@ +void script_1610() { + setWidgetIsHidden(false, new WidgetPointer(549,15)); + script_679(35979299); + return; +} diff --git a/dumps/scripts/1611.cs2 b/dumps/scripts/1611.cs2 new file mode 100644 index 0000000..7875b7f --- /dev/null +++ b/dumps/scripts/1611.cs2 @@ -0,0 +1,9 @@ +int script_1611() { + int ivar0; + ivar0 = 0; + ivar0 = add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(bitconfig_4003, bitconfig_4007), bitconfig_4008), bitconfig_4009), bitconfig_4010), bitconfig_4011), bitconfig_4013), bitconfig_4014), bitconfig_4015), bitconfig_4016), bitconfig_4017), bitconfig_4018), bitconfig_4019), bitconfig_4020), bitconfig_4021), bitconfig_4022), bitconfig_4023), bitconfig_4024), bitconfig_4025), bitconfig_4026); + if (bitconfig_4012 == 4) { + ivar0 = add(ivar0, 1); + } + return ivar0; +} diff --git a/dumps/scripts/1612.cs2 b/dumps/scripts/1612.cs2 new file mode 100644 index 0000000..a973172 --- /dev/null +++ b/dumps/scripts/1612.cs2 @@ -0,0 +1,49 @@ +void script_1612(int arg0,int arg1) { + int ivar2; + string svar0; + ivar2 = getItemIdInSlot(94, arg1); + if (ivar2 == -1) { + setItemOnWidgetMethod2200(-1, 0, new WidgetPointer(arg0)); + setWidgetSize(32, 32, 0, 0, new WidgetPointer(arg0)); + setWidgetPosition(0, 0, 1, 1, new WidgetPointer(arg0)); + setWidgetSprite(cs2method_3408(105, 100, 796, arg1), new WidgetPointer(arg0)); + setWidgetBorderThickness(0, new WidgetPointer(arg0)); + setWidgetShadowColor(new Color(0, 0, 0), new WidgetPointer(arg0)); + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(arg0)); + setWidgetNoOptions(new WidgetPointer(arg0)); + return; + } + setWidgetSize(36, 32, 0, 0, new WidgetPointer(arg0)); + setWidgetPosition(2, 0, 0, 1, new WidgetPointer(arg0)); + setItemOnWidgetMethod2200(ivar2, getItemAmtInSlot(94, arg1), new WidgetPointer(arg0)); + setWidgetBorderThickness(1, new WidgetPointer(arg0)); + setWidgetShadowColor(new Color(48, 32, 32), new WidgetPointer(arg0)); + setScriptCallOnClickContextMenu(1620, new WidgetPointer(-32768,3), -1, 100, 0, 8, "Iiiii", new WidgetPointer(arg0)); + setWidgetNoOptions(new WidgetPointer(arg0)); + if (((boolean)getItemHashmapData(ivar2, 1430))) { + setWidgetContextMenuOption(1, new WidgetPointer(arg0), "Remove"); + } + svar0 = getItemHashmapData(ivar2, 528); + if (strLength(svar0) > 0) { + setWidgetContextMenuOption(2, new WidgetPointer(arg0), svar0); + } + svar0 = getItemHashmapData(ivar2, 529); + if (strLength(svar0) > 0) { + setWidgetContextMenuOption(3, new WidgetPointer(arg0), svar0); + } + svar0 = getItemHashmapData(ivar2, 530); + if (strLength(svar0) > 0) { + setWidgetContextMenuOption(4, new WidgetPointer(arg0), svar0); + } + svar0 = getItemHashmapData(ivar2, 531); + if (strLength(svar0) > 0) { + setWidgetContextMenuOption(5, new WidgetPointer(arg0), svar0); + } + svar0 = getItemHashmapData(ivar2, 1211); + if (strLength(svar0) > 0) { + setWidgetContextMenuOption(6, new WidgetPointer(arg0), svar0); + } + setWidgetContextMenuOption(10, new WidgetPointer(arg0), "Examine"); + cs2method2305(new WidgetPointer(arg0), "" + getItemName(ivar2)); + return; +} diff --git a/dumps/scripts/1613.cs2 b/dumps/scripts/1613.cs2 new file mode 100644 index 0000000..4e8f52c --- /dev/null +++ b/dumps/scripts/1613.cs2 @@ -0,0 +1,77 @@ +void script_1613(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + if (((boolean)arg1)) { + globalint_1031 = 0; + } + ivar2 = getItemContainerLength(93); + ivar3 = subtract(multiply(ivar2, 2), 1); + ivar4 = 0; + while (ivar4 <= ivar3) { + if (setWidgetRegister(new WidgetPointer(arg0), ivar4)) { + createExtraChild(new WidgetPointer(arg0), 5, ivar4); + setWidgetSize(36, 32, 0, 0); + if (ivar4 < ivar2) { + setWidgetShadowColor(new Color(48, 32, 32)); + setScriptCallOnUse(1615, 1, new WidgetPointer(-32768,3), -2147483643, "1Ii"); + setScriptCallOnUseWith(1615, 0, new WidgetPointer(-32768,3), -2147483643, "1Ii"); + cs2method1302(2); + cs2method1303(5); + cs2method1304(5); + setScriptCallOnMouseDragReleased(1616, new WidgetPointer(-32768,3), -2147483643, new WidgetPointer(-32768,6), -2147483641, "IiIi"); + setScriptCallOnClickContextMenu(1620, new WidgetPointer(-32768,3), -2147483643, 100, 0, 8, "Iiiii"); + } else { + setWidgetRGB(new Color(0, 0, 0)); + cs2method2103(255); + setWidgetHidden(0); + } + } + ivar4 = add(ivar4, 1); + } + ivar5 = divide(ivar2, 4); + ivar6 = divide(subtract(getWidgetActualWidth(new WidgetPointer(arg0)), multiply(4, 36)), 3); + ivar7 = divide(subtract(getWidgetActualHeight(new WidgetPointer(arg0)), multiply(ivar5, 32)), 6); + ivar8 = -1; + ivar3 = subtract(globalint_1031, 1); + ivar4 = 0; + while (ivar4 < ivar2) { + if (setWidgetRegister(new WidgetPointer(arg0), ivar4)) { + setWidgetNoOptions(); + setWidgetPosition(multiply(mod(ivar4, 4), add(36, ivar6)), multiply(divide(ivar4, 4), add(32, ivar7)), 0, 0); + ivar8 = getItemIdInSlot(93, ivar4); + if (ivar8 != -1) { + setWidgetHidden(0); + setItemOnWidgetMethod1200(ivar8, getItemAmtInSlot(93, ivar4)); + if (ivar4 == ivar3) { + setWidgetBorderThickness(2); + } else { + setWidgetBorderThickness(1); + } + script_2833(ivar8); + cs2method1301(arg0, -1); + } else { + setWidgetHidden(1); + setScriptCallOnConfigChange(-1, ""); + setItemOnWidgetMethod1200(-1, 0); + setWidgetBorderThickness(1); + if (ivar4 == ivar3) { + globalint_1031 = 0; + } + } + } + ivar4 = add(ivar4, 1); + } + ivar4 = 0; + while (ivar4 < ivar2) { + if (setWidgetRegister(new WidgetPointer(arg0), add(ivar2, ivar4))) { + setWidgetPosition(multiply(mod(ivar4, 4), add(36, ivar6)), multiply(divide(ivar4, 4), add(32, ivar7)), 0, 0); + } + ivar4 = add(ivar4, 1); + } + return; +} diff --git a/dumps/scripts/1614.cs2 b/dumps/scripts/1614.cs2 new file mode 100644 index 0000000..dcd938c --- /dev/null +++ b/dumps/scripts/1614.cs2 @@ -0,0 +1,11 @@ +void script_1614(int arg0,int arg1,int arg2) { + int ivar3; + ivar3 = -1; + ivar3 = getItemDefOpcode129Or130Method4209(arg2, arg0); + if (ivar3 != -1) { + cs2method1309(arg1, ivar3); + } else { + cs2method1309(arg1, 36); + } + return; +} diff --git a/dumps/scripts/1615.cs2 b/dumps/scripts/1615.cs2 new file mode 100644 index 0000000..70eb7c1 --- /dev/null +++ b/dumps/scripts/1615.cs2 @@ -0,0 +1,14 @@ +void script_1615(int arg0,int arg1,int arg2) { + if (((boolean)arg0)) { + if (setWidgetRegister(new WidgetPointer(arg1), arg2)) { + setWidgetBorderThickness(2); + } + globalint_1031 = add(1, arg2); + } else { + if (setWidgetRegister(new WidgetPointer(arg1), arg2)) { + setWidgetBorderThickness(1); + } + globalint_1031 = 0; + } + return; +} diff --git a/dumps/scripts/1616.cs2 b/dumps/scripts/1616.cs2 new file mode 100644 index 0000000..de5c2ae --- /dev/null +++ b/dumps/scripts/1616.cs2 @@ -0,0 +1,40 @@ +void script_1616(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + int ivar6; + int stack_dump0; + if (arg0 != arg2) { + return; + } + ivar4 = getItemContainerLength(93); + arg1 = mod(arg1, ivar4); + arg3 = mod(arg3, ivar4); + ivar5 = -1; + ivar6 = 0; + if (setWidgetRegister(new WidgetPointer(arg0), arg1) && setWidgetRegister(new WidgetPointer(arg2), arg3)) { + stack_dump0 = getWidgetItemId(); + ivar6 = getWidgetItemAmt(); + ivar5 = stack_dump0; + setItemOnWidgetMethod1200(getWidgetItemId(), getWidgetItemAmt()); + setItemOnWidgetMethod1200(ivar5, ivar6); + setWidgetNoOptions(); + setWidgetNoOptions(); + if (getWidgetItemId() != -1) { + setWidgetHidden(0); + script_2833(getWidgetItemId()); + } else { + setScriptCallOnConfigChange(-1, ""); + setWidgetHidden(1); + } + if (setWidgetRegister(new WidgetPointer(arg2), arg3)) { + if (getWidgetItemId() != -1) { + setWidgetHidden(0); + script_2833(getWidgetItemId()); + } else { + setScriptCallOnConfigChange(-1, ""); + setWidgetHidden(1); + } + } + } + return; +} diff --git a/dumps/scripts/1617.cs2 b/dumps/scripts/1617.cs2 new file mode 100644 index 0000000..8ad7798 --- /dev/null +++ b/dumps/scripts/1617.cs2 @@ -0,0 +1,5 @@ +void script_1617() { + setWidgetText(new WidgetPointer(63,8), intToStr(standart_config_620) + " Constitution XP"); + setWidgetText(new WidgetPointer(63,7), intToStr(standart_config_621) + " Slayer XP"); + return; +} diff --git a/dumps/scripts/1618.cs2 b/dumps/scripts/1618.cs2 new file mode 100644 index 0000000..0c3a87a --- /dev/null +++ b/dumps/scripts/1618.cs2 @@ -0,0 +1,33 @@ +void script_1618() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + ivar0 = -1; + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + ivar4 = 0; + setWidgetIsHidden(false, new WidgetPointer(287,4)); + if (((boolean)globalint_1032)) { + ivar0 = 221; + } else { + ivar0 = 222; + } + ivar1 = getItemContainerLength(ivar0); + if (ivar1 != multiply(5, 5)) { + messageType0("Nothing happens, as if something is wrong."); + return; + } + while (ivar4 < ivar1) { + script_1619(ivar2, ivar3, getItemIdInSlot(ivar0, ivar4)); + ivar2 = add(ivar2, 1); + if (ivar2 >= 5) { + ivar2 = 0; + ivar3 = add(ivar3, 1); + } + ivar4 = add(ivar4, 1); + } + return; +} diff --git a/dumps/scripts/1619.cs2 b/dumps/scripts/1619.cs2 new file mode 100644 index 0000000..aacd4a6 --- /dev/null +++ b/dumps/scripts/1619.cs2 @@ -0,0 +1,13 @@ +void script_1619(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + if ((((arg0 < 0) || (arg0 >= 5)) || (arg1 < 0)) || (arg1 >= 5)) { + messageType0("Nothing happens, as if something has gone wrong."); + return; + } + ivar3 = cs2method_3408(105, 103, 800, arg1); + ivar4 = ((int)cs2method_3408(105, 73, ivar3, arg0)); + setWidgetModel(cs2method_3408(111, 109, 797, arg2), new WidgetPointer(ivar4)); + setWidget3DRotation(0, 0, 520, 0, 0, 2180, new WidgetPointer(ivar4)); + return; +} diff --git a/dumps/scripts/162.cs2 b/dumps/scripts/162.cs2 new file mode 100644 index 0000000..ce4d3d6 --- /dev/null +++ b/dumps/scripts/162.cs2 @@ -0,0 +1,12 @@ +void script_162(int arg0,int arg1,int arg2,int arg3) { + if (setWidgetRegister(new WidgetPointer(arg1), arg0)) { + arg3 = subtract(arg3, cs2method2601(new WidgetPointer(arg1))); + if (arg3 < 10) { + script_157(arg2, arg1, subtract(cs2method2601(new WidgetPointer(arg1)), 4), 1); + } + if (add(arg3, getWidgetActualHeight()) > subtract(getWidgetActualHeight(new WidgetPointer(arg1)), 10)) { + script_157(arg2, arg1, add(cs2method2601(new WidgetPointer(arg1)), 4), 1); + } + } + return; +} diff --git a/dumps/scripts/1620.cs2 b/dumps/scripts/1620.cs2 new file mode 100644 index 0000000..7ad36d5 --- /dev/null +++ b/dumps/scripts/1620.cs2 @@ -0,0 +1,8 @@ +void script_1620(int arg0,int arg1,int arg2,int arg3,int arg4) { + arg4 = add(arg4, getClientCycle()); + if (setWidgetRegister(new WidgetPointer(arg0), arg1) || ((arg1 == -1) && setWidgetRegister(new WidgetPointer(arg0)))) { + cs2method2103(arg2); + setScriptCallOnGameloop(1621, new WidgetPointer(arg0), arg1, arg3, arg4, "Iiii"); + } + return; +} diff --git a/dumps/scripts/1621.cs2 b/dumps/scripts/1621.cs2 new file mode 100644 index 0000000..ea03cfc --- /dev/null +++ b/dumps/scripts/1621.cs2 @@ -0,0 +1,10 @@ +void script_1621(int arg0,int arg1,int arg2,int arg3) { + if (getClientCycle() < arg3) { + return; + } + if (setWidgetRegister(new WidgetPointer(arg0), arg1) || ((arg1 == -1) && setWidgetRegister(new WidgetPointer(arg0)))) { + cs2method2103(arg2); + setScriptCallOnGameloop(-1, ""); + } + return; +} diff --git a/dumps/scripts/1622.cs2 b/dumps/scripts/1622.cs2 new file mode 100644 index 0000000..31580de --- /dev/null +++ b/dumps/scripts/1622.cs2 @@ -0,0 +1,37 @@ +void script_1622(int arg0) { + switch (arg0) { + case 21561344: + if (setWidgetRegister(new WidgetPointer(329,2))) { + setWidgetSprite(6367); + } + if (setWidgetRegister(new WidgetPointer(329,3))) { + setWidgetSprite(6368); + } + if (setWidgetRegister(new WidgetPointer(329,4))) { + setWidgetSprite(6369); + } + break; + case 33947660: + if (setWidgetRegister(new WidgetPointer(518,0))) { + setWidgetSprite(6367); + } + if (setWidgetRegister(new WidgetPointer(518,1))) { + setWidgetSprite(6368); + } + if (setWidgetRegister(new WidgetPointer(518,2))) { + setWidgetSprite(6369); + } + break; + case 21561345: + if (setWidgetRegister(new WidgetPointer(329,40))) { + setWidgetSprite(6367); + } + if (setWidgetRegister(new WidgetPointer(329,41))) { + setWidgetSprite(6368); + } + if (setWidgetRegister(new WidgetPointer(329,42))) { + setWidgetSprite(6369); + } + } + return; +} diff --git a/dumps/scripts/1623.cs2 b/dumps/scripts/1623.cs2 new file mode 100644 index 0000000..514cf93 --- /dev/null +++ b/dumps/scripts/1623.cs2 @@ -0,0 +1,37 @@ +void script_1623(int arg0) { + switch (arg0) { + case 21561344: + if (setWidgetRegister(new WidgetPointer(329,2))) { + setWidgetSprite(6355); + } + if (setWidgetRegister(new WidgetPointer(329,3))) { + setWidgetSprite(6356); + } + if (setWidgetRegister(new WidgetPointer(329,4))) { + setWidgetSprite(6357); + } + break; + case 33947660: + if (setWidgetRegister(new WidgetPointer(518,0))) { + setWidgetSprite(6355); + } + if (setWidgetRegister(new WidgetPointer(518,1))) { + setWidgetSprite(6356); + } + if (setWidgetRegister(new WidgetPointer(518,2))) { + setWidgetSprite(6357); + } + break; + case 21561345: + if (setWidgetRegister(new WidgetPointer(329,40))) { + setWidgetSprite(6355); + } + if (setWidgetRegister(new WidgetPointer(329,41))) { + setWidgetSprite(6356); + } + if (setWidgetRegister(new WidgetPointer(329,42))) { + setWidgetSprite(6357); + } + } + return; +} diff --git a/dumps/scripts/1624.cs2 b/dumps/scripts/1624.cs2 new file mode 100644 index 0000000..4a604f3 --- /dev/null +++ b/dumps/scripts/1624.cs2 @@ -0,0 +1,12 @@ +void script_1624() { + if (((boolean)getLanguage())) { + setWidgetSprite(7668, new WidgetPointer(518,6)); + } else if (getLanguage() == 2) { + setWidgetSprite(7667, new WidgetPointer(518,6)); + } else { + if (getLanguage() == 3) { + setWidgetSprite(7669, new WidgetPointer(518,6)); + } + } + return; +} diff --git a/dumps/scripts/1625.cs2 b/dumps/scripts/1625.cs2 new file mode 100644 index 0000000..48dadab --- /dev/null +++ b/dumps/scripts/1625.cs2 @@ -0,0 +1,4 @@ +void script_1625() { + script_1626(); + return; +} diff --git a/dumps/scripts/1626.cs2 b/dumps/scripts/1626.cs2 new file mode 100644 index 0000000..f257aa6 --- /dev/null +++ b/dumps/scripts/1626.cs2 @@ -0,0 +1,18 @@ +void script_1626() { + string svar0; + string svar1; + svar0 = "Curtsy"; + svar1 = "Bow"; + if (((int)IsFemale()) > 0) { + setWidgetSprite(2317, new WidgetPointer(464,4)); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(464,54), svar0, 50, 150, "IIsii", new WidgetPointer(464,4)); + setWidgetContextMenuOption(1, new WidgetPointer(464,4), svar0); + setWidgetContextMenuOption(2, new WidgetPointer(464,4), svar1); + } else { + setWidgetSprite(703, new WidgetPointer(464,4)); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(464,54), svar1, 50, 150, "IIsii", new WidgetPointer(464,4)); + setWidgetContextMenuOption(2, new WidgetPointer(464,4), svar0); + setWidgetContextMenuOption(1, new WidgetPointer(464,4), svar1); + } + return; +} diff --git a/dumps/scripts/1627.cs2 b/dumps/scripts/1627.cs2 new file mode 100644 index 0000000..81219c7 --- /dev/null +++ b/dumps/scripts/1627.cs2 @@ -0,0 +1,4 @@ +void script_1627() { + script_1628(); + return; +} diff --git a/dumps/scripts/1628.cs2 b/dumps/scripts/1628.cs2 new file mode 100644 index 0000000..8a1ea00 --- /dev/null +++ b/dumps/scripts/1628.cs2 @@ -0,0 +1,26 @@ +void script_1628() { + int ivar0; + int ivar1; + int ivar2; + globalint_1033 = 0; + ivar0 = subtract(extractX(getMyPositionHash()), mod(extractX(getMyPositionHash()), 64)); + ivar1 = subtract(extractY(getMyPositionHash()), mod(extractY(getMyPositionHash()), 64)); + ivar2 = addToCoordinate(0, ivar0, 0, ivar1); + cs2method5405(0, 6); + cs2method5406(0, 0, addToCoordinate(ivar2, 22, 0, 9), 450, addToCoordinate(ivar2, 22, 0, 9), 400, 0); + cs2method5406(0, 1, addToCoordinate(ivar2, 13, 0, 17), 450, addToCoordinate(ivar2, 13, 0, 7), 400, 0); + cs2method5406(0, 2, addToCoordinate(ivar2, 17, 0, 20), 550, addToCoordinate(ivar2, 17, 0, 20), 600, 0); + cs2method5406(0, 3, addToCoordinate(ivar2, 17, 0, 20), 650, addToCoordinate(ivar2, 17, 0, 20), 700, 0); + cs2method5406(0, 4, addToCoordinate(ivar2, 24, 0, 19), 450, addToCoordinate(ivar2, 24, 0, 19), 500, 0); + cs2method5406(0, 5, addToCoordinate(ivar2, 26, 0, 12), 450, addToCoordinate(ivar2, 26, 0, 12), 500, 0); + cs2method5405(1, 6); + cs2method5406(1, 0, addToCoordinate(ivar2, 8, 0, 12), 300, addToCoordinate(ivar2, 8, 0, 12), 300, 0); + cs2method5406(1, 1, addToCoordinate(ivar2, 8, 0, 20), 300, addToCoordinate(ivar2, 8, 0, 20), 300, 0); + cs2method5406(1, 2, addToCoordinate(ivar2, 8, 0, 12), 300, addToCoordinate(ivar2, 8, 0, 12), 300, 0); + cs2method5406(1, 3, addToCoordinate(ivar2, 8, 0, 28), 300, addToCoordinate(ivar2, 8, 0, 28), 300, 0); + cs2method5406(1, 4, addToCoordinate(ivar2, 30, 0, 16), 300, addToCoordinate(ivar2, 30, 0, 16), 300, 0); + cs2method5406(1, 5, addToCoordinate(ivar2, 30, 0, 16), 400, addToCoordinate(ivar2, 30, 0, 16), 400, 0); + setScriptCallOnMinimapRelatedSetting3(1631, "", new WidgetPointer(75,0)); + cameraMethod5502(0, 0, 200, 200, 1, 0); + return; +} diff --git a/dumps/scripts/1629.cs2 b/dumps/scripts/1629.cs2 new file mode 100644 index 0000000..dd658ac --- /dev/null +++ b/dumps/scripts/1629.cs2 @@ -0,0 +1,6 @@ +void script_1629() { + globalint_1033 = 1; + cameraMethod5502(0, globalint_1033, 200, 100, 1, globalint_1033); + setScriptCallOnMinimapRelatedSetting3(1631, "", new WidgetPointer(75,0)); + return; +} diff --git a/dumps/scripts/163.cs2 b/dumps/scripts/163.cs2 new file mode 100644 index 0000000..6175840 --- /dev/null +++ b/dumps/scripts/163.cs2 @@ -0,0 +1,4 @@ +void script_163(int arg0) { + setWidgetSprite(941, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1630.cs2 b/dumps/scripts/1630.cs2 new file mode 100644 index 0000000..4beeae9 --- /dev/null +++ b/dumps/scripts/1630.cs2 @@ -0,0 +1,6 @@ +void script_1630() { + globalint_1033 = 3; + cameraMethod5502(0, globalint_1033, 200, 200, 1, globalint_1033); + setScriptCallOnMinimapRelatedSetting3(1631, "", new WidgetPointer(75,0)); + return; +} diff --git a/dumps/scripts/1631.cs2 b/dumps/scripts/1631.cs2 new file mode 100644 index 0000000..7d9b3d6 --- /dev/null +++ b/dumps/scripts/1631.cs2 @@ -0,0 +1,21 @@ +void script_1631() { + if (globalint_1033 <= cs2method5407(0)) { + flow_1: + globalint_1033 = add(globalint_1033, 1); + SWITCH (globalint_1033) { + case 4: + GOTO flow_2 + case 2: + GOTO flow_2 + } + setScriptCallOnMinimapRelatedSetting3(-1, "", new WidgetPointer(75,0)); + GOTO flow_3 + flow_2: + setScriptCallOnMinimapRelatedSetting3(1631, "", new WidgetPointer(75,0)); + cameraMethod5502(0, globalint_1033, 200, 200, 1, globalint_1033); + flow_3: + } else { + globalint_1033 = 0; + } + return; +} diff --git a/dumps/scripts/1632.cs2 b/dumps/scripts/1632.cs2 new file mode 100644 index 0000000..168b6c5 --- /dev/null +++ b/dumps/scripts/1632.cs2 @@ -0,0 +1,8 @@ +void script_1632() { + int ivar0; + setWidgetIsHidden(true, new WidgetPointer(1109,22)); + setWidgetIsHidden(true, new WidgetPointer(1109,20)); + ivar0 = getWidgetActualY(new WidgetPointer(1109,18)); + setWidgetPosition(148, ivar0, 0, 0, new WidgetPointer(1109,18)); + return; +} diff --git a/dumps/scripts/1633.cs2 b/dumps/scripts/1633.cs2 new file mode 100644 index 0000000..7cfe5d5 --- /dev/null +++ b/dumps/scripts/1633.cs2 @@ -0,0 +1,59 @@ +void script_1633(string arg0) { + int ivar0; + int ivar1; + string svar1; + arg0 = lower(strRemoveEntities(arg0)); + ivar0 = strLength(arg0); + ivar1 = 0; + arg0 = script_2332(arg0, "_", "\u00a0"); + arg0 = script_2332(arg0, "-", "\u00a0"); + arg0 = script_2332(arg0, " ", "\u00a0"); + while (((boolean)strIndexof(0, arg0, " ")) && (ivar0 > 0)) { + arg0 = substr(1, ivar0, arg0); + ivar0 = strLength(arg0); + } + while ((strIndexof(subtract(ivar0, 1), arg0, " ") == subtract(ivar0, 1)) && (ivar0 > 0)) { + arg0 = substr(0, subtract(ivar0, 1), arg0); + ivar0 = strLength(arg0); + } + while (((boolean)strIndexof(0, arg0, "\u00a0")) && (ivar0 > 0)) { + arg0 = substr(1, ivar0, arg0); + ivar0 = strLength(arg0); + } + while ((strIndexof(subtract(ivar0, 1), arg0, "\u00a0") == subtract(ivar0, 1)) && (ivar0 > 0)) { + arg0 = substr(0, subtract(ivar0, 1), arg0); + ivar0 = strLength(arg0); + } + svar1 = lower(strRemoveEntities(cs2method5020())); + ivar0 = strLength(svar1); + svar1 = script_2332(svar1, "_", "\u00a0"); + svar1 = script_2332(svar1, "-", "\u00a0"); + svar1 = script_2332(svar1, " ", "\u00a0"); + while (((boolean)strIndexof(0, svar1, " ")) && (ivar0 > 0)) { + svar1 = substr(1, ivar0, svar1); + ivar0 = strLength(svar1); + } + while ((strIndexof(subtract(ivar0, 1), arg0, " ") == subtract(ivar0, 1)) && (ivar0 > 0)) { + svar1 = substr(0, subtract(ivar0, 1), svar1); + ivar0 = strLength(svar1); + } + while (((boolean)strIndexof(0, svar1, "\u00a0")) && (ivar0 > 0)) { + svar1 = substr(1, ivar0, svar1); + ivar0 = strLength(svar1); + } + while ((strIndexof(subtract(ivar0, 1), svar1, "\u00a0") == subtract(ivar0, 1)) && (ivar0 > 0)) { + svar1 = substr(0, subtract(ivar0, 1), svar1); + ivar0 = strLength(svar1); + } + if (stringMethod4107(arg0, "") != 0) { + if (((boolean)stringMethod4107(arg0, svar1))) { + script_1890("You cannot kick or ban yourself."); + return; + } + cs2method3617(arg0); + arg0 = script_1814(arg0); + cs2method5006(1); + cs2method5008("[Attempting to kick/ban " + arg0 + " from this Friends Chat.]"); + } + return; +} diff --git a/dumps/scripts/1634.cs2 b/dumps/scripts/1634.cs2 new file mode 100644 index 0000000..05fae40 --- /dev/null +++ b/dumps/scripts/1634.cs2 @@ -0,0 +1,4 @@ +void script_1634(int arg0) { + setWidgetText(new WidgetPointer(arg0), intToStr(standart_config_1105)); + return; +} diff --git a/dumps/scripts/1635.cs2 b/dumps/scripts/1635.cs2 new file mode 100644 index 0000000..9c9e369 --- /dev/null +++ b/dumps/scripts/1635.cs2 @@ -0,0 +1,4 @@ +void script_1635(int arg0) { + setWidgetText(new WidgetPointer(arg0), intToStr(bitconfig_6594)); + return; +} diff --git a/dumps/scripts/1636.cs2 b/dumps/scripts/1636.cs2 new file mode 100644 index 0000000..156bbec --- /dev/null +++ b/dumps/scripts/1636.cs2 @@ -0,0 +1,53 @@ +void script_1636(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int stack_dump0; + int stack_dump1; + int stack_dump2; + string stack_dump3; + cs2func_script_1637_struct(2,0,0) structdump_4; + cs2func_script_1637_struct(2,0,0) structdump_5; + deleteAllExtraChilds(new WidgetPointer(arg0)); + ivar2 = 0; + ivar3 = 0; + ivar4 = 0; + while (ivar4 < 50) { + stack_dump0 = arg0; + stack_dump1 = ivar3; + stack_dump2 = ivar2; + stack_dump3 = script_1638(ivar4); + structdump_4 = script_1637(stack_dump0, stack_dump1, stack_dump2, stack_dump3); + ivar2 = structdump_4.intpart_1; + ivar3 = structdump_4.intpart_0; + ivar4 = add(ivar4, 1); + } + if (((boolean)ivar3)) { + stack_dump0 = arg0; + stack_dump1 = 0; + stack_dump2 = 0; + stack_dump3 = "Loading..."; + structdump_5 = script_1637(stack_dump0, stack_dump1, stack_dump2, stack_dump3); + stack_dump0 = structdump_5.intpart_0; + structdump_5.intpart_1; + stack_dump0; + } + ivar5 = 0; + ivar6 = 0; + if (ivar2 > 15) { + ivar5 = cs2method2601(new WidgetPointer(arg0)); + ivar6 = add(multiply(ivar2, 15), 8); + setWidgetScrollMax(0, ivar6, new WidgetPointer(arg0)); + if (ivar5 > ivar6) { + ivar5 = ivar6; + } + script_72(arg1, arg0, ivar5); + } else { + setWidgetScrollMax(0, 0, new WidgetPointer(arg0)); + cs2method2100(0, 0, new WidgetPointer(arg0)); + script_72(arg1, arg0, 0); + } + return; +} diff --git a/dumps/scripts/1637.cs2 b/dumps/scripts/1637.cs2 new file mode 100644 index 0000000..eec92ef --- /dev/null +++ b/dumps/scripts/1637.cs2 @@ -0,0 +1,19 @@ +cs2func_script_1637_struct(2,0,0) script_1637(int arg0,int arg1,int arg2,string arg3) { + int ivar3; + if (((boolean)stringMethod4107(arg3, ""))) { + return newstruct cs2func_script_1637_struct(arg1, arg2); + } + createExtraChild(new WidgetPointer(arg0), 4, arg1); + setWidgetText(arg3); + setWidgetFont(495); + ivar3 = getLineCount(430, 495, arg3); + if (ivar3 < 1) { + ivar3 = 1; + } + setWidgetSize(430, multiply(14, ivar3), 0, 0); + setWidgetPosition(3, add(multiply(arg2, 15), 4), 0, 0); + setWidgetTextAlignment(1, 0, 14); + setWidgetRGB(new Color(170, 170, 170)); + setWidgetUnknownBoolean(true); + return newstruct cs2func_script_1637_struct(add(arg1, 1), add(arg2, ivar3)); +} diff --git a/dumps/scripts/1638.cs2 b/dumps/scripts/1638.cs2 new file mode 100644 index 0000000..8331322 --- /dev/null +++ b/dumps/scripts/1638.cs2 @@ -0,0 +1,105 @@ +string script_1638(int arg0) { + switch (arg0) { + case 0: + return globalstring_224; + case 1: + return globalstring_225; + case 2: + return globalstring_226; + case 3: + return globalstring_227; + case 4: + return globalstring_228; + case 5: + return globalstring_229; + case 6: + return globalstring_230; + case 7: + return globalstring_231; + case 8: + return globalstring_232; + case 9: + return globalstring_233; + case 10: + return globalstring_234; + case 11: + return globalstring_235; + case 12: + return globalstring_236; + case 13: + return globalstring_237; + case 14: + return globalstring_238; + case 15: + return globalstring_239; + case 16: + return globalstring_240; + case 17: + return globalstring_241; + case 18: + return globalstring_242; + case 19: + return globalstring_243; + case 20: + return globalstring_244; + case 21: + return globalstring_245; + case 22: + return globalstring_246; + case 23: + return globalstring_247; + case 24: + return globalstring_248; + case 25: + return globalstring_249; + case 26: + return globalstring_250; + case 27: + return globalstring_251; + case 28: + return globalstring_252; + case 29: + return globalstring_253; + case 30: + return globalstring_254; + case 31: + return globalstring_255; + case 32: + return globalstring_256; + case 33: + return globalstring_257; + case 34: + return globalstring_258; + case 35: + return globalstring_259; + case 36: + return globalstring_260; + case 37: + return globalstring_261; + case 38: + return globalstring_262; + case 39: + return globalstring_263; + case 40: + return globalstring_264; + case 41: + return globalstring_265; + case 42: + return globalstring_266; + case 43: + return globalstring_267; + case 44: + return globalstring_268; + case 45: + return globalstring_269; + case 46: + return globalstring_270; + case 47: + return globalstring_271; + case 48: + return globalstring_272; + case 49: + return globalstring_273; + } + return ""; +} diff --git a/dumps/scripts/1639.cs2 b/dumps/scripts/1639.cs2 new file mode 100644 index 0000000..ded3f41 --- /dev/null +++ b/dumps/scripts/1639.cs2 @@ -0,0 +1,67 @@ +void script_1639() { + int stack_dump0; + int stack_dump1; + int stack_dump2; + string stack_dump3; + cs2func_script_1637_struct(2,0,0) structdump_4; + globalstring_224 = ""; + globalstring_225 = ""; + globalstring_226 = ""; + globalstring_227 = ""; + globalstring_228 = ""; + globalstring_229 = ""; + globalstring_230 = ""; + globalstring_231 = ""; + globalstring_232 = ""; + globalstring_233 = ""; + globalstring_234 = ""; + globalstring_235 = ""; + globalstring_236 = ""; + globalstring_237 = ""; + globalstring_238 = ""; + globalstring_239 = ""; + globalstring_240 = ""; + globalstring_241 = ""; + globalstring_242 = ""; + globalstring_243 = ""; + globalstring_244 = ""; + globalstring_245 = ""; + globalstring_246 = ""; + globalstring_247 = ""; + globalstring_248 = ""; + globalstring_249 = ""; + globalstring_250 = ""; + globalstring_251 = ""; + globalstring_252 = ""; + globalstring_253 = ""; + globalstring_254 = ""; + globalstring_255 = ""; + globalstring_256 = ""; + globalstring_257 = ""; + globalstring_258 = ""; + globalstring_259 = ""; + globalstring_260 = ""; + globalstring_261 = ""; + globalstring_262 = ""; + globalstring_263 = ""; + globalstring_264 = ""; + globalstring_265 = ""; + globalstring_266 = ""; + globalstring_267 = ""; + globalstring_268 = ""; + globalstring_269 = ""; + globalstring_270 = ""; + globalstring_271 = ""; + globalstring_272 = ""; + globalstring_273 = ""; + deleteAllExtraChilds(new WidgetPointer(632,15)); + stack_dump0 = 41418767; + stack_dump1 = 0; + stack_dump2 = 0; + stack_dump3 = "Loading..."; + structdump_4 = script_1637(stack_dump0, stack_dump1, stack_dump2, stack_dump3); + stack_dump0 = structdump_4.intpart_0; + structdump_4.intpart_1; + stack_dump0; + return; +} diff --git a/dumps/scripts/164.cs2 b/dumps/scripts/164.cs2 new file mode 100644 index 0000000..718e7ff --- /dev/null +++ b/dumps/scripts/164.cs2 @@ -0,0 +1,8 @@ +void script_164(int arg0,int arg1) { + if (script_166(arg1) == 7) { + setWidgetSprite(942, new WidgetPointer(arg0)); + return; + } + setWidgetSprite(941, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1640.cs2 b/dumps/scripts/1640.cs2 new file mode 100644 index 0000000..04135fc --- /dev/null +++ b/dumps/scripts/1640.cs2 @@ -0,0 +1,19 @@ +void script_1640(int arg0,int arg1,int arg2) { + int ivar3; + string svar0; + svar0 = globalstring_274; + ivar3 = getWidgetActualWidth(new WidgetPointer(arg0)); + if (getMaxLineWidth(ivar3, arg2, svar0 + " ") > ivar3) { + while (getMaxLineWidth(2147483647, arg2, svar0 + "... ") > ivar3) { + svar0 = substr(0, subtract(strLength(svar0), 1), svar0); + } + svar0 = svar0 + "..."; + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(arg1), globalstring_274, 25, 5000, "IIsii", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(40, new WidgetPointer(arg1), "I", new WidgetPointer(arg0)); + } else { + setScriptCallOnMouseOver(-1, "", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg0)); + } + setWidgetText(new WidgetPointer(arg0), svar0); + return; +} diff --git a/dumps/scripts/1641.cs2 b/dumps/scripts/1641.cs2 new file mode 100644 index 0000000..d07b5c1 --- /dev/null +++ b/dumps/scripts/1641.cs2 @@ -0,0 +1,3 @@ +int script_1641() { + return add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(bitconfig_6598, bitconfig_6599), bitconfig_6600), bitconfig_6601), bitconfig_6602), bitconfig_6603), bitconfig_6604), bitconfig_6605), bitconfig_6606), bitconfig_6607), bitconfig_6608), bitconfig_6609), bitconfig_1421), bitconfig_6611), bitconfig_6612), bitconfig_6613), bitconfig_6614), bitconfig_6615), bitconfig_6616), bitconfig_6617), bitconfig_6618), bitconfig_6619), bitconfig_6620); +} diff --git a/dumps/scripts/1642.cs2 b/dumps/scripts/1642.cs2 new file mode 100644 index 0000000..6572555 --- /dev/null +++ b/dumps/scripts/1642.cs2 @@ -0,0 +1,3 @@ +int script_1642() { + return 23; +} diff --git a/dumps/scripts/1643.cs2 b/dumps/scripts/1643.cs2 new file mode 100644 index 0000000..f8687d4 --- /dev/null +++ b/dumps/scripts/1643.cs2 @@ -0,0 +1,3 @@ +int script_1643() { + return add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(bitconfig_6622, bitconfig_6623), bitconfig_6624), bitconfig_6625), bitconfig_6626), bitconfig_6627), bitconfig_6650), bitconfig_6629), bitconfig_6630), bitconfig_6631), bitconfig_6632), bitconfig_6633), bitconfig_6634), bitconfig_6635), bitconfig_6636), bitconfig_6637); +} diff --git a/dumps/scripts/1644.cs2 b/dumps/scripts/1644.cs2 new file mode 100644 index 0000000..a31f8ce --- /dev/null +++ b/dumps/scripts/1644.cs2 @@ -0,0 +1,3 @@ +int script_1644() { + return 16; +} diff --git a/dumps/scripts/1645.cs2 b/dumps/scripts/1645.cs2 new file mode 100644 index 0000000..367d51c --- /dev/null +++ b/dumps/scripts/1645.cs2 @@ -0,0 +1,3 @@ +int script_1645() { + return add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(bitconfig_6639, bitconfig_6640), bitconfig_6641), bitconfig_6642), bitconfig_6643), bitconfig_6644), bitconfig_6645), bitconfig_6646), bitconfig_6647), bitconfig_6648), bitconfig_6649), bitconfig_6628), bitconfig_6651), bitconfig_6652), bitconfig_6653), bitconfig_6654), bitconfig_6655); +} diff --git a/dumps/scripts/1646.cs2 b/dumps/scripts/1646.cs2 new file mode 100644 index 0000000..677d184 --- /dev/null +++ b/dumps/scripts/1646.cs2 @@ -0,0 +1,3 @@ +int script_1646() { + return 17; +} diff --git a/dumps/scripts/1647.cs2 b/dumps/scripts/1647.cs2 new file mode 100644 index 0000000..779b9a0 --- /dev/null +++ b/dumps/scripts/1647.cs2 @@ -0,0 +1,3 @@ +int script_1647() { + return add(add(add(add(bitconfig_6658, bitconfig_6659), bitconfig_6660), bitconfig_6661), bitconfig_6662); +} diff --git a/dumps/scripts/1648.cs2 b/dumps/scripts/1648.cs2 new file mode 100644 index 0000000..06e6d58 --- /dev/null +++ b/dumps/scripts/1648.cs2 @@ -0,0 +1,3 @@ +int script_1648() { + return 67; +} diff --git a/dumps/scripts/1649.cs2 b/dumps/scripts/1649.cs2 new file mode 100644 index 0000000..17def6f --- /dev/null +++ b/dumps/scripts/1649.cs2 @@ -0,0 +1,11 @@ +void script_1649(int arg0,int arg1) { + if (((boolean)arg1)) { + if (arg0 < 0) { + arg0 = 0; + } else { + arg0 = subtract(arg0, mod(arg0, 14)); + } + } + script_1651(arg0, 1); + return; +} diff --git a/dumps/scripts/165.cs2 b/dumps/scripts/165.cs2 new file mode 100644 index 0000000..4069d0d --- /dev/null +++ b/dumps/scripts/165.cs2 @@ -0,0 +1,15 @@ +void script_165(int arg0,int arg1) { + int ivar2; + ivar2 = script_166(arg1); + if (ivar2 == 7) { + setWidgetSprite(833, new WidgetPointer(arg0)); + setWidgetRGB(new Color(255, 0, 0), cs2method_3408(105, 73, 688, arg1)); + } else if (ivar2 == 6) { + setWidgetSprite(834, new WidgetPointer(arg0)); + setWidgetRGB(new Color(0, 255, 0), cs2method_3408(105, 73, 688, arg1)); + } else { + setWidgetSprite(943, new WidgetPointer(arg0)); + setWidgetRGB(new Color(204, 204, 204), cs2method_3408(105, 73, 688, arg1)); + } + return; +} diff --git a/dumps/scripts/1650.cs2 b/dumps/scripts/1650.cs2 new file mode 100644 index 0000000..9422d37 --- /dev/null +++ b/dumps/scripts/1650.cs2 @@ -0,0 +1,25 @@ +void script_1650() { + if (((boolean)script_1653())) { + script_1652(0); + setWidgetIsHidden(true, new WidgetPointer(746,75)); + return; + } + if (globalint_41 != -1) { + setWidgetIsHidden(false, new WidgetPointer(746,75)); + } + if (globalint_1037 < 142) { + globalint_1037 = 142; + } else { + if (globalint_1037 > subtract(getWidgetActualHeight(new WidgetPointer(746,3)), 117)) { + script_1651(0, 1); + return; + } + } + setWidgetSize(519, globalint_1037, 0, 0, new WidgetPointer(746,73)); + setWidgetPosition(0, 23, 0, 2, new WidgetPointer(746,73)); + setWidgetPosition(0, subtract(getWidgetActualY(new WidgetPointer(746,73)), 94), 0, 0, new WidgetPointer(746,75)); + setWidgetPosition(0, subtract(getWidgetActualY(new WidgetPointer(746,73)), 69), 0, 0, new WidgetPointer(746,72)); + script_1301(8978491, 8978490); + script_84(); + return; +} diff --git a/dumps/scripts/1651.cs2 b/dumps/scripts/1651.cs2 new file mode 100644 index 0000000..fc59eff --- /dev/null +++ b/dumps/scripts/1651.cs2 @@ -0,0 +1,27 @@ +void script_1651(int arg0,int arg1) { + int ivar2; + if (((boolean)script_1653())) { + arg0 = subtract(getWidgetActualHeight(new WidgetPointer(746,3)), 172); + setWidgetIsHidden(true, new WidgetPointer(746,75)); + } else { + if (globalint_41 != -1) { + setWidgetIsHidden(false, new WidgetPointer(746,75)); + } + } + ivar2 = subtract(subtract(subtract(getWidgetActualHeight(new WidgetPointer(746,3)), 87), arg0), 30); + ivar2 = subtract(ivar2, mod(ivar2, 14)); + if (ivar2 < 142) { + ivar2 = 142; + } + globalint_7 = subtract(globalint_7, subtract(ivar2, getWidgetActualHeight(new WidgetPointer(746,73)))); + setWidgetSize(519, ivar2, 0, 0, new WidgetPointer(746,73)); + setWidgetPosition(0, 23, 0, 2, new WidgetPointer(746,73)); + if (((boolean)arg1)) { + globalint_1037 = ivar2; + } + setWidgetPosition(0, subtract(getWidgetActualY(new WidgetPointer(746,73)), 94), 0, 0, new WidgetPointer(746,75)); + setWidgetPosition(0, subtract(getWidgetActualY(new WidgetPointer(746,73)), 69), 0, 0, new WidgetPointer(746,72)); + script_1301(8978491, 8978490); + script_84(); + return; +} diff --git a/dumps/scripts/1652.cs2 b/dumps/scripts/1652.cs2 new file mode 100644 index 0000000..2998d5b --- /dev/null +++ b/dumps/scripts/1652.cs2 @@ -0,0 +1,4 @@ +void script_1652(int arg0) { + script_1651(subtract(getWidgetActualHeight(new WidgetPointer(746,3)), 259), arg0); + return; +} diff --git a/dumps/scripts/1653.cs2 b/dumps/scripts/1653.cs2 new file mode 100644 index 0000000..a72126e --- /dev/null +++ b/dumps/scripts/1653.cs2 @@ -0,0 +1,17 @@ +int script_1653() { + flow_0: + IF (isWidgetHidden(new WidgetPointer(752,8))) + GOTO flow_1 + GOTO flow_2 + flow_1: + IF (isWidgetHidden(new WidgetPointer(752,3)) || isWidgetHidden(new WidgetPointer(752,7))) + GOTO flow_3 + flow_2: + IF ((((isWidgetOpen(new WidgetPointer(752,13)) || isWidgetOpen(new WidgetPointer(752,12))) || isWidgetOpen(new WidgetPointer(752,11))) || isWidgetOpen(new WidgetPointer(752,10))) || isWidgetHidden(new WidgetPointer(137,0))) + GOTO flow_3 + GOTO flow_4 + flow_3: + return 1; + flow_4: + return 0; +} diff --git a/dumps/scripts/1654.cs2 b/dumps/scripts/1654.cs2 new file mode 100644 index 0000000..bfaf8bf --- /dev/null +++ b/dumps/scripts/1654.cs2 @@ -0,0 +1,7 @@ +void script_1654() { + if (globalint_193 <= getClientCycle()) { + globalint_193 = add(getClientCycle(), 10); + setScriptCallOnGameloop(1452, globalint_193, "i", new WidgetPointer(762,93)); + } + return; +} diff --git a/dumps/scripts/1655.cs2 b/dumps/scripts/1655.cs2 new file mode 100644 index 0000000..27b9568 --- /dev/null +++ b/dumps/scripts/1655.cs2 @@ -0,0 +1,4 @@ +void script_1655() { + script_1656(); + return; +} diff --git a/dumps/scripts/1656.cs2 b/dumps/scripts/1656.cs2 new file mode 100644 index 0000000..980a4b2 --- /dev/null +++ b/dumps/scripts/1656.cs2 @@ -0,0 +1,11 @@ +void script_1656() { + if (((boolean)bitconfig_6673)) { + setScriptCallOnClickContextMenu(29, "", new WidgetPointer(767,10)); + setWidgetIsHidden(true, new WidgetPointer(767,54)); + } else { + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(767,10)); + setWidgetIsHidden(false, new WidgetPointer(767,54)); + script_679(50266167); + } + return; +} diff --git a/dumps/scripts/1657.cs2 b/dumps/scripts/1657.cs2 new file mode 100644 index 0000000..042fed0 --- /dev/null +++ b/dumps/scripts/1657.cs2 @@ -0,0 +1,7 @@ +void script_1657(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7) { + script_31(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + if (setWidgetRegister(new WidgetPointer(arg0), 1)) { + script_37(arg0, arg1, globalint_107, 1); + } + return; +} diff --git a/dumps/scripts/1658.cs2 b/dumps/scripts/1658.cs2 new file mode 100644 index 0000000..6a99137 --- /dev/null +++ b/dumps/scripts/1658.cs2 @@ -0,0 +1,3 @@ +void script_1658() { + return; +} diff --git a/dumps/scripts/1659.cs2 b/dumps/scripts/1659.cs2 new file mode 100644 index 0000000..589d33d --- /dev/null +++ b/dumps/scripts/1659.cs2 @@ -0,0 +1,3 @@ +void script_1659() { + return; +} diff --git a/dumps/scripts/166.cs2 b/dumps/scripts/166.cs2 new file mode 100644 index 0000000..74c5e45 --- /dev/null +++ b/dumps/scripts/166.cs2 @@ -0,0 +1,73 @@ +int script_166(int arg0) { + switch (arg0) { + case 1: + return bitconfig_3851; + case 2: + return bitconfig_3852; + case 3: + return bitconfig_3853; + case 4: + return bitconfig_3854; + case 5: + return bitconfig_3855; + case 6: + return bitconfig_3856; + case 7: + return bitconfig_3857; + case 8: + return bitconfig_3858; + case 9: + return bitconfig_3859; + case 10: + return bitconfig_3860; + case 11: + return bitconfig_3861; + case 12: + return bitconfig_3862; + case 13: + return bitconfig_3863; + case 14: + return bitconfig_3864; + case 15: + return bitconfig_3865; + case 16: + return bitconfig_3866; + case 17: + return bitconfig_3867; + case 18: + return bitconfig_3868; + case 19: + return bitconfig_3869; + case 20: + return bitconfig_3870; + case 22: + if (((boolean)bitconfig_5294)) { + return 7; + } + return 0; + case 23: + return bitconfig_3871; + case 24: + return bitconfig_3872; + case 25: + return bitconfig_3946; + case 26: + return bitconfig_4132; + case 27: + return bitconfig_4307; + case 28: + return bitconfig_4308; + case 29: + return bitconfig_4309; + case 30: + return bitconfig_5366; + case 31: + if (((boolean)bitconfig_5295)) { + return 7; + } + return 0; + case 33: + return bitconfig_6500; + } + return 0; +} diff --git a/dumps/scripts/1660.cs2 b/dumps/scripts/1660.cs2 new file mode 100644 index 0000000..3c7ecd3 --- /dev/null +++ b/dumps/scripts/1660.cs2 @@ -0,0 +1,4 @@ +void script_1660(int arg0,int arg1,int arg2) { + script_1661(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/1661.cs2 b/dumps/scripts/1661.cs2 new file mode 100644 index 0000000..ecade1e --- /dev/null +++ b/dumps/scripts/1661.cs2 @@ -0,0 +1,14 @@ +void script_1661(int arg0,int arg1,int arg2) { + deleteAllExtraChilds(new WidgetPointer(arg2)); + if ((bitconfig_4895 != 3) || (standart_config_281 != 55)) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg2)); + return; + } + createExtraChild(new WidgetPointer(arg2), 6, 0); + setWidgetModel(41760); + setWidgetAnimation(10221); + setWidgetSize(43, 43, 0, 0); + script_1663(arg0, arg1, arg2); + setScriptCallOnGameloop(1662, new WidgetPointer(arg0), arg1, new WidgetPointer(arg2), "IiI", new WidgetPointer(arg2)); + return; +} diff --git a/dumps/scripts/1662.cs2 b/dumps/scripts/1662.cs2 new file mode 100644 index 0000000..041e604 --- /dev/null +++ b/dumps/scripts/1662.cs2 @@ -0,0 +1,6 @@ +void script_1662(int arg0,int arg1,int arg2) { + if (setWidgetRegister(new WidgetPointer(arg2), 0)) { + script_1663(arg0, arg1, arg2); + } + return; +} diff --git a/dumps/scripts/1663.cs2 b/dumps/scripts/1663.cs2 new file mode 100644 index 0000000..f965753 --- /dev/null +++ b/dumps/scripts/1663.cs2 @@ -0,0 +1,28 @@ +void script_1663(int arg0,int arg1,int arg2) { + int ivar3; + ivar3 = 0; + if (setWidgetRegister(new WidgetPointer(arg0), arg1) && isWidgetHidden()) { + setWidgetHidden(0); + if (add(getWidgetActualY(), getWidgetActualHeight()) < cs2method2601(new WidgetPointer(arg0))) { + setWidget3DRotation(0, 0, 512, 1024, 0, 1500); + setWidgetPosition(0, getWidgetActualY(new WidgetPointer(arg0)), 1, 0); + return; + } + if (getWidgetActualY() >= add(cs2method2601(new WidgetPointer(arg0)), getWidgetActualHeight(new WidgetPointer(arg0)))) { + setWidget3DRotation(0, 0, 512, 0, 0, 1500); + setWidgetPosition(0, subtract(add(getWidgetActualY(new WidgetPointer(arg0)), getWidgetActualHeight(new WidgetPointer(arg0))), getWidgetActualHeight()), 1, 0); + return; + } + ivar3 = add(subtract(getWidgetActualY(), cs2method2601(new WidgetPointer(arg0))), getWidgetActualY(new WidgetPointer(arg0))); + if (ivar3 > subtract(getWidgetActualHeight(new WidgetPointer(arg2)), getWidgetActualHeight())) { + setWidget3DRotation(0, 0, 512, 256, 0, 1500); + setWidgetPosition(0, subtract(ivar3, getWidgetActualHeight()), 1, 0); + } else { + setWidget3DRotation(0, 0, 512, 768, 0, 1500); + setWidgetPosition(0, add(ivar3, getWidgetActualHeight()), 1, 0); + } + return; + } + setWidgetHidden(1); + return; +} diff --git a/dumps/scripts/1664.cs2 b/dumps/scripts/1664.cs2 new file mode 100644 index 0000000..cd81490 --- /dev/null +++ b/dumps/scripts/1664.cs2 @@ -0,0 +1,53 @@ +void script_1664(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int stack_dump0; + cs2func_script_1467_struct(2,0,0) structdump_1; + cs2func_script_1467_struct(2,0,0) structdump_2; + if (getClientCycle() < arg0) { + return; + } + setScriptCallOnGameloop(-1, "", new WidgetPointer(762,93)); + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + ivar4 = 0; + ivar5 = getItemContainerLength(95); + script_41(49938529); + stack_dump0 = bitconfig_4893; + structdump_1 = script_1467(stack_dump0); + ivar2 = structdump_1.intpart_1; + ivar1 = structdump_1.intpart_0; + while (ivar3 < ivar5) { + if (setWidgetRegister(new WidgetPointer(762,93), ivar3)) { + setWidgetHidden(1); + if (getItemIdInSlot(95, ivar3) != -1) { + script_1453(ivar3); + } else { + setItemOnWidgetMethod1200(-1, -1); + setWidgetNoOptions(); + } + } + ivar3 = add(ivar3, 1); + } + if (((boolean)bitconfig_4893)) { + if (globalint_5 == 11) { + globalstring_138 = globalstring_22; + } + script_1479(globalstring_138); + } else if (((boolean)bitconfig_4893)) { + script_1456(); + } else { + stack_dump0 = bitconfig_4893; + structdump_2 = script_1467(stack_dump0); + script_1457(structdump_2.intpart_0, structdump_2.intpart_1); + } + if ((bitconfig_4893 != 0) && ((boolean)globalint_188)) { + script_1474(); + } + script_1459(); + return; +} diff --git a/dumps/scripts/1665.cs2 b/dumps/scripts/1665.cs2 new file mode 100644 index 0000000..d2bd334 --- /dev/null +++ b/dumps/scripts/1665.cs2 @@ -0,0 +1,35 @@ +void script_1665(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + ivar4 = 0; + ivar5 = 0; + if (((boolean)script_3287())) { + ivar4 = add(subtract(516, 439), 1); + ivar5 = subtract(516, ivar4); + } else { + ivar4 = subtract(add(subtract(516, 439), 1), 10); + ivar5 = subtract(subtract(516, 10), ivar4); + } + ivar6 = globalint_1038; + ivar7 = subtract(globalint_192, ivar6); + ivar8 = multiply(subtract(ivar4, ivar6), -1); + ivar9 = subtract(ivar7, subtract(439, 1)); + if (ivar9 > 0) { + ivar6 = add(ivar6, ivar9); + ivar7 = subtract(439, 1); + } else { + if (ivar8 > 0) { + ivar7 = add(ivar7, ivar8); + ivar6 = ivar4; + } + } + setWidgetText(new WidgetPointer(arg0), intToStr(ivar6)); + setWidgetText(new WidgetPointer(arg2), intToStr(ivar7)); + setWidgetText(new WidgetPointer(arg1), intToStr(ivar4)); + setWidgetText(new WidgetPointer(arg3), intToStr(ivar5)); + return; +} diff --git a/dumps/scripts/1666.cs2 b/dumps/scripts/1666.cs2 new file mode 100644 index 0000000..04652f4 --- /dev/null +++ b/dumps/scripts/1666.cs2 @@ -0,0 +1,4 @@ +void script_1666() { + cs2method5421(1, "kbase/view.ws?guid=controls_banks#memberspace"); + return; +} diff --git a/dumps/scripts/1667.cs2 b/dumps/scripts/1667.cs2 new file mode 100644 index 0000000..9fc46d8 --- /dev/null +++ b/dumps/scripts/1667.cs2 @@ -0,0 +1,16 @@ +void script_1667() { + int ivar0; + ivar0 = 0; + if (cs2method3701()) { + script_4310(); + if (((boolean)script_4292())) { + setWidgetIsHidden(true, new WidgetPointer(1096,279)); + setWidgetIsHidden(true, new WidgetPointer(1096,265)); + } else { + setWidgetIsHidden(false, new WidgetPointer(1096,279)); + setWidgetIsHidden(false, new WidgetPointer(1096,265)); + } + } + script_4310(); + return; +} diff --git a/dumps/scripts/1668.cs2 b/dumps/scripts/1668.cs2 new file mode 100644 index 0000000..1adeefc --- /dev/null +++ b/dumps/scripts/1668.cs2 @@ -0,0 +1,17 @@ +string script_1668(int arg0) { + switch (arg0) { + case 1: + return "Herring"; + case 2: + return "Cod"; + case 3: + return "Bass"; + case 4: + return "Trout"; + case 5: + return "Pike"; + case 6: + return "Salmon"; + } + return "Fish"; +} diff --git a/dumps/scripts/1669.cs2 b/dumps/scripts/1669.cs2 new file mode 100644 index 0000000..07b08c8 --- /dev/null +++ b/dumps/scripts/1669.cs2 @@ -0,0 +1,7 @@ +void script_1669() { + setScriptCallOnItemContainerUpdate(2175, 93, 1, "Y", new WidgetPointer(920,0)); + setScriptCallOnConfigChange(2175, 1660, 1661, 1662, 1663, 1664, 5, "Y", new WidgetPointer(924,0)); + script_2174(); + script_2186(); + return; +} diff --git a/dumps/scripts/167.cs2 b/dumps/scripts/167.cs2 new file mode 100644 index 0000000..d8eb911 --- /dev/null +++ b/dumps/scripts/167.cs2 @@ -0,0 +1,4 @@ +void script_167(int arg0,int arg1) { + setWidgetRGB(new Color(arg1), new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1670.cs2 b/dumps/scripts/1670.cs2 new file mode 100644 index 0000000..527b2dc --- /dev/null +++ b/dumps/scripts/1670.cs2 @@ -0,0 +1,32 @@ +void script_1670(int arg0,int arg1,int arg2,int arg3,string arg4,string arg5,string arg6,string arg7,string arg8,string arg9) { + if (setWidgetRegister(new WidgetPointer(arg2), arg3)) { + if (arg0 != -1) { + if (getItemHashmapData(arg1, 599) > 0) { + setItemOnWidgetMethod1212(arg0, getItemHashmapData(arg1, 599)); + } else { + setItemOnWidgetMethod1212(arg0, 1); + } + cs2method1305(getItemName(arg1)); + setWidgetContextMenuOption(1, arg4); + setWidgetContextMenuOption(2, arg5); + setWidgetContextMenuOption(3, arg6); + setWidgetContextMenuOption(4, arg7); + setWidgetContextMenuOption(5, arg8); + setWidgetContextMenuOption(6, "Examine" + ""); + setWidgetContextMenuOption(7, arg9); + setWidgetShadowColor(new Color(51, 51, 51)); + setWidgetBorderThickness(1); + } else { + setItemOnWidgetMethod1200(-1, 0); + cs2method1305(""); + setWidgetContextMenuOption(1, ""); + setWidgetContextMenuOption(2, ""); + setWidgetContextMenuOption(3, ""); + setWidgetContextMenuOption(4, ""); + setWidgetContextMenuOption(5, ""); + setWidgetContextMenuOption(6, ""); + setWidgetContextMenuOption(7, ""); + } + } + return; +} diff --git a/dumps/scripts/1671.cs2 b/dumps/scripts/1671.cs2 new file mode 100644 index 0000000..ca7e7e1 --- /dev/null +++ b/dumps/scripts/1671.cs2 @@ -0,0 +1,18 @@ +void script_1671(int arg0,int arg1) { + string svar0; + svar0 = "Empty display"; + switch (arg1) { + case 0: + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(81,40), svar0, 25, 180, "IIsii", new WidgetPointer(arg0)); + break; + case 1: + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(83,40), svar0, 25, 180, "IIsii", new WidgetPointer(arg0)); + break; + case 2: + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(80,52), svar0, 25, 180, "IIsii", new WidgetPointer(arg0)); + break; + case 3: + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(82,38), svar0, 25, 180, "IIsii", new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/1672.cs2 b/dumps/scripts/1672.cs2 new file mode 100644 index 0000000..ac7aa66 --- /dev/null +++ b/dumps/scripts/1672.cs2 @@ -0,0 +1,5 @@ +void script_1672() { + script_1675(bitconfig_6768); + script_1673(); + return; +} diff --git a/dumps/scripts/1673.cs2 b/dumps/scripts/1673.cs2 new file mode 100644 index 0000000..23799e6 --- /dev/null +++ b/dumps/scripts/1673.cs2 @@ -0,0 +1,42 @@ +void script_1673() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int stack_dump0; + cs2func_script_1674_struct(2,0,0) structdump_1; + deleteAllExtraChilds(new WidgetPointer(84,20)); + deleteAllExtraChilds(new WidgetPointer(84,22)); + deleteAllExtraChilds(new WidgetPointer(84,21)); + ivar0 = 0; + ivar1 = 0; + ivar2 = 264; + ivar3 = 0; + setWidgetPosition(getWidgetActualX(new WidgetPointer(84,20)), ivar0, 0, 0, new WidgetPointer(84,20)); + stack_dump0 = bitconfig_6768; + structdump_1 = script_1674(stack_dump0); + ivar3 = structdump_1.intpart_1; + ivar1 = structdump_1.intpart_0; + setWidgetScrollMax(0, ivar1, new WidgetPointer(84,22)); + cs2method2100(0, ivar3, new WidgetPointer(84,22)); + ivar1 = add(ivar1, 4); + if (ivar1 > ivar2) { + setWidgetSize(16, 4, 0, 1, new WidgetPointer(84,21)); + setWidgetSize(20, 4, 1, 1, new WidgetPointer(84,22)); + if (setWidgetRegister(new WidgetPointer(84,21), 0)) { + script_31(5505045, 5505046, 792, 789, 790, 791, 773, 788); + } + script_72(5505045, 5505046, cs2method2601(new WidgetPointer(84,22))); + } else { + setWidgetSize(0, 4, 0, 1, new WidgetPointer(84,21)); + setWidgetSize(4, 4, 1, 1, new WidgetPointer(84,22)); + } + if (ivar1 < 111) { + setWidgetSize(350, add(111, 68), 0, 0, new WidgetPointer(84,0)); + } else if (ivar1 < ivar2) { + setWidgetSize(350, add(ivar1, 70), 0, 0, new WidgetPointer(84,0)); + } else { + setWidgetSize(350, add(ivar2, 70), 0, 0, new WidgetPointer(84,0)); + } + return; +} diff --git a/dumps/scripts/1674.cs2 b/dumps/scripts/1674.cs2 new file mode 100644 index 0000000..067a0b6 --- /dev/null +++ b/dumps/scripts/1674.cs2 @@ -0,0 +1,80 @@ +cs2func_script_1674_struct(2,0,0) script_1674(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + string svar0; + ivar1 = 836; + ivar2 = 1; + ivar3 = 2; + svar0 = ""; + ivar4 = 0; + ivar5 = 0; + svar0 = cs2method_3408(105, 115, ivar1, 0); + createExtraChild(new WidgetPointer(84,22), 5, 0); + setWidgetSize(17, 17, 0, 0); + setWidgetPosition(2, ivar3, 0, 0); + if (((boolean)arg0)) { + setWidgetSprite(699); + ivar4 = ivar3; + } else { + setWidgetSprite(697); + } + createExtraChild(new WidgetPointer(84,22), 4, 1); + setWidgetFont(494); + setWidgetRGB(new Color(255, 152, 31)); + setWidgetTextAlignment(0, 1, 0); + setWidgetSize(23, 16, 1, 0); + setWidgetPosition(0, add(ivar3, 2), 2, 0); + setWidgetText(svar0); + createExtraChild(new WidgetPointer(84,22), 3, 2); + setWidgetSize(0, 17, 1, 0); + setWidgetPosition(0, ivar3, 1, 0); + cs2method2103(255); + setWidgetFilled(1); + if (arg0 != 0) { + setWidgetContextMenuOption(1, svar0); + setScriptCallOnMouseEntered(1356, new WidgetPointer(-32768,3), getWidgetCustomChildArrayIndex(), 16777215, "Iii"); + setScriptCallOnMouseExit(1356, new WidgetPointer(-32768,3), getWidgetCustomChildArrayIndex(), 16750623, "Iii"); + setScriptCallOnClickContextMenu(1676, -2147483644, 0, arg0, "iii"); + } + ivar3 = add(ivar3, getWidgetActualHeight()); + ivar5 = 1; + while (ivar2 < getCommonDefinitionSize(ivar1)) { + if (isBitFlagged(standart_config_617, subtract(ivar2, 1))) { + svar0 = cs2method_3408(105, 115, ivar1, ivar2); + createExtraChild(new WidgetPointer(84,22), 5, multiply(ivar5, 3)); + setWidgetSize(17, 17, 0, 0); + setWidgetPosition(2, ivar3, 0, 0); + if (ivar2 == arg0) { + setWidgetSprite(699); + ivar4 = ivar3; + } else { + setWidgetSprite(697); + } + createExtraChild(new WidgetPointer(84,22), 4, add(multiply(ivar5, 3), 1)); + setWidgetFont(494); + setWidgetRGB(new Color(255, 152, 31)); + setWidgetTextAlignment(0, 1, 0); + setWidgetSize(23, 16, 1, 0); + setWidgetPosition(0, add(ivar3, 2), 2, 0); + setWidgetText(svar0); + createExtraChild(new WidgetPointer(84,22), 3, add(multiply(ivar5, 3), 2)); + setWidgetSize(0, 17, 1, 0); + setWidgetPosition(0, ivar3, 1, 0); + cs2method2103(255); + setWidgetFilled(1); + if (ivar2 != arg0) { + setWidgetContextMenuOption(1, svar0); + setScriptCallOnMouseEntered(1356, new WidgetPointer(-32768,3), getWidgetCustomChildArrayIndex(), 16777215, "Iii"); + setScriptCallOnMouseExit(1356, new WidgetPointer(-32768,3), getWidgetCustomChildArrayIndex(), 16750623, "Iii"); + setScriptCallOnClickContextMenu(1676, -2147483644, ivar2, arg0, "iii"); + } + ivar3 = add(ivar3, getWidgetActualHeight()); + ivar5 = add(ivar5, 1); + } + ivar2 = add(ivar2, 1); + } + return newstruct cs2func_script_1674_struct(ivar3, max(subtract(ivar4, 8), 0)); +} diff --git a/dumps/scripts/1675.cs2 b/dumps/scripts/1675.cs2 new file mode 100644 index 0000000..a31782e --- /dev/null +++ b/dumps/scripts/1675.cs2 @@ -0,0 +1,8 @@ +void script_1675(int arg0) { + if (((boolean)arg0)) { + setWidgetModel(cs2method_3408(105, 109, 839, bitconfig_6764), new WidgetPointer(84,19)); + } else { + setWidgetModel(cs2method_3408(105, 109, 838, arg0), new WidgetPointer(84,19)); + } + return; +} diff --git a/dumps/scripts/1676.cs2 b/dumps/scripts/1676.cs2 new file mode 100644 index 0000000..4cb98e1 --- /dev/null +++ b/dumps/scripts/1676.cs2 @@ -0,0 +1,19 @@ +void script_1676(int arg0,int arg1,int arg2) { + int stack_dump0; + cs2func_script_1674_struct(2,0,0) structdump_1; + if (arg0 != 1) { + return; + } + if (arg1 == arg2) { + return; + } + script_1675(arg1); + bitconfig_6768 = arg1; + deleteAllExtraChilds(new WidgetPointer(84,22)); + stack_dump0 = arg1; + structdump_1 = script_1674(stack_dump0); + stack_dump0 = structdump_1.intpart_0; + structdump_1.intpart_1; + stack_dump0; + return; +} diff --git a/dumps/scripts/1677.cs2 b/dumps/scripts/1677.cs2 new file mode 100644 index 0000000..12aad19 --- /dev/null +++ b/dumps/scripts/1677.cs2 @@ -0,0 +1,15 @@ +void script_1677() { + setScriptCallOnGameloop(1688, "", new WidgetPointer(85,0)); + globalint_1046 = 0; + globalint_1045 = 0; + globalint_1051 = 0; + globalint_1048 = 0; + globalint_1049 = 255; + globalint_1044 = 0; + cs2method5405(0, 0); + cs2method5405(1, 0); + script_1678(); + cameraMethod5502(0, 0, 200, 200, 1, 0); + setScriptCallOnMinimapRelatedSetting3(1679, "", new WidgetPointer(85,0)); + return; +} diff --git a/dumps/scripts/1678.cs2 b/dumps/scripts/1678.cs2 new file mode 100644 index 0000000..dc381ba --- /dev/null +++ b/dumps/scripts/1678.cs2 @@ -0,0 +1,26 @@ +void script_1678() { + int ivar0; + int ivar1; + int ivar2; + ivar0 = 0; + ivar1 = 0; + ivar2 = -1; + if (((boolean)cs2method5407(0))) { + ivar0 = subtract(extractX(getMyPositionHash()), mod(extractX(getMyPositionHash()), 64)); + ivar1 = subtract(extractY(getMyPositionHash()), mod(extractY(getMyPositionHash()), 64)); + ivar2 = addToCoordinate(0, ivar0, 0, ivar1); + cs2method5405(0, 5); + cs2method5405(1, 5); + cs2method5406(0, 0, addToCoordinate(ivar2, 51, 0, 39), 400, addToCoordinate(ivar2, 51, 0, 39), 400, 0); + cs2method5406(1, 0, addToCoordinate(ivar2, 50, 0, 25), 225, addToCoordinate(ivar2, 50, 0, 25), 225, 0); + cs2method5406(0, 1, addToCoordinate(ivar2, 51, 0, 29), 325, addToCoordinate(ivar2, 51, 0, 29), 225, 0); + cs2method5406(1, 1, addToCoordinate(ivar2, 50, 0, 19), 175, addToCoordinate(ivar2, 50, 0, 19), 175, 0); + cs2method5406(0, 2, addToCoordinate(ivar2, 57, 0, 23), 1200, addToCoordinate(ivar2, 57, 0, 23), 1200, 0); + cs2method5406(1, 2, addToCoordinate(ivar2, 47, 0, 18), 25, addToCoordinate(ivar2, 47, 0, 18), 25, 0); + cs2method5406(0, 3, addToCoordinate(ivar2, 46, 0, 5), 600, addToCoordinate(ivar2, 46, 0, 5), 600, 0); + cs2method5406(1, 3, addToCoordinate(ivar2, 46, 0, 16), 250, addToCoordinate(ivar2, 46, 0, 16), 250, 0); + cs2method5406(0, 4, addToCoordinate(ivar2, 41, 0, 27), 1125, addToCoordinate(ivar2, 41, 0, 27), 1125, 0); + cs2method5406(1, 4, addToCoordinate(ivar2, 44, 0, 19), 275, addToCoordinate(ivar2, 44, 0, 19), 275, 0); + } + return; +} diff --git a/dumps/scripts/1679.cs2 b/dumps/scripts/1679.cs2 new file mode 100644 index 0000000..61d337e --- /dev/null +++ b/dumps/scripts/1679.cs2 @@ -0,0 +1,11 @@ +void script_1679() { + script_1678(); + switch (globalint_1044) { + case 0: + script_1687(); + break; + default: + setScriptCallOnMinimapRelatedSetting3(-1, "", new WidgetPointer(85,0)); + } + return; +} diff --git a/dumps/scripts/168.cs2 b/dumps/scripts/168.cs2 new file mode 100644 index 0000000..326d126 --- /dev/null +++ b/dumps/scripts/168.cs2 @@ -0,0 +1,63 @@ +void script_168() { + setWidgetSprite(-1, new WidgetPointer(559,86)); + setWidgetSprite(-1, new WidgetPointer(559,72)); + setWidgetSprite(-1, new WidgetPointer(559,73)); + setWidgetSprite(-1, new WidgetPointer(559,74)); + setWidgetSprite(-1, new WidgetPointer(559,75)); + setWidgetSprite(-1, new WidgetPointer(559,76)); + setWidgetSprite(-1, new WidgetPointer(559,77)); + setWidgetSprite(-1, new WidgetPointer(559,78)); + setWidgetSprite(-1, new WidgetPointer(559,79)); + setWidgetSprite(-1, new WidgetPointer(559,80)); + setWidgetSprite(-1, new WidgetPointer(559,81)); + setWidgetSprite(-1, new WidgetPointer(559,82)); + setWidgetSprite(-1, new WidgetPointer(559,83)); + setWidgetSprite(-1, new WidgetPointer(559,84)); + setWidgetSprite(-1, new WidgetPointer(559,85)); + if (((boolean)bitconfig_3801)) { + setWidgetSprite(442, new WidgetPointer(559,86)); + } + if (((boolean)bitconfig_3802)) { + setWidgetSprite(442, new WidgetPointer(559,72)); + } + if (((boolean)bitconfig_3803)) { + setWidgetSprite(442, new WidgetPointer(559,73)); + } + if (((boolean)bitconfig_3804)) { + setWidgetSprite(442, new WidgetPointer(559,74)); + } + if (((boolean)bitconfig_3805)) { + setWidgetSprite(442, new WidgetPointer(559,75)); + } + if (((boolean)bitconfig_3806)) { + setWidgetSprite(442, new WidgetPointer(559,76)); + } + if (((boolean)bitconfig_3807)) { + setWidgetSprite(442, new WidgetPointer(559,77)); + } + if (((boolean)bitconfig_3808)) { + setWidgetSprite(442, new WidgetPointer(559,78)); + } + if (((boolean)bitconfig_3809)) { + setWidgetSprite(442, new WidgetPointer(559,79)); + } + if (((boolean)bitconfig_3810)) { + setWidgetSprite(442, new WidgetPointer(559,80)); + } + if (((boolean)bitconfig_3811)) { + setWidgetSprite(442, new WidgetPointer(559,81)); + } + if (((boolean)bitconfig_3812)) { + setWidgetSprite(442, new WidgetPointer(559,82)); + } + if (((boolean)bitconfig_3813)) { + setWidgetSprite(442, new WidgetPointer(559,83)); + } + if (((boolean)bitconfig_3814)) { + setWidgetSprite(442, new WidgetPointer(559,84)); + } + if (((boolean)bitconfig_3815)) { + setWidgetSprite(442, new WidgetPointer(559,85)); + } + return; +} diff --git a/dumps/scripts/1680.cs2 b/dumps/scripts/1680.cs2 new file mode 100644 index 0000000..32d6333 --- /dev/null +++ b/dumps/scripts/1680.cs2 @@ -0,0 +1,5 @@ +void script_1680() { + script_1678(); + script_1687(); + return; +} diff --git a/dumps/scripts/1681.cs2 b/dumps/scripts/1681.cs2 new file mode 100644 index 0000000..1d25058 --- /dev/null +++ b/dumps/scripts/1681.cs2 @@ -0,0 +1,4 @@ +void script_1681() { + script_1680(); + return; +} diff --git a/dumps/scripts/1682.cs2 b/dumps/scripts/1682.cs2 new file mode 100644 index 0000000..bce9497 --- /dev/null +++ b/dumps/scripts/1682.cs2 @@ -0,0 +1,5 @@ +void script_1682() { + globalint_1044 = 0; + script_1680(); + return; +} diff --git a/dumps/scripts/1683.cs2 b/dumps/scripts/1683.cs2 new file mode 100644 index 0000000..b35de8b --- /dev/null +++ b/dumps/scripts/1683.cs2 @@ -0,0 +1,5 @@ +void script_1683() { + globalint_1044 = 1; + script_1680(); + return; +} diff --git a/dumps/scripts/1684.cs2 b/dumps/scripts/1684.cs2 new file mode 100644 index 0000000..13b011c --- /dev/null +++ b/dumps/scripts/1684.cs2 @@ -0,0 +1,5 @@ +void script_1684() { + globalint_1044 = 2; + script_1680(); + return; +} diff --git a/dumps/scripts/1685.cs2 b/dumps/scripts/1685.cs2 new file mode 100644 index 0000000..d7dd6af --- /dev/null +++ b/dumps/scripts/1685.cs2 @@ -0,0 +1,5 @@ +void script_1685() { + globalint_1044 = 3; + script_1680(); + return; +} diff --git a/dumps/scripts/1686.cs2 b/dumps/scripts/1686.cs2 new file mode 100644 index 0000000..762722b --- /dev/null +++ b/dumps/scripts/1686.cs2 @@ -0,0 +1,5 @@ +void script_1686() { + globalint_1044 = 4; + script_1680(); + return; +} diff --git a/dumps/scripts/1687.cs2 b/dumps/scripts/1687.cs2 new file mode 100644 index 0000000..0f3e840 --- /dev/null +++ b/dumps/scripts/1687.cs2 @@ -0,0 +1,8 @@ +void script_1687() { + if (globalint_1044 < subtract(cs2method5407(0), 1)) { + globalint_1044 = add(globalint_1044, 1); + cameraMethod5502(0, globalint_1044, 200, 200, 1, globalint_1044); + setScriptCallOnMinimapRelatedSetting3(1679, "", new WidgetPointer(85,0)); + } + return; +} diff --git a/dumps/scripts/1688.cs2 b/dumps/scripts/1688.cs2 new file mode 100644 index 0000000..889e46f --- /dev/null +++ b/dumps/scripts/1688.cs2 @@ -0,0 +1,4 @@ +void script_1688() { + script_1689(); + return; +} diff --git a/dumps/scripts/1689.cs2 b/dumps/scripts/1689.cs2 new file mode 100644 index 0000000..e96d713 --- /dev/null +++ b/dumps/scripts/1689.cs2 @@ -0,0 +1,33 @@ +void script_1689() { + globalint_1047 = add(globalint_1047, 1); + if (globalint_1047 >= subtract(2, 1)) { + globalint_1047 = 0; + if (((boolean)globalint_1045)) { + globalint_1046 = min(add(globalint_1046, 2), 255); + } else { + if (((boolean)globalint_1045)) { + globalint_1046 = max(subtract(globalint_1046, 2), 0); + } + } + cs2method2103(globalint_1046, new WidgetPointer(85,2)); + } + globalint_1050 = add(globalint_1050, 1); + if (globalint_1050 >= subtract(6, 1)) { + globalint_1050 = 0; + if (((boolean)globalint_1048)) { + globalint_1049 = min(add(globalint_1049, 1), 255); + if (globalint_1049 >= 255) { + globalint_1048 = 1; + } + } else { + if (((boolean)globalint_1048) && ((boolean)globalint_1051)) { + globalint_1049 = max(subtract(globalint_1049, 3), 192); + if (globalint_1049 <= 192) { + globalint_1048 = 0; + } + } + } + cs2method2103(globalint_1049, new WidgetPointer(85,1)); + } + return; +} diff --git a/dumps/scripts/169.cs2 b/dumps/scripts/169.cs2 new file mode 100644 index 0000000..3ed40ed --- /dev/null +++ b/dumps/scripts/169.cs2 @@ -0,0 +1,8 @@ +void script_169(int arg0,int arg1) { + if (bitconfig_3905 == arg0) { + setWidgetRGB(new Color(221, 80, 50), new WidgetPointer(arg1)); + } else { + setWidgetRGB(new Color(100, 80, 30), new WidgetPointer(arg1)); + } + return; +} diff --git a/dumps/scripts/1690.cs2 b/dumps/scripts/1690.cs2 new file mode 100644 index 0000000..f41329e --- /dev/null +++ b/dumps/scripts/1690.cs2 @@ -0,0 +1,4 @@ +void script_1690() { + cameraUnlock(); + return; +} diff --git a/dumps/scripts/1691.cs2 b/dumps/scripts/1691.cs2 new file mode 100644 index 0000000..d282d75 --- /dev/null +++ b/dumps/scripts/1691.cs2 @@ -0,0 +1,59 @@ +void script_1691(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int stack_dump0; + int stack_dump1; + int stack_dump2; + cs2func_script_1692_struct(2,0,0) structdump_3; + deleteAllExtraChilds(new WidgetPointer(arg0)); + ivar2 = 0; + globalarray_0 = new int[96]; + ivar3 = 0; + ivar4 = 0; + ivar5 = -1; + while (((boolean)ivar4) && (ivar2 < 96)) { + ivar5 = cs2method_3408(105, 74, 845, ivar2); + if (ivar5 == 345) { + ivar4 = 1; + } else if (((boolean)script_1694(ivar2)) && (ivar5 != -1)) { + globalarray_0[ivar3] = ivar2; + ivar3 = add(ivar3, 1); + } else { + setWidgetHidden(1); + } + createExtraChild(new WidgetPointer(arg0), 3, ivar2); + ivar2 = add(ivar2, 1); + } + script_1693(0, 0, subtract(ivar3, 1)); + ivar6 = 0; + ivar7 = -1; + ivar2 = 0; + while (ivar2 < ivar3) { + if (setWidgetRegister(new WidgetPointer(arg0), globalarray_0[ivar2])) { + stack_dump0 = arg0; + stack_dump1 = ivar6; + stack_dump2 = globalarray_0[ivar2]; + structdump_3 = script_1692(stack_dump0, stack_dump1, stack_dump2); + ivar7 = structdump_3.intpart_1; + ivar6 = structdump_3.intpart_0; + } + ivar2 = add(ivar2, 1); + } + if (ivar6 <= getWidgetActualHeight(new WidgetPointer(arg0))) { + setWidgetScrollMax(0, 0, new WidgetPointer(arg0)); + deleteAllExtraChilds(new WidgetPointer(arg1)); + setWidgetIsHidden(true, new WidgetPointer(arg1)); + } else { + if ((ivar7 != -1) && setWidgetRegister(new WidgetPointer(arg0), ivar7)) { + deleteExtraChild(); + } + setWidgetScrollMax(0, ivar6, new WidgetPointer(arg0)); + setWidgetIsHidden(false, new WidgetPointer(arg1)); + script_31(arg1, arg0, 798, 795, 796, 797, 793, 794); + } + return; +} diff --git a/dumps/scripts/1692.cs2 b/dumps/scripts/1692.cs2 new file mode 100644 index 0000000..2130aaf --- /dev/null +++ b/dumps/scripts/1692.cs2 @@ -0,0 +1,71 @@ +cs2func_script_1692_struct(2,0,0) script_1692(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + int ivar6; + string svar0; + string svar1; + ivar3 = cs2method_3408(105, 74, 845, arg2); + svar0 = getOtherCommonData(ivar3, 925); + ivar4 = add(multiply(getLineCount(subtract(getWidgetActualWidth(new WidgetPointer(arg0)), 22), 495, svar0), 12), 5); + ivar5 = add(add(32, ivar4), 10); + setWidgetSize(0, ivar5, 1, 0); + setWidgetPosition(0, arg1, 1, 0); + setWidgetFilled(1); + setWidgetRGB(new Color(0, 0, 0)); + cs2method2103(255); + setScriptCallOnMouseEntered(2140, new WidgetPointer(-32768,3), -2147483643, 200, "Iii"); + setScriptCallOnMouseExit(2140, new WidgetPointer(-32768,3), -2147483643, 255, "Iii"); + setWidgetContextMenuOption(1, "Take"); + setWidgetContextMenuOption(10, "Examine"); + cs2method1305("" + getItemName(getOtherCommonData(ivar3, 813))); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(2, add(arg1, 4), 0, 0); + setItemOnWidgetMethod1205(getOtherCommonData(ivar3, 813), 1); + setWidgetBorderThickness(1); + setWidgetShadowColor(new Color(48, 32, 32)); + createExtraChild(new WidgetPointer(arg0), 4, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(2, add(arg1, 4), 2, 0); + setWidgetRGB(new Color(255, 240, 140)); + setWidgetTextAlignment(0, 1, 0); + setWidgetUnknownBoolean(true); + createExtraChild(new WidgetPointer(arg0), 4, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(add(36, 4), 12, 1, 0); + setWidgetPosition(2, add(add(arg1, 4), subtract(32, getWidgetActualHeight())), 2, 0); + setWidgetFont(494); + setWidgetRGB(new Color(255, 152, 31)); + setWidgetTextAlignment(0, 1, 0); + setWidgetUnknownBoolean(true); + ivar6 = getOtherCommonData(ivar3, 923); + if (ivar6 != -1) { + setWidgetSize(add(36, 4), subtract(32, getWidgetActualHeight()), 1, 0); + setWidgetText(getOtherCommonData(ivar6, 845)); + } else { + setWidgetSize(add(36, 4), 32, 1, 0); + setWidgetHidden(1); + } + svar1 = getOtherCommonData(ivar3, 924); + if (getLineCount(getWidgetActualWidth(), 496, svar1) <= 1) { + setWidgetFont(496); + } else if (getLineCount(getWidgetActualWidth(), 495, svar1) <= 1) { + setWidgetFont(495); + } else { + setWidgetFont(494); + } + setWidgetText(svar1); + createExtraChild(new WidgetPointer(arg0), 4, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(22, ivar4, 1, 0); + setWidgetPosition(2, add(add(arg1, 32), 6), 0, 0); + setWidgetFont(495); + setWidgetRGB(new Color(255, 240, 140)); + setWidgetTextAlignment(0, 1, 0); + setWidgetUnknownBoolean(true); + setWidgetText(svar0); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(0, 32, 1, 0); + setWidgetPosition(0, subtract(add(arg1, ivar5), 16), 0, 0); + setWidgetSprite(995); + cs2method1107(1); + return newstruct cs2func_script_1692_struct(add(arg1, ivar5), getWidgetCustomChildArrayIndex()); +} diff --git a/dumps/scripts/1693.cs2 b/dumps/scripts/1693.cs2 new file mode 100644 index 0000000..bbf191e --- /dev/null +++ b/dumps/scripts/1693.cs2 @@ -0,0 +1,60 @@ +void script_1693(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + string svar0; + string svar1; + ivar3 = divide(add(arg1, arg2), 2); + ivar4 = globalarray_0[ivar3]; + globalarray_0[ivar3] = globalarray_0[arg2]; + globalarray_0[arg2] = ivar4; + ivar5 = arg1; + ivar6 = arg1; + ivar7 = 0; + svar0 = ""; + svar1 = ""; + ivar8 = -1; + while (ivar6 < arg2) { + ivar8 = cs2method_3408(105, 74, 845, globalarray_0[ivar6]); + if (ivar8 != -1) { + ivar8 = getOtherCommonData(ivar8, 923); + if (ivar8 != -1) { + svar0 = getOtherCommonData(ivar8, 846); + } else { + svar0 = ""; + } + } else { + svar0 = ""; + } + ivar8 = cs2method_3408(105, 74, 845, ivar4); + if (ivar8 != -1) { + ivar8 = getOtherCommonData(ivar8, 923); + if (ivar8 != -1) { + svar1 = getOtherCommonData(ivar8, 846); + } else { + svar1 = ""; + } + } else { + svar1 = ""; + } + if (stringMethod4107(svar0, svar1) < bitAnd(ivar6, 1)) { + ivar7 = globalarray_0[ivar6]; + globalarray_0[ivar6] = globalarray_0[ivar5]; + globalarray_0[ivar5] = ivar7; + ivar5 = add(ivar5, 1); + } + ivar6 = add(ivar6, 1); + } + globalarray_0[arg2] = globalarray_0[ivar5]; + globalarray_0[ivar5] = ivar4; + if (arg1 < subtract(ivar5, 1)) { + script_1693(0, arg1, subtract(ivar5, 1)); + } + if (add(ivar5, 1) < arg2) { + script_1693(0, add(ivar5, 1), arg2); + } + return; +} diff --git a/dumps/scripts/1694.cs2 b/dumps/scripts/1694.cs2 new file mode 100644 index 0000000..19682e5 --- /dev/null +++ b/dumps/scripts/1694.cs2 @@ -0,0 +1,12 @@ +int script_1694(int arg0) { + if (arg0 < 32) { + return isBitFlagged(globalint_1040, arg0); + } + if (arg0 < 64) { + return isBitFlagged(globalint_1041, mod(arg0, 32)); + } + if (arg0 < 96) { + return isBitFlagged(globalint_1042, mod(arg0, 32)); + } + return 0; +} diff --git a/dumps/scripts/1695.cs2 b/dumps/scripts/1695.cs2 new file mode 100644 index 0000000..78f9236 --- /dev/null +++ b/dumps/scripts/1695.cs2 @@ -0,0 +1,45 @@ +int script_1695(int arg0) { + switch (arg0) { + case 0: + if (bitconfig_6852 > 0) { + return 4; + } + if (bitconfig_6847 > 0) { + return 1; + } + return 0; + case 2: + if (bitconfig_6853 > 0) { + return 4; + } + if (bitconfig_6848 > 0) { + return 1; + } + return 0; + case 1: + if (bitconfig_6854 > 0) { + return 4; + } + if (bitconfig_6849 > 0) { + return 1; + } + return 0; + case 4: + if (bitconfig_6855 > 0) { + return 4; + } + if (bitconfig_6850 > 0) { + return 1; + } + return 0; + case 6: + if (bitconfig_6856 > 0) { + return 4; + } + if (bitconfig_6851 > 0) { + return 1; + } + return 0; + } + return 0; +} diff --git a/dumps/scripts/1696.cs2 b/dumps/scripts/1696.cs2 new file mode 100644 index 0000000..8d24cb8 --- /dev/null +++ b/dumps/scripts/1696.cs2 @@ -0,0 +1,45 @@ +int script_1696(int arg0) { + switch (arg0) { + case 0: + if (bitconfig_6830 > 0) { + return 4; + } + if (bitconfig_6821 > 0) { + return 1; + } + return 0; + case 2: + if (bitconfig_6834 > 0) { + return 4; + } + if (bitconfig_6821 > 0) { + return 1; + } + return 0; + case 1: + if (bitconfig_6833 > 0) { + return 4; + } + if (((bitconfig_6821 > 0) || (bitconfig_6822 > 0)) || (bitconfig_6823 > 0)) { + return 1; + } + return 0; + case 4: + if (bitconfig_6831 > 0) { + return 4; + } + if (bitconfig_6822 > 0) { + return 1; + } + return 0; + case 6: + if (bitconfig_6832 > 0) { + return 4; + } + if (bitconfig_6823 > 0) { + return 1; + } + return 0; + } + return 0; +} diff --git a/dumps/scripts/1697.cs2 b/dumps/scripts/1697.cs2 new file mode 100644 index 0000000..39155ba --- /dev/null +++ b/dumps/scripts/1697.cs2 @@ -0,0 +1,15 @@ +int script_1697(int arg0) { + switch (arg0) { + case 0: + return subtract(bitconfig_6857, 30); + case 2: + return subtract(bitconfig_6858, 30); + case 1: + return subtract(bitconfig_6859, 30); + case 4: + return subtract(bitconfig_6860, 30); + case 6: + return subtract(bitconfig_6861, 30); + } + return 0; +} diff --git a/dumps/scripts/1698.cs2 b/dumps/scripts/1698.cs2 new file mode 100644 index 0000000..0dd48ad --- /dev/null +++ b/dumps/scripts/1698.cs2 @@ -0,0 +1,27 @@ +void script_1698() { + string svar0; + setScriptCallOnConfigChange(1699, 1583, 1584, 1582, 1395, 4, "Y", new WidgetPointer(271,9)); + setWidgetScrollMax(getWidgetActualWidth(new WidgetPointer(271,8)), getWidgetActualHeight(new WidgetPointer(271,8)), new WidgetPointer(271,5)); + setScriptCallOnClickContextMenu(1701, "", new WidgetPointer(271,12)); + svar0 = "This is the effect that prayers and curses have during combat. It includes curses that have used against you. The adjustment has no effect outside of combat. The percentage shown is relative to your skill level and may vary depending on the enemy you are fighting, and the prayers or curses used. Partial percentages are not shown."; + if (((boolean)globalint_1052)) { + setWidgetSize(16384, 63, 2, 0, new WidgetPointer(271,9)); + setWidgetSize(16384, add(63, getWidgetActualHeight(new WidgetPointer(271,0))), 2, 1, new WidgetPointer(271,5)); + setWidgetSize(16, add(add(63, getWidgetActualHeight(new WidgetPointer(271,0))), 2), 0, 1, new WidgetPointer(271,6)); + setWidgetIsHidden(false, new WidgetPointer(271,24)); + script_1700(); + script_1704(); + setScriptCallOnMouseOver(38, new WidgetPointer(271,13), new WidgetPointer(271,49), svar0, 25, 190, "IIsii", new WidgetPointer(271,13)); + setScriptCallOnMouseExit(40, new WidgetPointer(271,49), "I", new WidgetPointer(271,13)); + } else { + setWidgetSize(16384, 19, 2, 0, new WidgetPointer(271,9)); + setWidgetSize(16384, add(19, getWidgetActualHeight(new WidgetPointer(271,0))), 2, 1, new WidgetPointer(271,5)); + setWidgetSize(16, add(add(19, getWidgetActualHeight(new WidgetPointer(271,0))), 2), 0, 1, new WidgetPointer(271,6)); + setWidgetIsHidden(true, new WidgetPointer(271,24)); + script_1700(); + script_1704(); + setScriptCallOnMouseOver(-1, "", new WidgetPointer(271,13)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(271,13)); + } + return; +} diff --git a/dumps/scripts/1699.cs2 b/dumps/scripts/1699.cs2 new file mode 100644 index 0000000..779d657 --- /dev/null +++ b/dumps/scripts/1699.cs2 @@ -0,0 +1,5 @@ +void script_1699() { + script_1706(); + script_1704(); + return; +} diff --git a/dumps/scripts/17.cs2 b/dumps/scripts/17.cs2 new file mode 100644 index 0000000..9bb3c0b --- /dev/null +++ b/dumps/scripts/17.cs2 @@ -0,0 +1,7 @@ +void script_17(int arg0) { + setWidgetBorderThickness(2, new WidgetPointer(arg0)); + if (bitAnd(cs2method2800(new WidgetPointer(arg0)), 32) != 0) { + script_71(4); + } + return; +} diff --git a/dumps/scripts/170.cs2 b/dumps/scripts/170.cs2 new file mode 100644 index 0000000..8e14f6e --- /dev/null +++ b/dumps/scripts/170.cs2 @@ -0,0 +1,14 @@ +void script_170() { + if (((boolean)bitconfig_3905)) { + setWidgetText(new WidgetPointer(588,7), intToStr(bitconfig_3901) + "/5"); + } else if (bitconfig_3905 == 2) { + setWidgetText(new WidgetPointer(588,7), intToStr(bitconfig_3902) + "/5"); + } else if (bitconfig_3905 == 3) { + setWidgetText(new WidgetPointer(588,7), intToStr(bitconfig_3903) + "/5"); + } else { + if (bitconfig_3905 == 4) { + setWidgetText(new WidgetPointer(588,7), intToStr(bitconfig_3904) + "/5"); + } + } + return; +} diff --git a/dumps/scripts/1700.cs2 b/dumps/scripts/1700.cs2 new file mode 100644 index 0000000..7642569 --- /dev/null +++ b/dumps/scripts/1700.cs2 @@ -0,0 +1,10 @@ +void script_1700() { + if (((boolean)globalint_1052)) { + setWidgetText(new WidgetPointer(271,12), "Hide stat adjustments."); + setWidgetContextMenuOption(1, new WidgetPointer(271,12), "Hide stat adjustments"); + } else { + setWidgetText(new WidgetPointer(271,12), "Show stat adjustments."); + setWidgetContextMenuOption(1, new WidgetPointer(271,12), "Show stat adjustments"); + } + return; +} diff --git a/dumps/scripts/1701.cs2 b/dumps/scripts/1701.cs2 new file mode 100644 index 0000000..d44ee7d --- /dev/null +++ b/dumps/scripts/1701.cs2 @@ -0,0 +1,12 @@ +void script_1701() { + if (((boolean)globalint_1052)) { + playSoundEffect(8123, 1, 0); + globalint_1052 = 0; + } else { + playSoundEffect(8096, 1, 0); + globalint_1052 = 1; + } + setScriptCallOnGameloop(1702, 0, "i", new WidgetPointer(271,9)); + script_1700(); + return; +} diff --git a/dumps/scripts/1702.cs2 b/dumps/scripts/1702.cs2 new file mode 100644 index 0000000..ce7cf9d --- /dev/null +++ b/dumps/scripts/1702.cs2 @@ -0,0 +1,42 @@ +void script_1702(int arg0) { + int ivar1; + string svar0; + ivar1 = getWidgetActualHeight(new WidgetPointer(271,9)); + svar0 = "This is the effect that prayers and curses have during combat. It includes curses that have been used against you. The adjustment has no effect outside of combat. The percentage shown is relative to your skill level, and may vary depending on the enemy you are fighting, and the prayers or curses used. Partial percentages are not shown."; + if (arg0 >= 0) { + if (((boolean)globalint_1052)) { + if (ivar1 < 63) { + ivar1 = min(add(ivar1, 3), 63); + setScriptCallOnGameloop(1702, 0, "i", new WidgetPointer(271,9)); + setWidgetSize(16384, ivar1, 2, 0, new WidgetPointer(271,9)); + setWidgetSize(16384, add(ivar1, getWidgetActualHeight(new WidgetPointer(271,0))), 2, 1, new WidgetPointer(271,5)); + setWidgetSize(16, add(add(ivar1, getWidgetActualHeight(new WidgetPointer(271,0))), 2), 0, 1, new WidgetPointer(271,6)); + } + if (getWidgetActualHeight(new WidgetPointer(271,9)) >= 63) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(271,9)); + script_1704(); + setWidgetIsHidden(false, new WidgetPointer(271,24)); + setScriptCallOnMouseOver(38, new WidgetPointer(271,13), new WidgetPointer(271,49), svar0, 25, 190, "IIsii", new WidgetPointer(271,13)); + setScriptCallOnMouseExit(40, new WidgetPointer(271,49), "I", new WidgetPointer(271,13)); + } + } else { + if (ivar1 > 19) { + ivar1 = max(subtract(ivar1, 3), 19); + setScriptCallOnGameloop(1702, 0, "i", new WidgetPointer(271,9)); + setWidgetSize(16384, ivar1, 2, 0, new WidgetPointer(271,9)); + setWidgetSize(16384, add(ivar1, getWidgetActualHeight(new WidgetPointer(271,0))), 2, 1, new WidgetPointer(271,5)); + setWidgetSize(16, add(add(ivar1, getWidgetActualHeight(new WidgetPointer(271,0))), 2), 0, 1, new WidgetPointer(271,6)); + setScriptCallOnMouseOver(-1, "", new WidgetPointer(271,13)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(271,13)); + } + if (getWidgetActualHeight(new WidgetPointer(271,9)) <= 19) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(271,9)); + script_1704(); + setWidgetIsHidden(true, new WidgetPointer(271,24)); + } + } + } else { + setScriptCallOnGameloop(1702, add(arg0, 1), "i", new WidgetPointer(271,9)); + } + return; +} diff --git a/dumps/scripts/1703.cs2 b/dumps/scripts/1703.cs2 new file mode 100644 index 0000000..6a85b92 --- /dev/null +++ b/dumps/scripts/1703.cs2 @@ -0,0 +1,4 @@ +void script_1703() { + script_1704(); + return; +} diff --git a/dumps/scripts/1704.cs2 b/dumps/scripts/1704.cs2 new file mode 100644 index 0000000..b8dd2ca --- /dev/null +++ b/dumps/scripts/1704.cs2 @@ -0,0 +1,36 @@ +void script_1704() { + int ivar0; + ivar0 = 0; + if (((boolean)bitconfig_6840)) { + if (((boolean)globalint_1052)) { + if (((boolean)globalint_181)) { + deleteAllExtraChilds(new WidgetPointer(271,6)); + cs2method2100(0, 0, new WidgetPointer(271,5)); + ivar0 = 1; + } else { + if (((boolean)getExtraChildGap(new WidgetPointer(271,6)))) { + script_31(17760262, 17760261, 792, 789, 790, 791, 773, 788); + ivar0 = 1; + } + } + } else { + if (getExtraChildGap(new WidgetPointer(271,6)) != 0) { + deleteAllExtraChilds(new WidgetPointer(271,6)); + cs2method2100(0, 0, new WidgetPointer(271,5)); + ivar0 = 1; + } + } + } else { + if (getExtraChildGap(new WidgetPointer(271,6)) != 0) { + deleteAllExtraChilds(new WidgetPointer(271,6)); + cs2method2100(0, 0, new WidgetPointer(271,5)); + setWidgetSize(16384, add(19, getWidgetActualHeight(new WidgetPointer(271,0))), 2, 1, new WidgetPointer(271,5)); + ivar0 = 1; + } + } + if (((boolean)ivar0)) { + script_1237(17760264); + script_1293(17760263); + } + return; +} diff --git a/dumps/scripts/1705.cs2 b/dumps/scripts/1705.cs2 new file mode 100644 index 0000000..4b8f314 --- /dev/null +++ b/dumps/scripts/1705.cs2 @@ -0,0 +1,4 @@ +void script_1705() { + script_1706(); + return; +} diff --git a/dumps/scripts/1706.cs2 b/dumps/scripts/1706.cs2 new file mode 100644 index 0000000..7462146 --- /dev/null +++ b/dumps/scripts/1706.cs2 @@ -0,0 +1,41 @@ +void script_1706() { + int ivar0; + int ivar1; + int ivar2; + ivar0 = 0; + ivar1 = 0; + ivar2 = 10; + while ((ivar0 != -1) && (ivar2 > 0)) { + ivar1 = script_1708(ivar0); + if (setWidgetRegister(new WidgetPointer(script_1707(ivar0)))) { + if (ivar1 > 0) { + setWidgetRGB(new Color(50, 255, 50)); + setWidgetText(concat(concat(ivar1, "+"), "%")); + } else if (ivar1 < 0) { + setWidgetRGB(new Color(255, 50, 50)); + setWidgetText(concat(intToStr(ivar1), "%")); + } else { + setWidgetRGB(new Color(255, 152, 31)); + setWidgetText(concat(intToStr(ivar1), "%")); + } + } + switch (ivar0) { + case 0: + ivar0 = 2; + break; + case 2: + ivar0 = 1; + break; + case 1: + ivar0 = 4; + break; + case 4: + ivar0 = 6; + break; + case 6: + ivar0 = -1; + } + ivar2 = subtract(ivar2, 1); + } + return; +} diff --git a/dumps/scripts/1707.cs2 b/dumps/scripts/1707.cs2 new file mode 100644 index 0000000..e6690db --- /dev/null +++ b/dumps/scripts/1707.cs2 @@ -0,0 +1,15 @@ +int script_1707(int arg0) { + switch (arg0) { + case 0: + return 17760290; + case 2: + return 17760289; + case 1: + return 17760288; + case 4: + return 17760287; + case 6: + return 17760286; + } + return -1; +} diff --git a/dumps/scripts/1708.cs2 b/dumps/scripts/1708.cs2 new file mode 100644 index 0000000..93a3b08 --- /dev/null +++ b/dumps/scripts/1708.cs2 @@ -0,0 +1,3 @@ +int script_1708(int arg0) { + return add(script_1709(arg0), script_1710(arg0)); +} diff --git a/dumps/scripts/1709.cs2 b/dumps/scripts/1709.cs2 new file mode 100644 index 0000000..6d0f1e2 --- /dev/null +++ b/dumps/scripts/1709.cs2 @@ -0,0 +1,147 @@ +int script_1709(int arg0) { + int ivar1; + ivar1 = 0; + switch (arg0) { + case 0: + if (((boolean)bitconfig_5944)) { + if (getItemIdInSlot(94, 2) == 19892) { + ivar1 = add(add(ivar1, 5), 5); + } else { + ivar1 = add(ivar1, 5); + } + } else if (((boolean)bitconfig_5947)) { + if (getItemIdInSlot(94, 2) == 19892) { + ivar1 = add(add(ivar1, 10), 5); + } else { + ivar1 = add(ivar1, 10); + } + } else { + if (((boolean)bitconfig_5953)) { + if (getItemIdInSlot(94, 2) == 19892) { + ivar1 = add(add(ivar1, 15), 5); + } else { + ivar1 = add(ivar1, 15); + } + } + } + if (((boolean)bitconfig_5967)) { + ivar1 = add(ivar1, 15); + } + if (((boolean)bitconfig_5968)) { + ivar1 = add(ivar1, 20); + } + break; + case 2: + if (((boolean)bitconfig_5943)) { + if (getItemIdInSlot(94, 2) == 19892) { + ivar1 = add(add(ivar1, 5), 5); + } else { + ivar1 = add(ivar1, 5); + } + } else if (((boolean)bitconfig_5946)) { + if (getItemIdInSlot(94, 2) == 19892) { + ivar1 = add(add(ivar1, 10), 5); + } else { + ivar1 = add(ivar1, 10); + } + } else { + if (((boolean)bitconfig_5952)) { + if (getItemIdInSlot(94, 2) == 19892) { + ivar1 = add(add(ivar1, 15), 5); + } else { + ivar1 = add(ivar1, 15); + } + } + } + if (((boolean)bitconfig_5967)) { + ivar1 = add(ivar1, 18); + } + if (((boolean)bitconfig_5968)) { + ivar1 = add(ivar1, 23); + } + break; + case 1: + if (((boolean)bitconfig_5942)) { + if (getItemIdInSlot(94, 2) == 19892) { + ivar1 = add(add(ivar1, 5), 5); + } else { + ivar1 = add(ivar1, 5); + } + } else if (((boolean)bitconfig_5945)) { + if (getItemIdInSlot(94, 2) == 19892) { + ivar1 = add(add(ivar1, 10), 5); + } else { + ivar1 = add(ivar1, 10); + } + } else if (((boolean)bitconfig_5951)) { + if (getItemIdInSlot(94, 2) == 19892) { + ivar1 = add(add(ivar1, 15), 5); + } else { + ivar1 = add(ivar1, 15); + } + } else if (((boolean)bitconfig_7769)) { + ivar1 = add(ivar1, 25); + } else { + if (((boolean)bitconfig_7381)) { + ivar1 = add(ivar1, 25); + } + } + if (((boolean)bitconfig_5967)) { + ivar1 = add(ivar1, 20); + } + if (((boolean)bitconfig_5968)) { + ivar1 = add(ivar1, 25); + } + break; + case 4: + if (((boolean)bitconfig_5960)) { + if (getItemIdInSlot(94, 2) == 19892) { + ivar1 = add(add(ivar1, 5), 5); + } else { + ivar1 = add(ivar1, 5); + } + } else if (((boolean)bitconfig_5962)) { + if (getItemIdInSlot(94, 2) == 19892) { + ivar1 = add(add(ivar1, 10), 5); + } else { + ivar1 = add(ivar1, 10); + } + } else if (((boolean)bitconfig_5964)) { + if (getItemIdInSlot(94, 2) == 19892) { + ivar1 = add(add(ivar1, 15), 5); + } else { + ivar1 = add(ivar1, 15); + } + } else { + if (((boolean)bitconfig_7381)) { + ivar1 = add(ivar1, 20); + } + } + break; + case 6: + if (((boolean)bitconfig_5961)) { + if (getItemIdInSlot(94, 2) == 19892) { + ivar1 = add(add(ivar1, 5), 5); + } else { + ivar1 = add(ivar1, 5); + } + } else if (((boolean)bitconfig_5963)) { + if (getItemIdInSlot(94, 2) == 19892) { + ivar1 = add(add(ivar1, 10), 5); + } else { + ivar1 = add(ivar1, 10); + } + } else if (((boolean)bitconfig_5965)) { + if (getItemIdInSlot(94, 2) == 19892) { + ivar1 = add(add(ivar1, 15), 5); + } else { + ivar1 = add(ivar1, 15); + } + } else { + if (((boolean)bitconfig_7769)) { + ivar1 = add(ivar1, 20); + } + } + } + return ivar1; +} diff --git a/dumps/scripts/171.cs2 b/dumps/scripts/171.cs2 new file mode 100644 index 0000000..71c615e --- /dev/null +++ b/dumps/scripts/171.cs2 @@ -0,0 +1,36 @@ +void script_171() { + if (((boolean)globalint_40)) { + setWidgetText(new WidgetPointer(390,6), "Show riddle"); + setWidgetContextMenuOption(1, new WidgetPointer(390,6), "Show"); + setWidgetIsHidden(false, new WidgetPointer(390,7)); + setWidgetIsHidden(false, new WidgetPointer(390,8)); + setWidgetIsHidden(false, new WidgetPointer(390,9)); + setWidgetIsHidden(false, new WidgetPointer(390,10)); + setWidgetIsHidden(false, new WidgetPointer(390,11)); + setWidgetIsHidden(false, new WidgetPointer(390,12)); + setWidgetIsHidden(false, new WidgetPointer(390,13)); + setWidgetIsHidden(false, new WidgetPointer(390,14)); + setWidgetIsHidden(true, new WidgetPointer(390,3)); + setWidgetIsHidden(true, new WidgetPointer(390,5)); + globalint_40 = 1; + } else { + setWidgetText(new WidgetPointer(390,6), "Hide riddle"); + setWidgetContextMenuOption(1, new WidgetPointer(390,6), "Hide"); + setWidgetText(new WidgetPointer(390,18), "You seek the grail of old," + "
" + "but no longer is it a goblet of gold." + "
" + "Among these nine will you find what you seek," + "
" + "but be careful and don't peek!" + "
" + "A wrong choice will expel you," + "
" + "so consider carefully each clue." + "
" + "
" + "Three boxes contain only air," + "
" + "beware of three boxes, for danger lurks there." + "
" + "Two hold only rubbish but would fool you with disguise," + "
" + "only one box holds your prize." + "
" + "
" + "Clues will give the information you need," + "
" + "
" + "rubbish always sits to the right of danger, pay heed." + "
" + "There is nothing helpful in boxes great in height," + "
" + "and boxes on either end will not end your plight." + "
" + "A tall or small box will only bring you anger," + "
" + "but a square box will not put you in danger."); + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(390,18)); + setWidgetIsHidden(true, new WidgetPointer(390,7)); + setWidgetIsHidden(true, new WidgetPointer(390,8)); + setWidgetIsHidden(true, new WidgetPointer(390,9)); + setWidgetIsHidden(true, new WidgetPointer(390,10)); + setWidgetIsHidden(true, new WidgetPointer(390,11)); + setWidgetIsHidden(true, new WidgetPointer(390,12)); + setWidgetIsHidden(true, new WidgetPointer(390,13)); + setWidgetIsHidden(true, new WidgetPointer(390,14)); + setWidgetIsHidden(false, new WidgetPointer(390,3)); + setWidgetIsHidden(false, new WidgetPointer(390,5)); + setWidgetScrollMax(190, 520, new WidgetPointer(390,19)); + script_31(25559045, 25559059, 792, 789, 790, 791, 773, 788); + globalint_40 = 0; + } + return; +} diff --git a/dumps/scripts/1710.cs2 b/dumps/scripts/1710.cs2 new file mode 100644 index 0000000..be447c7 --- /dev/null +++ b/dumps/scripts/1710.cs2 @@ -0,0 +1,20 @@ +int script_1710(int arg0) { + int ivar1; + ivar1 = script_1711(arg0); + if (bitconfig_6839 > 0) { + switch (arg0) { + case 0: + ivar1 = add(ivar1, 15); + ivar1 = add(ivar1, script_1714(arg0, bitconfig_6844)); + break; + case 2: + ivar1 = add(ivar1, 23); + ivar1 = add(ivar1, script_1714(arg0, bitconfig_6845)); + break; + case 1: + ivar1 = add(ivar1, 15); + ivar1 = add(ivar1, script_1714(arg0, bitconfig_6846)); + } + } + return ivar1; +} diff --git a/dumps/scripts/1711.cs2 b/dumps/scripts/1711.cs2 new file mode 100644 index 0000000..b6e728d --- /dev/null +++ b/dumps/scripts/1711.cs2 @@ -0,0 +1,41 @@ +int script_1711(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + ivar1 = -25; + ivar2 = 15; + ivar3 = script_1695(arg0); + ivar4 = script_1696(arg0); + if (ivar3 == 4) { + ivar1 = subtract(0, 25); + } else { + if (((boolean)ivar3)) { + ivar1 = subtract(0, 20); + } + } + ivar5 = script_1714(arg0, script_1697(arg0)); + ivar6 = script_1713(arg0); + ivar7 = script_1712(arg0); + ivar8 = 0; + if (getItemIdInSlot(94, 2) == 19892) { + ivar8 = 5; + } + if ((ivar6 < add(ivar8, 5)) && (ivar4 == 4)) { + ivar6 = add(ivar8, 5); + } + if ((ivar7 < 10) && (ivar3 == 4)) { + if (add(ivar7, ivar5) > subtract(0, 10)) { + ivar7 = subtract(0, 10); + } + } else { + if (((ivar7 < 10) && ((boolean)ivar3)) && (add(ivar7, ivar5) > subtract(0, 10))) { + ivar7 = subtract(0, 10); + } + } + return min(max(add(add(ivar5, ivar6), ivar7), ivar1), ivar2); +} diff --git a/dumps/scripts/1712.cs2 b/dumps/scripts/1712.cs2 new file mode 100644 index 0000000..5af416e --- /dev/null +++ b/dumps/scripts/1712.cs2 @@ -0,0 +1,50 @@ +int script_1712(int arg0) { + int ivar1; + ivar1 = 0; + if (getItemIdInSlot(94, 2) == 19892) { + ivar1 = multiplyDivide(getSkillActualLvl(arg0), 100, 5); + } + switch (arg0) { + case 0: + if (bitconfig_6852 > 0) { + return subtract(0, script_1714(0, script_1718(0, add(10, ivar1)))); + } + if (bitconfig_6847 > 0) { + return subtract(0, script_1714(0, script_1718(0, add(10, ivar1)))); + } + return 0; + case 2: + if (bitconfig_6853 > 0) { + return subtract(0, script_1714(2, script_1718(2, add(10, ivar1)))); + } + if (bitconfig_6848 > 0) { + return subtract(0, script_1714(2, script_1718(2, add(10, ivar1)))); + } + return 0; + case 1: + if (bitconfig_6854 > 0) { + return subtract(0, script_1714(1, script_1718(1, add(10, ivar1)))); + } + if (bitconfig_6849 > 0) { + return subtract(0, script_1714(1, script_1718(1, add(10, ivar1)))); + } + return 0; + case 4: + if (bitconfig_6855 > 0) { + return subtract(0, script_1714(4, script_1718(4, add(10, ivar1)))); + } + if (bitconfig_6850 > 0) { + return subtract(0, script_1714(4, script_1718(4, add(10, ivar1)))); + } + return 0; + case 6: + if (bitconfig_6856 > 0) { + return subtract(0, script_1714(6, script_1718(0, add(10, ivar1)))); + } + if (bitconfig_6851 > 0) { + return subtract(0, script_1714(6, script_1718(0, add(10, ivar1)))); + } + return 0; + } + return 0; +} diff --git a/dumps/scripts/1713.cs2 b/dumps/scripts/1713.cs2 new file mode 100644 index 0000000..5a0ce17 --- /dev/null +++ b/dumps/scripts/1713.cs2 @@ -0,0 +1,34 @@ +int script_1713(int arg0) { + int ivar1; + ivar1 = 0; + if (getItemIdInSlot(94, 2) == 19892) { + ivar1 = multiplyDivide(getSkillActualLvl(arg0), 100, 5); + } + switch (arg0) { + case 0: + if (((boolean)bitconfig_6830)) { + return script_1714(0, script_1718(0, add(ivar1, 5))); + } + break; + case 2: + if (((boolean)bitconfig_6834)) { + return script_1714(2, script_1718(2, add(ivar1, 5))); + } + break; + case 1: + if (((boolean)bitconfig_6833)) { + return script_1714(1, script_1718(1, add(ivar1, 5))); + } + break; + case 4: + if (((boolean)bitconfig_6831)) { + return script_1714(4, script_1718(4, add(ivar1, 5))); + } + break; + case 6: + if (((boolean)bitconfig_6832)) { + return script_1714(6, script_1718(6, add(ivar1, 5))); + } + } + return 0; +} diff --git a/dumps/scripts/1714.cs2 b/dumps/scripts/1714.cs2 new file mode 100644 index 0000000..45c27ca --- /dev/null +++ b/dumps/scripts/1714.cs2 @@ -0,0 +1,6 @@ +int script_1714(int arg0,int arg1) { + if (getSkillActualLvl(arg0) != 0) { + return divide(multiply(arg1, 100), getSkillActualLvl(arg0)); + } + return 0; +} diff --git a/dumps/scripts/1715.cs2 b/dumps/scripts/1715.cs2 new file mode 100644 index 0000000..dbf9958 --- /dev/null +++ b/dumps/scripts/1715.cs2 @@ -0,0 +1,39 @@ +void script_1715() { + int ivar0; + ivar0 = -1; + if (globalint_1043 == -1) { + return; + } + switch (globalint_1043) { + case 4761: + case 4762: + ivar0 = 1572874; + break; + case 4764: + case 4763: + ivar0 = 1572872; + break; + case 4765: + case 4766: + ivar0 = 1572873; + break; + case 4767: + case 4768: + ivar0 = 1572875; + break; + case 4770: + case 4769: + ivar0 = 1572876; + break; + case 4772: + case 4771: + ivar0 = 1572877; + } + if (ivar0 == -1) { + return; + } + setItemOnWidgetMethod2200(globalint_1043, -1, new WidgetPointer(ivar0)); + setWidget3DViewDistance(1600, new WidgetPointer(ivar0)); + setWidgetAnimation(12554, new WidgetPointer(ivar0)); + return; +} diff --git a/dumps/scripts/1716.cs2 b/dumps/scripts/1716.cs2 new file mode 100644 index 0000000..28b6535 --- /dev/null +++ b/dumps/scripts/1716.cs2 @@ -0,0 +1,7 @@ +void script_1716() { + if (globalint_1063 != bitconfig_6840) { + globalint_1063 = bitconfig_6840; + script_1717(); + } + return; +} diff --git a/dumps/scripts/1717.cs2 b/dumps/scripts/1717.cs2 new file mode 100644 index 0000000..aaf4377 --- /dev/null +++ b/dumps/scripts/1717.cs2 @@ -0,0 +1,24 @@ +void script_1717() { + if (((boolean)globalint_181)) { + deleteAllExtraChilds(new WidgetPointer(271,7)); + deleteAllExtraChilds(new WidgetPointer(271,8)); + setWidgetIsHidden(false, new WidgetPointer(271,42)); + setWidgetIsHidden(true, new WidgetPointer(271,0)); + script_1388(17760298); + script_1237(17760264); + setWidgetIsHidden(true, new WidgetPointer(271,9)); + deleteAllExtraChilds(new WidgetPointer(271,6)); + cs2method2100(0, 0, new WidgetPointer(271,5)); + setWidgetSize(16384, 16384, 2, 2, new WidgetPointer(271,5)); + } else { + deleteAllExtraChilds(new WidgetPointer(271,42)); + setWidgetIsHidden(true, new WidgetPointer(271,42)); + setWidgetIsHidden(false, new WidgetPointer(271,0)); + script_1237(17760264); + script_1293(17760263); + setWidgetIsHidden(false, new WidgetPointer(271,9)); + setWidgetSize(16384, add(getWidgetActualHeight(new WidgetPointer(271,9)), getWidgetActualHeight(new WidgetPointer(271,0))), 2, 1, new WidgetPointer(271,5)); + script_1704(); + } + return; +} diff --git a/dumps/scripts/1718.cs2 b/dumps/scripts/1718.cs2 new file mode 100644 index 0000000..7d5117e --- /dev/null +++ b/dumps/scripts/1718.cs2 @@ -0,0 +1,3 @@ +int script_1718(int arg0,int arg1) { + return divide(multiply(getSkillActualLvl(arg0), arg1), 100); +} diff --git a/dumps/scripts/1719.cs2 b/dumps/scripts/1719.cs2 new file mode 100644 index 0000000..af7f8b8 --- /dev/null +++ b/dumps/scripts/1719.cs2 @@ -0,0 +1,14 @@ +int script_1719() { + int ivar0; + ivar0 = 0; + ivar0 = add(ivar0, bitconfig_8136); + ivar0 = add(ivar0, bitconfig_8137); + ivar0 = add(ivar0, bitconfig_8138); + ivar0 = add(ivar0, bitconfig_8139); + ivar0 = add(ivar0, bitconfig_8140); + ivar0 = add(ivar0, bitconfig_8141); + ivar0 = add(ivar0, bitconfig_8145); + ivar0 = add(ivar0, bitconfig_8146); + ivar0 = add(ivar0, bitconfig_8148); + return ivar0; +} diff --git a/dumps/scripts/172.cs2 b/dumps/scripts/172.cs2 new file mode 100644 index 0000000..d4de81e --- /dev/null +++ b/dumps/scripts/172.cs2 @@ -0,0 +1,32 @@ +void script_172() { + globalint_12 = 0; + globalint_13 = 0; + globalint_14 = 0; + globalint_15 = 0; + globalint_16 = 0; + globalint_17 = 0; + globalint_18 = 0; + globalint_19 = 0; + globalint_20 = 0; + globalint_21 = 0; + globalint_22 = 0; + globalint_23 = 0; + globalint_24 = 0; + globalint_25 = 0; + globalint_26 = 0; + globalint_27 = 0; + globalint_28 = 0; + globalint_29 = 0; + globalint_30 = 0; + globalint_31 = 0; + globalint_32 = 0; + globalint_33 = 0; + globalint_34 = 0; + globalint_35 = 0; + globalint_36 = 0; + globalint_37 = 0; + globalint_38 = 0; + globalint_39 = 0; + globalint_212 = 0; + return; +} diff --git a/dumps/scripts/1720.cs2 b/dumps/scripts/1720.cs2 new file mode 100644 index 0000000..d2def77 --- /dev/null +++ b/dumps/scripts/1720.cs2 @@ -0,0 +1,14 @@ +int script_1720() { + int ivar0; + ivar0 = 0; + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + return ivar0; +} diff --git a/dumps/scripts/1721.cs2 b/dumps/scripts/1721.cs2 new file mode 100644 index 0000000..f08edb0 --- /dev/null +++ b/dumps/scripts/1721.cs2 @@ -0,0 +1,79 @@ +void script_1721() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + string svar0; + int stack_dump0; + cs2func_script_2791_struct(4,1,0) structdump_1; + ivar0 = 0; + ivar1 = 84; + ivar2 = 5; + ivar3 = 0; + ivar4 = 0; + ivar5 = 125; + ivar6 = 64; + ivar7 = 32; + ivar8 = 10; + ivar9 = -1; + ivar10 = 2200; + svar0 = ""; + ivar11 = 0; + ivar12 = -1; + ivar13 = 0; + if (((boolean)mod(getCommonDefinitionSize(869), ivar2))) { + ivar13 = multiply(divide(getCommonDefinitionSize(869), ivar2), ivar5); + } else { + ivar13 = add(multiply(divide(getCommonDefinitionSize(869), ivar2), ivar5), ivar5); + } + deleteAllExtraChilds(new WidgetPointer(88,22)); + deleteAllExtraChilds(new WidgetPointer(88,23)); + setWidgetScrollMax(multiply(ivar2, ivar1), ivar13, new WidgetPointer(88,21)); + while (ivar0 < getCommonDefinitionSize(869)) { + createExtraChild(new WidgetPointer(88,22), 6, ivar0); + setWidgetSize(ivar1, ivar5, 0, 0); + stack_dump0 = ivar0; + structdump_1 = script_2791(stack_dump0); + ivar12 = structdump_1.intpart_3; + ivar10 = structdump_1.intpart_2; + ivar11 = structdump_1.intpart_1; + svar0 = structdump_1.stringpart_0; + ivar9 = structdump_1.intpart_0; + setWidgetModel(ivar9); + setWidget3DRotation(1, 20, 5, 1950, 0, ivar10); + setWidgetPosition(multiply(ivar3, ivar1), multiply(ivar4, ivar5), 0, 0); + if (((boolean)ivar11)) { + setWidgetContextMenuOption(1, "Speak-to"); + setScriptCallOnMouseOver(1860, -2147483643, ivar12, "iA"); + setScriptCallOnMouseExit(2607, -2147483643, "i"); + } + createExtraChild(new WidgetPointer(88,23), 4, ivar0); + setWidgetSize(ivar6, ivar7, 0, 0); + setWidgetRGB(new Color(255, 153, 53)); + setWidgetFont(494); + setWidgetUnknownBoolean(true); + setWidgetText(svar0); + setWidgetTextAlignment(1, 1, 0); + setWidgetPosition(add(multiply(ivar3, ivar1), ivar8), add(multiply(ivar4, ivar5), ivar8), 0, 0); + ivar3 = add(ivar3, 1); + if (ivar3 >= ivar2) { + ivar3 = 0; + ivar4 = add(ivar4, 1); + } + ivar0 = add(ivar0, 1); + } + if (((boolean)cs2method2601(new WidgetPointer(88,22)))) { + script_31(5767188, 5767189, 792, 789, 790, 791, 773, 788); + } + return; +} diff --git a/dumps/scripts/1722.cs2 b/dumps/scripts/1722.cs2 new file mode 100644 index 0000000..572f2ac --- /dev/null +++ b/dumps/scripts/1722.cs2 @@ -0,0 +1,8 @@ +void script_1722(int arg0,int arg1,int arg2,int arg3,int arg4) { + arg4 = add(arg4, getClientCycle()); + if (setWidgetRegister(new WidgetPointer(arg0), arg1) || ((arg1 == -1) && setWidgetRegister(new WidgetPointer(arg0)))) { + setWidgetSprite(arg2); + setScriptCallOnGameloop(1723, new WidgetPointer(arg0), arg1, arg3, arg4, "Iidi"); + } + return; +} diff --git a/dumps/scripts/1723.cs2 b/dumps/scripts/1723.cs2 new file mode 100644 index 0000000..b76c3ea --- /dev/null +++ b/dumps/scripts/1723.cs2 @@ -0,0 +1,10 @@ +void script_1723(int arg0,int arg1,int arg2,int arg3) { + if (getClientCycle() < arg3) { + return; + } + if (setWidgetRegister(new WidgetPointer(arg0), arg1) || ((arg1 == -1) && setWidgetRegister(new WidgetPointer(arg0)))) { + setWidgetSprite(arg2); + setScriptCallOnGameloop(-1, ""); + } + return; +} diff --git a/dumps/scripts/1724.cs2 b/dumps/scripts/1724.cs2 new file mode 100644 index 0000000..b08379d --- /dev/null +++ b/dumps/scripts/1724.cs2 @@ -0,0 +1,4 @@ +void script_1724(int arg0) { + script_1725(arg0); + return; +} diff --git a/dumps/scripts/1725.cs2 b/dumps/scripts/1725.cs2 new file mode 100644 index 0000000..d492254 --- /dev/null +++ b/dumps/scripts/1725.cs2 @@ -0,0 +1,5 @@ +void script_1725(int arg0) { + setWidgetIsHidden(false, new WidgetPointer(arg0)); + setScriptCallOnGameloop(1726, new WidgetPointer(arg0), "I", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1726.cs2 b/dumps/scripts/1726.cs2 new file mode 100644 index 0000000..a32f5c7 --- /dev/null +++ b/dumps/scripts/1726.cs2 @@ -0,0 +1,13 @@ +void script_1726(int arg0) { + int ivar1; + ivar1 = 0; + if (mod(getClientCycle(), 40) > 20) { + cs2method2103(0, new WidgetPointer(arg0)); + if (mod(getClientCycle(), 40) == 21) { + playSoundEffect(5009, 1, 0); + } + } else { + cs2method2103(255, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/1727.cs2 b/dumps/scripts/1727.cs2 new file mode 100644 index 0000000..e8e582c --- /dev/null +++ b/dumps/scripts/1727.cs2 @@ -0,0 +1,4 @@ +void script_1727(int arg0) { + script_1728(arg0); + return; +} diff --git a/dumps/scripts/1728.cs2 b/dumps/scripts/1728.cs2 new file mode 100644 index 0000000..1eba235 --- /dev/null +++ b/dumps/scripts/1728.cs2 @@ -0,0 +1,5 @@ +void script_1728(int arg0) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + cs2method2103(0, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1729.cs2 b/dumps/scripts/1729.cs2 new file mode 100644 index 0000000..7c55a99 --- /dev/null +++ b/dumps/scripts/1729.cs2 @@ -0,0 +1,4 @@ +void script_1729(int arg0) { + script_1730(arg0, -1); + return; +} diff --git a/dumps/scripts/173.cs2 b/dumps/scripts/173.cs2 new file mode 100644 index 0000000..fcf2b63 --- /dev/null +++ b/dumps/scripts/173.cs2 @@ -0,0 +1,5 @@ +void script_173(int arg0) { + globalint_42 = arg0; + script_178(); + return; +} diff --git a/dumps/scripts/1730.cs2 b/dumps/scripts/1730.cs2 new file mode 100644 index 0000000..577896e --- /dev/null +++ b/dumps/scripts/1730.cs2 @@ -0,0 +1,20 @@ +void script_1730(int arg0,int arg1) { + flow_0: + IF (arg1 == -1) + GOTO flow_1 + GOTO flow_2 + flow_1: + IF (setWidgetRegister(new WidgetPointer(arg0))) + GOTO flow_3 + flow_2: + IF (setWidgetRegister(new WidgetPointer(arg0), arg1) && (globalint_198 != 1)) + GOTO flow_4 + GOTO flow_5 + flow_3: + flow_4: + setWidgetHidden(0); + globalint_198 = 1; + setScriptCallOnGameloop(2196, new WidgetPointer(arg0), arg1, getWidgetText(), "Iis"); + flow_5: + return; +} diff --git a/dumps/scripts/1731.cs2 b/dumps/scripts/1731.cs2 new file mode 100644 index 0000000..e4d6583 --- /dev/null +++ b/dumps/scripts/1731.cs2 @@ -0,0 +1,4 @@ +void script_1731(int arg0,string arg1) { + script_2197(arg0, -1, arg1); + return; +} diff --git a/dumps/scripts/1732.cs2 b/dumps/scripts/1732.cs2 new file mode 100644 index 0000000..5971725 --- /dev/null +++ b/dumps/scripts/1732.cs2 @@ -0,0 +1,4 @@ +void script_1732(int arg0) { + globalint_198 = 0; + return; +} diff --git a/dumps/scripts/1733.cs2 b/dumps/scripts/1733.cs2 new file mode 100644 index 0000000..e1a1764 --- /dev/null +++ b/dumps/scripts/1733.cs2 @@ -0,0 +1,4 @@ +void script_1733(int arg0) { + globalint_198 = 0; + return; +} diff --git a/dumps/scripts/1734.cs2 b/dumps/scripts/1734.cs2 new file mode 100644 index 0000000..06ebbb0 --- /dev/null +++ b/dumps/scripts/1734.cs2 @@ -0,0 +1,4 @@ +void script_1734(int arg0,int arg1) { + script_1735(arg0, arg1); + return; +} diff --git a/dumps/scripts/1735.cs2 b/dumps/scripts/1735.cs2 new file mode 100644 index 0000000..54624d3 --- /dev/null +++ b/dumps/scripts/1735.cs2 @@ -0,0 +1,7 @@ +void script_1735(int arg0,int arg1) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetHidden(0); + setScriptCallOnGameloop(1736, new WidgetPointer(arg0), arg1, "Ii"); + } + return; +} diff --git a/dumps/scripts/1736.cs2 b/dumps/scripts/1736.cs2 new file mode 100644 index 0000000..c19510b --- /dev/null +++ b/dumps/scripts/1736.cs2 @@ -0,0 +1,15 @@ +void script_1736(int arg0,int arg1) { + int ivar2; + ivar2 = 0; + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + if (mod(getClientCycle(), 40) > 20) { + cs2method2103(0); + if (mod(getClientCycle(), 40) == 21) { + playSoundEffect(5009, 1, 0); + } + } else { + cs2method2103(255); + } + } + return; +} diff --git a/dumps/scripts/1737.cs2 b/dumps/scripts/1737.cs2 new file mode 100644 index 0000000..f369249 --- /dev/null +++ b/dumps/scripts/1737.cs2 @@ -0,0 +1,4 @@ +void script_1737(int arg0,int arg1) { + script_1738(arg0, arg1); + return; +} diff --git a/dumps/scripts/1738.cs2 b/dumps/scripts/1738.cs2 new file mode 100644 index 0000000..3c0bfd2 --- /dev/null +++ b/dumps/scripts/1738.cs2 @@ -0,0 +1,7 @@ +void script_1738(int arg0,int arg1) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + cs2method2103(0); + setScriptCallOnGameloop(-1, ""); + } + return; +} diff --git a/dumps/scripts/1739.cs2 b/dumps/scripts/1739.cs2 new file mode 100644 index 0000000..a643c74 --- /dev/null +++ b/dumps/scripts/1739.cs2 @@ -0,0 +1,4 @@ +void script_1739(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,string arg6,string arg7,string arg8,string arg9,string arg10,string arg11,string arg12,string arg13,string arg14) { + setScriptCallOnItemContainerUpdate(151, new WidgetPointer(arg0), arg1, arg2, arg3, arg4, new WidgetPointer(arg5), arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg1, 1, "IviiiIsssssssssY", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/174.cs2 b/dumps/scripts/174.cs2 new file mode 100644 index 0000000..dfebc76 --- /dev/null +++ b/dumps/scripts/174.cs2 @@ -0,0 +1,7 @@ +void script_174(int arg0) { + if (globalint_42 == arg0) { + globalint_42 = -1; + script_178(); + } + return; +} diff --git a/dumps/scripts/1740.cs2 b/dumps/scripts/1740.cs2 new file mode 100644 index 0000000..0c4cabe --- /dev/null +++ b/dumps/scripts/1740.cs2 @@ -0,0 +1,4 @@ +void script_1740(int arg0) { + script_1741(arg0); + return; +} diff --git a/dumps/scripts/1741.cs2 b/dumps/scripts/1741.cs2 new file mode 100644 index 0000000..60e6b96 --- /dev/null +++ b/dumps/scripts/1741.cs2 @@ -0,0 +1,31 @@ +void script_1741(int arg0) { + if (((boolean)globalint_119)) { + setWidgetSprite(781, new WidgetPointer(750,6)); + setWidgetSprite(783, new WidgetPointer(750,3)); + setWidgetContextMenuOption(1, new WidgetPointer(arg0), "Turn run mode off"); + } else if (((boolean)globalint_119)) { + setWidgetSprite(1199, new WidgetPointer(750,6)); + setWidgetSprite(1210, new WidgetPointer(750,3)); + setWidgetContextMenuOption(1, new WidgetPointer(arg0), "Turn run mode on"); + } else if (globalint_119 == 3) { + setWidgetSprite(1794, new WidgetPointer(750,6)); + } else { + if (globalint_119 == 4) { + setWidgetSprite(1795, new WidgetPointer(750,6)); + } + } + if (getDisplayMode() >= 2) { + setWidgetSprite(1207, new WidgetPointer(arg0)); + setWidgetPosition(25, 1, 0, 0, new WidgetPointer(750,3)); + setWidgetPosition(25, 1, 0, 0, new WidgetPointer(750,4)); + setWidgetPosition(3, 15, 0, 0, new WidgetPointer(750,5)); + setWidgetPosition(31, 7, 0, 0, new WidgetPointer(750,6)); + } else { + setWidgetSprite(1206, new WidgetPointer(arg0)); + setWidgetPosition(1, 1, 0, 0, new WidgetPointer(750,3)); + setWidgetPosition(1, 1, 0, 0, new WidgetPointer(750,4)); + setWidgetPosition(29, 15, 0, 0, new WidgetPointer(750,5)); + setWidgetPosition(7, 7, 0, 0, new WidgetPointer(750,6)); + } + return; +} diff --git a/dumps/scripts/1742.cs2 b/dumps/scripts/1742.cs2 new file mode 100644 index 0000000..a6310a0 --- /dev/null +++ b/dumps/scripts/1742.cs2 @@ -0,0 +1,41 @@ +int script_1742(int arg0) { + switch (arg0) { + case 0: + return 48889880; + case 1: + return 48889987; + case 2: + return 48889881; + case 3: + return 48889882; + case 4: + return 48889883; + case 5: + return 48889884; + case 6: + return 48889885; + case 7: + return 48889886; + case 8: + return 48889887; + case 9: + return 48889888; + case 10: + return 48889889; + case 11: + return 48889890; + case 12: + return 48889891; + case 13: + return 48889892; + case 14: + return 48889893; + case 15: + return 48889894; + case 95: + return 48955400; + case 99: + return 48890032; + } + return -1; +} diff --git a/dumps/scripts/1743.cs2 b/dumps/scripts/1743.cs2 new file mode 100644 index 0000000..475fde7 --- /dev/null +++ b/dumps/scripts/1743.cs2 @@ -0,0 +1,11 @@ +int script_1743() { + int ivar0; + int ivar1; + ivar0 = getWidgetActualX(); + ivar1 = getWidgetParentId(); + while (ivar1 != -1) { + ivar0 = subtract(add(ivar0, getWidgetActualX(new WidgetPointer(ivar1))), cs2method2600(new WidgetPointer(ivar1))); + ivar1 = getWidgetParentId(new WidgetPointer(ivar1)); + } + return ivar0; +} diff --git a/dumps/scripts/1744.cs2 b/dumps/scripts/1744.cs2 new file mode 100644 index 0000000..53ac4f4 --- /dev/null +++ b/dumps/scripts/1744.cs2 @@ -0,0 +1,11 @@ +int script_1744() { + int ivar0; + int ivar1; + ivar0 = getWidgetActualY(); + ivar1 = getWidgetParentId(); + while (ivar1 != -1) { + ivar0 = subtract(add(ivar0, getWidgetActualY(new WidgetPointer(ivar1))), cs2method2601(new WidgetPointer(ivar1))); + ivar1 = getWidgetParentId(new WidgetPointer(ivar1)); + } + return ivar0; +} diff --git a/dumps/scripts/1745.cs2 b/dumps/scripts/1745.cs2 new file mode 100644 index 0000000..7013d0a --- /dev/null +++ b/dumps/scripts/1745.cs2 @@ -0,0 +1,16 @@ +void script_1745() { + if (globalint_217 < 1) { + globalint_217 = add(globalint_217, 1); + return; + } + globalint_217 = 0; + if (((boolean)globalint_216)) { + globalint_215 = subtract(globalint_215, 9); + } else { + globalint_215 = add(globalint_215, 9); + } + globalint_215 = min(globalint_215, 255); + globalint_215 = max(globalint_215, 0); + cs2method2103(globalint_215, new WidgetPointer(680,2)); + return; +} diff --git a/dumps/scripts/1746.cs2 b/dumps/scripts/1746.cs2 new file mode 100644 index 0000000..9f15228 --- /dev/null +++ b/dumps/scripts/1746.cs2 @@ -0,0 +1,11 @@ +void script_1746(int arg0,int arg1) { + if (globalint_228 > 2) { + setWidgetModel(15678, new WidgetPointer(arg0)); + setWidgetRGB(new Color(51, 255, 0), new WidgetPointer(arg1)); + } else { + setWidgetModel(15677, new WidgetPointer(arg0)); + setWidgetRGB(new Color(145, 0, 0), new WidgetPointer(arg1)); + } + setWidgetText(new WidgetPointer(arg1), intToStr(globalint_228)); + return; +} diff --git a/dumps/scripts/1747.cs2 b/dumps/scripts/1747.cs2 new file mode 100644 index 0000000..286ee0f --- /dev/null +++ b/dumps/scripts/1747.cs2 @@ -0,0 +1,11 @@ +void script_1747(int arg0,int arg1) { + if (globalint_229 > 2) { + setWidgetModel(15680, new WidgetPointer(arg0)); + setWidgetRGB(new Color(51, 255, 0), new WidgetPointer(arg1)); + } else { + setWidgetModel(15679, new WidgetPointer(arg0)); + setWidgetRGB(new Color(145, 0, 0), new WidgetPointer(arg1)); + } + setWidgetText(new WidgetPointer(arg1), intToStr(globalint_229)); + return; +} diff --git a/dumps/scripts/1748.cs2 b/dumps/scripts/1748.cs2 new file mode 100644 index 0000000..7dcfa58 --- /dev/null +++ b/dumps/scripts/1748.cs2 @@ -0,0 +1,44 @@ +void script_1748(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12,int arg13) { + int ivar14; + int ivar15; + int ivar16; + int ivar17; + ivar14 = script_718(globalint_1437); + ivar15 = script_718(globalint_1438); + ivar16 = script_715(ivar14, globalint_1439, ivar15, globalint_1440); + if (setWidgetRegister(new WidgetPointer(arg0))) { + setWidgetStringNode(718, script_4126(ivar16)); + setWidgetRGB(new Color(ivar16)); + } + if (setWidgetRegister(new WidgetPointer(arg8))) { + setWidgetStringNode(718, script_4126(ivar16)); + setWidgetRGB(new Color(ivar16)); + } + if (setWidgetRegister(new WidgetPointer(arg1))) { + setWidgetStringNode(718, script_4126(ivar14)); + setWidgetRGB(new Color(ivar14)); + } + if (setWidgetRegister(new WidgetPointer(arg2))) { + setWidgetStringNode(718, script_4126(ivar15)); + setWidgetRGB(new Color(ivar15)); + } + setWidgetModel(cs2method_3408(105, 109, 1595, divide(globalint_1449, 10)), new WidgetPointer(arg10)); + setWidgetModel(cs2method_3408(105, 109, 1595, mod(globalint_1449, 10)), new WidgetPointer(arg11)); + ivar17 = add(multiply(globalint_1437, globalint_1439), multiply(globalint_1438, globalint_1440)); + if (globalint_1449 < ivar17) { + setWidgetSprite(4567, new WidgetPointer(arg13)); + } else if (globalint_1449 > ivar17) { + setWidgetSprite(4568, new WidgetPointer(arg13)); + } else { + setWidgetSprite(4565, new WidgetPointer(arg13)); + playSoundEffect2False(3559, 1, 0, 255); + } + if (ivar16 == 65535) { + setWidgetSprite(4565, new WidgetPointer(arg12)); + playSoundEffect2False(3559, 1, 10, 255); + } else { + setWidgetSprite(4566, new WidgetPointer(arg12)); + } + script_2472(arg3, arg4, arg5, arg6, arg7, arg9, standart_config_850, standart_config_855, 1108); + return; +} diff --git a/dumps/scripts/1749.cs2 b/dumps/scripts/1749.cs2 new file mode 100644 index 0000000..a776a8b --- /dev/null +++ b/dumps/scripts/1749.cs2 @@ -0,0 +1,11 @@ +void script_1749(int arg0,int arg1) { + if (globalint_230 > 2) { + setWidgetModel(15682, new WidgetPointer(arg0)); + setWidgetRGB(new Color(51, 255, 0), new WidgetPointer(arg1)); + } else { + setWidgetModel(15681, new WidgetPointer(arg0)); + setWidgetRGB(new Color(145, 0, 0), new WidgetPointer(arg1)); + } + setWidgetText(new WidgetPointer(arg1), intToStr(globalint_230)); + return; +} diff --git a/dumps/scripts/175.cs2 b/dumps/scripts/175.cs2 new file mode 100644 index 0000000..fd6c3f4 --- /dev/null +++ b/dumps/scripts/175.cs2 @@ -0,0 +1,76 @@ +void script_175(int arg0,int arg1) { + if (standart_config_281 < 1000) { + messageType0("You can't do this while in the tutorial."); + return; + } + switch (arg0) { + case 1: + if ((globalint_41 == arg1) && (getDisplayMode() >= 2)) { + globalint_41 = -1; + script_1364(); + } else if (globalint_41 == -1) { + globalint_41 = arg1; + script_1364(); + } else { + globalint_41 = arg1; + } + switch (arg1) { + case 0: + case 2: + globalint_1650 = 0; + globalint_1651 = 0; + cs2method5006(0); + globalstring_1 = ""; + globalint_1028 = 0; + script_1558(0); + break; + case 4: + globalint_1650 = 0; + globalint_1651 = 1; + cs2method5006(1); + globalstring_1 = ""; + globalint_1028 = 0; + script_1558(0); + break; + case 7: + globalint_1650 = 0; + globalint_1651 = 2; + cs2method5006(2); + globalstring_1 = ""; + globalint_1028 = 0; + script_1558(0); + } + script_181(globalint_41); + script_178(); + script_84(); + script_89(); + break; + case 2: + script_184(arg1, 0); + script_178(); + script_84(); + script_89(); + break; + case 3: + if ((arg1 == 3) && (getFriendlistSize() < 0)) { + messageType0("The friends list is still loading, your selection won't take effect immediately."); + } + script_184(arg1, 1); + script_178(); + script_84(); + script_89(); + break; + case 4: + script_184(arg1, 2); + script_178(); + script_84(); + script_89(); + break; + case 5: + script_184(arg1, 3); + script_178(); + script_84(); + script_89(); + } + return; +} diff --git a/dumps/scripts/1750.cs2 b/dumps/scripts/1750.cs2 new file mode 100644 index 0000000..d2299dd --- /dev/null +++ b/dumps/scripts/1750.cs2 @@ -0,0 +1,151 @@ +void script_1750() { + if (((boolean)bitconfig_2309)) { + setWidgetSprite(731, new WidgetPointer(464,32)); + } else { + setWidgetSprite(751, new WidgetPointer(464,32)); + } + if (((boolean)bitconfig_2310)) { + setWidgetSprite(729, new WidgetPointer(464,30)); + } else { + setWidgetSprite(749, new WidgetPointer(464,30)); + } + if (((boolean)bitconfig_2311)) { + setWidgetSprite(732, new WidgetPointer(464,33)); + } else { + setWidgetSprite(752, new WidgetPointer(464,33)); + } + if (((boolean)bitconfig_2312)) { + setWidgetSprite(730, new WidgetPointer(464,31)); + } else { + setWidgetSprite(750, new WidgetPointer(464,31)); + } + if (bitconfig_532 >= 7) { + setWidgetSprite(726, new WidgetPointer(464,24)); + setWidgetSprite(727, new WidgetPointer(464,25)); + } else { + setWidgetSprite(746, new WidgetPointer(464,24)); + setWidgetSprite(747, new WidgetPointer(464,25)); + } + if (((boolean)bitconfig_1367)) { + setWidgetSprite(725, new WidgetPointer(464,29)); + } else { + setWidgetSprite(745, new WidgetPointer(464,29)); + } + if (((boolean)bitconfig_1368)) { + setWidgetSprite(722, new WidgetPointer(464,26)); + } else { + setWidgetSprite(742, new WidgetPointer(464,26)); + } + if (((boolean)bitconfig_1369)) { + setWidgetSprite(723, new WidgetPointer(464,27)); + } else { + setWidgetSprite(743, new WidgetPointer(464,27)); + } + if (((boolean)bitconfig_1370)) { + setWidgetSprite(724, new WidgetPointer(464,28)); + } else { + setWidgetSprite(744, new WidgetPointer(464,28)); + } + if (((boolean)bitconfig_1371)) { + setWidgetSprite(728, new WidgetPointer(464,37)); + } else { + setWidgetSprite(748, new WidgetPointer(464,37)); + } + if (((boolean)bitconfig_1920)) { + setWidgetSprite(734, new WidgetPointer(464,35)); + } else { + setWidgetSprite(754, new WidgetPointer(464,35)); + } + if (((boolean)bitconfig_1921)) { + setWidgetSprite(733, new WidgetPointer(464,34)); + } else { + setWidgetSprite(753, new WidgetPointer(464,34)); + } + if (((boolean)bitconfig_2055)) { + setWidgetSprite(735, new WidgetPointer(464,38)); + } else { + setWidgetSprite(755, new WidgetPointer(464,38)); + } + if (((boolean)bitconfig_2787)) { + setWidgetSprite(736, new WidgetPointer(464,39)); + } else { + setWidgetSprite(756, new WidgetPointer(464,39)); + } + if (bitconfig_4075 == 12) { + setWidgetSprite(737, new WidgetPointer(464,36)); + } else { + setWidgetSprite(757, new WidgetPointer(464,36)); + } + if (((boolean)bitconfig_4202)) { + setWidgetSprite(738, new WidgetPointer(464,40)); + } else { + setWidgetSprite(758, new WidgetPointer(464,40)); + } + if (((boolean)bitconfig_4394)) { + setWidgetSprite(739, new WidgetPointer(464,41)); + } else { + setWidgetSprite(759, new WidgetPointer(464,41)); + } + if (((boolean)bitconfig_4476)) { + setWidgetSprite(0, new WidgetPointer(464,42)); + } else { + setWidgetSprite(5, new WidgetPointer(464,42)); + } + if (((boolean)bitconfig_4884)) { + setWidgetSprite(1416, new WidgetPointer(464,43)); + } else { + setWidgetSprite(1417, new WidgetPointer(464,43)); + } + if (((boolean)bitconfig_5490)) { + setWidgetSprite(1585, new WidgetPointer(464,44)); + } else { + setWidgetSprite(1588, new WidgetPointer(464,44)); + } + if (((boolean)bitconfig_5732)) { + setWidgetSprite(1587, new WidgetPointer(464,45)); + } else { + setWidgetSprite(1590, new WidgetPointer(464,45)); + } + if (((boolean)bitconfig_5641)) { + setWidgetSprite(1592, new WidgetPointer(464,46)); + } else { + setWidgetSprite(1593, new WidgetPointer(464,46)); + } + if ((bitconfig_6014 == 85) || (bitconfig_7322 == 18)) { + setWidgetSprite(1215, new WidgetPointer(464,47)); + } else { + setWidgetSprite(1742, new WidgetPointer(464,47)); + } + script_1626(); + if (((boolean)bitconfig_6936)) { + setWidgetSprite(2422, new WidgetPointer(464,48)); + } else { + setWidgetSprite(2423, new WidgetPointer(464,48)); + } + if (((boolean)bitconfig_6095)) { + setWidgetSprite(3757, new WidgetPointer(464,49)); + } else { + setWidgetSprite(3758, new WidgetPointer(464,49)); + } + if (bitconfig_8300 == 20) { + setWidgetSprite(3887, new WidgetPointer(464,50)); + } else { + setWidgetSprite(3889, new WidgetPointer(464,50)); + } + if (((boolean)bitconfig_8688)) { + setWidgetSprite(3888, new WidgetPointer(464,52)); + } else { + setWidgetSprite(4408, new WidgetPointer(464,52)); + } + if (bitconfig_8601 == 428) { + setWidgetSprite(4407, new WidgetPointer(464,51)); + } else { + setWidgetSprite(4409, new WidgetPointer(464,51)); + } + if (bitconfig_9198 == 60) { + setWidgetSprite(6559, new WidgetPointer(464,53)); + } else { + setWidgetSprite(6573, new WidgetPointer(464,53)); + } + return; +} diff --git a/dumps/scripts/1751.cs2 b/dumps/scripts/1751.cs2 new file mode 100644 index 0000000..81ef27e --- /dev/null +++ b/dumps/scripts/1751.cs2 @@ -0,0 +1,27 @@ +string script_1751(int arg0) { + int ivar1; + if (arg0 < 2) { + return "in a minute"; + } + ivar1 = divide(arg0, 60); + arg0 = mod(arg0, 60); + if (ivar1 > 1) { + if (arg0 > 1) { + return "in " + intToStr(ivar1) + " hours " + intToStr(arg0) + " minutes"; + } + if (((boolean)arg0)) { + return "in " + intToStr(ivar1) + " hours 1 minute"; + } + return "in " + intToStr(ivar1) + " hours"; + } + if (((boolean)ivar1)) { + if (arg0 > 1) { + return "in 1 hour " + intToStr(arg0) + " minutes"; + } + if (((boolean)arg0)) { + return "in 1 hour 1 minute"; + } + return "in 1 hour"; + } + return "in " + intToStr(arg0) + " minutes"; +} diff --git a/dumps/scripts/1752.cs2 b/dumps/scripts/1752.cs2 new file mode 100644 index 0000000..cd55a23 --- /dev/null +++ b/dumps/scripts/1752.cs2 @@ -0,0 +1,11 @@ +void script_1752(int arg0,int arg1) { + if (globalint_223 > 0) { + setWidgetModel(15669, new WidgetPointer(arg0)); + setWidgetRGB(new Color(51, 255, 0), new WidgetPointer(arg1)); + } else { + setWidgetModel(15666, new WidgetPointer(arg0)); + setWidgetRGB(new Color(145, 0, 0), new WidgetPointer(arg1)); + } + setWidgetText(new WidgetPointer(arg1), intToStr(globalint_223)); + return; +} diff --git a/dumps/scripts/1753.cs2 b/dumps/scripts/1753.cs2 new file mode 100644 index 0000000..ff037d9 --- /dev/null +++ b/dumps/scripts/1753.cs2 @@ -0,0 +1,11 @@ +void script_1753(int arg0,int arg1) { + if (globalint_224 > 0) { + setWidgetModel(15704, new WidgetPointer(arg0)); + setWidgetRGB(new Color(51, 255, 0), new WidgetPointer(arg1)); + } else { + setWidgetModel(15703, new WidgetPointer(arg0)); + setWidgetRGB(new Color(145, 0, 0), new WidgetPointer(arg1)); + } + setWidgetText(new WidgetPointer(arg1), intToStr(globalint_224)); + return; +} diff --git a/dumps/scripts/1754.cs2 b/dumps/scripts/1754.cs2 new file mode 100644 index 0000000..3ab1acc --- /dev/null +++ b/dumps/scripts/1754.cs2 @@ -0,0 +1,11 @@ +void script_1754(int arg0,int arg1) { + if (globalint_226 > 4) { + setWidgetModel(15690, new WidgetPointer(arg0)); + setWidgetRGB(new Color(51, 255, 0), new WidgetPointer(arg1)); + } else { + setWidgetModel(15689, new WidgetPointer(arg0)); + setWidgetRGB(new Color(145, 0, 0), new WidgetPointer(arg1)); + } + setWidgetText(new WidgetPointer(arg1), intToStr(globalint_226)); + return; +} diff --git a/dumps/scripts/1755.cs2 b/dumps/scripts/1755.cs2 new file mode 100644 index 0000000..9abbda3 --- /dev/null +++ b/dumps/scripts/1755.cs2 @@ -0,0 +1,19 @@ +void script_1755(int arg0,int arg1) { + if (globalint_227 > 2) { + if (getItemIdInSlot(94, 0) == 8950) { + setWidgetModel(15700, new WidgetPointer(arg0)); + } else { + setWidgetModel(15674, new WidgetPointer(arg0)); + } + setWidgetRGB(new Color(51, 255, 0), new WidgetPointer(arg1)); + } else { + if (getItemIdInSlot(94, 0) == 8950) { + setWidgetModel(15699, new WidgetPointer(arg0)); + } else { + setWidgetModel(15673, new WidgetPointer(arg0)); + } + setWidgetRGB(new Color(145, 0, 0), new WidgetPointer(arg1)); + } + setWidgetText(new WidgetPointer(arg1), intToStr(globalint_227)); + return; +} diff --git a/dumps/scripts/1756.cs2 b/dumps/scripts/1756.cs2 new file mode 100644 index 0000000..f70c722 --- /dev/null +++ b/dumps/scripts/1756.cs2 @@ -0,0 +1,11 @@ +void script_1756(int arg0,int arg1) { + if (globalint_225 > 0) { + setWidgetModel(15667, new WidgetPointer(arg0)); + setWidgetRGB(new Color(51, 255, 0), new WidgetPointer(arg1)); + } else { + setWidgetModel(15659, new WidgetPointer(arg0)); + setWidgetRGB(new Color(145, 0, 0), new WidgetPointer(arg1)); + } + setWidgetText(new WidgetPointer(arg1), intToStr(globalint_225)); + return; +} diff --git a/dumps/scripts/1757.cs2 b/dumps/scripts/1757.cs2 new file mode 100644 index 0000000..ed2954a --- /dev/null +++ b/dumps/scripts/1757.cs2 @@ -0,0 +1,9 @@ +void script_1757(int arg0,int arg1) { + if (globalint_219 > 0) { + setWidgetIsHidden(false, new WidgetPointer(arg0)); + } else { + setWidgetIsHidden(true, new WidgetPointer(arg0)); + } + setWidgetText(new WidgetPointer(arg1), intToStr(globalint_219)); + return; +} diff --git a/dumps/scripts/1758.cs2 b/dumps/scripts/1758.cs2 new file mode 100644 index 0000000..4f7d05e --- /dev/null +++ b/dumps/scripts/1758.cs2 @@ -0,0 +1,9 @@ +void script_1758(int arg0,int arg1) { + if (globalint_218 > 0) { + setWidgetIsHidden(false, new WidgetPointer(arg0)); + } else { + setWidgetIsHidden(true, new WidgetPointer(arg0)); + } + setWidgetText(new WidgetPointer(arg1), intToStr(globalint_218)); + return; +} diff --git a/dumps/scripts/1759.cs2 b/dumps/scripts/1759.cs2 new file mode 100644 index 0000000..064fe66 --- /dev/null +++ b/dumps/scripts/1759.cs2 @@ -0,0 +1,9 @@ +void script_1759(int arg0,int arg1) { + if (globalint_220 > 0) { + setWidgetIsHidden(false, new WidgetPointer(arg0)); + } else { + setWidgetIsHidden(true, new WidgetPointer(arg0)); + } + setWidgetText(new WidgetPointer(arg1), intToStr(globalint_220)); + return; +} diff --git a/dumps/scripts/176.cs2 b/dumps/scripts/176.cs2 new file mode 100644 index 0000000..f0dc8ee --- /dev/null +++ b/dumps/scripts/176.cs2 @@ -0,0 +1,5 @@ +void script_176(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7) { + script_2732(arg0, arg1, standart_config_287, 4); + setScriptCallOnClickContextMenu(3417, -2147483644, arg1, new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), new WidgetPointer(arg6), new WidgetPointer(arg7), "iiIIIIII", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1760.cs2 b/dumps/scripts/1760.cs2 new file mode 100644 index 0000000..06cb2e2 --- /dev/null +++ b/dumps/scripts/1760.cs2 @@ -0,0 +1,4 @@ +void script_1760(int arg0) { + setWidgetText(new WidgetPointer(arg0), intToStr(globalint_221)); + return; +} diff --git a/dumps/scripts/1761.cs2 b/dumps/scripts/1761.cs2 new file mode 100644 index 0000000..d32c185 --- /dev/null +++ b/dumps/scripts/1761.cs2 @@ -0,0 +1,4 @@ +void script_1761(int arg0) { + setWidgetText(new WidgetPointer(arg0), intToStr(globalint_222)); + return; +} diff --git a/dumps/scripts/1762.cs2 b/dumps/scripts/1762.cs2 new file mode 100644 index 0000000..8f551a1 --- /dev/null +++ b/dumps/scripts/1762.cs2 @@ -0,0 +1,10 @@ +void script_1762(int arg0) { + if (globalint_231 > 6) { + setWidgetText(new WidgetPointer(arg0), "Time Left : " + intToStr(subtract(globalint_231, 5)) + " mins"); + } else if (globalint_231 == 6) { + setWidgetText(new WidgetPointer(arg0), "Time Left : 1 min"); + } else { + setWidgetText(new WidgetPointer(arg0), "Time Left : 0 mins"); + } + return; +} diff --git a/dumps/scripts/1763.cs2 b/dumps/scripts/1763.cs2 new file mode 100644 index 0000000..3fd72eb --- /dev/null +++ b/dumps/scripts/1763.cs2 @@ -0,0 +1,8 @@ +void script_1763() { + setWidgetText(new WidgetPointer(894,5), globalstring_197); + setWidgetText(new WidgetPointer(894,6), globalstring_198); + setWidgetText(new WidgetPointer(894,8), globalstring_199); + setWidgetText(new WidgetPointer(894,9), globalstring_200); + setWidgetText(new WidgetPointer(894,7), ""); + return; +} diff --git a/dumps/scripts/1764.cs2 b/dumps/scripts/1764.cs2 new file mode 100644 index 0000000..2b8ccb0 --- /dev/null +++ b/dumps/scripts/1764.cs2 @@ -0,0 +1,20 @@ +void script_1764(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + ivar4 = subtract(getWidgetActualWidth(new WidgetPointer(arg0)), getWidgetActualWidth(new WidgetPointer(arg1))); + arg2 = max(arg2, 0); + arg2 = min(arg2, ivar4); + switch (arg3) { + case 0: + cs2method6019(multiplyDivide(arg2, ivar4, 255)); + script_1159(); + break; + case 1: + cs2method6018(multiplyDivide(arg2, ivar4, 127)); + script_1165(); + break; + case 2: + cs2method6020(multiplyDivide(arg2, ivar4, 127)); + script_1162(); + } + return; +} diff --git a/dumps/scripts/1765.cs2 b/dumps/scripts/1765.cs2 new file mode 100644 index 0000000..09b5289 --- /dev/null +++ b/dumps/scripts/1765.cs2 @@ -0,0 +1,4 @@ +void script_1765() { + script_1766(); + return; +} diff --git a/dumps/scripts/1766.cs2 b/dumps/scripts/1766.cs2 new file mode 100644 index 0000000..0d88a9f --- /dev/null +++ b/dumps/scripts/1766.cs2 @@ -0,0 +1,241 @@ +void script_1766() { + flow_0: + if (((boolean)globalint_232)) { + setWidgetSprite(1817, new WidgetPointer(548,138)); + setWidgetSprite(1817, new WidgetPointer(746,24)); + setWidgetContextMenuOption(1, new WidgetPointer(548,129), "Combat Styles"); + setWidgetContextMenuOption(1, new WidgetPointer(746,39), "Combat Styles"); + } else { + if (((boolean)globalint_232)) { + setWidgetSprite(7710, new WidgetPointer(548,138)); + setWidgetSprite(7710, new WidgetPointer(746,24)); + setWidgetContextMenuOption(1, new WidgetPointer(548,129), "Props"); + setWidgetContextMenuOption(1, new WidgetPointer(746,39), "Props"); + } + } + if (((boolean)globalint_822)) { + script_4089(); + setWidgetSprite(1820, new WidgetPointer(548,139)); + setWidgetSprite(1820, new WidgetPointer(746,131)); + setWidgetContextMenuOption(1, new WidgetPointer(548,130), "Task List"); + setWidgetContextMenuOption(1, new WidgetPointer(746,40), "Task List"); + } else if (((boolean)globalint_822)) { + setWidgetIsHidden(true, new WidgetPointer(746,130)); + setWidgetIsHidden(true, new WidgetPointer(548,137)); + setWidgetSprite(1812, new WidgetPointer(548,139)); + setWidgetSprite(1812, new WidgetPointer(746,131)); + setWidgetContextMenuOption(1, new WidgetPointer(548,130), "Camera"); + setWidgetContextMenuOption(1, new WidgetPointer(746,40), "Camera"); + } else { + if (globalint_822 == 2) { + setWidgetIsHidden(true, new WidgetPointer(746,130)); + setWidgetIsHidden(true, new WidgetPointer(548,137)); + setWidgetSprite(7709, new WidgetPointer(548,139)); + setWidgetSprite(7709, new WidgetPointer(746,131)); + setWidgetContextMenuOption(1, new WidgetPointer(548,130), "Spotlights"); + setWidgetContextMenuOption(1, new WidgetPointer(746,40), "Spotlights"); + } + } + SWITCH (globalint_233) { + case 1: + GOTO flow_11 + case 2: + GOTO flow_12 + case 4: + GOTO flow_13 + case 5: + GOTO flow_14 + } + setWidgetSprite(1818, new WidgetPointer(548,140)); + setWidgetSprite(1818, new WidgetPointer(746,25)); + setWidgetContextMenuOption(1, new WidgetPointer(548,131), "Stats"); + setWidgetContextMenuOption(1, new WidgetPointer(746,41), "Stats"); + GOTO flow_15 + flow_11: + setWidgetSprite(1815, new WidgetPointer(548,140)); + setWidgetSprite(1815, new WidgetPointer(746,25)); + setWidgetContextMenuOption(1, new WidgetPointer(548,131), "Squad Commands"); + setWidgetContextMenuOption(1, new WidgetPointer(746,41), "Squad Commands"); + GOTO flow_15 + flow_12: + setWidgetSprite(7708, new WidgetPointer(548,140)); + setWidgetSprite(7708, new WidgetPointer(746,25)); + setWidgetContextMenuOption(1, new WidgetPointer(548,131), "Sound Effects"); + setWidgetContextMenuOption(1, new WidgetPointer(746,41), "Sound Effects"); + GOTO flow_15 + flow_13: + setWidgetSprite(3248, new WidgetPointer(548,140)); + setWidgetSprite(3248, new WidgetPointer(746,25)); + setWidgetContextMenuOption(1, new WidgetPointer(548,131), "Turn Options"); + setWidgetContextMenuOption(1, new WidgetPointer(746,41), "Turn Options"); + GOTO flow_15 + flow_14: + setWidgetSprite(3248, new WidgetPointer(548,140)); + setWidgetSprite(3248, new WidgetPointer(746,25)); + setWidgetContextMenuOption(1, new WidgetPointer(548,131), "Command Options"); + setWidgetContextMenuOption(1, new WidgetPointer(746,41), "Command Options"); + flow_15: + SWITCH (globalint_234) { + case 1: + GOTO flow_16 + case 2: + GOTO flow_17 + case 3: + GOTO flow_18 + case 4: + GOTO flow_19 + case 5: + GOTO flow_20 + } + setWidgetSprite(1819, new WidgetPointer(548,141)); + setWidgetSprite(1819, new WidgetPointer(746,26)); + setWidgetContextMenuOption(1, new WidgetPointer(548,132), "Quest Journals"); + setWidgetContextMenuOption(1, new WidgetPointer(746,42), "Quest Journals"); + GOTO flow_21 + flow_16: + setWidgetSprite(1813, new WidgetPointer(548,141)); + setWidgetSprite(1813, new WidgetPointer(746,26)); + setWidgetContextMenuOption(1, new WidgetPointer(548,132), "Special Units"); + setWidgetContextMenuOption(1, new WidgetPointer(746,42), "Special Units"); + GOTO flow_21 + flow_17: + setWidgetSprite(3249, new WidgetPointer(548,141)); + setWidgetSprite(3249, new WidgetPointer(746,26)); + setWidgetContextMenuOption(1, new WidgetPointer(548,132), "Troop Details"); + setWidgetContextMenuOption(1, new WidgetPointer(746,42), "Troop Details"); + GOTO flow_21 + flow_18: + setWidgetSprite(3028, new WidgetPointer(548,141)); + setWidgetSprite(3028, new WidgetPointer(746,26)); + setWidgetContextMenuOption(1, new WidgetPointer(548,132), "Party organiser"); + setWidgetContextMenuOption(1, new WidgetPointer(746,42), "Party organiser"); + GOTO flow_21 + flow_19: + setWidgetSprite(1834, new WidgetPointer(548,141)); + setWidgetSprite(1834, new WidgetPointer(746,26)); + setWidgetContextMenuOption(1, new WidgetPointer(548,132), "Book"); + setWidgetContextMenuOption(1, new WidgetPointer(746,42), "Book"); + GOTO flow_21 + flow_20: + setWidgetSprite(7711, new WidgetPointer(548,141)); + setWidgetSprite(7711, new WidgetPointer(746,26)); + setWidgetContextMenuOption(1, new WidgetPointer(548,132), "Actors"); + setWidgetContextMenuOption(1, new WidgetPointer(746,42), "Actors"); + flow_21: + if (((boolean)globalint_235)) { + setWidgetSprite(1821, new WidgetPointer(548,142)); + setWidgetSprite(1821, new WidgetPointer(746,27)); + setWidgetContextMenuOption(1, new WidgetPointer(548,133), "Inventory"); + setWidgetContextMenuOption(1, new WidgetPointer(746,43), "Inventory"); + } else if (((boolean)globalint_235)) { + setWidgetSprite(1814, new WidgetPointer(548,142)); + setWidgetSprite(1814, new WidgetPointer(746,27)); + setWidgetContextMenuOption(1, new WidgetPointer(548,133), "My Squads"); + setWidgetContextMenuOption(1, new WidgetPointer(746,43), "My Squads"); + } else { + if (globalint_235 == 2) { + setWidgetSprite(3247, new WidgetPointer(548,142)); + setWidgetSprite(3247, new WidgetPointer(746,27)); + setWidgetContextMenuOption(1, new WidgetPointer(548,133), "Commands"); + setWidgetContextMenuOption(1, new WidgetPointer(746,43), "Commands"); + } + } + if (((boolean)globalint_236)) { + setWidgetSprite(1822, new WidgetPointer(548,143)); + setWidgetSprite(1822, new WidgetPointer(746,28)); + setWidgetContextMenuOption(1, new WidgetPointer(548,134), "Worn Equipment"); + setWidgetContextMenuOption(1, new WidgetPointer(746,44), "Worn Equipment"); + } else if (((boolean)globalint_236)) { + setWidgetSprite(1833, new WidgetPointer(548,143)); + setWidgetSprite(1833, new WidgetPointer(746,28)); + setWidgetContextMenuOption(1, new WidgetPointer(548,134), "Acrobat Emotes"); + setWidgetContextMenuOption(1, new WidgetPointer(746,44), "Acrobat Emotes"); + } else if (globalint_236 == 2) { + setWidgetSprite(1816, new WidgetPointer(548,143)); + setWidgetSprite(1816, new WidgetPointer(746,28)); + setWidgetContextMenuOption(1, new WidgetPointer(548,134), "Forfeit"); + setWidgetContextMenuOption(1, new WidgetPointer(746,44), "Forfeit"); + } else if (globalint_236 == 3) { + setWidgetSprite(3250, new WidgetPointer(548,143)); + setWidgetSprite(3250, new WidgetPointer(746,28)); + setWidgetContextMenuOption(1, new WidgetPointer(548,134), "Diplomacy"); + setWidgetContextMenuOption(1, new WidgetPointer(746,44), "Diplomacy"); + } else { + if (globalint_236 == 4) { + setWidgetSprite(3250, new WidgetPointer(548,143)); + setWidgetSprite(3250, new WidgetPointer(746,28)); + setWidgetContextMenuOption(1, new WidgetPointer(548,134), "Retreat"); + setWidgetContextMenuOption(1, new WidgetPointer(746,44), "Retreat"); + } + } + if (((boolean)globalint_237)) { + setWidgetSprite(1823, new WidgetPointer(548,144)); + setWidgetSprite(1823, new WidgetPointer(746,29)); + } + if (((boolean)globalint_238)) { + setWidgetSprite(1824, new WidgetPointer(548,145)); + setWidgetSprite(1824, new WidgetPointer(746,30)); + setWidgetContextMenuOption(1, new WidgetPointer(548,136), "Magic Spellbook"); + setWidgetContextMenuOption(1, new WidgetPointer(746,46), "Magic Spellbook"); + } + if (globalint_823 != 2) { + setWidgetSprite(-1, new WidgetPointer(548,107)); + setWidgetSprite(-1, new WidgetPointer(746,31)); + setWidgetNoOptions(new WidgetPointer(746,47)); + setWidgetNoOptions(new WidgetPointer(548,99)); + } else { + if (globalint_823 == 2) { + setWidgetSprite(447, new WidgetPointer(548,107)); + setWidgetSprite(447, new WidgetPointer(746,31)); + setWidgetContextMenuOption(1, new WidgetPointer(548,99), "Production"); + setWidgetContextMenuOption(1, new WidgetPointer(746,47), "Production"); + } + } + if (((boolean)globalint_240)) { + setWidgetSprite(6238, new WidgetPointer(548,108)); + setWidgetSprite(6238, new WidgetPointer(746,32)); + } + if (((boolean)globalint_241)) { + setWidgetSprite(6237, new WidgetPointer(548,109)); + setWidgetSprite(6237, new WidgetPointer(746,33)); + } + if (((boolean)globalint_242)) { + setWidgetSprite(1828, new WidgetPointer(548,110)); + setWidgetSprite(1828, new WidgetPointer(746,34)); + } + if (((boolean)globalint_243)) { + setWidgetSprite(1829, new WidgetPointer(548,111)); + setWidgetSprite(1829, new WidgetPointer(746,35)); + } + if (((boolean)globalint_244)) { + setWidgetSprite(1830, new WidgetPointer(548,112)); + setWidgetSprite(1830, new WidgetPointer(746,36)); + setWidgetContextMenuOption(1, new WidgetPointer(548,104), "Emotes"); + setWidgetContextMenuOption(1, new WidgetPointer(746,52), "Emotes"); + } else { + if (((boolean)globalint_244)) { + setWidgetSprite(3247, new WidgetPointer(548,112)); + setWidgetSprite(3247, new WidgetPointer(746,36)); + setWidgetContextMenuOption(1, new WidgetPointer(548,104), "Special Attacks"); + setWidgetContextMenuOption(1, new WidgetPointer(746,52), "Special Attacks"); + } + } + if (((boolean)globalint_245)) { + setWidgetSprite(1831, new WidgetPointer(548,113)); + setWidgetSprite(1831, new WidgetPointer(746,37)); + setWidgetContextMenuOption(1, new WidgetPointer(548,105), "Music Player"); + setWidgetContextMenuOption(1, new WidgetPointer(746,53), "Music Player"); + } else { + if (((boolean)globalint_245)) { + setWidgetSprite(7707, new WidgetPointer(548,113)); + setWidgetSprite(7707, new WidgetPointer(746,37)); + setWidgetContextMenuOption(1, new WidgetPointer(548,105), "Face Direction"); + setWidgetContextMenuOption(1, new WidgetPointer(746,53), "Face Direction"); + } + } + if (((boolean)globalint_824)) { + setWidgetSprite(1832, new WidgetPointer(548,114)); + setWidgetSprite(1832, new WidgetPointer(746,38)); + } + return; +} diff --git a/dumps/scripts/1767.cs2 b/dumps/scripts/1767.cs2 new file mode 100644 index 0000000..0a8e1de --- /dev/null +++ b/dumps/scripts/1767.cs2 @@ -0,0 +1,16 @@ +void script_1767() { + script_71(5); + doWidgetType21Task(0, new WidgetPointer(783,1)); + doWidgetType21Task(0, new WidgetPointer(783,2)); + doWidgetType21Task(0, new WidgetPointer(783,3)); + doWidgetType21Task(0, new WidgetPointer(783,4)); + doWidgetType21Task(0, new WidgetPointer(783,5)); + doWidgetType21Task(0, new WidgetPointer(783,6)); + doWidgetType21Task(0, new WidgetPointer(783,7)); + doWidgetType21Task(0, new WidgetPointer(783,8)); + doWidgetType21Task(0, new WidgetPointer(783,9)); + doWidgetType21Task(0, new WidgetPointer(783,10)); + doWidgetType21Task(0, new WidgetPointer(783,11)); + script_1766(); + return; +} diff --git a/dumps/scripts/1768.cs2 b/dumps/scripts/1768.cs2 new file mode 100644 index 0000000..6ff2825 --- /dev/null +++ b/dumps/scripts/1768.cs2 @@ -0,0 +1,4 @@ +void script_1768() { + script_71(4); + return; +} diff --git a/dumps/scripts/1769.cs2 b/dumps/scripts/1769.cs2 new file mode 100644 index 0000000..a250209 --- /dev/null +++ b/dumps/scripts/1769.cs2 @@ -0,0 +1,7 @@ +void script_1769(int arg0) { + setWidgetModel(getOtherCommonData(globalint_269, 581), new WidgetPointer(arg0)); + setWidget3DRotation(0, 160, getOtherCommonData(globalint_269, 584), getOtherCommonData(globalint_269, 585), getOtherCommonData(globalint_269, 586), getOtherCommonData(globalint_269, 583), new WidgetPointer(arg0)); + setWidgetAnimation(getOtherCommonData(globalint_269, 582), new WidgetPointer(arg0)); + setWidgetPosition(0, getOtherCommonData(globalint_269, 587), 1, 0, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/177.cs2 b/dumps/scripts/177.cs2 new file mode 100644 index 0000000..5a8fce5 --- /dev/null +++ b/dumps/scripts/177.cs2 @@ -0,0 +1,4 @@ +void script_177() { + script_178(); + return; +} diff --git a/dumps/scripts/1770.cs2 b/dumps/scripts/1770.cs2 new file mode 100644 index 0000000..87a2f81 --- /dev/null +++ b/dumps/scripts/1770.cs2 @@ -0,0 +1,76 @@ +void script_1770() { + if (((boolean)globalint_246)) { + setWidgetSprite(699, new WidgetPointer(791,19)); + script_1783(51838998, 51839029, -1, -1); + } else { + setWidgetSprite(697, new WidgetPointer(791,19)); + } + if (((boolean)globalint_246)) { + setWidgetSprite(699, new WidgetPointer(791,24)); + script_1783(51838998, 51839029, 51839000, -1); + } else { + setWidgetSprite(697, new WidgetPointer(791,24)); + } + if (globalint_246 == 2) { + setWidgetSprite(699, new WidgetPointer(791,27)); + script_1783(51838998, 51839029, 51839003, -1); + } else { + setWidgetSprite(697, new WidgetPointer(791,27)); + } + if (globalint_246 == 3) { + setWidgetSprite(699, new WidgetPointer(791,30)); + script_1783(51838998, 51839029, 51839006, -1); + } else { + setWidgetSprite(697, new WidgetPointer(791,30)); + } + if (globalint_246 == 4) { + setWidgetSprite(699, new WidgetPointer(791,33)); + script_1783(51838998, 51839029, 51839009, -1); + } else { + setWidgetSprite(697, new WidgetPointer(791,33)); + } + if (globalint_246 == 5) { + setWidgetSprite(699, new WidgetPointer(791,36)); + script_1783(51838998, 51839029, 51839012, -1); + } else { + setWidgetSprite(697, new WidgetPointer(791,36)); + } + if (globalint_246 == 6) { + setWidgetSprite(699, new WidgetPointer(791,39)); + script_1783(51838998, 51839029, 51839015, -1); + } else { + setWidgetSprite(697, new WidgetPointer(791,39)); + } + if (globalint_246 == 7) { + setWidgetSprite(699, new WidgetPointer(791,42)); + script_1783(51838998, 51839029, 51839018, -1); + } else { + setWidgetSprite(697, new WidgetPointer(791,42)); + } + if (globalint_246 == 8) { + setWidgetSprite(699, new WidgetPointer(791,45)); + script_1783(51838998, 51839029, 51839021, -1); + } else { + setWidgetSprite(697, new WidgetPointer(791,45)); + } + if (globalint_246 == 9) { + setWidgetSprite(699, new WidgetPointer(791,48)); + script_1783(51838998, 51839029, 51839024, -1); + } else { + setWidgetSprite(697, new WidgetPointer(791,48)); + } + if (globalint_246 == 10) { + setWidgetSprite(699, new WidgetPointer(791,51)); + script_1783(51838998, 51839029, 51839027, -1); + } else { + setWidgetSprite(697, new WidgetPointer(791,51)); + } + if (globalint_246 == 15) { + setWidgetSprite(699, new WidgetPointer(791,55)); + script_1783(51838998, 51839029, -1, -1); + } else { + setWidgetSprite(697, new WidgetPointer(791,55)); + } + script_1784(); + return; +} diff --git a/dumps/scripts/1771.cs2 b/dumps/scripts/1771.cs2 new file mode 100644 index 0000000..f96d4ed --- /dev/null +++ b/dumps/scripts/1771.cs2 @@ -0,0 +1,82 @@ +void script_1771() { + if (((boolean)globalint_247)) { + setWidgetSprite(699, new WidgetPointer(791,99)); + script_1783(51839072, 51839073, -1, -1); + } else { + setWidgetSprite(697, new WidgetPointer(791,99)); + } + if (((boolean)globalint_247)) { + setWidgetSprite(699, new WidgetPointer(791,59)); + script_1783(51839072, 51839073, 51839035, -1); + } else { + setWidgetSprite(697, new WidgetPointer(791,59)); + } + if (globalint_247 == 2) { + setWidgetSprite(699, new WidgetPointer(791,62)); + script_1783(51839072, 51839073, 51839038, -1); + } else { + setWidgetSprite(697, new WidgetPointer(791,62)); + } + if (globalint_247 == 3) { + setWidgetSprite(699, new WidgetPointer(791,65)); + script_1783(51839072, 51839073, 51839041, -1); + } else { + setWidgetSprite(697, new WidgetPointer(791,65)); + } + if (globalint_247 == 4) { + setWidgetSprite(699, new WidgetPointer(791,68)); + script_1783(51839072, 51839073, 51839044, -1); + } else { + setWidgetSprite(697, new WidgetPointer(791,68)); + } + if (globalint_247 == 5) { + setWidgetSprite(699, new WidgetPointer(791,71)); + script_1783(51839072, 51839073, 51839047, -1); + } else { + setWidgetSprite(697, new WidgetPointer(791,71)); + } + if (globalint_247 == 6) { + setWidgetSprite(699, new WidgetPointer(791,74)); + script_1783(51839072, 51839073, 51839050, -1); + } else { + setWidgetSprite(697, new WidgetPointer(791,74)); + } + if (globalint_247 == 7) { + setWidgetSprite(699, new WidgetPointer(791,77)); + script_1783(51839072, 51839073, 51839053, -1); + } else { + setWidgetSprite(697, new WidgetPointer(791,77)); + } + if (globalint_247 == 8) { + setWidgetSprite(699, new WidgetPointer(791,80)); + script_1783(51839072, 51839073, 51839056, -1); + } else { + setWidgetSprite(697, new WidgetPointer(791,80)); + } + if (globalint_247 == 9) { + setWidgetSprite(699, new WidgetPointer(791,83)); + script_1783(51839072, 51839073, 51839059, -1); + } else { + setWidgetSprite(697, new WidgetPointer(791,83)); + } + if (globalint_247 == 10) { + setWidgetSprite(699, new WidgetPointer(791,86)); + script_1783(51839072, 51839073, 51839062, -1); + } else { + setWidgetSprite(697, new WidgetPointer(791,86)); + } + if (globalint_247 == 11) { + setWidgetSprite(699, new WidgetPointer(791,89)); + script_1783(51839072, 51839073, 51839065, -1); + } else { + setWidgetSprite(697, new WidgetPointer(791,89)); + } + if (globalint_247 == 12) { + setWidgetSprite(699, new WidgetPointer(791,92)); + script_1783(51839072, 51839073, 51839068, -1); + } else { + setWidgetSprite(697, new WidgetPointer(791,92)); + } + script_1784(); + return; +} diff --git a/dumps/scripts/1772.cs2 b/dumps/scripts/1772.cs2 new file mode 100644 index 0000000..710dd40 --- /dev/null +++ b/dumps/scripts/1772.cs2 @@ -0,0 +1,11 @@ +void script_1772() { + if (((boolean)globalint_248)) { + setWidgetSprite(699, new WidgetPointer(791,105)); + setWidgetSprite(697, new WidgetPointer(791,108)); + } else { + setWidgetSprite(697, new WidgetPointer(791,105)); + setWidgetSprite(699, new WidgetPointer(791,108)); + } + script_1784(); + return; +} diff --git a/dumps/scripts/1773.cs2 b/dumps/scripts/1773.cs2 new file mode 100644 index 0000000..d7c42df --- /dev/null +++ b/dumps/scripts/1773.cs2 @@ -0,0 +1,17 @@ +void script_1773() { + if (((boolean)globalint_249)) { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(791,111)); + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(791,112)); + setWidgetIsHidden(true, new WidgetPointer(791,114)); + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(791,115)); + setWidgetText(new WidgetPointer(791,115), "...you keep" + "
" + "your items."); + } else { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(791,111)); + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(791,112)); + setWidgetIsHidden(false, new WidgetPointer(791,114)); + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(791,115)); + setWidgetText(new WidgetPointer(791,115), "...you DROP ALL your items."); + } + script_1784(); + return; +} diff --git a/dumps/scripts/1774.cs2 b/dumps/scripts/1774.cs2 new file mode 100644 index 0000000..c535700 --- /dev/null +++ b/dumps/scripts/1774.cs2 @@ -0,0 +1,11 @@ +void script_1774() { + if (((boolean)globalint_250)) { + setWidgetSprite(699, new WidgetPointer(791,121)); + cs2method2103(0, new WidgetPointer(791,120)); + } else { + setWidgetSprite(698, new WidgetPointer(791,121)); + cs2method2103(225, new WidgetPointer(791,120)); + } + script_1784(); + return; +} diff --git a/dumps/scripts/1775.cs2 b/dumps/scripts/1775.cs2 new file mode 100644 index 0000000..d43b325 --- /dev/null +++ b/dumps/scripts/1775.cs2 @@ -0,0 +1,41 @@ +void script_1775() { + switch (globalint_252) { + case 0: + setWidgetSprite(699, new WidgetPointer(791,127)); + setWidgetIsHidden(false, new WidgetPointer(791,125)); + setWidgetIsHidden(false, new WidgetPointer(791,126)); + setWidgetIsHidden(false, new WidgetPointer(791,124)); + setWidgetIsHidden(false, new WidgetPointer(791,123)); + cs2method2103(0, new WidgetPointer(791,122)); + break; + case 1: + setWidgetSprite(699, new WidgetPointer(791,127)); + setWidgetIsHidden(true, new WidgetPointer(791,125)); + setWidgetIsHidden(true, new WidgetPointer(791,126)); + setWidgetIsHidden(false, new WidgetPointer(791,124)); + setWidgetIsHidden(false, new WidgetPointer(791,123)); + if (isMember()) { + cs2method2103(225, new WidgetPointer(791,122)); + } else { + cs2method2103(0, new WidgetPointer(791,122)); + } + break; + case 2: + setWidgetSprite(699, new WidgetPointer(791,127)); + setWidgetIsHidden(true, new WidgetPointer(791,125)); + setWidgetIsHidden(true, new WidgetPointer(791,126)); + setWidgetIsHidden(true, new WidgetPointer(791,124)); + setWidgetIsHidden(false, new WidgetPointer(791,123)); + cs2method2103(225, new WidgetPointer(791,122)); + break; + case 3: + setWidgetSprite(698, new WidgetPointer(791,127)); + setWidgetIsHidden(true, new WidgetPointer(791,125)); + setWidgetIsHidden(true, new WidgetPointer(791,126)); + setWidgetIsHidden(true, new WidgetPointer(791,124)); + setWidgetIsHidden(true, new WidgetPointer(791,123)); + cs2method2103(225, new WidgetPointer(791,122)); + } + script_1784(); + return; +} diff --git a/dumps/scripts/1776.cs2 b/dumps/scripts/1776.cs2 new file mode 100644 index 0000000..9ca710e --- /dev/null +++ b/dumps/scripts/1776.cs2 @@ -0,0 +1,11 @@ +void script_1776() { + if (((boolean)globalint_251)) { + setWidgetSprite(699, new WidgetPointer(791,129)); + cs2method2103(0, new WidgetPointer(791,128)); + } else { + setWidgetSprite(698, new WidgetPointer(791,129)); + cs2method2103(225, new WidgetPointer(791,128)); + } + script_1784(); + return; +} diff --git a/dumps/scripts/1777.cs2 b/dumps/scripts/1777.cs2 new file mode 100644 index 0000000..5ec0548 --- /dev/null +++ b/dumps/scripts/1777.cs2 @@ -0,0 +1,11 @@ +void script_1777() { + if (((boolean)globalint_256)) { + setWidgetSprite(699, new WidgetPointer(791,131)); + cs2method2103(0, new WidgetPointer(791,130)); + } else { + setWidgetSprite(698, new WidgetPointer(791,131)); + cs2method2103(225, new WidgetPointer(791,130)); + } + script_1784(); + return; +} diff --git a/dumps/scripts/1778.cs2 b/dumps/scripts/1778.cs2 new file mode 100644 index 0000000..efc2a73 --- /dev/null +++ b/dumps/scripts/1778.cs2 @@ -0,0 +1,11 @@ +void script_1778() { + if (((boolean)globalint_253)) { + setWidgetSprite(699, new WidgetPointer(791,133)); + cs2method2103(0, new WidgetPointer(791,132)); + } else { + setWidgetSprite(698, new WidgetPointer(791,133)); + cs2method2103(225, new WidgetPointer(791,132)); + } + script_1784(); + return; +} diff --git a/dumps/scripts/1779.cs2 b/dumps/scripts/1779.cs2 new file mode 100644 index 0000000..1ca271b --- /dev/null +++ b/dumps/scripts/1779.cs2 @@ -0,0 +1,11 @@ +void script_1779() { + if (((boolean)globalint_254)) { + setWidgetSprite(699, new WidgetPointer(791,135)); + cs2method2103(0, new WidgetPointer(791,134)); + } else { + setWidgetSprite(698, new WidgetPointer(791,135)); + cs2method2103(225, new WidgetPointer(791,134)); + } + script_1784(); + return; +} diff --git a/dumps/scripts/178.cs2 b/dumps/scripts/178.cs2 new file mode 100644 index 0000000..f80a70c --- /dev/null +++ b/dumps/scripts/178.cs2 @@ -0,0 +1,45 @@ +void script_178() { + int ivar0; + int ivar1; + int ivar2; + ivar0 = 0; + ivar1 = 0; + ivar2 = 8; + while (ivar0 < ivar2) { + if ((globalint_42 == ivar0) && (globalint_41 == ivar0)) { + setWidgetSprite(1023, cs2method_3408(105, 73, 683, ivar0)); + } else if (globalint_42 == ivar0) { + setWidgetSprite(1020, cs2method_3408(105, 73, 683, ivar0)); + } else if (globalint_41 == ivar0) { + setWidgetSprite(1022, cs2method_3408(105, 73, 683, ivar0)); + } else if (((boolean)mod(divide(script_179(ivar0), 25), 2))) { + setWidgetSprite(1021, cs2method_3408(105, 73, 683, ivar0)); + } else { + setWidgetSprite(1019, cs2method_3408(105, 73, 683, ivar0)); + } + ivar0 = add(ivar0, 1); + } + if (((boolean)script_185(1))) { + setWidgetText(cs2method_3408(105, 73, 684, 1), "" + "Filter"); + } else { + setWidgetText(cs2method_3408(105, 73, 684, 1), "All"); + } + ivar0 = 2; + while (ivar0 < ivar2) { + ivar1 = script_185(ivar0); + if (((ivar0 == 3) && ((boolean)ivar1)) && (getFriendlistSize() < 0)) { + setWidgetText(cs2method_3408(105, 73, 684, ivar0), "" + "Loading"); + } else if (((boolean)ivar1)) { + setWidgetText(cs2method_3408(105, 73, 684, ivar0), "" + "Friends"); + } else if (ivar1 == 2) { + setWidgetText(cs2method_3408(105, 73, 684, ivar0), "" + "Off"); + } else if (ivar1 == 3) { + setWidgetText(cs2method_3408(105, 73, 684, ivar0), "" + "Hide"); + } else { + setWidgetText(cs2method_3408(105, 73, 684, ivar0), "On"); + } + ivar0 = add(ivar0, 1); + } + setWidgetIsHidden(false, new WidgetPointer(751,1)); + return; +} diff --git a/dumps/scripts/1780.cs2 b/dumps/scripts/1780.cs2 new file mode 100644 index 0000000..448cb19 --- /dev/null +++ b/dumps/scripts/1780.cs2 @@ -0,0 +1,11 @@ +void script_1780() { + if (((boolean)globalint_255)) { + setWidgetSprite(699, new WidgetPointer(791,137)); + cs2method2103(0, new WidgetPointer(791,136)); + } else { + setWidgetSprite(698, new WidgetPointer(791,137)); + cs2method2103(225, new WidgetPointer(791,136)); + } + script_1784(); + return; +} diff --git a/dumps/scripts/1781.cs2 b/dumps/scripts/1781.cs2 new file mode 100644 index 0000000..fe65247 --- /dev/null +++ b/dumps/scripts/1781.cs2 @@ -0,0 +1,19 @@ +void script_1781() { + int ivar0; + ivar0 = 0; + while (ivar0 <= 4) { + if (setWidgetRegister(new WidgetPointer(791,141), multiply(ivar0, 4))) { + if (globalint_257 == ivar0) { + setWidgetSprite(699); + script_1783(51839117, 51839118, 51839117, add(multiply(ivar0, 4), 3)); + } else if (isMember() && ((boolean)getOtherCommonData(cs2method_3408(105, 74, 1604, ivar0), 557))) { + setWidgetSprite(698); + } else { + setWidgetSprite(697); + } + } + ivar0 = add(ivar0, 1); + } + script_1784(); + return; +} diff --git a/dumps/scripts/1782.cs2 b/dumps/scripts/1782.cs2 new file mode 100644 index 0000000..ff5b8e6 --- /dev/null +++ b/dumps/scripts/1782.cs2 @@ -0,0 +1,26 @@ +void script_1782() { + if (standart_config_1149 != -1) { + script_1801(); + if (((boolean)globalint_258)) { + script_1363(51839119); + setScriptCallOnMouseOver(95, new WidgetPointer(-32768,3), "I", new WidgetPointer(791,143)); + setScriptCallOnMouseExit(97, new WidgetPointer(-32768,3), "I", new WidgetPointer(791,143)); + if (((boolean)globalint_259)) { + setWidgetText(new WidgetPointer(791,146), "Accept"); + setWidgetFont(496, new WidgetPointer(791,146)); + } else { + setWidgetText(new WidgetPointer(791,146), "Accept -" + "
" + "Opponent has accepted."); + setWidgetFont(494, new WidgetPointer(791,146)); + } + } else { + script_1360(51839119); + setScriptCallOnMouseOver(-1, "", new WidgetPointer(791,143)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(791,143)); + setWidgetText(new WidgetPointer(791,146), "Waiting for opponent..."); + setWidgetFont(495, new WidgetPointer(791,146)); + } + } else { + script_1802(); + } + return; +} diff --git a/dumps/scripts/1783.cs2 b/dumps/scripts/1783.cs2 new file mode 100644 index 0000000..ecaca4f --- /dev/null +++ b/dumps/scripts/1783.cs2 @@ -0,0 +1,18 @@ +void script_1783(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + if (arg2 == -1) { + if (setWidgetRegister(new WidgetPointer(arg1), 1)) { + script_157(arg1, arg0, 0, 1); + } + return; + } + ivar4 = 0; + if (setWidgetRegister(new WidgetPointer(arg2), arg3) || ((arg3 == -1) && setWidgetRegister(new WidgetPointer(arg2)))) { + ivar4 = add(getWidgetActualY(), divide(getWidgetActualHeight(), 2)); + ivar4 = subtract(ivar4, divide(getWidgetActualHeight(new WidgetPointer(arg0)), 2)); + if (setWidgetRegister(new WidgetPointer(arg1), 1)) { + script_157(arg1, arg0, ivar4, 1); + } + } + return; +} diff --git a/dumps/scripts/1784.cs2 b/dumps/scripts/1784.cs2 new file mode 100644 index 0000000..5fe72d8 --- /dev/null +++ b/dumps/scripts/1784.cs2 @@ -0,0 +1,381 @@ +void script_1784() { + int ivar0; + int ivar1; + int ivar2; + int stack_dump0; + int stack_dump1; + int stack_dump2; + int stack_dump3; + string stack_dump4; + cs2func_script_1785_struct(2,0,0) structdump_5; + cs2func_script_1785_struct(2,0,0) structdump_6; + cs2func_script_1785_struct(2,0,0) structdump_7; + cs2func_script_1785_struct(2,0,0) structdump_8; + cs2func_script_1785_struct(2,0,0) structdump_9; + cs2func_script_1785_struct(2,0,0) structdump_10; + cs2func_script_1785_struct(2,0,0) structdump_11; + cs2func_script_1785_struct(2,0,0) structdump_12; + cs2func_script_1785_struct(2,0,0) structdump_13; + cs2func_script_1785_struct(2,0,0) structdump_14; + cs2func_script_1785_struct(2,0,0) structdump_15; + cs2func_script_1785_struct(2,0,0) structdump_16; + cs2func_script_1785_struct(2,0,0) structdump_17; + cs2func_script_1785_struct(2,0,0) structdump_18; + cs2func_script_1785_struct(2,0,0) structdump_19; + cs2func_script_1785_struct(2,0,0) structdump_20; + cs2func_script_1785_struct(2,0,0) structdump_21; + cs2func_script_1785_struct(2,0,0) structdump_22; + cs2func_script_1785_struct(2,0,0) structdump_23; + cs2func_script_1785_struct(2,0,0) structdump_24; + cs2func_script_1785_struct(2,0,0) structdump_25; + cs2func_script_1785_struct(2,0,0) structdump_26; + cs2func_script_1785_struct(2,0,0) structdump_27; + cs2func_script_1785_struct(2,0,0) structdump_28; + cs2func_script_1785_struct(2,0,0) structdump_29; + cs2func_script_1785_struct(2,0,0) structdump_30; + cs2func_script_1785_struct(2,0,0) structdump_31; + cs2func_script_1785_struct(2,0,0) structdump_32; + cs2func_script_1785_struct(2,0,0) structdump_33; + cs2func_script_1785_struct(2,0,0) structdump_34; + cs2func_script_1785_struct(2,0,0) structdump_35; + cs2func_script_1785_struct(2,0,0) structdump_36; + cs2func_script_1785_struct(2,0,0) structdump_37; + ivar0 = 0; + ivar1 = subtract(getWidgetActualWidth(new WidgetPointer(792,3)), 16); + ivar2 = 0; + stack_dump0 = ivar0; + stack_dump1 = ivar2; + stack_dump2 = ivar1; + stack_dump3 = 1; + stack_dump4 = "~ Winning ~"; + structdump_5 = script_1785(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar2 = structdump_5.intpart_1; + ivar0 = structdump_5.intpart_0; + stack_dump0 = ivar0; + stack_dump1 = ivar2; + stack_dump2 = ivar1; + stack_dump3 = 0; + stack_dump4 = "Victory is awarded..."; + structdump_6 = script_1785(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar2 = structdump_6.intpart_1; + ivar0 = structdump_6.intpart_0; + if (((boolean)globalint_248)) { + stack_dump0 = ivar0; + stack_dump1 = ivar2; + stack_dump2 = ivar1; + stack_dump3 = 0; + stack_dump4 = "...to the team that defeats all its enemies."; + structdump_7 = script_1785(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar2 = structdump_7.intpart_1; + ivar0 = structdump_7.intpart_0; + } else { + stack_dump0 = ivar0; + stack_dump1 = ivar2; + stack_dump2 = ivar1; + stack_dump3 = 0; + stack_dump4 = "...to the team that defeats all its enemies, excluding the last five."; + structdump_8 = script_1785(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar2 = structdump_8.intpart_1; + ivar0 = structdump_8.intpart_0; + } + if ((globalint_246 > 0) && (globalint_246 < 15)) { + stack_dump0 = ivar0; + stack_dump1 = ivar2; + stack_dump2 = ivar1; + stack_dump3 = 0; + stack_dump4 = "OR" + "
" + "...to the team that first achieves " + intToStr(cs2method_3408(105, 105, 1605, globalint_246)) + " kills."; + structdump_9 = script_1785(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar2 = structdump_9.intpart_1; + ivar0 = structdump_9.intpart_0; + } + if (globalint_247 > 0) { + if (globalint_246 > 0) { + stack_dump0 = ivar0; + stack_dump1 = ivar2; + stack_dump2 = ivar1; + stack_dump3 = 0; + stack_dump4 = "OR" + "
" + "...to the team that scores the most kills " + script_1751(cs2method_3408(105, 105, 1800, globalint_247)) + "."; + structdump_10 = script_1785(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar2 = structdump_10.intpart_1; + ivar0 = structdump_10.intpart_0; + } else { + stack_dump0 = ivar0; + stack_dump1 = ivar2; + stack_dump2 = ivar1; + stack_dump3 = 0; + stack_dump4 = "OR" + "
" + "...to the team with the most survivors " + script_1751(cs2method_3408(105, 105, 1800, globalint_247)) + "."; + structdump_11 = script_1785(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar2 = structdump_11.intpart_1; + ivar0 = structdump_11.intpart_0; + } + } + ivar0 = add(ivar0, 7); + if (((boolean)globalint_246)) { + stack_dump0 = ivar0; + stack_dump1 = ivar2; + stack_dump2 = ivar1; + stack_dump3 = 0; + stack_dump4 = "" + "Knock-out mode:" + "" + "
" + "Once war has begun, players may no longer join/rejoin the fight."; + structdump_12 = script_1785(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar2 = structdump_12.intpart_1; + ivar0 = structdump_12.intpart_0; + } else { + stack_dump0 = ivar0; + stack_dump1 = ivar2; + stack_dump2 = ivar1; + stack_dump3 = 0; + stack_dump4 = "" + "Run-in mode:" + "" + "
" + "Players may join/rejoin the fight at any time during the war."; + structdump_13 = script_1785(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar2 = structdump_13.intpart_1; + ivar0 = structdump_13.intpart_0; + if ((globalint_246 == 15) && ((boolean)globalint_247)) { + ivar0 = add(ivar0, 7); + stack_dump0 = ivar0; + stack_dump1 = ivar2; + stack_dump2 = ivar1; + stack_dump3 = 0; + stack_dump4 = "This war has no time limit or kill target, so it might go on for ages!"; + structdump_14 = script_1785(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar2 = structdump_14.intpart_1; + ivar0 = structdump_14.intpart_0; + } + } + ivar0 = add(ivar0, 7); + stack_dump0 = ivar0; + stack_dump1 = ivar2; + stack_dump2 = ivar1; + stack_dump3 = 1; + stack_dump4 = "~ Item loss ~"; + structdump_15 = script_1785(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar2 = structdump_15.intpart_1; + ivar0 = structdump_15.intpart_0; + if (((boolean)globalint_249)) { + stack_dump0 = ivar0; + stack_dump1 = ivar2; + stack_dump2 = ivar1; + stack_dump3 = 0; + stack_dump4 = "On death, players keep their items."; + structdump_16 = script_1785(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar2 = structdump_16.intpart_1; + ivar0 = structdump_16.intpart_0; + } else { + stack_dump0 = ivar0; + stack_dump1 = ivar2; + stack_dump2 = ivar1; + stack_dump3 = 0; + stack_dump4 = "" + "On death, players DROP their items." + "" + "
" + "Players may not teleport."; + structdump_17 = script_1785(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar2 = structdump_17.intpart_1; + ivar0 = structdump_17.intpart_0; + } + ivar0 = add(ivar0, 7); + stack_dump0 = ivar0; + stack_dump1 = ivar2; + stack_dump2 = ivar1; + stack_dump3 = 1; + stack_dump4 = "~ Combat rules ~"; + structdump_18 = script_1785(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar2 = structdump_18.intpart_1; + ivar0 = structdump_18.intpart_0; + if (((boolean)globalint_250)) { + stack_dump0 = ivar0; + stack_dump1 = ivar2; + stack_dump2 = ivar1; + stack_dump3 = 0; + stack_dump4 = "Melee combat is allowed."; + structdump_19 = script_1785(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar2 = structdump_19.intpart_1; + ivar0 = structdump_19.intpart_0; + } else { + stack_dump0 = ivar0; + stack_dump1 = ivar2; + stack_dump2 = ivar1; + stack_dump3 = 0; + stack_dump4 = "" + "Melee combat" + "" + " is forbidden."; + structdump_20 = script_1785(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar2 = structdump_20.intpart_1; + ivar0 = structdump_20.intpart_0; + } + switch (globalint_252) { + case 0: + stack_dump0 = ivar0; + stack_dump1 = ivar2; + stack_dump2 = ivar1; + stack_dump3 = 0; + stack_dump4 = "Magical combat is allowed."; + structdump_21 = script_1785(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar2 = structdump_21.intpart_1; + ivar0 = structdump_21.intpart_0; + break; + case 1: + stack_dump0 = ivar0; + stack_dump1 = ivar2; + stack_dump2 = ivar1; + stack_dump3 = 0; + stack_dump4 = "Spells from the " + "" + "standard spellbook" + "" + " are allowed."; + structdump_22 = script_1785(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar2 = structdump_22.intpart_1; + ivar0 = structdump_22.intpart_0; + break; + case 2: + if (isMember()) { + stack_dump0 = ivar0; + stack_dump1 = ivar2; + stack_dump2 = ivar1; + stack_dump3 = 0; + stack_dump4 = "The " + "" + "Bind" + "" + ", " + "" + "Snare" + "" + " and " + "" + "Entangle" + "" + " spells are allowed."; + structdump_23 = script_1785(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar2 = structdump_23.intpart_1; + ivar0 = structdump_23.intpart_0; + } else { + stack_dump0 = ivar0; + stack_dump1 = ivar2; + stack_dump2 = ivar1; + stack_dump3 = 0; + stack_dump4 = "The " + "" + "Bind" + "" + " spell is allowed."; + structdump_24 = script_1785(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar2 = structdump_24.intpart_1; + ivar0 = structdump_24.intpart_0; + } + break; + case 3: + stack_dump0 = ivar0; + stack_dump1 = ivar2; + stack_dump2 = ivar1; + stack_dump3 = 0; + stack_dump4 = "" + "Magical combat" + "" + " is forbidden."; + structdump_25 = script_1785(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar2 = structdump_25.intpart_1; + ivar0 = structdump_25.intpart_0; + } + if (((boolean)globalint_251)) { + stack_dump0 = ivar0; + stack_dump1 = ivar2; + stack_dump2 = ivar1; + stack_dump3 = 0; + stack_dump4 = "Ranged combat is allowed."; + structdump_26 = script_1785(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar2 = structdump_26.intpart_1; + ivar0 = structdump_26.intpart_0; + } else { + stack_dump0 = ivar0; + stack_dump1 = ivar2; + stack_dump2 = ivar1; + stack_dump3 = 0; + stack_dump4 = "" + "Ranged combat" + "" + " is forbidden."; + structdump_27 = script_1785(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar2 = structdump_27.intpart_1; + ivar0 = structdump_27.intpart_0; + } + if (((boolean)globalint_256)) { + stack_dump0 = ivar0; + stack_dump1 = ivar2; + stack_dump2 = ivar1; + stack_dump3 = 0; + stack_dump4 = "Prayer is allowed."; + structdump_28 = script_1785(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar2 = structdump_28.intpart_1; + ivar0 = structdump_28.intpart_0; + } else { + stack_dump0 = ivar0; + stack_dump1 = ivar2; + stack_dump2 = ivar1; + stack_dump3 = 0; + stack_dump4 = "" + "Prayer" + "" + " is forbidden."; + structdump_29 = script_1785(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar2 = structdump_29.intpart_1; + ivar0 = structdump_29.intpart_0; + } + if (isMember()) { + if (((boolean)globalint_253)) { + stack_dump0 = ivar0; + stack_dump1 = ivar2; + stack_dump2 = ivar1; + stack_dump3 = 0; + stack_dump4 = "Summoning is allowed."; + structdump_30 = script_1785(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar2 = structdump_30.intpart_1; + ivar0 = structdump_30.intpart_0; + } else { + stack_dump0 = ivar0; + stack_dump1 = ivar2; + stack_dump2 = ivar1; + stack_dump3 = 0; + stack_dump4 = "" + "Summoning" + "" + " is forbidden." + "
" + "Familiars will be dismissed."; + structdump_31 = script_1785(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar2 = structdump_31.intpart_1; + ivar0 = structdump_31.intpart_0; + } + } + if (((boolean)globalint_254)) { + stack_dump0 = ivar0; + stack_dump1 = ivar2; + stack_dump2 = ivar1; + stack_dump3 = 0; + stack_dump4 = "Food is allowed."; + structdump_32 = script_1785(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar2 = structdump_32.intpart_1; + ivar0 = structdump_32.intpart_0; + } else { + stack_dump0 = ivar0; + stack_dump1 = ivar2; + stack_dump2 = ivar1; + stack_dump3 = 0; + stack_dump4 = "" + "Food" + "" + " is forbidden."; + structdump_33 = script_1785(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar2 = structdump_33.intpart_1; + ivar0 = structdump_33.intpart_0; + } + if (((boolean)globalint_255)) { + stack_dump0 = ivar0; + stack_dump1 = ivar2; + stack_dump2 = ivar1; + stack_dump3 = 0; + stack_dump4 = "Potions are allowed."; + structdump_34 = script_1785(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar2 = structdump_34.intpart_1; + ivar0 = structdump_34.intpart_0; + } else { + stack_dump0 = ivar0; + stack_dump1 = ivar2; + stack_dump2 = ivar1; + stack_dump3 = 0; + stack_dump4 = "" + "Potions" + "" + " are forbidden." + "
" + "Boosted stats will be reset (excluding Prayer boosts)."; + structdump_35 = script_1785(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar2 = structdump_35.intpart_1; + ivar0 = structdump_35.intpart_0; + } + ivar0 = add(ivar0, 7); + stack_dump0 = ivar0; + stack_dump1 = ivar2; + stack_dump2 = ivar1; + stack_dump3 = 1; + stack_dump4 = "~ Arena ~"; + structdump_36 = script_1785(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar2 = structdump_36.intpart_1; + ivar0 = structdump_36.intpart_0; + stack_dump0 = ivar0; + stack_dump1 = ivar2; + stack_dump2 = ivar1; + stack_dump3 = 0; + stack_dump4 = getOtherCommonData(cs2method_3408(105, 74, 1604, globalint_257), 555); + structdump_37 = script_1785(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar2 = structdump_37.intpart_1; + ivar0 = structdump_37.intpart_0; + if (ivar0 > getWidgetActualHeight(new WidgetPointer(792,3))) { + setWidgetIsHidden(false, new WidgetPointer(792,4)); + setWidgetPosition(7, 46, 0, 0, new WidgetPointer(792,3)); + setWidgetScrollMax(0, ivar0, new WidgetPointer(792,3)); + script_31(51904516, 51904515, 792, 789, 790, 791, 773, 788); + if (setWidgetRegister(new WidgetPointer(792,4), 1)) { + script_37(51904516, 51904515, cs2method2601(new WidgetPointer(792,3)), 1); + } + } else { + deleteAllExtraChilds(new WidgetPointer(792,4)); + setWidgetIsHidden(true, new WidgetPointer(792,4)); + setWidgetPosition(15, 46, 0, 0, new WidgetPointer(792,3)); + setWidgetScrollMax(0, 0, new WidgetPointer(792,3)); + cs2method2100(0, 0, new WidgetPointer(792,3)); + } + return; +} diff --git a/dumps/scripts/1785.cs2 b/dumps/scripts/1785.cs2 new file mode 100644 index 0000000..a14e42e --- /dev/null +++ b/dumps/scripts/1785.cs2 @@ -0,0 +1,16 @@ +cs2func_script_1785_struct(2,0,0) script_1785(int arg0,int arg1,int arg2,int arg3,string arg4) { + createExtraChild(new WidgetPointer(792,3), 4, arg1); + setWidgetPosition(0, arg0, 0, 0); + setWidgetFont(495); + setWidgetUnknownBoolean(true); + setWidgetSize(arg2, add(multiply(getLineCount(arg2, 495, arg4), 12), 5), 0, 0); + setWidgetText(arg4); + if (((boolean)arg3)) { + setWidgetTextAlignment(1, 0, 0); + setWidgetRGB(new Color(255, 152, 31)); + return newstruct cs2func_script_1785_struct(add(add(arg0, getWidgetActualHeight()), 12), add(arg1, 1)); + } + setWidgetTextAlignment(0, 0, 0); + setWidgetRGB(new Color(200, 170, 100)); + return newstruct cs2func_script_1785_struct(add(add(arg0, getWidgetActualHeight()), 5), add(arg1, 1)); +} diff --git a/dumps/scripts/1786.cs2 b/dumps/scripts/1786.cs2 new file mode 100644 index 0000000..e6180ae --- /dev/null +++ b/dumps/scripts/1786.cs2 @@ -0,0 +1,5 @@ +void script_1786(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12,int arg13,int arg14,int arg15,int arg16) { + setScriptCallOnConfigChange(1787, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), new WidgetPointer(arg6), new WidgetPointer(arg7), new WidgetPointer(arg8), new WidgetPointer(arg9), new WidgetPointer(arg10), new WidgetPointer(arg11), new WidgetPointer(arg12), new WidgetPointer(arg13), new WidgetPointer(arg14), new WidgetPointer(arg15), new WidgetPointer(arg16), 1305, 1, "IIIIIIIIIIIIIIIIIY", new WidgetPointer(arg0)); + setScriptCallOnGlobalConfigChange(1787, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), new WidgetPointer(arg6), new WidgetPointer(arg7), new WidgetPointer(arg8), new WidgetPointer(arg9), new WidgetPointer(arg10), new WidgetPointer(arg11), new WidgetPointer(arg12), new WidgetPointer(arg13), new WidgetPointer(arg14), new WidgetPointer(arg15), new WidgetPointer(arg16), 270, 260, 261, 262, 263, 264, 271, 7, "IIIIIIIIIIIIIIIIIY", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1787.cs2 b/dumps/scripts/1787.cs2 new file mode 100644 index 0000000..72b9a5d --- /dev/null +++ b/dumps/scripts/1787.cs2 @@ -0,0 +1,128 @@ +void script_1787(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12,int arg13,int arg14,int arg15,int arg16) { + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + int ivar22; + int ivar23; + int ivar24; + string svar0; + svar0 = ""; + ivar17 = 0; + ivar18 = 0; + ivar19 = 0; + if (((boolean)globalint_271)) { + setWidgetText(new WidgetPointer(arg3), cs2method3611() + ":"); + } else { + setWidgetText(new WidgetPointer(arg3), "This clan:"); + } + setWidgetText(new WidgetPointer(arg5), intToStr(globalint_261)); + setWidgetText(new WidgetPointer(arg11), intToStr(globalint_262)); + if (bitconfig_5280 > 0) { + if (globalint_263 < 65535) { + setWidgetText(new WidgetPointer(arg7), script_46(globalint_263, ",")); + } else { + setWidgetText(new WidgetPointer(arg7), "" + "You rock!" + ""); + } + if (globalint_264 < 65535) { + setWidgetText(new WidgetPointer(arg13), script_46(globalint_264, ",")); + } else { + setWidgetText(new WidgetPointer(arg13), "" + "They rock!" + ""); + } + setWidgetIsHidden(false, new WidgetPointer(arg6)); + setWidgetIsHidden(false, new WidgetPointer(arg12)); + setWidgetIsHidden(false, new WidgetPointer(arg7)); + setWidgetIsHidden(false, new WidgetPointer(arg13)); + ivar17 = 1; + if (bitconfig_5280 < 15) { + svar0 = "/ " + script_46(cs2method_3408(105, 105, 1605, bitconfig_5280), ","); + setWidgetText(new WidgetPointer(arg8), svar0); + setWidgetText(new WidgetPointer(arg14), svar0); + setWidgetIsHidden(false, new WidgetPointer(arg8)); + setWidgetIsHidden(false, new WidgetPointer(arg14)); + ivar18 = 1; + } else { + setWidgetIsHidden(true, new WidgetPointer(arg8)); + setWidgetIsHidden(true, new WidgetPointer(arg14)); + } + } else { + setWidgetIsHidden(true, new WidgetPointer(arg6)); + setWidgetIsHidden(true, new WidgetPointer(arg12)); + setWidgetIsHidden(true, new WidgetPointer(arg7)); + setWidgetIsHidden(true, new WidgetPointer(arg13)); + setWidgetIsHidden(true, new WidgetPointer(arg8)); + setWidgetIsHidden(true, new WidgetPointer(arg14)); + } + if (((boolean)globalint_260)) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg16)); + if (bitconfig_5281 > 0) { + setWidgetText(new WidgetPointer(arg15), "Time remaining:"); + if (globalint_270 > 60) { + script_1791(arg16); + } else if (globalint_270 > 1) { + setWidgetText(new WidgetPointer(arg16), intToStr(globalint_270) + " minutes"); + } else if (((boolean)globalint_270)) { + setWidgetText(new WidgetPointer(arg16), "" + "1 minute" + ""); + } else { + setWidgetText(new WidgetPointer(arg16), "" + "Not much!" + ""); + } + setWidgetIsHidden(false, new WidgetPointer(arg15)); + setWidgetIsHidden(false, new WidgetPointer(arg16)); + ivar19 = 1; + } else { + setWidgetIsHidden(true, new WidgetPointer(arg15)); + setWidgetIsHidden(true, new WidgetPointer(arg16)); + } + } else { + setWidgetText(new WidgetPointer(arg15), "Countdown to battle:"); + if (globalint_265 != globalint_270) { + globalint_265 = globalint_270; + script_1790(arg16); + setScriptCallOnGameloop(1789, new WidgetPointer(arg16), getClientCycle(), globalint_270, "Iii", new WidgetPointer(arg16)); + } + setWidgetIsHidden(false, new WidgetPointer(arg15)); + setWidgetIsHidden(false, new WidgetPointer(arg16)); + ivar19 = 1; + } + ivar20 = getMaxLineWidth(512, 494, getWidgetText(new WidgetPointer(arg3))); + ivar21 = getMaxLineWidth(512, 494, getWidgetText(new WidgetPointer(arg9))); + ivar20 = max(add(add(getMaxLineWidth(512, 494, getWidgetText(new WidgetPointer(arg4))), 10), getMaxLineWidth(512, 494, getWidgetText(new WidgetPointer(arg5)))), ivar20); + ivar21 = max(add(add(getMaxLineWidth(512, 494, getWidgetText(new WidgetPointer(arg10))), 10), getMaxLineWidth(512, 494, getWidgetText(new WidgetPointer(arg11)))), ivar21); + ivar22 = add(getWidgetActualHeight(new WidgetPointer(arg3)), getWidgetActualHeight(new WidgetPointer(arg4))); + if (((boolean)ivar17)) { + ivar20 = max(add(add(getMaxLineWidth(512, 494, getWidgetText(new WidgetPointer(arg6))), 10), getMaxLineWidth(512, 494, getWidgetText(new WidgetPointer(arg7)))), ivar20); + ivar21 = max(add(add(getMaxLineWidth(512, 494, getWidgetText(new WidgetPointer(arg12))), 10), getMaxLineWidth(512, 494, getWidgetText(new WidgetPointer(arg13)))), ivar21); + ivar22 = add(ivar22, getWidgetActualHeight(new WidgetPointer(arg6))); + if (((boolean)ivar18)) { + ivar20 = max(getMaxLineWidth(512, 494, getWidgetText(new WidgetPointer(arg8))), ivar20); + ivar21 = max(getMaxLineWidth(512, 494, getWidgetText(new WidgetPointer(arg14))), ivar21); + ivar22 = add(ivar22, getWidgetActualHeight(new WidgetPointer(arg8))); + } + } + ivar23 = add(add(ivar20, 10), ivar21); + if (((boolean)ivar19)) { + setWidgetSize(add(ivar23, 8), add(ivar22, 8), 0, 0, new WidgetPointer(arg0)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg0)), getWidgetActualHeight(new WidgetPointer(arg0)), 0, 0, new WidgetPointer(arg1)); + script_1788(ivar20, arg3, arg4, arg5, arg6, arg7, arg8, ivar21, arg9, arg10, arg11, arg12, arg13, arg14, ivar23); + setWidgetPosition(add(add(4, ivar20), 5), 4, 0, 0, new WidgetPointer(arg2)); + setWidgetSize(0, ivar22, 0, 0, new WidgetPointer(arg2)); + script_1086(arg0, 0, 0, 0); + return; + } + ivar24 = ivar22; + ivar22 = add(add(add(ivar22, 10), getWidgetActualHeight(new WidgetPointer(arg15))), getWidgetActualHeight(new WidgetPointer(arg16))); + ivar23 = max(getMaxLineWidth(512, 494, getWidgetText(new WidgetPointer(arg15))), ivar23); + ivar23 = max(getMaxLineWidth(512, 494, getWidgetText(new WidgetPointer(arg16))), ivar23); + setWidgetSize(add(ivar23, 8), add(ivar22, 8), 0, 0, new WidgetPointer(arg0)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg0)), getWidgetActualHeight(new WidgetPointer(arg0)), 0, 0, new WidgetPointer(arg1)); + script_1788(ivar20, arg3, arg4, arg5, arg6, arg7, arg8, ivar21, arg9, arg10, arg11, arg12, arg13, arg14, ivar23); + setWidgetPosition(add(add(4, ivar20), divide(subtract(ivar23, add(ivar20, ivar21)), 2)), 4, 0, 0, new WidgetPointer(arg2)); + setWidgetSize(0, ivar24, 0, 0, new WidgetPointer(arg2)); + setWidgetSize(ivar23, getWidgetActualHeight(new WidgetPointer(arg15)), 0, 0, new WidgetPointer(arg15)); + setWidgetSize(ivar23, getWidgetActualHeight(new WidgetPointer(arg16)), 0, 0, new WidgetPointer(arg16)); + setWidgetPosition(4, add(add(4, ivar24), 10), 0, 0, new WidgetPointer(arg15)); + setWidgetPosition(4, add(add(add(4, ivar24), 10), getWidgetActualHeight(new WidgetPointer(arg15))), 0, 0, new WidgetPointer(arg16)); + script_1086(arg0, add(add(4, ivar24), 5), 0, 0); + return; +} diff --git a/dumps/scripts/1788.cs2 b/dumps/scripts/1788.cs2 new file mode 100644 index 0000000..b05385e --- /dev/null +++ b/dumps/scripts/1788.cs2 @@ -0,0 +1,23 @@ +void script_1788(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12,int arg13,int arg14) { + int ivar15; + setWidgetSize(arg0, getWidgetActualHeight(new WidgetPointer(arg1)), 0, 0, new WidgetPointer(arg1)); + setWidgetSize(arg0, getWidgetActualHeight(new WidgetPointer(arg2)), 0, 0, new WidgetPointer(arg2)); + setWidgetSize(arg0, getWidgetActualHeight(new WidgetPointer(arg3)), 0, 0, new WidgetPointer(arg3)); + setWidgetSize(arg0, getWidgetActualHeight(new WidgetPointer(arg4)), 0, 0, new WidgetPointer(arg4)); + setWidgetSize(arg0, getWidgetActualHeight(new WidgetPointer(arg5)), 0, 0, new WidgetPointer(arg5)); + setWidgetSize(arg0, getWidgetActualHeight(new WidgetPointer(arg6)), 0, 0, new WidgetPointer(arg6)); + setWidgetSize(arg7, getWidgetActualHeight(new WidgetPointer(arg8)), 0, 0, new WidgetPointer(arg8)); + setWidgetSize(arg7, getWidgetActualHeight(new WidgetPointer(arg9)), 0, 0, new WidgetPointer(arg9)); + setWidgetSize(arg7, getWidgetActualHeight(new WidgetPointer(arg10)), 0, 0, new WidgetPointer(arg10)); + setWidgetSize(arg7, getWidgetActualHeight(new WidgetPointer(arg11)), 0, 0, new WidgetPointer(arg11)); + setWidgetSize(arg7, getWidgetActualHeight(new WidgetPointer(arg12)), 0, 0, new WidgetPointer(arg12)); + setWidgetSize(arg7, getWidgetActualHeight(new WidgetPointer(arg13)), 0, 0, new WidgetPointer(arg13)); + ivar15 = subtract(add(4, arg14), arg7); + setWidgetPosition(ivar15, getWidgetActualY(new WidgetPointer(arg8)), 0, 0, new WidgetPointer(arg8)); + setWidgetPosition(ivar15, getWidgetActualY(new WidgetPointer(arg9)), 0, 0, new WidgetPointer(arg9)); + setWidgetPosition(ivar15, getWidgetActualY(new WidgetPointer(arg10)), 0, 0, new WidgetPointer(arg10)); + setWidgetPosition(ivar15, getWidgetActualY(new WidgetPointer(arg11)), 0, 0, new WidgetPointer(arg11)); + setWidgetPosition(ivar15, getWidgetActualY(new WidgetPointer(arg12)), 0, 0, new WidgetPointer(arg12)); + setWidgetPosition(ivar15, getWidgetActualY(new WidgetPointer(arg13)), 0, 0, new WidgetPointer(arg13)); + return; +} diff --git a/dumps/scripts/1789.cs2 b/dumps/scripts/1789.cs2 new file mode 100644 index 0000000..c24ce2c --- /dev/null +++ b/dumps/scripts/1789.cs2 @@ -0,0 +1,7 @@ +void script_1789(int arg0,int arg1,int arg2) { + int ivar3; + ivar3 = subtract(getClientCycle(), arg1); + globalint_265 = max(subtract(arg2, divide(ivar3, 30)), 0); + script_1790(arg0); + return; +} diff --git a/dumps/scripts/179.cs2 b/dumps/scripts/179.cs2 new file mode 100644 index 0000000..cf40965 --- /dev/null +++ b/dumps/scripts/179.cs2 @@ -0,0 +1,19 @@ +int script_179(int arg0) { + switch (arg0) { + case 1: + return globalint_44; + case 2: + return globalint_45; + case 3: + return globalint_46; + case 4: + return globalint_47; + case 5: + return globalint_48; + case 6: + return globalint_49; + case 7: + return globalint_1511; + } + return 0; +} diff --git a/dumps/scripts/1790.cs2 b/dumps/scripts/1790.cs2 new file mode 100644 index 0000000..ee3d8db --- /dev/null +++ b/dumps/scripts/1790.cs2 @@ -0,0 +1,17 @@ +void script_1790(int arg0) { + int ivar1; + int ivar2; + ivar1 = multiplyDivide(3, 5, globalint_265); + if (ivar1 <= 3) { + setWidgetText(new WidgetPointer(arg0), "" + "GET READY!" + ""); + return; + } + ivar2 = divide(ivar1, 60); + ivar1 = mod(ivar1, 60); + if (ivar1 >= 10) { + setWidgetText(new WidgetPointer(arg0), intToStr(ivar2) + "m " + intToStr(ivar1) + "s"); + } else { + setWidgetText(new WidgetPointer(arg0), intToStr(ivar2) + "m 0" + intToStr(ivar1) + "s"); + } + return; +} diff --git a/dumps/scripts/1791.cs2 b/dumps/scripts/1791.cs2 new file mode 100644 index 0000000..9569746 --- /dev/null +++ b/dumps/scripts/1791.cs2 @@ -0,0 +1,12 @@ +void script_1791(int arg0) { + int ivar1; + int ivar2; + ivar1 = divide(globalint_270, 60); + ivar2 = mod(globalint_270, 60); + if (ivar2 >= 10) { + setWidgetText(new WidgetPointer(arg0), intToStr(ivar1) + "h " + intToStr(ivar2) + "m"); + } else { + setWidgetText(new WidgetPointer(arg0), intToStr(ivar1) + "h 0" + intToStr(ivar2) + "m"); + } + return; +} diff --git a/dumps/scripts/1792.cs2 b/dumps/scripts/1792.cs2 new file mode 100644 index 0000000..a90fb61 --- /dev/null +++ b/dumps/scripts/1792.cs2 @@ -0,0 +1,38 @@ +void script_1792(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + int ivar6; + int ivar7; + int ivar8; + int ivar9; + if (((boolean)bitconfig_5283)) { + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(arg3)); + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(arg4)); + setWidgetSprite(444, new WidgetPointer(arg1)); + setWidgetText(new WidgetPointer(arg4), "ITEMS ARE" + "
" + "SAFE"); + } else { + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(arg3)); + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(arg4)); + setWidgetSprite(445, new WidgetPointer(arg1)); + setWidgetText(new WidgetPointer(arg4), "ITEMS ARE" + "
" + "DROPPED"); + } + cs2method2107(1, new WidgetPointer(arg1)); + ivar6 = getMaxLineWidth(512, 494, getWidgetText(new WidgetPointer(arg3))); + ivar6 = max(getMaxLineWidth(512, 494, getWidgetText(new WidgetPointer(arg4))), ivar6); + ivar6 = add(ivar6, 6); + ivar7 = 5; + setWidgetPosition(0, ivar7, 0, 0, new WidgetPointer(arg3)); + ivar8 = getLineCount(ivar6, 494, getWidgetText(new WidgetPointer(arg3))); + ivar8 = add(multiply(ivar8, 10), 3); + setWidgetSize(ivar6, ivar8, 0, 0, new WidgetPointer(arg3)); + ivar7 = subtract(add(ivar7, ivar8), 1); + setWidgetPosition(divide(subtract(ivar6, getWidgetActualWidth(new WidgetPointer(arg2))), 2), ivar7, 0, 0, new WidgetPointer(arg2)); + ivar7 = subtract(add(ivar7, getWidgetActualHeight(new WidgetPointer(arg2))), 1); + setWidgetPosition(0, ivar7, 0, 0, new WidgetPointer(arg4)); + ivar9 = getLineCount(ivar6, 494, getWidgetText(new WidgetPointer(arg4))); + ivar9 = add(multiply(ivar9, 10), 3); + setWidgetSize(ivar6, ivar8, 0, 0, new WidgetPointer(arg4)); + ivar7 = add(add(ivar7, ivar9), 3); + setWidgetSize(ivar6, ivar7, 0, 0, new WidgetPointer(arg0)); + setWidgetSize(ivar6, ivar7, 0, 0, new WidgetPointer(arg1)); + script_1086(arg0, 0, 0, 0); + return; +} diff --git a/dumps/scripts/1793.cs2 b/dumps/scripts/1793.cs2 new file mode 100644 index 0000000..fff4950 --- /dev/null +++ b/dumps/scripts/1793.cs2 @@ -0,0 +1,19 @@ +void script_1793(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + int ivar6; + script_1795(arg4, arg5); + if (((boolean)bitconfig_5279)) { + setWidgetText(new WidgetPointer(arg0), "Free-for-all: Dangerous"); + setWidgetText(new WidgetPointer(arg1), "This is a " + "" + "DANGEROUS" + "" + " arena. When players fight each other in here, they drop " + "" + "ALL" + "" + " their items on death. Gravestones do not appear." + "
" + "
" + "A non-combat zone exists at the southern end of the arena. This portal leads into that zone." + "
" + "
" + "You cannot teleport out of this arena unless you're standing in the non-combat zone."); + setScriptCallOnConfigChange(1794, new WidgetPointer(arg4), new WidgetPointer(arg5), 1147, 1046, 2, "IIY", new WidgetPointer(arg4)); + } else { + setWidgetText(new WidgetPointer(arg0), "Free-for-all: Safe"); + setWidgetText(new WidgetPointer(arg1), "This is a SAFE arena. Although players may fight each other in here, items are not dropped on death." + "
" + "
" + "You can teleport out of the arena at any time." + "
" + "
" + "A non-combat zone exists at the southern end of the arena. This portal leads into that zone."); + setScriptCallOnConfigChange(1794, new WidgetPointer(arg4), new WidgetPointer(arg5), 1147, 1045, 2, "IIY", new WidgetPointer(arg4)); + } + ivar6 = getMaxLineWidth(getWidgetActualWidth(new WidgetPointer(arg0)), 496, getWidgetText(new WidgetPointer(arg0))); + ivar6 = divide(subtract(getWidgetActualWidth(new WidgetPointer(arg0)), ivar6), 2); + ivar6 = subtract(ivar6, add(getWidgetActualWidth(new WidgetPointer(arg2)), 10)); + setWidgetPosition(ivar6, getWidgetActualY(new WidgetPointer(arg2)), 0, 0, new WidgetPointer(arg2)); + setWidgetPosition(ivar6, getWidgetActualY(new WidgetPointer(arg3)), 2, 0, new WidgetPointer(arg3)); + return; +} diff --git a/dumps/scripts/1794.cs2 b/dumps/scripts/1794.cs2 new file mode 100644 index 0000000..8b90d20 --- /dev/null +++ b/dumps/scripts/1794.cs2 @@ -0,0 +1,4 @@ +void script_1794(int arg0,int arg1) { + script_1795(arg0, arg1); + return; +} diff --git a/dumps/scripts/1795.cs2 b/dumps/scripts/1795.cs2 new file mode 100644 index 0000000..de5c037 --- /dev/null +++ b/dumps/scripts/1795.cs2 @@ -0,0 +1,22 @@ +void script_1795(int arg0,int arg1) { + int ivar2; + int ivar3; + ivar2 = 697; + ivar3 = 699; + if (((boolean)bitconfig_5279)) { + if (((boolean)bitconfig_5295)) { + setWidgetSprite(ivar3, new WidgetPointer(arg1)); + setScriptCallOnClickContextMenu(44, new WidgetPointer(arg1), ivar2, "Id", new WidgetPointer(arg0)); + } else { + setWidgetSprite(ivar2, new WidgetPointer(arg1)); + setScriptCallOnClickContextMenu(44, new WidgetPointer(arg1), ivar3, "Id", new WidgetPointer(arg0)); + } + } else if (((boolean)bitconfig_5294)) { + setWidgetSprite(ivar3, new WidgetPointer(arg1)); + setScriptCallOnClickContextMenu(44, new WidgetPointer(arg1), ivar2, "Id", new WidgetPointer(arg0)); + } else { + setWidgetSprite(ivar2, new WidgetPointer(arg1)); + setScriptCallOnClickContextMenu(44, new WidgetPointer(arg1), ivar3, "Id", new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/1796.cs2 b/dumps/scripts/1796.cs2 new file mode 100644 index 0000000..1307556 --- /dev/null +++ b/dumps/scripts/1796.cs2 @@ -0,0 +1,27 @@ +void script_1796(int arg0) { + globalint_246 = 0; + globalint_247 = 0; + globalint_248 = 0; + globalint_249 = 0; + globalint_250 = 0; + globalint_251 = 0; + if (isMember()) { + globalint_252 = 1; + globalint_253 = 0; + script_1775(); + script_1778(); + } else { + globalint_252 = 0; + globalint_253 = 0; + } + globalint_254 = 0; + globalint_255 = 0; + globalint_256 = 0; + globalint_257 = 0; + globalint_258 = 0; + globalint_259 = 0; + setScriptCallOnConfigChange(1836, 1305, 1149, 2, "Y", new WidgetPointer(arg0)); + setScriptCallOnGlobalConfigChange(1837, 259, 1, "Y", new WidgetPointer(arg0)); + setScriptCallOnGlobalStringChange(1838, new WidgetPointer(arg0), 37, 1, "IY", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1797.cs2 b/dumps/scripts/1797.cs2 new file mode 100644 index 0000000..90f15ca --- /dev/null +++ b/dumps/scripts/1797.cs2 @@ -0,0 +1,65 @@ +void script_1797(int arg0,int arg1) { + int ivar2; + int ivar3; + ivar2 = 0; + ivar3 = 0; + while (ivar2 < 10) { + switch (ivar2) { + case 0: + setWidgetPosition(25, ivar3, 0, 0, new WidgetPointer(791,23)); + setWidgetPosition(4, ivar3, 0, 0, new WidgetPointer(791,24)); + setWidgetPosition(0, ivar3, 0, 0, new WidgetPointer(791,25)); + break; + case 1: + setWidgetPosition(25, ivar3, 0, 0, new WidgetPointer(791,26)); + setWidgetPosition(4, ivar3, 0, 0, new WidgetPointer(791,27)); + setWidgetPosition(0, ivar3, 0, 0, new WidgetPointer(791,28)); + break; + case 2: + setWidgetPosition(25, ivar3, 0, 0, new WidgetPointer(791,29)); + setWidgetPosition(4, ivar3, 0, 0, new WidgetPointer(791,30)); + setWidgetPosition(0, ivar3, 0, 0, new WidgetPointer(791,31)); + break; + case 3: + setWidgetPosition(25, ivar3, 0, 0, new WidgetPointer(791,32)); + setWidgetPosition(4, ivar3, 0, 0, new WidgetPointer(791,33)); + setWidgetPosition(0, ivar3, 0, 0, new WidgetPointer(791,34)); + break; + case 4: + setWidgetPosition(25, ivar3, 0, 0, new WidgetPointer(791,35)); + setWidgetPosition(4, ivar3, 0, 0, new WidgetPointer(791,36)); + setWidgetPosition(0, ivar3, 0, 0, new WidgetPointer(791,37)); + break; + case 5: + setWidgetPosition(25, ivar3, 0, 0, new WidgetPointer(791,38)); + setWidgetPosition(4, ivar3, 0, 0, new WidgetPointer(791,39)); + setWidgetPosition(0, ivar3, 0, 0, new WidgetPointer(791,40)); + break; + case 6: + setWidgetPosition(25, ivar3, 0, 0, new WidgetPointer(791,41)); + setWidgetPosition(4, ivar3, 0, 0, new WidgetPointer(791,42)); + setWidgetPosition(0, ivar3, 0, 0, new WidgetPointer(791,43)); + break; + case 7: + setWidgetPosition(25, ivar3, 0, 0, new WidgetPointer(791,44)); + setWidgetPosition(4, ivar3, 0, 0, new WidgetPointer(791,45)); + setWidgetPosition(0, ivar3, 0, 0, new WidgetPointer(791,46)); + break; + case 8: + setWidgetPosition(25, ivar3, 0, 0, new WidgetPointer(791,47)); + setWidgetPosition(4, ivar3, 0, 0, new WidgetPointer(791,48)); + setWidgetPosition(0, ivar3, 0, 0, new WidgetPointer(791,49)); + break; + case 9: + setWidgetPosition(25, ivar3, 0, 0, new WidgetPointer(791,50)); + setWidgetPosition(4, ivar3, 0, 0, new WidgetPointer(791,51)); + setWidgetPosition(0, ivar3, 0, 0, new WidgetPointer(791,52)); + } + ivar3 = add(ivar3, 17); + ivar2 = add(ivar2, 1); + } + setWidgetScrollMax(0, ivar3, new WidgetPointer(arg0)); + cs2method2100(0, 0, new WidgetPointer(arg0)); + script_31(arg1, arg0, 792, 789, 790, 791, 773, 788); + return; +} diff --git a/dumps/scripts/1798.cs2 b/dumps/scripts/1798.cs2 new file mode 100644 index 0000000..e2508af --- /dev/null +++ b/dumps/scripts/1798.cs2 @@ -0,0 +1,75 @@ +void script_1798(int arg0,int arg1) { + int ivar2; + int ivar3; + ivar2 = 0; + ivar3 = 0; + while (ivar2 < 12) { + switch (ivar2) { + case 0: + setWidgetPosition(25, ivar3, 0, 0, new WidgetPointer(791,58)); + setWidgetPosition(4, ivar3, 0, 0, new WidgetPointer(791,59)); + setWidgetPosition(0, ivar3, 0, 0, new WidgetPointer(791,60)); + break; + case 1: + setWidgetPosition(25, ivar3, 0, 0, new WidgetPointer(791,61)); + setWidgetPosition(4, ivar3, 0, 0, new WidgetPointer(791,62)); + setWidgetPosition(0, ivar3, 0, 0, new WidgetPointer(791,63)); + break; + case 2: + setWidgetPosition(25, ivar3, 0, 0, new WidgetPointer(791,64)); + setWidgetPosition(4, ivar3, 0, 0, new WidgetPointer(791,65)); + setWidgetPosition(0, ivar3, 0, 0, new WidgetPointer(791,66)); + break; + case 3: + setWidgetPosition(25, ivar3, 0, 0, new WidgetPointer(791,67)); + setWidgetPosition(4, ivar3, 0, 0, new WidgetPointer(791,68)); + setWidgetPosition(0, ivar3, 0, 0, new WidgetPointer(791,69)); + break; + case 4: + setWidgetPosition(25, ivar3, 0, 0, new WidgetPointer(791,70)); + setWidgetPosition(4, ivar3, 0, 0, new WidgetPointer(791,71)); + setWidgetPosition(0, ivar3, 0, 0, new WidgetPointer(791,72)); + break; + case 5: + setWidgetPosition(25, ivar3, 0, 0, new WidgetPointer(791,73)); + setWidgetPosition(4, ivar3, 0, 0, new WidgetPointer(791,74)); + setWidgetPosition(0, ivar3, 0, 0, new WidgetPointer(791,75)); + break; + case 6: + setWidgetPosition(25, ivar3, 0, 0, new WidgetPointer(791,76)); + setWidgetPosition(4, ivar3, 0, 0, new WidgetPointer(791,77)); + setWidgetPosition(0, ivar3, 0, 0, new WidgetPointer(791,78)); + break; + case 7: + setWidgetPosition(25, ivar3, 0, 0, new WidgetPointer(791,79)); + setWidgetPosition(4, ivar3, 0, 0, new WidgetPointer(791,80)); + setWidgetPosition(0, ivar3, 0, 0, new WidgetPointer(791,81)); + break; + case 8: + setWidgetPosition(25, ivar3, 0, 0, new WidgetPointer(791,82)); + setWidgetPosition(4, ivar3, 0, 0, new WidgetPointer(791,83)); + setWidgetPosition(0, ivar3, 0, 0, new WidgetPointer(791,84)); + break; + case 9: + setWidgetPosition(25, ivar3, 0, 0, new WidgetPointer(791,85)); + setWidgetPosition(4, ivar3, 0, 0, new WidgetPointer(791,86)); + setWidgetPosition(0, ivar3, 0, 0, new WidgetPointer(791,87)); + break; + case 10: + setWidgetPosition(25, ivar3, 0, 0, new WidgetPointer(791,88)); + setWidgetPosition(4, ivar3, 0, 0, new WidgetPointer(791,89)); + setWidgetPosition(0, ivar3, 0, 0, new WidgetPointer(791,90)); + break; + case 11: + setWidgetPosition(25, ivar3, 0, 0, new WidgetPointer(791,91)); + setWidgetPosition(4, ivar3, 0, 0, new WidgetPointer(791,92)); + setWidgetPosition(0, ivar3, 0, 0, new WidgetPointer(791,93)); + } + ivar3 = add(ivar3, 17); + ivar2 = add(ivar2, 1); + } + setWidgetScrollMax(0, ivar3, new WidgetPointer(arg0)); + cs2method2100(0, 0, new WidgetPointer(arg0)); + script_31(arg1, arg0, 792, 789, 790, 791, 773, 788); + return; +} diff --git a/dumps/scripts/1799.cs2 b/dumps/scripts/1799.cs2 new file mode 100644 index 0000000..cdebc34 --- /dev/null +++ b/dumps/scripts/1799.cs2 @@ -0,0 +1,52 @@ +void script_1799(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + ivar2 = 0; + ivar3 = 0; + ivar4 = -1; + while (ivar2 <= 4) { + ivar4 = cs2method_3408(105, 74, 1604, ivar2); + createExtraChild(new WidgetPointer(arg0), 5, multiply(ivar2, 4)); + setWidgetPosition(4, ivar3, 0, 0); + setWidgetSize(17, 17, 0, 0); + if (isMember() && ((boolean)getOtherCommonData(ivar4, 557))) { + setWidgetSprite(698); + } else if (((boolean)ivar2)) { + setWidgetSprite(699); + } else { + setWidgetSprite(697); + } + createExtraChild(new WidgetPointer(arg0), 4, add(multiply(ivar2, 4), 1)); + setWidgetPosition(25, ivar3, 0, 0); + setWidgetSize(25, 17, 1, 0); + setWidgetText(getOtherCommonData(ivar4, 555)); + setWidgetFont(495); + setWidgetTextAlignment(0, 0, 0); + setWidgetRGB(new Color(200, 170, 100)); + setWidgetUnknownBoolean(true); + createExtraChild(new WidgetPointer(arg0), 4, add(multiply(ivar2, 4), 2)); + setWidgetPosition(4, add(ivar3, 17), 0, 0); + setWidgetSize(8, add(multiply(getLineCount(subtract(getWidgetActualWidth(new WidgetPointer(arg0)), 8), 494, getOtherCommonData(ivar4, 556)), 10), 3), 1, 0); + setWidgetText(getOtherCommonData(ivar4, 556)); + setWidgetFont(494); + setWidgetTextAlignment(0, 0, 0); + setWidgetRGB(new Color(200, 170, 100)); + setWidgetUnknownBoolean(true); + createExtraChild(new WidgetPointer(arg0), 3, add(multiply(ivar2, 4), 3)); + setWidgetPosition(4, ivar3, 0, 0); + setWidgetSize(8, add(17, getWidgetActualHeight()), 1, 0); + cs2method2103(255); + setWidgetContextMenuOption(1, getOtherCommonData(ivar4, 555)); + setScriptCallOnClickContextMenu(1833, -2147483644, ivar2, "ii"); + ivar3 = add(ivar3, getWidgetActualHeight()); + if (ivar2 < 4) { + ivar3 = add(ivar3, 3); + } + ivar2 = add(ivar2, 1); + } + setWidgetScrollMax(0, ivar3, new WidgetPointer(arg0)); + cs2method2100(0, 0, new WidgetPointer(arg0)); + script_31(arg1, arg0, 792, 789, 790, 791, 773, 788); + return; +} diff --git a/dumps/scripts/18.cs2 b/dumps/scripts/18.cs2 new file mode 100644 index 0000000..bd5aad2 --- /dev/null +++ b/dumps/scripts/18.cs2 @@ -0,0 +1,4 @@ +void script_18(int arg0) { + setWidgetBorderThickness(0, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/180.cs2 b/dumps/scripts/180.cs2 new file mode 100644 index 0000000..cd2c488 --- /dev/null +++ b/dumps/scripts/180.cs2 @@ -0,0 +1,14 @@ +void script_180(int arg0) { + if (arg0 == globalint_41) { + return; + } + if (((arg0 == 3) && (standart_config_287 > 0)) && (globalint_41 != -1)) { + return; + } + if (script_179(arg0) > 24) { + return; + } + script_183(arg0, 249); + setScriptCallOnGameloop(182, arg0, "i", cs2method_3408(105, 73, 683, arg0)); + return; +} diff --git a/dumps/scripts/1800.cs2 b/dumps/scripts/1800.cs2 new file mode 100644 index 0000000..329f5ff --- /dev/null +++ b/dumps/scripts/1800.cs2 @@ -0,0 +1,9 @@ +void script_1800(int arg0) { + script_915(arg0); + if (standart_config_1149 != -1) { + script_1801(); + } else { + script_1802(); + } + return; +} diff --git a/dumps/scripts/1801.cs2 b/dumps/scripts/1801.cs2 new file mode 100644 index 0000000..6577dbc --- /dev/null +++ b/dumps/scripts/1801.cs2 @@ -0,0 +1,9 @@ +void script_1801() { + setWidgetIsHidden(false, new WidgetPointer(791,143)); + setWidgetIsHidden(false, new WidgetPointer(791,146)); + setWidgetIsHidden(true, new WidgetPointer(791,144)); + setWidgetIsHidden(true, new WidgetPointer(791,147)); + setWidgetIsHidden(true, new WidgetPointer(791,145)); + setWidgetIsHidden(true, new WidgetPointer(791,148)); + return; +} diff --git a/dumps/scripts/1802.cs2 b/dumps/scripts/1802.cs2 new file mode 100644 index 0000000..cd73e52 --- /dev/null +++ b/dumps/scripts/1802.cs2 @@ -0,0 +1,9 @@ +void script_1802() { + setWidgetIsHidden(true, new WidgetPointer(791,143)); + setWidgetIsHidden(true, new WidgetPointer(791,146)); + setWidgetIsHidden(false, new WidgetPointer(791,144)); + setWidgetIsHidden(false, new WidgetPointer(791,147)); + setWidgetIsHidden(false, new WidgetPointer(791,145)); + setWidgetIsHidden(false, new WidgetPointer(791,148)); + return; +} diff --git a/dumps/scripts/1803.cs2 b/dumps/scripts/1803.cs2 new file mode 100644 index 0000000..4969a51 --- /dev/null +++ b/dumps/scripts/1803.cs2 @@ -0,0 +1,5 @@ +void script_1803(int arg0,int arg1) { + cs2method2100(0, 0, new WidgetPointer(arg0)); + script_1784(); + return; +} diff --git a/dumps/scripts/1804.cs2 b/dumps/scripts/1804.cs2 new file mode 100644 index 0000000..dd4ba6f --- /dev/null +++ b/dumps/scripts/1804.cs2 @@ -0,0 +1,8 @@ +void script_1804(int arg0,int arg1,int arg2) { + if (isMember()) { + script_1163(arg0, arg1, arg2, 25, 250, "You may choose:" + "
" + "- Allow all spells" + "
" + "- Standard spellbook only" + "
" + "- Bind/Snare/Entangle only" + "
" + "- No Magic"); + } else { + script_1163(arg0, arg1, arg2, 25, 250, "You may choose:" + "
" + "- Standard spellbook" + "
" + "- Bind only" + "
" + "- No Magic"); + } + return; +} diff --git a/dumps/scripts/1805.cs2 b/dumps/scripts/1805.cs2 new file mode 100644 index 0000000..67e73d2 --- /dev/null +++ b/dumps/scripts/1805.cs2 @@ -0,0 +1,4 @@ +void script_1805() { + script_1806(globalstring_22); + return; +} diff --git a/dumps/scripts/1806.cs2 b/dumps/scripts/1806.cs2 new file mode 100644 index 0000000..022f131 --- /dev/null +++ b/dumps/scripts/1806.cs2 @@ -0,0 +1,30 @@ +void script_1806(string arg0) { + int ivar0; + script_1548(12); + arg0 = lower(strRemoveEntities(arg0)); + ivar0 = strLength(arg0); + arg0 = script_2332(arg0, "_", "\u00a0"); + arg0 = script_2332(arg0, " ", "\u00a0"); + while (((boolean)strIndexof(0, arg0, " ")) && (ivar0 > 0)) { + arg0 = substr(1, ivar0, arg0); + ivar0 = strLength(arg0); + } + while ((strIndexof(subtract(ivar0, 1), arg0, " ") == subtract(ivar0, 1)) && (ivar0 > 0)) { + arg0 = substr(0, subtract(ivar0, 1), arg0); + ivar0 = strLength(arg0); + } + if (((boolean)stringMethod4107(globalstring_38, arg0))) { + messageType0("Caller not changed."); + return; + } + globalstring_38 = arg0; + if (strLength(globalstring_38) > 0) { + messageType0("Caller set: " + script_1814(globalstring_38)); + } else { + messageType0("Caller feature disabled."); + } + script_1809(17367062, 17367064, 17367065); + script_1809(51707918, 51707920, 51707921); + script_1809(72876037, 72876039, 72876040); + return; +} diff --git a/dumps/scripts/1807.cs2 b/dumps/scripts/1807.cs2 new file mode 100644 index 0000000..058b2e3 --- /dev/null +++ b/dumps/scripts/1807.cs2 @@ -0,0 +1,11 @@ +void script_1807(int arg0,int arg1,int arg2) { + if (((boolean)script_42(globalint_266))) { + globalstring_38 = ""; + globalstring_39 = ""; + globalint_266 = 1; + } + script_1809(arg0, arg1, arg2); + setScriptCallOnGlobalStringChange(1808, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), 38, 1, "IIIY", new WidgetPointer(arg0)); + setScriptCallOnMessage(1810, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), "III", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1808.cs2 b/dumps/scripts/1808.cs2 new file mode 100644 index 0000000..b4b0679 --- /dev/null +++ b/dumps/scripts/1808.cs2 @@ -0,0 +1,5 @@ +void script_1808(int arg0,int arg1,int arg2) { + script_1548(12); + script_1809(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/1809.cs2 b/dumps/scripts/1809.cs2 new file mode 100644 index 0000000..c54fe7e --- /dev/null +++ b/dumps/scripts/1809.cs2 @@ -0,0 +1,16 @@ +void script_1809(int arg0,int arg1,int arg2) { + string svar0; + svar0 = ""; + if (strLength(globalstring_38) > 0) { + svar0 = script_1814(globalstring_38); + setWidgetText(new WidgetPointer(arg1), svar0); + setWidgetSize(getMaxLineWidth(512, 496, svar0), 15, 0, 0, new WidgetPointer(arg1)); + } else { + setWidgetText(new WidgetPointer(arg1), ""); + setWidgetSize(0, 15, 0, 0, new WidgetPointer(arg1)); + } + globalint_267 = -1; + globalstring_39 = ""; + script_1811(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/181.cs2 b/dumps/scripts/181.cs2 new file mode 100644 index 0000000..77ca298 --- /dev/null +++ b/dumps/scripts/181.cs2 @@ -0,0 +1,13 @@ +void script_181(int arg0) { + script_183(arg0, 0); + if (((boolean)arg0)) { + script_183(1, 0); + script_183(2, 0); + script_183(3, 0); + script_183(4, 0); + script_183(5, 0); + script_183(6, 0); + script_183(7, 0); + } + return; +} diff --git a/dumps/scripts/1810.cs2 b/dumps/scripts/1810.cs2 new file mode 100644 index 0000000..43553f3 --- /dev/null +++ b/dumps/scripts/1810.cs2 @@ -0,0 +1,4 @@ +void script_1810(int arg0,int arg1,int arg2) { + script_1811(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/1811.cs2 b/dumps/scripts/1811.cs2 new file mode 100644 index 0000000..2542d16 --- /dev/null +++ b/dumps/scripts/1811.cs2 @@ -0,0 +1,46 @@ +void script_1811(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + string svar0; + if (((boolean)strLength(globalstring_38))) { + script_1812(arg2, ""); + return; + } + ivar3 = subtract(min(cs2method5017(), 100), 1); + svar0 = ""; + ivar4 = -1; + while (ivar3 >= 0) { + switch (cs2method5004(ivar3)) { + case 1: + case 2: + case 3: + case 7: + case 42: + case 9: + case 11: + case 41: + case 44: + case 45: + case 17: + case 18: + case 20: + case 25: + case 24: + if (((boolean)stringMethod4107(lower(strRemoveEntities(cs2method5010(ivar3))), globalstring_38))) { + svar0 = cs2method5003(ivar3); + ivar4 = ivar3; + } + } + ivar3 = subtract(ivar3, 1); + } + if (ivar4 < 0) { + globalint_267 = -1; + script_1812(arg2, ""); + return; + } + if (((globalint_267 == -1) || (ivar4 <= globalint_267)) || (stringMethod4107(svar0, globalstring_39) != 0)) { + script_1812(arg2, svar0); + } + globalint_267 = ivar4; + return; +} diff --git a/dumps/scripts/1812.cs2 b/dumps/scripts/1812.cs2 new file mode 100644 index 0000000..0072399 --- /dev/null +++ b/dumps/scripts/1812.cs2 @@ -0,0 +1,12 @@ +void script_1812(int arg0,string arg1) { + if (((boolean)strLength(arg1))) { + setWidgetText(new WidgetPointer(arg0), ""); + globalstring_39 = ""; + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + return; + } + setWidgetText(new WidgetPointer(arg0), arg1); + globalstring_39 = arg1; + setScriptCallOnGameloop(1813, add(getClientCycle(), 1000), new WidgetPointer(arg0), "iI", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1813.cs2 b/dumps/scripts/1813.cs2 new file mode 100644 index 0000000..3241d8d --- /dev/null +++ b/dumps/scripts/1813.cs2 @@ -0,0 +1,7 @@ +void script_1813(int arg0,int arg1) { + if (getClientCycle() >= arg0) { + setWidgetText(new WidgetPointer(arg1), ""); + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg1)); + } + return; +} diff --git a/dumps/scripts/1814.cs2 b/dumps/scripts/1814.cs2 new file mode 100644 index 0000000..f9c09b5 --- /dev/null +++ b/dumps/scripts/1814.cs2 @@ -0,0 +1,36 @@ +string script_1814(string arg0) { + int ivar0; + string svar1; + ivar0 = strLength(arg0); + if (ivar0 <= 0) { + return arg0; + } + svar1 = concat("\u00a0", arg0); + svar1 = script_2332(svar1, "\u00a0a", "\u00a0A"); + svar1 = script_2332(svar1, "\u00a0b", "\u00a0B"); + svar1 = script_2332(svar1, "\u00a0c", "\u00a0C"); + svar1 = script_2332(svar1, "\u00a0d", "\u00a0D"); + svar1 = script_2332(svar1, "\u00a0e", "\u00a0E"); + svar1 = script_2332(svar1, "\u00a0f", "\u00a0F"); + svar1 = script_2332(svar1, "\u00a0g", "\u00a0G"); + svar1 = script_2332(svar1, "\u00a0h", "\u00a0H"); + svar1 = script_2332(svar1, "\u00a0i", "\u00a0I"); + svar1 = script_2332(svar1, "\u00a0j", "\u00a0J"); + svar1 = script_2332(svar1, "\u00a0k", "\u00a0K"); + svar1 = script_2332(svar1, "\u00a0l", "\u00a0L"); + svar1 = script_2332(svar1, "\u00a0m", "\u00a0M"); + svar1 = script_2332(svar1, "\u00a0n", "\u00a0N"); + svar1 = script_2332(svar1, "\u00a0o", "\u00a0O"); + svar1 = script_2332(svar1, "\u00a0p", "\u00a0P"); + svar1 = script_2332(svar1, "\u00a0q", "\u00a0Q"); + svar1 = script_2332(svar1, "\u00a0r", "\u00a0R"); + svar1 = script_2332(svar1, "\u00a0s", "\u00a0S"); + svar1 = script_2332(svar1, "\u00a0t", "\u00a0T"); + svar1 = script_2332(svar1, "\u00a0u", "\u00a0U"); + svar1 = script_2332(svar1, "\u00a0v", "\u00a0V"); + svar1 = script_2332(svar1, "\u00a0w", "\u00a0W"); + svar1 = script_2332(svar1, "\u00a0x", "\u00a0X"); + svar1 = script_2332(svar1, "\u00a0y", "\u00a0Y"); + svar1 = script_2332(svar1, "\u00a0z", "\u00a0Z"); + return substr(1, add(ivar0, 1), svar1); +} diff --git a/dumps/scripts/1815.cs2 b/dumps/scripts/1815.cs2 new file mode 100644 index 0000000..818f8a1 --- /dev/null +++ b/dumps/scripts/1815.cs2 @@ -0,0 +1,11 @@ +int script_1815() { + int ivar0; + int ivar1; + ivar0 = getWidgetActualX(); + ivar1 = getWidgetParentId(); + while (ivar1 != -1) { + ivar0 = subtract(add(ivar0, getWidgetActualX(new WidgetPointer(ivar1))), cs2method2600(new WidgetPointer(ivar1))); + ivar1 = getWidgetParentId(new WidgetPointer(ivar1)); + } + return ivar0; +} diff --git a/dumps/scripts/1816.cs2 b/dumps/scripts/1816.cs2 new file mode 100644 index 0000000..15e6270 --- /dev/null +++ b/dumps/scripts/1816.cs2 @@ -0,0 +1,56 @@ +void script_1816(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + switch (globalint_268) { + case 4: + script_1817(arg0, arg1, arg2, arg3, arg4, arg5); + setWidgetText(new WidgetPointer(arg2), "Your clan knocked the enemy right out of the arena."); + break; + case 5: + script_1817(arg0, arg1, arg2, arg3, arg4, arg5); + setWidgetText(new WidgetPointer(arg2), "Your clan reached the target kill-count."); + break; + case 6: + script_1817(arg0, arg1, arg2, arg3, arg4, arg5); + setWidgetText(new WidgetPointer(arg2), "Your clan had the highest kill-count when the time expired."); + break; + case 7: + script_1817(arg0, arg1, arg2, arg3, arg4, arg5); + setWidgetText(new WidgetPointer(arg2), "Your clan had the most survivors when the time expired."); + break; + case 8: + script_1818(arg0, arg1, arg2, arg3, arg4, arg5); + setWidgetText(new WidgetPointer(arg2), "Your clan was knocked right out of the arena."); + break; + case 9: + script_1818(arg0, arg1, arg2, arg3, arg4, arg5); + setWidgetText(new WidgetPointer(arg2), "Your enemy reached the target kill-count."); + break; + case 10: + script_1818(arg0, arg1, arg2, arg3, arg4, arg5); + setWidgetText(new WidgetPointer(arg2), "Your enemy had the highest kill-count when the time expired."); + break; + case 11: + script_1818(arg0, arg1, arg2, arg3, arg4, arg5); + setWidgetText(new WidgetPointer(arg2), "Your enemy had the most survivors when the time expired."); + break; + case 1: + script_1819(arg0, arg1, arg2, arg3, arg4, arg5); + setWidgetText(new WidgetPointer(arg2), "The match was aborted due to a lack of fighters."); + break; + case 2: + script_1819(arg0, arg1, arg2, arg3, arg4, arg5); + setWidgetText(new WidgetPointer(arg2), "Your kill-counts were equal."); + break; + case 3: + script_1819(arg0, arg1, arg2, arg3, arg4, arg5); + setWidgetText(new WidgetPointer(arg2), "You had equal numbers of survivors."); + break; + default: + setWidgetIsHidden(true, new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(arg1)); + setWidgetIsHidden(true, new WidgetPointer(arg2)); + setWidgetIsHidden(true, new WidgetPointer(arg3)); + setWidgetIsHidden(true, new WidgetPointer(arg4)); + setWidgetIsHidden(true, new WidgetPointer(arg5)); + } + return; +} diff --git a/dumps/scripts/1817.cs2 b/dumps/scripts/1817.cs2 new file mode 100644 index 0000000..89359a2 --- /dev/null +++ b/dumps/scripts/1817.cs2 @@ -0,0 +1,16 @@ +void script_1817(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + setWidgetText(new WidgetPointer(arg0), "Victory!"); + setWidgetPosition(75, 89, 0, 0, new WidgetPointer(arg0)); + setWidgetText(new WidgetPointer(arg1), "Your clan is victorious."); + setWidgetPosition(79, 130, 0, 0, new WidgetPointer(arg1)); + setWidgetPosition(79, 180, 0, 0, new WidgetPointer(arg2)); + setWidgetSize(175, 125, 0, 0, new WidgetPointer(arg2)); + setWidgetPosition(52, 118, 0, 0, new WidgetPointer(arg3)); + setWidgetIsHidden(false, new WidgetPointer(arg0)); + setWidgetIsHidden(false, new WidgetPointer(arg1)); + setWidgetIsHidden(false, new WidgetPointer(arg2)); + setWidgetIsHidden(false, new WidgetPointer(arg3)); + setWidgetIsHidden(false, new WidgetPointer(arg4)); + setWidgetIsHidden(true, new WidgetPointer(arg5)); + return; +} diff --git a/dumps/scripts/1818.cs2 b/dumps/scripts/1818.cs2 new file mode 100644 index 0000000..ad50949 --- /dev/null +++ b/dumps/scripts/1818.cs2 @@ -0,0 +1,16 @@ +void script_1818(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + setWidgetText(new WidgetPointer(arg0), "Defeat!"); + setWidgetPosition(64, 49, 0, 0, new WidgetPointer(arg0)); + setWidgetText(new WidgetPointer(arg1), "Your clan has been defeated."); + setWidgetPosition(41, 93, 0, 0, new WidgetPointer(arg1)); + setWidgetPosition(41, 179, 0, 0, new WidgetPointer(arg2)); + setWidgetSize(180, 125, 0, 0, new WidgetPointer(arg2)); + setWidgetPosition(38, 81, 0, 0, new WidgetPointer(arg3)); + setWidgetIsHidden(false, new WidgetPointer(arg0)); + setWidgetIsHidden(false, new WidgetPointer(arg1)); + setWidgetIsHidden(false, new WidgetPointer(arg2)); + setWidgetIsHidden(false, new WidgetPointer(arg3)); + setWidgetIsHidden(true, new WidgetPointer(arg4)); + setWidgetIsHidden(false, new WidgetPointer(arg5)); + return; +} diff --git a/dumps/scripts/1819.cs2 b/dumps/scripts/1819.cs2 new file mode 100644 index 0000000..bcae6ed --- /dev/null +++ b/dumps/scripts/1819.cs2 @@ -0,0 +1,16 @@ +void script_1819(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + setWidgetText(new WidgetPointer(arg0), "Draw!"); + setWidgetPosition(75, 89, 0, 0, new WidgetPointer(arg0)); + setWidgetText(new WidgetPointer(arg1), "It's a draw."); + setWidgetPosition(79, 130, 0, 0, new WidgetPointer(arg1)); + setWidgetPosition(79, 180, 0, 0, new WidgetPointer(arg2)); + setWidgetSize(175, 125, 0, 0, new WidgetPointer(arg2)); + setWidgetPosition(52, 118, 0, 0, new WidgetPointer(arg3)); + setWidgetIsHidden(false, new WidgetPointer(arg0)); + setWidgetIsHidden(false, new WidgetPointer(arg1)); + setWidgetIsHidden(false, new WidgetPointer(arg2)); + setWidgetIsHidden(false, new WidgetPointer(arg3)); + setWidgetIsHidden(false, new WidgetPointer(arg4)); + setWidgetIsHidden(true, new WidgetPointer(arg5)); + return; +} diff --git a/dumps/scripts/182.cs2 b/dumps/scripts/182.cs2 new file mode 100644 index 0000000..f9b422c --- /dev/null +++ b/dumps/scripts/182.cs2 @@ -0,0 +1,18 @@ +void script_182(int arg0) { + int ivar1; + int ivar2; + ivar1 = script_179(arg0); + ivar2 = 0; + if (((boolean)mod(ivar1, 25))) { + script_178(); + ivar2 = divide(ivar1, 25); + if (ivar2 <= 1) { + setScriptCallOnGameloop(-1, "", cs2method_3408(105, 73, 683, arg0)); + } else { + script_183(arg0, subtract(ivar1, 1)); + } + } else { + script_183(arg0, subtract(ivar1, 1)); + } + return; +} diff --git a/dumps/scripts/1820.cs2 b/dumps/scripts/1820.cs2 new file mode 100644 index 0000000..d5c0aee --- /dev/null +++ b/dumps/scripts/1820.cs2 @@ -0,0 +1,9 @@ +int script_1820(int arg0) { + if (standart_config_1149 == -1) { + return 0; + } + if (arg0 != 1) { + return 0; + } + return 1; +} diff --git a/dumps/scripts/1821.cs2 b/dumps/scripts/1821.cs2 new file mode 100644 index 0000000..edd1230 --- /dev/null +++ b/dumps/scripts/1821.cs2 @@ -0,0 +1,10 @@ +void script_1821(int arg0,int arg1) { + if (((boolean)script_1820(arg0))) { + return; + } + if (globalint_246 != arg1) { + globalint_246 = arg1; + script_1770(); + } + return; +} diff --git a/dumps/scripts/1822.cs2 b/dumps/scripts/1822.cs2 new file mode 100644 index 0000000..db16fb8 --- /dev/null +++ b/dumps/scripts/1822.cs2 @@ -0,0 +1,10 @@ +void script_1822(int arg0,int arg1) { + if (((boolean)script_1820(arg0))) { + return; + } + if (globalint_247 != arg1) { + globalint_247 = arg1; + script_1771(); + } + return; +} diff --git a/dumps/scripts/1823.cs2 b/dumps/scripts/1823.cs2 new file mode 100644 index 0000000..08736ac --- /dev/null +++ b/dumps/scripts/1823.cs2 @@ -0,0 +1,10 @@ +void script_1823(int arg0) { + if (((boolean)script_1820(arg0))) { + return; + } + if (((boolean)globalint_248)) { + globalint_248 = 0; + script_1772(); + } + return; +} diff --git a/dumps/scripts/1824.cs2 b/dumps/scripts/1824.cs2 new file mode 100644 index 0000000..ae48c63 --- /dev/null +++ b/dumps/scripts/1824.cs2 @@ -0,0 +1,10 @@ +void script_1824(int arg0) { + if (((boolean)script_1820(arg0))) { + return; + } + if (((boolean)globalint_248)) { + globalint_248 = 1; + script_1772(); + } + return; +} diff --git a/dumps/scripts/1825.cs2 b/dumps/scripts/1825.cs2 new file mode 100644 index 0000000..b6777b7 --- /dev/null +++ b/dumps/scripts/1825.cs2 @@ -0,0 +1,12 @@ +void script_1825(int arg0) { + if (((boolean)script_1820(arg0))) { + return; + } + if (((boolean)globalint_249)) { + globalint_249 = 1; + } else { + globalint_249 = 0; + } + script_1773(); + return; +} diff --git a/dumps/scripts/1826.cs2 b/dumps/scripts/1826.cs2 new file mode 100644 index 0000000..cd1db6f --- /dev/null +++ b/dumps/scripts/1826.cs2 @@ -0,0 +1,12 @@ +void script_1826(int arg0) { + if (((boolean)script_1820(arg0))) { + return; + } + if (((boolean)globalint_250)) { + globalint_250 = 1; + } else { + globalint_250 = 0; + } + script_1774(); + return; +} diff --git a/dumps/scripts/1827.cs2 b/dumps/scripts/1827.cs2 new file mode 100644 index 0000000..82625ac --- /dev/null +++ b/dumps/scripts/1827.cs2 @@ -0,0 +1,18 @@ +void script_1827(int arg0) { + if (((boolean)script_1820(arg0))) { + return; + } + if (isMember()) { + if (((boolean)globalint_252)) { + globalint_252 = 2; + } else if (globalint_252 == 2) { + globalint_252 = 3; + } else { + globalint_252 = 1; + } + } else { + globalint_252 = mod(add(globalint_252, 1), 4); + } + script_1775(); + return; +} diff --git a/dumps/scripts/1828.cs2 b/dumps/scripts/1828.cs2 new file mode 100644 index 0000000..96e588a --- /dev/null +++ b/dumps/scripts/1828.cs2 @@ -0,0 +1,12 @@ +void script_1828(int arg0) { + if (((boolean)script_1820(arg0))) { + return; + } + if (((boolean)globalint_251)) { + globalint_251 = 1; + } else { + globalint_251 = 0; + } + script_1776(); + return; +} diff --git a/dumps/scripts/1829.cs2 b/dumps/scripts/1829.cs2 new file mode 100644 index 0000000..d95d002 --- /dev/null +++ b/dumps/scripts/1829.cs2 @@ -0,0 +1,12 @@ +void script_1829(int arg0) { + if (((boolean)script_1820(arg0))) { + return; + } + if (((boolean)globalint_256)) { + globalint_256 = 1; + } else { + globalint_256 = 0; + } + script_1777(); + return; +} diff --git a/dumps/scripts/183.cs2 b/dumps/scripts/183.cs2 new file mode 100644 index 0000000..200aa5a --- /dev/null +++ b/dumps/scripts/183.cs2 @@ -0,0 +1,25 @@ +void script_183(int arg0,int arg1) { + switch (arg0) { + case 1: + globalint_44 = arg1; + break; + case 2: + globalint_45 = arg1; + break; + case 3: + globalint_46 = arg1; + break; + case 4: + globalint_47 = arg1; + break; + case 5: + globalint_48 = arg1; + break; + case 6: + globalint_49 = arg1; + break; + case 7: + globalint_1511 = arg1; + } + return; +} diff --git a/dumps/scripts/1830.cs2 b/dumps/scripts/1830.cs2 new file mode 100644 index 0000000..f03f658 --- /dev/null +++ b/dumps/scripts/1830.cs2 @@ -0,0 +1,15 @@ +void script_1830(int arg0) { + if (isMember()) { + return; + } + if (((boolean)script_1820(arg0))) { + return; + } + if (((boolean)globalint_253)) { + globalint_253 = 1; + } else { + globalint_253 = 0; + } + script_1778(); + return; +} diff --git a/dumps/scripts/1831.cs2 b/dumps/scripts/1831.cs2 new file mode 100644 index 0000000..139697a --- /dev/null +++ b/dumps/scripts/1831.cs2 @@ -0,0 +1,12 @@ +void script_1831(int arg0) { + if (((boolean)script_1820(arg0))) { + return; + } + if (((boolean)globalint_254)) { + globalint_254 = 1; + } else { + globalint_254 = 0; + } + script_1779(); + return; +} diff --git a/dumps/scripts/1832.cs2 b/dumps/scripts/1832.cs2 new file mode 100644 index 0000000..ad67bed --- /dev/null +++ b/dumps/scripts/1832.cs2 @@ -0,0 +1,12 @@ +void script_1832(int arg0) { + if (((boolean)script_1820(arg0))) { + return; + } + if (((boolean)globalint_255)) { + globalint_255 = 1; + } else { + globalint_255 = 0; + } + script_1780(); + return; +} diff --git a/dumps/scripts/1833.cs2 b/dumps/scripts/1833.cs2 new file mode 100644 index 0000000..8be2ee4 --- /dev/null +++ b/dumps/scripts/1833.cs2 @@ -0,0 +1,13 @@ +void script_1833(int arg0,int arg1) { + if (((boolean)script_1820(arg0))) { + return; + } + if (isMember() && ((boolean)getOtherCommonData(cs2method_3408(105, 74, 1604, arg1), 557))) { + return; + } + if (globalint_257 != arg1) { + globalint_257 = arg1; + script_1781(); + } + return; +} diff --git a/dumps/scripts/1834.cs2 b/dumps/scripts/1834.cs2 new file mode 100644 index 0000000..6f4df3c --- /dev/null +++ b/dumps/scripts/1834.cs2 @@ -0,0 +1,13 @@ +void script_1834(int arg0) { + if (arg0 != 1) { + return; + } + if (((((boolean)globalint_250) && (globalint_252 >= 2)) && ((boolean)globalint_251)) && (isMember() || ((boolean)globalint_253))) { + return; + } + if (((boolean)globalint_258)) { + globalint_258 = 1; + script_1782(); + } + return; +} diff --git a/dumps/scripts/1835.cs2 b/dumps/scripts/1835.cs2 new file mode 100644 index 0000000..a01cf0e --- /dev/null +++ b/dumps/scripts/1835.cs2 @@ -0,0 +1,4 @@ +void script_1835(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6) { + script_2784(-1, arg0, arg1, arg2, arg3, arg4, arg5, arg6); + return; +} diff --git a/dumps/scripts/1836.cs2 b/dumps/scripts/1836.cs2 new file mode 100644 index 0000000..57b7bec --- /dev/null +++ b/dumps/scripts/1836.cs2 @@ -0,0 +1,53 @@ +void script_1836() { + if (globalint_246 != bitconfig_5280) { + globalint_246 = bitconfig_5280; + script_1770(); + } + if (globalint_247 != bitconfig_5281) { + globalint_247 = bitconfig_5281; + script_1771(); + } + if (script_42(globalint_248) != bitconfig_5282) { + globalint_248 = script_734(bitconfig_5282); + script_1772(); + } + if (script_42(globalint_249) != bitconfig_5283) { + globalint_249 = script_734(bitconfig_5283); + script_1773(); + } + if (script_42(globalint_250) != bitconfig_5284) { + globalint_250 = script_734(bitconfig_5284); + script_1774(); + } + if (globalint_252 != bitconfig_5286) { + globalint_252 = bitconfig_5286; + script_1775(); + } + if (script_42(globalint_251) != bitconfig_5285) { + globalint_251 = script_734(bitconfig_5285); + script_1776(); + } + if (script_42(globalint_256) != bitconfig_5290) { + globalint_256 = script_734(bitconfig_5290); + script_1777(); + } + if (script_42(globalint_253) != bitconfig_5287) { + globalint_253 = script_734(bitconfig_5287); + script_1778(); + } + if (script_42(globalint_254) != bitconfig_5288) { + globalint_254 = script_734(bitconfig_5288); + script_1779(); + } + if (script_42(globalint_255) != bitconfig_5289) { + globalint_255 = script_734(bitconfig_5289); + script_1780(); + } + if (globalint_257 != bitconfig_5292) { + globalint_257 = bitconfig_5292; + script_1781(); + } + globalint_258 = script_734(bitconfig_5293); + script_1782(); + return; +} diff --git a/dumps/scripts/1837.cs2 b/dumps/scripts/1837.cs2 new file mode 100644 index 0000000..38c4d80 --- /dev/null +++ b/dumps/scripts/1837.cs2 @@ -0,0 +1,4 @@ +void script_1837() { + script_1782(); + return; +} diff --git a/dumps/scripts/1838.cs2 b/dumps/scripts/1838.cs2 new file mode 100644 index 0000000..de39b81 --- /dev/null +++ b/dumps/scripts/1838.cs2 @@ -0,0 +1,4 @@ +void script_1838(int arg0) { + setWidgetText(new WidgetPointer(arg0), globalstring_37); + return; +} diff --git a/dumps/scripts/1839.cs2 b/dumps/scripts/1839.cs2 new file mode 100644 index 0000000..141e4c1 --- /dev/null +++ b/dumps/scripts/1839.cs2 @@ -0,0 +1,88 @@ +void script_1839(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + flow_0: + deleteAllExtraChilds(new WidgetPointer(arg1)); + ivar4 = 0; + ivar5 = 0; + ivar6 = 0; + ivar7 = script_285(arg1, ivar7); + createExtraChild(new WidgetPointer(arg1), 5, getExtraChildGap(new WidgetPointer(arg1))); + setWidgetPosition(0, ivar7, 0, 0); + setWidgetSize(0, 5, 1, 0); + setWidgetSprite(1121); + cs2method1107(1); + ivar7 = add(ivar7, 4); + globalarray_0 = new int[add(105, 1)]; + ivar8 = -1; + ivar9 = -1; + IF (((boolean)arg0)) + GOTO flow_1 + GOTO flow_7 + flow_1: + IF (ivar4 <= 105) + GOTO flow_2 + GOTO flow_6 + flow_2: + ivar8 = cs2method_3408(105, 74, 1805, ivar4); + if ((ivar8 != -1) && (isMember() || ((boolean)getOtherCommonData(ivar8, 478)))) { + ivar7 = script_1840(arg1, ivar4, ivar7); + } + ivar4 = add(ivar4, 1); + GOTO flow_1 + flow_6: + setWidgetText(new WidgetPointer(arg3), "Key order:" + "
" + "Traditional"); + GOTO flow_28 + flow_7: + IF (ivar4 <= 105) + GOTO flow_8 + GOTO flow_12 + flow_8: + ivar8 = cs2method_3408(105, 74, 1805, ivar4); + if ((ivar8 != -1) && (isMember() || ((boolean)getOtherCommonData(ivar8, 478)))) { + globalarray_0[ivar6] = ivar4; + ivar6 = add(ivar6, 1); + } + ivar4 = add(ivar4, 1); + GOTO flow_7 + flow_12: + ivar6 = subtract(ivar6, 1); + ivar4 = 0; + if (((boolean)arg0)) { + script_1842(0, 0, ivar6); + while (ivar4 <= ivar6) { + ivar7 = script_1840(arg1, globalarray_0[ivar4], ivar7); + ivar4 = add(ivar4, 1); + } + setWidgetText(new WidgetPointer(arg3), "Key order:" + "
" + "Alphabetical"); + } else { + if (arg0 == 2) { + script_1843(0, 0, ivar6); + while (ivar9 < getCommonDefinitionSize(1806)) { + ivar7 = script_1841(arg1, ivar9, ivar7); + while (getOtherCommonData(cs2method_3408(105, 74, 1805, globalarray_0[ivar5]), 597) == ivar9) { + ivar5 = add(ivar5, 1); + } + script_1842(0, ivar4, subtract(ivar5, 1)); + while (ivar4 < ivar5) { + ivar7 = script_1840(arg1, globalarray_0[ivar4], ivar7); + ivar4 = add(ivar4, 1); + } + ivar9 = add(ivar9, 1); + } + setWidgetText(new WidgetPointer(arg3), "Key order:" + "
" + "Categorised"); + } + } + flow_28: + ivar7 = add(ivar7, 5); + setWidgetScrollMax(0, ivar7, new WidgetPointer(arg1)); + script_31(arg2, arg1, 792, 789, 790, 791, 773, 788); + if (setWidgetRegister(new WidgetPointer(arg2), 1)) { + script_37(arg2, arg1, cs2method2601(new WidgetPointer(arg1)), 1); + } + return; +} diff --git a/dumps/scripts/184.cs2 b/dumps/scripts/184.cs2 new file mode 100644 index 0000000..7d69db0 --- /dev/null +++ b/dumps/scripts/184.cs2 @@ -0,0 +1,29 @@ +void script_184(int arg0,int arg1) { + switch (arg0) { + case 1: + if (arg1 > 0) { + bitconfig_6161 = 1; + } else { + bitconfig_6161 = 0; + } + break; + case 2: + cs2method5001(arg1, cs2method5005(), cs2method5016()); + break; + case 3: + cs2method5001(cs2method5000(), arg1, cs2method5016()); + break; + case 4: + standart_config_2159 = arg1; + break; + case 5: + cs2method5001(cs2method5000(), cs2method5005(), arg1); + break; + case 6: + standart_config_1055 = arg1; + break; + case 7: + standart_config_1054 = arg1; + } + return; +} diff --git a/dumps/scripts/1840.cs2 b/dumps/scripts/1840.cs2 new file mode 100644 index 0000000..91e3157 --- /dev/null +++ b/dumps/scripts/1840.cs2 @@ -0,0 +1,36 @@ +int script_1840(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + string svar0; + ivar3 = cs2method_3408(105, 74, 1805, arg1); + if (ivar3 == -1) { + return arg2; + } + svar0 = getOtherCommonData(ivar3, 596); + ivar4 = getOtherCommonData(ivar3, 477); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + createExtraChild(new WidgetPointer(arg0), 4, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(3, arg2, 0, 0); + setWidgetSize(15, 15, 0, 0); + setWidgetPosition(add(getWidgetActualX(), getWidgetActualWidth()), arg2, 0, 0); + setWidgetSize(add(getWidgetActualX(), getWidgetActualX()), getWidgetActualHeight(), 1, 0); + setWidgetSprite(getOtherCommonData(ivar3, 595)); + setWidgetRGB(new Color(175, 175, 175)); + setWidgetFont(495); + setWidgetUnknownBoolean(true); + setWidgetTextAlignment(0, 1, 0); + setWidgetText(svar0); + if (ivar4 != -1) { + cs2method1305("" + svar0 + ""); + cs2method1305("" + svar0 + ""); + setWidgetContextMenuOption(1, "Highlight"); + setWidgetContextMenuOption(1, "Highlight"); + setScriptCallOnClickContextMenu(288, ivar4, "y"); + setScriptCallOnClickContextMenu(288, ivar4, "y"); + setScriptCallOnMouseEntered(1356, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), 16777215, "Iii"); + setScriptCallOnMouseEntered(1356, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), 16777215, "Iii"); + setScriptCallOnMouseExit(1356, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), 11513775, "Iii"); + setScriptCallOnMouseExit(1356, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), 11513775, "Iii"); + } + return add(arg2, getWidgetActualHeight()); +} diff --git a/dumps/scripts/1841.cs2 b/dumps/scripts/1841.cs2 new file mode 100644 index 0000000..4d9f701 --- /dev/null +++ b/dumps/scripts/1841.cs2 @@ -0,0 +1,11 @@ +int script_1841(int arg0,int arg1,int arg2) { + createExtraChild(new WidgetPointer(arg0), 4, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetText(cs2method_3408(105, 115, 1806, arg1)); + setWidgetPosition(0, arg2, 0, 0); + setWidgetSize(0, 30, 1, 0); + setWidgetRGB(new Color(255, 152, 31)); + setWidgetFont(496); + setWidgetUnknownBoolean(true); + setWidgetTextAlignment(1, 1, 0); + return add(arg2, getWidgetActualHeight()); +} diff --git a/dumps/scripts/1842.cs2 b/dumps/scripts/1842.cs2 new file mode 100644 index 0000000..9a3b332 --- /dev/null +++ b/dumps/scripts/1842.cs2 @@ -0,0 +1,38 @@ +void script_1842(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + ivar3 = divide(add(arg1, arg2), 2); + ivar4 = globalarray_0[ivar3]; + globalarray_0[ivar3] = globalarray_0[arg2]; + globalarray_0[arg2] = ivar4; + ivar5 = arg1; + ivar6 = arg1; + ivar7 = 0; + ivar8 = -1; + ivar9 = -1; + while (ivar6 < arg2) { + ivar8 = cs2method_3408(105, 74, 1805, globalarray_0[ivar6]); + ivar9 = cs2method_3408(105, 74, 1805, ivar4); + if (stringMethod4107(lower(getOtherCommonData(ivar8, 596)), lower(getOtherCommonData(ivar9, 596))) < bitAnd(ivar6, 1)) { + ivar7 = globalarray_0[ivar6]; + globalarray_0[ivar6] = globalarray_0[ivar5]; + globalarray_0[ivar5] = ivar7; + ivar5 = add(ivar5, 1); + } + ivar6 = add(ivar6, 1); + } + globalarray_0[arg2] = globalarray_0[ivar5]; + globalarray_0[ivar5] = ivar4; + if (arg1 < subtract(ivar5, 1)) { + script_1842(0, arg1, subtract(ivar5, 1)); + } + if (add(ivar5, 1) < arg2) { + script_1842(0, add(ivar5, 1), arg2); + } + return; +} diff --git a/dumps/scripts/1843.cs2 b/dumps/scripts/1843.cs2 new file mode 100644 index 0000000..773e2a0 --- /dev/null +++ b/dumps/scripts/1843.cs2 @@ -0,0 +1,38 @@ +void script_1843(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + ivar3 = divide(add(arg1, arg2), 2); + ivar4 = globalarray_0[ivar3]; + globalarray_0[ivar3] = globalarray_0[arg2]; + globalarray_0[arg2] = ivar4; + ivar5 = arg1; + ivar6 = arg1; + ivar7 = 0; + ivar8 = -1; + ivar9 = -1; + while (ivar6 < arg2) { + ivar8 = cs2method_3408(105, 74, 1805, globalarray_0[ivar6]); + ivar9 = cs2method_3408(105, 74, 1805, ivar4); + if (getOtherCommonData(ivar8, 597) < getOtherCommonData(ivar9, 597)) { + ivar7 = globalarray_0[ivar6]; + globalarray_0[ivar6] = globalarray_0[ivar5]; + globalarray_0[ivar5] = ivar7; + ivar5 = add(ivar5, 1); + } + ivar6 = add(ivar6, 1); + } + globalarray_0[arg2] = globalarray_0[ivar5]; + globalarray_0[ivar5] = ivar4; + if (arg1 < subtract(ivar5, 1)) { + script_1843(0, arg1, subtract(ivar5, 1)); + } + if (add(ivar5, 1) < arg2) { + script_1843(0, add(ivar5, 1), arg2); + } + return; +} diff --git a/dumps/scripts/1844.cs2 b/dumps/scripts/1844.cs2 new file mode 100644 index 0000000..0996ccd --- /dev/null +++ b/dumps/scripts/1844.cs2 @@ -0,0 +1,505 @@ +int script_1844(int arg0) { + switch (arg0) { + case 0: + return globalint_0; + case 1: + return globalint_274; + case 2: + return globalint_275; + case 3: + return globalint_276; + case 4: + return globalint_277; + case 5: + return globalint_278; + case 6: + return globalint_279; + case 7: + return globalint_280; + case 8: + return globalint_281; + case 9: + return globalint_282; + case 10: + return globalint_283; + case 11: + return globalint_284; + case 12: + return globalint_285; + case 13: + return globalint_286; + case 14: + return globalint_287; + case 15: + return globalint_288; + case 16: + return globalint_289; + case 17: + return globalint_290; + case 18: + return globalint_291; + case 19: + return globalint_292; + case 20: + return globalint_293; + case 21: + return globalint_294; + case 22: + return globalint_295; + case 23: + return globalint_296; + case 24: + return globalint_297; + case 25: + return globalint_298; + case 26: + return globalint_299; + case 27: + return globalint_300; + case 28: + return globalint_301; + case 29: + return globalint_302; + case 30: + return globalint_303; + case 31: + return globalint_304; + case 32: + return globalint_305; + case 33: + return globalint_306; + case 34: + return globalint_307; + case 35: + return globalint_308; + case 36: + return globalint_309; + case 37: + return globalint_310; + case 38: + return globalint_311; + case 39: + return globalint_312; + case 40: + return globalint_313; + case 41: + return globalint_314; + case 42: + return globalint_315; + case 43: + return globalint_316; + case 44: + return globalint_317; + case 45: + return globalint_318; + case 46: + return globalint_319; + case 47: + return globalint_320; + case 48: + return globalint_321; + case 49: + return globalint_322; + case 50: + return globalint_323; + case 51: + return globalint_324; + case 52: + return globalint_325; + case 53: + return globalint_326; + case 54: + return globalint_327; + case 55: + return globalint_328; + case 56: + return globalint_329; + case 57: + return globalint_330; + case 58: + return globalint_331; + case 59: + return globalint_332; + case 60: + return globalint_333; + case 61: + return globalint_334; + case 62: + return globalint_335; + case 63: + return globalint_336; + case 64: + return globalint_337; + case 65: + return globalint_338; + case 66: + return globalint_339; + case 67: + return globalint_340; + case 68: + return globalint_341; + case 69: + return globalint_342; + case 70: + return globalint_343; + case 71: + return globalint_344; + case 72: + return globalint_345; + case 73: + return globalint_346; + case 74: + return globalint_347; + case 75: + return globalint_348; + case 76: + return globalint_349; + case 77: + return globalint_350; + case 78: + return globalint_351; + case 79: + return globalint_352; + case 80: + return globalint_353; + case 81: + return globalint_354; + case 82: + return globalint_355; + case 83: + return globalint_356; + case 84: + return globalint_357; + case 85: + return globalint_358; + case 86: + return globalint_359; + case 87: + return globalint_360; + case 88: + return globalint_361; + case 89: + return globalint_362; + case 90: + return globalint_363; + case 91: + return globalint_364; + case 92: + return globalint_365; + case 93: + return globalint_366; + case 94: + return globalint_367; + case 95: + return globalint_368; + case 96: + return globalint_369; + case 97: + return globalint_370; + case 98: + return globalint_371; + case 99: + return globalint_372; + case 100: + return globalint_373; + case 101: + return globalint_374; + case 102: + return globalint_375; + case 103: + return globalint_376; + case 104: + return globalint_377; + case 105: + return globalint_378; + case 106: + return globalint_379; + case 107: + return globalint_380; + case 108: + return globalint_381; + case 109: + return globalint_382; + case 110: + return globalint_383; + case 111: + return globalint_384; + case 112: + return globalint_385; + case 113: + return globalint_386; + case 114: + return globalint_387; + case 115: + return globalint_388; + case 116: + return globalint_389; + case 117: + return globalint_390; + case 118: + return globalint_391; + case 119: + return globalint_392; + case 120: + return globalint_393; + case 121: + return globalint_394; + case 122: + return globalint_395; + case 123: + return globalint_396; + case 124: + return globalint_397; + case 125: + return globalint_398; + case 126: + return globalint_399; + case 127: + return globalint_400; + case 128: + return globalint_401; + case 129: + return globalint_402; + case 130: + return globalint_403; + case 131: + return globalint_404; + case 132: + return globalint_405; + case 133: + return globalint_406; + case 134: + return globalint_407; + case 135: + return globalint_408; + case 136: + return globalint_409; + case 137: + return globalint_410; + case 138: + return globalint_411; + case 139: + return globalint_412; + case 140: + return globalint_413; + case 141: + return globalint_414; + case 142: + return globalint_415; + case 143: + return globalint_416; + case 144: + return globalint_417; + case 145: + return globalint_418; + case 146: + return globalint_419; + case 147: + return globalint_420; + case 148: + return globalint_421; + case 149: + return globalint_422; + case 150: + return globalint_423; + case 151: + return globalint_424; + case 152: + return globalint_425; + case 153: + return globalint_426; + case 154: + return globalint_427; + case 155: + return globalint_428; + case 156: + return globalint_429; + case 157: + return globalint_430; + case 158: + return globalint_431; + case 159: + return globalint_432; + case 160: + return globalint_433; + case 161: + return globalint_434; + case 162: + return globalint_435; + case 163: + return globalint_436; + case 164: + return globalint_437; + case 165: + return globalint_438; + case 166: + return globalint_439; + case 167: + return globalint_440; + case 168: + return globalint_441; + case 169: + return globalint_442; + case 170: + return globalint_443; + case 171: + return globalint_444; + case 172: + return globalint_445; + case 173: + return globalint_446; + case 174: + return globalint_447; + case 175: + return globalint_448; + case 176: + return globalint_449; + case 177: + return globalint_450; + case 178: + return globalint_451; + case 179: + return globalint_452; + case 180: + return globalint_453; + case 181: + return globalint_454; + case 182: + return globalint_455; + case 183: + return globalint_456; + case 184: + return globalint_457; + case 185: + return globalint_458; + case 186: + return globalint_459; + case 187: + return globalint_460; + case 188: + return globalint_461; + case 189: + return globalint_462; + case 190: + return globalint_463; + case 191: + return globalint_464; + case 192: + return globalint_465; + case 193: + return globalint_466; + case 194: + return globalint_467; + case 195: + return globalint_468; + case 196: + return globalint_469; + case 197: + return globalint_470; + case 198: + return globalint_471; + case 199: + return globalint_472; + case 200: + return globalint_473; + case 201: + return globalint_474; + case 202: + return globalint_475; + case 203: + return globalint_476; + case 204: + return globalint_477; + case 205: + return globalint_478; + case 206: + return globalint_479; + case 207: + return globalint_480; + case 208: + return globalint_481; + case 209: + return globalint_482; + case 210: + return globalint_483; + case 211: + return globalint_484; + case 212: + return globalint_485; + case 213: + return globalint_486; + case 214: + return globalint_487; + case 215: + return globalint_488; + case 216: + return globalint_489; + case 217: + return globalint_490; + case 218: + return globalint_491; + case 219: + return globalint_492; + case 220: + return globalint_493; + case 221: + return globalint_494; + case 222: + return globalint_495; + case 223: + return globalint_496; + case 224: + return globalint_497; + case 225: + return globalint_498; + case 226: + return globalint_499; + case 227: + return globalint_500; + case 228: + return globalint_501; + case 229: + return globalint_502; + case 230: + return globalint_503; + case 231: + return globalint_504; + case 232: + return globalint_505; + case 233: + return globalint_506; + case 234: + return globalint_507; + case 235: + return globalint_508; + case 236: + return globalint_509; + case 237: + return globalint_510; + case 238: + return globalint_511; + case 239: + return globalint_512; + case 240: + return globalint_513; + case 241: + return globalint_514; + case 242: + return globalint_515; + case 243: + return globalint_516; + case 244: + return globalint_517; + case 245: + return globalint_518; + case 246: + return globalint_519; + case 247: + return globalint_520; + case 248: + return globalint_521; + case 249: + return globalint_522; + } + return 0; +} diff --git a/dumps/scripts/1845.cs2 b/dumps/scripts/1845.cs2 new file mode 100644 index 0000000..8c69298 --- /dev/null +++ b/dumps/scripts/1845.cs2 @@ -0,0 +1,7 @@ +void script_1845() { + setWidgetText(new WidgetPointer(893,9), globalstring_197); + setWidgetText(new WidgetPointer(893,10), globalstring_198); + setWidgetText(new WidgetPointer(893,11), globalstring_199); + setWidgetText(new WidgetPointer(893,12), globalstring_200); + return; +} diff --git a/dumps/scripts/1846.cs2 b/dumps/scripts/1846.cs2 new file mode 100644 index 0000000..8065c08 --- /dev/null +++ b/dumps/scripts/1846.cs2 @@ -0,0 +1,8 @@ +void script_1846() { + if ((((script_1305() != 8) && ((boolean)script_1569())) && (isWidgetOpen(new WidgetPointer(script_8(8))) && (bitconfig_6521 != 3))) && (bitconfig_6521 != 10)) { + script_736(script_1742(8), -1, script_121(8), -1); + setScriptCallOnGameloop(1847, "", new WidgetPointer(746,22)); + setScriptCallOnGameloop(1847, "", new WidgetPointer(548,128)); + } + return; +} diff --git a/dumps/scripts/1847.cs2 b/dumps/scripts/1847.cs2 new file mode 100644 index 0000000..d1b8d9a --- /dev/null +++ b/dumps/scripts/1847.cs2 @@ -0,0 +1,19 @@ +void script_1847() { + int ivar0; + ivar0 = script_121(8); + if (((script_1305() != 8) && ((boolean)script_1569())) && isWidgetOpen(new WidgetPointer(script_8(8)))) { + if (ivar0 != -1) { + if (mod(getClientCycle(), 40) > 20) { + setWidgetIsHidden(false, new WidgetPointer(ivar0)); + if (mod(getClientCycle(), 40) == 21) { + playSoundEffect(5009, 1, 0); + } + } else { + setWidgetIsHidden(true, new WidgetPointer(ivar0)); + } + } + } else { + script_1849(); + } + return; +} diff --git a/dumps/scripts/1848.cs2 b/dumps/scripts/1848.cs2 new file mode 100644 index 0000000..00983a3 --- /dev/null +++ b/dumps/scripts/1848.cs2 @@ -0,0 +1,4 @@ +void script_1848() { + script_1849(); + return; +} diff --git a/dumps/scripts/1849.cs2 b/dumps/scripts/1849.cs2 new file mode 100644 index 0000000..78817c4 --- /dev/null +++ b/dumps/scripts/1849.cs2 @@ -0,0 +1,7 @@ +void script_1849() { + setScriptCallOnGameloop(-1, "", new WidgetPointer(746,22)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(548,128)); + script_736(-1, -1, -1, -1); + script_1364(); + return; +} diff --git a/dumps/scripts/185.cs2 b/dumps/scripts/185.cs2 new file mode 100644 index 0000000..4534ae6 --- /dev/null +++ b/dumps/scripts/185.cs2 @@ -0,0 +1,19 @@ +int script_185(int arg0) { + switch (arg0) { + case 1: + return bitconfig_6161; + case 2: + return cs2method5000(); + case 3: + return cs2method5005(); + case 4: + return standart_config_2159; + case 5: + return cs2method5016(); + case 6: + return standart_config_1055; + case 7: + return standart_config_1054; + } + return 0; +} diff --git a/dumps/scripts/1850.cs2 b/dumps/scripts/1850.cs2 new file mode 100644 index 0000000..3ab1ebc --- /dev/null +++ b/dumps/scripts/1850.cs2 @@ -0,0 +1,4 @@ +void script_1850(int arg0) { + script_1886(arg0); + return; +} diff --git a/dumps/scripts/1851.cs2 b/dumps/scripts/1851.cs2 new file mode 100644 index 0000000..05ecc21 --- /dev/null +++ b/dumps/scripts/1851.cs2 @@ -0,0 +1,3 @@ +int script_1851() { + return globalint_996; +} diff --git a/dumps/scripts/1852.cs2 b/dumps/scripts/1852.cs2 new file mode 100644 index 0000000..eb45093 --- /dev/null +++ b/dumps/scripts/1852.cs2 @@ -0,0 +1,3 @@ +int script_1852() { + return globalint_997; +} diff --git a/dumps/scripts/1853.cs2 b/dumps/scripts/1853.cs2 new file mode 100644 index 0000000..00866f7 --- /dev/null +++ b/dumps/scripts/1853.cs2 @@ -0,0 +1,3 @@ +int script_1853() { + return globalint_998; +} diff --git a/dumps/scripts/1854.cs2 b/dumps/scripts/1854.cs2 new file mode 100644 index 0000000..a561c5e --- /dev/null +++ b/dumps/scripts/1854.cs2 @@ -0,0 +1,3 @@ +int script_1854() { + return globalint_999; +} diff --git a/dumps/scripts/1855.cs2 b/dumps/scripts/1855.cs2 new file mode 100644 index 0000000..a77f788 --- /dev/null +++ b/dumps/scripts/1855.cs2 @@ -0,0 +1,4 @@ +void script_1855(int arg0) { + globalint_996 = arg0; + return; +} diff --git a/dumps/scripts/1856.cs2 b/dumps/scripts/1856.cs2 new file mode 100644 index 0000000..308cfb2 --- /dev/null +++ b/dumps/scripts/1856.cs2 @@ -0,0 +1,4 @@ +void script_1856(int arg0) { + globalint_997 = arg0; + return; +} diff --git a/dumps/scripts/1857.cs2 b/dumps/scripts/1857.cs2 new file mode 100644 index 0000000..94dbc36 --- /dev/null +++ b/dumps/scripts/1857.cs2 @@ -0,0 +1,4 @@ +void script_1857(int arg0) { + globalint_998 = arg0; + return; +} diff --git a/dumps/scripts/1858.cs2 b/dumps/scripts/1858.cs2 new file mode 100644 index 0000000..9286a2b --- /dev/null +++ b/dumps/scripts/1858.cs2 @@ -0,0 +1,4 @@ +void script_1858(int arg0) { + globalint_999 = arg0; + return; +} diff --git a/dumps/scripts/1859.cs2 b/dumps/scripts/1859.cs2 new file mode 100644 index 0000000..1111959 --- /dev/null +++ b/dumps/scripts/1859.cs2 @@ -0,0 +1,21 @@ +cs2func_script_1859_struct(2,0,0) script_1859(int arg0) { + if (((boolean)arg0)) { + cs2method5405(0, 5); + cs2method5405(1, 5); + cs2method5406(0, 0, 43568355, 1350, 43470051, 1350, 0); + cs2method5406(1, 0, 43568367, 330, 43568367, 330, 0); + cs2method5406(0, 1, 43371759, 1250, 43371765, 1250, 0); + cs2method5406(1, 1, 43568367, 330, 43568367, 330, 0); + script_1899(0, 100, 150); + cs2method5406(0, 2, 43568379, 1150, 43683067, 1150, 0); + cs2method5406(1, 2, 43568367, 330, 43568367, 330, 0); + script_1899(1, 100, 150); + cs2method5406(0, 3, 43764975, 1050, 43764969, 1050, 0); + cs2method5406(1, 3, 43568367, 330, 43568367, 330, 0); + script_1899(2, 100, 150); + cs2method5406(0, 4, 43568355, 950, 43470051, 950, 0); + cs2method5406(1, 4, 43568367, 330, 43568367, 330, 0); + script_1899(3, 100, 150); + } + return newstruct cs2func_script_1859_struct(43568355, 1250324); +} diff --git a/dumps/scripts/186.cs2 b/dumps/scripts/186.cs2 new file mode 100644 index 0000000..1ccc0f4 --- /dev/null +++ b/dumps/scripts/186.cs2 @@ -0,0 +1,4 @@ +void script_186(int arg0) { + setWidgetSprite(1022, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1860.cs2 b/dumps/scripts/1860.cs2 new file mode 100644 index 0000000..913c83d --- /dev/null +++ b/dumps/scripts/1860.cs2 @@ -0,0 +1,6 @@ +void script_1860(int arg0,int arg1) { + if (setWidgetRegister(new WidgetPointer(88,22), arg0)) { + setWidgetAnimation(arg1); + } + return; +} diff --git a/dumps/scripts/1861.cs2 b/dumps/scripts/1861.cs2 new file mode 100644 index 0000000..8bd8e20 --- /dev/null +++ b/dumps/scripts/1861.cs2 @@ -0,0 +1,10 @@ +void script_1861() { + setWidgetModel(cs2method_3408(105, 109, 1318, bitconfig_5470), new WidgetPointer(799,10)); + setWidgetModel(cs2method_3408(105, 109, 1318, bitconfig_5471), new WidgetPointer(799,11)); + setWidgetModel(cs2method_3408(105, 109, 1318, bitconfig_5472), new WidgetPointer(799,12)); + setWidgetModel(cs2method_3408(105, 109, 1318, bitconfig_5473), new WidgetPointer(799,13)); + setWidgetModel(cs2method_3408(105, 109, 1318, bitconfig_5474), new WidgetPointer(799,14)); + setWidgetModel(cs2method_3408(105, 109, 1318, bitconfig_5475), new WidgetPointer(799,15)); + setWidgetModel(cs2method_3408(105, 109, 1318, bitconfig_5476), new WidgetPointer(799,16)); + return; +} diff --git a/dumps/scripts/1862.cs2 b/dumps/scripts/1862.cs2 new file mode 100644 index 0000000..01d9733 --- /dev/null +++ b/dumps/scripts/1862.cs2 @@ -0,0 +1,6 @@ +void script_1862(int arg0,int arg1) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + cs2method2103(100); + } + return; +} diff --git a/dumps/scripts/1863.cs2 b/dumps/scripts/1863.cs2 new file mode 100644 index 0000000..eb89192 --- /dev/null +++ b/dumps/scripts/1863.cs2 @@ -0,0 +1,6 @@ +void script_1863(int arg0,int arg1) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + cs2method2103(0); + } + return; +} diff --git a/dumps/scripts/1864.cs2 b/dumps/scripts/1864.cs2 new file mode 100644 index 0000000..8da1343 --- /dev/null +++ b/dumps/scripts/1864.cs2 @@ -0,0 +1,170 @@ +void script_1864(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + if (arg0 != 1) { + return; + } + switch (arg2) { + case 12: + switch (arg3) { + case 0: + messageType0("Rick: " + intToStr(cs2method_3408(105, 105, 238, 1)) + " coins."); + break; + case 1: + messageType0("Maid: " + intToStr(cs2method_3408(105, 105, 238, 3)) + " coins."); + break; + case 2: + messageType0("Cook: " + intToStr(cs2method_3408(105, 105, 238, 5)) + " coins."); + break; + case 3: + messageType0("Butler: " + intToStr(cs2method_3408(105, 105, 238, 6)) + " coins."); + break; + case 4: + messageType0("Demon Butler: " + intToStr(cs2method_3408(105, 105, 238, 8)) + " coins."); + } + return; + case 0: + switch (arg1) { + case 8170: + arg1 = 8415; + break; + case 8315: + arg1 = 8395; + break; + case 8222: + arg1 = 8396; + break; + case 8121: + arg1 = 8397; + break; + case 8379: + arg1 = 8406; + break; + case 8037: + arg1 = 8398; + break; + case 8255: + arg1 = 8401; + break; + case 8163: + arg1 = 8399; + break; + case 8027: + arg1 = 8400; + break; + case 8259: + arg1 = 8403; + break; + case 8340: + arg1 = 8407; + break; + case 9822: + arg1 = 9842; + break; + case 8068: + arg1 = 8405; + break; + case 8333: + arg1 = 8408; + break; + case 8195: + arg1 = 8416; + break; + case 8363: + arg1 = 8409; + break; + case 8302: + arg1 = 8410; + break; + case 8123: + arg1 = 8411; + break; + case 8122: + arg1 = 18800; + break; + case 8151: + arg1 = 8414; + } + messageType0(getItemName(arg1) + ": " + formatNumber(getItemValue(arg1), 1) + " coins."); + return; + case 14: + case 15: + return; + } + globalarray_0 = new int[6]; + globalarray_1 = new int[6]; + ivar4 = 0; + if (getItemHashmapData(arg1, 211) != -1) { + globalarray_0[0] = getItemHashmapData(arg1, 211); + globalarray_0[0] = getItemHashmapData(arg1, 212); + ivar4 = add(ivar4, 1); + } + if (getItemHashmapData(arg1, 213) != -1) { + globalarray_0[1] = getItemHashmapData(arg1, 213); + globalarray_0[1] = getItemHashmapData(arg1, 214); + ivar4 = add(ivar4, 1); + } + if (getItemHashmapData(arg1, 215) != -1) { + globalarray_0[2] = getItemHashmapData(arg1, 215); + globalarray_0[2] = getItemHashmapData(arg1, 216); + ivar4 = add(ivar4, 1); + } + if (getItemHashmapData(arg1, 217) != -1) { + globalarray_0[3] = getItemHashmapData(arg1, 217); + globalarray_0[3] = getItemHashmapData(arg1, 218); + ivar4 = add(ivar4, 1); + } + if (getItemHashmapData(arg1, 219) != -1) { + globalarray_0[4] = getItemHashmapData(arg1, 219); + globalarray_0[4] = getItemHashmapData(arg1, 220); + ivar4 = add(ivar4, 1); + } + if (getItemHashmapData(arg1, 221) != -1) { + globalarray_0[5] = getItemHashmapData(arg1, 221); + globalarray_0[5] = getItemHashmapData(arg1, 222); + ivar4 = add(ivar4, 1); + } + switch (ivar4) { + case 1: + messageType0(getItemName(arg1) + ":"); + messageType0(formatNumber(globalarray_1[0], 1) + " x " + getItemName(globalarray_0[0])); + break; + case 2: + messageType0(getItemName(arg1) + ":"); + messageType0(formatNumber(globalarray_1[0], 1) + " x " + getItemName(globalarray_0[0])); + messageType0(formatNumber(globalarray_1[1], 1) + " x " + getItemName(globalarray_0[1])); + break; + case 3: + messageType0(getItemName(arg1) + ":"); + messageType0(formatNumber(globalarray_1[0], 1) + " x " + getItemName(globalarray_0[0])); + messageType0(formatNumber(globalarray_1[1], 1) + " x " + getItemName(globalarray_0[1])); + messageType0(formatNumber(globalarray_1[2], 1) + " x " + getItemName(globalarray_0[2])); + break; + case 4: + messageType0(getItemName(arg1) + ":"); + messageType0(formatNumber(globalarray_1[0], 1) + " x " + getItemName(globalarray_0[0])); + messageType0(formatNumber(globalarray_1[1], 1) + " x " + getItemName(globalarray_0[1])); + messageType0(formatNumber(globalarray_1[2], 1) + " x " + getItemName(globalarray_0[2])); + messageType0(formatNumber(globalarray_1[3], 1) + " x " + getItemName(globalarray_0[3])); + break; + case 5: + messageType0(getItemName(arg1) + ":"); + messageType0(formatNumber(globalarray_1[0], 1) + " x " + getItemName(globalarray_0[0])); + messageType0(formatNumber(globalarray_1[1], 1) + " x " + getItemName(globalarray_0[1])); + messageType0(formatNumber(globalarray_1[2], 1) + " x " + getItemName(globalarray_0[2])); + messageType0(formatNumber(globalarray_1[3], 1) + " x " + getItemName(globalarray_0[3])); + messageType0(formatNumber(globalarray_1[4], 1) + " x " + getItemName(globalarray_0[4])); + break; + case 6: + messageType0(getItemName(arg1) + ":"); + messageType0(formatNumber(globalarray_1[0], 1) + " x " + getItemName(globalarray_0[0])); + messageType0(formatNumber(globalarray_1[1], 1) + " x " + getItemName(globalarray_0[1])); + messageType0(formatNumber(globalarray_1[2], 1) + " x " + getItemName(globalarray_0[2])); + messageType0(formatNumber(globalarray_1[3], 1) + " x " + getItemName(globalarray_0[3])); + messageType0(formatNumber(globalarray_1[4], 1) + " x " + getItemName(globalarray_0[4])); + messageType0(formatNumber(globalarray_1[5], 1) + " x " + getItemName(globalarray_0[5])); + break; + default: + messageType0(getItemName(arg1)); + } + return; +} diff --git a/dumps/scripts/1865.cs2 b/dumps/scripts/1865.cs2 new file mode 100644 index 0000000..d3497b1 --- /dev/null +++ b/dumps/scripts/1865.cs2 @@ -0,0 +1,7 @@ +void script_1865(int arg0,int arg1) { + if (arg0 != 1) { + return; + } + messageType0(cs2method_3408(111, 115, 2024, arg1)); + return; +} diff --git a/dumps/scripts/1866.cs2 b/dumps/scripts/1866.cs2 new file mode 100644 index 0000000..a78e0ff --- /dev/null +++ b/dumps/scripts/1866.cs2 @@ -0,0 +1,18 @@ +cs2func_script_1866_struct(2,0,0) script_1866(int arg0) { + if (((boolean)arg0)) { + cs2method5405(0, 4); + cs2method5405(1, 4); + cs2method5406(0, 0, 48417962, 1000, 48385194, 1000, 0); + cs2method5406(1, 0, 48417960, 600, 48401568, 600, 0); + cs2method5406(0, 1, 48417946, 1000, 48434326, 1000, 0); + cs2method5406(1, 1, 48450710, 600, 48467090, 600, 0); + script_1899(0, 100, 100); + cs2method5406(0, 2, 48532612, 1000, 48532610, 1000, 0); + cs2method5406(1, 2, 48581761, 600, 48581760, 600, 0); + script_1899(1, 100, 100); + cs2method5406(0, 3, 48548992, 1000, 48548992, 1000, 0); + cs2method5406(1, 3, 48598144, 600, 48598144, 600, 0); + script_1899(2, 100, 100); + } + return newstruct cs2func_script_1866_struct(48483486, 1250324); +} diff --git a/dumps/scripts/1867.cs2 b/dumps/scripts/1867.cs2 new file mode 100644 index 0000000..2c2b1dc --- /dev/null +++ b/dumps/scripts/1867.cs2 @@ -0,0 +1,4 @@ +void script_1867() { + cs2method5400(0, "www", "parents.ws"); + return; +} diff --git a/dumps/scripts/1868.cs2 b/dumps/scripts/1868.cs2 new file mode 100644 index 0000000..88530a6 --- /dev/null +++ b/dumps/scripts/1868.cs2 @@ -0,0 +1,8 @@ +void script_1868(int arg0) { + if (((boolean)mod(getClientCycle(), 50)) && (getSystemUpdateTimer() > 0)) { + setWidgetPosition(0, -8, 1, 1, new WidgetPointer(906,27)); + script_1870(59375650); + setScriptCallOnGameloop(1869, new WidgetPointer(906,34), "I", new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/1869.cs2 b/dumps/scripts/1869.cs2 new file mode 100644 index 0000000..049eef8 --- /dev/null +++ b/dumps/scripts/1869.cs2 @@ -0,0 +1,7 @@ +void script_1869(int arg0) { + if (mod(getClientCycle(), 50) != 0) { + return; + } + script_1870(arg0); + return; +} diff --git a/dumps/scripts/187.cs2 b/dumps/scripts/187.cs2 new file mode 100644 index 0000000..aba3bb9 --- /dev/null +++ b/dumps/scripts/187.cs2 @@ -0,0 +1,4 @@ +void script_187(int arg0) { + setWidgetSprite(1021, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1870.cs2 b/dumps/scripts/1870.cs2 new file mode 100644 index 0000000..de8d251 --- /dev/null +++ b/dumps/scripts/1870.cs2 @@ -0,0 +1,29 @@ +void script_1870(int arg0) { + int ivar1; + int ivar2; + int ivar3; + string svar0; + ivar1 = 0; + ivar2 = 0; + ivar3 = getSystemUpdateTimer(); + svar0 = "0"; + if (ivar3 > 0) { + ivar1 = mod(divide(ivar3, 50), 60); + ivar2 = divide(ivar3, 3000); + if (ivar1 < 10) { + svar0 = "System update in: " + intToStr(ivar2) + ":0" + intToStr(ivar1); + } else { + svar0 = "System update in: " + intToStr(ivar2) + ":" + intToStr(ivar1); + } + setWidgetText(new WidgetPointer(arg0), svar0); + if (strLength(svar0) > 0) { + setWidgetSize(add(getTextWidth(494, "System update in: "), 40), getWidgetActualHeight(new WidgetPointer(906,30)), 0, 0, new WidgetPointer(906,30)); + setWidgetIsHidden(false, new WidgetPointer(906,30)); + } else { + setWidgetIsHidden(true, new WidgetPointer(906,30)); + } + } else { + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/1871.cs2 b/dumps/scripts/1871.cs2 new file mode 100644 index 0000000..820108a --- /dev/null +++ b/dumps/scripts/1871.cs2 @@ -0,0 +1,4 @@ +void script_1871(string arg0) { + setWidgetText(new WidgetPointer(906,235), arg0); + return; +} diff --git a/dumps/scripts/1872.cs2 b/dumps/scripts/1872.cs2 new file mode 100644 index 0000000..620c697 --- /dev/null +++ b/dumps/scripts/1872.cs2 @@ -0,0 +1,4 @@ +void script_1872() { + script_1873(); + return; +} diff --git a/dumps/scripts/1873.cs2 b/dumps/scripts/1873.cs2 new file mode 100644 index 0000000..50167a5 --- /dev/null +++ b/dumps/scripts/1873.cs2 @@ -0,0 +1,8 @@ +void script_1873() { + if (globalint_200 > 0) { + script_3064(1); + setScriptCallOnGameloop(-1, "", new WidgetPointer(906,171)); + script_3097(); + } + return; +} diff --git a/dumps/scripts/1874.cs2 b/dumps/scripts/1874.cs2 new file mode 100644 index 0000000..8898161 --- /dev/null +++ b/dumps/scripts/1874.cs2 @@ -0,0 +1,5 @@ +void script_1874(int arg0,int arg1,int arg2) { + globalint_1097 = script_1401(arg0, 494, 0, globalstring_277); + script_1875(arg1, arg2, globalstring_277); + return; +} diff --git a/dumps/scripts/1875.cs2 b/dumps/scripts/1875.cs2 new file mode 100644 index 0000000..5cd20f2 --- /dev/null +++ b/dumps/scripts/1875.cs2 @@ -0,0 +1,29 @@ +void script_1875(int arg0,int arg1,string arg2) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + string svar1; + ivar2 = 59375766; + setWidgetPosition(script_1551(globalint_1097, 494, subtract(getWidgetActualX(new WidgetPointer(ivar2)), 15), arg2), getWidgetActualY(new WidgetPointer(arg1)), 0, 0, new WidgetPointer(arg1)); + ivar3 = subtract(getWidgetActualWidth(new WidgetPointer(ivar2)), 0); + ivar4 = strLength(arg2); + svar1 = ""; + if (globalint_1097 > 0) { + svar1 = substr(0, min(globalint_1097, ivar4), arg2); + } + ivar5 = subtract(getTextWidth(494, svar1), ivar3); + setWidgetPosition(0, 0, 0, 1, new WidgetPointer(arg0)); + setWidgetSize(max(getTextWidth(494, arg2), ivar3), getWidgetActualHeight(new WidgetPointer(arg0)), 0, 0, new WidgetPointer(arg0)); + if (ivar5 > 0) { + setWidgetPosition(subtract(getWidgetActualX(new WidgetPointer(arg0)), ivar5), getWidgetActualY(new WidgetPointer(arg0)), 0, 0, new WidgetPointer(arg0)); + setWidgetPosition(min(subtract(getWidgetActualX(new WidgetPointer(arg1)), ivar5), subtract(ivar3, 1)), getWidgetActualY(new WidgetPointer(arg1)), 0, 0, new WidgetPointer(arg1)); + } + if (hasWindowFocus()) { + setWidgetIsHidden(false, new WidgetPointer(arg1)); + } else { + setWidgetIsHidden(true, new WidgetPointer(arg1)); + } + setScriptCallOnGameloop(1876, getClientCycle(), new WidgetPointer(arg1), "iI", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1876.cs2 b/dumps/scripts/1876.cs2 new file mode 100644 index 0000000..3bd9dfc --- /dev/null +++ b/dumps/scripts/1876.cs2 @@ -0,0 +1,8 @@ +void script_1876(int arg0,int arg1) { + if ((mod(subtract(getClientCycle(), arg0), 40) < 20) && hasWindowFocus()) { + setWidgetIsHidden(false, new WidgetPointer(arg1)); + } else { + setWidgetIsHidden(true, new WidgetPointer(arg1)); + } + return; +} diff --git a/dumps/scripts/1877.cs2 b/dumps/scripts/1877.cs2 new file mode 100644 index 0000000..5d56838 --- /dev/null +++ b/dumps/scripts/1877.cs2 @@ -0,0 +1,4 @@ +void script_1877(int arg0,int arg1,int arg2,int arg3) { + script_1900(arg0, arg1, arg2, arg3); + return; +} diff --git a/dumps/scripts/1878.cs2 b/dumps/scripts/1878.cs2 new file mode 100644 index 0000000..0c52b22 --- /dev/null +++ b/dumps/scripts/1878.cs2 @@ -0,0 +1,5 @@ +void script_1878(int arg0,int arg1,int arg2) { + globalint_1097 = script_1401(add(arg0, getWidgetActualX(new WidgetPointer(arg1))), 3793, getWidgetActualX(new WidgetPointer(arg1)), globalstring_277); + script_1879(arg1, arg2, globalstring_277); + return; +} diff --git a/dumps/scripts/1879.cs2 b/dumps/scripts/1879.cs2 new file mode 100644 index 0000000..a44fd78 --- /dev/null +++ b/dumps/scripts/1879.cs2 @@ -0,0 +1,10 @@ +void script_1879(int arg0,int arg1,string arg2) { + setWidgetPosition(script_1551(globalint_1097, 3793, getWidgetActualX(new WidgetPointer(arg0)), arg2), 4, 0, 0, new WidgetPointer(arg1)); + if (hasWindowFocus()) { + setWidgetIsHidden(false, new WidgetPointer(arg1)); + } else { + setWidgetIsHidden(true, new WidgetPointer(arg1)); + } + setScriptCallOnGameloop(1880, getClientCycle(), new WidgetPointer(arg1), "iI", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/188.cs2 b/dumps/scripts/188.cs2 new file mode 100644 index 0000000..500a53d --- /dev/null +++ b/dumps/scripts/188.cs2 @@ -0,0 +1,4 @@ +void script_188(int arg0) { + setWidgetSprite(1025, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1880.cs2 b/dumps/scripts/1880.cs2 new file mode 100644 index 0000000..0426504 --- /dev/null +++ b/dumps/scripts/1880.cs2 @@ -0,0 +1,8 @@ +void script_1880(int arg0,int arg1) { + if ((mod(subtract(getClientCycle(), arg0), 40) < 20) && hasWindowFocus()) { + setWidgetIsHidden(false, new WidgetPointer(arg1)); + } else { + setWidgetIsHidden(true, new WidgetPointer(arg1)); + } + return; +} diff --git a/dumps/scripts/1881.cs2 b/dumps/scripts/1881.cs2 new file mode 100644 index 0000000..4332194 --- /dev/null +++ b/dumps/scripts/1881.cs2 @@ -0,0 +1,4 @@ +void script_1881() { + script_2172(1); + return; +} diff --git a/dumps/scripts/1882.cs2 b/dumps/scripts/1882.cs2 new file mode 100644 index 0000000..7ffe086 --- /dev/null +++ b/dumps/scripts/1882.cs2 @@ -0,0 +1,6 @@ +void script_1882(int arg0) { + if (((boolean)arg0)) { + script_2172(1); + } + return; +} diff --git a/dumps/scripts/1883.cs2 b/dumps/scripts/1883.cs2 new file mode 100644 index 0000000..60dd80f --- /dev/null +++ b/dumps/scripts/1883.cs2 @@ -0,0 +1,12 @@ +int script_1883(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5) { + deleteAllExtraChilds(new WidgetPointer(arg4)); + if (arg3 == -1) { + setWidgetIsHidden(true, new WidgetPointer(arg4)); + return arg0; + } + script_1885(arg0, arg1, arg3, arg4, arg5); + setWidgetIsHidden(false, new WidgetPointer(arg4)); + setScriptCallOnMouseEntered(1894, subtract(arg0, arg2), add(add(arg1, arg2), arg2), arg3, arg5, new WidgetPointer(arg4), "iiosI", new WidgetPointer(arg4)); + setScriptCallOnMouseExit(1884, arg0, arg1, arg3, arg5, new WidgetPointer(arg4), "iiosI", new WidgetPointer(arg4)); + return add(add(arg0, arg1), arg2); +} diff --git a/dumps/scripts/1884.cs2 b/dumps/scripts/1884.cs2 new file mode 100644 index 0000000..8c3ce9d --- /dev/null +++ b/dumps/scripts/1884.cs2 @@ -0,0 +1,4 @@ +void script_1884(int arg0,int arg1,int arg2,int arg3,string arg4) { + script_1885(arg0, arg1, arg2, arg3, arg4); + return; +} diff --git a/dumps/scripts/1885.cs2 b/dumps/scripts/1885.cs2 new file mode 100644 index 0000000..a3beefe --- /dev/null +++ b/dumps/scripts/1885.cs2 @@ -0,0 +1,33 @@ +void script_1885(int arg0,int arg1,int arg2,int arg3,string arg4) { + setWidgetSize(arg1, 64, 0, 0, new WidgetPointer(arg3)); + setWidgetPosition(arg0, 0, 0, 1, new WidgetPointer(arg3)); + script_333(arg3, 6116682, 3024411, 2, 4); + createExtraChild(new WidgetPointer(arg3), 5, getExtraChildGap(new WidgetPointer(arg3))); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(0, 4, 1, 0); + setWidgetShadowColor(new Color(48, 32, 32)); + setWidgetBorderThickness(1); + setItemOnWidgetMethod1205(arg2, 1); + createExtraChild(new WidgetPointer(arg3), 4, getExtraChildGap(new WidgetPointer(arg3))); + setWidgetSize(multiply(4, 2), subtract(add(4, 32), 3), 1, 1); + setWidgetPosition(0, 0, 1, 2); + setWidgetFont(494); + setWidgetTextAlignment(1, 1, 0); + setWidgetRGB(new Color(255, 152, 31)); + setWidgetUnknownBoolean(true); + setWidgetText(arg4); + createExtraChild(new WidgetPointer(arg3), 5, getExtraChildGap(new WidgetPointer(arg3))); + setWidgetSize(14, 0, 1, 1); + setWidgetPosition(0, 0, 1, 1); + setWidgetSprite(3872); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg3), 5, getExtraChildGap(new WidgetPointer(arg3))); + setWidgetSize(8, 0, 0, 1); + setWidgetPosition(0, 0, 0, 1); + setWidgetSprite(3871); + createExtraChild(new WidgetPointer(arg3), 5, getExtraChildGap(new WidgetPointer(arg3))); + setWidgetSize(8, 0, 0, 1); + setWidgetPosition(0, 0, 2, 1); + setWidgetSprite(3873); + return; +} diff --git a/dumps/scripts/1886.cs2 b/dumps/scripts/1886.cs2 new file mode 100644 index 0000000..1b06548 --- /dev/null +++ b/dumps/scripts/1886.cs2 @@ -0,0 +1,8 @@ +void script_1886(int arg0) { + if ((bitconfig_4895 == 3) && (standart_config_281 < 125)) { + setWidgetIsHidden(true, new WidgetPointer(arg0)); + } else { + setWidgetIsHidden(false, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/1887.cs2 b/dumps/scripts/1887.cs2 new file mode 100644 index 0000000..aa40280 --- /dev/null +++ b/dumps/scripts/1887.cs2 @@ -0,0 +1,4 @@ +void script_1887(int arg0,string arg1) { + script_3408(arg0, arg1); + return; +} diff --git a/dumps/scripts/1888.cs2 b/dumps/scripts/1888.cs2 new file mode 100644 index 0000000..062eff0 --- /dev/null +++ b/dumps/scripts/1888.cs2 @@ -0,0 +1,19 @@ +void script_1888() { + if (((boolean)globalint_1025)) { + return; + } + if ((((boolean)script_2728()) && ((boolean)bitconfig_6521)) && (standart_config_281 >= 1000)) { + if (globalint_94 > getClientCycle()) { + return; + } + globalint_94 = add(getClientCycle(), 1500); + if (((boolean)standart_config_1647)) { + messageType0("Your health is low! Run away from your attacker and speak to Xenia."); + } else { + messageType0("Your health is low! Find a safe place away from your attacker"); + messageType0("or eat some food to heal yourself."); + } + } + globalint_1025 = 1; + return; +} diff --git a/dumps/scripts/1889.cs2 b/dumps/scripts/1889.cs2 new file mode 100644 index 0000000..d3ffd03 --- /dev/null +++ b/dumps/scripts/1889.cs2 @@ -0,0 +1,6 @@ +string script_1889() { + if (((boolean)script_1431())) { + return "World " + intToStr(getWorldId()) + " (PvP)"; + } + return "World " + intToStr(getWorldId()); +} diff --git a/dumps/scripts/189.cs2 b/dumps/scripts/189.cs2 new file mode 100644 index 0000000..38ab376 --- /dev/null +++ b/dumps/scripts/189.cs2 @@ -0,0 +1,4 @@ +void script_189(int arg0) { + setWidgetSprite(1025, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1890.cs2 b/dumps/scripts/1890.cs2 new file mode 100644 index 0000000..f7be6c4 --- /dev/null +++ b/dumps/scripts/1890.cs2 @@ -0,0 +1,4 @@ +void script_1890(string arg0) { + message(11, 0, arg0); + return; +} diff --git a/dumps/scripts/1891.cs2 b/dumps/scripts/1891.cs2 new file mode 100644 index 0000000..99f84d9 --- /dev/null +++ b/dumps/scripts/1891.cs2 @@ -0,0 +1,6 @@ +int script_1891() { + if ((cs2method3612() > 0) && (cs2method3618() >= cs2method3616())) { + return 1; + } + return 0; +} diff --git a/dumps/scripts/1892.cs2 b/dumps/scripts/1892.cs2 new file mode 100644 index 0000000..f5d96e5 --- /dev/null +++ b/dumps/scripts/1892.cs2 @@ -0,0 +1,12 @@ +void script_1892(int arg0,int arg1) { + setScriptCallOnFriendListChange(1893, new WidgetPointer(arg0), new WidgetPointer(arg1), "II", new WidgetPointer(arg0)); + setWidgetScrollMax(0, 0, new WidgetPointer(arg0)); + cs2method2100(0, 0, new WidgetPointer(arg0)); + script_31(arg1, arg0, 5666, 5663, 5664, 5665, 5686, 5685); + script_1895(arg0, arg1); + if (cs2method6900()) { + setWidgetText(new WidgetPointer(1108,27), "Friends Chat channel:"); + setWidgetContextMenuOption(1, new WidgetPointer(1108,22), "Enable"); + } + return; +} diff --git a/dumps/scripts/1893.cs2 b/dumps/scripts/1893.cs2 new file mode 100644 index 0000000..f85f0c0 --- /dev/null +++ b/dumps/scripts/1893.cs2 @@ -0,0 +1,4 @@ +void script_1893(int arg0,int arg1) { + script_1895(arg0, arg1); + return; +} diff --git a/dumps/scripts/1894.cs2 b/dumps/scripts/1894.cs2 new file mode 100644 index 0000000..31acc40 --- /dev/null +++ b/dumps/scripts/1894.cs2 @@ -0,0 +1,35 @@ +void script_1894(int arg0,int arg1,int arg2,int arg3,string arg4) { + int ivar4; + setWidgetSize(arg1, 76, 0, 0, new WidgetPointer(arg3)); + setWidgetPosition(arg0, 0, 0, 1, new WidgetPointer(arg3)); + ivar4 = divide(subtract(76, 64), 2); + script_333(arg3, 6116682, 3024411, 4, 4); + createExtraChild(new WidgetPointer(arg3), 5, getExtraChildGap(new WidgetPointer(arg3))); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(0, add(4, ivar4), 1, 0); + setWidgetShadowColor(new Color(48, 32, 32)); + setWidgetBorderThickness(1); + setItemOnWidgetMethod1205(arg2, 1); + createExtraChild(new WidgetPointer(arg3), 4, getExtraChildGap(new WidgetPointer(arg3))); + setWidgetSize(subtract(add(multiply(4, 2), 70), 56), subtract(add(add(add(4, ivar4), 32), ivar4), 3), 1, 1); + setWidgetPosition(0, ivar4, 1, 2); + setWidgetFont(494); + setWidgetTextAlignment(1, 1, 0); + setWidgetRGB(new Color(255, 152, 31)); + setWidgetUnknownBoolean(true); + setWidgetText(arg4); + createExtraChild(new WidgetPointer(arg3), 5, getExtraChildGap(new WidgetPointer(arg3))); + setWidgetSize(58, 0, 1, 1); + setWidgetPosition(0, 0, 1, 1); + setWidgetSprite(3875); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg3), 5, getExtraChildGap(new WidgetPointer(arg3))); + setWidgetSize(30, 0, 0, 1); + setWidgetPosition(0, 0, 0, 1); + setWidgetSprite(3874); + createExtraChild(new WidgetPointer(arg3), 5, getExtraChildGap(new WidgetPointer(arg3))); + setWidgetSize(30, 0, 0, 1); + setWidgetPosition(0, 0, 2, 1); + setWidgetSprite(3876); + return; +} diff --git a/dumps/scripts/1895.cs2 b/dumps/scripts/1895.cs2 new file mode 100644 index 0000000..dd1720a --- /dev/null +++ b/dumps/scripts/1895.cs2 @@ -0,0 +1,144 @@ +void script_1895(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + string svar0; + string svar1; + string svar2; + string svar3; + int stack_dump0; + previousAndCurrentName(0,2,0) structdump_1; + deleteAllExtraChilds(new WidgetPointer(arg0)); + ivar2 = getFriendlistSize(); + if (ivar2 == -2) { + createExtraChild(new WidgetPointer(arg0), 4, 0); + setWidgetFont(496); + setWidgetText("Loading Friends List - Please wait..."); + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(138, 100, 0, 0); + setWidgetRGB(new Color(255, 255, 100)); + setWidgetUnknownBoolean(true); + return; + } + if (ivar2 == -1) { + createExtraChild(new WidgetPointer(arg0), 4, 0); + setWidgetFont(496); + setWidgetText("Connecting to Friend Server - Please wait..."); + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(138, 100, 0, 0); + setWidgetRGB(new Color(255, 255, 100)); + setWidgetUnknownBoolean(true); + return; + } + ivar3 = 0; + ivar4 = subtract(subtract(add(add(getWidgetActualX(new WidgetPointer(1108,12)), getWidgetActualX(new WidgetPointer(1108,7))), 14), getMaxLineWidth(2147483647, 496, " ")), getWidgetActualX(new WidgetPointer(1108,13))); + svar0 = ""; + svar1 = ""; + svar2 = ""; + ivar5 = 0; + svar3 = ""; + ivar6 = 0; + ivar7 = 0; + ivar8 = 0; + ivar9 = 0; + while (ivar3 < ivar2) { + ivar8 = multiply(ivar3, 3); + ivar9 = add(multiply(ivar3, 16), 2); + stack_dump0 = ivar3; + structdump_1 = getFriendName(stack_dump0); + svar3 = structdump_1.stringpart_1; + svar0 = structdump_1.stringpart_0; + if (stringMethod4107(svar3, "") != 0) { + ivar6 = 1; + } else { + ivar6 = 0; + } + if (((boolean)ivar6)) { + svar1 = " " + svar0; + } else { + svar1 = svar0; + } + createExtraChild(new WidgetPointer(arg0), 4, ivar8); + setWidgetFont(496); + setWidgetPosition(0, ivar9, 0, 0); + setWidgetSize(ivar4, 15, 0, 0); + setWidgetRGB(new Color(255, 255, 100)); + setWidgetUnknownBoolean(true); + if (getMaxLineWidth(2147483647, 496, svar1) > ivar4) { + while ((getMaxLineWidth(2147483647, 496, svar1 + "...") > ivar4) && (strLength(svar1) > 0)) { + svar1 = substr(0, subtract(strLength(svar1), 1), svar1); + } + setWidgetText(svar1 + "..."); + if (((boolean)ivar6)) { + ivar5 = add(getMaxLineWidth(2147483647, 496, "Last known as: " + svar3), 8); + if (ivar5 > getWidgetActualWidth(new WidgetPointer(arg0))) { + svar2 = svar0 + "
" + "Last known as:" + "
" + svar3; + } else { + svar2 = svar0 + "
" + "Last known as: " + svar3; + } + } else { + svar2 = svar0; + } + setScriptCallOnMouseOver(4538, new WidgetPointer(1108,34), new WidgetPointer(-32768,3), -1, svar2, 120, 3793, 3793, 16777215, 13, 4, 2, -2147483647, -2147483646, "IIisifdiiiiii"); + setScriptCallOnMouseExit(40, new WidgetPointer(1108,34), "I"); + } else if (((boolean)ivar6)) { + setWidgetText(svar1); + ivar5 = add(getMaxLineWidth(2147483647, 496, "Last known as: " + svar3), 8); + if (ivar5 > getWidgetActualWidth(new WidgetPointer(arg0))) { + svar2 = "Last known as:" + "
" + svar3; + } else { + svar2 = "Last known as: " + svar3; + } + setScriptCallOnMouseOver(4538, new WidgetPointer(1108,34), new WidgetPointer(-32768,3), ivar3, svar2, 120, 3793, 3793, 16777215, 13, 4, 2, -2147483647, -2147483646, "IIisifdiiiiii"); + setScriptCallOnMouseExit(40, new WidgetPointer(1108,34), "I"); + } else { + setWidgetText(svar0); + } + createExtraChild(new WidgetPointer(arg0), 5, add(ivar8, 1)); + setWidgetSprite(2313); + setWidgetSize(14, 14, 0, 0); + setWidgetPosition(0, ivar9, 0, 0); + if (((boolean)ivar6)) { + setWidgetHidden(1); + } + createExtraChild(new WidgetPointer(arg0), 4, add(ivar8, 2)); + setWidgetFont(496); + setWidgetText(script_196(getFriendRank(ivar3))); + setWidgetPosition(137, ivar9, 0, 0); + setWidgetSize(131, 15, 0, 0); + setWidgetRGB(new Color(255, 255, 255)); + setWidgetUnknownBoolean(true); + setWidgetContextMenuOption(1, "Not in Friends Chat"); + setWidgetContextMenuOption(2, "Recruit"); + setWidgetContextMenuOption(3, "Corporal"); + setWidgetContextMenuOption(4, "Sergeant"); + setWidgetContextMenuOption(5, "Lieutenant"); + setWidgetContextMenuOption(6, "Captain"); + setWidgetContextMenuOption(7, "General"); + setScriptCallOnClickContextMenu(197, ivar3, -2147483644, "ii"); + ivar3 = add(ivar3, 1); + } + ivar10 = 0; + ivar11 = 0; + if (ivar3 > 12) { + ivar10 = cs2method2601(new WidgetPointer(arg0)); + ivar11 = add(multiply(ivar3, 16), 4); + setWidgetScrollMax(0, ivar11, new WidgetPointer(arg0)); + if (ivar10 > ivar11) { + ivar10 = ivar11; + } + script_72(arg1, arg0, ivar10); + } else { + setWidgetScrollMax(0, 0, new WidgetPointer(arg0)); + cs2method2100(0, 0, new WidgetPointer(arg0)); + script_72(arg1, arg0, 0); + } + return; +} diff --git a/dumps/scripts/1896.cs2 b/dumps/scripts/1896.cs2 new file mode 100644 index 0000000..e3d64a7 --- /dev/null +++ b/dumps/scripts/1896.cs2 @@ -0,0 +1,12 @@ +void script_1896() { + int ivar0; + int ivar1; + ivar0 = 0; + ivar1 = 0; + if (((boolean)script_4468())) { + setWidgetIsHidden(false, new WidgetPointer(912,44)); + return; + } + script_2447(); + return; +} diff --git a/dumps/scripts/1897.cs2 b/dumps/scripts/1897.cs2 new file mode 100644 index 0000000..99a8940 --- /dev/null +++ b/dumps/scripts/1897.cs2 @@ -0,0 +1,3 @@ +void script_1897() { + return; +} diff --git a/dumps/scripts/1898.cs2 b/dumps/scripts/1898.cs2 new file mode 100644 index 0000000..1b1c7ad --- /dev/null +++ b/dumps/scripts/1898.cs2 @@ -0,0 +1,25 @@ +cs2func_script_1898_struct(2,0,0) script_1898(int arg0) { + switch (arg0) { + case 0: + return newstruct cs2func_script_1898_struct(globalint_523, globalint_533); + case 1: + return newstruct cs2func_script_1898_struct(globalint_524, globalint_534); + case 2: + return newstruct cs2func_script_1898_struct(globalint_525, globalint_535); + case 3: + return newstruct cs2func_script_1898_struct(globalint_526, globalint_536); + case 4: + return newstruct cs2func_script_1898_struct(globalint_527, globalint_537); + case 5: + return newstruct cs2func_script_1898_struct(globalint_528, globalint_538); + case 6: + return newstruct cs2func_script_1898_struct(globalint_529, globalint_539); + case 7: + return newstruct cs2func_script_1898_struct(globalint_530, globalint_540); + case 8: + return newstruct cs2func_script_1898_struct(globalint_531, globalint_541); + case 9: + return newstruct cs2func_script_1898_struct(globalint_532, globalint_542); + } + return newstruct cs2func_script_1898_struct(0, 0); +} diff --git a/dumps/scripts/1899.cs2 b/dumps/scripts/1899.cs2 new file mode 100644 index 0000000..54a1515 --- /dev/null +++ b/dumps/scripts/1899.cs2 @@ -0,0 +1,55 @@ +void script_1899(int arg0,int arg1,int arg2) { + int stack_dump0; + switch (arg0) { + case 0: + stack_dump0 = arg1; + globalint_533 = arg2; + globalint_523 = stack_dump0; + break; + case 1: + stack_dump0 = arg1; + globalint_534 = arg2; + globalint_524 = stack_dump0; + break; + case 2: + stack_dump0 = arg1; + globalint_535 = arg2; + globalint_525 = stack_dump0; + break; + case 3: + stack_dump0 = arg1; + globalint_536 = arg2; + globalint_526 = stack_dump0; + break; + case 4: + stack_dump0 = arg1; + globalint_537 = arg2; + globalint_527 = stack_dump0; + break; + case 5: + stack_dump0 = arg1; + globalint_538 = arg2; + globalint_528 = stack_dump0; + break; + case 6: + stack_dump0 = arg1; + globalint_539 = arg2; + globalint_529 = stack_dump0; + break; + case 7: + stack_dump0 = arg1; + globalint_540 = arg2; + globalint_530 = stack_dump0; + break; + case 8: + stack_dump0 = arg1; + globalint_541 = arg2; + globalint_531 = stack_dump0; + break; + case 9: + stack_dump0 = arg1; + globalint_542 = arg2; + globalint_532 = stack_dump0; + } + return; +} diff --git a/dumps/scripts/19.cs2 b/dumps/scripts/19.cs2 new file mode 100644 index 0000000..78aa504 --- /dev/null +++ b/dumps/scripts/19.cs2 @@ -0,0 +1,446 @@ +int script_19(int arg0,int arg1) { + int ivar2; + ivar2 = 0; + if (arg0 == 556) { + flow_1: + if (getItemAmtInContainer(94, 1381) > 0) { + return 99999999; + } + if (getItemAmtInContainer(94, 15598) > 0) { + return 99999999; + } + if (getItemAmtInContainer(94, 17009) > 0) { + return 99999999; + } + if (getItemAmtInContainer(94, 17011) > 0) { + return 99999999; + } + if (getItemAmtInContainer(94, 16169) > 0) { + return 99999999; + } + if (getItemAmtInContainer(94, 16170) > 0) { + return 99999999; + } + if (script_1(94, 1397) > 0) { + return 99999999; + } + if (script_1(94, 1405) > 0) { + return 99999999; + } + if (script_1(94, 19327) > 0) { + return 99999999; + } + if (script_1(94, 21777) > 0) { + return 99999999; + } + if (script_1(94, 21490) > 0) { + return 99999999; + } + if (script_1(94, 21496) > 0) { + return 99999999; + } + if (script_1(94, 21500) > 0) { + return 99999999; + } + ivar2 = add(add(add(add(add(add(getItemAmtInContainer(93, 556), getItemAmtInContainer(93, 17780)), getItemAmtInContainer(93, 16091)), script_1(93, 4697)), script_1(93, 4695)), script_1(93, 4696)), getItemAmtInContainer(93, 20941)); + IF ((((((arg1 == 12582946) || (arg1 == 12582951)) || (arg1 == 12582954)) || (arg1 == 62259232)) || (arg1 == 62259237)) || (arg1 == 62259236)) + GOTO flow_28 + GOTO flow_31 + flow_28: + IF ((getItemIdInSlot(94, 5) == 19671) || (getItemIdInSlot(94, 5) == 19867)) + GOTO flow_29 + IF ((getItemIdInSlot(94, 5) == 19865) && (globalint_1334 > 0)) + GOTO flow_30 + GOTO flow_31 + flow_29: + flow_30: + ivar2 = add(ivar2, multiply(globalint_1334, 2)); + flow_31: + IF ((arg1 == 12582957) || (arg1 == 62259241)) + GOTO flow_32 + GOTO flow_35 + flow_32: + IF ((getItemIdInSlot(94, 5) == 19671) || (getItemIdInSlot(94, 5) == 19867)) + GOTO flow_33 + IF ((getItemIdInSlot(94, 5) == 19865) && (globalint_1334 > 0)) + GOTO flow_34 + GOTO flow_35 + flow_33: + flow_34: + ivar2 = add(ivar2, multiply(globalint_1334, 3)); + flow_35: + IF ((((((arg1 == 12582961) || (arg1 == 12582964)) || (arg1 == 12582970)) || (arg1 == 62259242)) || (arg1 == 62259245)) || (arg1 == 62259243)) + GOTO flow_36 + GOTO flow_39 + flow_36: + IF ((getItemIdInSlot(94, 5) == 19671) || (getItemIdInSlot(94, 5) == 19867)) + GOTO flow_37 + IF ((getItemIdInSlot(94, 5) == 19865) && (globalint_1335 > 0)) + GOTO flow_38 + GOTO flow_39 + flow_37: + flow_38: + ivar2 = add(ivar2, multiply(globalint_1335, 3)); + flow_39: + IF ((arg1 == 12582975) || (arg1 == 62259247)) + GOTO flow_40 + GOTO flow_43 + flow_40: + IF ((getItemIdInSlot(94, 5) == 19671) || (getItemIdInSlot(94, 5) == 19867)) + GOTO flow_41 + IF ((getItemIdInSlot(94, 5) == 19865) && (globalint_1335 > 0)) + GOTO flow_42 + GOTO flow_43 + flow_41: + flow_42: + ivar2 = add(ivar2, multiply(globalint_1335, 4)); + flow_43: + IF ((((((((arg1 == 12582982) || (arg1 == 12582985)) || (arg1 == 12582989)) || (arg1 == 12582992)) || (arg1 == 62259248)) || (arg1 == 62259254)) || (arg1 == 62259249)) || (arg1 == 62259258)) + GOTO flow_44 + GOTO flow_47 + flow_44: + IF ((getItemIdInSlot(94, 5) == 19889) || (getItemIdInSlot(94, 5) == 19868)) + GOTO flow_45 + IF ((getItemIdInSlot(94, 5) == 19866) && (globalint_1402 > 0)) + GOTO flow_46 + GOTO flow_47 + flow_45: + flow_46: + ivar2 = add(ivar2, multiply(globalint_1402, 5)); + flow_47: + IF ((((((((arg1 == 12582996) || (arg1 == 12582999)) || (arg1 == 12583001)) || (arg1 == 12583003)) || (arg1 == 62259261)) || (arg1 == 62259263)) || (arg1 == 62259262)) || (arg1 == 62259267)) + GOTO flow_48 + GOTO flow_51 + flow_48: + IF ((getItemIdInSlot(94, 5) == 19889) || (getItemIdInSlot(94, 5) == 19868)) + GOTO flow_49 + IF ((getItemIdInSlot(94, 5) == 19866) && (globalint_1403 > 0)) + GOTO flow_50 + GOTO flow_51 + flow_49: + flow_50: + ivar2 = add(ivar2, multiply(globalint_1403, 7)); + flow_51: + if ((((((((bitconfig_4540 == 2) || (bitconfig_4540 == 3)) || (bitconfig_5493 != 0)) || (getItemIdInSlot(94, 1) == 15445)) || (getItemIdInSlot(94, 1) == 15446)) || (getItemIdInSlot(94, 1) == 15447)) || (getItemIdInSlot(94, 1) == 15448)) || (getItemIdInSlot(94, 1) == 15449)) { + ivar2 = add(ivar2, getItemAmtInContainer(93, 12850)); + } + return ivar2; + } + if (arg0 == 555) { + if (getItemAmtInContainer(94, 1383) > 0) { + return 99999999; + } + if (getItemAmtInContainer(94, 16997) > 0) { + return 99999999; + } + if (getItemAmtInContainer(94, 16999) > 0) { + return 99999999; + } + if (getItemAmtInContainer(94, 16163) > 0) { + return 99999999; + } + if (getItemAmtInContainer(94, 16164) > 0) { + return 99999999; + } + if (getItemAmtInContainer(94, 18346) > 0) { + return 99999999; + } + if (script_1(94, 1395) > 0) { + return 99999999; + } + if (script_1(94, 1403) > 0) { + return 99999999; + } + if (script_1(94, 6562) > 0) { + return 99999999; + } + if (script_1(94, 6563) > 0) { + return 99999999; + } + if (script_1(94, 11736) > 0) { + return 99999999; + } + if (script_1(94, 11738) > 0) { + return 99999999; + } + if (script_1(94, 19325) > 0) { + return 99999999; + } + if (script_1(94, 21491) > 0) { + return 99999999; + } + if (script_1(94, 21495) > 0) { + return 99999999; + } + if (script_1(94, 21499) > 0) { + return 99999999; + } + if (script_1(94, 21506) > 0) { + return 99999999; + } + if (script_1(94, 21507) > 0) { + return 99999999; + } + if (script_1(94, 21504) > 0) { + return 99999999; + } + if (script_1(94, 21505) > 0) { + return 99999999; + } + ivar2 = add(add(add(add(add(add(getItemAmtInContainer(93, 555), getItemAmtInContainer(93, 17781)), getItemAmtInContainer(93, 16092)), script_1(93, 4694)), script_1(93, 4695)), script_1(93, 4698)), getItemAmtInContainer(93, 20940)); + if ((((((((bitconfig_4540 == 2) || (bitconfig_4540 == 3)) || (bitconfig_5493 != 0)) || (getItemIdInSlot(94, 1) == 15445)) || (getItemIdInSlot(94, 1) == 15446)) || (getItemIdInSlot(94, 1) == 15447)) || (getItemIdInSlot(94, 1) == 15448)) || (getItemIdInSlot(94, 1) == 15449)) { + ivar2 = add(ivar2, getItemAmtInContainer(93, 12850)); + } + return ivar2; + } + if (arg0 == 557) { + if (getItemAmtInContainer(94, 1385) > 0) { + return 99999999; + } + if (getItemAmtInContainer(94, 17001) > 0) { + return 99999999; + } + if (getItemAmtInContainer(94, 17003) > 0) { + return 99999999; + } + if (getItemAmtInContainer(94, 16165) > 0) { + return 99999999; + } + if (getItemAmtInContainer(94, 16166) > 0) { + return 99999999; + } + if (script_1(94, 1399) > 0) { + return 99999999; + } + if (script_1(94, 1407) > 0) { + return 99999999; + } + if (script_1(94, 3053) > 0) { + return 99999999; + } + if (script_1(94, 3054) > 0) { + return 99999999; + } + if (script_1(94, 6562) > 0) { + return 99999999; + } + if (script_1(94, 6563) > 0) { + return 99999999; + } + if (script_1(94, 19329) > 0) { + return 99999999; + } + if (script_1(94, 21492) > 0) { + return 99999999; + } + if (script_1(94, 21497) > 0) { + return 99999999; + } + if (script_1(94, 21501) > 0) { + return 99999999; + } + if (script_1(94, 21502) > 0) { + return 99999999; + } + if (script_1(94, 21503) > 0) { + return 99999999; + } + if (script_1(94, 21504) > 0) { + return 99999999; + } + if (script_1(94, 21505) > 0) { + return 99999999; + } + ivar2 = add(add(add(add(add(add(getItemAmtInContainer(93, 557), getItemAmtInContainer(93, 17782)), getItemAmtInContainer(93, 16093)), script_1(93, 4696)), script_1(93, 4699)), script_1(93, 4698)), getItemAmtInContainer(93, 20942)); + if ((((((((bitconfig_4540 == 2) || (bitconfig_4540 == 3)) || (bitconfig_5493 != 0)) || (getItemIdInSlot(94, 1) == 15445)) || (getItemIdInSlot(94, 1) == 15446)) || (getItemIdInSlot(94, 1) == 15447)) || (getItemIdInSlot(94, 1) == 15448)) || (getItemIdInSlot(94, 1) == 15449)) { + ivar2 = add(ivar2, getItemAmtInContainer(93, 12850)); + } + return ivar2; + } + if (arg0 == 554) { + if (getItemAmtInContainer(94, 1387) > 0) { + return 99999999; + } + if (getItemAmtInContainer(94, 17005) > 0) { + return 99999999; + } + if (getItemAmtInContainer(94, 17007) > 0) { + return 99999999; + } + if (getItemAmtInContainer(94, 16167) > 0) { + return 99999999; + } + if (getItemAmtInContainer(94, 16168) > 0) { + return 99999999; + } + if (script_1(94, 1393) > 0) { + return 99999999; + } + if (script_1(94, 1401) > 0) { + return 99999999; + } + if (script_1(94, 3053) > 0) { + return 99999999; + } + if (script_1(94, 3054) > 0) { + return 99999999; + } + if (script_1(94, 11736) > 0) { + return 99999999; + } + if (script_1(94, 11738) > 0) { + return 99999999; + } + if (script_1(94, 19323) > 0) { + return 99999999; + } + if (script_1(94, 21493) > 0) { + return 99999999; + } + if (script_1(94, 21494) > 0) { + return 99999999; + } + if (script_1(94, 21498) > 0) { + return 99999999; + } + if (script_1(94, 21502) > 0) { + return 99999999; + } + if (script_1(94, 21503) > 0) { + return 99999999; + } + if (script_1(94, 21506) > 0) { + return 99999999; + } + if (script_1(94, 21507) > 0) { + return 99999999; + } + ivar2 = add(add(add(add(add(add(getItemAmtInContainer(93, 554), getItemAmtInContainer(93, 17783)), getItemAmtInContainer(93, 16094)), script_1(93, 4694)), script_1(93, 4697)), script_1(93, 4699)), getItemAmtInContainer(93, 20939)); + if ((((((((bitconfig_4540 == 2) || (bitconfig_4540 == 3)) || (bitconfig_5493 != 0)) || (getItemIdInSlot(94, 1) == 15445)) || (getItemIdInSlot(94, 1) == 15446)) || (getItemIdInSlot(94, 1) == 15447)) || (getItemIdInSlot(94, 1) == 15448)) || (getItemIdInSlot(94, 1) == 15449)) { + ivar2 = add(ivar2, getItemAmtInContainer(93, 12850)); + } + return ivar2; + } + if (arg0 == 8843) { + return add(script_1(94, 2416), script_1(94, 8841)); + } + if (arg0 == 4170) { + return add(add(add(add(add(add(script_1(94, 4170), script_1(94, 15486)), script_1(94, 15502)), script_1(94, 22207)), script_1(94, 22213)), script_1(94, 22211)), script_1(94, 22209)); + } + if (((arg0 == 1409) || (arg0 == 2415)) || (arg0 == 2417)) { + return script_1(94, arg0); + } + if (arg0 == 13867) { + if (script_1(94, 13869) > 0) { + return script_1(94, 13869); + } + if (script_1(94, 13941) > 0) { + return script_1(94, 13941); + } + if (script_1(94, 13943) > 0) { + return script_1(94, 13943); + } + return script_1(94, arg0); + } + if (arg0 == 21514) { + return script_1(94, 21514); + } + if (((((((((bitconfig_4540 == 2) || (bitconfig_4540 == 3)) || (bitconfig_5493 != 0)) || (getItemIdInSlot(94, 1) == 15445)) || (getItemIdInSlot(94, 1) == 15446)) || (getItemIdInSlot(94, 1) == 15447)) || (getItemIdInSlot(94, 1) == 15448)) || (getItemIdInSlot(94, 1) == 15449)) && ((((((((((arg0 == 559) || (arg0 == 558)) || (arg0 == 564)) || (arg0 == 562)) || (arg0 == 561)) || (arg0 == 560)) || (arg0 == 563)) || (arg0 == 566)) || (arg0 == 565)) || (arg0 == 9075))) { + return add(script_1(93, arg0), script_1(93, 12851)); + } + switch (arg0) { + flow_202: + case 559: + return add(add(add(getItemAmtInContainer(93, 559), getItemAmtInContainer(93, 17788)), getItemAmtInContainer(93, 16099)), getItemAmtInContainer(93, 20944)); + case 558: + return add(add(add(getItemAmtInContainer(93, 558), getItemAmtInContainer(93, 17784)), getItemAmtInContainer(93, 16095)), getItemAmtInContainer(93, 20943)); + case 564: + return add(add(getItemAmtInContainer(93, 564), getItemAmtInContainer(93, 17789)), getItemAmtInContainer(93, 16100)); + case 562: + IF ((((((((arg1 == 12582946) || (arg1 == 12582951)) || (arg1 == 12582954)) || (arg1 == 12582957)) || (arg1 == 62259232)) || (arg1 == 62259237)) || (arg1 == 62259236)) || (arg1 == 62259241)) + GOTO flow_206 + GOTO flow_209 + flow_206: + IF ((getItemIdInSlot(94, 5) == 19671) || (getItemIdInSlot(94, 5) == 19867)) + GOTO flow_207 + IF ((getItemIdInSlot(94, 5) == 19865) && (globalint_1334 > 0)) + GOTO flow_208 + GOTO flow_209 + flow_207: + flow_208: + return add(add(add(add(getItemAmtInContainer(93, 562), getItemAmtInContainer(93, 17785)), getItemAmtInContainer(93, 16096)), globalint_1334), getItemAmtInContainer(93, 20947)); + flow_209: + return add(add(add(getItemAmtInContainer(93, 562), getItemAmtInContainer(93, 17785)), getItemAmtInContainer(93, 16096)), getItemAmtInContainer(93, 20947)); + case 561: + if ((getItemIdInSlot(94, 3) == 18341) && (globalint_1234 > 0)) { + return add(add(add(add(getItemAmtInContainer(93, 561), getItemAmtInContainer(93, 17791)), getItemAmtInContainer(93, 16102)), globalint_1234), getItemAmtInContainer(93, 20946)); + } + return add(add(getItemAmtInContainer(93, 561), getItemAmtInContainer(93, 17791)), getItemAmtInContainer(93, 16102)); + case 560: + IF ((((((((arg1 == 12582961) || (arg1 == 12582964)) || (arg1 == 12582970)) || (arg1 == 12582975)) || (arg1 == 62259242)) || (arg1 == 62259245)) || (arg1 == 62259243)) || (arg1 == 62259247)) + GOTO flow_217 + GOTO flow_220 + flow_217: + IF ((getItemIdInSlot(94, 5) == 19671) || (getItemIdInSlot(94, 5) == 19867)) + GOTO flow_218 + IF ((getItemIdInSlot(94, 5) == 19865) && (globalint_1335 > 0)) + GOTO flow_219 + GOTO flow_220 + flow_218: + flow_219: + return add(add(add(add(getItemAmtInContainer(93, 560), getItemAmtInContainer(93, 17786)), getItemAmtInContainer(93, 16097)), globalint_1335), getItemAmtInContainer(93, 20945)); + flow_220: + IF ((((((((arg1 == 12582996) || (arg1 == 12582999)) || (arg1 == 12583001)) || (arg1 == 12583003)) || (arg1 == 62259261)) || (arg1 == 62259263)) || (arg1 == 62259262)) || (arg1 == 62259267)) + GOTO flow_221 + GOTO flow_224 + flow_221: + IF ((getItemIdInSlot(94, 5) == 19889) || (getItemIdInSlot(94, 5) == 19868)) + GOTO flow_222 + IF ((getItemIdInSlot(94, 5) == 19866) && (globalint_1403 > 0)) + GOTO flow_223 + GOTO flow_224 + flow_222: + flow_223: + return add(add(add(getItemAmtInContainer(93, 560), getItemAmtInContainer(93, 17786)), getItemAmtInContainer(93, 16097)), globalint_1403); + flow_224: + return add(add(add(getItemAmtInContainer(93, 560), getItemAmtInContainer(93, 17786)), getItemAmtInContainer(93, 16097)), getItemAmtInContainer(93, 20945)); + case 563: + if ((getItemIdInSlot(94, 3) == 18342) && (globalint_1235 > 0)) { + return add(add(add(add(getItemAmtInContainer(93, 563), getItemAmtInContainer(93, 17792)), getItemAmtInContainer(93, 16103)), globalint_1235), getItemAmtInContainer(93, 20948)); + } + return add(add(getItemAmtInContainer(93, 563), getItemAmtInContainer(93, 17792)), getItemAmtInContainer(93, 16103)); + case 566: + return add(add(script_1(93, 566), script_1(93, 17793)), script_1(93, 16104)); + case 565: + IF ((((((((arg1 == 12582982) || (arg1 == 12582985)) || (arg1 == 12582989)) || (arg1 == 12582992)) || (arg1 == 62259248)) || (arg1 == 62259254)) || (arg1 == 62259249)) || (arg1 == 62259258)) + GOTO flow_233 + GOTO flow_236 + flow_233: + IF ((getItemIdInSlot(94, 5) == 19889) || (getItemIdInSlot(94, 5) == 19868)) + GOTO flow_234 + IF ((getItemIdInSlot(94, 5) == 19866) && (globalint_1402 > 0)) + GOTO flow_235 + GOTO flow_236 + flow_234: + flow_235: + return add(add(add(getItemAmtInContainer(93, 565), getItemAmtInContainer(93, 17787)), getItemAmtInContainer(93, 16098)), globalint_1402); + flow_236: + IF ((((((((arg1 == 12582996) || (arg1 == 12582999)) || (arg1 == 12583001)) || (arg1 == 12583003)) || (arg1 == 62259261)) || (arg1 == 62259263)) || (arg1 == 62259262)) || (arg1 == 62259267)) + GOTO flow_237 + GOTO flow_240 + flow_237: + IF ((getItemIdInSlot(94, 5) == 19889) || (getItemIdInSlot(94, 5) == 19868)) + GOTO flow_238 + IF ((getItemIdInSlot(94, 5) == 19866) && (globalint_1403 > 0)) + GOTO flow_239 + GOTO flow_240 + flow_238: + flow_239: + return add(add(add(getItemAmtInContainer(93, 565), getItemAmtInContainer(93, 17787)), getItemAmtInContainer(93, 16098)), globalint_1403); + flow_240: + return add(add(script_1(93, 565), script_1(93, 17787)), script_1(93, 16098)); + case 9075: + return add(add(script_1(93, 9075), script_1(93, 17790)), script_1(93, 16101)); + } + return script_1(93, arg0); +} diff --git a/dumps/scripts/190.cs2 b/dumps/scripts/190.cs2 new file mode 100644 index 0000000..774647e --- /dev/null +++ b/dumps/scripts/190.cs2 @@ -0,0 +1,4 @@ +void script_190(int arg0) { + setWidgetSprite(1024, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1900.cs2 b/dumps/scripts/1900.cs2 new file mode 100644 index 0000000..9533ea8 --- /dev/null +++ b/dumps/scripts/1900.cs2 @@ -0,0 +1,63 @@ +void script_1900(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + string svar0; + globalint_159 = 0; + globalint_158 = 0; + ivar4 = 0; + while (setWidgetRegister(new WidgetPointer(arg0), ivar4)) { + if (ivar4 == arg2) { + setScriptCallOnMouseEntered(-1, ""); + setScriptCallOnMouseExit(-1, ""); + if (setWidgetRegister(new WidgetPointer(arg1), ivar4)) { + setWidgetHidden(0); + setWidgetRGB(new Color(150, 151, 119)); + } + } else { + setScriptCallOnMouseEntered(1082, subtract(arg3, 1), new WidgetPointer(arg1), ivar4, "iIi"); + setScriptCallOnMouseExit(1083, subtract(arg3, 1), new WidgetPointer(arg1), ivar4, "iIi"); + if (setWidgetRegister(new WidgetPointer(arg1), ivar4)) { + setWidgetHidden(1); + } + } + ivar4 = add(ivar4, 1); + } + globalint_128 = -1; + globalint_129 = 0; + globalstring_30 = ""; + svar0 = "Search phrases..."; + if (((boolean)globalint_126)) { + svar0 = "To " + globalstring_27 + ": " + "" + svar0; + } else if (globalint_126 == 2) { + svar0 = "[" + "" + cs2method3611() + "" + "]: " + "" + svar0; + } else if (globalint_126 == 8) { + if (cs2method3751()) { + svar0 = "[" + "" + cs2method3752() + "" + "]: " + "" + svar0; + } + } else if (globalint_126 == 10) { + if (cs2method3750()) { + svar0 = "[" + "" + cs2method3752() + "" + "]: " + "" + svar0; + } + } else { + svar0 = "" + svar0; + } + setWidgetIsHidden(true, new WidgetPointer(137,50)); + setScriptCallOnKeyPress(-1, "", new WidgetPointer(137,56)); + setWidgetIsHidden(false, new WidgetPointer(137,0)); + setWidgetIsHidden(true, new WidgetPointer(137,7)); + setWidgetIsHidden(true, new WidgetPointer(137,9)); + setWidgetIsHidden(false, new WidgetPointer(137,13)); + setWidgetIsHidden(true, new WidgetPointer(137,17)); + setWidgetIsHidden(true, new WidgetPointer(137,1)); + setWidgetIsHidden(false, new WidgetPointer(137,3)); + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(137,3)); + setWidgetFont(495, new WidgetPointer(137,3)); + setWidgetTextAlignment(0, 1, 0, new WidgetPointer(137,3)); + setWidgetText(new WidgetPointer(137,3), svar0); + setWidgetUnknownBoolean(false, new WidgetPointer(137,3)); + deleteAllExtraChilds(new WidgetPointer(137,16)); + setWidgetText(new WidgetPointer(137,14), "Search for: *"); + setScriptCallOnKeyPress(1901, -2147483640, false, new WidgetPointer(137,1), new WidgetPointer(137,14), new WidgetPointer(137,16), new WidgetPointer(137,15), 0, "izIIIIi", new WidgetPointer(137,13)); + setWidgetScrollMax(0, 0, new WidgetPointer(137,16)); + script_72(8978447, 8978448, 0); + return; +} diff --git a/dumps/scripts/1901.cs2 b/dumps/scripts/1901.cs2 new file mode 100644 index 0000000..1897892 --- /dev/null +++ b/dumps/scripts/1901.cs2 @@ -0,0 +1,118 @@ +void script_1901(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6) { + int ivar7; + int ivar8; + int ivar9; + int ivar10; + if (arg0 == 104) { + if (((boolean)arg6)) { + return; + } + if (globalint_128 <= 0) { + globalint_128 = subtract(arg6, 1); + } else { + globalint_128 = subtract(globalint_128, 1); + } + if (setWidgetRegister(new WidgetPointer(arg4), add(globalint_128, 1))) { + if (setWidgetRegister(new WidgetPointer(arg4), 0)) { + setWidgetPosition(getWidgetActualX(), getWidgetActualY(), 0, 0); + setWidgetSize(getWidgetActualWidth(), getWidgetActualHeight(), 0, 0); + setWidgetRGB(new Color(87, 126, 69)); + setWidgetFilled(1); + } + if (getWidgetActualY() < cs2method2601(new WidgetPointer(arg4))) { + script_72(arg5, arg4, subtract(cs2method2601(new WidgetPointer(arg4)), getWidgetActualHeight())); + } else { + if (add(getWidgetActualY(), getWidgetActualHeight()) > add(getWidgetActualHeight(new WidgetPointer(arg4)), cs2method2601(new WidgetPointer(arg4)))) { + script_72(arg5, arg4, getWidgetScrollMaxV(new WidgetPointer(arg4))); + } + } + } + return; + } + if (arg0 == 105) { + if (((boolean)arg6)) { + return; + } + if (globalint_128 == subtract(arg6, 1)) { + globalint_128 = 0; + } else { + globalint_128 = add(globalint_128, 1); + } + if (setWidgetRegister(new WidgetPointer(arg4), add(globalint_128, 1))) { + if (setWidgetRegister(new WidgetPointer(arg4), 0)) { + setWidgetPosition(getWidgetActualX(), getWidgetActualY(), 0, 0); + setWidgetSize(getWidgetActualWidth(), getWidgetActualHeight(), 0, 0); + setWidgetRGB(new Color(87, 126, 69)); + setWidgetFilled(1); + } + if (add(getWidgetActualY(), getWidgetActualHeight()) > add(getWidgetActualHeight(new WidgetPointer(arg4)), cs2method2601(new WidgetPointer(arg4)))) { + script_72(arg5, arg4, add(cs2method2601(new WidgetPointer(arg4)), getWidgetActualHeight())); + } else { + if (getWidgetActualY() < cs2method2601(new WidgetPointer(arg4))) { + script_72(arg5, arg4, 0); + } + } + } + return; + } + if (arg0 == 102) { + script_1050(globalint_126, globalstring_27); + return; + } + if (arg0 == 13) { + script_1054(); + return; + } + ivar7 = strLength(globalstring_30); + ivar8 = cs2method5071(0, globalstring_30); + ivar9 = 0; + ivar10 = -1; + if (arg0 == 84) { + if (globalint_128 < 0) { + if (ivar7 > 0) { + globalint_129 = 0; + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg3)); + script_1904(arg2, arg4, arg5); + } else { + script_1054(); + } + } else { + if (((ivar8 > 0) && setWidgetRegister(new WidgetPointer(arg4), add(globalint_128, 1))) && (ivar9 < ivar8)) { + while (true) { + ivar10 = cs2method5072(); + if (((boolean)stringMethod4107(getWidgetText(), cs2method5055(ivar10)))) { + script_1071(arg2, ivar10, 0); + return; + } + ivar9 = add(ivar9, 1); + } + } + } + return; + } + if (arg0 == 85) { + if (ivar7 > 0) { + globalstring_30 = substr(0, subtract(ivar7, 1), globalstring_30); + } else if (((boolean)globalint_127)) { + script_1054(); + } else { + globalint_128 = -1; + setWidgetIsHidden(true, new WidgetPointer(137,7)); + setWidgetIsHidden(true, new WidgetPointer(137,9)); + setWidgetIsHidden(true, new WidgetPointer(137,13)); + setWidgetIsHidden(false, new WidgetPointer(137,17)); + setWidgetIsHidden(false, new WidgetPointer(137,1)); + setWidgetIsHidden(true, new WidgetPointer(137,3)); + script_1068(arg2, 0); + return; + } + } else if (isValidChar(((char)arg1)) && (ivar7 < 80)) { + globalstring_30 = strRemoveEntities(concatChar(((char)arg1), globalstring_30)); + } else { + return; + } + setWidgetText(new WidgetPointer(arg3), "Search for: " + globalstring_30 + "*"); + globalint_129 = 50; + setScriptCallOnGameloop(1903, new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), "IIII", new WidgetPointer(arg3)); + return; +} diff --git a/dumps/scripts/1902.cs2 b/dumps/scripts/1902.cs2 new file mode 100644 index 0000000..4cbc4ba --- /dev/null +++ b/dumps/scripts/1902.cs2 @@ -0,0 +1,75 @@ +void script_1902(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + string svar0; + globalint_128 = -1; + ivar3 = cs2method5071(0, globalstring_30); + ivar4 = getWidgetActualWidth(new WidgetPointer(arg1)); + ivar5 = subtract(ivar4, 8); + if (ivar3 == -1) { + createExtraChild(new WidgetPointer(arg1), 4, 0); + setWidgetPosition(0, 48, 0, 0); + setWidgetSize(ivar4, 14, 0, 0); + setWidgetFont(495); + setWidgetText("Too many results. Please refine your search."); + setWidgetTextAlignment(1, 1, 0); + setWidgetRGB(new Color(0, 0, 0)); + setWidgetUnknownBoolean(false); + setWidgetScrollMax(0, 0, new WidgetPointer(arg1)); + script_1905(arg1, arg2); + return; + } + if (((boolean)ivar3)) { + createExtraChild(new WidgetPointer(arg1), 4, 0); + setWidgetPosition(0, 48, 0, 0); + setWidgetSize(ivar4, 14, 0, 0); + setWidgetFont(495); + setWidgetText("No matching items found."); + setWidgetTextAlignment(1, 1, 0); + setWidgetRGB(new Color(0, 0, 0)); + setWidgetUnknownBoolean(false); + setWidgetScrollMax(0, 0, new WidgetPointer(arg1)); + script_1905(arg1, arg2); + return; + } + ivar6 = 1; + ivar7 = cs2method5072(); + svar0 = ""; + createExtraChild(new WidgetPointer(arg1), 3, 0); + while (ivar7 != -1) { + if (stringMethod4107(svar0, cs2method5055(ivar7)) != 0) { + svar0 = cs2method5055(ivar7); + createExtraChild(new WidgetPointer(arg1), 4, ivar6); + setWidgetPosition(4, multiply(14, subtract(ivar6, 1)), 0, 0); + setWidgetSize(ivar5, 14, 0, 0); + setWidgetRGB(new Color(0, 0, 0)); + setWidgetText(cs2method5055(ivar7)); + setWidgetFont(495); + setWidgetUnknownBoolean(false); + setScriptCallOnMouseEntered(1906, ivar6, new WidgetPointer(arg1), "iI"); + setScriptCallOnMousePressed(1070, new WidgetPointer(arg0), ivar7, 0, "Iei"); + ivar6 = add(ivar6, 1); + } + ivar7 = cs2method5072(); + } + if (((boolean)ivar6)) { + createExtraChild(new WidgetPointer(arg1), 4, 0); + setWidgetPosition(0, 48, 0, 0); + setWidgetSize(ivar4, 14, 0, 0); + setWidgetFont(495); + setWidgetText("No matching items found."); + setWidgetTextAlignment(1, 1, 0); + setWidgetRGB(new Color(0, 0, 0)); + setWidgetUnknownBoolean(false); + setWidgetScrollMax(0, 0, new WidgetPointer(arg1)); + script_1905(arg1, arg2); + return; + } + setScriptCallOnKeyPress(1901, -2147483640, false, new WidgetPointer(137,1), new WidgetPointer(137,14), new WidgetPointer(137,16), new WidgetPointer(137,15), subtract(ivar6, 1), "izIIIIi", new WidgetPointer(137,13)); + setWidgetScrollMax(0, multiply(14, subtract(ivar6, 1)), new WidgetPointer(arg1)); + script_1905(arg1, arg2); + return; +} diff --git a/dumps/scripts/1903.cs2 b/dumps/scripts/1903.cs2 new file mode 100644 index 0000000..07e87d8 --- /dev/null +++ b/dumps/scripts/1903.cs2 @@ -0,0 +1,9 @@ +void script_1903(int arg0,int arg1,int arg2,int arg3) { + globalint_129 = subtract(globalint_129, 1); + if (globalint_129 > 0) { + return; + } + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg1)); + script_1904(arg0, arg2, arg3); + return; +} diff --git a/dumps/scripts/1904.cs2 b/dumps/scripts/1904.cs2 new file mode 100644 index 0000000..6e44917 --- /dev/null +++ b/dumps/scripts/1904.cs2 @@ -0,0 +1,10 @@ +void script_1904(int arg0,int arg1,int arg2) { + deleteAllExtraChilds(new WidgetPointer(arg1)); + if (strLength(globalstring_30) > 0) { + script_1902(arg0, arg1, arg2); + } else { + setWidgetScrollMax(0, 0, new WidgetPointer(arg1)); + script_1905(arg1, arg2); + } + return; +} diff --git a/dumps/scripts/1905.cs2 b/dumps/scripts/1905.cs2 new file mode 100644 index 0000000..438b858 --- /dev/null +++ b/dumps/scripts/1905.cs2 @@ -0,0 +1,19 @@ +void script_1905(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + ivar2 = getWidgetActualHeight(new WidgetPointer(arg0)); + ivar3 = getWidgetScrollMaxV(new WidgetPointer(arg0)); + ivar4 = subtract(ivar3, ivar2); + if (ivar4 < 0) { + ivar4 = 0; + } + ivar5 = cs2method2601(new WidgetPointer(arg0)); + if (ivar5 > ivar4) { + ivar5 = ivar4; + } + script_31(arg1, arg0, 792, 789, 790, 791, 773, 788); + script_72(arg1, arg0, ivar5); + return; +} diff --git a/dumps/scripts/1906.cs2 b/dumps/scripts/1906.cs2 new file mode 100644 index 0000000..faa7aaa --- /dev/null +++ b/dumps/scripts/1906.cs2 @@ -0,0 +1,12 @@ +void script_1906(int arg0,int arg1) { + if (setWidgetRegister(new WidgetPointer(arg1), arg0)) { + globalint_128 = subtract(arg0, 1); + if (setWidgetRegister(new WidgetPointer(arg1), 0)) { + setWidgetPosition(getWidgetActualX(), getWidgetActualY(), 0, 0); + setWidgetSize(getWidgetActualWidth(), getWidgetActualHeight(), 0, 0); + setWidgetRGB(new Color(87, 126, 69)); + setWidgetFilled(1); + } + } + return; +} diff --git a/dumps/scripts/1907.cs2 b/dumps/scripts/1907.cs2 new file mode 100644 index 0000000..1812be9 --- /dev/null +++ b/dumps/scripts/1907.cs2 @@ -0,0 +1,4 @@ +void script_1907() { + setScriptCallOnGlobalConfigChange(1908, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 17, "Y", new WidgetPointer(806,138)); + return; +} diff --git a/dumps/scripts/1908.cs2 b/dumps/scripts/1908.cs2 new file mode 100644 index 0000000..09f46e8 --- /dev/null +++ b/dumps/scripts/1908.cs2 @@ -0,0 +1,160 @@ +void script_1908() { + int ivar0; + string svar0; + ivar0 = 12; + svar0 = ""; + setWidgetSize(16, divide(multiply(divide(multiply(globalint_564, 100), ivar0), 16384), 100), 0, 2, new WidgetPointer(806,138)); + setWidgetSize(16, divide(multiply(divide(multiply(globalint_565, 100), ivar0), 16384), 100), 0, 2, new WidgetPointer(806,139)); + setWidgetSize(16, divide(multiply(divide(multiply(globalint_566, 100), ivar0), 16384), 100), 0, 2, new WidgetPointer(806,140)); + setWidgetSize(16, divide(multiply(divide(multiply(globalint_567, 100), ivar0), 16384), 100), 0, 2, new WidgetPointer(806,144)); + setWidgetSize(16, divide(multiply(divide(multiply(globalint_568, 100), ivar0), 16384), 100), 0, 2, new WidgetPointer(806,148)); + setWidgetSize(16, divide(multiply(divide(multiply(globalint_569, 100), ivar0), 16384), 100), 0, 2, new WidgetPointer(806,82)); + setWidgetSize(16, divide(multiply(divide(multiply(globalint_570, 100), ivar0), 16384), 100), 0, 2, new WidgetPointer(806,86)); + setWidgetSize(16, divide(multiply(divide(multiply(globalint_571, 100), ivar0), 16384), 100), 0, 2, new WidgetPointer(806,90)); + setWidgetSize(16, divide(multiply(divide(multiply(globalint_572, 100), ivar0), 16384), 100), 0, 2, new WidgetPointer(806,94)); + setWidgetSize(16, divide(multiply(divide(multiply(globalint_573, 100), ivar0), 16384), 100), 0, 2, new WidgetPointer(806,61)); + setWidgetSize(16, divide(multiply(divide(multiply(globalint_574, 100), ivar0), 16384), 100), 0, 2, new WidgetPointer(806,65)); + setWidgetSize(16, divide(multiply(divide(multiply(globalint_575, 100), ivar0), 16384), 100), 0, 2, new WidgetPointer(806,69)); + setWidgetSize(16, divide(multiply(divide(multiply(globalint_576, 100), ivar0), 16384), 100), 0, 2, new WidgetPointer(806,73)); + setWidgetSize(16, divide(multiply(divide(multiply(globalint_577, 100), ivar0), 16384), 100), 0, 2, new WidgetPointer(806,103)); + setWidgetSize(16, divide(multiply(divide(multiply(globalint_578, 100), ivar0), 16384), 100), 0, 2, new WidgetPointer(806,107)); + setWidgetSize(16, divide(multiply(divide(multiply(globalint_579, 100), ivar0), 16384), 100), 0, 2, new WidgetPointer(806,111)); + setWidgetSize(16, divide(multiply(divide(multiply(globalint_580, 100), ivar0), 16384), 100), 0, 2, new WidgetPointer(806,115)); + if (((boolean)globalint_564)) { + svar0 = "There are no class 1 clay locations in the area."; + } else if (((boolean)globalint_564)) { + svar0 = "There is 1 class 1 clay location in the area."; + } else { + svar0 = "There are " + intToStr(globalint_564) + " class 1 clay locations in the area."; + } + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(806,49), svar0, 25, 100, "IIsii", new WidgetPointer(806,138)); + if (((boolean)globalint_565)) { + svar0 = "There are no class 2 fishing locations in the area."; + } else if (((boolean)globalint_565)) { + svar0 = "There is 1 class 2 fishing location in the area."; + } else { + svar0 = "There are " + intToStr(globalint_565) + " class 2 fishing locations in the area."; + } + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(806,49), svar0, 25, 100, "IIsii", new WidgetPointer(806,139)); + if (((boolean)globalint_566)) { + svar0 = "There are no class 3 fishing locations in the area."; + } else if (((boolean)globalint_566)) { + svar0 = "There is 1 class 3 fishing location in the area."; + } else { + svar0 = "There are " + intToStr(globalint_566) + " class 3 fishing locations in the area."; + } + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(806,49), svar0, 25, 100, "IIsii", new WidgetPointer(806,140)); + if (((boolean)globalint_567)) { + svar0 = "There are no class 4 fishing locations in the area."; + } else if (((boolean)globalint_567)) { + svar0 = "There is 1 class 4 fishing location in the area."; + } else { + svar0 = "There are " + intToStr(globalint_567) + " class 4 fishing locations in the area."; + } + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(806,49), svar0, 25, 100, "IIsii", new WidgetPointer(806,144)); + if (((boolean)globalint_568)) { + svar0 = "There are no class 5 fishing locations in the area."; + } else if (((boolean)globalint_568)) { + svar0 = "There is 1 class 5 fishing location in the area."; + } else { + svar0 = "There are " + intToStr(globalint_568) + " class 5 fishing locations in the area."; + } + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(806,49), svar0, 25, 100, "IIsii", new WidgetPointer(806,148)); + if (((boolean)globalint_569)) { + svar0 = "There are no class 2 mining locations in the area."; + } else if (((boolean)globalint_569)) { + svar0 = "There is 1 class 2 mining location in the area."; + } else { + svar0 = "There are " + intToStr(globalint_569) + " class 2 mining locations in the area."; + } + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(806,49), svar0, 25, 100, "IIsii", new WidgetPointer(806,82)); + if (((boolean)globalint_570)) { + svar0 = "There are no class 3 mining locations in the area."; + } else if (((boolean)globalint_570)) { + svar0 = "There is 1 class 3 mining location in the area."; + } else { + svar0 = "There are " + intToStr(globalint_570) + " class 3 mining locations in the area."; + } + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(806,49), svar0, 25, 100, "IIsii", new WidgetPointer(806,86)); + if (((boolean)globalint_571)) { + svar0 = "There are no class 4 mining locations in the area."; + } else if (((boolean)globalint_571)) { + svar0 = "There is 1 class 4 mining location in the area."; + } else { + svar0 = "There are " + intToStr(globalint_571) + " class 4 mining locations in the area."; + } + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(806,49), svar0, 25, 100, "IIsii", new WidgetPointer(806,90)); + if (((boolean)globalint_572)) { + svar0 = "There are no class 5 mining locations in the area."; + } else if (((boolean)globalint_572)) { + svar0 = "There is 1 class 5 mining location in the area."; + } else { + svar0 = "There are " + intToStr(globalint_572) + " class 5 mining locations in the area."; + } + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(806,49), svar0, 25, 100, "IIsii", new WidgetPointer(806,94)); + if (((boolean)globalint_573)) { + svar0 = "There are no class 2 woodcutting locations in the area."; + } else if (((boolean)globalint_573)) { + svar0 = "There is 1 class 2 woodcutting location in the area."; + } else { + svar0 = "There are " + intToStr(globalint_573) + " class 2 woodcutting locations in the area."; + } + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(806,49), svar0, 25, 100, "IIsii", new WidgetPointer(806,61)); + if (((boolean)globalint_574)) { + svar0 = "There are no class 3 woodcutting locations in the area."; + } else if (((boolean)globalint_574)) { + svar0 = "There is 1 class 3 woodcutting location in the area."; + } else { + svar0 = "There are " + intToStr(globalint_574) + " class 3 woodcutting locations in the area."; + } + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(806,49), svar0, 25, 100, "IIsii", new WidgetPointer(806,65)); + if (((boolean)globalint_575)) { + svar0 = "There are no class 4 woodcutting locations in the area."; + } else if (((boolean)globalint_575)) { + svar0 = "There is 1 class 4 woodcutting location in the area."; + } else { + svar0 = "There are " + intToStr(globalint_575) + " class 4 woodcutting locations in the area."; + } + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(806,49), svar0, 25, 100, "IIsii", new WidgetPointer(806,69)); + if (((boolean)globalint_576)) { + svar0 = "There are no class 5 woodcutting locations in the area."; + } else if (((boolean)globalint_576)) { + svar0 = "There is 1 class 5 woodcutting location in the area."; + } else { + svar0 = "There are " + intToStr(globalint_576) + " class 5 woodcutting locations in the area."; + } + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(806,49), svar0, 25, 100, "IIsii", new WidgetPointer(806,73)); + if (((boolean)globalint_577)) { + svar0 = "There are no class 2 hunting locations in the area."; + } else if (((boolean)globalint_577)) { + svar0 = "There is 1 class 2 hunting location in the area."; + } else { + svar0 = "There are " + intToStr(globalint_577) + " class 2 hunting locations in the area."; + } + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(806,49), svar0, 25, 100, "IIsii", new WidgetPointer(806,103)); + if (((boolean)globalint_578)) { + svar0 = "There are no class 3 hunting locations in the area."; + } else if (((boolean)globalint_578)) { + svar0 = "There is 1 class 3 hunting location in the area."; + } else { + svar0 = "There are " + intToStr(globalint_578) + " class 3 hunting locations in the area."; + } + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(806,49), svar0, 25, 100, "IIsii", new WidgetPointer(806,107)); + if (((boolean)globalint_579)) { + svar0 = "There are no class 4 hunting locations in the area."; + } else if (((boolean)globalint_579)) { + svar0 = "There is 1 class 4 hunting location in the area."; + } else { + svar0 = "There are " + intToStr(globalint_579) + " class 4 hunting locations in the area."; + } + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(806,49), svar0, 25, 100, "IIsii", new WidgetPointer(806,111)); + if (((boolean)globalint_580)) { + svar0 = "There are no class 5 hunting locations in the area."; + } else if (((boolean)globalint_580)) { + svar0 = "There is 1 class 5 hunting location in the area."; + } else { + svar0 = "There are " + intToStr(globalint_580) + " class 5 hunting locations in the area."; + } + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(806,49), svar0, 25, 100, "IIsii", new WidgetPointer(806,115)); + return; +} diff --git a/dumps/scripts/1909.cs2 b/dumps/scripts/1909.cs2 new file mode 100644 index 0000000..9cb4049 --- /dev/null +++ b/dumps/scripts/1909.cs2 @@ -0,0 +1,8 @@ +void script_1909() { + if (isWidgetHidden(new WidgetPointer(806,122))) { + setWidgetIsHidden(false, new WidgetPointer(806,122)); + } else { + setWidgetIsHidden(true, new WidgetPointer(806,122)); + } + return; +} diff --git a/dumps/scripts/191.cs2 b/dumps/scripts/191.cs2 new file mode 100644 index 0000000..29ec58b --- /dev/null +++ b/dumps/scripts/191.cs2 @@ -0,0 +1,4 @@ +void script_191(int arg0) { + setWidgetSprite(1024, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1910.cs2 b/dumps/scripts/1910.cs2 new file mode 100644 index 0000000..4036e91 --- /dev/null +++ b/dumps/scripts/1910.cs2 @@ -0,0 +1,13 @@ +void script_1910() { + setWidgetIsHidden(false, new WidgetPointer(813,16)); + setWidgetIsHidden(false, new WidgetPointer(813,76)); + setWidgetIsHidden(true, new WidgetPointer(813,17)); + setWidgetIsHidden(true, new WidgetPointer(813,77)); + setWidgetIsHidden(true, new WidgetPointer(813,18)); + setWidgetIsHidden(true, new WidgetPointer(813,78)); + setWidgetIsHidden(true, new WidgetPointer(813,19)); + setWidgetIsHidden(true, new WidgetPointer(813,79)); + setWidgetIsHidden(true, new WidgetPointer(813,75)); + globalint_582 = 0; + return; +} diff --git a/dumps/scripts/1911.cs2 b/dumps/scripts/1911.cs2 new file mode 100644 index 0000000..7cd1fe9 --- /dev/null +++ b/dumps/scripts/1911.cs2 @@ -0,0 +1,13 @@ +void script_1911() { + setWidgetIsHidden(true, new WidgetPointer(813,16)); + setWidgetIsHidden(true, new WidgetPointer(813,76)); + setWidgetIsHidden(false, new WidgetPointer(813,17)); + setWidgetIsHidden(false, new WidgetPointer(813,77)); + setWidgetIsHidden(true, new WidgetPointer(813,18)); + setWidgetIsHidden(true, new WidgetPointer(813,78)); + setWidgetIsHidden(true, new WidgetPointer(813,19)); + setWidgetIsHidden(true, new WidgetPointer(813,79)); + setWidgetIsHidden(true, new WidgetPointer(813,75)); + globalint_582 = 0; + return; +} diff --git a/dumps/scripts/1912.cs2 b/dumps/scripts/1912.cs2 new file mode 100644 index 0000000..6c4a7cc --- /dev/null +++ b/dumps/scripts/1912.cs2 @@ -0,0 +1,13 @@ +void script_1912() { + setWidgetIsHidden(true, new WidgetPointer(813,16)); + setWidgetIsHidden(true, new WidgetPointer(813,76)); + setWidgetIsHidden(true, new WidgetPointer(813,17)); + setWidgetIsHidden(true, new WidgetPointer(813,77)); + setWidgetIsHidden(false, new WidgetPointer(813,18)); + setWidgetIsHidden(false, new WidgetPointer(813,78)); + setWidgetIsHidden(true, new WidgetPointer(813,19)); + setWidgetIsHidden(true, new WidgetPointer(813,79)); + setWidgetIsHidden(true, new WidgetPointer(813,75)); + globalint_582 = 0; + return; +} diff --git a/dumps/scripts/1913.cs2 b/dumps/scripts/1913.cs2 new file mode 100644 index 0000000..a872578 --- /dev/null +++ b/dumps/scripts/1913.cs2 @@ -0,0 +1,13 @@ +void script_1913() { + setWidgetIsHidden(true, new WidgetPointer(813,16)); + setWidgetIsHidden(true, new WidgetPointer(813,76)); + setWidgetIsHidden(true, new WidgetPointer(813,17)); + setWidgetIsHidden(true, new WidgetPointer(813,77)); + setWidgetIsHidden(true, new WidgetPointer(813,18)); + setWidgetIsHidden(true, new WidgetPointer(813,78)); + setWidgetIsHidden(false, new WidgetPointer(813,19)); + setWidgetIsHidden(false, new WidgetPointer(813,79)); + setWidgetIsHidden(true, new WidgetPointer(813,75)); + globalint_582 = 0; + return; +} diff --git a/dumps/scripts/1914.cs2 b/dumps/scripts/1914.cs2 new file mode 100644 index 0000000..8a13dd1 --- /dev/null +++ b/dumps/scripts/1914.cs2 @@ -0,0 +1,3 @@ +void script_1914(int arg0) { + return; +} diff --git a/dumps/scripts/1915.cs2 b/dumps/scripts/1915.cs2 new file mode 100644 index 0000000..2261c51 --- /dev/null +++ b/dumps/scripts/1915.cs2 @@ -0,0 +1,6 @@ +void script_1915() { + setWidgetIsHidden(true, new WidgetPointer(813,75)); + globalint_582 = 0; + setScriptCallOnGlobalConfigChange(1918, 583, 584, 585, 586, 587, 5, "Y", new WidgetPointer(813,27)); + return; +} diff --git a/dumps/scripts/1916.cs2 b/dumps/scripts/1916.cs2 new file mode 100644 index 0000000..c39aa84 --- /dev/null +++ b/dumps/scripts/1916.cs2 @@ -0,0 +1,23 @@ +void script_1916(int arg0) { + if ((arg0 == 53280867) && (globalint_583 > 0)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(arg0)); + return; + } + if ((arg0 == 53280869) && (globalint_584 > 0)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(arg0)); + return; + } + if ((arg0 == 53280871) && (globalint_585 > 0)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(arg0)); + return; + } + if ((arg0 == 53280873) && (globalint_586 > 0)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(arg0)); + return; + } + if ((arg0 == 53280875) && (globalint_587 > 0)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(arg0)); + return; + } + return; +} diff --git a/dumps/scripts/1917.cs2 b/dumps/scripts/1917.cs2 new file mode 100644 index 0000000..eba4592 --- /dev/null +++ b/dumps/scripts/1917.cs2 @@ -0,0 +1,38 @@ +void script_1917(int arg0) { + if (arg0 == 53280867) { + if (globalint_583 > 0) { + setWidgetRGB(new Color(200, 170, 100), new WidgetPointer(arg0)); + return; + } + setWidgetRGB(new Color(51, 51, 51), new WidgetPointer(arg0)); + } + if (arg0 == 53280869) { + if (globalint_584 > 0) { + setWidgetRGB(new Color(200, 170, 100), new WidgetPointer(arg0)); + return; + } + setWidgetRGB(new Color(51, 51, 51), new WidgetPointer(arg0)); + } + if (arg0 == 53280871) { + if (globalint_585 > 0) { + setWidgetRGB(new Color(200, 170, 100), new WidgetPointer(arg0)); + return; + } + setWidgetRGB(new Color(51, 51, 51), new WidgetPointer(arg0)); + } + if (arg0 == 53280873) { + if (globalint_586 > 0) { + setWidgetRGB(new Color(200, 170, 100), new WidgetPointer(arg0)); + return; + } + setWidgetRGB(new Color(51, 51, 51), new WidgetPointer(arg0)); + } + if (arg0 == 53280875) { + if (globalint_587 > 0) { + setWidgetRGB(new Color(200, 170, 100), new WidgetPointer(arg0)); + return; + } + setWidgetRGB(new Color(51, 51, 51), new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/1918.cs2 b/dumps/scripts/1918.cs2 new file mode 100644 index 0000000..28c5b90 --- /dev/null +++ b/dumps/scripts/1918.cs2 @@ -0,0 +1,4 @@ +void script_1918() { + script_1919(); + return; +} diff --git a/dumps/scripts/1919.cs2 b/dumps/scripts/1919.cs2 new file mode 100644 index 0000000..273c2f1 --- /dev/null +++ b/dumps/scripts/1919.cs2 @@ -0,0 +1,28 @@ +void script_1919() { + if (globalint_583 > 0) { + setWidgetRGB(new Color(200, 170, 100), new WidgetPointer(813,99)); + } else { + setWidgetRGB(new Color(51, 51, 51), new WidgetPointer(813,99)); + } + if (globalint_584 > 0) { + setWidgetRGB(new Color(200, 170, 100), new WidgetPointer(813,101)); + } else { + setWidgetRGB(new Color(51, 51, 51), new WidgetPointer(813,101)); + } + if (globalint_585 > 0) { + setWidgetRGB(new Color(200, 170, 100), new WidgetPointer(813,103)); + } else { + setWidgetRGB(new Color(51, 51, 51), new WidgetPointer(813,103)); + } + if (globalint_586 > 0) { + setWidgetRGB(new Color(200, 170, 100), new WidgetPointer(813,105)); + } else { + setWidgetRGB(new Color(51, 51, 51), new WidgetPointer(813,105)); + } + if (globalint_587 > 0) { + setWidgetRGB(new Color(200, 170, 100), new WidgetPointer(813,107)); + } else { + setWidgetRGB(new Color(51, 51, 51), new WidgetPointer(813,107)); + } + return; +} diff --git a/dumps/scripts/192.cs2 b/dumps/scripts/192.cs2 new file mode 100644 index 0000000..206c8f5 --- /dev/null +++ b/dumps/scripts/192.cs2 @@ -0,0 +1,93 @@ +void script_192() { + int ivar0; + int ivar1; + if (standart_config_281 < 1000) { + return; + } + ivar0 = cs2method5017(); + ivar1 = 0; + if (ivar0 > globalint_43) { + if (((boolean)globalint_41)) { + globalint_43 = ivar0; + return; + } + ivar0 = subtract(subtract(ivar0, globalint_43), 1); + if (ivar0 >= 100) { + ivar0 = 99; + } + while (ivar0 >= 0) { + ivar1 = cs2method5004(ivar0); + if (((boolean)script_90(ivar0, 0)) && ((boolean)script_506(ivar0))) { + switch (ivar1) { + case 0: + case 4: + case 27: + case 26: + case 29: + case 28: + case 110: + case 109: + case 117: + script_180(1); + break; + case 1: + case 2: + case 17: + case 116: + script_180(2); + break; + case 3: + case 5: + case 6: + case 7: + case 19: + case 18: + case 31: + case 30: + script_180(3); + break; + case 9: + case 11: + case 20: + case 107: + script_180(4); + break; + case 103: + case 100: + case 101: + case 111: + case 108: + case 106: + case 105: + case 118: + case 114: + case 113: + case 112: + script_180(5); + break; + case 102: + case 104: + script_180(6); + break; + case 42: + case 43: + case 41: + script_180(7); + break; + case 46: + case 44: + case 45: + script_180(7); + break; + case 115: + if (strLength(cs2method5003(ivar0)) > 1) { + script_180(1); + } + } + } + ivar0 = subtract(ivar0, 1); + } + globalint_43 = cs2method5017(); + } + return; +} diff --git a/dumps/scripts/1920.cs2 b/dumps/scripts/1920.cs2 new file mode 100644 index 0000000..a77526f --- /dev/null +++ b/dumps/scripts/1920.cs2 @@ -0,0 +1,15 @@ +void script_1920() { + setScriptCallOnGlobalStringChange(1921, 40, 1, "Y", new WidgetPointer(812,5)); + setScriptCallOnGlobalStringChange(1921, 41, 1, "Y", new WidgetPointer(812,6)); + setScriptCallOnGlobalStringChange(1921, 42, 1, "Y", new WidgetPointer(812,7)); + setScriptCallOnGlobalConfigChange(1921, 551, 1, "Y", new WidgetPointer(812,5)); + setScriptCallOnGlobalConfigChange(1921, 552, 1, "Y", new WidgetPointer(812,6)); + setScriptCallOnGlobalConfigChange(1921, 553, 1, "Y", new WidgetPointer(812,7)); + globalstring_40 = "You have no clan leader."; + globalstring_41 = "You have no allied clans."; + globalstring_42 = ""; + globalint_551 = 0; + globalint_552 = 0; + globalint_553 = 0; + return; +} diff --git a/dumps/scripts/1921.cs2 b/dumps/scripts/1921.cs2 new file mode 100644 index 0000000..1b1cdf4 --- /dev/null +++ b/dumps/scripts/1921.cs2 @@ -0,0 +1,18 @@ +void script_1921() { + if (globalint_551 > 0) { + setWidgetText(new WidgetPointer(812,5), concat(concat(globalint_551, concat(globalstring_40, " (")), ")")); + } else { + setWidgetText(new WidgetPointer(812,5), globalstring_40); + } + if (globalint_552 > 0) { + setWidgetText(new WidgetPointer(812,6), concat(concat(globalint_552, concat(globalstring_41, " (")), ")")); + } else { + setWidgetText(new WidgetPointer(812,6), globalstring_41); + } + if (globalint_553 > 0) { + setWidgetText(new WidgetPointer(812,7), concat(concat(globalint_553, concat(globalstring_42, " (")), ")")); + } else { + setWidgetText(new WidgetPointer(812,7), globalstring_42); + } + return; +} diff --git a/dumps/scripts/1922.cs2 b/dumps/scripts/1922.cs2 new file mode 100644 index 0000000..9be6f35 --- /dev/null +++ b/dumps/scripts/1922.cs2 @@ -0,0 +1,4 @@ +void script_1922() { + setScriptCallOnGlobalConfigChange(1923, 550, 554, 555, 3, "Y", new WidgetPointer(804,11)); + return; +} diff --git a/dumps/scripts/1923.cs2 b/dumps/scripts/1923.cs2 new file mode 100644 index 0000000..33ebc96 --- /dev/null +++ b/dumps/scripts/1923.cs2 @@ -0,0 +1,28 @@ +void script_1923() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + ivar0 = globalint_550; + ivar1 = globalint_554; + ivar2 = globalint_555; + ivar3 = 0; + if (((boolean)ivar0)) { + ivar1 = max(0, min(subtract(5, ivar1), 5)); + ivar2 = max(0, min(subtract(5, ivar2), 5)); + setWidgetText(new WidgetPointer(804,34), intToStr(ivar1)); + setWidgetText(new WidgetPointer(804,33), intToStr(ivar2)); + setWidgetIsHidden(false, new WidgetPointer(804,2)); + } else { + setWidgetIsHidden(true, new WidgetPointer(804,2)); + if (mod(ivar0, 100) != 0) { + ivar3 = 1; + } + ivar0 = divide(divide(multiply(ivar0, 60), 100), 60); + if (((boolean)ivar3)) { + ivar0 = add(ivar0, 1); + } + setWidgetText(new WidgetPointer(804,1), "Game start : " + intToStr(ivar0) + " mins"); + } + return; +} diff --git a/dumps/scripts/1924.cs2 b/dumps/scripts/1924.cs2 new file mode 100644 index 0000000..6a60b27 --- /dev/null +++ b/dumps/scripts/1924.cs2 @@ -0,0 +1,13 @@ +void script_1924() { + setWidgetText(new WidgetPointer(811,127), concat(intToStr(20), "
" + "points.")); + setWidgetText(new WidgetPointer(811,65), concat(intToStr(20), "
" + "points.")); + setWidgetText(new WidgetPointer(811,49), concat(intToStr(30), "
" + "points.")); + setWidgetText(new WidgetPointer(811,106), concat(intToStr(28), "
" + "points.")); + setWidgetText(new WidgetPointer(811,92), concat(intToStr(24), "
" + "points.")); + setWidgetText(new WidgetPointer(811,78), concat(intToStr(26), "
" + "points.")); + setItemOnWidgetMethod2200(14385, 1, new WidgetPointer(811,74)); + setWidget3DRotation(0, 0, 1274, 876, 625, 1715, new WidgetPointer(811,74)); + script_1929(); + globalint_544 = 0; + return; +} diff --git a/dumps/scripts/1925.cs2 b/dumps/scripts/1925.cs2 new file mode 100644 index 0000000..67375bb --- /dev/null +++ b/dumps/scripts/1925.cs2 @@ -0,0 +1,4 @@ +void script_1925(int arg0) { + script_1927(arg0); + return; +} diff --git a/dumps/scripts/1926.cs2 b/dumps/scripts/1926.cs2 new file mode 100644 index 0000000..fe56522 --- /dev/null +++ b/dumps/scripts/1926.cs2 @@ -0,0 +1,5 @@ +void script_1926(int arg0) { + script_1928(); + script_41(53149804); + return; +} diff --git a/dumps/scripts/1927.cs2 b/dumps/scripts/1927.cs2 new file mode 100644 index 0000000..ec108c8 --- /dev/null +++ b/dumps/scripts/1927.cs2 @@ -0,0 +1,17 @@ +void script_1927(int arg0) { + int ivar1; + ivar1 = 1; + while (ivar1 <= 6) { + if ((ivar1 == cs2method_3408(73, 105, 2027, arg0)) || (ivar1 == globalint_544)) { + setWidgetIsHidden(false, cs2method_3408(105, 73, 2031, ivar1)); + setWidgetRGB(new Color(255, 255, 255), cs2method_3408(105, 73, 2030, ivar1)); + setWidgetRGB(new Color(255, 255, 255), cs2method_3408(105, 73, 2029, ivar1)); + } else { + setWidgetIsHidden(true, cs2method_3408(105, 73, 2031, ivar1)); + setWidgetRGB(new Color(200, 170, 100), cs2method_3408(105, 73, 2030, ivar1)); + setWidgetRGB(new Color(200, 170, 100), cs2method_3408(105, 73, 2029, ivar1)); + } + ivar1 = add(ivar1, 1); + } + return; +} diff --git a/dumps/scripts/1928.cs2 b/dumps/scripts/1928.cs2 new file mode 100644 index 0000000..4308110 --- /dev/null +++ b/dumps/scripts/1928.cs2 @@ -0,0 +1,17 @@ +void script_1928() { + int ivar0; + ivar0 = 1; + while (ivar0 <= 6) { + if (ivar0 == globalint_544) { + setWidgetIsHidden(false, cs2method_3408(105, 73, 2031, ivar0)); + setWidgetRGB(new Color(255, 255, 255), cs2method_3408(105, 73, 2030, ivar0)); + setWidgetRGB(new Color(255, 255, 255), cs2method_3408(105, 73, 2029, ivar0)); + } else { + setWidgetIsHidden(true, cs2method_3408(105, 73, 2031, ivar0)); + setWidgetRGB(new Color(200, 170, 100), cs2method_3408(105, 73, 2030, ivar0)); + setWidgetRGB(new Color(200, 170, 100), cs2method_3408(105, 73, 2029, ivar0)); + } + ivar0 = add(ivar0, 1); + } + return; +} diff --git a/dumps/scripts/1929.cs2 b/dumps/scripts/1929.cs2 new file mode 100644 index 0000000..c488517 --- /dev/null +++ b/dumps/scripts/1929.cs2 @@ -0,0 +1,21 @@ +void script_1929() { + setWidgetIsHidden(true, new WidgetPointer(811,110)); + setWidgetRGB(new Color(200, 170, 100), new WidgetPointer(811,126)); + setWidgetRGB(new Color(200, 170, 100), new WidgetPointer(811,127)); + setWidgetIsHidden(true, new WidgetPointer(811,52)); + setWidgetRGB(new Color(200, 170, 100), new WidgetPointer(811,63)); + setWidgetRGB(new Color(200, 170, 100), new WidgetPointer(811,65)); + setWidgetIsHidden(true, new WidgetPointer(811,38)); + setWidgetRGB(new Color(200, 170, 100), new WidgetPointer(811,48)); + setWidgetRGB(new Color(200, 170, 100), new WidgetPointer(811,49)); + setWidgetIsHidden(true, new WidgetPointer(811,95)); + setWidgetRGB(new Color(200, 170, 100), new WidgetPointer(811,105)); + setWidgetRGB(new Color(200, 170, 100), new WidgetPointer(811,106)); + setWidgetIsHidden(true, new WidgetPointer(811,81)); + setWidgetRGB(new Color(200, 170, 100), new WidgetPointer(811,91)); + setWidgetRGB(new Color(200, 170, 100), new WidgetPointer(811,92)); + setWidgetIsHidden(true, new WidgetPointer(811,67)); + setWidgetRGB(new Color(200, 170, 100), new WidgetPointer(811,77)); + setWidgetRGB(new Color(200, 170, 100), new WidgetPointer(811,78)); + return; +} diff --git a/dumps/scripts/193.cs2 b/dumps/scripts/193.cs2 new file mode 100644 index 0000000..7a6c94a --- /dev/null +++ b/dumps/scripts/193.cs2 @@ -0,0 +1,92 @@ +int script_193(int arg0) { + int ivar1; + if (((boolean)globalint_41)) { + return 1; + } + ivar1 = cs2method5004(arg0); + if (ivar1 == -1) { + return 0; + } + if (ivar1 == 115) { + return 1; + } + switch (globalint_41) { + flow_7: + case 1: + if ((((((((((boolean)ivar1) || (ivar1 == 4)) || (ivar1 == 27)) || (ivar1 == 28)) || (ivar1 == 29)) || (ivar1 == 109)) || (ivar1 == 110)) || (ivar1 == 26)) || (ivar1 == 117)) { + return 1; + } + break; + case 2: + if (((((boolean)ivar1) || (ivar1 == 2)) || (ivar1 == 17)) || (ivar1 == 116)) { + return 1; + } + break; + case 3: + switch (ivar1) { + case 19: + case 3: + case 18: + case 5: + case 6: + case 7: + case 31: + case 30: + return 1; + } + break; + case 4: + switch (ivar1) { + case 20: + case 9: + case 11: + return 1; + } + break; + case 5: + switch (ivar1) { + case 118: + case 103: + case 100: + case 101: + case 114: + case 113: + case 112: + case 111: + case 108: + case 106: + case 105: + return 1; + } + if (((boolean)script_506(arg0))) { + return 1; + } + break; + case 6: + if ((ivar1 == 102) || (ivar1 == 104)) { + return 1; + } + break; + case 7: + SWITCH (ivar1) { + case 42: + GOTO flow_28 + case 43: + GOTO flow_28 + case 41: + GOTO flow_28 + case 46: + GOTO flow_28 + case 107: + GOTO flow_28 + case 44: + GOTO flow_28 + case 45: + GOTO flow_28 + } + break; + flow_28: + return 1; + } + return 0; +} diff --git a/dumps/scripts/1930.cs2 b/dumps/scripts/1930.cs2 new file mode 100644 index 0000000..d492761 --- /dev/null +++ b/dumps/scripts/1930.cs2 @@ -0,0 +1,17 @@ +int script_1930(int arg0) { + switch (arg0) { + case 1: + return 20; + case 2: + return 20; + case 3: + return 30; + case 4: + return 28; + case 5: + return 24; + case 6: + return 26; + } + return -1; +} diff --git a/dumps/scripts/1931.cs2 b/dumps/scripts/1931.cs2 new file mode 100644 index 0000000..be5b719 --- /dev/null +++ b/dumps/scripts/1931.cs2 @@ -0,0 +1,21 @@ +int script_1931(int arg0) { + if (arg0 == 53149717) { + return 1; + } + if (arg0 == 53149718) { + return 2; + } + if (arg0 == 53149719) { + return 3; + } + if (arg0 == 53149720) { + return 4; + } + if (arg0 == 53149721) { + return 5; + } + if (arg0 == 53149722) { + return 6; + } + return 0; +} diff --git a/dumps/scripts/1932.cs2 b/dumps/scripts/1932.cs2 new file mode 100644 index 0000000..71e8ad1 --- /dev/null +++ b/dumps/scripts/1932.cs2 @@ -0,0 +1,5 @@ +void script_1932() { + setWidgetIsHidden(false, new WidgetPointer(811,4)); + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(811,5)); + return; +} diff --git a/dumps/scripts/1933.cs2 b/dumps/scripts/1933.cs2 new file mode 100644 index 0000000..26957cd --- /dev/null +++ b/dumps/scripts/1933.cs2 @@ -0,0 +1,6 @@ +void script_1933() { + setWidgetIsHidden(true, new WidgetPointer(811,4)); + setWidgetRGB(new Color(200, 170, 100), new WidgetPointer(811,5)); + script_41(53149731); + return; +} diff --git a/dumps/scripts/1934.cs2 b/dumps/scripts/1934.cs2 new file mode 100644 index 0000000..ef3aa32 --- /dev/null +++ b/dumps/scripts/1934.cs2 @@ -0,0 +1,5 @@ +void script_1934() { + setWidgetIsHidden(false, new WidgetPointer(811,3)); + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(811,30)); + return; +} diff --git a/dumps/scripts/1935.cs2 b/dumps/scripts/1935.cs2 new file mode 100644 index 0000000..e43e758 --- /dev/null +++ b/dumps/scripts/1935.cs2 @@ -0,0 +1,6 @@ +void script_1935() { + setWidgetIsHidden(true, new WidgetPointer(811,3)); + setWidgetRGB(new Color(200, 170, 100), new WidgetPointer(811,30)); + script_41(53149731); + return; +} diff --git a/dumps/scripts/1936.cs2 b/dumps/scripts/1936.cs2 new file mode 100644 index 0000000..4ccc333 --- /dev/null +++ b/dumps/scripts/1936.cs2 @@ -0,0 +1,5 @@ +void script_1936(int arg0) { + globalint_544 = script_1931(arg0); + script_1927(arg0); + return; +} diff --git a/dumps/scripts/1937.cs2 b/dumps/scripts/1937.cs2 new file mode 100644 index 0000000..a80fe61 --- /dev/null +++ b/dumps/scripts/1937.cs2 @@ -0,0 +1,5 @@ +void script_1937() { + setWidgetText(new WidgetPointer(811,32), intToStr(globalint_549)); + script_1928(); + return; +} diff --git a/dumps/scripts/1938.cs2 b/dumps/scripts/1938.cs2 new file mode 100644 index 0000000..94ac83e --- /dev/null +++ b/dumps/scripts/1938.cs2 @@ -0,0 +1,9 @@ +void script_1938() { + globalint_556 = add(getClientCycle(), multiply(2000, 30)); + globalint_559 = 255; + globalint_560 = 0; + globalint_561 = 0; + globalint_562 = 0; + setWidgetUnknownBoolean(false, new WidgetPointer(809,15)); + return; +} diff --git a/dumps/scripts/1939.cs2 b/dumps/scripts/1939.cs2 new file mode 100644 index 0000000..fa4ed8c --- /dev/null +++ b/dumps/scripts/1939.cs2 @@ -0,0 +1,4 @@ +void script_1939() { + globalint_556 = add(getClientCycle(), multiply(globalint_558, 30)); + return; +} diff --git a/dumps/scripts/194.cs2 b/dumps/scripts/194.cs2 new file mode 100644 index 0000000..58e6ca4 --- /dev/null +++ b/dumps/scripts/194.cs2 @@ -0,0 +1,10 @@ +void script_194(int arg0) { + if (((boolean)arg0)) { + if (cs2method3612() > 0) { + sendUnknownVarByteEmptyFriendPacketMethod3620(); + } else { + script_111(); + } + } + return; +} diff --git a/dumps/scripts/1940.cs2 b/dumps/scripts/1940.cs2 new file mode 100644 index 0000000..00b1eb7 --- /dev/null +++ b/dumps/scripts/1940.cs2 @@ -0,0 +1,8 @@ +void script_1940() { + int ivar0; + ivar0 = add(getClientCycle(), multiply(globalint_557, 3000)); + if (ivar0 < globalint_556) { + globalint_556 = ivar0; + } + return; +} diff --git a/dumps/scripts/1941.cs2 b/dumps/scripts/1941.cs2 new file mode 100644 index 0000000..922b1ca --- /dev/null +++ b/dumps/scripts/1941.cs2 @@ -0,0 +1,35 @@ +void script_1941() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + ivar0 = add(add(add(standart_config_1332, standart_config_1334), standart_config_1337), multiply(2, subtract(standart_config_1333, standart_config_1335))); + setWidgetText(new WidgetPointer(809,17), "Score: " + intToStr(ivar0)); + if (((boolean)globalint_556)) { + return; + } + ivar1 = subtract(globalint_556, getClientCycle()); + ivar2 = divide(ivar1, 3000); + ivar3 = mod(divide(ivar1, 50), 60); + if ((ivar2 < 0) || (ivar3 < 0)) { + setWidgetText(new WidgetPointer(809,15), "Game ending"); + setWidgetUnknownBoolean(true, new WidgetPointer(809,15)); + script_1942(); + } else if (((boolean)ivar2) && ((boolean)ivar3)) { + setWidgetText(new WidgetPointer(809,15), "Game ending"); + } else if (ivar3 < 10) { + setWidgetText(new WidgetPointer(809,15), intToStr(ivar2) + ":0" + intToStr(ivar3)); + } else { + setWidgetText(new WidgetPointer(809,15), intToStr(ivar2) + ":" + intToStr(ivar3)); + } + if (ivar2 < 1) { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(809,15)); + setWidgetUnknownBoolean(true, new WidgetPointer(809,15)); + script_1942(); + } else { + if (isWidgetHidden(new WidgetPointer(809,18))) { + setWidgetIsHidden(true, new WidgetPointer(809,18)); + } + } + return; +} diff --git a/dumps/scripts/1942.cs2 b/dumps/scripts/1942.cs2 new file mode 100644 index 0000000..ebcd933 --- /dev/null +++ b/dumps/scripts/1942.cs2 @@ -0,0 +1,33 @@ +void script_1942() { + if (((boolean)globalint_560)) { + globalint_559 = min(255, add(globalint_559, 6)); + if (globalint_559 == 255) { + globalint_560 = 1; + } + } else { + if (((boolean)globalint_560)) { + globalint_559 = max(60, subtract(globalint_559, 6)); + if (globalint_559 == 60) { + globalint_560 = 0; + } + } + } + cs2method2103(globalint_559, new WidgetPointer(809,14)); + if (globalint_561 < 4) { + if (isWidgetHidden(new WidgetPointer(809,18))) { + globalint_562 = min(20, add(globalint_562, 1)); + if (globalint_562 == 20) { + globalint_562 = 0; + setWidgetIsHidden(false, new WidgetPointer(809,18)); + } + } else { + globalint_562 = min(35, add(globalint_562, 1)); + if (globalint_562 == 35) { + globalint_562 = 0; + setWidgetIsHidden(true, new WidgetPointer(809,18)); + globalint_561 = min(4, add(globalint_561, 1)); + } + } + } + return; +} diff --git a/dumps/scripts/1943.cs2 b/dumps/scripts/1943.cs2 new file mode 100644 index 0000000..04ea573 --- /dev/null +++ b/dumps/scripts/1943.cs2 @@ -0,0 +1,6 @@ +void script_1943() { + setWidgetIsHidden(false, new WidgetPointer(802,19)); + setWidgetText(new WidgetPointer(802,16), globalstring_43); + globalint_581 = 1; + return; +} diff --git a/dumps/scripts/1944.cs2 b/dumps/scripts/1944.cs2 new file mode 100644 index 0000000..a306539 --- /dev/null +++ b/dumps/scripts/1944.cs2 @@ -0,0 +1,6 @@ +void script_1944() { + setWidgetText(new WidgetPointer(802,16), ""); + setWidgetIsHidden(true, new WidgetPointer(802,19)); + globalint_581 = 0; + return; +} diff --git a/dumps/scripts/1945.cs2 b/dumps/scripts/1945.cs2 new file mode 100644 index 0000000..71beea4 --- /dev/null +++ b/dumps/scripts/1945.cs2 @@ -0,0 +1,6 @@ +void script_1945() { + int ivar0; + ivar0 = add(add(add(standart_config_1332, standart_config_1334), standart_config_1337), multiply(2, subtract(standart_config_1333, standart_config_1335))); + setWidgetText(new WidgetPointer(802,8), "Score: " + intToStr(ivar0)); + return; +} diff --git a/dumps/scripts/1946.cs2 b/dumps/scripts/1946.cs2 new file mode 100644 index 0000000..27736f1 --- /dev/null +++ b/dumps/scripts/1946.cs2 @@ -0,0 +1,99 @@ +void script_1946() { + int ivar0; + string svar0; + ivar0 = 0; + svar0 = ""; + setScriptCallOnMouseExit(40, new WidgetPointer(810,5), "I", new WidgetPointer(810,10)); + if (globalint_589 == 99999992) { + setWidgetText(new WidgetPointer(810,81), "You abandon the game!"); + setWidgetText(new WidgetPointer(810,17), "You abandon the game." + "
" + "
" + "The mystics don't seem happy and scowl at you, muttering unpleasant sentiments under their breath." + "
" + "
" + "You notice that you received no score as a result."); + setWidgetText(new WidgetPointer(810,58), "-100%"); + setWidgetText(new WidgetPointer(810,32), ""); + setWidgetText(new WidgetPointer(810,33), ""); + svar0 = "The awards tab is not available when you leave a game early."; + setScriptCallOnMouseOver(38, new WidgetPointer(810,10), new WidgetPointer(810,5), svar0, 25, 189, "IIsii", new WidgetPointer(810,10)); + } else { + if (((boolean)globalint_588)) { + setWidgetText(new WidgetPointer(810,32), intToStr(globalint_597)); + setWidgetText(new WidgetPointer(810,33), intToStr(globalint_598)); + } else { + setWidgetText(new WidgetPointer(810,32), intToStr(globalint_598)); + setWidgetText(new WidgetPointer(810,33), intToStr(globalint_597)); + } + if (globalint_588 == globalint_589) { + setWidgetText(new WidgetPointer(810,81), "Your valiant team takes the victory!"); + if (((boolean)ivar0)) { + setWidgetText(new WidgetPointer(810,17), "With the heroic conquest of all resources and facilities, your team have ripped success from the feeble fingers of your unworthy foes." + "
" + "
" + "The mystics stand in awe of your power, and you hear them praising you in excited whispers." + "
" + "
" + "You notice that they have increased your score as a reward."); + } else { + setWidgetText(new WidgetPointer(810,17), "The heroic, skillful and brave deeds of your team have ripped success from the feeble fingers of your unworthy foes." + "
" + "
" + "The mystics stand in awe of your power, and you hear them praising you in excited whispers." + "
" + "
" + "You notice that they have increased your score as a reward."); + } + setWidgetText(new WidgetPointer(810,58), "+10%"); + } else if (((boolean)globalint_589)) { + setWidgetText(new WidgetPointer(810,81), "The game was a draw!"); + setWidgetText(new WidgetPointer(810,17), "As if ordained by fate, the teams were equally brave and skillful, resulting in a draw." + "
" + "
" + "The mystics nod knowingly, and you hear them discussing how the balance of the universe is reflected beautifully in the conflict's outcome." + "
" + "
"); + setWidgetText(new WidgetPointer(810,58), "+0%"); + } else { + setWidgetText(new WidgetPointer(810,81), "The enemy team has defeated you!"); + if (((boolean)ivar0)) { + setWidgetText(new WidgetPointer(810,17), "Despite your best efforts, your team was beaten; the victory snatched away as the enemy took control of all resources and facilities." + "
" + "
" + "The mystics frown at you, and shake their heads sadly." + "
" + "
" + "You hear them arguing over whether they overestimated you, or if you were just unlucky."); + } + setWidgetText(new WidgetPointer(810,17), "Despite your best efforts, your team was beaten; the victory snatched away by your fearsome foes." + "
" + "
" + "The mystics frown at you, and shake their heads sadly." + "
" + "
" + "You hear them arguing over whether they overestimated you, or if you were just unlucky."); + setWidgetText(new WidgetPointer(810,58), "+0%"); + } + } + setWidgetText(new WidgetPointer(810,59), intToStr(globalint_590)); + setWidgetText(new WidgetPointer(810,59), intToStr(globalint_590)); + setWidgetText(new WidgetPointer(810,60), intToStr(globalint_591)); + setWidgetText(new WidgetPointer(810,61), intToStr(globalint_592)); + setWidgetText(new WidgetPointer(810,62), intToStr(globalint_593)); + setWidgetText(new WidgetPointer(810,23), intToStr(globalint_594)); + setWidgetText(new WidgetPointer(810,25), intToStr(globalint_595)); + if (globalint_589 != 99999992) { + setWidgetText(new WidgetPointer(810,63), intToStr(globalint_596)); + } else { + setWidgetText(new WidgetPointer(810,63), intToStr(0)); + } + if ((globalint_600 > 0) || (globalint_603 > 0)) { + setWidgetText(new WidgetPointer(810,136), intToStr(globalint_599)); + setWidgetText(new WidgetPointer(810,135), intToStr(globalint_600)); + setWidgetText(new WidgetPointer(810,139), intToStr(globalint_601)); + setWidgetText(new WidgetPointer(810,140), intToStr(globalint_602)); + setWidgetText(new WidgetPointer(810,138), intToStr(globalint_603)); + setWidgetText(new WidgetPointer(810,137), intToStr(globalint_604)); + setWidgetText(new WidgetPointer(810,141), intToStr(globalint_605)); + setWidgetText(new WidgetPointer(810,142), intToStr(globalint_606)); + script_1587(53084278, 53084303, 495, globalstring_44); + script_1587(53084277, 53084303, 495, globalstring_45); + script_1587(53084281, 53084303, 495, globalstring_46); + script_1587(53084282, 53084303, 495, globalstring_47); + script_1587(53084280, 53084303, 495, globalstring_48); + script_1587(53084279, 53084303, 495, globalstring_49); + script_1587(53084283, 53084303, 495, globalstring_50); + script_1587(53084284, 53084303, 495, globalstring_51); + if (globalint_607 > 0) { + setWidgetText(new WidgetPointer(810,127), intToStr(globalint_607)); + } + if (globalint_608 > 0) { + setWidgetText(new WidgetPointer(810,126), intToStr(globalint_608)); + } + if (globalint_609 > 0) { + setWidgetText(new WidgetPointer(810,130), intToStr(globalint_609)); + } + if (globalint_610 > 0) { + setWidgetText(new WidgetPointer(810,131), intToStr(globalint_610)); + } + if (globalint_611 > 0) { + setWidgetText(new WidgetPointer(810,129), intToStr(globalint_611)); + } + if (globalint_612 > 0) { + setWidgetText(new WidgetPointer(810,128), intToStr(globalint_612)); + } + if (globalint_613 > 0) { + setWidgetText(new WidgetPointer(810,132), intToStr(globalint_613)); + } + if (globalint_614 > 0) { + setWidgetText(new WidgetPointer(810,133), intToStr(globalint_614)); + } + } + return; +} diff --git a/dumps/scripts/1947.cs2 b/dumps/scripts/1947.cs2 new file mode 100644 index 0000000..2e89dfd --- /dev/null +++ b/dumps/scripts/1947.cs2 @@ -0,0 +1,11 @@ +void script_1947() { + if ((globalint_600 < 1) && (globalint_603 < 1)) { + messageType0("The awards tab is not available for this scoring."); + } else { + setWidgetIsHidden(true, new WidgetPointer(810,84)); + setWidgetIsHidden(false, new WidgetPointer(810,85)); + setWidgetIsHidden(true, new WidgetPointer(810,86)); + setWidgetIsHidden(false, new WidgetPointer(810,144)); + } + return; +} diff --git a/dumps/scripts/1948.cs2 b/dumps/scripts/1948.cs2 new file mode 100644 index 0000000..278b5d6 --- /dev/null +++ b/dumps/scripts/1948.cs2 @@ -0,0 +1,7 @@ +void script_1948() { + setWidgetIsHidden(false, new WidgetPointer(810,84)); + setWidgetIsHidden(true, new WidgetPointer(810,85)); + setWidgetIsHidden(false, new WidgetPointer(810,86)); + setWidgetIsHidden(true, new WidgetPointer(810,144)); + return; +} diff --git a/dumps/scripts/1949.cs2 b/dumps/scripts/1949.cs2 new file mode 100644 index 0000000..dd05354 --- /dev/null +++ b/dumps/scripts/1949.cs2 @@ -0,0 +1,9 @@ +void script_1949(int arg0,int arg1,int arg2,int arg3) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetRGB(new Color(arg2)); + if (arg3 != -1) { + script_41(arg3); + } + } + return; +} diff --git a/dumps/scripts/195.cs2 b/dumps/scripts/195.cs2 new file mode 100644 index 0000000..3353a86 --- /dev/null +++ b/dumps/scripts/195.cs2 @@ -0,0 +1,18 @@ +void script_195(int arg0,int arg1) { + int ivar2; + setScriptCallOnClanListChange(203, new WidgetPointer(-32768,3), "I", new WidgetPointer(arg0)); + setScriptCallOnFriendListChange(203, new WidgetPointer(-32768,3), "I", new WidgetPointer(arg0)); + script_1600(); + deleteAllExtraChilds(new WidgetPointer(1109,4)); + ivar2 = 0; + while (ivar2 < 50) { + createExtraChild(new WidgetPointer(1109,4), 3, ivar2); + setWidgetSize(0, 19, 1, 0); + setWidgetPosition(0, multiply(multiply(ivar2, 2), 19), 1, 0); + setWidgetRGB(new Color(35, 34, 32)); + setWidgetFilled(1); + cs2method2103(128); + ivar2 = add(ivar2, 1); + } + return; +} diff --git a/dumps/scripts/1950.cs2 b/dumps/scripts/1950.cs2 new file mode 100644 index 0000000..a85a079 --- /dev/null +++ b/dumps/scripts/1950.cs2 @@ -0,0 +1,6 @@ +void script_1950(int arg0) { + setWidgetSprite(3153, new WidgetPointer(arg0)); + setScriptCallOnMousePressed(1242, new WidgetPointer(-32768,3), "I", new WidgetPointer(arg0)); + cs2method5512(); + return; +} diff --git a/dumps/scripts/1951.cs2 b/dumps/scripts/1951.cs2 new file mode 100644 index 0000000..792faad --- /dev/null +++ b/dumps/scripts/1951.cs2 @@ -0,0 +1,10 @@ +void script_1951() { + if (((boolean)globalint_616)) { + setWidgetIsHidden(false, new WidgetPointer(745,1)); + } else { + globalint_616 = 0; + setWidgetIsHidden(true, new WidgetPointer(745,1)); + script_1952(); + } + return; +} diff --git a/dumps/scripts/1952.cs2 b/dumps/scripts/1952.cs2 new file mode 100644 index 0000000..83ec40e --- /dev/null +++ b/dumps/scripts/1952.cs2 @@ -0,0 +1,17 @@ +void script_1952() { + int ivar0; + int ivar1; + ivar0 = -1; + ivar1 = -1; + if (getDisplayMode() < 2) { + ivar0 = 35913744; + ivar1 = 35913953; + } else { + ivar0 = 48889872; + ivar1 = 48890023; + } + setWidgetText(new WidgetPointer(ivar1), ""); + setWidgetIsHidden(true, new WidgetPointer(ivar0)); + globalint_2 = 0; + return; +} diff --git a/dumps/scripts/1953.cs2 b/dumps/scripts/1953.cs2 new file mode 100644 index 0000000..ed30729 --- /dev/null +++ b/dumps/scripts/1953.cs2 @@ -0,0 +1,187 @@ +void script_1953() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + ivar0 = getItemAmtInContainer(93, 2015); + ivar1 = getItemAmtInContainer(93, 2019); + ivar2 = getItemAmtInContainer(93, 2017); + ivar3 = getItemAmtInContainer(93, 2108); + ivar4 = getItemAmtInContainer(93, 2102); + ivar5 = getItemAmtInContainer(93, 2128); + ivar6 = getItemAmtInContainer(93, 2120); + ivar7 = getItemAmtInContainer(93, 1973); + ivar8 = getItemAmtInContainer(93, 2114); + ivar9 = getItemAmtInContainer(93, 2126); + ivar10 = getItemAmtInContainer(93, 1927); + ivar11 = getItemAmtInContainer(93, 2021); + if ((((ivar0 >= 2) && (ivar1 >= 1)) && ((ivar3 >= 1) && (ivar6 >= 1))) && (ivar4 >= 1)) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(436,81)); + } else { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(436,81)); + } + if ((ivar0 >= 1) && (ivar6 >= 3)) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(436,82)); + } else { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(436,82)); + } + if (((ivar8 >= 1) && (ivar4 >= 1)) && (ivar3 >= 1)) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(436,83)); + } else { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(436,83)); + } + if (((ivar8 >= 2) && (ivar4 >= 1)) && (ivar3 >= 1)) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(436,84)); + } else { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(436,84)); + } + if (((ivar0 >= 1) && (ivar1 >= 1)) && (ivar9 >= 1)) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(436,85)); + } else { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(436,85)); + } + if (((ivar2 >= 1) && (ivar5 >= 1)) && ((ivar10 >= 1) && (ivar7 >= 1))) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(436,86)); + } else { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(436,86)); + } + if ((((ivar0 >= 1) && (ivar1 >= 1)) && ((ivar11 >= 1) && (ivar4 >= 2))) && (ivar3 >= 1)) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(436,87)); + } else { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(436,87)); + } + if (getItemAmtInContainer(93, 2114) > 0) { + setItemOnWidgetMethod2200(2114, 100, new WidgetPointer(436,24)); + } else { + setItemOnWidgetMethod2200(9497, 100, new WidgetPointer(436,24)); + } + if (getItemAmtInContainer(93, 2102) > 0) { + setItemOnWidgetMethod2200(2102, 140, new WidgetPointer(436,25)); + } else { + setItemOnWidgetMethod2200(9492, 140, new WidgetPointer(436,25)); + } + if (getItemAmtInContainer(93, 2108) > 0) { + setItemOnWidgetMethod2200(2108, 140, new WidgetPointer(436,26)); + } else { + setItemOnWidgetMethod2200(9493, 140, new WidgetPointer(436,26)); + } + if (getItemAmtInContainer(93, 2015) > 1) { + setItemOnWidgetMethod2200(2015, 120, new WidgetPointer(436,4)); + } else { + setItemOnWidgetMethod2200(9491, 120, new WidgetPointer(436,4)); + } + if (getItemAmtInContainer(93, 2019) > 0) { + setItemOnWidgetMethod2200(2019, 120, new WidgetPointer(436,5)); + } else { + setItemOnWidgetMethod2200(9491, 120, new WidgetPointer(436,5)); + } + if (getItemAmtInContainer(93, 2108) > 0) { + setItemOnWidgetMethod2200(2108, 140, new WidgetPointer(436,6)); + } else { + setItemOnWidgetMethod2200(9493, 140, new WidgetPointer(436,6)); + } + if (getItemAmtInContainer(93, 2120) > 0) { + setItemOnWidgetMethod2200(2120, 140, new WidgetPointer(436,7)); + } else { + setItemOnWidgetMethod2200(9555, 140, new WidgetPointer(436,7)); + } + if (getItemAmtInContainer(93, 2102) > 0) { + setItemOnWidgetMethod2200(2102, 140, new WidgetPointer(436,8)); + } else { + setItemOnWidgetMethod2200(9492, 140, new WidgetPointer(436,8)); + } + if (getItemAmtInContainer(93, 2015) > 0) { + setItemOnWidgetMethod2200(2015, 120, new WidgetPointer(436,17)); + } else { + setItemOnWidgetMethod2200(9491, 120, new WidgetPointer(436,17)); + } + if (getItemAmtInContainer(93, 2120) > 2) { + setItemOnWidgetMethod2200(2120, 120, new WidgetPointer(436,18)); + } else { + setItemOnWidgetMethod2200(9555, 140, new WidgetPointer(436,18)); + } + if (getItemAmtInContainer(93, 2015) > 0) { + setItemOnWidgetMethod2200(2015, 120, new WidgetPointer(436,62)); + } else { + setItemOnWidgetMethod2200(9491, 120, new WidgetPointer(436,62)); + } + if (getItemAmtInContainer(93, 2019) > 0) { + setItemOnWidgetMethod2200(2019, 120, new WidgetPointer(436,64)); + } else { + setItemOnWidgetMethod2200(9491, 120, new WidgetPointer(436,64)); + } + if (getItemAmtInContainer(93, 2021) > 0) { + setItemOnWidgetMethod2200(2021, 120, new WidgetPointer(436,63)); + } else { + setItemOnWidgetMethod2200(9556, 120, new WidgetPointer(436,63)); + } + if (getItemAmtInContainer(93, 2108) > 0) { + setItemOnWidgetMethod2200(2108, 140, new WidgetPointer(436,65)); + } else { + setItemOnWidgetMethod2200(9493, 140, new WidgetPointer(436,65)); + } + if (getItemAmtInContainer(93, 2102) > 1) { + setItemOnWidgetMethod2200(2102, 140, new WidgetPointer(436,66)); + } else { + setItemOnWidgetMethod2200(9492, 140, new WidgetPointer(436,66)); + } + if (getItemAmtInContainer(93, 2017) > 0) { + setItemOnWidgetMethod2200(2017, 120, new WidgetPointer(436,51)); + } else { + setItemOnWidgetMethod2200(9491, 120, new WidgetPointer(436,51)); + } + if (getItemAmtInContainer(93, 2128) > 0) { + setItemOnWidgetMethod2200(2128, 120, new WidgetPointer(436,52)); + } else { + setItemOnWidgetMethod2200(9494, 120, new WidgetPointer(436,52)); + } + if (getItemAmtInContainer(93, 1973) > 0) { + setItemOnWidgetMethod2200(1973, 140, new WidgetPointer(436,54)); + } else { + setItemOnWidgetMethod2200(9507, 140, new WidgetPointer(436,54)); + } + if (getItemAmtInContainer(93, 1927) > 0) { + setItemOnWidgetMethod2200(1927, 100, new WidgetPointer(436,53)); + } else { + setItemOnWidgetMethod2200(9495, 100, new WidgetPointer(436,53)); + } + if (getItemAmtInContainer(93, 2114) > 1) { + setItemOnWidgetMethod2200(2114, 100, new WidgetPointer(436,33)); + } else { + setItemOnWidgetMethod2200(9497, 100, new WidgetPointer(436,33)); + } + if (getItemAmtInContainer(93, 2102) > 0) { + setItemOnWidgetMethod2200(2102, 140, new WidgetPointer(436,34)); + } else { + setItemOnWidgetMethod2200(9492, 140, new WidgetPointer(436,34)); + } + if (getItemAmtInContainer(93, 2108) > 0) { + setItemOnWidgetMethod2200(2108, 140, new WidgetPointer(436,35)); + } else { + setItemOnWidgetMethod2200(9493, 140, new WidgetPointer(436,35)); + } + if (getItemAmtInContainer(93, 2015) > 0) { + setItemOnWidgetMethod2200(2015, 120, new WidgetPointer(436,42)); + } else { + setItemOnWidgetMethod2200(9491, 120, new WidgetPointer(436,42)); + } + if (getItemAmtInContainer(93, 2019) > 0) { + setItemOnWidgetMethod2200(2019, 120, new WidgetPointer(436,43)); + } else { + setItemOnWidgetMethod2200(9491, 120, new WidgetPointer(436,43)); + } + if (getItemAmtInContainer(93, 2126) > 0) { + setItemOnWidgetMethod2200(2126, 140, new WidgetPointer(436,44)); + } else { + setItemOnWidgetMethod2200(9496, 140, new WidgetPointer(436,44)); + } + return; +} diff --git a/dumps/scripts/1954.cs2 b/dumps/scripts/1954.cs2 new file mode 100644 index 0000000..7546d30 --- /dev/null +++ b/dumps/scripts/1954.cs2 @@ -0,0 +1,4 @@ +void script_1954() { + setWidgetIsHidden(true, new WidgetPointer(809,18)); + return; +} diff --git a/dumps/scripts/1955.cs2 b/dumps/scripts/1955.cs2 new file mode 100644 index 0000000..ddf28ef --- /dev/null +++ b/dumps/scripts/1955.cs2 @@ -0,0 +1,4 @@ +void script_1955(int arg0) { + setWidgetIsHidden(false, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1956.cs2 b/dumps/scripts/1956.cs2 new file mode 100644 index 0000000..b674ca7 --- /dev/null +++ b/dumps/scripts/1956.cs2 @@ -0,0 +1,4 @@ +void script_1956(int arg0) { + setWidgetIsHidden(true, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1957.cs2 b/dumps/scripts/1957.cs2 new file mode 100644 index 0000000..82577d0 --- /dev/null +++ b/dumps/scripts/1957.cs2 @@ -0,0 +1,11 @@ +void script_1957(int arg0,int arg1,int arg2) { + int ivar3; + ivar3 = getItemAmtInContainer(93, arg1); + setWidgetText(new WidgetPointer(arg0), intToStr(ivar3) + "/" + intToStr(arg2)); + if (ivar3 >= arg2) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(arg0)); + } else { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/1958.cs2 b/dumps/scripts/1958.cs2 new file mode 100644 index 0000000..6bd14a0 --- /dev/null +++ b/dumps/scripts/1958.cs2 @@ -0,0 +1,8 @@ +void script_1958(int arg0,int arg1) { + if (getSkillCurrentLvl(7) >= arg1) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(arg0)); + } else { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/1959.cs2 b/dumps/scripts/1959.cs2 new file mode 100644 index 0000000..31093bf --- /dev/null +++ b/dumps/scripts/1959.cs2 @@ -0,0 +1,142 @@ +void script_1959() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + ivar0 = getItemAmtInContainer(93, 1985); + ivar1 = getItemAmtInContainer(93, 1982); + ivar2 = getItemAmtInContainer(93, 2169); + ivar3 = getItemAmtInContainer(93, 2162); + ivar4 = getItemAmtInContainer(93, 1957); + ivar5 = getItemAmtInContainer(93, 1965); + ivar6 = getItemAmtInContainer(93, 2126); + ivar7 = getItemAmtInContainer(93, 2128); + ivar8 = getItemAmtInContainer(93, 2152); + ivar9 = getItemAmtInContainer(93, 2116); + ivar10 = getItemAmtInContainer(93, 2110); + ivar11 = getItemAmtInContainer(93, 2122); + if (((ivar7 >= 4) && (ivar9 >= 1)) && ((ivar10 >= 1) && (ivar11 >= 1))) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(434,59)); + } else { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(434,59)); + } + if (((ivar7 >= 1) && (ivar2 >= 1)) && ((ivar8 >= 1) && (ivar0 >= 1))) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(434,60)); + } else { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(434,60)); + } + if (((ivar3 >= 1) && (ivar2 >= 1)) && (ivar0 >= 1)) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(434,61)); + } else { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(434,61)); + } + if ((((ivar1 >= 2) && (ivar4 >= 1)) && ((ivar5 >= 1) && (ivar6 >= 1))) && (ivar0 >= 1)) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(434,62)); + } else { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(434,62)); + } + if ((ivar1 >= 1) && (ivar0 >= 1)) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(434,63)); + } else { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(434,63)); + } + if (getItemAmtInContainer(93, 2128) > 3) { + setItemOnWidgetMethod2200(2128, 120, new WidgetPointer(434,4)); + } else { + setItemOnWidgetMethod2200(9494, 120, new WidgetPointer(434,4)); + } + if (getItemAmtInContainer(93, 2116) > 0) { + setItemOnWidgetMethod2200(2116, 120, new WidgetPointer(434,5)); + } else { + setItemOnWidgetMethod2200(9498, 120, new WidgetPointer(434,5)); + } + if (getItemAmtInContainer(93, 2110) > 0) { + setItemOnWidgetMethod2200(2110, 120, new WidgetPointer(434,6)); + } else { + setItemOnWidgetMethod2200(9498, 120, new WidgetPointer(434,6)); + } + if (getItemAmtInContainer(93, 2122) > 0) { + setItemOnWidgetMethod2200(2122, 120, new WidgetPointer(434,7)); + } else { + setItemOnWidgetMethod2200(9498, 120, new WidgetPointer(434,7)); + } + if (getItemAmtInContainer(93, 2128) > 0) { + setItemOnWidgetMethod2200(2128, 120, new WidgetPointer(434,15)); + } else { + setItemOnWidgetMethod2200(9494, 120, new WidgetPointer(434,15)); + } + if (getItemAmtInContainer(93, 2152) > 0) { + setItemOnWidgetMethod2200(2152, 100, new WidgetPointer(434,16)); + } else { + setItemOnWidgetMethod2200(9499, 100, new WidgetPointer(434,16)); + } + if (getItemAmtInContainer(93, 2169) > 0) { + setItemOnWidgetMethod2200(2169, 90, new WidgetPointer(434,17)); + } else { + setItemOnWidgetMethod2200(9500, 90, new WidgetPointer(434,17)); + } + if (getItemAmtInContainer(93, 1985) > 0) { + setItemOnWidgetMethod2200(1985, 140, new WidgetPointer(434,18)); + } else { + setItemOnWidgetMethod2200(9502, 140, new WidgetPointer(434,18)); + } + if (getItemAmtInContainer(93, 2162) > 0) { + setItemOnWidgetMethod2200(2162, 100, new WidgetPointer(434,27)); + } else { + setItemOnWidgetMethod2200(9501, 100, new WidgetPointer(434,27)); + } + if (getItemAmtInContainer(93, 2169) > 0) { + setItemOnWidgetMethod2200(2169, 90, new WidgetPointer(434,26)); + } else { + setItemOnWidgetMethod2200(9500, 90, new WidgetPointer(434,26)); + } + if (getItemAmtInContainer(93, 1985) > 0) { + setItemOnWidgetMethod2200(1985, 140, new WidgetPointer(434,28)); + } else { + setItemOnWidgetMethod2200(9502, 140, new WidgetPointer(434,28)); + } + if (getItemAmtInContainer(93, 1982) > 1) { + setItemOnWidgetMethod2200(1982, 100, new WidgetPointer(434,35)); + } else { + setItemOnWidgetMethod2200(9503, 100, new WidgetPointer(434,35)); + } + if (getItemAmtInContainer(93, 1957) > 0) { + setItemOnWidgetMethod2200(1957, 140, new WidgetPointer(434,36)); + } else { + setItemOnWidgetMethod2200(9504, 140, new WidgetPointer(434,36)); + } + if (getItemAmtInContainer(93, 1965) > 0) { + setItemOnWidgetMethod2200(1965, 90, new WidgetPointer(434,37)); + } else { + setItemOnWidgetMethod2200(9505, 90, new WidgetPointer(434,37)); + } + if (getItemAmtInContainer(93, 2126) > 0) { + setItemOnWidgetMethod2200(2126, 140, new WidgetPointer(434,38)); + } else { + setItemOnWidgetMethod2200(9496, 140, new WidgetPointer(434,38)); + } + if (getItemAmtInContainer(93, 1985) > 0) { + setItemOnWidgetMethod2200(1985, 140, new WidgetPointer(434,39)); + } else { + setItemOnWidgetMethod2200(9502, 140, new WidgetPointer(434,39)); + } + if (getItemAmtInContainer(93, 1982) > 0) { + setItemOnWidgetMethod2200(1982, 100, new WidgetPointer(434,48)); + } else { + setItemOnWidgetMethod2200(9503, 100, new WidgetPointer(434,48)); + } + if (getItemAmtInContainer(93, 1985) > 0) { + setItemOnWidgetMethod2200(1985, 140, new WidgetPointer(434,49)); + } else { + setItemOnWidgetMethod2200(9502, 140, new WidgetPointer(434,49)); + } + return; +} diff --git a/dumps/scripts/196.cs2 b/dumps/scripts/196.cs2 new file mode 100644 index 0000000..b390f16 --- /dev/null +++ b/dumps/scripts/196.cs2 @@ -0,0 +1,23 @@ +string script_196(int arg0) { + switch (arg0) { + case 0: + return "Not in Friends Chat"; + case 1: + return "Recruit"; + case 2: + return "Corporal"; + case 3: + return "Sergeant"; + case 4: + return "Lieutenant"; + case 5: + return "Captain"; + case 6: + return "General"; + case 7: + return "Channel Owner"; + case 127: + return "Jagex Mod"; + } + return "Not in Friends Chat"; +} diff --git a/dumps/scripts/1960.cs2 b/dumps/scripts/1960.cs2 new file mode 100644 index 0000000..0bc8949 --- /dev/null +++ b/dumps/scripts/1960.cs2 @@ -0,0 +1,13 @@ +void script_1960() { + if (globalint_1279 != 0) { + playSoundEffect(9445, 1, 0); + } + globalint_1279 = 0; + setWidgetIsHidden(false, new WidgetPointer(60,45)); + setWidgetIsHidden(true, new WidgetPointer(60,46)); + setWidgetIsHidden(true, new WidgetPointer(60,87)); + setWidgetIsHidden(false, new WidgetPointer(60,20)); + setWidgetIsHidden(true, new WidgetPointer(60,17)); + setWidgetIsHidden(true, new WidgetPointer(60,14)); + return; +} diff --git a/dumps/scripts/1961.cs2 b/dumps/scripts/1961.cs2 new file mode 100644 index 0000000..9c83ff2 --- /dev/null +++ b/dumps/scripts/1961.cs2 @@ -0,0 +1,106 @@ +void script_1961() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + ivar0 = getItemAmtInContainer(93, 1985); + ivar1 = getItemAmtInContainer(93, 2169); + ivar2 = getItemAmtInContainer(93, 2162); + ivar3 = getItemAmtInContainer(93, 1957); + ivar4 = getItemAmtInContainer(93, 2126); + ivar5 = getItemAmtInContainer(93, 2128); + ivar6 = getItemAmtInContainer(93, 2152); + ivar7 = getItemAmtInContainer(93, 1973); + ivar8 = getItemAmtInContainer(93, 1942); + if (((ivar2 >= 4) && (ivar3 >= 2)) && (ivar1 >= 1)) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(435,45)); + } else { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(435,45)); + } + if (((ivar3 >= 2) && (ivar1 >= 1)) && (ivar8 >= 2)) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(435,46)); + } else { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(435,46)); + } + if ((((ivar6 >= 4) && (ivar1 >= 1)) && ((ivar0 >= 2) && (ivar5 >= 2))) && (ivar4 >= 1)) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(435,47)); + } else { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(435,47)); + } + if ((ivar7 >= 4) && (ivar5 >= 1)) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(435,48)); + } else { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(435,48)); + } + if (getItemAmtInContainer(93, 2152) > 3) { + setItemOnWidgetMethod2200(2152, 100, new WidgetPointer(435,22)); + } else { + setItemOnWidgetMethod2200(9499, 100, new WidgetPointer(435,22)); + } + if (getItemAmtInContainer(93, 2128) > 1) { + setItemOnWidgetMethod2200(2128, 120, new WidgetPointer(435,24)); + } else { + setItemOnWidgetMethod2200(9494, 120, new WidgetPointer(435,24)); + } + if (getItemAmtInContainer(93, 1985) > 1) { + setItemOnWidgetMethod2200(1985, 140, new WidgetPointer(435,23)); + } else { + setItemOnWidgetMethod2200(9502, 140, new WidgetPointer(435,23)); + } + if (getItemAmtInContainer(93, 2169) > 0) { + setItemOnWidgetMethod2200(2169, 90, new WidgetPointer(435,25)); + } else { + setItemOnWidgetMethod2200(9500, 90, new WidgetPointer(435,25)); + } + if (getItemAmtInContainer(93, 2126) > 0) { + setItemOnWidgetMethod2200(2126, 140, new WidgetPointer(435,26)); + } else { + setItemOnWidgetMethod2200(9496, 140, new WidgetPointer(435,26)); + } + if (getItemAmtInContainer(93, 2162) > 3) { + setItemOnWidgetMethod2200(2162, 100, new WidgetPointer(435,4)); + } else { + setItemOnWidgetMethod2200(9501, 100, new WidgetPointer(435,4)); + } + if (getItemAmtInContainer(93, 2169) > 0) { + setItemOnWidgetMethod2200(2169, 90, new WidgetPointer(435,6)); + } else { + setItemOnWidgetMethod2200(9500, 90, new WidgetPointer(435,6)); + } + if (getItemAmtInContainer(93, 1957) > 1) { + setItemOnWidgetMethod2200(1957, 140, new WidgetPointer(435,5)); + } else { + setItemOnWidgetMethod2200(9504, 140, new WidgetPointer(435,5)); + } + if (getItemAmtInContainer(93, 1942) > 1) { + setItemOnWidgetMethod2200(1942, 100, new WidgetPointer(435,14)); + } else { + setItemOnWidgetMethod2200(9506, 100, new WidgetPointer(435,14)); + } + if (getItemAmtInContainer(93, 2169) > 0) { + setItemOnWidgetMethod2200(2169, 90, new WidgetPointer(435,15)); + } else { + setItemOnWidgetMethod2200(9500, 90, new WidgetPointer(435,15)); + } + if (getItemAmtInContainer(93, 1957) > 1) { + setItemOnWidgetMethod2200(1957, 140, new WidgetPointer(435,13)); + } else { + setItemOnWidgetMethod2200(9504, 140, new WidgetPointer(435,13)); + } + if (getItemAmtInContainer(93, 1973) > 3) { + setItemOnWidgetMethod2200(1973, 140, new WidgetPointer(435,35)); + } else { + setItemOnWidgetMethod2200(9507, 140, new WidgetPointer(435,35)); + } + if (getItemAmtInContainer(93, 2128) > 0) { + setItemOnWidgetMethod2200(2128, 120, new WidgetPointer(435,36)); + } else { + setItemOnWidgetMethod2200(9494, 120, new WidgetPointer(435,36)); + } + return; +} diff --git a/dumps/scripts/1962.cs2 b/dumps/scripts/1962.cs2 new file mode 100644 index 0000000..76f39c6 --- /dev/null +++ b/dumps/scripts/1962.cs2 @@ -0,0 +1,8 @@ +void script_1962(int arg0,int arg1) { + if (getItemAmtInContainer(93, 2996) >= arg1) { + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(arg0)); + } else { + setWidgetRGB(new Color(119, 115, 106), new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/1963.cs2 b/dumps/scripts/1963.cs2 new file mode 100644 index 0000000..cfcee87 --- /dev/null +++ b/dumps/scripts/1963.cs2 @@ -0,0 +1,8 @@ +void script_1963(int arg0,int arg1) { + if (standart_config_261 != arg1) { + setWidgetText(new WidgetPointer(arg0), "" + strRemoveEntities(getWidgetText(new WidgetPointer(arg0))) + ""); + } else { + setWidgetText(new WidgetPointer(arg0), strRemoveEntities(getWidgetText(new WidgetPointer(arg0)))); + } + return; +} diff --git a/dumps/scripts/1964.cs2 b/dumps/scripts/1964.cs2 new file mode 100644 index 0000000..1165665 --- /dev/null +++ b/dumps/scripts/1964.cs2 @@ -0,0 +1,4 @@ +void script_1964(int arg0) { + setWidgetText(new WidgetPointer(arg0), strRemoveEntities(getWidgetText(new WidgetPointer(arg0)))); + return; +} diff --git a/dumps/scripts/1965.cs2 b/dumps/scripts/1965.cs2 new file mode 100644 index 0000000..ecc85f5 --- /dev/null +++ b/dumps/scripts/1965.cs2 @@ -0,0 +1,8 @@ +void script_1965(int arg0) { + if (standart_config_261 > 0) { + cs2method2103(255, new WidgetPointer(arg0)); + } else { + cs2method2103(200, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/1966.cs2 b/dumps/scripts/1966.cs2 new file mode 100644 index 0000000..ca67f91 --- /dev/null +++ b/dumps/scripts/1966.cs2 @@ -0,0 +1,8 @@ +void script_1966(int arg0) { + if (standart_config_261 > 0) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(arg0)); + } else { + setWidgetRGB(new Color(150, 150, 150), new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/1967.cs2 b/dumps/scripts/1967.cs2 new file mode 100644 index 0000000..816ced7 --- /dev/null +++ b/dumps/scripts/1967.cs2 @@ -0,0 +1,23 @@ +void script_1967() { + int ivar0; + int ivar1; + int ivar2; + ivar0 = 1; + ivar1 = -1; + ivar2 = -1; + while (ivar0 <= getCommonDefinitionSize(2120)) { + setWidgetText(cs2method_3408(105, 73, 2118, ivar0), cs2method_3408(105, 115, 2023, ivar0)); + ivar1 = cs2method_3408(105, 111, 2019, ivar0); + ivar2 = ((int)cs2method_3408(105, 73, 2120, ivar0)); + setItemOnWidgetMethod2200(ivar1, 1, cs2method_3408(105, 73, 2117, ivar0)); + cs2method2305(new WidgetPointer(ivar2), cs2method_3408(105, 115, 2023, ivar0)); + if (getItemAmtInContainer(93, ivar1) > 0) { + setWidgetRGB(new Color(0, 255, 0), cs2method_3408(105, 73, 2118, ivar0)); + } else { + setWidgetRGB(new Color(255, 0, 0), cs2method_3408(105, 73, 2118, ivar0)); + } + ivar0 = add(ivar0, 1); + } + script_1969(); + return; +} diff --git a/dumps/scripts/1968.cs2 b/dumps/scripts/1968.cs2 new file mode 100644 index 0000000..c392c80 --- /dev/null +++ b/dumps/scripts/1968.cs2 @@ -0,0 +1,4 @@ +void script_1968() { + script_1969(); + return; +} diff --git a/dumps/scripts/1969.cs2 b/dumps/scripts/1969.cs2 new file mode 100644 index 0000000..ca09a9a --- /dev/null +++ b/dumps/scripts/1969.cs2 @@ -0,0 +1,22 @@ +void script_1969() { + int ivar0; + int ivar1; + ivar0 = 1; + ivar1 = 0; + while (ivar0 <= getCommonDefinitionSize(2119)) { + if (((boolean)globalint_617)) { + ivar1 = cs2method_3408(105, 105, 2022, ivar0); + setWidgetText(cs2method_3408(105, 73, 2119, ivar0), intToStr(ivar1) + " Coins"); + } else { + ivar1 = cs2method_3408(105, 105, 2021, ivar0); + setWidgetText(cs2method_3408(105, 73, 2119, ivar0), intToStr(ivar1) + " Coins"); + } + if (getItemAmtInContainer(93, 995) >= ivar1) { + setWidgetRGB(new Color(0, 255, 0), cs2method_3408(105, 73, 2119, ivar0)); + } else { + setWidgetRGB(new Color(255, 0, 0), cs2method_3408(105, 73, 2119, ivar0)); + } + ivar0 = add(ivar0, 1); + } + return; +} diff --git a/dumps/scripts/197.cs2 b/dumps/scripts/197.cs2 new file mode 100644 index 0000000..7ac3c85 --- /dev/null +++ b/dumps/scripts/197.cs2 @@ -0,0 +1,19 @@ +void script_197(int arg0,int arg1) { + int ivar2; + string svar0; + string svar1; + int stack_dump0; + previousAndCurrentName(0,2,0) structdump_1; + ivar2 = subtract(arg1, 1); + svar0 = ""; + svar1 = ""; + stack_dump0 = arg0; + structdump_1 = getFriendName(stack_dump0); + svar1 = structdump_1.stringpart_1; + svar0 = structdump_1.stringpart_0; + cs2method3604(ivar2, svar0); + if (setWidgetRegister(new WidgetPointer(1108,13), add(multiply(arg0, 2), 1))) { + setWidgetText(script_196(ivar2)); + } + return; +} diff --git a/dumps/scripts/1970.cs2 b/dumps/scripts/1970.cs2 new file mode 100644 index 0000000..098c8a6 --- /dev/null +++ b/dumps/scripts/1970.cs2 @@ -0,0 +1,4 @@ +void script_1970(int arg0,int arg1) { + script_1971(arg0, arg1); + return; +} diff --git a/dumps/scripts/1971.cs2 b/dumps/scripts/1971.cs2 new file mode 100644 index 0000000..60586e5 --- /dev/null +++ b/dumps/scripts/1971.cs2 @@ -0,0 +1,28 @@ +void script_1971(int arg0,int arg1) { + switch (arg0) { + case 0: + if ((globalint_618 < 0) || (globalint_618 > 25)) { + globalint_618 = 0; + } + setWidgetText(new WidgetPointer(arg1), cs2method_3408(105, 115, 2121, globalint_618)); + break; + case 1: + if ((globalint_619 < 0) || (globalint_619 > 25)) { + globalint_619 = 0; + } + setWidgetText(new WidgetPointer(arg1), cs2method_3408(105, 115, 2121, globalint_619)); + break; + case 2: + if ((globalint_620 < 0) || (globalint_620 > 25)) { + globalint_620 = 0; + } + setWidgetText(new WidgetPointer(arg1), cs2method_3408(105, 115, 2121, globalint_620)); + break; + case 3: + if ((globalint_621 < 0) || (globalint_621 > 25)) { + globalint_621 = 0; + } + setWidgetText(new WidgetPointer(arg1), cs2method_3408(105, 115, 2121, globalint_621)); + } + return; +} diff --git a/dumps/scripts/1972.cs2 b/dumps/scripts/1972.cs2 new file mode 100644 index 0000000..3da2f45 --- /dev/null +++ b/dumps/scripts/1972.cs2 @@ -0,0 +1,21 @@ +void script_1972(int arg0,int arg1,int arg2) { + if (arg2 != 1) { + return; + } + playSoundEffect(4911, 1, 0); + switch (arg0) { + case 0: + globalint_618 = mod(add(globalint_618, 1), 26); + break; + case 1: + globalint_619 = mod(add(globalint_619, 1), 26); + break; + case 2: + globalint_620 = mod(add(globalint_620, 1), 26); + break; + case 3: + globalint_621 = mod(add(globalint_621, 1), 26); + } + script_1971(arg0, arg1); + return; +} diff --git a/dumps/scripts/1973.cs2 b/dumps/scripts/1973.cs2 new file mode 100644 index 0000000..58694c0 --- /dev/null +++ b/dumps/scripts/1973.cs2 @@ -0,0 +1,21 @@ +void script_1973(int arg0,int arg1,int arg2) { + if (arg2 != 1) { + return; + } + playSoundEffect(4911, 1, 0); + switch (arg0) { + case 0: + globalint_618 = script_686(subtract(globalint_618, 1), 26); + break; + case 1: + globalint_619 = script_686(subtract(globalint_619, 1), 26); + break; + case 2: + globalint_620 = script_686(subtract(globalint_620, 1), 26); + break; + case 3: + globalint_621 = script_686(subtract(globalint_621, 1), 26); + } + script_1971(arg0, arg1); + return; +} diff --git a/dumps/scripts/1974.cs2 b/dumps/scripts/1974.cs2 new file mode 100644 index 0000000..19790ad --- /dev/null +++ b/dumps/scripts/1974.cs2 @@ -0,0 +1,5 @@ +void script_1974(int arg0,int arg1,int arg2) { + setWidget3DRotation(0, 0, getWidgetRotateX(new WidgetPointer(arg0)), getWidgetRotateY(new WidgetPointer(arg0)), getWidgetRotateY(new WidgetPointer(arg0)), arg2, new WidgetPointer(arg0)); + setItemOnWidgetMethod2200(arg1, 1, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/1975.cs2 b/dumps/scripts/1975.cs2 new file mode 100644 index 0000000..80f711d --- /dev/null +++ b/dumps/scripts/1975.cs2 @@ -0,0 +1,3 @@ +int script_1975() { + return add(add(add(add(add(add(add(add(add(add(add(add(add(add(bitconfig_5691, bitconfig_5692), bitconfig_5693), bitconfig_5694), bitconfig_5695), bitconfig_5696), bitconfig_5697), bitconfig_5698), bitconfig_5699), bitconfig_5700), bitconfig_5701), bitconfig_5702), bitconfig_5703), bitconfig_5704), bitconfig_5705); +} diff --git a/dumps/scripts/1976.cs2 b/dumps/scripts/1976.cs2 new file mode 100644 index 0000000..ac1bed1 --- /dev/null +++ b/dumps/scripts/1976.cs2 @@ -0,0 +1,20 @@ +int script_1976() { + int ivar0; + ivar0 = 0; + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 3); + return ivar0; +} diff --git a/dumps/scripts/1977.cs2 b/dumps/scripts/1977.cs2 new file mode 100644 index 0000000..919945f --- /dev/null +++ b/dumps/scripts/1977.cs2 @@ -0,0 +1,3 @@ +int script_1977() { + return add(add(add(add(add(add(add(add(add(add(add(bitconfig_5706, bitconfig_5707), bitconfig_5723), bitconfig_5709), bitconfig_5710), bitconfig_5711), bitconfig_5712), bitconfig_5713), bitconfig_5714), bitconfig_5715), bitconfig_5716), bitconfig_5717); +} diff --git a/dumps/scripts/1978.cs2 b/dumps/scripts/1978.cs2 new file mode 100644 index 0000000..06c8261 --- /dev/null +++ b/dumps/scripts/1978.cs2 @@ -0,0 +1,17 @@ +int script_1978() { + int ivar0; + ivar0 = 0; + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 3); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + return ivar0; +} diff --git a/dumps/scripts/1979.cs2 b/dumps/scripts/1979.cs2 new file mode 100644 index 0000000..1c8e327 --- /dev/null +++ b/dumps/scripts/1979.cs2 @@ -0,0 +1,3 @@ +int script_1979() { + return add(add(add(add(add(add(add(add(add(bitconfig_5718, bitconfig_5719), bitconfig_5720), bitconfig_5721), bitconfig_5708), bitconfig_5722), bitconfig_5724), bitconfig_5725), bitconfig_5726), bitconfig_5727); +} diff --git a/dumps/scripts/198.cs2 b/dumps/scripts/198.cs2 new file mode 100644 index 0000000..aa1b603 --- /dev/null +++ b/dumps/scripts/198.cs2 @@ -0,0 +1,4 @@ +void script_198(int arg0) { + script_199(arg0); + return; +} diff --git a/dumps/scripts/1980.cs2 b/dumps/scripts/1980.cs2 new file mode 100644 index 0000000..4b1b8f2 --- /dev/null +++ b/dumps/scripts/1980.cs2 @@ -0,0 +1,15 @@ +int script_1980() { + int ivar0; + ivar0 = 0; + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + return ivar0; +} diff --git a/dumps/scripts/1981.cs2 b/dumps/scripts/1981.cs2 new file mode 100644 index 0000000..13a0eb7 --- /dev/null +++ b/dumps/scripts/1981.cs2 @@ -0,0 +1,3 @@ +int script_1981() { + return add(add(add(add(add(add(add(add(add(bitconfig_5648, bitconfig_5649), bitconfig_5650), bitconfig_5651), bitconfig_5652), bitconfig_5653), bitconfig_5654), bitconfig_5655), bitconfig_5656), bitconfig_5657); +} diff --git a/dumps/scripts/1982.cs2 b/dumps/scripts/1982.cs2 new file mode 100644 index 0000000..fdba5dc --- /dev/null +++ b/dumps/scripts/1982.cs2 @@ -0,0 +1,3 @@ +int script_1982() { + return add(add(add(add(add(add(add(add(add(add(bitconfig_5658, bitconfig_5659), bitconfig_5660), bitconfig_5661), bitconfig_5662), bitconfig_5663), bitconfig_5664), bitconfig_5665), bitconfig_5666), bitconfig_5667), bitconfig_5668); +} diff --git a/dumps/scripts/1983.cs2 b/dumps/scripts/1983.cs2 new file mode 100644 index 0000000..ed8d635 --- /dev/null +++ b/dumps/scripts/1983.cs2 @@ -0,0 +1,3 @@ +int script_1983() { + return add(add(add(add(add(add(add(add(bitconfig_5669, bitconfig_5670), bitconfig_5671), bitconfig_5672), bitconfig_5673), bitconfig_5674), bitconfig_5675), bitconfig_5676), bitconfig_5677); +} diff --git a/dumps/scripts/1984.cs2 b/dumps/scripts/1984.cs2 new file mode 100644 index 0000000..2f739c8 --- /dev/null +++ b/dumps/scripts/1984.cs2 @@ -0,0 +1,3 @@ +int script_1984() { + return 10; +} diff --git a/dumps/scripts/1985.cs2 b/dumps/scripts/1985.cs2 new file mode 100644 index 0000000..1e1a130 --- /dev/null +++ b/dumps/scripts/1985.cs2 @@ -0,0 +1,3 @@ +int script_1985() { + return 11; +} diff --git a/dumps/scripts/1986.cs2 b/dumps/scripts/1986.cs2 new file mode 100644 index 0000000..5cbaae1 --- /dev/null +++ b/dumps/scripts/1986.cs2 @@ -0,0 +1,3 @@ +int script_1986() { + return 9; +} diff --git a/dumps/scripts/1987.cs2 b/dumps/scripts/1987.cs2 new file mode 100644 index 0000000..48727ea --- /dev/null +++ b/dumps/scripts/1987.cs2 @@ -0,0 +1,6 @@ +int script_1987() { + if (add(add(add(script_1995(), script_1983()), script_1982()), script_1981()) == add(add(add(9, 11), 10), 9)) { + return 1; + } + return 0; +} diff --git a/dumps/scripts/1988.cs2 b/dumps/scripts/1988.cs2 new file mode 100644 index 0000000..6051982 --- /dev/null +++ b/dumps/scripts/1988.cs2 @@ -0,0 +1,12 @@ +int script_1988() { + int ivar0; + ivar0 = 0; + ivar0 = add(ivar0, bitconfig_8180); + ivar0 = add(ivar0, bitconfig_8181); + ivar0 = add(ivar0, bitconfig_8188); + ivar0 = add(ivar0, bitconfig_8191); + ivar0 = add(ivar0, bitconfig_8192); + ivar0 = add(ivar0, bitconfig_8193); + ivar0 = add(ivar0, bitconfig_8194); + return ivar0; +} diff --git a/dumps/scripts/1989.cs2 b/dumps/scripts/1989.cs2 new file mode 100644 index 0000000..8d38baa --- /dev/null +++ b/dumps/scripts/1989.cs2 @@ -0,0 +1,12 @@ +int script_1989() { + int ivar0; + ivar0 = 0; + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + return ivar0; +} diff --git a/dumps/scripts/199.cs2 b/dumps/scripts/199.cs2 new file mode 100644 index 0000000..c85c010 --- /dev/null +++ b/dumps/scripts/199.cs2 @@ -0,0 +1,30 @@ +void script_199(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + string svar0; + ivar1 = 0; + ivar2 = cs2method3612(); + ivar3 = 2; + ivar4 = 100; + ivar5 = 19; + svar0 = ""; + if (ivar2 > 0) { + deleteAllExtraChilds(new WidgetPointer(arg0)); + while (ivar1 < ivar2) { + svar0 = cs2method3613(ivar1); + createExtraChild(new WidgetPointer(arg0), 4, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetRGB(new Color(164, 153, 125)); + setWidgetFont(3793); + setWidgetUnknownBoolean(false); + setWidgetPosition(0, multiply(ivar1, ivar5), 0, 0); + setWidgetSize(ivar4, ivar5, 0, 0); + setWidgetText(svar0); + ivar1 = add(ivar1, 1); + } + setScriptCallOnClanChatDeltaStuff(198, new WidgetPointer(-32768,3), "I", new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/1990.cs2 b/dumps/scripts/1990.cs2 new file mode 100644 index 0000000..d867d3c --- /dev/null +++ b/dumps/scripts/1990.cs2 @@ -0,0 +1,18 @@ +int script_1990() { + int ivar0; + ivar0 = 0; + ivar0 = add(add(add(add(add(add(add(bitconfig_5783, bitconfig_5785), bitconfig_5786), bitconfig_5790), bitconfig_5791), bitconfig_5793), bitconfig_5792), bitconfig_5784); + if (bitconfig_5782 == 5) { + ivar0 = add(ivar0, 1); + } + if (bitconfig_5787 == 5) { + ivar0 = add(ivar0, 1); + } + if (bitconfig_5788 == 5) { + ivar0 = add(ivar0, 1); + } + if (bitconfig_5789 == 5) { + ivar0 = add(ivar0, 1); + } + return ivar0; +} diff --git a/dumps/scripts/1991.cs2 b/dumps/scripts/1991.cs2 new file mode 100644 index 0000000..286c05d --- /dev/null +++ b/dumps/scripts/1991.cs2 @@ -0,0 +1,12 @@ +int script_1991() { + int ivar0; + ivar0 = 0; + ivar0 = add(add(add(add(add(add(add(add(add(bitconfig_5799, bitconfig_5794), bitconfig_5795), bitconfig_5800), bitconfig_5796), bitconfig_5798), bitconfig_5802), bitconfig_5803), bitconfig_5804), bitconfig_5801); + if (bitconfig_5805 == 15) { + ivar0 = add(ivar0, 1); + } + if (bitconfig_5797 == 15) { + ivar0 = add(ivar0, 1); + } + return ivar0; +} diff --git a/dumps/scripts/1992.cs2 b/dumps/scripts/1992.cs2 new file mode 100644 index 0000000..0ace18f --- /dev/null +++ b/dumps/scripts/1992.cs2 @@ -0,0 +1,18 @@ +int script_1992() { + int ivar0; + ivar0 = 0; + ivar0 = add(add(add(add(add(add(bitconfig_5811, bitconfig_5806), bitconfig_5810), bitconfig_5809), bitconfig_5808), bitconfig_5812), bitconfig_5813); + if (bitconfig_5807 == 5) { + ivar0 = add(ivar0, 1); + } + if (bitconfig_5814 == 5) { + ivar0 = add(ivar0, 1); + } + if (bitconfig_5815 == 5) { + ivar0 = add(ivar0, 1); + } + if (bitconfig_5816 == 5) { + ivar0 = add(ivar0, 1); + } + return ivar0; +} diff --git a/dumps/scripts/1993.cs2 b/dumps/scripts/1993.cs2 new file mode 100644 index 0000000..46499a1 --- /dev/null +++ b/dumps/scripts/1993.cs2 @@ -0,0 +1,3 @@ +int script_1993() { + return add(add(add(add(bitconfig_8205, bitconfig_8212), bitconfig_8217), bitconfig_8221), bitconfig_8224); +} diff --git a/dumps/scripts/1994.cs2 b/dumps/scripts/1994.cs2 new file mode 100644 index 0000000..721ea3b --- /dev/null +++ b/dumps/scripts/1994.cs2 @@ -0,0 +1,10 @@ +int script_1994() { + int ivar0; + ivar0 = 0; + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + return ivar0; +} diff --git a/dumps/scripts/1995.cs2 b/dumps/scripts/1995.cs2 new file mode 100644 index 0000000..8721281 --- /dev/null +++ b/dumps/scripts/1995.cs2 @@ -0,0 +1,3 @@ +int script_1995() { + return add(add(add(add(add(add(add(add(bitconfig_8231, bitconfig_8232), bitconfig_8233), bitconfig_8234), bitconfig_8235), bitconfig_8236), bitconfig_8237), bitconfig_8238), bitconfig_8239); +} diff --git a/dumps/scripts/1996.cs2 b/dumps/scripts/1996.cs2 new file mode 100644 index 0000000..da7f8c9 --- /dev/null +++ b/dumps/scripts/1996.cs2 @@ -0,0 +1,3 @@ +int script_1996() { + return 9; +} diff --git a/dumps/scripts/1997.cs2 b/dumps/scripts/1997.cs2 new file mode 100644 index 0000000..16beed0 --- /dev/null +++ b/dumps/scripts/1997.cs2 @@ -0,0 +1,5 @@ +void script_1997() { + setWidgetIsHidden(false, new WidgetPointer(391,28)); + setWidgetIsHidden(false, new WidgetPointer(391,32)); + return; +} diff --git a/dumps/scripts/1998.cs2 b/dumps/scripts/1998.cs2 new file mode 100644 index 0000000..7d3a3ef --- /dev/null +++ b/dumps/scripts/1998.cs2 @@ -0,0 +1,5 @@ +void script_1998() { + setWidgetIsHidden(true, new WidgetPointer(391,28)); + setWidgetIsHidden(true, new WidgetPointer(391,32)); + return; +} diff --git a/dumps/scripts/1999.cs2 b/dumps/scripts/1999.cs2 new file mode 100644 index 0000000..7b64f95 --- /dev/null +++ b/dumps/scripts/1999.cs2 @@ -0,0 +1,5 @@ +void script_1999(int arg0) { + script_2001(arg0, standart_config_118); + setScriptCallOnConfigChange(2000, new WidgetPointer(arg0), standart_config_118, 1081, 1, "IvY", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/2.cs2 b/dumps/scripts/2.cs2 new file mode 100644 index 0000000..1d6db91 --- /dev/null +++ b/dumps/scripts/2.cs2 @@ -0,0 +1,37 @@ +cs2func_script_2_struct(1,1,0) script_2(int arg0) { + switch (arg0) { + case 0: + return newstruct cs2func_script_2_struct(1, "Rooms"); + case 1: + return newstruct cs2func_script_2_struct(1, "Skills"); + case 2: + return newstruct cs2func_script_2_struct(1, "Surfaces"); + case 3: + return newstruct cs2func_script_2_struct(1, "Storage"); + case 4: + return newstruct cs2func_script_2_struct(1, "Decorative"); + case 5: + return newstruct cs2func_script_2_struct(1, "Trophies"); + case 6: + return newstruct cs2func_script_2_struct(1, "Games & Sport"); + case 7: + return newstruct cs2func_script_2_struct(1, "Garden"); + case 8: + return newstruct cs2func_script_2_struct(1, "Dungeon"); + case 9: + return newstruct cs2func_script_2_struct(1, "Chapel"); + case 10: + return newstruct cs2func_script_2_struct(1, "Other"); + case 11: + return newstruct cs2func_script_2_struct(1, "Menagerie"); + case 12: + return newstruct cs2func_script_2_struct(1, "Servants"); + case 13: + return newstruct cs2func_script_2_struct(1, "Minigames"); + case 14: + return newstruct cs2func_script_2_struct(1, "Dungeoneering"); + case 15: + return newstruct cs2func_script_2_struct(1, "Milestones"); + } + return newstruct cs2func_script_2_struct(-1, ""); +} diff --git a/dumps/scripts/20.cs2 b/dumps/scripts/20.cs2 new file mode 100644 index 0000000..c65fc2b --- /dev/null +++ b/dumps/scripts/20.cs2 @@ -0,0 +1,12 @@ +string script_20(int arg0) { + if (arg0 >= 99999999) { + return "*"; + } + if (arg0 >= 10000000) { + return concat(intToStr(divide(arg0, 1000000)), "M"); + } + if (arg0 >= 10000) { + return concat(intToStr(divide(arg0, 1000)), "K"); + } + return intToStr(arg0); +} diff --git a/dumps/scripts/200.cs2 b/dumps/scripts/200.cs2 new file mode 100644 index 0000000..4850375 --- /dev/null +++ b/dumps/scripts/200.cs2 @@ -0,0 +1,4 @@ +void script_200(int arg0) { + script_201(); + return; +} diff --git a/dumps/scripts/2000.cs2 b/dumps/scripts/2000.cs2 new file mode 100644 index 0000000..2a8a0e7 --- /dev/null +++ b/dumps/scripts/2000.cs2 @@ -0,0 +1,4 @@ +void script_2000(int arg0,int arg1) { + script_2001(arg0, arg1); + return; +} diff --git a/dumps/scripts/2001.cs2 b/dumps/scripts/2001.cs2 new file mode 100644 index 0000000..4d8c6e9 --- /dev/null +++ b/dumps/scripts/2001.cs2 @@ -0,0 +1,95 @@ +void script_2001(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + string svar0; + deleteAllExtraChilds(new WidgetPointer(arg0)); + ivar2 = -1; + ivar3 = 0; + ivar4 = getItemContainerLength(arg1); + ivar5 = 4; + setWidgetPosition(getWidgetActualX(new WidgetPointer(arg0)), 46, 0, 0, new WidgetPointer(arg0)); + setWidgetSize(464, 255, 0, 0, new WidgetPointer(arg0)); + setWidgetScrollMax(0, 0, new WidgetPointer(arg0)); + cs2method2100(0, 0, new WidgetPointer(arg0)); + ivar5 = 4; + ivar3 = 0; + ivar6 = 0; + ivar7 = 0; + ivar8 = 0; + ivar9 = -1; + ivar10 = 0; + svar0 = ""; + ivar11 = 0; + ivar12 = script_2002(); + ivar9 = getItemIdInSlot(arg1, ivar3); + if (ivar9 != -1) { + ivar7 = add(multiply(mod(ivar3, 9), 48), multiply(mod(ivar3, 9), ivar5)); + ivar8 = add(multiply(divide(ivar3, 9), 52), multiply(divide(ivar3, 9), 13)); + createExtraChild(new WidgetPointer(arg0), 5, ivar6); + ivar6 = add(ivar6, 1); + setWidgetSize(48, 52, 0, 0); + setWidgetPosition(ivar7, ivar8, 0, 0); + setWidgetSprite(2205); + cs2method1305("" + getItemName(ivar9) + ""); + setWidgetContextMenuOption(1, "Info"); + setWidgetContextMenuOption(2, "Buy 1"); + setWidgetContextMenuOption(3, "Buy 5"); + setWidgetContextMenuOption(4, "Buy 10"); + setWidgetContextMenuOption(5, "Buy 50"); + setWidgetContextMenuOption(6, "Buy 500"); + setWidgetContextMenuOption(10, "Examine"); + setScriptCallOnMouseEntered(2724, new WidgetPointer(-32768,3), ivar6, 0, "Ii1"); + setScriptCallOnMouseExit(2724, new WidgetPointer(-32768,3), ivar6, 1, "Ii1"); + createExtraChild(new WidgetPointer(arg0), 5, ivar6); + ivar6 = add(ivar6, 1); + setWidgetSize(48, 52, 0, 0); + setWidgetPosition(ivar7, ivar8, 0, 0); + setWidgetSprite(2206); + setWidgetHidden(1); + createExtraChild(new WidgetPointer(arg0), 5, ivar6); + ivar6 = add(ivar6, 1); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(add(ivar7, 6), add(ivar8, 4), 0, 0); + setItemOnWidgetMethod1212(ivar9, ivar12); + setWidgetShadowColor(new Color(48, 32, 32)); + setWidgetBorderThickness(1); + createExtraChild(new WidgetPointer(arg0), 5, ivar6); + ivar6 = add(ivar6, 1); + setWidgetSize(12, 12, 0, 0); + setWidgetPosition(add(ivar7, 2), add(ivar8, 38), 0, 0); + setWidgetSprite(cs2method_3408(111, 100, 200, standart_config_532)); + createExtraChild(new WidgetPointer(arg0), 4, ivar6); + ivar6 = add(ivar6, 1); + setWidgetSize(31, 12, 0, 0); + setWidgetPosition(add(ivar7, 13), add(ivar8, 39), 0, 0); + setWidgetFont(494); + setWidgetTextAlignment(2, 1, 0); + ivar11 = script_2720(ivar9, ivar3); + if (ivar11 == -1) { + setWidgetText("N/A"); + } else { + setWidgetText(script_940(ivar11)); + } + setWidgetRGB(new Color(script_1146(ivar11))); + setWidgetUnknownBoolean(true); + createExtraChild(new WidgetPointer(arg0), 5, ivar6); + ivar6 = add(ivar6, 1); + setWidgetSize(12, 12, 0, 0); + setWidgetPosition(add(ivar7, 33), add(ivar8, 4), 0, 0); + setWidgetSprite(2180); + script_812(ivar9); + svar0 = script_2706(ivar9); + setScriptCallOnMouseOver(2707, new WidgetPointer(-32768,3), -2147483643, new WidgetPointer(620,34), svar0, 25, 200, -2147483647, -2147483646, "IiIsiiii"); + setScriptCallOnMouseExit(40, new WidgetPointer(620,34), "I"); + } + return; +} diff --git a/dumps/scripts/2002.cs2 b/dumps/scripts/2002.cs2 new file mode 100644 index 0000000..9e97269 --- /dev/null +++ b/dumps/scripts/2002.cs2 @@ -0,0 +1,38 @@ +int script_2002() { + int ivar0; + ivar0 = 0; + if (((boolean)bitconfig_8150)) { + if (bitconfig_4069 > 79) { + ivar0 = 0; + } else { + ivar0 = subtract(80, bitconfig_4069); + } + } else if (((boolean)bitconfig_3976)) { + if (bitconfig_4069 > 63) { + ivar0 = 0; + } else { + ivar0 = subtract(64, bitconfig_4069); + } + } else if (((boolean)bitconfig_3975)) { + if (bitconfig_4069 > 31) { + ivar0 = 0; + } else { + ivar0 = subtract(32, bitconfig_4069); + } + } else if (((boolean)bitconfig_3974)) { + if (bitconfig_4069 > 15) { + ivar0 = 0; + } else { + ivar0 = subtract(16, bitconfig_4069); + } + } else { + if (((boolean)bitconfig_3974)) { + if (bitconfig_4069 > 7) { + ivar0 = 0; + } else { + ivar0 = subtract(8, bitconfig_4069); + } + } + } + return ivar0; +} diff --git a/dumps/scripts/2003.cs2 b/dumps/scripts/2003.cs2 new file mode 100644 index 0000000..257a613 --- /dev/null +++ b/dumps/scripts/2003.cs2 @@ -0,0 +1,119 @@ +void script_2003() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int stack_dump0; + ivar0 = 0; + if (getSkillActualLvl(19) >= 40) { + ivar0 = bitconfig_4449; + } else { + ivar0 = divide(multiply(bitconfig_4449, cs2method_3408(105, 105, 1369, getSkillActualLvl(19))), 100); + } + if (((boolean)bitconfig_4449)) { + setWidgetText(new WidgetPointer(686,13), "Trade one point" + "
" + "for " + formatNumber(ivar0, 1) + " XP?"); + } else { + setWidgetText(new WidgetPointer(686,13), "Trade " + formatNumber(bitconfig_4449, 1) + " points" + "
" + "for " + formatNumber(ivar0, 1) + " XP?"); + } + deleteAllExtraChilds(new WidgetPointer(686,6)); + ivar1 = getCommonDefinitionSize(1589); + ivar2 = 0; + ivar3 = 0; + ivar4 = 0; + ivar5 = 0; + ivar6 = -1; + ivar7 = 0; + ivar8 = 0; + while (ivar8 < ivar1) { + ivar6 = cs2method_3408(105, 79, 1589, ivar8); + ivar7 = cs2method_3408(111, 105, 1365, ivar6); + ivar2 = multiply(mod(ivar8, 9), 50); + ivar3 = multiply(divide(ivar8, 9), 54); + stack_dump0 = max(ivar4, ivar2); + ivar5 = max(ivar5, ivar3); + ivar4 = stack_dump0; + createExtraChild(new WidgetPointer(686,6), 5, getExtraChildGap(new WidgetPointer(686,6))); + setWidgetSize(48, 52, 0, 0); + setWidgetPosition(ivar2, ivar3, 0, 0); + setWidgetSprite(2205); + if (ivar6 == 11209) { + setWidgetContextMenuOption(1, "Trade points for XP"); + setScriptCallOnClickContextMenu(69, 0, new WidgetPointer(686,9), "1I"); + } else { + cs2method1305("" + getItemName(ivar6) + ""); + setWidgetContextMenuOption(1, "Value"); + setWidgetContextMenuOption(2, "Buy 1"); + setWidgetContextMenuOption(3, "Buy 5"); + setWidgetContextMenuOption(4, "Buy 10"); + if (ivar6 != 12625) { + setWidgetContextMenuOption(5, "Buy X"); + } + setWidgetContextMenuOption(10, "Examine"); + } + setScriptCallOnMouseEntered(2140, new WidgetPointer(-32768,3), add(getWidgetCustomChildArrayIndex(), 1), 0, "Iii"); + setScriptCallOnMouseExit(2140, new WidgetPointer(-32768,3), add(getWidgetCustomChildArrayIndex(), 1), 255, "Iii"); + createExtraChild(new WidgetPointer(686,6), 5, getExtraChildGap(new WidgetPointer(686,6))); + setWidgetSize(48, 52, 0, 0); + setWidgetPosition(ivar2, ivar3, 0, 0); + setWidgetSprite(2206); + cs2method2103(255); + createExtraChild(new WidgetPointer(686,6), 5, getExtraChildGap(new WidgetPointer(686,6))); + if (ivar6 == 11209) { + setWidgetSize(34, 34, 0, 0); + setWidgetPosition(add(ivar2, 7), add(ivar3, 2), 0, 0); + if (((boolean)getLanguage())) { + setWidgetSprite(2714); + } else { + setWidgetSprite(2730); + } + } else { + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(add(ivar2, 6), add(ivar3, 4), 0, 0); + setItemOnWidgetMethod1205(ivar6, 5); + setWidgetBorderThickness(1); + } + setWidgetShadowColor(new Color(48, 32, 32)); + createExtraChild(new WidgetPointer(686,6), 5, getExtraChildGap(new WidgetPointer(686,6))); + setWidgetSize(12, 12, 0, 0); + setWidgetPosition(add(ivar2, 2), add(ivar3, 38), 0, 0); + setItemOnWidgetMethod1205(12625, 1); + createExtraChild(new WidgetPointer(686,6), 4, getExtraChildGap(new WidgetPointer(686,6))); + setWidgetSize(31, 12, 0, 0); + setWidgetPosition(add(ivar2, 13), add(ivar3, 39), 0, 0); + setWidgetFont(494); + setWidgetTextAlignment(2, 1, 0); + if (ivar7 == -1) { + setWidgetText("N/A"); + } else { + setWidgetText(script_940(ivar7)); + } + if (ivar7 <= bitconfig_4449) { + setWidgetRGB(new Color(255, 255, 0)); + } else { + setWidgetRGB(new Color(255, 0, 0)); + } + setWidgetUnknownBoolean(true); + ivar8 = add(ivar8, 1); + } + stack_dump0 = add(ivar4, 48); + ivar5 = add(ivar5, 52); + ivar4 = stack_dump0; + ivar9 = getWidgetActualHeight(new WidgetPointer(686,6)); + setWidgetSize(ivar4, ivar9, 0, 0, new WidgetPointer(686,6)); + if (ivar5 > ivar9) { + setWidgetPosition(divide(subtract(subtract(getWidgetActualWidth(new WidgetPointer(686,5)), getWidgetActualWidth(new WidgetPointer(686,7))), ivar4), 2), 0, 0, 1, new WidgetPointer(686,6)); + setWidgetIsHidden(false, new WidgetPointer(686,7)); + setWidgetScrollMax(0, ivar5, new WidgetPointer(686,6)); + script_31(44957703, 44957702, 792, 789, 790, 791, 773, 788); + } else { + setWidgetPosition(0, 0, 1, 1, new WidgetPointer(686,6)); + setWidgetIsHidden(true, new WidgetPointer(686,7)); + } + return; +} diff --git a/dumps/scripts/2004.cs2 b/dumps/scripts/2004.cs2 new file mode 100644 index 0000000..d2531f9 --- /dev/null +++ b/dumps/scripts/2004.cs2 @@ -0,0 +1,13 @@ +void script_2004(int arg0,int arg1) { + int ivar2; + ivar2 = cs2method6143(); + if ((((boolean)ivar2) && (globalint_1394 > 0)) && (globalint_1394 <= 255)) { + cs2method6038(globalint_1394); + } else { + if (ivar2 > 0) { + cs2method6038(0); + } + } + script_2007(arg0, arg1, 0, 1); + return; +} diff --git a/dumps/scripts/2005.cs2 b/dumps/scripts/2005.cs2 new file mode 100644 index 0000000..52c6730 --- /dev/null +++ b/dumps/scripts/2005.cs2 @@ -0,0 +1,36 @@ +void script_2005(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + if ((arg2 >= getWidgetActualX(new WidgetPointer(arg1))) && (arg2 <= add(getWidgetActualX(new WidgetPointer(arg1)), getWidgetActualWidth(new WidgetPointer(arg1))))) { + return; + } + ivar4 = subtract(getWidgetActualWidth(new WidgetPointer(arg0)), getWidgetActualWidth(new WidgetPointer(arg1))); + ivar5 = divide(getWidgetActualWidth(new WidgetPointer(arg1)), 2); + if (arg2 == -1) { + arg2 = getWidgetActualWidth(new WidgetPointer(arg0)); + } + arg2 = max(subtract(arg2, ivar5), 0); + arg2 = min(arg2, ivar4); + switch (arg3) { + case 0: + cs2method6018(multiplyDivide(arg2, ivar4, 127)); + script_1217(arg0, arg1); + break; + case 1: + cs2method6019(multiplyDivide(arg2, ivar4, 255)); + script_1216(arg0, arg1); + break; + case 2: + cs2method6020(multiplyDivide(arg2, ivar4, 127)); + script_1218(arg0, arg1); + break; + case 3: + cs2method6001(add(min(multiplyDivide(arg2, ivar4, 4), 3), 1)); + script_1185(arg0, arg1); + break; + case 4: + cs2method6038(multiplyDivide(arg2, ivar4, 255)); + script_2007(arg0, arg1, 1, 1); + } + return; +} diff --git a/dumps/scripts/2006.cs2 b/dumps/scripts/2006.cs2 new file mode 100644 index 0000000..a104dc4 --- /dev/null +++ b/dumps/scripts/2006.cs2 @@ -0,0 +1,9 @@ +void script_2006(int arg0) { + if (arg0 > 0) { + setWidgetSprite(4123, new WidgetPointer(744,108)); + } else { + setWidgetSprite(4124, new WidgetPointer(744,108)); + } + setScriptCallOnGameloop(3961, 0, new WidgetPointer(744,7), "iI", new WidgetPointer(744,7)); + return; +} diff --git a/dumps/scripts/2007.cs2 b/dumps/scripts/2007.cs2 new file mode 100644 index 0000000..eaf3de2 --- /dev/null +++ b/dumps/scripts/2007.cs2 @@ -0,0 +1,23 @@ +void script_2007(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + cs2method2301(arg0, -1, new WidgetPointer(arg1)); + ivar4 = subtract(getWidgetActualWidth(new WidgetPointer(arg0)), getWidgetActualWidth(new WidgetPointer(arg1))); + ivar5 = multiplyDivide(cs2method6143(), 255, ivar4); + setWidgetPosition(ivar5, 0, 0, 0, new WidgetPointer(arg1)); + if (cs2method6143() > 0) { + if (((boolean)arg3)) { + setWidgetSprite(4123, new WidgetPointer(744,108)); + } else { + setWidgetSprite(4118, new WidgetPointer(744,108)); + } + } else if (((boolean)arg3)) { + setWidgetSprite(4124, new WidgetPointer(744,108)); + } else { + setWidgetSprite(4119, new WidgetPointer(744,108)); + } + if (((boolean)arg2)) { + globalint_1394 = cs2method6143(); + } + return; +} diff --git a/dumps/scripts/2008.cs2 b/dumps/scripts/2008.cs2 new file mode 100644 index 0000000..d797672 --- /dev/null +++ b/dumps/scripts/2008.cs2 @@ -0,0 +1,4 @@ +void script_2008(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 86 Agility"); + return; +} diff --git a/dumps/scripts/2009.cs2 b/dumps/scripts/2009.cs2 new file mode 100644 index 0000000..a393463 --- /dev/null +++ b/dumps/scripts/2009.cs2 @@ -0,0 +1,4 @@ +void script_2009(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 90 Agility"); + return; +} diff --git a/dumps/scripts/201.cs2 b/dumps/scripts/201.cs2 new file mode 100644 index 0000000..5441926 --- /dev/null +++ b/dumps/scripts/201.cs2 @@ -0,0 +1,7 @@ +void script_201() { + if ((((boolean)globalint_1034) && ((boolean)globalint_1027)) && (strLength(globalstring_202) > 0)) { + sendUnknownFriendPacketMethod3619(globalstring_202); + globalint_1034 = 2; + } + return; +} diff --git a/dumps/scripts/2010.cs2 b/dumps/scripts/2010.cs2 new file mode 100644 index 0000000..2025c5f --- /dev/null +++ b/dumps/scripts/2010.cs2 @@ -0,0 +1,4 @@ +void script_2010(int arg0,int arg1,string arg2) { + script_311(arg0, arg1, getOtherCommonData(471, 596) + "
" + arg2); + return; +} diff --git a/dumps/scripts/2011.cs2 b/dumps/scripts/2011.cs2 new file mode 100644 index 0000000..7d0ab47 --- /dev/null +++ b/dumps/scripts/2011.cs2 @@ -0,0 +1,4 @@ +void script_2011(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 26 Agility"); + return; +} diff --git a/dumps/scripts/2012.cs2 b/dumps/scripts/2012.cs2 new file mode 100644 index 0000000..32aa8ac --- /dev/null +++ b/dumps/scripts/2012.cs2 @@ -0,0 +1,4 @@ +void script_2012(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 80 Agility"); + return; +} diff --git a/dumps/scripts/2013.cs2 b/dumps/scripts/2013.cs2 new file mode 100644 index 0000000..1cea175 --- /dev/null +++ b/dumps/scripts/2013.cs2 @@ -0,0 +1,4 @@ +void script_2013(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 70 Agility"); + return; +} diff --git a/dumps/scripts/2014.cs2 b/dumps/scripts/2014.cs2 new file mode 100644 index 0000000..3796e19 --- /dev/null +++ b/dumps/scripts/2014.cs2 @@ -0,0 +1,4 @@ +void script_2014(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 51 Agility"); + return; +} diff --git a/dumps/scripts/2015.cs2 b/dumps/scripts/2015.cs2 new file mode 100644 index 0000000..cfcaf2b --- /dev/null +++ b/dumps/scripts/2015.cs2 @@ -0,0 +1,4 @@ +void script_2015(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 38 Agility"); + return; +} diff --git a/dumps/scripts/2016.cs2 b/dumps/scripts/2016.cs2 new file mode 100644 index 0000000..656d06e --- /dev/null +++ b/dumps/scripts/2016.cs2 @@ -0,0 +1,4 @@ +void script_2016(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 53 Agility, level 42 Ranged, level 21 Strength" + "
" + "Requires a grapple"); + return; +} diff --git a/dumps/scripts/2017.cs2 b/dumps/scripts/2017.cs2 new file mode 100644 index 0000000..5eae92e --- /dev/null +++ b/dumps/scripts/2017.cs2 @@ -0,0 +1,4 @@ +void script_2017(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 43 Agility"); + return; +} diff --git a/dumps/scripts/2018.cs2 b/dumps/scripts/2018.cs2 new file mode 100644 index 0000000..c6aee84 --- /dev/null +++ b/dumps/scripts/2018.cs2 @@ -0,0 +1,4 @@ +void script_2018(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 41 Agility"); + return; +} diff --git a/dumps/scripts/2019.cs2 b/dumps/scripts/2019.cs2 new file mode 100644 index 0000000..d9056f7 --- /dev/null +++ b/dumps/scripts/2019.cs2 @@ -0,0 +1,4 @@ +void script_2019(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 15 Agility"); + return; +} diff --git a/dumps/scripts/202.cs2 b/dumps/scripts/202.cs2 new file mode 100644 index 0000000..413ed38 --- /dev/null +++ b/dumps/scripts/202.cs2 @@ -0,0 +1,25 @@ +void script_202(int arg0,int arg1,string arg2,string arg3) { + switch (arg0) { + case 5: + if (isFriend(arg3)) { + globalint_1650 = 1; + globalstring_23 = arg2; + script_1558(0); + return; + } + cs2method3605(arg2); + break; + case 6: + cs2method3607(arg2); + break; + case 7: + cs2method3606(arg2); + break; + case 8: + cs2method3608(arg2); + break; + case 9: + script_1633(arg2); + } + return; +} diff --git a/dumps/scripts/2020.cs2 b/dumps/scripts/2020.cs2 new file mode 100644 index 0000000..28674e4 --- /dev/null +++ b/dumps/scripts/2020.cs2 @@ -0,0 +1,37 @@ +void script_2020(int arg0,int arg1,int arg2,string arg3) { + deleteAllExtraChilds(new WidgetPointer(arg2)); + createExtraChild(new WidgetPointer(arg2), 5, 0); + setWidgetSize(10, 0, 1, 1); + setWidgetPosition(0, 0, 1, 1); + setWidgetSprite(3859); + createExtraChild(new WidgetPointer(arg2), 5, 1); + setWidgetSize(6, 0, 0, 1); + setWidgetPosition(0, 0, 0, 1); + setWidgetSprite(3857); + createExtraChild(new WidgetPointer(arg2), 5, 2); + setWidgetSize(6, 0, 0, 1); + setWidgetPosition(0, 0, 2, 1); + setWidgetSprite(3858); + createExtraChild(new WidgetPointer(arg2), 4, 3); + setWidgetSize(0, 0, 1, 1); + setWidgetPosition(0, 0, 1, 1); + setWidgetFont(494); + setWidgetTextAlignment(1, 1, 0); + setWidgetRGB(new Color(255, 152, 31)); + setWidgetUnknownBoolean(true); + setWidgetText(arg3); + setWidgetSize(arg1, 26, 0, 0, new WidgetPointer(arg2)); + setWidgetIsHidden(false, new WidgetPointer(arg2)); + setScriptCallOnMouseEntered(2021, new WidgetPointer(-32768,3), 1, "I1", new WidgetPointer(arg2)); + setScriptCallOnMouseExit(2021, new WidgetPointer(-32768,3), 0, "I1", new WidgetPointer(arg2)); + if (arg0 == -1) { + setWidgetNoOptions(new WidgetPointer(arg2)); + cs2method2310(new WidgetPointer(arg2), arg3); + setScriptCallOnMousePressed(2022, 1, arg0, "ii", new WidgetPointer(arg2)); + } else { + setWidgetContextMenuOption(1, new WidgetPointer(arg2), arg3); + cs2method2310(new WidgetPointer(arg2), ""); + setScriptCallOnClickContextMenu(2022, -2147483644, arg0, "ii", new WidgetPointer(arg2)); + } + return; +} diff --git a/dumps/scripts/2021.cs2 b/dumps/scripts/2021.cs2 new file mode 100644 index 0000000..6dcee16 --- /dev/null +++ b/dumps/scripts/2021.cs2 @@ -0,0 +1,24 @@ +void script_2021(int arg0,int arg1) { + if (((boolean)arg1)) { + if (setWidgetRegister(new WidgetPointer(arg0), 0)) { + setWidgetSprite(3862); + } + if (setWidgetRegister(new WidgetPointer(arg0), 1)) { + setWidgetSprite(3860); + } + if (setWidgetRegister(new WidgetPointer(arg0), 2)) { + setWidgetSprite(3861); + } + } else { + if (setWidgetRegister(new WidgetPointer(arg0), 0)) { + setWidgetSprite(3859); + } + if (setWidgetRegister(new WidgetPointer(arg0), 1)) { + setWidgetSprite(3857); + } + if (setWidgetRegister(new WidgetPointer(arg0), 2)) { + setWidgetSprite(3858); + } + } + return; +} diff --git a/dumps/scripts/2022.cs2 b/dumps/scripts/2022.cs2 new file mode 100644 index 0000000..154c0f4 --- /dev/null +++ b/dumps/scripts/2022.cs2 @@ -0,0 +1,14 @@ +void script_2022(int arg0,int arg1) { + if (arg0 != 1) { + return; + } + if (arg1 <= -1) { + setWidgetText(new WidgetPointer(916,17), ""); + return; + } + bitconfig_8095 = min(arg1, bitconfig_8094); + script_2047(); + setScriptCallOnGameloop(2024, add(getClientCycle(), 15), "i", new WidgetPointer(905,28)); + setWidgetIsHidden(false, new WidgetPointer(905,28)); + return; +} diff --git a/dumps/scripts/2023.cs2 b/dumps/scripts/2023.cs2 new file mode 100644 index 0000000..3b5149a --- /dev/null +++ b/dumps/scripts/2023.cs2 @@ -0,0 +1,10 @@ +void script_2023(int arg0,int arg1) { + if (arg0 != 1) { + return; + } + bitconfig_8095 = max(min(add(bitconfig_8095, arg1), bitconfig_8094), 0); + script_2047(); + setScriptCallOnGameloop(2024, add(getClientCycle(), 15), "i", new WidgetPointer(905,28)); + setWidgetIsHidden(false, new WidgetPointer(905,28)); + return; +} diff --git a/dumps/scripts/2024.cs2 b/dumps/scripts/2024.cs2 new file mode 100644 index 0000000..ffa211f --- /dev/null +++ b/dumps/scripts/2024.cs2 @@ -0,0 +1,8 @@ +void script_2024(int arg0) { + if (getClientCycle() < arg0) { + return; + } + setScriptCallOnGameloop(-1, "", new WidgetPointer(905,28)); + setWidgetIsHidden(true, new WidgetPointer(905,28)); + return; +} diff --git a/dumps/scripts/2025.cs2 b/dumps/scripts/2025.cs2 new file mode 100644 index 0000000..7a24f1a --- /dev/null +++ b/dumps/scripts/2025.cs2 @@ -0,0 +1,4 @@ +void script_2025() { + script_2047(); + return; +} diff --git a/dumps/scripts/2026.cs2 b/dumps/scripts/2026.cs2 new file mode 100644 index 0000000..8f54881 --- /dev/null +++ b/dumps/scripts/2026.cs2 @@ -0,0 +1,14 @@ +void script_2026() { + setWidgetFont(496, new WidgetPointer(752,4)); + setWidgetFont(496, new WidgetPointer(752,5)); + setWidgetSize(20, 40, 1, 0, new WidgetPointer(752,4)); + setWidgetSize(20, 20, 1, 0, new WidgetPointer(752,5)); + setWidgetPosition(0, 20, 1, 0, new WidgetPointer(752,4)); + setWidgetPosition(0, 60, 1, 0, new WidgetPointer(752,5)); + setScriptCallOnMouseOver(-1, "", new WidgetPointer(752,5)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(752,5)); + setScriptCallOnAnyWidgetOpenAndClose(-1, "", new WidgetPointer(752,5)); + setWidgetRGB(new Color(0, 0, 128), new WidgetPointer(752,5)); + deleteAllExtraChilds(new WidgetPointer(752,3)); + return; +} diff --git a/dumps/scripts/2027.cs2 b/dumps/scripts/2027.cs2 new file mode 100644 index 0000000..5186a1f --- /dev/null +++ b/dumps/scripts/2027.cs2 @@ -0,0 +1,32 @@ +void script_2027(int arg0) { + if (isBitFlagged(standart_config_331, 0)) { + setWidget3DRotation(0, 0, 512, 1536, 0, 400, new WidgetPointer(arg0)); + } else if (isBitFlagged(standart_config_331, 1)) { + setWidget3DRotation(0, 0, 512, 1664, 0, 400, new WidgetPointer(arg0)); + } else if (isBitFlagged(standart_config_331, 2)) { + setWidget3DRotation(0, 0, 512, 1792, 0, 400, new WidgetPointer(arg0)); + } else if (isBitFlagged(standart_config_331, 3)) { + setWidget3DRotation(0, 0, 512, 1920, 0, 400, new WidgetPointer(arg0)); + } else if (isBitFlagged(standart_config_331, 4)) { + setWidget3DRotation(0, 0, 512, 0, 0, 400, new WidgetPointer(arg0)); + } else if (isBitFlagged(standart_config_331, 5)) { + setWidget3DRotation(0, 0, 512, 128, 0, 400, new WidgetPointer(arg0)); + } else if (isBitFlagged(standart_config_331, 6)) { + setWidget3DRotation(0, 0, 512, 256, 0, 400, new WidgetPointer(arg0)); + } else if (isBitFlagged(standart_config_331, 7)) { + setWidget3DRotation(0, 0, 512, 384, 0, 400, new WidgetPointer(arg0)); + } else if (isBitFlagged(standart_config_331, 8)) { + setWidget3DRotation(0, 0, 512, 512, 0, 400, new WidgetPointer(arg0)); + } else if (isBitFlagged(standart_config_331, 9)) { + setWidget3DRotation(0, 0, 512, 640, 0, 400, new WidgetPointer(arg0)); + } else if (isBitFlagged(standart_config_331, 10)) { + setWidget3DRotation(0, 0, 512, 768, 0, 400, new WidgetPointer(arg0)); + } else if (isBitFlagged(standart_config_331, 11)) { + setWidget3DRotation(0, 0, 512, 896, 0, 400, new WidgetPointer(arg0)); + } else { + if (isBitFlagged(standart_config_331, 12)) { + setWidget3DRotation(0, 0, 512, 1024, 0, 400, new WidgetPointer(arg0)); + } + } + return; +} diff --git a/dumps/scripts/2028.cs2 b/dumps/scripts/2028.cs2 new file mode 100644 index 0000000..2488326 --- /dev/null +++ b/dumps/scripts/2028.cs2 @@ -0,0 +1,32 @@ +void script_2028(int arg0) { + if (isBitFlagged(standart_config_331, 13)) { + setWidget3DRotation(0, 0, 512, 1536, 0, 400, new WidgetPointer(arg0)); + } else if (isBitFlagged(standart_config_331, 14)) { + setWidget3DRotation(0, 0, 512, 1664, 0, 400, new WidgetPointer(arg0)); + } else if (isBitFlagged(standart_config_331, 15)) { + setWidget3DRotation(0, 0, 512, 1792, 0, 400, new WidgetPointer(arg0)); + } else if (isBitFlagged(standart_config_331, 16)) { + setWidget3DRotation(0, 0, 512, 1920, 0, 400, new WidgetPointer(arg0)); + } else if (isBitFlagged(standart_config_331, 17)) { + setWidget3DRotation(0, 0, 512, 0, 0, 400, new WidgetPointer(arg0)); + } else if (isBitFlagged(standart_config_331, 18)) { + setWidget3DRotation(0, 0, 512, 128, 0, 400, new WidgetPointer(arg0)); + } else if (isBitFlagged(standart_config_331, 19)) { + setWidget3DRotation(0, 0, 512, 256, 0, 400, new WidgetPointer(arg0)); + } else if (isBitFlagged(standart_config_331, 20)) { + setWidget3DRotation(0, 0, 512, 384, 0, 400, new WidgetPointer(arg0)); + } else if (isBitFlagged(standart_config_331, 21)) { + setWidget3DRotation(0, 0, 512, 512, 0, 400, new WidgetPointer(arg0)); + } else if (isBitFlagged(standart_config_331, 22)) { + setWidget3DRotation(0, 0, 512, 640, 0, 400, new WidgetPointer(arg0)); + } else if (isBitFlagged(standart_config_331, 23)) { + setWidget3DRotation(0, 0, 512, 768, 0, 400, new WidgetPointer(arg0)); + } else if (isBitFlagged(standart_config_331, 24)) { + setWidget3DRotation(0, 0, 512, 896, 0, 400, new WidgetPointer(arg0)); + } else { + if (isBitFlagged(standart_config_331, 25)) { + setWidget3DRotation(0, 0, 512, 1024, 0, 400, new WidgetPointer(arg0)); + } + } + return; +} diff --git a/dumps/scripts/2029.cs2 b/dumps/scripts/2029.cs2 new file mode 100644 index 0000000..d4ffd52 --- /dev/null +++ b/dumps/scripts/2029.cs2 @@ -0,0 +1,8 @@ +void script_2029(int arg0,int arg1) { + if (standart_config_330 > arg1) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(arg0)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/203.cs2 b/dumps/scripts/203.cs2 new file mode 100644 index 0000000..610f276 --- /dev/null +++ b/dumps/scripts/203.cs2 @@ -0,0 +1,8 @@ +void script_203(int arg0) { + if (cs2method5428(72679429, -1)) { + setScriptCallOnGameloop(204, "", new WidgetPointer(1109,5)); + return; + } + script_518(); + return; +} diff --git a/dumps/scripts/2030.cs2 b/dumps/scripts/2030.cs2 new file mode 100644 index 0000000..a9402fe --- /dev/null +++ b/dumps/scripts/2030.cs2 @@ -0,0 +1,12 @@ +void script_2030(int arg0) { + if (isBitFlagged(standart_config_331, 26)) { + setWidget3DRotation(0, 0, 512, 1024, 0, 1000, new WidgetPointer(arg0)); + } else if (isBitFlagged(standart_config_331, 27)) { + setWidget3DRotation(0, 0, 512, 1536, 0, 1000, new WidgetPointer(arg0)); + } else { + if (isBitFlagged(standart_config_331, 28)) { + setWidget3DRotation(0, 0, 512, 0, 0, 1000, new WidgetPointer(arg0)); + } + } + return; +} diff --git a/dumps/scripts/2031.cs2 b/dumps/scripts/2031.cs2 new file mode 100644 index 0000000..bcea378 --- /dev/null +++ b/dumps/scripts/2031.cs2 @@ -0,0 +1,12 @@ +void script_2031(int arg0) { + if (isBitFlagged(standart_config_331, 29)) { + setWidget3DRotation(0, 0, 512, 1024, 0, 1000, new WidgetPointer(arg0)); + } else if (isBitFlagged(standart_config_331, 30)) { + setWidget3DRotation(0, 0, 512, 1536, 0, 1000, new WidgetPointer(arg0)); + } else { + if (isBitFlagged(standart_config_331, 31)) { + setWidget3DRotation(0, 0, 512, 0, 0, 1000, new WidgetPointer(arg0)); + } + } + return; +} diff --git a/dumps/scripts/2032.cs2 b/dumps/scripts/2032.cs2 new file mode 100644 index 0000000..c543c61 --- /dev/null +++ b/dumps/scripts/2032.cs2 @@ -0,0 +1,83 @@ +void script_2032() { + setWidgetIsHidden(true, new WidgetPointer(366,2)); + setWidgetIsHidden(true, new WidgetPointer(366,3)); + setWidgetIsHidden(true, new WidgetPointer(366,4)); + setWidgetIsHidden(true, new WidgetPointer(366,5)); + setWidgetIsHidden(true, new WidgetPointer(366,6)); + setWidgetIsHidden(true, new WidgetPointer(366,7)); + setWidgetIsHidden(true, new WidgetPointer(366,8)); + setWidgetIsHidden(true, new WidgetPointer(366,9)); + setWidgetIsHidden(true, new WidgetPointer(366,10)); + setWidgetIsHidden(true, new WidgetPointer(366,11)); + setWidgetIsHidden(true, new WidgetPointer(366,12)); + setWidgetIsHidden(true, new WidgetPointer(366,13)); + setWidgetIsHidden(true, new WidgetPointer(366,14)); + setWidgetIsHidden(true, new WidgetPointer(366,15)); + setWidgetIsHidden(true, new WidgetPointer(366,16)); + setWidgetIsHidden(true, new WidgetPointer(366,17)); + setWidgetIsHidden(true, new WidgetPointer(366,18)); + setWidgetIsHidden(true, new WidgetPointer(366,19)); + setWidgetIsHidden(true, new WidgetPointer(366,20)); + setWidgetIsHidden(true, new WidgetPointer(366,21)); + if (standart_config_391 > 0) { + setWidgetIsHidden(false, new WidgetPointer(366,2)); + } + if (standart_config_391 > 4) { + setWidgetIsHidden(false, new WidgetPointer(366,3)); + } + if (standart_config_391 > 9) { + setWidgetIsHidden(false, new WidgetPointer(366,4)); + } + if (standart_config_391 > 14) { + setWidgetIsHidden(false, new WidgetPointer(366,5)); + } + if (standart_config_391 > 19) { + setWidgetIsHidden(false, new WidgetPointer(366,6)); + } + if (standart_config_391 > 24) { + setWidgetIsHidden(false, new WidgetPointer(366,7)); + } + if (standart_config_391 > 29) { + setWidgetIsHidden(false, new WidgetPointer(366,8)); + } + if (standart_config_391 > 34) { + setWidgetIsHidden(false, new WidgetPointer(366,9)); + } + if (standart_config_391 > 39) { + setWidgetIsHidden(false, new WidgetPointer(366,10)); + } + if (standart_config_391 > 44) { + setWidgetIsHidden(false, new WidgetPointer(366,11)); + } + if (standart_config_391 > 49) { + setWidgetIsHidden(false, new WidgetPointer(366,12)); + } + if (standart_config_391 > 54) { + setWidgetIsHidden(false, new WidgetPointer(366,13)); + } + if (standart_config_391 > 59) { + setWidgetIsHidden(false, new WidgetPointer(366,14)); + } + if (standart_config_391 > 64) { + setWidgetIsHidden(false, new WidgetPointer(366,15)); + } + if (standart_config_391 > 69) { + setWidgetIsHidden(false, new WidgetPointer(366,16)); + } + if (standart_config_391 > 74) { + setWidgetIsHidden(false, new WidgetPointer(366,17)); + } + if (standart_config_391 > 79) { + setWidgetIsHidden(false, new WidgetPointer(366,18)); + } + if (standart_config_391 > 84) { + setWidgetIsHidden(false, new WidgetPointer(366,19)); + } + if (standart_config_391 > 89) { + setWidgetIsHidden(false, new WidgetPointer(366,20)); + } + if (standart_config_391 > 94) { + setWidgetIsHidden(false, new WidgetPointer(366,21)); + } + return; +} diff --git a/dumps/scripts/2033.cs2 b/dumps/scripts/2033.cs2 new file mode 100644 index 0000000..37365ee --- /dev/null +++ b/dumps/scripts/2033.cs2 @@ -0,0 +1,78 @@ +void script_2033() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + ivar0 = getItemAmtInContainer(93, 2169); + ivar1 = getItemAmtInContainer(93, 2162); + ivar2 = getItemAmtInContainer(93, 2128); + ivar3 = getItemAmtInContainer(93, 2152); + ivar4 = getItemAmtInContainer(93, 1973); + if ((ivar3 >= 2) && (ivar0 >= 1)) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(437,37)); + } else { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(437,37)); + } + if ((ivar2 >= 2) && (ivar0 >= 1)) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(437,38)); + } else { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(437,38)); + } + if (((ivar2 >= 1) && (ivar0 >= 1)) && (ivar1 >= 2)) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(437,39)); + } else { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(437,39)); + } + if ((ivar4 >= 2) && (ivar0 >= 1)) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(437,40)); + } else { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(437,40)); + } + if (getItemAmtInContainer(93, 2152) > 1) { + setItemOnWidgetMethod2200(2152, 100, new WidgetPointer(437,4)); + } else { + setItemOnWidgetMethod2200(9499, 100, new WidgetPointer(437,4)); + } + if (getItemAmtInContainer(93, 2169) > 0) { + setItemOnWidgetMethod2200(2169, 90, new WidgetPointer(437,5)); + } else { + setItemOnWidgetMethod2200(9500, 90, new WidgetPointer(437,5)); + } + if (getItemAmtInContainer(93, 2128) > 1) { + setItemOnWidgetMethod2200(2128, 120, new WidgetPointer(437,12)); + } else { + setItemOnWidgetMethod2200(9494, 120, new WidgetPointer(437,12)); + } + if (getItemAmtInContainer(93, 2169) > 0) { + setItemOnWidgetMethod2200(2169, 90, new WidgetPointer(437,11)); + } else { + setItemOnWidgetMethod2200(9500, 90, new WidgetPointer(437,11)); + } + if (getItemAmtInContainer(93, 1973) > 1) { + setItemOnWidgetMethod2200(1973, 140, new WidgetPointer(437,27)); + } else { + setItemOnWidgetMethod2200(9507, 140, new WidgetPointer(437,27)); + } + if (getItemAmtInContainer(93, 2169) > 0) { + setItemOnWidgetMethod2200(2169, 90, new WidgetPointer(437,28)); + } else { + setItemOnWidgetMethod2200(9500, 90, new WidgetPointer(437,28)); + } + if (getItemAmtInContainer(93, 2162) > 1) { + setItemOnWidgetMethod2200(2162, 100, new WidgetPointer(437,19)); + } else { + setItemOnWidgetMethod2200(9501, 100, new WidgetPointer(437,19)); + } + if (getItemAmtInContainer(93, 2128) > 0) { + setItemOnWidgetMethod2200(2128, 120, new WidgetPointer(437,20)); + } else { + setItemOnWidgetMethod2200(9494, 120, new WidgetPointer(437,20)); + } + if (getItemAmtInContainer(93, 2169) > 0) { + setItemOnWidgetMethod2200(2169, 90, new WidgetPointer(437,18)); + } else { + setItemOnWidgetMethod2200(9500, 90, new WidgetPointer(437,18)); + } + return; +} diff --git a/dumps/scripts/2034.cs2 b/dumps/scripts/2034.cs2 new file mode 100644 index 0000000..4505ac9 --- /dev/null +++ b/dumps/scripts/2034.cs2 @@ -0,0 +1,3 @@ +int script_2034() { + return add(add(add(add(add(add(add(add(add(add(add(bitconfig_5782, bitconfig_5783), bitconfig_5785), bitconfig_5787), bitconfig_5786), bitconfig_5788), bitconfig_5790), bitconfig_5789), bitconfig_5791), bitconfig_5793), bitconfig_5792), bitconfig_5784); +} diff --git a/dumps/scripts/2035.cs2 b/dumps/scripts/2035.cs2 new file mode 100644 index 0000000..1e9ac95 --- /dev/null +++ b/dumps/scripts/2035.cs2 @@ -0,0 +1,17 @@ +int script_2035() { + int ivar0; + ivar0 = 0; + ivar0 = add(ivar0, 5); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 5); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 5); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 5); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + return ivar0; +} diff --git a/dumps/scripts/2036.cs2 b/dumps/scripts/2036.cs2 new file mode 100644 index 0000000..0669762 --- /dev/null +++ b/dumps/scripts/2036.cs2 @@ -0,0 +1,3 @@ +int script_2036() { + return add(add(add(add(add(add(add(add(add(add(add(bitconfig_5799, bitconfig_5805), bitconfig_5794), bitconfig_5797), bitconfig_5795), bitconfig_5800), bitconfig_5796), bitconfig_5798), bitconfig_5802), bitconfig_5803), bitconfig_5804), bitconfig_5801); +} diff --git a/dumps/scripts/2037.cs2 b/dumps/scripts/2037.cs2 new file mode 100644 index 0000000..df93719 --- /dev/null +++ b/dumps/scripts/2037.cs2 @@ -0,0 +1,17 @@ +int script_2037() { + int ivar0; + ivar0 = 0; + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 15); + ivar0 = add(ivar0, 15); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + return ivar0; +} diff --git a/dumps/scripts/2038.cs2 b/dumps/scripts/2038.cs2 new file mode 100644 index 0000000..cb4a529 --- /dev/null +++ b/dumps/scripts/2038.cs2 @@ -0,0 +1,3 @@ +int script_2038() { + return add(add(add(add(add(add(add(add(add(add(bitconfig_5811, bitconfig_5806), bitconfig_5810), bitconfig_5809), bitconfig_5807), bitconfig_5808), bitconfig_5812), bitconfig_5814), bitconfig_5815), bitconfig_5816), bitconfig_5813); +} diff --git a/dumps/scripts/2039.cs2 b/dumps/scripts/2039.cs2 new file mode 100644 index 0000000..a04a27c --- /dev/null +++ b/dumps/scripts/2039.cs2 @@ -0,0 +1,16 @@ +int script_2039() { + int ivar0; + ivar0 = 0; + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 5); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 5); + ivar0 = add(ivar0, 5); + ivar0 = add(ivar0, 5); + ivar0 = add(ivar0, 1); + return ivar0; +} diff --git a/dumps/scripts/204.cs2 b/dumps/scripts/204.cs2 new file mode 100644 index 0000000..4036230 --- /dev/null +++ b/dumps/scripts/204.cs2 @@ -0,0 +1,8 @@ +void script_204() { + if (cs2method5428(72679429, -1)) { + return; + } + setScriptCallOnGameloop(-1, "", new WidgetPointer(1109,5)); + script_518(); + return; +} diff --git a/dumps/scripts/2040.cs2 b/dumps/scripts/2040.cs2 new file mode 100644 index 0000000..5e0bb5d --- /dev/null +++ b/dumps/scripts/2040.cs2 @@ -0,0 +1,8 @@ +void script_2040(int arg0) { + if (((boolean)bitconfig_949)) { + setWidgetText(new WidgetPointer(arg0), "Coal to add: " + intToStr(bitconfig_940)); + } else { + setWidgetText(new WidgetPointer(arg0), "Coal in furnace: " + intToStr(bitconfig_949)); + } + return; +} diff --git a/dumps/scripts/2041.cs2 b/dumps/scripts/2041.cs2 new file mode 100644 index 0000000..f08c880 --- /dev/null +++ b/dumps/scripts/2041.cs2 @@ -0,0 +1,75 @@ +void script_2041() { + setWidgetText(new WidgetPointer(28,42), "Bronze: " + intToStr(bitconfig_941)); + if (bitconfig_941 > 0) { + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(28,44)); + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(28,42)); + } else { + setWidgetRGB(new Color(153, 153, 153), new WidgetPointer(28,44)); + setWidgetRGB(new Color(153, 153, 153), new WidgetPointer(28,42)); + } + setWidgetText(new WidgetPointer(28,39), "Iron: " + intToStr(bitconfig_942)); + if (bitconfig_942 > 0) { + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(28,41)); + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(28,39)); + } else { + setWidgetRGB(new Color(153, 153, 153), new WidgetPointer(28,41)); + setWidgetRGB(new Color(153, 153, 153), new WidgetPointer(28,39)); + } + setWidgetText(new WidgetPointer(28,37), "Steel: " + intToStr(bitconfig_943)); + if (bitconfig_943 > 0) { + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(28,38)); + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(28,37)); + } else { + setWidgetRGB(new Color(153, 153, 153), new WidgetPointer(28,38)); + setWidgetRGB(new Color(153, 153, 153), new WidgetPointer(28,37)); + } + setWidgetText(new WidgetPointer(28,34), "Mithril: " + intToStr(bitconfig_944)); + if (bitconfig_944 > 0) { + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(28,35)); + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(28,34)); + } else { + setWidgetRGB(new Color(153, 153, 153), new WidgetPointer(28,35)); + setWidgetRGB(new Color(153, 153, 153), new WidgetPointer(28,34)); + } + setWidgetText(new WidgetPointer(28,31), "Adamantite: " + intToStr(bitconfig_945)); + if (bitconfig_945 > 0) { + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(28,32)); + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(28,31)); + } else { + setWidgetRGB(new Color(153, 153, 153), new WidgetPointer(28,32)); + setWidgetRGB(new Color(153, 153, 153), new WidgetPointer(28,31)); + } + setWidgetText(new WidgetPointer(28,28), "Runite: " + intToStr(bitconfig_946)); + if (bitconfig_946 > 0) { + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(28,29)); + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(28,28)); + } else { + setWidgetRGB(new Color(153, 153, 153), new WidgetPointer(28,29)); + setWidgetRGB(new Color(153, 153, 153), new WidgetPointer(28,28)); + } + setWidgetText(new WidgetPointer(28,25), "Silver: " + intToStr(bitconfig_948)); + if (bitconfig_948 > 0) { + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(28,26)); + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(28,25)); + } else { + setWidgetRGB(new Color(153, 153, 153), new WidgetPointer(28,26)); + setWidgetRGB(new Color(153, 153, 153), new WidgetPointer(28,25)); + } + setWidgetText(new WidgetPointer(28,22), "Gold: " + intToStr(bitconfig_947)); + if (bitconfig_947 > 0) { + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(28,23)); + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(28,22)); + } else { + setWidgetRGB(new Color(153, 153, 153), new WidgetPointer(28,23)); + setWidgetRGB(new Color(153, 153, 153), new WidgetPointer(28,22)); + } + setWidgetText(new WidgetPointer(28,2), "Perfect Gold: " + intToStr(bitconfig_958)); + if (bitconfig_958 > 0) { + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(28,4)); + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(28,2)); + } else { + setWidgetRGB(new Color(153, 153, 153), new WidgetPointer(28,4)); + setWidgetRGB(new Color(153, 153, 153), new WidgetPointer(28,2)); + } + return; +} diff --git a/dumps/scripts/2042.cs2 b/dumps/scripts/2042.cs2 new file mode 100644 index 0000000..5643d9d --- /dev/null +++ b/dumps/scripts/2042.cs2 @@ -0,0 +1,17 @@ +cs2func_script_2042_struct(2,1,0) script_2042(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + string svar0; + svar0 = "null"; + ivar3 = -1; + ivar4 = 1; + if (((boolean)script_1024(arg2))) { + svar0 = "" + "130 combined levels in " + "" + "Attack and Strength" + "" + " is one of the requirements for " + "" + getCommonString(1481, arg2) + "" + "."; + } else { + svar0 = "" + "You now have all the levels necessary to complete " + "" + getCommonString(1481, arg2) + "" + "."; + } + if (ivar3 == -1) { + ivar3 = 6513; + } + return newstruct cs2func_script_2042_struct(ivar3, ivar4, svar0); +} diff --git a/dumps/scripts/2043.cs2 b/dumps/scripts/2043.cs2 new file mode 100644 index 0000000..62d85a0 --- /dev/null +++ b/dumps/scripts/2043.cs2 @@ -0,0 +1,4 @@ +void script_2043(int arg0) { + setWidgetText(new WidgetPointer(arg0), intToStr(standart_config_157)); + return; +} diff --git a/dumps/scripts/2044.cs2 b/dumps/scripts/2044.cs2 new file mode 100644 index 0000000..a6a6028 --- /dev/null +++ b/dumps/scripts/2044.cs2 @@ -0,0 +1,88 @@ +void script_2044() { + setWidgetIsHidden(true, new WidgetPointer(325,2)); + setWidgetIsHidden(true, new WidgetPointer(325,3)); + setWidgetIsHidden(true, new WidgetPointer(325,10)); + setWidgetIsHidden(true, new WidgetPointer(325,8)); + setWidgetIsHidden(true, new WidgetPointer(325,4)); + setWidgetIsHidden(true, new WidgetPointer(325,6)); + setWidgetIsHidden(true, new WidgetPointer(325,5)); + setWidgetIsHidden(true, new WidgetPointer(325,11)); + setWidgetIsHidden(true, new WidgetPointer(325,9)); + setWidgetIsHidden(true, new WidgetPointer(325,7)); + setWidgetIsHidden(true, new WidgetPointer(325,12)); + setWidgetIsHidden(true, new WidgetPointer(325,31)); + setWidgetIsHidden(true, new WidgetPointer(325,30)); + setWidgetIsHidden(true, new WidgetPointer(325,29)); + setWidgetIsHidden(true, new WidgetPointer(325,28)); + setWidgetIsHidden(true, new WidgetPointer(325,27)); + setWidgetIsHidden(true, new WidgetPointer(325,26)); + setWidgetIsHidden(true, new WidgetPointer(325,25)); + setWidgetIsHidden(true, new WidgetPointer(325,24)); + setWidgetIsHidden(true, new WidgetPointer(325,23)); + setWidgetIsHidden(true, new WidgetPointer(325,22)); + switch (standart_config_158) { + case 0: + setWidgetIsHidden(false, new WidgetPointer(325,2)); + break; + case 1: + setWidgetIsHidden(false, new WidgetPointer(325,3)); + break; + case 2: + setWidgetIsHidden(false, new WidgetPointer(325,10)); + break; + case 3: + setWidgetIsHidden(false, new WidgetPointer(325,8)); + break; + case 4: + setWidgetIsHidden(false, new WidgetPointer(325,4)); + break; + case 5: + setWidgetIsHidden(false, new WidgetPointer(325,6)); + break; + case 6: + setWidgetIsHidden(false, new WidgetPointer(325,5)); + break; + case 7: + setWidgetIsHidden(false, new WidgetPointer(325,11)); + break; + case 8: + setWidgetIsHidden(false, new WidgetPointer(325,9)); + break; + case 9: + setWidgetIsHidden(false, new WidgetPointer(325,7)); + break; + case 10: + setWidgetIsHidden(false, new WidgetPointer(325,12)); + } + if (standart_config_156 < 2) { + setWidgetIsHidden(false, new WidgetPointer(325,31)); + } + if (standart_config_156 < 3) { + setWidgetIsHidden(false, new WidgetPointer(325,30)); + } + if (standart_config_156 < 4) { + setWidgetIsHidden(false, new WidgetPointer(325,29)); + } + if (standart_config_156 < 5) { + setWidgetIsHidden(false, new WidgetPointer(325,28)); + } + if (standart_config_156 < 6) { + setWidgetIsHidden(false, new WidgetPointer(325,27)); + } + if (standart_config_156 < 7) { + setWidgetIsHidden(false, new WidgetPointer(325,26)); + } + if (standart_config_156 < 8) { + setWidgetIsHidden(false, new WidgetPointer(325,25)); + } + if (standart_config_156 < 9) { + setWidgetIsHidden(false, new WidgetPointer(325,24)); + } + if (standart_config_156 < 10) { + setWidgetIsHidden(false, new WidgetPointer(325,23)); + } + if (standart_config_156 < 11) { + setWidgetIsHidden(false, new WidgetPointer(325,22)); + } + return; +} diff --git a/dumps/scripts/2045.cs2 b/dumps/scripts/2045.cs2 new file mode 100644 index 0000000..6c8048d --- /dev/null +++ b/dumps/scripts/2045.cs2 @@ -0,0 +1,59 @@ +void script_2045(int arg0,int arg1,int arg2,int arg3,int arg4) { + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + opcStruct5208(2,0,0) structdump_0; + opcStruct5209(2,0,0) structdump_1; + if (cs2method5220()) { + script_2046(arg0); + return; + } + ivar5 = getWidgetActualWidth(new WidgetPointer(arg1)); + if (ivar5 <= 0) { + return; + } + ivar6 = 0; + ivar7 = 0; + structdump_0 = cs2method5208(); + ivar7 = structdump_0.intpart_1; + ivar6 = structdump_0.intpart_0; + if (ivar6 <= 0) { + return; + } + ivar8 = 0; + ivar9 = 0; + ivar10 = 0; + ivar11 = 0; + ivar12 = 0; + ivar13 = 0; + structdump_1 = cs2method5209(); + ivar13 = structdump_1.intpart_1; + ivar12 = structdump_1.intpart_0; + ivar8 = add(ivar13, divide(ivar7, 2)); + ivar9 = subtract(ivar13, divide(ivar7, 2)); + ivar10 = add(ivar12, divide(ivar6, 2)); + ivar11 = subtract(ivar12, divide(ivar6, 2)); + ivar11 = add(ivar11, multiplyDivide(ivar6, ivar5, subtract(ivar5, getWidgetActualWidth(new WidgetPointer(arg0))))); + if (((ivar12 != arg2) || (ivar13 != arg3)) || (ivar7 != arg4)) { + setScriptCallOnGameloop(2045, new WidgetPointer(arg0), new WidgetPointer(arg1), ivar12, ivar13, ivar7, "IIiii", new WidgetPointer(arg0)); + script_295(arg0, ivar8, ivar9, ivar10, ivar11); + } + if (((boolean)bitconfig_6174)) { + script_4(49479716, globalint_674, 280, arg0, ivar8, ivar9, ivar10, ivar11, "You are here"); + } else { + deleteAllExtraChilds(new WidgetPointer(755,36)); + } + script_4(49479717, globalint_623, globalint_624, arg0, ivar8, ivar9, ivar10, ivar11, globalstring_53); + script_4(49479718, globalint_625, globalint_626, arg0, ivar8, ivar9, ivar10, ivar11, globalstring_54); + script_4(49479719, globalint_627, globalint_628, arg0, ivar8, ivar9, ivar10, ivar11, globalstring_55); + script_4(49479720, globalint_629, globalint_630, arg0, ivar8, ivar9, ivar10, ivar11, globalstring_56); + script_4(49479721, globalint_940, globalint_941, arg0, ivar8, ivar9, ivar10, ivar11, globalstring_190); + script_4(49479722, standart_config_1159, 972, arg0, ivar8, ivar9, ivar10, ivar11, "Your marker"); + return; +} diff --git a/dumps/scripts/2046.cs2 b/dumps/scripts/2046.cs2 new file mode 100644 index 0000000..04771da --- /dev/null +++ b/dumps/scripts/2046.cs2 @@ -0,0 +1,12 @@ +void script_2046(int arg0) { + setScriptCallOnGameloop(2045, new WidgetPointer(arg0), new WidgetPointer(755,28), 0, 0, 0, "IIiii", new WidgetPointer(arg0)); + deleteAllExtraChilds(new WidgetPointer(arg0)); + deleteAllExtraChilds(new WidgetPointer(755,36)); + deleteAllExtraChilds(new WidgetPointer(755,37)); + deleteAllExtraChilds(new WidgetPointer(755,38)); + deleteAllExtraChilds(new WidgetPointer(755,39)); + deleteAllExtraChilds(new WidgetPointer(755,40)); + deleteAllExtraChilds(new WidgetPointer(755,41)); + deleteAllExtraChilds(new WidgetPointer(755,42)); + return; +} diff --git a/dumps/scripts/2047.cs2 b/dumps/scripts/2047.cs2 new file mode 100644 index 0000000..7311a63 --- /dev/null +++ b/dumps/scripts/2047.cs2 @@ -0,0 +1,52 @@ +void script_2047() { + string svar0; + if (((boolean)script_1103()) && (bitconfig_8095 >= bitconfig_8094)) { + setWidgetText(new WidgetPointer(916,17), "All"); + } else { + setWidgetText(new WidgetPointer(916,17), intToStr(bitconfig_8095)); + } + svar0 = script_1111(); + if (isWidgetHidden(new WidgetPointer(905,14))) { + cs2method2310(new WidgetPointer(905,14), svar0); + } + if (isWidgetHidden(new WidgetPointer(905,15))) { + cs2method2310(new WidgetPointer(905,15), svar0); + } + if (isWidgetHidden(new WidgetPointer(905,16))) { + cs2method2310(new WidgetPointer(905,16), svar0); + } + if (isWidgetHidden(new WidgetPointer(905,17))) { + cs2method2310(new WidgetPointer(905,17), svar0); + } + if (isWidgetHidden(new WidgetPointer(905,18))) { + cs2method2310(new WidgetPointer(905,18), svar0); + } + if (isWidgetHidden(new WidgetPointer(905,19))) { + cs2method2310(new WidgetPointer(905,19), svar0); + } + if (isWidgetHidden(new WidgetPointer(905,20))) { + cs2method2310(new WidgetPointer(905,20), svar0); + } + if (isWidgetHidden(new WidgetPointer(905,21))) { + cs2method2310(new WidgetPointer(905,21), svar0); + } + if (isWidgetHidden(new WidgetPointer(905,22))) { + cs2method2310(new WidgetPointer(905,22), svar0); + } + if (isWidgetHidden(new WidgetPointer(905,23))) { + cs2method2310(new WidgetPointer(905,23), svar0); + } + if (isWidgetHidden(new WidgetPointer(905,24))) { + cs2method2310(new WidgetPointer(905,24), svar0); + } + if (isWidgetHidden(new WidgetPointer(905,25))) { + cs2method2310(new WidgetPointer(905,25), svar0); + } + if (isWidgetHidden(new WidgetPointer(905,26))) { + cs2method2310(new WidgetPointer(905,26), svar0); + } + if (isWidgetHidden(new WidgetPointer(905,27))) { + cs2method2310(new WidgetPointer(905,27), svar0); + } + return; +} diff --git a/dumps/scripts/2048.cs2 b/dumps/scripts/2048.cs2 new file mode 100644 index 0000000..4c47e4c --- /dev/null +++ b/dumps/scripts/2048.cs2 @@ -0,0 +1,9 @@ +void script_2048(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12,string arg13,string arg14) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + script_2049(arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + } else { + createExtraChild(new WidgetPointer(arg0), 5, arg1); + script_2049(arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + } + return; +} diff --git a/dumps/scripts/2049.cs2 b/dumps/scripts/2049.cs2 new file mode 100644 index 0000000..56e915d --- /dev/null +++ b/dumps/scripts/2049.cs2 @@ -0,0 +1,33 @@ +void script_2049(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,string arg11,string arg12) { + int ivar11; + int ivar12; + setWidgetHidden(0); + setWidgetSize(arg1, arg2, 0, 0); + setWidgetPosition(arg3, arg4, 1, 1); + cs2method1106(arg5); + cs2method1107(arg6); + setWidgetHFlip(arg7); + setWidgetVFlip(arg8); + setWidgetSprite(arg0); + ivar11 = 0; + ivar12 = 0; + if (((boolean)arg9)) { + cs2method1122(1); + ivar11 = mod(getClientCycle(), 50); + ivar12 = divide(50, 2); + if (ivar11 <= ivar12) { + cs2method2103(subtract(255, multiplyDivide(ivar11, ivar12, 255))); + } else { + cs2method2103(multiplyDivide(subtract(ivar11, ivar12), ivar12, 255)); + } + } + if (arg10 != -1) { + cs2method1305("" + arg11 + ""); + setWidgetContextMenuOption(1, arg12); + setScriptCallOnClickContextMenu(2053, -2147483644, new WidgetPointer(-32768,3), arg10, "iIc"); + } else { + setWidgetContextMenuOption(1, ""); + setScriptCallOnClickContextMenu(-1, ""); + } + return; +} diff --git a/dumps/scripts/205.cs2 b/dumps/scripts/205.cs2 new file mode 100644 index 0000000..9d9787e --- /dev/null +++ b/dumps/scripts/205.cs2 @@ -0,0 +1,98 @@ +void script_205(int arg0) { + if ((bitconfig_8902 > 0) && (bitconfig_8902 < 13)) { + if (getWidgetSpriteId(new WidgetPointer(825,94)) == 5459) { + setWidgetSprite(5457, new WidgetPointer(825,94)); + } else { + if (getWidgetSpriteId(new WidgetPointer(825,94)) == 5458) { + setWidgetSprite(5455, new WidgetPointer(825,94)); + } + } + if (getWidgetSpriteId(new WidgetPointer(825,98)) == 5459) { + setWidgetSprite(5457, new WidgetPointer(825,98)); + } else { + if (getWidgetSpriteId(new WidgetPointer(825,98)) == 5458) { + setWidgetSprite(5455, new WidgetPointer(825,98)); + } + } + if (getWidgetSpriteId(new WidgetPointer(825,102)) == 5459) { + setWidgetSprite(5457, new WidgetPointer(825,102)); + } else { + if (getWidgetSpriteId(new WidgetPointer(825,102)) == 5458) { + setWidgetSprite(5455, new WidgetPointer(825,102)); + } + } + if (getWidgetSpriteId(new WidgetPointer(825,106)) == 5459) { + setWidgetSprite(5457, new WidgetPointer(825,106)); + } else { + if (getWidgetSpriteId(new WidgetPointer(825,106)) == 5458) { + setWidgetSprite(5455, new WidgetPointer(825,106)); + } + } + if (getWidgetSpriteId(new WidgetPointer(825,110)) == 5459) { + setWidgetSprite(5457, new WidgetPointer(825,110)); + } else { + if (getWidgetSpriteId(new WidgetPointer(825,110)) == 5458) { + setWidgetSprite(5455, new WidgetPointer(825,110)); + } + } + if (getWidgetSpriteId(new WidgetPointer(825,114)) == 5459) { + setWidgetSprite(5457, new WidgetPointer(825,114)); + } else { + if (getWidgetSpriteId(new WidgetPointer(825,114)) == 5458) { + setWidgetSprite(5455, new WidgetPointer(825,114)); + } + } + if (getWidgetSpriteId(new WidgetPointer(825,118)) == 5459) { + setWidgetSprite(5457, new WidgetPointer(825,118)); + } else { + if (getWidgetSpriteId(new WidgetPointer(825,118)) == 5458) { + setWidgetSprite(5455, new WidgetPointer(825,118)); + } + } + if (getWidgetSpriteId(new WidgetPointer(825,122)) == 5459) { + setWidgetSprite(5457, new WidgetPointer(825,122)); + } else { + if (getWidgetSpriteId(new WidgetPointer(825,122)) == 5458) { + setWidgetSprite(5455, new WidgetPointer(825,122)); + } + } + if (getWidgetSpriteId(new WidgetPointer(825,126)) == 5459) { + setWidgetSprite(5457, new WidgetPointer(825,126)); + } else { + if (getWidgetSpriteId(new WidgetPointer(825,126)) == 5458) { + setWidgetSprite(5455, new WidgetPointer(825,126)); + } + } + if (getWidgetSpriteId(new WidgetPointer(825,130)) == 5459) { + setWidgetSprite(5457, new WidgetPointer(825,130)); + } else { + if (getWidgetSpriteId(new WidgetPointer(825,130)) == 5458) { + setWidgetSprite(5455, new WidgetPointer(825,130)); + } + } + if (getWidgetSpriteId(new WidgetPointer(825,0)) == 5459) { + setWidgetSprite(5457, new WidgetPointer(825,0)); + } else { + if (getWidgetSpriteId(new WidgetPointer(825,0)) == 5458) { + setWidgetSprite(5455, new WidgetPointer(825,0)); + } + } + if (getWidgetSpriteId(new WidgetPointer(825,137)) == 5459) { + setWidgetSprite(5457, new WidgetPointer(825,137)); + } else { + if (getWidgetSpriteId(new WidgetPointer(825,137)) == 5458) { + setWidgetSprite(5455, new WidgetPointer(825,137)); + } + } + } + if (getWidgetSpriteId(new WidgetPointer(arg0)) == 5456) { + setWidgetSprite(5458, new WidgetPointer(arg0)); + } + if (getWidgetSpriteId(new WidgetPointer(arg0)) == 5455) { + setWidgetSprite(5458, new WidgetPointer(arg0)); + } + if (getWidgetSpriteId(new WidgetPointer(arg0)) == 5457) { + setWidgetSprite(5459, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/2050.cs2 b/dumps/scripts/2050.cs2 new file mode 100644 index 0000000..076a8fe --- /dev/null +++ b/dumps/scripts/2050.cs2 @@ -0,0 +1,9 @@ +void script_2050(int arg0,int arg1) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetHidden(1); + } else { + createExtraChild(new WidgetPointer(arg0), 5, arg1); + setWidgetHidden(1); + } + return; +} diff --git a/dumps/scripts/2051.cs2 b/dumps/scripts/2051.cs2 new file mode 100644 index 0000000..698e5ea --- /dev/null +++ b/dumps/scripts/2051.cs2 @@ -0,0 +1,9 @@ +void script_2051(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,string arg8,string arg9,string arg10) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + script_2052(arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + } else { + createExtraChild(new WidgetPointer(arg0), 4, arg1); + script_2052(arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + } + return; +} diff --git a/dumps/scripts/2052.cs2 b/dumps/scripts/2052.cs2 new file mode 100644 index 0000000..7efbbf8 --- /dev/null +++ b/dumps/scripts/2052.cs2 @@ -0,0 +1,18 @@ +void script_2052(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,string arg6,string arg7,string arg8) { + setWidgetHidden(0); + setWidgetSize(arg0, arg1, 0, 0); + setWidgetPosition(arg2, arg3, 1, 1); + setWidgetRGB(new Color(arg4)); + setWidgetFont(591); + setWidgetTextAlignment(1, 1, 13); + setWidgetText(arg6); + if (arg5 != -1) { + cs2method1305("" + arg7 + ""); + setWidgetContextMenuOption(1, arg8); + setScriptCallOnClickContextMenu(2053, -2147483644, new WidgetPointer(-32768,3), arg5, "iIc"); + } else { + setWidgetContextMenuOption(1, ""); + setScriptCallOnClickContextMenu(-1, ""); + } + return; +} diff --git a/dumps/scripts/2053.cs2 b/dumps/scripts/2053.cs2 new file mode 100644 index 0000000..1b08412 --- /dev/null +++ b/dumps/scripts/2053.cs2 @@ -0,0 +1,6 @@ +void script_2053(int arg0,int arg1,int arg2) { + if (((boolean)arg0)) { + setScriptCallOnGameloop(2054, add(getClientCycle(), 3), new WidgetPointer(arg1), arg2, "iIc", new WidgetPointer(arg1)); + } + return; +} diff --git a/dumps/scripts/2054.cs2 b/dumps/scripts/2054.cs2 new file mode 100644 index 0000000..a19d002 --- /dev/null +++ b/dumps/scripts/2054.cs2 @@ -0,0 +1,7 @@ +void script_2054(int arg0,int arg1,int arg2) { + if (getClientCycle() >= arg0) { + cs2method5214(arg2); + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg1)); + } + return; +} diff --git a/dumps/scripts/2055.cs2 b/dumps/scripts/2055.cs2 new file mode 100644 index 0000000..7184682 --- /dev/null +++ b/dumps/scripts/2055.cs2 @@ -0,0 +1,3 @@ +string script_2055(int arg0) { + return intToStr(extractZ(arg0)) + "_" + intToStr(divide(extractX(arg0), 64)) + "_" + intToStr(divide(extractY(arg0), 64)) + "_" + intToStr(mod(extractX(arg0), 64)) + "_" + intToStr(mod(extractY(arg0), 64)); +} diff --git a/dumps/scripts/2056.cs2 b/dumps/scripts/2056.cs2 new file mode 100644 index 0000000..ceca33a --- /dev/null +++ b/dumps/scripts/2056.cs2 @@ -0,0 +1,11 @@ +void script_2056() { + int ivar0; + ivar0 = 20054023; + globalint_762 = cs2method_3408(105, 109, 208, rndExcl(getCommonDefinitionSize(208))); + if (globalint_762 != -1) { + setWidgetModel(globalint_762, new WidgetPointer(ivar0)); + } + setWidgetPosition(subtract(0, getWidgetActualWidth(new WidgetPointer(ivar0))), 120, 0, 0, new WidgetPointer(ivar0)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(306,20)); + return; +} diff --git a/dumps/scripts/2057.cs2 b/dumps/scripts/2057.cs2 new file mode 100644 index 0000000..ba4fd15 --- /dev/null +++ b/dumps/scripts/2057.cs2 @@ -0,0 +1,4 @@ +void script_2057() { + script_2059(-1); + return; +} diff --git a/dumps/scripts/2058.cs2 b/dumps/scripts/2058.cs2 new file mode 100644 index 0000000..254eaa6 --- /dev/null +++ b/dumps/scripts/2058.cs2 @@ -0,0 +1,4 @@ +void script_2058(int arg0) { + script_2059(arg0); + return; +} diff --git a/dumps/scripts/2059.cs2 b/dumps/scripts/2059.cs2 new file mode 100644 index 0000000..f9ac775 --- /dev/null +++ b/dumps/scripts/2059.cs2 @@ -0,0 +1,141 @@ +void script_2059(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + ivar1 = -1; + ivar2 = 0; + if (((boolean)script_1119())) { + ivar1 = cs2method_3408(105, 74, 728, bitconfig_357); + ivar2 = 1; + } else { + ivar1 = cs2method_3408(105, 74, 2162, bitconfig_357); + } + ivar3 = 0; + globalarray_0 = new int[4]; + switch (bitconfig_357) { + case 0: + ivar3 = bitconfig_5822; + globalarray_0[0] = bitconfig_6459; + globalarray_0[1] = bitconfig_6460; + globalarray_0[2] = bitconfig_6461; + globalarray_0[3] = bitconfig_6462; + break; + case 1: + ivar3 = bitconfig_5823; + globalarray_0[0] = bitconfig_6466; + globalarray_0[1] = 0; + globalarray_0[2] = 0; + globalarray_0[3] = bitconfig_6467; + break; + case 2: + ivar3 = bitconfig_5824; + globalarray_0[0] = bitconfig_6463; + globalarray_0[1] = 0; + globalarray_0[2] = bitconfig_6464; + globalarray_0[3] = bitconfig_6465; + break; + case 3: + ivar3 = bitconfig_7347; + globalarray_0[0] = bitconfig_7348; + globalarray_0[1] = bitconfig_7349; + globalarray_0[2] = bitconfig_7350; + globalarray_0[3] = bitconfig_7351; + } + if (arg0 != -1) { + if (ivar3 != arg0) { + playSoundEffect(5845, 1, 0); + } + ivar3 = arg0; + } + globalint_631 = ivar3; + ivar4 = cs2method_3408(105, 103, getOtherCommonData(ivar1, 662), ivar3); + ivar5 = getOtherCommonData(ivar1, 654); + ivar6 = getOtherCommonData(ivar1, 655); + ivar7 = getCommonDefinitionSize(ivar4); + ivar8 = 0; + ivar9 = 0; + ivar10 = -1; + ivar11 = 0; + ivar12 = 0; + ivar13 = 0; + ivar14 = -1; + ivar15 = -1; + ivar16 = -1; + while (ivar9 < ivar7) { + ivar10 = cs2method_3408(105, 103, ivar4, ivar9); + if (ivar10 != -1) { + ivar8 = getCommonDefinitionSize(ivar10); + ivar11 = 0; + ivar13 = 0; + while (ivar11 < ivar8) { + ivar14 = ((int)cs2method_3408(105, 73, ivar10, ivar13)); + if (ivar14 != -1) { + ivar11 = add(ivar11, 1); + ivar15 = cs2method_3408(73, 105, 727, ivar14); + if (((ivar15 == -1) || ((boolean)globalarray_0[ivar15])) && (isMember() || ((boolean)cs2method_3408(73, 105, 743, ivar14)))) { + ivar12 = add(ivar12, 1); + setWidgetPosition(ivar6, ivar5, 0, 0, new WidgetPointer(ivar14)); + setWidgetIsHidden(false, new WidgetPointer(ivar14)); + ivar6 = add(ivar6, add(getOtherCommonData(ivar1, 657), getOtherCommonData(ivar1, 658))); + if (((boolean)mod(ivar12, getOtherCommonData(ivar1, 660)))) { + ivar5 = add(ivar5, add(getOtherCommonData(ivar1, 656), getOtherCommonData(ivar1, 659))); + ivar6 = getOtherCommonData(ivar1, 655); + } + ivar16 = cs2method_3408(73, 64, 209, ivar14); + if (ivar16 != -1) { + cs2method2308(ivar16, 36, new WidgetPointer(ivar14)); + } + } else { + setWidgetIsHidden(true, new WidgetPointer(ivar14)); + } + } + ivar13 = add(ivar13, 1); + if (ivar13 > 997) { + return; + } + } + } + ivar9 = add(ivar9, 1); + } + if (((boolean)ivar2)) { + setWidgetScrollMax(getWidgetActualWidth(new WidgetPointer(getOtherCommonData(ivar1, 316))), add(add(ivar5, getOtherCommonData(ivar1, 656)), getOtherCommonData(ivar1, 654)), new WidgetPointer(getOtherCommonData(ivar1, 316))); + script_31(getOtherCommonData(ivar1, 684), getOtherCommonData(ivar1, 316), 792, 789, 790, 791, 773, 788); + } else { + if (setWidgetRegister(new WidgetPointer(getOtherCommonData(ivar1, 316)))) { + cs2method1100(0, 0); + deleteAllExtraChilds(new WidgetPointer(getOtherCommonData(ivar1, 684))); + } + } + ivar17 = getOtherCommonData(ivar1, 663); + ivar18 = 0; + if (ivar17 != -1) { + ivar18 = getCommonDefinitionSize(ivar17); + ivar13 = 0; + while (ivar13 < ivar18) { + if (ivar13 == ivar3) { + setWidgetSprite(1703, cs2method_3408(105, 73, ivar17, ivar13)); + } else { + setWidgetSprite(1701, cs2method_3408(105, 73, ivar17, ivar13)); + } + ivar13 = add(ivar13, 1); + } + } + script_1121(); + deleteAllExtraChilds(new WidgetPointer(getOtherCommonData(ivar1, 688))); + return; +} diff --git a/dumps/scripts/206.cs2 b/dumps/scripts/206.cs2 new file mode 100644 index 0000000..2559cce --- /dev/null +++ b/dumps/scripts/206.cs2 @@ -0,0 +1,110 @@ +void script_206() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + string svar0; + string svar1; + ivar0 = 0; + ivar1 = 0; + ivar2 = -1; + svar0 = ""; + svar1 = ""; + ivar3 = getItemContainerLength(134); + globalarray_0 = new int[ivar3]; + globalarray_1 = new int[ivar3]; + ivar4 = 0; + ivar5 = 99; + ivar6 = 0; + while (ivar0 < ivar3) { + ivar2 = getItemIdInSlot(134, ivar0); + ivar1 = getItemAmtInSlot(134, ivar0); + if (ivar2 != -1) { + ivar5 = 99; + ivar6 = 0; + while (ivar6 < ivar3) { + if (globalarray_0[ivar6] != -1) { + if (globalarray_0[ivar6] == ivar2) { + ivar5 = ivar6; + ivar6 = ivar3; + } + ivar6 = add(ivar6, 1); + } else { + ivar6 = ivar3; + } + } + if (ivar5 == 99) { + globalarray_0[ivar4] = ivar2; + globalarray_0[ivar4] = ivar1; + ivar4 = add(ivar4, 1); + } else { + globalarray_0[ivar5] = add(globalarray_1[ivar5], ivar1); + } + } + ivar0 = add(ivar0, 1); + } + ivar4 = 0; + while (ivar4 < ivar3) { + ivar2 = globalarray_0[ivar4]; + if (ivar2 != -1) { + ivar1 = globalarray_1[ivar4]; + svar0 = concat(svar0, script_207(2, ivar1, ivar2)); + } else { + ivar4 = ivar3; + } + ivar4 = add(ivar4, 1); + } + ivar0 = 0; + ivar4 = 0; + while (ivar4 < ivar3) { + globalarray_0[ivar4] = -1; + globalarray_0[ivar4] = 0; + ivar4 = add(ivar4, 1); + } + ivar4 = 0; + ivar6 = 0; + while (ivar0 < ivar3) { + ivar2 = getItemIdInSlotSplit(134, ivar0); + ivar1 = getItemAmtInSlotSplit(134, ivar0); + if (ivar2 != -1) { + ivar5 = 99; + ivar6 = 0; + while (ivar6 < ivar3) { + if (globalarray_0[ivar6] != -1) { + if (globalarray_0[ivar6] == ivar2) { + ivar5 = ivar6; + ivar6 = ivar3; + } + ivar6 = add(ivar6, 1); + } else { + ivar6 = ivar3; + } + } + if (ivar5 == 99) { + globalarray_0[ivar4] = ivar2; + globalarray_0[ivar4] = ivar1; + ivar4 = add(ivar4, 1); + } else { + globalarray_0[ivar5] = add(globalarray_1[ivar5], ivar1); + } + } + ivar0 = add(ivar0, 1); + } + ivar4 = 0; + while (ivar4 < ivar3) { + ivar2 = globalarray_0[ivar4]; + if (ivar2 != -1) { + ivar1 = globalarray_1[ivar4]; + svar1 = concat(svar1, script_207(2, ivar1, ivar2)); + } else { + ivar4 = ivar3; + } + ivar4 = add(ivar4, 1); + } + setWidgetText(new WidgetPointer(626,36), svar0); + setWidgetText(new WidgetPointer(626,37), svar1); + return; +} diff --git a/dumps/scripts/2060.cs2 b/dumps/scripts/2060.cs2 new file mode 100644 index 0000000..aee935f --- /dev/null +++ b/dumps/scripts/2060.cs2 @@ -0,0 +1,17 @@ +void script_2060(int arg0) { + int ivar1; + int ivar2; + int ivar3; + ivar1 = cs2method_3408(105, 74, 2162, bitconfig_357); + ivar2 = cs2method_3408(73, 105, getOtherCommonData(ivar1, 664), arg0); + ivar3 = getOtherCommonData(ivar1, 661); + if (ivar3 != -1) { + script_41(ivar3); + } + if (ivar2 == globalint_631) { + setWidgetSprite(1703, new WidgetPointer(arg0)); + } else { + setWidgetSprite(1701, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/2061.cs2 b/dumps/scripts/2061.cs2 new file mode 100644 index 0000000..71c1f20 --- /dev/null +++ b/dumps/scripts/2061.cs2 @@ -0,0 +1,17 @@ +void script_2061(int arg0) { + int ivar1; + int ivar2; + int ivar3; + string svar0; + ivar1 = cs2method_3408(105, 74, 2162, bitconfig_357); + ivar2 = cs2method_3408(73, 105, getOtherCommonData(ivar1, 664), arg0); + ivar3 = getOtherCommonData(ivar1, 661); + svar0 = cs2method_3408(105, 115, getOtherCommonData(ivar1, 665), ivar2); + if (ivar3 != -1) { + script_39(arg0, ivar3, 25, 300, svar0); + } + if (ivar2 != globalint_631) { + setWidgetSprite(1702, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/2062.cs2 b/dumps/scripts/2062.cs2 new file mode 100644 index 0000000..8778edd --- /dev/null +++ b/dumps/scripts/2062.cs2 @@ -0,0 +1,4 @@ +void script_2062() { + script_2064(-1); + return; +} diff --git a/dumps/scripts/2063.cs2 b/dumps/scripts/2063.cs2 new file mode 100644 index 0000000..025d7b7 --- /dev/null +++ b/dumps/scripts/2063.cs2 @@ -0,0 +1,4 @@ +void script_2063() { + script_2064(standart_config_153); + return; +} diff --git a/dumps/scripts/2064.cs2 b/dumps/scripts/2064.cs2 new file mode 100644 index 0000000..1057d02 --- /dev/null +++ b/dumps/scripts/2064.cs2 @@ -0,0 +1,85 @@ +void script_2064(int arg0) { + int ivar1; + setWidgetIsHidden(true, new WidgetPointer(138,28)); + setWidgetIsHidden(true, new WidgetPointer(138,37)); + setWidgetIsHidden(true, new WidgetPointer(138,36)); + setWidgetIsHidden(true, new WidgetPointer(138,31)); + setWidgetIsHidden(true, new WidgetPointer(138,39)); + setWidgetIsHidden(true, new WidgetPointer(138,38)); + setWidgetIsHidden(true, new WidgetPointer(138,35)); + setWidgetIsHidden(true, new WidgetPointer(138,34)); + setWidgetIsHidden(true, new WidgetPointer(138,33)); + setWidgetIsHidden(true, new WidgetPointer(138,32)); + setWidgetIsHidden(true, new WidgetPointer(138,29)); + setWidgetIsHidden(true, new WidgetPointer(138,30)); + setWidgetIsHidden(true, new WidgetPointer(138,41)); + setWidgetIsHidden(true, new WidgetPointer(138,40)); + ivar1 = 0; + if (bitconfig_5332 < 120) { + ivar1 = 1; + } + setWidgetIsHidden(((boolean)ivar1), new WidgetPointer(138,6)); + setWidgetIsHidden(((boolean)ivar1), new WidgetPointer(138,7)); + setWidgetIsHidden(((boolean)ivar1), new WidgetPointer(138,8)); + setWidgetIsHidden(((boolean)ivar1), new WidgetPointer(138,19)); + setWidgetIsHidden(((boolean)ivar1), new WidgetPointer(138,20)); + setWidgetIsHidden(((boolean)ivar1), new WidgetPointer(138,21)); + setWidgetIsHidden(((boolean)ivar1), new WidgetPointer(138,12)); + switch (arg0) { + case 0: + setWidgetIsHidden(false, new WidgetPointer(138,28)); + break; + case 1: + setWidgetIsHidden(false, new WidgetPointer(138,37)); + setWidgetAnimation(786, new WidgetPointer(138,37)); + break; + case 2: + setWidgetIsHidden(false, new WidgetPointer(138,36)); + setWidgetAnimation(786, new WidgetPointer(138,36)); + break; + case 3: + setWidgetIsHidden(false, new WidgetPointer(138,31)); + setWidgetAnimation(785, new WidgetPointer(138,31)); + break; + case 4: + setWidgetIsHidden(false, new WidgetPointer(138,39)); + setWidgetAnimation(785, new WidgetPointer(138,39)); + break; + case 5: + setWidgetIsHidden(false, new WidgetPointer(138,38)); + setWidgetAnimation(785, new WidgetPointer(138,38)); + break; + case 6: + setWidgetIsHidden(false, new WidgetPointer(138,35)); + setWidgetAnimation(785, new WidgetPointer(138,35)); + break; + case 7: + setWidgetIsHidden(false, new WidgetPointer(138,34)); + setWidgetAnimation(785, new WidgetPointer(138,34)); + break; + case 8: + setWidgetIsHidden(false, new WidgetPointer(138,32)); + setWidgetAnimation(785, new WidgetPointer(138,32)); + break; + case 9: + setWidgetIsHidden(false, new WidgetPointer(138,33)); + setWidgetAnimation(785, new WidgetPointer(138,33)); + break; + case 10: + setWidgetIsHidden(false, new WidgetPointer(138,29)); + setWidgetAnimation(785, new WidgetPointer(138,29)); + break; + case 11: + setWidgetIsHidden(false, new WidgetPointer(138,30)); + setWidgetAnimation(785, new WidgetPointer(138,30)); + break; + case 12: + setWidgetIsHidden(false, new WidgetPointer(138,41)); + setWidgetAnimation(786, new WidgetPointer(138,41)); + break; + case 13: + setWidgetIsHidden(false, new WidgetPointer(138,40)); + setWidgetAnimation(786, new WidgetPointer(138,40)); + } + return; +} diff --git a/dumps/scripts/2065.cs2 b/dumps/scripts/2065.cs2 new file mode 100644 index 0000000..5d4612f --- /dev/null +++ b/dumps/scripts/2065.cs2 @@ -0,0 +1,4 @@ +void script_2065(int arg0,int arg1,int arg2,int arg3,int arg4) { + script_2070(arg0, arg1, arg2, arg3, arg4); + return; +} diff --git a/dumps/scripts/2066.cs2 b/dumps/scripts/2066.cs2 new file mode 100644 index 0000000..00efcc5 --- /dev/null +++ b/dumps/scripts/2066.cs2 @@ -0,0 +1,4 @@ +void script_2066(int arg0,int arg1,int arg2,int arg3) { + script_2070(arg0, add(globalint_656, 1), arg1, arg2, arg3); + return; +} diff --git a/dumps/scripts/2067.cs2 b/dumps/scripts/2067.cs2 new file mode 100644 index 0000000..4411a70 --- /dev/null +++ b/dumps/scripts/2067.cs2 @@ -0,0 +1,4 @@ +void script_2067(int arg0,int arg1,int arg2,int arg3) { + script_2070(arg0, subtract(globalint_656, 1), arg1, arg2, arg3); + return; +} diff --git a/dumps/scripts/2068.cs2 b/dumps/scripts/2068.cs2 new file mode 100644 index 0000000..136b379 --- /dev/null +++ b/dumps/scripts/2068.cs2 @@ -0,0 +1,4 @@ +void script_2068(int arg0,int arg1,int arg2,int arg3) { + script_2070(arg0, 0, arg1, arg2, arg3); + return; +} diff --git a/dumps/scripts/2069.cs2 b/dumps/scripts/2069.cs2 new file mode 100644 index 0000000..096c7b2 --- /dev/null +++ b/dumps/scripts/2069.cs2 @@ -0,0 +1,4 @@ +void script_2069(int arg0,int arg1,int arg2,int arg3) { + script_2070(arg0, subtract(globalint_657, 1), arg1, arg2, arg3); + return; +} diff --git a/dumps/scripts/207.cs2 b/dumps/scripts/207.cs2 new file mode 100644 index 0000000..fd8c0a0 --- /dev/null +++ b/dumps/scripts/207.cs2 @@ -0,0 +1,23 @@ +string script_207(int arg0,int arg1,int arg2) { + string svar0; + string svar1; + string svar2; + svar0 = ""; + svar1 = ""; + svar2 = ""; + if (itemIsStackable(arg2)) { + svar2 = concat(svar2, "" + getItemName(arg2) + " " + "" + "x " + "" + intToStr(arg1) + "
"); + } else if (arg1 < 100000) { + svar0 = formatNumber(arg1, 1); + svar2 = concat(svar2, "" + getItemName(arg2) + "" + " x " + "" + svar0 + "
"); + } else if (arg1 < 10000000) { + svar0 = formatNumber(arg1, 1); + svar1 = formatNumber(divide(arg1, 1000), 1); + svar2 = concat(svar2, "" + getItemName(arg2) + "" + " x " + "" + svar1 + "K (" + svar0 + ")" + "
"); + } else { + svar0 = formatNumber(arg1, 1); + svar1 = formatNumber(divide(arg1, 1000000), 1); + svar2 = concat(svar2, "" + getItemName(arg2) + "" + " x " + "" + svar1 + "M (" + svar0 + ")" + "
"); + } + return svar2; +} diff --git a/dumps/scripts/2070.cs2 b/dumps/scripts/2070.cs2 new file mode 100644 index 0000000..3f10195 --- /dev/null +++ b/dumps/scripts/2070.cs2 @@ -0,0 +1,12 @@ +void script_2070(int arg0,int arg1,int arg2,int arg3,int arg4) { + if (arg0 != 1) { + return; + } + if ((arg1 >= globalint_657) || (arg1 < 0)) { + return; + } + globalint_656 = arg1; + playSoundEffect2False(3550, 1, 0, 100); + script_1439(arg2, arg3, arg4); + return; +} diff --git a/dumps/scripts/2071.cs2 b/dumps/scripts/2071.cs2 new file mode 100644 index 0000000..123c0f9 --- /dev/null +++ b/dumps/scripts/2071.cs2 @@ -0,0 +1,30 @@ +cs2func_script_2071_struct(2,0,0) script_2071(int arg0) { + if (((boolean)arg0)) { + cs2method5405(0, 8); + cs2method5405(1, 8); + cs2method5406(0, 0, 30756001, 1845, 30756002, 1845, 0); + cs2method5406(1, 0, 30903456, 890, 30903456, 890, 0); + cs2method5406(0, 1, 30821543, 1710, 30870697, 1710, 0); + cs2method5406(1, 1, 30903456, 890, 30903456, 890, 0); + script_1899(0, 300, 300); + cs2method5406(0, 2, 30985384, 1620, 31018151, 1620, 0); + cs2method5406(1, 2, 30903456, 890, 30903456, 890, 0); + script_1899(1, 300, 300); + cs2method5406(0, 3, 31067299, 1522, 31083680, 1522, 0); + cs2method5406(1, 3, 30903456, 890, 30903456, 890, 0); + script_1899(2, 400, 400); + cs2method5406(0, 4, 31067292, 1470, 31050906, 1470, 0); + cs2method5406(1, 4, 30903456, 890, 30903456, 890, 0); + script_1899(3, 300, 300); + cs2method5406(0, 5, 30936215, 1450, 30870679, 1450, 0); + cs2method5406(1, 5, 30903456, 890, 30903456, 890, 0); + script_1899(4, 300, 300); + cs2method5406(0, 6, 30821529, 1445, 30788762, 1445, 0); + cs2method5406(1, 6, 30903456, 890, 30903456, 890, 0); + script_1899(5, 300, 300); + cs2method5406(0, 7, 30756001, 1450, 30756002, 1450, 0); + cs2method5406(1, 7, 30903456, 890, 30903456, 890, 0); + script_1899(6, 300, 300); + } + return newstruct cs2func_script_2071_struct(30821543, 1250324); +} diff --git a/dumps/scripts/2072.cs2 b/dumps/scripts/2072.cs2 new file mode 100644 index 0000000..46a3b81 --- /dev/null +++ b/dumps/scripts/2072.cs2 @@ -0,0 +1,4 @@ +void script_2072() { + setWidgetText(new WidgetPointer(276,59), "Zeal: " + intToStr(bitconfig_5827)); + return; +} diff --git a/dumps/scripts/2073.cs2 b/dumps/scripts/2073.cs2 new file mode 100644 index 0000000..efeded1 --- /dev/null +++ b/dumps/scripts/2073.cs2 @@ -0,0 +1,25 @@ +void script_2073(int arg0) { + switch (arg0) { + case 18087988: + case 18087940: + setWidgetIsHidden(false, new WidgetPointer(276,79)); + setWidgetIsHidden(true, new WidgetPointer(276,80)); + setWidgetIsHidden(true, new WidgetPointer(276,78)); + break; + case 18087957: + case 18087987: + setWidgetIsHidden(true, new WidgetPointer(276,79)); + setWidgetIsHidden(true, new WidgetPointer(276,80)); + setWidgetIsHidden(false, new WidgetPointer(276,78)); + break; + case 18087958: + case 18087941: + setWidgetIsHidden(true, new WidgetPointer(276,79)); + setWidgetIsHidden(false, new WidgetPointer(276,80)); + setWidgetIsHidden(true, new WidgetPointer(276,78)); + break; + default: + return; + } + return; +} diff --git a/dumps/scripts/2074.cs2 b/dumps/scripts/2074.cs2 new file mode 100644 index 0000000..e311060 --- /dev/null +++ b/dumps/scripts/2074.cs2 @@ -0,0 +1,8 @@ +void script_2074() { + if (((boolean)globalint_632)) { + setWidgetText(new WidgetPointer(837,8), "Players needed"); + } else { + setWidgetText(new WidgetPointer(837,8), "Players in game"); + } + return; +} diff --git a/dumps/scripts/2075.cs2 b/dumps/scripts/2075.cs2 new file mode 100644 index 0000000..52c5475 --- /dev/null +++ b/dumps/scripts/2075.cs2 @@ -0,0 +1,15 @@ +void script_2075() { + int ivar0; + ivar0 = 0; + if (((boolean)globalint_632)) { + if (subtract(10, globalint_633) > 0) { + ivar0 = subtract(10, globalint_633); + } else { + ivar0 = 0; + } + setWidgetText(new WidgetPointer(837,3), intToStr(ivar0)); + } else { + setWidgetText(new WidgetPointer(837,3), intToStr(globalint_637)); + } + return; +} diff --git a/dumps/scripts/2076.cs2 b/dumps/scripts/2076.cs2 new file mode 100644 index 0000000..7b80e86 --- /dev/null +++ b/dumps/scripts/2076.cs2 @@ -0,0 +1,15 @@ +void script_2076() { + int ivar0; + ivar0 = 0; + if (((boolean)globalint_632)) { + if (subtract(10, globalint_634) > 0) { + ivar0 = subtract(10, globalint_634); + } else { + ivar0 = 0; + } + setWidgetText(new WidgetPointer(837,5), intToStr(ivar0)); + } else { + setWidgetText(new WidgetPointer(837,5), intToStr(globalint_638)); + } + return; +} diff --git a/dumps/scripts/2077.cs2 b/dumps/scripts/2077.cs2 new file mode 100644 index 0000000..eaa9bd2 --- /dev/null +++ b/dumps/scripts/2077.cs2 @@ -0,0 +1,19 @@ +void script_2077() { + int ivar0; + int ivar1; + ivar0 = 0; + ivar1 = 0; + if (((boolean)globalint_632)) { + ivar0 = subtract(3, globalint_635); + if (((boolean)ivar0)) { + setWidgetText(new WidgetPointer(837,9), "New game: " + intToStr(ivar0) + " min"); + } else { + setWidgetText(new WidgetPointer(837,9), "New game: " + intToStr(ivar0) + " mins"); + } + } else { + ivar1 = subtract(20, globalint_636); + ivar0 = add(ivar1, 3); + setWidgetText(new WidgetPointer(837,9), "New game: " + intToStr(ivar0) + " mins"); + } + return; +} diff --git a/dumps/scripts/2078.cs2 b/dumps/scripts/2078.cs2 new file mode 100644 index 0000000..89965c4 --- /dev/null +++ b/dumps/scripts/2078.cs2 @@ -0,0 +1,11 @@ +void script_2078() { + int ivar0; + ivar0 = 0; + ivar0 = subtract(20, globalint_636); + if (((boolean)ivar0)) { + setWidgetText(new WidgetPointer(836,27), intToStr(ivar0) + " min"); + } else { + setWidgetText(new WidgetPointer(836,27), intToStr(ivar0) + " mins"); + } + return; +} diff --git a/dumps/scripts/2079.cs2 b/dumps/scripts/2079.cs2 new file mode 100644 index 0000000..d598692 --- /dev/null +++ b/dumps/scripts/2079.cs2 @@ -0,0 +1,4 @@ +void script_2079() { + setWidgetText(new WidgetPointer(836,9), intToStr(globalint_643)); + return; +} diff --git a/dumps/scripts/208.cs2 b/dumps/scripts/208.cs2 new file mode 100644 index 0000000..b7e05e2 --- /dev/null +++ b/dumps/scripts/208.cs2 @@ -0,0 +1,3 @@ +int script_208() { + return 0; +} diff --git a/dumps/scripts/2080.cs2 b/dumps/scripts/2080.cs2 new file mode 100644 index 0000000..9e24132 --- /dev/null +++ b/dumps/scripts/2080.cs2 @@ -0,0 +1,4 @@ +void script_2080() { + setWidgetText(new WidgetPointer(836,13), intToStr(globalint_644)); + return; +} diff --git a/dumps/scripts/2081.cs2 b/dumps/scripts/2081.cs2 new file mode 100644 index 0000000..4e465b5 --- /dev/null +++ b/dumps/scripts/2081.cs2 @@ -0,0 +1,8 @@ +void script_2081() { + if (globalint_639 > 0) { + setWidgetText(new WidgetPointer(836,10), intToStr(globalint_641)); + } else { + setWidgetText(new WidgetPointer(836,10), "---"); + } + return; +} diff --git a/dumps/scripts/2082.cs2 b/dumps/scripts/2082.cs2 new file mode 100644 index 0000000..ae4a272 --- /dev/null +++ b/dumps/scripts/2082.cs2 @@ -0,0 +1,8 @@ +void script_2082() { + if (globalint_640 > 0) { + setWidgetText(new WidgetPointer(836,14), intToStr(globalint_642)); + } else { + setWidgetText(new WidgetPointer(836,14), "---"); + } + return; +} diff --git a/dumps/scripts/2083.cs2 b/dumps/scripts/2083.cs2 new file mode 100644 index 0000000..d2bbf94 --- /dev/null +++ b/dumps/scripts/2083.cs2 @@ -0,0 +1,8 @@ +void script_2083() { + if (globalint_639 > 0) { + setWidgetText(new WidgetPointer(836,11), intToStr(globalint_639) + "%"); + } else { + setWidgetText(new WidgetPointer(836,11), "---"); + } + return; +} diff --git a/dumps/scripts/2084.cs2 b/dumps/scripts/2084.cs2 new file mode 100644 index 0000000..0141a31 --- /dev/null +++ b/dumps/scripts/2084.cs2 @@ -0,0 +1,8 @@ +void script_2084() { + if (globalint_640 > 0) { + setWidgetText(new WidgetPointer(836,15), intToStr(globalint_640) + "%"); + } else { + setWidgetText(new WidgetPointer(836,15), "---"); + } + return; +} diff --git a/dumps/scripts/2085.cs2 b/dumps/scripts/2085.cs2 new file mode 100644 index 0000000..7d6ef87 --- /dev/null +++ b/dumps/scripts/2085.cs2 @@ -0,0 +1,10 @@ +void script_2085() { + if (globalint_645 <= 5) { + setWidgetRGB(new Color(51, 102, 255), new WidgetPointer(836,29)); + } else if (globalint_645 >= 25) { + setWidgetRGB(new Color(225, 35, 35), new WidgetPointer(836,29)); + } else { + setWidgetRGB(new Color(102, 102, 102), new WidgetPointer(836,29)); + } + return; +} diff --git a/dumps/scripts/2086.cs2 b/dumps/scripts/2086.cs2 new file mode 100644 index 0000000..860edb3 --- /dev/null +++ b/dumps/scripts/2086.cs2 @@ -0,0 +1,10 @@ +void script_2086() { + if (globalint_647 <= 5) { + setWidgetRGB(new Color(51, 102, 255), new WidgetPointer(836,31)); + } else if (globalint_647 >= 25) { + setWidgetRGB(new Color(225, 35, 35), new WidgetPointer(836,31)); + } else { + setWidgetRGB(new Color(102, 102, 102), new WidgetPointer(836,31)); + } + return; +} diff --git a/dumps/scripts/2087.cs2 b/dumps/scripts/2087.cs2 new file mode 100644 index 0000000..7145f38 --- /dev/null +++ b/dumps/scripts/2087.cs2 @@ -0,0 +1,10 @@ +void script_2087() { + if (globalint_649 <= 5) { + setWidgetRGB(new Color(51, 102, 255), new WidgetPointer(836,30)); + } else if (globalint_649 >= 25) { + setWidgetRGB(new Color(225, 35, 35), new WidgetPointer(836,30)); + } else { + setWidgetRGB(new Color(102, 102, 102), new WidgetPointer(836,30)); + } + return; +} diff --git a/dumps/scripts/2088.cs2 b/dumps/scripts/2088.cs2 new file mode 100644 index 0000000..4228813 --- /dev/null +++ b/dumps/scripts/2088.cs2 @@ -0,0 +1,18 @@ +void script_2088() { + int ivar0; + int ivar1; + ivar0 = 0; + ivar1 = 0; + ivar0 = cs2method_3408(105, 105, 723, globalint_645); + ivar1 = cs2method_3408(105, 105, 2196, globalint_645); + if (globalint_645 < 15) { + setWidgetRGB(new Color(51, 102, 255), new WidgetPointer(836,5)); + } else if (globalint_645 > 15) { + setWidgetRGB(new Color(225, 35, 35), new WidgetPointer(836,5)); + } else { + setWidgetRGB(new Color(102, 102, 102), new WidgetPointer(836,5)); + } + setWidgetPosition(ivar0, 66, 2, 0, new WidgetPointer(836,5)); + setWidgetSize(ivar1, 8, 0, 0, new WidgetPointer(836,5)); + return; +} diff --git a/dumps/scripts/2089.cs2 b/dumps/scripts/2089.cs2 new file mode 100644 index 0000000..abebd87 --- /dev/null +++ b/dumps/scripts/2089.cs2 @@ -0,0 +1,18 @@ +void script_2089() { + int ivar0; + int ivar1; + ivar0 = 0; + ivar1 = 0; + ivar0 = cs2method_3408(105, 105, 723, globalint_647); + ivar1 = cs2method_3408(105, 105, 2196, globalint_647); + if (globalint_647 < 15) { + setWidgetRGB(new Color(51, 102, 255), new WidgetPointer(836,68)); + } else if (globalint_647 > 15) { + setWidgetRGB(new Color(225, 35, 35), new WidgetPointer(836,68)); + } else { + setWidgetRGB(new Color(102, 102, 102), new WidgetPointer(836,68)); + } + setWidgetPosition(ivar0, 66, 2, 0, new WidgetPointer(836,68)); + setWidgetSize(ivar1, 8, 0, 0, new WidgetPointer(836,68)); + return; +} diff --git a/dumps/scripts/209.cs2 b/dumps/scripts/209.cs2 new file mode 100644 index 0000000..05b1374 --- /dev/null +++ b/dumps/scripts/209.cs2 @@ -0,0 +1,22 @@ +void script_209() { + if (bitconfig_6101 < 8) { + setWidgetSprite(1785, new WidgetPointer(591,10)); + } else if (bitconfig_6101 < 15) { + setWidgetSprite(1786, new WidgetPointer(591,10)); + } else if (bitconfig_6101 < 23) { + setWidgetSprite(1787, new WidgetPointer(591,10)); + } else if (bitconfig_6101 < 30) { + setWidgetSprite(1788, new WidgetPointer(591,10)); + } else if (bitconfig_6101 < 38) { + setWidgetSprite(1789, new WidgetPointer(591,10)); + } else if (bitconfig_6101 < 45) { + setWidgetSprite(1790, new WidgetPointer(591,10)); + } else if (bitconfig_6101 < 53) { + setWidgetSprite(1791, new WidgetPointer(591,10)); + } else if (bitconfig_6101 < 60) { + setWidgetSprite(1792, new WidgetPointer(591,10)); + } else { + setWidgetSprite(1793, new WidgetPointer(591,10)); + } + return; +} diff --git a/dumps/scripts/2090.cs2 b/dumps/scripts/2090.cs2 new file mode 100644 index 0000000..201a98e --- /dev/null +++ b/dumps/scripts/2090.cs2 @@ -0,0 +1,18 @@ +void script_2090() { + int ivar0; + int ivar1; + ivar0 = 0; + ivar1 = 0; + ivar0 = cs2method_3408(105, 105, 723, globalint_649); + ivar1 = cs2method_3408(105, 105, 2196, globalint_649); + if (globalint_649 < 15) { + setWidgetRGB(new Color(51, 102, 255), new WidgetPointer(836,61)); + } else if (globalint_649 > 15) { + setWidgetRGB(new Color(225, 35, 35), new WidgetPointer(836,61)); + } else { + setWidgetRGB(new Color(102, 102, 102), new WidgetPointer(836,61)); + } + setWidgetPosition(ivar0, 66, 2, 0, new WidgetPointer(836,61)); + setWidgetSize(ivar1, 8, 0, 0, new WidgetPointer(836,61)); + return; +} diff --git a/dumps/scripts/2091.cs2 b/dumps/scripts/2091.cs2 new file mode 100644 index 0000000..2fe12d7 --- /dev/null +++ b/dumps/scripts/2091.cs2 @@ -0,0 +1,59 @@ +void script_2091(int arg0,int arg1) { + string svar0; + svar0 = ""; + if (((boolean)bitconfig_5835)) { + return; + } + switch (arg0) { + case 54788124: + case 54788105: + case 54788109: + svar0 = "The number of times that the avatar has been killed."; + break; + case 54788121: + case 54788106: + case 54788110: + svar0 = "The Slayer level required to attack each avatar."; + break; + case 54788120: + case 54788107: + case 54788111: + svar0 = "The remaining health of each avatar."; + break; + case 54788122: + case 54788123: + svar0 = "How much time the game has remaining."; + break; + case 54788104: + svar0 = "This column displays the blue team's statistics."; + break; + case 54788108: + svar0 = "This column displays the red team's statistics."; + break; + case 54788125: + svar0 = "Shows which team controls the soul obelisk."; + break; + case 54788126: + svar0 = "Shows which team controls the western graveyard."; + break; + case 54788127: + svar0 = "Shows which team controls the eastern graveyard."; + break; + case 54788102: + svar0 = "Shows how much control a team has over the soul obelisk."; + break; + case 54788165: + svar0 = "Shows how much control a team has over the eastern graveyard."; + break; + case 54788158: + svar0 = "Shows how much control a team has over the western graveyard."; + break; + case 54788152: + svar0 = "Shows how active you have been during the game."; + break; + default: + return; + } + script_39(arg0, arg1, 25, getWidgetActualWidth(new WidgetPointer(getWidgetParentId(new WidgetPointer(arg1)))), svar0); + return; +} diff --git a/dumps/scripts/2092.cs2 b/dumps/scripts/2092.cs2 new file mode 100644 index 0000000..01b26ab --- /dev/null +++ b/dumps/scripts/2092.cs2 @@ -0,0 +1,5 @@ +void script_2092(int arg0) { + script_41(arg0); + globalint_655 = 0; + return; +} diff --git a/dumps/scripts/2093.cs2 b/dumps/scripts/2093.cs2 new file mode 100644 index 0000000..fbaf20f --- /dev/null +++ b/dumps/scripts/2093.cs2 @@ -0,0 +1,13 @@ +void script_2093() { + if (globalint_654 < 100) { + globalint_654 = add(globalint_654, 1); + } + if (globalint_654 == 50) { + setWidgetIsHidden(true, new WidgetPointer(834,60)); + } + if (globalint_654 == 100) { + setWidgetIsHidden(false, new WidgetPointer(834,60)); + globalint_654 = 0; + } + return; +} diff --git a/dumps/scripts/2094.cs2 b/dumps/scripts/2094.cs2 new file mode 100644 index 0000000..d9598e2 --- /dev/null +++ b/dumps/scripts/2094.cs2 @@ -0,0 +1,13 @@ +void script_2094() { + if (globalint_654 < 100) { + globalint_654 = add(globalint_654, 1); + } + if (globalint_654 == 50) { + setWidgetIsHidden(true, new WidgetPointer(834,56)); + } + if (globalint_654 == 100) { + setWidgetIsHidden(false, new WidgetPointer(834,56)); + globalint_654 = 0; + } + return; +} diff --git a/dumps/scripts/2095.cs2 b/dumps/scripts/2095.cs2 new file mode 100644 index 0000000..a1bb046 --- /dev/null +++ b/dumps/scripts/2095.cs2 @@ -0,0 +1,17 @@ +void script_2095() { + if (globalint_654 < 100) { + globalint_654 = add(globalint_654, 1); + } + if (globalint_654 == 50) { + setWidgetIsHidden(true, new WidgetPointer(834,48)); + setWidgetIsHidden(true, new WidgetPointer(834,52)); + setWidgetIsHidden(true, new WidgetPointer(834,56)); + } + if (globalint_654 == 100) { + setWidgetIsHidden(false, new WidgetPointer(834,48)); + setWidgetIsHidden(false, new WidgetPointer(834,52)); + setWidgetIsHidden(false, new WidgetPointer(834,56)); + globalint_654 = 0; + } + return; +} diff --git a/dumps/scripts/2096.cs2 b/dumps/scripts/2096.cs2 new file mode 100644 index 0000000..5f26110 --- /dev/null +++ b/dumps/scripts/2096.cs2 @@ -0,0 +1,13 @@ +void script_2096() { + if (globalint_654 < 100) { + globalint_654 = add(globalint_654, 1); + } + if (globalint_654 == 50) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(834,13)); + } + if (globalint_654 == 100) { + setWidgetRGB(new Color(255, 35, 35), new WidgetPointer(834,13)); + globalint_654 = 0; + } + return; +} diff --git a/dumps/scripts/2097.cs2 b/dumps/scripts/2097.cs2 new file mode 100644 index 0000000..7d14a54 --- /dev/null +++ b/dumps/scripts/2097.cs2 @@ -0,0 +1,8 @@ +void script_2097() { + if (globalint_645 <= 5) { + setWidgetRGB(new Color(51, 102, 255), new WidgetPointer(834,28)); + } else { + setWidgetRGB(new Color(102, 102, 102), new WidgetPointer(834,28)); + } + return; +} diff --git a/dumps/scripts/2098.cs2 b/dumps/scripts/2098.cs2 new file mode 100644 index 0000000..51893ee --- /dev/null +++ b/dumps/scripts/2098.cs2 @@ -0,0 +1,4 @@ +void script_2098() { + setWidgetText(new WidgetPointer(834,13), intToStr(globalint_642)); + return; +} diff --git a/dumps/scripts/2099.cs2 b/dumps/scripts/2099.cs2 new file mode 100644 index 0000000..75a6344 --- /dev/null +++ b/dumps/scripts/2099.cs2 @@ -0,0 +1,18 @@ +void script_2099() { + int ivar0; + int ivar1; + ivar0 = 0; + ivar1 = 0; + ivar0 = cs2method_3408(105, 105, 723, globalint_645); + ivar1 = cs2method_3408(105, 105, 2196, globalint_645); + if (globalint_645 < 15) { + setWidgetRGB(new Color(51, 102, 255), new WidgetPointer(834,5)); + } else if (globalint_645 > 15) { + setWidgetRGB(new Color(225, 35, 35), new WidgetPointer(834,5)); + } else { + setWidgetRGB(new Color(102, 102, 102), new WidgetPointer(834,5)); + } + setWidgetPosition(ivar0, 66, 2, 0, new WidgetPointer(834,5)); + setWidgetSize(ivar1, 8, 0, 0, new WidgetPointer(834,5)); + return; +} diff --git a/dumps/scripts/21.cs2 b/dumps/scripts/21.cs2 new file mode 100644 index 0000000..eb0f664 --- /dev/null +++ b/dumps/scripts/21.cs2 @@ -0,0 +1,35 @@ +void script_21(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12) { + if (((getSkillCurrentLvl(6) < arg3) && (((boolean)arg4) || (getSkillActualLvl(6) < arg3))) && (((boolean)bitconfig_9071) || ((((arg0 != 28180504) && (arg0 != 28180507)) && ((arg0 != 28180513) && (arg0 != 28180525))) && (arg0 != 28180522)))) { + if (((boolean)bitconfig_4089)) { + if ((standart_config_1092 < arg3) || ((boolean)cs2method_3408(73, 105, 1061, arg0))) { + setWidgetSprite(arg2, new WidgetPointer(arg0)); + return; + } + } else { + setWidgetSprite(arg2, new WidgetPointer(arg0)); + return; + } + } + if ((arg5 != -1) && (script_19(arg5, arg0) < arg6)) { + setWidgetSprite(arg2, new WidgetPointer(arg0)); + return; + } + if ((arg7 != -1) && (script_19(arg7, arg0) < arg8)) { + setWidgetSprite(arg2, new WidgetPointer(arg0)); + return; + } + if ((arg9 != -1) && (script_19(arg9, arg0) < arg10)) { + setWidgetSprite(arg2, new WidgetPointer(arg0)); + return; + } + if ((arg11 != -1) && (script_19(arg11, arg0) < arg12)) { + setWidgetSprite(arg2, new WidgetPointer(arg0)); + return; + } + if ((arg0 == 12582939) && isMember()) { + setWidgetSprite(arg2, new WidgetPointer(arg0)); + return; + } + setWidgetSprite(arg1, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/210.cs2 b/dumps/scripts/210.cs2 new file mode 100644 index 0000000..1fc6170 --- /dev/null +++ b/dumps/scripts/210.cs2 @@ -0,0 +1,22 @@ +void script_210() { + if (bitconfig_6101 < 8) { + setWidgetSprite(1785, new WidgetPointer(381,16)); + } else if (bitconfig_6101 < 15) { + setWidgetSprite(1786, new WidgetPointer(381,16)); + } else if (bitconfig_6101 < 23) { + setWidgetSprite(1787, new WidgetPointer(381,16)); + } else if (bitconfig_6101 < 30) { + setWidgetSprite(1788, new WidgetPointer(381,16)); + } else if (bitconfig_6101 < 38) { + setWidgetSprite(1789, new WidgetPointer(381,16)); + } else if (bitconfig_6101 < 45) { + setWidgetSprite(1790, new WidgetPointer(381,16)); + } else if (bitconfig_6101 < 53) { + setWidgetSprite(1791, new WidgetPointer(381,16)); + } else if (bitconfig_6101 < 60) { + setWidgetSprite(1792, new WidgetPointer(381,16)); + } else { + setWidgetSprite(1793, new WidgetPointer(381,16)); + } + return; +} diff --git a/dumps/scripts/2100.cs2 b/dumps/scripts/2100.cs2 new file mode 100644 index 0000000..5a67dc9 --- /dev/null +++ b/dumps/scripts/2100.cs2 @@ -0,0 +1,50 @@ +void script_2100(int arg0,int arg1) { + string svar0; + svar0 = ""; + switch (arg0) { + case 54657051: + case 54657036: + case 54657032: + svar0 = "The number of times that the avatar has been killed."; + break; + case 54657048: + case 54657037: + case 54657033: + svar0 = "The Slayer level required to attack each avatar."; + break; + case 54657047: + case 54657038: + case 54657034: + svar0 = "The remaining health of each avatar."; + break; + case 54657049: + case 54657050: + svar0 = "How much time the game has remaining."; + break; + case 54657031: + svar0 = "This column displays the blue team's statistics."; + break; + case 54657035: + svar0 = "This column displays the red team's statistics."; + break; + case 54657052: + svar0 = "Shows which team controls the soul obelisk."; + break; + case 54657053: + svar0 = "Shows which team controls the western graveyard."; + break; + case 54657054: + svar0 = "Shows which team controls the eastern graveyard."; + break; + case 54657092: + svar0 = "Shows how much control a team has over the soul obelisk."; + break; + case 54657098: + svar0 = "Shows how active you have been during the game."; + break; + default: + return; + } + script_39(arg0, arg1, 25, getWidgetActualWidth(new WidgetPointer(getWidgetParentId(new WidgetPointer(arg1)))), svar0); + return; +} diff --git a/dumps/scripts/2101.cs2 b/dumps/scripts/2101.cs2 new file mode 100644 index 0000000..5f3add1 --- /dev/null +++ b/dumps/scripts/2101.cs2 @@ -0,0 +1,4 @@ +void script_2101(int arg0) { + setItemOnWidgetMethod2200(standart_config_856, 1, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/2102.cs2 b/dumps/scripts/2102.cs2 new file mode 100644 index 0000000..365dd4a --- /dev/null +++ b/dumps/scripts/2102.cs2 @@ -0,0 +1,9 @@ +void script_2102() { + int ivar0; + script_31(19464198, 19464196, 798, 795, 796, 797, 793, 794); + ivar0 = add(multiply(getLineCount(getWidgetActualWidth(new WidgetPointer(297,7)), 495, getWidgetText(new WidgetPointer(297,7))), 12), 5); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(297,7)), ivar0, 0, 0, new WidgetPointer(297,7)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(297,49)), add(add(getWidgetActualY(new WidgetPointer(297,7)), ivar0), 5), 0, 0, new WidgetPointer(297,49)); + script_2104(0); + return; +} diff --git a/dumps/scripts/2103.cs2 b/dumps/scripts/2103.cs2 new file mode 100644 index 0000000..809eed8 --- /dev/null +++ b/dumps/scripts/2103.cs2 @@ -0,0 +1,4 @@ +void script_2103(int arg0) { + script_2104(arg0); + return; +} diff --git a/dumps/scripts/2104.cs2 b/dumps/scripts/2104.cs2 new file mode 100644 index 0000000..b0d1269 --- /dev/null +++ b/dumps/scripts/2104.cs2 @@ -0,0 +1,10 @@ +void script_2104(int arg0) { + if (((boolean)arg0)) { + setWidgetIsHidden(false, new WidgetPointer(297,23)); + setWidgetIsHidden(true, new WidgetPointer(297,9)); + } else { + setWidgetIsHidden(true, new WidgetPointer(297,23)); + setWidgetIsHidden(false, new WidgetPointer(297,9)); + } + return; +} diff --git a/dumps/scripts/2105.cs2 b/dumps/scripts/2105.cs2 new file mode 100644 index 0000000..13bad0e --- /dev/null +++ b/dumps/scripts/2105.cs2 @@ -0,0 +1,4 @@ +void script_2105(int arg0,int arg1) { + setScriptCallOnGameloop(2106, new WidgetPointer(arg0), new WidgetPointer(arg1), getWidgetActualX(new WidgetPointer(arg1)), getWidgetActualY(new WidgetPointer(arg1)), 0, 0, "IIiiii", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/2106.cs2 b/dumps/scripts/2106.cs2 new file mode 100644 index 0000000..3de196c --- /dev/null +++ b/dumps/scripts/2106.cs2 @@ -0,0 +1,7 @@ +void script_2106(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + arg4 = max(min(subtract(add(arg4, rnd(1)), rnd(1)), 5), -5); + arg5 = max(min(subtract(add(arg5, rnd(1)), rnd(1)), 5), -5); + setWidgetPosition(add(arg2, arg4), add(arg3, arg5), 0, 0, new WidgetPointer(arg1)); + setScriptCallOnGameloop(2106, new WidgetPointer(arg0), new WidgetPointer(arg1), arg2, arg3, arg4, arg5, "IIiiii", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/2107.cs2 b/dumps/scripts/2107.cs2 new file mode 100644 index 0000000..fc8be35 --- /dev/null +++ b/dumps/scripts/2107.cs2 @@ -0,0 +1,7 @@ +void script_2107(int arg0,int arg1,int arg2,int arg3) { + setWidgetModel(7753, new WidgetPointer(arg0)); + setWidgetModel(7752, new WidgetPointer(arg1)); + setWidgetModel(20104, new WidgetPointer(arg2)); + setWidgetModel(7751, new WidgetPointer(arg3)); + return; +} diff --git a/dumps/scripts/2108.cs2 b/dumps/scripts/2108.cs2 new file mode 100644 index 0000000..e56e5a7 --- /dev/null +++ b/dumps/scripts/2108.cs2 @@ -0,0 +1,4 @@ +void script_2108(int arg0,int arg1,int arg2,int arg3) { + script_2112(arg0, arg1, arg2, arg3, bitconfig_693, bitconfig_5851); + return; +} diff --git a/dumps/scripts/2109.cs2 b/dumps/scripts/2109.cs2 new file mode 100644 index 0000000..e8a1385 --- /dev/null +++ b/dumps/scripts/2109.cs2 @@ -0,0 +1,4 @@ +void script_2109(int arg0,int arg1,int arg2,int arg3) { + script_2112(arg0, arg1, arg2, arg3, bitconfig_694, bitconfig_5852); + return; +} diff --git a/dumps/scripts/211.cs2 b/dumps/scripts/211.cs2 new file mode 100644 index 0000000..705d6a3 --- /dev/null +++ b/dumps/scripts/211.cs2 @@ -0,0 +1,7 @@ +void script_211() { + if (standart_config_448 == -1) { + script_656(); + } + script_606(); + return; +} diff --git a/dumps/scripts/2110.cs2 b/dumps/scripts/2110.cs2 new file mode 100644 index 0000000..0135ee0 --- /dev/null +++ b/dumps/scripts/2110.cs2 @@ -0,0 +1,4 @@ +void script_2110(int arg0,int arg1,int arg2,int arg3) { + script_2112(arg0, arg1, arg2, arg3, bitconfig_695, bitconfig_5853); + return; +} diff --git a/dumps/scripts/2111.cs2 b/dumps/scripts/2111.cs2 new file mode 100644 index 0000000..36f7a76 --- /dev/null +++ b/dumps/scripts/2111.cs2 @@ -0,0 +1,22 @@ +void script_2111(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6) { + int ivar7; + int ivar8; + if (arg0 != 1) { + return; + } + ivar7 = 0; + ivar8 = 0; + playSoundEffect(4911, 1, 0); + if (((boolean)arg1)) { + ivar7 = script_686(mod(add(bitconfig_693, arg2), 4), 4); + ivar8 = bitconfig_5851; + } else if (arg1 == 2) { + ivar7 = script_686(mod(add(bitconfig_694, arg2), 4), 4); + ivar8 = bitconfig_5852; + } else { + ivar7 = script_686(mod(add(bitconfig_695, arg2), 4), 4); + ivar8 = bitconfig_5853; + } + script_2112(arg3, arg4, arg5, arg6, ivar7, ivar8); + return; +} diff --git a/dumps/scripts/2112.cs2 b/dumps/scripts/2112.cs2 new file mode 100644 index 0000000..3aa294c --- /dev/null +++ b/dumps/scripts/2112.cs2 @@ -0,0 +1,32 @@ +void script_2112(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + setWidget3DRotation(0, 0, getWidgetRotateX(new WidgetPointer(arg0)), getWidgetRotateY(new WidgetPointer(arg0)), cs2method2607(new WidgetPointer(arg0)), add(add(395, arg5), arg5), new WidgetPointer(arg0)); + setWidget3DRotation(0, 0, getWidgetRotateX(new WidgetPointer(arg1)), getWidgetRotateY(new WidgetPointer(arg1)), cs2method2607(new WidgetPointer(arg1)), add(add(395, arg5), arg5), new WidgetPointer(arg1)); + setWidget3DRotation(0, 0, getWidgetRotateX(new WidgetPointer(arg2)), getWidgetRotateY(new WidgetPointer(arg2)), cs2method2607(new WidgetPointer(arg2)), add(add(395, arg5), arg5), new WidgetPointer(arg2)); + setWidget3DRotation(0, 0, getWidgetRotateX(new WidgetPointer(arg3)), getWidgetRotateY(new WidgetPointer(arg3)), cs2method2607(new WidgetPointer(arg3)), add(add(395, arg5), arg5), new WidgetPointer(arg3)); + switch (arg4) { + case 0: + setWidgetPosition(0, 43, 1, 0, new WidgetPointer(arg0)); + setWidgetPosition(0, 126, 1, 0, new WidgetPointer(arg1)); + setWidgetPosition(0, 210, 1, 0, new WidgetPointer(arg2)); + setWidgetPosition(0, -70, 1, 0, new WidgetPointer(arg3)); + break; + case 1: + setWidgetPosition(0, 43, 1, 0, new WidgetPointer(arg1)); + setWidgetPosition(0, 126, 1, 0, new WidgetPointer(arg2)); + setWidgetPosition(0, 210, 1, 0, new WidgetPointer(arg3)); + setWidgetPosition(0, -70, 1, 0, new WidgetPointer(arg0)); + break; + case 2: + setWidgetPosition(0, 43, 1, 0, new WidgetPointer(arg2)); + setWidgetPosition(0, 126, 1, 0, new WidgetPointer(arg3)); + setWidgetPosition(0, 210, 1, 0, new WidgetPointer(arg0)); + setWidgetPosition(0, -70, 1, 0, new WidgetPointer(arg1)); + break; + default: + setWidgetPosition(0, 43, 1, 0, new WidgetPointer(arg3)); + setWidgetPosition(0, 126, 1, 0, new WidgetPointer(arg0)); + setWidgetPosition(0, 210, 1, 0, new WidgetPointer(arg1)); + setWidgetPosition(0, -70, 1, 0, new WidgetPointer(arg2)); + } + return; +} diff --git a/dumps/scripts/2113.cs2 b/dumps/scripts/2113.cs2 new file mode 100644 index 0000000..0bd7eb7 --- /dev/null +++ b/dumps/scripts/2113.cs2 @@ -0,0 +1,14 @@ +void script_2113(int arg0) { + setWidget3DRotation(0, 0, rndExcl(2048), rndExcl(2048), rndExcl(2048), getWidget3DDistance(new WidgetPointer(arg0)), new WidgetPointer(arg0)); + switch (rndExcl(3)) { + case 0: + setScriptCallOnGameloop(66, add(rndExcl(3), 9), 0, add(rndExcl(3), 9), new WidgetPointer(arg0), "iiiI", new WidgetPointer(arg0)); + break; + case 1: + setScriptCallOnGameloop(66, add(rndExcl(3), 9), add(rndExcl(3), 9), 0, new WidgetPointer(arg0), "iiiI", new WidgetPointer(arg0)); + break; + default: + setScriptCallOnGameloop(66, 0, add(rndExcl(3), 9), add(rndExcl(3), 9), new WidgetPointer(arg0), "iiiI", new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/2114.cs2 b/dumps/scripts/2114.cs2 new file mode 100644 index 0000000..91111c6 --- /dev/null +++ b/dumps/scripts/2114.cs2 @@ -0,0 +1,7 @@ +void script_2114(int arg0,int arg1) { + setWidgetIsHidden(false, new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(arg1)); + globalint_679 = 0; + setScriptCallOnGlobalConfigChange(2115, new WidgetPointer(arg0), new WidgetPointer(arg1), 679, 1, "IIY", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/2115.cs2 b/dumps/scripts/2115.cs2 new file mode 100644 index 0000000..7a6cdcd --- /dev/null +++ b/dumps/scripts/2115.cs2 @@ -0,0 +1,23 @@ +void script_2115(int arg0,int arg1) { + int ivar2; + if (((boolean)script_42(globalint_679))) { + return; + } + setWidgetIsHidden(false, new WidgetPointer(arg1)); + if ((globalint_677 == -1) || (globalint_678 == -1)) { + return; + } + if ((globalint_675 == -1) || (globalint_676 == -1)) { + globalint_675 = 56070889; + globalint_676 = 56087272; + } + ivar2 = add(rnd(50), 50); + cs2method5405(0, 2); + cs2method5406(0, 0, globalint_675, 450, globalint_675, add(450, divide(ivar2, 2)), 0); + cs2method5406(0, 1, globalint_676, add(450, ivar2), globalint_676, add(450, multiply(ivar2, 2)), 0); + cs2method5405(1, 2); + cs2method5406(1, 0, globalint_677, 250, globalint_677, 250, 0); + cs2method5406(1, 1, globalint_678, 150, globalint_678, 150, 0); + cameraMethod5502(0, 0, 200, 200, 1, 0); + return; +} diff --git a/dumps/scripts/2116.cs2 b/dumps/scripts/2116.cs2 new file mode 100644 index 0000000..cb2d9e0 --- /dev/null +++ b/dumps/scripts/2116.cs2 @@ -0,0 +1,36 @@ +void script_2116(int arg0,int arg1,int arg2,int arg3,int arg4) { + int ivar5; + int ivar6; + int ivar7; + deleteAllExtraChilds(new WidgetPointer(arg0)); + deleteAllExtraChilds(new WidgetPointer(arg3)); + setWidgetText(new WidgetPointer(arg4), ""); + ivar5 = 0; + ivar6 = 0; + ivar7 = divide(subtract(getWidgetActualWidth(new WidgetPointer(arg0)), 320), 3); + while (ivar5 < getItemContainerLength(307)) { + if (getItemAmtInSlot(307, ivar5) > 0) { + script_2117(ivar5, ivar6, ivar7, arg0, arg3, arg4); + ivar6 = add(ivar6, 1); + } else { + script_2118(ivar5, arg0); + } + ivar5 = add(ivar5, 1); + } + ivar5 = add(ivar7, multiply(divide(add(ivar6, 1), 2), add(ivar7, 64))); + cs2method2100(0, 0, new WidgetPointer(arg0)); + if (ivar5 > getWidgetActualHeight(new WidgetPointer(arg0))) { + setWidgetScrollMax(0, ivar5, new WidgetPointer(arg0)); + script_31(arg1, arg0, 792, 789, 790, 791, 773, 788); + setWidgetPosition(392, getWidgetActualY(new WidgetPointer(arg4)), 0, 0, new WidgetPointer(arg4)); + setWidgetPosition(392, getWidgetActualY(new WidgetPointer(arg3)), 0, 0, new WidgetPointer(arg3)); + setWidgetIsHidden(false, new WidgetPointer(arg2)); + } else { + setWidgetScrollMax(0, 0, new WidgetPointer(arg0)); + deleteAllExtraChilds(new WidgetPointer(arg1)); + setWidgetPosition(384, getWidgetActualY(new WidgetPointer(arg3)), 0, 0, new WidgetPointer(arg3)); + setWidgetPosition(384, getWidgetActualY(new WidgetPointer(arg4)), 0, 0, new WidgetPointer(arg4)); + setWidgetIsHidden(true, new WidgetPointer(arg2)); + } + return; +} diff --git a/dumps/scripts/2117.cs2 b/dumps/scripts/2117.cs2 new file mode 100644 index 0000000..c5c0326 --- /dev/null +++ b/dumps/scripts/2117.cs2 @@ -0,0 +1,82 @@ +void script_2117(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + int ivar6; + int ivar7; + ivar6 = add(arg2, multiply(divide(arg1, 2), add(64, arg2))); + ivar7 = add(arg2, multiply(mod(arg1, 2), add(160, arg2))); + createExtraChild(new WidgetPointer(arg3), 3, multiply(arg0, 7)); + setWidgetSize(160, 64, 0, 0); + setWidgetPosition(ivar7, ivar6, 0, 0); + setWidgetRGB(new Color(0, 0, 0)); + cs2method2103(200); + setWidgetFilled(1); + setWidgetContextMenuOption(1, "Choose"); + if (arg0 == 26) { + setWidgetContextMenuOption(10, "Explain"); + cs2method1305("" + "Emote" + ""); + } else if (arg0 == 27) { + setWidgetContextMenuOption(10, "Explain"); + cs2method1305("" + "Costume point" + ""); + } else { + setWidgetContextMenuOption(10, "Examine"); + cs2method1305("" + getItemName(getItemIdInSlot(307, arg0)) + ""); + } + setScriptCallOnClickContextMenu(2120, -2147483644, new WidgetPointer(arg3), arg0, new WidgetPointer(arg4), new WidgetPointer(arg5), "iIiII"); + createExtraChild(new WidgetPointer(arg3), 5, add(multiply(arg0, 7), 1)); + setWidgetSize(159, 32, 0, 0); + cs2method1107(1); + setWidgetSprite(1074); + setWidgetPosition(ivar7, subtract(ivar6, 17), 0, 0); + createExtraChild(new WidgetPointer(arg3), 5, add(multiply(arg0, 7), 2)); + setWidgetSize(160, 32, 0, 0); + cs2method1107(1); + setWidgetSprite(1074); + setWidgetVFlip(1); + setWidgetPosition(ivar7, add(ivar6, 49), 0, 0); + createExtraChild(new WidgetPointer(arg3), 5, add(multiply(arg0, 7), 3)); + setWidgetSize(32, 63, 0, 0); + cs2method1107(1); + setWidgetSprite(1075); + setWidgetPosition(subtract(ivar7, 14), ivar6, 0, 0); + createExtraChild(new WidgetPointer(arg3), 5, add(multiply(arg0, 7), 4)); + setWidgetSize(32, 63, 0, 0); + cs2method1107(1); + setWidgetSprite(1075); + setWidgetHFlip(1); + setWidgetPosition(add(ivar7, 142), ivar6, 0, 0); + createExtraChild(new WidgetPointer(arg3), 5, add(multiply(arg0, 7), 5)); + if (arg0 == 26) { + setWidgetSize(22, 22, 0, 0); + setWidgetPosition(add(ivar7, 15), add(ivar6, 20), 0, 0); + setWidgetBorderThickness(0); + setWidgetSprite(1830); + } else if (arg0 == 27) { + setWidgetSize(42, 42, 0, 0); + setWidgetPosition(add(ivar7, 5), add(ivar6, 12), 0, 0); + setWidgetBorderThickness(0); + setWidgetSprite(1044); + } else if ((getItemAmtInSlot(307, arg0) > 1) && itemIsStackable(getItemIdInSlot(307, arg0))) { + setItemOnWidgetMethod1200(getItemIdInSlot(307, arg0), getItemAmtInSlot(307, arg0)); + } else { + setItemOnWidgetMethod1200(getItemIdInSlot(307, arg0), -1); + } + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(add(ivar7, 8), add(ivar6, 16), 0, 0); + setWidgetBorderThickness(1); + setWidgetShadowColor(new Color(48, 32, 32)); + createExtraChild(new WidgetPointer(arg3), 4, add(multiply(arg0, 7), 6)); + setWidgetFont(496); + setWidgetRGB(new Color(255, 152, 31)); + setWidgetTextAlignment(1, 1, 0); + setWidgetSize(subtract(160, add(add(subtract(getWidgetActualX(), ivar7), getWidgetActualWidth()), 4)), 64, 0, 0); + setWidgetPosition(subtract(subtract(add(ivar7, 160), getWidgetActualWidth()), 2), ivar6, 0, 0); + if (arg0 == 26) { + setWidgetText("Unlock emote!"); + } else if (arg0 == 27) { + setWidgetText("Save up for a costume!"); + } else if (((boolean)getItemAmtInSlot(307, arg0))) { + setWidgetText(cs2method_3408(105, 115, 2238, arg0) + ":" + "
" + getItemName(getItemIdInSlot(307, arg0))); + } else { + setWidgetText(cs2method_3408(105, 115, 2238, arg0) + ":" + "
" + intToStr(getItemAmtInSlot(307, arg0)) + " x " + getItemName(getItemIdInSlot(307, arg0))); + } + return; +} diff --git a/dumps/scripts/2118.cs2 b/dumps/scripts/2118.cs2 new file mode 100644 index 0000000..372a8eb --- /dev/null +++ b/dumps/scripts/2118.cs2 @@ -0,0 +1,12 @@ +void script_2118(int arg0,int arg1) { + int ivar2; + ivar2 = 0; + while (ivar2 < 7) { + createExtraChild(new WidgetPointer(arg1), 3, add(multiply(arg0, 7), ivar2)); + setWidgetSize(0, 0, 0, 0); + setWidgetPosition(-1, -1, 0, 0); + setWidgetHidden(1); + ivar2 = add(ivar2, 1); + } + return; +} diff --git a/dumps/scripts/2119.cs2 b/dumps/scripts/2119.cs2 new file mode 100644 index 0000000..75f92ca --- /dev/null +++ b/dumps/scripts/2119.cs2 @@ -0,0 +1,8 @@ +void script_2119(int arg0,int arg1) { + if ((getWidgetScrollMaxV(new WidgetPointer(arg0)) > 0) && (cs2method2601(new WidgetPointer(arg0)) < 35)) { + setWidgetIsHidden(false, new WidgetPointer(arg1)); + } else { + setWidgetIsHidden(true, new WidgetPointer(arg1)); + } + return; +} diff --git a/dumps/scripts/212.cs2 b/dumps/scripts/212.cs2 new file mode 100644 index 0000000..043ad6d --- /dev/null +++ b/dumps/scripts/212.cs2 @@ -0,0 +1,6 @@ +void script_212(string arg0) { + if (stringMethod4107(arg0, "") != 0) { + cs2method5421(1, arg0); + } + return; +} diff --git a/dumps/scripts/2120.cs2 b/dumps/scripts/2120.cs2 new file mode 100644 index 0000000..d6eb03b --- /dev/null +++ b/dumps/scripts/2120.cs2 @@ -0,0 +1,42 @@ +void script_2120(int arg0,int arg1,int arg2,int arg3,int arg4) { + int ivar5; + int ivar6; + if (arg0 != 1) { + return; + } + ivar5 = 0; + while (ivar5 < getItemContainerLength(307)) { + if (setWidgetRegister(new WidgetPointer(arg1), multiply(ivar5, 7))) { + if (ivar5 == arg2) { + cs2method2103(100); + } else { + cs2method2103(200); + } + } + ivar5 = add(ivar5, 1); + } + setWidgetText(new WidgetPointer(arg4), "Confirm:" + "
" + cs2method_3408(105, 115, 2238, arg2)); + deleteAllExtraChilds(new WidgetPointer(arg3)); + ivar6 = 833; + ivar5 = 0; + while (ivar5 < getItemContainerLength(307)) { + if (ivar5 == arg2) { + createExtraChild(new WidgetPointer(arg3), 5, ivar5); + setWidgetSize(90, 56, 0, 0); + setWidgetPosition(0, 0, 0, 0); + setWidgetSprite(ivar6); + setWidgetHidden(0); + setScriptCallOnMouseExit(688, new WidgetPointer(-32768,3), -2147483643, ivar6, "Iid"); + ivar6 = 834; + setScriptCallOnMouseEntered(688, new WidgetPointer(-32768,3), -2147483643, ivar6, "Iid"); + setWidgetContextMenuOption(1, "Confirm"); + return; + } + createExtraChild(new WidgetPointer(arg3), 3, ivar5); + setWidgetPosition(-1, -1, 0, 0); + setWidgetSize(0, 0, 0, 0); + setWidgetHidden(1); + ivar5 = add(ivar5, 1); + } + return; +} diff --git a/dumps/scripts/2121.cs2 b/dumps/scripts/2121.cs2 new file mode 100644 index 0000000..5027b2f --- /dev/null +++ b/dumps/scripts/2121.cs2 @@ -0,0 +1,13 @@ +void script_2121(int arg0,int arg1) { + script_2122(1, arg0, "Mime outfit"); + script_2122(11, arg0, "Frog kit"); + script_2122(21, arg0, "Zombie outfit (Gravedigger reward)"); + script_2122(31, arg0, "Camo kit (Drill Demon reward)"); + script_2122(41, arg0, "Lederhosen outfit (Freaky Forester reward)"); + setWidgetScrollMax(0, 320, new WidgetPointer(arg0)); + script_31(arg1, arg0, 792, 789, 790, 791, 773, 788); + if (setWidgetRegister(new WidgetPointer(arg1), 1)) { + script_37(arg1, arg0, cs2method2601(new WidgetPointer(arg0)), 1); + } + return; +} diff --git a/dumps/scripts/2122.cs2 b/dumps/scripts/2122.cs2 new file mode 100644 index 0000000..14f02fb --- /dev/null +++ b/dumps/scripts/2122.cs2 @@ -0,0 +1,50 @@ +void script_2122(int arg0,int arg1,string arg2) { + int ivar2; + int ivar3; + ivar2 = multiply(divide(arg0, 10), 64); + createExtraChild(new WidgetPointer(arg1), 4, subtract(arg0, 1)); + setWidgetSize(subtract(getWidgetActualWidth(new WidgetPointer(arg1)), 10), 17, 0, 0); + setWidgetPosition(5, add(ivar2, 2), 0, 0); + setWidgetFont(495); + setWidgetTextAlignment(0, 0, 0); + setWidgetRGB(new Color(255, 152, 31)); + setWidgetText(arg2); + ivar3 = 0; + while (ivar3 < 7) { + script_2123(add(arg0, ivar3), ivar3, arg1, ivar2); + ivar3 = add(ivar3, 1); + } + createExtraChild(new WidgetPointer(arg1), 4, add(arg0, 7)); + setWidgetSize(100, 64, 0, 0); + setWidgetPosition(subtract(getWidgetActualWidth(new WidgetPointer(arg1)), 100), ivar2, 0, 0); + setWidgetFont(495); + setWidgetTextAlignment(1, 1, 0); + setWidgetRGB(new Color(255, 152, 31)); + switch (arg0) { + case 1: + setWidgetText("Points:" + "
" + intToStr(bitconfig_5903)); + break; + case 11: + setWidgetText("Points:" + "
" + intToStr(bitconfig_5904)); + break; + case 21: + setWidgetText("Points:" + "
" + intToStr(bitconfig_5905)); + break; + case 31: + setWidgetText("Points:" + "
" + intToStr(bitconfig_5906)); + break; + case 41: + setWidgetText("Points:" + "
" + intToStr(bitconfig_5907)); + break; + default: + setWidgetText(""); + } + if (add(arg0, 10) < 43) { + createExtraChild(new WidgetPointer(arg1), 5, add(arg0, 8)); + setWidgetSprite(962); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg1)), 32, 0, 0); + cs2method1107(1); + setWidgetPosition(0, add(ivar2, 58), 0, 0); + } + return; +} diff --git a/dumps/scripts/2123.cs2 b/dumps/scripts/2123.cs2 new file mode 100644 index 0000000..282c2fc --- /dev/null +++ b/dumps/scripts/2123.cs2 @@ -0,0 +1,57 @@ +void script_2123(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + createExtraChild(new WidgetPointer(arg2), 5, arg0); + setWidgetPosition(add(5, multiply(add(36, 20), arg1)), add(arg3, 22), 0, 0); + setWidgetSize(36, 32, 0, 0); + ivar4 = cs2method_3408(105, 79, 2240, arg0); + if (ivar4 != -1) { + setWidgetBorderThickness(1); + setWidgetShadowColor(new Color(48, 32, 32)); + setItemOnWidgetMethod1200(ivar4, -1); + setWidgetContextMenuOption(1, "Claim"); + setWidgetContextMenuOption(10, "Examine"); + cs2method1305("" + getItemName(ivar4) + ""); + if (add(add(add(getItemAmtInContainer(93, ivar4), getItemAmtInContainer(94, ivar4)), getItemAmtInContainer(95, ivar4)), getItemAmtInContainer(530, ivar4)) > 0) { + cs2method2103(200); + } else if (divide(arg0, 10) == divide(1, 10)) { + if (bitconfig_2698 > 0) { + cs2method2103(200); + } else { + cs2method2103(0); + } + } else if (arg0 == 11) { + if (bitconfig_2776 > 0) { + cs2method2103(200); + } else { + cs2method2103(0); + } + } else if (divide(arg0, 10) == divide(11, 10)) { + if (bitconfig_2699 > 0) { + cs2method2103(200); + } else { + cs2method2103(0); + } + } else if (divide(arg0, 10) == divide(21, 10)) { + if (bitconfig_2700 > 0) { + cs2method2103(200); + } else { + cs2method2103(0); + } + } else if (divide(arg0, 10) == divide(31, 10)) { + if (bitconfig_2701 > 0) { + cs2method2103(200); + } else { + cs2method2103(0); + } + } else if (divide(arg0, 10) == divide(41, 10)) { + if (bitconfig_2702 > 0) { + cs2method2103(200); + } else { + cs2method2103(0); + } + } else { + cs2method2103(0); + } + } + return; +} diff --git a/dumps/scripts/2124.cs2 b/dumps/scripts/2124.cs2 new file mode 100644 index 0000000..ea018eb --- /dev/null +++ b/dumps/scripts/2124.cs2 @@ -0,0 +1,17 @@ +void script_2124(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8) { + globalint_681 = rndExcl(2048); + globalint_684 = rndExcl(2048); + globalint_687 = rndExcl(2048); + globalint_690 = rndExcl(2048); + globalint_680 = subtract(25, rnd(50)); + globalint_682 = subtract(25, rnd(50)); + globalint_683 = subtract(25, rnd(50)); + globalint_685 = subtract(25, rnd(50)); + globalint_686 = subtract(25, rnd(50)); + globalint_688 = subtract(25, rnd(50)); + globalint_689 = subtract(25, rnd(50)); + globalint_691 = subtract(25, rnd(50)); + script_2127(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + setScriptCallOnGameloop(2126, new WidgetPointer(arg1), new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), new WidgetPointer(arg6), new WidgetPointer(arg7), new WidgetPointer(arg8), "IIIIIIII", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/2125.cs2 b/dumps/scripts/2125.cs2 new file mode 100644 index 0000000..b1647bb --- /dev/null +++ b/dumps/scripts/2125.cs2 @@ -0,0 +1,4 @@ +void script_2125(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8) { + script_2127(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + return; +} diff --git a/dumps/scripts/2126.cs2 b/dumps/scripts/2126.cs2 new file mode 100644 index 0000000..54e02bb --- /dev/null +++ b/dumps/scripts/2126.cs2 @@ -0,0 +1,28 @@ +void script_2126(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7) { + globalint_681 = mod(add(add(globalint_681, rndExcl(4)), 2), 2048); + globalint_684 = mod(add(add(globalint_684, rndExcl(4)), 2), 2048); + globalint_687 = mod(add(add(globalint_687, rndExcl(4)), 2), 2048); + globalint_690 = mod(add(add(globalint_690, rndExcl(4)), 2), 2048); + if ((globalint_680 < 20) && ((globalint_680 < -20) || ((boolean)rndExcl(2)))) { + globalint_680 = min(add(add(globalint_680, rndExcl(3)), 1), 25); + } else { + globalint_680 = max(subtract(globalint_680, add(rndExcl(3), 1)), -25); + } + if ((globalint_683 < 20) && ((globalint_683 < -20) || ((boolean)rndExcl(2)))) { + globalint_683 = min(add(add(globalint_683, rndExcl(3)), 1), 25); + } else { + globalint_683 = max(subtract(globalint_683, add(rndExcl(3), 1)), -25); + } + if ((globalint_686 < 20) && ((globalint_686 < -20) || ((boolean)rndExcl(2)))) { + globalint_686 = min(add(add(globalint_686, rndExcl(3)), 1), 25); + } else { + globalint_686 = max(subtract(globalint_686, add(rndExcl(3), 1)), -25); + } + if ((globalint_689 < 20) && ((globalint_689 < -20) || ((boolean)rndExcl(2)))) { + globalint_689 = min(add(add(globalint_689, rndExcl(3)), 1), 25); + } else { + globalint_689 = max(subtract(globalint_689, add(rndExcl(3), 1)), -25); + } + script_2127(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + return; +} diff --git a/dumps/scripts/2127.cs2 b/dumps/scripts/2127.cs2 new file mode 100644 index 0000000..dfa3e53 --- /dev/null +++ b/dumps/scripts/2127.cs2 @@ -0,0 +1,11 @@ +void script_2127(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7) { + script_2128(arg0, bitconfig_5893); + script_2128(arg1, bitconfig_5894); + script_2128(arg2, bitconfig_5895); + script_2128(arg3, bitconfig_5896); + script_2128(arg4, bitconfig_5897); + script_2128(arg5, bitconfig_5898); + script_2128(arg6, bitconfig_5899); + script_2128(arg7, bitconfig_5900); + return; +} diff --git a/dumps/scripts/2128.cs2 b/dumps/scripts/2128.cs2 new file mode 100644 index 0000000..7d02a67 --- /dev/null +++ b/dumps/scripts/2128.cs2 @@ -0,0 +1,23 @@ +void script_2128(int arg0,int arg1) { + switch (arg1) { + case 1: + setWidgetModel(16036, new WidgetPointer(arg0)); + setWidget3DRotation(0, 0, script_686(globalint_680, 2048), globalint_681, script_686(globalint_682, 2048), 800, new WidgetPointer(arg0)); + break; + case 2: + setWidgetModel(16025, new WidgetPointer(arg0)); + setWidget3DRotation(0, 17, script_686(globalint_683, 2048), globalint_684, script_686(globalint_685, 2048), 800, new WidgetPointer(arg0)); + break; + case 3: + setWidgetModel(16022, new WidgetPointer(arg0)); + setWidget3DRotation(0, 0, script_686(globalint_686, 2048), globalint_687, script_686(globalint_688, 2048), 800, new WidgetPointer(arg0)); + break; + case 4: + setWidgetModel(16034, new WidgetPointer(arg0)); + setWidget3DRotation(0, 0, script_686(globalint_689, 2048), globalint_690, script_686(globalint_691, 2048), 800, new WidgetPointer(arg0)); + break; + default: + setWidgetModel(-1, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/2129.cs2 b/dumps/scripts/2129.cs2 new file mode 100644 index 0000000..747fc88 --- /dev/null +++ b/dumps/scripts/2129.cs2 @@ -0,0 +1,18 @@ +void script_2129(int arg0,int arg1,int arg2) { + switch (arg1) { + case 27525135: + case 27525134: + case 27525133: + case 27525132: + case 27525138: + case 27525139: + case 27525136: + case 27525137: + setWidgetPosition(getWidgetActualX(new WidgetPointer(arg1)), getWidgetActualY(new WidgetPointer(arg1)), 0, 0, new WidgetPointer(arg0)); + playSoundEffect(5507, 1, 0); + break; + default: + setWidgetPosition(getWidgetActualX(new WidgetPointer(arg2)), getWidgetActualY(new WidgetPointer(arg2)), 0, 0, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/213.cs2 b/dumps/scripts/213.cs2 new file mode 100644 index 0000000..3728d3a --- /dev/null +++ b/dumps/scripts/213.cs2 @@ -0,0 +1,63 @@ +void script_213(int arg0,int arg1,int arg2,int arg3) { + flow_0: + SWITCH (bitconfig_278) { + case 1: + GOTO flow_1 + case 2: + GOTO flow_2 + case 3: + GOTO flow_3 + } + cs2method2103(255, new WidgetPointer(arg2)); + GOTO flow_4 + flow_1: + cs2method2103(200, new WidgetPointer(arg2)); + GOTO flow_4 + flow_2: + cs2method2103(150, new WidgetPointer(arg2)); + GOTO flow_4 + flow_3: + cs2method2103(50, new WidgetPointer(arg2)); + flow_4: + SWITCH (globalint_97) { + case 1: + GOTO flow_5 + case 2: + GOTO flow_6 + case 3: + GOTO flow_7 + case 4: + GOTO flow_8 + case 5: + GOTO flow_9 + } + setWidgetIsHidden(true, new WidgetPointer(arg0)); + setWidgetIsHidden(false, new WidgetPointer(arg2)); + GOTO flow_10 + flow_5: + script_2766(0, 20, arg3); + GOTO flow_10 + flow_6: + setWidgetIsHidden(false, new WidgetPointer(arg0)); + setWidgetAnimation(10708, new WidgetPointer(arg1)); + setWidgetIsHidden(true, new WidgetPointer(arg2)); + script_2768(10, arg3); + GOTO flow_10 + flow_7: + setWidgetIsHidden(true, new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(arg2)); + script_2768(50, arg3); + GOTO flow_10 + flow_8: + setWidgetIsHidden(false, new WidgetPointer(arg0)); + setWidgetAnimation(10712, new WidgetPointer(arg1)); + setWidgetIsHidden(true, new WidgetPointer(arg2)); + script_2768(115, arg3); + GOTO flow_10 + flow_9: + setWidgetIsHidden(true, new WidgetPointer(arg0)); + setWidgetIsHidden(false, new WidgetPointer(arg2)); + script_2768(50, arg3); + flow_10: + return; +} diff --git a/dumps/scripts/2130.cs2 b/dumps/scripts/2130.cs2 new file mode 100644 index 0000000..07a7f88 --- /dev/null +++ b/dumps/scripts/2130.cs2 @@ -0,0 +1,4 @@ +void script_2130(int arg0,int arg1) { + setWidgetPosition(getWidgetActualX(new WidgetPointer(arg1)), getWidgetActualY(new WidgetPointer(arg1)), 0, 0, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/2131.cs2 b/dumps/scripts/2131.cs2 new file mode 100644 index 0000000..028a426 --- /dev/null +++ b/dumps/scripts/2131.cs2 @@ -0,0 +1,7 @@ +void script_2131(int arg0,int arg1) { + setScriptCallOnGameloop(2132, new WidgetPointer(arg0), subtract(rndExcl(6), 3), subtract(rndExcl(6), 3), new WidgetPointer(arg1), 0, "IiiIi", new WidgetPointer(arg0)); + setScriptCallOnMouseEntered(2133, new WidgetPointer(arg0), "I", new WidgetPointer(arg0)); + setScriptCallOnMouseOver(2135, new WidgetPointer(arg0), -2147483647, -2147483646, "Iii", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(2134, new WidgetPointer(arg0), "I", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/2132.cs2 b/dumps/scripts/2132.cs2 new file mode 100644 index 0000000..f30611b --- /dev/null +++ b/dumps/scripts/2132.cs2 @@ -0,0 +1,69 @@ +void script_2132(int arg0,int arg1,int arg2,int arg3,int arg4) { + int ivar5; + int ivar6; + int ivar7; + int ivar8; + flow_0: + ivar5 = add(getWidgetActualX(new WidgetPointer(arg0)), arg1); + ivar6 = add(getWidgetActualY(new WidgetPointer(arg0)), arg2); + if ((getWidgetActualX(new WidgetPointer(arg3)) >= ivar5) && (getWidgetActualX(new WidgetPointer(arg3)) < add(ivar5, getWidgetActualWidth(new WidgetPointer(arg0))))) { + if ((getWidgetActualY(new WidgetPointer(arg3)) >= ivar6) && (getWidgetActualY(new WidgetPointer(arg3)) < add(ivar6, getWidgetActualHeight(new WidgetPointer(arg0))))) { + ivar5 = subtract(ivar5, add(rndExcl(3), 2)); + ivar6 = subtract(ivar6, add(rndExcl(3), 2)); + if (arg4 <= getClientCycle()) { + playSoundEffect(819, 1, 0); + arg4 = add(add(getClientCycle(), 20), rndExcl(40)); + } + } + } else { + if (((ivar5 >= getWidgetActualX(new WidgetPointer(arg3))) && (ivar5 < add(getWidgetActualX(new WidgetPointer(arg3)), getWidgetActualWidth(new WidgetPointer(arg3))))) && ((ivar6 >= getWidgetActualY(new WidgetPointer(arg3))) && (ivar6 < add(getWidgetActualY(new WidgetPointer(arg3)), getWidgetActualHeight(new WidgetPointer(arg3)))))) { + ivar5 = add(add(ivar5, rndExcl(3)), 2); + ivar6 = add(add(ivar6, rndExcl(3)), 2); + if (arg4 <= getClientCycle()) { + playSoundEffect(819, 1, 0); + arg4 = add(add(getClientCycle(), 20), rndExcl(40)); + } + } + } + ivar5 = max(ivar5, 0); + ivar6 = max(ivar6, 0); + ivar7 = subtract(getWidgetActualWidth(new WidgetPointer(getWidgetParentId(new WidgetPointer(arg0)))), getWidgetActualWidth(new WidgetPointer(arg0))); + ivar5 = min(ivar5, ivar7); + ivar8 = subtract(getWidgetActualHeight(new WidgetPointer(getWidgetParentId(new WidgetPointer(arg0)))), getWidgetActualHeight(new WidgetPointer(arg0))); + ivar6 = min(ivar6, ivar8); + IF (ivar5 <= 0) + GOTO flow_14 + GOTO flow_15 + flow_14: + IF (arg1 < 0) + GOTO flow_17 + flow_15: + IF ((ivar5 >= ivar7) && (arg1 > 0)) + GOTO flow_17 + GOTO flow_18 + flow_17: + arg1 = subtract(0, arg1); + flow_18: + IF (ivar6 <= 0) + GOTO flow_19 + GOTO flow_20 + flow_19: + IF (arg2 < 0) + GOTO flow_22 + flow_20: + IF ((ivar6 >= ivar8) && (arg2 > 0)) + GOTO flow_22 + GOTO flow_23 + flow_22: + arg2 = subtract(0, arg2); + flow_23: + if (((boolean)arg1)) { + arg1 = add(rndExcl(3), 1); + } + if (((boolean)arg2)) { + arg2 = add(rndExcl(3), 1); + } + setWidgetPosition(ivar5, ivar6, 0, 0, new WidgetPointer(arg0)); + setScriptCallOnGameloop(2132, new WidgetPointer(arg0), arg1, arg2, new WidgetPointer(arg3), arg4, "IiiIi", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/2133.cs2 b/dumps/scripts/2133.cs2 new file mode 100644 index 0000000..3f071bd --- /dev/null +++ b/dumps/scripts/2133.cs2 @@ -0,0 +1,5 @@ +void script_2133(int arg0) { + setWidgetAnimation(1, new WidgetPointer(arg0)); + playSoundEffect(819, 1, 0); + return; +} diff --git a/dumps/scripts/2134.cs2 b/dumps/scripts/2134.cs2 new file mode 100644 index 0000000..bc6f112 --- /dev/null +++ b/dumps/scripts/2134.cs2 @@ -0,0 +1,4 @@ +void script_2134(int arg0) { + setWidgetAnimation(0, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/2135.cs2 b/dumps/scripts/2135.cs2 new file mode 100644 index 0000000..d29316f --- /dev/null +++ b/dumps/scripts/2135.cs2 @@ -0,0 +1,26 @@ +void script_2135(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + ivar3 = getWidgetActualX(new WidgetPointer(arg0)); + ivar4 = getWidgetActualY(new WidgetPointer(arg0)); + if ((arg1 >= 0) && (arg1 <= divide(getWidgetActualWidth(new WidgetPointer(arg0)), 2))) { + ivar3 = subtract(ivar3, add(rndExcl(2), 2)); + } else { + if (arg1 <= getWidgetActualWidth(new WidgetPointer(arg0))) { + ivar3 = add(add(ivar3, rndExcl(2)), 2); + } + } + if ((arg2 >= 0) && (arg2 <= divide(getWidgetActualHeight(new WidgetPointer(arg0)), 2))) { + ivar4 = subtract(ivar4, add(rndExcl(2), 2)); + } else { + if (arg2 <= getWidgetActualHeight(new WidgetPointer(arg0))) { + ivar4 = add(add(ivar4, rndExcl(2)), 2); + } + } + ivar3 = max(ivar3, 0); + ivar4 = max(ivar4, 0); + ivar3 = min(ivar3, subtract(getWidgetActualWidth(new WidgetPointer(getWidgetParentId(new WidgetPointer(arg0)))), getWidgetActualWidth(new WidgetPointer(arg0)))); + ivar4 = min(ivar4, subtract(getWidgetActualHeight(new WidgetPointer(getWidgetParentId(new WidgetPointer(arg0)))), getWidgetActualHeight(new WidgetPointer(arg0)))); + setWidgetPosition(ivar3, ivar4, 0, 0, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/2136.cs2 b/dumps/scripts/2136.cs2 new file mode 100644 index 0000000..be2e736 --- /dev/null +++ b/dumps/scripts/2136.cs2 @@ -0,0 +1,110 @@ +void script_2136(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int stack_dump0; + int stack_dump1; + deleteAllExtraChilds(new WidgetPointer(arg0)); + ivar1 = add(add(118, bitconfig_5855), bitconfig_5855); + createExtraChild(new WidgetPointer(arg0), 4, 0); + setWidgetSize(200, 32, 0, 0); + setWidgetPosition(ivar1, 36, 0, 0); + setWidgetFont(497); + setWidgetTextAlignment(0, 1, 0); + setWidgetRGB(new Color(52, 46, 16)); + setWidgetUnknownBoolean(false); + setWidgetText(cs2method_3408(105, 115, 2224, bitconfig_5856)); + setScriptCallOnMouseEntered(1356, new WidgetPointer(-32768,3), -2147483643, 16777215, "Iii"); + setScriptCallOnMouseExit(1356, new WidgetPointer(-32768,3), -2147483643, 3419664, "Iii"); + setWidgetContextMenuOption(1, "Select"); + createExtraChild(new WidgetPointer(arg0), 4, 1); + setWidgetSize(200, 32, 0, 0); + setWidgetPosition(ivar1, 70, 0, 0); + setWidgetFont(497); + setWidgetTextAlignment(0, 1, 0); + setWidgetRGB(new Color(52, 46, 16)); + setWidgetUnknownBoolean(false); + setWidgetText(cs2method_3408(105, 115, 2224, bitconfig_5858)); + setScriptCallOnMouseEntered(1356, new WidgetPointer(-32768,3), -2147483643, 16777215, "Iii"); + setScriptCallOnMouseExit(1356, new WidgetPointer(-32768,3), -2147483643, 3419664, "Iii"); + setWidgetContextMenuOption(1, "Select"); + createExtraChild(new WidgetPointer(arg0), 4, 2); + setWidgetSize(200, 32, 0, 0); + setWidgetPosition(ivar1, 104, 0, 0); + setWidgetFont(497); + setWidgetTextAlignment(0, 1, 0); + setWidgetRGB(new Color(52, 46, 16)); + setWidgetUnknownBoolean(false); + setWidgetText(cs2method_3408(105, 115, 2224, bitconfig_5860)); + setScriptCallOnMouseEntered(1356, new WidgetPointer(-32768,3), -2147483643, 16777215, "Iii"); + setScriptCallOnMouseExit(1356, new WidgetPointer(-32768,3), -2147483643, 3419664, "Iii"); + setWidgetContextMenuOption(1, "Select"); + createExtraChild(new WidgetPointer(arg0), 6, 3); + setWidgetSize(226, 144, 0, 0); + setWidgetPosition(0, 147, 1, 0); + switch (bitconfig_5857) { + case 0: + setWidgetModel(cs2method_3408(105, 109, 2225, bitconfig_5862)); + break; + case 1: + setWidgetModel(cs2method_3408(105, 109, 2226, bitconfig_5862)); + break; + case 2: + setWidgetModel(cs2method_3408(105, 109, 2227, bitconfig_5862)); + break; + default: + setWidgetModel(cs2method_3408(105, 109, 2228, bitconfig_5862)); + } + ivar2 = multiply(subtract(bitconfig_5855, 5), 4); + ivar3 = multiply(subtract(bitconfig_5859, 4), 4); + setWidget3DRotation(ivar2, ivar3, pow(bitconfig_5861, 2), pow(bitconfig_5861, 2), pow(bitconfig_5861, 2), add(add(400, bitconfig_5863), bitconfig_5863)); + ivar4 = bitconfig_5855; + ivar5 = divide(bitconfig_5859, 2); + ivar6 = 0; + switch (bitconfig_5863) { + case 0: + stack_dump0 = ivar5; + stack_dump1 = ivar6; + ivar6 = ivar4; + stack_dump0 = stack_dump0; + ivar5 = stack_dump1; + ivar4 = stack_dump0; + break; + case 1: + stack_dump0 = ivar6; + stack_dump1 = ivar4; + ivar6 = ivar5; + stack_dump0 = stack_dump0; + ivar5 = stack_dump1; + ivar4 = stack_dump0; + break; + case 2: + stack_dump0 = ivar4; + stack_dump1 = ivar6; + ivar6 = ivar5; + stack_dump0 = stack_dump0; + ivar5 = stack_dump1; + ivar4 = stack_dump0; + } + setScriptCallOnGameloop(2137, ivar4, ivar5, ivar6, ivar2, ivar3, new WidgetPointer(-32768,3), -2147483643, "iiiiiIi"); + createExtraChild(new WidgetPointer(arg0), 3, 4); + setWidgetSize(226, 144, 0, 0); + setWidgetPosition(0, 147, 1, 0); + setWidgetRGB(new Color(script_693(add(bitconfig_5861, 95), add(bitconfig_5859, 85), add(bitconfig_5855, 29)))); + setWidgetFilled(1); + cs2method2103(0); + setScriptCallOnGameloop(2138, new WidgetPointer(-32768,3), -2147483643, 0, "Iii"); + createExtraChild(new WidgetPointer(arg0), 5, 5); + setWidgetSize(19, 16, 0, 0); + setWidgetPosition(349, add(bitconfig_5859, 148), 0, 0); + setWidgetHFlip(1); + setWidgetSprite(1538); + setScriptCallOnMouseEntered(2140, new WidgetPointer(-32768,3), -2147483643, 125, "Iii"); + setScriptCallOnMouseExit(2140, new WidgetPointer(-32768,3), -2147483643, 0, "Iii"); + setWidgetContextMenuOption(1, "Change spin"); + setScriptCallOnClickContextMenu(2139, -2147483644, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), ivar2, ivar3, "iIiii"); + return; +} diff --git a/dumps/scripts/2137.cs2 b/dumps/scripts/2137.cs2 new file mode 100644 index 0000000..bce3c00 --- /dev/null +++ b/dumps/scripts/2137.cs2 @@ -0,0 +1,6 @@ +void script_2137(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6) { + if (setWidgetRegister(new WidgetPointer(arg5), arg6)) { + setWidget3DRotation(arg3, arg4, bitAnd(add(getWidgetRotateX(), arg0), 2047), bitAnd(add(getWidgetRotateY(), arg1), 2047), bitAnd(add(cs2method1607(), arg2), 2047), getWidget3DDistance()); + } + return; +} diff --git a/dumps/scripts/2138.cs2 b/dumps/scripts/2138.cs2 new file mode 100644 index 0000000..c7530fa --- /dev/null +++ b/dumps/scripts/2138.cs2 @@ -0,0 +1,52 @@ +void script_2138(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + ivar3 = add(bitconfig_5861, 95); + ivar4 = add(bitconfig_5859, 85); + ivar5 = add(bitconfig_5855, 29); + ivar6 = 0; + ivar7 = 0; + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + if (arg2 < 150) { + arg2 = add(arg2, 10); + cs2method2103(arg2); + setScriptCallOnGameloop(2138, new WidgetPointer(-32768,3), -2147483643, arg2, "Iii"); + } else if (arg2 <= 225) { + arg2 = add(arg2, 2); + cs2method2103(arg2); + setScriptCallOnGameloop(2138, new WidgetPointer(-32768,3), -2147483643, arg2, "Iii"); + } else if (arg2 < 300) { + arg2 = add(arg2, 2); + cs2method2103(subtract(450, arg2)); + setScriptCallOnGameloop(2138, new WidgetPointer(-32768,3), -2147483643, arg2, "Iii"); + } else { + arg2 = 150; + cs2method2103(150); + setScriptCallOnGameloop(2138, new WidgetPointer(-32768,3), -2147483643, arg2, "Iii"); + } + ivar6 = multiplyDivide(cs2method1609(), 255, 100); + ivar7 = divide(ivar6, 2); + switch (bitconfig_5863) { + case 0: + ivar4 = add(ivar4, ivar6); + ivar3 = add(ivar3, ivar7); + break; + case 1: + ivar5 = add(ivar5, ivar6); + ivar3 = add(ivar3, ivar7); + break; + case 2: + ivar5 = add(ivar5, ivar6); + ivar4 = add(ivar4, ivar7); + break; + default: + ivar4 = add(ivar4, ivar6); + ivar5 = add(ivar5, ivar7); + } + setWidgetRGB(new Color(script_693(ivar3, ivar4, ivar5))); + } + return; +} diff --git a/dumps/scripts/2139.cs2 b/dumps/scripts/2139.cs2 new file mode 100644 index 0000000..6571f0c --- /dev/null +++ b/dumps/scripts/2139.cs2 @@ -0,0 +1,9 @@ +void script_2139(int arg0,int arg1,int arg2,int arg3,int arg4) { + if (arg0 != 1) { + return; + } + if (setWidgetRegister(new WidgetPointer(arg1), 3)) { + setWidget3DRotation(arg3, arg4, bitAnd(add(getWidgetRotateX(), 25), 2047), bitAnd(add(getWidgetRotateY(), 25), 2047), bitAnd(add(cs2method1607(), 25), 2047), getWidget3DDistance()); + } + return; +} diff --git a/dumps/scripts/214.cs2 b/dumps/scripts/214.cs2 new file mode 100644 index 0000000..38cd396 --- /dev/null +++ b/dumps/scripts/214.cs2 @@ -0,0 +1,7 @@ +void script_214(int arg0,int arg1) { + int ivar2; + ivar2 = getWidgetParentId(new WidgetPointer(arg0)); + setScriptCallOnConfigChange(1660, new WidgetPointer(arg0), arg1, new WidgetPointer(ivar2), 281, 1255, 2, "IiIY", new WidgetPointer(ivar2)); + script_1661(arg0, arg1, ivar2); + return; +} diff --git a/dumps/scripts/2140.cs2 b/dumps/scripts/2140.cs2 new file mode 100644 index 0000000..4ef0568 --- /dev/null +++ b/dumps/scripts/2140.cs2 @@ -0,0 +1,6 @@ +void script_2140(int arg0,int arg1,int arg2) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + cs2method2103(arg2); + } + return; +} diff --git a/dumps/scripts/2141.cs2 b/dumps/scripts/2141.cs2 new file mode 100644 index 0000000..c4a6aee --- /dev/null +++ b/dumps/scripts/2141.cs2 @@ -0,0 +1,34 @@ +void script_2141() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + string svar0; + int stack_dump0; + cs2func_script_942_struct(1,1,0) structdump_1; + deleteAllExtraChilds(new WidgetPointer(864,7)); + if (standart_config_1469 == -1) { + return; + } + ivar0 = 0; + ivar1 = 10; + ivar2 = 0; + ivar3 = 0; + svar0 = ""; + while (ivar2 != -1) { + stack_dump0 = ivar3; + structdump_1 = script_942(stack_dump0); + svar0 = structdump_1.stringpart_0; + ivar2 = structdump_1.intpart_0; + if (((boolean)ivar2)) { + ivar1 = add(ivar1, script_2142(ivar0, ivar1, ivar3, svar0)); + ivar0 = add(ivar0, 1); + } + ivar3 = add(ivar3, 1); + } + setWidgetScrollMax(296, ivar1, new WidgetPointer(864,7)); + if (ivar1 > 240) { + script_31(56623112, 56623111, 798, 795, 796, 797, 793, 794); + } + return; +} diff --git a/dumps/scripts/2142.cs2 b/dumps/scripts/2142.cs2 new file mode 100644 index 0000000..9fc39d0 --- /dev/null +++ b/dumps/scripts/2142.cs2 @@ -0,0 +1,18 @@ +int script_2142(int arg0,int arg1,int arg2,string arg3) { + int ivar3; + int ivar4; + ivar3 = getLineCount(390, 495, arg3); + ivar4 = 15; + createExtraChild(new WidgetPointer(864,7), 4, arg0); + setWidgetSize(390, multiply(ivar3, ivar4), 0, 0); + setWidgetText(arg3); + setWidgetPosition(15, arg1, 0, 0); + setWidgetTextAlignment(0, 0, 0); + setWidgetRGB(new Color(70, 50, 10)); + setWidgetFont(495); + setWidgetUnknownBoolean(false); + setWidgetContextMenuOption(1, "Teleport"); + setScriptCallOnMouseEntered(1356, new WidgetPointer(-32768,3), -2147483643, 6574120, "Iii"); + setScriptCallOnMouseExit(1356, new WidgetPointer(-32768,3), -2147483643, 4600330, "Iii"); + return add(multiply(ivar3, ivar4), 5); +} diff --git a/dumps/scripts/2143.cs2 b/dumps/scripts/2143.cs2 new file mode 100644 index 0000000..6798120 --- /dev/null +++ b/dumps/scripts/2143.cs2 @@ -0,0 +1,23 @@ +void script_2143(int arg0,int arg1) { + int ivar2; + int ivar3; + ivar2 = 1093; + if (IsFemale()) { + ivar2 = 3872; + } + ivar3 = 0; + while (ivar3 <= getCommonDefinitionSize(ivar2)) { + if (setWidgetRegister(new WidgetPointer(arg0), ivar3)) { + if (((boolean)script_2476(ivar3))) { + setWidgetRGB(new Color(17, 255, 0)); + } else { + setWidgetRGB(new Color(255, 17, 0)); + } + } + ivar3 = add(1, ivar3); + } + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetRGB(new Color(255, 255, 255)); + } + return; +} diff --git a/dumps/scripts/2144.cs2 b/dumps/scripts/2144.cs2 new file mode 100644 index 0000000..d6f22a2 --- /dev/null +++ b/dumps/scripts/2144.cs2 @@ -0,0 +1,13 @@ +void script_2144(int arg0) { + int ivar1; + ivar1 = 1093; + if (IsFemale()) { + ivar1 = 3872; + } + if (((boolean)standart_config_1442)) { + setWidgetText(new WidgetPointer(arg0), "No Prefix"); + } else { + setWidgetText(new WidgetPointer(arg0), cs2method_3408(105, 115, ivar1, standart_config_1442)); + } + return; +} diff --git a/dumps/scripts/2145.cs2 b/dumps/scripts/2145.cs2 new file mode 100644 index 0000000..e82fe72 --- /dev/null +++ b/dumps/scripts/2145.cs2 @@ -0,0 +1,218 @@ +cs2func_script_2145_struct(2,1,0) script_2145(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + string svar0; + int stack_dump0; + int stack_dump1; + int stack_dump2; + int stack_dump3; + string stack_dump4; + cs2func_script_2146_struct(2,1,0) structdump_5; + cs2func_script_2146_struct(2,1,0) structdump_6; + cs2func_script_2146_struct(2,1,0) structdump_7; + cs2func_script_2146_struct(2,1,0) structdump_8; + cs2func_script_2146_struct(2,1,0) structdump_9; + cs2func_script_2146_struct(2,1,0) structdump_10; + cs2func_script_2146_struct(2,1,0) structdump_11; + cs2func_script_2146_struct(2,1,0) structdump_12; + cs2func_script_2146_struct(2,1,0) structdump_13; + cs2func_script_2146_struct(2,1,0) structdump_14; + cs2func_script_2146_struct(2,1,0) structdump_15; + cs2func_script_2146_struct(2,1,0) structdump_16; + ivar3 = cs2method_3408(105, 74, 169, arg1); + ivar4 = cs2method_3408(105, 74, getOtherCommonData(ivar3, 61), arg2); + ivar5 = getSkillActualLvl(arg0); + svar0 = "null"; + ivar6 = -1; + ivar7 = 0; + if (ivar4 == -1) { + return newstruct cs2func_script_2145_struct(ivar6, 0, svar0); + } + if (((boolean)arg1) && (script_2193(arg2) == 2)) { + return newstruct cs2func_script_2145_struct(ivar6, 0, svar0); + } + if (getOtherCommonData(ivar4, 871) == -1) { + return newstruct cs2func_script_2145_struct(ivar6, 0, svar0); + } + if ((getOtherCommonData(ivar4, 871) == arg0) && (ivar5 == getOtherCommonData(ivar4, 872))) { + stack_dump0 = arg0; + stack_dump1 = arg1; + stack_dump2 = ivar5; + stack_dump3 = arg2; + stack_dump4 = getOtherCommonData(ivar4, 845); + structdump_5 = script_2146(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar7 = structdump_5.intpart_1; + ivar6 = structdump_5.intpart_0; + svar0 = structdump_5.stringpart_0; + return newstruct cs2func_script_2145_struct(ivar6, ivar7, svar0); + } + if (getOtherCommonData(ivar4, 873) == -1) { + return newstruct cs2func_script_2145_struct(ivar6, 0, svar0); + } + if ((getOtherCommonData(ivar4, 873) == arg0) && (ivar5 == getOtherCommonData(ivar4, 874))) { + stack_dump0 = arg0; + stack_dump1 = arg1; + stack_dump2 = ivar5; + stack_dump3 = arg2; + stack_dump4 = getOtherCommonData(ivar4, 845); + structdump_6 = script_2146(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar7 = structdump_6.intpart_1; + ivar6 = structdump_6.intpart_0; + svar0 = structdump_6.stringpart_0; + return newstruct cs2func_script_2145_struct(ivar6, ivar7, svar0); + } + if (getOtherCommonData(ivar4, 875) == -1) { + return newstruct cs2func_script_2145_struct(ivar6, 0, svar0); + } + if ((getOtherCommonData(ivar4, 875) == arg0) && (ivar5 == getOtherCommonData(ivar4, 876))) { + stack_dump0 = arg0; + stack_dump1 = arg1; + stack_dump2 = ivar5; + stack_dump3 = arg2; + stack_dump4 = getOtherCommonData(ivar4, 845); + structdump_7 = script_2146(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar7 = structdump_7.intpart_1; + ivar6 = structdump_7.intpart_0; + svar0 = structdump_7.stringpart_0; + return newstruct cs2func_script_2145_struct(ivar6, ivar7, svar0); + } + if (getOtherCommonData(ivar4, 877) == -1) { + return newstruct cs2func_script_2145_struct(ivar6, 0, svar0); + } + if ((getOtherCommonData(ivar4, 877) == arg0) && (ivar5 == getOtherCommonData(ivar4, 878))) { + stack_dump0 = arg0; + stack_dump1 = arg1; + stack_dump2 = ivar5; + stack_dump3 = arg2; + stack_dump4 = getOtherCommonData(ivar4, 845); + structdump_8 = script_2146(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar7 = structdump_8.intpart_1; + ivar6 = structdump_8.intpart_0; + svar0 = structdump_8.stringpart_0; + return newstruct cs2func_script_2145_struct(ivar6, ivar7, svar0); + } + if (getOtherCommonData(ivar4, 879) == -1) { + return newstruct cs2func_script_2145_struct(ivar6, 0, svar0); + } + if ((getOtherCommonData(ivar4, 879) == arg0) && (ivar5 == getOtherCommonData(ivar4, 880))) { + stack_dump0 = arg0; + stack_dump1 = arg1; + stack_dump2 = ivar5; + stack_dump3 = arg2; + stack_dump4 = getOtherCommonData(ivar4, 845); + structdump_9 = script_2146(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar7 = structdump_9.intpart_1; + ivar6 = structdump_9.intpart_0; + svar0 = structdump_9.stringpart_0; + return newstruct cs2func_script_2145_struct(ivar6, ivar7, svar0); + } + if (getOtherCommonData(ivar4, 881) == -1) { + return newstruct cs2func_script_2145_struct(ivar6, 0, svar0); + } + if ((getOtherCommonData(ivar4, 881) == arg0) && (ivar5 == getOtherCommonData(ivar4, 882))) { + stack_dump0 = arg0; + stack_dump1 = arg1; + stack_dump2 = ivar5; + stack_dump3 = arg2; + stack_dump4 = getOtherCommonData(ivar4, 845); + structdump_10 = script_2146(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar7 = structdump_10.intpart_1; + ivar6 = structdump_10.intpart_0; + svar0 = structdump_10.stringpart_0; + return newstruct cs2func_script_2145_struct(ivar6, ivar7, svar0); + } + if (getOtherCommonData(ivar4, 883) == -1) { + return newstruct cs2func_script_2145_struct(ivar6, 0, svar0); + } + if ((getOtherCommonData(ivar4, 883) == arg0) && (ivar5 == getOtherCommonData(ivar4, 884))) { + stack_dump0 = arg0; + stack_dump1 = arg1; + stack_dump2 = ivar5; + stack_dump3 = arg2; + stack_dump4 = getOtherCommonData(ivar4, 845); + structdump_11 = script_2146(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar7 = structdump_11.intpart_1; + ivar6 = structdump_11.intpart_0; + svar0 = structdump_11.stringpart_0; + return newstruct cs2func_script_2145_struct(ivar6, ivar7, svar0); + } + if (getOtherCommonData(ivar4, 885) == -1) { + return newstruct cs2func_script_2145_struct(ivar6, 0, svar0); + } + if ((getOtherCommonData(ivar4, 885) == arg0) && (ivar5 == getOtherCommonData(ivar4, 886))) { + stack_dump0 = arg0; + stack_dump1 = arg1; + stack_dump2 = ivar5; + stack_dump3 = arg2; + stack_dump4 = getOtherCommonData(ivar4, 845); + structdump_12 = script_2146(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar7 = structdump_12.intpart_1; + ivar6 = structdump_12.intpart_0; + svar0 = structdump_12.stringpart_0; + return newstruct cs2func_script_2145_struct(ivar6, ivar7, svar0); + } + if (getOtherCommonData(ivar4, 887) == -1) { + return newstruct cs2func_script_2145_struct(ivar6, 0, svar0); + } + if ((getOtherCommonData(ivar4, 887) == arg0) && (ivar5 == getOtherCommonData(ivar4, 888))) { + stack_dump0 = arg0; + stack_dump1 = arg1; + stack_dump2 = ivar5; + stack_dump3 = arg2; + stack_dump4 = getOtherCommonData(ivar4, 845); + structdump_13 = script_2146(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar7 = structdump_13.intpart_1; + ivar6 = structdump_13.intpart_0; + svar0 = structdump_13.stringpart_0; + return newstruct cs2func_script_2145_struct(ivar6, ivar7, svar0); + } + if (getOtherCommonData(ivar4, 889) == -1) { + return newstruct cs2func_script_2145_struct(ivar6, 0, svar0); + } + if ((getOtherCommonData(ivar4, 889) == arg0) && (ivar5 == getOtherCommonData(ivar4, 890))) { + stack_dump0 = arg0; + stack_dump1 = arg1; + stack_dump2 = ivar5; + stack_dump3 = arg2; + stack_dump4 = getOtherCommonData(ivar4, 845); + structdump_14 = script_2146(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar7 = structdump_14.intpart_1; + ivar6 = structdump_14.intpart_0; + svar0 = structdump_14.stringpart_0; + return newstruct cs2func_script_2145_struct(ivar6, ivar7, svar0); + } + if (getOtherCommonData(ivar4, 891) == -1) { + return newstruct cs2func_script_2145_struct(ivar6, 0, svar0); + } + if ((getOtherCommonData(ivar4, 891) == arg0) && (ivar5 == getOtherCommonData(ivar4, 892))) { + stack_dump0 = arg0; + stack_dump1 = arg1; + stack_dump2 = ivar5; + stack_dump3 = arg2; + stack_dump4 = getOtherCommonData(ivar4, 845); + structdump_15 = script_2146(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar7 = structdump_15.intpart_1; + ivar6 = structdump_15.intpart_0; + svar0 = structdump_15.stringpart_0; + return newstruct cs2func_script_2145_struct(ivar6, ivar7, svar0); + } + if (getOtherCommonData(ivar4, 893) == -1) { + return newstruct cs2func_script_2145_struct(ivar6, 0, svar0); + } + if ((getOtherCommonData(ivar4, 893) == arg0) && (ivar5 == getOtherCommonData(ivar4, 894))) { + stack_dump0 = arg0; + stack_dump1 = arg1; + stack_dump2 = ivar5; + stack_dump3 = arg2; + stack_dump4 = getOtherCommonData(ivar4, 845); + structdump_16 = script_2146(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar7 = structdump_16.intpart_1; + ivar6 = structdump_16.intpart_0; + svar0 = structdump_16.stringpart_0; + return newstruct cs2func_script_2145_struct(ivar6, ivar7, svar0); + } + return newstruct cs2func_script_2145_struct(-1, 0, ""); +} diff --git a/dumps/scripts/2146.cs2 b/dumps/scripts/2146.cs2 new file mode 100644 index 0000000..875a90e --- /dev/null +++ b/dumps/scripts/2146.cs2 @@ -0,0 +1,17 @@ +cs2func_script_2146_struct(2,1,0) script_2146(int arg0,int arg1,int arg2,int arg3,string arg4) { + int ivar4; + int ivar5; + string svar1; + svar1 = "null"; + ivar4 = -1; + ivar5 = 1; + if (((boolean)script_2152(arg1, arg3))) { + svar1 = "" + "Level " + intToStr(arg2) + " " + "" + cs2method_3408(83, 115, 680, arg0) + "" + " is one of the requirements for " + "" + arg4 + "" + "."; + } else { + svar1 = "" + "You have all of the levels required to complete " + "" + arg4 + "" + "."; + } + if (ivar4 == -1) { + ivar4 = 6513; + } + return newstruct cs2func_script_2146_struct(ivar4, ivar5, svar1); +} diff --git a/dumps/scripts/2147.cs2 b/dumps/scripts/2147.cs2 new file mode 100644 index 0000000..1e4698e --- /dev/null +++ b/dumps/scripts/2147.cs2 @@ -0,0 +1,4 @@ +void script_2147() { + globalint_698 = script_1432(); + return; +} diff --git a/dumps/scripts/2148.cs2 b/dumps/scripts/2148.cs2 new file mode 100644 index 0000000..9438d55 --- /dev/null +++ b/dumps/scripts/2148.cs2 @@ -0,0 +1,7 @@ +int script_2148(int arg0,int arg1) { + int ivar2; + ivar2 = cs2method_3408(105, 74, 169, arg0); + globalint_699 = cs2method_3408(105, 74, getOtherCommonData(ivar2, 61), arg1); + globalint_698 = script_1432(); + return script_2149(); +} diff --git a/dumps/scripts/2149.cs2 b/dumps/scripts/2149.cs2 new file mode 100644 index 0000000..bb29514 --- /dev/null +++ b/dumps/scripts/2149.cs2 @@ -0,0 +1,18 @@ +int script_2149() { + if (((boolean)script_2155())) { + return 0; + } + if (standart_config_101 < getOtherCommonData(globalint_699, 895)) { + return 0; + } + if (globalint_698 < getOtherCommonData(globalint_699, 896)) { + return 0; + } + if (((boolean)script_2153())) { + return 0; + } + if (((boolean)getOtherCommonData(globalint_699, 898)) && ((boolean)script_2194(getOtherCommonData(globalint_699, 847)))) { + return 0; + } + return 1; +} diff --git a/dumps/scripts/215.cs2 b/dumps/scripts/215.cs2 new file mode 100644 index 0000000..832e214 --- /dev/null +++ b/dumps/scripts/215.cs2 @@ -0,0 +1,4 @@ +void script_215() { + script_216(); + return; +} diff --git a/dumps/scripts/2150.cs2 b/dumps/scripts/2150.cs2 new file mode 100644 index 0000000..54cad22 --- /dev/null +++ b/dumps/scripts/2150.cs2 @@ -0,0 +1,9 @@ +int script_2150(int arg0,int arg1) { + int ivar2; + ivar2 = cs2method_3408(105, 74, 169, arg0); + globalint_699 = cs2method_3408(105, 74, getOtherCommonData(ivar2, 61), arg1); + if (standart_config_101 < getOtherCommonData(globalint_699, 895)) { + return 0; + } + return 1; +} diff --git a/dumps/scripts/2151.cs2 b/dumps/scripts/2151.cs2 new file mode 100644 index 0000000..c226bd7 --- /dev/null +++ b/dumps/scripts/2151.cs2 @@ -0,0 +1,9 @@ +int script_2151(int arg0,int arg1) { + int ivar2; + ivar2 = cs2method_3408(105, 74, 169, arg0); + globalint_699 = cs2method_3408(105, 74, getOtherCommonData(ivar2, 61), arg1); + if (script_1432() < getOtherCommonData(globalint_699, 896)) { + return 0; + } + return 1; +} diff --git a/dumps/scripts/2152.cs2 b/dumps/scripts/2152.cs2 new file mode 100644 index 0000000..0257db9 --- /dev/null +++ b/dumps/scripts/2152.cs2 @@ -0,0 +1,6 @@ +int script_2152(int arg0,int arg1) { + int ivar2; + ivar2 = cs2method_3408(105, 74, 169, arg0); + globalint_699 = cs2method_3408(105, 74, getOtherCommonData(ivar2, 61), arg1); + return script_2153(); +} diff --git a/dumps/scripts/2153.cs2 b/dumps/scripts/2153.cs2 new file mode 100644 index 0000000..debe24c --- /dev/null +++ b/dumps/scripts/2153.cs2 @@ -0,0 +1,91 @@ +int script_2153() { + int ivar0; + ivar0 = getOtherCommonData(globalint_699, 871); + if (((boolean)getOtherCommonData(globalint_699, 897)) && (add(getSkillActualLvl(0), getSkillActualLvl(2)) < 130)) { + return 0; + } + if (ivar0 == -1) { + return 1; + } + if (getSkillActualLvl(ivar0) < getOtherCommonData(globalint_699, 872)) { + return 0; + } + ivar0 = getOtherCommonData(globalint_699, 873); + if (ivar0 == -1) { + return 1; + } + if (getSkillActualLvl(ivar0) < getOtherCommonData(globalint_699, 874)) { + return 0; + } + ivar0 = getOtherCommonData(globalint_699, 875); + if (ivar0 == -1) { + return 1; + } + if (getSkillActualLvl(ivar0) < getOtherCommonData(globalint_699, 876)) { + return 0; + } + ivar0 = getOtherCommonData(globalint_699, 877); + if (ivar0 == -1) { + return 1; + } + if (getSkillActualLvl(ivar0) < getOtherCommonData(globalint_699, 878)) { + return 0; + } + ivar0 = getOtherCommonData(globalint_699, 879); + if (ivar0 == -1) { + return 1; + } + if (getSkillActualLvl(ivar0) < getOtherCommonData(globalint_699, 880)) { + return 0; + } + ivar0 = getOtherCommonData(globalint_699, 881); + if (ivar0 == -1) { + return 1; + } + if (getSkillActualLvl(ivar0) < getOtherCommonData(globalint_699, 882)) { + return 0; + } + ivar0 = getOtherCommonData(globalint_699, 883); + if (ivar0 == -1) { + return 1; + } + if (getSkillActualLvl(ivar0) < getOtherCommonData(globalint_699, 884)) { + return 0; + } + ivar0 = getOtherCommonData(globalint_699, 885); + if (ivar0 == -1) { + return 1; + } + if (getSkillActualLvl(ivar0) < getOtherCommonData(globalint_699, 886)) { + return 0; + } + ivar0 = getOtherCommonData(globalint_699, 887); + if (ivar0 == -1) { + return 1; + } + if (getSkillActualLvl(ivar0) < getOtherCommonData(globalint_699, 888)) { + return 0; + } + ivar0 = getOtherCommonData(globalint_699, 889); + if (ivar0 == -1) { + return 1; + } + if (getSkillActualLvl(ivar0) < getOtherCommonData(globalint_699, 890)) { + return 0; + } + ivar0 = getOtherCommonData(globalint_699, 891); + if (ivar0 == -1) { + return 1; + } + if (getSkillActualLvl(ivar0) < getOtherCommonData(globalint_699, 892)) { + return 0; + } + ivar0 = getOtherCommonData(globalint_699, 893); + if (ivar0 == -1) { + return 1; + } + if (getSkillActualLvl(ivar0) < getOtherCommonData(globalint_699, 894)) { + return 0; + } + return 1; +} diff --git a/dumps/scripts/2154.cs2 b/dumps/scripts/2154.cs2 new file mode 100644 index 0000000..30ff6d5 --- /dev/null +++ b/dumps/scripts/2154.cs2 @@ -0,0 +1,4 @@ +int script_2154(int arg0) { + globalint_699 = cs2method_3408(105, 74, 2252, arg0); + return script_2155(); +} diff --git a/dumps/scripts/2155.cs2 b/dumps/scripts/2155.cs2 new file mode 100644 index 0000000..65ad801 --- /dev/null +++ b/dumps/scripts/2155.cs2 @@ -0,0 +1,88 @@ +int script_2155() { + int ivar0; + ivar0 = getOtherCommonData(globalint_699, 859); + if (ivar0 == -1) { + return 1; + } + if (((boolean)script_2156(ivar0))) { + return 0; + } + ivar0 = getOtherCommonData(globalint_699, 860); + if (ivar0 == -1) { + return 1; + } + if (((boolean)script_2156(ivar0))) { + return 0; + } + ivar0 = getOtherCommonData(globalint_699, 861); + if (ivar0 == -1) { + return 1; + } + if (((boolean)script_2156(ivar0))) { + return 0; + } + ivar0 = getOtherCommonData(globalint_699, 862); + if (ivar0 == -1) { + return 1; + } + if (((boolean)script_2156(ivar0))) { + return 0; + } + ivar0 = getOtherCommonData(globalint_699, 863); + if (ivar0 == -1) { + return 1; + } + if (((boolean)script_2156(ivar0))) { + return 0; + } + ivar0 = getOtherCommonData(globalint_699, 864); + if (ivar0 == -1) { + return 1; + } + if (((boolean)script_2156(ivar0))) { + return 0; + } + ivar0 = getOtherCommonData(globalint_699, 865); + if (ivar0 == -1) { + return 1; + } + if (((boolean)script_2156(ivar0))) { + return 0; + } + ivar0 = getOtherCommonData(globalint_699, 866); + if (ivar0 == -1) { + return 1; + } + if (((boolean)script_2156(ivar0))) { + return 0; + } + ivar0 = getOtherCommonData(globalint_699, 867); + if (ivar0 == -1) { + return 1; + } + if (((boolean)script_2156(ivar0))) { + return 0; + } + ivar0 = getOtherCommonData(globalint_699, 868); + if (ivar0 == -1) { + return 1; + } + if (((boolean)script_2156(ivar0))) { + return 0; + } + ivar0 = getOtherCommonData(globalint_699, 869); + if (ivar0 == -1) { + return 1; + } + if (((boolean)script_2156(ivar0))) { + return 0; + } + ivar0 = getOtherCommonData(globalint_699, 870); + if (ivar0 == -1) { + return 1; + } + if (((boolean)script_2156(ivar0))) { + return 0; + } + return 1; +} diff --git a/dumps/scripts/2156.cs2 b/dumps/scripts/2156.cs2 new file mode 100644 index 0000000..d6fd5d5 --- /dev/null +++ b/dumps/scripts/2156.cs2 @@ -0,0 +1,8 @@ +int script_2156(int arg0) { + int ivar1; + ivar1 = script_2193(arg0); + if (ivar1 == 2) { + return 1; + } + return 0; +} diff --git a/dumps/scripts/2157.cs2 b/dumps/scripts/2157.cs2 new file mode 100644 index 0000000..9925993 --- /dev/null +++ b/dumps/scripts/2157.cs2 @@ -0,0 +1,3 @@ +int script_2157(int arg0,int arg1) { + return script_2158(arg0, 1, arg1); +} diff --git a/dumps/scripts/2158.cs2 b/dumps/scripts/2158.cs2 new file mode 100644 index 0000000..4737e3f --- /dev/null +++ b/dumps/scripts/2158.cs2 @@ -0,0 +1,9 @@ +int script_2158(int arg0,int arg1,int arg2) { + if (arg0 < arg1) { + return 0; + } + if (arg0 < arg2) { + return 1; + } + return 2; +} diff --git a/dumps/scripts/2159.cs2 b/dumps/scripts/2159.cs2 new file mode 100644 index 0000000..f22778b --- /dev/null +++ b/dumps/scripts/2159.cs2 @@ -0,0 +1,9 @@ +int script_2159(int arg0,int arg1,int arg2,int arg3) { + if (((boolean)arg0) && ((boolean)arg2)) { + return 0; + } + if ((arg0 < arg1) && (arg2 < arg3)) { + return 1; + } + return 2; +} diff --git a/dumps/scripts/216.cs2 b/dumps/scripts/216.cs2 new file mode 100644 index 0000000..1d0c413 --- /dev/null +++ b/dumps/scripts/216.cs2 @@ -0,0 +1,24 @@ +void script_216() { + globalint_790 = 1; + setWidgetIsHidden(true, new WidgetPointer(594,61)); + setWidgetIsHidden(true, new WidgetPointer(594,34)); + setWidgetIsHidden(true, new WidgetPointer(594,33)); + setWidgetIsHidden(true, new WidgetPointer(594,148)); + setWidgetIsHidden(true, new WidgetPointer(594,149)); + setWidgetIsHidden(true, new WidgetPointer(594,150)); + setWidgetIsHidden(true, new WidgetPointer(594,151)); + setWidgetIsHidden(true, new WidgetPointer(594,165)); + setWidgetIsHidden(true, new WidgetPointer(594,166)); + setWidgetIsHidden(true, new WidgetPointer(594,104)); + setWidgetIsHidden(true, new WidgetPointer(594,120)); + setWidgetIsHidden(true, new WidgetPointer(594,62)); + setWidgetIsHidden(true, new WidgetPointer(594,117)); + setWidgetIsHidden(true, new WidgetPointer(594,121)); + if (((boolean)getLanguage())) { + setWidgetIsHidden(false, new WidgetPointer(594,61)); + script_217(); + } else { + setWidgetIsHidden(false, new WidgetPointer(594,33)); + } + return; +} diff --git a/dumps/scripts/2160.cs2 b/dumps/scripts/2160.cs2 new file mode 100644 index 0000000..fa7e866 --- /dev/null +++ b/dumps/scripts/2160.cs2 @@ -0,0 +1,76 @@ +void script_2160(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + ivar1 = cs2method_3408(105, 74, 169, arg0); + if (ivar1 == -1) { + return; + } + ivar2 = getOtherCommonData(ivar1, 61); + if (ivar2 == -1) { + return; + } + ivar3 = getOtherCommonData(ivar1, 152); + ivar4 = getOtherCommonData(ivar1, 153); + deleteAllExtraChilds(new WidgetPointer(ivar3)); + ivar5 = 0; + ivar6 = 0; + ivar7 = -1; + ivar8 = -1; + ivar9 = 0; + if (isMember()) { + globalint_693 = bitconfig_4536; + } else { + globalint_693 = 0; + } + globalint_694 = bitconfig_4538; + globalint_1103 = bitconfig_7264; + globalint_692 = bitconfig_4537; + globalint_272 = getCommonDefinitionSize(ivar2); + while (ivar6 < globalint_272) { + ivar7 = cs2method_3408(105, 74, ivar2, ivar5); + createExtraChild(new WidgetPointer(ivar3), 4, ivar5); + if (ivar7 != -1) { + ivar6 = add(ivar6, 1); + ivar9 = script_2193(ivar5); + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(0, 15, 1, 0); + setWidgetRGB(new Color(34, 34, 34)); + setWidgetFont(494); + setWidgetTextAlignment(0, 0, 0); + setWidgetUnknownBoolean(true); + setWidgetText(getOtherCommonData(ivar7, 845)); + if (((ivar8 == -1) && (ivar7 == 510)) && ((boolean)arg0)) { + ivar8 = getWidgetCustomChildArrayIndex(); + } + } else { + setWidgetHidden(1); + } + ivar5 = add(ivar5, 1); + } + globalint_273 = subtract(ivar5, 1); + while (ivar5 < add(globalint_273, 10)) { + createExtraChild(new WidgetPointer(ivar3), 4, ivar5); + setWidgetFont(496); + setWidgetSize(0, 30, 1, 0); + setWidgetSize(0, 20, 1, 0); + setWidgetTextAlignment(0, 1, 0); + setWidgetText(""); + setWidgetRGB(new Color(255, 153, 0)); + setWidgetHidden(1); + setWidgetUnknownBoolean(true); + ivar5 = add(ivar5, 1); + } + script_2162(arg0, globalint_693, globalint_694, globalint_692, globalint_1103); + script_31(ivar4, ivar3, 792, 789, 790, 791, 773, 788); + if (ivar8 != -1) { + script_214(ivar3, ivar8); + } + return; +} diff --git a/dumps/scripts/2161.cs2 b/dumps/scripts/2161.cs2 new file mode 100644 index 0000000..3188023 --- /dev/null +++ b/dumps/scripts/2161.cs2 @@ -0,0 +1,5 @@ +void script_2161(int arg0,int arg1,int arg2) { + int ivar3; + ivar3 = 0; + return; +} diff --git a/dumps/scripts/2162.cs2 b/dumps/scripts/2162.cs2 new file mode 100644 index 0000000..dd1a783 --- /dev/null +++ b/dumps/scripts/2162.cs2 @@ -0,0 +1,287 @@ +void script_2162(int arg0,int arg1,int arg2,int arg3,int arg4) { + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + int ivar22; + int ivar23; + int ivar24; + int ivar25; + int ivar26; + string svar0; + string svar1; + do { + flow_17: + ivar10 = 0; + ivar23 = 0; + if (((boolean)arg2)) { + ivar23 = subtract(ivar18, 1); + } + ivar24 = 5; + ivar25 = 0; + ivar26 = -1; + if (((boolean)arg0)) { + ivar26 = bitconfig_6913; + } else if (getOtherCommonData(ivar5, 693) > 0) { + ivar26 = subtract(bitconfig_697, multiply(1000, subtract(getOtherCommonData(ivar5, 693), 1))); + } else { + ivar26 = subtract(bitconfig_697, multiply(1000, subtract(arg0, 1))); + } + while (true) { + flow_24: + IF (((boolean)arg2)) + GOTO flow_25 + GOTO flow_26 + flow_25: + IF (ivar23 < ivar18) + GOTO flow_28 + flow_26: + IF (((boolean)arg2) && (ivar23 >= 0)) + GOTO flow_28 + break; + flow_28: + ivar21 = cs2method_3408(105, 105, ivar17, ivar23); + if (setWidgetRegister(new WidgetPointer(ivar7), add(add(globalint_273, ivar23), 1))) { + setWidgetPosition(0, ivar24, 0, 0); + svar0 = cs2method_3408(105, 115, ivar15, ivar21); + setWidgetText(svar0); + setWidgetHidden(0); + ivar24 = add(ivar24, getWidgetActualHeight()); + } + ivar13 = 0; + while (ivar11 < globalint_272) { + globalint_699 = cs2method_3408(105, 74, ivar6, globalarray_0[ivar10]); + if (globalint_699 != -1) { + ivar11 = add(ivar11, 1); + switch (arg1) { + flow_34: + case 0: + ivar22 = getOtherCommonData(globalint_699, 856); + if ((ivar22 == 4) && (standart_config_281 == 1000)) { + ivar22 = 0; + } + break; + case 1: + switch (arg0) { + case 1: + ivar22 = globalarray_1[ivar10]; + break; + case 3: + ivar22 = getOtherCommonData(globalint_699, 677); + } + break; + case 2: + SWITCH (arg0) { + case 1: + GOTO flow_43 + case 3: + GOTO flow_44 + } + break; + flow_43: + ivar22 = getOtherCommonData(globalint_699, 848); + break; + flow_44: + ivar22 = getOtherCommonData(globalint_699, 678); + } + if (ivar22 != ivar21) { + ivar14 = 0; + } + if ((((boolean)ivar14) && ((boolean)arg3)) && ((boolean)globalarray_1[ivar10])) { + ivar12 = script_2149(); + if (((boolean)ivar12)) { + ivar14 = 0; + } + } + if ((((boolean)ivar14) && ((boolean)arg4)) && (globalarray_1[ivar10] == 2)) { + ivar14 = 0; + } + if (((boolean)ivar14) && setWidgetRegister(new WidgetPointer(ivar7), globalarray_0[ivar10])) { + setWidgetPosition(10, ivar24, 0, 0); + setWidgetHidden(0); + if (((boolean)getOtherCommonData(globalint_699, 694))) { + if (((boolean)globalarray_1[ivar10])) { + setWidgetContextMenuOption(1, "View Quest Overview"); + setWidgetContextMenuOption(2, "View Quest Journal"); + setWidgetContextMenuOption(3, "Toggle Map Hint"); + } else if (((boolean)globalarray_1[ivar10])) { + setWidgetContextMenuOption(1, "View Quest Journal"); + setWidgetContextMenuOption(2, "View Quest Overview"); + setWidgetContextMenuOption(3, "Toggle Map Hints"); + } else { + setWidgetContextMenuOption(1, "View Quest Journal"); + setWidgetContextMenuOption(2, "View Quest Overview"); + setWidgetContextMenuOption(3, ""); + } + } else if (((boolean)globalarray_1[ivar10])) { + setWidgetContextMenuOption(2, "Toggle Map Hint"); + } else { + setWidgetContextMenuOption(2, ""); + } + setWidgetContextMenuOption(1, "View Quest Journal"); + setWidgetContextMenuOption(3, ""); + setScriptCallOnMouseEntered(1356, new WidgetPointer(-32768,3), -2147483643, 16777215, "Iii"); + if (globalarray_0[ivar10] == ivar26) { + setWidgetRGB(new Color(0, 255, 255)); + setScriptCallOnMouseExit(1949, new WidgetPointer(-32768,3), -2147483643, 65535, new WidgetPointer(ivar9), "IiiI"); + } else if (((boolean)globalarray_1[ivar10])) { + setWidgetRGB(new Color(255, 0, 0)); + setScriptCallOnMouseExit(1949, new WidgetPointer(-32768,3), -2147483643, 16711680, new WidgetPointer(ivar9), "IiiI"); + } else if (((boolean)globalarray_1[ivar10])) { + setWidgetRGB(new Color(255, 255, 0)); + setScriptCallOnMouseExit(1949, new WidgetPointer(-32768,3), -2147483643, 16776960, new WidgetPointer(ivar9), "IiiI"); + } else { + setWidgetRGB(new Color(0, 255, 0)); + setScriptCallOnMouseExit(1949, new WidgetPointer(-32768,3), -2147483643, 65280, new WidgetPointer(ivar9), "IiiI"); + } + ivar24 = add(ivar24, getWidgetActualHeight()); + ivar13 = add(ivar13, 1); + if ((((boolean)cs2method_3408(105, 105, ivar16, ivar21)) && (stringMethod4107(getOtherCommonData(globalint_699, 857), "") != 0)) && setWidgetRegister(new WidgetPointer(ivar7), add(add(globalint_273, ivar23), 1))) { + setWidgetText(getOtherCommonData(globalint_699, 857)); + } + ivar25 = add(ivar25, 1); + } + ivar14 = 1; + } + ivar10 = add(ivar10, 1); + } + if (ivar13 != 0) { + ivar24 = add(ivar24, 10); + } else { + if (setWidgetRegister(new WidgetPointer(ivar7), add(add(globalint_273, ivar23), 1))) { + setWidgetText(""); + setWidgetHidden(1); + } + ivar24 = subtract(ivar24, 20); + } + ivar10 = 0; + ivar11 = 0; + if (((boolean)arg2)) { + ivar23 = add(ivar23, 1); + } else { + ivar23 = subtract(ivar23, 1); + } + } + svar1 = ""; + if (((boolean)arg0)) { + if (ivar25 == globalint_272) { + svar1 = "Showing all " + intToStr(globalint_272) + " items"; + } else { + svar1 = "Showing " + intToStr(ivar25) + " of " + intToStr(globalint_272) + " items"; + } + if (((boolean)arg2)) { + svar1 = concat(svar1, " (reversed)"); + } + setWidgetText(new WidgetPointer(190,8), svar1); + } + IF (((boolean)globalint_695) || (ivar20 != add(ivar24, 5))) + GOTO flow_102 + IF (((boolean)arg2)) + GOTO flow_99 + GOTO flow_100 + flow_99: + IF (((boolean)globalint_694)) + GOTO flow_102 + flow_100: + IF (((boolean)arg2) && ((boolean)globalint_694)) + GOTO flow_102 + GOTO flow_103 + flow_102: + setWidgetScrollMax(getWidgetActualWidth(new WidgetPointer(ivar7)), add(ivar24, 5), new WidgetPointer(ivar7)); + ivar20 = ivar24; + cs2method2100(0, 0, new WidgetPointer(ivar7)); + script_31(ivar8, ivar7, 792, 789, 790, 791, 773, 788); + break; + flow_103: + cs2method2100(0, ivar19, new WidgetPointer(ivar7)); + } while (false); + if ((((arg1 == -1) || (arg2 == -1)) || (arg3 == -1)) || (arg4 == -1)) { + return; + } + globalarray_0 = new int[add(globalint_273, 1)]; + globalarray_1 = new int[add(globalint_273, 1)]; + ivar5 = cs2method_3408(105, 74, 169, arg0); + if (ivar5 == -1) { + return; + } + ivar6 = getOtherCommonData(ivar5, 61); + ivar7 = getOtherCommonData(ivar5, 152); + ivar8 = getOtherCommonData(ivar5, 153); + ivar9 = getOtherCommonData(ivar5, 670); + globalint_698 = script_1432(); + ivar10 = 0; + ivar11 = 0; + ivar12 = 1; + ivar13 = 0; + ivar14 = 1; + ivar15 = cs2method_3408(105, 103, getOtherCommonData(ivar5, 673), arg1); + ivar16 = cs2method_3408(105, 103, getOtherCommonData(ivar5, 676), arg1); + ivar17 = cs2method_3408(105, 103, getOtherCommonData(ivar5, 675), arg1); + if (ivar17 == -1) { + ivar17 = 223; + } + if (ivar15 == -1) { + return; + } + ivar18 = getCommonDefinitionSize(ivar15); + ivar19 = cs2method2601(new WidgetPointer(ivar7)); + ivar20 = getWidgetScrollMaxV(new WidgetPointer(ivar7)); + ivar21 = 0; + ivar22 = 0; + svar0 = ""; + script_2164(arg0); + while (ivar10 <= globalint_273) { + globalarray_0[ivar10] = ivar10; + ivar10 = add(ivar10, 1); + } + ivar10 = 0; + script_2163(0, ivar6, 0, globalint_273); + switch (arg0) { + while (true) { + case 1: + if (ivar10 <= globalint_273) { + globalarray_0[ivar10] = script_2193(globalarray_0[ivar10]); + ivar10 = add(ivar10, 1); + } + } + flow_14: + GOTO flow_17 + while (true) { + case 3: + if (ivar10 <= globalint_273) { + globalarray_0[ivar10] = 0; + ivar10 = add(ivar10, 1); + } + } + } + if (((boolean)arg0)) { + globalint_692 = arg3; + globalint_1103 = arg4; + globalint_694 = arg2; + if (((boolean)globalint_692)) { + setWidgetSprite(699, new WidgetPointer(190,10)); + } else { + setWidgetSprite(697, new WidgetPointer(190,10)); + } + if (((boolean)globalint_1103)) { + setWidgetSprite(699, new WidgetPointer(190,12)); + } else { + setWidgetSprite(697, new WidgetPointer(190,12)); + } + } + globalint_695 = 0; + return; +} diff --git a/dumps/scripts/2163.cs2 b/dumps/scripts/2163.cs2 new file mode 100644 index 0000000..24d7006 --- /dev/null +++ b/dumps/scripts/2163.cs2 @@ -0,0 +1,44 @@ +void script_2163(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + string svar0; + string svar1; + ivar4 = divide(add(arg2, arg3), 2); + ivar5 = globalarray_0[ivar4]; + globalarray_0[ivar4] = globalarray_0[arg3]; + globalarray_0[arg3] = ivar5; + ivar6 = arg2; + ivar7 = arg2; + ivar8 = -1; + svar0 = "null"; + svar1 = "null"; + svar1 = lower(getOtherCommonData(cs2method_3408(105, 74, arg1, ivar5), 846)); + if (((boolean)stringMethod4107(svar1, ""))) { + svar1 = lower(getOtherCommonData(cs2method_3408(105, 74, arg1, ivar5), 845)); + } + while (ivar7 < arg3) { + svar0 = lower(getOtherCommonData(cs2method_3408(105, 74, arg1, globalarray_0[ivar7]), 846)); + if (((boolean)stringMethod4107(svar0, ""))) { + svar0 = lower(getOtherCommonData(cs2method_3408(105, 74, arg1, globalarray_0[ivar7]), 845)); + } + if (stringMethod4107(svar0, svar1) < bitAnd(ivar7, 1)) { + ivar8 = globalarray_0[ivar7]; + globalarray_0[ivar7] = globalarray_0[ivar6]; + globalarray_0[ivar6] = ivar8; + ivar6 = add(ivar6, 1); + } + ivar7 = add(ivar7, 1); + } + globalarray_0[arg3] = globalarray_0[ivar6]; + globalarray_0[ivar6] = ivar5; + if (arg2 < subtract(ivar6, 1)) { + script_2163(0, arg1, arg2, subtract(ivar6, 1)); + } + if (add(ivar6, 1) < arg3) { + script_2163(0, arg1, add(ivar6, 1), arg3); + } + return; +} diff --git a/dumps/scripts/2164.cs2 b/dumps/scripts/2164.cs2 new file mode 100644 index 0000000..45ac051 --- /dev/null +++ b/dumps/scripts/2164.cs2 @@ -0,0 +1,18 @@ +void script_2164(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + ivar1 = cs2method_3408(105, 74, 169, arg0); + ivar2 = getOtherCommonData(ivar1, 61); + ivar3 = getOtherCommonData(ivar1, 152); + ivar4 = 0; + while (ivar4 < add(globalint_273, 10)) { + if (setWidgetRegister(new WidgetPointer(ivar3), ivar4)) { + setWidgetPosition(0, 0, 0, 0); + setWidgetHidden(1); + } + ivar4 = add(ivar4, 1); + } + return; +} diff --git a/dumps/scripts/2165.cs2 b/dumps/scripts/2165.cs2 new file mode 100644 index 0000000..b55ab26 --- /dev/null +++ b/dumps/scripts/2165.cs2 @@ -0,0 +1,6 @@ +void script_2165() { + script_2160(1); + setScriptCallOnConfigChange(2169, 1384, 1, "Y", new WidgetPointer(190,18)); + setScriptCallOnGlobalConfigChange(2169, 695, 1, "Y", new WidgetPointer(190,18)); + return; +} diff --git a/dumps/scripts/2166.cs2 b/dumps/scripts/2166.cs2 new file mode 100644 index 0000000..d449da4 --- /dev/null +++ b/dumps/scripts/2166.cs2 @@ -0,0 +1,4 @@ +void script_2166() { + setWidgetText(new WidgetPointer(190,2), "Quest Points: " + intToStr(standart_config_101) + " / " + intToStr(standart_config_904)); + return; +} diff --git a/dumps/scripts/2167.cs2 b/dumps/scripts/2167.cs2 new file mode 100644 index 0000000..03ec3a7 --- /dev/null +++ b/dumps/scripts/2167.cs2 @@ -0,0 +1,4 @@ +void script_2167(int arg0,int arg1) { + script_2161(1, arg0, arg1); + return; +} diff --git a/dumps/scripts/2168.cs2 b/dumps/scripts/2168.cs2 new file mode 100644 index 0000000..281d502 --- /dev/null +++ b/dumps/scripts/2168.cs2 @@ -0,0 +1,10 @@ +void script_2168() { + if (isMember()) { + messageType0("More advanced sorting options are available on a members' world."); + } else { + if (standart_config_281 < 1000) { + messageType0("More advanced sorting options are available after the Tutorial."); + } + } + return; +} diff --git a/dumps/scripts/2169.cs2 b/dumps/scripts/2169.cs2 new file mode 100644 index 0000000..f5febdb --- /dev/null +++ b/dumps/scripts/2169.cs2 @@ -0,0 +1,18 @@ +void script_2169() { + int ivar0; + if (isMember()) { + globalint_693 = bitconfig_4536; + } else { + globalint_693 = 0; + } + globalint_694 = bitconfig_4538; + globalint_692 = bitconfig_4537; + script_2162(1, globalint_693, globalint_694, globalint_692, globalint_1103); + ivar0 = 0; + if (isMember() && (standart_config_281 >= 1000)) { + script_944(1, globalint_693, 2, 12451856, 12451854, 12451855, -1, 897, 788, 788, 1040, 16777215, 16776960, 494, 792, 789, 790, 791, 773, 788); + } else { + script_1355(12451856, 12451854, 12451855, -1, 897, 16776960, 494, "Free/Members"); + } + return; +} diff --git a/dumps/scripts/217.cs2 b/dumps/scripts/217.cs2 new file mode 100644 index 0000000..ca13800 --- /dev/null +++ b/dumps/scripts/217.cs2 @@ -0,0 +1,10 @@ +void script_217() { + setWidgetText(new WidgetPointer(594,106), "Reporting: " + globalstring_24); + setWidgetText(new WidgetPointer(594,71), globalstring_24); + if (stringMethod4107(globalstring_24, "") != 0) { + setWidgetIsHidden(true, new WidgetPointer(594,81)); + } else { + setWidgetIsHidden(false, new WidgetPointer(594,81)); + } + return; +} diff --git a/dumps/scripts/2170.cs2 b/dumps/scripts/2170.cs2 new file mode 100644 index 0000000..1a1e8f1 --- /dev/null +++ b/dumps/scripts/2170.cs2 @@ -0,0 +1,4 @@ +void script_2170() { + script_2172(0); + return; +} diff --git a/dumps/scripts/2171.cs2 b/dumps/scripts/2171.cs2 new file mode 100644 index 0000000..6f99d30 --- /dev/null +++ b/dumps/scripts/2171.cs2 @@ -0,0 +1,6 @@ +void script_2171(int arg0) { + if (((boolean)arg0)) { + script_2172(0); + } + return; +} diff --git a/dumps/scripts/2172.cs2 b/dumps/scripts/2172.cs2 new file mode 100644 index 0000000..850dcc1 --- /dev/null +++ b/dumps/scripts/2172.cs2 @@ -0,0 +1,20 @@ +void script_2172(int arg0) { + int ivar1; + int ivar2; + ivar1 = globalint_692; + ivar2 = globalint_1103; + script_41(12451860); + if (((boolean)arg0)) { + if (((boolean)globalint_692)) { + ivar1 = 0; + } else { + ivar1 = 1; + } + } else if (((boolean)globalint_1103)) { + ivar2 = 0; + } else { + ivar2 = 1; + } + script_2162(1, globalint_693, globalint_694, ivar1, ivar2); + return; +} diff --git a/dumps/scripts/2173.cs2 b/dumps/scripts/2173.cs2 new file mode 100644 index 0000000..41c67c8 --- /dev/null +++ b/dumps/scripts/2173.cs2 @@ -0,0 +1,4 @@ +void script_2173() { + script_2174(); + return; +} diff --git a/dumps/scripts/2174.cs2 b/dumps/scripts/2174.cs2 new file mode 100644 index 0000000..996b678 --- /dev/null +++ b/dumps/scripts/2174.cs2 @@ -0,0 +1,18 @@ +void script_2174() { + int ivar0; + int ivar1; + int ivar2; + ivar0 = 0; + ivar1 = 141; + ivar2 = getCommonDefinitionSize(964); + while (ivar0 < ivar2) { + if (((boolean)script_2189(ivar0))) { + ivar1 = 255; + } else { + ivar1 = 141; + } + cs2method2103(ivar1, cs2method_3408(105, 73, 964, ivar0)); + ivar0 = add(ivar0, 1); + } + return; +} diff --git a/dumps/scripts/2175.cs2 b/dumps/scripts/2175.cs2 new file mode 100644 index 0000000..469031f --- /dev/null +++ b/dumps/scripts/2175.cs2 @@ -0,0 +1,5 @@ +void script_2175() { + script_2174(); + script_2186(); + return; +} diff --git a/dumps/scripts/2176.cs2 b/dumps/scripts/2176.cs2 new file mode 100644 index 0000000..3105f64 --- /dev/null +++ b/dumps/scripts/2176.cs2 @@ -0,0 +1,23 @@ +void script_2176(int arg0) { + string svar0; + svar0 = ""; + switch (arg0) { + case 12451850: + case 12451849: + if (((boolean)globalint_692)) { + svar0 = "Click to hide the quests you cannot start." + "
" + "
" + "Some recommended stats and abilities (such as combat levels) are left for you to decide."; + } else { + svar0 = "Click to show all quests regardless of requirements."; + } + break; + case 12451851: + case 12451852: + if (((boolean)globalint_692)) { + svar0 = "Click to hide the quests you have completed."; + } else { + svar0 = "Click to show all quests regardless of completion status."; + } + } + script_569(12451859, -1, 12451860, 25, 450, svar0); + return; +} diff --git a/dumps/scripts/2177.cs2 b/dumps/scripts/2177.cs2 new file mode 100644 index 0000000..1893db8 --- /dev/null +++ b/dumps/scripts/2177.cs2 @@ -0,0 +1,6 @@ +void script_2177(int arg0) { + if (setWidgetRegister(new WidgetPointer(190,18), arg0)) { + setScriptCallOnGameloop(2178, arg0, getWidgetText(), "is"); + } + return; +} diff --git a/dumps/scripts/2178.cs2 b/dumps/scripts/2178.cs2 new file mode 100644 index 0000000..9bc28f3 --- /dev/null +++ b/dumps/scripts/2178.cs2 @@ -0,0 +1,13 @@ +void script_2178(int arg0,string arg1) { + if (setWidgetRegister(new WidgetPointer(190,18), arg0)) { + if (mod(getClientCycle(), 20) > 9) { + setWidgetText(""); + if (mod(getClientCycle(), 20) == 10) { + playSoundEffect(5009, 1, 0); + } + } else { + setWidgetText(arg1); + } + } + return; +} diff --git a/dumps/scripts/2179.cs2 b/dumps/scripts/2179.cs2 new file mode 100644 index 0000000..822cd12 --- /dev/null +++ b/dumps/scripts/2179.cs2 @@ -0,0 +1,4 @@ +void script_2179(int arg0) { + script_2180(arg0); + return; +} diff --git a/dumps/scripts/218.cs2 b/dumps/scripts/218.cs2 new file mode 100644 index 0000000..160c4a3 --- /dev/null +++ b/dumps/scripts/218.cs2 @@ -0,0 +1,4 @@ +void script_218() { + script_216(); + return; +} diff --git a/dumps/scripts/2180.cs2 b/dumps/scripts/2180.cs2 new file mode 100644 index 0000000..3ae3655 --- /dev/null +++ b/dumps/scripts/2180.cs2 @@ -0,0 +1,9 @@ +void script_2180(int arg0) { + int ivar1; + ivar1 = cs2method_3408(105, 74, 2252, arg0); + if (setWidgetRegister(new WidgetPointer(190,18), arg0)) { + setWidgetText(getOtherCommonData(ivar1, 845)); + setScriptCallOnGameloop(-1, ""); + } + return; +} diff --git a/dumps/scripts/2181.cs2 b/dumps/scripts/2181.cs2 new file mode 100644 index 0000000..a2bd2c5 --- /dev/null +++ b/dumps/scripts/2181.cs2 @@ -0,0 +1,9 @@ +void script_2181() { + int ivar0; + ivar0 = 0; + while (ivar0 <= globalint_273) { + script_2180(ivar0); + ivar0 = add(ivar0, 1); + } + return; +} diff --git a/dumps/scripts/2182.cs2 b/dumps/scripts/2182.cs2 new file mode 100644 index 0000000..9552f30 --- /dev/null +++ b/dumps/scripts/2182.cs2 @@ -0,0 +1,5 @@ +void script_2182(int arg0,int arg1,int arg2) { + cs2method2100(0, 0, new WidgetPointer(arg0)); + script_2184(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/2183.cs2 b/dumps/scripts/2183.cs2 new file mode 100644 index 0000000..d6af64d --- /dev/null +++ b/dumps/scripts/2183.cs2 @@ -0,0 +1,4 @@ +void script_2183(int arg0,int arg1,int arg2) { + script_2184(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/2184.cs2 b/dumps/scripts/2184.cs2 new file mode 100644 index 0000000..fdbbb84 --- /dev/null +++ b/dumps/scripts/2184.cs2 @@ -0,0 +1,89 @@ +void script_2184(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + deleteAllExtraChilds(new WidgetPointer(arg0)); + ivar3 = divide(subtract(getWidgetActualWidth(new WidgetPointer(arg0)), multiply(5, 36)), 6); + ivar4 = 0; + ivar5 = -1; + ivar6 = 0; + ivar7 = 0; + ivar8 = 0; + if (getContainerFreeSlots(90) < getItemContainerLength(90)) { + while (ivar4 < getItemContainerLength(90)) { + ivar6 = getItemAmtInSlot(90, ivar4); + createExtraChild(new WidgetPointer(arg0), 5, multiply(ivar4, 2)); + createExtraChild(new WidgetPointer(arg0), 4, add(multiply(ivar4, 2), 1)); + if (ivar6 > 0) { + ivar5 = getItemIdInSlot(90, ivar4); + setWidgetSize(36, 32, 0, 0); + ivar8 = add(multiply(divide(ivar4, 5), add(32, 40)), 2); + setWidgetPosition(add(multiply(mod(ivar4, 5), add(36, ivar3)), ivar3), ivar8, 0, 0); + setWidgetHidden(0); + setItemOnWidgetMethod1200(ivar5, ivar6); + setWidgetShadowColor(new Color(51, 51, 51)); + setWidgetBorderThickness(1); + setWidgetContextMenuOption(1, "Remove-1"); + setWidgetContextMenuOption(2, "Remove-5"); + setWidgetContextMenuOption(3, "Remove-10"); + setWidgetContextMenuOption(4, "Remove-All"); + setWidgetContextMenuOption(5, "Remove-X"); + setWidgetContextMenuOption(10, "Examine"); + cs2method1305("" + getItemName(ivar5)); + setWidgetSize(subtract(add(36, ivar3), 6), 40, 0, 0); + setWidgetPosition(add(add(multiply(mod(ivar4, 5), add(36, ivar3)), divide(ivar3, 2)), 3), add(ivar8, 32), 0, 0); + setWidgetHidden(0); + setWidgetTextAlignment(1, 0, 0); + setWidgetFont(494); + setWidgetRGB(new Color(255, 255, 255)); + setWidgetUnknownBoolean(true); + ivar7 = script_2185(ivar4); + if (ivar6 > 1) { + setWidgetText(formatNumber(ivar6, 1) + " x " + formatNumber(ivar7, 1) + "
" + "= " + formatNumber(multiply(ivar6, ivar7), 1)); + } else { + setWidgetText(formatNumber(ivar7, 1)); + } + } else { + setWidgetSize(0, 0, 0, 0); + setWidgetPosition(0, 0, 0, 0); + setWidgetHidden(1); + setWidgetSize(0, 0, 0, 0); + setWidgetPosition(0, 0, 0, 0); + setWidgetHidden(1); + } + ivar4 = add(ivar4, 1); + } + } else { + createExtraChild(new WidgetPointer(arg0), 4, 0); + setWidgetSize(0, getWidgetActualHeight(new WidgetPointer(arg0)), 1, 0); + setWidgetPosition(0, 0, 1, 0); + setWidgetRGB(new Color(255, 255, 255)); + setWidgetUnknownBoolean(true); + setWidgetTextAlignment(1, 1, 0); + setWidgetFont(495); + setWidgetText("Click on items in your inventory to check their values."); + } + ivar8 = add(add(ivar8, 32), 40); + if (ivar8 > getWidgetActualHeight(new WidgetPointer(arg0))) { + setWidgetScrollMax(0, ivar8, new WidgetPointer(arg0)); + setWidgetPosition(-8, getWidgetActualY(new WidgetPointer(arg0)), 1, 0, new WidgetPointer(arg0)); + script_31(arg1, arg0, 792, 789, 790, 791, 773, 788); + if (setWidgetRegister(new WidgetPointer(arg1), 1)) { + script_37(arg1, arg0, cs2method2601(new WidgetPointer(arg0)), 1); + } + } else { + setWidgetScrollMax(0, 0, new WidgetPointer(arg0)); + cs2method2100(0, 0, new WidgetPointer(arg0)); + deleteAllExtraChilds(new WidgetPointer(arg1)); + setWidgetPosition(0, getWidgetActualY(new WidgetPointer(arg0)), 1, 0, new WidgetPointer(arg0)); + } + if (globalint_728 < 0) { + setWidgetText(new WidgetPointer(arg2), "Total value:" + "
" + "---"); + } else { + setWidgetText(new WidgetPointer(arg2), "Total value:" + "
" + formatNumber(globalint_728, 1)); + } + return; +} diff --git a/dumps/scripts/2185.cs2 b/dumps/scripts/2185.cs2 new file mode 100644 index 0000000..c77a5b4 --- /dev/null +++ b/dumps/scripts/2185.cs2 @@ -0,0 +1,61 @@ +int script_2185(int arg0) { + switch (arg0) { + case 0: + return globalint_700; + case 1: + return globalint_701; + case 2: + return globalint_702; + case 3: + return globalint_703; + case 4: + return globalint_704; + case 5: + return globalint_705; + case 6: + return globalint_706; + case 7: + return globalint_707; + case 8: + return globalint_708; + case 9: + return globalint_709; + case 10: + return globalint_710; + case 11: + return globalint_711; + case 12: + return globalint_712; + case 13: + return globalint_713; + case 14: + return globalint_714; + case 15: + return globalint_715; + case 16: + return globalint_716; + case 17: + return globalint_717; + case 18: + return globalint_718; + case 19: + return globalint_719; + case 20: + return globalint_720; + case 21: + return globalint_721; + case 22: + return globalint_722; + case 23: + return globalint_723; + case 24: + return globalint_724; + case 25: + return globalint_725; + case 26: + return globalint_726; + case 27: + return globalint_727; + } + return 0; +} diff --git a/dumps/scripts/2186.cs2 b/dumps/scripts/2186.cs2 new file mode 100644 index 0000000..4990073 --- /dev/null +++ b/dumps/scripts/2186.cs2 @@ -0,0 +1,57 @@ +void script_2186() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + ivar0 = 60293120; + deleteAllExtraChilds(new WidgetPointer(ivar0)); + ivar1 = 0; + ivar2 = 0; + ivar1 = divide(subtract(getWidgetActualWidth(new WidgetPointer(ivar0)), multiply(36, 4)), 3); + ivar2 = divide(subtract(getWidgetActualHeight(new WidgetPointer(ivar0)), multiply(32, 7)), 6); + deleteAllExtraChilds(new WidgetPointer(924,35)); + ivar3 = getCommonDefinitionSize(962); + ivar4 = 0; + ivar5 = 0; + ivar6 = 0; + ivar7 = 0; + ivar8 = -1; + ivar9 = -1; + while (ivar4 < ivar3) { + if (setWidgetRegister(cs2method_3408(105, 73, 962, ivar4))) { + ivar5 = getWidgetActualX(); + ivar6 = getWidgetActualY(); + ivar8 = cs2method_3408(105, 103, 963, ivar4); + ivar7 = script_2187(ivar4); + createExtraChild(new WidgetPointer(924,35), 5, ivar4); + setWidgetPosition(add(ivar5, 0), add(ivar6, 2), 0, 0); + setWidgetSize(36, 32, 0, 0); + setWidgetBorderThickness(1); + if (ivar7 != 0) { + ivar9 = cs2method_3408(105, 79, ivar8, ivar7); + cs2method1305(getItemName(ivar9)); + setWidgetContextMenuOption(1, "Withdraw-1"); + if (ivar8 == 958) { + setWidgetContextMenuOption(2, "Withdraw-5"); + setWidgetContextMenuOption(3, "Withdraw-10"); + setWidgetContextMenuOption(4, "Withdraw-All"); + setWidgetContextMenuOption(5, "Withdraw-X"); + setItemOnWidgetMethod1200(ivar9, script_2188(ivar4)); + } else { + setItemOnWidgetMethod1205(ivar9, 1); + } + } + } else { + messageType0("Nothing happens, as if something is wrong."); + return; + } + ivar4 = add(ivar4, 1); + } + return; +} diff --git a/dumps/scripts/2187.cs2 b/dumps/scripts/2187.cs2 new file mode 100644 index 0000000..b39dcac --- /dev/null +++ b/dumps/scripts/2187.cs2 @@ -0,0 +1,25 @@ +int script_2187(int arg0) { + switch (arg0) { + case 0: + return bitconfig_7301; + case 1: + return bitconfig_7302; + case 2: + return bitconfig_7303; + case 3: + return bitconfig_7304; + case 4: + return bitconfig_7305; + case 5: + return bitconfig_7298; + case 6: + return bitconfig_7299; + case 7: + return bitconfig_7300; + case 8: + return bitconfig_7296; + case 9: + return bitconfig_7297; + } + return -1; +} diff --git a/dumps/scripts/2188.cs2 b/dumps/scripts/2188.cs2 new file mode 100644 index 0000000..3d70787 --- /dev/null +++ b/dumps/scripts/2188.cs2 @@ -0,0 +1,11 @@ +int script_2188(int arg0) { + switch (arg0) { + case 5: + return bitconfig_7307; + case 6: + return bitconfig_7308; + case 7: + return bitconfig_7309; + } + return 1; +} diff --git a/dumps/scripts/2189.cs2 b/dumps/scripts/2189.cs2 new file mode 100644 index 0000000..cb1ceae --- /dev/null +++ b/dumps/scripts/2189.cs2 @@ -0,0 +1,70 @@ +int script_2189(int arg0) { + switch (bitconfig_7306) { + flow_1: + case 1: + switch (arg0) { + case 0: + case 5: + return 1; + } + break; + case 2: + switch (arg0) { + case 0: + case 5: + case 1: + return 1; + } + break; + case 3: + switch (arg0) { + case 0: + case 1: + case 2: + case 5: + case 6: + return 1; + } + break; + case 4: + switch (arg0) { + case 0: + case 1: + case 2: + case 3: + case 5: + case 6: + case 7: + case 8: + return 1; + } + break; + case 5: + SWITCH (arg0) { + case 0: + GOTO flow_14 + case 1: + GOTO flow_14 + case 2: + GOTO flow_14 + case 3: + GOTO flow_14 + case 4: + GOTO flow_14 + case 5: + GOTO flow_14 + case 6: + GOTO flow_14 + case 7: + GOTO flow_14 + case 8: + GOTO flow_14 + case 9: + GOTO flow_14 + } + break; + flow_14: + return 1; + } + return 0; +} diff --git a/dumps/scripts/219.cs2 b/dumps/scripts/219.cs2 new file mode 100644 index 0000000..c7b95b4 --- /dev/null +++ b/dumps/scripts/219.cs2 @@ -0,0 +1,4 @@ +void script_219() { + script_220(); + return; +} diff --git a/dumps/scripts/2190.cs2 b/dumps/scripts/2190.cs2 new file mode 100644 index 0000000..7e8d26d --- /dev/null +++ b/dumps/scripts/2190.cs2 @@ -0,0 +1,91 @@ +void script_2190(int arg0,int arg1,int arg2,string arg3,string arg4,string arg5,string arg6) { + int ivar3; + int ivar4; + if (((arg1 != -1) && (arg1 != 6)) && (strLength(arg3) <= 0)) { + return; + } + script_3018(); + setWidgetText(new WidgetPointer(906,149), arg3); + if (stringMethod4107(arg4, "") != 0) { + if ((arg1 != -1) && (arg1 != 6)) { + globalstring_277 = arg4; + } else { + globalstring_277 = arg4; + } + if (((boolean)arg0)) { + setWidgetText(new WidgetPointer(906,151), replaceLtGt(globalstring_277)); + } else { + setWidgetText(new WidgetPointer(906,151), globalstring_277); + } + } + if ((arg1 == 6) || (arg1 == 10)) { + setWidgetText(new WidgetPointer(906,159), "Yes"); + setWidgetContextMenuOption(1, new WidgetPointer(906,159), "Yes"); + setWidgetText(new WidgetPointer(906,161), "No"); + setWidgetContextMenuOption(1, new WidgetPointer(906,161), "No"); + } else { + if (((boolean)arg1)) { + setWidgetSize(386, 136, 0, 0, new WidgetPointer(906,147)); + setWidgetSize(0, 12, 1, 0, new WidgetPointer(906,151)); + globalint_1650 = 1; + } + } + if (((boolean)arg2)) { + setWidgetSize(0, 0, 1, 1, new WidgetPointer(906,155)); + setWidgetSize(0, 0, 1, 1, new WidgetPointer(906,159)); + setWidgetIsHidden(true, new WidgetPointer(906,160)); + setWidgetIsHidden(true, new WidgetPointer(906,161)); + } + setWidgetIsHidden(false, new WidgetPointer(906,41)); + ivar3 = 0; + switch (arg1) { + case 0: + ivar3 = 0; + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 7: + case 9: + ivar3 = 2; + } + if (isWidgetHidden(cs2method_3408(105, 73, 941, 5))) { + script_3161(0); + } else { + if (isWidgetHidden(cs2method_3408(105, 73, 941, 3))) { + script_4556(0); + } + } + setScriptCallOnKeyPress(3022, -2147483640, false, new WidgetPointer(-32768,3), ivar3, arg1, arg5, "izIiis", new WidgetPointer(906,151)); + setScriptCallOnClickContextMenu(3019, arg1, arg5, "is", new WidgetPointer(906,155)); + ivar4 = 0; + if ((arg1 != -1) && (arg1 != 6)) { + globalint_1097 = strLength(globalstring_277); + setScriptCallOnMousePressed(1874, -2147483647, new WidgetPointer(906,151), new WidgetPointer(906,152), "iII", new WidgetPointer(906,151)); + script_1875(59375767, 59375768, globalstring_277); + setWidgetIsHidden(true, new WidgetPointer(906,152)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(906,147)), 136, 0, 0, new WidgetPointer(906,147)); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(906,153)); + setScriptCallOnMouseEntered(-1, "", new WidgetPointer(906,153)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(906,153)); + setWidgetIsHidden(true, new WidgetPointer(906,153)); + } else { + globalint_1097 = 0; + setWidgetIsHidden(true, new WidgetPointer(906,152)); + if ((strLength(arg6) > 0) && (strLength(globalstring_277) > 0)) { + ivar4 = max(44, multiply(getLineCount(getWidgetActualWidth(new WidgetPointer(906,150)), 494, globalstring_277), 13)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(906,150)), ivar4, 0, 0, new WidgetPointer(906,150)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(906,147)), add(ivar4, 95), 0, 0, new WidgetPointer(906,147)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(906,153)), add(add(getWidgetActualY(new WidgetPointer(906,150)), ivar4), 5), 0, 0, new WidgetPointer(906,153)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(906,153)), 13, 0, 0, new WidgetPointer(906,153)); + setWidgetText(new WidgetPointer(906,153), "" + arg6 + ""); + setWidgetRGB(new Color(44, 111, 248), new WidgetPointer(906,153)); + setScriptCallOnMouseEntered(1333, new WidgetPointer(906,153), arg6, 1, "Is1", new WidgetPointer(906,153)); + setScriptCallOnMouseExit(1333, new WidgetPointer(906,153), arg6, 0, "Is1", new WidgetPointer(906,153)); + setWidgetIsHidden(false, new WidgetPointer(906,153)); + } + } + return; +} diff --git a/dumps/scripts/2191.cs2 b/dumps/scripts/2191.cs2 new file mode 100644 index 0000000..f89f432 --- /dev/null +++ b/dumps/scripts/2191.cs2 @@ -0,0 +1,22 @@ +void script_2191(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11) { + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + ivar12 = getMaxLineWidth(512, 494, getWidgetText(new WidgetPointer(arg1))); + ivar13 = getMaxLineWidth(512, 494, getWidgetText(new WidgetPointer(arg2))); + ivar14 = getMaxLineWidth(512, 494, getWidgetText(new WidgetPointer(arg3))); + ivar15 = getMaxLineWidth(512, 494, getWidgetText(new WidgetPointer(arg4))); + ivar16 = getMaxLineWidth(512, 494, getWidgetText(new WidgetPointer(arg5))); + ivar17 = getMaxLineWidth(512, 494, getWidgetText(new WidgetPointer(arg10))); + script_2337(arg0); + setScriptCallOnGameloop(2336, new WidgetPointer(arg0), getDisplayMode(), "Ii", new WidgetPointer(arg0)); + script_2335(arg0, arg2, arg3, arg4, arg5, ivar12, ivar13, ivar14, ivar15, ivar16, arg6, arg7, arg8, arg9, arg10, arg11, ivar17); + setScriptCallOnConfigChange(2333, new WidgetPointer(arg0), new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), ivar12, ivar13, ivar14, ivar15, ivar16, new WidgetPointer(arg6), new WidgetPointer(arg7), new WidgetPointer(arg8), new WidgetPointer(arg9), new WidgetPointer(arg10), new WidgetPointer(arg11), ivar17, 1048, 1058, 2040, 3, "IIIIIiiiiiIIIIIIiY", new WidgetPointer(arg0)); + setWidgetSize(100, 75, 0, 0, new WidgetPointer(601,0)); + cs2method2103(255, new WidgetPointer(601,1)); + globalint_1435 = 255; + return; +} diff --git a/dumps/scripts/2192.cs2 b/dumps/scripts/2192.cs2 new file mode 100644 index 0000000..b60cc6e --- /dev/null +++ b/dumps/scripts/2192.cs2 @@ -0,0 +1,10 @@ +void script_2192(int arg0,int arg1) { + if (((boolean)arg0)) { + setScriptCallOnMousePressed(2355, 1, arg1, "1i", new WidgetPointer(916,21)); + setWidgetHFlip(0, new WidgetPointer(916,22)); + } else { + setScriptCallOnMousePressed(2355, 0, arg1, "1i", new WidgetPointer(916,21)); + setWidgetHFlip(1, new WidgetPointer(916,22)); + } + return; +} diff --git a/dumps/scripts/2193.cs2 b/dumps/scripts/2193.cs2 new file mode 100644 index 0000000..522beff --- /dev/null +++ b/dumps/scripts/2193.cs2 @@ -0,0 +1,379 @@ +int script_2193(int arg0) { + switch (arg0) { + case 147: + return script_2157(standart_config_281, 1000); + case 159: + return script_2157(standart_config_130, 4); + case 1: + return script_2157(standart_config_29, 2); + case 2: + return script_2157(bitconfig_2561, 3); + case 3: + return script_2157(standart_config_31, 100); + case 4: + return script_2157(standart_config_176, 10); + case 5: + return script_2157(standart_config_32, 3); + case 6: + return script_2157(bitconfig_2378, 6); + case 7: + return script_2157(standart_config_160, 2); + case 8: + return script_2157(standart_config_122, 7); + case 9: + return script_2157(standart_config_71, 4); + case 10: + return script_2157(standart_config_273, 110); + case 11: + return script_2157(standart_config_107, 5); + case 13: + return script_2157(standart_config_63, 6); + case 15: + return script_2159(standart_config_145, 7, standart_config_146, 4); + case 16: + return script_2157(bitconfig_6914, 3); + case 18: + return script_2157(bitconfig_3185, 240); + case 19: + return script_2157(bitconfig_299, 110); + case 20: + return script_2157(standart_config_293, 65); + case 21: + return script_2157(standart_config_68, 16); + case 22: + return script_2157(standart_config_655, 140); + case 23: + return script_2157(standart_config_10, 8); + case 24: + return script_2157(bitconfig_3274, 130); + case 25: + return script_2157(bitconfig_487, 14); + case 26: + if (standart_config_399 > 6) { + return 2; + } + if (((boolean)standart_config_399) && ((boolean)bitconfig_203)) { + return 0; + } + return 1; + case 27: + return script_2157(bitconfig_2573, 320); + case 28: + return script_2157(bitconfig_2258, 13); + case 29: + return script_2157(standart_config_314, 80); + case 30: + return script_2157(bitconfig_358, 15); + case 31: + return script_2157(bitconfig_1465, 80); + case 32: + return script_2157(standart_config_131, 9); + case 33: + return script_2157(standart_config_80, 4); + case 34: + return script_2157(standart_config_0, 11); + case 35: + return script_2157(standart_config_335, 110); + case 36: + return script_2157(bitconfig_2780, 40); + case 37: + if (isBitFlagged(standart_config_299, 20)) { + return 2; + } + if (isBitFlagged(standart_config_299, 1)) { + return 0; + } + return 1; + case 38: + return script_2157(bitconfig_2639, 11); + case 39: + return script_2157(bitconfig_1560, 70); + case 40: + return script_2157(bitconfig_2866, 200); + case 41: + return script_2157(bitconfig_2497, 60); + case 42: + return script_2157(bitconfig_1803, 90); + case 43: + return script_2157(bitconfig_2326, 90); + case 44: + return script_2157(standart_config_148, 11); + case 45: + return script_2157(bitconfig_334, 28); + case 46: + return script_2157(standart_config_17, 14); + case 47: + return script_2157(standart_config_11, 5); + case 48: + return script_2157(bitconfig_822, 140); + case 49: + return script_2157(standart_config_347, 10); + case 50: + return script_2157(standart_config_65, 10); + case 51: + return script_2157(bitconfig_961, 60); + case 52: + return script_2157(standart_config_180, 6); + case 53: + return script_2157(bitconfig_217, 8); + case 54: + return script_2157(bitconfig_571, 50); + case 55: + return script_2157(bitconfig_346, 10); + case 56: + return script_2157(standart_config_150, 160); + case 57: + return script_2157(bitconfig_1527, 160); + case 58: + return script_2157(standart_config_382, 11); + case 59: + return script_2157(standart_config_223, 9); + case 60: + return script_2157(standart_config_188, 15); + case 61: + return script_2157(standart_config_5, 10); + case 62: + return script_2157(bitconfig_34, 10); + case 63: + return script_2157(bitconfig_418, 26); + case 64: + return script_2157(bitconfig_1990, 430); + case 65: + return script_2157(standart_config_387, 105); + case 66: + return script_2157(standart_config_175, 12); + case 67: + return script_2157(standart_config_139, 75); + case 68: + return script_2157(standart_config_147, 6); + case 69: + return script_2157(bitconfig_532, 11); + case 70: + return script_2157(bitconfig_2448, 190); + case 71: + return script_2157(bitconfig_1383, 4); + case 72: + return script_2157(standart_config_14, 7); + case 73: + return script_2158(standart_config_365, 1, 9); + case 74: + return script_2157(standart_config_30, 80); + case 75: + return script_2157(bitconfig_260, 70); + case 76: + return script_2157(standart_config_517, 8); + case 77: + return script_2158(bitconfig_1103, 9, 60); + case 78: + return script_2157(standart_config_192, 2); + case 79: + return script_2157(bitconfig_2790, 320); + case 80: + return script_2157(standart_config_307, 110); + case 81: + return script_2157(standart_config_112, 7); + case 82: + return script_2157(standart_config_416, 280); + case 83: + return script_2157(standart_config_165, 29); + case 84: + return script_2157(standart_config_302, 60); + case 85: + return script_2157(bitconfig_6178, 4); + case 86: + return script_2157(bitconfig_1404, 127); + case 87: + return script_2157(bitconfig_1850, 5); + case 88: + return script_2157(bitconfig_657, 2); + case 89: + return script_2157(standart_config_328, 15); + case 90: + return script_2157(standart_config_402, 6); + case 91: + return script_2157(bitconfig_2140, 30); + case 92: + return script_2157(standart_config_600, 19); + case 93: + return script_2157(standart_config_76, 6); + case 94: + return script_2157(standart_config_159, 12); + case 95: + return script_2157(bitconfig_2610, 14); + case 96: + return script_2157(standart_config_339, 85); + case 97: + return script_2157(bitconfig_1372, 125); + case 98: + return script_2157(standart_config_60, 3); + case 99: + return script_2157(standart_config_116, 15); + case 100: + return script_2157(bitconfig_2011, 13); + case 101: + return script_2157(bitconfig_1444, 60); + case 102: + return script_2157(bitconfig_2098, 200); + case 103: + return script_2158(standart_config_320, 3, 6); + case 104: + return script_2157(bitconfig_1028, 70); + case 105: + return script_2157(bitconfig_451, 2); + case 106: + return script_2157(standart_config_26, 80); + case 107: + return script_2157(standart_config_359, 100); + case 108: + return script_2157(standart_config_197, 30); + case 109: + return script_2157(standart_config_226, 7); + case 110: + return script_2157(standart_config_111, 9); + case 111: + return script_2157(standart_config_200, 5); + case 112: + return script_2157(standart_config_385, 45); + case 113: + return script_2157(standart_config_317, 50); + case 114: + if (standart_config_161 == 10) { + return 2; + } + if (isBitFlagged(standart_config_162, 11)) { + return 0; + } + return 1; + case 115: + return script_2157(bitconfig_1051, 11); + case 116: + return script_2157(standart_config_212, 13); + case 117: + return script_2157(bitconfig_3293, 135); + case 118: + return script_2157(bitconfig_3311, 340); + case 119: + return script_2157(bitconfig_3337, 18); + case 120: + return script_2157(standart_config_980, 130); + case 121: + return script_2157(bitconfig_3523, 150); + case 122: + return script_2157(bitconfig_3534, 80); + case 123: + return script_2157(bitconfig_3550, 11); + case 124: + return script_2157(bitconfig_3618, 28); + case 125: + return script_2157(bitconfig_2783, 60); + case 126: + return script_2157(bitconfig_3888, 90); + case 127: + return script_2157(bitconfig_3954, 200); + case 128: + return script_2157(bitconfig_4055, 65); + case 129: + return script_2157(bitconfig_4105, 18); + case 130: + return script_2157(bitconfig_4230, 700); + case 131: + return script_2157(bitconfig_4302, 110); + case 132: + return script_2158(bitconfig_4321, 10, 200); + case 133: + return script_2157(bitconfig_4396, 60); + case 134: + return script_2157(bitconfig_4505, 100); + case 135: + return script_2157(bitconfig_4569, 500); + case 136: + return script_2157(bitconfig_4684, 150); + case 137: + return script_2157(bitconfig_4700, 63); + case 138: + return script_2157(bitconfig_4764, 250); + case 139: + return script_2157(bitconfig_4797, 100); + case 140: + return script_2157(bitconfig_5032, 80); + case 141: + return script_2157(bitconfig_5075, 20); + case 142: + return script_2157(bitconfig_5133, 90); + case 143: + return script_2157(bitconfig_5331, 35); + case 144: + return script_2157(bitconfig_5387, 250); + case 145: + return script_2157(bitconfig_5491, 910); + case 146: + return script_2157(bitconfig_5761, 30); + case 148: + return script_2157(bitconfig_5733, 60); + case 149: + return script_2158(bitconfig_6001, 3, 45); + case 150: + return script_2158(bitconfig_6048, 10, 250); + case 155: + return script_2157(bitconfig_6112, 60); + case 156: + return script_2157(bitconfig_6289, 240); + case 157: + return script_2157(bitconfig_6775, 90); + case 151: + return script_2158(bitconfig_6180, 2, 140); + case 152: + return script_2157(bitconfig_1938, 110); + case 153: + return script_2157(bitconfig_5448, 50); + case 154: + return script_2158(bitconfig_6307, 2, 5); + case 158: + return script_2158(bitconfig_7826, 10, 180); + case 160: + return script_2157(bitconfig_6471, 90); + case 161: + return script_2157(bitconfig_6553, 46); + case 162: + return script_2157(bitconfig_6962, 12); + case 163: + return script_2158(bitconfig_6883, 3, 147); + case 165: + return script_2157(bitconfig_7050, 35); + case 167: + return script_2157(bitconfig_7793, 30); + case 168: + return script_2157(bitconfig_8045, 150); + case 170: + return script_2157(bitconfig_7238, 60); + case 171: + return script_2157(bitconfig_7958, 90); + case 172: + return script_2157(bitconfig_7871, 5); + case 173: + return script_2158(bitconfig_7451, 2, 63); + case 14: + return script_2157(bitconfig_8704, 90); + case 174: + return script_2157(bitconfig_8248, 40); + case 17: + return script_2157(bitconfig_5730, 100); + case 176: + return script_2157(bitconfig_9829, 400); + case 179: + return script_2158(bitconfig_8605, 10, 315); + case 12: + return script_2157(bitconfig_5332, 120); + case 180: + return script_2157(bitconfig_998, 9); + case 181: + return script_2158(bitconfig_8961, 10, 210); + case 182: + return script_2157(bitconfig_9369, 50); + case 183: + return script_2158(bitconfig_9491, 5, 250); + case 184: + return script_2157(bitconfig_9757, 170); + } + return 0; +} diff --git a/dumps/scripts/2194.cs2 b/dumps/scripts/2194.cs2 new file mode 100644 index 0000000..9283d71 --- /dev/null +++ b/dumps/scripts/2194.cs2 @@ -0,0 +1,89 @@ +int script_2194(int arg0) { + switch (arg0) { + case 79: + if (((boolean)bitconfig_888)) { + return 0; + } + break; + case 144: + if (((boolean)bitconfig_5394)) { + return 0; + } + break; + case 145: + if (bitconfig_4310 < 10) { + return 0; + } + break; + case 35: + if (((boolean)bitconfig_0)) { + return 0; + } + break; + case 120: + if (bitconfig_1895 < 110) { + return 0; + } + break; + case 157: + if (bitconfig_3637 < 125) { + return 0; + } + break; + case 156: + if (script_2656() < 100) { + return 0; + } + break; + case 162: + if (bitconfig_3909 < 8) { + return 0; + } + if (((boolean)bitconfig_5834)) { + return 0; + } + if (((boolean)bitconfig_5830)) { + return 0; + } + break; + case 163: + if (((boolean)bitconfig_5686)) { + return 0; + } + break; + case 168: + if (bitconfig_1910 < 20) { + return 0; + } + break; + case 171: + if (((boolean)bitconfig_7973)) { + return 0; + } + break; + case 174: + if (((boolean)bitconfig_7544)) { + return 0; + } + break; + case 179: + if (script_2656() < 100) { + return 0; + } + if (bitconfig_1914 < 50) { + return 0; + } + if (bitconfig_8494 < 5) { + return 0; + } + break; + case 148: + if (bitconfig_8601 < 6) { + return 0; + } + break; + default: + return 1; + } + return 1; +} diff --git a/dumps/scripts/2195.cs2 b/dumps/scripts/2195.cs2 new file mode 100644 index 0000000..67a3780 --- /dev/null +++ b/dumps/scripts/2195.cs2 @@ -0,0 +1,4 @@ +void script_2195(int arg0,int arg1) { + script_1730(arg0, arg1); + return; +} diff --git a/dumps/scripts/2196.cs2 b/dumps/scripts/2196.cs2 new file mode 100644 index 0000000..690b985 --- /dev/null +++ b/dumps/scripts/2196.cs2 @@ -0,0 +1,4 @@ +void script_2196(int arg0,int arg1,string arg2) { + script_2197(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/2197.cs2 b/dumps/scripts/2197.cs2 new file mode 100644 index 0000000..c7b7c09 --- /dev/null +++ b/dumps/scripts/2197.cs2 @@ -0,0 +1,31 @@ +void script_2197(int arg0,int arg1,string arg2) { + int ivar2; + flow_0: + ivar2 = 0; + IF (arg1 == -1) + GOTO flow_1 + GOTO flow_2 + flow_1: + IF (setWidgetRegister(new WidgetPointer(arg0))) + GOTO flow_3 + flow_2: + IF (setWidgetRegister(new WidgetPointer(arg0), arg1)) + GOTO flow_3 + GOTO flow_10 + flow_3: + if (globalint_198 != 1) { + setScriptCallOnGameloop(-1, ""); + setWidgetText(arg2); + return; + } + if (mod(getClientCycle(), 20) > 9) { + setWidgetText(""); + if (mod(getClientCycle(), 20) == 10) { + playSoundEffect(5009, 1, 0); + } + } else { + setWidgetText(arg2); + } + flow_10: + return; +} diff --git a/dumps/scripts/2198.cs2 b/dumps/scripts/2198.cs2 new file mode 100644 index 0000000..ae7678d --- /dev/null +++ b/dumps/scripts/2198.cs2 @@ -0,0 +1,4 @@ +void script_2198(int arg0,int arg1) { + globalint_198 = 0; + return; +} diff --git a/dumps/scripts/2199.cs2 b/dumps/scripts/2199.cs2 new file mode 100644 index 0000000..36c3ed4 --- /dev/null +++ b/dumps/scripts/2199.cs2 @@ -0,0 +1,16 @@ +void script_2199() { + switch (rndExcl(4)) { + case 0: + globalint_1136 = 61079562; + break; + case 1: + globalint_1136 = 61079563; + break; + case 2: + globalint_1136 = 61079564; + break; + case 3: + globalint_1136 = 61079565; + } + return; +} diff --git a/dumps/scripts/22.cs2 b/dumps/scripts/22.cs2 new file mode 100644 index 0000000..62af927 --- /dev/null +++ b/dumps/scripts/22.cs2 @@ -0,0 +1,4 @@ +void script_22() { + setWidgetText(new WidgetPointer(139,4), intToStr(standart_config_143)); + return; +} diff --git a/dumps/scripts/220.cs2 b/dumps/scripts/220.cs2 new file mode 100644 index 0000000..f86a420 --- /dev/null +++ b/dumps/scripts/220.cs2 @@ -0,0 +1,22 @@ +void script_220() { + script_217(); + if (((boolean)stringMethod4107(globalstring_24, ""))) { + return; + } + globalint_790 = 2; + setWidgetIsHidden(true, new WidgetPointer(594,33)); + setWidgetIsHidden(true, new WidgetPointer(594,34)); + setWidgetIsHidden(true, new WidgetPointer(594,61)); + setWidgetIsHidden(true, new WidgetPointer(594,148)); + setWidgetIsHidden(true, new WidgetPointer(594,149)); + setWidgetIsHidden(true, new WidgetPointer(594,150)); + setWidgetIsHidden(true, new WidgetPointer(594,151)); + setWidgetIsHidden(true, new WidgetPointer(594,165)); + setWidgetIsHidden(true, new WidgetPointer(594,166)); + setWidgetIsHidden(false, new WidgetPointer(594,104)); + setWidgetIsHidden(true, new WidgetPointer(594,120)); + setWidgetIsHidden(true, new WidgetPointer(594,62)); + setWidgetIsHidden(true, new WidgetPointer(594,117)); + setWidgetIsHidden(true, new WidgetPointer(594,121)); + return; +} diff --git a/dumps/scripts/2200.cs2 b/dumps/scripts/2200.cs2 new file mode 100644 index 0000000..77e42d4 --- /dev/null +++ b/dumps/scripts/2200.cs2 @@ -0,0 +1,16 @@ +void script_2200() { + switch (rndExcl(4)) { + case 0: + globalint_1136 = 61079558; + break; + case 1: + globalint_1136 = 61079559; + break; + case 2: + globalint_1136 = 61079560; + break; + case 3: + globalint_1136 = 61079561; + } + return; +} diff --git a/dumps/scripts/2201.cs2 b/dumps/scripts/2201.cs2 new file mode 100644 index 0000000..506bf15 --- /dev/null +++ b/dumps/scripts/2201.cs2 @@ -0,0 +1,11 @@ +void script_2201() { + if (((boolean)standart_config_1701)) { + script_2200(); + } else { + script_2199(); + } + script_2209(); + setWidgetIsHidden(false, new WidgetPointer(globalint_1136)); + setScriptCallOnGameloop(2210, "", new WidgetPointer(932,1)); + return; +} diff --git a/dumps/scripts/2202.cs2 b/dumps/scripts/2202.cs2 new file mode 100644 index 0000000..1b6ba92 --- /dev/null +++ b/dumps/scripts/2202.cs2 @@ -0,0 +1,13 @@ +int script_2202(string arg0) { + int ivar0; + int ivar1; + ivar0 = strLength(arg0); + ivar1 = 0; + while (ivar1 < ivar0) { + if (strIndexof(0, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", substr(ivar1, add(ivar1, 1), arg0)) == -1) { + return 1; + } + ivar1 = add(ivar1, 1); + } + return 0; +} diff --git a/dumps/scripts/2203.cs2 b/dumps/scripts/2203.cs2 new file mode 100644 index 0000000..2226e82 --- /dev/null +++ b/dumps/scripts/2203.cs2 @@ -0,0 +1,16 @@ +int script_2203(string arg0) { + int ivar0; + int ivar1; + ivar0 = strLength(arg0); + if (ivar0 > 12) { + return 0; + } + ivar1 = 0; + while (ivar1 < ivar0) { + if (strIndexof(0, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_@. \u00a0", substr(ivar1, add(ivar1, 1), arg0)) == -1) { + return 0; + } + ivar1 = add(ivar1, 1); + } + return 1; +} diff --git a/dumps/scripts/2204.cs2 b/dumps/scripts/2204.cs2 new file mode 100644 index 0000000..f55095c --- /dev/null +++ b/dumps/scripts/2204.cs2 @@ -0,0 +1,4 @@ +void script_2204() { + setScriptCallOnGameloop(2211, "", new WidgetPointer(932,1)); + return; +} diff --git a/dumps/scripts/2205.cs2 b/dumps/scripts/2205.cs2 new file mode 100644 index 0000000..b95d86f --- /dev/null +++ b/dumps/scripts/2205.cs2 @@ -0,0 +1,4 @@ +void script_2205() { + script_2206(); + return; +} diff --git a/dumps/scripts/2206.cs2 b/dumps/scripts/2206.cs2 new file mode 100644 index 0000000..3821720 --- /dev/null +++ b/dumps/scripts/2206.cs2 @@ -0,0 +1,4 @@ +void script_2206() { + script_1174(11); + return; +} diff --git a/dumps/scripts/2207.cs2 b/dumps/scripts/2207.cs2 new file mode 100644 index 0000000..e411b2c --- /dev/null +++ b/dumps/scripts/2207.cs2 @@ -0,0 +1,6 @@ +void script_2207() { + if (((boolean)globalint_1137)) { + setScriptCallOnGameloop(2212, "", new WidgetPointer(932,1)); + } + return; +} diff --git a/dumps/scripts/2208.cs2 b/dumps/scripts/2208.cs2 new file mode 100644 index 0000000..2c2c9ba --- /dev/null +++ b/dumps/scripts/2208.cs2 @@ -0,0 +1,4 @@ +void script_2208() { + script_2209(); + return; +} diff --git a/dumps/scripts/2209.cs2 b/dumps/scripts/2209.cs2 new file mode 100644 index 0000000..a3c84ef --- /dev/null +++ b/dumps/scripts/2209.cs2 @@ -0,0 +1,22 @@ +void script_2209() { + setWidgetText(new WidgetPointer(932,3), "Correct " + intToStr(standart_config_1703) + "/5"); + globalint_1137 = 0; + setScriptCallOnGameloop(-1, "", new WidgetPointer(932,1)); + setWidgetPosition(0, 120, 0, 0, new WidgetPointer(932,10)); + setWidgetPosition(0, 120, 0, 0, new WidgetPointer(932,11)); + setWidgetPosition(0, 120, 0, 0, new WidgetPointer(932,12)); + setWidgetPosition(0, 120, 0, 0, new WidgetPointer(932,13)); + setWidgetPosition(0, 120, 0, 0, new WidgetPointer(932,6)); + setWidgetPosition(0, 120, 0, 0, new WidgetPointer(932,7)); + setWidgetPosition(0, 120, 0, 0, new WidgetPointer(932,8)); + setWidgetPosition(0, 120, 0, 0, new WidgetPointer(932,9)); + setWidgetIsHidden(true, new WidgetPointer(932,10)); + setWidgetIsHidden(true, new WidgetPointer(932,11)); + setWidgetIsHidden(true, new WidgetPointer(932,12)); + setWidgetIsHidden(true, new WidgetPointer(932,13)); + setWidgetIsHidden(true, new WidgetPointer(932,6)); + setWidgetIsHidden(true, new WidgetPointer(932,7)); + setWidgetIsHidden(true, new WidgetPointer(932,8)); + setWidgetIsHidden(true, new WidgetPointer(932,9)); + return; +} diff --git a/dumps/scripts/221.cs2 b/dumps/scripts/221.cs2 new file mode 100644 index 0000000..fdf7997 --- /dev/null +++ b/dumps/scripts/221.cs2 @@ -0,0 +1,23 @@ +void script_221() { + if (((boolean)stringMethod4107(globalstring_24, ""))) { + script_675(); + return; + } + globalint_790 = 3; + setWidgetIsHidden(true, new WidgetPointer(594,33)); + setWidgetIsHidden(true, new WidgetPointer(594,34)); + setWidgetIsHidden(true, new WidgetPointer(594,61)); + setWidgetIsHidden(true, new WidgetPointer(594,148)); + setWidgetIsHidden(true, new WidgetPointer(594,149)); + setWidgetIsHidden(true, new WidgetPointer(594,150)); + setWidgetIsHidden(true, new WidgetPointer(594,151)); + setWidgetIsHidden(true, new WidgetPointer(594,165)); + setWidgetIsHidden(true, new WidgetPointer(594,166)); + setWidgetIsHidden(true, new WidgetPointer(594,104)); + setWidgetIsHidden(false, new WidgetPointer(594,120)); + setWidgetIsHidden(true, new WidgetPointer(594,62)); + setWidgetIsHidden(true, new WidgetPointer(594,117)); + setWidgetIsHidden(true, new WidgetPointer(594,121)); + setWidgetText(new WidgetPointer(594,135), "Ignore " + globalstring_24 + "?"); + return; +} diff --git a/dumps/scripts/2210.cs2 b/dumps/scripts/2210.cs2 new file mode 100644 index 0000000..0c6cf76 --- /dev/null +++ b/dumps/scripts/2210.cs2 @@ -0,0 +1,7 @@ +void script_2210() { + if (getWidgetActualX(new WidgetPointer(globalint_1136)) < 200) { + setScriptCallOnGameloop(2210, "", new WidgetPointer(932,1)); + setWidgetPosition(add(1, getWidgetActualX(new WidgetPointer(globalint_1136))), getWidgetActualY(new WidgetPointer(globalint_1136)), 0, 0, new WidgetPointer(globalint_1136)); + } + return; +} diff --git a/dumps/scripts/2211.cs2 b/dumps/scripts/2211.cs2 new file mode 100644 index 0000000..e737fda --- /dev/null +++ b/dumps/scripts/2211.cs2 @@ -0,0 +1,7 @@ +void script_2211() { + if (getWidgetActualX(new WidgetPointer(globalint_1136)) < 339) { + setScriptCallOnGameloop(2211, "", new WidgetPointer(932,1)); + setWidgetPosition(add(1, getWidgetActualX(new WidgetPointer(globalint_1136))), getWidgetActualY(new WidgetPointer(globalint_1136)), 0, 0, new WidgetPointer(globalint_1136)); + } + return; +} diff --git a/dumps/scripts/2212.cs2 b/dumps/scripts/2212.cs2 new file mode 100644 index 0000000..6a844c6 --- /dev/null +++ b/dumps/scripts/2212.cs2 @@ -0,0 +1,10 @@ +void script_2212() { + if (getWidgetActualX(new WidgetPointer(globalint_1136)) < subtract(getWidgetActualWidth(new WidgetPointer(932,1)), 1)) { + setScriptCallOnGameloop(2212, "", new WidgetPointer(932,1)); + setWidgetPosition(add(1, getWidgetActualX(new WidgetPointer(globalint_1136))), getWidgetActualY(new WidgetPointer(globalint_1136)), 0, 0, new WidgetPointer(globalint_1136)); + } else { + setWidgetIsHidden(true, new WidgetPointer(globalint_1136)); + setWidgetPosition(0, 120, 0, 0, new WidgetPointer(globalint_1136)); + } + return; +} diff --git a/dumps/scripts/2213.cs2 b/dumps/scripts/2213.cs2 new file mode 100644 index 0000000..189264b --- /dev/null +++ b/dumps/scripts/2213.cs2 @@ -0,0 +1,79 @@ +void script_2213() { + int ivar0; + int ivar1; + int ivar2; + string svar0; + setWidgetSprite(4063, new WidgetPointer(673,102)); + setWidgetVFlip(0, new WidgetPointer(673,102)); + setWidgetHFlip(1, new WidgetPointer(673,102)); + setWidgetSprite(4063, new WidgetPointer(673,109)); + setWidgetVFlip(0, new WidgetPointer(673,109)); + setWidgetHFlip(0, new WidgetPointer(673,109)); + setWidgetSprite(4065, new WidgetPointer(673,103)); + setWidgetVFlip(0, new WidgetPointer(673,103)); + setWidgetHFlip(1, new WidgetPointer(673,103)); + setWidgetSprite(4065, new WidgetPointer(673,110)); + setWidgetVFlip(0, new WidgetPointer(673,110)); + setWidgetHFlip(0, new WidgetPointer(673,110)); + globalint_1411 = 1; + setWidgetSprite(4086, new WidgetPointer(673,41)); + cs2method5431(); + resetAccountCreateRC(); + globalstring_122 = ""; + globalstring_326 = ""; + globalstring_124 = ""; + globalstring_125 = ""; + globalstring_123 = ""; + globalstring_327 = ""; + globalstring_328 = ""; + globalstring_329 = ""; + globalint_1407 = 0; + globalint_1408 = 0; + globalint_1101 = 0; + script_3213(-1, ""); + setWidgetText(new WidgetPointer(673,44), ""); + setWidgetText(new WidgetPointer(673,120), ""); + setWidgetText(new WidgetPointer(673,91), ""); + setWidgetText(new WidgetPointer(673,81), ""); + setWidgetSprite(4057, new WidgetPointer(673,94)); + setWidgetSprite(4057, new WidgetPointer(673,113)); + setWidgetSprite(4057, new WidgetPointer(673,84)); + setWidgetSprite(4057, new WidgetPointer(673,74)); + setWidgetSprite(4057, new WidgetPointer(673,49)); + setWidgetIsHidden(true, new WidgetPointer(673,99)); + setWidgetIsHidden(true, new WidgetPointer(673,118)); + setWidgetIsHidden(true, new WidgetPointer(673,89)); + setWidgetIsHidden(true, new WidgetPointer(673,79)); + setWidgetIsHidden(true, new WidgetPointer(673,125)); + if (globalint_1407 != 0) { + setWidgetText(new WidgetPointer(673,43), intToStr(globalint_1407)); + setWidgetSprite(4059, new WidgetPointer(673,49)); + } else { + setWidgetText(new WidgetPointer(673,43), ""); + } + ivar0 = getTextWidth(3793, getWidgetText(new WidgetPointer(673,71))); + setWidgetSize(ivar0, getWidgetActualHeight(new WidgetPointer(673,61)), 0, 0, new WidgetPointer(673,61)); + ivar1 = getTextWidth(3793, getWidgetText(new WidgetPointer(673,72))); + setWidgetSize(ivar1, getWidgetActualHeight(new WidgetPointer(673,63)), 0, 0, new WidgetPointer(673,63)); + ivar2 = getTextWidth(3793, getWidgetText(new WidgetPointer(673,62))); + setWidgetSize(ivar2, getWidgetActualHeight(new WidgetPointer(673,62)), 0, 0, new WidgetPointer(673,62)); + svar0 = getWidgetText(new WidgetPointer(673,62)); + setWidgetText(new WidgetPointer(673,62), concat(concat(getWidgetText(new WidgetPointer(673,71)), concat(" ", concat(getWidgetText(new WidgetPointer(673,62)), " "))), getWidgetText(new WidgetPointer(673,72)))); + setWidgetPosition(0, getWidgetActualY(new WidgetPointer(673,62)), 1, 0, new WidgetPointer(673,62)); + setWidgetSize(getTextWidth(3793, getWidgetText(new WidgetPointer(673,62))), getWidgetActualHeight(new WidgetPointer(673,62)), 0, 0, new WidgetPointer(673,62)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(673,62)), getWidgetActualY(new WidgetPointer(673,61)), 0, 0, new WidgetPointer(673,61)); + setWidgetText(new WidgetPointer(673,62), svar0); + setWidgetSize(ivar2, getWidgetActualHeight(new WidgetPointer(673,62)), 0, 0, new WidgetPointer(673,62)); + setWidgetPosition(add(add(getWidgetActualX(new WidgetPointer(673,61)), getWidgetActualWidth(new WidgetPointer(673,61))), getTextWidth(3793, " ")), getWidgetActualY(new WidgetPointer(673,62)), 0, 0, new WidgetPointer(673,62)); + setWidgetPosition(add(add(getWidgetActualX(new WidgetPointer(673,62)), getWidgetActualWidth(new WidgetPointer(673,62))), getTextWidth(3793, " ")), getWidgetActualY(new WidgetPointer(673,63)), 0, 0, new WidgetPointer(673,63)); + globalint_1099 = 0; + setScriptCallOnMousePressed(3217, -2147483647, new WidgetPointer(673,100), new WidgetPointer(673,44), new WidgetPointer(673,101), 6, "iIIIi", new WidgetPointer(673,44)); + setScriptCallOnMousePressed(3217, -2147483647, new WidgetPointer(673,119), new WidgetPointer(673,120), new WidgetPointer(673,121), 14, "iIIIi", new WidgetPointer(673,120)); + setScriptCallOnMousePressed(3217, -2147483647, new WidgetPointer(673,90), new WidgetPointer(673,91), new WidgetPointer(673,92), 7, "iIIIi", new WidgetPointer(673,91)); + setScriptCallOnMousePressed(3217, -2147483647, new WidgetPointer(673,80), new WidgetPointer(673,81), new WidgetPointer(673,82), 8, "iIIIi", new WidgetPointer(673,81)); + setScriptCallOnMousePressed(3217, -2147483647, new WidgetPointer(673,126), new WidgetPointer(673,43), new WidgetPointer(673,127), 15, "iIIIi", new WidgetPointer(673,43)); + script_3208(0); + script_2714(6, 1); + globalint_1089 = -1; + return; +} diff --git a/dumps/scripts/2214.cs2 b/dumps/scripts/2214.cs2 new file mode 100644 index 0000000..273cb10 --- /dev/null +++ b/dumps/scripts/2214.cs2 @@ -0,0 +1,19 @@ +void script_2214() { + if (((boolean)globalint_1137)) { + if (getWidgetActualX(new WidgetPointer(globalint_1136)) < 256) { + setWidgetPosition(add(1, getWidgetActualX(new WidgetPointer(globalint_1136))), getWidgetActualY(new WidgetPointer(globalint_1136)), 0, 0, new WidgetPointer(globalint_1136)); + } + if (getWidgetActualX(new WidgetPointer(globalint_1136)) > 256) { + setWidgetPosition(subtract(getWidgetActualX(new WidgetPointer(globalint_1136)), 1), getWidgetActualY(new WidgetPointer(globalint_1136)), 0, 0, new WidgetPointer(globalint_1136)); + } + if (getWidgetActualY(new WidgetPointer(932,14)) > 70) { + setWidgetPosition(getWidgetActualX(new WidgetPointer(globalint_1136)), subtract(getWidgetActualY(new WidgetPointer(globalint_1136)), 2), 0, 0, new WidgetPointer(globalint_1136)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(932,14)), subtract(getWidgetActualY(new WidgetPointer(932,14)), 2), 0, 0, new WidgetPointer(932,14)); + setScriptCallOnGameloop(2214, "", new WidgetPointer(932,1)); + } else { + setWidgetIsHidden(true, new WidgetPointer(globalint_1136)); + setScriptCallOnGameloop(2215, "", new WidgetPointer(932,1)); + } + } + return; +} diff --git a/dumps/scripts/2215.cs2 b/dumps/scripts/2215.cs2 new file mode 100644 index 0000000..14d0f17 --- /dev/null +++ b/dumps/scripts/2215.cs2 @@ -0,0 +1,9 @@ +void script_2215() { + if (getWidgetActualY(new WidgetPointer(932,14)) < 180) { + setScriptCallOnGameloop(2215, "", new WidgetPointer(932,1)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(932,14)), add(2, getWidgetActualY(new WidgetPointer(932,14))), 0, 0, new WidgetPointer(932,14)); + } else { + globalint_1137 = 0; + } + return; +} diff --git a/dumps/scripts/2216.cs2 b/dumps/scripts/2216.cs2 new file mode 100644 index 0000000..e984e95 --- /dev/null +++ b/dumps/scripts/2216.cs2 @@ -0,0 +1,12 @@ +void script_2216() { + if (standart_config_1700 == 2) { + if (((boolean)globalint_1137)) { + playSoundEffect(8731, 1, 0); + } + globalint_1137 = 1; + setScriptCallOnGameloop(2214, "", new WidgetPointer(932,1)); + } else { + messageType0("There is nothing to push off!"); + } + return; +} diff --git a/dumps/scripts/2217.cs2 b/dumps/scripts/2217.cs2 new file mode 100644 index 0000000..9dd275f --- /dev/null +++ b/dumps/scripts/2217.cs2 @@ -0,0 +1,4 @@ +void script_2217() { + script_31(60948492, 60948495, 792, 789, 790, 791, 773, 788); + return; +} diff --git a/dumps/scripts/2218.cs2 b/dumps/scripts/2218.cs2 new file mode 100644 index 0000000..173d10c --- /dev/null +++ b/dumps/scripts/2218.cs2 @@ -0,0 +1,14 @@ +void script_2218() { + globalint_1126 = standart_config_1675; + globalint_1127 = standart_config_1676; + globalint_1128 = standart_config_1677; + globalint_1129 = standart_config_1678; + globalint_1131 = standart_config_1680; + globalint_1130 = standart_config_1679; + globalint_1132 = standart_config_1682; + globalint_1134 = standart_config_1684; + globalint_1133 = standart_config_1683; + globalint_1135 = standart_config_1681; + script_2220(); + return; +} diff --git a/dumps/scripts/2219.cs2 b/dumps/scripts/2219.cs2 new file mode 100644 index 0000000..988aac3 --- /dev/null +++ b/dumps/scripts/2219.cs2 @@ -0,0 +1,14 @@ +void script_2219() { + globalint_1126 = standart_config_1675; + globalint_1127 = standart_config_1676; + globalint_1128 = standart_config_1677; + globalint_1129 = standart_config_1678; + globalint_1131 = standart_config_1680; + globalint_1130 = standart_config_1679; + globalint_1132 = standart_config_1682; + globalint_1134 = standart_config_1684; + globalint_1133 = standart_config_1683; + globalint_1135 = standart_config_1681; + script_2220(); + return; +} diff --git a/dumps/scripts/222.cs2 b/dumps/scripts/222.cs2 new file mode 100644 index 0000000..d79e386 --- /dev/null +++ b/dumps/scripts/222.cs2 @@ -0,0 +1,11 @@ +void script_222() { + if (isFriend(globalstring_24)) { + message(26, 0, "Sorry, you cannot ignore players in your Friends List."); + } else { + cs2method3630(globalstring_24); + message(26, 0, "You are ignoring " + globalstring_24 + " until you log out."); + } + globalint_11 = 0; + script_675(); + return; +} diff --git a/dumps/scripts/2220.cs2 b/dumps/scripts/2220.cs2 new file mode 100644 index 0000000..91c636e --- /dev/null +++ b/dumps/scripts/2220.cs2 @@ -0,0 +1,48 @@ +void script_2220() { + if (((boolean)bitconfig_7324)) { + setWidgetIsHidden(true, new WidgetPointer(931,121)); + } else { + setWidgetIsHidden(false, new WidgetPointer(931,121)); + } + if (((boolean)bitconfig_7325)) { + setWidgetIsHidden(true, new WidgetPointer(931,122)); + } else { + setWidgetIsHidden(false, new WidgetPointer(931,122)); + } + if (((boolean)bitconfig_7326)) { + setWidgetIsHidden(true, new WidgetPointer(931,123)); + } else { + setWidgetIsHidden(false, new WidgetPointer(931,123)); + } + setWidgetText(new WidgetPointer(931,154), intToStr(globalint_1126)); + setWidgetText(new WidgetPointer(931,148), intToStr(globalint_1127)); + setWidgetText(new WidgetPointer(931,142), intToStr(globalint_1128)); + setWidgetText(new WidgetPointer(931,112), intToStr(globalint_1129)); + setWidgetText(new WidgetPointer(931,136), intToStr(globalint_1131)); + setWidgetText(new WidgetPointer(931,130), intToStr(globalint_1130)); + setWidgetText(new WidgetPointer(931,155), "Total Workers: " + intToStr(globalint_1135)); + setWidgetText(new WidgetPointer(931,115), intToStr(standart_config_1687) + "/15"); + setWidgetText(new WidgetPointer(931,117), intToStr(standart_config_1688) + "/15"); + setWidgetText(new WidgetPointer(931,116), intToStr(standart_config_1686) + "/15"); + setWidgetText(new WidgetPointer(931,120), intToStr(standart_config_1689) + "/7"); + setWidgetText(new WidgetPointer(931,118), intToStr(standart_config_1690) + "/7"); + setWidgetText(new WidgetPointer(931,119), intToStr(standart_config_1691) + "/7"); + script_2221(); + setWidgetText(new WidgetPointer(931,20), "Turn " + intToStr(standart_config_1674) + "/15"); + if (((boolean)globalint_1132)) { + setWidgetSprite(941, new WidgetPointer(931,121)); + } else { + setWidgetSprite(942, new WidgetPointer(931,121)); + } + if (((boolean)globalint_1134)) { + setWidgetSprite(941, new WidgetPointer(931,122)); + } else { + setWidgetSprite(942, new WidgetPointer(931,122)); + } + if (((boolean)globalint_1133)) { + setWidgetSprite(941, new WidgetPointer(931,123)); + } else { + setWidgetSprite(942, new WidgetPointer(931,123)); + } + return; +} diff --git a/dumps/scripts/2221.cs2 b/dumps/scripts/2221.cs2 new file mode 100644 index 0000000..09e7550 --- /dev/null +++ b/dumps/scripts/2221.cs2 @@ -0,0 +1,16 @@ +void script_2221() { + switch (standart_config_1685) { + case 0: + setWidgetText(new WidgetPointer(931,156), ""); + break; + case 1: + setWidgetText(new WidgetPointer(931,156), "Not enough workers."); + break; + case 2: + setWidgetText(new WidgetPointer(931,156), "Not enough resources."); + break; + case 3: + setWidgetText(new WidgetPointer(931,156), "Worker limit reached."); + } + return; +} diff --git a/dumps/scripts/2222.cs2 b/dumps/scripts/2222.cs2 new file mode 100644 index 0000000..332b6b0 --- /dev/null +++ b/dumps/scripts/2222.cs2 @@ -0,0 +1,18 @@ +void script_2222(int arg0) { + switch (arg0) { + case 13: + script_1174(11); + break; + case 84: + if (isWidgetHidden(new WidgetPointer(669,13))) { + if (((boolean)globalint_1088)) { + script_2932(0, "dob", "set_members_dob.ws"); + } else { + script_1174(12); + } + } else { + script_2715(); + } + } + return; +} diff --git a/dumps/scripts/2223.cs2 b/dumps/scripts/2223.cs2 new file mode 100644 index 0000000..a2c4f69 --- /dev/null +++ b/dumps/scripts/2223.cs2 @@ -0,0 +1,61 @@ +void script_2223() { + int ivar0; + int ivar1; + int ivar2; + string svar0; + string svar1; + string svar2; + string svar3; + openInterface(48758833, 669); + setWidgetSprite(4088, new WidgetPointer(669,27)); + setWidgetSprite(4063, new WidgetPointer(669,28)); + setWidgetVFlip(0, new WidgetPointer(669,28)); + setWidgetHFlip(1, new WidgetPointer(669,28)); + setWidgetSprite(4063, new WidgetPointer(669,29)); + setWidgetVFlip(0, new WidgetPointer(669,29)); + setWidgetHFlip(0, new WidgetPointer(669,29)); + setWidgetSprite(4065, new WidgetPointer(669,21)); + setWidgetVFlip(0, new WidgetPointer(669,21)); + setWidgetHFlip(1, new WidgetPointer(669,21)); + setWidgetSprite(4065, new WidgetPointer(669,26)); + setWidgetVFlip(0, new WidgetPointer(669,26)); + setWidgetHFlip(0, new WidgetPointer(669,26)); + svar0 = ""; + ivar0 = getTextWidth(3793, getWidgetText(new WidgetPointer(669,48))); + setWidgetSize(ivar0, getWidgetActualHeight(new WidgetPointer(669,7)), 0, 0, new WidgetPointer(669,7)); + ivar1 = getTextWidth(3793, getWidgetText(new WidgetPointer(669,49))); + setWidgetSize(ivar1, getWidgetActualHeight(new WidgetPointer(669,9)), 0, 0, new WidgetPointer(669,9)); + ivar2 = getTextWidth(3793, getWidgetText(new WidgetPointer(669,8))); + setWidgetSize(ivar2, getWidgetActualHeight(new WidgetPointer(669,8)), 0, 0, new WidgetPointer(669,8)); + svar1 = getWidgetText(new WidgetPointer(669,8)); + setWidgetText(new WidgetPointer(669,8), concat(concat(getWidgetText(new WidgetPointer(669,48)), concat(" ", concat(getWidgetText(new WidgetPointer(669,8)), " "))), getWidgetText(new WidgetPointer(669,49)))); + setWidgetPosition(0, getWidgetActualY(new WidgetPointer(669,8)), 1, 0, new WidgetPointer(669,8)); + setWidgetSize(getTextWidth(3793, getWidgetText(new WidgetPointer(669,8))), getWidgetActualHeight(new WidgetPointer(669,8)), 0, 0, new WidgetPointer(669,8)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(669,8)), getWidgetActualY(new WidgetPointer(669,7)), 0, 0, new WidgetPointer(669,7)); + setWidgetText(new WidgetPointer(669,8), svar1); + setWidgetSize(ivar2, getWidgetActualHeight(new WidgetPointer(669,8)), 0, 0, new WidgetPointer(669,8)); + setWidgetPosition(add(add(getWidgetActualX(new WidgetPointer(669,7)), getWidgetActualWidth(new WidgetPointer(669,7))), getTextWidth(3793, " ")), getWidgetActualY(new WidgetPointer(669,8)), 0, 0, new WidgetPointer(669,8)); + setWidgetPosition(add(add(getWidgetActualX(new WidgetPointer(669,8)), getWidgetActualWidth(new WidgetPointer(669,8))), getTextWidth(3793, " ")), getWidgetActualY(new WidgetPointer(669,9)), 0, 0, new WidgetPointer(669,9)); + if (globalint_1407 < 13) { + setWidgetIsHidden(true, new WidgetPointer(669,14)); + setWidgetIsHidden(true, new WidgetPointer(669,27)); + setWidgetIsHidden(false, new WidgetPointer(669,13)); + setWidgetText(new WidgetPointer(669,18), "Congratulations, your account has been created successfully!"); + } else { + setWidgetIsHidden(false, new WidgetPointer(669,14)); + setWidgetIsHidden(false, new WidgetPointer(669,27)); + setWidgetIsHidden(true, new WidgetPointer(669,13)); + setWidgetText(new WidgetPointer(669,18), "Congratulations, your account has been successfully created!"); + } + svar2 = "dob"; + svar3 = "set_members_dob.ws"; + if (((boolean)globalint_1088)) { + svar0 = "Continue To Buy"; + setScriptCallOnMousePressed(2931, svar2, svar3, 0, "ss1", new WidgetPointer(669,40)); + } else { + svar0 = "Continue"; + setScriptCallOnMousePressed(1173, 12, "i", new WidgetPointer(669,40)); + } + script_1174(8); + return; +} diff --git a/dumps/scripts/2224.cs2 b/dumps/scripts/2224.cs2 new file mode 100644 index 0000000..828c0cb --- /dev/null +++ b/dumps/scripts/2224.cs2 @@ -0,0 +1,11 @@ +void script_2224() { + if ((globalint_1127 < 15) && (script_2240() < globalint_1135)) { + playSoundEffect(8729, 1, 0); + globalint_1126 = add(globalint_1126, 1); + } else { + standart_config_1685 = 1; + playSoundEffect(2277, 1, 0); + } + script_2220(); + return; +} diff --git a/dumps/scripts/2225.cs2 b/dumps/scripts/2225.cs2 new file mode 100644 index 0000000..9332b67 --- /dev/null +++ b/dumps/scripts/2225.cs2 @@ -0,0 +1,8 @@ +void script_2225() { + if (globalint_1126 > 0) { + playSoundEffect(8729, 1, 0); + globalint_1126 = subtract(globalint_1126, 1); + script_2220(); + } + return; +} diff --git a/dumps/scripts/2226.cs2 b/dumps/scripts/2226.cs2 new file mode 100644 index 0000000..afa05c4 --- /dev/null +++ b/dumps/scripts/2226.cs2 @@ -0,0 +1,11 @@ +void script_2226() { + if ((globalint_1127 < 15) && (script_2240() < globalint_1135)) { + playSoundEffect(8729, 1, 0); + globalint_1127 = add(globalint_1127, 1); + } else { + standart_config_1685 = 1; + playSoundEffect(2277, 1, 0); + } + script_2220(); + return; +} diff --git a/dumps/scripts/2227.cs2 b/dumps/scripts/2227.cs2 new file mode 100644 index 0000000..076b768 --- /dev/null +++ b/dumps/scripts/2227.cs2 @@ -0,0 +1,8 @@ +void script_2227() { + if (globalint_1127 > 0) { + playSoundEffect(8729, 1, 0); + globalint_1127 = subtract(globalint_1127, 1); + script_2220(); + } + return; +} diff --git a/dumps/scripts/2228.cs2 b/dumps/scripts/2228.cs2 new file mode 100644 index 0000000..f0eebb9 --- /dev/null +++ b/dumps/scripts/2228.cs2 @@ -0,0 +1,11 @@ +void script_2228() { + if ((globalint_1127 < 15) && (script_2240() < globalint_1135)) { + playSoundEffect(8729, 1, 0); + globalint_1128 = add(globalint_1128, 1); + } else { + standart_config_1685 = 1; + playSoundEffect(2277, 1, 0); + } + script_2220(); + return; +} diff --git a/dumps/scripts/2229.cs2 b/dumps/scripts/2229.cs2 new file mode 100644 index 0000000..e2bee8f --- /dev/null +++ b/dumps/scripts/2229.cs2 @@ -0,0 +1,8 @@ +void script_2229() { + if (globalint_1128 > 0) { + playSoundEffect(8729, 1, 0); + globalint_1128 = subtract(globalint_1128, 1); + script_2220(); + } + return; +} diff --git a/dumps/scripts/223.cs2 b/dumps/scripts/223.cs2 new file mode 100644 index 0000000..e1e6772 --- /dev/null +++ b/dumps/scripts/223.cs2 @@ -0,0 +1,5 @@ +void script_223() { + globalint_11 = 0; + script_675(); + return; +} diff --git a/dumps/scripts/2230.cs2 b/dumps/scripts/2230.cs2 new file mode 100644 index 0000000..4642e0c --- /dev/null +++ b/dumps/scripts/2230.cs2 @@ -0,0 +1,11 @@ +void script_2230() { + if ((globalint_1127 < 15) && (script_2240() < globalint_1135)) { + playSoundEffect(8729, 1, 0); + globalint_1129 = add(globalint_1129, 1); + } else { + standart_config_1685 = 1; + playSoundEffect(2277, 1, 0); + } + script_2220(); + return; +} diff --git a/dumps/scripts/2231.cs2 b/dumps/scripts/2231.cs2 new file mode 100644 index 0000000..e134a86 --- /dev/null +++ b/dumps/scripts/2231.cs2 @@ -0,0 +1,8 @@ +void script_2231() { + if (globalint_1129 > 0) { + playSoundEffect(8729, 1, 0); + globalint_1129 = subtract(globalint_1129, 1); + script_2220(); + } + return; +} diff --git a/dumps/scripts/2232.cs2 b/dumps/scripts/2232.cs2 new file mode 100644 index 0000000..998f4ca --- /dev/null +++ b/dumps/scripts/2232.cs2 @@ -0,0 +1,11 @@ +void script_2232() { + if ((globalint_1127 < 15) && (script_2240() < globalint_1135)) { + playSoundEffect(8729, 1, 0); + globalint_1131 = add(globalint_1131, 1); + } else { + standart_config_1685 = 1; + playSoundEffect(2277, 1, 0); + } + script_2220(); + return; +} diff --git a/dumps/scripts/2233.cs2 b/dumps/scripts/2233.cs2 new file mode 100644 index 0000000..c3621e4 --- /dev/null +++ b/dumps/scripts/2233.cs2 @@ -0,0 +1,8 @@ +void script_2233() { + if (globalint_1131 > 0) { + playSoundEffect(8729, 1, 0); + globalint_1131 = subtract(globalint_1131, 1); + script_2220(); + } + return; +} diff --git a/dumps/scripts/2234.cs2 b/dumps/scripts/2234.cs2 new file mode 100644 index 0000000..45d7af4 --- /dev/null +++ b/dumps/scripts/2234.cs2 @@ -0,0 +1,11 @@ +void script_2234() { + if ((globalint_1127 < 15) && (script_2240() < globalint_1135)) { + playSoundEffect(8729, 1, 0); + globalint_1130 = add(globalint_1130, 1); + } else { + standart_config_1685 = 1; + playSoundEffect(2277, 1, 0); + } + script_2220(); + return; +} diff --git a/dumps/scripts/2235.cs2 b/dumps/scripts/2235.cs2 new file mode 100644 index 0000000..4b6744e --- /dev/null +++ b/dumps/scripts/2235.cs2 @@ -0,0 +1,8 @@ +void script_2235() { + if (globalint_1130 > 0) { + playSoundEffect(8729, 1, 0); + globalint_1130 = subtract(globalint_1130, 1); + script_2220(); + } + return; +} diff --git a/dumps/scripts/2236.cs2 b/dumps/scripts/2236.cs2 new file mode 100644 index 0000000..59069fb --- /dev/null +++ b/dumps/scripts/2236.cs2 @@ -0,0 +1,11 @@ +void script_2236() { + if ((globalint_1135 < 15) && (add(add(standart_config_1687, standart_config_1688), standart_config_1686) > 1)) { + playSoundEffect(8729, 1, 0); + globalint_1135 = add(globalint_1135, 1); + } else { + standart_config_1685 = 2; + playSoundEffect(2277, 1, 0); + } + script_2220(); + return; +} diff --git a/dumps/scripts/2237.cs2 b/dumps/scripts/2237.cs2 new file mode 100644 index 0000000..22f83b4 --- /dev/null +++ b/dumps/scripts/2237.cs2 @@ -0,0 +1,10 @@ +void script_2237() { + playSoundEffect(8729, 1, 0); + if (((boolean)globalint_1132)) { + globalint_1132 = 1; + } else { + globalint_1132 = 0; + } + script_2220(); + return; +} diff --git a/dumps/scripts/2238.cs2 b/dumps/scripts/2238.cs2 new file mode 100644 index 0000000..dc9ef67 --- /dev/null +++ b/dumps/scripts/2238.cs2 @@ -0,0 +1,10 @@ +void script_2238() { + playSoundEffect(8729, 1, 0); + if (((boolean)globalint_1134)) { + globalint_1134 = 1; + } else { + globalint_1134 = 0; + } + script_2220(); + return; +} diff --git a/dumps/scripts/2239.cs2 b/dumps/scripts/2239.cs2 new file mode 100644 index 0000000..b534f0b --- /dev/null +++ b/dumps/scripts/2239.cs2 @@ -0,0 +1,10 @@ +void script_2239() { + playSoundEffect(8729, 1, 0); + if (((boolean)globalint_1133)) { + globalint_1133 = 1; + } else { + globalint_1133 = 0; + } + script_2220(); + return; +} diff --git a/dumps/scripts/224.cs2 b/dumps/scripts/224.cs2 new file mode 100644 index 0000000..e585d62 --- /dev/null +++ b/dumps/scripts/224.cs2 @@ -0,0 +1,87 @@ +void script_224() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + string svar0; + ivar0 = ((int)isWidgetHidden(new WidgetPointer(594,61))); + if (((boolean)ivar0)) { + setWidgetIsHidden(false, new WidgetPointer(594,61)); + } + ivar1 = 100; + svar0 = ""; + ivar2 = 0; + ivar3 = 0; + ivar4 = 0; + deleteAllExtraChilds(new WidgetPointer(594,94)); + deleteAllExtraChilds(new WidgetPointer(594,93)); + deleteAllExtraChilds(new WidgetPointer(594,92)); + setWidgetScrollMax(0, 0, new WidgetPointer(594,94)); + cs2method2100(0, 0, new WidgetPointer(594,94)); + while (ivar1 >= 0) { + ivar3 = cs2method5004(ivar1); + if (((((ivar3 != 0) && (ivar3 != 4)) && ((ivar3 != 27) && (ivar3 != 28))) && (((ivar3 != 29) && (ivar3 != 43)) && ((ivar3 != 103) && (ivar3 != 104)))) && ((((ivar3 != 26) && (ivar3 != 30)) && ((ivar3 != 31) && (stringMethod4107(cs2method5010(ivar1), "") != 0))) && (stringMethod4107(cs2method5003(ivar1), "") != 0))) { + if (((stringMethod4107(strRemoveEntities(cs2method5010(ivar1)), cs2method5015()) != 0) && (ivar3 != 6)) && (ivar3 != 19)) { + ivar4 = 1; + createExtraChild(new WidgetPointer(594,93), 3, getExtraChildGap(new WidgetPointer(594,93))); + setWidgetPosition(0, multiply(ivar2, 14), 0, 0); + setWidgetSize(16384, 14, 2, 0); + setWidgetRGB(new Color(103, 138, 176)); + cs2method2103(255); + setWidgetFilled(1); + setScriptCallOnMouseEntered(237, -2147483643, "i"); + setScriptCallOnMouseExit(238, -2147483643, "i"); + createExtraChild(new WidgetPointer(594,92), 3, getExtraChildGap(new WidgetPointer(594,92))); + setWidgetPosition(0, multiply(ivar2, 14), 0, 0); + setWidgetSize(16384, 14, 2, 0); + setWidgetRGB(new Color(103, 138, 176)); + cs2method2103(255); + setWidgetFilled(1); + setScriptCallOnMouseEntered(239, -2147483643, "i"); + } + createExtraChild(new WidgetPointer(594,94), 4, getExtraChildGap(new WidgetPointer(594,94))); + setWidgetPosition(5, multiply(ivar2, 14), 0, 0); + setWidgetSize(16384, 14, 2, 0); + if ((ivar3 != 6) && (ivar3 != 19)) { + setWidgetText(" " + cs2method5010(ivar1) + ": " + cs2method5003(ivar1)); + } else { + setWidgetText("To " + cs2method5010(ivar1) + ": " + cs2method5003(ivar1)); + } + setWidgetRGB(new Color(119, 119, 119)); + if (((stringMethod4107(strRemoveEntities(cs2method5010(ivar1)), cs2method5015()) != 0) && (ivar3 != 6)) && (ivar3 != 19)) { + cs2method1305(strRemoveEntities(cs2method5019(ivar1))); + setWidgetContextMenuOption(1, "Report"); + setScriptCallOnClickContextMenu(234, -2147483643, "i"); + setWidgetRGB(new Color(0, 0, 0)); + } + setWidgetFont(495); + setWidgetTextAlignment(0, 0, 14); + ivar2 = add(ivar2, 1); + } + ivar1 = subtract(ivar1, 1); + } + if (((boolean)ivar4)) { + createExtraChild(new WidgetPointer(594,94), 4, getExtraChildGap(new WidgetPointer(594,94))); + setWidgetPosition(5, multiply(ivar2, 14), 0, 0); + setWidgetSize(16384, 14, 2, 0); + setWidgetText("There is no chat to report at the moment."); + setWidgetRGB(new Color(0, 0, 153)); + setWidgetFont(495); + setWidgetTextAlignment(0, 0, 14); + } + if (ivar2 > divide(getWidgetActualHeight(new WidgetPointer(594,87)), 14)) { + setWidgetSize(63, getWidgetActualHeight(new WidgetPointer(594,87)), 1, 0, new WidgetPointer(594,87)); + setWidgetScrollMax(0, multiply(ivar2, 14), new WidgetPointer(594,91)); + script_31(38928470, 38928475, 792, 789, 790, 791, 773, 788); + if (setWidgetRegister(new WidgetPointer(594,86), 1)) { + script_37(38928470, 38928475, getWidgetScrollMaxV(new WidgetPointer(594,91)), 1); + } + } else { + setWidgetSize(44, getWidgetActualHeight(new WidgetPointer(594,87)), 1, 0, new WidgetPointer(594,87)); + } + if (((boolean)ivar0)) { + setWidgetIsHidden(true, new WidgetPointer(594,61)); + } + return; +} diff --git a/dumps/scripts/2240.cs2 b/dumps/scripts/2240.cs2 new file mode 100644 index 0000000..150c39c --- /dev/null +++ b/dumps/scripts/2240.cs2 @@ -0,0 +1,15 @@ +int script_2240() { + int ivar0; + ivar0 = 5; + ivar0 = add(add(add(add(add(globalint_1126, globalint_1127), globalint_1128), globalint_1129), globalint_1131), globalint_1130); + if (((boolean)globalint_1133)) { + ivar0 = add(ivar0, 1); + } + if (((boolean)globalint_1134)) { + ivar0 = add(ivar0, 1); + } + if (((boolean)globalint_1132)) { + ivar0 = add(ivar0, 1); + } + return ivar0; +} diff --git a/dumps/scripts/2241.cs2 b/dumps/scripts/2241.cs2 new file mode 100644 index 0000000..cfb9f62 --- /dev/null +++ b/dumps/scripts/2241.cs2 @@ -0,0 +1,57 @@ +void script_2241() { + setWidgetText(new WidgetPointer(929,106), "+ " + intToStr(standart_config_1693) + " ( " + intToStr(standart_config_1687) + " )" + "
" + "+ " + intToStr(standart_config_1692) + " ( " + intToStr(standart_config_1686) + " )" + "
" + "+ " + intToStr(standart_config_1694) + " ( " + intToStr(standart_config_1688) + " )" + "
"); + setWidgetText(new WidgetPointer(929,108), "+ " + intToStr(standart_config_1695) + " ( " + intToStr(standart_config_1689) + " )" + "
" + "+ " + intToStr(standart_config_1697) + " ( " + intToStr(standart_config_1690) + " )" + "
" + "+ " + intToStr(standart_config_1696) + " ( " + intToStr(standart_config_1691) + " )" + "
"); + if (((boolean)bitconfig_7324)) { + setWidgetText(new WidgetPointer(929,113), "WORKING"); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(929,113)); + } else { + playSoundEffect(8723, 10, 0); + setWidgetText(new WidgetPointer(929,113), "NEEDS REPAIR"); + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(929,113)); + } + if (((boolean)bitconfig_7326)) { + setWidgetText(new WidgetPointer(929,112), "WORKING"); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(929,112)); + } else { + playSoundEffect(8723, 10, 1); + setWidgetText(new WidgetPointer(929,112), "NEEDS REPAIR"); + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(929,112)); + } + if (((boolean)bitconfig_7325)) { + setWidgetText(new WidgetPointer(929,114), "WORKING"); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(929,114)); + } else { + playSoundEffect(8723, 10, 2); + setWidgetText(new WidgetPointer(929,114), "NEEDS REPAIR"); + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(929,114)); + } + setWidgetText(new WidgetPointer(929,102), intToStr(divide(globalint_1135, 5))); + switch (standart_config_1698) { + case 5: + setWidgetText(new WidgetPointer(929,104), "Your workers uncover a hidden stash and you receive"); + setWidgetText(new WidgetPointer(929,105), "3 extra resources."); + playSoundEffect(8728, 1, 0); + break; + case 6: + setWidgetText(new WidgetPointer(929,104), "An accident at work has taken place. As a result you have"); + setWidgetText(new WidgetPointer(929,105), "lost 3 resources."); + playSoundEffect(8723, 10, 0); + break; + case 7: + setWidgetText(new WidgetPointer(929,104), "The paint machine is out of glaze and requires a repair to work at full efficiency."); + setWidgetText(new WidgetPointer(929,105), "Painter needs repair."); + break; + case 8: + setWidgetText(new WidgetPointer(929,104), "The conveyor team needs re-training in order to work at full efficiency."); + setWidgetText(new WidgetPointer(929,105), "Conveyor needs repair."); + break; + case 9: + setWidgetText(new WidgetPointer(929,104), "The oven is coated in soot. It requires a repair to work at full efficiency."); + setWidgetText(new WidgetPointer(929,105), "Oven needs repair."); + break; + default: + setWidgetText(new WidgetPointer(929,104), ""); + setWidgetText(new WidgetPointer(929,105), "Nothing unusual happened."); + } + return; +} diff --git a/dumps/scripts/2242.cs2 b/dumps/scripts/2242.cs2 new file mode 100644 index 0000000..4377f0a --- /dev/null +++ b/dumps/scripts/2242.cs2 @@ -0,0 +1,56 @@ +void script_2242() { + int ivar0; + playSoundEffect(8727, 3, 0); + setWidgetText(new WidgetPointer(927,22), "Turns taken score: " + intToStr(standart_config_1674) + " x 101 = " + intToStr(multiply(standart_config_1674, 101))); + setWidgetText(new WidgetPointer(927,26), "Resources spare: " + intToStr(add(standart_config_1688, add(standart_config_1687, standart_config_1686))) + " x -10 = -" + intToStr(multiply(add(standart_config_1688, add(standart_config_1687, standart_config_1686)), 10))); + if (standart_config_1674 < 16) { + setWidgetText(new WidgetPointer(927,27), "Completed within turn limit: -100"); + } else { + setWidgetText(new WidgetPointer(927,27), "Not completed within turn limit: 0"); + } + setWidgetText(new WidgetPointer(927,28), "Workers employed: " + intToStr(standart_config_1681) + " x -10 = -" + intToStr(multiply(standart_config_1681, 10))); + setWidgetText(new WidgetPointer(927,32), "Turns taken: " + intToStr(standart_config_1674)); + if (((boolean)bitconfig_7324)) { + setWidgetText(new WidgetPointer(927,23), "Oven not repaired: 50"); + } else { + setWidgetText(new WidgetPointer(927,23), "Oven repaired: 0"); + } + if (((boolean)bitconfig_7326)) { + setWidgetText(new WidgetPointer(927,24), "Conveyor not repaired: 50"); + } else { + setWidgetText(new WidgetPointer(927,24), "Conveyor repaired: 0"); + } + if (((boolean)bitconfig_7325)) { + setWidgetText(new WidgetPointer(927,25), "Painter not repaired: 50"); + } else { + setWidgetText(new WidgetPointer(927,25), "Painter repaired: 0"); + } + ivar0 = 0; + ivar0 = multiply(standart_config_1674, 101); + if (((boolean)bitconfig_7325)) { + ivar0 = add(ivar0, 50); + } + if (((boolean)bitconfig_7324)) { + ivar0 = add(ivar0, 50); + } + if (((boolean)bitconfig_7326)) { + ivar0 = add(ivar0, 50); + } + ivar0 = subtract(ivar0, multiply(add(standart_config_1688, add(standart_config_1687, standart_config_1686)), 10)); + if (standart_config_1674 < 16) { + ivar0 = subtract(ivar0, 100); + } + ivar0 = subtract(ivar0, multiply(standart_config_1681, 10)); + if (ivar0 < 0) { + ivar0 = 0; + } + if (ivar0 > 32768) { + ivar0 = 32768; + } + if (ivar0 == bitconfig_7339) { + setWidgetText(new WidgetPointer(927,31), "Final score: " + intToStr(ivar0) + " (New best score)"); + } else { + setWidgetText(new WidgetPointer(927,31), "Final score: " + intToStr(ivar0)); + } + return; +} diff --git a/dumps/scripts/2243.cs2 b/dumps/scripts/2243.cs2 new file mode 100644 index 0000000..ea743b7 --- /dev/null +++ b/dumps/scripts/2243.cs2 @@ -0,0 +1,7 @@ +void script_2243(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8) { + setWidgetText(new WidgetPointer(935,80), intToStr(arg6)); + setWidgetText(new WidgetPointer(935,85), intToStr(arg7)); + setWidgetText(new WidgetPointer(935,101), intToStr(divide(arg8, 100)) + "." + intToStr(mod(arg8, 100))); + setScriptCallOnGameloop(2244, 0, arg0, arg1, 0, arg2, arg3, 0, arg4, arg5, arg6, arg7, arg8, "iiiiiiiiiiii", new WidgetPointer(935,0)); + return; +} diff --git a/dumps/scripts/2244.cs2 b/dumps/scripts/2244.cs2 new file mode 100644 index 0000000..b04eb47 --- /dev/null +++ b/dumps/scripts/2244.cs2 @@ -0,0 +1,17 @@ +void script_2244(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11) { + int ivar12; + arg0 = script_2245(arg1, arg2, arg0, 61276214, 61276209); + arg3 = script_2245(arg4, arg5, arg3, 61276224, 61276219); + arg6 = script_2245(arg7, arg8, arg6, 61276234, 61276229); + ivar12 = add(add(arg0, arg3), arg6); + setWidgetSize(add(1, divide(multiply(223, ivar12), add(add(arg2, arg5), arg8))), 10, 0, 0, new WidgetPointer(935,95)); + ivar12 = add(add(ivar12, arg9), arg10); + setWidgetText(new WidgetPointer(935,90), intToStr(ivar12)); + setWidgetText(new WidgetPointer(935,107), intToStr(divide(multiply(ivar12, arg11), 100))); + if (((arg0 == arg1) && (arg3 == arg4)) && (arg6 == arg7)) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(935,0)); + } else { + setScriptCallOnGameloop(2244, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, "iiiiiiiiiiii", new WidgetPointer(935,0)); + } + return; +} diff --git a/dumps/scripts/2245.cs2 b/dumps/scripts/2245.cs2 new file mode 100644 index 0000000..f12fea7 --- /dev/null +++ b/dumps/scripts/2245.cs2 @@ -0,0 +1,21 @@ +int script_2245(int arg0,int arg1,int arg2,int arg3,int arg4) { + if (arg2 == arg0) { + return arg2; + } + if (arg2 < arg0) { + arg2 = add(arg2, divide(add(arg1, 49), 50)); + if (arg2 > arg0) { + arg2 = arg0; + } + } else { + if (arg2 > arg0) { + arg2 = subtract(arg2, divide(add(arg1, 49), 50)); + if (arg2 < arg0) { + arg2 = arg0; + } + } + } + setWidgetSize(add(1, divide(multiply(223, arg2), arg1)), 10, 0, 0, new WidgetPointer(arg3)); + setWidgetText(new WidgetPointer(arg4), intToStr(arg2)); + return arg2; +} diff --git a/dumps/scripts/2246.cs2 b/dumps/scripts/2246.cs2 new file mode 100644 index 0000000..1c01cc5 --- /dev/null +++ b/dumps/scripts/2246.cs2 @@ -0,0 +1,23 @@ +void script_2246(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + ivar4 = getItemIdInSlot(arg2, arg3); + if (ivar4 == -1) { + setWidgetIsHidden(true, new WidgetPointer(arg0)); + setWidgetIsHidden(false, new WidgetPointer(arg1)); + } + setWidgetIsHidden(false, new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(arg1)); + setItemOnWidgetMethod2200(ivar4, getItemAmtInSlot(94, arg3), new WidgetPointer(arg0)); + setWidgetNoOptions(new WidgetPointer(arg0)); + setScriptCallOnClickContextMenu(1620, new WidgetPointer(-32768,3), -1, 100, 0, 8, "Iiiii", new WidgetPointer(arg0)); + if (getItemHashmapData(ivar4, 1047) > 0) { + if ((getItemHashmapData(ivar4, 1050) > 0) || (getItemHashmapData(ivar4, 1051) > 0)) { + setWidgetContextMenuOption(3, new WidgetPointer(arg0), "Destroy"); + } else { + setWidgetContextMenuOption(3, new WidgetPointer(arg0), "Bind"); + } + } + setWidgetContextMenuOption(10, new WidgetPointer(arg0), "Examine"); + cs2method2305(new WidgetPointer(arg0), "" + getItemName(ivar4)); + return; +} diff --git a/dumps/scripts/2247.cs2 b/dumps/scripts/2247.cs2 new file mode 100644 index 0000000..46c7e19 --- /dev/null +++ b/dumps/scripts/2247.cs2 @@ -0,0 +1,77 @@ +void script_2247() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + ivar0 = 0; + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + ivar4 = 0; + ivar5 = 0; + ivar6 = 3016; + if (isMember()) { + ivar6 = 3015; + } + if (((boolean)mod(getCommonDefinitionSize(ivar6), 5))) { + ivar3 = multiply(divide(getCommonDefinitionSize(ivar6), 5), 67); + } else { + ivar3 = add(multiply(divide(getCommonDefinitionSize(ivar6), 5), 67), 67); + } + deleteAllExtraChilds(new WidgetPointer(940,1)); + setWidgetScrollMax(multiply(5, 60), ivar3, new WidgetPointer(940,1)); + while (ivar0 < getCommonDefinitionSize(ivar6)) { + createExtraChild(new WidgetPointer(940,2), 5, ivar4); + setWidgetContextMenuOption(1, getItemName(getOtherCommonData(cs2method_3408(105, 74, ivar6, ivar0), 1070))); + setScriptCallOnClickContextMenu(2250, ivar4, "i"); + ivar5 = ivar4; + ivar4 = add(ivar4, 1); + setWidgetSprite(2206); + if (getSkillActualLvl(24) < getOtherCommonData(cs2method_3408(105, 74, ivar6, ivar0), 1071)) { + setWidgetRGB(new Color(255, 0, 0)); + } + setWidgetSize(52, 55, 0, 0); + setWidgetPosition(multiply(ivar1, 60), subtract(multiply(ivar2, 67), 1), 0, 0); + setWidgetHidden(1); + createExtraChild(new WidgetPointer(940,2), 5, ivar4); + ivar4 = add(ivar4, 1); + setWidgetSprite(2205); + setWidgetSize(48, 52, 0, 0); + setWidgetPosition(add(multiply(ivar1, 60), 2), add(multiply(ivar2, 67), 1), 0, 0); + setScriptCallOnMouseOver(2248, ivar5, "i"); + setScriptCallOnMouseExit(2249, ivar5, "i"); + createExtraChild(new WidgetPointer(940,2), 5, ivar4); + ivar4 = add(ivar4, 1); + setWidgetSprite(2184); + setWidgetRGB(new Color(200, 0, 0)); + setWidgetSize(12, 12, 0, 0); + setWidgetPosition(add(multiply(ivar1, 60), 5), add(multiply(ivar2, 67), 40), 0, 0); + createExtraChild(new WidgetPointer(940,2), 4, ivar4); + ivar4 = add(ivar4, 1); + setWidgetRGB(new Color(226, 226, 162)); + setWidgetFont(494); + setWidgetUnknownBoolean(true); + setWidgetTextAlignment(1, 1, 0); + setWidgetText(script_940(getOtherCommonData(cs2method_3408(105, 74, ivar6, ivar0), 1072))); + setWidgetSize(31, 12, 0, 0); + setWidgetPosition(add(multiply(ivar1, 60), 18), add(multiply(ivar2, 67), 40), 0, 0); + createExtraChild(new WidgetPointer(940,2), 5, ivar4); + ivar4 = add(ivar4, 1); + setItemOnWidgetMethod1200(getOtherCommonData(cs2method_3408(105, 74, ivar6, divide(subtract(ivar4, 5), 5)), 1070), -1); + setWidgetSize(25, 25, 0, 0); + setWidgetPosition(add(multiply(ivar1, 60), 13), add(multiply(ivar2, 67), 9), 0, 0); + ivar1 = add(ivar1, 1); + if (ivar1 >= 5) { + ivar1 = 0; + ivar2 = add(ivar2, 1); + } + ivar0 = add(ivar0, 1); + } + if (((boolean)cs2method2601(new WidgetPointer(940,1)))) { + script_31(61603875, 61603841, 792, 789, 790, 791, 773, 788); + } + return; +} diff --git a/dumps/scripts/2248.cs2 b/dumps/scripts/2248.cs2 new file mode 100644 index 0000000..13da73d --- /dev/null +++ b/dumps/scripts/2248.cs2 @@ -0,0 +1,6 @@ +void script_2248(int arg0) { + if (setWidgetRegister(new WidgetPointer(940,2), arg0)) { + setWidgetHidden(0); + } + return; +} diff --git a/dumps/scripts/2249.cs2 b/dumps/scripts/2249.cs2 new file mode 100644 index 0000000..0d350da --- /dev/null +++ b/dumps/scripts/2249.cs2 @@ -0,0 +1,6 @@ +void script_2249(int arg0) { + if (setWidgetRegister(new WidgetPointer(940,2), arg0)) { + setWidgetHidden(1); + } + return; +} diff --git a/dumps/scripts/225.cs2 b/dumps/scripts/225.cs2 new file mode 100644 index 0000000..b414518 --- /dev/null +++ b/dumps/scripts/225.cs2 @@ -0,0 +1,6 @@ +void script_225() { + script_231(); + script_232(); + setWidgetIsHidden(false, new WidgetPointer(594,148)); + return; +} diff --git a/dumps/scripts/2250.cs2 b/dumps/scripts/2250.cs2 new file mode 100644 index 0000000..4d764b2 --- /dev/null +++ b/dumps/scripts/2250.cs2 @@ -0,0 +1,70 @@ +void script_2250(int arg0) { + int ivar1; + int ivar2; + flow_0: + ivar1 = divide(arg0, 5); + ivar2 = 3016; + if (isMember()) { + ivar2 = 3015; + } + IF (isMember()) + GOTO flow_3 + GOTO flow_4 + flow_3: + IF (ivar1 == 41) + GOTO flow_6 + flow_4: + IF (isMember() && (ivar1 == 17)) + GOTO flow_6 + GOTO flow_7 + flow_6: + setWidgetIsHidden(true, new WidgetPointer(940,42)); + setWidgetText(new WidgetPointer(940,40), getOtherCommonData(cs2method_3408(105, 74, ivar2, ivar1), 1078)); + setWidgetIsHidden(false, new WidgetPointer(940,43)); + setWidgetText(new WidgetPointer(940,43), getItemName(getOtherCommonData(cs2method_3408(105, 74, ivar2, ivar1), 1070))); + setWidgetIsHidden(false, new WidgetPointer(940,44)); + setItemOnWidgetMethod2200(getOtherCommonData(cs2method_3408(105, 74, ivar2, ivar1), 1070), -1, new WidgetPointer(940,44)); + setWidgetIsHidden(false, new WidgetPointer(940,41)); + setWidgetIsHidden(false, new WidgetPointer(940,66)); + setWidgetIsHidden(false, new WidgetPointer(940,64)); + setWidgetIsHidden(false, new WidgetPointer(940,62)); + setWidgetIsHidden(false, new WidgetPointer(940,63)); + setWidgetIsHidden(true, new WidgetPointer(940,67)); + setWidgetIsHidden(true, new WidgetPointer(940,68)); + setWidgetText(new WidgetPointer(940,62), "1 : 1xp"); + GOTO flow_10 + flow_7: + if (getSkillActualLvl(24) < getOtherCommonData(cs2method_3408(105, 74, ivar2, ivar1), 1071)) { + setWidgetIsHidden(true, new WidgetPointer(940,42)); + setWidgetText(new WidgetPointer(940,40), getOtherCommonData(cs2method_3408(105, 74, ivar2, ivar1), 1078)); + setWidgetIsHidden(false, new WidgetPointer(940,43)); + setWidgetText(new WidgetPointer(940,43), getItemName(getOtherCommonData(cs2method_3408(105, 74, ivar2, ivar1), 1070))); + setWidgetIsHidden(false, new WidgetPointer(940,44)); + setItemOnWidgetMethod2200(getOtherCommonData(cs2method_3408(105, 74, ivar2, ivar1), 1070), -1, new WidgetPointer(940,44)); + setWidgetIsHidden(false, new WidgetPointer(940,41)); + setWidgetIsHidden(true, new WidgetPointer(940,66)); + setWidgetIsHidden(true, new WidgetPointer(940,64)); + setWidgetIsHidden(true, new WidgetPointer(940,62)); + setWidgetIsHidden(true, new WidgetPointer(940,63)); + setWidgetIsHidden(false, new WidgetPointer(940,67)); + setWidgetIsHidden(false, new WidgetPointer(940,68)); + setWidgetText(new WidgetPointer(940,68), "Dungeoneering " + intToStr(getOtherCommonData(cs2method_3408(105, 74, ivar2, ivar1), 1071)) + " required"); + } else { + setWidgetIsHidden(true, new WidgetPointer(940,42)); + setWidgetText(new WidgetPointer(940,40), getOtherCommonData(cs2method_3408(105, 74, ivar2, ivar1), 1078)); + setWidgetIsHidden(false, new WidgetPointer(940,43)); + setWidgetText(new WidgetPointer(940,43), getItemName(getOtherCommonData(cs2method_3408(105, 74, ivar2, ivar1), 1070))); + setWidgetIsHidden(false, new WidgetPointer(940,44)); + setItemOnWidgetMethod2200(getOtherCommonData(cs2method_3408(105, 74, ivar2, ivar1), 1070), -1, new WidgetPointer(940,44)); + setWidgetIsHidden(false, new WidgetPointer(940,41)); + setWidgetIsHidden(false, new WidgetPointer(940,66)); + setWidgetIsHidden(false, new WidgetPointer(940,64)); + setWidgetIsHidden(false, new WidgetPointer(940,62)); + setWidgetIsHidden(false, new WidgetPointer(940,63)); + setWidgetIsHidden(true, new WidgetPointer(940,67)); + setWidgetIsHidden(true, new WidgetPointer(940,68)); + setWidgetText(new WidgetPointer(940,62), intToStr(getOtherCommonData(cs2method_3408(105, 74, ivar2, ivar1), 1072))); + } + flow_10: + return; +} diff --git a/dumps/scripts/2251.cs2 b/dumps/scripts/2251.cs2 new file mode 100644 index 0000000..e319e8f --- /dev/null +++ b/dumps/scripts/2251.cs2 @@ -0,0 +1,4 @@ +void script_2251(int arg0) { + setWidgetText(new WidgetPointer(arg0), "Deaths: " + intToStr(bitconfig_7554)); + return; +} diff --git a/dumps/scripts/2252.cs2 b/dumps/scripts/2252.cs2 new file mode 100644 index 0000000..cc0e57a --- /dev/null +++ b/dumps/scripts/2252.cs2 @@ -0,0 +1,4 @@ +void script_2252() { + script_2967(0); + return; +} diff --git a/dumps/scripts/2253.cs2 b/dumps/scripts/2253.cs2 new file mode 100644 index 0000000..a5f8e1a --- /dev/null +++ b/dumps/scripts/2253.cs2 @@ -0,0 +1,12 @@ +void script_2253() { + int ivar0; + setWidgetText(new WidgetPointer(945,14), globalstring_315); + if (globalint_1233 > 200) { + globalint_1233 = 200; + } + ivar0 = globalint_1233; + ivar0 = add(divide(multiply(ivar0, 37), 40), 14); + setWidgetSize(ivar0, 18, 1, 0, new WidgetPointer(945,16)); + setWidgetPosition(add(ivar0, 1), 15, 0, 0, new WidgetPointer(945,17)); + return; +} diff --git a/dumps/scripts/2254.cs2 b/dumps/scripts/2254.cs2 new file mode 100644 index 0000000..84219ae --- /dev/null +++ b/dumps/scripts/2254.cs2 @@ -0,0 +1,4 @@ +void script_2254(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 15 Agility"); + return; +} diff --git a/dumps/scripts/2255.cs2 b/dumps/scripts/2255.cs2 new file mode 100644 index 0000000..340f04d --- /dev/null +++ b/dumps/scripts/2255.cs2 @@ -0,0 +1,4 @@ +void script_2255(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 47 Agility"); + return; +} diff --git a/dumps/scripts/2256.cs2 b/dumps/scripts/2256.cs2 new file mode 100644 index 0000000..a36f5a2 --- /dev/null +++ b/dumps/scripts/2256.cs2 @@ -0,0 +1,4 @@ +void script_2256(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 64 Agility"); + return; +} diff --git a/dumps/scripts/2257.cs2 b/dumps/scripts/2257.cs2 new file mode 100644 index 0000000..dbe0088 --- /dev/null +++ b/dumps/scripts/2257.cs2 @@ -0,0 +1,4 @@ +void script_2257(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 60 Agility"); + return; +} diff --git a/dumps/scripts/2258.cs2 b/dumps/scripts/2258.cs2 new file mode 100644 index 0000000..7f745ae --- /dev/null +++ b/dumps/scripts/2258.cs2 @@ -0,0 +1,4 @@ +void script_2258(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 65 Agility" + "
" + "Requires the Priest in Peril quest"); + return; +} diff --git a/dumps/scripts/2259.cs2 b/dumps/scripts/2259.cs2 new file mode 100644 index 0000000..f2a223e --- /dev/null +++ b/dumps/scripts/2259.cs2 @@ -0,0 +1,4 @@ +void script_2259(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 29 Agility"); + return; +} diff --git a/dumps/scripts/226.cs2 b/dumps/scripts/226.cs2 new file mode 100644 index 0000000..b23b301 --- /dev/null +++ b/dumps/scripts/226.cs2 @@ -0,0 +1,13 @@ +void script_226() { + script_231(); + script_232(); + setWidgetIsHidden(false, new WidgetPointer(594,149)); + if (((boolean)getLanguage())) { + setWidgetIsHidden(false, new WidgetPointer(594,210)); + setWidgetIsHidden(true, new WidgetPointer(594,212)); + } else { + setWidgetIsHidden(true, new WidgetPointer(594,210)); + setWidgetIsHidden(false, new WidgetPointer(594,212)); + } + return; +} diff --git a/dumps/scripts/2260.cs2 b/dumps/scripts/2260.cs2 new file mode 100644 index 0000000..66478c8 --- /dev/null +++ b/dumps/scripts/2260.cs2 @@ -0,0 +1,175 @@ +void script_2260(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + ivar1 = getWidgetActualWidth(new WidgetPointer(arg0)); + ivar2 = getWidgetActualHeight(new WidgetPointer(arg0)); + ivar3 = 0; + ivar4 = 0; + ivar5 = 0; + ivar6 = 2987; + ivar7 = 2988; + if (isMember()) { + if (globalint_1320 == 2) { + ivar6 = 2989; + ivar7 = 2990; + } else if (globalint_1320 == 3) { + ivar6 = 2991; + ivar7 = 2992; + } else if (globalint_1320 == 4) { + ivar6 = 2993; + ivar7 = 2994; + } else { + ivar6 = 2987; + ivar7 = 2988; + } + } else if (globalint_1320 == 2) { + ivar6 = 2997; + ivar7 = 2998; + } else if (globalint_1320 == 3) { + ivar6 = 2999; + ivar7 = 3000; + } else if (globalint_1320 == 4) { + ivar6 = 3001; + ivar7 = 3002; + } else { + ivar6 = 2995; + ivar7 = 2996; + } + deleteAllExtraChilds(new WidgetPointer(arg0)); + deleteAllExtraChilds(new WidgetPointer(956,25)); + createExtraChild(new WidgetPointer(arg0), 4, ivar3); + ivar3 = add(ivar3, 1); + setWidgetSize(31, 12, 0, 0); + setWidgetPosition(0, 0, 0, 0); + setWidgetFont(494); + setWidgetTextAlignment(0, 1, 0); + setWidgetText("Resources:"); + setWidgetRGB(new Color(198, 155, 1)); + setWidgetUnknownBoolean(true); + createExtraChild(new WidgetPointer(arg0), 5, ivar3); + ivar3 = add(ivar3, 1); + setWidgetSize(160, 12, 0, 0); + setWidgetPosition(0, 7, 0, 0); + setWidgetSprite(1074); + ivar5 = add(ivar5, 20); + ivar8 = ivar3; + while (subtract(ivar3, ivar8) < multiply(getCommonDefinitionSize(ivar6), 5)) { + createExtraChild(new WidgetPointer(arg0), 5, ivar3); + setWidgetSize(48, 52, 0, 0); + setWidgetPosition(ivar4, ivar5, 0, 0); + setWidgetSprite(2205); + cs2method1305("" + getItemName(cs2method_3408(105, 79, ivar6, divide(subtract(ivar3, ivar8), 5))) + ""); + setWidgetContextMenuOption(1, "Info"); + setWidgetContextMenuOption(2, "Buy 1"); + setWidgetContextMenuOption(3, "Buy 5"); + setWidgetContextMenuOption(4, "Buy 10"); + setWidgetContextMenuOption(5, "Buy 50"); + setWidgetContextMenuOption(6, "Buy 250"); + setWidgetContextMenuOption(10, "Examine"); + setScriptCallOnMouseEntered(2261, new WidgetPointer(-32768,3), add(ivar3, 1), 0, "Ii1"); + setScriptCallOnMouseExit(2261, new WidgetPointer(-32768,3), add(ivar3, 1), 1, "Ii1"); + createExtraChild(new WidgetPointer(arg0), 5, add(ivar3, 1)); + setWidgetSize(48, 52, 0, 0); + setWidgetPosition(ivar4, ivar5, 0, 0); + setWidgetSprite(2206); + setWidgetHidden(1); + createExtraChild(new WidgetPointer(arg0), 5, add(ivar3, 2)); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(add(ivar4, 6), add(ivar5, 4), 0, 0); + setItemOnWidgetMethod1205(cs2method_3408(105, 79, ivar6, divide(subtract(ivar3, ivar8), 5)), 1); + setWidgetShadowColor(new Color(48, 32, 32)); + setWidgetBorderThickness(1); + createExtraChild(new WidgetPointer(arg0), 5, add(ivar3, 3)); + setWidgetSize(12, 12, 0, 0); + setWidgetPosition(add(ivar4, 2), add(ivar5, 38), 0, 0); + setWidgetSprite(2181); + createExtraChild(new WidgetPointer(arg0), 4, add(ivar3, 4)); + setWidgetSize(31, 12, 0, 0); + setWidgetPosition(add(ivar4, 13), add(ivar5, 39), 0, 0); + setWidgetFont(494); + setWidgetTextAlignment(2, 1, 0); + setWidgetText(script_940(script_2262(cs2method_3408(105, 79, ivar6, divide(subtract(ivar3, ivar8), 5))))); + setWidgetRGB(new Color(226, 226, 162)); + setWidgetUnknownBoolean(true); + ivar4 = add(ivar4, 50); + if (add(ivar4, 48) > ivar1) { + ivar4 = 0; + ivar5 = add(ivar5, 54); + } + ivar3 = add(ivar3, 5); + } + if (ivar4 != 0) { + ivar4 = 0; + ivar5 = add(ivar5, 52); + } + createExtraChild(new WidgetPointer(arg0), 4, ivar3); + ivar3 = add(ivar3, 1); + setWidgetSize(31, 12, 0, 0); + setWidgetPosition(0, add(ivar5, 10), 0, 0); + setWidgetFont(494); + setWidgetTextAlignment(0, 1, 0); + setWidgetText("Tools:"); + setWidgetRGB(new Color(198, 155, 1)); + setWidgetUnknownBoolean(true); + createExtraChild(new WidgetPointer(arg0), 5, ivar3); + ivar3 = add(ivar3, 1); + setWidgetSize(160, 12, 0, 0); + setWidgetPosition(0, add(ivar5, 17), 0, 0); + setWidgetSprite(1074); + ivar5 = add(ivar5, 30); + ivar8 = ivar3; + while (subtract(ivar3, ivar8) < multiply(getCommonDefinitionSize(ivar7), 5)) { + createExtraChild(new WidgetPointer(arg0), 5, ivar3); + setWidgetSize(48, 52, 0, 0); + setWidgetPosition(ivar4, ivar5, 0, 0); + setWidgetSprite(2205); + cs2method1305("" + getItemName(cs2method_3408(105, 79, ivar7, divide(subtract(ivar3, ivar8), 5))) + ""); + setWidgetContextMenuOption(1, "Info"); + setWidgetContextMenuOption(2, "Buy 1"); + setWidgetContextMenuOption(3, "Buy 5"); + setWidgetContextMenuOption(4, "Buy 10"); + setWidgetContextMenuOption(5, "Buy 50"); + setWidgetContextMenuOption(6, "Buy 250"); + setWidgetContextMenuOption(10, "Examine"); + setScriptCallOnMouseEntered(2261, new WidgetPointer(-32768,3), add(ivar3, 1), 0, "Ii1"); + setScriptCallOnMouseExit(2261, new WidgetPointer(-32768,3), add(ivar3, 1), 1, "Ii1"); + createExtraChild(new WidgetPointer(arg0), 5, add(ivar3, 1)); + setWidgetSize(48, 52, 0, 0); + setWidgetPosition(ivar4, ivar5, 0, 0); + setWidgetSprite(2206); + setWidgetHidden(1); + createExtraChild(new WidgetPointer(arg0), 5, add(ivar3, 2)); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(add(ivar4, 6), add(ivar5, 4), 0, 0); + setItemOnWidgetMethod1205(cs2method_3408(105, 79, ivar7, divide(subtract(ivar3, ivar8), 5)), 1); + setWidgetShadowColor(new Color(48, 32, 32)); + setWidgetBorderThickness(1); + createExtraChild(new WidgetPointer(arg0), 5, add(ivar3, 3)); + setWidgetSize(12, 12, 0, 0); + setWidgetPosition(add(ivar4, 2), add(ivar5, 38), 0, 0); + setWidgetSprite(2181); + createExtraChild(new WidgetPointer(arg0), 4, add(ivar3, 4)); + setWidgetSize(31, 12, 0, 0); + setWidgetPosition(add(ivar4, 13), add(ivar5, 39), 0, 0); + setWidgetFont(494); + setWidgetTextAlignment(2, 1, 0); + setWidgetText(script_940(script_2262(cs2method_3408(105, 79, ivar7, divide(subtract(ivar3, ivar8), 5))))); + setWidgetRGB(new Color(226, 226, 162)); + setWidgetUnknownBoolean(true); + ivar4 = add(ivar4, 50); + if (add(ivar4, 48) > ivar1) { + ivar4 = 0; + ivar5 = add(ivar5, 54); + } + ivar3 = add(ivar3, 5); + } + setWidgetScrollMax(0, add(ivar5, 52), new WidgetPointer(arg0)); + script_31(62652441, arg0, 792, 789, 790, 791, 773, 788); + return; +} diff --git a/dumps/scripts/2261.cs2 b/dumps/scripts/2261.cs2 new file mode 100644 index 0000000..4b515b3 --- /dev/null +++ b/dumps/scripts/2261.cs2 @@ -0,0 +1,6 @@ +void script_2261(int arg0,int arg1,int arg2) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetHidden(arg2); + } + return; +} diff --git a/dumps/scripts/2262.cs2 b/dumps/scripts/2262.cs2 new file mode 100644 index 0000000..cdb306d --- /dev/null +++ b/dumps/scripts/2262.cs2 @@ -0,0 +1,3 @@ +int script_2262(int arg0) { + return multiplyDivide(getItemValue(arg0), 100, getItemHashmapData(arg0, 1046)); +} diff --git a/dumps/scripts/2263.cs2 b/dumps/scripts/2263.cs2 new file mode 100644 index 0000000..f6212e5 --- /dev/null +++ b/dumps/scripts/2263.cs2 @@ -0,0 +1,14 @@ +void script_2263(int arg0,int arg1,string arg2,string arg3) { + if (arg1 != 1) { + setWidgetContextMenuOption(1, new WidgetPointer(arg0), "Make 1 " + arg3 + "(" + intToStr(arg1) + ") "); + setWidgetContextMenuOption(2, new WidgetPointer(arg0), "Make 5 " + arg3 + "(" + intToStr(multiply(arg1, 5)) + ")"); + setWidgetContextMenuOption(3, new WidgetPointer(arg0), "Make X " + arg3); + setWidgetContextMenuOption(4, new WidgetPointer(arg0), "Make All " + arg3); + return; + } + setWidgetContextMenuOption(1, new WidgetPointer(arg0), "Make 1 " + arg2); + setWidgetContextMenuOption(2, new WidgetPointer(arg0), "Make 5 " + arg3); + setWidgetContextMenuOption(3, new WidgetPointer(arg0), "Make X " + arg3); + setWidgetContextMenuOption(4, new WidgetPointer(arg0), "Make All " + arg3); + return; +} diff --git a/dumps/scripts/2264.cs2 b/dumps/scripts/2264.cs2 new file mode 100644 index 0000000..9d4e1e8 --- /dev/null +++ b/dumps/scripts/2264.cs2 @@ -0,0 +1,43 @@ +void script_2264() { + setWidgetIsHidden(true, new WidgetPointer(944,78)); + setWidgetIsHidden(true, new WidgetPointer(944,79)); + setWidgetIsHidden(true, new WidgetPointer(944,80)); + cs2method2310(new WidgetPointer(944,81), "Make"); + setWidgetIsHidden(true, new WidgetPointer(944,25)); + setWidgetIsHidden(true, new WidgetPointer(944,26)); + setWidgetIsHidden(true, new WidgetPointer(944,27)); + cs2method2310(new WidgetPointer(944,28), "Make"); + setWidgetIsHidden(true, new WidgetPointer(944,31)); + setWidgetIsHidden(true, new WidgetPointer(944,32)); + setWidgetIsHidden(true, new WidgetPointer(944,33)); + cs2method2310(new WidgetPointer(944,34), "Make"); + setWidgetIsHidden(true, new WidgetPointer(944,37)); + setWidgetIsHidden(true, new WidgetPointer(944,38)); + setWidgetIsHidden(true, new WidgetPointer(944,39)); + cs2method2310(new WidgetPointer(944,40), "Make"); + setWidgetIsHidden(true, new WidgetPointer(944,43)); + setWidgetIsHidden(true, new WidgetPointer(944,44)); + setWidgetIsHidden(true, new WidgetPointer(944,45)); + cs2method2310(new WidgetPointer(944,46), "Make"); + setWidgetIsHidden(true, new WidgetPointer(944,49)); + setWidgetIsHidden(true, new WidgetPointer(944,50)); + setWidgetIsHidden(true, new WidgetPointer(944,51)); + cs2method2310(new WidgetPointer(944,52), "Make"); + setWidgetIsHidden(true, new WidgetPointer(944,55)); + setWidgetIsHidden(true, new WidgetPointer(944,56)); + setWidgetIsHidden(true, new WidgetPointer(944,57)); + cs2method2310(new WidgetPointer(944,58), "Make"); + setWidgetIsHidden(true, new WidgetPointer(944,61)); + setWidgetIsHidden(true, new WidgetPointer(944,62)); + setWidgetIsHidden(true, new WidgetPointer(944,63)); + cs2method2310(new WidgetPointer(944,64), "Make"); + setWidgetIsHidden(true, new WidgetPointer(944,67)); + setWidgetIsHidden(true, new WidgetPointer(944,68)); + setWidgetIsHidden(true, new WidgetPointer(944,69)); + cs2method2310(new WidgetPointer(944,70), "Make"); + setWidgetIsHidden(true, new WidgetPointer(944,73)); + setWidgetIsHidden(true, new WidgetPointer(944,74)); + setWidgetIsHidden(true, new WidgetPointer(944,75)); + cs2method2310(new WidgetPointer(944,76), "Make"); + return; +} diff --git a/dumps/scripts/2265.cs2 b/dumps/scripts/2265.cs2 new file mode 100644 index 0000000..10610ce --- /dev/null +++ b/dumps/scripts/2265.cs2 @@ -0,0 +1,55 @@ +void script_2265(int arg0) { + setWidgetIsHidden(false, new WidgetPointer(arg0)); + switch (arg0) { + case 61866061: + if (globalint_755 != -1) { + setItemOnWidgetMethod2208(globalint_755, -1, new WidgetPointer(arg0)); + } + break; + case 61866008: + if (globalint_756 != -1) { + setItemOnWidgetMethod2208(globalint_756, -1, new WidgetPointer(arg0)); + } + break; + case 61866014: + if (globalint_757 != -1) { + setItemOnWidgetMethod2208(globalint_757, -1, new WidgetPointer(arg0)); + } + break; + case 61866020: + if (globalint_758 != -1) { + setItemOnWidgetMethod2208(globalint_758, -1, new WidgetPointer(arg0)); + } + break; + case 61866026: + if (globalint_759 != -1) { + setItemOnWidgetMethod2208(globalint_759, -1, new WidgetPointer(arg0)); + } + break; + case 61866032: + if (globalint_760 != -1) { + setItemOnWidgetMethod2208(globalint_760, -1, new WidgetPointer(arg0)); + } + break; + case 61866038: + if (globalint_1139 != -1) { + setItemOnWidgetMethod2208(globalint_1139, -1, new WidgetPointer(arg0)); + } + break; + case 61866044: + if (globalint_1140 != -1) { + setItemOnWidgetMethod2208(globalint_1140, -1, new WidgetPointer(arg0)); + } + break; + case 61866050: + if (globalint_1141 != -1) { + setItemOnWidgetMethod2208(globalint_1141, -1, new WidgetPointer(arg0)); + } + break; + case 61866056: + if (globalint_1142 != -1) { + setItemOnWidgetMethod2208(globalint_1142, -1, new WidgetPointer(arg0)); + } + } + return; +} diff --git a/dumps/scripts/2266.cs2 b/dumps/scripts/2266.cs2 new file mode 100644 index 0000000..24a5b5e --- /dev/null +++ b/dumps/scripts/2266.cs2 @@ -0,0 +1,54 @@ +void script_2266(int arg0) { + switch (arg0) { + case 61866061: + if (stringMethod4107("", globalstring_132) != 0) { + setWidgetText(new WidgetPointer(944,15), globalstring_132); + } + break; + case 61866008: + if (stringMethod4107("", globalstring_133) != 0) { + setWidgetText(new WidgetPointer(944,15), globalstring_133); + } + break; + case 61866014: + if (stringMethod4107("", globalstring_134) != 0) { + setWidgetText(new WidgetPointer(944,15), globalstring_134); + } + break; + case 61866020: + if (stringMethod4107("", globalstring_135) != 0) { + setWidgetText(new WidgetPointer(944,15), globalstring_135); + } + break; + case 61866026: + if (stringMethod4107("", globalstring_136) != 0) { + setWidgetText(new WidgetPointer(944,15), globalstring_136); + } + break; + case 61866032: + if (stringMethod4107("", globalstring_137) != 0) { + setWidgetText(new WidgetPointer(944,15), globalstring_137); + } + break; + case 61866038: + if (stringMethod4107("", globalstring_280) != 0) { + setWidgetText(new WidgetPointer(944,15), globalstring_280); + } + break; + case 61866044: + if (stringMethod4107("", globalstring_281) != 0) { + setWidgetText(new WidgetPointer(944,15), globalstring_281); + } + break; + case 61866050: + if (stringMethod4107("", globalstring_282) != 0) { + setWidgetText(new WidgetPointer(944,15), globalstring_282); + } + break; + case 61866056: + if (stringMethod4107("", globalstring_283) != 0) { + setWidgetText(new WidgetPointer(944,15), globalstring_283); + } + } + return; +} diff --git a/dumps/scripts/2267.cs2 b/dumps/scripts/2267.cs2 new file mode 100644 index 0000000..54daf6a --- /dev/null +++ b/dumps/scripts/2267.cs2 @@ -0,0 +1,4 @@ +void script_2267(int arg0) { + setWidgetText(new WidgetPointer(arg0), globalstring_131); + return; +} diff --git a/dumps/scripts/2268.cs2 b/dumps/scripts/2268.cs2 new file mode 100644 index 0000000..2fcff39 --- /dev/null +++ b/dumps/scripts/2268.cs2 @@ -0,0 +1,8 @@ +void script_2268(int arg0) { + if (((boolean)standart_config_170)) { + setWidgetText(new WidgetPointer(arg0), "Right-click the object to see more options."); + } else { + setWidgetText(new WidgetPointer(arg0), "Click the object to see more options."); + } + return; +} diff --git a/dumps/scripts/2269.cs2 b/dumps/scripts/2269.cs2 new file mode 100644 index 0000000..049facf --- /dev/null +++ b/dumps/scripts/2269.cs2 @@ -0,0 +1,190 @@ +void script_2269() { + script_2270(); + switch (globalint_754) { + case 1: + setWidgetIsHidden(false, new WidgetPointer(944,22)); + setWidgetPosition(0, 23, 1, 0, new WidgetPointer(944,22)); + setWidgetSize(200, 105, 0, 0, new WidgetPointer(944,22)); + break; + case 2: + setWidgetIsHidden(false, new WidgetPointer(944,22)); + setWidgetIsHidden(false, new WidgetPointer(944,23)); + setWidgetPosition(-130, 23, 1, 0, new WidgetPointer(944,22)); + setWidgetPosition(130, 23, 1, 0, new WidgetPointer(944,23)); + setWidgetSize(150, 105, 0, 0, new WidgetPointer(944,22)); + setWidgetSize(150, 105, 0, 0, new WidgetPointer(944,23)); + break; + case 3: + setWidgetIsHidden(false, new WidgetPointer(944,22)); + setWidgetIsHidden(false, new WidgetPointer(944,23)); + setWidgetIsHidden(false, new WidgetPointer(944,29)); + setWidgetPosition(-150, 23, 1, 0, new WidgetPointer(944,22)); + setWidgetPosition(0, 23, 1, 0, new WidgetPointer(944,23)); + setWidgetPosition(150, 23, 1, 0, new WidgetPointer(944,29)); + setWidgetSize(120, 105, 0, 0, new WidgetPointer(944,22)); + setWidgetSize(120, 105, 0, 0, new WidgetPointer(944,23)); + setWidgetSize(120, 105, 0, 0, new WidgetPointer(944,29)); + break; + case 4: + setWidgetIsHidden(false, new WidgetPointer(944,22)); + setWidgetIsHidden(false, new WidgetPointer(944,23)); + setWidgetIsHidden(false, new WidgetPointer(944,29)); + setWidgetIsHidden(false, new WidgetPointer(944,35)); + setWidgetPosition(-180, 23, 1, 0, new WidgetPointer(944,22)); + setWidgetPosition(-60, 23, 1, 0, new WidgetPointer(944,23)); + setWidgetPosition(60, 23, 1, 0, new WidgetPointer(944,29)); + setWidgetPosition(180, 23, 1, 0, new WidgetPointer(944,35)); + setWidgetSize(100, 105, 0, 0, new WidgetPointer(944,22)); + setWidgetSize(100, 105, 0, 0, new WidgetPointer(944,23)); + setWidgetSize(100, 105, 0, 0, new WidgetPointer(944,29)); + setWidgetSize(100, 105, 0, 0, new WidgetPointer(944,35)); + break; + case 5: + setWidgetIsHidden(false, new WidgetPointer(944,22)); + setWidgetIsHidden(false, new WidgetPointer(944,23)); + setWidgetIsHidden(false, new WidgetPointer(944,29)); + setWidgetIsHidden(false, new WidgetPointer(944,35)); + setWidgetIsHidden(false, new WidgetPointer(944,41)); + setWidgetPosition(-200, 23, 1, 0, new WidgetPointer(944,22)); + setWidgetPosition(-100, 23, 1, 0, new WidgetPointer(944,23)); + setWidgetPosition(0, 23, 1, 0, new WidgetPointer(944,29)); + setWidgetPosition(100, 23, 1, 0, new WidgetPointer(944,35)); + setWidgetPosition(200, 23, 1, 0, new WidgetPointer(944,41)); + setWidgetSize(90, 105, 0, 0, new WidgetPointer(944,22)); + setWidgetSize(90, 105, 0, 0, new WidgetPointer(944,23)); + setWidgetSize(90, 105, 0, 0, new WidgetPointer(944,29)); + setWidgetSize(90, 105, 0, 0, new WidgetPointer(944,35)); + setWidgetSize(90, 105, 0, 0, new WidgetPointer(944,41)); + break; + case 6: + setWidgetIsHidden(false, new WidgetPointer(944,22)); + setWidgetIsHidden(false, new WidgetPointer(944,23)); + setWidgetIsHidden(false, new WidgetPointer(944,29)); + setWidgetIsHidden(false, new WidgetPointer(944,35)); + setWidgetIsHidden(false, new WidgetPointer(944,41)); + setWidgetIsHidden(false, new WidgetPointer(944,47)); + setWidgetPosition(-210, 23, 1, 0, new WidgetPointer(944,22)); + setWidgetPosition(-124, 23, 1, 0, new WidgetPointer(944,23)); + setWidgetPosition(-42, 23, 1, 0, new WidgetPointer(944,29)); + setWidgetPosition(42, 23, 1, 0, new WidgetPointer(944,35)); + setWidgetPosition(124, 23, 1, 0, new WidgetPointer(944,41)); + setWidgetPosition(210, 23, 1, 0, new WidgetPointer(944,47)); + setWidgetSize(85, 105, 0, 0, new WidgetPointer(944,22)); + setWidgetSize(85, 105, 0, 0, new WidgetPointer(944,23)); + setWidgetSize(85, 105, 0, 0, new WidgetPointer(944,29)); + setWidgetSize(85, 105, 0, 0, new WidgetPointer(944,35)); + setWidgetSize(85, 105, 0, 0, new WidgetPointer(944,41)); + setWidgetSize(85, 105, 0, 0, new WidgetPointer(944,47)); + break; + case 7: + setWidgetIsHidden(false, new WidgetPointer(944,22)); + setWidgetIsHidden(false, new WidgetPointer(944,23)); + setWidgetIsHidden(false, new WidgetPointer(944,29)); + setWidgetIsHidden(false, new WidgetPointer(944,35)); + setWidgetIsHidden(false, new WidgetPointer(944,41)); + setWidgetIsHidden(false, new WidgetPointer(944,47)); + setWidgetIsHidden(false, new WidgetPointer(944,53)); + setWidgetPosition(-210, 23, 1, 0, new WidgetPointer(944,22)); + setWidgetPosition(-140, 23, 1, 0, new WidgetPointer(944,23)); + setWidgetPosition(-70, 23, 1, 0, new WidgetPointer(944,29)); + setWidgetPosition(0, 23, 1, 0, new WidgetPointer(944,35)); + setWidgetPosition(70, 23, 1, 0, new WidgetPointer(944,41)); + setWidgetPosition(140, 23, 1, 0, new WidgetPointer(944,47)); + setWidgetPosition(210, 23, 1, 0, new WidgetPointer(944,53)); + setWidgetSize(70, 105, 0, 0, new WidgetPointer(944,22)); + setWidgetSize(70, 105, 0, 0, new WidgetPointer(944,23)); + setWidgetSize(70, 105, 0, 0, new WidgetPointer(944,29)); + setWidgetSize(70, 105, 0, 0, new WidgetPointer(944,35)); + setWidgetSize(70, 105, 0, 0, new WidgetPointer(944,41)); + setWidgetSize(70, 105, 0, 0, new WidgetPointer(944,47)); + setWidgetSize(70, 105, 0, 0, new WidgetPointer(944,53)); + break; + case 8: + setWidgetIsHidden(false, new WidgetPointer(944,22)); + setWidgetIsHidden(false, new WidgetPointer(944,23)); + setWidgetIsHidden(false, new WidgetPointer(944,29)); + setWidgetIsHidden(false, new WidgetPointer(944,35)); + setWidgetIsHidden(false, new WidgetPointer(944,41)); + setWidgetIsHidden(false, new WidgetPointer(944,47)); + setWidgetIsHidden(false, new WidgetPointer(944,53)); + setWidgetIsHidden(false, new WidgetPointer(944,59)); + setWidgetPosition(-210, 23, 1, 0, new WidgetPointer(944,22)); + setWidgetPosition(-150, 23, 1, 0, new WidgetPointer(944,23)); + setWidgetPosition(-90, 23, 1, 0, new WidgetPointer(944,29)); + setWidgetPosition(-30, 23, 1, 0, new WidgetPointer(944,35)); + setWidgetPosition(30, 23, 1, 0, new WidgetPointer(944,41)); + setWidgetPosition(90, 23, 1, 0, new WidgetPointer(944,47)); + setWidgetPosition(150, 23, 1, 0, new WidgetPointer(944,53)); + setWidgetPosition(210, 23, 1, 0, new WidgetPointer(944,59)); + setWidgetSize(60, 105, 0, 0, new WidgetPointer(944,22)); + setWidgetSize(60, 105, 0, 0, new WidgetPointer(944,23)); + setWidgetSize(60, 105, 0, 0, new WidgetPointer(944,29)); + setWidgetSize(60, 105, 0, 0, new WidgetPointer(944,35)); + setWidgetSize(60, 105, 0, 0, new WidgetPointer(944,41)); + setWidgetSize(60, 105, 0, 0, new WidgetPointer(944,47)); + setWidgetSize(60, 105, 0, 0, new WidgetPointer(944,53)); + setWidgetSize(60, 105, 0, 0, new WidgetPointer(944,59)); + break; + case 9: + setWidgetIsHidden(false, new WidgetPointer(944,22)); + setWidgetIsHidden(false, new WidgetPointer(944,23)); + setWidgetIsHidden(false, new WidgetPointer(944,29)); + setWidgetIsHidden(false, new WidgetPointer(944,35)); + setWidgetIsHidden(false, new WidgetPointer(944,41)); + setWidgetIsHidden(false, new WidgetPointer(944,47)); + setWidgetIsHidden(false, new WidgetPointer(944,53)); + setWidgetIsHidden(false, new WidgetPointer(944,59)); + setWidgetIsHidden(false, new WidgetPointer(944,65)); + setWidgetPosition(-220, 23, 1, 0, new WidgetPointer(944,22)); + setWidgetPosition(-165, 23, 1, 0, new WidgetPointer(944,23)); + setWidgetPosition(-110, 23, 1, 0, new WidgetPointer(944,29)); + setWidgetPosition(-55, 23, 1, 0, new WidgetPointer(944,35)); + setWidgetPosition(0, 23, 1, 0, new WidgetPointer(944,41)); + setWidgetPosition(55, 23, 1, 0, new WidgetPointer(944,47)); + setWidgetPosition(110, 23, 1, 0, new WidgetPointer(944,53)); + setWidgetPosition(165, 23, 1, 0, new WidgetPointer(944,59)); + setWidgetPosition(220, 23, 1, 0, new WidgetPointer(944,65)); + setWidgetSize(55, 105, 0, 0, new WidgetPointer(944,22)); + setWidgetSize(55, 105, 0, 0, new WidgetPointer(944,23)); + setWidgetSize(55, 105, 0, 0, new WidgetPointer(944,29)); + setWidgetSize(55, 105, 0, 0, new WidgetPointer(944,35)); + setWidgetSize(55, 105, 0, 0, new WidgetPointer(944,41)); + setWidgetSize(55, 105, 0, 0, new WidgetPointer(944,47)); + setWidgetSize(55, 105, 0, 0, new WidgetPointer(944,53)); + setWidgetSize(55, 105, 0, 0, new WidgetPointer(944,59)); + setWidgetSize(55, 105, 0, 0, new WidgetPointer(944,65)); + break; + case 10: + setWidgetIsHidden(false, new WidgetPointer(944,22)); + setWidgetIsHidden(false, new WidgetPointer(944,23)); + setWidgetIsHidden(false, new WidgetPointer(944,29)); + setWidgetIsHidden(false, new WidgetPointer(944,35)); + setWidgetIsHidden(false, new WidgetPointer(944,41)); + setWidgetIsHidden(false, new WidgetPointer(944,47)); + setWidgetIsHidden(false, new WidgetPointer(944,53)); + setWidgetIsHidden(false, new WidgetPointer(944,59)); + setWidgetIsHidden(false, new WidgetPointer(944,65)); + setWidgetIsHidden(false, new WidgetPointer(944,71)); + setWidgetPosition(-225, 23, 1, 0, new WidgetPointer(944,22)); + setWidgetPosition(-175, 23, 1, 0, new WidgetPointer(944,23)); + setWidgetPosition(-125, 23, 1, 0, new WidgetPointer(944,29)); + setWidgetPosition(-75, 23, 1, 0, new WidgetPointer(944,35)); + setWidgetPosition(-25, 23, 1, 0, new WidgetPointer(944,41)); + setWidgetPosition(25, 23, 1, 0, new WidgetPointer(944,47)); + setWidgetPosition(75, 23, 1, 0, new WidgetPointer(944,53)); + setWidgetPosition(125, 23, 1, 0, new WidgetPointer(944,59)); + setWidgetPosition(175, 23, 1, 0, new WidgetPointer(944,65)); + setWidgetPosition(225, 23, 1, 0, new WidgetPointer(944,71)); + setWidgetSize(50, 105, 0, 0, new WidgetPointer(944,22)); + setWidgetSize(50, 105, 0, 0, new WidgetPointer(944,23)); + setWidgetSize(50, 105, 0, 0, new WidgetPointer(944,29)); + setWidgetSize(50, 105, 0, 0, new WidgetPointer(944,35)); + setWidgetSize(50, 105, 0, 0, new WidgetPointer(944,41)); + setWidgetSize(50, 105, 0, 0, new WidgetPointer(944,47)); + setWidgetSize(50, 105, 0, 0, new WidgetPointer(944,53)); + setWidgetSize(50, 105, 0, 0, new WidgetPointer(944,59)); + setWidgetSize(50, 105, 0, 0, new WidgetPointer(944,65)); + setWidgetSize(50, 105, 0, 0, new WidgetPointer(944,71)); + } + return; +} diff --git a/dumps/scripts/227.cs2 b/dumps/scripts/227.cs2 new file mode 100644 index 0000000..562dda0 --- /dev/null +++ b/dumps/scripts/227.cs2 @@ -0,0 +1,6 @@ +void script_227() { + script_231(); + script_232(); + setWidgetIsHidden(false, new WidgetPointer(594,150)); + return; +} diff --git a/dumps/scripts/2270.cs2 b/dumps/scripts/2270.cs2 new file mode 100644 index 0000000..fb7be70 --- /dev/null +++ b/dumps/scripts/2270.cs2 @@ -0,0 +1,13 @@ +void script_2270() { + setWidgetIsHidden(true, new WidgetPointer(944,22)); + setWidgetIsHidden(true, new WidgetPointer(944,23)); + setWidgetIsHidden(true, new WidgetPointer(944,29)); + setWidgetIsHidden(true, new WidgetPointer(944,35)); + setWidgetIsHidden(true, new WidgetPointer(944,41)); + setWidgetIsHidden(true, new WidgetPointer(944,47)); + setWidgetIsHidden(true, new WidgetPointer(944,53)); + setWidgetIsHidden(true, new WidgetPointer(944,59)); + setWidgetIsHidden(true, new WidgetPointer(944,65)); + setWidgetIsHidden(true, new WidgetPointer(944,71)); + return; +} diff --git a/dumps/scripts/2271.cs2 b/dumps/scripts/2271.cs2 new file mode 100644 index 0000000..6239cee --- /dev/null +++ b/dumps/scripts/2271.cs2 @@ -0,0 +1,13 @@ +void script_2271(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12,int arg13,string arg14,string arg15) { + cs2method2305(new WidgetPointer(arg0), "" + arg14); + script_2273(arg0, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); + setScriptCallOnMouseOver(2274, new WidgetPointer(arg0), new WidgetPointer(arg1), arg4, arg14, arg15, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, "IIissoioioioi", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(11, new WidgetPointer(arg1), "I", new WidgetPointer(arg0)); + if (cs2method2800(new WidgetPointer(arg0)) != 0) { + setScriptCallOnUse(17, new WidgetPointer(arg0), "I", new WidgetPointer(arg0)); + setScriptCallOnUseWith(18, new WidgetPointer(arg0), "I", new WidgetPointer(arg0)); + } + setScriptCallOnItemContainerUpdate(2272, new WidgetPointer(arg0), arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, 93, 1, "Iddi1oioioioiY", new WidgetPointer(arg0)); + setScriptCallOnSkillChange(2272, new WidgetPointer(arg0), arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, 6, 1, "Iddi1oioioioiY", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/2272.cs2 b/dumps/scripts/2272.cs2 new file mode 100644 index 0000000..c47092c --- /dev/null +++ b/dumps/scripts/2272.cs2 @@ -0,0 +1,4 @@ +void script_2272(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12) { + script_2273(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); + return; +} diff --git a/dumps/scripts/2273.cs2 b/dumps/scripts/2273.cs2 new file mode 100644 index 0000000..58a76a9 --- /dev/null +++ b/dumps/scripts/2273.cs2 @@ -0,0 +1,19 @@ +void script_2273(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12) { + if ((getSkillCurrentLvl(6) < arg3) && (((boolean)arg4) || (getSkillActualLvl(6) < arg3))) { + if (((boolean)bitconfig_4089)) { + if ((standart_config_1092 < arg3) || ((boolean)cs2method_3408(73, 105, 1061, arg0))) { + setWidgetSprite(arg2, new WidgetPointer(arg0)); + return; + } + } else { + setWidgetSprite(arg2, new WidgetPointer(arg0)); + return; + } + } + if (standart_config_1795 == -1) { + setWidgetSprite(arg2, new WidgetPointer(arg0)); + return; + } + setWidgetSprite(arg1, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/2274.cs2 b/dumps/scripts/2274.cs2 new file mode 100644 index 0000000..7fcc63d --- /dev/null +++ b/dumps/scripts/2274.cs2 @@ -0,0 +1,74 @@ +void script_2274(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,string arg11,string arg12) { + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + deleteAllExtraChilds(new WidgetPointer(arg1)); + ivar11 = add(2, multiply(13, getLineCount(177, 495, "Level " + intToStr(arg2) + ": " + arg11))); + ivar12 = add(2, multiply(13, getLineCount(177, 494, arg12))); + ivar13 = add(add(add(add(add(2, ivar11), ivar12), 32), 14), 2); + if (arg3 == -1) { + ivar13 = subtract(subtract(ivar13, 32), 14); + } + ivar14 = 5; + if (getWidgetActualY(new WidgetPointer(arg0)) < 130) { + ivar14 = subtract(subtract(261, ivar13), 5); + } + createExtraChild(new WidgetPointer(arg1), 3, 0); + setWidgetPosition(5, ivar14, 0, 0); + setWidgetSize(180, ivar13, 0, 0); + setWidgetFilled(1); + setWidgetRGB(new Color(0, 0, 0)); + cs2method2103(42); + createExtraChild(new WidgetPointer(arg1), 3, 1); + setWidgetPosition(6, add(ivar14, 1), 0, 0); + setWidgetSize(179, subtract(ivar13, 1), 0, 0); + setWidgetFilled(0); + setWidgetRGB(new Color(46, 43, 35)); + createExtraChild(new WidgetPointer(arg1), 3, 2); + setWidgetPosition(5, ivar14, 0, 0); + setWidgetSize(179, subtract(ivar13, 1), 0, 0); + setWidgetFilled(0); + setWidgetRGB(new Color(114, 100, 81)); + createExtraChild(new WidgetPointer(arg1), 4, 3); + setWidgetPosition(7, add(ivar14, 2), 0, 0); + setWidgetSize(177, ivar11, 0, 0); + setWidgetTextAlignment(1, 1, 0); + setWidgetFont(495); + setWidgetRGB(new Color(255, 152, 31)); + setWidgetUnknownBoolean(false); + setWidgetText("Level " + intToStr(arg2) + ": " + arg11); + createExtraChild(new WidgetPointer(arg1), 4, 4); + setWidgetPosition(7, add(add(ivar14, 2), ivar11), 0, 0); + setWidgetSize(177, ivar12, 0, 0); + setWidgetTextAlignment(1, 1, 0); + setWidgetFont(494); + setWidgetRGB(new Color(175, 106, 26)); + setWidgetUnknownBoolean(false); + setWidgetText(arg12); + ivar15 = 1; + ivar16 = divide(subtract(190, multiply(ivar15, 35)), add(ivar15, 1)); + createExtraChild(new WidgetPointer(arg1), 5, 5); + setWidgetPosition(ivar16, add(add(add(ivar14, 2), ivar11), ivar12), 0, 0); + setWidgetSize(35, 32, 0, 0); + setItemOnWidgetMethod1200(17489, -1); + createExtraChild(new WidgetPointer(arg1), 4, 6); + setWidgetPosition(ivar16, add(add(add(add(ivar14, 2), ivar11), ivar12), 32), 0, 0); + setWidgetSize(35, 14, 0, 0); + setWidgetTextAlignment(1, 1, 0); + setWidgetFont(494); + if (standart_config_1795 != -1) { + setWidgetRGB(new Color(0, 255, 0)); + } else { + setWidgetRGB(new Color(255, 0, 0)); + } + setWidgetUnknownBoolean(false); + if (standart_config_1795 != -1) { + setWidgetText("1/1"); + } else { + setWidgetText("0/1"); + } + return; +} diff --git a/dumps/scripts/2275.cs2 b/dumps/scripts/2275.cs2 new file mode 100644 index 0000000..0241ad0 --- /dev/null +++ b/dumps/scripts/2275.cs2 @@ -0,0 +1,123 @@ +void script_2275() { + globalint_1184 = 0; + globalint_1185 = 255; + globalint_1186 = 0; + setWidgetIsHidden(true, new WidgetPointer(933,19)); + setWidgetIsHidden(true, new WidgetPointer(933,18)); + setWidgetIsHidden(true, new WidgetPointer(933,17)); + setWidgetIsHidden(true, new WidgetPointer(933,187)); + setWidgetIsHidden(true, new WidgetPointer(933,240)); + setWidgetIsHidden(true, new WidgetPointer(933,241)); + setWidgetIsHidden(true, new WidgetPointer(933,190)); + setWidgetIsHidden(true, new WidgetPointer(933,188)); + setWidgetIsHidden(true, new WidgetPointer(933,227)); + setWidgetIsHidden(true, new WidgetPointer(933,228)); + setWidgetIsHidden(true, new WidgetPointer(933,191)); + setWidgetIsHidden(true, new WidgetPointer(933,189)); + setWidgetIsHidden(true, new WidgetPointer(933,214)); + setWidgetIsHidden(true, new WidgetPointer(933,215)); + setWidgetIsHidden(true, new WidgetPointer(933,54)); + setWidgetIsHidden(true, new WidgetPointer(933,68)); + setWidgetIsHidden(true, new WidgetPointer(933,69)); + setWidgetIsHidden(true, new WidgetPointer(933,70)); + setWidgetIsHidden(true, new WidgetPointer(933,71)); + setWidgetIsHidden(true, new WidgetPointer(933,72)); + setWidgetIsHidden(true, new WidgetPointer(933,73)); + setWidgetIsHidden(true, new WidgetPointer(933,82)); + setWidgetIsHidden(true, new WidgetPointer(933,74)); + cs2method2103(200, new WidgetPointer(933,68)); + cs2method2103(200, new WidgetPointer(933,69)); + cs2method2103(200, new WidgetPointer(933,70)); + setWidgetIsHidden(true, new WidgetPointer(933,55)); + setWidgetIsHidden(true, new WidgetPointer(933,64)); + setWidgetIsHidden(true, new WidgetPointer(933,75)); + setWidgetIsHidden(true, new WidgetPointer(933,56)); + setWidgetIsHidden(true, new WidgetPointer(933,57)); + setWidgetIsHidden(true, new WidgetPointer(933,78)); + setWidgetIsHidden(true, new WidgetPointer(933,80)); + setWidgetIsHidden(true, new WidgetPointer(933,59)); + setWidgetIsHidden(true, new WidgetPointer(933,61)); + setWidgetIsHidden(true, new WidgetPointer(933,76)); + setWidgetIsHidden(true, new WidgetPointer(933,62)); + setWidgetIsHidden(true, new WidgetPointer(933,58)); + setWidgetIsHidden(true, new WidgetPointer(933,79)); + setWidgetIsHidden(true, new WidgetPointer(933,81)); + setWidgetIsHidden(true, new WidgetPointer(933,60)); + setWidgetIsHidden(true, new WidgetPointer(933,63)); + setWidgetIsHidden(true, new WidgetPointer(933,77)); + setWidgetIsHidden(true, new WidgetPointer(933,66)); + setWidgetIsHidden(true, new WidgetPointer(933,65)); + setWidgetIsHidden(true, new WidgetPointer(933,67)); + setWidgetIsHidden(true, new WidgetPointer(933,146)); + setWidgetIsHidden(true, new WidgetPointer(933,147)); + setWidgetIsHidden(true, new WidgetPointer(933,148)); + setWidgetIsHidden(true, new WidgetPointer(933,149)); + setWidgetIsHidden(true, new WidgetPointer(933,150)); + setWidgetIsHidden(true, new WidgetPointer(933,151)); + setWidgetIsHidden(true, new WidgetPointer(933,152)); + setWidgetIsHidden(true, new WidgetPointer(933,153)); + setWidgetIsHidden(true, new WidgetPointer(933,154)); + setWidgetIsHidden(true, new WidgetPointer(933,155)); + setWidgetIsHidden(true, new WidgetPointer(933,156)); + setWidgetIsHidden(true, new WidgetPointer(933,157)); + setWidgetIsHidden(true, new WidgetPointer(933,158)); + setWidgetIsHidden(true, new WidgetPointer(933,159)); + setWidgetIsHidden(true, new WidgetPointer(933,160)); + setWidgetSize(8192, 16384, 2, 2, new WidgetPointer(933,112)); + setWidgetText(new WidgetPointer(933,96), "100%"); + setWidgetIsHidden(false, new WidgetPointer(933,111)); + setWidgetSize(183, 1, 0, 0, new WidgetPointer(933,111)); + cs2method2103(0, new WidgetPointer(933,297)); + cs2method2103(0, new WidgetPointer(933,298)); + cs2method2103(0, new WidgetPointer(933,299)); + setWidgetIsHidden(true, new WidgetPointer(933,84)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(933,84)), 118, 0, 0, new WidgetPointer(933,84)); + setWidgetIsHidden(false, new WidgetPointer(933,13)); + setWidgetIsHidden(false, new WidgetPointer(933,16)); + setWidgetIsHidden(false, new WidgetPointer(933,14)); + setWidgetIsHidden(false, new WidgetPointer(933,15)); + script_2278(); + script_2938(); + script_3184(); + script_3248(); + script_3257(); + globalint_1189 = 5; + globalint_1190 = -10; + setWidgetIsHidden(true, new WidgetPointer(933,192)); + setWidgetIsHidden(true, new WidgetPointer(933,83)); + setWidgetIsHidden(false, new WidgetPointer(933,186)); + setWidgetIsHidden(false, new WidgetPointer(933,53)); + setWidgetIsHidden(false, new WidgetPointer(933,37)); + cs2method2103(255, new WidgetPointer(933,186)); + cs2method2103(255, new WidgetPointer(933,53)); + cs2method2103(255, new WidgetPointer(933,37)); + setWidgetIsHidden(true, new WidgetPointer(933,20)); + setWidgetSize(90, 45, 0, 0, new WidgetPointer(933,25)); + cs2method2103(0, new WidgetPointer(933,25)); + setWidgetIsHidden(true, new WidgetPointer(933,21)); + setWidgetSize(90, 45, 0, 0, new WidgetPointer(933,24)); + cs2method2103(0, new WidgetPointer(933,24)); + setWidgetIsHidden(true, new WidgetPointer(933,22)); + setWidgetSize(90, 45, 0, 0, new WidgetPointer(933,23)); + cs2method2103(0, new WidgetPointer(933,23)); + globalint_1397 = 0; + globalint_1398 = 0; + globalint_1399 = 0; + globalint_1400 = 0; + globalint_1401 = 0; + setWidgetIsHidden(true, new WidgetPointer(933,322)); + setWidgetIsHidden(true, new WidgetPointer(933,323)); + setWidgetIsHidden(true, new WidgetPointer(933,321)); + setWidgetIsHidden(true, new WidgetPointer(933,324)); + setWidgetIsHidden(true, new WidgetPointer(933,320)); + setWidgetIsHidden(true, new WidgetPointer(933,325)); + setWidgetIsHidden(true, new WidgetPointer(933,319)); + setWidgetIsHidden(true, new WidgetPointer(933,326)); + setWidgetIsHidden(true, new WidgetPointer(933,318)); + setWidgetIsHidden(true, new WidgetPointer(933,327)); + setWidgetIsHidden(false, new WidgetPointer(933,330)); + setWidgetText(new WidgetPointer(933,331), "-Calculating-"); + script_4750(); + setScriptCallOnWidgetResize(4749, "", new WidgetPointer(933,0)); + return; +} diff --git a/dumps/scripts/2276.cs2 b/dumps/scripts/2276.cs2 new file mode 100644 index 0000000..28eb52c --- /dev/null +++ b/dumps/scripts/2276.cs2 @@ -0,0 +1,25 @@ +void script_2276(int arg0,int arg1,int arg2) { + int ivar3; + string svar0; + string svar1; + svar0 = cs2method_3408(105, 115, 2857, arg1); + ivar3 = cs2method_3408(105, 105, 2858, arg1); + svar1 = cs2method_3408(105, 115, 2859, arg1); + if (((boolean)arg0)) { + setWidgetText(new WidgetPointer(arg2), svar0); + if (ivar3 == 2) { + setWidgetRGB(new Color(0, 160, 0), new WidgetPointer(arg2)); + } else if (((boolean)ivar3)) { + setWidgetRGB(new Color(144, 144, 0), new WidgetPointer(arg2)); + } else { + if (((boolean)ivar3)) { + setWidgetRGB(new Color(160, 0, 0), new WidgetPointer(arg2)); + } + } + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(933,254), svar1, 25, 200, "IIsii", new WidgetPointer(arg2)); + setScriptCallOnMouseExit(40, new WidgetPointer(933,254), "I", new WidgetPointer(arg2)); + } else { + setWidgetText(new WidgetPointer(arg2), ""); + } + return; +} diff --git a/dumps/scripts/2277.cs2 b/dumps/scripts/2277.cs2 new file mode 100644 index 0000000..d9a44f4 --- /dev/null +++ b/dumps/scripts/2277.cs2 @@ -0,0 +1,4 @@ +void script_2277() { + script_2278(); + return; +} diff --git a/dumps/scripts/2278.cs2 b/dumps/scripts/2278.cs2 new file mode 100644 index 0000000..98b1346 --- /dev/null +++ b/dumps/scripts/2278.cs2 @@ -0,0 +1,20 @@ +void script_2278() { + if (((boolean)globalint_1198)) { + setWidgetText(new WidgetPointer(933,309), globalstring_310); + setWidgetText(new WidgetPointer(933,310), cs2method_3408(105, 115, 2857, globalint_1203)); + setWidgetText(new WidgetPointer(933,311), cs2method_3408(105, 115, 2857, globalint_1204)); + setWidgetText(new WidgetPointer(933,312), cs2method_3408(105, 115, 2857, globalint_1205)); + setWidgetText(new WidgetPointer(933,313), cs2method_3408(105, 115, 2857, globalint_1206)); + setWidgetText(new WidgetPointer(933,314), cs2method_3408(105, 115, 2857, globalint_1207)); + setWidgetText(new WidgetPointer(933,315), cs2method_3408(105, 115, 2857, globalint_1208)); + } else { + setWidgetText(new WidgetPointer(933,309), ""); + setWidgetText(new WidgetPointer(933,310), ""); + setWidgetText(new WidgetPointer(933,311), ""); + setWidgetText(new WidgetPointer(933,312), ""); + setWidgetText(new WidgetPointer(933,313), ""); + setWidgetText(new WidgetPointer(933,314), ""); + setWidgetText(new WidgetPointer(933,315), ""); + } + return; +} diff --git a/dumps/scripts/2279.cs2 b/dumps/scripts/2279.cs2 new file mode 100644 index 0000000..1286bbd --- /dev/null +++ b/dumps/scripts/2279.cs2 @@ -0,0 +1,6 @@ +void script_2279() { + if (((boolean)globalint_1198)) { + setWidgetText(new WidgetPointer(933,309), globalstring_310); + } + return; +} diff --git a/dumps/scripts/228.cs2 b/dumps/scripts/228.cs2 new file mode 100644 index 0000000..e87bc21 --- /dev/null +++ b/dumps/scripts/228.cs2 @@ -0,0 +1,6 @@ +void script_228() { + script_231(); + script_232(); + setWidgetIsHidden(false, new WidgetPointer(594,151)); + return; +} diff --git a/dumps/scripts/2280.cs2 b/dumps/scripts/2280.cs2 new file mode 100644 index 0000000..3b5c50d --- /dev/null +++ b/dumps/scripts/2280.cs2 @@ -0,0 +1,4 @@ +void script_2280() { + script_2276(globalint_1198, globalint_1203, 61145398); + return; +} diff --git a/dumps/scripts/2281.cs2 b/dumps/scripts/2281.cs2 new file mode 100644 index 0000000..da15bd3 --- /dev/null +++ b/dumps/scripts/2281.cs2 @@ -0,0 +1,4 @@ +void script_2281() { + script_2276(globalint_1198, globalint_1204, 61145399); + return; +} diff --git a/dumps/scripts/2282.cs2 b/dumps/scripts/2282.cs2 new file mode 100644 index 0000000..bdd0769 --- /dev/null +++ b/dumps/scripts/2282.cs2 @@ -0,0 +1,4 @@ +void script_2282() { + script_2276(globalint_1198, globalint_1205, 61145400); + return; +} diff --git a/dumps/scripts/2283.cs2 b/dumps/scripts/2283.cs2 new file mode 100644 index 0000000..8371e28 --- /dev/null +++ b/dumps/scripts/2283.cs2 @@ -0,0 +1,15 @@ +void script_2283(int arg0,int arg1) { + globalstring_123 = globalstring_122; + if (strLength(globalstring_122) <= 0) { + script_3213(44105822, "Please enter your Email address here."); + return; + } + if (((boolean)script_3936(globalstring_122))) { + script_3213(44105822, "Please enter a valid Email address."); + return; + } + script_3208(1); + sendRequestAccount(globalstring_122); + setScriptCallOnGameloop(2284, arg0, arg1, "11", new WidgetPointer(673,20)); + return; +} diff --git a/dumps/scripts/2284.cs2 b/dumps/scripts/2284.cs2 new file mode 100644 index 0000000..97c4bba --- /dev/null +++ b/dumps/scripts/2284.cs2 @@ -0,0 +1,63 @@ +void script_2284(int arg0,int arg1) { + int ivar2; + string svar0; + string svar1; + ivar2 = getAccountCreateRC(); + if (ivar2 == -3) { + return; + } + setScriptCallOnGameloop(-1, "", new WidgetPointer(673,20)); + script_3208(0); + if (ivar2 == 2) { + setWidgetSprite(4059, new WidgetPointer(673,94)); + setWidgetIsHidden(true, new WidgetPointer(673,99)); + setWidgetIsHidden(true, new WidgetPointer(673,31)); + if (((boolean)arg1) && (strLength(globalstring_326) > 0)) { + script_3953(0); + } + if (strLength(globalstring_124) > 0) { + script_3228(7, 1, 0); + if (strLength(globalstring_125) > 0) { + script_3228(8, 1, 0); + } + } + if (((boolean)arg0)) { + script_2714(14, 1); + } + return; + } + svar0 = "accountappeal"; + svar1 = "passwordchoice.ws"; + switch (ivar2) { + case 3: + case -4: + case -1: + script_3213(44105822, "Error contacting server."); + break; + case -5: + script_3213(44105822, "No response from server."); + break; + case 7: + script_3213(44105822, "The server is currently very busy. Please try again shortly."); + break; + case 38: + case 9: + script_3213(44105822, "You cannot create an account at this time. Please try again later."); + break; + case 20: + script_3213(44105822, "Email already in use. Try a different email or click " + "" + "here" + "" + " to recover this account."); + break; + case 21: + script_3213(44105822, "Please enter a valid Email address."); + break; + case 37: + script_3213(44105822, "RuneScape has been updated. Please reload this page."); + break; + default: + script_3213(44105822, "Unexpected server response."); + } + if (((boolean)arg1) && (strLength(globalstring_326) > 0)) { + script_3953(0); + } + return; +} diff --git a/dumps/scripts/2285.cs2 b/dumps/scripts/2285.cs2 new file mode 100644 index 0000000..eff35a1 --- /dev/null +++ b/dumps/scripts/2285.cs2 @@ -0,0 +1,4 @@ +void script_2285() { + script_2276(globalint_1198, globalint_1206, 61145401); + return; +} diff --git a/dumps/scripts/2286.cs2 b/dumps/scripts/2286.cs2 new file mode 100644 index 0000000..55c1b1b --- /dev/null +++ b/dumps/scripts/2286.cs2 @@ -0,0 +1,4 @@ +void script_2286() { + script_2276(globalint_1198, globalint_1207, 61145402); + return; +} diff --git a/dumps/scripts/2287.cs2 b/dumps/scripts/2287.cs2 new file mode 100644 index 0000000..79c7652 --- /dev/null +++ b/dumps/scripts/2287.cs2 @@ -0,0 +1,4 @@ +void script_2287() { + script_2276(globalint_1198, globalint_1208, 61145403); + return; +} diff --git a/dumps/scripts/2288.cs2 b/dumps/scripts/2288.cs2 new file mode 100644 index 0000000..c49fd5c --- /dev/null +++ b/dumps/scripts/2288.cs2 @@ -0,0 +1,4 @@ +void script_2288() { + script_2938(); + return; +} diff --git a/dumps/scripts/2289.cs2 b/dumps/scripts/2289.cs2 new file mode 100644 index 0000000..f116ccd --- /dev/null +++ b/dumps/scripts/2289.cs2 @@ -0,0 +1,21 @@ +void script_2289(int arg0,int arg1,int arg2) { + if (((boolean)script_2296(arg2))) { + if (((boolean)script_2295(arg2))) { + return; + } + if (setWidgetRegister(new WidgetPointer(arg0), arg2)) { + setWidgetContextMenuOption(1, "Deactivate"); + } + if (setWidgetRegister(new WidgetPointer(arg1), arg2)) { + setWidgetSprite(155); + } + } else { + if (setWidgetRegister(new WidgetPointer(arg0), arg2)) { + setWidgetContextMenuOption(1, "Activate"); + } + if (setWidgetRegister(new WidgetPointer(arg1), arg2)) { + setWidgetSprite(-1); + } + } + return; +} diff --git a/dumps/scripts/229.cs2 b/dumps/scripts/229.cs2 new file mode 100644 index 0000000..f4e32c3 --- /dev/null +++ b/dumps/scripts/229.cs2 @@ -0,0 +1,6 @@ +void script_229() { + script_231(); + script_232(); + setWidgetIsHidden(false, new WidgetPointer(594,165)); + return; +} diff --git a/dumps/scripts/2290.cs2 b/dumps/scripts/2290.cs2 new file mode 100644 index 0000000..3b9bf2d --- /dev/null +++ b/dumps/scripts/2290.cs2 @@ -0,0 +1,17 @@ +void script_2290(int arg0,int arg1) { + if (((boolean)script_2297(arg1))) { + if (((boolean)script_2295(arg1))) { + return; + } + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetSprite(181); + setWidgetContextMenuOption(1, "Deselect"); + } + } else { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetSprite(180); + setWidgetContextMenuOption(1, "Select"); + } + } + return; +} diff --git a/dumps/scripts/2291.cs2 b/dumps/scripts/2291.cs2 new file mode 100644 index 0000000..efa16a7 --- /dev/null +++ b/dumps/scripts/2291.cs2 @@ -0,0 +1,12 @@ +void script_2291(int arg0,int arg1) { + if (((boolean)script_2297(arg1))) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetSprite(181); + } + } else { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetSprite(180); + } + } + return; +} diff --git a/dumps/scripts/2292.cs2 b/dumps/scripts/2292.cs2 new file mode 100644 index 0000000..935d5d0 --- /dev/null +++ b/dumps/scripts/2292.cs2 @@ -0,0 +1,5 @@ +void script_2292(int arg0,int arg1) { + setWidgetSprite(939, new WidgetPointer(arg1)); + setWidgetRGB(new Color(255, 100, 30), new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/2293.cs2 b/dumps/scripts/2293.cs2 new file mode 100644 index 0000000..c4c42bd --- /dev/null +++ b/dumps/scripts/2293.cs2 @@ -0,0 +1,5 @@ +void script_2293(int arg0,int arg1) { + setWidgetSprite(938, new WidgetPointer(arg1)); + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/2294.cs2 b/dumps/scripts/2294.cs2 new file mode 100644 index 0000000..3eada7d --- /dev/null +++ b/dumps/scripts/2294.cs2 @@ -0,0 +1,12 @@ +int script_2294(int arg0) { + if (((boolean)bitconfig_6840)) { + if (((boolean)getOtherCommonData(cs2method_3408(105, 74, 863, arg0), 739))) { + return 1; + } + return 0; + } + if (((boolean)getOtherCommonData(cs2method_3408(105, 74, 2279, arg0), 739))) { + return 1; + } + return 0; +} diff --git a/dumps/scripts/2295.cs2 b/dumps/scripts/2295.cs2 new file mode 100644 index 0000000..e394eb0 --- /dev/null +++ b/dumps/scripts/2295.cs2 @@ -0,0 +1,27 @@ +int script_2295(int arg0) { + int ivar1; + if (isMember() && ((boolean)script_2294(arg0))) { + return 0; + } + if (((boolean)script_5256())) { + playSoundEffect(2673, 1, 0); + return 0; + } + ivar1 = 2279; + if (((boolean)bitconfig_6840)) { + ivar1 = 863; + } + if (getSkillActualLvl(5) < getOtherCommonData(cs2method_3408(105, 74, ivar1, arg0), 737)) { + playSoundEffect(2673, 1, 0); + return 0; + } + if ((arg0 == 25) && ((getSkillActualLvl(1) < 55) || (bitconfig_3909 != 8))) { + playSoundEffect(2673, 1, 0); + return 0; + } + if ((arg0 == 26) && ((getSkillActualLvl(1) < 70) || (bitconfig_3909 != 8))) { + playSoundEffect(2673, 1, 0); + return 0; + } + return 1; +} diff --git a/dumps/scripts/2296.cs2 b/dumps/scripts/2296.cs2 new file mode 100644 index 0000000..b3586e5 --- /dev/null +++ b/dumps/scripts/2296.cs2 @@ -0,0 +1,113 @@ +int script_2296(int arg0) { + int ivar1; + ivar1 = cs2method_3408(105, 74, 2279, arg0); + if (((boolean)bitconfig_6840)) { + ivar1 = cs2method_3408(105, 74, 863, arg0); + switch (ivar1) { + case 888: + return bitconfig_6820; + case 889: + return bitconfig_6821; + case 890: + return bitconfig_6822; + case 891: + return bitconfig_6823; + case 892: + return bitconfig_6824; + case 893: + return bitconfig_6825; + case 894: + return bitconfig_6826; + case 895: + return bitconfig_6827; + case 896: + return bitconfig_6828; + case 897: + return bitconfig_6829; + case 898: + return bitconfig_6830; + case 899: + return bitconfig_6831; + case 900: + return bitconfig_6832; + case 901: + return bitconfig_6833; + case 902: + return bitconfig_6834; + case 903: + return bitconfig_6835; + case 904: + return bitconfig_6836; + case 905: + return bitconfig_6837; + case 906: + return bitconfig_6838; + case 907: + return bitconfig_6839; + } + return 0; + } + switch (ivar1) { + case 660: + return bitconfig_5942; + case 661: + return bitconfig_5943; + case 662: + return bitconfig_5944; + case 663: + return bitconfig_5945; + case 664: + return bitconfig_5946; + case 665: + return bitconfig_5947; + case 666: + return bitconfig_5948; + case 667: + return bitconfig_5949; + case 668: + return bitconfig_5950; + case 669: + return bitconfig_5951; + case 670: + return bitconfig_5952; + case 671: + return bitconfig_5953; + case 672: + return bitconfig_5954; + case 673: + return bitconfig_5955; + case 674: + return bitconfig_5956; + case 675: + return bitconfig_5957; + case 676: + return bitconfig_5958; + case 677: + return bitconfig_5959; + case 678: + return bitconfig_5960; + case 679: + return bitconfig_5961; + case 680: + return bitconfig_5962; + case 681: + return bitconfig_5963; + case 682: + return bitconfig_5964; + case 683: + return bitconfig_5965; + case 684: + return bitconfig_5966; + case 685: + return bitconfig_5967; + case 1005: + return bitconfig_7768; + case 686: + return bitconfig_5968; + case 1006: + return bitconfig_7769; + case 1029: + return bitconfig_7381; + } + return 0; +} diff --git a/dumps/scripts/2297.cs2 b/dumps/scripts/2297.cs2 new file mode 100644 index 0000000..9e31614 --- /dev/null +++ b/dumps/scripts/2297.cs2 @@ -0,0 +1,113 @@ +int script_2297(int arg0) { + int ivar1; + ivar1 = cs2method_3408(105, 74, 2279, arg0); + if (((boolean)bitconfig_6840)) { + ivar1 = cs2method_3408(105, 74, 863, arg0); + switch (ivar1) { + case 888: + return bitconfig_6862; + case 889: + return bitconfig_6863; + case 890: + return bitconfig_6864; + case 891: + return bitconfig_6865; + case 892: + return bitconfig_6866; + case 893: + return bitconfig_6867; + case 894: + return bitconfig_6868; + case 895: + return bitconfig_6869; + case 896: + return bitconfig_6870; + case 897: + return bitconfig_6871; + case 898: + return bitconfig_6872; + case 899: + return bitconfig_6873; + case 900: + return bitconfig_6874; + case 901: + return bitconfig_6875; + case 902: + return bitconfig_6876; + case 903: + return bitconfig_6877; + case 904: + return bitconfig_6878; + case 905: + return bitconfig_6879; + case 906: + return bitconfig_6880; + case 907: + return bitconfig_6881; + } + return 0; + } + switch (ivar1) { + case 660: + return bitconfig_5971; + case 661: + return bitconfig_5972; + case 662: + return bitconfig_5973; + case 663: + return bitconfig_5974; + case 664: + return bitconfig_5975; + case 665: + return bitconfig_5976; + case 666: + return bitconfig_5977; + case 667: + return bitconfig_5978; + case 668: + return bitconfig_5979; + case 669: + return bitconfig_5980; + case 670: + return bitconfig_5981; + case 671: + return bitconfig_5982; + case 672: + return bitconfig_5983; + case 673: + return bitconfig_5984; + case 674: + return bitconfig_5985; + case 675: + return bitconfig_5986; + case 676: + return bitconfig_5987; + case 677: + return bitconfig_5988; + case 678: + return bitconfig_5989; + case 679: + return bitconfig_5990; + case 680: + return bitconfig_5991; + case 681: + return bitconfig_5992; + case 682: + return bitconfig_5993; + case 683: + return bitconfig_5994; + case 684: + return bitconfig_5995; + case 685: + return bitconfig_5996; + case 1005: + return bitconfig_7770; + case 686: + return bitconfig_5997; + case 1006: + return bitconfig_7771; + case 1029: + return bitconfig_7382; + } + return 0; +} diff --git a/dumps/scripts/2298.cs2 b/dumps/scripts/2298.cs2 new file mode 100644 index 0000000..c20453e --- /dev/null +++ b/dumps/scripts/2298.cs2 @@ -0,0 +1,4 @@ +void script_2298() { + script_817(5); + return; +} diff --git a/dumps/scripts/2299.cs2 b/dumps/scripts/2299.cs2 new file mode 100644 index 0000000..82d69db --- /dev/null +++ b/dumps/scripts/2299.cs2 @@ -0,0 +1,18 @@ +void script_2299(int arg0) { + if (((boolean)globalint_181)) { + if (((boolean)bitconfig_6840)) { + setWidgetContextMenuOption(2, new WidgetPointer(arg0), "Finish quick curse selection"); + setWidgetText(new WidgetPointer(271,46), "Select your quick curses:"); + } else { + setWidgetContextMenuOption(2, new WidgetPointer(arg0), "Finish quick prayer selection"); + setWidgetText(new WidgetPointer(271,46), "Select your quick prayers:"); + } + } else if (((boolean)bitconfig_6840)) { + setWidgetContextMenuOption(2, new WidgetPointer(arg0), "Select quick curses"); + } else { + setWidgetContextMenuOption(2, new WidgetPointer(arg0), "Select quick prayers"); + } + script_817(5); + script_2303(); + return; +} diff --git a/dumps/scripts/23.cs2 b/dumps/scripts/23.cs2 new file mode 100644 index 0000000..fc1638d --- /dev/null +++ b/dumps/scripts/23.cs2 @@ -0,0 +1,360 @@ +void script_23() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + string svar0; + string svar1; + string svar2; + string svar3; + int stack_dump0; + cs2func_script_12_struct(1,1,0) structdump_1; + int stack_dump2; + cs2func_script_13_struct(1,1,0) structdump_3; + cs2func_script_13_struct(1,1,0) structdump_4; + cs2func_script_13_struct(1,1,0) structdump_5; + cs2func_script_13_struct(1,1,0) structdump_6; + cs2func_script_13_struct(1,1,0) structdump_7; + cs2func_script_13_struct(1,1,0) structdump_8; + cs2func_script_13_struct(1,1,0) structdump_9; + cs2func_script_13_struct(1,1,0) structdump_10; + cs2func_script_13_struct(1,1,0) structdump_11; + cs2func_script_13_struct(1,1,0) structdump_12; + cs2func_script_13_struct(1,1,0) structdump_13; + cs2func_script_13_struct(1,1,0) structdump_14; + cs2func_script_13_struct(1,1,0) structdump_15; + cs2func_script_13_struct(1,1,0) structdump_16; + cs2func_script_13_struct(1,1,0) structdump_17; + cs2func_script_13_struct(1,1,0) structdump_18; + cs2func_script_13_struct(1,1,0) structdump_19; + int stack_dump20; + cs2func_script_1567_struct(2,2,0) structdump_21; + cs2func_script_14_struct(2,2,0) structdump_22; + flow_0: + ivar0 = 0; + svar0 = ""; + stack_dump0 = bitconfig_3288; + structdump_1 = script_12(stack_dump0); + ivar0 = structdump_1.intpart_0; + svar0 = structdump_1.stringpart_0; + setWidgetText(new WidgetPointer(499,6), svar0); + setScriptCallOnClickContextMenu(212, cs2method_3408(105, 115, 696, bitconfig_3288), "s", new WidgetPointer(499,28)); + svar1 = ""; + ivar1 = 0; + if (ivar0 > 1) { + stack_dump0 = bitconfig_3288; + stack_dump2 = 0; + structdump_3 = script_13(stack_dump0, stack_dump2); + ivar1 = structdump_3.intpart_0; + svar1 = structdump_3.stringpart_0; + setWidgetText(new WidgetPointer(499,10), svar1); + setWidgetIsHidden(false, new WidgetPointer(499,10)); + } else { + setWidgetText(new WidgetPointer(499,10), ""); + setWidgetIsHidden(true, new WidgetPointer(499,10)); + } + if (ivar0 >= 2) { + stack_dump0 = bitconfig_3288; + stack_dump2 = 1; + structdump_4 = script_13(stack_dump0, stack_dump2); + ivar1 = structdump_4.intpart_0; + svar1 = structdump_4.stringpart_0; + setWidgetText(new WidgetPointer(499,11), svar1); + setWidgetPosition(353, 78, 0, 0, new WidgetPointer(499,5)); + setWidgetIsHidden(false, new WidgetPointer(499,11)); + } else { + setWidgetText(new WidgetPointer(499,11), ""); + setWidgetIsHidden(true, new WidgetPointer(499,11)); + } + if (ivar0 >= 3) { + stack_dump0 = bitconfig_3288; + stack_dump2 = 2; + structdump_5 = script_13(stack_dump0, stack_dump2); + ivar1 = structdump_5.intpart_0; + svar1 = structdump_5.stringpart_0; + setWidgetText(new WidgetPointer(499,12), svar1); + setWidgetPosition(353, 95, 0, 0, new WidgetPointer(499,5)); + setWidgetIsHidden(false, new WidgetPointer(499,12)); + } else { + setWidgetText(new WidgetPointer(499,12), ""); + setWidgetIsHidden(true, new WidgetPointer(499,12)); + } + if (ivar0 >= 4) { + stack_dump0 = bitconfig_3288; + stack_dump2 = 3; + structdump_6 = script_13(stack_dump0, stack_dump2); + ivar1 = structdump_6.intpart_0; + svar1 = structdump_6.stringpart_0; + setWidgetText(new WidgetPointer(499,13), svar1); + setWidgetPosition(353, 114, 0, 0, new WidgetPointer(499,5)); + setWidgetIsHidden(false, new WidgetPointer(499,13)); + } else { + setWidgetText(new WidgetPointer(499,13), ""); + setWidgetIsHidden(true, new WidgetPointer(499,13)); + } + if (ivar0 >= 5) { + stack_dump0 = bitconfig_3288; + stack_dump2 = 4; + structdump_7 = script_13(stack_dump0, stack_dump2); + ivar1 = structdump_7.intpart_0; + svar1 = structdump_7.stringpart_0; + setWidgetText(new WidgetPointer(499,14), svar1); + setWidgetPosition(353, 129, 0, 0, new WidgetPointer(499,5)); + setWidgetIsHidden(false, new WidgetPointer(499,14)); + } else { + setWidgetText(new WidgetPointer(499,14), ""); + setWidgetIsHidden(true, new WidgetPointer(499,14)); + } + if (ivar0 >= 6) { + stack_dump0 = bitconfig_3288; + stack_dump2 = 5; + structdump_8 = script_13(stack_dump0, stack_dump2); + ivar1 = structdump_8.intpart_0; + svar1 = structdump_8.stringpart_0; + setWidgetText(new WidgetPointer(499,15), svar1); + setWidgetPosition(353, 146, 0, 0, new WidgetPointer(499,5)); + setWidgetIsHidden(false, new WidgetPointer(499,15)); + } else { + setWidgetText(new WidgetPointer(499,15), ""); + setWidgetIsHidden(true, new WidgetPointer(499,15)); + } + if (ivar0 >= 7) { + stack_dump0 = bitconfig_3288; + stack_dump2 = 6; + structdump_9 = script_13(stack_dump0, stack_dump2); + ivar1 = structdump_9.intpart_0; + svar1 = structdump_9.stringpart_0; + setWidgetText(new WidgetPointer(499,16), svar1); + setWidgetPosition(353, 168, 0, 0, new WidgetPointer(499,5)); + setWidgetIsHidden(false, new WidgetPointer(499,16)); + } else { + setWidgetText(new WidgetPointer(499,16), ""); + setWidgetIsHidden(true, new WidgetPointer(499,16)); + } + if (ivar0 >= 8) { + stack_dump0 = bitconfig_3288; + stack_dump2 = 7; + structdump_10 = script_13(stack_dump0, stack_dump2); + ivar1 = structdump_10.intpart_0; + svar1 = structdump_10.stringpart_0; + setWidgetText(new WidgetPointer(499,17), svar1); + setWidgetPosition(353, 180, 0, 0, new WidgetPointer(499,5)); + setWidgetIsHidden(false, new WidgetPointer(499,17)); + } else { + setWidgetText(new WidgetPointer(499,17), ""); + setWidgetIsHidden(true, new WidgetPointer(499,17)); + } + if (ivar0 >= 9) { + stack_dump0 = bitconfig_3288; + stack_dump2 = 8; + structdump_11 = script_13(stack_dump0, stack_dump2); + ivar1 = structdump_11.intpart_0; + svar1 = structdump_11.stringpart_0; + setWidgetText(new WidgetPointer(499,18), svar1); + setWidgetPosition(353, 197, 0, 0, new WidgetPointer(499,5)); + setWidgetIsHidden(false, new WidgetPointer(499,18)); + } else { + setWidgetText(new WidgetPointer(499,18), ""); + setWidgetIsHidden(true, new WidgetPointer(499,18)); + } + if (ivar0 >= 10) { + stack_dump0 = bitconfig_3288; + stack_dump2 = 9; + structdump_12 = script_13(stack_dump0, stack_dump2); + ivar1 = structdump_12.intpart_0; + svar1 = structdump_12.stringpart_0; + setWidgetText(new WidgetPointer(499,19), svar1); + setWidgetPosition(353, 214, 0, 0, new WidgetPointer(499,5)); + setWidgetIsHidden(false, new WidgetPointer(499,19)); + } else { + setWidgetText(new WidgetPointer(499,19), ""); + setWidgetIsHidden(true, new WidgetPointer(499,19)); + } + if (ivar0 >= 11) { + stack_dump0 = bitconfig_3288; + stack_dump2 = 10; + structdump_13 = script_13(stack_dump0, stack_dump2); + ivar1 = structdump_13.intpart_0; + svar1 = structdump_13.stringpart_0; + setWidgetText(new WidgetPointer(499,20), svar1); + setWidgetPosition(353, 231, 0, 0, new WidgetPointer(499,5)); + setWidgetIsHidden(false, new WidgetPointer(499,20)); + } else { + setWidgetText(new WidgetPointer(499,20), ""); + setWidgetIsHidden(true, new WidgetPointer(499,20)); + } + if (ivar0 >= 12) { + stack_dump0 = bitconfig_3288; + stack_dump2 = 11; + structdump_14 = script_13(stack_dump0, stack_dump2); + ivar1 = structdump_14.intpart_0; + svar1 = structdump_14.stringpart_0; + setWidgetText(new WidgetPointer(499,21), svar1); + setWidgetPosition(353, 248, 0, 0, new WidgetPointer(499,5)); + setWidgetIsHidden(false, new WidgetPointer(499,21)); + } else { + setWidgetText(new WidgetPointer(499,21), ""); + setWidgetIsHidden(true, new WidgetPointer(499,21)); + } + if (ivar0 >= 13) { + stack_dump0 = bitconfig_3288; + stack_dump2 = 12; + structdump_15 = script_13(stack_dump0, stack_dump2); + ivar1 = structdump_15.intpart_0; + svar1 = structdump_15.stringpart_0; + setWidgetText(new WidgetPointer(499,22), svar1); + setWidgetPosition(353, 265, 0, 0, new WidgetPointer(499,5)); + setWidgetIsHidden(false, new WidgetPointer(499,22)); + } else { + setWidgetText(new WidgetPointer(499,22), ""); + setWidgetIsHidden(true, new WidgetPointer(499,22)); + } + if (ivar0 >= 14) { + stack_dump0 = bitconfig_3288; + stack_dump2 = 13; + structdump_16 = script_13(stack_dump0, stack_dump2); + ivar1 = structdump_16.intpart_0; + svar1 = structdump_16.stringpart_0; + setWidgetText(new WidgetPointer(499,23), svar1); + setWidgetPosition(353, 282, 0, 0, new WidgetPointer(499,5)); + setWidgetIsHidden(false, new WidgetPointer(499,23)); + } else { + setWidgetText(new WidgetPointer(499,23), ""); + setWidgetIsHidden(true, new WidgetPointer(499,23)); + } + if (ivar0 >= 15) { + stack_dump0 = bitconfig_3288; + stack_dump2 = 14; + structdump_17 = script_13(stack_dump0, stack_dump2); + ivar1 = structdump_17.intpart_0; + svar1 = structdump_17.stringpart_0; + setWidgetText(new WidgetPointer(499,24), svar1); + setWidgetPosition(353, 299, 0, 0, new WidgetPointer(499,5)); + setWidgetIsHidden(false, new WidgetPointer(499,24)); + } else { + setWidgetText(new WidgetPointer(499,24), ""); + setWidgetIsHidden(true, new WidgetPointer(499,24)); + } + if (ivar0 >= 16) { + stack_dump0 = bitconfig_3288; + stack_dump2 = 15; + structdump_18 = script_13(stack_dump0, stack_dump2); + ivar1 = structdump_18.intpart_0; + svar1 = structdump_18.stringpart_0; + setWidgetText(new WidgetPointer(499,25), svar1); + setWidgetPosition(353, 316, 0, 0, new WidgetPointer(499,5)); + setWidgetIsHidden(false, new WidgetPointer(499,25)); + } else { + setWidgetText(new WidgetPointer(499,25), ""); + setWidgetIsHidden(true, new WidgetPointer(499,25)); + } + if (ivar0 < 2) { + setWidgetIsHidden(true, new WidgetPointer(499,4)); + setWidgetIsHidden(true, new WidgetPointer(499,3)); + setWidgetIsHidden(true, new WidgetPointer(499,5)); + } else { + setWidgetIsHidden(false, new WidgetPointer(499,4)); + setWidgetIsHidden(false, new WidgetPointer(499,3)); + setWidgetIsHidden(false, new WidgetPointer(499,5)); + } + if (ivar0 == 2) { + setWidgetModel(20838, new WidgetPointer(499,3)); + } else if (ivar0 == 3) { + setWidgetModel(20839, new WidgetPointer(499,3)); + } else if (ivar0 == 4) { + setWidgetModel(20840, new WidgetPointer(499,3)); + } else if (ivar0 == 5) { + setWidgetModel(20841, new WidgetPointer(499,3)); + } else if (ivar0 == 6) { + setWidgetModel(20842, new WidgetPointer(499,3)); + } else if (ivar0 == 7) { + setWidgetModel(20843, new WidgetPointer(499,3)); + } else if (ivar0 == 8) { + setWidgetModel(20844, new WidgetPointer(499,3)); + } else if (ivar0 == 9) { + setWidgetModel(20845, new WidgetPointer(499,3)); + } else if (ivar0 == 10) { + setWidgetModel(20846, new WidgetPointer(499,3)); + } else if (ivar0 == 11) { + setWidgetModel(20847, new WidgetPointer(499,3)); + } else if (ivar0 == 12) { + setWidgetModel(20848, new WidgetPointer(499,3)); + } else if (ivar0 == 13) { + setWidgetModel(20849, new WidgetPointer(499,3)); + } else if (ivar0 == 14) { + setWidgetModel(20850, new WidgetPointer(499,3)); + } else if (ivar0 == 15) { + setWidgetModel(43501, new WidgetPointer(499,3)); + } else { + if (ivar0 == 16) { + setWidgetModel(43500, new WidgetPointer(499,3)); + } + } + stack_dump0 = bitconfig_3288; + stack_dump2 = bitconfig_3289; + structdump_19 = script_13(stack_dump0, stack_dump2); + ivar1 = structdump_19.intpart_0; + svar1 = structdump_19.stringpart_0; + setWidgetText(new WidgetPointer(499,9), svar1); + if (((boolean)ivar1)) { + setWidgetText(new WidgetPointer(499,9), svar1); + } else { + setWidgetText(new WidgetPointer(499,9), concat(svar1, " - Members Only")); + } + deleteAllExtraChilds(new WidgetPointer(499,7)); + deleteAllExtraChilds(new WidgetPointer(499,8)); + ivar2 = 0; + ivar3 = 3; + ivar4 = 0; + ivar5 = 7620; + ivar6 = 2287; + svar2 = ""; + svar3 = ""; + IF (((boolean)script_1566(bitconfig_3288, bitconfig_3289))) + GOTO flow_85 + GOTO flow_88 + flow_85: + IF (ivar6 != -1) + GOTO flow_86 + GOTO flow_87 + flow_86: + stack_dump0 = bitconfig_3288; + stack_dump2 = bitconfig_3289; + stack_dump20 = ivar2; + structdump_21 = script_1567(stack_dump0, stack_dump2, stack_dump20); + svar3 = structdump_21.stringpart_1; + svar2 = structdump_21.stringpart_0; + ivar6 = structdump_21.intpart_1; + ivar4 = structdump_21.intpart_0; + ivar3 = add(ivar3, script_24(ivar4, ivar5, ivar6, ivar2, ivar3, svar2)); + ivar2 = add(ivar2, 1); + GOTO flow_85 + flow_87: + GOTO flow_90 + flow_88: + IF (ivar5 != -1) + GOTO flow_89 + GOTO flow_90 + flow_89: + stack_dump0 = bitconfig_3288; + stack_dump2 = bitconfig_3289; + stack_dump20 = ivar2; + structdump_22 = script_14(stack_dump0, stack_dump2, stack_dump20); + svar3 = structdump_22.stringpart_1; + svar2 = structdump_22.stringpart_0; + ivar5 = structdump_22.intpart_1; + ivar4 = structdump_22.intpart_0; + ivar3 = add(ivar3, script_24(ivar4, ivar5, ivar6, ivar2, ivar3, svar2)); + ivar2 = add(ivar2, 1); + GOTO flow_88 + flow_90: + cs2method2100(0, 0, new WidgetPointer(499,7)); + setWidgetScrollMax(296, ivar3, new WidgetPointer(499,7)); + if (ivar3 > 240) { + script_31(32702472, 32702471, 798, 795, 796, 797, 793, 794); + } + return; +} diff --git a/dumps/scripts/230.cs2 b/dumps/scripts/230.cs2 new file mode 100644 index 0000000..156e033 --- /dev/null +++ b/dumps/scripts/230.cs2 @@ -0,0 +1,6 @@ +void script_230() { + script_231(); + script_232(); + setWidgetIsHidden(false, new WidgetPointer(594,166)); + return; +} diff --git a/dumps/scripts/2300.cs2 b/dumps/scripts/2300.cs2 new file mode 100644 index 0000000..6851972 --- /dev/null +++ b/dumps/scripts/2300.cs2 @@ -0,0 +1,15 @@ +void script_2300(int arg0) { + if (arg0 != 1) { + return; + } + if (((boolean)standart_config_1397)) { + return; + } + if (((boolean)script_42(globalint_182))) { + globalint_182 = 0; + } else { + globalint_182 = 1; + } + script_2303(); + return; +} diff --git a/dumps/scripts/2301.cs2 b/dumps/scripts/2301.cs2 new file mode 100644 index 0000000..8ab30e1 --- /dev/null +++ b/dumps/scripts/2301.cs2 @@ -0,0 +1,4 @@ +void script_2301(int arg0) { + script_2308(arg0, script_42(globalint_182)); + return; +} diff --git a/dumps/scripts/2302.cs2 b/dumps/scripts/2302.cs2 new file mode 100644 index 0000000..67d5537 --- /dev/null +++ b/dumps/scripts/2302.cs2 @@ -0,0 +1,4 @@ +void script_2302(int arg0) { + script_2309(arg0, script_42(globalint_182)); + return; +} diff --git a/dumps/scripts/2303.cs2 b/dumps/scripts/2303.cs2 new file mode 100644 index 0000000..1cf066d --- /dev/null +++ b/dumps/scripts/2303.cs2 @@ -0,0 +1,29 @@ +void script_2303() { + if (((boolean)script_42(globalint_182))) { + setWidgetSprite(782, new WidgetPointer(749,2)); + if (((boolean)bitconfig_6840)) { + setWidgetContextMenuOption(1, new WidgetPointer(749,1), "Turn curses off"); + } else { + setWidgetContextMenuOption(1, new WidgetPointer(749,1), "Turn prayers off"); + } + } else if (((boolean)bitconfig_6840)) { + setWidgetContextMenuOption(1, new WidgetPointer(749,1), "Turn quick curses on"); + } else { + setWidgetContextMenuOption(1, new WidgetPointer(749,1), "Turn quick prayers on"); + } + setWidgetSprite(1209, new WidgetPointer(749,2)); + if (getDisplayMode() >= 2) { + setWidgetSprite(1207, new WidgetPointer(749,1)); + setWidgetPosition(25, 1, 0, 0, new WidgetPointer(749,2)); + setWidgetPosition(25, 1, 0, 0, new WidgetPointer(749,3)); + setWidgetPosition(3, 15, 0, 0, new WidgetPointer(749,4)); + setWidgetPosition(31, 7, 0, 0, new WidgetPointer(749,5)); + } else { + setWidgetSprite(1206, new WidgetPointer(749,1)); + setWidgetPosition(1, 1, 0, 0, new WidgetPointer(749,2)); + setWidgetPosition(1, 1, 0, 0, new WidgetPointer(749,3)); + setWidgetPosition(31, 15, 0, 0, new WidgetPointer(749,4)); + setWidgetPosition(7, 7, 0, 0, new WidgetPointer(749,5)); + } + return; +} diff --git a/dumps/scripts/2304.cs2 b/dumps/scripts/2304.cs2 new file mode 100644 index 0000000..d8315a1 --- /dev/null +++ b/dumps/scripts/2304.cs2 @@ -0,0 +1,5 @@ +void script_2304() { + setScriptCallOnGeneralDataChange(2305, "", new WidgetPointer(750,1)); + script_2306(); + return; +} diff --git a/dumps/scripts/2305.cs2 b/dumps/scripts/2305.cs2 new file mode 100644 index 0000000..c4a19e4 --- /dev/null +++ b/dumps/scripts/2305.cs2 @@ -0,0 +1,4 @@ +void script_2305() { + script_2306(); + return; +} diff --git a/dumps/scripts/2306.cs2 b/dumps/scripts/2306.cs2 new file mode 100644 index 0000000..d2b67ef --- /dev/null +++ b/dumps/scripts/2306.cs2 @@ -0,0 +1,15 @@ +void script_2306() { + int ivar0; + int ivar1; + int ivar2; + ivar0 = 31; + ivar1 = 0; + ivar2 = 31; + if (getRunEnergy() >= 100) { + ivar1 = 0; + } else { + ivar1 = subtract(ivar0, divide(multiply(ivar0, getRunEnergy()), 100)); + } + setWidgetSize(ivar2, ivar1, 0, 0, new WidgetPointer(750,4)); + return; +} diff --git a/dumps/scripts/2307.cs2 b/dumps/scripts/2307.cs2 new file mode 100644 index 0000000..fd1d4a7 --- /dev/null +++ b/dumps/scripts/2307.cs2 @@ -0,0 +1,4 @@ +void script_2307(int arg0) { + script_2309(arg0, globalint_119); + return; +} diff --git a/dumps/scripts/2308.cs2 b/dumps/scripts/2308.cs2 new file mode 100644 index 0000000..17aa250 --- /dev/null +++ b/dumps/scripts/2308.cs2 @@ -0,0 +1,8 @@ +void script_2308(int arg0,int arg1) { + if (getDisplayMode() >= 2) { + setWidgetSprite(1127, new WidgetPointer(arg0)); + } else { + setWidgetSprite(784, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/2309.cs2 b/dumps/scripts/2309.cs2 new file mode 100644 index 0000000..72d3c8a --- /dev/null +++ b/dumps/scripts/2309.cs2 @@ -0,0 +1,8 @@ +void script_2309(int arg0,int arg1) { + if (getDisplayMode() >= 2) { + setWidgetSprite(1207, new WidgetPointer(arg0)); + } else { + setWidgetSprite(1206, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/231.cs2 b/dumps/scripts/231.cs2 new file mode 100644 index 0000000..db50d8b --- /dev/null +++ b/dumps/scripts/231.cs2 @@ -0,0 +1,13 @@ +void script_231() { + setWidgetIsHidden(true, new WidgetPointer(594,148)); + setWidgetIsHidden(true, new WidgetPointer(594,149)); + setWidgetIsHidden(true, new WidgetPointer(594,150)); + setWidgetIsHidden(true, new WidgetPointer(594,151)); + setWidgetIsHidden(true, new WidgetPointer(594,165)); + setWidgetIsHidden(true, new WidgetPointer(594,166)); + setWidgetIsHidden(true, new WidgetPointer(594,117)); + setWidgetIsHidden(true, new WidgetPointer(594,62)); + setWidgetIsHidden(true, new WidgetPointer(594,34)); + setWidgetIsHidden(true, new WidgetPointer(594,121)); + return; +} diff --git a/dumps/scripts/2310.cs2 b/dumps/scripts/2310.cs2 new file mode 100644 index 0000000..e7f6593 --- /dev/null +++ b/dumps/scripts/2310.cs2 @@ -0,0 +1,6 @@ +void script_2310() { + setWidgetSprite(2560, new WidgetPointer(137,157)); + setWidgetSprite(2560, new WidgetPointer(137,155)); + setWidgetSprite(2561, new WidgetPointer(137,156)); + return; +} diff --git a/dumps/scripts/2311.cs2 b/dumps/scripts/2311.cs2 new file mode 100644 index 0000000..6253b92 --- /dev/null +++ b/dumps/scripts/2311.cs2 @@ -0,0 +1,6 @@ +void script_2311() { + setWidgetSprite(2558, new WidgetPointer(137,157)); + setWidgetSprite(2558, new WidgetPointer(137,155)); + setWidgetSprite(2559, new WidgetPointer(137,156)); + return; +} diff --git a/dumps/scripts/2312.cs2 b/dumps/scripts/2312.cs2 new file mode 100644 index 0000000..a97cc8b --- /dev/null +++ b/dumps/scripts/2312.cs2 @@ -0,0 +1,53 @@ +void script_2312() { + int ivar0; + ivar0 = 0; + while (ivar0 < 31) { + createExtraChild(new WidgetPointer(137,75), 4, ivar0); + setWidgetSize(46, 20, 0, 0); + setWidgetPosition(4, multiply(ivar0, 20), 0, 0); + setWidgetFont(496); + setWidgetTextAlignment(1, 1, 0); + setWidgetText(intToStr(add(ivar0, 1))); + setWidgetRGB(new Color(255, 255, 255)); + setWidgetContextMenuOption(1, "Select"); + setScriptCallOnClickContextMenu(2316, ivar0, "i"); + setScriptCallOnMouseEntered(1356, new WidgetPointer(-32768,3), -2147483643, 65280, "Iii"); + setScriptCallOnMouseExit(1356, new WidgetPointer(-32768,3), -2147483643, 16777215, "Iii"); + ivar0 = add(ivar0, 1); + } + setWidgetScrollMax(0, multiply(ivar0, 20), new WidgetPointer(137,75)); + script_31(8978508, 8978507, 792, 789, 790, 791, 773, 788); + ivar0 = 0; + while (ivar0 < 12) { + createExtraChild(new WidgetPointer(137,78), 4, ivar0); + setWidgetSize(158, 20, 0, 0); + setWidgetPosition(4, multiply(ivar0, 20), 0, 0); + setWidgetFont(496); + setWidgetTextAlignment(1, 1, 0); + setWidgetText(cs2method_3408(105, 115, 950, ivar0)); + setWidgetRGB(new Color(255, 255, 255)); + setWidgetContextMenuOption(1, "Select"); + setScriptCallOnClickContextMenu(2334, ivar0, "i"); + setScriptCallOnMouseEntered(1356, new WidgetPointer(-32768,3), -2147483643, 65280, "Iii"); + setScriptCallOnMouseExit(1356, new WidgetPointer(-32768,3), -2147483643, 16777215, "Iii"); + ivar0 = add(ivar0, 1); + } + setWidgetScrollMax(0, multiply(ivar0, 20), new WidgetPointer(137,78)); + script_31(8978511, 8978510, 792, 789, 790, 791, 773, 788); + setWidgetIsHidden(true, new WidgetPointer(137,75)); + setWidgetIsHidden(true, new WidgetPointer(137,74)); + setWidgetIsHidden(true, new WidgetPointer(137,76)); + setWidgetIsHidden(true, new WidgetPointer(137,78)); + setWidgetIsHidden(true, new WidgetPointer(137,77)); + setWidgetIsHidden(true, new WidgetPointer(137,79)); + setWidgetIsHidden(true, new WidgetPointer(137,81)); + setWidgetIsHidden(true, new WidgetPointer(137,82)); + setWidgetIsHidden(true, new WidgetPointer(137,80)); + setWidgetIsHidden(true, new WidgetPointer(137,68)); + setWidgetIsHidden(true, new WidgetPointer(137,69)); + setWidgetIsHidden(true, new WidgetPointer(137,70)); + setWidgetIsHidden(false, new WidgetPointer(137,71)); + setWidgetIsHidden(false, new WidgetPointer(137,72)); + setWidgetIsHidden(false, new WidgetPointer(137,73)); + return; +} diff --git a/dumps/scripts/2313.cs2 b/dumps/scripts/2313.cs2 new file mode 100644 index 0000000..6057e14 --- /dev/null +++ b/dumps/scripts/2313.cs2 @@ -0,0 +1,21 @@ +void script_2313() { + if (isWidgetHidden(new WidgetPointer(137,75))) { + setWidgetVFlip(1, new WidgetPointer(137,146)); + setWidgetIsHidden(false, new WidgetPointer(137,75)); + setWidgetIsHidden(false, new WidgetPointer(137,74)); + setWidgetIsHidden(false, new WidgetPointer(137,76)); + setWidgetIsHidden(false, new WidgetPointer(137,68)); + } else { + setWidgetVFlip(0, new WidgetPointer(137,146)); + setWidgetIsHidden(true, new WidgetPointer(137,75)); + setWidgetIsHidden(true, new WidgetPointer(137,74)); + setWidgetIsHidden(true, new WidgetPointer(137,76)); + setWidgetIsHidden(true, new WidgetPointer(137,68)); + } + setWidgetVFlip(0, new WidgetPointer(137,131)); + setWidgetIsHidden(true, new WidgetPointer(137,78)); + setWidgetIsHidden(true, new WidgetPointer(137,77)); + setWidgetIsHidden(true, new WidgetPointer(137,79)); + setWidgetIsHidden(true, new WidgetPointer(137,69)); + return; +} diff --git a/dumps/scripts/2314.cs2 b/dumps/scripts/2314.cs2 new file mode 100644 index 0000000..8914c9f --- /dev/null +++ b/dumps/scripts/2314.cs2 @@ -0,0 +1,21 @@ +void script_2314() { + if (isWidgetHidden(new WidgetPointer(137,78))) { + setWidgetVFlip(1, new WidgetPointer(137,131)); + setWidgetIsHidden(false, new WidgetPointer(137,78)); + setWidgetIsHidden(false, new WidgetPointer(137,77)); + setWidgetIsHidden(false, new WidgetPointer(137,79)); + setWidgetIsHidden(false, new WidgetPointer(137,69)); + } else { + setWidgetVFlip(0, new WidgetPointer(137,131)); + setWidgetIsHidden(true, new WidgetPointer(137,78)); + setWidgetIsHidden(true, new WidgetPointer(137,77)); + setWidgetIsHidden(true, new WidgetPointer(137,79)); + setWidgetIsHidden(true, new WidgetPointer(137,69)); + } + setWidgetVFlip(0, new WidgetPointer(137,146)); + setWidgetIsHidden(true, new WidgetPointer(137,75)); + setWidgetIsHidden(true, new WidgetPointer(137,74)); + setWidgetIsHidden(true, new WidgetPointer(137,76)); + setWidgetIsHidden(true, new WidgetPointer(137,68)); + return; +} diff --git a/dumps/scripts/2315.cs2 b/dumps/scripts/2315.cs2 new file mode 100644 index 0000000..9f3d810 --- /dev/null +++ b/dumps/scripts/2315.cs2 @@ -0,0 +1,13 @@ +void script_2315() { + setWidgetVFlip(0, new WidgetPointer(137,146)); + setWidgetIsHidden(true, new WidgetPointer(137,75)); + setWidgetIsHidden(true, new WidgetPointer(137,74)); + setWidgetIsHidden(true, new WidgetPointer(137,76)); + setWidgetIsHidden(true, new WidgetPointer(137,68)); + setWidgetVFlip(0, new WidgetPointer(137,131)); + setWidgetIsHidden(true, new WidgetPointer(137,78)); + setWidgetIsHidden(true, new WidgetPointer(137,77)); + setWidgetIsHidden(true, new WidgetPointer(137,79)); + setWidgetIsHidden(true, new WidgetPointer(137,69)); + return; +} diff --git a/dumps/scripts/2316.cs2 b/dumps/scripts/2316.cs2 new file mode 100644 index 0000000..25e7c7a --- /dev/null +++ b/dumps/scripts/2316.cs2 @@ -0,0 +1,9 @@ +void script_2316(int arg0) { + setWidgetText(new WidgetPointer(137,140), intToStr(add(arg0, 1))); + setWidgetVFlip(0, new WidgetPointer(137,146)); + setWidgetIsHidden(true, new WidgetPointer(137,75)); + setWidgetIsHidden(true, new WidgetPointer(137,76)); + setWidgetIsHidden(true, new WidgetPointer(137,74)); + setWidgetIsHidden(true, new WidgetPointer(137,68)); + return; +} diff --git a/dumps/scripts/2317.cs2 b/dumps/scripts/2317.cs2 new file mode 100644 index 0000000..0ee2716 --- /dev/null +++ b/dumps/scripts/2317.cs2 @@ -0,0 +1,4 @@ +void script_2317() { + script_2319(); + return; +} diff --git a/dumps/scripts/2318.cs2 b/dumps/scripts/2318.cs2 new file mode 100644 index 0000000..d505d30 --- /dev/null +++ b/dumps/scripts/2318.cs2 @@ -0,0 +1,9 @@ +void script_2318(int arg0) { + if (arg0 != 1) { + return; + } + playSoundEffect(2266, 1, 0); + bitconfig_8348 = subtract(1, bitconfig_8348); + script_2319(); + return; +} diff --git a/dumps/scripts/2319.cs2 b/dumps/scripts/2319.cs2 new file mode 100644 index 0000000..7043fee --- /dev/null +++ b/dumps/scripts/2319.cs2 @@ -0,0 +1,15 @@ +void script_2319() { + if (((boolean)bitconfig_8348)) { + setWidgetIsHidden(true, new WidgetPointer(762,0)); + setWidgetIsHidden(true, new WidgetPointer(763,0)); + setWidgetIsHidden(false, new WidgetPointer(667,0)); + setWidgetIsHidden(false, new WidgetPointer(763,1)); + } else { + setWidgetIsHidden(false, new WidgetPointer(762,0)); + setWidgetIsHidden(false, new WidgetPointer(763,0)); + setWidgetIsHidden(true, new WidgetPointer(667,0)); + setWidgetIsHidden(true, new WidgetPointer(763,1)); + } + script_722(); + return; +} diff --git a/dumps/scripts/232.cs2 b/dumps/scripts/232.cs2 new file mode 100644 index 0000000..fad14d2 --- /dev/null +++ b/dumps/scripts/232.cs2 @@ -0,0 +1,18 @@ +void script_232() { + setWidgetIsHidden(true, new WidgetPointer(594,62)); + setWidgetIsHidden(true, new WidgetPointer(594,117)); + setWidgetIsHidden(true, new WidgetPointer(594,121)); + setWidgetIsHidden(true, new WidgetPointer(594,34)); + if (isWidgetHidden(new WidgetPointer(594,61))) { + setWidgetIsHidden(false, new WidgetPointer(594,62)); + } else if (isWidgetHidden(new WidgetPointer(594,104))) { + setWidgetIsHidden(false, new WidgetPointer(594,117)); + } else if (isWidgetHidden(new WidgetPointer(594,120))) { + setWidgetIsHidden(false, new WidgetPointer(594,121)); + } else { + if (isWidgetHidden(new WidgetPointer(594,33))) { + setWidgetIsHidden(false, new WidgetPointer(594,34)); + } + } + return; +} diff --git a/dumps/scripts/2320.cs2 b/dumps/scripts/2320.cs2 new file mode 100644 index 0000000..0724a66 --- /dev/null +++ b/dumps/scripts/2320.cs2 @@ -0,0 +1,4 @@ +void script_2320() { + setWidgetAnimation(1378, new WidgetPointer(305,2)); + return; +} diff --git a/dumps/scripts/2321.cs2 b/dumps/scripts/2321.cs2 new file mode 100644 index 0000000..9ed5d51 --- /dev/null +++ b/dumps/scripts/2321.cs2 @@ -0,0 +1,11 @@ +void script_2321(int arg0) { + if (getWidgetActualX(new WidgetPointer(arg0)) < subtract(getWidgetActualWidth(new WidgetPointer(306,1)), 1)) { + if (getWidgetActualX(new WidgetPointer(arg0)) == add(140, getWidgetActualWidth(new WidgetPointer(arg0)))) { + setScriptCallOnGameloop(2323, new WidgetPointer(306,9), "I", new WidgetPointer(306,22)); + } + setWidgetPosition(add(1, getWidgetActualX(new WidgetPointer(arg0))), getWidgetActualY(new WidgetPointer(arg0)), 0, 0, new WidgetPointer(arg0)); + } else { + script_2322(); + } + return; +} diff --git a/dumps/scripts/2322.cs2 b/dumps/scripts/2322.cs2 new file mode 100644 index 0000000..0a01f4a --- /dev/null +++ b/dumps/scripts/2322.cs2 @@ -0,0 +1,11 @@ +void script_2322() { + int ivar0; + ivar0 = 20054024; + globalint_763 = cs2method_3408(105, 109, 208, rndExcl(getCommonDefinitionSize(208))); + if (globalint_763 != -1) { + setWidgetModel(globalint_763, new WidgetPointer(ivar0)); + } + setWidgetPosition(subtract(0, getWidgetActualWidth(new WidgetPointer(ivar0))), 120, 0, 0, new WidgetPointer(ivar0)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(306,21)); + return; +} diff --git a/dumps/scripts/2323.cs2 b/dumps/scripts/2323.cs2 new file mode 100644 index 0000000..dfc6a01 --- /dev/null +++ b/dumps/scripts/2323.cs2 @@ -0,0 +1,11 @@ +void script_2323(int arg0) { + if (getWidgetActualX(new WidgetPointer(arg0)) < subtract(getWidgetActualWidth(new WidgetPointer(306,1)), 1)) { + if (getWidgetActualX(new WidgetPointer(arg0)) == add(140, getWidgetActualWidth(new WidgetPointer(arg0)))) { + setScriptCallOnGameloop(399, new WidgetPointer(306,6), "I", new WidgetPointer(306,19)); + } + setWidgetPosition(add(1, getWidgetActualX(new WidgetPointer(arg0))), getWidgetActualY(new WidgetPointer(arg0)), 0, 0, new WidgetPointer(arg0)); + } else { + script_2324(); + } + return; +} diff --git a/dumps/scripts/2324.cs2 b/dumps/scripts/2324.cs2 new file mode 100644 index 0000000..eaba857 --- /dev/null +++ b/dumps/scripts/2324.cs2 @@ -0,0 +1,11 @@ +void script_2324() { + int ivar0; + ivar0 = 20054025; + globalint_764 = cs2method_3408(105, 109, 208, rndExcl(getCommonDefinitionSize(208))); + if (globalint_764 != -1) { + setWidgetModel(globalint_764, new WidgetPointer(ivar0)); + } + setWidgetPosition(subtract(0, getWidgetActualWidth(new WidgetPointer(ivar0))), 120, 0, 0, new WidgetPointer(ivar0)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(306,22)); + return; +} diff --git a/dumps/scripts/2325.cs2 b/dumps/scripts/2325.cs2 new file mode 100644 index 0000000..e7bb795 --- /dev/null +++ b/dumps/scripts/2325.cs2 @@ -0,0 +1,26 @@ +void script_2325() { + if (((boolean)globalint_766) || (globalint_766 == 2)) { + messageType0("You can't do that right now."); + return; + } + playSoundEffect(6421, 1, 0); + if ((getWidgetActualX(new WidgetPointer(306,6)) >= getWidgetActualX(new WidgetPointer(306,18))) && (getWidgetActualX(new WidgetPointer(306,6)) < add(getWidgetActualX(new WidgetPointer(306,18)), getWidgetActualWidth(new WidgetPointer(306,18))))) { + globalint_765 = 1; + script_2326(globalint_761); + } + if ((getWidgetActualX(new WidgetPointer(306,7)) >= getWidgetActualX(new WidgetPointer(306,18))) && (getWidgetActualX(new WidgetPointer(306,7)) < add(getWidgetActualX(new WidgetPointer(306,18)), getWidgetActualWidth(new WidgetPointer(306,18))))) { + globalint_765 = 2; + script_2326(globalint_762); + } + if ((getWidgetActualX(new WidgetPointer(306,8)) >= getWidgetActualX(new WidgetPointer(306,18))) && (getWidgetActualX(new WidgetPointer(306,8)) < add(getWidgetActualX(new WidgetPointer(306,18)), getWidgetActualWidth(new WidgetPointer(306,18))))) { + globalint_765 = 3; + script_2326(globalint_763); + } + if ((getWidgetActualX(new WidgetPointer(306,9)) >= getWidgetActualX(new WidgetPointer(306,18))) && (getWidgetActualX(new WidgetPointer(306,9)) < add(getWidgetActualX(new WidgetPointer(306,18)), getWidgetActualWidth(new WidgetPointer(306,18))))) { + globalint_765 = 4; + script_2326(globalint_764); + } + globalint_766 = 1; + setScriptCallOnGameloop(2328, new WidgetPointer(-32768,3), "I", new WidgetPointer(306,10)); + return; +} diff --git a/dumps/scripts/2326.cs2 b/dumps/scripts/2326.cs2 new file mode 100644 index 0000000..9a0d95c --- /dev/null +++ b/dumps/scripts/2326.cs2 @@ -0,0 +1,32 @@ +void script_2326(int arg0) { + int ivar1; + ivar1 = getClientCycle(); + switch (arg0) { + case 32826: + case 32820: + case 32828: + globalint_767 = 0; + setWidgetIsHidden(false, new WidgetPointer(306,25)); + setWidgetText(new WidgetPointer(306,26), "Incorrect"); + playSoundEffect(6424, 1, 0); + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(306,26)); + setScriptCallOnGameloop(2327, ivar1, "i", new WidgetPointer(306,25)); + break; + default: + globalint_767 = add(globalint_767, 1); + if (globalint_767 == 10) { + setWidgetIsHidden(false, new WidgetPointer(306,27)); + setWidgetContextMenuOption(1, new WidgetPointer(306,29), "Train"); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(306,23)); + } else { + setWidgetIsHidden(false, new WidgetPointer(306,25)); + setWidgetText(new WidgetPointer(306,26), "Correct"); + playSoundEffect(6423, 1, 0); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(306,26)); + setScriptCallOnGameloop(2327, ivar1, "i", new WidgetPointer(306,25)); + } + } + setWidgetText(new WidgetPointer(306,3), "Correct: " + intToStr(globalint_767) + "/" + intToStr(10)); + playSoundEffect(6423, 1, 0); + return; +} diff --git a/dumps/scripts/2327.cs2 b/dumps/scripts/2327.cs2 new file mode 100644 index 0000000..b42d8e5 --- /dev/null +++ b/dumps/scripts/2327.cs2 @@ -0,0 +1,7 @@ +void script_2327(int arg0) { + if (getClientCycle() >= add(100, arg0)) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(306,25)); + setWidgetIsHidden(true, new WidgetPointer(306,25)); + } + return; +} diff --git a/dumps/scripts/2328.cs2 b/dumps/scripts/2328.cs2 new file mode 100644 index 0000000..46a9506 --- /dev/null +++ b/dumps/scripts/2328.cs2 @@ -0,0 +1,51 @@ +void script_2328(int arg0) { + if (((boolean)globalint_766)) { + if (getWidgetActualY(new WidgetPointer(arg0)) > 100) { + setWidgetPosition(getWidgetActualX(new WidgetPointer(arg0)), subtract(getWidgetActualY(new WidgetPointer(arg0)), 2), 0, 0, new WidgetPointer(arg0)); + playSoundEffect(6422, 1, 0); + if (getWidgetActualY(new WidgetPointer(arg0)) < 170) { + switch (globalint_765) { + case 1: + setWidgetPosition(getWidgetActualX(new WidgetPointer(306,6)), subtract(getWidgetActualY(new WidgetPointer(306,6)), 2), 0, 0, new WidgetPointer(306,6)); + break; + case 2: + setWidgetPosition(getWidgetActualX(new WidgetPointer(306,7)), subtract(getWidgetActualY(new WidgetPointer(306,7)), 2), 0, 0, new WidgetPointer(306,7)); + break; + case 3: + setWidgetPosition(getWidgetActualX(new WidgetPointer(306,8)), subtract(getWidgetActualY(new WidgetPointer(306,8)), 2), 0, 0, new WidgetPointer(306,8)); + break; + case 4: + setWidgetPosition(getWidgetActualX(new WidgetPointer(306,9)), subtract(getWidgetActualY(new WidgetPointer(306,9)), 2), 0, 0, new WidgetPointer(306,9)); + } + } + } else { + setWidgetPosition(getWidgetActualX(new WidgetPointer(arg0)), 100, 0, 0, new WidgetPointer(arg0)); + globalint_766 = 2; + switch (globalint_765) { + case 1: + script_1411(); + break; + case 2: + script_2056(); + break; + case 3: + script_2322(); + break; + case 4: + script_2324(); + } + } + } else { + if (globalint_766 == 2) { + if (getWidgetActualY(new WidgetPointer(arg0)) < 200) { + setWidgetPosition(getWidgetActualX(new WidgetPointer(arg0)), add(getWidgetActualY(new WidgetPointer(arg0)), 2), 0, 0, new WidgetPointer(arg0)); + } else { + setWidgetPosition(getWidgetActualX(new WidgetPointer(arg0)), 200, 0, 0, new WidgetPointer(arg0)); + globalint_766 = 0; + globalint_765 = 0; + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + } + } + } + return; +} diff --git a/dumps/scripts/2329.cs2 b/dumps/scripts/2329.cs2 new file mode 100644 index 0000000..55e25dd --- /dev/null +++ b/dumps/scripts/2329.cs2 @@ -0,0 +1,93 @@ +void script_2329() { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(496,4)); + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(496,5)); + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(496,6)); + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(496,7)); + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(496,8)); + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(496,9)); + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(496,10)); + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(496,11)); + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(496,12)); + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(496,13)); + if (((boolean)bitconfig_3264)) { + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(496,4)); + } else if (bitconfig_3264 == 2) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,4)); + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(496,5)); + } else if (bitconfig_3264 == 3) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,4)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,5)); + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(496,6)); + } else if (bitconfig_3264 == 4) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,4)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,5)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,6)); + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(496,7)); + } else if (bitconfig_3264 == 5) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,4)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,5)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,6)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,7)); + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(496,8)); + } else if (bitconfig_3264 == 6) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,4)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,5)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,6)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,7)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,8)); + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(496,9)); + } else if (bitconfig_3264 == 7) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,4)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,5)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,6)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,7)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,8)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,9)); + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(496,10)); + } else if (bitconfig_3264 == 8) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,4)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,5)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,6)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,7)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,8)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,9)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,10)); + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(496,11)); + } else if (bitconfig_3264 == 9) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,4)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,5)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,6)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,7)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,8)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,9)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,10)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,11)); + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(496,12)); + } else if (bitconfig_3264 == 10) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,4)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,5)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,6)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,7)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,8)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,9)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,10)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,11)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,12)); + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(496,13)); + } else { + if (bitconfig_3264 == 11) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,4)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,5)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,6)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,7)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,8)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,9)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,10)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,11)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,12)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,12)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(496,13)); + } + } + return; +} diff --git a/dumps/scripts/233.cs2 b/dumps/scripts/233.cs2 new file mode 100644 index 0000000..7b74418 --- /dev/null +++ b/dumps/scripts/233.cs2 @@ -0,0 +1,4 @@ +void script_233() { + script_231(); + return; +} diff --git a/dumps/scripts/2330.cs2 b/dumps/scripts/2330.cs2 new file mode 100644 index 0000000..f78bcc7 --- /dev/null +++ b/dumps/scripts/2330.cs2 @@ -0,0 +1,4 @@ +void script_2330(int arg0) { + setWidgetIsHidden(false, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/2331.cs2 b/dumps/scripts/2331.cs2 new file mode 100644 index 0000000..7f1128f --- /dev/null +++ b/dumps/scripts/2331.cs2 @@ -0,0 +1,4 @@ +void script_2331(int arg0) { + setWidgetIsHidden(true, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/2332.cs2 b/dumps/scripts/2332.cs2 new file mode 100644 index 0000000..080175d --- /dev/null +++ b/dumps/scripts/2332.cs2 @@ -0,0 +1,11 @@ +string script_2332(string arg0,string arg1,string arg2) { + int ivar0; + int ivar1; + ivar0 = strIndexof(0, arg0, arg1); + ivar1 = strLength(arg1); + while (ivar0 != -1) { + arg0 = substr(0, ivar0, arg0) + arg2 + substr(add(ivar0, ivar1), strLength(arg0), arg0); + ivar0 = strIndexof(ivar0, arg0, arg1); + } + return arg0; +} diff --git a/dumps/scripts/2333.cs2 b/dumps/scripts/2333.cs2 new file mode 100644 index 0000000..1bf82fe --- /dev/null +++ b/dumps/scripts/2333.cs2 @@ -0,0 +1,4 @@ +void script_2333(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12,int arg13,int arg14,int arg15,int arg16) { + script_2335(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); + return; +} diff --git a/dumps/scripts/2334.cs2 b/dumps/scripts/2334.cs2 new file mode 100644 index 0000000..2fabba7 --- /dev/null +++ b/dumps/scripts/2334.cs2 @@ -0,0 +1,9 @@ +void script_2334(int arg0) { + setWidgetText(new WidgetPointer(137,125), cs2method_3408(105, 115, 950, arg0)); + setWidgetVFlip(0, new WidgetPointer(137,131)); + setWidgetIsHidden(true, new WidgetPointer(137,78)); + setWidgetIsHidden(true, new WidgetPointer(137,79)); + setWidgetIsHidden(true, new WidgetPointer(137,77)); + setWidgetIsHidden(true, new WidgetPointer(137,69)); + return; +} diff --git a/dumps/scripts/2335.cs2 b/dumps/scripts/2335.cs2 new file mode 100644 index 0000000..5ef7ced --- /dev/null +++ b/dumps/scripts/2335.cs2 @@ -0,0 +1,71 @@ +void script_2335(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12,int arg13,int arg14,int arg15,int arg16) { + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + int ivar22; + if (bitconfig_8725 < 4000) { + setWidgetText(new WidgetPointer(arg15), intToStr(bitconfig_8725)); + } else { + setWidgetText(new WidgetPointer(arg15), "Max"); + } + if (bitconfig_3939 < 4000) { + setWidgetText(new WidgetPointer(arg10), intToStr(bitconfig_3939)); + } else { + setWidgetText(new WidgetPointer(arg10), "Max"); + } + if (bitconfig_3941 < 4000) { + setWidgetText(new WidgetPointer(arg11), intToStr(bitconfig_3941)); + } else { + setWidgetText(new WidgetPointer(arg11), "Max"); + } + if (bitconfig_3938 < 4000) { + setWidgetText(new WidgetPointer(arg12), intToStr(bitconfig_3938)); + } else { + setWidgetText(new WidgetPointer(arg12), "Max"); + } + if (bitconfig_3942 < 4000) { + setWidgetText(new WidgetPointer(arg13), intToStr(bitconfig_3942)); + } else { + setWidgetText(new WidgetPointer(arg13), "Max"); + } + ivar17 = getMaxLineWidth(512, 494, getWidgetText(new WidgetPointer(arg15))); + ivar18 = getMaxLineWidth(512, 494, getWidgetText(new WidgetPointer(arg10))); + ivar19 = getMaxLineWidth(512, 494, getWidgetText(new WidgetPointer(arg11))); + ivar20 = getMaxLineWidth(512, 494, getWidgetText(new WidgetPointer(arg12))); + ivar21 = getMaxLineWidth(512, 494, getWidgetText(new WidgetPointer(arg13))); + ivar22 = arg5; + ivar22 = max(ivar22, add(add(arg16, 10), ivar17)); + ivar22 = max(ivar22, add(add(arg6, 10), ivar18)); + ivar22 = max(ivar22, add(add(arg7, 10), ivar19)); + ivar22 = max(ivar22, add(add(arg8, 10), ivar20)); + ivar22 = max(ivar22, add(add(arg9, 10), ivar21)); + setWidgetSize(ivar22, getWidgetActualHeight(new WidgetPointer(arg0)), 0, 0, new WidgetPointer(arg0)); + if (bitconfig_8725 < 40) { + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(arg14)); + } else { + setWidgetRGB(new Color(102, 255, 255), new WidgetPointer(arg14)); + } + if (bitconfig_3939 < 40) { + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(arg1)); + } else { + setWidgetRGB(new Color(102, 255, 255), new WidgetPointer(arg1)); + } + if (bitconfig_3941 < 40) { + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(arg2)); + } else { + setWidgetRGB(new Color(102, 255, 255), new WidgetPointer(arg2)); + } + if (bitconfig_3938 < 40) { + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(arg3)); + } else { + setWidgetRGB(new Color(102, 255, 255), new WidgetPointer(arg3)); + } + if (bitconfig_3942 < 40) { + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(arg4)); + } else { + setWidgetRGB(new Color(102, 255, 255), new WidgetPointer(arg4)); + } + return; +} diff --git a/dumps/scripts/2336.cs2 b/dumps/scripts/2336.cs2 new file mode 100644 index 0000000..3823c4b --- /dev/null +++ b/dumps/scripts/2336.cs2 @@ -0,0 +1,7 @@ +void script_2336(int arg0,int arg1) { + if (getDisplayMode() != arg1) { + setScriptCallOnGameloop(2336, new WidgetPointer(arg0), getDisplayMode(), "Ii", new WidgetPointer(arg0)); + script_2337(arg0); + } + return; +} diff --git a/dumps/scripts/2337.cs2 b/dumps/scripts/2337.cs2 new file mode 100644 index 0000000..0e00d1c --- /dev/null +++ b/dumps/scripts/2337.cs2 @@ -0,0 +1,8 @@ +void script_2337(int arg0) { + if (getDisplayMode() >= 2) { + setWidgetPosition(add(getWidgetActualWidth(new WidgetPointer(746,13)), 10), 10, 2, 0, new WidgetPointer(arg0)); + } else { + setWidgetPosition(10, 10, 2, 0, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/2338.cs2 b/dumps/scripts/2338.cs2 new file mode 100644 index 0000000..e6fd045 --- /dev/null +++ b/dumps/scripts/2338.cs2 @@ -0,0 +1,4 @@ +void script_2338() { + script_2339(); + return; +} diff --git a/dumps/scripts/2339.cs2 b/dumps/scripts/2339.cs2 new file mode 100644 index 0000000..326db7b --- /dev/null +++ b/dumps/scripts/2339.cs2 @@ -0,0 +1,46 @@ +void script_2339() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + globalint_770 = 0; + ivar0 = subtract(extractX(getMyPositionHash()), mod(extractX(getMyPositionHash()), 64)); + ivar1 = subtract(extractY(getMyPositionHash()), mod(extractY(getMyPositionHash()), 64)); + ivar2 = 574; + ivar3 = 942; + ivar4 = addToCoordinate(0, ivar0, 0, ivar1); + cs2method5405(0, 14); + cs2method5405(1, 14); + cs2method5406(0, 0, addToCoordinate(ivar4, 20, 0, 30), ivar3, addToCoordinate(ivar4, 27, 0, 26), ivar3, 0); + cs2method5406(1, 0, addToCoordinate(ivar4, 25, 0, 36), ivar2, addToCoordinate(ivar4, 31, 0, 33), ivar2, 0); + cs2method5406(0, 1, addToCoordinate(ivar4, 41, 0, 36), ivar3, addToCoordinate(ivar4, 41, 0, 39), ivar3, 0); + cs2method5406(1, 1, addToCoordinate(ivar4, 38, 0, 42), ivar2, addToCoordinate(ivar4, 38, 0, 46), ivar2, 0); + cs2method5406(0, 2, addToCoordinate(ivar4, 35, 0, 49), ivar3, addToCoordinate(ivar4, 37, 0, 51), ivar3, 0); + cs2method5406(1, 2, addToCoordinate(ivar4, 38, 0, 57), ivar2, addToCoordinate(ivar4, 40, 0, 57), ivar2, 0); + cs2method5406(0, 3, addToCoordinate(ivar4, 35, 0, 40), ivar3, addToCoordinate(ivar4, 31, 0, 37), ivar3, 0); + cs2method5406(1, 3, addToCoordinate(ivar4, 38, 0, 54), ivar2, addToCoordinate(ivar4, 37, 0, 54), ivar2, 0); + cs2method5406(0, 4, addToCoordinate(ivar4, 24, 0, 41), ivar3, addToCoordinate(ivar4, 24, 0, 38), ivar3, 0); + cs2method5406(1, 4, addToCoordinate(ivar4, 12, 0, 43), ivar2, addToCoordinate(ivar4, 7, 0, 41), ivar2, 0); + cs2method5406(0, 5, addToCoordinate(ivar4, 30, 0, 43), ivar3, addToCoordinate(ivar4, 31, 0, 43), ivar3, 0); + cs2method5406(1, 5, addToCoordinate(ivar4, 8, 0, 41), ivar2, addToCoordinate(ivar4, 0, 0, 39), ivar2, 0); + cs2method5406(0, 6, addToCoordinate(ivar4, 35, 0, 43), ivar3, addToCoordinate(ivar4, 37, 0, 43), ivar3, 0); + cs2method5406(1, 6, addToCoordinate(ivar4, 36, 0, 27), ivar2, addToCoordinate(ivar4, 27, 0, 28), ivar2, 0); + cs2method5406(0, 7, addToCoordinate(ivar4, 35, 0, 45), ivar3, addToCoordinate(ivar4, 31, 0, 44), ivar3, 0); + cs2method5406(1, 7, addToCoordinate(ivar4, 36, 0, 30), ivar2, addToCoordinate(ivar4, 35, 0, 31), ivar2, 0); + cs2method5406(0, 8, addToCoordinate(ivar4, 41, 0, 40), ivar3, addToCoordinate(ivar4, 42, 0, 40), ivar3, 0); + cs2method5406(1, 8, addToCoordinate(ivar4, 54, 0, 39), ivar2, addToCoordinate(ivar4, 56, 0, 39), ivar2, 0); + cs2method5406(0, 9, addToCoordinate(ivar4, 44, 0, 42), ivar3, addToCoordinate(ivar4, 44, 0, 45), ivar3, 0); + cs2method5406(1, 9, addToCoordinate(ivar4, 54, 0, 40), ivar2, addToCoordinate(ivar4, 53, 0, 39), ivar2, 0); + cs2method5406(0, 10, addToCoordinate(ivar4, 30, 0, 51), ivar3, addToCoordinate(ivar4, 20, 0, 50), ivar3, 0); + cs2method5406(1, 10, addToCoordinate(ivar4, 32, 0, 40), ivar2, addToCoordinate(ivar4, 26, 0, 42), ivar2, 0); + cs2method5406(0, 11, addToCoordinate(ivar4, 22, 0, 39), ivar3, addToCoordinate(ivar4, 22, 0, 36), ivar3, 0); + cs2method5406(1, 11, addToCoordinate(ivar4, 33, 0, 41), ivar2, addToCoordinate(ivar4, 34, 0, 41), ivar2, 0); + cs2method5406(0, 12, addToCoordinate(ivar4, 32, 0, 29), ivar3, addToCoordinate(ivar4, 42, 0, 27), ivar3, 0); + cs2method5406(1, 12, addToCoordinate(ivar4, 32, 0, 42), ivar2, addToCoordinate(ivar4, 32, 0, 43), ivar2, 0); + cs2method5406(0, 13, addToCoordinate(ivar4, 47, 0, 40), 778, addToCoordinate(ivar4, 47, 0, 46), 778, 0); + cs2method5406(1, 13, addToCoordinate(ivar4, 31, 0, 41), ivar2, addToCoordinate(ivar4, 28, 0, 41), ivar2, 0); + setScriptCallOnMinimapRelatedSetting3(2344, "", new WidgetPointer(558,0)); + cameraMethod5502(0, globalint_770, 500, 900, 1, globalint_770); + return; +} diff --git a/dumps/scripts/234.cs2 b/dumps/scripts/234.cs2 new file mode 100644 index 0000000..7cb2251 --- /dev/null +++ b/dumps/scripts/234.cs2 @@ -0,0 +1,13 @@ +void script_234(int arg0) { + int ivar1; + string svar0; + svar0 = ""; + ivar1 = -1; + if (setWidgetRegister(new WidgetPointer(594,94), arg0)) { + globalstring_24 = cs2method1802(); + globalint_792 = globalint_791; + script_240(); + script_217(); + } + return; +} diff --git a/dumps/scripts/2340.cs2 b/dumps/scripts/2340.cs2 new file mode 100644 index 0000000..aa48aad --- /dev/null +++ b/dumps/scripts/2340.cs2 @@ -0,0 +1,6 @@ +void script_2340() { + globalint_770 = 2; + cameraMethod5502(0, globalint_770, 500, 900, 1, globalint_770); + setScriptCallOnMinimapRelatedSetting3(2344, "", new WidgetPointer(558,0)); + return; +} diff --git a/dumps/scripts/2341.cs2 b/dumps/scripts/2341.cs2 new file mode 100644 index 0000000..3750ef4 --- /dev/null +++ b/dumps/scripts/2341.cs2 @@ -0,0 +1,6 @@ +void script_2341() { + globalint_770 = 4; + cameraMethod5502(0, globalint_770, 600, 900, 1, globalint_770); + setScriptCallOnMinimapRelatedSetting3(2344, "", new WidgetPointer(558,0)); + return; +} diff --git a/dumps/scripts/2342.cs2 b/dumps/scripts/2342.cs2 new file mode 100644 index 0000000..7683099 --- /dev/null +++ b/dumps/scripts/2342.cs2 @@ -0,0 +1,6 @@ +void script_2342() { + globalint_770 = 6; + cameraMethod5502(0, globalint_770, 600, 900, 1, globalint_770); + setScriptCallOnMinimapRelatedSetting3(2344, "", new WidgetPointer(558,0)); + return; +} diff --git a/dumps/scripts/2343.cs2 b/dumps/scripts/2343.cs2 new file mode 100644 index 0000000..1eb3007 --- /dev/null +++ b/dumps/scripts/2343.cs2 @@ -0,0 +1,6 @@ +void script_2343() { + globalint_770 = 8; + cameraMethod5502(0, globalint_770, 500, 900, 1, globalint_770); + setScriptCallOnMinimapRelatedSetting3(2344, "", new WidgetPointer(558,0)); + return; +} diff --git a/dumps/scripts/2344.cs2 b/dumps/scripts/2344.cs2 new file mode 100644 index 0000000..c82fff2 --- /dev/null +++ b/dumps/scripts/2344.cs2 @@ -0,0 +1,30 @@ +void script_2344() { + if (globalint_770 < cs2method5407(0)) { + flow_1: + globalint_770 = add(globalint_770, 1); + SWITCH (globalint_770) { + case 9: + GOTO flow_2 + case 10: + GOTO flow_2 + case 11: + GOTO flow_2 + case 12: + GOTO flow_3 + } + setScriptCallOnMinimapRelatedSetting3(-1, "", new WidgetPointer(558,0)); + cameraMethod5502(0, globalint_770, 900, 500, 1, globalint_770); + GOTO flow_4 + flow_2: + setScriptCallOnMinimapRelatedSetting3(2344, "", new WidgetPointer(558,0)); + cameraMethod5502(0, globalint_770, 900, 900, 1, globalint_770); + GOTO flow_4 + flow_3: + setScriptCallOnMinimapRelatedSetting3(-1, "", new WidgetPointer(558,0)); + cameraMethod5502(0, globalint_770, 900, 100, 1, globalint_770); + flow_4: + } else { + globalint_770 = 0; + } + return; +} diff --git a/dumps/scripts/2345.cs2 b/dumps/scripts/2345.cs2 new file mode 100644 index 0000000..53c3424 --- /dev/null +++ b/dumps/scripts/2345.cs2 @@ -0,0 +1,26 @@ +void script_2345() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + globalint_769 = 0; + ivar0 = subtract(extractX(getMyPositionHash()), mod(extractX(getMyPositionHash()), 64)); + ivar1 = subtract(extractY(getMyPositionHash()), mod(extractY(getMyPositionHash()), 64)); + ivar2 = addToCoordinate(0, ivar0, 0, ivar1); + ivar3 = addToCoordinate(ivar2, extractX(507944), 0, extractY(507944)); + cs2method5405(0, 5); + cs2method5406(0, 0, addToCoordinate(ivar3, 0, 0, -5), 800, addToCoordinate(ivar3, 0, 0, -5), 900, 0); + cs2method5406(0, 1, addToCoordinate(ivar3, -5, 0, -1), 800, addToCoordinate(ivar3, -5, 0, 0), 900, 0); + cs2method5406(0, 2, addToCoordinate(ivar3, -1, 0, 5), 800, addToCoordinate(ivar3, 0, 0, 5), 900, 0); + cs2method5406(0, 3, addToCoordinate(ivar3, 5, 0, 1), 800, addToCoordinate(ivar3, 5, 0, 0), 900, 0); + cs2method5406(0, 4, addToCoordinate(ivar3, 0, 0, -3), 800, addToCoordinate(ivar3, 0, 0, -3), 900, 0); + cs2method5405(1, 5); + cs2method5406(1, 0, ivar3, 400, ivar3, 400, 0); + cs2method5406(1, 1, ivar3, 400, ivar3, 400, 0); + cs2method5406(1, 2, ivar3, 400, ivar3, 400, 0); + cs2method5406(1, 3, ivar3, 400, ivar3, 400, 0); + cs2method5406(1, 4, ivar3, 500, ivar3, 500, 0); + cameraMethod5502(0, 0, 200, 200, 1, 0); + setScriptCallOnMinimapRelatedSetting3(2346, "", new WidgetPointer(582,0)); + return; +} diff --git a/dumps/scripts/2346.cs2 b/dumps/scripts/2346.cs2 new file mode 100644 index 0000000..dc97147 --- /dev/null +++ b/dumps/scripts/2346.cs2 @@ -0,0 +1,15 @@ +void script_2346() { + globalint_769 = add(globalint_769, 1); + if (globalint_769 >= subtract(cs2method5407(0), 1)) { + globalint_769 = 0; + setScriptCallOnMinimapRelatedSetting3(-1, "", new WidgetPointer(582,0)); + return; + } + if (globalint_769 == subtract(cs2method5407(0), 2)) { + cameraMethod5502(0, globalint_769, 200, 75, 1, globalint_769); + } else { + cameraMethod5502(0, globalint_769, 200, 200, 1, globalint_769); + } + setScriptCallOnMinimapRelatedSetting3(2346, "", new WidgetPointer(582,0)); + return; +} diff --git a/dumps/scripts/2347.cs2 b/dumps/scripts/2347.cs2 new file mode 100644 index 0000000..13f1e8d --- /dev/null +++ b/dumps/scripts/2347.cs2 @@ -0,0 +1,39 @@ +void script_2347(int arg0) { + if (((boolean)arg0)) { + if (bitconfig_6048 >= 250) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(723,6)); + } else if (((boolean)bitconfig_6048)) { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(723,6)); + } else { + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(723,6)); + } + } + if (arg0 == 2) { + if (bitconfig_6112 >= 60) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(723,7)); + } else if (((boolean)bitconfig_6112)) { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(723,7)); + } else { + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(723,7)); + } + } + if (arg0 == 3) { + if (bitconfig_6289 >= 240) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(723,8)); + } else if (((boolean)bitconfig_6289)) { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(723,8)); + } else { + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(723,8)); + } + } + if (arg0 == 4) { + if (bitconfig_6775 >= 100) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(723,9)); + } else if (((boolean)bitconfig_6775)) { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(723,9)); + } else { + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(723,9)); + } + } + return; +} diff --git a/dumps/scripts/2348.cs2 b/dumps/scripts/2348.cs2 new file mode 100644 index 0000000..1fe4b03 --- /dev/null +++ b/dumps/scripts/2348.cs2 @@ -0,0 +1,4 @@ +void script_2348(int arg0,int arg1,int arg2) { + script_2349(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/2349.cs2 b/dumps/scripts/2349.cs2 new file mode 100644 index 0000000..fe2113d --- /dev/null +++ b/dumps/scripts/2349.cs2 @@ -0,0 +1,10 @@ +void script_2349(int arg0,int arg1,int arg2) { + if (script_19(arg1, -1) >= arg2) { + setWidgetRGB(new Color(0, 204, 0), new WidgetPointer(arg0)); + setWidgetText(new WidgetPointer(arg0), intToStr(arg2) + "/" + intToStr(arg2)); + } else { + setWidgetRGB(new Color(192, 0, 0), new WidgetPointer(arg0)); + setWidgetText(new WidgetPointer(arg0), script_20(script_19(arg1, -1)) + "/" + intToStr(arg2)); + } + return; +} diff --git a/dumps/scripts/235.cs2 b/dumps/scripts/235.cs2 new file mode 100644 index 0000000..061cc60 --- /dev/null +++ b/dumps/scripts/235.cs2 @@ -0,0 +1,8 @@ +void script_235() { + if (stringMethod4107(globalstring_24, "") != 0) { + script_220(); + } else { + message(26, 0, "You must first select a name from the list."); + } + return; +} diff --git a/dumps/scripts/2350.cs2 b/dumps/scripts/2350.cs2 new file mode 100644 index 0000000..a6c9203 --- /dev/null +++ b/dumps/scripts/2350.cs2 @@ -0,0 +1,4 @@ +void script_2350(int arg0,int arg1) { + script_2351(arg0, arg1); + return; +} diff --git a/dumps/scripts/2351.cs2 b/dumps/scripts/2351.cs2 new file mode 100644 index 0000000..e0e5d14 --- /dev/null +++ b/dumps/scripts/2351.cs2 @@ -0,0 +1,8 @@ +void script_2351(int arg0,int arg1) { + if (getItemAmtInContainer(93, arg1) > 0) { + setWidgetRGB(new Color(0, 204, 0), new WidgetPointer(arg0)); + } else { + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/2352.cs2 b/dumps/scripts/2352.cs2 new file mode 100644 index 0000000..f7e413a --- /dev/null +++ b/dumps/scripts/2352.cs2 @@ -0,0 +1,10 @@ +void script_2352() { + if ((getLanguage() == 2) || (getLanguage() == 3)) { + setWidgetFont(494, new WidgetPointer(433,16)); + setWidgetFont(494, new WidgetPointer(433,17)); + setWidgetFont(494, new WidgetPointer(433,18)); + setWidgetFont(494, new WidgetPointer(433,19)); + setWidgetFont(494, new WidgetPointer(433,20)); + } + return; +} diff --git a/dumps/scripts/2353.cs2 b/dumps/scripts/2353.cs2 new file mode 100644 index 0000000..1f4072a --- /dev/null +++ b/dumps/scripts/2353.cs2 @@ -0,0 +1,11 @@ +void script_2353(int arg0) { + if (((boolean)globalint_771)) { + setScriptCallOnGameloop(2354, new WidgetPointer(arg0), "I", new WidgetPointer(arg0)); + } else { + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + setWidgetText(new WidgetPointer(arg0), "Saving your game and loading QuestHelp"); + setWidgetIsHidden(true, new WidgetPointer(arg0)); + setWidgetIsHidden(false, new WidgetPointer(275,14)); + } + return; +} diff --git a/dumps/scripts/2354.cs2 b/dumps/scripts/2354.cs2 new file mode 100644 index 0000000..205dc37 --- /dev/null +++ b/dumps/scripts/2354.cs2 @@ -0,0 +1,20 @@ +void script_2354(int arg0) { + if (((boolean)globalint_772)) { + setWidgetText(new WidgetPointer(arg0), "Saving your game and loading QuestHelp"); + globalint_772 = add(globalint_772, 1); + } else if (globalint_772 == 20) { + setWidgetText(new WidgetPointer(arg0), "Saving your game and loading QuestHelp."); + globalint_772 = add(globalint_772, 1); + } else if (globalint_772 == 40) { + setWidgetText(new WidgetPointer(arg0), "Saving your game and loading QuestHelp.."); + globalint_772 = add(globalint_772, 1); + } else if (globalint_772 == 60) { + setWidgetText(new WidgetPointer(arg0), "Saving your game and loading QuestHelp."); + globalint_772 = add(globalint_772, 1); + } else if (globalint_772 == 80) { + globalint_772 = 1; + } else { + globalint_772 = add(globalint_772, 1); + } + return; +} diff --git a/dumps/scripts/2355.cs2 b/dumps/scripts/2355.cs2 new file mode 100644 index 0000000..81615da --- /dev/null +++ b/dumps/scripts/2355.cs2 @@ -0,0 +1,11 @@ +void script_2355(int arg0,int arg1) { + globalint_92 = arg0; + if (((boolean)arg0)) { + setScriptCallOnGameloop(2356, arg1, "i", new WidgetPointer(916,21)); + script_2192(0, arg1); + } else { + setScriptCallOnGameloop(2356, 0, "i", new WidgetPointer(916,21)); + script_2192(1, arg1); + } + return; +} diff --git a/dumps/scripts/2356.cs2 b/dumps/scripts/2356.cs2 new file mode 100644 index 0000000..3948628 --- /dev/null +++ b/dumps/scripts/2356.cs2 @@ -0,0 +1,28 @@ +void script_2356(int arg0) { + int ivar1; + int ivar2; + ivar1 = getWidgetActualWidth(new WidgetPointer(905,5)); + ivar2 = 0; + if (ivar1 < arg0) { + ivar2 = add(ivar1, 9); + if (ivar2 >= arg0) { + setWidgetSize(add(arg0, 5), 0, 0, 1, new WidgetPointer(916,2)); + setWidgetSize(arg0, 0, 0, 1, new WidgetPointer(905,5)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(916,21)); + return; + } + setWidgetSize(add(ivar2, 5), 0, 0, 1, new WidgetPointer(916,2)); + setWidgetSize(ivar2, 0, 0, 1, new WidgetPointer(905,5)); + } else { + ivar2 = subtract(ivar1, 9); + if (ivar2 <= arg0) { + setWidgetSize(add(arg0, 5), 0, 0, 1, new WidgetPointer(916,2)); + setWidgetSize(arg0, 0, 0, 1, new WidgetPointer(905,5)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(916,21)); + return; + } + setWidgetSize(add(ivar2, 5), 0, 0, 1, new WidgetPointer(916,2)); + setWidgetSize(ivar2, 0, 0, 1, new WidgetPointer(905,5)); + } + return; +} diff --git a/dumps/scripts/2357.cs2 b/dumps/scripts/2357.cs2 new file mode 100644 index 0000000..68108c7 --- /dev/null +++ b/dumps/scripts/2357.cs2 @@ -0,0 +1,18 @@ +void script_2357(int arg0) { + int ivar1; + int ivar2; + int ivar3; + cs2method202(arg0); + if (standart_config_1893 == -1) { + return; + } + ivar1 = ((int)cs2method_3408(73, 73, 1592, standart_config_1893)); + ivar2 = getWidgetActualX(new WidgetPointer(arg0)); + ivar3 = getWidgetActualY(new WidgetPointer(arg0)); + if (arg0 == 69009490) { + ivar2 = subtract(add(ivar2, divide(getWidgetActualWidth(new WidgetPointer(arg0)), 2)), divide(getWidgetActualWidth(new WidgetPointer(ivar1)), 2)); + ivar3 = subtract(add(ivar3, divide(getWidgetActualHeight(new WidgetPointer(arg0)), 2)), divide(getWidgetActualHeight(new WidgetPointer(ivar1)), 2)); + } + setWidgetPosition(ivar2, ivar3, 0, 0, new WidgetPointer(ivar1)); + return; +} diff --git a/dumps/scripts/2358.cs2 b/dumps/scripts/2358.cs2 new file mode 100644 index 0000000..7a63aaa --- /dev/null +++ b/dumps/scripts/2358.cs2 @@ -0,0 +1,31 @@ +void script_2358(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + ivar1 = cs2method_3408(73, 105, 2125, arg0); + ivar2 = cs2method_3408(73, 105, 2124, arg0); + ivar3 = 1; + if (standart_config_1893 == -1) { + if (((boolean)ivar2)) { + ivar3 = ((int)isBitFlagged(standart_config_1890, ivar1)); + } else if (ivar2 == 2) { + ivar3 = ((int)isBitFlagged(standart_config_1891, ivar1)); + } else { + ivar3 = ((int)isBitFlagged(standart_config_1892, ivar1)); + } + if (((boolean)ivar3)) { + cs2method203(arg0); + } + return; + } + ivar4 = cs2method_3408(73, 74, 704, standart_config_1893); + ivar5 = getOtherCommonData(ivar4, 1222); + ivar6 = getOtherCommonData(ivar4, 1223); + ivar7 = ((int)cs2method_3408(73, 73, 1592, standart_config_1893)); + setWidgetPosition(ivar5, ivar6, 0, 0, new WidgetPointer(ivar7)); + return; +} diff --git a/dumps/scripts/2359.cs2 b/dumps/scripts/2359.cs2 new file mode 100644 index 0000000..769c86e --- /dev/null +++ b/dumps/scripts/2359.cs2 @@ -0,0 +1,4 @@ +void script_2359() { + setWidgetIsHidden(true, new WidgetPointer(1053,96)); + return; +} diff --git a/dumps/scripts/236.cs2 b/dumps/scripts/236.cs2 new file mode 100644 index 0000000..389b101 --- /dev/null +++ b/dumps/scripts/236.cs2 @@ -0,0 +1,4 @@ +void script_236() { + cs2method5400(0, "bugtracker_v4", "index.html"); + return; +} diff --git a/dumps/scripts/2360.cs2 b/dumps/scripts/2360.cs2 new file mode 100644 index 0000000..fc47329 --- /dev/null +++ b/dumps/scripts/2360.cs2 @@ -0,0 +1,4 @@ +void script_2360() { + setWidgetIsHidden(true, new WidgetPointer(1054,54)); + return; +} diff --git a/dumps/scripts/2361.cs2 b/dumps/scripts/2361.cs2 new file mode 100644 index 0000000..bbe4778 --- /dev/null +++ b/dumps/scripts/2361.cs2 @@ -0,0 +1,9 @@ +void script_2361(int arg0) { + int ivar1; + if (((boolean)bitconfig_8271)) { + return; + } + ivar1 = ((int)cs2method_3408(105, 73, 2352, bitconfig_8271)); + setWidgetIntegerNode(1224, arg0, new WidgetPointer(ivar1)); + return; +} diff --git a/dumps/scripts/2362.cs2 b/dumps/scripts/2362.cs2 new file mode 100644 index 0000000..8ab8e8a --- /dev/null +++ b/dumps/scripts/2362.cs2 @@ -0,0 +1,5 @@ +void script_2362() { + int ivar0; + ivar0 = 0; + return; +} diff --git a/dumps/scripts/2363.cs2 b/dumps/scripts/2363.cs2 new file mode 100644 index 0000000..eed21d9 --- /dev/null +++ b/dumps/scripts/2363.cs2 @@ -0,0 +1,6 @@ +void script_2363(int arg0,int arg1) { + setWidgetScrollMax(200, globalint_773, new WidgetPointer(arg1)); + cs2method2100(0, 0, new WidgetPointer(arg1)); + script_31(arg0, arg1, 792, 789, 790, 791, 773, 788); + return; +} diff --git a/dumps/scripts/2364.cs2 b/dumps/scripts/2364.cs2 new file mode 100644 index 0000000..cf43609 --- /dev/null +++ b/dumps/scripts/2364.cs2 @@ -0,0 +1,29 @@ +void script_2364(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int stack_dump0; + ivar1 = 1; + ivar2 = 0; + ivar3 = -1; + ivar4 = -1; + while (ivar1 < 9) { + ivar3 = ((int)cs2method_3408(105, 73, 2352, ivar1)); + if (setWidgetRegister(new WidgetPointer(ivar3))) { + stack_dump0 = 1224; + /* + mgi.tools.jagdecs2.DecompilerException: opcode 1613 not decompileable + at mgi.tools.jagdecs2.FlowBlocksGenerator.analyzeSpecialCall(FlowBlocksGenerator.java:297) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:249) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + ivar1 = add(ivar1, 1); + } + return; +} diff --git a/dumps/scripts/2365.cs2 b/dumps/scripts/2365.cs2 new file mode 100644 index 0000000..66781d3 --- /dev/null +++ b/dumps/scripts/2365.cs2 @@ -0,0 +1,4 @@ +void script_2365(int arg0) { + setWidgetIntegerNode(1224, 0, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/2366.cs2 b/dumps/scripts/2366.cs2 new file mode 100644 index 0000000..c23ee65 --- /dev/null +++ b/dumps/scripts/2366.cs2 @@ -0,0 +1,14 @@ +void script_2366(int arg0,int arg1,int arg2) { + int ivar3; + ivar3 = 0; + while (ivar3 < arg2) { + if (setWidgetRegister(new WidgetPointer(arg0), ivar3)) { + setWidgetSprite(180); + } + ivar3 = add(ivar3, 1); + } + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetSprite(181); + } + return; +} diff --git a/dumps/scripts/2367.cs2 b/dumps/scripts/2367.cs2 new file mode 100644 index 0000000..28a52e1 --- /dev/null +++ b/dumps/scripts/2367.cs2 @@ -0,0 +1,11 @@ +void script_2367() { + setWidgetIntegerNode(1224, 0, new WidgetPointer(1054,30)); + setWidgetIntegerNode(1224, 0, new WidgetPointer(1054,31)); + setWidgetIntegerNode(1224, 0, new WidgetPointer(1054,32)); + setWidgetIntegerNode(1224, 0, new WidgetPointer(1054,33)); + setWidgetIntegerNode(1224, 0, new WidgetPointer(1054,34)); + setWidgetIntegerNode(1224, 0, new WidgetPointer(1054,35)); + setWidgetIntegerNode(1224, 0, new WidgetPointer(1054,36)); + setWidgetIntegerNode(1224, 0, new WidgetPointer(1054,37)); + return; +} diff --git a/dumps/scripts/2368.cs2 b/dumps/scripts/2368.cs2 new file mode 100644 index 0000000..6c4468a --- /dev/null +++ b/dumps/scripts/2368.cs2 @@ -0,0 +1,5 @@ +void script_2368() { + globalint_1088 = 0; + script_1174(7); + return; +} diff --git a/dumps/scripts/2369.cs2 b/dumps/scripts/2369.cs2 new file mode 100644 index 0000000..9696eb3 --- /dev/null +++ b/dumps/scripts/2369.cs2 @@ -0,0 +1,10 @@ +void script_2369(int arg0,int arg1,int arg2) { + int ivar3; + ivar3 = cs2method2600(new WidgetPointer(905,13)); + cs2method2100(add(cs2method2600(new WidgetPointer(905,13)), arg2), 0, new WidgetPointer(905,13)); + if (ivar3 != cs2method2600(new WidgetPointer(905,13))) { + setWidgetSprite(arg1, new WidgetPointer(arg0)); + } + script_2370(); + return; +} diff --git a/dumps/scripts/237.cs2 b/dumps/scripts/237.cs2 new file mode 100644 index 0000000..d04c7b5 --- /dev/null +++ b/dumps/scripts/237.cs2 @@ -0,0 +1,6 @@ +void script_237(int arg0) { + if (setWidgetRegister(new WidgetPointer(594,93), arg0)) { + cs2method2103(192); + } + return; +} diff --git a/dumps/scripts/2370.cs2 b/dumps/scripts/2370.cs2 new file mode 100644 index 0000000..f13e0a8 --- /dev/null +++ b/dumps/scripts/2370.cs2 @@ -0,0 +1,18 @@ +void script_2370() { + int ivar0; + ivar0 = cs2method2600(new WidgetPointer(905,13)); + if (ivar0 <= 0) { + cs2method2103(150, new WidgetPointer(905,11)); + setWidgetSprite(3877, new WidgetPointer(905,11)); + } else { + cs2method2103(0, new WidgetPointer(905,11)); + } + if (ivar0 >= subtract(getWidgetScrollMaxH(new WidgetPointer(905,13)), getWidgetActualWidth(new WidgetPointer(905,13)))) { + cs2method2103(150, new WidgetPointer(905,12)); + setWidgetSprite(3879, new WidgetPointer(905,12)); + } else { + cs2method2103(0, new WidgetPointer(905,12)); + } + globalint_93 = ivar0; + return; +} diff --git a/dumps/scripts/2371.cs2 b/dumps/scripts/2371.cs2 new file mode 100644 index 0000000..d8e8db0 --- /dev/null +++ b/dumps/scripts/2371.cs2 @@ -0,0 +1,8 @@ +void script_2371() { + if (((boolean)bitconfig_4894)) { + setWidgetIsHidden(false, new WidgetPointer(667,49)); + } else { + setWidgetIsHidden(true, new WidgetPointer(667,49)); + } + return; +} diff --git a/dumps/scripts/2372.cs2 b/dumps/scripts/2372.cs2 new file mode 100644 index 0000000..a9762ae --- /dev/null +++ b/dumps/scripts/2372.cs2 @@ -0,0 +1,4 @@ +void script_2372(int arg0,int arg1) { + script_2373(arg0, arg1); + return; +} diff --git a/dumps/scripts/2373.cs2 b/dumps/scripts/2373.cs2 new file mode 100644 index 0000000..233cc72 --- /dev/null +++ b/dumps/scripts/2373.cs2 @@ -0,0 +1,101 @@ +void script_2373(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + string svar0; + int stack_dump0; + int stack_dump1; + int stack_dump2; + cs2func_script_788_struct(2,0,0) structdump_3; + cs2func_script_788_struct(2,0,0) structdump_4; + deleteAllExtraChilds(new WidgetPointer(667,7)); + ivar2 = 0; + ivar3 = -1; + ivar4 = -1; + svar0 = ""; + while (ivar2 < getItemContainerLength(94)) { + switch (ivar2) { + case 0: + ivar3 = 43712525; + break; + case 1: + ivar3 = 43712527; + break; + case 2: + ivar3 = 43712528; + break; + case 3: + ivar3 = 43712530; + break; + case 4: + ivar3 = 43712531; + break; + case 5: + ivar3 = 43712532; + break; + case 7: + ivar3 = 43712533; + break; + case 9: + ivar3 = 43712535; + break; + case 10: + ivar3 = 43712534; + break; + case 12: + ivar3 = 43712536; + break; + case 13: + ivar3 = 43712529; + break; + case 14: + ivar3 = 43712526; + break; + default: + ivar3 = -1; + } + createExtraChild(new WidgetPointer(667,7), 5, ivar2); + if (ivar3 != -1) { + ivar4 = getItemIdInSlot(94, ivar2); + if (ivar4 != -1) { + setWidgetSize(36, 32, 0, 0); + stack_dump0 = ivar3; + stack_dump1 = 2; + stack_dump2 = 2; + structdump_3 = script_788(stack_dump0, stack_dump1, stack_dump2); + setWidgetPosition(structdump_3.intpart_0, structdump_3.intpart_1, 0, 0); + setItemOnWidgetMethod1200(ivar4, getItemAmtInSlot(94, ivar2)); + cs2method1305(concat("", getItemName(ivar4))); + setWidgetContextMenuOption(1, "Remove"); + setWidgetContextMenuOption(9, "Stats"); + cs2method1306("Compare"); + setWidgetContextMenuOption(10, "Examine"); + setWidgetShadowColor(new Color(48, 32, 32)); + if (arg1 == ivar2) { + setWidgetBorderThickness(2); + } else { + setWidgetBorderThickness(1); + } + setScriptCallOnClickContextMenu(1620, new WidgetPointer(-32768,3), -2147483643, 100, 0, 8, "Iiiii"); + setScriptCallOnUse(2372, new WidgetPointer(arg0), ivar2, "Ii"); + setScriptCallOnUseWith(2372, new WidgetPointer(arg0), -1, "Ii"); + } else { + setWidgetSize(32, 32, 0, 0); + stack_dump0 = ivar3; + stack_dump1 = 2; + stack_dump2 = 2; + structdump_4 = script_788(stack_dump0, stack_dump1, stack_dump2); + setWidgetPosition(structdump_4.intpart_0, structdump_4.intpart_1, 0, 0); + setWidgetSprite(cs2method_3408(105, 100, 796, ivar2)); + } + } else { + setWidgetHidden(1); + } + ivar2 = add(ivar2, 1); + } + if ((arg1 != -1) && (getItemIdInSlot(94, arg1) == -1)) { + arg1 = -1; + } + setScriptCallOnItemContainerUpdate(2372, new WidgetPointer(-32768,3), arg1, 94, 1, "IiY", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/2374.cs2 b/dumps/scripts/2374.cs2 new file mode 100644 index 0000000..eaff1b5 --- /dev/null +++ b/dumps/scripts/2374.cs2 @@ -0,0 +1,5 @@ +void script_2374(int arg0,int arg1) { + setWidgetNpcHead(arg1, new WidgetPointer(arg0)); + setWidgetAnimation(9806, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/2375.cs2 b/dumps/scripts/2375.cs2 new file mode 100644 index 0000000..f0a2829 --- /dev/null +++ b/dumps/scripts/2375.cs2 @@ -0,0 +1,4 @@ +void script_2375(int arg0,int arg1) { + script_2377(bitconfig_6098, arg0, arg1); + return; +} diff --git a/dumps/scripts/2376.cs2 b/dumps/scripts/2376.cs2 new file mode 100644 index 0000000..dd09730 --- /dev/null +++ b/dumps/scripts/2376.cs2 @@ -0,0 +1,7 @@ +void script_2376(int arg0,int arg1,int arg2,int arg3) { + if (arg0 != 1) { + return; + } + script_2377(arg1, arg2, arg3); + return; +} diff --git a/dumps/scripts/2377.cs2 b/dumps/scripts/2377.cs2 new file mode 100644 index 0000000..d648e24 --- /dev/null +++ b/dumps/scripts/2377.cs2 @@ -0,0 +1,14 @@ +void script_2377(int arg0,int arg1,int arg2) { + if (((boolean)arg0)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(arg1)); + setWidgetUnknownBoolean(true, new WidgetPointer(arg1)); + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(arg2)); + setWidgetUnknownBoolean(false, new WidgetPointer(arg2)); + } else { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(arg2)); + setWidgetUnknownBoolean(true, new WidgetPointer(arg2)); + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(arg1)); + setWidgetUnknownBoolean(false, new WidgetPointer(arg1)); + } + return; +} diff --git a/dumps/scripts/2378.cs2 b/dumps/scripts/2378.cs2 new file mode 100644 index 0000000..c5fec0c --- /dev/null +++ b/dumps/scripts/2378.cs2 @@ -0,0 +1,43 @@ +void script_2378(int arg0) { + int ivar1; + ivar1 = -1; + switch (bitconfig_6099) { + case 0: + ivar1 = 58982423; + break; + case 1: + ivar1 = 58982424; + break; + case 2: + ivar1 = 58982425; + break; + case 3: + ivar1 = 58982426; + break; + case 4: + ivar1 = 58982427; + break; + case 5: + ivar1 = 58982428; + break; + case 6: + ivar1 = 58982429; + break; + case 7: + ivar1 = 58982422; + break; + case 8: + ivar1 = 58982421; + break; + case 9: + ivar1 = 58982420; + break; + case 10: + ivar1 = 58982430; + break; + case 11: + ivar1 = 58982431; + } + script_2380(ivar1, arg0); + return; +} diff --git a/dumps/scripts/2379.cs2 b/dumps/scripts/2379.cs2 new file mode 100644 index 0000000..9bb8ad6 --- /dev/null +++ b/dumps/scripts/2379.cs2 @@ -0,0 +1,8 @@ +void script_2379(int arg0,int arg1,int arg2,int arg3) { + if (arg0 != 1) { + return; + } + bitconfig_6099 = arg3; + script_2380(arg1, arg2); + return; +} diff --git a/dumps/scripts/238.cs2 b/dumps/scripts/238.cs2 new file mode 100644 index 0000000..1c864f0 --- /dev/null +++ b/dumps/scripts/238.cs2 @@ -0,0 +1,6 @@ +void script_238(int arg0) { + if (setWidgetRegister(new WidgetPointer(594,93), arg0)) { + cs2method2103(255); + } + return; +} diff --git a/dumps/scripts/2380.cs2 b/dumps/scripts/2380.cs2 new file mode 100644 index 0000000..12945a7 --- /dev/null +++ b/dumps/scripts/2380.cs2 @@ -0,0 +1,9 @@ +void script_2380(int arg0,int arg1) { + if (arg0 == -1) { + setWidgetIsHidden(true, new WidgetPointer(arg1)); + return; + } + setWidgetIsHidden(false, new WidgetPointer(arg1)); + setWidgetPosition(subtract(add(getWidgetActualX(new WidgetPointer(arg0)), getWidgetActualWidth(new WidgetPointer(arg0))), getWidgetActualWidth(new WidgetPointer(arg1))), subtract(add(getWidgetActualY(new WidgetPointer(arg0)), getWidgetActualHeight(new WidgetPointer(arg0))), getWidgetActualHeight(new WidgetPointer(arg1))), 0, 0, new WidgetPointer(arg1)); + return; +} diff --git a/dumps/scripts/2381.cs2 b/dumps/scripts/2381.cs2 new file mode 100644 index 0000000..bd4a1e6 --- /dev/null +++ b/dumps/scripts/2381.cs2 @@ -0,0 +1,5 @@ +void script_2381(int arg0,int arg1,string arg2) { + setWidgetText(new WidgetPointer(arg0), arg2); + setWidgetRGB(new Color(arg1), new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/2382.cs2 b/dumps/scripts/2382.cs2 new file mode 100644 index 0000000..e923462 --- /dev/null +++ b/dumps/scripts/2382.cs2 @@ -0,0 +1,6 @@ +void script_2382(int arg0,int arg1,int arg2) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetBorderThickness(arg2); + } + return; +} diff --git a/dumps/scripts/2383.cs2 b/dumps/scripts/2383.cs2 new file mode 100644 index 0000000..1c22871 --- /dev/null +++ b/dumps/scripts/2383.cs2 @@ -0,0 +1,4 @@ +void script_2383(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 16 Agility"); + return; +} diff --git a/dumps/scripts/2384.cs2 b/dumps/scripts/2384.cs2 new file mode 100644 index 0000000..607abcf --- /dev/null +++ b/dumps/scripts/2384.cs2 @@ -0,0 +1,4 @@ +void script_2384(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 48 Agility"); + return; +} diff --git a/dumps/scripts/2385.cs2 b/dumps/scripts/2385.cs2 new file mode 100644 index 0000000..f427e32 --- /dev/null +++ b/dumps/scripts/2385.cs2 @@ -0,0 +1,4 @@ +void script_2385(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 35 Ranged, level 35 Strength, level 32 Agility" + "
" + "Requires a grapple"); + return; +} diff --git a/dumps/scripts/2386.cs2 b/dumps/scripts/2386.cs2 new file mode 100644 index 0000000..a45802b --- /dev/null +++ b/dumps/scripts/2386.cs2 @@ -0,0 +1,4 @@ +void script_2386(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 70 Ranged" + "
" + "Requires a grapple"); + return; +} diff --git a/dumps/scripts/2387.cs2 b/dumps/scripts/2387.cs2 new file mode 100644 index 0000000..c97a207 --- /dev/null +++ b/dumps/scripts/2387.cs2 @@ -0,0 +1,4 @@ +void script_2387(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 37 Strength, level 19 Ranged, level 11 Agility" + "
" + "Requires a grapple"); + return; +} diff --git a/dumps/scripts/2388.cs2 b/dumps/scripts/2388.cs2 new file mode 100644 index 0000000..91285f8 --- /dev/null +++ b/dumps/scripts/2388.cs2 @@ -0,0 +1,4 @@ +void script_2388(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 28 Agility"); + return; +} diff --git a/dumps/scripts/2389.cs2 b/dumps/scripts/2389.cs2 new file mode 100644 index 0000000..b71ebc3 --- /dev/null +++ b/dumps/scripts/2389.cs2 @@ -0,0 +1,4 @@ +void script_2389(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 13 Agility"); + return; +} diff --git a/dumps/scripts/239.cs2 b/dumps/scripts/239.cs2 new file mode 100644 index 0000000..0486542 --- /dev/null +++ b/dumps/scripts/239.cs2 @@ -0,0 +1,4 @@ +void script_239(int arg0) { + globalint_791 = arg0; + return; +} diff --git a/dumps/scripts/2390.cs2 b/dumps/scripts/2390.cs2 new file mode 100644 index 0000000..2ccd6ed --- /dev/null +++ b/dumps/scripts/2390.cs2 @@ -0,0 +1,4 @@ +void script_2390(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 40 Agility" + "
" + "Requires a rope on first passage"); + return; +} diff --git a/dumps/scripts/2391.cs2 b/dumps/scripts/2391.cs2 new file mode 100644 index 0000000..3483997 --- /dev/null +++ b/dumps/scripts/2391.cs2 @@ -0,0 +1,4 @@ +void script_2391(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 61 Agility" + "
" + "Wear a nosepeg or equivalent item"); + return; +} diff --git a/dumps/scripts/2392.cs2 b/dumps/scripts/2392.cs2 new file mode 100644 index 0000000..eabacef --- /dev/null +++ b/dumps/scripts/2392.cs2 @@ -0,0 +1,4 @@ +void script_2392(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 25 Agility" + "
" + "Requires some progress in the In Aid of the Myreque quest"); + return; +} diff --git a/dumps/scripts/2393.cs2 b/dumps/scripts/2393.cs2 new file mode 100644 index 0000000..f23f591 --- /dev/null +++ b/dumps/scripts/2393.cs2 @@ -0,0 +1,4 @@ +void script_2393(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 39 Agility, level 38 Strength, level 21 Ranged" + "
" + "Requires a grapple"); + return; +} diff --git a/dumps/scripts/2394.cs2 b/dumps/scripts/2394.cs2 new file mode 100644 index 0000000..df85df6 --- /dev/null +++ b/dumps/scripts/2394.cs2 @@ -0,0 +1,4 @@ +void script_2394(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 74 Agility"); + return; +} diff --git a/dumps/scripts/2395.cs2 b/dumps/scripts/2395.cs2 new file mode 100644 index 0000000..77a5757 --- /dev/null +++ b/dumps/scripts/2395.cs2 @@ -0,0 +1,4 @@ +void script_2395(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 81 Agility"); + return; +} diff --git a/dumps/scripts/2396.cs2 b/dumps/scripts/2396.cs2 new file mode 100644 index 0000000..2be991c --- /dev/null +++ b/dumps/scripts/2396.cs2 @@ -0,0 +1,4 @@ +void script_2396(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 85 Agility"); + return; +} diff --git a/dumps/scripts/2397.cs2 b/dumps/scripts/2397.cs2 new file mode 100644 index 0000000..37b6571 --- /dev/null +++ b/dumps/scripts/2397.cs2 @@ -0,0 +1,4 @@ +void script_2397(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 68 Agility"); + return; +} diff --git a/dumps/scripts/2398.cs2 b/dumps/scripts/2398.cs2 new file mode 100644 index 0000000..cdb56ae --- /dev/null +++ b/dumps/scripts/2398.cs2 @@ -0,0 +1,4 @@ +void script_2398(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 59 Agility"); + return; +} diff --git a/dumps/scripts/2399.cs2 b/dumps/scripts/2399.cs2 new file mode 100644 index 0000000..621a3a6 --- /dev/null +++ b/dumps/scripts/2399.cs2 @@ -0,0 +1,4 @@ +void script_2399(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 25 Agility"); + return; +} diff --git a/dumps/scripts/24.cs2 b/dumps/scripts/24.cs2 new file mode 100644 index 0000000..1262344 --- /dev/null +++ b/dumps/scripts/24.cs2 @@ -0,0 +1,75 @@ +int script_24(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5) { + int ivar5; + createExtraChild(new WidgetPointer(499,7), 4, multiply(arg3, 3)); + setWidgetSize(26, 32, 0, 0); + if (arg0 > 0) { + setWidgetText(intToStr(arg0)); + } else { + setWidgetText(" "); + } + setWidgetPosition(0, arg4, 0, 0); + setWidgetTextAlignment(2, 0, 0); + setWidgetRGB(new Color(70, 50, 10)); + setWidgetFont(497); + setWidgetUnknownBoolean(false); + createExtraChild(new WidgetPointer(499,7), 5, add(multiply(arg3, 3), 1)); + setWidgetSize(36, 32, 0, 0); + if (((boolean)script_1566(bitconfig_3288, bitconfig_3289))) { + if (bitconfig_3288 == 7) { + setWidgetSize(30, 30, 0, 0); + } else { + if (bitconfig_3288 == 4) { + setWidgetSize(24, 24, 0, 0); + setWidgetPosition(0, arg4, 1, 0); + } + } + setWidgetBorderThickness(0); + if (arg2 != -1) { + setWidgetSprite(arg2); + } else { + setWidgetSprite(2287); + } + } else if (arg1 != -1) { + if ((arg1 == 18637) || (arg1 == 18638)) { + setWidgetSize(24, 24, 0, 0); + setWidgetPosition(0, arg4, 1, 0); + setWidgetBorderThickness(0); + if (arg1 == 18637) { + setWidgetSprite(3057); + } else { + setWidgetSprite(3056); + } + } else if ((bitconfig_3288 == 21) && (bitconfig_3289 != 10)) { + setWidgetContextMenuOption(1, "Check protection price"); + setScriptCallOnClickContextMenu(1865, -2147483644, arg1, "io"); + setScriptCallOnMouseEntered(1862, new WidgetPointer(-32768,3), -2147483643, "Ii"); + setScriptCallOnMouseExit(1863, new WidgetPointer(-32768,3), -2147483643, "Ii"); + } else { + if (((bitconfig_3288 == 22) && (bitconfig_3289 != 13)) && ((bitconfig_3289 != 14) && (bitconfig_3289 != 15))) { + setWidgetContextMenuOption(1, "Check materials"); + setScriptCallOnClickContextMenu(1864, -2147483644, arg1, bitconfig_3289, arg3, "ioii"); + setScriptCallOnMouseEntered(1862, new WidgetPointer(-32768,3), -2147483643, "Ii"); + setScriptCallOnMouseExit(1863, new WidgetPointer(-32768,3), -2147483643, "Ii"); + } + } + setWidgetBorderThickness(1); + setWidgetShadowColor(new Color(96, 78, 50)); + setItemOnWidgetMethod1200(arg1, -1); + } else { + setItemOnWidgetMethod1200(7620, -1); + } + setWidgetPosition(28, arg4, 0, 0); + createExtraChild(new WidgetPointer(499,7), 4, add(multiply(arg3, 3), 2)); + ivar5 = getLineCount(228, 495, arg5); + setWidgetSize(228, multiply(ivar5, 15), 0, 0); + setWidgetText(arg5); + setWidgetPosition(66, arg4, 0, 0); + setWidgetTextAlignment(0, 0, 0); + setWidgetRGB(new Color(70, 50, 10)); + setWidgetFont(495); + setWidgetUnknownBoolean(false); + if (multiply(ivar5, 15) < 32) { + return 32; + } + return add(multiply(ivar5, 15), 5); +} diff --git a/dumps/scripts/240.cs2 b/dumps/scripts/240.cs2 new file mode 100644 index 0000000..8273fd2 --- /dev/null +++ b/dumps/scripts/240.cs2 @@ -0,0 +1,14 @@ +void script_240() { + int ivar0; + ivar0 = 0; + while (ivar0 < getExtraChildGap(new WidgetPointer(594,92))) { + if (setWidgetRegister(new WidgetPointer(594,92), ivar0)) { + cs2method2103(255); + } + ivar0 = add(ivar0, 1); + } + if (setWidgetRegister(new WidgetPointer(594,92), globalint_792)) { + cs2method2103(110); + } + return; +} diff --git a/dumps/scripts/2400.cs2 b/dumps/scripts/2400.cs2 new file mode 100644 index 0000000..4d6f712 --- /dev/null +++ b/dumps/scripts/2400.cs2 @@ -0,0 +1,4 @@ +void script_2400(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 37 Agility" + "
" + "Requires the Grand Tree quest"); + return; +} diff --git a/dumps/scripts/2401.cs2 b/dumps/scripts/2401.cs2 new file mode 100644 index 0000000..8abd728 --- /dev/null +++ b/dumps/scripts/2401.cs2 @@ -0,0 +1,4 @@ +void script_2401(int arg0,int arg1) { + script_2010(arg0, arg1, "Requires a rope for the first crossing"); + return; +} diff --git a/dumps/scripts/2402.cs2 b/dumps/scripts/2402.cs2 new file mode 100644 index 0000000..3128e67 --- /dev/null +++ b/dumps/scripts/2402.cs2 @@ -0,0 +1,4 @@ +void script_2402(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 20 Agility"); + return; +} diff --git a/dumps/scripts/2403.cs2 b/dumps/scripts/2403.cs2 new file mode 100644 index 0000000..8c8b928 --- /dev/null +++ b/dumps/scripts/2403.cs2 @@ -0,0 +1,4 @@ +void script_2403(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 62 Agility"); + return; +} diff --git a/dumps/scripts/2404.cs2 b/dumps/scripts/2404.cs2 new file mode 100644 index 0000000..1afd3f6 --- /dev/null +++ b/dumps/scripts/2404.cs2 @@ -0,0 +1,4 @@ +void script_2404(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 5 Agility"); + return; +} diff --git a/dumps/scripts/2405.cs2 b/dumps/scripts/2405.cs2 new file mode 100644 index 0000000..a1b3da7 --- /dev/null +++ b/dumps/scripts/2405.cs2 @@ -0,0 +1,4 @@ +void script_2405(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 70 Agility" + "
" + "Requires a rope on first passage"); + return; +} diff --git a/dumps/scripts/2406.cs2 b/dumps/scripts/2406.cs2 new file mode 100644 index 0000000..983fd9a --- /dev/null +++ b/dumps/scripts/2406.cs2 @@ -0,0 +1,4 @@ +void script_2406(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 60 Agility" + "
" + "Only permits west-to-east travel"); + return; +} diff --git a/dumps/scripts/2407.cs2 b/dumps/scripts/2407.cs2 new file mode 100644 index 0000000..801a7ff --- /dev/null +++ b/dumps/scripts/2407.cs2 @@ -0,0 +1,4 @@ +void script_2407(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 42 Agility"); + return; +} diff --git a/dumps/scripts/2408.cs2 b/dumps/scripts/2408.cs2 new file mode 100644 index 0000000..d237849 --- /dev/null +++ b/dumps/scripts/2408.cs2 @@ -0,0 +1,4 @@ +void script_2408(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 31 Agility"); + return; +} diff --git a/dumps/scripts/2409.cs2 b/dumps/scripts/2409.cs2 new file mode 100644 index 0000000..c3c2fe2 --- /dev/null +++ b/dumps/scripts/2409.cs2 @@ -0,0 +1,4 @@ +void script_2409(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 37 Ranged, level 19 Strength, level 8 Agility" + "
" + "Requires a grapple"); + return; +} diff --git a/dumps/scripts/241.cs2 b/dumps/scripts/241.cs2 new file mode 100644 index 0000000..5e92028 --- /dev/null +++ b/dumps/scripts/241.cs2 @@ -0,0 +1,4 @@ +void script_241(int arg0) { + script_243(arg0, 1); + return; +} diff --git a/dumps/scripts/2410.cs2 b/dumps/scripts/2410.cs2 new file mode 100644 index 0000000..2cda8ca --- /dev/null +++ b/dumps/scripts/2410.cs2 @@ -0,0 +1,48 @@ +void script_2410(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5,string arg6,string arg7,string arg8,string arg9,string arg10) { + if (strLength(arg5) > 0) { + setWidgetContextMenuOption(1, arg5); + if (arg0 != -1) { + cs2method1309(1, arg0); + } else { + cs2method1309(1, 36); + } + } + if (strLength(arg6) > 0) { + setWidgetContextMenuOption(2, arg6); + if (arg1 != -1) { + cs2method1309(2, arg1); + } else { + cs2method1309(2, 36); + } + } + if (strLength(arg7) > 0) { + setWidgetContextMenuOption(3, arg7); + if (arg2 != -1) { + cs2method1309(3, arg2); + } else { + cs2method1309(3, 36); + } + } + cs2method1306("Use"); + cs2method1311(46); + cs2method1308(46, 36); + setWidgetContextMenuOption(10, "Examine"); + if (strLength(arg8) > 0) { + setWidgetContextMenuOption(7, arg8); + if (arg3 != -1) { + cs2method1309(7, arg3); + } else { + cs2method1309(7, 36); + } + } + if (strLength(arg9) > 0) { + setWidgetContextMenuOption(8, arg9); + if (arg4 != -1) { + cs2method1309(8, arg4); + } else { + cs2method1309(8, 36); + } + } + cs2method1305("" + arg10); + return; +} diff --git a/dumps/scripts/2411.cs2 b/dumps/scripts/2411.cs2 new file mode 100644 index 0000000..e1553f7 --- /dev/null +++ b/dumps/scripts/2411.cs2 @@ -0,0 +1,9 @@ +void script_2411(int arg0) { + if (((boolean)bitconfig_995)) { + script_2410(getItemDefOpcode129Or130Method4209(arg0, 1), getItemDefOpcode129Or130Method4209(arg0, 2), -1, getItemDefOpcode129Or130Method4209(arg0, 4), getItemDefOpcode129Or130Method4209(arg0, 5), getItemOption(arg0, 1), getItemOption(arg0, 2), "", getItemOption(arg0, 4), getItemOption(arg0, 5), getItemName(arg0)); + } else { + script_2410(getItemDefOpcode129Or130Method4209(arg0, 1), getItemDefOpcode129Or130Method4209(arg0, 2), getItemDefOpcode129Or130Method4209(arg0, 1), getItemDefOpcode129Or130Method4209(arg0, 4), getItemDefOpcode129Or130Method4209(arg0, 5), "Lletya", getItemOption(arg0, 2), "Temple", getItemOption(arg0, 4), getItemOption(arg0, 5), getItemName(arg0)); + } + setScriptCallOnConfigChange(2412, new WidgetPointer(-32768,3), -2147483643, arg0, 1560, 1, "IioY"); + return; +} diff --git a/dumps/scripts/2412.cs2 b/dumps/scripts/2412.cs2 new file mode 100644 index 0000000..7b33529 --- /dev/null +++ b/dumps/scripts/2412.cs2 @@ -0,0 +1,7 @@ +void script_2412(int arg0,int arg1,int arg2) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetNoOptions(); + script_2411(arg2); + } + return; +} diff --git a/dumps/scripts/2413.cs2 b/dumps/scripts/2413.cs2 new file mode 100644 index 0000000..b38f993 --- /dev/null +++ b/dumps/scripts/2413.cs2 @@ -0,0 +1,3 @@ +cs2func_script_2413_struct(3,0,0) script_2413(int arg0) { + return newstruct cs2func_script_2413_struct(divide(arg0, 65536), divide(bitAnd(arg0, 65280), 256), bitAnd(arg0, 255)); +} diff --git a/dumps/scripts/2414.cs2 b/dumps/scripts/2414.cs2 new file mode 100644 index 0000000..13e314d --- /dev/null +++ b/dumps/scripts/2414.cs2 @@ -0,0 +1,45 @@ +void script_2414() { + if (bitconfig_6180 == 120) { + setWidgetIsHidden(false, new WidgetPointer(765,4)); + setWidgetIsHidden(true, new WidgetPointer(765,3)); + if (((boolean)getItemAmtInContainer(93, 14831))) { + setWidgetIsHidden(true, new WidgetPointer(765,33)); + } + if (((boolean)getItemAmtInContainer(93, 14824)) && ((boolean)getItemAmtInContainer(94, 14824))) { + setWidgetIsHidden(true, new WidgetPointer(765,39)); + } + if (((boolean)getItemAmtInContainer(93, 14830))) { + setWidgetIsHidden(true, new WidgetPointer(765,37)); + } + if (((boolean)getItemAmtInContainer(93, 14823)) && ((boolean)getItemAmtInContainer(94, 14823))) { + setWidgetIsHidden(true, new WidgetPointer(765,38)); + } + if (((boolean)getItemAmtInContainer(93, 14829))) { + setWidgetIsHidden(true, new WidgetPointer(765,36)); + } + if (((boolean)getItemAmtInContainer(93, 14828))) { + setWidgetIsHidden(true, new WidgetPointer(765,35)); + } + if (((boolean)getItemAmtInContainer(93, 14827))) { + setWidgetIsHidden(true, new WidgetPointer(765,34)); + } + } else { + setWidgetIsHidden(true, new WidgetPointer(765,4)); + setWidgetIsHidden(false, new WidgetPointer(765,3)); + } + setWidgetAnimation(-1, new WidgetPointer(765,10)); + setWidgetIsHidden(false, new WidgetPointer(765,11)); + setWidgetModel(46967, new WidgetPointer(765,5)); + setWidgetAnimation(11762, new WidgetPointer(765,10)); + setWidgetIsHidden(true, new WidgetPointer(765,19)); + setWidgetIsHidden(false, new WidgetPointer(765,20)); + setWidgetIsHidden(true, new WidgetPointer(765,6)); + setWidgetIsHidden(false, new WidgetPointer(765,18)); + setWidgetAnimation(-1, new WidgetPointer(765,20)); + setWidgetIsHidden(true, new WidgetPointer(765,41)); + setWidgetIsHidden(true, new WidgetPointer(765,40)); + setWidgetIsHidden(true, new WidgetPointer(765,7)); + globalint_805 = 0; + globalint_806 = 0; + return; +} diff --git a/dumps/scripts/2415.cs2 b/dumps/scripts/2415.cs2 new file mode 100644 index 0000000..9872c12 --- /dev/null +++ b/dumps/scripts/2415.cs2 @@ -0,0 +1,42 @@ +void script_2415() { + setWidgetModel(46997, new WidgetPointer(765,14)); + setWidgetModel(46976, new WidgetPointer(765,16)); + setWidgetModel(46974, new WidgetPointer(765,15)); + setWidgetModel(46995, new WidgetPointer(765,17)); + setWidgetModel(46986, new WidgetPointer(765,18)); + setWidgetModel(46987, new WidgetPointer(765,33)); + setWidgetModel(46978, new WidgetPointer(765,34)); + setWidgetModel(46990, new WidgetPointer(765,35)); + setWidgetModel(46991, new WidgetPointer(765,36)); + setWidgetModel(46993, new WidgetPointer(765,37)); + setWidgetModel(46977, new WidgetPointer(765,38)); + setWidgetModel(46975, new WidgetPointer(765,39)); + if (((boolean)globalint_805)) { + setWidgetModel(46982, new WidgetPointer(765,14)); + } else if (globalint_805 == 2) { + setWidgetModel(46979, new WidgetPointer(765,16)); + } else if (globalint_805 == 3) { + setWidgetModel(46989, new WidgetPointer(765,15)); + } else if (globalint_805 == 4) { + setWidgetModel(46981, new WidgetPointer(765,17)); + } else if (globalint_805 == 5) { + setWidgetModel(46996, new WidgetPointer(765,18)); + } else if (globalint_805 == 6) { + setWidgetModel(46983, new WidgetPointer(765,33)); + } else if (globalint_805 == 7) { + setWidgetModel(46980, new WidgetPointer(765,34)); + } else if (globalint_805 == 8) { + setWidgetModel(46984, new WidgetPointer(765,35)); + } else if (globalint_805 == 9) { + setWidgetModel(46992, new WidgetPointer(765,36)); + } else if (globalint_805 == 10) { + setWidgetModel(46994, new WidgetPointer(765,37)); + } else if (globalint_805 == 11) { + setWidgetModel(46985, new WidgetPointer(765,38)); + } else { + if (globalint_805 == 12) { + setWidgetModel(46988, new WidgetPointer(765,39)); + } + } + return; +} diff --git a/dumps/scripts/2416.cs2 b/dumps/scripts/2416.cs2 new file mode 100644 index 0000000..abb3bd8 --- /dev/null +++ b/dumps/scripts/2416.cs2 @@ -0,0 +1,12 @@ +void script_2416(int arg0) { + if ((globalint_805 == 2) || (globalint_805 == 8)) { + setWidgetContextMenuOption(1, new WidgetPointer(arg0), "Cut wire"); + } else if ((globalint_805 == 3) || (globalint_805 == 9)) { + setWidgetContextMenuOption(1, new WidgetPointer(arg0), "Replace wire"); + } else if ((globalint_805 == 4) || (globalint_805 == 10)) { + setWidgetContextMenuOption(1, new WidgetPointer(arg0), "Repair wire"); + } else { + setWidgetContextMenuOption(1, new WidgetPointer(arg0), "Inspect"); + } + return; +} diff --git a/dumps/scripts/2417.cs2 b/dumps/scripts/2417.cs2 new file mode 100644 index 0000000..52d0174 --- /dev/null +++ b/dumps/scripts/2417.cs2 @@ -0,0 +1,8 @@ +void script_2417(int arg0) { + if ((globalint_805 == 5) || (globalint_805 == 11)) { + setWidgetContextMenuOption(1, new WidgetPointer(arg0), "Pump"); + } else { + setWidgetContextMenuOption(1, new WidgetPointer(arg0), "Inspect"); + } + return; +} diff --git a/dumps/scripts/2418.cs2 b/dumps/scripts/2418.cs2 new file mode 100644 index 0000000..64fe55d --- /dev/null +++ b/dumps/scripts/2418.cs2 @@ -0,0 +1,8 @@ +void script_2418(int arg0) { + if (globalint_805 == 6) { + setWidgetContextMenuOption(1, new WidgetPointer(arg0), "Fix"); + } else { + setWidgetContextMenuOption(1, new WidgetPointer(arg0), "Inspect"); + } + return; +} diff --git a/dumps/scripts/2419.cs2 b/dumps/scripts/2419.cs2 new file mode 100644 index 0000000..67549ee --- /dev/null +++ b/dumps/scripts/2419.cs2 @@ -0,0 +1,45 @@ +void script_2419() { + if (globalint_806 > 0) { + setWidgetIsHidden(true, new WidgetPointer(765,11)); + } + if (globalint_806 > 1) { + setWidgetModel(46964, new WidgetPointer(765,5)); + } + if (globalint_806 > 2) { + if (bitconfig_6180 == 75) { + setWidgetModel(46956, new WidgetPointer(765,5)); + setWidgetIsHidden(true, new WidgetPointer(765,15)); + } else { + setWidgetModel(46966, new WidgetPointer(765,5)); + setWidgetIsHidden(true, new WidgetPointer(765,36)); + } + } + if (globalint_806 > 3) { + if (bitconfig_6180 == 75) { + setWidgetModel(46965, new WidgetPointer(765,5)); + setWidgetIsHidden(true, new WidgetPointer(765,17)); + } else { + setWidgetModel(46957, new WidgetPointer(765,5)); + setWidgetIsHidden(true, new WidgetPointer(765,37)); + setWidgetContextMenuOption(1, new WidgetPointer(765,5), "Inspect"); + } + } + if (((boolean)bitconfig_6194)) { + setWidgetAnimation(11762, new WidgetPointer(765,10)); + } else if (((boolean)bitconfig_6194)) { + setWidgetAnimation(11761, new WidgetPointer(765,10)); + } else if (bitconfig_6194 == 2) { + setWidgetAnimation(11760, new WidgetPointer(765,10)); + } else if (bitconfig_6194 == 3) { + setWidgetAnimation(11759, new WidgetPointer(765,10)); + } else if (bitconfig_6194 == 4) { + setWidgetAnimation(11763, new WidgetPointer(765,10)); + } else if (bitconfig_6194 == 5) { + setWidgetAnimation(11764, new WidgetPointer(765,10)); + } else { + if (bitconfig_6194 == 6) { + setWidgetAnimation(11765, new WidgetPointer(765,10)); + } + } + return; +} diff --git a/dumps/scripts/242.cs2 b/dumps/scripts/242.cs2 new file mode 100644 index 0000000..751fe2e --- /dev/null +++ b/dumps/scripts/242.cs2 @@ -0,0 +1,4 @@ +void script_242(int arg0) { + script_243(arg0, 0); + return; +} diff --git a/dumps/scripts/2420.cs2 b/dumps/scripts/2420.cs2 new file mode 100644 index 0000000..44c7d05 --- /dev/null +++ b/dumps/scripts/2420.cs2 @@ -0,0 +1,12 @@ +void script_2420() { + setWidgetIsHidden(true, new WidgetPointer(674,18)); + setWidgetIsHidden(false, new WidgetPointer(674,19)); + setWidgetAnimation(-1, new WidgetPointer(674,19)); + setWidgetAnimation(-1, new WidgetPointer(674,9)); + setWidgetIsHidden(false, new WidgetPointer(674,10)); + setWidgetModel(46967, new WidgetPointer(674,6)); + setWidgetIsHidden(true, new WidgetPointer(674,5)); + setWidgetAnimation(11762, new WidgetPointer(674,9)); + globalint_737 = 0; + return; +} diff --git a/dumps/scripts/2421.cs2 b/dumps/scripts/2421.cs2 new file mode 100644 index 0000000..917878a --- /dev/null +++ b/dumps/scripts/2421.cs2 @@ -0,0 +1,42 @@ +void script_2421() { + setWidgetModel(46997, new WidgetPointer(674,13)); + setWidgetModel(46976, new WidgetPointer(674,15)); + setWidgetModel(46974, new WidgetPointer(674,14)); + setWidgetModel(46995, new WidgetPointer(674,16)); + setWidgetModel(46986, new WidgetPointer(674,17)); + if (((boolean)globalint_737)) { + setWidgetModel(46982, new WidgetPointer(674,13)); + playSoundEffect(6691, 1, 0); + setWidgetIsHidden(true, new WidgetPointer(674,10)); + } else if (globalint_737 == 2) { + setWidgetModel(46979, new WidgetPointer(674,15)); + playSoundEffect(6694, 1, 0); + setWidgetModel(46964, new WidgetPointer(674,6)); + } else if (globalint_737 == 3) { + setWidgetModel(46989, new WidgetPointer(674,14)); + setWidgetModel(46956, new WidgetPointer(674,6)); + } else if (globalint_737 == 4) { + setWidgetModel(46981, new WidgetPointer(674,16)); + playSoundEffect(6695, 1, 0); + setWidgetModel(46965, new WidgetPointer(674,6)); + } else if (globalint_737 == 5) { + setWidgetModel(46996, new WidgetPointer(674,17)); + playSoundEffect(6690, 1, 0); + setWidgetIsHidden(false, new WidgetPointer(674,5)); + } else if (globalint_737 == 6) { + setWidgetAnimation(11761, new WidgetPointer(674,9)); + } else if (globalint_737 == 7) { + setWidgetAnimation(11760, new WidgetPointer(674,9)); + } else if (globalint_737 == 8) { + setWidgetAnimation(11759, new WidgetPointer(674,9)); + } else if (globalint_737 == 9) { + setWidgetAnimation(11763, new WidgetPointer(674,9)); + } else if (globalint_737 == 10) { + setWidgetAnimation(11764, new WidgetPointer(674,9)); + } else { + if (globalint_737 == 11) { + setWidgetAnimation(11765, new WidgetPointer(674,9)); + } + } + return; +} diff --git a/dumps/scripts/2422.cs2 b/dumps/scripts/2422.cs2 new file mode 100644 index 0000000..f484217 --- /dev/null +++ b/dumps/scripts/2422.cs2 @@ -0,0 +1,14 @@ +?? script_2422() { + int stack_dump0; + stack_dump0 = 0; + /* + mgi.tools.jagdecs2.DecompilerException: Unknown special opcode:6509 + at mgi.tools.jagdecs2.FlowBlocksGenerator.analyzeSpecialCall(FlowBlocksGenerator.java:348) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:249) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ +} diff --git a/dumps/scripts/2423.cs2 b/dumps/scripts/2423.cs2 new file mode 100644 index 0000000..9048c3d --- /dev/null +++ b/dumps/scripts/2423.cs2 @@ -0,0 +1,18 @@ +void script_2423(int arg0) { + int ivar1; + ivar1 = -1; + if (((boolean)globalint_811)) { + ivar1 = 1358; + } else if (((boolean)globalint_811)) { + ivar1 = 1359; + } else if (globalint_811 == 2) { + ivar1 = 1360; + } else { + if (globalint_811 == 3) { + ivar1 = 1361; + } + } + setWidgetAnimation(-1, new WidgetPointer(arg0)); + setWidgetAnimation(ivar1, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/2424.cs2 b/dumps/scripts/2424.cs2 new file mode 100644 index 0000000..601c55d --- /dev/null +++ b/dumps/scripts/2424.cs2 @@ -0,0 +1,5 @@ +void script_2424(int arg0,int arg1,int arg2) { + script_1583(arg0, arg2, globalstring_130); + script_1583(arg1, arg2, globalstring_142); + return; +} diff --git a/dumps/scripts/2425.cs2 b/dumps/scripts/2425.cs2 new file mode 100644 index 0000000..aeea23d --- /dev/null +++ b/dumps/scripts/2425.cs2 @@ -0,0 +1,4 @@ +void script_2425(int arg0,int arg1) { + script_1583(arg0, arg1, globalstring_147); + return; +} diff --git a/dumps/scripts/2426.cs2 b/dumps/scripts/2426.cs2 new file mode 100644 index 0000000..54cc12e --- /dev/null +++ b/dumps/scripts/2426.cs2 @@ -0,0 +1,6 @@ +void script_2426(int arg0,int arg1,int arg2,int arg3) { + setWidgetText(new WidgetPointer(arg0), globalstring_143); + setWidgetText(new WidgetPointer(arg1), globalstring_144); + script_1585(arg2, arg3, globalstring_145); + return; +} diff --git a/dumps/scripts/2427.cs2 b/dumps/scripts/2427.cs2 new file mode 100644 index 0000000..a5d9876 --- /dev/null +++ b/dumps/scripts/2427.cs2 @@ -0,0 +1,4 @@ +void script_2427(int arg0) { + setItemOnWidgetMethod2200(cs2method_3408(105, 111, 172, globalint_809), 72, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/2428.cs2 b/dumps/scripts/2428.cs2 new file mode 100644 index 0000000..a0400c7 --- /dev/null +++ b/dumps/scripts/2428.cs2 @@ -0,0 +1,4 @@ +void script_2428(int arg0) { + setItemOnWidgetMethod2200(cs2method_3408(105, 111, 172, globalint_810), 72, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/2429.cs2 b/dumps/scripts/2429.cs2 new file mode 100644 index 0000000..40dfa5f --- /dev/null +++ b/dumps/scripts/2429.cs2 @@ -0,0 +1,4 @@ +void script_2429(int arg0) { + setWidgetText(new WidgetPointer(arg0), globalstring_146); + return; +} diff --git a/dumps/scripts/243.cs2 b/dumps/scripts/243.cs2 new file mode 100644 index 0000000..68932b1 --- /dev/null +++ b/dumps/scripts/243.cs2 @@ -0,0 +1,205 @@ +void script_243(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + flow_0: + ivar2 = -1; + ivar3 = -1; + ivar4 = -1; + ivar5 = 1; + SWITCH (arg0) { + case 38928641: + GOTO flow_1 + case 38928642: + GOTO flow_2 + case 38928643: + GOTO flow_3 + case 38928648: + GOTO flow_4 + case 38928649: + GOTO flow_5 + case 38928650: + GOTO flow_6 + case 38928655: + GOTO flow_7 + case 38928672: + GOTO flow_8 + case 38928673: + GOTO flow_9 + case 38928674: + GOTO flow_10 + case 38928683: + GOTO flow_11 + case 38928684: + GOTO flow_12 + case 38928690: + GOTO flow_13 + case 38928685: + GOTO flow_14 + case 38928386: + GOTO flow_15 + case 38928460: + GOTO flow_16 + case 38928387: + GOTO flow_17 + case 38928438: + GOTO flow_18 + case 38928509: + GOTO flow_19 + case 38928514: + GOTO flow_20 + } + script_675(); + GOTO flow_21 + flow_1: + ivar2 = 38928637; + ivar3 = 38928638; + ivar4 = 38928639; + GOTO flow_21 + flow_2: + ivar2 = 38928668; + ivar3 = 38928669; + ivar4 = 38928670; + GOTO flow_21 + flow_3: + ivar2 = 38928644; + ivar3 = 38928645; + ivar4 = 38928646; + GOTO flow_21 + flow_4: + ivar2 = 38928664; + ivar3 = 38928665; + ivar4 = 38928666; + GOTO flow_21 + flow_5: + ivar2 = 38928660; + ivar3 = 38928661; + ivar4 = 38928662; + GOTO flow_21 + flow_6: + ivar2 = 38928651; + ivar3 = 38928652; + ivar4 = 38928653; + GOTO flow_21 + flow_7: + ivar2 = 38928656; + ivar3 = 38928657; + ivar4 = 38928658; + GOTO flow_21 + flow_8: + ivar2 = 38928621; + ivar3 = 38928622; + ivar4 = 38928623; + GOTO flow_21 + flow_9: + ivar2 = 38928679; + ivar3 = 38928680; + ivar4 = 38928681; + GOTO flow_21 + flow_10: + ivar2 = 38928675; + ivar3 = 38928676; + ivar4 = 38928677; + GOTO flow_21 + flow_11: + ivar2 = 38928625; + ivar3 = 38928626; + ivar4 = 38928627; + GOTO flow_21 + flow_12: + ivar2 = 38928629; + ivar3 = 38928630; + ivar4 = 38928631; + GOTO flow_21 + flow_13: + ivar2 = 38928633; + ivar3 = 38928634; + ivar4 = 38928635; + GOTO flow_21 + flow_14: + ivar2 = 38928686; + ivar3 = 38928687; + ivar4 = 38928688; + GOTO flow_21 + flow_15: + ivar2 = 38928395; + ivar3 = 38928396; + ivar4 = 38928397; + ivar5 = 0; + GOTO flow_21 + flow_16: + ivar2 = 38928461; + ivar3 = 38928462; + ivar4 = 38928463; + ivar5 = 0; + GOTO flow_21 + flow_17: + ivar2 = 38928388; + ivar3 = 38928389; + ivar4 = 38928390; + ivar5 = 0; + GOTO flow_21 + flow_18: + ivar2 = 38928439; + ivar3 = 38928440; + ivar4 = 38928441; + ivar5 = 0; + GOTO flow_21 + flow_19: + ivar2 = 38928510; + ivar3 = 38928511; + ivar4 = 38928512; + ivar5 = 0; + GOTO flow_21 + flow_20: + ivar2 = 38928515; + ivar3 = 38928516; + ivar4 = 38928517; + ivar5 = 0; + flow_21: + if (((boolean)arg1)) { + if (((boolean)ivar5)) { + if (ivar2 != -1) { + setWidgetSprite(1750, new WidgetPointer(ivar2)); + } + if (ivar3 != -1) { + setWidgetSprite(1751, new WidgetPointer(ivar3)); + } + if (ivar4 != -1) { + setWidgetSprite(1752, new WidgetPointer(ivar4)); + } + } else { + if (ivar2 != -1) { + setWidgetSprite(1756, new WidgetPointer(ivar2)); + } + if (ivar3 != -1) { + setWidgetSprite(1757, new WidgetPointer(ivar3)); + } + if (ivar4 != -1) { + setWidgetSprite(1758, new WidgetPointer(ivar4)); + } + } + } else if (((boolean)ivar5)) { + if (ivar2 != -1) { + setWidgetSprite(1753, new WidgetPointer(ivar2)); + } + if (ivar3 != -1) { + setWidgetSprite(1754, new WidgetPointer(ivar3)); + } + if (ivar4 != -1) { + setWidgetSprite(1755, new WidgetPointer(ivar4)); + } + } else { + if (ivar2 != -1) { + setWidgetSprite(1759, new WidgetPointer(ivar2)); + } + if (ivar3 != -1) { + setWidgetSprite(1760, new WidgetPointer(ivar3)); + } + if (ivar4 != -1) { + setWidgetSprite(1761, new WidgetPointer(ivar4)); + } + } + return; +} diff --git a/dumps/scripts/2430.cs2 b/dumps/scripts/2430.cs2 new file mode 100644 index 0000000..7ef481e --- /dev/null +++ b/dumps/scripts/2430.cs2 @@ -0,0 +1,339 @@ +void script_2430() { + if (((boolean)bitconfig_1628)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,56)); + } + if (((boolean)bitconfig_1629)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,57)); + } + if (((boolean)bitconfig_1630)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,58)); + } + if (((boolean)bitconfig_1631)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,59)); + } + if (((boolean)bitconfig_1632)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,60)); + } + if (((boolean)bitconfig_1633)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,61)); + } + if (((boolean)bitconfig_1634)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,62)); + } + if (((boolean)bitconfig_1635)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,63)); + } + if (((boolean)bitconfig_1636)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,64)); + } + if (((boolean)bitconfig_1637)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,65)); + } + if (((boolean)bitconfig_1638)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,66)); + } + if (((boolean)bitconfig_1639)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,67)); + } + if (((boolean)bitconfig_1640)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,68)); + } + if (((boolean)bitconfig_1641)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,69)); + } + if (((boolean)bitconfig_1642)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,70)); + } + if (((boolean)bitconfig_1643)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,71)); + } + if (((boolean)bitconfig_1644)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,72)); + } + if (((boolean)bitconfig_1645)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,73)); + } + if (((boolean)bitconfig_1646)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,74)); + } + if (((boolean)bitconfig_1647)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,75)); + } + if (((boolean)bitconfig_1648)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,76)); + } + if (((boolean)bitconfig_1649)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,77)); + } + if (((boolean)bitconfig_1650)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,78)); + } + if (((boolean)bitconfig_1651)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,79)); + } + if (((boolean)bitconfig_1652)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,80)); + } + if (((boolean)bitconfig_1653)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,81)); + } + if (((boolean)bitconfig_1654)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,82)); + } + if (((boolean)bitconfig_1655)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,83)); + } + if (((boolean)bitconfig_1656)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,84)); + } + if (((boolean)bitconfig_1657)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,85)); + } + if (((boolean)bitconfig_1658)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,86)); + } + if (((boolean)bitconfig_1659)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,87)); + } + if (((boolean)bitconfig_1660)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,88)); + } + if (((boolean)bitconfig_1661)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,89)); + } + if (((boolean)bitconfig_1662)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,90)); + } + if (((boolean)bitconfig_1663)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,91)); + } + if (((boolean)bitconfig_1664)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,92)); + } + if (((boolean)bitconfig_1665)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,93)); + } + if (((boolean)bitconfig_1666)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,94)); + } + if (((boolean)bitconfig_1667)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,95)); + } + if (((boolean)bitconfig_1668)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,96)); + } + if (((boolean)bitconfig_1669)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,97)); + } + if (((boolean)bitconfig_1670)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,98)); + } + if (((boolean)bitconfig_1671)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,99)); + } + if (((boolean)bitconfig_1672)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,100)); + } + if (((boolean)bitconfig_1673)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,101)); + } + if (((boolean)bitconfig_1674)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,102)); + } + if (((boolean)bitconfig_1675)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,103)); + } + if (((boolean)bitconfig_1676)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,104)); + } + if (((boolean)bitconfig_1677)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,105)); + } + if (((boolean)bitconfig_1678)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,106)); + } + if (((boolean)bitconfig_1679)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,107)); + } + if (((boolean)bitconfig_1680)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,108)); + } + if (((boolean)bitconfig_1681)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,109)); + } + if (((boolean)bitconfig_1682)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,110)); + } + if (((boolean)bitconfig_1683)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,111)); + } + if (((boolean)bitconfig_1684)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,0)); + } + if (((boolean)bitconfig_1685)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,1)); + } + if (((boolean)bitconfig_1686)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,2)); + } + if (((boolean)bitconfig_1687)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,3)); + } + if (((boolean)bitconfig_1688)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,4)); + } + if (((boolean)bitconfig_1689)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,5)); + } + if (((boolean)bitconfig_1690)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,6)); + } + if (((boolean)bitconfig_1691)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,7)); + } + if (((boolean)bitconfig_1692)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,8)); + } + if (((boolean)bitconfig_1693)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,9)); + } + if (((boolean)bitconfig_1694)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,10)); + } + if (((boolean)bitconfig_1695)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,11)); + } + if (((boolean)bitconfig_1696)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,12)); + } + if (((boolean)bitconfig_1697)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,13)); + } + if (((boolean)bitconfig_1698)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,14)); + } + if (((boolean)bitconfig_1699)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,15)); + } + if (((boolean)bitconfig_1700)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,16)); + } + if (((boolean)bitconfig_1701)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,17)); + } + if (((boolean)bitconfig_1702)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,18)); + } + if (((boolean)bitconfig_1703)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,19)); + } + if (((boolean)bitconfig_1704)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,20)); + } + if (((boolean)bitconfig_1705)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,21)); + } + if (((boolean)bitconfig_1706)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,22)); + } + if (((boolean)bitconfig_1707)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,23)); + } + if (((boolean)bitconfig_1708)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,24)); + } + if (((boolean)bitconfig_1709)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,25)); + } + if (((boolean)bitconfig_1710)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,26)); + } + if (((boolean)bitconfig_1711)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,27)); + } + if (((boolean)bitconfig_1712)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,28)); + } + if (((boolean)bitconfig_1713)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,29)); + } + if (((boolean)bitconfig_1714)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,30)); + } + if (((boolean)bitconfig_1715)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,31)); + } + if (((boolean)bitconfig_1716)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,32)); + } + if (((boolean)bitconfig_1717)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,33)); + } + if (((boolean)bitconfig_1718)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,34)); + } + if (((boolean)bitconfig_1719)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,35)); + } + if (((boolean)bitconfig_1720)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,36)); + } + if (((boolean)bitconfig_1721)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,37)); + } + if (((boolean)bitconfig_1722)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,38)); + } + if (((boolean)bitconfig_1723)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,39)); + } + if (((boolean)bitconfig_1724)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,40)); + } + if (((boolean)bitconfig_1725)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,41)); + } + if (((boolean)bitconfig_1726)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,42)); + } + if (((boolean)bitconfig_1727)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,43)); + } + if (((boolean)bitconfig_1728)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,44)); + } + if (((boolean)bitconfig_1729)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,45)); + } + if (((boolean)bitconfig_1730)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,46)); + } + if (((boolean)bitconfig_1731)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,47)); + } + if (((boolean)bitconfig_1732)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,48)); + } + if (((boolean)bitconfig_1733)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,49)); + } + if (((boolean)bitconfig_1734)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,50)); + } + if (((boolean)bitconfig_1735)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,51)); + } + if (((boolean)bitconfig_1736)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,52)); + } + if (((boolean)bitconfig_1737)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,53)); + } + if (((boolean)bitconfig_1738)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,54)); + } + if (((boolean)bitconfig_1739)) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(43,55)); + } + return; +} diff --git a/dumps/scripts/2431.cs2 b/dumps/scripts/2431.cs2 new file mode 100644 index 0000000..2d8c3bd --- /dev/null +++ b/dumps/scripts/2431.cs2 @@ -0,0 +1,5 @@ +void script_2431(int arg0) { + script_2410(getItemDefOpcode129Or130Method4209(arg0, 2), getItemDefOpcode129Or130Method4209(arg0, 1), getItemDefOpcode129Or130Method4209(arg0, 3), getItemDefOpcode129Or130Method4209(arg0, 4), getItemDefOpcode129Or130Method4209(arg0, 5), getItemOption(arg0, 2), getItemOption(arg0, 1), getItemOption(arg0, 3), getItemOption(arg0, 4), getItemOption(arg0, 5), getItemName(arg0)); + setScriptCallOnConfigChange(-1, ""); + return; +} diff --git a/dumps/scripts/2432.cs2 b/dumps/scripts/2432.cs2 new file mode 100644 index 0000000..e17ca57 --- /dev/null +++ b/dumps/scripts/2432.cs2 @@ -0,0 +1,3 @@ +void script_2432(int arg0) { + return; +} diff --git a/dumps/scripts/2433.cs2 b/dumps/scripts/2433.cs2 new file mode 100644 index 0000000..5c928ef --- /dev/null +++ b/dumps/scripts/2433.cs2 @@ -0,0 +1,11 @@ +void script_2433() { + if (((boolean)script_1431()) || ((boolean)stringMethod4107(globalstring_148, "null"))) { + return; + } + if (getDisplayMode() < 2) { + setWidgetText(new WidgetPointer(548,11), globalstring_148); + } else { + setWidgetText(new WidgetPointer(746,164), globalstring_148); + } + return; +} diff --git a/dumps/scripts/2434.cs2 b/dumps/scripts/2434.cs2 new file mode 100644 index 0000000..c285645 --- /dev/null +++ b/dumps/scripts/2434.cs2 @@ -0,0 +1,17 @@ +void script_2434(int arg0) { + globalint_815 = divide(multiply(arg0, 300), 10); + if (globalint_815 > 0) { + if (getDisplayMode() < 2) { + setScriptCallOnGameloop(2435, "", new WidgetPointer(548,12)); + setWidgetIsHidden(false, new WidgetPointer(548,13)); + setWidgetIsHidden(false, new WidgetPointer(548,14)); + } else { + setScriptCallOnGameloop(2435, "", new WidgetPointer(746,14)); + setWidgetIsHidden(false, new WidgetPointer(746,169)); + setWidgetIsHidden(false, new WidgetPointer(746,168)); + } + } else { + script_2436(); + } + return; +} diff --git a/dumps/scripts/2435.cs2 b/dumps/scripts/2435.cs2 new file mode 100644 index 0000000..983b35d --- /dev/null +++ b/dumps/scripts/2435.cs2 @@ -0,0 +1,41 @@ +void script_2435() { + int ivar0; + int ivar1; + string svar0; + string svar1; + if (globalint_815 > 0) { + globalint_815 = subtract(globalint_815, 1); + } else { + script_2436(); + return; + } + ivar0 = divide(globalint_815, 50); + ivar1 = divide(ivar0, 60); + ivar0 = subtract(ivar0, multiply(ivar1, 60)); + svar0 = ""; + svar1 = ""; + if (((boolean)ivar1)) { + svar0 = "00"; + } else if (ivar1 < 10) { + svar0 = "0" + intToStr(ivar1); + } else { + svar0 = intToStr(ivar1); + } + if (((boolean)ivar0)) { + svar1 = "00"; + } else if (ivar0 < 10) { + svar1 = "0" + intToStr(ivar0); + } else { + svar1 = intToStr(ivar0); + } + if (getDisplayMode() < 2) { + setWidgetIsHidden(false, new WidgetPointer(548,14)); + setWidgetIsHidden(false, new WidgetPointer(548,13)); + setWidgetText(new WidgetPointer(548,14), svar0 + ":" + svar1); + } else { + setWidgetIsHidden(false, new WidgetPointer(746,169)); + setWidgetIsHidden(false, new WidgetPointer(746,168)); + setWidgetText(new WidgetPointer(746,169), svar0 + ":" + svar1); + } + return; +} diff --git a/dumps/scripts/2436.cs2 b/dumps/scripts/2436.cs2 new file mode 100644 index 0000000..353c301 --- /dev/null +++ b/dumps/scripts/2436.cs2 @@ -0,0 +1,14 @@ +void script_2436() { + globalint_815 = 0; + script_1952(); + if (getDisplayMode() < 2) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(548,12)); + setWidgetIsHidden(true, new WidgetPointer(548,14)); + setWidgetIsHidden(true, new WidgetPointer(548,13)); + } else { + setScriptCallOnGameloop(-1, "", new WidgetPointer(746,14)); + setWidgetIsHidden(true, new WidgetPointer(746,169)); + setWidgetIsHidden(true, new WidgetPointer(746,168)); + } + return; +} diff --git a/dumps/scripts/2437.cs2 b/dumps/scripts/2437.cs2 new file mode 100644 index 0000000..30bc184 --- /dev/null +++ b/dumps/scripts/2437.cs2 @@ -0,0 +1,31 @@ +void script_2437() { + int ivar0; + int ivar1; + int ivar2; + ivar0 = 0; + ivar1 = 0; + ivar2 = 0; + switch (globalint_816) { + case 0: + return; + case 1: + ivar2 = globalint_817; + break; + case 2: + ivar2 = multiplyDivide(globalint_817, 125, 100); + break; + case 3: + ivar2 = multiplyDivide(globalint_817, 150, 100); + break; + default: + ivar2 = multiplyDivide(globalint_817, 175, 100); + } + if (ivar2 > 100) { + ivar2 = 100; + } + ivar0 = cs2method_3408(105, 105, 1090, ivar2); + ivar1 = cs2method_3408(105, 105, 1091, ivar2); + setWidgetPosition(91, ivar0, 2, 0, new WidgetPointer(15,11)); + setWidgetSize(18, ivar1, 0, 0, new WidgetPointer(15,11)); + return; +} diff --git a/dumps/scripts/2438.cs2 b/dumps/scripts/2438.cs2 new file mode 100644 index 0000000..90f5af0 --- /dev/null +++ b/dumps/scripts/2438.cs2 @@ -0,0 +1,21 @@ +void script_2438() { + int ivar0; + int ivar1; + int ivar2; + ivar0 = 0; + ivar1 = 0; + ivar2 = multiplyDivide(bitconfig_651, 1000, 100); + if (ivar2 > 100) { + ivar2 = 100; + } + ivar0 = cs2method_3408(105, 105, 1090, ivar2); + ivar1 = cs2method_3408(105, 105, 1091, ivar2); + setWidgetPosition(40, ivar0, 2, 0, new WidgetPointer(15,14)); + setWidgetSize(18, ivar1, 0, 0, new WidgetPointer(15,14)); + if (ivar2 < 25) { + setWidgetRGB(new Color(255, 153, 0), new WidgetPointer(15,14)); + } else { + setWidgetRGB(new Color(0, 102, 0), new WidgetPointer(15,14)); + } + return; +} diff --git a/dumps/scripts/2439.cs2 b/dumps/scripts/2439.cs2 new file mode 100644 index 0000000..e8ce7a4 --- /dev/null +++ b/dumps/scripts/2439.cs2 @@ -0,0 +1,10 @@ +void script_2439() { + if (((boolean)globalint_818)) { + setWidgetText(new WidgetPointer(15,16), "Net: Ripped!"); + setWidgetRGB(new Color(225, 35, 35), new WidgetPointer(15,16)); + } else { + setWidgetText(new WidgetPointer(15,16), "Net: OK"); + setWidgetRGB(new Color(255, 153, 0), new WidgetPointer(15,16)); + } + return; +} diff --git a/dumps/scripts/244.cs2 b/dumps/scripts/244.cs2 new file mode 100644 index 0000000..383e910 --- /dev/null +++ b/dumps/scripts/244.cs2 @@ -0,0 +1,6 @@ +void script_244() { + script_132(); + globalint_11 = 0; + globalstring_24 = ""; + return; +} diff --git a/dumps/scripts/2440.cs2 b/dumps/scripts/2440.cs2 new file mode 100644 index 0000000..27ec666 --- /dev/null +++ b/dumps/scripts/2440.cs2 @@ -0,0 +1,10 @@ +void script_2440() { + int ivar0; + ivar0 = divide(globalint_819, 2); + if (ivar0 < 1) { + setWidgetText(new WidgetPointer(15,17), "Catch: Nothing"); + } else { + setWidgetText(new WidgetPointer(15,17), "Catch: " + intToStr(ivar0) + " Fish"); + } + return; +} diff --git a/dumps/scripts/2441.cs2 b/dumps/scripts/2441.cs2 new file mode 100644 index 0000000..ad0cdc5 --- /dev/null +++ b/dumps/scripts/2441.cs2 @@ -0,0 +1,8 @@ +void script_2441() { + if (globalint_820 < 2) { + setWidgetText(new WidgetPointer(15,18), "Time Left: ~1 Min"); + } else { + setWidgetText(new WidgetPointer(15,18), "Time Left: " + intToStr(globalint_820) + " Mins"); + } + return; +} diff --git a/dumps/scripts/2442.cs2 b/dumps/scripts/2442.cs2 new file mode 100644 index 0000000..f9ea654 --- /dev/null +++ b/dumps/scripts/2442.cs2 @@ -0,0 +1,41 @@ +void script_2442() { + globalstring_149 = ""; + globalstring_150 = ""; + globalstring_151 = ""; + globalstring_152 = ""; + globalstring_153 = ""; + globalstring_154 = ""; + globalstring_155 = ""; + globalstring_156 = ""; + globalstring_157 = ""; + globalstring_158 = ""; + globalstring_159 = ""; + globalstring_160 = ""; + globalstring_161 = ""; + globalstring_162 = ""; + globalstring_163 = ""; + globalstring_164 = ""; + globalstring_165 = ""; + globalstring_166 = ""; + globalstring_167 = ""; + globalstring_168 = ""; + globalstring_169 = ""; + globalstring_170 = ""; + globalstring_171 = ""; + globalstring_172 = ""; + globalstring_173 = ""; + globalstring_174 = ""; + globalstring_175 = ""; + globalstring_176 = ""; + globalstring_177 = ""; + globalstring_178 = ""; + setScriptCallOnGlobalStringChange(2443, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 30, "Y", new WidgetPointer(34,9)); + setScriptCallOnConfigChange(2448, 1439, 1, "Y", new WidgetPointer(34,9)); + setScriptCallOnConfigChange(2443, 1440, 1441, 2, "Y", new WidgetPointer(34,6)); + setWidgetIsHidden(true, new WidgetPointer(34,16)); + deleteAllExtraChilds(new WidgetPointer(34,15)); + cs2method2100(0, 0, new WidgetPointer(34,15)); + setWidgetScrollMax(0, 0, new WidgetPointer(34,15)); + script_31(2228239, 2228233, 792, 789, 790, 791, 773, 788); + return; +} diff --git a/dumps/scripts/2443.cs2 b/dumps/scripts/2443.cs2 new file mode 100644 index 0000000..8c77a81 --- /dev/null +++ b/dumps/scripts/2443.cs2 @@ -0,0 +1,4 @@ +void script_2443() { + script_2444(); + return; +} diff --git a/dumps/scripts/2444.cs2 b/dumps/scripts/2444.cs2 new file mode 100644 index 0000000..0355189 --- /dev/null +++ b/dumps/scripts/2444.cs2 @@ -0,0 +1,63 @@ +void script_2444() { + int ivar0; + int ivar1; + int ivar2; + string svar0; + if (((boolean)standart_config_1437)) { + return; + } + if (isWidgetHidden(new WidgetPointer(34,10))) { + setScriptCallOnGameloop(2443, "", new WidgetPointer(34,9)); + return; + } + setScriptCallOnGameloop(-1, "", new WidgetPointer(34,9)); + script_1548(13); + setWidgetIsHidden(true, new WidgetPointer(34,16)); + globalint_821 = 0; + ivar0 = 0; + ivar1 = 0; + ivar2 = 0; + svar0 = ""; + deleteAllExtraChilds(new WidgetPointer(34,9)); + if (cs2method6900()) { + setWidgetText(new WidgetPointer(34,13), "The notes system is not available for users restricted to quick-chat."); + setWidgetIsHidden(false, new WidgetPointer(34,13)); + return; + } + setWidgetText(new WidgetPointer(34,13), ""); + setWidgetIsHidden(true, new WidgetPointer(34,13)); + while (ivar1 < 30) { + svar0 = script_2452(ivar1); + if (stringMethod4107(svar0, "") != 0) { + ivar0 = script_2445(ivar0, ivar2, script_2453(ivar1), svar0); + ivar2 = add(ivar2, 1); + } + ivar1 = add(ivar1, 1); + } + if (ivar2 <= 0) { + setWidgetText(new WidgetPointer(34,13), "No notes"); + setWidgetIsHidden(false, new WidgetPointer(34,13)); + setWidgetText(new WidgetPointer(34,1), "Notes"); + } else if ((ivar2 > 0) && (ivar2 <= 30)) { + setWidgetText(new WidgetPointer(34,1), "Notes (" + intToStr(ivar2) + "/" + "30" + ")"); + } else { + setWidgetText(new WidgetPointer(34,1), "Notes"); + } + if ((ivar0 > 0) && (ivar0 < 13)) { + if (setWidgetRegister(new WidgetPointer(34,9), subtract(ivar2, 1))) { + setWidgetSize(getWidgetActualWidth(), subtract(getWidgetActualHeight(new WidgetPointer(34,9)), add(getWidgetActualY(), getWidgetActualHeight())), 0, 0, new WidgetPointer(34,12)); + setWidgetPosition(getWidgetActualX(), add(getWidgetActualY(), getWidgetActualHeight()), 0, 0, new WidgetPointer(34,12)); + setWidgetIsHidden(false, new WidgetPointer(34,12)); + } + } else { + setWidgetIsHidden(true, new WidgetPointer(34,12)); + } + if (ivar0 < 1) { + setWidgetScrollMax(0, 0, new WidgetPointer(34,9)); + } else { + setWidgetScrollMax(0, add(multiply(ivar0, 15), 10), new WidgetPointer(34,9)); + } + script_72(2228239, 2228233, cs2method2601(new WidgetPointer(34,9))); + setWidgetIsHidden(true, new WidgetPointer(34,44)); + return; +} diff --git a/dumps/scripts/2445.cs2 b/dumps/scripts/2445.cs2 new file mode 100644 index 0000000..8f2414e --- /dev/null +++ b/dumps/scripts/2445.cs2 @@ -0,0 +1,27 @@ +int script_2445(int arg0,int arg1,int arg2,string arg3) { + int ivar3; + int ivar4; + ivar3 = getWidgetActualWidth(new WidgetPointer(34,9)); + arg3 = replaceLtGt(script_2446(arg3)); + createExtraChild(new WidgetPointer(34,9), 4, arg1); + setWidgetPosition(0, add(multiply(arg0, 15), 5), 0, 0); + ivar4 = getLineCount(ivar3, 494, arg3); + setWidgetSize(0, multiply(ivar4, 14), 1, 0); + setWidgetRGB(new Color(arg2)); + setWidgetText(arg3); + setWidgetFont(494); + setWidgetTextAlignment(0, 1, 14); + setWidgetUnknownBoolean(true); + setScriptCallOnMouseDragged(2450, new WidgetPointer(-32768,3), -2147483643, -2147483646, "Iii"); + setScriptCallOnMouseDragReleased(2451, new WidgetPointer(-32768,6), "I"); + if (standart_config_1439 == arg1) { + setWidgetContextMenuOption(1, "Unselect"); + } else { + setWidgetContextMenuOption(1, "Select"); + } + setWidgetContextMenuOption(2, "Edit"); + setWidgetContextMenuOption(3, "Colour"); + setWidgetContextMenuOption(4, "Delete"); + cs2method1303(14); + return add(arg0, ivar4); +} diff --git a/dumps/scripts/2446.cs2 b/dumps/scripts/2446.cs2 new file mode 100644 index 0000000..e2768a2 --- /dev/null +++ b/dumps/scripts/2446.cs2 @@ -0,0 +1,56 @@ +string script_2446(string arg0) { + string svar1; + svar1 = lower(arg0); + if (((boolean)stringMethod4107(svar1, "all your base are belong to us"))) { + return "orly?"; + } + if (((boolean)stringMethod4107(svar1, "orly"))) { + return "yarly"; + } + if (((boolean)stringMethod4107(svar1, "bangin'"))) { + return "donk"; + } + if (((boolean)stringMethod4107(svar1, "murder")) || ((boolean)stringMethod4107(svar1, "redrum"))) { + return "All rest and no play makes Guthix a dull boy."; + } + if (((boolean)stringMethod4107(svar1, "humperdinck")) || ((boolean)stringMethod4107(svar1, "humperdink"))) { + return "Have fun storming the castle!"; + } + if (((boolean)stringMethod4107(svar1, "i am your father"))) { + return "Nooooooooooooooooooooooooo!"; + } + if (((boolean)stringMethod4107(svar1, "i'll be back"))) { + return "Come with me if you want to live."; + } + if (((boolean)stringMethod4107(svar1, "there is no spoon"))) { + return "Then you will see, it is not the spoon that bends, it is only yourself."; + } + if (((boolean)stringMethod4107(svar1, "milton waddams"))) { + return "The ratio of people to cake is too big."; + } + if (((boolean)stringMethod4107(svar1, "you fight like a dairy farmer"))) { + return "How appropriate. You fight like a cow."; + } + if (((boolean)stringMethod4107(svar1, "finish the fight"))) { + return "They must love the smell of hero."; + } + if (((boolean)stringMethod4107(svar1, "r.i.p. runescape"))) { + return "Wanna bet?"; + } + if (((boolean)stringMethod4107(svar1, "penso, logo existo"))) { + return "Borboletas salpicadas de goiabada..."; + } + if (((boolean)stringMethod4107(svar1, "le temps passe"))) { + return "L'\u0153uf dur."; + } + if (((boolean)stringMethod4107(svar1, "paul"))) { + return "Rargh, I'm a lava monster!"; + } + if (((boolean)stringMethod4107(svar1, "andrew"))) { + return "Cabbage."; + } + if (((boolean)stringMethod4107(svar1, "sevga"))) { + return "Marmaros had a close encounter with a prayer-eating behemoth."; + } + return arg0; +} diff --git a/dumps/scripts/2447.cs2 b/dumps/scripts/2447.cs2 new file mode 100644 index 0000000..b3d28dd --- /dev/null +++ b/dumps/scripts/2447.cs2 @@ -0,0 +1,5 @@ +void script_2447() { + setWidgetIsHidden(true, new WidgetPointer(912,44)); + setWidgetIsHidden(true, new WidgetPointer(912,2)); + return; +} diff --git a/dumps/scripts/2448.cs2 b/dumps/scripts/2448.cs2 new file mode 100644 index 0000000..a2a46c4 --- /dev/null +++ b/dumps/scripts/2448.cs2 @@ -0,0 +1,4 @@ +void script_2448() { + script_2449(1); + return; +} diff --git a/dumps/scripts/2449.cs2 b/dumps/scripts/2449.cs2 new file mode 100644 index 0000000..9d10c8f --- /dev/null +++ b/dumps/scripts/2449.cs2 @@ -0,0 +1,30 @@ +void script_2449(int arg0) { + int ivar1; + ivar1 = 0; + while (setWidgetRegister(new WidgetPointer(34,9), ivar1)) { + setWidgetContextMenuOption(1, "Select"); + ivar1 = add(ivar1, 1); + } + if (setWidgetRegister(new WidgetPointer(34,9), standart_config_1439)) { + setWidgetContextMenuOption(1, "Unselect"); + if (isWidgetHidden(new WidgetPointer(34,10))) { + setWidgetIsHidden(true, new WidgetPointer(34,14)); + return; + } + setWidgetIsHidden(false, new WidgetPointer(34,14)); + setWidgetPosition(getWidgetActualX(), getWidgetActualY(), 0, 0, new WidgetPointer(34,14)); + setWidgetSize(getWidgetActualWidth(), getWidgetActualHeight(), 0, 0, new WidgetPointer(34,14)); + if (((boolean)arg0)) { + if (getWidgetActualY() < cs2method2601(new WidgetPointer(34,9))) { + script_157(2228239, 2228233, subtract(getWidgetActualY(), 5), 1); + } else { + if (add(getWidgetActualY(), getWidgetActualHeight()) > add(cs2method2601(new WidgetPointer(34,9)), getWidgetActualHeight(new WidgetPointer(34,9)))) { + script_157(2228239, 2228233, add(add(subtract(getWidgetActualY(), getWidgetActualHeight(new WidgetPointer(34,9))), getWidgetActualHeight()), 5), 1); + } + } + } + } else { + setWidgetIsHidden(true, new WidgetPointer(34,14)); + } + return; +} diff --git a/dumps/scripts/245.cs2 b/dumps/scripts/245.cs2 new file mode 100644 index 0000000..cd3b81e --- /dev/null +++ b/dumps/scripts/245.cs2 @@ -0,0 +1,4 @@ +void script_245() { + script_246(); + return; +} diff --git a/dumps/scripts/2450.cs2 b/dumps/scripts/2450.cs2 new file mode 100644 index 0000000..8591ca2 --- /dev/null +++ b/dumps/scripts/2450.cs2 @@ -0,0 +1,46 @@ +void script_2450(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + ivar3 = 0; + ivar4 = 0; + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetIsHidden(true, new WidgetPointer(34,14)); + setWidgetIsHidden(false, new WidgetPointer(34,10)); + ivar4 = getWidgetActualHeight(); + setWidgetPosition(getWidgetActualX(), arg2, 0, 0, new WidgetPointer(34,10)); + setWidgetSize(getWidgetActualWidth(), ivar4, 0, 0, new WidgetPointer(34,10)); + ivar3 = add(arg2, divide(ivar4, 2)); + } + ivar5 = getWidgetActualY(new WidgetPointer(34,11)); + ivar6 = add(ivar5, getWidgetActualHeight(new WidgetPointer(34,11))); + if ((ivar3 >= ivar5) && (ivar3 <= ivar6)) { + setWidgetSprite(1846, new WidgetPointer(34,8)); + } else { + setWidgetSprite(1845, new WidgetPointer(34,8)); + } + ivar7 = 0; + ivar8 = getWidgetActualY(new WidgetPointer(34,9)); + ivar9 = add(ivar8, ivar4); + ivar10 = add(ivar8, getWidgetActualHeight(new WidgetPointer(34,9))); + ivar11 = subtract(ivar10, ivar4); + if ((ivar3 >= ivar8) && (ivar3 <= ivar9)) { + ivar7 = -4; + } else if ((ivar3 >= ivar11) && (ivar3 <= ivar10)) { + ivar7 = 4; + } else { + globalint_821 = 0; + return; + } + globalint_821 = add(globalint_821, 1); + if (globalint_821 > 5) { + script_157(2228239, 2228233, add(cs2method2601(new WidgetPointer(34,9)), ivar7), 1); + } + return; +} diff --git a/dumps/scripts/2451.cs2 b/dumps/scripts/2451.cs2 new file mode 100644 index 0000000..f5e5487 --- /dev/null +++ b/dumps/scripts/2451.cs2 @@ -0,0 +1,10 @@ +void script_2451(int arg0) { + setWidgetIsHidden(true, new WidgetPointer(34,10)); + setWidgetSprite(1845, new WidgetPointer(34,8)); + globalint_821 = 0; + script_2449(0); + if (arg0 != -1) { + setWidgetIsHidden(false, new WidgetPointer(34,44)); + } + return; +} diff --git a/dumps/scripts/2452.cs2 b/dumps/scripts/2452.cs2 new file mode 100644 index 0000000..d223e0e --- /dev/null +++ b/dumps/scripts/2452.cs2 @@ -0,0 +1,96 @@ +string script_2452(int arg0) { + string svar0; + svar0 = ""; + switch (arg0) { + case 0: + svar0 = globalstring_149; + break; + case 1: + svar0 = globalstring_150; + break; + case 2: + svar0 = globalstring_151; + break; + case 3: + svar0 = globalstring_152; + break; + case 4: + svar0 = globalstring_153; + break; + case 5: + svar0 = globalstring_154; + break; + case 6: + svar0 = globalstring_155; + break; + case 7: + svar0 = globalstring_156; + break; + case 8: + svar0 = globalstring_157; + break; + case 9: + svar0 = globalstring_158; + break; + case 10: + svar0 = globalstring_159; + break; + case 11: + svar0 = globalstring_160; + break; + case 12: + svar0 = globalstring_161; + break; + case 13: + svar0 = globalstring_162; + break; + case 14: + svar0 = globalstring_163; + break; + case 15: + svar0 = globalstring_164; + break; + case 16: + svar0 = globalstring_165; + break; + case 17: + svar0 = globalstring_166; + break; + case 18: + svar0 = globalstring_167; + break; + case 19: + svar0 = globalstring_168; + break; + case 20: + svar0 = globalstring_169; + break; + case 21: + svar0 = globalstring_170; + break; + case 22: + svar0 = globalstring_171; + break; + case 23: + svar0 = globalstring_172; + break; + case 24: + svar0 = globalstring_173; + break; + case 25: + svar0 = globalstring_174; + break; + case 26: + svar0 = globalstring_175; + break; + case 27: + svar0 = globalstring_176; + break; + case 28: + svar0 = globalstring_177; + break; + case 29: + svar0 = globalstring_178; + } + return svar0; +} diff --git a/dumps/scripts/2453.cs2 b/dumps/scripts/2453.cs2 new file mode 100644 index 0000000..786ba7f --- /dev/null +++ b/dumps/scripts/2453.cs2 @@ -0,0 +1,96 @@ +int script_2453(int arg0) { + int ivar1; + ivar1 = 16777215; + switch (arg0) { + case 0: + ivar1 = script_2454(bitconfig_6316); + break; + case 1: + ivar1 = script_2454(bitconfig_6317); + break; + case 2: + ivar1 = script_2454(bitconfig_6318); + break; + case 3: + ivar1 = script_2454(bitconfig_6319); + break; + case 4: + ivar1 = script_2454(bitconfig_6320); + break; + case 5: + ivar1 = script_2454(bitconfig_6321); + break; + case 6: + ivar1 = script_2454(bitconfig_6322); + break; + case 7: + ivar1 = script_2454(bitconfig_6323); + break; + case 8: + ivar1 = script_2454(bitconfig_6324); + break; + case 9: + ivar1 = script_2454(bitconfig_6325); + break; + case 10: + ivar1 = script_2454(bitconfig_6326); + break; + case 11: + ivar1 = script_2454(bitconfig_6327); + break; + case 12: + ivar1 = script_2454(bitconfig_6328); + break; + case 13: + ivar1 = script_2454(bitconfig_6329); + break; + case 14: + ivar1 = script_2454(bitconfig_6330); + break; + case 15: + ivar1 = script_2454(bitconfig_6331); + break; + case 16: + ivar1 = script_2454(bitconfig_6332); + break; + case 17: + ivar1 = script_2454(bitconfig_6333); + break; + case 18: + ivar1 = script_2454(bitconfig_6334); + break; + case 19: + ivar1 = script_2454(bitconfig_6335); + break; + case 20: + ivar1 = script_2454(bitconfig_6336); + break; + case 21: + ivar1 = script_2454(bitconfig_6337); + break; + case 22: + ivar1 = script_2454(bitconfig_6338); + break; + case 23: + ivar1 = script_2454(bitconfig_6339); + break; + case 24: + ivar1 = script_2454(bitconfig_6340); + break; + case 25: + ivar1 = script_2454(bitconfig_6341); + break; + case 26: + ivar1 = script_2454(bitconfig_6342); + break; + case 27: + ivar1 = script_2454(bitconfig_6343); + break; + case 28: + ivar1 = script_2454(bitconfig_6344); + break; + case 29: + ivar1 = script_2454(bitconfig_6345); + } + return ivar1; +} diff --git a/dumps/scripts/2454.cs2 b/dumps/scripts/2454.cs2 new file mode 100644 index 0000000..2ecd6a4 --- /dev/null +++ b/dumps/scripts/2454.cs2 @@ -0,0 +1,18 @@ +int script_2454(int arg0) { + int ivar1; + ivar1 = 16777215; + switch (arg0) { + case 0: + ivar1 = 16777215; + break; + case 1: + ivar1 = 65280; + break; + case 2: + ivar1 = 14064640; + break; + case 3: + ivar1 = 16727871; + } + return ivar1; +} diff --git a/dumps/scripts/2455.cs2 b/dumps/scripts/2455.cs2 new file mode 100644 index 0000000..24f5d91 --- /dev/null +++ b/dumps/scripts/2455.cs2 @@ -0,0 +1,6 @@ +void script_2455(int arg0,int arg1) { + if (isWidgetHidden(new WidgetPointer(34,16)) && isWidgetHidden(new WidgetPointer(34,44))) { + setWidgetSprite(arg1, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/2456.cs2 b/dumps/scripts/2456.cs2 new file mode 100644 index 0000000..cc830f1 --- /dev/null +++ b/dumps/scripts/2456.cs2 @@ -0,0 +1,4 @@ +void script_2456() { + setWidgetIsHidden(true, new WidgetPointer(34,16)); + return; +} diff --git a/dumps/scripts/2457.cs2 b/dumps/scripts/2457.cs2 new file mode 100644 index 0000000..00eeee7 --- /dev/null +++ b/dumps/scripts/2457.cs2 @@ -0,0 +1,16 @@ +void script_2457(int arg0,int arg1) { + if (isWidgetOpen(new WidgetPointer(746,87))) { + return; + } + if (isWidgetOpen(new WidgetPointer(script_8(95)))) { + return; + } + globalint_10 = 0; + script_1304(arg0); + if (globalint_168 == arg0) { + globalint_168 = -1; + } else { + globalint_168 = arg0; + } + return; +} diff --git a/dumps/scripts/2458.cs2 b/dumps/scripts/2458.cs2 new file mode 100644 index 0000000..a3dd6fd --- /dev/null +++ b/dumps/scripts/2458.cs2 @@ -0,0 +1,74 @@ +int script_2458(int arg0) { + if (getDisplayMode() >= 2) { + switch (arg0) { + case 0: + return 48889895; + case 1: + return 48889896; + case 2: + return 48889897; + case 3: + return 48889898; + case 4: + return 48889899; + case 5: + return 48889900; + case 6: + return 48889901; + case 7: + return 48889902; + case 8: + return 48889903; + case 9: + return 48889904; + case 10: + return 48889905; + case 11: + return 48889906; + case 12: + return 48889907; + case 13: + return 48889908; + case 14: + return 48889909; + case 15: + return 48889910; + } + } else { + switch (arg0) { + case 0: + return 35913857; + case 1: + return 35913858; + case 2: + return 35913859; + case 3: + return 35913860; + case 4: + return 35913861; + case 5: + return 35913862; + case 6: + return 35913863; + case 7: + return 35913864; + case 8: + return 35913827; + case 9: + return 35913828; + case 10: + return 35913829; + case 11: + return 35913830; + case 12: + return 35913831; + case 13: + return 35913832; + case 14: + return 35913833; + case 15: + return 35913834; + } + } + return -1; +} diff --git a/dumps/scripts/2459.cs2 b/dumps/scripts/2459.cs2 new file mode 100644 index 0000000..febafec --- /dev/null +++ b/dumps/scripts/2459.cs2 @@ -0,0 +1,74 @@ +int script_2459(int arg0) { + if (getDisplayMode() >= 2) { + switch (arg0) { + case 0: + return 48889911; + case 1: + return 48889912; + case 2: + return 48889913; + case 3: + return 48889914; + case 4: + return 48889915; + case 5: + return 48889916; + case 6: + return 48889917; + case 7: + return 48889918; + case 8: + return 48889919; + case 9: + return 48889920; + case 10: + return 48889921; + case 11: + return 48889922; + case 12: + return 48889923; + case 13: + return 48889924; + case 14: + return 48889925; + case 15: + return 48889926; + } + } else { + switch (arg0) { + case 0: + return 35913848; + case 1: + return 35913849; + case 2: + return 35913850; + case 3: + return 35913851; + case 4: + return 35913852; + case 5: + return 35913853; + case 6: + return 35913854; + case 7: + return 35913855; + case 8: + return 35913801; + case 9: + return 35913802; + case 10: + return 35913803; + case 11: + return 35913804; + case 12: + return 35913805; + case 13: + return 35913806; + case 14: + return 35913807; + case 15: + return 35913808; + } + } + return -1; +} diff --git a/dumps/scripts/246.cs2 b/dumps/scripts/246.cs2 new file mode 100644 index 0000000..0cf06bf --- /dev/null +++ b/dumps/scripts/246.cs2 @@ -0,0 +1,13 @@ +void script_246() { + setScriptCallOnKeyPress(247, -2147483640, false, "iz", new WidgetPointer(594,53)); + setScriptCallOnKeyPress(-1, "", new WidgetPointer(137,56)); + globalint_6 = 0; + globalint_11 = 1; + if (isWidgetHidden(new WidgetPointer(752,3))) { + setWidgetIsHidden(true, new WidgetPointer(752,3)); + setWidgetIsHidden(false, new WidgetPointer(752,8)); + globalint_5 = 0; + globalstring_22 = ""; + } + return; +} diff --git a/dumps/scripts/2460.cs2 b/dumps/scripts/2460.cs2 new file mode 100644 index 0000000..1eb9656 --- /dev/null +++ b/dumps/scripts/2460.cs2 @@ -0,0 +1,4 @@ +void script_2460(int arg0) { + script_2308(arg0, 1); + return; +} diff --git a/dumps/scripts/2461.cs2 b/dumps/scripts/2461.cs2 new file mode 100644 index 0000000..4e3abaf --- /dev/null +++ b/dumps/scripts/2461.cs2 @@ -0,0 +1,4 @@ +void script_2461(int arg0) { + script_2309(arg0, 0); + return; +} diff --git a/dumps/scripts/2462.cs2 b/dumps/scripts/2462.cs2 new file mode 100644 index 0000000..4ccea72 --- /dev/null +++ b/dumps/scripts/2462.cs2 @@ -0,0 +1,8 @@ +void script_2462(int arg0,int arg1) { + if (((boolean)arg1)) { + setWidgetSprite(1837, new WidgetPointer(arg0)); + } else { + setWidgetSprite(1835, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/2463.cs2 b/dumps/scripts/2463.cs2 new file mode 100644 index 0000000..728098c --- /dev/null +++ b/dumps/scripts/2463.cs2 @@ -0,0 +1,17 @@ +void script_2463(string arg0,string arg1) { + if (getDisplayMode() >= 2) { + setWidgetIsHidden(false, new WidgetPointer(746,73)); + } + setWidgetIsHidden(false, new WidgetPointer(752,3)); + setWidgetIsHidden(true, new WidgetPointer(752,7)); + setWidgetIsHidden(true, new WidgetPointer(752,8)); + setWidgetText(new WidgetPointer(752,4), arg0); + globalint_5 = 13; + script_1564(arg1); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(752,3)); + script_2026(); + setScriptCallOnKeyPress(112, -2147483640, false, "iz", new WidgetPointer(752,5)); + setScriptCallOnWindowPaneRefresh(138, "", new WidgetPointer(752,5)); + script_1188(); + return; +} diff --git a/dumps/scripts/2464.cs2 b/dumps/scripts/2464.cs2 new file mode 100644 index 0000000..cb36d2f --- /dev/null +++ b/dumps/scripts/2464.cs2 @@ -0,0 +1,22 @@ +void script_2464(int arg0,int arg1) { + if (arg0 > subtract(getClientCycle(), 5)) { + return; + } + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg1)); + if (((boolean)script_2465(script_1305()))) { + if (getDisplayMode() >= 2) { + script_71(-1); + return; + } + if (((boolean)script_2465(4))) { + script_71(4); + } else if (((boolean)script_2465(9))) { + script_71(9); + } else { + if (((boolean)script_2465(12)) && (standart_config_281 > 3)) { + script_71(12); + } + } + } + return; +} diff --git a/dumps/scripts/2465.cs2 b/dumps/scripts/2465.cs2 new file mode 100644 index 0000000..9fde24f --- /dev/null +++ b/dumps/scripts/2465.cs2 @@ -0,0 +1,6 @@ +int script_2465(int arg0) { + if (isWidgetOpen(new WidgetPointer(script_8(arg0)))) { + return 1; + } + return 0; +} diff --git a/dumps/scripts/2466.cs2 b/dumps/scripts/2466.cs2 new file mode 100644 index 0000000..4ff4516 --- /dev/null +++ b/dumps/scripts/2466.cs2 @@ -0,0 +1,24 @@ +cs2func_script_2466_struct(2,0,0) script_2466(int arg0) { + if (((boolean)arg0)) { + cs2method5405(0, 6); + cs2method5405(1, 6); + cs2method5406(0, 0, 68048581, 710, 67999435, 605, 0); + cs2method5406(1, 0, 67966671, 258, 67917522, 258, 0); + cs2method5406(0, 1, 67901139, 725, 67802842, 875, 0); + cs2method5406(1, 1, 67802841, 474, 67753692, 474, 0); + script_1899(0, 200, 300); + cs2method5406(0, 2, 67753692, 925, 67655393, 915, 0); + cs2method5406(1, 2, 67606243, 530, 67540709, 530, 0); + script_1899(1, 300, 200); + cs2method5406(0, 3, 67524326, 780, 67475176, 700, 0); + cs2method5406(1, 3, 67491561, 444, 67442412, 355, 0); + script_1899(2, 200, 200); + cs2method5406(0, 4, 67393263, 665, 67393268, 645, 0); + cs2method5406(1, 4, 67458806, 190, 67475194, 160, 0); + script_1899(3, 200, 200); + cs2method5406(0, 5, 67475195, 650, 67524350, 640, 0); + cs2method5406(1, 5, 67540734, 70, 67589888, 15, 0); + script_1899(4, 200, 200); + } + return newstruct cs2func_script_2466_struct(67671776, 1250324); +} diff --git a/dumps/scripts/2467.cs2 b/dumps/scripts/2467.cs2 new file mode 100644 index 0000000..a619afe --- /dev/null +++ b/dumps/scripts/2467.cs2 @@ -0,0 +1,4 @@ +void script_2467(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,string arg8) { + script_2468(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + return; +} diff --git a/dumps/scripts/2468.cs2 b/dumps/scripts/2468.cs2 new file mode 100644 index 0000000..a4a7d8c --- /dev/null +++ b/dumps/scripts/2468.cs2 @@ -0,0 +1,53 @@ +void script_2468(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,string arg8) { + int ivar8; + int ivar9; + int ivar10; + int ivar11; + ivar8 = 0; + ivar9 = 0; + ivar10 = 0; + ivar11 = 0; + if (globalint_1 < add(getClientCycle(), 25)) { + if (globalint_1 < getClientCycle()) { + globalint_1 = getClientCycle(); + } + globalint_1 = add(globalint_1, 2); + return; + } + globalint_1 = add(add(getClientCycle(), 25), 10); + if (globalint_2 != 1) { + ivar10 = add(getMaxLineWidth(2147483647, arg7, arg8), 8); + ivar11 = getLineCount(ivar10, arg7, arg8); + if (ivar11 > 1) { + ivar11 = multiply(ivar11, 15); + } else { + ivar11 = 17; + } + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + ivar8 = add(add(add(getWidgetActualX(new WidgetPointer(arg4)), getWidgetActualX()), arg2), 3); + ivar9 = subtract(subtract(add(add(getWidgetActualY(new WidgetPointer(arg4)), getWidgetActualY()), arg3), ivar11), cs2method2601(new WidgetPointer(arg4))); + } else { + return; + } + if (ivar8 < 0) { + ivar8 = 0; + } else { + if (add(ivar8, ivar10) > add(getWidgetActualX(new WidgetPointer(arg4)), getWidgetActualWidth(new WidgetPointer(arg4)))) { + ivar8 = subtract(ivar8, subtract(add(ivar8, ivar10), add(getWidgetActualX(new WidgetPointer(arg4)), getWidgetActualWidth(new WidgetPointer(arg4))))); + } + } + if (ivar9 < 0) { + ivar9 = 0; + } else { + if (add(ivar9, ivar11) > add(getWidgetActualY(new WidgetPointer(arg4)), getWidgetActualHeight(new WidgetPointer(arg4)))) { + ivar9 = subtract(ivar9, subtract(add(ivar9, ivar11), add(getWidgetActualY(new WidgetPointer(arg4)), getWidgetActualHeight(new WidgetPointer(arg4))))); + } + } + setWidgetIsHidden(false, new WidgetPointer(arg5)); + setWidgetSize(ivar10, ivar11, 0, 0, new WidgetPointer(arg5)); + setWidgetPosition(ivar8, ivar9, 0, 0, new WidgetPointer(arg5)); + setWidgetText(new WidgetPointer(arg6), arg8); + globalint_2 = 1; + } + return; +} diff --git a/dumps/scripts/2469.cs2 b/dumps/scripts/2469.cs2 new file mode 100644 index 0000000..5bdf565 --- /dev/null +++ b/dumps/scripts/2469.cs2 @@ -0,0 +1,4 @@ +void script_2469(int arg0,int arg1) { + script_2470(arg0, arg1); + return; +} diff --git a/dumps/scripts/247.cs2 b/dumps/scripts/247.cs2 new file mode 100644 index 0000000..76cc387 --- /dev/null +++ b/dumps/scripts/247.cs2 @@ -0,0 +1,4 @@ +void script_247(int arg0,int arg1) { + globalstring_24 = script_74(2, arg0, arg1, globalstring_24); + return; +} diff --git a/dumps/scripts/2470.cs2 b/dumps/scripts/2470.cs2 new file mode 100644 index 0000000..09f49e3 --- /dev/null +++ b/dumps/scripts/2470.cs2 @@ -0,0 +1,7 @@ +void script_2470(int arg0,int arg1) { + setWidgetText(new WidgetPointer(arg1), ""); + setWidgetIsHidden(true, new WidgetPointer(arg0)); + globalint_2 = 0; + globalint_1 = 0; + return; +} diff --git a/dumps/scripts/2471.cs2 b/dumps/scripts/2471.cs2 new file mode 100644 index 0000000..0253532 --- /dev/null +++ b/dumps/scripts/2471.cs2 @@ -0,0 +1,6 @@ +void script_2471() { + setWidgetIsHidden(true, cs2method_3408(110, 73, 1092, standart_config_1174)); + setWidgetSprite(1244, new WidgetPointer(747,3)); + setWidgetIsHidden(true, new WidgetPointer(747,8)); + return; +} diff --git a/dumps/scripts/2472.cs2 b/dumps/scripts/2472.cs2 new file mode 100644 index 0000000..dfa42b4 --- /dev/null +++ b/dumps/scripts/2472.cs2 @@ -0,0 +1,83 @@ +void script_2472(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8) { + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + if (arg7 == -1) { + if (arg6 == -1) { + setWidgetIsHidden(true, new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(arg2)); + setWidgetIsHidden(true, new WidgetPointer(arg5)); + setWidgetPosition(subtract(getWidgetActualX(cs2method_3408(105, 73, arg8, 0)), 10), subtract(getWidgetActualY(cs2method_3408(105, 73, arg8, 0)), 10), 0, 0, new WidgetPointer(arg4)); + return; + } + arg7 = 20210; + } else { + if (arg6 == -1) { + arg6 = 20210; + } + } + setWidgetIsHidden(false, new WidgetPointer(arg0)); + setWidgetIsHidden(false, new WidgetPointer(arg2)); + setWidgetIsHidden(false, new WidgetPointer(arg5)); + ivar9 = getWidgetActualX(cs2method_3408(105, 73, arg8, getItemHashmapData(arg6, 359))); + ivar10 = getWidgetActualX(cs2method_3408(105, 73, arg8, getItemHashmapData(arg7, 359))); + ivar11 = 0; + ivar12 = -1; + if (ivar9 > ivar10) { + ivar12 = arg7; + arg7 = arg6; + arg6 = ivar12; + ivar11 = ivar10; + ivar10 = ivar9; + ivar9 = ivar11; + } + ivar13 = getWidgetActualY(cs2method_3408(105, 73, arg8, getItemHashmapData(arg6, 359))); + ivar14 = getWidgetActualY(cs2method_3408(105, 73, arg8, getItemHashmapData(arg7, 359))); + ivar15 = subtract(ivar10, ivar9); + ivar16 = 0; + setWidgetPosition(subtract(ivar9, 10), subtract(ivar13, 10), 0, 0, new WidgetPointer(arg0)); + setWidgetPosition(subtract(ivar10, 10), subtract(ivar14, 10), 0, 0, new WidgetPointer(arg2)); + if (setWidgetRegister(new WidgetPointer(arg1))) { + setWidgetStringNode(718, script_4126(script_718(getItemHashmapData(arg6, 359)))); + setWidgetRGB(new Color(script_718(getItemHashmapData(arg6, 359)))); + } + if (setWidgetRegister(new WidgetPointer(arg3))) { + setWidgetStringNode(718, script_4126(script_718(getItemHashmapData(arg7, 359)))); + setWidgetRGB(new Color(script_718(getItemHashmapData(arg7, 359)))); + } + ivar17 = 0; + ivar18 = 0; + ivar19 = add(getItemHashmapData(arg6, 358), getItemHashmapData(arg7, 358)); + if (ivar13 < ivar14) { + ivar16 = subtract(ivar14, ivar13); + setWidgetPosition(ivar9, ivar13, 0, 0, new WidgetPointer(arg5)); + cs2method2124(0, new WidgetPointer(arg5)); + ivar11 = 1; + } else { + ivar16 = subtract(ivar13, ivar14); + setWidgetPosition(ivar9, ivar14, 0, 0, new WidgetPointer(arg5)); + cs2method2124(1, new WidgetPointer(arg5)); + ivar11 = -1; + } + setWidgetSize(ivar15, ivar16, 0, 0, new WidgetPointer(arg5)); + if (arg6 == 20210) { + ivar17 = subtract(add(ivar9, divide(multiply(ivar15, getItemHashmapData(arg7, 358)), multiply(2, ivar19))), 10); + ivar18 = subtract(add(ivar13, multiply(ivar11, divide(multiply(ivar16, getItemHashmapData(arg7, 358)), multiply(2, ivar19)))), 10); + } else if (arg7 == 20210) { + ivar17 = subtract(add(ivar9, divide(multiply(ivar15, add(multiply(2, getItemHashmapData(arg7, 358)), getItemHashmapData(arg6, 358))), multiply(2, ivar19))), 10); + ivar18 = subtract(add(ivar13, multiply(ivar11, divide(multiply(ivar16, add(multiply(2, getItemHashmapData(arg7, 358)), getItemHashmapData(arg6, 358))), multiply(2, ivar19)))), 10); + } else { + ivar17 = subtract(add(ivar9, divide(multiply(ivar15, getItemHashmapData(arg7, 358)), ivar19)), 10); + ivar18 = subtract(add(ivar13, multiply(ivar11, divide(multiply(ivar16, getItemHashmapData(arg7, 358)), ivar19))), 10); + } + setWidgetPosition(ivar17, ivar18, 0, 0, new WidgetPointer(arg4)); + return; +} diff --git a/dumps/scripts/2473.cs2 b/dumps/scripts/2473.cs2 new file mode 100644 index 0000000..c208e12 --- /dev/null +++ b/dumps/scripts/2473.cs2 @@ -0,0 +1,6 @@ +void script_2473(int arg0,int arg1,int arg2) { + if (standart_config_850 != -1) { + script_1163(arg0, arg1, arg2, 0, 180, getItemName(standart_config_850)); + } + return; +} diff --git a/dumps/scripts/2474.cs2 b/dumps/scripts/2474.cs2 new file mode 100644 index 0000000..331cb63 --- /dev/null +++ b/dumps/scripts/2474.cs2 @@ -0,0 +1,6 @@ +void script_2474(int arg0,int arg1,int arg2) { + if (standart_config_855 != -1) { + script_1163(arg0, arg1, arg2, 0, 180, getItemName(standart_config_855)); + } + return; +} diff --git a/dumps/scripts/2475.cs2 b/dumps/scripts/2475.cs2 new file mode 100644 index 0000000..c79ba8c --- /dev/null +++ b/dumps/scripts/2475.cs2 @@ -0,0 +1,45 @@ +void script_2475(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + int ivar6; + ivar4 = 1093; + if (IsFemale()) { + ivar4 = 3872; + } + ivar5 = 0; + ivar6 = 0; + while (ivar5 <= getCommonDefinitionSize(ivar4)) { + createExtraChild(new WidgetPointer(arg0), 4, ivar5); + if (((boolean)ivar5) || ((ivar5 >= arg2) && (ivar5 <= arg3))) { + if (((boolean)ivar5)) { + setWidgetText("No Prefix"); + } else { + setWidgetText(cs2method_3408(105, 115, ivar4, ivar5)); + } + setWidgetPosition(0, ivar6, 0, 0); + setWidgetSize(165, 17, 0, 0); + setWidgetUnknownBoolean(false); + setWidgetFont(495); + setWidgetTextAlignment(0, 1, 0); + setWidgetContextMenuOption(1, "Select"); + setScriptCallOnClickContextMenu(2143, new WidgetPointer(-32768,3), -2147483643, "Ii"); + if (((boolean)script_2476(ivar5))) { + setWidgetRGB(new Color(17, 255, 0)); + } else { + setWidgetRGB(new Color(255, 17, 0)); + } + ivar6 = add(ivar6, 19); + } else { + setWidgetHidden(1); + } + ivar5 = add(1, ivar5); + } + if (ivar6 > getWidgetActualHeight(new WidgetPointer(arg0))) { + setWidgetScrollMax(0, add(25, ivar6), new WidgetPointer(arg0)); + setWidgetIsHidden(false, new WidgetPointer(arg1)); + script_31(arg1, arg0, 792, 789, 790, 791, 773, 788); + } else { + setWidgetIsHidden(true, new WidgetPointer(arg1)); + } + return; +} diff --git a/dumps/scripts/2476.cs2 b/dumps/scripts/2476.cs2 new file mode 100644 index 0000000..72fdffe --- /dev/null +++ b/dumps/scripts/2476.cs2 @@ -0,0 +1,124 @@ +int script_2476(int arg0) { + switch (arg0) { + case 1: + if (standart_config_1447 < 1) { + return 0; + } + break; + case 2: + if (standart_config_1447 < cs2method_3408(105, 105, 2461, 2)) { + return 0; + } + break; + case 3: + if (standart_config_1447 < cs2method_3408(105, 105, 2461, 3)) { + return 0; + } + break; + case 4: + if (standart_config_1447 < cs2method_3408(105, 105, 2461, 4)) { + return 0; + } + break; + case 5: + if (isBitFlagged(standart_config_2232, 0)) { + return 0; + } + break; + case 6: + if (isBitFlagged(standart_config_2232, 1)) { + return 0; + } + break; + case 7: + if (isBitFlagged(standart_config_2232, 2)) { + return 0; + } + break; + case 8: + if (isBitFlagged(standart_config_2232, 3)) { + return 0; + } + break; + case 9: + if (isBitFlagged(standart_config_2232, 4)) { + return 0; + } + break; + case 10: + if (isBitFlagged(standart_config_2232, 5)) { + return 0; + } + break; + case 11: + if (isBitFlagged(standart_config_2232, 6)) { + return 0; + } + break; + case 12: + if (isBitFlagged(standart_config_2232, 7)) { + return 0; + } + break; + case 13: + if (isBitFlagged(standart_config_2232, 8)) { + return 0; + } + break; + case 14: + if (isBitFlagged(standart_config_2232, 9)) { + return 0; + } + break; + case 15: + if (isBitFlagged(standart_config_2232, 10)) { + return 0; + } + break; + case 16: + if (isBitFlagged(standart_config_2232, 11)) { + return 0; + } + break; + case 17: + if (isBitFlagged(standart_config_2232, 12)) { + return 0; + } + break; + case 18: + if (isBitFlagged(standart_config_2232, 13)) { + return 0; + } + break; + case 19: + if (isBitFlagged(standart_config_2232, 14)) { + return 0; + } + break; + case 20: + if (isBitFlagged(standart_config_2232, 15)) { + return 0; + } + break; + case 21: + if (((boolean)bitconfig_9809)) { + return 0; + } + break; + case 22: + if (((boolean)bitconfig_9809)) { + return 0; + } + break; + case 23: + if (((boolean)bitconfig_9809)) { + return 0; + } + break; + case 24: + if (((boolean)bitconfig_9809)) { + return 0; + } + } + return 1; +} diff --git a/dumps/scripts/2477.cs2 b/dumps/scripts/2477.cs2 new file mode 100644 index 0000000..19de5a7 --- /dev/null +++ b/dumps/scripts/2477.cs2 @@ -0,0 +1,36 @@ +void script_2477() { + if (bitconfig_6348 == 28) { + setWidgetRGB(new Color(255, 255, 51), new WidgetPointer(854,1)); + } else { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(854,1)); + } + if (bitconfig_6348 < 30) { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(854,2)); + } else if (bitconfig_6348 == 30) { + setWidgetRGB(new Color(255, 255, 51), new WidgetPointer(854,2)); + } else { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(854,2)); + } + if (bitconfig_6348 < 32) { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(854,3)); + } else if (bitconfig_6348 == 32) { + setWidgetRGB(new Color(255, 255, 51), new WidgetPointer(854,3)); + } else { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(854,3)); + } + if (bitconfig_6348 < 34) { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(854,4)); + } else if (bitconfig_6348 == 34) { + setWidgetRGB(new Color(255, 255, 51), new WidgetPointer(854,4)); + } else { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(854,4)); + } + if (bitconfig_6348 < 36) { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(854,5)); + } else if (bitconfig_6348 == 36) { + setWidgetRGB(new Color(255, 255, 51), new WidgetPointer(854,5)); + } else { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(854,5)); + } + return; +} diff --git a/dumps/scripts/2478.cs2 b/dumps/scripts/2478.cs2 new file mode 100644 index 0000000..04a462f --- /dev/null +++ b/dumps/scripts/2478.cs2 @@ -0,0 +1,47 @@ +void script_2478(int arg0) { + switch (arg0) { + case 55967745: + if (bitconfig_6348 == 28) { + setWidgetRGB(new Color(255, 255, 51), new WidgetPointer(arg0)); + } else { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(arg0)); + } + break; + case 55967746: + if (bitconfig_6348 < 30) { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(arg0)); + } else if (bitconfig_6348 == 30) { + setWidgetRGB(new Color(255, 255, 51), new WidgetPointer(arg0)); + } else { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(arg0)); + } + break; + case 55967747: + if (bitconfig_6348 < 32) { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(arg0)); + } else if (bitconfig_6348 == 32) { + setWidgetRGB(new Color(255, 255, 51), new WidgetPointer(arg0)); + } else { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(arg0)); + } + break; + case 55967748: + if (bitconfig_6348 < 34) { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(arg0)); + } else if (bitconfig_6348 == 34) { + setWidgetRGB(new Color(255, 255, 51), new WidgetPointer(arg0)); + } else { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(arg0)); + } + break; + case 55967749: + if (bitconfig_6348 < 36) { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(arg0)); + } else if (bitconfig_6348 == 36) { + setWidgetRGB(new Color(255, 255, 51), new WidgetPointer(arg0)); + } else { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(arg0)); + } + } + return; +} diff --git a/dumps/scripts/2479.cs2 b/dumps/scripts/2479.cs2 new file mode 100644 index 0000000..c2a6c5f --- /dev/null +++ b/dumps/scripts/2479.cs2 @@ -0,0 +1,10 @@ +void script_2479() { + if (globalint_825 < 1) { + globalint_825 = 6; + } + if (globalint_825 > 0) { + globalint_825 = subtract(globalint_825, 1); + } + setWidgetText(new WidgetPointer(37,35), intToStr(globalint_825)); + return; +} diff --git a/dumps/scripts/248.cs2 b/dumps/scripts/248.cs2 new file mode 100644 index 0000000..247d560 --- /dev/null +++ b/dumps/scripts/248.cs2 @@ -0,0 +1,8 @@ +void script_248(int arg0) { + if (strLength(globalstring_24) > 0) { + cs2method5002(arg0, globalint_6, globalstring_24, ""); + } + script_675(); + globalint_11 = 0; + return; +} diff --git a/dumps/scripts/2480.cs2 b/dumps/scripts/2480.cs2 new file mode 100644 index 0000000..3fbcf8d --- /dev/null +++ b/dumps/scripts/2480.cs2 @@ -0,0 +1,61 @@ +void script_2480() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + ivar0 = 0; + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + ivar4 = 0; + ivar2 = divide(subtract(getWidgetActualWidth(new WidgetPointer(41,15)), multiply(36, 10)), subtract(10, 1)); + ivar3 = divide(subtract(getWidgetActualHeight(new WidgetPointer(41,15)), 128), 3); + deleteAllExtraChilds(new WidgetPointer(41,15)); + deleteAllExtraChilds(new WidgetPointer(881,0)); + while (((boolean)ivar4)) { + if (cs2method_3408(105, 79, globalint_875, ivar0) != 11760) { + createExtraChild(new WidgetPointer(41,15), 5, ivar0); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(multiply(add(36, ivar2), mod(ivar0, 10)), multiply(divide(ivar0, 10), add(32, ivar3)), 0, 0); + setItemOnWidgetMethod1200(cs2method_3408(105, 79, globalint_875, ivar0), -1); + cs2method1305("" + getItemName(cs2method_3408(105, 79, globalint_875, ivar0))); + setWidgetContextMenuOption(1, "Value"); + setWidgetContextMenuOption(2, "Buy 1"); + setWidgetContextMenuOption(3, "Examine"); + setWidgetShadowColor(new Color(51, 51, 51)); + setWidgetBorderThickness(1); + createExtraChild(new WidgetPointer(881,0), 5, ivar0); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(multiply(42, mod(ivar0, 4)), multiply(divide(ivar0, 4), 42), 0, 0); + setItemOnWidgetMethod1200(cs2method_3408(105, 79, globalint_875, ivar0), getItemAmtInContainer(93, cs2method_3408(105, 79, globalint_875, ivar0))); + cs2method1305("" + getItemName(cs2method_3408(105, 79, globalint_875, ivar0))); + setWidgetContextMenuOption(1, "Value"); + setWidgetContextMenuOption(2, "Sell 1"); + setWidgetContextMenuOption(3, "Sell X"); + setWidgetContextMenuOption(4, "Examine"); + setWidgetShadowColor(new Color(51, 51, 51)); + setWidgetBorderThickness(1); + ivar0 = add(ivar0, 1); + } else { + ivar4 = 1; + } + } + ivar1 = ivar0; + ivar0 = 0; + ivar4 = 0; + while (((boolean)ivar4)) { + if (cs2method_3408(105, 79, globalint_875, ivar0) != 11760) { + createExtraChild(new WidgetPointer(41,15), 5, ivar1); + setWidgetSize(12, 6, 0, 0); + setWidgetPosition(multiply(add(36, ivar2), mod(ivar0, 10)), multiply(divide(ivar0, 10), add(32, ivar3)), 0, 0); + setWidgetSprite(1066); + } else { + ivar4 = 1; + } + ivar0 = add(ivar0, 1); + ivar1 = add(ivar1, 1); + } + setWidgetText(new WidgetPointer(41,17), script_46(standart_config_1448, ",")); + return; +} diff --git a/dumps/scripts/2481.cs2 b/dumps/scripts/2481.cs2 new file mode 100644 index 0000000..1df5fd6 --- /dev/null +++ b/dumps/scripts/2481.cs2 @@ -0,0 +1,14 @@ +void script_2481() { + cs2method2308(14, 15, new WidgetPointer(855,17)); + cs2method2308(16, 17, new WidgetPointer(855,33)); + cs2method2308(18, 19, new WidgetPointer(855,19)); + cs2method2308(20, 21, new WidgetPointer(855,9)); + cs2method2308(26, 27, new WidgetPointer(855,11)); + cs2method2308(22, 23, new WidgetPointer(855,13)); + cs2method2308(24, 25, new WidgetPointer(855,15)); + cs2method2308(28, 29, new WidgetPointer(855,7)); + cs2method2308(30, 31, new WidgetPointer(855,2)); + cs2method2308(32, 33, new WidgetPointer(855,3)); + cs2method2308(34, 35, new WidgetPointer(855,1)); + return; +} diff --git a/dumps/scripts/2482.cs2 b/dumps/scripts/2482.cs2 new file mode 100644 index 0000000..80b6d6d --- /dev/null +++ b/dumps/scripts/2482.cs2 @@ -0,0 +1,4 @@ +void script_2482() { + script_2484(); + return; +} diff --git a/dumps/scripts/2483.cs2 b/dumps/scripts/2483.cs2 new file mode 100644 index 0000000..94f54ff --- /dev/null +++ b/dumps/scripts/2483.cs2 @@ -0,0 +1,4 @@ +void script_2483() { + script_2484(); + return; +} diff --git a/dumps/scripts/2484.cs2 b/dumps/scripts/2484.cs2 new file mode 100644 index 0000000..1e37915 --- /dev/null +++ b/dumps/scripts/2484.cs2 @@ -0,0 +1,44 @@ +void script_2484() { + int ivar0; + ivar0 = 1; + globalint_838 = bitconfig_6347; + while ((ivar0 <= 4) && (((int)cs2method_3408(105, 73, 2383, ivar0)) != 42926100)) { + if (ivar0 <= globalint_838) { + setWidgetRGB(new Color(225, 152, 31), cs2method_3408(105, 73, 2384, ivar0)); + setWidgetContextMenuOption(1, cs2method_3408(105, 73, 2383, ivar0), "Select"); + switch (ivar0) { + case 1: + setWidgetText(cs2method_3408(105, 73, 2384, ivar0), "Conflict"); + break; + case 2: + setWidgetText(cs2method_3408(105, 73, 2384, ivar0), "Siege"); + break; + case 3: + setWidgetText(cs2method_3408(105, 73, 2384, ivar0), "Hoard"); + break; + case 4: + setWidgetText(cs2method_3408(105, 73, 2384, ivar0), "Rescue"); + } + } else { + setWidgetRGB(new Color(153, 102, 0), cs2method_3408(105, 73, 2384, ivar0)); + setWidgetContextMenuOption(1, cs2method_3408(105, 73, 2383, ivar0), "Select"); + switch (ivar0) { + case 2: + setWidgetText(cs2method_3408(105, 73, 2384, ivar0), "Siege" + "
" + "- Locked"); + break; + case 3: + setWidgetText(cs2method_3408(105, 73, 2384, ivar0), "Hoard" + "
" + "- Locked"); + break; + case 4: + setWidgetText(cs2method_3408(105, 73, 2384, ivar0), "Rescue" + "
" + "- Locked"); + } + } + ivar0 = add(ivar0, 1); + } + setWidgetRGB(new Color(153, 102, 0), new WidgetPointer(655,42)); + setWidgetRGB(new Color(153, 102, 0), new WidgetPointer(655,31)); + setWidgetRGB(new Color(153, 102, 0), new WidgetPointer(655,38)); + setWidgetRGB(new Color(153, 102, 0), new WidgetPointer(655,26)); + script_2486(); + return; +} diff --git a/dumps/scripts/2485.cs2 b/dumps/scripts/2485.cs2 new file mode 100644 index 0000000..54e5e86 --- /dev/null +++ b/dumps/scripts/2485.cs2 @@ -0,0 +1,4 @@ +void script_2485() { + script_2486(); + return; +} diff --git a/dumps/scripts/2486.cs2 b/dumps/scripts/2486.cs2 new file mode 100644 index 0000000..61d5cd5 --- /dev/null +++ b/dumps/scripts/2486.cs2 @@ -0,0 +1,19 @@ +void script_2486() { + if (globalint_882 != -1) { + setWidgetText(new WidgetPointer(655,42), "Players: " + intToStr(globalint_882)); + } + if (globalint_887 != -1) { + setWidgetText(new WidgetPointer(655,31), "Players: " + intToStr(globalint_887)); + } + if (globalint_892 != -1) { + setWidgetText(new WidgetPointer(655,38), "Players: " + intToStr(globalint_892)); + } + if (globalint_897 != -1) { + setWidgetText(new WidgetPointer(655,26), "Players: " + intToStr(globalint_897)); + } + setWidgetRGB(new Color(225, 152, 31), new WidgetPointer(655,42)); + setWidgetRGB(new Color(225, 152, 31), new WidgetPointer(655,31)); + setWidgetRGB(new Color(225, 152, 31), new WidgetPointer(655,38)); + setWidgetRGB(new Color(225, 152, 31), new WidgetPointer(655,26)); + return; +} diff --git a/dumps/scripts/2487.cs2 b/dumps/scripts/2487.cs2 new file mode 100644 index 0000000..3394bd3 --- /dev/null +++ b/dumps/scripts/2487.cs2 @@ -0,0 +1,16 @@ +void script_2487(int arg0) { + setWidgetIsHidden(true, new WidgetPointer(844,10)); + setWidgetIsHidden(true, new WidgetPointer(844,11)); + setWidgetSprite(1421, new WidgetPointer(844,51)); + setWidgetSprite(1421, new WidgetPointer(844,49)); + switch (arg0) { + case 55312435: + setWidgetIsHidden(false, new WidgetPointer(844,10)); + setWidgetSprite(1420, new WidgetPointer(844,51)); + break; + case 55312433: + setWidgetIsHidden(false, new WidgetPointer(844,11)); + setWidgetSprite(1420, new WidgetPointer(844,49)); + } + return; +} diff --git a/dumps/scripts/2488.cs2 b/dumps/scripts/2488.cs2 new file mode 100644 index 0000000..68108ce --- /dev/null +++ b/dumps/scripts/2488.cs2 @@ -0,0 +1,10 @@ +void script_2488() { + setWidgetIsHidden(false, new WidgetPointer(844,10)); + setWidgetIsHidden(true, new WidgetPointer(844,11)); + setWidgetSprite(1420, new WidgetPointer(844,51)); + setWidgetSprite(1421, new WidgetPointer(844,49)); + setItemOnWidgetMethod2205(436, 1, new WidgetPointer(844,52)); + setItemOnWidgetMethod2205(1511, 1, new WidgetPointer(844,50)); + script_2490(); + return; +} diff --git a/dumps/scripts/2489.cs2 b/dumps/scripts/2489.cs2 new file mode 100644 index 0000000..a0500b8 --- /dev/null +++ b/dumps/scripts/2489.cs2 @@ -0,0 +1,4 @@ +void script_2489() { + script_2490(); + return; +} diff --git a/dumps/scripts/249.cs2 b/dumps/scripts/249.cs2 new file mode 100644 index 0000000..28e1cec --- /dev/null +++ b/dumps/scripts/249.cs2 @@ -0,0 +1,22 @@ +void script_249() { + globalint_799 = add(globalint_799, 1); + if (globalint_799 >= 30) { + globalint_799 = 0; + if (((boolean)globalint_798)) { + globalint_798 = 0; + } else { + globalint_798 = 1; + } + } + if (((boolean)globalint_798)) { + setWidgetText(new WidgetPointer(594,53), replaceLtGt(globalstring_24) + "" + " "); + } else { + setWidgetText(new WidgetPointer(594,53), replaceLtGt(globalstring_24) + "" + "|"); + } + if (((boolean)stringMethod4107(globalstring_24, ""))) { + setWidgetRGB(new Color(187, 187, 187), new WidgetPointer(594,58)); + } else { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(594,58)); + } + return; +} diff --git a/dumps/scripts/2490.cs2 b/dumps/scripts/2490.cs2 new file mode 100644 index 0000000..5d7b811 --- /dev/null +++ b/dumps/scripts/2490.cs2 @@ -0,0 +1,98 @@ +void script_2490() { + if (globalint_826 < 0) { + globalint_826 = 0; + } + if (globalint_827 < 0) { + globalint_827 = 1; + } + setWidgetText(new WidgetPointer(844,47), "Charges left: " + intToStr(globalint_826)); + setItemOnWidgetMethod2205(436, 1, new WidgetPointer(844,29)); + setItemOnWidgetMethod2205(438, 1, new WidgetPointer(844,30)); + setItemOnWidgetMethod2205(440, 1, new WidgetPointer(844,31)); + setItemOnWidgetMethod2205(442, 1, new WidgetPointer(844,32)); + setItemOnWidgetMethod2205(434, 1, new WidgetPointer(844,33)); + setItemOnWidgetMethod2205(444, 1, new WidgetPointer(844,34)); + setItemOnWidgetMethod2205(447, 1, new WidgetPointer(844,35)); + setItemOnWidgetMethod2205(449, 1, new WidgetPointer(844,36)); + setItemOnWidgetMethod2205(451, 1, new WidgetPointer(844,37)); + setWidgetText(new WidgetPointer(844,38), getItemName(436)); + setWidgetText(new WidgetPointer(844,39), getItemName(438)); + setWidgetText(new WidgetPointer(844,40), getItemName(440)); + setWidgetText(new WidgetPointer(844,41), getItemName(442)); + setWidgetText(new WidgetPointer(844,42), getItemName(434)); + setWidgetText(new WidgetPointer(844,43), getItemName(444)); + setWidgetText(new WidgetPointer(844,44), getItemName(447)); + setWidgetText(new WidgetPointer(844,45), getItemName(449)); + setWidgetText(new WidgetPointer(844,46), getItemName(451)); + setWidgetRGB(new Color(225, 152, 31), new WidgetPointer(844,38)); + setWidgetRGB(new Color(225, 152, 31), new WidgetPointer(844,39)); + setWidgetRGB(new Color(225, 152, 31), new WidgetPointer(844,40)); + setWidgetRGB(new Color(153, 102, 0), new WidgetPointer(844,41)); + setWidgetRGB(new Color(153, 102, 0), new WidgetPointer(844,42)); + setWidgetRGB(new Color(153, 102, 0), new WidgetPointer(844,43)); + setWidgetRGB(new Color(153, 102, 0), new WidgetPointer(844,44)); + setWidgetRGB(new Color(153, 102, 0), new WidgetPointer(844,45)); + setWidgetRGB(new Color(153, 102, 0), new WidgetPointer(844,46)); + if (globalint_827 >= 2) { + setWidgetRGB(new Color(225, 152, 31), new WidgetPointer(844,41)); + setWidgetRGB(new Color(225, 152, 31), new WidgetPointer(844,42)); + } + if (globalint_827 >= 3) { + setWidgetRGB(new Color(225, 152, 31), new WidgetPointer(844,43)); + setWidgetRGB(new Color(225, 152, 31), new WidgetPointer(844,44)); + } + if (globalint_827 >= 4) { + setWidgetRGB(new Color(225, 152, 31), new WidgetPointer(844,45)); + setWidgetRGB(new Color(225, 152, 31), new WidgetPointer(844,46)); + } + setItemOnWidgetMethod2205(1521, 1, new WidgetPointer(844,13)); + setItemOnWidgetMethod2205(1519, 1, new WidgetPointer(844,14)); + setItemOnWidgetMethod2205(1517, 1, new WidgetPointer(844,15)); + setItemOnWidgetMethod2205(12581, 1, new WidgetPointer(844,16)); + setItemOnWidgetMethod2205(1515, 1, new WidgetPointer(844,17)); + setItemOnWidgetMethod2205(1513, 1, new WidgetPointer(844,18)); + setWidgetText(new WidgetPointer(844,21), getItemName(1521)); + setWidgetText(new WidgetPointer(844,22), getItemName(1519)); + setWidgetText(new WidgetPointer(844,23), getItemName(1517)); + setWidgetText(new WidgetPointer(844,24), "Special logs"); + setWidgetText(new WidgetPointer(844,25), getItemName(1515)); + setWidgetText(new WidgetPointer(844,26), getItemName(1513)); + setWidgetRGB(new Color(225, 152, 31), new WidgetPointer(844,21)); + setWidgetRGB(new Color(225, 152, 31), new WidgetPointer(844,22)); + setWidgetRGB(new Color(153, 102, 0), new WidgetPointer(844,23)); + setWidgetRGB(new Color(153, 102, 0), new WidgetPointer(844,24)); + setWidgetRGB(new Color(153, 102, 0), new WidgetPointer(844,25)); + setWidgetRGB(new Color(153, 102, 0), new WidgetPointer(844,26)); + if (globalint_827 >= 2) { + setWidgetRGB(new Color(225, 152, 31), new WidgetPointer(844,23)); + setWidgetRGB(new Color(225, 152, 31), new WidgetPointer(844,24)); + } + if (globalint_827 >= 3) { + setWidgetRGB(new Color(225, 152, 31), new WidgetPointer(844,25)); + } + if (globalint_827 >= 4) { + setWidgetRGB(new Color(225, 152, 31), new WidgetPointer(844,26)); + } + setItemOnWidgetMethod2205(317, 1, new WidgetPointer(844,6)); + setItemOnWidgetMethod2205(377, 1, new WidgetPointer(844,8)); + setWidgetText(new WidgetPointer(844,7), "Fish 1"); + setWidgetText(new WidgetPointer(844,9), "Fish 2"); + setWidgetRGB(new Color(225, 152, 31), new WidgetPointer(844,7)); + if (globalint_827 >= 3) { + setWidgetRGB(new Color(225, 152, 31), new WidgetPointer(844,9)); + } else { + setWidgetRGB(new Color(153, 102, 0), new WidgetPointer(844,9)); + } + setItemOnWidgetMethod2205(2152, 1, new WidgetPointer(844,2)); + setItemOnWidgetMethod2205(239, 1, new WidgetPointer(844,4)); + setWidgetText(new WidgetPointer(844,3), "Herblore" + "
" + "secondaries 1"); + setWidgetText(new WidgetPointer(844,5), "Herblore" + "
" + "secondaries 2"); + setWidgetRGB(new Color(225, 152, 31), new WidgetPointer(844,3)); + setWidgetRGB(new Color(225, 152, 31), new WidgetPointer(844,5)); + if (globalint_827 >= 3) { + setWidgetRGB(new Color(225, 152, 31), new WidgetPointer(844,5)); + } else { + setWidgetRGB(new Color(153, 102, 0), new WidgetPointer(844,5)); + } + return; +} diff --git a/dumps/scripts/2491.cs2 b/dumps/scripts/2491.cs2 new file mode 100644 index 0000000..1756615 --- /dev/null +++ b/dumps/scripts/2491.cs2 @@ -0,0 +1,4 @@ +void script_2491() { + setWidgetText(new WidgetPointer(862,8), script_46(bitconfig_6380, ",")); + return; +} diff --git a/dumps/scripts/2492.cs2 b/dumps/scripts/2492.cs2 new file mode 100644 index 0000000..11b4bb3 --- /dev/null +++ b/dumps/scripts/2492.cs2 @@ -0,0 +1,27 @@ +void script_2492() { + if (((boolean)stringMethod4107(globalstring_184, ""))) { + setScriptCallOnMouseOver(38, new WidgetPointer(862,50), new WidgetPointer(862,11), globalstring_184, 50, 250, "IIsii", new WidgetPointer(862,50)); + setScriptCallOnMouseExit(40, new WidgetPointer(862,11), "I", new WidgetPointer(862,50)); + } + if (((boolean)stringMethod4107(globalstring_185, ""))) { + setScriptCallOnMouseOver(38, new WidgetPointer(862,51), new WidgetPointer(862,11), globalstring_185, 50, 250, "IIsii", new WidgetPointer(862,51)); + setScriptCallOnMouseExit(40, new WidgetPointer(862,11), "I", new WidgetPointer(862,51)); + } + if (((boolean)stringMethod4107(globalstring_186, ""))) { + setScriptCallOnMouseOver(38, new WidgetPointer(862,52), new WidgetPointer(862,11), globalstring_186, 50, 250, "IIsii", new WidgetPointer(862,52)); + setScriptCallOnMouseExit(40, new WidgetPointer(862,11), "I", new WidgetPointer(862,52)); + } + if (((boolean)stringMethod4107(globalstring_187, ""))) { + setScriptCallOnMouseOver(38, new WidgetPointer(862,53), new WidgetPointer(862,11), globalstring_187, 50, 250, "IIsii", new WidgetPointer(862,53)); + setScriptCallOnMouseExit(40, new WidgetPointer(862,11), "I", new WidgetPointer(862,53)); + } + if (((boolean)stringMethod4107(globalstring_188, ""))) { + setScriptCallOnMouseOver(38, new WidgetPointer(862,54), new WidgetPointer(862,11), globalstring_188, 50, 250, "IIsii", new WidgetPointer(862,54)); + setScriptCallOnMouseExit(40, new WidgetPointer(862,11), "I", new WidgetPointer(862,54)); + } + if (((boolean)stringMethod4107(globalstring_189, ""))) { + setScriptCallOnMouseOver(38, new WidgetPointer(862,55), new WidgetPointer(862,11), globalstring_189, 50, 250, "IIsii", new WidgetPointer(862,55)); + setScriptCallOnMouseExit(40, new WidgetPointer(862,11), "I", new WidgetPointer(862,55)); + } + return; +} diff --git a/dumps/scripts/2493.cs2 b/dumps/scripts/2493.cs2 new file mode 100644 index 0000000..e8defba --- /dev/null +++ b/dumps/scripts/2493.cs2 @@ -0,0 +1,9 @@ +void script_2493(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + setItemOnWidgetMethod2200(arg0, -1, new WidgetPointer(862,50)); + setItemOnWidgetMethod2200(arg1, -1, new WidgetPointer(862,51)); + setItemOnWidgetMethod2200(arg2, -1, new WidgetPointer(862,52)); + setItemOnWidgetMethod2200(arg3, -1, new WidgetPointer(862,53)); + setItemOnWidgetMethod2200(arg4, -1, new WidgetPointer(862,54)); + setItemOnWidgetMethod2200(arg5, -1, new WidgetPointer(862,55)); + return; +} diff --git a/dumps/scripts/2494.cs2 b/dumps/scripts/2494.cs2 new file mode 100644 index 0000000..c57ead4 --- /dev/null +++ b/dumps/scripts/2494.cs2 @@ -0,0 +1,9 @@ +void script_2494(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + setItemOnWidgetMethod2200(arg0, -1, new WidgetPointer(653,26)); + setItemOnWidgetMethod2200(arg1, -1, new WidgetPointer(653,27)); + setItemOnWidgetMethod2200(arg2, -1, new WidgetPointer(653,28)); + setItemOnWidgetMethod2200(arg3, -1, new WidgetPointer(653,29)); + setItemOnWidgetMethod2200(arg4, -1, new WidgetPointer(653,30)); + setItemOnWidgetMethod2200(arg5, -1, new WidgetPointer(653,31)); + return; +} diff --git a/dumps/scripts/2495.cs2 b/dumps/scripts/2495.cs2 new file mode 100644 index 0000000..4972acb --- /dev/null +++ b/dumps/scripts/2495.cs2 @@ -0,0 +1,10 @@ +void script_2495() { + int ivar0; + ivar0 = 1; + globalint_837 = bitconfig_6350; + script_2496(); + if ((globalint_837 > 0) && (globalint_837 <= 9)) { + script_2500(((int)cs2method_3408(105, 73, 2400, globalint_837))); + } + return; +} diff --git a/dumps/scripts/2496.cs2 b/dumps/scripts/2496.cs2 new file mode 100644 index 0000000..87ca160 --- /dev/null +++ b/dumps/scripts/2496.cs2 @@ -0,0 +1,33 @@ +void script_2496() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + ivar0 = 1; + ivar1 = script_2497(); + ivar2 = -1; + ivar3 = -1; + while ((ivar0 <= 9) || (((int)cs2method_3408(105, 73, 2400, ivar0)) != 2949145)) { + if (ivar0 <= ivar1) { + ivar2 = ((int)cs2method_3408(105, 73, 2400, ivar0)); + ivar3 = ((int)cs2method_3408(105, 73, 2402, ivar0)); + setScriptCallOnMousePressed(2499, new WidgetPointer(-32768,3), "I", new WidgetPointer(ivar2)); + setScriptCallOnMousePressed(2499, new WidgetPointer(ivar2), "I", new WidgetPointer(ivar3)); + setWidgetRGB(new Color(225, 152, 31), new WidgetPointer(ivar3)); + setWidgetContextMenuOption(1, new WidgetPointer(ivar2), "Select"); + setWidgetContextMenuOption(1, new WidgetPointer(ivar3), "Select"); + setWidgetText(new WidgetPointer(ivar3), cs2method_3408(105, 115, 2403, ivar0)); + } else { + ivar2 = ((int)cs2method_3408(105, 73, 2400, ivar0)); + ivar3 = ((int)cs2method_3408(105, 73, 2402, ivar0)); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(ivar2)); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(ivar3)); + setWidgetRGB(new Color(153, 102, 0), new WidgetPointer(ivar3)); + setWidgetNoOptions(new WidgetPointer(ivar2)); + setWidgetNoOptions(new WidgetPointer(ivar3)); + setWidgetText(new WidgetPointer(ivar3), cs2method_3408(105, 115, 2403, ivar0) + " - Locked"); + } + ivar0 = add(ivar0, 1); + } + return; +} diff --git a/dumps/scripts/2497.cs2 b/dumps/scripts/2497.cs2 new file mode 100644 index 0000000..385d8d4 --- /dev/null +++ b/dumps/scripts/2497.cs2 @@ -0,0 +1,18 @@ +int script_2497() { + if (standart_config_1447 < 51) { + return 3; + } + if (standart_config_1447 < 101) { + return 4; + } + if (standart_config_1447 < 201) { + return 5; + } + if (standart_config_1447 < 301) { + return 7; + } + if (standart_config_1447 < 401) { + return 8; + } + return 9; +} diff --git a/dumps/scripts/2498.cs2 b/dumps/scripts/2498.cs2 new file mode 100644 index 0000000..d5165e1 --- /dev/null +++ b/dumps/scripts/2498.cs2 @@ -0,0 +1,7 @@ +void script_2498() { + globalint_837 = bitconfig_6350; + if ((globalint_837 > 0) && (globalint_837 <= 9)) { + script_2500(((int)cs2method_3408(105, 73, 2400, globalint_837))); + } + return; +} diff --git a/dumps/scripts/2499.cs2 b/dumps/scripts/2499.cs2 new file mode 100644 index 0000000..909510f --- /dev/null +++ b/dumps/scripts/2499.cs2 @@ -0,0 +1,4 @@ +void script_2499(int arg0) { + script_2500(arg0); + return; +} diff --git a/dumps/scripts/25.cs2 b/dumps/scripts/25.cs2 new file mode 100644 index 0000000..79a9aea --- /dev/null +++ b/dumps/scripts/25.cs2 @@ -0,0 +1,94 @@ +void script_25() { + int ivar0; + int ivar1; + ivar0 = 0; + ivar1 = 0; + if (ivar0 != 0) { + if (isBitFlagged(ivar0, 0)) { + ivar1 = flagBit(ivar1, 0); + } + if (isBitFlagged(ivar0, 1)) { + ivar1 = flagBit(ivar1, 1); + } + if (isBitFlagged(ivar0, 2)) { + ivar1 = flagBit(ivar1, 2); + } + if (isBitFlagged(ivar0, 3)) { + ivar1 = flagBit(ivar1, 3); + } + globalint_996 = ivar1; + ivar1 = 0; + if (isBitFlagged(ivar0, 4)) { + ivar1 = flagBit(ivar1, 0); + } + if (isBitFlagged(ivar0, 5)) { + ivar1 = flagBit(ivar1, 1); + } + if (isBitFlagged(ivar0, 6)) { + ivar1 = flagBit(ivar1, 2); + } + if (isBitFlagged(ivar0, 7)) { + ivar1 = flagBit(ivar1, 3); + } + globalint_997 = ivar1; + ivar1 = 0; + if (isBitFlagged(ivar0, 14)) { + ivar1 = flagBit(ivar1, 0); + } + if (isBitFlagged(ivar0, 15)) { + ivar1 = flagBit(ivar1, 1); + } + if (isBitFlagged(ivar0, 16)) { + ivar1 = flagBit(ivar1, 2); + } + if (isBitFlagged(ivar0, 17)) { + ivar1 = flagBit(ivar1, 3); + } + if (isBitFlagged(ivar0, 18)) { + ivar1 = flagBit(ivar1, 4); + } + if (isBitFlagged(ivar0, 19)) { + ivar1 = flagBit(ivar1, 5); + } + if (isBitFlagged(ivar0, 20)) { + ivar1 = flagBit(ivar1, 6); + } + if (isBitFlagged(ivar0, 21)) { + ivar1 = flagBit(ivar1, 7); + } + if (isBitFlagged(ivar0, 22)) { + ivar1 = flagBit(ivar1, 8); + } + globalint_998 = ivar1; + ivar1 = 0; + if (isBitFlagged(ivar0, 23)) { + ivar1 = flagBit(ivar1, 0); + } + if (isBitFlagged(ivar0, 24)) { + ivar1 = flagBit(ivar1, 1); + } + if (isBitFlagged(ivar0, 25)) { + ivar1 = flagBit(ivar1, 2); + } + if (isBitFlagged(ivar0, 26)) { + ivar1 = flagBit(ivar1, 3); + } + if (isBitFlagged(ivar0, 27)) { + ivar1 = flagBit(ivar1, 4); + } + if (isBitFlagged(ivar0, 28)) { + ivar1 = flagBit(ivar1, 5); + } + if (isBitFlagged(ivar0, 29)) { + ivar1 = flagBit(ivar1, 6); + } + if (isBitFlagged(ivar0, 30)) { + ivar1 = flagBit(ivar1, 7); + } + if (isBitFlagged(ivar0, 31)) { + ivar1 = flagBit(ivar1, 8); + } + globalint_999 = ivar1; + } + return; +} diff --git a/dumps/scripts/250.cs2 b/dumps/scripts/250.cs2 new file mode 100644 index 0000000..5678ece --- /dev/null +++ b/dumps/scripts/250.cs2 @@ -0,0 +1,6 @@ +void script_250(int arg0) { + if (((boolean)mod(getClientCycle(), 5))) { + script_251(arg0); + } + return; +} diff --git a/dumps/scripts/2500.cs2 b/dumps/scripts/2500.cs2 new file mode 100644 index 0000000..ee1e2e1 --- /dev/null +++ b/dumps/scripts/2500.cs2 @@ -0,0 +1,17 @@ +void script_2500(int arg0) { + int ivar1; + ivar1 = 1; + while ((ivar1 <= 9) || (((int)cs2method_3408(105, 73, 2400, ivar1)) != 2949145)) { + if (((int)cs2method_3408(105, 73, 2400, ivar1)) != arg0) { + setWidgetSprite(1134, cs2method_3408(105, 73, 2400, ivar1)); + } else { + setWidgetSprite(1135, new WidgetPointer(arg0)); + globalint_837 = ivar1; + } + ivar1 = add(ivar1, 1); + } + if ((globalint_837 > 0) && (globalint_837 <= 9)) { + setWidgetModel(cs2method_3408(105, 109, 2399, globalint_837), new WidgetPointer(45,39)); + } + return; +} diff --git a/dumps/scripts/2501.cs2 b/dumps/scripts/2501.cs2 new file mode 100644 index 0000000..42e5120 --- /dev/null +++ b/dumps/scripts/2501.cs2 @@ -0,0 +1,7 @@ +void script_2501() { + setWidgetIsHidden(true, new WidgetPointer(291,55)); + setWidgetIsHidden(true, new WidgetPointer(291,56)); + setWidgetIsHidden(true, new WidgetPointer(291,57)); + setWidgetIsHidden(true, new WidgetPointer(291,58)); + return; +} diff --git a/dumps/scripts/2502.cs2 b/dumps/scripts/2502.cs2 new file mode 100644 index 0000000..a6f2a53 --- /dev/null +++ b/dumps/scripts/2502.cs2 @@ -0,0 +1,16 @@ +void script_2502() { + switch (globalint_838) { + case 1: + setWidgetIsHidden(false, new WidgetPointer(291,58)); + break; + case 2: + setWidgetIsHidden(false, new WidgetPointer(291,55)); + break; + case 3: + setWidgetIsHidden(false, new WidgetPointer(291,57)); + break; + case 4: + setWidgetIsHidden(false, new WidgetPointer(291,56)); + } + return; +} diff --git a/dumps/scripts/2503.cs2 b/dumps/scripts/2503.cs2 new file mode 100644 index 0000000..41493fa --- /dev/null +++ b/dumps/scripts/2503.cs2 @@ -0,0 +1,6 @@ +void script_2503() { + if ((globalint_837 > 0) && (globalint_837 <= 9)) { + setWidgetText(new WidgetPointer(291,33), cs2method_3408(105, 115, 2403, globalint_837)); + } + return; +} diff --git a/dumps/scripts/2504.cs2 b/dumps/scripts/2504.cs2 new file mode 100644 index 0000000..5799906 --- /dev/null +++ b/dumps/scripts/2504.cs2 @@ -0,0 +1,15 @@ +void script_2504() { + int ivar0; + ivar0 = 0; + setWidgetText(new WidgetPointer(291,73), globalstring_180); + setWidgetText(new WidgetPointer(291,28), globalstring_181); + ivar0 = add(multiply(getLineCount(207, 497, globalstring_180), 17), 5); + setWidgetSize(207, ivar0, 0, 0, new WidgetPointer(291,73)); + setWidgetScrollMax(0, ivar0, new WidgetPointer(291,72)); + script_72(19071045, 19071048, 0); + ivar0 = add(multiply(getLineCount(207, 497, globalstring_181), 17), 5); + setWidgetSize(207, ivar0, 0, 0, new WidgetPointer(291,28)); + setWidgetScrollMax(0, ivar0, new WidgetPointer(291,68)); + script_72(19071046, 19071044, 0); + return; +} diff --git a/dumps/scripts/2505.cs2 b/dumps/scripts/2505.cs2 new file mode 100644 index 0000000..acc9d5f --- /dev/null +++ b/dumps/scripts/2505.cs2 @@ -0,0 +1,4 @@ +void script_2505(int arg0) { + setWidgetText(new WidgetPointer(arg0), "Limit: " + script_46(script_2687(), ",")); + return; +} diff --git a/dumps/scripts/2506.cs2 b/dumps/scripts/2506.cs2 new file mode 100644 index 0000000..7363260 --- /dev/null +++ b/dumps/scripts/2506.cs2 @@ -0,0 +1,5 @@ +void script_2506(int arg0) { + globalint_839 = subtract(bitconfig_6351, bitconfig_6427); + setWidgetText(new WidgetPointer(arg0), script_46(globalint_839, ",")); + return; +} diff --git a/dumps/scripts/2507.cs2 b/dumps/scripts/2507.cs2 new file mode 100644 index 0000000..2a91b05 --- /dev/null +++ b/dumps/scripts/2507.cs2 @@ -0,0 +1,5 @@ +void script_2507(int arg0) { + globalint_840 = bitconfig_6427; + setWidgetText(new WidgetPointer(arg0), script_46(globalint_840, ",")); + return; +} diff --git a/dumps/scripts/2508.cs2 b/dumps/scripts/2508.cs2 new file mode 100644 index 0000000..8c30e3c --- /dev/null +++ b/dumps/scripts/2508.cs2 @@ -0,0 +1,50 @@ +void script_2508(int arg0) { + switch (arg0) { + case 55836719: + globalint_840 = 0; + break; + case 55836713: + if (((globalint_840 < subtract(2147483647, 10)) && (globalint_839 >= 10)) && ((boolean)script_2509(10))) { + globalint_840 = add(globalint_840, 10); + globalint_839 = subtract(globalint_839, 10); + } + break; + case 55836715: + if (((globalint_840 < subtract(2147483647, 100)) && (globalint_839 >= 100)) && ((boolean)script_2509(100))) { + globalint_840 = add(globalint_840, 100); + globalint_839 = subtract(globalint_839, 100); + } + break; + case 55836721: + if (((globalint_840 < subtract(2147483647, 500)) && (globalint_839 >= 500)) && ((boolean)script_2509(500))) { + globalint_840 = add(globalint_840, 500); + globalint_839 = subtract(globalint_839, 500); + } + break; + case 55836723: + if (((globalint_840 < subtract(2147483647, 1000)) && (globalint_839 >= 1000)) && ((boolean)script_2509(1000))) { + globalint_840 = add(globalint_840, 1000); + globalint_839 = subtract(globalint_839, 1000); + } + break; + case 55836725: + if (((globalint_840 < subtract(2147483647, 10000)) && (globalint_839 >= 10000)) && ((boolean)script_2509(10000))) { + globalint_840 = add(globalint_840, 10000); + globalint_839 = subtract(globalint_839, 10000); + } + break; + case 55836717: + if (globalint_839 < script_2687()) { + globalint_840 = globalint_839; + globalint_839 = 0; + } else { + if (globalint_840 < script_2687()) { + globalint_840 = script_2687(); + globalint_839 = subtract(globalint_839, script_2687()); + } + } + } + setWidgetText(new WidgetPointer(852,63), script_46(globalint_840, ",")); + setWidgetText(new WidgetPointer(852,62), script_46(globalint_839, ",")); + return; +} diff --git a/dumps/scripts/2509.cs2 b/dumps/scripts/2509.cs2 new file mode 100644 index 0000000..3c2a342 --- /dev/null +++ b/dumps/scripts/2509.cs2 @@ -0,0 +1,6 @@ +int script_2509(int arg0) { + if (globalint_840 <= subtract(script_2687(), arg0)) { + return 1; + } + return 0; +} diff --git a/dumps/scripts/251.cs2 b/dumps/scripts/251.cs2 new file mode 100644 index 0000000..fa24954 --- /dev/null +++ b/dumps/scripts/251.cs2 @@ -0,0 +1,12 @@ +void script_251(int arg0) { + if (((boolean)script_133(42996800, 849335423, getMyPositionHash())) && cs2method6108()) { + if (isWidgetHidden(new WidgetPointer(arg0))) { + setWidgetIsHidden(false, new WidgetPointer(arg0)); + } + } else { + if (isWidgetHidden(new WidgetPointer(arg0))) { + setWidgetIsHidden(true, new WidgetPointer(arg0)); + } + } + return; +} diff --git a/dumps/scripts/2510.cs2 b/dumps/scripts/2510.cs2 new file mode 100644 index 0000000..f348d28 --- /dev/null +++ b/dumps/scripts/2510.cs2 @@ -0,0 +1,23 @@ +void script_2510() { + if (globalint_852 <= 0) { + globalint_852 = 0; + } + if (globalint_853 <= 0) { + globalint_853 = 0; + } + if (globalint_854 <= 0) { + globalint_854 = 0; + } + if (globalint_855 <= 0) { + globalint_855 = 0; + } + if (globalint_856 <= 0) { + globalint_856 = 0; + } + setWidgetText(new WidgetPointer(654,9), intToStr(globalint_852)); + setWidgetText(new WidgetPointer(654,58), intToStr(globalint_853)); + setWidgetText(new WidgetPointer(654,50), intToStr(globalint_854)); + setWidgetText(new WidgetPointer(654,42), intToStr(globalint_855)); + setWidgetText(new WidgetPointer(654,67), intToStr(globalint_856)); + return; +} diff --git a/dumps/scripts/2511.cs2 b/dumps/scripts/2511.cs2 new file mode 100644 index 0000000..f1e1e93 --- /dev/null +++ b/dumps/scripts/2511.cs2 @@ -0,0 +1,8 @@ +void script_2511() { + setWidgetText(new WidgetPointer(654,8), cs2method_3408(105, 115, 2385, 1)); + setWidgetText(new WidgetPointer(654,57), cs2method_3408(105, 115, 2385, 2)); + setWidgetText(new WidgetPointer(654,49), cs2method_3408(105, 115, 2385, 3)); + setWidgetText(new WidgetPointer(654,41), cs2method_3408(105, 115, 2385, 4)); + setWidgetText(new WidgetPointer(654,66), cs2method_3408(105, 115, 2385, 5)); + return; +} diff --git a/dumps/scripts/2512.cs2 b/dumps/scripts/2512.cs2 new file mode 100644 index 0000000..d73cd4d --- /dev/null +++ b/dumps/scripts/2512.cs2 @@ -0,0 +1,8 @@ +void script_2512() { + setWidgetText(new WidgetPointer(654,10), script_46(cs2method_3408(105, 105, 2454, 1), ",")); + setWidgetText(new WidgetPointer(654,59), script_46(cs2method_3408(105, 105, 2454, 2), ",")); + setWidgetText(new WidgetPointer(654,51), script_46(cs2method_3408(105, 105, 2454, 3), ",")); + setWidgetText(new WidgetPointer(654,43), script_46(cs2method_3408(105, 105, 2454, 4), ",")); + setWidgetText(new WidgetPointer(654,68), script_46(cs2method_3408(105, 105, 2454, 5), ",")); + return; +} diff --git a/dumps/scripts/2513.cs2 b/dumps/scripts/2513.cs2 new file mode 100644 index 0000000..c9648b8 --- /dev/null +++ b/dumps/scripts/2513.cs2 @@ -0,0 +1,23 @@ +void script_2513() { + if (globalint_847 < 0) { + globalint_847 = 0; + } + if (globalint_848 < 0) { + globalint_848 = 0; + } + if (globalint_849 < 0) { + globalint_849 = 0; + } + if (globalint_850 < 0) { + globalint_850 = 0; + } + if (globalint_851 < 0) { + globalint_851 = 0; + } + setWidgetText(new WidgetPointer(654,13), intToStr(globalint_847)); + setWidgetText(new WidgetPointer(654,61), intToStr(globalint_848)); + setWidgetText(new WidgetPointer(654,53), intToStr(globalint_849)); + setWidgetText(new WidgetPointer(654,45), intToStr(globalint_850)); + setWidgetText(new WidgetPointer(654,70), intToStr(globalint_851)); + return; +} diff --git a/dumps/scripts/2514.cs2 b/dumps/scripts/2514.cs2 new file mode 100644 index 0000000..a4a4058 --- /dev/null +++ b/dumps/scripts/2514.cs2 @@ -0,0 +1,12 @@ +void script_2514() { + setWidgetText(new WidgetPointer(654,11), "0"); + setWidgetText(new WidgetPointer(654,60), "0"); + setWidgetText(new WidgetPointer(654,52), "0"); + setWidgetText(new WidgetPointer(654,44), "0"); + setWidgetText(new WidgetPointer(654,69), "0"); + setWidgetText(new WidgetPointer(654,74), "0"); + if (globalint_839 >= 0) { + setWidgetText(new WidgetPointer(654,77), script_46(globalint_839, ",")); + } + return; +} diff --git a/dumps/scripts/2515.cs2 b/dumps/scripts/2515.cs2 new file mode 100644 index 0000000..3429ebe --- /dev/null +++ b/dumps/scripts/2515.cs2 @@ -0,0 +1,4 @@ +void script_2515() { + script_2516(); + return; +} diff --git a/dumps/scripts/2516.cs2 b/dumps/scripts/2516.cs2 new file mode 100644 index 0000000..a6695cc --- /dev/null +++ b/dumps/scripts/2516.cs2 @@ -0,0 +1,16 @@ +void script_2516() { + globalint_847 = bitconfig_6364; + globalint_848 = bitconfig_6366; + globalint_849 = bitconfig_6367; + globalint_850 = bitconfig_6363; + globalint_851 = bitconfig_6365; + globalint_839 = bitconfig_6351; + setWidgetText(new WidgetPointer(654,13), intToStr(globalint_847)); + setWidgetText(new WidgetPointer(654,61), intToStr(globalint_848)); + setWidgetText(new WidgetPointer(654,53), intToStr(globalint_849)); + setWidgetText(new WidgetPointer(654,45), intToStr(globalint_850)); + setWidgetText(new WidgetPointer(654,70), intToStr(globalint_851)); + setWidgetText(new WidgetPointer(654,77), script_46(globalint_839, ",")); + script_2517(); + return; +} diff --git a/dumps/scripts/2517.cs2 b/dumps/scripts/2517.cs2 new file mode 100644 index 0000000..3b66dde --- /dev/null +++ b/dumps/scripts/2517.cs2 @@ -0,0 +1,29 @@ +void script_2517() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + ivar0 = 0; + ivar1 = 0; + ivar2 = multiply(globalint_847, cs2method_3408(105, 105, 2454, 1)); + ivar3 = multiply(globalint_848, cs2method_3408(105, 105, 2454, 2)); + ivar4 = multiply(globalint_849, cs2method_3408(105, 105, 2454, 3)); + ivar5 = multiply(globalint_850, cs2method_3408(105, 105, 2454, 4)); + ivar6 = multiply(globalint_851, cs2method_3408(105, 105, 2454, 5)); + setWidgetText(new WidgetPointer(654,11), script_46(ivar2, ",")); + setWidgetText(new WidgetPointer(654,60), script_46(ivar3, ",")); + setWidgetText(new WidgetPointer(654,52), script_46(ivar4, ",")); + setWidgetText(new WidgetPointer(654,44), script_46(ivar5, ",")); + setWidgetText(new WidgetPointer(654,69), script_46(ivar6, ",")); + ivar1 = add(ivar2, ivar3); + ivar1 = add(ivar1, ivar4); + ivar1 = add(ivar1, ivar5); + ivar1 = add(ivar1, ivar6); + setWidgetText(new WidgetPointer(654,74), script_46(ivar1, ",")); + ivar0 = subtract(globalint_839, ivar1); + setWidgetText(new WidgetPointer(654,77), script_46(ivar0, ",")); + return; +} diff --git a/dumps/scripts/2518.cs2 b/dumps/scripts/2518.cs2 new file mode 100644 index 0000000..2c8188e --- /dev/null +++ b/dumps/scripts/2518.cs2 @@ -0,0 +1,37 @@ +void script_2518(int arg0) { + int ivar1; + ivar1 = script_2520(); + switch (arg0) { + case 42860559: + if ((globalint_847 < 5) && (ivar1 < 5)) { + globalint_847 = add(globalint_847, 1); + setWidgetText(new WidgetPointer(654,13), intToStr(globalint_847)); + } + break; + case 42860607: + if ((globalint_848 < 5) && (ivar1 < 5)) { + globalint_848 = add(globalint_848, 1); + setWidgetText(new WidgetPointer(654,61), intToStr(globalint_848)); + } + break; + case 42860599: + if ((globalint_849 < 5) && (ivar1 < 5)) { + globalint_849 = add(globalint_849, 1); + setWidgetText(new WidgetPointer(654,53), intToStr(globalint_849)); + } + break; + case 42860591: + if ((globalint_850 < 5) && (ivar1 < 5)) { + globalint_850 = add(globalint_850, 1); + setWidgetText(new WidgetPointer(654,45), intToStr(globalint_850)); + } + break; + case 42860616: + if ((globalint_851 < 5) && (ivar1 < 5)) { + globalint_851 = add(globalint_851, 1); + setWidgetText(new WidgetPointer(654,70), intToStr(globalint_851)); + } + } + script_2517(); + return; +} diff --git a/dumps/scripts/2519.cs2 b/dumps/scripts/2519.cs2 new file mode 100644 index 0000000..68f9f91 --- /dev/null +++ b/dumps/scripts/2519.cs2 @@ -0,0 +1,37 @@ +void script_2519(int arg0) { + int ivar1; + ivar1 = script_2520(); + switch (arg0) { + case 42860558: + if (globalint_847 > 0) { + globalint_847 = subtract(globalint_847, 1); + setWidgetText(new WidgetPointer(654,13), intToStr(globalint_847)); + } + break; + case 42860606: + if (globalint_848 > 0) { + globalint_848 = subtract(globalint_848, 1); + setWidgetText(new WidgetPointer(654,61), intToStr(globalint_848)); + } + break; + case 42860598: + if (globalint_849 > 0) { + globalint_849 = subtract(globalint_849, 1); + setWidgetText(new WidgetPointer(654,53), intToStr(globalint_849)); + } + break; + case 42860590: + if (globalint_850 > 0) { + globalint_850 = subtract(globalint_850, 1); + setWidgetText(new WidgetPointer(654,45), intToStr(globalint_850)); + } + break; + case 42860615: + if (globalint_851 > 0) { + globalint_851 = subtract(globalint_851, 1); + setWidgetText(new WidgetPointer(654,70), intToStr(globalint_851)); + } + } + script_2517(); + return; +} diff --git a/dumps/scripts/252.cs2 b/dumps/scripts/252.cs2 new file mode 100644 index 0000000..b03a1d9 --- /dev/null +++ b/dumps/scripts/252.cs2 @@ -0,0 +1,4 @@ +void script_252() { + script_253(); + return; +} diff --git a/dumps/scripts/2520.cs2 b/dumps/scripts/2520.cs2 new file mode 100644 index 0000000..5d247a6 --- /dev/null +++ b/dumps/scripts/2520.cs2 @@ -0,0 +1,15 @@ +int script_2520() { + int ivar0; + ivar0 = 0; + ivar0 = add(ivar0, globalint_847); + ivar0 = add(ivar0, globalint_852); + ivar0 = add(ivar0, globalint_848); + ivar0 = add(ivar0, globalint_853); + ivar0 = add(ivar0, globalint_849); + ivar0 = add(ivar0, globalint_854); + ivar0 = add(ivar0, globalint_850); + ivar0 = add(ivar0, globalint_855); + ivar0 = add(ivar0, globalint_851); + ivar0 = add(ivar0, globalint_856); + return ivar0; +} diff --git a/dumps/scripts/2521.cs2 b/dumps/scripts/2521.cs2 new file mode 100644 index 0000000..ad0ae7a --- /dev/null +++ b/dumps/scripts/2521.cs2 @@ -0,0 +1,50 @@ +void script_2521() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + ivar0 = 0; + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + ivar4 = -1; + ivar5 = -1; + ivar1 = divide(subtract(getWidgetActualWidth(new WidgetPointer(848,2)), 180), 4); + ivar2 = divide(subtract(getWidgetActualHeight(new WidgetPointer(848,2)), 128), 3); + while ((ivar0 < 5) && (cs2method_3408(105, 79, globalint_875, ivar0) != 11760)) { + ivar5 = cs2method_3408(105, 79, globalint_875, ivar0); + switch (ivar0) { + case 0: + setWidgetText(new WidgetPointer(848,19), getItemName(getRealItem(ivar5))); + ivar3 = globalint_876; + break; + case 1: + setWidgetText(new WidgetPointer(848,20), getItemName(getRealItem(ivar5))); + ivar3 = globalint_877; + break; + case 2: + setWidgetText(new WidgetPointer(848,21), getItemName(getRealItem(ivar5))); + ivar3 = globalint_878; + break; + case 3: + setWidgetText(new WidgetPointer(848,22), getItemName(getRealItem(ivar5))); + ivar3 = globalint_879; + break; + case 4: + setWidgetText(new WidgetPointer(848,23), getItemName(getRealItem(ivar5))); + ivar3 = globalint_880; + } + createExtraChild(new WidgetPointer(848,2), 5, ivar0); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(multiply(add(36, ivar1), mod(ivar0, 5)), multiply(divide(ivar0, 5), add(32, ivar2)), 0, 0); + setItemOnWidgetMethod1200(getRealItem(ivar5), ivar3); + cs2method1305("" + getItemName(getRealItem(ivar5))); + setWidgetContextMenuOption(1, "Select"); + setWidgetContextMenuOption(2, "Examine"); + setWidgetShadowColor(new Color(51, 51, 51)); + ivar0 = add(ivar0, 1); + } + return; +} diff --git a/dumps/scripts/2522.cs2 b/dumps/scripts/2522.cs2 new file mode 100644 index 0000000..08a7193 --- /dev/null +++ b/dumps/scripts/2522.cs2 @@ -0,0 +1,8 @@ +void script_2522(int arg0) { + if (((boolean)bitconfig_6375)) { + setWidgetSprite(1135, new WidgetPointer(arg0)); + } else { + setWidgetSprite(1134, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/2523.cs2 b/dumps/scripts/2523.cs2 new file mode 100644 index 0000000..125a772 --- /dev/null +++ b/dumps/scripts/2523.cs2 @@ -0,0 +1,8 @@ +void script_2523(int arg0) { + if (((boolean)bitconfig_6376)) { + setWidgetSprite(1135, new WidgetPointer(arg0)); + } else { + setWidgetSprite(1134, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/2524.cs2 b/dumps/scripts/2524.cs2 new file mode 100644 index 0000000..398c207 --- /dev/null +++ b/dumps/scripts/2524.cs2 @@ -0,0 +1,8 @@ +void script_2524(int arg0) { + if (((boolean)bitconfig_6377)) { + setWidgetSprite(1135, new WidgetPointer(arg0)); + } else { + setWidgetSprite(1134, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/2525.cs2 b/dumps/scripts/2525.cs2 new file mode 100644 index 0000000..4eafcee --- /dev/null +++ b/dumps/scripts/2525.cs2 @@ -0,0 +1,8 @@ +void script_2525(int arg0) { + if (((boolean)bitconfig_6378)) { + setWidgetSprite(1135, new WidgetPointer(arg0)); + } else { + setWidgetSprite(1134, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/2526.cs2 b/dumps/scripts/2526.cs2 new file mode 100644 index 0000000..08d2738 --- /dev/null +++ b/dumps/scripts/2526.cs2 @@ -0,0 +1,8 @@ +void script_2526(int arg0) { + if (((boolean)bitconfig_6379)) { + setWidgetSprite(1135, new WidgetPointer(arg0)); + } else { + setWidgetSprite(1134, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/2527.cs2 b/dumps/scripts/2527.cs2 new file mode 100644 index 0000000..4c60c85 --- /dev/null +++ b/dumps/scripts/2527.cs2 @@ -0,0 +1,13 @@ +void script_2527() { + script_2529(); + script_2531(); + script_2533(); + script_2535(); + script_2537(); + script_2539(); + script_2541(); + script_2543(); + script_2545(); + script_2547(); + return; +} diff --git a/dumps/scripts/2528.cs2 b/dumps/scripts/2528.cs2 new file mode 100644 index 0000000..0a3102d --- /dev/null +++ b/dumps/scripts/2528.cs2 @@ -0,0 +1,4 @@ +void script_2528() { + script_2529(); + return; +} diff --git a/dumps/scripts/2529.cs2 b/dumps/scripts/2529.cs2 new file mode 100644 index 0000000..f6bdd9d --- /dev/null +++ b/dumps/scripts/2529.cs2 @@ -0,0 +1,12 @@ +void script_2529() { + if (((boolean)globalint_908)) { + setWidgetSprite(1949, new WidgetPointer(39,68)); + } else if (globalint_908 == 2) { + setWidgetSprite(1946, new WidgetPointer(39,68)); + } else { + if (globalint_908 == 3) { + setWidgetSprite(1947, new WidgetPointer(39,68)); + } + } + return; +} diff --git a/dumps/scripts/253.cs2 b/dumps/scripts/253.cs2 new file mode 100644 index 0000000..4623ef5 --- /dev/null +++ b/dumps/scripts/253.cs2 @@ -0,0 +1,21 @@ +void script_253() { + setScriptCallOnGlobalConfigChange(260, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 7, "Y", new WidgetPointer(923,0)); + setItemOnWidgetMethod2205(15658, 0, new WidgetPointer(923,80)); + setItemOnWidgetMethod2205(15661, 0, new WidgetPointer(923,81)); + setItemOnWidgetMethod2205(15662, 0, new WidgetPointer(923,82)); + setItemOnWidgetMethod2205(15664, 0, new WidgetPointer(923,83)); + setItemOnWidgetMethod2205(15665, 0, new WidgetPointer(923,84)); + setItemOnWidgetMethod2205(15663, 0, new WidgetPointer(923,85)); + setItemOnWidgetMethod2205(15660, 0, new WidgetPointer(923,86)); + setItemOnWidgetMethod2205(15659, 0, new WidgetPointer(923,87)); + setScriptCallOnGlobalConfigChange(256, 1111, 1113, 1112, 1114, 1115, 1116, 1117, 7, "Y", new WidgetPointer(919,0)); + globalint_1111 = 0; + globalint_1112 = 0; + globalint_1113 = 0; + globalint_1114 = 0; + globalint_1115 = 0; + globalint_1116 = 0; + globalint_1117 = -1; + setWidgetScrollMax(getWidgetActualWidth(new WidgetPointer(919,6)), getWidgetActualHeight(new WidgetPointer(919,6)), new WidgetPointer(919,6)); + return; +} diff --git a/dumps/scripts/2530.cs2 b/dumps/scripts/2530.cs2 new file mode 100644 index 0000000..146e8f2 --- /dev/null +++ b/dumps/scripts/2530.cs2 @@ -0,0 +1,4 @@ +void script_2530() { + script_2531(); + return; +} diff --git a/dumps/scripts/2531.cs2 b/dumps/scripts/2531.cs2 new file mode 100644 index 0000000..356b7b6 --- /dev/null +++ b/dumps/scripts/2531.cs2 @@ -0,0 +1,12 @@ +void script_2531() { + if (((boolean)globalint_909)) { + setWidgetSprite(1949, new WidgetPointer(39,62)); + } else if (globalint_909 == 2) { + setWidgetSprite(1946, new WidgetPointer(39,62)); + } else { + if (globalint_909 == 3) { + setWidgetSprite(1947, new WidgetPointer(39,62)); + } + } + return; +} diff --git a/dumps/scripts/2532.cs2 b/dumps/scripts/2532.cs2 new file mode 100644 index 0000000..1f20eaa --- /dev/null +++ b/dumps/scripts/2532.cs2 @@ -0,0 +1,4 @@ +void script_2532() { + script_2533(); + return; +} diff --git a/dumps/scripts/2533.cs2 b/dumps/scripts/2533.cs2 new file mode 100644 index 0000000..e1235b4 --- /dev/null +++ b/dumps/scripts/2533.cs2 @@ -0,0 +1,12 @@ +void script_2533() { + if (((boolean)globalint_910)) { + setWidgetSprite(1949, new WidgetPointer(39,48)); + } else if (globalint_910 == 2) { + setWidgetSprite(1946, new WidgetPointer(39,48)); + } else { + if (globalint_910 == 3) { + setWidgetSprite(1947, new WidgetPointer(39,48)); + } + } + return; +} diff --git a/dumps/scripts/2534.cs2 b/dumps/scripts/2534.cs2 new file mode 100644 index 0000000..30519e8 --- /dev/null +++ b/dumps/scripts/2534.cs2 @@ -0,0 +1,4 @@ +void script_2534() { + script_2535(); + return; +} diff --git a/dumps/scripts/2535.cs2 b/dumps/scripts/2535.cs2 new file mode 100644 index 0000000..0223d10 --- /dev/null +++ b/dumps/scripts/2535.cs2 @@ -0,0 +1,12 @@ +void script_2535() { + if (((boolean)globalint_911)) { + setWidgetSprite(1949, new WidgetPointer(39,36)); + } else if (globalint_911 == 2) { + setWidgetSprite(1946, new WidgetPointer(39,36)); + } else { + if (globalint_911 == 3) { + setWidgetSprite(1947, new WidgetPointer(39,36)); + } + } + return; +} diff --git a/dumps/scripts/2536.cs2 b/dumps/scripts/2536.cs2 new file mode 100644 index 0000000..84337a6 --- /dev/null +++ b/dumps/scripts/2536.cs2 @@ -0,0 +1,4 @@ +void script_2536() { + script_2537(); + return; +} diff --git a/dumps/scripts/2537.cs2 b/dumps/scripts/2537.cs2 new file mode 100644 index 0000000..437ae05 --- /dev/null +++ b/dumps/scripts/2537.cs2 @@ -0,0 +1,12 @@ +void script_2537() { + if (((boolean)globalint_912)) { + setWidgetSprite(1949, new WidgetPointer(39,42)); + } else if (globalint_912 == 2) { + setWidgetSprite(1946, new WidgetPointer(39,42)); + } else { + if (globalint_912 == 3) { + setWidgetSprite(1947, new WidgetPointer(39,42)); + } + } + return; +} diff --git a/dumps/scripts/2538.cs2 b/dumps/scripts/2538.cs2 new file mode 100644 index 0000000..e432079 --- /dev/null +++ b/dumps/scripts/2538.cs2 @@ -0,0 +1,4 @@ +void script_2538() { + script_2539(); + return; +} diff --git a/dumps/scripts/2539.cs2 b/dumps/scripts/2539.cs2 new file mode 100644 index 0000000..3f37816 --- /dev/null +++ b/dumps/scripts/2539.cs2 @@ -0,0 +1,12 @@ +void script_2539() { + if (((boolean)globalint_913)) { + setWidgetSprite(1949, new WidgetPointer(39,30)); + } else if (globalint_913 == 2) { + setWidgetSprite(1946, new WidgetPointer(39,30)); + } else { + if (globalint_913 == 3) { + setWidgetSprite(1947, new WidgetPointer(39,30)); + } + } + return; +} diff --git a/dumps/scripts/254.cs2 b/dumps/scripts/254.cs2 new file mode 100644 index 0000000..bc26593 --- /dev/null +++ b/dumps/scripts/254.cs2 @@ -0,0 +1,4 @@ +void script_254() { + script_255(); + return; +} diff --git a/dumps/scripts/2540.cs2 b/dumps/scripts/2540.cs2 new file mode 100644 index 0000000..73c9856 --- /dev/null +++ b/dumps/scripts/2540.cs2 @@ -0,0 +1,4 @@ +void script_2540() { + script_2541(); + return; +} diff --git a/dumps/scripts/2541.cs2 b/dumps/scripts/2541.cs2 new file mode 100644 index 0000000..14eb28a --- /dev/null +++ b/dumps/scripts/2541.cs2 @@ -0,0 +1,12 @@ +void script_2541() { + if (((boolean)globalint_914)) { + setWidgetSprite(1949, new WidgetPointer(39,24)); + } else if (globalint_914 == 2) { + setWidgetSprite(1946, new WidgetPointer(39,24)); + } else { + if (globalint_914 == 3) { + setWidgetSprite(1947, new WidgetPointer(39,24)); + } + } + return; +} diff --git a/dumps/scripts/2542.cs2 b/dumps/scripts/2542.cs2 new file mode 100644 index 0000000..970f902 --- /dev/null +++ b/dumps/scripts/2542.cs2 @@ -0,0 +1,4 @@ +void script_2542() { + script_2543(); + return; +} diff --git a/dumps/scripts/2543.cs2 b/dumps/scripts/2543.cs2 new file mode 100644 index 0000000..5400a2e --- /dev/null +++ b/dumps/scripts/2543.cs2 @@ -0,0 +1,12 @@ +void script_2543() { + if (((boolean)globalint_915)) { + setWidgetSprite(1949, new WidgetPointer(39,12)); + } else if (globalint_915 == 2) { + setWidgetSprite(1946, new WidgetPointer(39,12)); + } else { + if (globalint_915 == 3) { + setWidgetSprite(1947, new WidgetPointer(39,12)); + } + } + return; +} diff --git a/dumps/scripts/2544.cs2 b/dumps/scripts/2544.cs2 new file mode 100644 index 0000000..ffacb31 --- /dev/null +++ b/dumps/scripts/2544.cs2 @@ -0,0 +1,4 @@ +void script_2544() { + script_2545(); + return; +} diff --git a/dumps/scripts/2545.cs2 b/dumps/scripts/2545.cs2 new file mode 100644 index 0000000..16ddef1 --- /dev/null +++ b/dumps/scripts/2545.cs2 @@ -0,0 +1,12 @@ +void script_2545() { + if (((boolean)globalint_916)) { + setWidgetSprite(1949, new WidgetPointer(39,18)); + } else if (globalint_916 == 2) { + setWidgetSprite(1946, new WidgetPointer(39,18)); + } else { + if (globalint_916 == 3) { + setWidgetSprite(1947, new WidgetPointer(39,18)); + } + } + return; +} diff --git a/dumps/scripts/2546.cs2 b/dumps/scripts/2546.cs2 new file mode 100644 index 0000000..e24a684 --- /dev/null +++ b/dumps/scripts/2546.cs2 @@ -0,0 +1,4 @@ +void script_2546() { + script_2547(); + return; +} diff --git a/dumps/scripts/2547.cs2 b/dumps/scripts/2547.cs2 new file mode 100644 index 0000000..743cd71 --- /dev/null +++ b/dumps/scripts/2547.cs2 @@ -0,0 +1,12 @@ +void script_2547() { + if (((boolean)globalint_917)) { + setWidgetSprite(1949, new WidgetPointer(39,6)); + } else if (globalint_917 == 2) { + setWidgetSprite(1946, new WidgetPointer(39,6)); + } else { + if (globalint_917 == 3) { + setWidgetSprite(1947, new WidgetPointer(39,6)); + } + } + return; +} diff --git a/dumps/scripts/2548.cs2 b/dumps/scripts/2548.cs2 new file mode 100644 index 0000000..253f7f8 --- /dev/null +++ b/dumps/scripts/2548.cs2 @@ -0,0 +1,14 @@ +void script_2548() { + if (((boolean)globalint_918)) { + setWidgetSprite(1908, new WidgetPointer(39,71)); + } else if (globalint_918 == 2) { + setWidgetSprite(1910, new WidgetPointer(39,71)); + } else if (globalint_918 == 3) { + setWidgetSprite(1911, new WidgetPointer(39,71)); + } else { + if (globalint_918 == 4) { + setWidgetSprite(1909, new WidgetPointer(39,71)); + } + } + return; +} diff --git a/dumps/scripts/2549.cs2 b/dumps/scripts/2549.cs2 new file mode 100644 index 0000000..6eaf3d4 --- /dev/null +++ b/dumps/scripts/2549.cs2 @@ -0,0 +1,14 @@ +void script_2549() { + if (((boolean)globalint_919)) { + setWidgetSprite(1908, new WidgetPointer(39,65)); + } else if (globalint_919 == 2) { + setWidgetSprite(1910, new WidgetPointer(39,65)); + } else if (globalint_919 == 3) { + setWidgetSprite(1911, new WidgetPointer(39,65)); + } else { + if (globalint_919 == 4) { + setWidgetSprite(1909, new WidgetPointer(39,65)); + } + } + return; +} diff --git a/dumps/scripts/255.cs2 b/dumps/scripts/255.cs2 new file mode 100644 index 0000000..637d5a2 --- /dev/null +++ b/dumps/scripts/255.cs2 @@ -0,0 +1,4 @@ +void script_255() { + setScriptCallOnGlobalConfigChange(256, 1111, 1112, 1113, 1114, 1115, 1116, 6, "Y", new WidgetPointer(919,0)); + return; +} diff --git a/dumps/scripts/2550.cs2 b/dumps/scripts/2550.cs2 new file mode 100644 index 0000000..3c90cb1 --- /dev/null +++ b/dumps/scripts/2550.cs2 @@ -0,0 +1,14 @@ +void script_2550() { + if (((boolean)globalint_920)) { + setWidgetSprite(1908, new WidgetPointer(39,51)); + } else if (globalint_920 == 2) { + setWidgetSprite(1910, new WidgetPointer(39,51)); + } else if (globalint_920 == 3) { + setWidgetSprite(1911, new WidgetPointer(39,51)); + } else { + if (globalint_920 == 4) { + setWidgetSprite(1909, new WidgetPointer(39,51)); + } + } + return; +} diff --git a/dumps/scripts/2551.cs2 b/dumps/scripts/2551.cs2 new file mode 100644 index 0000000..1696554 --- /dev/null +++ b/dumps/scripts/2551.cs2 @@ -0,0 +1,14 @@ +void script_2551() { + if (((boolean)globalint_921)) { + setWidgetSprite(1908, new WidgetPointer(39,38)); + } else if (globalint_921 == 2) { + setWidgetSprite(1910, new WidgetPointer(39,38)); + } else if (globalint_921 == 3) { + setWidgetSprite(1911, new WidgetPointer(39,38)); + } else { + if (globalint_921 == 4) { + setWidgetSprite(1909, new WidgetPointer(39,38)); + } + } + return; +} diff --git a/dumps/scripts/2552.cs2 b/dumps/scripts/2552.cs2 new file mode 100644 index 0000000..b397cf9 --- /dev/null +++ b/dumps/scripts/2552.cs2 @@ -0,0 +1,14 @@ +void script_2552() { + if (((boolean)globalint_922)) { + setWidgetSprite(1908, new WidgetPointer(39,45)); + } else if (globalint_922 == 2) { + setWidgetSprite(1910, new WidgetPointer(39,45)); + } else if (globalint_922 == 3) { + setWidgetSprite(1911, new WidgetPointer(39,45)); + } else { + if (globalint_922 == 4) { + setWidgetSprite(1909, new WidgetPointer(39,45)); + } + } + return; +} diff --git a/dumps/scripts/2553.cs2 b/dumps/scripts/2553.cs2 new file mode 100644 index 0000000..7de08e6 --- /dev/null +++ b/dumps/scripts/2553.cs2 @@ -0,0 +1,14 @@ +void script_2553() { + if (((boolean)globalint_923)) { + setWidgetSprite(1908, new WidgetPointer(39,33)); + } else if (globalint_923 == 2) { + setWidgetSprite(1910, new WidgetPointer(39,33)); + } else if (globalint_923 == 3) { + setWidgetSprite(1911, new WidgetPointer(39,33)); + } else { + if (globalint_923 == 4) { + setWidgetSprite(1909, new WidgetPointer(39,33)); + } + } + return; +} diff --git a/dumps/scripts/2554.cs2 b/dumps/scripts/2554.cs2 new file mode 100644 index 0000000..316f21f --- /dev/null +++ b/dumps/scripts/2554.cs2 @@ -0,0 +1,14 @@ +void script_2554() { + if (((boolean)globalint_924)) { + setWidgetSprite(1908, new WidgetPointer(39,27)); + } else if (globalint_924 == 2) { + setWidgetSprite(1910, new WidgetPointer(39,27)); + } else if (globalint_924 == 3) { + setWidgetSprite(1911, new WidgetPointer(39,27)); + } else { + if (globalint_924 == 4) { + setWidgetSprite(1909, new WidgetPointer(39,27)); + } + } + return; +} diff --git a/dumps/scripts/2555.cs2 b/dumps/scripts/2555.cs2 new file mode 100644 index 0000000..8392a13 --- /dev/null +++ b/dumps/scripts/2555.cs2 @@ -0,0 +1,14 @@ +void script_2555() { + if (((boolean)globalint_925)) { + setWidgetSprite(1908, new WidgetPointer(39,15)); + } else if (globalint_925 == 2) { + setWidgetSprite(1910, new WidgetPointer(39,15)); + } else if (globalint_925 == 3) { + setWidgetSprite(1911, new WidgetPointer(39,15)); + } else { + if (globalint_925 == 4) { + setWidgetSprite(1909, new WidgetPointer(39,15)); + } + } + return; +} diff --git a/dumps/scripts/2556.cs2 b/dumps/scripts/2556.cs2 new file mode 100644 index 0000000..5b061dd --- /dev/null +++ b/dumps/scripts/2556.cs2 @@ -0,0 +1,14 @@ +void script_2556() { + if (((boolean)globalint_926)) { + setWidgetSprite(1908, new WidgetPointer(39,21)); + } else if (globalint_926 == 2) { + setWidgetSprite(1910, new WidgetPointer(39,21)); + } else if (globalint_926 == 3) { + setWidgetSprite(1911, new WidgetPointer(39,21)); + } else { + if (globalint_926 == 4) { + setWidgetSprite(1909, new WidgetPointer(39,21)); + } + } + return; +} diff --git a/dumps/scripts/2557.cs2 b/dumps/scripts/2557.cs2 new file mode 100644 index 0000000..65f34c8 --- /dev/null +++ b/dumps/scripts/2557.cs2 @@ -0,0 +1,14 @@ +void script_2557() { + if (((boolean)globalint_927)) { + setWidgetSprite(1908, new WidgetPointer(39,9)); + } else if (globalint_927 == 2) { + setWidgetSprite(1910, new WidgetPointer(39,9)); + } else if (globalint_927 == 3) { + setWidgetSprite(1911, new WidgetPointer(39,9)); + } else { + if (globalint_927 == 4) { + setWidgetSprite(1909, new WidgetPointer(39,9)); + } + } + return; +} diff --git a/dumps/scripts/2558.cs2 b/dumps/scripts/2558.cs2 new file mode 100644 index 0000000..8989d63 --- /dev/null +++ b/dumps/scripts/2558.cs2 @@ -0,0 +1,12 @@ +void script_2558(int arg0) { + if (getWidgetSpriteId(new WidgetPointer(arg0)) == 1946) { + setWidgetSprite(1951, new WidgetPointer(arg0)); + } else if (getWidgetSpriteId(new WidgetPointer(arg0)) == 1947) { + setWidgetSprite(1952, new WidgetPointer(arg0)); + } else { + if (getWidgetSpriteId(new WidgetPointer(arg0)) == 1949) { + setWidgetSprite(1954, new WidgetPointer(arg0)); + } + } + return; +} diff --git a/dumps/scripts/2559.cs2 b/dumps/scripts/2559.cs2 new file mode 100644 index 0000000..4475c8c --- /dev/null +++ b/dumps/scripts/2559.cs2 @@ -0,0 +1,13 @@ +void script_2559(int arg0,int arg1) { + if (getWidgetSpriteId(new WidgetPointer(arg0)) == 1951) { + setWidgetSprite(1946, new WidgetPointer(arg0)); + } else if (getWidgetSpriteId(new WidgetPointer(arg0)) == 1952) { + setWidgetSprite(1947, new WidgetPointer(arg0)); + } else { + if (getWidgetSpriteId(new WidgetPointer(arg0)) == 1954) { + setWidgetSprite(1949, new WidgetPointer(arg0)); + } + } + script_41(arg1); + return; +} diff --git a/dumps/scripts/256.cs2 b/dumps/scripts/256.cs2 new file mode 100644 index 0000000..12e9791 --- /dev/null +++ b/dumps/scripts/256.cs2 @@ -0,0 +1,4 @@ +void script_256() { + script_257(); + return; +} diff --git a/dumps/scripts/2560.cs2 b/dumps/scripts/2560.cs2 new file mode 100644 index 0000000..b7c0260 --- /dev/null +++ b/dumps/scripts/2560.cs2 @@ -0,0 +1,13 @@ +void script_2560() { + setWidgetText(new WidgetPointer(845,10), cs2method_3408(105, 115, 2385, 1)); + setWidgetText(new WidgetPointer(845,14), cs2method_3408(105, 115, 2385, 2)); + setWidgetText(new WidgetPointer(845,18), cs2method_3408(105, 115, 2385, 3)); + setWidgetText(new WidgetPointer(845,22), cs2method_3408(105, 115, 2385, 4)); + setWidgetText(new WidgetPointer(845,26), cs2method_3408(105, 115, 2385, 5)); + setWidgetText(new WidgetPointer(845,9), "x " + intToStr(globalint_828)); + setWidgetText(new WidgetPointer(845,13), "x " + intToStr(globalint_829)); + setWidgetText(new WidgetPointer(845,17), "x " + intToStr(globalint_830)); + setWidgetText(new WidgetPointer(845,21), "x " + intToStr(globalint_831)); + setWidgetText(new WidgetPointer(845,25), "x " + intToStr(globalint_832)); + return; +} diff --git a/dumps/scripts/2561.cs2 b/dumps/scripts/2561.cs2 new file mode 100644 index 0000000..0b6ab95 --- /dev/null +++ b/dumps/scripts/2561.cs2 @@ -0,0 +1,82 @@ +void script_2561() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + ivar0 = 0; + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + if (((boolean)globalint_844)) { + setWidgetSprite(1135, new WidgetPointer(863,27)); + setWidgetSprite(1134, new WidgetPointer(863,28)); + } else { + setWidgetSprite(1134, new WidgetPointer(863,27)); + setWidgetSprite(1135, new WidgetPointer(863,28)); + } + if (((boolean)globalint_844)) { + if (((boolean)globalint_845)) { + setWidgetText(new WidgetPointer(863,57), "Dwarf"); + ivar0 = 175; + ivar1 = 5300; + ivar2 = 60; + } else if (globalint_845 == 2) { + setWidgetText(new WidgetPointer(863,57), "Goblin"); + ivar0 = 175; + ivar1 = 4800; + ivar2 = 110; + } else { + if (globalint_845 == 3) { + setWidgetText(new WidgetPointer(863,57), "Elf"); + ivar0 = 225; + ivar1 = 4800; + ivar2 = 60; + } + } + } else { + if (((boolean)globalint_844)) { + if (((boolean)globalint_845)) { + setWidgetText(new WidgetPointer(863,57), "Dwarf"); + ivar0 = 350; + ivar1 = 10100; + ivar2 = 60; + } else if (globalint_845 == 2) { + setWidgetText(new WidgetPointer(863,57), "Goblin"); + ivar0 = 350; + ivar1 = 9600; + ivar2 = 110; + } else { + if (globalint_845 == 3) { + setWidgetText(new WidgetPointer(863,57), "Elf"); + ivar0 = 400; + ivar1 = 9600; + ivar2 = 60; + } + } + } + } + ivar3 = 100; + setWidgetText(new WidgetPointer(863,15), script_46(ivar3, ",")); + setWidgetText(new WidgetPointer(863,5), intToStr(ivar0)); + setWidgetText(new WidgetPointer(863,7), intToStr(ivar1)); + setWidgetText(new WidgetPointer(863,9), intToStr(ivar2)); + setWidgetText(new WidgetPointer(863,58), cs2method_3408(105, 115, 2386, globalint_845)); + if (((boolean)globalint_845) && ((boolean)globalint_844)) { + setWidgetModel(47798, new WidgetPointer(863,34)); + } else if ((globalint_845 == 2) && ((boolean)globalint_844)) { + setWidgetModel(47794, new WidgetPointer(863,34)); + } else if ((globalint_845 == 3) && ((boolean)globalint_844)) { + setWidgetModel(47792, new WidgetPointer(863,34)); + } else if (((boolean)globalint_845) && ((boolean)globalint_844)) { + setWidgetModel(47786, new WidgetPointer(863,34)); + } else if ((globalint_845 == 2) && ((boolean)globalint_844)) { + setWidgetModel(47787, new WidgetPointer(863,34)); + } else { + if ((globalint_845 == 3) && ((boolean)globalint_844)) { + setWidgetModel(47796, new WidgetPointer(863,34)); + } + } + globalint_839 = bitconfig_6351; + globalint_846 = bitconfig_6380; + return; +} diff --git a/dumps/scripts/2562.cs2 b/dumps/scripts/2562.cs2 new file mode 100644 index 0000000..9331305 --- /dev/null +++ b/dumps/scripts/2562.cs2 @@ -0,0 +1,8 @@ +void script_2562() { + if (globalint_846 < 10) { + globalint_846 = add(globalint_846, 1); + } + setWidgetText(new WidgetPointer(863,30), intToStr(globalint_846)); + script_2565(); + return; +} diff --git a/dumps/scripts/2563.cs2 b/dumps/scripts/2563.cs2 new file mode 100644 index 0000000..019670e --- /dev/null +++ b/dumps/scripts/2563.cs2 @@ -0,0 +1,8 @@ +void script_2563() { + if (globalint_846 > 1) { + globalint_846 = subtract(globalint_846, 1); + } + setWidgetText(new WidgetPointer(863,30), intToStr(globalint_846)); + script_2565(); + return; +} diff --git a/dumps/scripts/2564.cs2 b/dumps/scripts/2564.cs2 new file mode 100644 index 0000000..385f266 --- /dev/null +++ b/dumps/scripts/2564.cs2 @@ -0,0 +1,5 @@ +void script_2564() { + globalint_839 = bitconfig_6351; + script_2565(); + return; +} diff --git a/dumps/scripts/2565.cs2 b/dumps/scripts/2565.cs2 new file mode 100644 index 0000000..25f67db --- /dev/null +++ b/dumps/scripts/2565.cs2 @@ -0,0 +1,9 @@ +void script_2565() { + int ivar0; + ivar0 = 0; + globalint_846 = bitconfig_6380; + setWidgetText(new WidgetPointer(863,30), intToStr(bitconfig_6380)); + ivar0 = subtract(globalint_839, multiply(100, globalint_846)); + setWidgetText(new WidgetPointer(863,14), script_46(ivar0, ",")); + return; +} diff --git a/dumps/scripts/2566.cs2 b/dumps/scripts/2566.cs2 new file mode 100644 index 0000000..35c91da --- /dev/null +++ b/dumps/scripts/2566.cs2 @@ -0,0 +1,20 @@ +void script_2566() { + setWidgetText(new WidgetPointer(843,7), globalstring_182); + setWidgetText(new WidgetPointer(843,8), globalstring_183); + if (((boolean)globalint_945)) { + setWidgetModel(47798, new WidgetPointer(843,18)); + } else if (((boolean)globalint_945)) { + setWidgetModel(47794, new WidgetPointer(843,18)); + } else if (globalint_945 == 2) { + setWidgetModel(47792, new WidgetPointer(843,18)); + } else if (globalint_945 == 3) { + setWidgetModel(47786, new WidgetPointer(843,18)); + } else if (globalint_945 == 4) { + setWidgetModel(47787, new WidgetPointer(843,18)); + } else { + if (globalint_945 == 5) { + setWidgetModel(47796, new WidgetPointer(843,18)); + } + } + return; +} diff --git a/dumps/scripts/2567.cs2 b/dumps/scripts/2567.cs2 new file mode 100644 index 0000000..a10c89e --- /dev/null +++ b/dumps/scripts/2567.cs2 @@ -0,0 +1,44 @@ +void script_2567() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + ivar0 = 0; + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + ivar4 = -1; + ivar5 = 5; + ivar1 = divide(subtract(getWidgetActualWidth(new WidgetPointer(842,17)), multiply(36, ivar5)), subtract(ivar5, 1)); + ivar2 = divide(subtract(getWidgetActualHeight(new WidgetPointer(842,17)), 128), 3); + if (getItemAmtInContainer(93, 15001) > 0) { + ivar4 = 1991; + } else if (getItemAmtInContainer(93, 15002) > 0) { + ivar4 = 1995; + } else if (getItemAmtInContainer(93, 15003) > 0) { + ivar4 = 1998; + } else { + if (getItemAmtInContainer(93, 15004) > 0) { + ivar4 = 1999; + } + } + while (((boolean)ivar3)) { + if (cs2method_3408(105, 79, ivar4, ivar0) != 1511) { + createExtraChild(new WidgetPointer(842,17), 5, ivar0); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(multiply(add(36, ivar1), mod(ivar0, ivar5)), multiply(divide(ivar0, ivar5), add(32, ivar2)), 0, 0); + setItemOnWidgetMethod1200(cs2method_3408(105, 79, ivar4, ivar0), -1); + cs2method1305("" + getItemName(cs2method_3408(105, 79, ivar4, ivar0))); + setWidgetContextMenuOption(1, "Withdraw"); + setWidgetContextMenuOption(2, "Examine"); + setWidgetShadowColor(new Color(51, 51, 51)); + setWidgetBorderThickness(1); + ivar0 = add(ivar0, 1); + } else { + ivar3 = 1; + } + } + return; +} diff --git a/dumps/scripts/2568.cs2 b/dumps/scripts/2568.cs2 new file mode 100644 index 0000000..58dd64f --- /dev/null +++ b/dumps/scripts/2568.cs2 @@ -0,0 +1,129 @@ +void script_2568() { + if (setWidgetRegister(new WidgetPointer(842,17), 0)) { + if (((boolean)globalint_857)) { + cs2method2103(190); + } else { + cs2method2103(0); + } + } + if (setWidgetRegister(new WidgetPointer(842,17), 1)) { + if (((boolean)globalint_858)) { + cs2method2103(190); + } else { + cs2method2103(0); + } + } + if (setWidgetRegister(new WidgetPointer(842,17), 2)) { + if (((boolean)globalint_859)) { + cs2method2103(190); + } else { + cs2method2103(0); + } + } + if (setWidgetRegister(new WidgetPointer(842,17), 3)) { + if (((boolean)globalint_860)) { + cs2method2103(190); + } else { + cs2method2103(0); + } + } + if (setWidgetRegister(new WidgetPointer(842,17), 4)) { + if (((boolean)globalint_861)) { + cs2method2103(190); + } else { + cs2method2103(0); + } + } + if (setWidgetRegister(new WidgetPointer(842,17), 5)) { + if (((boolean)globalint_862)) { + cs2method2103(190); + } else { + cs2method2103(0); + } + } + if (setWidgetRegister(new WidgetPointer(842,17), 6)) { + if (((boolean)globalint_863)) { + cs2method2103(190); + } else { + cs2method2103(0); + } + } + if (setWidgetRegister(new WidgetPointer(842,17), 7)) { + if (((boolean)globalint_864)) { + cs2method2103(190); + } else { + cs2method2103(0); + } + } + if (setWidgetRegister(new WidgetPointer(842,17), 8)) { + if (((boolean)globalint_865)) { + cs2method2103(190); + } else { + cs2method2103(0); + } + } + if (setWidgetRegister(new WidgetPointer(842,17), 9)) { + if (((boolean)globalint_866)) { + cs2method2103(190); + } else { + cs2method2103(0); + } + } + if (setWidgetRegister(new WidgetPointer(842,17), 10)) { + if (((boolean)globalint_867)) { + cs2method2103(190); + } else { + cs2method2103(0); + } + } + if (setWidgetRegister(new WidgetPointer(842,17), 11)) { + if (((boolean)globalint_868)) { + cs2method2103(190); + } else { + cs2method2103(0); + } + } + if (setWidgetRegister(new WidgetPointer(842,17), 12)) { + if (((boolean)globalint_869)) { + cs2method2103(190); + } else { + cs2method2103(0); + } + } + if (setWidgetRegister(new WidgetPointer(842,17), 13)) { + if (((boolean)globalint_870)) { + cs2method2103(190); + } else { + cs2method2103(0); + } + } + if (setWidgetRegister(new WidgetPointer(842,17), 14)) { + if (((boolean)globalint_871)) { + cs2method2103(190); + } else { + cs2method2103(0); + } + } + if (setWidgetRegister(new WidgetPointer(842,17), 15)) { + if (((boolean)globalint_872)) { + cs2method2103(190); + } else { + cs2method2103(0); + } + } + if (setWidgetRegister(new WidgetPointer(842,17), 16)) { + if (((boolean)globalint_873)) { + cs2method2103(190); + } else { + cs2method2103(0); + } + } + if (setWidgetRegister(new WidgetPointer(842,17), 17)) { + if (((boolean)globalint_874)) { + cs2method2103(190); + } else { + cs2method2103(0); + } + } + return; +} diff --git a/dumps/scripts/2569.cs2 b/dumps/scripts/2569.cs2 new file mode 100644 index 0000000..0409a40 --- /dev/null +++ b/dumps/scripts/2569.cs2 @@ -0,0 +1,10 @@ +void script_2569() { + setWidgetIsHidden(true, new WidgetPointer(292,130)); + if (((boolean)getLanguage())) { + setWidgetFont(496, new WidgetPointer(292,124)); + } else { + setWidgetFont(494, new WidgetPointer(292,124)); + } + script_2570(); + return; +} diff --git a/dumps/scripts/257.cs2 b/dumps/scripts/257.cs2 new file mode 100644 index 0000000..34d22b5 --- /dev/null +++ b/dumps/scripts/257.cs2 @@ -0,0 +1,113 @@ +void script_257() { + int ivar0; + int ivar1; + int ivar2; + string svar0; + if ((((((((boolean)globalint_1111) || ((boolean)globalint_1112)) || ((boolean)globalint_1113)) || ((boolean)globalint_1114)) || ((boolean)globalint_1115)) || ((boolean)globalint_1116)) || (globalint_1117 == -1)) { + return; + } + ivar0 = multiply(getExtraChildGap(new WidgetPointer(919,7)), add(18, 4)); + ivar1 = multiply(add(getExtraChildGap(new WidgetPointer(919,7)), 1), add(18, 4)); + setWidgetScrollMax(getWidgetScrollMaxH(new WidgetPointer(919,6)), ivar1, new WidgetPointer(919,6)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(919,8)), ivar1, 0, 0, new WidgetPointer(919,8)); + createExtraChild(new WidgetPointer(919,8), 4, getExtraChildGap(new WidgetPointer(919,8))); + setWidgetRGB(new Color(164, 164, 103)); + setWidgetSize(16384, 18, 2, 0); + setWidgetPosition(0, ivar0, 0, 2); + setWidgetFont(494); + setWidgetText(script_1668(globalint_1111)); + setWidgetTextAlignment(1, 1, 0); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(919,7)), ivar1, 0, 0, new WidgetPointer(919,7)); + createExtraChild(new WidgetPointer(919,7), 4, getExtraChildGap(new WidgetPointer(919,7))); + setWidgetRGB(new Color(164, 164, 103)); + setWidgetSize(16384, 18, 2, 0); + setWidgetPosition(0, ivar0, 0, 2); + setWidgetFont(494); + setWidgetText(script_276(globalint_1113)); + setWidgetTextAlignment(1, 1, 0); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(919,9)), ivar1, 0, 0, new WidgetPointer(919,9)); + createExtraChild(new WidgetPointer(919,9), 4, getExtraChildGap(new WidgetPointer(919,9))); + setWidgetRGB(new Color(164, 164, 103)); + setWidgetSize(16384, 18, 2, 0); + setWidgetPosition(0, ivar0, 0, 2); + setWidgetFont(494); + setWidgetText(intToStr(globalint_1112)); + setWidgetTextAlignment(1, 1, 0); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(919,10)), ivar1, 0, 0, new WidgetPointer(919,10)); + createExtraChild(new WidgetPointer(919,10), 5, getExtraChildGap(new WidgetPointer(919,10))); + setWidgetSize(20, 20, 0, 0); + setWidgetPosition(0, add(ivar0, 2), 1, 2); + svar0 = ""; + ivar2 = -1; + switch (globalint_1114) { + case 1: + ivar2 = 15658; + svar0 = "Worm"; + break; + case 2: + ivar2 = 15659; + svar0 = "Maggot"; + break; + case 3: + ivar2 = 15662; + svar0 = "Cricket"; + break; + case 4: + ivar2 = 15663; + svar0 = "Locust"; + break; + case 5: + ivar2 = 15661; + svar0 = "Crayfish"; + break; + case 6: + ivar2 = 15660; + svar0 = "Shrimp"; + break; + case 7: + ivar2 = 15664; + svar0 = "Green moth"; + break; + case 8: + ivar2 = 15665; + svar0 = "Grey moth"; + } + setItemOnWidgetMethod1205(ivar2, 0); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(919,20), svar0, 25, 128, "IIsii"); + setScriptCallOnMouseExit(40, new WidgetPointer(919,20), "I"); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(919,11)), ivar1, 0, 0, new WidgetPointer(919,11)); + createExtraChild(new WidgetPointer(919,11), 4, getExtraChildGap(new WidgetPointer(919,11))); + setWidgetRGB(new Color(164, 164, 103)); + setWidgetSize(16384, 18, 2, 0); + setWidgetPosition(0, ivar0, 0, 2); + setWidgetFont(494); + setWidgetText(script_278(globalint_1115)); + setWidgetTextAlignment(1, 1, 0); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(919,12)), ivar1, 0, 0, new WidgetPointer(919,12)); + createExtraChild(new WidgetPointer(919,12), 4, getExtraChildGap(new WidgetPointer(919,12))); + setWidgetRGB(new Color(164, 164, 103)); + setWidgetSize(16384, 18, 2, 0); + setWidgetPosition(0, ivar0, 0, 2); + setWidgetFont(494); + setWidgetText(intToStr(globalint_1116)); + setWidgetTextAlignment(1, 1, 0); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(919,13)), ivar1, 0, 0, new WidgetPointer(919,13)); + createExtraChild(new WidgetPointer(919,13), 4, getExtraChildGap(new WidgetPointer(919,13))); + setWidgetRGB(new Color(164, 164, 103)); + setWidgetSize(16384, 18, 2, 0); + setWidgetPosition(0, ivar0, 0, 2); + setWidgetFont(494); + setWidgetText(intToStr(globalint_1117) + "%"); + setWidgetTextAlignment(1, 1, 0); + if (getWidgetActualHeight(new WidgetPointer(919,1)) == 185) { + script_31(60227589, 60227590, 792, 789, 790, 791, 773, 788); + } + globalint_1111 = 0; + globalint_1112 = 0; + globalint_1113 = 0; + globalint_1114 = 0; + globalint_1115 = 0; + globalint_1116 = 0; + globalint_1117 = -1; + return; +} diff --git a/dumps/scripts/2570.cs2 b/dumps/scripts/2570.cs2 new file mode 100644 index 0000000..d1ab5ed --- /dev/null +++ b/dumps/scripts/2570.cs2 @@ -0,0 +1,97 @@ +void script_2570() { + int ivar0; + int ivar1; + int ivar2; + ivar0 = 0; + ivar1 = 0; + ivar2 = -1; + globalint_930 = -1; + globalint_931 = -1; + globalint_932 = -1; + globalint_933 = -1; + globalint_934 = -1; + globalint_935 = -1; + globalint_936 = -1; + globalint_937 = -1; + globalint_938 = -1; + globalint_939 = -1; + if ((bitconfig_6429 > 0) && (bitconfig_6429 < 11)) { + globalint_929 = subtract(bitconfig_6429, 1); + } else { + globalint_929 = 0; + } + while ((ivar1 < 10) && (ivar0 < 28)) { + ivar2 = getItemIdInSlot(93, ivar0); + if (((boolean)getItemHashmapData(ivar2, 802)) || ((boolean)getItemHashmapData(ivar2, 803))) { + setWidgetText(cs2method_3408(105, 73, 2423, ivar1), "Squad " + intToStr(add(ivar1, 1))); + if (((boolean)getItemHashmapData(ivar2, 806))) { + setWidgetSprite(2023, cs2method_3408(105, 73, 2427, ivar1)); + } else { + if (((boolean)getItemHashmapData(ivar2, 806))) { + setWidgetSprite(2022, cs2method_3408(105, 73, 2427, ivar1)); + } + } + if (((boolean)getItemHashmapData(ivar2, 805))) { + setWidgetSprite(2016, cs2method_3408(105, 73, 2426, ivar1)); + } else if (getItemHashmapData(ivar2, 805) == 2) { + setWidgetSprite(2018, cs2method_3408(105, 73, 2426, ivar1)); + } else { + if (getItemHashmapData(ivar2, 805) == 3) { + setWidgetSprite(2017, cs2method_3408(105, 73, 2426, ivar1)); + } + } + if (((boolean)getItemHashmapData(ivar2, 803))) { + setWidgetRGB(new Color(204, 0, 0), cs2method_3408(105, 73, 2429, ivar1)); + } else { + setWidgetRGB(new Color(0, 0, 0), cs2method_3408(105, 73, 2429, ivar1)); + } + switch (ivar1) { + case 0: + globalint_930 = ivar0; + break; + case 1: + globalint_931 = ivar0; + break; + case 2: + globalint_932 = ivar0; + break; + case 3: + globalint_933 = ivar0; + break; + case 4: + globalint_934 = ivar0; + break; + case 5: + globalint_935 = ivar0; + break; + case 6: + globalint_936 = ivar0; + break; + case 7: + globalint_937 = ivar0; + break; + case 8: + globalint_938 = ivar0; + break; + case 9: + globalint_939 = ivar0; + } + ivar1 = add(ivar1, 1); + } + ivar0 = add(ivar0, 1); + } + if ((ivar1 < 10) && (ivar1 < 10)) { + while (true) { + setWidgetText(cs2method_3408(105, 73, 2423, ivar1), "No squad"); + setWidgetText(cs2method_3408(105, 73, 2424, ivar1), ""); + setWidgetSprite(-1, cs2method_3408(105, 73, 2427, ivar1)); + setWidgetSprite(-1, cs2method_3408(105, 73, 2426, ivar1)); + setScriptCallOnClickContextMenu(-1, "", cs2method_3408(105, 73, 2422, ivar1)); + setWidgetNoOptions(cs2method_3408(105, 73, 2422, ivar1)); + ivar1 = add(ivar1, 1); + } + } + script_2599(); + script_2573(); + return; +} diff --git a/dumps/scripts/2571.cs2 b/dumps/scripts/2571.cs2 new file mode 100644 index 0000000..bf6b73c --- /dev/null +++ b/dumps/scripts/2571.cs2 @@ -0,0 +1,8 @@ +void script_2571(int arg0) { + if (add(getContainerIntNodeCountIgnoreStacks(93, 803), getContainerIntNodeCountIgnoreStacks(93, 802)) < add(1, arg0)) { + return; + } + globalint_929 = arg0; + script_2573(); + return; +} diff --git a/dumps/scripts/2572.cs2 b/dumps/scripts/2572.cs2 new file mode 100644 index 0000000..8b6c852 --- /dev/null +++ b/dumps/scripts/2572.cs2 @@ -0,0 +1,12 @@ +void script_2572() { + if (add(getContainerIntNodeCountIgnoreStacks(93, 803), getContainerIntNodeCountIgnoreStacks(93, 802)) < bitconfig_6429) { + return; + } + if ((bitconfig_6429 > 0) && (bitconfig_6429 < 11)) { + globalint_929 = subtract(bitconfig_6429, 1); + } else { + globalint_929 = 0; + } + script_2573(); + return; +} diff --git a/dumps/scripts/2573.cs2 b/dumps/scripts/2573.cs2 new file mode 100644 index 0000000..dadc610 --- /dev/null +++ b/dumps/scripts/2573.cs2 @@ -0,0 +1,58 @@ +void script_2573() { + int ivar0; + ivar0 = -1; + switch (globalint_929) { + case 0: + ivar0 = getItemIdInSlot(93, globalint_930); + break; + case 1: + ivar0 = getItemIdInSlot(93, globalint_931); + break; + case 2: + ivar0 = getItemIdInSlot(93, globalint_932); + break; + case 3: + ivar0 = getItemIdInSlot(93, globalint_933); + break; + case 4: + ivar0 = getItemIdInSlot(93, globalint_934); + break; + case 5: + ivar0 = getItemIdInSlot(93, globalint_935); + break; + case 6: + ivar0 = getItemIdInSlot(93, globalint_936); + break; + case 7: + ivar0 = getItemIdInSlot(93, globalint_937); + break; + case 8: + ivar0 = getItemIdInSlot(93, globalint_938); + break; + case 9: + ivar0 = getItemIdInSlot(93, globalint_939); + } + if ((ivar0 == -1) || ((getItemHashmapData(ivar0, 802) != 1) && (getItemHashmapData(ivar0, 803) != 1))) { + return; + } + script_2575(); + setWidgetText(new WidgetPointer(292,99), getItemName(ivar0)); + setItemOnWidgetMethod2200(ivar0, -1, new WidgetPointer(292,112)); + if (((boolean)getItemHashmapData(ivar0, 802))) { + script_2578(); + script_2584(); + script_2585(); + script_2588(); + script_2591(); + } else { + if (((boolean)getItemHashmapData(ivar0, 803))) { + script_2590(); + script_2587(); + script_2579(); + script_2580(); + script_2583(); + script_2597(); + } + } + return; +} diff --git a/dumps/scripts/2574.cs2 b/dumps/scripts/2574.cs2 new file mode 100644 index 0000000..03ad256 --- /dev/null +++ b/dumps/scripts/2574.cs2 @@ -0,0 +1,41 @@ +void script_2574() { + int ivar0; + int ivar1; + int ivar2; + ivar0 = 0; + ivar1 = 0; + ivar2 = multiplyDivide(bitconfig_6457, 1000, 100); + if (ivar2 < 1) { + ivar2 = 1; + } + if (ivar2 > 100) { + ivar2 = 100; + } + ivar0 = cs2method_3408(105, 105, 197, ivar2); + ivar1 = cs2method_3408(105, 105, 198, ivar2); + if (((boolean)bitconfig_5095)) { + setWidgetPosition(481, ivar0, 0, 0, new WidgetPointer(781,46)); + setWidgetSize(16, ivar1, 0, 0, new WidgetPointer(781,46)); + } else { + if (bitconfig_5095 == 2) { + setWidgetPosition(481, ivar0, 0, 0, new WidgetPointer(781,37)); + setWidgetSize(16, ivar1, 0, 0, new WidgetPointer(781,37)); + } + } + if (ivar2 < 25) { + if (((boolean)bitconfig_5095)) { + setWidgetRGB(new Color(255, 153, 0), new WidgetPointer(781,46)); + } else { + if (bitconfig_5095 == 2) { + setWidgetRGB(new Color(255, 153, 0), new WidgetPointer(781,37)); + } + } + } else if (((boolean)bitconfig_5095)) { + setWidgetRGB(new Color(102, 102, 0), new WidgetPointer(781,46)); + } else { + if (bitconfig_5095 == 2) { + setWidgetRGB(new Color(40, 70, 5), new WidgetPointer(781,37)); + } + } + return; +} diff --git a/dumps/scripts/2575.cs2 b/dumps/scripts/2575.cs2 new file mode 100644 index 0000000..0ff0cea --- /dev/null +++ b/dumps/scripts/2575.cs2 @@ -0,0 +1,10 @@ +void script_2575() { + int ivar0; + ivar0 = 0; + while (ivar0 < getCommonDefinitionSize(2428)) { + setWidgetRGB(new Color(102, 102, 102), cs2method_3408(105, 73, 2428, ivar0)); + ivar0 = add(ivar0, 1); + } + setWidgetRGB(new Color(255, 0, 51), cs2method_3408(105, 73, 2428, globalint_929)); + return; +} diff --git a/dumps/scripts/2576.cs2 b/dumps/scripts/2576.cs2 new file mode 100644 index 0000000..2139b09 --- /dev/null +++ b/dumps/scripts/2576.cs2 @@ -0,0 +1,26 @@ +void script_2576(int arg0,int arg1) { + string svar0; + svar0 = ""; + switch (arg0) { + case 51183658: + case 51183649: + svar0 = "How much time is left for this round."; + break; + case 51183659: + case 51183650: + svar0 = "How many orbs the green team have captured this round."; + break; + case 51183660: + case 51183651: + svar0 = "How many orbs the yellow team have captured this round."; + break; + case 51183662: + case 51183653: + svar0 = "How active you have been during this round."; + break; + default: + return; + } + script_39(arg0, arg1, 25, getWidgetActualWidth(new WidgetPointer(getWidgetParentId(new WidgetPointer(arg1)))), svar0); + return; +} diff --git a/dumps/scripts/2577.cs2 b/dumps/scripts/2577.cs2 new file mode 100644 index 0000000..92c0662 --- /dev/null +++ b/dumps/scripts/2577.cs2 @@ -0,0 +1,10 @@ +void script_2577(int arg0,int arg1,int arg2) { + if (getItemAmtInContainer(93, 995) < arg1) { + setWidgetRGB(new Color(204, 0, 0), new WidgetPointer(arg0)); + } else if (getSkillActualLvl(22) < arg2) { + setWidgetRGB(new Color(204, 204, 0), new WidgetPointer(arg0)); + } else { + setWidgetRGB(new Color(0, 204, 0), new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/2578.cs2 b/dumps/scripts/2578.cs2 new file mode 100644 index 0000000..ed77c09 --- /dev/null +++ b/dumps/scripts/2578.cs2 @@ -0,0 +1,8 @@ +void script_2578() { + setWidgetRGB(new Color(102, 102, 102), new WidgetPointer(292,114)); + setWidgetSprite(941, new WidgetPointer(292,113)); + setWidgetNoOptions(new WidgetPointer(292,113)); + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(292,113)); + setScriptCallOnMousePressed(2606, new WidgetPointer(-32768,3), "I", new WidgetPointer(292,113)); + return; +} diff --git a/dumps/scripts/2579.cs2 b/dumps/scripts/2579.cs2 new file mode 100644 index 0000000..1f82fcb --- /dev/null +++ b/dumps/scripts/2579.cs2 @@ -0,0 +1,10 @@ +void script_2579() { + setWidgetRGB(new Color(102, 102, 102), new WidgetPointer(292,117)); + setWidgetNoOptions(new WidgetPointer(292,102)); + setWidgetNoOptions(new WidgetPointer(292,104)); + setWidgetNoOptions(new WidgetPointer(292,103)); + setScriptCallOnMousePressed(2606, new WidgetPointer(-32768,3), "I", new WidgetPointer(292,102)); + setScriptCallOnMousePressed(2606, new WidgetPointer(-32768,3), "I", new WidgetPointer(292,104)); + setScriptCallOnMousePressed(2606, new WidgetPointer(-32768,3), "I", new WidgetPointer(292,103)); + return; +} diff --git a/dumps/scripts/258.cs2 b/dumps/scripts/258.cs2 new file mode 100644 index 0000000..caf7ee9 --- /dev/null +++ b/dumps/scripts/258.cs2 @@ -0,0 +1,4 @@ +void script_258(int arg0,int arg1) { + cs2method2103(arg1, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/2580.cs2 b/dumps/scripts/2580.cs2 new file mode 100644 index 0000000..c50fbe5 --- /dev/null +++ b/dumps/scripts/2580.cs2 @@ -0,0 +1,8 @@ +void script_2580() { + setWidgetRGB(new Color(102, 102, 102), new WidgetPointer(292,116)); + setWidgetNoOptions(new WidgetPointer(292,110)); + setWidgetNoOptions(new WidgetPointer(292,111)); + setScriptCallOnMousePressed(2606, new WidgetPointer(-32768,3), "I", new WidgetPointer(292,110)); + setScriptCallOnMousePressed(2606, new WidgetPointer(-32768,3), "I", new WidgetPointer(292,111)); + return; +} diff --git a/dumps/scripts/2581.cs2 b/dumps/scripts/2581.cs2 new file mode 100644 index 0000000..b0a6564 --- /dev/null +++ b/dumps/scripts/2581.cs2 @@ -0,0 +1,50 @@ +int script_2581(int arg0) { + switch (arg0) { + case 830: + if (cs2method6102() || (cs2method6131() != 0)) { + return script_42(((int)cs2method6103())); + } + return -1; + case 831: + return script_42(((int)cs2method6105())); + case 833: + return cs2method6129(); + case 834: + return script_42(((int)cs2method6108())); + case 836: + return script_42(((int)cs2method6110())); + case 837: + return cs2method6111(); + case 838: + return script_42(((int)cs2method6112())); + case 839: + return script_42(((int)cs2method6114())); + case 840: + return script_42(((int)cs2method6115())); + case 841: + return cs2method6116(); + case 842: + return cs2method6123(); + case 843: + return script_42(((int)cs2method6130())); + case 844: + if (cs2method6133()) { + return script_42(globalint_987); + } + return -1; + case 845: + return globalint_178; + case 908: + return cs2method6135(); + case 963: + return script_42(((int)cs2method6136())); + case 1009: + return cs2method6139(); + case 2430: + if (cs2method7215()) { + return cs2method6149(); + } + return -1; + } + return -1; +} diff --git a/dumps/scripts/2582.cs2 b/dumps/scripts/2582.cs2 new file mode 100644 index 0000000..a6d1665 --- /dev/null +++ b/dumps/scripts/2582.cs2 @@ -0,0 +1,116 @@ +int script_2582(int arg0,int arg1,int arg2) { + int stack_dump0; + opcStruct5303(2,0,0) structdump_1; + switch (arg0) { + case 830: + cs2method6003(((boolean)script_734(arg1))); + break; + case 831: + cs2method6005(((boolean)script_734(arg1))); + break; + case 833: + cs2method6029(((boolean)arg1)); + break; + case 834: + cs2method6008(((boolean)script_734(arg1))); + break; + case 836: + cs2method6010(((boolean)script_734(arg1))); + break; + case 837: + if ((arg1 > 0) && cs2method6136()) { + cs2method6034(true); + } + cs2method6011(arg1); + break; + case 838: + cs2method6012(((boolean)script_734(arg1))); + break; + case 839: + cs2method6014(((boolean)script_734(arg1))); + break; + case 840: + if (((boolean)arg1) && (((boolean)cs2method6131()) || (cs2method6131() == 2))) { + cs2method6014(false); + cs2method6015(false); + } else { + if (cs2method6130()) { + cs2method6030(true); + } + cs2method6015(((boolean)script_734(arg1))); + } + break; + case 841: + cs2method6016(arg1); + if (((arg1 > 0) && (cs2method6131() != 0)) && (cs2method6131() != 2)) { + script_2700(4, arg2, 0, 1); + return 2; + } + cs2method6024(arg1); + break; + case 842: + if (cs2method7206() || ((boolean)cs2method7306(arg1))) { + return 0; + } + cs2method6023(arg1); + return 1; + case 843: + if (((boolean)arg1) && (((boolean)cs2method6131()) || (cs2method6131() == 2))) { + cs2method6014(false); + cs2method6015(false); + cs2method6034(false); + cs2method6030(false); + } else { + cs2method6030(((boolean)script_734(arg1))); + } + break; + case 844: + globalint_987 = script_734(arg1); + cs2method6028(((boolean)globalint_987)); + break; + case 845: + globalint_178 = arg1; + if (getDisplayMode() == 3) { + stack_dump0 = arg1; + structdump_1 = cs2method5303(stack_dump0); + if (cs2method5300(structdump_1.intpart_0, structdump_1.intpart_1)) { + script_2700(2, arg2, 0, 0); + return 2; + } + return 0; + } + break; + case 908: + cs2method6033(arg1); + break; + case 963: + if (((boolean)arg1)) { + cs2method6011(0); + } else { + if (cs2method6130()) { + cs2method6030(true); + } + } + cs2method6034(((boolean)script_734(arg1))); + break; + case 1009: + if (cs2method7211() && ((boolean)cs2method7311(arg1))) { + cs2method6036(arg1); + return 1; + } + return 0; + case 2430: + if (cs2method7215()) { + if (cs2method7315(arg1) == 3) { + return 0; + } + cs2method6041(arg1); + } else { + return 0; + } + break; + default: + return 0; + } + return 1; +} diff --git a/dumps/scripts/2583.cs2 b/dumps/scripts/2583.cs2 new file mode 100644 index 0000000..b5e23c2 --- /dev/null +++ b/dumps/scripts/2583.cs2 @@ -0,0 +1,7 @@ +void script_2583() { + setWidgetRGB(new Color(255, 153, 53), new WidgetPointer(292,114)); + setWidgetContextMenuOption(1, new WidgetPointer(292,113), "Resupply"); + setScriptCallOnClickContextMenu(2592, new WidgetPointer(-32768,3), "I", new WidgetPointer(292,113)); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(292,113)); + return; +} diff --git a/dumps/scripts/2584.cs2 b/dumps/scripts/2584.cs2 new file mode 100644 index 0000000..239d176 --- /dev/null +++ b/dumps/scripts/2584.cs2 @@ -0,0 +1,13 @@ +void script_2584() { + setWidgetRGB(new Color(255, 153, 53), new WidgetPointer(292,117)); + setWidgetContextMenuOption(1, new WidgetPointer(292,102), "Select dwarf"); + setWidgetContextMenuOption(1, new WidgetPointer(292,104), "Select goblin"); + setWidgetContextMenuOption(1, new WidgetPointer(292,103), "Select elf"); + setScriptCallOnClickContextMenu(2586, new WidgetPointer(-32768,3), "I", new WidgetPointer(292,102)); + setScriptCallOnClickContextMenu(2586, new WidgetPointer(-32768,3), "I", new WidgetPointer(292,104)); + setScriptCallOnClickContextMenu(2586, new WidgetPointer(-32768,3), "I", new WidgetPointer(292,103)); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(292,102)); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(292,104)); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(292,103)); + return; +} diff --git a/dumps/scripts/2585.cs2 b/dumps/scripts/2585.cs2 new file mode 100644 index 0000000..8e09d21 --- /dev/null +++ b/dumps/scripts/2585.cs2 @@ -0,0 +1,10 @@ +void script_2585() { + setWidgetRGB(new Color(255, 153, 53), new WidgetPointer(292,116)); + setWidgetContextMenuOption(1, new WidgetPointer(292,110), "Select light"); + setWidgetContextMenuOption(1, new WidgetPointer(292,111), "Select heavy"); + setScriptCallOnClickContextMenu(2589, new WidgetPointer(-32768,3), "I", new WidgetPointer(292,110)); + setScriptCallOnClickContextMenu(2589, new WidgetPointer(-32768,3), "I", new WidgetPointer(292,111)); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(292,110)); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(292,111)); + return; +} diff --git a/dumps/scripts/2586.cs2 b/dumps/scripts/2586.cs2 new file mode 100644 index 0000000..0ca1d5e --- /dev/null +++ b/dumps/scripts/2586.cs2 @@ -0,0 +1,5 @@ +void script_2586(int arg0) { + script_2587(); + setWidgetSprite(1135, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/2587.cs2 b/dumps/scripts/2587.cs2 new file mode 100644 index 0000000..2304749 --- /dev/null +++ b/dumps/scripts/2587.cs2 @@ -0,0 +1,6 @@ +void script_2587() { + setWidgetSprite(1134, new WidgetPointer(292,102)); + setWidgetSprite(1134, new WidgetPointer(292,104)); + setWidgetSprite(1134, new WidgetPointer(292,103)); + return; +} diff --git a/dumps/scripts/2588.cs2 b/dumps/scripts/2588.cs2 new file mode 100644 index 0000000..3024cbd --- /dev/null +++ b/dumps/scripts/2588.cs2 @@ -0,0 +1,103 @@ +void script_2588() { + int ivar0; + int ivar1; + script_2587(); + ivar0 = -1; + switch (globalint_929) { + case 0: + ivar0 = getItemIdInSlot(93, globalint_930); + break; + case 1: + ivar0 = getItemIdInSlot(93, globalint_931); + break; + case 2: + ivar0 = getItemIdInSlot(93, globalint_932); + break; + case 3: + ivar0 = getItemIdInSlot(93, globalint_933); + break; + case 4: + ivar0 = getItemIdInSlot(93, globalint_934); + break; + case 5: + ivar0 = getItemIdInSlot(93, globalint_935); + break; + case 6: + ivar0 = getItemIdInSlot(93, globalint_936); + break; + case 7: + ivar0 = getItemIdInSlot(93, globalint_937); + break; + case 8: + ivar0 = getItemIdInSlot(93, globalint_938); + break; + case 9: + ivar0 = getItemIdInSlot(93, globalint_939); + } + if (ivar0 == -1) { + return; + } + ivar1 = getItemHashmapData(ivar0, 805); + switch (globalint_929) { + case 0: + if ((bitconfig_6385 != 0) && (bitconfig_6385 != ivar1)) { + ivar1 = bitconfig_6385; + } + break; + case 1: + if ((bitconfig_6386 != 0) && (bitconfig_6386 != ivar1)) { + ivar1 = bitconfig_6386; + } + break; + case 2: + if ((bitconfig_6387 != 0) && (bitconfig_6387 != ivar1)) { + ivar1 = bitconfig_6387; + } + break; + case 3: + if ((bitconfig_6388 != 0) && (bitconfig_6388 != ivar1)) { + ivar1 = bitconfig_6388; + } + break; + case 4: + if ((bitconfig_6389 != 0) && (bitconfig_6389 != ivar1)) { + ivar1 = bitconfig_6389; + } + break; + case 5: + if ((bitconfig_6390 != 0) && (bitconfig_6390 != ivar1)) { + ivar1 = bitconfig_6390; + } + break; + case 6: + if ((bitconfig_6391 != 0) && (bitconfig_6391 != ivar1)) { + ivar1 = bitconfig_6391; + } + break; + case 7: + if ((bitconfig_6392 != 0) && (bitconfig_6392 != ivar1)) { + ivar1 = bitconfig_6392; + } + break; + case 8: + if ((bitconfig_6393 != 0) && (bitconfig_6393 != ivar1)) { + ivar1 = bitconfig_6393; + } + break; + case 9: + if ((bitconfig_6394 != 0) && (bitconfig_6394 != ivar1)) { + ivar1 = bitconfig_6394; + } + } + switch (ivar1) { + case 1: + setWidgetSprite(1135, new WidgetPointer(292,102)); + break; + case 2: + setWidgetSprite(1135, new WidgetPointer(292,104)); + break; + case 3: + setWidgetSprite(1135, new WidgetPointer(292,103)); + } + return; +} diff --git a/dumps/scripts/2589.cs2 b/dumps/scripts/2589.cs2 new file mode 100644 index 0000000..2b45baa --- /dev/null +++ b/dumps/scripts/2589.cs2 @@ -0,0 +1,5 @@ +void script_2589(int arg0) { + script_2590(); + setWidgetSprite(1135, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/259.cs2 b/dumps/scripts/259.cs2 new file mode 100644 index 0000000..e8f3095 --- /dev/null +++ b/dumps/scripts/259.cs2 @@ -0,0 +1,5 @@ +void script_259(int arg0) { + cs2method2103(255, new WidgetPointer(arg0)); + script_41(60489816); + return; +} diff --git a/dumps/scripts/2590.cs2 b/dumps/scripts/2590.cs2 new file mode 100644 index 0000000..df624cd --- /dev/null +++ b/dumps/scripts/2590.cs2 @@ -0,0 +1,5 @@ +void script_2590() { + setWidgetSprite(1134, new WidgetPointer(292,110)); + setWidgetSprite(1134, new WidgetPointer(292,111)); + return; +} diff --git a/dumps/scripts/2591.cs2 b/dumps/scripts/2591.cs2 new file mode 100644 index 0000000..ff3fa3d --- /dev/null +++ b/dumps/scripts/2591.cs2 @@ -0,0 +1,140 @@ +void script_2591() { + int ivar0; + int ivar1; + script_2590(); + ivar0 = -1; + switch (globalint_929) { + case 0: + ivar0 = getItemIdInSlot(93, globalint_930); + break; + case 1: + ivar0 = getItemIdInSlot(93, globalint_931); + break; + case 2: + ivar0 = getItemIdInSlot(93, globalint_932); + break; + case 3: + ivar0 = getItemIdInSlot(93, globalint_933); + break; + case 4: + ivar0 = getItemIdInSlot(93, globalint_934); + break; + case 5: + ivar0 = getItemIdInSlot(93, globalint_935); + break; + case 6: + ivar0 = getItemIdInSlot(93, globalint_936); + break; + case 7: + ivar0 = getItemIdInSlot(93, globalint_937); + break; + case 8: + ivar0 = getItemIdInSlot(93, globalint_938); + break; + case 9: + ivar0 = getItemIdInSlot(93, globalint_939); + } + if (ivar0 == -1) { + return; + } + ivar1 = getItemHashmapData(ivar0, 806); + switch (globalint_929) { + case 0: + if (((boolean)bitconfig_6415)) { + if (((boolean)ivar1)) { + ivar1 = 1; + } else { + ivar1 = 0; + } + } + break; + case 1: + if (((boolean)bitconfig_6416)) { + if (((boolean)ivar1)) { + ivar1 = 1; + } else { + ivar1 = 0; + } + } + break; + case 2: + if (((boolean)bitconfig_6417)) { + if (((boolean)ivar1)) { + ivar1 = 1; + } else { + ivar1 = 0; + } + } + break; + case 3: + if (((boolean)bitconfig_6418)) { + if (((boolean)ivar1)) { + ivar1 = 1; + } else { + ivar1 = 0; + } + } + break; + case 4: + if (((boolean)bitconfig_6419)) { + if (((boolean)ivar1)) { + ivar1 = 1; + } else { + ivar1 = 0; + } + } + break; + case 5: + if (((boolean)bitconfig_6420)) { + if (((boolean)ivar1)) { + ivar1 = 1; + } else { + ivar1 = 0; + } + } + break; + case 6: + if (((boolean)bitconfig_6421)) { + if (((boolean)ivar1)) { + ivar1 = 1; + } else { + ivar1 = 0; + } + } + break; + case 7: + if (((boolean)bitconfig_6422)) { + if (((boolean)ivar1)) { + ivar1 = 1; + } else { + ivar1 = 0; + } + } + break; + case 8: + if (((boolean)bitconfig_6423)) { + if (((boolean)ivar1)) { + ivar1 = 1; + } else { + ivar1 = 0; + } + } + break; + case 9: + if (((boolean)bitconfig_6424)) { + if (((boolean)ivar1)) { + ivar1 = 1; + } else { + ivar1 = 0; + } + } + } + switch (ivar1) { + case 0: + setWidgetSprite(1135, new WidgetPointer(292,110)); + break; + case 1: + setWidgetSprite(1135, new WidgetPointer(292,111)); + } + return; +} diff --git a/dumps/scripts/2592.cs2 b/dumps/scripts/2592.cs2 new file mode 100644 index 0000000..6b3137f --- /dev/null +++ b/dumps/scripts/2592.cs2 @@ -0,0 +1,9 @@ +void script_2592(int arg0) { + playSoundEffect(6784, 1, 0); + if (getWidgetSpriteId(new WidgetPointer(arg0)) == 941) { + setWidgetSprite(942, new WidgetPointer(arg0)); + } else { + setWidgetSprite(941, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/2593.cs2 b/dumps/scripts/2593.cs2 new file mode 100644 index 0000000..056e4e8 --- /dev/null +++ b/dumps/scripts/2593.cs2 @@ -0,0 +1,17 @@ +void script_2593(int arg0) { + if (((boolean)arg0) || (arg0 == 2)) { + if (cs2method6130()) { + cs2method6014(false); + cs2method6015(false); + cs2method6034(false); + } else { + if (cs2method6115()) { + cs2method6014(false); + } + } + } + if ((arg0 == 2) && cs2method6136()) { + cs2method6011(0); + } + return; +} diff --git a/dumps/scripts/2594.cs2 b/dumps/scripts/2594.cs2 new file mode 100644 index 0000000..bda8ab8 --- /dev/null +++ b/dumps/scripts/2594.cs2 @@ -0,0 +1,4 @@ +void script_2594() { + script_2595(1); + return; +} diff --git a/dumps/scripts/2595.cs2 b/dumps/scripts/2595.cs2 new file mode 100644 index 0000000..06cde6a --- /dev/null +++ b/dumps/scripts/2595.cs2 @@ -0,0 +1,14 @@ +void script_2595(int arg0) { + int ivar1; + int stack_dump0; + int stack_dump1; + int stack_dump2; + cs2func_script_2692_struct(2,0,0) structdump_3; + ivar1 = cs2method6131(); + stack_dump0 = ivar1; + stack_dump1 = getDisplayMode(); + stack_dump2 = ivar1; + structdump_3 = script_2692(stack_dump2); + script_2596(stack_dump0, stack_dump1, structdump_3.intpart_0, structdump_3.intpart_1, arg0); + return; +} diff --git a/dumps/scripts/2596.cs2 b/dumps/scripts/2596.cs2 new file mode 100644 index 0000000..446e74b --- /dev/null +++ b/dumps/scripts/2596.cs2 @@ -0,0 +1,109 @@ +void script_2596(int arg0,int arg1,int arg2,int arg3,int arg4) { + int ivar5; + int ivar6; + int ivar7; + int ivar8; + ivar5 = -1; + ivar6 = -1; + switch (arg4) { + case 1: + setWidgetText(new WidgetPointer(742,19), "Graphics Options"); + openInterface(48627718, 978); + ivar5 = 48627716; + ivar6 = 48627732; + setWidgetSize(0, 0, 1, 1, new WidgetPointer(978,5)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(742,4)), 304, 0, 0, new WidgetPointer(742,4)); + setScriptCallOnMousePressed(29, "", new WidgetPointer(742,18)); + setWidgetContextMenuOption(1, new WidgetPointer(742,18), "Close"); + break; + case 0: + openInterface(57802780, 978); + setWidgetSprite(4129, new WidgetPointer(882,11)); + setWidgetSprite(4129, new WidgetPointer(882,12)); + setWidgetSprite(4129, new WidgetPointer(882,14)); + ivar5 = 57802756; + ivar6 = 57802757; + script_1217(57802808, 57802809); + script_1216(57802801, 57802802); + script_1218(57802815, 57802816); + script_1220(57802834, 57802832); + setWidgetPosition(0, 5, 1, 0, new WidgetPointer(978,0)); + setWidgetPosition(0, 5, 1, 0, new WidgetPointer(978,5)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(882,28)), add(add(add(add(getWidgetActualY(new WidgetPointer(978,0)), getWidgetActualY(new WidgetPointer(978,8))), getWidgetActualHeight(new WidgetPointer(978,0))), 5), getWidgetActualHeight(new WidgetPointer(882,29))), 0, 0, new WidgetPointer(882,28)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(882,28)), getWidgetActualHeight(new WidgetPointer(882,28)), 0, 0, new WidgetPointer(882,22)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(882,8)), add(getWidgetActualHeight(new WidgetPointer(882,22)), 47), 0, 0, new WidgetPointer(882,8)); + setWidgetPosition(0, add(getWidgetActualY(new WidgetPointer(882,8)), 33), 1, 0, new WidgetPointer(882,22)); + setWidgetPosition(0, 0, 1, 1, new WidgetPointer(882,28)); + setWidgetPosition(0, 100, 1, 1, new WidgetPointer(882,29)); + setWidgetPosition(0, -5, 1, 1, new WidgetPointer(978,2)); + setWidgetIsHidden(false, new WidgetPointer(882,29)); + setWidgetIsHidden(true, new WidgetPointer(882,23)); + script_2918(0); + setScriptCallOnWidgetResize(2917, 0, "1", new WidgetPointer(882,4)); + setScriptCallOnWidgetResize(2919, 0, arg4, "1i", new WidgetPointer(744,50)); + break; + case 2: + openInterface(59703298, 978); + ivar5 = 59703296; + ivar6 = 59703355; + setWidgetPosition(0, 5, 1, 0, new WidgetPointer(978,0)); + setWidgetPosition(0, 0, 1, 0, new WidgetPointer(978,5)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(911,2)), add(add(add(add(getWidgetActualY(new WidgetPointer(978,0)), getWidgetActualY(new WidgetPointer(978,8))), getWidgetActualHeight(new WidgetPointer(978,0))), 5), getWidgetActualHeight(new WidgetPointer(911,5))), 0, 0, new WidgetPointer(911,2)); + setWidgetIsHidden(false, new WidgetPointer(911,5)); + setWidgetIsHidden(true, new WidgetPointer(911,3)); + setScriptCallOnWidgetResize(2919, 0, arg4, "1i", new WidgetPointer(906,23)); + script_4041(); + } + setScriptCallOnMousePressed(3383, arg4, "i", new WidgetPointer(978,1)); + script_1149(1, arg1, 64094220, 64094229, 64094230, arg2, arg3, arg0, arg4); + script_1149(2, arg1, 64094221, 64094227, 64094228, arg2, arg3, arg0, arg4); + script_1149(3, arg1, 64094222, 64094225, 64094226, arg2, arg3, arg0, arg4); + setWidgetIsHidden(true, new WidgetPointer(ivar6)); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(ivar5)); + if (globalint_178 < 0) { + globalint_178 = max(cs2method5305(), 0); + } + if (globalint_178 >= cs2method5302()) { + globalint_178 = 0; + } + ivar7 = 64094224; + deleteAllExtraChilds(new WidgetPointer(ivar7)); + createExtraChild(new WidgetPointer(ivar7), 3, getExtraChildGap(new WidgetPointer(ivar7))); + setWidgetSize(0, 0, 1, 1); + setWidgetPosition(0, 0, 1, 1); + setWidgetFilled(1); + setWidgetRGB(new Color(46, 43, 38)); + createExtraChild(new WidgetPointer(ivar7), 3, getExtraChildGap(new WidgetPointer(ivar7))); + setWidgetSize(0, 0, 1, 1); + setWidgetPosition(0, 0, 1, 0); + setWidgetFilled(0); + setWidgetRGB(new Color(95, 91, 82)); + ivar8 = getWidgetCustomChildArrayIndex(); + createExtraChild(new WidgetPointer(ivar7), 4, getExtraChildGap(new WidgetPointer(ivar7))); + setWidgetFont(494); + setWidgetTextAlignment(1, 1, 0); + if (cs2method5302() <= 0) { + setWidgetSize(0, 0, 1, 1); + setWidgetPosition(0, 0, 1, 1); + setWidgetRGB(new Color(235, 224, 188)); + setWidgetText("N/A"); + } else { + setWidgetSize(21, 0, 1, 1); + setWidgetPosition(2, 0, 0, 1); + if (globalint_178 < subtract(cs2method5302(), 1)) { + setWidgetRGB(new Color(235, 224, 188)); + } else { + setWidgetRGB(new Color(0, 177, 225)); + } + setWidgetText(script_2693(globalint_178)); + createExtraChild(new WidgetPointer(ivar7), 5, getExtraChildGap(new WidgetPointer(ivar7))); + setWidgetSize(16, 16, 0, 0); + setWidgetPosition(1, 0, 2, 1); + setWidgetSprite(2554); + setScriptCallOnMouseEntered(2691, new WidgetPointer(-32768,3), getWidgetCustomChildArrayIndex(), 1, ivar8, 8419437, 1, "Ii1ii1"); + setScriptCallOnMouseExit(2691, new WidgetPointer(-32768,3), getWidgetCustomChildArrayIndex(), 0, ivar8, 6249298, 1, "Ii1ii1"); + setScriptCallOnMousePressed(2695, new WidgetPointer(-32768,3), -2147483643, getWidgetCustomChildArrayIndex(), ivar8, -1, 845, arg2, arg3, arg0, arg1, arg4, "IiiiiJiiiii"); + } + script_3451(arg4, 0); + return; +} diff --git a/dumps/scripts/2597.cs2 b/dumps/scripts/2597.cs2 new file mode 100644 index 0000000..2cbd93c --- /dev/null +++ b/dumps/scripts/2597.cs2 @@ -0,0 +1,99 @@ +void script_2597() { + int ivar0; + int ivar1; + ivar0 = -1; + ivar1 = 0; + switch (globalint_929) { + case 0: + ivar0 = getItemIdInSlot(93, globalint_930); + break; + case 1: + ivar0 = getItemIdInSlot(93, globalint_931); + break; + case 2: + ivar0 = getItemIdInSlot(93, globalint_932); + break; + case 3: + ivar0 = getItemIdInSlot(93, globalint_933); + break; + case 4: + ivar0 = getItemIdInSlot(93, globalint_934); + break; + case 5: + ivar0 = getItemIdInSlot(93, globalint_935); + break; + case 6: + ivar0 = getItemIdInSlot(93, globalint_936); + break; + case 7: + ivar0 = getItemIdInSlot(93, globalint_937); + break; + case 8: + ivar0 = getItemIdInSlot(93, globalint_938); + break; + case 9: + ivar0 = getItemIdInSlot(93, globalint_939); + } + if ((ivar0 == -1) || (getItemHashmapData(ivar0, 803) != 1)) { + return; + } + switch (globalint_929) { + case 0: + if (((boolean)bitconfig_6405)) { + ivar1 = 1; + } + break; + case 1: + if (((boolean)bitconfig_6406)) { + ivar1 = 1; + } + break; + case 2: + if (((boolean)bitconfig_6407)) { + ivar1 = 1; + } + break; + case 3: + if (((boolean)bitconfig_6408)) { + ivar1 = 1; + } + break; + case 4: + if (((boolean)bitconfig_6409)) { + ivar1 = 1; + } + break; + case 5: + if (((boolean)bitconfig_6410)) { + ivar1 = 1; + } + break; + case 6: + if (((boolean)bitconfig_6411)) { + ivar1 = 1; + } + break; + case 7: + if (((boolean)bitconfig_6412)) { + ivar1 = 1; + } + break; + case 8: + if (((boolean)bitconfig_6413)) { + ivar1 = 1; + } + break; + case 9: + if (((boolean)bitconfig_6414)) { + ivar1 = 1; + } + } + switch (ivar1) { + case 0: + setWidgetSprite(941, new WidgetPointer(292,113)); + break; + case 1: + setWidgetSprite(942, new WidgetPointer(292,113)); + } + return; +} diff --git a/dumps/scripts/2598.cs2 b/dumps/scripts/2598.cs2 new file mode 100644 index 0000000..f62b166 --- /dev/null +++ b/dumps/scripts/2598.cs2 @@ -0,0 +1,4 @@ +void script_2598() { + script_2599(); + return; +} diff --git a/dumps/scripts/2599.cs2 b/dumps/scripts/2599.cs2 new file mode 100644 index 0000000..e446c42 --- /dev/null +++ b/dumps/scripts/2599.cs2 @@ -0,0 +1,92 @@ +void script_2599() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + ivar0 = 0; + ivar1 = 0; + ivar2 = 0; + ivar3 = -1; + globalarray_0 = new int[10]; + globalarray_1 = new int[10]; + globalarray_2 = new int[10]; + ivar4 = 0; + while ((ivar1 < 28) && (ivar2 < 10)) { + ivar3 = getItemIdInSlot(93, ivar1); + if ((ivar3 != -1) && (((boolean)getItemHashmapData(ivar3, 802)) || ((boolean)getItemHashmapData(ivar3, 803)))) { + globalarray_0[ivar2] = ivar3; + ivar2 = add(ivar2, 1); + } + ivar1 = add(ivar1, 1); + } + ivar3 = -1; + globalarray_0[0] = bitconfig_6405; + globalarray_0[1] = bitconfig_6406; + globalarray_0[2] = bitconfig_6407; + globalarray_0[3] = bitconfig_6408; + globalarray_0[4] = bitconfig_6409; + globalarray_0[5] = bitconfig_6410; + globalarray_0[6] = bitconfig_6411; + globalarray_0[7] = bitconfig_6412; + globalarray_0[8] = bitconfig_6413; + globalarray_0[9] = bitconfig_6414; + ivar1 = 0; + while (ivar1 < 10) { + if (globalarray_0[ivar1] != -1) { + if (((boolean)getItemHashmapData(ivar3, 803))) { + globalarray_0[ivar1] = multiply(bitconfig_6405, 50); + } + if (((boolean)getItemHashmapData(globalarray_0[ivar1], 803)) && ((boolean)globalarray_1[ivar1])) { + globalarray_0[ivar1] = 50; + ivar4 = add(ivar4, globalarray_2[ivar1]); + } + setWidgetText(cs2method_3408(105, 73, 2424, ivar1), "Cost: " + intToStr(globalarray_2[ivar1])); + } + ivar1 = add(ivar1, 1); + } + setWidgetText(new WidgetPointer(292,101), intToStr(globalarray_2[globalint_929])); + globalint_928 = ivar4; + setWidgetText(new WidgetPointer(292,126), intToStr(globalint_928)); + setWidgetText(new WidgetPointer(292,128), "Remaining investment credits: " + intToStr(subtract(bitconfig_6351, globalint_928))); + if (globalint_928 <= bitconfig_6351) { + setWidgetSprite(1870, new WidgetPointer(292,123)); + setScriptCallOnClickContextMenu(2605, "", new WidgetPointer(292,122)); + setWidgetContextMenuOption(1, new WidgetPointer(292,122), "Apply changes"); + setScriptCallOnMouseEntered(94, new WidgetPointer(-32768,3), "I", new WidgetPointer(292,122)); + setWidgetRGB(new Color(255, 153, 53), new WidgetPointer(292,126)); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(292,122)); + } else { + setWidgetSprite(1871, new WidgetPointer(292,123)); + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(292,122)); + setWidgetNoOptions(new WidgetPointer(292,122)); + setScriptCallOnMouseEntered(-1, "", new WidgetPointer(292,122)); + setWidgetRGB(new Color(255, 17, 17), new WidgetPointer(292,126)); + setScriptCallOnMousePressed(2606, new WidgetPointer(-32768,3), "I", new WidgetPointer(292,122)); + } + ivar1 = 0; + while (ivar1 < 10) { + if ((globalarray_0[ivar1] != -1) && ((boolean)getItemHashmapData(globalarray_0[ivar1], 803))) { + ivar0 = add(ivar0, 50); + } + ivar1 = add(ivar1, 1); + } + if (ivar0 > 0) { + setWidgetText(new WidgetPointer(292,124), "Resupply all" + "
" + "(" + intToStr(ivar0) + ")"); + } + if ((bitconfig_6351 >= ivar0) && (ivar0 > 0)) { + setWidgetRGB(new Color(255, 153, 53), new WidgetPointer(292,124)); + setScriptCallOnClickContextMenu(2603, "", new WidgetPointer(292,119)); + setWidgetContextMenuOption(1, new WidgetPointer(292,119), "Resupply all"); + setScriptCallOnMouseEntered(94, new WidgetPointer(-32768,3), "I", new WidgetPointer(292,119)); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(292,119)); + } else { + setWidgetText(new WidgetPointer(292,124), "Resupply all"); + setWidgetRGB(new Color(102, 102, 102), new WidgetPointer(292,124)); + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(292,119)); + setWidgetNoOptions(new WidgetPointer(292,119)); + setScriptCallOnMouseEntered(-1, "", new WidgetPointer(292,119)); + setScriptCallOnMousePressed(2606, new WidgetPointer(-32768,3), "I", new WidgetPointer(292,119)); + } + return; +} diff --git a/dumps/scripts/26.cs2 b/dumps/scripts/26.cs2 new file mode 100644 index 0000000..7b91b74 --- /dev/null +++ b/dumps/scripts/26.cs2 @@ -0,0 +1,47 @@ +void script_26() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + ivar0 = 0; + ivar1 = 0; + ivar2 = 25; + ivar3 = 20; + ivar4 = 0; + ivar5 = 0; + ivar6 = 0; + ivar4 = divide(subtract(getWidgetActualWidth(new WidgetPointer(197,16)), ivar2), add(ivar2, 36)); + while (ivar0 <= getItemContainerLength(347)) { + createExtraChild(new WidgetPointer(197,16), 5, ivar0); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(add(ivar2, multiply(add(36, ivar2), subtract(ivar0, multiply(ivar1, ivar4)))), add(ivar3, multiply(ivar1, add(32, ivar3))), 0, 0); + ivar5 = add(ivar2, multiply(add(36, ivar2), subtract(ivar0, multiply(ivar1, ivar4)))); + ivar6 = add(ivar3, multiply(ivar1, add(32, ivar3))); + if (getItemIdInSlot(347, ivar0) != -1) { + if (getItemIdInSlot(347, ivar0) == 6910) { + setWidgetPosition(subtract(ivar5, 8), add(ivar6, 94), 0, 0, new WidgetPointer(197,12)); + } + if (getItemIdInSlot(347, ivar0) == 6912) { + setWidgetPosition(subtract(ivar5, 8), add(ivar6, 94), 0, 0, new WidgetPointer(197,14)); + } + if (getItemIdInSlot(347, ivar0) == 6914) { + setWidgetPosition(subtract(ivar5, 8), add(ivar6, 94), 0, 0, new WidgetPointer(197,13)); + } + setItemOnWidgetMethod1200(getItemIdInSlot(347, ivar0), getItemAmtInSlot(347, ivar0)); + setWidgetShadowColor(new Color(0, 0, 0)); + cs2method1305("" + getItemName(getItemIdInSlot(347, ivar0))); + setWidgetBorderThickness(1); + setWidgetContextMenuOption(1, "Value"); + setWidgetContextMenuOption(2, "Buy"); + setWidgetContextMenuOption(10, "Examine"); + } + ivar0 = add(ivar0, 1); + if (((boolean)mod(ivar0, ivar4))) { + ivar1 = add(ivar1, 1); + } + } + return; +} diff --git a/dumps/scripts/260.cs2 b/dumps/scripts/260.cs2 new file mode 100644 index 0000000..29abd12 --- /dev/null +++ b/dumps/scripts/260.cs2 @@ -0,0 +1,4 @@ +void script_260() { + script_261(); + return; +} diff --git a/dumps/scripts/2600.cs2 b/dumps/scripts/2600.cs2 new file mode 100644 index 0000000..ecaaeae --- /dev/null +++ b/dumps/scripts/2600.cs2 @@ -0,0 +1,5 @@ +void script_2600() { + playSoundEffect(6784, 1, 0); + setWidgetIsHidden(true, new WidgetPointer(292,130)); + return; +} diff --git a/dumps/scripts/2601.cs2 b/dumps/scripts/2601.cs2 new file mode 100644 index 0000000..1b12a9b --- /dev/null +++ b/dumps/scripts/2601.cs2 @@ -0,0 +1,15 @@ +int script_2601(int arg0,int arg1,int arg2,string arg3) { + createExtraChild(new WidgetPointer(arg2), 4, getExtraChildGap(new WidgetPointer(arg2))); + setWidgetSize(211, 16, 0, 0); + if (((boolean)arg0)) { + setWidgetPosition(6, arg1, 2, 0); + } else { + setWidgetPosition(0, arg1, 0, 0); + } + setWidgetFont(495); + setWidgetTextAlignment(0, 1, 0); + setWidgetRGB(new Color(235, 224, 188)); + setWidgetUnknownBoolean(true); + setWidgetText(arg3); + return getWidgetCustomChildArrayIndex(); +} diff --git a/dumps/scripts/2602.cs2 b/dumps/scripts/2602.cs2 new file mode 100644 index 0000000..ca28f2b --- /dev/null +++ b/dumps/scripts/2602.cs2 @@ -0,0 +1,3 @@ +void script_2602() { + return; +} diff --git a/dumps/scripts/2603.cs2 b/dumps/scripts/2603.cs2 new file mode 100644 index 0000000..52d2e67 --- /dev/null +++ b/dumps/scripts/2603.cs2 @@ -0,0 +1,9 @@ +void script_2603() { + playSoundEffect(6784, 1, 0); + setWidgetIsHidden(false, new WidgetPointer(292,130)); + setWidgetText(new WidgetPointer(292,132), "Are you sure you wish to resupply all defeated squads?"); + setWidgetIsHidden(false, new WidgetPointer(292,135)); + setWidgetIsHidden(true, new WidgetPointer(292,134)); + setWidgetIsHidden(true, new WidgetPointer(292,137)); + return; +} diff --git a/dumps/scripts/2604.cs2 b/dumps/scripts/2604.cs2 new file mode 100644 index 0000000..377ea97 --- /dev/null +++ b/dumps/scripts/2604.cs2 @@ -0,0 +1,9 @@ +void script_2604() { + playSoundEffect(6784, 1, 0); + setWidgetIsHidden(false, new WidgetPointer(292,130)); + setWidgetText(new WidgetPointer(292,132), "Are you sure you wish to reset all your squad contract selections?"); + setWidgetIsHidden(true, new WidgetPointer(292,135)); + setWidgetIsHidden(true, new WidgetPointer(292,137)); + setWidgetIsHidden(false, new WidgetPointer(292,134)); + return; +} diff --git a/dumps/scripts/2605.cs2 b/dumps/scripts/2605.cs2 new file mode 100644 index 0000000..1e1a9da --- /dev/null +++ b/dumps/scripts/2605.cs2 @@ -0,0 +1,9 @@ +void script_2605() { + playSoundEffect(6784, 1, 0); + setWidgetIsHidden(false, new WidgetPointer(292,130)); + setWidgetText(new WidgetPointer(292,132), "Are you sure you wish to apply the selected changes?"); + setWidgetIsHidden(true, new WidgetPointer(292,135)); + setWidgetIsHidden(false, new WidgetPointer(292,137)); + setWidgetIsHidden(true, new WidgetPointer(292,134)); + return; +} diff --git a/dumps/scripts/2606.cs2 b/dumps/scripts/2606.cs2 new file mode 100644 index 0000000..cac5701 --- /dev/null +++ b/dumps/scripts/2606.cs2 @@ -0,0 +1,78 @@ +void script_2606(int arg0) { + int ivar1; + playSoundEffect(2277, 1, 0); + ivar1 = -1; + switch (globalint_929) { + case 0: + if (globalint_930 != -1) { + ivar1 = getItemIdInSlot(93, globalint_930); + } + break; + case 1: + if (globalint_931 != -1) { + ivar1 = getItemIdInSlot(93, globalint_931); + } + break; + case 2: + if (globalint_932 != -1) { + ivar1 = getItemIdInSlot(93, globalint_932); + } + break; + case 3: + if (globalint_933 != -1) { + ivar1 = getItemIdInSlot(93, globalint_933); + } + break; + case 4: + if (globalint_934 != -1) { + ivar1 = getItemIdInSlot(93, globalint_934); + } + break; + case 5: + if (globalint_935 != -1) { + ivar1 = getItemIdInSlot(93, globalint_935); + } + break; + case 6: + if (globalint_936 != -1) { + ivar1 = getItemIdInSlot(93, globalint_936); + } + break; + case 7: + if (globalint_937 != -1) { + ivar1 = getItemIdInSlot(93, globalint_937); + } + break; + case 8: + if (globalint_938 != -1) { + ivar1 = getItemIdInSlot(93, globalint_938); + } + break; + case 9: + if (globalint_939 != -1) { + ivar1 = getItemIdInSlot(93, globalint_939); + } + } + switch (arg0) { + case 19136631: + if (((boolean)getContainerIntNodeCountIgnoreStacks(93, 803))) { + messageType0("You have no squads that need resupplying."); + } else { + messageType0("You do not have sufficient investment credits to resupply all your squads."); + } + break; + case 19136634: + messageType0("You do not have sufficient investment credits to apply the selected changes."); + break; + case 19136615: + case 19136614: + case 19136623: + case 19136622: + case 19136616: + messageType0("You must resupply this squad first."); + break; + case 19136625: + messageType0("This squad does not need resupplying."); + } + return; +} diff --git a/dumps/scripts/2607.cs2 b/dumps/scripts/2607.cs2 new file mode 100644 index 0000000..8d1197e --- /dev/null +++ b/dumps/scripts/2607.cs2 @@ -0,0 +1,6 @@ +void script_2607(int arg0) { + if (setWidgetRegister(new WidgetPointer(88,22), arg0)) { + setWidgetAnimation(-1); + } + return; +} diff --git a/dumps/scripts/2608.cs2 b/dumps/scripts/2608.cs2 new file mode 100644 index 0000000..facc540 --- /dev/null +++ b/dumps/scripts/2608.cs2 @@ -0,0 +1,4 @@ +void script_2608(int arg0) { + setWidgetText(new WidgetPointer(arg0), intToStr(bitconfig_6382)); + return; +} diff --git a/dumps/scripts/2609.cs2 b/dumps/scripts/2609.cs2 new file mode 100644 index 0000000..00824d1 --- /dev/null +++ b/dumps/scripts/2609.cs2 @@ -0,0 +1,8 @@ +void script_2609(int arg0) { + if ((((boolean)bitconfig_6357) || (bitconfig_6357 == 4)) || (bitconfig_6357 == 3)) { + setWidgetPosition(0, 5, 0, 0, new WidgetPointer(arg0)); + } else { + setWidgetPosition(0, 0, 0, 0, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/261.cs2 b/dumps/scripts/261.cs2 new file mode 100644 index 0000000..f9922bb --- /dev/null +++ b/dumps/scripts/261.cs2 @@ -0,0 +1,6 @@ +void script_261() { + script_266(); + script_263(); + script_265(); + return; +} diff --git a/dumps/scripts/2610.cs2 b/dumps/scripts/2610.cs2 new file mode 100644 index 0000000..c4ab866 --- /dev/null +++ b/dumps/scripts/2610.cs2 @@ -0,0 +1,91 @@ +void script_2610(int arg0) { + string svar0; + svar0 = ""; + if (bitconfig_6357 == 2) { + setWidgetIsHidden(false, new WidgetPointer(arg0)); + if (bitconfig_6372 == 15) { + if (bitconfig_6373 > 0) { + svar0 = "Collected " + intToStr(bitconfig_6373) + " out of 4 rocks"; + setWidgetSprite(1985, new WidgetPointer(37,36)); + } else { + svar0 = "Send a squad to collect rocks"; + setWidgetSprite(1990, new WidgetPointer(37,36)); + } + setScriptCallOnMouseOver(38, new WidgetPointer(37,0), new WidgetPointer(37,41), svar0, 50, 150, "IIsii", new WidgetPointer(37,0)); + setScriptCallOnMouseExit(40, new WidgetPointer(37,41), "I", new WidgetPointer(37,0)); + if (bitconfig_6373 > 1) { + svar0 = "Collected " + intToStr(bitconfig_6373) + " out of 4 rocks"; + setWidgetSprite(1985, new WidgetPointer(37,39)); + } else { + svar0 = "Send a squad to collect rocks."; + setWidgetSprite(1990, new WidgetPointer(37,39)); + } + setScriptCallOnMouseOver(38, new WidgetPointer(37,3), new WidgetPointer(37,41), svar0, 50, 150, "IIsii", new WidgetPointer(37,3)); + setScriptCallOnMouseExit(40, new WidgetPointer(37,41), "I", new WidgetPointer(37,3)); + if (bitconfig_6373 > 2) { + svar0 = "Collected " + intToStr(bitconfig_6373) + " out of 4 rocks"; + setWidgetSprite(1985, new WidgetPointer(37,38)); + } else { + svar0 = "Send a squad to collect rocks."; + setWidgetSprite(1990, new WidgetPointer(37,38)); + } + setScriptCallOnMouseOver(38, new WidgetPointer(37,4), new WidgetPointer(37,41), svar0, 50, 150, "IIsii", new WidgetPointer(37,4)); + setScriptCallOnMouseExit(40, new WidgetPointer(37,41), "I", new WidgetPointer(37,4)); + if (bitconfig_6373 > 3) { + svar0 = "Collected " + intToStr(bitconfig_6373) + " out of 4 rocks"; + setWidgetSprite(1985, new WidgetPointer(37,37)); + } else { + svar0 = "Send a squad to collect rocks."; + setWidgetSprite(1990, new WidgetPointer(37,37)); + } + setScriptCallOnMouseOver(38, new WidgetPointer(37,5), new WidgetPointer(37,41), svar0, 50, 150, "IIsii", new WidgetPointer(37,5)); + setScriptCallOnMouseExit(40, new WidgetPointer(37,41), "I", new WidgetPointer(37,5)); + } else { + if (bitconfig_6368 > 0) { + svar0 = "Collected wheels"; + setWidgetSprite(1981, new WidgetPointer(37,36)); + } else { + svar0 = "Send a squad to collect wheels."; + setWidgetSprite(1986, new WidgetPointer(37,36)); + } + setScriptCallOnMouseOver(38, new WidgetPointer(37,0), new WidgetPointer(37,41), svar0, 50, 150, "IIsii", new WidgetPointer(37,0)); + setScriptCallOnMouseExit(40, new WidgetPointer(37,41), "I", new WidgetPointer(37,0)); + if (bitconfig_6370 > 0) { + svar0 = "Collected logs"; + setWidgetSprite(1982, new WidgetPointer(37,39)); + } else { + svar0 = "Send a squad to collect logs."; + setWidgetSprite(1987, new WidgetPointer(37,39)); + } + setScriptCallOnMouseOver(38, new WidgetPointer(37,3), new WidgetPointer(37,41), svar0, 50, 150, "IIsii", new WidgetPointer(37,3)); + setScriptCallOnMouseExit(40, new WidgetPointer(37,41), "I", new WidgetPointer(37,3)); + if (bitconfig_6371 > 0) { + svar0 = "Collected rope"; + setWidgetSprite(1983, new WidgetPointer(37,38)); + } else { + svar0 = "Send a squad to collect rope."; + setWidgetSprite(1988, new WidgetPointer(37,38)); + } + setScriptCallOnMouseOver(38, new WidgetPointer(37,4), new WidgetPointer(37,41), svar0, 50, 150, "IIsii", new WidgetPointer(37,4)); + setScriptCallOnMouseExit(40, new WidgetPointer(37,41), "I", new WidgetPointer(37,4)); + if (bitconfig_6369 > 0) { + svar0 = "Collected metal limbs"; + setWidgetSprite(1984, new WidgetPointer(37,37)); + } else { + svar0 = "Send a squad to collect metal limbs."; + setWidgetSprite(1989, new WidgetPointer(37,37)); + } + setScriptCallOnMouseOver(38, new WidgetPointer(37,5), new WidgetPointer(37,41), svar0, 50, 150, "IIsii", new WidgetPointer(37,5)); + setScriptCallOnMouseExit(40, new WidgetPointer(37,41), "I", new WidgetPointer(37,5)); + } + } else if (((boolean)bitconfig_6357)) { + setWidgetIsHidden(true, new WidgetPointer(arg0)); + } else if (bitconfig_6357 == 3) { + setWidgetIsHidden(true, new WidgetPointer(arg0)); + } else { + if (bitconfig_6357 == 4) { + setWidgetIsHidden(true, new WidgetPointer(arg0)); + } + } + return; +} diff --git a/dumps/scripts/2611.cs2 b/dumps/scripts/2611.cs2 new file mode 100644 index 0000000..d249271 --- /dev/null +++ b/dumps/scripts/2611.cs2 @@ -0,0 +1,8 @@ +void script_2611(int arg0,int arg1) { + if (((boolean)arg1)) { + cs2method6201(256, 320); + cameraMethod5504(383, 0); + } + script_2612(addToCoordinate(getMyPositionHash(), -16, 0, -16), arg0); + return; +} diff --git a/dumps/scripts/2612.cs2 b/dumps/scripts/2612.cs2 new file mode 100644 index 0000000..517234d --- /dev/null +++ b/dumps/scripts/2612.cs2 @@ -0,0 +1,20 @@ +void script_2612(int arg0,int arg1) { + cameraMethod5511(addToCoordinate(arg0, 16, 0, 16)); + switch (arg1) { + case 0: + cs2method6201(144, 180); + break; + case 1: + cs2method6201(176, 220); + break; + case 2: + cs2method6201(208, 260); + break; + case 3: + cs2method6201(240, 300); + break; + case 4: + cs2method6201(272, 340); + } + return; +} diff --git a/dumps/scripts/2613.cs2 b/dumps/scripts/2613.cs2 new file mode 100644 index 0000000..79ac3ab --- /dev/null +++ b/dumps/scripts/2613.cs2 @@ -0,0 +1,41 @@ +void script_2613() { + int ivar0; + int ivar1; + int ivar2; + ivar0 = 0; + ivar1 = 0; + ivar2 = 0; + switch (script_2617()) { + case 0: + ivar2 = addToCoordinate(globalint_834, 0, 0, 5); + break; + case 7: + ivar2 = addToCoordinate(globalint_834, -4, 0, 4); + break; + case 6: + ivar2 = addToCoordinate(globalint_834, -5, 0, 0); + break; + case 5: + ivar2 = addToCoordinate(globalint_834, -4, 0, -4); + break; + case 4: + ivar2 = addToCoordinate(globalint_834, 0, 0, -5); + break; + case 3: + ivar2 = addToCoordinate(globalint_834, 4, 0, -4); + break; + case 2: + ivar2 = addToCoordinate(globalint_834, 5, 0, 0); + break; + case 1: + ivar2 = addToCoordinate(globalint_834, 4, 0, 4); + } + ivar0 = divide(extractX(ivar2), 64); + ivar1 = divide(extractY(ivar2), 64); + if ((globalint_835 != ivar0) || (globalint_836 != ivar1)) { + return; + } + globalint_834 = ivar2; + script_2612(globalint_834, globalint_833); + return; +} diff --git a/dumps/scripts/2614.cs2 b/dumps/scripts/2614.cs2 new file mode 100644 index 0000000..5009b4a --- /dev/null +++ b/dumps/scripts/2614.cs2 @@ -0,0 +1,41 @@ +void script_2614() { + int ivar0; + int ivar1; + int ivar2; + ivar0 = 0; + ivar1 = 0; + ivar2 = 0; + switch (script_2617()) { + case 0: + ivar2 = addToCoordinate(globalint_834, 0, 0, -5); + break; + case 7: + ivar2 = addToCoordinate(globalint_834, 4, 0, -4); + break; + case 6: + ivar2 = addToCoordinate(globalint_834, 5, 0, 0); + break; + case 5: + ivar2 = addToCoordinate(globalint_834, 4, 0, 4); + break; + case 4: + ivar2 = addToCoordinate(globalint_834, 0, 0, 5); + break; + case 3: + ivar2 = addToCoordinate(globalint_834, -4, 0, 4); + break; + case 2: + ivar2 = addToCoordinate(globalint_834, -5, 0, 0); + break; + case 1: + ivar2 = addToCoordinate(globalint_834, -4, 0, -4); + } + ivar0 = divide(extractX(ivar2), 64); + ivar1 = divide(extractY(ivar2), 64); + if ((globalint_835 != ivar0) || (globalint_836 != ivar1)) { + return; + } + globalint_834 = ivar2; + script_2612(globalint_834, globalint_833); + return; +} diff --git a/dumps/scripts/2615.cs2 b/dumps/scripts/2615.cs2 new file mode 100644 index 0000000..cae7da4 --- /dev/null +++ b/dumps/scripts/2615.cs2 @@ -0,0 +1,41 @@ +void script_2615() { + int ivar0; + int ivar1; + int ivar2; + ivar0 = 0; + ivar1 = 0; + ivar2 = 0; + switch (script_2617()) { + case 0: + ivar2 = addToCoordinate(globalint_834, -5, 0, 0); + break; + case 7: + ivar2 = addToCoordinate(globalint_834, -4, 0, -4); + break; + case 6: + ivar2 = addToCoordinate(globalint_834, 0, 0, -5); + break; + case 5: + ivar2 = addToCoordinate(globalint_834, 4, 0, -4); + break; + case 4: + ivar2 = addToCoordinate(globalint_834, 5, 0, 0); + break; + case 3: + ivar2 = addToCoordinate(globalint_834, 4, 0, 4); + break; + case 2: + ivar2 = addToCoordinate(globalint_834, 0, 0, 5); + break; + case 1: + ivar2 = addToCoordinate(globalint_834, -4, 0, 4); + } + ivar0 = divide(extractX(ivar2), 64); + ivar1 = divide(extractY(ivar2), 64); + if ((globalint_835 != ivar0) || (globalint_836 != ivar1)) { + return; + } + globalint_834 = ivar2; + script_2612(globalint_834, globalint_833); + return; +} diff --git a/dumps/scripts/2616.cs2 b/dumps/scripts/2616.cs2 new file mode 100644 index 0000000..e8b2c7d --- /dev/null +++ b/dumps/scripts/2616.cs2 @@ -0,0 +1,41 @@ +void script_2616() { + int ivar0; + int ivar1; + int ivar2; + ivar0 = 0; + ivar1 = 0; + ivar2 = 0; + switch (script_2617()) { + case 0: + ivar2 = addToCoordinate(globalint_834, 5, 0, 0); + break; + case 7: + ivar2 = addToCoordinate(globalint_834, 4, 0, 4); + break; + case 6: + ivar2 = addToCoordinate(globalint_834, 0, 0, 5); + break; + case 5: + ivar2 = addToCoordinate(globalint_834, -4, 0, 4); + break; + case 4: + ivar2 = addToCoordinate(globalint_834, -5, 0, 0); + break; + case 3: + ivar2 = addToCoordinate(globalint_834, -4, 0, -4); + break; + case 2: + ivar2 = addToCoordinate(globalint_834, 0, 0, -5); + break; + case 1: + ivar2 = addToCoordinate(globalint_834, 4, 0, -4); + } + ivar0 = divide(extractX(ivar2), 64); + ivar1 = divide(extractY(ivar2), 64); + if ((globalint_835 != ivar0) || (globalint_836 != ivar1)) { + return; + } + globalint_834 = ivar2; + script_2612(globalint_834, globalint_833); + return; +} diff --git a/dumps/scripts/2617.cs2 b/dumps/scripts/2617.cs2 new file mode 100644 index 0000000..03ab542 --- /dev/null +++ b/dumps/scripts/2617.cs2 @@ -0,0 +1,29 @@ +int script_2617() { + int ivar0; + ivar0 = cameraGetHrot(); + if ((ivar0 < 128) || (ivar0 >= 1920)) { + return 0; + } + if ((ivar0 < 384) && (ivar0 >= 128)) { + return 7; + } + if ((ivar0 >= 384) && (ivar0 < 650)) { + return 6; + } + if ((ivar0 < 896) && (ivar0 >= 650)) { + return 5; + } + if ((ivar0 >= 896) && (ivar0 < 1152)) { + return 4; + } + if ((ivar0 < 1408) && (ivar0 >= 1152)) { + return 3; + } + if ((ivar0 >= 1408) && (ivar0 < 1664)) { + return 2; + } + if ((ivar0 < 1920) && (ivar0 >= 1664)) { + return 1; + } + return 0; +} diff --git a/dumps/scripts/2618.cs2 b/dumps/scripts/2618.cs2 new file mode 100644 index 0000000..4140e9e --- /dev/null +++ b/dumps/scripts/2618.cs2 @@ -0,0 +1,16 @@ +void script_2618(int arg0) { + switch (arg0) { + case 1: + cs2method5507(); + break; + case 2: + cs2method5508(); + break; + case 3: + cs2method5509(); + break; + case 4: + cs2method5510(); + } + return; +} diff --git a/dumps/scripts/2619.cs2 b/dumps/scripts/2619.cs2 new file mode 100644 index 0000000..6c3233a --- /dev/null +++ b/dumps/scripts/2619.cs2 @@ -0,0 +1,4 @@ +void script_2619() { + cs2method6201(0, 0); + return; +} diff --git a/dumps/scripts/262.cs2 b/dumps/scripts/262.cs2 new file mode 100644 index 0000000..d99b22a --- /dev/null +++ b/dumps/scripts/262.cs2 @@ -0,0 +1,5 @@ +void script_262(int arg0) { + globalint_1109 = arg0; + script_261(); + return; +} diff --git a/dumps/scripts/2620.cs2 b/dumps/scripts/2620.cs2 new file mode 100644 index 0000000..2014698 --- /dev/null +++ b/dumps/scripts/2620.cs2 @@ -0,0 +1,4 @@ +void script_2620() { + script_2621(); + return; +} diff --git a/dumps/scripts/2621.cs2 b/dumps/scripts/2621.cs2 new file mode 100644 index 0000000..7357304 --- /dev/null +++ b/dumps/scripts/2621.cs2 @@ -0,0 +1,12 @@ +void script_2621() { + if (isWidgetHidden(new WidgetPointer(850,1))) { + setWidgetIsHidden(true, new WidgetPointer(850,1)); + setWidgetIsHidden(false, new WidgetPointer(850,47)); + setWidgetHFlip(0, new WidgetPointer(850,50)); + } else { + setWidgetIsHidden(false, new WidgetPointer(850,1)); + setWidgetIsHidden(true, new WidgetPointer(850,47)); + setWidgetHFlip(1, new WidgetPointer(850,50)); + } + return; +} diff --git a/dumps/scripts/2622.cs2 b/dumps/scripts/2622.cs2 new file mode 100644 index 0000000..e424960 --- /dev/null +++ b/dumps/scripts/2622.cs2 @@ -0,0 +1,31 @@ +void script_2622() { + int ivar0; + int ivar1; + ivar0 = -1; + ivar1 = 1; + if (((boolean)stringMethod4107(globalstring_179, "")) || ((boolean)stringMethod4107(globalstring_179, "null"))) { + return; + } + setWidgetText(new WidgetPointer(850,44), getWidgetText(new WidgetPointer(850,43))); + setWidgetText(new WidgetPointer(850,43), getWidgetText(new WidgetPointer(850,42))); + setWidgetText(new WidgetPointer(850,42), getWidgetText(new WidgetPointer(850,41))); + setWidgetText(new WidgetPointer(850,41), getWidgetText(new WidgetPointer(850,40))); + setWidgetText(new WidgetPointer(850,40), getWidgetText(new WidgetPointer(850,39))); + setWidgetText(new WidgetPointer(850,39), getWidgetText(new WidgetPointer(850,38))); + setWidgetText(new WidgetPointer(850,38), getWidgetText(new WidgetPointer(850,37))); + setWidgetText(new WidgetPointer(850,37), getWidgetText(new WidgetPointer(850,36))); + setWidgetText(new WidgetPointer(850,36), getWidgetText(new WidgetPointer(850,35))); + setWidgetText(new WidgetPointer(850,35), getWidgetText(new WidgetPointer(850,34))); + setWidgetText(new WidgetPointer(850,34), getWidgetText(new WidgetPointer(850,33))); + setWidgetText(new WidgetPointer(850,33), getWidgetText(new WidgetPointer(850,32))); + setWidgetText(new WidgetPointer(850,32), getWidgetText(new WidgetPointer(850,31))); + setWidgetText(new WidgetPointer(850,31), getWidgetText(new WidgetPointer(850,30))); + setWidgetText(new WidgetPointer(850,30), getWidgetText(new WidgetPointer(850,29))); + setWidgetText(new WidgetPointer(850,29), getWidgetText(new WidgetPointer(850,28))); + setWidgetText(new WidgetPointer(850,28), getWidgetText(new WidgetPointer(850,27))); + setWidgetText(new WidgetPointer(850,27), getWidgetText(new WidgetPointer(850,26))); + setWidgetText(new WidgetPointer(850,26), getWidgetText(new WidgetPointer(850,25))); + setWidgetText(new WidgetPointer(850,25), globalstring_179); + script_157(55705645, 55705646, getWidgetScrollMaxV(new WidgetPointer(850,46)), 1); + return; +} diff --git a/dumps/scripts/2623.cs2 b/dumps/scripts/2623.cs2 new file mode 100644 index 0000000..e7f56e5 --- /dev/null +++ b/dumps/scripts/2623.cs2 @@ -0,0 +1,25 @@ +void script_2623() { + int ivar0; + ivar0 = 1; + while (((int)cs2method_3408(105, 73, 2451, ivar0)) != 55705624) { + setWidgetText(cs2method_3408(105, 73, 2451, ivar0), ""); + ivar0 = add(ivar0, 1); + } + setWidgetText(new WidgetPointer(850,25), "Welcome to Mobilising Armies."); + switch (bitconfig_6352) { + case 1: + setWidgetSprite(1906, new WidgetPointer(850,50)); + break; + case 2: + setWidgetSprite(1904, new WidgetPointer(850,50)); + break; + case 3: + setWidgetSprite(1905, new WidgetPointer(850,50)); + break; + case 4: + setWidgetSprite(1907, new WidgetPointer(850,50)); + } + script_157(55705645, 55705646, getWidgetScrollMaxV(new WidgetPointer(850,46)), 1); + setScriptCallOnKeyPress(2625, -2147483640, false, "iz", new WidgetPointer(850,48)); + return; +} diff --git a/dumps/scripts/2624.cs2 b/dumps/scripts/2624.cs2 new file mode 100644 index 0000000..034d6e6 --- /dev/null +++ b/dumps/scripts/2624.cs2 @@ -0,0 +1,12 @@ +void script_2624() { + int ivar0; + int ivar1; + ivar0 = 1; + ivar1 = -1; + while (((int)cs2method_3408(105, 73, 2450, ivar0)) != 55705624) { + ivar1 = ((int)cs2method_3408(105, 73, 2450, ivar0)); + setWidgetText(new WidgetPointer(ivar1), "" + cs2method_3408(73, 115, 2449, ivar1) + " " + "" + cs2method_3408(73, 115, 2448, ivar1)); + ivar0 = add(ivar0, 1); + } + return; +} diff --git a/dumps/scripts/2625.cs2 b/dumps/scripts/2625.cs2 new file mode 100644 index 0000000..ba0c373 --- /dev/null +++ b/dumps/scripts/2625.cs2 @@ -0,0 +1,14 @@ +void script_2625(int arg0,int arg1) { + if (arg0 == 84) { + script_2621(); + } else { + if (isWidgetHidden(new WidgetPointer(850,1))) { + if (strIndexof(((char)lower(((char)arg1))), 0, "abcdefghijklmnopqrst") != -1) { + script_2621(); + } else { + return; + } + } + } + return; +} diff --git a/dumps/scripts/2626.cs2 b/dumps/scripts/2626.cs2 new file mode 100644 index 0000000..b06b1e8 --- /dev/null +++ b/dumps/scripts/2626.cs2 @@ -0,0 +1,17 @@ +void script_2626() { + cs2method2308(0, 1, new WidgetPointer(859,13)); + cs2method2308(2, 3, new WidgetPointer(859,14)); + if (bitconfig_6357 == 2) { + cs2method2308(4, 5, new WidgetPointer(859,16)); + cs2method2308(12, 13, new WidgetPointer(859,17)); + } else if (bitconfig_6357 == 3) { + cs2method2308(6, 7, new WidgetPointer(859,16)); + } else { + if (bitconfig_6357 == 4) { + cs2method2308(10, 11, new WidgetPointer(859,16)); + cs2method2308(8, 9, new WidgetPointer(859,17)); + } + } + script_2628(); + return; +} diff --git a/dumps/scripts/2627.cs2 b/dumps/scripts/2627.cs2 new file mode 100644 index 0000000..616eabe --- /dev/null +++ b/dumps/scripts/2627.cs2 @@ -0,0 +1,4 @@ +void script_2627() { + script_2628(); + return; +} diff --git a/dumps/scripts/2628.cs2 b/dumps/scripts/2628.cs2 new file mode 100644 index 0000000..1968e8c --- /dev/null +++ b/dumps/scripts/2628.cs2 @@ -0,0 +1,65 @@ +void script_2628() { + if (((boolean)globalint_906)) { + setWidgetSprite(1868, new WidgetPointer(859,25)); + setWidgetText(new WidgetPointer(859,11), "Idle"); + } else { + if (globalint_906 == 2) { + setWidgetSprite(1867, new WidgetPointer(859,25)); + switch (globalint_907) { + case 0: + globalint_906 = 0; + setWidgetSprite(1868, new WidgetPointer(859,25)); + setWidgetText(new WidgetPointer(859,11), "Idle"); + break; + case 1: + case 2: + setWidgetText(new WidgetPointer(859,11), "Exploring"); + break; + case 3: + case 4: + setWidgetText(new WidgetPointer(859,11), "Attacking wall"); + break; + case 5: + case 6: + case 7: + setWidgetText(new WidgetPointer(859,11), "Rescuing TzHaar"); + break; + case 8: + case 9: + setWidgetText(new WidgetPointer(859,11), "Collecting gold"); + break; + case 10: + case 11: + case 12: + setWidgetText(new WidgetPointer(859,11), "Stealing TzHaar"); + break; + case 13: + case 14: + case 15: + setWidgetText(new WidgetPointer(859,11), "Collecting parts"); + break; + case 17: + case 16: + case 18: + setWidgetText(new WidgetPointer(859,11), "Collecting Rocks"); + break; + case 19: + case 20: + setWidgetText(new WidgetPointer(859,11), "Attacking catapult"); + break; + case 21: + setWidgetText(new WidgetPointer(859,11), "Retaliating"); + break; + case 22: + setWidgetText(new WidgetPointer(859,11), "Moving to destination"); + break; + case 23: + setWidgetText(new WidgetPointer(859,11), "Attacking"); + break; + default: + setWidgetText(new WidgetPointer(859,11), "Busy"); + } + } + } + return; +} diff --git a/dumps/scripts/2629.cs2 b/dumps/scripts/2629.cs2 new file mode 100644 index 0000000..204b979 --- /dev/null +++ b/dumps/scripts/2629.cs2 @@ -0,0 +1,9 @@ +void script_2629(int arg0) { + if ((globalint_905 == arg0) && ((boolean)globalint_904)) { + script_2635(); + return; + } + script_2635(); + script_2630(arg0); + return; +} diff --git a/dumps/scripts/263.cs2 b/dumps/scripts/263.cs2 new file mode 100644 index 0000000..071a470 --- /dev/null +++ b/dumps/scripts/263.cs2 @@ -0,0 +1,31 @@ +void script_263() { + string svar0; + svar0 = "None"; + switch (globalint_1109) { + case 1: + svar0 = "Worm"; + break; + case 2: + svar0 = "Maggot"; + break; + case 4: + svar0 = "Locust"; + break; + case 3: + svar0 = "Cricket"; + break; + case 5: + svar0 = "Cray"; + break; + case 6: + svar0 = "Shrimp"; + break; + case 7: + svar0 = "Green moth"; + break; + case 8: + svar0 = "Grey moth"; + } + setWidgetText(new WidgetPointer(923,51), svar0); + return; +} diff --git a/dumps/scripts/2630.cs2 b/dumps/scripts/2630.cs2 new file mode 100644 index 0000000..4fe78e9 --- /dev/null +++ b/dumps/scripts/2630.cs2 @@ -0,0 +1,55 @@ +void script_2630(int arg0) { + int ivar1; + int ivar2; + ivar1 = -1; + ivar2 = -1; + globalint_905 = arg0; + globalint_904 = 1; + switch (arg0) { + case 56295437: + arg0 = 56295426; + ivar1 = 1914; + ivar2 = 1922; + break; + case 56295438: + arg0 = 56295432; + ivar1 = 1915; + ivar2 = 1923; + break; + case 56295439: + arg0 = 56295431; + ivar1 = 1916; + ivar2 = 1924; + break; + case 56295440: + if (bitconfig_6357 == 2) { + arg0 = 56295446; + ivar1 = 1917; + ivar2 = 1925; + } + if (bitconfig_6357 == 3) { + arg0 = 56295430; + ivar1 = 1918; + ivar2 = 1926; + } + if (bitconfig_6357 == 4) { + arg0 = 56295447; + ivar1 = 1921; + ivar2 = 1929; + } + break; + case 56295441: + if (bitconfig_6357 == 2) { + arg0 = 56295445; + ivar1 = 1920; + ivar2 = 1928; + } + if (bitconfig_6357 == 4) { + arg0 = 56295444; + ivar1 = 1919; + ivar2 = 1927; + } + } + setScriptCallOnGameloop(2631, new WidgetPointer(arg0), ivar1, ivar2, "Idd", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/2631.cs2 b/dumps/scripts/2631.cs2 new file mode 100644 index 0000000..aac08aa --- /dev/null +++ b/dumps/scripts/2631.cs2 @@ -0,0 +1,8 @@ +void script_2631(int arg0,int arg1,int arg2) { + if (mod(getClientCycle(), 20) < 10) { + setWidgetSprite(arg2, new WidgetPointer(arg0)); + } else { + setWidgetSprite(arg1, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/2632.cs2 b/dumps/scripts/2632.cs2 new file mode 100644 index 0000000..f9c5314 --- /dev/null +++ b/dumps/scripts/2632.cs2 @@ -0,0 +1,48 @@ +void script_2632(int arg0) { + if (arg0 != 56295424) { + script_1360(arg0); + } + switch (arg0) { + case 56295424: + setWidgetText(new WidgetPointer(859,28), "Go to"); + setWidgetText(new WidgetPointer(859,29), "Click to view this squad."); + break; + case 56295437: + setWidgetText(new WidgetPointer(859,28), "Attack"); + setWidgetText(new WidgetPointer(859,29), "Select the enemy squad you wish to attack."); + break; + case 56295438: + setWidgetText(new WidgetPointer(859,28), "Move"); + setWidgetText(new WidgetPointer(859,29), "Select the destination for your squad."); + break; + case 56295439: + setWidgetText(new WidgetPointer(859,28), "Explore"); + setWidgetText(new WidgetPointer(859,29), "Send the unit to explore for treasure."); + break; + case 56295440: + if (bitconfig_6357 == 2) { + setWidgetText(new WidgetPointer(859,28), "Attack wall/catapult"); + setWidgetText(new WidgetPointer(859,29), "Select the wall or catapult you want your squad to attack."); + } else if (bitconfig_6357 == 3) { + setWidgetText(new WidgetPointer(859,28), "Collect gold"); + setWidgetText(new WidgetPointer(859,29), "Select the cave entrance from which your squad should gather gold."); + } else { + if (bitconfig_6357 == 4) { + setWidgetText(new WidgetPointer(859,28), "Rescue"); + setWidgetText(new WidgetPointer(859,29), "Select the fissure from which your squad should rescue TzHaar."); + } + } + break; + case 56295441: + if (bitconfig_6357 == 2) { + setWidgetText(new WidgetPointer(859,28), "Collect"); + setWidgetText(new WidgetPointer(859,29), "Select a resource for your squad to collect."); + } else { + if (bitconfig_6357 == 4) { + setWidgetText(new WidgetPointer(859,28), "Steal"); + setWidgetText(new WidgetPointer(859,29), "Select a lander to steal TzHaar from."); + } + } + } + return; +} diff --git a/dumps/scripts/2633.cs2 b/dumps/scripts/2633.cs2 new file mode 100644 index 0000000..538c81a --- /dev/null +++ b/dumps/scripts/2633.cs2 @@ -0,0 +1,8 @@ +void script_2633(int arg0) { + if (arg0 != 56295424) { + script_679(arg0); + } + setWidgetText(new WidgetPointer(859,28), ""); + setWidgetText(new WidgetPointer(859,29), ""); + return; +} diff --git a/dumps/scripts/2634.cs2 b/dumps/scripts/2634.cs2 new file mode 100644 index 0000000..9bda462 --- /dev/null +++ b/dumps/scripts/2634.cs2 @@ -0,0 +1,4 @@ +void script_2634() { + script_2635(); + return; +} diff --git a/dumps/scripts/2635.cs2 b/dumps/scripts/2635.cs2 new file mode 100644 index 0000000..f12718a --- /dev/null +++ b/dumps/scripts/2635.cs2 @@ -0,0 +1,20 @@ +void script_2635() { + globalint_904 = 0; + setScriptCallOnGameloop(-1, "", new WidgetPointer(859,2)); + setWidgetSprite(1914, new WidgetPointer(859,2)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(859,8)); + setWidgetSprite(1915, new WidgetPointer(859,8)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(859,7)); + setWidgetSprite(1916, new WidgetPointer(859,7)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(859,22)); + setWidgetSprite(1917, new WidgetPointer(859,22)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(859,23)); + setWidgetSprite(1921, new WidgetPointer(859,23)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(859,6)); + setWidgetSprite(1918, new WidgetPointer(859,6)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(859,20)); + setWidgetSprite(1919, new WidgetPointer(859,20)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(859,21)); + setWidgetSprite(1920, new WidgetPointer(859,21)); + return; +} diff --git a/dumps/scripts/2636.cs2 b/dumps/scripts/2636.cs2 new file mode 100644 index 0000000..58cd18e --- /dev/null +++ b/dumps/scripts/2636.cs2 @@ -0,0 +1,14 @@ +void script_2636() { + if (bitconfig_6357 == 2) { + cs2method2306(new WidgetPointer(859,16), "Attack wall"); + cs2method2306(new WidgetPointer(859,17), "Collect"); + } else if (bitconfig_6357 == 4) { + cs2method2306(new WidgetPointer(859,16), "Rescue"); + cs2method2306(new WidgetPointer(859,17), "Steal"); + } else { + if (bitconfig_6357 == 3) { + cs2method2306(new WidgetPointer(859,16), "Collect gold"); + } + } + return; +} diff --git a/dumps/scripts/2637.cs2 b/dumps/scripts/2637.cs2 new file mode 100644 index 0000000..e82d733 --- /dev/null +++ b/dumps/scripts/2637.cs2 @@ -0,0 +1,14 @@ +void script_2637() { + if (((boolean)globalint_902)) { + setWidgetSprite(1949, new WidgetPointer(859,24)); + } else if (globalint_902 == 2) { + setWidgetSprite(1946, new WidgetPointer(859,24)); + } else { + if (globalint_902 == 3) { + setWidgetSprite(1947, new WidgetPointer(859,24)); + } + } + setWidgetText(new WidgetPointer(859,28), ""); + setWidgetText(new WidgetPointer(859,29), ""); + return; +} diff --git a/dumps/scripts/2638.cs2 b/dumps/scripts/2638.cs2 new file mode 100644 index 0000000..3ba1f99 --- /dev/null +++ b/dumps/scripts/2638.cs2 @@ -0,0 +1,12 @@ +void script_2638() { + if (((boolean)globalint_903)) { + setWidgetSprite(2023, new WidgetPointer(859,26)); + setWidgetText(new WidgetPointer(859,10), "Light"); + } else { + if (((boolean)globalint_903)) { + setWidgetSprite(2022, new WidgetPointer(859,26)); + setWidgetText(new WidgetPointer(859,10), "Heavy"); + } + } + return; +} diff --git a/dumps/scripts/2639.cs2 b/dumps/scripts/2639.cs2 new file mode 100644 index 0000000..f92c074 --- /dev/null +++ b/dumps/scripts/2639.cs2 @@ -0,0 +1,5 @@ +void script_2639() { + globalint_842 = 0; + script_2642(); + return; +} diff --git a/dumps/scripts/264.cs2 b/dumps/scripts/264.cs2 new file mode 100644 index 0000000..a165ad4 --- /dev/null +++ b/dumps/scripts/264.cs2 @@ -0,0 +1,5 @@ +void script_264(int arg0) { + globalint_1110 = arg0; + script_261(); + return; +} diff --git a/dumps/scripts/2640.cs2 b/dumps/scripts/2640.cs2 new file mode 100644 index 0000000..66af744 --- /dev/null +++ b/dumps/scripts/2640.cs2 @@ -0,0 +1,4 @@ +void script_2640() { + script_2642(); + return; +} diff --git a/dumps/scripts/2641.cs2 b/dumps/scripts/2641.cs2 new file mode 100644 index 0000000..e002f81 --- /dev/null +++ b/dumps/scripts/2641.cs2 @@ -0,0 +1,4 @@ +void script_2641() { + script_2643(); + return; +} diff --git a/dumps/scripts/2642.cs2 b/dumps/scripts/2642.cs2 new file mode 100644 index 0000000..ff876a6 --- /dev/null +++ b/dumps/scripts/2642.cs2 @@ -0,0 +1,89 @@ +void script_2642() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + ivar0 = 0; + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + globalint_842 = 1; + ivar4 = -1; + script_2645(56360984); + deleteAllExtraChilds(new WidgetPointer(860,23)); + setWidgetText(new WidgetPointer(860,19), "A list of items you can trade with Mal for investment credit." + "
" + "Items highlighted with a green rectangle are present in your bank or inventory."); + ivar1 = divide(subtract(getWidgetActualWidth(new WidgetPointer(860,23)), multiply(36, 10)), 10); + ivar2 = divide(subtract(getWidgetActualHeight(new WidgetPointer(860,23)), 128), 3); + ivar5 = 3; + ivar6 = 3; + ivar7 = 0; + while (((boolean)ivar3) && (ivar0 < 900)) { + ivar4 = cs2method_3408(105, 111, 1939, ivar0); + if ((ivar4 != 11760) && (ivar4 != -1)) { + createExtraChild(new WidgetPointer(860,23), 5, ivar0); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(add(ivar5, multiply(add(36, ivar1), mod(ivar0, 10))), add(ivar6, multiply(divide(ivar0, 10), add(32, ivar2))), 0, 0); + setItemOnWidgetMethod1200(ivar4, -1); + cs2method1305("" + getItemName(ivar4)); + setWidgetContextMenuOption(1, "Examine"); + setWidgetShadowColor(new Color(51, 51, 51)); + setWidgetBorderThickness(1); + ivar7 = getWidgetActualY(); + ivar0 = add(ivar0, 1); + } else { + ivar3 = 1; + } + } + ivar8 = 0; + ivar9 = 9999; + ivar10 = 0; + ivar11 = 0; + while (ivar8 <= getItemContainerLength(93)) { + if (getItemIdInSlot(93, ivar8) != -1) { + ivar9 = cs2method_3408(111, 105, 1941, getItemIdInSlot(93, ivar8)); + if (((ivar9 != 9999) && (ivar9 < 900)) && setWidgetRegister(new WidgetPointer(860,23), ivar9)) { + ivar10 = getWidgetActualX(); + ivar11 = getWidgetActualY(); + setWidgetBorderThickness(2); + createExtraChild(new WidgetPointer(860,23), 3, ivar0); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(subtract(ivar10, 1), subtract(ivar11, 1), 0, 0); + setWidgetRGB(new Color(102, 255, 102)); + cs2method2103(150); + ivar0 = add(ivar0, 1); + } + } + ivar8 = add(ivar8, 1); + } + ivar8 = 0; + ivar9 = 9999; + while (ivar8 <= getItemContainerLength(95)) { + if (getItemIdInSlot(95, ivar8) != -1) { + ivar9 = cs2method_3408(111, 105, 1941, getItemIdInSlot(95, ivar8)); + if (((ivar9 != 9999) && (ivar9 < 900)) && setWidgetRegister(new WidgetPointer(860,23), ivar9)) { + ivar10 = getWidgetActualX(); + ivar11 = getWidgetActualY(); + setWidgetBorderThickness(2); + createExtraChild(new WidgetPointer(860,23), 3, ivar0); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(subtract(ivar10, 1), subtract(ivar11, 1), 0, 0); + setWidgetRGB(new Color(102, 255, 102)); + cs2method2103(150); + ivar0 = add(ivar0, 1); + } + } + ivar8 = add(ivar8, 1); + } + setWidgetScrollMax(getWidgetActualWidth(new WidgetPointer(860,23)), add(ivar7, 32), new WidgetPointer(860,23)); + cs2method2100(0, 0, new WidgetPointer(860,23)); + script_31(56360982, 56360983, 792, 789, 790, 791, 773, 788); + return; +} diff --git a/dumps/scripts/2643.cs2 b/dumps/scripts/2643.cs2 new file mode 100644 index 0000000..21daf40 --- /dev/null +++ b/dumps/scripts/2643.cs2 @@ -0,0 +1,95 @@ +void script_2643() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + ivar0 = 900; + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + globalint_842 = 2; + ivar4 = -1; + script_2645(56360984); + deleteAllExtraChilds(new WidgetPointer(860,23)); + setWidgetText(new WidgetPointer(860,19), "A list of items you can trade with Mal for investment credit." + "
" + "Items highlighted with a green rectangle are present in your bank or inventory."); + ivar1 = divide(subtract(getWidgetActualWidth(new WidgetPointer(860,23)), multiply(36, 10)), 10); + ivar2 = divide(subtract(getWidgetActualHeight(new WidgetPointer(860,23)), 128), 3); + ivar5 = 3; + ivar6 = 3; + ivar7 = 0; + while ((((boolean)ivar3) && (ivar0 >= 900)) && (ivar0 < 1800)) { + ivar4 = cs2method_3408(105, 111, 1939, ivar0); + if ((ivar4 != 11760) && (ivar4 != -1)) { + createExtraChild(new WidgetPointer(860,23), 5, subtract(ivar0, 900)); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(add(ivar5, multiply(add(36, ivar1), mod(subtract(ivar0, 900), 10))), add(ivar6, multiply(divide(subtract(ivar0, 900), 10), add(32, ivar2))), 0, 0); + setItemOnWidgetMethod1200(ivar4, -1); + cs2method1305("" + getItemName(ivar4)); + setWidgetContextMenuOption(1, "Examine"); + setWidgetShadowColor(new Color(51, 51, 51)); + setWidgetBorderThickness(1); + ivar7 = getWidgetActualY(); + ivar0 = add(ivar0, 1); + } else { + ivar3 = 1; + } + } + ivar8 = 0; + ivar9 = 9999; + ivar10 = 0; + ivar11 = 0; + while (ivar8 <= getItemContainerLength(93)) { + if (getItemIdInSlot(93, ivar8) != -1) { + ivar9 = cs2method_3408(111, 105, 1941, getItemIdInSlot(93, ivar8)); + if ((ivar9 != 9999) && (ivar9 >= 900)) { + ivar9 = subtract(ivar9, 900); + if (setWidgetRegister(new WidgetPointer(860,23), ivar9)) { + ivar10 = getWidgetActualX(); + ivar11 = getWidgetActualY(); + setWidgetBorderThickness(2); + createExtraChild(new WidgetPointer(860,23), 3, subtract(ivar0, 900)); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(subtract(ivar10, 1), subtract(ivar11, 1), 0, 0); + setWidgetRGB(new Color(102, 255, 102)); + cs2method2103(150); + ivar0 = add(ivar0, 1); + } + } + } + ivar8 = add(ivar8, 1); + } + ivar8 = 0; + ivar9 = 9999; + while (ivar8 <= getItemContainerLength(95)) { + if (getItemIdInSlot(95, ivar8) != -1) { + ivar9 = cs2method_3408(111, 105, 1941, getItemIdInSlot(95, ivar8)); + if ((ivar9 != 9999) && (ivar9 >= 900)) { + ivar9 = subtract(ivar9, 900); + if (setWidgetRegister(new WidgetPointer(860,23), ivar9)) { + ivar10 = getWidgetActualX(); + ivar11 = getWidgetActualY(); + setWidgetBorderThickness(2); + createExtraChild(new WidgetPointer(860,23), 3, subtract(ivar0, 900)); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(subtract(ivar10, 1), subtract(ivar11, 1), 0, 0); + setWidgetRGB(new Color(102, 255, 102)); + cs2method2103(150); + ivar0 = add(ivar0, 1); + } + } + } + ivar8 = add(ivar8, 1); + } + setWidgetScrollMax(getWidgetActualWidth(new WidgetPointer(860,23)), add(ivar7, 32), new WidgetPointer(860,23)); + cs2method2100(0, 0, new WidgetPointer(860,23)); + script_31(56360982, 56360983, 792, 789, 790, 791, 773, 788); + return; +} diff --git a/dumps/scripts/2644.cs2 b/dumps/scripts/2644.cs2 new file mode 100644 index 0000000..f12f07f --- /dev/null +++ b/dumps/scripts/2644.cs2 @@ -0,0 +1,4 @@ +void script_2644(int arg0) { + script_2645(arg0); + return; +} diff --git a/dumps/scripts/2645.cs2 b/dumps/scripts/2645.cs2 new file mode 100644 index 0000000..ec482f6 --- /dev/null +++ b/dumps/scripts/2645.cs2 @@ -0,0 +1,12 @@ +void script_2645(int arg0) { + if (((boolean)globalint_842)) { + setWidgetText(new WidgetPointer(arg0), "Next page"); + setScriptCallOnClickContextMenu(2641, "", new WidgetPointer(860,20)); + } else { + if (globalint_842 == 2) { + setWidgetText(new WidgetPointer(arg0), "Previous page"); + setScriptCallOnClickContextMenu(2640, "", new WidgetPointer(860,20)); + } + } + return; +} diff --git a/dumps/scripts/2646.cs2 b/dumps/scripts/2646.cs2 new file mode 100644 index 0000000..8c686d3 --- /dev/null +++ b/dumps/scripts/2646.cs2 @@ -0,0 +1,83 @@ +void script_2646(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + if (globalint_842 == 3) { + globalint_842 = 1; + setWidgetText(new WidgetPointer(arg0), "Check bank & inventory"); + setWidgetText(new WidgetPointer(860,18), "Commodities"); + setWidgetIsHidden(false, new WidgetPointer(860,20)); + script_2645(56360980); + script_2642(); + return; + } + globalint_842 = 3; + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + ivar4 = 0; + ivar5 = 0; + globalint_842 = 3; + ivar6 = -1; + setWidgetIsHidden(true, new WidgetPointer(860,20)); + setWidgetText(new WidgetPointer(arg0), "View all commodities"); + setWidgetText(new WidgetPointer(860,18), "Commodities in your bank & inventory"); + deleteAllExtraChilds(new WidgetPointer(860,23)); + setWidgetText(new WidgetPointer(860,19), "A list of items already in your inventory or bank that you can trade with Mal for investment credit."); + ivar3 = divide(subtract(getWidgetActualWidth(new WidgetPointer(860,23)), multiply(36, 10)), subtract(10, 1)); + ivar4 = divide(subtract(getWidgetActualHeight(new WidgetPointer(860,23)), 128), 3); + ivar7 = 0; + while (ivar1 <= getItemContainerLength(95)) { + ivar6 = getItemIdInSlot(95, ivar1); + if ((ivar6 != -1) && commonIntegerExists('o', 1939, ivar6)) { + createExtraChild(new WidgetPointer(860,23), 5, ivar2); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(multiply(add(36, ivar3), mod(ivar2, 10)), multiply(divide(ivar2, 10), add(32, ivar4)), 0, 0); + setItemOnWidgetMethod1200(ivar6, -1); + cs2method1305("" + getItemName(ivar6)); + setWidgetContextMenuOption(1, "Examine"); + setWidgetShadowColor(new Color(51, 51, 51)); + setWidgetBorderThickness(1); + ivar2 = add(ivar2, 1); + ivar7 = getWidgetActualY(); + } + ivar1 = add(ivar1, 1); + } + ivar8 = 0; + while (ivar8 <= getItemContainerLength(93)) { + ivar6 = getItemIdInSlot(93, ivar8); + if ((ivar6 != -1) && commonIntegerExists('o', 1939, ivar6)) { + createExtraChild(new WidgetPointer(860,23), 5, ivar2); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(multiply(add(36, ivar3), mod(ivar2, 10)), multiply(divide(ivar2, 10), add(32, ivar4)), 0, 0); + setItemOnWidgetMethod1200(ivar6, -1); + cs2method1305("" + getItemName(ivar6)); + setWidgetContextMenuOption(1, "Examine"); + setWidgetShadowColor(new Color(51, 51, 51)); + setWidgetBorderThickness(1); + ivar2 = add(ivar2, 1); + ivar7 = getWidgetActualY(); + } + ivar8 = add(ivar8, 1); + } + if (((boolean)ivar2)) { + createExtraChild(new WidgetPointer(860,23), 4, ivar2); + setWidgetSize(200, 32, 0, 0); + setWidgetPosition(0, 0, 1, 4); + setWidgetText("No valid commodities were found in your bank or inventory."); + setWidgetFont(496); + setWidgetTextAlignment(1, 1, 0); + setWidgetUnknownBoolean(false); + setWidgetRGB(new Color(255, 152, 31)); + ivar2 = 1; + } + setWidgetScrollMax(getWidgetActualWidth(new WidgetPointer(860,23)), add(ivar7, 32), new WidgetPointer(860,23)); + cs2method2100(0, 0, new WidgetPointer(860,23)); + script_31(56360982, 56360983, 792, 789, 790, 791, 773, 788); + return; +} diff --git a/dumps/scripts/2647.cs2 b/dumps/scripts/2647.cs2 new file mode 100644 index 0000000..3d3e6aa --- /dev/null +++ b/dumps/scripts/2647.cs2 @@ -0,0 +1,25 @@ +void script_2647(int arg0) { + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 1, 0); + setWidgetSize(0, 32, 1, 0); + setWidgetSprite(1076); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 1, 2); + setWidgetSize(0, 32, 1, 0); + setWidgetSprite(1076); + cs2method1107(1); + setWidgetVFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 0, 1); + setWidgetSize(32, 2, 0, 1); + setWidgetSprite(1077); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 2, 1); + setWidgetSize(32, 2, 0, 1); + setWidgetSprite(1077); + cs2method1107(1); + setWidgetHFlip(1); + return; +} diff --git a/dumps/scripts/2648.cs2 b/dumps/scripts/2648.cs2 new file mode 100644 index 0000000..52384a7 --- /dev/null +++ b/dumps/scripts/2648.cs2 @@ -0,0 +1,6 @@ +void script_2648(int arg0,int arg1) { + deleteAllExtraChilds(new WidgetPointer(arg0)); + globalint_2 = 0; + script_679(arg1); + return; +} diff --git a/dumps/scripts/2649.cs2 b/dumps/scripts/2649.cs2 new file mode 100644 index 0000000..51d382d --- /dev/null +++ b/dumps/scripts/2649.cs2 @@ -0,0 +1,4 @@ +void script_2649(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8) { + script_2670(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + return; +} diff --git a/dumps/scripts/265.cs2 b/dumps/scripts/265.cs2 new file mode 100644 index 0000000..948501c --- /dev/null +++ b/dumps/scripts/265.cs2 @@ -0,0 +1,25 @@ +void script_265() { + string svar0; + svar0 = "None"; + switch (globalint_1110) { + case 1: + svar0 = "Standard"; + break; + case 3: + svar0 = "Large"; + break; + case 2: + svar0 = "Slim"; + break; + case 4: + svar0 = "Bone"; + break; + case 5: + svar0 = "Wooden"; + break; + case 6: + svar0 = "Double"; + } + setWidgetText(new WidgetPointer(923,52), svar0); + return; +} diff --git a/dumps/scripts/2650.cs2 b/dumps/scripts/2650.cs2 new file mode 100644 index 0000000..44ea203 --- /dev/null +++ b/dumps/scripts/2650.cs2 @@ -0,0 +1,9 @@ +void script_2650() { + int ivar0; + ivar0 = 1093; + if (IsFemale()) { + ivar0 = 3872; + } + setWidgetSize(getTextWidth(495, cs2method_3408(105, 115, ivar0, standart_config_1442) + cs2method5015() + "" + ":"), getWidgetActualHeight(new WidgetPointer(137,54)), 0, 0, new WidgetPointer(137,54)); + return; +} diff --git a/dumps/scripts/2651.cs2 b/dumps/scripts/2651.cs2 new file mode 100644 index 0000000..f1418c6 --- /dev/null +++ b/dumps/scripts/2651.cs2 @@ -0,0 +1,4 @@ +void script_2651(int arg0) { + script_2308(arg0, 0); + return; +} diff --git a/dumps/scripts/2652.cs2 b/dumps/scripts/2652.cs2 new file mode 100644 index 0000000..f9a60cb --- /dev/null +++ b/dumps/scripts/2652.cs2 @@ -0,0 +1,4 @@ +void script_2652(int arg0) { + script_2309(arg0, 0); + return; +} diff --git a/dumps/scripts/2653.cs2 b/dumps/scripts/2653.cs2 new file mode 100644 index 0000000..ae2102d --- /dev/null +++ b/dumps/scripts/2653.cs2 @@ -0,0 +1,4 @@ +void script_2653() { + setWidgetText(new WidgetPointer(918,7), intToStr(standart_config_1652) + " " + cs2method_3408(105, 115, 950, standart_config_1653) + " " + intToStr(standart_config_1654)); + return; +} diff --git a/dumps/scripts/2654.cs2 b/dumps/scripts/2654.cs2 new file mode 100644 index 0000000..0290273 --- /dev/null +++ b/dumps/scripts/2654.cs2 @@ -0,0 +1,14 @@ +void script_2654() { + if (getDisplayMode() >= 2) { + setWidgetSprite(1207, new WidgetPointer(748,1)); + setWidgetSprite(1207, new WidgetPointer(748,2)); + setWidgetPosition(25, 1, 0, 0, new WidgetPointer(748,3)); + setWidgetPosition(3, 15, 0, 0, new WidgetPointer(748,8)); + } else { + setWidgetSprite(1206, new WidgetPointer(748,1)); + setWidgetSprite(1206, new WidgetPointer(748,2)); + setWidgetPosition(1, 1, 0, 0, new WidgetPointer(748,3)); + setWidgetPosition(31, 15, 0, 0, new WidgetPointer(748,8)); + } + return; +} diff --git a/dumps/scripts/2655.cs2 b/dumps/scripts/2655.cs2 new file mode 100644 index 0000000..eeab54f --- /dev/null +++ b/dumps/scripts/2655.cs2 @@ -0,0 +1,12 @@ +void script_2655(int arg0,int arg1) { + if (arg0 <= 11) { + setWidgetScrollMax(404, 215, new WidgetPointer(868,6)); + script_72(56885255, 56885254, 0); + } else if (((boolean)arg1)) { + script_72(56885255, 56885254, 0); + } else { + script_72(56885255, 56885254, subtract(multiply(arg0, 20), 180)); + } + setWidgetScrollMax(404, multiply(arg0, 20), new WidgetPointer(868,6)); + return; +} diff --git a/dumps/scripts/2656.cs2 b/dumps/scripts/2656.cs2 new file mode 100644 index 0000000..20bbd13 --- /dev/null +++ b/dumps/scripts/2656.cs2 @@ -0,0 +1,31 @@ +int script_2656() { + int ivar0; + int ivar1; + ivar0 = 0; + ivar1 = 0; + ivar0 = add(ivar0, bitconfig_6113); + ivar1 = divide(add(1, bitconfig_6114), 2); + ivar0 = add(ivar0, ivar1); + ivar1 = divide(bitconfig_6115, 2); + ivar0 = add(ivar0, ivar1); + ivar1 = divide(bitconfig_6116, 2); + ivar0 = add(ivar0, ivar1); + ivar1 = add(add(bitconfig_6117, bitconfig_6118), add(bitconfig_6119, bitconfig_6120)); + ivar0 = add(ivar0, ivar1); + ivar0 = add(bitconfig_6121, ivar0); + ivar1 = divide(bitconfig_6122, 2); + ivar0 = add(ivar0, ivar1); + ivar1 = divide(bitconfig_6123, 2); + ivar0 = add(ivar0, ivar1); + ivar1 = divide(bitconfig_6124, 2); + ivar0 = add(ivar0, ivar1); + ivar1 = divide(bitconfig_6125, 2); + ivar0 = add(ivar0, ivar1); + ivar1 = add(add(add(bitconfig_6151, bitconfig_6152), add(bitconfig_6153, bitconfig_6154)), bitconfig_6155); + ivar0 = add(ivar0, ivar1); + ivar0 = multiply(ivar0, 4); + if ((bitconfig_6112 == 20) && (ivar0 > 75)) { + bitconfig_6112 = 50; + } + return ivar0; +} diff --git a/dumps/scripts/2657.cs2 b/dumps/scripts/2657.cs2 new file mode 100644 index 0000000..968501a --- /dev/null +++ b/dumps/scripts/2657.cs2 @@ -0,0 +1,102 @@ +void script_2657() { + bitconfig_6302 = 0; + if (((boolean)bitconfig_6290)) { + setWidgetIsHidden(false, new WidgetPointer(876,4)); + setWidgetIsHidden(true, new WidgetPointer(876,5)); + } + if (((boolean)bitconfig_6290)) { + setWidgetIsHidden(true, new WidgetPointer(876,4)); + cs2method5405(0, 2); + cs2method5405(1, 2); + cs2method5406(0, 0, 53651260, 1450, 53733182, 1385, 0); + cs2method5406(1, 0, 53749565, 700, 53749565, 700, 0); + cs2method5406(0, 1, 53765948, 1125, 53782331, 1000, 0); + cs2method5406(1, 1, 53765942, 600, 53765942, 600, 0); + cameraMethod5502(0, 0, 250, 350, 1, 0); + } + if (bitconfig_6290 == 2) { + cs2method5405(0, 3); + cs2method5405(1, 3); + cs2method5406(0, 0, 53798717, 1065, 53798718, 1130, 0); + cs2method5406(1, 0, 53782326, 600, 53782326, 600, 0); + cs2method5406(0, 1, 53831484, 1140, 53880637, 1105, 0); + cs2method5406(1, 1, 53913403, 600, 53946170, 600, 0); + cs2method5406(0, 2, 53897019, 825, 53913404, 565, 0); + cs2method5406(1, 2, 53897015, 600, 53864247, 600, 0); + cameraMethod5502(0, 0, 250, 350, 1, 0); + setScriptCallOnMinimapRelatedSetting3(2658, "", new WidgetPointer(876,0)); + } + if (bitconfig_6290 == 3) { + setWidgetIsHidden(true, new WidgetPointer(876,4)); + cs2method5405(0, 4); + cs2method5405(1, 4); + cs2method5406(0, 0, 55027504, 805, 54978351, 650, 0); + cs2method5406(1, 0, 55027497, 620, 55027497, 580, 0); + cs2method5406(0, 1, 55043882, 725, 55093034, 650, 0); + cs2method5406(1, 1, 55109414, 555, 55109414, 505, 0); + cs2method5406(0, 2, 55191335, 800, 55207717, 740, 0); + cs2method5406(1, 2, 55207715, 525, 55207714, 505, 0); + cs2method5406(0, 3, 55224098, 745, 55224096, 650, 0); + cs2method5406(1, 3, 55224092, 600, 55240475, 670, 0); + cameraMethod5502(0, 0, 300, 400, 1, 0); + setScriptCallOnMinimapRelatedSetting3(2658, "", new WidgetPointer(876,0)); + } + if (bitconfig_6290 == 4) { + setWidgetIsHidden(true, new WidgetPointer(876,4)); + cs2method5405(0, 3); + cs2method5405(1, 3); + cs2method5406(0, 0, 53782327, 1125, 53798710, 1085, 0); + cs2method5406(1, 0, 53782322, 750, 53782323, 750, 0); + cs2method5406(0, 1, 53798703, 1015, 53782318, 865, 0); + cs2method5406(1, 1, 53733165, 750, 53733167, 750, 0); + cs2method5406(0, 2, 53684015, 980, 53651247, 865, 0); + cs2method5406(1, 2, 53651241, 620, 53651240, 540, 0); + cameraMethod5502(0, 0, 300, 400, 1, 0); + setScriptCallOnMinimapRelatedSetting3(2658, "", new WidgetPointer(876,0)); + } + if (bitconfig_6290 == 5) { + setWidgetIsHidden(false, new WidgetPointer(876,5)); + } + if (bitconfig_6290 == 6) { + cs2method5405(0, 6); + cs2method5405(0, 6); + cs2method5405(1, 6); + cs2method5406(0, 0, 53684015, 980, 53651247, 1185, 0); + cs2method5406(1, 0, 53651241, 620, 53651240, 540, 0); + cs2method5406(0, 1, 53749551, 1190, 53765935, 1165, 0); + cs2method5406(1, 1, 53798702, 750, 53847854, 750, 0); + cs2method5406(0, 2, 53815087, 1220, 53847854, 1190, 0); + cs2method5406(1, 2, 53864237, 750, 53880620, 750, 0); + cs2method5406(0, 3, 53864238, 1160, 53897005, 1135, 0); + cs2method5406(1, 3, 53897001, 750, 53913383, 750, 0); + cs2method5406(0, 4, 53897003, 1045, 53913386, 1005, 0); + cs2method5406(1, 4, 53929766, 750, 53946149, 750, 0); + cs2method5406(0, 5, 53913383, 975, 53913384, 920, 0); + cs2method5406(1, 5, 53978919, 725, 53978920, 725, 0); + cameraMethod5502(0, 0, 500, 600, 1, 0); + setScriptCallOnMinimapRelatedSetting3(2658, "", new WidgetPointer(876,0)); + } + if (bitconfig_6290 == 7) { + setWidgetIsHidden(true, new WidgetPointer(876,5)); + cs2method5405(0, 2); + cs2method5405(1, 2); + cs2method5406(0, 0, 53913383, 975, 53929767, 1410, 0); + cs2method5406(1, 0, 53978919, 725, 54011687, 725, 0); + cs2method5406(0, 1, 53978919, 915, 53995303, 800, 0); + cs2method5406(1, 1, 54060839, 650, 54060839, 725, 0); + cameraMethod5502(0, 0, 400, 200, 1, 0); + setScriptCallOnMinimapRelatedSetting3(2658, "", new WidgetPointer(876,0)); + } + if (bitconfig_6290 == 8) { + setWidgetIsHidden(true, new WidgetPointer(876,5)); + cs2method5405(0, 2); + cs2method5405(1, 2); + cs2method5406(0, 0, 53978919, 915, 53995303, 960, 0); + cs2method5406(1, 0, 54060839, 650, 54060839, 725, 0); + cs2method5406(0, 1, 54093606, 985, 54093606, 950, 0); + cs2method5406(1, 1, 54142759, 800, 54142759, 800, 0); + cameraMethod5502(0, 0, 400, 200, 1, 0); + setScriptCallOnMinimapRelatedSetting3(2658, "", new WidgetPointer(876,0)); + } + return; +} diff --git a/dumps/scripts/2658.cs2 b/dumps/scripts/2658.cs2 new file mode 100644 index 0000000..a08eb6d --- /dev/null +++ b/dumps/scripts/2658.cs2 @@ -0,0 +1,11 @@ +void script_2658() { + bitconfig_6302 = add(bitconfig_6302, 1); + if (bitconfig_6302 >= subtract(cs2method5407(0), 1)) { + bitconfig_6302 = 0; + setScriptCallOnMinimapRelatedSetting3(-1, "", new WidgetPointer(876,0)); + return; + } + cameraMethod5502(0, bitconfig_6302, 600, 400, 1, bitconfig_6302); + setScriptCallOnMinimapRelatedSetting3(2658, "", new WidgetPointer(876,0)); + return; +} diff --git a/dumps/scripts/2659.cs2 b/dumps/scripts/2659.cs2 new file mode 100644 index 0000000..589a43d --- /dev/null +++ b/dumps/scripts/2659.cs2 @@ -0,0 +1,11 @@ +void script_2659() { + setWidgetIsHidden(true, new WidgetPointer(866,5)); + setWidgetIsHidden(false, new WidgetPointer(866,10)); + setWidgetIsHidden(false, new WidgetPointer(866,8)); + setWidgetIsHidden(true, new WidgetPointer(866,13)); + setWidgetIsHidden(false, new WidgetPointer(866,7)); + setWidgetIsHidden(true, new WidgetPointer(866,12)); + setWidgetIsHidden(false, new WidgetPointer(866,6)); + setWidgetIsHidden(true, new WidgetPointer(866,11)); + return; +} diff --git a/dumps/scripts/266.cs2 b/dumps/scripts/266.cs2 new file mode 100644 index 0000000..31df83c --- /dev/null +++ b/dumps/scripts/266.cs2 @@ -0,0 +1,28 @@ +void script_266() { + string svar0; + globalarray_0 = new int[4]; + globalarray_0[globalint_1104] = add(globalarray_0[globalint_1104], 1); + globalarray_0[globalint_1105] = add(globalarray_0[globalint_1105], 1); + globalarray_0[globalint_1106] = add(globalarray_0[globalint_1106], 1); + globalarray_0[globalint_1107] = add(globalarray_0[globalint_1107], 1); + globalarray_0[globalint_1108] = add(globalarray_0[globalint_1108], 1); + setWidgetText(new WidgetPointer(923,53), "Small x " + intToStr(globalarray_0[1])); + setWidgetText(new WidgetPointer(923,54), "Med. x " + intToStr(globalarray_0[2])); + setWidgetText(new WidgetPointer(923,55), "Large x " + intToStr(globalarray_0[3])); + svar0 = ""; + if (globalarray_0[1] > 0) { + svar0 = "Remove-weight"; + } + setWidgetContextMenuOption(1, new WidgetPointer(923,53), svar0); + svar0 = ""; + if (globalarray_0[2] > 0) { + svar0 = "Remove-weight"; + } + setWidgetContextMenuOption(1, new WidgetPointer(923,54), svar0); + svar0 = ""; + if (globalarray_0[3] > 0) { + svar0 = "Remove-weight"; + } + setWidgetContextMenuOption(1, new WidgetPointer(923,55), svar0); + return; +} diff --git a/dumps/scripts/2660.cs2 b/dumps/scripts/2660.cs2 new file mode 100644 index 0000000..677fbf6 --- /dev/null +++ b/dumps/scripts/2660.cs2 @@ -0,0 +1,11 @@ +void script_2660() { + setWidgetIsHidden(false, new WidgetPointer(866,5)); + setWidgetIsHidden(true, new WidgetPointer(866,10)); + setWidgetIsHidden(true, new WidgetPointer(866,8)); + setWidgetIsHidden(false, new WidgetPointer(866,13)); + setWidgetIsHidden(false, new WidgetPointer(866,7)); + setWidgetIsHidden(true, new WidgetPointer(866,12)); + setWidgetIsHidden(false, new WidgetPointer(866,6)); + setWidgetIsHidden(true, new WidgetPointer(866,11)); + return; +} diff --git a/dumps/scripts/2661.cs2 b/dumps/scripts/2661.cs2 new file mode 100644 index 0000000..c41c9e1 --- /dev/null +++ b/dumps/scripts/2661.cs2 @@ -0,0 +1,11 @@ +void script_2661() { + setWidgetIsHidden(false, new WidgetPointer(866,5)); + setWidgetIsHidden(true, new WidgetPointer(866,10)); + setWidgetIsHidden(false, new WidgetPointer(866,8)); + setWidgetIsHidden(true, new WidgetPointer(866,13)); + setWidgetIsHidden(true, new WidgetPointer(866,7)); + setWidgetIsHidden(false, new WidgetPointer(866,12)); + setWidgetIsHidden(false, new WidgetPointer(866,6)); + setWidgetIsHidden(true, new WidgetPointer(866,11)); + return; +} diff --git a/dumps/scripts/2662.cs2 b/dumps/scripts/2662.cs2 new file mode 100644 index 0000000..f994792 --- /dev/null +++ b/dumps/scripts/2662.cs2 @@ -0,0 +1,11 @@ +void script_2662() { + setWidgetIsHidden(false, new WidgetPointer(866,5)); + setWidgetIsHidden(true, new WidgetPointer(866,10)); + setWidgetIsHidden(false, new WidgetPointer(866,8)); + setWidgetIsHidden(true, new WidgetPointer(866,13)); + setWidgetIsHidden(false, new WidgetPointer(866,7)); + setWidgetIsHidden(true, new WidgetPointer(866,12)); + setWidgetIsHidden(true, new WidgetPointer(866,6)); + setWidgetIsHidden(false, new WidgetPointer(866,11)); + return; +} diff --git a/dumps/scripts/2663.cs2 b/dumps/scripts/2663.cs2 new file mode 100644 index 0000000..14ef341 --- /dev/null +++ b/dumps/scripts/2663.cs2 @@ -0,0 +1,12 @@ +void script_2663() { + int ivar0; + int ivar1; + ivar0 = ((int)cs2method_3408(105, 73, 2566, bitconfig_6297)); + ivar1 = ((int)cs2method_3408(105, 73, 2565, bitconfig_6297)); + if (getWidgetActualX(new WidgetPointer(ivar0)) > 3) { + playSoundEffect2False(7570, 1, 0, 50); + setWidgetPosition(subtract(getWidgetActualX(new WidgetPointer(ivar0)), 2), getWidgetActualY(new WidgetPointer(ivar0)), 0, 0, new WidgetPointer(ivar0)); + setWidgetPosition(subtract(getWidgetActualX(new WidgetPointer(ivar1)), 2), getWidgetActualY(new WidgetPointer(ivar1)), 0, 0, new WidgetPointer(ivar1)); + } + return; +} diff --git a/dumps/scripts/2664.cs2 b/dumps/scripts/2664.cs2 new file mode 100644 index 0000000..2d8d714 --- /dev/null +++ b/dumps/scripts/2664.cs2 @@ -0,0 +1,12 @@ +void script_2664() { + int ivar0; + int ivar1; + ivar0 = ((int)cs2method_3408(105, 73, 2566, bitconfig_6297)); + ivar1 = ((int)cs2method_3408(105, 73, 2565, bitconfig_6297)); + if (getWidgetActualX(new WidgetPointer(ivar0)) < 353) { + playSoundEffect2False(7570, 1, 0, 50); + setWidgetPosition(add(getWidgetActualX(new WidgetPointer(ivar0)), 2), getWidgetActualY(new WidgetPointer(ivar0)), 0, 0, new WidgetPointer(ivar0)); + setWidgetPosition(add(getWidgetActualX(new WidgetPointer(ivar1)), 2), getWidgetActualY(new WidgetPointer(ivar1)), 0, 0, new WidgetPointer(ivar1)); + } + return; +} diff --git a/dumps/scripts/2665.cs2 b/dumps/scripts/2665.cs2 new file mode 100644 index 0000000..deadb76 --- /dev/null +++ b/dumps/scripts/2665.cs2 @@ -0,0 +1,12 @@ +void script_2665() { + int ivar0; + int ivar1; + ivar0 = ((int)cs2method_3408(105, 73, 2566, bitconfig_6297)); + ivar1 = ((int)cs2method_3408(105, 73, 2565, bitconfig_6297)); + if (getWidgetActualY(new WidgetPointer(ivar0)) > -13) { + playSoundEffect2False(7570, 1, 0, 50); + setWidgetPosition(getWidgetActualX(new WidgetPointer(ivar0)), subtract(getWidgetActualY(new WidgetPointer(ivar0)), 2), 0, 0, new WidgetPointer(ivar0)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(ivar1)), subtract(getWidgetActualY(new WidgetPointer(ivar1)), 2), 0, 0, new WidgetPointer(ivar1)); + } + return; +} diff --git a/dumps/scripts/2666.cs2 b/dumps/scripts/2666.cs2 new file mode 100644 index 0000000..b41a5d7 --- /dev/null +++ b/dumps/scripts/2666.cs2 @@ -0,0 +1,12 @@ +void script_2666() { + int ivar0; + int ivar1; + ivar0 = ((int)cs2method_3408(105, 73, 2566, bitconfig_6297)); + ivar1 = ((int)cs2method_3408(105, 73, 2565, bitconfig_6297)); + if (getWidgetActualY(new WidgetPointer(ivar0)) < 293) { + playSoundEffect2False(7570, 1, 0, 50); + setWidgetPosition(getWidgetActualX(new WidgetPointer(ivar0)), add(getWidgetActualY(new WidgetPointer(ivar0)), 2), 0, 0, new WidgetPointer(ivar0)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(ivar1)), add(getWidgetActualY(new WidgetPointer(ivar1)), 2), 0, 0, new WidgetPointer(ivar1)); + } + return; +} diff --git a/dumps/scripts/2667.cs2 b/dumps/scripts/2667.cs2 new file mode 100644 index 0000000..48f28e1 --- /dev/null +++ b/dumps/scripts/2667.cs2 @@ -0,0 +1,55 @@ +void script_2667() { + int ivar0; + int ivar1; + ivar0 = ((int)cs2method_3408(105, 73, 2566, bitconfig_6297)); + ivar1 = ((int)cs2method_3408(105, 73, 2565, bitconfig_6297)); + if ((getWidgetActualX(new WidgetPointer(ivar0)) < 17) || (getWidgetActualX(new WidgetPointer(ivar0)) > 57)) { + return; + } + if ((getWidgetActualY(new WidgetPointer(ivar0)) > 12) && (getWidgetActualY(new WidgetPointer(ivar0)) < 32)) { + setWidgetPosition(37, 22, 0, 0, new WidgetPointer(ivar0)); + setWidgetPosition(37, 22, 0, 0, new WidgetPointer(ivar1)); + return; + } + if ((getWidgetActualY(new WidgetPointer(ivar0)) > 38) && (getWidgetActualY(new WidgetPointer(ivar0)) < 58)) { + setWidgetPosition(37, 48, 0, 0, new WidgetPointer(ivar0)); + setWidgetPosition(37, 48, 0, 0, new WidgetPointer(ivar1)); + return; + } + if ((getWidgetActualY(new WidgetPointer(ivar0)) > 70) && (getWidgetActualY(new WidgetPointer(ivar0)) < 90)) { + setWidgetPosition(37, 80, 0, 0, new WidgetPointer(ivar0)); + setWidgetPosition(37, 80, 0, 0, new WidgetPointer(ivar1)); + return; + } + if ((getWidgetActualY(new WidgetPointer(ivar0)) > 98) && (getWidgetActualY(new WidgetPointer(ivar0)) < 118)) { + setWidgetPosition(37, 108, 0, 0, new WidgetPointer(ivar0)); + setWidgetPosition(37, 108, 0, 0, new WidgetPointer(ivar1)); + return; + } + if ((getWidgetActualY(new WidgetPointer(ivar0)) > 128) && (getWidgetActualY(new WidgetPointer(ivar0)) < 148)) { + setWidgetPosition(37, 138, 0, 0, new WidgetPointer(ivar0)); + setWidgetPosition(37, 138, 0, 0, new WidgetPointer(ivar1)); + return; + } + if ((getWidgetActualY(new WidgetPointer(ivar0)) > 156) && (getWidgetActualY(new WidgetPointer(ivar0)) < 176)) { + setWidgetPosition(37, 166, 0, 0, new WidgetPointer(ivar0)); + setWidgetPosition(37, 166, 0, 0, new WidgetPointer(ivar1)); + return; + } + if ((getWidgetActualY(new WidgetPointer(ivar0)) > 184) && (getWidgetActualY(new WidgetPointer(ivar0)) < 204)) { + setWidgetPosition(37, 194, 0, 0, new WidgetPointer(ivar0)); + setWidgetPosition(37, 194, 0, 0, new WidgetPointer(ivar1)); + return; + } + if ((getWidgetActualY(new WidgetPointer(ivar0)) > 214) && (getWidgetActualY(new WidgetPointer(ivar0)) < 234)) { + setWidgetPosition(37, 224, 0, 0, new WidgetPointer(ivar0)); + setWidgetPosition(37, 224, 0, 0, new WidgetPointer(ivar1)); + return; + } + if ((getWidgetActualY(new WidgetPointer(ivar0)) > 242) && (getWidgetActualY(new WidgetPointer(ivar0)) < 262)) { + setWidgetPosition(37, 252, 0, 0, new WidgetPointer(ivar0)); + setWidgetPosition(37, 252, 0, 0, new WidgetPointer(ivar1)); + return; + } + return; +} diff --git a/dumps/scripts/2668.cs2 b/dumps/scripts/2668.cs2 new file mode 100644 index 0000000..4f59a22 --- /dev/null +++ b/dumps/scripts/2668.cs2 @@ -0,0 +1,9 @@ +void script_2668() { + if (((boolean)bitconfig_6303)) { + setWidgetIsHidden(true, new WidgetPointer(866,5)); + setWidgetIsHidden(true, new WidgetPointer(866,8)); + setWidgetIsHidden(true, new WidgetPointer(866,7)); + setWidgetIsHidden(true, new WidgetPointer(866,6)); + } + return; +} diff --git a/dumps/scripts/2669.cs2 b/dumps/scripts/2669.cs2 new file mode 100644 index 0000000..d5a4caa --- /dev/null +++ b/dumps/scripts/2669.cs2 @@ -0,0 +1,33 @@ +void script_2669() { + if (((boolean)bitconfig_6304)) { + setWidgetModel(48047, new WidgetPointer(866,64)); + } + if (((boolean)bitconfig_6304)) { + setWidgetModel(48028, new WidgetPointer(866,64)); + } + if (bitconfig_6304 == 2) { + setWidgetModel(48038, new WidgetPointer(866,64)); + } + if (bitconfig_6304 == 3) { + setWidgetModel(48027, new WidgetPointer(866,64)); + } + if (bitconfig_6304 == 4) { + setWidgetModel(48030, new WidgetPointer(866,64)); + } + if (bitconfig_6304 == 5) { + setWidgetModel(48052, new WidgetPointer(866,64)); + } + if (bitconfig_6304 == 6) { + setWidgetModel(48051, new WidgetPointer(866,64)); + } + if (bitconfig_6304 == 7) { + setWidgetModel(48050, new WidgetPointer(866,64)); + } + if (bitconfig_6304 == 8) { + setWidgetModel(48015, new WidgetPointer(866,64)); + } + if (bitconfig_6304 == 9) { + setWidgetModel(48029, new WidgetPointer(866,64)); + } + return; +} diff --git a/dumps/scripts/267.cs2 b/dumps/scripts/267.cs2 new file mode 100644 index 0000000..a50fb5a --- /dev/null +++ b/dumps/scripts/267.cs2 @@ -0,0 +1,40 @@ +void script_267(int arg0) { + int ivar1; + int ivar2; + int ivar3; + if (script_269() >= 5) { + return; + } + globalarray_0 = new int[5]; + globalarray_0[0] = globalint_1104; + globalarray_0[1] = globalint_1105; + globalarray_0[2] = globalint_1106; + globalarray_0[3] = globalint_1107; + globalarray_0[4] = globalint_1108; + globalarray_1 = new int[5]; + ivar1 = 0; + ivar2 = 0; + ivar3 = 3; + while (ivar3 > 0) { + if (arg0 == ivar3) { + globalarray_0[ivar2] = arg0; + ivar2 = add(ivar2, 1); + } + ivar1 = 0; + while (ivar1 < 5) { + if (globalarray_0[ivar1] == ivar3) { + globalarray_0[ivar2] = ivar3; + ivar2 = add(ivar2, 1); + } + ivar1 = add(ivar1, 1); + } + ivar3 = subtract(ivar3, 1); + } + globalint_1104 = globalarray_1[0]; + globalint_1105 = globalarray_1[1]; + globalint_1106 = globalarray_1[2]; + globalint_1107 = globalarray_1[3]; + globalint_1108 = globalarray_1[4]; + script_261(); + return; +} diff --git a/dumps/scripts/2670.cs2 b/dumps/scripts/2670.cs2 new file mode 100644 index 0000000..c41e48f --- /dev/null +++ b/dumps/scripts/2670.cs2 @@ -0,0 +1,112 @@ +void script_2670(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8) { + int ivar9; + int ivar10; + ivar9 = 952; + ivar10 = 953; + if (((boolean)arg8)) { + globalint_91 = 0; + setWidgetIsHidden(true, new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(arg4)); + setWidgetIsHidden(false, new WidgetPointer(arg1)); + setWidgetIsHidden(true, new WidgetPointer(arg6)); + setWidgetNoOptions(new WidgetPointer(arg3)); + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(arg3)); + setWidgetSprite(ivar10, new WidgetPointer(arg7)); + setWidgetSprite(ivar10, new WidgetPointer(arg5)); + setWidgetSprite(ivar10, new WidgetPointer(arg2)); + setWidgetSprite(ivar9, new WidgetPointer(arg3)); + setScriptCallOnMouseEntered(-1, "", new WidgetPointer(arg3)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg3)); + setWidgetContextMenuOption(1, new WidgetPointer(arg2), "Clan"); + setScriptCallOnClickContextMenu(2649, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), new WidgetPointer(arg6), new WidgetPointer(arg7), 1, "IIIIIIIIi", new WidgetPointer(arg2)); + setScriptCallOnMouseEntered(44, new WidgetPointer(-32768,3), ivar9, "Id", new WidgetPointer(arg2)); + setScriptCallOnMouseExit(44, new WidgetPointer(-32768,3), ivar10, "Id", new WidgetPointer(arg2)); + setWidgetContextMenuOption(1, new WidgetPointer(arg5), "Friend"); + setScriptCallOnClickContextMenu(2649, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), new WidgetPointer(arg6), new WidgetPointer(arg7), 2, "IIIIIIIIi", new WidgetPointer(arg5)); + setScriptCallOnMouseEntered(44, new WidgetPointer(-32768,3), ivar9, "Id", new WidgetPointer(arg5)); + setScriptCallOnMouseExit(44, new WidgetPointer(-32768,3), ivar10, "Id", new WidgetPointer(arg5)); + setWidgetContextMenuOption(1, new WidgetPointer(arg7), "Guest"); + setScriptCallOnClickContextMenu(2649, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), new WidgetPointer(arg6), new WidgetPointer(arg7), 3, "IIIIIIIIi", new WidgetPointer(arg7)); + setScriptCallOnMouseEntered(44, new WidgetPointer(-32768,3), ivar9, "Id", new WidgetPointer(arg7)); + setScriptCallOnMouseExit(44, new WidgetPointer(-32768,3), ivar10, "Id", new WidgetPointer(arg7)); + } else if (((boolean)arg8)) { + globalint_91 = 1; + setWidgetIsHidden(false, new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(arg1)); + setWidgetIsHidden(true, new WidgetPointer(arg4)); + setWidgetIsHidden(true, new WidgetPointer(arg6)); + setWidgetNoOptions(new WidgetPointer(arg2)); + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(arg2)); + setWidgetSprite(ivar10, new WidgetPointer(arg7)); + setWidgetSprite(ivar10, new WidgetPointer(arg5)); + setWidgetSprite(ivar9, new WidgetPointer(arg2)); + setWidgetSprite(ivar10, new WidgetPointer(arg3)); + setScriptCallOnMouseEntered(-1, "", new WidgetPointer(arg2)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg2)); + setWidgetContextMenuOption(1, new WidgetPointer(arg3), "Private"); + setScriptCallOnClickContextMenu(2649, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), new WidgetPointer(arg6), new WidgetPointer(arg7), 0, "IIIIIIIIi", new WidgetPointer(arg3)); + setScriptCallOnMouseEntered(44, new WidgetPointer(-32768,3), ivar9, "Id", new WidgetPointer(arg3)); + setScriptCallOnMouseExit(44, new WidgetPointer(-32768,3), ivar10, "Id", new WidgetPointer(arg3)); + setWidgetContextMenuOption(1, new WidgetPointer(arg5), "Friend"); + setScriptCallOnClickContextMenu(2649, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), new WidgetPointer(arg6), new WidgetPointer(arg7), 2, "IIIIIIIIi", new WidgetPointer(arg5)); + setScriptCallOnMouseEntered(44, new WidgetPointer(-32768,3), ivar9, "Id", new WidgetPointer(arg5)); + setScriptCallOnMouseExit(44, new WidgetPointer(-32768,3), ivar10, "Id", new WidgetPointer(arg5)); + setWidgetContextMenuOption(1, new WidgetPointer(arg7), "Guest"); + setScriptCallOnClickContextMenu(2649, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), new WidgetPointer(arg6), new WidgetPointer(arg7), 3, "IIIIIIIIi", new WidgetPointer(arg7)); + setScriptCallOnMouseEntered(44, new WidgetPointer(-32768,3), ivar9, "Id", new WidgetPointer(arg7)); + setScriptCallOnMouseExit(44, new WidgetPointer(-32768,3), ivar10, "Id", new WidgetPointer(arg7)); + } else if (arg8 == 2) { + globalint_91 = 2; + setWidgetIsHidden(false, new WidgetPointer(arg4)); + setWidgetIsHidden(true, new WidgetPointer(arg1)); + setWidgetIsHidden(true, new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(arg6)); + setWidgetNoOptions(new WidgetPointer(arg5)); + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(arg5)); + setWidgetSprite(ivar10, new WidgetPointer(arg7)); + setWidgetSprite(ivar9, new WidgetPointer(arg5)); + setWidgetSprite(ivar10, new WidgetPointer(arg2)); + setWidgetSprite(ivar10, new WidgetPointer(arg3)); + setScriptCallOnMouseEntered(-1, "", new WidgetPointer(arg5)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg5)); + setWidgetContextMenuOption(1, new WidgetPointer(arg3), "Private"); + setScriptCallOnClickContextMenu(2649, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), new WidgetPointer(arg6), new WidgetPointer(arg7), 0, "IIIIIIIIi", new WidgetPointer(arg3)); + setScriptCallOnMouseEntered(44, new WidgetPointer(-32768,3), ivar9, "Id", new WidgetPointer(arg3)); + setScriptCallOnMouseExit(44, new WidgetPointer(-32768,3), ivar10, "Id", new WidgetPointer(arg3)); + setWidgetContextMenuOption(1, new WidgetPointer(arg2), "Clan"); + setScriptCallOnClickContextMenu(2649, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), new WidgetPointer(arg6), new WidgetPointer(arg7), 1, "IIIIIIIIi", new WidgetPointer(arg2)); + setScriptCallOnMouseEntered(44, new WidgetPointer(-32768,3), ivar9, "Id", new WidgetPointer(arg2)); + setScriptCallOnMouseExit(44, new WidgetPointer(-32768,3), ivar10, "Id", new WidgetPointer(arg2)); + setWidgetContextMenuOption(1, new WidgetPointer(arg7), "Guest"); + setScriptCallOnClickContextMenu(2649, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), new WidgetPointer(arg6), new WidgetPointer(arg7), 3, "IIIIIIIIi", new WidgetPointer(arg7)); + setScriptCallOnMouseEntered(44, new WidgetPointer(-32768,3), ivar9, "Id", new WidgetPointer(arg7)); + setScriptCallOnMouseExit(44, new WidgetPointer(-32768,3), ivar10, "Id", new WidgetPointer(arg7)); + } else { + globalint_91 = 3; + setWidgetIsHidden(false, new WidgetPointer(arg6)); + setWidgetIsHidden(true, new WidgetPointer(arg1)); + setWidgetIsHidden(true, new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(arg4)); + setWidgetNoOptions(new WidgetPointer(arg7)); + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(arg7)); + setWidgetSprite(ivar9, new WidgetPointer(arg7)); + setWidgetSprite(ivar10, new WidgetPointer(arg5)); + setWidgetSprite(ivar10, new WidgetPointer(arg2)); + setWidgetSprite(ivar10, new WidgetPointer(arg3)); + setScriptCallOnMouseEntered(-1, "", new WidgetPointer(arg7)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg7)); + setWidgetContextMenuOption(1, new WidgetPointer(arg3), "Private"); + setScriptCallOnClickContextMenu(2649, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), new WidgetPointer(arg6), new WidgetPointer(arg7), 0, "IIIIIIIIi", new WidgetPointer(arg3)); + setScriptCallOnMouseEntered(44, new WidgetPointer(-32768,3), ivar9, "Id", new WidgetPointer(arg3)); + setScriptCallOnMouseExit(44, new WidgetPointer(-32768,3), ivar10, "Id", new WidgetPointer(arg3)); + setWidgetContextMenuOption(1, new WidgetPointer(arg2), "Clan"); + setScriptCallOnClickContextMenu(2649, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), new WidgetPointer(arg6), new WidgetPointer(arg7), 1, "IIIIIIIIi", new WidgetPointer(arg2)); + setScriptCallOnMouseEntered(44, new WidgetPointer(-32768,3), ivar9, "Id", new WidgetPointer(arg2)); + setScriptCallOnMouseExit(44, new WidgetPointer(-32768,3), ivar10, "Id", new WidgetPointer(arg2)); + setWidgetContextMenuOption(1, new WidgetPointer(arg5), "Friend"); + setScriptCallOnClickContextMenu(2649, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), new WidgetPointer(arg6), new WidgetPointer(arg7), 2, "IIIIIIIIi", new WidgetPointer(arg5)); + setScriptCallOnMouseEntered(44, new WidgetPointer(-32768,3), ivar9, "Id", new WidgetPointer(arg5)); + setScriptCallOnMouseExit(44, new WidgetPointer(-32768,3), ivar10, "Id", new WidgetPointer(arg5)); + } + return; +} diff --git a/dumps/scripts/2671.cs2 b/dumps/scripts/2671.cs2 new file mode 100644 index 0000000..5c56670 --- /dev/null +++ b/dumps/scripts/2671.cs2 @@ -0,0 +1,52 @@ +void script_2671() { + if (((boolean)bitconfig_6454)) { + setWidgetIsHidden(false, new WidgetPointer(747,18)); + setWidgetIsHidden(true, new WidgetPointer(747,9)); + } else { + setWidgetIsHidden(true, new WidgetPointer(747,18)); + setWidgetIsHidden(false, new WidgetPointer(747,9)); + } + if (bitconfig_6454 == 2) { + setWidgetIsHidden(false, new WidgetPointer(747,23)); + setWidgetIsHidden(true, new WidgetPointer(747,14)); + } else { + setWidgetIsHidden(true, new WidgetPointer(747,23)); + setWidgetIsHidden(false, new WidgetPointer(747,14)); + } + if (bitconfig_6454 == 3) { + setWidgetIsHidden(false, new WidgetPointer(747,19)); + setWidgetIsHidden(true, new WidgetPointer(747,10)); + } else { + setWidgetIsHidden(true, new WidgetPointer(747,19)); + setWidgetIsHidden(false, new WidgetPointer(747,10)); + } + if (bitconfig_6454 == 4) { + setWidgetIsHidden(false, new WidgetPointer(747,20)); + setWidgetIsHidden(true, new WidgetPointer(747,11)); + } else { + setWidgetIsHidden(true, new WidgetPointer(747,20)); + setWidgetIsHidden(false, new WidgetPointer(747,11)); + } + if (bitconfig_6454 == 5) { + setWidgetIsHidden(false, new WidgetPointer(747,21)); + setWidgetIsHidden(true, new WidgetPointer(747,12)); + } else { + setWidgetIsHidden(true, new WidgetPointer(747,21)); + setWidgetIsHidden(false, new WidgetPointer(747,12)); + } + if (bitconfig_6454 == 6) { + setWidgetIsHidden(false, new WidgetPointer(747,22)); + setWidgetIsHidden(true, new WidgetPointer(747,13)); + } else { + setWidgetIsHidden(true, new WidgetPointer(747,22)); + setWidgetIsHidden(false, new WidgetPointer(747,13)); + } + if (bitconfig_6454 == 7) { + setWidgetIsHidden(false, new WidgetPointer(747,26)); + setWidgetIsHidden(true, new WidgetPointer(747,15)); + } else { + setWidgetIsHidden(true, new WidgetPointer(747,26)); + setWidgetIsHidden(false, new WidgetPointer(747,15)); + } + return; +} diff --git a/dumps/scripts/2672.cs2 b/dumps/scripts/2672.cs2 new file mode 100644 index 0000000..6559235 --- /dev/null +++ b/dumps/scripts/2672.cs2 @@ -0,0 +1,4 @@ +void script_2672() { + script_2674(bitconfig_6455); + return; +} diff --git a/dumps/scripts/2673.cs2 b/dumps/scripts/2673.cs2 new file mode 100644 index 0000000..6ecc7d7 --- /dev/null +++ b/dumps/scripts/2673.cs2 @@ -0,0 +1,4 @@ +void script_2673(int arg0) { + script_2674(arg0); + return; +} diff --git a/dumps/scripts/2674.cs2 b/dumps/scripts/2674.cs2 new file mode 100644 index 0000000..0a06122 --- /dev/null +++ b/dumps/scripts/2674.cs2 @@ -0,0 +1,43 @@ +void script_2674(int arg0) { + if (arg0 != 0) { + setWidgetSprite(2034, new WidgetPointer(880,7)); + } else { + setWidgetSprite(2035, new WidgetPointer(880,7)); + } + if (arg0 != 1) { + setWidgetSprite(2034, new WidgetPointer(880,9)); + } else { + setWidgetSprite(2035, new WidgetPointer(880,9)); + } + if (arg0 != 2) { + setWidgetSprite(2034, new WidgetPointer(880,11)); + } else { + setWidgetSprite(2035, new WidgetPointer(880,11)); + } + if (arg0 != 3) { + setWidgetSprite(2034, new WidgetPointer(880,13)); + } else { + setWidgetSprite(2035, new WidgetPointer(880,13)); + } + if (arg0 != 4) { + setWidgetSprite(2034, new WidgetPointer(880,15)); + } else { + setWidgetSprite(2035, new WidgetPointer(880,15)); + } + if (arg0 != 5) { + setWidgetSprite(2034, new WidgetPointer(880,17)); + } else { + setWidgetSprite(2035, new WidgetPointer(880,17)); + } + if (arg0 != 6) { + setWidgetSprite(2034, new WidgetPointer(880,19)); + } else { + setWidgetSprite(2035, new WidgetPointer(880,19)); + } + if (arg0 != 7) { + setWidgetSprite(2034, new WidgetPointer(880,25)); + } else { + setWidgetSprite(2035, new WidgetPointer(880,25)); + } + return; +} diff --git a/dumps/scripts/2675.cs2 b/dumps/scripts/2675.cs2 new file mode 100644 index 0000000..e8a7bdb --- /dev/null +++ b/dumps/scripts/2675.cs2 @@ -0,0 +1,4 @@ +void script_2675(int arg0,int arg1) { + setWidgetRGB(new Color(arg1), new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/2676.cs2 b/dumps/scripts/2676.cs2 new file mode 100644 index 0000000..5b59e9b --- /dev/null +++ b/dumps/scripts/2676.cs2 @@ -0,0 +1,32 @@ +void script_2676(int arg0,int arg1) { + int ivar2; + ivar2 = 0; + switch (arg1) { + case 1: + ivar2 = standart_config_1485; + break; + case 2: + ivar2 = standart_config_1486; + break; + case 3: + ivar2 = standart_config_1487; + break; + case 4: + ivar2 = standart_config_1488; + break; + case 5: + ivar2 = standart_config_1489; + break; + case 6: + ivar2 = standart_config_1490; + break; + case 7: + ivar2 = standart_config_1491; + } + if (((boolean)ivar2)) { + setWidgetIsHidden(true, new WidgetPointer(arg0)); + } else { + setWidgetIsHidden(false, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/2677.cs2 b/dumps/scripts/2677.cs2 new file mode 100644 index 0000000..45f01a7 --- /dev/null +++ b/dumps/scripts/2677.cs2 @@ -0,0 +1,5 @@ +void script_2677() { + setWidgetScrollMax(431, 1863, new WidgetPointer(467,11)); + script_31(30605325, 30605323, 792, 789, 790, 791, 773, 788); + return; +} diff --git a/dumps/scripts/2678.cs2 b/dumps/scripts/2678.cs2 new file mode 100644 index 0000000..3ff9283 --- /dev/null +++ b/dumps/scripts/2678.cs2 @@ -0,0 +1,155 @@ +void script_2678() { + flow_0: + SWITCH (globalint_943) { + case 1: + GOTO flow_1 + case 2: + GOTO flow_2 + case 3: + GOTO flow_3 + case 4: + GOTO flow_4 + case 5: + GOTO flow_5 + case 6: + GOTO flow_6 + case 7: + GOTO flow_7 + } + setWidgetModel(15185, new WidgetPointer(400,11)); + setWidgetModel(15185, new WidgetPointer(400,8)); + setWidgetModel(15179, new WidgetPointer(400,3)); + setWidgetModel(15185, new WidgetPointer(400,10)); + setWidgetModel(15185, new WidgetPointer(400,6)); + setWidgetModel(15181, new WidgetPointer(400,4)); + setWidgetModel(15185, new WidgetPointer(400,7)); + setWidgetModel(15185, new WidgetPointer(400,9)); + setWidgetModel(15202, new WidgetPointer(400,15)); + setWidgetModel(15187, new WidgetPointer(400,12)); + setWidgetModel(15196, new WidgetPointer(400,13)); + setWidgetModel(15183, new WidgetPointer(400,5)); + setWidgetModel(15177, new WidgetPointer(400,2)); + setWidgetModel(15204, new WidgetPointer(400,16)); + setWidgetModel(15200, new WidgetPointer(400,14)); + GOTO flow_8 + flow_1: + setWidgetModel(15192, new WidgetPointer(400,11)); + setWidgetModel(15185, new WidgetPointer(400,8)); + setWidgetModel(15179, new WidgetPointer(400,3)); + setWidgetModel(15185, new WidgetPointer(400,10)); + setWidgetModel(15185, new WidgetPointer(400,6)); + setWidgetModel(15181, new WidgetPointer(400,4)); + setWidgetModel(15185, new WidgetPointer(400,7)); + setWidgetModel(15185, new WidgetPointer(400,9)); + setWidgetModel(15203, new WidgetPointer(400,15)); + setWidgetModel(15187, new WidgetPointer(400,12)); + setWidgetModel(15196, new WidgetPointer(400,13)); + setWidgetModel(15183, new WidgetPointer(400,5)); + setWidgetModel(15177, new WidgetPointer(400,2)); + setWidgetModel(15204, new WidgetPointer(400,16)); + setWidgetModel(15200, new WidgetPointer(400,14)); + GOTO flow_8 + flow_2: + setWidgetModel(15192, new WidgetPointer(400,11)); + setWidgetModel(15185, new WidgetPointer(400,8)); + setWidgetModel(15179, new WidgetPointer(400,3)); + setWidgetModel(15185, new WidgetPointer(400,10)); + setWidgetModel(15185, new WidgetPointer(400,6)); + setWidgetModel(15181, new WidgetPointer(400,4)); + setWidgetModel(15185, new WidgetPointer(400,7)); + setWidgetModel(15185, new WidgetPointer(400,9)); + setWidgetModel(15203, new WidgetPointer(400,15)); + setWidgetModel(15193, new WidgetPointer(400,12)); + setWidgetModel(15197, new WidgetPointer(400,13)); + setWidgetModel(15183, new WidgetPointer(400,5)); + setWidgetModel(15177, new WidgetPointer(400,2)); + setWidgetModel(15204, new WidgetPointer(400,16)); + setWidgetModel(15200, new WidgetPointer(400,14)); + GOTO flow_8 + flow_3: + setWidgetModel(15192, new WidgetPointer(400,11)); + setWidgetModel(15189, new WidgetPointer(400,8)); + setWidgetModel(15180, new WidgetPointer(400,3)); + setWidgetModel(15185, new WidgetPointer(400,10)); + setWidgetModel(15185, new WidgetPointer(400,6)); + setWidgetModel(15181, new WidgetPointer(400,4)); + setWidgetModel(15185, new WidgetPointer(400,7)); + setWidgetModel(15185, new WidgetPointer(400,9)); + setWidgetModel(15203, new WidgetPointer(400,15)); + setWidgetModel(15187, new WidgetPointer(400,12)); + setWidgetModel(15196, new WidgetPointer(400,13)); + setWidgetModel(15183, new WidgetPointer(400,5)); + setWidgetModel(15177, new WidgetPointer(400,2)); + setWidgetModel(15204, new WidgetPointer(400,16)); + setWidgetModel(15200, new WidgetPointer(400,14)); + GOTO flow_8 + flow_4: + setWidgetModel(15192, new WidgetPointer(400,11)); + setWidgetModel(15185, new WidgetPointer(400,8)); + setWidgetModel(15179, new WidgetPointer(400,3)); + setWidgetModel(15185, new WidgetPointer(400,10)); + setWidgetModel(15185, new WidgetPointer(400,6)); + setWidgetModel(15181, new WidgetPointer(400,4)); + setWidgetModel(15185, new WidgetPointer(400,7)); + setWidgetModel(15185, new WidgetPointer(400,9)); + setWidgetModel(15203, new WidgetPointer(400,15)); + setWidgetModel(15193, new WidgetPointer(400,12)); + setWidgetModel(15197, new WidgetPointer(400,13)); + setWidgetModel(15184, new WidgetPointer(400,5)); + setWidgetModel(15178, new WidgetPointer(400,2)); + setWidgetModel(15204, new WidgetPointer(400,16)); + setWidgetModel(15200, new WidgetPointer(400,14)); + GOTO flow_8 + flow_5: + setWidgetModel(15192, new WidgetPointer(400,11)); + setWidgetModel(15189, new WidgetPointer(400,8)); + setWidgetModel(15180, new WidgetPointer(400,3)); + setWidgetModel(15191, new WidgetPointer(400,10)); + setWidgetModel(15186, new WidgetPointer(400,6)); + setWidgetModel(15181, new WidgetPointer(400,4)); + setWidgetModel(15185, new WidgetPointer(400,7)); + setWidgetModel(15185, new WidgetPointer(400,9)); + setWidgetModel(15203, new WidgetPointer(400,15)); + setWidgetModel(15187, new WidgetPointer(400,12)); + setWidgetModel(15196, new WidgetPointer(400,13)); + setWidgetModel(15183, new WidgetPointer(400,5)); + setWidgetModel(15177, new WidgetPointer(400,2)); + setWidgetModel(15204, new WidgetPointer(400,16)); + setWidgetModel(15200, new WidgetPointer(400,14)); + GOTO flow_8 + flow_6: + setWidgetModel(15192, new WidgetPointer(400,11)); + setWidgetModel(15185, new WidgetPointer(400,8)); + setWidgetModel(15179, new WidgetPointer(400,3)); + setWidgetModel(15185, new WidgetPointer(400,10)); + setWidgetModel(15185, new WidgetPointer(400,6)); + setWidgetModel(15181, new WidgetPointer(400,4)); + setWidgetModel(15185, new WidgetPointer(400,7)); + setWidgetModel(15185, new WidgetPointer(400,9)); + setWidgetModel(15203, new WidgetPointer(400,15)); + setWidgetModel(15193, new WidgetPointer(400,12)); + setWidgetModel(15197, new WidgetPointer(400,13)); + setWidgetModel(15184, new WidgetPointer(400,5)); + setWidgetModel(15178, new WidgetPointer(400,2)); + setWidgetModel(15205, new WidgetPointer(400,16)); + setWidgetModel(15201, new WidgetPointer(400,14)); + GOTO flow_8 + flow_7: + setWidgetModel(15192, new WidgetPointer(400,11)); + setWidgetModel(15189, new WidgetPointer(400,8)); + setWidgetModel(15180, new WidgetPointer(400,3)); + setWidgetModel(15191, new WidgetPointer(400,10)); + setWidgetModel(15186, new WidgetPointer(400,6)); + setWidgetModel(15182, new WidgetPointer(400,4)); + setWidgetModel(15188, new WidgetPointer(400,7)); + setWidgetModel(15190, new WidgetPointer(400,9)); + setWidgetModel(15203, new WidgetPointer(400,15)); + setWidgetModel(15187, new WidgetPointer(400,12)); + setWidgetModel(15196, new WidgetPointer(400,13)); + setWidgetModel(15183, new WidgetPointer(400,5)); + setWidgetModel(15177, new WidgetPointer(400,2)); + setWidgetModel(15204, new WidgetPointer(400,16)); + setWidgetModel(15200, new WidgetPointer(400,14)); + flow_8: + return; +} diff --git a/dumps/scripts/2679.cs2 b/dumps/scripts/2679.cs2 new file mode 100644 index 0000000..d060929 --- /dev/null +++ b/dumps/scripts/2679.cs2 @@ -0,0 +1,5 @@ +void script_2679() { + setWidgetScrollMax(250, 981, new WidgetPointer(397,11)); + script_31(26017856, 26017803, 792, 789, 790, 791, 773, 788); + return; +} diff --git a/dumps/scripts/268.cs2 b/dumps/scripts/268.cs2 new file mode 100644 index 0000000..72112f0 --- /dev/null +++ b/dumps/scripts/268.cs2 @@ -0,0 +1,24 @@ +void script_268(int arg0) { + int ivar1; + globalarray_0 = new int[5]; + globalarray_0[0] = globalint_1104; + globalarray_0[1] = globalint_1105; + globalarray_0[2] = globalint_1106; + globalarray_0[3] = globalint_1107; + globalarray_0[4] = globalint_1108; + ivar1 = 0; + if (globalarray_0[arg0] != 0) { + ivar1 = arg0; + while (ivar1 < subtract(5, 1)) { + globalarray_0[ivar1] = globalarray_0[add(ivar1, 1)]; + } + globalarray_0[subtract(5, 1)] = 0; + } + globalint_1104 = globalarray_0[0]; + globalint_1105 = globalarray_0[1]; + globalint_1106 = globalarray_0[2]; + globalint_1107 = globalarray_0[3]; + globalint_1108 = globalarray_0[4]; + script_261(); + return; +} diff --git a/dumps/scripts/2680.cs2 b/dumps/scripts/2680.cs2 new file mode 100644 index 0000000..d3edf9b --- /dev/null +++ b/dumps/scripts/2680.cs2 @@ -0,0 +1,10 @@ +void script_2680() { + if (((boolean)bitconfig_2176)) { + setWidgetSprite(179, new WidgetPointer(398,15)); + setWidgetSprite(170, new WidgetPointer(398,1)); + } else { + setWidgetSprite(170, new WidgetPointer(398,15)); + setWidgetSprite(179, new WidgetPointer(398,1)); + } + return; +} diff --git a/dumps/scripts/2681.cs2 b/dumps/scripts/2681.cs2 new file mode 100644 index 0000000..b04f41d --- /dev/null +++ b/dumps/scripts/2681.cs2 @@ -0,0 +1,4 @@ +void script_2681() { + setWidgetText(new WidgetPointer(398,18), "Number of rooms: " + intToStr(globalint_944)); + return; +} diff --git a/dumps/scripts/2682.cs2 b/dumps/scripts/2682.cs2 new file mode 100644 index 0000000..e3f7436 --- /dev/null +++ b/dumps/scripts/2682.cs2 @@ -0,0 +1,4 @@ +void script_2682() { + script_2685(bitconfig_6450); + return; +} diff --git a/dumps/scripts/2683.cs2 b/dumps/scripts/2683.cs2 new file mode 100644 index 0000000..52e68a8 --- /dev/null +++ b/dumps/scripts/2683.cs2 @@ -0,0 +1,4 @@ +void script_2683() { + script_2685(1); + return; +} diff --git a/dumps/scripts/2684.cs2 b/dumps/scripts/2684.cs2 new file mode 100644 index 0000000..882056e --- /dev/null +++ b/dumps/scripts/2684.cs2 @@ -0,0 +1,4 @@ +void script_2684() { + script_2685(0); + return; +} diff --git a/dumps/scripts/2685.cs2 b/dumps/scripts/2685.cs2 new file mode 100644 index 0000000..2afe3f3 --- /dev/null +++ b/dumps/scripts/2685.cs2 @@ -0,0 +1,18 @@ +void script_2685(int arg0) { + if (((boolean)arg0)) { + setWidgetSprite(178, new WidgetPointer(398,31)); + setWidgetSprite(177, new WidgetPointer(398,32)); + setWidgetSprite(184, new WidgetPointer(398,33)); + setWidgetSprite(176, new WidgetPointer(398,7)); + setWidgetSprite(174, new WidgetPointer(398,8)); + setWidgetSprite(183, new WidgetPointer(398,23)); + } else { + setWidgetSprite(176, new WidgetPointer(398,31)); + setWidgetSprite(174, new WidgetPointer(398,32)); + setWidgetSprite(183, new WidgetPointer(398,33)); + setWidgetSprite(178, new WidgetPointer(398,7)); + setWidgetSprite(177, new WidgetPointer(398,8)); + setWidgetSprite(184, new WidgetPointer(398,23)); + } + return; +} diff --git a/dumps/scripts/2686.cs2 b/dumps/scripts/2686.cs2 new file mode 100644 index 0000000..541c67e --- /dev/null +++ b/dumps/scripts/2686.cs2 @@ -0,0 +1,5 @@ +void script_2686() { + setWidgetScrollMax(332, 1404, new WidgetPointer(402,12)); + script_31(26345589, 26345484, 792, 789, 790, 791, 773, 788); + return; +} diff --git a/dumps/scripts/2687.cs2 b/dumps/scripts/2687.cs2 new file mode 100644 index 0000000..6cf4ff4 --- /dev/null +++ b/dumps/scripts/2687.cs2 @@ -0,0 +1,15 @@ +int script_2687() { + if (standart_config_1447 < 100) { + return 10000; + } + if (standart_config_1447 < 200) { + return 12500; + } + if (standart_config_1447 < 300) { + return 15000; + } + if (standart_config_1447 < 400) { + return 17500; + } + return 20000; +} diff --git a/dumps/scripts/2688.cs2 b/dumps/scripts/2688.cs2 new file mode 100644 index 0000000..1ef13ff --- /dev/null +++ b/dumps/scripts/2688.cs2 @@ -0,0 +1,24 @@ +void script_2688() { + if ((cs2method3612() > 0) && (cs2method3618() >= cs2method3616())) { + if (((boolean)globalint_1413)) { + return; + } + if (((boolean)globalint_11)) { + script_675(); + } + if (getDisplayMode() >= 2) { + setWidgetIsHidden(false, new WidgetPointer(746,73)); + } + setWidgetIsHidden(false, new WidgetPointer(752,3)); + setWidgetIsHidden(true, new WidgetPointer(752,7)); + setWidgetIsHidden(true, new WidgetPointer(752,8)); + setWidgetText(new WidgetPointer(752,4), "Enter the player to ban from the channel:"); + globalint_5 = 15; + script_1564(""); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(752,3)); + script_2026(); + setScriptCallOnKeyPress(112, -2147483640, false, "iz", new WidgetPointer(752,5)); + script_1188(); + } + return; +} diff --git a/dumps/scripts/2689.cs2 b/dumps/scripts/2689.cs2 new file mode 100644 index 0000000..1fbe2eb --- /dev/null +++ b/dumps/scripts/2689.cs2 @@ -0,0 +1,4 @@ +void script_2689(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(1727, 596)); + return; +} diff --git a/dumps/scripts/269.cs2 b/dumps/scripts/269.cs2 new file mode 100644 index 0000000..7202d64 --- /dev/null +++ b/dumps/scripts/269.cs2 @@ -0,0 +1,20 @@ +int script_269() { + int ivar0; + ivar0 = 0; + if (globalint_1104 != 0) { + ivar0 = add(ivar0, 1); + } + if (globalint_1105 != 0) { + ivar0 = add(ivar0, 1); + } + if (globalint_1106 != 0) { + ivar0 = add(ivar0, 1); + } + if (globalint_1107 != 0) { + ivar0 = add(ivar0, 1); + } + if (globalint_1108 != 0) { + ivar0 = add(ivar0, 1); + } + return ivar0; +} diff --git a/dumps/scripts/2690.cs2 b/dumps/scripts/2690.cs2 new file mode 100644 index 0000000..7351eb6 --- /dev/null +++ b/dumps/scripts/2690.cs2 @@ -0,0 +1,25 @@ +void script_2690(int arg0) { + int ivar1; + int ivar2; + int ivar3; + ivar1 = 0; + ivar2 = 0; + ivar3 = 5; + while (setWidgetRegister(new WidgetPointer(1022,15), ivar1)) { + ivar1 = add(ivar1, 1); + } + if (arg0 > 4) { + ivar3 = add(ivar3, 40); + ivar2 = multiply(subtract(arg0, 5), 40); + } else { + ivar2 = multiply(arg0, 40); + } + ivar2 = add(ivar2, 17); + createExtraChild(new WidgetPointer(1022,15), 5, ivar1); + setWidgetSprite(937); + setWidgetSize(10, 32, 0, 0); + setWidgetPosition(ivar2, ivar3, 0, 0); + setWidgetHidden(0); + setScriptCallOnGameloop(144, new WidgetPointer(1022,15), ivar1, getClientCycle(), add(getClientCycle(), 750), "Iiii"); + return; +} diff --git a/dumps/scripts/2691.cs2 b/dumps/scripts/2691.cs2 new file mode 100644 index 0000000..800d135 --- /dev/null +++ b/dumps/scripts/2691.cs2 @@ -0,0 +1,23 @@ +void script_2691(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + if (((boolean)arg5) && setWidgetRegister(new WidgetPointer(arg0), arg3)) { + setWidgetRGB(new Color(arg4)); + } + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + if (((boolean)arg2)) { + if (getWidgetSpriteId() == 2554) { + setWidgetSprite(2555); + } else { + if (getWidgetSpriteId() == 2556) { + setWidgetSprite(2557); + } + } + } else if (getWidgetSpriteId() == 2555) { + setWidgetSprite(2554); + } else { + if (getWidgetSpriteId() == 2557) { + setWidgetSprite(2556); + } + } + } + return; +} diff --git a/dumps/scripts/2692.cs2 b/dumps/scripts/2692.cs2 new file mode 100644 index 0000000..b32e739 --- /dev/null +++ b/dumps/scripts/2692.cs2 @@ -0,0 +1,26 @@ +cs2func_script_2692_struct(2,0,0) script_2692(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + ivar1 = -1; + ivar2 = -1; + ivar3 = 0; + ivar4 = 0; + ivar5 = 0; + ivar6 = subtract(getCommonDefinitionSize(201), 1); + while (ivar6 >= 0) { + ivar1 = cs2method_3408(105, 74, 201, ivar6); + ivar3 = add(ivar3, 1); + ivar2 = getOtherCommonData(ivar1, 683); + ivar5 = subtract(getCommonDefinitionSize(ivar2), 1); + while (ivar5 >= 0) { + ivar4 = max(getTextWidth(494, cs2method_3408(105, 115, ivar2, ivar5)), ivar4); + ivar5 = subtract(ivar5, 1); + } + ivar6 = subtract(ivar6, 1); + } + return newstruct cs2func_script_2692_struct(ivar3, ivar4); +} diff --git a/dumps/scripts/2693.cs2 b/dumps/scripts/2693.cs2 new file mode 100644 index 0000000..9bd07a3 --- /dev/null +++ b/dumps/scripts/2693.cs2 @@ -0,0 +1,13 @@ +string script_2693(int arg0) { + int ivar1; + int ivar2; + int stack_dump0; + opcStruct5303(2,0,0) structdump_1; + ivar1 = 0; + ivar2 = 0; + stack_dump0 = arg0; + structdump_1 = cs2method5303(stack_dump0); + ivar2 = structdump_1.intpart_1; + ivar1 = structdump_1.intpart_0; + return intToStr(ivar1) + "x" + intToStr(ivar2); +} diff --git a/dumps/scripts/2694.cs2 b/dumps/scripts/2694.cs2 new file mode 100644 index 0000000..5159f13 --- /dev/null +++ b/dumps/scripts/2694.cs2 @@ -0,0 +1,37 @@ +void script_2694(int arg0,int arg1,string arg2,string arg3,string arg4) { + int ivar2; + ivar2 = 0; + if (((boolean)arg0)) { + if (strLength(arg2) > 0) { + ivar2 = strIndexof(0, arg2, "
"); + if (ivar2 == -1) { + messageType0(arg2); + return; + } + messageType0(substr(0, ivar2, arg2)); + } + return; + } + if (arg0 == 2) { + setWidgetText(new WidgetPointer(978,7), script_400(arg2, "
", " ")); + script_2190(0, -1, 0, "", arg2, "", arg3); + if (strLength(arg3) > 0) { + setScriptCallOnMousePressed(702, arg4, 1, "s1", new WidgetPointer(906,153)); + } else { + setScriptCallOnMousePressed(-1, "", new WidgetPointer(906,153)); + } + return; + } + setWidgetText(new WidgetPointer(978,7), script_400(arg2, "
", " ")); + setWidgetText(new WidgetPointer(744,76), arg2); + setScriptCallOnMousePressed(3452, 6, 0, 1, "i11", new WidgetPointer(744,79)); + if (strLength(arg3) > 0) { + setWidgetText(new WidgetPointer(744,78), arg3); + setScriptCallOnMousePressed(702, arg4, 1, "s1", new WidgetPointer(744,78)); + } else { + setWidgetText(new WidgetPointer(744,78), ""); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(744,77)); + } + script_1174(9); + return; +} diff --git a/dumps/scripts/2695.cs2 b/dumps/scripts/2695.cs2 new file mode 100644 index 0000000..82ceb6a --- /dev/null +++ b/dumps/scripts/2695.cs2 @@ -0,0 +1,143 @@ +void script_2695(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10) { + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + int ivar22; + int ivar23; + int ivar24; + int ivar25; + int ivar26; + int ivar27; + int ivar28; + ivar11 = 0; + ivar12 = 0; + ivar13 = 0; + ivar14 = -1; + ivar15 = -1; + ivar16 = -1; + ivar17 = -1; + ivar18 = -1; + ivar19 = -1; + if (((boolean)arg10)) { + ivar14 = 48627716; + ivar15 = 48627732; + ivar16 = 48627733; + ivar17 = 48627734; + ivar18 = 48627715; + ivar19 = 48627718; + } else if (arg10 == 2) { + ivar14 = 59703296; + ivar15 = 59703355; + ivar16 = 59703360; + ivar17 = 59703361; + ivar18 = 59703359; + ivar19 = 59703298; + } else { + ivar14 = 57802756; + ivar15 = 57802757; + ivar16 = 57802758; + ivar17 = 57802759; + ivar18 = 57802755; + ivar19 = 57802780; + } + ivar20 = 0; + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + ivar11 = add(script_1743(), script_3365(ivar19)); + ivar20 = script_1744(); + ivar12 = add(subtract(add(ivar20, getWidgetActualHeight()), 1), script_3366(ivar19)); + ivar13 = getWidgetActualWidth(); + } + if ((isWidgetHidden(new WidgetPointer(ivar15)) && (getWidgetActualX(new WidgetPointer(ivar15)) == ivar11)) && (getWidgetActualY(new WidgetPointer(ivar15)) == ivar12)) { + return; + } + deleteAllExtraChilds(new WidgetPointer(ivar16)); + deleteAllExtraChilds(new WidgetPointer(ivar17)); + cs2method2100(0, 0, new WidgetPointer(ivar16)); + ivar21 = getOtherCommonData(arg5, 683); + ivar22 = script_2581(arg5); + ivar23 = script_829(arg5, ivar21); + ivar24 = 0; + ivar25 = 0; + ivar26 = 0; + while (ivar25 <= ivar23) { + if (ivar26 != ivar22) { + createExtraChild(new WidgetPointer(ivar16), 4, getExtraChildGap(new WidgetPointer(ivar16))); + setWidgetSize(2, 15, 1, 0); + setWidgetPosition(0, ivar24, 1, 0); + setWidgetTextAlignment(1, 1, 0); + setWidgetFont(494); + setScriptCallOnMouseEntered(1356, new WidgetPointer(-32768,3), -2147483643, 2511483, "Iii"); + if (arg5 != 1009) { + if (ivar25 < ivar23) { + setWidgetRGB(new Color(235, 224, 188)); + setScriptCallOnMouseExit(1356, new WidgetPointer(-32768,3), -2147483643, 15458492, "Iii"); + } else { + setWidgetRGB(new Color(0, 177, 225)); + setScriptCallOnMouseExit(1356, new WidgetPointer(-32768,3), -2147483643, 45537, "Iii"); + } + } else if (ivar25 > 0) { + setWidgetRGB(new Color(235, 224, 188)); + setScriptCallOnMouseExit(1356, new WidgetPointer(-32768,3), -2147483643, 15458492, "Iii"); + } else { + setWidgetRGB(new Color(0, 177, 225)); + setScriptCallOnMouseExit(1356, new WidgetPointer(-32768,3), -2147483643, 45537, "Iii"); + } + if (ivar21 != -1) { + setWidgetText(cs2method_3408(105, 115, ivar21, ivar26)); + } else { + setWidgetText(script_2693(ivar25)); + } + setScriptCallOnMousePressed(2699, ivar26, arg5, arg6, arg7, arg8, arg9, arg10, "iJiiiii"); + ivar24 = add(ivar24, getWidgetActualHeight()); + } + ivar25 = add(ivar25, 1); + ivar26 = add(ivar26, 1); + } + ivar24 = add(ivar24, 2); + ivar27 = 0; + if (((boolean)arg10)) { + ivar27 = 334; + } else { + ivar27 = getWidgetActualHeight(new WidgetPointer(ivar14)); + } + ivar28 = 1; + if (ivar27 < add(ivar12, ivar24)) { + ivar12 = add(subtract(add(ivar20, 1), ivar24), script_3366(ivar19)); + setWidgetPosition(0, 0, 1, 0, new WidgetPointer(ivar18)); + ivar28 = 0; + } else { + setWidgetPosition(0, 0, 1, 2, new WidgetPointer(ivar18)); + setWidgetScrollMax(0, 0, new WidgetPointer(ivar16)); + setWidgetIsHidden(true, new WidgetPointer(ivar17)); + } + setWidgetPosition(ivar11, ivar12, 0, 0, new WidgetPointer(ivar15)); + setWidgetSize(ivar13, ivar24, 0, 0, new WidgetPointer(ivar15)); + setWidgetIsHidden(false, new WidgetPointer(ivar15)); + if (setWidgetRegister(new WidgetPointer(arg0), arg2)) { + setWidgetSprite(2556); + } + if ((arg4 != -1) && setWidgetRegister(new WidgetPointer(arg0), arg4)) { + setWidgetRGB(new Color(178, 170, 159)); + } + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setScriptCallOnMousePressed(2696, new WidgetPointer(arg0), arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, "IiiiiJiiiii"); + setScriptCallOnMouseEntered(2691, new WidgetPointer(-32768,3), arg2, 1, arg3, 8419437, 0, "Ii1ii1"); + setScriptCallOnMouseExit(2691, new WidgetPointer(-32768,3), arg2, 0, arg3, 6249298, 0, "Ii1ii1"); + if (setWidgetRegister(new WidgetPointer(arg0), arg3)) { + setWidgetRGB(new Color(178, 170, 159)); + if (((boolean)ivar28)) { + setWidgetSize(getWidgetActualWidth(), add(getWidgetActualHeight(), 5), 0, 0); + } + } + } + setScriptCallOnMousePressed(2696, new WidgetPointer(arg0), arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, "IiiiiJiiiii", new WidgetPointer(ivar14)); + return; +} diff --git a/dumps/scripts/2696.cs2 b/dumps/scripts/2696.cs2 new file mode 100644 index 0000000..50777d4 --- /dev/null +++ b/dumps/scripts/2696.cs2 @@ -0,0 +1,34 @@ +void script_2696(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10) { + if (((boolean)arg10)) { + deleteAllExtraChilds(new WidgetPointer(742,21)); + deleteAllExtraChilds(new WidgetPointer(742,22)); + setWidgetIsHidden(true, new WidgetPointer(742,20)); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(742,4)); + } else if (arg10 == 2) { + deleteAllExtraChilds(new WidgetPointer(911,64)); + deleteAllExtraChilds(new WidgetPointer(911,65)); + setWidgetIsHidden(true, new WidgetPointer(911,59)); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(911,0)); + } else { + deleteAllExtraChilds(new WidgetPointer(882,6)); + deleteAllExtraChilds(new WidgetPointer(882,7)); + setWidgetIsHidden(true, new WidgetPointer(882,5)); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(882,4)); + } + if (setWidgetRegister(new WidgetPointer(arg0), arg2)) { + setWidgetSprite(2554); + } + if ((arg4 != -1) && setWidgetRegister(new WidgetPointer(arg0), arg4)) { + setWidgetRGB(new Color(235, 224, 188)); + } + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setScriptCallOnMousePressed(2695, new WidgetPointer(-32768,3), -2147483643, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, "IiiiiJiiiii"); + setScriptCallOnMouseEntered(2691, new WidgetPointer(-32768,3), arg2, 1, arg3, 8419437, 1, "Ii1ii1"); + setScriptCallOnMouseExit(2691, new WidgetPointer(-32768,3), arg2, 0, arg3, 6249298, 1, "Ii1ii1"); + if (setWidgetRegister(new WidgetPointer(arg0), arg3)) { + setWidgetRGB(new Color(95, 91, 82)); + setWidgetSize(getWidgetActualWidth(), getWidgetActualHeight(), 0, 0); + } + } + return; +} diff --git a/dumps/scripts/2697.cs2 b/dumps/scripts/2697.cs2 new file mode 100644 index 0000000..16cbfc3 --- /dev/null +++ b/dumps/scripts/2697.cs2 @@ -0,0 +1,34 @@ +void script_2697(int arg0,int arg1) { + int ivar2; + int stack_dump0; + int stack_dump1; + int stack_dump2; + cs2func_script_2692_struct(2,0,0) structdump_3; + cs2func_script_2692_struct(2,0,0) structdump_4; + if (arg0 == cs2method6131()) { + return; + } + cs2method6031(arg0); + ivar2 = cs2method6131(); + script_2593(ivar2); + if (arg0 != ivar2) { + cs2method6032(ivar2, 1); + script_2694(arg1, 1, "RuneScape was unable to enter that display mode." + "
" + "
" + "Please visit our Knowledge Base for more information.", "Consult Knowledge Base", "kbase/view.ws?guid=controls_display_options"); + stack_dump0 = ivar2; + stack_dump1 = getDisplayMode(); + stack_dump2 = ivar2; + structdump_3 = script_2692(stack_dump2); + script_3387(stack_dump0, stack_dump1, structdump_3.intpart_0, structdump_3.intpart_1, arg1); + } + stack_dump0 = ivar2; + stack_dump1 = getDisplayMode(); + stack_dump2 = ivar2; + structdump_4 = script_2692(stack_dump2); + script_3387(stack_dump0, stack_dump1, structdump_4.intpart_0, structdump_4.intpart_1, arg1); + if (((boolean)ivar2) || (ivar2 == 3)) { + script_2700(1, arg1, 0, 1); + } else { + cs2method6032(ivar2, 0); + } + return; +} diff --git a/dumps/scripts/2698.cs2 b/dumps/scripts/2698.cs2 new file mode 100644 index 0000000..32594e1 --- /dev/null +++ b/dumps/scripts/2698.cs2 @@ -0,0 +1,44 @@ +void script_2698(int arg0,int arg1,int arg2,int arg3,int arg4) { + int ivar5; + int stack_dump0; + opcStruct5303(2,0,0) structdump_1; + if (arg0 == getDisplayMode()) { + return; + } + ivar5 = -1; + if (arg0 != 3) { + cs2method5307(arg0); + ivar5 = getDisplayMode(); + cs2method5309(ivar5); + if (arg0 != ivar5) { + script_2694(arg4, 0, "RuneScape was unable to enter that display mode." + "
" + "
" + "Please visit our Knowledge Base for more information.", "Consult Knowledge Base", "kbase/view.ws?guid=controls_display_options"); + script_2596(arg3, ivar5, arg1, arg2, arg4); + return; + } + script_2596(arg3, ivar5, arg1, arg2, arg4); + if ((arg0 >= 2) && (ivar5 >= 2)) { + globalint_994 = 2; + } + return; + } + if (isSiteSettingsMembers()) { + script_2694(arg4, 0, "Fullscreen mode is only available to RuneScape members." + "
" + "
" + "Please visit the RuneScape website to learn about other benefits of membership.", "Members' benefits", "members/members.ws"); + return; + } + if (cs2method5302() > globalint_178) { + stack_dump0 = globalint_178; + structdump_1 = cs2method5303(stack_dump0); + if (cs2method5300(structdump_1.intpart_0, structdump_1.intpart_1)) { + script_2596(arg3, arg0, arg1, arg2, arg4); + script_2700(2, arg4, 0, 0); + return; + } + } + arg0 = cs2method5308(); + cs2method5307(arg0); + if (((boolean)arg4)) { + messageType0("Unable to enter fullscreen mode at that resolution."); + } + script_2596(arg3, arg0, arg1, arg2, arg4); + return; +} diff --git a/dumps/scripts/2699.cs2 b/dumps/scripts/2699.cs2 new file mode 100644 index 0000000..4a3ae4d --- /dev/null +++ b/dumps/scripts/2699.cs2 @@ -0,0 +1,25 @@ +void script_2699(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6) { + int ivar7; + ivar7 = script_2582(arg1, arg0, arg6); + if (((boolean)ivar7)) { + if (arg1 == 845) { + arg5 = cs2method5308(); + cs2method5307(arg5); + script_2694(arg6, 0, "RuneScape was unable to change to that resolution." + "
" + "
" + "Please visit our Knowledge Base for more information.", "Consult Knowledge Base", "kbase/view.ws?guid=controls_display_options"); + } else if (arg1 == 1009) { + script_3413(arg6); + } else { + script_2694(arg6, 1, "RuneScape was unable to implement that setting." + "
" + "
" + "Please visit our Knowledge Base for more information.", "Consult Knowledge Base", "kbase/view.ws?guid=controls_display_options"); + } + } else { + if (cs2method7007() != 0) { + cs2method7005(); + } + } + if (arg1 == 845) { + script_2596(arg4, arg5, arg2, arg3, arg6); + } else { + script_3387(arg4, arg5, arg2, arg3, arg6); + } + return; +} diff --git a/dumps/scripts/27.cs2 b/dumps/scripts/27.cs2 new file mode 100644 index 0000000..2f22b0e --- /dev/null +++ b/dumps/scripts/27.cs2 @@ -0,0 +1,7 @@ +void script_27() { + setWidgetText(new WidgetPointer(197,8), intToStr(bitconfig_1485)); + setWidgetText(new WidgetPointer(197,11), intToStr(bitconfig_1489)); + setWidgetText(new WidgetPointer(197,9), intToStr(bitconfig_1488)); + setWidgetText(new WidgetPointer(197,10), intToStr(bitconfig_1486)); + return; +} diff --git a/dumps/scripts/270.cs2 b/dumps/scripts/270.cs2 new file mode 100644 index 0000000..db81384 --- /dev/null +++ b/dumps/scripts/270.cs2 @@ -0,0 +1,3 @@ +int script_270(int arg0) { + return 0; +} diff --git a/dumps/scripts/2700.cs2 b/dumps/scripts/2700.cs2 new file mode 100644 index 0000000..d7ad103 --- /dev/null +++ b/dumps/scripts/2700.cs2 @@ -0,0 +1,20 @@ +void script_2700(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + ivar4 = add(getClientCycle(), 750); + if (((boolean)arg1)) { + setScriptCallOnGameloop(2703, ivar4, arg0, arg1, arg2, arg3, "iii11", new WidgetPointer(746,83)); + setScriptCallOnGameloop(2703, ivar4, arg0, arg1, arg2, arg3, "iii11", new WidgetPointer(548,21)); + script_2701(arg0, arg2, arg3); + } else if (arg1 == 2) { + setScriptCallOnGameloop(2703, ivar4, arg0, arg1, arg2, arg3, "iii11", new WidgetPointer(906,23)); + script_3090(); + setScriptCallOnClickContextMenu(2704, 1, arg0, arg1, arg2, arg3, "1ii11", new WidgetPointer(906,127)); + setScriptCallOnClickContextMenu(2704, 0, arg0, arg1, arg2, arg3, "1ii11", new WidgetPointer(906,129)); + } else { + setScriptCallOnGameloop(2703, ivar4, arg0, arg1, arg2, arg3, "iii11", new WidgetPointer(744,17)); + script_1174(10); + setScriptCallOnMousePressed(2704, 1, arg0, arg1, arg2, arg3, "1ii11", new WidgetPointer(744,56)); + setScriptCallOnMousePressed(2704, 0, arg0, arg1, arg2, arg3, "1ii11", new WidgetPointer(744,57)); + } + return; +} diff --git a/dumps/scripts/2701.cs2 b/dumps/scripts/2701.cs2 new file mode 100644 index 0000000..49f2ca8 --- /dev/null +++ b/dumps/scripts/2701.cs2 @@ -0,0 +1,24 @@ +void script_2701(int arg0,int arg1,int arg2) { + if (((boolean)getDisplayMode())) { + openInterface(35913749, 883); + } else { + openInterface(48889939, 883); + } + setWidgetIsHidden(false, new WidgetPointer(746,83)); + setWidgetIsHidden(false, new WidgetPointer(548,21)); + script_1151(57868306); + script_1151(57868309); + setScriptCallOnMouseEntered(2702, 1, new WidgetPointer(883,18), new WidgetPointer(883,19), "1II", new WidgetPointer(883,17)); + setScriptCallOnMouseExit(2702, 0, new WidgetPointer(883,18), new WidgetPointer(883,19), "1II", new WidgetPointer(883,17)); + setScriptCallOnMouseEntered(2702, 1, new WidgetPointer(883,21), new WidgetPointer(883,22), "1II", new WidgetPointer(883,20)); + setScriptCallOnMouseExit(2702, 0, new WidgetPointer(883,21), new WidgetPointer(883,22), "1II", new WidgetPointer(883,20)); + setScriptCallOnMousePressed(2704, 1, arg0, 1, arg1, arg2, "1ii11", new WidgetPointer(883,17)); + setScriptCallOnMousePressed(2704, 0, arg0, 1, arg1, arg2, "1ii11", new WidgetPointer(883,20)); + setWidgetIsHidden(false, new WidgetPointer(548,191)); + setWidgetIsHidden(false, new WidgetPointer(548,69)); + setWidgetIsHidden(false, new WidgetPointer(548,194)); + setWidgetIsHidden(false, new WidgetPointer(548,203)); + setWidgetIsHidden(false, new WidgetPointer(548,163)); + setWidgetIsHidden(false, new WidgetPointer(548,115)); + return; +} diff --git a/dumps/scripts/2702.cs2 b/dumps/scripts/2702.cs2 new file mode 100644 index 0000000..74cc548 --- /dev/null +++ b/dumps/scripts/2702.cs2 @@ -0,0 +1,10 @@ +void script_2702(int arg0,int arg1,int arg2) { + if (((boolean)arg0)) { + script_1166(arg1); + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(arg2)); + } else { + script_1151(arg1); + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(arg2)); + } + return; +} diff --git a/dumps/scripts/2703.cs2 b/dumps/scripts/2703.cs2 new file mode 100644 index 0000000..7d85fdb --- /dev/null +++ b/dumps/scripts/2703.cs2 @@ -0,0 +1,30 @@ +void script_2703(int arg0,int arg1,int arg2,int arg3,int arg4) { + int ivar5; + int ivar6; + int ivar7; + ivar5 = subtract(arg0, getClientCycle()); + if (ivar5 <= 0) { + script_2705(0, arg1, arg2, 1, arg3, arg4); + return; + } + ivar6 = getDisplayMode(); + if (isBitFlagged(arg1, 1) && (ivar6 != 3)) { + script_2705(0, arg1, arg2, 1, arg3, arg4); + return; + } + ivar7 = 48889939; + if (((boolean)arg2)) { + if (((boolean)ivar6)) { + ivar7 = 35913749; + } + if (isWidgetOpen(new WidgetPointer(ivar7))) { + script_2701(arg1, arg3, arg4); + } + setWidgetText(new WidgetPointer(883,16), "Reverting in: " + intToStr(divide(ivar5, 50))); + } else if (arg2 == 2) { + setWidgetText(new WidgetPointer(906,126), "Reverting in: " + intToStr(divide(ivar5, 50))); + } else { + setWidgetText(new WidgetPointer(744,54), "Reverting in: " + intToStr(divide(ivar5, 50))); + } + return; +} diff --git a/dumps/scripts/2704.cs2 b/dumps/scripts/2704.cs2 new file mode 100644 index 0000000..999962e --- /dev/null +++ b/dumps/scripts/2704.cs2 @@ -0,0 +1,4 @@ +void script_2704(int arg0,int arg1,int arg2,int arg3,int arg4) { + script_2705(arg0, arg1, arg2, 0, arg3, arg4); + return; +} diff --git a/dumps/scripts/2705.cs2 b/dumps/scripts/2705.cs2 new file mode 100644 index 0000000..8b9a8be --- /dev/null +++ b/dumps/scripts/2705.cs2 @@ -0,0 +1,177 @@ +void script_2705(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + int ivar6; + string svar0; + int stack_dump0; + int stack_dump1; + int stack_dump2; + cs2func_script_2692_struct(2,0,0) structdump_3; + cs2func_script_2692_struct(2,0,0) structdump_4; + cs2func_script_2692_struct(2,0,0) structdump_5; + cs2func_script_2692_struct(2,0,0) structdump_6; + cs2func_script_2692_struct(2,0,0) structdump_7; + cs2func_script_2692_struct(2,0,0) structdump_8; + cs2func_script_2692_struct(2,0,0) structdump_9; + cs2func_script_2692_struct(2,0,0) structdump_10; + cs2func_script_2692_struct(2,0,0) structdump_11; + if (((boolean)arg2)) { + closeInterface(48889939); + closeInterface(35913749); + setScriptCallOnGameloop(-1, "", new WidgetPointer(746,83)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(548,21)); + setWidgetIsHidden(true, new WidgetPointer(548,191)); + setWidgetIsHidden(true, new WidgetPointer(548,69)); + setWidgetIsHidden(true, new WidgetPointer(548,194)); + setWidgetIsHidden(true, new WidgetPointer(548,203)); + setWidgetIsHidden(true, new WidgetPointer(548,163)); + setWidgetIsHidden(true, new WidgetPointer(548,115)); + } else if (arg2 == 2) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(906,23)); + } else { + setScriptCallOnGameloop(-1, "", new WidgetPointer(744,17)); + } + ivar6 = 0; + if (((boolean)arg0)) { + cs2method6032(cs2method6131(), 1); + if (getDisplayMode() != 3) { + cs2method5309(getDisplayMode()); + } + cs2method6024(cs2method6116()); + if (isBitFlagged(arg1, 1)) { + globalint_994 = 2; + } + globalint_1240 = 3; + globalint_1277 = 0; + } else { + if (isBitFlagged(arg1, 0)) { + cs2method7006(); + if (((boolean)arg4)) { + ivar6 = cs2method6132(); + cs2method6031(ivar6); + script_2593(ivar6); + } + } else { + ivar6 = cs2method6131(); + } + if (isBitFlagged(arg1, 1) && (getDisplayMode() != cs2method5308())) { + cs2method5307(cs2method5308()); + } + if (isBitFlagged(arg1, 2)) { + cs2method6016(cs2method6124()); + } + if (isBitFlagged(arg1, 3)) { + cs2method6027(0); + } + if (arg2 == 3) { + script_1174(0); + script_3384(arg2); + return; + } + if (((boolean)arg5)) { + stack_dump0 = ivar6; + stack_dump1 = getDisplayMode(); + stack_dump2 = ivar6; + structdump_3 = script_2692(stack_dump2); + script_3387(stack_dump0, stack_dump1, structdump_3.intpart_0, structdump_3.intpart_1, arg2); + } else if (isBitFlagged(arg1, 1) || ((boolean)arg4)) { + stack_dump0 = ivar6; + stack_dump1 = getDisplayMode(); + stack_dump2 = ivar6; + structdump_4 = script_2692(stack_dump2); + script_2596(stack_dump0, stack_dump1, structdump_4.intpart_0, structdump_4.intpart_1, arg2); + } else { + stack_dump0 = ivar6; + stack_dump1 = getDisplayMode(); + stack_dump2 = ivar6; + structdump_5 = script_2692(stack_dump2); + script_3387(stack_dump0, stack_dump1, structdump_5.intpart_0, structdump_5.intpart_1, arg2); + } + if (((boolean)arg2) && ((boolean)arg3)) { + messageType0("The requested change has been cancelled."); + } + } + svar0 = "kbase/view.ws?guid=controls_display_options"; + if (arg2 != 1) { + ivar6 = cs2method6131(); + if (arg2 == 2) { + setWidgetIsHidden(true, new WidgetPointer(906,42)); + if (((boolean)arg5)) { + stack_dump0 = ivar6; + stack_dump1 = getDisplayMode(); + stack_dump2 = ivar6; + structdump_6 = script_2692(stack_dump2); + script_3387(stack_dump0, stack_dump1, structdump_6.intpart_0, structdump_6.intpart_1, arg2); + } else if (isBitFlagged(arg1, 1) || ((boolean)arg4)) { + stack_dump0 = ivar6; + stack_dump1 = getDisplayMode(); + stack_dump2 = ivar6; + structdump_7 = script_2692(stack_dump2); + script_2596(stack_dump0, stack_dump1, structdump_7.intpart_0, structdump_7.intpart_1, arg2); + } else { + stack_dump0 = ivar6; + stack_dump1 = getDisplayMode(); + stack_dump2 = ivar6; + structdump_8 = script_2692(stack_dump2); + script_3387(stack_dump0, stack_dump1, structdump_8.intpart_0, structdump_8.intpart_1, arg2); + } + if (((boolean)arg4) && ((boolean)arg3)) { + script_2190(0, -1, 0, "", "The change of detail mode has been cancelled." + "
" + "
" + "Perhaps different graphical settings would work better for you?", "", "Advanced info"); + setScriptCallOnMousePressed(702, svar0, 1, "s1", new WidgetPointer(906,153)); + } + } else if (arg2 == 3) { + if (hasSSKey()) { + script_1174(5); + if (((boolean)globalint_1273)) { + return; + } + setScriptCallOnGameloop(3381, new WidgetPointer(975,44), 0, "Ii", new WidgetPointer(975,44)); + } else if (((boolean)script_3487(3))) { + script_1174(7); + } else { + script_1174(11); + } + } else { + if (((boolean)arg5)) { + stack_dump0 = ivar6; + stack_dump1 = getDisplayMode(); + stack_dump2 = ivar6; + structdump_9 = script_2692(stack_dump2); + script_3387(stack_dump0, stack_dump1, structdump_9.intpart_0, structdump_9.intpart_1, arg2); + } else if (isBitFlagged(arg1, 1) || ((boolean)arg4)) { + stack_dump0 = ivar6; + stack_dump1 = getDisplayMode(); + stack_dump2 = ivar6; + structdump_10 = script_2692(stack_dump2); + script_2596(stack_dump0, stack_dump1, structdump_10.intpart_0, structdump_10.intpart_1, arg2); + } else { + stack_dump0 = ivar6; + stack_dump1 = getDisplayMode(); + stack_dump2 = ivar6; + structdump_11 = script_2692(stack_dump2); + script_3387(stack_dump0, stack_dump1, structdump_11.intpart_0, structdump_11.intpart_1, arg2); + } + if (((boolean)arg4) && ((boolean)arg3)) { + setWidgetText(new WidgetPointer(744,76), "The change of detail mode has been cancelled." + "
" + "
" + "Perhaps different graphical settings would work better for you?"); + if (((boolean)arg5)) { + setScriptCallOnMousePressed(3452, 6, 0, 1, "i11", new WidgetPointer(744,79)); + } else if (isBitFlagged(arg1, 1) || ((boolean)arg4)) { + setScriptCallOnMousePressed(1173, 6, "i", new WidgetPointer(744,79)); + } else { + setScriptCallOnMousePressed(3452, 6, 0, 1, "i11", new WidgetPointer(744,79)); + } + setWidgetText(new WidgetPointer(744,78), "Advanced info"); + setScriptCallOnMousePressed(702, svar0, 1, "s1", new WidgetPointer(744,78)); + script_1174(9); + } else if (((boolean)arg5)) { + script_3239(6, 0, 1); + } else if (isBitFlagged(arg1, 1) || ((boolean)arg4)) { + script_1174(6); + } else { + script_3239(6, 0, 1); + } + } + } + if (((boolean)arg0) && ((boolean)arg4)) { + script_3384(arg2); + } + return; +} diff --git a/dumps/scripts/2706.cs2 b/dumps/scripts/2706.cs2 new file mode 100644 index 0000000..dbbbbef --- /dev/null +++ b/dumps/scripts/2706.cs2 @@ -0,0 +1,33 @@ +string script_2706(int arg0) { + if (((boolean)script_926(arg0))) { + if (((boolean)script_925(arg0))) { + if (((boolean)stringMethod4107(getItemOption(arg0, 2), "Wield"))) { + return "You do not meet the requirements to use or wield this item." + "
"; + } + return "You do not meet the requirements to use or wear this item." + "
"; + } + if (((boolean)stringMethod4107(getItemOption(arg0, 2), "Wield"))) { + return "You can wield this item but not use it." + "
"; + } + if (((boolean)stringMethod4107(getItemOption(arg0, 2), "Wear"))) { + return "You can wear this item but not use it." + "
"; + } + return "You do not meet the requirements to use this item." + "
"; + } + if (((boolean)script_928(arg0))) { + if (((boolean)script_925(arg0))) { + if (((boolean)stringMethod4107(getItemOption(arg0, 2), "Wield"))) { + return "You can use this item but not wield it." + "
"; + } + return "You can use this item but not wear it." + "
"; + } + } else { + if (((boolean)script_925(arg0))) { + if (((boolean)stringMethod4107(getItemOption(arg0, 2), "Wield"))) { + return "You do not meet the requirements to wield this item." + "
"; + } + return "You do not meet the requirements to wear this item." + "
"; + } + } + return ""; +} diff --git a/dumps/scripts/2707.cs2 b/dumps/scripts/2707.cs2 new file mode 100644 index 0000000..a8ff581 --- /dev/null +++ b/dumps/scripts/2707.cs2 @@ -0,0 +1,67 @@ +void script_2707(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,string arg7) { + int ivar7; + int ivar8; + int ivar9; + if (((arg0 == -1) || (arg2 == -1)) || ((boolean)stringMethod4107(arg7, ""))) { + return; + } + if (globalint_1 < add(getClientCycle(), arg3)) { + if (globalint_1 < getClientCycle()) { + globalint_1 = getClientCycle(); + } + globalint_1 = add(globalint_1, 2); + return; + } + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + arg5 = add(arg5, script_1743()); + arg6 = add(arg6, script_1744()); + } + globalint_1 = add(add(getClientCycle(), arg3), 10); + ivar7 = 0; + ivar8 = 0; + ivar9 = -1; + if (globalint_2 != 1) { + ivar9 = getWidgetParentId(new WidgetPointer(arg2)); + if ((ivar9 != -1) && (arg4 >= getWidgetActualWidth(new WidgetPointer(ivar9)))) { + arg4 = getWidgetActualWidth(new WidgetPointer(ivar9)); + } + ivar7 = add(6, getMaxLineWidth(subtract(arg4, 6), 495, arg7)); + ivar8 = add(6, multiply(16, getLineCount(subtract(arg4, 6), 495, arg7))); + setWidgetSize(ivar7, ivar8, 0, 0, new WidgetPointer(arg2)); + arg5 = subtract(subtract(arg5, 5), ivar7); + arg6 = subtract(subtract(arg6, 3), ivar8); + if (ivar9 != -1) { + if (add(arg5, ivar7) > getWidgetActualWidth(new WidgetPointer(ivar9))) { + arg5 = subtract(getWidgetActualWidth(new WidgetPointer(ivar9)), ivar7); + } + if (add(arg6, ivar8) > getWidgetActualHeight(new WidgetPointer(ivar9))) { + arg6 = subtract(getWidgetActualHeight(new WidgetPointer(ivar9)), ivar8); + } + } + if (arg5 < 0) { + arg5 = 0; + } + if (arg6 < 0) { + arg6 = 0; + } + setWidgetPosition(arg5, arg6, 0, 0, new WidgetPointer(arg2)); + deleteAllExtraChilds(new WidgetPointer(arg2)); + createExtraChild(new WidgetPointer(arg2), 3, 0); + setWidgetSize(ivar7, ivar8, 0, 0); + setWidgetFilled(1); + setWidgetRGB(new Color(255, 255, 160)); + createExtraChild(new WidgetPointer(arg2), 3, 1); + setWidgetSize(ivar7, ivar8, 0, 0); + setWidgetFilled(0); + setWidgetRGB(new Color(0, 0, 0)); + createExtraChild(new WidgetPointer(arg2), 4, 2); + setWidgetSize(subtract(arg4, 6), ivar8, 0, 0); + setWidgetPosition(0, 0, 1, 1); + setWidgetText(arg7); + setWidgetTextAlignment(1, 1, 16); + setWidgetFont(495); + setWidgetRGB(new Color(0, 0, 0)); + globalint_2 = 1; + } + return; +} diff --git a/dumps/scripts/2708.cs2 b/dumps/scripts/2708.cs2 new file mode 100644 index 0000000..a006eb5 --- /dev/null +++ b/dumps/scripts/2708.cs2 @@ -0,0 +1,79 @@ +void script_2708(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + cs2method3115(0, 0, 4, 3, 135, 30, 3791, 3792, 297, 16777215, 3793); + setWidgetSize(278, 90, 0, 0, new WidgetPointer(744,23)); + setWidgetSprite(2498, new WidgetPointer(744,23)); + setWidgetSprite(4140, new WidgetPointer(744,8)); + setWidgetSprite(4139, new WidgetPointer(744,9)); + setWidgetSprite(4141, new WidgetPointer(744,10)); + setWidgetSprite(4142, new WidgetPointer(744,11)); + setWidgetSprite(4144, new WidgetPointer(744,12)); + setWidgetSprite(4143, new WidgetPointer(744,13)); + setWidgetSprite(4145, new WidgetPointer(744,14)); + setWidgetSprite(4146, new WidgetPointer(744,15)); + setWidgetSprite(4129, new WidgetPointer(744,22)); + setWidgetSprite(4129, new WidgetPointer(744,97)); + setWidgetSprite(4129, new WidgetPointer(744,100)); + setWidgetSprite(4067, new WidgetPointer(744,70)); + setWidgetHFlip(1, new WidgetPointer(744,70)); + setWidgetVFlip(1, new WidgetPointer(744,70)); + setWidgetSprite(4067, new WidgetPointer(744,74)); + setWidgetHFlip(0, new WidgetPointer(744,74)); + setWidgetVFlip(1, new WidgetPointer(744,74)); + setWidgetSprite(4067, new WidgetPointer(744,4)); + setWidgetSprite(4067, new WidgetPointer(744,6)); + cs2method6039(rndExcl(18)); + if (globalint_176 <= 0) { + globalint_176 = multiply(add(rndExcl(5), 1), 10); + } + setScriptCallOnWidgetResize(3229, "", new WidgetPointer(744,17)); + script_3964(); + globalstring_32 = ""; + globalstring_33 = ""; + globalint_547 = 0; + globalint_1093 = 0; + openInterface(48758834, 882); + script_2595(0); + setScriptCallOnMousePressed(1173, 11, "i", new WidgetPointer(882,20)); + setScriptCallOnKeyPress(1221, -2147483640, false, "iz", new WidgetPointer(744,17)); + script_2710(arg0, arg1, arg2, arg3, arg4, arg5); + script_1129(); + if (isFromBilling()) { + globalint_1090 = 11; + globalint_1091 = 11; + script_3239(11, 1, 0); + } else { + if ((globalint_1240 == 2) && (cs2method6131() != 0)) { + globalint_1240 = 3; + } + if (((boolean)cs2method5420())) { + globalint_1240 = 3; + } + if ((cs2method6148() && ((boolean)cs2method5420())) && (((globalint_1240 < 3) || cs2method6144()) || ((boolean)cs2method6132()))) { + globalint_1090 = 0; + globalint_1091 = 0; + script_3239(0, 1, 0); + } else if (hasSSKey()) { + globalint_1090 = 5; + globalint_1091 = 5; + script_3239(5, 1, 0); + if (((boolean)globalint_1273)) { + return; + } + setScriptCallOnGameloop(3381, new WidgetPointer(975,44), 0, "Ii", new WidgetPointer(975,44)); + } else if (((boolean)script_3487(3))) { + globalint_1090 = 7; + globalint_1091 = 7; + script_3239(7, 1, 0); + } else { + globalint_1090 = 11; + globalint_1091 = 11; + script_3239(11, 1, 0); + } + } + script_3230(); + if (cs2method5436()) { + openInterface(48758900, 405); + cs2method2005(1, new WidgetPointer(744,116)); + } + return; +} diff --git a/dumps/scripts/2709.cs2 b/dumps/scripts/2709.cs2 new file mode 100644 index 0000000..ba3588d --- /dev/null +++ b/dumps/scripts/2709.cs2 @@ -0,0 +1,6 @@ +int script_2709() { + if (cs2method6910() == 8388605) { + return 0; + } + return 1; +} diff --git a/dumps/scripts/271.cs2 b/dumps/scripts/271.cs2 new file mode 100644 index 0000000..8b9b5b1 --- /dev/null +++ b/dumps/scripts/271.cs2 @@ -0,0 +1,10 @@ +void script_271() { + globalint_1109 = 0; + globalint_1110 = 0; + globalint_1104 = 0; + globalint_1105 = 0; + globalint_1106 = 0; + globalint_1107 = 0; + globalint_1108 = 0; + return; +} diff --git a/dumps/scripts/2710.cs2 b/dumps/scripts/2710.cs2 new file mode 100644 index 0000000..bd677f1 --- /dev/null +++ b/dumps/scripts/2710.cs2 @@ -0,0 +1,56 @@ +void script_2710(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + int ivar6; + int ivar7; + int stack_dump0; + cs2func_script_1239_struct(2,0,0) structdump_1; + cs2method2103(0, new WidgetPointer(arg2)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg2)); + setWidgetIsHidden(false, new WidgetPointer(arg2)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + setScriptCallOnMinimapRelatedSetting3(-1, "", new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(arg0)); + cs2method6021(true); + cs2method6035(true); + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg1)); + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(arg1)); + cs2method2103(0, new WidgetPointer(arg1)); + setWidgetIsHidden(false, new WidgetPointer(arg1)); + if (((boolean)globalint_994)) { + globalint_986 = 1; + } else { + if (globalint_994 != 2) { + if (getBenchmarkToolkit() > 400) { + globalint_994 = 1; + globalint_986 = 1; + if (getDisplayMode() > 1) { + cs2method5307(1); + } + if (cs2method5308() > 1) { + cs2method5309(1); + } + } else { + globalint_994 = 2; + } + } + } + setScriptCallOnMousePressed(2713, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), "IIIIII", new WidgetPointer(arg3)); + setScriptCallOnMouseOver(2961, new WidgetPointer(arg4), new WidgetPointer(arg5), 1, "II1", new WidgetPointer(arg3)); + setScriptCallOnMouseExit(2961, new WidgetPointer(arg4), new WidgetPointer(arg5), 0, "II1", new WidgetPointer(arg3)); + globalint_986 = 1; + if (((boolean)globalint_986)) { + setWidgetSprite(2700, new WidgetPointer(arg4)); + return; + } + ivar6 = -1; + ivar7 = 0; + stack_dump0 = 0; + structdump_1 = script_1239(stack_dump0); + ivar7 = structdump_1.intpart_1; + ivar6 = structdump_1.intpart_0; + cameraMoveTo(ivar6, 1000, 100, 100); + cameraPointAt(ivar6, 0, 100, 100); + setWidgetSprite(2703, new WidgetPointer(arg4)); + globalint_177 = add(add(getClientCycle(), 30), 30); + setScriptCallOnGameloop(2712, new WidgetPointer(arg0), new WidgetPointer(arg2), new WidgetPointer(arg1), "III", new WidgetPointer(arg2)); + return; +} diff --git a/dumps/scripts/2711.cs2 b/dumps/scripts/2711.cs2 new file mode 100644 index 0000000..18848a0 --- /dev/null +++ b/dumps/scripts/2711.cs2 @@ -0,0 +1,4 @@ +void script_2711(int arg0,int arg1) { + script_2714(arg0, arg1); + return; +} diff --git a/dumps/scripts/2712.cs2 b/dumps/scripts/2712.cs2 new file mode 100644 index 0000000..2b52236 --- /dev/null +++ b/dumps/scripts/2712.cs2 @@ -0,0 +1,15 @@ +void script_2712(int arg0,int arg1,int arg2) { + int ivar3; + if (getClientCycle() < globalint_177) { + return; + } + globalint_176 = add(globalint_176, 2); + ivar3 = mod(globalint_176, 10); + if (ivar3 != 2) { + globalint_176 = add(subtract(globalint_176, ivar3), 2); + } + setWidgetIsHidden(false, new WidgetPointer(arg0)); + setScriptCallOnGameloop(1249, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), "III", new WidgetPointer(arg0)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg1)); + return; +} diff --git a/dumps/scripts/2713.cs2 b/dumps/scripts/2713.cs2 new file mode 100644 index 0000000..4dc7133 --- /dev/null +++ b/dumps/scripts/2713.cs2 @@ -0,0 +1,46 @@ +void script_2713(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + int ivar6; + int ivar7; + int stack_dump0; + cs2func_script_1239_struct(2,0,0) structdump_1; + setScriptCallOnMousePressed(-1, "", new WidgetPointer(arg3)); + setScriptCallOnMouseOver(-1, "", new WidgetPointer(arg3)); + setScriptCallOnMouseOver(-1, "", new WidgetPointer(arg3)); + ivar6 = -1; + ivar7 = 0; + if (((boolean)globalint_986)) { + cs2method2103(0, new WidgetPointer(arg1)); + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(arg1)); + setWidgetIsHidden(false, new WidgetPointer(arg1)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg1)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg2)); + globalint_176 = subtract(globalint_176, mod(globalint_176, 10)); + stack_dump0 = 0; + structdump_1 = script_1239(stack_dump0); + ivar7 = structdump_1.intpart_1; + ivar6 = structdump_1.intpart_0; + cameraMoveTo(ivar6, 1000, 100, 100); + cameraPointAt(ivar6, 0, 100, 100); + setWidgetIsHidden(false, new WidgetPointer(arg0)); + setScriptCallOnGameloop(2962, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), add(getClientCycle(), 30), "IIIIIIi", new WidgetPointer(arg0)); + globalint_986 = 0; + globalint_994 = 2; + } else { + setScriptCallOnMinimapRelatedSetting3(-1, "", new WidgetPointer(arg0)); + if (isWidgetHidden(new WidgetPointer(arg1))) { + cs2method2103(255, new WidgetPointer(arg1)); + setWidgetIsHidden(false, new WidgetPointer(arg1)); + } + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(arg1)); + setScriptCallOnGameloop(1253, new WidgetPointer(-32768,3), "I", new WidgetPointer(arg1)); + if (isWidgetHidden(new WidgetPointer(arg2))) { + cs2method2103(255, new WidgetPointer(arg2)); + setWidgetIsHidden(false, new WidgetPointer(arg2)); + } + setScriptCallOnGameloop(1253, new WidgetPointer(-32768,3), "I", new WidgetPointer(arg2)); + setScriptCallOnGameloop(2963, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), add(getClientCycle(), 30), "IIIIIIi", new WidgetPointer(arg0)); + globalint_986 = 1; + } + script_3230(); + return; +} diff --git a/dumps/scripts/2714.cs2 b/dumps/scripts/2714.cs2 new file mode 100644 index 0000000..01efea1 --- /dev/null +++ b/dumps/scripts/2714.cs2 @@ -0,0 +1,70 @@ +void script_2714(int arg0,int arg1) { + int ivar2; + if (getAccountCreateRC() == -3) { + return; + } + ivar2 = globalint_174; + globalint_174 = arg0; + globalint_175 = getClientCycle(); + switch (arg0) { + case 6: + if (((boolean)arg1)) { + globalint_1099 = strLength(globalstring_122); + script_3218(44105828, 44105772, 44105829, 6, globalstring_122); + } + break; + case 14: + if (((boolean)arg1)) { + globalint_1099 = strLength(globalstring_326); + script_3218(44105847, 44105848, 44105849, 14, globalstring_326); + } + break; + case 7: + if (((boolean)arg1)) { + globalint_1099 = strLength(globalstring_124); + script_3218(44105818, 44105819, 44105820, 7, script_2949(globalstring_124)); + } + break; + case 8: + if (((boolean)arg1)) { + globalint_1099 = strLength(globalstring_125); + script_3218(44105808, 44105809, 44105810, 8, script_2949(globalstring_125)); + } + break; + case 15: + if (((boolean)arg1)) { + if (globalint_1407 < 1) { + globalint_1099 = 0; + script_3218(44105854, 44105771, 44105855, 15, ""); + } else { + globalint_1099 = strLength(intToStr(globalint_1407)); + script_3218(44105854, 44105771, 44105855, 15, intToStr(globalint_1407)); + } + } + } + if ((ivar2 == 6) && (arg0 != 6)) { + if (stringMethod4107(globalstring_123, globalstring_122) != 0) { + script_2283(0, 1); + } + } else if ((ivar2 == 14) && (arg0 != 14)) { + if (stringMethod4107(globalstring_327, globalstring_326) != 0) { + script_3953(0); + } + } else if ((ivar2 == 7) && (arg0 != 7)) { + if (stringMethod4107(globalstring_328, globalstring_124) != 0) { + script_3228(7, 0, 0); + if (strLength(globalstring_125) > 0) { + script_3228(8, 1, 0); + } + } + } else if ((ivar2 == 8) && (arg0 != 8)) { + if (stringMethod4107(globalstring_329, globalstring_125) != 0) { + script_3228(8, 1, 0); + } + } else { + if (((ivar2 == 15) && (arg0 != 15)) && (globalint_1408 != globalint_1407)) { + script_3954(0); + } + } + return; +} diff --git a/dumps/scripts/2715.cs2 b/dumps/scripts/2715.cs2 new file mode 100644 index 0000000..c12c64a --- /dev/null +++ b/dumps/scripts/2715.cs2 @@ -0,0 +1,6 @@ +void script_2715() { + setWidgetIsHidden(false, new WidgetPointer(669,14)); + setWidgetIsHidden(false, new WidgetPointer(669,27)); + setWidgetIsHidden(true, new WidgetPointer(669,13)); + return; +} diff --git a/dumps/scripts/2716.cs2 b/dumps/scripts/2716.cs2 new file mode 100644 index 0000000..15b3e6c --- /dev/null +++ b/dumps/scripts/2716.cs2 @@ -0,0 +1,6 @@ +void script_2716(int arg0,int arg1) { + script_2723(arg0, arg1, standart_config_118, standart_config_1496); + setScriptCallOnItemContainerUpdate(2722, new WidgetPointer(arg0), new WidgetPointer(arg1), standart_config_118, standart_config_1496, standart_config_118, 1, "IIvvY", new WidgetPointer(arg0)); + setScriptCallOnGlobalConfigChange(2722, new WidgetPointer(arg0), new WidgetPointer(arg1), standart_config_118, standart_config_1496, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 40, "IIvvY", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/2717.cs2 b/dumps/scripts/2717.cs2 new file mode 100644 index 0000000..7756c36 --- /dev/null +++ b/dumps/scripts/2717.cs2 @@ -0,0 +1,9 @@ +void script_2717(int arg0) { + if (standart_config_1496 != -1) { + script_2726(arg0, standart_config_1496); + setScriptCallOnItemContainerUpdate(2725, new WidgetPointer(arg0), standart_config_1496, standart_config_1496, 1, "IvY", new WidgetPointer(arg0)); + setWidgetIsHidden(false, new WidgetPointer(620,22)); + setWidgetIsHidden(false, new WidgetPointer(620,21)); + } + return; +} diff --git a/dumps/scripts/2718.cs2 b/dumps/scripts/2718.cs2 new file mode 100644 index 0000000..2751e0a --- /dev/null +++ b/dumps/scripts/2718.cs2 @@ -0,0 +1,12 @@ +void script_2718(int arg0,int arg1,int arg2) { + int ivar3; + ivar3 = 464; + if (((boolean)arg1)) { + ivar3 = 448; + } + setWidgetPosition(getWidgetActualX(new WidgetPointer(arg0)), 118, 0, 0, new WidgetPointer(arg0)); + setWidgetSize(ivar3, 181, 0, 0, new WidgetPointer(arg0)); + setWidgetPosition(474, 120, 0, 0, new WidgetPointer(arg2)); + setWidgetSize(16, 181, 0, 0, new WidgetPointer(arg2)); + return; +} diff --git a/dumps/scripts/2719.cs2 b/dumps/scripts/2719.cs2 new file mode 100644 index 0000000..d94e8c9 --- /dev/null +++ b/dumps/scripts/2719.cs2 @@ -0,0 +1,7 @@ +void script_2719(int arg0,int arg1) { + setWidgetPosition(getWidgetActualX(new WidgetPointer(arg0)), 46, 0, 0, new WidgetPointer(arg0)); + setWidgetSize(464, 255, 0, 0, new WidgetPointer(arg0)); + setWidgetPosition(474, 46, 0, 0, new WidgetPointer(arg1)); + setWidgetSize(16, 255, 0, 0, new WidgetPointer(arg1)); + return; +} diff --git a/dumps/scripts/272.cs2 b/dumps/scripts/272.cs2 new file mode 100644 index 0000000..31c5584 --- /dev/null +++ b/dumps/scripts/272.cs2 @@ -0,0 +1,4 @@ +void script_272() { + script_273(); + return; +} diff --git a/dumps/scripts/2720.cs2 b/dumps/scripts/2720.cs2 new file mode 100644 index 0000000..898c7c8 --- /dev/null +++ b/dumps/scripts/2720.cs2 @@ -0,0 +1,48 @@ +int script_2720(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + arg0 = getRealItem(arg0); + ivar2 = cs2method_3408(111, 105, 731, arg0); + if (((standart_config_532 == 6529) && (ivar2 != -1)) && (ivar2 > 0)) { + return ivar2; + } + ivar2 = cs2method_3408(111, 105, 733, arg0); + if ((ivar2 != -1) && (ivar2 > 0)) { + return ivar2; + } + if (((boolean)getItemHashmapData(arg0, 258)) || ((boolean)getItemHashmapData(arg0, 259))) { + return 99000; + } + ivar3 = 130; + ivar4 = 100; + ivar5 = 0; + ivar6 = script_2721(arg1); + if (ivar6 == -1) { + return -1; + } + ivar7 = getItemAmtInContainer(standart_config_118, arg0); + ivar8 = subtract(ivar7, ivar6); + if (((boolean)ivar6)) { + ivar5 = ivar4; + } else if (((boolean)ivar7)) { + ivar5 = ivar3; + } else if (ivar7 >= ivar6) { + ivar5 = ivar4; + } else { + ivar5 = subtract(ivar3, multiplyDivide(subtract(ivar3, ivar4), ivar6, ivar7)); + } + if (ivar5 < 0) { + ivar5 = 0; + } + ivar5 = max(ivar4, min(ivar3, ivar5)); + ivar2 = multiplyDivide(getItemValue(arg0), 100, ivar5); + if (standart_config_532 == 6529) { + ivar2 = multiplyDivide(3, 2, ivar2); + } + return max(ivar2, 1); +} diff --git a/dumps/scripts/2721.cs2 b/dumps/scripts/2721.cs2 new file mode 100644 index 0000000..87ba161 --- /dev/null +++ b/dumps/scripts/2721.cs2 @@ -0,0 +1,126 @@ +int script_2721(int arg0) { + int ivar1; + ivar1 = -1; + switch (arg0) { + case 0: + ivar1 = globalint_946; + break; + case 1: + ivar1 = globalint_947; + break; + case 2: + ivar1 = globalint_948; + break; + case 3: + ivar1 = globalint_949; + break; + case 4: + ivar1 = globalint_950; + break; + case 5: + ivar1 = globalint_951; + break; + case 6: + ivar1 = globalint_952; + break; + case 7: + ivar1 = globalint_953; + break; + case 8: + ivar1 = globalint_954; + break; + case 9: + ivar1 = globalint_955; + break; + case 10: + ivar1 = globalint_956; + break; + case 11: + ivar1 = globalint_957; + break; + case 12: + ivar1 = globalint_958; + break; + case 13: + ivar1 = globalint_959; + break; + case 14: + ivar1 = globalint_960; + break; + case 15: + ivar1 = globalint_961; + break; + case 16: + ivar1 = globalint_962; + break; + case 17: + ivar1 = globalint_963; + break; + case 18: + ivar1 = globalint_964; + break; + case 19: + ivar1 = globalint_965; + break; + case 20: + ivar1 = globalint_966; + break; + case 21: + ivar1 = globalint_967; + break; + case 22: + ivar1 = globalint_968; + break; + case 23: + ivar1 = globalint_969; + break; + case 24: + ivar1 = globalint_970; + break; + case 25: + ivar1 = globalint_971; + break; + case 26: + ivar1 = globalint_972; + break; + case 27: + ivar1 = globalint_973; + break; + case 28: + ivar1 = globalint_974; + break; + case 29: + ivar1 = globalint_975; + break; + case 30: + ivar1 = globalint_976; + break; + case 31: + ivar1 = globalint_977; + break; + case 32: + ivar1 = globalint_978; + break; + case 33: + ivar1 = globalint_979; + break; + case 34: + ivar1 = globalint_980; + break; + case 35: + ivar1 = globalint_981; + break; + case 36: + ivar1 = globalint_982; + break; + case 37: + ivar1 = globalint_983; + break; + case 38: + ivar1 = globalint_984; + break; + case 39: + ivar1 = globalint_985; + } + return ivar1; +} diff --git a/dumps/scripts/2722.cs2 b/dumps/scripts/2722.cs2 new file mode 100644 index 0000000..2db349c --- /dev/null +++ b/dumps/scripts/2722.cs2 @@ -0,0 +1,4 @@ +void script_2722(int arg0,int arg1,int arg2,int arg3) { + script_2723(arg0, arg1, arg2, arg3); + return; +} diff --git a/dumps/scripts/2723.cs2 b/dumps/scripts/2723.cs2 new file mode 100644 index 0000000..cb55552 --- /dev/null +++ b/dumps/scripts/2723.cs2 @@ -0,0 +1,163 @@ +void script_2723(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + string svar0; + deleteAllExtraChilds(new WidgetPointer(arg0)); + ivar4 = 1; + if (getWidgetScrollMaxV(new WidgetPointer(arg0)) > 0) { + ivar4 = 0; + } + ivar5 = -1; + ivar6 = 0; + ivar7 = getItemContainerLength(arg2); + ivar8 = 4; + if (arg3 != -1) { + while (ivar6 < ivar7) { + if (getItemIdInSlot(arg2, ivar6) != -1) { + ivar5 = ivar6; + } + ivar6 = add(ivar6, 1); + } + if (ivar5 > 26) { + setWidgetScrollMax(0, multiply(63, add(divide(ivar5, 9), 1)), new WidgetPointer(arg0)); + if (((boolean)ivar4)) { + script_31(arg1, arg0, 792, 789, 790, 791, 773, 788); + } else { + script_72(arg1, arg0, cs2method2601(new WidgetPointer(arg0))); + } + script_2718(arg0, 1, arg1); + ivar8 = 2; + } else { + setWidgetScrollMax(0, 0, new WidgetPointer(arg0)); + cs2method2100(0, 0, new WidgetPointer(arg0)); + deleteAllExtraChilds(new WidgetPointer(arg1)); + script_2718(arg0, 0, arg1); + ivar8 = 4; + } + } else { + script_2719(arg0, arg1); + while (ivar6 < ivar7) { + if (getItemIdInSlot(arg2, ivar6) != -1) { + ivar5 = ivar6; + } + ivar6 = add(ivar6, 1); + } + if (ivar5 > 35) { + setWidgetScrollMax(0, multiply(63, add(divide(ivar5, 9), 1)), new WidgetPointer(arg0)); + if (((boolean)ivar4)) { + script_31(arg1, arg0, 792, 789, 790, 791, 773, 788); + } else { + script_72(arg1, arg0, cs2method2601(new WidgetPointer(arg0))); + } + ivar8 = 2; + } else { + setWidgetScrollMax(0, 0, new WidgetPointer(arg0)); + cs2method2100(0, 0, new WidgetPointer(arg0)); + deleteAllExtraChilds(new WidgetPointer(arg1)); + ivar8 = 4; + } + } + ivar6 = 0; + ivar9 = 0; + ivar10 = 0; + ivar11 = 0; + ivar12 = -1; + ivar13 = 0; + svar0 = ""; + ivar14 = 0; + ivar15 = 0; + while (ivar6 < ivar7) { + ivar12 = getItemIdInSlot(arg2, ivar6); + if (ivar12 != -1) { + if (((boolean)getItemHashmapData(ivar12, 258)) || ((boolean)getItemHashmapData(ivar12, 259))) { + ivar15 = 1; + } else { + ivar15 = 0; + } + ivar10 = add(multiply(mod(ivar6, 9), 48), multiply(mod(ivar6, 9), ivar8)); + ivar11 = add(multiply(divide(ivar6, 9), 52), multiply(divide(ivar6, 9), 13)); + createExtraChild(new WidgetPointer(arg0), 5, ivar9); + ivar9 = add(ivar9, 1); + setWidgetSize(48, 52, 0, 0); + setWidgetPosition(ivar10, ivar11, 0, 0); + setWidgetSprite(2205); + cs2method1305("" + getItemName(ivar12) + ""); + setWidgetContextMenuOption(1, "Info"); + setWidgetContextMenuOption(2, "Buy 1"); + setWidgetContextMenuOption(10, "Examine"); + if (((boolean)ivar15)) { + setWidgetContextMenuOption(3, "Buy 5"); + setWidgetContextMenuOption(4, "Buy 10"); + setWidgetContextMenuOption(5, "Buy 50"); + setWidgetContextMenuOption(6, "Buy 500"); + } + setScriptCallOnMouseEntered(2724, new WidgetPointer(-32768,3), ivar9, 0, "Ii1"); + setScriptCallOnMouseExit(2724, new WidgetPointer(-32768,3), ivar9, 1, "Ii1"); + createExtraChild(new WidgetPointer(arg0), 5, ivar9); + ivar9 = add(ivar9, 1); + setWidgetSize(48, 52, 0, 0); + setWidgetPosition(ivar10, ivar11, 0, 0); + setWidgetSprite(2206); + setWidgetHidden(1); + createExtraChild(new WidgetPointer(arg0), 5, ivar9); + ivar9 = add(ivar9, 1); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(add(ivar10, 6), add(ivar11, 4), 0, 0); + if (((boolean)ivar15)) { + setItemOnWidgetMethod1205(ivar12, getItemAmtInSlot(arg2, ivar6)); + } else { + setItemOnWidgetMethod1212(ivar12, getItemAmtInSlot(arg2, ivar6)); + } + setWidgetShadowColor(new Color(48, 32, 32)); + setWidgetBorderThickness(1); + createExtraChild(new WidgetPointer(arg0), 5, ivar9); + ivar9 = add(ivar9, 1); + setWidgetSize(12, 12, 0, 0); + setWidgetPosition(add(ivar10, 2), add(ivar11, 38), 0, 0); + setWidgetSprite(cs2method_3408(111, 100, 200, standart_config_532)); + createExtraChild(new WidgetPointer(arg0), 4, ivar9); + ivar9 = add(ivar9, 1); + setWidgetSize(31, 12, 0, 0); + setWidgetPosition(add(ivar10, 13), add(ivar11, 39), 0, 0); + setWidgetFont(494); + setWidgetTextAlignment(2, 1, 0); + ivar14 = script_2720(ivar12, ivar6); + if (ivar14 == -1) { + setWidgetText("N/A"); + } else { + setWidgetText(script_940(ivar14)); + } + setWidgetRGB(new Color(script_1146(ivar14))); + setWidgetUnknownBoolean(true); + createExtraChild(new WidgetPointer(arg0), 5, ivar9); + ivar9 = add(ivar9, 1); + setWidgetSize(12, 12, 0, 0); + setWidgetPosition(add(ivar10, 33), add(ivar11, 4), 0, 0); + setWidgetSprite(2180); + script_812(ivar12); + svar0 = script_2706(ivar12); + setScriptCallOnMouseOver(2707, new WidgetPointer(-32768,3), -2147483643, new WidgetPointer(620,34), svar0, 25, 200, -2147483647, -2147483646, "IiIsiiii"); + setScriptCallOnMouseExit(40, new WidgetPointer(620,34), "I"); + } else { + ivar13 = 0; + while (ivar13 < 6) { + createExtraChild(new WidgetPointer(arg0), 3, ivar9); + setWidgetHidden(1); + ivar9 = add(ivar9, 1); + ivar13 = add(ivar13, 1); + } + } + ivar6 = add(ivar6, 1); + } + return; +} diff --git a/dumps/scripts/2724.cs2 b/dumps/scripts/2724.cs2 new file mode 100644 index 0000000..2a46075 --- /dev/null +++ b/dumps/scripts/2724.cs2 @@ -0,0 +1,6 @@ +void script_2724(int arg0,int arg1,int arg2) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetHidden(arg2); + } + return; +} diff --git a/dumps/scripts/2725.cs2 b/dumps/scripts/2725.cs2 new file mode 100644 index 0000000..be7ad00 --- /dev/null +++ b/dumps/scripts/2725.cs2 @@ -0,0 +1,4 @@ +void script_2725(int arg0,int arg1) { + script_2726(arg0, arg1); + return; +} diff --git a/dumps/scripts/2726.cs2 b/dumps/scripts/2726.cs2 new file mode 100644 index 0000000..de27af8 --- /dev/null +++ b/dumps/scripts/2726.cs2 @@ -0,0 +1,76 @@ +void script_2726(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + setWidgetIsHidden(false, new WidgetPointer(620,26)); + deleteAllExtraChilds(new WidgetPointer(arg0)); + ivar2 = 0; + ivar3 = getItemContainerLength(arg1); + ivar4 = 0; + ivar5 = 0; + ivar6 = -1; + ivar7 = 0; + while (ivar2 < ivar3) { + ivar6 = getItemIdInSlot(arg1, ivar2); + if (ivar6 != -1) { + ivar5 = add(multiply(mod(ivar2, 9), 48), multiply(mod(ivar2, 9), 4)); + createExtraChild(new WidgetPointer(arg0), 5, ivar4); + ivar4 = add(ivar4, 1); + setWidgetSize(48, 52, 0, 0); + setWidgetPosition(ivar5, 0, 0, 0); + setWidgetSprite(2205); + cs2method1305("" + getItemName(ivar6) + ""); + setWidgetContextMenuOption(1, "Info"); + setWidgetContextMenuOption(2, "Take 1"); + setWidgetContextMenuOption(3, "Take 5"); + setWidgetContextMenuOption(4, "Take 10"); + setWidgetContextMenuOption(5, "Take 50"); + setWidgetContextMenuOption(10, "Examine"); + setScriptCallOnMouseEntered(2724, new WidgetPointer(-32768,3), ivar4, 0, "Ii1"); + setScriptCallOnMouseExit(2724, new WidgetPointer(-32768,3), ivar4, 1, "Ii1"); + createExtraChild(new WidgetPointer(arg0), 5, ivar4); + ivar4 = add(ivar4, 1); + setWidgetSize(48, 52, 0, 0); + setWidgetPosition(ivar5, 0, 0, 0); + setWidgetSprite(2206); + setWidgetHidden(1); + createExtraChild(new WidgetPointer(arg0), 5, ivar4); + ivar4 = add(ivar4, 1); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(add(ivar5, 6), 4, 0, 0); + setItemOnWidgetMethod1212(ivar6, getItemAmtInSlot(arg1, ivar2)); + setWidgetShadowColor(new Color(48, 32, 32)); + setWidgetBorderThickness(1); + createExtraChild(new WidgetPointer(arg0), 4, ivar4); + ivar4 = add(ivar4, 1); + setWidgetSize(32, 12, 0, 0); + setWidgetPosition(add(ivar5, 13), 39, 0, 0); + setWidgetFont(494); + setWidgetRGB(new Color(255, 255, 0)); + setWidgetText("Free"); + setWidgetTextAlignment(2, 1, 0); + setWidgetUnknownBoolean(true); + } else { + ivar7 = 0; + while (ivar7 < 4) { + createExtraChild(new WidgetPointer(arg0), 3, ivar4); + setWidgetHidden(1); + ivar4 = add(ivar4, 1); + ivar7 = add(ivar7, 1); + } + } + ivar2 = add(ivar2, 1); + } + setWidgetIsHidden(false, new WidgetPointer(620,27)); + setWidgetIsHidden(false, new WidgetPointer(620,28)); + setWidgetIsHidden(false, new WidgetPointer(620,29)); + setWidgetIsHidden(false, new WidgetPointer(620,30)); + setWidgetIsHidden(false, new WidgetPointer(620,31)); + setWidgetIsHidden(false, new WidgetPointer(620,23)); + setItemOnWidgetMethod2205(1931, 1, new WidgetPointer(620,28)); + setWidgetSprite(cs2method_3408(111, 100, 200, standart_config_532), new WidgetPointer(620,29)); + return; +} diff --git a/dumps/scripts/2727.cs2 b/dumps/scripts/2727.cs2 new file mode 100644 index 0000000..ea02821 --- /dev/null +++ b/dumps/scripts/2727.cs2 @@ -0,0 +1,6 @@ +int script_2727() { + if (isBitFlagged(cs2method6510(), 10)) { + return 1; + } + return 0; +} diff --git a/dumps/scripts/2728.cs2 b/dumps/scripts/2728.cs2 new file mode 100644 index 0000000..2ca5090 --- /dev/null +++ b/dumps/scripts/2728.cs2 @@ -0,0 +1,14 @@ +int script_2728() { + int ivar0; + if (script_2761() > 100) { + return 0; + } + ivar0 = getCommonDefinitionSize(681); + while (ivar0 > 0) { + if (getSkillActualLvl(cs2method_3408(105, 83, 681, ivar0)) > 20) { + return 0; + } + ivar0 = subtract(ivar0, 1); + } + return 1; +} diff --git a/dumps/scripts/2729.cs2 b/dumps/scripts/2729.cs2 new file mode 100644 index 0000000..2c7aa39 --- /dev/null +++ b/dumps/scripts/2729.cs2 @@ -0,0 +1,16 @@ +void script_2729(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + ivar4 = getDisplayMode(); + if (ivar4 != 1) { + if (arg3 != 1) { + return; + } + } else { + if (((boolean)arg3)) { + return; + } + } + script_2730(arg1, arg2, ivar4); + setScriptCallOnGameloop(2729, new WidgetPointer(-32768,3), new WidgetPointer(arg1), new WidgetPointer(arg2), ivar4, "IIIi", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/273.cs2 b/dumps/scripts/273.cs2 new file mode 100644 index 0000000..7f0f5ed --- /dev/null +++ b/dumps/scripts/273.cs2 @@ -0,0 +1,9 @@ +void script_273() { + setWidgetSize(getWidgetActualWidth(new WidgetPointer(919,1)), 185, 0, 0, new WidgetPointer(919,1)); + setScriptCallOnClickContextMenu(274, "", new WidgetPointer(919,23)); + setWidgetText(new WidgetPointer(919,31), "Hide"); + script_31(60227589, 60227590, 792, 789, 790, 791, 773, 788); + setWidgetVFlip(1, new WidgetPointer(919,29)); + setWidgetVFlip(1, new WidgetPointer(919,30)); + return; +} diff --git a/dumps/scripts/2730.cs2 b/dumps/scripts/2730.cs2 new file mode 100644 index 0000000..1adcbc4 --- /dev/null +++ b/dumps/scripts/2730.cs2 @@ -0,0 +1,14 @@ +void script_2730(int arg0,int arg1,int arg2) { + if (arg2 != 1) { + setWidgetSprite(297, new WidgetPointer(arg0)); + setWidgetSize(0, 0, 1, 1, new WidgetPointer(arg0)); + cs2method2107(1, new WidgetPointer(arg0)); + setWidgetUnknownBoolean(true, new WidgetPointer(arg1)); + } else { + setWidgetSprite(1017, new WidgetPointer(arg0)); + setWidgetSize(519, 142, 0, 0, new WidgetPointer(arg0)); + cs2method2107(0, new WidgetPointer(arg0)); + setWidgetUnknownBoolean(false, new WidgetPointer(arg1)); + } + return; +} diff --git a/dumps/scripts/2731.cs2 b/dumps/scripts/2731.cs2 new file mode 100644 index 0000000..516bc14 --- /dev/null +++ b/dumps/scripts/2731.cs2 @@ -0,0 +1,5 @@ +void script_2731(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7) { + script_2732(arg0, arg1, bitconfig_3612, 1); + setScriptCallOnClickContextMenu(2733, -2147483644, arg1, new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), new WidgetPointer(arg6), new WidgetPointer(arg7), "iiIIIIII", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/2732.cs2 b/dumps/scripts/2732.cs2 new file mode 100644 index 0000000..a6c800a --- /dev/null +++ b/dumps/scripts/2732.cs2 @@ -0,0 +1,31 @@ +void script_2732(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + deleteAllExtraChilds(new WidgetPointer(arg0)); + createExtraChild(new WidgetPointer(arg0), 3, 0); + setWidgetSize(2, 2, 1, 1); + setWidgetPosition(0, 0, 1, 1); + setWidgetFilled(1); + if (((boolean)arg3)) { + setWidgetRGB(new Color(cs2method_3408(105, 105, 3724, arg1))); + } else if (arg3 == 2) { + setWidgetRGB(new Color(cs2method_3408(105, 105, 3723, arg1))); + } else if (arg3 == 3) { + setWidgetRGB(new Color(cs2method_3408(105, 105, 3726, arg1))); + } else { + setWidgetRGB(new Color(cs2method_3408(105, 105, 3056, arg1))); + } + createExtraChild(new WidgetPointer(arg0), 5, 1); + setWidgetSize(20, 20, 0, 0); + setWidgetPosition(0, 0, 1, 1); + ivar4 = 2289; + ivar5 = 2288; + if (arg2 == arg1) { + setWidgetSprite(ivar4); + } else { + setWidgetSprite(ivar5); + setScriptCallOnMouseEntered(688, new WidgetPointer(-32768,3), getWidgetCustomChildArrayIndex(), ivar4, "Iid", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(688, new WidgetPointer(-32768,3), getWidgetCustomChildArrayIndex(), ivar5, "Iid", new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/2733.cs2 b/dumps/scripts/2733.cs2 new file mode 100644 index 0000000..c8878ce --- /dev/null +++ b/dumps/scripts/2733.cs2 @@ -0,0 +1,12 @@ +void script_2733(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7) { + if (arg0 != 1) { + return; + } + if (bitconfig_3612 == arg1) { + return; + } + bitconfig_3612 = arg1; + playSoundEffect(2266, 1, 0); + script_2735(arg2, arg3, arg4, arg5, arg6, arg7); + return; +} diff --git a/dumps/scripts/2734.cs2 b/dumps/scripts/2734.cs2 new file mode 100644 index 0000000..ddc14dd --- /dev/null +++ b/dumps/scripts/2734.cs2 @@ -0,0 +1,4 @@ +void script_2734(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + script_2735(arg0, arg1, arg2, arg3, arg4, arg5); + return; +} diff --git a/dumps/scripts/2735.cs2 b/dumps/scripts/2735.cs2 new file mode 100644 index 0000000..db671c5 --- /dev/null +++ b/dumps/scripts/2735.cs2 @@ -0,0 +1,95 @@ +void script_2735(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + if (standart_config_287 <= 0) { + setWidgetIsHidden(false, new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(arg2)); + } else { + setWidgetIsHidden(true, new WidgetPointer(arg0)); + setWidgetIsHidden(false, new WidgetPointer(arg2)); + } + setWidgetRGB(new Color(cs2method_3408(105, 105, 3724, bitconfig_3612)), new WidgetPointer(arg1)); + setWidgetRGB(new Color(cs2method_3408(105, 105, 3056, standart_config_287)), new WidgetPointer(arg3)); + setWidgetRGB(new Color(cs2method_3408(105, 105, 3723, bitconfig_9188)), new WidgetPointer(arg4)); + setWidgetRGB(new Color(cs2method_3408(105, 105, 3726, bitconfig_9191)), new WidgetPointer(arg5)); + setWidgetUnknownBoolean(((boolean)cs2method_3408(105, 49, 3057, standart_config_287)), new WidgetPointer(arg3)); + script_3418(64356369, 0, bitconfig_3612); + script_3418(64356370, 1, bitconfig_3612); + script_3418(64356371, 2, bitconfig_3612); + script_3418(64356372, 3, bitconfig_3612); + script_3418(64356373, 4, bitconfig_3612); + script_3418(64356374, 5, bitconfig_3612); + script_3418(64356375, 6, bitconfig_3612); + script_3418(64356376, 7, bitconfig_3612); + script_3418(64356377, 8, bitconfig_3612); + script_3418(64356378, 9, bitconfig_3612); + script_3418(64356379, 10, bitconfig_3612); + script_3418(64356380, 11, bitconfig_3612); + script_3418(64356381, 12, bitconfig_3612); + script_3418(64356382, 13, bitconfig_3612); + script_3418(64356383, 14, bitconfig_3612); + script_3418(64356384, 15, bitconfig_3612); + script_3418(64356385, 20, bitconfig_3612); + script_3418(64356386, 17, bitconfig_3612); + script_3418(64356387, 18, bitconfig_3612); + script_3418(64356388, 19, bitconfig_3612); + script_3418(64356449, 0, bitconfig_9191); + script_3418(64356450, 1, bitconfig_9191); + script_3418(64356451, 2, bitconfig_9191); + script_3418(64356452, 3, bitconfig_9191); + script_3418(64356453, 4, bitconfig_9191); + script_3418(64356454, 5, bitconfig_9191); + script_3418(64356455, 6, bitconfig_9191); + script_3418(64356456, 7, bitconfig_9191); + script_3418(64356457, 8, bitconfig_9191); + script_3418(64356458, 9, bitconfig_9191); + script_3418(64356459, 10, bitconfig_9191); + script_3418(64356460, 11, bitconfig_9191); + script_3418(64356461, 12, bitconfig_9191); + script_3418(64356462, 13, bitconfig_9191); + script_3418(64356463, 14, bitconfig_9191); + script_3418(64356464, 15, bitconfig_9191); + script_3418(64356465, 20, bitconfig_9191); + script_3418(64356466, 17, bitconfig_9191); + script_3418(64356467, 18, bitconfig_9191); + script_3418(64356468, 19, bitconfig_9191); + script_3418(64356424, 0, bitconfig_9188); + script_3418(64356425, 1, bitconfig_9188); + script_3418(64356426, 2, bitconfig_9188); + script_3418(64356427, 3, bitconfig_9188); + script_3418(64356428, 4, bitconfig_9188); + script_3418(64356429, 5, bitconfig_9188); + script_3418(64356430, 6, bitconfig_9188); + script_3418(64356431, 7, bitconfig_9188); + script_3418(64356432, 8, bitconfig_9188); + script_3418(64356433, 9, bitconfig_9188); + script_3418(64356434, 10, bitconfig_9188); + script_3418(64356435, 11, bitconfig_9188); + script_3418(64356436, 12, bitconfig_9188); + script_3418(64356437, 13, bitconfig_9188); + script_3418(64356438, 14, bitconfig_9188); + script_3418(64356439, 15, bitconfig_9188); + script_3418(64356440, 20, bitconfig_9188); + script_3418(64356441, 17, bitconfig_9188); + script_3418(64356442, 18, bitconfig_9188); + script_3418(64356443, 19, bitconfig_9188); + script_3418(64356401, 1, standart_config_287); + script_3418(64356402, 2, standart_config_287); + script_3418(64356403, 3, standart_config_287); + script_3418(64356404, 4, standart_config_287); + script_3418(64356405, 5, standart_config_287); + script_3418(64356406, 6, standart_config_287); + script_3418(64356407, 7, standart_config_287); + script_3418(64356408, 8, standart_config_287); + script_3418(64356409, 9, standart_config_287); + script_3418(64356410, 10, standart_config_287); + script_3418(64356411, 11, standart_config_287); + script_3418(64356412, 12, standart_config_287); + script_3418(64356413, 13, standart_config_287); + script_3418(64356414, 14, standart_config_287); + script_3418(64356415, 15, standart_config_287); + script_3418(64356416, 16, standart_config_287); + script_3418(64356417, 17, standart_config_287); + script_3418(64356418, 18, standart_config_287); + script_84(); + script_89(); + return; +} diff --git a/dumps/scripts/2736.cs2 b/dumps/scripts/2736.cs2 new file mode 100644 index 0000000..0183292 --- /dev/null +++ b/dumps/scripts/2736.cs2 @@ -0,0 +1,15 @@ +void script_2736() { + if (((boolean)bitconfig_6084)) { + if (((boolean)globalint_774)) { + return; + } + globalint_774 = 1; + } else { + if (((boolean)globalint_774)) { + return; + } + globalint_774 = 0; + } + script_2790(); + return; +} diff --git a/dumps/scripts/2737.cs2 b/dumps/scripts/2737.cs2 new file mode 100644 index 0000000..1cf1bdd --- /dev/null +++ b/dumps/scripts/2737.cs2 @@ -0,0 +1,4 @@ +void script_2737(int arg0) { + script_2739(arg0, -1); + return; +} diff --git a/dumps/scripts/2738.cs2 b/dumps/scripts/2738.cs2 new file mode 100644 index 0000000..a265200 --- /dev/null +++ b/dumps/scripts/2738.cs2 @@ -0,0 +1,4 @@ +void script_2738(int arg0,int arg1) { + script_2739(arg0, arg1); + return; +} diff --git a/dumps/scripts/2739.cs2 b/dumps/scripts/2739.cs2 new file mode 100644 index 0000000..b2901e1 --- /dev/null +++ b/dumps/scripts/2739.cs2 @@ -0,0 +1,46 @@ +void script_2739(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + deleteAllExtraChilds(new WidgetPointer(arg0)); + ivar2 = getItemContainerLength(93); + ivar3 = -1; + ivar4 = divide(ivar2, 4); + ivar5 = divide(subtract(getWidgetActualWidth(new WidgetPointer(arg0)), multiply(4, 36)), 3); + ivar6 = divide(subtract(getWidgetActualHeight(new WidgetPointer(arg0)), multiply(ivar4, 32)), 6); + ivar7 = 0; + while (ivar7 < ivar2) { + createExtraChild(new WidgetPointer(arg0), 5, ivar7); + ivar3 = getItemIdInSlot(93, ivar7); + if (ivar3 != -1) { + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(multiply(mod(ivar7, 4), add(36, ivar5)), multiply(divide(ivar7, 4), add(32, ivar6)), 0, 0); + setItemOnWidgetMethod1200(ivar3, getItemAmtInSlot(93, ivar7)); + cs2method1305(concat("", getItemName(ivar3))); + setWidgetContextMenuOption(1, "Equip"); + setWidgetContextMenuOption(9, "Stats"); + cs2method1306("Compare"); + setWidgetContextMenuOption(10, "Examine"); + setWidgetShadowColor(new Color(48, 32, 32)); + if (arg1 == ivar7) { + setWidgetBorderThickness(2); + } else { + setWidgetBorderThickness(1); + } + setScriptCallOnClickContextMenu(1620, new WidgetPointer(-32768,3), -2147483643, 100, 0, 8, "Iiiii"); + setScriptCallOnUse(2738, new WidgetPointer(arg0), ivar7, "Ii"); + setScriptCallOnUseWith(2738, new WidgetPointer(arg0), -1, "Ii"); + } else { + setWidgetHidden(1); + } + ivar7 = add(ivar7, 1); + } + if ((arg1 != -1) && (getItemIdInSlot(93, arg1) == -1)) { + arg1 = -1; + } + setScriptCallOnItemContainerUpdate(2738, new WidgetPointer(-32768,3), arg1, 93, 1, "IiY", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/274.cs2 b/dumps/scripts/274.cs2 new file mode 100644 index 0000000..d2fea38 --- /dev/null +++ b/dumps/scripts/274.cs2 @@ -0,0 +1,4 @@ +void script_274() { + script_275(); + return; +} diff --git a/dumps/scripts/2740.cs2 b/dumps/scripts/2740.cs2 new file mode 100644 index 0000000..9e8c37c --- /dev/null +++ b/dumps/scripts/2740.cs2 @@ -0,0 +1,59 @@ +void script_2740(int arg0) { + int ivar1; + ivar1 = script_284(getMyPositionHash()); + switch (globalint_1007) { + case 1: + script_2766(0, 50, arg0); + break; + case 2: + script_2768(50, arg0); + cs2method5405(0, 2); + cs2method5405(1, 2); + cs2method5406(0, 0, addToCoordinate(ivar1, 31, 0, 37), 900, addToCoordinate(ivar1, 31, 0, 37), 900, 0); + cs2method5406(0, 1, addToCoordinate(ivar1, 31, 0, 39), 750, addToCoordinate(ivar1, 31, 0, 39), 750, 0); + cs2method5406(1, 0, addToCoordinate(ivar1, 31, 0, 43), 700, addToCoordinate(ivar1, 31, 0, 43), 700, 0); + cs2method5406(1, 1, addToCoordinate(ivar1, 31, 0, 43), 700, addToCoordinate(ivar1, 31, 0, 43), 700, 0); + cameraMethod5502(0, 0, 50, 0, 1, 0); + break; + case 3: + script_2768(50, arg0); + cs2method5405(0, 2); + cs2method5405(1, 2); + cs2method5406(0, 0, addToCoordinate(ivar1, 31, 0, 27), 900, addToCoordinate(ivar1, 31, 0, 27), 900, 0); + cs2method5406(0, 1, addToCoordinate(ivar1, 31, 0, 27), 1000, addToCoordinate(ivar1, 31, 0, 27), 1000, 0); + cs2method5406(1, 0, addToCoordinate(ivar1, 31, 0, 33), 750, addToCoordinate(ivar1, 31, 0, 33), 750, 0); + cs2method5406(1, 1, addToCoordinate(ivar1, 31, 0, 33), 750, addToCoordinate(ivar1, 31, 0, 33), 750, 0); + cameraMethod5502(0, 0, 50, 0, 1, 0); + break; + case 40: + script_2768(50, arg0); + cs2method5405(0, 2); + cs2method5405(1, 2); + cs2method5406(0, 0, addToCoordinate(ivar1, 36, 0, 29), 850, addToCoordinate(ivar1, 36, 0, 29), 850, 0); + cs2method5406(0, 1, addToCoordinate(ivar1, 36, 0, 29), 800, addToCoordinate(ivar1, 36, 0, 29), 800, 0); + cs2method5406(1, 0, addToCoordinate(ivar1, 33, 0, 36), 700, addToCoordinate(ivar1, 33, 0, 36), 700, 0); + cs2method5406(1, 1, addToCoordinate(ivar1, 33, 0, 36), 600, addToCoordinate(ivar1, 33, 0, 36), 600, 0); + cameraMethod5502(0, 0, 50, 0, 1, 0); + break; + case 50: + script_2768(50, arg0); + cs2method5405(0, 2); + cs2method5405(1, 2); + cs2method5406(0, 0, addToCoordinate(ivar1, 39, 0, 23), 1000, addToCoordinate(ivar1, 39, 0, 23), 1000, 0); + cs2method5406(0, 1, addToCoordinate(ivar1, 39, 0, 23), 950, addToCoordinate(ivar1, 39, 0, 23), 950, 0); + cs2method5406(1, 0, addToCoordinate(ivar1, 36, 0, 28), 750, addToCoordinate(ivar1, 36, 0, 28), 750, 0); + cs2method5406(1, 1, addToCoordinate(ivar1, 36, 0, 28), 650, addToCoordinate(ivar1, 36, 0, 28), 650, 0); + cameraMethod5502(0, 0, 50, 0, 1, 0); + break; + case 99: + script_2766(0, 50, arg0); + break; + case 100: + cs2method5512(); + script_2768(50, arg0); + break; + default: + cs2method5512(); + } + return; +} diff --git a/dumps/scripts/2741.cs2 b/dumps/scripts/2741.cs2 new file mode 100644 index 0000000..e13dde3 --- /dev/null +++ b/dumps/scripts/2741.cs2 @@ -0,0 +1,21 @@ +void script_2741() { + int ivar0; + string svar0; + string svar1; + svar0 = "Confirm"; + svar1 = "Continue"; + ivar0 = add(getTextWidth(495, svar0), 30); + script_3965(67371125, ivar0, svar0, ""); + script_368(67371123, add(getTextWidth(495, svar1), 30), svar1, ""); + svar1 = "Back"; + ivar0 = add(ivar0, 55); + script_368(67371124, add(getTextWidth(495, svar1), 30), svar1, ""); + if (((boolean)bitconfig_8246) && ((boolean)bitconfig_8247)) { + setWidgetPosition(20, 0, 2, 2, new WidgetPointer(1028,115)); + setWidgetPosition(0, 0, 2, 2, new WidgetPointer(1028,116)); + } else { + setWidgetPosition(ivar0, 0, 2, 2, new WidgetPointer(1028,115)); + setWidgetPosition(ivar0, 0, 2, 2, new WidgetPointer(1028,116)); + } + return; +} diff --git a/dumps/scripts/2742.cs2 b/dumps/scripts/2742.cs2 new file mode 100644 index 0000000..67e8a94 --- /dev/null +++ b/dumps/scripts/2742.cs2 @@ -0,0 +1,6 @@ +void script_2742() { + setWidgetSprite(2560, new WidgetPointer(204,21)); + setWidgetSprite(2560, new WidgetPointer(204,19)); + setWidgetSprite(2561, new WidgetPointer(204,20)); + return; +} diff --git a/dumps/scripts/2743.cs2 b/dumps/scripts/2743.cs2 new file mode 100644 index 0000000..68c7b66 --- /dev/null +++ b/dumps/scripts/2743.cs2 @@ -0,0 +1,6 @@ +void script_2743() { + setWidgetSprite(2558, new WidgetPointer(204,21)); + setWidgetSprite(2558, new WidgetPointer(204,19)); + setWidgetSprite(2559, new WidgetPointer(204,20)); + return; +} diff --git a/dumps/scripts/2744.cs2 b/dumps/scripts/2744.cs2 new file mode 100644 index 0000000..38894b2 --- /dev/null +++ b/dumps/scripts/2744.cs2 @@ -0,0 +1,71 @@ +void script_2744() { + int ivar0; + ivar0 = 0; + while (ivar0 < 31) { + createExtraChild(new WidgetPointer(204,86), 4, ivar0); + setWidgetSize(46, 20, 0, 0); + setWidgetPosition(4, multiply(ivar0, 20), 0, 0); + setWidgetFont(496); + setWidgetTextAlignment(1, 1, 0); + setWidgetText(intToStr(add(ivar0, 1))); + setWidgetRGB(new Color(255, 255, 255)); + setWidgetContextMenuOption(1, "Select"); + setScriptCallOnClickContextMenu(2748, ivar0, "i"); + setScriptCallOnMouseEntered(1356, new WidgetPointer(-32768,3), -2147483643, 16723968, "Iii"); + setScriptCallOnMouseExit(1356, new WidgetPointer(-32768,3), -2147483643, 16777215, "Iii"); + ivar0 = add(ivar0, 1); + } + setWidgetScrollMax(0, multiply(ivar0, 20), new WidgetPointer(204,86)); + script_31(13369431, 13369430, 792, 789, 790, 791, 773, 788); + ivar0 = 0; + while (ivar0 < 12) { + createExtraChild(new WidgetPointer(204,98), 4, ivar0); + setWidgetSize(158, 20, 0, 0); + setWidgetPosition(4, multiply(ivar0, 20), 0, 0); + setWidgetFont(496); + setWidgetTextAlignment(1, 1, 0); + setWidgetText(cs2method_3408(105, 115, 950, ivar0)); + setWidgetRGB(new Color(255, 255, 255)); + setWidgetContextMenuOption(1, "Select"); + setScriptCallOnClickContextMenu(2749, ivar0, "i"); + setScriptCallOnMouseEntered(1356, new WidgetPointer(-32768,3), -2147483643, 16723968, "Iii"); + setScriptCallOnMouseExit(1356, new WidgetPointer(-32768,3), -2147483643, 16777215, "Iii"); + ivar0 = add(ivar0, 1); + } + setWidgetScrollMax(0, multiply(ivar0, 20), new WidgetPointer(204,98)); + script_31(13369443, 13369442, 792, 789, 790, 791, 773, 788); + ivar0 = 0; + while (ivar0 < 90) { + createExtraChild(new WidgetPointer(204,110), 4, ivar0); + setWidgetSize(70, 20, 0, 0); + setWidgetPosition(6, add(multiply(ivar0, 20), 1), 0, 0); + setWidgetFont(496); + setWidgetTextAlignment(1, 1, 0); + setWidgetText(intToStr(subtract(2009, ivar0))); + setWidgetRGB(new Color(255, 255, 255)); + setWidgetContextMenuOption(1, "Select"); + setScriptCallOnClickContextMenu(2750, ivar0, "i"); + setScriptCallOnMouseEntered(1356, new WidgetPointer(-32768,3), -2147483643, 16723968, "Iii"); + setScriptCallOnMouseExit(1356, new WidgetPointer(-32768,3), -2147483643, 16777215, "Iii"); + ivar0 = add(ivar0, 1); + } + setWidgetScrollMax(0, multiply(ivar0, 20), new WidgetPointer(204,110)); + script_31(13369455, 13369454, 792, 789, 790, 791, 773, 788); + setWidgetIsHidden(true, new WidgetPointer(204,86)); + setWidgetIsHidden(true, new WidgetPointer(204,77)); + setWidgetIsHidden(true, new WidgetPointer(204,87)); + setWidgetIsHidden(true, new WidgetPointer(204,98)); + setWidgetIsHidden(true, new WidgetPointer(204,89)); + setWidgetIsHidden(true, new WidgetPointer(204,99)); + setWidgetIsHidden(true, new WidgetPointer(204,110)); + setWidgetIsHidden(true, new WidgetPointer(204,111)); + setWidgetIsHidden(true, new WidgetPointer(204,101)); + setWidgetIsHidden(true, new WidgetPointer(204,26)); + setWidgetIsHidden(true, new WidgetPointer(204,27)); + setWidgetIsHidden(true, new WidgetPointer(204,28)); + setWidgetIsHidden(false, new WidgetPointer(204,29)); + setWidgetIsHidden(false, new WidgetPointer(204,45)); + setWidgetIsHidden(false, new WidgetPointer(204,61)); + setWidgetIsHidden(true, new WidgetPointer(204,113)); + return; +} diff --git a/dumps/scripts/2745.cs2 b/dumps/scripts/2745.cs2 new file mode 100644 index 0000000..33c10f6 --- /dev/null +++ b/dumps/scripts/2745.cs2 @@ -0,0 +1,27 @@ +void script_2745() { + if (isWidgetHidden(new WidgetPointer(204,86))) { + setWidgetVFlip(1, new WidgetPointer(204,44)); + setWidgetIsHidden(false, new WidgetPointer(204,86)); + setWidgetIsHidden(false, new WidgetPointer(204,77)); + setWidgetIsHidden(false, new WidgetPointer(204,87)); + setWidgetIsHidden(false, new WidgetPointer(204,26)); + } else { + setWidgetVFlip(0, new WidgetPointer(204,44)); + setWidgetIsHidden(true, new WidgetPointer(204,86)); + setWidgetIsHidden(true, new WidgetPointer(204,77)); + setWidgetIsHidden(true, new WidgetPointer(204,87)); + setWidgetIsHidden(true, new WidgetPointer(204,26)); + } + setWidgetVFlip(0, new WidgetPointer(204,60)); + setWidgetIsHidden(true, new WidgetPointer(204,98)); + setWidgetIsHidden(true, new WidgetPointer(204,89)); + setWidgetIsHidden(true, new WidgetPointer(204,99)); + setWidgetIsHidden(true, new WidgetPointer(204,27)); + setWidgetVFlip(0, new WidgetPointer(204,76)); + setWidgetIsHidden(true, new WidgetPointer(204,110)); + setWidgetIsHidden(true, new WidgetPointer(204,101)); + setWidgetIsHidden(true, new WidgetPointer(204,111)); + setWidgetIsHidden(true, new WidgetPointer(204,28)); + setWidgetIsHidden(true, new WidgetPointer(204,113)); + return; +} diff --git a/dumps/scripts/2746.cs2 b/dumps/scripts/2746.cs2 new file mode 100644 index 0000000..a9ab107 --- /dev/null +++ b/dumps/scripts/2746.cs2 @@ -0,0 +1,27 @@ +void script_2746() { + if (isWidgetHidden(new WidgetPointer(204,98))) { + setWidgetVFlip(1, new WidgetPointer(204,60)); + setWidgetIsHidden(false, new WidgetPointer(204,98)); + setWidgetIsHidden(false, new WidgetPointer(204,89)); + setWidgetIsHidden(false, new WidgetPointer(204,99)); + setWidgetIsHidden(false, new WidgetPointer(204,27)); + } else { + setWidgetVFlip(0, new WidgetPointer(204,60)); + setWidgetIsHidden(true, new WidgetPointer(204,98)); + setWidgetIsHidden(true, new WidgetPointer(204,89)); + setWidgetIsHidden(true, new WidgetPointer(204,99)); + setWidgetIsHidden(true, new WidgetPointer(204,27)); + } + setWidgetVFlip(0, new WidgetPointer(204,44)); + setWidgetIsHidden(true, new WidgetPointer(204,86)); + setWidgetIsHidden(true, new WidgetPointer(204,77)); + setWidgetIsHidden(true, new WidgetPointer(204,87)); + setWidgetIsHidden(true, new WidgetPointer(204,26)); + setWidgetVFlip(0, new WidgetPointer(204,76)); + setWidgetIsHidden(true, new WidgetPointer(204,110)); + setWidgetIsHidden(true, new WidgetPointer(204,101)); + setWidgetIsHidden(true, new WidgetPointer(204,111)); + setWidgetIsHidden(true, new WidgetPointer(204,28)); + setWidgetIsHidden(true, new WidgetPointer(204,113)); + return; +} diff --git a/dumps/scripts/2747.cs2 b/dumps/scripts/2747.cs2 new file mode 100644 index 0000000..6322ac3 --- /dev/null +++ b/dumps/scripts/2747.cs2 @@ -0,0 +1,27 @@ +void script_2747() { + if (isWidgetHidden(new WidgetPointer(204,110))) { + setWidgetVFlip(1, new WidgetPointer(204,76)); + setWidgetIsHidden(false, new WidgetPointer(204,110)); + setWidgetIsHidden(false, new WidgetPointer(204,101)); + setWidgetIsHidden(false, new WidgetPointer(204,111)); + setWidgetIsHidden(false, new WidgetPointer(204,28)); + } else { + setWidgetVFlip(0, new WidgetPointer(204,76)); + setWidgetIsHidden(true, new WidgetPointer(204,110)); + setWidgetIsHidden(true, new WidgetPointer(204,101)); + setWidgetIsHidden(true, new WidgetPointer(204,111)); + setWidgetIsHidden(true, new WidgetPointer(204,28)); + } + setWidgetVFlip(0, new WidgetPointer(204,44)); + setWidgetIsHidden(true, new WidgetPointer(204,86)); + setWidgetIsHidden(true, new WidgetPointer(204,77)); + setWidgetIsHidden(true, new WidgetPointer(204,87)); + setWidgetIsHidden(true, new WidgetPointer(204,26)); + setWidgetVFlip(0, new WidgetPointer(204,60)); + setWidgetIsHidden(true, new WidgetPointer(204,98)); + setWidgetIsHidden(true, new WidgetPointer(204,89)); + setWidgetIsHidden(true, new WidgetPointer(204,99)); + setWidgetIsHidden(true, new WidgetPointer(204,27)); + setWidgetIsHidden(true, new WidgetPointer(204,113)); + return; +} diff --git a/dumps/scripts/2748.cs2 b/dumps/scripts/2748.cs2 new file mode 100644 index 0000000..35387b3 --- /dev/null +++ b/dumps/scripts/2748.cs2 @@ -0,0 +1,9 @@ +void script_2748(int arg0) { + setWidgetText(new WidgetPointer(204,30), intToStr(add(arg0, 1))); + setWidgetVFlip(0, new WidgetPointer(204,44)); + setWidgetIsHidden(true, new WidgetPointer(204,86)); + setWidgetIsHidden(true, new WidgetPointer(204,87)); + setWidgetIsHidden(true, new WidgetPointer(204,77)); + setWidgetIsHidden(true, new WidgetPointer(204,26)); + return; +} diff --git a/dumps/scripts/2749.cs2 b/dumps/scripts/2749.cs2 new file mode 100644 index 0000000..5705986 --- /dev/null +++ b/dumps/scripts/2749.cs2 @@ -0,0 +1,9 @@ +void script_2749(int arg0) { + setWidgetText(new WidgetPointer(204,46), cs2method_3408(105, 115, 950, arg0)); + setWidgetVFlip(0, new WidgetPointer(204,60)); + setWidgetIsHidden(true, new WidgetPointer(204,98)); + setWidgetIsHidden(true, new WidgetPointer(204,99)); + setWidgetIsHidden(true, new WidgetPointer(204,89)); + setWidgetIsHidden(true, new WidgetPointer(204,27)); + return; +} diff --git a/dumps/scripts/275.cs2 b/dumps/scripts/275.cs2 new file mode 100644 index 0000000..5967378 --- /dev/null +++ b/dumps/scripts/275.cs2 @@ -0,0 +1,10 @@ +void script_275() { + setWidgetSize(getWidgetActualWidth(new WidgetPointer(919,1)), 75, 0, 0, new WidgetPointer(919,1)); + setScriptCallOnClickContextMenu(272, "", new WidgetPointer(919,23)); + setWidgetText(new WidgetPointer(919,31), "Show All"); + deleteAllExtraChilds(new WidgetPointer(919,5)); + setWidgetVFlip(0, new WidgetPointer(919,29)); + setWidgetVFlip(0, new WidgetPointer(919,30)); + cs2method2100(0, 0, new WidgetPointer(919,6)); + return; +} diff --git a/dumps/scripts/2750.cs2 b/dumps/scripts/2750.cs2 new file mode 100644 index 0000000..aaa6755 --- /dev/null +++ b/dumps/scripts/2750.cs2 @@ -0,0 +1,9 @@ +void script_2750(int arg0) { + setWidgetText(new WidgetPointer(204,62), intToStr(subtract(2009, arg0))); + setWidgetIsHidden(true, new WidgetPointer(204,110)); + setWidgetIsHidden(true, new WidgetPointer(204,111)); + setWidgetIsHidden(true, new WidgetPointer(204,101)); + setWidgetIsHidden(true, new WidgetPointer(204,28)); + setWidgetIsHidden(false, new WidgetPointer(204,61)); + return; +} diff --git a/dumps/scripts/2751.cs2 b/dumps/scripts/2751.cs2 new file mode 100644 index 0000000..fa46440 --- /dev/null +++ b/dumps/scripts/2751.cs2 @@ -0,0 +1,4 @@ +void script_2751() { + setWidgetText(new WidgetPointer(1051,11), intToStr(standart_config_1652) + " " + cs2method_3408(105, 115, 950, standart_config_1653) + " " + intToStr(standart_config_1654)); + return; +} diff --git a/dumps/scripts/2752.cs2 b/dumps/scripts/2752.cs2 new file mode 100644 index 0000000..136945a --- /dev/null +++ b/dumps/scripts/2752.cs2 @@ -0,0 +1,11 @@ +void script_2752() { + setWidgetTextAlignment(1, 1, 0); + setWidgetFont(495); + setWidgetRGB(new Color(0, 0, 255)); + setWidgetUnknownBoolean(false); + setWidgetSize(0, subtract(getWidgetActualHeight(new WidgetPointer(getWidgetParentId())), add(getWidgetActualY(new WidgetPointer(752,5)), getWidgetActualHeight(new WidgetPointer(752,5)))), 1, 0); + setWidgetPosition(0, 0, 1, 2); + setScriptCallOnMouseEntered(1356, new WidgetPointer(-32768,3), -2147483643, 16777215, "Iii"); + setScriptCallOnMouseExit(1356, new WidgetPointer(-32768,3), -2147483643, 255, "Iii"); + return; +} diff --git a/dumps/scripts/2753.cs2 b/dumps/scripts/2753.cs2 new file mode 100644 index 0000000..8e7ac25 --- /dev/null +++ b/dumps/scripts/2753.cs2 @@ -0,0 +1,26 @@ +void script_2753(int arg0,int arg1,int arg2,int arg3,string arg4) { + if (arg1 != 1) { + return; + } + if (setWidgetRegister(new WidgetPointer(arg2), arg3)) { + deleteExtraChild(); + } + if ((globalint_5 != arg0) || (strLength(arg4) <= 0)) { + return; + } + globalstring_22 = strRemoveEntities(arg4); + setWidgetText(new WidgetPointer(752,5), replaceLtGt(globalstring_22)); + if (globalint_5 == 8) { + sendNameInput(globalstring_22); + script_1548(0); + } else if (globalint_5 == 9) { + sendStringInput(globalstring_22); + script_1548(0); + } else { + if (globalint_5 == 10) { + sendUnknownFriendPacketMethod3619(globalstring_22); + script_1548(0); + } + } + return; +} diff --git a/dumps/scripts/2754.cs2 b/dumps/scripts/2754.cs2 new file mode 100644 index 0000000..3df9f44 --- /dev/null +++ b/dumps/scripts/2754.cs2 @@ -0,0 +1,4 @@ +void script_2754(int arg0,int arg1,int arg2) { + script_2755(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/2755.cs2 b/dumps/scripts/2755.cs2 new file mode 100644 index 0000000..1418188 --- /dev/null +++ b/dumps/scripts/2755.cs2 @@ -0,0 +1,39 @@ +void script_2755(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int stack_dump0; + ivar3 = 0; + ivar4 = 0; + ivar5 = 0; + ivar6 = 0; + if (setWidgetRegister(new WidgetPointer(arg0), arg1) || ((arg1 == -1) && setWidgetRegister(new WidgetPointer(arg0)))) { + stack_dump0 = script_1743(); + ivar4 = script_1744(); + ivar3 = stack_dump0; + if (ivar3 < multiplyDivide(1, 3, getWidgetActualWidth(new WidgetPointer(746,3)))) { + if (ivar4 < multiplyDivide(1, 3, getWidgetActualHeight(new WidgetPointer(746,3)))) { + setWidget3DRotation(0, 0, 512, 768, 0, 1000, new WidgetPointer(arg2)); + setWidgetPosition(add(ivar3, getWidgetActualWidth()), add(ivar4, getWidgetActualHeight()), 0, 0, new WidgetPointer(arg2)); + } else { + setWidget3DRotation(0, 0, 512, 256, 0, 1000, new WidgetPointer(arg2)); + setWidgetPosition(add(ivar3, getWidgetActualWidth()), subtract(ivar4, getWidgetActualHeight(new WidgetPointer(arg2))), 0, 0, new WidgetPointer(arg2)); + } + } else if (ivar4 < multiplyDivide(1, 3, getWidgetActualHeight(new WidgetPointer(746,3)))) { + if (arg0 == 48890031) { + ivar5 = subtract(subtract(ivar3, getWidgetActualWidth(new WidgetPointer(arg2))), 10); + ivar6 = add(ivar4, getWidgetActualHeight()); + setWidget3DRotation(0, 0, 512, 1280, 0, 1000, new WidgetPointer(arg2)); + setWidgetPosition(ivar5, ivar6, 0, 0, new WidgetPointer(arg2)); + return; + } + setWidget3DRotation(0, 0, 512, 1280, 0, 1000, new WidgetPointer(arg2)); + setWidgetPosition(subtract(ivar3, getWidgetActualWidth(new WidgetPointer(arg2))), add(ivar4, getWidgetActualHeight()), 0, 0, new WidgetPointer(arg2)); + } else { + setWidget3DRotation(0, 0, 512, 1792, 0, 1000, new WidgetPointer(arg2)); + setWidgetPosition(subtract(ivar3, getWidgetActualWidth(new WidgetPointer(arg2))), subtract(ivar4, getWidgetActualHeight(new WidgetPointer(arg2))), 0, 0, new WidgetPointer(arg2)); + } + } + return; +} diff --git a/dumps/scripts/2756.cs2 b/dumps/scripts/2756.cs2 new file mode 100644 index 0000000..09e2ad5 --- /dev/null +++ b/dumps/scripts/2756.cs2 @@ -0,0 +1,14 @@ +void script_2756() { + if (bitconfig_3756 == add(16, 1)) { + script_736(48890035, -1, 35913914, -1); + } else if (bitconfig_3756 == add(17, 1)) { + script_736(48890031, -1, 35913912, -1); + } else if (bitconfig_3756 == add(18, 1)) { + script_736(48890037, -1, 35913908, -1); + } else if (bitconfig_3756 == add(19, 1)) { + script_736(48890030, -1, 35913906, -1); + } else { + script_736(script_1742(subtract(bitconfig_3756, 1)), -1, script_121(subtract(bitconfig_3756, 1)), -1); + } + return; +} diff --git a/dumps/scripts/2757.cs2 b/dumps/scripts/2757.cs2 new file mode 100644 index 0000000..8d8b499 --- /dev/null +++ b/dumps/scripts/2757.cs2 @@ -0,0 +1,11 @@ +void script_2757(int arg0) { + if ((((boolean)globalint_173) || ((boolean)bitconfig_542)) || (arg0 != 1)) { + return; + } + if (cameraGetVrot() < 150) { + cameraMethod5504(150, 0); + } else { + cameraMethod5504(149, 0); + } + return; +} diff --git a/dumps/scripts/2758.cs2 b/dumps/scripts/2758.cs2 new file mode 100644 index 0000000..399be8d --- /dev/null +++ b/dumps/scripts/2758.cs2 @@ -0,0 +1,6 @@ +void script_2758(int arg0) { + setScriptCallOnConfigChange(2759, new WidgetPointer(-32768,3), 466, 1, "IY", new WidgetPointer(arg0)); + setScriptCallOnGlobalConfigChange(2759, new WidgetPointer(-32768,3), 173, 1, "IY", new WidgetPointer(arg0)); + script_2760(arg0); + return; +} diff --git a/dumps/scripts/2759.cs2 b/dumps/scripts/2759.cs2 new file mode 100644 index 0000000..fffb39f --- /dev/null +++ b/dumps/scripts/2759.cs2 @@ -0,0 +1,4 @@ +void script_2759(int arg0) { + script_2760(arg0); + return; +} diff --git a/dumps/scripts/276.cs2 b/dumps/scripts/276.cs2 new file mode 100644 index 0000000..b4751df --- /dev/null +++ b/dumps/scripts/276.cs2 @@ -0,0 +1,13 @@ +string script_276(int arg0) { + switch (arg0) { + case 1: + return "Lake"; + case 2: + return "River"; + case 3: + return "Beach"; + case 4: + return "Docks"; + } + return "Waterfront"; +} diff --git a/dumps/scripts/2760.cs2 b/dumps/scripts/2760.cs2 new file mode 100644 index 0000000..5b06c7d --- /dev/null +++ b/dumps/scripts/2760.cs2 @@ -0,0 +1,12 @@ +void script_2760(int arg0) { + if (((boolean)globalint_173) || ((boolean)bitconfig_542)) { + setWidgetNoOptions(new WidgetPointer(arg0)); + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(arg0)); + cs2method2005(0, new WidgetPointer(arg0)); + } else { + setWidgetContextMenuOption(1, new WidgetPointer(arg0), "Face North"); + setScriptCallOnClickContextMenu(2757, -2147483644, "i", new WidgetPointer(arg0)); + cs2method2005(1, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/2761.cs2 b/dumps/scripts/2761.cs2 new file mode 100644 index 0000000..2a0478a --- /dev/null +++ b/dumps/scripts/2761.cs2 @@ -0,0 +1,3 @@ +int script_2761() { + return add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(getSkillActualLvl(0), getSkillActualLvl(2)), getSkillActualLvl(1)), getSkillActualLvl(4)), getSkillActualLvl(5)), getSkillActualLvl(6)), getSkillActualLvl(20)), getSkillActualLvl(22)), getSkillActualLvl(3)), getSkillActualLvl(16)), getSkillActualLvl(15)), getSkillActualLvl(17)), getSkillActualLvl(12)), getSkillActualLvl(9)), getSkillActualLvl(18)), getSkillActualLvl(21)), getSkillActualLvl(14)), getSkillActualLvl(13)), getSkillActualLvl(10)), getSkillActualLvl(7)), getSkillActualLvl(11)), getSkillActualLvl(8)), getSkillActualLvl(19)), getSkillActualLvl(23)), getSkillActualLvl(24)); +} diff --git a/dumps/scripts/2762.cs2 b/dumps/scripts/2762.cs2 new file mode 100644 index 0000000..e909ec2 --- /dev/null +++ b/dumps/scripts/2762.cs2 @@ -0,0 +1,65 @@ +void script_2762(int arg0,int arg1) { + switch (globalint_1007) { + case 101: + cs2method5405(0, 2); + cs2method5406(0, 0, script_2764(60347213, arg1), 450, script_2764(60347213, arg1), 500, 0); + cs2method5406(0, 1, script_2764(60363597, arg1), 600, script_2764(60363597, arg1), 550, 0); + cs2method5405(1, 2); + cs2method5406(1, 0, script_2764(60248915, arg1), 350, script_2764(60248915, arg1), 375, 0); + cs2method5406(1, 1, script_2764(60298065, arg1), 350, script_2764(60298065, arg1), 375, 0); + cameraMethod5502(0, 0, 300, 400, 1, 0); + break; + case 102: + cs2method5405(0, 2); + cs2method5406(0, 0, script_2764(60248921, arg1), 600, script_2764(60248922, arg1), 600, 0); + cs2method5406(0, 1, script_2764(60265310, arg1), 700, script_2764(60265309, arg1), 700, 0); + cs2method5405(1, 2); + cs2method5406(1, 0, script_2764(60265295, arg1), 400, script_2764(60265293, arg1), 400, 0); + cs2method5406(1, 1, script_2764(60265298, arg1), 400, script_2764(60265298, arg1), 400, 0); + cameraMethod5502(0, 0, 250, 200, 1, 0); + break; + case 103: + cs2method5405(0, 2); + cs2method5406(0, 0, script_2764(60281685, arg1), 700, script_2764(60298070, arg1), 650, 0); + cs2method5406(0, 1, script_2764(60298074, arg1), 650, script_2764(60298074, arg1), 650, 0); + cs2method5405(1, 2); + cs2method5406(1, 0, script_2764(60298083, arg1), 5, script_2764(60298083, arg1), 5, 0); + cs2method5406(1, 1, script_2764(60298088, arg1), 5, script_2764(60298088, arg1), 5, 0); + cameraMethod5502(0, 0, 200, 200, 1, 0); + break; + case 104: + cs2method5405(0, 2); + cs2method5406(0, 0, script_2764(60117861, arg1), 300, script_2764(60117860, arg1), 300, 0); + cs2method5406(0, 1, script_2764(60150626, arg1), 300, script_2764(60134242, arg1), 300, 0); + cs2method5405(1, 2); + cs2method5406(1, 0, script_2764(60298077, arg1), 250, script_2764(60298077, arg1), 250, 0); + cs2method5406(1, 1, script_2764(60298077, arg1), 250, script_2764(60298077, arg1), 250, 0); + cameraMethod5502(0, 0, 100, 50, 1, 0); + break; + case 105: + cs2method5405(0, 2); + cs2method5406(0, 0, script_2764(60298079, arg1), 700, script_2764(60298083, arg1), 700, 0); + cs2method5406(0, 1, script_2764(60216163, arg1), 700, script_2764(60232547, arg1), 700, 0); + cs2method5405(1, 2); + cs2method5406(1, 0, script_2764(60068707, arg1), 5, script_2764(60068707, arg1), 5, 0); + cs2method5406(1, 1, script_2764(60068707, arg1), 5, script_2764(60068707, arg1), 5, 0); + cameraMethod5502(0, 0, 80, 50, 1, 0); + break; + case 106: + script_2766(0, 40, arg0); + break; + case 107: + script_2768(25, arg0); + cs2method5405(0, 2); + cs2method5406(0, 0, script_2764(60281694, arg1), 350, script_2764(60281695, arg1), 350, 0); + cs2method5406(0, 1, script_2764(60216165, arg1), 550, script_2764(60232549, arg1), 550, 0); + cs2method5405(1, 2); + cs2method5406(1, 0, script_2764(60216158, arg1), 300, script_2764(60216158, arg1), 300, 0); + cs2method5406(1, 1, script_2764(60101470, arg1), 350, script_2764(60101470, arg1), 350, 0); + cameraMethod5502(0, 0, 120, 40, 1, 0); + break; + default: + cs2method5512(); + } + return; +} diff --git a/dumps/scripts/2763.cs2 b/dumps/scripts/2763.cs2 new file mode 100644 index 0000000..4293eaa --- /dev/null +++ b/dumps/scripts/2763.cs2 @@ -0,0 +1,38 @@ +void script_2763(int arg0,int arg1) { + switch (globalint_1007) { + case 201: + cs2method5405(0, 2); + cs2method5406(0, 0, script_2764(60314467, arg1), 600, script_2764(60330851, arg1), 600, 0); + cs2method5406(0, 1, script_2764(60363619, arg1), 550, script_2764(60363619, arg1), 600, 0); + cs2method5405(1, 2); + cs2method5406(1, 0, script_2764(60068707, arg1), 200, script_2764(60068707, arg1), 200, 0); + cs2method5406(1, 1, script_2764(60068707, arg1), 200, script_2764(60068707, arg1), 200, 0); + cameraMethod5502(0, 0, 200, 75, 1, 0); + break; + case 202: + script_2766(0, 10, arg0); + break; + case 203: + cs2method5405(0, 2); + cs2method5406(0, 0, script_2764(60363619, arg1), 550, script_2764(60363619, arg1), 550, 0); + cs2method5406(0, 1, script_2764(60347235, arg1), 750, script_2764(60347235, arg1), 750, 0); + cs2method5405(1, 2); + cs2method5406(1, 0, script_2764(60068707, arg1), 200, script_2764(60068707, arg1), 200, 0); + cs2method5406(1, 1, script_2764(60068707, arg1), 200, script_2764(60068707, arg1), 200, 0); + cameraMethod5502(0, 0, 50, 25, 1, 0); + script_2768(75, arg0); + break; + case 204: + cs2method5405(0, 2); + cs2method5406(0, 0, script_2764(60281702, arg1), 550, script_2764(60298086, arg1), 550, 0); + cs2method5406(0, 1, script_2764(60330855, arg1), 550, script_2764(60314471, arg1), 550, 0); + cs2method5405(1, 2); + cs2method5406(1, 0, script_2764(60379998, arg1), 400, script_2764(60363614, arg1), 400, 0); + cs2method5406(1, 1, script_2764(60183394, arg1), 400, script_2764(60199777, arg1), 400, 0); + cameraMethod5502(0, 0, 150, 220, 1, 0); + break; + default: + cs2method5512(); + } + return; +} diff --git a/dumps/scripts/2764.cs2 b/dumps/scripts/2764.cs2 new file mode 100644 index 0000000..7bd2aa2 --- /dev/null +++ b/dumps/scripts/2764.cs2 @@ -0,0 +1,3 @@ +int script_2764(int arg0,int arg1) { + return addToCoordinate(arg1, subtract(add(16, extractX(arg0)), extractX(59773760)), 0, subtract(add(16, extractY(arg0)), extractY(59773760))); +} diff --git a/dumps/scripts/2765.cs2 b/dumps/scripts/2765.cs2 new file mode 100644 index 0000000..933a24b --- /dev/null +++ b/dumps/scripts/2765.cs2 @@ -0,0 +1,20 @@ +void script_2765(int arg0) { + if (globalint_1007 <= 0) { + cs2method5512(); + return; + } + if (globalint_1007 <= 100) { + script_2770(arg0, script_284(getMyPositionHash())); + return; + } + if (globalint_1007 <= 200) { + script_2762(arg0, script_284(getMyPositionHash())); + return; + } + if (globalint_1007 <= 300) { + script_2763(arg0, script_284(getMyPositionHash())); + return; + } + script_2826(arg0, script_284(getMyPositionHash())); + return; +} diff --git a/dumps/scripts/2766.cs2 b/dumps/scripts/2766.cs2 new file mode 100644 index 0000000..7d1d7c9 --- /dev/null +++ b/dumps/scripts/2766.cs2 @@ -0,0 +1,11 @@ +void script_2766(int arg0,int arg1,int arg2) { + createExtraChild(new WidgetPointer(arg2), 3, 0); + cs2method2103(255); + setWidgetFilled(1); + setWidgetRGB(new Color(arg0)); + setWidgetSize(0, 0, 1, 1); + setWidgetPosition(0, 0, 1, 1); + arg1 = min(arg1, 250); + setScriptCallOnGameloop(2767, add(getClientCycle(), arg1), new WidgetPointer(arg2), "iI"); + return; +} diff --git a/dumps/scripts/2767.cs2 b/dumps/scripts/2767.cs2 new file mode 100644 index 0000000..d7f9c26 --- /dev/null +++ b/dumps/scripts/2767.cs2 @@ -0,0 +1,14 @@ +void script_2767(int arg0,int arg1) { + int ivar2; + ivar2 = 0; + if (setWidgetRegister(new WidgetPointer(arg1), 0)) { + ivar2 = subtract(arg0, getClientCycle()); + if (ivar2 <= 0) { + cs2method2103(0); + setScriptCallOnGameloop(-1, ""); + return; + } + cs2method2103(max(subtract(cs2method1609(), divide(cs2method1609(), ivar2)), 1)); + } + return; +} diff --git a/dumps/scripts/2768.cs2 b/dumps/scripts/2768.cs2 new file mode 100644 index 0000000..4ca147f --- /dev/null +++ b/dumps/scripts/2768.cs2 @@ -0,0 +1,10 @@ +void script_2768(int arg0,int arg1) { + if (setWidgetRegister(new WidgetPointer(arg1), 0)) { + setWidgetFilled(1); + setWidgetSize(0, 0, 1, 1); + setWidgetPosition(0, 0, 1, 1); + cs2method2103(0); + setScriptCallOnGameloop(2769, add(getClientCycle(), arg0), new WidgetPointer(arg1), "iI"); + } + return; +} diff --git a/dumps/scripts/2769.cs2 b/dumps/scripts/2769.cs2 new file mode 100644 index 0000000..96edc24 --- /dev/null +++ b/dumps/scripts/2769.cs2 @@ -0,0 +1,17 @@ +void script_2769(int arg0,int arg1) { + int ivar2; + int ivar3; + ivar2 = 0; + ivar3 = 0; + if (setWidgetRegister(new WidgetPointer(arg1), 0)) { + ivar2 = subtract(arg0, getClientCycle()); + if (ivar2 <= 0) { + setScriptCallOnGameloop(-1, ""); + deleteExtraChild(); + return; + } + ivar3 = subtract(255, cs2method1609()); + cs2method2103(min(add(cs2method1609(), divide(ivar3, ivar2)), 254)); + } + return; +} diff --git a/dumps/scripts/277.cs2 b/dumps/scripts/277.cs2 new file mode 100644 index 0000000..4d8eb70 --- /dev/null +++ b/dumps/scripts/277.cs2 @@ -0,0 +1,21 @@ +string script_277(int arg0) { + switch (arg0) { + case 1: + return "Worm"; + case 2: + return "Maggot"; + case 3: + return "Cricket"; + case 4: + return "Locust"; + case 5: + return "Cray"; + case 6: + return "Shrimp"; + case 7: + return "Green moth"; + case 8: + return "Grey moth"; + } + return "Unknown bait"; +} diff --git a/dumps/scripts/2770.cs2 b/dumps/scripts/2770.cs2 new file mode 100644 index 0000000..38654c3 --- /dev/null +++ b/dumps/scripts/2770.cs2 @@ -0,0 +1,120 @@ +void script_2770(int arg0,int arg1) { + switch (globalint_1007) { + case 1: + cs2method5405(0, 2); + cs2method5406(0, 0, script_2764(60298061, arg1), 600, script_2764(60298061, arg1), 600, 0); + cs2method5406(0, 1, script_2764(60298061, arg1), 450, script_2764(60298061, arg1), 450, 0); + cs2method5405(1, 2); + cs2method5406(1, 0, script_2764(60298068, arg1), 100, script_2764(60298068, arg1), 100, 0); + cs2method5406(1, 1, script_2764(60298073, arg1), 100, script_2764(60298073, arg1), 100, 0); + cameraMethod5502(0, 0, 100, 140, 1, 0); + setScriptCallOnGameloop(2771, new WidgetPointer(arg0), getClientCycle(), "Ii", new WidgetPointer(arg0)); + break; + case 2: + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + cs2method5405(0, 10); + cs2method5405(1, 10); + cs2method5406(0, 0, script_2764(60183397, arg1), 400, script_2764(60183397, arg1), 420, 0); + cs2method5406(0, 1, script_2764(60199780, arg1), 400, script_2764(60199780, arg1), 420, 128); + cs2method5406(0, 2, script_2764(60216163, arg1), 400, script_2764(60216163, arg1), 420, 0); + cs2method5406(0, 3, script_2764(60232546, arg1), 400, script_2764(60232546, arg1), 420, -128); + cs2method5406(0, 4, script_2764(60248929, arg1), 400, script_2764(60248929, arg1), 420, 0); + cs2method5406(0, 5, script_2764(60265312, arg1), 400, script_2764(60265312, arg1), 420, 128); + cs2method5406(0, 6, script_2764(60281695, arg1), 400, script_2764(60281695, arg1), 420, 0); + cs2method5406(0, 7, script_2764(60298078, arg1), 400, script_2764(60298078, arg1), 420, -128); + cs2method5406(0, 8, script_2764(60298077, arg1), 400, script_2764(60298077, arg1), 420, 0); + cs2method5406(0, 9, script_2764(60298076, arg1), 400, script_2764(60298076, arg1), 420, 128); + cs2method5406(0, 10, script_2764(60298075, arg1), 400, script_2764(60298075, arg1), 420, 0); + cs2method5406(1, 0, script_2764(60298074, arg1), 400, script_2764(60298074, arg1), 400, 0); + cs2method5406(1, 1, script_2764(60298073, arg1), 395, script_2764(60298073, arg1), 395, 0); + cs2method5406(1, 2, script_2764(60298072, arg1), 390, script_2764(60298072, arg1), 390, 0); + cs2method5406(1, 3, script_2764(60298071, arg1), 385, script_2764(60298071, arg1), 385, 0); + cs2method5406(1, 4, script_2764(60298070, arg1), 380, script_2764(60298070, arg1), 380, 0); + cs2method5406(1, 5, script_2764(60298069, arg1), 375, script_2764(60298069, arg1), 375, 0); + cs2method5406(1, 6, script_2764(60298068, arg1), 370, script_2764(60298068, arg1), 370, 0); + cs2method5406(1, 7, script_2764(60298067, arg1), 365, script_2764(60298067, arg1), 365, 0); + cs2method5406(1, 8, script_2764(60298066, arg1), 360, script_2764(60298066, arg1), 360, 0); + cs2method5406(1, 9, script_2764(60298065, arg1), 355, script_2764(60298065, arg1), 355, 0); + cs2method5406(1, 10, script_2764(60298065, arg1), 350, script_2764(60298065, arg1), 350, 0); + setScriptCallOnMinimapRelatedSetting3(2772, new WidgetPointer(arg0), 1, "Ii", new WidgetPointer(arg0)); + cameraMethod5502(0, 0, 3000, 2500, 1, 0); + playSoundEffect(6645, 1, 0); + break; + case 3: + setScriptCallOnMinimapRelatedSetting3(-1, "", new WidgetPointer(arg0)); + cs2method5405(0, 2); + cs2method5406(0, 0, script_2764(60298070, arg1), 350, script_2764(60298070, arg1), 350, 0); + cs2method5406(0, 1, script_2764(60298070, arg1), 300, script_2764(60298070, arg1), 300, 0); + cs2method5405(1, 2); + cs2method5406(1, 0, script_2764(60298078, arg1), 300, script_2764(60298078, arg1), 300, 0); + cs2method5406(1, 1, script_2764(60298078, arg1), 350, script_2764(60298078, arg1), 350, 0); + cameraMethod5502(0, 0, 60, 50, 1, 0); + break; + case 4: + cs2method5405(0, 2); + cs2method5406(0, 0, script_2764(60363602, arg1), 450, script_2764(60363601, arg1), 450, 0); + cs2method5406(0, 1, script_2764(60330828, arg1), 600, script_2764(60330829, arg1), 600, 0); + cs2method5405(1, 2); + cs2method5406(1, 0, script_2764(60298065, arg1), 400, script_2764(60298066, arg1), 400, 0); + cs2method5406(1, 1, script_2764(60298067, arg1), 350, script_2764(60298066, arg1), 350, 0); + cameraMethod5502(0, 0, 250, 200, 1, 0); + break; + case 5: + cs2method5405(0, 2); + cs2method5406(0, 0, script_2764(60363601, arg1), 700, script_2764(60363601, arg1), 700, 0); + cs2method5406(0, 1, script_2764(60363601, arg1), 700, script_2764(60363601, arg1), 700, 0); + cs2method5405(1, 2); + cs2method5406(1, 0, script_2764(60298062, arg1), 350, script_2764(60298061, arg1), 350, 0); + cs2method5406(1, 1, script_2764(60298061, arg1), 150, script_2764(60298061, arg1), 350, 0); + cameraMethod5502(0, 0, 100, 100, 1, 0); + break; + case 6: + cs2method5405(0, 2); + cs2method5406(0, 0, script_2764(60347213, arg1), 450, script_2764(60347214, arg1), 450, 0); + cs2method5406(0, 1, script_2764(60314446, arg1), 450, script_2764(60314446, arg1), 450, 0); + cs2method5405(1, 2); + cs2method5406(1, 0, script_2764(60298065, arg1), 400, script_2764(60298066, arg1), 400, 0); + cs2method5406(1, 1, script_2764(60298067, arg1), 400, script_2764(60298066, arg1), 400, 0); + cameraMethod5502(0, 0, 60, 60, 1, 0); + break; + case 7: + cs2method5405(0, 2); + cs2method5406(0, 0, script_2764(60314446, arg1), 400, script_2764(60314445, arg1), 400, 0); + cs2method5406(0, 1, script_2764(60314444, arg1), 400, script_2764(60314445, arg1), 400, 0); + cs2method5405(1, 2); + cs2method5406(1, 0, script_2764(60248909, arg1), 350, script_2764(60248909, arg1), 350, 0); + cs2method5406(1, 1, script_2764(60248909, arg1), 350, script_2764(60248909, arg1), 350, 0); + cameraMethod5502(0, 0, 30, 30, 1, 0); + break; + case 8: + cs2method5405(0, 2); + cs2method5406(0, 0, script_2764(60363605, arg1), 450, script_2764(60363604, arg1), 450, 0); + cs2method5406(0, 1, script_2764(60347219, arg1), 450, script_2764(60363604, arg1), 450, 0); + cs2method5405(1, 2); + cs2method5406(1, 0, script_2764(60330836, arg1), 400, script_2764(60314453, arg1), 400, 0); + cs2method5406(1, 1, script_2764(60298069, arg1), 400, script_2764(60314453, arg1), 400, 0); + cameraMethod5502(0, 0, 150, 150, 1, 0); + break; + case 9: + cs2method5405(0, 2); + cs2method5406(0, 0, script_2764(60363601, arg1), 500, script_2764(60330833, arg1), 500, 0); + cs2method5406(0, 1, script_2764(60248912, arg1), 700, script_2764(60248913, arg1), 700, 0); + cs2method5405(1, 2); + cs2method5406(1, 0, script_2764(60330828, arg1), 250, script_2764(60330828, arg1), 250, 0); + cs2method5406(1, 1, script_2764(60347212, arg1), 250, script_2764(60347212, arg1), 250, 0); + cameraMethod5502(0, 0, 30, 30, 1, 0); + break; + case 10: + cs2method5405(0, 2); + cs2method5406(0, 0, script_2764(60363593, arg1), 800, script_2764(60363593, arg1), 800, 0); + cs2method5406(0, 1, script_2764(60363591, arg1), 600, script_2764(60363591, arg1), 600, 0); + cs2method5405(1, 2); + cs2method5406(1, 0, script_2764(60298064, arg1), 500, script_2764(60298064, arg1), 500, 0); + cs2method5406(1, 1, script_2764(60265298, arg1), 400, script_2764(60265298, arg1), 400, 0); + cameraMethod5502(0, 0, 400, 80, 1, 0); + break; + default: + cs2method5512(); + } + return; +} diff --git a/dumps/scripts/2771.cs2 b/dumps/scripts/2771.cs2 new file mode 100644 index 0000000..e0f7970 --- /dev/null +++ b/dumps/scripts/2771.cs2 @@ -0,0 +1,21 @@ +void script_2771(int arg0,int arg1) { + int ivar2; + ivar2 = subtract(getClientCycle(), arg1); + if ((ivar2 >= 181) || (globalint_1007 != 1)) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + return; + } + if (((boolean)mod(ivar2, 25))) { + switch (rnd(2)) { + case 0: + playSoundEffect(6645, 1, 0); + break; + case 1: + playSoundEffect(6644, 1, 0); + break; + case 2: + playSoundEffect(6643, 1, 0); + } + } + return; +} diff --git a/dumps/scripts/2772.cs2 b/dumps/scripts/2772.cs2 new file mode 100644 index 0000000..cbbf638 --- /dev/null +++ b/dumps/scripts/2772.cs2 @@ -0,0 +1,23 @@ +void script_2772(int arg0,int arg1) { + int ivar2; + ivar2 = subtract(cs2method5407(0), 2); + if ((globalint_1007 != 2) || (arg1 > ivar2)) { + setScriptCallOnMinimapRelatedSetting3(-1, "", new WidgetPointer(arg0)); + return; + } + switch (rnd(2)) { + case 0: + playSoundEffect(6645, 1, 0); + break; + case 1: + playSoundEffect(6644, 1, 0); + break; + case 2: + playSoundEffect(6643, 1, 0); + } + cameraMethod5502(0, arg1, 2500, 2400, 1, arg1); + if (arg1 < ivar2) { + setScriptCallOnMinimapRelatedSetting3(2772, new WidgetPointer(arg0), add(arg1, 1), "Ii", new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/2773.cs2 b/dumps/scripts/2773.cs2 new file mode 100644 index 0000000..81be690 --- /dev/null +++ b/dumps/scripts/2773.cs2 @@ -0,0 +1,61 @@ +void script_2773(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8) { + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int stack_dump0; + if (standart_config_281 < 6) { + return; + } + ivar9 = -1; + ivar10 = -1; + ivar11 = -1; + ivar12 = -1; + switch (arg0) { + case 1: + cs2method5510(); + stack_dump0 = arg1; + ivar10 = arg5; + ivar9 = stack_dump0; + stack_dump0 = 2273; + ivar12 = 2278; + ivar11 = stack_dump0; + break; + case 2: + cs2method5509(); + stack_dump0 = arg2; + ivar10 = arg6; + ivar9 = stack_dump0; + stack_dump0 = 2272; + ivar12 = 2277; + ivar11 = stack_dump0; + break; + case 3: + cs2method5507(); + stack_dump0 = arg3; + ivar10 = arg7; + ivar9 = stack_dump0; + stack_dump0 = 2274; + ivar12 = 2279; + ivar11 = stack_dump0; + break; + case 4: + cs2method5508(); + stack_dump0 = arg4; + ivar10 = arg8; + ivar9 = stack_dump0; + stack_dump0 = 2275; + ivar12 = 2280; + ivar11 = stack_dump0; + break; + default: + return; + } + setWidgetSprite(2276, new WidgetPointer(ivar9)); + ivar13 = 2271; + setScriptCallOnGameloop(1723, new WidgetPointer(-32768,3), -2147483643, ivar13, add(getClientCycle(), 10), "Iidi", new WidgetPointer(ivar9)); + setWidgetSprite(ivar12, new WidgetPointer(ivar10)); + setScriptCallOnGameloop(1723, new WidgetPointer(-32768,3), -2147483643, ivar11, add(getClientCycle(), 10), "Iidi", new WidgetPointer(ivar10)); + return; +} diff --git a/dumps/scripts/2774.cs2 b/dumps/scripts/2774.cs2 new file mode 100644 index 0000000..d248170 --- /dev/null +++ b/dumps/scripts/2774.cs2 @@ -0,0 +1,6 @@ +void script_2774(int arg0) { + playSoundEffect(2277, 1, 0); + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(arg0)); + setScriptCallOnGameloop(2775, add(getClientCycle(), 15), new WidgetPointer(-32768,3), "iI", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/2775.cs2 b/dumps/scripts/2775.cs2 new file mode 100644 index 0000000..4a634f8 --- /dev/null +++ b/dumps/scripts/2775.cs2 @@ -0,0 +1,8 @@ +void script_2775(int arg0,int arg1) { + if (getClientCycle() < arg0) { + return; + } + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg1)); + setWidgetRGB(new Color(255, 48, 48), new WidgetPointer(arg1)); + return; +} diff --git a/dumps/scripts/2776.cs2 b/dumps/scripts/2776.cs2 new file mode 100644 index 0000000..cf48e5e --- /dev/null +++ b/dumps/scripts/2776.cs2 @@ -0,0 +1,4 @@ +void script_2776(int arg0,int arg1,int arg2) { + setScriptCallOnGameloop(2777, getClientCycle(), new WidgetPointer(arg1), new WidgetPointer(arg2), "iII", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/2777.cs2 b/dumps/scripts/2777.cs2 new file mode 100644 index 0000000..58749da --- /dev/null +++ b/dumps/scripts/2777.cs2 @@ -0,0 +1,7 @@ +void script_2777(int arg0,int arg1,int arg2) { + int ivar3; + ivar3 = subtract(255, script_1210(200, 75, arg0, 0)); + cs2method2103(ivar3, new WidgetPointer(arg1)); + cs2method2103(ivar3, new WidgetPointer(arg2)); + return; +} diff --git a/dumps/scripts/2778.cs2 b/dumps/scripts/2778.cs2 new file mode 100644 index 0000000..d28618a --- /dev/null +++ b/dumps/scripts/2778.cs2 @@ -0,0 +1,106 @@ +void script_2778(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + string svar0; + ivar4 = ((int)isWidgetHidden(new WidgetPointer(arg1))); + ivar5 = 0; + if (((boolean)bitconfig_7949) && (standart_config_281 < 1000)) { + if (((boolean)ivar4)) { + ivar5 = 1; + } + setWidgetIsHidden(false, new WidgetPointer(arg1)); + setWidgetSize(0, add(getWidgetActualHeight(new WidgetPointer(arg1)), 1), 1, 1, new WidgetPointer(arg0)); + } else { + if (((boolean)ivar4)) { + ivar5 = 1; + } + setWidgetIsHidden(true, new WidgetPointer(arg1)); + setWidgetSize(0, 0, 1, 1, new WidgetPointer(arg0)); + } + svar0 = globalstring_194; + if ((strLength(globalstring_195) > 0) && ((boolean)standart_config_170)) { + svar0 = globalstring_195; + } + ivar6 = -1; + if (setWidgetRegister(new WidgetPointer(arg0), 0)) { + ivar6 = getWidgetItemId(); + } + ivar7 = -1; + if (setWidgetRegister(new WidgetPointer(arg0), 1)) { + ivar7 = getWidgetSpriteId(); + } + if (((setWidgetRegister(new WidgetPointer(arg2), 0) && ((boolean)stringMethod4107(svar0, getWidgetText()))) && ((ivar6 == globalint_1003) && (ivar7 == globalint_1004))) && ((boolean)ivar5)) { + return; + } + deleteAllExtraChilds(new WidgetPointer(arg0)); + deleteAllExtraChilds(new WidgetPointer(arg2)); + deleteAllExtraChilds(new WidgetPointer(arg3)); + ivar8 = getWidgetActualWidth(new WidgetPointer(arg0)); + if (ivar8 <= 0) { + return; + } + ivar9 = 0; + ivar10 = 0; + if (globalint_1003 != -1) { + createExtraChild(new WidgetPointer(arg0), 6, 0); + setWidgetSize(globalint_1005, globalint_1006, 0, 0); + if (globalint_1005 < 70) { + ivar10 = divide(subtract(70, globalint_1005), 2); + } + setWidgetPosition(ivar10, 0, 0, 1); + setItemOnWidgetMethod1205(globalint_1003, 1); + ivar9 = add(max(globalint_1005, 70), 5); + ivar8 = subtract(ivar8, ivar9); + createExtraChild(new WidgetPointer(arg0), 3, 1); + setWidgetSize(0, 0, 0, 0); + setWidgetPosition(0, 0, 0, 1); + setWidgetHidden(1); + } else { + if (globalint_1004 != -1) { + createExtraChild(new WidgetPointer(arg0), 3, 0); + setWidgetSize(0, 0, 0, 0); + setWidgetPosition(0, 0, 0, 1); + setWidgetHidden(1); + createExtraChild(new WidgetPointer(arg0), 5, 1); + setWidgetSize(globalint_1005, globalint_1006, 0, 0); + if (globalint_1005 < 70) { + ivar10 = divide(subtract(70, globalint_1005), 2); + } + setWidgetPosition(ivar10, 0, 0, 1); + setWidgetSprite(globalint_1004); + ivar9 = add(max(globalint_1005, 70), 5); + ivar8 = subtract(ivar8, ivar9); + } + } + cs2method2100(0, 0, new WidgetPointer(arg2)); + setWidgetPosition(ivar9, 0, 0, 1, new WidgetPointer(arg2)); + ivar11 = add(multiply(getLineCount(ivar8, 307, svar0), 12), 3); + if (ivar11 > getWidgetActualHeight(new WidgetPointer(arg0))) { + ivar8 = subtract(ivar8, add(getWidgetActualWidth(new WidgetPointer(arg3)), 5)); + setWidgetSize(ivar8, 0, 0, 1, new WidgetPointer(arg2)); + ivar11 = add(multiply(getLineCount(ivar8, 307, svar0), 12), 3); + setWidgetScrollMax(0, ivar11, new WidgetPointer(arg2)); + setWidgetIsHidden(false, new WidgetPointer(arg3)); + script_31(arg3, arg2, 792, 789, 790, 791, 773, 788); + } else { + ivar11 = getWidgetActualHeight(new WidgetPointer(arg0)); + setWidgetSize(ivar8, 0, 0, 1, new WidgetPointer(arg2)); + setWidgetScrollMax(0, 0, new WidgetPointer(arg2)); + setWidgetIsHidden(true, new WidgetPointer(arg3)); + } + createExtraChild(new WidgetPointer(arg2), 4, 0); + setWidgetSize(0, ivar11, 1, 0); + setWidgetPosition(0, 0, 1, 0); + setWidgetFont(307); + setWidgetTextAlignment(1, 1, 0); + setWidgetRGB(new Color(0, 0, 0)); + setWidgetUnknownBoolean(false); + setWidgetText(svar0); + return; +} diff --git a/dumps/scripts/2779.cs2 b/dumps/scripts/2779.cs2 new file mode 100644 index 0000000..2e6d571 --- /dev/null +++ b/dumps/scripts/2779.cs2 @@ -0,0 +1,77 @@ +void script_2779(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,string arg8,string arg9,string arg10,string arg11,string arg12) { + int ivar8; + int ivar9; + int ivar10; + if (isWidgetHidden(new WidgetPointer(906,29))) { + return; + } + setWidgetNoOptions(new WidgetPointer(906,236)); + setWidgetNoOptions(new WidgetPointer(906,242)); + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(906,236)); + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(906,242)); + ivar8 = arg7; + if (((boolean)arg4)) { + ivar8 = max(arg7, add(getTextWidth(3793, arg9), 26)); + if (((boolean)mod(ivar8, 2))) { + ivar8 = add(ivar8, 1); + } + } + setWidgetSize(ivar8, 154, 0, 0, new WidgetPointer(906,29)); + ivar9 = add(multiply(getLineCount(getWidgetActualWidth(new WidgetPointer(906,235)), 3793, arg8), 16), 5); + setWidgetSize(20, ivar9, 1, 0, new WidgetPointer(906,235)); + setWidgetText(new WidgetPointer(906,235), arg8); + if (((boolean)arg2)) { + globalint_1092 = add(getClientCycle(), 5); + setWidgetSprite(4107, new WidgetPointer(906,234)); + setWidgetSize(111, 111, 0, 0, new WidgetPointer(906,234)); + setWidgetPosition(0, 7, 1, 0, new WidgetPointer(906,234)); + setWidgetPosition(0, 112, 1, 0, new WidgetPointer(906,235)); + setScriptCallOnGameloop(3094, "", new WidgetPointer(906,234)); + } else { + globalint_1092 = 0; + setScriptCallOnGameloop(-1, "", new WidgetPointer(906,234)); + setWidgetSprite(arg3, new WidgetPointer(906,234)); + setWidgetSize(76, 63, 0, 0, new WidgetPointer(906,234)); + setWidgetPosition(0, 18, 1, 0, new WidgetPointer(906,234)); + setWidgetPosition(0, 123, 1, 0, new WidgetPointer(906,235)); + ivar9 = subtract(ivar9, 35); + } + ivar10 = 0; + ivar9 = add(getWidgetActualY(new WidgetPointer(906,235)), ivar9); + if (((boolean)arg4) && ((boolean)arg6)) { + ivar10 = 12; + ivar9 = add(ivar9, ivar10); + setWidgetIsHidden(true, new WidgetPointer(906,236)); + setWidgetIsHidden(true, new WidgetPointer(906,242)); + } else if (((boolean)arg4) && ((boolean)arg6)) { + ivar10 = 41; + ivar9 = add(ivar9, ivar10); + setWidgetPosition(0, 8, 1, 2, new WidgetPointer(906,236)); + setWidgetIsHidden(false, new WidgetPointer(906,236)); + setWidgetIsHidden(true, new WidgetPointer(906,242)); + script_3098(59375852, 59375854, 59375855, 59375856, arg5, arg9, arg10); + } else if (((boolean)arg4) && ((boolean)arg6)) { + ivar10 = 41; + ivar9 = add(ivar9, ivar10); + setWidgetPosition(0, 8, 1, 2, new WidgetPointer(906,242)); + setWidgetIsHidden(false, new WidgetPointer(906,242)); + setWidgetIsHidden(true, new WidgetPointer(906,236)); + script_3099(59375858, 59375860, 59375861, 59375862, arg11, arg12); + } else { + ivar10 = 70; + ivar9 = add(ivar9, ivar10); + setWidgetPosition(0, 40, 1, 2, new WidgetPointer(906,236)); + setWidgetPosition(0, 10, 1, 2, new WidgetPointer(906,242)); + setWidgetIsHidden(false, new WidgetPointer(906,242)); + setWidgetIsHidden(false, new WidgetPointer(906,236)); + script_3098(59375852, 59375854, 59375855, 59375856, arg5, arg9, arg10); + script_3099(59375858, 59375860, 59375861, 59375862, arg11, arg12); + } + setWidgetSize(getWidgetActualWidth(new WidgetPointer(906,29)), ivar9, 0, 0, new WidgetPointer(906,29)); + script_3095(59375852, 59375858, arg0); + setWidgetPosition(0, ivar10, 1, 2, new WidgetPointer(906,235)); + setScriptCallOnKeyPress(3100, -2147483640, "i", new WidgetPointer(906,44)); + setWidgetIsHidden(false, new WidgetPointer(906,44)); + setWidgetIsHidden(false, new WidgetPointer(906,29)); + return; +} diff --git a/dumps/scripts/278.cs2 b/dumps/scripts/278.cs2 new file mode 100644 index 0000000..cbff2b4 --- /dev/null +++ b/dumps/scripts/278.cs2 @@ -0,0 +1,17 @@ +string script_278(int arg0) { + switch (arg0) { + case 1: + return "Standard"; + case 3: + return "Large"; + case 2: + return "Slim"; + case 6: + return "Double"; + case 5: + return "Wood"; + case 4: + return "Bone"; + } + return "Unknown hook"; +} diff --git a/dumps/scripts/2780.cs2 b/dumps/scripts/2780.cs2 new file mode 100644 index 0000000..72ada66 --- /dev/null +++ b/dumps/scripts/2780.cs2 @@ -0,0 +1,4 @@ +void script_2780(int arg0,int arg1,int arg2,int arg3,int arg4) { + script_2162(arg0, arg1, arg2, arg3, arg4); + return; +} diff --git a/dumps/scripts/2781.cs2 b/dumps/scripts/2781.cs2 new file mode 100644 index 0000000..19ce18b --- /dev/null +++ b/dumps/scripts/2781.cs2 @@ -0,0 +1,117 @@ +string script_2781() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + string svar0; + opcStruct6901(3,0,0) structdump_0; + svar0 = ""; + ivar0 = getCurrentDaysSinceLaunch(); + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + structdump_0 = cs2method6901(); + ivar3 = structdump_0.intpart_2; + ivar2 = structdump_0.intpart_1; + ivar1 = structdump_0.intpart_0; + ivar1 = subtract(divide(ivar1, 1440), 11745); + ivar4 = cs2method6907(); + ivar5 = cs2method6908(); + ivar6 = subtract(ivar5, ivar0); + if ((ivar5 <= ivar4) || (ivar6 < 0)) { + ivar6 = 0; + } + if (((ivar4 != 0) && (add(ivar1, ivar0) >= ivar4)) && ((globalint_1315 != ivar0) && (ivar1 <= 14))) { + if (ivar1 <= 7) { + if (ivar1 <= 3) { + if (ivar1 <= 1) { + if (((boolean)ivar1)) { + if ((ivar6 > 0) && (ivar6 <= 14)) { + if (ivar6 <= 7) { + if (ivar6 <= 3) { + if (((boolean)ivar6)) { + svar0 = "Your credit card has expired and your membership credit has run out. Please re-subscribe using a new credit card to restart your membership." + "
" + "
" + "If you renew today, you will pay the lower 'loyalty' rate. After this, your discount will no longer be available."; + globalint_1316 = ivar0; + } else { + if (add(globalint_1316, 2) < ivar0) { + svar0 = "Your credit card has expired and your membership credit has run out. Please re-subscribe using a new credit card to restart your membership." + "
" + "
" + "If you renew within the next " + intToStr(ivar6) + " days, you will pay the lower 'loyalty' rate. After this, your discount will no longer be available."; + globalint_1316 = ivar0; + } + } + } else { + if (add(globalint_1316, 4) < ivar0) { + svar0 = "Your credit card has expired and your membership credit has run out. Please re-subscribe using a new credit card to restart your membership." + "
" + "
" + "If you renew within the next " + intToStr(ivar6) + " days, you will pay the lower 'loyalty' rate. After this, your discount will no longer be available."; + if (ivar6 == 7) { + globalint_1316 = ivar0; + } else { + globalint_1316 = subtract(ivar0, subtract(7, ivar6)); + } + } + } + } else { + if (add(globalint_1316, 7) < ivar0) { + svar0 = "Your credit card has expired and your membership credit has run out. Please re-subscribe using a new credit card to restart your membership." + "
" + "
" + "If you renew within the next " + intToStr(ivar6) + " days, you will pay the lower 'loyalty' rate. After this, your discount will no longer be available."; + if (ivar6 == 14) { + globalint_1316 = ivar0; + } else { + globalint_1316 = subtract(ivar0, subtract(14, ivar6)); + } + } + } + } + } else { + if (ivar6 > 0) { + svar0 = "Your credit card has expired. Please re-subscribe using a new credit card to continue your membership." + "
" + "
" + "If you renew within the next " + intToStr(ivar6) + " days, you will continue paying your lower 'loyalty' rate. After this, your discount will no longer be available."; + } else { + svar0 = "Your credit card has expired. Please re-subscribe using a new credit card to continue your membership."; + } + globalint_1315 = ivar0; + } + } else { + if (add(globalint_1315, 2) < ivar0) { + if (ivar6 > 0) { + svar0 = "Your credit card has expired. Please re-subscribe using a new credit card to continue your membership." + "
" + "
" + "If you renew within the next " + intToStr(ivar6) + " days, you will continue paying your lower 'loyalty' rate. After this, your discount will no longer be available."; + } else { + svar0 = "Your credit card has expired. Please re-subscribe using a new credit card to continue your membership."; + } + if (ivar1 == 3) { + globalint_1315 = ivar0; + } else { + globalint_1315 = subtract(ivar0, subtract(3, ivar1)); + } + } + } + } else { + if (add(globalint_1315, 4) < ivar0) { + if (ivar6 > 0) { + svar0 = "Your credit card has expired. Please re-subscribe using a new credit card to continue your membership." + "
" + "
" + "If you renew within the next " + intToStr(ivar6) + " days, you will continue paying your lower 'loyalty' rate. After this, your discount will no longer be available."; + } else { + svar0 = "Your credit card has expired. Please re-subscribe using a new credit card to continue your membership."; + } + if (ivar1 == 7) { + globalint_1315 = ivar0; + } else { + globalint_1315 = subtract(ivar0, subtract(7, ivar1)); + } + } + } + } else { + if (add(globalint_1315, 7) < ivar0) { + if (ivar6 > 0) { + svar0 = "Your credit card has expired. Please re-subscribe using a new credit card to continue your membership." + "
" + "
" + "If you renew within the next " + intToStr(ivar6) + " days, you will continue paying your lower 'loyalty' rate. After this, your discount will no longer be available."; + } else { + svar0 = "Your credit card has expired. Please re-subscribe using a new credit card to continue your membership."; + } + if (ivar1 == 14) { + globalint_1315 = ivar0; + } else { + globalint_1315 = subtract(ivar0, subtract(14, ivar1)); + } + } + } + } + return svar0; +} diff --git a/dumps/scripts/2782.cs2 b/dumps/scripts/2782.cs2 new file mode 100644 index 0000000..1b99c04 --- /dev/null +++ b/dumps/scripts/2782.cs2 @@ -0,0 +1,90 @@ +void script_2782() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + string svar0; + if (strLength(globalstring_321) <= 0) { + setWidgetIsHidden(true, new WidgetPointer(667,52)); + setWidgetIsHidden(true, new WidgetPointer(670,1)); + setWidgetIsHidden(true, new WidgetPointer(763,3)); + return; + } + deleteAllExtraChilds(new WidgetPointer(667,54)); + ivar0 = getTextWidth(496, globalstring_321); + ivar1 = getMaxLineWidth(2147483647, 494, globalstring_322); + ivar2 = getMaxLineWidth(2147483647, 494, globalstring_323); + ivar3 = getMaxLineWidth(2147483647, 494, globalstring_324); + ivar4 = 0; + ivar5 = 0; + svar0 = "Superior stats are shown in " + "" + "white" + "" + "."; + if (strLength(globalstring_325) > 0) { + ivar4 = getMaxLineWidth(2147483647, 494, globalstring_325); + ivar5 = getTextWidth(494, svar0); + } + ivar6 = add(multiply(getLineCount(2147483647, 494, globalstring_324), 10), 3); + ivar7 = add(add(add(5, ivar2), 5), ivar3); + if (ivar4 > 0) { + ivar7 = add(add(ivar7, 5), ivar4); + ivar7 = max(ivar7, add(ivar5, 10)); + } + ivar7 = max(ivar7, ivar1); + ivar8 = max(max(ivar7, ivar0), getWidgetActualWidth(new WidgetPointer(667,65))); + ivar9 = 0; + if (ivar8 > ivar7) { + ivar9 = divide(subtract(ivar8, ivar7), 2); + } + createExtraChild(new WidgetPointer(667,54), 4, getExtraChildGap(new WidgetPointer(667,54))); + setWidgetPosition(add(ivar9, 10), 25, 0, 0); + setWidgetSize(getWidgetActualX(), ivar6, 1, 0); + setWidgetFont(494); + setWidgetUnknownBoolean(true); + setWidgetRGB(new Color(255, 152, 31)); + setWidgetText(globalstring_322); + createExtraChild(new WidgetPointer(667,54), 4, getExtraChildGap(new WidgetPointer(667,54))); + setWidgetPosition(add(ivar9, 15), 25, 0, 0); + setWidgetSize(getWidgetActualX(), ivar6, 1, 0); + setWidgetFont(494); + setWidgetUnknownBoolean(true); + setWidgetRGB(new Color(255, 152, 31)); + setWidgetText(globalstring_323); + createExtraChild(new WidgetPointer(667,54), 4, getExtraChildGap(new WidgetPointer(667,54))); + setWidgetPosition(add(add(add(ivar9, 15), ivar2), 5), 25, 0, 0); + setWidgetSize(ivar3, ivar6, 0, 0); + setWidgetFont(494); + setWidgetUnknownBoolean(true); + setWidgetRGB(new Color(255, 152, 31)); + setWidgetTextAlignment(1, 0, 0); + setWidgetText(globalstring_324); + if (ivar4 > 0) { + createExtraChild(new WidgetPointer(667,54), 4, getExtraChildGap(new WidgetPointer(667,54))); + setWidgetPosition(add(add(add(add(add(ivar9, 15), ivar2), 5), ivar3), 5), 25, 0, 0); + setWidgetSize(ivar4, ivar6, 0, 0); + setWidgetFont(494); + setWidgetUnknownBoolean(true); + setWidgetRGB(new Color(255, 152, 31)); + setWidgetTextAlignment(1, 0, 0); + setWidgetText(globalstring_325); + createExtraChild(new WidgetPointer(667,54), 4, getExtraChildGap(new WidgetPointer(667,54))); + setWidgetPosition(0, add(25, ivar6), 1, 0); + setWidgetSize(ivar5, 12, 0, 0); + setWidgetTextAlignment(1, 1, 0); + setWidgetFont(494); + setWidgetUnknownBoolean(true); + setWidgetRGB(new Color(255, 152, 31)); + setWidgetText(svar0); + ivar6 = add(ivar6, getWidgetActualHeight()); + } + setWidgetSize(add(ivar8, 20), add(ivar6, 60), 0, 0, new WidgetPointer(667,54)); + setWidgetText(new WidgetPointer(667,64), globalstring_321); + setWidgetIsHidden(false, new WidgetPointer(667,52)); + setWidgetIsHidden(false, new WidgetPointer(670,1)); + setWidgetIsHidden(false, new WidgetPointer(763,3)); + return; +} diff --git a/dumps/scripts/2783.cs2 b/dumps/scripts/2783.cs2 new file mode 100644 index 0000000..ae2b156 --- /dev/null +++ b/dumps/scripts/2783.cs2 @@ -0,0 +1,5 @@ +void script_2783() { + playSoundEffect(2266, 1, 0); + script_2947(); + return; +} diff --git a/dumps/scripts/2784.cs2 b/dumps/scripts/2784.cs2 new file mode 100644 index 0000000..ebb4064 --- /dev/null +++ b/dumps/scripts/2784.cs2 @@ -0,0 +1,77 @@ +void script_2784(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7) { + int ivar8; + int ivar9; + int ivar10; + int ivar11; + if (((boolean)arg0) || (((extractX(getMyPositionHash()) >= extractX(45094272)) && (extractX(getMyPositionHash()) <= extractX(852481535))) && ((extractY(getMyPositionHash()) >= extractY(45094272)) && (extractY(getMyPositionHash()) <= extractY(852481535))))) { + if (arg6 != -1) { + if (extractY(getMyPositionHash()) < add(extractY(45094272), 8)) { + setWidgetIsHidden(false, new WidgetPointer(arg6)); + deleteAllExtraChilds(new WidgetPointer(arg6)); + script_1086(arg6, 0, 0, 0); + } else { + setWidgetIsHidden(true, new WidgetPointer(arg6)); + } + } + if (((boolean)arg7) && (mod(getClientCycle(), 50) != 0)) { + return; + } + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(arg4)); + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(arg5)); + setWidgetSprite(444, new WidgetPointer(arg2)); + setWidgetText(new WidgetPointer(arg5), "ITEMS ARE" + "
" + "SAFE"); + } else if (((boolean)arg0) || (((extractX(getMyPositionHash()) >= extractX(48240000)) && (extractX(getMyPositionHash()) <= extractX(855627263))) && ((extractY(getMyPositionHash()) >= extractY(48240000)) && (extractY(getMyPositionHash()) <= extractY(855627263))))) { + if (arg6 != -1) { + if (extractY(getMyPositionHash()) < add(extractY(48240000), 8)) { + setWidgetIsHidden(false, new WidgetPointer(arg6)); + deleteAllExtraChilds(new WidgetPointer(arg6)); + script_1086(arg6, 0, 0, 0); + } else { + setWidgetIsHidden(true, new WidgetPointer(arg6)); + } + } + if (((boolean)arg7) && (mod(getClientCycle(), 50) != 0)) { + return; + } + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(arg4)); + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(arg5)); + setWidgetSprite(445, new WidgetPointer(arg2)); + setWidgetText(new WidgetPointer(arg5), "ITEMS ARE" + "
" + "DROPPED"); + } else { + setWidgetIsHidden(true, new WidgetPointer(arg4)); + setWidgetIsHidden(true, new WidgetPointer(arg5)); + setWidgetIsHidden(true, new WidgetPointer(arg2)); + setWidgetIsHidden(true, new WidgetPointer(arg3)); + if (arg6 != -1) { + setWidgetIsHidden(true, new WidgetPointer(arg6)); + } + deleteAllExtraChilds(new WidgetPointer(arg1)); + return; + } + setWidgetIsHidden(false, new WidgetPointer(arg4)); + setWidgetIsHidden(false, new WidgetPointer(arg5)); + setWidgetIsHidden(false, new WidgetPointer(arg2)); + setWidgetIsHidden(false, new WidgetPointer(arg3)); + cs2method2107(1, new WidgetPointer(arg2)); + ivar8 = getMaxLineWidth(512, 494, getWidgetText(new WidgetPointer(arg4))); + ivar8 = max(getMaxLineWidth(512, 494, getWidgetText(new WidgetPointer(arg5))), ivar8); + ivar8 = add(ivar8, 8); + ivar9 = 5; + setWidgetPosition(0, ivar9, 0, 0, new WidgetPointer(arg4)); + ivar10 = getLineCount(ivar8, 494, getWidgetText(new WidgetPointer(arg4))); + ivar10 = add(multiply(ivar10, 10), 3); + setWidgetSize(ivar8, ivar10, 0, 0, new WidgetPointer(arg4)); + ivar9 = subtract(add(ivar9, ivar10), 1); + setWidgetPosition(divide(subtract(ivar8, getWidgetActualWidth(new WidgetPointer(arg3))), 2), ivar9, 0, 0, new WidgetPointer(arg3)); + ivar9 = subtract(add(ivar9, getWidgetActualHeight(new WidgetPointer(arg3))), 1); + setWidgetPosition(0, ivar9, 0, 0, new WidgetPointer(arg5)); + ivar11 = getLineCount(ivar8, 494, getWidgetText(new WidgetPointer(arg5))); + ivar11 = add(multiply(ivar11, 10), 3); + setWidgetSize(ivar8, ivar10, 0, 0, new WidgetPointer(arg5)); + ivar9 = add(add(ivar9, ivar11), 3); + setWidgetSize(ivar8, ivar9, 0, 0, new WidgetPointer(arg1)); + setWidgetSize(ivar8, ivar9, 0, 0, new WidgetPointer(arg2)); + deleteAllExtraChilds(new WidgetPointer(arg1)); + script_1086(arg1, 0, 0, 0); + return; +} diff --git a/dumps/scripts/2785.cs2 b/dumps/scripts/2785.cs2 new file mode 100644 index 0000000..f7f74c7 --- /dev/null +++ b/dumps/scripts/2785.cs2 @@ -0,0 +1,15 @@ +int script_2785(int arg0) { + switch (arg0) { + case 34: + case 32: + case 33: + if (standart_config_281 < 93) { + return 32; + } + if (standart_config_281 < 120) { + return 33; + } + return 34; + } + return arg0; +} diff --git a/dumps/scripts/2786.cs2 b/dumps/scripts/2786.cs2 new file mode 100644 index 0000000..2ac6b55 --- /dev/null +++ b/dumps/scripts/2786.cs2 @@ -0,0 +1,59 @@ +void script_2786(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + int ivar6; + ivar4 = getWidgetActualWidth(new WidgetPointer(arg0)); + ivar5 = getWidgetActualHeight(new WidgetPointer(arg0)); + ivar6 = getExtraChildGap(new WidgetPointer(arg0)); + if (arg1 > 0) { + createExtraChild(new WidgetPointer(arg0), 5, ivar6); + setWidgetPosition(0, arg1, 0, 0); + setWidgetSize(ivar4, 32, 0, 0); + setWidgetSprite(1076); + cs2method1107(1); + ivar6 = add(ivar6, 1); + } + if (arg2 > 0) { + createExtraChild(new WidgetPointer(arg0), 5, ivar6); + setWidgetPosition(0, arg2, 0, 0); + setWidgetSize(ivar4, 32, 0, 0); + setWidgetSprite(1076); + cs2method1107(1); + ivar6 = add(ivar6, 1); + } + if (arg3 > 0) { + createExtraChild(new WidgetPointer(arg0), 5, ivar6); + setWidgetPosition(0, arg3, 0, 0); + setWidgetSize(ivar4, 32, 0, 0); + setWidgetSprite(1076); + cs2method1107(1); + ivar6 = add(ivar6, 1); + } + createExtraChild(new WidgetPointer(arg0), 5, ivar6); + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(ivar4, 32, 0, 0); + setWidgetSprite(1076); + cs2method1107(1); + ivar6 = add(ivar6, 1); + createExtraChild(new WidgetPointer(arg0), 5, ivar6); + setWidgetPosition(0, subtract(ivar5, 32), 0, 0); + setWidgetSize(ivar4, 32, 0, 0); + setWidgetSprite(1076); + cs2method1107(1); + setWidgetVFlip(1); + ivar6 = add(ivar6, 1); + createExtraChild(new WidgetPointer(arg0), 5, ivar6); + setWidgetPosition(0, 1, 0, 0); + setWidgetSize(32, subtract(ivar5, 2), 0, 0); + setWidgetSprite(1077); + cs2method1107(1); + ivar6 = add(ivar6, 1); + createExtraChild(new WidgetPointer(arg0), 5, ivar6); + setWidgetPosition(subtract(ivar4, 32), 1, 0, 0); + setWidgetSize(32, subtract(ivar5, 2), 0, 0); + setWidgetSprite(1077); + cs2method1107(1); + setWidgetHFlip(1); + ivar6 = add(ivar6, 1); + return; +} diff --git a/dumps/scripts/2787.cs2 b/dumps/scripts/2787.cs2 new file mode 100644 index 0000000..7c42098 --- /dev/null +++ b/dumps/scripts/2787.cs2 @@ -0,0 +1,408 @@ +cs2func_script_2787_struct(2,2,0) script_2787(int arg0,int arg1) { + switch (arg0) { + flow_1: + case 0: + switch (arg1) { + case 0: + return newstruct cs2func_script_2787_struct(-1, 2287, "You can see what each spell does by selecting the spellbook icon on your side interface. Move your mouse over the icon of the spell you want and a description will be available.", " "); + case 1: + return newstruct cs2func_script_2787_struct(1, 3759, "Wind Rush", "You can now cast " + "" + "Wind Rush" + "" + "."); + case 2: + return newstruct cs2func_script_2787_struct(1, 15, "Wind Strike", "You can now cast " + "" + "Wind Strike" + "" + "."); + case 3: + return newstruct cs2func_script_2787_struct(3, 16, "Confuse", "You can now cast " + "" + "Confuse" + "" + "."); + case 4: + return newstruct cs2func_script_2787_struct(5, 17, "Water Strike", "You can now cast " + "" + "Water Strike" + "" + "."); + case 5: + return newstruct cs2func_script_2787_struct(9, 19, "Earth Strike", "You can now cast " + "" + "Earth Strike" + "" + "."); + case 6: + return newstruct cs2func_script_2787_struct(10, 1564, "Members: Teleport to Mobilising Armies", "You can now cast " + "" + "Teleport to Mobilising Armies" + "" + "."); + case 7: + return newstruct cs2func_script_2787_struct(11, 20, "Weaken", "You can now cast " + "" + "Weaken" + "" + "."); + case 8: + return newstruct cs2func_script_2787_struct(13, 21, "Fire Strike", "You can now cast " + "" + "Fire Strike" + "" + "."); + case 9: + return newstruct cs2func_script_2787_struct(15, 22, "Bones to Bananas", "You can now cast " + "" + "Bones to Bananas" + "" + "."); + case 10: + return newstruct cs2func_script_2787_struct(17, 23, "Wind Bolt", "You can now cast " + "" + "Wind Bolt" + "" + "."); + case 11: + return newstruct cs2func_script_2787_struct(19, 24, "Curse", "You can now cast " + "" + "Curse" + "" + "."); + case 12: + return newstruct cs2func_script_2787_struct(20, 319, "Bind", "You can now cast " + "" + "Bind" + "" + "."); + case 13: + return newstruct cs2func_script_2787_struct(21, 25, "Low Level Alchemy", "You can now cast " + "" + "Low Level Alchemy" + "" + "."); + case 14: + return newstruct cs2func_script_2787_struct(23, 26, "Water Bolt", "You can now cast " + "" + "Water Bolt" + "" + "."); + case 15: + return newstruct cs2func_script_2787_struct(25, 27, "Teleport to Varrock", "You can now cast " + "" + "Teleport to Varrock" + "" + "."); + case 16: + return newstruct cs2func_script_2787_struct(29, 29, "Earth Bolt", "You can now cast " + "" + "Earth Bolt" + "" + "."); + case 17: + return newstruct cs2func_script_2787_struct(31, 30, "Teleport to Lumbridge", "You can now cast " + "" + "Teleport to Lumbridge" + "" + "."); + case 18: + return newstruct cs2func_script_2787_struct(33, 31, "Telekinetic Grab", "You can now cast " + "" + "Telekinetic Grab" + "" + "."); + case 19: + return newstruct cs2func_script_2787_struct(35, 32, "Fire Bolt", "You can now cast " + "" + "Fire Bolt" + "" + "."); + case 20: + return newstruct cs2func_script_2787_struct(37, 33, "Teleport to Falador", "You can now cast " + "" + "Teleport to Falador" + "" + "."); + case 21: + return newstruct cs2func_script_2787_struct(39, 34, "Crumble Undead", "You can now cast " + "" + "Crumble Undead" + "" + "."); + case 22: + return newstruct cs2func_script_2787_struct(40, 355, "Members: Teleport to House", "Members can now cast " + "" + "Teleport to House" + "" + "."); + case 23: + return newstruct cs2func_script_2787_struct(41, 35, "Wind Blast", "You can now cast " + "" + "Wind Blast" + "" + "."); + case 24: + return newstruct cs2func_script_2787_struct(43, 36, "Superheat Item", "You can now cast " + "" + "Superheat Item" + "" + "."); + case 25: + return newstruct cs2func_script_2787_struct(45, 37, "Members: Teleport to Camelot", "Members can now cast " + "" + "Teleport to Camelot" + "" + "."); + case 26: + return newstruct cs2func_script_2787_struct(47, 38, "Water Blast", "You can now cast " + "" + "Water Blast" + "" + "."); + case 27: + return newstruct cs2func_script_2787_struct(50, 320, "Members: Snare", "Members can now cast " + "" + "Snare" + "" + "."); + case 28: + return newstruct cs2func_script_2787_struct(50, 324, "Members: Magic Dart" + "
" + " (with level 55 Slayer)", "Members now have the Magic level required to cast " + "" + "Magic Dart" + "" + ". (They also need level 55 Slayer.)"); + case 29: + return newstruct cs2func_script_2787_struct(50, 53, "Members: Iban's Blast" + "
" + " (after Underground Pass)", "Members now have the Magic level required to cast " + "" + "Iban's Blast" + "" + " (after Underground Pass)."); + case 30: + return newstruct cs2func_script_2787_struct(51, 54, "Members: Teleport to Ardougne" + "
" + " (after Plague City)", "Members can now cast " + "" + "Teleport to Ardougne" + "" + "."); + case 31: + return newstruct cs2func_script_2787_struct(53, 40, "Earth Blast", "You can now cast " + "" + "Earth Blast" + "" + "."); + case 32: + return newstruct cs2func_script_2787_struct(55, 41, "High-level Alchemy", "You can now cast " + "" + "High-level Alchemy" + "" + "."); + case 33: + return newstruct cs2func_script_2787_struct(58, 55, "Members: Teleport to the Watchtower" + "
" + " (after Watchtower)", "Members now have the Magic level required to cast " + "" + "Teleport to the Watchtower" + "" + " (after Watchtower)."); + case 34: + return newstruct cs2func_script_2787_struct(59, 44, "Fire Blast", "You can now cast " + "" + "Fire Blast" + "" + "."); + case 35: + return newstruct cs2func_script_2787_struct(60, 354, "Members: Bones to Peaches" + "
" + " (after Mage Training Arena)", "Members can now learn " + "" + "Bones to Peaches" + "" + " in the Mage Training Arena."); + case 36: + return newstruct cs2func_script_2787_struct(60, 61, "Members: Saradomin Strike" + "
" + " (after Mage Arena)", "Members can now learn " + "" + "Saradomin Strike" + "" + " in the Mage Arena."); + case 37: + return newstruct cs2func_script_2787_struct(60, 60, "Members: Claws of Guthix" + "
" + " (after Mage Arena)", "Members can now learn " + "" + "Claws of Guthix" + "" + " in the Mage Arena."); + case 38: + return newstruct cs2func_script_2787_struct(60, 59, "Members: Flames of Zamorak" + "
" + " (after Mage Arena)", "Members can now learn " + "" + "Flames of Zamorak" + "" + " in the Mage Arena."); + case 39: + return newstruct cs2func_script_2787_struct(61, 323, "Members: Teleport to Trollheim" + "
" + " (after Eadgar's Ruse)", "Members now have the Magic level required to cast " + "" + "Teleport to Trollheim" + "" + " (after Eadgar's Ruse)."); + case 40: + return newstruct cs2func_script_2787_struct(62, 46, "Members: Wind Wave", "Members can now cast " + "" + "Wind Wave" + "" + "."); + case 41: + return newstruct cs2func_script_2787_struct(64, 357, "Members: Teleport to Ape Atoll" + "
" + " (after saving Awowogei in Recipe for Disaster)", "Members now have the Magic level required to cast " + "" + "Teleport to Ape Atoll" + "" + " (after saving Awowogei in Recipe for Disaster)."); + case 42: + return newstruct cs2func_script_2787_struct(65, 48, "Members: Water Wave", "Members can now cast " + "" + "Water Wave" + "" + "."); + case 43: + return newstruct cs2func_script_2787_struct(66, 56, "Members: Vulnerability", "Members can now cast " + "" + "Vulnerability" + "" + "."); + case 44: + return newstruct cs2func_script_2787_struct(70, 51, "Members: Earth Wave", "Members can now cast " + "" + "Earth Wave" + "" + "."); + case 45: + return newstruct cs2func_script_2787_struct(73, 57, "Members: Enfeeble", "Members can now cast " + "" + "Enfeeble" + "" + "."); + case 46: + return newstruct cs2func_script_2787_struct(74, 349, "Members: Tele-other Lumbridge", "Members can now cast " + "" + "Tele-other to Lumbridge" + "" + "."); + case 47: + return newstruct cs2func_script_2787_struct(75, 52, "Members: Fire Wave", "Members can now cast " + "" + "Fire Wave" + "" + "."); + case 48: + return newstruct cs2func_script_2787_struct(77, 7699, "Members: Storm of Armadyl" + "
" + " (after Ritual of the Mahjarrat)", "Members can now cast " + "" + "Storm of Armadyl" + "" + " (after Ritual of the Mahjarrat)."); + case 49: + return newstruct cs2func_script_2787_struct(79, 321, "Members: Entangle", "Members can now cast " + "" + "Entangle" + "" + "."); + case 50: + return newstruct cs2func_script_2787_struct(80, 58, "Members: Stun", "Members can now cast " + "" + "Stun" + "" + "."); + case 51: + return newstruct cs2func_script_2787_struct(80, 322, "Members: Charge", "Members can now cast " + "" + "Charge" + "" + "."); + case 52: + return newstruct cs2func_script_2787_struct(81, 500, "Members: Wind Surge", "Members can now cast " + "" + "Wind Surge" + "" + "."); + case 53: + return newstruct cs2func_script_2787_struct(82, 350, "Members: Tele-other Falador", "Members can now cast " + "" + "Tele-other to Falador" + "" + "."); + case 54: + return newstruct cs2func_script_2787_struct(85, 1565, "Teleport Block", "You can now cast " + "" + "Teleport Block" + "" + "."); + case 55: + return newstruct cs2func_script_2787_struct(85, 501, "Members: Water Surge", "Members can now cast " + "" + "Water Surge" + "" + "."); + case 56: + return newstruct cs2func_script_2787_struct(90, 811, "Members: Earth Surge", "Members can now cast " + "" + "Earth Surge" + "" + "."); + case 57: + return newstruct cs2func_script_2787_struct(90, 351, "Members: Tele-other to Camelot", "Members can now cast " + "" + "Tele-other to Camelot" + "" + "."); + case 58: + return newstruct cs2func_script_2787_struct(95, 814, "Members: Fire Surge", "Members can now cast " + "" + "Fire Surge" + "" + "."); + } + break; + case 1: + switch (arg1) { + case 0: + return newstruct cs2func_script_2787_struct(-1, 2287, "Once you have completed Desert Treasure, you will be able to access the Ancient Magicks spellbook.", ""); + case 1: + return newstruct cs2func_script_2787_struct(-1, 356, "Members: Home teleport (to Edgeville)", ""); + case 2: + return newstruct cs2func_script_2787_struct(50, 329, "Members: Smoke Rush", "Members using the Ancient Magicks spellbook can now cast " + "" + "Smoke Rush" + "" + "."); + case 3: + return newstruct cs2func_script_2787_struct(52, 337, "Members: Shadow Rush", "Members using the Ancient Magicks spellbook can now cast " + "" + "Shadow Rush" + "" + "."); + case 4: + return newstruct cs2func_script_2787_struct(54, 341, "Members: Teleport to Paddewwa", "Members using the Ancient Magicks spellbook can now cast " + "" + "Teleport to Paddewwa" + "" + "."); + case 5: + return newstruct cs2func_script_2787_struct(56, 333, "Members: Blood Rush", "Members using the Ancient Magicks spellbook can now cast " + "" + "Blood Rush" + "" + "."); + case 6: + return newstruct cs2func_script_2787_struct(58, 325, "Members: Ice Rush", "Members using the Ancient Magicks spellbook can now cast " + "" + "Ice Rush" + "" + "."); + case 7: + return newstruct cs2func_script_2787_struct(60, 342, "Members: Teleport to Senntisten", "Members using the Ancient Magicks spellbook can now cast " + "" + "Teleport to Senntisten" + "" + "."); + case 8: + return newstruct cs2func_script_2787_struct(61, 1568, "Members: Miasmic Rush", "Members using the Ancient Magicks spellbook can now cast " + "" + "Miasmic Rush" + "" + "."); + case 9: + return newstruct cs2func_script_2787_struct(62, 330, "Members: Smoke Burst", "Members using the Ancient Magicks spellbook can now cast " + "" + "Smoke Burst" + "" + "."); + case 10: + return newstruct cs2func_script_2787_struct(64, 338, "Members: Shadow Burst", "Members using the Ancient Magicks spellbook can now cast " + "" + "Shadow Burst" + "" + "."); + case 11: + return newstruct cs2func_script_2787_struct(66, 343, "Members: Teleport to Kharyrll", "Members using the Ancient Magicks spellbook can now cast " + "" + "Teleport to Kharyrll" + "" + "."); + case 12: + return newstruct cs2func_script_2787_struct(68, 334, "Members: Blood Burst", "Members using the Ancient Magicks spellbook can now cast " + "" + "Blood Burst" + "" + "."); + case 13: + return newstruct cs2func_script_2787_struct(70, 326, "Members: Ice Burst", "Members using the Ancient Magicks spellbook can now cast " + "" + "Ice Burst" + "" + "."); + case 14: + return newstruct cs2func_script_2787_struct(72, 344, "Members: Teleport to Lassar", "Members using the Ancient Magicks spellbook can now cast " + "" + "Teleport to Lassar" + "" + "."); + case 15: + return newstruct cs2func_script_2787_struct(73, 1569, "Members: Miasmic Burst", "Members using the Ancient Magicks spellbook can now cast " + "" + "Miasmic Burst" + "" + "."); + case 16: + return newstruct cs2func_script_2787_struct(74, 331, "Members: Smoke Blitz", "Members using the Ancient Magicks spellbook can now cast " + "" + "Smoke Blitz" + "" + "."); + case 17: + return newstruct cs2func_script_2787_struct(76, 339, "Members: Shadow Blitz", "Members using the Ancient Magicks spellbook can now cast " + "" + "Shadow Blitz" + "" + "."); + case 18: + return newstruct cs2func_script_2787_struct(78, 345, "Members: Teleport to Dareeyak", "Members using the Ancient Magicks spellbook can now cast " + "" + "Teleport to Dareeyak" + "" + "."); + case 19: + return newstruct cs2func_script_2787_struct(80, 335, "Members: Blood Blitz", "Members using the Ancient Magicks spellbook can now cast " + "" + "Blood Blitz" + "" + "."); + case 20: + return newstruct cs2func_script_2787_struct(82, 327, "Members: Ice Blitz", "Members using the Ancient Magicks spellbook can now cast " + "" + "Ice Blitz" + "" + "."); + case 21: + return newstruct cs2func_script_2787_struct(84, 346, "Members: Teleport to Carrallangar", "Members using the Ancient Magicks spellbook can now cast " + "" + "Teleport to Carrallangar" + "" + "."); + case 22: + return newstruct cs2func_script_2787_struct(85, 1567, "Members: Miasmic Blitz", "Members using the Ancient Magicks spellbook can now cast " + "" + "Miasmic Blitz" + "" + "."); + case 23: + return newstruct cs2func_script_2787_struct(86, 332, "Members: Smoke Barrage", "Members using the Ancient Magicks spellbook can now cast " + "" + "Smoke Barrage" + "" + "."); + case 24: + return newstruct cs2func_script_2787_struct(88, 340, "Members: Shadow Barrage", "Members using the Ancient Magicks spellbook can now cast " + "" + "Shadow Barrage" + "" + "."); + case 25: + return newstruct cs2func_script_2787_struct(90, 347, "Members: Teleport to Annakarl", "Members using the Ancient Magicks spellbook can now cast " + "" + "Teleport to Annakarl" + "" + "."); + case 26: + return newstruct cs2func_script_2787_struct(92, 336, "Members: Blood Barrage", "Members using the Ancient Magicks spellbook can now cast " + "" + "Blood Barrage" + "" + "."); + case 27: + return newstruct cs2func_script_2787_struct(94, 328, "Members: Ice Barrage", "Members using the Ancient Magicks spellbook can now cast " + "" + "Ice Barrage" + "" + "."); + case 28: + return newstruct cs2func_script_2787_struct(96, 348, "Members: Teleport to Ghorrock", "Members using the Ancient Magicks spellbook can now cast " + "" + "Teleport to Ghorrock" + "" + "."); + case 29: + return newstruct cs2func_script_2787_struct(97, 1566, "Members: Miasmic Barrage", "Members using the Ancient Magicks spellbook can now cast " + "" + "Miasmic Barrage" + "" + "."); + } + break; + case 2: + SWITCH (arg1) { + case 0: + GOTO flow_95 + case 1: + GOTO flow_96 + case 2: + GOTO flow_97 + case 3: + GOTO flow_98 + case 4: + GOTO flow_99 + case 5: + GOTO flow_100 + case 6: + GOTO flow_101 + case 7: + GOTO flow_102 + case 8: + GOTO flow_103 + case 9: + GOTO flow_104 + case 10: + GOTO flow_105 + case 11: + GOTO flow_106 + case 12: + GOTO flow_107 + case 13: + GOTO flow_108 + case 14: + GOTO flow_109 + case 15: + GOTO flow_110 + case 16: + GOTO flow_111 + case 17: + GOTO flow_112 + case 18: + GOTO flow_113 + case 19: + GOTO flow_114 + case 20: + GOTO flow_115 + case 21: + GOTO flow_116 + case 22: + GOTO flow_117 + case 23: + GOTO flow_118 + case 24: + GOTO flow_119 + case 25: + GOTO flow_120 + case 26: + GOTO flow_121 + case 27: + GOTO flow_122 + case 28: + GOTO flow_123 + case 29: + GOTO flow_124 + case 30: + GOTO flow_125 + case 31: + GOTO flow_126 + case 32: + GOTO flow_127 + case 33: + GOTO flow_128 + case 34: + GOTO flow_129 + case 35: + GOTO flow_130 + case 36: + GOTO flow_131 + case 37: + GOTO flow_132 + case 38: + GOTO flow_133 + case 39: + GOTO flow_134 + case 40: + GOTO flow_135 + case 41: + GOTO flow_136 + case 42: + GOTO flow_137 + case 43: + GOTO flow_138 + case 44: + GOTO flow_139 + case 45: + GOTO flow_140 + case 46: + GOTO flow_141 + case 47: + GOTO flow_142 + case 48: + GOTO flow_143 + case 49: + GOTO flow_144 + case 50: + GOTO flow_145 + case 51: + GOTO flow_146 + case 52: + GOTO flow_147 + } + break; + flow_95: + return newstruct cs2func_script_2787_struct(-1, 2287, "Once you have completed Lunar Diplomacy, you will be able to access the Lunar spellbook.", ""); + flow_96: + return newstruct cs2func_script_2787_struct(-1, 356, "Members: Home teleport (to Lunar Isle)", ""); + flow_97: + return newstruct cs2func_script_2787_struct(65, 543, "Members: Bake Pie", "Members using the Lunar spellbook can now cast " + "" + "Bake Pie" + "" + "."); + flow_98: + return newstruct cs2func_script_2787_struct(66, 567, "Members: Cure Plant", "Members using the Lunar spellbook can now cast " + "" + "Cure Plant" + "" + "."); + flow_99: + return newstruct cs2func_script_2787_struct(66, 577, "Members: Monster Examine" + "
" + " (after Dream Mentor)", "Members using the Lunar or Dungeoneering spellbook now have the Magic level required to cast " + "" + "Monster Examine" + "" + " (after Dream Mentor)."); + flow_100: + return newstruct cs2func_script_2787_struct(67, 568, "Members: Contact", "Members using the Lunar spellbook now have the Magic level required to cast " + "" + "Contact" + "" + " (after Dream Mentor)."); + flow_101: + return newstruct cs2func_script_2787_struct(68, 559, "Members: Cure Other", "Members using the Lunar or Dungeoneering spellbook can now cast " + "" + "Cure Other" + "" + "."); + flow_102: + return newstruct cs2func_script_2787_struct(68, 578, "Members: Humidify" + "
" + " (after Dream Mentor)", "Members using the Lunar or Dungeoneering spellbook now have the Magic level required to cast " + "" + "Humidify" + "" + " (after Dream Mentor)."); + flow_103: + return newstruct cs2func_script_2787_struct(69, 544, "Members: Teleport to Moonclan Island", "Members using the Lunar spellbook can now cast " + "" + "Teleport to Moonclan Island" + "" + "."); + flow_104: + return newstruct cs2func_script_2787_struct(70, 569, "Members: Group Teleport to Moonclan Island", "Members using the Lunar spellbook can now cast " + "" + "Group Teleport to Moonclan Island" + "" + "."); + flow_105: + return newstruct cs2func_script_2787_struct(71, 562, "Members: Cure Me", "Members using the Lunar or Dungeoneering spellbook can now cast " + "" + "Cure Me" + "" + "."); + flow_106: + return newstruct cs2func_script_2787_struct(71, 579, "Members: Hunter Kit" + "
" + " (after Dream Mentor)", "Members using the Lunar spellbook now have the Magic level required to cast " + "" + "Hunter Kit" + "" + " (after Dream Mentor)."); + flow_107: + return newstruct cs2func_script_2787_struct(71, 583, "Members: Teleport to Ourania", "Members using the Lunar spellbook can now cast " + "" + "Teleport to Ourania" + "" + "."); + flow_108: + return newstruct cs2func_script_2787_struct(72, 545, "Members: Teleport to Waterbirth", "Members using the Lunar spellbook can now cast " + "" + "Teleport to Waterbirth" + "" + "."); + flow_109: + return newstruct cs2func_script_2787_struct(72, 4585, "Members: Teleport to South Falador" + "
" + " (unlocked at the Livid Farm)", "Members using the Lunar spellbook can now cast " + "" + "Teleport to South Falador" + "" + " (unlocked at the Livid Farm)."); + flow_110: + return newstruct cs2func_script_2787_struct(73, 570, "Members: Group Teleport to Waterbirth", "Members using the Lunar spellbook can now cast " + "" + "Group Teleport to Waterbirth" + "" + "."); + flow_111: + return newstruct cs2func_script_2787_struct(74, 565, "Members: Cure Group", "Members using the Lunar or Dungeoneering spellbook can now cast " + "" + "Cure Group" + "" + "."); + flow_112: + return newstruct cs2func_script_2787_struct(75, 4586, "Members: Repair Rune Pouch" + "
" + " (unlocked at the Livid Farm)", "Members using the Lunar spellbook now have the Magic level required to cast " + "" + "Repair Rune Pouch" + "" + " (unlocked at the Livid Farm)."); + flow_113: + return newstruct cs2func_script_2787_struct(75, 547, "Members: Teleport to the Barbarian Outpost", "Members using the Lunar spellbook can now cast " + "" + "Teleport to the Barbarian Outpost" + "" + "."); + flow_114: + return newstruct cs2func_script_2787_struct(75, 576, "Members: Stat Spy" + "
" + " (after Dream Mentor)", "Members using the Lunar spellbook now have the Magic level required to cast " + "" + "Stat Spy" + "" + " (after Dream Mentor)."); + flow_115: + return newstruct cs2func_script_2787_struct(76, 4587, "Members: Teleport to North Ardougne" + "
" + " (unlocked at the Livid Farm)", "Members using the Lunar spellbook now have the Magic level required to cast " + "" + "Teleport to North Ardougne" + "" + " (unlocked at the Livid Farm)."); + flow_116: + return newstruct cs2func_script_2787_struct(76, 571, "Members: Group Teleport to the Barbarian Outpost", "Members using the Lunar spellbook can now cast " + "" + "Group Teleport to the Barbarian Outpost" + "" + "."); + flow_117: + return newstruct cs2func_script_2787_struct(77, 548, "Members: Superglass Make", "Members using the Lunar spellbook can now cast " + "" + "Superglass Make" + "" + "."); + flow_118: + return newstruct cs2func_script_2787_struct(78, 4588, "Members: Remote Farming" + "
" + " (unlocked at the Livid Farm)", "Members using the Lunar spellbook can now cast " + "" + "Remote Farming" + "" + " (unlocked at the Livid Farm)."); + flow_119: + return newstruct cs2func_script_2787_struct(78, 549, "Members: Teleport to Port Khazard", "Members using the Lunar spellbook can now cast " + "" + "Teleport to Port Khazard" + "" + "."); + flow_120: + return newstruct cs2func_script_2787_struct(79, 572, "Members: Group Teleport to Port Khazard", "Members using the Lunar spellbook can now cast " + "" + "Group Teleport to Port Khazard" + "" + "."); + flow_121: + return newstruct cs2func_script_2787_struct(79, 580, "Members: Dream" + "
" + " (after Dream Mentor)", "Members using the Lunar spellbook now have the Magic level required to cast " + "" + "Dream" + "" + " (after Dream Mentor)."); + flow_122: + return newstruct cs2func_script_2787_struct(80, 4590, "Members: Spiritualise Food" + "
" + " (unlocked at the Livid Farm)", "Members using the Lunar spellbook can now cast " + "" + "Spiritualise Food" + "" + " (unlocked at the Livid Farm)."); + flow_123: + return newstruct cs2func_script_2787_struct(80, 550, "Members: String Jewellery", "Members using the Lunar spellbook can now cast " + "" + "String Jewellery" + "" + "."); + flow_124: + return newstruct cs2func_script_2787_struct(81, 554, "Members: Stat Restore Potion Share", "Members using the Lunar spellbook can now cast " + "" + "Stat Restore Potion Share" + "" + "."); + flow_125: + return newstruct cs2func_script_2787_struct(82, 552, "Members: Magic Imbue", "Members using the Lunar spellbook can now cast " + "" + "Magic Imbue" + "" + "."); + flow_126: + return newstruct cs2func_script_2787_struct(83, 4589, "Members: Make Leather" + "
" + " (unlocked at the Livid Farm)", "Members using the Lunar spellbook can now cast " + "" + "Make Leather" + "" + " (unlocked at the Livid Farm)."); + flow_127: + return newstruct cs2func_script_2787_struct(83, 553, "Members: Fertile Soil", "Members using the Lunar spellbook can now cast " + "" + "Fertile Soil" + "" + "."); + flow_128: + return newstruct cs2func_script_2787_struct(84, 551, "Members: Boost Potion Share", "Members using the Lunar spellbook can now cast " + "" + "Boost Potion Share" + "" + "."); + flow_129: + return newstruct cs2func_script_2787_struct(85, 555, "Members: Teleport to the Fishing Guild", "Members using the Lunar spellbook can now cast " + "" + "Teleport to the Fishing Guild" + "" + "."); + flow_130: + return newstruct cs2func_script_2787_struct(86, 573, "Members: Group Teleport to the Fishing Guild", "Members using the Lunar spellbook can now cast " + "" + "Group Teleport to the Fishing Guild" + "" + "."); + flow_131: + return newstruct cs2func_script_2787_struct(86, 581, "Members: Plank Make" + "
" + " (after Dream Mentor)", "Members using the Lunar spellbook now have the Magic level required to cast " + "" + "Plank Make" + "" + " (after Dream Mentor)."); + flow_132: + return newstruct cs2func_script_2787_struct(87, 556, "Members: Teleport to Catherby", "Members using the Lunar spellbook can now cast " + "" + "Teleport to Catherby" + "" + "."); + flow_133: + return newstruct cs2func_script_2787_struct(87, 7684, "Members: Tune Bane Ore" + "
" + " (after Ritual of the Mahjarrat)", "Members using the Lunar spellbook now have the Magic level required to cast " + "" + "Tune Bane Ore" + "" + " (after Ritual of the Mahjarrat)."); + flow_134: + return newstruct cs2func_script_2787_struct(88, 574, "Members: Group Teleport to Catherby", "Members using the Lunar spellbook can now cast " + "" + "Group Teleport to Catherby" + "" + "."); + flow_135: + return newstruct cs2func_script_2787_struct(89, 557, "Members: Teleport to the Ice Plateau", "Members using the Lunar spellbook can now cast " + "" + "Teleport to the Ice Plateau" + "" + "."); + flow_136: + return newstruct cs2func_script_2787_struct(90, 4591, "Members: Disruption Shield" + "
" + " (unlocked at the Livid Farm)", "Members using the Lunar spellbook can now cast " + "" + "Disruption Shield" + "" + " (unlocked at the Livid Farm)."); + flow_137: + return newstruct cs2func_script_2787_struct(90, 575, "Members: Group Teleport to the Ice Plateau", "Members using the Lunar spellbook can now cast " + "" + "Group Teleport to the Ice Plateau" + "" + "."); + flow_138: + return newstruct cs2func_script_2787_struct(91, 558, "Members: Energy Transfer", "Members using the Lunar spellbook can now cast " + "" + "Energy Transfer" + "" + "."); + flow_139: + return newstruct cs2func_script_2787_struct(92, 560, "Members: Heal Other", "Members using the Lunar spellbook can now cast " + "" + "Heal Other" + "" + "."); + flow_140: + return newstruct cs2func_script_2787_struct(92, 7685, "Members: Teleport to Trollheim" + "
" + " (unlocked at the Livid Farm)", "Members using the Lunar spellbook can now cast " + "" + "Teleport to Trollheim" + "" + ". (unlocked at the Livid Farm)."); + flow_141: + return newstruct cs2func_script_2787_struct(93, 561, "Members: Vengeance Other", "Members using the Lunar or Dungeoneering spellbook can now cast " + "" + "Vengeance Other" + "" + "."); + flow_142: + return newstruct cs2func_script_2787_struct(93, 7686, "Members: Group Teleport to Trollheim" + "
" + " (unlocked at the Livid Farm)", "Members using the Lunar spellbook can now cast " + "" + "Group Teleport to Trollheim" + "" + ". (unlocked at the Livid Farm)."); + flow_143: + return newstruct cs2func_script_2787_struct(94, 564, "Members: Vengeance", "Members using the Lunar or Dungeoneering spellbook can now cast " + "" + "Vengeance" + "" + "."); + flow_144: + return newstruct cs2func_script_2787_struct(95, 4592, "Members: Vengeance Group" + "
" + " (unlocked at the Livid Farm)", "Members using the Lunar spellbook can now cast " + "" + "Vengeance Group" + "" + " (unlocked at the Livid Farm)."); + flow_145: + return newstruct cs2func_script_2787_struct(95, 566, "Members: Heal Group", "Members using the Lunar spellbook can now cast " + "" + "Heal Group" + "" + "."); + flow_146: + return newstruct cs2func_script_2787_struct(96, 582, "Members: Spellbook Swap" + "
" + " (after Dream Mentor)", "Members using the Lunar spellbook now have the Magic level required to cast " + "" + "Spellbook Swap" + "" + " (after Dream Mentor)."); + flow_147: + return newstruct cs2func_script_2787_struct(99, 7687, "Members: Borrowed Power" + "
" + " (unlocked at the Livid Farm)", "Members using the Lunar spellbook can now cast " + "" + "Borrowed Power" + "" + ". (unlocked at the Livid Farm)."); + } + return newstruct cs2func_script_2787_struct(0, -1, "", ""); +} diff --git a/dumps/scripts/2788.cs2 b/dumps/scripts/2788.cs2 new file mode 100644 index 0000000..1345422 --- /dev/null +++ b/dumps/scripts/2788.cs2 @@ -0,0 +1,107 @@ +cs2func_script_2788_struct(2,2,0) script_2788(int arg0,int arg1) { + switch (arg1) { + case 0: + return newstruct cs2func_script_2788_struct(-1, 2287, "You can see what each prayer does by selecting the Prayer icon on your side interface. Move your mouse over the icon of the prayer you want and a description will be available.", ""); + case 1: + return newstruct cs2func_script_2788_struct(1, getOtherCommonData(660, 735), "Thick Skin", "You can now use the " + "" + "Thick Skin" + "" + " prayer."); + case 2: + return newstruct cs2func_script_2788_struct(4, getOtherCommonData(661, 735), "Burst of Strength", "You can now use the " + "" + "Burst of Strength" + "" + " prayer."); + case 3: + return newstruct cs2func_script_2788_struct(7, getOtherCommonData(662, 735), "Clarity of Thought", "You can now use the " + "" + "Clarity of Thought" + "" + " prayer."); + case 4: + return newstruct cs2func_script_2788_struct(8, getOtherCommonData(678, 735), "Sharp Eye", "You can now use the " + "" + "Sharp Eye" + "" + " prayer."); + case 5: + return newstruct cs2func_script_2788_struct(9, getOtherCommonData(679, 735), "Mystic Will", "You can now use the " + "" + "Mystic Will" + "" + " prayer."); + case 6: + return newstruct cs2func_script_2788_struct(10, getOtherCommonData(663, 735), "Rock Skin", "You can now use the " + "" + "Rock Skin" + "" + " prayer."); + case 7: + return newstruct cs2func_script_2788_struct(13, getOtherCommonData(664, 735), "Superhuman Strength", "You can now use the " + "" + "Superhuman Strength" + "" + " prayer."); + case 8: + return newstruct cs2func_script_2788_struct(16, getOtherCommonData(665, 735), "Improved Reflexes", "You can now use the " + "" + "Improved Reflexes" + "" + " prayer."); + case 9: + return newstruct cs2func_script_2788_struct(19, getOtherCommonData(666, 735), "Rapid Restore", "You can now use the " + "" + "Rapid Restore" + "" + " prayer."); + case 10: + return newstruct cs2func_script_2788_struct(22, getOtherCommonData(667, 735), "Rapid Heal", "You can now use the " + "" + "Rapid Heal" + "" + " prayer."); + case 11: + return newstruct cs2func_script_2788_struct(25, getOtherCommonData(668, 735), "Protect Item", "You can now use the " + "" + "Protect Item" + "" + " prayer."); + case 12: + return newstruct cs2func_script_2788_struct(26, getOtherCommonData(680, 735), "Hawk Eye", "You can now use the " + "" + "Hawk Eye" + "" + " prayer."); + case 13: + return newstruct cs2func_script_2788_struct(27, getOtherCommonData(681, 735), "Mystic Lore", "You can now use the " + "" + "Mystic Lore" + "" + " prayer."); + case 14: + return newstruct cs2func_script_2788_struct(28, getOtherCommonData(669, 735), "Steel Skin", "You can now use the " + "" + "Steel Skin" + "" + " prayer."); + case 15: + return newstruct cs2func_script_2788_struct(31, getOtherCommonData(670, 735), "Ultimate Strength", "You can now use the " + "" + "Ultimate Strength" + "" + " prayer."); + case 16: + return newstruct cs2func_script_2788_struct(34, getOtherCommonData(671, 735), "Incredible Reflexes", "You can now use the " + "" + "Incredible Reflexes" + "" + " prayer."); + case 17: + return newstruct cs2func_script_2788_struct(35, getOtherCommonData(684, 735), "Members: Protect from Summoning", "Members can now use the " + "" + "Protect from Summoning" + "" + " prayer."); + case 18: + return newstruct cs2func_script_2788_struct(37, getOtherCommonData(672, 735), "Protect from Magic", "You can now use the " + "" + "Protect from Magic" + "" + " prayer."); + case 19: + return newstruct cs2func_script_2788_struct(40, getOtherCommonData(673, 735), "Protect from Missiles", "You can now use the " + "" + "Protect from Missiles" + "" + " prayer."); + case 20: + return newstruct cs2func_script_2788_struct(43, getOtherCommonData(674, 735), "Protect from Melee", "You can now use the " + "" + "Protect from Melee" + "" + " prayer."); + case 21: + return newstruct cs2func_script_2788_struct(44, getOtherCommonData(682, 735), "Eagle Eye", "You can now use the " + "" + "Eagle Eye" + "" + " prayer."); + case 22: + return newstruct cs2func_script_2788_struct(45, getOtherCommonData(683, 735), "Mystic Might", "You can now use the " + "" + "Mystic Might" + "" + " prayer."); + case 23: + return newstruct cs2func_script_2788_struct(46, getOtherCommonData(675, 735), "Members: Retribution", "Members can now use the " + "" + "Retribution" + "" + " prayer."); + case 24: + return newstruct cs2func_script_2788_struct(49, getOtherCommonData(676, 735), "Members: Redemption", "Members can now use the " + "" + "Redemption" + "" + " prayer."); + case 25: + return newstruct cs2func_script_2788_struct(50, getOtherCommonData(888, 735), "Members: Protect Item (curse)", "Members can now use the " + "" + "Protect Item" + "" + " curse (after The Temple at Senntisten)."); + case 26: + return newstruct cs2func_script_2788_struct(50, getOtherCommonData(889, 735), "Members: Sap Warrior", "Members can now use the " + "" + "Sap Warrior" + "" + " curse (after The Temple at Senntisten)."); + case 27: + return newstruct cs2func_script_2788_struct(52, getOtherCommonData(677, 735), "Members: Smite", "Members can now use the " + "" + "Smite" + "" + " prayer."); + case 28: + return newstruct cs2func_script_2788_struct(52, getOtherCommonData(890, 735), "Members: Sap Ranger", "Members can now use the " + "" + "Sap Ranger" + "" + " curse (after The Temple at Senntisten)."); + case 29: + return newstruct cs2func_script_2788_struct(54, getOtherCommonData(891, 735), "Members: Sap Mage", "Members can now use the " + "" + "Sap Mage" + "" + " curse (after The Temple at Senntisten)."); + case 30: + return newstruct cs2func_script_2788_struct(56, getOtherCommonData(892, 735), "Members: Sap Spirit", "Members can now use the " + "" + "Sap Spirit" + "" + " curse (after The Temple at Senntisten)."); + case 31: + return newstruct cs2func_script_2788_struct(59, getOtherCommonData(893, 735), "Members: Berserker", "Members can now use the " + "" + "Berserker" + "" + " curse (after The Temple at Senntisten)."); + case 32: + return newstruct cs2func_script_2788_struct(60, getOtherCommonData(685, 735), "Members: Chivalry" + "
" + " (after King's Ransom)", "Members now have the Prayer level required to use the " + "" + "Chivalry" + "" + " prayer (after King's Ransom)."); + case 33: + return newstruct cs2func_script_2788_struct(62, getOtherCommonData(894, 735), "Members: Deflect Summoning", "Members can now use the " + "" + "Deflect Summoning" + "" + " curse (after The Temple at Senntisten)."); + case 34: + return newstruct cs2func_script_2788_struct(65, getOtherCommonData(895, 735), "Members: Deflect Magic", "Members can now use the " + "" + "Deflect Magic" + "" + " curse (after The Temple at Senntisten)."); + case 35: + return newstruct cs2func_script_2788_struct(65, getOtherCommonData(1005, 735), "Members: Rapid Renewal" + "
" + " (with 65 Dungeoneering)", "Members can now use the " + "" + "Rapid Renewal" + "" + " prayer (bought from Daemonheim). (They also need level 65 Dungeoneering.)"); + case 36: + return newstruct cs2func_script_2788_struct(68, getOtherCommonData(896, 735), "Members: Deflect Missiles", "Members can now use the " + "" + "Deflect Missiles" + "" + " curse (after The Temple at Senntisten)."); + case 37: + return newstruct cs2func_script_2788_struct(70, getOtherCommonData(686, 735), "Members: Piety" + "
" + " (after King's Ransom)", "Members now have the Prayer level required to use the " + "" + "Piety" + "" + " prayer (after King's Ransom)."); + case 38: + return newstruct cs2func_script_2788_struct(71, getOtherCommonData(897, 735), "Members: Deflect Melee", "Members can now use the " + "" + "Deflect Melee" + "" + " curse (after The Temple at Senntisten)."); + case 39: + return newstruct cs2func_script_2788_struct(74, getOtherCommonData(1029, 735), "Members: Rigour" + "
" + " (with 74 Dungeoneering)", "Members can now use the " + "" + "Rigour" + "" + " prayer (bought from Daemonheim). (They also need level 74 Dungeoneering.)"); + case 40: + return newstruct cs2func_script_2788_struct(74, getOtherCommonData(898, 735), "Members: Leech Attack", "Members can now use the " + "" + "Leech Attack" + "" + " curse (after The Temple at Senntisten)."); + case 41: + return newstruct cs2func_script_2788_struct(76, getOtherCommonData(899, 735), "Members: Leech Ranged", "Members can now use the " + "" + "Leech Ranged" + "" + " curse (after The Temple at Senntisten)."); + case 42: + return newstruct cs2func_script_2788_struct(77, getOtherCommonData(1006, 735), "Members: Augury" + "
" + " (with 77 Dungeoneering)", "Members can now use the " + "" + "Augury" + "" + " prayer (bought from Daemonheim). (They also need level 77 Dungeoneering.)"); + case 43: + return newstruct cs2func_script_2788_struct(78, getOtherCommonData(900, 735), "Members: Leech Magic", "Members can now use the " + "" + "Leech Magic" + "" + " curse (after The Temple at Senntisten)."); + case 44: + return newstruct cs2func_script_2788_struct(80, getOtherCommonData(901, 735), "Members: Leech Defence", "Members can now use the " + "" + "Leech Defence" + "" + " curse (after The Temple at Senntisten)."); + case 45: + return newstruct cs2func_script_2788_struct(82, getOtherCommonData(902, 735), "Members: Leech Strength", "Members can now use the " + "" + "Leech Strength" + "" + " curse (after The Temple at Senntisten)."); + case 46: + return newstruct cs2func_script_2788_struct(84, getOtherCommonData(903, 735), "Members: Leech Energy", "Members can now use the " + "" + "Leech Energy" + "" + " curse (after The Temple at Senntisten)."); + case 47: + return newstruct cs2func_script_2788_struct(86, getOtherCommonData(904, 735), "Members: Leech Special Attack", "Members can now use the " + "" + "Leech Special Attack" + "" + " curse (after The Temple at Senntisten)."); + case 48: + return newstruct cs2func_script_2788_struct(89, getOtherCommonData(905, 735), "Members: Wrath", "Members can now use the " + "" + "Wrath" + "" + " curse (after The Temple at Senntisten)."); + case 49: + return newstruct cs2func_script_2788_struct(92, getOtherCommonData(906, 735), "Members: Soul Split", "Members can now use the " + "" + "Soul Split" + "" + " curse (after The Temple at Senntisten)."); + case 50: + return newstruct cs2func_script_2788_struct(95, getOtherCommonData(907, 735), "Members: Turmoil", "Members can now use the " + "" + "Turmoil" + "" + " curse (after The Temple at Senntisten)."); + } + return newstruct cs2func_script_2788_struct(0, -1, "", ""); +} diff --git a/dumps/scripts/2789.cs2 b/dumps/scripts/2789.cs2 new file mode 100644 index 0000000..59e96e1 --- /dev/null +++ b/dumps/scripts/2789.cs2 @@ -0,0 +1,4 @@ +void script_2789() { + script_2790(); + return; +} diff --git a/dumps/scripts/279.cs2 b/dumps/scripts/279.cs2 new file mode 100644 index 0000000..fea2616 --- /dev/null +++ b/dumps/scripts/279.cs2 @@ -0,0 +1,20 @@ +void script_279(int arg0,int arg1) { + string svar0; + svar0 = ""; + switch (arg0) { + case 1: + svar0 = "Found the perfect tackle for three species."; + break; + case 2: + svar0 = "Found the perfect tackle for all six species."; + break; + case 3: + svar0 = "Achieved an average rating of at least 80%."; + break; + case 4: + svar0 = "At least 80% of fish caught were the heaviest species."; + } + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(922,57), svar0, 25, 128, "IIsii", new WidgetPointer(arg1)); + setScriptCallOnMouseExit(40, new WidgetPointer(922,57), "I", new WidgetPointer(arg1)); + return; +} diff --git a/dumps/scripts/2790.cs2 b/dumps/scripts/2790.cs2 new file mode 100644 index 0000000..ec47b6f --- /dev/null +++ b/dumps/scripts/2790.cs2 @@ -0,0 +1,177 @@ +void script_2790() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + string svar0; + int stack_dump0; + ivar0 = -1; + ivar1 = -1; + ivar2 = -1; + ivar3 = -1; + if (IsFemale()) { + stack_dump0 = 2341; + ivar2 = 7; + ivar0 = stack_dump0; + ivar3 = globalint_1008; + } else if (((boolean)globalint_774)) { + setWidgetSprite(1056, new WidgetPointer(309,6)); + setWidgetSprite(1047, new WidgetPointer(309,7)); + stack_dump0 = 703; + ivar2 = 1; + ivar0 = stack_dump0; + ivar1 = 2340; + ivar3 = globalint_1009; + } else { + setWidgetSprite(1048, new WidgetPointer(309,6)); + setWidgetSprite(1055, new WidgetPointer(309,7)); + stack_dump0 = 2338; + ivar2 = 0; + ivar0 = stack_dump0; + ivar3 = globalint_1008; + } + deleteAllExtraChilds(new WidgetPointer(309,10)); + ivar4 = 0; + ivar5 = getCommonDefinitionSize(ivar0); + ivar6 = -1; + ivar7 = -1; + svar0 = ""; + ivar8 = 0; + ivar9 = 0; + while (ivar4 < ivar5) { + if (ivar1 == -1) { + ivar6 = cs2method_3408(105, 74, ivar0, ivar4); + ivar7 = getOtherCommonData(ivar6, 788); + svar0 = getOtherCommonData(ivar6, 792); + } else { + ivar7 = cs2method_3408(105, 75, ivar0, ivar4); + svar0 = cs2method_3408(105, 115, ivar1, ivar4); + } + createExtraChild(new WidgetPointer(309,10), 5, getExtraChildGap(new WidgetPointer(309,10))); + setWidgetSize(17, 17, 0, 0); + setWidgetPosition(0, add(ivar8, 1), 0, 0); + createExtraChild(new WidgetPointer(309,10), 4, getExtraChildGap(new WidgetPointer(309,10))); + setWidgetSize(20, 19, 1, 0); + setWidgetPosition(0, ivar8, 2, 0); + setWidgetTextAlignment(0, 1, 0); + setWidgetRGB(new Color(255, 152, 31)); + setWidgetFont(495); + setWidgetText(svar0); + if (ivar7 == ivar3) { + setWidgetSprite(699); + ivar9 = ivar8; + } else { + setWidgetSprite(697); + setScriptCallOnMouseEntered(1356, new WidgetPointer(-32768,3), getWidgetCustomChildArrayIndex(), 16777215, "Iii"); + setScriptCallOnMouseExit(1356, new WidgetPointer(-32768,3), getWidgetCustomChildArrayIndex(), 16750623, "Iii"); + setScriptCallOnMouseEntered(1356, new WidgetPointer(-32768,3), getWidgetCustomChildArrayIndex(), 16777215, "Iii"); + setScriptCallOnMouseExit(1356, new WidgetPointer(-32768,3), getWidgetCustomChildArrayIndex(), 16750623, "Iii"); + setWidgetContextMenuOption(1, svar0); + setWidgetContextMenuOption(1, svar0); + setScriptCallOnClickContextMenu(2831, -2147483644, ivar7, ivar2, "iKi"); + setScriptCallOnClickContextMenu(2831, -2147483644, ivar7, ivar2, "iKi"); + } + ivar4 = add(ivar4, 1); + ivar8 = add(ivar8, 19); + } + if (ivar8 > getWidgetActualHeight(new WidgetPointer(309,10))) { + setWidgetSize(20, 4, 1, 1, new WidgetPointer(309,10)); + setWidgetScrollMax(0, ivar8, new WidgetPointer(309,10)); + if (ivar9 < cs2method2601(new WidgetPointer(309,10))) { + cs2method2100(0, subtract(ivar9, 5), new WidgetPointer(309,10)); + } else { + if (add(ivar9, 19) >= add(cs2method2601(new WidgetPointer(309,10)), getWidgetActualHeight(new WidgetPointer(309,10)))) { + cs2method2100(0, subtract(add(ivar9, 25), getWidgetActualHeight(new WidgetPointer(309,10))), new WidgetPointer(309,10)); + } + } + setWidgetIsHidden(false, new WidgetPointer(309,11)); + script_31(20250635, 20250634, 792, 789, 790, 791, 773, 788); + } else { + setWidgetSize(4, 4, 1, 1, new WidgetPointer(309,10)); + setWidgetScrollMax(0, 0, new WidgetPointer(309,10)); + cs2method2100(0, 0, new WidgetPointer(309,10)); + deleteAllExtraChilds(new WidgetPointer(309,11)); + setWidgetIsHidden(true, new WidgetPointer(309,11)); + } + deleteAllExtraChilds(new WidgetPointer(309,16)); + ivar5 = getCommonDefinitionSize(2345); + ivar10 = 5; + ivar11 = 0; + if (multiply(add(divide(subtract(ivar5, 1), ivar10), 1), 21) > getWidgetActualHeight(new WidgetPointer(309,16))) { + stack_dump0 = 4; + ivar11 = 2; + ivar10 = stack_dump0; + } + ivar4 = 0; + ivar8 = 0; + ivar12 = 0; + ivar13 = -1; + ivar14 = 0; + while (ivar4 < ivar5) { + ivar14 = cs2method_3408(105, 105, 2345, ivar4); + svar0 = cs2method_3408(105, 115, 2344, ivar4); + createExtraChild(new WidgetPointer(309,16), 3, getExtraChildGap(new WidgetPointer(309,16))); + setWidgetSize(21, 21, 0, 0); + setWidgetFilled(1); + setWidgetPosition(add(multiply(ivar12, getWidgetActualWidth()), ivar11), ivar8, 0, 0); + setWidgetRGB(new Color(cs2method_3408(105, 105, 2343, ivar4))); + setScriptCallOnMouseOver(1160, new WidgetPointer(-32768,3), -2147483643, new WidgetPointer(309,22), svar0, 0, 512, "IiIsii"); + setScriptCallOnMouseExit(40, new WidgetPointer(309,22), "I"); + createExtraChild(new WidgetPointer(309,16), 5, getExtraChildGap(new WidgetPointer(309,16))); + setWidgetSize(getWidgetActualWidth(), getWidgetActualHeight(), 0, 0); + setWidgetPosition(getWidgetActualX(), getWidgetActualY(), 0, 0); + if (ivar14 == globalint_1015) { + setWidgetSprite(1043); + ivar9 = ivar8; + } else { + ivar13 = 1041; + setWidgetSprite(ivar13); + setScriptCallOnMouseExit(688, new WidgetPointer(-32768,3), getWidgetCustomChildArrayIndex(), ivar13, "Iid"); + ivar13 = 1042; + setScriptCallOnMouseEntered(688, new WidgetPointer(-32768,3), getWidgetCustomChildArrayIndex(), ivar13, "Iid"); + setWidgetContextMenuOption(1, svar0); + setScriptCallOnClickContextMenu(2832, -2147483644, ivar14, "ii"); + } + ivar4 = add(ivar4, 1); + if (ivar12 < subtract(ivar10, 1)) { + ivar12 = add(ivar12, 1); + } else { + ivar12 = 0; + ivar8 = add(ivar8, getWidgetActualHeight()); + } + } + if (ivar12 != 0) { + ivar8 = add(ivar8, 21); + } + if ((ivar8 > getWidgetActualHeight(new WidgetPointer(309,16))) || (ivar10 < 5)) { + setWidgetSize(20, 4, 1, 1, new WidgetPointer(309,16)); + setWidgetScrollMax(0, ivar8, new WidgetPointer(309,16)); + if (ivar9 < cs2method2601(new WidgetPointer(309,16))) { + cs2method2100(0, subtract(ivar9, 5), new WidgetPointer(309,16)); + } else { + if (add(ivar9, 21) >= add(cs2method2601(new WidgetPointer(309,16)), getWidgetActualHeight(new WidgetPointer(309,16)))) { + cs2method2100(0, subtract(add(ivar9, 25), getWidgetActualHeight(new WidgetPointer(309,16))), new WidgetPointer(309,16)); + } + } + setWidgetIsHidden(false, new WidgetPointer(309,17)); + script_31(20250641, 20250640, 792, 789, 790, 791, 773, 788); + } else { + setWidgetSize(4, 4, 1, 1, new WidgetPointer(309,16)); + setWidgetScrollMax(0, 0, new WidgetPointer(309,16)); + cs2method2100(0, 0, new WidgetPointer(309,16)); + deleteAllExtraChilds(new WidgetPointer(309,17)); + setWidgetIsHidden(true, new WidgetPointer(309,17)); + } + return; +} diff --git a/dumps/scripts/2791.cs2 b/dumps/scripts/2791.cs2 new file mode 100644 index 0000000..0cc0bca --- /dev/null +++ b/dumps/scripts/2791.cs2 @@ -0,0 +1,104 @@ +cs2func_script_2791_struct(4,1,0) script_2791(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + string svar0; + ivar1 = getOtherCommonData(cs2method_3408(105, 74, 869, arg0), 938); + svar0 = getOtherCommonData(cs2method_3408(105, 74, 869, arg0), 935); + ivar2 = getOtherCommonData(cs2method_3408(105, 74, 869, arg0), 939); + ivar3 = getOtherCommonData(cs2method_3408(105, 74, 869, arg0), 937); + ivar4 = 1; + ivar5 = 0; + if (((boolean)getOtherCommonData(cs2method_3408(105, 74, 869, arg0), 940))) { + switch (arg0) { + case 0: + if (getSkillActualLvl(7) < 40) { + ivar1 = getOtherCommonData(cs2method_3408(105, 74, 869, arg0), 936); + ivar4 = 0; + } + break; + case 1: + if (bitconfig_1527 < 160) { + ivar1 = getOtherCommonData(cs2method_3408(105, 74, 869, arg0), 936); + ivar4 = 0; + } + break; + case 2: + if (standart_config_359 < 100) { + ivar1 = getOtherCommonData(cs2method_3408(105, 74, 869, arg0), 936); + ivar4 = 0; + } + break; + case 3: + if (bitconfig_5491 > 370) { + ivar5 = 1; + } + break; + case 5: + if (bitconfig_418 < 26) { + ivar1 = getOtherCommonData(cs2method_3408(105, 74, 869, arg0), 936); + ivar4 = 0; + } + break; + case 6: + if (((boolean)bitconfig_5525)) { + ivar5 = 1; + } + break; + case 7: + if (bitconfig_5491 > 370) { + ivar5 = 1; + } + break; + case 9: + if (getSkillActualLvl(10) < 15) { + ivar1 = getOtherCommonData(cs2method_3408(105, 74, 869, arg0), 936); + ivar4 = 0; + } + break; + case 11: + if ((bitconfig_3618 < 16) || ((boolean)bitconfig_5550)) { + ivar1 = getOtherCommonData(cs2method_3408(105, 74, 869, arg0), 936); + ivar4 = 0; + } + break; + case 12: + if (bitconfig_3293 < 135) { + ivar1 = getOtherCommonData(cs2method_3408(105, 74, 869, arg0), 936); + ivar4 = 0; + } else { + if (bitconfig_6180 == 140) { + ivar5 = 1; + } + } + break; + case 17: + if (bitconfig_3618 < 28) { + ivar1 = getOtherCommonData(cs2method_3408(105, 74, 869, arg0), 936); + ivar4 = 0; + } + break; + case 14: + if (standart_config_492 < 4) { + ivar1 = getOtherCommonData(cs2method_3408(105, 74, 869, arg0), 936); + ivar4 = 0; + } + break; + case 16: + if (bitconfig_9067 < 8) { + ivar1 = getOtherCommonData(cs2method_3408(105, 74, 869, arg0), 936); + ivar4 = 0; + } + } + if (((boolean)ivar5)) { + ivar1 = getOtherCommonData(cs2method_3408(105, 74, 869, arg0), 942); + ivar4 = 1; + svar0 = getOtherCommonData(cs2method_3408(105, 74, 869, arg0), 941); + ivar3 = getOtherCommonData(cs2method_3408(105, 74, 869, arg0), 943); + ivar2 = getOtherCommonData(cs2method_3408(105, 74, 869, arg0), 944); + } + } + return newstruct cs2func_script_2791_struct(ivar1, ivar4, ivar3, ivar2, svar0); +} diff --git a/dumps/scripts/2792.cs2 b/dumps/scripts/2792.cs2 new file mode 100644 index 0000000..5d86560 --- /dev/null +++ b/dumps/scripts/2792.cs2 @@ -0,0 +1,4 @@ +void script_2792() { + script_2801(5832706, 3, 0); + return; +} diff --git a/dumps/scripts/2793.cs2 b/dumps/scripts/2793.cs2 new file mode 100644 index 0000000..63cca08 --- /dev/null +++ b/dumps/scripts/2793.cs2 @@ -0,0 +1,4 @@ +void script_2793() { + script_2801(5832706, 3, 0); + return; +} diff --git a/dumps/scripts/2794.cs2 b/dumps/scripts/2794.cs2 new file mode 100644 index 0000000..35451df --- /dev/null +++ b/dumps/scripts/2794.cs2 @@ -0,0 +1,4 @@ +void script_2794() { + script_2801(5832706, -3, 0); + return; +} diff --git a/dumps/scripts/2795.cs2 b/dumps/scripts/2795.cs2 new file mode 100644 index 0000000..dfb1971 --- /dev/null +++ b/dumps/scripts/2795.cs2 @@ -0,0 +1,4 @@ +void script_2795() { + script_2801(5832706, -3, 0); + return; +} diff --git a/dumps/scripts/2796.cs2 b/dumps/scripts/2796.cs2 new file mode 100644 index 0000000..818ef88 --- /dev/null +++ b/dumps/scripts/2796.cs2 @@ -0,0 +1,4 @@ +void script_2796() { + script_2801(5832706, 2, 0); + return; +} diff --git a/dumps/scripts/2797.cs2 b/dumps/scripts/2797.cs2 new file mode 100644 index 0000000..74630d9 --- /dev/null +++ b/dumps/scripts/2797.cs2 @@ -0,0 +1,4 @@ +void script_2797() { + script_2801(5832706, 2, 0); + return; +} diff --git a/dumps/scripts/2798.cs2 b/dumps/scripts/2798.cs2 new file mode 100644 index 0000000..e7ec709 --- /dev/null +++ b/dumps/scripts/2798.cs2 @@ -0,0 +1,4 @@ +void script_2798() { + script_2801(5832706, -2, 0); + return; +} diff --git a/dumps/scripts/2799.cs2 b/dumps/scripts/2799.cs2 new file mode 100644 index 0000000..9a6de43 --- /dev/null +++ b/dumps/scripts/2799.cs2 @@ -0,0 +1,4 @@ +void script_2799() { + script_2801(5832706, -2, 0); + return; +} diff --git a/dumps/scripts/28.cs2 b/dumps/scripts/28.cs2 new file mode 100644 index 0000000..dcea66d --- /dev/null +++ b/dumps/scripts/28.cs2 @@ -0,0 +1,4 @@ +void script_28(int arg0) { + script_48(); + return; +} diff --git a/dumps/scripts/280.cs2 b/dumps/scripts/280.cs2 new file mode 100644 index 0000000..e33fae8 --- /dev/null +++ b/dumps/scripts/280.cs2 @@ -0,0 +1,6 @@ +void script_280() { + setScriptCallOnGlobalConfigChange(281, 1118, 1119, 1120, 1121, 4, "Y", new WidgetPointer(925,0)); + setScriptCallOnConfigChange(281, 1660, 1661, 2, "Y", new WidgetPointer(925,0)); + setWidgetText(new WidgetPointer(925,78), intToStr(bitconfig_7285)); + return; +} diff --git a/dumps/scripts/2800.cs2 b/dumps/scripts/2800.cs2 new file mode 100644 index 0000000..73fc45a --- /dev/null +++ b/dumps/scripts/2800.cs2 @@ -0,0 +1,4 @@ +void script_2800(int arg0,int arg1,int arg2) { + script_2801(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/2801.cs2 b/dumps/scripts/2801.cs2 new file mode 100644 index 0000000..5b35a51 --- /dev/null +++ b/dumps/scripts/2801.cs2 @@ -0,0 +1,10 @@ +void script_2801(int arg0,int arg1,int arg2) { + setWidgetRGB(new Color(arg2), new WidgetPointer(arg0)); + if (arg1 > 0) { + cs2method2103(0, new WidgetPointer(arg0)); + } else { + cs2method2103(255, new WidgetPointer(arg0)); + } + setScriptCallOnGameloop(2802, arg1, new WidgetPointer(arg0), "iI", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/2802.cs2 b/dumps/scripts/2802.cs2 new file mode 100644 index 0000000..0e89873 --- /dev/null +++ b/dumps/scripts/2802.cs2 @@ -0,0 +1,11 @@ +void script_2802(int arg0,int arg1) { + int ivar2; + int ivar3; + ivar2 = getWidgetShadeColor(new WidgetPointer(arg1)); + ivar3 = min(max(add(ivar2, arg0), 0), 255); + cs2method2103(ivar3, new WidgetPointer(arg1)); + if (((boolean)ivar3) || (ivar3 == 255)) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg1)); + } + return; +} diff --git a/dumps/scripts/2803.cs2 b/dumps/scripts/2803.cs2 new file mode 100644 index 0000000..dc2bc41 --- /dev/null +++ b/dumps/scripts/2803.cs2 @@ -0,0 +1,4 @@ +void script_2803(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + script_2804(arg0, arg1, arg2, arg3, arg4, arg5); + return; +} diff --git a/dumps/scripts/2804.cs2 b/dumps/scripts/2804.cs2 new file mode 100644 index 0000000..a538ce6 --- /dev/null +++ b/dumps/scripts/2804.cs2 @@ -0,0 +1,6 @@ +void script_2804(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + setWidgetRGB(new Color(arg5), new WidgetPointer(arg0)); + cs2method2103(arg4, new WidgetPointer(arg0)); + setScriptCallOnGameloop(2805, new WidgetPointer(arg0), subtract(0, arg2), arg1, arg3, arg4, "Iiiii", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/2805.cs2 b/dumps/scripts/2805.cs2 new file mode 100644 index 0000000..baf402d --- /dev/null +++ b/dumps/scripts/2805.cs2 @@ -0,0 +1,11 @@ +void script_2805(int arg0,int arg1,int arg2,int arg3,int arg4) { + int ivar5; + int ivar6; + ivar5 = getWidgetShadeColor(new WidgetPointer(arg0)); + ivar6 = min(max(add(ivar5, arg1), arg3), arg4); + if ((ivar6 == arg3) || (ivar6 == arg4)) { + setScriptCallOnGameloop(2805, new WidgetPointer(arg0), arg2, arg1, arg3, arg4, "Iiiii", new WidgetPointer(arg0)); + } + cs2method2103(ivar6, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/2806.cs2 b/dumps/scripts/2806.cs2 new file mode 100644 index 0000000..77543a8 --- /dev/null +++ b/dumps/scripts/2806.cs2 @@ -0,0 +1,4 @@ +void script_2806() { + script_2807(5832705); + return; +} diff --git a/dumps/scripts/2807.cs2 b/dumps/scripts/2807.cs2 new file mode 100644 index 0000000..26a37c7 --- /dev/null +++ b/dumps/scripts/2807.cs2 @@ -0,0 +1,5 @@ +void script_2807(int arg0) { + cs2method2103(255, new WidgetPointer(arg0)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/2808.cs2 b/dumps/scripts/2808.cs2 new file mode 100644 index 0000000..ee2516b --- /dev/null +++ b/dumps/scripts/2808.cs2 @@ -0,0 +1,9 @@ +int script_2808(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + ivar3 = addToCoordinate(0, multiply(8, divide(extractX(arg1), 8)), extractZ(arg1), multiply(8, divide(extractY(arg1), 8))); + ivar4 = subtract(extractX(arg2), extractX(ivar3)); + ivar5 = subtract(extractY(arg2), extractY(ivar3)); + return addToCoordinate(arg0, ivar4, 0, ivar5); +} diff --git a/dumps/scripts/2809.cs2 b/dumps/scripts/2809.cs2 new file mode 100644 index 0000000..169720a --- /dev/null +++ b/dumps/scripts/2809.cs2 @@ -0,0 +1,4 @@ +void script_2809(int arg0) { + script_2797(); + return; +} diff --git a/dumps/scripts/281.cs2 b/dumps/scripts/281.cs2 new file mode 100644 index 0000000..cf6cc63 --- /dev/null +++ b/dumps/scripts/281.cs2 @@ -0,0 +1,108 @@ +void script_281() { + setItemOnWidgetMethod2200(globalint_1118, globalint_1119, new WidgetPointer(925,67)); + cs2method2305(new WidgetPointer(925,67), getItemName(globalint_1118)); + setItemOnWidgetMethod2200(globalint_1120, globalint_1121, new WidgetPointer(925,68)); + cs2method2305(new WidgetPointer(925,68), getItemName(globalint_1120)); + setWidgetText(new WidgetPointer(925,77), intToStr(bitconfig_7295)); + switch (globalint_1118) { + case 384: + setWidgetText(new WidgetPointer(925,52), "Shark"); + break; + case 372: + setWidgetText(new WidgetPointer(925,52), "Swordfish"); + break; + case 378: + setWidgetText(new WidgetPointer(925,52), "Lobster"); + break; + case 360: + setWidgetText(new WidgetPointer(925,52), "Tuna"); + break; + case 332: + setWidgetText(new WidgetPointer(925,52), "Salmon"); + break; + case 350: + setWidgetText(new WidgetPointer(925,52), "Pike"); + break; + case 336: + setWidgetText(new WidgetPointer(925,52), "Trout"); + break; + case 346: + setWidgetText(new WidgetPointer(925,52), "Herring"); + break; + case 328: + setWidgetText(new WidgetPointer(925,52), "Sardine"); + break; + case 318: + setWidgetText(new WidgetPointer(925,52), "Shrimp"); + break; + default: + setWidgetText(new WidgetPointer(925,52), ""); + } + switch (globalint_1120) { + case 384: + setWidgetText(new WidgetPointer(925,53), "Shark"); + break; + case 372: + setWidgetText(new WidgetPointer(925,53), "Swordfish"); + break; + case 378: + setWidgetText(new WidgetPointer(925,53), "Lobster"); + break; + case 360: + setWidgetText(new WidgetPointer(925,53), "Tuna"); + break; + case 332: + setWidgetText(new WidgetPointer(925,53), "Salmon"); + break; + case 350: + setWidgetText(new WidgetPointer(925,53), "Pike"); + break; + case 336: + setWidgetText(new WidgetPointer(925,53), "Trout"); + break; + case 346: + setWidgetText(new WidgetPointer(925,53), "Herring"); + break; + case 328: + setWidgetText(new WidgetPointer(925,53), "Sardine"); + break; + case 318: + setWidgetText(new WidgetPointer(925,53), "Shrimp"); + break; + default: + setWidgetText(new WidgetPointer(925,53), ""); + } + switch (bitconfig_7306) { + case 0: + setWidgetText(new WidgetPointer(925,25), "Cost: " + intToStr(110) + " tokens"); + setWidgetText(new WidgetPointer(925,26), "(Requires " + intToStr(20) + " medals)"); + setItemOnWidgetMethod2200(15666, -1, new WidgetPointer(925,41)); + break; + case 1: + setWidgetText(new WidgetPointer(925,25), "Cost: " + intToStr(230) + " tokens"); + setWidgetText(new WidgetPointer(925,26), "(Requires " + intToStr(50) + " medals)"); + setItemOnWidgetMethod2200(15667, -1, new WidgetPointer(925,41)); + break; + case 2: + setWidgetText(new WidgetPointer(925,25), "Cost: " + intToStr(470) + " tokens"); + setWidgetText(new WidgetPointer(925,26), "(Requires " + intToStr(110) + " medals)"); + setItemOnWidgetMethod2200(15668, -1, new WidgetPointer(925,41)); + break; + case 3: + setWidgetText(new WidgetPointer(925,25), "Cost: " + intToStr(900) + " tokens"); + setWidgetText(new WidgetPointer(925,26), "(Requires " + intToStr(230) + " medals)"); + setItemOnWidgetMethod2200(15669, -1, new WidgetPointer(925,41)); + break; + case 4: + setWidgetText(new WidgetPointer(925,25), "Cost: " + intToStr(1860) + " tokens"); + setWidgetText(new WidgetPointer(925,26), "(Requires " + intToStr(500) + " medals)"); + setItemOnWidgetMethod2200(15669, -1, new WidgetPointer(925,41)); + break; + case 5: + setWidgetText(new WidgetPointer(925,25), "You already own the best tackle box available."); + setWidgetText(new WidgetPointer(925,26), "(Unavailable)"); + setItemOnWidgetMethod2200(-1, -1, new WidgetPointer(925,41)); + } + setWidget3DRotation(0, 0, 250, 1666, 0, 1440, new WidgetPointer(925,41)); + return; +} diff --git a/dumps/scripts/2810.cs2 b/dumps/scripts/2810.cs2 new file mode 100644 index 0000000..493cca4 --- /dev/null +++ b/dumps/scripts/2810.cs2 @@ -0,0 +1,4 @@ +void script_2810(int arg0) { + script_2797(); + return; +} diff --git a/dumps/scripts/2811.cs2 b/dumps/scripts/2811.cs2 new file mode 100644 index 0000000..58833d8 --- /dev/null +++ b/dumps/scripts/2811.cs2 @@ -0,0 +1,4 @@ +void script_2811(int arg0) { + script_2804(arg0, 1, 1, 225, 255, 16777147); + return; +} diff --git a/dumps/scripts/2812.cs2 b/dumps/scripts/2812.cs2 new file mode 100644 index 0000000..8bca9e5 --- /dev/null +++ b/dumps/scripts/2812.cs2 @@ -0,0 +1,11 @@ +void script_2812(int arg0,int arg1) { + int ivar2; + int ivar3; + ivar2 = getWidgetShadeColor(new WidgetPointer(arg1)); + ivar3 = min(max(add(ivar2, multiply(arg0, 1)), 225), 255); + if ((ivar3 == 225) || (ivar3 == 255)) { + setScriptCallOnGameloop(2812, subtract(0, arg0), new WidgetPointer(arg1), "iI", new WidgetPointer(arg1)); + } + cs2method2103(ivar3, new WidgetPointer(arg1)); + return; +} diff --git a/dumps/scripts/2813.cs2 b/dumps/scripts/2813.cs2 new file mode 100644 index 0000000..98649d0 --- /dev/null +++ b/dumps/scripts/2813.cs2 @@ -0,0 +1,4 @@ +void script_2813(int arg0) { + script_2807(arg0); + return; +} diff --git a/dumps/scripts/2814.cs2 b/dumps/scripts/2814.cs2 new file mode 100644 index 0000000..7245756 --- /dev/null +++ b/dumps/scripts/2814.cs2 @@ -0,0 +1,9 @@ +void script_2814() { + if (globalint_1065 != -1) { + script_2815(); + setScriptCallOnGlobalConfigChange(-1, "", new WidgetPointer(89,0)); + } else { + setScriptCallOnGlobalConfigChange(2814, 1065, 1, "Y", new WidgetPointer(89,0)); + } + return; +} diff --git a/dumps/scripts/2815.cs2 b/dumps/scripts/2815.cs2 new file mode 100644 index 0000000..d4c6dc3 --- /dev/null +++ b/dumps/scripts/2815.cs2 @@ -0,0 +1,19 @@ +void script_2815() { + cs2method5405(0, 4); + cs2method5405(1, 4); + cs2method5406(0, 0, script_2808(globalint_1065, 73750262, 74110714), 378, script_2808(globalint_1065, 73750262, 74077947), 378, 0); + cs2method5406(1, 0, script_2808(globalint_1065, 73750262, 74045178), 210, script_2808(globalint_1065, 73750262, 74028794), 210, 0); + cs2method5406(0, 1, script_2808(globalint_1065, 73750262, 74077946), 378, script_2808(globalint_1065, 73750262, 74061562), 378, 0); + cs2method5406(1, 1, script_2808(globalint_1065, 73750262, 74012410), 335, script_2808(globalint_1065, 73750262, 73996026), 325, 0); + cs2method5406(0, 2, script_2808(globalint_1065, 73750262, 74045176), 378, script_2808(globalint_1065, 73750262, 74045175), 378, 0); + cs2method5406(1, 2, script_2808(globalint_1065, 73750262, 73979640), 346, script_2808(globalint_1065, 73750262, 73979639), 346, 0); + cs2method5406(0, 3, script_2808(globalint_1065, 73750262, 73996016), 670, script_2808(globalint_1065, 73750262, 73963244), 785, 0); + cs2method5406(1, 3, script_2808(globalint_1065, 73750262, 73996022), 210, script_2808(globalint_1065, 73750262, 73996021), 210, 0); + globalint_1065 = -1; + globalint_1064 = 0; + globalint_1067 = 877; + script_2825(1); + script_2810(5832706); + setScriptCallOnMinimapRelatedSetting3(2824, 1, "i", new WidgetPointer(89,0)); + return; +} diff --git a/dumps/scripts/2816.cs2 b/dumps/scripts/2816.cs2 new file mode 100644 index 0000000..50555d8 --- /dev/null +++ b/dumps/scripts/2816.cs2 @@ -0,0 +1,9 @@ +void script_2816() { + if (globalint_1065 != -1) { + script_2817(); + setScriptCallOnGlobalConfigChange(-1, "", new WidgetPointer(89,0)); + } else { + setScriptCallOnGlobalConfigChange(2816, 1065, 1, "Y", new WidgetPointer(89,0)); + } + return; +} diff --git a/dumps/scripts/2817.cs2 b/dumps/scripts/2817.cs2 new file mode 100644 index 0000000..36b4c30 --- /dev/null +++ b/dumps/scripts/2817.cs2 @@ -0,0 +1,27 @@ +void script_2817() { + cs2method5405(0, 8); + cs2method5405(1, 8); + cs2method5406(0, 0, script_2808(globalint_1065, 73750262, 73701111), 378, script_2808(globalint_1065, 73750262, 73717495), 378, 0); + cs2method5406(1, 0, script_2808(globalint_1065, 73750262, 73750263), 325, script_2808(globalint_1065, 73750262, 73766647), 295, 0); + cs2method5406(0, 1, script_2808(globalint_1065, 73750262, 73733879), 378, script_2808(globalint_1065, 73750262, 73750263), 378, 0); + cs2method5406(1, 1, script_2808(globalint_1065, 73750262, 73783031), 330, script_2808(globalint_1065, 73750262, 73799415), 335, 0); + cs2method5406(0, 2, script_2808(globalint_1065, 73750262, 73766647), 378, script_2808(globalint_1065, 73750262, 73783031), 378, 0); + cs2method5406(1, 2, script_2808(globalint_1065, 73750262, 73815799), 330, script_2808(globalint_1065, 73750262, 73832183), 350, 0); + cs2method5406(0, 3, script_2808(globalint_1065, 73750262, 73799415), 378, script_2808(globalint_1065, 73750262, 73815799), 378, 0); + cs2method5406(1, 3, script_2808(globalint_1065, 73750262, 73848567), 325, script_2808(globalint_1065, 73750262, 73864951), 305, 0); + cs2method5406(0, 4, script_2808(globalint_1065, 73750262, 73832183), 378, script_2808(globalint_1065, 73750262, 73848567), 378, 0); + cs2method5406(1, 4, script_2808(globalint_1065, 73750262, 73881335), 340, script_2808(globalint_1065, 73750262, 73897719), 325, 0); + cs2method5406(0, 5, script_2808(globalint_1065, 73750262, 73864950), 378, script_2808(globalint_1065, 73750262, 73881333), 378, 0); + cs2method5406(1, 5, script_2808(globalint_1065, 73750262, 73914103), 330, script_2808(globalint_1065, 73750262, 73930487), 340, 0); + cs2method5406(0, 6, script_2808(globalint_1065, 73750262, 73897717), 378, script_2808(globalint_1065, 73750262, 73914101), 378, 0); + cs2method5406(1, 6, script_2808(globalint_1065, 73750262, 73946871), 346, script_2808(globalint_1065, 73750262, 73963255), 346, 0); + cs2method5406(0, 7, script_2808(globalint_1065, 73750262, 73930485), 378, script_2808(globalint_1065, 73750262, 73946869), 378, 0); + cs2method5406(1, 7, script_2808(globalint_1065, 73750262, 73979639), 345, script_2808(globalint_1065, 73750262, 73996023), 355, 0); + globalint_1065 = -1; + globalint_1064 = 0; + globalint_1067 = 875; + script_2825(1); + script_2810(5832706); + setScriptCallOnMinimapRelatedSetting3(2824, 1, "i", new WidgetPointer(89,0)); + return; +} diff --git a/dumps/scripts/2818.cs2 b/dumps/scripts/2818.cs2 new file mode 100644 index 0000000..7c2e654 --- /dev/null +++ b/dumps/scripts/2818.cs2 @@ -0,0 +1,9 @@ +void script_2818() { + if (globalint_1065 != -1) { + script_2819(); + setScriptCallOnGlobalConfigChange(-1, "", new WidgetPointer(89,0)); + } else { + setScriptCallOnGlobalConfigChange(2818, 1065, 1, "Y", new WidgetPointer(89,0)); + } + return; +} diff --git a/dumps/scripts/2819.cs2 b/dumps/scripts/2819.cs2 new file mode 100644 index 0000000..53702dd --- /dev/null +++ b/dumps/scripts/2819.cs2 @@ -0,0 +1,21 @@ +void script_2819() { + cs2method5405(0, 5); + cs2method5405(1, 5); + cs2method5406(0, 0, script_2808(globalint_1065, 9437888, 10207993), 378, script_2808(globalint_1065, 9437888, 10289912), 378, 0); + cs2method5406(1, 0, script_2808(globalint_1065, 9437888, 10191601), 210, script_2808(globalint_1065, 9437888, 10257133), 210, 0); + cs2method5406(0, 1, script_2808(globalint_1065, 9437888, 10371817), 378, script_2808(globalint_1065, 9437888, 10371810), 378, 0); + cs2method5406(1, 1, script_2808(globalint_1065, 9437888, 10240743), 210, script_2808(globalint_1065, 9437888, 10224357), 210, 0); + cs2method5406(0, 2, script_2808(globalint_1065, 9437888, 10240727), 378, script_2808(globalint_1065, 9437888, 10175188), 378, 0); + cs2method5406(1, 2, script_2808(globalint_1065, 9437888, 10109663), 210, script_2808(globalint_1065, 9437888, 10044126), 210, 0); + cs2method5406(0, 3, script_2808(globalint_1065, 9437888, 9994963), 435, script_2808(globalint_1065, 9437888, 9945813), 465, 0); + cs2method5406(1, 3, script_2808(globalint_1065, 9437888, 9945824), 210, script_2808(globalint_1065, 9437888, 9945824), 210, 0); + cs2method5406(0, 4, script_2808(globalint_1065, 9437888, 9945817), 545, script_2808(globalint_1065, 9437888, 9945818), 530, 0); + cs2method5406(1, 4, script_2808(globalint_1065, 9437888, 9945824), 210, script_2808(globalint_1065, 9437888, 9945824), 210, 0); + globalint_1065 = -1; + globalint_1064 = 0; + globalint_1067 = 876; + script_2825(1); + script_2810(5832706); + setScriptCallOnMinimapRelatedSetting3(2824, 1, "i", new WidgetPointer(89,0)); + return; +} diff --git a/dumps/scripts/282.cs2 b/dumps/scripts/282.cs2 new file mode 100644 index 0000000..2d39dcb --- /dev/null +++ b/dumps/scripts/282.cs2 @@ -0,0 +1,18 @@ +void script_282() { + int ivar0; + int ivar1; + int ivar2; + ivar0 = 0; + ivar1 = 0; + ivar2 = multiplyDivide(standart_config_1380, 1000, 100); + ivar0 = cs2method_3408(105, 105, 706, ivar2); + ivar1 = cs2method_3408(105, 105, 707, ivar2); + setWidgetPosition(15, ivar0, 2, 0, new WidgetPointer(836,56)); + setWidgetSize(14, ivar1, 0, 0, new WidgetPointer(836,56)); + if (ivar2 < 25) { + setWidgetRGB(new Color(255, 150, 35), new WidgetPointer(836,56)); + } else { + setWidgetRGB(new Color(4, 131, 6), new WidgetPointer(836,56)); + } + return; +} diff --git a/dumps/scripts/2820.cs2 b/dumps/scripts/2820.cs2 new file mode 100644 index 0000000..7c31885 --- /dev/null +++ b/dumps/scripts/2820.cs2 @@ -0,0 +1,9 @@ +void script_2820() { + if (globalint_1065 != -1) { + script_2821(); + setScriptCallOnGlobalConfigChange(-1, "", new WidgetPointer(89,0)); + } else { + setScriptCallOnGlobalConfigChange(2820, 1065, 1, "Y", new WidgetPointer(89,0)); + } + return; +} diff --git a/dumps/scripts/2821.cs2 b/dumps/scripts/2821.cs2 new file mode 100644 index 0000000..8e2b288 --- /dev/null +++ b/dumps/scripts/2821.cs2 @@ -0,0 +1,17 @@ +void script_2821() { + cs2method5405(0, 3); + cs2method5405(1, 3); + cs2method5406(0, 0, script_2808(globalint_1065, 837292320, 32362799), 2385, script_2808(globalint_1065, 837292320, 32330031), 2370, 0); + cs2method5406(1, 0, script_2808(globalint_1065, 837292320, 32379191), 2265, script_2808(globalint_1065, 837292320, 32395576), 2260, 0); + cs2method5406(0, 1, script_2808(globalint_1065, 837292320, 32297264), 2420, script_2808(globalint_1065, 837292320, 32264497), 2355, 0); + cs2method5406(1, 1, script_2808(globalint_1065, 837292320, 32379193), 2285, script_2808(globalint_1065, 837292320, 32362809), 2235, 0); + cs2method5406(0, 2, script_2808(globalint_1065, 837292320, 32264499), 2395, script_2808(globalint_1065, 837292320, 32248117), 2380, 0); + cs2method5406(1, 2, script_2808(globalint_1065, 837292320, 32346424), 2270, script_2808(globalint_1065, 837292320, 32330040), 2250, 0); + globalint_1065 = -1; + globalint_1064 = 0; + globalint_1067 = 878; + script_2825(0); + script_2810(5832706); + setScriptCallOnMinimapRelatedSetting3(2824, 0, "i", new WidgetPointer(89,0)); + return; +} diff --git a/dumps/scripts/2822.cs2 b/dumps/scripts/2822.cs2 new file mode 100644 index 0000000..8684ff0 --- /dev/null +++ b/dumps/scripts/2822.cs2 @@ -0,0 +1,9 @@ +void script_2822() { + if (globalint_1065 != -1) { + script_2823(); + setScriptCallOnGlobalConfigChange(-1, "", new WidgetPointer(89,0)); + } else { + setScriptCallOnGlobalConfigChange(2822, 1065, 1, "Y", new WidgetPointer(89,0)); + } + return; +} diff --git a/dumps/scripts/2823.cs2 b/dumps/scripts/2823.cs2 new file mode 100644 index 0000000..4f3a5ce --- /dev/null +++ b/dumps/scripts/2823.cs2 @@ -0,0 +1,25 @@ +void script_2823() { + cs2method5405(0, 7); + cs2method5405(1, 7); + cs2method5406(0, 0, script_2808(globalint_1065, 40636184, 41029429), 378, script_2808(globalint_1065, 40636184, 41062196), 378, 0); + cs2method5406(1, 0, script_2808(globalint_1065, 40636184, 41127727), 210, script_2808(globalint_1065, 40636184, 41127728), 210, 0); + cs2method5406(0, 1, script_2808(globalint_1065, 40636184, 41062198), 378, script_2808(globalint_1065, 40636184, 41045814), 378, 0); + cs2method5406(1, 1, script_2808(globalint_1065, 40636184, 41144113), 210, script_2808(globalint_1065, 40636184, 41144114), 210, 0); + cs2method5406(0, 2, script_2808(globalint_1065, 40636184, 40996661), 378, script_2808(globalint_1065, 40636184, 40963893), 378, 0); + cs2method5406(1, 2, script_2808(globalint_1065, 40636184, 41160499), 210, script_2808(globalint_1065, 40636184, 41160500), 210, 0); + cs2method5406(0, 3, script_2808(globalint_1065, 40636184, 40931123), 378, script_2808(globalint_1065, 40636184, 40931121), 378, 0); + cs2method5406(1, 3, script_2808(globalint_1065, 40636184, 41160501), 210, script_2808(globalint_1065, 40636184, 41160502), 210, 0); + cs2method5406(0, 4, script_2808(globalint_1065, 40636184, 40963888), 378, script_2808(globalint_1065, 40636184, 40996655), 378, 0); + cs2method5406(1, 4, script_2808(globalint_1065, 40636184, 41160504), 210, script_2808(globalint_1065, 40636184, 41160505), 210, 0); + cs2method5406(0, 5, script_2808(globalint_1065, 40636184, 41062192), 378, script_2808(globalint_1065, 40636184, 41078576), 378, 0); + cs2method5406(1, 5, script_2808(globalint_1065, 40636184, 41160507), 210, script_2808(globalint_1065, 40636184, 41160508), 210, 0); + cs2method5406(0, 6, script_2808(globalint_1065, 40636184, 41094960), 378, script_2808(globalint_1065, 40636184, 41111344), 378, 0); + cs2method5406(1, 6, script_2808(globalint_1065, 40636184, 41160510), 210, script_2808(globalint_1065, 40636184, 41160512), 210, 0); + globalint_1065 = -1; + globalint_1064 = 0; + globalint_1067 = 879; + script_2825(0); + script_2810(5832706); + setScriptCallOnMinimapRelatedSetting3(2824, 0, "i", new WidgetPointer(89,0)); + return; +} diff --git a/dumps/scripts/2824.cs2 b/dumps/scripts/2824.cs2 new file mode 100644 index 0000000..3840515 --- /dev/null +++ b/dumps/scripts/2824.cs2 @@ -0,0 +1,4 @@ +void script_2824(int arg0) { + script_2825(arg0); + return; +} diff --git a/dumps/scripts/2825.cs2 b/dumps/scripts/2825.cs2 new file mode 100644 index 0000000..cbd2617 --- /dev/null +++ b/dumps/scripts/2825.cs2 @@ -0,0 +1,12 @@ +void script_2825(int arg0) { + if (globalint_1064 == subtract(cs2method5407(0), 1)) { + if (((boolean)arg0)) { + cs2method5512(); + } + setScriptCallOnMinimapRelatedSetting3(-1, "", new WidgetPointer(89,0)); + return; + } + cameraMethod5502(0, globalint_1064, cs2method_3408(105, 105, globalint_1067, globalint_1064), cs2method_3408(105, 105, globalint_1067, add(globalint_1064, 1)), 1, globalint_1064); + globalint_1064 = add(globalint_1064, 1); + return; +} diff --git a/dumps/scripts/2826.cs2 b/dumps/scripts/2826.cs2 new file mode 100644 index 0000000..11f5062 --- /dev/null +++ b/dumps/scripts/2826.cs2 @@ -0,0 +1,26 @@ +void script_2826(int arg0,int arg1) { + switch (globalint_1007) { + case 301: + cs2method5405(0, 4); + cs2method5405(1, 4); + cs2method5406(0, 0, script_2764(60248925, arg1), 565, script_2764(60232544, arg1), 820, 0); + cs2method5406(1, 0, script_2764(60248932, arg1), 295, script_2764(60281705, arg1), 378, 0); + cs2method5406(0, 1, script_2764(60330858, arg1), 700, script_2764(60363630, arg1), 705, 0); + cs2method5406(1, 1, script_2764(60478315, arg1), 335, script_2764(60527467, arg1), 305, 0); + cs2method5406(0, 2, script_2764(60281699, arg1), 740, script_2764(60183394, arg1), 755, 0); + cs2method5406(1, 2, script_2764(60281717, arg1), 315, script_2764(60265345, arg1), 270, 0); + cs2method5406(0, 3, script_2764(60281695, arg1), 554, script_2764(60298077, arg1), 554, 0); + cs2method5406(1, 3, script_2764(60085092, arg1), 305, script_2764(59806564, arg1), 215, 0); + cameraMethod5502(0, 0, 500, 300, 1, 0); + break; + case 302: + cameraMethod5502(0, 1, 600, 300, 1, 1); + break; + case 303: + cameraMethod5502(0, 2, 600, 300, 1, 2); + break; + default: + cs2method5512(); + } + return; +} diff --git a/dumps/scripts/2827.cs2 b/dumps/scripts/2827.cs2 new file mode 100644 index 0000000..2afd35b --- /dev/null +++ b/dumps/scripts/2827.cs2 @@ -0,0 +1,20 @@ +void script_2827(string arg0) { + int ivar0; + ivar0 = 0; + ivar0 = multiply(getLineCount(346, 495, arg0), 13); + if (ivar0 > 48) { + ivar0 = multiply(getLineCount(328, 495, arg0), 13); + } + if (ivar0 > 48) { + setWidgetScrollMax(0, ivar0, new WidgetPointer(178,23)); + script_31(11665432, 11665431, 792, 789, 790, 791, 773, 788); + setWidgetSize(334, 48, 0, 0, new WidgetPointer(178,23)); + setWidgetSize(16384, ivar0, 2, 0, new WidgetPointer(178,53)); + setWidgetSize(16384, ivar0, 2, 0, new WidgetPointer(178,54)); + setWidgetTextAlignment(0, 0, 0, new WidgetPointer(178,55)); + } else { + setWidgetSize(354, 48, 0, 0, new WidgetPointer(178,23)); + setWidgetTextAlignment(0, 1, 0, new WidgetPointer(178,55)); + } + return; +} diff --git a/dumps/scripts/2828.cs2 b/dumps/scripts/2828.cs2 new file mode 100644 index 0000000..d8710dc --- /dev/null +++ b/dumps/scripts/2828.cs2 @@ -0,0 +1,20 @@ +void script_2828(string arg0) { + int ivar0; + ivar0 = 0; + ivar0 = multiply(getLineCount(346, 495, arg0), 15); + if (ivar0 > 48) { + ivar0 = multiply(getLineCount(328, 495, arg0), 15); + } + if (ivar0 > 48) { + setWidgetScrollMax(0, ivar0, new WidgetPointer(178,58)); + script_31(11665412, 11665466, 792, 789, 790, 791, 773, 788); + setWidgetSize(334, 48, 0, 0, new WidgetPointer(178,58)); + setWidgetSize(16384, ivar0, 2, 0, new WidgetPointer(178,7)); + setWidgetSize(16384, ivar0, 2, 0, new WidgetPointer(178,8)); + setWidgetTextAlignment(0, 0, 0, new WidgetPointer(178,59)); + } else { + setWidgetSize(354, 48, 0, 0, new WidgetPointer(178,58)); + setWidgetTextAlignment(0, 1, 0, new WidgetPointer(178,59)); + } + return; +} diff --git a/dumps/scripts/2829.cs2 b/dumps/scripts/2829.cs2 new file mode 100644 index 0000000..b435ee1 --- /dev/null +++ b/dumps/scripts/2829.cs2 @@ -0,0 +1,8 @@ +void script_2829(int arg0) { + if (((boolean)bitconfig_6924)) { + setWidgetSprite(942, new WidgetPointer(arg0)); + } else { + setWidgetSprite(941, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/283.cs2 b/dumps/scripts/283.cs2 new file mode 100644 index 0000000..ad30ee2 --- /dev/null +++ b/dumps/scripts/283.cs2 @@ -0,0 +1,18 @@ +void script_283() { + int ivar0; + int ivar1; + int ivar2; + ivar0 = 0; + ivar1 = 0; + ivar2 = multiplyDivide(standart_config_1380, 1000, 100); + ivar0 = cs2method_3408(105, 105, 706, ivar2); + ivar1 = cs2method_3408(105, 105, 707, ivar2); + setWidgetPosition(15, ivar0, 2, 0, new WidgetPointer(834,74)); + setWidgetSize(14, ivar1, 0, 0, new WidgetPointer(834,74)); + if (ivar2 < 25) { + setWidgetRGB(new Color(255, 150, 35), new WidgetPointer(834,74)); + } else { + setWidgetRGB(new Color(4, 131, 6), new WidgetPointer(834,74)); + } + return; +} diff --git a/dumps/scripts/2830.cs2 b/dumps/scripts/2830.cs2 new file mode 100644 index 0000000..f03542b --- /dev/null +++ b/dumps/scripts/2830.cs2 @@ -0,0 +1,8 @@ +void script_2830(int arg0,int arg1) { + if (arg0 != 1) { + return; + } + globalint_774 = arg1; + script_2790(); + return; +} diff --git a/dumps/scripts/2831.cs2 b/dumps/scripts/2831.cs2 new file mode 100644 index 0000000..77e487b --- /dev/null +++ b/dumps/scripts/2831.cs2 @@ -0,0 +1,13 @@ +void script_2831(int arg0,int arg1,int arg2) { + if (arg0 != 1) { + return; + } + cs2method403(arg2, arg1); + if (((boolean)arg2)) { + globalint_1009 = arg1; + } else { + globalint_1008 = arg1; + } + script_2790(); + return; +} diff --git a/dumps/scripts/2832.cs2 b/dumps/scripts/2832.cs2 new file mode 100644 index 0000000..1b524e5 --- /dev/null +++ b/dumps/scripts/2832.cs2 @@ -0,0 +1,9 @@ +void script_2832(int arg0,int arg1) { + if (arg0 != 1) { + return; + } + cs2method404(0, arg1); + globalint_1015 = arg1; + script_2790(); + return; +} diff --git a/dumps/scripts/2833.cs2 b/dumps/scripts/2833.cs2 new file mode 100644 index 0000000..198bcc1 --- /dev/null +++ b/dumps/scripts/2833.cs2 @@ -0,0 +1,21 @@ +void script_2833(int arg0) { + switch (arg0) { + case 6099: + case 6102: + case 6101: + case 6100: + script_2411(arg0); + return; + case 13561: + case 19760: + case 13562: + script_2431(arg0); + return; + case 18339: + script_1273(arg0); + return; + } + setScriptCallOnConfigChange(-1, ""); + script_2410(getItemDefOpcode129Or130Method4209(arg0, 1), getItemDefOpcode129Or130Method4209(arg0, 2), getItemDefOpcode129Or130Method4209(arg0, 3), getItemDefOpcode129Or130Method4209(arg0, 4), getItemDefOpcode129Or130Method4209(arg0, 5), getItemOption(arg0, 1), getItemOption(arg0, 2), getItemOption(arg0, 3), getItemOption(arg0, 4), getItemOption(arg0, 5), getItemName(arg0)); + return; +} diff --git a/dumps/scripts/2834.cs2 b/dumps/scripts/2834.cs2 new file mode 100644 index 0000000..c32fc5e --- /dev/null +++ b/dumps/scripts/2834.cs2 @@ -0,0 +1,4 @@ +void script_2834() { + script_2835(); + return; +} diff --git a/dumps/scripts/2835.cs2 b/dumps/scripts/2835.cs2 new file mode 100644 index 0000000..d75d3eb --- /dev/null +++ b/dumps/scripts/2835.cs2 @@ -0,0 +1,22 @@ +void script_2835() { + int ivar0; + int ivar1; + int ivar2; + ivar0 = subtract(extractX(getMyPositionHash()), mod(extractX(getMyPositionHash()), 64)); + ivar1 = subtract(extractY(getMyPositionHash()), mod(extractY(getMyPositionHash()), 64)); + ivar2 = addToCoordinate(0, ivar0, 0, ivar1); + cs2method5405(0, 4); + cs2method5405(1, 4); + cs2method5406(0, 0, script_2808(ivar2, 54662856, 55072476), 1185, script_2808(ivar2, 54662856, 55105244), 1030, 0); + cs2method5406(1, 0, script_2808(ivar2, 54662856, 55072467), 338, script_2808(ivar2, 54662856, 55072469), 338, 0); + cs2method5406(0, 1, script_2808(ivar2, 54662856, 55154393), 790, script_2808(ivar2, 54662856, 55154391), 705, 0); + cs2method5406(1, 1, script_2808(ivar2, 54662856, 55072473), 338, script_2808(ivar2, 54662856, 55072474), 338, 0); + cs2method5406(0, 2, script_2808(ivar2, 54662856, 55072470), 620, script_2808(ivar2, 54662856, 55072472), 580, 0); + cs2method5406(1, 2, script_2808(ivar2, 54662856, 55072477), 338, script_2808(ivar2, 54662856, 55072479), 338, 0); + cs2method5406(0, 3, script_2808(ivar2, 54662856, 55072483), 495, script_2808(ivar2, 54662856, 55072485), 445, 0); + cs2method5406(1, 3, script_2808(ivar2, 54662856, 55072486), 338, script_2808(ivar2, 54662856, 55072488), 338, 0); + globalint_1068 = 0; + setScriptCallOnMinimapRelatedSetting3(2836, "", new WidgetPointer(384,0)); + cameraMethod5502(0, 0, 400, 400, 1, 0); + return; +} diff --git a/dumps/scripts/2836.cs2 b/dumps/scripts/2836.cs2 new file mode 100644 index 0000000..3ac7379 --- /dev/null +++ b/dumps/scripts/2836.cs2 @@ -0,0 +1,21 @@ +void script_2836() { + flow_0: + globalint_1068 = add(globalint_1068, 1); + SWITCH (globalint_1068) { + case 2: + GOTO flow_1 + case 3: + GOTO flow_2 + } + setScriptCallOnMinimapRelatedSetting3(2836, "", new WidgetPointer(384,0)); + cameraMethod5502(0, globalint_1068, 400, 400, 1, globalint_1068); + GOTO flow_3 + flow_1: + setScriptCallOnMinimapRelatedSetting3(2836, "", new WidgetPointer(384,0)); + cameraMethod5502(0, globalint_1068, 400, 0, 1, globalint_1068); + GOTO flow_3 + flow_2: + setScriptCallOnMinimapRelatedSetting3(-1, "", new WidgetPointer(384,0)); + flow_3: + return; +} diff --git a/dumps/scripts/2837.cs2 b/dumps/scripts/2837.cs2 new file mode 100644 index 0000000..58ca3dd --- /dev/null +++ b/dumps/scripts/2837.cs2 @@ -0,0 +1,4 @@ +void script_2837() { + script_2838(); + return; +} diff --git a/dumps/scripts/2838.cs2 b/dumps/scripts/2838.cs2 new file mode 100644 index 0000000..dcf1e43 --- /dev/null +++ b/dumps/scripts/2838.cs2 @@ -0,0 +1,26 @@ +void script_2838() { + int ivar0; + int ivar1; + int ivar2; + ivar0 = subtract(extractX(getMyPositionHash()), mod(extractX(getMyPositionHash()), 64)); + ivar1 = subtract(extractY(getMyPositionHash()), mod(extractY(getMyPositionHash()), 64)); + ivar2 = addToCoordinate(0, ivar0, 0, ivar1); + cs2method5405(0, 6); + cs2method5405(1, 6); + cs2method5406(0, 0, script_2808(ivar2, 54662856, 55072469), 1025, script_2808(ivar2, 54662856, 55072469), 790, 0); + cs2method5406(1, 0, script_2808(ivar2, 54662856, 55072472), 355, script_2808(ivar2, 54662856, 55072472), 265, 0); + cs2method5406(0, 1, script_2808(ivar2, 54662856, 55072482), 506, script_2808(ivar2, 54662856, 55072482), 506, 0); + cs2method5406(1, 1, script_2808(ivar2, 54662856, 55072485), 190, script_2808(ivar2, 54662856, 55072485), 190, 0); + cs2method5406(0, 2, script_2808(ivar2, 54662856, 55072479), 506, script_2808(ivar2, 54662856, 55072479), 506, 0); + cs2method5406(1, 2, script_2808(ivar2, 54662856, 55072484), 195, script_2808(ivar2, 54662856, 55072484), 210, 0); + cs2method5406(0, 3, script_2808(ivar2, 54662856, 55072476), 506, script_2808(ivar2, 54662856, 55072475), 506, 0); + cs2method5406(1, 3, script_2808(ivar2, 54662856, 55072479), 115, script_2808(ivar2, 54662856, 55072478), 70, 0); + cs2method5406(0, 4, script_2808(ivar2, 54662856, 55072474), 506, script_2808(ivar2, 54662856, 55072473), 506, 0); + cs2method5406(1, 4, script_2808(ivar2, 54662856, 55072478), 240, script_2808(ivar2, 54662856, 55072477), 330, 0); + cs2method5406(0, 5, script_2808(ivar2, 54662856, 55072472), 506, script_2808(ivar2, 54662856, 55072471), 506, 0); + cs2method5406(1, 5, script_2808(ivar2, 54662856, 55072485), 350, script_2808(ivar2, 54662856, 55072487), 350, 0); + globalint_1068 = 0; + setScriptCallOnMinimapRelatedSetting3(2840, "", new WidgetPointer(384,0)); + cameraMethod5502(0, globalint_1068, 100, 100, 1, globalint_1068); + return; +} diff --git a/dumps/scripts/2839.cs2 b/dumps/scripts/2839.cs2 new file mode 100644 index 0000000..0b4b18d --- /dev/null +++ b/dumps/scripts/2839.cs2 @@ -0,0 +1,6 @@ +void script_2839() { + globalint_1068 = 2; + cameraMethod5502(0, globalint_1068, 350, 400, 1, globalint_1068); + setScriptCallOnMinimapRelatedSetting3(2840, "", new WidgetPointer(384,0)); + return; +} diff --git a/dumps/scripts/284.cs2 b/dumps/scripts/284.cs2 new file mode 100644 index 0000000..a578d22 --- /dev/null +++ b/dumps/scripts/284.cs2 @@ -0,0 +1,9 @@ +int script_284(int arg0) { + int ivar1; + int ivar2; + ivar1 = extractX(arg0); + ivar2 = extractY(arg0); + ivar1 = subtract(ivar1, mod(ivar1, 64)); + ivar2 = subtract(ivar2, mod(ivar2, 64)); + return addToCoordinate(0, ivar1, 0, ivar2); +} diff --git a/dumps/scripts/2840.cs2 b/dumps/scripts/2840.cs2 new file mode 100644 index 0000000..aafc532 --- /dev/null +++ b/dumps/scripts/2840.cs2 @@ -0,0 +1,32 @@ +void script_2840() { + flow_0: + globalint_1068 = add(globalint_1068, 1); + SWITCH (globalint_1068) { + case 1: + GOTO flow_1 + case 2: + GOTO flow_2 + case 3: + GOTO flow_3 + case 5: + GOTO flow_4 + } + setScriptCallOnMinimapRelatedSetting3(2840, "", new WidgetPointer(384,0)); + cameraMethod5502(0, globalint_1068, 400, 400, 1, globalint_1068); + GOTO flow_5 + flow_1: + setScriptCallOnMinimapRelatedSetting3(2840, "", new WidgetPointer(384,0)); + cameraMethod5502(0, globalint_1068, 400, 0, 1, globalint_1068); + GOTO flow_5 + flow_2: + setScriptCallOnMinimapRelatedSetting3(-1, "", new WidgetPointer(384,0)); + GOTO flow_5 + flow_3: + setScriptCallOnMinimapRelatedSetting3(2840, "", new WidgetPointer(384,0)); + cameraMethod5502(0, globalint_1068, 650, 700, 1, globalint_1068); + GOTO flow_5 + flow_4: + setScriptCallOnMinimapRelatedSetting3(-1, "", new WidgetPointer(384,0)); + flow_5: + return; +} diff --git a/dumps/scripts/2841.cs2 b/dumps/scripts/2841.cs2 new file mode 100644 index 0000000..2f6cff0 --- /dev/null +++ b/dumps/scripts/2841.cs2 @@ -0,0 +1,11 @@ +void script_2841() { + setWidgetIsHidden(false, new WidgetPointer(473,39)); + setWidgetIsHidden(true, new WidgetPointer(473,68)); + setWidgetIsHidden(true, new WidgetPointer(473,131)); + setWidgetIsHidden(true, new WidgetPointer(473,176)); + setWidgetIsHidden(false, new WidgetPointer(473,228)); + setWidgetIsHidden(true, new WidgetPointer(473,225)); + setWidgetIsHidden(true, new WidgetPointer(473,222)); + setWidgetIsHidden(true, new WidgetPointer(473,37)); + return; +} diff --git a/dumps/scripts/2842.cs2 b/dumps/scripts/2842.cs2 new file mode 100644 index 0000000..ee225cd --- /dev/null +++ b/dumps/scripts/2842.cs2 @@ -0,0 +1,11 @@ +void script_2842() { + setWidgetIsHidden(true, new WidgetPointer(473,39)); + setWidgetIsHidden(false, new WidgetPointer(473,68)); + setWidgetIsHidden(true, new WidgetPointer(473,131)); + setWidgetIsHidden(true, new WidgetPointer(473,176)); + setWidgetIsHidden(true, new WidgetPointer(473,228)); + setWidgetIsHidden(false, new WidgetPointer(473,225)); + setWidgetIsHidden(true, new WidgetPointer(473,222)); + setWidgetIsHidden(true, new WidgetPointer(473,37)); + return; +} diff --git a/dumps/scripts/2843.cs2 b/dumps/scripts/2843.cs2 new file mode 100644 index 0000000..643fa49 --- /dev/null +++ b/dumps/scripts/2843.cs2 @@ -0,0 +1,11 @@ +void script_2843() { + setWidgetIsHidden(true, new WidgetPointer(473,39)); + setWidgetIsHidden(true, new WidgetPointer(473,68)); + setWidgetIsHidden(false, new WidgetPointer(473,131)); + setWidgetIsHidden(true, new WidgetPointer(473,176)); + setWidgetIsHidden(true, new WidgetPointer(473,228)); + setWidgetIsHidden(true, new WidgetPointer(473,225)); + setWidgetIsHidden(false, new WidgetPointer(473,222)); + setWidgetIsHidden(true, new WidgetPointer(473,37)); + return; +} diff --git a/dumps/scripts/2844.cs2 b/dumps/scripts/2844.cs2 new file mode 100644 index 0000000..fb296e6 --- /dev/null +++ b/dumps/scripts/2844.cs2 @@ -0,0 +1,11 @@ +void script_2844() { + setWidgetIsHidden(true, new WidgetPointer(473,39)); + setWidgetIsHidden(true, new WidgetPointer(473,68)); + setWidgetIsHidden(true, new WidgetPointer(473,131)); + setWidgetIsHidden(false, new WidgetPointer(473,176)); + setWidgetIsHidden(true, new WidgetPointer(473,228)); + setWidgetIsHidden(true, new WidgetPointer(473,225)); + setWidgetIsHidden(true, new WidgetPointer(473,222)); + setWidgetIsHidden(false, new WidgetPointer(473,37)); + return; +} diff --git a/dumps/scripts/2845.cs2 b/dumps/scripts/2845.cs2 new file mode 100644 index 0000000..ca90a09 --- /dev/null +++ b/dumps/scripts/2845.cs2 @@ -0,0 +1,316 @@ +void script_2845() { + int ivar0; + if (((boolean)bitconfig_3251)) { + setWidgetModel(20522, new WidgetPointer(473,43)); + setWidgetText(new WidgetPointer(473,44), "Attacker level up to 2"); + setWidgetText(new WidgetPointer(473,46), "+20 bonus damage"); + setWidgetText(new WidgetPointer(473,45), "200 Attacker Honour Points"); + if (bitconfig_3256 > 199) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,45)); + } + } else if (bitconfig_3251 == 2) { + setWidgetModel(20523, new WidgetPointer(473,43)); + setWidgetText(new WidgetPointer(473,44), "Attacker level up to 3"); + setWidgetText(new WidgetPointer(473,46), "+30 bonus damage"); + setWidgetText(new WidgetPointer(473,45), "300 Attacker Honour Points"); + if (bitconfig_3256 > 299) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,45)); + } + } else if (bitconfig_3251 == 3) { + setWidgetModel(20524, new WidgetPointer(473,43)); + setWidgetText(new WidgetPointer(473,44), "Attacker level up to 4"); + setWidgetText(new WidgetPointer(473,46), "+40 bonus damage"); + setWidgetText(new WidgetPointer(473,45), "400 Attacker Honour Points"); + if (bitconfig_3256 > 399) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,45)); + } + } else if (bitconfig_3251 == 4) { + setWidgetModel(20525, new WidgetPointer(473,43)); + setWidgetText(new WidgetPointer(473,44), "Attacker level up to 5"); + setWidgetText(new WidgetPointer(473,46), "+50 bonus damage"); + setWidgetText(new WidgetPointer(473,45), "500 Attacker Honour Points"); + if (bitconfig_3256 > 499) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,45)); + } + } else if (bitconfig_3251 == 5) { + setWidgetModel(20525, new WidgetPointer(473,43)); + setWidgetText(new WidgetPointer(473,44), "Attacker level up complete"); + setWidgetText(new WidgetPointer(473,46), " - Mastered - "); + setWidgetText(new WidgetPointer(473,45), " - Mastered - "); + } else { + bitconfig_3251 = 1; + setWidgetModel(20522, new WidgetPointer(473,43)); + setWidgetText(new WidgetPointer(473,44), "Attacker level up to 2"); + setWidgetText(new WidgetPointer(473,46), "+20 bonus damage"); + setWidgetText(new WidgetPointer(473,45), "200 Attacker Honour Points"); + if (bitconfig_3256 > 199) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,45)); + } + } + if (((boolean)bitconfig_3253)) { + setWidgetModel(20531, new WidgetPointer(473,50)); + setWidgetText(new WidgetPointer(473,51), "Defender level up to 2"); + setWidgetText(new WidgetPointer(473,53), "Lure range 5"); + setWidgetText(new WidgetPointer(473,52), "200 Defender Honour Points"); + if (bitconfig_3263 > 199) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,52)); + } + } else if (bitconfig_3253 == 2) { + setWidgetModel(20532, new WidgetPointer(473,50)); + setWidgetText(new WidgetPointer(473,51), "Defender level up to 3"); + setWidgetText(new WidgetPointer(473,53), "Lure range 6"); + setWidgetText(new WidgetPointer(473,52), "300 Defender Honour Points"); + if (bitconfig_3263 > 299) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,52)); + } + } else if (bitconfig_3253 == 3) { + setWidgetModel(20533, new WidgetPointer(473,50)); + setWidgetText(new WidgetPointer(473,51), "Defender level up to 4"); + setWidgetText(new WidgetPointer(473,53), "Lure range 8"); + setWidgetText(new WidgetPointer(473,52), "400 Defender Honour Points"); + if (bitconfig_3263 > 399) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,52)); + } + } else if (bitconfig_3253 == 4) { + setWidgetModel(20534, new WidgetPointer(473,50)); + setWidgetText(new WidgetPointer(473,51), "Defender level up to 5"); + setWidgetText(new WidgetPointer(473,53), "Lure range 10"); + setWidgetText(new WidgetPointer(473,52), "500 Defender Honour Points"); + if (bitconfig_3263 > 499) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,52)); + } + } else if (bitconfig_3253 == 5) { + setWidgetModel(20534, new WidgetPointer(473,50)); + setWidgetText(new WidgetPointer(473,51), "Defender level up complete"); + setWidgetText(new WidgetPointer(473,53), " - Mastered - "); + setWidgetText(new WidgetPointer(473,52), " - Mastered - "); + } else { + bitconfig_3253 = 1; + setWidgetModel(20531, new WidgetPointer(473,50)); + setWidgetText(new WidgetPointer(473,51), "Defender level up to 2"); + setWidgetText(new WidgetPointer(473,53), "Lure range 5"); + setWidgetText(new WidgetPointer(473,52), "200 Defender Honour Points"); + if (bitconfig_3263 > 199) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,52)); + } + } + if (((boolean)bitconfig_3254)) { + setWidgetModel(20526, new WidgetPointer(473,57)); + setWidgetText(new WidgetPointer(473,58), "Collector level up to 2"); + setWidgetText(new WidgetPointer(473,60), "Egg conversion"); + setWidgetText(new WidgetPointer(473,59), "200 Collector Honour Points"); + if (bitconfig_3261 > 199) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,59)); + } + } else if (bitconfig_3254 == 2) { + setWidgetModel(20527, new WidgetPointer(473,57)); + setWidgetText(new WidgetPointer(473,58), "Collector level up to 3"); + setWidgetText(new WidgetPointer(473,60), "Egg convert success (80%)"); + setWidgetText(new WidgetPointer(473,59), "300 Collector Honour Points"); + if (bitconfig_3261 > 299) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,59)); + } + } else if (bitconfig_3254 == 3) { + setWidgetModel(20528, new WidgetPointer(473,57)); + setWidgetText(new WidgetPointer(473,58), "Collector level up to 4"); + setWidgetText(new WidgetPointer(473,60), "Egg convert success (90%)"); + setWidgetText(new WidgetPointer(473,59), "400 Collector Honour Points"); + if (bitconfig_3261 > 399) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,59)); + } + } else if (bitconfig_3254 == 4) { + setWidgetModel(20529, new WidgetPointer(473,57)); + setWidgetText(new WidgetPointer(473,58), "Collector level up to 5"); + setWidgetText(new WidgetPointer(473,60), "Egg convert success (100%)"); + setWidgetText(new WidgetPointer(473,59), "500 Collector Honour Points"); + if (bitconfig_3261 > 499) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,59)); + } + } else if (bitconfig_3254 == 5) { + setWidgetModel(20529, new WidgetPointer(473,57)); + setWidgetText(new WidgetPointer(473,58), "Collector level up complete"); + setWidgetText(new WidgetPointer(473,60), " - Mastered - "); + setWidgetText(new WidgetPointer(473,59), " - Mastered - "); + } else { + bitconfig_3254 = 1; + setWidgetModel(20526, new WidgetPointer(473,57)); + setWidgetText(new WidgetPointer(473,58), "Collector level up to 2"); + setWidgetText(new WidgetPointer(473,60), "Egg conversion"); + setWidgetText(new WidgetPointer(473,59), "200 Collector Honour Points"); + if (bitconfig_3261 > 199) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,59)); + } + } + if (((boolean)bitconfig_3255)) { + setWidgetModel(20538, new WidgetPointer(473,64)); + setWidgetText(new WidgetPointer(473,65), "Healer level up to 2"); + setWidgetText(new WidgetPointer(473,67), "Heal 150 points, more run energy"); + setWidgetText(new WidgetPointer(473,66), "200 Healer Honour Points"); + if (bitconfig_3262 > 199) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,66)); + } + } else if (bitconfig_3255 == 2) { + setWidgetModel(20539, new WidgetPointer(473,64)); + setWidgetText(new WidgetPointer(473,65), "Healer level up to 3"); + setWidgetText(new WidgetPointer(473,67), "Heal 200 points, more run energy"); + setWidgetText(new WidgetPointer(473,66), "300 Healer Honour Points"); + if (bitconfig_3262 > 299) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,66)); + } + } else if (bitconfig_3255 == 3) { + setWidgetModel(20540, new WidgetPointer(473,64)); + setWidgetText(new WidgetPointer(473,65), "Healer level up to 4"); + setWidgetText(new WidgetPointer(473,67), "Heal 250 points, more run energy"); + setWidgetText(new WidgetPointer(473,66), "400 Healer Honour Points"); + if (bitconfig_3262 > 399) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,66)); + } + } else if (bitconfig_3255 == 4) { + setWidgetModel(20541, new WidgetPointer(473,64)); + setWidgetText(new WidgetPointer(473,65), "Healer level up to 5"); + setWidgetText(new WidgetPointer(473,67), "Heal 350 points, more run energy"); + setWidgetText(new WidgetPointer(473,66), "500 Healer Honour Points"); + if (bitconfig_3262 > 499) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,66)); + } + } else if (bitconfig_3255 == 5) { + setWidgetModel(20541, new WidgetPointer(473,64)); + setWidgetText(new WidgetPointer(473,65), "Healer level up complete"); + setWidgetText(new WidgetPointer(473,67), " - Mastered - "); + setWidgetText(new WidgetPointer(473,66), " - Mastered - "); + } else { + bitconfig_3255 = 1; + setWidgetModel(20538, new WidgetPointer(473,64)); + setWidgetText(new WidgetPointer(473,65), "Healer level up to 2"); + setWidgetText(new WidgetPointer(473,67), "Heal 150 points and even more run energy"); + setWidgetText(new WidgetPointer(473,66), "200 Healer Honour Points"); + if (bitconfig_3262 > 199) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,66)); + } + } + if (((bitconfig_3256 > 274) && (bitconfig_3263 > 274)) && ((bitconfig_3261 > 274) && (bitconfig_3262 > 274))) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,128)); + } + if (((bitconfig_3256 > 274) && (bitconfig_3263 > 274)) && ((bitconfig_3261 > 274) && (bitconfig_3262 > 274))) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,121)); + } + if (((bitconfig_3256 > 274) && (bitconfig_3263 > 274)) && ((bitconfig_3261 > 274) && (bitconfig_3262 > 274))) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,114)); + } + if (((bitconfig_3256 > 274) && (bitconfig_3263 > 274)) && ((bitconfig_3261 > 274) && (bitconfig_3262 > 274))) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,107)); + } + if (((bitconfig_3256 > 374) && (bitconfig_3263 > 374)) && ((bitconfig_3261 > 374) && (bitconfig_3262 > 374))) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,100)); + } + if (((bitconfig_3256 > 374) && (bitconfig_3263 > 374)) && ((bitconfig_3261 > 374) && (bitconfig_3262 > 374))) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,93)); + } + if (((bitconfig_3256 > 99) && (bitconfig_3263 > 99)) && ((bitconfig_3261 > 99) && (bitconfig_3262 > 99))) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,87)); + } + if (((bitconfig_3256 > 149) && (bitconfig_3263 > 149)) && ((bitconfig_3261 > 149) && (bitconfig_3262 > 149))) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,81)); + } + if (getItemAmtInContainer(93, 995) > 94999) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,212)); + } + if (((boolean)bitconfig_3245)) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,95)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,102)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,109)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,116)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,123)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,130)); + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,214)); + } + if ((((bitconfig_3256 > 9) || (bitconfig_3263 > 9)) || (bitconfig_3261 > 9)) || (bitconfig_3262 > 9)) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,206)); + } + if ((((bitconfig_3256 > 19) || (bitconfig_3263 > 19)) || (bitconfig_3261 > 19)) || (bitconfig_3262 > 19)) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,200)); + } + if ((((bitconfig_3256 > 29) || (bitconfig_3263 > 29)) || (bitconfig_3261 > 29)) || (bitconfig_3262 > 29)) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,194)); + } + if ((((getItemAmtInContainer(93, 15439) < 1) && (getItemAmtInContainer(95, 15439) < 1)) && ((getItemAmtInContainer(94, 15439) < 1) && (getItemAmtInContainer(530, 15439) < 1))) && (((getItemAmtInContainer(93, 15440) < 1) && (getItemAmtInContainer(95, 15440) < 1)) && ((getItemAmtInContainer(94, 15440) < 1) && (getItemAmtInContainer(530, 15440) < 1)))) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,219)); + } + if ((((bitconfig_3251 == 5) || (bitconfig_3253 == 5)) || (bitconfig_3254 == 5)) || (bitconfig_3255 == 5)) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,183)); + } + if ((((getItemAmtInContainer(93, 15440) < 1) && (getItemAmtInContainer(95, 15440) < 1)) && ((getItemAmtInContainer(94, 15440) < 1) && (getItemAmtInContainer(530, 15440) < 1))) && ((((getItemAmtInContainer(93, 15439) > 0) || (getItemAmtInContainer(95, 15439) > 0)) || (getItemAmtInContainer(94, 15439) > 0)) || (getItemAmtInContainer(530, 15439) > 0))) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,184)); + } + if (((bitconfig_3256 > 389) && (bitconfig_3263 > 389)) && ((bitconfig_3261 > 389) && (bitconfig_3262 > 389))) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,146)); + } + if ((getItemAmtInContainer(93, 15438) > 0) || (getItemAmtInContainer(94, 15438) > 0)) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,140)); + } + ivar0 = 0; + if ((getItemAmtInContainer(93, 4151) > 0) || (getItemAmtInContainer(93, 11235) > 0)) { + ivar0 = 1; + } + if (((boolean)bitconfig_7342)) { + if ((((bitconfig_3256 > 49) || (bitconfig_3263 > 49)) || (bitconfig_3261 > 49)) || (bitconfig_3262 > 49)) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,162)); + } + } else { + if (((boolean)ivar0)) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,162)); + } + } + if (((boolean)bitconfig_7344)) { + if ((((bitconfig_3256 > 49) || (bitconfig_3263 > 49)) || (bitconfig_3261 > 49)) || (bitconfig_3262 > 49)) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,156)); + } + } else { + if (((boolean)ivar0)) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,156)); + } + } + if (((boolean)bitconfig_7341)) { + if ((((bitconfig_3256 > 49) || (bitconfig_3263 > 49)) || (bitconfig_3261 > 49)) || (bitconfig_3262 > 49)) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,174)); + } + } else { + if (((boolean)ivar0)) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,174)); + } + } + if (((boolean)bitconfig_7343)) { + if ((((bitconfig_3256 > 49) || (bitconfig_3263 > 49)) || (bitconfig_3261 > 49)) || (bitconfig_3262 > 49)) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,168)); + } + } else { + if (((boolean)ivar0)) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(473,168)); + } + } + if (((boolean)bitconfig_7342)) { + setWidgetText(new WidgetPointer(473,162), "Carrying a valid weapon"); + setWidgetText(new WidgetPointer(473,161), "Use Penance Egg Paint (White)"); + } + if (((boolean)bitconfig_7344)) { + setWidgetText(new WidgetPointer(473,156), "Carrying a valid weapon"); + setWidgetText(new WidgetPointer(473,155), "Use Penance Egg Paint (Green)"); + } + if (((boolean)bitconfig_7343)) { + setWidgetText(new WidgetPointer(473,168), "Carrying a valid weapon"); + setWidgetText(new WidgetPointer(473,167), "Use Penance Egg Paint (Blue)"); + } + if (((boolean)bitconfig_7341)) { + setWidgetText(new WidgetPointer(473,174), "Carrying a valid weapon"); + setWidgetText(new WidgetPointer(473,173), "Use Penance Egg Paint (Yellow)"); + } + setItemOnWidgetMethod2200(10534, -1, new WidgetPointer(473,172)); + setItemOnWidgetMethod2200(10531, -1, new WidgetPointer(473,154)); + setItemOnWidgetMethod2200(15705, -1, new WidgetPointer(473,160)); + setItemOnWidgetMethod2200(10533, -1, new WidgetPointer(473,166)); + setWidgetText(new WidgetPointer(473,9), intToStr(bitconfig_3256)); + setWidgetText(new WidgetPointer(473,10), intToStr(bitconfig_3263)); + setWidgetText(new WidgetPointer(473,11), intToStr(bitconfig_3261)); + setWidgetText(new WidgetPointer(473,12), intToStr(bitconfig_3262)); + return; +} diff --git a/dumps/scripts/2846.cs2 b/dumps/scripts/2846.cs2 new file mode 100644 index 0000000..c3ee91e --- /dev/null +++ b/dumps/scripts/2846.cs2 @@ -0,0 +1,57 @@ +void script_2846(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + deleteAllExtraChilds(new WidgetPointer(arg0)); + ivar1 = 308; + ivar2 = 55; + ivar3 = 0; + ivar4 = getCommonDefinitionSize(903); + while (ivar3 < ivar4) { + createExtraChild(new WidgetPointer(arg0), 6, ivar3); + setWidgetSize(50, 50, 0, 0); + setWidgetPosition(ivar1, ivar2, 0, 0); + setWidgetModel(cs2method_3408(105, 109, 903, ivar3)); + setWidget3DRotation(0, 0, 512, 0, 0, 2750); + setScriptCallOnMouseDragReleased(2848, new WidgetPointer(-32768,3), -2147483643, new WidgetPointer(-32768,6), -2147483641, -2147483647, -2147483646, "IiIiii"); + cs2method1302(2); + cs2method1303(14); + setWidgetContextMenuOption(1, "Select"); + ivar3 = add(ivar3, 1); + if (ivar3 == 3) { + ivar1 = add(308, 48); + ivar2 = 55; + } else if (ivar3 == 6) { + ivar1 = add(308, 96); + ivar2 = 55; + } else { + ivar2 = add(48, ivar2); + } + } + ivar1 = 113; + ivar2 = 83; + ivar4 = getCommonDefinitionSize(904); + ivar4 = add(ivar4, ivar3); + ivar5 = 0; + while (ivar3 < ivar4) { + createExtraChild(new WidgetPointer(arg0), 3, ivar3); + setWidgetSize(50, 50, 0, 0); + setWidgetPosition(ivar1, ivar2, 0, 0); + cs2method2103(255); + ivar3 = add(ivar3, 1); + ivar5 = add(ivar5, 1); + if (ivar5 == 3) { + ivar1 = 113; + ivar2 = add(83, 52); + } else if (ivar5 == 6) { + ivar1 = 113; + ivar2 = add(83, 104); + } else { + ivar1 = add(50, ivar1); + } + } + script_2847(arg0); + return; +} diff --git a/dumps/scripts/2847.cs2 b/dumps/scripts/2847.cs2 new file mode 100644 index 0000000..5f1149a --- /dev/null +++ b/dumps/scripts/2847.cs2 @@ -0,0 +1,36 @@ +void script_2847(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + ivar1 = 308; + ivar2 = 55; + ivar3 = 0; + ivar4 = getCommonDefinitionSize(903); + globalarray_0 = new int[ivar4]; + globalarray_0[0] = 5; + globalarray_0[1] = 8; + globalarray_0[2] = 2; + globalarray_0[3] = 0; + globalarray_0[4] = 4; + globalarray_0[5] = 1; + globalarray_0[6] = 3; + globalarray_0[7] = 7; + globalarray_0[8] = 6; + while (ivar3 < ivar4) { + if (setWidgetRegister(new WidgetPointer(arg0), globalarray_0[ivar3])) { + setWidgetPosition(ivar1, ivar2, 0, 0); + } + ivar3 = add(ivar3, 1); + if (ivar3 == 3) { + ivar1 = add(308, 48); + ivar2 = 55; + } else if (ivar3 == 6) { + ivar1 = add(308, 96); + ivar2 = 55; + } else { + ivar2 = add(48, ivar2); + } + } + return; +} diff --git a/dumps/scripts/2848.cs2 b/dumps/scripts/2848.cs2 new file mode 100644 index 0000000..0735b67 --- /dev/null +++ b/dumps/scripts/2848.cs2 @@ -0,0 +1,41 @@ +void script_2848(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + int ivar6; + int ivar7; + ivar6 = 0; + ivar7 = 0; + if (arg2 != -1) { + if (arg3 == -1) { + if (setWidgetRegister(new WidgetPointer(arg2)) && (arg2 == 31064075)) { + ivar6 = arg4; + ivar7 = arg5; + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetPosition(cs2method_3408(105, 105, 905, arg1), cs2method_3408(105, 105, 906, arg1), 0, 0); + } + } + } else { + if (arg3 < 9) { + return; + } + if (((boolean)script_2849(subtract(arg3, 9)))) { + if (setWidgetRegister(new WidgetPointer(arg2), arg3)) { + ivar6 = getWidgetActualX(); + ivar7 = getWidgetActualY(); + } + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + switch (rnd(2)) { + case 0: + playSoundEffect(8502, 1, 0); + break; + case 1: + playSoundEffect(8518, 1, 0); + break; + case 2: + playSoundEffect(8515, 1, 0); + } + setWidgetPosition(ivar6, ivar7, 0, 0); + } + } + } + } + return; +} diff --git a/dumps/scripts/2849.cs2 b/dumps/scripts/2849.cs2 new file mode 100644 index 0000000..3577b51 --- /dev/null +++ b/dumps/scripts/2849.cs2 @@ -0,0 +1,23 @@ +int script_2849(int arg0) { + switch (arg0) { + case 0: + return bitconfig_7060; + case 1: + return bitconfig_7061; + case 2: + return bitconfig_7062; + case 3: + return bitconfig_7063; + case 4: + return bitconfig_7064; + case 5: + return bitconfig_7065; + case 6: + return bitconfig_7066; + case 7: + return bitconfig_7067; + case 8: + return bitconfig_7068; + } + return 0; +} diff --git a/dumps/scripts/285.cs2 b/dumps/scripts/285.cs2 new file mode 100644 index 0000000..7458986 --- /dev/null +++ b/dumps/scripts/285.cs2 @@ -0,0 +1,226 @@ +int script_285(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + string svar0; + string svar1; + string svar2; + script_41(49479737); + ivar2 = 1; + ivar3 = -1; + svar0 = "Hide"; + svar1 = "Show"; + svar2 = "`You are here'"; + if (((boolean)bitconfig_6174)) { + svar0 = "Show"; + svar1 = "Hide"; + ivar2 = 0; + } + createExtraChild(new WidgetPointer(arg0), 5, 0); + createExtraChild(new WidgetPointer(arg0), 4, 1); + setWidgetPosition(-1, arg1, 0, 0); + setWidgetSize(26, 26, 0, 0); + setWidgetPosition(subtract(add(getWidgetActualX(), getWidgetActualWidth()), 1), arg1, 0, 0); + setWidgetSize(getWidgetActualX(), getWidgetActualHeight(), 1, 0); + ivar4 = getWidgetActualWidth(); + setWidgetSprite(getOtherCommonData(280, 130)); + setWidgetRGB(new Color(175, 175, 175)); + setWidgetFont(495); + setWidgetUnknownBoolean(true); + setWidgetTextAlignment(0, 1, 0); + setWidgetText(svar2); + cs2method1305("" + svar2 + ""); + cs2method1305("" + svar2 + ""); + setWidgetContextMenuOption(1, svar0); + setWidgetContextMenuOption(1, svar0); + svar2 = "Toggles the " + "" + "You are here" + "" + " marker."; + setScriptCallOnMouseEntered(1356, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), 16777215, "Iii"); + setScriptCallOnMouseEntered(1356, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), 16777215, "Iii"); + setScriptCallOnMouseOver(310, svar2, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), "sIi"); + setScriptCallOnMouseOver(310, svar2, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), "sIi"); + setScriptCallOnMouseExit(289, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), 11513775, "Iii"); + setScriptCallOnMouseExit(289, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), 11513775, "Iii"); + setScriptCallOnClickContextMenu(286, -2147483644, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), getWidgetCustomChildArrayIndex(), 2, svar1, ivar2, "iIiiis1"); + setScriptCallOnClickContextMenu(286, -2147483644, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), getWidgetCustomChildArrayIndex(), 2, svar1, ivar2, "iIiiis1"); + script_287(2, ivar2, arg0, arg1); + arg1 = add(arg1, getWidgetActualHeight()); + svar2 = "Intra-map links"; + if (((boolean)bitconfig_6175)) { + svar0 = "Show"; + svar1 = "Hide"; + ivar2 = 0; + } else { + svar0 = "Hide"; + svar1 = "Show"; + ivar2 = 1; + } + createExtraChild(new WidgetPointer(arg0), 5, 3); + createExtraChild(new WidgetPointer(arg0), 4, 4); + setWidgetPosition(3, arg1, 0, 0); + setWidgetSize(22, 26, 0, 0); + setWidgetPosition(add(getWidgetActualX(), getWidgetActualWidth()), arg1, 0, 0); + setWidgetSize(add(getWidgetActualX(), getWidgetActualX()), getWidgetActualHeight(), 1, 0); + setWidgetRGB(new Color(175, 175, 175)); + setWidgetFont(495); + setWidgetUnknownBoolean(true); + setWidgetTextAlignment(0, 1, 0); + setWidgetText(svar2); + cs2method1305("" + svar2 + ""); + cs2method1305("" + svar2 + ""); + setWidgetContextMenuOption(1, svar0); + setWidgetContextMenuOption(1, svar0); + svar2 = "Toggles the features that show links within a map."; + setScriptCallOnMouseEntered(1356, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), 16777215, "Iii"); + setScriptCallOnMouseEntered(1356, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), 16777215, "Iii"); + setScriptCallOnMouseOver(310, svar2, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), "sIi"); + setScriptCallOnMouseOver(310, svar2, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), "sIi"); + setScriptCallOnMouseExit(289, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), 11513775, "Iii"); + setScriptCallOnMouseExit(289, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), 11513775, "Iii"); + setScriptCallOnClickContextMenu(286, -2147483644, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), getWidgetCustomChildArrayIndex(), 10, svar1, ivar2, "iIiiis1"); + setScriptCallOnClickContextMenu(286, -2147483644, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), getWidgetCustomChildArrayIndex(), 10, svar1, ivar2, "iIiiis1"); + createExtraChild(new WidgetPointer(arg0), 3, 5); + setWidgetPosition(4, add(arg1, 12), 0, 0); + setWidgetSize(5, 5, 0, 0); + setWidgetRGB(new Color(0, 0, 0)); + setWidgetFilled(1); + createExtraChild(new WidgetPointer(arg0), 3, 6); + setWidgetPosition(17, add(arg1, 12), 0, 0); + setWidgetSize(5, 5, 0, 0); + setWidgetRGB(new Color(0, 0, 0)); + setWidgetFilled(1); + createExtraChild(new WidgetPointer(arg0), 3, 7); + setWidgetPosition(3, add(arg1, 11), 0, 0); + setWidgetSize(5, 5, 0, 0); + setWidgetRGB(new Color(255, 255, 0)); + setWidgetFilled(1); + createExtraChild(new WidgetPointer(arg0), 3, 8); + setWidgetPosition(16, add(arg1, 11), 0, 0); + setWidgetSize(5, 5, 0, 0); + setWidgetRGB(new Color(255, 255, 0)); + setWidgetFilled(1); + createExtraChild(new WidgetPointer(arg0), 9, 9); + setWidgetPosition(5, add(arg1, 13), 0, 0); + setWidgetSize(15, 0, 0, 0); + cs2method1104(2); + setWidgetRGB(new Color(255, 255, 0)); + script_287(10, ivar2, arg0, arg1); + arg1 = add(arg1, getWidgetActualHeight()); + svar2 = "Map labels"; + if (((boolean)bitconfig_6176)) { + svar0 = "Show"; + svar1 = "Hide"; + ivar2 = 0; + } else { + svar0 = "Hide"; + svar1 = "Show"; + ivar2 = 1; + } + createExtraChild(new WidgetPointer(arg0), 4, 11); + setWidgetPosition(1, arg1, 0, 0); + setWidgetSize(23, 26, 0, 0); + setWidgetFont(494); + setWidgetTextAlignment(1, 1, 0); + setWidgetUnknownBoolean(true); + setWidgetRGB(new Color(255, 255, 255)); + setWidgetText("ABC" + "
" + "XYZ"); + createExtraChild(new WidgetPointer(arg0), 4, 12); + setWidgetPosition(add(getWidgetActualX(), getWidgetActualWidth()), arg1, 0, 0); + setWidgetSize(add(getWidgetActualX(), getWidgetActualX()), getWidgetActualHeight(), 1, 0); + setWidgetRGB(new Color(175, 175, 175)); + setWidgetFont(495); + setWidgetUnknownBoolean(true); + setWidgetTextAlignment(0, 1, 0); + setWidgetText(svar2); + cs2method1305("" + svar2 + ""); + cs2method1305("" + svar2 + ""); + setWidgetContextMenuOption(1, svar0); + setWidgetContextMenuOption(1, svar0); + svar2 = "Toggles most text labels." + "
" + "Some are always shown."; + setScriptCallOnMouseEntered(1356, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), 16777215, "Iii"); + setScriptCallOnMouseEntered(1356, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), 16777215, "Iii"); + setScriptCallOnMouseOver(310, svar2, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), "sIi"); + setScriptCallOnMouseOver(310, svar2, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), "sIi"); + setScriptCallOnMouseExit(289, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), 11513775, "Iii"); + setScriptCallOnMouseExit(289, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), 11513775, "Iii"); + setScriptCallOnClickContextMenu(286, -2147483644, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), getWidgetCustomChildArrayIndex(), 13, svar1, ivar2, "iIiiis1"); + setScriptCallOnClickContextMenu(286, -2147483644, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), getWidgetCustomChildArrayIndex(), 13, svar1, ivar2, "iIiiis1"); + script_287(13, ivar2, arg0, arg1); + arg1 = add(arg1, getWidgetActualHeight()); + svar2 = "Icon tooltips"; + if (((boolean)bitconfig_6177)) { + svar0 = "Show"; + svar1 = "Hide"; + ivar2 = 0; + } else { + svar0 = "Hide"; + svar1 = "Show"; + ivar2 = 1; + } + createExtraChild(new WidgetPointer(arg0), 3, 14); + setWidgetPosition(3, add(arg1, 6), 0, 0); + setWidgetSize(20, 14, 0, 0); + setWidgetFilled(1); + setWidgetRGB(new Color(255, 255, 160)); + createExtraChild(new WidgetPointer(arg0), 3, 15); + setWidgetPosition(3, add(arg1, 6), 0, 0); + setWidgetSize(getWidgetActualWidth(), getWidgetActualHeight(), 0, 0); + setWidgetFilled(0); + setWidgetRGB(new Color(1, 1, 1)); + createExtraChild(new WidgetPointer(arg0), 4, 16); + setWidgetPosition(add(add(getWidgetActualX(), getWidgetActualWidth()), 2), arg1, 0, 0); + setWidgetSize(add(getWidgetActualX(), getWidgetActualX()), 26, 1, 0); + setWidgetRGB(new Color(175, 175, 175)); + setWidgetFont(495); + setWidgetUnknownBoolean(true); + setWidgetTextAlignment(0, 1, 0); + setWidgetText(svar2); + cs2method1305("" + svar2 + ""); + cs2method1305("" + svar2 + ""); + setWidgetContextMenuOption(1, svar0); + setWidgetContextMenuOption(1, svar0); + svar2 = "Toggles icon tooltips."; + setScriptCallOnMouseEntered(1356, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), 16777215, "Iii"); + setScriptCallOnMouseEntered(1356, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), 16777215, "Iii"); + setScriptCallOnMouseOver(310, svar2, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), "sIi"); + setScriptCallOnMouseOver(310, svar2, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), "sIi"); + setScriptCallOnMouseExit(289, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), 11513775, "Iii"); + setScriptCallOnMouseExit(289, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), 11513775, "Iii"); + setScriptCallOnClickContextMenu(286, -2147483644, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), getWidgetCustomChildArrayIndex(), 17, svar1, ivar2, "iIiiis1"); + setScriptCallOnClickContextMenu(286, -2147483644, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), getWidgetCustomChildArrayIndex(), 17, svar1, ivar2, "iIiiis1"); + script_287(17, ivar2, arg0, arg1); + arg1 = add(arg1, getWidgetActualHeight()); + createExtraChild(new WidgetPointer(arg0), 5, 18); + setWidgetSize(26, 26, 0, 0); + svar2 = "Double-click the map to set a marker"; + ivar5 = max(add(multiply(getLineCount(ivar4, 494, svar2), 10), 3), getWidgetActualHeight()); + setWidgetPosition(-1, add(arg1, divide(subtract(ivar5, getWidgetActualHeight()), 2)), 0, 0); + setWidgetSprite(getOtherCommonData(972, 130)); + createExtraChild(new WidgetPointer(arg0), 4, 19); + setWidgetPosition(0, arg1, 2, 0); + setWidgetSize(ivar4, ivar5, 0, 0); + setWidgetRGB(new Color(175, 175, 175)); + setWidgetUnknownBoolean(true); + if ((standart_config_1159 == -1) || ((boolean)standart_config_1159)) { + setWidgetTextAlignment(1, 1, 0); + setWidgetFont(494); + setWidgetText(svar2); + } else { + svar2 = "Clear your marker"; + setWidgetTextAlignment(0, 1, 0); + setWidgetFont(495); + setWidgetText(svar2); + setWidgetContextMenuOption(1, svar2); + setWidgetContextMenuOption(1, svar2); + svar2 = "Removes the marker."; + setScriptCallOnMouseEntered(1356, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), 16777215, "Iii"); + setScriptCallOnMouseEntered(1356, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), 16777215, "Iii"); + setScriptCallOnMouseOver(310, svar2, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), "sIi"); + setScriptCallOnMouseOver(310, svar2, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), "sIi"); + setScriptCallOnMouseExit(289, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), 11513775, "Iii"); + setScriptCallOnMouseExit(289, new WidgetPointer(arg0), getWidgetCustomChildArrayIndex(), 11513775, "Iii"); + setScriptCallOnClickContextMenu(286, -2147483644, new WidgetPointer(arg0), -1, -1, -1, "", 0, "iIiiis1"); + setScriptCallOnClickContextMenu(286, -2147483644, new WidgetPointer(arg0), -1, -1, -1, "", 0, "iIiiis1"); + } + return add(arg1, getWidgetActualHeight()); +} diff --git a/dumps/scripts/2850.cs2 b/dumps/scripts/2850.cs2 new file mode 100644 index 0000000..023304c --- /dev/null +++ b/dumps/scripts/2850.cs2 @@ -0,0 +1,26 @@ +void script_2850() { + globalint_1069 = 500; + globalint_1070 = addToCoordinate(getMyPositionHash(), 0, 0, -8); + globalint_1071 = 0; + globalint_1072 = getMyPositionHash(); + globalint_1073 = 450; + globalint_1074 = 0; + globalint_1282 = 25; + cameraMoveTo(globalint_1070, globalint_1069, 10, 3); + cameraPointAt(script_2865(globalint_1070, globalint_1071), globalint_1073, 10, 3); + globalint_1075 = 0; + globalint_1076 = 0; + setScriptCallOnKeyPress(2851, new WidgetPointer(-32768,3), -2147483640, 0, "Iii", new WidgetPointer(475,1)); + setWidgetIsHidden(false, new WidgetPointer(475,54)); + setWidgetIsHidden(false, new WidgetPointer(475,7)); + setWidgetIsHidden(false, new WidgetPointer(475,58)); + setWidgetIsHidden(true, new WidgetPointer(475,33)); + setWidgetSprite(1232, new WidgetPointer(475,28)); + setWidgetText(new WidgetPointer(475,29), "You are now in Aim Mode"); + setScriptCallOnGameloop(2853, new WidgetPointer(475,1), getClientCycle(), "Ii", new WidgetPointer(475,1)); + setScriptCallOnGameloop(2852, new WidgetPointer(475,7), "I", new WidgetPointer(475,7)); + setWidgetIsHidden(false, new WidgetPointer(475,2)); + setScriptCallOnGameloop(2870, new WidgetPointer(-32768,3), add(getClientCycle(), 150), "Ii", new WidgetPointer(475,2)); + script_3455(); + return; +} diff --git a/dumps/scripts/2851.cs2 b/dumps/scripts/2851.cs2 new file mode 100644 index 0000000..6c8a84d --- /dev/null +++ b/dumps/scripts/2851.cs2 @@ -0,0 +1,279 @@ +void script_2851(int arg0,int arg1,int arg2) { + if (isWidgetHidden(new WidgetPointer(475,55))) { + if (arg1 == 2) { + script_835(1); + } + return; + } + if ((getClientCycle() > add(arg2, 5)) || (globalint_1074 == 2)) { + switch (getLanguage()) { + case 2: + switch (arg1) { + case 2: + script_835(0); + break; + case 6: + script_3455(); + break; + case 7: + script_3453(); + break; + case 8: + script_3456(); + break; + case 34: + script_2858(); + break; + case 35: + script_2854(); + break; + case 36: + script_2859(); + break; + case 50: + script_2857(); + break; + case 51: + script_2855(); + break; + case 52: + script_2856(); + break; + case 98: + script_2860(); + break; + case 99: + script_2861(); + break; + case 96: + script_2863(); + break; + case 97: + script_2862(); + break; + case 13: + script_675(); + break; + case 1: + script_3455(); + if (((boolean)globalint_1074)) { + globalint_1074 = 1; + setWidgetSprite(1233, new WidgetPointer(475,28)); + setWidgetText(new WidgetPointer(475,29), "You are now in Focus Mode"); + if (isWidgetHidden(new WidgetPointer(475,54))) { + setWidgetIsHidden(true, new WidgetPointer(475,54)); + setWidgetIsHidden(false, new WidgetPointer(475,33)); + setWidgetIsHidden(true, new WidgetPointer(475,100)); + setWidgetIsHidden(false, new WidgetPointer(475,58)); + } + } else if (globalint_1074 == 2) { + globalint_1074 = 0; + setWidgetSprite(1232, new WidgetPointer(475,28)); + setWidgetText(new WidgetPointer(475,29), "You are now in Aim Mode"); + if (isWidgetHidden(new WidgetPointer(475,100))) { + setWidgetIsHidden(true, new WidgetPointer(475,33)); + setWidgetIsHidden(false, new WidgetPointer(475,54)); + setWidgetIsHidden(true, new WidgetPointer(475,100)); + setWidgetIsHidden(false, new WidgetPointer(475,58)); + } + } else { + globalint_1074 = 2; + setWidgetSprite(1231, new WidgetPointer(475,28)); + setWidgetText(new WidgetPointer(475,29), "You are now in Fine Control Mode"); + if (isWidgetHidden(new WidgetPointer(475,33))) { + setWidgetIsHidden(true, new WidgetPointer(475,33)); + setWidgetIsHidden(true, new WidgetPointer(475,54)); + setWidgetIsHidden(false, new WidgetPointer(475,100)); + setWidgetIsHidden(true, new WidgetPointer(475,58)); + } + } + setScriptCallOnGameloop(2853, new WidgetPointer(arg0), getClientCycle(), "Ii", new WidgetPointer(arg0)); + break; + case 83: + if (((boolean)globalint_1074)) { + if (isWidgetHidden(new WidgetPointer(475,54))) { + setWidgetIsHidden(false, new WidgetPointer(475,54)); + setWidgetIsHidden(true, new WidgetPointer(475,33)); + setWidgetIsHidden(true, new WidgetPointer(475,100)); + setWidgetIsHidden(false, new WidgetPointer(475,7)); + setWidgetIsHidden(false, new WidgetPointer(475,58)); + } else { + setWidgetIsHidden(true, new WidgetPointer(475,54)); + setWidgetIsHidden(true, new WidgetPointer(475,33)); + setWidgetIsHidden(true, new WidgetPointer(475,100)); + setWidgetIsHidden(true, new WidgetPointer(475,7)); + setWidgetIsHidden(true, new WidgetPointer(475,58)); + } + } else if (((boolean)globalint_1074)) { + if (isWidgetHidden(new WidgetPointer(475,33))) { + setWidgetIsHidden(true, new WidgetPointer(475,54)); + setWidgetIsHidden(false, new WidgetPointer(475,33)); + setWidgetIsHidden(true, new WidgetPointer(475,100)); + setWidgetIsHidden(false, new WidgetPointer(475,7)); + setWidgetIsHidden(false, new WidgetPointer(475,58)); + } else { + setWidgetIsHidden(true, new WidgetPointer(475,54)); + setWidgetIsHidden(true, new WidgetPointer(475,33)); + setWidgetIsHidden(true, new WidgetPointer(475,100)); + setWidgetIsHidden(true, new WidgetPointer(475,7)); + setWidgetIsHidden(true, new WidgetPointer(475,58)); + } + } else { + if (globalint_1074 == 2) { + if (isWidgetHidden(new WidgetPointer(475,100))) { + setWidgetIsHidden(true, new WidgetPointer(475,54)); + setWidgetIsHidden(true, new WidgetPointer(475,33)); + setWidgetIsHidden(false, new WidgetPointer(475,100)); + setWidgetIsHidden(false, new WidgetPointer(475,7)); + setWidgetIsHidden(true, new WidgetPointer(475,58)); + } else { + setWidgetIsHidden(true, new WidgetPointer(475,54)); + setWidgetIsHidden(true, new WidgetPointer(475,33)); + setWidgetIsHidden(true, new WidgetPointer(475,100)); + setWidgetIsHidden(true, new WidgetPointer(475,7)); + setWidgetIsHidden(true, new WidgetPointer(475,58)); + } + } + } + break; + default: + return; + } + break; + default: + switch (arg1) { + case 2: + script_835(0); + break; + case 6: + script_3455(); + break; + case 7: + script_3453(); + break; + case 8: + script_3456(); + break; + case 32: + script_2858(); + break; + case 33: + script_2854(); + break; + case 34: + script_2859(); + break; + case 48: + script_2857(); + break; + case 49: + script_2855(); + break; + case 50: + script_2856(); + break; + case 98: + script_2860(); + break; + case 99: + script_2861(); + break; + case 96: + script_2863(); + break; + case 97: + script_2862(); + break; + case 13: + script_675(); + break; + case 1: + script_3455(); + if (((boolean)globalint_1074)) { + globalint_1074 = 1; + setWidgetSprite(1233, new WidgetPointer(475,28)); + setWidgetText(new WidgetPointer(475,29), "You are now in Focus Mode"); + if (isWidgetHidden(new WidgetPointer(475,54))) { + setWidgetIsHidden(true, new WidgetPointer(475,54)); + setWidgetIsHidden(false, new WidgetPointer(475,33)); + setWidgetIsHidden(true, new WidgetPointer(475,100)); + setWidgetIsHidden(false, new WidgetPointer(475,58)); + } + } else if (globalint_1074 == 2) { + globalint_1074 = 0; + setWidgetSprite(1232, new WidgetPointer(475,28)); + setWidgetText(new WidgetPointer(475,29), "You are now in Aim Mode"); + if (isWidgetHidden(new WidgetPointer(475,100))) { + setWidgetIsHidden(true, new WidgetPointer(475,33)); + setWidgetIsHidden(false, new WidgetPointer(475,54)); + setWidgetIsHidden(true, new WidgetPointer(475,100)); + setWidgetIsHidden(false, new WidgetPointer(475,58)); + } + } else { + globalint_1074 = 2; + setWidgetSprite(1231, new WidgetPointer(475,28)); + setWidgetText(new WidgetPointer(475,29), "You are now in Fine Control Mode"); + if (isWidgetHidden(new WidgetPointer(475,33))) { + setWidgetIsHidden(true, new WidgetPointer(475,33)); + setWidgetIsHidden(true, new WidgetPointer(475,54)); + setWidgetIsHidden(false, new WidgetPointer(475,100)); + setWidgetIsHidden(true, new WidgetPointer(475,58)); + } + } + setScriptCallOnGameloop(2853, new WidgetPointer(arg0), getClientCycle(), "Ii", new WidgetPointer(arg0)); + break; + case 83: + if (((boolean)globalint_1074)) { + if (isWidgetHidden(new WidgetPointer(475,54))) { + setWidgetIsHidden(false, new WidgetPointer(475,54)); + setWidgetIsHidden(true, new WidgetPointer(475,33)); + setWidgetIsHidden(true, new WidgetPointer(475,100)); + setWidgetIsHidden(false, new WidgetPointer(475,7)); + setWidgetIsHidden(false, new WidgetPointer(475,58)); + } else { + setWidgetIsHidden(true, new WidgetPointer(475,54)); + setWidgetIsHidden(true, new WidgetPointer(475,33)); + setWidgetIsHidden(true, new WidgetPointer(475,100)); + setWidgetIsHidden(true, new WidgetPointer(475,7)); + setWidgetIsHidden(true, new WidgetPointer(475,58)); + } + } else if (((boolean)globalint_1074)) { + if (isWidgetHidden(new WidgetPointer(475,33))) { + setWidgetIsHidden(true, new WidgetPointer(475,54)); + setWidgetIsHidden(false, new WidgetPointer(475,33)); + setWidgetIsHidden(true, new WidgetPointer(475,100)); + setWidgetIsHidden(false, new WidgetPointer(475,7)); + setWidgetIsHidden(false, new WidgetPointer(475,58)); + } else { + setWidgetIsHidden(true, new WidgetPointer(475,54)); + setWidgetIsHidden(true, new WidgetPointer(475,33)); + setWidgetIsHidden(true, new WidgetPointer(475,100)); + setWidgetIsHidden(true, new WidgetPointer(475,7)); + setWidgetIsHidden(true, new WidgetPointer(475,58)); + } + } else { + if (globalint_1074 == 2) { + if (isWidgetHidden(new WidgetPointer(475,100))) { + setWidgetIsHidden(true, new WidgetPointer(475,54)); + setWidgetIsHidden(true, new WidgetPointer(475,33)); + setWidgetIsHidden(false, new WidgetPointer(475,100)); + setWidgetIsHidden(false, new WidgetPointer(475,7)); + setWidgetIsHidden(true, new WidgetPointer(475,58)); + } else { + setWidgetIsHidden(true, new WidgetPointer(475,54)); + setWidgetIsHidden(true, new WidgetPointer(475,33)); + setWidgetIsHidden(true, new WidgetPointer(475,100)); + setWidgetIsHidden(true, new WidgetPointer(475,7)); + setWidgetIsHidden(true, new WidgetPointer(475,58)); + } + } + } + break; + } + return; + } + script_2864(); + setScriptCallOnKeyPress(2851, new WidgetPointer(arg0), -2147483640, getClientCycle(), "Iii", new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/2852.cs2 b/dumps/scripts/2852.cs2 new file mode 100644 index 0000000..0ac8d19 --- /dev/null +++ b/dumps/scripts/2852.cs2 @@ -0,0 +1,29 @@ +void script_2852(int arg0) { + if ((globalint_1076 < add(globalint_1075, 250)) && (globalint_1076 > subtract(globalint_1075, 250))) { + globalint_1076 = globalint_1075; + } else if (globalint_1076 > globalint_1075) { + if (subtract(globalint_1076, 32768) > globalint_1075) { + globalint_1076 = add(globalint_1076, 250); + if (globalint_1076 > 65535) { + globalint_1076 = subtract(globalint_1076, 63335); + } + } else { + globalint_1076 = subtract(globalint_1076, 250); + if (globalint_1076 < 0) { + globalint_1076 = add(globalint_1076, 63335); + } + } + } else if (add(globalint_1076, 32768) < globalint_1075) { + globalint_1076 = subtract(globalint_1076, 250); + if (globalint_1076 < 0) { + globalint_1076 = add(globalint_1076, 63335); + } + } else { + globalint_1076 = add(globalint_1076, 250); + if (globalint_1076 > 65535) { + globalint_1076 = subtract(globalint_1076, 63335); + } + } + cs2method2106(globalint_1076, new WidgetPointer(475,31)); + return; +} diff --git a/dumps/scripts/2853.cs2 b/dumps/scripts/2853.cs2 new file mode 100644 index 0000000..4ba1b3e --- /dev/null +++ b/dumps/scripts/2853.cs2 @@ -0,0 +1,27 @@ +void script_2853(int arg0,int arg1) { + int ivar2; + int ivar3; + ivar2 = subtract(getClientCycle(), arg1); + ivar3 = 0; + if (ivar2 <= 30) { + if (ivar2 == 5) { + playSoundEffect(2871, 1, 0); + } + ivar3 = subtract(multiply(11, ivar2), 325); + setWidgetPosition(ivar3, 5, 0, 0, new WidgetPointer(475,8)); + return; + } + if (ivar2 < 170) { + return; + } + if (ivar2 < 201) { + if (ivar2 == 5) { + playSoundEffect(2871, 1, 0); + } + ivar3 = subtract(5, multiply(11, subtract(ivar2, 170))); + setWidgetPosition(ivar3, 5, 0, 0, new WidgetPointer(475,8)); + return; + } + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/2854.cs2 b/dumps/scripts/2854.cs2 new file mode 100644 index 0000000..60ac337 --- /dev/null +++ b/dumps/scripts/2854.cs2 @@ -0,0 +1,9 @@ +void script_2854() { + if (((boolean)script_2869(addToCoordinate(globalint_1070, 0, 0, 1)))) { + return; + } + if (script_2866(getMyPositionHash(), addToCoordinate(globalint_1070, 0, 0, 1)) < 31) { + globalint_1070 = addToCoordinate(globalint_1070, 0, 0, 1); + } + return; +} diff --git a/dumps/scripts/2855.cs2 b/dumps/scripts/2855.cs2 new file mode 100644 index 0000000..0466f9d --- /dev/null +++ b/dumps/scripts/2855.cs2 @@ -0,0 +1,9 @@ +void script_2855() { + if (((boolean)script_2869(addToCoordinate(globalint_1070, 0, 0, -1)))) { + return; + } + if (script_2866(getMyPositionHash(), addToCoordinate(globalint_1070, 0, 0, -1)) < 31) { + globalint_1070 = addToCoordinate(globalint_1070, 0, 0, -1); + } + return; +} diff --git a/dumps/scripts/2856.cs2 b/dumps/scripts/2856.cs2 new file mode 100644 index 0000000..131ddeb --- /dev/null +++ b/dumps/scripts/2856.cs2 @@ -0,0 +1,9 @@ +void script_2856() { + if (((boolean)script_2869(addToCoordinate(globalint_1070, 1, 0, 0)))) { + return; + } + if (script_2866(getMyPositionHash(), addToCoordinate(globalint_1070, 1, 0, 0)) < 31) { + globalint_1070 = addToCoordinate(globalint_1070, 1, 0, 0); + } + return; +} diff --git a/dumps/scripts/2857.cs2 b/dumps/scripts/2857.cs2 new file mode 100644 index 0000000..6cb0577 --- /dev/null +++ b/dumps/scripts/2857.cs2 @@ -0,0 +1,9 @@ +void script_2857() { + if (((boolean)script_2869(addToCoordinate(globalint_1070, -1, 0, 0)))) { + return; + } + if (script_2866(getMyPositionHash(), addToCoordinate(globalint_1070, -1, 0, 0)) < 31) { + globalint_1070 = addToCoordinate(globalint_1070, -1, 0, 0); + } + return; +} diff --git a/dumps/scripts/2858.cs2 b/dumps/scripts/2858.cs2 new file mode 100644 index 0000000..0579d65 --- /dev/null +++ b/dumps/scripts/2858.cs2 @@ -0,0 +1,6 @@ +void script_2858() { + if (globalint_1069 < 5000) { + globalint_1069 = add(globalint_1069, 50); + } + return; +} diff --git a/dumps/scripts/2859.cs2 b/dumps/scripts/2859.cs2 new file mode 100644 index 0000000..4bcfc55 --- /dev/null +++ b/dumps/scripts/2859.cs2 @@ -0,0 +1,9 @@ +void script_2859() { + if (globalint_1069 >= 100) { + globalint_1069 = subtract(globalint_1069, 50); + } + if (globalint_1073 > globalint_1069) { + globalint_1073 = globalint_1069; + } + return; +} diff --git a/dumps/scripts/286.cs2 b/dumps/scripts/286.cs2 new file mode 100644 index 0000000..306dd7e --- /dev/null +++ b/dumps/scripts/286.cs2 @@ -0,0 +1,23 @@ +void script_286(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,string arg6) { + if (arg0 != 1) { + return; + } + if (setWidgetRegister(new WidgetPointer(arg1), arg2)) { + setWidgetContextMenuOption(1, arg6); + } + if (setWidgetRegister(new WidgetPointer(arg1), arg3)) { + setWidgetContextMenuOption(1, arg6); + } + if (setWidgetRegister(new WidgetPointer(arg1), arg4)) { + if (((boolean)arg5)) { + setWidgetHidden(0); + } else { + setWidgetHidden(1); + } + } + if (arg2 == 11) { + cs2method5231(950, arg5); + } + playSoundEffect(2266, 1, 0); + return; +} diff --git a/dumps/scripts/2860.cs2 b/dumps/scripts/2860.cs2 new file mode 100644 index 0000000..b543f7b --- /dev/null +++ b/dumps/scripts/2860.cs2 @@ -0,0 +1,13 @@ +void script_2860() { + if (((boolean)globalint_1074)) { + globalint_1073 = add(globalint_1073, 25); + if (globalint_1073 > globalint_1069) { + globalint_1073 = globalint_1069; + } + } else if (((boolean)globalint_1074)) { + globalint_1072 = addToCoordinate(globalint_1072, 0, 0, 1); + } else { + cs2method5507(); + } + return; +} diff --git a/dumps/scripts/2861.cs2 b/dumps/scripts/2861.cs2 new file mode 100644 index 0000000..ac64973 --- /dev/null +++ b/dumps/scripts/2861.cs2 @@ -0,0 +1,13 @@ +void script_2861() { + if (((boolean)globalint_1074)) { + globalint_1073 = subtract(globalint_1073, 25); + if (globalint_1073 <= 25) { + globalint_1073 = 25; + } + } else if (((boolean)globalint_1074)) { + globalint_1072 = addToCoordinate(globalint_1072, 0, 0, -1); + } else { + cs2method5508(); + } + return; +} diff --git a/dumps/scripts/2862.cs2 b/dumps/scripts/2862.cs2 new file mode 100644 index 0000000..86ba434 --- /dev/null +++ b/dumps/scripts/2862.cs2 @@ -0,0 +1,14 @@ +void script_2862() { + if (((boolean)globalint_1074)) { + if (globalint_1071 == 19) { + globalint_1071 = 0; + } else { + globalint_1071 = add(globalint_1071, 1); + } + } else if (((boolean)globalint_1074)) { + globalint_1072 = addToCoordinate(globalint_1072, 1, 0, 0); + } else { + cs2method5509(); + } + return; +} diff --git a/dumps/scripts/2863.cs2 b/dumps/scripts/2863.cs2 new file mode 100644 index 0000000..e6db71c --- /dev/null +++ b/dumps/scripts/2863.cs2 @@ -0,0 +1,14 @@ +void script_2863() { + if (((boolean)globalint_1074)) { + if (((boolean)globalint_1071)) { + globalint_1071 = 19; + } else { + globalint_1071 = subtract(globalint_1071, 1); + } + } else if (((boolean)globalint_1074)) { + globalint_1072 = addToCoordinate(globalint_1072, -1, 0, 0); + } else { + cs2method5510(); + } + return; +} diff --git a/dumps/scripts/2864.cs2 b/dumps/scripts/2864.cs2 new file mode 100644 index 0000000..3eeb1e8 --- /dev/null +++ b/dumps/scripts/2864.cs2 @@ -0,0 +1,21 @@ +void script_2864() { + int ivar0; + ivar0 = 0; + if (((boolean)globalint_1074)) { + cameraPointAt(script_2865(globalint_1070, globalint_1071), globalint_1073, 0, 25); + cameraMoveTo(globalint_1070, globalint_1069, 0, 25); + ivar0 = script_2867(globalint_1070, script_2865(globalint_1070, globalint_1071)); + } else if (((boolean)globalint_1074)) { + cameraMoveTo(globalint_1070, globalint_1069, 20, 3); + cameraPointAt(globalint_1072, 50, 20, 3); + ivar0 = script_2867(globalint_1070, globalint_1072); + } else { + cameraMethod5511(globalint_1070); + } + if (((boolean)ivar0)) { + globalint_1075 = 0; + } else { + globalint_1075 = multiply(subtract(ivar0, 1), 8191); + } + return; +} diff --git a/dumps/scripts/2865.cs2 b/dumps/scripts/2865.cs2 new file mode 100644 index 0000000..d87fc23 --- /dev/null +++ b/dumps/scripts/2865.cs2 @@ -0,0 +1,66 @@ +int script_2865(int arg0,int arg1) { + int ivar2; + ivar2 = arg0; + switch (arg1) { + case 0: + ivar2 = addToCoordinate(arg0, 0, 0, 4); + break; + case 1: + ivar2 = addToCoordinate(arg0, 1, 0, 4); + break; + case 2: + ivar2 = addToCoordinate(arg0, 2, 0, 3); + break; + case 3: + ivar2 = addToCoordinate(arg0, 3, 0, 2); + break; + case 4: + ivar2 = addToCoordinate(arg0, 4, 0, 1); + break; + case 5: + ivar2 = addToCoordinate(arg0, 4, 0, 0); + break; + case 6: + ivar2 = addToCoordinate(arg0, 4, 0, -1); + break; + case 7: + ivar2 = addToCoordinate(arg0, 3, 0, -2); + break; + case 8: + ivar2 = addToCoordinate(arg0, 2, 0, -3); + break; + case 9: + ivar2 = addToCoordinate(arg0, 1, 0, -4); + break; + case 10: + ivar2 = addToCoordinate(arg0, 0, 0, -4); + break; + case 11: + ivar2 = addToCoordinate(arg0, -1, 0, -4); + break; + case 12: + ivar2 = addToCoordinate(arg0, -2, 0, -3); + break; + case 13: + ivar2 = addToCoordinate(arg0, -3, 0, -2); + break; + case 14: + ivar2 = addToCoordinate(arg0, -4, 0, -1); + break; + case 15: + ivar2 = addToCoordinate(arg0, -4, 0, 0); + break; + case 16: + ivar2 = addToCoordinate(arg0, -4, 0, 1); + break; + case 17: + ivar2 = addToCoordinate(arg0, -3, 0, 2); + break; + case 18: + ivar2 = addToCoordinate(arg0, -2, 0, 3); + break; + case 19: + ivar2 = addToCoordinate(arg0, -1, 0, 4); + } + return ivar2; +} diff --git a/dumps/scripts/2866.cs2 b/dumps/scripts/2866.cs2 new file mode 100644 index 0000000..92a8613 --- /dev/null +++ b/dumps/scripts/2866.cs2 @@ -0,0 +1,18 @@ +int script_2866(int arg0,int arg1) { + int ivar2; + int ivar3; + ivar2 = 0; + ivar3 = 0; + ivar2 = subtract(extractX(arg0), extractX(arg1)); + if (ivar2 < 0) { + ivar2 = multiply(ivar2, -1); + } + ivar3 = subtract(extractY(arg0), extractY(arg1)); + if (ivar3 < 0) { + ivar3 = multiply(ivar3, -1); + } + if (ivar2 > ivar3) { + return ivar2; + } + return ivar3; +} diff --git a/dumps/scripts/2867.cs2 b/dumps/scripts/2867.cs2 new file mode 100644 index 0000000..fa843c9 --- /dev/null +++ b/dumps/scripts/2867.cs2 @@ -0,0 +1,27 @@ +int script_2867(int arg0,int arg1) { + if (arg0 == arg1) { + return 0; + } + if (subtract(extractX(arg0), extractX(arg1)) > multiply(2, multiply(subtract(extractY(arg0), extractY(arg1)), -1))) { + if (subtract(extractX(arg0), extractX(arg1)) > multiply(2, subtract(extractY(arg0), extractY(arg1)))) { + return 7; + } + if (multiply(2, subtract(extractX(arg0), extractX(arg1))) > subtract(extractY(arg0), extractY(arg1))) { + return 6; + } + if (multiply(2, subtract(extractX(arg0), extractX(arg1))) > multiply(subtract(extractY(arg0), extractY(arg1)), -1)) { + return 5; + } + return 4; + } + if (subtract(extractX(arg0), extractX(arg1)) > multiply(2, subtract(extractY(arg0), extractY(arg1)))) { + if (multiply(2, subtract(extractX(arg0), extractX(arg1))) > subtract(extractY(arg0), extractY(arg1))) { + if (multiply(2, subtract(extractX(arg0), extractX(arg1))) > multiply(subtract(extractY(arg0), extractY(arg1)), -1)) { + return 8; + } + return 1; + } + return 2; + } + return 3; +} diff --git a/dumps/scripts/2868.cs2 b/dumps/scripts/2868.cs2 new file mode 100644 index 0000000..ab00670 --- /dev/null +++ b/dumps/scripts/2868.cs2 @@ -0,0 +1,24 @@ +int script_2868(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + ivar3 = 0; + ivar4 = 0; + ivar5 = 0; + ivar6 = 0; + ivar7 = 0; + ivar8 = 0; + ivar3 = extractX(arg1); + ivar4 = extractX(arg2); + ivar5 = extractY(arg1); + ivar6 = extractY(arg2); + ivar8 = extractX(arg0); + ivar7 = extractY(arg0); + if (((ivar8 <= ivar4) && (ivar8 >= ivar3)) && ((ivar7 <= ivar6) && (ivar7 >= ivar5))) { + return 1; + } + return 0; +} diff --git a/dumps/scripts/2869.cs2 b/dumps/scripts/2869.cs2 new file mode 100644 index 0000000..896806e --- /dev/null +++ b/dumps/scripts/2869.cs2 @@ -0,0 +1,9 @@ +int script_2869(int arg0) { + if (((boolean)script_2868(arg0, 35884240, 37440815))) { + return 1; + } + if (((boolean)script_2868(arg0, 52513484, 53398263))) { + return 1; + } + return 0; +} diff --git a/dumps/scripts/287.cs2 b/dumps/scripts/287.cs2 new file mode 100644 index 0000000..a8f7351 --- /dev/null +++ b/dumps/scripts/287.cs2 @@ -0,0 +1,8 @@ +void script_287(int arg0,int arg1,int arg2,int arg3) { + createExtraChild(new WidgetPointer(arg2), 5, arg0); + setWidgetSize(17, 17, 0, 0); + setWidgetPosition(4, add(arg3, 4), 0, 0); + setWidgetHidden(arg1); + setWidgetSprite(1726); + return; +} diff --git a/dumps/scripts/2870.cs2 b/dumps/scripts/2870.cs2 new file mode 100644 index 0000000..350fb50 --- /dev/null +++ b/dumps/scripts/2870.cs2 @@ -0,0 +1,8 @@ +void script_2870(int arg0,int arg1) { + if (getClientCycle() >= arg1) { + setWidgetIsHidden(true, new WidgetPointer(arg0)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + return; + } + return; +} diff --git a/dumps/scripts/2871.cs2 b/dumps/scripts/2871.cs2 new file mode 100644 index 0000000..49757c7 --- /dev/null +++ b/dumps/scripts/2871.cs2 @@ -0,0 +1,11 @@ +void script_2871(int arg0) { + if (((boolean)arg0)) { + if (((boolean)globalint_1077)) { + globalint_1077 = 0; + } else { + globalint_1077 = 1; + } + } + script_2872(); + return; +} diff --git a/dumps/scripts/2872.cs2 b/dumps/scripts/2872.cs2 new file mode 100644 index 0000000..5f596c1 --- /dev/null +++ b/dumps/scripts/2872.cs2 @@ -0,0 +1,31 @@ +void script_2872() { + if (((boolean)globalint_1077)) { + setWidgetSprite(2432, new WidgetPointer(187,12)); + script_2878(); + setWidgetIsHidden(true, new WidgetPointer(187,1)); + setWidgetIsHidden(true, new WidgetPointer(187,2)); + setWidgetIsHidden(true, new WidgetPointer(187,17)); + setWidgetIsHidden(true, new WidgetPointer(187,18)); + setWidgetIsHidden(false, new WidgetPointer(187,9)); + setWidgetIsHidden(false, new WidgetPointer(187,10)); + setWidgetIsHidden(false, new WidgetPointer(187,11)); + setWidgetIsHidden(false, new WidgetPointer(187,13)); + script_3683(); + if (bitconfig_7081 == 32767) { + setWidgetIsHidden(false, new WidgetPointer(187,14)); + } + } else { + setWidgetSprite(2431, new WidgetPointer(187,12)); + setWidgetIsHidden(true, new WidgetPointer(187,9)); + setWidgetIsHidden(true, new WidgetPointer(187,10)); + setWidgetIsHidden(true, new WidgetPointer(187,11)); + setWidgetIsHidden(true, new WidgetPointer(187,13)); + setWidgetIsHidden(true, new WidgetPointer(187,14)); + setWidgetIsHidden(true, new WidgetPointer(187,18)); + setWidgetIsHidden(false, new WidgetPointer(187,1)); + setWidgetIsHidden(false, new WidgetPointer(187,2)); + setWidgetIsHidden(false, new WidgetPointer(187,17)); + } + globalint_2 = 0; + return; +} diff --git a/dumps/scripts/2873.cs2 b/dumps/scripts/2873.cs2 new file mode 100644 index 0000000..a56bbc6 --- /dev/null +++ b/dumps/scripts/2873.cs2 @@ -0,0 +1,9 @@ +void script_2873() { + if (((boolean)bitconfig_7078)) { + setWidgetSprite(2434, new WidgetPointer(187,10)); + } else { + setWidgetSprite(2433, new WidgetPointer(187,10)); + } + globalint_2 = 0; + return; +} diff --git a/dumps/scripts/2874.cs2 b/dumps/scripts/2874.cs2 new file mode 100644 index 0000000..ecac325 --- /dev/null +++ b/dumps/scripts/2874.cs2 @@ -0,0 +1,9 @@ +void script_2874() { + if (((boolean)bitconfig_7078)) { + setWidgetSprite(2434, new WidgetPointer(187,10)); + } else { + setWidgetSprite(2433, new WidgetPointer(187,10)); + } + globalint_2 = 0; + return; +} diff --git a/dumps/scripts/2875.cs2 b/dumps/scripts/2875.cs2 new file mode 100644 index 0000000..f932615 --- /dev/null +++ b/dumps/scripts/2875.cs2 @@ -0,0 +1,9 @@ +void script_2875() { + if (((boolean)bitconfig_7079)) { + setWidgetSprite(2437, new WidgetPointer(187,13)); + } else { + setWidgetSprite(2436, new WidgetPointer(187,13)); + } + globalint_2 = 0; + return; +} diff --git a/dumps/scripts/2876.cs2 b/dumps/scripts/2876.cs2 new file mode 100644 index 0000000..37b4513 --- /dev/null +++ b/dumps/scripts/2876.cs2 @@ -0,0 +1,9 @@ +void script_2876() { + if (((boolean)bitconfig_7079)) { + setWidgetSprite(2437, new WidgetPointer(187,13)); + } else { + setWidgetSprite(2436, new WidgetPointer(187,13)); + } + globalint_2 = 0; + return; +} diff --git a/dumps/scripts/2877.cs2 b/dumps/scripts/2877.cs2 new file mode 100644 index 0000000..0c7eabf --- /dev/null +++ b/dumps/scripts/2877.cs2 @@ -0,0 +1,4 @@ +void script_2877() { + script_2878(); + return; +} diff --git a/dumps/scripts/2878.cs2 b/dumps/scripts/2878.cs2 new file mode 100644 index 0000000..01decd2 --- /dev/null +++ b/dumps/scripts/2878.cs2 @@ -0,0 +1,34 @@ +void script_2878() { + int ivar0; + script_41(12255248); + globalint_1 = 0; + deleteAllExtraChilds(new WidgetPointer(187,9)); + while (getExtraChildGap(new WidgetPointer(187,9)) < 12) { + createExtraChild(new WidgetPointer(187,9), 4, getExtraChildGap(new WidgetPointer(187,9))); + } + while (getExtraChildGap(new WidgetPointer(187,9)) < 24) { + createExtraChild(new WidgetPointer(187,9), 5, getExtraChildGap(new WidgetPointer(187,9))); + } + ivar0 = 5; + ivar0 = script_2879(0, bitconfig_7081, ivar0); + ivar0 = script_2879(1, bitconfig_7082, ivar0); + ivar0 = script_2879(2, bitconfig_7083, ivar0); + ivar0 = script_2879(3, bitconfig_7084, ivar0); + ivar0 = script_2879(4, bitconfig_7085, ivar0); + ivar0 = script_2879(5, bitconfig_7086, ivar0); + ivar0 = script_2879(6, bitconfig_7087, ivar0); + ivar0 = script_2879(7, bitconfig_7088, ivar0); + ivar0 = script_2879(8, bitconfig_7089, ivar0); + ivar0 = script_2879(9, bitconfig_7090, ivar0); + ivar0 = script_2879(10, bitconfig_7091, ivar0); + ivar0 = script_2879(11, bitconfig_7092, ivar0); + if ((bitconfig_7081 == 32767) && ((boolean)globalint_1077)) { + setWidgetIsHidden(false, new WidgetPointer(187,14)); + } else { + setWidgetIsHidden(true, new WidgetPointer(187,14)); + } + createExtraChild(new WidgetPointer(187,9), 4, getExtraChildGap(new WidgetPointer(187,9))); + setWidgetPosition(15, ivar0, 0, 0); + setWidgetSize(150, ivar0, 0, 1); + return; +} diff --git a/dumps/scripts/2879.cs2 b/dumps/scripts/2879.cs2 new file mode 100644 index 0000000..5f1b76d --- /dev/null +++ b/dumps/scripts/2879.cs2 @@ -0,0 +1,41 @@ +int script_2879(int arg0,int arg1,int arg2) { + string svar0; + svar0 = "Remove from Playlist"; + if (setWidgetRegister(new WidgetPointer(187,9), arg0) && setWidgetRegister(new WidgetPointer(187,9), add(arg0, 12))) { + if (arg1 == 32767) { + setWidgetHidden(1); + setWidgetHidden(1); + return arg2; + } + setWidgetPosition(15, arg2, 0, 0); + setWidgetTextAlignment(0, 1, 0); + if ((bitconfig_4388 == arg1) && ((boolean)bitconfig_7078)) { + setWidgetRGB(new Color(255, 255, 102)); + setScriptCallOnMouseExit(1356, new WidgetPointer(-32768,3), -2147483643, 16777062, "Iii"); + } else { + setWidgetRGB(new Color(0, 255, 255)); + setScriptCallOnMouseExit(1356, new WidgetPointer(-32768,3), -2147483643, 65535, "Iii"); + } + setScriptCallOnMouseEntered(1356, new WidgetPointer(-32768,3), -2147483643, 16777215, "Iii"); + setWidgetText(getCommonString(1345, arg1)); + setWidgetSize(150, 15, 0, 0); + setWidgetContextMenuOption(1, "Play"); + setWidgetContextMenuOption(2, "Remove"); + cs2method1305(getCommonString(1345, arg1)); + cs2method1305(getCommonString(1345, arg1)); + setWidgetUnknownBoolean(false); + setWidgetFont(494); + cs2method1301(12255241, -1); + cs2method1301(-1, -1); + cs2method1302(2); + setWidgetSize(12, 12, 0, 0); + setWidgetPosition(2, add(arg2, 1), 0, 0); + setWidgetContextMenuOption(2, "Remove"); + setWidgetSprite(2430); + setScriptCallOnClickContextMenu(2885, new WidgetPointer(-32768,3), -2147483643, 150, 0, 20, -2147483644, "Iiiiii"); + setScriptCallOnMouseOver(1160, new WidgetPointer(187,9), -2147483643, new WidgetPointer(187,16), svar0, 25, 189, "IiIsii"); + setScriptCallOnMouseExit(40, new WidgetPointer(187,16), "I"); + setScriptCallOnMousePressed(40, new WidgetPointer(187,16), "I"); + } + return add(arg2, 15); +} diff --git a/dumps/scripts/288.cs2 b/dumps/scripts/288.cs2 new file mode 100644 index 0000000..3fb5f8b --- /dev/null +++ b/dumps/scripts/288.cs2 @@ -0,0 +1,4 @@ +void script_288(int arg0) { + cs2method5230(arg0); + return; +} diff --git a/dumps/scripts/2880.cs2 b/dumps/scripts/2880.cs2 new file mode 100644 index 0000000..aed7553 --- /dev/null +++ b/dumps/scripts/2880.cs2 @@ -0,0 +1,4 @@ +void script_2880() { + script_2881(); + return; +} diff --git a/dumps/scripts/2881.cs2 b/dumps/scripts/2881.cs2 new file mode 100644 index 0000000..6148777 --- /dev/null +++ b/dumps/scripts/2881.cs2 @@ -0,0 +1,11 @@ +void script_2881() { + if (((boolean)bitconfig_4393) || ((boolean)bitconfig_542)) { + return; + } + if (((boolean)globalint_1077)) { + script_39(12255244, 12255248, 25, 189, "Click here to access full song list"); + } else { + script_39(12255244, 12255248, 25, 189, "Click here to access playlist"); + } + return; +} diff --git a/dumps/scripts/2882.cs2 b/dumps/scripts/2882.cs2 new file mode 100644 index 0000000..b403237 --- /dev/null +++ b/dumps/scripts/2882.cs2 @@ -0,0 +1,11 @@ +void script_2882() { + if (((boolean)bitconfig_4393) || ((boolean)bitconfig_542)) { + return; + } + if (((boolean)bitconfig_7078)) { + script_39(12255242, 12255248, 25, 189, "Playlist on"); + } else { + script_39(12255242, 12255248, 25, 189, "Playlist off"); + } + return; +} diff --git a/dumps/scripts/2883.cs2 b/dumps/scripts/2883.cs2 new file mode 100644 index 0000000..e156d99 --- /dev/null +++ b/dumps/scripts/2883.cs2 @@ -0,0 +1,7 @@ +void script_2883() { + if (((boolean)bitconfig_4393) || ((boolean)bitconfig_542)) { + return; + } + script_39(12255243, 12255248, 25, 189, "Clear playlist"); + return; +} diff --git a/dumps/scripts/2884.cs2 b/dumps/scripts/2884.cs2 new file mode 100644 index 0000000..3226a76 --- /dev/null +++ b/dumps/scripts/2884.cs2 @@ -0,0 +1,11 @@ +void script_2884() { + if (((boolean)bitconfig_4393) || ((boolean)bitconfig_542)) { + return; + } + if (((boolean)bitconfig_7079)) { + script_39(12255245, 12255248, 25, 189, "Shuffle on"); + } else { + script_39(12255245, 12255248, 25, 189, "Shuffle off"); + } + return; +} diff --git a/dumps/scripts/2885.cs2 b/dumps/scripts/2885.cs2 new file mode 100644 index 0000000..ba4dbae --- /dev/null +++ b/dumps/scripts/2885.cs2 @@ -0,0 +1,13 @@ +void script_2885(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + if (((arg5 != 2) && (arg5 != 3)) && (arg5 != 4)) { + return; + } + script_41(12255248); + globalint_1 = 0; + arg4 = add(arg4, getClientCycle()); + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + cs2method2103(arg2); + setScriptCallOnGameloop(1621, new WidgetPointer(arg0), arg1, arg3, arg4, "Iiii"); + } + return; +} diff --git a/dumps/scripts/2886.cs2 b/dumps/scripts/2886.cs2 new file mode 100644 index 0000000..0bbd2c6 --- /dev/null +++ b/dumps/scripts/2886.cs2 @@ -0,0 +1,11 @@ +void script_2886() { + int ivar0; + globalint_1078 = bitconfig_7189; + globalint_1086 = 0; + ivar0 = getClientCycle(); + setScriptCallOnGameloop(2892, new WidgetPointer(476,24), ivar0, "Ii", new WidgetPointer(476,24)); + playSoundEffect(8641, 1, 0); + setScriptCallOnWidgetResize(2887, "", new WidgetPointer(476,0)); + script_2888(); + return; +} diff --git a/dumps/scripts/2887.cs2 b/dumps/scripts/2887.cs2 new file mode 100644 index 0000000..a81ab14 --- /dev/null +++ b/dumps/scripts/2887.cs2 @@ -0,0 +1,4 @@ +void script_2887() { + script_2888(); + return; +} diff --git a/dumps/scripts/2888.cs2 b/dumps/scripts/2888.cs2 new file mode 100644 index 0000000..7cd4c3b --- /dev/null +++ b/dumps/scripts/2888.cs2 @@ -0,0 +1,10 @@ +void script_2888() { + if (getDisplayMode() >= 2) { + setWidgetPosition(0, 287, 0, 0, new WidgetPointer(476,56)); + setWidgetPosition(0, 254, 0, 0, new WidgetPointer(476,55)); + } else { + setWidgetPosition(18, 40, 2, 0, new WidgetPointer(476,56)); + setWidgetPosition(18, 7, 2, 0, new WidgetPointer(476,55)); + } + return; +} diff --git a/dumps/scripts/2889.cs2 b/dumps/scripts/2889.cs2 new file mode 100644 index 0000000..81836d7 --- /dev/null +++ b/dumps/scripts/2889.cs2 @@ -0,0 +1,26 @@ +void script_2889() { + int ivar0; + int ivar1; + int ivar2; + ivar0 = cs2method_3408(105, 110, 927, bitconfig_7099); + ivar1 = -1; + ivar2 = -1; + if (ivar0 != -1) { + if (getNpcNodemapData(ivar0, 956) != -1) { + setWidgetModel(cs2method_3408(110, 109, 934, getNpcNodemapData(ivar0, 956)), new WidgetPointer(476,45)); + setWidgetAnimation(cs2method_3408(110, 65, 935, getNpcNodemapData(ivar0, 956)), new WidgetPointer(476,45)); + setWidgetSprite(cs2method_3408(110, 100, 932, getNpcNodemapData(ivar0, 956)), new WidgetPointer(476,49)); + setWidgetText(new WidgetPointer(476,52), cs2method_3408(110, 115, 930, getNpcNodemapData(ivar0, 956))); + } + if (getNpcNodemapData(ivar0, 957) != -1) { + setWidgetModel(cs2method_3408(110, 109, 934, getNpcNodemapData(ivar0, 957)), new WidgetPointer(476,46)); + setWidgetAnimation(cs2method_3408(110, 65, 935, getNpcNodemapData(ivar0, 957)), new WidgetPointer(476,46)); + setWidgetSprite(cs2method_3408(110, 100, 932, getNpcNodemapData(ivar0, 957)), new WidgetPointer(476,50)); + setWidgetText(new WidgetPointer(476,53), cs2method_3408(110, 115, 930, getNpcNodemapData(ivar0, 957))); + } + setWidgetSprite(cs2method_3408(110, 100, 933, ivar0), new WidgetPointer(476,48)); + setWidgetModel(cs2method_3408(110, 109, 934, ivar0), new WidgetPointer(476,44)); + setWidgetAnimation(cs2method_3408(110, 65, 935, ivar0), new WidgetPointer(476,44)); + } + return; +} diff --git a/dumps/scripts/289.cs2 b/dumps/scripts/289.cs2 new file mode 100644 index 0000000..aeb5a3d --- /dev/null +++ b/dumps/scripts/289.cs2 @@ -0,0 +1,7 @@ +void script_289(int arg0,int arg1,int arg2) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetRGB(new Color(arg2)); + } + script_41(49479737); + return; +} diff --git a/dumps/scripts/2890.cs2 b/dumps/scripts/2890.cs2 new file mode 100644 index 0000000..11aa104 --- /dev/null +++ b/dumps/scripts/2890.cs2 @@ -0,0 +1,91 @@ +void script_2890() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + ivar0 = -1; + ivar1 = 0; + ivar2 = -1; + ivar3 = -1; + ivar4 = -1; + ivar5 = -1; + ivar6 = -1; + ivar7 = -1; + ivar8 = 1; + ivar9 = 0; + ivar10 = 31195136; + while (ivar8 <= getCommonDefinitionSize(929)) { + if ((((ivar8 != globalint_1080) && (ivar8 != globalint_1081)) && ((ivar8 != globalint_1082) && (ivar8 != globalint_1083))) && (((ivar8 != globalint_1084) && (ivar8 != globalint_1085)) && isBitFlagged(standart_config_1632, ivar8))) { + ivar0 = cs2method_3408(105, 110, 929, ivar8); + if ((ivar0 != -1) && (ivar1 < 6)) { + ivar1 = add(ivar1, 1); + if (globalint_1080 == -1) { + globalint_1080 = ivar8; + } else if (globalint_1081 == -1) { + globalint_1081 = ivar8; + } else if (globalint_1082 == -1) { + globalint_1082 = ivar8; + } else if (globalint_1083 == -1) { + globalint_1083 = ivar8; + } else if (globalint_1084 == -1) { + globalint_1084 = ivar8; + } else { + if (globalint_1085 == -1) { + globalint_1085 = ivar8; + } + } + ivar0 = -1; + } + } + ivar8 = add(ivar8, 1); + } + ivar8 = 1; + ivar11 = 0; + while (ivar8 <= 6) { + ivar10 = ((int)cs2method_3408(105, 73, 925, ivar8)); + if ((ivar10 != 31195136) && (getWidgetSpriteId(new WidgetPointer(ivar10)) == -1)) { + switch (ivar8) { + case 1: + ivar0 = cs2method_3408(105, 110, 929, globalint_1080); + break; + case 2: + ivar0 = cs2method_3408(105, 110, 929, globalint_1081); + break; + case 3: + ivar0 = cs2method_3408(105, 110, 929, globalint_1082); + break; + case 4: + ivar0 = cs2method_3408(105, 110, 929, globalint_1083); + break; + case 5: + ivar0 = cs2method_3408(105, 110, 929, globalint_1084); + break; + case 6: + ivar0 = cs2method_3408(105, 110, 929, globalint_1085); + } + if (ivar0 != -1) { + setWidgetSprite(cs2method_3408(110, 100, 932, ivar0), new WidgetPointer(ivar10)); + setWidgetText(cs2method_3408(73, 73, 926, ivar10), cs2method_3408(110, 115, 930, ivar0)); + setScriptCallOnMouseOver(1160, new WidgetPointer(ivar10), -1, new WidgetPointer(476,59), cs2method_3408(110, 115, 930, ivar0), 25, 200, "IiIsii", new WidgetPointer(ivar10)); + setScriptCallOnMouseExit(40, new WidgetPointer(476,59), "I", new WidgetPointer(ivar10)); + if ((ivar10 != 31195149) && (ivar10 != 31195150)) { + setWidgetIsHidden(false, new WidgetPointer(476,17)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(ivar10)), getWidgetActualY(new WidgetPointer(ivar10)), 0, 0, new WidgetPointer(476,17)); + script_1725(31195153); + ivar11 = add(getClientCycle(), 150); + setScriptCallOnGameloop(2891, ivar11, new WidgetPointer(ivar10), "iI", new WidgetPointer(ivar10)); + } + } + } + ivar8 = add(ivar8, 1); + } + return; +} diff --git a/dumps/scripts/2891.cs2 b/dumps/scripts/2891.cs2 new file mode 100644 index 0000000..8c7876b --- /dev/null +++ b/dumps/scripts/2891.cs2 @@ -0,0 +1,8 @@ +void script_2891(int arg0,int arg1) { + if (getClientCycle() >= arg0) { + script_1728(31195153); + setWidgetIsHidden(true, new WidgetPointer(476,17)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg1)); + } + return; +} diff --git a/dumps/scripts/2892.cs2 b/dumps/scripts/2892.cs2 new file mode 100644 index 0000000..326210c --- /dev/null +++ b/dumps/scripts/2892.cs2 @@ -0,0 +1,10 @@ +void script_2892(int arg0,int arg1) { + if (subtract(getClientCycle(), arg1) >= 180) { + globalint_1086 = 1; + } + if (subtract(getClientCycle(), arg1) >= 1000) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(476,24)); + setWidgetIsHidden(true, new WidgetPointer(476,24)); + } + return; +} diff --git a/dumps/scripts/2893.cs2 b/dumps/scripts/2893.cs2 new file mode 100644 index 0000000..3036c2a --- /dev/null +++ b/dumps/scripts/2893.cs2 @@ -0,0 +1,8 @@ +void script_2893() { + if (((boolean)globalint_1086)) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(476,24)); + setWidgetIsHidden(true, new WidgetPointer(476,24)); + globalint_1086 = 0; + } + return; +} diff --git a/dumps/scripts/2894.cs2 b/dumps/scripts/2894.cs2 new file mode 100644 index 0000000..aeb6082 --- /dev/null +++ b/dumps/scripts/2894.cs2 @@ -0,0 +1,6 @@ +void script_2894(int arg0) { + if (bitconfig_7093 >= 0) { + setWidgetText(new WidgetPointer(arg0), intToStr(bitconfig_7093)); + } + return; +} diff --git a/dumps/scripts/2895.cs2 b/dumps/scripts/2895.cs2 new file mode 100644 index 0000000..497da8c --- /dev/null +++ b/dumps/scripts/2895.cs2 @@ -0,0 +1,13 @@ +void script_2895(int arg0) { + if (globalint_1078 > bitconfig_7189) { + if (globalint_1079 != 1) { + setScriptCallOnGameloop(2896, new WidgetPointer(arg0), "I", new WidgetPointer(arg0)); + globalint_1079 = 1; + } + } else { + if (((boolean)globalint_1078)) { + globalint_1078 = bitconfig_7189; + } + } + return; +} diff --git a/dumps/scripts/2896.cs2 b/dumps/scripts/2896.cs2 new file mode 100644 index 0000000..40b3621 --- /dev/null +++ b/dumps/scripts/2896.cs2 @@ -0,0 +1,12 @@ +void script_2896(int arg0) { + if (((boolean)mod(getClientCycle(), 5))) { + if (multiplyDivide(globalint_1078, 2000, 200) > multiplyDivide(bitconfig_7189, 2000, 200)) { + setWidgetSize(20, multiplyDivide(globalint_1078, 2000, 200), 0, 0, new WidgetPointer(arg0)); + globalint_1078 = subtract(globalint_1078, 1); + } else { + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + globalint_1079 = 0; + } + } + return; +} diff --git a/dumps/scripts/2897.cs2 b/dumps/scripts/2897.cs2 new file mode 100644 index 0000000..85842fc --- /dev/null +++ b/dumps/scripts/2897.cs2 @@ -0,0 +1,5 @@ +void script_2897(int arg0) { + setWidgetIsHidden(false, new WidgetPointer(arg0)); + script_1725(arg0); + return; +} diff --git a/dumps/scripts/2898.cs2 b/dumps/scripts/2898.cs2 new file mode 100644 index 0000000..3879318 --- /dev/null +++ b/dumps/scripts/2898.cs2 @@ -0,0 +1,5 @@ +void script_2898(int arg0) { + script_1728(arg0); + setWidgetIsHidden(true, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/2899.cs2 b/dumps/scripts/2899.cs2 new file mode 100644 index 0000000..c43279b --- /dev/null +++ b/dumps/scripts/2899.cs2 @@ -0,0 +1,8 @@ +void script_2899() { + int ivar0; + setWidgetIsHidden(false, new WidgetPointer(476,58)); + cs2method2103(0, new WidgetPointer(476,58)); + ivar0 = getClientCycle(); + setScriptCallOnGameloop(2900, ivar0, "i", new WidgetPointer(476,58)); + return; +} diff --git a/dumps/scripts/29.cs2 b/dumps/scripts/29.cs2 new file mode 100644 index 0000000..cc2e6be --- /dev/null +++ b/dumps/scripts/29.cs2 @@ -0,0 +1,4 @@ +void script_29() { + script_675(); + return; +} diff --git a/dumps/scripts/290.cs2 b/dumps/scripts/290.cs2 new file mode 100644 index 0000000..628bdf7 --- /dev/null +++ b/dumps/scripts/290.cs2 @@ -0,0 +1,4 @@ +void script_290(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + script_291(arg0, arg1, arg2, arg3, arg4, arg5); + return; +} diff --git a/dumps/scripts/2900.cs2 b/dumps/scripts/2900.cs2 new file mode 100644 index 0000000..756f5f2 --- /dev/null +++ b/dumps/scripts/2900.cs2 @@ -0,0 +1,11 @@ +void script_2900(int arg0) { + if (getClientCycle() > add(arg0, 200)) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(476,58)); + setWidgetIsHidden(true, new WidgetPointer(476,58)); + } else { + if (getClientCycle() > add(arg0, 150)) { + cs2method2103(min(add(getWidgetShadeColor(new WidgetPointer(476,58)), 10), 255), new WidgetPointer(476,58)); + } + } + return; +} diff --git a/dumps/scripts/2901.cs2 b/dumps/scripts/2901.cs2 new file mode 100644 index 0000000..7b81785 --- /dev/null +++ b/dumps/scripts/2901.cs2 @@ -0,0 +1,5 @@ +void script_2901(int arg0,int arg1,string arg2) { + setWidgetIsHidden(false, new WidgetPointer(arg0)); + setWidgetText(new WidgetPointer(arg1), arg2); + return; +} diff --git a/dumps/scripts/2902.cs2 b/dumps/scripts/2902.cs2 new file mode 100644 index 0000000..1617526 --- /dev/null +++ b/dumps/scripts/2902.cs2 @@ -0,0 +1,7 @@ +void script_2902(int arg0,int arg1,int arg2) { + if (globalint_1087 != arg2) { + setWidgetIsHidden(true, new WidgetPointer(arg0)); + } + setWidgetText(new WidgetPointer(arg1), ""); + return; +} diff --git a/dumps/scripts/2903.cs2 b/dumps/scripts/2903.cs2 new file mode 100644 index 0000000..5934e32 --- /dev/null +++ b/dumps/scripts/2903.cs2 @@ -0,0 +1,18 @@ +void script_2903(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8) { + if (globalint_1087 == arg8) { + globalint_1087 = 0; + setWidgetIsHidden(true, new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(arg1)); + } else { + globalint_1087 = arg8; + setWidgetIsHidden(false, new WidgetPointer(arg0)); + setWidgetIsHidden(false, new WidgetPointer(arg1)); + } + setWidgetIsHidden(true, new WidgetPointer(arg2)); + setWidgetIsHidden(true, new WidgetPointer(arg3)); + setWidgetIsHidden(true, new WidgetPointer(arg4)); + setWidgetIsHidden(true, new WidgetPointer(arg5)); + setWidgetIsHidden(true, new WidgetPointer(arg6)); + setWidgetIsHidden(true, new WidgetPointer(arg7)); + return; +} diff --git a/dumps/scripts/2904.cs2 b/dumps/scripts/2904.cs2 new file mode 100644 index 0000000..bba50a9 --- /dev/null +++ b/dumps/scripts/2904.cs2 @@ -0,0 +1,12 @@ +void script_2904(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7) { + globalint_1087 = 0; + setWidgetIsHidden(true, new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(arg1)); + setWidgetIsHidden(true, new WidgetPointer(arg2)); + setWidgetIsHidden(true, new WidgetPointer(arg3)); + setWidgetIsHidden(true, new WidgetPointer(arg4)); + setWidgetIsHidden(true, new WidgetPointer(arg5)); + setWidgetIsHidden(true, new WidgetPointer(arg6)); + setWidgetIsHidden(true, new WidgetPointer(arg7)); + return; +} diff --git a/dumps/scripts/2905.cs2 b/dumps/scripts/2905.cs2 new file mode 100644 index 0000000..bd83c39 --- /dev/null +++ b/dumps/scripts/2905.cs2 @@ -0,0 +1,31 @@ +void script_2905(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + ivar4 = getWidgetParentId(new WidgetPointer(arg0)); + ivar5 = 0; + if (arg1 == 10010) { + switch (bitconfig_7193) { + case 1: + ivar5 = 1; + break; + case 2: + ivar5 = 1; + arg1 = 11259; + } + } else if (arg1 == 11262) { + ivar5 = bitconfig_7192; + } else { + if (arg1 == 11260) { + ivar5 = bitconfig_7194; + } + } + setWidgetText(new WidgetPointer(arg3), getItemName(arg1) + "
" + "(" + intToStr(ivar5) + "/" + intToStr(arg2) + ")"); + setItemOnWidgetMethod2205(arg1, -1, new WidgetPointer(arg0)); + setWidgetBorderThickness(1, new WidgetPointer(arg0)); + if (ivar5 > 0) { + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(arg3)); + } else { + setWidgetRGB(new Color(204, 0, 0), new WidgetPointer(arg3)); + } + return; +} diff --git a/dumps/scripts/2906.cs2 b/dumps/scripts/2906.cs2 new file mode 100644 index 0000000..dad7d0f --- /dev/null +++ b/dumps/scripts/2906.cs2 @@ -0,0 +1,32 @@ +void script_2906(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + ivar3 = getWidgetParentId(new WidgetPointer(arg0)); + ivar4 = 0; + if (arg1 == 10010) { + ivar4 = add(getItemAmtInContainer(94, 11259), getItemAmtInContainer(93, 11259)); + if (ivar4 > 0) { + arg1 = 11259; + } + } + switch (arg1) { + case 11259: + case 10010: + if (((boolean)ivar4)) { + ivar4 = add(getItemAmtInContainer(93, 10010), getItemAmtInContainer(94, 10010)); + } + break; + default: + ivar4 = getItemAmtInContainer(93, arg1); + } + setWidgetText(new WidgetPointer(arg2), getItemName(arg1)); + if (ivar4 > 0) { + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(arg2)); + setItemOnWidgetMethod2200(arg1, ivar4, new WidgetPointer(arg0)); + } else { + setWidgetRGB(new Color(204, 0, 0), new WidgetPointer(arg2)); + setItemOnWidgetMethod2200(arg1, -1, new WidgetPointer(arg0)); + } + setWidgetBorderThickness(1, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/2907.cs2 b/dumps/scripts/2907.cs2 new file mode 100644 index 0000000..3eafa84 --- /dev/null +++ b/dumps/scripts/2907.cs2 @@ -0,0 +1,5 @@ +void script_2907(int arg0,int arg1) { + setWidgetText(new WidgetPointer(arg1), ""); + cs2method2103(0, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/2908.cs2 b/dumps/scripts/2908.cs2 new file mode 100644 index 0000000..43bdc51 --- /dev/null +++ b/dumps/scripts/2908.cs2 @@ -0,0 +1,8 @@ +void script_2908(int arg0) { + if (((boolean)bitconfig_7191)) { + setWidgetIsHidden(true, new WidgetPointer(arg0)); + } else { + setWidgetIsHidden(false, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/2909.cs2 b/dumps/scripts/2909.cs2 new file mode 100644 index 0000000..ec23dda --- /dev/null +++ b/dumps/scripts/2909.cs2 @@ -0,0 +1,10 @@ +void script_2909(int arg0,int arg1) { + if (((boolean)bitconfig_7191)) { + setWidgetIsHidden(true, new WidgetPointer(arg0)); + } else if (bitconfig_7191 < 5) { + setWidgetText(new WidgetPointer(arg1), "" + "1 min"); + } else { + setWidgetText(new WidgetPointer(arg1), intToStr(divide(add(bitconfig_7191, 4), 5)) + " min"); + } + return; +} diff --git a/dumps/scripts/291.cs2 b/dumps/scripts/291.cs2 new file mode 100644 index 0000000..670208f --- /dev/null +++ b/dumps/scripts/291.cs2 @@ -0,0 +1,77 @@ +void script_291(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + setWidgetText(new WidgetPointer(755,20), cs2method5207(cs2method5235())); + deleteAllExtraChilds(new WidgetPointer(arg2)); + deleteAllExtraChilds(new WidgetPointer(arg3)); + if (((boolean)arg0)) { + setWidgetIsHidden(true, new WidgetPointer(arg1)); + setWidgetSprite(773, new WidgetPointer(755,21)); + setScriptCallOnMousePressed(290, 1, new WidgetPointer(arg1), new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), "1IIIII", new WidgetPointer(755,21)); + setScriptCallOnMousePressed(290, 1, new WidgetPointer(arg1), new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), "1IIIII", new WidgetPointer(755,20)); + return; + } + setWidgetIsHidden(false, new WidgetPointer(arg1)); + setWidgetSprite(788, new WidgetPointer(755,21)); + setScriptCallOnMousePressed(290, 0, new WidgetPointer(arg1), new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), "1IIIII", new WidgetPointer(755,21)); + setScriptCallOnMousePressed(290, 0, new WidgetPointer(arg1), new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), "1IIIII", new WidgetPointer(755,20)); + globalarray_0 = new int[add(41, 1)]; + globalarray_0[0] = 0; + ivar6 = 1; + ivar7 = 1; + ivar8 = -1; + while (ivar6 <= 41) { + ivar8 = cs2method_3408(105, 96, 708, ivar6); + if (ivar8 != -1) { + globalarray_0[ivar7] = ivar6; + ivar7 = add(ivar7, 1); + } + ivar6 = add(ivar6, 1); + } + script_293(0, 1, subtract(ivar7, 1)); + createExtraChild(new WidgetPointer(arg2), 4, getExtraChildGap(new WidgetPointer(arg2))); + setWidgetPosition(0, 0, 1, 0); + setWidgetSize(0, 20, 1, 0); + setWidgetFont(496); + setWidgetTextAlignment(0, 1, 0); + setWidgetRGB(new Color(255, 255, 255)); + setScriptCallOnMouseEntered(1356, new WidgetPointer(-32768,3), -2147483643, 11513775, "Iii"); + setScriptCallOnMouseExit(1356, new WidgetPointer(-32768,3), -2147483643, 16777215, "Iii"); + ivar8 = cs2method_3408(105, 96, 708, globalarray_0[0]); + setWidgetText(cs2method5207(ivar8)); + setScriptCallOnMousePressed(294, ivar8, new WidgetPointer(arg1), new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), "`IIIII"); + script_309(ivar8, arg2, 0); + ivar9 = getWidgetActualHeight(); + ivar10 = 0; + ivar6 = 1; + while (ivar6 < ivar7) { + createExtraChild(new WidgetPointer(arg2), 4, getExtraChildGap(new WidgetPointer(arg2))); + setWidgetPosition(0, ivar9, 1, 0); + setWidgetSize(0, 20, 1, 0); + setWidgetFont(495); + setWidgetTextAlignment(0, 1, 0); + setWidgetRGB(new Color(255, 255, 255)); + setScriptCallOnMouseEntered(1356, new WidgetPointer(-32768,3), -2147483643, 11513775, "Iii"); + setScriptCallOnMouseExit(1356, new WidgetPointer(-32768,3), -2147483643, 16777215, "Iii"); + ivar8 = cs2method_3408(105, 96, 708, globalarray_0[ivar6]); + setWidgetText(cs2method5207(ivar8)); + setScriptCallOnMousePressed(294, ivar8, new WidgetPointer(arg1), new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), "`IIIII"); + if (ivar8 == cs2method5235()) { + ivar10 = ivar9; + } + script_309(ivar8, arg2, ivar9); + ivar9 = add(ivar9, getWidgetActualHeight()); + ivar6 = add(ivar6, 1); + } + setWidgetScrollMax(0, ivar9, new WidgetPointer(arg2)); + ivar9 = max(ivar9, 20); + ivar9 = add(ivar9, 3); + ivar9 = min(ivar9, 150); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg1)), ivar9, 0, 0, new WidgetPointer(arg1)); + script_31(arg3, arg2, 792, 789, 790, 791, 773, 788); + script_157(arg3, arg2, ivar10, 1); + return; +} diff --git a/dumps/scripts/2910.cs2 b/dumps/scripts/2910.cs2 new file mode 100644 index 0000000..cc189bd --- /dev/null +++ b/dumps/scripts/2910.cs2 @@ -0,0 +1,12 @@ +void script_2910(int arg0,int arg1) { + if (((boolean)stringMethod4107(getWidgetText(new WidgetPointer(arg1)), "Hide"))) { + setScriptCallOnGameloop(2911, 0, 24, subtract(getWidgetActualHeight(new WidgetPointer(getWidgetParentId(new WidgetPointer(arg0)))), 24), 0, new WidgetPointer(arg0), "1iiiI", new WidgetPointer(arg0)); + setWidgetText(new WidgetPointer(arg1), "Show"); + setWidgetContextMenuOption(1, new WidgetPointer(arg1), "Show"); + } else { + setScriptCallOnGameloop(2911, 1, 24, subtract(getWidgetActualHeight(new WidgetPointer(getWidgetParentId(new WidgetPointer(arg0)))), 24), 0, new WidgetPointer(arg0), "1iiiI", new WidgetPointer(arg0)); + setWidgetText(new WidgetPointer(arg1), "Hide"); + setWidgetContextMenuOption(1, new WidgetPointer(arg1), "Hide"); + } + return; +} diff --git a/dumps/scripts/2911.cs2 b/dumps/scripts/2911.cs2 new file mode 100644 index 0000000..0d4e711 --- /dev/null +++ b/dumps/scripts/2911.cs2 @@ -0,0 +1,16 @@ +void script_2911(int arg0,int arg1,int arg2,int arg3,int arg4) { + int ivar5; + ivar5 = 10; + arg3 = add(arg3, 1); + if (((boolean)arg0)) { + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg4)), add(arg1, divide(multiply(arg2, subtract(ivar5, arg3)), ivar5)), 0, 0, new WidgetPointer(arg4)); + } else { + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg4)), add(arg1, divide(multiply(arg2, arg3), ivar5)), 0, 0, new WidgetPointer(arg4)); + } + if (arg3 == ivar5) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg4)); + } else { + setScriptCallOnGameloop(2911, arg0, arg1, arg2, arg3, new WidgetPointer(arg4), "1iiiI", new WidgetPointer(arg4)); + } + return; +} diff --git a/dumps/scripts/2912.cs2 b/dumps/scripts/2912.cs2 new file mode 100644 index 0000000..f295088 --- /dev/null +++ b/dumps/scripts/2912.cs2 @@ -0,0 +1,4 @@ +void script_2912(int arg0,int arg1) { + script_2914(arg0, arg1, 0); + return; +} diff --git a/dumps/scripts/2913.cs2 b/dumps/scripts/2913.cs2 new file mode 100644 index 0000000..9bbc7ab --- /dev/null +++ b/dumps/scripts/2913.cs2 @@ -0,0 +1,4 @@ +void script_2913(int arg0,int arg1) { + script_2914(arg0, arg1, 1); + return; +} diff --git a/dumps/scripts/2914.cs2 b/dumps/scripts/2914.cs2 new file mode 100644 index 0000000..a4cb2b6 --- /dev/null +++ b/dumps/scripts/2914.cs2 @@ -0,0 +1,142 @@ +void script_2914(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + ivar3 = getWidgetActualWidth(new WidgetPointer(arg0)); + ivar4 = getWidgetActualHeight(new WidgetPointer(arg0)); + ivar5 = getExtraChildGap(new WidgetPointer(arg0)); + createExtraChild(new WidgetPointer(arg0), 5, ivar5); + setWidgetPosition(0, 0, 1, 0); + setWidgetSize(4, 32, 1, 0); + setWidgetSprite(1124); + cs2method1107(1); + ivar5 = add(ivar5, 1); + createExtraChild(new WidgetPointer(arg0), 5, ivar5); + setWidgetPosition(0, -12, 1, 2); + setWidgetSize(4, 32, 1, 0); + setWidgetSprite(822); + cs2method1107(1); + ivar5 = add(ivar5, 1); + createExtraChild(new WidgetPointer(arg0), 5, ivar5); + setWidgetPosition(-13, 0, 0, 1); + setWidgetSize(32, 4, 0, 1); + setWidgetSprite(821); + cs2method1107(1); + ivar5 = add(ivar5, 1); + createExtraChild(new WidgetPointer(arg0), 5, ivar5); + setWidgetPosition(-12, 0, 2, 1); + setWidgetSize(32, 4, 0, 1); + setWidgetSprite(823); + cs2method1107(1); + ivar5 = add(ivar5, 1); + createExtraChild(new WidgetPointer(arg0), 5, ivar5); + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(32, 32, 0, 0); + setWidgetSprite(1123); + ivar5 = add(ivar5, 1); + createExtraChild(new WidgetPointer(arg0), 5, ivar5); + setWidgetPosition(0, 0, 2, 0); + setWidgetSize(32, 32, 0, 0); + setWidgetSprite(1125); + ivar5 = add(ivar5, 1); + createExtraChild(new WidgetPointer(arg0), 5, ivar5); + setWidgetPosition(0, 0, 0, 2); + setWidgetSize(32, 32, 0, 0); + setWidgetSprite(826); + ivar5 = add(ivar5, 1); + createExtraChild(new WidgetPointer(arg0), 5, ivar5); + setWidgetPosition(0, 0, 2, 2); + setWidgetSize(32, 32, 0, 0); + setWidgetSprite(827); + ivar5 = add(ivar5, 1); + if (arg2 > 0) { + createExtraChild(new WidgetPointer(arg0), 3, ivar5); + setWidgetPosition(8, 7, 0, 1); + setWidgetSize(1, 30, 0, 1); + setWidgetRGB(new Color(0, 0, 0)); + cs2method2103(200); + setWidgetFilled(1); + ivar5 = add(ivar5, 1); + createExtraChild(new WidgetPointer(arg0), 3, ivar5); + setWidgetPosition(8, 7, 0, 1); + setWidgetSize(3, 30, 0, 1); + setWidgetRGB(new Color(0, 0, 0)); + cs2method2103(220); + setWidgetFilled(1); + ivar5 = add(ivar5, 1); + createExtraChild(new WidgetPointer(arg0), 3, ivar5); + setWidgetPosition(8, 7, 0, 1); + setWidgetSize(5, 30, 0, 1); + setWidgetRGB(new Color(0, 0, 0)); + cs2method2103(220); + setWidgetFilled(1); + ivar5 = add(ivar5, 1); + createExtraChild(new WidgetPointer(arg0), 3, ivar5); + setWidgetPosition(8, 7, 2, 1); + setWidgetSize(7, 30, 0, 1); + setWidgetRGB(new Color(255, 255, 255)); + cs2method2103(250); + setWidgetFilled(1); + ivar5 = add(ivar5, 1); + createExtraChild(new WidgetPointer(arg0), 3, ivar5); + setWidgetPosition(8, 7, 2, 1); + setWidgetSize(5, 30, 0, 1); + setWidgetRGB(new Color(0, 0, 0)); + cs2method2103(245); + setWidgetFilled(1); + ivar5 = add(ivar5, 1); + createExtraChild(new WidgetPointer(arg0), 3, ivar5); + setWidgetPosition(8, 7, 2, 1); + setWidgetSize(1, 30, 0, 1); + setWidgetRGB(new Color(0, 0, 0)); + cs2method2103(200); + setWidgetFilled(1); + ivar5 = add(ivar5, 1); + createExtraChild(new WidgetPointer(arg0), 3, ivar5); + setWidgetPosition(8, 7, 2, 1); + setWidgetSize(3, 30, 0, 1); + setWidgetRGB(new Color(0, 0, 0)); + cs2method2103(220); + setWidgetFilled(1); + ivar5 = add(ivar5, 1); + createExtraChild(new WidgetPointer(arg0), 3, ivar5); + setWidgetPosition(1, 8, 1, 2); + setWidgetSize(24, 3, 1, 0); + setWidgetRGB(new Color(0, 0, 0)); + cs2method2103(235); + setWidgetFilled(1); + ivar5 = add(ivar5, 1); + createExtraChild(new WidgetPointer(arg0), 3, ivar5); + setWidgetPosition(-1, 22, 1, 0); + setWidgetSize(28, 3, 1, 0); + setWidgetRGB(new Color(255, 255, 255)); + cs2method2103(250); + setWidgetFilled(1); + ivar5 = add(ivar5, 1); + createExtraChild(new WidgetPointer(arg0), 3, ivar5); + setWidgetPosition(0, 7, 1, 2); + setWidgetSize(14, 28, 1, 1); + setWidgetRGB(new Color(0, 0, 0)); + setWidgetFilled(0); + ivar5 = add(ivar5, 1); + } + if (arg1 > 0) { + createExtraChild(new WidgetPointer(arg0), 5, ivar5); + setWidgetPosition(0, subtract(arg1, 5), 1, 0); + setWidgetSize(4, 32, 1, 0); + setWidgetSprite(828); + cs2method1107(1); + ivar5 = add(ivar5, 1); + createExtraChild(new WidgetPointer(arg0), 5, ivar5); + setWidgetPosition(0, subtract(arg1, 3), 0, 0); + setWidgetSize(32, 32, 0, 0); + setWidgetSprite(829); + ivar5 = add(ivar5, 1); + createExtraChild(new WidgetPointer(arg0), 5, ivar5); + setWidgetPosition(0, subtract(arg1, 3), 2, 0); + setWidgetSize(32, 32, 0, 0); + setWidgetSprite(830); + ivar5 = add(ivar5, 1); + } + return; +} diff --git a/dumps/scripts/2915.cs2 b/dumps/scripts/2915.cs2 new file mode 100644 index 0000000..facb398 --- /dev/null +++ b/dumps/scripts/2915.cs2 @@ -0,0 +1,3 @@ +int script_2915() { + return multiply(max(getSkillCurrentLvl(3), 0), 10); +} diff --git a/dumps/scripts/2916.cs2 b/dumps/scripts/2916.cs2 new file mode 100644 index 0000000..6dbfa30 --- /dev/null +++ b/dumps/scripts/2916.cs2 @@ -0,0 +1,6 @@ +int script_2916() { + if (((boolean)globalint_1533)) { + return multiply(max(getSkillCurrentLvl(3), 0), 10); + } + return multiply(max(getSkillActualLvl(3), 1), 10); +} diff --git a/dumps/scripts/2917.cs2 b/dumps/scripts/2917.cs2 new file mode 100644 index 0000000..ad6e47e --- /dev/null +++ b/dumps/scripts/2917.cs2 @@ -0,0 +1,4 @@ +void script_2917(int arg0) { + script_2918(arg0); + return; +} diff --git a/dumps/scripts/2918.cs2 b/dumps/scripts/2918.cs2 new file mode 100644 index 0000000..f74ce14 --- /dev/null +++ b/dumps/scripts/2918.cs2 @@ -0,0 +1,24 @@ +void script_2918(int arg0) { + int ivar1; + int ivar2; + ivar1 = 0; + ivar2 = 33; + if (((boolean)arg0)) { + return; + } + ivar2 = 30; + if (getWidgetActualHeight(new WidgetPointer(882,4)) < add(getWidgetActualHeight(new WidgetPointer(882,22)), 146)) { + setWidgetPosition(0, 0, 1, 1, new WidgetPointer(882,8)); + setWidgetPosition(0, add(getWidgetActualY(new WidgetPointer(882,8)), ivar2), 1, 0, new WidgetPointer(882,22)); + setWidgetIsHidden(true, new WidgetPointer(744,23)); + } else { + ivar1 = add(getWidgetActualY(new WidgetPointer(744,23)), getWidgetActualHeight(new WidgetPointer(744,23))); + setWidgetPosition(0, 0, 1, 1, new WidgetPointer(882,8)); + if (subtract(getWidgetActualY(new WidgetPointer(882,8)), 2) < ivar1) { + setWidgetPosition(0, add(ivar1, 2), 1, 0, new WidgetPointer(882,8)); + } + setWidgetPosition(0, add(getWidgetActualY(new WidgetPointer(882,8)), ivar2), 1, 0, new WidgetPointer(882,22)); + setWidgetIsHidden(false, new WidgetPointer(744,23)); + } + return; +} diff --git a/dumps/scripts/2919.cs2 b/dumps/scripts/2919.cs2 new file mode 100644 index 0000000..588ba40 --- /dev/null +++ b/dumps/scripts/2919.cs2 @@ -0,0 +1,23 @@ +void script_2919(int arg0,int arg1) { + int ivar2; + int stack_dump0; + int stack_dump1; + int stack_dump2; + cs2func_script_2692_struct(2,0,0) structdump_3; + cs2func_script_2692_struct(2,0,0) structdump_4; + ivar2 = cs2method6131(); + if (((boolean)arg0)) { + stack_dump0 = ivar2; + stack_dump1 = getDisplayMode(); + stack_dump2 = ivar2; + structdump_3 = script_2692(stack_dump2); + script_2596(stack_dump0, stack_dump1, structdump_3.intpart_0, structdump_3.intpart_1, arg1); + } else { + stack_dump0 = ivar2; + stack_dump1 = getDisplayMode(); + stack_dump2 = ivar2; + structdump_4 = script_2692(stack_dump2); + script_3387(stack_dump0, stack_dump1, structdump_4.intpart_0, structdump_4.intpart_1, arg1); + } + return; +} diff --git a/dumps/scripts/292.cs2 b/dumps/scripts/292.cs2 new file mode 100644 index 0000000..274656a --- /dev/null +++ b/dumps/scripts/292.cs2 @@ -0,0 +1,11 @@ +int script_292(int arg0,int arg1,int arg2,int arg3) { + if (arg0 == -1) { + arg0 = 280; + } + createExtraChild(new WidgetPointer(arg1), 5, getExtraChildGap(new WidgetPointer(arg1))); + setWidgetPosition(arg3, arg2, 2, 0); + setWidgetSize(20, 20, 0, 0); + cs2method1107(0); + setWidgetSprite(getOtherCommonData(arg0, 130)); + return add(arg3, 10); +} diff --git a/dumps/scripts/2920.cs2 b/dumps/scripts/2920.cs2 new file mode 100644 index 0000000..83f3c1c --- /dev/null +++ b/dumps/scripts/2920.cs2 @@ -0,0 +1,43 @@ +void script_2920(int arg0,int arg1,string arg2) { + openInterface(59375696, 914); + script_3181(); + if (strLength(arg2) > 0) { + globalstring_277 = strRemoveEntities(arg2); + } else { + globalstring_277 = ""; + } + setWidgetText(new WidgetPointer(914,27), globalstring_277); + if (isWidgetHidden(cs2method_3408(105, 73, 941, 5))) { + script_3161(0); + } + setScriptCallOnKeyPress(3185, -2147483640, false, new WidgetPointer(-32768,3), "izI", new WidgetPointer(914,27)); + setScriptCallOnClickContextMenu(3182, "", new WidgetPointer(914,16)); + globalint_1097 = strLength(globalstring_277); + setScriptCallOnMousePressed(1878, -2147483647, new WidgetPointer(914,27), new WidgetPointer(914,28), "iII", new WidgetPointer(914,27)); + script_1879(59899931, 59899932, globalstring_277); + setWidgetIsHidden(true, new WidgetPointer(914,28)); + if (((boolean)arg0)) { + if (((boolean)globalint_6)) { + setWidgetSprite(4084, new WidgetPointer(914,23)); + } else { + setWidgetSprite(4086, new WidgetPointer(914,23)); + } + if ((arg1 == 5) || (arg1 == 6)) { + setWidgetText(new WidgetPointer(914,22), "Suggest to mute this player for 48 hours"); + } else { + setWidgetText(new WidgetPointer(914,22), "Mute this player for 48 hours"); + } + setWidgetSize(add(getTextWidth(3793, getWidgetText(new WidgetPointer(914,22))), 18), getWidgetActualHeight(new WidgetPointer(914,21)), 0, 0, new WidgetPointer(914,21)); + setWidgetPosition(16, 32, 0, 0, new WidgetPointer(914,14)); + setWidgetPosition(21, 62, 0, 0, new WidgetPointer(914,15)); + setWidgetPosition(299, 60, 0, 0, new WidgetPointer(914,16)); + setWidgetIsHidden(false, new WidgetPointer(914,21)); + } else { + setWidgetPosition(16, 42, 0, 0, new WidgetPointer(914,14)); + setWidgetPosition(21, 82, 0, 0, new WidgetPointer(914,15)); + setWidgetPosition(299, 80, 0, 0, new WidgetPointer(914,16)); + setWidgetIsHidden(true, new WidgetPointer(914,21)); + } + setWidgetIsHidden(false, new WidgetPointer(906,45)); + return; +} diff --git a/dumps/scripts/2921.cs2 b/dumps/scripts/2921.cs2 new file mode 100644 index 0000000..5bf8bd6 --- /dev/null +++ b/dumps/scripts/2921.cs2 @@ -0,0 +1,103 @@ +void script_2921(int arg0,int arg1,string arg2) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + openInterface(59375670, 979); + globalstring_279 = arg2; + script_3397(); + if (isWidgetHidden(cs2method_3408(105, 73, 941, 5))) { + script_3161(0); + } + setScriptCallOnKeyPress(3398, -2147483640, false, new WidgetPointer(-32768,3), "izI", new WidgetPointer(979,0)); + setScriptCallOnClickContextMenu(3399, "", new WidgetPointer(979,9)); + ivar2 = 100; + ivar3 = 0; + ivar4 = 0; + ivar5 = 0; + deleteAllExtraChilds(new WidgetPointer(979,27)); + deleteAllExtraChilds(new WidgetPointer(979,26)); + deleteAllExtraChilds(new WidgetPointer(979,25)); + setWidgetScrollMax(0, 0, new WidgetPointer(979,27)); + cs2method2100(0, 0, new WidgetPointer(979,27)); + while (ivar2 >= 0) { + ivar4 = cs2method5004(ivar2); + if (((((ivar4 != 0) && (ivar4 != 4)) && ((ivar4 != 27) && (ivar4 != 28))) && (((ivar4 != 29) && (ivar4 != 43)) && ((ivar4 != 103) && (ivar4 != 104)))) && ((((ivar4 != 26) && (ivar4 != 30)) && ((ivar4 != 31) && (ivar4 != 115))) && ((stringMethod4107(cs2method5010(ivar2), "") != 0) && (stringMethod4107(cs2method5003(ivar2), "") != 0)))) { + if (((stringMethod4107(strRemoveEntities(cs2method5010(ivar2)), cs2method5015()) != 0) && (ivar4 != 6)) && (ivar4 != 19)) { + ivar5 = 1; + createExtraChild(new WidgetPointer(979,26), 3, getExtraChildGap(new WidgetPointer(979,26))); + setWidgetPosition(2, add(multiply(ivar3, 14), 1), 0, 0); + setWidgetSize(4, 14, 1, 0); + setWidgetRGB(new Color(96, 96, 96)); + cs2method2103(255); + setWidgetFilled(1); + setScriptCallOnMouseEntered(3392, -2147483643, "i"); + setScriptCallOnMouseExit(3393, -2147483643, "i"); + createExtraChild(new WidgetPointer(979,25), 3, getExtraChildGap(new WidgetPointer(979,25))); + setWidgetPosition(2, add(multiply(ivar3, 14), 1), 0, 0); + setWidgetSize(4, 14, 1, 0); + setWidgetRGB(new Color(73, 73, 73)); + cs2method2103(255); + setWidgetFilled(1); + setScriptCallOnMouseEntered(3394, -2147483643, "i"); + } + createExtraChild(new WidgetPointer(979,27), 4, getExtraChildGap(new WidgetPointer(979,27))); + setWidgetPosition(5, multiply(ivar3, 14), 0, 0); + setWidgetSize(10, 14, 1, 0); + if ((ivar4 != 6) && (ivar4 != 19)) { + setWidgetText(" " + cs2method5010(ivar2) + ": " + cs2method5003(ivar2)); + } else { + setWidgetText("To " + cs2method5010(ivar2) + ": " + cs2method5003(ivar2)); + } + setWidgetRGB(new Color(102, 102, 120)); + if (((stringMethod4107(strRemoveEntities(cs2method5010(ivar2)), cs2method5015()) != 0) && (ivar4 != 6)) && (ivar4 != 19)) { + cs2method1305(strRemoveEntities(cs2method5010(ivar2))); + setWidgetContextMenuOption(1, "Report"); + setScriptCallOnClickContextMenu(3396, -2147483643, "i"); + setWidgetRGB(new Color(255, 255, 255)); + } + setWidgetFont(495); + setWidgetTextAlignment(0, 0, 14); + ivar3 = add(ivar3, 1); + } + ivar2 = subtract(ivar2, 1); + } + if (((boolean)ivar5)) { + createExtraChild(new WidgetPointer(979,27), 4, getExtraChildGap(new WidgetPointer(979,27))); + setWidgetPosition(5, multiply(ivar3, 14), 0, 0); + setWidgetSize(16384, 14, 2, 0); + setWidgetText("There is no chat to report at the moment."); + setWidgetRGB(new Color(125, 125, 209)); + setWidgetFont(495); + setWidgetTextAlignment(0, 0, 14); + } + if (ivar3 > divide(getWidgetActualHeight(new WidgetPointer(979,5)), 14)) { + setWidgetSize(38, getWidgetActualHeight(new WidgetPointer(979,5)), 1, 0, new WidgetPointer(979,5)); + setWidgetScrollMax(0, add(multiply(ivar3, 14), 5), new WidgetPointer(979,24)); + script_31(64159750, 64159768, 792, 789, 790, 791, 773, 788); + if (setWidgetRegister(new WidgetPointer(979,6), 1)) { + script_37(64159750, 64159768, getWidgetScrollMaxV(new WidgetPointer(979,24)), 1); + } + } else { + setWidgetSize(21, getWidgetActualHeight(new WidgetPointer(979,5)), 1, 0, new WidgetPointer(979,5)); + } + if (((boolean)arg0)) { + if (((boolean)globalint_6)) { + setWidgetSprite(1768, new WidgetPointer(979,20)); + } else { + setWidgetSprite(1770, new WidgetPointer(979,20)); + } + if ((arg1 == 5) || (arg1 == 6)) { + setWidgetText(new WidgetPointer(979,19), "Suggest to mute this player for 48 hours"); + } else { + setWidgetText(new WidgetPointer(979,19), "Mute this player for 48 hours"); + } + setWidgetSize(add(getTextWidth(494, getWidgetText(new WidgetPointer(979,19))), 18), getWidgetActualHeight(new WidgetPointer(979,7)), 0, 0, new WidgetPointer(979,7)); + setWidgetPosition(18, 273, 0, 0, new WidgetPointer(979,8)); + setWidgetIsHidden(false, new WidgetPointer(979,7)); + } else { + setWidgetPosition(18, 266, 0, 0, new WidgetPointer(979,8)); + } + setWidgetIsHidden(false, new WidgetPointer(906,46)); + return; +} diff --git a/dumps/scripts/2922.cs2 b/dumps/scripts/2922.cs2 new file mode 100644 index 0000000..3d54b13 --- /dev/null +++ b/dumps/scripts/2922.cs2 @@ -0,0 +1,4 @@ +void script_2922() { + script_3391(); + return; +} diff --git a/dumps/scripts/2923.cs2 b/dumps/scripts/2923.cs2 new file mode 100644 index 0000000..60ea824 --- /dev/null +++ b/dumps/scripts/2923.cs2 @@ -0,0 +1,37 @@ +void script_2923(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + int ivar6; + if (standart_config_102 > 0) { + setWidgetSprite(1801, new WidgetPointer(arg2)); + setWidgetSprite(1801, new WidgetPointer(arg3)); + setWidgetIsHidden(true, new WidgetPointer(arg0)); + setWidgetIsHidden(false, new WidgetPointer(arg1)); + setWidgetContextMenuOption(1, new WidgetPointer(arg1), "Use cure (p)"); + } else if (standart_config_456 > 0) { + setWidgetSprite(1800, new WidgetPointer(arg2)); + setWidgetSprite(1800, new WidgetPointer(arg3)); + setWidgetIsHidden(true, new WidgetPointer(arg0)); + setWidgetIsHidden(false, new WidgetPointer(arg1)); + setWidgetContextMenuOption(1, new WidgetPointer(arg1), "Use cure (d)"); + } else { + setWidgetSprite(1208, new WidgetPointer(arg2)); + setWidgetSprite(1208, new WidgetPointer(arg3)); + setWidgetIsHidden(false, new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(arg1)); + setWidgetNoOptions(new WidgetPointer(arg1)); + } + setWidgetSize(0, subtract(16384, max(min(multiplyDivide(bitconfig_7198, script_2916(), 16384), 16384), 0)), 1, 2, new WidgetPointer(arg3)); + setWidgetSize(0, subtract(16384, max(min(multiplyDivide(script_2915(), script_2916(), 16384), 16384), 0)), 1, 2, new WidgetPointer(arg4)); + setWidgetText(new WidgetPointer(arg5), intToStr(bitconfig_7198)); + ivar6 = multiplyDivide(bitconfig_7198, script_2916(), 100); + if (ivar6 > 75) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(arg5)); + } else if (ivar6 > 50) { + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(arg5)); + } else if (ivar6 > 25) { + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(arg5)); + } else { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(arg5)); + } + script_2654(); + return; +} diff --git a/dumps/scripts/2924.cs2 b/dumps/scripts/2924.cs2 new file mode 100644 index 0000000..1a292f4 --- /dev/null +++ b/dumps/scripts/2924.cs2 @@ -0,0 +1,4 @@ +void script_2924(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + script_2925(arg0, arg1, arg2, arg3, arg4, arg5); + return; +} diff --git a/dumps/scripts/2925.cs2 b/dumps/scripts/2925.cs2 new file mode 100644 index 0000000..8241132 --- /dev/null +++ b/dumps/scripts/2925.cs2 @@ -0,0 +1,12 @@ +void script_2925(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + if (arg0 != -1) { + setWidgetSprite(arg1, new WidgetPointer(arg0)); + } + if (arg2 != -1) { + setWidgetSprite(arg3, new WidgetPointer(arg2)); + } + if (arg4 != -1) { + setWidgetSprite(arg5, new WidgetPointer(arg4)); + } + return; +} diff --git a/dumps/scripts/2926.cs2 b/dumps/scripts/2926.cs2 new file mode 100644 index 0000000..9f8974b --- /dev/null +++ b/dumps/scripts/2926.cs2 @@ -0,0 +1,4 @@ +void script_2926(int arg0,int arg1,int arg2,int arg3,string arg4) { + script_2927(arg0, arg1, arg2, arg3, arg4); + return; +} diff --git a/dumps/scripts/2927.cs2 b/dumps/scripts/2927.cs2 new file mode 100644 index 0000000..6b1b19d --- /dev/null +++ b/dumps/scripts/2927.cs2 @@ -0,0 +1,14 @@ +void script_2927(int arg0,int arg1,int arg2,int arg3,string arg4) { + if (arg0 != -1) { + if (((boolean)arg3)) { + setWidgetText(new WidgetPointer(arg1), "" + arg4 + ""); + setWidgetRGB(new Color(250, 250, 250), new WidgetPointer(arg1)); + setWidgetSize(getTextWidth(arg2, arg4), getWidgetActualHeight(new WidgetPointer(arg0)), 0, 0, new WidgetPointer(arg0)); + } else { + setWidgetText(new WidgetPointer(arg1), "" + arg4 + ""); + setWidgetRGB(new Color(200, 200, 200), new WidgetPointer(arg1)); + setWidgetSize(getTextWidth(arg2, arg4), getWidgetActualHeight(new WidgetPointer(arg0)), 0, 0, new WidgetPointer(arg0)); + } + } + return; +} diff --git a/dumps/scripts/2928.cs2 b/dumps/scripts/2928.cs2 new file mode 100644 index 0000000..56947dc --- /dev/null +++ b/dumps/scripts/2928.cs2 @@ -0,0 +1,4 @@ +void script_2928() { + script_304(50243054); + return; +} diff --git a/dumps/scripts/2929.cs2 b/dumps/scripts/2929.cs2 new file mode 100644 index 0000000..067577e --- /dev/null +++ b/dumps/scripts/2929.cs2 @@ -0,0 +1,4 @@ +void script_2929(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10) { + script_864(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + return; +} diff --git a/dumps/scripts/293.cs2 b/dumps/scripts/293.cs2 new file mode 100644 index 0000000..8c01ffe --- /dev/null +++ b/dumps/scripts/293.cs2 @@ -0,0 +1,32 @@ +void script_293(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + ivar3 = divide(add(arg1, arg2), 2); + ivar4 = globalarray_0[ivar3]; + globalarray_0[ivar3] = globalarray_0[arg2]; + globalarray_0[arg2] = ivar4; + ivar5 = arg1; + ivar6 = arg1; + ivar7 = 0; + while (ivar6 < arg2) { + if (stringMethod4107(lower(cs2method5207(cs2method_3408(105, 96, 708, globalarray_0[ivar6]))), lower(cs2method5207(cs2method_3408(105, 96, 708, ivar4)))) < bitAnd(ivar6, 1)) { + ivar7 = globalarray_0[ivar6]; + globalarray_0[ivar6] = globalarray_0[ivar5]; + globalarray_0[ivar5] = ivar7; + ivar5 = add(ivar5, 1); + } + ivar6 = add(ivar6, 1); + } + globalarray_0[arg2] = globalarray_0[ivar5]; + globalarray_0[ivar5] = ivar4; + if (arg1 < subtract(ivar5, 1)) { + script_293(0, arg1, subtract(ivar5, 1)); + } + if (add(ivar5, 1) < arg2) { + script_293(0, add(ivar5, 1), arg2); + } + return; +} diff --git a/dumps/scripts/2930.cs2 b/dumps/scripts/2930.cs2 new file mode 100644 index 0000000..d247f36 --- /dev/null +++ b/dumps/scripts/2930.cs2 @@ -0,0 +1,31 @@ +void script_2930(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9) { + int ivar10; + if (arg7 < arg8) { + arg7 = add(arg7, 1); + setScriptCallOnGameloop(2930, new WidgetPointer(arg0), arg1, arg2, new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), arg6, arg7, arg8, arg9, "I1iIIIiiii", new WidgetPointer(arg0)); + return; + } + ivar10 = getWidgetActualWidth(new WidgetPointer(arg0)); + if (((boolean)arg1)) { + if (subtract(ivar10, arg2) < arg6) { + setWidgetSize(min(add(ivar10, arg9), add(arg6, arg2)), 31, 0, 0, new WidgetPointer(arg0)); + } else { + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + setWidgetSize(add(arg6, arg2), 31, 0, 0, new WidgetPointer(arg0)); + } + setWidgetSprite(2569, new WidgetPointer(arg3)); + setWidgetSprite(2568, new WidgetPointer(arg4)); + setWidgetSprite(2568, new WidgetPointer(arg5)); + } else { + if (ivar10 > 32) { + setWidgetSize(max(subtract(ivar10, arg9), 32), 31, 0, 0, new WidgetPointer(arg0)); + } else { + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + setWidgetSize(32, 31, 0, 0, new WidgetPointer(arg0)); + } + setWidgetSprite(2567, new WidgetPointer(arg3)); + setWidgetSprite(2566, new WidgetPointer(arg4)); + setWidgetSprite(2566, new WidgetPointer(arg5)); + } + return; +} diff --git a/dumps/scripts/2931.cs2 b/dumps/scripts/2931.cs2 new file mode 100644 index 0000000..2bf28cd --- /dev/null +++ b/dumps/scripts/2931.cs2 @@ -0,0 +1,4 @@ +void script_2931(int arg0,string arg1,string arg2) { + script_2932(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/2932.cs2 b/dumps/scripts/2932.cs2 new file mode 100644 index 0000000..c984cf7 --- /dev/null +++ b/dumps/scripts/2932.cs2 @@ -0,0 +1,6 @@ +void script_2932(int arg0,string arg1,string arg2) { + if ((stringMethod4107(arg1, "") != 0) && (stringMethod4107(arg2, "") != 0)) { + cs2method5421(arg0, "loginapplet/loginapplet.ws?ssl=1&expired=0&mod=" + arg1 + "&dest=" + arg2); + } + return; +} diff --git a/dumps/scripts/2933.cs2 b/dumps/scripts/2933.cs2 new file mode 100644 index 0000000..ec68c23 --- /dev/null +++ b/dumps/scripts/2933.cs2 @@ -0,0 +1,4 @@ +void script_2933(int arg0,string arg1) { + script_2934(arg0, arg1); + return; +} diff --git a/dumps/scripts/2934.cs2 b/dumps/scripts/2934.cs2 new file mode 100644 index 0000000..b87e914 --- /dev/null +++ b/dumps/scripts/2934.cs2 @@ -0,0 +1,6 @@ +void script_2934(int arg0,string arg1) { + if (stringMethod4107(arg1, "") != 0) { + cs2method5421(arg0, arg1); + } + return; +} diff --git a/dumps/scripts/2935.cs2 b/dumps/scripts/2935.cs2 new file mode 100644 index 0000000..6c4a074 --- /dev/null +++ b/dumps/scripts/2935.cs2 @@ -0,0 +1,4 @@ +void script_2935(int arg0) { + script_2936(arg0); + return; +} diff --git a/dumps/scripts/2936.cs2 b/dumps/scripts/2936.cs2 new file mode 100644 index 0000000..c57e5c8 --- /dev/null +++ b/dumps/scripts/2936.cs2 @@ -0,0 +1,16 @@ +void script_2936(int arg0) { + if (((boolean)cs2method5420())) { + globalint_547 = arg0; + script_2940(11); + setWidgetIsHidden(true, new WidgetPointer(744,28)); + if (hasSSKey()) { + setWidgetIsHidden(false, new WidgetPointer(744,27)); + } else { + setWidgetIsHidden(false, new WidgetPointer(744,26)); + } + if (((boolean)globalint_547)) { + script_2945(); + } + } + return; +} diff --git a/dumps/scripts/2937.cs2 b/dumps/scripts/2937.cs2 new file mode 100644 index 0000000..fc8c1bd --- /dev/null +++ b/dumps/scripts/2937.cs2 @@ -0,0 +1,17 @@ +void script_2937() { + globalint_1089 = -1; + setWidgetSprite(4066, new WidgetPointer(596,35)); + setWidgetSprite(4066, new WidgetPointer(596,34)); + setWidgetSprite(4065, new WidgetPointer(596,32)); + setWidgetSprite(4065, new WidgetPointer(596,33)); + setWidgetSprite(4065, new WidgetPointer(596,20)); + setWidgetVFlip(1, new WidgetPointer(596,20)); + setWidgetHFlip(1, new WidgetPointer(596,20)); + setWidgetSprite(4065, new WidgetPointer(596,24)); + setWidgetVFlip(1, new WidgetPointer(596,24)); + setWidgetHFlip(0, new WidgetPointer(596,24)); + setWidgetSprite(4065, new WidgetPointer(596,21)); + setWidgetSprite(4065, new WidgetPointer(596,25)); + setScriptCallOnGameloop(4700, "", new WidgetPointer(744,17)); + return; +} diff --git a/dumps/scripts/2938.cs2 b/dumps/scripts/2938.cs2 new file mode 100644 index 0000000..0e3b322 --- /dev/null +++ b/dumps/scripts/2938.cs2 @@ -0,0 +1,20 @@ +void script_2938() { + if (((boolean)globalint_1199)) { + setWidgetText(new WidgetPointer(933,267), globalstring_311); + setWidgetText(new WidgetPointer(933,268), cs2method_3408(105, 115, 2857, globalint_1209)); + setWidgetText(new WidgetPointer(933,269), cs2method_3408(105, 115, 2857, globalint_1210)); + setWidgetText(new WidgetPointer(933,270), cs2method_3408(105, 115, 2857, globalint_1211)); + setWidgetText(new WidgetPointer(933,271), cs2method_3408(105, 115, 2857, globalint_1212)); + setWidgetText(new WidgetPointer(933,272), cs2method_3408(105, 115, 2857, globalint_1213)); + setWidgetText(new WidgetPointer(933,273), cs2method_3408(105, 115, 2857, globalint_1214)); + } else { + setWidgetText(new WidgetPointer(933,267), ""); + setWidgetText(new WidgetPointer(933,268), ""); + setWidgetText(new WidgetPointer(933,269), ""); + setWidgetText(new WidgetPointer(933,270), ""); + setWidgetText(new WidgetPointer(933,271), ""); + setWidgetText(new WidgetPointer(933,272), ""); + setWidgetText(new WidgetPointer(933,273), ""); + } + return; +} diff --git a/dumps/scripts/2939.cs2 b/dumps/scripts/2939.cs2 new file mode 100644 index 0000000..dfdf793 --- /dev/null +++ b/dumps/scripts/2939.cs2 @@ -0,0 +1,6 @@ +void script_2939() { + if (((boolean)globalint_1199)) { + setWidgetText(new WidgetPointer(933,267), globalstring_311); + } + return; +} diff --git a/dumps/scripts/294.cs2 b/dumps/scripts/294.cs2 new file mode 100644 index 0000000..7225ab0 --- /dev/null +++ b/dumps/scripts/294.cs2 @@ -0,0 +1,18 @@ +void script_294(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + playSoundEffect(2266, 1, 0); + arg0 = script_2785(arg0); + if (arg0 == cs2method5235()) { + script_291(0, arg1, arg2, arg3, arg4, arg5); + return; + } + globalstring_31 = ""; + script_308(arg4); + script_2046(arg5); + script_41(49479737); + loadDungeonmap(arg0); + globalint_172 = cs2method5218(arg0); + script_1372(); + script_307(); + script_291(0, arg1, arg2, arg3, arg4, arg5); + return; +} diff --git a/dumps/scripts/2940.cs2 b/dumps/scripts/2940.cs2 new file mode 100644 index 0000000..a17717f --- /dev/null +++ b/dumps/scripts/2940.cs2 @@ -0,0 +1,36 @@ +void script_2940(int arg0) { + int ivar1; + flow_0: + ivar1 = script_2948(); + IF (ivar1 == -3) + GOTO flow_1 + GOTO flow_2 + flow_1: + IF (arg0 != 13) + GOTO flow_3 + flow_2: + IF ((ivar1 == 21) || ((boolean)ivar1)) + GOTO flow_3 + GOTO flow_4 + flow_3: + return; + flow_4: + setWidgetText(new WidgetPointer(596,73), globalstring_32); + setWidgetText(new WidgetPointer(596,79), script_2949(globalstring_33)); + if (strLength(globalstring_32) > 0) { + globalint_174 = 4; + } else { + globalint_174 = 3; + } + if (globalint_174 == 3) { + globalint_1099 = strLength(globalstring_32); + script_3237(39059528, 39059529, 39059530, 3, globalstring_32); + } else { + globalint_1099 = strLength(script_2949(globalstring_33)); + script_3237(39059534, 39059535, 39059536, 4, script_2949(globalstring_33)); + } + setWidgetIsHidden(false, new WidgetPointer(744,26)); + setWidgetIsHidden(false, new WidgetPointer(596,6)); + script_3964(); + return; +} diff --git a/dumps/scripts/2941.cs2 b/dumps/scripts/2941.cs2 new file mode 100644 index 0000000..f98de42 --- /dev/null +++ b/dumps/scripts/2941.cs2 @@ -0,0 +1,7 @@ +void script_2941() { + setScriptCallOnWidgetResize(-1, "", new WidgetPointer(744,26)); + globalstring_33 = ""; + globalint_1099 = 0; + resetRCs(); + return; +} diff --git a/dumps/scripts/2942.cs2 b/dumps/scripts/2942.cs2 new file mode 100644 index 0000000..a0aa199 --- /dev/null +++ b/dumps/scripts/2942.cs2 @@ -0,0 +1,4 @@ +void script_2942() { + script_2276(globalint_1199, globalint_1209, 61145356); + return; +} diff --git a/dumps/scripts/2943.cs2 b/dumps/scripts/2943.cs2 new file mode 100644 index 0000000..96581d8 --- /dev/null +++ b/dumps/scripts/2943.cs2 @@ -0,0 +1,4 @@ +void script_2943(int arg0) { + globalint_174 = arg0; + return; +} diff --git a/dumps/scripts/2944.cs2 b/dumps/scripts/2944.cs2 new file mode 100644 index 0000000..7a889dc --- /dev/null +++ b/dumps/scripts/2944.cs2 @@ -0,0 +1,4 @@ +void script_2944() { + script_2945(); + return; +} diff --git a/dumps/scripts/2945.cs2 b/dumps/scripts/2945.cs2 new file mode 100644 index 0000000..274898c --- /dev/null +++ b/dumps/scripts/2945.cs2 @@ -0,0 +1,65 @@ +void script_2945() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + string svar0; + string svar1; + globalint_1100 = -1; + if (hasSSKey() && (((boolean)strLength(globalstring_32)) || ((boolean)strLength(globalstring_33)))) { + script_2940(11); + return; + } + ivar0 = 0; + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + if ((((boolean)cs2method5420()) && ((boolean)script_2727())) && ((boolean)globalint_547)) { + globalint_174 = 12; + setWidgetIsHidden(false, new WidgetPointer(744,28)); + playMusicEffect(349, 0); + script_3412(48758826, 48758827); + ivar2 = getWidgetActualWidth(new WidgetPointer(744,43)); + ivar3 = getWidgetActualWidth(new WidgetPointer(744,43)); + ivar0 = max(337, add(getTextWidth(591, getWidgetText(new WidgetPointer(744,42))), 31)); + ivar3 = max(152, multiply(getLineCount(ivar2, 496, getWidgetText(new WidgetPointer(744,43))), 16)); + ivar1 = max(252, add(ivar3, 100)); + setWidgetSize(ivar2, ivar3, 0, 0, new WidgetPointer(744,43)); + setWidgetSize(ivar0, ivar1, 0, 0, new WidgetPointer(744,28)); + setWidgetIsHidden(true, new WidgetPointer(744,26)); + setWidgetIsHidden(true, new WidgetPointer(744,27)); + return; + } + globalint_200 = 0; + globalint_201 = 0; + ivar4 = 39059516; + ivar5 = 39059501; + if (hasSSKey()) { + ivar4 = 63897649; + ivar5 = 63897644; + } + setWidgetText(new WidgetPointer(ivar4), "Logging in..."); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(ivar5)); + script_2950(-3, 0, 1, -1, 0, -1, 0, "Logging In - Please Wait", "", ""); + setWidgetIsHidden(true, new WidgetPointer(596,9)); + globalint_1100 = -3; + svar0 = globalstring_32; + svar1 = globalstring_33; + if (hasSSKey()) { + svar0 = ""; + svar1 = ""; + } + if (((boolean)cs2method5420())) { + directlogin(0, svar0, svar1); + } else { + setUserAndPass(svar0, svar1); + } + if (hasSSKey()) { + setScriptCallOnGameloop(2946, 0, "i", new WidgetPointer(975,26)); + } else { + setScriptCallOnGameloop(2946, 0, "i", new WidgetPointer(596,7)); + } + return; +} diff --git a/dumps/scripts/2946.cs2 b/dumps/scripts/2946.cs2 new file mode 100644 index 0000000..df797c6 --- /dev/null +++ b/dumps/scripts/2946.cs2 @@ -0,0 +1,375 @@ +void script_2946(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + string svar0; + string svar1; + string svar2; + string svar3; + string svar4; + ivar1 = script_2948(); + ivar2 = 39059516; + ivar3 = 39059515; + ivar4 = 39059501; + ivar5 = 39059463; + if (hasSSKey()) { + ivar2 = 63897649; + ivar4 = 63897644; + ivar5 = 63897626; + } + if (ivar1 == 42) { + setWidgetSprite(6297, new WidgetPointer(744,97)); + setWidgetIsHidden(false, new WidgetPointer(744,103)); + setWidgetText(new WidgetPointer(744,130), intToStr(getWorldId())); + setWidgetText(new WidgetPointer(744,131), intToStr(getReturncode42ExtraData())); + globalint_1100 = 42; + return; + } + if (ivar1 == 43) { + setWidgetText(new WidgetPointer(744,130), intToStr(getWorldId())); + setWidgetText(new WidgetPointer(744,131), intToStr(getReturncode42ExtraData())); + globalint_1100 = 43; + return; + } + setWidgetIsHidden(true, new WidgetPointer(744,103)); + setWidgetSprite(4129, new WidgetPointer(744,97)); + if (ivar1 == -3) { + setWidgetText(new WidgetPointer(ivar2), "Logging in..."); + setWidgetText(new WidgetPointer(ivar3), "Logging in..."); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(ivar4)); + script_2950(ivar1, 0, 1, -1, 0, -1, 0, "Logging In - Please Wait", "", ""); + globalint_1100 = -3; + return; + } + if (globalint_1100 == -3) { + script_2954(); + } + ivar6 = 0; + svar0 = ""; + if (ivar1 == 21) { + globalint_1100 = 21; + setWidgetText(new WidgetPointer(ivar2), "Logging in..."); + setWidgetText(new WidgetPointer(ivar3), "Logging in..."); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(ivar4)); + if (((boolean)globalint_200)) { + globalint_200 = getWorldswitchTimer(); + } + globalint_200 = subtract(globalint_200, 1); + if (globalint_200 <= 0) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(ivar4)); + if (((boolean)arg0)) { + script_2945(); + } else { + script_4634(arg0); + } + return; + } + ivar6 = divide(globalint_200, 50); + if (((boolean)ivar6)) { + svar0 = "You have only just left another world. Your profile will be transferred in" + "
" + "1 second."; + } else { + svar0 = "You have only just left another world. Your profile will be transferred in" + "
" + intToStr(ivar6) + " seconds."; + } + if (isWidgetHidden(new WidgetPointer(ivar5))) { + script_2950(ivar1, 0, 0, 2611, 1, 1, 0, svar0, "Abort Login", ""); + } else { + script_3233(svar0); + } + return; + } + script_2954(); + ivar7 = 0; + svar1 = ""; + if (((boolean)ivar1)) { + flow_27: + setWidgetText(new WidgetPointer(ivar2), "Logging in..."); + setWidgetText(new WidgetPointer(ivar3), "Logging in..."); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(ivar4)); + if (((boolean)globalint_201)) { + globalint_202 = ((int)canShowVideoAd()); + } + ivar7 = divide(subtract(500, globalint_201), 50); + if (((boolean)globalint_202)) { + if (((boolean)ivar7)) { + svar1 = "Could not display video advertisement. Login will continue in 1 second."; + } else { + svar1 = "Could not display video advertisement. Login will continue in " + intToStr(ivar7) + " seconds"; + } + } else if (globalint_201 < 500) { + if (((boolean)ivar7)) { + svar1 = "Displaying video advertisement. Login will continue in 1 second."; + } else { + svar1 = "Displaying video advertisement. Login will continue in " + intToStr(ivar7) + " seconds."; + } + } else { + svar1 = "Displaying video advertisement. Login will continue in 0 seconds."; + } + script_2950(ivar1, 0, 0, 2611, 0, -1, 0, svar1, "", ""); + globalint_201 = add(globalint_201, 1); + IF (((boolean)globalint_202)) + GOTO flow_41 + GOTO flow_42 + flow_41: + IF (isShowingVideoAd()) + GOTO flow_43 + flow_42: + IF (globalint_201 < 500) + GOTO flow_43 + GOTO flow_44 + flow_43: + return; + flow_44: + script_2954(); + skipLoginstage10(); + return; + } + script_2954(); + if (hasSSKey()) { + setWidgetText(new WidgetPointer(ivar2), "Play Game"); + setWidgetText(new WidgetPointer(ivar3), "Play Game"); + } else { + setWidgetText(new WidgetPointer(ivar2), "Log In"); + setWidgetText(new WidgetPointer(ivar3), "Log In"); + } + setScriptCallOnMousePressed(2944, "", new WidgetPointer(ivar4)); + if (hasSSKey()) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(975,26)); + } else { + setScriptCallOnGameloop(-1, "", new WidgetPointer(596,7)); + } + svar2 = ""; + ivar8 = 1; + ivar9 = 0; + ivar10 = 2608; + ivar11 = 0; + ivar12 = 0; + svar3 = ""; + ivar13 = 1; + svar4 = "Back"; + switch (ivar1) { + case -2: + script_2954(); + if (hasSSKey()) { + return; + } + script_2940(11); + return; + case 29: + switch (getDetailedRC()) { + case 0: + svar2 = "You must have a Combat Level of at least 20 (not including Summoning) to enter a PvP world."; + break; + case 1: + svar2 = "You are currently carrying lent items and cannot enter a PvP world."; + break; + case 2: + svar2 = "You must be standing in the Wilderness or Edgeville to enter this bounty world."; + break; + case 3: + svar2 = "You must have a total skill level of 1,000 or greater to enter this world."; + break; + case 5: + svar2 = "You must have a total skill level of 1,500 or greater to enter this world."; + break; + case 4: + svar2 = "You must move to a safe area before you can log in to a PvP or bounty world."; + break; + default: + svar2 = "Unexpected server response. Please try using a different world."; + } + break; + case 46: + svar2 = "This instance is marked for deletion/rebuild. Please try using a different world."; + break; + case 45: + switch (getReturncodeExtraData()) { + case 0: + switch (getDetailedRC()) { + case 0: + svar2 = "You must be near the TzHaar Fight Pits entrance to enter a global match."; + break; + default: + svar2 = "Unable to log in. Please try using a different world."; + } + break; + case 1: + switch (getDetailedRC()) { + case 1: + svar2 = "There was an error connecting to your meeting room. Please try again."; + break; + case 2: + svar2 = "You need a higher rank to enter that private tent."; + break; + case 3: + svar2 = "You need an invitation to enter that private room."; + break; + default: + svar2 = "Unable to log in. Please try using a different world."; + } + break; + default: + svar2 = "Unexpected server response. Please try using a different world."; + } + break; + case -5: + svar2 = "Connection timed out. Please try using a different world."; + break; + case -4: + svar2 = "Error connecting to server."; + break; + case -1: + svar2 = "No response from server. Please try using a different world."; + break; + case 5: + svar2 = "Your account has not logged out from its last session. Try again in a few minutes."; + break; + case 7: + svar2 = "This world is full. Please use a different world."; + break; + case 8: + svar2 = "Unable to connect: login server offline."; + break; + case 9: + svar2 = "Login limit exceeded: too many connections from your address."; + break; + case 10: + svar2 = "Unable to connect: bad session id."; + break; + case 13: + svar2 = "Could not complete login. Please try using a different world."; + break; + case 16: + svar2 = "Too many incorrect logins from your address. Please wait 5 minutes before trying again."; + break; + case 17: + svar2 = "You are standing in a members-only area. To play on this world, move to a free area first."; + break; + case 20: + svar2 = "Invalid loginserver requested. Please try using a different world."; + break; + case 22: + svar2 = "Malformed login packet. Please try again."; + break; + case 23: + svar2 = "No reply from login server. Please wait a minute and try again."; + break; + case 24: + svar2 = "Error loading your profile. Please contact customer support."; + break; + case 25: + svar2 = "Unexpected loginserver response. Please try using a different world."; + break; + case 26: + svar2 = "This computer's address has been blocked, as it was used to break our rules."; + break; + case 27: + svar2 = "Service unavailable."; + break; + case 36: + svar2 = "Unable to connect: authentication server offline."; + break; + case 37: + svar2 = "Your account is currently inaccessible. Please try again in a few minutes."; + break; + case 39: + svar2 = "The instance you tried to join no longer exists. Please try using a different world."; + break; + case 41: + svar2 = "The instance you tried to join is full. Please try back later or try using a different world."; + break; + case 44: + svar2 = "Our systems are currently unavailable. Please try again in a few minutes."; + break; + case 35: + svar2 = "Your session has expired. Please click 'Back' in your browser to renew it."; + svar4 = "Close"; + break; + case 14: + ivar8 = 0; + ivar10 = 2610; + svar2 = "The server is being updated. Please wait a few minutes and try again."; + break; + case 6: + ivar8 = 0; + ivar10 = 2610; + svar2 = "RuneScape has been updated! Please reload this page."; + break; + case 3: + if (((boolean)globalint_1414)) { + svar2 = "Invalid username or password." + "
" + "
" + "For accounts created after the 24th of November 2010, please use your email address to login. Otherwise please login with your username."; + } else if (globalint_1414 == 2) { + svar2 = "Invalid email or password." + "
" + "
" + "For accounts created after the 24th of November 2010, please use your email address to login. Otherwise please login with your username."; + } else { + svar2 = "Invalid login or password." + "
" + "
" + "For accounts created after the 24th of November 2010, please use your email address to login. Otherwise please login with your username."; + } + svar4 = "Try Again"; + ivar11 = 1; + svar3 = "Forgotten your password?"; + break; + case 4: + svar2 = "Your account has been disabled. Check your message centre for details."; + ivar11 = 1; + svar3 = "Message Centre"; + break; + case 11: + svar2 = "Your password is an extremely common choice, and is not secure. You must change it before you can login."; + ivar11 = 1; + svar3 = "Change Password"; + break; + case 18: + ivar10 = 2612; + svar2 = "Your account has been locked. If you have not received an account recovery email, please select 'Recover Account'."; + ivar11 = 1; + svar3 = "Recover Account"; + break; + case 30: + svar2 = "This is not a member's account; please choose a 'free' world from the website to play on this account."; + ivar11 = 1; + if (((boolean)cs2method5420())) { + svar3 = "Choose World"; + } else { + svar3 = "Subscribe"; + } + break; + case 31: + svar2 = "You must change your account's display name before you can login."; + ivar11 = 1; + svar3 = "Change Display Name"; + break; + case 19: + svar2 = "Fullscreen is currently a members-only feature. To log in, exit fullscreen via the options menu or use a member's account."; + ivar11 = 1; + svar3 = "Subscribe"; + break; + case 12: + svar2 = "You need a member's account to log in to this world. Please subscribe or use a different world."; + ivar11 = 1; + svar3 = "Subscribe"; + break; + case 40: + svar2 = "You need a member's account to log in to this world. Please subscribe or use a different world."; + ivar11 = 1; + svar3 = "Subscribe"; + break; + case 32: + svar2 = "Your account has negative membership credit. Please log into the billing system to add credit to your account."; + ivar11 = 1; + svar3 = "Add Credit"; + break; + default: + svar2 = "Unexpected server response. Please try using a different world."; + } + script_2950(ivar1, ivar8, ivar9, ivar10, ivar11, ivar12, ivar13, svar2, svar3, svar4); + resetRCs(); + return; +} diff --git a/dumps/scripts/2947.cs2 b/dumps/scripts/2947.cs2 new file mode 100644 index 0000000..cbbabf4 --- /dev/null +++ b/dumps/scripts/2947.cs2 @@ -0,0 +1,11 @@ +void script_2947() { + globalstring_321 = ""; + globalstring_322 = ""; + globalstring_323 = ""; + globalstring_324 = ""; + globalstring_325 = ""; + setWidgetIsHidden(true, new WidgetPointer(667,52)); + setWidgetIsHidden(true, new WidgetPointer(670,1)); + setWidgetIsHidden(true, new WidgetPointer(763,3)); + return; +} diff --git a/dumps/scripts/2948.cs2 b/dumps/scripts/2948.cs2 new file mode 100644 index 0000000..3099796 --- /dev/null +++ b/dumps/scripts/2948.cs2 @@ -0,0 +1,6 @@ +int script_2948() { + if (((boolean)cs2method5420())) { + return getGameloginRc(); + } + return getLobbyRC(); +} diff --git a/dumps/scripts/2949.cs2 b/dumps/scripts/2949.cs2 new file mode 100644 index 0000000..3503eaa --- /dev/null +++ b/dumps/scripts/2949.cs2 @@ -0,0 +1,10 @@ +string script_2949(string arg0) { + int ivar0; + ivar0 = strLength(arg0); + arg0 = ""; + while (ivar0 > 0) { + arg0 = arg0 + "*"; + ivar0 = subtract(ivar0, 1); + } + return arg0; +} diff --git a/dumps/scripts/295.cs2 b/dumps/scripts/295.cs2 new file mode 100644 index 0000000..aec63ba --- /dev/null +++ b/dumps/scripts/295.cs2 @@ -0,0 +1,266 @@ +void script_295(int arg0,int arg1,int arg2,int arg3,int arg4) { + int ivar5; + if (cs2method5229()) { + deleteAllExtraChilds(new WidgetPointer(arg0)); + return; + } + ivar5 = 0; + switch (cs2method5235()) { + case 31: + ivar5 = script_297(589620541, 52864326, 0, 16776960, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + break; + case 1: + ivar5 = script_297(39325979, 38474018, 0, 16776960, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + break; + case 26: + ivar5 = script_300(143, 1, 280, arg0, arg1, arg2, arg3, arg4, ivar5, "Lower level"); + ivar5 = script_300(1573071, 1, 280, arg0, arg1, arg2, arg3, arg4, ivar5, "Middle level"); + ivar5 = script_300(3145999, 1, 280, arg0, arg1, arg2, arg3, arg4, ivar5, "Upper level"); + ivar5 = script_297(44831902, 313267358, 0, 16776960, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(44618924, 313070764, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(44324084, 312759540, 0, 65535, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(44225744, 312661200, 0, 16711680, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(44569840, 313005296, 0, 65280, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(44750053, 313185509, 0, 32767, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(44881101, 313316557, 0, 16776960, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(44733625, 313169081, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(44618896, 313070736, 0, 65535, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(44274873, 312710329, 0, 16711680, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(313283821, 581719277, 0, 16776960, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(312694002, 581129458, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(312612023, 581047479, 0, 65535, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(312628396, 581063852, 0, 16711680, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(313037957, 581473413, 0, 65280, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(313349258, 581784714, 0, 32767, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(313332908, 581768364, 0, 16776960, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + break; + case 21: + ivar5 = script_298(46524306, 46491549, 0, 16711680, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_298(46786463, 46835605, 0, 16711680, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(46589842, 47310831, 0, 16776960, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(46507915, 45557681, 0, 65535, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + break; + case 20: + ivar5 = script_297(594388249, 57517334, 0, 16711680, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + break; + case 25: + ivar5 = script_297(50079065, 50079060, 0, 16711680, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + break; + case 3: + ivar5 = script_298(42575123, 42591571, 0, 16776960, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_298(42247537, 42067252, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_298(42263852, 42247532, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(42951961, 42935643, 0, 65535, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(42870115, 42870048, 0, 32767, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(42247458, 42149154, 0, 32767, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + break; + case 14: + ivar5 = script_297(41101361, 41199667, 0, 16776960, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + break; + case 2: + ivar5 = script_297(583460733, 315025277, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(583460675, 315025219, 0, 16711680, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(315189070, 46753614, 0, 16776960, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(315172731, 46737275, 0, 65535, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_300(79, 1, 280, arg0, arg1, arg2, arg3, arg4, ivar5, "Lower level"); + ivar5 = script_300(1572943, 1, 280, arg0, arg1, arg2, arg3, arg4, ivar5, "Middle level"); + ivar5 = script_300(3145807, 1, 280, arg0, arg1, arg2, arg3, arg4, ivar5, "Upper level"); + break; + case 6: + ivar5 = script_297(50259980, 37212744, 0, 32767, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(41669235, 41112143, 0, 16776960, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + break; + case 24: + ivar5 = script_300(524464, 1, 280, arg0, arg1, arg2, arg3, arg4, ivar5, "War"); + ivar5 = script_298(30528630, 31364198, 0, 32767, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_298(30823536, 30463099, 0, 32767, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(31167590, 33461373, 0, 32767, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_300(1966240, 1, 280, arg0, arg1, arg2, arg3, arg4, ivar5, "Famine"); + ivar5 = script_298(33412216, 33117287, 0, 16711680, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_298(33051738, 33461373, 0, 16711680, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_298(33428568, 33461373, 0, 16711680, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_298(32953416, 33461373, 0, 16711680, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_298(33281093, 33461373, 0, 16711680, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(33199202, 34788484, 0, 16711680, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_300(655448, 1, 280, arg0, arg1, arg2, arg3, arg4, ivar5, "Pestilence"); + ivar5 = script_298(34739338, 35165351, 0, 16711807, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_298(35230878, 34788484, 0, 16711807, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(35198115, 38638687, 0, 16711807, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_300(2097224, 1, 280, arg0, arg1, arg2, arg3, arg4, ivar5, "Death"); + ivar5 = script_298(38753372, 38360163, 0, 65280, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + break; + case 9: + ivar5 = script_300(1573096, 1, 280, arg0, arg1, arg2, arg3, arg4, ivar5, "Jail"); + ivar5 = script_300(524432, 1, 280, arg0, arg1, arg2, arg3, arg4, ivar5, "Lower level"); + ivar5 = script_300(1704080, 1, 280, arg0, arg1, arg2, arg3, arg4, ivar5, "Middle level"); + ivar5 = script_300(2883728, 1, 280, arg0, arg1, arg2, arg3, arg4, ivar5, "Upper level"); + ivar5 = script_300(1704000, 1, 280, arg0, arg1, arg2, arg3, arg4, ivar5, "Secure sector"); + ivar5 = script_297(50417803, 588304518, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(588533912, 320098456, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(588828849, 857280689, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(588943533, 52072618, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(319901872, 51482798, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + break; + case 15: + ivar5 = script_297(584602804, 316167348, 0, 16711680, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(316282011, 47846554, 0, 16711680, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(584127643, 46781541, 0, 16711680, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + break; + case 13: + ivar5 = script_300(524488, 1, 280, arg0, arg1, arg2, arg3, arg4, ivar5, "Upper level"); + ivar5 = script_297(43410808, 580199803, 0, 16711680, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(43197740, 580068647, 0, 16711680, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + break; + case 22: + ivar5 = script_297(55354521, 54399220, 0, 16711680, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(55354579, 54399245, 0, 16711680, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(54748371, 53727504, 0, 16711680, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(54748313, 53645556, 0, 16711680, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + break; + case 16: + ivar5 = script_300(524810, 1, 280, arg0, arg1, arg2, arg3, arg4, ivar5, "Sub-level 1"); + ivar5 = script_297(41740191, 834769206, 0, 16776960, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_300(1573291, 1, 280, arg0, arg1, arg2, arg3, arg4, ivar5, "Sub-level 2"); + ivar5 = script_297(834949429, 566513973, 0, 16711680, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(835178804, 566743348, 0, 16711680, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(835359013, 566923557, 0, 16711680, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(835195165, 566759709, 0, 16711680, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(835424536, 566989080, 0, 16711680, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(837439784, 569004328, 0, 16711680, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_300(1573194, 1, 280, arg0, arg1, arg2, arg3, arg4, ivar5, "Sub-level 3"); + ivar5 = script_297(566530346, 298094890, 0, 8323327, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(566350115, 297914659, 0, 8323327, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(566333726, 297898270, 0, 8323327, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(566399249, 297963793, 0, 8323327, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(566792458, 298357002, 0, 8323327, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(567185697, 298750241, 0, 8323327, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(567415076, 298979620, 0, 8323327, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(567398676, 298963220, 0, 8323327, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(568529179, 300093723, 0, 8323327, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_300(1573099, 1, 280, arg0, arg1, arg2, arg3, arg4, ivar5, "Sub-level 4"); + ivar5 = script_297(299405624, 30970168, 0, 16744192, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(300503316, 32067860, 0, 16744192, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_300(2621578, 1, 280, arg0, arg1, arg2, arg3, arg4, ivar5, "Sub-level 5"); + ivar5 = script_297(31314191, 47501665, 0, 16711680, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_300(3473463, 1, 280, arg0, arg1, arg2, arg3, arg4, ivar5, "Sub-level 6"); + break; + case 30: + ivar5 = script_300(524402, 1, 280, arg0, arg1, arg2, arg3, arg4, ivar5, "Lower level"); + ivar5 = script_300(2097240, 1, 280, arg0, arg1, arg2, arg3, arg4, ivar5, "Middle level"); + ivar5 = script_300(3670104, 1, 280, arg0, arg1, arg2, arg3, arg4, ivar5, "Upper level"); + ivar5 = script_297(51827152, 51827157, 0, 16711680, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(51696079, 51794383, 0, 16711680, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(319902165, 588337616, 0, 16744192, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(588386779, 319951318, 0, 16744192, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(319951334, 588386785, 0, 16744192, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(51630567, 319984103, 0, 32512, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(51876321, 51794401, 0, 16711680, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(52171227, 320606678, 0, 32512, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(320606697, 52171235, 0, 32512, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(51941857, 320459233, 0, 32512, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(320442833, 52089297, 0, 32512, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(320786911, 52351450, 0, 32512, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(589124065, 320770529, 0, 16744192, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(320639465, 589074914, 0, 16744192, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(51909098, 51909091, 0, 16711680, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(320229869, 51876333, 0, 32512, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(51532274, 319967725, 0, 32512, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(51778038, 51597814, 0, 16711680, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(51909104, 51909109, 0, 16711680, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(320066037, 320131573, 0, 16711680, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(320524790, 320459254, 0, 16711680, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(51564996, 319951300, 0, 32512, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(51745225, 320180684, 0, 32512, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(51909081, 320393689, 0, 32512, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(52171209, 320606668, 0, 32512, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(52269558, 320754166, 0, 32512, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(319902151, 588337610, 0, 16744192, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(320180692, 588616151, 0, 16744192, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(320492001, 588976609, 0, 16744192, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(52187642, 51597859, 0, 16711680, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(51597875, 51597879, 0, 16711680, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + break; + case 23: + ivar5 = script_297(52335986, 52286839, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(52286826, 52188518, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(52204896, 52303200, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(52254020, 52221268, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(52073812, 51909968, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(51696969, 51500355, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(51680598, 51483990, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(51893599, 51959137, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(51959142, 51893606, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(51467624, 51484017, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(53155191, 53073274, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(52974942, 53106013, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(52729209, 52794736, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(52827495, 52794722, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(52909390, 53007697, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(53105989, 52974917, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(52630860, 52663632, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(52729190, 52680035, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(52565343, 52598117, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(53253448, 53318987, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(52499781, 52385096, 0, 65280, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(54187384, 54351224, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(54056300, 54121829, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(54367593, 54433128, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(54105437, 53908823, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(54007119, 54056266, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(53859656, 53794120, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(53843294, 53826914, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(53630292, 53744980, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(53515590, 53417331, 0, 65280, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(53499251, 53400902, 0, 65280, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(53777819, 53826967, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(53876128, 53892509, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(53826996, 53925299, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(54023584, 54056349, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(54416818, 54318512, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(54449563, 54482318, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(54072714, 54023558, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(53826948, 53745021, 0, 65280, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(52614547, 52565399, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(52499882, 52532657, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(52614557, 52663709, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(52925867, 52827569, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(53106073, 53138838, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(53286311, 53237162, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(53302713, 53351865, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(53450160, 53515696, 0, 65280, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(53433760, 53548446, 0, 65280, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(53056899, 52958589, 0, 65280, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(51565989, 51500447, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(51746233, 51811765, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(51811753, 51877297, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(51664289, 51582365, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(51910053, 51959206, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(52008374, 52106677, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(52270514, 52270509, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(51713427, 51647888, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(51991962, 51860875, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(52139418, 52221339, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(52123021, 52188558, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(52270479, 52270475, 0, 16711935, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(52368776, 52467083, 0, 65280, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(52385177, 52450715, 0, 65280, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(51926406, 51762557, 0, 65280, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + break; + case 34: + case 32: + case 33: + ivar5 = script_300(15, 1, 280, arg0, arg1, arg2, arg3, arg4, ivar5, "The world map screen" + "
" + "shows you where you are," + "
" + "and where important" + "
" + "features may be found."); + break; + case 36: + ivar5 = script_300(28316927, 0, 280, arg0, arg1, arg2, arg3, arg4, ivar5, "Lower level"); + ivar5 = script_300(296752383, 0, 280, arg0, arg1, arg2, arg3, arg4, ivar5, "Upper level"); + ivar5 = script_297(297424118, 29054198, 0, 65280, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(29136098, 297571551, 0, 65280, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(28579021, 297014473, 0, 65280, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + ivar5 = script_297(296867009, 27219081, 0, 65280, 6, arg0, arg1, arg2, arg3, arg4, ivar5); + break; + default: + deleteAllExtraChilds(new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/2950.cs2 b/dumps/scripts/2950.cs2 new file mode 100644 index 0000000..09df9a4 --- /dev/null +++ b/dumps/scripts/2950.cs2 @@ -0,0 +1,4 @@ +void script_2950(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,string arg7,string arg8,string arg9) { + script_3232(arg0, arg1, arg2, arg3, arg4, arg5, arg6, 0, arg7, arg8, arg9); + return; +} diff --git a/dumps/scripts/2951.cs2 b/dumps/scripts/2951.cs2 new file mode 100644 index 0000000..5bdf294 --- /dev/null +++ b/dumps/scripts/2951.cs2 @@ -0,0 +1,46 @@ +void script_2951() { + int ivar0; + int ivar1; + ivar0 = 39059469; + if (hasSSKey()) { + ivar0 = 63897603; + } + ivar1 = script_2948(); + if (((ivar1 != -3) && (ivar1 != 42)) && (ivar1 != 43)) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(ivar0)); + return; + } + if (getClientCycle() < globalint_1092) { + return; + } + globalint_1092 = add(getClientCycle(), 5); + switch (getWidgetSpriteId(new WidgetPointer(ivar0))) { + case 4107: + setWidgetSprite(4108, new WidgetPointer(ivar0)); + break; + case 4108: + setWidgetSprite(4109, new WidgetPointer(ivar0)); + break; + case 4109: + setWidgetSprite(4110, new WidgetPointer(ivar0)); + break; + case 4110: + setWidgetSprite(4111, new WidgetPointer(ivar0)); + break; + case 4111: + setWidgetSprite(4112, new WidgetPointer(ivar0)); + break; + case 4112: + setWidgetSprite(4113, new WidgetPointer(ivar0)); + break; + case 4113: + setWidgetSprite(4114, new WidgetPointer(ivar0)); + break; + case 4114: + setWidgetSprite(4107, new WidgetPointer(ivar0)); + break; + default: + setWidgetSprite(4107, new WidgetPointer(ivar0)); + } + return; +} diff --git a/dumps/scripts/2952.cs2 b/dumps/scripts/2952.cs2 new file mode 100644 index 0000000..a79b924 --- /dev/null +++ b/dumps/scripts/2952.cs2 @@ -0,0 +1,66 @@ +void script_2952(int arg0,int arg1,int arg2) { + string svar0; + string svar1; + svar0 = ""; + svar1 = ""; + switch (arg2) { + case 3: + svar0 = "accountappeal"; + svar1 = "passwordchoice.ws"; + setScriptCallOnMousePressed(2931, svar0, svar1, 1, "ss1", new WidgetPointer(arg0)); + setScriptCallOnMousePressed(2953, "", new WidgetPointer(arg1)); + break; + case 4: + svar0 = "ticketing"; + svar1 = "inbox.ws"; + setScriptCallOnMousePressed(2931, svar0, svar1, 1, "ss1", new WidgetPointer(arg0)); + setScriptCallOnMousePressed(2953, "", new WidgetPointer(arg1)); + break; + case 11: + svar0 = "password_history"; + svar1 = "password.ws"; + setScriptCallOnMousePressed(2931, svar0, svar1, 1, "ss1", new WidgetPointer(arg0)); + setScriptCallOnMousePressed(2953, "", new WidgetPointer(arg1)); + break; + case 18: + svar0 = "accountappeal"; + svar1 = "lockchoice.ws"; + setScriptCallOnMousePressed(2931, svar0, svar1, 1, "ss1", new WidgetPointer(arg0)); + setScriptCallOnMousePressed(2953, "", new WidgetPointer(arg1)); + break; + case 30: + if (((boolean)cs2method5420())) { + svar1 = "slu.ws"; + setScriptCallOnMousePressed(2933, svar1, 0, "s1", new WidgetPointer(arg0)); + } else { + svar0 = "dob"; + svar1 = "set_members_dob.ws"; + setScriptCallOnMousePressed(2931, svar0, svar1, 1, "ss1", new WidgetPointer(arg0)); + } + setScriptCallOnMousePressed(2953, "", new WidgetPointer(arg1)); + break; + case 31: + svar0 = "displaynames"; + svar1 = "name.ws"; + setScriptCallOnMousePressed(2931, svar0, svar1, 1, "ss1", new WidgetPointer(arg0)); + setScriptCallOnMousePressed(2953, "", new WidgetPointer(arg1)); + break; + case 19: + case 32: + case 40: + case 12: + svar0 = "dob"; + svar1 = "set_members_dob.ws"; + setScriptCallOnMousePressed(2931, svar0, svar1, 1, "ss1", new WidgetPointer(arg0)); + setScriptCallOnMousePressed(2953, "", new WidgetPointer(arg1)); + break; + case 21: + setScriptCallOnMousePressed(3234, "", new WidgetPointer(arg0)); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(arg1)); + break; + default: + setScriptCallOnMousePressed(-1, "", new WidgetPointer(arg0)); + setScriptCallOnMousePressed(2953, "", new WidgetPointer(arg1)); + } + return; +} diff --git a/dumps/scripts/2953.cs2 b/dumps/scripts/2953.cs2 new file mode 100644 index 0000000..c66cff8 --- /dev/null +++ b/dumps/scripts/2953.cs2 @@ -0,0 +1,4 @@ +void script_2953() { + script_2954(); + return; +} diff --git a/dumps/scripts/2954.cs2 b/dumps/scripts/2954.cs2 new file mode 100644 index 0000000..b39fe2c --- /dev/null +++ b/dumps/scripts/2954.cs2 @@ -0,0 +1,69 @@ +void script_2954() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + ivar0 = 39059463; + ivar1 = 39059464; + ivar2 = 39059470; + ivar3 = 39059469; + ivar4 = 39059471; + ivar5 = 39059519; + ivar6 = 39059472; + ivar7 = 39059473; + ivar8 = 39059474; + ivar9 = 39059521; + ivar10 = 39059522; + ivar11 = 39059523; + ivar12 = 39059475; + ivar13 = 39059524; + if (hasSSKey()) { + ivar0 = 63897626; + ivar1 = 63897601; + ivar2 = 63897604; + ivar3 = 63897603; + ivar4 = 63897605; + ivar5 = 63897606; + ivar6 = 63897611; + ivar7 = 63897612; + ivar8 = 63897613; + ivar9 = 63897607; + ivar10 = 63897608; + ivar11 = 63897609; + ivar12 = 63897614; + ivar13 = 63897610; + } + setScriptCallOnMousePressed(-1, "", new WidgetPointer(ivar4)); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(ivar5)); + setScriptCallOnMouseEntered(-1, "", new WidgetPointer(ivar5)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(ivar5)); + setScriptCallOnMouseEntered(-1, "", new WidgetPointer(ivar4)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(ivar4)); + setWidgetPosition(6, 5, 0, 2, new WidgetPointer(ivar4)); + setWidgetPosition(6, 5, 0, 2, new WidgetPointer(ivar5)); + setWidgetText(new WidgetPointer(ivar12), ""); + setWidgetText(new WidgetPointer(ivar13), ""); + setWidgetIsHidden(true, new WidgetPointer(ivar4)); + setWidgetIsHidden(true, new WidgetPointer(ivar5)); + setWidgetText(new WidgetPointer(ivar2), ""); + globalint_1092 = 0; + setWidgetSprite(-1, new WidgetPointer(ivar3)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(ivar3)); + setWidgetIsHidden(true, new WidgetPointer(ivar0)); + setWidgetIsHidden(true, new WidgetPointer(ivar1)); + if (hasSSKey()) { + return; + } + script_2940(11); + return; +} diff --git a/dumps/scripts/2955.cs2 b/dumps/scripts/2955.cs2 new file mode 100644 index 0000000..12ad7a1 --- /dev/null +++ b/dumps/scripts/2955.cs2 @@ -0,0 +1,23 @@ +void script_2955(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5) { + int ivar5; + int ivar6; + int ivar7; + int ivar8; + ivar5 = 4044; + ivar6 = 4044; + ivar7 = 4046; + setScriptCallOnMouseExit(2924, new WidgetPointer(arg1), ivar5, new WidgetPointer(arg2), ivar7, new WidgetPointer(arg3), ivar6, "IdIdId", new WidgetPointer(arg0)); + setWidgetSprite(ivar5, new WidgetPointer(arg1)); + setWidgetSprite(ivar7, new WidgetPointer(arg2)); + setWidgetSprite(ivar6, new WidgetPointer(arg3)); + ivar5 = 4045; + ivar6 = 4045; + ivar7 = 4047; + setScriptCallOnMouseEntered(2924, new WidgetPointer(arg1), ivar5, new WidgetPointer(arg2), ivar7, new WidgetPointer(arg3), ivar6, "IdIdId", new WidgetPointer(arg0)); + ivar8 = 39059475; + if (hasSSKey()) { + ivar8 = 63897614; + } + setWidgetText(new WidgetPointer(ivar8), arg5); + return; +} diff --git a/dumps/scripts/2956.cs2 b/dumps/scripts/2956.cs2 new file mode 100644 index 0000000..b2cff2c --- /dev/null +++ b/dumps/scripts/2956.cs2 @@ -0,0 +1,23 @@ +void script_2956(int arg0,int arg1,int arg2,int arg3,string arg4) { + int ivar4; + int ivar5; + int ivar6; + int ivar7; + ivar4 = 4044; + ivar5 = 4044; + ivar6 = 4046; + setScriptCallOnMouseExit(2924, new WidgetPointer(arg1), ivar4, new WidgetPointer(arg2), ivar6, new WidgetPointer(arg3), ivar5, "IdIdId", new WidgetPointer(arg0)); + setWidgetSprite(ivar4, new WidgetPointer(arg1)); + setWidgetSprite(ivar6, new WidgetPointer(arg2)); + setWidgetSprite(ivar5, new WidgetPointer(arg3)); + ivar4 = 4045; + ivar6 = 4047; + ivar5 = 4045; + setScriptCallOnMouseEntered(2924, new WidgetPointer(arg1), ivar4, new WidgetPointer(arg2), ivar6, new WidgetPointer(arg3), ivar5, "IdIdId", new WidgetPointer(arg0)); + ivar7 = 39059524; + if (hasSSKey()) { + ivar7 = 63897610; + } + setWidgetText(new WidgetPointer(ivar7), arg4); + return; +} diff --git a/dumps/scripts/2957.cs2 b/dumps/scripts/2957.cs2 new file mode 100644 index 0000000..e66eaef --- /dev/null +++ b/dumps/scripts/2957.cs2 @@ -0,0 +1,25 @@ +void script_2957(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + deleteAllExtraChilds(new WidgetPointer(arg0)); + ivar1 = getWidgetActualWidth(new WidgetPointer(arg0)); + ivar2 = getWidgetActualHeight(new WidgetPointer(arg0)); + ivar3 = subtract(ivar1, 9); + ivar4 = subtract(ivar2, 9); + ivar5 = subtract(ivar1, 18); + ivar6 = subtract(ivar2, 18); + script_98(arg0, 0, 1040, 0, 0, ivar1, ivar2); + script_98(arg0, 1, 1275, 0, 0, 9, 9); + script_98(arg0, 2, 1276, ivar3, 0, 9, 9); + script_98(arg0, 3, 1277, 0, ivar4, 9, 9); + script_98(arg0, 4, 1278, ivar3, ivar4, 9, 9); + script_98(arg0, 5, 1279, 0, 9, 9, ivar6); + script_98(arg0, 6, 1280, 9, 0, ivar5, 9); + script_98(arg0, 7, 1281, ivar3, 9, 9, ivar6); + script_98(arg0, 8, 1282, 9, ivar4, ivar5, 9); + return; +} diff --git a/dumps/scripts/2958.cs2 b/dumps/scripts/2958.cs2 new file mode 100644 index 0000000..da76d60 --- /dev/null +++ b/dumps/scripts/2958.cs2 @@ -0,0 +1,35 @@ +void script_2958(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + ivar4 = getWidgetParentId(new WidgetPointer(arg0)); + ivar5 = 0; + switch (arg1) { + case 20024: + ivar5 = bitconfig_8399; + setWidgetText(new WidgetPointer(arg3), getItemName(arg1) + "
" + "(" + intToStr(ivar5) + "/" + intToStr(arg2) + ")"); + break; + case 20012: + ivar5 = bitconfig_8400; + setWidgetText(new WidgetPointer(arg3), getItemName(arg1) + "
" + "(" + intToStr(ivar5) + "/" + intToStr(arg2) + ")"); + break; + case 20032: + ivar5 = bitconfig_8403; + setWidgetText(new WidgetPointer(arg3), getItemName(arg1) + "
" + "(" + intToStr(ivar5) + "/" + intToStr(arg2) + ")"); + break; + case 20036: + ivar5 = bitconfig_8402; + setWidgetText(new WidgetPointer(arg3), getItemName(arg1) + "
" + "(" + intToStr(ivar5) + "/" + intToStr(arg2) + ")"); + break; + case 20040: + ivar5 = bitconfig_8404; + setWidgetText(new WidgetPointer(arg3), getItemName(arg1) + "
" + "(" + intToStr(ivar5) + "/" + intToStr(arg2) + ")"); + break; + case 20028: + ivar5 = bitconfig_8401; + setWidgetText(new WidgetPointer(arg3), getItemName(arg1) + "
" + "(" + intToStr(ivar5) + "/" + intToStr(arg2) + ")"); + } + setItemOnWidgetMethod2205(arg1, -1, new WidgetPointer(arg0)); + setWidgetBorderThickness(1, new WidgetPointer(arg0)); + cs2method2314(171, new WidgetPointer(arg3)); + return; +} diff --git a/dumps/scripts/2959.cs2 b/dumps/scripts/2959.cs2 new file mode 100644 index 0000000..014f95e --- /dev/null +++ b/dumps/scripts/2959.cs2 @@ -0,0 +1,7 @@ +void script_2959(int arg0) { + cs2method2309(1, 170, new WidgetPointer(arg0)); + cs2method2309(2, 170, new WidgetPointer(arg0)); + cs2method2309(3, 170, new WidgetPointer(arg0)); + cs2method2309(4, 170, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/296.cs2 b/dumps/scripts/296.cs2 new file mode 100644 index 0000000..d7352fa --- /dev/null +++ b/dumps/scripts/296.cs2 @@ -0,0 +1,26 @@ +cs2func_script_296_struct(2,0,0) script_296(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6) { + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int stack_dump0; + opcStruct5224(2,0,0) structdump_1; + ivar7 = 0; + ivar8 = 0; + if (((boolean)arg1)) { + ivar7 = extractX(arg0); + ivar8 = extractY(arg0); + } else { + stack_dump0 = arg0; + structdump_1 = cs2method5224(stack_dump0); + ivar8 = structdump_1.intpart_1; + ivar7 = structdump_1.intpart_0; + } + ivar9 = getWidgetActualWidth(new WidgetPointer(arg2)); + ivar10 = getWidgetActualHeight(new WidgetPointer(arg2)); + ivar7 = multiplyDivide(ivar9, subtract(arg5, arg6), subtract(ivar7, arg6)); + ivar8 = multiplyDivide(ivar10, subtract(arg3, arg4), subtract(ivar8, arg4)); + ivar7 = subtract(ivar7, divide(ivar9, 2)); + ivar8 = subtract(divide(ivar10, 2), ivar8); + return newstruct cs2func_script_296_struct(ivar7, ivar8); +} diff --git a/dumps/scripts/2960.cs2 b/dumps/scripts/2960.cs2 new file mode 100644 index 0000000..3d99600 --- /dev/null +++ b/dumps/scripts/2960.cs2 @@ -0,0 +1,21 @@ +void script_2960(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5) { + if (arg0 != -1) { + if (((boolean)arg4)) { + setWidgetSprite(2525, new WidgetPointer(arg0)); + } else { + setWidgetSprite(2524, new WidgetPointer(arg0)); + } + } + if (arg1 != -1) { + if (((boolean)arg4)) { + setWidgetText(new WidgetPointer(arg0), arg5); + setWidgetRGB(new Color(250, 215, 134), new WidgetPointer(arg2)); + setWidgetSize(add(getTextWidth(arg3, arg5), 23), getWidgetActualHeight(new WidgetPointer(arg1)), 0, 0, new WidgetPointer(arg1)); + } else { + setWidgetText(new WidgetPointer(arg2), arg5); + setWidgetRGB(new Color(231, 172, 36), new WidgetPointer(arg2)); + setWidgetSize(add(getTextWidth(arg3, arg5), 23), getWidgetActualHeight(new WidgetPointer(arg1)), 0, 0, new WidgetPointer(arg1)); + } + } + return; +} diff --git a/dumps/scripts/2961.cs2 b/dumps/scripts/2961.cs2 new file mode 100644 index 0000000..5af230c --- /dev/null +++ b/dumps/scripts/2961.cs2 @@ -0,0 +1,18 @@ +void script_2961(int arg0,int arg1,int arg2) { + if (((boolean)arg2)) { + if (((boolean)globalint_986)) { + setWidgetSprite(2702, new WidgetPointer(arg0)); + } else { + setWidgetSprite(2701, new WidgetPointer(arg0)); + } + setWidgetRGB(new Color(235, 224, 188), new WidgetPointer(arg1)); + } else { + if (((boolean)globalint_986)) { + setWidgetSprite(2700, new WidgetPointer(arg0)); + } else { + setWidgetSprite(2703, new WidgetPointer(arg0)); + } + setWidgetRGB(new Color(178, 170, 159), new WidgetPointer(arg1)); + } + return; +} diff --git a/dumps/scripts/2962.cs2 b/dumps/scripts/2962.cs2 new file mode 100644 index 0000000..74d5713 --- /dev/null +++ b/dumps/scripts/2962.cs2 @@ -0,0 +1,13 @@ +void script_2962(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6) { + if (getClientCycle() >= arg6) { + globalint_176 = add(globalint_176, 2); + setScriptCallOnGameloop(1249, new WidgetPointer(arg0), new WidgetPointer(arg2), new WidgetPointer(arg1), "III", new WidgetPointer(arg0)); + globalint_177 = 0; + setScriptCallOnMousePressed(2713, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), "IIIIII", new WidgetPointer(arg3)); + setScriptCallOnMouseOver(2961, new WidgetPointer(arg4), new WidgetPointer(arg5), 1, "II1", new WidgetPointer(arg3)); + setScriptCallOnMouseExit(2961, new WidgetPointer(arg4), new WidgetPointer(arg5), 0, "II1", new WidgetPointer(arg3)); + setWidgetSprite(2703, new WidgetPointer(arg4)); + globalint_986 = 0; + } + return; +} diff --git a/dumps/scripts/2963.cs2 b/dumps/scripts/2963.cs2 new file mode 100644 index 0000000..fbb5795 --- /dev/null +++ b/dumps/scripts/2963.cs2 @@ -0,0 +1,12 @@ +void script_2963(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6) { + if (getClientCycle() >= arg6) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(arg0)); + setScriptCallOnMousePressed(2713, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), "IIIIII", new WidgetPointer(arg3)); + setScriptCallOnMouseOver(2961, new WidgetPointer(arg4), new WidgetPointer(arg5), 1, "II1", new WidgetPointer(arg3)); + setScriptCallOnMouseExit(2961, new WidgetPointer(arg4), new WidgetPointer(arg5), 0, "II1", new WidgetPointer(arg3)); + setWidgetSprite(2700, new WidgetPointer(arg4)); + globalint_986 = 1; + } + return; +} diff --git a/dumps/scripts/2964.cs2 b/dumps/scripts/2964.cs2 new file mode 100644 index 0000000..e3b959c --- /dev/null +++ b/dumps/scripts/2964.cs2 @@ -0,0 +1,27 @@ +cs2func_script_2964_struct(2,0,0) script_2964(int arg0) { + if (((boolean)arg0)) { + cs2method5405(0, 7); + cs2method5405(1, 7); + cs2method5406(0, 0, 27727014, 890, 27808931, 895, 0); + cs2method5406(1, 0, 27858076, 605, 27890842, 615, 0); + cs2method5406(0, 1, 27907228, 995, 27956377, 1060, 0); + cs2method5406(1, 1, 27874444, 855, 27874444, 835, 0); + script_1899(0, 200, 300); + cs2method5406(0, 2, 28005518, 1525, 28005514, 1540, 0); + cs2method5406(1, 2, 27874444, 855, 27874444, 852, 0); + script_1899(1, 200, 300); + cs2method5406(0, 3, 27874437, 1575, 27792517, 1575, 0); + cs2method5406(1, 3, 27874444, 885, 27874444, 865, 0); + script_1899(2, 300, 400); + cs2method5406(0, 4, 27759756, 1605, 27759758, 1600, 0); + cs2method5406(1, 4, 27874444, 890, 27874444, 880, 0); + script_1899(3, 300, 400); + cs2method5406(0, 5, 27874452, 1615, 27874452, 1605, 0); + cs2method5406(1, 5, 27874444, 905, 27874444, 895, 0); + script_1899(4, 300, 400); + cs2method5406(0, 6, 27874452, 1610, 27874452, 1585, 0); + cs2method5406(1, 6, 27874444, 900, 27874444, 865, 0); + script_1899(5, 300, 400); + } + return newstruct cs2func_script_2964_struct(27661487, 1250324); +} diff --git a/dumps/scripts/2965.cs2 b/dumps/scripts/2965.cs2 new file mode 100644 index 0000000..5a05fb0 --- /dev/null +++ b/dumps/scripts/2965.cs2 @@ -0,0 +1,4 @@ +void script_2965() { + script_2276(globalint_1199, globalint_1210, 61145357); + return; +} diff --git a/dumps/scripts/2966.cs2 b/dumps/scripts/2966.cs2 new file mode 100644 index 0000000..029176e --- /dev/null +++ b/dumps/scripts/2966.cs2 @@ -0,0 +1,4 @@ +void script_2966() { + script_2276(globalint_1199, globalint_1211, 61145358); + return; +} diff --git a/dumps/scripts/2967.cs2 b/dumps/scripts/2967.cs2 new file mode 100644 index 0000000..853b894 --- /dev/null +++ b/dumps/scripts/2967.cs2 @@ -0,0 +1,50 @@ +void script_2967(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + script_3209(); + script_3208(1); + ivar1 = script_3228(7, 0, 0); + ivar2 = script_3228(8, 0, 0); + ivar3 = 1; + if (((stringMethod4107(globalstring_124, globalstring_125) != 0) && (strLength(globalstring_124) > 0)) && (strLength(globalstring_125) > 0)) { + script_3213(44105802, "Please ensure both passwords match."); + ivar3 = 0; + } + ivar4 = 1; + if (strLength(globalstring_122) <= 0) { + script_3213(44105822, "Please enter your Email address here."); + ivar4 = 0; + } + if (((boolean)script_3936(globalstring_122))) { + script_3213(44105822, "Please enter a valid Email address."); + ivar4 = 0; + } + ivar5 = 1; + if (strLength(globalstring_326) <= 0) { + script_3213(44105841, "Please enter your Email address again here."); + ivar5 = 0; + } + if (stringMethod4107(globalstring_122, globalstring_326) != 0) { + script_3213(44105841, "Please ensure both Email addresses match."); + ivar5 = 0; + } + ivar6 = script_3954(0); + if (((((boolean)ivar4) && ((boolean)ivar5)) && (((boolean)ivar1) && ((boolean)ivar2))) && (((boolean)ivar3) && ((boolean)ivar6))) { + if (globalint_1407 < 13) { + setAgeMinor(); + script_4038(); + } else if (isAgeMinor()) { + script_4038(); + } else { + sendCreateAccount(globalint_1407, globalint_1411, globalstring_122, globalstring_124); + setScriptCallOnGameloop(3220, "", new WidgetPointer(673,26)); + } + } else { + script_3208(0); + } + return; +} diff --git a/dumps/scripts/2968.cs2 b/dumps/scripts/2968.cs2 new file mode 100644 index 0000000..a985a9b --- /dev/null +++ b/dumps/scripts/2968.cs2 @@ -0,0 +1,17 @@ +void script_2968(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + ivar3 = getWidgetParentId(new WidgetPointer(arg0)); + ivar4 = 0; + ivar4 = getItemAmtInContainer(93, arg1); + if (ivar4 > 0) { + setWidgetRGB(new Color(125, 215, 100), new WidgetPointer(arg2)); + setItemOnWidgetMethod2200(arg1, ivar4, new WidgetPointer(arg0)); + } else { + setWidgetRGB(new Color(135, 35, 0), new WidgetPointer(arg2)); + setItemOnWidgetMethod2200(arg1, -1, new WidgetPointer(arg0)); + } + setWidgetBorderThickness(1, new WidgetPointer(arg0)); + cs2method2314(171, new WidgetPointer(arg2)); + return; +} diff --git a/dumps/scripts/2969.cs2 b/dumps/scripts/2969.cs2 new file mode 100644 index 0000000..f0581ce --- /dev/null +++ b/dumps/scripts/2969.cs2 @@ -0,0 +1,4 @@ +void script_2969() { + script_2971(globalint_1404, globalint_1405); + return; +} diff --git a/dumps/scripts/297.cs2 b/dumps/scripts/297.cs2 new file mode 100644 index 0000000..5983273 --- /dev/null +++ b/dumps/scripts/297.cs2 @@ -0,0 +1,147 @@ +int script_297(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10) { + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + int ivar22; + int ivar23; + int ivar24; + int ivar25; + int ivar26; + int ivar27; + int stack_dump0; + int stack_dump1; + int stack_dump2; + int stack_dump3; + int stack_dump4; + int stack_dump5; + int stack_dump6; + cs2func_script_296_struct(2,0,0) structdump_7; + cs2func_script_296_struct(2,0,0) structdump_8; + cs2func_script_2413_struct(3,0,0) structdump_9; + if (((boolean)bitconfig_6175)) { + return arg10; + } + arg3 = 16776960; + ivar11 = add(arg10, 1); + ivar12 = add(arg10, 2); + ivar13 = add(arg10, 3); + ivar14 = add(arg10, 4); + ivar15 = 0; + ivar16 = 0; + stack_dump0 = arg0; + stack_dump1 = arg2; + stack_dump2 = arg5; + stack_dump3 = arg6; + stack_dump4 = arg7; + stack_dump5 = arg8; + stack_dump6 = arg9; + structdump_7 = script_296(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4, stack_dump5, stack_dump6); + ivar16 = structdump_7.intpart_1; + ivar15 = structdump_7.intpart_0; + ivar17 = 0; + ivar18 = 0; + stack_dump0 = arg1; + stack_dump1 = arg2; + stack_dump2 = arg5; + stack_dump3 = arg6; + stack_dump4 = arg7; + stack_dump5 = arg8; + stack_dump6 = arg9; + structdump_8 = script_296(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4, stack_dump5, stack_dump6); + ivar18 = structdump_8.intpart_1; + ivar17 = structdump_8.intpart_0; + ivar19 = add(ivar15, divide(subtract(ivar17, ivar15), 2)); + ivar20 = add(ivar16, divide(subtract(ivar18, ivar16), 2)); + ivar21 = subtract(ivar17, ivar15); + ivar22 = subtract(ivar18, ivar16); + ivar23 = 0; + if (ivar21 < 0) { + if (ivar22 < 0) { + ivar21 = subtract(0, ivar21); + ivar22 = subtract(0, ivar22); + } else { + ivar21 = subtract(0, ivar21); + ivar23 = 1; + } + } else { + if (ivar22 < 0) { + ivar22 = subtract(0, ivar22); + ivar23 = 1; + } + } + if (setWidgetRegister(new WidgetPointer(arg5), arg10) && setWidgetRegister(new WidgetPointer(arg5), ivar11)) { + setWidgetPosition(add(ivar15, 1), add(ivar16, 1), 1, 1); + setWidgetPosition(add(ivar17, 1), add(ivar18, 1), 1, 1); + } else { + createExtraChild(new WidgetPointer(arg5), 3, arg10); + createExtraChild(new WidgetPointer(arg5), 3, ivar11); + setWidgetPosition(add(ivar15, 1), add(ivar16, 1), 1, 1); + setWidgetPosition(add(ivar17, 1), add(ivar18, 1), 1, 1); + setWidgetSize(arg4, arg4, 0, 0); + setWidgetSize(arg4, arg4, 0, 0); + setWidgetRGB(new Color(0, 0, 0)); + setWidgetRGB(new Color(0, 0, 0)); + setWidgetFilled(1); + setWidgetFilled(1); + } + ivar24 = 0; + ivar25 = 0; + ivar26 = 0; + ivar27 = 0; + if (setWidgetRegister(new WidgetPointer(arg5), ivar12) && setWidgetRegister(new WidgetPointer(arg5), ivar13)) { + setWidgetPosition(ivar15, ivar16, 1, 1); + setWidgetPosition(ivar17, ivar18, 1, 1); + } else { + stack_dump0 = arg3; + structdump_9 = script_2413(stack_dump0); + ivar26 = structdump_9.intpart_2; + ivar25 = structdump_9.intpart_1; + ivar24 = structdump_9.intpart_0; + stack_dump0 = max(subtract(ivar24, 48), 0); + stack_dump1 = max(subtract(ivar25, 48), 0); + ivar26 = max(subtract(ivar26, 48), 0); + stack_dump0 = stack_dump0; + ivar25 = stack_dump1; + ivar24 = stack_dump0; + ivar27 = script_693(ivar24, ivar25, ivar26); + createExtraChild(new WidgetPointer(arg5), 3, ivar12); + createExtraChild(new WidgetPointer(arg5), 3, ivar13); + setWidgetPosition(ivar15, ivar16, 1, 1); + setWidgetPosition(ivar17, ivar18, 1, 1); + setWidgetSize(arg4, arg4, 0, 0); + setWidgetSize(arg4, arg4, 0, 0); + setWidgetRGB(new Color(ivar27)); + setWidgetRGB(new Color(ivar27)); + setWidgetFilled(1); + setWidgetFilled(1); + setScriptCallOnMouseEntered(301, 1, new WidgetPointer(arg5), ivar12, ivar13, ivar14, arg3, "1Iiiii"); + setScriptCallOnMouseEntered(301, 1, new WidgetPointer(arg5), ivar12, ivar13, ivar14, arg3, "1Iiiii"); + setScriptCallOnMouseExit(301, 0, new WidgetPointer(arg5), ivar12, ivar13, ivar14, ivar27, "1Iiiii"); + setScriptCallOnMouseExit(301, 0, new WidgetPointer(arg5), ivar12, ivar13, ivar14, ivar27, "1Iiiii"); + setWidgetContextMenuOption(1, "Scroll map"); + setWidgetContextMenuOption(1, "Scroll map"); + setScriptCallOnClickContextMenu(302, -2147483644, arg1, arg2, "ic1"); + setScriptCallOnClickContextMenu(302, -2147483644, arg0, arg2, "ic1"); + } + if (setWidgetRegister(new WidgetPointer(arg5), ivar14)) { + setWidgetPosition(ivar19, ivar20, 1, 1); + setWidgetSize(ivar21, ivar22, 0, 0); + } else { + createExtraChild(new WidgetPointer(arg5), 9, ivar14); + setWidgetPosition(ivar19, ivar20, 1, 1); + setWidgetSize(ivar21, ivar22, 0, 0); + cs2method1124(ivar23); + cs2method1104(add(1, divide(arg4, 5))); + setWidgetRGB(new Color(arg3)); + setWidgetHidden(1); + } + return add(ivar14, 1); +} diff --git a/dumps/scripts/2970.cs2 b/dumps/scripts/2970.cs2 new file mode 100644 index 0000000..860b131 --- /dev/null +++ b/dumps/scripts/2970.cs2 @@ -0,0 +1,4 @@ +void script_2970(int arg0,int arg1) { + script_2971(arg0, arg1); + return; +} diff --git a/dumps/scripts/2971.cs2 b/dumps/scripts/2971.cs2 new file mode 100644 index 0000000..7c4278a --- /dev/null +++ b/dumps/scripts/2971.cs2 @@ -0,0 +1,118 @@ +void script_2971(int arg0,int arg1) { + int ivar2; + int ivar3; + string svar0; + string svar1; + string svar2; + flow_0: + svar0 = ""; + svar1 = ""; + svar2 = ""; + ivar2 = -1; + ivar3 = -1; + SWITCH (arg0) { + case 0: + GOTO flow_1 + case 1: + GOTO flow_2 + case 2: + GOTO flow_3 + case 3: + GOTO flow_4 + case 4: + GOTO flow_5 + case 5: + GOTO flow_6 + case 6: + GOTO flow_7 + case 7: + GOTO flow_8 + } + svar0 = "Unknown"; + svar1 = "This should not get here."; + svar2 = "This should never get here."; + ivar2 = 62129; + ivar3 = 30081093; + GOTO flow_9 + flow_1: + svar0 = "Nothing."; + svar1 = "There are no requirements for building this feature."; + svar2 = "This feature is an abscence of anything. Oddly, some creatures prefer the minimalist approach."; + ivar2 = 62129; + ivar3 = 30081093; + GOTO flow_9 + flow_2: + svar0 = "Pond"; + svar1 = "You need a Construction level of 65 to build a pond."; + svar2 = "Ponds attract creatures with an affinity for water. They are essentially very small, man-made lakes...or glorified puddles, depending on your view."; + ivar3 = 30081092; + ivar2 = 62128; + GOTO flow_9 + flow_3: + svar0 = "Tall grass"; + svar1 = "You need a Construction level of 62 to build tall grass."; + svar2 = "Tall grass is favoured by creatures who sneak and hide. It's also a favourite with people too lazy to trim their lawn. Essentially, it's a patch of land allowed to grow wild."; + ivar3 = 30081094; + ivar2 = 62134; + GOTO flow_9 + flow_4: + svar0 = "Abandoned house"; + svar1 = "You need a Construction level of 57 to build an abandoned house."; + svar2 = "Something approximating an abandoned house: popular amongst creatures that think they're domesticated."; + ivar3 = 30081095; + ivar2 = 62132; + GOTO flow_9 + flow_5: + svar0 = "Thermal vent"; + svar1 = "You need a Construction level of 59 to build a thermal vent."; + svar2 = "A home-made volcano, or, at least, something that looks like one. These are popular among earthy creatures."; + ivar3 = 30081096; + ivar2 = 62133; + GOTO flow_9 + flow_6: + svar0 = "Standing stones"; + svar1 = "You need a Construction level of 70 to build standing stones."; + svar2 = "A circle of home-made mystical stones, popular among creatures that are more magically inclined."; + ivar3 = 30081097; + ivar2 = 62136; + GOTO flow_9 + flow_7: + svar0 = "Dark pit"; + svar1 = "You need a Construction level of 80 to build a dark pit."; + svar2 = "A deep, dark, endless pit, popular among the more sinister creatures. Don't look too closely: you might fall in."; + ivar3 = 30081098; + ivar2 = 62131; + GOTO flow_9 + flow_8: + svar0 = "Boneyard"; + svar1 = "You need a Construction level of 56 to build a boneyard."; + svar2 = "An animal graveyard, or a collection of well-made bone mockeries. Popular among scavengers and sinister creatures."; + ivar3 = 30081099; + ivar2 = 62135; + flow_9: + script_2973(); + if (getSkillCurrentLvl(22) < arg1) { + setWidgetRGB(new Color(204, 204, 0), new WidgetPointer(459,37)); + svar2 = concat(svar2, "
" + "
" + "You can pay Papa Mambo to build this for you."); + } else { + setWidgetRGB(new Color(0, 204, 0), new WidgetPointer(459,37)); + } + setWidgetText(new WidgetPointer(459,37), svar0); + setWidgetText(new WidgetPointer(459,38), svar1); + setWidgetText(new WidgetPointer(459,36), svar2); + setWidgetModel(ivar2, new WidgetPointer(459,35)); + setWidgetIsHidden(true, new WidgetPointer(459,69)); + setWidgetIsHidden(true, new WidgetPointer(459,68)); + setWidgetIsHidden(true, new WidgetPointer(459,70)); + setWidgetIsHidden(true, new WidgetPointer(459,71)); + setWidgetIsHidden(true, new WidgetPointer(459,72)); + setWidgetIsHidden(true, new WidgetPointer(459,73)); + setWidgetIsHidden(true, new WidgetPointer(459,74)); + setWidgetIsHidden(true, new WidgetPointer(459,75)); + if (ivar3 != -1) { + setWidgetIsHidden(false, new WidgetPointer(ivar3)); + } else { + setWidgetIsHidden(false, new WidgetPointer(459,69)); + } + return; +} diff --git a/dumps/scripts/2972.cs2 b/dumps/scripts/2972.cs2 new file mode 100644 index 0000000..7e451fa --- /dev/null +++ b/dumps/scripts/2972.cs2 @@ -0,0 +1,4 @@ +void script_2972() { + script_2973(); + return; +} diff --git a/dumps/scripts/2973.cs2 b/dumps/scripts/2973.cs2 new file mode 100644 index 0000000..52759e0 --- /dev/null +++ b/dumps/scripts/2973.cs2 @@ -0,0 +1,38 @@ +void script_2973() { + if (getSkillCurrentLvl(22) < 56) { + setWidgetRGB(new Color(134, 131, 96), new WidgetPointer(459,27)); + } else { + setWidgetRGB(new Color(234, 231, 196), new WidgetPointer(459,27)); + } + if (getSkillCurrentLvl(22) < 57) { + setWidgetRGB(new Color(134, 131, 96), new WidgetPointer(459,23)); + } else { + setWidgetRGB(new Color(234, 231, 196), new WidgetPointer(459,23)); + } + if (getSkillCurrentLvl(22) < 59) { + setWidgetRGB(new Color(134, 131, 96), new WidgetPointer(459,19)); + } else { + setWidgetRGB(new Color(234, 231, 196), new WidgetPointer(459,19)); + } + if (getSkillCurrentLvl(22) < 62) { + setWidgetRGB(new Color(134, 131, 96), new WidgetPointer(459,15)); + } else { + setWidgetRGB(new Color(234, 231, 196), new WidgetPointer(459,15)); + } + if (getSkillCurrentLvl(22) < 65) { + setWidgetRGB(new Color(134, 131, 96), new WidgetPointer(459,7)); + } else { + setWidgetRGB(new Color(234, 231, 196), new WidgetPointer(459,7)); + } + if (getSkillCurrentLvl(22) < 70) { + setWidgetRGB(new Color(134, 131, 96), new WidgetPointer(459,11)); + } else { + setWidgetRGB(new Color(234, 231, 196), new WidgetPointer(459,11)); + } + if (getSkillCurrentLvl(22) < 80) { + setWidgetRGB(new Color(134, 131, 96), new WidgetPointer(459,3)); + } else { + setWidgetRGB(new Color(234, 231, 196), new WidgetPointer(459,3)); + } + return; +} diff --git a/dumps/scripts/2974.cs2 b/dumps/scripts/2974.cs2 new file mode 100644 index 0000000..d492669 --- /dev/null +++ b/dumps/scripts/2974.cs2 @@ -0,0 +1,23 @@ +void script_2974(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + ivar1 = getWidgetRotateY(new WidgetPointer(arg0)); + ivar2 = getWidgetRotateX(new WidgetPointer(arg0)); + ivar3 = cs2method2607(new WidgetPointer(arg0)); + ivar4 = getWidget3DDistance(new WidgetPointer(arg0)); + ivar5 = cs2method2610(new WidgetPointer(arg0)); + ivar6 = cs2method2611(new WidgetPointer(arg0)); + ivar7 = 0; + if (ivar1 == 2047) { + ivar7 = 0; + } else { + ivar7 = add(ivar1, 1); + } + setWidget3DRotation(ivar5, ivar6, ivar2, ivar7, ivar3, ivar4, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/2975.cs2 b/dumps/scripts/2975.cs2 new file mode 100644 index 0000000..f363c33 --- /dev/null +++ b/dumps/scripts/2975.cs2 @@ -0,0 +1,12 @@ +void script_2975(int arg0,int arg1,int arg2,int arg3) { + if (((boolean)arg3)) { + setWidgetSprite(4032, new WidgetPointer(arg0)); + setWidgetSprite(4032, new WidgetPointer(arg2)); + setWidgetSprite(4038, new WidgetPointer(arg1)); + } else { + setWidgetSprite(4031, new WidgetPointer(arg0)); + setWidgetSprite(4031, new WidgetPointer(arg2)); + setWidgetSprite(4037, new WidgetPointer(arg1)); + } + return; +} diff --git a/dumps/scripts/2976.cs2 b/dumps/scripts/2976.cs2 new file mode 100644 index 0000000..0ea2990 --- /dev/null +++ b/dumps/scripts/2976.cs2 @@ -0,0 +1,48 @@ +void script_2976(int arg0) { + flow_0: + SWITCH (globalint_1406) { + case 1: + GOTO flow_1 + case 2: + GOTO flow_2 + case 3: + GOTO flow_3 + case 4: + GOTO flow_4 + case 5: + GOTO flow_5 + case 6: + GOTO flow_6 + case 7: + GOTO flow_7 + case 8: + GOTO flow_8 + } + cameraUnlock(); + GOTO flow_9 + flow_1: + script_2977(arg0); + GOTO flow_9 + flow_2: + script_2978(arg0); + GOTO flow_9 + flow_3: + script_2979(arg0); + GOTO flow_9 + flow_4: + script_2980(arg0); + GOTO flow_9 + flow_5: + script_2981(arg0); + GOTO flow_9 + flow_6: + script_2982(arg0); + GOTO flow_9 + flow_7: + script_2983(arg0); + GOTO flow_9 + flow_8: + script_2984(arg0); + flow_9: + return; +} diff --git a/dumps/scripts/2977.cs2 b/dumps/scripts/2977.cs2 new file mode 100644 index 0000000..77a82b6 --- /dev/null +++ b/dumps/scripts/2977.cs2 @@ -0,0 +1,14 @@ +void script_2977(int arg0) { + int ivar1; + ivar1 = script_284(getMyPositionHash()); + cs2method5405(0, 3); + cs2method5405(1, 3); + cs2method5406(0, 0, addToCoordinate(ivar1, 23, 0, 25), 700, addToCoordinate(ivar1, 23, 0, 25), 700, 0); + cs2method5406(1, 0, addToCoordinate(ivar1, 30, 0, 33), 400, addToCoordinate(ivar1, 30, 0, 22), 400, 0); + cs2method5406(0, 1, addToCoordinate(ivar1, 23, 0, 25), 700, addToCoordinate(ivar1, 23, 0, 25), 700, 0); + cs2method5406(1, 1, addToCoordinate(ivar1, 27, 0, 29), 500, addToCoordinate(ivar1, 27, 0, 29), 500, 0); + cs2method5406(0, 2, addToCoordinate(ivar1, 23, 0, 25), 700, addToCoordinate(ivar1, 23, 0, 25), 700, 0); + cs2method5406(1, 2, addToCoordinate(ivar1, 31, 0, 33), 400, addToCoordinate(ivar1, 31, 0, 33), 400, 0); + cameraMethod5502(0, 0, 1000000, 1000000, 1, 0); + return; +} diff --git a/dumps/scripts/2978.cs2 b/dumps/scripts/2978.cs2 new file mode 100644 index 0000000..1ef95c7 --- /dev/null +++ b/dumps/scripts/2978.cs2 @@ -0,0 +1,12 @@ +void script_2978(int arg0) { + int ivar1; + ivar1 = script_284(getMyPositionHash()); + cs2method5405(0, 2); + cs2method5405(1, 2); + cs2method5406(0, 0, addToCoordinate(ivar1, 23, 0, 25), 700, addToCoordinate(ivar1, 23, 0, 25), 700, 0); + cs2method5406(1, 0, addToCoordinate(ivar1, 31, 0, 33), 400, addToCoordinate(ivar1, 31, 0, 22), 400, 0); + cs2method5406(0, 1, addToCoordinate(ivar1, 31, 0, 25), 800, addToCoordinate(ivar1, 31, 0, 25), 800, 0); + cs2method5406(1, 1, addToCoordinate(ivar1, 31, 0, 33), 300, addToCoordinate(ivar1, 31, 0, 33), 300, 0); + cameraMethod5502(0, 0, 450, 450, 1, 0); + return; +} diff --git a/dumps/scripts/2979.cs2 b/dumps/scripts/2979.cs2 new file mode 100644 index 0000000..75547d4 --- /dev/null +++ b/dumps/scripts/2979.cs2 @@ -0,0 +1,12 @@ +void script_2979(int arg0) { + int ivar1; + ivar1 = script_284(getMyPositionHash()); + cs2method5405(0, 2); + cs2method5405(1, 2); + cs2method5406(0, 0, addToCoordinate(ivar1, 31, 0, 25), 800, addToCoordinate(ivar1, 31, 0, 25), 800, 0); + cs2method5406(1, 0, addToCoordinate(ivar1, 31, 0, 33), 300, addToCoordinate(ivar1, 31, 0, 33), 300, 0); + cs2method5406(0, 1, addToCoordinate(ivar1, 30, 0, 25), 900, addToCoordinate(ivar1, 30, 0, 25), 900, 0); + cs2method5406(1, 1, addToCoordinate(ivar1, 30, 0, 33), 500, addToCoordinate(ivar1, 30, 0, 33), 500, 0); + cameraMethod5502(0, 0, 450, 450, 1, 0); + return; +} diff --git a/dumps/scripts/298.cs2 b/dumps/scripts/298.cs2 new file mode 100644 index 0000000..b2c9753 --- /dev/null +++ b/dumps/scripts/298.cs2 @@ -0,0 +1,127 @@ +int script_298(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10) { + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + int ivar22; + int ivar23; + int ivar24; + int ivar25; + int stack_dump0; + int stack_dump1; + int stack_dump2; + int stack_dump3; + int stack_dump4; + int stack_dump5; + int stack_dump6; + cs2func_script_296_struct(2,0,0) structdump_7; + cs2func_script_296_struct(2,0,0) structdump_8; + cs2func_script_2413_struct(3,0,0) structdump_9; + if (((boolean)bitconfig_6175)) { + return arg10; + } + arg3 = 16776960; + ivar11 = add(arg10, 1); + ivar12 = add(arg10, 2); + ivar13 = 0; + ivar14 = 0; + stack_dump0 = arg0; + stack_dump1 = arg2; + stack_dump2 = arg5; + stack_dump3 = arg6; + stack_dump4 = arg7; + stack_dump5 = arg8; + stack_dump6 = arg9; + structdump_7 = script_296(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4, stack_dump5, stack_dump6); + ivar14 = structdump_7.intpart_1; + ivar13 = structdump_7.intpart_0; + ivar15 = 0; + ivar16 = 0; + stack_dump0 = arg1; + stack_dump1 = arg2; + stack_dump2 = arg5; + stack_dump3 = arg6; + stack_dump4 = arg7; + stack_dump5 = arg8; + stack_dump6 = arg9; + structdump_8 = script_296(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4, stack_dump5, stack_dump6); + ivar16 = structdump_8.intpart_1; + ivar15 = structdump_8.intpart_0; + ivar17 = add(ivar13, divide(subtract(ivar15, ivar13), 2)); + ivar18 = add(ivar14, divide(subtract(ivar16, ivar14), 2)); + ivar19 = subtract(ivar15, ivar13); + ivar20 = subtract(ivar16, ivar14); + ivar21 = 0; + if (ivar19 < 0) { + if (ivar20 < 0) { + ivar19 = subtract(0, ivar19); + ivar20 = subtract(0, ivar20); + } else { + ivar19 = subtract(0, ivar19); + ivar21 = 1; + } + } else { + if (ivar20 < 0) { + ivar20 = subtract(0, ivar20); + ivar21 = 1; + } + } + if (setWidgetRegister(new WidgetPointer(arg5), arg10)) { + setWidgetPosition(add(ivar13, 1), add(ivar14, 1), 1, 1); + } else { + createExtraChild(new WidgetPointer(arg5), 3, arg10); + setWidgetPosition(add(ivar13, 1), add(ivar14, 1), 1, 1); + setWidgetSize(arg4, arg4, 0, 0); + setWidgetRGB(new Color(0, 0, 0)); + setWidgetFilled(1); + } + ivar22 = 0; + ivar23 = 0; + ivar24 = 0; + ivar25 = 0; + if (setWidgetRegister(new WidgetPointer(arg5), ivar11)) { + setWidgetPosition(ivar13, ivar14, 1, 1); + } else { + stack_dump0 = arg3; + structdump_9 = script_2413(stack_dump0); + ivar24 = structdump_9.intpart_2; + ivar23 = structdump_9.intpart_1; + ivar22 = structdump_9.intpart_0; + stack_dump0 = max(subtract(ivar22, 48), 0); + stack_dump1 = max(subtract(ivar23, 48), 0); + ivar24 = max(subtract(ivar24, 48), 0); + stack_dump0 = stack_dump0; + ivar23 = stack_dump1; + ivar22 = stack_dump0; + ivar25 = script_693(ivar22, ivar23, ivar24); + createExtraChild(new WidgetPointer(arg5), 3, ivar11); + setWidgetPosition(ivar13, ivar14, 1, 1); + setWidgetSize(arg4, arg4, 0, 0); + setWidgetRGB(new Color(ivar25)); + setWidgetFilled(1); + setScriptCallOnMouseEntered(301, 1, new WidgetPointer(arg5), ivar11, -1, ivar12, arg3, "1Iiiii"); + setScriptCallOnMouseExit(301, 0, new WidgetPointer(arg5), ivar11, -1, ivar12, ivar25, "1Iiiii"); + setWidgetContextMenuOption(1, "Scroll map"); + setScriptCallOnClickContextMenu(302, -2147483644, arg1, arg2, "ic1"); + } + if (setWidgetRegister(new WidgetPointer(arg5), ivar12)) { + setWidgetPosition(ivar17, ivar18, 1, 1); + setWidgetSize(ivar19, ivar20, 0, 0); + } else { + createExtraChild(new WidgetPointer(arg5), 9, ivar12); + setWidgetPosition(ivar17, ivar18, 1, 1); + setWidgetSize(ivar19, ivar20, 0, 0); + cs2method1124(ivar21); + cs2method1104(add(1, divide(arg4, 5))); + setWidgetRGB(new Color(arg3)); + setWidgetHidden(1); + } + return add(ivar12, 1); +} diff --git a/dumps/scripts/2980.cs2 b/dumps/scripts/2980.cs2 new file mode 100644 index 0000000..e009a18 --- /dev/null +++ b/dumps/scripts/2980.cs2 @@ -0,0 +1,12 @@ +void script_2980(int arg0) { + int ivar1; + ivar1 = script_284(getMyPositionHash()); + cs2method5405(0, 2); + cs2method5405(1, 2); + cs2method5406(0, 0, addToCoordinate(ivar1, 19, 0, 28), 900, addToCoordinate(ivar1, 19, 0, 28), 900, 0); + cs2method5406(1, 0, addToCoordinate(ivar1, 27, 0, 29), 400, addToCoordinate(ivar1, 27, 0, 29), 400, 0); + cs2method5406(0, 1, addToCoordinate(ivar1, 19, 0, 28), 1000, addToCoordinate(ivar1, 19, 0, 28), 1000, 0); + cs2method5406(1, 1, addToCoordinate(ivar1, 25, 0, 29), 300, addToCoordinate(ivar1, 25, 0, 29), 300, 0); + cameraMethod5502(0, 0, 450, 450, 1, 0); + return; +} diff --git a/dumps/scripts/2981.cs2 b/dumps/scripts/2981.cs2 new file mode 100644 index 0000000..213da3a --- /dev/null +++ b/dumps/scripts/2981.cs2 @@ -0,0 +1,12 @@ +void script_2981(int arg0) { + int ivar1; + ivar1 = script_284(getMyPositionHash()); + cs2method5405(0, 2); + cs2method5405(1, 2); + cs2method5406(0, 0, addToCoordinate(ivar1, 22, 0, 20), 700, addToCoordinate(ivar1, 22, 0, 20), 700, 0); + cs2method5406(1, 0, addToCoordinate(ivar1, 20, 0, 31), 500, addToCoordinate(ivar1, 20, 0, 31), 500, 0); + cs2method5406(0, 1, addToCoordinate(ivar1, 22, 0, 25), 700, addToCoordinate(ivar1, 22, 0, 25), 700, 0); + cs2method5406(1, 1, addToCoordinate(ivar1, 20, 0, 31), 400, addToCoordinate(ivar1, 20, 0, 31), 400, 0); + cameraMethod5502(0, 0, 450, 450, 1, 0); + return; +} diff --git a/dumps/scripts/2982.cs2 b/dumps/scripts/2982.cs2 new file mode 100644 index 0000000..7cd35f5 --- /dev/null +++ b/dumps/scripts/2982.cs2 @@ -0,0 +1,12 @@ +void script_2982(int arg0) { + int ivar1; + ivar1 = script_284(getMyPositionHash()); + cs2method5405(0, 2); + cs2method5405(1, 2); + cs2method5406(0, 0, addToCoordinate(ivar1, 22, 0, 25), 1000, addToCoordinate(ivar1, 22, 0, 25), 1000, 0); + cs2method5406(1, 0, addToCoordinate(ivar1, 20, 0, 31), 300, addToCoordinate(ivar1, 20, 0, 31), 300, 0); + cs2method5406(0, 1, addToCoordinate(ivar1, 30, 0, 23), 1000, addToCoordinate(ivar1, 30, 0, 23), 1000, 0); + cs2method5406(1, 1, addToCoordinate(ivar1, 12, 0, 30), 300, addToCoordinate(ivar1, 12, 0, 30), 300, 0); + cameraMethod5502(0, 0, 450, 450, 1, 0); + return; +} diff --git a/dumps/scripts/2983.cs2 b/dumps/scripts/2983.cs2 new file mode 100644 index 0000000..6698d3d --- /dev/null +++ b/dumps/scripts/2983.cs2 @@ -0,0 +1,12 @@ +void script_2983(int arg0) { + int ivar1; + ivar1 = script_284(getMyPositionHash()); + cs2method5405(0, 2); + cs2method5405(1, 2); + cs2method5406(0, 0, addToCoordinate(ivar1, 26, 0, 23), 500, addToCoordinate(ivar1, 26, 0, 23), 500, 0); + cs2method5406(1, 0, addToCoordinate(ivar1, 12, 0, 30), 400, addToCoordinate(ivar1, 12, 0, 30), 400, 0); + cs2method5406(0, 1, addToCoordinate(ivar1, 30, 0, 25), 900, addToCoordinate(ivar1, 30, 0, 25), 900, 0); + cs2method5406(1, 1, addToCoordinate(ivar1, 30, 0, 33), 500, addToCoordinate(ivar1, 30, 0, 33), 500, 0); + cameraMethod5502(0, 0, 450, 950, 1, 0); + return; +} diff --git a/dumps/scripts/2984.cs2 b/dumps/scripts/2984.cs2 new file mode 100644 index 0000000..5ab219a --- /dev/null +++ b/dumps/scripts/2984.cs2 @@ -0,0 +1,15 @@ +void script_2984(int arg0) { + int ivar1; + ivar1 = script_284(getMyPositionHash()); + cs2method5405(0, 3); + cs2method5405(1, 3); + cs2method5406(0, 0, addToCoordinate(ivar1, 26, 0, 3), 400, addToCoordinate(ivar1, 26, 0, 3), 400, 0); + cs2method5406(1, 0, addToCoordinate(ivar1, 12, 0, 23), 300, addToCoordinate(ivar1, 12, 0, 23), 300, 0); + cs2method5406(0, 1, addToCoordinate(ivar1, 28, 0, 16), 700, addToCoordinate(ivar1, 28, 0, 16), 700, 0); + cs2method5406(1, 1, addToCoordinate(ivar1, 13, 0, 22), 400, addToCoordinate(ivar1, 13, 0, 22), 400, 0); + cs2method5406(0, 2, addToCoordinate(ivar1, 36, 0, 16), 800, addToCoordinate(ivar1, 36, 0, 16), 800, 0); + cs2method5406(1, 2, addToCoordinate(ivar1, 36, 0, 22), 400, addToCoordinate(ivar1, 36, 0, 22), 400, 0); + cameraMethod5502(0, 0, 450, 450, 1, 0); + setScriptCallOnMinimapRelatedSetting3(2985, new WidgetPointer(arg0), "I", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/2985.cs2 b/dumps/scripts/2985.cs2 new file mode 100644 index 0000000..85ce0ed --- /dev/null +++ b/dumps/scripts/2985.cs2 @@ -0,0 +1,5 @@ +void script_2985(int arg0) { + setScriptCallOnMinimapRelatedSetting3(-1, "", new WidgetPointer(arg0)); + cameraMethod5502(0, 1, 450, 450, 1, 1); + return; +} diff --git a/dumps/scripts/2986.cs2 b/dumps/scripts/2986.cs2 new file mode 100644 index 0000000..4e3cc75 --- /dev/null +++ b/dumps/scripts/2986.cs2 @@ -0,0 +1,33 @@ +void script_2986() { + if (((boolean)bitconfig_8386)) { + script_2987(4718594, 4718593, 4718623, 4718595); + } + if (((boolean)bitconfig_8393)) { + script_2987(4718597, 4718596, 4718624, 4718598); + } + if (((boolean)bitconfig_8394)) { + script_2987(4718600, 4718599, 4718625, 4718601); + } + if (((boolean)bitconfig_8395)) { + script_2987(4718603, 4718602, 4718626, 4718604); + } + if (((boolean)bitconfig_8391)) { + script_2987(4718606, 4718605, 4718627, 4718607); + } + if (((boolean)bitconfig_8387)) { + script_2987(4718609, 4718608, 4718628, 4718610); + } + if (((boolean)bitconfig_8388)) { + script_2987(4718612, 4718611, 4718629, 4718613); + } + if (((boolean)bitconfig_8390)) { + script_2987(4718615, 4718614, 4718630, 4718616); + } + if (((boolean)bitconfig_8389)) { + script_2987(4718618, 4718617, 4718631, 4718619); + } + if (((boolean)bitconfig_8392)) { + script_2987(4718621, 4718620, 4718632, 4718622); + } + return; +} diff --git a/dumps/scripts/2987.cs2 b/dumps/scripts/2987.cs2 new file mode 100644 index 0000000..2262b50 --- /dev/null +++ b/dumps/scripts/2987.cs2 @@ -0,0 +1,7 @@ +void script_2987(int arg0,int arg1,int arg2,int arg3) { + setWidgetIsHidden(false, new WidgetPointer(arg0)); + setWidgetIsHidden(false, new WidgetPointer(arg1)); + setWidgetIsHidden(false, new WidgetPointer(arg3)); + setWidgetIsHidden(true, new WidgetPointer(arg2)); + return; +} diff --git a/dumps/scripts/2988.cs2 b/dumps/scripts/2988.cs2 new file mode 100644 index 0000000..84b6fa3 --- /dev/null +++ b/dumps/scripts/2988.cs2 @@ -0,0 +1,140 @@ +void script_2988(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + string svar0; + string svar1; + string svar2; + flow_0: + svar0 = "null"; + svar1 = "null"; + svar2 = "null"; + ivar1 = -1; + ivar2 = -1; + ivar3 = -1; + ivar4 = -1; + ivar5 = -1; + SWITCH (arg0) { + case 4718660: + GOTO flow_1 + case 4718659: + GOTO flow_4 + case 4718658: + GOTO flow_7 + case 4718657: + GOTO flow_10 + case 4718656: + GOTO flow_13 + case 4718665: + GOTO flow_16 + case 4718664: + GOTO flow_19 + case 4718663: + GOTO flow_22 + case 4718662: + GOTO flow_25 + case 4718661: + GOTO flow_28 + } + svar1 = "Coming soon"; + GOTO flow_31 + flow_1: + if (((boolean)bitconfig_8386)) { + return; + } + svar0 = "Common jadinko"; + svar1 = "The most abundant form of jadinko. The common jadinkos lack the magical properties of their counterparts; however, they are the easiest of all the jadinkos to attract." + "
" + "
" + "These jadinkos are caught with marasamaw plants."; + svar2 = "To attract common jadinkos:" + "
" + "
" + "grow any of the vine flowers."; + ivar5 = 62244; + GOTO flow_31 + flow_4: + if (((boolean)bitconfig_8393)) { + return; + } + svar0 = "Shadow jadinko"; + svar1 = "This species of jadinko is particularly sinister, tied as it is with darkness. Shadow jadinkos produce shadow vines which are useful for those who want to be more stealthy when hunting." + "
" + "
" + "These jadinkos are caught by tracking."; + svar2 = "To attract shadow jadinkos:" + "
" + "
" + "grow red vine flowers and build an abandoned house."; + ivar5 = 62253; + GOTO flow_31 + flow_7: + if (((boolean)bitconfig_8394)) { + return; + } + svar0 = "Diseased jadinko"; + svar1 = "The diseased jadinko is a sorry sort of creature, corrupted by some unknown illness that it can never shake. That's unfortunate for the jadinko, but fortunate for the hunter, because the corrupt vines these creatures produce can be made into juju hunter potions that are invaluable for hunting in the habitat." + "
" + "
" + "These jadinkos are caught by tracking."; + svar2 = "To attract diseased jadinkos:" + "
" + "
" + "grow a banana tree and build a boneyard."; + ivar5 = 62251; + GOTO flow_31 + flow_10: + if (((boolean)bitconfig_8395)) { + return; + } + svar0 = "Igneous jadinko"; + svar1 = "The igneous jadinko have a great affinity with the earth. They dwell beneath the stones, unless attracted by the sweet scent of lergberry and oranges. Their vines are particularly useful for those who wish to gather herbs more efficiently." + "
" + "
" + "These jadinkos are caught with marasamaw plants."; + svar2 = "To attract igneous jadinkos:" + "
" + "
" + "grow a lergberry bush, an orange tree, a blue vine plant and construct a thermal vent."; + ivar5 = 62249; + GOTO flow_31 + flow_13: + if (((boolean)bitconfig_8391)) { + return; + } + svar0 = "Cannibal jadinko"; + svar1 = "These jadinko prey on other jadinkos. They roam the habitat looking for other creatures to snack on. Unlike other jadinkos, the cannibal jadinko's magic is located not in the vine, but in its teeth. The plant teeth can be used to make a deliciously tasty gumbo, if mixed with the right herbs." + "
" + "
" + "These jadinkos are caught with marasamaw plants."; + svar2 = "To attract cannibal jadinkos:" + "
" + "
" + "grow a kalferberry bush, a green vine flower, construct tall grass and be sure to have used the juju hunter potion on the flower."; + ivar5 = 62241; + GOTO flow_31 + flow_16: + if (((boolean)bitconfig_8387)) { + return; + } + svar0 = "Aquatic jadinko"; + svar1 = "The aquatic jadinko rarely comes out on land, but, when it does, it's highly sought after by the discerning hunter. The vines that grow from this creature's back can be used to create a juju fishing potion that allows you to catch the elusive baron shark." + "
" + "
" + "These jadinkos are caught with marasamaw plants."; + svar2 = "To attract aquatic jadinkos:" + "
" + "
" + "grow a kalferberry bush, an apple tree, a red vine flower and construct a pond. You must also be under the effects of a juju hunter potion."; + ivar5 = 62250; + GOTO flow_31 + flow_19: + if (((boolean)bitconfig_8388)) { + return; + } + svar0 = "Amphibious jadinko"; + svar1 = "The amphibious jadinko is as at home on land as it is in water. These creatures may be slimy and froggish, but their oily vines can be extremely useful. When combined with the appropriate herb, their vines can be used to create potions that attract wood spirits when you are woodcutting, making a lumberjack's life significantly easier." + "
" + "
" + "These jadinkos are caught with marasamaw plants."; + svar2 = "To attract amphibian jadinkos:" + "
" + "
" + "grow a lergberry bush, a blue flower and construct a pond."; + ivar5 = 62243; + GOTO flow_31 + flow_22: + if (((boolean)bitconfig_8390)) { + return; + } + svar0 = "Carrion jadinko"; + svar1 = "The carrion jadinko is probably the least pleasant of the jadinko species. They scavenge on the leftovers of other creatures and feast cannibalistically on the remains of other hunted jadinkos. The vines that these creatures produce are particularly pungent and rot rather nicely to create supercompost."; + svar2 = "To attract carrion jadinkos:" + "
" + "
" + "grow a kalferberry bush, a green vine flower and build a boneyard."; + ivar5 = 62248; + GOTO flow_31 + flow_25: + if (((boolean)bitconfig_8389)) { + return; + } + svar0 = "Camouflaged jadinko"; + svar1 = "The camouflaged jadinko is a stealthy critter that takes great delight in hiding itself in foliage. The magic of its striped vines is particularly odd and cannot be turned into a potion; however, Papa Mambo has mentioned that he has uses for these vines." + "
" + "
" + "These jadinkos are caught by tracking."; + svar2 = "To attract camouflaged jadinkos:" + "
" + "
" + "grow a lergberry bush and build standing stones. In addition, you must be under the effects of the juju hunter potion."; + ivar5 = 62245; + GOTO flow_31 + flow_28: + if (((boolean)bitconfig_8392)) { + return; + } + svar0 = "Draconic jadinko"; + svar1 = "While not dragons, these rare and elusive creatures certainly resemble them. They are powerful beasts with a deep connection to the earth: so deep that their vines can be used to create powerful potions that attracts the mining spirits of stone." + "
" + "
" + "These jadinkos are caught with marasamaw plants."; + svar2 = "To attract draconic jadinkos:" + "
" + "
" + "grow a lergberry bush, a red vine flower and build a dark pit. In addition you will need to be under the influence of the juju hunter potion."; + ivar5 = 62238; + flow_31: + setWidgetIsHidden(true, new WidgetPointer(72,56)); + setWidgetIsHidden(false, new WidgetPointer(72,58)); + setWidgetText(new WidgetPointer(72,60), svar0); + setWidgetText(new WidgetPointer(72,61), svar1); + setWidgetText(new WidgetPointer(72,62), svar2); + setWidgetModel(ivar5, new WidgetPointer(72,59)); + return; +} diff --git a/dumps/scripts/2989.cs2 b/dumps/scripts/2989.cs2 new file mode 100644 index 0000000..3fb02a2 --- /dev/null +++ b/dumps/scripts/2989.cs2 @@ -0,0 +1,5 @@ +void script_2989() { + setWidgetIsHidden(true, new WidgetPointer(72,58)); + setWidgetIsHidden(false, new WidgetPointer(72,56)); + return; +} diff --git a/dumps/scripts/299.cs2 b/dumps/scripts/299.cs2 new file mode 100644 index 0000000..fddd0f4 --- /dev/null +++ b/dumps/scripts/299.cs2 @@ -0,0 +1,5 @@ +void script_299(int arg0,int arg1,int arg2) { + script_41(arg0); + setWidgetSprite(arg2, new WidgetPointer(arg1)); + return; +} diff --git a/dumps/scripts/2990.cs2 b/dumps/scripts/2990.cs2 new file mode 100644 index 0000000..2f40cda --- /dev/null +++ b/dumps/scripts/2990.cs2 @@ -0,0 +1,5 @@ +void script_2990() { + setWidgetSprite(4031, new WidgetPointer(72,75)); + setWidgetSprite(4031, new WidgetPointer(72,63)); + return; +} diff --git a/dumps/scripts/2991.cs2 b/dumps/scripts/2991.cs2 new file mode 100644 index 0000000..30ccf34 --- /dev/null +++ b/dumps/scripts/2991.cs2 @@ -0,0 +1,5 @@ +void script_2991() { + setWidgetSprite(4032, new WidgetPointer(72,75)); + setWidgetSprite(4032, new WidgetPointer(72,63)); + return; +} diff --git a/dumps/scripts/2992.cs2 b/dumps/scripts/2992.cs2 new file mode 100644 index 0000000..5e8fbad --- /dev/null +++ b/dumps/scripts/2992.cs2 @@ -0,0 +1,33 @@ +void script_2992() { + if (((boolean)bitconfig_8386)) { + setWidgetIsHidden(true, new WidgetPointer(311,25)); + setWidgetIsHidden(false, new WidgetPointer(311,26)); + setWidgetIsHidden(true, new WidgetPointer(311,57)); + setWidgetIsHidden(true, new WidgetPointer(311,59)); + } + if (((boolean)bitconfig_8388)) { + setWidgetIsHidden(true, new WidgetPointer(311,9)); + setWidgetIsHidden(false, new WidgetPointer(311,10)); + } + if (((boolean)bitconfig_8390)) { + setWidgetIsHidden(true, new WidgetPointer(311,5)); + setWidgetIsHidden(false, new WidgetPointer(311,6)); + } + if (((boolean)bitconfig_8392)) { + setWidgetIsHidden(true, new WidgetPointer(311,1)); + setWidgetIsHidden(false, new WidgetPointer(311,2)); + } + if (((boolean)bitconfig_8387)) { + setWidgetIsHidden(true, new WidgetPointer(311,13)); + setWidgetIsHidden(false, new WidgetPointer(311,14)); + } + if (((boolean)bitconfig_8395)) { + setWidgetIsHidden(true, new WidgetPointer(311,21)); + setWidgetIsHidden(false, new WidgetPointer(311,22)); + } + if (((boolean)bitconfig_8391)) { + setWidgetIsHidden(true, new WidgetPointer(311,17)); + setWidgetIsHidden(false, new WidgetPointer(311,18)); + } + return; +} diff --git a/dumps/scripts/2993.cs2 b/dumps/scripts/2993.cs2 new file mode 100644 index 0000000..ce12fce --- /dev/null +++ b/dumps/scripts/2993.cs2 @@ -0,0 +1,6 @@ +void script_2993(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6) { + createExtraChild(new WidgetPointer(arg1), arg0, arg2); + setWidgetSize(arg3, arg4, 0, 0); + setWidgetPosition(arg5, arg6, 0, 0); + return; +} diff --git a/dumps/scripts/2994.cs2 b/dumps/scripts/2994.cs2 new file mode 100644 index 0000000..3cee1c7 --- /dev/null +++ b/dumps/scripts/2994.cs2 @@ -0,0 +1,11 @@ +void script_2994(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10) { + createExtraChild(new WidgetPointer(arg0), 5, arg1); + setWidgetSize(arg2, arg3, 0, 0); + setWidgetPosition(arg4, arg5, 0, 0); + setWidgetSprite(arg6); + setWidgetHFlip(arg7); + setWidgetVFlip(arg8); + cs2method1107(arg9); + cs2method2103(arg10); + return; +} diff --git a/dumps/scripts/2995.cs2 b/dumps/scripts/2995.cs2 new file mode 100644 index 0000000..9ffa6cf --- /dev/null +++ b/dumps/scripts/2995.cs2 @@ -0,0 +1,11 @@ +void script_2995(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,string arg12) { + createExtraChild(new WidgetPointer(arg0), 4, arg1); + setWidgetSize(arg2, arg3, 0, 0); + setWidgetPosition(arg4, arg5, 0, 0); + setWidgetText(arg12); + setWidgetRGB(new Color(arg6)); + setWidgetFont(arg7); + setWidgetTextAlignment(arg8, arg9, arg10); + setWidgetUnknownBoolean(((boolean)arg11)); + return; +} diff --git a/dumps/scripts/2996.cs2 b/dumps/scripts/2996.cs2 new file mode 100644 index 0000000..1979410 --- /dev/null +++ b/dumps/scripts/2996.cs2 @@ -0,0 +1,9 @@ +void script_2996(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8) { + createExtraChild(new WidgetPointer(arg0), 3, arg1); + setWidgetSize(arg2, arg3, 0, 0); + setWidgetPosition(arg4, arg5, 0, 0); + setWidgetRGB(new Color(arg6)); + setWidgetFilled(arg7); + cs2method2103(arg8); + return; +} diff --git a/dumps/scripts/2997.cs2 b/dumps/scripts/2997.cs2 new file mode 100644 index 0000000..65d3a61 --- /dev/null +++ b/dumps/scripts/2997.cs2 @@ -0,0 +1,12 @@ +void script_2997(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12,int arg13) { + createExtraChild(new WidgetPointer(arg0), 6, arg1); + setWidgetSize(arg2, arg3, 0, 0); + setWidgetPosition(arg4, arg5, 0, 0); + if (arg6 != -1) { + setWidgetModel(arg6); + setWidget3DRotation(arg8, arg9, arg10, arg11, arg12, arg13); + } else { + setItemOnWidgetMethod1200(arg7, -1); + } + return; +} diff --git a/dumps/scripts/2998.cs2 b/dumps/scripts/2998.cs2 new file mode 100644 index 0000000..8e4a61e --- /dev/null +++ b/dumps/scripts/2998.cs2 @@ -0,0 +1,57 @@ +void script_2998() { + int ivar0; + int stack_dump0; + int stack_dump1; + cs2func_script_3011_struct(7,0,0) structdump_2; + cs2func_script_3011_struct(7,0,0) structdump_3; + cs2func_script_3011_struct(7,0,0) structdump_4; + cs2func_script_3011_struct(7,0,0) structdump_5; + script_2999(); + setScriptCallOnMousePressed(3002, 0, "i", new WidgetPointer(907,41)); + setScriptCallOnMousePressed(3002, 1, "i", new WidgetPointer(907,29)); + setScriptCallOnMousePressed(3002, 2, "i", new WidgetPointer(907,17)); + setScriptCallOnMousePressed(3002, 3, "i", new WidgetPointer(907,55)); + ivar0 = 0; + if (getWidgetSpriteId(new WidgetPointer(907,34)) == 2672) { + ivar0 = 0; + } else if (getWidgetSpriteId(new WidgetPointer(907,22)) == 2672) { + ivar0 = 1; + } else if (getWidgetSpriteId(new WidgetPointer(907,10)) == 2672) { + ivar0 = 2; + } else { + if (getWidgetSpriteId(new WidgetPointer(907,48)) == 2672) { + ivar0 = 3; + } + } + switch (ivar0) { + case 0: + stack_dump0 = 0; + stack_dump1 = 0; + structdump_2 = script_3011(stack_dump1); + script_3006(stack_dump0, structdump_2.intpart_0, structdump_2.intpart_1, structdump_2.intpart_2, structdump_2.intpart_3, structdump_2.intpart_4, structdump_2.intpart_5, structdump_2.intpart_6); + break; + case 1: + stack_dump0 = 1; + stack_dump1 = 1; + structdump_3 = script_3011(stack_dump1); + script_3006(stack_dump0, structdump_3.intpart_0, structdump_3.intpart_1, structdump_3.intpart_2, structdump_3.intpart_3, structdump_3.intpart_4, structdump_3.intpart_5, structdump_3.intpart_6); + break; + case 2: + stack_dump0 = 2; + stack_dump1 = 2; + structdump_4 = script_3011(stack_dump1); + script_3006(stack_dump0, structdump_4.intpart_0, structdump_4.intpart_1, structdump_4.intpart_2, structdump_4.intpart_3, structdump_4.intpart_4, structdump_4.intpart_5, structdump_4.intpart_6); + break; + case 3: + stack_dump0 = 3; + stack_dump1 = 3; + structdump_5 = script_3011(stack_dump1); + script_3006(stack_dump0, structdump_5.intpart_0, structdump_5.intpart_1, structdump_5.intpart_2, structdump_5.intpart_3, structdump_5.intpart_4, structdump_5.intpart_5, structdump_5.intpart_6); + } + setWidgetIsHidden(false, new WidgetPointer(907,2)); + script_3001(); + setScriptCallOnGameloop(3000, "", new WidgetPointer(907,1)); + openInterface(59441194, 908); + script_3014(); + return; +} diff --git a/dumps/scripts/2999.cs2 b/dumps/scripts/2999.cs2 new file mode 100644 index 0000000..d0b551a --- /dev/null +++ b/dumps/scripts/2999.cs2 @@ -0,0 +1,236 @@ +void script_2999() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + string svar0; + string svar1; + string svar2; + string svar3; + string svar4; + string svar5; + int stack_dump0; + cs2func_script_3011_struct(7,0,0) structdump_1; + cs2func_script_3011_struct(7,0,0) structdump_2; + cs2func_script_3011_struct(7,0,0) structdump_3; + cs2func_script_3011_struct(7,0,0) structdump_4; + cs2func_script_3011_struct(7,0,0) structdump_5; + cs2func_script_3011_struct(7,0,0) structdump_6; + cs2func_script_3011_struct(7,0,0) structdump_7; + cs2func_script_3011_struct(7,0,0) structdump_8; + cs2func_script_3011_struct(7,0,0) structdump_9; + cs2func_script_3011_struct(7,0,0) structdump_10; + opcStruct6901(3,0,0) structdump_11; + cs2func_script_3011_struct(7,0,0) structdump_12; + cs2func_script_3011_struct(7,0,0) structdump_13; + cs2func_script_3011_struct(7,0,0) structdump_14; + svar0 = ""; + svar1 = ""; + svar2 = ""; + svar3 = ""; + svar0 = "email-register"; + switch (cs2method6906()) { + case 0: + setWidgetSprite(2672, new WidgetPointer(907,34)); + stack_dump0 = 0; + structdump_1 = script_3011(stack_dump0); + script_3010(structdump_1.intpart_0, structdump_1.intpart_1, structdump_1.intpart_2, structdump_1.intpart_3, structdump_1.intpart_4, structdump_1.intpart_5, structdump_1.intpart_6); + setWidgetText(new WidgetPointer(907,39), "Unregistered"); + svar2 = "You do not currently have an email address registered. Click " + "" + "" + "here" + "" + "" + " to register."; + svar3 = "You do not currently have an email address registered. Click " + "" + "" + "here" + "" + "" + " to register."; + setWidgetText(new WidgetPointer(907,40), svar2); + setScriptCallOnMouseEntered(68, new WidgetPointer(-32768,3), svar3, "Is", new WidgetPointer(907,40)); + setScriptCallOnMouseExit(68, new WidgetPointer(-32768,3), svar2, "Is", new WidgetPointer(907,40)); + svar1 = "set_address.ws"; + break; + case 1: + setWidgetSprite(2672, new WidgetPointer(907,34)); + stack_dump0 = 0; + structdump_2 = script_3011(stack_dump0); + script_3010(structdump_2.intpart_0, structdump_2.intpart_1, structdump_2.intpart_2, structdump_2.intpart_3, structdump_2.intpart_4, structdump_2.intpart_5, structdump_2.intpart_6); + setWidgetText(new WidgetPointer(907,39), "Pending Parental Confirmation"); + svar2 = "You have registered your email address. We are currently waiting for your parent to confirm their email address. Click " + "" + "" + "here" + "" + "" + " to submit a confirmation code."; + svar3 = "You have registered your email address. We are currently waiting for your parent to confirm their email address. Click " + "" + "" + "here" + "" + "" + " to submit a confirmation code."; + setWidgetText(new WidgetPointer(907,40), svar2); + setScriptCallOnMouseEntered(68, new WidgetPointer(-32768,3), svar3, "Is", new WidgetPointer(907,40)); + setScriptCallOnMouseExit(68, new WidgetPointer(-32768,3), svar2, "Is", new WidgetPointer(907,40)); + svar1 = "enter_code.ws"; + break; + case 2: + setWidgetSprite(2672, new WidgetPointer(907,34)); + stack_dump0 = 0; + structdump_3 = script_3011(stack_dump0); + script_3010(structdump_3.intpart_0, structdump_3.intpart_1, structdump_3.intpart_2, structdump_3.intpart_3, structdump_3.intpart_4, structdump_3.intpart_5, structdump_3.intpart_6); + setWidgetText(new WidgetPointer(907,39), "Pending Confirmation"); + svar2 = "Your email address is currently pending confirmation. Click " + "" + "" + "here" + "" + "" + " to submit a confirmation code."; + svar3 = "Your email address is currently pending confirmation. Click " + "" + "" + "here" + "" + "" + " to submit a confirmation code."; + setWidgetText(new WidgetPointer(907,40), svar2); + setScriptCallOnMouseEntered(68, new WidgetPointer(-32768,3), svar3, "Is", new WidgetPointer(907,40)); + setScriptCallOnMouseExit(68, new WidgetPointer(-32768,3), svar2, "Is", new WidgetPointer(907,40)); + svar1 = "enter_code.ws"; + break; + case 3: + setWidgetSprite(2669, new WidgetPointer(907,34)); + stack_dump0 = 0; + structdump_4 = script_3011(stack_dump0); + script_3008(structdump_4.intpart_0, structdump_4.intpart_1, structdump_4.intpart_2, structdump_4.intpart_3, structdump_4.intpart_4, structdump_4.intpart_5, structdump_4.intpart_6); + setWidgetText(new WidgetPointer(907,39), "Registered"); + svar2 = "Your email address is now registered. Click " + "" + "" + "here" + "" + "" + " to view or change your email preferences."; + svar3 = "Your email address is now registered. Click " + "" + "" + "here" + "" + "" + " to view or change your email preferences."; + setWidgetText(new WidgetPointer(907,40), svar2); + setScriptCallOnMouseEntered(68, new WidgetPointer(-32768,3), svar3, "Is", new WidgetPointer(907,40)); + setScriptCallOnMouseExit(68, new WidgetPointer(-32768,3), svar2, "Is", new WidgetPointer(907,40)); + svar1 = "change_settings.ws"; + break; + case 4: + setWidgetSprite(2669, new WidgetPointer(907,34)); + stack_dump0 = 0; + structdump_5 = script_3011(stack_dump0); + script_3008(structdump_5.intpart_0, structdump_5.intpart_1, structdump_5.intpart_2, structdump_5.intpart_3, structdump_5.intpart_4, structdump_5.intpart_5, structdump_5.intpart_6); + setWidgetText(new WidgetPointer(907,39), "No longer registered"); + svar2 = "Your account no longer has a registered email address. Click " + "" + "" + "here" + "" + "" + " to register again."; + svar3 = "Your account no longer has a registered email address. Click " + "" + "" + "here" + "" + "" + " to register again."; + setWidgetText(new WidgetPointer(907,40), svar2); + setScriptCallOnMouseEntered(68, new WidgetPointer(-32768,3), svar3, "Is", new WidgetPointer(907,40)); + setScriptCallOnMouseExit(68, new WidgetPointer(-32768,3), svar2, "Is", new WidgetPointer(907,40)); + svar1 = "set_address.ws"; + } + setScriptCallOnMousePressed(3088, svar0, svar1, 1, "ss1", new WidgetPointer(907,40)); + script_3376(59441192); + ivar0 = getRecoveryQuestionsDate(); + svar0 = "recovery_questions"; + if (((boolean)ivar0)) { + setWidgetSprite(2672, new WidgetPointer(907,22)); + stack_dump0 = 1; + structdump_6 = script_3011(stack_dump0); + script_3010(structdump_6.intpart_0, structdump_6.intpart_1, structdump_6.intpart_2, structdump_6.intpart_3, structdump_6.intpart_4, structdump_6.intpart_5, structdump_6.intpart_6); + setWidgetText(new WidgetPointer(907,27), "Not Set"); + svar2 = "You do not have any recovery questions set. It will be more difficult to recover your password if it gets stolen or you forget it. Click " + "" + "" + "here" + "" + "" + " to set your recovery questions."; + svar3 = "You do not have any recovery questions set. It will be more difficult to recover your password if it gets stolen or you forget it. Click " + "" + "" + "here" + "" + "" + " to set your recovery questions."; + setWidgetText(new WidgetPointer(907,28), svar2); + setScriptCallOnMouseEntered(68, new WidgetPointer(-32768,3), svar3, "Is", new WidgetPointer(907,28)); + setScriptCallOnMouseExit(68, new WidgetPointer(-32768,3), svar2, "Is", new WidgetPointer(907,28)); + svar1 = "add_recoveries.ws"; + } else if (ivar0 < add(getCurrentDaysSinceLaunch(), 1)) { + setWidgetSprite(2669, new WidgetPointer(907,22)); + stack_dump0 = 1; + structdump_7 = script_3011(stack_dump0); + script_3008(structdump_7.intpart_0, structdump_7.intpart_1, structdump_7.intpart_2, structdump_7.intpart_3, structdump_7.intpart_4, structdump_7.intpart_5, structdump_7.intpart_6); + setWidgetText(new WidgetPointer(907,27), "Set"); + svar2 = "Recovery questions last set: " + timeToStr(ivar0) + ". Click " + "" + "" + "here" + "" + "" + " to change your recovery questions."; + svar3 = "Recovery questions last set: " + timeToStr(ivar0) + ". Click " + "" + "" + "here" + "" + "" + " to change your recovery questions."; + setWidgetText(new WidgetPointer(907,28), svar2); + setScriptCallOnMouseEntered(68, new WidgetPointer(-32768,3), svar3, "Is", new WidgetPointer(907,28)); + setScriptCallOnMouseExit(68, new WidgetPointer(-32768,3), svar2, "Is", new WidgetPointer(907,28)); + svar1 = "add_recoveries.ws"; + } else { + setWidgetSprite(2672, new WidgetPointer(907,22)); + stack_dump0 = 1; + structdump_8 = script_3011(stack_dump0); + script_3010(structdump_8.intpart_0, structdump_8.intpart_1, structdump_8.intpart_2, structdump_8.intpart_3, structdump_8.intpart_4, structdump_8.intpart_5, structdump_8.intpart_6); + setWidgetText(new WidgetPointer(907,27), "Changed"); + svar2 = "Your new recovery questions will become active on " + timeToStr(ivar0) + ". If you didn't request this, cancel it and change your password immediately. Click " + "" + "" + "here" + "" + "" + " to cancel."; + svar3 = "Your new recovery questions will become active on " + timeToStr(ivar0) + ". If you didn't request this, cancel it and change your password immediately. Click " + "" + "" + "here" + "" + "" + " to cancel."; + setWidgetText(new WidgetPointer(907,28), svar2); + setScriptCallOnMouseEntered(68, new WidgetPointer(-32768,3), svar3, "Is", new WidgetPointer(907,28)); + setScriptCallOnMouseExit(68, new WidgetPointer(-32768,3), svar2, "Is", new WidgetPointer(907,28)); + svar1 = "cancel_recoveries.ws"; + } + setScriptCallOnMousePressed(3088, svar0, svar1, 1, "ss1", new WidgetPointer(907,28)); + script_3376(59441180); + ivar1 = cs2method6903(); + if (((boolean)ivar1)) { + setWidgetSprite(2669, new WidgetPointer(907,10)); + stack_dump0 = 2; + structdump_9 = script_3011(stack_dump0); + script_3008(structdump_9.intpart_0, structdump_9.intpart_1, structdump_9.intpart_2, structdump_9.intpart_3, structdump_9.intpart_4, structdump_9.intpart_5, structdump_9.intpart_6); + setWidgetText(new WidgetPointer(907,15), intToStr(ivar1) + " Unread"); + svar2 = "You have no unread messages. Click " + "" + "" + "here" + "" + "" + " to open your Message Centre."; + svar3 = "You have no unread messages. Click " + "" + "" + "here" + "" + "" + " to open your Message Centre."; + setWidgetText(new WidgetPointer(907,16), svar2); + setScriptCallOnMouseEntered(68, new WidgetPointer(-32768,3), svar3, "Is", new WidgetPointer(907,16)); + setScriptCallOnMouseExit(68, new WidgetPointer(-32768,3), svar2, "Is", new WidgetPointer(907,16)); + } else { + setWidgetSprite(2672, new WidgetPointer(907,10)); + stack_dump0 = 2; + structdump_10 = script_3011(stack_dump0); + script_3010(structdump_10.intpart_0, structdump_10.intpart_1, structdump_10.intpart_2, structdump_10.intpart_3, structdump_10.intpart_4, structdump_10.intpart_5, structdump_10.intpart_6); + setWidgetText(new WidgetPointer(907,15), intToStr(ivar1) + " Unread"); + if (((boolean)ivar1)) { + svar2 = "You have 1 unread message. Click " + "" + "" + "here" + "" + "" + " to open your Message Centre."; + svar3 = "You have 1 unread message. Click " + "" + "" + "here" + "" + "" + " to open your Message Centre."; + } else { + svar2 = "You have " + intToStr(ivar1) + " unread messages. Click " + "" + "" + "here" + "" + "" + " to open your Message Centre."; + svar3 = "You have " + intToStr(ivar1) + " unread messages. Click " + "" + "" + "here" + "" + "" + " to open your Message Centre."; + } + setWidgetText(new WidgetPointer(907,16), svar2); + setScriptCallOnMouseEntered(68, new WidgetPointer(-32768,3), svar3, "Is", new WidgetPointer(907,16)); + setScriptCallOnMouseExit(68, new WidgetPointer(-32768,3), svar2, "Is", new WidgetPointer(907,16)); + } + script_3376(59441168); + ivar2 = 0; + ivar3 = 0; + ivar4 = 0; + structdump_11 = cs2method6901(); + ivar2 = structdump_11.intpart_2; + ivar4 = structdump_11.intpart_1; + ivar3 = structdump_11.intpart_0; + svar4 = minutesToUtcTime(ivar3); + ivar5 = 0; + ivar6 = 0; + ivar7 = 0; + svar5 = ""; + if (((boolean)ivar2)) { + setWidgetSprite(2669, new WidgetPointer(907,48)); + stack_dump0 = 3; + structdump_12 = script_3011(stack_dump0); + script_3008(structdump_12.intpart_0, structdump_12.intpart_1, structdump_12.intpart_2, structdump_12.intpart_3, structdump_12.intpart_4, structdump_12.intpart_5, structdump_12.intpart_6); + setWidgetText(new WidgetPointer(907,53), "Subscription Active"); + svar2 = "You have an active subscription. Click " + "" + "" + "here" + "" + "" + " to view your account information. Make sure you play on a members' world to enjoy all of your members' benefits."; + svar3 = "You have an active subscription. Click " + "" + "" + "here" + "" + "" + " to view your account information. Make sure you play on a members' world to enjoy all of your members' benefits."; + setWidgetText(new WidgetPointer(907,54), svar2); + setScriptCallOnMouseEntered(68, new WidgetPointer(-32768,3), svar3, "Is", new WidgetPointer(907,54)); + setScriptCallOnMouseExit(68, new WidgetPointer(-32768,3), svar2, "Is", new WidgetPointer(907,54)); + svar0 = "billing_core"; + svar1 = "userdetails.ws"; + } else if (isSiteSettingsMembers()) { + ivar5 = divide(ivar4, 1440); + ivar6 = divide(mod(ivar4, 1440), 60); + ivar7 = mod(ivar4, 60); + if (add(add(ivar5, ivar6), ivar7) != 0) { + svar5 = " (in " + script_4582(ivar5, ivar6, ivar7) + ")"; + } + setWidgetSprite(2669, new WidgetPointer(907,48)); + stack_dump0 = 3; + structdump_13 = script_3011(stack_dump0); + script_3008(structdump_13.intpart_0, structdump_13.intpart_1, structdump_13.intpart_2, structdump_13.intpart_3, structdump_13.intpart_4, structdump_13.intpart_5, structdump_13.intpart_6); + setWidgetText(new WidgetPointer(907,53), "Expires " + svar4); + svar2 = "Your membership will expire on " + svar4 + svar5 + ". Renew now to avoid losing member status. Click " + "" + "" + "here" + "" + "" + " to renew."; + svar3 = "Your membership will expire on " + svar4 + svar5 + ". Renew now to avoid losing member status. Click " + "" + "" + "here" + "" + "" + " to renew."; + setWidgetText(new WidgetPointer(907,54), svar2); + setScriptCallOnMouseEntered(68, new WidgetPointer(-32768,3), svar3, "Is", new WidgetPointer(907,54)); + setScriptCallOnMouseExit(68, new WidgetPointer(-32768,3), svar2, "Is", new WidgetPointer(907,54)); + svar0 = "dob"; + svar1 = "set_members_dob.ws"; + } else { + setWidgetSprite(2672, new WidgetPointer(907,48)); + stack_dump0 = 3; + structdump_14 = script_3011(stack_dump0); + script_3010(structdump_14.intpart_0, structdump_14.intpart_1, structdump_14.intpart_2, structdump_14.intpart_3, structdump_14.intpart_4, structdump_14.intpart_5, structdump_14.intpart_6); + setWidgetText(new WidgetPointer(907,53), "Not a Member"); + svar2 = "You are not a member. Members get loads of extra benefits and features. Click " + "" + "" + "here" + "" + "" + " to become a member."; + svar3 = "You are not a member. Members get loads of extra benefits and features. Click " + "" + "" + "here" + "" + "" + " to become a member."; + setWidgetText(new WidgetPointer(907,54), svar2); + setScriptCallOnMouseEntered(68, new WidgetPointer(-32768,3), svar3, "Is", new WidgetPointer(907,54)); + setScriptCallOnMouseExit(68, new WidgetPointer(-32768,3), svar2, "Is", new WidgetPointer(907,54)); + svar0 = "dob"; + svar1 = "set_members_dob.ws"; + } + setScriptCallOnMousePressed(3088, svar0, svar1, 1, "ss1", new WidgetPointer(907,54)); + script_3376(59441206); + return; +} diff --git a/dumps/scripts/3.cs2 b/dumps/scripts/3.cs2 new file mode 100644 index 0000000..46f6a8e --- /dev/null +++ b/dumps/scripts/3.cs2 @@ -0,0 +1,970 @@ +cs2func_script_3_struct(2,2,0) script_3(int arg0,int arg1) { + switch (arg0) { + flow_1: + case 0: + switch (arg1) { + case 0: + return newstruct cs2func_script_3_struct(1, 8170, "Garden", "You can now build a " + "" + "garden" + "" + " for your house."); + case 1: + return newstruct cs2func_script_3_struct(1, 8315, "Parlour", "You can now build a " + "" + "parlour" + "" + " for your house."); + case 2: + return newstruct cs2func_script_3_struct(5, 8222, "Kitchen", "You can now build a " + "" + "kitchen" + "" + " for your house."); + case 3: + return newstruct cs2func_script_3_struct(10, 8121, "Dining room", "You can now build a " + "" + "dining room" + "" + " for your house."); + case 4: + return newstruct cs2func_script_3_struct(15, 8379, "Workshop", "You can now build a " + "" + "workshop" + "" + " for your house."); + case 5: + return newstruct cs2func_script_3_struct(20, 8037, "Bedroom", "You can now build a " + "" + "bedroom" + "" + " for your house."); + case 6: + return newstruct cs2func_script_3_struct(25, 8255, "Hall (skill trophies)", "You can now build a " + "" + "hall" + "" + " for your house, in which you can display " + "" + "skill trophies" + "" + "."); + case 7: + return newstruct cs2func_script_3_struct(30, 8163, "Games room", "You can now build a " + "" + "games room" + "" + " for your house."); + case 8: + return newstruct cs2func_script_3_struct(32, 8027, "Combat room", "You can now build a " + "" + "combat room" + "" + " for your house."); + case 9: + return newstruct cs2func_script_3_struct(35, 8259, "Hall (quest trophies)", "You can now build a " + "" + "hall" + "" + " for your house, in which you can display your " + "" + "quest trophies" + "" + "."); + case 10: + return newstruct cs2func_script_3_struct(37, 15221, "Menagerie", "You can now build a " + "" + "menagerie" + "" + " for your house."); + case 11: + return newstruct cs2func_script_3_struct(40, 8340, "Study", "You can now build a " + "" + "study" + "" + " for your house."); + case 12: + return newstruct cs2func_script_3_struct(42, 9822, "Costume room", "You can now build a " + "" + "costume room" + "" + " for your house."); + case 13: + return newstruct cs2func_script_3_struct(45, 8068, "Chapel", "You can now build a " + "" + "chapel" + "" + " for your house."); + case 14: + return newstruct cs2func_script_3_struct(50, 8333, "Portal chamber", "You can now build a " + "" + "portal chamber" + "" + " for your house."); + case 15: + return newstruct cs2func_script_3_struct(55, 8195, "Formal garden", "You can now build a " + "" + "formal garden" + "" + " for your house."); + case 16: + return newstruct cs2func_script_3_struct(60, 8363, "Throne room", "You can now build a " + "" + "throne room" + "" + " for your house."); + case 17: + return newstruct cs2func_script_3_struct(65, 8302, "Oubliette", "You can now build an " + "" + "oubliette" + "" + " for your house."); + case 18: + return newstruct cs2func_script_3_struct(70, 8123, "Dungeon", "You can now build a " + "" + "dungeon" + "" + " for your house."); + case 19: + return newstruct cs2func_script_3_struct(70, 8122, "Dungeon pit", "You can now build a " + "" + "dungeon pit" + "" + " in your dungeon (after Love Story)."); + case 20: + return newstruct cs2func_script_3_struct(75, 8151, "Treasure room", "You can now build a " + "" + "treasure room" + "" + " for your house."); + } + break; + case 1: + switch (arg1) { + case 0: + return newstruct cs2func_script_3_struct(3, 8325, "Clay fireplace", "You can now construct " + "" + "clay fireplaces" + "" + " for your house."); + case 1: + return newstruct cs2func_script_3_struct(5, 8216, "Firepit", "You can now construct " + "" + "firepits" + "" + " for your house."); + case 2: + return newstruct cs2func_script_3_struct(7, 8230, "Pump and drain", "You can now construct " + "" + "pumps and drains" + "" + " for your house."); + case 3: + return newstruct cs2func_script_3_struct(11, 8217, "Firepit with hook", "You can now construct " + "" + "firepits with hooks" + "" + " for your house."); + case 4: + return newstruct cs2func_script_3_struct(15, 8389, "Repair bench", "You can now construct " + "" + "repair benches" + "" + " for your house (at which you can repair " + "" + "bent arrows" + "" + " and " + "" + "broken staves" + "" + ")."); + case 5: + return newstruct cs2func_script_3_struct(16, 8392, "Pluming stand", "You can now construct " + "" + "pluming stands" + "" + " for your house."); + case 6: + return newstruct cs2func_script_3_struct(16, 8380, "Crafting table 1", "You can now construct " + "" + "crafting table 1" + "" + " for your house, at which you can craft " + "" + "toy horsies" + "" + "."); + case 7: + return newstruct cs2func_script_3_struct(17, 8218, "Firepit with pot", "You can now construct " + "" + "firepits with pots" + "" + " for your house."); + case 8: + return newstruct cs2func_script_3_struct(17, 8375, "Wooden workbench", "You can now construct " + "" + "wooden workbenches" + "" + " for your house, at which you can build " + "" + "flatpack items" + "" + " up to " + "" + "level 20 Construction" + "" + "."); + case 9: + return newstruct cs2func_script_3_struct(24, 8219, "Small oven", "You can now construct " + "" + "small ovens" + "" + " for your house."); + case 10: + return newstruct cs2func_script_3_struct(25, 8381, "Crafting table 2", "You can now construct " + "" + "crafting table 2" + "" + " for your house, at which you can craft " + "" + "toy horsies" + "" + " and " + "" + "clockwork mechanisms" + "" + "."); + case 11: + return newstruct cs2func_script_3_struct(27, 8231, "Pump and tub", "You can now construct " + "" + "pumps and tubs" + "" + " for your house."); + case 12: + return newstruct cs2func_script_3_struct(29, 8220, "Large oven", "You can now construct " + "" + "large ovens" + "" + " for your house."); + case 13: + return newstruct cs2func_script_3_struct(32, 8376, "Oak workbench", "You can now construct " + "" + "oak workbenches" + "" + " for your house, at which you can build " + "" + "flatpack items" + "" + " up to " + "" + "level 40 Construction" + "" + "."); + case 14: + return newstruct cs2func_script_3_struct(33, 8326, "Stone fireplace", "You can now construct " + "" + "stone fireplaces" + "" + " for your house."); + case 15: + return newstruct cs2func_script_3_struct(34, 8382, "Crafting table 3", "You can now construct " + "" + "crafting table 3" + "" + " for your house, at which you can craft " + "" + "toy horsies" + "" + ", " + "" + "clockwork mechanisms" + "" + ", " + "" + "clockwork soldiers" + "" + " and " + "" + "clockwork dolls" + "" + "."); + case 16: + return newstruct cs2func_script_3_struct(34, 8221, "Steel range", "You can now construct " + "" + "steel ranges" + "" + " for your house."); + case 17: + return newstruct cs2func_script_3_struct(35, 8390, "Whetstone", "You can now construct " + "" + "whetstones" + "" + " for your house, at which you can sharpen " + "" + "rusty swords" + "" + ", and repair " + "" + "broken arrows" + "" + " and " + "" + "staves" + "" + "."); + case 18: + return newstruct cs2func_script_3_struct(41, 8393, "Shield easel", "You can now construct " + "" + "shield easels" + "" + " for your house."); + case 19: + return newstruct cs2func_script_3_struct(42, 8222, "Fancy range", "You can now construct " + "" + "fancy ranges" + "" + " for your house."); + case 20: + return newstruct cs2func_script_3_struct(42, 8383, "Crafting table 4", "You can now construct " + "" + "crafting table 4" + "" + " for your house, at which you can craft " + "" + "toy horsies" + "" + ", " + "" + "clockwork mechanisms" + "" + ", " + "" + "clockwork soldiers" + "" + ", " + "" + "clockwork dolls" + "" + ", " + "" + "clockwork mice" + "" + ", " + "" + "clockwork cats" + "" + ", " + "" + "watches" + "" + " and " + "" + "sextants" + "" + "."); + case 21: + return newstruct cs2func_script_3_struct(46, 8377, "Steel-framed workbench", "You can now construct " + "" + "steel-framed workbenches" + "" + " for your house, at which you can build flatpack items" + "" + " up to level 60 Construction" + "" + "."); + case 22: + return newstruct cs2func_script_3_struct(47, 8232, "Sink", "You can now construct " + "" + "sinks" + "" + " for your house."); + case 23: + return newstruct cs2func_script_3_struct(55, 8391, "Armour stand", "You can now construct " + "" + "armour stands" + "" + " for your house, at which you can repair " + "" + "broken arrows" + "" + ", " + "" + "broken staves" + "" + ", " + "" + "rusty swords" + "" + ", " + "" + "damaged armour" + "" + " and " + "" + "damaged Barrows items" + "" + "."); + case 24: + return newstruct cs2func_script_3_struct(62, 8378, "Workbench with vice", "You can now construct " + "" + "workbenches with vices" + "" + " for your house, at which you can build " + "" + "flatpack items" + "" + " up to " + "" + "level 80 Construction" + "" + "."); + case 25: + return newstruct cs2func_script_3_struct(63, 8327, "Marble fireplace", "You can now construct " + "" + "marble fireplaces" + "" + " for your house."); + case 26: + return newstruct cs2func_script_3_struct(66, 8394, "Banner easel", "You can now construct " + "" + "banner easels" + "" + " for your house."); + case 27: + return newstruct cs2func_script_3_struct(77, 8379, "Workbench with lathe", "You can now construct " + "" + "workbenches with lathes" + "" + " for your house, at which you can build " + "" + "flatpack items" + "" + " of " + "" + "any level" + "" + "."); + } + break; + case 2: + switch (arg1) { + case 0: + return newstruct cs2func_script_3_struct(1, 8309, "Crude wooden chair", "You can now construct " + "" + "crude wooden chairs" + "" + " for your house."); + case 1: + return newstruct cs2func_script_3_struct(8, 8310, "Wooden chair", "You can now construct " + "" + "wooden chairs" + "" + " for your house."); + case 2: + return newstruct cs2func_script_3_struct(10, 8115, "Wooden dining table", "You can now construct " + "" + "wooden dining tables" + "" + " for your house."); + case 3: + return newstruct cs2func_script_3_struct(10, 8108, "Wooden dining bench", "You can now construct " + "" + "wooden dining benches" + "" + " for your house."); + case 4: + return newstruct cs2func_script_3_struct(12, 8246, "Wooden kitchen table", "You can now construct " + "" + "wooden kitchen tables" + "" + " for your house."); + case 5: + return newstruct cs2func_script_3_struct(14, 8311, "Rocking chair", "You can now construct " + "" + "rocking chairs" + "" + " for your house."); + case 6: + return newstruct cs2func_script_3_struct(19, 8312, "Oak chair", "You can now construct " + "" + "oak chairs" + "" + " for your house."); + case 7: + return newstruct cs2func_script_3_struct(20, 8031, "Wooden bed", "You can now construct " + "" + "wooden beds" + "" + " for your house."); + case 8: + return newstruct cs2func_script_3_struct(22, 8116, "Oak dining table", "You can now construct " + "" + "oak dining tables" + "" + " for your house."); + case 9: + return newstruct cs2func_script_3_struct(22, 8109, "Oak dining bench", "You can now construct " + "" + "oak dining benches" + "" + " for your house."); + case 10: + return newstruct cs2func_script_3_struct(26, 8313, "Oak armchair", "You can now construct " + "" + "oak armchairs" + "" + " for your house."); + case 11: + return newstruct cs2func_script_3_struct(30, 8032, "Oak bed", "You can now construct " + "" + "oak beds" + "" + " for your house."); + case 12: + return newstruct cs2func_script_3_struct(31, 8117, "Carved oak dining table", "You can now construct " + "" + "carved oak dining tables" + "" + " for your house."); + case 13: + return newstruct cs2func_script_3_struct(31, 8110, "Carved oak dining bench", "You can now construct " + "" + "carved oak dining benches" + "" + " for your house."); + case 14: + return newstruct cs2func_script_3_struct(32, 8247, "Oak kitchen table", "You can now construct " + "" + "oak kitchen tables" + "" + " for your house."); + case 15: + return newstruct cs2func_script_3_struct(34, 8033, "Large oak bed", "You can now construct " + "" + "large oak beds" + "" + " for your house."); + case 16: + return newstruct cs2func_script_3_struct(35, 8314, "Teak armchair", "You can now construct " + "" + "teak armchairs" + "" + " for your house."); + case 17: + return newstruct cs2func_script_3_struct(38, 8118, "Teak dining table", "You can now construct " + "" + "teak dining tables" + "" + " for your house."); + case 18: + return newstruct cs2func_script_3_struct(38, 8111, "Teak dining bench", "You can now construct " + "" + "teak dining benches" + "" + " for your house."); + case 19: + return newstruct cs2func_script_3_struct(40, 8034, "Teak bed", "You can now construct " + "" + "teak beds" + "" + " for your house."); + case 20: + return newstruct cs2func_script_3_struct(44, 8112, "Carved teak dining bench", "You can now construct " + "" + "carved teak dining benches" + "" + " for your house."); + case 21: + return newstruct cs2func_script_3_struct(45, 8119, "Carved teak dining table", "You can now construct " + "" + "carved teak dining tables" + "" + " for your house."); + case 22: + return newstruct cs2func_script_3_struct(45, 8035, "Large teak bed", "You can now construct " + "" + "large teak beds" + "" + " for your house."); + case 23: + return newstruct cs2func_script_3_struct(50, 8315, "Mahogany armchair", "You can now construct " + "" + "mahogany armchairs" + "" + " for your house."); + case 24: + return newstruct cs2func_script_3_struct(52, 8120, "Mahogany dining table", "You can now construct " + "" + "mahogany dining tables" + "" + " for your house."); + case 25: + return newstruct cs2func_script_3_struct(52, 8113, "Mahogany dining bench", "You can now construct " + "" + "mahogany dining benches" + "" + " for your house."); + case 26: + return newstruct cs2func_script_3_struct(52, 8248, "Teak kitchen table", "You can now construct " + "" + "teak kitchen tables" + "" + " for your house."); + case 27: + return newstruct cs2func_script_3_struct(53, 8036, "Mahogany four-poster bed", "You can now construct " + "" + "mahogany four-poster beds" + "" + " for your house."); + case 28: + return newstruct cs2func_script_3_struct(60, 8357, "Oak throne", "You can now construct " + "" + "oak thrones" + "" + " for your house."); + case 29: + return newstruct cs2func_script_3_struct(60, 8037, "Gilded mahogany four-poster bed", "You can now construct " + "" + "gilded mahogany four-poster beds" + "" + " for your house."); + case 30: + return newstruct cs2func_script_3_struct(61, 8114, "Gilded mahogany dining bench", "You can now construct " + "" + "gilded mahogany dining benches" + "" + " for your house."); + case 31: + return newstruct cs2func_script_3_struct(67, 8358, "Teak throne", "You can now construct " + "" + "teak thrones" + "" + " for your house."); + case 32: + return newstruct cs2func_script_3_struct(72, 8121, "Gilded mahogany and marble table", "You can now construct " + "" + "gilded mahogany and marble tables" + "" + " for your house."); + case 33: + return newstruct cs2func_script_3_struct(74, 8359, "Mahogany throne", "You can now construct " + "" + "mahogany thrones" + "" + " for your house."); + case 34: + return newstruct cs2func_script_3_struct(81, 8360, "Gilded mahogany throne", "You can now construct " + "" + "gilded mahogany thrones" + "" + " for your house."); + case 35: + return newstruct cs2func_script_3_struct(88, 8361, "Skeleton throne", "You can now construct " + "" + "skeleton thrones" + "" + " for your house."); + case 36: + return newstruct cs2func_script_3_struct(95, 8362, "Crystal throne", "You can now construct " + "" + "crystal thrones" + "" + " for your house."); + case 37: + return newstruct cs2func_script_3_struct(99, 8363, "Demonic throne", "You can now construct " + "" + "demonic thrones" + "" + " for your house."); + } + break; + case 3: + switch (arg1) { + case 0: + return newstruct cs2func_script_3_struct(4, 8319, "Wooden bookcase", "You can now construct " + "" + "wooden bookcases" + "" + " for your house."); + case 1: + return newstruct cs2func_script_3_struct(6, 8223, "Wooden shelves 1", "You can now construct " + "" + "wooden shelves 1" + "" + " for your house, which provide " + "" + "kettles" + "" + ", " + "" + "teapots" + "" + " and " + "" + "cups" + "" + "."); + case 2: + return newstruct cs2func_script_3_struct(7, 8239, "Beer barrel", "You can now construct " + "" + "beer barrels" + "" + " for your house."); + case 3: + return newstruct cs2func_script_3_struct(9, 8233, "Wooden larder", "You can now construct " + "" + "wooden larders" + "" + " for your house."); + case 4: + return newstruct cs2func_script_3_struct(12, 8240, "Cider barrel", "You can now construct " + "" + "cider barrels" + "" + " for your house."); + case 5: + return newstruct cs2func_script_3_struct(12, 8224, "Wooden shelves 2", "You can now construct " + "" + "wooden shelves 2" + "" + " for your house, which provide " + "" + "kettles" + "" + ", " + "" + "teapots" + "" + ", " + "" + "cups" + "" + " and " + "" + "beer glasses" + "" + "."); + case 6: + return newstruct cs2func_script_3_struct(15, 8384, "Tool store 1", "You can now construct " + "" + "tool store 1" + "" + " for your house, which provide " + "" + "saws" + "" + ", " + "" + "hammers" + "" + ", " + "" + "chisels" + "" + " and " + "" + "shears" + "" + "."); + case 7: + return newstruct cs2func_script_3_struct(18, 8241, "Asgarnian Ale barrel", "You can now construct " + "" + "Asgarnian Ale barrels" + "" + " for your house."); + case 8: + return newstruct cs2func_script_3_struct(20, 8038, "Shoe box", "You can now construct " + "" + "shoe boxes" + "" + " for your house."); + case 9: + return newstruct cs2func_script_3_struct(21, 8045, "Wooden shaving stand", "You can now construct " + "" + "wooden shaving stands" + "" + " for your house."); + case 10: + return newstruct cs2func_script_3_struct(23, 8225, "Wooden shelves 3", "You can now construct " + "" + "wooden shelves 3" + "" + " for your house, which provide " + "" + "kettles" + "" + ", " + "" + "teapots" + "" + ", " + "" + "cups" + "" + ", " + "" + "beer glasses" + "" + " and " + "" + "cake tins" + "" + "."); + case 11: + return newstruct cs2func_script_3_struct(25, 8385, "Tool store 2", "You can now construct " + "" + "tool store 2" + "" + " for your house, which provide " + "" + "buckets" + "" + ", " + "" + "spades" + "" + " and " + "" + "tinderboxes" + "" + "."); + case 12: + return newstruct cs2func_script_3_struct(26, 8242, "Greenman's Ale barrel", "You can now construct " + "" + "Greenman's Ale barrels" + "" + " for your house."); + case 13: + return newstruct cs2func_script_3_struct(27, 8039, "Oak chest of drawers", "You can now construct " + "" + "oak chests of drawers" + "" + " for your house."); + case 14: + return newstruct cs2func_script_3_struct(29, 8046, "Oak shaving stand", "You can now construct " + "" + "oak shaving stands" + "" + " for your house."); + case 15: + return newstruct cs2func_script_3_struct(29, 8320, "Oak bookcase", "You can now construct " + "" + "oak bookcases" + "" + " for your house."); + case 16: + return newstruct cs2func_script_3_struct(33, 8234, "Oak larder", "You can now construct " + "" + "oak larders" + "" + " for your house."); + case 17: + return newstruct cs2func_script_3_struct(34, 8226, "Oak shelves 1", "You can now construct " + "" + "oak shelves 1" + "" + " for your house, which provide " + "" + "kettles" + "" + ", " + "" + "teapots" + "" + ", " + "" + "cups" + "" + ", " + "" + "beer glasses" + "" + ", " + "" + "cake tins" + "" + " and " + "" + "bowls" + "" + "."); + case 18: + return newstruct cs2func_script_3_struct(35, 8386, "Tool store 3", "You can now construct " + "" + "tool store 3" + "" + " for your house, which provide " + "" + "brown aprons" + "" + ", " + "" + "glassblowing pipes" + "" + " and " + "" + "needles" + "" + "."); + case 19: + return newstruct cs2func_script_3_struct(36, 8243, "Dragon Bitter barrel", "You can now construct " + "" + "Dragon Bitter barrels" + "" + " for your house."); + case 20: + return newstruct cs2func_script_3_struct(37, 8047, "Oak dresser", "You can now construct " + "" + "oak dressers" + "" + " for your house."); + case 21: + return newstruct cs2func_script_3_struct(39, 8040, "Oak wardrobe (bedroom)", "You can now construct " + "" + "oak wardrobes (bedroom)" + "" + " for your house."); + case 22: + return newstruct cs2func_script_3_struct(40, 8321, "Mahogany bookcase", "You can now construct " + "" + "mahogany bookcases" + "" + " for your house."); + case 23: + return newstruct cs2func_script_3_struct(42, 9829, "Oak wardrobe", "You can now construct " + "" + "oak wardrobes" + "" + " for your " + "" + "costume room" + "" + "."); + case 24: + return newstruct cs2func_script_3_struct(43, 8235, "Teak larder", "You can now construct " + "" + "teak larders" + "" + " for your house."); + case 25: + return newstruct cs2func_script_3_struct(44, 8387, "Tool store 4", "You can now construct " + "" + "tool store 4" + "" + " for your house, which provide " + "" + "amulets" + "" + ", " + "" + "necklaces" + "" + ", " + "" + "rings" + "" + ", " + "" + "holy symbols" + "" + " and " + "" + "tiara moulds" + "" + "."); + case 26: + return newstruct cs2func_script_3_struct(44, 9823, "Oak fancy dress box", "You can now construct " + "" + "oak fancy dress boxes" + "" + " for your " + "" + "costume room" + "" + "."); + case 27: + return newstruct cs2func_script_3_struct(45, 8227, "Oak shelves 2", "You can now construct " + "" + "oak shelves 2" + "" + " for your house, which provide " + "" + "kettles" + "" + ", " + "" + "teapots" + "" + ", " + "" + "cups" + "" + ", " + "" + "beer glasses" + "" + ", " + "" + "cake tins" + "" + ", " + "" + "bowls" + "" + " and " + "" + "pie dishes" + "" + "."); + case 28: + return newstruct cs2func_script_3_struct(46, 8048, "Teak dresser", "You can now construct " + "" + "teak dressers" + "" + " for your house."); + case 29: + return newstruct cs2func_script_3_struct(46, 9826, "Oak armour case", "You can now construct " + "" + "oak armour cases" + "" + " for your " + "" + "costume room" + "" + "."); + case 30: + return newstruct cs2func_script_3_struct(48, 8244, "Chef's Delight barrel", "You can now construct " + "" + "Chef's Delight barrels" + "" + " for your house."); + case 31: + return newstruct cs2func_script_3_struct(48, 9839, "Oak treasure chest", "You can now construct " + "" + "oak treasure chests" + "" + " for your " + "" + "costume room" + "" + "."); + case 32: + return newstruct cs2func_script_3_struct(50, 9836, "Oak toy box", "You can now construct " + "" + "oak toy boxes" + "" + " for your " + "" + "costume room" + "" + "."); + case 33: + return newstruct cs2func_script_3_struct(51, 8041, "Teak chest of drawers", "You can now construct " + "" + "teak chests of drawers" + "" + " for your house."); + case 34: + return newstruct cs2func_script_3_struct(51, 9830, "Carved oak wardrobe", "You can now construct " + "" + "carved oak wardrobes" + "" + " for your " + "" + "costume room" + "" + "."); + case 35: + return newstruct cs2func_script_3_struct(54, 9817, "Oak cape rack", "You can now construct " + "" + "oak cape racks" + "" + " for your " + "" + "costume room" + "" + "."); + case 36: + return newstruct cs2func_script_3_struct(55, 8388, "Tool store 5", "You can now construct " + "" + "tool store 5" + "" + " for your house, which provide " + "" + "rakes" + "" + ", " + "" + "spades" + "" + ", " + "" + "trowels" + "" + ", " + "" + "seed dibbers" + "" + " and " + "" + "watering cans" + "" + "."); + case 37: + return newstruct cs2func_script_3_struct(56, 8049, "Fancy teak dresser", "You can now construct " + "" + "fancy teak dressers" + "" + " for your house."); + case 38: + return newstruct cs2func_script_3_struct(56, 8228, "Teak shelves 1", "You can now construct " + "" + "teak shelves 1" + "" + " for your house, which provide " + "" + "kettles" + "" + ", " + "" + "teapots" + "" + ", " + "" + "cups" + "" + ", " + "" + "beer glasses" + "" + ", " + "" + "cake tins" + "" + ", " + "" + "bowls" + "" + ", " + "" + "pie dishes" + "" + " and " + "" + "pots" + "" + "."); + case 39: + return newstruct cs2func_script_3_struct(60, 9831, "Teak wardrobe", "You can now construct " + "" + "teak wardrobes" + "" + " for your " + "" + "costume room" + "" + "."); + case 40: + return newstruct cs2func_script_3_struct(62, 9824, "Teak fancy dress box", "You can now construct " + "" + "teak fancy dress boxes" + "" + " for your " + "" + "costume room" + "" + "."); + case 41: + return newstruct cs2func_script_3_struct(63, 9818, "Teak cape rack", "You can now construct " + "" + "teak cape racks" + "" + " for your " + "" + "costume room" + "" + "."); + case 42: + return newstruct cs2func_script_3_struct(63, 8042, "Teak wardrobe (bedroom)", "You can now construct " + "" + "teak wardrobes (bedroom)" + "" + " for your house."); + case 43: + return newstruct cs2func_script_3_struct(64, 8050, "Mahogany dresser", "You can now construct " + "" + "mahogany dressers" + "" + " for your house."); + case 44: + return newstruct cs2func_script_3_struct(64, 9827, "Teak armour case", "You can now construct " + "" + "teak armour cases" + "" + " for your " + "" + "costume room" + "" + "."); + case 45: + return newstruct cs2func_script_3_struct(66, 9840, "Teak treasure chest", "You can now construct " + "" + "teak treasure chests" + "" + " for your " + "" + "costume room" + "" + "."); + case 46: + return newstruct cs2func_script_3_struct(67, 8229, "Teak shelves 2", "You can now construct " + "" + "teak shelves 2" + "" + " for your house, which provide " + "" + "kettles" + "" + ", " + "" + "teapots" + "" + ", " + "" + "cups" + "" + ", " + "" + "beer glasses" + "" + ", " + "" + "cake tins" + "" + ", " + "" + "bowls" + "" + ", " + "" + "pie dishes" + "" + ", " + "" + "pots" + "" + " and " + "" + "chef's hats" + "" + "."); + case 47: + return newstruct cs2func_script_3_struct(68, 9837, "Teak toy box", "You can now construct " + "" + "teak toy boxes" + "" + " for your " + "" + "costume room" + "" + "."); + case 48: + return newstruct cs2func_script_3_struct(69, 9832, "Carved teak wardrobe", "You can now construct " + "" + "carved teak wardrobes" + "" + " for your " + "" + "costume room" + "" + "."); + case 49: + return newstruct cs2func_script_3_struct(72, 9819, "Mahogany cape rack", "You can now construct " + "" + "mahogany cape racks" + "" + " for your " + "" + "costume room" + "" + "."); + case 50: + return newstruct cs2func_script_3_struct(74, 8051, "Gilded mahogany dresser", "You can now construct " + "" + "gilded mahogany dressers" + "" + " for your house."); + case 51: + return newstruct cs2func_script_3_struct(75, 8043, "Mahogany wardrobe (bedroom)", "You can now construct " + "" + "mahogany wardrobes (bedroom)" + "" + " for your house."); + case 52: + return newstruct cs2func_script_3_struct(78, 9833, "Mahogany wardrobe", "You can now construct " + "" + "mahogany wardrobes" + "" + " for your " + "" + "costume room" + "" + "."); + case 53: + return newstruct cs2func_script_3_struct(80, 9825, "Mahogany fancy dress box", "You can now construct " + "" + "mahogany fancy dress boxes" + "" + " for your " + "" + "costume room" + "" + "."); + case 54: + return newstruct cs2func_script_3_struct(81, 9820, "Gilded mahogany cape rack", "You can now construct " + "" + "gilded mahogany cape racks" + "" + " for your " + "" + "costume room" + "" + "."); + case 55: + return newstruct cs2func_script_3_struct(82, 9828, "Mahogany armour case", "You can now construct " + "" + "mahogany armour cases" + "" + " for your " + "" + "costume room" + "" + "."); + case 56: + return newstruct cs2func_script_3_struct(84, 9841, "Mahogany treasure chest", "You can now construct " + "" + "mahogany treasure chests" + "" + " for your " + "" + "costume room" + "" + "."); + case 57: + return newstruct cs2func_script_3_struct(86, 9838, "Mahogany toy box", "You can now construct " + "" + "mahogany toy boxes" + "" + " for your " + "" + "costume room" + "" + "."); + case 58: + return newstruct cs2func_script_3_struct(87, 8044, "Gilded mahogany wardrobe (bedroom)", "You can now construct " + "" + "gilded mahogany wardrobes (bedroom)" + "" + " for your house."); + case 59: + return newstruct cs2func_script_3_struct(87, 9834, "Gilded mahogany wardrobe", "You can now construct " + "" + "gilded mahogany wardrobes" + "" + " for your " + "" + "costume room" + "" + "."); + case 60: + return newstruct cs2func_script_3_struct(90, 9821, "Marble cape rack", "You can now construct " + "" + "marble cape racks" + "" + " for your " + "" + "costume room" + "" + "."); + case 61: + return newstruct cs2func_script_3_struct(96, 9835, "Marble wardrobe", "You can now construct " + "" + "marble wardrobes" + "" + " for your " + "" + "costume room" + "" + "."); + case 62: + return newstruct cs2func_script_3_struct(99, 9822, "Magic stone cape rack", "You can now construct " + "" + "magic stone cape racks" + "" + " for your " + "" + "costume room" + "" + "."); + } + break; + case 4: + switch (arg1) { + case 0: + return newstruct cs2func_script_3_struct(2, 8316, "Brown rug", "You can now make " + "" + "brown rugs" + "" + " for your house."); + case 1: + return newstruct cs2func_script_3_struct(2, 8322, "Torn curtains", "You can now make " + "" + "torn curtains" + "" + " for your house."); + case 2: + return newstruct cs2func_script_3_struct(13, 8317, "Rug", "You can now make " + "" + "rugs" + "" + " for your house."); + case 3: + return newstruct cs2func_script_3_struct(18, 8323, "Curtains", "You can now make " + "" + "curtains" + "" + " for your house."); + case 4: + return newstruct cs2func_script_3_struct(25, 8052, "Oak clock", "You can now construct " + "" + "oak clocks" + "" + " for your house."); + case 5: + return newstruct cs2func_script_3_struct(40, 8334, "Oak lectern", "You can now construct " + "" + "oak lecterns" + "" + " for your house."); + case 6: + return newstruct cs2func_script_3_struct(40, 8324, "Opulent curtains", "You can now make " + "" + "opulent curtains" + "" + " for your house."); + case 7: + return newstruct cs2func_script_3_struct(41, 8341, "Globe", "You can now construct " + "" + "globes" + "" + " for your house."); + case 8: + return newstruct cs2func_script_3_struct(43, 8354, "Alchemical chart", "You can now make " + "" + "alchemical charts" + "" + " for your house."); + case 9: + return newstruct cs2func_script_3_struct(44, 8348, "Wooden telescope", "You can now construct " + "" + "wooden telescopes" + "" + " for your house."); + case 10: + return newstruct cs2func_script_3_struct(47, 8335, "Oak eagle lectern", "You can now construct " + "" + "oak eagle lecterns" + "" + " for your house."); + case 11: + return newstruct cs2func_script_3_struct(47, 8336, "Oak demon lectern", "You can now construct " + "" + "oak demon lecterns" + "" + " for your house."); + case 12: + return newstruct cs2func_script_3_struct(50, 8342, "Ornamental globe", "You can now construct " + "" + "ornamental globes" + "" + " for your house."); + case 13: + return newstruct cs2func_script_3_struct(55, 8053, "Teak clock", "You can now construct " + "" + "teak clocks" + "" + " for your house."); + case 14: + return newstruct cs2func_script_3_struct(57, 8337, "Teak eagle lectern", "You can now construct " + "" + "teak eagle lecterns" + "" + " for your house."); + case 15: + return newstruct cs2func_script_3_struct(57, 8338, "Teak demon lectern", "You can now construct " + "" + "teak demon lecterns" + "" + " for your house."); + case 16: + return newstruct cs2func_script_3_struct(59, 8343, "Lunar globe", "You can now construct " + "" + "lunar globes" + "" + " for your house."); + case 17: + return newstruct cs2func_script_3_struct(63, 8355, "Astronomical chart", "You can now make " + "" + "astronomical charts" + "" + " for your house."); + case 18: + return newstruct cs2func_script_3_struct(64, 8349, "Teak telescope", "You can now construct " + "" + "teak telescopes" + "" + " for your house."); + case 19: + return newstruct cs2func_script_3_struct(65, 8318, "Opulent rug", "You can now make " + "" + "opulent rugs" + "" + " for your house."); + case 20: + return newstruct cs2func_script_3_struct(67, 8339, "Mahogany eagle lectern", "You can now construct " + "" + "mahogany eagle lecterns" + "" + " for your house."); + case 21: + return newstruct cs2func_script_3_struct(67, 8340, "Mahogany demon lectern", "You can now construct " + "" + "mahogany demon lecterns" + "" + " for your house."); + case 22: + return newstruct cs2func_script_3_struct(68, 8344, "Celestial globe", "You can now construct " + "" + "celestial globes" + "" + " for your house."); + case 23: + return newstruct cs2func_script_3_struct(72, 8128, "Dungeon candles", "You can now make " + "" + "dungeon candles" + "" + " for your house."); + case 24: + return newstruct cs2func_script_3_struct(72, 8125, "Decorative dungeon bloodstain", "You can now put " + "" + "decorative dungeon bloodstains" + "" + " in your house."); + case 25: + return newstruct cs2func_script_3_struct(77, 8345, "Armillary sphere", "You can now construct " + "" + "armillary spheres" + "" + " for your house."); + case 26: + return newstruct cs2func_script_3_struct(83, 8356, "Infernal chart", "You can now make " + "" + "infernal charts" + "" + " for your house."); + case 27: + return newstruct cs2func_script_3_struct(83, 8126, "Decorative dungeon pipe", "You can now construct " + "" + "decorative dungeon pipes" + "" + " for your house."); + case 28: + return newstruct cs2func_script_3_struct(84, 8129, "Dungeon torches", "You can now make " + "" + "dungeon torches" + "" + " for your house."); + case 29: + return newstruct cs2func_script_3_struct(84, 8350, "Mahogany 'scope", "You can now construct " + "" + "mahogany 'scopes" + "" + " for your house."); + case 30: + return newstruct cs2func_script_3_struct(85, 8054, "Gilded mahogany clock", "You can now construct " + "" + "gilded mahogany clocks" + "" + " for your house."); + case 31: + return newstruct cs2func_script_3_struct(86, 8346, "Small orrery", "You can now construct " + "" + "small orreries" + "" + " for your house."); + case 32: + return newstruct cs2func_script_3_struct(94, 8127, "Hanging dungeon skeleton", "You can now put " + "" + "hanging dungeon skeletons" + "" + " in your house."); + case 33: + return newstruct cs2func_script_3_struct(94, 8130, "Dungeon skull torches", "You can now make " + "" + "dungeon skull torches" + "" + " for your house."); + case 34: + return newstruct cs2func_script_3_struct(95, 8347, "Large orrery", "You can now construct " + "" + "large orreries" + "" + " for your house."); + } + break; + case 5: + switch (arg1) { + case 0: + return newstruct cs2func_script_3_struct(16, 8102, "Oak wall decoration", "You can now display " + "" + "oak wall decorations" + "" + " in your house."); + case 1: + return newstruct cs2func_script_3_struct(28, 8085, "Suit of armour", "You can now display a " + "" + "suit of armour" + "" + " in your house."); + case 2: + return newstruct cs2func_script_3_struct(35, 8086, "Small portrait", "You can now display " + "" + "small portraits" + "" + " in your house."); + case 3: + return newstruct cs2func_script_3_struct(36, 8267, "Mounted bass", "You can now display " + "" + "mounted bass" + "" + " in your house."); + case 4: + return newstruct cs2func_script_3_struct(36, 8103, "Teak wall decoration", "You can now display " + "" + "teak wall decorations" + "" + " in your house."); + case 5: + return newstruct cs2func_script_3_struct(38, 8087, "Minor Slayer monster head", "You can now display " + "" + "minor Slayer monster heads" + "" + " in your house."); + case 6: + return newstruct cs2func_script_3_struct(38, 8294, "Small map", "You can now display " + "" + "small maps" + "" + " in your house."); + case 7: + return newstruct cs2func_script_3_struct(41, 8095, "Rune display case", "You can now put " + "" + "rune display cases" + "" + " in your house."); + case 8: + return newstruct cs2func_script_3_struct(42, 8090, "Mounted sword", "You can now display " + "" + "mounted swords" + "" + " in your house."); + case 9: + return newstruct cs2func_script_3_struct(44, 8091, "Small landscape", "You can now display " + "" + "small landscapes" + "" + " in your house."); + case 10: + return newstruct cs2func_script_3_struct(47, 8092, "Guild trophy", "You can now display " + "" + "guild trophies" + "" + " in your house."); + case 11: + return newstruct cs2func_script_3_struct(55, 8093, "Large portrait", "You can now display " + "" + "large portraits" + "" + " in your house."); + case 12: + return newstruct cs2func_script_3_struct(56, 8104, "Gilded mahogany wall decoration", "You can now display " + "" + "gilded mahogany wall decorations" + "" + " in your house."); + case 13: + return newstruct cs2func_script_3_struct(56, 8268, "Mounted swordfish", "You can now display " + "" + "mounted swordfish" + "" + " in your house."); + case 14: + return newstruct cs2func_script_3_struct(58, 8295, "Medium map", "You can now display " + "" + "medium maps" + "" + " in your house."); + case 15: + return newstruct cs2func_script_3_struct(58, 8088, "Medium Slayer monster head", "You can now display " + "" + "medium Slayer monster heads" + "" + " in your house."); + case 16: + return newstruct cs2func_script_3_struct(65, 8094, "Large landscape", "You can now display " + "" + "large landscapes" + "" + " in your house."); + case 17: + return newstruct cs2func_script_3_struct(66, 8105, "Round wall-mounted shield", "You can now display " + "" + "round wall-mounted shields" + "" + " in your house."); + case 18: + return newstruct cs2func_script_3_struct(76, 8269, "Mounted shark", "You can now display " + "" + "mounted shark" + "" + " in your house."); + case 19: + return newstruct cs2func_script_3_struct(76, 8106, "Square wall-mounted shield", "You can now display " + "" + "square wall-mounted shields" + "" + " in your house."); + case 20: + return newstruct cs2func_script_3_struct(78, 8089, "Major Slayer monster head", "You can now display " + "" + "major Slayer monster heads" + "" + " in your house."); + case 21: + return newstruct cs2func_script_3_struct(78, 8296, "Large map", "You can now display " + "" + "large maps" + "" + " in your house."); + case 22: + return newstruct cs2func_script_3_struct(86, 8107, "Wall-mounted kiteshield", "You can now display " + "" + "wall-mounted kiteshields" + "" + " in your house."); + } + break; + case 6: + switch (arg1) { + case 0: + return newstruct cs2func_script_3_struct(30, 8162, "Hoop-and-stick game", "You can now construct " + "" + "hoop-and-stick games" + "" + " for your " + "" + "games room" + "" + "."); + case 1: + return newstruct cs2func_script_3_struct(32, 8023, "Boxing ring", "You can now construct " + "" + "boxing rings" + "" + " for your " + "" + "combat room" + "" + "."); + case 2: + return newstruct cs2func_script_3_struct(34, 8028, "Boxing glove rack", "You can now construct " + "" + "boxing glove racks" + "" + " for your " + "" + "combat room" + "" + "."); + case 3: + return newstruct cs2func_script_3_struct(34, 8165, "Oak prize chest", "You can now construct " + "" + "oak prize chests" + "" + " for your " + "" + "games room" + "" + "."); + case 4: + return newstruct cs2func_script_3_struct(37, 8156, "Lesser magical balance", "You can now construct " + "" + "lesser magical balances" + "" + " for your " + "" + "games room" + "" + "."); + case 5: + return newstruct cs2func_script_3_struct(39, 8159, "Jester game", "You can now construct " + "" + "jester games" + "" + " for your " + "" + "games room" + ""); + case 6: + return newstruct cs2func_script_3_struct(39, 8153, "Clay attack stone", "You can now construct " + "" + "clay attack stones" + "" + " for your " + "" + "games room" + "" + "."); + case 7: + return newstruct cs2func_script_3_struct(41, 8024, "Fencing ring", "You can now construct " + "" + "fencing rings" + "" + " for your " + "" + "combat room" + "" + "."); + case 8: + return newstruct cs2func_script_3_struct(44, 8029, "Weapons rack", "You can now construct " + "" + "weapons racks" + "" + " for your " + "" + "combat room" + "" + "."); + case 9: + return newstruct cs2func_script_3_struct(44, 8166, "Teak prize chest", "You can now construct " + "" + "teak prize chests" + "" + " for your " + "" + "games room" + "" + "."); + case 10: + return newstruct cs2func_script_3_struct(49, 8160, "Treasure hunt fairy house", "You can now construct " + "" + "treasure hunt fairy houses" + "" + " for your " + "" + "games room" + "" + "."); + case 11: + return newstruct cs2func_script_3_struct(51, 8025, "Combat ring", "You can now construct " + "" + "combat rings" + "" + " for your " + "" + "combat room" + "" + "."); + case 12: + return newstruct cs2func_script_3_struct(54, 8163, "Dartboard", "You can now construct " + "" + "dartboards" + "" + " for your " + "" + "games room" + "" + "."); + case 13: + return newstruct cs2func_script_3_struct(54, 8030, "Upgraded weapons rack", "You can now construct " + "" + "upgraded weapons racks" + "" + " for your " + "" + "combat room" + "" + "."); + case 14: + return newstruct cs2func_script_3_struct(54, 8167, "Mahogany prize chest", "You can now construct " + "" + "mahogany prize chests" + "" + " for your " + "" + "games room" + "" + "."); + case 15: + return newstruct cs2func_script_3_struct(57, 8157, "Medium balance", "You can now construct " + "" + "medium balances" + "" + " for your " + "" + "games room" + "" + "."); + case 16: + return newstruct cs2func_script_3_struct(59, 8154, "Limestone attack stone", "You can now construct " + "" + "limestone attack stones" + "" + " for your " + "" + "games room" + "" + "."); + case 17: + return newstruct cs2func_script_3_struct(59, 8161, "Hangman game", "You can now construct " + "" + "hangman games" + "" + " for your " + "" + "games room" + "" + "."); + case 18: + return newstruct cs2func_script_3_struct(71, 8026, "Ranging pedestals", "You can now construct " + "" + "ranging pedestals" + "" + " for your " + "" + "combat room" + "" + "."); + case 19: + return newstruct cs2func_script_3_struct(77, 8158, "Greater magical balance", "You can now add " + "" + "greater magic balances" + "" + " for your " + "" + "games room" + "" + "."); + case 20: + return newstruct cs2func_script_3_struct(79, 8155, "Marble attack stone", "You can now construct " + "" + "marble attack stones" + "" + " for your " + "" + "games room" + "" + "."); + case 21: + return newstruct cs2func_script_3_struct(81, 8164, "Archery target", "You can now construct " + "" + "archery targets" + "" + " for your " + "" + "games room" + "" + "."); + case 22: + return newstruct cs2func_script_3_struct(81, 8027, "Balance beam", "You can now construct " + "" + "balance beams" + "" + " for your " + "" + "games room" + "" + "."); + } + break; + case 7: + switch (arg1) { + case 0: + return newstruct cs2func_script_3_struct(1, 8168, "Exit portal", "You can now build an " + "" + "exit portal" + "" + " for your " + "" + "garden" + "" + "."); + case 1: + return newstruct cs2func_script_3_struct(1, 8096, "Low-level plants", "You can now put " + "" + "low-level plants" + "" + " in your " + "" + "garden" + "" + "."); + case 2: + return newstruct cs2func_script_3_struct(5, 8169, "Decorative rock", "You can now put " + "" + "decorative rocks" + "" + " in your " + "" + "garden" + "" + "."); + case 3: + return newstruct cs2func_script_3_struct(5, 8173, "Tree", "You can now plant " + "" + "trees" + "" + " in your " + "" + "garden" + "" + "."); + case 4: + return newstruct cs2func_script_3_struct(6, 8097, "Mid-level plants", "You can now put " + "" + "mid-level plants" + "" + " in your " + "" + "garden" + "" + "."); + case 5: + return newstruct cs2func_script_3_struct(10, 8170, "Pond", "You can now put a " + "" + "pond" + "" + " in your " + "" + "garden" + "" + "."); + case 6: + return newstruct cs2func_script_3_struct(10, 8174, "Nice tree", "You can now plant " + "" + "nice trees" + "" + " in your " + "" + "garden" + "" + "."); + case 7: + return newstruct cs2func_script_3_struct(12, 8098, "High-level plants", "You can now put " + "" + "high-level plants" + "" + " in your " + "" + "garden" + "" + "."); + case 8: + return newstruct cs2func_script_3_struct(15, 8171, "Imp statue", "You can now put " + "" + "imp statues" + "" + " in your " + "" + "garden" + "" + "."); + case 9: + return newstruct cs2func_script_3_struct(15, 8175, "Oak tree", "You can now plant " + "" + "oak trees" + "" + " in your " + "" + "garden" + "" + "."); + case 10: + return newstruct cs2func_script_3_struct(30, 8176, "Willow tree", "You can now plant " + "" + "willow trees" + "" + " in your " + "" + "garden" + "" + "."); + case 11: + return newstruct cs2func_script_3_struct(45, 8177, "Maple tree", "You can now plant " + "" + "maple trees" + "" + " in your " + "" + "garden" + "" + "."); + case 12: + return newstruct cs2func_script_3_struct(55, 8196, "Boundary stones", "You can now put " + "" + "boundary stones" + "" + " in your " + "" + "garden" + "" + "."); + case 13: + return newstruct cs2func_script_3_struct(56, 8203, "Thorny hedge", "You can now plant " + "" + "thorny hedges" + "" + " in your " + "" + "garden" + "" + "."); + case 14: + return newstruct cs2func_script_3_struct(59, 8197, "Wooden fence", "You can now put " + "" + "wooden fences" + "" + " around your " + "" + "garden" + "" + "."); + case 15: + return newstruct cs2func_script_3_struct(60, 8204, "Nice hedge", "You can now plant " + "" + "nice hedges" + "" + " in your " + "" + "garden" + "" + "."); + case 16: + return newstruct cs2func_script_3_struct(60, 8178, "Yew tree", "You can now plant " + "" + "yew trees" + "" + " in your " + "" + "garden" + "" + "."); + case 17: + return newstruct cs2func_script_3_struct(63, 8198, "Stone wall", "You can now put " + "" + "stone walls" + "" + " around your " + "" + "garden" + "" + "."); + case 18: + return newstruct cs2func_script_3_struct(64, 8205, "Small box hedge", "You can now plant " + "" + "small box hedges" + "" + " in your " + "" + "garden" + "" + "."); + case 19: + return newstruct cs2func_script_3_struct(65, 8192, "Gazebo", "You can now put " + "" + "gazebos" + "" + " in your " + "" + "garden" + "" + "."); + case 20: + return newstruct cs2func_script_3_struct(66, 8213, "Sunflower", "You can now plant " + "" + "sunflowers" + "" + " in your " + "" + "garden" + "" + "."); + case 21: + return newstruct cs2func_script_3_struct(66, 8210, "Rosemary", "You can now plant " + "" + "rosemary" + "" + " in your " + "" + "garden" + "" + "."); + case 22: + return newstruct cs2func_script_3_struct(67, 8199, "Iron railings", "You can now put " + "" + "iron railings" + "" + " around your " + "" + "garden" + "" + "."); + case 23: + return newstruct cs2func_script_3_struct(68, 8206, "Topiary hedge", "You can now plant " + "" + "topiary hedges" + "" + " in your " + "" + "garden" + "" + "."); + case 24: + return newstruct cs2func_script_3_struct(70, 8172, "Dungeon entrance", "You can now put " + "" + "dungeon entrances" + "" + " in your " + "" + "garden" + "" + "."); + case 25: + return newstruct cs2func_script_3_struct(71, 8214, "Marigolds", "You can now plant " + "" + "marigolds" + "" + " in your " + "" + "garden" + "" + "."); + case 26: + return newstruct cs2func_script_3_struct(71, 8211, "Daffodils", "You can now plant " + "" + "daffodils" + "" + " in your " + "" + "garden" + "" + "."); + case 27: + return newstruct cs2func_script_3_struct(71, 8200, "Picket fence", "You can now put " + "" + "picket fences" + "" + " around your " + "" + "garden" + "" + "."); + case 28: + return newstruct cs2func_script_3_struct(71, 8193, "Small fountain", "You can now put " + "" + "small fountains" + "" + " in your " + "" + "garden" + "" + "."); + case 29: + return newstruct cs2func_script_3_struct(72, 8207, "Fancy hedge", "You can now put " + "" + "fancy hedges" + "" + " around your " + "" + "garden" + "" + "."); + case 30: + return newstruct cs2func_script_3_struct(75, 8179, "Magic tree", "You can now plant " + "" + "magic trees" + "" + " in your " + "" + "garden" + "" + "."); + case 31: + return newstruct cs2func_script_3_struct(75, 8194, "Large fountain", "You can now put " + "" + "large fountains" + "" + " in your " + "" + "garden" + "" + "."); + case 32: + return newstruct cs2func_script_3_struct(75, 8201, "Garden fence", "You can now put " + "" + "garden fences" + "" + " around your " + "" + "garden" + "" + "."); + case 33: + return newstruct cs2func_script_3_struct(76, 8208, "Tall fancy hedge", "You can now plant " + "" + "tall fancy hedges" + "" + " in your " + "" + "garden" + "" + "."); + case 34: + return newstruct cs2func_script_3_struct(76, 8215, "Roses", "You can now plant " + "" + "roses" + "" + " in your " + "" + "garden" + "" + "."); + case 35: + return newstruct cs2func_script_3_struct(76, 8212, "Bluebells", "You can now plant " + "" + "bluebells" + "" + " in your " + "" + "garden" + "" + "."); + case 36: + return newstruct cs2func_script_3_struct(79, 8202, "Marble wall", "You can now put " + "" + "marble walls" + "" + " around your " + "" + "garden" + "" + "."); + case 37: + return newstruct cs2func_script_3_struct(80, 8209, "Tall box hedge", "You can now plant " + "" + "tall box hedges" + "" + " in your " + "" + "garden" + "" + "."); + case 38: + return newstruct cs2func_script_3_struct(81, 8195, "Posh fountain", "You can now put " + "" + "posh fountains" + "" + " in your " + "" + "garden" + "" + "."); + } + break; + case 8: + switch (arg1) { + case 0: + return newstruct cs2func_script_3_struct(61, 8370, "Throne room floor decoration", "You can now add " + "" + "floor decorations" + "" + " to your " + "" + "throne room" + "" + " floor."); + case 1: + return newstruct cs2func_script_3_struct(65, 8297, "Oak cage", "You can add " + "" + "oak cages" + "" + " to your " + "" + "dungeon" + "" + "."); + case 2: + return newstruct cs2func_script_3_struct(65, 8302, "Oubliette spikes", "You can now add " + "" + "oubliette spikes" + "" + " to your " + "" + "dungeon" + "" + "."); + case 3: + return newstruct cs2func_script_3_struct(68, 8371, "Steel cage", "You can now add " + "" + "steel cages" + "" + " to your " + "" + "throne room" + "" + " floor."); + case 4: + return newstruct cs2func_script_3_struct(70, 8298, "Oak and steel cage", "You can now add " + "" + "oak and steel cages" + "" + " to your " + "" + "dungeon" + "" + "."); + case 5: + return newstruct cs2func_script_3_struct(70, 8131, "Skeleton guard", "You can now add " + "" + "skeleton guards" + "" + " to your " + "" + "dungeon" + "" + "."); + case 6: + return newstruct cs2func_script_3_struct(70, 18791, "Pit dog", "You can now add " + "" + "pit dogs" + "" + " to your dungeon pits (after Love Story)."); + case 7: + return newstruct cs2func_script_3_struct(71, 8303, "Tentacle pool", "You can now add " + "" + "tentacle pools" + "" + " to your " + "" + "dungeon" + "" + "."); + case 8: + return newstruct cs2func_script_3_struct(71, 18797, "Minor pit trap", "You can now add " + "" + "minor traps" + "" + " to your dungeon pits (after Love Story)."); + case 9: + return newstruct cs2func_script_3_struct(72, 8143, "Spike trap", "You can now add " + "" + "spike traps" + "" + " to your " + "" + "dungeon" + "" + "."); + case 10: + return newstruct cs2func_script_3_struct(73, 18792, "Pit ogre", "You can now add " + "" + "pit ogres" + "" + " to your dungeon pits (after Love Story)."); + case 11: + return newstruct cs2func_script_3_struct(74, 8372, "Large trapdoor", "You can now add " + "" + "large trapdoors" + "" + " to your " + "" + "throne room" + "" + " floor."); + case 12: + return newstruct cs2func_script_3_struct(74, 8122, "Oak dungeon door", "You can now add " + "" + "oak dungeon doors" + "" + " to your " + "" + "dungeon" + "" + "."); + case 13: + return newstruct cs2func_script_3_struct(74, 8132, "Guard dog", "You can now add " + "" + "guard dogs" + "" + " to your " + "" + "dungeon" + "" + "."); + case 14: + return newstruct cs2func_script_3_struct(75, 8148, "Wooden dungeon treasure crate", "You can now add " + "" + "wooden dungeon treasure crates" + "" + " to your " + "" + "treasure room" + "" + "."); + case 15: + return newstruct cs2func_script_3_struct(75, 8138, "Demon", "You can now add " + "" + "demons" + "" + " to your " + "" + "dungeon" + "" + "."); + case 16: + return newstruct cs2func_script_3_struct(75, 8299, "Steel cage", "You can now add " + "" + "steel cages" + "" + " to your " + "" + "dungeon" + "" + "."); + case 17: + return newstruct cs2func_script_3_struct(76, 8144, "Man trap", "You can now add " + "" + "man traps" + "" + " to your " + "" + "dungeon" + "" + "."); + case 18: + return newstruct cs2func_script_3_struct(77, 8304, "Oubliette flame pit", "You can now add " + "" + "oubliette flame pits" + "" + " to your " + "" + "dungeon" + "" + "."); + case 19: + return newstruct cs2func_script_3_struct(78, 8133, "Hobgoblin guard", "You can now add " + "" + "hobgoblin guards" + "" + " to your " + "" + "dungeon" + "" + "."); + case 20: + return newstruct cs2func_script_3_struct(79, 8149, "Oak dungeon treasure chest", "You can now add " + "" + "oak dungeon treasure chests" + "" + " to your " + "" + "treasure room" + "" + "."); + case 21: + return newstruct cs2func_script_3_struct(79, 18793, "Pit rock protector", "You can now add " + "" + "pit rock protectors" + "" + " to your dungeon pits (after Love Story)."); + case 22: + return newstruct cs2func_script_3_struct(80, 8300, "Spiked cage", "You can now add " + "" + "spiked cages" + "" + " to your " + "" + "dungeon" + "" + "."); + case 23: + return newstruct cs2func_script_3_struct(80, 8145, "Tangle vine", "You can now add " + "" + "tangle vines" + "" + " to your " + "" + "dungeon" + "" + "."); + case 24: + return newstruct cs2func_script_3_struct(80, 8139, "Kalphite soldier", "You can now add " + "" + "kalphite soldiers" + "" + " to your " + "" + "dungeon" + "" + "."); + case 25: + return newstruct cs2func_script_3_struct(82, 8373, "Lesser magic cage", "You can now add " + "" + "lesser magic cages" + "" + " to your " + "" + "throne room" + "" + " floor."); + case 26: + return newstruct cs2func_script_3_struct(82, 8134, "Baby red dragon", "You can now add " + "" + "baby red dragons" + "" + " to your " + "" + "dungeon" + "" + "."); + case 27: + return newstruct cs2func_script_3_struct(83, 8150, "Teak dungeon treasure chest", "You can now add " + "" + "teak dungeon treasure chests" + "" + " to your " + "" + "treasure room" + "" + "."); + case 28: + return newstruct cs2func_script_3_struct(83, 8305, "Rocnar", "You can now add " + "" + "rocnars" + "" + " to your " + "" + "dungeon" + "" + "."); + case 29: + return newstruct cs2func_script_3_struct(83, 18798, "Major pit trap", "You can now add " + "" + "major traps" + "" + " to your dungeon pits (after Love Story)."); + case 30: + return newstruct cs2func_script_3_struct(84, 8123, "Steel-plated oak door", "You can now add " + "" + "steel-plated oak doors" + "" + " to your " + "" + "dungeon" + "" + "."); + case 31: + return newstruct cs2func_script_3_struct(84, 8146, "Marble trap", "You can now add " + "" + "marble traps" + "" + " to your " + "" + "dungeon" + "" + "."); + case 32: + return newstruct cs2func_script_3_struct(84, 18794, "Pit scabarite", "You can now add " + "" + "pit scarabites" + "" + " to your dungeon pits (after Love Story)."); + case 33: + return newstruct cs2func_script_3_struct(85, 8140, "Tok-Xil", "You can now add " + "" + "Tok-Xil" + "" + " to your " + "" + "dungeon" + "" + "."); + case 34: + return newstruct cs2func_script_3_struct(85, 8301, "Bone cage", "You can now add " + "" + "bone cages" + "" + " to your " + "" + "dungeon" + "" + "."); + case 35: + return newstruct cs2func_script_3_struct(86, 8135, "Huge spider", "You can now add " + "" + "huge spiders" + "" + " to your " + "" + "dungeon" + "" + "."); + case 36: + return newstruct cs2func_script_3_struct(87, 8151, "Mahogany dungeon treasure chest", "You can now add " + "" + "mahogany dungeon treasure chests" + "" + " to your " + "" + "treasure room" + "" + "."); + case 37: + return newstruct cs2func_script_3_struct(88, 8147, "Teleport trap", "You can now add " + "" + "teleport traps" + "" + " to your " + "" + "dungeon" + "" + "."); + case 38: + return newstruct cs2func_script_3_struct(89, 8374, "Greater magic cage", "You can now add " + "" + "greater magic cages" + "" + " to your " + "" + "throne room" + "" + " floor."); + case 39: + return newstruct cs2func_script_3_struct(89, 18795, "Pit black demon", "You can now add " + "" + "pit black demons" + "" + " to your dungeon pits (after Love Story)."); + case 40: + return newstruct cs2func_script_3_struct(90, 8136, "Troll guard", "You can now add " + "" + "troll guards" + "" + " to your " + "" + "dungeon" + "" + "."); + case 41: + return newstruct cs2func_script_3_struct(90, 8141, "Dagannoth", "You can now add " + "" + "dagannoths" + "" + " to your " + "" + "dungeon" + "" + "."); + case 42: + return newstruct cs2func_script_3_struct(91, 8152, "Magic dungeon treasure chest", "You can now add " + "" + "magic dungeon treasure chests" + "" + " to your " + "" + "treasure room" + "" + "."); + case 43: + return newstruct cs2func_script_3_struct(94, 8124, "Marble dungeon door", "You can now add " + "" + "marble dungeon doors" + "" + " to your " + "" + "dungeon" + "" + "."); + case 44: + return newstruct cs2func_script_3_struct(94, 8137, "Hellhound", "You can now add " + "" + "hellhounds" + "" + " to your " + "" + "dungeon" + "" + "."); + case 45: + return newstruct cs2func_script_3_struct(95, 8142, "Steel dragon", "You can now add " + "" + "steel dragons" + "" + " to your " + "" + "dungeon" + "" + "."); + case 46: + return newstruct cs2func_script_3_struct(96, 18799, "Superior pit trap", "You can now add " + "" + "superior traps" + "" + " to your dungeon pits (after Love Story)."); + case 47: + return newstruct cs2func_script_3_struct(97, 18796, "Pit iron dragon", "You can now add " + "" + "pit iron dragons" + "" + " to your dungeon pits (after Love Story)."); + } + break; + case 9: + switch (arg1) { + case 0: + return newstruct cs2func_script_3_struct(45, 8062, "Oak altar", "You can now construct " + "" + "oak altars" + "" + " for your " + "" + "chapel" + "" + "."); + case 1: + return newstruct cs2func_script_3_struct(45, 8070, "Steel torches", "You can now add " + "" + "steel torches" + "" + " to your " + "" + "chapel" + "" + "."); + case 2: + return newstruct cs2func_script_3_struct(48, 8055, "Symbol of Saradomin", "You can now add " + "" + "symbols of Saradomin" + "" + " to your " + "" + "chapel" + "" + "."); + case 3: + return newstruct cs2func_script_3_struct(48, 8057, "Symbol of Guthix", "You can now add " + "" + "symbols of Guthix" + "" + " to your " + "" + "chapel" + "" + "."); + case 4: + return newstruct cs2func_script_3_struct(48, 8056, "Symbol of Zamorak", "You can now add " + "" + "symbols of Zamorak" + "" + " to your " + "" + "chapel" + "" + "."); + case 5: + return newstruct cs2func_script_3_struct(49, 8069, "Wooden torches", "You can now add " + "" + "wooden torches" + "" + " to your " + "" + "chapel" + "" + "."); + case 6: + return newstruct cs2func_script_3_struct(49, 8079, "Chapel windchimes", "You can now add " + "" + "chapel windchimes" + "" + " to your " + "" + "chapel" + "" + "."); + case 7: + return newstruct cs2func_script_3_struct(49, 8082, "Small chapel statue", "You can now construct " + "" + "small chapel statues" + "" + " for your " + "" + "chapel" + "" + "."); + case 8: + return newstruct cs2func_script_3_struct(49, 8076, "Shuttered chapel window", "You can now add " + "" + "shuttered windows" + "" + " to your " + "" + "chapel" + "" + "."); + case 9: + return newstruct cs2func_script_3_struct(50, 8063, "Teak altar", "You can now construct " + "" + "teak altars" + "" + " for your " + "" + "chapel" + "" + "."); + case 10: + return newstruct cs2func_script_3_struct(53, 8071, "Steel candlesticks", "You can now add " + "" + "steel candlesticks" + "" + " to your " + "" + "chapel" + "" + "."); + case 11: + return newstruct cs2func_script_3_struct(56, 8064, "Cloth-covered teak altar", "You can now add " + "" + "cloth-covered teak altars" + "" + " to your " + "" + "chapel" + "" + "."); + case 12: + return newstruct cs2func_script_3_struct(57, 8072, "Gold candlesticks", "You can now add " + "" + "gold candlesticks" + "" + " to your " + "" + "chapel" + "" + "."); + case 13: + return newstruct cs2func_script_3_struct(58, 8080, "Chapel bells", "You can now add " + "" + "chapel bells" + "" + " to your " + "" + "chapel" + "" + "."); + case 14: + return newstruct cs2func_script_3_struct(59, 8058, "Icon of Saradomin", "You can now add " + "" + "icons of Saradomin" + "" + " to your " + "" + "chapel" + "" + "."); + case 15: + return newstruct cs2func_script_3_struct(59, 8060, "Icon of Guthix", "You can now add " + "" + "icons of Guthix" + "" + " to your " + "" + "chapel" + "" + "."); + case 16: + return newstruct cs2func_script_3_struct(59, 8059, "Icon of Zamorak", "You can now add " + "" + "icons of Zamorak" + "" + " to your " + "" + "chapel" + "" + "."); + case 17: + return newstruct cs2func_script_3_struct(60, 8065, "Cloth-covered mahogany altar", "You can now construct " + "" + "cloth-covered mahogany altars" + "" + " for your " + "" + "chapel" + "" + "."); + case 18: + return newstruct cs2func_script_3_struct(61, 8073, "Oak incense burners", "You can now add " + "" + "oak incense burners" + "" + " to your " + "" + "chapel" + "" + "."); + case 19: + return newstruct cs2func_script_3_struct(64, 8066, "Limestone altar", "You can now construct " + "" + "limestone altars" + "" + " for your " + "" + "chapel" + "" + "."); + case 20: + return newstruct cs2func_script_3_struct(65, 8074, "Mahogany incense burners", "You can now add " + "" + "mahogany incense burners" + "" + " to your " + "" + "chapel" + "" + "."); + case 21: + return newstruct cs2func_script_3_struct(69, 8083, "Medium chapel statue", "You can now add " + "" + "medium chapel statues" + "" + " to your " + "" + "chapel" + "" + "."); + case 22: + return newstruct cs2func_script_3_struct(69, 8081, "Chapel organ", "You can now add " + "" + "organs" + "" + " to your " + "" + "chapel" + "" + "."); + case 23: + return newstruct cs2func_script_3_struct(69, 8077, "Decorative chapel window", "You can now add " + "" + "decorative windows" + "" + " to your " + "" + "chapel" + "" + "."); + case 24: + return newstruct cs2func_script_3_struct(69, 8075, "Marble incense burner", "You can now add " + "" + "marble incense burners" + "" + " to your " + "" + "chapel" + "" + "."); + case 25: + return newstruct cs2func_script_3_struct(70, 8067, "Marble altar", "You can now construct " + "" + "marble altars" + "" + " for your " + "" + "chapel" + "" + "."); + case 26: + return newstruct cs2func_script_3_struct(71, 8061, "Icon of Bob the Cat", "You can now add " + "" + "icons of Bob the Cat" + "" + " to your " + "" + "chapel" + "" + "."); + case 27: + return newstruct cs2func_script_3_struct(75, 8068, "Gilded marble altar", "You can now construct " + "" + "gilded marble altars" + "" + " for your " + "" + "chapel" + "" + "."); + case 28: + return newstruct cs2func_script_3_struct(89, 8084, "Large chapel statue", "You can now add " + "" + "large chapel statues" + "" + " to your " + "" + "chapel" + "" + "."); + case 29: + return newstruct cs2func_script_3_struct(89, 8078, "Stained-glass chapel window", "You can now add " + "" + "stained-glass windows" + "" + " to your " + "" + "chapel" + "" + "."); + } + break; + case 10: + switch (arg1) { + case 0: + return newstruct cs2func_script_3_struct(5, 8236, "Cat blanket", "You can now add " + "" + "cat blankets" + "" + " to your house."); + case 1: + return newstruct cs2func_script_3_struct(19, 8237, "Cat basket", "You can now add " + "" + "cat baskets" + "" + " to your house."); + case 2: + return newstruct cs2func_script_3_struct(26, 8099, "Rope bell pull", "You can now add " + "" + "rope bell pulls" + "" + " to your house."); + case 3: + return newstruct cs2func_script_3_struct(27, 8249, "Oak staircase", "You can now construct " + "" + "oak staircases" + "" + " for your house."); + case 4: + return newstruct cs2func_script_3_struct(33, 8238, "Cushioned cat basket", "You can now add " + "" + "cushioned cat baskets" + "" + " to your house."); + case 5: + return newstruct cs2func_script_3_struct(37, 8100, "Teak bell pull", "You can now add " + "" + "teak bell pulls" + "" + " to your house."); + case 6: + return newstruct cs2func_script_3_struct(42, 8351, "Crystal ball", "You can now add " + "" + "crystal balls" + "" + " to your house."); + case 7: + return newstruct cs2func_script_3_struct(48, 8252, "Teak staircase", "You can now construct " + "" + "teak staircases" + "" + " for your house."); + case 8: + return newstruct cs2func_script_3_struct(50, 8328, "Teak portal frame", "You can now construct " + "" + "teak portal frames" + "" + " for your house."); + case 9: + return newstruct cs2func_script_3_struct(50, 8331, "Teleport focus", "You can now construct " + "" + "teleport focuses" + "" + " for your house."); + case 10: + return newstruct cs2func_script_3_struct(54, 8352, "Elemental sphere", "You can now add " + "" + "elemental spheres" + "" + " to your house."); + case 11: + return newstruct cs2func_script_3_struct(60, 8101, "Gilded teak bell pull", "You can now add " + "" + "gilded teak bell pulls" + "" + " to your house."); + case 12: + return newstruct cs2func_script_3_struct(65, 8332, "Greater teleport focus", "You can now construct " + "" + "greater teleport focuses" + "" + " for your house."); + case 13: + return newstruct cs2func_script_3_struct(65, 8329, "Mahogany portal frame", "You can now construct " + "" + "mahogany portal frames" + "" + " for your house."); + case 14: + return newstruct cs2func_script_3_struct(66, 8353, "Crystal of power", "You can now make " + "" + "crystals of power" + "" + " for your house."); + case 15: + return newstruct cs2func_script_3_struct(67, 8258, "Limestone spiral staircase", "You can now construct " + "" + "limestone spiral staircases" + "" + " for your house."); + case 16: + return newstruct cs2func_script_3_struct(68, 8306, "Oak oubliette ladder", "You can now construct " + "" + "oak oubliette ladders" + "" + " for your house."); + case 17: + return newstruct cs2func_script_3_struct(68, 8364, "Oak lever", "You can now construct " + "" + "oak levers" + "" + " for your house."); + case 18: + return newstruct cs2func_script_3_struct(68, 8367, "Oak trapdoor", "You can now make " + "" + "oak trapdoors" + "" + " for your " + "" + "throne room" + "" + "."); + case 19: + return newstruct cs2func_script_3_struct(78, 8307, "Teak oubliette ladder", "You can now construct " + "" + "teak oubliette ladders" + "" + " for your house."); + case 20: + return newstruct cs2func_script_3_struct(78, 8365, "Teak lever", "You can now construct " + "" + "teak levers" + "" + " for your house."); + case 21: + return newstruct cs2func_script_3_struct(78, 8368, "Teak trapdoor", "You can now construct " + "" + "teak trapdoors" + "" + " for your " + "" + "throne room" + "" + "."); + case 22: + return newstruct cs2func_script_3_struct(80, 8330, "Marble portal frame", "You can now construct " + "" + "marble portal frames" + "" + " for your house."); + case 23: + return newstruct cs2func_script_3_struct(80, 8333, "Scrying pool", "You can now construct " + "" + "scrying pools" + "" + " for your house."); + case 24: + return newstruct cs2func_script_3_struct(82, 8255, "Marble staircase", "You can now construct a " + "" + "marble staircase" + "" + " for your house."); + case 25: + return newstruct cs2func_script_3_struct(88, 8308, "Mahogany oubliette ladder", "You can now construct " + "" + "mahogany oubliette ladders" + "" + " for your house."); + case 26: + return newstruct cs2func_script_3_struct(88, 8366, "Mahogany lever", "You can now construct " + "" + "mahogany levers" + "" + " for your house."); + case 27: + return newstruct cs2func_script_3_struct(88, 8369, "Mahogany trapdoor", "You can now construct " + "" + "mahogany trapdoors" + "" + " for your " + "" + "throne room" + "" + "."); + case 28: + return newstruct cs2func_script_3_struct(91, 18778, "Starved ancient effigies", "You can now investigate " + "" + "starved ancient effigies" + "" + " using your knowledge of Construction."); + case 29: + return newstruct cs2func_script_3_struct(93, 18779, "Nourished ancient effigies", "You can now investigate " + "" + "nourished ancient effigies" + "" + " using your knowledge of Construction."); + case 30: + return newstruct cs2func_script_3_struct(95, 18780, "Sated ancient effigies", "You can now investigate " + "" + "sated ancient effigies" + "" + " using your knowledge of Construction."); + case 31: + return newstruct cs2func_script_3_struct(97, 18781, "Gorged ancient effigies", "You can now investigate " + "" + "gorged ancient effigies" + "" + " using your knowledge of Construction."); + case 32: + return newstruct cs2func_script_3_struct(97, 8259, "Marble spiral staircase", "You can now construct " + "" + "marble spiral staircases" + "" + " for your house."); + } + break; + case 11: + switch (arg1) { + case 0: + return newstruct cs2func_script_3_struct(37, 15222, "Garden habitat", "You can now construct " + "" + "garden habitats" + "" + " for your " + "" + "menagerie" + "" + "."); + case 1: + return newstruct cs2func_script_3_struct(37, 15227, "Oak pet house", "You can now construct " + "" + "oak pet houses" + "" + " for your " + "" + "menagerie" + "" + "."); + case 2: + return newstruct cs2func_script_3_struct(37, 15233, "Oak pet feeder", "You can now construct " + "" + "oak pet feeders" + "" + " for your " + "" + "menagerie" + "" + "."); + case 3: + return newstruct cs2func_script_3_struct(41, 15236, "Mini obelisk", "You can now construct " + "" + "mini obelisks" + "" + " for your " + "" + "menagerie" + "" + "."); + case 4: + return newstruct cs2func_script_3_struct(47, 15223, "Jungle habitat", "You can now construct " + "" + "jungle habitats" + "" + " for your " + "" + "menagerie" + "" + "."); + case 5: + return newstruct cs2func_script_3_struct(52, 15228, "Teak pet house", "You can now construct " + "" + "teak pet houses" + "" + " for your " + "" + "menagerie" + "" + "."); + case 6: + return newstruct cs2func_script_3_struct(52, 15234, "Teak pet feeder", "You can now construct " + "" + "teak pet feeders" + "" + " for your " + "" + "menagerie" + "" + "."); + case 7: + return newstruct cs2func_script_3_struct(57, 15224, "Desert habitat", "You can now construct " + "" + "desert habitats" + "" + " for your " + "" + "menagerie" + "" + "."); + case 8: + return newstruct cs2func_script_3_struct(67, 15229, "Mahogany pet house", "You can now construct " + "" + "mahogany pet houses" + "" + " for your " + "" + "menagerie" + "" + "."); + case 9: + return newstruct cs2func_script_3_struct(67, 15235, "Mahogany pet feeder", "You can now construct " + "" + "mahogany pet feeders" + "" + " for your " + "" + "menagerie" + "" + "."); + case 10: + return newstruct cs2func_script_3_struct(67, 15225, "Polar habitat", "You can now construct " + "" + "polar habitats" + "" + " for your " + "" + "menagerie" + "" + "."); + case 11: + return newstruct cs2func_script_3_struct(77, 15226, "Volcanic habitat", "You can now construct " + "" + "volcanic habitats" + "" + " for your " + "" + "menagerie" + "" + "."); + case 12: + return newstruct cs2func_script_3_struct(92, 15230, "Consecrated pet house", "You can now construct " + "" + "consecrated pet houses" + "" + " for your " + "" + "menagerie" + "" + "."); + case 13: + return newstruct cs2func_script_3_struct(92, 15231, "Desecrated pet house", "You can now construct " + "" + "desecrated pet houses" + "" + " for your " + "" + "menagerie" + "" + "."); + case 14: + return newstruct cs2func_script_3_struct(92, 15232, "Natural pet house", "You can now construct " + "" + "natural pet houses" + "" + " for your " + "" + "menagerie" + "" + "."); + } + break; + case 12: + switch (arg1) { + case 0: + return newstruct cs2func_script_3_struct(20, 7974, "Rick", "You can now hire " + "" + "Rick" + "" + "."); + case 1: + return newstruct cs2func_script_3_struct(25, 7974, "Maid", "You can now hire " + "" + "maids" + "" + "."); + case 2: + return newstruct cs2func_script_3_struct(30, 7974, "Cook", "You can now hire " + "" + "cooks" + "" + "."); + case 3: + return newstruct cs2func_script_3_struct(40, 7974, "Butler", "You can now hire " + "" + "butlers" + "" + "."); + case 4: + return newstruct cs2func_script_3_struct(50, 7974, "Demon butler", "You can now hire " + "" + "demon butlers" + "" + "."); + } + break; + case 13: + switch (arg1) { + case 0: + return newstruct cs2func_script_3_struct(1, 14172, "Stealing Creation - class 1 barriers", "You can now make " + "" + "class 1 barriers" + "" + " in Stealing Creation."); + case 1: + return newstruct cs2func_script_3_struct(20, 14174, "Stealing Creation - class 2 barriers", "You can now make " + "" + "class 2 barriers" + "" + " in Stealing Creation."); + case 2: + return newstruct cs2func_script_3_struct(40, 14176, "Stealing Creation - class 3 barriers", "You can now make " + "" + "class 3 barriers" + "" + " in Stealing Creation."); + case 3: + return newstruct cs2func_script_3_struct(50, 20704, "Members: access to the Livid Farm (with 70 Magic, 60 Agility, 60 Crafting, 60 Farming and Lunar Diplomacy)", "Members can access the " + "" + "Livid Farm" + "" + " (with 70 Magic, 60 Agility, 60 Crafting, 60 Farming and Lunar Diplomacy)."); + case 4: + return newstruct cs2func_script_3_struct(60, 14178, "Stealing Creation - class 4 barriers", "You can now make " + "" + "class 4 barriers" + "" + " in Stealing Creation."); + case 5: + return newstruct cs2func_script_3_struct(80, 14180, "Stealing Creation - class 5 barriers", "You can now make " + "" + "class 5 barriers" + "" + " in Stealing Creation."); + } + break; + case 14: + switch (arg1) { + case 0: + return newstruct cs2func_script_3_struct(-1, 15707, "Dungeoneering skill tasks" + "
" + "As your Construction level increases, you will be able to attempt higher-level construction tasks within Daemonheim. You will also be more likely to succeed when attempting construction tasks within Daemonheim.", ""); + case 1: + return newstruct cs2func_script_3_struct(5, 1510, "Start room photo booth", "You can now make " + "" + "a photo booth" + "" + " in the start room of Daemonheim."); + case 2: + return newstruct cs2func_script_3_struct(25, 18835, "Start room farming patch" + "
" + "5 seeping elm branches and 5 bathus bars", "You can now make " + "" + "farming patches" + "" + " in the start room of Daemonheim."); + case 3: + return newstruct cs2func_script_3_struct(50, 18837, "Start room range" + "
" + "5 utuku branches and 5 kratonite bars", "You can now make " + "" + "ranges" + "" + " in the start room of Daemonheim."); + case 4: + return newstruct cs2func_script_3_struct(75, 18836, "Start room prayer altar" + "
" + "5 bovistrangler logs and 5 zephyrium bars", "You can now make " + "" + "prayer altars" + "" + " in the start room of Daemonheim."); + } + break; + case 15: + SWITCH (arg1) { + case 0: + GOTO flow_444 + case 1: + GOTO flow_445 + case 2: + GOTO flow_446 + case 3: + GOTO flow_447 + case 4: + GOTO flow_448 + case 5: + GOTO flow_449 + case 6: + GOTO flow_450 + case 7: + GOTO flow_451 + case 8: + GOTO flow_452 + case 9: + GOTO flow_453 + case 10: + GOTO flow_454 + case 11: + GOTO flow_455 + case 12: + GOTO flow_456 + case 13: + GOTO flow_457 + case 14: + GOTO flow_458 + case 15: + GOTO flow_459 + case 16: + GOTO flow_460 + case 17: + GOTO flow_461 + case 18: + GOTO flow_462 + } + break; + flow_444: + return newstruct cs2func_script_3_struct(1, 2347, "Maximum rooms: 20", "You can now have a maximum of " + "" + "20 rooms" + "" + " in your house."); + flow_445: + return newstruct cs2func_script_3_struct(1, 8794, "Maximum dimensions: 3x3", "Your house can now have maximum dimensions of " + "" + "3 rooms wide by 3 rooms long" + "" + "."); + flow_446: + return newstruct cs2func_script_3_struct(15, 8794, "Maximum dimensions: 4x4", "Your house can now have maximum dimensions of " + "" + "4 rooms wide by 4 rooms long" + "" + "."); + flow_447: + return newstruct cs2func_script_3_struct(30, 8794, "Maximum dimensions: 5x5", "Your house can now have maximum dimensions of " + "" + "5 rooms wide by 5 rooms long" + "" + "."); + flow_448: + return newstruct cs2func_script_3_struct(38, 2347, "Maximum rooms: 21", "You can now have a maximum of " + "" + "21 rooms" + "" + " in your house."); + flow_449: + return newstruct cs2func_script_3_struct(44, 2347, "Maximum rooms: 22", "You can now have a maximum of " + "" + "22 rooms" + "" + " in your house."); + flow_450: + return newstruct cs2func_script_3_struct(45, 8794, "Maximum dimensions: 6x6", "Your house can now have maximum dimensions of " + "" + "6 rooms wide by 6 rooms long" + "" + "."); + flow_451: + return newstruct cs2func_script_3_struct(50, 2347, "Maximum rooms: 23", "You can now have a maximum of " + "" + "23 rooms" + "" + " in your house."); + flow_452: + return newstruct cs2func_script_3_struct(56, 2347, "Maximum rooms: 24", "You can now have a maximum of " + "" + "24 rooms" + "" + " in your house."); + flow_453: + return newstruct cs2func_script_3_struct(60, 8794, "Maximum dimensions: 7x7", "Your house can now have maximum dimensions of " + "" + "7 rooms wide by 7 rooms long" + "" + "."); + flow_454: + return newstruct cs2func_script_3_struct(62, 2347, "Maximum rooms: 25", "You can now have a maximum of " + "" + "25 rooms" + "" + " in your house."); + flow_455: + return newstruct cs2func_script_3_struct(68, 2347, "Maximum rooms: 26", "You can now have a maximum of " + "" + "26 rooms" + "" + " in your house."); + flow_456: + return newstruct cs2func_script_3_struct(74, 2347, "Maximum rooms: 27", "You can now have a maximum of " + "" + "27 rooms" + "" + " in your house."); + flow_457: + return newstruct cs2func_script_3_struct(80, 2347, "Maximum rooms: 28", "You can now have a maximum of " + "" + "28 rooms" + "" + " in your house."); + flow_458: + return newstruct cs2func_script_3_struct(86, 2347, "Maximum rooms: 29", "You can now have a maximum of " + "" + "29 rooms" + "" + " in your house."); + flow_459: + return newstruct cs2func_script_3_struct(92, 2347, "Maximum rooms: 30", "You can now have a maximum of " + "" + "30 rooms" + "" + " in your house."); + flow_460: + return newstruct cs2func_script_3_struct(96, 2347, "Maximum rooms: 31", "You can now have a maximum of " + "" + "31 rooms" + "" + " in your house."); + flow_461: + return newstruct cs2func_script_3_struct(99, 2347, "Maximum rooms: 32", "You can now have a maximum of " + "" + "32 rooms" + "" + " in your house."); + flow_462: + return newstruct cs2func_script_3_struct(99, 9789, "Skill mastery", "" + "Congratulations! You are now a master of " + "" + "Construction" + "" + ". Why not visit the " + "" + "Estate Agent" + "" + "? He has something special that is only available to true masters of the " + "" + "Construction" + "" + " skill!"); + } + return newstruct cs2func_script_3_struct(0, -1, "", ""); +} diff --git a/dumps/scripts/30.cs2 b/dumps/scripts/30.cs2 new file mode 100644 index 0000000..2e41536 --- /dev/null +++ b/dumps/scripts/30.cs2 @@ -0,0 +1,4 @@ +void script_30(int arg0,int arg1) { + script_31(arg0, arg1, 792, 789, 790, 791, 773, 788); + return; +} diff --git a/dumps/scripts/300.cs2 b/dumps/scripts/300.cs2 new file mode 100644 index 0000000..7abc1d5 --- /dev/null +++ b/dumps/scripts/300.cs2 @@ -0,0 +1,175 @@ +int script_300(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,string arg9) { + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int stack_dump0; + int stack_dump1; + int stack_dump2; + int stack_dump3; + int stack_dump4; + int stack_dump5; + int stack_dump6; + cs2func_script_296_struct(2,0,0) structdump_7; + ivar9 = 0; + ivar10 = 0; + stack_dump0 = arg0; + stack_dump1 = arg1; + stack_dump2 = arg3; + stack_dump3 = arg4; + stack_dump4 = arg5; + stack_dump5 = arg6; + stack_dump6 = arg7; + structdump_7 = script_296(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4, stack_dump5, stack_dump6); + ivar10 = structdump_7.intpart_1; + ivar9 = structdump_7.intpart_0; + ivar11 = getOtherCommonData(arg2, 650); + ivar12 = getOtherCommonData(arg2, 651); + ivar13 = add(add(getMaxLineWidth(512, 591, arg9), ivar11), ivar11); + ivar14 = add(add(add(multiply(getLineCount(getWidgetActualWidth(new WidgetPointer(arg3)), 591, arg9), 13), 2), ivar12), ivar12); + ivar15 = getOtherCommonData(arg2, 647); + ivar16 = getOtherCommonData(arg2, 648); + ivar17 = getOtherCommonData(arg2, 649); + ivar18 = getOtherCommonData(arg2, 652); + ivar19 = divide(subtract(ivar13, ivar11), 2); + ivar20 = divide(subtract(ivar14, ivar12), 2); + if (setWidgetRegister(new WidgetPointer(arg3), arg8)) { + setWidgetPosition(ivar9, ivar10, 1, 1); + } else { + createExtraChild(new WidgetPointer(arg3), 5, arg8); + setWidgetPosition(ivar9, ivar10, 1, 1); + setWidgetSize(subtract(ivar13, multiply(ivar11, 2)), subtract(ivar14, multiply(ivar12, 2)), 0, 0); + setWidgetSprite(getOtherCommonData(arg2, 646)); + cs2method1107(1); + } + arg8 = add(arg8, 1); + if (setWidgetRegister(new WidgetPointer(arg3), arg8)) { + setWidgetPosition(ivar9, subtract(ivar10, ivar20), 1, 1); + } else { + createExtraChild(new WidgetPointer(arg3), 5, arg8); + setWidgetPosition(ivar9, subtract(ivar10, ivar20), 1, 1); + setWidgetSize(subtract(ivar13, multiply(ivar11, 2)), ivar12, 0, 0); + setWidgetSprite(ivar16); + cs2method1107(1); + setWidgetVFlip(0); + setWidgetHFlip(0); + } + arg8 = add(arg8, 1); + if (setWidgetRegister(new WidgetPointer(arg3), arg8)) { + setWidgetPosition(ivar9, add(ivar10, ivar20), 1, 1); + } else { + createExtraChild(new WidgetPointer(arg3), 5, arg8); + setWidgetPosition(ivar9, add(ivar10, ivar20), 1, 1); + setWidgetSize(subtract(ivar13, multiply(ivar11, 2)), ivar12, 0, 0); + setWidgetSprite(ivar16); + cs2method1107(1); + setWidgetVFlip(1); + setWidgetHFlip(0); + } + arg8 = add(arg8, 1); + if (setWidgetRegister(new WidgetPointer(arg3), arg8)) { + setWidgetPosition(subtract(ivar9, ivar19), ivar10, 1, 1); + } else { + createExtraChild(new WidgetPointer(arg3), 5, arg8); + setWidgetPosition(subtract(ivar9, ivar19), ivar10, 1, 1); + setWidgetSize(ivar11, subtract(ivar14, multiply(ivar12, 2)), 0, 0); + setWidgetSprite(ivar17); + cs2method1107(1); + setWidgetVFlip(0); + setWidgetHFlip(0); + } + arg8 = add(arg8, 1); + if (setWidgetRegister(new WidgetPointer(arg3), arg8)) { + setWidgetPosition(add(ivar9, ivar19), ivar10, 1, 1); + } else { + createExtraChild(new WidgetPointer(arg3), 5, arg8); + setWidgetPosition(add(ivar9, ivar19), ivar10, 1, 1); + setWidgetSize(ivar11, subtract(ivar14, multiply(ivar12, 2)), 0, 0); + setWidgetSprite(ivar17); + cs2method1107(1); + setWidgetVFlip(0); + setWidgetHFlip(1); + } + arg8 = add(arg8, 1); + if (setWidgetRegister(new WidgetPointer(arg3), arg8)) { + setWidgetPosition(subtract(ivar9, ivar19), subtract(ivar10, ivar20), 1, 1); + } else { + createExtraChild(new WidgetPointer(arg3), 5, arg8); + setWidgetPosition(subtract(ivar9, ivar19), subtract(ivar10, ivar20), 1, 1); + setWidgetSize(ivar11, ivar12, 0, 0); + setWidgetSprite(ivar15); + cs2method1107(0); + setWidgetVFlip(0); + setWidgetHFlip(0); + } + arg8 = add(arg8, 1); + if (setWidgetRegister(new WidgetPointer(arg3), arg8)) { + setWidgetPosition(add(ivar9, ivar19), subtract(ivar10, ivar20), 1, 1); + } else { + createExtraChild(new WidgetPointer(arg3), 5, arg8); + setWidgetPosition(add(ivar9, ivar19), subtract(ivar10, ivar20), 1, 1); + setWidgetSize(ivar11, ivar12, 0, 0); + setWidgetSprite(ivar15); + cs2method1107(0); + setWidgetVFlip(0); + setWidgetHFlip(1); + } + arg8 = add(arg8, 1); + if (setWidgetRegister(new WidgetPointer(arg3), arg8)) { + setWidgetPosition(subtract(ivar9, ivar19), add(ivar10, ivar20), 1, 1); + } else { + createExtraChild(new WidgetPointer(arg3), 5, arg8); + setWidgetPosition(subtract(ivar9, ivar19), add(ivar10, ivar20), 1, 1); + setWidgetSize(ivar11, ivar12, 0, 0); + setWidgetSprite(ivar15); + cs2method1107(0); + setWidgetVFlip(1); + setWidgetHFlip(0); + } + arg8 = add(arg8, 1); + if (setWidgetRegister(new WidgetPointer(arg3), arg8)) { + setWidgetPosition(add(ivar9, ivar19), add(ivar10, ivar20), 1, 1); + } else { + createExtraChild(new WidgetPointer(arg3), 5, arg8); + setWidgetPosition(add(ivar9, ivar19), add(ivar10, ivar20), 1, 1); + setWidgetSize(ivar11, ivar12, 0, 0); + setWidgetSprite(ivar15); + cs2method1107(0); + setWidgetVFlip(1); + setWidgetHFlip(1); + } + arg8 = add(arg8, 1); + if (setWidgetRegister(new WidgetPointer(arg3), arg8)) { + setWidgetPosition(add(ivar9, 1), add(ivar10, 1), 1, 1); + } else { + createExtraChild(new WidgetPointer(arg3), 4, arg8); + setWidgetPosition(add(ivar9, 1), add(ivar10, 1), 1, 1); + setWidgetSize(ivar13, ivar14, 0, 0); + setWidgetRGB(new Color(getOtherCommonData(arg2, 653))); + setWidgetTextAlignment(1, 1, 13); + setWidgetFont(591); + setWidgetText(arg9); + } + arg8 = add(arg8, 1); + if (setWidgetRegister(new WidgetPointer(arg3), arg8)) { + setWidgetPosition(ivar9, ivar10, 1, 1); + } else { + createExtraChild(new WidgetPointer(arg3), 4, arg8); + setWidgetPosition(ivar9, ivar10, 1, 1); + setWidgetSize(ivar13, ivar14, 0, 0); + setWidgetRGB(new Color(ivar18)); + setWidgetTextAlignment(1, 1, 13); + setWidgetFont(591); + setWidgetText(arg9); + } + arg8 = add(arg8, 1); + return arg8; +} diff --git a/dumps/scripts/3000.cs2 b/dumps/scripts/3000.cs2 new file mode 100644 index 0000000..0751bb0 --- /dev/null +++ b/dumps/scripts/3000.cs2 @@ -0,0 +1,6 @@ +void script_3000() { + if (((boolean)mod(getClientCycle(), 50))) { + script_3001(); + } + return; +} diff --git a/dumps/scripts/3001.cs2 b/dumps/scripts/3001.cs2 new file mode 100644 index 0000000..33c2179 --- /dev/null +++ b/dumps/scripts/3001.cs2 @@ -0,0 +1,57 @@ +void script_3001() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + string svar0; + string svar1; + string svar2; + string svar3; + opcStruct6901(3,0,0) structdump_0; + ivar0 = 0; + ivar1 = 0; + ivar2 = 0; + svar0 = ""; + ivar3 = 0; + ivar4 = 0; + ivar5 = 0; + svar1 = ""; + svar2 = ""; + svar3 = ""; + structdump_0 = cs2method6901(); + ivar0 = structdump_0.intpart_2; + ivar2 = structdump_0.intpart_1; + ivar1 = structdump_0.intpart_0; + if (((boolean)ivar0) && isSiteSettingsMembers()) { + svar0 = minutesToUtcTime(ivar1); + ivar3 = divide(ivar2, 1440); + ivar4 = divide(mod(ivar2, 1440), 60); + ivar5 = mod(ivar2, 60); + if (add(add(ivar3, ivar4), ivar5) != 0) { + svar1 = " (in " + script_4582(ivar3, ivar4, ivar5) + ")"; + } + svar2 = "Your membership will expire on " + svar0 + svar1 + ". Renew now to avoid losing member status. Click " + "" + "" + "here" + "" + "" + " to renew."; + svar3 = "Your membership will expire on " + svar0 + svar1 + ". Renew now to avoid losing member status. Click " + "" + "" + "here" + "" + "" + " to renew."; + setWidgetText(new WidgetPointer(907,54), svar2); + setScriptCallOnMouseEntered(68, new WidgetPointer(-32768,3), svar3, "Is", new WidgetPointer(907,54)); + setScriptCallOnMouseExit(68, new WidgetPointer(-32768,3), svar2, "Is", new WidgetPointer(907,54)); + } + ivar6 = cs2method6904(); + if (((boolean)ivar6)) { + setWidgetText(new WidgetPointer(907,1), "Welcome to RuneScape!"); + return; + } + ivar7 = subtract(getCurrentDaysSinceLaunch(), ivar6); + if (ivar7 < 1) { + setWidgetText(new WidgetPointer(907,1), "You last logged in earlier today from: " + getLastIp()); + } else if (((boolean)ivar7)) { + setWidgetText(new WidgetPointer(907,1), "You last logged in yesterday from: " + getLastIp()); + } else { + setWidgetText(new WidgetPointer(907,1), "You last logged in " + intToStr(ivar7) + " days ago from: " + getLastIp()); + } + return; +} diff --git a/dumps/scripts/3002.cs2 b/dumps/scripts/3002.cs2 new file mode 100644 index 0000000..5500f08 --- /dev/null +++ b/dumps/scripts/3002.cs2 @@ -0,0 +1,4 @@ +void script_3002(int arg0) { + script_3003(arg0); + return; +} diff --git a/dumps/scripts/3003.cs2 b/dumps/scripts/3003.cs2 new file mode 100644 index 0000000..27652f9 --- /dev/null +++ b/dumps/scripts/3003.cs2 @@ -0,0 +1,23 @@ +void script_3003(int arg0) { + int ivar1; + if (((int)cs2method_3408(105, 73, 942, arg0)) == -1) { + return; + } + ivar1 = -1; + if (getWidgetActualHeight(new WidgetPointer(907,3)) > 30) { + ivar1 = 0; + } else if (getWidgetActualHeight(new WidgetPointer(907,4)) > 30) { + ivar1 = 1; + } else if (getWidgetActualHeight(new WidgetPointer(907,5)) > 30) { + ivar1 = 2; + } else { + if (getWidgetActualHeight(new WidgetPointer(907,43)) > 30) { + ivar1 = 3; + } + } + if (arg0 == ivar1) { + return; + } + script_3004(ivar1, arg0); + return; +} diff --git a/dumps/scripts/3004.cs2 b/dumps/scripts/3004.cs2 new file mode 100644 index 0000000..ffc8dca --- /dev/null +++ b/dumps/scripts/3004.cs2 @@ -0,0 +1,20 @@ +void script_3004(int arg0,int arg1) { + int stack_dump0; + cs2func_script_3011_struct(7,0,0) structdump_1; + cs2func_script_3011_struct(7,0,0) structdump_2; + setScriptCallOnMousePressed(-1, "", new WidgetPointer(907,41)); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(907,29)); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(907,17)); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(907,55)); + if (getWidgetSpriteId(new WidgetPointer(script_3013(arg1))) == 2669) { + stack_dump0 = arg1; + structdump_1 = script_3011(stack_dump0); + script_3007(structdump_1.intpart_0, structdump_1.intpart_1, structdump_1.intpart_2, structdump_1.intpart_3, structdump_1.intpart_4, structdump_1.intpart_5, structdump_1.intpart_6); + } else { + stack_dump0 = arg1; + structdump_2 = script_3011(stack_dump0); + script_3009(structdump_2.intpart_0, structdump_2.intpart_1, structdump_2.intpart_2, structdump_2.intpart_3, structdump_2.intpart_4, structdump_2.intpart_5, structdump_2.intpart_6); + } + setScriptCallOnGameloop(3005, arg1, arg0, "ii", new WidgetPointer(907,2)); + return; +} diff --git a/dumps/scripts/3005.cs2 b/dumps/scripts/3005.cs2 new file mode 100644 index 0000000..eb381be --- /dev/null +++ b/dumps/scripts/3005.cs2 @@ -0,0 +1,131 @@ +void script_3005(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int stack_dump0; + cs2func_script_3011_struct(7,0,0) structdump_1; + cs2func_script_3011_struct(7,0,0) structdump_2; + ivar2 = script_3012(arg1); + ivar3 = getWidgetActualHeight(new WidgetPointer(ivar2)); + ivar4 = subtract(ivar3, 3); + if (ivar3 > 30) { + if (ivar4 < 30) { + setWidgetSize(0, 30, 1, 0, new WidgetPointer(ivar2)); + } else { + setWidgetSize(0, ivar4, 1, 0, new WidgetPointer(ivar2)); + } + switch (arg1) { + case 0: + ivar4 = subtract(getWidgetActualY(new WidgetPointer(907,4)), 3); + if (ivar4 < 30) { + setWidgetPosition(0, 30, 0, 0, new WidgetPointer(907,4)); + } else { + setWidgetPosition(0, ivar4, 0, 0, new WidgetPointer(907,4)); + } + ivar4 = subtract(getWidgetActualY(new WidgetPointer(907,5)), 3); + if (ivar4 < multiply(30, 2)) { + setWidgetPosition(0, multiply(30, 2), 0, 0, new WidgetPointer(907,5)); + } else { + setWidgetPosition(0, ivar4, 0, 0, new WidgetPointer(907,5)); + } + ivar4 = subtract(getWidgetActualY(new WidgetPointer(907,43)), 3); + if (ivar4 < multiply(30, 3)) { + setWidgetPosition(0, multiply(30, 3), 0, 0, new WidgetPointer(907,43)); + } else { + setWidgetPosition(0, ivar4, 0, 0, new WidgetPointer(907,43)); + } + break; + case 1: + ivar4 = subtract(getWidgetActualY(new WidgetPointer(907,5)), 3); + if (ivar4 < multiply(30, 2)) { + setWidgetPosition(0, multiply(30, 2), 0, 0, new WidgetPointer(907,5)); + } else { + setWidgetPosition(0, ivar4, 0, 0, new WidgetPointer(907,5)); + } + ivar4 = subtract(getWidgetActualY(new WidgetPointer(907,43)), 3); + if (ivar4 < multiply(30, 3)) { + setWidgetPosition(0, multiply(30, 3), 0, 0, new WidgetPointer(907,43)); + } else { + setWidgetPosition(0, ivar4, 0, 0, new WidgetPointer(907,43)); + } + break; + case 2: + ivar4 = subtract(getWidgetActualY(new WidgetPointer(907,43)), 3); + if (ivar4 < multiply(30, 3)) { + setWidgetPosition(0, multiply(30, 3), 0, 0, new WidgetPointer(907,43)); + } else { + setWidgetPosition(0, ivar4, 0, 0, new WidgetPointer(907,43)); + } + } + } + ivar5 = script_3012(arg0); + ivar3 = getWidgetActualHeight(new WidgetPointer(ivar5)); + ivar4 = add(ivar3, 3); + if (ivar3 < 88) { + if (ivar4 > 88) { + setWidgetSize(0, 88, 1, 0, new WidgetPointer(ivar5)); + } else { + setWidgetSize(0, ivar4, 1, 0, new WidgetPointer(ivar5)); + } + switch (arg0) { + case 0: + ivar4 = add(getWidgetActualY(new WidgetPointer(907,4)), 3); + if (ivar4 > 88) { + setWidgetPosition(0, 88, 0, 0, new WidgetPointer(907,4)); + } else { + setWidgetPosition(0, ivar4, 0, 0, new WidgetPointer(907,4)); + } + ivar4 = add(getWidgetActualY(new WidgetPointer(907,5)), 3); + if (ivar4 > add(88, 30)) { + setWidgetPosition(0, add(88, 30), 0, 0, new WidgetPointer(907,5)); + } else { + setWidgetPosition(0, ivar4, 0, 0, new WidgetPointer(907,5)); + } + ivar4 = add(getWidgetActualY(new WidgetPointer(907,43)), 3); + if (ivar4 > add(88, multiply(30, 2))) { + setWidgetPosition(0, add(88, multiply(30, 2)), 0, 0, new WidgetPointer(907,43)); + } else { + setWidgetPosition(0, ivar4, 0, 0, new WidgetPointer(907,43)); + } + break; + case 1: + ivar4 = add(getWidgetActualY(new WidgetPointer(907,5)), 3); + if (ivar4 > add(88, 30)) { + setWidgetPosition(0, add(88, 30), 0, 0, new WidgetPointer(907,5)); + } else { + setWidgetPosition(0, ivar4, 0, 0, new WidgetPointer(907,5)); + } + ivar4 = add(getWidgetActualY(new WidgetPointer(907,43)), 3); + if (ivar4 > add(88, multiply(30, 2))) { + setWidgetPosition(0, add(88, multiply(30, 2)), 0, 0, new WidgetPointer(907,43)); + } else { + setWidgetPosition(0, ivar4, 0, 0, new WidgetPointer(907,43)); + } + break; + case 2: + ivar4 = add(getWidgetActualY(new WidgetPointer(907,43)), 3); + if (ivar4 > add(88, multiply(30, 2))) { + setWidgetPosition(0, add(88, multiply(30, 2)), 0, 0, new WidgetPointer(907,43)); + } else { + setWidgetPosition(0, ivar4, 0, 0, new WidgetPointer(907,43)); + } + } + } else { + setScriptCallOnGameloop(-1, "", new WidgetPointer(907,2)); + if (getWidgetSpriteId(new WidgetPointer(script_3013(arg1))) == 2669) { + stack_dump0 = arg1; + structdump_1 = script_3011(stack_dump0); + script_3008(structdump_1.intpart_0, structdump_1.intpart_1, structdump_1.intpart_2, structdump_1.intpart_3, structdump_1.intpart_4, structdump_1.intpart_5, structdump_1.intpart_6); + } else { + stack_dump0 = arg1; + structdump_2 = script_3011(stack_dump0); + script_3010(structdump_2.intpart_0, structdump_2.intpart_1, structdump_2.intpart_2, structdump_2.intpart_3, structdump_2.intpart_4, structdump_2.intpart_5, structdump_2.intpart_6); + } + setScriptCallOnMousePressed(3002, 3, "i", new WidgetPointer(907,55)); + setScriptCallOnMousePressed(3002, 2, "i", new WidgetPointer(907,17)); + setScriptCallOnMousePressed(3002, 1, "i", new WidgetPointer(907,29)); + setScriptCallOnMousePressed(3002, 0, "i", new WidgetPointer(907,41)); + } + return; +} diff --git a/dumps/scripts/3006.cs2 b/dumps/scripts/3006.cs2 new file mode 100644 index 0000000..0e0067b --- /dev/null +++ b/dumps/scripts/3006.cs2 @@ -0,0 +1,30 @@ +void script_3006(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7) { + setWidgetSize(0, 88, 1, 0, new WidgetPointer(arg1)); + if (getWidgetSpriteId(new WidgetPointer(arg5)) == 2669) { + script_3007(arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } else { + script_3009(arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } + switch (arg0) { + case 0: + setWidgetPosition(0, 88, 0, 0, new WidgetPointer(907,4)); + setWidgetPosition(0, add(88, 30), 0, 0, new WidgetPointer(907,5)); + setWidgetPosition(0, add(88, multiply(30, 2)), 0, 0, new WidgetPointer(907,43)); + break; + case 1: + setWidgetPosition(0, 30, 0, 0, new WidgetPointer(907,4)); + setWidgetPosition(0, add(88, 30), 0, 0, new WidgetPointer(907,5)); + setWidgetPosition(0, add(88, multiply(30, 2)), 0, 0, new WidgetPointer(907,43)); + break; + case 2: + setWidgetPosition(0, 30, 0, 0, new WidgetPointer(907,4)); + setWidgetPosition(0, multiply(30, 2), 0, 0, new WidgetPointer(907,5)); + setWidgetPosition(0, add(88, multiply(30, 2)), 0, 0, new WidgetPointer(907,43)); + break; + case 3: + setWidgetPosition(0, 30, 0, 0, new WidgetPointer(907,4)); + setWidgetPosition(0, multiply(30, 2), 0, 0, new WidgetPointer(907,5)); + setWidgetPosition(0, multiply(30, 3), 0, 0, new WidgetPointer(907,43)); + } + return; +} diff --git a/dumps/scripts/3007.cs2 b/dumps/scripts/3007.cs2 new file mode 100644 index 0000000..6001d4b --- /dev/null +++ b/dumps/scripts/3007.cs2 @@ -0,0 +1,14 @@ +void script_3007(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6) { + setWidgetSize(13, 88, 0, 0, new WidgetPointer(arg1)); + setWidgetSprite(4681, new WidgetPointer(arg1)); + setWidgetSize(26, 88, 1, 0, new WidgetPointer(arg2)); + setWidgetSprite(4682, new WidgetPointer(arg2)); + setWidgetSize(13, 88, 0, 0, new WidgetPointer(arg3)); + setWidgetSprite(4684, new WidgetPointer(arg3)); + setWidgetSprite(2670, new WidgetPointer(arg5)); + setWidgetSize(13, 88, 0, 0, new WidgetPointer(arg6)); + setWidgetSprite(4683, new WidgetPointer(arg6)); + setScriptCallOnMouseEntered(-1, "", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/3008.cs2 b/dumps/scripts/3008.cs2 new file mode 100644 index 0000000..bcd88f5 --- /dev/null +++ b/dumps/scripts/3008.cs2 @@ -0,0 +1,26 @@ +void script_3008(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6) { + int ivar7; + int ivar8; + int ivar9; + int ivar10; + ivar7 = 4677; + ivar8 = 4678; + ivar9 = 4679; + ivar10 = 4680; + setWidgetSize(13, 30, 0, 0, new WidgetPointer(arg1)); + setWidgetSprite(ivar7, new WidgetPointer(arg1)); + setWidgetSize(26, 30, 1, 0, new WidgetPointer(arg2)); + setWidgetSprite(ivar8, new WidgetPointer(arg2)); + setWidgetSize(13, 30, 0, 0, new WidgetPointer(arg3)); + setWidgetSprite(ivar10, new WidgetPointer(arg3)); + setWidgetSprite(2670, new WidgetPointer(arg5)); + setWidgetSize(13, 30, 0, 0, new WidgetPointer(arg6)); + setWidgetSprite(ivar9, new WidgetPointer(arg6)); + setScriptCallOnMouseExit(4164, new WidgetPointer(arg1), ivar7, new WidgetPointer(arg2), ivar8, new WidgetPointer(arg6), ivar9, new WidgetPointer(arg3), ivar10, "IdIdIdId", new WidgetPointer(arg0)); + ivar7 = 4673; + ivar8 = 4674; + ivar9 = 4675; + ivar10 = 4676; + setScriptCallOnMouseEntered(4164, new WidgetPointer(arg1), ivar7, new WidgetPointer(arg2), ivar8, new WidgetPointer(arg6), ivar9, new WidgetPointer(arg3), ivar10, "IdIdIdId", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/3009.cs2 b/dumps/scripts/3009.cs2 new file mode 100644 index 0000000..73fa4ac --- /dev/null +++ b/dumps/scripts/3009.cs2 @@ -0,0 +1,14 @@ +void script_3009(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6) { + setWidgetSize(13, 88, 0, 0, new WidgetPointer(arg1)); + setWidgetSprite(4681, new WidgetPointer(arg1)); + setWidgetSize(26, 88, 1, 0, new WidgetPointer(arg2)); + setWidgetSprite(4682, new WidgetPointer(arg2)); + setWidgetSize(13, 88, 0, 0, new WidgetPointer(arg3)); + setWidgetSprite(4684, new WidgetPointer(arg3)); + setWidgetSprite(2673, new WidgetPointer(arg5)); + setWidgetSize(13, 88, 0, 0, new WidgetPointer(arg6)); + setWidgetSprite(4683, new WidgetPointer(arg6)); + setScriptCallOnMouseEntered(-1, "", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/301.cs2 b/dumps/scripts/301.cs2 new file mode 100644 index 0000000..7e5ab9d --- /dev/null +++ b/dumps/scripts/301.cs2 @@ -0,0 +1,18 @@ +void script_301(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + if (setWidgetRegister(new WidgetPointer(arg1), arg2)) { + setWidgetRGB(new Color(arg5)); + } + if ((arg3 != -1) && setWidgetRegister(new WidgetPointer(arg1), arg3)) { + setWidgetRGB(new Color(arg5)); + } + if (((boolean)arg0)) { + if (setWidgetRegister(new WidgetPointer(arg1), arg4)) { + setWidgetHidden(0); + } + } else { + if (setWidgetRegister(new WidgetPointer(arg1), arg4)) { + setWidgetHidden(1); + } + } + return; +} diff --git a/dumps/scripts/3010.cs2 b/dumps/scripts/3010.cs2 new file mode 100644 index 0000000..2c9369f --- /dev/null +++ b/dumps/scripts/3010.cs2 @@ -0,0 +1,26 @@ +void script_3010(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6) { + int ivar7; + int ivar8; + int ivar9; + int ivar10; + ivar7 = 4677; + ivar8 = 4678; + ivar9 = 4679; + ivar10 = 4680; + setWidgetSize(13, 30, 0, 0, new WidgetPointer(arg1)); + setWidgetSprite(ivar7, new WidgetPointer(arg1)); + setWidgetSize(26, 30, 1, 0, new WidgetPointer(arg2)); + setWidgetSprite(ivar8, new WidgetPointer(arg2)); + setWidgetSize(13, 30, 0, 0, new WidgetPointer(arg3)); + setWidgetSprite(ivar10, new WidgetPointer(arg3)); + setWidgetSprite(2673, new WidgetPointer(arg5)); + setWidgetSize(13, 30, 0, 0, new WidgetPointer(arg6)); + setWidgetSprite(4679, new WidgetPointer(arg6)); + setScriptCallOnMouseExit(4164, new WidgetPointer(arg1), ivar7, new WidgetPointer(arg2), ivar8, new WidgetPointer(arg6), ivar9, new WidgetPointer(arg3), ivar10, "IdIdIdId", new WidgetPointer(arg0)); + ivar7 = 4673; + ivar8 = 4674; + ivar9 = 4675; + ivar10 = 4676; + setScriptCallOnMouseEntered(4164, new WidgetPointer(arg1), ivar7, new WidgetPointer(arg2), ivar8, new WidgetPointer(arg6), ivar9, new WidgetPointer(arg3), ivar10, "IdIdIdId", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/3011.cs2 b/dumps/scripts/3011.cs2 new file mode 100644 index 0000000..b7bcd4f --- /dev/null +++ b/dumps/scripts/3011.cs2 @@ -0,0 +1,13 @@ +cs2func_script_3011_struct(7,0,0) script_3011(int arg0) { + switch (arg0) { + case 0: + return newstruct cs2func_script_3011_struct(script_3012(arg0), 59441182, 59441183, 59441185, script_3013(arg0), 59441187, 59441184); + case 1: + return newstruct cs2func_script_3011_struct(script_3012(arg0), 59441170, 59441171, 59441173, script_3013(arg0), 59441175, 59441172); + case 2: + return newstruct cs2func_script_3011_struct(script_3012(arg0), 59441158, 59441159, 59441161, script_3013(arg0), 59441163, 59441160); + case 3: + return newstruct cs2func_script_3011_struct(script_3012(arg0), 59441196, 59441197, 59441199, script_3013(arg0), 59441201, 59441198); + } + return newstruct cs2func_script_3011_struct(-1, -1, -1, -1, -1, -1, -1); +} diff --git a/dumps/scripts/3012.cs2 b/dumps/scripts/3012.cs2 new file mode 100644 index 0000000..f366d5d --- /dev/null +++ b/dumps/scripts/3012.cs2 @@ -0,0 +1,13 @@ +int script_3012(int arg0) { + switch (arg0) { + case 0: + return 59441155; + case 1: + return 59441156; + case 2: + return 59441157; + case 3: + return 59441195; + } + return -1; +} diff --git a/dumps/scripts/3013.cs2 b/dumps/scripts/3013.cs2 new file mode 100644 index 0000000..7216608 --- /dev/null +++ b/dumps/scripts/3013.cs2 @@ -0,0 +1,13 @@ +int script_3013(int arg0) { + switch (arg0) { + case 0: + return 59441186; + case 1: + return 59441174; + case 2: + return 59441162; + case 3: + return 59441200; + } + return -1; +} diff --git a/dumps/scripts/3014.cs2 b/dumps/scripts/3014.cs2 new file mode 100644 index 0000000..3f37892 --- /dev/null +++ b/dumps/scripts/3014.cs2 @@ -0,0 +1,50 @@ +void script_3014() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + flow_0: + ivar0 = 0; + ivar1 = 0; + ivar2 = ((int)isSiteSettingsMembers()); + ivar3 = rndExcl(100); + setWidgetIsHidden(true, new WidgetPointer(908,15)); + setWidgetIsHidden(false, new WidgetPointer(908,30)); + setWidgetText(new WidgetPointer(908,33), "Invite your friends to the world of RuneScape and receive a 7 day 10% XP boost."); + setWidgetText(new WidgetPointer(908,32), "Invite your friends to the world of RuneScape and receive a 7 day 10% XP boost."); + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(908,33)); + setWidgetPosition(8, 50, 0, 0, new WidgetPointer(908,33)); + setWidgetSize(363, 73, 0, 0, new WidgetPointer(908,33)); + setWidgetFont(591, new WidgetPointer(908,33)); + setWidgetTextAlignment(1, 2, 0, new WidgetPointer(908,33)); + setWidgetRGB(new Color(28, 28, 28), new WidgetPointer(908,32)); + setWidgetPosition(9, 51, 0, 0, new WidgetPointer(908,32)); + setWidgetSize(363, 73, 0, 0, new WidgetPointer(908,32)); + setWidgetFont(591, new WidgetPointer(908,32)); + setWidgetTextAlignment(1, 2, 0, new WidgetPointer(908,32)); + setWidgetSprite(7670, new WidgetPointer(908,31)); + setWidgetSprite(7662, new WidgetPointer(908,35)); + SWITCH (getLanguage()) { + case 1: + GOTO flow_1 + case 2: + GOTO flow_2 + case 3: + GOTO flow_3 + } + setWidgetSprite(7662, new WidgetPointer(908,35)); + GOTO flow_4 + flow_1: + setWidgetSprite(7664, new WidgetPointer(908,35)); + GOTO flow_4 + flow_2: + setWidgetSprite(7663, new WidgetPointer(908,35)); + GOTO flow_4 + flow_3: + setWidgetSprite(7665, new WidgetPointer(908,35)); + flow_4: + setScriptCallOnMouseEntered(4924, "", new WidgetPointer(908,30)); + setScriptCallOnMouseExit(5003, "", new WidgetPointer(908,30)); + setScriptCallOnMousePressed(5208, "", new WidgetPointer(908,30)); + return; +} diff --git a/dumps/scripts/3015.cs2 b/dumps/scripts/3015.cs2 new file mode 100644 index 0000000..ac669b1 --- /dev/null +++ b/dumps/scripts/3015.cs2 @@ -0,0 +1,4 @@ +void script_3015(int arg0,string arg1,string arg2,string arg3,string arg4) { + script_2190(1, arg0, 1, arg1, arg2, arg3, arg4); + return; +} diff --git a/dumps/scripts/3016.cs2 b/dumps/scripts/3016.cs2 new file mode 100644 index 0000000..a0b633b --- /dev/null +++ b/dumps/scripts/3016.cs2 @@ -0,0 +1,4 @@ +void script_3016() { + script_3017(); + return; +} diff --git a/dumps/scripts/3017.cs2 b/dumps/scripts/3017.cs2 new file mode 100644 index 0000000..028509a --- /dev/null +++ b/dumps/scripts/3017.cs2 @@ -0,0 +1,12 @@ +void script_3017() { + script_3018(); + setWidgetIsHidden(true, new WidgetPointer(906,41)); + if (isWidgetHidden(cs2method_3408(105, 73, 941, 5))) { + script_3161(1); + } else { + if (isWidgetHidden(cs2method_3408(105, 73, 941, 3))) { + script_4556(1); + } + } + return; +} diff --git a/dumps/scripts/3018.cs2 b/dumps/scripts/3018.cs2 new file mode 100644 index 0000000..a28ea5c --- /dev/null +++ b/dumps/scripts/3018.cs2 @@ -0,0 +1,21 @@ +void script_3018() { + setWidgetText(new WidgetPointer(906,149), ""); + setWidgetText(new WidgetPointer(906,151), ""); + setScriptCallOnKeyPress(-1, "", new WidgetPointer(906,151)); + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(906,155)); + setWidgetText(new WidgetPointer(906,159), "Ok"); + setWidgetContextMenuOption(1, new WidgetPointer(906,159), "Ok"); + setWidgetText(new WidgetPointer(906,161), "Close"); + setWidgetContextMenuOption(1, new WidgetPointer(906,161), "Close"); + setWidgetSize(265, 136, 0, 0, new WidgetPointer(906,147)); + setWidgetSize(0, 0, 1, 1, new WidgetPointer(906,151)); + setWidgetSize(8034, 0, 2, 1, new WidgetPointer(906,155)); + setWidgetSize(8034, 0, 2, 1, new WidgetPointer(906,159)); + setWidgetSize(8034, 0, 2, 1, new WidgetPointer(906,160)); + setWidgetSize(8034, 0, 2, 1, new WidgetPointer(906,161)); + setWidgetIsHidden(false, new WidgetPointer(906,160)); + setWidgetIsHidden(false, new WidgetPointer(906,161)); + globalstring_277 = ""; + globalint_1650 = 0; + return; +} diff --git a/dumps/scripts/3019.cs2 b/dumps/scripts/3019.cs2 new file mode 100644 index 0000000..903bad9 --- /dev/null +++ b/dumps/scripts/3019.cs2 @@ -0,0 +1,4 @@ +void script_3019(int arg0,string arg1) { + script_3020(arg0, arg1); + return; +} diff --git a/dumps/scripts/302.cs2 b/dumps/scripts/302.cs2 new file mode 100644 index 0000000..e625709 --- /dev/null +++ b/dumps/scripts/302.cs2 @@ -0,0 +1,6 @@ +void script_302(int arg0,int arg1,int arg2) { + if (((boolean)arg0) && (arg1 != -1)) { + script_303(arg1, arg2); + } + return; +} diff --git a/dumps/scripts/3020.cs2 b/dumps/scripts/3020.cs2 new file mode 100644 index 0000000..9ab7fb1 --- /dev/null +++ b/dumps/scripts/3020.cs2 @@ -0,0 +1,100 @@ +void script_3020(int arg0,string arg1) { + int ivar1; + int ivar2; + int ivar3; + string svar1; + string svar2; + string svar3; + string svar4; + ivar1 = 0; + svar1 = ""; + svar2 = ""; + ivar2 = -1; + svar3 = ""; + svar4 = ""; + ivar3 = -1; + if (strLength(globalstring_277) > 0) { + switch (arg0) { + case 0: + if ((strLength(globalstring_277) > 0) && (strLength(arg1) > 0)) { + if (cs2method5005() == 2) { + script_3047(1); + } + cs2method5009(strRemoveEntities(arg1), globalstring_277); + } + break; + case 1: + if (getFriendlistSize() < 0) { + messageType0("Unable to update Friends List - system busy."); + } else { + if (strLength(globalstring_277) > 0) { + cs2method3605(globalstring_277); + } + } + break; + case 2: + if (getIgnoreCount() < 0) { + messageType0("Unable to update Ignore List - system busy."); + } else { + if (strLength(globalstring_277) > 0) { + cs2method3607(globalstring_277); + } + } + break; + case 3: + if (getFriendlistSize() < 0) { + messageType0("Unable to update Friends List - system busy."); + } else { + if (strLength(globalstring_277) > 0) { + cs2method3606(globalstring_277); + } + } + break; + case 4: + if (getIgnoreCount() < 0) { + messageType0("Unable to update Ignore List - system busy."); + } else { + if (strLength(globalstring_277) > 0) { + cs2method3608(globalstring_277); + } + } + break; + case 5: + if ((cs2method3612() <= 0) && (strLength(globalstring_277) > 0)) { + sendUnknownFriendPacketMethod3619(globalstring_277); + } + break; + case 6: + globalint_1094 = 0; + cs2method5400(0, "bugtracker_v4", "index.html"); + break; + case 7: + if (strLength(globalstring_277) > 0) { + script_4465(globalstring_277); + } + break; + case 9: + if ((cs2method3612() > 0) && (strLength(globalstring_277) > 0)) { + script_1633(globalstring_277); + } + break; + case 10: + cancelLogin(); + globalint_1100 = -1; + break; + case 12: + script_3017(); + cancelLogin(); + globalint_1100 = -1; + script_4701(1, globalint_1553, globalint_1554, globalstring_128); + return; + } + } + globalint_1650 = 0; + if (((boolean)ivar1)) { + script_3015(ivar2, svar1, svar2, svar3, svar4); + } else { + script_3017(); + } + return; +} diff --git a/dumps/scripts/3021.cs2 b/dumps/scripts/3021.cs2 new file mode 100644 index 0000000..d0946a4 --- /dev/null +++ b/dumps/scripts/3021.cs2 @@ -0,0 +1,4 @@ +void script_3021() { + script_2276(globalint_1199, globalint_1212, 61145359); + return; +} diff --git a/dumps/scripts/3022.cs2 b/dumps/scripts/3022.cs2 new file mode 100644 index 0000000..1be7ed9 --- /dev/null +++ b/dumps/scripts/3022.cs2 @@ -0,0 +1,45 @@ +void script_3022(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5) { + int stack_dump0; + int stack_dump1; + int stack_dump2; + int stack_dump3; + string stack_dump4; + cs2func_script_802_struct(1,1,0) structdump_5; + switch (arg0) { + case 84: + script_3020(arg4, arg5); + return; + case 13: + script_3017(); + return; + case 102: + case 103: + case 98: + case 99: + case 96: + case 97: + if ((arg4 != -1) && (arg4 != 6)) { + globalint_1097 = script_1553(arg0, globalint_1097, globalstring_277); + script_1875(59375767, 59375768, globalstring_277); + } + return; + case 85: + case 101: + case -1: + if (((arg4 != -1) && (arg4 != 6)) && ((isValidChar(((char)arg1)) || (arg0 == 85)) || (arg0 == 101))) { + stack_dump0 = globalint_1097; + stack_dump1 = arg3; + stack_dump2 = arg0; + stack_dump3 = arg1; + stack_dump4 = globalstring_277; + structdump_5 = script_802(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + stack_dump4 = structdump_5.stringpart_0; + globalint_1097 = structdump_5.intpart_0; + globalstring_277 = stack_dump4; + setWidgetText(new WidgetPointer(arg2), replaceLtGt(globalstring_277)); + script_1875(59375767, 59375768, globalstring_277); + } + return; + } + return; +} diff --git a/dumps/scripts/3023.cs2 b/dumps/scripts/3023.cs2 new file mode 100644 index 0000000..778c86b --- /dev/null +++ b/dumps/scripts/3023.cs2 @@ -0,0 +1,22 @@ +void script_3023() { + setWidgetSize(subtract(getWidgetActualX(new WidgetPointer(909,31)), getWidgetActualX(new WidgetPointer(909,30))), 0, 0, 1, new WidgetPointer(909,45)); + setWidgetSize(subtract(subtract(getWidgetActualWidth(new WidgetPointer(909,41)), getWidgetActualWidth(new WidgetPointer(909,45))), 2), 0, 0, 1, new WidgetPointer(909,46)); + setWidgetScrollMax(0, 0, new WidgetPointer(909,41)); + cs2method2100(0, 0, new WidgetPointer(909,41)); + script_31(59572271, 59572265, 792, 789, 790, 791, 773, 788); + setWidgetScrollMax(0, 0, new WidgetPointer(909,78)); + cs2method2100(0, 0, new WidgetPointer(909,78)); + script_31(59572303, 59572302, 792, 789, 790, 791, 773, 788); + setWidgetScrollMax(0, 0, new WidgetPointer(909,52)); + cs2method2100(0, 0, new WidgetPointer(909,52)); + script_31(59572277, 59572276, 792, 789, 790, 791, 773, 788); + globalint_1122 = getWidgetActualHeight(new WidgetPointer(909,52)); + script_3029(59572269, 59572268, 59572270, 59572266, 59572265, 59572271); + setScriptCallOnFriendListChange(3028, new WidgetPointer(909,45), new WidgetPointer(909,44), new WidgetPointer(909,46), new WidgetPointer(909,42), new WidgetPointer(909,41), new WidgetPointer(909,47), "IIIIII", new WidgetPointer(909,41)); + script_3041(59572311, 59572310, 59572308, 59572302, 59572303); + setScriptCallOnFriendListChange(3040, new WidgetPointer(909,87), new WidgetPointer(909,86), new WidgetPointer(909,84), new WidgetPointer(909,78), new WidgetPointer(909,79), "IIIII", new WidgetPointer(909,78)); + script_3024(59572280); + globalstring_276 = ""; + script_3401(); + return; +} diff --git a/dumps/scripts/3024.cs2 b/dumps/scripts/3024.cs2 new file mode 100644 index 0000000..b6f7a10 --- /dev/null +++ b/dumps/scripts/3024.cs2 @@ -0,0 +1,4 @@ +void script_3024(int arg0) { + setWidgetRGB(new Color(41, 32, 22), new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/3025.cs2 b/dumps/scripts/3025.cs2 new file mode 100644 index 0000000..6d0b66f --- /dev/null +++ b/dumps/scripts/3025.cs2 @@ -0,0 +1,4 @@ +void script_3025(int arg0) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/3026.cs2 b/dumps/scripts/3026.cs2 new file mode 100644 index 0000000..1fb6d9c --- /dev/null +++ b/dumps/scripts/3026.cs2 @@ -0,0 +1,4 @@ +void script_3026(int arg0) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/3027.cs2 b/dumps/scripts/3027.cs2 new file mode 100644 index 0000000..0440edc --- /dev/null +++ b/dumps/scripts/3027.cs2 @@ -0,0 +1,4 @@ +void script_3027(int arg0) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/3028.cs2 b/dumps/scripts/3028.cs2 new file mode 100644 index 0000000..be5e7d8 --- /dev/null +++ b/dumps/scripts/3028.cs2 @@ -0,0 +1,4 @@ +void script_3028(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + script_3029(arg0, arg1, arg2, arg3, arg4, arg5); + return; +} diff --git a/dumps/scripts/3029.cs2 b/dumps/scripts/3029.cs2 new file mode 100644 index 0000000..00564fa --- /dev/null +++ b/dumps/scripts/3029.cs2 @@ -0,0 +1,150 @@ +void script_3029(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + string svar0; + string svar1; + string svar2; + string svar3; + int stack_dump0; + previousAndCurrentName(0,2,0) structdump_1; + if (cs2method5428(arg3, -1)) { + setScriptCallOnGameloop(3028, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), "IIIIII", new WidgetPointer(arg4)); + return; + } + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg4)); + deleteAllExtraChilds(new WidgetPointer(arg0)); + deleteAllExtraChilds(new WidgetPointer(arg1)); + deleteAllExtraChilds(new WidgetPointer(arg2)); + deleteAllExtraChilds(new WidgetPointer(arg3)); + ivar6 = getFriendlistSize(); + ivar7 = 0; + ivar8 = 0; + svar0 = ""; + svar1 = ""; + svar2 = ""; + ivar9 = 0; + ivar10 = 0; + ivar11 = 15; + ivar12 = 0; + ivar13 = 5; + ivar14 = 0; + ivar15 = 0; + ivar16 = 0; + svar3 = ""; + if (ivar6 == -2) { + setWidgetText(new WidgetPointer(909,38), "Name"); + script_3038(arg3, "Loading Friends List." + "
" + "
" + "Please wait."); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(909,31)), getWidgetActualHeight(new WidgetPointer(909,36)), 0, 0, new WidgetPointer(909,31)); + } else if (ivar6 == -1) { + setWidgetText(new WidgetPointer(909,38), "Name"); + script_3038(arg3, "Connecting to server." + "
" + "
" + "Please wait."); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(909,31)), getWidgetActualHeight(new WidgetPointer(909,36)), 0, 0, new WidgetPointer(909,31)); + } else if (ivar6 > 0) { + setWidgetText(new WidgetPointer(909,38), "Name (" + intToStr(ivar6) + "/200)"); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(909,31)), 4, 0, 1, new WidgetPointer(909,31)); + while (ivar7 < ivar6) { + stack_dump0 = ivar7; + structdump_1 = getFriendName(stack_dump0); + svar1 = structdump_1.stringpart_1; + svar0 = structdump_1.stringpart_0; + ivar9 = getFriendWorld(ivar7); + script_2996(arg3, ivar7, getWidgetActualWidth(new WidgetPointer(arg3)), ivar11, 0, ivar8, 0, 1, 0); + if (((boolean)mod(ivar7, 2))) { + setWidgetRGB(new Color(32, 25, 17)); + } else { + setWidgetRGB(new Color(41, 32, 22)); + } + setScriptCallOnMouseEntered(3030, new WidgetPointer(arg3), ivar7, "Ii"); + setScriptCallOnMouseExit(3035, ""); + if (strLength(svar1) > 0) { + ivar16 = add(getTextWidth(494, "Last known as: " + svar1), 8); + if (ivar16 > getWidgetActualWidth(new WidgetPointer(909,19))) { + svar3 = "Last known as:" + "
" + svar1; + } else { + svar3 = "Last known as: " + svar1; + } + setScriptCallOnMouseOver(2467, new WidgetPointer(-32768,3), -2147483643, svar3, -2147483647, -2147483646, new WidgetPointer(909,41), new WidgetPointer(909,32), new WidgetPointer(909,35), 494, "IisiiIIIf"); + } + cs2method1305(svar0); + if (ivar9 > 0) { + setWidgetContextMenuOption(1, "Message"); + setWidgetContextMenuOption(2, "Join"); + } else { + setWidgetContextMenuOption(3, "Message"); + setWidgetContextMenuOption(4, "Join"); + } + setWidgetContextMenuOption(10, "Delete"); + setScriptCallOnClickContextMenu(3039, -2147483644, ivar9, svar0, ivar7, "iisi"); + script_2994(arg1, ivar7, 14, 14, 5, add(ivar8, 1), -1, 0, 0, 0, 0); + if (stringMethod4107(svar1, "") != 0) { + setWidgetSprite(2313); + ivar13 = 20; + } else { + setWidgetSprite(-1); + ivar13 = 5; + } + svar2 = svar0; + script_2995(arg0, ivar7, 0, ivar11, ivar13, ivar8, 16777215, 494, 0, 1, 0, 1, svar2); + setWidgetSize(ivar13, ivar11, 1, 0); + cs2method1126(1); + if (((boolean)ivar9)) { + svar2 = "Offline"; + ivar14 = 16711680; + } else if (ivar9 == getWorldId()) { + ivar14 = 65280; + } else { + ivar14 = 16776960; + } + svar2 = cs2method3610(ivar7); + script_2995(arg2, ivar7, 0, ivar11, 5, ivar8, ivar14, 494, 0, 1, 0, 1, svar2); + setWidgetSize(5, ivar11, 1, 0); + cs2method1126(1); + ivar8 = add(ivar8, ivar11); + ivar7 = add(ivar7, 1); + } + ivar10 = add(divide(getWidgetActualHeight(new WidgetPointer(arg4)), ivar11), 1); + if (ivar10 > ivar6) { + while (ivar7 < ivar10) { + script_2996(arg3, ivar7, getWidgetActualWidth(new WidgetPointer(arg3)), ivar11, 0, ivar8, 0, 1, 0); + if (((boolean)mod(ivar7, 2))) { + setWidgetRGB(new Color(32, 25, 17)); + } else { + setWidgetRGB(new Color(41, 32, 22)); + } + ivar8 = add(ivar8, ivar11); + ivar7 = add(ivar7, 1); + } + ivar12 = getWidgetActualHeight(new WidgetPointer(arg4)); + } else { + ivar12 = ivar8; + } + if (ivar10 <= ivar6) { + ivar15 = cs2method2601(new WidgetPointer(909,41)); + setWidgetScrollMax(0, ivar12, new WidgetPointer(909,41)); + if (ivar15 > ivar12) { + ivar15 = ivar12; + } + script_72(59572271, 59572265, ivar15); + } else { + setWidgetScrollMax(0, 0, new WidgetPointer(909,41)); + cs2method2100(0, 0, new WidgetPointer(909,41)); + script_72(59572271, 59572265, 0); + } + } else { + if (((boolean)ivar6)) { + setWidgetText(new WidgetPointer(909,38), "Name"); + script_3038(arg3, "You have not added any friends to your list."); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(909,31)), getWidgetActualHeight(new WidgetPointer(909,36)), 0, 0, new WidgetPointer(909,31)); + } + } + return; +} diff --git a/dumps/scripts/303.cs2 b/dumps/scripts/303.cs2 new file mode 100644 index 0000000..3ce40fb --- /dev/null +++ b/dumps/scripts/303.cs2 @@ -0,0 +1,9 @@ +void script_303(int arg0,int arg1) { + playSoundEffect(2266, 1, 0); + if (((boolean)arg1)) { + cs2method5214(arg0); + } else { + cs2method5221(arg0); + } + return; +} diff --git a/dumps/scripts/3030.cs2 b/dumps/scripts/3030.cs2 new file mode 100644 index 0000000..5c35920 --- /dev/null +++ b/dumps/scripts/3030.cs2 @@ -0,0 +1,4 @@ +void script_3030(int arg0,int arg1) { + script_3032(arg0, arg1, 1); + return; +} diff --git a/dumps/scripts/3031.cs2 b/dumps/scripts/3031.cs2 new file mode 100644 index 0000000..fbba374 --- /dev/null +++ b/dumps/scripts/3031.cs2 @@ -0,0 +1,4 @@ +void script_3031(int arg0,int arg1) { + script_3032(arg0, arg1, 0); + return; +} diff --git a/dumps/scripts/3032.cs2 b/dumps/scripts/3032.cs2 new file mode 100644 index 0000000..c8ab106 --- /dev/null +++ b/dumps/scripts/3032.cs2 @@ -0,0 +1,21 @@ +void script_3032(int arg0,int arg1,int arg2) { + int ivar3; + ivar3 = -1; + if (((boolean)arg2)) { + ivar3 = 59572267; + } else { + if (((boolean)arg2)) { + ivar3 = 59572309; + } + } + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetIsHidden(false, new WidgetPointer(ivar3)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(ivar3)), getWidgetActualY(), 0, 0, new WidgetPointer(ivar3)); + } + if (((boolean)arg2)) { + script_2470(59572256, 59572259); + } else { + script_2470(59572304, 59572307); + } + return; +} diff --git a/dumps/scripts/3033.cs2 b/dumps/scripts/3033.cs2 new file mode 100644 index 0000000..76933dc --- /dev/null +++ b/dumps/scripts/3033.cs2 @@ -0,0 +1,4 @@ +void script_3033() { + script_2276(globalint_1199, globalint_1213, 61145360); + return; +} diff --git a/dumps/scripts/3034.cs2 b/dumps/scripts/3034.cs2 new file mode 100644 index 0000000..0b76075 --- /dev/null +++ b/dumps/scripts/3034.cs2 @@ -0,0 +1,4 @@ +void script_3034() { + script_2276(globalint_1199, globalint_1214, 61145361); + return; +} diff --git a/dumps/scripts/3035.cs2 b/dumps/scripts/3035.cs2 new file mode 100644 index 0000000..975ceaf --- /dev/null +++ b/dumps/scripts/3035.cs2 @@ -0,0 +1,5 @@ +void script_3035() { + setWidgetIsHidden(true, new WidgetPointer(909,43)); + script_2470(59572256, 59572259); + return; +} diff --git a/dumps/scripts/3036.cs2 b/dumps/scripts/3036.cs2 new file mode 100644 index 0000000..9880aee --- /dev/null +++ b/dumps/scripts/3036.cs2 @@ -0,0 +1,4 @@ +void script_3036() { + script_3037(); + return; +} diff --git a/dumps/scripts/3037.cs2 b/dumps/scripts/3037.cs2 new file mode 100644 index 0000000..66e3ed7 --- /dev/null +++ b/dumps/scripts/3037.cs2 @@ -0,0 +1,5 @@ +void script_3037() { + setWidgetIsHidden(true, new WidgetPointer(909,85)); + script_2470(59572304, 59572307); + return; +} diff --git a/dumps/scripts/3038.cs2 b/dumps/scripts/3038.cs2 new file mode 100644 index 0000000..7cf17ac --- /dev/null +++ b/dumps/scripts/3038.cs2 @@ -0,0 +1,5 @@ +void script_3038(int arg0,string arg1) { + script_2995(arg0, 0, 0, 0, 0, 0, 16777215, 494, 1, 1, 0, 1, arg1); + setWidgetSize(0, 0, 1, 1); + return; +} diff --git a/dumps/scripts/3039.cs2 b/dumps/scripts/3039.cs2 new file mode 100644 index 0000000..002ce18 --- /dev/null +++ b/dumps/scripts/3039.cs2 @@ -0,0 +1,21 @@ +void script_3039(int arg0,int arg1,int arg2,string arg3) { + switch (arg0) { + case 1: + if (cs2method6900()) { + script_3015(0, "Send message to " + arg3, "", arg3, ""); + } else { + messageType0("Users restricted to quick-chat cannot send messages from the Lobby."); + } + break; + case 2: + script_1182(arg1); + break; + case 3: + case 4: + messageType0("That player is currently offline."); + break; + case 10: + cs2method3606(strRemoveEntities(arg3)); + } + return; +} diff --git a/dumps/scripts/304.cs2 b/dumps/scripts/304.cs2 new file mode 100644 index 0000000..2057fa1 --- /dev/null +++ b/dumps/scripts/304.cs2 @@ -0,0 +1,23 @@ +void script_304(int arg0) { + int ivar1; + if (arg0 == -1) { + return; + } + playSoundEffect(2266, 1, 0); + ivar1 = getDungeonmap(arg0); + ivar1 = script_2785(ivar1); + if (ivar1 == -1) { + return; + } + script_2046(49479709); + globalstring_31 = ""; + script_308(49479705); + setWidgetText(new WidgetPointer(755,20), cs2method5207(ivar1)); + script_41(49479737); + cs2method5227(ivar1, arg0); + cs2method5214(arg0); + globalint_172 = cs2method5218(ivar1); + script_1372(); + script_307(); + return; +} diff --git a/dumps/scripts/3040.cs2 b/dumps/scripts/3040.cs2 new file mode 100644 index 0000000..15acfb9 --- /dev/null +++ b/dumps/scripts/3040.cs2 @@ -0,0 +1,4 @@ +void script_3040(int arg0,int arg1,int arg2,int arg3,int arg4) { + script_3041(arg0, arg1, arg2, arg3, arg4); + return; +} diff --git a/dumps/scripts/3041.cs2 b/dumps/scripts/3041.cs2 new file mode 100644 index 0000000..4f27cc2 --- /dev/null +++ b/dumps/scripts/3041.cs2 @@ -0,0 +1,125 @@ +void script_3041(int arg0,int arg1,int arg2,int arg3,int arg4) { + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + string svar0; + string svar1; + string svar2; + string svar3; + int stack_dump0; + opcStruct3622(0,2,0) structdump_1; + if (cs2method5428(arg2, -1)) { + setScriptCallOnGameloop(3040, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), "IIIII", new WidgetPointer(arg3)); + return; + } + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg3)); + deleteAllExtraChilds(new WidgetPointer(arg0)); + deleteAllExtraChilds(new WidgetPointer(arg1)); + deleteAllExtraChilds(new WidgetPointer(arg2)); + ivar5 = getIgnoreCount(); + ivar6 = 0; + ivar7 = 0; + svar0 = ""; + svar1 = ""; + svar2 = ""; + ivar8 = 0; + ivar9 = 0; + ivar10 = 15; + ivar11 = 0; + ivar12 = 5; + ivar13 = 0; + ivar14 = 0; + ivar15 = 0; + svar3 = ""; + if (ivar5 == -2) { + setWidgetText(new WidgetPointer(909,89), "Name"); + script_3038(arg2, "Loading Ignore List." + "
" + "
" + "Please wait."); + } else if (ivar5 == -1) { + setWidgetText(new WidgetPointer(909,89), "Name"); + script_3038(arg2, "Connecting to server." + "
" + "
" + "Please wait."); + } else if (ivar5 > 0) { + setWidgetText(new WidgetPointer(909,89), "Name (" + intToStr(ivar5) + "/100)"); + while (ivar6 < ivar5) { + stack_dump0 = ivar6; + structdump_1 = cs2method3622(stack_dump0); + svar1 = structdump_1.stringpart_1; + svar0 = structdump_1.stringpart_0; + script_2996(arg2, ivar6, getWidgetActualWidth(new WidgetPointer(arg2)), ivar10, 0, ivar7, 0, 1, 0); + if (((boolean)mod(ivar6, 2))) { + setWidgetRGB(new Color(32, 25, 17)); + } else { + setWidgetRGB(new Color(41, 32, 22)); + } + setScriptCallOnMouseEntered(3031, new WidgetPointer(arg2), ivar6, "Ii"); + setScriptCallOnMouseExit(3036, ""); + if (strLength(svar1) > 0) { + ivar15 = add(getTextWidth(494, "Last known as: " + svar1), 8); + if (ivar15 > getWidgetActualWidth(new WidgetPointer(909,76))) { + svar3 = "Last known as:" + "
" + svar1; + } else { + svar3 = "Last known as: " + svar1; + } + setScriptCallOnMouseOver(2467, new WidgetPointer(-32768,3), -2147483643, svar3, -2147483647, -2147483646, new WidgetPointer(909,78), new WidgetPointer(909,80), new WidgetPointer(909,83), 494, "IisiiIIIf"); + } + cs2method1305(svar0); + setWidgetContextMenuOption(1, "Delete"); + setScriptCallOnClickContextMenu(3042, -2147483644, svar0, "is"); + script_2994(arg1, ivar6, 14, 14, 5, add(ivar7, 1), -1, 0, 0, 0, 0); + if (stringMethod4107(svar1, "") != 0) { + setWidgetSprite(2313); + ivar12 = 20; + } else { + setWidgetSprite(-1); + ivar12 = 5; + } + svar2 = svar0; + script_2995(arg0, ivar6, 0, ivar10, ivar12, ivar7, 16777215, 494, 0, 1, 0, 1, svar2); + setWidgetSize(ivar12, ivar10, 1, 0); + cs2method1126(1); + ivar7 = add(ivar7, ivar10); + ivar6 = add(ivar6, 1); + } + ivar9 = add(divide(getWidgetActualHeight(new WidgetPointer(arg3)), ivar10), 1); + if (ivar9 > ivar5) { + while (ivar6 < ivar9) { + script_2996(arg2, ivar6, getWidgetActualWidth(new WidgetPointer(arg2)), ivar10, 0, ivar7, 0, 1, 0); + if (((boolean)mod(ivar6, 2))) { + setWidgetRGB(new Color(32, 25, 17)); + } else { + setWidgetRGB(new Color(41, 32, 22)); + } + ivar7 = add(ivar7, ivar10); + ivar6 = add(ivar6, 1); + } + ivar11 = getWidgetActualHeight(new WidgetPointer(arg3)); + } else { + ivar11 = ivar7; + } + if (ivar9 <= ivar5) { + ivar14 = cs2method2601(new WidgetPointer(909,78)); + setWidgetScrollMax(0, ivar11, new WidgetPointer(909,78)); + if (ivar14 > ivar11) { + ivar14 = ivar11; + } + script_72(59572303, 59572302, ivar14); + } else { + setWidgetScrollMax(0, 0, new WidgetPointer(909,78)); + cs2method2100(0, 0, new WidgetPointer(909,78)); + script_72(59572303, 59572302, 0); + } + } else { + if (((boolean)ivar5)) { + setWidgetText(new WidgetPointer(909,89), "Name"); + script_3038(arg2, "You are not ignoring any players."); + } + } + return; +} diff --git a/dumps/scripts/3042.cs2 b/dumps/scripts/3042.cs2 new file mode 100644 index 0000000..5c4124c --- /dev/null +++ b/dumps/scripts/3042.cs2 @@ -0,0 +1,7 @@ +void script_3042(int arg0,string arg1) { + if (((boolean)arg0)) { + cs2method3608(arg1); + script_3037(); + } + return; +} diff --git a/dumps/scripts/3043.cs2 b/dumps/scripts/3043.cs2 new file mode 100644 index 0000000..59ae116 --- /dev/null +++ b/dumps/scripts/3043.cs2 @@ -0,0 +1,5 @@ +void script_3043(int arg0) { + setScriptCallOnGameloop(3044, new WidgetPointer(arg0), "I", new WidgetPointer(arg0)); + script_3045(); + return; +} diff --git a/dumps/scripts/3044.cs2 b/dumps/scripts/3044.cs2 new file mode 100644 index 0000000..4347df8 --- /dev/null +++ b/dumps/scripts/3044.cs2 @@ -0,0 +1,8 @@ +void script_3044(int arg0) { + if (cs2method5005() == -1) { + return; + } + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + script_3045(); + return; +} diff --git a/dumps/scripts/3045.cs2 b/dumps/scripts/3045.cs2 new file mode 100644 index 0000000..683ec87 --- /dev/null +++ b/dumps/scripts/3045.cs2 @@ -0,0 +1,13 @@ +void script_3045() { + switch (cs2method5005()) { + case 0: + setWidgetText(new WidgetPointer(909,66), "Everybody"); + break; + case 1: + setWidgetText(new WidgetPointer(909,66), "Friends"); + break; + case 2: + setWidgetText(new WidgetPointer(909,66), "Nobody"); + } + return; +} diff --git a/dumps/scripts/3046.cs2 b/dumps/scripts/3046.cs2 new file mode 100644 index 0000000..c2d58e7 --- /dev/null +++ b/dumps/scripts/3046.cs2 @@ -0,0 +1,17 @@ +void script_3046(int arg0) { + if (arg0 > 1) { + script_3047(subtract(arg0, 2)); + } else { + switch (cs2method5005()) { + case 0: + script_3047(1); + break; + case 1: + script_3047(2); + break; + case 2: + script_3047(0); + } + } + return; +} diff --git a/dumps/scripts/3047.cs2 b/dumps/scripts/3047.cs2 new file mode 100644 index 0000000..76b5a2f --- /dev/null +++ b/dumps/scripts/3047.cs2 @@ -0,0 +1,10 @@ +void script_3047(int arg0) { + switch (arg0) { + case 0: + case 1: + case 2: + cs2method5001(cs2method5000(), arg0, cs2method5016()); + } + script_3045(); + return; +} diff --git a/dumps/scripts/3048.cs2 b/dumps/scripts/3048.cs2 new file mode 100644 index 0000000..227f80e --- /dev/null +++ b/dumps/scripts/3048.cs2 @@ -0,0 +1,4 @@ +void script_3048() { + script_3015(1, "Add friend", "", "", ""); + return; +} diff --git a/dumps/scripts/3049.cs2 b/dumps/scripts/3049.cs2 new file mode 100644 index 0000000..08224b5 --- /dev/null +++ b/dumps/scripts/3049.cs2 @@ -0,0 +1,4 @@ +void script_3049() { + script_3015(3, "Remove friend", "", "", ""); + return; +} diff --git a/dumps/scripts/305.cs2 b/dumps/scripts/305.cs2 new file mode 100644 index 0000000..a89624d --- /dev/null +++ b/dumps/scripts/305.cs2 @@ -0,0 +1,9 @@ +void script_305(int arg0) { + if (((boolean)arg0)) { + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(755,14)); + } else { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(755,14)); + } + setScriptCallOnGameloop(306, getClientCycle(), new WidgetPointer(-32768,3), "iI", new WidgetPointer(755,14)); + return; +} diff --git a/dumps/scripts/3050.cs2 b/dumps/scripts/3050.cs2 new file mode 100644 index 0000000..82fdb0c --- /dev/null +++ b/dumps/scripts/3050.cs2 @@ -0,0 +1,4 @@ +void script_3050() { + script_3015(2, "Add ignore", "", "", ""); + return; +} diff --git a/dumps/scripts/3051.cs2 b/dumps/scripts/3051.cs2 new file mode 100644 index 0000000..353f772 --- /dev/null +++ b/dumps/scripts/3051.cs2 @@ -0,0 +1,4 @@ +void script_3051() { + script_3015(4, "Remove ignore", "", "", ""); + return; +} diff --git a/dumps/scripts/3052.cs2 b/dumps/scripts/3052.cs2 new file mode 100644 index 0000000..54c0962 --- /dev/null +++ b/dumps/scripts/3052.cs2 @@ -0,0 +1,5 @@ +void script_3052(int arg0) { + setScriptCallOnFriendListChange(3053, new WidgetPointer(arg0), "I", new WidgetPointer(arg0)); + script_3054(arg0); + return; +} diff --git a/dumps/scripts/3053.cs2 b/dumps/scripts/3053.cs2 new file mode 100644 index 0000000..3c98591 --- /dev/null +++ b/dumps/scripts/3053.cs2 @@ -0,0 +1,4 @@ +void script_3053(int arg0) { + script_3054(arg0); + return; +} diff --git a/dumps/scripts/3054.cs2 b/dumps/scripts/3054.cs2 new file mode 100644 index 0000000..27e6859 --- /dev/null +++ b/dumps/scripts/3054.cs2 @@ -0,0 +1,95 @@ +void script_3054(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + string svar0; + string svar1; + string svar2; + if (cs2method5428(59572276, -1)) { + setScriptCallOnGameloop(3053, new WidgetPointer(arg0), "I", new WidgetPointer(arg0)); + return; + } + deleteAllExtraChilds(new WidgetPointer(909,52)); + svar0 = ""; + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + svar1 = ""; + svar2 = ""; + while (ivar2 < 100) { + ivar3 = cs2method5004(ivar2); + svar1 = cs2method5010(ivar2); + svar2 = cs2method5019(ivar2); + switch (ivar3) { + case 0: + case 4: + case 27: + case 26: + case 29: + case 28: + case 31: + case 30: + ivar1 = script_3055(ivar1, 0, ivar3, cs2method5003(ivar2), "", ""); + break; + case 3: + ivar1 = script_3055(ivar1, 1, ivar3, "From " + svar1 + ": " + svar0 + cs2method5003(ivar2), svar1, svar2); + globalstring_276 = svar2; + break; + case 5: + ivar1 = script_3055(ivar1, 0, ivar3, svar0 + cs2method5003(ivar2), svar1, svar2); + break; + case 6: + ivar1 = script_3055(ivar1, 1, ivar3, "To " + svar1 + ": " + svar0 + cs2method5003(ivar2), svar1, svar2); + break; + case 7: + ivar1 = script_3055(ivar1, 1, ivar3, "From " + svar1 + ": " + svar0 + cs2method5003(ivar2), svar1, svar2); + globalstring_276 = svar2; + break; + case 18: + ivar1 = script_3055(ivar1, 1, ivar3, "From " + svar1 + ": " + svar0 + cs2method5003(ivar2), svar1, svar2); + globalstring_276 = svar2; + break; + case 19: + ivar1 = script_3055(ivar1, 1, ivar3, "To " + svar1 + ": " + svar0 + cs2method5003(ivar2), svar1, svar2); + break; + case 115: + ivar1 = script_3055(ivar1, 0, ivar3, "" + cs2method5003(ivar2) + "", "", ""); + } + ivar2 = add(ivar2, 1); + } + ivar4 = divide(getWidgetActualHeight(new WidgetPointer(909,52)), 15); + ivar2 = 0; + ivar5 = 0; + if (ivar1 < ivar4) { + ivar5 = subtract(ivar4, ivar1); + while (ivar2 < ivar5) { + ivar1 = script_3055(ivar1, 0, 0, "", "", ""); + ivar2 = add(ivar2, 1); + } + } + ivar6 = 0; + ivar7 = 0; + while (ivar7 <= ivar1) { + if (setWidgetRegister(new WidgetPointer(909,52), ivar7)) { + ivar6 = add(ivar6, getWidgetActualHeight()); + } + ivar7 = add(ivar7, 1); + } + ivar8 = max(ivar6, multiply(ivar4, 15)); + if (ivar8 > getWidgetActualHeight(new WidgetPointer(909,52))) { + setWidgetScrollMax(0, ivar8, new WidgetPointer(909,52)); + script_72(59572277, 59572276, subtract(add(globalint_1122, getWidgetScrollMaxV(new WidgetPointer(909,52))), globalint_1123)); + } else { + setWidgetScrollMax(0, 0, new WidgetPointer(909,52)); + cs2method2100(0, 0, new WidgetPointer(909,52)); + script_72(59572277, 59572276, 0); + } + globalint_1122 = cs2method2601(new WidgetPointer(909,52)); + globalint_1123 = getWidgetScrollMaxV(new WidgetPointer(909,52)); + return; +} diff --git a/dumps/scripts/3055.cs2 b/dumps/scripts/3055.cs2 new file mode 100644 index 0000000..5139231 --- /dev/null +++ b/dumps/scripts/3055.cs2 @@ -0,0 +1,50 @@ +int script_3055(int arg0,int arg1,int arg2,string arg3,string arg4,string arg5) { + int ivar3; + int ivar4; + int ivar5; + int ivar6; + string svar3; + ivar3 = getWidgetActualWidth(new WidgetPointer(909,52)); + ivar4 = multiply(max(getLineCount(ivar3, 494, arg3), 1), 15); + createExtraChild(new WidgetPointer(909,52), 4, arg0); + setWidgetSize(0, ivar4, 1, 0); + setWidgetRGB(new Color(255, 255, 255)); + setWidgetFont(494); + setWidgetText(arg3); + setWidgetTextAlignment(0, 0, 15); + ivar5 = 0; + ivar6 = 0; + while (ivar6 < arg0) { + if (setWidgetRegister(new WidgetPointer(909,52), ivar6)) { + ivar5 = add(ivar5, getWidgetActualHeight()); + } + ivar6 = add(ivar6, 1); + } + setWidgetPosition(0, ivar5, 0, 2); + svar3 = ""; + if (((boolean)arg1)) { + cs2method1305(strRemoveEntities(arg4)); + setScriptCallOnClickContextMenu(3056, -2147483644, arg4, arg5, "iss"); + switch (arg2) { + case 3: + case 18: + case 6: + case 7: + svar3 = strRemoveEntities(arg5); + if (stringMethod4107(strRemoveEntities(cs2method5020()), svar3) != 0) { + if (isFriend(svar3) && cs2method3623(svar3)) { + setWidgetContextMenuOption(1, "Add friend"); + setWidgetContextMenuOption(2, "Add ignore"); + } else { + if (isFriend(svar3) && cs2method6900()) { + setWidgetContextMenuOption(3, "Message"); + } + } + if ((getClientRights() > 0) || (((int)hasMoreThen5Blackmarks()) > 0)) { + setWidgetContextMenuOption(5, "Report abuse"); + } + } + } + } + return add(arg0, 1); +} diff --git a/dumps/scripts/3056.cs2 b/dumps/scripts/3056.cs2 new file mode 100644 index 0000000..67f8e4f --- /dev/null +++ b/dumps/scripts/3056.cs2 @@ -0,0 +1,20 @@ +void script_3056(int arg0,string arg1,string arg2) { + switch (arg0) { + case 1: + if (isFriend(strRemoveEntities(arg2))) { + cs2method3605(strRemoveEntities(arg2)); + } + break; + case 2: + if (isFriend(strRemoveEntities(arg2))) { + cs2method3607(strRemoveEntities(arg2)); + } + break; + case 3: + script_3015(0, "Send message to " + arg1, "", arg2, ""); + break; + case 5: + script_3177(0, arg1); + } + return; +} diff --git a/dumps/scripts/3057.cs2 b/dumps/scripts/3057.cs2 new file mode 100644 index 0000000..744c1f6 --- /dev/null +++ b/dumps/scripts/3057.cs2 @@ -0,0 +1,4 @@ +void script_3057(int arg0,int arg1) { + script_1299(arg0, arg1); + return; +} diff --git a/dumps/scripts/3058.cs2 b/dumps/scripts/3058.cs2 new file mode 100644 index 0000000..92f5020 --- /dev/null +++ b/dumps/scripts/3058.cs2 @@ -0,0 +1,30 @@ +void script_3058() { + cs2func_script_3406_struct(3,0,0) structdump_0; + int stack_dump1; + int stack_dump2; + openInterface(59375801, 907); + script_2998(); + openInterface(59375802, 910); + script_3103(); + openInterface(59375803, 909); + script_3023(); + script_3052(59572273); + script_3043(59572290); + openInterface(59375805, 912); + script_3159(59768841); + script_3171(59768842); + openInterface(59375804, 589); + script_4554(38600715); + script_4565(38600716); + openInterface(59375806, 911); + script_3158(); + setScriptCallOnMessage(3405, new WidgetPointer(909,49), new WidgetPointer(912,10), new WidgetPointer(589,12), "III", new WidgetPointer(906,23)); + structdump_0 = script_3406(); + stack_dump1 = structdump_0.intpart_0; + stack_dump2 = structdump_0.intpart_1; + globalint_1510 = structdump_0.intpart_2; + stack_dump1 = stack_dump1; + globalint_1276 = stack_dump2; + globalint_1275 = stack_dump1; + return; +} diff --git a/dumps/scripts/3059.cs2 b/dumps/scripts/3059.cs2 new file mode 100644 index 0000000..550f4d0 --- /dev/null +++ b/dumps/scripts/3059.cs2 @@ -0,0 +1,4 @@ +void script_3059(int arg0) { + script_3060(arg0); + return; +} diff --git a/dumps/scripts/306.cs2 b/dumps/scripts/306.cs2 new file mode 100644 index 0000000..229d457 --- /dev/null +++ b/dumps/scripts/306.cs2 @@ -0,0 +1,8 @@ +void script_306(int arg0,int arg1) { + if (subtract(getClientCycle(), arg0) < 15) { + return; + } + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg1)); + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(arg1)); + return; +} diff --git a/dumps/scripts/3060.cs2 b/dumps/scripts/3060.cs2 new file mode 100644 index 0000000..16a2bb6 --- /dev/null +++ b/dumps/scripts/3060.cs2 @@ -0,0 +1,73 @@ +void script_3060(int arg0) { + int stack_dump0; + if (((int)cs2method_3408(105, 73, 941, arg0)) == -1) { + return; + } + if (isWidgetHidden(cs2method_3408(105, 73, 941, arg0))) { + return; + } + setWidgetIsHidden(true, cs2method_3408(105, 73, 941, 0)); + setWidgetIsHidden(true, cs2method_3408(105, 73, 941, 1)); + setWidgetIsHidden(true, cs2method_3408(105, 73, 941, 2)); + setWidgetIsHidden(true, cs2method_3408(105, 73, 941, 5)); + setWidgetIsHidden(true, cs2method_3408(105, 73, 941, 3)); + setWidgetIsHidden(true, cs2method_3408(105, 73, 941, 4)); + setWidgetRGB(new Color(235, 224, 188), new WidgetPointer(906,216)); + setWidgetRGB(new Color(235, 224, 188), new WidgetPointer(906,213)); + setWidgetRGB(new Color(235, 224, 188), new WidgetPointer(906,211)); + setWidgetRGB(new Color(235, 224, 188), new WidgetPointer(906,209)); + setWidgetRGB(new Color(235, 224, 188), new WidgetPointer(906,266)); + setWidgetRGB(new Color(235, 224, 188), new WidgetPointer(906,207)); + setWidgetSprite(4672, new WidgetPointer(906,215)); + setWidgetSprite(4672, new WidgetPointer(906,22)); + setWidgetSprite(4672, new WidgetPointer(906,21)); + setWidgetSprite(4672, new WidgetPointer(906,20)); + setWidgetSprite(4672, new WidgetPointer(906,265)); + setWidgetSprite(4672, new WidgetPointer(906,19)); + setScriptCallOnMouseEntered(45, new WidgetPointer(906,216), 16448250, "Ii", new WidgetPointer(906,199)); + setScriptCallOnMouseEntered(45, new WidgetPointer(906,213), 16448250, "Ii", new WidgetPointer(906,200)); + setScriptCallOnMouseEntered(45, new WidgetPointer(906,211), 16448250, "Ii", new WidgetPointer(906,201)); + setScriptCallOnMouseEntered(45, new WidgetPointer(906,209), 16448250, "Ii", new WidgetPointer(906,203)); + setScriptCallOnMouseEntered(45, new WidgetPointer(906,266), 16448250, "Ii", new WidgetPointer(906,202)); + setScriptCallOnMouseEntered(45, new WidgetPointer(906,207), 16448250, "Ii", new WidgetPointer(906,204)); + setScriptCallOnMouseExit(45, new WidgetPointer(906,216), 15458492, "Ii", new WidgetPointer(906,199)); + setScriptCallOnMouseExit(45, new WidgetPointer(906,213), 15458492, "Ii", new WidgetPointer(906,200)); + setScriptCallOnMouseExit(45, new WidgetPointer(906,211), 15458492, "Ii", new WidgetPointer(906,201)); + setScriptCallOnMouseExit(45, new WidgetPointer(906,209), 15458492, "Ii", new WidgetPointer(906,203)); + setScriptCallOnMouseExit(45, new WidgetPointer(906,266), 15458492, "Ii", new WidgetPointer(906,202)); + setScriptCallOnMouseExit(45, new WidgetPointer(906,207), 15458492, "Ii", new WidgetPointer(906,204)); + if (arg0 != 5) { + script_3161(0); + } + if (arg0 != 3) { + script_4556(0); + } + if (((boolean)arg0)) { + setWidgetPosition(0, 3, 1, 2, new WidgetPointer(906,28)); + setWidgetSize(655, 26, 0, 1, new WidgetPointer(906,27)); + stack_dump0 = 1; + /* + mgi.tools.jagdecs2.DecompilerException: Unknown special opcode:6509 + at mgi.tools.jagdecs2.FlowBlocksGenerator.analyzeSpecialCall(FlowBlocksGenerator.java:348) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:249) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + setWidgetPosition(0, 241, 1, 1, new WidgetPointer(906,28)); + setWidgetSize(655, 477, 0, 0, new WidgetPointer(906,27)); + stack_dump0 = 0; + /* + mgi.tools.jagdecs2.DecompilerException: Unknown special opcode:6509 + at mgi.tools.jagdecs2.FlowBlocksGenerator.analyzeSpecialCall(FlowBlocksGenerator.java:348) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:249) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ +} diff --git a/dumps/scripts/3061.cs2 b/dumps/scripts/3061.cs2 new file mode 100644 index 0000000..790a2eb --- /dev/null +++ b/dumps/scripts/3061.cs2 @@ -0,0 +1,4 @@ +void script_3061(int arg0) { + script_3062(arg0); + return; +} diff --git a/dumps/scripts/3062.cs2 b/dumps/scripts/3062.cs2 new file mode 100644 index 0000000..f1705ee --- /dev/null +++ b/dumps/scripts/3062.cs2 @@ -0,0 +1,45 @@ +void script_3062(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + if ((globalint_1100 == 42) || (globalint_1100 == 43)) { + return; + } + if (cs2method6500()) { + script_3064(0); + setScriptCallOnGameloop(3061, new WidgetPointer(arg0), "I", new WidgetPointer(arg0)); + return; + } + globalint_1322 = 0; + script_3064(1); + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + script_3097(); + globalint_1100 = -1; + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + ivar4 = 0; + if (((boolean)script_2727()) && ((boolean)globalint_547)) { + script_3076(59375720); + script_3074(59375718); + script_3026(59375720); + script_3025(59375718); + setWidgetIsHidden(false, new WidgetPointer(906,43)); + playMusicEffect(349, 0); + script_3412(59375713, 59375714); + ivar3 = getWidgetActualWidth(new WidgetPointer(906,98)); + ivar4 = getWidgetActualWidth(new WidgetPointer(906,98)); + ivar1 = max(337, add(getTextWidth(496, getWidgetText(new WidgetPointer(906,97))), 30)); + ivar4 = max(152, multiply(getLineCount(ivar3, 496, getWidgetText(new WidgetPointer(906,98))), 16)); + ivar2 = max(243, add(ivar4, 91)); + setWidgetSize(ivar3, ivar4, 0, 0, new WidgetPointer(906,98)); + setWidgetSize(ivar1, ivar2, 0, 0, new WidgetPointer(906,95)); + return; + } + globalint_200 = 0; + script_3064(0); + cs2method5612(0); + setScriptCallOnGameloop(3063, new WidgetPointer(arg0), getWorldId(), "Ii", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/3063.cs2 b/dumps/scripts/3063.cs2 new file mode 100644 index 0000000..e36e1c9 --- /dev/null +++ b/dumps/scripts/3063.cs2 @@ -0,0 +1,337 @@ +void script_3063(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + string svar0; + string svar1; + string svar2; + string svar3; + string svar4; + string svar5; + string svar6; + string svar7; + string svar8; + int stack_dump0; + opcStruct6506(4,3,0) structdump_1; + ivar2 = getGameloginRC(); + if (ivar2 == -3) { + script_3064(0); + script_3093(ivar2, 0, 1, -1, 0, -1, 0, "Logging In - Please Wait", "", "", "", ""); + globalint_1100 = -3; + return; + } + if (globalint_1100 == -3) { + script_3097(); + } + ivar3 = 0; + svar0 = ""; + ivar4 = 0; + svar1 = ""; + ivar5 = 0; + svar2 = ""; + ivar6 = 0; + ivar7 = 0; + svar3 = ""; + if (ivar2 == 21) { + globalint_1100 = 21; + script_3064(0); + if (((boolean)globalint_200)) { + globalint_200 = getWorldswitchTimer(); + } + globalint_200 = subtract(globalint_200, 1); + if (globalint_200 <= 0) { + if (cs2method6500()) { + globalint_200 = 1; + return; + } + if (arg1 > 0) { + stack_dump0 = arg1; + structdump_1 = cs2method6506(stack_dump0); + svar3 = structdump_1.stringpart_2; + ivar7 = structdump_1.intpart_3; + ivar6 = structdump_1.intpart_2; + svar2 = structdump_1.stringpart_1; + ivar5 = structdump_1.intpart_1; + svar1 = structdump_1.stringpart_0; + ivar4 = structdump_1.intpart_0; + if (setWorldHost(arg1, svar3)) { + ivar4 = 0; + } + } + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + script_3062(arg0); + return; + } + ivar3 = divide(globalint_200, 50); + if (((boolean)ivar3)) { + svar0 = "You have only just left another world. Your profile will be transferred in" + "
" + "1 second."; + } else { + svar0 = "You have only just left another world. Your profile will be transferred in" + "
" + intToStr(ivar3) + " seconds."; + } + if (isWidgetHidden(new WidgetPointer(906,29))) { + script_3093(ivar2, 0, 0, 2611, 1, 1, 0, svar0, "Abort Login", "Abort Login", "", ""); + } else { + script_1871(svar0); + } + return; + } + if (ivar2 == 42) { + setWidgetIsHidden(false, new WidgetPointer(906,40)); + setWidgetText(new WidgetPointer(906,5), intToStr(arg1)); + setWidgetText(new WidgetPointer(906,6), intToStr(getReturncode42ExtraData())); + if (globalint_1100 != 42) { + script_3093(ivar2, 1, 0, 2611, 0, 0, 1, "World " + intToStr(arg1) + " is currently full." + "
" + "You have been added to the" + "
" + "queue for this world." + "
" + "You can track your progress in the" + "
" + "queue from lower left corner of this" + "
" + "screen.", "", "", "OK", "OK"); + } + globalint_1100 = 42; + return; + } + if (ivar2 == 43) { + setWidgetText(new WidgetPointer(906,5), intToStr(arg1)); + setWidgetText(new WidgetPointer(906,6), intToStr(getReturncode42ExtraData())); + globalint_1100 = 43; + return; + } + setWidgetIsHidden(true, new WidgetPointer(906,40)); + if (arg0 == 59375639) { + script_1299(1, 1); + } + script_3097(); + script_3064(1); + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + svar4 = ""; + ivar8 = 1; + ivar9 = 0; + ivar10 = 2608; + ivar11 = 0; + ivar12 = 0; + svar5 = ""; + svar6 = ""; + ivar13 = 1; + svar7 = "Back"; + svar8 = "Back"; + ivar14 = getDetailedRC(); + ivar15 = getReturncodeExtraData(); + switch (ivar2) { + case -2: + script_3097(); + return; + case 29: + switch (ivar14) { + case 0: + svar4 = "You must have a Combat Level of at least 20 (not including Summoning) to enter a PvP world."; + break; + case 1: + svar4 = "You are currently carrying lent items and cannot enter a PvP world."; + break; + case 2: + svar4 = "You must be standing in the Wilderness or Edgeville to enter this bounty world."; + break; + case 3: + svar4 = "You must have a total skill level of 1,000 or greater to enter this world."; + break; + case 5: + svar4 = "You must have a total skill level of 1,500 or greater to enter this world."; + break; + case 4: + svar4 = "You must move to a safe area before you can log in to a PvP or bounty world."; + break; + default: + svar4 = "Unexpected server response. Please try using a different world."; + } + break; + case 46: + svar4 = "This instance is marked for deletion/rebuild. Please try using a different world."; + break; + case 45: + switch (ivar15) { + case 0: + switch (ivar14) { + case 0: + svar4 = "You must be near the TzHaar Fight Pits entrance to enter a global match."; + break; + default: + svar4 = "Unable to log in. Please try using a different world."; + } + break; + case 1: + switch (ivar14) { + case 1: + svar4 = "There was an error connecting to your meeting room. Please try again."; + break; + case 2: + svar4 = "You need a higher rank to enter that private tent."; + break; + case 3: + svar4 = "You need an invitation to enter that private room."; + break; + default: + svar4 = "Unable to log in. Please try using a different world."; + } + break; + default: + svar4 = "Unable to log in. Please try using a different world."; + } + break; + case -5: + svar4 = "Connection timed out. Please try using a different world."; + break; + case -4: + svar4 = "Error connecting to server."; + break; + case -1: + svar4 = "No response from server. Please try using a different world."; + break; + case 5: + svar4 = "Your account has not logged out from its last session. Try again in a few minutes."; + break; + case 7: + svar4 = "This world is full. Please use a different world."; + break; + case 8: + svar4 = "Unable to connect: login server offline."; + break; + case 9: + svar4 = "Login limit exceeded: too many connections from your address."; + break; + case 10: + svar4 = "Unable to connect: bad session id."; + break; + case 13: + svar4 = "Could not complete login. Please try using a different world."; + break; + case 16: + svar4 = "Too many incorrect logins from your address. Please wait 5 minutes before trying again."; + break; + case 17: + svar4 = "You are standing in a members-only area. To play on this world, move to a free area first."; + break; + case 20: + svar4 = "Invalid loginserver requested. Please try using a different world."; + break; + case 22: + svar4 = "Malformed login packet. Please try again."; + break; + case 23: + svar4 = "No reply from login server. Please wait a minute and try again."; + break; + case 24: + svar4 = "Error loading your profile. Please contact customer support."; + break; + case 25: + svar4 = "Unexpected loginserver response. Please try using a different world."; + break; + case 26: + svar4 = "This computer's address has been blocked, as it was used to break our rules."; + break; + case 27: + svar4 = "Service unavailable."; + break; + case 3: + svar4 = "Your password has been updated. Please leave the lobby and log in again."; + break; + case 36: + svar4 = "Unable to connect: authentication server offline."; + break; + case 37: + svar4 = "Your account is currently inaccessible. Please try again in a few minutes."; + break; + case 39: + svar4 = "The instance you tried to join no longer exists. Please try using a different world."; + break; + case 41: + svar4 = "The instance you tried to join is full. Please try back later or try using a different world."; + break; + case 44: + svar4 = "Our systems are currently unavailable. Please try again in a few minutes."; + break; + case 35: + svar4 = "Your session has expired. Please click 'Back' in your browser to renew it."; + svar7 = "Close"; + svar8 = "Close"; + break; + case 14: + ivar8 = 0; + ivar10 = 2610; + svar4 = "The server is being updated. Please wait a few minutes and try again."; + break; + case 6: + ivar8 = 0; + ivar10 = 2610; + svar4 = "RuneScape has been updated! Please reload this page."; + break; + case 4: + svar4 = "Your account has been disabled. Check your Message Centre for details."; + ivar11 = 1; + svar5 = "Message Centre"; + svar6 = "Message Centre"; + break; + case 11: + svar4 = "Your password is an extremely common choice, and is not secure. You must change it before you can log in."; + ivar11 = 1; + svar5 = "Change Password"; + svar6 = "Change Password"; + break; + case 18: + ivar10 = 2612; + svar4 = "Your account has been locked. If you have not received an account recovery email, please select 'Recover Account'."; + ivar11 = 1; + svar5 = "Recover Account"; + svar6 = "Recover Account"; + break; + case 31: + svar4 = "You must change your account's display name before you can log in."; + ivar11 = 1; + svar5 = "Change Display Name"; + svar6 = "Change Display Name"; + break; + case 30: + svar4 = "This is not a member's account. Please choose a 'free' world from the website to play on this account."; + ivar11 = 1; + svar5 = "Subscribe"; + svar6 = "Subscribe"; + break; + case 19: + svar4 = "Fullscreen is currently a members-only feature. To log in, either exit fullscreen via the options menu or use a member's account."; + ivar11 = 1; + svar5 = "Subscribe"; + svar6 = "Subscribe"; + break; + case 12: + ivar8 = 0; + ivar10 = 2607; + svar4 = "You need a member's account to log in to this world. Please subscribe or use a different world."; + ivar11 = 1; + svar5 = "Subscribe"; + svar6 = "Subscribe"; + break; + case 40: + ivar8 = 0; + ivar10 = 2607; + svar4 = "You need a member's account to log in to this instance. Please subscribe or use a different world."; + ivar11 = 1; + svar5 = "Subscribe"; + svar6 = "Subscribe"; + break; + case 32: + svar4 = "Your account has negative membership credit. Please log into the billing system to add credit to your account."; + ivar11 = 1; + svar5 = "Add Credit"; + svar6 = "Add Credit"; + break; + default: + svar4 = "Unexpected server response. Please try using a different world."; + } + script_3093(ivar2, ivar8, ivar9, ivar10, ivar11, ivar12, ivar13, svar4, svar5, svar6, svar7, svar8); + return; +} diff --git a/dumps/scripts/3064.cs2 b/dumps/scripts/3064.cs2 new file mode 100644 index 0000000..bf5fa88 --- /dev/null +++ b/dumps/scripts/3064.cs2 @@ -0,0 +1,13 @@ +void script_3064(int arg0) { + if (((boolean)arg0)) { + setWidgetText(new WidgetPointer(906,184), "Play"); + setWidgetContextMenuOption(1, new WidgetPointer(906,171), "Play"); + setScriptCallOnClickContextMenu(3061, new WidgetPointer(906,171), "I", new WidgetPointer(906,171)); + } else { + setWidgetText(new WidgetPointer(906,184), "Entering game..."); + setWidgetNoOptions(new WidgetPointer(906,171)); + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(906,171)); + } + script_3065(arg0); + return; +} diff --git a/dumps/scripts/3065.cs2 b/dumps/scripts/3065.cs2 new file mode 100644 index 0000000..19e080e --- /dev/null +++ b/dumps/scripts/3065.cs2 @@ -0,0 +1,5 @@ +void script_3065(int arg0) { + script_3066(globalint_998, 1, 59375792, 59375794, arg0); + script_3066(globalint_999, 2, 59375793, 59375795, arg0); + return; +} diff --git a/dumps/scripts/3066.cs2 b/dumps/scripts/3066.cs2 new file mode 100644 index 0000000..2614f82 --- /dev/null +++ b/dumps/scripts/3066.cs2 @@ -0,0 +1,23 @@ +void script_3066(int arg0,int arg1,int arg2,int arg3,int arg4) { + if (arg0 > 0) { + setWidgetSprite(4661, new WidgetPointer(arg2)); + setWidgetText(new WidgetPointer(arg3), intToStr(arg0)); + if (((boolean)arg4)) { + setWidgetContextMenuOption(1, new WidgetPointer(arg2), "Click Here To Play"); + setScriptCallOnClickContextMenu(3067, arg1, "i", new WidgetPointer(arg2)); + } else { + setWidgetNoOptions(new WidgetPointer(arg2)); + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(arg2)); + } + setScriptCallOnMouseEntered(3068, new WidgetPointer(arg2), "I", new WidgetPointer(arg2)); + setScriptCallOnMouseExit(3069, new WidgetPointer(arg2), "I", new WidgetPointer(arg2)); + } else { + setWidgetSprite(4660, new WidgetPointer(arg2)); + setWidgetText(new WidgetPointer(arg3), ""); + setScriptCallOnMouseEntered(-1, "", new WidgetPointer(arg2)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg2)); + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(arg2)); + setWidgetNoOptions(new WidgetPointer(arg2)); + } + return; +} diff --git a/dumps/scripts/3067.cs2 b/dumps/scripts/3067.cs2 new file mode 100644 index 0000000..d8e8357 --- /dev/null +++ b/dumps/scripts/3067.cs2 @@ -0,0 +1,83 @@ +void script_3067(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + string svar0; + string svar1; + string svar2; + worldData(5,3,0) structdump_0; + worldData(5,3,0) structdump_1; + if (cs2method6500()) { + setScriptCallOnGameloop(3067, arg0, "i", new WidgetPointer(906,172)); + return; + } + setScriptCallOnGameloop(-1, "", new WidgetPointer(906,172)); + ivar1 = 0; + ivar2 = 0; + svar0 = ""; + ivar3 = 0; + svar1 = ""; + ivar4 = 0; + ivar5 = 0; + svar2 = ""; + ivar6 = -1; + if (((boolean)arg0)) { + ivar6 = globalint_998; + } else if (arg0 == 2) { + ivar6 = globalint_999; + } else { + return; + } + structdump_0 = getFirstWorldData(); + svar2 = structdump_0.stringpart_2; + ivar5 = structdump_0.intpart_4; + ivar4 = structdump_0.intpart_3; + svar1 = structdump_0.stringpart_1; + ivar3 = structdump_0.intpart_2; + svar0 = structdump_0.stringpart_0; + ivar2 = structdump_0.intpart_1; + ivar1 = structdump_0.intpart_0; + ivar7 = 0; + while ((ivar1 != -1) && ((boolean)ivar7)) { + if (ivar1 == ivar6) { + ivar7 = 1; + } else { + structdump_1 = getNextWorldData(); + svar2 = structdump_1.stringpart_2; + ivar5 = structdump_1.intpart_4; + ivar4 = structdump_1.intpart_3; + svar1 = structdump_1.stringpart_1; + ivar3 = structdump_1.intpart_2; + svar0 = structdump_1.stringpart_0; + ivar2 = structdump_1.intpart_1; + ivar1 = structdump_1.intpart_0; + } + } + if (((boolean)arg0)) { + script_3382(59375792); + } else { + if (arg0 == 2) { + script_3382(59375793); + } + } + if (ivar1 > 0) { + if (getWorldId() != ivar1) { + if (setWorldHost(ivar1, svar2)) { + globalint_547 = 0; + script_3062(59375787); + } else { + script_3064(1); + script_3093(-5, 1, 0, 2608, 0, -1, 1, "Could not connect you to the chosen world. Please choose another.", "", "", "Back", "Back"); + } + } else { + script_3062(59375787); + } + } else { + script_3093(-5, 1, 0, 2608, 0, -1, 1, "World " + intToStr(ivar6) + " is running in a different language or is unavailable.", "", "", "Back", "Back"); + } + return; +} diff --git a/dumps/scripts/3068.cs2 b/dumps/scripts/3068.cs2 new file mode 100644 index 0000000..06c0b95 --- /dev/null +++ b/dumps/scripts/3068.cs2 @@ -0,0 +1,5 @@ +void script_3068(int arg0) { + setWidgetSprite(4662, new WidgetPointer(arg0)); + script_3083(arg0, -1, "Click here to login to your favourite world"); + return; +} diff --git a/dumps/scripts/3069.cs2 b/dumps/scripts/3069.cs2 new file mode 100644 index 0000000..b20b830 --- /dev/null +++ b/dumps/scripts/3069.cs2 @@ -0,0 +1,4 @@ +void script_3069(int arg0) { + script_3382(arg0); + return; +} diff --git a/dumps/scripts/307.cs2 b/dumps/scripts/307.cs2 new file mode 100644 index 0000000..dc11080 --- /dev/null +++ b/dumps/scripts/307.cs2 @@ -0,0 +1,8 @@ +void script_307() { + if (((boolean)bitconfig_6176)) { + cs2method5231(950, 1); + } else { + cs2method5231(950, 0); + } + return; +} diff --git a/dumps/scripts/3070.cs2 b/dumps/scripts/3070.cs2 new file mode 100644 index 0000000..3f3baf3 --- /dev/null +++ b/dumps/scripts/3070.cs2 @@ -0,0 +1,11 @@ +?? script_3070() { + /* + mgi.tools.jagdecs2.DecompilerException: No documentation for:CALL_CS2 2422 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:178) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ +} diff --git a/dumps/scripts/3071.cs2 b/dumps/scripts/3071.cs2 new file mode 100644 index 0000000..46001ec --- /dev/null +++ b/dumps/scripts/3071.cs2 @@ -0,0 +1,4 @@ +void script_3071(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + script_3072(arg0, arg1, arg2, arg3, arg4, arg5); + return; +} diff --git a/dumps/scripts/3072.cs2 b/dumps/scripts/3072.cs2 new file mode 100644 index 0000000..655f94e --- /dev/null +++ b/dumps/scripts/3072.cs2 @@ -0,0 +1,12 @@ +void script_3072(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + if (arg0 != -1) { + setWidgetSprite(arg1, new WidgetPointer(arg0)); + } + if (arg2 != -1) { + setWidgetSprite(arg3, new WidgetPointer(arg2)); + } + if (arg4 != -1) { + setWidgetSprite(arg5, new WidgetPointer(arg4)); + } + return; +} diff --git a/dumps/scripts/3073.cs2 b/dumps/scripts/3073.cs2 new file mode 100644 index 0000000..b7be04d --- /dev/null +++ b/dumps/scripts/3073.cs2 @@ -0,0 +1,4 @@ +void script_3073(int arg0) { + script_3074(arg0); + return; +} diff --git a/dumps/scripts/3074.cs2 b/dumps/scripts/3074.cs2 new file mode 100644 index 0000000..cbba1f9 --- /dev/null +++ b/dumps/scripts/3074.cs2 @@ -0,0 +1,4 @@ +void script_3074(int arg0) { + script_3077(arg0, 2679, 2680, 2681, 2682); + return; +} diff --git a/dumps/scripts/3075.cs2 b/dumps/scripts/3075.cs2 new file mode 100644 index 0000000..a287ff7 --- /dev/null +++ b/dumps/scripts/3075.cs2 @@ -0,0 +1,4 @@ +void script_3075(int arg0) { + script_3076(arg0); + return; +} diff --git a/dumps/scripts/3076.cs2 b/dumps/scripts/3076.cs2 new file mode 100644 index 0000000..db37901 --- /dev/null +++ b/dumps/scripts/3076.cs2 @@ -0,0 +1,4 @@ +void script_3076(int arg0) { + script_3077(arg0, 2683, 2684, 2685, 2686); + return; +} diff --git a/dumps/scripts/3077.cs2 b/dumps/scripts/3077.cs2 new file mode 100644 index 0000000..49a71e6 --- /dev/null +++ b/dumps/scripts/3077.cs2 @@ -0,0 +1,18 @@ +void script_3077(int arg0,int arg1,int arg2,int arg3,int arg4) { + script_2994(arg0, 0, 16, 32, 0, 0, arg1, 0, 0, 0, 0); + script_2994(arg0, 1, 32, 32, 16, 0, arg2, 0, 0, 0, 0); + setWidgetSize(32, 32, 1, 0); + script_2994(arg0, 2, 16, 32, 0, 0, arg1, 1, 0, 0, 0); + setWidgetPosition(0, 0, 2, 0); + script_2994(arg0, 3, 16, 32, 0, 0, arg3, 0, 0, 0, 0); + setWidgetHidden(1); + script_2994(arg0, 4, 32, 32, 16, 0, arg4, 0, 0, 0, 0); + setWidgetSize(32, 32, 1, 0); + setWidgetHidden(1); + script_2994(arg0, 5, 16, 32, 0, 0, arg3, 1, 0, 0, 0); + setWidgetPosition(0, 0, 2, 0); + setWidgetHidden(1); + setScriptCallOnMouseEntered(3078, new WidgetPointer(arg0), "I", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(3080, new WidgetPointer(arg0), "I", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/3078.cs2 b/dumps/scripts/3078.cs2 new file mode 100644 index 0000000..d2dc9a7 --- /dev/null +++ b/dumps/scripts/3078.cs2 @@ -0,0 +1,4 @@ +void script_3078(int arg0) { + script_3079(arg0); + return; +} diff --git a/dumps/scripts/3079.cs2 b/dumps/scripts/3079.cs2 new file mode 100644 index 0000000..c97a7fa --- /dev/null +++ b/dumps/scripts/3079.cs2 @@ -0,0 +1,12 @@ +void script_3079(int arg0) { + if (setWidgetRegister(new WidgetPointer(arg0), 3)) { + setWidgetHidden(0); + } + if (setWidgetRegister(new WidgetPointer(arg0), 4)) { + setWidgetHidden(0); + } + if (setWidgetRegister(new WidgetPointer(arg0), 5)) { + setWidgetHidden(0); + } + return; +} diff --git a/dumps/scripts/308.cs2 b/dumps/scripts/308.cs2 new file mode 100644 index 0000000..90db0f8 --- /dev/null +++ b/dumps/scripts/308.cs2 @@ -0,0 +1,6 @@ +void script_308(int arg0) { + setScriptCallOnKeyPress(1382, -2147483640, false, new WidgetPointer(arg0), -1, "izIc", new WidgetPointer(arg0)); + setWidgetText(new WidgetPointer(arg0), "Search the map by typing here."); + setWidgetTextAlignment(0, 1, 0, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/3080.cs2 b/dumps/scripts/3080.cs2 new file mode 100644 index 0000000..981eb16 --- /dev/null +++ b/dumps/scripts/3080.cs2 @@ -0,0 +1,4 @@ +void script_3080(int arg0) { + script_3081(arg0); + return; +} diff --git a/dumps/scripts/3081.cs2 b/dumps/scripts/3081.cs2 new file mode 100644 index 0000000..2b13d9b --- /dev/null +++ b/dumps/scripts/3081.cs2 @@ -0,0 +1,12 @@ +void script_3081(int arg0) { + if (setWidgetRegister(new WidgetPointer(arg0), 3)) { + setWidgetHidden(1); + } + if (setWidgetRegister(new WidgetPointer(arg0), 4)) { + setWidgetHidden(1); + } + if (setWidgetRegister(new WidgetPointer(arg0), 5)) { + setWidgetHidden(1); + } + return; +} diff --git a/dumps/scripts/3082.cs2 b/dumps/scripts/3082.cs2 new file mode 100644 index 0000000..82ec299 --- /dev/null +++ b/dumps/scripts/3082.cs2 @@ -0,0 +1,4 @@ +void script_3082(int arg0,int arg1,string arg2) { + script_3083(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/3083.cs2 b/dumps/scripts/3083.cs2 new file mode 100644 index 0000000..1e8f089 --- /dev/null +++ b/dumps/scripts/3083.cs2 @@ -0,0 +1,10 @@ +void script_3083(int arg0,int arg1,string arg2) { + if (arg1 < 0) { + setScriptCallOnMouseOver(3084, new WidgetPointer(arg0), arg1, add(getClientCycle(), 25), arg2, -2147483647, -2147483646, "Iiisii", new WidgetPointer(arg0)); + } else { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setScriptCallOnMouseOver(3084, new WidgetPointer(arg0), arg1, add(getClientCycle(), 25), arg2, -2147483647, -2147483646, "Iiisii"); + } + } + return; +} diff --git a/dumps/scripts/3084.cs2 b/dumps/scripts/3084.cs2 new file mode 100644 index 0000000..09a7307 --- /dev/null +++ b/dumps/scripts/3084.cs2 @@ -0,0 +1,4 @@ +void script_3084(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5) { + script_3085(arg0, arg1, arg2, arg3, arg4, arg5); + return; +} diff --git a/dumps/scripts/3085.cs2 b/dumps/scripts/3085.cs2 new file mode 100644 index 0000000..abf11f6 --- /dev/null +++ b/dumps/scripts/3085.cs2 @@ -0,0 +1,44 @@ +void script_3085(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5) { + int ivar5; + int ivar6; + int ivar7; + int ivar8; + ivar5 = 0; + ivar6 = 0; + ivar7 = 0; + ivar8 = arg0; + if (getClientCycle() > arg2) { + setWidgetText(new WidgetPointer(906,223), arg5); + setWidgetSize(add(multiply(getWidgetActualX(new WidgetPointer(906,223)), 2), getTextWidth(495, arg5)), getWidgetActualHeight(new WidgetPointer(906,220)), 0, 0, new WidgetPointer(906,220)); + while (((boolean)ivar7)) { + if (ivar8 == 59375643) { + ivar7 = 1; + } + ivar5 = add(ivar5, getWidgetActualX(new WidgetPointer(ivar8))); + ivar6 = add(ivar6, getWidgetActualY(new WidgetPointer(ivar8))); + ivar8 = getWidgetParentId(new WidgetPointer(ivar8)); + } + if ((arg1 > -1) && setWidgetRegister(new WidgetPointer(arg0), arg1)) { + ivar5 = add(ivar5, getWidgetActualX()); + ivar6 = add(ivar6, getWidgetActualY()); + } + ivar5 = add(add(ivar5, arg3), 3); + ivar6 = subtract(subtract(add(ivar6, arg4), 3), getWidgetActualHeight(new WidgetPointer(906,220))); + if (add(ivar5, getWidgetActualWidth(new WidgetPointer(906,220))) > getWidgetActualWidth(new WidgetPointer(906,23))) { + ivar5 = subtract(getWidgetActualWidth(new WidgetPointer(906,23)), getWidgetActualWidth(new WidgetPointer(906,220))); + } + if (ivar6 < 0) { + ivar6 = 0; + } + setWidgetPosition(ivar5, ivar6, 0, 0, new WidgetPointer(906,220)); + setWidgetIsHidden(false, new WidgetPointer(906,220)); + if (arg1 < 0) { + setScriptCallOnMouseOver(-1, "", new WidgetPointer(arg0)); + } else { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setScriptCallOnMouseOver(-1, ""); + } + } + } + return; +} diff --git a/dumps/scripts/3086.cs2 b/dumps/scripts/3086.cs2 new file mode 100644 index 0000000..282da04 --- /dev/null +++ b/dumps/scripts/3086.cs2 @@ -0,0 +1,4 @@ +void script_3086(int arg0,int arg1) { + script_3087(arg0, arg1); + return; +} diff --git a/dumps/scripts/3087.cs2 b/dumps/scripts/3087.cs2 new file mode 100644 index 0000000..5b97c86 --- /dev/null +++ b/dumps/scripts/3087.cs2 @@ -0,0 +1,11 @@ +void script_3087(int arg0,int arg1) { + setWidgetIsHidden(true, new WidgetPointer(906,220)); + if (arg1 < 0) { + setScriptCallOnMouseOver(-1, "", new WidgetPointer(arg0)); + } else { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setScriptCallOnMouseOver(-1, ""); + } + } + return; +} diff --git a/dumps/scripts/3088.cs2 b/dumps/scripts/3088.cs2 new file mode 100644 index 0000000..69c8fe2 --- /dev/null +++ b/dumps/scripts/3088.cs2 @@ -0,0 +1,6 @@ +void script_3088(int arg0,string arg1,string arg2) { + if ((stringMethod4107(arg1, "") != 0) && (stringMethod4107(arg2, "") != 0)) { + cs2method5400(arg0, arg1, arg2); + } + return; +} diff --git a/dumps/scripts/3089.cs2 b/dumps/scripts/3089.cs2 new file mode 100644 index 0000000..c6c98f4 --- /dev/null +++ b/dumps/scripts/3089.cs2 @@ -0,0 +1,6 @@ +void script_3089(int arg0,string arg1,string arg2) { + if ((stringMethod4107(arg1, "") != 0) && (stringMethod4107(arg2, "") != 0)) { + cs2method5421(arg0, "loginapplet/loginapplet.ws?ssl=1&expired=0&mod=" + arg1 + "&dest=" + arg2); + } + return; +} diff --git a/dumps/scripts/309.cs2 b/dumps/scripts/309.cs2 new file mode 100644 index 0000000..0961a3b --- /dev/null +++ b/dumps/scripts/309.cs2 @@ -0,0 +1,26 @@ +void script_309(int arg0,int arg1,int arg2) { + int ivar3; + ivar3 = 0; + if ((globalint_623 != -1) && (getDungeonmap(globalint_623) == arg0)) { + ivar3 = script_292(globalint_624, arg1, arg2, ivar3); + } + if ((globalint_625 != -1) && (getDungeonmap(globalint_625) == arg0)) { + ivar3 = script_292(globalint_626, arg1, arg2, ivar3); + } + if ((globalint_627 != -1) && (getDungeonmap(globalint_627) == arg0)) { + ivar3 = script_292(globalint_628, arg1, arg2, ivar3); + } + if ((globalint_629 != -1) && (getDungeonmap(globalint_629) == arg0)) { + ivar3 = script_292(globalint_630, arg1, arg2, ivar3); + } + if ((standart_config_1159 != -1) && (getDungeonmap(standart_config_1159) == arg0)) { + ivar3 = script_292(972, arg1, arg2, ivar3); + } + if ((globalint_940 != -1) && (getDungeonmap(globalint_940) == arg0)) { + ivar3 = script_292(globalint_941, arg1, arg2, ivar3); + } + if ((globalint_674 != -1) && (getDungeonmap(globalint_674) == arg0)) { + ivar3 = script_292(280, arg1, arg2, ivar3); + } + return; +} diff --git a/dumps/scripts/3090.cs2 b/dumps/scripts/3090.cs2 new file mode 100644 index 0000000..bb20d4c --- /dev/null +++ b/dumps/scripts/3090.cs2 @@ -0,0 +1,4 @@ +void script_3090() { + setWidgetIsHidden(false, new WidgetPointer(906,42)); + return; +} diff --git a/dumps/scripts/3091.cs2 b/dumps/scripts/3091.cs2 new file mode 100644 index 0000000..696cd38 --- /dev/null +++ b/dumps/scripts/3091.cs2 @@ -0,0 +1,4 @@ +void script_3091(int arg0) { + script_3092(arg0); + return; +} diff --git a/dumps/scripts/3092.cs2 b/dumps/scripts/3092.cs2 new file mode 100644 index 0000000..7a54215 --- /dev/null +++ b/dumps/scripts/3092.cs2 @@ -0,0 +1,8 @@ +void script_3092(int arg0) { + globalint_547 = arg0; + setWidgetIsHidden(true, new WidgetPointer(906,43)); + if (((boolean)globalint_547)) { + script_3062(59375787); + } + return; +} diff --git a/dumps/scripts/3093.cs2 b/dumps/scripts/3093.cs2 new file mode 100644 index 0000000..b70bf20 --- /dev/null +++ b/dumps/scripts/3093.cs2 @@ -0,0 +1,4 @@ +void script_3093(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,string arg7,string arg8,string arg9,string arg10,string arg11) { + script_2779(arg0, arg1, arg2, arg3, arg4, arg5, arg6, 250, arg7, arg8, arg9, arg10, arg11); + return; +} diff --git a/dumps/scripts/3094.cs2 b/dumps/scripts/3094.cs2 new file mode 100644 index 0000000..8f83dfe --- /dev/null +++ b/dumps/scripts/3094.cs2 @@ -0,0 +1,44 @@ +void script_3094() { + int ivar0; + ivar0 = getGameloginRC(); + if ((ivar0 != -3) && ((boolean)globalint_1322)) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(906,234)); + return; + } + if (((boolean)globalint_1322) && (ivar0 == -3)) { + globalint_1322 = 0; + } + if (getClientCycle() < globalint_1092) { + return; + } + globalint_1092 = add(getClientCycle(), 5); + switch (getWidgetSpriteId(new WidgetPointer(906,234))) { + case 4107: + setWidgetSprite(4108, new WidgetPointer(906,234)); + break; + case 4108: + setWidgetSprite(4109, new WidgetPointer(906,234)); + break; + case 4109: + setWidgetSprite(4110, new WidgetPointer(906,234)); + break; + case 4110: + setWidgetSprite(4111, new WidgetPointer(906,234)); + break; + case 4111: + setWidgetSprite(4112, new WidgetPointer(906,234)); + break; + case 4112: + setWidgetSprite(4113, new WidgetPointer(906,234)); + break; + case 4113: + setWidgetSprite(4114, new WidgetPointer(906,234)); + break; + case 4114: + setWidgetSprite(4107, new WidgetPointer(906,234)); + break; + default: + setWidgetSprite(4107, new WidgetPointer(906,234)); + } + return; +} diff --git a/dumps/scripts/3095.cs2 b/dumps/scripts/3095.cs2 new file mode 100644 index 0000000..c8475d1 --- /dev/null +++ b/dumps/scripts/3095.cs2 @@ -0,0 +1,47 @@ +void script_3095(int arg0,int arg1,int arg2) { + string svar0; + string svar1; + svar0 = ""; + svar1 = ""; + switch (arg2) { + case 4: + svar0 = "ticketing"; + svar1 = "inbox.ws"; + setScriptCallOnClickContextMenu(3088, svar0, svar1, 1, "ss1", new WidgetPointer(arg0)); + break; + case 11: + svar0 = "password_history"; + svar1 = "password.ws"; + setScriptCallOnClickContextMenu(3088, svar0, svar1, 1, "ss1", new WidgetPointer(arg0)); + break; + case 18: + svar0 = "accountappeal"; + svar1 = "lockchoice.ws"; + setScriptCallOnClickContextMenu(3089, svar0, svar1, 1, "ss1", new WidgetPointer(arg0)); + break; + case 31: + svar0 = "displaynames"; + svar1 = "name.ws"; + setScriptCallOnClickContextMenu(3088, svar0, svar1, 1, "ss1", new WidgetPointer(arg0)); + break; + case 19: + case 32: + case -2000: + case -3000: + case 40: + case 12: + case 30: + svar0 = "dob"; + svar1 = "set_members_dob.ws"; + setScriptCallOnClickContextMenu(3088, svar0, svar1, 1, "ss1", new WidgetPointer(arg0)); + break; + case 21: + setScriptCallOnMousePressed(1872, "", new WidgetPointer(arg0)); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(arg1)); + return; + default: + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(arg0)); + } + setScriptCallOnClickContextMenu(3096, "", new WidgetPointer(arg1)); + return; +} diff --git a/dumps/scripts/3096.cs2 b/dumps/scripts/3096.cs2 new file mode 100644 index 0000000..a3a13ce --- /dev/null +++ b/dumps/scripts/3096.cs2 @@ -0,0 +1,4 @@ +void script_3096() { + script_3097(); + return; +} diff --git a/dumps/scripts/3097.cs2 b/dumps/scripts/3097.cs2 new file mode 100644 index 0000000..98281f4 --- /dev/null +++ b/dumps/scripts/3097.cs2 @@ -0,0 +1,24 @@ +void script_3097() { + setWidgetNoOptions(new WidgetPointer(906,236)); + setWidgetNoOptions(new WidgetPointer(906,242)); + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(906,236)); + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(906,242)); + setScriptCallOnMouseEntered(-1, "", new WidgetPointer(906,242)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(906,242)); + setScriptCallOnMouseEntered(-1, "", new WidgetPointer(906,236)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(906,236)); + setWidgetPosition(6, 5, 0, 2, new WidgetPointer(906,236)); + setWidgetPosition(6, 5, 0, 2, new WidgetPointer(906,242)); + setWidgetText(new WidgetPointer(906,241), ""); + setWidgetText(new WidgetPointer(906,247), ""); + setWidgetIsHidden(true, new WidgetPointer(906,236)); + setWidgetIsHidden(true, new WidgetPointer(906,242)); + setWidgetText(new WidgetPointer(906,235), ""); + globalint_1092 = 0; + setWidgetSprite(-1, new WidgetPointer(906,234)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(906,234)); + setScriptCallOnKeyPress(-1, "", new WidgetPointer(906,44)); + setWidgetIsHidden(true, new WidgetPointer(906,44)); + setWidgetIsHidden(true, new WidgetPointer(906,29)); + return; +} diff --git a/dumps/scripts/3098.cs2 b/dumps/scripts/3098.cs2 new file mode 100644 index 0000000..dc7ed5e --- /dev/null +++ b/dumps/scripts/3098.cs2 @@ -0,0 +1,19 @@ +void script_3098(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5,string arg6) { + int ivar5; + int ivar6; + int ivar7; + ivar5 = 4044; + ivar6 = 4044; + ivar7 = 4046; + setScriptCallOnMouseExit(3071, new WidgetPointer(arg1), ivar5, new WidgetPointer(arg2), ivar7, new WidgetPointer(arg3), ivar6, "IdIdId", new WidgetPointer(arg0)); + setWidgetSprite(ivar5, new WidgetPointer(arg1)); + setWidgetSprite(ivar7, new WidgetPointer(arg2)); + setWidgetSprite(ivar6, new WidgetPointer(arg3)); + ivar5 = 4045; + ivar6 = 4045; + ivar7 = 4047; + setScriptCallOnMouseEntered(3071, new WidgetPointer(arg1), ivar5, new WidgetPointer(arg2), ivar7, new WidgetPointer(arg3), ivar6, "IdIdId", new WidgetPointer(arg0)); + setWidgetText(new WidgetPointer(906,241), arg5); + setWidgetContextMenuOption(1, new WidgetPointer(906,236), arg6); + return; +} diff --git a/dumps/scripts/3099.cs2 b/dumps/scripts/3099.cs2 new file mode 100644 index 0000000..6def8e0 --- /dev/null +++ b/dumps/scripts/3099.cs2 @@ -0,0 +1,19 @@ +void script_3099(int arg0,int arg1,int arg2,int arg3,string arg4,string arg5) { + int ivar4; + int ivar5; + int ivar6; + ivar4 = 4044; + ivar5 = 4044; + ivar6 = 4046; + setScriptCallOnMouseExit(3071, new WidgetPointer(arg1), ivar4, new WidgetPointer(arg2), ivar6, new WidgetPointer(arg3), ivar5, "IdIdId", new WidgetPointer(arg0)); + setWidgetSprite(ivar4, new WidgetPointer(arg1)); + setWidgetSprite(ivar6, new WidgetPointer(arg2)); + setWidgetSprite(ivar5, new WidgetPointer(arg3)); + ivar4 = 4045; + ivar6 = 4047; + ivar5 = 4045; + setScriptCallOnMouseEntered(3071, new WidgetPointer(arg1), ivar4, new WidgetPointer(arg2), ivar6, new WidgetPointer(arg3), ivar5, "IdIdId", new WidgetPointer(arg0)); + setWidgetText(new WidgetPointer(906,247), arg4); + setWidgetContextMenuOption(1, new WidgetPointer(906,242), arg5); + return; +} diff --git a/dumps/scripts/31.cs2 b/dumps/scripts/31.cs2 new file mode 100644 index 0000000..14b058f --- /dev/null +++ b/dumps/scripts/31.cs2 @@ -0,0 +1,74 @@ +void script_31(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7) { + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + ivar8 = getWidgetScrollMaxV(new WidgetPointer(arg1)); + ivar9 = getWidgetActualHeight(new WidgetPointer(arg0)); + ivar10 = subtract(ivar9, 32); + ivar11 = 0; + if (ivar8 > 0) { + ivar11 = multiplyDivide(ivar9, ivar8, ivar10); + } else { + ivar11 = ivar10; + } + ivar11 = max(ivar11, 10); + ivar12 = cs2method2601(new WidgetPointer(arg1)); + ivar13 = 0; + ivar14 = 0; + if (ivar12 > 0) { + ivar13 = subtract(ivar8, getWidgetActualHeight(new WidgetPointer(arg1))); + if (((boolean)ivar13)) { + ivar13 = 1; + } + if (ivar12 > ivar13) { + cs2method2100(0, ivar13, new WidgetPointer(arg1)); + ivar12 = ivar13; + } + ivar14 = multiplyDivide(ivar12, ivar13, subtract(ivar10, ivar11)); + ivar14 = min(max(ivar14, 0), subtract(ivar10, ivar11)); + } + createExtraChild(new WidgetPointer(arg0), 5, 0); + setWidgetPosition(0, 16, 0, 0); + setWidgetSize(16, 32, 0, 1); + setWidgetSprite(arg2); + cs2method1107(1); + setScriptCallOnMousePressed(34, new WidgetPointer(arg0), new WidgetPointer(arg1), -2147483646, "IIi"); + createExtraChild(new WidgetPointer(arg0), 5, 1); + setWidgetPosition(0, add(16, ivar14), 0, 0); + setWidgetSprite(arg4); + cs2method1107(1); + cs2method1301(arg0, 0); + cs2method1302(1); + setWidgetSize(16, ivar11, 0, 0); + setScriptCallOnMouseDragged(35, new WidgetPointer(arg0), new WidgetPointer(arg1), -2147483646, 0, "IIi1"); + setScriptCallOnMouseDragReleased(35, new WidgetPointer(arg0), new WidgetPointer(arg1), -2147483646, 1, "IIi1"); + createExtraChild(new WidgetPointer(arg0), 5, 2); + setWidgetPosition(0, add(16, ivar14), 0, 0); + setWidgetSize(16, 5, 0, 0); + setWidgetSprite(arg3); + cs2method1107(0); + createExtraChild(new WidgetPointer(arg0), 5, 3); + setWidgetPosition(0, subtract(add(add(16, ivar14), ivar11), 5), 0, 0); + setWidgetSize(16, 5, 0, 0); + setWidgetSprite(arg5); + cs2method1107(0); + createExtraChild(new WidgetPointer(arg0), 5, 4); + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(16, 16, 0, 0); + setWidgetSprite(arg6); + cs2method1107(0); + setScriptCallOnMouseDraggedOver(32, new WidgetPointer(arg0), new WidgetPointer(arg1), "II"); + createExtraChild(new WidgetPointer(arg0), 5, 5); + setWidgetPosition(0, 0, 0, 2); + setWidgetSize(16, 16, 0, 0); + setWidgetSprite(arg7); + cs2method1107(0); + setScriptCallOnMouseDraggedOver(33, new WidgetPointer(arg0), new WidgetPointer(arg1), "II"); + setScriptCallOnMouseScroll(36, new WidgetPointer(arg0), new WidgetPointer(arg1), -2147483646, "IIi", new WidgetPointer(arg0)); + setScriptCallOnMouseScroll(36, new WidgetPointer(arg0), new WidgetPointer(arg1), -2147483646, "IIi", new WidgetPointer(arg1)); + return; +} diff --git a/dumps/scripts/310.cs2 b/dumps/scripts/310.cs2 new file mode 100644 index 0000000..61c80ba --- /dev/null +++ b/dumps/scripts/310.cs2 @@ -0,0 +1,15 @@ +void script_310(int arg0,int arg1,string arg2) { + int ivar2; + int ivar3; + int stack_dump0; + ivar2 = 0; + ivar3 = 0; + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + stack_dump0 = add(add(getWidgetActualX(), getWidgetActualHeight()), 1); + ivar3 = add(add(getWidgetActualY(), getWidgetActualHeight()), 1); + ivar2 = stack_dump0; + ivar3 = subtract(ivar3, cs2method2601(new WidgetPointer(arg0))); + script_312(ivar2, ivar3, arg2); + } + return; +} diff --git a/dumps/scripts/3100.cs2 b/dumps/scripts/3100.cs2 new file mode 100644 index 0000000..0b373f2 --- /dev/null +++ b/dumps/scripts/3100.cs2 @@ -0,0 +1,16 @@ +void script_3100(int arg0) { + int ivar1; + ivar1 = getGameloginRC(); + if (ivar1 == -3) { + return; + } + if ((ivar1 == 21) && (arg0 == 13)) { + script_1873(); + return; + } + if (arg0 == 13) { + script_3097(); + return; + } + return; +} diff --git a/dumps/scripts/3101.cs2 b/dumps/scripts/3101.cs2 new file mode 100644 index 0000000..602da25 --- /dev/null +++ b/dumps/scripts/3101.cs2 @@ -0,0 +1,4 @@ +void script_3101() { + script_3102(); + return; +} diff --git a/dumps/scripts/3102.cs2 b/dumps/scripts/3102.cs2 new file mode 100644 index 0000000..507aadf --- /dev/null +++ b/dumps/scripts/3102.cs2 @@ -0,0 +1,39 @@ +void script_3102() { + script_3104(59637767); + script_3105(59637765); + script_3107(59637770); + script_3107(59637771); + script_3108(59637814); + script_3108(59637791); + script_3108(59637811); + script_3108(59637808); + script_3108(59637804); + if (getLanguage() != 0) { + setWidgetText(new WidgetPointer(910,51), "Language"); + } + script_3109(59637786); + script_3109(59637779); + script_3111(59637796); + script_3111(59637784); + script_3110(59637816); + script_3110(59637817); + script_3110(59637818); + script_3110(59637819); + script_3110(59637821); + script_3155(59637813); + script_3155(59637810); + setWidgetIsHidden(false, new WidgetPointer(910,75)); + setWidgetIsHidden(false, new WidgetPointer(910,34)); + setWidgetIsHidden(false, new WidgetPointer(910,60)); + setWidgetIsHidden(false, new WidgetPointer(910,84)); + setWidgetIsHidden(false, new WidgetPointer(910,42)); + setWidgetPosition(110, 0, 2, 0, new WidgetPointer(910,33)); + setWidgetPosition(94, 0, 2, 0, new WidgetPointer(910,74)); + setWidgetPosition(173, 0, 2, 0, new WidgetPointer(910,59)); + setWidgetPosition(157, 0, 2, 0, new WidgetPointer(910,83)); + setWidgetPosition(173, 0, 2, 0, new WidgetPointer(910,41)); + setWidgetSize(330, 2, 1, 1, new WidgetPointer(910,32)); + setWidgetSize(313, 0, 1, 1, new WidgetPointer(910,72)); + script_3110(59637820); + return; +} diff --git a/dumps/scripts/3103.cs2 b/dumps/scripts/3103.cs2 new file mode 100644 index 0000000..7065450 --- /dev/null +++ b/dumps/scripts/3103.cs2 @@ -0,0 +1,17 @@ +void script_3103() { + script_3102(); + script_3113(); + script_3125(59637815, 1, 0, "Descending world number", "Ascending world number"); + script_3125(59637790, 3, 2, "Descending player count", "Ascending player count"); + script_3125(59637812, 5, 4, "Descending activity", "Ascending activity"); + script_3125(59637809, 9, 8, "Descending type", "Ascending type"); + script_3125(59637807, 7, 6, "Descending LootShare", "Ascending LootShare"); + script_3125(59637805, 11, 10, "Descending ping", "Ascending ping"); + script_3116(); + if (((boolean)cs2method5420())) { + script_3143(0, "Please choose a game world from the list." + "
" + "This will cause the game applet to reload."); + } else { + script_3143(0, "Please choose a game world from the list."); + } + return; +} diff --git a/dumps/scripts/3104.cs2 b/dumps/scripts/3104.cs2 new file mode 100644 index 0000000..96098b5 --- /dev/null +++ b/dumps/scripts/3104.cs2 @@ -0,0 +1,4 @@ +void script_3104(int arg0) { + setWidgetRGB(new Color(235, 224, 188), new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/3105.cs2 b/dumps/scripts/3105.cs2 new file mode 100644 index 0000000..7cec87f --- /dev/null +++ b/dumps/scripts/3105.cs2 @@ -0,0 +1,4 @@ +void script_3105(int arg0) { + setWidgetRGB(new Color(235, 224, 188), new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/3106.cs2 b/dumps/scripts/3106.cs2 new file mode 100644 index 0000000..17fe212 --- /dev/null +++ b/dumps/scripts/3106.cs2 @@ -0,0 +1,4 @@ +void script_3106(int arg0) { + setWidgetRGB(new Color(250, 250, 250), new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/3107.cs2 b/dumps/scripts/3107.cs2 new file mode 100644 index 0000000..f3f3033 --- /dev/null +++ b/dumps/scripts/3107.cs2 @@ -0,0 +1,4 @@ +void script_3107(int arg0) { + setWidgetRGB(new Color(235, 224, 188), new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/3108.cs2 b/dumps/scripts/3108.cs2 new file mode 100644 index 0000000..c804996 --- /dev/null +++ b/dumps/scripts/3108.cs2 @@ -0,0 +1,4 @@ +void script_3108(int arg0) { + setWidgetRGB(new Color(235, 224, 188), new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/3109.cs2 b/dumps/scripts/3109.cs2 new file mode 100644 index 0000000..e1ae133 --- /dev/null +++ b/dumps/scripts/3109.cs2 @@ -0,0 +1,4 @@ +void script_3109(int arg0) { + setWidgetRGB(new Color(56, 46, 34), new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/311.cs2 b/dumps/scripts/311.cs2 new file mode 100644 index 0000000..25d3673 --- /dev/null +++ b/dumps/scripts/311.cs2 @@ -0,0 +1,8 @@ +void script_311(int arg0,int arg1,string arg2) { + if (((boolean)bitconfig_6177)) { + deleteAllExtraChilds(new WidgetPointer(755,57)); + return; + } + script_312(add(arg0, 3), add(arg1, 3), arg2); + return; +} diff --git a/dumps/scripts/3110.cs2 b/dumps/scripts/3110.cs2 new file mode 100644 index 0000000..9984091 --- /dev/null +++ b/dumps/scripts/3110.cs2 @@ -0,0 +1,4 @@ +void script_3110(int arg0) { + setWidgetRGB(new Color(69, 55, 24), new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/3111.cs2 b/dumps/scripts/3111.cs2 new file mode 100644 index 0000000..cd29c6a --- /dev/null +++ b/dumps/scripts/3111.cs2 @@ -0,0 +1,4 @@ +void script_3111(int arg0) { + setWidgetRGB(new Color(14, 11, 9), new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/3112.cs2 b/dumps/scripts/3112.cs2 new file mode 100644 index 0000000..585c257 --- /dev/null +++ b/dumps/scripts/3112.cs2 @@ -0,0 +1,4 @@ +void script_3112() { + script_3113(); + return; +} diff --git a/dumps/scripts/3113.cs2 b/dumps/scripts/3113.cs2 new file mode 100644 index 0000000..4a47d02 --- /dev/null +++ b/dumps/scripts/3113.cs2 @@ -0,0 +1,4 @@ +void script_3113() { + setScriptCallOnGameloop(3115, "", new WidgetPointer(910,0)); + return; +} diff --git a/dumps/scripts/3114.cs2 b/dumps/scripts/3114.cs2 new file mode 100644 index 0000000..c2b1458 --- /dev/null +++ b/dumps/scripts/3114.cs2 @@ -0,0 +1,6 @@ +void script_3114(int arg0) { + if (getClientCycle() > arg0) { + script_3113(); + } + return; +} diff --git a/dumps/scripts/3115.cs2 b/dumps/scripts/3115.cs2 new file mode 100644 index 0000000..51a8b23 --- /dev/null +++ b/dumps/scripts/3115.cs2 @@ -0,0 +1,427 @@ +void script_3115() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + int ivar22; + int ivar23; + int ivar24; + int ivar25; + int ivar26; + int ivar27; + int ivar28; + int ivar29; + int ivar30; + int ivar31; + int ivar32; + int ivar33; + int ivar34; + int ivar35; + int ivar36; + int ivar37; + int ivar38; + int ivar39; + int ivar40; + int ivar41; + string svar0; + string svar1; + string svar2; + string svar3; + string svar4; + string svar5; + string svar6; + worldData(5,3,0) structdump_0; + worldData(5,3,0) structdump_1; + worldData(5,3,0) structdump_2; + int stack_dump3; + int stack_dump4; + int stack_dump5; + int stack_dump6; + int stack_dump7; + string stack_dump8; + string stack_dump9; + cs2func_script_3117_struct(6,3,0) structdump_10; + worldData(5,3,0) structdump_11; + ivar0 = script_1851(); + ivar1 = script_1852(); + if ((ivar1 == ivar0) && (ivar1 != 0)) { + ivar1 = 0; + script_1856(0); + } + switch (ivar0) { + case 4: + ivar0 = add(ivar0, 2); + break; + case 5: + ivar0 = add(ivar0, 2); + break; + case 6: + ivar0 = add(ivar0, 2); + break; + case 7: + ivar0 = add(ivar0, 2); + break; + case 8: + ivar0 = add(ivar0, 6); + break; + case 9: + ivar0 = add(ivar0, 6); + break; + case 10: + ivar0 = add(ivar0, 6); + break; + case 11: + ivar0 = add(ivar0, 6); + } + switch (ivar1) { + case 4: + ivar1 = add(ivar1, 2); + break; + case 5: + ivar1 = add(ivar1, 2); + break; + case 6: + ivar1 = add(ivar1, 2); + break; + case 7: + ivar1 = add(ivar1, 2); + break; + case 8: + ivar1 = add(ivar1, 6); + break; + case 9: + ivar1 = add(ivar1, 6); + break; + case 10: + ivar1 = add(ivar1, 6); + break; + case 11: + ivar1 = add(ivar1, 6); + } + cs2method6507(divide(ivar0, 2), script_734(mod(ivar0, 2)), divide(ivar1, 2), script_734(mod(ivar1, 2))); + ivar2 = 0; + if (cs2method6500()) { + return; + } + setScriptCallOnGameloop(3114, add(getClientCycle(), 500), "i", new WidgetPointer(910,0)); + ivar3 = 0; + if (globalint_998 > 0) { + ivar3 = getWidgetActualHeight(new WidgetPointer(910,21)); + } + if (globalint_999 > 0) { + ivar3 = add(ivar3, getWidgetActualHeight(new WidgetPointer(910,22))); + } + if (((boolean)ivar3)) { + setWidgetIsHidden(true, new WidgetPointer(910,24)); + setWidgetIsHidden(true, new WidgetPointer(910,18)); + setWidgetIsHidden(true, new WidgetPointer(910,23)); + } else { + setWidgetSize(getWidgetActualWidth(new WidgetPointer(910,23)), ivar3, 0, 0, new WidgetPointer(910,23)); + setWidgetIsHidden(false, new WidgetPointer(910,24)); + setWidgetIsHidden(false, new WidgetPointer(910,18)); + setWidgetIsHidden(false, new WidgetPointer(910,23)); + ivar3 = add(ivar3, getWidgetActualHeight(new WidgetPointer(910,18))); + setWidgetPosition(0, ivar3, 0, 0, new WidgetPointer(910,24)); + ivar3 = add(ivar3, getWidgetActualHeight(new WidgetPointer(910,24))); + } + setWidgetPosition(0, ivar3, 0, 0, new WidgetPointer(910,25)); + ivar3 = add(ivar3, getWidgetActualHeight(new WidgetPointer(910,25))); + setWidgetSize(16, ivar3, 1, 1, new WidgetPointer(910,62)); + setWidgetPosition(0, ivar3, 0, 0, new WidgetPointer(910,62)); + setWidgetSize(16, ivar3, 0, 1, new WidgetPointer(910,86)); + setWidgetPosition(0, ivar3, 2, 0, new WidgetPointer(910,86)); + ivar4 = 59637824; + ivar5 = 59637828; + ivar6 = 59637829; + ivar7 = 59637830; + ivar8 = 59637831; + ivar9 = 59637832; + ivar10 = 59637833; + ivar11 = 59637834; + ivar12 = 59637835; + ivar13 = 59637836; + ivar14 = 59637837; + ivar15 = 59637838; + ivar16 = 59637846; + deleteAllExtraChilds(new WidgetPointer(ivar4)); + deleteAllExtraChilds(new WidgetPointer(ivar5)); + deleteAllExtraChilds(new WidgetPointer(ivar6)); + deleteAllExtraChilds(new WidgetPointer(ivar7)); + deleteAllExtraChilds(new WidgetPointer(ivar8)); + deleteAllExtraChilds(new WidgetPointer(ivar9)); + deleteAllExtraChilds(new WidgetPointer(ivar10)); + deleteAllExtraChilds(new WidgetPointer(ivar11)); + deleteAllExtraChilds(new WidgetPointer(ivar12)); + deleteAllExtraChilds(new WidgetPointer(ivar13)); + deleteAllExtraChilds(new WidgetPointer(ivar14)); + deleteAllExtraChilds(new WidgetPointer(ivar15)); + ivar17 = 0; + ivar18 = 0; + svar0 = ""; + ivar19 = 0; + svar1 = ""; + ivar20 = 0; + ivar21 = 0; + ivar22 = -1; + ivar23 = -1; + ivar24 = -1; + ivar25 = -1; + ivar26 = 0; + ivar27 = 0; + svar2 = ""; + svar3 = ""; + ivar28 = -1; + ivar29 = -1; + ivar30 = 0; + ivar31 = 0; + ivar32 = 0; + ivar33 = 0; + ivar34 = 0; + svar4 = ""; + svar5 = ""; + ivar35 = -1; + ivar36 = -1; + structdump_0 = getFirstWorldData(); + svar2 = structdump_0.stringpart_2; + ivar21 = structdump_0.intpart_4; + ivar20 = structdump_0.intpart_3; + svar1 = structdump_0.stringpart_1; + ivar19 = structdump_0.intpart_2; + svar0 = structdump_0.stringpart_0; + ivar18 = structdump_0.intpart_1; + ivar17 = structdump_0.intpart_0; + if (ivar17 == -1) { + script_3143(1, "Unable to load list."); + setWidgetText(new WidgetPointer(910,1), "The world list could not be loaded." + "
" + "
" + "Please accept our apologies for the" + "
" + "inconvenience, and try again later."); + return; + } + ivar37 = 0; + ivar38 = 0; + ivar39 = 0; + svar6 = ""; + ivar40 = 0; + ivar41 = 0; + ivar2 = 0; + while (((boolean)ivar2)) { + if (ivar17 == -1) { + ivar2 = 1; + } else if ((ivar17 >= 170) && (ivar20 < 0)) { + structdump_1 = getNextWorldData(); + svar2 = structdump_1.stringpart_2; + ivar21 = structdump_1.intpart_4; + ivar20 = structdump_1.intpart_3; + svar1 = structdump_1.stringpart_1; + ivar19 = structdump_1.intpart_2; + svar0 = structdump_1.stringpart_0; + ivar18 = structdump_1.intpart_1; + ivar17 = structdump_1.intpart_0; + } else if (isBitFlagged(ivar18, 12)) { + structdump_2 = getNextWorldData(); + svar2 = structdump_2.stringpart_2; + ivar21 = structdump_2.intpart_4; + ivar20 = structdump_2.intpart_3; + svar1 = structdump_2.stringpart_1; + ivar19 = structdump_2.intpart_2; + svar0 = structdump_2.stringpart_0; + ivar18 = structdump_2.intpart_1; + ivar17 = structdump_2.intpart_0; + } else { + stack_dump3 = ivar17; + stack_dump4 = ivar18; + stack_dump5 = ivar37; + stack_dump6 = ivar20; + stack_dump7 = ivar19; + stack_dump8 = svar0; + stack_dump9 = svar1; + structdump_10 = script_3117(stack_dump3, stack_dump4, stack_dump5, stack_dump6, stack_dump7, stack_dump8, stack_dump9); + svar5 = structdump_10.stringpart_2; + svar4 = structdump_10.stringpart_1; + ivar25 = structdump_10.intpart_5; + ivar26 = structdump_10.intpart_4; + ivar29 = structdump_10.intpart_3; + ivar27 = structdump_10.intpart_2; + ivar22 = structdump_10.intpart_1; + svar3 = structdump_10.stringpart_0; + ivar28 = structdump_10.intpart_0; + if (ivar17 == globalint_998) { + ivar40 = 1; + } else { + if (ivar17 == globalint_999) { + ivar41 = 1; + } + } + script_2996(ivar4, ivar37, getWidgetActualWidth(new WidgetPointer(ivar4)), 20, 0, ivar38, ivar26, 1, 0); + script_2994(ivar5, ivar37, 13, 12, 0, add(ivar38, 4), ivar25, 0, 0, 0, 0); + setWidgetPosition(0, add(ivar38, 4), 1, 0); + script_2994(ivar7, ivar37, 19, 18, 2, add(ivar38, 1), ivar22, 0, 0, 0, 0); + script_2995(ivar6, ivar37, subtract(getWidgetActualWidth(new WidgetPointer(ivar6)), 25), 20, 25, ivar38, ivar27, 494, 0, 1, 0, 1, intToStr(ivar17)); + script_2995(ivar8, ivar37, subtract(getWidgetActualWidth(new WidgetPointer(ivar8)), 6), 20, 3, ivar38, ivar27, 494, 0, 1, 0, 1, svar5); + script_2994(ivar10, ivar37, 24, 12, 4, add(ivar38, 4), ivar28, 0, 0, 0, 0); + script_2995(ivar9, ivar37, 30, 20, 30, ivar38, ivar27, 494, 0, 1, 0, 1, svar3); + setWidgetSize(30, 20, 1, 0); + script_2995(ivar11, ivar37, subtract(getWidgetActualWidth(new WidgetPointer(ivar11)), 10), 20, 5, ivar38, ivar27, 494, 0, 1, 0, 1, svar4); + script_2994(ivar12, ivar37, 17, 17, 0, add(ivar38, 1), ivar29, 0, 0, 0, 0); + setWidgetPosition(0, add(ivar38, 1), 1, 0); + if (ivar21 == -1) { + svar6 = "-"; + } else if (ivar21 >= 1000) { + svar6 = "N/A"; + } else { + svar6 = intToStr(ivar21); + } + script_2995(ivar13, ivar37, subtract(getWidgetActualWidth(new WidgetPointer(ivar13)), 10), 20, 5, ivar38, ivar27, 494, 0, 1, 0, 1, svar6); + script_2995(ivar14, ivar37, getWidgetActualWidth(new WidgetPointer(ivar14)), 20, 0, ivar38, 0, 494, 0, 1, 0, 1, ""); + setScriptCallOnMouseEntered(3131, new WidgetPointer(ivar14), ivar37, ivar17, "Iii"); + setScriptCallOnMouseExit(3133, ""); + setWidgetContextMenuOption(1, "Select"); + cs2method1305("World " + intToStr(ivar17)); + setScriptCallOnClickContextMenu(3129, -2147483644, ivar37, ivar17, svar2, "iiis"); + script_2995(ivar15, ivar37, getWidgetActualWidth(new WidgetPointer(ivar15)), 20, 0, ivar38, 0, 494, 0, 1, 0, 1, ""); + setScriptCallOnMouseEntered(3130, new WidgetPointer(ivar5), new WidgetPointer(ivar15), ivar37, ivar17, "IIii"); + setScriptCallOnMouseExit(3132, new WidgetPointer(ivar5), ivar37, ivar17, "Iii"); + setWidgetContextMenuOption(1, "Alter"); + cs2method1305("Favourite"); + setScriptCallOnClickContextMenu(3128, -2147483644, ivar37, ivar17, "iii"); + if (ivar17 == getWorldId()) { + setWidgetIsHidden(false, new WidgetPointer(910,67)); + setWidgetPosition(0, ivar38, 0, 0, new WidgetPointer(910,67)); + } + if (ivar17 == globalint_998) { + ivar35 = ivar37; + } + if (ivar17 == globalint_999) { + ivar36 = ivar37; + } + structdump_11 = getNextWorldData(); + svar2 = structdump_11.stringpart_2; + ivar21 = structdump_11.intpart_4; + ivar20 = structdump_11.intpart_3; + svar1 = structdump_11.stringpart_1; + ivar19 = structdump_11.intpart_2; + svar0 = structdump_11.stringpart_0; + ivar18 = structdump_11.intpart_1; + ivar17 = structdump_11.intpart_0; + ivar38 = add(ivar38, 20); + ivar39 = add(ivar39, 1); + ivar37 = add(ivar37, 1); + } + } + setWidgetScrollMax(0, add(ivar38, getWidgetActualY(new WidgetPointer(910,63))), new WidgetPointer(910,62)); + script_31(ivar16, 59637822, 792, 789, 790, 791, 773, 788); + if (globalint_998 > 0) { + script_3118(globalint_998, 59637781, ivar35, ivar40); + } else { + script_3119(59637781, 1); + } + if (globalint_999 > 0) { + script_3118(globalint_999, 59637782, ivar36, ivar41); + } else { + script_3119(59637782, 0); + } + if ((globalint_998 > 0) && (globalint_999 > 0)) { + if (((boolean)ivar40) && ((boolean)ivar41)) { + setWidgetIsHidden(true, new WidgetPointer(910,23)); + } else if (((boolean)ivar40) && ((boolean)ivar41)) { + setWidgetPosition(getWidgetActualX(new WidgetPointer(910,56)), 0, 0, 0, new WidgetPointer(910,56)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(910,57)), 0, 0, 0, new WidgetPointer(910,57)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(910,58)), 0, 0, 0, new WidgetPointer(910,58)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(910,59)), 0, 0, 0, new WidgetPointer(910,59)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(910,60)), 0, 0, 0, new WidgetPointer(910,60)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(910,61)), 0, 0, 0, new WidgetPointer(910,61)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(910,56)), 20, 0, 0, new WidgetPointer(910,56)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(910,57)), 20, 0, 0, new WidgetPointer(910,57)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(910,58)), 20, 0, 0, new WidgetPointer(910,58)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(910,59)), 20, 0, 0, new WidgetPointer(910,59)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(910,60)), 20, 0, 0, new WidgetPointer(910,60)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(910,61)), 20, 0, 0, new WidgetPointer(910,61)); + setWidgetIsHidden(false, new WidgetPointer(910,23)); + } else if (((boolean)ivar40) && ((boolean)ivar41)) { + setWidgetPosition(getWidgetActualX(new WidgetPointer(910,56)), 20, 0, 0, new WidgetPointer(910,56)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(910,57)), 20, 0, 0, new WidgetPointer(910,57)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(910,58)), 20, 0, 0, new WidgetPointer(910,58)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(910,59)), 20, 0, 0, new WidgetPointer(910,59)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(910,60)), 20, 0, 0, new WidgetPointer(910,60)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(910,61)), 20, 0, 0, new WidgetPointer(910,61)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(910,56)), 20, 0, 0, new WidgetPointer(910,56)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(910,57)), 20, 0, 0, new WidgetPointer(910,57)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(910,58)), 20, 0, 0, new WidgetPointer(910,58)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(910,59)), 20, 0, 0, new WidgetPointer(910,59)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(910,60)), 20, 0, 0, new WidgetPointer(910,60)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(910,61)), 20, 0, 0, new WidgetPointer(910,61)); + setWidgetIsHidden(false, new WidgetPointer(910,23)); + } else { + setWidgetPosition(getWidgetActualX(new WidgetPointer(910,56)), 0, 0, 0, new WidgetPointer(910,56)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(910,57)), 0, 0, 0, new WidgetPointer(910,57)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(910,58)), 0, 0, 0, new WidgetPointer(910,58)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(910,59)), 0, 0, 0, new WidgetPointer(910,59)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(910,60)), 0, 0, 0, new WidgetPointer(910,60)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(910,61)), 0, 0, 0, new WidgetPointer(910,61)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(910,56)), 0, 0, 1, new WidgetPointer(910,56)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(910,57)), 0, 0, 1, new WidgetPointer(910,57)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(910,58)), 0, 0, 1, new WidgetPointer(910,58)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(910,59)), 0, 0, 1, new WidgetPointer(910,59)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(910,60)), 0, 0, 1, new WidgetPointer(910,60)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(910,61)), 0, 0, 1, new WidgetPointer(910,61)); + setWidgetIsHidden(false, new WidgetPointer(910,23)); + } + } else if ((globalint_998 > 0) && (globalint_999 <= 0)) { + if (((boolean)ivar40)) { + setWidgetIsHidden(true, new WidgetPointer(910,23)); + } else { + setWidgetPosition(getWidgetActualX(new WidgetPointer(910,56)), 0, 0, 0, new WidgetPointer(910,56)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(910,57)), 0, 0, 0, new WidgetPointer(910,57)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(910,58)), 0, 0, 0, new WidgetPointer(910,58)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(910,59)), 0, 0, 0, new WidgetPointer(910,59)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(910,60)), 0, 0, 0, new WidgetPointer(910,60)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(910,61)), 0, 0, 0, new WidgetPointer(910,61)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(910,56)), 0, 0, 1, new WidgetPointer(910,56)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(910,57)), 0, 0, 1, new WidgetPointer(910,57)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(910,58)), 0, 0, 1, new WidgetPointer(910,58)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(910,59)), 0, 0, 1, new WidgetPointer(910,59)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(910,60)), 0, 0, 1, new WidgetPointer(910,60)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(910,61)), 0, 0, 1, new WidgetPointer(910,61)); + setWidgetIsHidden(false, new WidgetPointer(910,23)); + } + } else if ((globalint_998 <= 0) && (globalint_999 > 0)) { + if (((boolean)ivar41)) { + setWidgetIsHidden(true, new WidgetPointer(910,23)); + } else { + setWidgetPosition(getWidgetActualX(new WidgetPointer(910,56)), 0, 0, 0, new WidgetPointer(910,56)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(910,57)), 0, 0, 0, new WidgetPointer(910,57)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(910,58)), 0, 0, 0, new WidgetPointer(910,58)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(910,59)), 0, 0, 0, new WidgetPointer(910,59)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(910,60)), 0, 0, 0, new WidgetPointer(910,60)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(910,61)), 0, 0, 0, new WidgetPointer(910,61)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(910,56)), 0, 0, 1, new WidgetPointer(910,56)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(910,57)), 0, 0, 1, new WidgetPointer(910,57)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(910,58)), 0, 0, 1, new WidgetPointer(910,58)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(910,59)), 0, 0, 1, new WidgetPointer(910,59)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(910,60)), 0, 0, 1, new WidgetPointer(910,60)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(910,61)), 0, 0, 1, new WidgetPointer(910,61)); + setWidgetIsHidden(false, new WidgetPointer(910,23)); + } + } else { + setWidgetIsHidden(true, new WidgetPointer(910,23)); + } + setWidgetIsHidden(true, new WidgetPointer(910,1)); + setWidgetIsHidden(false, new WidgetPointer(910,13)); + return; +} diff --git a/dumps/scripts/3116.cs2 b/dumps/scripts/3116.cs2 new file mode 100644 index 0000000..7484fe6 --- /dev/null +++ b/dumps/scripts/3116.cs2 @@ -0,0 +1,49 @@ +void script_3116() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + string svar0; + string svar1; + string svar2; + string svar3; + int stack_dump0; + opcStruct6506(4,3,0) structdump_1; + if (getWorldId() == -1) { + setWidgetIsHidden(true, new WidgetPointer(910,12)); + setWidgetText(new WidgetPointer(910,11), "World: Auto"); + return; + } + ivar0 = 0; + svar0 = ""; + ivar1 = 0; + svar1 = ""; + ivar2 = 0; + ivar3 = 0; + svar2 = ""; + stack_dump0 = getWorldId(); + structdump_1 = cs2method6506(stack_dump0); + svar2 = structdump_1.stringpart_2; + ivar3 = structdump_1.intpart_3; + ivar2 = structdump_1.intpart_2; + svar1 = structdump_1.stringpart_1; + ivar1 = structdump_1.intpart_1; + svar0 = structdump_1.stringpart_0; + ivar0 = structdump_1.intpart_0; + ivar4 = 0; + if (isBitFlagged(ivar0, 0)) { + ivar4 = 1; + } else { + ivar4 = 0; + } + svar3 = "World " + intToStr(getWorldId()); + setWidgetText(new WidgetPointer(910,11), svar3); + setWidgetPosition(add(getTextWidth(3793, svar3), 5), 0, 2, 2, new WidgetPointer(910,12)); + if (((boolean)ivar4)) { + setWidgetSprite(1531, new WidgetPointer(910,12)); + } else { + setWidgetSprite(1532, new WidgetPointer(910,12)); + } + return; +} diff --git a/dumps/scripts/3117.cs2 b/dumps/scripts/3117.cs2 new file mode 100644 index 0000000..dc81ecf --- /dev/null +++ b/dumps/scripts/3117.cs2 @@ -0,0 +1,126 @@ +cs2func_script_3117_struct(6,3,0) script_3117(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5,string arg6) { + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + string svar2; + string svar3; + string svar4; + ivar5 = -1; + ivar6 = -1; + ivar7 = 0; + ivar8 = 0; + svar2 = ""; + ivar9 = -1; + ivar10 = -1; + ivar11 = 0; + ivar12 = 0; + ivar13 = 0; + ivar14 = 0; + ivar15 = 0; + svar3 = ""; + svar4 = ""; + if (isBitFlagged(arg1, 0)) { + ivar11 = 1; + } else { + ivar11 = 0; + } + if (isBitFlagged(arg1, 1)) { + ivar12 = 1; + } else { + ivar12 = 0; + } + if (isBitFlagged(arg1, 2)) { + ivar13 = 1; + } else { + ivar13 = 0; + } + if (isBitFlagged(arg1, 3)) { + ivar14 = 1; + } else { + ivar14 = 0; + } + if (isBitFlagged(arg1, 4)) { + ivar15 = 1; + } else { + ivar15 = 0; + } + if (((boolean)getLanguage())) { + if (((boolean)ivar15)) { + ivar9 = cs2method_3408(105, 100, 730, 1); + svar2 = arg5; + } else if (strLength(arg5) > 1) { + ivar9 = cs2method_3408(105, 100, 730, 1); + svar2 = arg5; + } else { + ivar9 = cs2method_3408(105, 100, 1810, arg4); + svar2 = arg6; + } + } else { + if (((boolean)getLanguage())) { + ivar9 = 1517; + } else if (getLanguage() == 2) { + ivar9 = cs2method_3408(105, 100, 1810, 74); + } else { + if (getLanguage() == 3) { + ivar9 = cs2method_3408(105, 100, 1810, 31); + } + } + if (((boolean)ivar15)) { + svar2 = arg5; + } else if (strLength(arg5) > 1) { + svar2 = arg5; + } else if (((boolean)getLanguage())) { + svar2 = "German"; + } else if (getLanguage() == 2) { + svar2 = "French"; + } else { + if (getLanguage() == 3) { + svar2 = "Portuguese"; + } + } + } + if (((boolean)ivar11)) { + ivar5 = 1532; + ivar8 = 16579836; + svar3 = "Free"; + } else { + ivar5 = 1531; + ivar8 = 16579684; + svar3 = "Members"; + } + if (((boolean)ivar14)) { + ivar10 = 699; + } else { + ivar10 = 698; + } + if (arg0 == globalint_998) { + ivar7 = 2109969; + ivar6 = 1541; + } else if (arg0 == globalint_999) { + ivar7 = 2112529; + ivar6 = 1541; + } else { + if (((boolean)mod(arg2, 2))) { + ivar7 = 2103569; + } else { + ivar7 = 2695190; + } + ivar6 = 1545; + } + if (arg3 >= 1980) { + svar4 = "FULL"; + } else if (arg3 >= 0) { + svar4 = intToStr(arg3); + } else { + svar4 = "OFFLINE"; + } + return newstruct cs2func_script_3117_struct(ivar9, ivar5, ivar8, ivar10, ivar7, ivar6, svar2, svar3, svar4); +} diff --git a/dumps/scripts/3118.cs2 b/dumps/scripts/3118.cs2 new file mode 100644 index 0000000..350f2c4 --- /dev/null +++ b/dumps/scripts/3118.cs2 @@ -0,0 +1,150 @@ +void script_3118(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + string svar0; + string svar1; + string svar2; + string svar3; + string svar4; + string svar5; + int stack_dump0; + opcStruct6506(4,3,0) structdump_1; + int stack_dump2; + int stack_dump3; + int stack_dump4; + int stack_dump5; + string stack_dump6; + string stack_dump7; + cs2func_script_3117_struct(6,3,0) structdump_8; + deleteAllExtraChilds(new WidgetPointer(arg1)); + ivar4 = 0; + svar0 = ""; + ivar5 = 0; + svar1 = ""; + ivar6 = 0; + ivar7 = 0; + ivar8 = 0; + ivar9 = 0; + svar2 = ""; + ivar10 = -1; + ivar11 = -1; + ivar12 = -1; + ivar13 = -1; + ivar14 = 0; + ivar15 = 0; + stack_dump0 = arg0; + structdump_1 = cs2method6506(stack_dump0); + svar2 = structdump_1.stringpart_2; + ivar9 = structdump_1.intpart_3; + ivar6 = structdump_1.intpart_2; + svar1 = structdump_1.stringpart_1; + ivar5 = structdump_1.intpart_1; + svar0 = structdump_1.stringpart_0; + ivar4 = structdump_1.intpart_0; + setWidgetIsHidden(false, new WidgetPointer(arg1)); + ivar16 = -1; + svar3 = ""; + ivar17 = -1; + svar4 = ""; + svar5 = ""; + stack_dump0 = arg0; + stack_dump2 = ivar4; + stack_dump3 = -1; + stack_dump4 = ivar6; + stack_dump5 = ivar5; + stack_dump6 = svar0; + stack_dump7 = svar1; + structdump_8 = script_3117(stack_dump0, stack_dump2, stack_dump3, stack_dump4, stack_dump5, stack_dump6, stack_dump7); + svar5 = structdump_8.stringpart_2; + svar4 = structdump_8.stringpart_1; + ivar13 = structdump_8.intpart_5; + ivar15 = structdump_8.intpart_4; + ivar17 = structdump_8.intpart_3; + ivar14 = structdump_8.intpart_2; + ivar10 = structdump_8.intpart_1; + svar3 = structdump_8.stringpart_0; + ivar16 = structdump_8.intpart_0; + if (((boolean)arg3)) { + if (arg0 == globalint_998) { + ivar15 = 2109969; + } else { + if (arg0 == globalint_999) { + ivar15 = 2112529; + } + } + ivar13 = 1541; + ivar14 = 16579684; + script_2996(arg1, 0, getWidgetActualWidth(new WidgetPointer(arg1)), 20, 0, 0, ivar15, 1, 0); + script_2996(arg1, 1, 23, 20, 0, 0, 6316128, 1, 0); + setWidgetHidden(1); + script_2996(arg1, 2, 25, 20, 25, 0, 4210752, 1, 0); + setWidgetSize(25, 20, 1, 0); + setWidgetHidden(1); + script_2996(arg1, 3, 0, 20, 0, 0, 11685120, 1, 0); + setWidgetSize(0, 20, 1, 0); + if (getWorldId() == arg0) { + setWidgetHidden(0); + } else { + setWidgetHidden(1); + } + script_2994(arg1, 4, 13, 12, add(getWidgetActualX(new WidgetPointer(910,68)), divide(subtract(getWidgetActualWidth(new WidgetPointer(910,68)), 13), 2)), 4, ivar13, 0, 0, 0, 0); + script_2995(arg1, 5, subtract(getWidgetActualWidth(new WidgetPointer(arg1)), add(getWidgetActualX(new WidgetPointer(910,70)), 2)), 20, add(getWidgetActualX(new WidgetPointer(910,70)), 2), 0, ivar14, 494, 0, 1, 0, 1, "World " + intToStr(arg0) + " is running in a different language or is unavailable."); + script_2995(arg1, 6, getWidgetActualWidth(new WidgetPointer(910,77)), 20, getWidgetActualX(new WidgetPointer(910,77)), 0, 0, 494, 0, 1, 0, 1, ""); + setScriptCallOnMouseEntered(3121, new WidgetPointer(arg1), "I"); + setScriptCallOnMouseExit(3123, new WidgetPointer(arg1), "I"); + script_2995(arg1, 7, getWidgetActualWidth(new WidgetPointer(910,78)), 20, getWidgetActualX(new WidgetPointer(910,78)), 0, 0, 494, 0, 1, 0, 1, ""); + setScriptCallOnMouseEntered(3120, new WidgetPointer(arg1), "I"); + setScriptCallOnMouseExit(3122, new WidgetPointer(arg1), "I"); + setWidgetContextMenuOption(1, "Remove"); + cs2method1305("Favourite"); + setScriptCallOnClickContextMenu(3134, arg0, "i"); + return; + } + script_2996(arg1, 0, getWidgetActualWidth(new WidgetPointer(arg1)), 20, 0, 0, ivar15, 1, 0); + script_2996(arg1, 1, 23, 20, 0, 0, 6316128, 1, 0); + setWidgetHidden(1); + script_2996(arg1, 2, 25, 20, 25, 0, 4210752, 1, 0); + setWidgetSize(25, 20, 1, 0); + setWidgetHidden(1); + script_2996(arg1, 3, 0, 20, 0, 0, 11685120, 1, 0); + setWidgetSize(0, 20, 1, 0); + if (getWorldId() == arg0) { + setWidgetHidden(0); + } else { + setWidgetHidden(1); + } + script_2994(arg1, 4, 13, 12, add(getWidgetActualX(new WidgetPointer(910,68)), divide(subtract(getWidgetActualWidth(new WidgetPointer(910,68)), 13), 2)), 4, ivar13, 0, 0, 0, 0); + script_2994(arg1, 5, 19, 18, add(getWidgetActualX(new WidgetPointer(910,70)), 2), 1, ivar10, 0, 0, 0, 0); + script_2995(arg1, 6, subtract(getWidgetActualWidth(new WidgetPointer(910,69)), 25), 20, add(getWidgetActualX(new WidgetPointer(910,69)), 25), 0, ivar14, 494, 0, 1, 0, 1, intToStr(arg0)); + script_2995(arg1, 7, subtract(getWidgetActualWidth(new WidgetPointer(910,71)), 6), 20, add(getWidgetActualX(new WidgetPointer(910,71)), 3), 0, ivar14, 494, 0, 1, 0, 1, svar5); + script_2994(arg1, 8, 24, 12, add(getWidgetActualX(new WidgetPointer(910,73)), 4), 4, ivar16, 0, 0, 0, 0); + script_2995(arg1, 9, subtract(getWidgetActualWidth(new WidgetPointer(910,72)), 30), 20, add(getWidgetActualX(new WidgetPointer(910,72)), 30), 0, ivar14, 494, 0, 1, 0, 1, svar3); + script_2995(arg1, 10, subtract(getWidgetActualWidth(new WidgetPointer(910,74)), 10), 20, add(getWidgetActualX(new WidgetPointer(910,74)), 5), 0, ivar14, 494, 0, 1, 0, 1, svar4); + script_2994(arg1, 11, 17, 17, add(getWidgetActualX(new WidgetPointer(910,75)), divide(subtract(getWidgetActualWidth(new WidgetPointer(910,75)), 17), 2)), 1, ivar17, 0, 0, 0, 0); + script_2995(arg1, 12, subtract(getWidgetActualWidth(new WidgetPointer(910,75)), 10), 20, add(getWidgetActualX(new WidgetPointer(910,76)), 5), 0, ivar14, 494, 0, 1, 0, 1, intToStr(ivar9)); + script_2995(arg1, 13, getWidgetActualWidth(new WidgetPointer(910,77)), 20, getWidgetActualX(new WidgetPointer(910,77)), 0, 0, 494, 0, 1, 0, 1, ""); + setScriptCallOnMouseEntered(3121, new WidgetPointer(arg1), "I"); + setScriptCallOnMouseExit(3123, new WidgetPointer(arg1), "I"); + setWidgetContextMenuOption(1, "Select"); + cs2method1305("World " + intToStr(arg0)); + setScriptCallOnClickContextMenu(3129, -2147483644, arg2, arg0, svar2, "iiis"); + script_2995(arg1, 14, getWidgetActualWidth(new WidgetPointer(910,78)), 20, getWidgetActualX(new WidgetPointer(910,78)), 0, 0, 494, 0, 1, 0, 1, ""); + setScriptCallOnMouseEntered(3120, new WidgetPointer(arg1), "I"); + setScriptCallOnMouseExit(3122, new WidgetPointer(arg1), "I"); + setWidgetContextMenuOption(1, "Remove"); + cs2method1305("Favourite"); + setScriptCallOnClickContextMenu(3134, arg0, "i"); + return; +} diff --git a/dumps/scripts/3119.cs2 b/dumps/scripts/3119.cs2 new file mode 100644 index 0000000..83e4f16 --- /dev/null +++ b/dumps/scripts/3119.cs2 @@ -0,0 +1,5 @@ +void script_3119(int arg0,int arg1) { + deleteAllExtraChilds(new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/312.cs2 b/dumps/scripts/312.cs2 new file mode 100644 index 0000000..ec551b5 --- /dev/null +++ b/dumps/scripts/312.cs2 @@ -0,0 +1,63 @@ +void script_312(int arg0,int arg1,string arg2) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + if (globalint_1 < add(getClientCycle(), 25)) { + globalint_1 = max(globalint_1, getClientCycle()); + globalint_1 = add(globalint_1, 2); + return; + } + ivar2 = 49479737; + ivar3 = getWidgetParentId(new WidgetPointer(ivar2)); + ivar4 = getWidgetActualWidth(new WidgetPointer(ivar3)); + ivar5 = 0; + ivar6 = 0; + globalint_1 = add(getClientCycle(), 10); + if (((boolean)globalint_2)) { + ivar5 = getMaxLineWidth(ivar4, 495, arg2); + ivar6 = add(multiply(getLineCount(ivar5, 495, arg2), 12), 9); + ivar5 = add(ivar5, 4); + setWidgetSize(ivar5, ivar6, 0, 0, new WidgetPointer(ivar2)); + createExtraChild(new WidgetPointer(ivar2), 3, 0); + setWidgetSize(0, 0, 1, 1); + setWidgetPosition(0, 0, 1, 1); + setWidgetFilled(1); + setWidgetRGB(new Color(255, 255, 160)); + createExtraChild(new WidgetPointer(ivar2), 3, 1); + setWidgetSize(0, 0, 1, 1); + setWidgetPosition(0, 0, 1, 1); + setWidgetFilled(0); + setWidgetRGB(new Color(1, 1, 1)); + createExtraChild(new WidgetPointer(ivar2), 4, 2); + setWidgetSize(4, 6, 1, 1); + setWidgetPosition(0, 0, 1, 1); + setWidgetRGB(new Color(0, 0, 0)); + setWidgetTextAlignment(0, 1, 0); + setWidgetFont(495); + setWidgetText(arg2); + globalint_2 = 1; + } + ivar5 = arg0; + ivar6 = arg1; + ivar7 = subtract(0, ivar5); + if (ivar7 > 0) { + ivar5 = add(ivar5, ivar7); + } + ivar7 = subtract(add(ivar5, getWidgetActualWidth(new WidgetPointer(ivar2))), ivar4); + if (ivar7 > 0) { + ivar5 = subtract(ivar5, ivar7); + } + ivar7 = subtract(add(ivar6, getWidgetActualHeight(new WidgetPointer(ivar2))), getWidgetActualHeight(new WidgetPointer(ivar3))); + if (ivar7 > 0) { + ivar6 = subtract(ivar6, ivar7); + } + ivar7 = subtract(0, ivar6); + if (ivar7 > 0) { + ivar6 = add(ivar6, ivar7); + } + setWidgetPosition(ivar5, ivar6, 0, 0, new WidgetPointer(ivar2)); + return; +} diff --git a/dumps/scripts/3120.cs2 b/dumps/scripts/3120.cs2 new file mode 100644 index 0000000..a9b8c8d --- /dev/null +++ b/dumps/scripts/3120.cs2 @@ -0,0 +1,14 @@ +void script_3120(int arg0) { + if (setWidgetRegister(new WidgetPointer(arg0), 1)) { + setWidgetHidden(0); + setWidgetRGB(new Color(96, 96, 96)); + } + if (setWidgetRegister(new WidgetPointer(arg0), 2)) { + setWidgetHidden(0); + setWidgetRGB(new Color(64, 64, 64)); + } + if (setWidgetRegister(new WidgetPointer(arg0), 4)) { + setWidgetSprite(1542); + } + return; +} diff --git a/dumps/scripts/3121.cs2 b/dumps/scripts/3121.cs2 new file mode 100644 index 0000000..1c7b998 --- /dev/null +++ b/dumps/scripts/3121.cs2 @@ -0,0 +1,11 @@ +void script_3121(int arg0) { + if (setWidgetRegister(new WidgetPointer(arg0), 1)) { + setWidgetHidden(0); + setWidgetRGB(new Color(64, 64, 64)); + } + if (setWidgetRegister(new WidgetPointer(arg0), 2)) { + setWidgetHidden(0); + setWidgetRGB(new Color(96, 96, 96)); + } + return; +} diff --git a/dumps/scripts/3122.cs2 b/dumps/scripts/3122.cs2 new file mode 100644 index 0000000..63f2400 --- /dev/null +++ b/dumps/scripts/3122.cs2 @@ -0,0 +1,12 @@ +void script_3122(int arg0) { + if (setWidgetRegister(new WidgetPointer(arg0), 1)) { + setWidgetHidden(1); + } + if (setWidgetRegister(new WidgetPointer(arg0), 2)) { + setWidgetHidden(1); + } + if (setWidgetRegister(new WidgetPointer(arg0), 4)) { + setWidgetSprite(1541); + } + return; +} diff --git a/dumps/scripts/3123.cs2 b/dumps/scripts/3123.cs2 new file mode 100644 index 0000000..2cc53b9 --- /dev/null +++ b/dumps/scripts/3123.cs2 @@ -0,0 +1,9 @@ +void script_3123(int arg0) { + if (setWidgetRegister(new WidgetPointer(arg0), 1)) { + setWidgetHidden(1); + } + if (setWidgetRegister(new WidgetPointer(arg0), 2)) { + setWidgetHidden(1); + } + return; +} diff --git a/dumps/scripts/3124.cs2 b/dumps/scripts/3124.cs2 new file mode 100644 index 0000000..8e76e17 --- /dev/null +++ b/dumps/scripts/3124.cs2 @@ -0,0 +1,4 @@ +void script_3124(int arg0,int arg1,int arg2,string arg3,string arg4) { + script_3125(arg0, arg1, arg2, arg3, arg4); + return; +} diff --git a/dumps/scripts/3125.cs2 b/dumps/scripts/3125.cs2 new file mode 100644 index 0000000..51b535e --- /dev/null +++ b/dumps/scripts/3125.cs2 @@ -0,0 +1,16 @@ +void script_3125(int arg0,int arg1,int arg2,string arg3,string arg4) { + script_2994(arg0, 0, 11, 11, 0, 0, 1535, 0, 0, 0, 0); + setScriptCallOnMouseEntered(3126, new WidgetPointer(arg0), 0, "Ii"); + setScriptCallOnMouseExit(3127, new WidgetPointer(arg0), 0, "Ii"); + setWidgetContextMenuOption(1, "Sort"); + cs2method1305(arg3); + setScriptCallOnClickContextMenu(3148, arg1, "i"); + script_2994(arg0, 1, 11, 11, 0, 0, 1536, 0, 0, 0, 0); + setWidgetPosition(0, 0, 2, 0); + setScriptCallOnMouseEntered(3126, new WidgetPointer(arg0), 1, "Ii"); + setScriptCallOnMouseExit(3127, new WidgetPointer(arg0), 1, "Ii"); + setWidgetContextMenuOption(1, "Sort"); + cs2method1305(arg4); + setScriptCallOnClickContextMenu(3148, arg2, "i"); + return; +} diff --git a/dumps/scripts/3126.cs2 b/dumps/scripts/3126.cs2 new file mode 100644 index 0000000..c5987ea --- /dev/null +++ b/dumps/scripts/3126.cs2 @@ -0,0 +1,10 @@ +void script_3126(int arg0,int arg1) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + if (((boolean)arg1)) { + setWidgetSprite(1533); + } else { + setWidgetSprite(1534); + } + } + return; +} diff --git a/dumps/scripts/3127.cs2 b/dumps/scripts/3127.cs2 new file mode 100644 index 0000000..8402f52 --- /dev/null +++ b/dumps/scripts/3127.cs2 @@ -0,0 +1,10 @@ +void script_3127(int arg0,int arg1) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + if (((boolean)arg1)) { + setWidgetSprite(1535); + } else { + setWidgetSprite(1536); + } + } + return; +} diff --git a/dumps/scripts/3128.cs2 b/dumps/scripts/3128.cs2 new file mode 100644 index 0000000..e013460 --- /dev/null +++ b/dumps/scripts/3128.cs2 @@ -0,0 +1,6 @@ +void script_3128(int arg0,int arg1,int arg2) { + if (((boolean)arg0)) { + script_3135(arg2); + } + return; +} diff --git a/dumps/scripts/3129.cs2 b/dumps/scripts/3129.cs2 new file mode 100644 index 0000000..f29599f --- /dev/null +++ b/dumps/scripts/3129.cs2 @@ -0,0 +1,4 @@ +void script_3129(int arg0,int arg1,int arg2,string arg3) { + script_4701(arg0, arg1, arg2, arg3); + return; +} diff --git a/dumps/scripts/313.cs2 b/dumps/scripts/313.cs2 new file mode 100644 index 0000000..1d4918f --- /dev/null +++ b/dumps/scripts/313.cs2 @@ -0,0 +1,33 @@ +void script_313(int arg0) { + string svar0; + script_333(67371038, 7627330, 15130810, 0, 0); + script_333(67371041, 13022863, 15130810, 0, 0); + setWidgetSprite(4129, new WidgetPointer(1028,118)); + setWidgetSprite(4129, new WidgetPointer(1028,120)); + script_2741(); + setScriptCallOnClickContextMenu(353, 1, "1", new WidgetPointer(1028,115)); + setScriptCallOnClickContextMenu(353, 0, "1", new WidgetPointer(1028,116)); + setScriptCallOnClickContextMenu(350, -2147483644, 0, "i1", new WidgetPointer(1028,38)); + setScriptCallOnClickContextMenu(350, -2147483644, 1, "i1", new WidgetPointer(1028,39)); + script_385(-1); + svar0 = cs2method2801(1, new WidgetPointer(1028,102)); + script_368(67371110, add(getTextWidth(495, svar0), 30), svar0, ""); + setScriptCallOnClickContextMenu(358, -2147483644, "i", new WidgetPointer(1028,102)); + setScriptCallOnClickContextMenu(354, -2147483644, 0, "ii", new WidgetPointer(1028,95)); + setScriptCallOnClickContextMenu(354, -2147483644, 1, "ii", new WidgetPointer(1028,96)); + setScriptCallOnClickContextMenu(354, -2147483644, 2, "ii", new WidgetPointer(1028,100)); + setScriptCallOnClickContextMenu(354, -2147483644, 3, "ii", new WidgetPointer(1028,97)); + setScriptCallOnClickContextMenu(354, -2147483644, 6, "ii", new WidgetPointer(1028,98)); + setScriptCallOnClickContextMenu(354, -2147483644, 7, "ii", new WidgetPointer(1028,99)); + setWidgetSelfFull(new WidgetPointer(1028,112)); + setWidget3DRotation(-30, 135, 18, 4, 0, 325, new WidgetPointer(1028,112)); + setWidget3DRotation(-30, 135, 18, 4, 0, 325, new WidgetPointer(1028,113)); + globalint_196 = bitconfig_8093; + globalint_197 = bitconfig_8089; + globalint_86 = bitconfig_8090; + globalint_1020 = bitconfig_6501; + script_386(0); + setScriptCallOnConfigChange(315, 1158, 1363, 2, "Y", new WidgetPointer(arg0)); + setScriptCallOnGlobalConfigChange(349, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 12, "Y", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/3130.cs2 b/dumps/scripts/3130.cs2 new file mode 100644 index 0000000..e946310 --- /dev/null +++ b/dumps/scripts/3130.cs2 @@ -0,0 +1,18 @@ +void script_3130(int arg0,int arg1,int arg2,int arg3) { + if (setWidgetRegister(new WidgetPointer(arg0), arg2)) { + if ((globalint_998 == arg3) || (globalint_999 == arg3)) { + setWidgetSprite(1542); + } else { + setWidgetSprite(1546); + } + } + if (setWidgetRegister(new WidgetPointer(arg1), arg2)) { + setWidgetIsHidden(false, new WidgetPointer(910,65)); + setWidgetIsHidden(false, new WidgetPointer(910,66)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(910,65)), getWidgetActualY(), 0, 0, new WidgetPointer(910,65)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(910,66)), getWidgetActualY(), 0, 0, new WidgetPointer(910,66)); + } + setWidgetRGB(new Color(96, 96, 96), new WidgetPointer(910,66)); + setWidgetRGB(new Color(64, 64, 64), new WidgetPointer(910,65)); + return; +} diff --git a/dumps/scripts/3131.cs2 b/dumps/scripts/3131.cs2 new file mode 100644 index 0000000..1ef8a27 --- /dev/null +++ b/dumps/scripts/3131.cs2 @@ -0,0 +1,11 @@ +void script_3131(int arg0,int arg1,int arg2) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetIsHidden(false, new WidgetPointer(910,65)); + setWidgetIsHidden(false, new WidgetPointer(910,66)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(910,65)), getWidgetActualY(), 0, 0, new WidgetPointer(910,65)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(910,66)), getWidgetActualY(), 0, 0, new WidgetPointer(910,66)); + } + setWidgetRGB(new Color(64, 64, 64), new WidgetPointer(910,66)); + setWidgetRGB(new Color(96, 96, 96), new WidgetPointer(910,65)); + return; +} diff --git a/dumps/scripts/3132.cs2 b/dumps/scripts/3132.cs2 new file mode 100644 index 0000000..99be295 --- /dev/null +++ b/dumps/scripts/3132.cs2 @@ -0,0 +1,12 @@ +void script_3132(int arg0,int arg1,int arg2) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + if ((globalint_998 == arg2) || (globalint_999 == arg2)) { + setWidgetSprite(1541); + } else { + setWidgetSprite(1545); + } + } + setWidgetIsHidden(true, new WidgetPointer(910,65)); + setWidgetIsHidden(true, new WidgetPointer(910,66)); + return; +} diff --git a/dumps/scripts/3133.cs2 b/dumps/scripts/3133.cs2 new file mode 100644 index 0000000..1e821b4 --- /dev/null +++ b/dumps/scripts/3133.cs2 @@ -0,0 +1,5 @@ +void script_3133() { + setWidgetIsHidden(true, new WidgetPointer(910,65)); + setWidgetIsHidden(true, new WidgetPointer(910,66)); + return; +} diff --git a/dumps/scripts/3134.cs2 b/dumps/scripts/3134.cs2 new file mode 100644 index 0000000..518cfdd --- /dev/null +++ b/dumps/scripts/3134.cs2 @@ -0,0 +1,4 @@ +void script_3134(int arg0) { + script_3135(arg0); + return; +} diff --git a/dumps/scripts/3135.cs2 b/dumps/scripts/3135.cs2 new file mode 100644 index 0000000..e52a4f6 --- /dev/null +++ b/dumps/scripts/3135.cs2 @@ -0,0 +1,8 @@ +void script_3135(int arg0) { + if ((globalint_998 == arg0) || (globalint_999 == arg0)) { + script_3139(arg0); + } else { + script_3137(arg0); + } + return; +} diff --git a/dumps/scripts/3136.cs2 b/dumps/scripts/3136.cs2 new file mode 100644 index 0000000..078864a --- /dev/null +++ b/dumps/scripts/3136.cs2 @@ -0,0 +1,4 @@ +void script_3136(int arg0) { + script_3137(arg0); + return; +} diff --git a/dumps/scripts/3137.cs2 b/dumps/scripts/3137.cs2 new file mode 100644 index 0000000..aa4a6f9 --- /dev/null +++ b/dumps/scripts/3137.cs2 @@ -0,0 +1,25 @@ +void script_3137(int arg0) { + string svar0; + if ((globalint_998 > 0) && (globalint_999 > 0)) { + script_3143(1, "Please delete one of your existing favourite worlds before setting another."); + return; + } + if (globalint_998 < 1) { + script_1857(arg0); + } else { + if (globalint_999 < 1) { + script_1858(arg0); + } + } + globalint_998 = script_1853(); + globalint_999 = script_1854(); + script_3113(); + svar0 = "Your changes cannot be saved because" + "
" + "you are using the unsigned client."; + if (((boolean)cs2method5420())) { + script_3143(1, svar0); + } else { + script_3143(0, "World " + intToStr(arg0) + " has been added to your favourites."); + } + script_3065(1); + return; +} diff --git a/dumps/scripts/3138.cs2 b/dumps/scripts/3138.cs2 new file mode 100644 index 0000000..b2a9156 --- /dev/null +++ b/dumps/scripts/3138.cs2 @@ -0,0 +1,4 @@ +void script_3138(int arg0) { + script_3139(arg0); + return; +} diff --git a/dumps/scripts/3139.cs2 b/dumps/scripts/3139.cs2 new file mode 100644 index 0000000..963db03 --- /dev/null +++ b/dumps/scripts/3139.cs2 @@ -0,0 +1,22 @@ +void script_3139(int arg0) { + string svar0; + if (globalint_998 == arg0) { + script_1857(script_1854()); + script_1858(0); + } else { + if (globalint_999 == arg0) { + script_1858(0); + } + } + globalint_998 = script_1853(); + globalint_999 = script_1854(); + script_3113(); + svar0 = "Your changes cannot be saved because" + "
" + "you are using the unsigned client."; + if (((boolean)cs2method5420())) { + script_3143(1, svar0); + } else { + script_3143(0, "World " + intToStr(arg0) + " has been removed from your favourites."); + } + script_3065(1); + return; +} diff --git a/dumps/scripts/314.cs2 b/dumps/scripts/314.cs2 new file mode 100644 index 0000000..17c3d27 --- /dev/null +++ b/dumps/scripts/314.cs2 @@ -0,0 +1,8 @@ +void script_314(int arg0) { + if (globalint_179 != -1) { + setWidgetModel(globalint_179, new WidgetPointer(arg0)); + } else { + setWidgetModel(18535, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/3140.cs2 b/dumps/scripts/3140.cs2 new file mode 100644 index 0000000..4f3103a --- /dev/null +++ b/dumps/scripts/3140.cs2 @@ -0,0 +1,4 @@ +void script_3140(int arg0,string arg1) { + script_3141(arg0, arg1); + return; +} diff --git a/dumps/scripts/3141.cs2 b/dumps/scripts/3141.cs2 new file mode 100644 index 0000000..cdfa960 --- /dev/null +++ b/dumps/scripts/3141.cs2 @@ -0,0 +1,10 @@ +void script_3141(int arg0,string arg1) { + if (setWorldHost(arg0, arg1)) { + globalint_547 = 0; + script_3143(0, "Switched to game world " + intToStr(arg0)); + } else { + script_3143(1, "Sorry, we couldn't contact world " + intToStr(arg0) + "." + "
" + "Please choose a different world."); + } + script_3116(); + return; +} diff --git a/dumps/scripts/3142.cs2 b/dumps/scripts/3142.cs2 new file mode 100644 index 0000000..ea4392e --- /dev/null +++ b/dumps/scripts/3142.cs2 @@ -0,0 +1,4 @@ +void script_3142(int arg0,string arg1) { + script_3143(arg0, arg1); + return; +} diff --git a/dumps/scripts/3143.cs2 b/dumps/scripts/3143.cs2 new file mode 100644 index 0000000..d056d4a --- /dev/null +++ b/dumps/scripts/3143.cs2 @@ -0,0 +1,11 @@ +void script_3143(int arg0,string arg1) { + if (((boolean)arg0)) { + setWidgetRGB(new Color(235, 224, 188), new WidgetPointer(910,8)); + } else { + if (((boolean)arg0)) { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(910,8)); + } + } + setWidgetText(new WidgetPointer(910,8), arg1); + return; +} diff --git a/dumps/scripts/3144.cs2 b/dumps/scripts/3144.cs2 new file mode 100644 index 0000000..6328340 --- /dev/null +++ b/dumps/scripts/3144.cs2 @@ -0,0 +1,25 @@ +void script_3144(int arg0,int arg1,int arg2,int arg3,string arg4) { + if (setWidgetRegister(new WidgetPointer(arg0), arg2)) { + setWidgetIsHidden(false, new WidgetPointer(910,65)); + setWidgetIsHidden(false, new WidgetPointer(910,66)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(910,65)), getWidgetActualY(), 0, 0, new WidgetPointer(910,65)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(910,66)), getWidgetActualY(), 0, 0, new WidgetPointer(910,66)); + } + if (setWidgetRegister(new WidgetPointer(arg1), arg2)) { + if (getWidgetSpriteId() == 1541) { + setWidgetSprite(1542); + } else { + if (getWidgetSpriteId() == 1545) { + setWidgetSprite(1546); + } + } + } + if (((boolean)arg3)) { + setWidgetRGB(new Color(96, 96, 96), new WidgetPointer(910,65)); + setWidgetRGB(new Color(64, 64, 64), new WidgetPointer(910,66)); + } else { + setWidgetRGB(new Color(96, 96, 96), new WidgetPointer(910,66)); + setWidgetRGB(new Color(64, 64, 64), new WidgetPointer(910,65)); + } + return; +} diff --git a/dumps/scripts/3145.cs2 b/dumps/scripts/3145.cs2 new file mode 100644 index 0000000..ea4108e --- /dev/null +++ b/dumps/scripts/3145.cs2 @@ -0,0 +1,14 @@ +void script_3145(int arg0,int arg1,int arg2,int arg3) { + setWidgetIsHidden(true, new WidgetPointer(910,65)); + setWidgetIsHidden(true, new WidgetPointer(910,66)); + if (setWidgetRegister(new WidgetPointer(arg1), arg2)) { + if (getWidgetSpriteId() == 1542) { + setWidgetSprite(1541); + } else { + if (getWidgetSpriteId() == 1546) { + setWidgetSprite(1545); + } + } + } + return; +} diff --git a/dumps/scripts/3146.cs2 b/dumps/scripts/3146.cs2 new file mode 100644 index 0000000..d1d7561 --- /dev/null +++ b/dumps/scripts/3146.cs2 @@ -0,0 +1,4 @@ +void script_3146() { + setWidgetSprite(2656, new WidgetPointer(910,6)); + return; +} diff --git a/dumps/scripts/3147.cs2 b/dumps/scripts/3147.cs2 new file mode 100644 index 0000000..9e67ead --- /dev/null +++ b/dumps/scripts/3147.cs2 @@ -0,0 +1,4 @@ +void script_3147() { + setWidgetSprite(2655, new WidgetPointer(910,6)); + return; +} diff --git a/dumps/scripts/3148.cs2 b/dumps/scripts/3148.cs2 new file mode 100644 index 0000000..e54233e --- /dev/null +++ b/dumps/scripts/3148.cs2 @@ -0,0 +1,96 @@ +void script_3148(int arg0) { + int ivar1; + ivar1 = script_1851(); + if (ivar1 == arg0) { + return; + } + switch (arg0) { + case 0: + if (((boolean)ivar1)) { + script_1855(0); + script_3113(); + return; + } + break; + case 2: + if (ivar1 == 3) { + script_1855(2); + script_3113(); + return; + } + break; + case 4: + if (ivar1 == 5) { + script_1855(4); + script_3113(); + return; + } + break; + case 6: + if (ivar1 == 7) { + script_1855(6); + script_3113(); + return; + } + break; + case 8: + if (ivar1 == 9) { + script_1855(8); + script_3113(); + return; + } + break; + case 10: + if (ivar1 == 11) { + script_1855(10); + script_3113(); + return; + } + break; + case 1: + if (((boolean)ivar1)) { + script_1855(1); + script_3113(); + return; + } + break; + case 3: + if (ivar1 == 2) { + script_1855(3); + script_3113(); + return; + } + break; + case 5: + if (ivar1 == 4) { + script_1855(5); + script_3113(); + return; + } + break; + case 7: + if (ivar1 == 6) { + script_1855(7); + script_3113(); + return; + } + break; + case 9: + if (ivar1 == 8) { + script_1855(9); + script_3113(); + return; + } + break; + case 11: + if (ivar1 == 10) { + script_1855(11); + script_3113(); + return; + } + } + script_1856(ivar1); + script_1855(arg0); + script_3113(); + return; +} diff --git a/dumps/scripts/3149.cs2 b/dumps/scripts/3149.cs2 new file mode 100644 index 0000000..28d22b8 --- /dev/null +++ b/dumps/scripts/3149.cs2 @@ -0,0 +1,4 @@ +void script_3149(int arg0,int arg1,string arg2) { + script_3150(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/315.cs2 b/dumps/scripts/315.cs2 new file mode 100644 index 0000000..a896e9c --- /dev/null +++ b/dumps/scripts/315.cs2 @@ -0,0 +1,23 @@ +void script_315() { + int ivar0; + ivar0 = -1; + if ((bitconfig_8093 != globalint_196) || (globalint_197 != bitconfig_8089)) { + ivar0 = script_734(bitconfig_8093); + globalint_196 = bitconfig_8093; + globalint_197 = bitconfig_8089; + script_387(ivar0); + globalint_86 = bitconfig_8090; + script_390(ivar0); + } else { + if (globalint_86 != bitconfig_8090) { + globalint_86 = bitconfig_8090; + script_390(script_734(globalint_196)); + } + } + if (globalint_1020 != bitconfig_6501) { + globalint_1020 = bitconfig_6501; + script_391(); + } + script_2741(); + return; +} diff --git a/dumps/scripts/3150.cs2 b/dumps/scripts/3150.cs2 new file mode 100644 index 0000000..6bc0a02 --- /dev/null +++ b/dumps/scripts/3150.cs2 @@ -0,0 +1,10 @@ +void script_3150(int arg0,int arg1,string arg2) { + if (arg1 < 0) { + setScriptCallOnMouseOver(3151, new WidgetPointer(arg0), arg1, add(getClientCycle(), 25), arg2, -2147483647, -2147483646, "Iiisii", new WidgetPointer(arg0)); + } else { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setScriptCallOnMouseOver(3151, new WidgetPointer(arg0), arg1, add(getClientCycle(), 25), arg2, -2147483647, -2147483646, "Iiisii"); + } + } + return; +} diff --git a/dumps/scripts/3151.cs2 b/dumps/scripts/3151.cs2 new file mode 100644 index 0000000..22902d6 --- /dev/null +++ b/dumps/scripts/3151.cs2 @@ -0,0 +1,4 @@ +void script_3151(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5) { + script_3152(arg0, arg1, arg2, arg3, arg4, arg5); + return; +} diff --git a/dumps/scripts/3152.cs2 b/dumps/scripts/3152.cs2 new file mode 100644 index 0000000..80192be --- /dev/null +++ b/dumps/scripts/3152.cs2 @@ -0,0 +1,44 @@ +void script_3152(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5) { + int ivar5; + int ivar6; + int ivar7; + int ivar8; + ivar5 = 0; + ivar6 = 0; + ivar7 = 0; + ivar8 = arg0; + if (getClientCycle() > arg2) { + setWidgetText(new WidgetPointer(910,17), arg5); + setWidgetSize(add(multiply(getWidgetActualX(new WidgetPointer(910,17)), 2), getTextWidth(495, arg5)), getWidgetActualHeight(new WidgetPointer(910,14)), 0, 0, new WidgetPointer(910,14)); + while (((boolean)ivar7)) { + if (ivar8 == 59637773) { + ivar7 = 1; + } + ivar5 = add(ivar5, getWidgetActualX(new WidgetPointer(ivar8))); + ivar6 = add(ivar6, getWidgetActualY(new WidgetPointer(ivar8))); + ivar8 = getWidgetParentId(new WidgetPointer(ivar8)); + } + if ((arg1 > -1) && setWidgetRegister(new WidgetPointer(arg0), arg1)) { + ivar5 = add(ivar5, getWidgetActualX()); + ivar6 = add(ivar6, getWidgetActualY()); + } + ivar5 = add(add(ivar5, arg3), 3); + ivar6 = subtract(subtract(add(ivar6, arg4), 3), getWidgetActualHeight(new WidgetPointer(910,14))); + if (add(ivar5, getWidgetActualWidth(new WidgetPointer(910,14))) > getWidgetActualWidth(new WidgetPointer(910,0))) { + ivar5 = subtract(getWidgetActualWidth(new WidgetPointer(910,0)), getWidgetActualWidth(new WidgetPointer(910,14))); + } + if (ivar6 < 0) { + ivar6 = 0; + } + setWidgetPosition(ivar5, ivar6, 0, 0, new WidgetPointer(910,14)); + setWidgetIsHidden(false, new WidgetPointer(910,14)); + if (arg1 < 0) { + setScriptCallOnMouseOver(-1, "", new WidgetPointer(arg0)); + } else { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setScriptCallOnMouseOver(-1, ""); + } + } + } + return; +} diff --git a/dumps/scripts/3153.cs2 b/dumps/scripts/3153.cs2 new file mode 100644 index 0000000..ce31928 --- /dev/null +++ b/dumps/scripts/3153.cs2 @@ -0,0 +1,11 @@ +void script_3153(int arg0,int arg1) { + setWidgetIsHidden(true, new WidgetPointer(910,14)); + if (arg1 < 0) { + setScriptCallOnMouseOver(-1, "", new WidgetPointer(arg0)); + } else { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setScriptCallOnMouseOver(-1, ""); + } + } + return; +} diff --git a/dumps/scripts/3154.cs2 b/dumps/scripts/3154.cs2 new file mode 100644 index 0000000..4d924ce --- /dev/null +++ b/dumps/scripts/3154.cs2 @@ -0,0 +1,4 @@ +void script_3154(int arg0) { + script_3155(arg0); + return; +} diff --git a/dumps/scripts/3155.cs2 b/dumps/scripts/3155.cs2 new file mode 100644 index 0000000..1e85cef --- /dev/null +++ b/dumps/scripts/3155.cs2 @@ -0,0 +1,8 @@ +void script_3155(int arg0) { + script_2994(arg0, 0, 16, 16, 0, 0, 1547, 0, 0, 0, 0); + setScriptCallOnMouseEntered(3156, new WidgetPointer(arg0), "I"); + setScriptCallOnMouseExit(3157, new WidgetPointer(arg0), "I"); + script_2994(arg0, 1, 16, 16, 0, 0, 1548, 0, 0, 0, 0); + setWidgetHidden(1); + return; +} diff --git a/dumps/scripts/3156.cs2 b/dumps/scripts/3156.cs2 new file mode 100644 index 0000000..81a7110 --- /dev/null +++ b/dumps/scripts/3156.cs2 @@ -0,0 +1,6 @@ +void script_3156(int arg0) { + if (setWidgetRegister(new WidgetPointer(arg0), 1)) { + setWidgetHidden(0); + } + return; +} diff --git a/dumps/scripts/3157.cs2 b/dumps/scripts/3157.cs2 new file mode 100644 index 0000000..17d558f --- /dev/null +++ b/dumps/scripts/3157.cs2 @@ -0,0 +1,6 @@ +void script_3157(int arg0) { + if (setWidgetRegister(new WidgetPointer(arg0), 1)) { + setWidgetHidden(1); + } + return; +} diff --git a/dumps/scripts/3158.cs2 b/dumps/scripts/3158.cs2 new file mode 100644 index 0000000..5750b67 --- /dev/null +++ b/dumps/scripts/3158.cs2 @@ -0,0 +1,8 @@ +void script_3158() { + script_2595(2); + script_1217(59703337, 59703338); + script_1216(59703343, 59703344); + script_1218(59703331, 59703332); + script_1220(59703316, 59703314); + return; +} diff --git a/dumps/scripts/3159.cs2 b/dumps/scripts/3159.cs2 new file mode 100644 index 0000000..1e58dc5 --- /dev/null +++ b/dumps/scripts/3159.cs2 @@ -0,0 +1,32 @@ +void script_3159(int arg0) { + setWidgetSize(subtract(getWidgetActualX(new WidgetPointer(912,38)), getWidgetActualX(new WidgetPointer(912,36))), 0, 0, 1, new WidgetPointer(912,49)); + setWidgetSize(subtract(subtract(getWidgetActualWidth(new WidgetPointer(912,45)), getWidgetActualWidth(new WidgetPointer(912,49))), 2), 0, 0, 1, new WidgetPointer(912,51)); + setWidgetScrollMax(0, 0, new WidgetPointer(912,45)); + cs2method2100(0, 0, new WidgetPointer(912,45)); + script_31(59768878, 59768877, 792, 789, 790, 791, 773, 788); + setWidgetScrollMax(0, 0, new WidgetPointer(912,20)); + cs2method2100(0, 0, new WidgetPointer(912,20)); + script_31(59768853, 59768852, 792, 789, 790, 791, 773, 788); + setScriptCallOnClanChatSettingsStuff(3164, new WidgetPointer(912,49), new WidgetPointer(912,50), new WidgetPointer(912,51), new WidgetPointer(912,47), new WidgetPointer(912,45), new WidgetPointer(912,46), "IIIIII", new WidgetPointer(912,45)); + setScriptCallOnClanChatDeltaStuff(3164, new WidgetPointer(912,49), new WidgetPointer(912,50), new WidgetPointer(912,51), new WidgetPointer(912,47), new WidgetPointer(912,45), new WidgetPointer(912,46), "IIIIII", new WidgetPointer(912,45)); + if (cs2method3751()) { + setWidgetIsHidden(true, new WidgetPointer(912,39)); + script_3165(59768881, 59768882, 59768883, 59768879, 59768877, 59768878); + if (isWidgetHidden(new WidgetPointer(906,189))) { + script_3161(1); + } else { + script_3161(0); + } + } else { + setWidgetIsHidden(false, new WidgetPointer(912,39)); + script_3161(0); + } + globalstring_278 = ""; + script_3024(59768860); + script_3027(59768840); + globalint_1098 = strLength(globalstring_278); + setScriptCallOnMousePressed(1335, -2147483647, new WidgetPointer(912,24), new WidgetPointer(912,25), "iII", new WidgetPointer(912,24)); + script_1390(59768856, 59768857, globalstring_278); + setWidgetIsHidden(true, new WidgetPointer(912,25)); + return; +} diff --git a/dumps/scripts/316.cs2 b/dumps/scripts/316.cs2 new file mode 100644 index 0000000..ae86cd8 --- /dev/null +++ b/dumps/scripts/316.cs2 @@ -0,0 +1,4 @@ +void script_316() { + script_304(44960851); + return; +} diff --git a/dumps/scripts/3160.cs2 b/dumps/scripts/3160.cs2 new file mode 100644 index 0000000..f0f5f6a --- /dev/null +++ b/dumps/scripts/3160.cs2 @@ -0,0 +1,53 @@ +void script_3160(int arg0,int arg1) { + int stack_dump0; + int stack_dump1; + int stack_dump2; + int stack_dump3; + string stack_dump4; + cs2func_script_802_struct(1,1,0) structdump_5; + if (cs2method6900() || ((boolean)script_5280())) { + return; + } + switch (arg0) { + case 84: + if (cs2method3751()) { + if (strLength(globalstring_278) > 0) { + cs2method5006(2); + cs2method5008(globalstring_278); + } + } else { + message(43, 0, "You are not in a Clan."); + } + globalstring_278 = ""; + setWidgetText(new WidgetPointer(912,24), replaceLtGt(globalstring_278)); + globalint_1098 = strLength(globalstring_278); + script_1390(59768856, 59768857, globalstring_278); + break; + case 102: + case 103: + case 98: + case 99: + case 96: + case 97: + globalint_1098 = script_1553(arg0, globalint_1098, globalstring_278); + script_1390(59768856, 59768857, globalstring_278); + break; + case 85: + case 101: + case -1: + if ((isValidChar(((char)arg1)) || (arg0 == 85)) || (arg0 == 101)) { + stack_dump0 = globalint_1098; + stack_dump1 = 0; + stack_dump2 = arg0; + stack_dump3 = arg1; + stack_dump4 = globalstring_278; + structdump_5 = script_802(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + stack_dump4 = structdump_5.stringpart_0; + globalint_1098 = structdump_5.intpart_0; + globalstring_278 = stack_dump4; + setWidgetText(new WidgetPointer(912,24), replaceLtGt(globalstring_278)); + script_1390(59768856, 59768857, globalstring_278); + } + } + return; +} diff --git a/dumps/scripts/3161.cs2 b/dumps/scripts/3161.cs2 new file mode 100644 index 0000000..8a5bda8 --- /dev/null +++ b/dumps/scripts/3161.cs2 @@ -0,0 +1,11 @@ +void script_3161(int arg0) { + if (((boolean)arg0) && cs2method6900()) { + setScriptCallOnKeyPress(3160, -2147483640, false, "iz", new WidgetPointer(912,23)); + setScriptCallOnGameloop(1391, getClientCycle(), new WidgetPointer(912,25), "iI", new WidgetPointer(912,24)); + } else { + setScriptCallOnKeyPress(-1, "", new WidgetPointer(912,23)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(912,24)); + setWidgetText(new WidgetPointer(912,24), replaceLtGt(globalstring_278)); + } + return; +} diff --git a/dumps/scripts/3162.cs2 b/dumps/scripts/3162.cs2 new file mode 100644 index 0000000..afd0cba --- /dev/null +++ b/dumps/scripts/3162.cs2 @@ -0,0 +1,4 @@ +void script_3162() { + script_3184(); + return; +} diff --git a/dumps/scripts/3163.cs2 b/dumps/scripts/3163.cs2 new file mode 100644 index 0000000..ab4472c --- /dev/null +++ b/dumps/scripts/3163.cs2 @@ -0,0 +1,8 @@ +void script_3163() { + if (cs2method3612() > 0) { + sendUnknownVarByteEmptyFriendPacketMethod3620(); + } else { + script_3015(8, "Join Chat Channel", "", "", ""); + } + return; +} diff --git a/dumps/scripts/3164.cs2 b/dumps/scripts/3164.cs2 new file mode 100644 index 0000000..3d6c8fe --- /dev/null +++ b/dumps/scripts/3164.cs2 @@ -0,0 +1,14 @@ +void script_3164(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + if (cs2method3751()) { + script_3165(arg0, arg1, arg2, arg3, arg4, arg5); + if (isWidgetHidden(new WidgetPointer(906,189))) { + script_3161(1); + } else { + script_3161(0); + } + } else { + script_4547(arg0, arg1, arg2, arg3, arg4, arg5); + script_3161(0); + } + return; +} diff --git a/dumps/scripts/3165.cs2 b/dumps/scripts/3165.cs2 new file mode 100644 index 0000000..681748a --- /dev/null +++ b/dumps/scripts/3165.cs2 @@ -0,0 +1,137 @@ +void script_3165(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + string svar0; + string svar1; + string svar2; + if (cs2method5428(arg3, -1)) { + setScriptCallOnGameloop(3164, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), "IIIIII", new WidgetPointer(arg4)); + return; + } + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg4)); + deleteAllExtraChilds(new WidgetPointer(arg0)); + deleteAllExtraChilds(new WidgetPointer(arg1)); + deleteAllExtraChilds(new WidgetPointer(arg2)); + deleteAllExtraChilds(new WidgetPointer(arg3)); + ivar6 = 0; + ivar7 = cs2method3755(); + ivar8 = 0; + svar0 = ""; + ivar9 = 15; + ivar10 = 17; + ivar11 = 0; + ivar12 = 0; + ivar13 = 0; + ivar14 = 0; + ivar15 = 0; + ivar16 = 0; + svar1 = ""; + svar2 = ""; + ivar17 = 0; + ivar18 = script_4468(); + ivar19 = cs2method3760(strRemoveEntities(cs2method5020())); + ivar20 = 0; + if (ivar19 != -1) { + ivar20 = cs2method3757(ivar19); + } + script_1896(); + setWidgetIsHidden(true, new WidgetPointer(912,39)); + setWidgetText(new WidgetPointer(912,17), cs2method3752()); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(912,38)), 4, 0, 1, new WidgetPointer(912,38)); + while (ivar8 < ivar7) { + ivar16 = cs2method3757(ivar8); + svar2 = cs2method3756(ivar8); + svar0 = svar2; + script_2996(arg3, ivar8, getWidgetActualWidth(new WidgetPointer(arg3)), ivar9, 0, ivar12, 0, 1, 0); + if (((boolean)mod(ivar8, 2))) { + setWidgetRGB(new Color(32, 25, 17)); + } else { + setWidgetRGB(new Color(41, 32, 22)); + } + svar1 = "Rank: " + cs2method_3408(105, 115, 3715, ivar16); + setScriptCallOnMouseEntered(3167, new WidgetPointer(arg3), ivar8, svar1, "Iis"); + setScriptCallOnMouseExit(3169, new WidgetPointer(arg3), ivar8, "Ii"); + if (cs2method3760(strRemoveEntities(cs2method5020())) != ivar8) { + setScriptCallOnClickContextMenu(3170, svar2, -2147483644, "si"); + if (isFriend(strRemoveEntities(svar2))) { + setWidgetContextMenuOption(8, "Remove friend " + svar0); + } else if (cs2method3623(strRemoveEntities(svar2))) { + setWidgetContextMenuOption(9, "Remove ignore " + svar0); + } else { + setWidgetContextMenuOption(6, "Add friend " + svar0); + setWidgetContextMenuOption(7, "Add ignore " + svar0); + } + } + if (((boolean)ivar18) && (ivar20 > ivar16)) { + setWidgetContextMenuOption(10, "Kick/ban " + svar0); + } + script_2994(arg1, ivar8, 9, 9, 5, add(ivar12, 2), cs2method_3408(105, 100, 3712, ivar16), 0, 0, 0, 0); + script_2995(arg0, ivar8, 0, ivar9, ivar10, ivar12, 16777215, 494, 0, 1, 0, 1, svar0); + setWidgetSize(ivar10, ivar9, 1, 0); + cs2method1126(1); + ivar13 = cs2method3758(ivar8); + if (((boolean)ivar13)) { + svar0 = "Offline"; + ivar11 = 16711680; + } else { + if (ivar13 >= 1100) { + svar0 = "Lobby " + intToStr(subtract(ivar13, 1099)); + } else { + svar0 = "World " + intToStr(ivar13); + } + if (ivar13 == getWorldId()) { + ivar11 = 65280; + } else { + ivar11 = 16776960; + } + } + script_2995(arg2, ivar8, 0, ivar9, 5, ivar12, ivar11, 494, 0, 1, 0, 1, svar0); + setWidgetSize(5, ivar9, 1, 0); + cs2method1126(1); + ivar12 = add(ivar12, ivar9); + ivar8 = add(ivar8, 1); + } + ivar14 = add(divide(getWidgetActualHeight(new WidgetPointer(arg4)), ivar9), 1); + if (ivar14 > ivar7) { + while (ivar8 < ivar14) { + script_2996(arg3, ivar8, getWidgetActualWidth(new WidgetPointer(arg3)), ivar9, 0, ivar12, 0, 1, 0); + if (((boolean)mod(ivar8, 2))) { + setWidgetRGB(new Color(32, 25, 17)); + } else { + setWidgetRGB(new Color(41, 32, 22)); + } + ivar12 = add(ivar12, ivar9); + ivar8 = add(ivar8, 1); + } + ivar15 = getWidgetActualHeight(new WidgetPointer(arg4)); + } else { + ivar15 = ivar12; + } + if (ivar14 <= ivar7) { + ivar17 = cs2method2601(new WidgetPointer(912,45)); + setWidgetScrollMax(0, ivar15, new WidgetPointer(912,45)); + if (ivar17 > ivar15) { + ivar17 = ivar15; + } + script_72(59768878, 59768877, ivar17); + } else { + setWidgetScrollMax(0, 0, new WidgetPointer(912,45)); + cs2method2100(0, 0, new WidgetPointer(912,45)); + script_72(59768878, 59768877, 0); + } + script_1896(); + return; +} diff --git a/dumps/scripts/3166.cs2 b/dumps/scripts/3166.cs2 new file mode 100644 index 0000000..b239656 --- /dev/null +++ b/dumps/scripts/3166.cs2 @@ -0,0 +1,5 @@ +void script_3166(int arg0,string arg1) { + script_2995(arg0, 0, 0, 0, 0, 0, 16777215, 494, 1, 1, 0, 1, arg1); + setWidgetSize(0, 0, 1, 1); + return; +} diff --git a/dumps/scripts/3167.cs2 b/dumps/scripts/3167.cs2 new file mode 100644 index 0000000..b500f8d --- /dev/null +++ b/dumps/scripts/3167.cs2 @@ -0,0 +1,10 @@ +void script_3167(int arg0,int arg1,string arg2) { + int ivar2; + ivar2 = 59768880; + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetIsHidden(false, new WidgetPointer(ivar2)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(ivar2)), getWidgetActualY(), 0, 0, new WidgetPointer(ivar2)); + setScriptCallOnMouseOver(3168, new WidgetPointer(arg0), arg1, add(getClientCycle(), 25), arg2, -2147483647, -2147483646, "Iiisii"); + } + return; +} diff --git a/dumps/scripts/3168.cs2 b/dumps/scripts/3168.cs2 new file mode 100644 index 0000000..cb5a120 --- /dev/null +++ b/dumps/scripts/3168.cs2 @@ -0,0 +1,22 @@ +void script_3168(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5) { + int ivar5; + int ivar6; + ivar5 = 0; + ivar6 = 0; + if ((getClientCycle() > arg2) && setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetIsHidden(false, new WidgetPointer(912,30)); + setWidgetText(new WidgetPointer(912,34), arg5); + setWidgetSize(add(multiply(getWidgetActualX(new WidgetPointer(912,34)), 2), getTextWidth(495, arg5)), getWidgetActualHeight(new WidgetPointer(912,30)), 0, 0, new WidgetPointer(912,30)); + ivar5 = subtract(add(add(getWidgetActualX(), arg3), 3), cs2method2600(new WidgetPointer(arg0))); + ivar6 = subtract(subtract(subtract(add(add(add(getWidgetActualY(), arg4), getWidgetActualY(new WidgetPointer(912,36))), getWidgetActualY(new WidgetPointer(912,45))), 3), getWidgetActualHeight(new WidgetPointer(912,30))), cs2method2601(new WidgetPointer(912,45))); + if (add(ivar5, getWidgetActualWidth(new WidgetPointer(912,30))) > getWidgetActualWidth(new WidgetPointer(912,29))) { + ivar5 = subtract(getWidgetActualWidth(new WidgetPointer(912,29)), getWidgetActualWidth(new WidgetPointer(912,30))); + } + if (ivar6 < 0) { + ivar6 = 0; + } + setWidgetPosition(ivar5, ivar6, 0, 0, new WidgetPointer(912,30)); + setScriptCallOnMouseOver(-1, ""); + } + return; +} diff --git a/dumps/scripts/3169.cs2 b/dumps/scripts/3169.cs2 new file mode 100644 index 0000000..a608157 --- /dev/null +++ b/dumps/scripts/3169.cs2 @@ -0,0 +1,8 @@ +void script_3169(int arg0,int arg1) { + setWidgetIsHidden(true, new WidgetPointer(912,48)); + setWidgetIsHidden(true, new WidgetPointer(912,30)); + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setScriptCallOnMouseOver(-1, ""); + } + return; +} diff --git a/dumps/scripts/317.cs2 b/dumps/scripts/317.cs2 new file mode 100644 index 0000000..53a4db9 --- /dev/null +++ b/dumps/scripts/317.cs2 @@ -0,0 +1,5 @@ +void script_317(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5,string arg6,string arg7,string arg8,string arg9,string arg10) { + script_319(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + setScriptCallOnItemContainerUpdate(318, new WidgetPointer(arg0), arg1, arg2, arg5, arg6, arg7, arg8, arg9, arg10, arg3, arg4, 93, 1, "IiissssssiiY", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/3170.cs2 b/dumps/scripts/3170.cs2 new file mode 100644 index 0000000..1c4b506 --- /dev/null +++ b/dumps/scripts/3170.cs2 @@ -0,0 +1,23 @@ +void script_3170(int arg0,string arg1) { + int ivar1; + int ivar2; + ivar1 = -1; + ivar2 = -1; + switch (arg0) { + case 6: + cs2method3605(strRemoveEntities(arg1)); + break; + case 7: + cs2method3607(strRemoveEntities(arg1)); + break; + case 8: + cs2method3606(strRemoveEntities(arg1)); + break; + case 9: + cs2method3608(strRemoveEntities(arg1)); + break; + case 10: + script_4465(arg1); + } + return; +} diff --git a/dumps/scripts/3171.cs2 b/dumps/scripts/3171.cs2 new file mode 100644 index 0000000..9474e1f --- /dev/null +++ b/dumps/scripts/3171.cs2 @@ -0,0 +1,9 @@ +void script_3171(int arg0) { + setScriptCallOnFriendListChange(3172, new WidgetPointer(arg0), "I", new WidgetPointer(arg0)); + setScriptCallOnClanListChange(3172, new WidgetPointer(arg0), "I", new WidgetPointer(arg0)); + setScriptCallOnMessage(3172, new WidgetPointer(arg0), "I", new WidgetPointer(arg0)); + setScriptCallOnClanChatDeltaStuff(3172, new WidgetPointer(arg0), "I", new WidgetPointer(arg0)); + setScriptCallOnClanChatSettingsStuff(3172, new WidgetPointer(arg0), "I", new WidgetPointer(arg0)); + script_3173(arg0); + return; +} diff --git a/dumps/scripts/3172.cs2 b/dumps/scripts/3172.cs2 new file mode 100644 index 0000000..00af88d --- /dev/null +++ b/dumps/scripts/3172.cs2 @@ -0,0 +1,4 @@ +void script_3172(int arg0) { + script_3173(arg0); + return; +} diff --git a/dumps/scripts/3173.cs2 b/dumps/scripts/3173.cs2 new file mode 100644 index 0000000..2b6b544 --- /dev/null +++ b/dumps/scripts/3173.cs2 @@ -0,0 +1,72 @@ +void script_3173(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + string svar0; + string svar1; + string svar2; + string svar3; + script_4548(); + if (cs2method5428(59768852, -1)) { + setScriptCallOnGameloop(3172, new WidgetPointer(arg0), "I", new WidgetPointer(arg0)); + return; + } + deleteAllExtraChilds(new WidgetPointer(912,20)); + svar0 = ""; + svar1 = ""; + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + svar2 = ""; + svar3 = ""; + while (ivar1 < 100) { + ivar3 = cs2method5004(ivar1); + svar2 = cs2method5010(ivar1); + svar3 = cs2method5019(ivar1); + switch (ivar3) { + case 43: + case 26: + ivar2 = script_3174(ivar2, 0, ivar3, cs2method5003(ivar1), "", ""); + break; + case 41: + case 44: + ivar2 = script_3174(ivar2, 1, ivar3, "[" + svar0 + cs2method5011(ivar1) + "" + "] " + svar2 + ": " + svar1 + cs2method5003(ivar1), svar2, svar3); + break; + case 42: + ivar2 = script_3174(ivar2, 1, ivar3, "[" + svar0 + cs2method5011(ivar1) + "" + "] " + svar2 + ": " + svar1 + cs2method5003(ivar1), svar2, svar3); + break; + case 115: + ivar2 = script_3174(ivar2, 0, ivar3, "" + cs2method5003(ivar1) + "", "", ""); + } + ivar1 = add(ivar1, 1); + } + ivar4 = divide(getWidgetActualHeight(new WidgetPointer(912,20)), 15); + ivar1 = 0; + ivar5 = 0; + if (ivar2 < ivar4) { + ivar5 = subtract(ivar4, ivar2); + while (ivar1 < ivar5) { + ivar2 = script_3174(ivar2, 0, 0, "", "", ""); + ivar1 = add(ivar1, 1); + } + } + ivar6 = 0; + ivar7 = 0; + while (ivar7 <= ivar2) { + if (setWidgetRegister(new WidgetPointer(912,20), ivar7)) { + ivar6 = add(ivar6, getWidgetActualHeight()); + } + ivar7 = add(ivar7, 1); + } + ivar8 = max(ivar6, multiply(ivar4, 15)); + setWidgetScrollMax(0, ivar8, new WidgetPointer(912,20)); + script_72(59768853, 59768852, subtract(add(globalint_1124, getWidgetScrollMaxV(new WidgetPointer(912,20))), globalint_1125)); + globalint_1124 = cs2method2601(new WidgetPointer(912,20)); + globalint_1125 = getWidgetScrollMaxV(new WidgetPointer(912,20)); + return; +} diff --git a/dumps/scripts/3174.cs2 b/dumps/scripts/3174.cs2 new file mode 100644 index 0000000..70f238e --- /dev/null +++ b/dumps/scripts/3174.cs2 @@ -0,0 +1,53 @@ +int script_3174(int arg0,int arg1,int arg2,string arg3,string arg4,string arg5) { + int ivar3; + int ivar4; + int ivar5; + int ivar6; + ivar3 = getWidgetActualWidth(new WidgetPointer(912,20)); + ivar4 = multiply(max(getLineCount(ivar3, 494, arg3), 1), 15); + createExtraChild(new WidgetPointer(912,20), 4, arg0); + setWidgetPosition(0, multiply(arg0, 15), 0, 2); + setWidgetSize(0, ivar4, 1, 0); + setWidgetRGB(new Color(255, 255, 255)); + setWidgetFont(494); + setWidgetText(arg3); + setWidgetTextAlignment(0, 0, 15); + ivar5 = 0; + ivar6 = 0; + while (ivar6 < arg0) { + if (setWidgetRegister(new WidgetPointer(912,20), ivar6)) { + ivar5 = add(ivar5, getWidgetActualHeight()); + } + ivar6 = add(ivar6, 1); + } + setWidgetPosition(0, ivar5, 0, 2); + if (((boolean)arg1)) { + cs2method1305(strRemoveEntities(arg4)); + setScriptCallOnClickContextMenu(3175, -2147483644, arg4, arg5, "iss"); + switch (arg2) { + case 42: + case 9: + case 41: + case 20: + case 44: + case 45: + if (stringMethod4107(strRemoveEntities(cs2method5020()), strRemoveEntities(arg5)) != 0) { + if (isFriend(strRemoveEntities(arg5)) && cs2method3623(strRemoveEntities(arg5))) { + setWidgetContextMenuOption(1, "Add friend"); + setWidgetContextMenuOption(2, "Add ignore"); + } else { + if (isFriend(strRemoveEntities(arg5)) && cs2method6900()) { + setWidgetContextMenuOption(3, "Message"); + } + } + if ((getClientRights() > 0) || (((int)hasMoreThen5Blackmarks()) > 0)) { + setWidgetContextMenuOption(5, "Report abuse"); + } + if (((boolean)script_4467())) { + setWidgetContextMenuOption(10, "Kick/ban"); + } + } + } + } + return add(arg0, 1); +} diff --git a/dumps/scripts/3175.cs2 b/dumps/scripts/3175.cs2 new file mode 100644 index 0000000..38dafd2 --- /dev/null +++ b/dumps/scripts/3175.cs2 @@ -0,0 +1,27 @@ +void script_3175(int arg0,string arg1,string arg2) { + int ivar1; + int ivar2; + ivar1 = -1; + ivar2 = -1; + switch (arg0) { + case 1: + if (isFriend(strRemoveEntities(arg2))) { + cs2method3605(strRemoveEntities(arg2)); + } + break; + case 2: + if (isFriend(strRemoveEntities(arg2))) { + cs2method3607(strRemoveEntities(arg2)); + } + break; + case 3: + script_3015(0, "Send message to " + arg1, "", arg2, ""); + break; + case 5: + script_3177(0, arg1); + break; + case 10: + script_4465(arg2); + } + return; +} diff --git a/dumps/scripts/3176.cs2 b/dumps/scripts/3176.cs2 new file mode 100644 index 0000000..c6e1c0f --- /dev/null +++ b/dumps/scripts/3176.cs2 @@ -0,0 +1,4 @@ +void script_3176(int arg0,string arg1) { + script_3177(arg0, arg1); + return; +} diff --git a/dumps/scripts/3177.cs2 b/dumps/scripts/3177.cs2 new file mode 100644 index 0000000..cb48cb5 --- /dev/null +++ b/dumps/scripts/3177.cs2 @@ -0,0 +1,18 @@ +void script_3177(int arg0,string arg1) { + int ivar1; + script_41(59768846); + script_41(59572283); + globalstring_279 = ""; + globalint_6 = arg0; + globalint_1094 = 0; + ivar1 = 0; + if (hasMoreThen5Blackmarks() || (getClientRights() > 0)) { + ivar1 = 1; + } + if (((boolean)getLanguage())) { + script_2921(ivar1, getBlackmarks(), arg1); + } else { + script_2920(ivar1, getBlackmarks(), arg1); + } + return; +} diff --git a/dumps/scripts/3178.cs2 b/dumps/scripts/3178.cs2 new file mode 100644 index 0000000..641ebd0 --- /dev/null +++ b/dumps/scripts/3178.cs2 @@ -0,0 +1,10 @@ +void script_3178(int arg0) { + if (((boolean)globalint_6)) { + globalint_6 = 1; + setWidgetSprite(4086, new WidgetPointer(arg0)); + } else { + globalint_6 = 0; + setWidgetSprite(4084, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/3179.cs2 b/dumps/scripts/3179.cs2 new file mode 100644 index 0000000..1d8804b --- /dev/null +++ b/dumps/scripts/3179.cs2 @@ -0,0 +1,4 @@ +void script_3179() { + script_3180(); + return; +} diff --git a/dumps/scripts/318.cs2 b/dumps/scripts/318.cs2 new file mode 100644 index 0000000..93534d0 --- /dev/null +++ b/dumps/scripts/318.cs2 @@ -0,0 +1,4 @@ +void script_318(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5,string arg6,string arg7,string arg8,string arg9,string arg10) { + script_319(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + return; +} diff --git a/dumps/scripts/3180.cs2 b/dumps/scripts/3180.cs2 new file mode 100644 index 0000000..e727c4f --- /dev/null +++ b/dumps/scripts/3180.cs2 @@ -0,0 +1,9 @@ +void script_3180() { + script_3181(); + closeInterface(59375696); + setWidgetIsHidden(true, new WidgetPointer(906,45)); + if (isWidgetHidden(cs2method_3408(105, 73, 941, 5))) { + script_3161(1); + } + return; +} diff --git a/dumps/scripts/3181.cs2 b/dumps/scripts/3181.cs2 new file mode 100644 index 0000000..b3bda87 --- /dev/null +++ b/dumps/scripts/3181.cs2 @@ -0,0 +1,10 @@ +void script_3181() { + setWidgetText(new WidgetPointer(914,27), ""); + setScriptCallOnKeyPress(-1, "", new WidgetPointer(914,27)); + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(914,16)); + setWidgetIsHidden(true, new WidgetPointer(914,21)); + setWidgetSprite(4084, new WidgetPointer(914,23)); + globalstring_277 = ""; + globalint_1094 = 0; + return; +} diff --git a/dumps/scripts/3182.cs2 b/dumps/scripts/3182.cs2 new file mode 100644 index 0000000..58939ba --- /dev/null +++ b/dumps/scripts/3182.cs2 @@ -0,0 +1,4 @@ +void script_3182() { + script_3183(); + return; +} diff --git a/dumps/scripts/3183.cs2 b/dumps/scripts/3183.cs2 new file mode 100644 index 0000000..3dfcb29 --- /dev/null +++ b/dumps/scripts/3183.cs2 @@ -0,0 +1,11 @@ +void script_3183() { + if (strLength(globalstring_277) <= 0) { + return; + } + globalstring_279 = globalstring_277; + script_3180(); + if (strLength(globalstring_279) > 0) { + script_3190(); + } + return; +} diff --git a/dumps/scripts/3184.cs2 b/dumps/scripts/3184.cs2 new file mode 100644 index 0000000..395942c --- /dev/null +++ b/dumps/scripts/3184.cs2 @@ -0,0 +1,20 @@ +void script_3184() { + if (((boolean)globalint_1200)) { + setWidgetText(new WidgetPointer(933,277), globalstring_312); + setWidgetText(new WidgetPointer(933,278), cs2method_3408(105, 115, 2857, globalint_1215)); + setWidgetText(new WidgetPointer(933,279), cs2method_3408(105, 115, 2857, globalint_1216)); + setWidgetText(new WidgetPointer(933,280), cs2method_3408(105, 115, 2857, globalint_1217)); + setWidgetText(new WidgetPointer(933,281), cs2method_3408(105, 115, 2857, globalint_1218)); + setWidgetText(new WidgetPointer(933,282), cs2method_3408(105, 115, 2857, globalint_1219)); + setWidgetText(new WidgetPointer(933,283), cs2method_3408(105, 115, 2857, globalint_1220)); + } else { + setWidgetText(new WidgetPointer(933,277), ""); + setWidgetText(new WidgetPointer(933,278), ""); + setWidgetText(new WidgetPointer(933,279), ""); + setWidgetText(new WidgetPointer(933,280), ""); + setWidgetText(new WidgetPointer(933,281), ""); + setWidgetText(new WidgetPointer(933,282), ""); + setWidgetText(new WidgetPointer(933,283), ""); + } + return; +} diff --git a/dumps/scripts/3185.cs2 b/dumps/scripts/3185.cs2 new file mode 100644 index 0000000..87a080a --- /dev/null +++ b/dumps/scripts/3185.cs2 @@ -0,0 +1,45 @@ +void script_3185(int arg0,int arg1,int arg2) { + int stack_dump0; + int stack_dump1; + int stack_dump2; + int stack_dump3; + string stack_dump4; + cs2func_script_802_struct(1,1,0) structdump_5; + switch (arg0) { + case 84: + script_3183(); + return; + case 13: + script_3180(); + return; + case 102: + case 103: + case 98: + case 99: + case 96: + case 97: + globalint_1097 = script_1553(arg0, globalint_1097, globalstring_277); + script_1879(59899931, 59899932, globalstring_277); + return; + case 85: + case 101: + case -1: + if ((isValidChar(((char)arg1)) || (arg0 == 85)) || (arg0 == 101)) { + if ((arg0 == -1) && ((boolean)strLength(strRemoveEntities(concatChar(((char)arg1), ""))))) { + return; + } + stack_dump0 = globalint_1097; + stack_dump1 = 2; + stack_dump2 = arg0; + stack_dump3 = arg1; + stack_dump4 = globalstring_277; + structdump_5 = script_802(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + stack_dump4 = structdump_5.stringpart_0; + globalint_1097 = structdump_5.intpart_0; + globalstring_277 = stack_dump4; + setWidgetText(new WidgetPointer(arg2), globalstring_277); + script_1879(59899931, 59899932, globalstring_277); + } + } + return; +} diff --git a/dumps/scripts/3186.cs2 b/dumps/scripts/3186.cs2 new file mode 100644 index 0000000..f939c9b --- /dev/null +++ b/dumps/scripts/3186.cs2 @@ -0,0 +1,7 @@ +void script_3186(int arg0,int arg1) { + setWidgetSize(getTextWidth(2710, getWidgetText(new WidgetPointer(arg1))), 0, 0, 1, new WidgetPointer(arg1)); + setWidgetPosition(40, 0, 2, 1, new WidgetPointer(arg1)); + setWidgetSize(38, 31, 0, 0, new WidgetPointer(arg0)); + setWidgetIsHidden(false, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/3187.cs2 b/dumps/scripts/3187.cs2 new file mode 100644 index 0000000..485160c --- /dev/null +++ b/dumps/scripts/3187.cs2 @@ -0,0 +1,6 @@ +void script_3187(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6) { + int ivar7; + ivar7 = getTextWidth(2710, getWidgetText(new WidgetPointer(arg1))); + setScriptCallOnGameloop(3188, new WidgetPointer(arg0), arg2, ivar7, new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), new WidgetPointer(arg6), "I1iIIII", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/3188.cs2 b/dumps/scripts/3188.cs2 new file mode 100644 index 0000000..be0ccfb --- /dev/null +++ b/dumps/scripts/3188.cs2 @@ -0,0 +1,28 @@ +void script_3188(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6) { + int ivar7; + ivar7 = getWidgetActualWidth(new WidgetPointer(arg0)); + if (((boolean)arg1)) { + if (subtract(ivar7, arg2) < 55) { + setWidgetSize(min(add(ivar7, 5), add(55, arg2)), 31, 0, 0, new WidgetPointer(arg0)); + } else { + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + setWidgetSize(add(55, arg2), 31, 0, 0, new WidgetPointer(arg0)); + } + setWidgetSprite(2569, new WidgetPointer(arg3)); + setWidgetSprite(2568, new WidgetPointer(arg4)); + setWidgetSprite(2568, new WidgetPointer(arg5)); + setWidgetSprite(2614, new WidgetPointer(arg6)); + } else { + if (ivar7 > 38) { + setWidgetSize(max(subtract(ivar7, 5), 38), 31, 0, 0, new WidgetPointer(arg0)); + } else { + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + setWidgetSize(38, 31, 0, 0, new WidgetPointer(arg0)); + } + setWidgetSprite(2567, new WidgetPointer(arg3)); + setWidgetSprite(2566, new WidgetPointer(arg4)); + setWidgetSprite(2566, new WidgetPointer(arg5)); + setWidgetSprite(2613, new WidgetPointer(arg6)); + } + return; +} diff --git a/dumps/scripts/3189.cs2 b/dumps/scripts/3189.cs2 new file mode 100644 index 0000000..947f817 --- /dev/null +++ b/dumps/scripts/3189.cs2 @@ -0,0 +1,4 @@ +void script_3189() { + script_3190(); + return; +} diff --git a/dumps/scripts/319.cs2 b/dumps/scripts/319.cs2 new file mode 100644 index 0000000..7592888 --- /dev/null +++ b/dumps/scripts/319.cs2 @@ -0,0 +1,89 @@ +void script_319(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5,string arg6,string arg7,string arg8,string arg9,string arg10) { + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + string svar6; + deleteAllExtraChilds(new WidgetPointer(arg0)); + ivar5 = 0; + ivar6 = 0; + setWidgetScrollMax(0, multiply(add(divide(subtract(arg4, arg3), arg1), 1), 57), new WidgetPointer(arg0)); + ivar7 = 0; + ivar8 = 1; + ivar9 = 0; + ivar10 = 0; + ivar11 = -1; + svar6 = "hello"; + ivar12 = 0; + globalarray_0 = new int[10]; + ivar13 = -1; + ivar14 = 0; + ivar15 = 0; + while (ivar7 <= subtract(arg4, arg3)) { + flow_1: + ivar5 = add(add(16, multiply(mod(ivar7, arg1), 48)), multiply(mod(ivar7, arg1), 5)); + ivar6 = add(multiply(divide(ivar7, arg1), 52), multiply(divide(ivar7, arg1), 5)); + createExtraChild(new WidgetPointer(arg0), 5, ivar15); + ivar15 = add(ivar15, 1); + setWidgetSize(48, 52, 0, 0); + setWidgetPosition(ivar5, ivar6, 0, 0); + setWidgetSprite(2205); + setScriptCallOnMouseEntered(2724, new WidgetPointer(-32768,3), ivar15, 0, "Ii1"); + setScriptCallOnMouseExit(2724, new WidgetPointer(-32768,3), ivar15, 1, "Ii1"); + createExtraChild(new WidgetPointer(arg0), 5, ivar15); + ivar15 = add(ivar15, 1); + setWidgetSize(48, 52, 0, 0); + setWidgetPosition(ivar5, ivar6, 0, 0); + setWidgetSprite(2206); + setWidgetHidden(1); + createExtraChild(new WidgetPointer(arg0), 5, ivar15); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(add(ivar5, 6), add(ivar6, 4), 0, 0); + ivar13 = cs2method_3408(105, 111, 1182, ivar8); + ivar14 = cs2method_3408(111, 105, 1185, getRealItem(ivar13)); + IF (ivar13 == 12292) + GOTO flow_3 + GOTO flow_4 + flow_3: + script_760(ivar13, ivar13, arg0, ivar15, arg5, arg6, arg7, arg8, arg9, arg10); + GOTO flow_8 + flow_4: + IF (getItemAmtInContainer(93, ivar13) > 0) + GOTO flow_5 + IF ((getItemAmtInContainer(93, getNotedItem(ivar13)) > 0) && (getSkillActualLvl(23) >= cs2method_3408(105, 105, 1472, ivar14))) + GOTO flow_6 + GOTO flow_7 + flow_5: + flow_6: + script_760(ivar13, ivar13, arg0, ivar15, arg5, arg6, arg7, arg8, arg9, arg10); + GOTO flow_8 + flow_7: + script_760(cs2method_3408(105, 111, 1183, ivar8), ivar13, arg0, ivar15, arg5, arg6, arg7, arg8, arg9, arg10); + flow_8: + ivar15 = add(ivar15, 1); + createExtraChild(new WidgetPointer(arg0), 5, ivar15); + ivar15 = add(ivar15, 1); + setWidgetSize(12, 12, 0, 0); + setWidgetPosition(add(ivar5, 2), add(ivar6, 38), 0, 0); + setItemOnWidgetMethod1205(12183, 1); + createExtraChild(new WidgetPointer(arg0), 4, ivar15); + ivar15 = add(ivar15, 1); + setWidgetSize(31, 12, 0, 0); + setWidgetPosition(add(ivar5, 13), add(ivar6, 39), 0, 0); + setWidgetFont(494); + setWidgetRGB(new Color(255, 255, 255)); + setWidgetTextAlignment(2, 1, 0); + setWidgetText(script_940(getItemHashmapData(ivar13, 457))); + setWidgetUnknownBoolean(true); + ivar7 = add(ivar7, 1); + ivar8 = add(ivar8, 1); + } + return; +} diff --git a/dumps/scripts/3190.cs2 b/dumps/scripts/3190.cs2 new file mode 100644 index 0000000..4b04a0e --- /dev/null +++ b/dumps/scripts/3190.cs2 @@ -0,0 +1,30 @@ +void script_3190() { + openInterface(59375688, 915); + setWidgetIsHidden(false, new WidgetPointer(906,55)); + if (isWidgetHidden(cs2method_3408(105, 73, 941, 5))) { + script_3161(0); + } + if (strLength(globalstring_279) > 0) { + setWidgetText(new WidgetPointer(915,49), "Reporting: " + globalstring_279); + } else { + setWidgetText(new WidgetPointer(915,49), "Report Abuse"); + } + if (hasMoreThen5Blackmarks() || (getClientRights() > 0)) { + if (((boolean)globalint_6)) { + setWidgetSprite(4084, new WidgetPointer(915,46)); + } else { + setWidgetSprite(4086, new WidgetPointer(915,46)); + } + if ((getBlackmarks() == 5) || (getBlackmarks() == 6)) { + setWidgetText(new WidgetPointer(915,47), "Suggest to mute this player for 48 hours"); + } else { + setWidgetText(new WidgetPointer(915,47), "Mute this player for 48 hours"); + } + setWidgetSize(add(getTextWidth(3793, getWidgetText(new WidgetPointer(915,47))), 18), getWidgetActualHeight(new WidgetPointer(915,45)), 0, 0, new WidgetPointer(915,45)); + setWidgetIsHidden(false, new WidgetPointer(915,45)); + } else { + setWidgetIsHidden(true, new WidgetPointer(915,45)); + } + setScriptCallOnKeyPress(3201, -2147483640, "i", new WidgetPointer(915,18)); + return; +} diff --git a/dumps/scripts/3191.cs2 b/dumps/scripts/3191.cs2 new file mode 100644 index 0000000..9553e97 --- /dev/null +++ b/dumps/scripts/3191.cs2 @@ -0,0 +1,4 @@ +void script_3191() { + script_3192(); + return; +} diff --git a/dumps/scripts/3192.cs2 b/dumps/scripts/3192.cs2 new file mode 100644 index 0000000..76e034a --- /dev/null +++ b/dumps/scripts/3192.cs2 @@ -0,0 +1,5 @@ +void script_3192() { + script_3194(); + script_3177(globalint_6, globalstring_279); + return; +} diff --git a/dumps/scripts/3193.cs2 b/dumps/scripts/3193.cs2 new file mode 100644 index 0000000..c68b7a6 --- /dev/null +++ b/dumps/scripts/3193.cs2 @@ -0,0 +1,4 @@ +void script_3193() { + script_3194(); + return; +} diff --git a/dumps/scripts/3194.cs2 b/dumps/scripts/3194.cs2 new file mode 100644 index 0000000..3e7e9a9 --- /dev/null +++ b/dumps/scripts/3194.cs2 @@ -0,0 +1,10 @@ +void script_3194() { + closeInterface(59375688); + setWidgetIsHidden(true, new WidgetPointer(906,55)); + setScriptCallOnKeyPress(-1, "", new WidgetPointer(915,18)); + globalint_1094 = 0; + if (isWidgetHidden(cs2method_3408(105, 73, 941, 5))) { + script_3161(1); + } + return; +} diff --git a/dumps/scripts/3195.cs2 b/dumps/scripts/3195.cs2 new file mode 100644 index 0000000..6cbda6b --- /dev/null +++ b/dumps/scripts/3195.cs2 @@ -0,0 +1,4 @@ +void script_3195(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + script_3196(arg0, arg1, arg2, arg3, arg4, arg5); + return; +} diff --git a/dumps/scripts/3196.cs2 b/dumps/scripts/3196.cs2 new file mode 100644 index 0000000..d537dd4 --- /dev/null +++ b/dumps/scripts/3196.cs2 @@ -0,0 +1,55 @@ +void script_3196(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + int ivar6; + string svar0; + string svar1; + ivar6 = -1; + svar0 = ""; + svar1 = ""; + switch (arg0) { + case 1: + svar0 = "Help - selecting an offence"; + svar1 = "Here you can select the offence that you believe the player has committed." + "
" + "
" + "Clicking one of the offence buttons will send recent chat to Player Support for investigation. You should act quickly to report the player, particularly in areas where there is a lot of chat, such as at the Grand Exchange." + "
" + "
" + "If you have selected the wrong player, you can use the 'Change player' button to return to the previous page and choose again." + "
" + "
" + "Once your report has been sent, you'll be asked if you want to temporarily add the offender to your Ignore List."; + break; + case 2: + svar0 = "Help - selecting an offence"; + svar1 = "Here you can select the offence that you believe the player has committed." + "
" + "
" + "Clicking one of the offence buttons will send recent chat to Player Support for investigation. You should act quickly to report the player, particularly in areas where there is a lot of chat, such as at the Grand Exchange." + "
" + "
" + "If you have selected the wrong player, you can use the 'Change player' button to return to the chat list and choose again." + "
" + "
" + "You can only report players who have spoken recently." + "
" + "
" + "Once your report has been sent, you'll be asked if you want to temporarily add the offender to your Ignore List."; + break; + case 3: + svar0 = "Help - honour"; + svar1 = "An item scam is defined as cheating another player during a trade. We don't consider it a scam to ask for large amounts of gp for an item, but it is not in the spirit of the game to overprice an item. It is your responsibility to make sure that you are paying a good price." + "
" + "
" + "Asking for someone's bank PIN or recovery answers is just as serious as asking for a password; giving out your bank PIN allows other players access to your bank space. Never tell another player your password, PIN number or any other account security details." + "
" + "
" + "If you notice a bug, please report it to us straight away. If, after noticing a bug, you continue to exploit it, you are likely to have action taken against your account." + "
" + "
" + "There are no cheats for any of our games. Anyone that approaches you in-game to offer you cheats should be reported under 'Encouraging rule-breaking'." + "
" + "
" + "Don't encourage rule-breaking, such as encouraging someone to try real-world trading, scamming or exploiting bugs." + "
" + "
" + "You should not swap your account with another player, or share your account with anyone else. Sharing your account makes it less secure, and is also unfair to other players."; + break; + case 4: + svar0 = "Help - respect"; + svar1 = "There's no need to report anyone for using the term 'noob', it simply means 'new player'." + "
" + "
" + "Seriously offensive language includes racism and chat of a sexual nature." + "
" + "
" + "You don't need to report players for using abbreviations such as 'lmao', 'wtf', 'gtfo'." + "
" + "
" + "You shouldn't report any chat that has been starred out (like this: ****), as the censor has prevented anything that may have been offensive from being seen." + "
" + "
" + "Solicitation includes asking for a boyfriend or girlfriend in-game." + "
" + "
" + "Disruptive behaviour includes flooding the chat window with lines of unnecessary chat, but only if you feel it's impairing your gameplay." + "
" + "
" + "Beware of context when reporting players for real-life threats: they could be talking about in-game combat!"; + break; + case 5: + svar0 = "Help - security"; + svar1 = "Giving out your contact information in-game can put the security of your account at risk. There are some unscrupulous people out there, so, to protect your account and your privacy, it makes sense not to give your details to anyone you don't know." + "
" + "
" + "Contact information includes: full name, email addresses, instant messenger screen names, telephone numbers, your home/work address or age." + "
" + "
" + "Promoting a non-Jagex website in the forums or in-game could get you banned, even if you post the URL for your clan's site. We understand this rule may cause some inconvenience, but we want it to be impossible for people to send players to scam sites."; + break; + case 6: + svar0 = "Help - ignoring a player temporarily"; + svar1 = "Now that your report has been sent, you can choose whether or not to ignore the offender. This is a temporary measure, and will only last until you log out. To permanently ignore a player, make a note of their name and add them to your Ignore List once the 'Report Abuse' windows are closed." + "
" + "
" + "You cannot ignore moderators or people on your Friends List."; + } + setWidgetText(new WidgetPointer(arg1), svar0); + setWidgetText(new WidgetPointer(arg2), svar1); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg3)), add(multiply(getLineCount(getWidgetActualWidth(new WidgetPointer(arg2)), 3793, svar1), 12), 48), 0, 0, new WidgetPointer(arg3)); + switch (arg5) { + case 59834368: + ivar6 = 59375680; + break; + case 59899904: + ivar6 = 59375696; + break; + case 64159744: + ivar6 = 59375670; + break; + case 59965458: + ivar6 = 59375688; + } + if (ivar6 != -1) { + setWidgetSize(getWidgetActualWidth(new WidgetPointer(ivar6)), getWidgetActualHeight(new WidgetPointer(arg3)), 0, 0, new WidgetPointer(ivar6)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg5)), getWidgetActualHeight(new WidgetPointer(arg3)), 0, 0, new WidgetPointer(arg5)); + } + setWidgetIsHidden(false, new WidgetPointer(arg4)); + return; +} diff --git a/dumps/scripts/3197.cs2 b/dumps/scripts/3197.cs2 new file mode 100644 index 0000000..7b1c5ad --- /dev/null +++ b/dumps/scripts/3197.cs2 @@ -0,0 +1,4 @@ +void script_3197(int arg0,int arg1,int arg2,int arg3,int arg4) { + script_3198(arg0, arg1, arg2, arg3, arg4); + return; +} diff --git a/dumps/scripts/3198.cs2 b/dumps/scripts/3198.cs2 new file mode 100644 index 0000000..01dca69 --- /dev/null +++ b/dumps/scripts/3198.cs2 @@ -0,0 +1,32 @@ +void script_3198(int arg0,int arg1,int arg2,int arg3,int arg4) { + int ivar5; + int ivar6; + ivar5 = -1; + ivar6 = 0; + setWidgetIsHidden(true, new WidgetPointer(arg3)); + setWidgetText(new WidgetPointer(arg0), ""); + setWidgetText(new WidgetPointer(arg1), ""); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg2)), 300, 0, 0, new WidgetPointer(arg2)); + switch (arg4) { + case 59834368: + ivar5 = 59375680; + ivar6 = 300; + break; + case 59899904: + ivar5 = 59375696; + ivar6 = 122; + break; + case 64159744: + ivar5 = 59375670; + ivar6 = 303; + break; + case 59965458: + ivar5 = 59375688; + ivar6 = 312; + } + if (ivar5 != -1) { + setWidgetSize(getWidgetActualWidth(new WidgetPointer(ivar5)), ivar6, 0, 0, new WidgetPointer(ivar5)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg4)), ivar6, 0, 0, new WidgetPointer(arg4)); + } + return; +} diff --git a/dumps/scripts/3199.cs2 b/dumps/scripts/3199.cs2 new file mode 100644 index 0000000..30d6043 --- /dev/null +++ b/dumps/scripts/3199.cs2 @@ -0,0 +1,4 @@ +void script_3199(int arg0) { + script_3200(arg0); + return; +} diff --git a/dumps/scripts/32.cs2 b/dumps/scripts/32.cs2 new file mode 100644 index 0000000..9e23e01 --- /dev/null +++ b/dumps/scripts/32.cs2 @@ -0,0 +1,12 @@ +void script_32(int arg0,int arg1) { + int ivar2; + ivar2 = subtract(cs2method2601(new WidgetPointer(arg1)), 4); + switch (arg1) { + case 38666248: + ivar2 = script_4754(arg1, ivar2, 1); + } + if (setWidgetRegister(new WidgetPointer(arg0), 1)) { + script_37(arg0, arg1, ivar2, 1); + } + return; +} diff --git a/dumps/scripts/320.cs2 b/dumps/scripts/320.cs2 new file mode 100644 index 0000000..8e9dc51 --- /dev/null +++ b/dumps/scripts/320.cs2 @@ -0,0 +1,5 @@ +void script_320(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5,string arg6,string arg7,string arg8,string arg9,string arg10) { + script_322(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + setScriptCallOnItemContainerUpdate(321, new WidgetPointer(arg0), arg1, arg2, arg5, arg6, arg7, arg8, arg9, arg10, arg3, arg4, 93, 1, "IiissssssiiY", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/3200.cs2 b/dumps/scripts/3200.cs2 new file mode 100644 index 0000000..4a87747 --- /dev/null +++ b/dumps/scripts/3200.cs2 @@ -0,0 +1,18 @@ +void script_3200(int arg0) { + if (strLength(globalstring_279) > 0) { + cs2method5002(arg0, globalint_6, globalstring_279, ""); + } + script_3194(); + if (((strLength(globalstring_279) > 0) && cs2method3623(globalstring_279)) && (stringMethod4107(globalstring_279, cs2method5015()) != 0)) { + if (arg0 == 5) { + globalint_1094 = 1; + } + script_3203(); + } else { + globalint_1094 = 0; + if (arg0 == 5) { + script_2190(0, 6, 1, "", "Open a bug report form?" + "
" + "(opens a new window)", "", ""); + } + } + return; +} diff --git a/dumps/scripts/3201.cs2 b/dumps/scripts/3201.cs2 new file mode 100644 index 0000000..79fc9e7 --- /dev/null +++ b/dumps/scripts/3201.cs2 @@ -0,0 +1,19 @@ +void script_3201(int arg0) { + switch (arg0) { + case 85: + if (isWidgetHidden(new WidgetPointer(915,102))) { + script_3192(); + } + break; + case 1: + script_3196(1, 59965552, 59965553, 59965550, 59965542, 59965458); + break; + case 13: + if (isWidgetHidden(new WidgetPointer(915,102))) { + script_3198(59965552, 59965553, 59965550, 59965542, 59965458); + } else { + script_3194(); + } + } + return; +} diff --git a/dumps/scripts/3202.cs2 b/dumps/scripts/3202.cs2 new file mode 100644 index 0000000..0453d74 --- /dev/null +++ b/dumps/scripts/3202.cs2 @@ -0,0 +1,4 @@ +void script_3202() { + script_3203(); + return; +} diff --git a/dumps/scripts/3203.cs2 b/dumps/scripts/3203.cs2 new file mode 100644 index 0000000..a239b06 --- /dev/null +++ b/dumps/scripts/3203.cs2 @@ -0,0 +1,9 @@ +void script_3203() { + openInterface(59375680, 913); + setWidgetIsHidden(false, new WidgetPointer(906,56)); + if (isWidgetHidden(cs2method_3408(105, 73, 941, 5))) { + script_3161(0); + } + setScriptCallOnKeyPress(3206, -2147483640, "i", new WidgetPointer(913,0)); + return; +} diff --git a/dumps/scripts/3204.cs2 b/dumps/scripts/3204.cs2 new file mode 100644 index 0000000..95336ab --- /dev/null +++ b/dumps/scripts/3204.cs2 @@ -0,0 +1,4 @@ +void script_3204() { + script_3205(); + return; +} diff --git a/dumps/scripts/3205.cs2 b/dumps/scripts/3205.cs2 new file mode 100644 index 0000000..2f6bed5 --- /dev/null +++ b/dumps/scripts/3205.cs2 @@ -0,0 +1,5 @@ +void script_3205() { + closeInterface(59375680); + setWidgetIsHidden(true, new WidgetPointer(906,56)); + return; +} diff --git a/dumps/scripts/3206.cs2 b/dumps/scripts/3206.cs2 new file mode 100644 index 0000000..a0931e5 --- /dev/null +++ b/dumps/scripts/3206.cs2 @@ -0,0 +1,14 @@ +void script_3206(int arg0) { + switch (arg0) { + case 1: + script_3196(6, 59834382, 59834383, 59834371, 59834370, 59834368); + break; + case 13: + if (isWidgetHidden(new WidgetPointer(913,2))) { + script_3198(59834382, 59834383, 59834371, 59834370, 59834368); + } else { + script_3205(); + } + } + return; +} diff --git a/dumps/scripts/3207.cs2 b/dumps/scripts/3207.cs2 new file mode 100644 index 0000000..999ffc7 --- /dev/null +++ b/dumps/scripts/3207.cs2 @@ -0,0 +1,27 @@ +void script_3207(int arg0) { + int ivar1; + script_3205(); + ivar1 = 0; + if (isWidgetHidden(cs2method_3408(105, 73, 941, 5))) { + ivar1 = 1; + } + if (((boolean)arg0) && (strLength(globalstring_279) > 0)) { + if (isFriend(globalstring_279)) { + if (((boolean)ivar1)) { + message(26, 0, "Sorry, you cannot ignore players in your Friends List."); + } else { + message(26, 0, "Sorry, you cannot ignore players in your Friends List."); + } + } else if (((boolean)ivar1)) { + message(26, 0, "You are ignoring " + globalstring_279 + " until you log out."); + } else { + message(26, 0, "You are ignoring " + globalstring_279 + " until you log out."); + } + cs2method3630(globalstring_279); + } + if (((boolean)globalint_1094)) { + script_3015(6, "", "Open a bug report form?" + "
" + "(opens a new window)", "", ""); + globalint_1094 = 0; + } + return; +} diff --git a/dumps/scripts/3208.cs2 b/dumps/scripts/3208.cs2 new file mode 100644 index 0000000..96a6a34 --- /dev/null +++ b/dumps/scripts/3208.cs2 @@ -0,0 +1,23 @@ +void script_3208(int arg0) { + int ivar1; + int ivar2; + ivar1 = 4055; + ivar2 = 4053; + if (((boolean)arg0)) { + script_3209(); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(673,64)); + setScriptCallOnMouseEntered(-1, "", new WidgetPointer(673,64)); + setWidgetText(new WidgetPointer(673,70), "Please wait..."); + setWidgetText(new WidgetPointer(673,69), "Please wait..."); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(673,26)); + setScriptCallOnMouseEntered(-1, "", new WidgetPointer(673,26)); + } else { + setScriptCallOnMousePressed(2205, "", new WidgetPointer(673,64)); + setScriptCallOnMouseEntered(45, new WidgetPointer(-32768,3), 16448250, "Ii", new WidgetPointer(673,64)); + setWidgetText(new WidgetPointer(673,70), "Continue"); + setWidgetText(new WidgetPointer(673,69), "Continue"); + setScriptCallOnMousePressed(2252, "", new WidgetPointer(673,26)); + setScriptCallOnMouseEntered(3937, new WidgetPointer(673,65), ivar1, new WidgetPointer(673,66), ivar2, new WidgetPointer(673,67), ivar2, new WidgetPointer(673,68), ivar1, "IdIdIdId", new WidgetPointer(673,26)); + } + return; +} diff --git a/dumps/scripts/3209.cs2 b/dumps/scripts/3209.cs2 new file mode 100644 index 0000000..296e1dc --- /dev/null +++ b/dumps/scripts/3209.cs2 @@ -0,0 +1,8 @@ +void script_3209() { + setWidgetIsHidden(true, new WidgetPointer(673,101)); + setWidgetIsHidden(true, new WidgetPointer(673,121)); + setWidgetIsHidden(true, new WidgetPointer(673,92)); + setWidgetIsHidden(true, new WidgetPointer(673,82)); + setWidgetIsHidden(true, new WidgetPointer(673,127)); + return; +} diff --git a/dumps/scripts/321.cs2 b/dumps/scripts/321.cs2 new file mode 100644 index 0000000..f6a286a --- /dev/null +++ b/dumps/scripts/321.cs2 @@ -0,0 +1,4 @@ +void script_321(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5,string arg6,string arg7,string arg8,string arg9,string arg10) { + script_322(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + return; +} diff --git a/dumps/scripts/3210.cs2 b/dumps/scripts/3210.cs2 new file mode 100644 index 0000000..b3d0b9f --- /dev/null +++ b/dumps/scripts/3210.cs2 @@ -0,0 +1,4 @@ +void script_3210() { + script_3211(); + return; +} diff --git a/dumps/scripts/3211.cs2 b/dumps/scripts/3211.cs2 new file mode 100644 index 0000000..8c43cb3 --- /dev/null +++ b/dumps/scripts/3211.cs2 @@ -0,0 +1,10 @@ +void script_3211() { + if (getDisplayMode() < 2) { + setWidgetPosition(-85, 25, 1, 1, new WidgetPointer(673,33)); + setWidgetPosition(-85, 25, 1, 1, new WidgetPointer(673,38)); + } else { + setWidgetPosition(-85, 0, 1, 1, new WidgetPointer(673,33)); + setWidgetPosition(-85, 0, 1, 1, new WidgetPointer(673,38)); + } + return; +} diff --git a/dumps/scripts/3212.cs2 b/dumps/scripts/3212.cs2 new file mode 100644 index 0000000..268623e --- /dev/null +++ b/dumps/scripts/3212.cs2 @@ -0,0 +1,5 @@ +void script_3212(string arg0) { + arg0 = arg0 + "?cty=" + intToStr(cs2method3629()); + script_2934(1, arg0); + return; +} diff --git a/dumps/scripts/3213.cs2 b/dumps/scripts/3213.cs2 new file mode 100644 index 0000000..0d90315 --- /dev/null +++ b/dumps/scripts/3213.cs2 @@ -0,0 +1,127 @@ +void script_3213(int arg0,string arg1) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + string svar1; + string svar2; + flow_0: + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + ivar4 = 0; + ivar5 = 0; + svar1 = "accountappeal"; + svar2 = "passwordchoice.ws"; + SWITCH (arg0) { + case 44105822: + GOTO flow_1 + case 44105841: + GOTO flow_9 + case 44105812: + GOTO flow_17 + case 44105802: + GOTO flow_25 + case 44105777: + GOTO flow_33 + } + setWidgetIsHidden(true, new WidgetPointer(673,31)); + return; + flow_1: + if (strLength(arg1) > 0) { + setWidgetSprite(4061, new WidgetPointer(673,94)); + setWidgetIsHidden(false, new WidgetPointer(673,99)); + setWidgetText(new WidgetPointer(673,30), arg1); + setWidgetText(new WidgetPointer(673,137), arg1); + } else if (getWidgetSpriteId(new WidgetPointer(arg0)) == 4061) { + setWidgetText(new WidgetPointer(673,30), getWidgetText(new WidgetPointer(673,137))); + } else if (getWidgetSpriteId(new WidgetPointer(arg0)) == 4059) { + setWidgetText(new WidgetPointer(673,30), "This email address is available for use."); + } else { + setWidgetText(new WidgetPointer(673,30), "Please enter your email address here."); + } + setWidgetSize(110, add(multiply(getLineCount(subtract(110, 20), 3793, getWidgetText(new WidgetPointer(673,30))), 12), 10), 0, 0, new WidgetPointer(673,31)); + ivar2 = 99; + ivar4 = 450; + GOTO flow_41 + flow_9: + if (strLength(arg1) > 0) { + setWidgetSprite(4061, new WidgetPointer(673,113)); + setWidgetIsHidden(false, new WidgetPointer(673,118)); + setWidgetText(new WidgetPointer(673,30), arg1); + setWidgetText(new WidgetPointer(673,138), arg1); + } else if (getWidgetSpriteId(new WidgetPointer(arg0)) == 4061) { + setWidgetText(new WidgetPointer(673,30), getWidgetText(new WidgetPointer(673,138))); + } else if (getWidgetSpriteId(new WidgetPointer(arg0)) == 4059) { + setWidgetText(new WidgetPointer(673,30), "Both email addresses match."); + } else { + setWidgetText(new WidgetPointer(673,30), "Please enter your email address again here."); + } + setWidgetSize(110, add(multiply(getLineCount(subtract(110, 20), 3793, getWidgetText(new WidgetPointer(673,30))), 12), 10), 0, 0, new WidgetPointer(673,31)); + ivar2 = 128; + ivar4 = 450; + GOTO flow_41 + flow_17: + if (strLength(arg1) > 0) { + setWidgetSprite(4061, new WidgetPointer(673,84)); + setWidgetIsHidden(false, new WidgetPointer(673,89)); + setWidgetText(new WidgetPointer(673,30), arg1); + setWidgetText(new WidgetPointer(673,139), arg1); + } else if (getWidgetSpriteId(new WidgetPointer(arg0)) == 4061) { + setWidgetText(new WidgetPointer(673,30), getWidgetText(new WidgetPointer(673,139))); + } else if (getWidgetSpriteId(new WidgetPointer(arg0)) == 4059) { + setWidgetText(new WidgetPointer(673,30), "You have entered your password."); + } else { + setWidgetText(new WidgetPointer(673,30), "Please enter your desired password here."); + } + setWidgetSize(110, add(multiply(getLineCount(subtract(110, 20), 3793, getWidgetText(new WidgetPointer(673,30))), 12), 10), 0, 0, new WidgetPointer(673,31)); + ivar2 = 161; + ivar4 = 450; + GOTO flow_41 + flow_25: + if (strLength(arg1) > 0) { + setWidgetSprite(4061, new WidgetPointer(673,74)); + setWidgetIsHidden(false, new WidgetPointer(673,79)); + setWidgetText(new WidgetPointer(673,30), arg1); + setWidgetText(new WidgetPointer(673,140), arg1); + } else if (getWidgetSpriteId(new WidgetPointer(arg0)) == 4061) { + setWidgetText(new WidgetPointer(673,30), getWidgetText(new WidgetPointer(673,140))); + } else if (getWidgetSpriteId(new WidgetPointer(arg0)) == 4059) { + setWidgetText(new WidgetPointer(673,30), "Both passwords match."); + } else { + setWidgetText(new WidgetPointer(673,30), "Please enter your desired password again here."); + } + setWidgetSize(110, add(multiply(getLineCount(subtract(110, multiply(10, 2)), 3793, getWidgetText(new WidgetPointer(673,30))), 12), 10), 0, 0, new WidgetPointer(673,31)); + ivar2 = 190; + ivar4 = 450; + GOTO flow_41 + flow_33: + if (strLength(arg1) > 0) { + setWidgetSprite(4061, new WidgetPointer(673,49)); + setWidgetIsHidden(false, new WidgetPointer(673,125)); + setWidgetText(new WidgetPointer(673,30), arg1); + setWidgetText(new WidgetPointer(673,141), arg1); + } else if (getWidgetSpriteId(new WidgetPointer(arg0)) == 4061) { + setWidgetText(new WidgetPointer(673,30), getWidgetText(new WidgetPointer(673,141))); + } else if (getWidgetSpriteId(new WidgetPointer(arg0)) == 4059) { + setWidgetText(new WidgetPointer(673,30), "You have entered your age."); + } else { + setWidgetText(new WidgetPointer(673,30), "Please enter your age, in years, here."); + } + ivar5 = subtract(getWidgetActualWidth(new WidgetPointer(673,38)), 277); + setWidgetSize(min(add(getMaxLineWidth(multiply(divide(getTextWidth(3793, getWidgetText(new WidgetPointer(673,30))), 4), 3), 3793, getWidgetText(new WidgetPointer(673,30))), multiply(10, 2)), ivar5), 30, 0, 0, new WidgetPointer(673,31)); + ivar2 = 223; + ivar4 = 277; + flow_41: + ivar1 = divide(getWidgetActualHeight(new WidgetPointer(673,31)), 2); + ivar3 = subtract(ivar2, ivar1); + setWidgetPosition(ivar4, ivar3, 0, 0, new WidgetPointer(673,31)); + setWidgetIsHidden(false, new WidgetPointer(673,31)); + if (((boolean)stringMethod4107(getWidgetText(new WidgetPointer(673,30)), "Email already in use. Try a different email or click " + "" + "here" + "" + " to recover this account."))) { + setScriptCallOnMousePressed(2931, svar1, svar2, 1, "ss1", new WidgetPointer(673,32)); + } else { + setScriptCallOnMousePressed(-1, "", new WidgetPointer(673,32)); + } + return; +} diff --git a/dumps/scripts/3214.cs2 b/dumps/scripts/3214.cs2 new file mode 100644 index 0000000..9eb1183 --- /dev/null +++ b/dumps/scripts/3214.cs2 @@ -0,0 +1,4 @@ +void script_3214() { + script_2206(); + return; +} diff --git a/dumps/scripts/3215.cs2 b/dumps/scripts/3215.cs2 new file mode 100644 index 0000000..a88d5c5 --- /dev/null +++ b/dumps/scripts/3215.cs2 @@ -0,0 +1,10 @@ +void script_3215(int arg0) { + if (((boolean)arg0)) { + setWidgetContextMenuOption(1, new WidgetPointer(548,99), "Microtutorial"); + setWidgetContextMenuOption(1, new WidgetPointer(746,47), "Microtutorial"); + } else { + setWidgetContextMenuOption(1, new WidgetPointer(548,99), ""); + setWidgetContextMenuOption(1, new WidgetPointer(746,47), ""); + } + return; +} diff --git a/dumps/scripts/3216.cs2 b/dumps/scripts/3216.cs2 new file mode 100644 index 0000000..48ec8a8 --- /dev/null +++ b/dumps/scripts/3216.cs2 @@ -0,0 +1,307 @@ +void script_3216(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + string svar0; + int stack_dump0; + int stack_dump1; + int stack_dump2; + int stack_dump3; + string stack_dump4; + cs2func_script_802_struct(1,1,0) structdump_5; + cs2func_script_802_struct(1,1,0) structdump_6; + cs2func_script_802_struct(1,1,0) structdump_7; + cs2func_script_802_struct(1,1,0) structdump_8; + if (getAccountCreateRC() == -3) { + return; + } + svar0 = ""; + ivar2 = 0; + ivar3 = 0; + ivar4 = 0; + ivar5 = 0; + switch (globalint_174) { + case 6: + switch (arg0) { + case 13: + script_2206(); + return; + case 84: + case 80: + if (globalint_175 >= getClientCycle()) { + return; + } + if ((arg0 == 80) && isHoldingCtrl()) { + script_2714(15, 1); + } else { + script_2714(14, 1); + } + return; + case 102: + case 103: + case 98: + case 99: + case 96: + case 97: + globalint_1099 = script_1553(arg0, globalint_1099, globalstring_122); + script_3218(44105828, 44105772, 44105829, 6, globalstring_122); + return; + } + if (((strLength(globalstring_122) >= 320) && (arg0 != 85)) && (arg0 != 101)) { + return; + } + if (((strIndexof(((char)arg1), 0, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!#$%&'*+-/=?^_.{}~@") != -1) || (arg0 == 85)) || (arg0 == 101)) { + stack_dump0 = globalint_1099; + stack_dump1 = 3; + stack_dump2 = arg0; + stack_dump3 = arg1; + stack_dump4 = globalstring_122; + structdump_5 = script_802(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + stack_dump4 = structdump_5.stringpart_0; + globalint_1099 = structdump_5.intpart_0; + globalstring_122 = stack_dump4; + setWidgetText(new WidgetPointer(673,44), globalstring_122); + script_3218(44105828, 44105772, 44105829, 6, globalstring_122); + } + return; + case 14: + switch (arg0) { + case 13: + script_2206(); + return; + case 84: + case 80: + if (globalint_175 >= getClientCycle()) { + return; + } + if ((arg0 == 80) && isHoldingCtrl()) { + script_2714(6, 1); + } else { + script_2714(7, 1); + } + return; + case 102: + case 103: + case 98: + case 99: + case 96: + case 97: + globalint_1099 = script_1553(arg0, globalint_1099, globalstring_326); + script_3218(44105847, 44105848, 44105849, 14, globalstring_326); + return; + } + if (((strLength(globalstring_326) >= 320) && (arg0 != 85)) && (arg0 != 101)) { + return; + } + if (((strIndexof(((char)arg1), 0, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!#$%&'*+-/=?^_.{}~@") != -1) || (arg0 == 85)) || (arg0 == 101)) { + stack_dump0 = globalint_1099; + stack_dump1 = 3; + stack_dump2 = arg0; + stack_dump3 = arg1; + stack_dump4 = globalstring_326; + structdump_6 = script_802(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + stack_dump4 = structdump_6.stringpart_0; + globalint_1099 = structdump_6.intpart_0; + globalstring_326 = stack_dump4; + setWidgetText(new WidgetPointer(673,120), globalstring_326); + script_3218(44105847, 44105848, 44105849, 14, globalstring_326); + } + return; + case 7: + switch (arg0) { + case 13: + script_2206(); + return; + case 84: + case 80: + if (globalint_175 >= getClientCycle()) { + return; + } + if ((arg0 == 80) && isHoldingCtrl()) { + script_2714(14, 1); + } else { + script_2714(8, 1); + } + return; + case 102: + case 103: + case 98: + case 99: + case 96: + case 97: + globalint_1099 = script_1553(arg0, globalint_1099, globalstring_124); + script_3218(44105818, 44105819, 44105820, 7, script_2949(globalstring_124)); + return; + } + if (((strLength(globalstring_124) > 20) && (arg0 != 85)) && (arg0 != 101)) { + return; + } + stack_dump0 = globalint_1099; + stack_dump1 = 0; + stack_dump2 = arg0; + stack_dump3 = arg1; + stack_dump4 = globalstring_124; + structdump_7 = script_802(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + stack_dump4 = structdump_7.stringpart_0; + globalint_1099 = structdump_7.intpart_0; + globalstring_124 = stack_dump4; + setWidgetText(new WidgetPointer(673,91), script_2949(globalstring_124)); + script_3218(44105818, 44105819, 44105820, 7, script_2949(globalstring_124)); + return; + case 8: + switch (arg0) { + case 13: + script_2206(); + return; + case 84: + case 80: + if (globalint_175 >= getClientCycle()) { + return; + } + if ((arg0 == 80) && isHoldingCtrl()) { + script_2714(7, 1); + } else { + script_2714(15, 1); + } + return; + case 102: + case 103: + case 98: + case 99: + case 96: + case 97: + globalint_1099 = script_1553(arg0, globalint_1099, globalstring_125); + script_3218(44105808, 44105809, 44105810, 8, script_2949(globalstring_125)); + return; + } + if (((strLength(globalstring_125) > 20) && (arg0 != 85)) && (arg0 != 101)) { + return; + } + stack_dump0 = globalint_1099; + stack_dump1 = 0; + stack_dump2 = arg0; + stack_dump3 = arg1; + stack_dump4 = globalstring_125; + structdump_8 = script_802(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + stack_dump4 = structdump_8.stringpart_0; + globalint_1099 = structdump_8.intpart_0; + globalstring_125 = stack_dump4; + setWidgetText(new WidgetPointer(673,81), script_2949(globalstring_125)); + script_3218(44105808, 44105809, 44105810, 8, script_2949(globalstring_125)); + return; + case 15: + switch (arg0) { + case 13: + script_2206(); + return; + case 84: + case 80: + if (globalint_175 >= getClientCycle()) { + return; + } + if ((arg0 == 80) && isHoldingCtrl()) { + script_2714(8, 1); + } else { + if ((((arg0 == 84) && (strLength(globalstring_122) > 0)) && ((strLength(globalstring_326) > 0) && (strLength(globalstring_124) > 0))) && ((strLength(globalstring_125) > 0) && (globalint_1407 != 0))) { + script_2967(0); + return; + } + script_2714(6, 1); + } + return; + case 102: + case 103: + case 98: + case 99: + case 96: + case 97: + globalint_1099 = script_1553(arg0, globalint_1099, intToStr(globalint_1407)); + script_3218(44105854, 44105771, 44105855, 15, intToStr(globalint_1407)); + return; + } + if (((strLength(intToStr(globalint_1407)) >= 3) && (arg0 != 85)) && (arg0 != 101)) { + return; + } + if (strLength(intToStr(globalint_1407)) == 3) { + ivar3 = divide(globalint_1407, 100); + ivar4 = divide(subtract(globalint_1407, multiply(ivar3, 100)), 10); + ivar5 = subtract(globalint_1407, add(multiply(ivar3, 100), multiply(ivar4, 10))); + } else { + if (strLength(intToStr(globalint_1407)) == 2) { + ivar3 = divide(globalint_1407, 10); + ivar4 = subtract(globalint_1407, multiply(ivar3, 10)); + } + } + if (isDigit(((char)arg1))) { + ivar2 = strIndexof(((char)arg1), 0, "0123456789"); + if (globalint_1407 < 1) { + globalint_1407 = ivar2; + } else { + globalint_1407 = add(multiply(globalint_1407, 10), ivar2); + } + globalint_1099 = strLength(intToStr(globalint_1407)); + } else if (arg0 == 85) { + if (globalint_1099 >= 3) { + globalint_1407 = divide(globalint_1407, 10); + } else if (globalint_1099 == 2) { + if (strLength(intToStr(globalint_1407)) == 3) { + globalint_1407 = add(multiply(ivar3, 10), ivar5); + } else if (strLength(intToStr(globalint_1407)) == 2) { + globalint_1407 = divide(globalint_1407, 10); + } else { + globalint_1407 = 0; + globalint_1099 = 0; + } + } else if (((boolean)globalint_1099)) { + if (strLength(intToStr(globalint_1407)) == 3) { + globalint_1407 = subtract(globalint_1407, multiply(ivar3, 100)); + } else if (strLength(intToStr(globalint_1407)) == 2) { + globalint_1407 = subtract(globalint_1407, multiply(ivar3, 10)); + } else { + globalint_1407 = 0; + globalint_1099 = 0; + } + } else { + return; + } + globalint_1099 = max(subtract(globalint_1099, 1), 0); + } else { + if (arg0 == 101) { + if (globalint_1099 >= 3) { + return; + } + if (globalint_1099 == 2) { + if (strLength(intToStr(globalint_1407)) == 3) { + globalint_1407 = divide(globalint_1407, 10); + } else { + globalint_1099 = strLength(intToStr(globalint_1407)); + } + } else if (((boolean)globalint_1099)) { + if (strLength(intToStr(globalint_1407)) == 3) { + globalint_1407 = add(multiply(ivar3, 10), ivar5); + } else if (strLength(intToStr(globalint_1407)) == 2) { + globalint_1407 = divide(globalint_1407, 10); + } else { + return; + } + } else if (strLength(intToStr(globalint_1407)) == 3) { + globalint_1407 = subtract(globalint_1407, multiply(ivar3, 100)); + } else if (strLength(intToStr(globalint_1407)) == 2) { + globalint_1407 = ivar4; + } else { + globalint_1407 = 0; + } + } + } + if (globalint_1407 < 1) { + setWidgetText(new WidgetPointer(673,43), ""); + script_3218(44105854, 44105771, 44105855, 15, ""); + } else { + setWidgetText(new WidgetPointer(673,43), intToStr(globalint_1407)); + script_3218(44105854, 44105771, 44105855, 15, intToStr(globalint_1407)); + } + return; + } + return; +} diff --git a/dumps/scripts/3217.cs2 b/dumps/scripts/3217.cs2 new file mode 100644 index 0000000..3fe9e2c --- /dev/null +++ b/dumps/scripts/3217.cs2 @@ -0,0 +1,32 @@ +void script_3217(int arg0,int arg1,int arg2,int arg3,int arg4) { + string svar0; + if (getAccountCreateRC() == -3) { + return; + } + svar0 = ""; + switch (arg4) { + case 6: + svar0 = globalstring_122; + break; + case 14: + svar0 = globalstring_326; + break; + case 7: + svar0 = script_2949(globalstring_124); + break; + case 8: + svar0 = script_2949(globalstring_125); + break; + case 15: + if (globalint_1407 > 0) { + svar0 = intToStr(globalint_1407); + } + break; + case 16: + svar0 = globalstring_330; + } + globalint_1099 = script_1401(arg0, 3793, 0, svar0); + script_3218(arg1, arg2, arg3, arg4, svar0); + script_2714(arg4, 0); + return; +} diff --git a/dumps/scripts/3218.cs2 b/dumps/scripts/3218.cs2 new file mode 100644 index 0000000..8a41755 --- /dev/null +++ b/dumps/scripts/3218.cs2 @@ -0,0 +1,31 @@ +void script_3218(int arg0,int arg1,int arg2,int arg3,string arg4) { + int ivar4; + int ivar5; + int ivar6; + string svar1; + setWidgetPosition(script_1551(globalint_1099, 3793, add(getWidgetActualX(new WidgetPointer(arg0)), 6), arg4), getWidgetActualY(new WidgetPointer(arg2)), 0, 0, new WidgetPointer(arg2)); + ivar4 = subtract(getWidgetActualWidth(new WidgetPointer(arg0)), 11); + ivar5 = strLength(arg4); + svar1 = ""; + if (globalint_1099 > 0) { + svar1 = substr(0, min(globalint_1099, ivar5), arg4); + } + ivar6 = subtract(getTextWidth(3793, svar1), ivar4); + setWidgetPosition(6, getWidgetActualY(new WidgetPointer(arg1)), 0, 0, new WidgetPointer(arg1)); + setWidgetSize(max(getTextWidth(3793, arg4), ivar4), getWidgetActualHeight(new WidgetPointer(arg1)), 0, 0, new WidgetPointer(arg1)); + if (ivar6 > 0) { + setWidgetPosition(subtract(getWidgetActualX(new WidgetPointer(arg1)), ivar6), getWidgetActualY(new WidgetPointer(arg1)), 0, 0, new WidgetPointer(arg1)); + setWidgetPosition(subtract(getWidgetActualX(new WidgetPointer(arg2)), ivar6), getWidgetActualY(new WidgetPointer(arg2)), 0, 0, new WidgetPointer(arg2)); + } + if (hasWindowFocus()) { + setWidgetIsHidden(false, new WidgetPointer(arg2)); + } else { + setWidgetIsHidden(true, new WidgetPointer(arg2)); + } + if (arg3 == 16) { + setScriptCallOnGameloop(3955, getClientCycle(), new WidgetPointer(arg2), "iI", new WidgetPointer(arg0)); + } else { + setScriptCallOnGameloop(3219, getClientCycle(), new WidgetPointer(arg2), arg3, "iIi", new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/3219.cs2 b/dumps/scripts/3219.cs2 new file mode 100644 index 0000000..6215d21 --- /dev/null +++ b/dumps/scripts/3219.cs2 @@ -0,0 +1,8 @@ +void script_3219(int arg0,int arg1,int arg2) { + if (((globalint_174 == arg2) && (mod(subtract(getClientCycle(), arg0), 40) < 20)) && ((getAccountCreateRC() != -3) && hasWindowFocus())) { + setWidgetIsHidden(false, new WidgetPointer(arg1)); + } else { + setWidgetIsHidden(true, new WidgetPointer(arg1)); + } + return; +} diff --git a/dumps/scripts/322.cs2 b/dumps/scripts/322.cs2 new file mode 100644 index 0000000..5203fd9 --- /dev/null +++ b/dumps/scripts/322.cs2 @@ -0,0 +1,78 @@ +void script_322(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5,string arg6,string arg7,string arg8,string arg9,string arg10) { + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + string svar6; + deleteAllExtraChilds(new WidgetPointer(arg0)); + ivar5 = 0; + ivar6 = 0; + setWidgetScrollMax(0, multiply(add(divide(subtract(arg4, arg3), arg1), 1), 57), new WidgetPointer(arg0)); + ivar7 = 0; + ivar8 = 1; + ivar9 = 0; + ivar10 = 0; + ivar11 = -1; + ivar12 = -1; + ivar13 = -1; + svar6 = "hello"; + ivar14 = 0; + ivar15 = 0; + ivar16 = 0; + while (ivar7 < 78) { + ivar5 = add(add(16, multiply(mod(ivar7, arg1), 48)), multiply(mod(ivar7, arg1), 5)); + ivar6 = add(multiply(divide(ivar7, arg1), 52), multiply(divide(ivar7, arg1), 5)); + createExtraChild(new WidgetPointer(arg0), 5, ivar16); + ivar16 = add(ivar16, 1); + setWidgetSize(48, 52, 0, 0); + setWidgetPosition(ivar5, ivar6, 0, 0); + setWidgetSprite(2205); + setScriptCallOnMouseEntered(2724, new WidgetPointer(-32768,3), ivar16, 0, "Ii1"); + setScriptCallOnMouseExit(2724, new WidgetPointer(-32768,3), ivar16, 1, "Ii1"); + createExtraChild(new WidgetPointer(arg0), 5, ivar16); + ivar16 = add(ivar16, 1); + setWidgetSize(48, 52, 0, 0); + setWidgetPosition(ivar5, ivar6, 0, 0); + setWidgetSprite(2206); + setWidgetHidden(1); + createExtraChild(new WidgetPointer(arg0), 5, ivar16); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(add(ivar5, 6), add(ivar6, 4), 0, 0); + ivar12 = cs2method_3408(105, 111, 1277, ivar8); + ivar13 = cs2method_3408(105, 111, 1188, ivar8); + ivar15 = cs2method_3408(111, 105, 1185, getRealItem(ivar12)); + if (ivar13 == 12421) { + script_1670(ivar13, ivar13, arg0, ivar16, arg5, arg6, arg7, arg8, arg9, arg10); + } else if (((getItemAmtInContainer(93, getRealItem(ivar13)) > 0) && (getItemAmtInContainer(93, getRealItem(ivar13)) >= getItemHashmapData(getRealItem(ivar13), 599))) && (getSkillActualLvl(23) >= cs2method_3408(105, 105, 1472, ivar15))) { + script_1670(ivar13, ivar13, arg0, ivar16, arg5, arg6, arg7, arg8, arg9, arg10); + } else { + script_1670(cs2method_3408(105, 111, 1184, ivar8), ivar13, arg0, ivar16, arg5, arg6, arg7, arg8, arg9, arg10); + } + ivar16 = add(ivar16, 1); + createExtraChild(new WidgetPointer(arg0), 5, ivar16); + ivar16 = add(ivar16, 1); + setWidgetSize(12, 12, 0, 0); + setWidgetPosition(add(ivar5, 2), add(ivar6, 38), 0, 0); + setItemOnWidgetMethod1205(12183, 1); + createExtraChild(new WidgetPointer(arg0), 4, ivar16); + ivar16 = add(ivar16, 1); + setWidgetSize(31, 12, 0, 0); + setWidgetPosition(add(ivar5, 13), add(ivar6, 39), 0, 0); + setWidgetFont(494); + setWidgetRGB(new Color(255, 255, 255)); + setWidgetTextAlignment(2, 1, 0); + setWidgetText(intToStr(max(1, getItemHashmapData(ivar13, 457)))); + setWidgetUnknownBoolean(true); + ivar7 = add(ivar7, 1); + ivar8 = add(ivar8, 1); + } + return; +} diff --git a/dumps/scripts/3220.cs2 b/dumps/scripts/3220.cs2 new file mode 100644 index 0000000..338fc71 --- /dev/null +++ b/dumps/scripts/3220.cs2 @@ -0,0 +1,94 @@ +void script_3220() { + int ivar0; + int ivar1; + string svar0; + string svar1; + flow_0: + ivar0 = getAccountCreateRC(); + if (ivar0 == -3) { + return; + } + setScriptCallOnGameloop(-1, "", new WidgetPointer(673,26)); + ivar1 = 0; + svar0 = "accountappeal"; + svar1 = "passwordchoice.ws"; + IF (ivar0 == 2) + GOTO flow_3 + GOTO flow_4 + flow_3: + cs2method5430(); + script_2223(); + GOTO flow_20 + flow_4: + SWITCH (ivar0) { + case 3: + GOTO flow_5 + case -4: + GOTO flow_5 + case -1: + GOTO flow_5 + case -5: + GOTO flow_6 + case 7: + GOTO flow_7 + case 38: + GOTO flow_8 + case 9: + GOTO flow_8 + case 20: + GOTO flow_9 + case 21: + GOTO flow_10 + case 37: + GOTO flow_11 + case 30: + GOTO flow_12 + case 31: + GOTO flow_18 + case 32: + GOTO flow_19 + case 33: + GOTO flow_19 + } + script_3213(44105822, "Unexpected server response."); + GOTO flow_20 + flow_5: + script_3213(44105822, "Error contacting server."); + GOTO flow_20 + flow_6: + script_3213(44105822, "No response from server."); + GOTO flow_20 + flow_7: + script_3213(44105822, "The server is currently very busy. Please try again shortly."); + GOTO flow_20 + flow_8: + script_3213(44105822, "You cannot create an account at this time. Please try again later."); + GOTO flow_20 + flow_9: + script_3213(44105822, "Email already in use. Try a different email or click " + "" + "here" + "" + " to recover this account."); + GOTO flow_20 + flow_10: + script_3213(44105822, "Please enter a valid Email address."); + GOTO flow_20 + flow_11: + script_3213(44105822, "RuneScape has been updated. Please reload this page."); + GOTO flow_20 + flow_12: + ivar1 = strLength(globalstring_124); + if (ivar1 < 5) { + script_3213(44105812, "Passwords must be at least 5 characters long."); + } else if (ivar1 > 20) { + script_3213(44105812, "Passwords must be no more than " + intToStr(20) + " characters long."); + } else { + script_3213(44105812, "Please supply a valid password."); + } + GOTO flow_20 + flow_18: + script_3213(44105812, "Passwords may only contain letters and numbers."); + GOTO flow_20 + flow_19: + script_3213(44105812, "Your password is too easy to guess."); + flow_20: + script_3208(0); + return; +} diff --git a/dumps/scripts/3221.cs2 b/dumps/scripts/3221.cs2 new file mode 100644 index 0000000..2679738 --- /dev/null +++ b/dumps/scripts/3221.cs2 @@ -0,0 +1,3 @@ +void script_3221(string arg0,string arg1,string arg2,string arg3,string arg4) { + return; +} diff --git a/dumps/scripts/3222.cs2 b/dumps/scripts/3222.cs2 new file mode 100644 index 0000000..5e9ae16 --- /dev/null +++ b/dumps/scripts/3222.cs2 @@ -0,0 +1,92 @@ +int script_3222(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + string svar0; + ivar4 = cs2method_3408(105, 74, 3483, arg1); + ivar5 = 0; + ivar6 = 0; + ivar7 = -1; + ivar8 = 0; + svar0 = ""; + ivar9 = -1; + switch (arg2) { + case 0: + ivar5 = getOtherCommonData(ivar4, 1294); + ivar6 = getOtherCommonData(ivar4, 1295); + break; + case 1: + ivar5 = getOtherCommonData(ivar4, 1296); + ivar6 = getOtherCommonData(ivar4, 1297); + break; + case 2: + ivar5 = getOtherCommonData(ivar4, 1298); + ivar6 = getOtherCommonData(ivar4, 1299); + break; + case 3: + ivar5 = getOtherCommonData(ivar4, 1300); + ivar6 = getOtherCommonData(ivar4, 1301); + break; + case 4: + ivar5 = getOtherCommonData(ivar4, 1302); + ivar6 = getOtherCommonData(ivar4, 1303); + break; + case 5: + ivar5 = getOtherCommonData(ivar4, 1304); + ivar6 = getOtherCommonData(ivar4, 1305); + break; + case 6: + ivar5 = getOtherCommonData(ivar4, 1306); + ivar6 = getOtherCommonData(ivar4, 1307); + break; + case 7: + ivar5 = getOtherCommonData(ivar4, 1308); + ivar6 = getOtherCommonData(ivar4, 1309); + break; + case 8: + ivar5 = getOtherCommonData(ivar4, 1310); + ivar6 = getOtherCommonData(ivar4, 1311); + break; + case 9: + ivar5 = getOtherCommonData(ivar4, 1312); + ivar6 = getOtherCommonData(ivar4, 1313); + } + if (((boolean)ivar5)) { + return arg0; + } + if (ivar5 < 62) { + ivar7 = cs2method_3408(105, 83, 681, ivar5); + if (ivar7 != -1) { + svar0 = "This Task requires " + intToStr(ivar6) + " " + cs2method_3408(105, 115, 108, ivar5) + "."; + if (getSkillCurrentLvl(ivar7) >= ivar6) { + svar0 = concat("", svar0); + } + } + } else if (ivar5 == 62) { + ivar9 = cs2method_3408(105, 74, 2252, ivar6); + svar0 = "To complete this Task, you must complete the " + getOtherCommonData(ivar9, 845) + " quest."; + if (script_2193(ivar6) == 2) { + svar0 = concat("", svar0); + } + } else { + svar0 = script_3223(arg1, add(arg2, 1)); + } + ivar10 = 0; + if (stringMethod4107(svar0, "") != 0) { + setWidgetIsHidden(false, new WidgetPointer(arg3)); + setWidgetText(new WidgetPointer(arg3), svar0); + setWidgetFont(495, new WidgetPointer(arg3)); + setWidgetTextAlignment(0, 1, 0, new WidgetPointer(arg3)); + ivar10 = subtract(getWidgetActualWidth(new WidgetPointer(getWidgetParentId(new WidgetPointer(arg3)))), 18); + ivar8 = multiply(15, getLineCount(ivar10, 495, svar0)); + setWidgetSize(ivar10, ivar8, 0, 0, new WidgetPointer(arg3)); + setWidgetPosition(9, arg0, 0, 0, new WidgetPointer(arg3)); + } else { + ivar8 = 0; + } + return add(arg0, ivar8); +} diff --git a/dumps/scripts/3223.cs2 b/dumps/scripts/3223.cs2 new file mode 100644 index 0000000..be3395e --- /dev/null +++ b/dumps/scripts/3223.cs2 @@ -0,0 +1,371 @@ +string script_3223(int arg0,int arg1) { + int ivar2; + string svar0; + flow_0: + svar0 = ""; + ivar2 = 0; + SWITCH (arg0) { + case 23: + GOTO flow_1 + case 147: + GOTO flow_1 + case 167: + GOTO flow_1 + case 294: + GOTO flow_1 + case 249: + GOTO flow_1 + case 49: + GOTO flow_5 + case 59: + GOTO flow_9 + case 107: + GOTO flow_13 + case 178: + GOTO flow_19 + case 180: + GOTO flow_23 + case 177: + GOTO flow_27 + case 316: + GOTO flow_31 + case 321: + GOTO flow_35 + case 322: + GOTO flow_39 + case 323: + GOTO flow_43 + case 175: + GOTO flow_47 + case 219: + GOTO flow_51 + case 331: + GOTO flow_51 + case 248: + GOTO flow_55 + case 276: + GOTO flow_59 + case 3011: + GOTO flow_59 + case 281: + GOTO flow_63 + case 285: + GOTO flow_70 + case 289: + GOTO flow_74 + case 300: + GOTO flow_78 + case 3000: + GOTO flow_82 + case 3001: + GOTO flow_91 + case 3013: + GOTO flow_91 + case 3002: + GOTO flow_95 + case 12: + GOTO flow_107 + case 3003: + GOTO flow_111 + case 3007: + GOTO flow_115 + case 3008: + GOTO flow_119 + case 3010: + GOTO flow_123 + case 3012: + GOTO flow_127 + case 3015: + GOTO flow_131 + case 3031: + GOTO flow_135 + case 3034: + GOTO flow_139 + } + svar0 = ""; + ivar2 = 0; + GOTO flow_142 + flow_1: + if (((boolean)arg1)) { + svar0 = "You must have access to the fairy ring network to complete this Task."; + if (((boolean)bitconfig_2328)) { + ivar2 = 1; + } + } + GOTO flow_142 + flow_5: + if (((boolean)arg1)) { + svar0 = "You must unlock 500 music tracks in order to perform the Air Guitar emote."; + if (((boolean)bitconfig_4394)) { + ivar2 = 1; + } + } + GOTO flow_142 + flow_9: + if (arg1 == 2) { + svar0 = "You must also have completed the Abyss miniquest."; + if (standart_config_492 >= 4) { + ivar2 = 1; + } + } + GOTO flow_142 + flow_13: + IF (((boolean)arg1)) + GOTO flow_14 + GOTO flow_18 + flow_14: + svar0 = "You must have progressed to a certain point in the Dragon Slayer quest."; + IF (standart_config_176 >= 2) + GOTO flow_15 + GOTO flow_16 + flow_15: + IF (((boolean)bitconfig_3746)) + GOTO flow_17 + flow_16: + IF (standart_config_176 >= 10) + GOTO flow_17 + GOTO flow_18 + flow_17: + ivar2 = 1; + flow_18: + GOTO flow_142 + flow_19: + if (((boolean)arg1)) { + svar0 = "You must begin the relevant section of Otto Godblessed's barbarian training."; + if (bitconfig_3757 > 0) { + ivar2 = 1; + } + } + GOTO flow_142 + flow_23: + if (((boolean)arg1)) { + svar0 = "You must begin the relevant section of Otto Godblessed's barbarian training."; + if (bitconfig_3764 > 0) { + ivar2 = 1; + } + } + GOTO flow_142 + flow_27: + if (((boolean)arg1)) { + svar0 = "You must begin the relevant section of Otto Godblessed's barbarian training."; + if (bitconfig_3764 > 0) { + ivar2 = 1; + } + } + GOTO flow_142 + flow_31: + if (((boolean)arg1)) { + svar0 = "You must begin the relevant section of Otto Godblessed's barbarian training."; + if (bitconfig_3757 > 0) { + ivar2 = 1; + } + } + GOTO flow_142 + flow_35: + if (((boolean)arg1)) { + svar0 = "You must begin the relevant section of Otto Godblessed's barbarian training."; + if (bitconfig_3764 > 0) { + ivar2 = 1; + } + } + GOTO flow_142 + flow_39: + if (((boolean)arg1)) { + svar0 = "You must begin the relevant section of Otto Godblessed's barbarian training."; + if (bitconfig_3763 > 0) { + ivar2 = 1; + } + } + GOTO flow_142 + flow_43: + if (((boolean)arg1)) { + svar0 = "You must begin the relevant section of Otto Godblessed's barbarian training."; + if (bitconfig_3761 > 0) { + ivar2 = 1; + } + } + GOTO flow_142 + flow_47: + if (((boolean)arg1)) { + svar0 = "You must complete the Bar Crawl miniquest."; + if ((standart_config_76 >= 6) || ((boolean)bitconfig_3378)) { + ivar2 = 1; + } + } + GOTO flow_142 + flow_51: + if (arg1 == 2) { + svar0 = "You must have a total combat level of at least 100 to accept an assignment in Shilo Village."; + if (script_1432() >= 100) { + ivar2 = 1; + } + } + GOTO flow_142 + flow_55: + if (((boolean)arg1)) { + svar0 = "You must have completed the Knight Waves in Camelot."; + if (bitconfig_3909 == 8) { + ivar2 = 1; + } + } + GOTO flow_142 + flow_59: + if (((boolean)arg1)) { + svar0 = "You require 33 Quest Points to enter the Champions' Guild."; + if (standart_config_101 >= 33) { + ivar2 = 1; + } + } + GOTO flow_142 + flow_63: + if (((boolean)arg1)) { + svar0 = "You must unlock all four emotes by completing levels of the Stronghold of Security."; + if ((((boolean)bitconfig_2309) && ((boolean)bitconfig_2310)) && (((boolean)bitconfig_2311) && ((boolean)bitconfig_2312))) { + ivar2 = 1; + } + } + GOTO flow_142 + flow_70: + if (((boolean)arg1)) { + svar0 = "You must learn the secret of the Senntisten necklace."; + if (((boolean)bitconfig_3639)) { + ivar2 = 1; + } + } + GOTO flow_142 + flow_74: + if (((boolean)arg1)) { + svar0 = "You must have a total combat level of at least 40 to accept an assignment from Vannaka."; + if (script_1432() >= 40) { + ivar2 = 1; + } + } + GOTO flow_142 + flow_78: + if (((boolean)arg1)) { + svar0 = "Completing quests will increase your access to Kudos with the Varrock Museum."; + if (script_4035() >= 153) { + ivar2 = 1; + } + } + GOTO flow_142 + flow_82: + if (arg1 == 2) { + if (getMinute() >= standart_config_451) { + ivar2 = 1; + } + svar0 = "You may gather the Tears of Guthix once every week."; + } else { + if (arg1 == 3) { + if ((standart_config_101 >= bitconfig_456) || (script_4218() <= 0)) { + ivar2 = 1; + } + svar0 = "You must have gained a Quest Point or 100,000 total experience to enter Juna's cavern."; + } + } + GOTO flow_142 + flow_91: + if (((boolean)arg1)) { + svar0 = "You must have a total combat level of at least 40 to fight for the Void Knights."; + if (getMyCombat() >= 40) { + ivar2 = 1; + } + } + GOTO flow_142 + flow_95: + if (((boolean)arg1)) { + svar0 = "You must have Larry or Chuck explain the purpose of penguin spying."; + if (((boolean)bitconfig_5277)) { + ivar2 = 1; + } + } else if (arg1 == 2) { + svar0 = "You must have spied on fewer than ten penguins already this week."; + if (bitconfig_5276 < 10) { + ivar2 = 1; + } + } else { + if (arg1 == 3) { + svar0 = "You may spy on penguins if your total Penguin Points are less than the maximum of fifty."; + if (bitconfig_5275 < 50) { + ivar2 = 1; + } + } + } + GOTO flow_142 + flow_107: + if (((boolean)arg1)) { + svar0 = "You must have Larry or Chuck explain the purpose of Penguin Hide and Seek."; + if (((boolean)bitconfig_5277)) { + ivar2 = 1; + } + } + GOTO flow_142 + flow_111: + if (((boolean)arg1)) { + svar0 = "You may not chop down more than two evil trees per day."; + if (bitconfig_1545 < 2) { + ivar2 = 1; + } + } + GOTO flow_142 + flow_115: + if (((boolean)arg1)) { + svar0 = "You may attempt the Agility, Magic and Ranged performances after a week has passed since your last show."; + if ((((boolean)bitconfig_5251) || ((boolean)bitconfig_5252)) || ((boolean)bitconfig_5253)) { + ivar2 = 1; + } + } + GOTO flow_142 + flow_119: + if (arg1 == 2) { + svar0 = "You must wait at least a day since you last faced Bork."; + if (standart_config_1199 != getCurrentDaysSinceLaunch()) { + ivar2 = 1; + } + } + GOTO flow_142 + flow_123: + if (arg1 == 2) { + svar0 = "At least a week must pass since you last faced the Skeletal Horror."; + if (getMinute() > bitconfig_6305) { + ivar2 = 1; + } + } + GOTO flow_142 + flow_127: + if (((boolean)arg1)) { + svar0 = "You require 50 Runecrafting to enter the Runecrafters' Guild."; + if (getSkillActualLvl(20) >= 50) { + ivar2 = 1; + } + } + GOTO flow_142 + flow_131: + if (arg1 == 2) { + svar0 = "You must have at least 65 Attack or Defence in order to take on a case."; + if ((getSkillActualLvl(0) >= 65) || (getSkillActualLvl(1) >= 65)) { + ivar2 = 1; + } + } + GOTO flow_142 + flow_135: + if (((boolean)arg1)) { + svar0 = "You must have a total combat level of at least 48 to fight in the Clan Wars."; + if (script_1432() >= 48) { + ivar2 = 1; + } + } + GOTO flow_142 + flow_139: + if (((boolean)arg1)) { + svar0 = "To enter the Warriors' Guild your Attack or Strength level must be 99, or your combined Attack and Strength levels must total 130 or more."; + if (((add(getSkillActualLvl(2), getSkillActualLvl(0)) >= 130) || (getSkillActualLvl(0) >= 99)) || (getSkillActualLvl(2) >= 99)) { + ivar2 = 1; + } + } + flow_142: + if (((boolean)ivar2)) { + svar0 = concat("", svar0); + } + return svar0; +} diff --git a/dumps/scripts/3224.cs2 b/dumps/scripts/3224.cs2 new file mode 100644 index 0000000..a900ab4 --- /dev/null +++ b/dumps/scripts/3224.cs2 @@ -0,0 +1,2464 @@ +int script_3224(int arg0) { + int ivar1; + flow_0: + ivar1 = 0; + SWITCH (arg0) { + case 0: + GOTO flow_1 + case 1: + GOTO flow_4 + case 3: + GOTO flow_7 + case 5: + GOTO flow_10 + case 6: + GOTO flow_13 + case 7: + GOTO flow_16 + case 8: + GOTO flow_21 + case 9: + GOTO flow_24 + case 11: + GOTO flow_27 + case 12: + GOTO flow_30 + case 13: + GOTO flow_33 + case 14: + GOTO flow_36 + case 23: + GOTO flow_39 + case 25: + GOTO flow_42 + case 26: + GOTO flow_49 + case 27: + GOTO flow_52 + case 28: + GOTO flow_57 + case 29: + GOTO flow_60 + case 30: + GOTO flow_65 + case 31: + GOTO flow_70 + case 32: + GOTO flow_73 + case 33: + GOTO flow_76 + case 34: + GOTO flow_81 + case 35: + GOTO flow_84 + case 36: + GOTO flow_87 + case 37: + GOTO flow_90 + case 38: + GOTO flow_93 + case 39: + GOTO flow_96 + case 40: + GOTO flow_99 + case 41: + GOTO flow_102 + case 42: + GOTO flow_105 + case 44: + GOTO flow_108 + case 45: + GOTO flow_113 + case 46: + GOTO flow_118 + case 47: + GOTO flow_121 + case 48: + GOTO flow_124 + case 49: + GOTO flow_129 + case 50: + GOTO flow_132 + case 51: + GOTO flow_137 + case 52: + GOTO flow_140 + case 53: + GOTO flow_143 + case 54: + GOTO flow_146 + case 55: + GOTO flow_149 + case 56: + GOTO flow_152 + case 57: + GOTO flow_155 + case 58: + GOTO flow_160 + case 59: + GOTO flow_163 + case 60: + GOTO flow_170 + case 61: + GOTO flow_175 + case 84: + GOTO flow_178 + case 86: + GOTO flow_181 + case 88: + GOTO flow_184 + case 91: + GOTO flow_189 + case 97: + GOTO flow_192 + case 102: + GOTO flow_195 + case 103: + GOTO flow_198 + case 104: + GOTO flow_201 + case 105: + GOTO flow_206 + case 106: + GOTO flow_209 + case 107: + GOTO flow_212 + case 108: + GOTO flow_216 + case 109: + GOTO flow_219 + case 110: + GOTO flow_222 + case 112: + GOTO flow_225 + case 113: + GOTO flow_228 + case 114: + GOTO flow_231 + case 351: + GOTO flow_234 + case 352: + GOTO flow_237 + case 353: + GOTO flow_240 + case 354: + GOTO flow_243 + case 355: + GOTO flow_246 + case 356: + GOTO flow_249 + case 357: + GOTO flow_252 + case 118: + GOTO flow_255 + case 125: + GOTO flow_258 + case 129: + GOTO flow_261 + case 130: + GOTO flow_264 + case 131: + GOTO flow_267 + case 132: + GOTO flow_270 + case 133: + GOTO flow_273 + case 134: + GOTO flow_280 + case 136: + GOTO flow_283 + case 137: + GOTO flow_286 + case 138: + GOTO flow_289 + case 139: + GOTO flow_292 + case 140: + GOTO flow_299 + case 141: + GOTO flow_302 + case 142: + GOTO flow_309 + case 143: + GOTO flow_312 + case 144: + GOTO flow_317 + case 145: + GOTO flow_322 + case 146: + GOTO flow_327 + case 147: + GOTO flow_330 + case 148: + GOTO flow_333 + case 149: + GOTO flow_336 + case 150: + GOTO flow_339 + case 151: + GOTO flow_342 + case 309: + GOTO flow_349 + case 310: + GOTO flow_352 + case 311: + GOTO flow_355 + case 312: + GOTO flow_358 + case 313: + GOTO flow_363 + case 314: + GOTO flow_368 + case 315: + GOTO flow_373 + case 152: + GOTO flow_378 + case 160: + GOTO flow_381 + case 162: + GOTO flow_384 + case 163: + GOTO flow_387 + case 164: + GOTO flow_390 + case 165: + GOTO flow_393 + case 166: + GOTO flow_398 + case 167: + GOTO flow_403 + case 168: + GOTO flow_406 + case 169: + GOTO flow_409 + case 170: + GOTO flow_412 + case 171: + GOTO flow_417 + case 172: + GOTO flow_422 + case 173: + GOTO flow_425 + case 174: + GOTO flow_428 + case 175: + GOTO flow_433 + case 176: + GOTO flow_439 + case 177: + GOTO flow_442 + case 178: + GOTO flow_449 + case 179: + GOTO flow_456 + case 180: + GOTO flow_461 + case 181: + GOTO flow_464 + case 428: + GOTO flow_467 + case 316: + GOTO flow_470 + case 317: + GOTO flow_477 + case 318: + GOTO flow_484 + case 319: + GOTO flow_489 + case 320: + GOTO flow_492 + case 321: + GOTO flow_495 + case 322: + GOTO flow_502 + case 323: + GOTO flow_507 + case 417: + GOTO flow_512 + case 183: + GOTO flow_521 + case 184: + GOTO flow_524 + case 187: + GOTO flow_527 + case 193: + GOTO flow_530 + case 194: + GOTO flow_533 + case 195: + GOTO flow_536 + case 196: + GOTO flow_539 + case 197: + GOTO flow_544 + case 198: + GOTO flow_547 + case 199: + GOTO flow_552 + case 200: + GOTO flow_555 + case 201: + GOTO flow_558 + case 202: + GOTO flow_563 + case 203: + GOTO flow_566 + case 204: + GOTO flow_569 + case 205: + GOTO flow_572 + case 206: + GOTO flow_575 + case 207: + GOTO flow_578 + case 209: + GOTO flow_581 + case 210: + GOTO flow_584 + case 214: + GOTO flow_589 + case 215: + GOTO flow_594 + case 216: + GOTO flow_599 + case 217: + GOTO flow_612 + case 218: + GOTO flow_619 + case 219: + GOTO flow_624 + case 220: + GOTO flow_631 + case 324: + GOTO flow_636 + case 326: + GOTO flow_639 + case 327: + GOTO flow_646 + case 328: + GOTO flow_649 + case 329: + GOTO flow_652 + case 330: + GOTO flow_657 + case 331: + GOTO flow_662 + case 223: + GOTO flow_669 + case 226: + GOTO flow_672 + case 227: + GOTO flow_675 + case 229: + GOTO flow_678 + case 232: + GOTO flow_681 + case 233: + GOTO flow_684 + case 234: + GOTO flow_687 + case 235: + GOTO flow_690 + case 236: + GOTO flow_693 + case 237: + GOTO flow_696 + case 238: + GOTO flow_699 + case 239: + GOTO flow_702 + case 240: + GOTO flow_705 + case 241: + GOTO flow_708 + case 243: + GOTO flow_715 + case 244: + GOTO flow_720 + case 246: + GOTO flow_723 + case 247: + GOTO flow_726 + case 248: + GOTO flow_729 + case 249: + GOTO flow_734 + case 250: + GOTO flow_737 + case 251: + GOTO flow_740 + case 252: + GOTO flow_743 + case 253: + GOTO flow_750 + case 254: + GOTO flow_753 + case 255: + GOTO flow_758 + case 332: + GOTO flow_761 + case 333: + GOTO flow_766 + case 334: + GOTO flow_773 + case 335: + GOTO flow_778 + case 336: + GOTO flow_783 + case 257: + GOTO flow_788 + case 258: + GOTO flow_791 + case 261: + GOTO flow_794 + case 265: + GOTO flow_797 + case 267: + GOTO flow_800 + case 271: + GOTO flow_803 + case 272: + GOTO flow_806 + case 276: + GOTO flow_809 + case 277: + GOTO flow_812 + case 278: + GOTO flow_815 + case 280: + GOTO flow_818 + case 281: + GOTO flow_821 + case 282: + GOTO flow_830 + case 283: + GOTO flow_835 + case 284: + GOTO flow_838 + case 285: + GOTO flow_841 + case 287: + GOTO flow_846 + case 288: + GOTO flow_849 + case 289: + GOTO flow_852 + case 291: + GOTO flow_855 + case 292: + GOTO flow_858 + case 293: + GOTO flow_861 + case 294: + GOTO flow_864 + case 295: + GOTO flow_867 + case 296: + GOTO flow_870 + case 297: + GOTO flow_873 + case 299: + GOTO flow_876 + case 300: + GOTO flow_879 + case 301: + GOTO flow_882 + case 302: + GOTO flow_885 + case 304: + GOTO flow_888 + case 305: + GOTO flow_891 + case 306: + GOTO flow_894 + case 307: + GOTO flow_897 + case 308: + GOTO flow_900 + case 337: + GOTO flow_903 + case 338: + GOTO flow_906 + case 339: + GOTO flow_909 + case 340: + GOTO flow_912 + case 341: + GOTO flow_919 + case 342: + GOTO flow_924 + case 343: + GOTO flow_927 + case 344: + GOTO flow_932 + case 345: + GOTO flow_937 + case 381: + GOTO flow_940 + case 382: + GOTO flow_943 + case 392: + GOTO flow_946 + case 393: + GOTO flow_949 + case 397: + GOTO flow_952 + case 398: + GOTO flow_955 + case 99: + GOTO flow_958 + case 400: + GOTO flow_961 + case 401: + GOTO flow_964 + case 402: + GOTO flow_967 + case 403: + GOTO flow_970 + case 404: + GOTO flow_973 + case 405: + GOTO flow_976 + case 406: + GOTO flow_979 + case 407: + GOTO flow_982 + case 3000: + GOTO flow_985 + case 3001: + GOTO flow_991 + case 3002: + GOTO flow_994 + case 3003: + GOTO flow_1001 + case 3005: + GOTO flow_1004 + case 3007: + GOTO flow_1007 + case 3008: + GOTO flow_1012 + case 3009: + GOTO flow_1017 + case 3010: + GOTO flow_1020 + case 3011: + GOTO flow_1025 + case 3012: + GOTO flow_1028 + case 3013: + GOTO flow_1031 + case 3015: + GOTO flow_1034 + case 3016: + GOTO flow_1040 + case 3022: + GOTO flow_1045 + case 3023: + GOTO flow_1050 + case 3024: + GOTO flow_1053 + case 3026: + GOTO flow_1056 + case 3031: + GOTO flow_1059 + case 3025: + GOTO flow_1062 + case 3034: + GOTO flow_1065 + case 3500: + GOTO flow_1070 + case 3501: + GOTO flow_1073 + case 3505: + GOTO flow_1076 + case 3511: + GOTO flow_1079 + case 3502: + GOTO flow_1082 + case 3503: + GOTO flow_1085 + case 3504: + GOTO flow_1088 + case 3506: + GOTO flow_1091 + case 3508: + GOTO flow_1094 + case 3509: + GOTO flow_1097 + case 3507: + GOTO flow_1100 + case 3523: + GOTO flow_1103 + case 3510: + GOTO flow_1106 + case 3512: + GOTO flow_1109 + case 3513: + GOTO flow_1112 + case 3514: + GOTO flow_1115 + case 3515: + GOTO flow_1118 + case 3516: + GOTO flow_1121 + case 3517: + GOTO flow_1124 + case 3518: + GOTO flow_1127 + case 3519: + GOTO flow_1130 + case 3520: + GOTO flow_1133 + case 3521: + GOTO flow_1136 + } + return 1; + flow_1: + if (standart_config_63 < 6) { + return 0; + } + GOTO flow_1138 + flow_4: + if (getSkillActualLvl(17) < 5) { + return 0; + } + GOTO flow_1138 + flow_7: + if (standart_config_165 < 29) { + return 0; + } + GOTO flow_1138 + flow_10: + if (getSkillActualLvl(10) < 15) { + return 0; + } + GOTO flow_1138 + flow_13: + if (standart_config_68 < 16) { + return 0; + } + GOTO flow_1138 + flow_16: + if (standart_config_165 < 29) { + return 0; + } + if (standart_config_180 < 6) { + return 0; + } + GOTO flow_1138 + flow_21: + if (bitconfig_3337 < 18) { + return 0; + } + GOTO flow_1138 + flow_24: + if (standart_config_165 < 29) { + return 0; + } + GOTO flow_1138 + flow_27: + if (getSkillActualLvl(17) < 16) { + return 0; + } + GOTO flow_1138 + flow_30: + if (((boolean)bitconfig_5277)) { + return 0; + } + GOTO flow_1138 + flow_33: + if (bitconfig_4302 < 110) { + return 0; + } + GOTO flow_1138 + flow_36: + if (standart_config_30 < 80) { + return 0; + } + GOTO flow_1138 + flow_39: + if (((boolean)bitconfig_2328)) { + return 0; + } + GOTO flow_1138 + flow_42: + if (getSkillActualLvl(16) < 39) { + return 0; + } + if (getSkillActualLvl(4) < 21) { + return 0; + } + if (getSkillActualLvl(2) < 38) { + return 0; + } + GOTO flow_1138 + flow_49: + if (standart_config_63 < 6) { + return 0; + } + GOTO flow_1138 + flow_52: + if (bitconfig_4505 < 100) { + return 0; + } + if (getSkillActualLvl(14) < 46) { + return 0; + } + GOTO flow_1138 + flow_57: + if (getSkillActualLvl(19) < 47) { + return 0; + } + GOTO flow_1138 + flow_60: + if (standart_config_212 < 14) { + return 0; + } + if (getSkillActualLvl(6) < 58) { + return 0; + } + GOTO flow_1138 + flow_65: + if (bitconfig_2866 < 200) { + return 0; + } + if (getSkillActualLvl(11) < 50) { + return 0; + } + GOTO flow_1138 + flow_70: + if (bitconfig_1527 < 160) { + return 0; + } + GOTO flow_1138 + flow_73: + if (bitconfig_5075 < 20) { + return 0; + } + GOTO flow_1138 + flow_76: + if (standart_config_159 < 12) { + return 0; + } + if (getSkillActualLvl(10) < 3) { + return 0; + } + GOTO flow_1138 + flow_81: + if (getSkillActualLvl(16) < 33) { + return 0; + } + GOTO flow_1138 + flow_84: + if (getSkillActualLvl(17) < 38) { + return 0; + } + GOTO flow_1138 + flow_87: + if (getSkillActualLvl(17) < 28) { + return 0; + } + GOTO flow_1138 + flow_90: + if (getSkillActualLvl(14) < 30) { + return 0; + } + GOTO flow_1138 + flow_93: + if (bitconfig_3337 < 18) { + return 0; + } + GOTO flow_1138 + flow_96: + if (standart_config_139 < 75) { + return 0; + } + GOTO flow_1138 + flow_99: + if (standart_config_139 < 75) { + return 0; + } + GOTO flow_1138 + flow_102: + if (getSkillActualLvl(6) < 66) { + return 0; + } + GOTO flow_1138 + flow_105: + if (getSkillActualLvl(6) < 66) { + return 0; + } + GOTO flow_1138 + flow_108: + if (bitconfig_2448 < 190) { + return 0; + } + if (getSkillActualLvl(6) < 71) { + return 0; + } + GOTO flow_1138 + flow_113: + if (getSkillActualLvl(17) < 65) { + return 0; + } + if (getSkillActualLvl(21) < 54) { + return 0; + } + GOTO flow_1138 + flow_118: + if (bitconfig_3337 < 18) { + return 0; + } + GOTO flow_1138 + flow_121: + if (standart_config_365 < 9) { + return 0; + } + GOTO flow_1138 + flow_124: + if (bitconfig_4055 < 65) { + return 0; + } + if (getSkillActualLvl(18) < 59) { + return 0; + } + GOTO flow_1138 + flow_129: + if (((boolean)bitconfig_4394)) { + return 0; + } + GOTO flow_1138 + flow_132: + if (standart_config_165 < 29) { + return 0; + } + if (getSkillActualLvl(6) < 51) { + return 0; + } + GOTO flow_1138 + flow_137: + if (getSkillActualLvl(16) < 57) { + return 0; + } + GOTO flow_1138 + flow_140: + if (getSkillActualLvl(21) < 59) { + return 0; + } + GOTO flow_1138 + flow_143: + if (getSkillActualLvl(19) < 57) { + return 0; + } + GOTO flow_1138 + flow_146: + if (getSkillActualLvl(17) < 59) { + return 0; + } + GOTO flow_1138 + flow_149: + if (bitconfig_4396 < 60) { + return 0; + } + GOTO flow_1138 + flow_152: + if (getSkillActualLvl(10) < 81) { + return 0; + } + GOTO flow_1138 + flow_155: + if (bitconfig_4302 < 110) { + return 0; + } + if (getSkillActualLvl(23) < 93) { + return 0; + } + GOTO flow_1138 + flow_160: + if (getSkillActualLvl(17) < 82) { + return 0; + } + GOTO flow_1138 + flow_163: + if (standart_config_63 < 6) { + return 0; + } + if (standart_config_492 < 4) { + return 0; + } + if (getSkillActualLvl(20) < 75) { + return 0; + } + GOTO flow_1138 + flow_170: + if (getSkillActualLvl(13) < 91) { + return 0; + } + if (getSkillActualLvl(9) < 69) { + return 0; + } + GOTO flow_1138 + flow_175: + if (standart_config_107 < 5) { + return 0; + } + GOTO flow_1138 + flow_178: + if (getSkillActualLvl(10) < 25) { + return 0; + } + GOTO flow_1138 + flow_181: + if (getSkillActualLvl(13) < 30) { + return 0; + } + GOTO flow_1138 + flow_184: + if (standart_config_63 < 6) { + return 0; + } + if (getSkillActualLvl(20) < 5) { + return 0; + } + GOTO flow_1138 + flow_189: + if (standart_config_107 < 5) { + return 0; + } + GOTO flow_1138 + flow_192: + if (standart_config_63 < 6) { + return 0; + } + GOTO flow_1138 + flow_195: + if (getSkillActualLvl(14) < 15) { + return 0; + } + GOTO flow_1138 + flow_198: + if (getSkillActualLvl(14) < 30) { + return 0; + } + GOTO flow_1138 + flow_201: + if (standart_config_29 < 2) { + return 0; + } + if (getSkillActualLvl(7) < 40) { + return 0; + } + GOTO flow_1138 + flow_206: + if (getSkillActualLvl(10) < 30) { + return 0; + } + GOTO flow_1138 + flow_209: + if (getSkillActualLvl(8) < 30) { + return 0; + } + GOTO flow_1138 + flow_212: + if ((standart_config_176 < 2) || (((boolean)bitconfig_3746) && (standart_config_176 < 10))) { + return 0; + } + GOTO flow_1138 + flow_216: + if (getSkillActualLvl(13) < 36) { + return 0; + } + GOTO flow_1138 + flow_219: + if (getSkillActualLvl(6) < 31) { + return 0; + } + GOTO flow_1138 + flow_222: + if (getSkillActualLvl(11) < 30) { + return 0; + } + GOTO flow_1138 + flow_225: + if (getSkillActualLvl(14) < 20) { + return 0; + } + GOTO flow_1138 + flow_228: + if (getSkillActualLvl(13) < 20) { + return 0; + } + GOTO flow_1138 + flow_231: + if (getSkillActualLvl(12) < 16) { + return 0; + } + GOTO flow_1138 + flow_234: + if (getSkillActualLvl(13) < 68) { + return 0; + } + GOTO flow_1138 + flow_237: + if (((getSkillActualLvl(6) < 49) || (getSkillActualLvl(12) < 50)) || (getSkillActualLvl(13) < 40)) { + return 0; + } + GOTO flow_1138 + flow_240: + if (getSkillActualLvl(7) < 50) { + return 0; + } + GOTO flow_1138 + flow_243: + if (getSkillActualLvl(6) < 59) { + return 0; + } + GOTO flow_1138 + flow_246: + if (getSkillActualLvl(5) < 45) { + return 0; + } + GOTO flow_1138 + flow_249: + if (getSkillActualLvl(20) < 57) { + return 0; + } + GOTO flow_1138 + flow_252: + if (getSkillActualLvl(11) < 60) { + return 0; + } + GOTO flow_1138 + flow_255: + if (getSkillActualLvl(22) < 16) { + return 0; + } + GOTO flow_1138 + flow_258: + if (standart_config_63 < 6) { + return 0; + } + GOTO flow_1138 + flow_261: + if (getSkillActualLvl(1) < 10) { + return 0; + } + GOTO flow_1138 + flow_264: + if (getSkillActualLvl(12) < 36) { + return 0; + } + GOTO flow_1138 + flow_267: + if (getSkillActualLvl(16) < 26) { + return 0; + } + GOTO flow_1138 + flow_270: + if (bitconfig_961 < 60) { + return 0; + } + GOTO flow_1138 + flow_273: + if (getSkillActualLvl(16) < 11) { + return 0; + } + if (getSkillActualLvl(4) < 19) { + return 0; + } + if (getSkillActualLvl(2) < 37) { + return 0; + } + GOTO flow_1138 + flow_280: + if (bitconfig_1051 < 10) { + return 0; + } + GOTO flow_1138 + flow_283: + if (getSkillActualLvl(11) < 49) { + return 0; + } + GOTO flow_1138 + flow_286: + if (getSkillActualLvl(17) < 40) { + return 0; + } + GOTO flow_1138 + flow_289: + if (getSkillActualLvl(19) < 23) { + return 0; + } + GOTO flow_1138 + flow_292: + if (standart_config_122 < 7) { + return 0; + } + if (getSkillActualLvl(14) < 10) { + return 0; + } + if (getSkillActualLvl(13) < 13) { + return 0; + } + GOTO flow_1138 + flow_299: + if (bitconfig_1404 < 127) { + return 0; + } + GOTO flow_1138 + flow_302: + if (bitconfig_657 < 2) { + return 0; + } + if (getSkillActualLvl(1) < 20) { + return 0; + } + if (getSkillActualLvl(5) < 10) { + return 0; + } + GOTO flow_1138 + flow_309: + if (bitconfig_1527 < 160) { + return 0; + } + GOTO flow_1138 + flow_312: + if (getSkillActualLvl(5) < 70) { + return 0; + } + if (getSkillActualLvl(22) < 16) { + return 0; + } + GOTO flow_1138 + flow_317: + if (standart_config_63 < 6) { + return 0; + } + if (getSkillActualLvl(20) < 56) { + return 0; + } + GOTO flow_1138 + flow_322: + if (getSkillActualLvl(19) < 60) { + return 0; + } + if (getSkillActualLvl(8) < 60) { + return 0; + } + GOTO flow_1138 + flow_327: + if (getSkillActualLvl(14) < 60) { + return 0; + } + GOTO flow_1138 + flow_330: + if (((boolean)bitconfig_2328)) { + return 0; + } + GOTO flow_1138 + flow_333: + if (getSkillActualLvl(18) < 32) { + return 0; + } + GOTO flow_1138 + flow_336: + if (getSkillActualLvl(18) < 72) { + return 0; + } + GOTO flow_1138 + flow_339: + if (getSkillActualLvl(23) < 56) { + return 0; + } + GOTO flow_1138 + flow_342: + if (bitconfig_2610 < 14) { + return 0; + } + if (getSkillActualLvl(1) < 30) { + return 0; + } + if (getSkillActualLvl(5) < 20) { + return 0; + } + GOTO flow_1138 + flow_349: + if (getSkillActualLvl(10) < 90) { + return 0; + } + GOTO flow_1138 + flow_352: + if (getSkillActualLvl(7) < 93) { + return 0; + } + GOTO flow_1138 + flow_355: + if (getSkillActualLvl(14) < 80) { + return 0; + } + GOTO flow_1138 + flow_358: + if (getSkillActualLvl(19) < 75) { + return 0; + } + if (getSkillActualLvl(8) < 75) { + return 0; + } + GOTO flow_1138 + flow_363: + if (bitconfig_4302 < 110) { + return 0; + } + if (getSkillActualLvl(23) < 80) { + return 0; + } + GOTO flow_1138 + flow_368: + if (bitconfig_2448 < 190) { + return 0; + } + if (getSkillActualLvl(6) < 80) { + return 0; + } + GOTO flow_1138 + flow_373: + if (getSkillActualLvl(5) < 95) { + return 0; + } + if (bitconfig_6775 < 90) { + return 0; + } + GOTO flow_1138 + flow_378: + if (getSkillActualLvl(18) < 10) { + return 0; + } + GOTO flow_1138 + flow_381: + if (bitconfig_4302 < 110) { + return 0; + } + GOTO flow_1138 + flow_384: + if (standart_config_347 < 10) { + return 0; + } + GOTO flow_1138 + flow_387: + if (standart_config_347 < 10) { + return 0; + } + GOTO flow_1138 + flow_390: + if (standart_config_347 < 10) { + return 0; + } + GOTO flow_1138 + flow_393: + if (standart_config_347 < 10) { + return 0; + } + if (getSkillActualLvl(12) < 33) { + return 0; + } + GOTO flow_1138 + flow_398: + if (standart_config_347 < 10) { + return 0; + } + if (bitconfig_961 < 60) { + return 0; + } + GOTO flow_1138 + flow_403: + if (((boolean)bitconfig_2328)) { + return 0; + } + GOTO flow_1138 + flow_406: + if (standart_config_347 < 10) { + return 0; + } + GOTO flow_1138 + flow_409: + if (getSkillActualLvl(21) < 55) { + return 0; + } + GOTO flow_1138 + flow_412: + if (standart_config_347 < 10) { + return 0; + } + if (getSkillActualLvl(1) < 20) { + return 0; + } + GOTO flow_1138 + flow_417: + if (standart_config_347 < 10) { + return 0; + } + if (getSkillActualLvl(7) < 48) { + return 0; + } + GOTO flow_1138 + flow_422: + if (getSkillActualLvl(17) < 42) { + return 0; + } + GOTO flow_1138 + flow_425: + if (standart_config_347 < 10) { + return 0; + } + GOTO flow_1138 + flow_428: + if (standart_config_347 < 10) { + return 0; + } + if (getSkillActualLvl(1) < 40) { + return 0; + } + GOTO flow_1138 + flow_433: + if ((standart_config_76 < 6) && ((boolean)bitconfig_3378)) { + return 0; + } + if (getSkillActualLvl(16) < 35) { + return 0; + } + GOTO flow_1138 + flow_439: + if (bitconfig_2448 < 190) { + return 0; + } + GOTO flow_1138 + flow_442: + if (((boolean)bitconfig_3764)) { + return 0; + } + if (getSkillActualLvl(12) < 52) { + return 0; + } + if (getSkillActualLvl(11) < 52) { + return 0; + } + GOTO flow_1138 + flow_449: + if (((boolean)bitconfig_3757)) { + return 0; + } + if (getSkillActualLvl(2) < 35) { + return 0; + } + if (getSkillActualLvl(10) < 55) { + return 0; + } + GOTO flow_1138 + flow_456: + if (bitconfig_2448 < 190) { + return 0; + } + if (getSkillActualLvl(6) < 65) { + return 0; + } + GOTO flow_1138 + flow_461: + if (((boolean)bitconfig_3764)) { + return 0; + } + GOTO flow_1138 + flow_464: + if (bitconfig_2140 < 30) { + return 0; + } + GOTO flow_1138 + flow_467: + if ((((((bitconfig_2448 < 190) || (getSkillActualLvl(6) < 70)) || (getSkillActualLvl(19) < 60)) || (getSkillActualLvl(16) < 60)) || (getSkillActualLvl(12) < 60)) || (getSkillActualLvl(22) < 50)) { + return 0; + } + GOTO flow_1138 + flow_470: + if (((boolean)bitconfig_3757)) { + return 0; + } + if (getSkillActualLvl(10) < 96) { + return 0; + } + if (getSkillActualLvl(2) < 76) { + return 0; + } + GOTO flow_1138 + flow_477: + if (getSkillActualLvl(16) < 90) { + return 0; + } + if (getSkillActualLvl(3) < 35) { + return 0; + } + if (getSkillActualLvl(1) < 35) { + return 0; + } + GOTO flow_1138 + flow_484: + if (bitconfig_2448 < 190) { + return 0; + } + if (getSkillActualLvl(20) < 82) { + return 0; + } + GOTO flow_1138 + flow_489: + if (getSkillActualLvl(18) < 93) { + return 0; + } + GOTO flow_1138 + flow_492: + if (getSkillActualLvl(16) < 81) { + return 0; + } + GOTO flow_1138 + flow_495: + if (((boolean)bitconfig_3764)) { + return 0; + } + if (getSkillActualLvl(12) < 85) { + return 0; + } + if (getSkillActualLvl(11) < 85) { + return 0; + } + GOTO flow_1138 + flow_502: + if (((boolean)bitconfig_3763)) { + return 0; + } + if (getSkillActualLvl(13) < 90) { + return 0; + } + GOTO flow_1138 + flow_507: + if (((boolean)bitconfig_3761)) { + return 0; + } + if (getSkillActualLvl(15) < 80) { + return 0; + } + GOTO flow_1138 + flow_512: + if (bitconfig_6883 < 147) { + return 0; + } + if (getSkillActualLvl(0) < 75) { + return 0; + } + if (getSkillActualLvl(2) < 75) { + return 0; + } + if (getSkillActualLvl(18) < 65) { + return 0; + } + GOTO flow_1138 + flow_521: + if (getSkillActualLvl(16) < 10) { + return 0; + } + GOTO flow_1138 + flow_524: + if (getSkillActualLvl(14) < 40) { + return 0; + } + GOTO flow_1138 + flow_527: + if (getSkillActualLvl(16) < 15) { + return 0; + } + GOTO flow_1138 + flow_530: + if (standart_config_176 < 8) { + return 0; + } + GOTO flow_1138 + flow_533: + if (standart_config_176 < 8) { + return 0; + } + GOTO flow_1138 + flow_536: + if (standart_config_116 < 15) { + return 0; + } + GOTO flow_1138 + flow_539: + if (standart_config_175 < 12) { + return 0; + } + if (getSkillActualLvl(8) < 10) { + return 0; + } + GOTO flow_1138 + flow_544: + if (getSkillActualLvl(7) < 16) { + return 0; + } + GOTO flow_1138 + flow_547: + if (standart_config_116 < 15) { + return 0; + } + if (getSkillActualLvl(14) < 40) { + return 0; + } + GOTO flow_1138 + flow_552: + if (getSkillActualLvl(8) < 35) { + return 0; + } + GOTO flow_1138 + flow_555: + if (getSkillActualLvl(8) < 50) { + return 0; + } + GOTO flow_1138 + flow_558: + if (standart_config_320 < 6) { + return 0; + } + if (getSkillActualLvl(10) < 65) { + return 0; + } + GOTO flow_1138 + flow_563: + if (standart_config_175 < 12) { + return 0; + } + GOTO flow_1138 + flow_566: + if (standart_config_150 < 160) { + return 0; + } + GOTO flow_1138 + flow_569: + if (getSkillActualLvl(19) < 27) { + return 0; + } + GOTO flow_1138 + flow_572: + if (getSkillActualLvl(21) < 41) { + return 0; + } + GOTO flow_1138 + flow_575: + if (getSkillActualLvl(8) < 10) { + return 0; + } + GOTO flow_1138 + flow_578: + if (getSkillActualLvl(16) < 12) { + return 0; + } + GOTO flow_1138 + flow_581: + if (standart_config_116 < 15) { + return 0; + } + GOTO flow_1138 + flow_584: + if (standart_config_150 < 160) { + return 0; + } + if (standart_config_365 < 9) { + return 0; + } + GOTO flow_1138 + flow_589: + if (standart_config_63 < 6) { + return 0; + } + if (getSkillActualLvl(20) < 44) { + return 0; + } + GOTO flow_1138 + flow_594: + if (standart_config_320 < 6) { + return 0; + } + if (getSkillActualLvl(7) < 30) { + return 0; + } + GOTO flow_1138 + flow_599: + if (standart_config_139 < 75) { + return 0; + } + if (getSkillActualLvl(8) < 15) { + return 0; + } + if (getSkillActualLvl(16) < 50) { + return 0; + } + if (getSkillActualLvl(2) < 50) { + return 0; + } + if (getSkillActualLvl(17) < 50) { + return 0; + } + if (getSkillActualLvl(14) < 52) { + return 0; + } + GOTO flow_1138 + flow_612: + if (getSkillActualLvl(16) < 53) { + return 0; + } + if (getSkillActualLvl(4) < 42) { + return 0; + } + if (getSkillActualLvl(2) < 21) { + return 0; + } + GOTO flow_1138 + flow_619: + if (standart_config_139 < 75) { + return 0; + } + if (getSkillActualLvl(8) < 15) { + return 0; + } + GOTO flow_1138 + flow_624: + if (standart_config_116 < 15) { + return 0; + } + if (getSkillActualLvl(18) < 50) { + return 0; + } + if (script_1432() < 100) { + return 0; + } + GOTO flow_1138 + flow_631: + if (getSkillActualLvl(16) < 12) { + return 0; + } + if (getSkillActualLvl(8) < 34) { + return 0; + } + GOTO flow_1138 + flow_636: + if (getSkillActualLvl(20) < 91) { + return 0; + } + GOTO flow_1138 + flow_639: + if (bitconfig_4302 < 110) { + return 0; + } + if (getSkillActualLvl(23) < 95) { + return 0; + } + if (getSkillActualLvl(21) < 27) { + return 0; + } + GOTO flow_1138 + flow_646: + if (getSkillActualLvl(15) < 63) { + return 0; + } + GOTO flow_1138 + flow_649: + if (getSkillActualLvl(7) < 80) { + return 0; + } + GOTO flow_1138 + flow_652: + if (bitconfig_4302 < 110) { + return 0; + } + if (getSkillActualLvl(23) < 90) { + return 0; + } + GOTO flow_1138 + flow_657: + if (standart_config_116 < 15) { + return 0; + } + if (getSkillActualLvl(16) < 74) { + return 0; + } + GOTO flow_1138 + flow_662: + if (getMyCombat() < 100) { + return 0; + } + if (getSkillActualLvl(18) < 50) { + return 0; + } + if (bitconfig_5491 < 910) { + return 0; + } + GOTO flow_1138 + flow_669: + if (getSkillActualLvl(19) < 13) { + return 0; + } + GOTO flow_1138 + flow_672: + if (getSkillActualLvl(12) < 10) { + return 0; + } + GOTO flow_1138 + flow_675: + if (standart_config_192 < 2) { + return 0; + } + GOTO flow_1138 + flow_678: + if (getSkillActualLvl(7) < 21) { + return 0; + } + GOTO flow_1138 + flow_681: + if (getSkillActualLvl(10) < 16) { + return 0; + } + GOTO flow_1138 + flow_684: + if (getSkillActualLvl(16) < 48) { + return 0; + } + GOTO flow_1138 + flow_687: + if (standart_config_76 < 6) { + return 0; + } + GOTO flow_1138 + flow_690: + if (getSkillActualLvl(14) < 30) { + return 0; + } + GOTO flow_1138 + flow_693: + if (bitconfig_2067 < 1) { + return 0; + } + GOTO flow_1138 + flow_696: + if (getSkillActualLvl(6) < 45) { + return 0; + } + GOTO flow_1138 + flow_699: + if (getSkillActualLvl(4) < 40) { + return 0; + } + GOTO flow_1138 + flow_702: + if (getSkillActualLvl(4) < 40) { + return 0; + } + GOTO flow_1138 + flow_705: + if (standart_config_416 < 280) { + return 0; + } + GOTO flow_1138 + flow_708: + if (bitconfig_4302 < 110) { + return 0; + } + if (getSkillActualLvl(11) < 45) { + return 0; + } + if (getSkillActualLvl(23) < 46) { + return 0; + } + GOTO flow_1138 + flow_715: + if (getSkillActualLvl(10) < 46) { + return 0; + } + if (getSkillActualLvl(7) < 43) { + return 0; + } + GOTO flow_1138 + flow_720: + if (getSkillActualLvl(4) < 40) { + return 0; + } + GOTO flow_1138 + flow_723: + if (getSkillActualLvl(8) < 60) { + return 0; + } + GOTO flow_1138 + flow_726: + if (getSkillActualLvl(9) < 80) { + return 0; + } + GOTO flow_1138 + flow_729: + if (bitconfig_3909 < 8) { + return 0; + } + if (getSkillActualLvl(5) < 70) { + return 0; + } + GOTO flow_1138 + flow_734: + if (((boolean)bitconfig_2328)) { + return 0; + } + GOTO flow_1138 + flow_737: + if (getSkillActualLvl(11) < 75) { + return 0; + } + GOTO flow_1138 + flow_740: + if (getSkillActualLvl(6) < 55) { + return 0; + } + GOTO flow_1138 + flow_743: + if (getSkillActualLvl(2) < 22) { + return 0; + } + if (getSkillActualLvl(16) < 36) { + return 0; + } + if (getSkillActualLvl(4) < 39) { + return 0; + } + GOTO flow_1138 + flow_750: + if (getSkillActualLvl(10) < 76) { + return 0; + } + GOTO flow_1138 + flow_753: + if (standart_config_148 < 11) { + return 0; + } + if (getSkillActualLvl(7) < 80) { + return 0; + } + GOTO flow_1138 + flow_758: + if (getSkillActualLvl(6) < 56) { + return 0; + } + GOTO flow_1138 + flow_761: + if (getSkillActualLvl(10) < 35) { + return 0; + } + if (getSkillActualLvl(7) < 70) { + return 0; + } + GOTO flow_1138 + flow_766: + if (getSkillActualLvl(13) < 73) { + return 0; + } + if (getSkillActualLvl(9) < 65) { + return 0; + } + if (getSkillActualLvl(6) < 57) { + return 0; + } + GOTO flow_1138 + flow_773: + if (getSkillActualLvl(9) < 85) { + return 0; + } + if (getSkillActualLvl(12) < 10) { + return 0; + } + GOTO flow_1138 + flow_778: + if (getSkillActualLvl(15) < 92) { + return 0; + } + if (getSkillActualLvl(4) < 40) { + return 0; + } + GOTO flow_1138 + flow_783: + if (getSkillActualLvl(6) < 83) { + return 0; + } + if (bitconfig_2448 < 190) { + return 0; + } + GOTO flow_1138 + flow_788: + if (standart_config_63 < 6) { + return 0; + } + GOTO flow_1138 + flow_791: + if (getSkillActualLvl(14) < 15) { + return 0; + } + GOTO flow_1138 + flow_794: + if (getSkillActualLvl(16) < 13) { + return 0; + } + GOTO flow_1138 + flow_797: + if (getSkillActualLvl(12) < 8) { + return 0; + } + GOTO flow_1138 + flow_800: + if (getSkillActualLvl(22) < 10) { + return 0; + } + GOTO flow_1138 + flow_803: + if (getSkillActualLvl(14) < 10) { + return 0; + } + GOTO flow_1138 + flow_806: + if (getSkillActualLvl(10) < 20) { + return 0; + } + GOTO flow_1138 + flow_809: + if (standart_config_101 < 33) { + return 0; + } + GOTO flow_1138 + flow_812: + if ((bitconfig_3523 < 150) || (getSkillActualLvl(14) < 42)) { + return 0; + } + GOTO flow_1138 + flow_815: + if (bitconfig_1404 < 127) { + return 0; + } + GOTO flow_1138 + flow_818: + if (standart_config_111 < 9) { + return 0; + } + GOTO flow_1138 + flow_821: + if (bitconfig_2309 < 1) { + return 0; + } + if (bitconfig_2310 < 1) { + return 0; + } + if (bitconfig_2311 < 1) { + return 0; + } + if (bitconfig_2312 < 1) { + return 0; + } + GOTO flow_1138 + flow_830: + if (standart_config_180 < 6) { + return 0; + } + if (bitconfig_961 < 60) { + return 0; + } + GOTO flow_1138 + flow_835: + if (getSkillActualLvl(16) < 21) { + return 0; + } + GOTO flow_1138 + flow_838: + if (bitconfig_2011 < 13) { + return 0; + } + GOTO flow_1138 + flow_841: + if (bitconfig_3639 < 1) { + return 0; + } + if (getSkillActualLvl(6) < 49) { + return 0; + } + GOTO flow_1138 + flow_846: + if (getSkillActualLvl(17) < 40) { + return 0; + } + GOTO flow_1138 + flow_849: + if (getSkillActualLvl(6) < 25) { + return 0; + } + GOTO flow_1138 + flow_852: + if (script_1432() < 40) { + return 0; + } + GOTO flow_1138 + flow_855: + if (bitconfig_961 < 60) { + return 0; + } + GOTO flow_1138 + flow_858: + if (bitconfig_2866 < 200) { + return 0; + } + GOTO flow_1138 + flow_861: + if (standart_config_180 < 6) { + return 0; + } + GOTO flow_1138 + flow_864: + if (((boolean)bitconfig_2328)) { + return 0; + } + GOTO flow_1138 + flow_867: + if (standart_config_176 < 10) { + return 0; + } + GOTO flow_1138 + flow_870: + if (getSkillActualLvl(19) < 70) { + return 0; + } + GOTO flow_1138 + flow_873: + if (getSkillActualLvl(16) < 51) { + return 0; + } + GOTO flow_1138 + flow_876: + if (getSkillActualLvl(13) < 73) { + return 0; + } + GOTO flow_1138 + flow_879: + if (script_4035() < 153) { + return 0; + } + GOTO flow_1138 + flow_882: + if (getSkillActualLvl(7) < 32) { + return 0; + } + GOTO flow_1138 + flow_885: + if (getSkillActualLvl(12) < 66) { + return 0; + } + GOTO flow_1138 + flow_888: + if (getSkillActualLvl(22) < 40) { + return 0; + } + GOTO flow_1138 + flow_891: + if (getSkillActualLvl(6) < 25) { + return 0; + } + GOTO flow_1138 + flow_894: + if (standart_config_148 < 11) { + return 0; + } + GOTO flow_1138 + flow_897: + if (getSkillActualLvl(8) < 57) { + return 0; + } + GOTO flow_1138 + flow_900: + if (bitconfig_358 < 15) { + return 0; + } + GOTO flow_1138 + flow_903: + if (bitconfig_3523 < 150) { + return 0; + } + GOTO flow_1138 + flow_906: + if (bitconfig_6962 < 12) { + return 0; + } + GOTO flow_1138 + flow_909: + if (getSkillActualLvl(8) < 80) { + return 0; + } + GOTO flow_1138 + flow_912: + if (bitconfig_5133 < 90) { + return 0; + } + if (getSkillActualLvl(11) < 92) { + return 0; + } + if (getSkillActualLvl(19) < 15) { + return 0; + } + GOTO flow_1138 + flow_919: + if (bitconfig_3523 < 150) { + return 0; + } + if (getSkillActualLvl(6) < 80) { + return 0; + } + GOTO flow_1138 + flow_924: + if (getSkillActualLvl(7) < 95) { + return 0; + } + GOTO flow_1138 + flow_927: + if (bitconfig_6775 < 90) { + return 0; + } + if (getSkillActualLvl(5) < 92) { + return 0; + } + GOTO flow_1138 + flow_932: + if (getSkillActualLvl(13) < 88) { + return 0; + } + if (getSkillActualLvl(9) < 69) { + return 0; + } + GOTO flow_1138 + flow_937: + if (getSkillActualLvl(20) < 78) { + return 0; + } + GOTO flow_1138 + flow_940: + if (standart_config_63 < 6) { + return 0; + } + GOTO flow_1138 + flow_943: + if (standart_config_63 < 6) { + return 0; + } + GOTO flow_1138 + flow_946: + if (getSkillActualLvl(0) < 5) { + return 0; + } + GOTO flow_1138 + flow_949: + if (getSkillActualLvl(1) < 5) { + return 0; + } + GOTO flow_1138 + flow_952: + if (getSkillActualLvl(13) < 2) { + return 0; + } + GOTO flow_1138 + flow_955: + if (getSkillActualLvl(13) < 3) { + return 0; + } + GOTO flow_1138 + flow_958: + if (getSkillActualLvl(12) < 4) { + return 0; + } + GOTO flow_1138 + flow_961: + if (getSkillActualLvl(12) < 7) { + return 0; + } + GOTO flow_1138 + flow_964: + if (getSkillActualLvl(10) < 5) { + return 0; + } + GOTO flow_1138 + flow_967: + if (getSkillActualLvl(7) < 5) { + return 0; + } + GOTO flow_1138 + flow_970: + if (getSkillActualLvl(6) < 3) { + return 0; + } + GOTO flow_1138 + flow_973: + if (getSkillActualLvl(6) < 7) { + return 0; + } + GOTO flow_1138 + flow_976: + if (getSkillActualLvl(4) < 5) { + return 0; + } + GOTO flow_1138 + flow_979: + if (getSkillActualLvl(4) < 5) { + return 0; + } + GOTO flow_1138 + flow_982: + if (getSkillActualLvl(7) < 10) { + return 0; + } + GOTO flow_1138 + flow_985: + if (getMinute() < standart_config_451) { + return 0; + } + if ((standart_config_101 < bitconfig_456) && (script_4218() > 0)) { + return 0; + } + GOTO flow_1138 + flow_991: + if (script_1432() < 40) { + return 0; + } + GOTO flow_1138 + flow_994: + if (bitconfig_5276 == 10) { + return 0; + } + if (bitconfig_5275 == 50) { + return 0; + } + if (((boolean)bitconfig_5277)) { + return 0; + } + GOTO flow_1138 + flow_1001: + if (bitconfig_1545 >= 2) { + return 0; + } + GOTO flow_1138 + flow_1004: + if (getSkillCurrentLvl(21) < 17) { + return 0; + } + GOTO flow_1138 + flow_1007: + if (((bitconfig_5251 != 0) && (bitconfig_5252 != 0)) && (bitconfig_5253 != 0)) { + return 0; + } + GOTO flow_1138 + flow_1012: + if (bitconfig_3523 < 150) { + return 0; + } + if (standart_config_1199 == getCurrentDaysSinceLaunch()) { + return 0; + } + GOTO flow_1138 + flow_1017: + if (bitconfig_5133 < 90) { + return 0; + } + GOTO flow_1138 + flow_1020: + if (bitconfig_6307 < 12) { + return 0; + } + if (getMinute() < bitconfig_6305) { + return 0; + } + GOTO flow_1138 + flow_1025: + if (standart_config_101 < 33) { + return 0; + } + GOTO flow_1138 + flow_1028: + if (getSkillActualLvl(20) < 50) { + return 0; + } + GOTO flow_1138 + flow_1031: + if (script_1432() < 40) { + return 0; + } + GOTO flow_1138 + flow_1034: + if ((getSkillActualLvl(0) < 65) && (getSkillActualLvl(1) < 65)) { + return 0; + } + if (bitconfig_3888 < 90) { + return 0; + } + GOTO flow_1138 + flow_1040: + if (standart_config_175 < 12) { + return 0; + } + if (getSkillActualLvl(8) < 10) { + return 0; + } + GOTO flow_1138 + flow_1045: + if (standart_config_302 < 60) { + return 0; + } + if (standart_config_339 < 85) { + return 0; + } + GOTO flow_1138 + flow_1050: + if (standart_config_302 < 60) { + return 0; + } + GOTO flow_1138 + flow_1053: + if (getSkillActualLvl(17) < 21) { + return 0; + } + GOTO flow_1138 + flow_1056: + if (getSkillActualLvl(6) < 7) { + return 0; + } + GOTO flow_1138 + flow_1059: + if (script_1432() < 48) { + return 0; + } + GOTO flow_1138 + flow_1062: + if (standart_config_273 < 110) { + return 0; + } + GOTO flow_1138 + flow_1065: + if (((add(getSkillActualLvl(2), getSkillActualLvl(0)) < 130) && (getSkillActualLvl(0) < 99)) && (getSkillActualLvl(2) < 99)) { + return 0; + } + GOTO flow_1138 + flow_1070: + if (script_4098() != 3500) { + return 0; + } + GOTO flow_1138 + flow_1073: + if (script_4098() != 3501) { + return 0; + } + GOTO flow_1138 + flow_1076: + if (script_4098() != 3505) { + return 0; + } + GOTO flow_1138 + flow_1079: + if (script_4098() != 3511) { + return 0; + } + GOTO flow_1138 + flow_1082: + if (script_4098() != 3502) { + return 0; + } + GOTO flow_1138 + flow_1085: + if (script_4098() != 3503) { + return 0; + } + GOTO flow_1138 + flow_1088: + if (script_4098() != 3504) { + return 0; + } + GOTO flow_1138 + flow_1091: + if (script_4098() != 3506) { + return 0; + } + GOTO flow_1138 + flow_1094: + if (script_4098() != 3508) { + return 0; + } + GOTO flow_1138 + flow_1097: + if (script_4098() != 3509) { + return 0; + } + GOTO flow_1138 + flow_1100: + if (script_4098() != 3507) { + return 0; + } + GOTO flow_1138 + flow_1103: + if (script_4098() != 3523) { + return 0; + } + GOTO flow_1138 + flow_1106: + if (script_4098() != 3510) { + return 0; + } + GOTO flow_1138 + flow_1109: + if (script_4098() != 3512) { + return 0; + } + GOTO flow_1138 + flow_1112: + if (script_4098() != 3513) { + return 0; + } + GOTO flow_1138 + flow_1115: + if (script_4098() != 3514) { + return 0; + } + GOTO flow_1138 + flow_1118: + if ((((standart_config_281 < 135) || (standart_config_281 > 160)) || ((boolean)bitconfig_6495)) || ((boolean)bitconfig_6495)) { + return 0; + } + GOTO flow_1138 + flow_1121: + if ((((standart_config_281 < 135) || (standart_config_281 > 160)) || (bitconfig_6495 == 2)) || (bitconfig_6495 == 3)) { + return 0; + } + GOTO flow_1138 + flow_1124: + if ((((standart_config_281 < 140) || ((boolean)bitconfig_6495)) || ((boolean)bitconfig_6495)) || (getSkillActualLvl(8) > 1)) { + return 0; + } + GOTO flow_1138 + flow_1127: + if ((((standart_config_281 < 140) || (bitconfig_6495 == 2)) || (bitconfig_6495 == 3)) || (getSkillActualLvl(14) > 1)) { + return 0; + } + GOTO flow_1138 + flow_1130: + if (script_4098() != 3519) { + return 0; + } + GOTO flow_1138 + flow_1133: + if ((script_4098() != 3521) || (bitconfig_6494 > 2)) { + return 0; + } + GOTO flow_1138 + flow_1136: + if ((script_4098() != 3521) || (bitconfig_6494 != 5)) { + return 0; + } + flow_1138: + return 1; +} diff --git a/dumps/scripts/3225.cs2 b/dumps/scripts/3225.cs2 new file mode 100644 index 0000000..945d462 --- /dev/null +++ b/dumps/scripts/3225.cs2 @@ -0,0 +1,4 @@ +void script_3225(int arg0,int arg1,string arg2) { + script_3226(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/3226.cs2 b/dumps/scripts/3226.cs2 new file mode 100644 index 0000000..44d7f3e --- /dev/null +++ b/dumps/scripts/3226.cs2 @@ -0,0 +1,10 @@ +void script_3226(int arg0,int arg1,string arg2) { + if (((boolean)arg1)) { + setWidgetRGB(new Color(67, 200, 0), new WidgetPointer(arg0)); + setWidgetText(new WidgetPointer(arg0), "" + arg2 + ""); + } else { + setWidgetRGB(new Color(51, 153, 0), new WidgetPointer(arg0)); + setWidgetText(new WidgetPointer(arg0), "" + arg2 + ""); + } + return; +} diff --git a/dumps/scripts/3227.cs2 b/dumps/scripts/3227.cs2 new file mode 100644 index 0000000..0e1f9a0 --- /dev/null +++ b/dumps/scripts/3227.cs2 @@ -0,0 +1,3253 @@ +int script_3227(int arg0) { + flow_0: + if (getOtherCommonData(cs2method_3408(105, 74, 3483, arg0), 1270) != 4094) { + return script_2193(getOtherCommonData(cs2method_3408(105, 74, 3483, arg0), 1270)); + } + SWITCH (arg0) { + case 0: + GOTO flow_3 + case 1: + GOTO flow_6 + case 2: + GOTO flow_9 + case 3: + GOTO flow_12 + case 4: + GOTO flow_15 + case 5: + GOTO flow_18 + case 6: + GOTO flow_21 + case 7: + GOTO flow_24 + case 8: + GOTO flow_27 + case 9: + GOTO flow_30 + case 10: + GOTO flow_33 + case 11: + GOTO flow_36 + case 12: + GOTO flow_39 + case 13: + GOTO flow_42 + case 14: + GOTO flow_45 + case 15: + GOTO flow_48 + case 16: + GOTO flow_51 + case 17: + GOTO flow_54 + case 18: + GOTO flow_57 + case 19: + GOTO flow_60 + case 20: + GOTO flow_63 + case 21: + GOTO flow_66 + case 22: + GOTO flow_69 + case 23: + GOTO flow_72 + case 24: + GOTO flow_75 + case 25: + GOTO flow_78 + case 26: + GOTO flow_81 + case 27: + GOTO flow_84 + case 28: + GOTO flow_87 + case 29: + GOTO flow_90 + case 30: + GOTO flow_93 + case 31: + GOTO flow_96 + case 32: + GOTO flow_99 + case 33: + GOTO flow_102 + case 34: + GOTO flow_105 + case 35: + GOTO flow_108 + case 36: + GOTO flow_111 + case 37: + GOTO flow_114 + case 38: + GOTO flow_117 + case 39: + GOTO flow_120 + case 40: + GOTO flow_123 + case 41: + GOTO flow_126 + case 42: + GOTO flow_129 + case 43: + GOTO flow_132 + case 44: + GOTO flow_135 + case 45: + GOTO flow_138 + case 46: + GOTO flow_141 + case 47: + GOTO flow_144 + case 48: + GOTO flow_147 + case 49: + GOTO flow_150 + case 50: + GOTO flow_153 + case 51: + GOTO flow_156 + case 52: + GOTO flow_159 + case 53: + GOTO flow_162 + case 54: + GOTO flow_165 + case 55: + GOTO flow_168 + case 56: + GOTO flow_171 + case 57: + GOTO flow_174 + case 58: + GOTO flow_177 + case 59: + GOTO flow_180 + case 60: + GOTO flow_183 + case 61: + GOTO flow_188 + case 62: + GOTO flow_191 + case 63: + GOTO flow_194 + case 64: + GOTO flow_197 + case 65: + GOTO flow_200 + case 66: + GOTO flow_203 + case 67: + GOTO flow_206 + case 68: + GOTO flow_209 + case 69: + GOTO flow_212 + case 70: + GOTO flow_215 + case 71: + GOTO flow_218 + case 72: + GOTO flow_221 + case 73: + GOTO flow_224 + case 74: + GOTO flow_227 + case 75: + GOTO flow_230 + case 76: + GOTO flow_233 + case 77: + GOTO flow_236 + case 78: + GOTO flow_239 + case 79: + GOTO flow_242 + case 80: + GOTO flow_245 + case 81: + GOTO flow_248 + case 82: + GOTO flow_251 + case 83: + GOTO flow_254 + case 84: + GOTO flow_257 + case 85: + GOTO flow_260 + case 86: + GOTO flow_263 + case 87: + GOTO flow_266 + case 88: + GOTO flow_269 + case 89: + GOTO flow_272 + case 90: + GOTO flow_275 + case 91: + GOTO flow_278 + case 92: + GOTO flow_281 + case 93: + GOTO flow_284 + case 94: + GOTO flow_287 + case 95: + GOTO flow_290 + case 96: + GOTO flow_293 + case 97: + GOTO flow_296 + case 98: + GOTO flow_299 + case 99: + GOTO flow_302 + case 100: + GOTO flow_305 + case 101: + GOTO flow_308 + case 102: + GOTO flow_311 + case 103: + GOTO flow_314 + case 104: + GOTO flow_317 + case 105: + GOTO flow_320 + case 106: + GOTO flow_323 + case 107: + GOTO flow_326 + case 108: + GOTO flow_329 + case 109: + GOTO flow_332 + case 110: + GOTO flow_335 + case 111: + GOTO flow_338 + case 112: + GOTO flow_341 + case 113: + GOTO flow_344 + case 114: + GOTO flow_347 + case 351: + GOTO flow_350 + case 352: + GOTO flow_353 + case 353: + GOTO flow_356 + case 354: + GOTO flow_359 + case 355: + GOTO flow_362 + case 356: + GOTO flow_365 + case 357: + GOTO flow_368 + case 115: + GOTO flow_371 + case 116: + GOTO flow_374 + case 117: + GOTO flow_377 + case 118: + GOTO flow_380 + case 119: + GOTO flow_383 + case 120: + GOTO flow_386 + case 121: + GOTO flow_389 + case 122: + GOTO flow_392 + case 123: + GOTO flow_395 + case 124: + GOTO flow_398 + case 125: + GOTO flow_401 + case 126: + GOTO flow_404 + case 127: + GOTO flow_407 + case 128: + GOTO flow_410 + case 129: + GOTO flow_413 + case 130: + GOTO flow_418 + case 131: + GOTO flow_421 + case 132: + GOTO flow_424 + case 133: + GOTO flow_427 + case 134: + GOTO flow_432 + case 135: + GOTO flow_435 + case 136: + GOTO flow_438 + case 137: + GOTO flow_441 + case 138: + GOTO flow_444 + case 139: + GOTO flow_447 + case 140: + GOTO flow_450 + case 141: + GOTO flow_453 + case 142: + GOTO flow_456 + case 143: + GOTO flow_459 + case 144: + GOTO flow_462 + case 145: + GOTO flow_465 + case 146: + GOTO flow_468 + case 147: + GOTO flow_471 + case 148: + GOTO flow_474 + case 149: + GOTO flow_477 + case 150: + GOTO flow_480 + case 151: + GOTO flow_483 + case 309: + GOTO flow_486 + case 310: + GOTO flow_489 + case 311: + GOTO flow_492 + case 312: + GOTO flow_495 + case 313: + GOTO flow_498 + case 314: + GOTO flow_501 + case 315: + GOTO flow_504 + case 152: + GOTO flow_507 + case 153: + GOTO flow_510 + case 154: + GOTO flow_513 + case 155: + GOTO flow_516 + case 156: + GOTO flow_519 + case 157: + GOTO flow_522 + case 158: + GOTO flow_525 + case 159: + GOTO flow_528 + case 160: + GOTO flow_531 + case 161: + GOTO flow_534 + case 162: + GOTO flow_537 + case 163: + GOTO flow_540 + case 164: + GOTO flow_543 + case 165: + GOTO flow_546 + case 166: + GOTO flow_549 + case 167: + GOTO flow_552 + case 168: + GOTO flow_555 + case 169: + GOTO flow_558 + case 170: + GOTO flow_561 + case 171: + GOTO flow_564 + case 172: + GOTO flow_567 + case 173: + GOTO flow_570 + case 174: + GOTO flow_573 + case 175: + GOTO flow_576 + case 176: + GOTO flow_579 + case 177: + GOTO flow_582 + case 178: + GOTO flow_585 + case 179: + GOTO flow_588 + case 180: + GOTO flow_591 + case 181: + GOTO flow_594 + case 428: + GOTO flow_597 + case 316: + GOTO flow_600 + case 317: + GOTO flow_603 + case 318: + GOTO flow_606 + case 319: + GOTO flow_609 + case 320: + GOTO flow_612 + case 321: + GOTO flow_615 + case 322: + GOTO flow_618 + case 323: + GOTO flow_621 + case 417: + GOTO flow_624 + case 182: + GOTO flow_627 + case 183: + GOTO flow_632 + case 184: + GOTO flow_635 + case 185: + GOTO flow_638 + case 186: + GOTO flow_641 + case 187: + GOTO flow_644 + case 188: + GOTO flow_647 + case 189: + GOTO flow_650 + case 190: + GOTO flow_655 + case 191: + GOTO flow_658 + case 192: + GOTO flow_661 + case 193: + GOTO flow_664 + case 194: + GOTO flow_667 + case 195: + GOTO flow_670 + case 196: + GOTO flow_673 + case 197: + GOTO flow_676 + case 198: + GOTO flow_679 + case 199: + GOTO flow_682 + case 200: + GOTO flow_685 + case 201: + GOTO flow_688 + case 202: + GOTO flow_691 + case 203: + GOTO flow_694 + case 204: + GOTO flow_697 + case 205: + GOTO flow_700 + case 206: + GOTO flow_703 + case 207: + GOTO flow_706 + case 208: + GOTO flow_709 + case 209: + GOTO flow_712 + case 210: + GOTO flow_715 + case 211: + GOTO flow_718 + case 212: + GOTO flow_721 + case 213: + GOTO flow_724 + case 214: + GOTO flow_727 + case 215: + GOTO flow_730 + case 216: + GOTO flow_733 + case 217: + GOTO flow_736 + case 218: + GOTO flow_739 + case 219: + GOTO flow_744 + case 220: + GOTO flow_747 + case 324: + GOTO flow_750 + case 325: + GOTO flow_753 + case 326: + GOTO flow_756 + case 327: + GOTO flow_759 + case 328: + GOTO flow_762 + case 329: + GOTO flow_765 + case 330: + GOTO flow_768 + case 331: + GOTO flow_771 + case 221: + GOTO flow_774 + case 222: + GOTO flow_779 + case 223: + GOTO flow_782 + case 224: + GOTO flow_785 + case 225: + GOTO flow_788 + case 226: + GOTO flow_791 + case 227: + GOTO flow_794 + case 228: + GOTO flow_799 + case 229: + GOTO flow_804 + case 230: + GOTO flow_807 + case 231: + GOTO flow_810 + case 232: + GOTO flow_813 + case 233: + GOTO flow_816 + case 234: + GOTO flow_819 + case 235: + GOTO flow_822 + case 236: + GOTO flow_825 + case 237: + GOTO flow_830 + case 238: + GOTO flow_833 + case 239: + GOTO flow_836 + case 240: + GOTO flow_839 + case 241: + GOTO flow_842 + case 242: + GOTO flow_845 + case 243: + GOTO flow_848 + case 244: + GOTO flow_851 + case 245: + GOTO flow_856 + case 246: + GOTO flow_859 + case 247: + GOTO flow_864 + case 248: + GOTO flow_867 + case 249: + GOTO flow_870 + case 250: + GOTO flow_873 + case 251: + GOTO flow_876 + case 252: + GOTO flow_879 + case 253: + GOTO flow_882 + case 254: + GOTO flow_887 + case 255: + GOTO flow_892 + case 332: + GOTO flow_897 + case 333: + GOTO flow_900 + case 334: + GOTO flow_903 + case 335: + GOTO flow_906 + case 336: + GOTO flow_909 + case 256: + GOTO flow_912 + case 257: + GOTO flow_915 + case 258: + GOTO flow_918 + case 259: + GOTO flow_921 + case 260: + GOTO flow_924 + case 261: + GOTO flow_927 + case 262: + GOTO flow_930 + case 263: + GOTO flow_933 + case 264: + GOTO flow_936 + case 265: + GOTO flow_939 + case 266: + GOTO flow_942 + case 267: + GOTO flow_945 + case 268: + GOTO flow_948 + case 269: + GOTO flow_951 + case 270: + GOTO flow_954 + case 271: + GOTO flow_957 + case 272: + GOTO flow_960 + case 273: + GOTO flow_963 + case 274: + GOTO flow_966 + case 275: + GOTO flow_969 + case 276: + GOTO flow_972 + case 277: + GOTO flow_975 + case 278: + GOTO flow_978 + case 279: + GOTO flow_981 + case 280: + GOTO flow_984 + case 281: + GOTO flow_987 + case 282: + GOTO flow_992 + case 283: + GOTO flow_995 + case 284: + GOTO flow_998 + case 285: + GOTO flow_1001 + case 286: + GOTO flow_1004 + case 287: + GOTO flow_1007 + case 288: + GOTO flow_1010 + case 289: + GOTO flow_1013 + case 290: + GOTO flow_1016 + case 291: + GOTO flow_1019 + case 292: + GOTO flow_1022 + case 293: + GOTO flow_1025 + case 294: + GOTO flow_1028 + case 295: + GOTO flow_1031 + case 296: + GOTO flow_1034 + case 297: + GOTO flow_1037 + case 298: + GOTO flow_1040 + case 299: + GOTO flow_1043 + case 300: + GOTO flow_1046 + case 301: + GOTO flow_1049 + case 302: + GOTO flow_1052 + case 303: + GOTO flow_1055 + case 304: + GOTO flow_1058 + case 305: + GOTO flow_1061 + case 306: + GOTO flow_1064 + case 307: + GOTO flow_1067 + case 308: + GOTO flow_1070 + case 337: + GOTO flow_1073 + case 338: + GOTO flow_1076 + case 339: + GOTO flow_1079 + case 340: + GOTO flow_1082 + case 341: + GOTO flow_1085 + case 342: + GOTO flow_1088 + case 343: + GOTO flow_1091 + case 344: + GOTO flow_1094 + case 345: + GOTO flow_1097 + case 358: + GOTO flow_1100 + case 359: + GOTO flow_1103 + case 360: + GOTO flow_1106 + case 361: + GOTO flow_1109 + case 362: + GOTO flow_1112 + case 363: + GOTO flow_1115 + case 412: + GOTO flow_1118 + case 365: + GOTO flow_1121 + case 413: + GOTO flow_1124 + case 366: + GOTO flow_1127 + case 368: + GOTO flow_1130 + case 369: + GOTO flow_1133 + case 370: + GOTO flow_1136 + case 367: + GOTO flow_1139 + case 371: + GOTO flow_1142 + case 372: + GOTO flow_1145 + case 373: + GOTO flow_1148 + case 374: + GOTO flow_1151 + case 375: + GOTO flow_1154 + case 376: + GOTO flow_1157 + case 377: + GOTO flow_1160 + case 378: + GOTO flow_1163 + case 379: + GOTO flow_1166 + case 380: + GOTO flow_1169 + case 381: + GOTO flow_1172 + case 382: + GOTO flow_1175 + case 383: + GOTO flow_1178 + case 384: + GOTO flow_1181 + case 385: + GOTO flow_1184 + case 386: + GOTO flow_1187 + case 387: + GOTO flow_1190 + case 388: + GOTO flow_1193 + case 389: + GOTO flow_1196 + case 390: + GOTO flow_1199 + case 391: + GOTO flow_1202 + case 392: + GOTO flow_1205 + case 393: + GOTO flow_1208 + case 394: + GOTO flow_1211 + case 395: + GOTO flow_1214 + case 396: + GOTO flow_1217 + case 397: + GOTO flow_1220 + case 398: + GOTO flow_1223 + case 399: + GOTO flow_1226 + case 414: + GOTO flow_1229 + case 415: + GOTO flow_1232 + case 416: + GOTO flow_1235 + case 400: + GOTO flow_1238 + case 401: + GOTO flow_1241 + case 402: + GOTO flow_1244 + case 403: + GOTO flow_1247 + case 404: + GOTO flow_1250 + case 405: + GOTO flow_1253 + case 406: + GOTO flow_1256 + case 407: + GOTO flow_1259 + case 408: + GOTO flow_1262 + case 409: + GOTO flow_1265 + case 410: + GOTO flow_1268 + case 411: + GOTO flow_1271 + case 418: + GOTO flow_1274 + case 3522: + GOTO flow_1277 + case 3500: + GOTO flow_1280 + case 3501: + GOTO flow_1283 + case 3505: + GOTO flow_1286 + case 3511: + GOTO flow_1289 + case 3502: + GOTO flow_1292 + case 3503: + GOTO flow_1295 + case 3504: + GOTO flow_1298 + case 3506: + GOTO flow_1301 + case 3508: + GOTO flow_1304 + case 3509: + GOTO flow_1307 + case 3507: + GOTO flow_1310 + case 3523: + GOTO flow_1313 + case 3510: + GOTO flow_1316 + case 3512: + GOTO flow_1319 + case 3513: + GOTO flow_1322 + case 3514: + GOTO flow_1325 + case 3515: + GOTO flow_1328 + case 3516: + GOTO flow_1331 + case 3517: + GOTO flow_1334 + case 3518: + GOTO flow_1337 + case 3519: + GOTO flow_1340 + case 3520: + GOTO flow_1343 + case 422: + GOTO flow_1346 + case 423: + GOTO flow_1349 + case 424: + GOTO flow_1352 + case 425: + GOTO flow_1355 + case 419: + GOTO flow_1358 + case 420: + GOTO flow_1361 + case 421: + GOTO flow_1364 + case 426: + GOTO flow_1369 + case 427: + GOTO flow_1372 + case 3525: + GOTO flow_1375 + case 3526: + GOTO flow_1378 + case 3527: + GOTO flow_1381 + case 3528: + GOTO flow_1384 + case 3529: + GOTO flow_1387 + case 3530: + GOTO flow_1390 + case 429: + GOTO flow_1393 + case 430: + GOTO flow_1396 + case 431: + GOTO flow_1399 + case 432: + GOTO flow_1402 + } + return 0; + flow_3: + if (((boolean)bitconfig_6598)) { + return 2; + } + GOTO flow_1404 + flow_6: + if (((boolean)bitconfig_6599)) { + return 2; + } + GOTO flow_1404 + flow_9: + if (((boolean)bitconfig_6600)) { + return 2; + } + GOTO flow_1404 + flow_12: + if (((boolean)bitconfig_6601)) { + return 2; + } + GOTO flow_1404 + flow_15: + if (((boolean)bitconfig_6602)) { + return 2; + } + GOTO flow_1404 + flow_18: + if (((boolean)bitconfig_6603)) { + return 2; + } + GOTO flow_1404 + flow_21: + if (((boolean)bitconfig_6604)) { + return 2; + } + GOTO flow_1404 + flow_24: + if (((boolean)bitconfig_6605)) { + return 2; + } + GOTO flow_1404 + flow_27: + if (((boolean)bitconfig_6606)) { + return 2; + } + GOTO flow_1404 + flow_30: + if (((boolean)bitconfig_6607)) { + return 2; + } + GOTO flow_1404 + flow_33: + if (((boolean)bitconfig_6608)) { + return 2; + } + GOTO flow_1404 + flow_36: + if (((boolean)bitconfig_6609)) { + return 2; + } + GOTO flow_1404 + flow_39: + if (((boolean)bitconfig_1421)) { + return 2; + } + GOTO flow_1404 + flow_42: + if (((boolean)bitconfig_6611)) { + return 2; + } + GOTO flow_1404 + flow_45: + if (((boolean)bitconfig_6612)) { + return 2; + } + GOTO flow_1404 + flow_48: + if (((boolean)bitconfig_6613)) { + return 2; + } + GOTO flow_1404 + flow_51: + if (((boolean)bitconfig_6614)) { + return 2; + } + GOTO flow_1404 + flow_54: + if (((boolean)bitconfig_6615)) { + return 2; + } + GOTO flow_1404 + flow_57: + if (((boolean)bitconfig_6616)) { + return 2; + } + GOTO flow_1404 + flow_60: + if (((boolean)bitconfig_6617)) { + return 2; + } + GOTO flow_1404 + flow_63: + if (((boolean)bitconfig_6618)) { + return 2; + } + GOTO flow_1404 + flow_66: + if (((boolean)bitconfig_6619)) { + return 2; + } + GOTO flow_1404 + flow_69: + if (((boolean)bitconfig_6620)) { + return 2; + } + GOTO flow_1404 + flow_72: + if (((boolean)bitconfig_6622)) { + return 2; + } + GOTO flow_1404 + flow_75: + if (((boolean)bitconfig_6623)) { + return 2; + } + GOTO flow_1404 + flow_78: + if (((boolean)bitconfig_6624)) { + return 2; + } + GOTO flow_1404 + flow_81: + if (((boolean)bitconfig_6625)) { + return 2; + } + GOTO flow_1404 + flow_84: + if (((boolean)bitconfig_6626)) { + return 2; + } + GOTO flow_1404 + flow_87: + if (((boolean)bitconfig_6627)) { + return 2; + } + GOTO flow_1404 + flow_90: + if (((boolean)bitconfig_6628)) { + return 2; + } + GOTO flow_1404 + flow_93: + if (((boolean)bitconfig_6629)) { + return 2; + } + GOTO flow_1404 + flow_96: + if (((boolean)bitconfig_6630)) { + return 2; + } + GOTO flow_1404 + flow_99: + if (((boolean)bitconfig_6631)) { + return 2; + } + GOTO flow_1404 + flow_102: + if (((boolean)bitconfig_6632)) { + return 2; + } + GOTO flow_1404 + flow_105: + if (((boolean)bitconfig_6633)) { + return 2; + } + GOTO flow_1404 + flow_108: + if (((boolean)bitconfig_6634)) { + return 2; + } + GOTO flow_1404 + flow_111: + if (((boolean)bitconfig_6635)) { + return 2; + } + GOTO flow_1404 + flow_114: + if (((boolean)bitconfig_6636)) { + return 2; + } + GOTO flow_1404 + flow_117: + if (((boolean)bitconfig_6637)) { + return 2; + } + GOTO flow_1404 + flow_120: + if (((boolean)bitconfig_6639)) { + return 2; + } + GOTO flow_1404 + flow_123: + if (((boolean)bitconfig_6640)) { + return 2; + } + GOTO flow_1404 + flow_126: + if (((boolean)bitconfig_6641)) { + return 2; + } + GOTO flow_1404 + flow_129: + if (((boolean)bitconfig_6642)) { + return 2; + } + GOTO flow_1404 + flow_132: + if (((boolean)bitconfig_6643)) { + return 2; + } + GOTO flow_1404 + flow_135: + if (((boolean)bitconfig_6644)) { + return 2; + } + GOTO flow_1404 + flow_138: + if (((boolean)bitconfig_6645)) { + return 2; + } + GOTO flow_1404 + flow_141: + if (((boolean)bitconfig_6646)) { + return 2; + } + GOTO flow_1404 + flow_144: + if (((boolean)bitconfig_6647)) { + return 2; + } + GOTO flow_1404 + flow_147: + if (((boolean)bitconfig_6648)) { + return 2; + } + GOTO flow_1404 + flow_150: + if (((boolean)bitconfig_6649)) { + return 2; + } + GOTO flow_1404 + flow_153: + if (((boolean)bitconfig_6650)) { + return 2; + } + GOTO flow_1404 + flow_156: + if (((boolean)bitconfig_6651)) { + return 2; + } + GOTO flow_1404 + flow_159: + if (((boolean)bitconfig_6652)) { + return 2; + } + GOTO flow_1404 + flow_162: + if (((boolean)bitconfig_6653)) { + return 2; + } + GOTO flow_1404 + flow_165: + if (((boolean)bitconfig_6654)) { + return 2; + } + GOTO flow_1404 + flow_168: + if (((boolean)bitconfig_6655)) { + return 2; + } + GOTO flow_1404 + flow_171: + if (((boolean)bitconfig_6658)) { + return 2; + } + GOTO flow_1404 + flow_174: + if (((boolean)bitconfig_6659)) { + return 2; + } + GOTO flow_1404 + flow_177: + if (((boolean)bitconfig_6660)) { + return 2; + } + GOTO flow_1404 + flow_180: + if (((boolean)bitconfig_6661)) { + return 2; + } + GOTO flow_1404 + flow_183: + if (bitconfig_6662 == 63) { + return 2; + } + if (bitconfig_6662 > 0) { + return 1; + } + GOTO flow_1404 + flow_188: + if (((boolean)bitconfig_4949)) { + return 2; + } + GOTO flow_1404 + flow_191: + if (((boolean)bitconfig_4950)) { + return 2; + } + GOTO flow_1404 + flow_194: + if (((boolean)bitconfig_4951)) { + return 2; + } + GOTO flow_1404 + flow_197: + if (((boolean)bitconfig_4952)) { + return 2; + } + GOTO flow_1404 + flow_200: + if (((boolean)bitconfig_4953)) { + return 2; + } + GOTO flow_1404 + flow_203: + if (((boolean)bitconfig_4954)) { + return 2; + } + GOTO flow_1404 + flow_206: + if (((boolean)bitconfig_4955)) { + return 2; + } + GOTO flow_1404 + flow_209: + if (((boolean)bitconfig_4956)) { + return 2; + } + GOTO flow_1404 + flow_212: + if (((boolean)bitconfig_4957)) { + return 2; + } + GOTO flow_1404 + flow_215: + if (((boolean)bitconfig_4958)) { + return 2; + } + GOTO flow_1404 + flow_218: + if (((boolean)bitconfig_4959)) { + return 2; + } + GOTO flow_1404 + flow_221: + if (((boolean)bitconfig_4960)) { + return 2; + } + GOTO flow_1404 + flow_224: + if (((boolean)bitconfig_4961)) { + return 2; + } + GOTO flow_1404 + flow_227: + if (((boolean)bitconfig_4962)) { + return 2; + } + GOTO flow_1404 + flow_230: + if (((boolean)bitconfig_4963)) { + return 2; + } + GOTO flow_1404 + flow_233: + if (((boolean)bitconfig_4964)) { + return 2; + } + GOTO flow_1404 + flow_236: + if (((boolean)bitconfig_4965)) { + return 2; + } + GOTO flow_1404 + flow_239: + if (((boolean)bitconfig_4966)) { + return 2; + } + GOTO flow_1404 + flow_242: + if (((boolean)bitconfig_4967)) { + return 2; + } + GOTO flow_1404 + flow_245: + if (((boolean)bitconfig_4968)) { + return 2; + } + GOTO flow_1404 + flow_248: + if (((boolean)bitconfig_4969)) { + return 2; + } + GOTO flow_1404 + flow_251: + if (((boolean)bitconfig_4970)) { + return 2; + } + GOTO flow_1404 + flow_254: + if (((boolean)bitconfig_4971)) { + return 2; + } + GOTO flow_1404 + flow_257: + if (((boolean)bitconfig_4972)) { + return 2; + } + GOTO flow_1404 + flow_260: + if (((boolean)bitconfig_4973)) { + return 2; + } + GOTO flow_1404 + flow_263: + if (((boolean)bitconfig_4974)) { + return 2; + } + GOTO flow_1404 + flow_266: + if (((boolean)bitconfig_4975)) { + return 2; + } + GOTO flow_1404 + flow_269: + if (((boolean)bitconfig_4976)) { + return 2; + } + GOTO flow_1404 + flow_272: + if (((boolean)bitconfig_4977)) { + return 2; + } + GOTO flow_1404 + flow_275: + if (((boolean)bitconfig_4978)) { + return 2; + } + GOTO flow_1404 + flow_278: + if (((boolean)bitconfig_4979)) { + return 2; + } + GOTO flow_1404 + flow_281: + if (((boolean)bitconfig_4980)) { + return 2; + } + GOTO flow_1404 + flow_284: + if (((boolean)bitconfig_4981)) { + return 2; + } + GOTO flow_1404 + flow_287: + if (((boolean)bitconfig_4982)) { + return 2; + } + GOTO flow_1404 + flow_290: + if (((boolean)bitconfig_4983)) { + return 2; + } + GOTO flow_1404 + flow_293: + if (((boolean)bitconfig_4984)) { + return 2; + } + GOTO flow_1404 + flow_296: + if (((boolean)bitconfig_4985)) { + return 2; + } + GOTO flow_1404 + flow_299: + if (((boolean)bitconfig_4986)) { + return 2; + } + GOTO flow_1404 + flow_302: + if (((boolean)bitconfig_4987)) { + return 2; + } + GOTO flow_1404 + flow_305: + if (((boolean)bitconfig_4988)) { + return 2; + } + GOTO flow_1404 + flow_308: + if (((boolean)bitconfig_4989)) { + return 2; + } + GOTO flow_1404 + flow_311: + if (((boolean)bitconfig_4991)) { + return 2; + } + GOTO flow_1404 + flow_314: + if (((boolean)bitconfig_4992)) { + return 2; + } + GOTO flow_1404 + flow_317: + if (((boolean)bitconfig_4993)) { + return 2; + } + GOTO flow_1404 + flow_320: + if (((boolean)bitconfig_4994)) { + return 2; + } + GOTO flow_1404 + flow_323: + if (((boolean)bitconfig_4995)) { + return 2; + } + GOTO flow_1404 + flow_326: + if (((boolean)bitconfig_4996)) { + return 2; + } + GOTO flow_1404 + flow_329: + if (((boolean)bitconfig_4997)) { + return 2; + } + GOTO flow_1404 + flow_332: + if (((boolean)bitconfig_4998)) { + return 2; + } + GOTO flow_1404 + flow_335: + if (((boolean)bitconfig_4999)) { + return 2; + } + GOTO flow_1404 + flow_338: + if (((boolean)bitconfig_5998)) { + return 2; + } + GOTO flow_1404 + flow_341: + if (((boolean)bitconfig_5001)) { + return 2; + } + GOTO flow_1404 + flow_344: + if (((boolean)bitconfig_5002)) { + return 2; + } + GOTO flow_1404 + flow_347: + if (((boolean)bitconfig_5003)) { + return 2; + } + GOTO flow_1404 + flow_350: + if (((boolean)bitconfig_8180)) { + return 2; + } + GOTO flow_1404 + flow_353: + if (((boolean)bitconfig_8181)) { + return 2; + } + GOTO flow_1404 + flow_356: + if (((boolean)bitconfig_8188)) { + return 2; + } + GOTO flow_1404 + flow_359: + if (((boolean)bitconfig_8191)) { + return 2; + } + GOTO flow_1404 + flow_362: + if (((boolean)bitconfig_8192)) { + return 2; + } + GOTO flow_1404 + flow_365: + if (((boolean)bitconfig_8193)) { + return 2; + } + GOTO flow_1404 + flow_368: + if (((boolean)bitconfig_8194)) { + return 2; + } + GOTO flow_1404 + flow_371: + if (((boolean)bitconfig_5691)) { + return 2; + } + GOTO flow_1404 + flow_374: + if (((boolean)bitconfig_5692)) { + return 2; + } + GOTO flow_1404 + flow_377: + if (((boolean)bitconfig_5693)) { + return 2; + } + GOTO flow_1404 + flow_380: + if (((boolean)bitconfig_5694)) { + return 2; + } + GOTO flow_1404 + flow_383: + if (((boolean)bitconfig_5695)) { + return 2; + } + GOTO flow_1404 + flow_386: + if (((boolean)bitconfig_5696)) { + return 2; + } + GOTO flow_1404 + flow_389: + if (((boolean)bitconfig_5697)) { + return 2; + } + GOTO flow_1404 + flow_392: + if (((boolean)bitconfig_5698)) { + return 2; + } + GOTO flow_1404 + flow_395: + if (((boolean)bitconfig_5699)) { + return 2; + } + GOTO flow_1404 + flow_398: + if (((boolean)bitconfig_5700)) { + return 2; + } + GOTO flow_1404 + flow_401: + if (((boolean)bitconfig_5701)) { + return 2; + } + GOTO flow_1404 + flow_404: + if (((boolean)bitconfig_5702)) { + return 2; + } + GOTO flow_1404 + flow_407: + if (((boolean)bitconfig_5703)) { + return 2; + } + GOTO flow_1404 + flow_410: + if (((boolean)bitconfig_5704)) { + return 2; + } + GOTO flow_1404 + flow_413: + if (bitconfig_5705 == 3) { + return 2; + } + if (bitconfig_5705 > 0) { + return 1; + } + GOTO flow_1404 + flow_418: + if (((boolean)bitconfig_5706)) { + return 2; + } + GOTO flow_1404 + flow_421: + if (((boolean)bitconfig_5707)) { + return 2; + } + GOTO flow_1404 + flow_424: + if (((boolean)bitconfig_5723)) { + return 2; + } + GOTO flow_1404 + flow_427: + if (bitconfig_5709 == 3) { + return 2; + } + if (bitconfig_5709 > 0) { + return 1; + } + GOTO flow_1404 + flow_432: + if (((boolean)bitconfig_5710)) { + return 2; + } + GOTO flow_1404 + flow_435: + if (((boolean)bitconfig_5711)) { + return 2; + } + GOTO flow_1404 + flow_438: + if (((boolean)bitconfig_5712)) { + return 2; + } + GOTO flow_1404 + flow_441: + if (((boolean)bitconfig_5713)) { + return 2; + } + GOTO flow_1404 + flow_444: + if (((boolean)bitconfig_5714)) { + return 2; + } + GOTO flow_1404 + flow_447: + if (((boolean)bitconfig_5715)) { + return 2; + } + GOTO flow_1404 + flow_450: + if (((boolean)bitconfig_5716)) { + return 2; + } + GOTO flow_1404 + flow_453: + if (((boolean)bitconfig_5717)) { + return 2; + } + GOTO flow_1404 + flow_456: + if (((boolean)bitconfig_5718)) { + return 2; + } + GOTO flow_1404 + flow_459: + if (((boolean)bitconfig_5719)) { + return 2; + } + GOTO flow_1404 + flow_462: + if (((boolean)bitconfig_5720)) { + return 2; + } + GOTO flow_1404 + flow_465: + if (((boolean)bitconfig_5721)) { + return 2; + } + GOTO flow_1404 + flow_468: + if (((boolean)bitconfig_5722)) { + return 2; + } + GOTO flow_1404 + flow_471: + if (((boolean)bitconfig_5708)) { + return 2; + } + GOTO flow_1404 + flow_474: + if (((boolean)bitconfig_5724)) { + return 2; + } + GOTO flow_1404 + flow_477: + if (((boolean)bitconfig_5725)) { + return 2; + } + GOTO flow_1404 + flow_480: + if (((boolean)bitconfig_5726)) { + return 2; + } + GOTO flow_1404 + flow_483: + if (((boolean)bitconfig_5727)) { + return 2; + } + GOTO flow_1404 + flow_486: + if (((boolean)bitconfig_8114)) { + return 2; + } + GOTO flow_1404 + flow_489: + if (((boolean)bitconfig_8115)) { + return 2; + } + GOTO flow_1404 + flow_492: + if (((boolean)bitconfig_8116)) { + return 2; + } + GOTO flow_1404 + flow_495: + if (((boolean)bitconfig_8117)) { + return 2; + } + GOTO flow_1404 + flow_498: + if (((boolean)bitconfig_8118)) { + return 2; + } + GOTO flow_1404 + flow_501: + if (((boolean)bitconfig_8119)) { + return 2; + } + GOTO flow_1404 + flow_504: + if (((boolean)bitconfig_8120)) { + return 2; + } + GOTO flow_1404 + flow_507: + if (((boolean)bitconfig_5648)) { + return 2; + } + GOTO flow_1404 + flow_510: + if (((boolean)bitconfig_5649)) { + return 2; + } + GOTO flow_1404 + flow_513: + if (((boolean)bitconfig_5650)) { + return 2; + } + GOTO flow_1404 + flow_516: + if (((boolean)bitconfig_5651)) { + return 2; + } + GOTO flow_1404 + flow_519: + if (((boolean)bitconfig_5652)) { + return 2; + } + GOTO flow_1404 + flow_522: + if (((boolean)bitconfig_5653)) { + return 2; + } + GOTO flow_1404 + flow_525: + if (((boolean)bitconfig_5654)) { + return 2; + } + GOTO flow_1404 + flow_528: + if (((boolean)bitconfig_5655)) { + return 2; + } + GOTO flow_1404 + flow_531: + if (((boolean)bitconfig_5656)) { + return 2; + } + GOTO flow_1404 + flow_534: + if (((boolean)bitconfig_5657)) { + return 2; + } + GOTO flow_1404 + flow_537: + if (((boolean)bitconfig_5658)) { + return 2; + } + GOTO flow_1404 + flow_540: + if (((boolean)bitconfig_5659)) { + return 2; + } + GOTO flow_1404 + flow_543: + if (((boolean)bitconfig_5660)) { + return 2; + } + GOTO flow_1404 + flow_546: + if (((boolean)bitconfig_5661)) { + return 2; + } + GOTO flow_1404 + flow_549: + if (((boolean)bitconfig_5662)) { + return 2; + } + GOTO flow_1404 + flow_552: + if (((boolean)bitconfig_5663)) { + return 2; + } + GOTO flow_1404 + flow_555: + if (((boolean)bitconfig_5664)) { + return 2; + } + GOTO flow_1404 + flow_558: + if (((boolean)bitconfig_5665)) { + return 2; + } + GOTO flow_1404 + flow_561: + if (((boolean)bitconfig_5666)) { + return 2; + } + GOTO flow_1404 + flow_564: + if (((boolean)bitconfig_5667)) { + return 2; + } + GOTO flow_1404 + flow_567: + if (((boolean)bitconfig_5668)) { + return 2; + } + GOTO flow_1404 + flow_570: + if (((boolean)bitconfig_5669)) { + return 2; + } + GOTO flow_1404 + flow_573: + if (((boolean)bitconfig_5670)) { + return 2; + } + GOTO flow_1404 + flow_576: + if (((boolean)bitconfig_5671)) { + return 2; + } + GOTO flow_1404 + flow_579: + if (((boolean)bitconfig_5672)) { + return 2; + } + GOTO flow_1404 + flow_582: + if (((boolean)bitconfig_5673)) { + return 2; + } + GOTO flow_1404 + flow_585: + if (((boolean)bitconfig_5674)) { + return 2; + } + GOTO flow_1404 + flow_588: + if (((boolean)bitconfig_5675)) { + return 2; + } + GOTO flow_1404 + flow_591: + if (((boolean)bitconfig_5676)) { + return 2; + } + GOTO flow_1404 + flow_594: + if (((boolean)bitconfig_5677)) { + return 2; + } + GOTO flow_1404 + flow_597: + if (bitconfig_9067 > 0) { + return 2; + } + GOTO flow_1404 + flow_600: + if (((boolean)bitconfig_8231)) { + return 2; + } + GOTO flow_1404 + flow_603: + if (((boolean)bitconfig_8232)) { + return 2; + } + GOTO flow_1404 + flow_606: + if (((boolean)bitconfig_8233)) { + return 2; + } + GOTO flow_1404 + flow_609: + if (((boolean)bitconfig_8234)) { + return 2; + } + GOTO flow_1404 + flow_612: + if (((boolean)bitconfig_8235)) { + return 2; + } + GOTO flow_1404 + flow_615: + if (((boolean)bitconfig_8236)) { + return 2; + } + GOTO flow_1404 + flow_618: + if (((boolean)bitconfig_8237)) { + return 2; + } + GOTO flow_1404 + flow_621: + if (((boolean)bitconfig_8238)) { + return 2; + } + GOTO flow_1404 + flow_624: + if (((boolean)bitconfig_8239)) { + return 2; + } + GOTO flow_1404 + flow_627: + if (bitconfig_3566 == 5) { + return 2; + } + if (bitconfig_3566 > 0) { + return 1; + } + GOTO flow_1404 + flow_632: + if (((boolean)bitconfig_3567)) { + return 2; + } + GOTO flow_1404 + flow_635: + if (((boolean)bitconfig_3568)) { + return 2; + } + GOTO flow_1404 + flow_638: + if (((boolean)bitconfig_3569)) { + return 2; + } + GOTO flow_1404 + flow_641: + if (((boolean)bitconfig_3570)) { + return 2; + } + GOTO flow_1404 + flow_644: + if (((boolean)bitconfig_3571)) { + return 2; + } + GOTO flow_1404 + flow_647: + if (((boolean)bitconfig_3572)) { + return 2; + } + GOTO flow_1404 + flow_650: + if (bitconfig_3573 == 5) { + return 2; + } + if (bitconfig_3573 > 0) { + return 1; + } + GOTO flow_1404 + flow_655: + if (((boolean)bitconfig_3574)) { + return 2; + } + GOTO flow_1404 + flow_658: + if (((boolean)bitconfig_3575)) { + return 2; + } + GOTO flow_1404 + flow_661: + if (((boolean)bitconfig_3579)) { + return 2; + } + GOTO flow_1404 + flow_664: + if (((boolean)bitconfig_3580)) { + return 2; + } + GOTO flow_1404 + flow_667: + if (((boolean)bitconfig_3581)) { + return 2; + } + GOTO flow_1404 + flow_670: + if (((boolean)bitconfig_3582)) { + return 2; + } + GOTO flow_1404 + flow_673: + if (((boolean)bitconfig_3583)) { + return 2; + } + GOTO flow_1404 + flow_676: + if (((boolean)bitconfig_3584)) { + return 2; + } + GOTO flow_1404 + flow_679: + if (((boolean)bitconfig_3585)) { + return 2; + } + GOTO flow_1404 + flow_682: + if (((boolean)bitconfig_3586)) { + return 2; + } + GOTO flow_1404 + flow_685: + if (((boolean)bitconfig_3587)) { + return 2; + } + GOTO flow_1404 + flow_688: + if (((boolean)bitconfig_3588)) { + return 2; + } + GOTO flow_1404 + flow_691: + if (((boolean)bitconfig_3589)) { + return 2; + } + GOTO flow_1404 + flow_694: + if (((boolean)bitconfig_3590)) { + return 2; + } + GOTO flow_1404 + flow_697: + if (((boolean)bitconfig_3591)) { + return 2; + } + GOTO flow_1404 + flow_700: + if (((boolean)bitconfig_3592)) { + return 2; + } + GOTO flow_1404 + flow_703: + if (((boolean)bitconfig_3593)) { + return 2; + } + GOTO flow_1404 + flow_706: + if (((boolean)bitconfig_3594)) { + return 2; + } + GOTO flow_1404 + flow_709: + if (((boolean)bitconfig_3595)) { + return 2; + } + GOTO flow_1404 + flow_712: + if (((boolean)bitconfig_3596)) { + return 2; + } + GOTO flow_1404 + flow_715: + if (((boolean)bitconfig_3597)) { + return 2; + } + GOTO flow_1404 + flow_718: + if (((boolean)bitconfig_3600)) { + return 2; + } + GOTO flow_1404 + flow_721: + if (((boolean)bitconfig_3601)) { + return 2; + } + GOTO flow_1404 + flow_724: + if (((boolean)bitconfig_3602)) { + return 2; + } + GOTO flow_1404 + flow_727: + if (((boolean)bitconfig_3603)) { + return 2; + } + GOTO flow_1404 + flow_730: + if (((boolean)bitconfig_3604)) { + return 2; + } + GOTO flow_1404 + flow_733: + if (((boolean)bitconfig_3605)) { + return 2; + } + GOTO flow_1404 + flow_736: + if (((boolean)bitconfig_3606)) { + return 2; + } + GOTO flow_1404 + flow_739: + if (bitconfig_3607 == 5) { + return 2; + } + if (bitconfig_3607 > 0) { + return 1; + } + GOTO flow_1404 + flow_744: + if (((boolean)bitconfig_3608)) { + return 2; + } + GOTO flow_1404 + flow_747: + if (((boolean)bitconfig_3609)) { + return 2; + } + GOTO flow_1404 + flow_750: + if (((boolean)bitconfig_8121)) { + return 2; + } + GOTO flow_1404 + flow_753: + if (((boolean)bitconfig_8122)) { + return 2; + } + GOTO flow_1404 + flow_756: + if (((boolean)bitconfig_8123)) { + return 2; + } + GOTO flow_1404 + flow_759: + if (((boolean)bitconfig_8124)) { + return 2; + } + GOTO flow_1404 + flow_762: + if (((boolean)bitconfig_8125)) { + return 2; + } + GOTO flow_1404 + flow_765: + if (((boolean)bitconfig_8126)) { + return 2; + } + GOTO flow_1404 + flow_768: + if (((boolean)bitconfig_8127)) { + return 2; + } + GOTO flow_1404 + flow_771: + if (((boolean)bitconfig_8128)) { + return 2; + } + GOTO flow_1404 + flow_774: + if (bitconfig_5782 == 5) { + return 2; + } + if (bitconfig_5782 > 0) { + return 1; + } + GOTO flow_1404 + flow_779: + if (((boolean)bitconfig_5783)) { + return 2; + } + GOTO flow_1404 + flow_782: + if (((boolean)bitconfig_5784)) { + return 2; + } + GOTO flow_1404 + flow_785: + if (((boolean)bitconfig_5785)) { + return 2; + } + GOTO flow_1404 + flow_788: + if (((boolean)bitconfig_5786)) { + return 2; + } + GOTO flow_1404 + flow_791: + if (bitconfig_5787 == 5) { + return 2; + } + GOTO flow_1404 + flow_794: + if (bitconfig_5788 == 5) { + return 2; + } + if (bitconfig_5788 > 0) { + return 1; + } + GOTO flow_1404 + flow_799: + if (bitconfig_5789 == 5) { + return 2; + } + if (bitconfig_5789 > 0) { + return 1; + } + GOTO flow_1404 + flow_804: + if (((boolean)bitconfig_5790)) { + return 2; + } + GOTO flow_1404 + flow_807: + if (((boolean)bitconfig_5791)) { + return 2; + } + GOTO flow_1404 + flow_810: + if (((boolean)bitconfig_5792)) { + return 2; + } + GOTO flow_1404 + flow_813: + if (((boolean)bitconfig_5793)) { + return 2; + } + GOTO flow_1404 + flow_816: + if (((boolean)bitconfig_5794)) { + return 2; + } + GOTO flow_1404 + flow_819: + if (((boolean)bitconfig_5795)) { + return 2; + } + GOTO flow_1404 + flow_822: + if (((boolean)bitconfig_5796)) { + return 2; + } + GOTO flow_1404 + flow_825: + if (bitconfig_5797 == 15) { + return 2; + } + if (bitconfig_5797 > 0) { + return 1; + } + GOTO flow_1404 + flow_830: + if (((boolean)bitconfig_5798)) { + return 2; + } + GOTO flow_1404 + flow_833: + if (((boolean)bitconfig_5799)) { + return 2; + } + GOTO flow_1404 + flow_836: + if (((boolean)bitconfig_5800)) { + return 2; + } + GOTO flow_1404 + flow_839: + if (((boolean)bitconfig_5801)) { + return 2; + } + GOTO flow_1404 + flow_842: + if (((boolean)bitconfig_5802)) { + return 2; + } + GOTO flow_1404 + flow_845: + if (((boolean)bitconfig_5803)) { + return 2; + } + GOTO flow_1404 + flow_848: + if (((boolean)bitconfig_5804)) { + return 2; + } + GOTO flow_1404 + flow_851: + if (bitconfig_5805 == 15) { + return 2; + } + if (bitconfig_5805 > 0) { + return 1; + } + GOTO flow_1404 + flow_856: + if (((boolean)bitconfig_5806)) { + return 2; + } + GOTO flow_1404 + flow_859: + if (bitconfig_5807 == 5) { + return 2; + } + if (bitconfig_5807 > 0) { + return 1; + } + GOTO flow_1404 + flow_864: + if (((boolean)bitconfig_5808)) { + return 2; + } + GOTO flow_1404 + flow_867: + if (((boolean)bitconfig_5809)) { + return 2; + } + GOTO flow_1404 + flow_870: + if (((boolean)bitconfig_5810)) { + return 2; + } + GOTO flow_1404 + flow_873: + if (((boolean)bitconfig_5811)) { + return 2; + } + GOTO flow_1404 + flow_876: + if (((boolean)bitconfig_5812)) { + return 2; + } + GOTO flow_1404 + flow_879: + if (((boolean)bitconfig_5813)) { + return 2; + } + GOTO flow_1404 + flow_882: + if (bitconfig_5814 == 5) { + return 2; + } + if (bitconfig_5814 > 0) { + return 1; + } + GOTO flow_1404 + flow_887: + if (bitconfig_5815 == 5) { + return 2; + } + if (bitconfig_5815 > 0) { + return 1; + } + GOTO flow_1404 + flow_892: + if (bitconfig_5816 == 5) { + return 2; + } + if (bitconfig_5816 > 0) { + return 1; + } + GOTO flow_1404 + flow_897: + if (((boolean)bitconfig_8205)) { + return 2; + } + GOTO flow_1404 + flow_900: + if (((boolean)bitconfig_8212)) { + return 2; + } + GOTO flow_1404 + flow_903: + if (((boolean)bitconfig_8217)) { + return 2; + } + GOTO flow_1404 + flow_906: + if (((boolean)bitconfig_8221)) { + return 2; + } + GOTO flow_1404 + flow_909: + if (((boolean)bitconfig_8224)) { + return 2; + } + GOTO flow_1404 + flow_912: + if (((boolean)bitconfig_3986)) { + return 2; + } + GOTO flow_1404 + flow_915: + if (((boolean)bitconfig_3987)) { + return 2; + } + GOTO flow_1404 + flow_918: + if (((boolean)bitconfig_3988)) { + return 2; + } + GOTO flow_1404 + flow_921: + if (((boolean)bitconfig_3989)) { + return 2; + } + GOTO flow_1404 + flow_924: + if (((boolean)bitconfig_3990)) { + return 2; + } + GOTO flow_1404 + flow_927: + if (((boolean)bitconfig_3991)) { + return 2; + } + GOTO flow_1404 + flow_930: + if (((boolean)bitconfig_3992)) { + return 2; + } + GOTO flow_1404 + flow_933: + if (((boolean)bitconfig_3993)) { + return 2; + } + GOTO flow_1404 + flow_936: + if (((boolean)bitconfig_3994)) { + return 2; + } + GOTO flow_1404 + flow_939: + if (((boolean)bitconfig_3995)) { + return 2; + } + GOTO flow_1404 + flow_942: + if (((boolean)bitconfig_3996)) { + return 2; + } + GOTO flow_1404 + flow_945: + if (((boolean)bitconfig_3997)) { + return 2; + } + GOTO flow_1404 + flow_948: + if (((boolean)bitconfig_3998)) { + return 2; + } + GOTO flow_1404 + flow_951: + if (((boolean)bitconfig_3999)) { + return 2; + } + GOTO flow_1404 + flow_954: + if (((boolean)bitconfig_4000)) { + return 2; + } + GOTO flow_1404 + flow_957: + if (((boolean)bitconfig_4001)) { + return 2; + } + GOTO flow_1404 + flow_960: + if (((boolean)bitconfig_4002)) { + return 2; + } + GOTO flow_1404 + flow_963: + if (((boolean)bitconfig_4004)) { + return 2; + } + GOTO flow_1404 + flow_966: + if (((boolean)bitconfig_4005)) { + return 2; + } + GOTO flow_1404 + flow_969: + if (((boolean)bitconfig_4003)) { + return 2; + } + GOTO flow_1404 + flow_972: + if (((boolean)bitconfig_4007)) { + return 2; + } + GOTO flow_1404 + flow_975: + if (((boolean)bitconfig_4008)) { + return 2; + } + GOTO flow_1404 + flow_978: + if (((boolean)bitconfig_4009)) { + return 2; + } + GOTO flow_1404 + flow_981: + if (((boolean)bitconfig_4010)) { + return 2; + } + GOTO flow_1404 + flow_984: + if (((boolean)bitconfig_4011)) { + return 2; + } + GOTO flow_1404 + flow_987: + if (bitconfig_4012 == 4) { + return 2; + } + if (bitconfig_4012 > 0) { + return 1; + } + GOTO flow_1404 + flow_992: + if (((boolean)bitconfig_4013)) { + return 2; + } + GOTO flow_1404 + flow_995: + if (((boolean)bitconfig_4014)) { + return 2; + } + GOTO flow_1404 + flow_998: + if (((boolean)bitconfig_4015)) { + return 2; + } + GOTO flow_1404 + flow_1001: + if (((boolean)bitconfig_4016)) { + return 2; + } + GOTO flow_1404 + flow_1004: + if (((boolean)bitconfig_4017)) { + return 2; + } + GOTO flow_1404 + flow_1007: + if (((boolean)bitconfig_4018)) { + return 2; + } + GOTO flow_1404 + flow_1010: + if (((boolean)bitconfig_4019)) { + return 2; + } + GOTO flow_1404 + flow_1013: + if (((boolean)bitconfig_4020)) { + return 2; + } + GOTO flow_1404 + flow_1016: + if (((boolean)bitconfig_4021)) { + return 2; + } + GOTO flow_1404 + flow_1019: + if (((boolean)bitconfig_4022)) { + return 2; + } + GOTO flow_1404 + flow_1022: + if (((boolean)bitconfig_4023)) { + return 2; + } + GOTO flow_1404 + flow_1025: + if (((boolean)bitconfig_4024)) { + return 2; + } + GOTO flow_1404 + flow_1028: + if (((boolean)bitconfig_4025)) { + return 2; + } + GOTO flow_1404 + flow_1031: + if (((boolean)bitconfig_4026)) { + return 2; + } + GOTO flow_1404 + flow_1034: + if (((boolean)bitconfig_4027)) { + return 2; + } + GOTO flow_1404 + flow_1037: + if (((boolean)bitconfig_4028)) { + return 2; + } + GOTO flow_1404 + flow_1040: + if (((boolean)bitconfig_4029)) { + return 2; + } + GOTO flow_1404 + flow_1043: + if (((boolean)bitconfig_4030)) { + return 2; + } + GOTO flow_1404 + flow_1046: + if (((boolean)bitconfig_4031)) { + return 2; + } + GOTO flow_1404 + flow_1049: + if (((boolean)bitconfig_4032)) { + return 2; + } + GOTO flow_1404 + flow_1052: + if (((boolean)bitconfig_4033)) { + return 2; + } + GOTO flow_1404 + flow_1055: + if (((boolean)bitconfig_4034)) { + return 2; + } + GOTO flow_1404 + flow_1058: + if (((boolean)bitconfig_4035)) { + return 2; + } + GOTO flow_1404 + flow_1061: + if (((boolean)bitconfig_4036)) { + return 2; + } + GOTO flow_1404 + flow_1064: + if (((boolean)bitconfig_4037)) { + return 2; + } + GOTO flow_1404 + flow_1067: + if (((boolean)bitconfig_4038)) { + return 2; + } + GOTO flow_1404 + flow_1070: + if (((boolean)bitconfig_4039)) { + return 2; + } + GOTO flow_1404 + flow_1073: + if (((boolean)bitconfig_8136)) { + return 2; + } + GOTO flow_1404 + flow_1076: + if (((boolean)bitconfig_8137)) { + return 2; + } + GOTO flow_1404 + flow_1079: + if (((boolean)bitconfig_8138)) { + return 2; + } + GOTO flow_1404 + flow_1082: + if (((boolean)bitconfig_8139)) { + return 2; + } + GOTO flow_1404 + flow_1085: + if (((boolean)bitconfig_8140)) { + return 2; + } + GOTO flow_1404 + flow_1088: + if (((boolean)bitconfig_8141)) { + return 2; + } + GOTO flow_1404 + flow_1091: + if (((boolean)bitconfig_8145)) { + return 2; + } + GOTO flow_1404 + flow_1094: + if (((boolean)bitconfig_8146)) { + return 2; + } + GOTO flow_1404 + flow_1097: + if (((boolean)bitconfig_8148)) { + return 2; + } + GOTO flow_1404 + flow_1100: + if (((boolean)bitconfig_8517)) { + return 2; + } + GOTO flow_1404 + flow_1103: + if (((boolean)bitconfig_8518)) { + return 2; + } + GOTO flow_1404 + flow_1106: + if (((boolean)bitconfig_8519)) { + return 2; + } + GOTO flow_1404 + flow_1109: + if (((boolean)bitconfig_8520)) { + return 2; + } + GOTO flow_1404 + flow_1112: + if (((boolean)bitconfig_8521)) { + return 2; + } + GOTO flow_1404 + flow_1115: + if (((boolean)bitconfig_8522)) { + return 2; + } + GOTO flow_1404 + flow_1118: + if (((boolean)bitconfig_8523)) { + return 2; + } + GOTO flow_1404 + flow_1121: + if (((boolean)bitconfig_8524)) { + return 2; + } + GOTO flow_1404 + flow_1124: + if (((boolean)bitconfig_8525)) { + return 2; + } + GOTO flow_1404 + flow_1127: + if (((boolean)bitconfig_8526)) { + return 2; + } + GOTO flow_1404 + flow_1130: + if (((boolean)bitconfig_8527)) { + return 2; + } + GOTO flow_1404 + flow_1133: + if (((boolean)bitconfig_8528)) { + return 2; + } + GOTO flow_1404 + flow_1136: + if (((boolean)bitconfig_8529)) { + return 2; + } + GOTO flow_1404 + flow_1139: + if (((boolean)bitconfig_8530)) { + return 2; + } + GOTO flow_1404 + flow_1142: + if (((boolean)bitconfig_8531)) { + return 2; + } + GOTO flow_1404 + flow_1145: + if (((boolean)bitconfig_8532)) { + return 2; + } + GOTO flow_1404 + flow_1148: + if (((boolean)bitconfig_8533)) { + return 2; + } + GOTO flow_1404 + flow_1151: + if (((boolean)bitconfig_8534)) { + return 2; + } + GOTO flow_1404 + flow_1154: + if (((boolean)bitconfig_8535)) { + return 2; + } + GOTO flow_1404 + flow_1157: + if (((boolean)bitconfig_8536)) { + return 2; + } + GOTO flow_1404 + flow_1160: + if (((boolean)bitconfig_8537)) { + return 2; + } + GOTO flow_1404 + flow_1163: + if (((boolean)bitconfig_8538)) { + return 2; + } + GOTO flow_1404 + flow_1166: + if (((boolean)bitconfig_8539)) { + return 2; + } + GOTO flow_1404 + flow_1169: + if (((boolean)bitconfig_8540)) { + return 2; + } + GOTO flow_1404 + flow_1172: + if (((boolean)bitconfig_8541)) { + return 2; + } + GOTO flow_1404 + flow_1175: + if (((boolean)bitconfig_8542)) { + return 2; + } + GOTO flow_1404 + flow_1178: + if (((boolean)bitconfig_8543)) { + return 2; + } + GOTO flow_1404 + flow_1181: + if (((boolean)bitconfig_8544)) { + return 2; + } + GOTO flow_1404 + flow_1184: + if (((boolean)bitconfig_8545)) { + return 2; + } + GOTO flow_1404 + flow_1187: + if (((boolean)bitconfig_8546)) { + return 2; + } + GOTO flow_1404 + flow_1190: + if (((boolean)bitconfig_8547)) { + return 2; + } + GOTO flow_1404 + flow_1193: + if (((boolean)bitconfig_8548)) { + return 2; + } + GOTO flow_1404 + flow_1196: + if (((boolean)bitconfig_8549)) { + return 2; + } + GOTO flow_1404 + flow_1199: + if (((boolean)bitconfig_8550)) { + return 2; + } + GOTO flow_1404 + flow_1202: + if (((boolean)bitconfig_8551)) { + return 2; + } + GOTO flow_1404 + flow_1205: + if (((boolean)bitconfig_8552)) { + return 2; + } + GOTO flow_1404 + flow_1208: + if (((boolean)bitconfig_8553)) { + return 2; + } + GOTO flow_1404 + flow_1211: + if (((boolean)bitconfig_8554)) { + return 2; + } + GOTO flow_1404 + flow_1214: + if (((boolean)bitconfig_8555)) { + return 2; + } + GOTO flow_1404 + flow_1217: + if (((boolean)bitconfig_8556)) { + return 2; + } + GOTO flow_1404 + flow_1220: + if (((boolean)bitconfig_8557)) { + return 2; + } + GOTO flow_1404 + flow_1223: + if (((boolean)bitconfig_8558)) { + return 2; + } + GOTO flow_1404 + flow_1226: + if (((boolean)bitconfig_8559)) { + return 2; + } + GOTO flow_1404 + flow_1229: + if (((boolean)bitconfig_8560)) { + return 2; + } + GOTO flow_1404 + flow_1232: + if (((boolean)bitconfig_8573)) { + return 2; + } + GOTO flow_1404 + flow_1235: + if (((boolean)bitconfig_8574)) { + return 2; + } + GOTO flow_1404 + flow_1238: + if (((boolean)bitconfig_8561)) { + return 2; + } + GOTO flow_1404 + flow_1241: + if (((boolean)bitconfig_8562)) { + return 2; + } + GOTO flow_1404 + flow_1244: + if (((boolean)bitconfig_8563)) { + return 2; + } + GOTO flow_1404 + flow_1247: + if (((boolean)bitconfig_8564)) { + return 2; + } + GOTO flow_1404 + flow_1250: + if (((boolean)bitconfig_8565)) { + return 2; + } + GOTO flow_1404 + flow_1253: + if (((boolean)bitconfig_8566)) { + return 2; + } + GOTO flow_1404 + flow_1256: + if (((boolean)bitconfig_8567)) { + return 2; + } + GOTO flow_1404 + flow_1259: + if (((boolean)bitconfig_8568)) { + return 2; + } + GOTO flow_1404 + flow_1262: + if (((boolean)bitconfig_8569)) { + return 2; + } + GOTO flow_1404 + flow_1265: + if (((boolean)bitconfig_8570)) { + return 2; + } + GOTO flow_1404 + flow_1268: + if (((boolean)bitconfig_8571)) { + return 2; + } + GOTO flow_1404 + flow_1271: + if (((boolean)bitconfig_8572)) { + return 2; + } + GOTO flow_1404 + flow_1274: + if (((boolean)bitconfig_8781)) { + return 2; + } + GOTO flow_1404 + flow_1277: + if (standart_config_281 >= 7) { + return 2; + } + GOTO flow_1404 + flow_1280: + if (standart_config_281 > 7) { + return 2; + } + GOTO flow_1404 + flow_1283: + if (standart_config_281 > 10) { + return 2; + } + GOTO flow_1404 + flow_1286: + if (standart_config_281 > 49) { + return 2; + } + GOTO flow_1404 + flow_1289: + if (standart_config_281 > 95) { + return 2; + } + GOTO flow_1404 + flow_1292: + if (standart_config_281 > 15) { + return 2; + } + GOTO flow_1404 + flow_1295: + if (standart_config_281 > 30) { + return 2; + } + GOTO flow_1404 + flow_1298: + if (standart_config_281 > 40) { + return 2; + } + GOTO flow_1404 + flow_1301: + if (standart_config_281 > 55) { + return 2; + } + GOTO flow_1404 + flow_1304: + if (standart_config_281 > 60) { + return 2; + } + GOTO flow_1404 + flow_1307: + if (standart_config_281 > 62) { + return 2; + } + GOTO flow_1404 + flow_1310: + if (standart_config_281 > 75) { + return 2; + } + GOTO flow_1404 + flow_1313: + if (standart_config_281 > 70) { + return 2; + } + GOTO flow_1404 + flow_1316: + if (standart_config_281 > 90) { + return 2; + } + GOTO flow_1404 + flow_1319: + if (standart_config_281 > 115) { + return 2; + } + GOTO flow_1404 + flow_1322: + if (standart_config_281 > 127) { + return 2; + } + GOTO flow_1404 + flow_1325: + if (standart_config_281 > 165) { + return 2; + } + GOTO flow_1404 + flow_1328: + if (standart_config_281 > 160) { + return 2; + } + GOTO flow_1404 + flow_1331: + if (standart_config_281 > 160) { + return 2; + } + GOTO flow_1404 + flow_1334: + if ((getSkillActualLvl(8) > 1) || (getSkillActualLvl(14) > 1)) { + return 2; + } + GOTO flow_1404 + flow_1337: + if ((getSkillActualLvl(8) > 1) || (getSkillActualLvl(14) > 1)) { + return 2; + } + GOTO flow_1404 + flow_1340: + if (standart_config_281 > 170) { + return 2; + } + GOTO flow_1404 + flow_1343: + if (bitconfig_6494 > 2) { + return 2; + } + GOTO flow_1404 + flow_1346: + if (bitconfig_9013 == 3) { + return 2; + } + GOTO flow_1404 + flow_1349: + if (((boolean)bitconfig_9015)) { + return 2; + } + GOTO flow_1404 + flow_1352: + if (((boolean)bitconfig_9016)) { + return 2; + } + GOTO flow_1404 + flow_1355: + if (((boolean)bitconfig_9018)) { + return 2; + } + GOTO flow_1404 + flow_1358: + if (((boolean)bitconfig_9019)) { + return 2; + } + GOTO flow_1404 + flow_1361: + if (((boolean)bitconfig_9010)) { + return 2; + } + GOTO flow_1404 + flow_1364: + if (bitconfig_9011 == 3) { + return 2; + } + if (bitconfig_9011 > 0) { + return 1; + } + GOTO flow_1404 + flow_1369: + if (((boolean)bitconfig_9020)) { + return 2; + } + GOTO flow_1404 + flow_1372: + if (((boolean)bitconfig_9027)) { + return 2; + } + GOTO flow_1404 + flow_1375: + if (((boolean)bitconfig_9021)) { + return 2; + } + GOTO flow_1404 + flow_1378: + if (((boolean)bitconfig_9022)) { + return 2; + } + GOTO flow_1404 + flow_1381: + if (((boolean)bitconfig_9023)) { + return 2; + } + GOTO flow_1404 + flow_1384: + if (((boolean)bitconfig_9024)) { + return 2; + } + GOTO flow_1404 + flow_1387: + if (((boolean)bitconfig_9025)) { + return 2; + } + GOTO flow_1404 + flow_1390: + if (((boolean)bitconfig_9026)) { + return 2; + } + GOTO flow_1404 + flow_1393: + if (((boolean)bitconfig_9638)) { + return 2; + } + GOTO flow_1404 + flow_1396: + if (((boolean)bitconfig_9639)) { + return 2; + } + GOTO flow_1404 + flow_1399: + if (((boolean)bitconfig_9640)) { + return 2; + } + GOTO flow_1404 + flow_1402: + if (((boolean)bitconfig_9641)) { + return 2; + } + flow_1404: + return 0; +} diff --git a/dumps/scripts/3228.cs2 b/dumps/scripts/3228.cs2 new file mode 100644 index 0000000..4a9d1ee --- /dev/null +++ b/dumps/scripts/3228.cs2 @@ -0,0 +1,87 @@ +int script_3228(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + string svar0; + string svar1; + svar0 = ""; + ivar3 = -1; + switch (arg0) { + case 7: + svar0 = globalstring_124; + ivar3 = 44105812; + globalstring_328 = globalstring_124; + break; + case 8: + svar0 = globalstring_125; + ivar3 = 44105802; + globalstring_329 = globalstring_125; + } + ivar4 = strLength(svar0); + if (ivar4 <= 0) { + switch (arg0) { + case 7: + script_3213(44105812, "Please enter your desired password here."); + break; + case 8: + script_3213(44105802, "Please enter your desired password again here."); + } + return 0; + } + if ((((boolean)arg1) && (stringMethod4107(globalstring_124, globalstring_125) != 0)) && ((strLength(globalstring_124) > 0) || (strLength(globalstring_125) > 0))) { + script_3213(44105802, "Please ensure both passwords match."); + return 0; + } + if (ivar4 < 5) { + script_3213(ivar3, "Passwords must be at least 5 characters long."); + return 0; + } + if (ivar4 > 20) { + script_3213(ivar3, "Passwords must be no more than " + intToStr(20) + " characters long."); + return 0; + } + if (((boolean)script_2202(svar0))) { + script_3213(ivar3, "Passwords may only contain letters and numbers."); + return 0; + } + if (strIndexof(0, globalstring_122, svar0) != -1) { + script_3213(ivar3, "Your password is too similar to your Email address."); + return 0; + } + svar1 = substr(0, 1, svar0); + ivar5 = strLength(svar0); + ivar6 = 0; + ivar7 = 0; + while (ivar6 < ivar5) { + if (strIndexof(ivar6, svar0, svar1) == ivar6) { + ivar7 = add(ivar7, 1); + } + ivar6 = add(ivar6, 1); + } + if (ivar7 == ivar5) { + script_3213(ivar3, "Your password is too easy to guess."); + return 0; + } + switch (arg0) { + case 7: + setWidgetSprite(4059, new WidgetPointer(673,84)); + setWidgetIsHidden(true, new WidgetPointer(673,89)); + break; + case 8: + setWidgetSprite(4059, new WidgetPointer(673,74)); + setWidgetIsHidden(true, new WidgetPointer(673,79)); + } + setWidgetIsHidden(true, new WidgetPointer(673,31)); + if (((boolean)arg2)) { + switch (arg0) { + case 7: + script_2714(8, 1); + break; + case 8: + script_2714(15, 1); + } + } + return 1; +} diff --git a/dumps/scripts/3229.cs2 b/dumps/scripts/3229.cs2 new file mode 100644 index 0000000..6344a53 --- /dev/null +++ b/dumps/scripts/3229.cs2 @@ -0,0 +1,4 @@ +void script_3229() { + script_3230(); + return; +} diff --git a/dumps/scripts/323.cs2 b/dumps/scripts/323.cs2 new file mode 100644 index 0000000..1408f39 --- /dev/null +++ b/dumps/scripts/323.cs2 @@ -0,0 +1,5 @@ +void script_323(int arg0,int arg1) { + setWidgetText(new WidgetPointer(arg0), "Room:" + "
" + intToStr(bitconfig_2377) + " / 8"); + setWidgetText(new WidgetPointer(arg1), "Level:" + "
" + intToStr(bitconfig_2376)); + return; +} diff --git a/dumps/scripts/3230.cs2 b/dumps/scripts/3230.cs2 new file mode 100644 index 0000000..2d0cc05 --- /dev/null +++ b/dumps/scripts/3230.cs2 @@ -0,0 +1,46 @@ +void script_3230() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + ivar0 = 0; + if (getDisplayMode() < 2) { + setWidgetPosition(0, 16, 1, 1, new WidgetPointer(596,6)); + setWidgetPosition(0, 16, 1, 1, new WidgetPointer(596,7)); + setWidgetSize(0, 0, 1, 1, new WidgetPointer(744,16)); + setWidgetPosition(0, 26, 1, 0, new WidgetPointer(744,23)); + } else { + setWidgetPosition(0, 0, 1, 1, new WidgetPointer(596,6)); + setWidgetPosition(0, 0, 1, 1, new WidgetPointer(596,7)); + setWidgetSize(956, 503, 0, 0, new WidgetPointer(744,16)); + ivar0 = getWidgetActualY(new WidgetPointer(744,16)); + ivar0 = subtract(ivar0, getWidgetActualHeight(new WidgetPointer(744,23))); + ivar0 = divide(ivar0, 2); + setWidgetPosition(0, max(ivar0, 0), 1, 0, new WidgetPointer(744,23)); + } + ivar1 = 0; + ivar2 = 0; + ivar3 = 2; + ivar1 = add(getWidgetActualX(new WidgetPointer(744,99)), getWidgetActualX(new WidgetPointer(744,16))); + ivar1 = subtract(ivar1, add(getWidgetActualWidth(new WidgetPointer(744,81)), ivar3)); + ivar2 = add(getWidgetActualY(new WidgetPointer(744,101)), getWidgetActualY(new WidgetPointer(744,16))); + ivar2 = add(ivar2, ivar3); + ivar2 = add(ivar2, getWidgetActualHeight(new WidgetPointer(744,101))); + setWidgetPosition(ivar1, ivar2, 0, 0, new WidgetPointer(744,81)); + ivar1 = getWidgetActualX(new WidgetPointer(744,81)); + ivar1 = add(ivar1, getWidgetActualWidth(new WidgetPointer(744,81))); + ivar1 = subtract(getWidgetActualWidth(new WidgetPointer(744,17)), ivar1); + setWidgetPosition(ivar1, ivar2, 2, 0, new WidgetPointer(744,81)); + if ((cs2method6139() == 2) && (getDisplayMode() != 1)) { + setWidgetPosition(9, 57, 2, 0, new WidgetPointer(744,81)); + setWidgetSize(800, 503, 0, 0, new WidgetPointer(744,16)); + } else { + if (add(getWidgetActualWidth(new WidgetPointer(744,81)), getWidgetActualX(new WidgetPointer(744,81))) > getWidgetActualWidth(new WidgetPointer(744,17))) { + setWidgetPosition(5, 5, 2, 0, new WidgetPointer(744,81)); + } + } + if (((boolean)globalint_986)) { + setWidgetPosition(5, 5, 2, 0, new WidgetPointer(744,81)); + } + return; +} diff --git a/dumps/scripts/3231.cs2 b/dumps/scripts/3231.cs2 new file mode 100644 index 0000000..794e3ba --- /dev/null +++ b/dumps/scripts/3231.cs2 @@ -0,0 +1,4 @@ +void script_3231(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,string arg7,string arg8,string arg9) { + script_3232(arg0, arg1, arg2, arg3, arg4, arg5, arg6, 1, arg7, arg8, arg9); + return; +} diff --git a/dumps/scripts/3232.cs2 b/dumps/scripts/3232.cs2 new file mode 100644 index 0000000..028a84e --- /dev/null +++ b/dumps/scripts/3232.cs2 @@ -0,0 +1,120 @@ +void script_3232(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,string arg8,string arg9,string arg10) { + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + int ivar22; + ivar8 = 39059463; + ivar9 = 39059464; + ivar10 = 39059470; + ivar11 = 39059469; + ivar12 = 39059471; + ivar13 = 39059519; + ivar14 = 39059472; + ivar15 = 39059473; + ivar16 = 39059474; + ivar17 = 39059521; + ivar18 = 39059522; + ivar19 = 39059523; + if (hasSSKey()) { + ivar8 = 63897626; + ivar9 = 63897601; + ivar10 = 63897604; + ivar11 = 63897603; + ivar12 = 63897605; + ivar13 = 63897606; + ivar14 = 63897611; + ivar15 = 63897612; + ivar16 = 63897613; + ivar17 = 63897607; + ivar18 = 63897608; + ivar19 = 63897609; + } + if (isWidgetHidden(new WidgetPointer(ivar8))) { + return; + } + if (globalint_174 != 5) { + globalint_1089 = globalint_174; + } + globalint_174 = 5; + ivar20 = 250; + if (((boolean)arg4)) { + ivar20 = max(250, add(getTextWidth(3793, arg9), 36)); + if (mod(ivar20, 2) > 0) { + ivar20 = add(ivar20, 1); + } + } + setWidgetSize(ivar20, 154, 0, 0, new WidgetPointer(ivar9)); + ivar21 = add(multiply(getLineCount(getWidgetActualWidth(new WidgetPointer(ivar10)), 3793, arg8), 16), 5); + setWidgetSize(20, ivar21, 1, 0, new WidgetPointer(ivar10)); + setWidgetText(new WidgetPointer(ivar10), arg8); + if (((boolean)arg2)) { + globalint_1092 = add(getClientCycle(), 5); + setWidgetSprite(4107, new WidgetPointer(ivar11)); + setWidgetSize(111, 111, 0, 0, new WidgetPointer(ivar11)); + setWidgetPosition(0, 7, 1, 0, new WidgetPointer(ivar11)); + setWidgetPosition(0, 112, 1, 0, new WidgetPointer(ivar10)); + setScriptCallOnGameloop(2951, "", new WidgetPointer(ivar11)); + } else { + globalint_1092 = 0; + setScriptCallOnGameloop(-1, "", new WidgetPointer(ivar11)); + setWidgetSprite(arg3, new WidgetPointer(ivar11)); + setWidgetSize(76, 63, 0, 0, new WidgetPointer(ivar11)); + setWidgetPosition(0, 18, 1, 0, new WidgetPointer(ivar11)); + setWidgetPosition(0, 123, 1, 0, new WidgetPointer(ivar10)); + ivar21 = subtract(ivar21, 35); + } + ivar22 = 0; + ivar21 = add(getWidgetActualY(new WidgetPointer(ivar10)), ivar21); + if (((boolean)arg4) && ((boolean)arg6)) { + ivar22 = 12; + ivar21 = add(ivar21, ivar22); + setWidgetIsHidden(true, new WidgetPointer(ivar12)); + setWidgetIsHidden(true, new WidgetPointer(ivar13)); + } else if (((boolean)arg4) && ((boolean)arg6)) { + ivar22 = 41; + ivar21 = add(ivar21, ivar22); + setWidgetPosition(0, 8, 1, 2, new WidgetPointer(ivar12)); + setWidgetIsHidden(false, new WidgetPointer(ivar12)); + setWidgetIsHidden(true, new WidgetPointer(ivar13)); + script_2955(ivar12, ivar14, ivar15, ivar16, arg5, arg9); + } else if (((boolean)arg4) && ((boolean)arg6)) { + ivar22 = 41; + ivar21 = add(ivar21, ivar22); + setWidgetPosition(0, 8, 1, 2, new WidgetPointer(ivar13)); + setWidgetIsHidden(false, new WidgetPointer(ivar13)); + setWidgetIsHidden(true, new WidgetPointer(ivar12)); + script_2956(ivar13, ivar17, ivar18, ivar19, arg10); + } else { + ivar22 = 70; + ivar21 = add(ivar21, ivar22); + if (((boolean)arg7)) { + setWidgetPosition(0, 40, 1, 2, new WidgetPointer(ivar12)); + setWidgetPosition(0, 10, 1, 2, new WidgetPointer(ivar13)); + } else { + setWidgetPosition(0, 10, 1, 2, new WidgetPointer(ivar12)); + setWidgetPosition(0, 40, 1, 2, new WidgetPointer(ivar13)); + } + setWidgetIsHidden(false, new WidgetPointer(ivar13)); + setWidgetIsHidden(false, new WidgetPointer(ivar12)); + script_2955(ivar12, ivar14, ivar15, ivar16, arg5, arg9); + script_2956(ivar13, ivar17, ivar18, ivar19, arg10); + } + setWidgetSize(getWidgetActualWidth(new WidgetPointer(ivar9)), ivar21, 0, 0, new WidgetPointer(ivar9)); + script_2952(ivar12, ivar13, arg0); + setWidgetPosition(0, ivar22, 1, 2, new WidgetPointer(ivar10)); + setWidgetIsHidden(false, new WidgetPointer(ivar8)); + setWidgetIsHidden(false, new WidgetPointer(ivar9)); + setWidgetIsHidden(true, new WidgetPointer(596,6)); + return; +} diff --git a/dumps/scripts/3233.cs2 b/dumps/scripts/3233.cs2 new file mode 100644 index 0000000..366e827 --- /dev/null +++ b/dumps/scripts/3233.cs2 @@ -0,0 +1,9 @@ +void script_3233(string arg0) { + int ivar0; + ivar0 = 39059470; + if (hasSSKey()) { + ivar0 = 63897604; + } + setWidgetText(new WidgetPointer(ivar0), arg0); + return; +} diff --git a/dumps/scripts/3234.cs2 b/dumps/scripts/3234.cs2 new file mode 100644 index 0000000..4365071 --- /dev/null +++ b/dumps/scripts/3234.cs2 @@ -0,0 +1,4 @@ +void script_3234() { + script_3235(); + return; +} diff --git a/dumps/scripts/3235.cs2 b/dumps/scripts/3235.cs2 new file mode 100644 index 0000000..1b048f0 --- /dev/null +++ b/dumps/scripts/3235.cs2 @@ -0,0 +1,14 @@ +void script_3235() { + int ivar0; + ivar0 = 39059501; + if (hasSSKey()) { + ivar0 = 63897644; + } + if (globalint_200 > 0) { + setScriptCallOnMousePressed(2944, "", new WidgetPointer(ivar0)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(ivar0)); + resetRCs(); + script_2954(); + } + return; +} diff --git a/dumps/scripts/3236.cs2 b/dumps/scripts/3236.cs2 new file mode 100644 index 0000000..e949238 --- /dev/null +++ b/dumps/scripts/3236.cs2 @@ -0,0 +1,14 @@ +void script_3236(int arg0,int arg1,int arg2,int arg3,int arg4) { + string svar0; + svar0 = ""; + switch (arg3) { + case 3: + svar0 = globalstring_32; + break; + case 4: + svar0 = script_2949(globalstring_33); + } + globalint_1099 = script_1401(arg0, 3793, 0, svar0); + script_3237(arg4, arg1, arg2, arg3, svar0); + return; +} diff --git a/dumps/scripts/3237.cs2 b/dumps/scripts/3237.cs2 new file mode 100644 index 0000000..11b57c9 --- /dev/null +++ b/dumps/scripts/3237.cs2 @@ -0,0 +1,32 @@ +void script_3237(int arg0,int arg1,int arg2,int arg3,string arg4) { + int ivar4; + int ivar5; + int ivar6; + string svar1; + string svar2; + setWidgetPosition(script_1551(globalint_1099, 3793, add(getWidgetActualX(new WidgetPointer(arg0)), 6), arg4), getWidgetActualY(new WidgetPointer(arg2)), 0, 0, new WidgetPointer(arg2)); + ivar4 = subtract(getWidgetActualWidth(new WidgetPointer(arg0)), 11); + ivar5 = strLength(arg4); + svar1 = ""; + if (globalint_1099 > 0) { + svar1 = substr(0, globalint_1099, arg4); + } + svar2 = ""; + if (globalint_1099 < ivar5) { + svar2 = substr(globalint_1099, ivar5, arg4); + } + ivar6 = subtract(getTextWidth(3793, svar1), ivar4); + setWidgetPosition(6, getWidgetActualY(new WidgetPointer(arg1)), 0, 0, new WidgetPointer(arg1)); + setWidgetSize(max(getTextWidth(3793, arg4), ivar4), getWidgetActualHeight(new WidgetPointer(arg1)), 0, 0, new WidgetPointer(arg1)); + if (ivar6 > 0) { + setWidgetPosition(subtract(getWidgetActualX(new WidgetPointer(arg1)), ivar6), getWidgetActualY(new WidgetPointer(arg1)), 0, 0, new WidgetPointer(arg1)); + setWidgetPosition(subtract(getWidgetActualX(new WidgetPointer(arg2)), ivar6), getWidgetActualY(new WidgetPointer(arg2)), 0, 0, new WidgetPointer(arg2)); + } + if (hasWindowFocus()) { + setWidgetIsHidden(false, new WidgetPointer(arg2)); + } else { + setWidgetIsHidden(true, new WidgetPointer(arg2)); + } + setScriptCallOnGameloop(3238, getClientCycle(), new WidgetPointer(arg2), arg3, "iIi", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/3238.cs2 b/dumps/scripts/3238.cs2 new file mode 100644 index 0000000..e29c1e5 --- /dev/null +++ b/dumps/scripts/3238.cs2 @@ -0,0 +1,10 @@ +void script_3238(int arg0,int arg1,int arg2) { + int ivar3; + ivar3 = script_2948(); + if ((((globalint_174 == arg2) && (mod(subtract(getClientCycle(), arg0), 40) < 20)) && ((ivar3 != -3) && (ivar3 != 21))) && (((ivar3 != 1) && isWidgetHidden(new WidgetPointer(596,7))) && hasWindowFocus())) { + setWidgetIsHidden(false, new WidgetPointer(arg1)); + } else { + setWidgetIsHidden(true, new WidgetPointer(arg1)); + } + return; +} diff --git a/dumps/scripts/3239.cs2 b/dumps/scripts/3239.cs2 new file mode 100644 index 0000000..5b0a30f --- /dev/null +++ b/dumps/scripts/3239.cs2 @@ -0,0 +1,173 @@ +void script_3239(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + string svar0; + int stack_dump0; + int stack_dump1; + int stack_dump2; + cs2func_script_2692_struct(2,0,0) structdump_3; + ivar3 = script_2948(); + if (((boolean)arg1) && (((ivar3 == -3) || (ivar3 == 21)) || ((boolean)ivar3))) { + return; + } + globalint_175 = getClientCycle(); + script_41(48758864); + globalint_1 = 0; + globalint_174 = 1; + if (globalint_1090 != 6) { + globalint_1091 = globalint_1090; + setScriptCallOnMousePressed(1173, globalint_1091, "i", new WidgetPointer(882,20)); + } + if (((boolean)arg0)) { + globalint_174 = 0; + script_3385(); + setWidgetIsHidden(false, new WidgetPointer(744,24)); + } else { + setWidgetIsHidden(true, new WidgetPointer(744,24)); + closeInterface(48758808); + } + if (arg0 == 5) { + openInterface(48758811, 975); + setWidgetIsHidden(true, new WidgetPointer(744,23)); + setWidgetIsHidden(false, new WidgetPointer(744,27)); + } else { + closeInterface(48758811); + setWidgetIsHidden(false, new WidgetPointer(744,23)); + setWidgetIsHidden(true, new WidgetPointer(744,27)); + } + if ((arg0 == 11) || (arg0 == 12)) { + globalint_547 = 0; + openInterface(48758810, 596); + script_2937(); + script_2940(arg0); + setWidgetIsHidden(false, new WidgetPointer(596,6)); + script_3230(); + } else { + script_2941(); + closeInterface(48758810); + setWidgetIsHidden(true, new WidgetPointer(744,26)); + } + if (arg0 == 7) { + openInterface(48758832, 673); + script_2213(); + setWidgetIsHidden(false, new WidgetPointer(744,48)); + } else { + closeInterface(48758832); + setWidgetIsHidden(true, new WidgetPointer(744,48)); + } + if (arg0 == 8) { + globalint_174 = 10; + setWidgetIsHidden(false, new WidgetPointer(744,49)); + } else { + closeInterface(48758833); + setWidgetIsHidden(true, new WidgetPointer(744,49)); + } + if ((arg0 == 7) || (arg0 == 8)) { + setWidgetIsHidden(true, new WidgetPointer(744,23)); + } else { + setWidgetIsHidden(false, new WidgetPointer(744,23)); + } + ivar4 = 4120; + ivar5 = 4125; + if ((((boolean)arg0) || (arg0 == 7)) || (arg0 == 8)) { + setWidgetRGB(new Color(100, 100, 100), new WidgetPointer(744,107)); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(744,107)); + setScriptCallOnMouseEntered(-1, "", new WidgetPointer(744,107)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(744,107)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(744,107)); + setScriptCallOnMousePressed(1173, 6, "i", new WidgetPointer(744,107)); + setScriptCallOnMouseEntered(44, new WidgetPointer(-32768,3), ivar5, "Id", new WidgetPointer(744,107)); + setScriptCallOnMouseExit(44, new WidgetPointer(-32768,3), ivar4, "Id", new WidgetPointer(744,107)); + } + if (arg0 == 6) { + script_2595(0); + if (((boolean)arg2)) { + stack_dump0 = cs2method6131(); + stack_dump1 = getDisplayMode(); + stack_dump2 = cs2method6131(); + structdump_3 = script_2692(stack_dump2); + script_3387(stack_dump0, stack_dump1, structdump_3.intpart_0, structdump_3.intpart_1, 0); + } + setWidgetIsHidden(false, new WidgetPointer(744,50)); + globalint_174 = 13; + } else { + if ((globalint_1090 == 6) && (arg0 != 5)) { + setWidgetIsHidden(false, new WidgetPointer(744,23)); + } + setWidgetIsHidden(true, new WidgetPointer(744,50)); + setScriptCallOnWidgetResize(-1, "", new WidgetPointer(744,50)); + setScriptCallOnWidgetResize(-1, "", new WidgetPointer(882,4)); + } + ivar6 = 0; + ivar7 = 0; + svar0 = ""; + ivar8 = 3793; + if (arg0 == 9) { + ivar6 = getWidgetActualWidth(new WidgetPointer(744,76)); + ivar7 = add(multiply(getLineCount(ivar6, 3793, getWidgetText(new WidgetPointer(744,76))), 14), 5); + setWidgetSize(ivar6, ivar7, 0, 0, new WidgetPointer(744,76)); + svar0 = getWidgetText(new WidgetPointer(744,78)); + ivar7 = add(add(getWidgetActualY(new WidgetPointer(744,76)), ivar7), 6); + if (strLength(svar0) > 0) { + setWidgetPosition(0, ivar7, 1, 0, new WidgetPointer(744,77)); + setWidgetSize(getTextWidth(ivar8, svar0), getWidgetActualHeight(new WidgetPointer(744,77)), 0, 0, new WidgetPointer(744,77)); + setWidgetText(new WidgetPointer(744,78), "" + svar0 + ""); + setScriptCallOnMouseEntered(2926, new WidgetPointer(744,77), new WidgetPointer(744,78), svar0, ivar8, 1, "IIsf1", new WidgetPointer(744,77)); + setScriptCallOnMouseExit(2926, new WidgetPointer(744,77), new WidgetPointer(744,78), svar0, ivar8, 0, "IIsf1", new WidgetPointer(744,77)); + setWidgetIsHidden(false, new WidgetPointer(744,77)); + ivar7 = add(add(ivar7, getWidgetActualHeight(new WidgetPointer(744,77))), 6); + } else { + setWidgetPosition(0, 0, 1, 0, new WidgetPointer(744,77)); + setScriptCallOnMouseEntered(-1, "", new WidgetPointer(744,77)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(744,77)); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(744,77)); + setWidgetIsHidden(true, new WidgetPointer(744,77)); + setWidgetText(new WidgetPointer(744,78), ""); + } + setWidgetSize(getTextWidth(3795, getWidgetText(new WidgetPointer(744,79))), getWidgetActualHeight(new WidgetPointer(744,79)), 0, 0, new WidgetPointer(744,79)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(744,51)), add(add(ivar7, getWidgetActualHeight(new WidgetPointer(744,79))), 11), 0, 0, new WidgetPointer(744,51)); + setWidgetIsHidden(false, new WidgetPointer(744,51)); + } else { + setWidgetIsHidden(true, new WidgetPointer(744,51)); + setWidgetPosition(0, 0, 1, 0, new WidgetPointer(744,77)); + setScriptCallOnMouseEntered(-1, "", new WidgetPointer(744,77)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(744,77)); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(744,77)); + setWidgetIsHidden(true, new WidgetPointer(744,77)); + setWidgetText(new WidgetPointer(744,78), ""); + setWidgetText(new WidgetPointer(744,76), ""); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(744,79)); + } + if (arg0 == 10) { + globalint_174 = 11; + setWidgetIsHidden(false, new WidgetPointer(744,52)); + } else { + setWidgetIsHidden(true, new WidgetPointer(744,52)); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(744,56)); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(744,57)); + } + if ((arg0 != 9) && (arg0 != 10)) { + globalint_1090 = arg0; + } + if (arg0 == 12) { + globalstring_32 = globalstring_122; + globalstring_33 = globalstring_124; + globalstring_122 = ""; + globalstring_124 = ""; + globalstring_125 = ""; + setWidgetText(new WidgetPointer(596,73), globalstring_32); + setWidgetText(new WidgetPointer(596,79), script_2949(globalstring_33)); + globalint_174 = 4; + globalint_175 = getClientCycle(); + globalint_1099 = strLength(script_2949(globalstring_33)); + script_3237(39059528, 39059529, 39059530, 3, globalstring_32); + script_3237(39059534, 39059535, 39059536, 4, script_2949(globalstring_33)); + script_2945(); + } + return; +} diff --git a/dumps/scripts/324.cs2 b/dumps/scripts/324.cs2 new file mode 100644 index 0000000..520a11e --- /dev/null +++ b/dumps/scripts/324.cs2 @@ -0,0 +1,95 @@ +void script_324(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + ivar3 = min(bitconfig_2375, 500); + setWidgetSize(0, multiplyDivide(subtract(500, ivar3), 500, 16384), 1, 2, new WidgetPointer(arg0)); + ivar4 = add(164, multiplyDivide(ivar3, 500, 91)); + ivar5 = subtract(164, multiplyDivide(ivar3, 500, 164)); + ivar6 = subtract(41, multiplyDivide(ivar3, 500, 41)); + ivar7 = script_693(ivar4, ivar5, ivar6); + setWidgetRGB(new Color(ivar7), new WidgetPointer(arg0)); + setWidgetRGB(new Color(ivar7), new WidgetPointer(arg1)); + switch (multiplyDivide(add(ivar3, 5), 500, 25)) { + case 0: + setWidgetModel(16353, new WidgetPointer(arg2)); + break; + case 1: + setWidgetModel(16354, new WidgetPointer(arg2)); + break; + case 2: + setWidgetModel(16355, new WidgetPointer(arg2)); + break; + case 3: + setWidgetModel(16356, new WidgetPointer(arg2)); + break; + case 4: + setWidgetModel(16357, new WidgetPointer(arg2)); + break; + case 5: + setWidgetModel(16358, new WidgetPointer(arg2)); + break; + case 6: + setWidgetModel(16359, new WidgetPointer(arg2)); + break; + case 7: + setWidgetModel(16360, new WidgetPointer(arg2)); + break; + case 8: + setWidgetModel(16361, new WidgetPointer(arg2)); + break; + case 9: + setWidgetModel(16362, new WidgetPointer(arg2)); + break; + case 10: + setWidgetModel(16363, new WidgetPointer(arg2)); + break; + case 11: + setWidgetModel(16364, new WidgetPointer(arg2)); + break; + case 12: + setWidgetModel(16365, new WidgetPointer(arg2)); + break; + case 13: + setWidgetModel(16366, new WidgetPointer(arg2)); + break; + case 14: + setWidgetModel(16367, new WidgetPointer(arg2)); + break; + case 15: + setWidgetModel(16368, new WidgetPointer(arg2)); + break; + case 16: + setWidgetModel(16369, new WidgetPointer(arg2)); + break; + case 17: + setWidgetModel(16370, new WidgetPointer(arg2)); + break; + case 18: + setWidgetModel(16371, new WidgetPointer(arg2)); + break; + case 19: + setWidgetModel(16372, new WidgetPointer(arg2)); + break; + case 20: + setWidgetModel(16373, new WidgetPointer(arg2)); + break; + case 21: + setWidgetModel(16374, new WidgetPointer(arg2)); + break; + case 22: + setWidgetModel(16375, new WidgetPointer(arg2)); + break; + case 23: + setWidgetModel(16376, new WidgetPointer(arg2)); + break; + case 24: + setWidgetModel(16377, new WidgetPointer(arg2)); + break; + default: + setWidgetModel(16378, new WidgetPointer(arg2)); + } + return; +} diff --git a/dumps/scripts/3240.cs2 b/dumps/scripts/3240.cs2 new file mode 100644 index 0000000..46a8e9c --- /dev/null +++ b/dumps/scripts/3240.cs2 @@ -0,0 +1,6 @@ +void script_3240() { + if (((boolean)globalint_1200)) { + setWidgetText(new WidgetPointer(933,277), globalstring_312); + } + return; +} diff --git a/dumps/scripts/3241.cs2 b/dumps/scripts/3241.cs2 new file mode 100644 index 0000000..4b34fba --- /dev/null +++ b/dumps/scripts/3241.cs2 @@ -0,0 +1,4 @@ +void script_3241() { + script_2276(globalint_1200, globalint_1215, 61145366); + return; +} diff --git a/dumps/scripts/3242.cs2 b/dumps/scripts/3242.cs2 new file mode 100644 index 0000000..c0fbcd3 --- /dev/null +++ b/dumps/scripts/3242.cs2 @@ -0,0 +1,4 @@ +void script_3242() { + script_2276(globalint_1200, globalint_1216, 61145367); + return; +} diff --git a/dumps/scripts/3243.cs2 b/dumps/scripts/3243.cs2 new file mode 100644 index 0000000..4ef39fc --- /dev/null +++ b/dumps/scripts/3243.cs2 @@ -0,0 +1,4 @@ +void script_3243() { + script_2276(globalint_1200, globalint_1217, 61145368); + return; +} diff --git a/dumps/scripts/3244.cs2 b/dumps/scripts/3244.cs2 new file mode 100644 index 0000000..4b76813 --- /dev/null +++ b/dumps/scripts/3244.cs2 @@ -0,0 +1,4 @@ +void script_3244() { + script_2276(globalint_1200, globalint_1218, 61145369); + return; +} diff --git a/dumps/scripts/3245.cs2 b/dumps/scripts/3245.cs2 new file mode 100644 index 0000000..826f310 --- /dev/null +++ b/dumps/scripts/3245.cs2 @@ -0,0 +1,4 @@ +void script_3245() { + script_2276(globalint_1200, globalint_1219, 61145370); + return; +} diff --git a/dumps/scripts/3246.cs2 b/dumps/scripts/3246.cs2 new file mode 100644 index 0000000..51e2d3e --- /dev/null +++ b/dumps/scripts/3246.cs2 @@ -0,0 +1,4 @@ +void script_3246() { + script_2276(globalint_1200, globalint_1220, 61145371); + return; +} diff --git a/dumps/scripts/3247.cs2 b/dumps/scripts/3247.cs2 new file mode 100644 index 0000000..f2ef349 --- /dev/null +++ b/dumps/scripts/3247.cs2 @@ -0,0 +1,4 @@ +void script_3247() { + script_3248(); + return; +} diff --git a/dumps/scripts/3248.cs2 b/dumps/scripts/3248.cs2 new file mode 100644 index 0000000..bd03042 --- /dev/null +++ b/dumps/scripts/3248.cs2 @@ -0,0 +1,20 @@ +void script_3248() { + if (((boolean)globalint_1201)) { + setWidgetText(new WidgetPointer(933,287), globalstring_313); + setWidgetText(new WidgetPointer(933,288), cs2method_3408(105, 115, 2857, globalint_1221)); + setWidgetText(new WidgetPointer(933,289), cs2method_3408(105, 115, 2857, globalint_1222)); + setWidgetText(new WidgetPointer(933,290), cs2method_3408(105, 115, 2857, globalint_1223)); + setWidgetText(new WidgetPointer(933,291), cs2method_3408(105, 115, 2857, globalint_1224)); + setWidgetText(new WidgetPointer(933,292), cs2method_3408(105, 115, 2857, globalint_1225)); + setWidgetText(new WidgetPointer(933,293), cs2method_3408(105, 115, 2857, globalint_1226)); + } else { + setWidgetText(new WidgetPointer(933,287), ""); + setWidgetText(new WidgetPointer(933,288), ""); + setWidgetText(new WidgetPointer(933,289), ""); + setWidgetText(new WidgetPointer(933,290), ""); + setWidgetText(new WidgetPointer(933,291), ""); + setWidgetText(new WidgetPointer(933,292), ""); + setWidgetText(new WidgetPointer(933,293), ""); + } + return; +} diff --git a/dumps/scripts/3249.cs2 b/dumps/scripts/3249.cs2 new file mode 100644 index 0000000..5e66d6b --- /dev/null +++ b/dumps/scripts/3249.cs2 @@ -0,0 +1,6 @@ +void script_3249() { + if (((boolean)globalint_1201)) { + setWidgetText(new WidgetPointer(933,287), globalstring_313); + } + return; +} diff --git a/dumps/scripts/325.cs2 b/dumps/scripts/325.cs2 new file mode 100644 index 0000000..5a1b095 --- /dev/null +++ b/dumps/scripts/325.cs2 @@ -0,0 +1,9 @@ +void script_325() { + setWidgetIsHidden(true, new WidgetPointer(725,86)); + setWidgetIsHidden(false, new WidgetPointer(725,85)); + setWidgetSprite(1057, new WidgetPointer(725,88)); + setWidgetSprite(1051, new WidgetPointer(725,87)); + globalint_783 = 0; + script_328(47513685); + return; +} diff --git a/dumps/scripts/3250.cs2 b/dumps/scripts/3250.cs2 new file mode 100644 index 0000000..cc86165 --- /dev/null +++ b/dumps/scripts/3250.cs2 @@ -0,0 +1,4 @@ +void script_3250() { + script_2276(globalint_1201, globalint_1221, 61145376); + return; +} diff --git a/dumps/scripts/3251.cs2 b/dumps/scripts/3251.cs2 new file mode 100644 index 0000000..5a23269 --- /dev/null +++ b/dumps/scripts/3251.cs2 @@ -0,0 +1,4 @@ +void script_3251() { + script_2276(globalint_1201, globalint_1222, 61145377); + return; +} diff --git a/dumps/scripts/3252.cs2 b/dumps/scripts/3252.cs2 new file mode 100644 index 0000000..4af6c42 --- /dev/null +++ b/dumps/scripts/3252.cs2 @@ -0,0 +1,4 @@ +void script_3252() { + script_2276(globalint_1201, globalint_1223, 61145378); + return; +} diff --git a/dumps/scripts/3253.cs2 b/dumps/scripts/3253.cs2 new file mode 100644 index 0000000..b9e2c96 --- /dev/null +++ b/dumps/scripts/3253.cs2 @@ -0,0 +1,4 @@ +void script_3253() { + script_2276(globalint_1201, globalint_1224, 61145379); + return; +} diff --git a/dumps/scripts/3254.cs2 b/dumps/scripts/3254.cs2 new file mode 100644 index 0000000..12f417a --- /dev/null +++ b/dumps/scripts/3254.cs2 @@ -0,0 +1,4 @@ +void script_3254() { + script_2276(globalint_1201, globalint_1225, 61145380); + return; +} diff --git a/dumps/scripts/3255.cs2 b/dumps/scripts/3255.cs2 new file mode 100644 index 0000000..21f2130 --- /dev/null +++ b/dumps/scripts/3255.cs2 @@ -0,0 +1,4 @@ +void script_3255() { + script_2276(globalint_1201, globalint_1226, 61145381); + return; +} diff --git a/dumps/scripts/3256.cs2 b/dumps/scripts/3256.cs2 new file mode 100644 index 0000000..6d2a515 --- /dev/null +++ b/dumps/scripts/3256.cs2 @@ -0,0 +1,4 @@ +void script_3256() { + script_3257(); + return; +} diff --git a/dumps/scripts/3257.cs2 b/dumps/scripts/3257.cs2 new file mode 100644 index 0000000..bcf0ed0 --- /dev/null +++ b/dumps/scripts/3257.cs2 @@ -0,0 +1,20 @@ +void script_3257() { + if (((boolean)globalint_1202)) { + setWidgetText(new WidgetPointer(933,301), globalstring_314); + setWidgetText(new WidgetPointer(933,302), cs2method_3408(105, 115, 2857, globalint_1227)); + setWidgetText(new WidgetPointer(933,303), cs2method_3408(105, 115, 2857, globalint_1228)); + setWidgetText(new WidgetPointer(933,304), cs2method_3408(105, 115, 2857, globalint_1229)); + setWidgetText(new WidgetPointer(933,305), cs2method_3408(105, 115, 2857, globalint_1230)); + setWidgetText(new WidgetPointer(933,306), cs2method_3408(105, 115, 2857, globalint_1231)); + setWidgetText(new WidgetPointer(933,307), cs2method_3408(105, 115, 2857, globalint_1232)); + } else { + setWidgetText(new WidgetPointer(933,301), ""); + setWidgetText(new WidgetPointer(933,302), ""); + setWidgetText(new WidgetPointer(933,303), ""); + setWidgetText(new WidgetPointer(933,304), ""); + setWidgetText(new WidgetPointer(933,305), ""); + setWidgetText(new WidgetPointer(933,306), ""); + setWidgetText(new WidgetPointer(933,307), ""); + } + return; +} diff --git a/dumps/scripts/3258.cs2 b/dumps/scripts/3258.cs2 new file mode 100644 index 0000000..b9ef564 --- /dev/null +++ b/dumps/scripts/3258.cs2 @@ -0,0 +1,6 @@ +void script_3258() { + if (((boolean)globalint_1202)) { + setWidgetText(new WidgetPointer(933,301), globalstring_314); + } + return; +} diff --git a/dumps/scripts/3259.cs2 b/dumps/scripts/3259.cs2 new file mode 100644 index 0000000..81ee4fa --- /dev/null +++ b/dumps/scripts/3259.cs2 @@ -0,0 +1,4 @@ +void script_3259() { + script_2276(globalint_1202, globalint_1227, 61145390); + return; +} diff --git a/dumps/scripts/326.cs2 b/dumps/scripts/326.cs2 new file mode 100644 index 0000000..f713e27 --- /dev/null +++ b/dumps/scripts/326.cs2 @@ -0,0 +1,9 @@ +void script_326() { + setWidgetIsHidden(false, new WidgetPointer(725,86)); + setWidgetIsHidden(true, new WidgetPointer(725,85)); + setWidgetSprite(1057, new WidgetPointer(725,87)); + setWidgetSprite(1049, new WidgetPointer(725,88)); + globalint_783 = 1; + script_328(47513686); + return; +} diff --git a/dumps/scripts/3260.cs2 b/dumps/scripts/3260.cs2 new file mode 100644 index 0000000..b8d7775 --- /dev/null +++ b/dumps/scripts/3260.cs2 @@ -0,0 +1,4 @@ +void script_3260() { + script_2276(globalint_1202, globalint_1228, 61145391); + return; +} diff --git a/dumps/scripts/3261.cs2 b/dumps/scripts/3261.cs2 new file mode 100644 index 0000000..1914ae4 --- /dev/null +++ b/dumps/scripts/3261.cs2 @@ -0,0 +1,4 @@ +void script_3261() { + script_2276(globalint_1202, globalint_1229, 61145392); + return; +} diff --git a/dumps/scripts/3262.cs2 b/dumps/scripts/3262.cs2 new file mode 100644 index 0000000..03365a3 --- /dev/null +++ b/dumps/scripts/3262.cs2 @@ -0,0 +1,4 @@ +void script_3262() { + script_2276(globalint_1202, globalint_1230, 61145393); + return; +} diff --git a/dumps/scripts/3263.cs2 b/dumps/scripts/3263.cs2 new file mode 100644 index 0000000..22f01ad --- /dev/null +++ b/dumps/scripts/3263.cs2 @@ -0,0 +1,4 @@ +void script_3263() { + script_2276(globalint_1202, globalint_1231, 61145394); + return; +} diff --git a/dumps/scripts/3264.cs2 b/dumps/scripts/3264.cs2 new file mode 100644 index 0000000..737ce18 --- /dev/null +++ b/dumps/scripts/3264.cs2 @@ -0,0 +1,4 @@ +void script_3264() { + script_2276(globalint_1202, globalint_1232, 61145395); + return; +} diff --git a/dumps/scripts/3265.cs2 b/dumps/scripts/3265.cs2 new file mode 100644 index 0000000..a810900 --- /dev/null +++ b/dumps/scripts/3265.cs2 @@ -0,0 +1,14 @@ +int script_3265() { + int ivar0; + int ivar1; + int ivar2; + ivar0 = 0; + ivar1 = 0; + ivar2 = 0; + while (ivar0 < min(bitconfig_7554, 15)) { + ivar1 = add(ivar1, subtract(22, ivar2)); + ivar2 = min(add(ivar2, 3), 19); + ivar0 = add(ivar0, 1); + } + return ivar1; +} diff --git a/dumps/scripts/3266.cs2 b/dumps/scripts/3266.cs2 new file mode 100644 index 0000000..d34646b --- /dev/null +++ b/dumps/scripts/3266.cs2 @@ -0,0 +1,20 @@ +cs2func_script_3266_struct(2,0,0) script_3266(int arg0) { + int ivar1; + int ivar2; + int ivar3; + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + if (((boolean)arg0) && (bitconfig_7554 != 0)) { + return newstruct cs2func_script_3266_struct(1, 0); + } + while (ivar1 < min(subtract(bitconfig_7554, 1), 15)) { + ivar2 = add(ivar2, subtract(22, ivar3)); + ivar3 = min(add(ivar3, 3), 19); + if (arg0 == ivar2) { + return newstruct cs2func_script_3266_struct(1, add(ivar1, 1)); + } + ivar1 = add(ivar1, 1); + } + return newstruct cs2func_script_3266_struct(0, 0); +} diff --git a/dumps/scripts/3267.cs2 b/dumps/scripts/3267.cs2 new file mode 100644 index 0000000..2a78a6d --- /dev/null +++ b/dumps/scripts/3267.cs2 @@ -0,0 +1,765 @@ +void script_3267() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + int ivar22; + int ivar23; + int ivar24; + int ivar25; + int ivar26; + int ivar27; + int ivar28; + int ivar29; + int ivar30; + int ivar31; + int ivar32; + int ivar33; + int ivar34; + int ivar35; + int ivar36; + int ivar37; + int ivar38; + int ivar39; + int ivar40; + int ivar41; + cs2func_script_3273_struct(3,0,0) structdump_0; + cs2func_script_3273_struct(3,0,0) structdump_1; + cs2func_script_3273_struct(3,0,0) structdump_2; + int stack_dump3; + cs2func_script_3266_struct(2,0,0) structdump_4; + ivar0 = 0; + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + ivar4 = 0; + ivar5 = 0; + ivar6 = 0; + ivar7 = 0; + ivar8 = 0; + ivar9 = 25; + ivar10 = 25; + ivar11 = 50; + ivar12 = 25; + ivar13 = 25; + ivar14 = 50; + ivar15 = 25; + ivar16 = 25; + ivar17 = 50; + ivar18 = 100; + ivar19 = 50; + ivar20 = 25; + ivar21 = 150; + ivar22 = 25; + ivar23 = 100; + ivar24 = 25; + ivar25 = 100; + ivar26 = 25; + ivar27 = 50; + ivar28 = 25; + ivar29 = 50; + ivar30 = 25; + ivar31 = 25; + ivar32 = 25; + ivar33 = 150; + ivar34 = 100; + ivar35 = 200; + ivar36 = 100; + globalint_1185 = max(subtract(globalint_1185, 2), 0); + cs2method2103(globalint_1185, new WidgetPointer(933,251)); + cs2method2103(subtract(255, globalint_1185), new WidgetPointer(933,297)); + cs2method2103(subtract(255, globalint_1185), new WidgetPointer(933,298)); + cs2method2103(subtract(255, globalint_1185), new WidgetPointer(933,299)); + ivar37 = 0; + if (globalint_1188 == 2) { + ivar37 = 792; + } else { + if (globalint_1188 == 3) { + ivar37 = 1583; + } + } + ivar38 = multiplyDivide(globalint_1195, 10000, 1267); + structdump_0 = script_3273(); + ivar5 = structdump_0.intpart_2; + ivar4 = structdump_0.intpart_1; + ivar3 = structdump_0.intpart_0; + ivar39 = ivar5; + ivar40 = script_3274(); + ivar41 = subtract(10000, multiply(min(bitconfig_7554, 6), 1000)); + if (((boolean)globalint_1185) && (globalint_1192 != 0)) { + if (globalint_1186 < 350) { + if (getWidgetShadeColor(new WidgetPointer(933,186)) <= 31) { + globalint_1189 = 7; + } else { + if (getWidgetShadeColor(new WidgetPointer(933,186)) > 220) { + globalint_1189 = -7; + } + } + cs2method2103(add(getWidgetShadeColor(new WidgetPointer(933,186)), globalint_1189), new WidgetPointer(933,186)); + } else if ((globalint_1186 >= 350) && (globalint_1186 < 400)) { + if (globalint_1186 == 350) { + cs2method2103(255, new WidgetPointer(933,186)); + } + if (getWidgetShadeColor(new WidgetPointer(933,37)) <= 31) { + globalint_1189 = 7; + } else { + if (getWidgetShadeColor(new WidgetPointer(933,37)) > 220) { + globalint_1189 = -7; + } + } + cs2method2103(add(getWidgetShadeColor(new WidgetPointer(933,37)), globalint_1189), new WidgetPointer(933,37)); + } else if ((globalint_1186 >= 400) && (globalint_1186 < 1350)) { + if (globalint_1186 == 400) { + cs2method2103(255, new WidgetPointer(933,37)); + } + if (getWidgetShadeColor(new WidgetPointer(933,53)) <= 31) { + globalint_1189 = 7; + } else { + if (getWidgetShadeColor(new WidgetPointer(933,53)) > 220) { + globalint_1189 = -7; + } + } + cs2method2103(add(getWidgetShadeColor(new WidgetPointer(933,53)), globalint_1189), new WidgetPointer(933,53)); + } else { + if ((globalint_1186 >= 1350) && (globalint_1186 < 1600)) { + if (globalint_1186 == 1350) { + cs2method2103(255, new WidgetPointer(933,53)); + } + if (getWidgetShadeColor(new WidgetPointer(933,37)) <= 31) { + globalint_1189 = 7; + } else { + if (getWidgetShadeColor(new WidgetPointer(933,37)) > 220) { + globalint_1189 = -7; + } + } + cs2method2103(add(getWidgetShadeColor(new WidgetPointer(933,37)), globalint_1189), new WidgetPointer(933,37)); + } + } + if (globalint_1186 < ivar9) { + setWidgetIsHidden(false, new WidgetPointer(933,192)); + setWidgetIsHidden(false, new WidgetPointer(933,17)); + if (((boolean)globalint_1186)) { + playSoundEffect(8802, 1, 0); + } + } else if (globalint_1186 < add(ivar9, ivar10)) { + setWidgetIsHidden(false, new WidgetPointer(933,187)); + setWidgetIsHidden(false, new WidgetPointer(933,240)); + if (globalint_1187 < globalint_1319) { + setWidgetText(new WidgetPointer(933,240), "Floor " + intToStr(globalint_1187) + ":"); + setWidgetRGB(new Color(160, 0, 0), new WidgetPointer(933,240)); + } else { + setWidgetText(new WidgetPointer(933,240), "Floor " + intToStr(globalint_1319) + ":"); + } + setWidgetIsHidden(false, new WidgetPointer(933,22)); + setWidgetSize(add(getWidgetActualWidth(new WidgetPointer(933,23)), 5), add(getWidgetActualHeight(new WidgetPointer(933,23)), 5), 0, 0, new WidgetPointer(933,23)); + if (globalint_1186 == ivar9) { + playSoundEffect(8802, 1, 0); + } + cs2method2103(min(255, add(getWidgetShadeColor(new WidgetPointer(933,23)), 30)), new WidgetPointer(933,23)); + } else if (globalint_1186 < add(add(ivar9, ivar10), ivar11)) { + ivar8 = multiplyDivide(add(subtract(globalint_1186, add(ivar9, ivar10)), 1), ivar11, 100); + if (((boolean)ivar8)) { + globalint_1270 = 0; + } + setWidgetIsHidden(false, new WidgetPointer(933,241)); + setWidgetText(new WidgetPointer(933,241), intToStr(multiplyDivide(divide(add(globalint_1237, 5), 10), 100, ivar8))); + if (multiplyDivide(divide(add(globalint_1237, 5), 10), 100, ivar8) != globalint_1270) { + playSoundEffect(8806, 1, 0); + globalint_1270 = multiplyDivide(divide(add(globalint_1237, 5), 10), 100, ivar8); + } + } else if (globalint_1186 < add(add(add(ivar9, ivar10), ivar11), ivar12)) { + setWidgetIsHidden(false, new WidgetPointer(933,190)); + ivar8 = multiplyDivide(add(subtract(globalint_1186, add(add(ivar9, ivar10), ivar11)), 1), ivar12, 100); + cs2method2103(subtract(255, divide(multiply(ivar8, 255), 100)), new WidgetPointer(933,190)); + } else if (globalint_1186 < add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13)) { + setWidgetIsHidden(false, new WidgetPointer(933,188)); + setWidgetIsHidden(false, new WidgetPointer(933,227)); + if (isMember()) { + setWidgetText(new WidgetPointer(933,227), "Prestige " + intToStr(min(60, max(bitconfig_7550, bitconfig_7551)))); + } else { + setWidgetText(new WidgetPointer(933,227), "Prestige " + intToStr(min(35, max(bitconfig_7550, bitconfig_7551)))); + } + setWidgetIsHidden(false, new WidgetPointer(933,21)); + setWidgetSize(add(getWidgetActualWidth(new WidgetPointer(933,24)), 5), add(getWidgetActualHeight(new WidgetPointer(933,24)), 5), 0, 0, new WidgetPointer(933,24)); + if (globalint_1186 == add(add(add(ivar9, ivar10), ivar11), ivar12)) { + playSoundEffect(8802, 1, 0); + } + cs2method2103(min(255, add(getWidgetShadeColor(new WidgetPointer(933,24)), 30)), new WidgetPointer(933,24)); + } else if (globalint_1186 < add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14)) { + ivar8 = multiplyDivide(add(subtract(globalint_1186, add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13)), 1), ivar14, 100); + if (((boolean)ivar8)) { + globalint_1270 = 0; + } + setWidgetIsHidden(false, new WidgetPointer(933,228)); + setWidgetText(new WidgetPointer(933,228), intToStr(multiplyDivide(divide(add(globalint_1238, 5), 10), 100, ivar8))); + if (multiplyDivide(divide(add(globalint_1238, 5), 10), 100, ivar8) != globalint_1270) { + playSoundEffect(8806, 1, 0); + globalint_1270 = multiplyDivide(divide(add(globalint_1238, 5), 10), 100, ivar8); + } + } else if (globalint_1186 < add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15)) { + setWidgetIsHidden(false, new WidgetPointer(933,191)); + ivar8 = multiplyDivide(add(subtract(globalint_1186, add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14)), 1), ivar15, 100); + cs2method2103(subtract(255, divide(multiply(ivar8, 255), 100)), new WidgetPointer(933,191)); + } else if (globalint_1186 < add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16)) { + ivar8 = multiplyDivide(add(subtract(globalint_1186, add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15)), 1), ivar16, 100); + setWidgetIsHidden(false, new WidgetPointer(933,189)); + setWidgetIsHidden(false, new WidgetPointer(933,214)); + setWidgetIsHidden(false, new WidgetPointer(933,20)); + setWidgetSize(add(getWidgetActualWidth(new WidgetPointer(933,25)), 5), add(getWidgetActualHeight(new WidgetPointer(933,25)), 5), 0, 0, new WidgetPointer(933,25)); + if (globalint_1186 == add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15)) { + playSoundEffect(8802, 1, 0); + } + cs2method2103(min(255, add(getWidgetShadeColor(new WidgetPointer(933,25)), 30)), new WidgetPointer(933,25)); + } else if (globalint_1186 < add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17)) { + ivar8 = multiplyDivide(add(subtract(globalint_1186, add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16)), 1), ivar17, 100); + if (((boolean)ivar8)) { + globalint_1270 = 0; + } + setWidgetIsHidden(false, new WidgetPointer(933,215)); + setWidgetText(new WidgetPointer(933,215), intToStr(multiplyDivide(divide(add(globalint_1239, 5), 10), 100, ivar8))); + if (multiplyDivide(divide(add(globalint_1239, 5), 10), 100, ivar8) != globalint_1270) { + playSoundEffect(8806, 1, 0); + globalint_1270 = multiplyDivide(divide(add(globalint_1239, 5), 10), 100, ivar8); + } + } else if (globalint_1186 < add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18)) { + setWidgetIsHidden(true, new WidgetPointer(933,186)); + ivar8 = multiplyDivide(add(subtract(globalint_1186, add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17)), 1), ivar18, 100); + if (((boolean)ivar8)) { + globalint_1270 = 0; + } + setWidgetIsHidden(false, new WidgetPointer(933,19)); + setWidgetText(new WidgetPointer(933,39), intToStr(multiplyDivide(divide(add(globalint_1239, 5), 10), 100, ivar8))); + if (multiplyDivide(divide(add(globalint_1239, 5), 10), 100, ivar8) != globalint_1270) { + playSoundEffect(9243, 1, 0); + globalint_1270 = multiplyDivide(divide(add(globalint_1239, 5), 10), 100, ivar8); + } + } else if (globalint_1186 < add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19)) { + cs2method2103(255, new WidgetPointer(933,37)); + setWidgetIsHidden(false, new WidgetPointer(933,83)); + setWidgetIsHidden(false, new WidgetPointer(933,18)); + setWidgetIsHidden(false, new WidgetPointer(933,53)); + if (globalint_1186 == add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18)) { + playSoundEffect(8802, 1, 0); + } + } else if (globalint_1186 < add(add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19), ivar20)) { + setWidgetIsHidden(false, new WidgetPointer(933,54)); + if (globalint_1186 == add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19)) { + playSoundEffect(8802, 1, 0); + } + } else if (globalint_1186 < add(add(add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19), ivar20), ivar21)) { + setWidgetIsHidden(false, new WidgetPointer(933,68)); + setWidgetIsHidden(false, new WidgetPointer(933,69)); + setWidgetIsHidden(false, new WidgetPointer(933,70)); + setWidgetIsHidden(false, new WidgetPointer(933,71)); + setWidgetIsHidden(false, new WidgetPointer(933,72)); + setWidgetIsHidden(false, new WidgetPointer(933,73)); + setWidgetIsHidden(false, new WidgetPointer(933,74)); + if (globalint_1186 == add(add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19), ivar20)) { + playSoundEffect(8806, 1, 0); + } + if (globalint_1186 == add(add(add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19), ivar20), ivar21)) { + playSoundEffect(8802, 1, 0); + } + structdump_1 = script_3273(); + ivar5 = structdump_1.intpart_2; + ivar4 = structdump_1.intpart_1; + ivar3 = structdump_1.intpart_0; + if (ivar3 < 3) { + setWidgetIsHidden(false, new WidgetPointer(933,82)); + } + ivar8 = multiplyDivide(add(subtract(globalint_1186, add(add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19), ivar20)), 1), divide(ivar21, 3), 100); + if (globalint_1186 < add(add(add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19), ivar20), divide(ivar21, 3))) { + if (globalint_1186 == add(add(add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19), ivar20), divide(ivar21, 3))) { + playSoundEffect(8802, 1, 0); + } + cs2method2103(min(200, subtract(255, divide(multiply(ivar8, 255), 100))), new WidgetPointer(933,68)); + setWidgetText(new WidgetPointer(933,74), "+0%"); + if (((boolean)ivar8)) { + playSoundEffect(8806, 1, 0); + } + if (globalint_1186 == 475) { + playSoundEffect(9241, 1, 0); + } + } else if ((globalint_1186 < add(add(add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19), ivar20), multiply(divide(ivar21, 3), 2))) && (globalint_1188 > 1)) { + if ((globalint_1186 == add(add(add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19), ivar20), multiply(divide(ivar21, 3), 2))) && (globalint_1188 > 1)) { + playSoundEffect(8802, 1, 0); + } + ivar0 = 10000; + ivar1 = add(ivar0, 792); + if (ivar8 == 33) { + globalint_1270 = ivar0; + playSoundEffect(9241, 1, 0); + } + cs2method2103(min(200, divide(multiply(divide(ivar8, 2), 255), 100)), new WidgetPointer(933,68)); + cs2method2103(min(200, subtract(255, divide(multiply(ivar8, 255), 100))), new WidgetPointer(933,69)); + setWidgetText(new WidgetPointer(933,74), "+" + intToStr(divide(add(divide(multiplyDivide(ivar8, 100, subtract(ivar1, 10000)), 2), 50), 100)) + "%"); + if (divide(add(divide(multiplyDivide(ivar8, 100, subtract(ivar1, 10000)), 2), 50), 100) != globalint_1270) { + playSoundEffect(8806, 1, 0); + globalint_1270 = divide(add(divide(multiplyDivide(ivar8, 100, subtract(ivar1, 10000)), 2), 50), 100); + } + setWidgetText(new WidgetPointer(933,96), intToStr(divide(add(add(ivar0, divide(multiplyDivide(ivar8, 100, subtract(ivar1, ivar0)), 2)), 50), 100)) + "%"); + setWidgetSize(multiplyDivide(8192, 100, divide(add(add(ivar0, divide(multiplyDivide(ivar8, 100, subtract(ivar1, ivar0)), 2)), 50), 100)), 16384, 2, 2, new WidgetPointer(933,112)); + if (globalint_1186 == 525) { + playSoundEffect(9241, 1, 0); + } + } else { + if (globalint_1188 > 2) { + ivar0 = add(10000, 792); + ivar1 = add(10000, 1583); + if (ivar8 == 66) { + globalint_1270 = ivar0; + playSoundEffect(9241, 1, 0); + } + cs2method2103(min(200, divide(multiply(divide(ivar8, 3), 255), 100)), new WidgetPointer(933,69)); + cs2method2103(min(200, subtract(255, divide(multiply(ivar8, 255), 100))), new WidgetPointer(933,70)); + setWidgetText(new WidgetPointer(933,74), "+" + intToStr(divide(add(divide(multiplyDivide(ivar8, 100, subtract(ivar1, 10000)), 3), 50), 100)) + "%"); + if (divide(add(divide(multiplyDivide(ivar8, 100, subtract(ivar1, 10000)), 3), 50), 100) != globalint_1270) { + playSoundEffect(8806, 1, 0); + globalint_1270 = divide(add(divide(multiplyDivide(ivar8, 100, subtract(ivar1, 10000)), 3), 50), 100); + } + setWidgetText(new WidgetPointer(933,96), intToStr(divide(add(add(ivar0, divide(multiplyDivide(ivar8, 100, subtract(ivar1, ivar0)), 3)), 50), 100)) + "%"); + setWidgetSize(multiplyDivide(8192, 100, divide(add(add(ivar0, divide(multiplyDivide(ivar8, 100, subtract(ivar1, ivar0)), 3)), 50), 100)), 16384, 2, 2, new WidgetPointer(933,112)); + if (globalint_1186 == 575) { + playSoundEffect(9241, 1, 0); + } + } + } + } else if (globalint_1186 < add(add(add(add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19), ivar20), ivar21), ivar22)) { + setWidgetIsHidden(false, new WidgetPointer(933,55)); + if (globalint_1186 == add(add(add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19), ivar20), ivar21)) { + playSoundEffect(8802, 1, 0); + } + } else if (globalint_1186 < add(add(add(add(add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19), ivar20), ivar21), ivar22), ivar23)) { + ivar8 = multiplyDivide(add(subtract(globalint_1186, add(add(add(add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19), ivar20), ivar21), ivar22)), 1), ivar23, 100); + setWidgetIsHidden(false, new WidgetPointer(933,64)); + setWidgetIsHidden(false, new WidgetPointer(933,75)); + setWidgetSize(multiplyDivide(multiplyDivide(globalint_1195, 10000, 16384), 100, ivar8), 16384, 2, 2, new WidgetPointer(933,172)); + ivar0 = add(10000, ivar37); + ivar1 = add(add(10000, ivar37), ivar38); + if (((boolean)ivar8)) { + globalint_1270 = ivar0; + } + if (ivar1 >= ivar0) { + setWidgetText(new WidgetPointer(933,75), "+" + intToStr(divide(add(multiplyDivide(ivar8, 100, subtract(ivar1, ivar0)), 50), 100)) + "%"); + } else { + setWidgetText(new WidgetPointer(933,75), intToStr(divide(add(multiplyDivide(ivar8, 100, subtract(ivar1, ivar0)), 50), 100)) + "%"); + } + setWidgetText(new WidgetPointer(933,96), intToStr(divide(add(add(ivar0, multiplyDivide(ivar8, 100, subtract(ivar1, ivar0))), 50), 100)) + "%"); + if (divide(add(add(ivar0, multiplyDivide(ivar8, 100, subtract(ivar1, ivar0))), 50), 100) != globalint_1270) { + playSoundEffect(8806, 1, 0); + globalint_1270 = divide(add(add(ivar0, multiplyDivide(ivar8, 100, subtract(ivar1, ivar0))), 50), 100); + } + setWidgetSize(multiplyDivide(8192, 100, divide(add(add(ivar0, multiplyDivide(ivar8, 100, subtract(ivar1, ivar0))), 50), 100)), 16384, 2, 2, new WidgetPointer(933,112)); + } else if (globalint_1186 < add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19), ivar20), ivar21), ivar22), ivar23), ivar24)) { + setWidgetIsHidden(false, new WidgetPointer(933,56)); + if (globalint_1186 == add(add(add(add(add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19), ivar20), ivar21), ivar22), ivar23)) { + playSoundEffect(8802, 1, 0); + } + } else if (globalint_1186 < add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19), ivar20), ivar21), ivar22), ivar23), ivar24), ivar25)) { + setWidgetIsHidden(false, new WidgetPointer(933,57)); + setWidgetIsHidden(false, new WidgetPointer(933,78)); + setWidgetIsHidden(false, new WidgetPointer(933,80)); + setWidgetIsHidden(false, new WidgetPointer(933,59)); + ivar8 = multiplyDivide(add(subtract(globalint_1186, add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19), ivar20), ivar21), ivar22), ivar23), ivar24)), 1), ivar25, 100); + cs2method2103(subtract(255, divide(multiply(ivar8, 255), 100)), new WidgetPointer(933,78)); + cs2method2103(subtract(255, divide(multiply(ivar8, 255), 100)), new WidgetPointer(933,80)); + structdump_2 = script_3273(); + ivar5 = structdump_2.intpart_2; + ivar4 = structdump_2.intpart_1; + ivar3 = structdump_2.intpart_0; + setWidgetText(new WidgetPointer(933,57), intToStr(ivar3) + " : " + intToStr(ivar4)); + if (globalint_1186 == add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19), ivar20), ivar21), ivar22), ivar23), ivar24)) { + playSoundEffect(8806, 1, 0); + } + ivar0 = add(add(10000, ivar37), ivar38); + ivar1 = add(add(add(10000, ivar37), ivar38), ivar39); + if (((boolean)ivar8)) { + globalint_1270 = ivar0; + } + if (ivar1 >= ivar0) { + setWidgetText(new WidgetPointer(933,59), "+" + intToStr(divide(add(multiplyDivide(ivar8, 100, subtract(ivar1, ivar0)), 50), 100)) + "%"); + } else { + setWidgetText(new WidgetPointer(933,59), intToStr(divide(add(multiplyDivide(ivar8, 100, subtract(ivar1, ivar0)), 50), 100)) + "%"); + } + setWidgetText(new WidgetPointer(933,96), intToStr(divide(add(add(ivar0, multiplyDivide(ivar8, 100, subtract(ivar1, ivar0))), 50), 100)) + "%"); + if (divide(add(add(ivar0, multiplyDivide(ivar8, 100, subtract(ivar1, ivar0))), 50), 100) != globalint_1270) { + playSoundEffect(8806, 1, 0); + globalint_1270 = divide(add(add(ivar0, multiplyDivide(ivar8, 100, subtract(ivar1, ivar0))), 50), 100); + } + setWidgetSize(multiplyDivide(8192, 100, divide(add(add(ivar0, multiplyDivide(ivar8, 100, subtract(ivar1, ivar0))), 50), 100)), 16384, 2, 2, new WidgetPointer(933,112)); + } else if (globalint_1186 < add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19), ivar20), ivar21), ivar22), ivar23), ivar24), ivar25), ivar26)) { + setWidgetIsHidden(false, new WidgetPointer(933,61)); + if (globalint_1186 == add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19), ivar20), ivar21), ivar22), ivar23), ivar24), ivar25)) { + playSoundEffect(8802, 1, 0); + } + } else if (globalint_1186 < add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19), ivar20), ivar21), ivar22), ivar23), ivar24), ivar25), ivar26), ivar27)) { + setWidgetIsHidden(false, new WidgetPointer(933,76)); + ivar8 = multiplyDivide(add(subtract(globalint_1186, add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19), ivar20), ivar21), ivar22), ivar23), ivar24), ivar25), ivar26)), 1), ivar27, 100); + ivar0 = add(add(add(10000, ivar37), ivar38), ivar39); + ivar1 = add(add(add(add(10000, ivar37), ivar38), ivar39), globalint_1236); + if (((boolean)ivar8)) { + globalint_1270 = ivar0; + } + if (ivar1 >= ivar0) { + setWidgetText(new WidgetPointer(933,76), "+" + intToStr(divide(add(multiplyDivide(ivar8, 100, subtract(ivar1, ivar0)), 50), 100)) + "%"); + if (divide(add(multiplyDivide(ivar8, 100, subtract(ivar1, ivar0)), 50), 100) != globalint_1270) { + playSoundEffect(8806, 1, 0); + globalint_1270 = divide(add(multiplyDivide(ivar8, 100, subtract(ivar1, ivar0)), 50), 100); + } + } else { + setWidgetText(new WidgetPointer(933,76), intToStr(divide(add(multiplyDivide(ivar8, 100, subtract(ivar1, ivar0)), 50), 100)) + "%"); + } + setWidgetText(new WidgetPointer(933,96), intToStr(divide(add(add(ivar0, multiplyDivide(ivar8, 100, subtract(ivar1, ivar0))), 50), 100)) + "%"); + if (divide(add(add(ivar0, multiplyDivide(ivar8, 100, subtract(ivar1, ivar0))), 50), 100) != globalint_1270) { + playSoundEffect(8806, 1, 0); + globalint_1270 = divide(add(add(ivar0, multiplyDivide(ivar8, 100, subtract(ivar1, ivar0))), 50), 100); + } + setWidgetSize(multiplyDivide(8192, 100, divide(add(add(ivar0, multiplyDivide(ivar8, 100, subtract(ivar1, ivar0))), 50), 100)), 16384, 2, 2, new WidgetPointer(933,112)); + } else if (globalint_1186 < add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19), ivar20), ivar21), ivar22), ivar23), ivar24), ivar25), ivar26), ivar27), ivar28)) { + setWidgetIsHidden(false, new WidgetPointer(933,62)); + if (globalint_1186 == add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19), ivar20), ivar21), ivar22), ivar23), ivar24), ivar25), ivar26), ivar27)) { + playSoundEffect(8802, 1, 0); + } + } else if (globalint_1186 < add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19), ivar20), ivar21), ivar22), ivar23), ivar24), ivar25), ivar26), ivar27), ivar28), ivar29)) { + setWidgetIsHidden(false, new WidgetPointer(933,58)); + setWidgetIsHidden(false, new WidgetPointer(933,79)); + setWidgetIsHidden(false, new WidgetPointer(933,81)); + setWidgetIsHidden(false, new WidgetPointer(933,60)); + ivar8 = multiplyDivide(add(subtract(globalint_1186, add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19), ivar20), ivar21), ivar22), ivar23), ivar24), ivar25), ivar26), ivar27), ivar28)), 1), ivar29, 100); + cs2method2103(subtract(255, divide(multiply(ivar8, 255), 100)), new WidgetPointer(933,79)); + cs2method2103(subtract(255, divide(multiply(ivar8, 255), 100)), new WidgetPointer(933,81)); + setWidgetText(new WidgetPointer(933,58), intToStr(multiplyDivide(globalint_1320, 100, ivar8))); + if (multiplyDivide(globalint_1320, 100, ivar8) != globalint_1270) { + playSoundEffect(8806, 1, 0); + globalint_1270 = multiplyDivide(globalint_1320, 100, ivar8); + } + ivar0 = add(add(add(add(10000, ivar37), ivar38), ivar39), globalint_1236); + ivar1 = multiplyDivide(add(add(add(add(10000, ivar37), ivar38), ivar39), globalint_1236), 10000, ivar40); + if (ivar1 >= ivar0) { + setWidgetText(new WidgetPointer(933,60), "+" + intToStr(divide(add(multiplyDivide(ivar8, 100, subtract(ivar1, ivar0)), 50), 100)) + "%"); + } else { + setWidgetText(new WidgetPointer(933,60), intToStr(divide(add(multiplyDivide(ivar8, 100, subtract(ivar1, ivar0)), 50), 100)) + "%"); + } + setWidgetText(new WidgetPointer(933,96), intToStr(divide(add(add(ivar0, multiplyDivide(ivar8, 100, subtract(ivar1, ivar0))), 50), 100)) + "%"); + setWidgetSize(multiplyDivide(8192, 100, divide(add(add(ivar0, multiplyDivide(ivar8, 100, subtract(ivar1, ivar0))), 50), 100)), 16384, 2, 2, new WidgetPointer(933,112)); + } else if (globalint_1186 < add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19), ivar20), ivar21), ivar22), ivar23), ivar24), ivar25), ivar26), ivar27), ivar28), ivar29), ivar30)) { + setWidgetIsHidden(false, new WidgetPointer(933,63)); + if (globalint_1186 == add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19), ivar20), ivar21), ivar22), ivar23), ivar24), ivar25), ivar26), ivar27), ivar28), ivar29)) { + playSoundEffect(8802, 1, 0); + } + } else if (globalint_1186 < add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19), ivar20), ivar21), ivar22), ivar23), ivar24), ivar25), ivar26), ivar27), ivar28), ivar29), ivar30), ivar31)) { + setWidgetIsHidden(false, new WidgetPointer(933,77)); + ivar8 = multiplyDivide(add(subtract(globalint_1186, add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19), ivar20), ivar21), ivar22), ivar23), ivar24), ivar25), ivar26), ivar27), ivar28), ivar29), ivar30)), 1), ivar31, 100); + ivar0 = multiplyDivide(add(add(add(add(10000, ivar37), ivar38), ivar39), globalint_1236), 10000, ivar40); + ivar1 = multiplyDivide(multiplyDivide(add(add(add(add(10000, ivar37), ivar38), ivar39), globalint_1236), 10000, ivar40), 10000, script_3275()); + if (ivar1 >= ivar0) { + setWidgetText(new WidgetPointer(933,77), "+" + intToStr(divide(add(multiplyDivide(ivar8, 100, subtract(ivar1, ivar0)), 50), 100)) + "%"); + } else { + setWidgetText(new WidgetPointer(933,77), intToStr(divide(add(multiplyDivide(ivar8, 100, subtract(ivar1, ivar0)), 50), 100)) + "%"); + } + setWidgetText(new WidgetPointer(933,96), intToStr(divide(add(add(ivar0, multiplyDivide(ivar8, 100, subtract(ivar1, ivar0))), 50), 100)) + "%"); + setWidgetSize(multiplyDivide(8192, 100, divide(add(add(ivar0, multiplyDivide(ivar8, 100, subtract(ivar1, ivar0))), 50), 100)), 16384, 2, 2, new WidgetPointer(933,112)); + } else if (globalint_1186 < add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19), ivar20), ivar21), ivar22), ivar23), ivar24), ivar25), ivar26), ivar27), ivar28), ivar29), ivar30), ivar31), ivar32)) { + setWidgetIsHidden(false, new WidgetPointer(933,65)); + if (globalint_1186 == add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19), ivar20), ivar21), ivar22), ivar23), ivar24), ivar25), ivar26), ivar27), ivar28), ivar29), ivar30), ivar31)) { + playSoundEffect(8802, 1, 0); + } + } else if (globalint_1186 < add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19), ivar20), ivar21), ivar22), ivar23), ivar24), ivar25), ivar26), ivar27), ivar28), ivar29), ivar30), ivar31), ivar32), ivar33)) { + setWidgetIsHidden(false, new WidgetPointer(933,66)); + setWidgetIsHidden(false, new WidgetPointer(933,67)); + ivar8 = multiplyDivide(add(subtract(globalint_1186, add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19), ivar20), ivar21), ivar22), ivar23), ivar24), ivar25), ivar26), ivar27), ivar28), ivar29), ivar30), ivar31), ivar32)), 1), ivar33, 100); + if (bitconfig_7554 != 0) { + stack_dump3 = subtract(globalint_1186, add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19), ivar20), ivar21), ivar22), ivar23), ivar24), ivar25), ivar26), ivar27), ivar28), ivar29), ivar30), ivar31), ivar32)); + structdump_4 = script_3266(stack_dump3); + ivar7 = structdump_4.intpart_1; + ivar6 = structdump_4.intpart_0; + if (((boolean)ivar6)) { + playSoundEffect(9240, 1, 0); + switch (ivar7) { + case 0: + setWidgetIsHidden(false, new WidgetPointer(933,146)); + setWidgetSprite(2849, new WidgetPointer(933,146)); + break; + case 1: + setWidgetIsHidden(false, new WidgetPointer(933,146)); + setWidgetIsHidden(false, new WidgetPointer(933,147)); + setWidgetSprite(2850, new WidgetPointer(933,146)); + setWidgetSprite(2849, new WidgetPointer(933,147)); + break; + case 2: + setWidgetIsHidden(false, new WidgetPointer(933,146)); + setWidgetIsHidden(false, new WidgetPointer(933,147)); + setWidgetIsHidden(false, new WidgetPointer(933,148)); + setWidgetSprite(2850, new WidgetPointer(933,147)); + setWidgetSprite(2849, new WidgetPointer(933,148)); + break; + case 3: + setWidgetIsHidden(false, new WidgetPointer(933,146)); + setWidgetIsHidden(false, new WidgetPointer(933,147)); + setWidgetIsHidden(false, new WidgetPointer(933,148)); + setWidgetIsHidden(false, new WidgetPointer(933,149)); + setWidgetSprite(2850, new WidgetPointer(933,148)); + setWidgetSprite(2849, new WidgetPointer(933,149)); + break; + case 4: + setWidgetIsHidden(false, new WidgetPointer(933,146)); + setWidgetIsHidden(false, new WidgetPointer(933,147)); + setWidgetIsHidden(false, new WidgetPointer(933,148)); + setWidgetIsHidden(false, new WidgetPointer(933,149)); + setWidgetIsHidden(false, new WidgetPointer(933,150)); + setWidgetSprite(2850, new WidgetPointer(933,149)); + setWidgetSprite(2849, new WidgetPointer(933,150)); + break; + case 5: + setWidgetIsHidden(false, new WidgetPointer(933,146)); + setWidgetIsHidden(false, new WidgetPointer(933,147)); + setWidgetIsHidden(false, new WidgetPointer(933,148)); + setWidgetIsHidden(false, new WidgetPointer(933,149)); + setWidgetIsHidden(false, new WidgetPointer(933,150)); + setWidgetIsHidden(false, new WidgetPointer(933,151)); + setWidgetSprite(2850, new WidgetPointer(933,150)); + setWidgetSprite(2849, new WidgetPointer(933,151)); + break; + case 6: + setWidgetIsHidden(false, new WidgetPointer(933,146)); + setWidgetIsHidden(false, new WidgetPointer(933,147)); + setWidgetIsHidden(false, new WidgetPointer(933,148)); + setWidgetIsHidden(false, new WidgetPointer(933,149)); + setWidgetIsHidden(false, new WidgetPointer(933,150)); + setWidgetIsHidden(false, new WidgetPointer(933,151)); + setWidgetIsHidden(false, new WidgetPointer(933,152)); + setWidgetSprite(2850, new WidgetPointer(933,151)); + setWidgetSprite(2849, new WidgetPointer(933,152)); + break; + case 7: + setWidgetIsHidden(false, new WidgetPointer(933,146)); + setWidgetIsHidden(false, new WidgetPointer(933,147)); + setWidgetIsHidden(false, new WidgetPointer(933,148)); + setWidgetIsHidden(false, new WidgetPointer(933,149)); + setWidgetIsHidden(false, new WidgetPointer(933,150)); + setWidgetIsHidden(false, new WidgetPointer(933,151)); + setWidgetIsHidden(false, new WidgetPointer(933,152)); + setWidgetIsHidden(false, new WidgetPointer(933,153)); + setWidgetSprite(2850, new WidgetPointer(933,152)); + setWidgetSprite(2849, new WidgetPointer(933,153)); + break; + case 8: + setWidgetIsHidden(false, new WidgetPointer(933,146)); + setWidgetIsHidden(false, new WidgetPointer(933,147)); + setWidgetIsHidden(false, new WidgetPointer(933,148)); + setWidgetIsHidden(false, new WidgetPointer(933,149)); + setWidgetIsHidden(false, new WidgetPointer(933,150)); + setWidgetIsHidden(false, new WidgetPointer(933,151)); + setWidgetIsHidden(false, new WidgetPointer(933,152)); + setWidgetIsHidden(false, new WidgetPointer(933,153)); + setWidgetIsHidden(false, new WidgetPointer(933,154)); + setWidgetSprite(2850, new WidgetPointer(933,153)); + setWidgetSprite(2849, new WidgetPointer(933,154)); + break; + case 9: + setWidgetIsHidden(false, new WidgetPointer(933,146)); + setWidgetIsHidden(false, new WidgetPointer(933,147)); + setWidgetIsHidden(false, new WidgetPointer(933,148)); + setWidgetIsHidden(false, new WidgetPointer(933,149)); + setWidgetIsHidden(false, new WidgetPointer(933,150)); + setWidgetIsHidden(false, new WidgetPointer(933,151)); + setWidgetIsHidden(false, new WidgetPointer(933,152)); + setWidgetIsHidden(false, new WidgetPointer(933,153)); + setWidgetIsHidden(false, new WidgetPointer(933,154)); + setWidgetIsHidden(false, new WidgetPointer(933,155)); + setWidgetSprite(2850, new WidgetPointer(933,154)); + setWidgetSprite(2849, new WidgetPointer(933,155)); + break; + case 10: + setWidgetIsHidden(false, new WidgetPointer(933,146)); + setWidgetIsHidden(false, new WidgetPointer(933,147)); + setWidgetIsHidden(false, new WidgetPointer(933,148)); + setWidgetIsHidden(false, new WidgetPointer(933,149)); + setWidgetIsHidden(false, new WidgetPointer(933,150)); + setWidgetIsHidden(false, new WidgetPointer(933,151)); + setWidgetIsHidden(false, new WidgetPointer(933,152)); + setWidgetIsHidden(false, new WidgetPointer(933,153)); + setWidgetIsHidden(false, new WidgetPointer(933,154)); + setWidgetIsHidden(false, new WidgetPointer(933,155)); + setWidgetIsHidden(false, new WidgetPointer(933,156)); + setWidgetSprite(2850, new WidgetPointer(933,155)); + setWidgetSprite(2849, new WidgetPointer(933,156)); + break; + case 11: + setWidgetIsHidden(false, new WidgetPointer(933,146)); + setWidgetIsHidden(false, new WidgetPointer(933,147)); + setWidgetIsHidden(false, new WidgetPointer(933,148)); + setWidgetIsHidden(false, new WidgetPointer(933,149)); + setWidgetIsHidden(false, new WidgetPointer(933,150)); + setWidgetIsHidden(false, new WidgetPointer(933,151)); + setWidgetIsHidden(false, new WidgetPointer(933,152)); + setWidgetIsHidden(false, new WidgetPointer(933,153)); + setWidgetIsHidden(false, new WidgetPointer(933,154)); + setWidgetIsHidden(false, new WidgetPointer(933,155)); + setWidgetIsHidden(false, new WidgetPointer(933,156)); + setWidgetIsHidden(false, new WidgetPointer(933,157)); + setWidgetSprite(2850, new WidgetPointer(933,156)); + setWidgetSprite(2849, new WidgetPointer(933,157)); + break; + case 12: + setWidgetIsHidden(false, new WidgetPointer(933,146)); + setWidgetIsHidden(false, new WidgetPointer(933,147)); + setWidgetIsHidden(false, new WidgetPointer(933,148)); + setWidgetIsHidden(false, new WidgetPointer(933,149)); + setWidgetIsHidden(false, new WidgetPointer(933,150)); + setWidgetIsHidden(false, new WidgetPointer(933,151)); + setWidgetIsHidden(false, new WidgetPointer(933,152)); + setWidgetIsHidden(false, new WidgetPointer(933,153)); + setWidgetIsHidden(false, new WidgetPointer(933,154)); + setWidgetIsHidden(false, new WidgetPointer(933,155)); + setWidgetIsHidden(false, new WidgetPointer(933,156)); + setWidgetIsHidden(false, new WidgetPointer(933,157)); + setWidgetIsHidden(false, new WidgetPointer(933,158)); + setWidgetSprite(2850, new WidgetPointer(933,157)); + setWidgetSprite(2849, new WidgetPointer(933,158)); + break; + case 13: + setWidgetIsHidden(false, new WidgetPointer(933,146)); + setWidgetIsHidden(false, new WidgetPointer(933,147)); + setWidgetIsHidden(false, new WidgetPointer(933,148)); + setWidgetIsHidden(false, new WidgetPointer(933,149)); + setWidgetIsHidden(false, new WidgetPointer(933,150)); + setWidgetIsHidden(false, new WidgetPointer(933,151)); + setWidgetIsHidden(false, new WidgetPointer(933,152)); + setWidgetIsHidden(false, new WidgetPointer(933,153)); + setWidgetIsHidden(false, new WidgetPointer(933,154)); + setWidgetIsHidden(false, new WidgetPointer(933,155)); + setWidgetIsHidden(false, new WidgetPointer(933,156)); + setWidgetIsHidden(false, new WidgetPointer(933,157)); + setWidgetIsHidden(false, new WidgetPointer(933,158)); + setWidgetIsHidden(false, new WidgetPointer(933,159)); + setWidgetSprite(2850, new WidgetPointer(933,158)); + setWidgetSprite(2849, new WidgetPointer(933,159)); + break; + case 14: + setWidgetIsHidden(false, new WidgetPointer(933,146)); + setWidgetIsHidden(false, new WidgetPointer(933,147)); + setWidgetIsHidden(false, new WidgetPointer(933,148)); + setWidgetIsHidden(false, new WidgetPointer(933,149)); + setWidgetIsHidden(false, new WidgetPointer(933,150)); + setWidgetIsHidden(false, new WidgetPointer(933,151)); + setWidgetIsHidden(false, new WidgetPointer(933,152)); + setWidgetIsHidden(false, new WidgetPointer(933,153)); + setWidgetIsHidden(false, new WidgetPointer(933,154)); + setWidgetIsHidden(false, new WidgetPointer(933,155)); + setWidgetIsHidden(false, new WidgetPointer(933,156)); + setWidgetIsHidden(false, new WidgetPointer(933,157)); + setWidgetIsHidden(false, new WidgetPointer(933,158)); + setWidgetIsHidden(false, new WidgetPointer(933,159)); + setWidgetIsHidden(false, new WidgetPointer(933,160)); + setWidgetSprite(2850, new WidgetPointer(933,159)); + setWidgetSprite(2849, new WidgetPointer(933,160)); + } + } + } else { + setWidgetText(new WidgetPointer(933,67), "n/a"); + globalint_1186 = add(globalint_1186, 2); + } + ivar0 = multiplyDivide(multiplyDivide(add(add(add(add(10000, ivar37), ivar38), ivar39), globalint_1236), 10000, ivar40), 10000, script_3275()); + ivar1 = multiplyDivide(multiplyDivide(multiplyDivide(add(add(add(add(10000, ivar37), ivar38), ivar39), globalint_1236), 10000, ivar40), 10000, script_3275()), 10000, ivar41); + if (((boolean)ivar8)) { + globalint_1270 = ivar0; + } + if (ivar1 >= ivar0) { + setWidgetText(new WidgetPointer(933,67), "+" + intToStr(divide(add(multiplyDivide(ivar8, 100, subtract(ivar1, ivar0)), 50), 100)) + "%"); + } else { + setWidgetText(new WidgetPointer(933,67), intToStr(divide(add(multiplyDivide(ivar8, 100, subtract(ivar1, ivar0)), 50), 100)) + "%"); + } + setWidgetText(new WidgetPointer(933,96), intToStr(divide(add(add(ivar0, multiplyDivide(ivar8, 100, subtract(ivar1, ivar0))), 50), 100)) + "%"); + if (divide(add(add(ivar0, multiplyDivide(ivar8, 100, subtract(ivar1, ivar0))), 50), 100) != globalint_1270) { + playSoundEffect(8806, 1, 0); + globalint_1270 = divide(add(add(ivar0, multiplyDivide(ivar8, 100, subtract(ivar1, ivar0))), 50), 100); + } + setWidgetSize(multiplyDivide(8192, 100, divide(add(add(ivar0, multiplyDivide(ivar8, 100, subtract(ivar1, ivar0))), 50), 100)), 16384, 2, 2, new WidgetPointer(933,112)); + } else if (globalint_1186 < add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19), ivar20), ivar21), ivar22), ivar23), ivar24), ivar25), ivar26), ivar27), ivar28), ivar29), ivar30), ivar31), ivar32), ivar33), ivar34)) { + setWidgetIsHidden(true, new WidgetPointer(933,53)); + setWidgetIsHidden(false, new WidgetPointer(933,37)); + ivar8 = multiplyDivide(add(subtract(globalint_1186, add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19), ivar20), ivar21), ivar22), ivar23), ivar24), ivar25), ivar26), ivar27), ivar28), ivar29), ivar30), ivar31), ivar32), ivar33)), 1), ivar34, 100); + if (((boolean)ivar8)) { + globalint_1270 = 0; + } + if (globalint_1321 > 0) { + setWidgetIsHidden(false, new WidgetPointer(933,84)); + if (((boolean)ivar8)) { + playSoundEffect(8802, 1, 0); + } + setWidgetText(new WidgetPointer(933,94), "Unbalanced party penalty: x" + intToStr(divide(add(subtract(10000, globalint_1321), 50), 100)) + "%"); + if (divide(add(subtract(10000, globalint_1321), 50), 100) != globalint_1270) { + playSoundEffect(8806, 1, 0); + globalint_1270 = divide(add(subtract(10000, globalint_1321), 50), 100); + } + } else { + globalint_1186 = add(globalint_1186, 2); + } + ivar0 = multiplyDivide(multiplyDivide(multiplyDivide(add(add(add(add(10000, ivar37), ivar38), ivar39), globalint_1236), 10000, ivar40), 10000, script_3275()), 10000, ivar41); + ivar1 = multiplyDivide(multiplyDivide(multiplyDivide(multiplyDivide(add(add(add(add(10000, ivar37), ivar38), ivar39), globalint_1236), 10000, ivar40), 10000, script_3275()), 10000, ivar41), 10000, subtract(10000, globalint_1321)); + setWidgetText(new WidgetPointer(933,96), intToStr(divide(add(add(ivar0, multiplyDivide(ivar8, 100, subtract(ivar1, ivar0))), 50), 100)) + "%"); + setWidgetSize(multiplyDivide(8192, 100, divide(add(add(ivar0, multiplyDivide(ivar8, 100, subtract(ivar1, ivar0))), 50), 100)), 16384, 2, 2, new WidgetPointer(933,112)); + } else if (globalint_1186 < add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19), ivar20), ivar21), ivar22), ivar23), ivar24), ivar25), ivar26), ivar27), ivar28), ivar29), ivar30), ivar31), ivar32), ivar33), ivar34), ivar35)) { + setWidgetIsHidden(true, new WidgetPointer(933,13)); + setWidgetIsHidden(true, new WidgetPointer(933,16)); + setWidgetIsHidden(true, new WidgetPointer(933,14)); + setWidgetIsHidden(true, new WidgetPointer(933,15)); + setWidgetText(new WidgetPointer(933,39), intToStr(globalint_1239)); + ivar8 = multiplyDivide(add(subtract(globalint_1186, add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19), ivar20), ivar21), ivar22), ivar23), ivar24), ivar25), ivar26), ivar27), ivar28), ivar29), ivar30), ivar31), ivar32), ivar33), ivar34)), 1), ivar35, 100); + ivar0 = globalint_1239; + ivar1 = multiplyDivide(multiplyDivide(multiplyDivide(multiplyDivide(multiplyDivide(add(add(add(add(10000, ivar37), ivar38), ivar39), globalint_1236), 10000, ivar40), 10000, script_3275()), 10000, ivar41), 10000, subtract(10000, globalint_1321)), 10000, globalint_1239); + if (((boolean)ivar8)) { + globalint_1270 = ivar0; + } + if (((boolean)mod(ivar8, 5)) && (getWidgetActualY(new WidgetPointer(933,84)) != 138)) { + setWidgetPosition(getWidgetActualX(new WidgetPointer(933,84)), add(getWidgetActualY(new WidgetPointer(933,84)), 1), 0, 0, new WidgetPointer(933,84)); + } + setWidgetSize(183, multiplyDivide(80, 100, ivar8), 0, 0, new WidgetPointer(933,111)); + setWidgetText(new WidgetPointer(933,39), intToStr(divide(add(add(ivar0, multiplyDivide(ivar8, 100, subtract(ivar1, ivar0))), 5), 10)) + "%"); + if (divide(add(add(ivar0, multiplyDivide(ivar8, 100, subtract(ivar1, ivar0))), 5), 10) != globalint_1270) { + playSoundEffect(9243, 1, 0); + globalint_1270 = divide(add(add(ivar0, multiplyDivide(ivar8, 100, subtract(ivar1, ivar0))), 5), 10); + } + } else { + if (globalint_1186 < add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19), ivar20), ivar21), ivar22), ivar23), ivar24), ivar25), ivar26), ivar27), ivar28), ivar29), ivar30), ivar31), ivar32), ivar33), ivar34), ivar35), ivar36)) { + ivar8 = multiplyDivide(add(subtract(globalint_1186, add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19), ivar20), ivar21), ivar22), ivar23), ivar24), ivar25), ivar26), ivar27), ivar28), ivar29), ivar30), ivar31), ivar32), ivar33), ivar34), ivar35)), 1), ivar36, 100); + ivar0 = globalint_1239; + ivar1 = multiplyDivide(multiplyDivide(multiplyDivide(multiplyDivide(multiplyDivide(add(add(add(add(10000, ivar37), ivar38), ivar39), globalint_1236), 10000, ivar40), 10000, script_3275()), 10000, ivar41), 10000, subtract(10000, globalint_1321)), 10000, globalint_1239); + if (((boolean)ivar8)) { + globalint_1270 = ivar0; + } + if (standart_config_1780 < 2000000000) { + setWidgetText(new WidgetPointer(933,41), intToStr(divide(add(add(ivar0, multiplyDivide(ivar8, 100, subtract(ivar1, ivar0))), 5), 100)) + "%"); + if (divide(add(add(ivar0, multiplyDivide(ivar8, 100, subtract(ivar1, ivar0))), 5), 100) != globalint_1270) { + playSoundEffect(8800, 1, 0); + globalint_1270 = divide(add(add(ivar0, multiplyDivide(ivar8, 100, subtract(ivar1, ivar0))), 5), 100); + } + } else { + setWidgetText(new WidgetPointer(933,41), "n/a"); + } + } + } + globalint_1186 = min(add(script_3265(), add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(ivar9, ivar10), ivar11), ivar12), ivar13), ivar14), ivar15), ivar16), ivar17), ivar18), ivar19), ivar20), ivar21), ivar22), ivar23), ivar24), ivar25), ivar26), ivar27), ivar28), ivar29), ivar30), ivar31), ivar32), ivar33), ivar34), ivar35), ivar36)), add(globalint_1186, 1)); + } + script_3268(); + return; +} diff --git a/dumps/scripts/3268.cs2 b/dumps/scripts/3268.cs2 new file mode 100644 index 0000000..eb7ea7b --- /dev/null +++ b/dumps/scripts/3268.cs2 @@ -0,0 +1,342 @@ +void script_3268() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int stack_dump0; + int stack_dump1; + int stack_dump2; + int stack_dump3; + cs2func_script_3269_struct(4,0,0) structdump_4; + ivar0 = 1; + ivar1 = 18; + ivar2 = 255; + ivar3 = add(add(add(add(globalint_1198, globalint_1199), globalint_1200), globalint_1201), globalint_1202); + ivar4 = subtract(ivar2, multiply(ivar3, ivar1)); + ivar4 = min(ivar4, 105); + ivar5 = 4; + ivar6 = 0; + ivar7 = 0; + ivar8 = 0; + ivar9 = 0; + stack_dump0 = globalint_1184; + stack_dump1 = ivar5; + stack_dump2 = ivar1; + stack_dump3 = ivar4; + structdump_4 = script_3269(stack_dump0, stack_dump1, stack_dump2, stack_dump3); + ivar9 = structdump_4.intpart_3; + ivar8 = structdump_4.intpart_2; + ivar7 = structdump_4.intpart_1; + ivar6 = structdump_4.intpart_0; + switch (globalint_1184) { + case 0: + setWidgetPosition(ivar0, script_3270(getWidgetActualY(new WidgetPointer(933,265)), ivar5), 0, 0, new WidgetPointer(933,265)); + if (((boolean)globalint_1198)) { + setWidgetIsHidden(false, new WidgetPointer(933,265)); + setWidgetContextMenuOption(1, new WidgetPointer(933,265), "Expand"); + setWidgetSprite(2851, new WidgetPointer(933,317)); + } else { + setWidgetIsHidden(true, new WidgetPointer(933,265)); + setWidgetContextMenuOption(1, new WidgetPointer(933,265), ""); + } + setWidgetPosition(ivar0, script_3270(getWidgetActualY(new WidgetPointer(933,266)), ivar6), 0, 0, new WidgetPointer(933,266)); + if (((boolean)globalint_1199)) { + setWidgetIsHidden(false, new WidgetPointer(933,266)); + setWidgetContextMenuOption(1, new WidgetPointer(933,266), "Expand"); + setWidgetSprite(2851, new WidgetPointer(933,275)); + } else { + setWidgetIsHidden(true, new WidgetPointer(933,266)); + setWidgetIsHidden(true, new WidgetPointer(933,316)); + setWidgetContextMenuOption(1, new WidgetPointer(933,266), ""); + } + setWidgetPosition(ivar0, script_3270(getWidgetActualY(new WidgetPointer(933,276)), ivar7), 0, 0, new WidgetPointer(933,276)); + if (((boolean)globalint_1200)) { + setWidgetIsHidden(false, new WidgetPointer(933,276)); + setWidgetContextMenuOption(1, new WidgetPointer(933,276), "Expand"); + setWidgetSprite(2851, new WidgetPointer(933,285)); + } else { + setWidgetIsHidden(true, new WidgetPointer(933,276)); + setWidgetIsHidden(true, new WidgetPointer(933,274)); + setWidgetContextMenuOption(1, new WidgetPointer(933,276), ""); + } + setWidgetPosition(ivar0, script_3270(getWidgetActualY(new WidgetPointer(933,286)), ivar8), 0, 0, new WidgetPointer(933,286)); + if (((boolean)globalint_1201)) { + setWidgetIsHidden(false, new WidgetPointer(933,286)); + setWidgetContextMenuOption(1, new WidgetPointer(933,286), "Expand"); + setWidgetSprite(2851, new WidgetPointer(933,295)); + } else { + setWidgetIsHidden(true, new WidgetPointer(933,286)); + setWidgetIsHidden(true, new WidgetPointer(933,284)); + setWidgetContextMenuOption(1, new WidgetPointer(933,286), ""); + } + setWidgetPosition(ivar0, script_3270(getWidgetActualY(new WidgetPointer(933,296)), ivar9), 0, 0, new WidgetPointer(933,296)); + if (((boolean)globalint_1202)) { + setWidgetIsHidden(false, new WidgetPointer(933,296)); + setWidgetContextMenuOption(1, new WidgetPointer(933,296), "Expand"); + setWidgetSprite(2851, new WidgetPointer(933,308)); + } else { + setWidgetIsHidden(true, new WidgetPointer(933,296)); + setWidgetIsHidden(true, new WidgetPointer(933,294)); + setWidgetContextMenuOption(1, new WidgetPointer(933,296), ""); + } + setWidgetSize(16384, script_3270(getWidgetActualHeight(new WidgetPointer(933,265)), subtract(subtract(getWidgetActualY(new WidgetPointer(933,266)), getWidgetActualY(new WidgetPointer(933,265))), 5)), 2, 0, new WidgetPointer(933,265)); + setWidgetSize(16384, script_3270(getWidgetActualHeight(new WidgetPointer(933,266)), subtract(subtract(getWidgetActualY(new WidgetPointer(933,276)), getWidgetActualY(new WidgetPointer(933,266))), 5)), 2, 0, new WidgetPointer(933,266)); + setWidgetSize(16384, script_3270(getWidgetActualHeight(new WidgetPointer(933,276)), subtract(subtract(getWidgetActualY(new WidgetPointer(933,286)), getWidgetActualY(new WidgetPointer(933,276))), 5)), 2, 0, new WidgetPointer(933,276)); + setWidgetSize(16384, script_3270(getWidgetActualHeight(new WidgetPointer(933,286)), subtract(subtract(getWidgetActualY(new WidgetPointer(933,296)), getWidgetActualY(new WidgetPointer(933,286))), 5)), 2, 0, new WidgetPointer(933,286)); + setWidgetSize(16384, script_3270(getWidgetActualHeight(new WidgetPointer(933,296)), subtract(subtract(ivar2, getWidgetActualY(new WidgetPointer(933,296))), 5)), 2, 0, new WidgetPointer(933,296)); + break; + case 1: + setWidgetPosition(ivar0, script_3270(getWidgetActualY(new WidgetPointer(933,265)), ivar5), 0, 0, new WidgetPointer(933,265)); + setWidgetContextMenuOption(1, new WidgetPointer(933,265), "Shrink"); + setWidgetSprite(2852, new WidgetPointer(933,317)); + setWidgetPosition(ivar0, script_3270(getWidgetActualY(new WidgetPointer(933,266)), ivar6), 0, 0, new WidgetPointer(933,266)); + if (((boolean)globalint_1199)) { + setWidgetIsHidden(false, new WidgetPointer(933,266)); + setWidgetContextMenuOption(1, new WidgetPointer(933,266), "Expand"); + setWidgetSprite(2851, new WidgetPointer(933,275)); + } else { + setWidgetIsHidden(true, new WidgetPointer(933,266)); + setWidgetIsHidden(true, new WidgetPointer(933,316)); + setWidgetContextMenuOption(1, new WidgetPointer(933,266), ""); + } + setWidgetPosition(ivar0, script_3270(getWidgetActualY(new WidgetPointer(933,276)), ivar7), 0, 0, new WidgetPointer(933,276)); + if (((boolean)globalint_1200)) { + setWidgetIsHidden(false, new WidgetPointer(933,276)); + setWidgetContextMenuOption(1, new WidgetPointer(933,276), "Expand"); + setWidgetSprite(2851, new WidgetPointer(933,285)); + } else { + setWidgetIsHidden(true, new WidgetPointer(933,276)); + setWidgetIsHidden(true, new WidgetPointer(933,274)); + setWidgetContextMenuOption(1, new WidgetPointer(933,276), ""); + } + setWidgetPosition(ivar0, script_3270(getWidgetActualY(new WidgetPointer(933,286)), ivar8), 0, 0, new WidgetPointer(933,286)); + if (((boolean)globalint_1201)) { + setWidgetIsHidden(false, new WidgetPointer(933,286)); + setWidgetContextMenuOption(1, new WidgetPointer(933,286), "Expand"); + setWidgetSprite(2851, new WidgetPointer(933,295)); + } else { + setWidgetIsHidden(true, new WidgetPointer(933,286)); + setWidgetIsHidden(true, new WidgetPointer(933,284)); + setWidgetContextMenuOption(1, new WidgetPointer(933,286), ""); + } + setWidgetPosition(ivar0, script_3270(getWidgetActualY(new WidgetPointer(933,296)), ivar9), 0, 0, new WidgetPointer(933,296)); + if (((boolean)globalint_1202)) { + setWidgetIsHidden(false, new WidgetPointer(933,296)); + setWidgetContextMenuOption(1, new WidgetPointer(933,296), "Expand"); + setWidgetSprite(2851, new WidgetPointer(933,308)); + } else { + setWidgetIsHidden(true, new WidgetPointer(933,296)); + setWidgetIsHidden(true, new WidgetPointer(933,294)); + setWidgetContextMenuOption(1, new WidgetPointer(933,296), ""); + } + setWidgetSize(16384, script_3270(getWidgetActualHeight(new WidgetPointer(933,265)), subtract(subtract(getWidgetActualY(new WidgetPointer(933,266)), getWidgetActualY(new WidgetPointer(933,265))), 2)), 2, 0, new WidgetPointer(933,265)); + setWidgetSize(16384, script_3270(getWidgetActualHeight(new WidgetPointer(933,266)), subtract(subtract(getWidgetActualY(new WidgetPointer(933,276)), getWidgetActualY(new WidgetPointer(933,266))), 2)), 2, 0, new WidgetPointer(933,266)); + setWidgetSize(16384, script_3270(getWidgetActualHeight(new WidgetPointer(933,276)), subtract(subtract(getWidgetActualY(new WidgetPointer(933,286)), getWidgetActualY(new WidgetPointer(933,276))), 2)), 2, 0, new WidgetPointer(933,276)); + setWidgetSize(16384, script_3270(getWidgetActualHeight(new WidgetPointer(933,286)), subtract(subtract(getWidgetActualY(new WidgetPointer(933,296)), getWidgetActualY(new WidgetPointer(933,286))), 2)), 2, 0, new WidgetPointer(933,286)); + setWidgetSize(16384, script_3270(getWidgetActualHeight(new WidgetPointer(933,296)), subtract(subtract(ivar2, getWidgetActualY(new WidgetPointer(933,296))), 2)), 2, 0, new WidgetPointer(933,296)); + break; + case 2: + setWidgetPosition(ivar0, script_3270(getWidgetActualY(new WidgetPointer(933,265)), ivar5), 0, 0, new WidgetPointer(933,265)); + if (((boolean)globalint_1198)) { + setWidgetIsHidden(false, new WidgetPointer(933,265)); + setWidgetContextMenuOption(1, new WidgetPointer(933,265), "Expand"); + setWidgetSprite(2851, new WidgetPointer(933,317)); + } else { + setWidgetIsHidden(true, new WidgetPointer(933,265)); + setWidgetContextMenuOption(1, new WidgetPointer(933,265), ""); + } + setWidgetPosition(ivar0, script_3270(getWidgetActualY(new WidgetPointer(933,266)), ivar6), 0, 0, new WidgetPointer(933,266)); + setWidgetContextMenuOption(1, new WidgetPointer(933,266), "Shrink"); + setWidgetSprite(2852, new WidgetPointer(933,275)); + setWidgetPosition(ivar0, script_3270(getWidgetActualY(new WidgetPointer(933,276)), ivar7), 0, 0, new WidgetPointer(933,276)); + if (((boolean)globalint_1200)) { + setWidgetIsHidden(false, new WidgetPointer(933,276)); + setWidgetContextMenuOption(1, new WidgetPointer(933,276), "Expand"); + setWidgetSprite(2851, new WidgetPointer(933,285)); + } else { + setWidgetIsHidden(true, new WidgetPointer(933,276)); + setWidgetIsHidden(true, new WidgetPointer(933,274)); + setWidgetContextMenuOption(1, new WidgetPointer(933,276), ""); + } + setWidgetPosition(ivar0, script_3270(getWidgetActualY(new WidgetPointer(933,286)), ivar8), 0, 0, new WidgetPointer(933,286)); + if (((boolean)globalint_1201)) { + setWidgetIsHidden(false, new WidgetPointer(933,286)); + setWidgetContextMenuOption(1, new WidgetPointer(933,286), "Expand"); + setWidgetSprite(2851, new WidgetPointer(933,295)); + } else { + setWidgetIsHidden(true, new WidgetPointer(933,286)); + setWidgetIsHidden(true, new WidgetPointer(933,284)); + setWidgetContextMenuOption(1, new WidgetPointer(933,286), ""); + } + setWidgetPosition(ivar0, script_3270(getWidgetActualY(new WidgetPointer(933,296)), ivar9), 0, 0, new WidgetPointer(933,296)); + if (((boolean)globalint_1202)) { + setWidgetIsHidden(false, new WidgetPointer(933,296)); + setWidgetContextMenuOption(1, new WidgetPointer(933,296), "Expand"); + setWidgetSprite(2851, new WidgetPointer(933,308)); + } else { + setWidgetIsHidden(true, new WidgetPointer(933,296)); + setWidgetIsHidden(true, new WidgetPointer(933,294)); + setWidgetContextMenuOption(1, new WidgetPointer(933,296), ""); + } + setWidgetSize(16384, script_3270(getWidgetActualHeight(new WidgetPointer(933,265)), subtract(subtract(getWidgetActualY(new WidgetPointer(933,266)), getWidgetActualY(new WidgetPointer(933,265))), 2)), 2, 0, new WidgetPointer(933,265)); + setWidgetSize(16384, script_3270(getWidgetActualHeight(new WidgetPointer(933,266)), subtract(subtract(getWidgetActualY(new WidgetPointer(933,276)), getWidgetActualY(new WidgetPointer(933,266))), 2)), 2, 0, new WidgetPointer(933,266)); + setWidgetSize(16384, script_3270(getWidgetActualHeight(new WidgetPointer(933,276)), subtract(subtract(getWidgetActualY(new WidgetPointer(933,286)), getWidgetActualY(new WidgetPointer(933,276))), 2)), 2, 0, new WidgetPointer(933,276)); + setWidgetSize(16384, script_3270(getWidgetActualHeight(new WidgetPointer(933,286)), subtract(subtract(getWidgetActualY(new WidgetPointer(933,296)), getWidgetActualY(new WidgetPointer(933,286))), 2)), 2, 0, new WidgetPointer(933,286)); + setWidgetSize(16384, script_3270(getWidgetActualHeight(new WidgetPointer(933,296)), subtract(subtract(ivar2, getWidgetActualY(new WidgetPointer(933,296))), 2)), 2, 0, new WidgetPointer(933,296)); + break; + case 3: + setWidgetPosition(ivar0, script_3270(getWidgetActualY(new WidgetPointer(933,265)), ivar5), 0, 0, new WidgetPointer(933,265)); + if (((boolean)globalint_1198)) { + setWidgetIsHidden(false, new WidgetPointer(933,265)); + setWidgetContextMenuOption(1, new WidgetPointer(933,265), "Expand"); + setWidgetSprite(2851, new WidgetPointer(933,317)); + } else { + setWidgetIsHidden(true, new WidgetPointer(933,265)); + setWidgetContextMenuOption(1, new WidgetPointer(933,265), ""); + } + setWidgetPosition(ivar0, script_3270(getWidgetActualY(new WidgetPointer(933,266)), ivar6), 0, 0, new WidgetPointer(933,266)); + if (((boolean)globalint_1199)) { + setWidgetIsHidden(false, new WidgetPointer(933,266)); + setWidgetContextMenuOption(1, new WidgetPointer(933,266), "Expand"); + setWidgetSprite(2851, new WidgetPointer(933,275)); + } else { + setWidgetIsHidden(true, new WidgetPointer(933,266)); + setWidgetIsHidden(true, new WidgetPointer(933,316)); + setWidgetContextMenuOption(1, new WidgetPointer(933,266), ""); + } + setWidgetPosition(ivar0, script_3270(getWidgetActualY(new WidgetPointer(933,276)), ivar7), 0, 0, new WidgetPointer(933,276)); + setWidgetContextMenuOption(1, new WidgetPointer(933,276), "Shrink"); + setWidgetSprite(2852, new WidgetPointer(933,285)); + setWidgetPosition(ivar0, script_3270(getWidgetActualY(new WidgetPointer(933,286)), ivar8), 0, 0, new WidgetPointer(933,286)); + if (((boolean)globalint_1201)) { + setWidgetIsHidden(false, new WidgetPointer(933,286)); + setWidgetContextMenuOption(1, new WidgetPointer(933,286), "Expand"); + setWidgetSprite(2851, new WidgetPointer(933,295)); + } else { + setWidgetIsHidden(true, new WidgetPointer(933,286)); + setWidgetIsHidden(true, new WidgetPointer(933,284)); + setWidgetContextMenuOption(1, new WidgetPointer(933,286), ""); + } + setWidgetPosition(ivar0, script_3270(getWidgetActualY(new WidgetPointer(933,296)), ivar9), 0, 0, new WidgetPointer(933,296)); + if (((boolean)globalint_1202)) { + setWidgetIsHidden(false, new WidgetPointer(933,296)); + setWidgetContextMenuOption(1, new WidgetPointer(933,296), "Expand"); + setWidgetSprite(2851, new WidgetPointer(933,308)); + } else { + setWidgetIsHidden(true, new WidgetPointer(933,296)); + setWidgetIsHidden(true, new WidgetPointer(933,294)); + setWidgetContextMenuOption(1, new WidgetPointer(933,296), ""); + } + setWidgetSize(16384, script_3270(getWidgetActualHeight(new WidgetPointer(933,265)), subtract(subtract(getWidgetActualY(new WidgetPointer(933,266)), getWidgetActualY(new WidgetPointer(933,265))), 2)), 2, 0, new WidgetPointer(933,265)); + setWidgetSize(16384, script_3270(getWidgetActualHeight(new WidgetPointer(933,266)), subtract(subtract(getWidgetActualY(new WidgetPointer(933,276)), getWidgetActualY(new WidgetPointer(933,266))), 2)), 2, 0, new WidgetPointer(933,266)); + setWidgetSize(16384, script_3270(getWidgetActualHeight(new WidgetPointer(933,276)), subtract(subtract(getWidgetActualY(new WidgetPointer(933,286)), getWidgetActualY(new WidgetPointer(933,276))), 2)), 2, 0, new WidgetPointer(933,276)); + setWidgetSize(16384, script_3270(getWidgetActualHeight(new WidgetPointer(933,286)), subtract(subtract(getWidgetActualY(new WidgetPointer(933,296)), getWidgetActualY(new WidgetPointer(933,286))), 2)), 2, 0, new WidgetPointer(933,286)); + setWidgetSize(16384, script_3270(getWidgetActualHeight(new WidgetPointer(933,296)), subtract(subtract(ivar2, getWidgetActualY(new WidgetPointer(933,296))), 2)), 2, 0, new WidgetPointer(933,296)); + break; + case 4: + setWidgetPosition(ivar0, script_3270(getWidgetActualY(new WidgetPointer(933,265)), ivar5), 0, 0, new WidgetPointer(933,265)); + if (((boolean)globalint_1198)) { + setWidgetIsHidden(false, new WidgetPointer(933,265)); + setWidgetContextMenuOption(1, new WidgetPointer(933,265), "Expand"); + setWidgetSprite(2851, new WidgetPointer(933,317)); + } else { + setWidgetIsHidden(true, new WidgetPointer(933,265)); + setWidgetContextMenuOption(1, new WidgetPointer(933,265), ""); + } + setWidgetPosition(ivar0, script_3270(getWidgetActualY(new WidgetPointer(933,266)), ivar6), 0, 0, new WidgetPointer(933,266)); + if (((boolean)globalint_1199)) { + setWidgetIsHidden(false, new WidgetPointer(933,266)); + setWidgetContextMenuOption(1, new WidgetPointer(933,266), "Expand"); + setWidgetSprite(2851, new WidgetPointer(933,275)); + } else { + setWidgetIsHidden(true, new WidgetPointer(933,266)); + setWidgetIsHidden(true, new WidgetPointer(933,316)); + setWidgetContextMenuOption(1, new WidgetPointer(933,266), ""); + } + setWidgetPosition(ivar0, script_3270(getWidgetActualY(new WidgetPointer(933,276)), ivar7), 0, 0, new WidgetPointer(933,276)); + if (((boolean)globalint_1200)) { + setWidgetIsHidden(false, new WidgetPointer(933,276)); + setWidgetContextMenuOption(1, new WidgetPointer(933,276), "Expand"); + setWidgetSprite(2851, new WidgetPointer(933,285)); + } else { + setWidgetIsHidden(true, new WidgetPointer(933,276)); + setWidgetIsHidden(true, new WidgetPointer(933,274)); + setWidgetContextMenuOption(1, new WidgetPointer(933,276), ""); + } + setWidgetPosition(ivar0, script_3270(getWidgetActualY(new WidgetPointer(933,286)), ivar8), 0, 0, new WidgetPointer(933,286)); + setWidgetContextMenuOption(1, new WidgetPointer(933,286), "Shrink"); + setWidgetSprite(2852, new WidgetPointer(933,295)); + setWidgetPosition(ivar0, script_3270(getWidgetActualY(new WidgetPointer(933,296)), ivar9), 0, 0, new WidgetPointer(933,296)); + if (((boolean)globalint_1202)) { + setWidgetIsHidden(false, new WidgetPointer(933,296)); + setWidgetContextMenuOption(1, new WidgetPointer(933,296), "Expand"); + setWidgetSprite(2851, new WidgetPointer(933,308)); + } else { + setWidgetIsHidden(true, new WidgetPointer(933,296)); + setWidgetIsHidden(true, new WidgetPointer(933,294)); + setWidgetContextMenuOption(1, new WidgetPointer(933,296), ""); + } + setWidgetSize(16384, script_3270(getWidgetActualHeight(new WidgetPointer(933,265)), subtract(subtract(getWidgetActualY(new WidgetPointer(933,266)), getWidgetActualY(new WidgetPointer(933,265))), 2)), 2, 0, new WidgetPointer(933,265)); + setWidgetSize(16384, script_3270(getWidgetActualHeight(new WidgetPointer(933,266)), subtract(subtract(getWidgetActualY(new WidgetPointer(933,276)), getWidgetActualY(new WidgetPointer(933,266))), 2)), 2, 0, new WidgetPointer(933,266)); + setWidgetSize(16384, script_3270(getWidgetActualHeight(new WidgetPointer(933,276)), subtract(subtract(getWidgetActualY(new WidgetPointer(933,286)), getWidgetActualY(new WidgetPointer(933,276))), 2)), 2, 0, new WidgetPointer(933,276)); + setWidgetSize(16384, script_3270(getWidgetActualHeight(new WidgetPointer(933,286)), subtract(subtract(getWidgetActualY(new WidgetPointer(933,296)), getWidgetActualY(new WidgetPointer(933,286))), 2)), 2, 0, new WidgetPointer(933,286)); + setWidgetSize(16384, script_3270(getWidgetActualHeight(new WidgetPointer(933,296)), subtract(subtract(ivar2, getWidgetActualY(new WidgetPointer(933,296))), 2)), 2, 0, new WidgetPointer(933,296)); + break; + case 5: + setWidgetPosition(ivar0, script_3270(getWidgetActualY(new WidgetPointer(933,265)), ivar5), 0, 0, new WidgetPointer(933,265)); + if (((boolean)globalint_1198)) { + setWidgetIsHidden(false, new WidgetPointer(933,265)); + setWidgetContextMenuOption(1, new WidgetPointer(933,265), "Expand"); + setWidgetSprite(2851, new WidgetPointer(933,317)); + } else { + setWidgetIsHidden(true, new WidgetPointer(933,265)); + setWidgetContextMenuOption(1, new WidgetPointer(933,265), ""); + } + setWidgetPosition(ivar0, script_3270(getWidgetActualY(new WidgetPointer(933,266)), ivar6), 0, 0, new WidgetPointer(933,266)); + if (((boolean)globalint_1199)) { + setWidgetIsHidden(false, new WidgetPointer(933,266)); + setWidgetContextMenuOption(1, new WidgetPointer(933,266), "Expand"); + setWidgetSprite(2851, new WidgetPointer(933,275)); + } else { + setWidgetIsHidden(true, new WidgetPointer(933,266)); + setWidgetIsHidden(true, new WidgetPointer(933,316)); + setWidgetContextMenuOption(1, new WidgetPointer(933,266), ""); + } + setWidgetPosition(ivar0, script_3270(getWidgetActualY(new WidgetPointer(933,276)), ivar7), 0, 0, new WidgetPointer(933,276)); + if (((boolean)globalint_1200)) { + setWidgetIsHidden(false, new WidgetPointer(933,276)); + setWidgetContextMenuOption(1, new WidgetPointer(933,276), "Expand"); + setWidgetSprite(2851, new WidgetPointer(933,285)); + } else { + setWidgetIsHidden(true, new WidgetPointer(933,276)); + setWidgetIsHidden(true, new WidgetPointer(933,274)); + setWidgetContextMenuOption(1, new WidgetPointer(933,276), ""); + } + setWidgetPosition(ivar0, script_3270(getWidgetActualY(new WidgetPointer(933,286)), ivar8), 0, 0, new WidgetPointer(933,286)); + if (((boolean)globalint_1201)) { + setWidgetIsHidden(false, new WidgetPointer(933,286)); + setWidgetContextMenuOption(1, new WidgetPointer(933,286), "Expand"); + setWidgetSprite(2851, new WidgetPointer(933,295)); + } else { + setWidgetIsHidden(true, new WidgetPointer(933,286)); + setWidgetIsHidden(true, new WidgetPointer(933,284)); + setWidgetContextMenuOption(1, new WidgetPointer(933,286), ""); + } + setWidgetPosition(ivar0, script_3270(getWidgetActualY(new WidgetPointer(933,296)), ivar9), 0, 0, new WidgetPointer(933,296)); + setWidgetContextMenuOption(1, new WidgetPointer(933,296), "Shrink"); + setWidgetSprite(2852, new WidgetPointer(933,308)); + setWidgetSize(16384, script_3270(getWidgetActualHeight(new WidgetPointer(933,265)), subtract(subtract(getWidgetActualY(new WidgetPointer(933,266)), getWidgetActualY(new WidgetPointer(933,265))), 2)), 2, 0, new WidgetPointer(933,265)); + setWidgetSize(16384, script_3270(getWidgetActualHeight(new WidgetPointer(933,266)), subtract(subtract(getWidgetActualY(new WidgetPointer(933,276)), getWidgetActualY(new WidgetPointer(933,266))), 2)), 2, 0, new WidgetPointer(933,266)); + setWidgetSize(16384, script_3270(getWidgetActualHeight(new WidgetPointer(933,276)), subtract(subtract(getWidgetActualY(new WidgetPointer(933,286)), getWidgetActualY(new WidgetPointer(933,276))), 2)), 2, 0, new WidgetPointer(933,276)); + setWidgetSize(16384, script_3270(getWidgetActualHeight(new WidgetPointer(933,286)), subtract(subtract(getWidgetActualY(new WidgetPointer(933,296)), getWidgetActualY(new WidgetPointer(933,286))), 2)), 2, 0, new WidgetPointer(933,286)); + setWidgetSize(16384, script_3270(getWidgetActualHeight(new WidgetPointer(933,296)), subtract(subtract(ivar2, getWidgetActualY(new WidgetPointer(933,296))), 2)), 2, 0, new WidgetPointer(933,296)); + } + script_3271(); + return; +} diff --git a/dumps/scripts/3269.cs2 b/dumps/scripts/3269.cs2 new file mode 100644 index 0000000..dacc1ff --- /dev/null +++ b/dumps/scripts/3269.cs2 @@ -0,0 +1,47 @@ +cs2func_script_3269_struct(4,0,0) script_3269(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + int ivar6; + int ivar7; + if (((boolean)arg0)) { + arg2 = 48; + arg3 = 48; + } + ivar4 = arg1; + if (((boolean)globalint_1198)) { + ivar4 = add(ivar4, 2); + if (((boolean)arg0)) { + ivar4 = add(ivar4, arg3); + } else { + ivar4 = add(ivar4, arg2); + } + } + ivar5 = ivar4; + if (((boolean)globalint_1199)) { + ivar5 = add(ivar5, 2); + if (arg0 == 2) { + ivar5 = add(ivar5, arg3); + } else { + ivar5 = add(ivar5, arg2); + } + } + ivar6 = ivar5; + if (((boolean)globalint_1200)) { + ivar6 = add(ivar6, 2); + if (arg0 == 3) { + ivar6 = add(ivar6, arg3); + } else { + ivar6 = add(ivar6, arg2); + } + } + ivar7 = ivar6; + if (((boolean)globalint_1201)) { + ivar7 = add(ivar7, 2); + if (arg0 == 4) { + ivar7 = add(ivar7, arg3); + } else { + ivar7 = add(ivar7, arg2); + } + } + return newstruct cs2func_script_3269_struct(ivar4, ivar5, ivar6, ivar7); +} diff --git a/dumps/scripts/327.cs2 b/dumps/scripts/327.cs2 new file mode 100644 index 0000000..bfc5a61 --- /dev/null +++ b/dumps/scripts/327.cs2 @@ -0,0 +1,6 @@ +void script_327(int arg0) { + globalint_783 = 0; + setWidgetModel(-1, new WidgetPointer(725,83)); + script_328(arg0); + return; +} diff --git a/dumps/scripts/3270.cs2 b/dumps/scripts/3270.cs2 new file mode 100644 index 0000000..79fb3b3 --- /dev/null +++ b/dumps/scripts/3270.cs2 @@ -0,0 +1,11 @@ +int script_3270(int arg0,int arg1) { + int ivar2; + ivar2 = 2; + if (add(arg0, subtract(ivar2, 1)) < arg1) { + return add(arg0, ivar2); + } + if (subtract(arg0, subtract(ivar2, 1)) > arg1) { + return subtract(arg0, ivar2); + } + return arg1; +} diff --git a/dumps/scripts/3271.cs2 b/dumps/scripts/3271.cs2 new file mode 100644 index 0000000..c264dc9 --- /dev/null +++ b/dumps/scripts/3271.cs2 @@ -0,0 +1,16 @@ +void script_3271() { + if (((boolean)globalint_1202)) { + setWidgetSize(16384, subtract(getWidgetActualHeight(new WidgetPointer(933,296)), 1), 2, 0, new WidgetPointer(933,296)); + } else if (((boolean)globalint_1201)) { + setWidgetSize(16384, subtract(getWidgetActualHeight(new WidgetPointer(933,286)), 1), 2, 0, new WidgetPointer(933,286)); + } else if (((boolean)globalint_1200)) { + setWidgetSize(16384, subtract(getWidgetActualHeight(new WidgetPointer(933,276)), 1), 2, 0, new WidgetPointer(933,276)); + } else if (((boolean)globalint_1199)) { + setWidgetSize(16384, subtract(getWidgetActualHeight(new WidgetPointer(933,266)), 1), 2, 0, new WidgetPointer(933,266)); + } else { + if (((boolean)globalint_1198)) { + setWidgetSize(16384, subtract(getWidgetActualHeight(new WidgetPointer(933,265)), 1), 2, 0, new WidgetPointer(933,265)); + } + } + return; +} diff --git a/dumps/scripts/3272.cs2 b/dumps/scripts/3272.cs2 new file mode 100644 index 0000000..146ddb8 --- /dev/null +++ b/dumps/scripts/3272.cs2 @@ -0,0 +1,39 @@ +void script_3272(int arg0) { + switch (arg0) { + case 61145353: + if ((globalint_1184 != 1) && ((boolean)globalint_1198)) { + globalint_1184 = 1; + } else { + globalint_1184 = 0; + } + break; + case 61145354: + if ((globalint_1184 != 2) && ((boolean)globalint_1199)) { + globalint_1184 = 2; + } else { + globalint_1184 = 0; + } + break; + case 61145364: + if ((globalint_1184 != 3) && ((boolean)globalint_1200)) { + globalint_1184 = 3; + } else { + globalint_1184 = 0; + } + break; + case 61145374: + if ((globalint_1184 != 4) && ((boolean)globalint_1201)) { + globalint_1184 = 4; + } else { + globalint_1184 = 0; + } + break; + case 61145384: + if ((globalint_1184 != 5) && ((boolean)globalint_1202)) { + globalint_1184 = 5; + } else { + globalint_1184 = 0; + } + } + return; +} diff --git a/dumps/scripts/3273.cs2 b/dumps/scripts/3273.cs2 new file mode 100644 index 0000000..8bccf0d --- /dev/null +++ b/dumps/scripts/3273.cs2 @@ -0,0 +1,82 @@ +cs2func_script_3273_struct(3,0,0) script_3273() { + int ivar0; + int ivar1; + int ivar2; + ivar0 = 0; + ivar1 = divide(globalint_1191, 10); + ivar2 = subtract(globalint_1191, multiply(divide(globalint_1191, 10), 10)); + switch (ivar1) { + flow_1: + case 1: + switch (ivar2) { + case 1: + ivar0 = 0; + } + break; + case 2: + switch (ivar2) { + case 1: + ivar0 = -760; + break; + case 2: + ivar0 = 507; + } + break; + case 3: + switch (ivar2) { + case 1: + ivar0 = -1520; + break; + case 2: + ivar0 = 190; + break; + case 3: + ivar0 = 950; + } + break; + case 4: + switch (ivar2) { + case 1: + ivar0 = -2280; + break; + case 2: + ivar0 = -760; + break; + case 3: + ivar0 = 633; + break; + case 4: + ivar0 = 1457; + } + break; + case 5: + SWITCH (ivar2) { + case 1: + GOTO flow_20 + case 2: + GOTO flow_21 + case 3: + GOTO flow_22 + case 4: + GOTO flow_23 + case 5: + GOTO flow_24 + } + break; + flow_20: + ivar0 = -3040; + break; + flow_21: + ivar0 = -1267; + break; + flow_22: + ivar0 = 380; + break; + flow_23: + ivar0 = 1140; + break; + flow_24: + ivar0 = 1900; + } + return newstruct cs2func_script_3273_struct(ivar1, ivar2, ivar0); +} diff --git a/dumps/scripts/3274.cs2 b/dumps/scripts/3274.cs2 new file mode 100644 index 0000000..ec61510 --- /dev/null +++ b/dumps/scripts/3274.cs2 @@ -0,0 +1,15 @@ +int script_3274() { + switch (globalint_1320) { + case 1: + return 5000; + case 2: + return 5500; + case 3: + return 6000; + case 4: + return 6500; + case 5: + return 7000; + } + return 10000; +} diff --git a/dumps/scripts/3275.cs2 b/dumps/scripts/3275.cs2 new file mode 100644 index 0000000..c46cd0f --- /dev/null +++ b/dumps/scripts/3275.cs2 @@ -0,0 +1,12 @@ +int script_3275() { + if (((boolean)globalint_1196)) { + switch (globalint_1188) { + case 3: + return 9500; + case 2: + return 9500; + } + return 9500; + } + return 10000; +} diff --git a/dumps/scripts/3276.cs2 b/dumps/scripts/3276.cs2 new file mode 100644 index 0000000..1a5b005 --- /dev/null +++ b/dumps/scripts/3276.cs2 @@ -0,0 +1,473 @@ +void script_3276() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + int ivar22; + int ivar23; + int ivar24; + int ivar25; + int ivar26; + int ivar27; + int ivar28; + int ivar29; + int ivar30; + int ivar31; + int ivar32; + int ivar33; + int ivar34; + int ivar35; + int ivar36; + int ivar37; + int ivar38; + int ivar39; + int ivar40; + int ivar41; + cs2func_script_3273_struct(3,0,0) structdump_0; + cs2func_script_3273_struct(3,0,0) structdump_1; + cs2func_script_3273_struct(3,0,0) structdump_2; + ivar0 = 0; + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + ivar4 = 0; + ivar5 = 0; + ivar6 = 0; + ivar7 = 0; + ivar8 = 100; + ivar9 = 25; + ivar10 = 25; + ivar11 = 50; + ivar12 = 25; + ivar13 = 25; + ivar14 = 50; + ivar15 = 25; + ivar16 = 25; + ivar17 = 50; + ivar18 = 100; + ivar19 = 50; + ivar20 = 25; + ivar21 = 150; + ivar22 = 25; + ivar23 = 100; + ivar24 = 25; + ivar25 = 100; + ivar26 = 25; + ivar27 = 50; + ivar28 = 25; + ivar29 = 50; + ivar30 = 25; + ivar31 = 25; + ivar32 = 25; + ivar33 = 150; + ivar34 = 100; + ivar35 = 200; + ivar36 = 100; + globalint_1186 = 2000; + globalint_1185 = max(subtract(globalint_1185, 2), 0); + cs2method2103(globalint_1185, new WidgetPointer(933,251)); + cs2method2103(0, new WidgetPointer(933,297)); + cs2method2103(0, new WidgetPointer(933,298)); + cs2method2103(0, new WidgetPointer(933,299)); + ivar37 = 0; + if (globalint_1188 == 2) { + ivar37 = 792; + } else { + if (globalint_1188 == 3) { + ivar37 = 1583; + } + } + ivar38 = multiplyDivide(globalint_1195, 10000, 1267); + structdump_0 = script_3273(); + ivar5 = structdump_0.intpart_2; + ivar4 = structdump_0.intpart_1; + ivar3 = structdump_0.intpart_0; + ivar39 = ivar5; + ivar40 = script_3274(); + ivar41 = subtract(10000, multiply(min(bitconfig_7554, 6), 1000)); + setWidgetIsHidden(false, new WidgetPointer(933,192)); + setWidgetIsHidden(false, new WidgetPointer(933,17)); + setWidgetIsHidden(false, new WidgetPointer(933,187)); + setWidgetIsHidden(false, new WidgetPointer(933,240)); + if (globalint_1187 < globalint_1319) { + setWidgetText(new WidgetPointer(933,240), "Floor " + intToStr(globalint_1187) + ":"); + setWidgetRGB(new Color(160, 0, 0), new WidgetPointer(933,240)); + } else { + setWidgetText(new WidgetPointer(933,240), "Floor " + intToStr(globalint_1319) + ":"); + } + setWidgetIsHidden(false, new WidgetPointer(933,22)); + setWidgetSize(add(getWidgetActualWidth(new WidgetPointer(933,23)), 5), add(getWidgetActualHeight(new WidgetPointer(933,23)), 5), 0, 0, new WidgetPointer(933,23)); + playSoundEffect(8802, 1, 0); + cs2method2103(min(255, add(getWidgetShadeColor(new WidgetPointer(933,23)), 30)), new WidgetPointer(933,23)); + setWidgetIsHidden(false, new WidgetPointer(933,241)); + setWidgetText(new WidgetPointer(933,241), intToStr(multiplyDivide(divide(add(globalint_1237, 5), 10), 100, ivar8))); + setWidgetIsHidden(false, new WidgetPointer(933,190)); + cs2method2103(subtract(255, divide(multiply(ivar8, 255), 100)), new WidgetPointer(933,190)); + setWidgetIsHidden(false, new WidgetPointer(933,188)); + setWidgetIsHidden(false, new WidgetPointer(933,227)); + if (isMember()) { + setWidgetText(new WidgetPointer(933,227), "Prestige " + intToStr(min(60, max(bitconfig_7550, bitconfig_7551)))); + } else { + setWidgetText(new WidgetPointer(933,227), "Prestige " + intToStr(min(35, max(bitconfig_7550, bitconfig_7551)))); + } + setWidgetIsHidden(false, new WidgetPointer(933,21)); + setWidgetSize(add(getWidgetActualWidth(new WidgetPointer(933,24)), 5), add(getWidgetActualHeight(new WidgetPointer(933,24)), 5), 0, 0, new WidgetPointer(933,24)); + cs2method2103(255, new WidgetPointer(933,24)); + setWidgetIsHidden(false, new WidgetPointer(933,228)); + setWidgetText(new WidgetPointer(933,228), intToStr(multiplyDivide(divide(add(globalint_1238, 5), 10), 100, ivar8))); + setWidgetIsHidden(false, new WidgetPointer(933,191)); + cs2method2103(subtract(255, divide(multiply(ivar8, 255), 100)), new WidgetPointer(933,191)); + setWidgetIsHidden(false, new WidgetPointer(933,189)); + setWidgetIsHidden(false, new WidgetPointer(933,214)); + setWidgetIsHidden(false, new WidgetPointer(933,20)); + setWidgetSize(add(getWidgetActualWidth(new WidgetPointer(933,25)), 5), add(getWidgetActualHeight(new WidgetPointer(933,25)), 5), 0, 0, new WidgetPointer(933,25)); + cs2method2103(0, new WidgetPointer(933,25)); + setWidgetIsHidden(false, new WidgetPointer(933,215)); + setWidgetText(new WidgetPointer(933,215), intToStr(multiplyDivide(divide(add(globalint_1239, 5), 10), 100, ivar8))); + setWidgetIsHidden(true, new WidgetPointer(933,186)); + setWidgetIsHidden(false, new WidgetPointer(933,19)); + setWidgetText(new WidgetPointer(933,39), intToStr(multiplyDivide(divide(add(globalint_1239, 5), 10), 100, ivar8))); + cs2method2103(255, new WidgetPointer(933,37)); + setWidgetIsHidden(false, new WidgetPointer(933,83)); + setWidgetIsHidden(false, new WidgetPointer(933,18)); + setWidgetIsHidden(false, new WidgetPointer(933,53)); + setWidgetIsHidden(false, new WidgetPointer(933,54)); + setWidgetIsHidden(false, new WidgetPointer(933,68)); + setWidgetIsHidden(false, new WidgetPointer(933,69)); + setWidgetIsHidden(false, new WidgetPointer(933,70)); + setWidgetIsHidden(false, new WidgetPointer(933,71)); + setWidgetIsHidden(false, new WidgetPointer(933,72)); + setWidgetIsHidden(false, new WidgetPointer(933,73)); + setWidgetIsHidden(false, new WidgetPointer(933,74)); + structdump_1 = script_3273(); + ivar5 = structdump_1.intpart_2; + ivar4 = structdump_1.intpart_1; + ivar3 = structdump_1.intpart_0; + if (globalint_1188 <= 1) { + cs2method2103(0, new WidgetPointer(933,68)); + setWidgetText(new WidgetPointer(933,74), "+0%"); + } else if (globalint_1188 == 2) { + cs2method2103(0, new WidgetPointer(933,69)); + setWidgetText(new WidgetPointer(933,74), "+" + intToStr(divide(792, 100)) + "%"); + } else { + if (globalint_1188 > 2) { + cs2method2103(0, new WidgetPointer(933,70)); + setWidgetText(new WidgetPointer(933,74), "+" + intToStr(divide(1583, 100)) + "%"); + } + } + setWidgetIsHidden(false, new WidgetPointer(933,55)); + setWidgetIsHidden(false, new WidgetPointer(933,64)); + setWidgetIsHidden(false, new WidgetPointer(933,75)); + setWidgetSize(multiplyDivide(multiplyDivide(globalint_1195, 10000, 16384), 100, ivar8), 16384, 2, 2, new WidgetPointer(933,172)); + ivar0 = add(10000, ivar37); + ivar1 = add(add(10000, ivar37), ivar38); + if (ivar1 >= ivar0) { + setWidgetText(new WidgetPointer(933,75), "+" + intToStr(divide(add(multiplyDivide(ivar8, 100, subtract(ivar1, ivar0)), 50), 100)) + "%"); + } else { + setWidgetText(new WidgetPointer(933,75), intToStr(divide(add(multiplyDivide(ivar8, 100, subtract(ivar1, ivar0)), 50), 100)) + "%"); + } + setWidgetText(new WidgetPointer(933,96), intToStr(divide(add(add(ivar0, multiplyDivide(ivar8, 100, subtract(ivar1, ivar0))), 50), 100)) + "%"); + setWidgetSize(multiplyDivide(8192, 100, divide(add(add(ivar0, multiplyDivide(ivar8, 100, subtract(ivar1, ivar0))), 50), 100)), 16384, 2, 2, new WidgetPointer(933,112)); + setWidgetIsHidden(false, new WidgetPointer(933,56)); + setWidgetIsHidden(false, new WidgetPointer(933,57)); + setWidgetIsHidden(false, new WidgetPointer(933,78)); + setWidgetIsHidden(false, new WidgetPointer(933,80)); + setWidgetIsHidden(false, new WidgetPointer(933,59)); + cs2method2103(subtract(255, divide(multiply(ivar8, 255), 100)), new WidgetPointer(933,78)); + cs2method2103(subtract(255, divide(multiply(ivar8, 255), 100)), new WidgetPointer(933,80)); + structdump_2 = script_3273(); + ivar5 = structdump_2.intpart_2; + ivar4 = structdump_2.intpart_1; + ivar3 = structdump_2.intpart_0; + setWidgetText(new WidgetPointer(933,57), intToStr(ivar3) + " : " + intToStr(ivar4)); + ivar0 = add(add(10000, ivar37), ivar38); + ivar1 = add(add(add(10000, ivar37), ivar38), ivar39); + if (ivar1 >= ivar0) { + setWidgetText(new WidgetPointer(933,59), "+" + intToStr(divide(add(multiplyDivide(ivar8, 100, subtract(ivar1, ivar0)), 50), 100)) + "%"); + } else { + setWidgetText(new WidgetPointer(933,59), intToStr(divide(add(multiplyDivide(ivar8, 100, subtract(ivar1, ivar0)), 50), 100)) + "%"); + } + setWidgetIsHidden(false, new WidgetPointer(933,61)); + setWidgetIsHidden(false, new WidgetPointer(933,76)); + ivar0 = add(add(add(10000, ivar37), ivar38), ivar39); + ivar1 = add(add(add(add(10000, ivar37), ivar38), ivar39), globalint_1236); + if (ivar1 >= ivar0) { + setWidgetText(new WidgetPointer(933,76), "+" + intToStr(divide(add(multiplyDivide(ivar8, 100, subtract(ivar1, ivar0)), 50), 100)) + "%"); + } else { + setWidgetText(new WidgetPointer(933,76), intToStr(divide(add(multiplyDivide(ivar8, 100, subtract(ivar1, ivar0)), 50), 100)) + "%"); + } + setWidgetIsHidden(false, new WidgetPointer(933,62)); + setWidgetIsHidden(false, new WidgetPointer(933,58)); + setWidgetIsHidden(false, new WidgetPointer(933,79)); + setWidgetIsHidden(false, new WidgetPointer(933,81)); + setWidgetIsHidden(false, new WidgetPointer(933,60)); + cs2method2103(subtract(255, divide(multiply(ivar8, 255), 100)), new WidgetPointer(933,79)); + cs2method2103(subtract(255, divide(multiply(ivar8, 255), 100)), new WidgetPointer(933,81)); + setWidgetText(new WidgetPointer(933,58), intToStr(multiplyDivide(globalint_1320, 100, ivar8))); + ivar0 = add(add(add(add(10000, ivar37), ivar38), ivar39), globalint_1236); + ivar1 = multiplyDivide(add(add(add(add(10000, ivar37), ivar38), ivar39), globalint_1236), 10000, ivar40); + if (ivar1 >= ivar0) { + setWidgetText(new WidgetPointer(933,60), "+" + intToStr(divide(add(multiplyDivide(ivar8, 100, subtract(ivar1, ivar0)), 50), 100)) + "%"); + } else { + setWidgetText(new WidgetPointer(933,60), intToStr(divide(add(multiplyDivide(ivar8, 100, subtract(ivar1, ivar0)), 50), 100)) + "%"); + } + setWidgetIsHidden(false, new WidgetPointer(933,63)); + setWidgetIsHidden(false, new WidgetPointer(933,77)); + ivar0 = multiplyDivide(add(add(add(add(10000, ivar37), ivar38), ivar39), globalint_1236), 10000, ivar40); + ivar1 = multiplyDivide(multiplyDivide(add(add(add(add(10000, ivar37), ivar38), ivar39), globalint_1236), 10000, ivar40), 10000, script_3275()); + if (ivar1 >= ivar0) { + setWidgetText(new WidgetPointer(933,77), "+" + intToStr(divide(add(multiplyDivide(ivar8, 100, subtract(ivar1, ivar0)), 50), 100)) + "%"); + } else { + setWidgetText(new WidgetPointer(933,77), intToStr(divide(add(multiplyDivide(ivar8, 100, subtract(ivar1, ivar0)), 50), 100)) + "%"); + } + setWidgetIsHidden(false, new WidgetPointer(933,65)); + setWidgetIsHidden(false, new WidgetPointer(933,66)); + setWidgetIsHidden(false, new WidgetPointer(933,67)); + if (bitconfig_7554 != 0) { + switch (bitconfig_7554) { + case 1: + setWidgetIsHidden(false, new WidgetPointer(933,146)); + setWidgetSprite(2849, new WidgetPointer(933,146)); + break; + case 2: + setWidgetIsHidden(false, new WidgetPointer(933,146)); + setWidgetIsHidden(false, new WidgetPointer(933,147)); + setWidgetSprite(2850, new WidgetPointer(933,146)); + setWidgetSprite(2849, new WidgetPointer(933,147)); + break; + case 3: + setWidgetIsHidden(false, new WidgetPointer(933,146)); + setWidgetIsHidden(false, new WidgetPointer(933,147)); + setWidgetIsHidden(false, new WidgetPointer(933,148)); + setWidgetSprite(2850, new WidgetPointer(933,147)); + setWidgetSprite(2849, new WidgetPointer(933,148)); + break; + case 4: + setWidgetIsHidden(false, new WidgetPointer(933,146)); + setWidgetIsHidden(false, new WidgetPointer(933,147)); + setWidgetIsHidden(false, new WidgetPointer(933,148)); + setWidgetIsHidden(false, new WidgetPointer(933,149)); + setWidgetSprite(2850, new WidgetPointer(933,148)); + setWidgetSprite(2849, new WidgetPointer(933,149)); + break; + case 5: + setWidgetIsHidden(false, new WidgetPointer(933,146)); + setWidgetIsHidden(false, new WidgetPointer(933,147)); + setWidgetIsHidden(false, new WidgetPointer(933,148)); + setWidgetIsHidden(false, new WidgetPointer(933,149)); + setWidgetIsHidden(false, new WidgetPointer(933,150)); + setWidgetSprite(2850, new WidgetPointer(933,149)); + setWidgetSprite(2849, new WidgetPointer(933,150)); + break; + case 6: + setWidgetIsHidden(false, new WidgetPointer(933,146)); + setWidgetIsHidden(false, new WidgetPointer(933,147)); + setWidgetIsHidden(false, new WidgetPointer(933,148)); + setWidgetIsHidden(false, new WidgetPointer(933,149)); + setWidgetIsHidden(false, new WidgetPointer(933,150)); + setWidgetIsHidden(false, new WidgetPointer(933,151)); + setWidgetSprite(2850, new WidgetPointer(933,150)); + setWidgetSprite(2849, new WidgetPointer(933,151)); + break; + case 7: + setWidgetIsHidden(false, new WidgetPointer(933,146)); + setWidgetIsHidden(false, new WidgetPointer(933,147)); + setWidgetIsHidden(false, new WidgetPointer(933,148)); + setWidgetIsHidden(false, new WidgetPointer(933,149)); + setWidgetIsHidden(false, new WidgetPointer(933,150)); + setWidgetIsHidden(false, new WidgetPointer(933,151)); + setWidgetIsHidden(false, new WidgetPointer(933,152)); + setWidgetSprite(2850, new WidgetPointer(933,151)); + setWidgetSprite(2849, new WidgetPointer(933,152)); + break; + case 8: + setWidgetIsHidden(false, new WidgetPointer(933,146)); + setWidgetIsHidden(false, new WidgetPointer(933,147)); + setWidgetIsHidden(false, new WidgetPointer(933,148)); + setWidgetIsHidden(false, new WidgetPointer(933,149)); + setWidgetIsHidden(false, new WidgetPointer(933,150)); + setWidgetIsHidden(false, new WidgetPointer(933,151)); + setWidgetIsHidden(false, new WidgetPointer(933,152)); + setWidgetIsHidden(false, new WidgetPointer(933,153)); + setWidgetSprite(2850, new WidgetPointer(933,152)); + setWidgetSprite(2849, new WidgetPointer(933,153)); + break; + case 9: + setWidgetIsHidden(false, new WidgetPointer(933,146)); + setWidgetIsHidden(false, new WidgetPointer(933,147)); + setWidgetIsHidden(false, new WidgetPointer(933,148)); + setWidgetIsHidden(false, new WidgetPointer(933,149)); + setWidgetIsHidden(false, new WidgetPointer(933,150)); + setWidgetIsHidden(false, new WidgetPointer(933,151)); + setWidgetIsHidden(false, new WidgetPointer(933,152)); + setWidgetIsHidden(false, new WidgetPointer(933,153)); + setWidgetIsHidden(false, new WidgetPointer(933,154)); + setWidgetSprite(2850, new WidgetPointer(933,153)); + setWidgetSprite(2849, new WidgetPointer(933,154)); + break; + case 10: + setWidgetIsHidden(false, new WidgetPointer(933,146)); + setWidgetIsHidden(false, new WidgetPointer(933,147)); + setWidgetIsHidden(false, new WidgetPointer(933,148)); + setWidgetIsHidden(false, new WidgetPointer(933,149)); + setWidgetIsHidden(false, new WidgetPointer(933,150)); + setWidgetIsHidden(false, new WidgetPointer(933,151)); + setWidgetIsHidden(false, new WidgetPointer(933,152)); + setWidgetIsHidden(false, new WidgetPointer(933,153)); + setWidgetIsHidden(false, new WidgetPointer(933,154)); + setWidgetIsHidden(false, new WidgetPointer(933,155)); + setWidgetSprite(2850, new WidgetPointer(933,154)); + setWidgetSprite(2849, new WidgetPointer(933,155)); + break; + case 11: + setWidgetIsHidden(false, new WidgetPointer(933,146)); + setWidgetIsHidden(false, new WidgetPointer(933,147)); + setWidgetIsHidden(false, new WidgetPointer(933,148)); + setWidgetIsHidden(false, new WidgetPointer(933,149)); + setWidgetIsHidden(false, new WidgetPointer(933,150)); + setWidgetIsHidden(false, new WidgetPointer(933,151)); + setWidgetIsHidden(false, new WidgetPointer(933,152)); + setWidgetIsHidden(false, new WidgetPointer(933,153)); + setWidgetIsHidden(false, new WidgetPointer(933,154)); + setWidgetIsHidden(false, new WidgetPointer(933,155)); + setWidgetIsHidden(false, new WidgetPointer(933,156)); + setWidgetSprite(2850, new WidgetPointer(933,155)); + setWidgetSprite(2849, new WidgetPointer(933,156)); + break; + case 12: + setWidgetIsHidden(false, new WidgetPointer(933,146)); + setWidgetIsHidden(false, new WidgetPointer(933,147)); + setWidgetIsHidden(false, new WidgetPointer(933,148)); + setWidgetIsHidden(false, new WidgetPointer(933,149)); + setWidgetIsHidden(false, new WidgetPointer(933,150)); + setWidgetIsHidden(false, new WidgetPointer(933,151)); + setWidgetIsHidden(false, new WidgetPointer(933,152)); + setWidgetIsHidden(false, new WidgetPointer(933,153)); + setWidgetIsHidden(false, new WidgetPointer(933,154)); + setWidgetIsHidden(false, new WidgetPointer(933,155)); + setWidgetIsHidden(false, new WidgetPointer(933,156)); + setWidgetIsHidden(false, new WidgetPointer(933,157)); + setWidgetSprite(2850, new WidgetPointer(933,156)); + setWidgetSprite(2849, new WidgetPointer(933,157)); + break; + case 13: + setWidgetIsHidden(false, new WidgetPointer(933,146)); + setWidgetIsHidden(false, new WidgetPointer(933,147)); + setWidgetIsHidden(false, new WidgetPointer(933,148)); + setWidgetIsHidden(false, new WidgetPointer(933,149)); + setWidgetIsHidden(false, new WidgetPointer(933,150)); + setWidgetIsHidden(false, new WidgetPointer(933,151)); + setWidgetIsHidden(false, new WidgetPointer(933,152)); + setWidgetIsHidden(false, new WidgetPointer(933,153)); + setWidgetIsHidden(false, new WidgetPointer(933,154)); + setWidgetIsHidden(false, new WidgetPointer(933,155)); + setWidgetIsHidden(false, new WidgetPointer(933,156)); + setWidgetIsHidden(false, new WidgetPointer(933,157)); + setWidgetIsHidden(false, new WidgetPointer(933,158)); + setWidgetSprite(2850, new WidgetPointer(933,157)); + setWidgetSprite(2849, new WidgetPointer(933,158)); + break; + case 14: + setWidgetIsHidden(false, new WidgetPointer(933,146)); + setWidgetIsHidden(false, new WidgetPointer(933,147)); + setWidgetIsHidden(false, new WidgetPointer(933,148)); + setWidgetIsHidden(false, new WidgetPointer(933,149)); + setWidgetIsHidden(false, new WidgetPointer(933,150)); + setWidgetIsHidden(false, new WidgetPointer(933,151)); + setWidgetIsHidden(false, new WidgetPointer(933,152)); + setWidgetIsHidden(false, new WidgetPointer(933,153)); + setWidgetIsHidden(false, new WidgetPointer(933,154)); + setWidgetIsHidden(false, new WidgetPointer(933,155)); + setWidgetIsHidden(false, new WidgetPointer(933,156)); + setWidgetIsHidden(false, new WidgetPointer(933,157)); + setWidgetIsHidden(false, new WidgetPointer(933,158)); + setWidgetIsHidden(false, new WidgetPointer(933,159)); + setWidgetSprite(2850, new WidgetPointer(933,158)); + setWidgetSprite(2849, new WidgetPointer(933,159)); + break; + case 15: + setWidgetIsHidden(false, new WidgetPointer(933,146)); + setWidgetIsHidden(false, new WidgetPointer(933,147)); + setWidgetIsHidden(false, new WidgetPointer(933,148)); + setWidgetIsHidden(false, new WidgetPointer(933,149)); + setWidgetIsHidden(false, new WidgetPointer(933,150)); + setWidgetIsHidden(false, new WidgetPointer(933,151)); + setWidgetIsHidden(false, new WidgetPointer(933,152)); + setWidgetIsHidden(false, new WidgetPointer(933,153)); + setWidgetIsHidden(false, new WidgetPointer(933,154)); + setWidgetIsHidden(false, new WidgetPointer(933,155)); + setWidgetIsHidden(false, new WidgetPointer(933,156)); + setWidgetIsHidden(false, new WidgetPointer(933,157)); + setWidgetIsHidden(false, new WidgetPointer(933,158)); + setWidgetIsHidden(false, new WidgetPointer(933,159)); + setWidgetIsHidden(false, new WidgetPointer(933,160)); + setWidgetSprite(2850, new WidgetPointer(933,159)); + setWidgetSprite(2849, new WidgetPointer(933,160)); + } + } else { + setWidgetText(new WidgetPointer(933,67), "n/a"); + globalint_1186 = add(globalint_1186, 2); + } + ivar0 = multiplyDivide(multiplyDivide(add(add(add(add(10000, ivar37), ivar38), ivar39), globalint_1236), 10000, ivar40), 10000, script_3275()); + ivar1 = multiplyDivide(multiplyDivide(multiplyDivide(add(add(add(add(10000, ivar37), ivar38), ivar39), globalint_1236), 10000, ivar40), 10000, script_3275()), 10000, ivar41); + if (ivar1 >= ivar0) { + setWidgetText(new WidgetPointer(933,67), "+" + intToStr(divide(add(multiplyDivide(ivar8, 100, subtract(ivar1, ivar0)), 50), 100)) + "%"); + } else { + setWidgetText(new WidgetPointer(933,67), intToStr(divide(add(multiplyDivide(ivar8, 100, subtract(ivar1, ivar0)), 50), 100)) + "%"); + } + setWidgetIsHidden(true, new WidgetPointer(933,53)); + if (globalint_1321 > 0) { + setWidgetIsHidden(false, new WidgetPointer(933,84)); + setWidgetText(new WidgetPointer(933,94), "Unbalanced party penalty: x" + intToStr(divide(add(subtract(10000, globalint_1321), 50), 100)) + "%"); + } + ivar0 = multiplyDivide(multiplyDivide(multiplyDivide(add(add(add(add(10000, ivar37), ivar38), ivar39), globalint_1236), 10000, ivar40), 10000, script_3275()), 10000, ivar41); + ivar1 = multiplyDivide(multiplyDivide(multiplyDivide(multiplyDivide(add(add(add(add(10000, ivar37), ivar38), ivar39), globalint_1236), 10000, ivar40), 10000, script_3275()), 10000, ivar41), 10000, subtract(10000, globalint_1321)); + setWidgetText(new WidgetPointer(933,96), intToStr(divide(add(add(ivar0, multiplyDivide(ivar8, 100, subtract(ivar1, ivar0))), 50), 100)) + "%"); + setWidgetSize(multiplyDivide(8192, 100, divide(add(add(ivar0, multiplyDivide(ivar8, 100, subtract(ivar1, ivar0))), 50), 100)), 16384, 2, 2, new WidgetPointer(933,112)); + setWidgetIsHidden(true, new WidgetPointer(933,13)); + setWidgetIsHidden(true, new WidgetPointer(933,16)); + setWidgetIsHidden(true, new WidgetPointer(933,14)); + setWidgetIsHidden(true, new WidgetPointer(933,15)); + setWidgetText(new WidgetPointer(933,39), intToStr(globalint_1239)); + ivar0 = globalint_1239; + ivar1 = multiplyDivide(multiplyDivide(multiplyDivide(multiplyDivide(multiplyDivide(add(add(add(add(10000, ivar37), ivar38), ivar39), globalint_1236), 10000, ivar40), 10000, script_3275()), 10000, ivar41), 10000, subtract(10000, globalint_1321)), 10000, globalint_1239); + if (((boolean)mod(ivar8, 5)) && (getWidgetActualY(new WidgetPointer(933,84)) != 138)) { + setWidgetPosition(getWidgetActualX(new WidgetPointer(933,84)), add(getWidgetActualY(new WidgetPointer(933,84)), 1), 0, 0, new WidgetPointer(933,84)); + } + setWidgetSize(183, multiplyDivide(80, 100, ivar8), 0, 0, new WidgetPointer(933,111)); + setWidgetText(new WidgetPointer(933,39), intToStr(divide(add(add(ivar0, multiplyDivide(ivar8, 100, subtract(ivar1, ivar0))), 5), 10)) + "%"); + ivar0 = globalint_1239; + ivar1 = multiplyDivide(multiplyDivide(multiplyDivide(multiplyDivide(multiplyDivide(add(add(add(add(10000, ivar37), ivar38), ivar39), globalint_1236), 10000, ivar40), 10000, script_3275()), 10000, ivar41), 10000, subtract(10000, globalint_1321)), 10000, globalint_1239); + setWidgetText(new WidgetPointer(933,41), intToStr(divide(add(add(ivar0, multiplyDivide(ivar8, 100, subtract(ivar1, ivar0))), 5), 100)) + "%"); + setWidgetIsHidden(true, new WidgetPointer(933,16)); + setWidgetIsHidden(true, new WidgetPointer(933,14)); + setWidgetIsHidden(true, new WidgetPointer(933,15)); + if (standart_config_1780 < 2000000000) { + setWidgetText(new WidgetPointer(933,41), intToStr(divide(add(add(ivar0, multiplyDivide(ivar8, 100, subtract(ivar1, ivar0))), 5), 100)) + "%"); + } else { + setWidgetText(new WidgetPointer(933,41), "n/a"); + } + setWidgetIsHidden(true, new WidgetPointer(933,20)); + setWidgetIsHidden(true, new WidgetPointer(933,21)); + setWidgetIsHidden(true, new WidgetPointer(933,22)); + script_949(); + return; +} diff --git a/dumps/scripts/3277.cs2 b/dumps/scripts/3277.cs2 new file mode 100644 index 0000000..050ad80 --- /dev/null +++ b/dumps/scripts/3277.cs2 @@ -0,0 +1,10 @@ +void script_3277() { + globalint_1149 = 0; + globalint_1150 = 0; + globalint_1151 = 0; + globalint_1152 = 0; + deleteAllExtraChilds(new WidgetPointer(942,3)); + deleteAllExtraChilds(new WidgetPointer(942,5)); + deleteAllExtraChilds(new WidgetPointer(942,4)); + return; +} diff --git a/dumps/scripts/3278.cs2 b/dumps/scripts/3278.cs2 new file mode 100644 index 0000000..b0d2937 --- /dev/null +++ b/dumps/scripts/3278.cs2 @@ -0,0 +1,22 @@ +void script_3278(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + ivar4 = 0; + ivar5 = 0; + switch (arg3) { + case 1: + ivar4 = divide(getWidgetActualWidth(new WidgetPointer(942,3)), 4); + ivar5 = divide(getWidgetActualHeight(new WidgetPointer(942,3)), 4); + break; + case 2: + ivar4 = divide(getWidgetActualWidth(new WidgetPointer(942,3)), 4); + break; + } + createExtraChild(new WidgetPointer(942,3), 5, globalint_1149); + globalint_1149 = add(globalint_1149, 1); + setWidgetSize(32, 32, 0, 0); + setWidgetSprite(arg2); + setWidgetPosition(add(multiply(arg0, 32), ivar4), add(multiply(arg1, 32), ivar5), 0, 2); + setWidgetHidden(0); + return; +} diff --git a/dumps/scripts/3279.cs2 b/dumps/scripts/3279.cs2 new file mode 100644 index 0000000..d23f86d --- /dev/null +++ b/dumps/scripts/3279.cs2 @@ -0,0 +1,48 @@ +void script_3279(int arg0,int arg1,int arg2,int arg3,string arg4) { + int ivar4; + int ivar5; + if ((arg0 == -1) || (arg1 == -1)) { + return; + } + ivar4 = 0; + ivar5 = 0; + switch (arg3) { + case 1: + ivar4 = divide(getWidgetActualWidth(new WidgetPointer(942,3)), 4); + ivar5 = divide(getWidgetActualHeight(new WidgetPointer(942,3)), 4); + break; + case 2: + ivar4 = divide(getWidgetActualWidth(new WidgetPointer(942,3)), 4); + break; + } + createExtraChild(new WidgetPointer(942,5), 5, globalint_1152); + globalint_1152 = add(globalint_1152, 1); + switch (arg2) { + case 1: + setWidgetSprite(2825); + setWidgetPosition(add(add(multiply(arg0, 32), 6), ivar4), add(add(multiply(arg1, 32), 20), ivar5), 0, 2); + break; + case 2: + setWidgetSprite(2826); + setWidgetPosition(add(add(multiply(arg0, 32), 20), ivar4), add(add(multiply(arg1, 32), 20), ivar5), 0, 2); + break; + case 3: + setWidgetSprite(2827); + setWidgetPosition(add(add(multiply(arg0, 32), 13), ivar4), add(add(multiply(arg1, 32), 13), ivar5), 0, 2); + break; + case 4: + setWidgetSprite(2828); + setWidgetPosition(add(add(multiply(arg0, 32), 6), ivar4), add(add(multiply(arg1, 32), 6), ivar5), 0, 2); + break; + case 5: + setWidgetSprite(2829); + setWidgetPosition(add(add(multiply(arg0, 32), 20), ivar4), add(add(multiply(arg1, 32), 6), ivar5), 0, 2); + break; + } + setWidgetSize(11, 11, 0, 0); + setScriptCallOnMouseOver(3282, new WidgetPointer(-32768,3), -2147483643, new WidgetPointer(942,7), arg4, "IiIs"); + setScriptCallOnMouseExit(40, new WidgetPointer(942,7), "I"); + setWidgetFilled(1); + setWidgetHidden(0); + return; +} diff --git a/dumps/scripts/328.cs2 b/dumps/scripts/328.cs2 new file mode 100644 index 0000000..0b7cdc6 --- /dev/null +++ b/dumps/scripts/328.cs2 @@ -0,0 +1,61 @@ +void script_328(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + string svar0; + deleteAllExtraChilds(new WidgetPointer(arg0)); + ivar1 = 5; + ivar2 = 5; + ivar3 = 0; + ivar4 = 0; + ivar5 = 0; + ivar6 = 0; + svar0 = " "; + ivar7 = -1; + if (IsFemale()) { + ivar4 = getCommonDefinitionSize(2363); + if (((boolean)globalint_783)) { + ivar7 = 2362; + } else { + ivar7 = 2361; + } + } else if (((boolean)globalint_783)) { + ivar7 = 2129; + } else { + ivar7 = 1609; + } + ivar4 = getCommonDefinitionSize(2132); + ivar5 = multiply(ivar4, 2); + while (ivar3 < ivar4) { + createExtraChild(new WidgetPointer(arg0), 5, ivar3); + setWidgetSize(36, 36, 0, 0); + setWidgetPosition(ivar1, ivar2, 0, 0); + setWidgetSprite(180); + setWidgetContextMenuOption(1, "Select" + ""); + setScriptCallOnClickContextMenu(331, new WidgetPointer(-32768,3), -2147483643, "Ii"); + ivar3 = add(ivar3, 1); + ivar2 = add(28, ivar2); + } + ivar2 = 5; + while (ivar3 < ivar5) { + svar0 = cs2method_3408(105, 115, ivar7, ivar6); + createExtraChild(new WidgetPointer(arg0), 4, ivar3); + setWidgetText(svar0); + setWidgetSize(124, 16, 0, 0); + setWidgetPosition(add(ivar1, 20), ivar2, 0, 0); + setWidgetRGB(new Color(255, 255, 255)); + setWidgetFont(494); + setWidgetUnknownBoolean(false); + setWidgetTextAlignment(0, 1, 0); + setWidgetContextMenuOption(1, "Select" + ""); + setScriptCallOnClickContextMenu(331, new WidgetPointer(-32768,3), subtract(ivar3, ivar4), "Ii"); + ivar3 = add(ivar3, 1); + ivar6 = add(ivar6, 1); + ivar2 = add(28, ivar2); + } + return; +} diff --git a/dumps/scripts/3280.cs2 b/dumps/scripts/3280.cs2 new file mode 100644 index 0000000..a5b899c --- /dev/null +++ b/dumps/scripts/3280.cs2 @@ -0,0 +1,22 @@ +void script_3280(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + ivar3 = 0; + ivar4 = 0; + switch (arg2) { + case 1: + ivar3 = divide(getWidgetActualWidth(new WidgetPointer(942,3)), 4); + ivar4 = divide(getWidgetActualHeight(new WidgetPointer(942,3)), 4); + break; + case 2: + ivar3 = divide(getWidgetActualWidth(new WidgetPointer(942,3)), 4); + break; + } + createExtraChild(new WidgetPointer(942,4), 5, globalint_1151); + globalint_1151 = add(globalint_1151, 1); + setWidgetSize(32, 32, 0, 0); + setWidgetSprite(2831); + setWidgetPosition(add(multiply(arg0, 32), ivar3), add(multiply(arg1, 32), ivar4), 0, 2); + setWidgetHidden(0); + return; +} diff --git a/dumps/scripts/3281.cs2 b/dumps/scripts/3281.cs2 new file mode 100644 index 0000000..d0dc119 --- /dev/null +++ b/dumps/scripts/3281.cs2 @@ -0,0 +1,22 @@ +void script_3281(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + ivar3 = 0; + ivar4 = 0; + switch (arg2) { + case 1: + ivar3 = divide(getWidgetActualWidth(new WidgetPointer(942,3)), 4); + ivar4 = divide(getWidgetActualHeight(new WidgetPointer(942,3)), 4); + break; + case 2: + ivar3 = divide(getWidgetActualWidth(new WidgetPointer(942,3)), 4); + break; + } + createExtraChild(new WidgetPointer(942,4), 5, globalint_1151); + globalint_1151 = add(globalint_1151, 1); + setWidgetSize(32, 32, 0, 0); + setWidgetSprite(2833); + setWidgetPosition(add(multiply(arg0, 32), ivar3), add(multiply(arg1, 32), ivar4), 0, 2); + setWidgetHidden(0); + return; +} diff --git a/dumps/scripts/3282.cs2 b/dumps/scripts/3282.cs2 new file mode 100644 index 0000000..43b72eb --- /dev/null +++ b/dumps/scripts/3282.cs2 @@ -0,0 +1,4 @@ +void script_3282(int arg0,int arg1,int arg2,string arg3) { + script_3364(arg0, arg1, arg2, 25, getWidgetActualWidth(new WidgetPointer(getWidgetParentId(new WidgetPointer(arg2)))), 11, 11, arg3); + return; +} diff --git a/dumps/scripts/3283.cs2 b/dumps/scripts/3283.cs2 new file mode 100644 index 0000000..9bb1dae --- /dev/null +++ b/dumps/scripts/3283.cs2 @@ -0,0 +1,21 @@ +void script_3283(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + if (((boolean)arg3)) { + arg3 = 12; + } + ivar4 = getLineCount(add(getWidgetActualWidth(new WidgetPointer(arg1)), 16), arg2, getWidgetText(new WidgetPointer(arg1))); + ivar4 = multiply(ivar4, arg3); + messageType0("txt " + intToStr(ivar4) + ", layer " + intToStr(getWidgetActualHeight(new WidgetPointer(arg1)))); + if (getWidgetActualHeight(new WidgetPointer(arg1)) >= ivar4) { + messageType0("No scroll txt " + intToStr(ivar4) + ", layer " + intToStr(getWidgetActualHeight(new WidgetPointer(arg1)))); + setWidgetSize(add(getWidgetActualWidth(new WidgetPointer(arg1)), 16), getWidgetActualHeight(new WidgetPointer(arg1)), 0, 0, new WidgetPointer(arg1)); + setWidgetIsHidden(true, new WidgetPointer(arg0)); + } else { + ivar4 = getLineCount(getWidgetActualWidth(new WidgetPointer(arg1)), arg2, getWidgetText(new WidgetPointer(arg1))); + ivar4 = multiply(ivar4, arg3); + setWidgetScrollMax(0, add(ivar4, 10), new WidgetPointer(arg1)); + messageType0("Scroll txt " + intToStr(ivar4) + ", layer " + intToStr(getWidgetActualHeight(new WidgetPointer(arg1)))); + script_31(arg0, arg1, 792, 789, 790, 791, 773, 788); + } + return; +} diff --git a/dumps/scripts/3284.cs2 b/dumps/scripts/3284.cs2 new file mode 100644 index 0000000..945d8f0 --- /dev/null +++ b/dumps/scripts/3284.cs2 @@ -0,0 +1,27 @@ +void script_3284(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + ivar4 = add(61, multiply(10, subtract(arg0, 1))); + playSoundEffect(8809, 1, 0); + setWidgetPosition(0, ivar4, 0, 0, new WidgetPointer(arg1)); + setWidgetText(new WidgetPointer(arg2), intToStr(arg0)); + switch (cs2method_3408(105, 105, 1264, arg0)) { + case 1: + setWidgetText(new WidgetPointer(arg3), "Frozen"); + break; + case 2: + setWidgetText(new WidgetPointer(arg3), "Abandoned"); + break; + case 3: + setWidgetText(new WidgetPointer(arg3), "Furnished"); + break; + case 4: + setWidgetText(new WidgetPointer(arg3), "Occult"); + break; + case 5: + setWidgetText(new WidgetPointer(arg3), "Warped"); + break; + default: + setWidgetText(new WidgetPointer(arg3), "Dungeon"); + } + return; +} diff --git a/dumps/scripts/3285.cs2 b/dumps/scripts/3285.cs2 new file mode 100644 index 0000000..9cec163 --- /dev/null +++ b/dumps/scripts/3285.cs2 @@ -0,0 +1,8 @@ +void script_3285(int arg0) { + setWidgetScrollMax(0, arg0, new WidgetPointer(947,36)); + setWidgetScrollMax(0, arg0, new WidgetPointer(947,38)); + if (getWidgetScrollMaxV(new WidgetPointer(947,36)) < getWidgetActualHeight(new WidgetPointer(947,36))) { + setWidgetIsHidden(true, new WidgetPointer(947,47)); + } + return; +} diff --git a/dumps/scripts/3286.cs2 b/dumps/scripts/3286.cs2 new file mode 100644 index 0000000..3ea0841 --- /dev/null +++ b/dumps/scripts/3286.cs2 @@ -0,0 +1,4 @@ +void script_3286() { + globalint_10 = add(script_1305(), 100); + return; +} diff --git a/dumps/scripts/3287.cs2 b/dumps/scripts/3287.cs2 new file mode 100644 index 0000000..8439255 --- /dev/null +++ b/dumps/scripts/3287.cs2 @@ -0,0 +1,6 @@ +int script_3287() { + if (globalint_1324 > 2) { + return 1; + } + return 0; +} diff --git a/dumps/scripts/3288.cs2 b/dumps/scripts/3288.cs2 new file mode 100644 index 0000000..ec9e3d3 --- /dev/null +++ b/dumps/scripts/3288.cs2 @@ -0,0 +1,4 @@ +void script_3288(int arg0,int arg1,int arg2) { + script_3290(arg0, arg1, arg2, 792, 789, 790, 791, 773, 788); + return; +} diff --git a/dumps/scripts/3289.cs2 b/dumps/scripts/3289.cs2 new file mode 100644 index 0000000..4c549f6 --- /dev/null +++ b/dumps/scripts/3289.cs2 @@ -0,0 +1,4 @@ +void script_3289(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8) { + script_3290(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + return; +} diff --git a/dumps/scripts/329.cs2 b/dumps/scripts/329.cs2 new file mode 100644 index 0000000..ce0873b --- /dev/null +++ b/dumps/scripts/329.cs2 @@ -0,0 +1,12 @@ +void script_329(int arg0) { + int ivar1; + ivar1 = 0; + if (IsFemale()) { + ivar1 = getCommonDefinitionSize(2363); + } else { + ivar1 = getCommonDefinitionSize(2132); + } + script_332(globalint_785); + script_2366(arg0, globalint_785, ivar1); + return; +} diff --git a/dumps/scripts/3290.cs2 b/dumps/scripts/3290.cs2 new file mode 100644 index 0000000..2ce37ea --- /dev/null +++ b/dumps/scripts/3290.cs2 @@ -0,0 +1,76 @@ +void script_3290(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8) { + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + ivar9 = getWidgetScrollMaxV(new WidgetPointer(arg1)); + ivar10 = getWidgetActualHeight(new WidgetPointer(arg0)); + ivar11 = subtract(ivar10, 32); + ivar12 = 0; + if (ivar9 > 0) { + ivar12 = multiplyDivide(ivar10, ivar9, ivar11); + } else { + ivar12 = ivar11; + } + ivar12 = max(ivar12, 10); + ivar13 = cs2method2601(new WidgetPointer(arg1)); + ivar14 = 0; + ivar15 = 0; + if (ivar13 > 0) { + ivar14 = subtract(ivar9, getWidgetActualHeight(new WidgetPointer(arg1))); + if (((boolean)ivar14)) { + ivar14 = 1; + } + if (ivar13 > ivar14) { + cs2method2100(0, ivar14, new WidgetPointer(arg1)); + cs2method2100(0, ivar14, new WidgetPointer(arg2)); + ivar13 = ivar14; + } + ivar15 = multiplyDivide(ivar13, ivar14, subtract(ivar11, ivar12)); + ivar15 = min(max(ivar15, 0), subtract(ivar11, ivar12)); + } + createExtraChild(new WidgetPointer(arg0), 5, 0); + setWidgetPosition(0, 16, 0, 0); + setWidgetSize(16, 32, 0, 1); + setWidgetSprite(arg3); + cs2method1107(1); + setScriptCallOnMousePressed(3293, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), -2147483646, "IIIi"); + createExtraChild(new WidgetPointer(arg0), 5, 1); + setWidgetPosition(0, add(16, ivar15), 0, 0); + setWidgetSprite(arg5); + cs2method1107(1); + cs2method1301(arg0, 0); + cs2method1302(1); + setWidgetSize(16, ivar12, 0, 0); + setScriptCallOnMouseDragged(3294, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), -2147483646, 0, "IIIi1"); + setScriptCallOnMouseDragReleased(3294, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), -2147483646, 1, "IIIi1"); + createExtraChild(new WidgetPointer(arg0), 5, 2); + setWidgetPosition(0, add(16, ivar15), 0, 0); + setWidgetSize(16, 5, 0, 0); + setWidgetSprite(arg4); + cs2method1107(0); + createExtraChild(new WidgetPointer(arg0), 5, 3); + setWidgetPosition(0, subtract(add(add(16, ivar15), ivar12), 5), 0, 0); + setWidgetSize(16, 5, 0, 0); + setWidgetSprite(arg6); + cs2method1107(0); + createExtraChild(new WidgetPointer(arg0), 5, 4); + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(16, 16, 0, 0); + setWidgetSprite(arg7); + cs2method1107(0); + setScriptCallOnMouseDraggedOver(3291, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), "III"); + createExtraChild(new WidgetPointer(arg0), 5, 5); + setWidgetPosition(0, 0, 0, 2); + setWidgetSize(16, 16, 0, 0); + setWidgetSprite(arg8); + cs2method1107(0); + setScriptCallOnMouseDraggedOver(3292, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), "III"); + setScriptCallOnMouseScroll(3295, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), -2147483646, "IIIi", new WidgetPointer(arg0)); + setScriptCallOnMouseScroll(3295, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), -2147483646, "IIIi", new WidgetPointer(arg1)); + setScriptCallOnMouseScroll(3295, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), -2147483646, "IIIi", new WidgetPointer(arg2)); + return; +} diff --git a/dumps/scripts/3291.cs2 b/dumps/scripts/3291.cs2 new file mode 100644 index 0000000..05f66a6 --- /dev/null +++ b/dumps/scripts/3291.cs2 @@ -0,0 +1,8 @@ +void script_3291(int arg0,int arg1,int arg2) { + int ivar3; + ivar3 = subtract(cs2method2601(new WidgetPointer(arg1)), 4); + if (setWidgetRegister(new WidgetPointer(arg0), 1)) { + script_3296(arg0, arg1, arg2, ivar3, 1); + } + return; +} diff --git a/dumps/scripts/3292.cs2 b/dumps/scripts/3292.cs2 new file mode 100644 index 0000000..f4f7ffa --- /dev/null +++ b/dumps/scripts/3292.cs2 @@ -0,0 +1,8 @@ +void script_3292(int arg0,int arg1,int arg2) { + int ivar3; + ivar3 = add(cs2method2601(new WidgetPointer(arg1)), 4); + if (setWidgetRegister(new WidgetPointer(arg0), 1)) { + script_3296(arg0, arg1, arg2, ivar3, 1); + } + return; +} diff --git a/dumps/scripts/3293.cs2 b/dumps/scripts/3293.cs2 new file mode 100644 index 0000000..2f2d8f1 --- /dev/null +++ b/dumps/scripts/3293.cs2 @@ -0,0 +1,6 @@ +void script_3293(int arg0,int arg1,int arg2,int arg3) { + if (setWidgetRegister(new WidgetPointer(arg0), 1)) { + cs2method3109(0, divide(getWidgetActualHeight(), 2)); + } + return; +} diff --git a/dumps/scripts/3294.cs2 b/dumps/scripts/3294.cs2 new file mode 100644 index 0000000..6ace320 --- /dev/null +++ b/dumps/scripts/3294.cs2 @@ -0,0 +1,19 @@ +void script_3294(int arg0,int arg1,int arg2,int arg3,int arg4) { + int ivar5; + int ivar6; + ivar5 = 0; + ivar6 = 0; + if (setWidgetRegister(new WidgetPointer(arg0), 1)) { + if (setWidgetRegister(new WidgetPointer(arg0), 2)) { + setWidgetPosition(0, add(arg3, 16), 0, 0); + } + if (setWidgetRegister(new WidgetPointer(arg0), 3)) { + setWidgetPosition(0, add(subtract(add(arg3, getWidgetActualHeight()), 5), 16), 0, 0); + } + ivar5 = subtract(subtract(getWidgetActualHeight(new WidgetPointer(arg0)), 32), getWidgetActualHeight()); + ivar6 = subtract(getWidgetScrollMaxV(new WidgetPointer(arg1)), getWidgetActualHeight(new WidgetPointer(arg1))); + arg3 = divide(multiply(arg3, ivar6), ivar5); + script_3296(arg0, arg1, arg2, arg3, arg4); + } + return; +} diff --git a/dumps/scripts/3295.cs2 b/dumps/scripts/3295.cs2 new file mode 100644 index 0000000..2c598e0 --- /dev/null +++ b/dumps/scripts/3295.cs2 @@ -0,0 +1,8 @@ +void script_3295(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + ivar4 = add(cs2method2601(new WidgetPointer(arg1)), multiply(arg3, 45)); + if (setWidgetRegister(new WidgetPointer(arg0), 1)) { + script_3296(arg0, arg1, arg2, ivar4, 1); + } + return; +} diff --git a/dumps/scripts/3296.cs2 b/dumps/scripts/3296.cs2 new file mode 100644 index 0000000..a474619 --- /dev/null +++ b/dumps/scripts/3296.cs2 @@ -0,0 +1,28 @@ +void script_3296(int arg0,int arg1,int arg2,int arg3,int arg4) { + int ivar5; + int ivar6; + ivar5 = subtract(getWidgetScrollMaxV(new WidgetPointer(arg1)), getWidgetActualHeight(new WidgetPointer(arg1))); + if (((boolean)ivar5)) { + ivar5 = 1; + } + if (arg3 < 0) { + arg3 = 0; + } + if (arg3 > ivar5) { + arg3 = ivar5; + } + cs2method2100(0, arg3, new WidgetPointer(arg1)); + cs2method2100(0, arg3, new WidgetPointer(arg2)); + ivar6 = 0; + if (((boolean)arg4)) { + ivar6 = subtract(subtract(getWidgetActualHeight(new WidgetPointer(arg0)), 32), getWidgetActualHeight()); + setWidgetPosition(0, add(16, multiplyDivide(arg3, ivar5, ivar6)), 0, 0); + if (setWidgetRegister(new WidgetPointer(arg0), 2)) { + setWidgetPosition(0, getWidgetActualY(), 0, 0); + } + if (setWidgetRegister(new WidgetPointer(arg0), 3)) { + setWidgetPosition(0, subtract(add(getWidgetActualY(), getWidgetActualHeight()), 5), 0, 0); + } + } + return; +} diff --git a/dumps/scripts/3297.cs2 b/dumps/scripts/3297.cs2 new file mode 100644 index 0000000..07bfe7a --- /dev/null +++ b/dumps/scripts/3297.cs2 @@ -0,0 +1,28 @@ +void script_3297(int arg0,int arg1,int arg2,int arg3,int arg4) { + int ivar5; + int ivar6; + ivar5 = subtract(getWidgetScrollMaxV(new WidgetPointer(arg1)), getWidgetActualHeight(new WidgetPointer(arg1))); + if (((boolean)ivar5)) { + ivar5 = 1; + } + if (arg3 < 0) { + arg3 = 0; + } + if (arg3 > ivar5) { + arg3 = ivar5; + } + cs2method2100(0, arg3, new WidgetPointer(arg1)); + cs2method2100(0, arg3, new WidgetPointer(arg2)); + ivar6 = 0; + if (setWidgetRegister(new WidgetPointer(arg0), 1) && ((boolean)arg4)) { + ivar6 = subtract(subtract(getWidgetActualHeight(new WidgetPointer(arg0)), 32), getWidgetActualHeight()); + setWidgetPosition(0, add(16, divide(multiply(ivar6, arg3), ivar5)), 0, 0); + if (setWidgetRegister(new WidgetPointer(arg0), 2)) { + setWidgetPosition(0, getWidgetActualY(), 0, 0); + } + if (setWidgetRegister(new WidgetPointer(arg0), 3)) { + setWidgetPosition(0, subtract(add(getWidgetActualY(), getWidgetActualHeight()), 5), 0, 0); + } + } + return; +} diff --git a/dumps/scripts/3298.cs2 b/dumps/scripts/3298.cs2 new file mode 100644 index 0000000..16a587f --- /dev/null +++ b/dumps/scripts/3298.cs2 @@ -0,0 +1,23 @@ +void script_3298(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + int ivar6; + int ivar7; + ivar4 = getWidgetScrollMaxV(new WidgetPointer(arg1)); + ivar5 = getWidgetActualHeight(new WidgetPointer(arg0)); + ivar6 = subtract(ivar5, 32); + ivar7 = 0; + if (ivar4 > 0) { + ivar7 = divide(multiply(ivar6, ivar5), ivar4); + } else { + ivar7 = ivar6; + } + if (ivar7 < 10) { + ivar7 = 10; + } + if (setWidgetRegister(new WidgetPointer(arg0), 1)) { + setWidgetSize(16, ivar7, 0, 0); + script_3296(arg0, arg1, arg2, arg3, 1); + } + return; +} diff --git a/dumps/scripts/3299.cs2 b/dumps/scripts/3299.cs2 new file mode 100644 index 0000000..341c30c --- /dev/null +++ b/dumps/scripts/3299.cs2 @@ -0,0 +1,6 @@ +void script_3299(int arg0,int arg1) { + if (getItemIdInSlotSplit(arg0, arg1) != -1) { + messageType0(getItemName(getItemIdInSlotSplit(arg0, arg1))); + } + return; +} diff --git a/dumps/scripts/33.cs2 b/dumps/scripts/33.cs2 new file mode 100644 index 0000000..66ee459 --- /dev/null +++ b/dumps/scripts/33.cs2 @@ -0,0 +1,12 @@ +void script_33(int arg0,int arg1) { + int ivar2; + ivar2 = add(cs2method2601(new WidgetPointer(arg1)), 4); + switch (arg1) { + case 38666248: + ivar2 = script_4754(arg1, ivar2, 0); + } + if (setWidgetRegister(new WidgetPointer(arg0), 1)) { + script_37(arg0, arg1, ivar2, 1); + } + return; +} diff --git a/dumps/scripts/330.cs2 b/dumps/scripts/330.cs2 new file mode 100644 index 0000000..1fc3b91 --- /dev/null +++ b/dumps/scripts/330.cs2 @@ -0,0 +1,12 @@ +void script_330(int arg0) { + int ivar1; + ivar1 = 0; + if (IsFemale()) { + ivar1 = getCommonDefinitionSize(2363); + } else { + ivar1 = getCommonDefinitionSize(2132); + } + script_332(globalint_784); + script_2366(arg0, globalint_784, ivar1); + return; +} diff --git a/dumps/scripts/3300.cs2 b/dumps/scripts/3300.cs2 new file mode 100644 index 0000000..ac5691c --- /dev/null +++ b/dumps/scripts/3300.cs2 @@ -0,0 +1,4 @@ +void script_3300() { + setWidgetText(new WidgetPointer(949,72), globalstring_284); + return; +} diff --git a/dumps/scripts/3301.cs2 b/dumps/scripts/3301.cs2 new file mode 100644 index 0000000..2d7f197 --- /dev/null +++ b/dumps/scripts/3301.cs2 @@ -0,0 +1,4 @@ +void script_3301() { + setWidgetText(new WidgetPointer(949,78), globalstring_285); + return; +} diff --git a/dumps/scripts/3302.cs2 b/dumps/scripts/3302.cs2 new file mode 100644 index 0000000..e81174f --- /dev/null +++ b/dumps/scripts/3302.cs2 @@ -0,0 +1,4 @@ +void script_3302() { + setWidgetText(new WidgetPointer(949,84), globalstring_286); + return; +} diff --git a/dumps/scripts/3303.cs2 b/dumps/scripts/3303.cs2 new file mode 100644 index 0000000..2225342 --- /dev/null +++ b/dumps/scripts/3303.cs2 @@ -0,0 +1,4 @@ +void script_3303() { + setWidgetText(new WidgetPointer(949,90), globalstring_287); + return; +} diff --git a/dumps/scripts/3304.cs2 b/dumps/scripts/3304.cs2 new file mode 100644 index 0000000..5abd837 --- /dev/null +++ b/dumps/scripts/3304.cs2 @@ -0,0 +1,4 @@ +void script_3304() { + setWidgetText(new WidgetPointer(949,96), globalstring_288); + return; +} diff --git a/dumps/scripts/3305.cs2 b/dumps/scripts/3305.cs2 new file mode 100644 index 0000000..99a1333 --- /dev/null +++ b/dumps/scripts/3305.cs2 @@ -0,0 +1,4 @@ +void script_3305() { + setWidgetText(new WidgetPointer(949,73), intToStr(globalint_1153)); + return; +} diff --git a/dumps/scripts/3306.cs2 b/dumps/scripts/3306.cs2 new file mode 100644 index 0000000..c69b283 --- /dev/null +++ b/dumps/scripts/3306.cs2 @@ -0,0 +1,4 @@ +void script_3306() { + setWidgetText(new WidgetPointer(949,79), intToStr(globalint_1154)); + return; +} diff --git a/dumps/scripts/3307.cs2 b/dumps/scripts/3307.cs2 new file mode 100644 index 0000000..b32be8f --- /dev/null +++ b/dumps/scripts/3307.cs2 @@ -0,0 +1,4 @@ +void script_3307() { + setWidgetText(new WidgetPointer(949,85), intToStr(globalint_1155)); + return; +} diff --git a/dumps/scripts/3308.cs2 b/dumps/scripts/3308.cs2 new file mode 100644 index 0000000..3b9169a --- /dev/null +++ b/dumps/scripts/3308.cs2 @@ -0,0 +1,4 @@ +void script_3308() { + setWidgetText(new WidgetPointer(949,91), intToStr(globalint_1156)); + return; +} diff --git a/dumps/scripts/3309.cs2 b/dumps/scripts/3309.cs2 new file mode 100644 index 0000000..273c539 --- /dev/null +++ b/dumps/scripts/3309.cs2 @@ -0,0 +1,4 @@ +void script_3309() { + setWidgetText(new WidgetPointer(949,97), intToStr(globalint_1157)); + return; +} diff --git a/dumps/scripts/331.cs2 b/dumps/scripts/331.cs2 new file mode 100644 index 0000000..61cd910 --- /dev/null +++ b/dumps/scripts/331.cs2 @@ -0,0 +1,12 @@ +void script_331(int arg0,int arg1) { + int ivar2; + ivar2 = 0; + if (IsFemale()) { + ivar2 = getCommonDefinitionSize(2363); + } else { + ivar2 = getCommonDefinitionSize(2132); + } + script_332(arg1); + script_2366(arg0, arg1, ivar2); + return; +} diff --git a/dumps/scripts/3310.cs2 b/dumps/scripts/3310.cs2 new file mode 100644 index 0000000..5217735 --- /dev/null +++ b/dumps/scripts/3310.cs2 @@ -0,0 +1,4 @@ +void script_3310() { + setWidgetText(new WidgetPointer(949,75), intToStr(globalint_1163)); + return; +} diff --git a/dumps/scripts/3311.cs2 b/dumps/scripts/3311.cs2 new file mode 100644 index 0000000..fe22fc3 --- /dev/null +++ b/dumps/scripts/3311.cs2 @@ -0,0 +1,4 @@ +void script_3311() { + setWidgetText(new WidgetPointer(949,81), intToStr(globalint_1164)); + return; +} diff --git a/dumps/scripts/3312.cs2 b/dumps/scripts/3312.cs2 new file mode 100644 index 0000000..252fc42 --- /dev/null +++ b/dumps/scripts/3312.cs2 @@ -0,0 +1,4 @@ +void script_3312() { + setWidgetText(new WidgetPointer(949,87), intToStr(globalint_1165)); + return; +} diff --git a/dumps/scripts/3313.cs2 b/dumps/scripts/3313.cs2 new file mode 100644 index 0000000..5bcaf43 --- /dev/null +++ b/dumps/scripts/3313.cs2 @@ -0,0 +1,4 @@ +void script_3313() { + setWidgetText(new WidgetPointer(949,93), intToStr(globalint_1166)); + return; +} diff --git a/dumps/scripts/3314.cs2 b/dumps/scripts/3314.cs2 new file mode 100644 index 0000000..14b7dce --- /dev/null +++ b/dumps/scripts/3314.cs2 @@ -0,0 +1,4 @@ +void script_3314() { + setWidgetText(new WidgetPointer(949,99), intToStr(globalint_1167)); + return; +} diff --git a/dumps/scripts/3315.cs2 b/dumps/scripts/3315.cs2 new file mode 100644 index 0000000..5e10881 --- /dev/null +++ b/dumps/scripts/3315.cs2 @@ -0,0 +1,4 @@ +void script_3315() { + setWidgetText(new WidgetPointer(949,76), intToStr(globalint_1168)); + return; +} diff --git a/dumps/scripts/3316.cs2 b/dumps/scripts/3316.cs2 new file mode 100644 index 0000000..6f3af22 --- /dev/null +++ b/dumps/scripts/3316.cs2 @@ -0,0 +1,4 @@ +void script_3316() { + setWidgetText(new WidgetPointer(949,82), intToStr(globalint_1169)); + return; +} diff --git a/dumps/scripts/3317.cs2 b/dumps/scripts/3317.cs2 new file mode 100644 index 0000000..ab113ab --- /dev/null +++ b/dumps/scripts/3317.cs2 @@ -0,0 +1,4 @@ +void script_3317() { + setWidgetText(new WidgetPointer(949,88), intToStr(globalint_1170)); + return; +} diff --git a/dumps/scripts/3318.cs2 b/dumps/scripts/3318.cs2 new file mode 100644 index 0000000..6587359 --- /dev/null +++ b/dumps/scripts/3318.cs2 @@ -0,0 +1,4 @@ +void script_3318() { + setWidgetText(new WidgetPointer(949,94), intToStr(globalint_1171)); + return; +} diff --git a/dumps/scripts/3319.cs2 b/dumps/scripts/3319.cs2 new file mode 100644 index 0000000..d320799 --- /dev/null +++ b/dumps/scripts/3319.cs2 @@ -0,0 +1,4 @@ +void script_3319() { + setWidgetText(new WidgetPointer(949,100), intToStr(globalint_1172)); + return; +} diff --git a/dumps/scripts/332.cs2 b/dumps/scripts/332.cs2 new file mode 100644 index 0000000..e0540ae --- /dev/null +++ b/dumps/scripts/332.cs2 @@ -0,0 +1,9 @@ +void script_332(int arg0) { + int ivar1; + ivar1 = 2359; + if (((boolean)globalint_783)) { + ivar1 = 2360; + } + setWidgetModel(cs2method_3408(105, 109, ivar1, arg0), new WidgetPointer(725,83)); + return; +} diff --git a/dumps/scripts/3320.cs2 b/dumps/scripts/3320.cs2 new file mode 100644 index 0000000..ef35759 --- /dev/null +++ b/dumps/scripts/3320.cs2 @@ -0,0 +1,4 @@ +void script_3320() { + setWidgetText(new WidgetPointer(949,74), intToStr(globalint_1158)); + return; +} diff --git a/dumps/scripts/3321.cs2 b/dumps/scripts/3321.cs2 new file mode 100644 index 0000000..b106072 --- /dev/null +++ b/dumps/scripts/3321.cs2 @@ -0,0 +1,4 @@ +void script_3321() { + setWidgetText(new WidgetPointer(949,80), intToStr(globalint_1159)); + return; +} diff --git a/dumps/scripts/3322.cs2 b/dumps/scripts/3322.cs2 new file mode 100644 index 0000000..86d0ed8 --- /dev/null +++ b/dumps/scripts/3322.cs2 @@ -0,0 +1,4 @@ +void script_3322() { + setWidgetText(new WidgetPointer(949,86), intToStr(globalint_1160)); + return; +} diff --git a/dumps/scripts/3323.cs2 b/dumps/scripts/3323.cs2 new file mode 100644 index 0000000..195e20a --- /dev/null +++ b/dumps/scripts/3323.cs2 @@ -0,0 +1,4 @@ +void script_3323() { + setWidgetText(new WidgetPointer(949,92), intToStr(globalint_1161)); + return; +} diff --git a/dumps/scripts/3324.cs2 b/dumps/scripts/3324.cs2 new file mode 100644 index 0000000..9ff7b05 --- /dev/null +++ b/dumps/scripts/3324.cs2 @@ -0,0 +1,4 @@ +void script_3324() { + setWidgetText(new WidgetPointer(949,98), intToStr(globalint_1162)); + return; +} diff --git a/dumps/scripts/3325.cs2 b/dumps/scripts/3325.cs2 new file mode 100644 index 0000000..52e055b --- /dev/null +++ b/dumps/scripts/3325.cs2 @@ -0,0 +1,4 @@ +void script_3325() { + setWidgetText(new WidgetPointer(949,108), intToStr(globalint_1173)); + return; +} diff --git a/dumps/scripts/3326.cs2 b/dumps/scripts/3326.cs2 new file mode 100644 index 0000000..09599b8 --- /dev/null +++ b/dumps/scripts/3326.cs2 @@ -0,0 +1,4 @@ +void script_3326() { + setWidgetText(new WidgetPointer(949,106), intToStr(globalint_1174)); + return; +} diff --git a/dumps/scripts/3327.cs2 b/dumps/scripts/3327.cs2 new file mode 100644 index 0000000..d390036 --- /dev/null +++ b/dumps/scripts/3327.cs2 @@ -0,0 +1,4 @@ +void script_3327() { + setWidgetText(new WidgetPointer(939,59), globalstring_292); + return; +} diff --git a/dumps/scripts/3328.cs2 b/dumps/scripts/3328.cs2 new file mode 100644 index 0000000..47a9f59 --- /dev/null +++ b/dumps/scripts/3328.cs2 @@ -0,0 +1,4 @@ +void script_3328() { + setWidgetText(new WidgetPointer(939,62), globalstring_293); + return; +} diff --git a/dumps/scripts/3329.cs2 b/dumps/scripts/3329.cs2 new file mode 100644 index 0000000..8e09a03 --- /dev/null +++ b/dumps/scripts/3329.cs2 @@ -0,0 +1,4 @@ +void script_3329() { + setWidgetText(new WidgetPointer(939,65), globalstring_294); + return; +} diff --git a/dumps/scripts/333.cs2 b/dumps/scripts/333.cs2 new file mode 100644 index 0000000..d97ba62 --- /dev/null +++ b/dumps/scripts/333.cs2 @@ -0,0 +1,52 @@ +void script_333(int arg0,int arg1,int arg2,int arg3,int arg4) { + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int stack_dump0; + cs2func_script_2413_struct(3,0,0) structdump_1; + cs2func_script_2413_struct(3,0,0) structdump_2; + ivar5 = 0; + ivar6 = 0; + ivar7 = 0; + stack_dump0 = arg1; + structdump_1 = script_2413(stack_dump0); + ivar7 = structdump_1.intpart_2; + ivar6 = structdump_1.intpart_1; + ivar5 = structdump_1.intpart_0; + ivar8 = 0; + ivar9 = 0; + ivar10 = 0; + stack_dump0 = arg2; + structdump_2 = script_2413(stack_dump0); + ivar10 = structdump_2.intpart_2; + ivar9 = structdump_2.intpart_1; + ivar8 = structdump_2.intpart_0; + ivar11 = subtract(ivar8, ivar5); + ivar12 = subtract(ivar9, ivar6); + ivar13 = subtract(ivar10, ivar7); + ivar14 = subtract(getWidgetActualHeight(new WidgetPointer(arg0)), arg4); + arg3 = multiply(arg3, 2); + ivar15 = arg4; + ivar16 = 0; + ivar17 = subtract(ivar14, ivar15); + while (ivar15 < ivar14) { + createExtraChild(new WidgetPointer(arg0), 3, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(arg3, 1, 1, 0); + setWidgetFilled(1); + setWidgetPosition(0, ivar15, 1, 0); + setWidgetRGB(new Color(script_693(add(ivar5, multiplyDivide(ivar16, ivar17, ivar11)), add(ivar6, multiplyDivide(ivar16, ivar17, ivar12)), add(ivar7, multiplyDivide(ivar16, ivar17, ivar13))))); + ivar16 = add(ivar16, 1); + ivar15 = add(ivar15, 1); + } + return; +} diff --git a/dumps/scripts/3330.cs2 b/dumps/scripts/3330.cs2 new file mode 100644 index 0000000..e28e088 --- /dev/null +++ b/dumps/scripts/3330.cs2 @@ -0,0 +1,4 @@ +void script_3330() { + setWidgetText(new WidgetPointer(939,68), globalstring_295); + return; +} diff --git a/dumps/scripts/3331.cs2 b/dumps/scripts/3331.cs2 new file mode 100644 index 0000000..8909f87 --- /dev/null +++ b/dumps/scripts/3331.cs2 @@ -0,0 +1,4 @@ +void script_3331() { + setWidgetText(new WidgetPointer(939,71), globalstring_296); + return; +} diff --git a/dumps/scripts/3332.cs2 b/dumps/scripts/3332.cs2 new file mode 100644 index 0000000..1ba67f3 --- /dev/null +++ b/dumps/scripts/3332.cs2 @@ -0,0 +1,4 @@ +void script_3332() { + setWidgetText(new WidgetPointer(939,106), intToStr(globalint_1180)); + return; +} diff --git a/dumps/scripts/3333.cs2 b/dumps/scripts/3333.cs2 new file mode 100644 index 0000000..4706037 --- /dev/null +++ b/dumps/scripts/3333.cs2 @@ -0,0 +1,4 @@ +void script_3333() { + setWidgetText(new WidgetPointer(939,100), intToStr(globalint_1183)); + return; +} diff --git a/dumps/scripts/3334.cs2 b/dumps/scripts/3334.cs2 new file mode 100644 index 0000000..67624b0 --- /dev/null +++ b/dumps/scripts/3334.cs2 @@ -0,0 +1,4 @@ +void script_3334() { + setWidgetText(new WidgetPointer(939,83), intToStr(globalint_1181)); + return; +} diff --git a/dumps/scripts/3335.cs2 b/dumps/scripts/3335.cs2 new file mode 100644 index 0000000..0c856c8 --- /dev/null +++ b/dumps/scripts/3335.cs2 @@ -0,0 +1,4 @@ +void script_3335() { + setWidgetText(new WidgetPointer(939,84), intToStr(globalint_1182)); + return; +} diff --git a/dumps/scripts/3336.cs2 b/dumps/scripts/3336.cs2 new file mode 100644 index 0000000..e454027 --- /dev/null +++ b/dumps/scripts/3336.cs2 @@ -0,0 +1,4 @@ +void script_3336() { + script_3337(); + return; +} diff --git a/dumps/scripts/3337.cs2 b/dumps/scripts/3337.cs2 new file mode 100644 index 0000000..c369856 --- /dev/null +++ b/dumps/scripts/3337.cs2 @@ -0,0 +1,28 @@ +void script_3337() { + globalint_1243 = getSkillXp(0); + globalint_1244 = getSkillXp(2); + globalint_1245 = getSkillXp(1); + globalint_1246 = getSkillXp(4); + globalint_1247 = getSkillXp(5); + globalint_1248 = getSkillXp(6); + globalint_1249 = getSkillXp(20); + globalint_1250 = getSkillXp(3); + globalint_1251 = getSkillXp(12); + globalint_1252 = getSkillXp(14); + globalint_1253 = getSkillXp(13); + globalint_1254 = getSkillXp(10); + globalint_1255 = getSkillXp(7); + globalint_1256 = getSkillXp(11); + globalint_1257 = getSkillXp(8); + globalint_1258 = getSkillXp(16); + globalint_1259 = getSkillXp(15); + globalint_1260 = getSkillXp(17); + globalint_1261 = getSkillXp(9); + globalint_1262 = getSkillXp(18); + globalint_1263 = getSkillXp(19); + globalint_1264 = getSkillXp(22); + globalint_1265 = getSkillXp(21); + globalint_1266 = getSkillXp(23); + globalint_1267 = getSkillXp(24); + return; +} diff --git a/dumps/scripts/3338.cs2 b/dumps/scripts/3338.cs2 new file mode 100644 index 0000000..c51581e --- /dev/null +++ b/dumps/scripts/3338.cs2 @@ -0,0 +1,4 @@ +void script_3338(int arg0,int arg1) { + setScriptCallOnGameloop(3499, 0, new WidgetPointer(arg0), new WidgetPointer(arg1), "iII", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/3339.cs2 b/dumps/scripts/3339.cs2 new file mode 100644 index 0000000..4339b4a --- /dev/null +++ b/dumps/scripts/3339.cs2 @@ -0,0 +1,33 @@ +void script_3339(int arg0) { + int ivar1; + int ivar2; + int ivar3; + ivar1 = -1; + ivar2 = -1; + ivar3 = -1; + if (((boolean)getLanguage())) { + if (((boolean)globalint_1175)) { + ivar1 = 3068; + ivar2 = 3067; + ivar3 = 3069; + } else { + ivar1 = 3071; + ivar2 = 3070; + ivar3 = 3072; + } + } else if (((boolean)globalint_1175)) { + ivar1 = 3014; + ivar2 = 3013; + ivar3 = 3015; + } else { + ivar1 = 3017; + ivar2 = 3016; + ivar3 = 3018; + } + setWidgetSprite(ivar2, new WidgetPointer(arg0)); + setScriptCallOnMouseEntered(44, new WidgetPointer(-32768,3), ivar1, "Id", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(44, new WidgetPointer(-32768,3), ivar2, "Id", new WidgetPointer(arg0)); + setScriptCallOnMousePressed(44, new WidgetPointer(-32768,3), ivar3, "Id", new WidgetPointer(arg0)); + script_41(61538418); + return; +} diff --git a/dumps/scripts/334.cs2 b/dumps/scripts/334.cs2 new file mode 100644 index 0000000..de671f1 --- /dev/null +++ b/dumps/scripts/334.cs2 @@ -0,0 +1,29 @@ +void script_334(int arg0) { + int ivar1; + ivar1 = 1777; + if (bitconfig_6090 == 2) { + setWidgetSprite(7435, new WidgetPointer(arg0)); + setScriptCallOnMouseEntered(5115, new WidgetPointer(-32768,3), 1, "Ii", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(5115, new WidgetPointer(-32768,3), 0, "Ii", new WidgetPointer(arg0)); + setWidgetContextMenuOption(1, new WidgetPointer(arg0), "Citadel Interface"); + } else if (((boolean)bitconfig_6090)) { + setWidgetSprite(3046, new WidgetPointer(arg0)); + ivar1 = 3047; + setScriptCallOnMouseEntered(44, new WidgetPointer(-32768,3), ivar1, "Id", new WidgetPointer(arg0)); + ivar1 = 3046; + setScriptCallOnMouseExit(44, new WidgetPointer(-32768,3), ivar1, "Id", new WidgetPointer(arg0)); + setWidgetNoOptions(new WidgetPointer(arg0)); + setWidgetContextMenuOption(1, new WidgetPointer(arg0), "Daemonheim Map"); + } else { + setWidgetSprite(1776, new WidgetPointer(arg0)); + setScriptCallOnMouseEntered(44, new WidgetPointer(-32768,3), ivar1, "Id", new WidgetPointer(arg0)); + ivar1 = 1776; + setScriptCallOnMouseExit(44, new WidgetPointer(-32768,3), ivar1, "Id", new WidgetPointer(arg0)); + setWidgetNoOptions(new WidgetPointer(arg0)); + setWidgetContextMenuOption(1, new WidgetPointer(arg0), "World Map"); + if ((standart_config_1159 != -1) && (standart_config_1159 != 0)) { + setWidgetContextMenuOption(2, new WidgetPointer(arg0), "Clear your marker"); + } + } + return; +} diff --git a/dumps/scripts/3340.cs2 b/dumps/scripts/3340.cs2 new file mode 100644 index 0000000..f1e11a9 --- /dev/null +++ b/dumps/scripts/3340.cs2 @@ -0,0 +1,33 @@ +void script_3340(int arg0) { + int ivar1; + int ivar2; + int ivar3; + ivar1 = -1; + ivar2 = -1; + ivar3 = -1; + if (((boolean)getLanguage())) { + if (((boolean)globalint_1176)) { + ivar1 = 3068; + ivar2 = 3067; + ivar3 = 3069; + } else { + ivar1 = 3071; + ivar2 = 3070; + ivar3 = 3072; + } + } else if (((boolean)globalint_1176)) { + ivar1 = 3014; + ivar2 = 3013; + ivar3 = 3015; + } else { + ivar1 = 3017; + ivar2 = 3016; + ivar3 = 3018; + } + setWidgetSprite(ivar2, new WidgetPointer(arg0)); + setScriptCallOnMouseEntered(44, new WidgetPointer(-32768,3), ivar1, "Id", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(44, new WidgetPointer(-32768,3), ivar2, "Id", new WidgetPointer(arg0)); + setScriptCallOnMousePressed(44, new WidgetPointer(-32768,3), ivar3, "Id", new WidgetPointer(arg0)); + script_41(61538418); + return; +} diff --git a/dumps/scripts/3341.cs2 b/dumps/scripts/3341.cs2 new file mode 100644 index 0000000..3af1dac --- /dev/null +++ b/dumps/scripts/3341.cs2 @@ -0,0 +1,33 @@ +void script_3341(int arg0) { + int ivar1; + int ivar2; + int ivar3; + ivar1 = -1; + ivar2 = -1; + ivar3 = -1; + if (((boolean)getLanguage())) { + if (((boolean)globalint_1177)) { + ivar1 = 3068; + ivar2 = 3067; + ivar3 = 3069; + } else { + ivar1 = 3071; + ivar2 = 3070; + ivar3 = 3072; + } + } else if (((boolean)globalint_1177)) { + ivar1 = 3014; + ivar2 = 3013; + ivar3 = 3015; + } else { + ivar1 = 3017; + ivar2 = 3016; + ivar3 = 3018; + } + setWidgetSprite(ivar2, new WidgetPointer(arg0)); + setScriptCallOnMouseEntered(44, new WidgetPointer(-32768,3), ivar1, "Id", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(44, new WidgetPointer(-32768,3), ivar2, "Id", new WidgetPointer(arg0)); + setScriptCallOnMousePressed(44, new WidgetPointer(-32768,3), ivar3, "Id", new WidgetPointer(arg0)); + script_41(61538418); + return; +} diff --git a/dumps/scripts/3342.cs2 b/dumps/scripts/3342.cs2 new file mode 100644 index 0000000..c255422 --- /dev/null +++ b/dumps/scripts/3342.cs2 @@ -0,0 +1,33 @@ +void script_3342(int arg0) { + int ivar1; + int ivar2; + int ivar3; + ivar1 = -1; + ivar2 = -1; + ivar3 = -1; + if (((boolean)getLanguage())) { + if (((boolean)globalint_1178)) { + ivar1 = 3068; + ivar2 = 3067; + ivar3 = 3069; + } else { + ivar1 = 3071; + ivar2 = 3070; + ivar3 = 3072; + } + } else if (((boolean)globalint_1178)) { + ivar1 = 3014; + ivar2 = 3013; + ivar3 = 3015; + } else { + ivar1 = 3017; + ivar2 = 3016; + ivar3 = 3018; + } + setWidgetSprite(ivar2, new WidgetPointer(arg0)); + setScriptCallOnMouseEntered(44, new WidgetPointer(-32768,3), ivar1, "Id", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(44, new WidgetPointer(-32768,3), ivar2, "Id", new WidgetPointer(arg0)); + setScriptCallOnMousePressed(44, new WidgetPointer(-32768,3), ivar3, "Id", new WidgetPointer(arg0)); + script_41(61538418); + return; +} diff --git a/dumps/scripts/3343.cs2 b/dumps/scripts/3343.cs2 new file mode 100644 index 0000000..26c5c7b --- /dev/null +++ b/dumps/scripts/3343.cs2 @@ -0,0 +1,33 @@ +void script_3343(int arg0) { + int ivar1; + int ivar2; + int ivar3; + ivar1 = -1; + ivar2 = -1; + ivar3 = -1; + if (((boolean)getLanguage())) { + if (((boolean)globalint_1179)) { + ivar1 = 3068; + ivar2 = 3067; + ivar3 = 3069; + } else { + ivar1 = 3071; + ivar2 = 3070; + ivar3 = 3072; + } + } else if (((boolean)globalint_1179)) { + ivar1 = 3014; + ivar2 = 3013; + ivar3 = 3015; + } else { + ivar1 = 3017; + ivar2 = 3016; + ivar3 = 3018; + } + setWidgetSprite(ivar2, new WidgetPointer(arg0)); + setScriptCallOnMouseEntered(44, new WidgetPointer(-32768,3), ivar1, "Id", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(44, new WidgetPointer(-32768,3), ivar2, "Id", new WidgetPointer(arg0)); + setScriptCallOnMousePressed(44, new WidgetPointer(-32768,3), ivar3, "Id", new WidgetPointer(arg0)); + script_41(61538418); + return; +} diff --git a/dumps/scripts/3344.cs2 b/dumps/scripts/3344.cs2 new file mode 100644 index 0000000..f5b2ada --- /dev/null +++ b/dumps/scripts/3344.cs2 @@ -0,0 +1,4 @@ +void script_3344() { + script_3345(); + return; +} diff --git a/dumps/scripts/3345.cs2 b/dumps/scripts/3345.cs2 new file mode 100644 index 0000000..cd43275 --- /dev/null +++ b/dumps/scripts/3345.cs2 @@ -0,0 +1,8 @@ +void script_3345() { + if (((boolean)globalint_1175)) { + script_1163(61538364, -1, 61538418, 25, 200, "P1: Shared XP is ON"); + } else { + script_1163(61538364, -1, 61538418, 25, 200, "P1: Shared XP is OFF"); + } + return; +} diff --git a/dumps/scripts/3346.cs2 b/dumps/scripts/3346.cs2 new file mode 100644 index 0000000..bff2de3 --- /dev/null +++ b/dumps/scripts/3346.cs2 @@ -0,0 +1,4 @@ +void script_3346() { + script_3347(); + return; +} diff --git a/dumps/scripts/3347.cs2 b/dumps/scripts/3347.cs2 new file mode 100644 index 0000000..725a2f3 --- /dev/null +++ b/dumps/scripts/3347.cs2 @@ -0,0 +1,8 @@ +void script_3347() { + if (((boolean)globalint_1176)) { + script_1163(61538367, -1, 61538418, 25, 200, "P2: Shared XP is ON"); + } else { + script_1163(61538367, -1, 61538418, 25, 200, "P2: Shared XP is OFF"); + } + return; +} diff --git a/dumps/scripts/3348.cs2 b/dumps/scripts/3348.cs2 new file mode 100644 index 0000000..44bae40 --- /dev/null +++ b/dumps/scripts/3348.cs2 @@ -0,0 +1,4 @@ +void script_3348() { + script_3349(); + return; +} diff --git a/dumps/scripts/3349.cs2 b/dumps/scripts/3349.cs2 new file mode 100644 index 0000000..911d0a4 --- /dev/null +++ b/dumps/scripts/3349.cs2 @@ -0,0 +1,8 @@ +void script_3349() { + if (((boolean)globalint_1177)) { + script_1163(61538370, -1, 61538418, 25, 200, "P3: Shared XP is ON"); + } else { + script_1163(61538370, -1, 61538418, 25, 200, "P3: Shared XP is OFF"); + } + return; +} diff --git a/dumps/scripts/335.cs2 b/dumps/scripts/335.cs2 new file mode 100644 index 0000000..6ce40d7 --- /dev/null +++ b/dumps/scripts/335.cs2 @@ -0,0 +1,9 @@ +cs2func_script_335_struct(2,0,0) script_335(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + int ivar6; + ivar4 = script_338(arg3); + ivar5 = divide(multiply(arg2, 1000), ivar4); + ivar6 = subtract(arg2, ivar5); + return newstruct cs2func_script_335_struct(add(arg0, ivar5), add(arg1, ivar6)); +} diff --git a/dumps/scripts/3350.cs2 b/dumps/scripts/3350.cs2 new file mode 100644 index 0000000..fd06c8d --- /dev/null +++ b/dumps/scripts/3350.cs2 @@ -0,0 +1,4 @@ +void script_3350() { + script_3351(); + return; +} diff --git a/dumps/scripts/3351.cs2 b/dumps/scripts/3351.cs2 new file mode 100644 index 0000000..40f9e40 --- /dev/null +++ b/dumps/scripts/3351.cs2 @@ -0,0 +1,8 @@ +void script_3351() { + if (((boolean)globalint_1178)) { + script_1163(61538373, -1, 61538418, 25, 200, "P4: Shared XP is ON"); + } else { + script_1163(61538373, -1, 61538418, 25, 200, "P4: Shared XP is OFF"); + } + return; +} diff --git a/dumps/scripts/3352.cs2 b/dumps/scripts/3352.cs2 new file mode 100644 index 0000000..f7d128c --- /dev/null +++ b/dumps/scripts/3352.cs2 @@ -0,0 +1,4 @@ +void script_3352() { + script_3353(); + return; +} diff --git a/dumps/scripts/3353.cs2 b/dumps/scripts/3353.cs2 new file mode 100644 index 0000000..05e7719 --- /dev/null +++ b/dumps/scripts/3353.cs2 @@ -0,0 +1,8 @@ +void script_3353() { + if (((boolean)globalint_1179)) { + script_1163(61538376, -1, 61538418, 25, 200, "P5: Shared XP is ON"); + } else { + script_1163(61538376, -1, 61538418, 25, 200, "P5: Shared XP is OFF"); + } + return; +} diff --git a/dumps/scripts/3354.cs2 b/dumps/scripts/3354.cs2 new file mode 100644 index 0000000..a39356e --- /dev/null +++ b/dumps/scripts/3354.cs2 @@ -0,0 +1,17 @@ +cs2func_script_3354_struct(1,1,0) script_3354(int arg0) { + switch (arg0) { + case 0: + return newstruct cs2func_script_3354_struct(0, "Bosses"); + case 1: + return newstruct cs2func_script_3354_struct(0, "Floors"); + case 2: + return newstruct cs2func_script_3354_struct(0, "Item Binding"); + case 3: + return newstruct cs2func_script_3354_struct(0, "Rewards"); + case 4: + return newstruct cs2func_script_3354_struct(0, "Areas"); + case 5: + return newstruct cs2func_script_3354_struct(0, "Milestones"); + } + return newstruct cs2func_script_3354_struct(-1, ""); +} diff --git a/dumps/scripts/3355.cs2 b/dumps/scripts/3355.cs2 new file mode 100644 index 0000000..139862c --- /dev/null +++ b/dumps/scripts/3355.cs2 @@ -0,0 +1,338 @@ +cs2func_script_3355_struct(2,2,0) script_3355(int arg0,int arg1) { + switch (arg0) { + flow_1: + case 0: + switch (arg1) { + case 0: + return newstruct cs2func_script_3355_struct(1, 18619, "Gluttonous behemoth", "You can now fight " + "" + "gluttonous behemoths" + "" + " in Daemonheim."); + case 1: + return newstruct cs2func_script_3355_struct(1, 18617, "Astea Frostweb", "You can now fight " + "" + "Astea Frostweb" + "" + " in Daemonheim."); + case 2: + return newstruct cs2func_script_3355_struct(1, 18625, "Icy Bones", "You can now fight " + "" + "Icy Bones" + "" + " in Daemonheim."); + case 3: + return newstruct cs2func_script_3355_struct(5, 18628, "Luminescent icefiend", "You can now fight " + "" + "luminescent icefiends" + "" + " in Daemonheim."); + case 4: + return newstruct cs2func_script_3355_struct(11, 18621, "Plane-freezer Lakhrahnaz", "You can now fight " + "" + "Plane-freezer Lakhrahnaz" + "" + " in Daemonheim."); + case 5: + return newstruct cs2func_script_3355_struct(17, 18623, "To'Kash the Bloodchiller", "You can now fight " + "" + "To'Kash the Bloodchiller" + "" + " in Daemonheim."); + case 6: + return newstruct cs2func_script_3355_struct(23, 18618, "Skeletal Horde", "You can now fight " + "" + "skeletal hordes" + "" + " in Daemonheim."); + case 7: + return newstruct cs2func_script_3355_struct(23, 18624, "Hobgoblin Geomancer", "You can now fight the " + "" + "Geomancer Shaman" + "" + " in Daemonheim."); + case 8: + return newstruct cs2func_script_3355_struct(23, 19699, "Bulwark beast", "You can now fight " + "" + "bulwark beasts" + "" + " in Daemonheim."); + case 9: + return newstruct cs2func_script_3355_struct(29, 18632, "Unholy cursebearer", "You can now fight " + "" + "unholy cursebearers" + "" + " in Daemonheim."); + case 10: + return newstruct cs2func_script_3355_struct(35, 18622, "Rammernaut", "You can now fight " + "" + "rammernauts" + "" + " in Daemonheim."); + case 11: + return newstruct cs2func_script_3355_struct(35, 18633, "Stomp", "You can now fight " + "" + "stomps" + "" + " in Daemonheim."); + case 12: + return newstruct cs2func_script_3355_struct(35, 19697, "Har'Lakk the Riftsplitter", "You can now fight " + "" + "Har'Lakk the Riftsplitter" + "" + " in Daemonheim."); + case 13: + return newstruct cs2func_script_3355_struct(39, 18627, "Lexicus Runewright", "You can now fight " + "" + "Lexicus Runewright" + "" + " in Daemonheim."); + case 14: + return newstruct cs2func_script_3355_struct(45, 18630, "Sagittare", "You can now fight " + "" + "sagittares" + "" + " in Daemonheim."); + case 15: + return newstruct cs2func_script_3355_struct(51, 18631, "Night-gazer Khighorahk", "You can now fight " + "" + "Night-gazer Khighorahk" + "" + " in Daemonheim."); + case 16: + return newstruct cs2func_script_3355_struct(59, 18626, "Shadow-forger Ihlakhizan", "You can now fight " + "" + "Shadow-forger Ihlakhizan" + "" + " in Daemonheim."); + case 17: + return newstruct cs2func_script_3355_struct(65, 19696, "Bal'Lak the Pummeller", "You can now fight " + "" + "Bal'Lak the Pummeller" + "" + " in Daemonheim."); + case 18: + return newstruct cs2func_script_3355_struct(71, 19694, "Members: Skeletal trio", "Members can now fight the " + "" + "skeletal trio" + "" + " in Daemonheim."); + case 19: + return newstruct cs2func_script_3355_struct(71, 19695, "Members: Runebound behemoth", "Members can now fight " + "" + "runebound behemoths" + "" + " in Daemonheim."); + case 20: + return newstruct cs2func_script_3355_struct(71, 19692, "Members: Gravecreeper", "Members can now fight " + "" + "Grave Creeper" + "" + " in Daemonheim."); + case 21: + return newstruct cs2func_script_3355_struct(77, 19691, "Members: Necrolord", "Members can now fight " + "" + "necrolords" + "" + " in Daemonheim."); + case 22: + return newstruct cs2func_script_3355_struct(83, 19693, "Members: Flesh-spoiler Haasghenahk", "Members can now fight " + "" + "Flesh-spoiler Haasghenahk" + "" + " in Daemonheim."); + case 23: + return newstruct cs2func_script_3355_struct(89, 19698, "Members: Yk'Lagor the Thunderous", "Members can now fight " + "" + "Yk'Lagor the Thunderous" + "" + " in Daemonheim."); + case 24: + return newstruct cs2func_script_3355_struct(95, 19885, "Members: Blink", "Members can now fight " + "" + "Blink" + "" + " in Daemonheim."); + case 25: + return newstruct cs2func_script_3355_struct(95, 19883, "Members: Warped gulega", "Members can now fight " + "" + "warped gulega" + "" + " in Daemonheim."); + case 26: + return newstruct cs2func_script_3355_struct(95, 19884, "Members: Dreadnaut", "Members can now fight " + "" + "dreadnauts" + "" + " in Daemonheim."); + case 27: + return newstruct cs2func_script_3355_struct(101, 19882, "Members: Hope devourer", "Members can now fight " + "" + "hope devourers" + "" + " in Daemonheim."); + case 28: + return newstruct cs2func_script_3355_struct(107, 19881, "Members: World-gorger Shukarhazh", "Members can now fight " + "" + "World-gorger Shukarhazh" + "" + " in Daemonheim."); + case 29: + return newstruct cs2func_script_3355_struct(113, 19880, "Members: Kal'Ger the Warmonger", "Members can now fight " + "" + "Kal'Ger the Warmonger" + "" + " in Daemonheim."); + } + break; + case 1: + switch (arg1) { + case 0: + return newstruct cs2func_script_3355_struct(1, 18579, "Floor 1", "You can now access floor " + "" + "1" + "" + " of Daemonheim."); + case 1: + return newstruct cs2func_script_3355_struct(3, 18579, "Floor 2", "You can now access floor " + "" + "2" + "" + " of Daemonheim (once the previous floors are complete)."); + case 2: + return newstruct cs2func_script_3355_struct(5, 18579, "Floor 3", "You can now access floor " + "" + "3" + "" + " of Daemonheim (once the previous floors are complete)."); + case 3: + return newstruct cs2func_script_3355_struct(7, 18579, "Floor 4", "You can now access floor " + "" + "4" + "" + " of Daemonheim (once the previous floors are complete)."); + case 4: + return newstruct cs2func_script_3355_struct(9, 18579, "Floor 5", "You can now access floor " + "" + "5" + "" + " of Daemonheim (once the previous floors are complete)."); + case 5: + return newstruct cs2func_script_3355_struct(11, 18579, "Floor 6", "You can now access floor " + "" + "6" + "" + " of Daemonheim (once the previous floors are complete)."); + case 6: + return newstruct cs2func_script_3355_struct(13, 18579, "Floor 7", "You can now access floor " + "" + "7" + "" + " of Daemonheim (once the previous floors are complete)."); + case 7: + return newstruct cs2func_script_3355_struct(15, 18579, "Floor 8", "You can now access floor " + "" + "8" + "" + " of Daemonheim (once the previous floors are complete)."); + case 8: + return newstruct cs2func_script_3355_struct(17, 18579, "Floor 9", "You can now access floor " + "" + "9" + "" + " of Daemonheim (once the previous floors are complete)."); + case 9: + return newstruct cs2func_script_3355_struct(19, 18579, "Floor 10", "You can now access floor " + "" + "10" + "" + " of Daemonheim (once the previous floors are complete)."); + case 10: + return newstruct cs2func_script_3355_struct(21, 18579, "Floor 11", "You can now access floor " + "" + "11" + "" + " of Daemonheim (once the previous floors are complete)."); + case 11: + return newstruct cs2func_script_3355_struct(23, 18578, "Floor 12", "You can now access floor " + "" + "12" + "" + " of Daemonheim (once the previous floors are complete)."); + case 12: + return newstruct cs2func_script_3355_struct(25, 18578, "Floor 13", "You can now access floor " + "" + "13" + "" + " of Daemonheim (once the previous floors are complete)."); + case 13: + return newstruct cs2func_script_3355_struct(27, 18578, "Floor 14", "You can now access floor " + "" + "14" + "" + " of Daemonheim (once the previous floors are complete)."); + case 14: + return newstruct cs2func_script_3355_struct(29, 18578, "Floor 15", "You can now access floor " + "" + "15" + "" + " of Daemonheim (once the previous floors are complete)."); + case 15: + return newstruct cs2func_script_3355_struct(31, 18578, "Floor 16", "You can now access floor " + "" + "16" + "" + " of Daemonheim (once the previous floors are complete)."); + case 16: + return newstruct cs2func_script_3355_struct(33, 18578, "Floor 17", "You can now access floor " + "" + "17" + "" + " of Daemonheim (once the previous floors are complete)."); + case 17: + return newstruct cs2func_script_3355_struct(35, 18577, "Floor 18", "You can now access floor " + "" + "18" + "" + " of Daemonheim (once the previous floors are complete)."); + case 18: + return newstruct cs2func_script_3355_struct(37, 18577, "Floor 19", "You can now access floor " + "" + "19" + "" + " of Daemonheim (once the previous floors are complete)."); + case 19: + return newstruct cs2func_script_3355_struct(39, 18577, "Floor 20", "You can now access floor " + "" + "20" + "" + " of Daemonheim (once the previous floors are complete)."); + case 20: + return newstruct cs2func_script_3355_struct(41, 18577, "Floor 21", "You can now access floor " + "" + "21" + "" + " of Daemonheim (once the previous floors are complete)."); + case 21: + return newstruct cs2func_script_3355_struct(43, 18577, "Floor 22", "You can now access floor " + "" + "22" + "" + " of Daemonheim (once the previous floors are complete)."); + case 22: + return newstruct cs2func_script_3355_struct(45, 18577, "Floor 23", "You can now access floor " + "" + "23" + "" + " of Daemonheim (once the previous floors are complete)."); + case 23: + return newstruct cs2func_script_3355_struct(47, 18577, "Floor 24", "You can now access floor " + "" + "24" + "" + " of Daemonheim (once the previous floors are complete)."); + case 24: + return newstruct cs2func_script_3355_struct(49, 18577, "Floor 25", "You can now access floor " + "" + "25" + "" + " of Daemonheim (once the previous floors are complete)."); + case 25: + return newstruct cs2func_script_3355_struct(51, 18577, "Floor 26", "You can now access floor " + "" + "26" + "" + " of Daemonheim (once the previous floors are complete)."); + case 26: + return newstruct cs2func_script_3355_struct(53, 18577, "Floor 27", "You can now access floor " + "" + "27" + "" + " of Daemonheim (once the previous floors are complete)."); + case 27: + return newstruct cs2func_script_3355_struct(55, 18577, "Floor 28", "You can now access floor " + "" + "28" + "" + " of Daemonheim (once the previous floors are complete)."); + case 28: + return newstruct cs2func_script_3355_struct(57, 18577, "Floor 29", "You can now access floor " + "" + "29" + "" + " of Daemonheim (once the previous floors are complete)."); + case 29: + return newstruct cs2func_script_3355_struct(59, 18578, "Floor 30", "You can now access floor " + "" + "30" + "" + " of Daemonheim (once the previous floors are complete)."); + case 30: + return newstruct cs2func_script_3355_struct(61, 18578, "Floor 31", "You can now access floor " + "" + "31" + "" + " of Daemonheim (once the previous floors are complete)."); + case 31: + return newstruct cs2func_script_3355_struct(63, 18578, "Floor 32", "You can now access floor " + "" + "32" + "" + " of Daemonheim (once the previous floors are complete)."); + case 32: + return newstruct cs2func_script_3355_struct(65, 18578, "Floor 33", "You can now access floor " + "" + "33" + "" + " of Daemonheim (once the previous floors are complete)."); + case 33: + return newstruct cs2func_script_3355_struct(67, 18578, "Floor 34", "You can now access floor " + "" + "34" + "" + " of Daemonheim (once the previous floors are complete)."); + case 34: + return newstruct cs2func_script_3355_struct(69, 18578, "Floor 35", "You can now access floor " + "" + "35" + "" + " of Daemonheim (once the previous floors are complete)."); + case 35: + return newstruct cs2func_script_3355_struct(71, 19690, "Members: Floor 36", "Members can now access floor " + "" + "36" + "" + " of Daemonheim (once the previous floors are complete)."); + case 36: + return newstruct cs2func_script_3355_struct(73, 19690, "Members: Floor 37", "Members can now access floor " + "" + "37" + "" + " of Daemonheim (once the previous floors are complete)."); + case 37: + return newstruct cs2func_script_3355_struct(75, 19690, "Members: Floor 38", "Members can now access floor " + "" + "38" + "" + " of Daemonheim (once the previous floors are complete)."); + case 38: + return newstruct cs2func_script_3355_struct(77, 19690, "Members: Floor 39", "Members can now access floor " + "" + "39" + "" + " of Daemonheim (once the previous floors are complete)."); + case 39: + return newstruct cs2func_script_3355_struct(79, 19690, "Members: Floor 40", "Members can now access floor " + "" + "40" + "" + " of Daemonheim (once the previous floors are complete)."); + case 40: + return newstruct cs2func_script_3355_struct(81, 19690, "Members: Floor 41", "Members can now access floor " + "" + "41" + "" + " of Daemonheim (once the previous floors are complete)."); + case 41: + return newstruct cs2func_script_3355_struct(83, 19690, "Members: Floor 42", "Members can now access floor " + "" + "42" + "" + " of Daemonheim (once the previous floors are complete)."); + case 42: + return newstruct cs2func_script_3355_struct(85, 19690, "Members: Floor 43", "Members can now access floor " + "" + "43" + "" + " of Daemonheim (once the previous floors are complete)."); + case 43: + return newstruct cs2func_script_3355_struct(87, 19690, "Members: Floor 44", "Members can now access floor " + "" + "44" + "" + " of Daemonheim (once the previous floors are complete)."); + case 44: + return newstruct cs2func_script_3355_struct(89, 19690, "Members: Floor 45", "Members can now access floor " + "" + "45" + "" + " of Daemonheim (once the previous floors are complete)."); + case 45: + return newstruct cs2func_script_3355_struct(91, 19690, "Members: Floor 46", "Members can now access floor " + "" + "46" + "" + " of Daemonheim (once the previous floors are complete)."); + case 46: + return newstruct cs2func_script_3355_struct(93, 19690, "Members: Floor 47", "Members can now access floor " + "" + "47" + "" + " of Daemonheim (once the previous floors are complete)."); + case 47: + return newstruct cs2func_script_3355_struct(95, 19896, "Members: Floor 48", "Members can now access floor " + "" + "48" + "" + " of Daemonheim (once the previous floors are complete)."); + case 48: + return newstruct cs2func_script_3355_struct(97, 19896, "Members: Floor 49", "Members can now access floor " + "" + "49" + "" + " of Daemonheim (once the previous floors are complete)."); + case 49: + return newstruct cs2func_script_3355_struct(99, 19896, "Members: Floor 50", "Members can now access floor " + "" + "50" + "" + " of Daemonheim (once the previous floors are complete)."); + case 50: + return newstruct cs2func_script_3355_struct(101, 19896, "Members: Floor 51", "Members can now access floor " + "" + "51" + "" + " of Daemonheim (once the previous floors are complete)."); + case 51: + return newstruct cs2func_script_3355_struct(103, 19896, "Members: Floor 52", "Members can now access floor " + "" + "52" + "" + " of Daemonheim (once the previous floors are complete)."); + case 52: + return newstruct cs2func_script_3355_struct(105, 19896, "Members: Floor 53", "Members can now access floor " + "" + "53" + "" + " of Daemonheim (once the previous floors are complete)."); + case 53: + return newstruct cs2func_script_3355_struct(107, 19896, "Members: Floor 54", "Members can now access floor " + "" + "54" + "" + " of Daemonheim (once the previous floors are complete)."); + case 54: + return newstruct cs2func_script_3355_struct(109, 19896, "Members: Floor 55", "Members can now access floor " + "" + "55" + "" + " of Daemonheim (once the previous floors are complete)."); + case 55: + return newstruct cs2func_script_3355_struct(111, 19896, "Members: Floor 56", "Members can now access floor " + "" + "56" + "" + " of Daemonheim (once the previous floors are complete)."); + case 56: + return newstruct cs2func_script_3355_struct(113, 19896, "Members: Floor 57", "Members can now access floor " + "" + "57" + "" + " of Daemonheim (once the previous floors are complete)."); + case 57: + return newstruct cs2func_script_3355_struct(115, 19896, "Members: Floor 58", "Members can now access floor " + "" + "58" + "" + " of Daemonheim (once the previous floors are complete)."); + case 58: + return newstruct cs2func_script_3355_struct(117, 19896, "Members: Floor 59", "Members can now access floor " + "" + "59" + "" + " of Daemonheim (once the previous floors are complete)."); + case 59: + return newstruct cs2func_script_3355_struct(119, 19896, "Members: Floor 60", "Members can now access floor " + "" + "60" + "" + " of Daemonheim (once the previous floors are complete)."); + } + break; + case 2: + switch (arg1) { + case 0: + return newstruct cs2func_script_3355_struct(1, 16405, "Bind one item", "You can now bind " + "" + "one item" + "" + " within Daemonheim."); + case 1: + return newstruct cs2func_script_3355_struct(1, 16405, "Bind rune or ammo item", "You can now bind " + "" + "up to 125 of one type of rune or ammunition" + "" + " within Daemonheim."); + case 2: + return newstruct cs2func_script_3355_struct(50, 16415, "Bind two items", "You can now bind " + "" + "two items" + "" + " within Daemonheim."); + case 3: + return newstruct cs2func_script_3355_struct(100, 16423, "Bind three items", "You can now bind " + "" + "three items" + "" + " within Daemonheim."); + case 4: + return newstruct cs2func_script_3355_struct(120, 16425, "Bind four items", "You can now bind " + "" + "four items" + "" + " within Daemonheim."); + } + break; + case 3: + switch (arg1) { + case 0: + return newstruct cs2func_script_3355_struct(21, 18337, "Members: Bonecrusher" + "
" + " (with 21 Prayer)", "Members can now use " + "" + "bonecrushers" + "" + ". (They also need level 21 Prayer.)"); + case 1: + return newstruct cs2func_script_3355_struct(21, 19675, "Members: Herbicide" + "
" + " (with 21 Herblore)", "Members can now use " + "" + "herbicide" + "" + ". (They also need level 21 Herblore.)"); + case 2: + return newstruct cs2func_script_3355_struct(25, 18338, "Gem bag" + "
" + " (with 25 Crafting)", "You can now use " + "" + "gem bags" + "" + ". (You also need level 25 Crafting.)"); + case 3: + return newstruct cs2func_script_3355_struct(25, 18336, "Members: Scroll of life" + "
" + " (with 25 Farming)", "Members can now use the " + "" + "scroll of life" + "" + ". (They also need level 25 Farming.)"); + case 4: + return newstruct cs2func_script_3355_struct(30, 18333, "Arcane pulse necklace" + "
" + " (with 30 Magic)", "You can now wear " + "" + "arcane pulse necklaces" + "" + ". (You also need level 30 Magic.)"); + case 5: + return newstruct cs2func_script_3355_struct(30, 19671, "Magical blastbox" + "
" + " (with 30 Magic and 30 Runecrafting)", "You can now use " + "" + "magical blastboxes" + "" + ". (You also need level 30 Magic and 30 Runecrafting.)"); + case 6: + return newstruct cs2func_script_3355_struct(30, 19886, "Twisted bird skull necklace" + "
" + " (with 30 Prayer)", "You can now wear " + "" + "twisted bird skull necklaces" + "" + ". (You also need level 30 Prayer.)"); + case 7: + return newstruct cs2func_script_3355_struct(35, 18339, "Coal bag" + "
" + " (with 35 Mining)", "You can now use " + "" + "coal bags" + "" + ". (You also need level 35 Mining.)"); + case 8: + return newstruct cs2func_script_3355_struct(45, 18330, "Longbow sight" + "
" + " (with 45 Ranged)", "You can now use " + "" + "longbow sights" + "" + ". (You also need level 45 Ranged.)"); + case 9: + return newstruct cs2func_script_3355_struct(45, 18367, "Gravite longsword" + "
" + " (with 45 Attack)", "You can now wield " + "" + "gravite longswords" + "" + ". (You also need level 45 Attack.)"); + case 10: + return newstruct cs2func_script_3355_struct(45, 18365, "Gravite rapier" + "
" + " (with 45 Attack)", "You can now wield " + "" + "gravite rapiers" + "" + ". (You also need level 45 Attack.)"); + case 11: + return newstruct cs2func_script_3355_struct(45, 18373, "Gravite shortbow" + "
" + " Ammo: Arrows up to rune" + "
" + " (with 45 Ranged)", "You can now wield " + "" + "gravite shortbows" + "" + ". (You also need level 45 Ranged.)"); + case 12: + return newstruct cs2func_script_3355_struct(45, 18371, "Gravite staff" + "
" + " (with 45 Magic)", "You can now wield " + "" + "gravite staves" + "" + ". (You also need level 45 Magic.)"); + case 13: + return newstruct cs2func_script_3355_struct(45, 18369, "Gravite two-handed sword" + "
" + " (with 45 Attack)", "You can now wield " + "" + "gravite two-handed swords" + "" + ". (You also need level 45 Attack.)"); + case 14: + return newstruct cs2func_script_3355_struct(45, 18342, "Law staff" + "
" + " (with 40 Attack and 45 Magic)", "You can now use " + "" + "law staves" + "" + ". (You also need level 40 Attack and level 45 Magic.)"); + case 15: + return newstruct cs2func_script_3355_struct(48, 18346, "Tome of frost" + "
" + " (with 48 Magic)", "You can now use " + "" + "tomes of frost" + "" + ". (You also need level 48 Magic.)"); + case 16: + return newstruct cs2func_script_3355_struct(48, 19892, "Amulet of zealots" + "
" + " (with 48 Prayer)", "You now have the Dungeoneering level required to wear " + "" + "Amulets of hopelessness" + "" + ". (You also need level 48 Prayer.)"); + case 17: + return newstruct cs2func_script_3355_struct(49, 19890, "Members: Wasteless Herblore" + "
" + " (with 49 Herblore)", "Members can now learn the " + "" + "wasteless herblore" + "" + " ability (you also need 49 Herblore.)"); + case 18: + return newstruct cs2func_script_3355_struct(50, 18334, "Arcane blast necklace" + "
" + " (with 50 Magic)", "You can now wear " + "" + "arcane blast necklaces" + "" + ". (You also need level 50 Magic.)"); + case 19: + return newstruct cs2func_script_3355_struct(50, 19893, "Members: Spirit cape" + "
" + " (with 50 Defence and 50 Summoning)", "Members can now wear " + "" + "spirit capes" + "" + " (You also need level 50 Defence and 50 Summoning.)"); + case 20: + return newstruct cs2func_script_3355_struct(53, 18341, "Nature staff" + "
" + " (with 40 Attack and 53 Magic)", "You can now use " + "" + "nature staves" + "" + ". (You also need level 40 Attack and level 53 Magic.)"); + case 21: + return newstruct cs2func_script_3355_struct(55, 19670, "Scroll of efficiency" + "
" + " (with 55 Smithing)", "You can now use " + "" + "scrolls of efficiency" + "" + ". (You also need level 55 Smithing.)"); + case 22: + return newstruct cs2func_script_3355_struct(60, 18340, "Members: Anti-poison totem" + "
" + " (with 60 Defence and 70 Herblore)", "Members can now wield " + "" + "anti-poison totems" + "" + ". (They also need level 60 Defence and level 70 Herblore.)"); + case 23: + return newstruct cs2func_script_3355_struct(60, 19887, "Members: Split dragon tooth necklace" + "
" + " (with 60 Prayer)", "Members now have the Dungeoneering level required to wear " + "" + "Split dragon tooth necklaces" + "" + ". (They also need level 60 Prayer.)"); + case 24: + return newstruct cs2func_script_3355_struct(62, 19669, "Members: Ring of vigour" + "
" + " (with 62 Attack)", "Members can now wear " + "" + "rings of vigour" + "" + ". (They also need level 62 Attack.)"); + case 25: + return newstruct cs2func_script_3355_struct(65, 18343, "Members: Rapid Renewal" + "
" + " (with 65 Prayer)", "Members can now use the " + "" + "Rapid Renewal" + "" + " prayer (bought from Daemonheim). (They also need level 65 Prayer.)"); + case 26: + return newstruct cs2func_script_3355_struct(70, 18335, "Members: Arcane stream necklace" + "
" + " (with 70 Magic)", "Members can now wear " + "" + "arcane stream necklaces" + "" + ". (They also need level 70 Magic.)"); + case 27: + return newstruct cs2func_script_3355_struct(70, 19889, "Members: Celestial surgebox" + "
" + " (with 70 Magic and 70 Runecrafting)", "Members can now use " + "" + "celestial surgeboxes" + "" + ". (They also need level 70 Magic and level 70 Runecrafting.)"); + case 28: + return newstruct cs2func_script_3355_struct(73, 18347, "Members: Mercenary's gloves" + "
" + " (with 73 Ranged)", "Members can now wear " + "" + "mercenary's gloves" + "" + ". (They also need level 73 Ranged.)"); + case 29: + return newstruct cs2func_script_3355_struct(74, 18839, "Members: Rigour" + "
" + " (with 74 Prayer)", "Members can now use the " + "" + "Rigour" + "" + " prayer (bought from Daemonheim). (They also need level 74 Prayer.)"); + case 30: + return newstruct cs2func_script_3355_struct(77, 18344, "Members: Augury" + "
" + " (with 77 Prayer)", "Members can now use the " + "" + "Augury" + "" + " prayer (bought from Daemonheim). (They also need level 77 Prayer.)"); + case 31: + return newstruct cs2func_script_3355_struct(80, 18358, "Members: Chaotic crossbow" + "
" + " Ammo: Bolts up to rune" + "
" + " (with 80 Ranged)", "Members can now wield " + "" + "chaotic crossbows" + "" + ". (They also need level 80 Ranged.)"); + case 32: + return newstruct cs2func_script_3355_struct(80, 18359, "Members: Chaotic kiteshield" + "
" + " (with 80 Defence)", "Members can now wield " + "" + "chaotic kiteshields" + "" + ". (They also need level 80 Defence.)"); + case 33: + return newstruct cs2func_script_3355_struct(80, 18351, "Members: Chaotic longsword" + "
" + " (with 80 Attack)", "Members can now wield " + "" + "chaotic longswords" + "" + ". (They also need level 80 Attack.)"); + case 34: + return newstruct cs2func_script_3355_struct(80, 18353, "Members: Chaotic maul" + "
" + " (with 80 Attack)", "Members can now wield " + "" + "chaotic mauls" + "" + ". (They also need level 80 Attack.)"); + case 35: + return newstruct cs2func_script_3355_struct(80, 18349, "Members: Chaotic rapier" + "
" + " (with 80 Attack)", "Members can now wield " + "" + "chaotic rapiers" + "" + ". (They also need level 80 Attack.)"); + case 36: + return newstruct cs2func_script_3355_struct(80, 18355, "Members: Chaotic staff" + "
" + " (with 80 Magic)", "Members can now wield " + "" + "chaotic staves" + "" + ". (They also need level 80 Magic.)"); + case 37: + return newstruct cs2func_script_3355_struct(80, 18361, "Members: Eagle-eye kiteshield" + "
" + " (with 80 Defence)", "Members can now wield " + "" + "eagle-eye kiteshields" + "" + ". (They also need level 80 Defence.)"); + case 38: + return newstruct cs2func_script_3355_struct(80, 18363, "Members: Farseer kiteshield" + "
" + " (with 80 Defence)", "Members can now wield " + "" + "farseer kiteshields" + "" + ". (They also need level 80 Defence.)"); + case 39: + return newstruct cs2func_script_3355_struct(80, 19894, "Members: Seeker pet" + "
" + " (with 80 Summoning)", "Members can now raise " + "" + "Seekers" + "" + ". (They also need level 80 Summoning.)"); + case 40: + return newstruct cs2func_script_3355_struct(90, 19888, "Members: Demon horn necklace" + "
" + " (with 90 Prayer)", "Members now have the Dungeoneering level required to wear " + "" + "Demon horn necklaces" + "" + ". (They also need level 90 Prayer.)"); + } + break; + case 4: + switch (arg1) { + case 0: + return newstruct cs2func_script_3355_struct(10, 562, "Members: Edgeville Dungeon chaos druids", "Members can now pass the mysterious entrance in Edgeville Dungeon to reach the chaos druids."); + case 1: + return newstruct cs2func_script_3355_struct(15, 453, "Dwarven Mine hidden mine", "You can now pass the mysterious entrance in the Dwarven Mine to reach the hidden mine."); + case 2: + return newstruct cs2func_script_3355_struct(20, 532, "Edgeville Dungeon hill giants", "You can now pass the mysterious entrance in Edgeville Dungeon to reach the hill giants."); + case 3: + return newstruct cs2func_script_3355_struct(25, 9952, "Karamja Volcano lesser demons", "You can now pass the mysterious entrance in Karamja Volcano to reach the lesser demons."); + case 4: + return newstruct cs2func_script_3355_struct(30, 1517, "Daemonheim woodcutting island", "You can now pass the mysterious entrance in Daemonheim to reach the woodcutting island."); + case 5: + return newstruct cs2func_script_3355_struct(35, 554, "Members: Waterfall fire giants", "Members can now pass the Baxtorian Waterfall mysterious entrance to reach the fire giants."); + case 6: + return newstruct cs2func_script_3355_struct(45, 451, "Mining Guild hidden mine", "You can now pass the mysterious entrance in the Mining Guild to reach the hidden mine."); + case 7: + return newstruct cs2func_script_3355_struct(55, 8137, "Members: Taverley hellhounds", "Members can now pass the mysterious entrance in Taverley Dungeon to reach the hellhounds."); + case 8: + return newstruct cs2func_script_3355_struct(60, 1751, "Members: Taverley blue dragons", "Members can now pass the mysterious entrance in Taverley Dungeon to reach the blue dragons."); + case 9: + return newstruct cs2func_script_3355_struct(65, 8179, "Members: Varrock moss giants", "Members can now pass the mysterious entrance in Varrock Sewers to reach the moss giants."); + case 10: + return newstruct cs2func_script_3355_struct(70, 592, "Members: Chaos Tunnels black demons", "Members can now pass the mysterious entrance in the Chaos Tunnels to reach the black demons."); + case 11: + return newstruct cs2func_script_3355_struct(75, 11254, "Members: Al Kharid hidden mine", "Members can now pass the mysterious entrance in Al Kharid scorpion pit to reach the hidden mine."); + case 12: + return newstruct cs2func_script_3355_struct(80, 8142, "Members: Brimhaven metal dragons", "Members can now pass the mysterious entrance in Brimhaven Dungeon to reach the metal dragons."); + case 13: + return newstruct cs2func_script_3355_struct(85, 18796, "Members: Ice Dungeon frost dragons", "Members can now pass the mysterious entrance in the Asgarnian Ice Dungeon to reach the frost dragons."); + } + break; + case 5: + SWITCH (arg1) { + case 0: + GOTO flow_162 + case 1: + GOTO flow_163 + } + break; + flow_162: + return newstruct cs2func_script_3355_struct(99, 18508, "Skill Mastery", "You have achieved " + "" + "level 99" + "" + " in the " + "" + "Dungeoneering" + "" + " skill." + "
" + "What are you waiting for? Keep going!"); + flow_163: + return newstruct cs2func_script_3355_struct(120, 18509, "True Skill Mastery", "You have achieved " + "" + "level 120" + "" + " in the " + "" + "Dungeoneering" + "" + " skill." + "
" + "This is the highest level for this skill: for real, this time!"); + } + return newstruct cs2func_script_3355_struct(0, -1, "", ""); +} diff --git a/dumps/scripts/3356.cs2 b/dumps/scripts/3356.cs2 new file mode 100644 index 0000000..8e43eeb --- /dev/null +++ b/dumps/scripts/3356.cs2 @@ -0,0 +1,24 @@ +void script_3356(int arg0,int arg1,int arg2) { + int ivar3; + ivar3 = getItemIdInSlotSplit(arg2, arg1); + if (ivar3 == -1) { + setItemOnWidgetMethod2200(-1, 0, new WidgetPointer(arg0)); + setWidgetSize(32, 32, 0, 0, new WidgetPointer(arg0)); + setWidgetPosition(0, 0, 1, 1, new WidgetPointer(arg0)); + setWidgetSprite(cs2method_3408(105, 100, 796, arg1), new WidgetPointer(arg0)); + setWidgetBorderThickness(0, new WidgetPointer(arg0)); + setWidgetShadowColor(new Color(0, 0, 0), new WidgetPointer(arg0)); + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(arg0)); + setWidgetNoOptions(new WidgetPointer(arg0)); + return; + } + setWidgetSize(36, 32, 0, 0, new WidgetPointer(arg0)); + setWidgetPosition(2, 0, 0, 1, new WidgetPointer(arg0)); + setItemOnWidgetMethod2200(ivar3, getItemAmtInSlotSplit(arg2, arg1), new WidgetPointer(arg0)); + setWidgetBorderThickness(1, new WidgetPointer(arg0)); + setWidgetShadowColor(new Color(48, 32, 32), new WidgetPointer(arg0)); + setWidgetNoOptions(new WidgetPointer(arg0)); + setWidgetContextMenuOption(10, new WidgetPointer(arg0), "Examine" + ""); + cs2method2305(new WidgetPointer(arg0), "" + getItemName(ivar3)); + return; +} diff --git a/dumps/scripts/3357.cs2 b/dumps/scripts/3357.cs2 new file mode 100644 index 0000000..0da7cc8 --- /dev/null +++ b/dumps/scripts/3357.cs2 @@ -0,0 +1,46 @@ +cs2func_script_3357_struct(2,1,0) script_3357() { + flow_0: + SWITCH (standart_config_448) { + case 17935: + GOTO flow_1 + case 17936: + GOTO flow_2 + case 17937: + GOTO flow_3 + case 17938: + GOTO flow_4 + case 17939: + GOTO flow_5 + case 17940: + GOTO flow_6 + case 17941: + GOTO flow_7 + case 17942: + GOTO flow_8 + case 17943: + GOTO flow_9 + case 17944: + GOTO flow_10 + } + return newstruct cs2func_script_3357_struct(1, 18027, "Sundering Strike (Tier 1)"); + flow_1: + return newstruct cs2func_script_3357_struct(1, 18027, "Sundering Strike (Tier 1)"); + flow_2: + return newstruct cs2func_script_3357_struct(11, 18028, "Sundering Strike (Tier 2)"); + flow_3: + return newstruct cs2func_script_3357_struct(21, 18029, "Sundering Strike (Tier 3)"); + flow_4: + return newstruct cs2func_script_3357_struct(31, 18030, "Sundering Strike (Tier 4)"); + flow_5: + return newstruct cs2func_script_3357_struct(41, 18031, "Sundering Strike (Tier 5)"); + flow_6: + return newstruct cs2func_script_3357_struct(51, 18032, "Sundering Strike (Tier 6)"); + flow_7: + return newstruct cs2func_script_3357_struct(61, 18033, "Sundering Strike (Tier 7)"); + flow_8: + return newstruct cs2func_script_3357_struct(71, 18034, "Sundering Strike (Tier 8)"); + flow_9: + return newstruct cs2func_script_3357_struct(81, 18035, "Sundering Strike (Tier 9)"); + flow_10: + return newstruct cs2func_script_3357_struct(91, 18036, "Sundering Strike (Tier 10)"); +} diff --git a/dumps/scripts/3358.cs2 b/dumps/scripts/3358.cs2 new file mode 100644 index 0000000..f9a3a93 --- /dev/null +++ b/dumps/scripts/3358.cs2 @@ -0,0 +1,46 @@ +cs2func_script_3358_struct(2,1,0) script_3358() { + flow_0: + SWITCH (standart_config_448) { + case 17985: + GOTO flow_1 + case 17986: + GOTO flow_2 + case 17987: + GOTO flow_3 + case 17988: + GOTO flow_4 + case 17989: + GOTO flow_5 + case 17990: + GOTO flow_6 + case 17991: + GOTO flow_7 + case 17992: + GOTO flow_8 + case 17993: + GOTO flow_9 + case 17994: + GOTO flow_10 + } + return newstruct cs2func_script_3358_struct(2, 18037, "Poisonous Shot (Tier 1)"); + flow_1: + return newstruct cs2func_script_3358_struct(2, 18037, "Poisonous Shot (Tier 1)"); + flow_2: + return newstruct cs2func_script_3358_struct(12, 18038, "Poisonous Shot (Tier 2)"); + flow_3: + return newstruct cs2func_script_3358_struct(22, 18039, "Poisonous Shot (Tier 3)"); + flow_4: + return newstruct cs2func_script_3358_struct(32, 18040, "Poisonous Shot (Tier 4)"); + flow_5: + return newstruct cs2func_script_3358_struct(42, 18041, "Poisonous Shot (Tier 5)"); + flow_6: + return newstruct cs2func_script_3358_struct(52, 18042, "Poisonous Shot (Tier 6)"); + flow_7: + return newstruct cs2func_script_3358_struct(62, 18043, "Poisonous Shot (Tier 7)"); + flow_8: + return newstruct cs2func_script_3358_struct(72, 18044, "Poisonous Shot (Tier 8)"); + flow_9: + return newstruct cs2func_script_3358_struct(82, 18045, "Poisonous Shot (Tier 9)"); + flow_10: + return newstruct cs2func_script_3358_struct(92, 18046, "Poisonous Shot (Tier 10)"); +} diff --git a/dumps/scripts/3359.cs2 b/dumps/scripts/3359.cs2 new file mode 100644 index 0000000..b47eb5e --- /dev/null +++ b/dumps/scripts/3359.cs2 @@ -0,0 +1,46 @@ +cs2func_script_3359_struct(2,1,0) script_3359() { + flow_0: + SWITCH (standart_config_448) { + case 17945: + GOTO flow_1 + case 17946: + GOTO flow_2 + case 17947: + GOTO flow_3 + case 17948: + GOTO flow_4 + case 17949: + GOTO flow_5 + case 17950: + GOTO flow_6 + case 17951: + GOTO flow_7 + case 17952: + GOTO flow_8 + case 17953: + GOTO flow_9 + case 17954: + GOTO flow_10 + } + return newstruct cs2func_script_3359_struct(3, 18047, "Snaring Wave (Tier 1)"); + flow_1: + return newstruct cs2func_script_3359_struct(3, 18047, "Snaring Wave (Tier 1)"); + flow_2: + return newstruct cs2func_script_3359_struct(13, 18048, "Snaring Wave (Tier 2)"); + flow_3: + return newstruct cs2func_script_3359_struct(23, 18049, "Snaring Wave (Tier 3)"); + flow_4: + return newstruct cs2func_script_3359_struct(33, 18050, "Snaring Wave (Tier 4)"); + flow_5: + return newstruct cs2func_script_3359_struct(43, 18051, "Snaring Wave (Tier 5)"); + flow_6: + return newstruct cs2func_script_3359_struct(53, 18052, "Snaring Wave (Tier 6)"); + flow_7: + return newstruct cs2func_script_3359_struct(63, 18053, "Snaring Wave (Tier 7)"); + flow_8: + return newstruct cs2func_script_3359_struct(73, 18054, "Snaring Wave (Tier 8)"); + flow_9: + return newstruct cs2func_script_3359_struct(83, 18055, "Snaring Wave (Tier 9)"); + flow_10: + return newstruct cs2func_script_3359_struct(93, 18056, "Snaring Wave (Tier 10)"); +} diff --git a/dumps/scripts/336.cs2 b/dumps/scripts/336.cs2 new file mode 100644 index 0000000..36f3cd0 --- /dev/null +++ b/dumps/scripts/336.cs2 @@ -0,0 +1,292 @@ +void script_336() { + int ivar0; + int ivar1; + int ivar2; + int stack_dump0; + int stack_dump1; + int stack_dump2; + int stack_dump3; + cs2func_script_335_struct(2,0,0) structdump_4; + cs2func_script_335_struct(2,0,0) structdump_5; + cs2func_script_335_struct(2,0,0) structdump_6; + cs2func_script_335_struct(2,0,0) structdump_7; + cs2func_script_335_struct(2,0,0) structdump_8; + cs2func_script_335_struct(2,0,0) structdump_9; + cs2func_script_335_struct(2,0,0) structdump_10; + cs2func_script_335_struct(2,0,0) structdump_11; + cs2func_script_335_struct(2,0,0) structdump_12; + cs2func_script_335_struct(2,0,0) structdump_13; + cs2func_script_335_struct(2,0,0) structdump_14; + cs2func_script_335_struct(2,0,0) structdump_15; + cs2func_script_335_struct(2,0,0) structdump_16; + cs2func_script_335_struct(2,0,0) structdump_17; + cs2func_script_335_struct(2,0,0) structdump_18; + cs2func_script_335_struct(2,0,0) structdump_19; + cs2func_script_335_struct(2,0,0) structdump_20; + cs2func_script_335_struct(2,0,0) structdump_21; + cs2func_script_335_struct(2,0,0) structdump_22; + cs2func_script_335_struct(2,0,0) structdump_23; + cs2func_script_335_struct(2,0,0) structdump_24; + cs2func_script_335_struct(2,0,0) structdump_25; + cs2func_script_335_struct(2,0,0) structdump_26; + cs2func_script_335_struct(2,0,0) structdump_27; + cs2func_script_335_struct(2,0,0) structdump_28; + ivar0 = 0; + ivar1 = 0; + ivar2 = 0; + if (globalint_1243 < getSkillXp(0)) { + ivar2 = subtract(getSkillXp(0), globalint_1243); + stack_dump0 = ivar0; + stack_dump1 = ivar1; + stack_dump2 = ivar2; + stack_dump3 = 0; + structdump_4 = script_335(stack_dump0, stack_dump1, stack_dump2, stack_dump3); + ivar1 = structdump_4.intpart_1; + ivar0 = structdump_4.intpart_0; + } + if (globalint_1244 < getSkillXp(2)) { + ivar2 = subtract(getSkillXp(2), globalint_1244); + stack_dump0 = ivar0; + stack_dump1 = ivar1; + stack_dump2 = ivar2; + stack_dump3 = 0; + structdump_5 = script_335(stack_dump0, stack_dump1, stack_dump2, stack_dump3); + ivar1 = structdump_5.intpart_1; + ivar0 = structdump_5.intpart_0; + } + if (globalint_1245 < getSkillXp(1)) { + ivar2 = subtract(getSkillXp(1), globalint_1245); + stack_dump0 = ivar0; + stack_dump1 = ivar1; + stack_dump2 = ivar2; + stack_dump3 = 0; + structdump_6 = script_335(stack_dump0, stack_dump1, stack_dump2, stack_dump3); + ivar1 = structdump_6.intpart_1; + ivar0 = structdump_6.intpart_0; + } + if (globalint_1246 < getSkillXp(4)) { + ivar2 = subtract(getSkillXp(4), globalint_1246); + stack_dump0 = ivar0; + stack_dump1 = ivar1; + stack_dump2 = ivar2; + stack_dump3 = 0; + structdump_7 = script_335(stack_dump0, stack_dump1, stack_dump2, stack_dump3); + ivar1 = structdump_7.intpart_1; + ivar0 = structdump_7.intpart_0; + } + if (globalint_1247 < getSkillXp(5)) { + ivar2 = subtract(getSkillXp(5), globalint_1247); + stack_dump0 = ivar0; + stack_dump1 = ivar1; + stack_dump2 = ivar2; + stack_dump3 = 0; + structdump_8 = script_335(stack_dump0, stack_dump1, stack_dump2, stack_dump3); + ivar1 = structdump_8.intpart_1; + ivar0 = structdump_8.intpart_0; + } + if (globalint_1248 < getSkillXp(6)) { + ivar2 = subtract(getSkillXp(6), globalint_1248); + stack_dump0 = ivar0; + stack_dump1 = ivar1; + stack_dump2 = ivar2; + stack_dump3 = 0; + structdump_9 = script_335(stack_dump0, stack_dump1, stack_dump2, stack_dump3); + ivar1 = structdump_9.intpart_1; + ivar0 = structdump_9.intpart_0; + } + if (globalint_1249 < getSkillXp(20)) { + ivar2 = subtract(getSkillXp(20), globalint_1249); + stack_dump0 = ivar0; + stack_dump1 = ivar1; + stack_dump2 = ivar2; + stack_dump3 = 0; + structdump_10 = script_335(stack_dump0, stack_dump1, stack_dump2, stack_dump3); + ivar1 = structdump_10.intpart_1; + ivar0 = structdump_10.intpart_0; + } + if (globalint_1250 < getSkillXp(3)) { + ivar2 = subtract(getSkillXp(3), globalint_1250); + stack_dump0 = ivar0; + stack_dump1 = ivar1; + stack_dump2 = ivar2; + stack_dump3 = 0; + structdump_11 = script_335(stack_dump0, stack_dump1, stack_dump2, stack_dump3); + ivar1 = structdump_11.intpart_1; + ivar0 = structdump_11.intpart_0; + } + if (globalint_1251 < getSkillXp(12)) { + ivar2 = subtract(getSkillXp(12), globalint_1251); + stack_dump0 = ivar0; + stack_dump1 = ivar1; + stack_dump2 = ivar2; + stack_dump3 = 0; + structdump_12 = script_335(stack_dump0, stack_dump1, stack_dump2, stack_dump3); + ivar1 = structdump_12.intpart_1; + ivar0 = structdump_12.intpart_0; + } + if (globalint_1252 < getSkillXp(14)) { + ivar2 = subtract(getSkillXp(14), globalint_1252); + stack_dump0 = ivar0; + stack_dump1 = ivar1; + stack_dump2 = ivar2; + stack_dump3 = 0; + structdump_13 = script_335(stack_dump0, stack_dump1, stack_dump2, stack_dump3); + ivar1 = structdump_13.intpart_1; + ivar0 = structdump_13.intpart_0; + } + if (globalint_1253 < getSkillXp(13)) { + ivar2 = subtract(getSkillXp(13), globalint_1253); + stack_dump0 = ivar0; + stack_dump1 = ivar1; + stack_dump2 = ivar2; + stack_dump3 = 0; + structdump_14 = script_335(stack_dump0, stack_dump1, stack_dump2, stack_dump3); + ivar1 = structdump_14.intpart_1; + ivar0 = structdump_14.intpart_0; + } + if (globalint_1254 < getSkillXp(10)) { + ivar2 = subtract(getSkillXp(10), globalint_1254); + stack_dump0 = ivar0; + stack_dump1 = ivar1; + stack_dump2 = ivar2; + stack_dump3 = 0; + structdump_15 = script_335(stack_dump0, stack_dump1, stack_dump2, stack_dump3); + ivar1 = structdump_15.intpart_1; + ivar0 = structdump_15.intpart_0; + } + if (globalint_1255 < getSkillXp(7)) { + ivar2 = subtract(getSkillXp(7), globalint_1255); + stack_dump0 = ivar0; + stack_dump1 = ivar1; + stack_dump2 = ivar2; + stack_dump3 = 0; + structdump_16 = script_335(stack_dump0, stack_dump1, stack_dump2, stack_dump3); + ivar1 = structdump_16.intpart_1; + ivar0 = structdump_16.intpart_0; + } + if (globalint_1256 < getSkillXp(11)) { + ivar2 = subtract(getSkillXp(11), globalint_1256); + stack_dump0 = ivar0; + stack_dump1 = ivar1; + stack_dump2 = ivar2; + stack_dump3 = 0; + structdump_17 = script_335(stack_dump0, stack_dump1, stack_dump2, stack_dump3); + ivar1 = structdump_17.intpart_1; + ivar0 = structdump_17.intpart_0; + } + if (globalint_1257 < getSkillXp(8)) { + ivar2 = subtract(getSkillXp(8), globalint_1257); + stack_dump0 = ivar0; + stack_dump1 = ivar1; + stack_dump2 = ivar2; + stack_dump3 = 0; + structdump_18 = script_335(stack_dump0, stack_dump1, stack_dump2, stack_dump3); + ivar1 = structdump_18.intpart_1; + ivar0 = structdump_18.intpart_0; + } + if (globalint_1258 < getSkillXp(16)) { + ivar2 = subtract(getSkillXp(16), globalint_1258); + stack_dump0 = ivar0; + stack_dump1 = ivar1; + stack_dump2 = ivar2; + stack_dump3 = 0; + structdump_19 = script_335(stack_dump0, stack_dump1, stack_dump2, stack_dump3); + ivar1 = structdump_19.intpart_1; + ivar0 = structdump_19.intpart_0; + } + if (globalint_1259 < getSkillXp(15)) { + ivar2 = subtract(getSkillXp(15), globalint_1259); + stack_dump0 = ivar0; + stack_dump1 = ivar1; + stack_dump2 = ivar2; + stack_dump3 = 0; + structdump_20 = script_335(stack_dump0, stack_dump1, stack_dump2, stack_dump3); + ivar1 = structdump_20.intpart_1; + ivar0 = structdump_20.intpart_0; + } + if (globalint_1260 < getSkillXp(17)) { + ivar2 = subtract(getSkillXp(17), globalint_1260); + stack_dump0 = ivar0; + stack_dump1 = ivar1; + stack_dump2 = ivar2; + stack_dump3 = 0; + structdump_21 = script_335(stack_dump0, stack_dump1, stack_dump2, stack_dump3); + ivar1 = structdump_21.intpart_1; + ivar0 = structdump_21.intpart_0; + } + if (globalint_1261 < getSkillXp(9)) { + ivar2 = subtract(getSkillXp(9), globalint_1261); + stack_dump0 = ivar0; + stack_dump1 = ivar1; + stack_dump2 = ivar2; + stack_dump3 = 0; + structdump_22 = script_335(stack_dump0, stack_dump1, stack_dump2, stack_dump3); + ivar1 = structdump_22.intpart_1; + ivar0 = structdump_22.intpart_0; + } + if (globalint_1262 < getSkillXp(18)) { + ivar2 = subtract(getSkillXp(18), globalint_1262); + stack_dump0 = ivar0; + stack_dump1 = ivar1; + stack_dump2 = ivar2; + stack_dump3 = 0; + structdump_23 = script_335(stack_dump0, stack_dump1, stack_dump2, stack_dump3); + ivar1 = structdump_23.intpart_1; + ivar0 = structdump_23.intpart_0; + } + if (globalint_1263 < getSkillXp(19)) { + ivar2 = subtract(getSkillXp(19), globalint_1263); + stack_dump0 = ivar0; + stack_dump1 = ivar1; + stack_dump2 = ivar2; + stack_dump3 = 0; + structdump_24 = script_335(stack_dump0, stack_dump1, stack_dump2, stack_dump3); + ivar1 = structdump_24.intpart_1; + ivar0 = structdump_24.intpart_0; + } + if (globalint_1264 < getSkillXp(22)) { + ivar2 = subtract(getSkillXp(22), globalint_1264); + stack_dump0 = ivar0; + stack_dump1 = ivar1; + stack_dump2 = ivar2; + stack_dump3 = 0; + structdump_25 = script_335(stack_dump0, stack_dump1, stack_dump2, stack_dump3); + ivar1 = structdump_25.intpart_1; + ivar0 = structdump_25.intpart_0; + } + if (globalint_1265 < getSkillXp(21)) { + ivar2 = subtract(getSkillXp(21), globalint_1265); + stack_dump0 = ivar0; + stack_dump1 = ivar1; + stack_dump2 = ivar2; + stack_dump3 = 0; + structdump_26 = script_335(stack_dump0, stack_dump1, stack_dump2, stack_dump3); + ivar1 = structdump_26.intpart_1; + ivar0 = structdump_26.intpart_0; + } + if (globalint_1266 < getSkillXp(23)) { + ivar2 = subtract(getSkillXp(23), globalint_1266); + stack_dump0 = ivar0; + stack_dump1 = ivar1; + stack_dump2 = ivar2; + stack_dump3 = 0; + structdump_27 = script_335(stack_dump0, stack_dump1, stack_dump2, stack_dump3); + ivar1 = structdump_27.intpart_1; + ivar0 = structdump_27.intpart_0; + } + if (globalint_1267 < getSkillXp(24)) { + ivar2 = subtract(getSkillXp(24), globalint_1267); + stack_dump0 = ivar0; + stack_dump1 = ivar1; + stack_dump2 = ivar2; + stack_dump3 = 0; + structdump_28 = script_335(stack_dump0, stack_dump1, stack_dump2, stack_dump3); + ivar1 = structdump_28.intpart_1; + ivar0 = structdump_28.intpart_0; + } + if (((boolean)ivar0)) { + return; + } + script_337(ivar0, ivar1, 0); + return; +} diff --git a/dumps/scripts/3360.cs2 b/dumps/scripts/3360.cs2 new file mode 100644 index 0000000..0fa61f7 --- /dev/null +++ b/dumps/scripts/3360.cs2 @@ -0,0 +1,46 @@ +cs2func_script_3360_struct(2,1,0) script_3360() { + flow_0: + SWITCH (standart_config_448) { + case 17955: + GOTO flow_1 + case 17956: + GOTO flow_2 + case 17957: + GOTO flow_3 + case 17958: + GOTO flow_4 + case 17959: + GOTO flow_5 + case 17960: + GOTO flow_6 + case 17961: + GOTO flow_7 + case 17962: + GOTO flow_8 + case 17963: + GOTO flow_9 + case 17964: + GOTO flow_10 + } + return newstruct cs2func_script_3360_struct(5, 18057, "Aptitude (Tier 1)"); + flow_1: + return newstruct cs2func_script_3360_struct(5, 18057, "Aptitude (Tier 1)"); + flow_2: + return newstruct cs2func_script_3360_struct(15, 18058, "Aptitude (Tier 2)"); + flow_3: + return newstruct cs2func_script_3360_struct(25, 18059, "Aptitude (Tier 3)"); + flow_4: + return newstruct cs2func_script_3360_struct(35, 18060, "Aptitude (Tier 4)"); + flow_5: + return newstruct cs2func_script_3360_struct(45, 18061, "Aptitude (Tier 5)"); + flow_6: + return newstruct cs2func_script_3360_struct(55, 18062, "Aptitude (Tier 6)"); + flow_7: + return newstruct cs2func_script_3360_struct(65, 18063, "Aptitude (Tier 7)"); + flow_8: + return newstruct cs2func_script_3360_struct(75, 18064, "Aptitude (Tier 8)"); + flow_9: + return newstruct cs2func_script_3360_struct(85, 18065, "Aptitude (Tier 9)"); + flow_10: + return newstruct cs2func_script_3360_struct(95, 18066, "Aptitude (Tier 10)"); +} diff --git a/dumps/scripts/3361.cs2 b/dumps/scripts/3361.cs2 new file mode 100644 index 0000000..ded8902 --- /dev/null +++ b/dumps/scripts/3361.cs2 @@ -0,0 +1,46 @@ +cs2func_script_3361_struct(2,1,0) script_3361() { + flow_0: + SWITCH (standart_config_448) { + case 17975: + GOTO flow_1 + case 17976: + GOTO flow_2 + case 17977: + GOTO flow_3 + case 17978: + GOTO flow_4 + case 17979: + GOTO flow_5 + case 17980: + GOTO flow_6 + case 17981: + GOTO flow_7 + case 17982: + GOTO flow_8 + case 17983: + GOTO flow_9 + case 17984: + GOTO flow_10 + } + return newstruct cs2func_script_3361_struct(7, 18067, "Second Wind (Tier 1)"); + flow_1: + return newstruct cs2func_script_3361_struct(7, 18067, "Second Wind (Tier 1)"); + flow_2: + return newstruct cs2func_script_3361_struct(17, 18068, "Second Wind (Tier 2)"); + flow_3: + return newstruct cs2func_script_3361_struct(27, 18069, "Second Wind (Tier 3)"); + flow_4: + return newstruct cs2func_script_3361_struct(37, 18070, "Second Wind (Tier 4)"); + flow_5: + return newstruct cs2func_script_3361_struct(47, 18071, "Second Wind (Tier 5)"); + flow_6: + return newstruct cs2func_script_3361_struct(57, 18072, "Second Wind (Tier 6)"); + flow_7: + return newstruct cs2func_script_3361_struct(67, 18073, "Second Wind (Tier 7)"); + flow_8: + return newstruct cs2func_script_3361_struct(77, 18074, "Second Wind (Tier 8)"); + flow_9: + return newstruct cs2func_script_3361_struct(87, 18075, "Second Wind (Tier 9)"); + flow_10: + return newstruct cs2func_script_3361_struct(97, 18076, "Second Wind (Tier 10)"); +} diff --git a/dumps/scripts/3362.cs2 b/dumps/scripts/3362.cs2 new file mode 100644 index 0000000..fe6c44c --- /dev/null +++ b/dumps/scripts/3362.cs2 @@ -0,0 +1,46 @@ +cs2func_script_3362_struct(2,1,0) script_3362() { + flow_0: + SWITCH (standart_config_448) { + case 17965: + GOTO flow_1 + case 17966: + GOTO flow_2 + case 17967: + GOTO flow_3 + case 17968: + GOTO flow_4 + case 17969: + GOTO flow_5 + case 17970: + GOTO flow_6 + case 17971: + GOTO flow_7 + case 17972: + GOTO flow_8 + case 17973: + GOTO flow_9 + case 17974: + GOTO flow_10 + } + return newstruct cs2func_script_3362_struct(9, 18077, "Glimmer of Light (Tier 1)"); + flow_1: + return newstruct cs2func_script_3362_struct(9, 18077, "Glimmer of Light (Tier 1)"); + flow_2: + return newstruct cs2func_script_3362_struct(19, 18078, "Glimmer of Light (Tier 2)"); + flow_3: + return newstruct cs2func_script_3362_struct(29, 18079, "Glimmer of Light (Tier 3)"); + flow_4: + return newstruct cs2func_script_3362_struct(39, 18080, "Glimmer of Light (Tier 4)"); + flow_5: + return newstruct cs2func_script_3362_struct(49, 18081, "Glimmer of Light (Tier 5)"); + flow_6: + return newstruct cs2func_script_3362_struct(59, 18082, "Glimmer of Light (Tier 6)"); + flow_7: + return newstruct cs2func_script_3362_struct(69, 18083, "Glimmer of Light (Tier 7)"); + flow_8: + return newstruct cs2func_script_3362_struct(79, 18084, "Glimmer of Light (Tier 8)"); + flow_9: + return newstruct cs2func_script_3362_struct(89, 18085, "Glimmer of Light (Tier 9)"); + flow_10: + return newstruct cs2func_script_3362_struct(99, 18086, "Glimmer of Light (Tier 10)"); +} diff --git a/dumps/scripts/3363.cs2 b/dumps/scripts/3363.cs2 new file mode 100644 index 0000000..6ef3d49 --- /dev/null +++ b/dumps/scripts/3363.cs2 @@ -0,0 +1,5 @@ +void script_3363(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5) { + setWidgetSprite(arg4, new WidgetPointer(arg0)); + script_569(arg0, -1, arg1, arg2, arg3, arg5); + return; +} diff --git a/dumps/scripts/3364.cs2 b/dumps/scripts/3364.cs2 new file mode 100644 index 0000000..1ae2b4d --- /dev/null +++ b/dumps/scripts/3364.cs2 @@ -0,0 +1,96 @@ +void script_3364(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,string arg7) { + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + flow_0: + ivar7 = 0; + ivar8 = 0; + ivar9 = 0; + ivar10 = 0; + ivar11 = 0; + ivar12 = 0; + ivar13 = 0; + ivar14 = 0; + ivar15 = -1; + IF (arg1 == -1) + GOTO flow_1 + GOTO flow_2 + flow_1: + IF (setWidgetRegister(new WidgetPointer(arg0))) + GOTO flow_3 + flow_2: + IF (setWidgetRegister(new WidgetPointer(arg0), arg1)) + GOTO flow_3 + GOTO flow_25 + flow_3: + if (((boolean)script_4761(arg3))) { + return; + } + if (globalint_2 != 1) { + ivar7 = add(script_1743(), arg5); + ivar8 = add(add(script_1744(), getWidgetActualHeight()), arg6); + ivar15 = getWidgetParentId(new WidgetPointer(arg2)); + if ((ivar15 != -1) && (arg4 >= getWidgetActualWidth(new WidgetPointer(ivar15)))) { + arg4 = getWidgetActualWidth(new WidgetPointer(ivar15)); + } + ivar13 = add(4, getMaxLineWidth(subtract(arg4, 4), 495, arg7)); + ivar14 = add(add(4, multiply(13, getLineCount(subtract(arg4, 4), 495, arg7))), 3); + if (ivar15 != -1) { + ivar9 = subtract(ivar7, cs2method2600(new WidgetPointer(ivar15))); + ivar10 = subtract(ivar8, cs2method2601(new WidgetPointer(ivar15))); + if (ivar9 < 0) { + ivar7 = cs2method2600(new WidgetPointer(ivar15)); + ivar9 = 0; + } + if (ivar10 < 0) { + ivar8 = cs2method2601(new WidgetPointer(ivar15)); + ivar10 = 0; + } + if (ivar9 > 0) { + ivar11 = add(subtract(ivar9, getWidgetActualWidth(new WidgetPointer(ivar15))), ivar13); + if (ivar11 > 0) { + ivar7 = subtract(ivar7, ivar11); + } + } + if (ivar10 > 0) { + ivar12 = add(subtract(ivar10, getWidgetActualHeight(new WidgetPointer(ivar15))), ivar14); + if (ivar12 > 0) { + ivar8 = subtract(subtract(subtract(ivar8, ivar12), getWidgetActualHeight()), 10); + } + } + } + if (ivar7 < 0) { + ivar7 = 0; + } + if (ivar8 < 0) { + ivar8 = 0; + } + setWidgetSize(ivar13, ivar14, 0, 0, new WidgetPointer(arg2)); + setWidgetPosition(ivar7, ivar8, 0, 0, new WidgetPointer(arg2)); + deleteAllExtraChilds(new WidgetPointer(arg2)); + createExtraChild(new WidgetPointer(arg2), 3, 0); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg2)), getWidgetActualHeight(new WidgetPointer(arg2)), 0, 0); + setWidgetFilled(1); + setWidgetRGB(new Color(255, 255, 160)); + createExtraChild(new WidgetPointer(arg2), 3, 1); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg2)), getWidgetActualHeight(new WidgetPointer(arg2)), 0, 0); + setWidgetFilled(0); + setWidgetRGB(new Color(0, 0, 0)); + createExtraChild(new WidgetPointer(arg2), 4, 2); + setWidgetSize(subtract(arg4, 4), getWidgetActualHeight(new WidgetPointer(arg2)), 0, 0); + setWidgetPosition(2, 0, 0, 0); + setWidgetText(arg7); + setWidgetTextAlignment(0, 1, 0); + setWidgetFont(495); + setWidgetRGB(new Color(0, 0, 0)); + globalint_2 = 1; + } + flow_25: + return; +} diff --git a/dumps/scripts/3365.cs2 b/dumps/scripts/3365.cs2 new file mode 100644 index 0000000..ad38012 --- /dev/null +++ b/dumps/scripts/3365.cs2 @@ -0,0 +1,11 @@ +int script_3365(int arg0) { + int ivar1; + int ivar2; + ivar1 = getWidgetActualX(new WidgetPointer(arg0)); + ivar2 = getWidgetParentId(new WidgetPointer(arg0)); + while (ivar2 != -1) { + ivar1 = subtract(add(ivar1, getWidgetActualX(new WidgetPointer(ivar2))), cs2method2600(new WidgetPointer(ivar2))); + ivar2 = getWidgetParentId(new WidgetPointer(ivar2)); + } + return ivar1; +} diff --git a/dumps/scripts/3366.cs2 b/dumps/scripts/3366.cs2 new file mode 100644 index 0000000..9e48e92 --- /dev/null +++ b/dumps/scripts/3366.cs2 @@ -0,0 +1,11 @@ +int script_3366(int arg0) { + int ivar1; + int ivar2; + ivar1 = getWidgetActualY(new WidgetPointer(arg0)); + ivar2 = getWidgetParentId(new WidgetPointer(arg0)); + while (ivar2 != -1) { + ivar1 = subtract(add(ivar1, getWidgetActualY(new WidgetPointer(ivar2))), cs2method2601(new WidgetPointer(ivar2))); + ivar2 = getWidgetParentId(new WidgetPointer(ivar2)); + } + return ivar1; +} diff --git a/dumps/scripts/3367.cs2 b/dumps/scripts/3367.cs2 new file mode 100644 index 0000000..a550fb2 --- /dev/null +++ b/dumps/scripts/3367.cs2 @@ -0,0 +1,98 @@ +void script_3367() { + int ivar0; + int ivar1; + int ivar2; + ivar0 = 0; + ivar1 = 0; + ivar2 = 0; + if (globalint_1243 < getSkillXp(0)) { + ivar0 = add(ivar0, subtract(getSkillXp(0), globalint_1243)); + ivar1 = add(ivar1, divide(subtract(getSkillXp(0), globalint_1243), 2)); + } + if (globalint_1244 < getSkillXp(2)) { + ivar0 = add(ivar0, subtract(getSkillXp(2), globalint_1244)); + ivar1 = add(ivar1, divide(subtract(getSkillXp(2), globalint_1244), 2)); + } + if (globalint_1245 < getSkillXp(1)) { + ivar0 = add(ivar0, subtract(getSkillXp(1), globalint_1245)); + ivar1 = add(ivar1, divide(subtract(getSkillXp(1), globalint_1245), 2)); + } + if (globalint_1246 < getSkillXp(4)) { + ivar0 = add(ivar0, subtract(getSkillXp(4), globalint_1246)); + ivar1 = add(ivar1, divide(subtract(getSkillXp(4), globalint_1246), 2)); + } + if (globalint_1247 < getSkillXp(5)) { + ivar0 = add(ivar0, subtract(getSkillXp(5), globalint_1247)); + } + if (globalint_1248 < getSkillXp(6)) { + ivar0 = add(ivar0, subtract(getSkillXp(6), globalint_1248)); + ivar1 = add(ivar1, divide(subtract(getSkillXp(6), globalint_1248), 2)); + } + if (globalint_1249 < getSkillXp(20)) { + ivar0 = add(ivar0, subtract(getSkillXp(20), globalint_1249)); + } + if (globalint_1250 < getSkillXp(3)) { + ivar0 = add(ivar0, subtract(getSkillXp(3), globalint_1250)); + ivar1 = add(ivar1, divide(subtract(getSkillXp(3), globalint_1250), 2)); + } + if (globalint_1251 < getSkillXp(12)) { + ivar0 = add(ivar0, subtract(getSkillXp(12), globalint_1251)); + } + if (globalint_1252 < getSkillXp(14)) { + ivar0 = add(ivar0, subtract(getSkillXp(14), globalint_1252)); + } + if (globalint_1253 < getSkillXp(13)) { + ivar0 = add(ivar0, subtract(getSkillXp(13), globalint_1253)); + } + if (globalint_1254 < getSkillXp(10)) { + ivar0 = add(ivar0, subtract(getSkillXp(10), globalint_1254)); + } + if (globalint_1255 < getSkillXp(7)) { + ivar0 = add(ivar0, subtract(getSkillXp(7), globalint_1255)); + } + if (globalint_1256 < getSkillXp(11)) { + ivar0 = add(ivar0, subtract(getSkillXp(11), globalint_1256)); + } + if (globalint_1257 < getSkillXp(8)) { + ivar0 = add(ivar0, subtract(getSkillXp(8), globalint_1257)); + } + if (globalint_1258 < getSkillXp(16)) { + ivar0 = add(ivar0, subtract(getSkillXp(16), globalint_1258)); + } + if (globalint_1259 < getSkillXp(15)) { + ivar0 = add(ivar0, subtract(getSkillXp(15), globalint_1259)); + } + if (globalint_1260 < getSkillXp(17)) { + ivar0 = add(ivar0, subtract(getSkillXp(17), globalint_1260)); + } + if (globalint_1261 < getSkillXp(9)) { + ivar0 = add(ivar0, subtract(getSkillXp(9), globalint_1261)); + } + if (globalint_1262 < getSkillXp(18)) { + ivar0 = add(ivar0, subtract(getSkillXp(18), globalint_1262)); + } + if (globalint_1263 < getSkillXp(19)) { + ivar0 = add(ivar0, subtract(getSkillXp(19), globalint_1263)); + } + if (globalint_1264 < getSkillXp(22)) { + ivar0 = add(ivar0, subtract(getSkillXp(22), globalint_1264)); + } + if (globalint_1265 < getSkillXp(21)) { + ivar0 = add(ivar0, subtract(getSkillXp(21), globalint_1265)); + } + if (globalint_1266 < getSkillXp(23)) { + ivar0 = add(ivar0, subtract(getSkillXp(23), globalint_1266)); + } + if (globalint_1267 < getSkillXp(24)) { + ivar0 = add(ivar0, subtract(getSkillXp(24), globalint_1267)); + } + if (((boolean)ivar0)) { + return; + } + if (standart_config_2044 > 0) { + script_337(ivar0, standart_config_2044, 0); + } else { + script_3368(ivar0); + } + return; +} diff --git a/dumps/scripts/3368.cs2 b/dumps/scripts/3368.cs2 new file mode 100644 index 0000000..e3ca433 --- /dev/null +++ b/dumps/scripts/3368.cs2 @@ -0,0 +1,7 @@ +void script_3368(int arg0) { + setWidgetText(new WidgetPointer(548,26), formatNumber(arg0, 1) + "xp"); + setWidgetText(new WidgetPointer(746,189), formatNumber(arg0, 1) + "xp"); + setScriptCallOnGameloop(3369, new WidgetPointer(548,22), getClientCycle(), "Ii", new WidgetPointer(548,22)); + setScriptCallOnGameloop(3370, new WidgetPointer(746,184), getClientCycle(), "Ii", new WidgetPointer(746,184)); + return; +} diff --git a/dumps/scripts/3369.cs2 b/dumps/scripts/3369.cs2 new file mode 100644 index 0000000..2b4c3d0 --- /dev/null +++ b/dumps/scripts/3369.cs2 @@ -0,0 +1,15 @@ +void script_3369(int arg0,int arg1) { + int ivar2; + int ivar3; + ivar2 = subtract(getClientCycle(), arg1); + ivar3 = 0; + if (ivar2 > 70) { + setWidgetIsHidden(true, new WidgetPointer(548,24)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(548,22)); + return; + } + ivar3 = min(70, multiply(ivar2, 2)); + setWidgetPosition(7, ivar3, 0, 0, new WidgetPointer(548,24)); + setWidgetIsHidden(false, new WidgetPointer(548,24)); + return; +} diff --git a/dumps/scripts/337.cs2 b/dumps/scripts/337.cs2 new file mode 100644 index 0000000..e619fec --- /dev/null +++ b/dumps/scripts/337.cs2 @@ -0,0 +1,29 @@ +void script_337(int arg0,int arg1,int arg2) { + flow_0: + IF (((boolean)arg2)) + GOTO flow_1 + IF (((boolean)bitconfig_7232) && (arg1 > 0)) + GOTO flow_2 + GOTO flow_5 + flow_1: + flow_2: + if (arg1 < 10) { + setWidgetText(new WidgetPointer(548,26), formatNumber(arg0, 1) + "" + "(+0." + intToStr(arg1) + ")" + "" + "xp"); + setWidgetText(new WidgetPointer(746,189), formatNumber(arg0, 1) + "" + "(+0." + intToStr(arg1) + ")" + "" + "xp"); + setScriptCallOnGameloop(3369, new WidgetPointer(548,22), getClientCycle(), "Ii", new WidgetPointer(548,22)); + setScriptCallOnGameloop(3370, new WidgetPointer(746,184), getClientCycle(), "Ii", new WidgetPointer(746,184)); + return; + } + arg1 = divide(arg1, 10); + flow_5: + if (arg1 < 1) { + setWidgetText(new WidgetPointer(548,26), formatNumber(arg0, 1) + "" + "" + "xp"); + setWidgetText(new WidgetPointer(746,189), formatNumber(arg0, 1) + "" + "" + "xp"); + } else { + setWidgetText(new WidgetPointer(548,26), formatNumber(arg0, 1) + "" + "(+" + intToStr(arg1) + ")" + "" + "xp"); + setWidgetText(new WidgetPointer(746,189), formatNumber(arg0, 1) + "" + "(+" + intToStr(arg1) + ")" + "" + "xp"); + } + setScriptCallOnGameloop(3369, new WidgetPointer(548,22), getClientCycle(), "Ii", new WidgetPointer(548,22)); + setScriptCallOnGameloop(3370, new WidgetPointer(746,184), getClientCycle(), "Ii", new WidgetPointer(746,184)); + return; +} diff --git a/dumps/scripts/3370.cs2 b/dumps/scripts/3370.cs2 new file mode 100644 index 0000000..e25123b --- /dev/null +++ b/dumps/scripts/3370.cs2 @@ -0,0 +1,15 @@ +void script_3370(int arg0,int arg1) { + int ivar2; + int ivar3; + ivar2 = subtract(getClientCycle(), arg1); + ivar3 = 0; + if (ivar2 > 70) { + setWidgetIsHidden(true, new WidgetPointer(746,187)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(746,184)); + return; + } + ivar3 = min(70, multiply(ivar2, 2)); + setWidgetPosition(7, ivar3, 0, 0, new WidgetPointer(746,187)); + setWidgetIsHidden(false, new WidgetPointer(746,187)); + return; +} diff --git a/dumps/scripts/3371.cs2 b/dumps/scripts/3371.cs2 new file mode 100644 index 0000000..f1e0128 --- /dev/null +++ b/dumps/scripts/3371.cs2 @@ -0,0 +1,15 @@ +cs2func_script_3371_struct(2,0,0) script_3371(int arg0) { + if (((boolean)arg0)) { + cs2method5405(0, 3); + cs2method5405(1, 3); + cs2method5406(0, 0, 57609823, 380, 57740915, 445, 0); + cs2method5406(1, 0, 57527910, -15, 57577074, 10, 0); + cs2method5406(0, 1, 57396849, 715, 57151087, 775, 0); + cs2method5406(1, 1, 57151080, -45, 57085540, 210, 0); + script_1899(0, 75, 50); + cs2method5406(0, 2, 57396849, 715, 57151087, 775, 0); + cs2method5406(1, 2, 57151080, -45, 57085540, 210, 0); + script_1899(1, 50, 50); + } + return newstruct cs2func_script_3371_struct(57118312, 1250324); +} diff --git a/dumps/scripts/3372.cs2 b/dumps/scripts/3372.cs2 new file mode 100644 index 0000000..cabeafb --- /dev/null +++ b/dumps/scripts/3372.cs2 @@ -0,0 +1,15 @@ +cs2func_script_3372_struct(2,0,0) script_3372(int arg0) { + if (((boolean)arg0)) { + cs2method5405(0, 3); + cs2method5405(1, 3); + cs2method5406(0, 0, 57134673, 1210, 57019985, 1210, 0); + cs2method5406(1, 0, 56774236, 110, 56741471, 195, 0); + cs2method5406(0, 1, 56856155, 1210, 56839774, 1200, 0); + cs2method5406(1, 1, 56757863, 605, 56774251, 605, 0); + script_1899(0, 50, 50); + cs2method5406(0, 2, 56856155, 1210, 56839774, 1200, 0); + cs2method5406(1, 2, 56757863, 605, 56774251, 605, 0); + script_1899(1, 50, 50); + } + return newstruct cs2func_script_3372_struct(57118312, 1250324); +} diff --git a/dumps/scripts/3373.cs2 b/dumps/scripts/3373.cs2 new file mode 100644 index 0000000..10d03ff --- /dev/null +++ b/dumps/scripts/3373.cs2 @@ -0,0 +1,15 @@ +cs2func_script_3373_struct(2,0,0) script_3373(int arg0) { + if (((boolean)arg0)) { + cs2method5405(0, 3); + cs2method5405(1, 3); + cs2method5406(0, 0, 56249981, 1280, 56020596, 1270, 0); + cs2method5406(1, 0, 56184424, 690, 56135263, 685, 0); + cs2method5406(0, 1, 56200787, 1315, 56446535, 1315, 0); + cs2method5406(1, 1, 56397395, 645, 56561228, 610, 0); + script_1899(0, 50, 50); + cs2method5406(0, 2, 56200787, 1315, 56446535, 1315, 0); + cs2method5406(1, 2, 56397395, 645, 56561228, 610, 0); + script_1899(1, 50, 50); + } + return newstruct cs2func_script_3373_struct(56069736, 1250324); +} diff --git a/dumps/scripts/3374.cs2 b/dumps/scripts/3374.cs2 new file mode 100644 index 0000000..4e17cff --- /dev/null +++ b/dumps/scripts/3374.cs2 @@ -0,0 +1,18 @@ +cs2func_script_3374_struct(2,0,0) script_3374(int arg0) { + if (((boolean)arg0)) { + cs2method5405(0, 4); + cs2method5405(1, 4); + cs2method5406(0, 0, 55938707, 1545, 56004239, 1555, 0); + cs2method5406(1, 0, 56184460, 715, 56282762, 800, 0); + cs2method5406(0, 1, 56266371, 1960, 56462977, 2070, 0); + cs2method5406(1, 1, 56430224, 1155, 56495763, 1250, 0); + script_1899(0, 100, 100); + cs2method5406(0, 2, 56561294, 2200, 56577680, 2180, 0); + cs2method5406(1, 2, 56512160, 1245, 56512163, 1190, 0); + script_1899(1, 100, 100); + cs2method5406(0, 3, 56561294, 2200, 56577680, 2180, 0); + cs2method5406(1, 3, 56512160, 1245, 56512163, 1190, 0); + script_1899(2, 100, 100); + } + return newstruct cs2func_script_3374_struct(56069800, 1250324); +} diff --git a/dumps/scripts/3375.cs2 b/dumps/scripts/3375.cs2 new file mode 100644 index 0000000..4c59b88 --- /dev/null +++ b/dumps/scripts/3375.cs2 @@ -0,0 +1,5 @@ +void script_3375(int arg0,int arg1) { + setWidgetSize(arg0, arg1, 0, 0, new WidgetPointer(519,3)); + setWidgetPosition(add(16, divide(subtract(64, arg0), 2)), add(16, divide(subtract(64, arg1), 2)), 0, 0, new WidgetPointer(519,3)); + return; +} diff --git a/dumps/scripts/3376.cs2 b/dumps/scripts/3376.cs2 new file mode 100644 index 0000000..9407f09 --- /dev/null +++ b/dumps/scripts/3376.cs2 @@ -0,0 +1,14 @@ +void script_3376(int arg0) { + int ivar1; + int ivar2; + string svar0; + ivar1 = getWidgetActualWidth(new WidgetPointer(arg0)); + svar0 = strRemoveEntities(getWidgetText(new WidgetPointer(arg0))); + ivar2 = getLineCount(ivar1, 3793, svar0); + if (((boolean)ivar2)) { + setWidgetSize(getTextWidth(3793, svar0), 19, 0, 0, new WidgetPointer(arg0)); + } else { + setWidgetSize(ivar1, add(multiply(14, ivar2), 5), 0, 0, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/3377.cs2 b/dumps/scripts/3377.cs2 new file mode 100644 index 0000000..d284bf9 --- /dev/null +++ b/dumps/scripts/3377.cs2 @@ -0,0 +1,8 @@ +void script_3377() { + if (isWidgetHidden(new WidgetPointer(744,48)) || isWidgetHidden(new WidgetPointer(744,49))) { + script_2206(); + } else { + cs2method5411(); + } + return; +} diff --git a/dumps/scripts/3378.cs2 b/dumps/scripts/3378.cs2 new file mode 100644 index 0000000..b4adca4 --- /dev/null +++ b/dumps/scripts/3378.cs2 @@ -0,0 +1,6 @@ +void script_3378() { + setWidgetSprite(2560, new WidgetPointer(27,44)); + setWidgetSprite(2560, new WidgetPointer(27,45)); + setWidgetSprite(2561, new WidgetPointer(27,46)); + return; +} diff --git a/dumps/scripts/3379.cs2 b/dumps/scripts/3379.cs2 new file mode 100644 index 0000000..a8a76cd --- /dev/null +++ b/dumps/scripts/3379.cs2 @@ -0,0 +1,6 @@ +void script_3379() { + setWidgetSprite(2558, new WidgetPointer(27,44)); + setWidgetSprite(2558, new WidgetPointer(27,45)); + setWidgetSprite(2559, new WidgetPointer(27,46)); + return; +} diff --git a/dumps/scripts/338.cs2 b/dumps/scripts/338.cs2 new file mode 100644 index 0000000..a3f12f2 --- /dev/null +++ b/dumps/scripts/338.cs2 @@ -0,0 +1,66 @@ +int script_338(int arg0) { + if (arg0 == 23) { + return 1100; + } + if (bitconfig_7233 < 30) { + return 2700; + } + if (bitconfig_7233 < 60) { + return 2550; + } + if (bitconfig_7233 < 90) { + return 2400; + } + if (bitconfig_7233 < 120) { + return 2250; + } + if (bitconfig_7233 < 150) { + return 2100; + } + if (bitconfig_7233 < 180) { + return 2000; + } + if (bitconfig_7233 < 210) { + return 1900; + } + if (bitconfig_7233 < 240) { + return 1800; + } + if (bitconfig_7233 < 270) { + return 1700; + } + if (bitconfig_7233 < 300) { + return 1600; + } + if (bitconfig_7233 < 330) { + return 1500; + } + if (bitconfig_7233 < 360) { + return 1450; + } + if (bitconfig_7233 < 390) { + return 1400; + } + if (bitconfig_7233 < 420) { + return 1350; + } + if (bitconfig_7233 < 450) { + return 1300; + } + if (bitconfig_7233 < 480) { + return 1250; + } + if (bitconfig_7233 < 510) { + return 1200; + } + if (bitconfig_7233 < 540) { + return 1175; + } + if (bitconfig_7233 < 570) { + return 1150; + } + if (bitconfig_7233 < 600) { + return 1125; + } + return 1100; +} diff --git a/dumps/scripts/3380.cs2 b/dumps/scripts/3380.cs2 new file mode 100644 index 0000000..ce8e7ab --- /dev/null +++ b/dumps/scripts/3380.cs2 @@ -0,0 +1,4 @@ +void script_3380(string arg0) { + cs2method5421(1, arg0); + return; +} diff --git a/dumps/scripts/3381.cs2 b/dumps/scripts/3381.cs2 new file mode 100644 index 0000000..22bc8da --- /dev/null +++ b/dumps/scripts/3381.cs2 @@ -0,0 +1,10 @@ +void script_3381(int arg0,int arg1) { + arg1 = add(arg1, 1); + setScriptCallOnGameloop(3381, new WidgetPointer(arg0), arg1, "Ii", new WidgetPointer(arg0)); + if (arg1 > 1) { + globalint_1273 = 1; + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + script_2945(); + } + return; +} diff --git a/dumps/scripts/3382.cs2 b/dumps/scripts/3382.cs2 new file mode 100644 index 0000000..0ba50ec --- /dev/null +++ b/dumps/scripts/3382.cs2 @@ -0,0 +1,5 @@ +void script_3382(int arg0) { + setWidgetSprite(4661, new WidgetPointer(arg0)); + script_3087(arg0, -1); + return; +} diff --git a/dumps/scripts/3383.cs2 b/dumps/scripts/3383.cs2 new file mode 100644 index 0000000..0c8a0f3 --- /dev/null +++ b/dumps/scripts/3383.cs2 @@ -0,0 +1,4 @@ +void script_3383(int arg0) { + script_3384(arg0); + return; +} diff --git a/dumps/scripts/3384.cs2 b/dumps/scripts/3384.cs2 new file mode 100644 index 0000000..66e0d93 --- /dev/null +++ b/dumps/scripts/3384.cs2 @@ -0,0 +1,39 @@ +void script_3384(int arg0) { + int ivar1; + int ivar2; + opcStruct7000(2,0,0) structdump_0; + int stack_dump1; + int stack_dump2; + int stack_dump3; + cs2func_script_2692_struct(2,0,0) structdump_4; + ivar1 = 0; + ivar2 = 0; + structdump_0 = cs2method7000(); + ivar2 = structdump_0.intpart_1; + ivar1 = structdump_0.intpart_0; + script_2593(ivar1); + if (((boolean)ivar1) || (ivar1 == 3)) { + script_2700(1, arg0, 1, 0); + return; + } + globalint_1240 = 3; + globalint_1277 = 0; + cs2method6032(ivar1, 1); + if (arg0 == 3) { + if (hasSSKey()) { + script_1174(5); + setScriptCallOnGameloop(3381, new WidgetPointer(975,44), 0, "Ii", new WidgetPointer(975,44)); + } else if (((boolean)script_3487(1))) { + script_1174(11); + } else { + script_1174(11); + } + } else { + stack_dump1 = ivar1; + stack_dump2 = getDisplayMode(); + stack_dump3 = ivar1; + structdump_4 = script_2692(stack_dump3); + script_2596(stack_dump1, stack_dump2, structdump_4.intpart_0, structdump_4.intpart_1, arg0); + } + return; +} diff --git a/dumps/scripts/3385.cs2 b/dumps/scripts/3385.cs2 new file mode 100644 index 0000000..181fda4 --- /dev/null +++ b/dumps/scripts/3385.cs2 @@ -0,0 +1,34 @@ +void script_3385() { + string svar0; + openInterface(48758808, 976); + svar0 = ""; + if (cs2method6144()) { + svar0 = "There was a problem with your current graphic settings, so you have been given default settings for safety. Click below to auto-choose best graphics settings."; + setWidgetText(new WidgetPointer(976,4), svar0); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(976,2)), add(multiply(22, getLineCount(getWidgetActualWidth(new WidgetPointer(976,4)), 3793, svar0)), 86), 0, 0, new WidgetPointer(976,2)); + setWidgetSize(getTextWidth(3793, getWidgetText(new WidgetPointer(976,6))), getWidgetActualHeight(new WidgetPointer(976,6)), 0, 0, new WidgetPointer(976,6)); + } else if (((boolean)globalint_1277) && (globalint_1240 == -1)) { + svar0 = "This is your first time playing. Click below to auto-choose best graphics settings. Choose 'Leave Alone' to continue with default settings."; + setWidgetText(new WidgetPointer(976,4), svar0); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(976,2)), add(multiply(22, getLineCount(getWidgetActualWidth(new WidgetPointer(976,4)), 3793, svar0)), 86), 0, 0, new WidgetPointer(976,2)); + setWidgetSize(getTextWidth(3793, getWidgetText(new WidgetPointer(976,6))), getWidgetActualHeight(new WidgetPointer(976,6)), 0, 0, new WidgetPointer(976,6)); + } else if (globalint_1240 == -1) { + svar0 = "This is your first time playing, click below to auto choose best graphics settings."; + setWidgetText(new WidgetPointer(976,4), svar0); + setWidgetPosition(0, 10, 1, 0, new WidgetPointer(976,4)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(976,4)), 68, 0, 1, new WidgetPointer(976,4)); + setWidgetPosition(0, 17, 1, 2, new WidgetPointer(976,5)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(976,2)), add(multiply(22, getLineCount(getWidgetActualWidth(new WidgetPointer(976,4)), 3793, svar0)), 68), 0, 0, new WidgetPointer(976,2)); + setWidgetIsHidden(true, new WidgetPointer(976,6)); + } else { + svar0 = "Available graphics options have changed. Click below to auto choose best graphics settings."; + if (((boolean)globalint_1277)) { + svar0 = "Available graphics options have changed. Click below to auto-choose best graphics settings. Choose 'Leave Alone' to continue with your current settings."; + } + setWidgetText(new WidgetPointer(976,4), svar0); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(976,2)), add(multiply(22, getLineCount(getWidgetActualWidth(new WidgetPointer(976,4)), 3793, svar0)), 86), 0, 0, new WidgetPointer(976,2)); + setWidgetSize(getTextWidth(3793, getWidgetText(new WidgetPointer(976,6))), getWidgetActualHeight(new WidgetPointer(976,6)), 0, 0, new WidgetPointer(976,6)); + } + globalint_1277 = 1; + return; +} diff --git a/dumps/scripts/3386.cs2 b/dumps/scripts/3386.cs2 new file mode 100644 index 0000000..df8c338 --- /dev/null +++ b/dumps/scripts/3386.cs2 @@ -0,0 +1,4 @@ +void script_3386(int arg0,int arg1,int arg2,int arg3,int arg4) { + script_2596(arg0, arg1, arg2, arg3, arg4); + return; +} diff --git a/dumps/scripts/3387.cs2 b/dumps/scripts/3387.cs2 new file mode 100644 index 0000000..f574292 --- /dev/null +++ b/dumps/scripts/3387.cs2 @@ -0,0 +1,276 @@ +void script_3387(int arg0,int arg1,int arg2,int arg3,int arg4) { + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + int ivar22; + int ivar23; + int ivar24; + int ivar25; + int ivar26; + ivar5 = -1; + ivar6 = -1; + switch (arg4) { + case 1: + setWidgetText(new WidgetPointer(742,19), "Custom Graphics Options"); + openInterface(48627718, 977); + ivar5 = 48627716; + ivar6 = 48627732; + setScriptCallOnMousePressed(3386, arg0, arg1, arg2, arg3, arg4, "iiiii", new WidgetPointer(742,18)); + setWidgetContextMenuOption(1, new WidgetPointer(742,18), "Back"); + break; + case 0: + openInterface(57802780, 977); + ivar5 = 57802756; + ivar6 = 57802757; + setWidgetIsHidden(true, new WidgetPointer(882,29)); + setWidgetIsHidden(false, new WidgetPointer(882,23)); + setScriptCallOnMousePressed(3386, arg0, arg1, arg2, arg3, arg4, "iiiii", new WidgetPointer(882,23)); + setScriptCallOnWidgetResize(2917, 1, "1", new WidgetPointer(882,4)); + setScriptCallOnWidgetResize(2919, 1, arg4, "1i", new WidgetPointer(744,50)); + break; + case 2: + openInterface(59703298, 977); + ivar5 = 59703296; + ivar6 = 59703355; + setWidgetIsHidden(true, new WidgetPointer(911,5)); + setWidgetIsHidden(false, new WidgetPointer(911,3)); + setScriptCallOnMousePressed(3386, arg0, arg1, arg2, arg3, arg4, "iiiii", new WidgetPointer(911,3)); + setScriptCallOnWidgetResize(2919, 1, arg4, "1i", new WidgetPointer(906,23)); + script_4041(); + } + setWidgetIsHidden(true, new WidgetPointer(ivar6)); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(ivar5)); + ivar7 = 0; + ivar8 = 1; + ivar9 = -1; + ivar10 = -1; + ivar11 = -1; + ivar12 = -1; + ivar13 = -1; + setWidgetSprite(-1, new WidgetPointer(977,60)); + setWidgetSprite(-1, new WidgetPointer(977,56)); + setWidgetSprite(-1, new WidgetPointer(977,58)); + setWidgetSprite(-1, new WidgetPointer(977,54)); + setScriptCallOnMouseEntered(-1, "", new WidgetPointer(977,59)); + setScriptCallOnMouseEntered(-1, "", new WidgetPointer(977,55)); + setScriptCallOnMouseEntered(-1, "", new WidgetPointer(977,57)); + setScriptCallOnMouseEntered(-1, "", new WidgetPointer(977,53)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(977,59)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(977,55)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(977,57)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(977,53)); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(977,59)); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(977,55)); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(977,57)); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(977,53)); + if (cs2method7214()) { + switch (arg0) { + case 0: + script_1147(0, arg0, 64028721, 64028731, 64028732, arg4); + break; + case 2: + script_1147(2, arg0, 64028721, 64028731, 64028732, arg4); + break; + case 1: + script_1147(1, arg0, 64028721, 64028731, 64028732, arg4); + break; + case 3: + script_1147(3, arg0, 64028721, 64028731, 64028732, arg4); + } + setWidgetPosition(175, getWidgetActualY(new WidgetPointer(977,49)), 2, 0, new WidgetPointer(977,49)); + setWidgetSize(350, getWidgetActualHeight(new WidgetPointer(977,47)), 0, 0, new WidgetPointer(977,46)); + } else { + if (cs2method6147() || ((boolean)arg0)) { + ivar9 = 64028721; + script_1147(0, arg0, 64028721, 64028731, 64028732, arg4); + ivar7 = add(ivar7, 1); + } + while (ivar8 < 4) { + if (cs2method7314(ivar8) < 3) { + switch (ivar8) { + case 2: + ivar13 = 64028722; + script_1147(1, arg0, 64028722, 64028729, 64028730, arg4); + break; + case 1: + ivar13 = 64028723; + script_1147(2, arg0, 64028723, 64028727, 64028728, arg4); + break; + case 3: + ivar13 = 64028724; + script_1147(3, arg0, 64028724, 64028725, 64028726, arg4); + } + ivar7 = add(ivar7, 1); + if (ivar9 == -1) { + ivar9 = ivar13; + } else if (ivar10 == -1) { + ivar10 = ivar13; + } else if (ivar11 == -1) { + ivar11 = ivar13; + } else { + if (ivar12 == -1) { + ivar12 = ivar13; + } + } + } + ivar8 = add(ivar8, 1); + } + switch (ivar7) { + case 1: + setWidgetPosition(175, getWidgetActualY(new WidgetPointer(ivar9)), 2, 0, new WidgetPointer(ivar9)); + setWidgetSize(350, getWidgetActualHeight(new WidgetPointer(977,47)), 0, 0, new WidgetPointer(977,46)); + break; + case 2: + setWidgetPosition(90, getWidgetActualY(new WidgetPointer(ivar9)), 0, 0, new WidgetPointer(ivar9)); + setWidgetPosition(90, getWidgetActualY(new WidgetPointer(ivar10)), 2, 0, new WidgetPointer(ivar10)); + setWidgetSize(400, getWidgetActualHeight(new WidgetPointer(977,47)), 0, 0, new WidgetPointer(977,46)); + break; + case 3: + setWidgetPosition(58, getWidgetActualY(new WidgetPointer(ivar9)), 0, 0, new WidgetPointer(ivar9)); + setWidgetPosition(173, getWidgetActualY(new WidgetPointer(ivar10)), 2, 0, new WidgetPointer(ivar10)); + setWidgetPosition(58, getWidgetActualY(new WidgetPointer(ivar11)), 2, 0, new WidgetPointer(ivar11)); + setWidgetSize(400, getWidgetActualHeight(new WidgetPointer(977,47)), 0, 0, new WidgetPointer(977,46)); + } + } + ivar14 = 0; + ivar15 = -1; + ivar16 = 64028700; + ivar17 = 64028699; + deleteAllExtraChilds(new WidgetPointer(ivar16)); + deleteAllExtraChilds(new WidgetPointer(ivar17)); + script_2601(0, ivar14, ivar16, "Brightness"); + script_1185(64028704, 64028705); + cs2method2301(64028704, -1, new WidgetPointer(977,33)); + ivar18 = 1; + ivar19 = add(arg3, 21); + ivar20 = -1; + ivar21 = -1; + ivar22 = -1; + ivar23 = 0; + ivar24 = 0; + ivar25 = 0; + ivar26 = -1; + while (ivar24 < getCommonDefinitionSize(201)) { + ivar21 = cs2method_3408(105, 74, 201, ivar24); + ivar20 = script_2601(ivar18, ivar14, ivar16, getOtherCommonData(ivar21, 845)); + createExtraChild(new WidgetPointer(ivar16), 3, getExtraChildGap(new WidgetPointer(ivar16))); + setWidgetSize(ivar19, 16, 0, 0); + if (((boolean)ivar18)) { + setWidgetPosition(4, ivar14, 2, 0); + } else { + setWidgetPosition(subtract(233, ivar19), ivar14, 0, 0); + } + setWidgetFilled(1); + setWidgetRGB(new Color(46, 43, 38)); + createExtraChild(new WidgetPointer(ivar16), 3, getExtraChildGap(new WidgetPointer(ivar16))); + setWidgetSize(getWidgetActualWidth(), getWidgetActualHeight(), 0, 0); + setWidgetPosition(getWidgetActualX(), getWidgetActualY(), 0, 0); + setWidgetFilled(0); + setWidgetRGB(new Color(95, 91, 82)); + ivar15 = getWidgetCustomChildArrayIndex(); + createExtraChild(new WidgetPointer(ivar16), 4, getExtraChildGap(new WidgetPointer(ivar16))); + setWidgetFont(494); + setWidgetTextAlignment(1, 1, 0); + ivar23 = script_2581(ivar21); + if (ivar23 <= -1) { + setWidgetSize(getWidgetActualWidth(), getWidgetActualHeight(), 0, 0); + setWidgetPosition(getWidgetActualX(), getWidgetActualY(), 0, 0); + setWidgetRGB(new Color(235, 224, 188)); + setWidgetText("" + "N/A"); + } else { + setWidgetSize(arg3, getWidgetActualHeight(), 0, 0); + setWidgetPosition(add(getWidgetActualX(), 2), getWidgetActualY(), 0, 0); + ivar22 = getOtherCommonData(ivar21, 683); + ivar25 = script_829(ivar21, ivar22); + if (ivar21 != 1009) { + if (ivar23 < ivar25) { + setWidgetRGB(new Color(235, 224, 188)); + } else { + setWidgetRGB(new Color(0, 177, 225)); + } + } else if (ivar23 > 0) { + setWidgetRGB(new Color(235, 224, 188)); + } else { + setWidgetRGB(new Color(0, 177, 225)); + } + if (((int)isBitFlagged(getOtherCommonData(ivar21, 682), arg0)) != 1) { + setWidgetText("" + "N/A"); + setWidgetSize(getWidgetActualWidth(), getWidgetActualHeight(), 0, 0); + setWidgetPosition(getWidgetActualX(), getWidgetActualY(), 0, 0); + } else { + setWidgetText(cs2method_3408(105, 115, ivar22, ivar23)); + createExtraChild(new WidgetPointer(ivar16), 5, getExtraChildGap(new WidgetPointer(ivar16))); + setWidgetSize(16, 16, 0, 0); + setWidgetPosition(subtract(add(getWidgetActualX(), getWidgetActualWidth()), add(getWidgetActualWidth(), 1)), add(ivar14, divide(subtract(16, getWidgetActualHeight()), 2)), 0, 0); + setWidgetSprite(2554); + setScriptCallOnMouseEntered(2691, new WidgetPointer(-32768,3), getWidgetCustomChildArrayIndex(), 1, ivar15, 8419437, 1, "Ii1ii1"); + setScriptCallOnMouseExit(2691, new WidgetPointer(-32768,3), getWidgetCustomChildArrayIndex(), 0, ivar15, 6249298, 1, "Ii1ii1"); + setScriptCallOnMousePressed(2695, new WidgetPointer(-32768,3), -2147483643, getWidgetCustomChildArrayIndex(), ivar15, ivar20, ivar21, arg2, arg3, arg0, arg1, arg4, "IiiiiJiiiii"); + } + } + if (((boolean)ivar18)) { + ivar18 = 0; + ivar14 = add(ivar14, 20); + ivar26 = getExtraChildGap(new WidgetPointer(ivar17)); + createExtraChild(new WidgetPointer(ivar17), 3, ivar26); + setWidgetSize(2, 1, 1, 0); + setWidgetPosition(1, add(ivar14, 3), 0, 0); + setWidgetFilled(1); + setWidgetRGB(new Color(128, 120, 109)); + } else { + ivar18 = 1; + } + ivar24 = add(ivar24, 1); + } + if (((boolean)ivar18)) { + ivar14 = add(ivar14, 20); + } + if (((ivar26 != -1) && ((boolean)ivar18)) && setWidgetRegister(new WidgetPointer(ivar17), ivar26)) { + deleteExtraChild(); + } + setWidgetSize(getWidgetActualWidth(new WidgetPointer(977,26)), add(ivar14, 5), 0, 0, new WidgetPointer(977,26)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(977,24)), add(getWidgetActualY(new WidgetPointer(977,26)), getWidgetActualHeight(new WidgetPointer(977,26))), 0, 0, new WidgetPointer(977,24)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(977,3)), add(getWidgetActualY(new WidgetPointer(977,24)), getWidgetActualHeight(new WidgetPointer(977,24))), 0, 0, new WidgetPointer(977,3)); + switch (arg4) { + case 1: + setWidgetSize(getWidgetActualWidth(new WidgetPointer(742,4)), 334, 0, 0, new WidgetPointer(742,4)); + setWidgetPosition(0, getWidgetActualY(new WidgetPointer(977,2)), 0, 0, new WidgetPointer(977,2)); + setWidgetSize(20, subtract(getWidgetActualHeight(new WidgetPointer(742,6)), getWidgetActualHeight(new WidgetPointer(977,1))), 1, 0, new WidgetPointer(977,2)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(977,0)), getWidgetActualHeight(new WidgetPointer(742,6)), 0, 0, new WidgetPointer(977,0)); + setWidgetScrollMax(0, add(getWidgetActualHeight(new WidgetPointer(977,3)), 5), new WidgetPointer(977,2)); + script_31(64028742, 64028674, 792, 789, 790, 791, 773, 788); + break; + case 0: + setWidgetPosition(0, 0, 1, 0, new WidgetPointer(977,0)); + setWidgetPosition(0, 0, 1, 0, new WidgetPointer(882,28)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(977,2)), getWidgetActualHeight(new WidgetPointer(977,3)), 0, 0, new WidgetPointer(977,2)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(977,0)), add(getWidgetActualY(new WidgetPointer(977,2)), getWidgetActualHeight(new WidgetPointer(977,2))), 0, 0, new WidgetPointer(977,0)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(882,28)), add(add(getWidgetActualHeight(new WidgetPointer(977,0)), 15), getWidgetActualHeight(new WidgetPointer(882,23))), 0, 0, new WidgetPointer(882,28)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(882,22)), add(getWidgetActualHeight(new WidgetPointer(882,28)), 5), 0, 0, new WidgetPointer(882,22)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(882,8)), add(40, getWidgetActualHeight(new WidgetPointer(882,22))), 0, 0, new WidgetPointer(882,8)); + setWidgetPosition(0, 10, 1, 1, new WidgetPointer(882,22)); + break; + case 2: + setWidgetPosition(0, 0, 1, 0, new WidgetPointer(977,0)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(977,2)), getWidgetActualHeight(new WidgetPointer(977,3)), 0, 0, new WidgetPointer(977,2)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(977,0)), add(getWidgetActualY(new WidgetPointer(977,2)), getWidgetActualHeight(new WidgetPointer(977,2))), 0, 0, new WidgetPointer(977,0)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(911,2)), add(add(getWidgetActualHeight(new WidgetPointer(977,0)), 2), getWidgetActualHeight(new WidgetPointer(911,3))), 0, 0, new WidgetPointer(911,2)); + } + script_3451(arg4, 1); + script_2918(1); + return; +} diff --git a/dumps/scripts/3388.cs2 b/dumps/scripts/3388.cs2 new file mode 100644 index 0000000..34277c2 --- /dev/null +++ b/dumps/scripts/3388.cs2 @@ -0,0 +1,78 @@ +void script_3388(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int stack_dump0; + int stack_dump1; + int stack_dump2; + cs2func_script_2692_struct(2,0,0) structdump_3; + cs2func_script_2692_struct(2,0,0) structdump_4; + ivar3 = 4; + switch (arg0) { + case 1: + if (cs2method7007() != 1) { + cs2method7004(); + } else { + return; + } + break; + case 2: + if (ivar3 >= 2) { + if (cs2method7007() != 2) { + cs2method7003(); + } else { + return; + } + } else { + script_3413(arg1); + } + break; + case 3: + if (ivar3 >= 3) { + if (cs2method7007() != 3) { + cs2method7002(); + } else { + return; + } + } else { + script_3413(arg1); + } + break; + case 4: + if (ivar3 >= 4) { + if (cs2method7007() != 4) { + cs2method7001(); + } else { + return; + } + } else { + script_3413(arg1); + } + break; + case 0: + if (((boolean)arg2)) { + if (cs2method7007() != 0) { + cs2method7005(); + } else { + return; + } + } + break; + case -1: + script_3384(arg1); + } + ivar4 = cs2method6131(); + if (((boolean)arg0) || ((boolean)arg2)) { + stack_dump0 = ivar4; + stack_dump1 = getDisplayMode(); + stack_dump2 = ivar4; + structdump_3 = script_2692(stack_dump2); + script_3387(stack_dump0, stack_dump1, structdump_3.intpart_0, structdump_3.intpart_1, arg1); + } else { + stack_dump0 = ivar4; + stack_dump1 = getDisplayMode(); + stack_dump2 = ivar4; + structdump_4 = script_2692(stack_dump2); + script_2596(stack_dump0, stack_dump1, structdump_4.intpart_0, structdump_4.intpart_1, arg1); + } + return; +} diff --git a/dumps/scripts/3389.cs2 b/dumps/scripts/3389.cs2 new file mode 100644 index 0000000..8f08823 --- /dev/null +++ b/dumps/scripts/3389.cs2 @@ -0,0 +1,4 @@ +void script_3389(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + script_3390(arg0, arg1, arg2, arg3, arg4, arg5); + return; +} diff --git a/dumps/scripts/339.cs2 b/dumps/scripts/339.cs2 new file mode 100644 index 0000000..47f6da4 --- /dev/null +++ b/dumps/scripts/339.cs2 @@ -0,0 +1,6 @@ +void script_339() { + setWidgetSprite(3165, new WidgetPointer(205,54)); + setWidgetSprite(3165, new WidgetPointer(205,55)); + setWidgetSprite(3166, new WidgetPointer(205,56)); + return; +} diff --git a/dumps/scripts/3390.cs2 b/dumps/scripts/3390.cs2 new file mode 100644 index 0000000..01509bf --- /dev/null +++ b/dumps/scripts/3390.cs2 @@ -0,0 +1,12 @@ +void script_3390(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + if (arg0 != -1) { + setWidgetSprite(arg1, new WidgetPointer(arg0)); + } + if (arg2 != -1) { + setWidgetSprite(arg3, new WidgetPointer(arg2)); + } + if (arg4 != -1) { + setWidgetSprite(arg5, new WidgetPointer(arg4)); + } + return; +} diff --git a/dumps/scripts/3391.cs2 b/dumps/scripts/3391.cs2 new file mode 100644 index 0000000..edf311d --- /dev/null +++ b/dumps/scripts/3391.cs2 @@ -0,0 +1,8 @@ +void script_3391() { + closeInterface(59375670); + setWidgetIsHidden(true, new WidgetPointer(906,46)); + if (isWidgetHidden(cs2method_3408(105, 73, 941, 5))) { + script_3161(1); + } + return; +} diff --git a/dumps/scripts/3392.cs2 b/dumps/scripts/3392.cs2 new file mode 100644 index 0000000..416defb --- /dev/null +++ b/dumps/scripts/3392.cs2 @@ -0,0 +1,6 @@ +void script_3392(int arg0) { + if (setWidgetRegister(new WidgetPointer(979,26), arg0)) { + cs2method2103(0); + } + return; +} diff --git a/dumps/scripts/3393.cs2 b/dumps/scripts/3393.cs2 new file mode 100644 index 0000000..c6b2a0d --- /dev/null +++ b/dumps/scripts/3393.cs2 @@ -0,0 +1,6 @@ +void script_3393(int arg0) { + if (setWidgetRegister(new WidgetPointer(979,26), arg0)) { + cs2method2103(255); + } + return; +} diff --git a/dumps/scripts/3394.cs2 b/dumps/scripts/3394.cs2 new file mode 100644 index 0000000..448c95b --- /dev/null +++ b/dumps/scripts/3394.cs2 @@ -0,0 +1,4 @@ +void script_3394(int arg0) { + globalint_791 = arg0; + return; +} diff --git a/dumps/scripts/3395.cs2 b/dumps/scripts/3395.cs2 new file mode 100644 index 0000000..dbc5ab3 --- /dev/null +++ b/dumps/scripts/3395.cs2 @@ -0,0 +1,14 @@ +void script_3395() { + int ivar0; + ivar0 = 0; + while (ivar0 < getExtraChildGap(new WidgetPointer(979,25))) { + if (setWidgetRegister(new WidgetPointer(979,25), ivar0)) { + cs2method2103(255); + } + ivar0 = add(ivar0, 1); + } + if (setWidgetRegister(new WidgetPointer(979,25), globalint_792)) { + cs2method2103(0); + } + return; +} diff --git a/dumps/scripts/3396.cs2 b/dumps/scripts/3396.cs2 new file mode 100644 index 0000000..f5a1fb4 --- /dev/null +++ b/dumps/scripts/3396.cs2 @@ -0,0 +1,13 @@ +void script_3396(int arg0) { + int ivar1; + string svar0; + svar0 = ""; + ivar1 = -1; + if (setWidgetRegister(new WidgetPointer(979,27), arg0)) { + globalstring_279 = cs2method1802(); + globalint_792 = globalint_791; + script_3395(); + script_3397(); + } + return; +} diff --git a/dumps/scripts/3397.cs2 b/dumps/scripts/3397.cs2 new file mode 100644 index 0000000..cb80004 --- /dev/null +++ b/dumps/scripts/3397.cs2 @@ -0,0 +1,23 @@ +void script_3397() { + int ivar0; + int ivar1; + setWidgetText(new WidgetPointer(979,18), globalstring_279); + ivar0 = 2568; + ivar1 = 2569; + if (stringMethod4107(globalstring_279, "") != 0) { + setWidgetText(new WidgetPointer(979,40), "Reporting: " + globalstring_279); + cs2method2103(0, new WidgetPointer(979,10)); + cs2method2103(0, new WidgetPointer(979,11)); + cs2method2103(0, new WidgetPointer(979,12)); + cs2method2103(0, new WidgetPointer(979,13)); + setScriptCallOnMouseEntered(3071, new WidgetPointer(979,10), ivar0, new WidgetPointer(979,11), ivar1, new WidgetPointer(979,12), ivar0, "IdIdId", new WidgetPointer(979,9)); + } else { + setWidgetText(new WidgetPointer(979,40), "Report Abuse: Select Player"); + cs2method2103(100, new WidgetPointer(979,10)); + cs2method2103(100, new WidgetPointer(979,11)); + cs2method2103(100, new WidgetPointer(979,12)); + cs2method2103(100, new WidgetPointer(979,13)); + setScriptCallOnMouseEntered(-1, "", new WidgetPointer(979,9)); + } + return; +} diff --git a/dumps/scripts/3398.cs2 b/dumps/scripts/3398.cs2 new file mode 100644 index 0000000..da044cd --- /dev/null +++ b/dumps/scripts/3398.cs2 @@ -0,0 +1,18 @@ +void script_3398(int arg0,int arg1,int arg2) { + switch (arg0) { + case 84: + script_3400(); + return; + case 13: + if (isWidgetHidden(new WidgetPointer(915,102))) { + script_3198(64159808, 64159809, 64159795, 64159787, 64159744); + } else { + script_3391(); + } + return; + case 1: + script_3196(2, 64159808, 64159809, 64159795, 64159787, 64159744); + return; + } + return; +} diff --git a/dumps/scripts/3399.cs2 b/dumps/scripts/3399.cs2 new file mode 100644 index 0000000..baf802c --- /dev/null +++ b/dumps/scripts/3399.cs2 @@ -0,0 +1,4 @@ +void script_3399() { + script_3400(); + return; +} diff --git a/dumps/scripts/34.cs2 b/dumps/scripts/34.cs2 new file mode 100644 index 0000000..f9b92d3 --- /dev/null +++ b/dumps/scripts/34.cs2 @@ -0,0 +1,6 @@ +void script_34(int arg0,int arg1,int arg2) { + if (setWidgetRegister(new WidgetPointer(arg0), 1)) { + cs2method3109(0, divide(getWidgetActualHeight(), 2)); + } + return; +} diff --git a/dumps/scripts/340.cs2 b/dumps/scripts/340.cs2 new file mode 100644 index 0000000..0f0dbcc --- /dev/null +++ b/dumps/scripts/340.cs2 @@ -0,0 +1,6 @@ +void script_340() { + setWidgetSprite(3163, new WidgetPointer(205,54)); + setWidgetSprite(3163, new WidgetPointer(205,55)); + setWidgetSprite(3164, new WidgetPointer(205,56)); + return; +} diff --git a/dumps/scripts/3400.cs2 b/dumps/scripts/3400.cs2 new file mode 100644 index 0000000..6887b74 --- /dev/null +++ b/dumps/scripts/3400.cs2 @@ -0,0 +1,8 @@ +void script_3400() { + if (strLength(globalstring_279) <= 0) { + return; + } + script_3391(); + script_3190(); + return; +} diff --git a/dumps/scripts/3401.cs2 b/dumps/scripts/3401.cs2 new file mode 100644 index 0000000..7366467 --- /dev/null +++ b/dumps/scripts/3401.cs2 @@ -0,0 +1,11 @@ +void script_3401() { + if ((globalint_1274 < 0) || (globalint_1274 > subtract(getWidgetActualHeight(new WidgetPointer(909,61)), getWidgetActualHeight(new WidgetPointer(909,62))))) { + script_3404(); + } else { + script_3403(globalint_1274, 1); + } + cs2method2301(59572285, -1, new WidgetPointer(909,62)); + setScriptCallOnMouseDragged(3402, -2147483646, 0, "i1", new WidgetPointer(909,62)); + setScriptCallOnMouseDragReleased(3402, -2147483646, 1, "i1", new WidgetPointer(909,62)); + return; +} diff --git a/dumps/scripts/3402.cs2 b/dumps/scripts/3402.cs2 new file mode 100644 index 0000000..f8ba654 --- /dev/null +++ b/dumps/scripts/3402.cs2 @@ -0,0 +1,11 @@ +void script_3402(int arg0,int arg1) { + if (((boolean)arg1)) { + if (arg0 < 0) { + arg0 = 0; + } else { + arg0 = subtract(arg0, mod(arg0, 15)); + } + } + script_3403(arg0, arg1); + return; +} diff --git a/dumps/scripts/3403.cs2 b/dumps/scripts/3403.cs2 new file mode 100644 index 0000000..63d5776 --- /dev/null +++ b/dumps/scripts/3403.cs2 @@ -0,0 +1,24 @@ +void script_3403(int arg0,int arg1) { + int ivar2; + int ivar3; + ivar2 = subtract(subtract(subtract(subtract(getWidgetActualHeight(new WidgetPointer(909,13)), getWidgetActualY(new WidgetPointer(909,61))), 35), arg0), 7); + if (((boolean)arg1)) { + ivar2 = subtract(ivar2, mod(ivar2, 15)); + } + if (ivar2 < 113) { + ivar2 = 113; + } + setWidgetSize(20, ivar2, 1, 0, new WidgetPointer(909,49)); + globalint_1274 = arg0; + setWidgetPosition(0, subtract(subtract(getWidgetActualY(new WidgetPointer(909,49)), getWidgetActualY(new WidgetPointer(909,61))), 7), 0, 0, new WidgetPointer(909,62)); + ivar3 = subtract(ivar2, 8); + ivar3 = subtract(ivar3, mod(ivar3, 15)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(909,52)), ivar3, 0, 0, new WidgetPointer(909,52)); + globalint_1122 = subtract(globalint_1122, subtract(ivar3, ivar3)); + script_3054(59572273); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(909,16)), add(ivar2, 86), 0, 1, new WidgetPointer(909,16)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(909,48)), add(ivar2, 86), 0, 1, new WidgetPointer(909,48)); + script_3029(59572269, 59572268, 59572270, 59572266, 59572265, 59572271); + script_3041(59572311, 59572310, 59572308, 59572302, 59572303); + return; +} diff --git a/dumps/scripts/3404.cs2 b/dumps/scripts/3404.cs2 new file mode 100644 index 0000000..83f1164 --- /dev/null +++ b/dumps/scripts/3404.cs2 @@ -0,0 +1,4 @@ +void script_3404() { + script_3403(subtract(getWidgetActualHeight(new WidgetPointer(909,61)), getWidgetActualHeight(new WidgetPointer(909,62))), 1); + return; +} diff --git a/dumps/scripts/3405.cs2 b/dumps/scripts/3405.cs2 new file mode 100644 index 0000000..fd15e03 --- /dev/null +++ b/dumps/scripts/3405.cs2 @@ -0,0 +1,29 @@ +void script_3405(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + cs2func_script_3406_struct(3,0,0) structdump_0; + ivar3 = 0; + ivar4 = 0; + ivar5 = 0; + structdump_0 = script_3406(); + ivar5 = structdump_0.intpart_2; + ivar4 = structdump_0.intpart_1; + ivar3 = structdump_0.intpart_0; + script_3054(arg0); + script_3173(arg1); + script_4567(arg2); + if (isWidgetHidden(new WidgetPointer(906,187)) && (ivar3 > globalint_1275)) { + setScriptCallOnGameloop(3407, getClientCycle(), new WidgetPointer(906,187), new WidgetPointer(-32768,3), "iII", new WidgetPointer(906,201)); + } + if (isWidgetHidden(new WidgetPointer(906,189)) && (ivar4 > globalint_1276)) { + setScriptCallOnGameloop(3407, getClientCycle(), new WidgetPointer(906,189), new WidgetPointer(-32768,3), "iII", new WidgetPointer(906,203)); + } + if (isWidgetHidden(new WidgetPointer(906,188)) && (ivar5 > globalint_1510)) { + setScriptCallOnGameloop(3407, getClientCycle(), new WidgetPointer(906,188), new WidgetPointer(-32768,3), "iII", new WidgetPointer(906,202)); + } + globalint_1275 = ivar3; + globalint_1276 = ivar4; + globalint_1510 = ivar5; + return; +} diff --git a/dumps/scripts/3406.cs2 b/dumps/scripts/3406.cs2 new file mode 100644 index 0000000..9a7ccdc --- /dev/null +++ b/dumps/scripts/3406.cs2 @@ -0,0 +1,30 @@ +cs2func_script_3406_struct(3,0,0) script_3406() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + ivar0 = 0; + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + while (ivar3 < 100) { + switch (cs2method5004(ivar3)) { + case 18: + case 3: + case 7: + ivar0 = add(ivar0, 1); + break; + case 20: + case 9: + ivar2 = add(ivar2, 1); + break; + case 42: + case 41: + case 44: + case 45: + ivar1 = add(ivar1, 1); + } + ivar3 = add(ivar3, 1); + } + return newstruct cs2func_script_3406_struct(ivar0, ivar1, ivar2); +} diff --git a/dumps/scripts/3407.cs2 b/dumps/scripts/3407.cs2 new file mode 100644 index 0000000..60a7f66 --- /dev/null +++ b/dumps/scripts/3407.cs2 @@ -0,0 +1,24 @@ +void script_3407(int arg0,int arg1,int arg2) { + if (isWidgetHidden(new WidgetPointer(arg1))) { + deleteAllExtraChilds(new WidgetPointer(arg2)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg2)); + return; + } + if (mod(subtract(getClientCycle(), arg0), 40) < 20) { + if (setWidgetRegister(new WidgetPointer(arg2), 0)) { + setWidgetHidden(0); + } else { + createExtraChild(new WidgetPointer(arg2), 3, 0); + setWidgetSize(4, 2, 1, 1); + setWidgetPosition(0, 0, 1, 2); + setWidgetFilled(1); + cs2method2103(225); + setWidgetRGB(new Color(255, 255, 255)); + } + } else { + if (setWidgetRegister(new WidgetPointer(arg2), 0)) { + setWidgetHidden(1); + } + } + return; +} diff --git a/dumps/scripts/3408.cs2 b/dumps/scripts/3408.cs2 new file mode 100644 index 0000000..76f383e --- /dev/null +++ b/dumps/scripts/3408.cs2 @@ -0,0 +1,12 @@ +void script_3408(int arg0,string arg1) { + string svar1; + string svar2; + svar1 = "" + arg1 + ""; + svar2 = "" + arg1 + ""; + setWidgetContextMenuOption(1, new WidgetPointer(arg0), "Open link"); + setScriptCallOnClickContextMenu(1897, "", new WidgetPointer(arg0)); + cs2method2309(1, 146, new WidgetPointer(arg0)); + setScriptCallOnMouseEntered(2381, new WidgetPointer(arg0), 8978431, svar1, "Iis", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(2381, new WidgetPointer(arg0), 6605050, svar2, "Iis", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/3409.cs2 b/dumps/scripts/3409.cs2 new file mode 100644 index 0000000..5260475 --- /dev/null +++ b/dumps/scripts/3409.cs2 @@ -0,0 +1,9 @@ +void script_3409(int arg0) { + string svar0; + svar0 = "Access Forums"; + script_3408(arg0, svar0); + setWidgetSize(getTextWidth(495, svar0), getWidgetActualHeight(new WidgetPointer(arg0)), 0, 0, new WidgetPointer(arg0)); + setWidgetText(new WidgetPointer(arg0), "" + svar0 + ""); + setScriptCallOnClickContextMenu(3410, "", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/341.cs2 b/dumps/scripts/341.cs2 new file mode 100644 index 0000000..7624b1d --- /dev/null +++ b/dumps/scripts/341.cs2 @@ -0,0 +1,6 @@ +void script_341() { + setWidgetSprite(3165, new WidgetPointer(205,50)); + setWidgetSprite(3165, new WidgetPointer(205,51)); + setWidgetSprite(3166, new WidgetPointer(205,52)); + return; +} diff --git a/dumps/scripts/3410.cs2 b/dumps/scripts/3410.cs2 new file mode 100644 index 0000000..31640f6 --- /dev/null +++ b/dumps/scripts/3410.cs2 @@ -0,0 +1,4 @@ +void script_3410() { + cs2method5400(0, "forum", "forums.ws"); + return; +} diff --git a/dumps/scripts/3411.cs2 b/dumps/scripts/3411.cs2 new file mode 100644 index 0000000..e15c458 --- /dev/null +++ b/dumps/scripts/3411.cs2 @@ -0,0 +1,16 @@ +void script_3411() { + globalint_1240 = 3; + globalint_1277 = 0; + if (hasSSKey()) { + script_1174(5); + if (((boolean)globalint_1273)) { + return; + } + setScriptCallOnGameloop(3381, new WidgetPointer(975,44), 0, "Ii", new WidgetPointer(975,44)); + } else if (((boolean)script_3487(3))) { + script_1174(7); + } else { + script_1174(11); + } + return; +} diff --git a/dumps/scripts/3412.cs2 b/dumps/scripts/3412.cs2 new file mode 100644 index 0000000..91ceb90 --- /dev/null +++ b/dumps/scripts/3412.cs2 @@ -0,0 +1,5 @@ +void script_3412(int arg0,int arg1) { + setWidgetText(new WidgetPointer(arg0), "High-risk Wilderness World"); + setWidgetText(new WidgetPointer(arg1), "Warning: This is a High-risk Wilderness world." + "
" + "
" + "While you are in the Wilderness on this world, you will not be permitted to use the Protect Item prayer or curse, so you may lose ALL your items when you die." + "
" + "
" + "You have been warned!"); + return; +} diff --git a/dumps/scripts/3413.cs2 b/dumps/scripts/3413.cs2 new file mode 100644 index 0000000..c2565fa --- /dev/null +++ b/dumps/scripts/3413.cs2 @@ -0,0 +1,9 @@ +void script_3413(int arg0) { + if (((boolean)arg0)) { + script_2694(arg0, 1, "This setting is not available in your current version of Java.", "", ""); + script_2694(arg0, 1, "Please update to the latest version.", "", ""); + } else { + script_2694(arg0, 1, "This setting is not available in your current version of Java." + "
" + "
" + "Please update to the latest version, or try our Windows Client available from the link below.", "Download Windows Client", "kbase/view.ws?guid=Downloads_and_Wallpapers"); + } + return; +} diff --git a/dumps/scripts/3414.cs2 b/dumps/scripts/3414.cs2 new file mode 100644 index 0000000..86e010b --- /dev/null +++ b/dumps/scripts/3414.cs2 @@ -0,0 +1,6 @@ +void script_3414(int arg0) { + if (bitconfig_7868 == 2) { + setWidgetModel(57477, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/3415.cs2 b/dumps/scripts/3415.cs2 new file mode 100644 index 0000000..28543c3 --- /dev/null +++ b/dumps/scripts/3415.cs2 @@ -0,0 +1,24 @@ +cs2func_script_3415_struct(2,0,0) script_3415(int arg0) { + if (((boolean)arg0)) { + cs2method5405(0, 6); + cs2method5405(1, 6); + cs2method5406(0, 0, 39670136, 800, 39588214, 835, 0); + cs2method5406(1, 0, 39440756, 415, 39375218, 430, 0); + cs2method5406(0, 1, 39424372, 985, 39375219, 930, 0); + cs2method5406(1, 1, 39244140, 458, 39162214, 458, 0); + script_1899(0, 150, 150); + cs2method5406(0, 2, 39211370, 1025, 39145827, 810, 1200); + cs2method5406(1, 2, 39293279, 430, 39342430, 415, 0); + script_1899(1, 150, 150); + cs2method5406(0, 3, 39293278, 670, 39391581, 630, 400); + cs2method5406(1, 3, 39489881, 346, 39539030, 346, 0); + script_1899(2, 150, 150); + cs2method5406(0, 4, 39522648, 1150, 39571795, 1490, -600); + cs2method5406(1, 4, 39522637, 394, 39522637, 394, 0); + script_1899(3, 150, 150); + cs2method5406(0, 5, 39522635, 475, 39506249, 0, 0); + cs2method5406(1, 5, 39522635, 330, 39522633, 330, 0); + script_1899(4, 150, 150); + } + return newstruct cs2func_script_3415_struct(39293279, 0); +} diff --git a/dumps/scripts/3416.cs2 b/dumps/scripts/3416.cs2 new file mode 100644 index 0000000..7a161b6 --- /dev/null +++ b/dumps/scripts/3416.cs2 @@ -0,0 +1,5 @@ +void script_3416(int arg0) { + setWidgetSprite(3153, new WidgetPointer(arg0)); + setScriptCallOnMousePressed(1242, new WidgetPointer(-32768,3), "I", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/3417.cs2 b/dumps/scripts/3417.cs2 new file mode 100644 index 0000000..478145b --- /dev/null +++ b/dumps/scripts/3417.cs2 @@ -0,0 +1,16 @@ +void script_3417(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7) { + if (arg0 != 1) { + return; + } + if (standart_config_287 == arg1) { + if (((boolean)arg1)) { + arg1 = 1; + } else { + return; + } + } + standart_config_287 = arg1; + playSoundEffect(2266, 1, 0); + script_2735(arg2, arg3, arg4, arg5, arg6, arg7); + return; +} diff --git a/dumps/scripts/3418.cs2 b/dumps/scripts/3418.cs2 new file mode 100644 index 0000000..d511b3d --- /dev/null +++ b/dumps/scripts/3418.cs2 @@ -0,0 +1,20 @@ +void script_3418(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + ivar3 = 2289; + ivar4 = 2288; + if (arg2 == arg1) { + if (setWidgetRegister(new WidgetPointer(arg0), 1)) { + setWidgetSprite(ivar3); + setScriptCallOnMouseEntered(-1, "", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg0)); + } + } else { + if (setWidgetRegister(new WidgetPointer(arg0), 1)) { + setWidgetSprite(ivar4); + setScriptCallOnMouseEntered(688, new WidgetPointer(-32768,3), getWidgetCustomChildArrayIndex(), ivar3, "Iid", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(688, new WidgetPointer(-32768,3), getWidgetCustomChildArrayIndex(), ivar4, "Iid", new WidgetPointer(arg0)); + } + } + return; +} diff --git a/dumps/scripts/3419.cs2 b/dumps/scripts/3419.cs2 new file mode 100644 index 0000000..8671419 --- /dev/null +++ b/dumps/scripts/3419.cs2 @@ -0,0 +1,5 @@ +void script_3419() { + setWidgetScrollMax(431, 1863, new WidgetPointer(422,11)); + script_31(27656206, 27656203, 792, 789, 790, 791, 773, 788); + return; +} diff --git a/dumps/scripts/342.cs2 b/dumps/scripts/342.cs2 new file mode 100644 index 0000000..843bacf --- /dev/null +++ b/dumps/scripts/342.cs2 @@ -0,0 +1,6 @@ +void script_342() { + setWidgetSprite(3163, new WidgetPointer(205,50)); + setWidgetSprite(3163, new WidgetPointer(205,51)); + setWidgetSprite(3164, new WidgetPointer(205,52)); + return; +} diff --git a/dumps/scripts/3420.cs2 b/dumps/scripts/3420.cs2 new file mode 100644 index 0000000..7c88f43 --- /dev/null +++ b/dumps/scripts/3420.cs2 @@ -0,0 +1,13 @@ +void script_3420() { + if (globalint_1279 != 1) { + playSoundEffect(9445, 1, 0); + } + globalint_1279 = 1; + setWidgetIsHidden(true, new WidgetPointer(60,45)); + setWidgetIsHidden(false, new WidgetPointer(60,46)); + setWidgetIsHidden(true, new WidgetPointer(60,87)); + setWidgetIsHidden(true, new WidgetPointer(60,20)); + setWidgetIsHidden(false, new WidgetPointer(60,17)); + setWidgetIsHidden(true, new WidgetPointer(60,14)); + return; +} diff --git a/dumps/scripts/3421.cs2 b/dumps/scripts/3421.cs2 new file mode 100644 index 0000000..761ff09 --- /dev/null +++ b/dumps/scripts/3421.cs2 @@ -0,0 +1,13 @@ +void script_3421() { + if (globalint_1279 != 2) { + playSoundEffect(9445, 1, 0); + } + globalint_1279 = 2; + setWidgetIsHidden(true, new WidgetPointer(60,45)); + setWidgetIsHidden(true, new WidgetPointer(60,46)); + setWidgetIsHidden(false, new WidgetPointer(60,87)); + setWidgetIsHidden(true, new WidgetPointer(60,20)); + setWidgetIsHidden(true, new WidgetPointer(60,17)); + setWidgetIsHidden(false, new WidgetPointer(60,14)); + return; +} diff --git a/dumps/scripts/3422.cs2 b/dumps/scripts/3422.cs2 new file mode 100644 index 0000000..984a93d --- /dev/null +++ b/dumps/scripts/3422.cs2 @@ -0,0 +1,23 @@ +void script_3422() { + script_3425(3932336, 3932337); + script_3425(3932341, 3932342); + script_3425(3932346, 3932347); + script_3425(3932351, 3932352); + script_3425(3932356, 3932357); + script_3425(3932361, 3932362); + script_3425(3932366, 3932367); + script_3425(3932371, 3932372); + script_3425(3932376, 3932377); + script_3425(3932381, 3932382); + script_3425(3932421, 3932422); + script_3425(3932417, 3932418); + script_3425(3932413, 3932414); + script_3425(3932409, 3932410); + script_3425(3932405, 3932406); + script_3425(3932401, 3932402); + script_3425(3932397, 3932398); + script_3425(3932393, 3932394); + script_3425(3932389, 3932390); + script_3425(3932385, 3932386); + return; +} diff --git a/dumps/scripts/3423.cs2 b/dumps/scripts/3423.cs2 new file mode 100644 index 0000000..337a25d --- /dev/null +++ b/dumps/scripts/3423.cs2 @@ -0,0 +1,12 @@ +void script_3423() { + script_3425(3932245, 3932246); + script_3425(3932241, 3932242); + script_3425(3932237, 3932238); + script_3425(3932212, 3932213); + script_3425(3932233, 3932234); + script_3425(3932229, 3932230); + script_3425(3932225, 3932226); + script_3425(3932221, 3932222); + script_3425(3932426, 3932427); + return; +} diff --git a/dumps/scripts/3424.cs2 b/dumps/scripts/3424.cs2 new file mode 100644 index 0000000..023e5c3 --- /dev/null +++ b/dumps/scripts/3424.cs2 @@ -0,0 +1,17 @@ +void script_3424() { + script_3425(3932256, 3932257); + script_3425(3932261, 3932262); + script_3425(3932266, 3932267); + script_3425(3932321, 3932322); + script_3425(3932317, 3932318); + script_3425(3932313, 3932314); + script_3425(3932309, 3932310); + script_3425(3932305, 3932306); + script_3425(3932301, 3932302); + script_3425(3932297, 3932298); + script_3425(3932293, 3932294); + script_3425(3932289, 3932290); + script_3425(3932285, 3932286); + script_3425(3932281, 3932282); + return; +} diff --git a/dumps/scripts/3425.cs2 b/dumps/scripts/3425.cs2 new file mode 100644 index 0000000..a547718 --- /dev/null +++ b/dumps/scripts/3425.cs2 @@ -0,0 +1,15 @@ +void script_3425(int arg0,int arg1) { + int ivar2; + int ivar3; + ivar2 = cs2method_3408(73, 79, 3058, arg1); + ivar3 = cs2method_3408(79, 105, 3059, ivar2); + if (ivar2 == 4055) { + setWidgetText(new WidgetPointer(arg0), "Free!"); + } else { + setWidgetText(new WidgetPointer(arg0), intToStr(ivar3)); + } + setItemOnWidgetMethod2200(ivar2, -1, new WidgetPointer(arg1)); + setWidgetBorderThickness(1, new WidgetPointer(arg1)); + setWidgetShadowColor(new Color(51, 51, 51), new WidgetPointer(arg1)); + return; +} diff --git a/dumps/scripts/3426.cs2 b/dumps/scripts/3426.cs2 new file mode 100644 index 0000000..b52418c --- /dev/null +++ b/dumps/scripts/3426.cs2 @@ -0,0 +1,6 @@ +void script_3426(int arg0) { + string svar0; + svar0 = cs2method_3408(73, 115, 3063, arg0); + setWidgetText(new WidgetPointer(60,92), svar0); + return; +} diff --git a/dumps/scripts/3427.cs2 b/dumps/scripts/3427.cs2 new file mode 100644 index 0000000..fe55b4e --- /dev/null +++ b/dumps/scripts/3427.cs2 @@ -0,0 +1,4 @@ +void script_3427() { + setWidgetText(new WidgetPointer(60,92), "Items can be bought with Castle Wars tickets only."); + return; +} diff --git a/dumps/scripts/3428.cs2 b/dumps/scripts/3428.cs2 new file mode 100644 index 0000000..36ee93c --- /dev/null +++ b/dumps/scripts/3428.cs2 @@ -0,0 +1,18 @@ +void script_3428() { + setItemOnWidgetMethod2200(18739, -1, new WidgetPointer(985,29)); + setWidgetBorderThickness(1, new WidgetPointer(985,29)); + setWidgetShadowColor(new Color(51, 51, 51), new WidgetPointer(985,29)); + setItemOnWidgetMethod2200(18740, -1, new WidgetPointer(985,65)); + setWidgetBorderThickness(1, new WidgetPointer(985,65)); + setWidgetShadowColor(new Color(51, 51, 51), new WidgetPointer(985,65)); + setItemOnWidgetMethod2200(18741, -1, new WidgetPointer(985,64)); + setWidgetBorderThickness(1, new WidgetPointer(985,64)); + setWidgetShadowColor(new Color(51, 51, 51), new WidgetPointer(985,64)); + setItemOnWidgetMethod2200(18742, -1, new WidgetPointer(985,63)); + setWidgetBorderThickness(1, new WidgetPointer(985,63)); + setWidgetShadowColor(new Color(51, 51, 51), new WidgetPointer(985,63)); + setItemOnWidgetMethod2200(18743, -1, new WidgetPointer(985,62)); + setWidgetBorderThickness(1, new WidgetPointer(985,62)); + setWidgetShadowColor(new Color(51, 51, 51), new WidgetPointer(985,62)); + return; +} diff --git a/dumps/scripts/3429.cs2 b/dumps/scripts/3429.cs2 new file mode 100644 index 0000000..215adc6 --- /dev/null +++ b/dumps/scripts/3429.cs2 @@ -0,0 +1,6 @@ +void script_3429(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + setWidgetSprite(arg3, new WidgetPointer(arg0)); + setWidgetSprite(arg4, new WidgetPointer(arg1)); + setWidgetSprite(arg5, new WidgetPointer(arg2)); + return; +} diff --git a/dumps/scripts/343.cs2 b/dumps/scripts/343.cs2 new file mode 100644 index 0000000..86cf9e8 --- /dev/null +++ b/dumps/scripts/343.cs2 @@ -0,0 +1,6 @@ +void script_343() { + setWidgetSprite(3165, new WidgetPointer(205,46)); + setWidgetSprite(3165, new WidgetPointer(205,47)); + setWidgetSprite(3166, new WidgetPointer(205,48)); + return; +} diff --git a/dumps/scripts/3430.cs2 b/dumps/scripts/3430.cs2 new file mode 100644 index 0000000..486010a --- /dev/null +++ b/dumps/scripts/3430.cs2 @@ -0,0 +1,206 @@ +void script_3430() { + setWidgetFilled(0, new WidgetPointer(54,25)); + setWidgetFilled(0, new WidgetPointer(54,27)); + setWidgetFilled(0, new WidgetPointer(54,29)); + setWidgetFilled(0, new WidgetPointer(54,31)); + setWidgetFilled(0, new WidgetPointer(54,33)); + setWidgetFilled(0, new WidgetPointer(54,35)); + setWidgetFilled(0, new WidgetPointer(54,37)); + setWidgetFilled(0, new WidgetPointer(54,39)); + setWidgetFilled(0, new WidgetPointer(54,41)); + setWidgetFilled(0, new WidgetPointer(54,43)); + setWidgetFilled(0, new WidgetPointer(54,45)); + setWidgetFilled(0, new WidgetPointer(54,47)); + setWidgetFilled(0, new WidgetPointer(54,49)); + setWidgetFilled(0, new WidgetPointer(54,51)); + setWidgetFilled(0, new WidgetPointer(54,53)); + setWidgetFilled(0, new WidgetPointer(54,55)); + setWidgetFilled(0, new WidgetPointer(54,57)); + setWidgetFilled(0, new WidgetPointer(54,59)); + setWidgetFilled(0, new WidgetPointer(54,61)); + setWidgetFilled(0, new WidgetPointer(54,63)); + setWidgetFilled(0, new WidgetPointer(54,65)); + setWidgetFilled(0, new WidgetPointer(54,67)); + setWidgetFilled(0, new WidgetPointer(54,69)); + setWidgetFilled(0, new WidgetPointer(54,71)); + setWidgetFilled(0, new WidgetPointer(54,73)); + setWidgetFilled(0, new WidgetPointer(54,75)); + setWidgetFilled(0, new WidgetPointer(54,77)); + setWidgetFilled(0, new WidgetPointer(54,79)); + setWidgetFilled(0, new WidgetPointer(54,81)); + setWidgetFilled(0, new WidgetPointer(54,83)); + setWidgetFilled(0, new WidgetPointer(54,85)); + setWidgetFilled(0, new WidgetPointer(54,87)); + setWidgetFilled(0, new WidgetPointer(54,89)); + setWidgetFilled(0, new WidgetPointer(54,91)); + setWidgetFilled(0, new WidgetPointer(54,93)); + setWidgetFilled(0, new WidgetPointer(54,95)); + setWidgetFilled(0, new WidgetPointer(54,97)); + setWidgetFilled(0, new WidgetPointer(54,99)); + setWidgetFilled(0, new WidgetPointer(54,101)); + setWidgetFilled(0, new WidgetPointer(54,103)); + setWidgetFilled(0, new WidgetPointer(54,105)); + setWidgetFilled(0, new WidgetPointer(54,107)); + setWidgetFilled(0, new WidgetPointer(54,109)); + setWidgetFilled(0, new WidgetPointer(54,111)); + setWidgetFilled(0, new WidgetPointer(54,113)); + setWidgetFilled(0, new WidgetPointer(54,115)); + setWidgetFilled(0, new WidgetPointer(54,117)); + setWidgetFilled(0, new WidgetPointer(54,119)); + setWidgetFilled(0, new WidgetPointer(54,121)); + setWidgetFilled(0, new WidgetPointer(54,123)); + setWidgetFilled(0, new WidgetPointer(54,125)); + setWidgetFilled(0, new WidgetPointer(54,127)); + setWidgetFilled(0, new WidgetPointer(54,129)); + setWidgetFilled(0, new WidgetPointer(54,131)); + setWidgetFilled(0, new WidgetPointer(54,133)); + setWidgetFilled(0, new WidgetPointer(54,135)); + if (((boolean)bitconfig_157)) { + if (bitconfig_156 == 3) { + setWidgetFilled(1, new WidgetPointer(54,25)); + } else if (bitconfig_156 == 4) { + setWidgetFilled(1, new WidgetPointer(54,27)); + } else if (bitconfig_156 == 5) { + setWidgetFilled(1, new WidgetPointer(54,29)); + } else if (bitconfig_156 == 6) { + setWidgetFilled(1, new WidgetPointer(54,31)); + } else if (bitconfig_156 == 7) { + setWidgetFilled(1, new WidgetPointer(54,33)); + } else { + if (bitconfig_156 == 8) { + setWidgetFilled(1, new WidgetPointer(54,35)); + } + } + } else if (bitconfig_157 == 2) { + if (bitconfig_156 == 3) { + setWidgetFilled(1, new WidgetPointer(54,37)); + } else if (bitconfig_156 == 4) { + setWidgetFilled(1, new WidgetPointer(54,39)); + } else if (bitconfig_156 == 5) { + setWidgetFilled(1, new WidgetPointer(54,41)); + } else if (bitconfig_156 == 6) { + setWidgetFilled(1, new WidgetPointer(54,43)); + } else if (bitconfig_156 == 7) { + setWidgetFilled(1, new WidgetPointer(54,45)); + } else { + if (bitconfig_156 == 8) { + setWidgetFilled(1, new WidgetPointer(54,47)); + } + } + } else if (bitconfig_157 == 3) { + if (((boolean)bitconfig_156)) { + setWidgetFilled(1, new WidgetPointer(54,49)); + } else if (bitconfig_156 == 2) { + setWidgetFilled(1, new WidgetPointer(54,51)); + } else if (bitconfig_156 == 3) { + setWidgetFilled(1, new WidgetPointer(54,53)); + } else if (bitconfig_156 == 4) { + setWidgetFilled(1, new WidgetPointer(54,55)); + } else if (bitconfig_156 == 5) { + setWidgetFilled(1, new WidgetPointer(54,57)); + } else if (bitconfig_156 == 6) { + setWidgetFilled(1, new WidgetPointer(54,59)); + } else if (bitconfig_156 == 7) { + setWidgetFilled(1, new WidgetPointer(54,61)); + } else { + if (bitconfig_156 == 8) { + setWidgetFilled(1, new WidgetPointer(54,63)); + } + } + } else if (bitconfig_157 == 4) { + if (((boolean)bitconfig_156)) { + setWidgetFilled(1, new WidgetPointer(54,65)); + } else if (bitconfig_156 == 2) { + setWidgetFilled(1, new WidgetPointer(54,67)); + } else if (bitconfig_156 == 3) { + setWidgetFilled(1, new WidgetPointer(54,69)); + } else if (bitconfig_156 == 4) { + setWidgetFilled(1, new WidgetPointer(54,71)); + } else if (bitconfig_156 == 5) { + setWidgetFilled(1, new WidgetPointer(54,73)); + } else if (bitconfig_156 == 6) { + setWidgetFilled(1, new WidgetPointer(54,75)); + } else if (bitconfig_156 == 7) { + setWidgetFilled(1, new WidgetPointer(54,77)); + } else { + if (bitconfig_156 == 8) { + setWidgetFilled(1, new WidgetPointer(54,79)); + } + } + } else if (bitconfig_157 == 5) { + if (((boolean)bitconfig_156)) { + setWidgetFilled(1, new WidgetPointer(54,81)); + } else if (bitconfig_156 == 2) { + setWidgetFilled(1, new WidgetPointer(54,83)); + } else if (bitconfig_156 == 3) { + setWidgetFilled(1, new WidgetPointer(54,85)); + } else if (bitconfig_156 == 4) { + setWidgetFilled(1, new WidgetPointer(54,87)); + } else if (bitconfig_156 == 5) { + setWidgetFilled(1, new WidgetPointer(54,89)); + } else if (bitconfig_156 == 6) { + setWidgetFilled(1, new WidgetPointer(54,91)); + } else if (bitconfig_156 == 7) { + setWidgetFilled(1, new WidgetPointer(54,93)); + } else { + if (bitconfig_156 == 8) { + setWidgetFilled(1, new WidgetPointer(54,95)); + } + } + } else if (bitconfig_157 == 6) { + if (((boolean)bitconfig_156)) { + setWidgetFilled(1, new WidgetPointer(54,97)); + } else if (bitconfig_156 == 2) { + setWidgetFilled(1, new WidgetPointer(54,99)); + } else if (bitconfig_156 == 3) { + setWidgetFilled(1, new WidgetPointer(54,101)); + } else if (bitconfig_156 == 4) { + setWidgetFilled(1, new WidgetPointer(54,103)); + } else if (bitconfig_156 == 5) { + setWidgetFilled(1, new WidgetPointer(54,105)); + } else if (bitconfig_156 == 6) { + setWidgetFilled(1, new WidgetPointer(54,107)); + } else if (bitconfig_156 == 7) { + setWidgetFilled(1, new WidgetPointer(54,109)); + } else { + if (bitconfig_156 == 8) { + setWidgetFilled(1, new WidgetPointer(54,111)); + } + } + } else if (bitconfig_157 == 7) { + if (((boolean)bitconfig_156)) { + setWidgetFilled(1, new WidgetPointer(54,113)); + } else if (bitconfig_156 == 2) { + setWidgetFilled(1, new WidgetPointer(54,115)); + } else if (bitconfig_156 == 3) { + setWidgetFilled(1, new WidgetPointer(54,117)); + } else if (bitconfig_156 == 4) { + setWidgetFilled(1, new WidgetPointer(54,119)); + } else if (bitconfig_156 == 5) { + setWidgetFilled(1, new WidgetPointer(54,121)); + } else { + if (bitconfig_156 == 6) { + setWidgetFilled(1, new WidgetPointer(54,123)); + } + } + } else { + if (bitconfig_157 == 8) { + if (((boolean)bitconfig_156)) { + setWidgetFilled(1, new WidgetPointer(54,125)); + } else if (bitconfig_156 == 2) { + setWidgetFilled(1, new WidgetPointer(54,127)); + } else if (bitconfig_156 == 3) { + setWidgetFilled(1, new WidgetPointer(54,129)); + } else if (bitconfig_156 == 4) { + setWidgetFilled(1, new WidgetPointer(54,131)); + } else if (bitconfig_156 == 5) { + setWidgetFilled(1, new WidgetPointer(54,133)); + } else { + if (bitconfig_156 == 6) { + setWidgetFilled(1, new WidgetPointer(54,135)); + } + } + } + } + return; +} diff --git a/dumps/scripts/3431.cs2 b/dumps/scripts/3431.cs2 new file mode 100644 index 0000000..147d1e6 --- /dev/null +++ b/dumps/scripts/3431.cs2 @@ -0,0 +1,150 @@ +void script_3431(int arg0,int arg1,int arg2) { + if (((boolean)arg1)) { + if (arg0 == 3) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,25)); + } else if (arg0 == 4) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,27)); + } else if (arg0 == 5) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,29)); + } else if (arg0 == 6) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,31)); + } else if (arg0 == 7) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,33)); + } else { + if (arg0 == 8) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,35)); + } + } + } else if (arg1 == 2) { + if (arg0 == 3) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,37)); + } else if (arg0 == 4) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,39)); + } else if (arg0 == 5) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,41)); + } else if (arg0 == 6) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,43)); + } else if (arg0 == 7) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,45)); + } else { + if (arg0 == 8) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,47)); + } + } + } else if (arg1 == 3) { + if (((boolean)arg0)) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,49)); + } else if (arg0 == 2) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,51)); + } else if (arg0 == 3) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,53)); + } else if (arg0 == 4) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,55)); + } else if (arg0 == 5) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,57)); + } else if (arg0 == 6) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,59)); + } else if (arg0 == 7) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,61)); + } else { + if (arg0 == 8) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,63)); + } + } + } else if (arg1 == 4) { + if (((boolean)arg0)) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,65)); + } else if (arg0 == 2) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,67)); + } else if (arg0 == 3) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,69)); + } else if (arg0 == 4) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,71)); + } else if (arg0 == 5) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,73)); + } else if (arg0 == 6) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,75)); + } else if (arg0 == 7) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,77)); + } else { + if (arg0 == 8) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,79)); + } + } + } else if (arg1 == 5) { + if (((boolean)arg0)) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,81)); + } else if (arg0 == 2) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,83)); + } else if (arg0 == 3) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,85)); + } else if (arg0 == 4) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,87)); + } else if (arg0 == 5) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,89)); + } else if (arg0 == 6) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,91)); + } else if (arg0 == 7) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,93)); + } else { + if (arg0 == 8) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,95)); + } + } + } else if (arg1 == 6) { + if (((boolean)arg0)) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,97)); + } else if (arg0 == 2) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,99)); + } else if (arg0 == 3) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,101)); + } else if (arg0 == 4) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,103)); + } else if (arg0 == 5) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,105)); + } else if (arg0 == 6) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,107)); + } else if (arg0 == 7) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,109)); + } else { + if (arg0 == 8) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,111)); + } + } + } else if (arg1 == 7) { + if (((boolean)arg0)) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,113)); + } else if (arg0 == 2) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,115)); + } else if (arg0 == 3) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,117)); + } else if (arg0 == 4) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,119)); + } else if (arg0 == 5) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,121)); + } else { + if (arg0 == 6) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,123)); + } + } + } else { + if (arg1 == 8) { + if (((boolean)arg0)) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,125)); + } else if (arg0 == 2) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,127)); + } else if (arg0 == 3) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,129)); + } else if (arg0 == 4) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,131)); + } else if (arg0 == 5) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,133)); + } else { + if (arg0 == 6) { + setWidgetRGB(new Color(arg2), new WidgetPointer(54,135)); + } + } + } + } + return; +} diff --git a/dumps/scripts/3432.cs2 b/dumps/scripts/3432.cs2 new file mode 100644 index 0000000..37a2941 --- /dev/null +++ b/dumps/scripts/3432.cs2 @@ -0,0 +1,4 @@ +void script_3432(int arg0) { + cs2method2103(0, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/3433.cs2 b/dumps/scripts/3433.cs2 new file mode 100644 index 0000000..b39fec7 --- /dev/null +++ b/dumps/scripts/3433.cs2 @@ -0,0 +1,4 @@ +void script_3433(int arg0) { + cs2method2103(140, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/3434.cs2 b/dumps/scripts/3434.cs2 new file mode 100644 index 0000000..207ddda --- /dev/null +++ b/dumps/scripts/3434.cs2 @@ -0,0 +1,23 @@ +void script_3434(int arg0) { + if (((boolean)globalint_1280)) { + return; + } + if (globalint_1278 != arg0) { + playSoundEffect(9439, 1, 0); + } + globalint_1278 = arg0; + setWidgetSprite(1134, new WidgetPointer(54,16)); + setWidgetSprite(1134, new WidgetPointer(54,17)); + setWidgetSprite(1134, new WidgetPointer(54,18)); + if (((boolean)globalint_1278)) { + setWidgetSprite(1135, new WidgetPointer(54,16)); + } else if (globalint_1278 == 2) { + setWidgetSprite(1135, new WidgetPointer(54,17)); + } else if (globalint_1278 == 3) { + setWidgetSprite(1135, new WidgetPointer(54,18)); + } else { + globalint_1278 = 1; + setWidgetSprite(1135, new WidgetPointer(54,16)); + } + return; +} diff --git a/dumps/scripts/3435.cs2 b/dumps/scripts/3435.cs2 new file mode 100644 index 0000000..0d0d886 --- /dev/null +++ b/dumps/scripts/3435.cs2 @@ -0,0 +1,4 @@ +void script_3435() { + globalint_1280 = 1; + return; +} diff --git a/dumps/scripts/3436.cs2 b/dumps/scripts/3436.cs2 new file mode 100644 index 0000000..313145e --- /dev/null +++ b/dumps/scripts/3436.cs2 @@ -0,0 +1,21 @@ +void script_3436(int arg0,int arg1,int arg2,string arg3) { + setWidgetModel(arg0, new WidgetPointer(311,57)); + setWidgetText(new WidgetPointer(311,59), arg3); + setWidgetIsHidden(true, new WidgetPointer(311,39)); + setWidgetIsHidden(true, new WidgetPointer(311,11)); + setWidgetIsHidden(true, new WidgetPointer(311,7)); + setWidgetIsHidden(true, new WidgetPointer(311,3)); + setWidgetIsHidden(true, new WidgetPointer(311,23)); + setWidgetIsHidden(true, new WidgetPointer(311,19)); + setWidgetIsHidden(true, new WidgetPointer(311,15)); + setWidgetIsHidden(false, new WidgetPointer(arg1)); + setWidgetSprite(4041, new WidgetPointer(311,24)); + setWidgetSprite(4041, new WidgetPointer(311,20)); + setWidgetSprite(4041, new WidgetPointer(311,16)); + setWidgetSprite(4041, new WidgetPointer(311,12)); + setWidgetSprite(4041, new WidgetPointer(311,8)); + setWidgetSprite(4041, new WidgetPointer(311,4)); + setWidgetSprite(4041, new WidgetPointer(311,0)); + setWidgetSprite(4043, new WidgetPointer(arg2)); + return; +} diff --git a/dumps/scripts/3437.cs2 b/dumps/scripts/3437.cs2 new file mode 100644 index 0000000..73ed2e1 --- /dev/null +++ b/dumps/scripts/3437.cs2 @@ -0,0 +1,61 @@ +void script_3437() { + int ivar0; + ivar0 = -1; + if (((boolean)bitconfig_7912) || (((bitconfig_7904 == 8) && ((boolean)bitconfig_7921)) && ((boolean)bitconfig_7916))) { + if (bitconfig_7919 < 3) { + if (((boolean)bitconfig_7920)) { + ivar0 = cs2method_3408(105, 109, 5079, bitconfig_7919); + } + if (bitconfig_7920 == 2) { + ivar0 = cs2method_3408(105, 109, 5080, bitconfig_7919); + } + if (bitconfig_7920 == 3) { + ivar0 = cs2method_3408(105, 109, 5081, bitconfig_7919); + } + } else if (bitconfig_7919 < 6) { + if (((boolean)bitconfig_7920)) { + ivar0 = cs2method_3408(105, 109, 5080, bitconfig_7919); + } + if (bitconfig_7920 == 2) { + ivar0 = cs2method_3408(105, 109, 5081, bitconfig_7919); + } + if (bitconfig_7920 == 3) { + ivar0 = cs2method_3408(105, 109, 5079, bitconfig_7919); + } + } else if (bitconfig_7919 == 10) { + if (bitconfig_7920 == 3) { + ivar0 = cs2method_3408(105, 109, 5080, bitconfig_7919); + } + if (bitconfig_7920 == 2) { + ivar0 = cs2method_3408(105, 109, 5081, bitconfig_7919); + } + if (((boolean)bitconfig_7920)) { + ivar0 = cs2method_3408(105, 109, 5079, bitconfig_7919); + } + } else { + if (((boolean)bitconfig_7920)) { + ivar0 = cs2method_3408(105, 109, 5081, bitconfig_7919); + } + if (bitconfig_7920 == 2) { + ivar0 = cs2method_3408(105, 109, 5079, bitconfig_7919); + } + if (bitconfig_7920 == 3) { + ivar0 = cs2method_3408(105, 109, 5080, bitconfig_7919); + } + } + setWidgetModel(ivar0, new WidgetPointer(986,3)); + if (bitconfig_7920 != 0) { + setWidgetIsHidden(false, new WidgetPointer(986,5)); + } + if (((boolean)bitconfig_7920)) { + setWidgetPosition(30, 205, 0, 0, new WidgetPointer(986,5)); + } else if (bitconfig_7920 == 2) { + setWidgetPosition(112, 205, 0, 0, new WidgetPointer(986,5)); + } else if (bitconfig_7920 == 3) { + setWidgetPosition(196, 205, 0, 0, new WidgetPointer(986,5)); + } else { + setWidgetIsHidden(true, new WidgetPointer(986,5)); + } + } + return; +} diff --git a/dumps/scripts/3438.cs2 b/dumps/scripts/3438.cs2 new file mode 100644 index 0000000..5cc5fde --- /dev/null +++ b/dumps/scripts/3438.cs2 @@ -0,0 +1,12 @@ +void script_3438() { + if (((boolean)getLanguage())) { + setWidgetSprite(861, new WidgetPointer(329,11)); + } else if (getLanguage() == 2) { + setWidgetSprite(644, new WidgetPointer(329,11)); + } else { + if (getLanguage() == 3) { + setWidgetSprite(866, new WidgetPointer(329,11)); + } + } + return; +} diff --git a/dumps/scripts/3439.cs2 b/dumps/scripts/3439.cs2 new file mode 100644 index 0000000..b45345f --- /dev/null +++ b/dumps/scripts/3439.cs2 @@ -0,0 +1,18 @@ +void script_3439() { + setWidgetIsHidden(false, new WidgetPointer(1128,192)); + setWidgetIsHidden(false, new WidgetPointer(1128,88)); + setWidgetIsHidden(false, new WidgetPointer(1128,117)); + setWidgetIsHidden(false, new WidgetPointer(1128,155)); + setWidgetIsHidden(false, new WidgetPointer(1128,229)); + setWidgetIsHidden(false, new WidgetPointer(1128,266)); + setWidgetIsHidden(false, new WidgetPointer(1128,303)); + setWidgetText(new WidgetPointer(1128,9), concat("20", "/" + intToStr(20))); + setWidgetText(new WidgetPointer(1128,135), concat("20", "/" + intToStr(20))); + setWidgetText(new WidgetPointer(1128,173), concat("30", "/" + intToStr(20))); + setWidgetText(new WidgetPointer(1128,210), concat("28", "/" + intToStr(20))); + setWidgetText(new WidgetPointer(1128,247), concat("24", "/" + intToStr(20))); + setWidgetText(new WidgetPointer(1128,284), concat("26", "/" + intToStr(20))); + setWidgetText(new WidgetPointer(1128,321), concat("200", "/" + intToStr(200))); + setWidgetText(new WidgetPointer(1128,13), intToStr(bitconfig_5505)); + return; +} diff --git a/dumps/scripts/344.cs2 b/dumps/scripts/344.cs2 new file mode 100644 index 0000000..28ddcff --- /dev/null +++ b/dumps/scripts/344.cs2 @@ -0,0 +1,6 @@ +void script_344() { + setWidgetSprite(3163, new WidgetPointer(205,46)); + setWidgetSprite(3163, new WidgetPointer(205,47)); + setWidgetSprite(3164, new WidgetPointer(205,48)); + return; +} diff --git a/dumps/scripts/3440.cs2 b/dumps/scripts/3440.cs2 new file mode 100644 index 0000000..98bca7a --- /dev/null +++ b/dumps/scripts/3440.cs2 @@ -0,0 +1,12 @@ +void script_3440(int arg0,int arg1) { + playSoundEffect2False(6185, 1, 0, 200); + if (isWidgetHidden(new WidgetPointer(arg0))) { + setWidgetIsHidden(false, new WidgetPointer(arg0)); + setWidgetSprite(6007, new WidgetPointer(arg1)); + } else { + setWidgetIsHidden(true, new WidgetPointer(arg0)); + setWidgetSprite(6009, new WidgetPointer(arg1)); + } + script_5245(); + return; +} diff --git a/dumps/scripts/3441.cs2 b/dumps/scripts/3441.cs2 new file mode 100644 index 0000000..100318c --- /dev/null +++ b/dumps/scripts/3441.cs2 @@ -0,0 +1,6 @@ +int script_3441() { + if ((getItemAmtInContainer(94, 6465) > 0) || (getItemAmtInContainer(94, 15016) > 0)) { + return 1; + } + return 0; +} diff --git a/dumps/scripts/3442.cs2 b/dumps/scripts/3442.cs2 new file mode 100644 index 0000000..211859d --- /dev/null +++ b/dumps/scripts/3442.cs2 @@ -0,0 +1,8 @@ +void script_3442(int arg0,int arg1,int arg2) { + if (((boolean)script_3441())) { + script_569(arg0, -1, arg1, 50, 150, script_3443(arg2)); + } else { + script_569(arg0, -1, arg1, 50, 150, "A member of the Jury."); + } + return; +} diff --git a/dumps/scripts/3443.cs2 b/dumps/scripts/3443.cs2 new file mode 100644 index 0000000..3c514b2 --- /dev/null +++ b/dumps/scripts/3443.cs2 @@ -0,0 +1,29 @@ +string script_3443(int arg0) { + switch (arg0) { + case 1: + return "A ranger, he prefers the bow and arrow to all other combat. He's a straight arrow and hates evil do-ers."; + case 2: + return "A wizard, he researches the mysteries of life and performs magic."; + case 3: + return "A miner, works hard all day mining rock. Likes to party in the evenings."; + case 4: + return "A cook, he spends his day making bread and stopping people stealing his cakes. He hates stew."; + case 5: + return "A shady-looking gentleman. He's likely involved in the criminal underworld."; + case 6: + return "A young man. He's concerned with starting his own business and making money. Also enjoys a rowdy party."; + case 7: + return "A barbarian. He is sensitive to any disrespect of his culture."; + case 8: + return "An elderly gentleman. He's worried about his safety and a rise in crime."; + case 9: + return "A young woman. She's concerned with the safety of her children."; + case 10: + return "A shady-looking fellow. He covers up his face to hide his identity."; + case 11: + return "A desert citizen. She doesn't have much love for mainlanders."; + case 12: + return "An elderly gentleman. He doesn't like parties or noise."; + } + return ""; +} diff --git a/dumps/scripts/3444.cs2 b/dumps/scripts/3444.cs2 new file mode 100644 index 0000000..c4adcba --- /dev/null +++ b/dumps/scripts/3444.cs2 @@ -0,0 +1,4 @@ +void script_3444(int arg0) { + setWidget3DViewDistance(2000, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/3445.cs2 b/dumps/scripts/3445.cs2 new file mode 100644 index 0000000..d797312 --- /dev/null +++ b/dumps/scripts/3445.cs2 @@ -0,0 +1,4 @@ +void script_3445(int arg0) { + setWidget3DViewDistance(2600, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/3446.cs2 b/dumps/scripts/3446.cs2 new file mode 100644 index 0000000..3d1da1c --- /dev/null +++ b/dumps/scripts/3446.cs2 @@ -0,0 +1,6 @@ +void script_3446() { + setWidgetSprite(3165, new WidgetPointer(987,15)); + setWidgetSprite(3165, new WidgetPointer(987,16)); + setWidgetSprite(3166, new WidgetPointer(987,14)); + return; +} diff --git a/dumps/scripts/3447.cs2 b/dumps/scripts/3447.cs2 new file mode 100644 index 0000000..d23f047 --- /dev/null +++ b/dumps/scripts/3447.cs2 @@ -0,0 +1,6 @@ +void script_3447() { + setWidgetSprite(3163, new WidgetPointer(987,15)); + setWidgetSprite(3163, new WidgetPointer(987,16)); + setWidgetSprite(3164, new WidgetPointer(987,14)); + return; +} diff --git a/dumps/scripts/3448.cs2 b/dumps/scripts/3448.cs2 new file mode 100644 index 0000000..248eacd --- /dev/null +++ b/dumps/scripts/3448.cs2 @@ -0,0 +1,29 @@ +void script_3448() { + if (bitconfig_7933 != 0) { + setWidgetIsHidden(false, new WidgetPointer(987,30)); + } else { + setWidgetIsHidden(true, new WidgetPointer(987,30)); + } + switch (bitconfig_7933) { + case 1: + setWidgetPosition(16, 28, 0, 0, new WidgetPointer(987,30)); + break; + case 7: + setWidgetPosition(16, 161, 0, 0, new WidgetPointer(987,30)); + break; + case 2: + case 3: + case 4: + case 5: + case 6: + setWidgetPosition(add(16, multiply(subtract(bitconfig_7933, 1), 79)), 28, 0, 0, new WidgetPointer(987,30)); + break; + case 8: + case 9: + case 10: + case 11: + case 12: + setWidgetPosition(add(16, multiply(subtract(bitconfig_7933, 7), 79)), 161, 0, 0, new WidgetPointer(987,30)); + } + return; +} diff --git a/dumps/scripts/3449.cs2 b/dumps/scripts/3449.cs2 new file mode 100644 index 0000000..3a74b52 --- /dev/null +++ b/dumps/scripts/3449.cs2 @@ -0,0 +1,5 @@ +void script_3449(int arg0,int arg1) { + setItemOnWidgetMethod2200(arg0, 0, new WidgetPointer(519,0)); + setWidget3DViewDistance(arg1, new WidgetPointer(519,0)); + return; +} diff --git a/dumps/scripts/345.cs2 b/dumps/scripts/345.cs2 new file mode 100644 index 0000000..0336859 --- /dev/null +++ b/dumps/scripts/345.cs2 @@ -0,0 +1,6 @@ +void script_345() { + setWidgetSprite(3165, new WidgetPointer(205,58)); + setWidgetSprite(3165, new WidgetPointer(205,59)); + setWidgetSprite(3166, new WidgetPointer(205,60)); + return; +} diff --git a/dumps/scripts/3450.cs2 b/dumps/scripts/3450.cs2 new file mode 100644 index 0000000..81d9611 --- /dev/null +++ b/dumps/scripts/3450.cs2 @@ -0,0 +1,4 @@ +void script_3450(int arg0) { + script_1548(arg0); + return; +} diff --git a/dumps/scripts/3451.cs2 b/dumps/scripts/3451.cs2 new file mode 100644 index 0000000..39d0396 --- /dev/null +++ b/dumps/scripts/3451.cs2 @@ -0,0 +1,30 @@ +void script_3451(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + ivar2 = 64094244; + ivar3 = 64094245; + ivar4 = 64094246; + ivar5 = 64094247; + ivar6 = 64094248; + ivar7 = 64094209; + if (((boolean)arg1)) { + ivar2 = 64028682; + ivar3 = 64028683; + ivar4 = 64028684; + ivar5 = 64028685; + ivar6 = 64028686; + } + script_3932(arg0, arg1, ivar2, 1, add(getTextWidth(3793, "MIN"), 30), "MIN", ""); + script_3932(arg0, arg1, ivar3, 2, add(getTextWidth(3793, "LOW"), 30), "LOW", ""); + script_3932(arg0, arg1, ivar4, 3, add(getTextWidth(3793, "MID"), 30), "MID", ""); + script_3932(arg0, arg1, ivar5, 4, add(getTextWidth(3793, "HIGH"), 30), "HIGH", ""); + script_3932(arg0, arg1, ivar6, 0, add(getTextWidth(3793, "CUSTOM"), 30), "CUSTOM", ""); + if (((boolean)arg1)) { + script_3932(arg0, arg1, ivar7, -1, add(getTextWidth(3793, "RE-RUN AUTO SETUP"), 30), "RE-RUN AUTO SETUP", ""); + } + return; +} diff --git a/dumps/scripts/3452.cs2 b/dumps/scripts/3452.cs2 new file mode 100644 index 0000000..27617e6 --- /dev/null +++ b/dumps/scripts/3452.cs2 @@ -0,0 +1,4 @@ +void script_3452(int arg0,int arg1,int arg2) { + script_3239(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/3453.cs2 b/dumps/scripts/3453.cs2 new file mode 100644 index 0000000..f91009f --- /dev/null +++ b/dumps/scripts/3453.cs2 @@ -0,0 +1,15 @@ +void script_3453() { + if (globalint_1281 == 8) { + return; + } + if (((boolean)globalint_1074)) { + script_3454(add(globalint_1281, 1), globalint_1070, globalint_1069, script_2865(globalint_1070, globalint_1071), globalint_1073); + } else if (((boolean)globalint_1074)) { + script_3454(add(globalint_1281, 1), globalint_1070, globalint_1069, globalint_1072, 50); + } else { + return; + } + globalint_1281 = add(globalint_1281, 1); + setWidgetText(new WidgetPointer(475,78), intToStr(globalint_1281)); + return; +} diff --git a/dumps/scripts/3454.cs2 b/dumps/scripts/3454.cs2 new file mode 100644 index 0000000..a14bddc --- /dev/null +++ b/dumps/scripts/3454.cs2 @@ -0,0 +1,52 @@ +void script_3454(int arg0,int arg1,int arg2,int arg3,int arg4) { + switch (arg0) { + case 1: + globalint_1283 = arg1; + globalint_1284 = arg2; + globalint_1285 = arg3; + globalint_1286 = arg4; + break; + case 2: + globalint_1287 = arg1; + globalint_1288 = arg2; + globalint_1289 = arg3; + globalint_1290 = arg4; + break; + case 3: + globalint_1291 = arg1; + globalint_1292 = arg2; + globalint_1293 = arg3; + globalint_1294 = arg4; + break; + case 4: + globalint_1295 = arg1; + globalint_1296 = arg2; + globalint_1297 = arg3; + globalint_1298 = arg4; + break; + case 5: + globalint_1299 = arg1; + globalint_1300 = arg2; + globalint_1301 = arg3; + globalint_1302 = arg4; + break; + case 6: + globalint_1303 = arg1; + globalint_1304 = arg2; + globalint_1305 = arg3; + globalint_1306 = arg4; + break; + case 7: + globalint_1307 = arg1; + globalint_1308 = arg2; + globalint_1309 = arg3; + globalint_1310 = arg4; + break; + case 8: + globalint_1311 = arg1; + globalint_1312 = arg2; + globalint_1313 = arg3; + globalint_1314 = arg4; + } + return; +} diff --git a/dumps/scripts/3455.cs2 b/dumps/scripts/3455.cs2 new file mode 100644 index 0000000..fc77387 --- /dev/null +++ b/dumps/scripts/3455.cs2 @@ -0,0 +1,5 @@ +void script_3455() { + globalint_1281 = 0; + setWidgetText(new WidgetPointer(475,78), intToStr(globalint_1281)); + return; +} diff --git a/dumps/scripts/3456.cs2 b/dumps/scripts/3456.cs2 new file mode 100644 index 0000000..b680c3c --- /dev/null +++ b/dumps/scripts/3456.cs2 @@ -0,0 +1,4 @@ +void script_3456() { + setScriptCallOnGameloop(3457, new WidgetPointer(475,1), getClientCycle(), "Ii", new WidgetPointer(475,1)); + return; +} diff --git a/dumps/scripts/3457.cs2 b/dumps/scripts/3457.cs2 new file mode 100644 index 0000000..66f009f --- /dev/null +++ b/dumps/scripts/3457.cs2 @@ -0,0 +1,46 @@ +void script_3457(int arg0,int arg1) { + int ivar2; + ivar2 = subtract(getClientCycle(), arg1); + if ((ivar2 < 100) && (globalint_1281 > 0)) { + cameraPointAt(globalint_1285, globalint_1286, 3000, globalint_1282); + cameraMoveTo(globalint_1283, globalint_1284, 3000, globalint_1282); + return; + } + if ((ivar2 < 200) && (globalint_1281 > 1)) { + cameraPointAt(globalint_1289, globalint_1290, 0, globalint_1282); + cameraMoveTo(globalint_1287, globalint_1288, 0, globalint_1282); + return; + } + if ((ivar2 < 300) && (globalint_1281 > 2)) { + cameraPointAt(globalint_1293, globalint_1294, 0, globalint_1282); + cameraMoveTo(globalint_1291, globalint_1292, 0, globalint_1282); + return; + } + if ((ivar2 < 400) && (globalint_1281 > 3)) { + cameraPointAt(globalint_1297, globalint_1298, 0, globalint_1282); + cameraMoveTo(globalint_1295, globalint_1296, 0, globalint_1282); + return; + } + if ((ivar2 < 500) && (globalint_1281 > 4)) { + cameraPointAt(globalint_1301, globalint_1302, 0, globalint_1282); + cameraMoveTo(globalint_1299, globalint_1300, 0, globalint_1282); + return; + } + if ((ivar2 < 600) && (globalint_1281 > 5)) { + cameraPointAt(globalint_1305, globalint_1306, 0, globalint_1282); + cameraMoveTo(globalint_1303, globalint_1304, 0, globalint_1282); + return; + } + if ((ivar2 < 700) && (globalint_1281 > 6)) { + cameraPointAt(globalint_1309, globalint_1310, 0, globalint_1282); + cameraMoveTo(globalint_1307, globalint_1308, 0, globalint_1282); + return; + } + if ((ivar2 < 800) && (globalint_1281 > 7)) { + cameraPointAt(globalint_1313, globalint_1314, 0, globalint_1282); + cameraMoveTo(globalint_1311, globalint_1312, 0, globalint_1282); + return; + } + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/3458.cs2 b/dumps/scripts/3458.cs2 new file mode 100644 index 0000000..1a5e4e3 --- /dev/null +++ b/dumps/scripts/3458.cs2 @@ -0,0 +1,33 @@ +void script_3458(int arg0,int arg1) { + switch (globalint_1007) { + case 31: + cs2method5405(0, 3); + cs2method5405(1, 3); + cs2method5406(0, 0, script_3459(62363230, arg1), 500, script_3459(62363230, arg1), 500, 0); + cs2method5406(1, 0, script_3459(62297690, arg1), 350, script_3459(62297690, arg1), 350, 0); + cs2method5406(0, 1, script_3459(62363229, arg1), 450, script_3459(62363229, arg1), 450, 0); + cs2method5406(1, 1, script_3459(62314075, arg1), 350, script_3459(62314075, arg1), 350, 0); + cs2method5406(0, 2, script_3459(62330459, arg1), 550, script_3459(62330459, arg1), 550, 0); + cs2method5406(1, 2, script_3459(62330464, arg1), 350, script_3459(62281310, arg1), 350, 0); + cameraMethod5502(0, 0, 50, 10, 1, 0); + break; + case 32: + cameraMethod5502(0, 1, 500, 500, 1, 1); + break; + case 33: + script_2766(0, 50, arg0); + break; + case 34: + script_2768(25, arg0); + break; + case 35: + script_2766(0, 25, arg0); + break; + case 36: + script_2768(50, arg0); + break; + default: + cs2method5512(); + } + return; +} diff --git a/dumps/scripts/3459.cs2 b/dumps/scripts/3459.cs2 new file mode 100644 index 0000000..09eae40 --- /dev/null +++ b/dumps/scripts/3459.cs2 @@ -0,0 +1,3 @@ +int script_3459(int arg0,int arg1) { + return addToCoordinate(arg1, subtract(add(24, extractX(arg0)), extractX(61871680)), 0, subtract(add(24, extractY(arg0)), extractY(61871680))); +} diff --git a/dumps/scripts/346.cs2 b/dumps/scripts/346.cs2 new file mode 100644 index 0000000..3bd70d9 --- /dev/null +++ b/dumps/scripts/346.cs2 @@ -0,0 +1,6 @@ +void script_346() { + setWidgetSprite(3163, new WidgetPointer(205,58)); + setWidgetSprite(3163, new WidgetPointer(205,59)); + setWidgetSprite(3164, new WidgetPointer(205,60)); + return; +} diff --git a/dumps/scripts/3460.cs2 b/dumps/scripts/3460.cs2 new file mode 100644 index 0000000..c91a0f1 --- /dev/null +++ b/dumps/scripts/3460.cs2 @@ -0,0 +1,3 @@ +int script_3460(int arg0,int arg1,int arg2) { + return addToCoordinate(arg2, arg0, 0, arg1); +} diff --git a/dumps/scripts/3461.cs2 b/dumps/scripts/3461.cs2 new file mode 100644 index 0000000..06ea0d5 --- /dev/null +++ b/dumps/scripts/3461.cs2 @@ -0,0 +1,40 @@ +void script_3461(int arg0,int arg1,int arg2,int arg3,int arg4) { + if (globalint_1007 <= 0) { + setWidgetIsHidden(true, new WidgetPointer(arg1)); + setWidgetIsHidden(true, new WidgetPointer(arg4)); + cs2method5512(); + return; + } + if (globalint_1007 <= 10) { + setWidgetIsHidden(true, new WidgetPointer(arg1)); + setWidgetIsHidden(true, new WidgetPointer(arg4)); + script_3470(arg0, script_284(getMyPositionHash())); + return; + } + if (globalint_1007 <= 20) { + setWidgetIsHidden(true, new WidgetPointer(arg1)); + setWidgetIsHidden(true, new WidgetPointer(arg4)); + script_3465(arg0, script_284(getMyPositionHash())); + return; + } + if (globalint_1007 <= 30) { + setWidgetIsHidden(true, new WidgetPointer(arg4)); + script_3462(arg0, arg1, arg2, arg3); + return; + } + if (globalint_1007 <= 40) { + setWidgetIsHidden(true, new WidgetPointer(arg1)); + setWidgetIsHidden(true, new WidgetPointer(arg4)); + script_3458(arg0, script_284(getMyPositionHash())); + return; + } + if (globalint_1007 <= 100) { + setWidgetIsHidden(true, new WidgetPointer(arg1)); + script_3472(arg0, arg4); + return; + } + setWidgetIsHidden(true, new WidgetPointer(arg1)); + setWidgetIsHidden(true, new WidgetPointer(arg4)); + script_3466(arg0, script_284(getMyPositionHash())); + return; +} diff --git a/dumps/scripts/3462.cs2 b/dumps/scripts/3462.cs2 new file mode 100644 index 0000000..fa171f0 --- /dev/null +++ b/dumps/scripts/3462.cs2 @@ -0,0 +1,43 @@ +void script_3462(int arg0,int arg1,int arg2,int arg3) { + switch (globalint_1007) { + case 21: + setWidgetIsHidden(true, new WidgetPointer(arg1)); + deleteAllExtraChilds(new WidgetPointer(arg0)); + script_2766(0, 75, arg0); + break; + case 22: + setWidgetIsHidden(false, new WidgetPointer(arg1)); + deleteAllExtraChilds(new WidgetPointer(arg1)); + script_1088(arg1, 0); + deleteAllExtraChilds(new WidgetPointer(arg2)); + createExtraChild(new WidgetPointer(arg2), 6, 0); + setWidgetSize(0, 85, 1, 0); + setWidgetPosition(0, 0, 1, 0); + setWidgetSelfFull(); + setWidget3DRotation(0, 30, 0, 0, 0, 850); + setWidgetAnimation(14230); + setScriptCallOnGameloop(3464, new WidgetPointer(-32768,3), -2147483643, "Ii"); + script_2647(arg2); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg2)), add(multiply(getLineCount(getWidgetActualWidth(new WidgetPointer(arg3)), 494, getWidgetText(new WidgetPointer(arg3))), 10), 75), 0, 0, new WidgetPointer(arg2)); + cameraMoveTo(addToCoordinate(getMyPositionHash(), 0, 0, -3), 1500, 1000, 100); + cameraPointAt(getMyPositionHash(), 0, 1000, 100); + script_2768(75, arg0); + setScriptCallOnGameloop(3463, new WidgetPointer(-32768,3), getMyPositionHash(), "Ic", new WidgetPointer(arg0)); + break; + case 23: + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + script_2766(0, 25, arg0); + break; + case 24: + cs2method5512(); + deleteAllExtraChilds(new WidgetPointer(arg1)); + deleteAllExtraChilds(new WidgetPointer(arg2)); + setWidgetIsHidden(true, new WidgetPointer(arg1)); + script_2768(25, arg0); + break; + default: + setWidgetIsHidden(true, new WidgetPointer(arg1)); + cs2method5512(); + } + return; +} diff --git a/dumps/scripts/3463.cs2 b/dumps/scripts/3463.cs2 new file mode 100644 index 0000000..e6e6e70 --- /dev/null +++ b/dumps/scripts/3463.cs2 @@ -0,0 +1,14 @@ +void script_3463(int arg0,int arg1) { + if (globalint_1007 != 22) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + return; + } + if (getMyPositionHash() == arg1) { + return; + } + playSoundEffect(4874, 1, 0); + cameraMoveTo(addToCoordinate(getMyPositionHash(), 0, 0, -3), 1500, 1, 75); + cameraPointAt(getMyPositionHash(), 0, 1, 15); + setScriptCallOnGameloop(3463, new WidgetPointer(-32768,3), getMyPositionHash(), "Ic", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/3464.cs2 b/dumps/scripts/3464.cs2 new file mode 100644 index 0000000..f2e50ef --- /dev/null +++ b/dumps/scripts/3464.cs2 @@ -0,0 +1,6 @@ +void script_3464(int arg0,int arg1) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidget3DRotation(cs2method1610(), cs2method1611(), getWidgetRotateX(), mod(add(getWidgetRotateY(), 2), 2028), cs2method1607(), getWidget3DDistance()); + } + return; +} diff --git a/dumps/scripts/3465.cs2 b/dumps/scripts/3465.cs2 new file mode 100644 index 0000000..4ff4ff4 --- /dev/null +++ b/dumps/scripts/3465.cs2 @@ -0,0 +1,31 @@ +void script_3465(int arg0,int arg1) { + switch (globalint_1007) { + case 11: + deleteAllExtraChilds(new WidgetPointer(arg0)); + script_2766(0, 75, arg0); + break; + case 12: + cs2method5405(0, 2); + cs2method5405(1, 2); + cs2method5406(0, 0, script_3460(30, 27, arg1), 800, script_3460(30, 30, arg1), 850, 0); + cs2method5406(1, 0, script_3460(35, 30, arg1), 300, script_3460(35, 40, arg1), 300, 0); + cs2method5406(0, 1, script_3460(40, 40, arg1), 1000, script_3460(40, 40, arg1), 950, 0); + cs2method5406(1, 1, script_3460(28, 52, arg1), 200, script_3460(28, 46, arg1), 200, 0); + cameraMethod5502(0, 0, 100, 200, 1, 0); + script_2768(25, arg0); + break; + case 13: + cs2method5512(); + cameraMethod5504(268, 644); + break; + case 14: + script_2766(0, 25, arg0); + break; + case 15: + script_2768(25, arg0); + break; + default: + cs2method5512(); + } + return; +} diff --git a/dumps/scripts/3466.cs2 b/dumps/scripts/3466.cs2 new file mode 100644 index 0000000..90cdcfe --- /dev/null +++ b/dumps/scripts/3466.cs2 @@ -0,0 +1,157 @@ +void script_3466(int arg0,int arg1) { + switch (globalint_1007) { + case 101: + deleteAllExtraChilds(new WidgetPointer(arg0)); + script_2766(0, 50, arg0); + break; + case 102: + cs2method5405(0, 2); + cs2method5405(1, 2); + cs2method5406(0, 0, script_3460(7, 54, arg1), 1000, script_3460(8, 54, arg1), 1000, 0); + cs2method5406(1, 0, script_3460(13, 50, arg1), 450, script_3460(13, 50, arg1), 450, 0); + cs2method5406(0, 1, script_3460(13, 51, arg1), 800, script_3460(13, 52, arg1), 800, 0); + cs2method5406(1, 1, script_3460(14, 44, arg1), 550, script_3460(14, 44, arg1), 550, 0); + cameraMethod5502(0, 0, 100, 100, 1, 0); + script_2768(75, arg0); + break; + case 103: + deleteAllExtraChilds(new WidgetPointer(arg0)); + setScriptCallOnGameloop(3467, new WidgetPointer(arg0), getClientCycle(), 100, "Iii", new WidgetPointer(arg0)); + break; + case 104: + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + if (setWidgetRegister(new WidgetPointer(arg0), 0)) { + cs2method2103(0); + setScriptCallOnGameloop(-1, ""); + } else { + script_2766(0, 0, arg0); + } + break; + case 105: + cs2method5405(0, 2); + cs2method5405(1, 2); + cs2method5406(0, 0, script_3460(31, 22, arg1), 600, script_3460(31, 23, arg1), 600, 0); + cs2method5406(1, 0, script_3460(32, 29, arg1), 50, script_3460(32, 30, arg1), 50, 0); + cs2method5406(0, 1, script_3460(35, 33, arg1), 500, script_3460(35, 32, arg1), 500, 0); + cs2method5406(1, 1, script_3460(29, 36, arg1), 50, script_3460(30, 36, arg1), 50, 0); + cameraMethod5502(0, 0, 500, 450, 1, 0); + script_2768(50, arg0); + break; + case 106: + cameraMoveTo(script_3460(33, 38, arg1), 475, 1000, 100); + cameraPointAt(script_3460(29, 33, arg1), 50, 1000, 100); + break; + case 107: + cameraMoveTo(script_3460(32, 37, arg1), 450, 1000, 100); + cameraPointAt(script_3460(31, 31, arg1), 50, 1000, 100); + break; + case 108: + cameraMoveTo(script_3460(35, 38, arg1), 600, 1000, 100); + cameraPointAt(script_3460(29, 36, arg1), 50, 1000, 100); + break; + case 109: + cameraMoveTo(script_3460(35, 37, arg1), 500, 1000, 100); + cameraPointAt(script_3460(31, 31, arg1), 50, 1000, 100); + break; + case 110: + cameraMoveTo(script_3460(35, 36, arg1), 400, 1000, 100); + cameraPointAt(script_3460(28, 34, arg1), 50, 1000, 100); + break; + case 111: + cameraMoveTo(script_3460(36, 35, arg1), 800, 1000, 100); + cameraPointAt(script_3460(29, 36, arg1), 50, 1000, 100); + break; + case 112: + script_2766(0, 50, arg0); + break; + case 113: + cs2method5405(0, 7); + cs2method5405(1, 7); + cs2method5406(0, 0, script_3460(42, 82, arg1), 400, script_3460(42, 79, arg1), 400, 0); + cs2method5406(1, 0, script_3460(42, 58, arg1), 250, script_3460(42, 58, arg1), 250, 0); + cs2method5406(0, 1, script_3460(42, 59, arg1), 1500, script_3460(40, 55, arg1), 1500, 0); + cs2method5406(1, 1, script_3460(41, 46, arg1), 600, script_3460(41, 46, arg1), 600, 0); + cs2method5406(0, 2, script_3460(29, 50, arg1), 1800, script_3460(25, 47, arg1), 1800, 0); + cs2method5406(1, 2, script_3460(36, 43, arg1), 600, script_3460(35, 43, arg1), 600, 0); + cs2method5406(0, 3, script_3460(24, 40, arg1), 2100, script_3460(24, 34, arg1), 2100, 0); + cs2method5406(1, 3, script_3460(36, 42, arg1), 600, script_3460(36, 41, arg1), 600, 0); + cs2method5406(0, 4, script_3460(37, 26, arg1), 2400, script_3460(45, 26, arg1), 2400, 0); + cs2method5406(1, 4, script_3460(37, 42, arg1), 500, script_3460(38, 43, arg1), 500, 0); + cs2method5406(0, 5, script_3460(52, 35, arg1), 1700, script_3460(55, 39, arg1), 1700, 0); + cs2method5406(1, 5, script_3460(38, 42, arg1), 400, script_3460(38, 41, arg1), 400, 0); + cs2method5406(0, 6, script_3460(47, 52, arg1), 600, script_3460(43, 55, arg1), 600, 0); + cs2method5406(1, 6, script_3460(37, 48, arg1), 325, script_3460(37, 49, arg1), 325, 0); + setScriptCallOnMinimapRelatedSetting3(3468, new WidgetPointer(arg0), 1, 900, 1300, 1300, 1600, 1600, 1600, 1600, 1200, 1200, 200, "Iiiiiiiiiiii", new WidgetPointer(arg0)); + cameraMethod5502(0, 0, 100, 900, 1, 0); + script_2768(50, arg0); + break; + case 114: + cs2method5405(0, 3); + cs2method5405(1, 3); + cs2method5406(0, 0, script_3460(43, 59, arg1), 800, script_3460(43, 59, arg1), 800, 0); + cs2method5406(1, 0, script_3460(37, 37, arg1), 10, script_3460(37, 37, arg1), 10, 0); + cs2method5406(0, 1, script_3460(35, 59, arg1), 800, script_3460(35, 59, arg1), 800, 0); + cs2method5406(1, 1, script_3460(39, 38, arg1), 10, script_3460(39, 38, arg1), 10, 0); + cs2method5406(0, 2, script_3460(33, 60, arg1), 1000, script_3460(33, 60, arg1), 1000, 0); + cs2method5406(1, 2, script_3460(39, 38, arg1), 10, script_3460(39, 38, arg1), 10, 0); + setScriptCallOnMinimapRelatedSetting3(3468, new WidgetPointer(arg0), 1, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Iiiiiiiiiiii", new WidgetPointer(arg0)); + cameraMethod5502(0, 0, 150, 100, 1, 0); + break; + case 115: + setScriptCallOnMinimapRelatedSetting3(-1, "", new WidgetPointer(arg0)); + cs2method5405(0, 2); + cs2method5405(1, 2); + cs2method5406(0, 0, script_3460(35, 49, arg1), 800, script_3460(36, 48, arg1), 800, 0); + cs2method5406(1, 0, script_3460(42, 52, arg1), 200, script_3460(42, 52, arg1), 200, 0); + cs2method5406(0, 1, script_3460(39, 48, arg1), 800, script_3460(39, 48, arg1), 800, 0); + cs2method5406(1, 1, script_3460(41, 52, arg1), 200, script_3460(41, 52, arg1), 200, 0); + cameraMethod5502(0, 0, 150, 0, 1, 0); + break; + case 116: + cs2method5405(0, 15); + cs2method5405(1, 15); + cs2method5406(0, 0, script_3460(41, 55, arg1), 275, script_3460(41, 55, arg1), 275, 0); + cs2method5406(1, 0, script_3460(39, 47, arg1), 10, script_3460(39, 47, arg1), 10, 0); + cs2method5406(0, 1, script_3460(42, 55, arg1), 280, script_3460(42, 55, arg1), 280, 250); + cs2method5406(1, 1, script_3460(39, 47, arg1), 20, script_3460(39, 47, arg1), 20, 0); + cs2method5406(0, 2, script_3460(41, 55, arg1), 285, script_3460(41, 55, arg1), 285, -500); + cs2method5406(1, 2, script_3460(39, 47, arg1), 30, script_3460(39, 47, arg1), 30, 0); + cs2method5406(0, 3, script_3460(42, 55, arg1), 290, script_3460(42, 55, arg1), 290, 500); + cs2method5406(1, 3, script_3460(39, 47, arg1), 40, script_3460(39, 47, arg1), 40, 0); + cs2method5406(0, 4, script_3460(41, 55, arg1), 295, script_3460(41, 55, arg1), 295, -500); + cs2method5406(1, 4, script_3460(39, 47, arg1), 50, script_3460(39, 47, arg1), 50, 0); + cs2method5406(0, 5, script_3460(42, 55, arg1), 350, script_3460(42, 55, arg1), 350, 750); + cs2method5406(1, 5, script_3460(39, 47, arg1), 50, script_3460(39, 47, arg1), 50, 0); + cs2method5406(0, 6, script_3460(40, 55, arg1), 425, script_3460(40, 55, arg1), 425, -750); + cs2method5406(1, 6, script_3460(39, 47, arg1), 50, script_3460(39, 47, arg1), 50, 0); + cs2method5406(0, 7, script_3460(42, 55, arg1), 550, script_3460(42, 55, arg1), 550, 750); + cs2method5406(1, 7, script_3460(39, 47, arg1), 50, script_3460(39, 47, arg1), 50, 0); + cs2method5406(0, 8, script_3460(41, 55, arg1), 675, script_3460(41, 55, arg1), 675, -750); + cs2method5406(1, 8, script_3460(39, 47, arg1), 50, script_3460(39, 47, arg1), 50, 0); + cs2method5406(0, 9, script_3460(43, 55, arg1), 850, script_3460(43, 55, arg1), 850, 500); + cs2method5406(1, 9, script_3460(39, 47, arg1), 50, script_3460(39, 47, arg1), 50, 0); + cs2method5406(0, 10, script_3460(41, 55, arg1), 1000, script_3460(41, 55, arg1), 1000, -500); + cs2method5406(1, 10, script_3460(39, 47, arg1), 50, script_3460(39, 47, arg1), 50, 0); + cs2method5406(0, 11, script_3460(42, 55, arg1), 1150, script_3460(42, 55, arg1), 1150, 250); + cs2method5406(1, 11, script_3460(39, 47, arg1), 50, script_3460(39, 47, arg1), 50, 0); + cs2method5406(0, 12, script_3460(41, 55, arg1), 1300, script_3460(41, 55, arg1), 1300, -250); + cs2method5406(1, 12, script_3460(39, 47, arg1), 50, script_3460(39, 47, arg1), 50, 0); + cs2method5406(0, 13, script_3460(42, 55, arg1), 1450, script_3460(42, 55, arg1), 1450, 125); + cs2method5406(1, 13, script_3460(39, 47, arg1), 50, script_3460(39, 47, arg1), 50, 0); + cs2method5406(0, 14, script_3460(41, 55, arg1), 1500, script_3460(41, 55, arg1), 1500, 0); + cs2method5406(1, 14, script_3460(39, 47, arg1), 50, script_3460(39, 47, arg1), 50, 0); + setScriptCallOnMinimapRelatedSetting3(3469, new WidgetPointer(arg0), 1, "Ii", new WidgetPointer(arg0)); + cameraMethod5502(0, 0, 2500, 3200, 1, 0); + break; + case 117: + setScriptCallOnMinimapRelatedSetting3(-1, "", new WidgetPointer(arg0)); + script_2766(0, 50, arg0); + break; + case 118: + script_2768(50, arg0); + break; + default: + cs2method5512(); + } + return; +} diff --git a/dumps/scripts/3467.cs2 b/dumps/scripts/3467.cs2 new file mode 100644 index 0000000..2170292 --- /dev/null +++ b/dumps/scripts/3467.cs2 @@ -0,0 +1,8 @@ +void script_3467(int arg0,int arg1,int arg2) { + if (subtract(getClientCycle(), arg1) < arg2) { + return; + } + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + script_2766(0, 50, arg0); + return; +} diff --git a/dumps/scripts/3468.cs2 b/dumps/scripts/3468.cs2 new file mode 100644 index 0000000..6a8ee68 --- /dev/null +++ b/dumps/scripts/3468.cs2 @@ -0,0 +1,9 @@ +void script_3468(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11) { + if (arg1 < subtract(cs2method5407(0), 1)) { + cameraMethod5502(0, arg1, arg2, arg3, 1, arg1); + setScriptCallOnMinimapRelatedSetting3(3468, new WidgetPointer(arg0), add(arg1, 1), arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, 0, 0, "Iiiiiiiiiiii", new WidgetPointer(arg0)); + } else { + setScriptCallOnMinimapRelatedSetting3(-1, "", new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/3469.cs2 b/dumps/scripts/3469.cs2 new file mode 100644 index 0000000..81facbb --- /dev/null +++ b/dumps/scripts/3469.cs2 @@ -0,0 +1,20 @@ +void script_3469(int arg0,int arg1) { + switch (rnd(2)) { + case 0: + playSoundEffect(6645, 1, rndExcl(15)); + break; + case 1: + playSoundEffect(6644, 1, rndExcl(15)); + break; + case 2: + playSoundEffect(6643, 1, rndExcl(15)); + } + if (arg1 < subtract(cs2method5407(0), 2)) { + cameraMethod5502(0, arg1, 3100, 3300, 1, arg1); + setScriptCallOnMinimapRelatedSetting3(3469, new WidgetPointer(arg0), add(arg1, 1), "Ii", new WidgetPointer(arg0)); + return; + } + cameraMethod5502(0, arg1, 1000, 0, 1, arg1); + setScriptCallOnMinimapRelatedSetting3(-1, "", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/347.cs2 b/dumps/scripts/347.cs2 new file mode 100644 index 0000000..2e3e28e --- /dev/null +++ b/dumps/scripts/347.cs2 @@ -0,0 +1,17 @@ +void script_347(int arg0,int arg1,int arg2) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + if (arg2 == -1) { + setScriptCallOnGameloop(1518, new WidgetPointer(-32768,3), -2147483643, 0, "Iii"); + setScriptCallOnMousePressed(347, new WidgetPointer(-32768,3), -2147483643, -2147483647, "Iii"); + } else { + arg2 = subtract(arg2, divide(getWidgetActualWidth(), 2)); + if (arg2 >= 0) { + setScriptCallOnGameloop(1518, new WidgetPointer(-32768,3), -2147483643, 1, "Iii"); + } else { + setScriptCallOnGameloop(1518, new WidgetPointer(-32768,3), -2147483643, -1, "Iii"); + } + setScriptCallOnMousePressed(347, new WidgetPointer(-32768,3), -2147483643, -1, "Iii"); + } + } + return; +} diff --git a/dumps/scripts/3470.cs2 b/dumps/scripts/3470.cs2 new file mode 100644 index 0000000..efcb62e --- /dev/null +++ b/dumps/scripts/3470.cs2 @@ -0,0 +1,28 @@ +void script_3470(int arg0,int arg1) { + switch (globalint_1007) { + case 1: + deleteAllExtraChilds(new WidgetPointer(arg0)); + script_2766(0, 75, arg0); + break; + case 2: + cs2method5405(0, 5); + cs2method5405(1, 5); + cs2method5406(0, 0, script_3459(62019146, arg1), 510, script_3459(62035526, arg1), 715, 0); + cs2method5406(1, 0, script_3459(62117455, arg1), 170, script_3459(62051920, arg1), 170, 0); + cs2method5406(0, 1, script_3459(62658120, arg1), 1035, script_3459(62772815, arg1), 1430, 0); + cs2method5406(1, 1, script_3459(62527055, arg1), 170, script_3459(62576213, arg1), 170, 0); + cs2method5406(0, 2, script_3459(62527082, arg1), 2095, script_3459(62363249, arg1), 2095, 0); + cs2method5406(1, 2, script_3459(62379614, arg1), 170, script_3459(62264928, arg1), 170, 0); + cs2method5406(0, 3, script_3459(62035560, arg1), 1565, script_3459(61920865, arg1), 965, 0); + cs2method5406(1, 3, script_3459(62183006, arg1), 170, script_3459(62101084, arg1), 170, 0); + cs2method5406(0, 4, script_3459(62019146, arg1), 470, script_3459(62051906, arg1), 435, 0); + cs2method5406(1, 4, script_3459(62117455, arg1), 170, script_3459(62133836, arg1), 170, 0); + script_2768(150, arg0); + setScriptCallOnMinimapRelatedSetting3(3471, new WidgetPointer(arg0), 1, "Ii", new WidgetPointer(arg0)); + cameraMethod5502(0, 0, 100, 700, 1, 0); + break; + default: + cs2method5512(); + } + return; +} diff --git a/dumps/scripts/3471.cs2 b/dumps/scripts/3471.cs2 new file mode 100644 index 0000000..a713cf4 --- /dev/null +++ b/dumps/scripts/3471.cs2 @@ -0,0 +1,10 @@ +void script_3471(int arg0,int arg1) { + if (arg1 < subtract(cs2method5407(0), 1)) { + cameraMethod5502(0, arg1, 700, 700, 1, arg1); + setScriptCallOnMinimapRelatedSetting3(3471, new WidgetPointer(arg0), add(arg1, 1), "Ii", new WidgetPointer(arg0)); + } else { + setScriptCallOnMinimapRelatedSetting3(-1, "", new WidgetPointer(arg0)); + cs2method5512(); + } + return; +} diff --git a/dumps/scripts/3472.cs2 b/dumps/scripts/3472.cs2 new file mode 100644 index 0000000..85c3475 --- /dev/null +++ b/dumps/scripts/3472.cs2 @@ -0,0 +1,151 @@ +void script_3472(int arg0,int arg1) { + switch (globalint_1007) { + case 51: + deleteAllExtraChilds(new WidgetPointer(arg0)); + script_2766(0, 100, arg0); + break; + case 52: + if (((globalint_1065 == -1) || (subtract(extractX(getMyPositionHash()), extractX(globalint_1065)) > 128)) || (subtract(extractY(getMyPositionHash()), extractY(globalint_1065)) > 128)) { + globalint_1065 = script_284(getMyPositionHash()); + } + script_2768(75, arg0); + cs2method5405(0, 2); + cs2method5405(1, 2); + cs2method5406(0, 0, script_3474(0, 30, 26), 500, script_3474(0, 29, 26), 500, 0); + cs2method5406(1, 0, script_3474(0, 33, 26), 250, script_3474(0, 33, 26), 250, 0); + cs2method5406(0, 1, script_3474(0, 20, 30), 600, script_3474(0, 20, 30), 500, 0); + cs2method5406(1, 1, script_3474(0, 23, 26), 250, script_3474(0, 23, 26), 250, 0); + cameraMethod5502(0, 0, 150, 150, 1, 0); + break; + case 53: + cs2method5405(0, 3); + cs2method5405(1, 3); + cs2method5406(0, 0, script_3474(0, 7, 26), 425, script_3474(0, 6, 26), 425, 0); + cs2method5406(1, 0, script_3474(0, 13, 25), 275, script_3474(0, 13, 25), 275, 0); + cs2method5406(0, 1, script_3474(0, 5, 28), 425, script_3474(0, 6, 26), 425, 0); + cs2method5406(1, 1, script_3474(0, 11, 27), 275, script_3474(0, 11, 27), 275, 0); + cs2method5406(0, 2, script_3474(0, 3, 26), 425, script_3474(0, 3, 27), 425, 0); + cs2method5406(1, 2, script_3474(0, 11, 26), 275, script_3474(0, 11, 26), 275, 0); + setScriptCallOnMinimapRelatedSetting3(3473, new WidgetPointer(arg0), 1, 50, 0, 0, 0, "Iiiiii", new WidgetPointer(arg0)); + cameraMethod5502(0, 0, 150, 50, 1, 0); + break; + case 54: + setScriptCallOnMinimapRelatedSetting3(-1, "", new WidgetPointer(arg0)); + script_2766(0, 25, arg0); + break; + case 55: + script_2768(25, arg0); + cs2method5405(0, 4); + cs2method5405(1, 4); + cs2method5406(0, 0, script_3474(0, 79, 16), 800, script_3474(0, 79, 16), 800, 0); + cs2method5406(1, 0, script_3474(0, 73, 18), 325, script_3474(0, 73, 18), 325, 0); + cs2method5406(0, 1, script_3474(0, 81, 17), 900, script_3474(0, 81, 17), 900, 0); + cs2method5406(1, 1, script_3474(0, 73, 17), 275, script_3474(0, 73, 17), 275, 0); + cs2method5406(0, 2, script_3474(0, 82, 19), 1000, script_3474(0, 82, 19), 1000, 0); + cs2method5406(1, 2, script_3474(0, 73, 16), 225, script_3474(0, 73, 16), 225, 0); + cs2method5406(0, 3, script_3474(0, 82, 16), 1100, script_3474(0, 82, 16), 1100, 0); + cs2method5406(1, 3, script_3474(0, 73, 17), 175, script_3474(0, 73, 17), 175, 0); + setScriptCallOnMinimapRelatedSetting3(3473, new WidgetPointer(arg0), 1, 175, 125, 125, 0, "Iiiiii", new WidgetPointer(arg0)); + cameraMethod5502(0, 0, 150, 175, 1, 0); + break; + case 56: + script_2768(25, arg0); + cs2method5405(0, 2); + cs2method5405(1, 2); + cs2method5406(0, 0, script_3474(0, 3, 28), 425, script_3474(0, 3, 27), 425, 0); + cs2method5406(1, 0, script_3474(0, 11, 26), 275, script_3474(0, 11, 26), 275, 0); + cs2method5406(0, 1, script_3474(0, 0, 25), 425, script_3474(0, 0, 26), 425, 0); + cs2method5406(1, 1, script_3474(0, 11, 26), 275, script_3474(0, 11, 26), 275, 0); + cameraMethod5502(0, 0, 75, 0, 1, 0); + break; + case 57: + script_2768(25, arg0); + cs2method5405(0, 2); + cs2method5405(1, 2); + cs2method5406(0, 0, script_3474(0, 123, 15), 800, script_3474(0, 123, 15), 800, 0); + cs2method5406(1, 0, script_3474(0, 114, 11), 175, script_3474(0, 114, 11), 175, 0); + cs2method5406(0, 1, script_3474(0, 120, 10), 600, script_3474(0, 120, 10), 600, 0); + cs2method5406(1, 1, script_3474(0, 114, 12), 275, script_3474(0, 114, 12), 275, 0); + cameraMethod5502(0, 0, 100, 0, 1, 0); + break; + case 58: + script_2768(25, arg0); + cs2method5405(0, 2); + cs2method5405(1, 2); + cs2method5406(0, 0, script_3474(0, 7, 26), 400, script_3474(0, 7, 26), 400, 0); + cs2method5406(1, 0, script_3474(0, 11, 27), 275, script_3474(0, 11, 27), 275, 0); + cs2method5406(0, 1, script_3474(0, 8, 29), 400, script_3474(0, 8, 29), 400, 0); + cs2method5406(1, 1, script_3474(0, 11, 28), 275, script_3474(0, 11, 28), 275, 0); + cameraMethod5502(0, 0, 50, 0, 1, 0); + break; + case 59: + setScriptCallOnMinimapRelatedSetting3(-1, "", new WidgetPointer(arg0)); + script_2766(0, 75, arg0); + break; + case 60: + script_2768(75, arg0); + cs2method5405(0, 2); + cs2method5405(1, 2); + cs2method5406(0, 0, script_3474(0, 43, 28), 700, script_3474(0, 42, 28), 700, 0); + cs2method5406(1, 0, script_3474(0, 31, 24), 200, script_3474(0, 31, 24), 200, 0); + cs2method5406(0, 1, script_3474(0, 36, 25), 425, script_3474(0, 36, 25), 425, 0); + cs2method5406(1, 1, script_3474(0, 32, 27), 275, script_3474(0, 32, 27), 275, 0); + cameraMethod5502(0, 0, 125, 0, 1, 0); + break; + case 61: + script_2768(50, arg0); + cs2method5405(0, 3); + cs2method5405(1, 3); + cs2method5406(0, 0, script_3474(0, 40, 90), 1200, script_3474(0, 35, 90), 1200, -2000); + cs2method5406(1, 0, script_3474(0, 24, 110), 425, script_3474(0, 24, 110), 425, 0); + cs2method5406(0, 1, script_3474(0, 15, 97), 700, script_3474(0, 14, 97), 700, 500); + cs2method5406(1, 1, script_3474(0, 29, 110), 400, script_3474(0, 29, 110), 400, 0); + cs2method5406(0, 2, script_3474(0, 22, 102), 650, script_3474(0, 22, 102), 650, 0); + cs2method5406(1, 2, script_3474(0, 30, 111), 400, script_3474(0, 30, 111), 400, 0); + setScriptCallOnMinimapRelatedSetting3(3473, new WidgetPointer(arg0), 1, 400, 100, 100, 0, "Iiiiii", new WidgetPointer(arg0)); + cameraMethod5502(0, 0, 400, 400, 1, 0); + break; + case 62: + setScriptCallOnMinimapRelatedSetting3(-1, "", new WidgetPointer(arg0)); + cs2method5405(0, 2); + cs2method5405(1, 2); + cs2method5406(0, 0, script_3474(0, 34, 120), 750, script_3474(0, 29, 120), 750, 0); + cs2method5406(1, 0, script_3474(0, 30, 112), 425, script_3474(0, 30, 112), 425, 0); + cs2method5406(0, 1, script_3474(0, 33, 117), 750, script_3474(0, 33, 117), 750, 0); + cs2method5406(1, 1, script_3474(0, 30, 111), 425, script_3474(0, 30, 111), 425, 0); + cameraMethod5502(0, 0, 50, 100, 1, 0); + break; + case 63: + script_2768(50, arg0); + script_2784(1, arg1, 64880645, 64880646, 64880647, 64880648, -1, 1); + setWidgetIsHidden(false, new WidgetPointer(arg1)); + cs2method5405(0, 3); + cs2method5405(1, 3); + cs2method5406(0, 0, script_3474(1, 64, 98), 500, script_3474(1, 66, 96), 500, 0); + cs2method5406(1, 0, script_3474(1, 90, 98), 500, script_3474(1, 90, 98), 500, 0); + cs2method5406(0, 1, script_3474(1, 90, 80), 1000, script_3474(1, 88, 80), 950, 0); + cs2method5406(1, 1, script_3474(1, 91, 98), 500, script_3474(1, 91, 98), 500, 0); + cs2method5406(0, 2, script_3474(1, 91, 87), 1000, script_3474(1, 91, 87), 1000, 0); + cs2method5406(1, 2, script_3474(1, 90, 98), 500, script_3474(1, 90, 98), 500, 0); + setScriptCallOnMinimapRelatedSetting3(3473, new WidgetPointer(arg0), 1, 200, 0, 0, 0, "Iiiiii", new WidgetPointer(arg0)); + cameraMethod5502(0, 0, 700, 700, 1, 0); + break; + case 64: + setScriptCallOnMinimapRelatedSetting3(-1, "", new WidgetPointer(arg0)); + cs2method5405(0, 2); + cs2method5405(1, 2); + cs2method5406(0, 0, script_3474(1, 91, 91), 800, script_3474(1, 91, 91), 800, 0); + cs2method5406(1, 0, script_3474(1, 91, 98), 450, script_3474(1, 91, 98), 450, 0); + cs2method5406(0, 1, script_3474(1, 91, 94), 750, script_3474(1, 91, 94), 750, 0); + cs2method5406(1, 1, script_3474(1, 91, 98), 425, script_3474(1, 91, 98), 425, 0); + cameraMethod5502(0, 0, 75, 0, 1, 0); + break; + case 65: + setWidgetIsHidden(true, new WidgetPointer(arg1)); + script_2768(75, arg0); + break; + default: + cs2method5512(); + } + return; +} diff --git a/dumps/scripts/3473.cs2 b/dumps/scripts/3473.cs2 new file mode 100644 index 0000000..3a72cdf --- /dev/null +++ b/dumps/scripts/3473.cs2 @@ -0,0 +1,9 @@ +void script_3473(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + if (arg1 < subtract(cs2method5407(0), 1)) { + cameraMethod5502(0, arg1, arg2, arg3, 1, arg1); + setScriptCallOnMinimapRelatedSetting3(3473, new WidgetPointer(arg0), add(arg1, 1), arg4, arg5, 0, 0, "Iiiiii", new WidgetPointer(arg0)); + } else { + setScriptCallOnMinimapRelatedSetting3(-1, "", new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/3474.cs2 b/dumps/scripts/3474.cs2 new file mode 100644 index 0000000..a9f9722 --- /dev/null +++ b/dumps/scripts/3474.cs2 @@ -0,0 +1,3 @@ +int script_3474(int arg0,int arg1,int arg2) { + return addToCoordinate(globalint_1065, arg1, arg0, arg2); +} diff --git a/dumps/scripts/3475.cs2 b/dumps/scripts/3475.cs2 new file mode 100644 index 0000000..78a142d --- /dev/null +++ b/dumps/scripts/3475.cs2 @@ -0,0 +1,19 @@ +void script_3475(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + script_1088(arg0, 0); + script_680(arg3); + script_680(arg5); + setScriptCallOnMouseEntered(95, new WidgetPointer(arg3), "I", new WidgetPointer(arg2)); + setScriptCallOnMouseEntered(95, new WidgetPointer(arg5), "I", new WidgetPointer(arg4)); + setScriptCallOnMouseExit(93, new WidgetPointer(arg3), "I", new WidgetPointer(arg2)); + setScriptCallOnMouseExit(93, new WidgetPointer(arg5), "I", new WidgetPointer(arg4)); + cs2method2100(0, 300, new WidgetPointer(arg1)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg1)); + setWidgetIsHidden(false, new WidgetPointer(arg2)); + setWidgetIsHidden(false, new WidgetPointer(arg4)); + setScriptCallOnClickContextMenu(3479, new WidgetPointer(arg1), new WidgetPointer(arg2), new WidgetPointer(arg4), 1, "III1", new WidgetPointer(arg2)); + setScriptCallOnClickContextMenu(3479, new WidgetPointer(arg1), new WidgetPointer(arg2), new WidgetPointer(arg4), 0, "III1", new WidgetPointer(arg4)); + setScriptCallOnConfigChange(3476, 1506, 1507, 1508, 3, "Y", new WidgetPointer(arg0)); + setScriptCallOnGlobalConfigChange(3476, 1317, 1318, 2, "Y", new WidgetPointer(arg0)); + script_3477(); + return; +} diff --git a/dumps/scripts/3476.cs2 b/dumps/scripts/3476.cs2 new file mode 100644 index 0000000..058ba8b --- /dev/null +++ b/dumps/scripts/3476.cs2 @@ -0,0 +1,4 @@ +void script_3476() { + script_3477(); + return; +} diff --git a/dumps/scripts/3477.cs2 b/dumps/scripts/3477.cs2 new file mode 100644 index 0000000..6f3de92 --- /dev/null +++ b/dumps/scripts/3477.cs2 @@ -0,0 +1,329 @@ +void script_3477() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + ivar0 = subtract(3, script_3484(1)); + if (ivar0 > 0) { + setItemOnWidgetMethod2212(cs2method_3408(105, 111, 3082, 1), ivar0, new WidgetPointer(991,7)); + setScriptCallOnClickContextMenu(3481, -2147483644, "i", new WidgetPointer(991,7)); + setWidgetContextMenuOption(1, new WidgetPointer(991,7), "Select"); + } else { + setItemOnWidgetMethod2205(-1, 0, new WidgetPointer(991,7)); + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(991,7)); + setWidgetNoOptions(new WidgetPointer(991,7)); + } + ivar0 = subtract(2, script_3484(2)); + if (ivar0 > 0) { + setItemOnWidgetMethod2212(cs2method_3408(105, 111, 3082, 2), ivar0, new WidgetPointer(991,8)); + setScriptCallOnClickContextMenu(3481, -2147483644, "i", new WidgetPointer(991,8)); + setWidgetContextMenuOption(1, new WidgetPointer(991,8), "Select"); + } else { + setItemOnWidgetMethod2205(-1, 0, new WidgetPointer(991,8)); + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(991,8)); + setWidgetNoOptions(new WidgetPointer(991,8)); + } + ivar0 = subtract(2, script_3484(3)); + if (ivar0 > 0) { + setItemOnWidgetMethod2212(cs2method_3408(105, 111, 3082, 3), ivar0, new WidgetPointer(991,9)); + setScriptCallOnClickContextMenu(3481, -2147483644, "i", new WidgetPointer(991,9)); + setWidgetContextMenuOption(1, new WidgetPointer(991,9), "Select"); + } else { + setItemOnWidgetMethod2205(-1, 0, new WidgetPointer(991,9)); + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(991,9)); + setWidgetNoOptions(new WidgetPointer(991,9)); + } + ivar0 = subtract(2, script_3485(1)); + if (ivar0 > 0) { + setItemOnWidgetMethod2212(cs2method_3408(105, 111, 3083, 1), ivar0, new WidgetPointer(991,17)); + setScriptCallOnClickContextMenu(3481, -2147483644, "i", new WidgetPointer(991,17)); + setWidgetContextMenuOption(1, new WidgetPointer(991,17), "Select"); + } else { + setItemOnWidgetMethod2205(-1, 0, new WidgetPointer(991,17)); + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(991,17)); + setWidgetNoOptions(new WidgetPointer(991,17)); + } + ivar0 = subtract(4, script_3485(2)); + if (ivar0 > 0) { + setItemOnWidgetMethod2212(cs2method_3408(105, 111, 3083, 2), ivar0, new WidgetPointer(991,18)); + setScriptCallOnClickContextMenu(3481, -2147483644, "i", new WidgetPointer(991,18)); + setWidgetContextMenuOption(1, new WidgetPointer(991,18), "Select"); + } else { + setItemOnWidgetMethod2205(-1, 0, new WidgetPointer(991,18)); + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(991,18)); + setWidgetNoOptions(new WidgetPointer(991,18)); + } + ivar0 = subtract(2, script_3485(3)); + if (ivar0 > 0) { + setItemOnWidgetMethod2212(cs2method_3408(105, 111, 3083, 3), ivar0, new WidgetPointer(991,19)); + setScriptCallOnClickContextMenu(3481, -2147483644, "i", new WidgetPointer(991,19)); + setWidgetContextMenuOption(1, new WidgetPointer(991,19), "Select"); + } else { + setItemOnWidgetMethod2205(-1, 0, new WidgetPointer(991,19)); + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(991,19)); + setWidgetNoOptions(new WidgetPointer(991,19)); + } + deleteAllExtraChilds(new WidgetPointer(991,13)); + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + while (ivar1 < 28) { + createExtraChild(new WidgetPointer(991,13), 5, ivar1); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(add(multiply(subtract(6, ivar2), 16), multiply(ivar3, 32)), multiply(ivar2, 32), 0, 2); + ivar0 = script_3482(ivar1); + setItemOnWidgetMethod1205(cs2method_3408(105, 111, 3082, ivar0), 1); + if (ivar0 > 0) { + setWidgetContextMenuOption(1, "Remove tile"); + setScriptCallOnClickContextMenu(1620, new WidgetPointer(-32768,3), -2147483643, 150, 0, 10, "Iiiii"); + cs2method1303(5); + cs2method1304(5); + cs2method1302(2); + } + if (ivar3 >= ivar2) { + ivar3 = 0; + ivar2 = add(ivar2, 1); + } else { + ivar3 = add(ivar3, 1); + } + ivar1 = add(ivar1, 1); + } + deleteAllExtraChilds(new WidgetPointer(991,23)); + ivar1 = 0; + ivar2 = 6; + ivar3 = 0; + while (ivar1 < 28) { + createExtraChild(new WidgetPointer(991,23), 5, ivar1); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(add(multiply(subtract(6, ivar2), 16), multiply(ivar3, 32)), multiply(ivar2, 32), 0, 0); + ivar0 = script_3483(ivar1); + setItemOnWidgetMethod1205(cs2method_3408(105, 111, 3083, ivar0), 1); + if (ivar0 > 0) { + setWidgetContextMenuOption(1, "Remove tile"); + setScriptCallOnClickContextMenu(1620, new WidgetPointer(-32768,3), -2147483643, 125, 0, 8, "Iiiii"); + cs2method1303(5); + cs2method1304(5); + cs2method1302(2); + } + if (ivar3 >= ivar2) { + ivar3 = 0; + ivar2 = subtract(ivar2, 1); + } else { + ivar3 = add(ivar3, 1); + } + ivar1 = add(ivar1, 1); + } + script_3478(64946189, 0, 7, 16750623); + ivar1 = 0; + while (ivar1 <= 30) { + if (isBitFlagged(globalint_1317, ivar1)) { + switch (ivar1) { + case 0: + script_3478(64946189, -1, 5, 16750623); + break; + case 1: + script_3478(64946189, -2, 3, 16750623); + break; + case 2: + script_3478(64946189, 0, 3, 16750623); + break; + case 3: + script_3478(64946189, 2, 3, 16750623); + break; + case 4: + script_3478(64946189, -3, 1, 16750623); + break; + case 5: + script_3478(64946189, 1, 1, 16750623); + break; + case 6: + script_3478(64946189, 3, 1, 16750623); + break; + case 7: + script_3478(64946189, -4, -1, 16750623); + break; + case 8: + script_3478(64946189, -2, -1, 16750623); + break; + case 9: + script_3478(64946189, 2, -1, 16750623); + break; + case 10: + script_3478(64946189, 4, -1, 16750623); + break; + case 11: + script_3478(64946189, -5, -3, 16750623); + break; + case 12: + script_3478(64946189, -3, -3, 16750623); + break; + case 13: + script_3478(64946189, 1, -3, 16750623); + break; + case 14: + script_3478(64946189, 3, -3, 16750623); + break; + case 15: + script_3478(64946189, 5, -3, 16750623); + break; + case 16: + script_3478(64946189, -6, -5, 16750623); + break; + case 17: + script_3478(64946189, -4, -5, 16750623); + break; + case 18: + script_3478(64946189, -2, -5, 16750623); + break; + case 19: + script_3478(64946189, 0, -5, 16750623); + break; + case 20: + script_3478(64946189, 2, -5, 16750623); + break; + case 21: + script_3478(64946189, 4, -5, 16750623); + break; + case 22: + script_3478(64946189, 6, -5, 16750623); + break; + case 23: + script_3478(64946189, -7, -7, 16750623); + script_3478(64946199, -7, 7, 16750623); + break; + case 24: + script_3478(64946189, -5, -7, 16750623); + script_3478(64946199, -5, 7, 16750623); + break; + case 25: + script_3478(64946189, -3, -7, 16750623); + script_3478(64946199, -3, 7, 16750623); + break; + case 26: + script_3478(64946189, -1, -7, 16750623); + script_3478(64946199, -1, 7, 16750623); + break; + case 27: + script_3478(64946189, 1, -7, 16750623); + script_3478(64946199, 1, 7, 16750623); + break; + case 28: + script_3478(64946189, 3, -7, 16750623); + script_3478(64946199, 3, 7, 16750623); + break; + case 29: + script_3478(64946189, 5, -7, 16750623); + script_3478(64946199, 5, 7, 16750623); + break; + case 30: + script_3478(64946189, 7, -7, 16750623); + script_3478(64946199, 7, 7, 16750623); + } + } + ivar1 = add(ivar1, 1); + } + ivar1 = 0; + while (ivar1 <= 30) { + if (isBitFlagged(globalint_1318, ivar1)) { + switch (ivar1) { + case 0: + script_3478(64946199, -6, 5, 16750623); + break; + case 1: + script_3478(64946199, -4, 5, 16750623); + break; + case 2: + script_3478(64946199, -2, 5, 16750623); + break; + case 3: + script_3478(64946199, 0, 5, 16750623); + break; + case 4: + script_3478(64946199, 2, 5, 16750623); + break; + case 5: + script_3478(64946199, 4, 5, 16750623); + break; + case 6: + script_3478(64946199, 6, 5, 16750623); + break; + case 7: + script_3478(64946199, -5, 3, 16750623); + break; + case 8: + script_3478(64946199, -3, 3, 16750623); + break; + case 9: + script_3478(64946199, 3, 3, 16750623); + break; + case 10: + script_3478(64946199, 5, 3, 16750623); + break; + case 11: + script_3478(64946199, -4, 1, 16750623); + break; + case 12: + script_3478(64946199, 4, 1, 16750623); + break; + case 13: + script_3478(64946199, -3, -1, 16750623); + break; + case 14: + script_3478(64946199, -1, -1, 16750623); + break; + case 15: + script_3478(64946199, 1, -1, 16750623); + break; + case 16: + script_3478(64946199, 3, -1, 16750623); + break; + case 17: + script_3478(64946199, 0, -3, 16750623); + break; + case 18: + script_3478(64946199, 2, -3, 16750623); + break; + case 19: + script_3478(64946199, -1, -5, 16750623); + break; + case 20: + script_3478(64946199, 0, -7, 16750623); + break; + case 21: + script_3478(64946189, 1, 5, 0); + break; + case 22: + script_3478(64946189, -1, 1, 0); + break; + case 23: + script_3478(64946189, 0, -1, 0); + break; + case 24: + script_3478(64946189, -1, -3, 0); + break; + case 25: + script_3478(64946199, 1, 3, 0); + break; + case 26: + script_3478(64946199, -2, 1, 0); + break; + case 27: + script_3478(64946199, 0, 1, 0); + break; + case 28: + script_3478(64946199, 2, 1, 0); + break; + case 29: + script_3478(64946199, -2, -3, 0); + break; + case 30: + script_3478(64946199, 1, -5, 0); + break; + default: + setWidgetHidden(1); + } + } + ivar1 = add(ivar1, 1); + } + return; +} diff --git a/dumps/scripts/3478.cs2 b/dumps/scripts/3478.cs2 new file mode 100644 index 0000000..3f5fd11 --- /dev/null +++ b/dumps/scripts/3478.cs2 @@ -0,0 +1,8 @@ +void script_3478(int arg0,int arg1,int arg2,int arg3) { + createExtraChild(new WidgetPointer(arg0), 3, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(6, 6, 0, 0); + setWidgetRGB(new Color(arg3)); + setWidgetFilled(1); + setWidgetPosition(multiply(arg1, 16), multiply(arg2, 16), 1, 1); + return; +} diff --git a/dumps/scripts/3479.cs2 b/dumps/scripts/3479.cs2 new file mode 100644 index 0000000..1ca4858 --- /dev/null +++ b/dumps/scripts/3479.cs2 @@ -0,0 +1,7 @@ +void script_3479(int arg0,int arg1,int arg2,int arg3) { + setWidgetIsHidden(true, new WidgetPointer(arg1)); + setWidgetIsHidden(true, new WidgetPointer(arg2)); + playSoundEffect(2871, 1, 0); + setScriptCallOnGameloop(3480, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), arg3, getClientCycle(), "III1i", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/348.cs2 b/dumps/scripts/348.cs2 new file mode 100644 index 0000000..e8993d6 --- /dev/null +++ b/dumps/scripts/348.cs2 @@ -0,0 +1,20 @@ +void script_348(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + ivar3 = script_166(arg2); + ivar4 = 941; + if (ivar3 >= 7) { + setWidgetIsHidden(false, new WidgetPointer(arg0)); + setWidgetSprite(942, new WidgetPointer(arg1)); + setScriptCallOnMousePressed(44, new WidgetPointer(arg1), ivar4, "Id", new WidgetPointer(arg0)); + } else if (ivar3 == 6) { + setWidgetIsHidden(false, new WidgetPointer(arg0)); + setWidgetSprite(941, new WidgetPointer(arg1)); + ivar4 = 942; + setScriptCallOnMousePressed(44, new WidgetPointer(arg1), ivar4, "Id", new WidgetPointer(arg0)); + } else { + setWidgetIsHidden(true, new WidgetPointer(arg0)); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/3480.cs2 b/dumps/scripts/3480.cs2 new file mode 100644 index 0000000..edadbfe --- /dev/null +++ b/dumps/scripts/3480.cs2 @@ -0,0 +1,36 @@ +void script_3480(int arg0,int arg1,int arg2,int arg3,int arg4) { + int ivar5; + ivar5 = cs2method2601(new WidgetPointer(arg0)); + if (((boolean)arg3)) { + if (ivar5 != 0) { + ivar5 = max(subtract(ivar5, 6), 0); + cs2method2100(0, ivar5, new WidgetPointer(arg0)); + } + if (ivar5 <= 0) { + cs2method2100(0, 0, new WidgetPointer(arg0)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + setWidgetIsHidden(false, new WidgetPointer(arg1)); + setWidgetIsHidden(false, new WidgetPointer(arg2)); + return; + } + } else { + if (ivar5 != 300) { + ivar5 = min(add(ivar5, 6), 300); + cs2method2100(0, ivar5, new WidgetPointer(arg0)); + } + if (ivar5 >= 300) { + cs2method2100(0, 300, new WidgetPointer(arg0)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + setWidgetIsHidden(false, new WidgetPointer(arg1)); + setWidgetIsHidden(false, new WidgetPointer(arg2)); + return; + } + } + setWidgetIsHidden(true, new WidgetPointer(arg1)); + setWidgetIsHidden(true, new WidgetPointer(arg2)); + if (subtract(getClientCycle(), arg4) >= 10) { + playSoundEffect(2871, 1, 0); + setScriptCallOnGameloop(3480, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), arg3, getClientCycle(), "III1i", new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/3481.cs2 b/dumps/scripts/3481.cs2 new file mode 100644 index 0000000..196d32c --- /dev/null +++ b/dumps/scripts/3481.cs2 @@ -0,0 +1,6 @@ +void script_3481(int arg0) { + if (((boolean)arg0)) { + messageType0("Drag the tiles into the grid."); + } + return; +} diff --git a/dumps/scripts/3482.cs2 b/dumps/scripts/3482.cs2 new file mode 100644 index 0000000..d5d3866 --- /dev/null +++ b/dumps/scripts/3482.cs2 @@ -0,0 +1,61 @@ +int script_3482(int arg0) { + switch (arg0) { + case 0: + return bitconfig_7999; + case 1: + return bitconfig_8000; + case 2: + return -1; + case 3: + return bitconfig_8001; + case 4: + return bitconfig_8002; + case 5: + return bitconfig_8003; + case 6: + return bitconfig_8004; + case 7: + return -1; + case 8: + return bitconfig_8005; + case 9: + return bitconfig_8006; + case 10: + return bitconfig_8007; + case 11: + return bitconfig_8008; + case 12: + return -1; + case 13: + return bitconfig_8009; + case 14: + return bitconfig_8010; + case 15: + return bitconfig_8011; + case 16: + return bitconfig_8012; + case 17: + return -1; + case 18: + return bitconfig_8013; + case 19: + return bitconfig_8014; + case 20: + return bitconfig_8015; + case 21: + return bitconfig_8016; + case 22: + return bitconfig_8017; + case 23: + return bitconfig_8018; + case 24: + return bitconfig_8019; + case 25: + return bitconfig_8020; + case 26: + return bitconfig_8021; + case 27: + return bitconfig_8022; + } + return -1; +} diff --git a/dumps/scripts/3483.cs2 b/dumps/scripts/3483.cs2 new file mode 100644 index 0000000..d6dcbb8 --- /dev/null +++ b/dumps/scripts/3483.cs2 @@ -0,0 +1,61 @@ +int script_3483(int arg0) { + switch (arg0) { + case 0: + return bitconfig_8023; + case 1: + return bitconfig_8024; + case 2: + return bitconfig_8025; + case 3: + return bitconfig_8026; + case 4: + return bitconfig_8027; + case 5: + return bitconfig_8028; + case 6: + return bitconfig_8029; + case 7: + return bitconfig_8030; + case 8: + return bitconfig_8031; + case 9: + return -1; + case 10: + return bitconfig_8032; + case 11: + return bitconfig_8033; + case 12: + return bitconfig_8034; + case 13: + return bitconfig_8035; + case 14: + return -1; + case 15: + return -1; + case 16: + return -1; + case 17: + return bitconfig_8036; + case 18: + return bitconfig_8037; + case 19: + return bitconfig_8038; + case 20: + return bitconfig_8039; + case 21: + return bitconfig_8040; + case 22: + return -1; + case 23: + return bitconfig_8041; + case 24: + return bitconfig_8042; + case 25: + return bitconfig_8043; + case 26: + return -1; + case 27: + return bitconfig_8044; + } + return -1; +} diff --git a/dumps/scripts/3484.cs2 b/dumps/scripts/3484.cs2 new file mode 100644 index 0000000..438545e --- /dev/null +++ b/dumps/scripts/3484.cs2 @@ -0,0 +1,77 @@ +int script_3484(int arg0) { + int ivar1; + ivar1 = 0; + if (bitconfig_7999 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8000 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8001 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8002 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8003 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8004 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8005 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8006 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8007 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8008 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8009 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8010 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8011 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8012 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8013 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8014 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8015 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8016 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8017 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8018 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8019 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8020 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8021 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8022 == arg0) { + ivar1 = add(ivar1, 1); + } + return ivar1; +} diff --git a/dumps/scripts/3485.cs2 b/dumps/scripts/3485.cs2 new file mode 100644 index 0000000..1feadbb --- /dev/null +++ b/dumps/scripts/3485.cs2 @@ -0,0 +1,71 @@ +int script_3485(int arg0) { + int ivar1; + ivar1 = 0; + if (bitconfig_8023 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8024 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8025 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8026 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8027 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8028 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8029 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8030 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8031 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8032 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8033 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8034 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8035 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8036 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8037 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8038 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8039 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8040 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8041 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8042 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8043 == arg0) { + ivar1 = add(ivar1, 1); + } + if (bitconfig_8044 == arg0) { + ivar1 = add(ivar1, 1); + } + return ivar1; +} diff --git a/dumps/scripts/3486.cs2 b/dumps/scripts/3486.cs2 new file mode 100644 index 0000000..2a7aaee --- /dev/null +++ b/dumps/scripts/3486.cs2 @@ -0,0 +1,36 @@ +void script_3486(int arg0,int arg1,int arg2) { + int ivar3; + string svar0; + deleteAllExtraChilds(new WidgetPointer(arg0)); + deleteAllExtraChilds(new WidgetPointer(arg1)); + deleteAllExtraChilds(new WidgetPointer(arg2)); + createExtraChild(new WidgetPointer(arg0), 6, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(0, 0, 1, 1); + setWidgetPosition(0, 0, 1, 1); + setWidget3DRotation(0, 0, 0, 0, 0, 2600); + setWidgetNpcHead(2567); + setWidgetAnimation(9804); + script_2647(arg0); + script_1298(getWidgetParentId(new WidgetPointer(arg1)), 0, 0, 0); + createExtraChild(new WidgetPointer(arg1), 4, getExtraChildGap(new WidgetPointer(arg1))); + setWidgetFont(494); + setWidgetRGB(new Color(255, 255, 255)); + setWidgetUnknownBoolean(true); + setWidgetTextAlignment(0, 1, 0); + svar0 = "To modify the spell so that it goes to our chosen destination, you must connect the " + "" + "start node" + "" + " at the bottom to the " + "" + "destination node" + "" + " in the " + "" + "upper half" + "" + " of the tablet." + "
" + "
" + "Drag the " + "" + "conduit tiles" + "" + " into the grid to form a path leading upwards. You can click tiles to remove them from the grid." + "
" + "
" + "The tablet has been damaged slightly by the chipping process, creating " + "" + "dead zones" + "" + ". Magic cannot flow through a " + "" + "dead zone" + "" + ", so you must route the power around them."; + setWidgetText(svar0); + if (add(multiply(getLineCount(getWidgetActualWidth(new WidgetPointer(arg1)), 494, svar0), 10), 5) <= getWidgetActualHeight(new WidgetPointer(arg1))) { + setWidgetSize(0, 0, 1, 1); + setWidgetPosition(0, 0, 1, 1); + setWidgetScrollMax(0, 0, new WidgetPointer(arg1)); + setWidgetIsHidden(true, new WidgetPointer(arg2)); + return; + } + ivar3 = add(multiply(getLineCount(subtract(getWidgetActualWidth(new WidgetPointer(arg1)), 17), 494, svar0), 10), 5); + setWidgetSize(17, ivar3, 1, 0); + setWidgetPosition(0, 0, 0, 1); + setWidgetScrollMax(0, ivar3, new WidgetPointer(arg1)); + setWidgetIsHidden(false, new WidgetPointer(arg2)); + script_31(arg2, arg1, 792, 789, 790, 791, 773, 788); + return; +} diff --git a/dumps/scripts/3487.cs2 b/dumps/scripts/3487.cs2 new file mode 100644 index 0000000..095e71e --- /dev/null +++ b/dumps/scripts/3487.cs2 @@ -0,0 +1,17 @@ +int script_3487(int arg0) { + int ivar1; + int ivar2; + opcStruct5624(2,0,0) structdump_0; + if ((arg0 < 0) || (arg0 > 63)) { + return 0; + } + ivar1 = 0; + ivar2 = 0; + structdump_0 = getUserflowParam(); + ivar1 = structdump_0.intpart_1; + ivar2 = structdump_0.intpart_0; + if (arg0 < 32) { + return script_734(((int)isBitFlagged(ivar1, arg0))); + } + return script_734(((int)isBitFlagged(ivar2, subtract(arg0, 32)))); +} diff --git a/dumps/scripts/3488.cs2 b/dumps/scripts/3488.cs2 new file mode 100644 index 0000000..751e847 --- /dev/null +++ b/dumps/scripts/3488.cs2 @@ -0,0 +1,22 @@ +void script_3488() { + globalint_1186 = 1337; + globalint_1184 = 0; + setWidgetPosition(getWidgetActualX(new WidgetPointer(993,112)), 52, 0, 0, new WidgetPointer(993,112)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(993,27)), 52, 0, 0, new WidgetPointer(993,27)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(993,26)), 52, 0, 0, new WidgetPointer(993,26)); + setWidgetIsHidden(true, new WidgetPointer(993,254)); + setWidgetIsHidden(true, new WidgetPointer(993,239)); + setWidgetIsHidden(true, new WidgetPointer(993,224)); + setWidgetIsHidden(true, new WidgetPointer(993,209)); + cs2method2103(255, new WidgetPointer(993,257)); + cs2method2103(255, new WidgetPointer(993,242)); + cs2method2103(255, new WidgetPointer(993,227)); + cs2method2103(255, new WidgetPointer(993,212)); + setWidgetIsHidden(true, new WidgetPointer(993,194)); + setWidgetIsHidden(true, new WidgetPointer(993,195)); + setWidgetIsHidden(true, new WidgetPointer(993,196)); + setWidgetIsHidden(true, new WidgetPointer(993,197)); + setWidgetIsHidden(true, new WidgetPointer(993,261)); + setWidgetIsHidden(true, new WidgetPointer(993,191)); + return; +} diff --git a/dumps/scripts/3489.cs2 b/dumps/scripts/3489.cs2 new file mode 100644 index 0000000..7a72545 --- /dev/null +++ b/dumps/scripts/3489.cs2 @@ -0,0 +1,175 @@ +void script_3489() { + int ivar0; + int ivar1; + ivar0 = cs2method_3408(105, 103, 3088, globalint_1184); + ivar1 = 0; + if (globalint_1186 < 17) { + switch (globalint_1184) { + case 1: + if (bitconfig_8053 == 10) { + setWidgetIsHidden(true, new WidgetPointer(993,139)); + } else { + setWidgetIsHidden(false, new WidgetPointer(993,139)); + } + if (bitconfig_8054 == 10) { + setWidgetIsHidden(true, new WidgetPointer(993,46)); + } else { + setWidgetIsHidden(false, new WidgetPointer(993,46)); + } + if (bitconfig_8055 == 10) { + setWidgetIsHidden(true, new WidgetPointer(993,88)); + } else { + setWidgetIsHidden(false, new WidgetPointer(993,88)); + } + break; + case 2: + if (bitconfig_8056 == 10) { + setWidgetIsHidden(true, new WidgetPointer(993,139)); + } else { + setWidgetIsHidden(false, new WidgetPointer(993,139)); + } + if (bitconfig_8057 == 10) { + setWidgetIsHidden(true, new WidgetPointer(993,46)); + } else { + setWidgetIsHidden(false, new WidgetPointer(993,46)); + } + if (bitconfig_8058 == 10) { + setWidgetIsHidden(true, new WidgetPointer(993,88)); + } else { + setWidgetIsHidden(false, new WidgetPointer(993,88)); + } + break; + case 3: + if (bitconfig_8059 == 10) { + setWidgetIsHidden(true, new WidgetPointer(993,139)); + } else { + setWidgetIsHidden(false, new WidgetPointer(993,139)); + } + if (bitconfig_8060 == 10) { + setWidgetIsHidden(true, new WidgetPointer(993,46)); + } else { + setWidgetIsHidden(false, new WidgetPointer(993,46)); + } + if (bitconfig_8061 == 10) { + setWidgetIsHidden(true, new WidgetPointer(993,88)); + } else { + setWidgetIsHidden(false, new WidgetPointer(993,88)); + } + break; + case 4: + if (bitconfig_8062 == 10) { + setWidgetIsHidden(true, new WidgetPointer(993,139)); + } else { + setWidgetIsHidden(false, new WidgetPointer(993,139)); + } + if (bitconfig_8063 == 10) { + setWidgetIsHidden(true, new WidgetPointer(993,46)); + } else { + setWidgetIsHidden(false, new WidgetPointer(993,46)); + } + if (bitconfig_8064 == 10) { + setWidgetIsHidden(true, new WidgetPointer(993,88)); + } else { + setWidgetIsHidden(false, new WidgetPointer(993,88)); + } + } + setWidgetPosition(getWidgetActualX(new WidgetPointer(993,112)), add(getWidgetActualY(new WidgetPointer(993,112)), 4), 0, 0, new WidgetPointer(993,112)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(993,27)), add(getWidgetActualY(new WidgetPointer(993,27)), 4), 0, 0, new WidgetPointer(993,27)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(993,26)), add(getWidgetActualY(new WidgetPointer(993,26)), 4), 0, 0, new WidgetPointer(993,26)); + globalint_1186 = add(1, globalint_1186); + } else if (globalint_1186 < 33) { + setWidgetPosition(getWidgetActualX(new WidgetPointer(993,27)), add(getWidgetActualY(new WidgetPointer(993,27)), 4), 0, 0, new WidgetPointer(993,27)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(993,26)), add(getWidgetActualY(new WidgetPointer(993,26)), 4), 0, 0, new WidgetPointer(993,26)); + globalint_1186 = add(1, globalint_1186); + } else if (globalint_1186 < 49) { + setWidgetPosition(getWidgetActualX(new WidgetPointer(993,26)), add(getWidgetActualY(new WidgetPointer(993,26)), 4), 0, 0, new WidgetPointer(993,26)); + globalint_1186 = add(1, globalint_1186); + } else { + if (globalint_1186 < 69) { + ivar1 = multiplyDivide(subtract(globalint_1186, 48), 20, 100); + switch (globalint_1184) { + case 1: + setWidgetSize(multiplyDivide(multiplyDivide(16384, 100, multiply(bitconfig_8053, 10)), 100, ivar1), 16384, 2, 2, new WidgetPointer(993,160)); + if (bitconfig_8053 == 10) { + setWidgetIsHidden(true, new WidgetPointer(993,139)); + } else { + setWidgetIsHidden(false, new WidgetPointer(993,139)); + } + setWidgetSize(multiplyDivide(multiplyDivide(16384, 100, multiply(bitconfig_8054, 10)), 100, ivar1), 16384, 2, 2, new WidgetPointer(993,67)); + if (bitconfig_8054 == 10) { + setWidgetIsHidden(true, new WidgetPointer(993,46)); + } else { + setWidgetIsHidden(false, new WidgetPointer(993,46)); + } + setWidgetSize(multiplyDivide(multiplyDivide(16384, 100, multiply(bitconfig_8055, 10)), 100, ivar1), 16384, 2, 2, new WidgetPointer(993,109)); + if (bitconfig_8055 == 10) { + setWidgetIsHidden(true, new WidgetPointer(993,88)); + } else { + setWidgetIsHidden(false, new WidgetPointer(993,88)); + } + break; + case 2: + setWidgetSize(multiplyDivide(multiplyDivide(16384, 100, multiply(bitconfig_8056, 10)), 100, ivar1), 16384, 2, 2, new WidgetPointer(993,160)); + if (bitconfig_8056 == 10) { + setWidgetIsHidden(true, new WidgetPointer(993,139)); + } else { + setWidgetIsHidden(false, new WidgetPointer(993,139)); + } + setWidgetSize(multiplyDivide(multiplyDivide(16384, 100, multiply(bitconfig_8057, 10)), 100, ivar1), 16384, 2, 2, new WidgetPointer(993,67)); + if (bitconfig_8057 == 10) { + setWidgetIsHidden(true, new WidgetPointer(993,46)); + } else { + setWidgetIsHidden(false, new WidgetPointer(993,46)); + } + setWidgetSize(multiplyDivide(multiplyDivide(16384, 100, multiply(bitconfig_8058, 10)), 100, ivar1), 16384, 2, 2, new WidgetPointer(993,109)); + if (bitconfig_8058 == 10) { + setWidgetIsHidden(true, new WidgetPointer(993,88)); + } else { + setWidgetIsHidden(false, new WidgetPointer(993,88)); + } + break; + case 3: + setWidgetSize(multiplyDivide(multiplyDivide(16384, 100, multiply(bitconfig_8059, 10)), 100, ivar1), 16384, 2, 2, new WidgetPointer(993,160)); + if (bitconfig_8059 == 10) { + setWidgetIsHidden(true, new WidgetPointer(993,139)); + } else { + setWidgetIsHidden(false, new WidgetPointer(993,139)); + } + setWidgetSize(multiplyDivide(multiplyDivide(16384, 100, multiply(bitconfig_8060, 10)), 100, ivar1), 16384, 2, 2, new WidgetPointer(993,67)); + if (bitconfig_8060 == 10) { + setWidgetIsHidden(true, new WidgetPointer(993,46)); + } else { + setWidgetIsHidden(false, new WidgetPointer(993,46)); + } + setWidgetSize(multiplyDivide(multiplyDivide(16384, 100, multiply(bitconfig_8061, 10)), 100, ivar1), 16384, 2, 2, new WidgetPointer(993,109)); + if (bitconfig_8061 == 10) { + setWidgetIsHidden(true, new WidgetPointer(993,88)); + } else { + setWidgetIsHidden(false, new WidgetPointer(993,88)); + } + break; + case 4: + setWidgetSize(multiplyDivide(multiplyDivide(16384, 100, multiply(bitconfig_8062, 10)), 100, ivar1), 16384, 2, 2, new WidgetPointer(993,160)); + if (bitconfig_8062 == 10) { + setWidgetIsHidden(true, new WidgetPointer(993,139)); + } else { + setWidgetIsHidden(false, new WidgetPointer(993,139)); + } + setWidgetSize(multiplyDivide(multiplyDivide(16384, 100, multiply(bitconfig_8063, 10)), 100, ivar1), 16384, 2, 2, new WidgetPointer(993,67)); + if (bitconfig_8063 == 10) { + setWidgetIsHidden(true, new WidgetPointer(993,46)); + } else { + setWidgetIsHidden(false, new WidgetPointer(993,46)); + } + setWidgetSize(multiplyDivide(multiplyDivide(16384, 100, multiply(bitconfig_8064, 10)), 100, ivar1), 16384, 2, 2, new WidgetPointer(993,109)); + if (bitconfig_8064 == 10) { + setWidgetIsHidden(true, new WidgetPointer(993,88)); + } else { + setWidgetIsHidden(false, new WidgetPointer(993,88)); + } + } + globalint_1186 = add(1, globalint_1186); + } + } + return; +} diff --git a/dumps/scripts/349.cs2 b/dumps/scripts/349.cs2 new file mode 100644 index 0000000..f9c5488 --- /dev/null +++ b/dumps/scripts/349.cs2 @@ -0,0 +1,4 @@ +void script_349() { + script_391(); + return; +} diff --git a/dumps/scripts/3490.cs2 b/dumps/scripts/3490.cs2 new file mode 100644 index 0000000..70c8856 --- /dev/null +++ b/dumps/scripts/3490.cs2 @@ -0,0 +1,21 @@ +void script_3490(int arg0) { + int ivar1; + ivar1 = arg0; + switch (arg0) { + case 65077432: + ivar1 = 65077505; + break; + case 65077433: + ivar1 = 65077490; + break; + case 65077434: + ivar1 = 65077475; + break; + case 65077435: + ivar1 = 65077460; + } + if (getWidgetShadeColor(new WidgetPointer(ivar1)) > 220) { + cs2method2103(subtract(getWidgetShadeColor(new WidgetPointer(ivar1)), 2), new WidgetPointer(ivar1)); + } + return; +} diff --git a/dumps/scripts/3491.cs2 b/dumps/scripts/3491.cs2 new file mode 100644 index 0000000..f462beb --- /dev/null +++ b/dumps/scripts/3491.cs2 @@ -0,0 +1,19 @@ +void script_3491(int arg0) { + int ivar1; + ivar1 = arg0; + switch (arg0) { + case 65077432: + ivar1 = 65077505; + break; + case 65077433: + ivar1 = 65077490; + break; + case 65077434: + ivar1 = 65077475; + break; + case 65077435: + ivar1 = 65077460; + } + cs2method2103(255, new WidgetPointer(ivar1)); + return; +} diff --git a/dumps/scripts/3492.cs2 b/dumps/scripts/3492.cs2 new file mode 100644 index 0000000..386d61b --- /dev/null +++ b/dumps/scripts/3492.cs2 @@ -0,0 +1,23 @@ +void script_3492(int arg0) { + switch (arg0) { + case 65077384: + setWidgetIsHidden(false, new WidgetPointer(993,137)); + break; + case 65077291: + setWidgetIsHidden(false, new WidgetPointer(993,44)); + break; + case 65077333: + setWidgetIsHidden(false, new WidgetPointer(993,86)); + break; + case 65077526: + setWidgetSprite(2568, new WidgetPointer(993,281)); + setWidgetSprite(2569, new WidgetPointer(993,282)); + setWidgetSprite(2568, new WidgetPointer(993,283)); + break; + case 65077527: + setWidgetSprite(2568, new WidgetPointer(993,284)); + setWidgetSprite(2569, new WidgetPointer(993,285)); + setWidgetSprite(2568, new WidgetPointer(993,286)); + } + return; +} diff --git a/dumps/scripts/3493.cs2 b/dumps/scripts/3493.cs2 new file mode 100644 index 0000000..35b1b5d --- /dev/null +++ b/dumps/scripts/3493.cs2 @@ -0,0 +1,23 @@ +void script_3493(int arg0) { + switch (arg0) { + case 65077384: + setWidgetIsHidden(true, new WidgetPointer(993,137)); + break; + case 65077291: + setWidgetIsHidden(true, new WidgetPointer(993,44)); + break; + case 65077333: + setWidgetIsHidden(true, new WidgetPointer(993,86)); + break; + case 65077526: + setWidgetSprite(2566, new WidgetPointer(993,281)); + setWidgetSprite(2567, new WidgetPointer(993,282)); + setWidgetSprite(2566, new WidgetPointer(993,283)); + break; + case 65077527: + setWidgetSprite(2566, new WidgetPointer(993,284)); + setWidgetSprite(2567, new WidgetPointer(993,285)); + setWidgetSprite(2566, new WidgetPointer(993,286)); + } + return; +} diff --git a/dumps/scripts/3494.cs2 b/dumps/scripts/3494.cs2 new file mode 100644 index 0000000..f3fac53 --- /dev/null +++ b/dumps/scripts/3494.cs2 @@ -0,0 +1,134 @@ +void script_3494(int arg0) { + int ivar1; + playSoundEffect(9499, 1, 0); + setWidgetPosition(getWidgetActualX(new WidgetPointer(993,112)), 52, 0, 0, new WidgetPointer(993,112)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(993,27)), 52, 0, 0, new WidgetPointer(993,27)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(993,26)), 52, 0, 0, new WidgetPointer(993,26)); + setWidgetSize(0, 16384, 2, 2, new WidgetPointer(993,160)); + setWidgetSize(0, 16384, 2, 2, new WidgetPointer(993,67)); + setWidgetSize(0, 16384, 2, 2, new WidgetPointer(993,109)); + setWidgetIsHidden(true, new WidgetPointer(993,254)); + setWidgetIsHidden(true, new WidgetPointer(993,239)); + setWidgetIsHidden(true, new WidgetPointer(993,224)); + setWidgetIsHidden(true, new WidgetPointer(993,209)); + cs2method2103(255, new WidgetPointer(993,257)); + cs2method2103(255, new WidgetPointer(993,242)); + cs2method2103(255, new WidgetPointer(993,227)); + cs2method2103(255, new WidgetPointer(993,212)); + setWidgetIsHidden(true, new WidgetPointer(993,194)); + setWidgetIsHidden(true, new WidgetPointer(993,195)); + setWidgetIsHidden(true, new WidgetPointer(993,196)); + setWidgetIsHidden(true, new WidgetPointer(993,197)); + setWidgetIsHidden(true, new WidgetPointer(993,261)); + switch (globalint_1184) { + case 1: + if (((boolean)bitconfig_8065)) { + setWidgetText(new WidgetPointer(993,139), "In use"); + } else { + setWidgetText(new WidgetPointer(993,139), "Switch-to"); + } + if (bitconfig_8065 == 2) { + setWidgetText(new WidgetPointer(993,46), "In use"); + } else { + setWidgetText(new WidgetPointer(993,46), "Switch-to"); + } + if (bitconfig_8065 == 3) { + setWidgetText(new WidgetPointer(993,88), "In use"); + } else { + setWidgetText(new WidgetPointer(993,88), "Switch-to"); + } + break; + case 2: + if (bitconfig_8065 == 4) { + setWidgetText(new WidgetPointer(993,139), "In use"); + } else { + setWidgetText(new WidgetPointer(993,139), "Switch-to"); + } + if (bitconfig_8065 == 5) { + setWidgetText(new WidgetPointer(993,46), "In use"); + } else { + setWidgetText(new WidgetPointer(993,46), "Switch-to"); + } + if (bitconfig_8065 == 6) { + setWidgetText(new WidgetPointer(993,88), "In use"); + } else { + setWidgetText(new WidgetPointer(993,88), "Switch-to"); + } + break; + case 3: + if (bitconfig_8065 == 7) { + setWidgetText(new WidgetPointer(993,139), "In use"); + } else { + setWidgetText(new WidgetPointer(993,139), "Switch-to"); + } + if (bitconfig_8065 == 8) { + setWidgetText(new WidgetPointer(993,46), "In use"); + } else { + setWidgetText(new WidgetPointer(993,46), "Switch-to"); + } + if (bitconfig_8065 == 9) { + setWidgetText(new WidgetPointer(993,88), "In use"); + } else { + setWidgetText(new WidgetPointer(993,88), "Switch-to"); + } + break; + case 4: + if (bitconfig_8065 == 10) { + setWidgetText(new WidgetPointer(993,139), "In use"); + } else { + setWidgetText(new WidgetPointer(993,139), "Switch-to"); + } + if (bitconfig_8065 == 11) { + setWidgetText(new WidgetPointer(993,46), "In use"); + } else { + setWidgetText(new WidgetPointer(993,46), "Switch-to"); + } + if (bitconfig_8065 == 12) { + setWidgetText(new WidgetPointer(993,88), "In use"); + } else { + setWidgetText(new WidgetPointer(993,88), "Switch-to"); + } + } + switch (arg0) { + case 65077505: + setWidgetIsHidden(false, new WidgetPointer(993,254)); + setWidgetIsHidden(false, new WidgetPointer(993,194)); + globalint_1184 = 1; + setWidgetRGB(new Color(255, 50, 100), new WidgetPointer(993,134)); + setWidgetRGB(new Color(255, 50, 100), new WidgetPointer(993,41)); + setWidgetRGB(new Color(255, 50, 100), new WidgetPointer(993,83)); + break; + case 65077490: + setWidgetIsHidden(false, new WidgetPointer(993,239)); + setWidgetIsHidden(false, new WidgetPointer(993,195)); + globalint_1184 = 2; + setWidgetRGB(new Color(150, 255, 150), new WidgetPointer(993,134)); + setWidgetRGB(new Color(150, 255, 150), new WidgetPointer(993,41)); + setWidgetRGB(new Color(150, 255, 150), new WidgetPointer(993,83)); + break; + case 65077475: + setWidgetIsHidden(false, new WidgetPointer(993,224)); + setWidgetIsHidden(false, new WidgetPointer(993,196)); + globalint_1184 = 3; + setWidgetRGB(new Color(0, 200, 255), new WidgetPointer(993,134)); + setWidgetRGB(new Color(0, 200, 255), new WidgetPointer(993,41)); + setWidgetRGB(new Color(0, 200, 255), new WidgetPointer(993,83)); + break; + case 65077460: + setWidgetIsHidden(false, new WidgetPointer(993,209)); + setWidgetIsHidden(false, new WidgetPointer(993,197)); + globalint_1184 = 4; + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(993,134)); + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(993,41)); + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(993,83)); + } + ivar1 = cs2method_3408(105, 103, 3088, globalint_1184); + setWidgetText(new WidgetPointer(993,132), getOtherCommonData(cs2method_3408(105, 74, ivar1, 1), 1089)); + setWidgetText(new WidgetPointer(993,133), getOtherCommonData(cs2method_3408(105, 74, ivar1, 1), 1090)); + setWidgetText(new WidgetPointer(993,39), getOtherCommonData(cs2method_3408(105, 74, ivar1, 2), 1089)); + setWidgetText(new WidgetPointer(993,40), getOtherCommonData(cs2method_3408(105, 74, ivar1, 2), 1090)); + setWidgetText(new WidgetPointer(993,81), getOtherCommonData(cs2method_3408(105, 74, ivar1, 3), 1089)); + setWidgetText(new WidgetPointer(993,82), getOtherCommonData(cs2method_3408(105, 74, ivar1, 3), 1090)); + globalint_1186 = 0; + return; +} diff --git a/dumps/scripts/3495.cs2 b/dumps/scripts/3495.cs2 new file mode 100644 index 0000000..ab0df58 --- /dev/null +++ b/dumps/scripts/3495.cs2 @@ -0,0 +1,77 @@ +void script_3495(int arg0,int arg1) { + int ivar2; + string svar0; + string svar1; + string svar2; + svar0 = ""; + svar1 = ""; + ivar2 = 65077550; + switch (globalint_1184) { + case 1: + if (arg0 == 65077382) { + svar0 = cs2method_3408(105, 115, 3089, bitconfig_8053); + svar1 = cs2method_3408(105, 115, 3089, add(bitconfig_8053, 1)); + } else if (arg0 == 65077289) { + svar0 = cs2method_3408(105, 115, 3090, bitconfig_8054); + svar1 = cs2method_3408(105, 115, 3090, add(bitconfig_8054, 1)); + ivar2 = 65077549; + } else { + if (arg0 == 65077331) { + svar0 = cs2method_3408(105, 115, 3091, bitconfig_8055); + svar1 = cs2method_3408(105, 115, 3091, add(bitconfig_8055, 1)); + ivar2 = 65077548; + } + } + break; + case 2: + if (arg0 == 65077382) { + svar0 = cs2method_3408(105, 115, 3092, bitconfig_8056); + svar1 = cs2method_3408(105, 115, 3092, add(bitconfig_8056, 1)); + } else if (arg0 == 65077289) { + svar0 = cs2method_3408(105, 115, 3093, bitconfig_8057); + svar1 = cs2method_3408(105, 115, 3093, add(bitconfig_8057, 1)); + ivar2 = 65077549; + } else { + if (arg0 == 65077331) { + svar0 = cs2method_3408(105, 115, 3094, bitconfig_8058); + svar1 = cs2method_3408(105, 115, 3094, add(bitconfig_8058, 1)); + ivar2 = 65077548; + } + } + break; + case 3: + if (arg0 == 65077382) { + svar0 = cs2method_3408(105, 115, 3095, bitconfig_8059); + svar1 = cs2method_3408(105, 115, 3095, add(bitconfig_8059, 1)); + } else if (arg0 == 65077289) { + svar0 = cs2method_3408(105, 115, 3096, bitconfig_8060); + svar1 = cs2method_3408(105, 115, 3096, add(bitconfig_8060, 1)); + ivar2 = 65077549; + } else { + if (arg0 == 65077331) { + svar0 = cs2method_3408(105, 115, 3097, bitconfig_8061); + svar1 = cs2method_3408(105, 115, 3097, add(bitconfig_8061, 1)); + ivar2 = 65077548; + } + } + break; + case 4: + if (arg0 == 65077382) { + svar0 = cs2method_3408(105, 115, 3098, bitconfig_8062); + svar1 = cs2method_3408(105, 115, 3098, add(bitconfig_8062, 1)); + } else if (arg0 == 65077289) { + svar0 = cs2method_3408(105, 115, 3099, bitconfig_8063); + svar1 = cs2method_3408(105, 115, 3099, add(bitconfig_8063, 1)); + ivar2 = 65077549; + } else { + if (arg0 == 65077331) { + svar0 = cs2method_3408(105, 115, 3100, bitconfig_8064); + svar1 = cs2method_3408(105, 115, 3100, add(bitconfig_8064, 1)); + ivar2 = 65077548; + } + } + } + svar2 = "Current - " + svar0 + "
" + "Next - " + svar1; + script_569(arg0, arg1, ivar2, 25, getWidgetActualWidth(new WidgetPointer(getWidgetParentId(new WidgetPointer(ivar2)))), svar2); + return; +} diff --git a/dumps/scripts/3496.cs2 b/dumps/scripts/3496.cs2 new file mode 100644 index 0000000..257706c --- /dev/null +++ b/dumps/scripts/3496.cs2 @@ -0,0 +1,22 @@ +void script_3496(int arg0) { + switch (arg0) { + case 65208432: + setWidgetIsHidden(false, new WidgetPointer(995,125)); + break; + case 65208343: + setWidgetIsHidden(false, new WidgetPointer(995,39)); + break; + case 65208415: + setWidgetIsHidden(false, new WidgetPointer(995,107)); + break; + case 65208398: + setWidgetIsHidden(false, new WidgetPointer(995,90)); + break; + case 65208381: + setWidgetIsHidden(false, new WidgetPointer(995,73)); + break; + case 65208364: + setWidgetIsHidden(false, new WidgetPointer(995,57)); + } + return; +} diff --git a/dumps/scripts/3497.cs2 b/dumps/scripts/3497.cs2 new file mode 100644 index 0000000..3e9451e --- /dev/null +++ b/dumps/scripts/3497.cs2 @@ -0,0 +1,22 @@ +void script_3497(int arg0) { + switch (arg0) { + case 65208432: + setWidgetIsHidden(true, new WidgetPointer(995,125)); + break; + case 65208343: + setWidgetIsHidden(true, new WidgetPointer(995,39)); + break; + case 65208415: + setWidgetIsHidden(true, new WidgetPointer(995,107)); + break; + case 65208398: + setWidgetIsHidden(true, new WidgetPointer(995,90)); + break; + case 65208381: + setWidgetIsHidden(true, new WidgetPointer(995,73)); + break; + case 65208364: + setWidgetIsHidden(true, new WidgetPointer(995,57)); + } + return; +} diff --git a/dumps/scripts/3498.cs2 b/dumps/scripts/3498.cs2 new file mode 100644 index 0000000..7e6641c --- /dev/null +++ b/dumps/scripts/3498.cs2 @@ -0,0 +1,88 @@ +void script_3498(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + ivar2 = 65142858; + ivar3 = 65142862; + ivar4 = 65142864; + ivar5 = add(10, multiply(10, arg0)); + ivar6 = getWidgetActualY(new WidgetPointer(994,135)); + switch (ivar6) { + case -22: + ivar6 = arg0; + break; + case -137: + ivar6 = add(arg0, 11); + break; + case -222: + ivar6 = add(arg0, 17); + break; + case -277: + ivar6 = add(arg0, 29); + break; + case -400: + ivar6 = add(arg0, 35); + break; + case -500: + ivar6 = add(arg0, 47); + break; + default: + ivar6 = arg0; + } + if (arg1 != 0) { + ivar6 = arg1; + } + playSoundEffect(8809, 1, 0); + setWidgetPosition(0, ivar5, 0, 0, new WidgetPointer(ivar2)); + setWidgetText(new WidgetPointer(ivar3), intToStr(ivar6)); + switch (arg0) { + case 1: + setWidgetText(new WidgetPointer(ivar4), getWidgetText(new WidgetPointer(994,44))); + break; + case 2: + setWidgetText(new WidgetPointer(ivar4), getWidgetText(new WidgetPointer(994,46))); + break; + case 3: + setWidgetText(new WidgetPointer(ivar4), getWidgetText(new WidgetPointer(994,48))); + break; + case 4: + setWidgetText(new WidgetPointer(ivar4), getWidgetText(new WidgetPointer(994,50))); + break; + case 5: + setWidgetText(new WidgetPointer(ivar4), getWidgetText(new WidgetPointer(994,52))); + break; + case 6: + setWidgetText(new WidgetPointer(ivar4), getWidgetText(new WidgetPointer(994,54))); + break; + case 7: + setWidgetText(new WidgetPointer(ivar4), getWidgetText(new WidgetPointer(994,56))); + break; + case 8: + setWidgetText(new WidgetPointer(ivar4), getWidgetText(new WidgetPointer(994,58))); + break; + case 9: + setWidgetText(new WidgetPointer(ivar4), getWidgetText(new WidgetPointer(994,60))); + break; + case 10: + setWidgetText(new WidgetPointer(ivar4), getWidgetText(new WidgetPointer(994,62))); + break; + case 11: + setWidgetText(new WidgetPointer(ivar4), getWidgetText(new WidgetPointer(994,64))); + break; + case 12: + setWidgetText(new WidgetPointer(ivar4), getWidgetText(new WidgetPointer(994,66))); + break; + case 13: + setWidgetText(new WidgetPointer(ivar4), getWidgetText(new WidgetPointer(994,68))); + break; + case 14: + setWidgetText(new WidgetPointer(ivar4), getWidgetText(new WidgetPointer(994,70))); + break; + case 15: + setWidgetText(new WidgetPointer(ivar4), getWidgetText(new WidgetPointer(994,72))); + break; + } + return; +} diff --git a/dumps/scripts/3499.cs2 b/dumps/scripts/3499.cs2 new file mode 100644 index 0000000..e0e31c1 --- /dev/null +++ b/dumps/scripts/3499.cs2 @@ -0,0 +1,30 @@ +void script_3499(int arg0,int arg1,int arg2) { + int ivar3; + ivar3 = 0; + if (arg0 > 20000000) { + arg0 = 0; + } + if ((extractY(getMyPositionHash()) > 6400) || (extractY(getMyPositionHash()) > extractY(48238975))) { + setWidget3DRotation(0, 0, 512, mod(subtract(getWidgetRotateY(new WidgetPointer(arg1)), 30), 2047), 40, 275, new WidgetPointer(arg1)); + setWidgetIsHidden(true, new WidgetPointer(arg2)); + } else if (((boolean)script_133(33556928, 869257279, getMyPositionHash()))) { + if (mod(arg0, 68) > 34) { + setWidget3DRotation(0, 0, 512, mod(subtract(getWidgetRotateY(new WidgetPointer(arg1)), 30), 2047), 40, 275, new WidgetPointer(arg1)); + } else { + setWidget3DRotation(0, 0, 512, mod(add(getWidgetRotateY(new WidgetPointer(arg1)), 30), 2047), 40, 275, new WidgetPointer(arg1)); + } + setWidgetIsHidden(true, new WidgetPointer(arg2)); + } else if (subtract(extractZ(getMyPositionHash()), extractZ(globalint_1323)) > 0) { + setWidget3DRotation(0, 0, 512, mod(add(getWidgetRotateY(new WidgetPointer(arg1)), 30), 2047), 40, 275, new WidgetPointer(arg1)); + setWidgetIsHidden(true, new WidgetPointer(arg2)); + } else if (ivar3 == -1) { + setWidget3DRotation(0, 0, 0, 0, 40, 275, new WidgetPointer(arg1)); + setWidgetIsHidden(false, new WidgetPointer(arg2)); + } else { + setWidget3DRotation(0, 0, 512, divide(multiply(2047, ivar3), 65535), 40, 275, new WidgetPointer(arg1)); + setWidgetIsHidden(true, new WidgetPointer(arg2)); + } + ivar3 = script_3500(extractX(getMyPositionHash()), extractY(getMyPositionHash()), extractX(globalint_1323), extractY(globalint_1323)); + setScriptCallOnGameloop(3499, add(arg0, 1), new WidgetPointer(arg1), new WidgetPointer(arg2), "iII", new WidgetPointer(arg1)); + return; +} diff --git a/dumps/scripts/35.cs2 b/dumps/scripts/35.cs2 new file mode 100644 index 0000000..4ade2b9 --- /dev/null +++ b/dumps/scripts/35.cs2 @@ -0,0 +1,22 @@ +void script_35(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + ivar4 = 0; + ivar5 = 0; + if (setWidgetRegister(new WidgetPointer(arg0), 1)) { + if (setWidgetRegister(new WidgetPointer(arg0), 2)) { + setWidgetPosition(0, add(arg2, 16), 0, 0); + } + if (setWidgetRegister(new WidgetPointer(arg0), 3)) { + setWidgetPosition(0, add(subtract(add(arg2, getWidgetActualHeight()), 5), 16), 0, 0); + } + ivar4 = subtract(subtract(getWidgetActualHeight(new WidgetPointer(arg0)), 32), getWidgetActualHeight()); + if (ivar4 <= 0) { + return; + } + ivar5 = subtract(getWidgetScrollMaxV(new WidgetPointer(arg1)), getWidgetActualHeight(new WidgetPointer(arg1))); + arg2 = divide(multiply(arg2, ivar5), ivar4); + script_37(arg0, arg1, arg2, arg3); + } + return; +} diff --git a/dumps/scripts/350.cs2 b/dumps/scripts/350.cs2 new file mode 100644 index 0000000..15b57ca --- /dev/null +++ b/dumps/scripts/350.cs2 @@ -0,0 +1,41 @@ +void script_350(int arg0,int arg1) { + int ivar2; + int ivar3; + if (arg0 != 1) { + return; + } + if (((boolean)arg1)) { + if (IsFemale()) { + return; + } + cs2method403(0, -1); + cs2method403(1, -1); + cs2method403(7, getOtherCommonData(cs2method_3408(105, 74, 3302, bitconfig_8091), 788)); + cs2method403(8, -1); + } else { + if (IsFemale()) { + return; + } + cs2method403(7, -1); + cs2method403(8, -1); + cs2method403(0, getOtherCommonData(cs2method_3408(105, 74, 3304, bitconfig_8091), 788)); + cs2method403(1, cs2method_3408(105, 75, 3307, divide(bitconfig_8091, 2))); + } + playSoundEffect(9819, 1, 0); + cs2method410(script_42(arg1)); + globalint_196 = ((int)IsFemale()); + bitconfig_8093 = globalint_196; + script_387(arg1); + globalint_86 = 1; + bitconfig_8090 = 1; + ivar2 = cs2method_3408(105, 74, 3278, subtract(globalint_197, 1)); + ivar3 = -1; + if (ivar2 != -1) { + ivar3 = script_384(0, ivar2, arg1); + if (ivar3 != -1) { + script_359(ivar3, arg1); + } + } + script_390(arg1); + return; +} diff --git a/dumps/scripts/3500.cs2 b/dumps/scripts/3500.cs2 new file mode 100644 index 0000000..1fe346c --- /dev/null +++ b/dumps/scripts/3500.cs2 @@ -0,0 +1,43 @@ +int script_3500(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + ivar4 = subtract(arg2, arg0); + ivar5 = subtract(arg3, arg1); + if (ivar5 > 0) { + if (ivar4 > 0) { + if (ivar5 > ivar4) { + return divide(multiply(8192, ivar4), ivar5); + } + return subtract(16834, divide(multiply(8192, ivar5), ivar4)); + } + if (ivar4 < 0) { + if (subtract(0, ivar4) > ivar5) { + return subtract(49152, divide(multiply(8192, ivar5), ivar4)); + } + return add(65535, divide(multiply(8192, ivar4), ivar5)); + } + return 0; + } + if (ivar5 < 0) { + if (ivar4 > 0) { + if (ivar4 > subtract(0, ivar5)) { + return subtract(16834, divide(multiply(8192, ivar5), ivar4)); + } + return add(32768, divide(multiply(8192, ivar4), ivar5)); + } + if (ivar4 < 0) { + if (ivar5 < ivar4) { + return add(32768, divide(multiply(8192, ivar4), ivar5)); + } + return subtract(49152, divide(multiply(8192, ivar5), ivar4)); + } + return 32768; + } + if (ivar4 > 0) { + return 16384; + } + if (ivar4 < 0) { + return 49152; + } + return -1; +} diff --git a/dumps/scripts/3501.cs2 b/dumps/scripts/3501.cs2 new file mode 100644 index 0000000..39f24f4 --- /dev/null +++ b/dumps/scripts/3501.cs2 @@ -0,0 +1,24 @@ +void script_3501(int arg0) { + int ivar1; + int ivar2; + int ivar3; + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + while (ivar1 < getItemContainerLength(207)) { + createExtraChild(new WidgetPointer(arg0), 6, ivar1); + setWidgetSize(49, 49, 0, 0); + setWidgetPosition(multiply(56, ivar2), multiply(56, ivar3), 0, 0); + if (getItemIdInSlot(207, ivar1) != -1) { + setItemOnWidgetMethod1200(getItemIdInSlot(207, ivar1), getItemAmtInSlot(207, ivar1)); + setWidget3DRotation(0, 0, 512, 0, 0, 1340); + cs2method1111(1); + } else { + setWidgetHidden(1); + } + ivar1 = add(ivar1, 1); + ivar2 = mod(ivar1, 5); + ivar3 = divide(ivar1, 5); + } + return; +} diff --git a/dumps/scripts/3502.cs2 b/dumps/scripts/3502.cs2 new file mode 100644 index 0000000..e73f6a3 --- /dev/null +++ b/dumps/scripts/3502.cs2 @@ -0,0 +1,15 @@ +void script_3502() { + setItemOnWidgetMethod2200(cs2method_3408(105, 79, 3170, mod(add(script_3547(3), bitconfig_7387), getCommonDefinitionSize(3170))), -1, new WidgetPointer(1003,191)); + setItemOnWidgetMethod2200(cs2method_3408(105, 79, 3170, mod(add(script_3545(4), bitconfig_7387), getCommonDefinitionSize(3170))), -1, new WidgetPointer(1003,192)); + setItemOnWidgetMethod2200(cs2method_3408(105, 79, 3170, mod(add(script_3545(12), bitconfig_7387), getCommonDefinitionSize(3170))), -1, new WidgetPointer(1003,193)); + setItemOnWidgetMethod2200(cs2method_3408(105, 79, 3170, mod(add(script_3546(13), bitconfig_7387), getCommonDefinitionSize(3170))), -1, new WidgetPointer(1003,194)); + setItemOnWidgetMethod2200(cs2method_3408(105, 79, 3170, mod(add(script_3546(5), bitconfig_7387), getCommonDefinitionSize(3170))), -1, new WidgetPointer(1003,195)); + setItemOnWidgetMethod2200(cs2method_3408(105, 79, 3170, mod(add(script_3547(11), bitconfig_7387), getCommonDefinitionSize(3170))), -1, new WidgetPointer(1003,196)); + setItemOnWidgetMethod2200(cs2method_3408(105, 79, 3170, mod(add(script_3546(1), bitconfig_7387), getCommonDefinitionSize(3170))), -1, new WidgetPointer(1003,197)); + setItemOnWidgetMethod2200(cs2method_3408(105, 79, 3170, mod(add(script_3547(14), bitconfig_7387), getCommonDefinitionSize(3170))), -1, new WidgetPointer(1003,198)); + setItemOnWidgetMethod2200(cs2method_3408(105, 79, 3170, mod(add(script_3545(1), bitconfig_7387), getCommonDefinitionSize(3170))), -1, new WidgetPointer(1003,199)); + setItemOnWidgetMethod2200(cs2method_3408(105, 79, 3170, mod(add(script_3545(9), bitconfig_7387), getCommonDefinitionSize(3170))), -1, new WidgetPointer(1003,200)); + setItemOnWidgetMethod2200(cs2method_3408(105, 79, 3170, mod(add(script_3547(6), bitconfig_7387), getCommonDefinitionSize(3170))), -1, new WidgetPointer(1003,201)); + setItemOnWidgetMethod2200(cs2method_3408(105, 79, 3170, mod(add(script_3546(9), bitconfig_7387), getCommonDefinitionSize(3170))), -1, new WidgetPointer(1003,202)); + return; +} diff --git a/dumps/scripts/3503.cs2 b/dumps/scripts/3503.cs2 new file mode 100644 index 0000000..68cd427 --- /dev/null +++ b/dumps/scripts/3503.cs2 @@ -0,0 +1,4 @@ +void script_3503(int arg0,int arg1,int arg2) { + script_3625(3180, 3181, 3182, script_3548(bitconfig_7392), arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/3504.cs2 b/dumps/scripts/3504.cs2 new file mode 100644 index 0000000..6e1d2b4 --- /dev/null +++ b/dumps/scripts/3504.cs2 @@ -0,0 +1,4 @@ +void script_3504(int arg0,int arg1,int arg2) { + script_3625(3183, 3184, 3185, script_3549(bitconfig_7392), arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/3505.cs2 b/dumps/scripts/3505.cs2 new file mode 100644 index 0000000..c99f114 --- /dev/null +++ b/dumps/scripts/3505.cs2 @@ -0,0 +1,4 @@ +void script_3505(int arg0,int arg1,int arg2) { + script_3625(3186, 3187, 3188, script_3550(bitconfig_7392), arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/3506.cs2 b/dumps/scripts/3506.cs2 new file mode 100644 index 0000000..91b6a16 --- /dev/null +++ b/dumps/scripts/3506.cs2 @@ -0,0 +1,4 @@ +void script_3506(int arg0,int arg1,int arg2) { + script_3626(3180, 3181, 3182, script_3548(bitconfig_7392), arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/3507.cs2 b/dumps/scripts/3507.cs2 new file mode 100644 index 0000000..4a35362 --- /dev/null +++ b/dumps/scripts/3507.cs2 @@ -0,0 +1,4 @@ +void script_3507(int arg0,int arg1,int arg2) { + script_3626(3183, 3184, 3185, script_3549(bitconfig_7392), arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/3508.cs2 b/dumps/scripts/3508.cs2 new file mode 100644 index 0000000..9794b35 --- /dev/null +++ b/dumps/scripts/3508.cs2 @@ -0,0 +1,4 @@ +void script_3508(int arg0,int arg1,int arg2) { + script_3626(3186, 3187, 3188, script_3550(bitconfig_7392), arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/3509.cs2 b/dumps/scripts/3509.cs2 new file mode 100644 index 0000000..a2d9bf7 --- /dev/null +++ b/dumps/scripts/3509.cs2 @@ -0,0 +1,5 @@ +void script_3509(int arg0) { + script_3632(arg0); + script_3511(arg0); + return; +} diff --git a/dumps/scripts/351.cs2 b/dumps/scripts/351.cs2 new file mode 100644 index 0000000..121116a --- /dev/null +++ b/dumps/scripts/351.cs2 @@ -0,0 +1,33 @@ +void script_351(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + if ((arg1 == globalint_197) || (arg0 != 1)) { + return; + } + ivar2 = script_734(globalint_196); + playSoundEffect(9830, 1, 0); + ivar3 = 3278; + ivar4 = cs2method_3408(105, 74, ivar3, subtract(arg1, 1)); + if (ivar4 == -1) { + globalint_197 = 1; + bitconfig_8089 = 1; + ivar4 = cs2method_3408(105, 74, ivar3, 0); + } else { + globalint_197 = arg1; + bitconfig_8089 = arg1; + } + ivar5 = script_384(0, ivar4, script_734(((int)IsFemale()))); + if (ivar5 == -1) { + globalint_86 = 0; + bitconfig_8090 = 0; + } else { + globalint_86 = 1; + bitconfig_8090 = 1; + script_359(ivar5, ivar2); + } + script_387(ivar2); + script_390(ivar2); + return; +} diff --git a/dumps/scripts/3510.cs2 b/dumps/scripts/3510.cs2 new file mode 100644 index 0000000..4055269 --- /dev/null +++ b/dumps/scripts/3510.cs2 @@ -0,0 +1,4 @@ +void script_3510(int arg0) { + script_3511(arg0); + return; +} diff --git a/dumps/scripts/3511.cs2 b/dumps/scripts/3511.cs2 new file mode 100644 index 0000000..b14d39b --- /dev/null +++ b/dumps/scripts/3511.cs2 @@ -0,0 +1,8 @@ +void script_3511(int arg0) { + if (script_3546(3) == script_3547(3)) { + script_3633(arg0); + } else { + script_3634(arg0); + } + return; +} diff --git a/dumps/scripts/3512.cs2 b/dumps/scripts/3512.cs2 new file mode 100644 index 0000000..0676efb --- /dev/null +++ b/dumps/scripts/3512.cs2 @@ -0,0 +1,5 @@ +void script_3512(int arg0) { + script_3632(arg0); + script_3514(arg0); + return; +} diff --git a/dumps/scripts/3513.cs2 b/dumps/scripts/3513.cs2 new file mode 100644 index 0000000..273a1d6 --- /dev/null +++ b/dumps/scripts/3513.cs2 @@ -0,0 +1,4 @@ +void script_3513(int arg0) { + script_3514(arg0); + return; +} diff --git a/dumps/scripts/3514.cs2 b/dumps/scripts/3514.cs2 new file mode 100644 index 0000000..8f11753 --- /dev/null +++ b/dumps/scripts/3514.cs2 @@ -0,0 +1,8 @@ +void script_3514(int arg0) { + if (script_3547(4) == script_3545(4)) { + script_3633(arg0); + } else { + script_3634(arg0); + } + return; +} diff --git a/dumps/scripts/3515.cs2 b/dumps/scripts/3515.cs2 new file mode 100644 index 0000000..181c4a6 --- /dev/null +++ b/dumps/scripts/3515.cs2 @@ -0,0 +1,5 @@ +void script_3515(int arg0) { + script_3632(arg0); + script_3517(arg0); + return; +} diff --git a/dumps/scripts/3516.cs2 b/dumps/scripts/3516.cs2 new file mode 100644 index 0000000..5c04f37 --- /dev/null +++ b/dumps/scripts/3516.cs2 @@ -0,0 +1,4 @@ +void script_3516(int arg0) { + script_3517(arg0); + return; +} diff --git a/dumps/scripts/3517.cs2 b/dumps/scripts/3517.cs2 new file mode 100644 index 0000000..fcc5bc8 --- /dev/null +++ b/dumps/scripts/3517.cs2 @@ -0,0 +1,8 @@ +void script_3517(int arg0) { + if (script_3547(12) == script_3545(12)) { + script_3633(arg0); + } else { + script_3634(arg0); + } + return; +} diff --git a/dumps/scripts/3518.cs2 b/dumps/scripts/3518.cs2 new file mode 100644 index 0000000..d96a263 --- /dev/null +++ b/dumps/scripts/3518.cs2 @@ -0,0 +1,5 @@ +void script_3518(int arg0) { + script_3632(arg0); + script_3520(arg0); + return; +} diff --git a/dumps/scripts/3519.cs2 b/dumps/scripts/3519.cs2 new file mode 100644 index 0000000..c7cfcc0 --- /dev/null +++ b/dumps/scripts/3519.cs2 @@ -0,0 +1,4 @@ +void script_3519(int arg0) { + script_3520(arg0); + return; +} diff --git a/dumps/scripts/352.cs2 b/dumps/scripts/352.cs2 new file mode 100644 index 0000000..1fc6f0a --- /dev/null +++ b/dumps/scripts/352.cs2 @@ -0,0 +1,23 @@ +void script_352(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + if ((arg1 == globalint_86) || (arg0 != 1)) { + return; + } + playSoundEffect(9819, 1, 0); + ivar2 = cs2method_3408(105, 74, 3278, subtract(globalint_197, 1)); + if (ivar2 == -1) { + return; + } + ivar3 = script_734(((int)IsFemale())); + ivar4 = script_384(subtract(arg1, 1), ivar2, ivar3); + if (ivar4 == -1) { + return; + } + globalint_86 = arg1; + bitconfig_8090 = arg1; + script_359(ivar4, ivar3); + script_390(ivar3); + return; +} diff --git a/dumps/scripts/3520.cs2 b/dumps/scripts/3520.cs2 new file mode 100644 index 0000000..3154a9c --- /dev/null +++ b/dumps/scripts/3520.cs2 @@ -0,0 +1,8 @@ +void script_3520(int arg0) { + if (script_3545(13) == script_3546(13)) { + script_3633(arg0); + } else { + script_3634(arg0); + } + return; +} diff --git a/dumps/scripts/3521.cs2 b/dumps/scripts/3521.cs2 new file mode 100644 index 0000000..728ddf5 --- /dev/null +++ b/dumps/scripts/3521.cs2 @@ -0,0 +1,5 @@ +void script_3521(int arg0) { + script_3632(arg0); + script_3523(arg0); + return; +} diff --git a/dumps/scripts/3522.cs2 b/dumps/scripts/3522.cs2 new file mode 100644 index 0000000..657714e --- /dev/null +++ b/dumps/scripts/3522.cs2 @@ -0,0 +1,4 @@ +void script_3522(int arg0) { + script_3523(arg0); + return; +} diff --git a/dumps/scripts/3523.cs2 b/dumps/scripts/3523.cs2 new file mode 100644 index 0000000..8d3d7e1 --- /dev/null +++ b/dumps/scripts/3523.cs2 @@ -0,0 +1,8 @@ +void script_3523(int arg0) { + if (script_3545(5) == script_3546(5)) { + script_3633(arg0); + } else { + script_3634(arg0); + } + return; +} diff --git a/dumps/scripts/3524.cs2 b/dumps/scripts/3524.cs2 new file mode 100644 index 0000000..223de21 --- /dev/null +++ b/dumps/scripts/3524.cs2 @@ -0,0 +1,5 @@ +void script_3524(int arg0) { + script_3632(arg0); + script_3526(arg0); + return; +} diff --git a/dumps/scripts/3525.cs2 b/dumps/scripts/3525.cs2 new file mode 100644 index 0000000..093f0f2 --- /dev/null +++ b/dumps/scripts/3525.cs2 @@ -0,0 +1,4 @@ +void script_3525(int arg0) { + script_3526(arg0); + return; +} diff --git a/dumps/scripts/3526.cs2 b/dumps/scripts/3526.cs2 new file mode 100644 index 0000000..2a46cc5 --- /dev/null +++ b/dumps/scripts/3526.cs2 @@ -0,0 +1,8 @@ +void script_3526(int arg0) { + if (script_3546(11) == script_3547(11)) { + script_3633(arg0); + } else { + script_3634(arg0); + } + return; +} diff --git a/dumps/scripts/3527.cs2 b/dumps/scripts/3527.cs2 new file mode 100644 index 0000000..ddf6034 --- /dev/null +++ b/dumps/scripts/3527.cs2 @@ -0,0 +1,5 @@ +void script_3527(int arg0) { + script_3632(arg0); + script_3529(arg0); + return; +} diff --git a/dumps/scripts/3528.cs2 b/dumps/scripts/3528.cs2 new file mode 100644 index 0000000..f2fbd46 --- /dev/null +++ b/dumps/scripts/3528.cs2 @@ -0,0 +1,4 @@ +void script_3528(int arg0) { + script_3529(arg0); + return; +} diff --git a/dumps/scripts/3529.cs2 b/dumps/scripts/3529.cs2 new file mode 100644 index 0000000..73bcf62 --- /dev/null +++ b/dumps/scripts/3529.cs2 @@ -0,0 +1,8 @@ +void script_3529(int arg0) { + if (script_3547(15) == script_3546(1)) { + script_3633(arg0); + } else { + script_3634(arg0); + } + return; +} diff --git a/dumps/scripts/353.cs2 b/dumps/scripts/353.cs2 new file mode 100644 index 0000000..348e92b --- /dev/null +++ b/dumps/scripts/353.cs2 @@ -0,0 +1,10 @@ +void script_353(int arg0) { + playSoundEffect(9824, 1, 0); + if (((boolean)arg0) && ((boolean)bitconfig_8246)) { + bitconfig_8247 = 1; + setWidgetIsHidden(false, new WidgetPointer(1028,117)); + script_2741(); + } + script_386(arg0); + return; +} diff --git a/dumps/scripts/3530.cs2 b/dumps/scripts/3530.cs2 new file mode 100644 index 0000000..9e5ba43 --- /dev/null +++ b/dumps/scripts/3530.cs2 @@ -0,0 +1,5 @@ +void script_3530(int arg0) { + script_3632(arg0); + script_3532(arg0); + return; +} diff --git a/dumps/scripts/3531.cs2 b/dumps/scripts/3531.cs2 new file mode 100644 index 0000000..c5c9b33 --- /dev/null +++ b/dumps/scripts/3531.cs2 @@ -0,0 +1,4 @@ +void script_3531(int arg0) { + script_3532(arg0); + return; +} diff --git a/dumps/scripts/3532.cs2 b/dumps/scripts/3532.cs2 new file mode 100644 index 0000000..1243676 --- /dev/null +++ b/dumps/scripts/3532.cs2 @@ -0,0 +1,8 @@ +void script_3532(int arg0) { + if (script_3545(2) == script_3547(14)) { + script_3633(arg0); + } else { + script_3634(arg0); + } + return; +} diff --git a/dumps/scripts/3533.cs2 b/dumps/scripts/3533.cs2 new file mode 100644 index 0000000..cf186e1 --- /dev/null +++ b/dumps/scripts/3533.cs2 @@ -0,0 +1,5 @@ +void script_3533(int arg0) { + script_3632(arg0); + script_3535(arg0); + return; +} diff --git a/dumps/scripts/3534.cs2 b/dumps/scripts/3534.cs2 new file mode 100644 index 0000000..a56f41a --- /dev/null +++ b/dumps/scripts/3534.cs2 @@ -0,0 +1,4 @@ +void script_3534(int arg0) { + script_3535(arg0); + return; +} diff --git a/dumps/scripts/3535.cs2 b/dumps/scripts/3535.cs2 new file mode 100644 index 0000000..81d8f4c --- /dev/null +++ b/dumps/scripts/3535.cs2 @@ -0,0 +1,8 @@ +void script_3535(int arg0) { + if (script_3546(15) == script_3545(1)) { + script_3633(arg0); + } else { + script_3634(arg0); + } + return; +} diff --git a/dumps/scripts/3536.cs2 b/dumps/scripts/3536.cs2 new file mode 100644 index 0000000..7c1aaa9 --- /dev/null +++ b/dumps/scripts/3536.cs2 @@ -0,0 +1,5 @@ +void script_3536(int arg0) { + script_3632(arg0); + script_3538(arg0); + return; +} diff --git a/dumps/scripts/3537.cs2 b/dumps/scripts/3537.cs2 new file mode 100644 index 0000000..beadf16 --- /dev/null +++ b/dumps/scripts/3537.cs2 @@ -0,0 +1,4 @@ +void script_3537(int arg0) { + script_3538(arg0); + return; +} diff --git a/dumps/scripts/3538.cs2 b/dumps/scripts/3538.cs2 new file mode 100644 index 0000000..d72489a --- /dev/null +++ b/dumps/scripts/3538.cs2 @@ -0,0 +1,8 @@ +void script_3538(int arg0) { + if (script_3545(9) == script_3546(7)) { + script_3633(arg0); + } else { + script_3634(arg0); + } + return; +} diff --git a/dumps/scripts/3539.cs2 b/dumps/scripts/3539.cs2 new file mode 100644 index 0000000..e0643e2 --- /dev/null +++ b/dumps/scripts/3539.cs2 @@ -0,0 +1,5 @@ +void script_3539(int arg0) { + script_3632(arg0); + script_3541(arg0); + return; +} diff --git a/dumps/scripts/354.cs2 b/dumps/scripts/354.cs2 new file mode 100644 index 0000000..e985eec --- /dev/null +++ b/dumps/scripts/354.cs2 @@ -0,0 +1,10 @@ +void script_354(int arg0,int arg1) { + if ((arg0 != 1) || (arg1 == globalint_1020)) { + return; + } + playSoundEffect(9819, 1, 0); + globalint_1020 = arg1; + bitconfig_6501 = arg1; + script_391(); + return; +} diff --git a/dumps/scripts/3540.cs2 b/dumps/scripts/3540.cs2 new file mode 100644 index 0000000..5bbd31d --- /dev/null +++ b/dumps/scripts/3540.cs2 @@ -0,0 +1,4 @@ +void script_3540(int arg0) { + script_3541(arg0); + return; +} diff --git a/dumps/scripts/3541.cs2 b/dumps/scripts/3541.cs2 new file mode 100644 index 0000000..faf41f6 --- /dev/null +++ b/dumps/scripts/3541.cs2 @@ -0,0 +1,8 @@ +void script_3541(int arg0) { + if (script_3547(6) == script_3545(10)) { + script_3633(arg0); + } else { + script_3634(arg0); + } + return; +} diff --git a/dumps/scripts/3542.cs2 b/dumps/scripts/3542.cs2 new file mode 100644 index 0000000..2b62722 --- /dev/null +++ b/dumps/scripts/3542.cs2 @@ -0,0 +1,5 @@ +void script_3542(int arg0) { + script_3632(arg0); + script_3544(arg0); + return; +} diff --git a/dumps/scripts/3543.cs2 b/dumps/scripts/3543.cs2 new file mode 100644 index 0000000..c0dc274 --- /dev/null +++ b/dumps/scripts/3543.cs2 @@ -0,0 +1,4 @@ +void script_3543(int arg0) { + script_3544(arg0); + return; +} diff --git a/dumps/scripts/3544.cs2 b/dumps/scripts/3544.cs2 new file mode 100644 index 0000000..2b28832 --- /dev/null +++ b/dumps/scripts/3544.cs2 @@ -0,0 +1,8 @@ +void script_3544(int arg0) { + if (script_3547(7) == script_3546(9)) { + script_3633(arg0); + } else { + script_3634(arg0); + } + return; +} diff --git a/dumps/scripts/3545.cs2 b/dumps/scripts/3545.cs2 new file mode 100644 index 0000000..32aa988 --- /dev/null +++ b/dumps/scripts/3545.cs2 @@ -0,0 +1,3 @@ +int script_3545(int arg0) { + return cs2method_3408(105, 105, script_3548(bitconfig_7392), mod(add(arg0, bitconfig_7388), getCommonDefinitionSize(script_3548(bitconfig_7392)))); +} diff --git a/dumps/scripts/3546.cs2 b/dumps/scripts/3546.cs2 new file mode 100644 index 0000000..f5bdd5d --- /dev/null +++ b/dumps/scripts/3546.cs2 @@ -0,0 +1,3 @@ +int script_3546(int arg0) { + return cs2method_3408(105, 105, script_3549(bitconfig_7392), mod(add(arg0, bitconfig_7389), getCommonDefinitionSize(script_3549(bitconfig_7392)))); +} diff --git a/dumps/scripts/3547.cs2 b/dumps/scripts/3547.cs2 new file mode 100644 index 0000000..f97e23c --- /dev/null +++ b/dumps/scripts/3547.cs2 @@ -0,0 +1,3 @@ +int script_3547(int arg0) { + return cs2method_3408(105, 105, script_3550(bitconfig_7392), mod(add(arg0, bitconfig_7390), getCommonDefinitionSize(script_3550(bitconfig_7392)))); +} diff --git a/dumps/scripts/3548.cs2 b/dumps/scripts/3548.cs2 new file mode 100644 index 0000000..558f10a --- /dev/null +++ b/dumps/scripts/3548.cs2 @@ -0,0 +1,22 @@ +int script_3548(int arg0) { + flow_0: + SWITCH (arg0) { + case 2: + GOTO flow_1 + case 3: + GOTO flow_2 + case 4: + GOTO flow_3 + case 5: + GOTO flow_4 + } + return 3207; + flow_1: + return 3210; + flow_2: + return 3213; + flow_3: + return 3216; + flow_4: + return 3219; +} diff --git a/dumps/scripts/3549.cs2 b/dumps/scripts/3549.cs2 new file mode 100644 index 0000000..36f88e3 --- /dev/null +++ b/dumps/scripts/3549.cs2 @@ -0,0 +1,22 @@ +int script_3549(int arg0) { + flow_0: + SWITCH (arg0) { + case 2: + GOTO flow_1 + case 3: + GOTO flow_2 + case 4: + GOTO flow_3 + case 5: + GOTO flow_4 + } + return 3208; + flow_1: + return 3211; + flow_2: + return 3214; + flow_3: + return 3217; + flow_4: + return 3220; +} diff --git a/dumps/scripts/355.cs2 b/dumps/scripts/355.cs2 new file mode 100644 index 0000000..dd8b9e0 --- /dev/null +++ b/dumps/scripts/355.cs2 @@ -0,0 +1,103 @@ +void script_355(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int stack_dump0; + if (arg0 != 1) { + return; + } + ivar3 = -1; + ivar4 = -1; + switch (arg2) { + case 0: + case 7: + globalint_1008 = arg1; + cs2method403(arg2, arg1); + playSoundEffect(9860, 1, 0); + break; + case 1: + case 8: + globalint_1009 = arg1; + cs2method403(arg2, arg1); + playSoundEffect(9860, 1, 0); + break; + case 2: + case 3: + case 4: + case 9: + case 10: + case 11: + globalint_86 = 0; + cs2method411(2, 19713); + cs2method411(3, -1); + cs2method411(5, -1); + playSoundEffect(9819, 1, 0); + switch (arg2) { + case 9: + case 2: + stack_dump0 = arg1; + ivar4 = 3; + globalint_1010 = stack_dump0; + break; + case 10: + case 3: + stack_dump0 = arg1; + ivar4 = 4; + globalint_1011 = stack_dump0; + break; + case 11: + case 4: + stack_dump0 = arg1; + ivar4 = 5; + globalint_1012 = stack_dump0; + } + ivar3 = script_361(arg1, ivar4); + if (ivar3 != -1) { + if (IsFemale()) { + globalint_1010 = getOtherCommonData(ivar3, 1182); + cs2method403(9, globalint_1010); + globalint_1011 = getOtherCommonData(ivar3, 1183); + cs2method403(10, globalint_1011); + globalint_1012 = getOtherCommonData(ivar3, 1184); + cs2method403(11, globalint_1012); + script_392(-1, 1); + } else { + globalint_1010 = getOtherCommonData(ivar3, 1182); + cs2method403(2, globalint_1010); + globalint_1011 = getOtherCommonData(ivar3, 1183); + cs2method403(3, globalint_1011); + globalint_1012 = getOtherCommonData(ivar3, 1184); + cs2method403(4, globalint_1012); + script_392(-1, 0); + } + } else { + cs2method403(arg2, arg1); + } + break; + case 5: + case 12: + globalint_86 = 0; + cs2method411(2, 19713); + cs2method411(3, -1); + cs2method411(5, -1); + script_392(-1, script_734(((int)IsFemale()))); + cs2method403(arg2, arg1); + globalint_1013 = arg1; + playSoundEffect(9819, 1, 0); + break; + case 6: + case 13: + globalint_86 = 0; + cs2method411(2, 19713); + cs2method411(3, -1); + cs2method411(5, -1); + script_392(-1, script_734(((int)IsFemale()))); + cs2method403(arg2, arg1); + globalint_1014 = arg1; + playSoundEffect(9819, 1, 0); + break; + default: + return; + } + script_391(); + return; +} diff --git a/dumps/scripts/3550.cs2 b/dumps/scripts/3550.cs2 new file mode 100644 index 0000000..3534127 --- /dev/null +++ b/dumps/scripts/3550.cs2 @@ -0,0 +1,22 @@ +int script_3550(int arg0) { + flow_0: + SWITCH (arg0) { + case 2: + GOTO flow_1 + case 3: + GOTO flow_2 + case 4: + GOTO flow_3 + case 5: + GOTO flow_4 + } + return 3209; + flow_1: + return 3212; + flow_2: + return 3215; + flow_3: + return 3218; + flow_4: + return 3221; +} diff --git a/dumps/scripts/3551.cs2 b/dumps/scripts/3551.cs2 new file mode 100644 index 0000000..7b30eee --- /dev/null +++ b/dumps/scripts/3551.cs2 @@ -0,0 +1,13 @@ +void script_3551() { + setItemOnWidgetMethod2200(cs2method_3408(105, 79, 3170, mod(add(script_3590(15), bitconfig_7387), getCommonDefinitionSize(3170))), -1, new WidgetPointer(1000,181)); + setItemOnWidgetMethod2200(cs2method_3408(105, 79, 3170, mod(add(script_3588(5), bitconfig_7387), getCommonDefinitionSize(3170))), -1, new WidgetPointer(1000,182)); + setItemOnWidgetMethod2200(cs2method_3408(105, 79, 3170, mod(add(script_3589(5), bitconfig_7387), getCommonDefinitionSize(3170))), -1, new WidgetPointer(1000,183)); + setItemOnWidgetMethod2200(cs2method_3408(105, 79, 3170, mod(add(script_3588(9), bitconfig_7387), getCommonDefinitionSize(3170))), -1, new WidgetPointer(1000,184)); + setItemOnWidgetMethod2200(cs2method_3408(105, 79, 3170, mod(add(script_3590(13), bitconfig_7387), getCommonDefinitionSize(3170))), -1, new WidgetPointer(1000,185)); + setItemOnWidgetMethod2200(cs2method_3408(105, 79, 3170, mod(add(script_3588(13), bitconfig_7387), getCommonDefinitionSize(3170))), -1, new WidgetPointer(1000,186)); + setItemOnWidgetMethod2200(cs2method_3408(105, 79, 3170, mod(add(script_3589(1), bitconfig_7387), getCommonDefinitionSize(3170))), -1, new WidgetPointer(1000,187)); + setItemOnWidgetMethod2200(cs2method_3408(105, 79, 3170, mod(add(script_3590(5), bitconfig_7387), getCommonDefinitionSize(3170))), -1, new WidgetPointer(1000,188)); + setItemOnWidgetMethod2200(cs2method_3408(105, 79, 3170, mod(add(script_3590(7), bitconfig_7387), getCommonDefinitionSize(3170))), -1, new WidgetPointer(1000,189)); + setItemOnWidgetMethod2200(cs2method_3408(105, 79, 3170, mod(add(script_3589(13), bitconfig_7387), getCommonDefinitionSize(3170))), -1, new WidgetPointer(1000,190)); + return; +} diff --git a/dumps/scripts/3552.cs2 b/dumps/scripts/3552.cs2 new file mode 100644 index 0000000..6999c57 --- /dev/null +++ b/dumps/scripts/3552.cs2 @@ -0,0 +1,4 @@ +void script_3552(int arg0,int arg1,int arg2) { + script_3625(3198, 3199, 3200, script_3591(bitconfig_7392), arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/3553.cs2 b/dumps/scripts/3553.cs2 new file mode 100644 index 0000000..51014b3 --- /dev/null +++ b/dumps/scripts/3553.cs2 @@ -0,0 +1,4 @@ +void script_3553(int arg0,int arg1,int arg2) { + script_3625(3201, 3202, 3203, script_3592(bitconfig_7392), arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/3554.cs2 b/dumps/scripts/3554.cs2 new file mode 100644 index 0000000..92f0d50 --- /dev/null +++ b/dumps/scripts/3554.cs2 @@ -0,0 +1,4 @@ +void script_3554(int arg0,int arg1,int arg2) { + script_3625(3204, 3205, 3206, script_3593(bitconfig_7392), arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/3555.cs2 b/dumps/scripts/3555.cs2 new file mode 100644 index 0000000..e061831 --- /dev/null +++ b/dumps/scripts/3555.cs2 @@ -0,0 +1,4 @@ +void script_3555(int arg0,int arg1,int arg2) { + script_3626(3198, 3199, 3200, script_3591(bitconfig_7392), arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/3556.cs2 b/dumps/scripts/3556.cs2 new file mode 100644 index 0000000..411c50a --- /dev/null +++ b/dumps/scripts/3556.cs2 @@ -0,0 +1,4 @@ +void script_3556(int arg0,int arg1,int arg2) { + script_3626(3201, 3202, 3203, script_3592(bitconfig_7392), arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/3557.cs2 b/dumps/scripts/3557.cs2 new file mode 100644 index 0000000..396580e --- /dev/null +++ b/dumps/scripts/3557.cs2 @@ -0,0 +1,4 @@ +void script_3557(int arg0,int arg1,int arg2) { + script_3626(3204, 3205, 3206, script_3593(bitconfig_7392), arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/3558.cs2 b/dumps/scripts/3558.cs2 new file mode 100644 index 0000000..5c355f5 --- /dev/null +++ b/dumps/scripts/3558.cs2 @@ -0,0 +1,5 @@ +void script_3558(int arg0) { + script_3632(arg0); + script_3560(arg0); + return; +} diff --git a/dumps/scripts/3559.cs2 b/dumps/scripts/3559.cs2 new file mode 100644 index 0000000..6526719 --- /dev/null +++ b/dumps/scripts/3559.cs2 @@ -0,0 +1,4 @@ +void script_3559(int arg0) { + script_3560(arg0); + return; +} diff --git a/dumps/scripts/356.cs2 b/dumps/scripts/356.cs2 new file mode 100644 index 0000000..eb83840 --- /dev/null +++ b/dumps/scripts/356.cs2 @@ -0,0 +1,4 @@ +void script_356() { + script_304(46025850); + return; +} diff --git a/dumps/scripts/3560.cs2 b/dumps/scripts/3560.cs2 new file mode 100644 index 0000000..f6a4540 --- /dev/null +++ b/dumps/scripts/3560.cs2 @@ -0,0 +1,8 @@ +void script_3560(int arg0) { + if (script_3588(2) == script_3590(15)) { + script_3633(arg0); + } else { + script_3634(arg0); + } + return; +} diff --git a/dumps/scripts/3561.cs2 b/dumps/scripts/3561.cs2 new file mode 100644 index 0000000..be30cf2 --- /dev/null +++ b/dumps/scripts/3561.cs2 @@ -0,0 +1,5 @@ +void script_3561(int arg0) { + script_3632(arg0); + script_3563(arg0); + return; +} diff --git a/dumps/scripts/3562.cs2 b/dumps/scripts/3562.cs2 new file mode 100644 index 0000000..418ce2e --- /dev/null +++ b/dumps/scripts/3562.cs2 @@ -0,0 +1,4 @@ +void script_3562(int arg0) { + script_3563(arg0); + return; +} diff --git a/dumps/scripts/3563.cs2 b/dumps/scripts/3563.cs2 new file mode 100644 index 0000000..fe9632c --- /dev/null +++ b/dumps/scripts/3563.cs2 @@ -0,0 +1,8 @@ +void script_3563(int arg0) { + if (script_3588(5) == script_3590(4)) { + script_3633(arg0); + } else { + script_3634(arg0); + } + return; +} diff --git a/dumps/scripts/3564.cs2 b/dumps/scripts/3564.cs2 new file mode 100644 index 0000000..bbeedf5 --- /dev/null +++ b/dumps/scripts/3564.cs2 @@ -0,0 +1,5 @@ +void script_3564(int arg0) { + script_3632(arg0); + script_3566(arg0); + return; +} diff --git a/dumps/scripts/3565.cs2 b/dumps/scripts/3565.cs2 new file mode 100644 index 0000000..8f34755 --- /dev/null +++ b/dumps/scripts/3565.cs2 @@ -0,0 +1,4 @@ +void script_3565(int arg0) { + script_3566(arg0); + return; +} diff --git a/dumps/scripts/3566.cs2 b/dumps/scripts/3566.cs2 new file mode 100644 index 0000000..177d699 --- /dev/null +++ b/dumps/scripts/3566.cs2 @@ -0,0 +1,8 @@ +void script_3566(int arg0) { + if (script_3588(7) == script_3589(5)) { + script_3633(arg0); + } else { + script_3634(arg0); + } + return; +} diff --git a/dumps/scripts/3567.cs2 b/dumps/scripts/3567.cs2 new file mode 100644 index 0000000..a6712be --- /dev/null +++ b/dumps/scripts/3567.cs2 @@ -0,0 +1,5 @@ +void script_3567(int arg0) { + script_3632(arg0); + script_3569(arg0); + return; +} diff --git a/dumps/scripts/3568.cs2 b/dumps/scripts/3568.cs2 new file mode 100644 index 0000000..72db0fd --- /dev/null +++ b/dumps/scripts/3568.cs2 @@ -0,0 +1,4 @@ +void script_3568(int arg0) { + script_3569(arg0); + return; +} diff --git a/dumps/scripts/3569.cs2 b/dumps/scripts/3569.cs2 new file mode 100644 index 0000000..d0db860 --- /dev/null +++ b/dumps/scripts/3569.cs2 @@ -0,0 +1,8 @@ +void script_3569(int arg0) { + if (script_3588(9) == script_3590(6)) { + script_3633(arg0); + } else { + script_3634(arg0); + } + return; +} diff --git a/dumps/scripts/357.cs2 b/dumps/scripts/357.cs2 new file mode 100644 index 0000000..1f8b965 --- /dev/null +++ b/dumps/scripts/357.cs2 @@ -0,0 +1,28 @@ +void script_357(int arg0,int arg1,int arg2) { + if (arg0 != 1) { + return; + } + switch (arg2) { + case 0: + globalint_1015 = arg1; + break; + case 1: + globalint_1016 = arg1; + break; + case 2: + globalint_1017 = arg1; + break; + case 3: + globalint_1018 = arg1; + break; + case 4: + globalint_1019 = arg1; + break; + default: + return; + } + playSoundEffect(9830, 1, 0); + cs2method404(arg2, arg1); + script_391(); + return; +} diff --git a/dumps/scripts/3570.cs2 b/dumps/scripts/3570.cs2 new file mode 100644 index 0000000..990a54c --- /dev/null +++ b/dumps/scripts/3570.cs2 @@ -0,0 +1,5 @@ +void script_3570(int arg0) { + script_3632(arg0); + script_3572(arg0); + return; +} diff --git a/dumps/scripts/3571.cs2 b/dumps/scripts/3571.cs2 new file mode 100644 index 0000000..136793f --- /dev/null +++ b/dumps/scripts/3571.cs2 @@ -0,0 +1,4 @@ +void script_3571(int arg0) { + script_3572(arg0); + return; +} diff --git a/dumps/scripts/3572.cs2 b/dumps/scripts/3572.cs2 new file mode 100644 index 0000000..29bbbb1 --- /dev/null +++ b/dumps/scripts/3572.cs2 @@ -0,0 +1,8 @@ +void script_3572(int arg0) { + if (script_3588(12) == script_3590(13)) { + script_3633(arg0); + } else { + script_3634(arg0); + } + return; +} diff --git a/dumps/scripts/3573.cs2 b/dumps/scripts/3573.cs2 new file mode 100644 index 0000000..ea9f7d0 --- /dev/null +++ b/dumps/scripts/3573.cs2 @@ -0,0 +1,5 @@ +void script_3573(int arg0) { + script_3632(arg0); + script_3575(arg0); + return; +} diff --git a/dumps/scripts/3574.cs2 b/dumps/scripts/3574.cs2 new file mode 100644 index 0000000..fc0913f --- /dev/null +++ b/dumps/scripts/3574.cs2 @@ -0,0 +1,4 @@ +void script_3574(int arg0) { + script_3575(arg0); + return; +} diff --git a/dumps/scripts/3575.cs2 b/dumps/scripts/3575.cs2 new file mode 100644 index 0000000..efe913e --- /dev/null +++ b/dumps/scripts/3575.cs2 @@ -0,0 +1,8 @@ +void script_3575(int arg0) { + if (script_3588(13) == script_3589(15)) { + script_3633(arg0); + } else { + script_3634(arg0); + } + return; +} diff --git a/dumps/scripts/3576.cs2 b/dumps/scripts/3576.cs2 new file mode 100644 index 0000000..d9aad62 --- /dev/null +++ b/dumps/scripts/3576.cs2 @@ -0,0 +1,5 @@ +void script_3576(int arg0) { + script_3632(arg0); + script_3578(arg0); + return; +} diff --git a/dumps/scripts/3577.cs2 b/dumps/scripts/3577.cs2 new file mode 100644 index 0000000..77b6fc0 --- /dev/null +++ b/dumps/scripts/3577.cs2 @@ -0,0 +1,4 @@ +void script_3577(int arg0) { + script_3578(arg0); + return; +} diff --git a/dumps/scripts/3578.cs2 b/dumps/scripts/3578.cs2 new file mode 100644 index 0000000..496d71f --- /dev/null +++ b/dumps/scripts/3578.cs2 @@ -0,0 +1,8 @@ +void script_3578(int arg0) { + if (script_3589(1) == script_3590(14)) { + script_3633(arg0); + } else { + script_3634(arg0); + } + return; +} diff --git a/dumps/scripts/3579.cs2 b/dumps/scripts/3579.cs2 new file mode 100644 index 0000000..577878e --- /dev/null +++ b/dumps/scripts/3579.cs2 @@ -0,0 +1,5 @@ +void script_3579(int arg0) { + script_3632(arg0); + script_3581(arg0); + return; +} diff --git a/dumps/scripts/358.cs2 b/dumps/scripts/358.cs2 new file mode 100644 index 0000000..1b3db2f --- /dev/null +++ b/dumps/scripts/358.cs2 @@ -0,0 +1,120 @@ +void script_358(int arg0) { + int ivar1; + int ivar2; + flow_0: + if (arg0 != 1) { + return; + } + playSoundEffect(9830, 1, 0); + bitconfig_8092 = mod(add(bitconfig_8092, 1), 8); + ivar1 = 0; + ivar2 = script_361(globalint_1010, 3); + if (ivar2 == -1) { + ivar2 = 1076; + } + SWITCH (mod(add(bitconfig_8091, bitconfig_8092), 8)) { + case 1: + GOTO flow_5 + case 2: + GOTO flow_6 + case 3: + GOTO flow_7 + case 4: + GOTO flow_8 + case 5: + GOTO flow_9 + case 6: + GOTO flow_10 + case 7: + GOTO flow_11 + } + ivar1 = getOtherCommonData(ivar2, 1187); + globalint_1016 = ivar1; + cs2method404(1, ivar1); + ivar1 = getOtherCommonData(ivar2, 1188); + globalint_1017 = ivar1; + cs2method404(2, ivar1); + ivar1 = getOtherCommonData(ivar2, 1189); + globalint_1018 = ivar1; + cs2method404(3, ivar1); + GOTO flow_12 + flow_5: + ivar1 = getOtherCommonData(ivar2, 1190); + globalint_1016 = ivar1; + cs2method404(1, ivar1); + ivar1 = getOtherCommonData(ivar2, 1191); + globalint_1017 = ivar1; + cs2method404(2, ivar1); + ivar1 = getOtherCommonData(ivar2, 1192); + globalint_1018 = ivar1; + cs2method404(3, ivar1); + GOTO flow_12 + flow_6: + ivar1 = getOtherCommonData(ivar2, 1193); + globalint_1016 = ivar1; + cs2method404(1, ivar1); + ivar1 = getOtherCommonData(ivar2, 1194); + globalint_1017 = ivar1; + cs2method404(2, ivar1); + ivar1 = getOtherCommonData(ivar2, 1195); + globalint_1018 = ivar1; + cs2method404(3, ivar1); + GOTO flow_12 + flow_7: + ivar1 = getOtherCommonData(ivar2, 1196); + globalint_1016 = ivar1; + cs2method404(1, ivar1); + ivar1 = getOtherCommonData(ivar2, 1197); + globalint_1017 = ivar1; + cs2method404(2, ivar1); + ivar1 = getOtherCommonData(ivar2, 1198); + globalint_1018 = ivar1; + cs2method404(3, ivar1); + GOTO flow_12 + flow_8: + ivar1 = getOtherCommonData(ivar2, 1199); + globalint_1016 = ivar1; + cs2method404(1, ivar1); + ivar1 = getOtherCommonData(ivar2, 1200); + globalint_1017 = ivar1; + cs2method404(2, ivar1); + ivar1 = getOtherCommonData(ivar2, 1201); + globalint_1018 = ivar1; + cs2method404(3, ivar1); + GOTO flow_12 + flow_9: + ivar1 = getOtherCommonData(ivar2, 1202); + globalint_1016 = ivar1; + cs2method404(1, ivar1); + ivar1 = getOtherCommonData(ivar2, 1203); + globalint_1017 = ivar1; + cs2method404(2, ivar1); + ivar1 = getOtherCommonData(ivar2, 1204); + globalint_1018 = ivar1; + cs2method404(3, ivar1); + GOTO flow_12 + flow_10: + ivar1 = getOtherCommonData(ivar2, 1205); + globalint_1016 = ivar1; + cs2method404(1, ivar1); + ivar1 = getOtherCommonData(ivar2, 1206); + globalint_1017 = ivar1; + cs2method404(2, ivar1); + ivar1 = getOtherCommonData(ivar2, 1207); + globalint_1018 = ivar1; + cs2method404(3, ivar1); + GOTO flow_12 + flow_11: + ivar1 = getOtherCommonData(ivar2, 1208); + globalint_1016 = ivar1; + cs2method404(1, ivar1); + ivar1 = getOtherCommonData(ivar2, 1209); + globalint_1017 = ivar1; + cs2method404(2, ivar1); + ivar1 = getOtherCommonData(ivar2, 1210); + globalint_1018 = ivar1; + cs2method404(3, ivar1); + flow_12: + script_391(); + return; +} diff --git a/dumps/scripts/3580.cs2 b/dumps/scripts/3580.cs2 new file mode 100644 index 0000000..7df9bb7 --- /dev/null +++ b/dumps/scripts/3580.cs2 @@ -0,0 +1,4 @@ +void script_3580(int arg0) { + script_3581(arg0); + return; +} diff --git a/dumps/scripts/3581.cs2 b/dumps/scripts/3581.cs2 new file mode 100644 index 0000000..74fa915 --- /dev/null +++ b/dumps/scripts/3581.cs2 @@ -0,0 +1,8 @@ +void script_3581(int arg0) { + if (script_3589(4) == script_3590(5)) { + script_3633(arg0); + } else { + script_3634(arg0); + } + return; +} diff --git a/dumps/scripts/3582.cs2 b/dumps/scripts/3582.cs2 new file mode 100644 index 0000000..7b5d4dc --- /dev/null +++ b/dumps/scripts/3582.cs2 @@ -0,0 +1,5 @@ +void script_3582(int arg0) { + script_3632(arg0); + script_3584(arg0); + return; +} diff --git a/dumps/scripts/3583.cs2 b/dumps/scripts/3583.cs2 new file mode 100644 index 0000000..1824624 --- /dev/null +++ b/dumps/scripts/3583.cs2 @@ -0,0 +1,4 @@ +void script_3583(int arg0) { + script_3584(arg0); + return; +} diff --git a/dumps/scripts/3584.cs2 b/dumps/scripts/3584.cs2 new file mode 100644 index 0000000..29dc266 --- /dev/null +++ b/dumps/scripts/3584.cs2 @@ -0,0 +1,8 @@ +void script_3584(int arg0) { + if (script_3589(10) == script_3590(7)) { + script_3633(arg0); + } else { + script_3634(arg0); + } + return; +} diff --git a/dumps/scripts/3585.cs2 b/dumps/scripts/3585.cs2 new file mode 100644 index 0000000..c4a62b9 --- /dev/null +++ b/dumps/scripts/3585.cs2 @@ -0,0 +1,5 @@ +void script_3585(int arg0) { + script_3632(arg0); + script_3587(arg0); + return; +} diff --git a/dumps/scripts/3586.cs2 b/dumps/scripts/3586.cs2 new file mode 100644 index 0000000..aa4b941 --- /dev/null +++ b/dumps/scripts/3586.cs2 @@ -0,0 +1,4 @@ +void script_3586(int arg0) { + script_3587(arg0); + return; +} diff --git a/dumps/scripts/3587.cs2 b/dumps/scripts/3587.cs2 new file mode 100644 index 0000000..3a7a14b --- /dev/null +++ b/dumps/scripts/3587.cs2 @@ -0,0 +1,8 @@ +void script_3587(int arg0) { + if (script_3589(13) == script_3590(12)) { + script_3633(arg0); + } else { + script_3634(arg0); + } + return; +} diff --git a/dumps/scripts/3588.cs2 b/dumps/scripts/3588.cs2 new file mode 100644 index 0000000..b72e6dd --- /dev/null +++ b/dumps/scripts/3588.cs2 @@ -0,0 +1,3 @@ +int script_3588(int arg0) { + return cs2method_3408(105, 105, script_3591(bitconfig_7392), mod(add(arg0, bitconfig_7388), getCommonDefinitionSize(script_3591(bitconfig_7392)))); +} diff --git a/dumps/scripts/3589.cs2 b/dumps/scripts/3589.cs2 new file mode 100644 index 0000000..91fc686 --- /dev/null +++ b/dumps/scripts/3589.cs2 @@ -0,0 +1,3 @@ +int script_3589(int arg0) { + return cs2method_3408(105, 105, script_3592(bitconfig_7392), mod(add(arg0, bitconfig_7389), getCommonDefinitionSize(script_3592(bitconfig_7392)))); +} diff --git a/dumps/scripts/359.cs2 b/dumps/scripts/359.cs2 new file mode 100644 index 0000000..ca6762d --- /dev/null +++ b/dumps/scripts/359.cs2 @@ -0,0 +1,113 @@ +void script_359(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int stack_dump0; + cs2func_script_360_struct(3,0,0) structdump_1; + int stack_dump2; + ivar2 = -1; + if (((boolean)arg1)) { + cs2method403(2, -1); + cs2method403(3, -1); + cs2method403(4, -1); + cs2method403(5, -1); + cs2method403(6, -1); + cs2method403(8, -1); + cs2method403(14, -1); + cs2method403(15, -1); + globalint_1009 = -1; + ivar2 = getOtherCommonData(arg0, 1182); + if (ivar2 != -1) { + globalint_1010 = ivar2; + cs2method403(9, ivar2); + } + ivar2 = getOtherCommonData(arg0, 1183); + globalint_1011 = ivar2; + cs2method403(10, ivar2); + ivar2 = getOtherCommonData(arg0, 1184); + if (ivar2 != -1) { + globalint_1012 = ivar2; + cs2method403(11, ivar2); + } + ivar2 = getOtherCommonData(arg0, 1185); + if (ivar2 != -1) { + globalint_1013 = ivar2; + cs2method403(12, ivar2); + } + ivar2 = getOtherCommonData(arg0, 1186); + if (ivar2 != -1) { + globalint_1014 = ivar2; + cs2method403(13, ivar2); + } + } else { + cs2method403(9, -1); + cs2method403(10, -1); + cs2method403(11, -1); + cs2method403(12, -1); + cs2method403(13, -1); + cs2method403(14, -1); + cs2method403(15, -1); + ivar2 = getOtherCommonData(arg0, 1182); + if (ivar2 != -1) { + globalint_1010 = ivar2; + cs2method403(2, ivar2); + } + ivar2 = getOtherCommonData(arg0, 1183); + globalint_1011 = ivar2; + cs2method403(3, ivar2); + ivar2 = getOtherCommonData(arg0, 1184); + if (ivar2 != -1) { + globalint_1012 = ivar2; + cs2method403(4, ivar2); + } + ivar2 = getOtherCommonData(arg0, 1185); + if (ivar2 != -1) { + globalint_1013 = ivar2; + cs2method403(5, ivar2); + } + ivar2 = getOtherCommonData(arg0, 1186); + if (ivar2 != -1) { + cs2method403(6, ivar2); + globalint_1014 = ivar2; + } + } + stack_dump0 = arg0; + structdump_1 = script_360(stack_dump0); + stack_dump0 = structdump_1.intpart_0; + stack_dump2 = structdump_1.intpart_1; + globalint_1018 = structdump_1.intpart_2; + stack_dump0 = stack_dump0; + globalint_1017 = stack_dump2; + globalint_1016 = stack_dump0; + cs2method404(1, globalint_1016); + cs2method404(2, globalint_1017); + cs2method404(3, globalint_1018); + ivar3 = -1; + ivar4 = -1; + ivar5 = -1; + ivar6 = -1; + if (globalint_86 != 0) { + ivar4 = cs2method_3408(105, 74, 3278, subtract(globalint_197, 1)); + if (ivar4 != -1) { + ivar3 = getOtherCommonData(ivar4, 1163); + if (ivar3 != -1) { + if (getItemContainerLength(ivar3) >= 2) { + ivar5 = getItemIdInSlot(ivar3, 1); + } + if (getItemContainerLength(ivar3) >= 3) { + ivar6 = getItemIdInSlot(ivar3, 2); + } + } + } + script_392(ivar4, arg1); + } else { + script_392(-1, arg1); + } + cs2method411(2, 19713); + cs2method411(3, ivar5); + cs2method411(5, ivar6); + bitconfig_8092 = 0; + return; +} diff --git a/dumps/scripts/3590.cs2 b/dumps/scripts/3590.cs2 new file mode 100644 index 0000000..6653db9 --- /dev/null +++ b/dumps/scripts/3590.cs2 @@ -0,0 +1,3 @@ +int script_3590(int arg0) { + return cs2method_3408(105, 105, script_3593(bitconfig_7392), mod(add(arg0, bitconfig_7390), getCommonDefinitionSize(script_3593(bitconfig_7392)))); +} diff --git a/dumps/scripts/3591.cs2 b/dumps/scripts/3591.cs2 new file mode 100644 index 0000000..a0ab233 --- /dev/null +++ b/dumps/scripts/3591.cs2 @@ -0,0 +1,22 @@ +int script_3591(int arg0) { + flow_0: + SWITCH (arg0) { + case 2: + GOTO flow_1 + case 3: + GOTO flow_2 + case 4: + GOTO flow_3 + case 5: + GOTO flow_4 + } + return 3140; + flow_1: + return 3143; + flow_2: + return 3146; + flow_3: + return 3149; + flow_4: + return 3152; +} diff --git a/dumps/scripts/3592.cs2 b/dumps/scripts/3592.cs2 new file mode 100644 index 0000000..3c6eba8 --- /dev/null +++ b/dumps/scripts/3592.cs2 @@ -0,0 +1,22 @@ +int script_3592(int arg0) { + flow_0: + SWITCH (arg0) { + case 2: + GOTO flow_1 + case 3: + GOTO flow_2 + case 4: + GOTO flow_3 + case 5: + GOTO flow_4 + } + return 3141; + flow_1: + return 3144; + flow_2: + return 3147; + flow_3: + return 3150; + flow_4: + return 3153; +} diff --git a/dumps/scripts/3593.cs2 b/dumps/scripts/3593.cs2 new file mode 100644 index 0000000..64797f0 --- /dev/null +++ b/dumps/scripts/3593.cs2 @@ -0,0 +1,22 @@ +int script_3593(int arg0) { + flow_0: + SWITCH (arg0) { + case 2: + GOTO flow_1 + case 3: + GOTO flow_2 + case 4: + GOTO flow_3 + case 5: + GOTO flow_4 + } + return 3142; + flow_1: + return 3145; + flow_2: + return 3148; + flow_3: + return 3151; + flow_4: + return 3154; +} diff --git a/dumps/scripts/3594.cs2 b/dumps/scripts/3594.cs2 new file mode 100644 index 0000000..1143399 --- /dev/null +++ b/dumps/scripts/3594.cs2 @@ -0,0 +1,9 @@ +void script_3594() { + setItemOnWidgetMethod2200(cs2method_3408(105, 79, 3170, mod(add(script_3619(9), bitconfig_7387), getCommonDefinitionSize(3170))), -1, new WidgetPointer(1002,161)); + setItemOnWidgetMethod2200(cs2method_3408(105, 79, 3170, mod(add(script_3621(6), bitconfig_7387), getCommonDefinitionSize(3170))), -1, new WidgetPointer(1002,162)); + setItemOnWidgetMethod2200(cs2method_3408(105, 79, 3170, mod(add(script_3619(14), bitconfig_7387), getCommonDefinitionSize(3170))), -1, new WidgetPointer(1002,163)); + setItemOnWidgetMethod2200(cs2method_3408(105, 79, 3170, mod(add(script_3620(1), bitconfig_7387), getCommonDefinitionSize(3170))), -1, new WidgetPointer(1002,164)); + setItemOnWidgetMethod2200(cs2method_3408(105, 79, 3170, mod(add(script_3620(9), bitconfig_7387), getCommonDefinitionSize(3170))), -1, new WidgetPointer(1002,165)); + setItemOnWidgetMethod2200(cs2method_3408(105, 79, 3170, mod(add(script_3621(1), bitconfig_7387), getCommonDefinitionSize(3170))), -1, new WidgetPointer(1002,166)); + return; +} diff --git a/dumps/scripts/3595.cs2 b/dumps/scripts/3595.cs2 new file mode 100644 index 0000000..b882045 --- /dev/null +++ b/dumps/scripts/3595.cs2 @@ -0,0 +1,4 @@ +void script_3595(int arg0,int arg1,int arg2) { + script_3625(3171, 3172, 3173, script_3622(bitconfig_7392), arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/3596.cs2 b/dumps/scripts/3596.cs2 new file mode 100644 index 0000000..35af197 --- /dev/null +++ b/dumps/scripts/3596.cs2 @@ -0,0 +1,4 @@ +void script_3596(int arg0,int arg1,int arg2) { + script_3625(3174, 3175, 3176, script_3623(bitconfig_7392), arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/3597.cs2 b/dumps/scripts/3597.cs2 new file mode 100644 index 0000000..923d399 --- /dev/null +++ b/dumps/scripts/3597.cs2 @@ -0,0 +1,4 @@ +void script_3597(int arg0,int arg1,int arg2) { + script_3625(3177, 3178, 3179, script_3624(bitconfig_7392), arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/3598.cs2 b/dumps/scripts/3598.cs2 new file mode 100644 index 0000000..5148b1b --- /dev/null +++ b/dumps/scripts/3598.cs2 @@ -0,0 +1,4 @@ +void script_3598(int arg0,int arg1,int arg2) { + script_3626(3171, 3172, 3173, script_3622(bitconfig_7392), arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/3599.cs2 b/dumps/scripts/3599.cs2 new file mode 100644 index 0000000..92cc2cc --- /dev/null +++ b/dumps/scripts/3599.cs2 @@ -0,0 +1,4 @@ +void script_3599(int arg0,int arg1,int arg2) { + script_3626(3174, 3175, 3176, script_3623(bitconfig_7392), arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/36.cs2 b/dumps/scripts/36.cs2 new file mode 100644 index 0000000..ff98f6a --- /dev/null +++ b/dumps/scripts/36.cs2 @@ -0,0 +1,19 @@ +void script_36(int arg0,int arg1,int arg2) { + int ivar3; + ivar3 = cs2method2601(new WidgetPointer(arg1)); + switch (arg1) { + case 38666248: + if (arg2 > 0) { + ivar3 = script_4754(arg1, ivar3, 0); + } else { + ivar3 = script_4754(arg1, ivar3, 1); + } + break; + default: + ivar3 = add(ivar3, multiply(arg2, 45)); + } + if (setWidgetRegister(new WidgetPointer(arg0), 1)) { + script_37(arg0, arg1, ivar3, 1); + } + return; +} diff --git a/dumps/scripts/360.cs2 b/dumps/scripts/360.cs2 new file mode 100644 index 0000000..177e68b --- /dev/null +++ b/dumps/scripts/360.cs2 @@ -0,0 +1,34 @@ +cs2func_script_360_struct(3,0,0) script_360(int arg0) { + flow_0: + SWITCH (bitconfig_8091) { + case 1: + GOTO flow_1 + case 2: + GOTO flow_2 + case 3: + GOTO flow_3 + case 4: + GOTO flow_4 + case 5: + GOTO flow_5 + case 6: + GOTO flow_6 + case 7: + GOTO flow_7 + } + return newstruct cs2func_script_360_struct(getOtherCommonData(arg0, 1187), getOtherCommonData(arg0, 1188), getOtherCommonData(arg0, 1189)); + flow_1: + return newstruct cs2func_script_360_struct(getOtherCommonData(arg0, 1190), getOtherCommonData(arg0, 1191), getOtherCommonData(arg0, 1192)); + flow_2: + return newstruct cs2func_script_360_struct(getOtherCommonData(arg0, 1193), getOtherCommonData(arg0, 1194), getOtherCommonData(arg0, 1195)); + flow_3: + return newstruct cs2func_script_360_struct(getOtherCommonData(arg0, 1196), getOtherCommonData(arg0, 1197), getOtherCommonData(arg0, 1198)); + flow_4: + return newstruct cs2func_script_360_struct(getOtherCommonData(arg0, 1199), getOtherCommonData(arg0, 1200), getOtherCommonData(arg0, 1201)); + flow_5: + return newstruct cs2func_script_360_struct(getOtherCommonData(arg0, 1202), getOtherCommonData(arg0, 1203), getOtherCommonData(arg0, 1204)); + flow_6: + return newstruct cs2func_script_360_struct(getOtherCommonData(arg0, 1205), getOtherCommonData(arg0, 1206), getOtherCommonData(arg0, 1207)); + flow_7: + return newstruct cs2func_script_360_struct(getOtherCommonData(arg0, 1208), getOtherCommonData(arg0, 1209), getOtherCommonData(arg0, 1210)); +} diff --git a/dumps/scripts/3600.cs2 b/dumps/scripts/3600.cs2 new file mode 100644 index 0000000..cfbce95 --- /dev/null +++ b/dumps/scripts/3600.cs2 @@ -0,0 +1,4 @@ +void script_3600(int arg0,int arg1,int arg2) { + script_3626(3177, 3178, 3179, script_3624(bitconfig_7392), arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/3601.cs2 b/dumps/scripts/3601.cs2 new file mode 100644 index 0000000..313ee5e --- /dev/null +++ b/dumps/scripts/3601.cs2 @@ -0,0 +1,5 @@ +void script_3601(int arg0) { + script_3632(arg0); + script_3603(arg0); + return; +} diff --git a/dumps/scripts/3602.cs2 b/dumps/scripts/3602.cs2 new file mode 100644 index 0000000..88502cd --- /dev/null +++ b/dumps/scripts/3602.cs2 @@ -0,0 +1,4 @@ +void script_3602(int arg0) { + script_3603(arg0); + return; +} diff --git a/dumps/scripts/3603.cs2 b/dumps/scripts/3603.cs2 new file mode 100644 index 0000000..2a9fe59 --- /dev/null +++ b/dumps/scripts/3603.cs2 @@ -0,0 +1,8 @@ +void script_3603(int arg0) { + if (script_3619(9) == script_3620(7)) { + script_3633(arg0); + } else { + script_3634(arg0); + } + return; +} diff --git a/dumps/scripts/3604.cs2 b/dumps/scripts/3604.cs2 new file mode 100644 index 0000000..b324958 --- /dev/null +++ b/dumps/scripts/3604.cs2 @@ -0,0 +1,5 @@ +void script_3604(int arg0) { + script_3632(arg0); + script_3606(arg0); + return; +} diff --git a/dumps/scripts/3605.cs2 b/dumps/scripts/3605.cs2 new file mode 100644 index 0000000..aef489c --- /dev/null +++ b/dumps/scripts/3605.cs2 @@ -0,0 +1,4 @@ +void script_3605(int arg0) { + script_3606(arg0); + return; +} diff --git a/dumps/scripts/3606.cs2 b/dumps/scripts/3606.cs2 new file mode 100644 index 0000000..105ac1f --- /dev/null +++ b/dumps/scripts/3606.cs2 @@ -0,0 +1,8 @@ +void script_3606(int arg0) { + if (script_3619(10) == script_3621(6)) { + script_3633(arg0); + } else { + script_3634(arg0); + } + return; +} diff --git a/dumps/scripts/3607.cs2 b/dumps/scripts/3607.cs2 new file mode 100644 index 0000000..29819a7 --- /dev/null +++ b/dumps/scripts/3607.cs2 @@ -0,0 +1,5 @@ +void script_3607(int arg0) { + script_3632(arg0); + script_3609(arg0); + return; +} diff --git a/dumps/scripts/3608.cs2 b/dumps/scripts/3608.cs2 new file mode 100644 index 0000000..c506795 --- /dev/null +++ b/dumps/scripts/3608.cs2 @@ -0,0 +1,4 @@ +void script_3608(int arg0) { + script_3609(arg0); + return; +} diff --git a/dumps/scripts/3609.cs2 b/dumps/scripts/3609.cs2 new file mode 100644 index 0000000..2f80aa8 --- /dev/null +++ b/dumps/scripts/3609.cs2 @@ -0,0 +1,8 @@ +void script_3609(int arg0) { + if (script_3619(14) == script_3621(2)) { + script_3633(arg0); + } else { + script_3634(arg0); + } + return; +} diff --git a/dumps/scripts/361.cs2 b/dumps/scripts/361.cs2 new file mode 100644 index 0000000..824659d --- /dev/null +++ b/dumps/scripts/361.cs2 @@ -0,0 +1,49 @@ +int script_361(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + ivar2 = script_734(((int)IsFemale())); + ivar3 = subtract(getCommonDefinitionSize(3278), 1); + ivar4 = -1; + ivar5 = 0; + ivar6 = -1; + while (ivar3 >= 0) { + ivar4 = cs2method_3408(105, 74, 3278, ivar3); + if (ivar4 != -1) { + ivar5 = 0; + ivar6 = script_384(0, ivar4, ivar2); + while (ivar6 != -1) { + switch (arg1) { + case 3: + if (getOtherCommonData(ivar6, 1182) == arg0) { + return ivar6; + } + break; + case 4: + if (getOtherCommonData(ivar6, 1183) == arg0) { + return ivar6; + } + break; + case 5: + if (getOtherCommonData(ivar6, 1184) == arg0) { + return ivar6; + } + break; + case 6: + if (getOtherCommonData(ivar6, 1185) == arg0) { + return ivar6; + } + break; + default: + return -1; + } + ivar5 = add(ivar5, 1); + ivar6 = script_384(ivar5, ivar4, ivar2); + } + } + ivar3 = subtract(ivar3, 1); + } + return -1; +} diff --git a/dumps/scripts/3610.cs2 b/dumps/scripts/3610.cs2 new file mode 100644 index 0000000..6c552a3 --- /dev/null +++ b/dumps/scripts/3610.cs2 @@ -0,0 +1,5 @@ +void script_3610(int arg0) { + script_3632(arg0); + script_3612(arg0); + return; +} diff --git a/dumps/scripts/3611.cs2 b/dumps/scripts/3611.cs2 new file mode 100644 index 0000000..a9a9d21 --- /dev/null +++ b/dumps/scripts/3611.cs2 @@ -0,0 +1,4 @@ +void script_3611(int arg0) { + script_3612(arg0); + return; +} diff --git a/dumps/scripts/3612.cs2 b/dumps/scripts/3612.cs2 new file mode 100644 index 0000000..4519e82 --- /dev/null +++ b/dumps/scripts/3612.cs2 @@ -0,0 +1,8 @@ +void script_3612(int arg0) { + if (script_3619(15) == script_3620(1)) { + script_3633(arg0); + } else { + script_3634(arg0); + } + return; +} diff --git a/dumps/scripts/3613.cs2 b/dumps/scripts/3613.cs2 new file mode 100644 index 0000000..1060e9f --- /dev/null +++ b/dumps/scripts/3613.cs2 @@ -0,0 +1,5 @@ +void script_3613(int arg0) { + script_3632(arg0); + script_3615(arg0); + return; +} diff --git a/dumps/scripts/3614.cs2 b/dumps/scripts/3614.cs2 new file mode 100644 index 0000000..5e0f837 --- /dev/null +++ b/dumps/scripts/3614.cs2 @@ -0,0 +1,4 @@ +void script_3614(int arg0) { + script_3615(arg0); + return; +} diff --git a/dumps/scripts/3615.cs2 b/dumps/scripts/3615.cs2 new file mode 100644 index 0000000..5b95419 --- /dev/null +++ b/dumps/scripts/3615.cs2 @@ -0,0 +1,8 @@ +void script_3615(int arg0) { + if (script_3620(9) == script_3621(7)) { + script_3633(arg0); + } else { + script_3634(arg0); + } + return; +} diff --git a/dumps/scripts/3616.cs2 b/dumps/scripts/3616.cs2 new file mode 100644 index 0000000..301cefe --- /dev/null +++ b/dumps/scripts/3616.cs2 @@ -0,0 +1,5 @@ +void script_3616(int arg0) { + script_3632(arg0); + script_3618(arg0); + return; +} diff --git a/dumps/scripts/3617.cs2 b/dumps/scripts/3617.cs2 new file mode 100644 index 0000000..54248c5 --- /dev/null +++ b/dumps/scripts/3617.cs2 @@ -0,0 +1,4 @@ +void script_3617(int arg0) { + script_3618(arg0); + return; +} diff --git a/dumps/scripts/3618.cs2 b/dumps/scripts/3618.cs2 new file mode 100644 index 0000000..082d6a8 --- /dev/null +++ b/dumps/scripts/3618.cs2 @@ -0,0 +1,8 @@ +void script_3618(int arg0) { + if (script_3620(15) == script_3621(1)) { + script_3633(arg0); + } else { + script_3634(arg0); + } + return; +} diff --git a/dumps/scripts/3619.cs2 b/dumps/scripts/3619.cs2 new file mode 100644 index 0000000..432aa60 --- /dev/null +++ b/dumps/scripts/3619.cs2 @@ -0,0 +1,3 @@ +int script_3619(int arg0) { + return cs2method_3408(105, 105, script_3622(bitconfig_7392), mod(add(arg0, bitconfig_7388), getCommonDefinitionSize(script_3622(bitconfig_7392)))); +} diff --git a/dumps/scripts/362.cs2 b/dumps/scripts/362.cs2 new file mode 100644 index 0000000..330ea30 --- /dev/null +++ b/dumps/scripts/362.cs2 @@ -0,0 +1,13 @@ +void script_362(int arg0,int arg1,string arg2) { + deleteAllExtraChilds(new WidgetPointer(arg0)); + setWidgetSize(arg1, getWidgetActualHeight(new WidgetPointer(arg0)), 0, 0, new WidgetPointer(arg0)); + createExtraChild(new WidgetPointer(arg0), 4, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(0, 0, 1, 1); + setWidgetPosition(0, 0, 1, 1); + setWidgetFont(468); + setWidgetRGB(new Color(36, 27, 18)); + setWidgetTextAlignment(1, 1, 0); + setWidgetUnknownBoolean(false); + setWidgetText(arg2); + return; +} diff --git a/dumps/scripts/3620.cs2 b/dumps/scripts/3620.cs2 new file mode 100644 index 0000000..c52035c --- /dev/null +++ b/dumps/scripts/3620.cs2 @@ -0,0 +1,3 @@ +int script_3620(int arg0) { + return cs2method_3408(105, 105, script_3623(bitconfig_7392), mod(add(arg0, bitconfig_7389), getCommonDefinitionSize(script_3623(bitconfig_7392)))); +} diff --git a/dumps/scripts/3621.cs2 b/dumps/scripts/3621.cs2 new file mode 100644 index 0000000..c3a056d --- /dev/null +++ b/dumps/scripts/3621.cs2 @@ -0,0 +1,3 @@ +int script_3621(int arg0) { + return cs2method_3408(105, 105, script_3624(bitconfig_7392), mod(add(arg0, bitconfig_7390), getCommonDefinitionSize(script_3624(bitconfig_7392)))); +} diff --git a/dumps/scripts/3622.cs2 b/dumps/scripts/3622.cs2 new file mode 100644 index 0000000..9913031 --- /dev/null +++ b/dumps/scripts/3622.cs2 @@ -0,0 +1,22 @@ +int script_3622(int arg0) { + flow_0: + SWITCH (arg0) { + case 2: + GOTO flow_1 + case 3: + GOTO flow_2 + case 4: + GOTO flow_3 + case 5: + GOTO flow_4 + } + return 3155; + flow_1: + return 3158; + flow_2: + return 3161; + flow_3: + return 3164; + flow_4: + return 3167; +} diff --git a/dumps/scripts/3623.cs2 b/dumps/scripts/3623.cs2 new file mode 100644 index 0000000..7984ce2 --- /dev/null +++ b/dumps/scripts/3623.cs2 @@ -0,0 +1,22 @@ +int script_3623(int arg0) { + flow_0: + SWITCH (arg0) { + case 2: + GOTO flow_1 + case 3: + GOTO flow_2 + case 4: + GOTO flow_3 + case 5: + GOTO flow_4 + } + return 3156; + flow_1: + return 3159; + flow_2: + return 3162; + flow_3: + return 3165; + flow_4: + return 3168; +} diff --git a/dumps/scripts/3624.cs2 b/dumps/scripts/3624.cs2 new file mode 100644 index 0000000..43ee04b --- /dev/null +++ b/dumps/scripts/3624.cs2 @@ -0,0 +1,22 @@ +int script_3624(int arg0) { + flow_0: + SWITCH (arg0) { + case 2: + GOTO flow_1 + case 3: + GOTO flow_2 + case 4: + GOTO flow_3 + case 5: + GOTO flow_4 + } + return 3157; + flow_1: + return 3160; + flow_2: + return 3163; + flow_3: + return 3166; + flow_4: + return 3169; +} diff --git a/dumps/scripts/3625.cs2 b/dumps/scripts/3625.cs2 new file mode 100644 index 0000000..b6367e7 --- /dev/null +++ b/dumps/scripts/3625.cs2 @@ -0,0 +1,39 @@ +void script_3625(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6) { + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int stack_dump0; + ivar7 = 0; + ivar8 = getCommonDefinitionSize(arg0); + ivar9 = -1; + ivar10 = 0; + ivar11 = 0; + ivar12 = 0; + ivar13 = 0; + playSoundEffect(9506, 1, 0); + while (ivar7 < ivar8) { + ivar9 = ((int)cs2method_3408(105, 73, arg0, ivar7)); + ivar10 = cs2method_3408(105, 105, arg3, mod(add(ivar7, arg4), ivar8)); + ivar13 = mod(add(ivar10, arg5), getCommonDefinitionSize(3170)); + if (setWidgetRegister(new WidgetPointer(ivar9))) { + stack_dump0 = 1103; + /* + mgi.tools.jagdecs2.DecompilerException: opcode 1613 not decompileable + at mgi.tools.jagdecs2.FlowBlocksGenerator.analyzeSpecialCall(FlowBlocksGenerator.java:297) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:249) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + setScriptCallOnGameloop(3627, new WidgetPointer(ivar9), ivar11, ivar12, multiply(25, cs2method_3408(105, 105, arg1, ivar7)), multiply(25, cs2method_3408(105, 105, arg2, ivar7)), cs2method_3408(105, 79, 3170, ivar13), ivar13, 0, arg6, "IiiiiOiii", new WidgetPointer(ivar9)); + ivar7 = add(ivar7, 1); + } + return; +} diff --git a/dumps/scripts/3626.cs2 b/dumps/scripts/3626.cs2 new file mode 100644 index 0000000..4949877 --- /dev/null +++ b/dumps/scripts/3626.cs2 @@ -0,0 +1,39 @@ +void script_3626(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6) { + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int stack_dump0; + ivar7 = 0; + ivar8 = getCommonDefinitionSize(arg0); + ivar9 = -1; + ivar10 = 0; + ivar11 = 0; + ivar12 = 0; + ivar13 = 0; + playSoundEffect(9506, 1, 0); + while (ivar7 < ivar8) { + ivar9 = ((int)cs2method_3408(105, 73, arg0, ivar7)); + ivar10 = cs2method_3408(105, 105, arg3, mod(add(ivar7, arg4), ivar8)); + ivar13 = mod(add(ivar10, arg5), getCommonDefinitionSize(3170)); + if (setWidgetRegister(new WidgetPointer(ivar9))) { + stack_dump0 = 1103; + /* + mgi.tools.jagdecs2.DecompilerException: opcode 1613 not decompileable + at mgi.tools.jagdecs2.FlowBlocksGenerator.analyzeSpecialCall(FlowBlocksGenerator.java:297) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:249) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + setScriptCallOnGameloop(3628, new WidgetPointer(ivar9), ivar11, ivar12, multiply(25, cs2method_3408(105, 105, arg1, ivar7)), multiply(25, cs2method_3408(105, 105, arg2, ivar7)), cs2method_3408(105, 79, 3170, ivar13), ivar13, 0, arg6, "IiiiiOiii", new WidgetPointer(ivar9)); + ivar7 = add(ivar7, 1); + } + return; +} diff --git a/dumps/scripts/3627.cs2 b/dumps/scripts/3627.cs2 new file mode 100644 index 0000000..a8ccf67 --- /dev/null +++ b/dumps/scripts/3627.cs2 @@ -0,0 +1,15 @@ +void script_3627(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8) { + arg7 = add(arg7, 1); + if (arg7 == arg8) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + setWidgetPosition(arg1, arg2, 0, 0, new WidgetPointer(arg0)); + setItemOnWidgetMethod2200(arg5, -1, new WidgetPointer(arg0)); + if (setWidgetRegister(new WidgetPointer(arg0))) { + setWidgetIntegerNode(1103, arg6); + } + return; + } + setWidgetPosition(add(arg1, divide(multiply(arg3, arg7), arg8)), add(arg2, divide(multiply(arg4, arg7), arg8)), 0, 0, new WidgetPointer(arg0)); + setScriptCallOnGameloop(3627, new WidgetPointer(arg0), arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, "IiiiiOiii", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/3628.cs2 b/dumps/scripts/3628.cs2 new file mode 100644 index 0000000..6c4ce35 --- /dev/null +++ b/dumps/scripts/3628.cs2 @@ -0,0 +1,15 @@ +void script_3628(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8) { + arg7 = add(arg7, 1); + if (((boolean)arg7)) { + setWidgetPosition(add(arg1, arg3), add(arg2, arg4), 0, 0, new WidgetPointer(arg0)); + setItemOnWidgetMethod2200(arg5, -1, new WidgetPointer(arg0)); + } else { + setWidgetPosition(add(arg1, divide(multiply(arg3, subtract(arg8, arg7)), arg8)), add(arg2, divide(multiply(arg4, subtract(arg8, arg7)), arg8)), 0, 0, new WidgetPointer(arg0)); + } + if (arg7 == arg8) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + } else { + setScriptCallOnGameloop(3628, new WidgetPointer(arg0), arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, "IiiiiOiii", new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/3629.cs2 b/dumps/scripts/3629.cs2 new file mode 100644 index 0000000..64819b1 --- /dev/null +++ b/dumps/scripts/3629.cs2 @@ -0,0 +1,5 @@ +void script_3629(int arg0,int arg1,int arg2) { + setWidgetIsHidden(false, new WidgetPointer(arg0)); + setWidgetRGB(new Color(arg2), new WidgetPointer(arg1)); + return; +} diff --git a/dumps/scripts/363.cs2 b/dumps/scripts/363.cs2 new file mode 100644 index 0000000..d8b6343 --- /dev/null +++ b/dumps/scripts/363.cs2 @@ -0,0 +1,156 @@ +void script_363(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,string arg9,string arg10) { + int ivar9; + int ivar10; + int ivar11; + int ivar12; + deleteAllExtraChilds(new WidgetPointer(arg0)); + if ((arg3 == -1) && (strLength(arg9) <= 0)) { + setWidgetIsHidden(true, new WidgetPointer(arg0)); + setWidgetNoOptions(new WidgetPointer(arg0)); + return; + } + setWidgetIsHidden(false, new WidgetPointer(arg0)); + ivar9 = getWidgetActualHeight(new WidgetPointer(arg0)); + ivar10 = subtract(ivar9, 10); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(10, ivar10, 1, 0); + setWidgetPosition(0, 5, 1, 0); + cs2method1107(1); + setWidgetSprite(3413); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(10, 14, 1, 0); + setWidgetPosition(0, 0, 1, 0); + cs2method1107(1); + setWidgetSprite(3412); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(10, 14, 1, 0); + setWidgetPosition(0, subtract(ivar9, getWidgetActualHeight()), 1, 0); + cs2method1107(1); + setWidgetSprite(3411); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(14, ivar10, 0, 0); + setWidgetPosition(0, 5, 0, 0); + cs2method1107(1); + setWidgetSprite(3409); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(14, ivar10, 0, 0); + setWidgetPosition(0, 5, 2, 0); + cs2method1107(1); + setWidgetSprite(3410); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(14, 14, 0, 0); + setWidgetPosition(0, 0, 0, 0); + setWidgetSprite(3405); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(14, 14, 0, 0); + setWidgetPosition(0, 0, 2, 0); + setWidgetSprite(3406); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(14, 14, 0, 0); + setWidgetPosition(0, subtract(ivar9, getWidgetActualHeight()), 0, 0); + setWidgetSprite(3407); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(14, 14, 0, 0); + setWidgetPosition(0, subtract(ivar9, getWidgetActualHeight()), 2, 0); + setWidgetSprite(3408); + ivar11 = 0; + if (arg3 != -1) { + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(arg5, arg6, 0, 0); + if (arg7 == 2) { + ivar11 = subtract(ivar9, add(arg6, 2)); + } else { + ivar11 = divide(subtract(ivar9, arg6), 2); + } + setWidgetPosition(0, ivar11, 1, 0); + cs2method1107(0); + setWidgetSprite(arg3); + if (strLength(arg9) > 0) { + setWidgetContextMenuOption(1, new WidgetPointer(arg0), arg9); + createExtraChild(new WidgetPointer(arg0), 4, getExtraChildGap(new WidgetPointer(arg0))); + createExtraChild(new WidgetPointer(arg0), 4, getExtraChildGap(new WidgetPointer(arg0))); + if (add(multiply(getLineCount(subtract(getWidgetActualWidth(new WidgetPointer(arg0)), 6), 3793, arg9), 12), 5) <= ivar11) { + setWidgetSize(6, ivar11, 1, 0); + setWidgetSize(6, ivar11, 1, 0); + setWidgetTextAlignment(1, 1, 12); + setWidgetTextAlignment(1, 1, 12); + setWidgetPosition(1, 1, 1, 0); + setWidgetPosition(0, 0, 1, 0); + } else { + setWidgetSize(6, 10, 1, 1); + setWidgetSize(6, 10, 1, 1); + setWidgetTextAlignment(1, 0, 12); + setWidgetTextAlignment(1, 0, 12); + setWidgetPosition(1, 1, 1, 1); + setWidgetPosition(0, 0, 1, 1); + } + setWidgetFont(3793); + setWidgetFont(3793); + setWidgetRGB(new Color(255, 255, 255)); + setWidgetRGB(new Color(63, 16, 16)); + setWidgetUnknownBoolean(false); + setWidgetUnknownBoolean(false); + setWidgetText(arg9); + setWidgetText(arg9); + } + } else { + createExtraChild(new WidgetPointer(arg0), 4, getExtraChildGap(new WidgetPointer(arg0))); + createExtraChild(new WidgetPointer(arg0), 4, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(0, 0, 1, 1); + setWidgetSize(0, 0, 1, 1); + setWidgetPosition(1, 1, 1, 1); + setWidgetPosition(0, 0, 1, 1); + setWidgetTextAlignment(1, 1, 0); + setWidgetTextAlignment(1, 1, 0); + setWidgetFont(3793); + setWidgetFont(3793); + setWidgetRGB(new Color(255, 255, 255)); + setWidgetRGB(new Color(63, 16, 16)); + setWidgetUnknownBoolean(false); + setWidgetUnknownBoolean(false); + setWidgetText(arg9); + setWidgetText(arg9); + } + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(10, 4, 1, 0); + setWidgetPosition(0, 0, 1, 0); + ivar12 = getWidgetCustomChildArrayIndex(); + setWidgetVFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(10, 4, 1, 0); + setWidgetPosition(0, subtract(ivar9, getWidgetActualHeight()), 1, 0); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(3, ivar10, 0, 0); + setWidgetPosition(0, 5, 0, 0); + setWidgetHFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(3, ivar10, 0, 0); + setWidgetPosition(0, 5, 2, 0); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(16, 16, 0, 0); + setWidgetPosition(0, 0, 0, 0); + setWidgetHFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(16, 16, 0, 0); + setWidgetPosition(0, 0, 2, 0); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(16, 16, 0, 0); + setWidgetPosition(0, subtract(ivar9, getWidgetActualHeight()), 0, 0); + setWidgetHFlip(1); + setWidgetVFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(16, 16, 0, 0); + setWidgetPosition(0, subtract(ivar9, getWidgetActualHeight()), 2, 0); + setWidgetVFlip(1); + if (((boolean)arg8)) { + script_365(arg0, ivar12, 2); + setScriptCallOnMouseOver(366, new WidgetPointer(-1,65535), arg1, arg2, ivar12, ivar9, 1, arg4, new WidgetPointer(-32768,3), arg10, -2147483647, "Iigii11Isi", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(366, new WidgetPointer(-1,65535), arg1, arg2, ivar12, ivar9, 0, arg4, new WidgetPointer(-32768,3), arg10, -1, "Iigii11Isi", new WidgetPointer(arg0)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + } else { + script_365(arg0, ivar12, 0); + setScriptCallOnMouseOver(366, new WidgetPointer(arg0), arg1, arg2, ivar12, ivar9, 1, arg4, new WidgetPointer(-32768,3), arg10, -2147483647, "Iigii11Isi", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(366, new WidgetPointer(arg0), arg1, arg2, ivar12, ivar9, 0, arg4, new WidgetPointer(-32768,3), arg10, -1, "Iigii11Isi", new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/3630.cs2 b/dumps/scripts/3630.cs2 new file mode 100644 index 0000000..d2149a7 --- /dev/null +++ b/dumps/scripts/3630.cs2 @@ -0,0 +1,5 @@ +void script_3630(int arg0,int arg1,int arg2) { + setWidgetIsHidden(true, new WidgetPointer(arg0)); + setWidgetRGB(new Color(arg2), new WidgetPointer(arg1)); + return; +} diff --git a/dumps/scripts/3631.cs2 b/dumps/scripts/3631.cs2 new file mode 100644 index 0000000..0f9ce62 --- /dev/null +++ b/dumps/scripts/3631.cs2 @@ -0,0 +1,4 @@ +void script_3631(int arg0) { + script_3632(arg0); + return; +} diff --git a/dumps/scripts/3632.cs2 b/dumps/scripts/3632.cs2 new file mode 100644 index 0000000..3f63189 --- /dev/null +++ b/dumps/scripts/3632.cs2 @@ -0,0 +1,7 @@ +void script_3632(int arg0) { + if (setWidgetRegister(new WidgetPointer(arg0))) { + setWidgetIntegerNode(1101, getWidgetActualX()); + setWidgetIntegerNode(1102, getWidgetActualY()); + } + return; +} diff --git a/dumps/scripts/3633.cs2 b/dumps/scripts/3633.cs2 new file mode 100644 index 0000000..1679fc1 --- /dev/null +++ b/dumps/scripts/3633.cs2 @@ -0,0 +1,19 @@ +void script_3633(int arg0) { + int stack_dump0; + if (setWidgetRegister(new WidgetPointer(arg0))) { + setWidgetRGB(new Color(136, 255, 136), new WidgetPointer(arg0)); + setWidgetSize(31, 31, 0, 0, new WidgetPointer(arg0)); + stack_dump0 = 1101; + /* + mgi.tools.jagdecs2.DecompilerException: opcode 1613 not decompileable + at mgi.tools.jagdecs2.FlowBlocksGenerator.analyzeSpecialCall(FlowBlocksGenerator.java:297) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:249) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return; +} diff --git a/dumps/scripts/3634.cs2 b/dumps/scripts/3634.cs2 new file mode 100644 index 0000000..d2e7c49 --- /dev/null +++ b/dumps/scripts/3634.cs2 @@ -0,0 +1,19 @@ +void script_3634(int arg0) { + int stack_dump0; + if (setWidgetRegister(new WidgetPointer(arg0))) { + setWidgetRGB(new Color(204, 0, 0), new WidgetPointer(arg0)); + setWidgetSize(27, 27, 0, 0, new WidgetPointer(arg0)); + stack_dump0 = 1101; + /* + mgi.tools.jagdecs2.DecompilerException: opcode 1613 not decompileable + at mgi.tools.jagdecs2.FlowBlocksGenerator.analyzeSpecialCall(FlowBlocksGenerator.java:297) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:249) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return; +} diff --git a/dumps/scripts/3635.cs2 b/dumps/scripts/3635.cs2 new file mode 100644 index 0000000..f2dd89d --- /dev/null +++ b/dumps/scripts/3635.cs2 @@ -0,0 +1,11 @@ +void script_3635() { + setItemOnWidgetMethod2200(cs2method_3408(105, 79, 3170, mod(add(script_3667(14), bitconfig_7387), getCommonDefinitionSize(3170))), -1, new WidgetPointer(1001,171)); + setItemOnWidgetMethod2200(cs2method_3408(105, 79, 3170, mod(add(script_3666(2), bitconfig_7387), getCommonDefinitionSize(3170))), -1, new WidgetPointer(1001,172)); + setItemOnWidgetMethod2200(cs2method_3408(105, 79, 3170, mod(add(script_3668(12), bitconfig_7387), getCommonDefinitionSize(3170))), -1, new WidgetPointer(1001,173)); + setItemOnWidgetMethod2200(cs2method_3408(105, 79, 3170, mod(add(script_3666(5), bitconfig_7387), getCommonDefinitionSize(3170))), -1, new WidgetPointer(1001,174)); + setItemOnWidgetMethod2200(cs2method_3408(105, 79, 3170, mod(add(script_3668(5), bitconfig_7387), getCommonDefinitionSize(3170))), -1, new WidgetPointer(1001,175)); + setItemOnWidgetMethod2200(cs2method_3408(105, 79, 3170, mod(add(script_3666(10), bitconfig_7387), getCommonDefinitionSize(3170))), -1, new WidgetPointer(1001,176)); + setItemOnWidgetMethod2200(cs2method_3408(105, 79, 3170, mod(add(script_3667(5), bitconfig_7387), getCommonDefinitionSize(3170))), -1, new WidgetPointer(1001,177)); + setItemOnWidgetMethod2200(cs2method_3408(105, 79, 3170, mod(add(script_3666(13), bitconfig_7387), getCommonDefinitionSize(3170))), -1, new WidgetPointer(1001,178)); + return; +} diff --git a/dumps/scripts/3636.cs2 b/dumps/scripts/3636.cs2 new file mode 100644 index 0000000..4cecf19 --- /dev/null +++ b/dumps/scripts/3636.cs2 @@ -0,0 +1,4 @@ +void script_3636(int arg0,int arg1,int arg2) { + script_3625(3189, 3190, 3191, script_3669(bitconfig_7392), arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/3637.cs2 b/dumps/scripts/3637.cs2 new file mode 100644 index 0000000..8fa6a65 --- /dev/null +++ b/dumps/scripts/3637.cs2 @@ -0,0 +1,4 @@ +void script_3637(int arg0,int arg1,int arg2) { + script_3625(3192, 3193, 3194, script_3670(bitconfig_7392), arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/3638.cs2 b/dumps/scripts/3638.cs2 new file mode 100644 index 0000000..79fb10b --- /dev/null +++ b/dumps/scripts/3638.cs2 @@ -0,0 +1,4 @@ +void script_3638(int arg0,int arg1,int arg2) { + script_3625(3195, 3196, 3197, script_3671(bitconfig_7392), arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/3639.cs2 b/dumps/scripts/3639.cs2 new file mode 100644 index 0000000..c149504 --- /dev/null +++ b/dumps/scripts/3639.cs2 @@ -0,0 +1,4 @@ +void script_3639(int arg0,int arg1,int arg2) { + script_3626(3189, 3190, 3191, script_3669(bitconfig_7392), arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/364.cs2 b/dumps/scripts/364.cs2 new file mode 100644 index 0000000..fc45130 --- /dev/null +++ b/dumps/scripts/364.cs2 @@ -0,0 +1,4 @@ +void script_364() { + script_304(46435503); + return; +} diff --git a/dumps/scripts/3640.cs2 b/dumps/scripts/3640.cs2 new file mode 100644 index 0000000..191856a --- /dev/null +++ b/dumps/scripts/3640.cs2 @@ -0,0 +1,4 @@ +void script_3640(int arg0,int arg1,int arg2) { + script_3626(3192, 3193, 3194, script_3670(bitconfig_7392), arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/3641.cs2 b/dumps/scripts/3641.cs2 new file mode 100644 index 0000000..b3dc172 --- /dev/null +++ b/dumps/scripts/3641.cs2 @@ -0,0 +1,4 @@ +void script_3641(int arg0,int arg1,int arg2) { + script_3626(3195, 3196, 3197, script_3671(bitconfig_7392), arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/3642.cs2 b/dumps/scripts/3642.cs2 new file mode 100644 index 0000000..f089275 --- /dev/null +++ b/dumps/scripts/3642.cs2 @@ -0,0 +1,5 @@ +void script_3642(int arg0) { + script_3632(arg0); + script_3644(arg0); + return; +} diff --git a/dumps/scripts/3643.cs2 b/dumps/scripts/3643.cs2 new file mode 100644 index 0000000..8401e7f --- /dev/null +++ b/dumps/scripts/3643.cs2 @@ -0,0 +1,4 @@ +void script_3643(int arg0) { + script_3644(arg0); + return; +} diff --git a/dumps/scripts/3644.cs2 b/dumps/scripts/3644.cs2 new file mode 100644 index 0000000..2168958 --- /dev/null +++ b/dumps/scripts/3644.cs2 @@ -0,0 +1,8 @@ +void script_3644(int arg0) { + if (script_3666(1) == script_3667(14)) { + script_3633(arg0); + } else { + script_3634(arg0); + } + return; +} diff --git a/dumps/scripts/3645.cs2 b/dumps/scripts/3645.cs2 new file mode 100644 index 0000000..589446d --- /dev/null +++ b/dumps/scripts/3645.cs2 @@ -0,0 +1,5 @@ +void script_3645(int arg0) { + script_3632(arg0); + script_3647(arg0); + return; +} diff --git a/dumps/scripts/3646.cs2 b/dumps/scripts/3646.cs2 new file mode 100644 index 0000000..125fd6f --- /dev/null +++ b/dumps/scripts/3646.cs2 @@ -0,0 +1,4 @@ +void script_3646(int arg0) { + script_3647(arg0); + return; +} diff --git a/dumps/scripts/3647.cs2 b/dumps/scripts/3647.cs2 new file mode 100644 index 0000000..4622633 --- /dev/null +++ b/dumps/scripts/3647.cs2 @@ -0,0 +1,8 @@ +void script_3647(int arg0) { + if (script_3666(2) == script_3667(3)) { + script_3633(arg0); + } else { + script_3634(arg0); + } + return; +} diff --git a/dumps/scripts/3648.cs2 b/dumps/scripts/3648.cs2 new file mode 100644 index 0000000..bfbc71d --- /dev/null +++ b/dumps/scripts/3648.cs2 @@ -0,0 +1,5 @@ +void script_3648(int arg0) { + script_3632(arg0); + script_3650(arg0); + return; +} diff --git a/dumps/scripts/3649.cs2 b/dumps/scripts/3649.cs2 new file mode 100644 index 0000000..370228d --- /dev/null +++ b/dumps/scripts/3649.cs2 @@ -0,0 +1,4 @@ +void script_3649(int arg0) { + script_3650(arg0); + return; +} diff --git a/dumps/scripts/365.cs2 b/dumps/scripts/365.cs2 new file mode 100644 index 0000000..de34564 --- /dev/null +++ b/dumps/scripts/365.cs2 @@ -0,0 +1,79 @@ +void script_365(int arg0,int arg1,int arg2) { + if (((boolean)arg2)) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetSprite(4096); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(arg1, 1))) { + setWidgetSprite(4096); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(arg1, 2))) { + setWidgetSprite(4093); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(arg1, 3))) { + setWidgetSprite(4093); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(arg1, 4))) { + setWidgetSprite(4090); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(arg1, 5))) { + setWidgetSprite(4090); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(arg1, 6))) { + setWidgetSprite(4090); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(arg1, 7))) { + setWidgetSprite(4090); + } + } else if (arg2 == 2) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetSprite(4095); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(arg1, 1))) { + setWidgetSprite(4095); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(arg1, 2))) { + setWidgetSprite(4092); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(arg1, 3))) { + setWidgetSprite(4092); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(arg1, 4))) { + setWidgetSprite(4089); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(arg1, 5))) { + setWidgetSprite(4089); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(arg1, 6))) { + setWidgetSprite(4089); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(arg1, 7))) { + setWidgetSprite(4089); + } + } else { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetSprite(4097); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(arg1, 1))) { + setWidgetSprite(4097); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(arg1, 2))) { + setWidgetSprite(4094); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(arg1, 3))) { + setWidgetSprite(4094); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(arg1, 4))) { + setWidgetSprite(4091); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(arg1, 5))) { + setWidgetSprite(4091); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(arg1, 6))) { + setWidgetSprite(4091); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(arg1, 7))) { + setWidgetSprite(4091); + } + } + return; +} diff --git a/dumps/scripts/3650.cs2 b/dumps/scripts/3650.cs2 new file mode 100644 index 0000000..b916032 --- /dev/null +++ b/dumps/scripts/3650.cs2 @@ -0,0 +1,8 @@ +void script_3650(int arg0) { + if (script_3666(4) == script_3668(12)) { + script_3633(arg0); + } else { + script_3634(arg0); + } + return; +} diff --git a/dumps/scripts/3651.cs2 b/dumps/scripts/3651.cs2 new file mode 100644 index 0000000..bf250fb --- /dev/null +++ b/dumps/scripts/3651.cs2 @@ -0,0 +1,5 @@ +void script_3651(int arg0) { + script_3632(arg0); + script_3653(arg0); + return; +} diff --git a/dumps/scripts/3652.cs2 b/dumps/scripts/3652.cs2 new file mode 100644 index 0000000..c968b23 --- /dev/null +++ b/dumps/scripts/3652.cs2 @@ -0,0 +1,4 @@ +void script_3652(int arg0) { + script_3653(arg0); + return; +} diff --git a/dumps/scripts/3653.cs2 b/dumps/scripts/3653.cs2 new file mode 100644 index 0000000..fb7c1ae --- /dev/null +++ b/dumps/scripts/3653.cs2 @@ -0,0 +1,8 @@ +void script_3653(int arg0) { + if (script_3666(5) == script_3668(3)) { + script_3633(arg0); + } else { + script_3634(arg0); + } + return; +} diff --git a/dumps/scripts/3654.cs2 b/dumps/scripts/3654.cs2 new file mode 100644 index 0000000..3557f13 --- /dev/null +++ b/dumps/scripts/3654.cs2 @@ -0,0 +1,5 @@ +void script_3654(int arg0) { + script_3632(arg0); + script_3656(arg0); + return; +} diff --git a/dumps/scripts/3655.cs2 b/dumps/scripts/3655.cs2 new file mode 100644 index 0000000..f3f4f73 --- /dev/null +++ b/dumps/scripts/3655.cs2 @@ -0,0 +1,4 @@ +void script_3655(int arg0) { + script_3656(arg0); + return; +} diff --git a/dumps/scripts/3656.cs2 b/dumps/scripts/3656.cs2 new file mode 100644 index 0000000..75e17b0 --- /dev/null +++ b/dumps/scripts/3656.cs2 @@ -0,0 +1,8 @@ +void script_3656(int arg0) { + if (script_3666(9) == script_3668(5)) { + script_3633(arg0); + } else { + script_3634(arg0); + } + return; +} diff --git a/dumps/scripts/3657.cs2 b/dumps/scripts/3657.cs2 new file mode 100644 index 0000000..f5e96e9 --- /dev/null +++ b/dumps/scripts/3657.cs2 @@ -0,0 +1,5 @@ +void script_3657(int arg0) { + script_3632(arg0); + script_3659(arg0); + return; +} diff --git a/dumps/scripts/3658.cs2 b/dumps/scripts/3658.cs2 new file mode 100644 index 0000000..c97c19a --- /dev/null +++ b/dumps/scripts/3658.cs2 @@ -0,0 +1,4 @@ +void script_3658(int arg0) { + script_3659(arg0); + return; +} diff --git a/dumps/scripts/3659.cs2 b/dumps/scripts/3659.cs2 new file mode 100644 index 0000000..cbb92cb --- /dev/null +++ b/dumps/scripts/3659.cs2 @@ -0,0 +1,8 @@ +void script_3659(int arg0) { + if (script_3666(10) == script_3668(10)) { + script_3633(arg0); + } else { + script_3634(arg0); + } + return; +} diff --git a/dumps/scripts/366.cs2 b/dumps/scripts/366.cs2 new file mode 100644 index 0000000..340526e --- /dev/null +++ b/dumps/scripts/366.cs2 @@ -0,0 +1,50 @@ +void script_366(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,string arg9) { + int ivar9; + int ivar10; + int ivar11; + if (arg0 != -1) { + if (((boolean)arg5)) { + script_365(arg0, arg3, 1); + } else { + script_365(arg0, arg3, 0); + } + if (((boolean)arg6)) { + setScriptCallOnGameloop(367, new WidgetPointer(arg0), arg4, arg5, "Ii1", new WidgetPointer(arg0)); + } + } else { + script_365(arg7, arg3, 2); + } + if (setWidgetRegister(new WidgetPointer(arg7))) { + if (((boolean)arg5)) { + if (strLength(arg9) > 0) { + script_379(script_3365(arg7), getWidgetActualWidth(new WidgetPointer(arg7)), script_3366(arg7), arg8, arg9); + } + } else { + if ((script_3365(arg7) == globalint_2) && (getWidgetActualWidth(new WidgetPointer(arg7)) == globalint_773)) { + script_383(); + } + } + } + if (arg2 == -1) { + return; + } + ivar9 = 0; + ivar10 = getCommonDefinitionSize(arg2); + ivar11 = -1; + if (((boolean)arg5) && (ivar9 < ivar10)) { + while (true) { + if (ivar9 != arg1) { + ivar11 = ((int)cs2method_3408(105, 73, arg2, ivar9)); + if (ivar11 == -1) { + return; + } + if ((ivar11 != arg0) && isWidgetHidden(new WidgetPointer(ivar11))) { + setScriptCallOnGameloop(367, new WidgetPointer(ivar11), arg4, 0, "Ii1", new WidgetPointer(ivar11)); + script_365(ivar11, arg3, 0); + } + } + ivar9 = add(ivar9, 1); + } + } + return; +} diff --git a/dumps/scripts/3660.cs2 b/dumps/scripts/3660.cs2 new file mode 100644 index 0000000..1e5f56f --- /dev/null +++ b/dumps/scripts/3660.cs2 @@ -0,0 +1,5 @@ +void script_3660(int arg0) { + script_3632(arg0); + script_3662(arg0); + return; +} diff --git a/dumps/scripts/3661.cs2 b/dumps/scripts/3661.cs2 new file mode 100644 index 0000000..dbc52bb --- /dev/null +++ b/dumps/scripts/3661.cs2 @@ -0,0 +1,4 @@ +void script_3661(int arg0) { + script_3662(arg0); + return; +} diff --git a/dumps/scripts/3662.cs2 b/dumps/scripts/3662.cs2 new file mode 100644 index 0000000..0f010ff --- /dev/null +++ b/dumps/scripts/3662.cs2 @@ -0,0 +1,8 @@ +void script_3662(int arg0) { + if (script_3666(12) == script_3667(5)) { + script_3633(arg0); + } else { + script_3634(arg0); + } + return; +} diff --git a/dumps/scripts/3663.cs2 b/dumps/scripts/3663.cs2 new file mode 100644 index 0000000..9daaf19 --- /dev/null +++ b/dumps/scripts/3663.cs2 @@ -0,0 +1,5 @@ +void script_3663(int arg0) { + script_3632(arg0); + script_3665(arg0); + return; +} diff --git a/dumps/scripts/3664.cs2 b/dumps/scripts/3664.cs2 new file mode 100644 index 0000000..6665eff --- /dev/null +++ b/dumps/scripts/3664.cs2 @@ -0,0 +1,4 @@ +void script_3664(int arg0) { + script_3665(arg0); + return; +} diff --git a/dumps/scripts/3665.cs2 b/dumps/scripts/3665.cs2 new file mode 100644 index 0000000..7117352 --- /dev/null +++ b/dumps/scripts/3665.cs2 @@ -0,0 +1,8 @@ +void script_3665(int arg0) { + if (script_3666(13) == script_3667(12)) { + script_3633(arg0); + } else { + script_3634(arg0); + } + return; +} diff --git a/dumps/scripts/3666.cs2 b/dumps/scripts/3666.cs2 new file mode 100644 index 0000000..3f193d9 --- /dev/null +++ b/dumps/scripts/3666.cs2 @@ -0,0 +1,3 @@ +int script_3666(int arg0) { + return cs2method_3408(105, 105, script_3669(bitconfig_7392), mod(add(arg0, bitconfig_7388), getCommonDefinitionSize(script_3669(bitconfig_7392)))); +} diff --git a/dumps/scripts/3667.cs2 b/dumps/scripts/3667.cs2 new file mode 100644 index 0000000..9a963d6 --- /dev/null +++ b/dumps/scripts/3667.cs2 @@ -0,0 +1,3 @@ +int script_3667(int arg0) { + return cs2method_3408(105, 105, script_3670(bitconfig_7392), mod(add(arg0, bitconfig_7389), getCommonDefinitionSize(script_3670(bitconfig_7392)))); +} diff --git a/dumps/scripts/3668.cs2 b/dumps/scripts/3668.cs2 new file mode 100644 index 0000000..b01b19a --- /dev/null +++ b/dumps/scripts/3668.cs2 @@ -0,0 +1,3 @@ +int script_3668(int arg0) { + return cs2method_3408(105, 105, script_3671(bitconfig_7392), mod(add(arg0, bitconfig_7390), getCommonDefinitionSize(script_3671(bitconfig_7392)))); +} diff --git a/dumps/scripts/3669.cs2 b/dumps/scripts/3669.cs2 new file mode 100644 index 0000000..1b67a9b --- /dev/null +++ b/dumps/scripts/3669.cs2 @@ -0,0 +1,22 @@ +int script_3669(int arg0) { + flow_0: + SWITCH (arg0) { + case 2: + GOTO flow_1 + case 3: + GOTO flow_2 + case 4: + GOTO flow_3 + case 5: + GOTO flow_4 + } + return 3125; + flow_1: + return 3128; + flow_2: + return 3131; + flow_3: + return 3134; + flow_4: + return 3137; +} diff --git a/dumps/scripts/367.cs2 b/dumps/scripts/367.cs2 new file mode 100644 index 0000000..543fc17 --- /dev/null +++ b/dumps/scripts/367.cs2 @@ -0,0 +1,22 @@ +void script_367(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + ivar3 = 0; + if (((boolean)arg2)) { + ivar3 = add(arg1, 17); + } else { + ivar3 = arg1; + } + ivar4 = getWidgetActualHeight(new WidgetPointer(arg0)); + if (ivar4 < ivar3) { + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg0)), min(add(ivar4, 2), ivar3), 0, 0, new WidgetPointer(arg0)); + if (((boolean)mod(ivar4, arg1))) { + playSoundEffect(9840, 1, 0); + } + } else if (ivar4 > ivar3) { + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg0)), max(subtract(ivar4, 2), ivar3), 0, 0, new WidgetPointer(arg0)); + } else { + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/3670.cs2 b/dumps/scripts/3670.cs2 new file mode 100644 index 0000000..a4c722b --- /dev/null +++ b/dumps/scripts/3670.cs2 @@ -0,0 +1,22 @@ +int script_3670(int arg0) { + flow_0: + SWITCH (arg0) { + case 2: + GOTO flow_1 + case 3: + GOTO flow_2 + case 4: + GOTO flow_3 + case 5: + GOTO flow_4 + } + return 3126; + flow_1: + return 3129; + flow_2: + return 3132; + flow_3: + return 3135; + flow_4: + return 3138; +} diff --git a/dumps/scripts/3671.cs2 b/dumps/scripts/3671.cs2 new file mode 100644 index 0000000..6f8f539 --- /dev/null +++ b/dumps/scripts/3671.cs2 @@ -0,0 +1,22 @@ +int script_3671(int arg0) { + flow_0: + SWITCH (arg0) { + case 2: + GOTO flow_1 + case 3: + GOTO flow_2 + case 4: + GOTO flow_3 + case 5: + GOTO flow_4 + } + return 3127; + flow_1: + return 3130; + flow_2: + return 3133; + flow_3: + return 3136; + flow_4: + return 3139; +} diff --git a/dumps/scripts/3672.cs2 b/dumps/scripts/3672.cs2 new file mode 100644 index 0000000..74d914e --- /dev/null +++ b/dumps/scripts/3672.cs2 @@ -0,0 +1,44 @@ +void script_3672() { + int ivar0; + int ivar1; + string svar0; + string svar1; + string svar2; + string svar3; + svar0 = cs2method_3408(105, 115, 3230, globalint_1327); + svar1 = cs2method_3408(105, 115, 3230, globalint_1326); + svar2 = cs2method_3408(105, 115, 3231, globalint_1330); + svar3 = intToStr(globalint_1325) + "%"; + ivar0 = cs2method_3408(105, 100, 3233, globalint_1328); + ivar1 = cs2method_3408(105, 100, 3233, globalint_1329); + setWidgetText(new WidgetPointer(1004,72), svar0); + setWidgetRGB(new Color(cs2method_3408(105, 105, 3234, globalint_1327)), new WidgetPointer(1004,72)); + setWidgetText(new WidgetPointer(1004,71), svar1); + setWidgetRGB(new Color(cs2method_3408(105, 105, 3234, globalint_1326)), new WidgetPointer(1004,71)); + setWidgetSprite(ivar0, new WidgetPointer(1004,68)); + setWidgetSprite(ivar1, new WidgetPointer(1004,69)); + setWidgetText(new WidgetPointer(1004,70), svar2); + setWidgetRGB(new Color(cs2method_3408(105, 105, 3235, globalint_1330)), new WidgetPointer(1004,70)); + setWidgetText(new WidgetPointer(1004,73), svar3); + if (globalint_1327 != 3) { + setWidgetIsHidden(false, new WidgetPointer(1004,66)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1004,66)); + } + if (globalint_1326 != 3) { + setWidgetIsHidden(false, new WidgetPointer(1004,63)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1004,63)); + } + if (((boolean)globalint_1331)) { + setWidgetIsHidden(false, new WidgetPointer(1004,65)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1004,65)); + } + if (globalint_1330 > 66) { + setWidgetIsHidden(false, new WidgetPointer(1004,64)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1004,64)); + } + return; +} diff --git a/dumps/scripts/3673.cs2 b/dumps/scripts/3673.cs2 new file mode 100644 index 0000000..5832484 --- /dev/null +++ b/dumps/scripts/3673.cs2 @@ -0,0 +1,4 @@ +void script_3673() { + setWidgetIsHidden(true, new WidgetPointer(1004,82)); + return; +} diff --git a/dumps/scripts/3674.cs2 b/dumps/scripts/3674.cs2 new file mode 100644 index 0000000..28c318f --- /dev/null +++ b/dumps/scripts/3674.cs2 @@ -0,0 +1,12 @@ +void script_3674(int arg0) { + if (((boolean)arg0)) { + setWidgetSprite(2564, new WidgetPointer(1004,90)); + setWidgetSprite(2565, new WidgetPointer(1004,91)); + setWidgetSprite(2564, new WidgetPointer(1004,92)); + } else { + setWidgetSprite(2560, new WidgetPointer(1004,90)); + setWidgetSprite(2561, new WidgetPointer(1004,91)); + setWidgetSprite(2560, new WidgetPointer(1004,92)); + } + return; +} diff --git a/dumps/scripts/3675.cs2 b/dumps/scripts/3675.cs2 new file mode 100644 index 0000000..1e9bb52 --- /dev/null +++ b/dumps/scripts/3675.cs2 @@ -0,0 +1,4 @@ +void script_3675(int arg0) { + cs2method2103(125, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/3676.cs2 b/dumps/scripts/3676.cs2 new file mode 100644 index 0000000..893dd2c --- /dev/null +++ b/dumps/scripts/3676.cs2 @@ -0,0 +1,4 @@ +void script_3676(int arg0) { + cs2method2103(0, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/3677.cs2 b/dumps/scripts/3677.cs2 new file mode 100644 index 0000000..456f6a8 --- /dev/null +++ b/dumps/scripts/3677.cs2 @@ -0,0 +1,60 @@ +void script_3677(int arg0,int arg1) { + int ivar2; + string svar0; + ivar2 = 0; + switch (arg0) { + case 65929230: + ivar2 = globalint_1336; + break; + case 65929231: + ivar2 = globalint_1337; + break; + case 65929232: + ivar2 = globalint_1338; + break; + case 65929233: + ivar2 = globalint_1339; + break; + case 65929234: + ivar2 = globalint_1340; + break; + case 65929235: + ivar2 = globalint_1341; + break; + case 65929236: + ivar2 = globalint_1342; + break; + case 65929237: + ivar2 = globalint_1343; + break; + case 65929238: + ivar2 = globalint_1344; + break; + case 65929239: + ivar2 = globalint_1345; + break; + case 65929240: + ivar2 = globalint_1346; + break; + case 65929241: + ivar2 = globalint_1347; + break; + case 65929242: + ivar2 = globalint_1348; + break; + case 65929243: + ivar2 = globalint_1349; + break; + case 65929244: + ivar2 = globalint_1350; + break; + case 65929245: + ivar2 = globalint_1605; + break; + case 65929246: + ivar2 = globalint_1351; + } + svar0 = "Current price: " + script_940(ivar2) + " gp"; + script_569(arg0, arg1, 65929265, 25, getWidgetActualWidth(new WidgetPointer(getWidgetParentId(new WidgetPointer(1006,49)))), svar0); + return; +} diff --git a/dumps/scripts/3678.cs2 b/dumps/scripts/3678.cs2 new file mode 100644 index 0000000..1b1a7c7 --- /dev/null +++ b/dumps/scripts/3678.cs2 @@ -0,0 +1,44 @@ +void script_3678(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + deleteAllExtraChilds(new WidgetPointer(arg0)); + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + ivar4 = 6; + ivar5 = 5; + if (ivar4 > 1) { + if (getWidgetScrollMaxH(new WidgetPointer(arg0)) > 0) { + ivar2 = divide(subtract(getWidgetScrollMaxH(new WidgetPointer(arg0)), multiply(36, ivar4)), subtract(ivar4, 1)); + } else { + ivar2 = divide(subtract(getWidgetActualWidth(new WidgetPointer(arg0)), multiply(36, ivar4)), subtract(ivar4, 1)); + } + } + if (ivar5 > 1) { + if (getWidgetScrollMaxV(new WidgetPointer(arg0)) > 0) { + ivar3 = divide(subtract(getWidgetScrollMaxV(new WidgetPointer(arg0)), multiply(32, ivar5)), subtract(ivar5, 1)); + } else { + ivar3 = divide(subtract(getWidgetActualHeight(new WidgetPointer(arg0)), multiply(32, ivar5)), subtract(ivar5, 1)); + } + } + while (ivar1 < 30) { + createExtraChild(new WidgetPointer(arg0), 5, ivar1); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(multiply(add(36, ivar2), mod(ivar1, ivar4)), multiply(divide(ivar1, ivar4), add(32, ivar3)), 0, 0); + setItemOnWidgetMethod1212(cs2method_3408(105, 79, 3272, ivar1), ((int)isBitFlagged(globalint_1352, ivar1))); + if (isBitFlagged(globalint_1352, ivar1)) { + setWidgetContextMenuOption(1, "Take" + ""); + setWidgetBorderThickness(2); + } else { + cs2method2103(100); + } + setWidgetContextMenuOption(5, "Examine" + ""); + cs2method1305("" + cs2method_3408(105, 115, 3274, ivar1) + " Piece"); + setScriptCallOnClickContextMenu(3679, new WidgetPointer(-32768,3), ivar1, "Ii"); + ivar1 = add(ivar1, 1); + } + return; +} diff --git a/dumps/scripts/3679.cs2 b/dumps/scripts/3679.cs2 new file mode 100644 index 0000000..e1e3605 --- /dev/null +++ b/dumps/scripts/3679.cs2 @@ -0,0 +1,6 @@ +void script_3679(int arg0,int arg1) { + setWidgetNoOptions(new WidgetPointer(arg0)); + setWidgetContextMenuOption(5, new WidgetPointer(arg0), "Examine" + ""); + cs2method2305(new WidgetPointer(arg0), "" + cs2method_3408(105, 115, 3274, arg1) + " Piece"); + return; +} diff --git a/dumps/scripts/368.cs2 b/dumps/scripts/368.cs2 new file mode 100644 index 0000000..ac3f18c --- /dev/null +++ b/dumps/scripts/368.cs2 @@ -0,0 +1,30 @@ +void script_368(int arg0,int arg1,string arg2,string arg3) { + deleteAllExtraChilds(new WidgetPointer(arg0)); + setWidgetSize(arg1, 27, 0, 0, new WidgetPointer(arg0)); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(6, 26, 1, 0); + setWidgetPosition(0, 0, 1, 1); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(26, 26, 0, 0); + setWidgetPosition(0, 0, 0, 1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(26, 26, 0, 0); + setWidgetPosition(3, 0, 2, 1); + createExtraChild(new WidgetPointer(arg0), 4, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(0, 0, 1, 1); + setWidgetPosition(0, 0, 1, 1); + setWidgetFont(3793); + setWidgetRGB(new Color(235, 224, 188)); + setWidgetTextAlignment(1, 1, 0); + setWidgetUnknownBoolean(false); + setWidgetText(arg2); + script_370(arg0, 0); + setWidgetContextMenuOption(1, new WidgetPointer(arg0), arg2); + setScriptCallOnMouseEntered(369, new WidgetPointer(arg0), 1, "I1", new WidgetPointer(arg0)); + if (strLength(arg3) > 0) { + setScriptCallOnMouseOver(378, arg3, new WidgetPointer(-32768,3), -1, -2147483647, "sIii", new WidgetPointer(arg0)); + } + setScriptCallOnMouseExit(369, new WidgetPointer(arg0), 0, "I1", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/3680.cs2 b/dumps/scripts/3680.cs2 new file mode 100644 index 0000000..9b544ea --- /dev/null +++ b/dumps/scripts/3680.cs2 @@ -0,0 +1,90 @@ +void script_3680() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + string svar0; + int stack_dump0; + script_41(12255248); + globalint_1 = 0; + ivar0 = -1; + if (setWidgetRegister(new WidgetPointer(187,4))) { + stack_dump0 = 1133; + /* + mgi.tools.jagdecs2.DecompilerException: opcode 1613 not decompileable + at mgi.tools.jagdecs2.FlowBlocksGenerator.analyzeSpecialCall(FlowBlocksGenerator.java:297) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:249) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + ivar1 = 0; + ivar2 = 0; + svar0 = ""; + ivar3 = strLength(globalstring_196); + ivar4 = 5; + while (ivar0 != -1) { + if (setWidgetRegister(new WidgetPointer(187,1), multiply(ivar0, 2)) && setWidgetRegister(new WidgetPointer(187,1), add(multiply(ivar0, 2), 1))) { + setWidgetNoOptions(); + setWidgetNoOptions(); + svar0 = lower(getWidgetText()); + if (strLength(svar0) > 0) { + if (((boolean)script_837(ivar0))) { + if (((boolean)ivar3) || (strIndexof(0, svar0, globalstring_196) != -1)) { + setWidgetContextMenuOption(2, "Unlock hint"); + script_3681(ivar0); + setWidgetHidden(0); + setWidgetHidden(0); + setWidgetPosition(15, ivar4, 0, 0); + setWidgetPosition(2, add(ivar4, 1), 0, 0); + ivar4 = add(ivar4, 15); + } else { + setWidgetHidden(1); + setWidgetHidden(1); + } + ivar1 = add(ivar1, 1); + } else { + if (((boolean)ivar3) || (strIndexof(0, svar0, globalstring_196) != -1)) { + setWidgetContextMenuOption(2, "Unlock hint"); + setWidgetRGB(new Color(255, 0, 0)); + setScriptCallOnMouseExit(1356, new WidgetPointer(-32768,3), -2147483643, 16711680, "Iii"); + setScriptCallOnClickContextMenu(-1, ""); + setWidgetHidden(0); + setWidgetPosition(15, ivar4, 0, 0); + setWidgetPosition(2, add(ivar4, 1), 0, 0); + ivar4 = add(ivar4, 15); + } else { + setWidgetHidden(1); + } + setWidgetHidden(1); + } + ivar2 = add(ivar2, 1); + } + stack_dump0 = 1133; + /* + mgi.tools.jagdecs2.DecompilerException: opcode 1613 not decompileable + at mgi.tools.jagdecs2.FlowBlocksGenerator.analyzeSpecialCall(FlowBlocksGenerator.java:297) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:249) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + ivar0 = -1; + } + setWidgetScrollMax(167, add(5, ivar4), new WidgetPointer(187,1)); + script_72(12255234, 12255233, globalint_88); + setWidgetText(new WidgetPointer(187,5), "Unlocked:" + "
" + intToStr(ivar1) + " / " + intToStr(ivar2)); + if (ivar4 == 5) { + setWidgetIsHidden(false, new WidgetPointer(187,18)); + } else { + setWidgetIsHidden(true, new WidgetPointer(187,18)); + } + return; +} diff --git a/dumps/scripts/3681.cs2 b/dumps/scripts/3681.cs2 new file mode 100644 index 0000000..ec0c614 --- /dev/null +++ b/dumps/scripts/3681.cs2 @@ -0,0 +1,25 @@ +void script_3681(int arg0) { + string svar0; + string svar1; + svar0 = "Add to playlist"; + svar1 = "Remove from playlist"; + setWidgetContextMenuOption(1, "Play"); + setWidgetRGB(new Color(0, 255, 0)); + setScriptCallOnMouseExit(1356, new WidgetPointer(-32768,3), -2147483643, 65280, "Iii"); + setWidgetHidden(0); + setScriptCallOnClickContextMenu(2885, new WidgetPointer(-32768,3), -2147483643, 150, 0, 20, -2147483644, "Iiiiii"); + if ((((((((((((arg0 == bitconfig_7081) || (arg0 == bitconfig_7082)) || (arg0 == bitconfig_7083)) || (arg0 == bitconfig_7084)) || (arg0 == bitconfig_7085)) || (arg0 == bitconfig_7086)) || (arg0 == bitconfig_7087)) || (arg0 == bitconfig_7088)) || (arg0 == bitconfig_7089)) || (arg0 == bitconfig_7090)) || (arg0 == bitconfig_7091)) || (arg0 == bitconfig_7092)) { + setWidgetSprite(2430); + setWidgetContextMenuOption(4, svar1); + setWidgetContextMenuOption(4, svar1); + setScriptCallOnMouseOver(1160, new WidgetPointer(187,1), -2147483643, new WidgetPointer(187,16), svar1, 25, 189, "IiIsii"); + setScriptCallOnMouseExit(40, new WidgetPointer(187,16), "I"); + } else { + setWidgetContextMenuOption(3, svar0); + setWidgetContextMenuOption(3, svar0); + setWidgetSprite(2429); + setScriptCallOnMouseOver(1160, new WidgetPointer(187,1), -2147483643, new WidgetPointer(187,16), svar0, 25, 189, "IiIsii"); + setScriptCallOnMouseExit(40, new WidgetPointer(187,16), "I"); + } + return; +} diff --git a/dumps/scripts/3682.cs2 b/dumps/scripts/3682.cs2 new file mode 100644 index 0000000..ad83a5f --- /dev/null +++ b/dumps/scripts/3682.cs2 @@ -0,0 +1,9 @@ +void script_3682() { + if (((boolean)strLength(globalstring_196)) && (globalint_5 != 14)) { + setWidgetSprite(3246, new WidgetPointer(187,17)); + script_3685(); + } else { + script_3683(); + } + return; +} diff --git a/dumps/scripts/3683.cs2 b/dumps/scripts/3683.cs2 new file mode 100644 index 0000000..69e7d8f --- /dev/null +++ b/dumps/scripts/3683.cs2 @@ -0,0 +1,7 @@ +void script_3683() { + script_1548(14); + globalstring_196 = ""; + script_3680(); + setWidgetSprite(3245, new WidgetPointer(187,17)); + return; +} diff --git a/dumps/scripts/3684.cs2 b/dumps/scripts/3684.cs2 new file mode 100644 index 0000000..1295e72 --- /dev/null +++ b/dumps/scripts/3684.cs2 @@ -0,0 +1,7 @@ +void script_3684() { + if (((boolean)bitconfig_4393) || ((boolean)bitconfig_542)) { + return; + } + script_39(12255242, 12255248, 25, 189, "Click here to search for a song"); + return; +} diff --git a/dumps/scripts/3685.cs2 b/dumps/scripts/3685.cs2 new file mode 100644 index 0000000..c350819 --- /dev/null +++ b/dumps/scripts/3685.cs2 @@ -0,0 +1,20 @@ +void script_3685() { + if (((boolean)globalint_11)) { + messageType0("You can't do that while you're reporting abuse."); + return; + } + if (getDisplayMode() >= 2) { + setWidgetIsHidden(false, new WidgetPointer(746,73)); + } + setWidgetIsHidden(false, new WidgetPointer(752,3)); + setWidgetIsHidden(true, new WidgetPointer(752,7)); + setWidgetIsHidden(true, new WidgetPointer(752,8)); + setWidgetText(new WidgetPointer(752,4), "Enter the name of the song you wish to search for:"); + globalint_5 = 14; + script_1564(""); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(752,3)); + script_2026(); + setScriptCallOnKeyPress(112, -2147483640, false, "iz", new WidgetPointer(752,5)); + script_1188(); + return; +} diff --git a/dumps/scripts/3686.cs2 b/dumps/scripts/3686.cs2 new file mode 100644 index 0000000..1f4f870 --- /dev/null +++ b/dumps/scripts/3686.cs2 @@ -0,0 +1,4 @@ +void script_3686() { + script_304(303879163); + return; +} diff --git a/dumps/scripts/3687.cs2 b/dumps/scripts/3687.cs2 new file mode 100644 index 0000000..f31ff1d --- /dev/null +++ b/dumps/scripts/3687.cs2 @@ -0,0 +1,4 @@ +void script_3687() { + script_304(46016274); + return; +} diff --git a/dumps/scripts/3688.cs2 b/dumps/scripts/3688.cs2 new file mode 100644 index 0000000..66aa9aa --- /dev/null +++ b/dumps/scripts/3688.cs2 @@ -0,0 +1,4 @@ +void script_3688() { + script_304(54027871); + return; +} diff --git a/dumps/scripts/3689.cs2 b/dumps/scripts/3689.cs2 new file mode 100644 index 0000000..b97edc5 --- /dev/null +++ b/dumps/scripts/3689.cs2 @@ -0,0 +1,4 @@ +void script_3689() { + script_304(593945894); + return; +} diff --git a/dumps/scripts/369.cs2 b/dumps/scripts/369.cs2 new file mode 100644 index 0000000..a73b89c --- /dev/null +++ b/dumps/scripts/369.cs2 @@ -0,0 +1,4 @@ +void script_369(int arg0,int arg1) { + script_370(arg0, arg1); + return; +} diff --git a/dumps/scripts/3690.cs2 b/dumps/scripts/3690.cs2 new file mode 100644 index 0000000..0eb5988 --- /dev/null +++ b/dumps/scripts/3690.cs2 @@ -0,0 +1,4 @@ +void script_3690() { + script_304(61416605); + return; +} diff --git a/dumps/scripts/3691.cs2 b/dumps/scripts/3691.cs2 new file mode 100644 index 0000000..fb755ea --- /dev/null +++ b/dumps/scripts/3691.cs2 @@ -0,0 +1,4 @@ +void script_3691() { + script_304(55026826); + return; +} diff --git a/dumps/scripts/3692.cs2 b/dumps/scripts/3692.cs2 new file mode 100644 index 0000000..43b553b --- /dev/null +++ b/dumps/scripts/3692.cs2 @@ -0,0 +1,4 @@ +void script_3692() { + script_304(50499717); + return; +} diff --git a/dumps/scripts/3693.cs2 b/dumps/scripts/3693.cs2 new file mode 100644 index 0000000..cd9a16a --- /dev/null +++ b/dumps/scripts/3693.cs2 @@ -0,0 +1,4 @@ +void script_3693() { + script_304(30463099); + return; +} diff --git a/dumps/scripts/3694.cs2 b/dumps/scripts/3694.cs2 new file mode 100644 index 0000000..2203732 --- /dev/null +++ b/dumps/scripts/3694.cs2 @@ -0,0 +1,4 @@ +void script_3694() { + script_304(47916465); + return; +} diff --git a/dumps/scripts/3695.cs2 b/dumps/scripts/3695.cs2 new file mode 100644 index 0000000..ba40bf1 --- /dev/null +++ b/dumps/scripts/3695.cs2 @@ -0,0 +1,4 @@ +void script_3695() { + script_304(48539058); + return; +} diff --git a/dumps/scripts/3696.cs2 b/dumps/scripts/3696.cs2 new file mode 100644 index 0000000..a84cb2b --- /dev/null +++ b/dumps/scripts/3696.cs2 @@ -0,0 +1,4 @@ +void script_3696() { + script_304(49309006); + return; +} diff --git a/dumps/scripts/3697.cs2 b/dumps/scripts/3697.cs2 new file mode 100644 index 0000000..478ae7f --- /dev/null +++ b/dumps/scripts/3697.cs2 @@ -0,0 +1,4 @@ +void script_3697() { + script_304(584094911); + return; +} diff --git a/dumps/scripts/3698.cs2 b/dumps/scripts/3698.cs2 new file mode 100644 index 0000000..09c881e --- /dev/null +++ b/dumps/scripts/3698.cs2 @@ -0,0 +1,4 @@ +void script_3698() { + script_304(40019874); + return; +} diff --git a/dumps/scripts/3699.cs2 b/dumps/scripts/3699.cs2 new file mode 100644 index 0000000..cdbe1ee --- /dev/null +++ b/dumps/scripts/3699.cs2 @@ -0,0 +1,4 @@ +void script_3699() { + script_304(41707423); + return; +} diff --git a/dumps/scripts/37.cs2 b/dumps/scripts/37.cs2 new file mode 100644 index 0000000..40897f0 --- /dev/null +++ b/dumps/scripts/37.cs2 @@ -0,0 +1,52 @@ +void script_37(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + ivar4 = subtract(getWidgetScrollMaxV(new WidgetPointer(arg1)), getWidgetActualHeight(new WidgetPointer(arg1))); + if (((boolean)ivar4)) { + ivar4 = 1; + } + if (arg2 < 0) { + arg2 = 0; + } + if (arg2 > ivar4) { + arg2 = ivar4; + } + cs2method2100(0, arg2, new WidgetPointer(arg1)); + switch (arg1) { + case 8978490: + globalint_7 = arg2; + break; + case 19660815: + globalint_109 = arg2; + break; + case 48168973: + globalint_121 = arg2; + break; + case 49938525: + script_705(bitconfig_4893, arg2); + break; + case 59572276: + globalint_1122 = arg2; + break; + case 59768852: + globalint_1124 = arg2; + break; + case 12255233: + globalint_88 = arg2; + break; + case 73007109: + script_5082(arg1); + } + ivar5 = 0; + if (((boolean)arg3)) { + ivar5 = subtract(subtract(getWidgetActualHeight(new WidgetPointer(arg0)), 32), getWidgetActualHeight()); + setWidgetPosition(0, add(16, multiplyDivide(arg2, ivar4, ivar5)), 0, 0); + if (setWidgetRegister(new WidgetPointer(arg0), 2)) { + setWidgetPosition(0, getWidgetActualY(), 0, 0); + } + if (setWidgetRegister(new WidgetPointer(arg0), 3)) { + setWidgetPosition(0, subtract(add(getWidgetActualY(), getWidgetActualHeight()), 5), 0, 0); + } + } + return; +} diff --git a/dumps/scripts/370.cs2 b/dumps/scripts/370.cs2 new file mode 100644 index 0000000..d12b175 --- /dev/null +++ b/dumps/scripts/370.cs2 @@ -0,0 +1,25 @@ +void script_370(int arg0,int arg1) { + if (((boolean)arg1)) { + if (setWidgetRegister(new WidgetPointer(arg0), 0)) { + setWidgetSprite(4038); + } + if (setWidgetRegister(new WidgetPointer(arg0), 1)) { + setWidgetSprite(4032); + } + if (setWidgetRegister(new WidgetPointer(arg0), 2)) { + setWidgetSprite(4035); + } + } else { + if (setWidgetRegister(new WidgetPointer(arg0), 0)) { + setWidgetSprite(4037); + } + if (setWidgetRegister(new WidgetPointer(arg0), 1)) { + setWidgetSprite(4031); + } + if (setWidgetRegister(new WidgetPointer(arg0), 2)) { + setWidgetSprite(4034); + } + script_383(); + } + return; +} diff --git a/dumps/scripts/3700.cs2 b/dumps/scripts/3700.cs2 new file mode 100644 index 0000000..d60cada --- /dev/null +++ b/dumps/scripts/3700.cs2 @@ -0,0 +1,4 @@ +void script_3700() { + script_304(42100021); + return; +} diff --git a/dumps/scripts/3701.cs2 b/dumps/scripts/3701.cs2 new file mode 100644 index 0000000..b67b0d7 --- /dev/null +++ b/dumps/scripts/3701.cs2 @@ -0,0 +1,4 @@ +void script_3701() { + script_304(42624265); + return; +} diff --git a/dumps/scripts/3702.cs2 b/dumps/scripts/3702.cs2 new file mode 100644 index 0000000..8d99f9e --- /dev/null +++ b/dumps/scripts/3702.cs2 @@ -0,0 +1,4 @@ +void script_3702() { + script_304(47408819); + return; +} diff --git a/dumps/scripts/3703.cs2 b/dumps/scripts/3703.cs2 new file mode 100644 index 0000000..90ce72e --- /dev/null +++ b/dumps/scripts/3703.cs2 @@ -0,0 +1,4 @@ +void script_3703() { + script_304(46458553); + return; +} diff --git a/dumps/scripts/3704.cs2 b/dumps/scripts/3704.cs2 new file mode 100644 index 0000000..06abfc8 --- /dev/null +++ b/dumps/scripts/3704.cs2 @@ -0,0 +1,4 @@ +void script_3704() { + script_304(47146647); + return; +} diff --git a/dumps/scripts/3705.cs2 b/dumps/scripts/3705.cs2 new file mode 100644 index 0000000..713684d --- /dev/null +++ b/dumps/scripts/3705.cs2 @@ -0,0 +1,4 @@ +void script_3705() { + script_304(43125982); + return; +} diff --git a/dumps/scripts/3706.cs2 b/dumps/scripts/3706.cs2 new file mode 100644 index 0000000..6007291 --- /dev/null +++ b/dumps/scripts/3706.cs2 @@ -0,0 +1,4 @@ +void script_3706() { + script_304(46212764); + return; +} diff --git a/dumps/scripts/3707.cs2 b/dumps/scripts/3707.cs2 new file mode 100644 index 0000000..2cc2a15 --- /dev/null +++ b/dumps/scripts/3707.cs2 @@ -0,0 +1,4 @@ +void script_3707() { + script_304(42093725); + return; +} diff --git a/dumps/scripts/3708.cs2 b/dumps/scripts/3708.cs2 new file mode 100644 index 0000000..6f4bc8a --- /dev/null +++ b/dumps/scripts/3708.cs2 @@ -0,0 +1,4 @@ +void script_3708() { + script_304(575055984); + return; +} diff --git a/dumps/scripts/3709.cs2 b/dumps/scripts/3709.cs2 new file mode 100644 index 0000000..2dfdda9 --- /dev/null +++ b/dumps/scripts/3709.cs2 @@ -0,0 +1,4 @@ +void script_3709() { + script_304(42388643); + return; +} diff --git a/dumps/scripts/371.cs2 b/dumps/scripts/371.cs2 new file mode 100644 index 0000000..d6b384c --- /dev/null +++ b/dumps/scripts/371.cs2 @@ -0,0 +1,44 @@ +void script_371(int arg0) { + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(12, 12, 1, 1); + setWidgetPosition(0, 0, 1, 1); + cs2method1107(0); + setWidgetSprite(3457); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(12, 14, 1, 0); + setWidgetPosition(0, 0, 1, 0); + cs2method1107(1); + setWidgetSprite(3460); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(12, 14, 1, 0); + setWidgetPosition(0, 0, 1, 2); + cs2method1107(1); + setWidgetSprite(3461); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(14, 12, 0, 1); + setWidgetPosition(0, 0, 0, 1); + cs2method1107(0); + setWidgetSprite(3458); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(14, 12, 0, 1); + setWidgetPosition(0, 0, 2, 1); + cs2method1107(0); + setWidgetSprite(3459); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(14, 14, 0, 0); + setWidgetPosition(0, 0, 0, 0); + setWidgetSprite(3453); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(14, 14, 0, 0); + setWidgetPosition(0, 0, 2, 0); + setWidgetSprite(3454); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(14, 14, 0, 0); + setWidgetPosition(0, 0, 0, 2); + setWidgetSprite(3455); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(14, 14, 0, 0); + setWidgetPosition(0, 0, 2, 2); + setWidgetSprite(3456); + return; +} diff --git a/dumps/scripts/3710.cs2 b/dumps/scripts/3710.cs2 new file mode 100644 index 0000000..e0c629a --- /dev/null +++ b/dumps/scripts/3710.cs2 @@ -0,0 +1,4 @@ +void script_3710() { + script_304(307669049); + return; +} diff --git a/dumps/scripts/3711.cs2 b/dumps/scripts/3711.cs2 new file mode 100644 index 0000000..51812b1 --- /dev/null +++ b/dumps/scripts/3711.cs2 @@ -0,0 +1,4 @@ +void script_3711() { + script_304(44190931); + return; +} diff --git a/dumps/scripts/3712.cs2 b/dumps/scripts/3712.cs2 new file mode 100644 index 0000000..dea0331 --- /dev/null +++ b/dumps/scripts/3712.cs2 @@ -0,0 +1,4 @@ +void script_3712() { + script_304(41117702); + return; +} diff --git a/dumps/scripts/3713.cs2 b/dumps/scripts/3713.cs2 new file mode 100644 index 0000000..db8e4c9 --- /dev/null +++ b/dumps/scripts/3713.cs2 @@ -0,0 +1,4 @@ +void script_3713() { + script_304(44633391); + return; +} diff --git a/dumps/scripts/3714.cs2 b/dumps/scripts/3714.cs2 new file mode 100644 index 0000000..ac2f2ce --- /dev/null +++ b/dumps/scripts/3714.cs2 @@ -0,0 +1,4 @@ +void script_3714() { + script_304(42919960); + return; +} diff --git a/dumps/scripts/3715.cs2 b/dumps/scripts/3715.cs2 new file mode 100644 index 0000000..b2cfc82 --- /dev/null +++ b/dumps/scripts/3715.cs2 @@ -0,0 +1,4 @@ +void script_3715() { + script_304(41979164); + return; +} diff --git a/dumps/scripts/3716.cs2 b/dumps/scripts/3716.cs2 new file mode 100644 index 0000000..c3195d8 --- /dev/null +++ b/dumps/scripts/3716.cs2 @@ -0,0 +1,4 @@ +void script_3716() { + script_304(53596925); + return; +} diff --git a/dumps/scripts/3717.cs2 b/dumps/scripts/3717.cs2 new file mode 100644 index 0000000..977e73d --- /dev/null +++ b/dumps/scripts/3717.cs2 @@ -0,0 +1,4 @@ +void script_3717() { + script_304(42995009); + return; +} diff --git a/dumps/scripts/3718.cs2 b/dumps/scripts/3718.cs2 new file mode 100644 index 0000000..5c77894 --- /dev/null +++ b/dumps/scripts/3718.cs2 @@ -0,0 +1,4 @@ +void script_3718() { + script_304(583362409); + return; +} diff --git a/dumps/scripts/3719.cs2 b/dumps/scripts/3719.cs2 new file mode 100644 index 0000000..73e0698 --- /dev/null +++ b/dumps/scripts/3719.cs2 @@ -0,0 +1,4 @@ +void script_3719() { + script_304(41864378); + return; +} diff --git a/dumps/scripts/372.cs2 b/dumps/scripts/372.cs2 new file mode 100644 index 0000000..1eedd39 --- /dev/null +++ b/dumps/scripts/372.cs2 @@ -0,0 +1,4 @@ +void script_372() { + script_304(46795872); + return; +} diff --git a/dumps/scripts/3720.cs2 b/dumps/scripts/3720.cs2 new file mode 100644 index 0000000..8850071 --- /dev/null +++ b/dumps/scripts/3720.cs2 @@ -0,0 +1,4 @@ +void script_3720() { + script_304(46278466); + return; +} diff --git a/dumps/scripts/3721.cs2 b/dumps/scripts/3721.cs2 new file mode 100644 index 0000000..0ff6504 --- /dev/null +++ b/dumps/scripts/3721.cs2 @@ -0,0 +1,4 @@ +void script_3721() { + script_304(46534250); + return; +} diff --git a/dumps/scripts/3722.cs2 b/dumps/scripts/3722.cs2 new file mode 100644 index 0000000..2aaccc6 --- /dev/null +++ b/dumps/scripts/3722.cs2 @@ -0,0 +1,6 @@ +void script_3722(int arg0,int arg1,int arg2) { + if (standart_config_851 != -1) { + script_1163(arg0, arg1, arg2, 0, 180, getItemName(standart_config_851)); + } + return; +} diff --git a/dumps/scripts/3723.cs2 b/dumps/scripts/3723.cs2 new file mode 100644 index 0000000..e253c23 --- /dev/null +++ b/dumps/scripts/3723.cs2 @@ -0,0 +1,4 @@ +void script_3723() { + script_304(46321214); + return; +} diff --git a/dumps/scripts/3724.cs2 b/dumps/scripts/3724.cs2 new file mode 100644 index 0000000..3a03601 --- /dev/null +++ b/dumps/scripts/3724.cs2 @@ -0,0 +1,4 @@ +void script_3724() { + script_304(41603688); + return; +} diff --git a/dumps/scripts/3725.cs2 b/dumps/scripts/3725.cs2 new file mode 100644 index 0000000..5540546 --- /dev/null +++ b/dumps/scripts/3725.cs2 @@ -0,0 +1,4 @@ +void script_3725() { + script_304(44732033); + return; +} diff --git a/dumps/scripts/3726.cs2 b/dumps/scripts/3726.cs2 new file mode 100644 index 0000000..f8879aa --- /dev/null +++ b/dumps/scripts/3726.cs2 @@ -0,0 +1,4 @@ +void script_3726() { + script_304(49899609); + return; +} diff --git a/dumps/scripts/3727.cs2 b/dumps/scripts/3727.cs2 new file mode 100644 index 0000000..593f9d0 --- /dev/null +++ b/dumps/scripts/3727.cs2 @@ -0,0 +1,4 @@ +void script_3727() { + script_304(45813382); + return; +} diff --git a/dumps/scripts/3728.cs2 b/dumps/scripts/3728.cs2 new file mode 100644 index 0000000..cf3507b --- /dev/null +++ b/dumps/scripts/3728.cs2 @@ -0,0 +1,4 @@ +void script_3728() { + script_304(49244283); + return; +} diff --git a/dumps/scripts/3729.cs2 b/dumps/scripts/3729.cs2 new file mode 100644 index 0000000..c54ac0e --- /dev/null +++ b/dumps/scripts/3729.cs2 @@ -0,0 +1,4 @@ +void script_3729() { + script_304(61410205); + return; +} diff --git a/dumps/scripts/373.cs2 b/dumps/scripts/373.cs2 new file mode 100644 index 0000000..27237fb --- /dev/null +++ b/dumps/scripts/373.cs2 @@ -0,0 +1,36 @@ +void script_373(int arg0,int arg1,int arg2,int arg3,int arg4) { + int ivar5; + ivar5 = -1; + if (arg1 == -1) { + ivar5 = getWidgetParentId(new WidgetPointer(arg0)); + } else { + ivar5 = arg0; + } + if (((boolean)arg4)) { + flow_4: + IF (arg1 == -1) + GOTO flow_5 + GOTO flow_6 + flow_5: + IF (setWidgetRegister(new WidgetPointer(arg0))) + GOTO flow_7 + flow_6: + IF (setWidgetRegister(new WidgetPointer(arg0), arg1)) + GOTO flow_7 + GOTO flow_8 + flow_7: + createExtraChild(new WidgetPointer(ivar5), 3, arg2); + setWidgetSize(subtract(getWidgetActualWidth(), multiply(arg3, 2)), subtract(getWidgetActualHeight(), multiply(arg3, 2)), 0, 0); + setWidgetPosition(add(getWidgetActualX(), arg3), add(getWidgetActualY(), arg3), 0, 0); + setWidgetRGB(new Color(255, 255, 255)); + cs2method2103(200); + setWidgetFilled(1); + flow_8: + } else { + if (setWidgetRegister(new WidgetPointer(ivar5), arg2)) { + deleteExtraChild(); + } + script_383(); + } + return; +} diff --git a/dumps/scripts/3730.cs2 b/dumps/scripts/3730.cs2 new file mode 100644 index 0000000..35baa8e --- /dev/null +++ b/dumps/scripts/3730.cs2 @@ -0,0 +1,4 @@ +void script_3730() { + script_304(49440777); + return; +} diff --git a/dumps/scripts/3731.cs2 b/dumps/scripts/3731.cs2 new file mode 100644 index 0000000..ca8cad2 --- /dev/null +++ b/dumps/scripts/3731.cs2 @@ -0,0 +1,4 @@ +void script_3731() { + script_304(62606326); + return; +} diff --git a/dumps/scripts/3732.cs2 b/dumps/scripts/3732.cs2 new file mode 100644 index 0000000..53d081a --- /dev/null +++ b/dumps/scripts/3732.cs2 @@ -0,0 +1,4 @@ +void script_3732() { + script_304(50309136); + return; +} diff --git a/dumps/scripts/3733.cs2 b/dumps/scripts/3733.cs2 new file mode 100644 index 0000000..4a35c75 --- /dev/null +++ b/dumps/scripts/3733.cs2 @@ -0,0 +1,4 @@ +void script_3733() { + script_304(49286222); + return; +} diff --git a/dumps/scripts/3734.cs2 b/dumps/scripts/3734.cs2 new file mode 100644 index 0000000..9b12694 --- /dev/null +++ b/dumps/scripts/3734.cs2 @@ -0,0 +1,4 @@ +void script_3734() { + script_304(53159478); + return; +} diff --git a/dumps/scripts/3735.cs2 b/dumps/scripts/3735.cs2 new file mode 100644 index 0000000..a71d45a --- /dev/null +++ b/dumps/scripts/3735.cs2 @@ -0,0 +1,4 @@ +void script_3735() { + script_304(49450144); + return; +} diff --git a/dumps/scripts/3736.cs2 b/dumps/scripts/3736.cs2 new file mode 100644 index 0000000..0ae5783 --- /dev/null +++ b/dumps/scripts/3736.cs2 @@ -0,0 +1,4 @@ +void script_3736() { + script_304(62612726); + return; +} diff --git a/dumps/scripts/3737.cs2 b/dumps/scripts/3737.cs2 new file mode 100644 index 0000000..41de328 --- /dev/null +++ b/dumps/scripts/3737.cs2 @@ -0,0 +1,4 @@ +void script_3737() { + script_304(47926450); + return; +} diff --git a/dumps/scripts/3738.cs2 b/dumps/scripts/3738.cs2 new file mode 100644 index 0000000..f61a9fc --- /dev/null +++ b/dumps/scripts/3738.cs2 @@ -0,0 +1,4 @@ +void script_3738() { + script_304(45885335); + return; +} diff --git a/dumps/scripts/3739.cs2 b/dumps/scripts/3739.cs2 new file mode 100644 index 0000000..fd27439 --- /dev/null +++ b/dumps/scripts/3739.cs2 @@ -0,0 +1,4 @@ +void script_3739() { + script_304(41307804); + return; +} diff --git a/dumps/scripts/374.cs2 b/dumps/scripts/374.cs2 new file mode 100644 index 0000000..d6c23de --- /dev/null +++ b/dumps/scripts/374.cs2 @@ -0,0 +1,11 @@ +void script_374(int arg0,int arg1,string arg2) { + createExtraChild(new WidgetPointer(arg0), 4, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(0, 0, 1, 1); + setWidgetPosition(1, 1, 1, 1); + setWidgetFont(3793); + setWidgetRGB(new Color(205, 190, 154)); + setWidgetUnknownBoolean(false); + setWidgetTextAlignment(1, 1, arg1); + setWidgetText(arg2); + return; +} diff --git a/dumps/scripts/3740.cs2 b/dumps/scripts/3740.cs2 new file mode 100644 index 0000000..a70058b --- /dev/null +++ b/dumps/scripts/3740.cs2 @@ -0,0 +1,4 @@ +void script_3740() { + script_304(48909554); + return; +} diff --git a/dumps/scripts/3741.cs2 b/dumps/scripts/3741.cs2 new file mode 100644 index 0000000..882085e --- /dev/null +++ b/dumps/scripts/3741.cs2 @@ -0,0 +1,4 @@ +void script_3741() { + script_304(41651869); + return; +} diff --git a/dumps/scripts/3742.cs2 b/dumps/scripts/3742.cs2 new file mode 100644 index 0000000..f4ce630 --- /dev/null +++ b/dumps/scripts/3742.cs2 @@ -0,0 +1,4 @@ +void script_3742() { + script_304(51285508); + return; +} diff --git a/dumps/scripts/3743.cs2 b/dumps/scripts/3743.cs2 new file mode 100644 index 0000000..0f377e2 --- /dev/null +++ b/dumps/scripts/3743.cs2 @@ -0,0 +1,4 @@ +void script_3743() { + script_304(41061938); + return; +} diff --git a/dumps/scripts/3744.cs2 b/dumps/scripts/3744.cs2 new file mode 100644 index 0000000..4495e13 --- /dev/null +++ b/dumps/scripts/3744.cs2 @@ -0,0 +1,4 @@ +void script_3744() { + script_304(50089438); + return; +} diff --git a/dumps/scripts/3745.cs2 b/dumps/scripts/3745.cs2 new file mode 100644 index 0000000..0d6f014 --- /dev/null +++ b/dumps/scripts/3745.cs2 @@ -0,0 +1,4 @@ +void script_3745() { + script_304(52874276); + return; +} diff --git a/dumps/scripts/3746.cs2 b/dumps/scripts/3746.cs2 new file mode 100644 index 0000000..8ee990a --- /dev/null +++ b/dumps/scripts/3746.cs2 @@ -0,0 +1,4 @@ +void script_3746() { + script_304(51105268); + return; +} diff --git a/dumps/scripts/3747.cs2 b/dumps/scripts/3747.cs2 new file mode 100644 index 0000000..55b5139 --- /dev/null +++ b/dumps/scripts/3747.cs2 @@ -0,0 +1,4 @@ +void script_3747() { + script_304(47254853); + return; +} diff --git a/dumps/scripts/3748.cs2 b/dumps/scripts/3748.cs2 new file mode 100644 index 0000000..dfd95f4 --- /dev/null +++ b/dumps/scripts/3748.cs2 @@ -0,0 +1,4 @@ +void script_3748() { + script_304(52039168); + return; +} diff --git a/dumps/scripts/3749.cs2 b/dumps/scripts/3749.cs2 new file mode 100644 index 0000000..79db3bb --- /dev/null +++ b/dumps/scripts/3749.cs2 @@ -0,0 +1,4 @@ +void script_3749() { + script_304(46566752); + return; +} diff --git a/dumps/scripts/375.cs2 b/dumps/scripts/375.cs2 new file mode 100644 index 0000000..36c6d38 --- /dev/null +++ b/dumps/scripts/375.cs2 @@ -0,0 +1,4 @@ +void script_375(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6) { + script_376(arg0, arg1, arg2, arg3, arg4, arg5, arg6); + return; +} diff --git a/dumps/scripts/3750.cs2 b/dumps/scripts/3750.cs2 new file mode 100644 index 0000000..51d0703 --- /dev/null +++ b/dumps/scripts/3750.cs2 @@ -0,0 +1,4 @@ +void script_3750() { + script_304(51858922); + return; +} diff --git a/dumps/scripts/3751.cs2 b/dumps/scripts/3751.cs2 new file mode 100644 index 0000000..c221620 --- /dev/null +++ b/dumps/scripts/3751.cs2 @@ -0,0 +1,4 @@ +void script_3751() { + script_304(50678936); + return; +} diff --git a/dumps/scripts/3752.cs2 b/dumps/scripts/3752.cs2 new file mode 100644 index 0000000..e49a574 --- /dev/null +++ b/dumps/scripts/3752.cs2 @@ -0,0 +1,4 @@ +void script_3752() { + script_304(50482525); + return; +} diff --git a/dumps/scripts/3753.cs2 b/dumps/scripts/3753.cs2 new file mode 100644 index 0000000..2898b8c --- /dev/null +++ b/dumps/scripts/3753.cs2 @@ -0,0 +1,4 @@ +void script_3753() { + script_304(50597363); + return; +} diff --git a/dumps/scripts/3754.cs2 b/dumps/scripts/3754.cs2 new file mode 100644 index 0000000..c1f8562 --- /dev/null +++ b/dumps/scripts/3754.cs2 @@ -0,0 +1,4 @@ +void script_3754() { + script_304(50744716); + return; +} diff --git a/dumps/scripts/3755.cs2 b/dumps/scripts/3755.cs2 new file mode 100644 index 0000000..417ad54 --- /dev/null +++ b/dumps/scripts/3755.cs2 @@ -0,0 +1,4 @@ +void script_3755() { + script_304(51055996); + return; +} diff --git a/dumps/scripts/3756.cs2 b/dumps/scripts/3756.cs2 new file mode 100644 index 0000000..00eabb2 --- /dev/null +++ b/dumps/scripts/3756.cs2 @@ -0,0 +1,4 @@ +void script_3756() { + script_304(53038466); + return; +} diff --git a/dumps/scripts/3757.cs2 b/dumps/scripts/3757.cs2 new file mode 100644 index 0000000..2490baf --- /dev/null +++ b/dumps/scripts/3757.cs2 @@ -0,0 +1,4 @@ +void script_3757() { + script_304(53153079); + return; +} diff --git a/dumps/scripts/3758.cs2 b/dumps/scripts/3758.cs2 new file mode 100644 index 0000000..2a996c0 --- /dev/null +++ b/dumps/scripts/3758.cs2 @@ -0,0 +1,4 @@ +void script_3758() { + script_304(52268315); + return; +} diff --git a/dumps/scripts/3759.cs2 b/dumps/scripts/3759.cs2 new file mode 100644 index 0000000..a7f8f08 --- /dev/null +++ b/dumps/scripts/3759.cs2 @@ -0,0 +1,4 @@ +void script_3759() { + script_304(50662690); + return; +} diff --git a/dumps/scripts/376.cs2 b/dumps/scripts/376.cs2 new file mode 100644 index 0000000..f8cca22 --- /dev/null +++ b/dumps/scripts/376.cs2 @@ -0,0 +1,66 @@ +void script_376(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6) { + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int stack_dump0; + if (arg1 == -1) { + createExtraChild(new WidgetPointer(arg0), 3, arg6); + setWidgetHidden(1); + createExtraChild(new WidgetPointer(arg0), 3, add(arg6, 1)); + setWidgetHidden(1); + createExtraChild(new WidgetPointer(arg0), 3, add(arg6, 2)); + setWidgetHidden(1); + createExtraChild(new WidgetPointer(arg0), 3, add(arg6, 3)); + setWidgetHidden(1); + createExtraChild(new WidgetPointer(arg0), 3, add(arg6, 4)); + setWidgetHidden(1); + createExtraChild(new WidgetPointer(arg0), 3, add(arg6, 5)); + setWidgetHidden(1); + return; + } + ivar7 = 0; + ivar8 = 0; + ivar9 = 0; + ivar10 = 0; + if (setWidgetRegister(new WidgetPointer(arg1), arg2) || ((arg2 == -1) && setWidgetRegister(new WidgetPointer(arg1)))) { + stack_dump0 = subtract(getWidgetActualX(), arg5); + ivar8 = subtract(getWidgetActualY(), arg5); + ivar7 = stack_dump0; + ivar9 = min(add(getWidgetActualWidth(), multiply(arg5, 2)), getWidgetActualWidth(new WidgetPointer(arg0))); + ivar10 = add(getWidgetActualHeight(), multiply(arg5, 2)); + } else { + return; + } + createExtraChild(new WidgetPointer(arg0), 3, arg6); + setWidgetSize(subtract(ivar9, 2), 2, 0, 0); + setWidgetPosition(add(ivar7, 1), ivar8, 0, 0); + setWidgetFilled(1); + setWidgetRGB(new Color(arg3)); + createExtraChild(new WidgetPointer(arg0), 3, add(arg6, 1)); + setWidgetSize(subtract(ivar9, 2), 2, 0, 0); + setWidgetPosition(add(ivar7, 1), subtract(add(ivar8, ivar10), 2), 0, 0); + setWidgetFilled(1); + setWidgetRGB(new Color(arg4)); + createExtraChild(new WidgetPointer(arg0), 3, add(arg6, 2)); + setWidgetSize(2, subtract(ivar10, 2), 0, 0); + setWidgetPosition(ivar7, add(ivar8, 1), 0, 0); + setWidgetFilled(1); + setWidgetRGB(new Color(arg4)); + createExtraChild(new WidgetPointer(arg0), 3, add(arg6, 3)); + setWidgetSize(2, subtract(ivar10, 2), 0, 0); + setWidgetPosition(subtract(add(ivar7, ivar9), 2), add(ivar8, 1), 0, 0); + setWidgetFilled(1); + setWidgetRGB(new Color(arg4)); + createExtraChild(new WidgetPointer(arg0), 3, add(arg6, 4)); + setWidgetSize(2, divide(subtract(ivar10, 2), 2), 0, 0); + setWidgetPosition(ivar7, add(ivar8, 1), 0, 0); + setWidgetFilled(1); + setWidgetRGB(new Color(arg3)); + createExtraChild(new WidgetPointer(arg0), 3, add(arg6, 5)); + setWidgetSize(2, divide(subtract(ivar10, 2), 2), 0, 0); + setWidgetPosition(subtract(add(ivar7, ivar9), 2), add(ivar8, 1), 0, 0); + setWidgetFilled(1); + setWidgetRGB(new Color(arg3)); + return; +} diff --git a/dumps/scripts/3760.cs2 b/dumps/scripts/3760.cs2 new file mode 100644 index 0000000..ca8d974 --- /dev/null +++ b/dumps/scripts/3760.cs2 @@ -0,0 +1,4 @@ +void script_3760() { + script_304(51039517); + return; +} diff --git a/dumps/scripts/3761.cs2 b/dumps/scripts/3761.cs2 new file mode 100644 index 0000000..a3c2728 --- /dev/null +++ b/dumps/scripts/3761.cs2 @@ -0,0 +1,4 @@ +void script_3761() { + script_304(50531528); + return; +} diff --git a/dumps/scripts/3762.cs2 b/dumps/scripts/3762.cs2 new file mode 100644 index 0000000..c381cd0 --- /dev/null +++ b/dumps/scripts/3762.cs2 @@ -0,0 +1,4 @@ +void script_3762() { + script_304(51088556); + return; +} diff --git a/dumps/scripts/3763.cs2 b/dumps/scripts/3763.cs2 new file mode 100644 index 0000000..0440f1a --- /dev/null +++ b/dumps/scripts/3763.cs2 @@ -0,0 +1,4 @@ +void script_3763() { + script_304(51596469); + return; +} diff --git a/dumps/scripts/3764.cs2 b/dumps/scripts/3764.cs2 new file mode 100644 index 0000000..1b6d565 --- /dev/null +++ b/dumps/scripts/3764.cs2 @@ -0,0 +1,4 @@ +void script_3764() { + script_304(52579472); + return; +} diff --git a/dumps/scripts/3765.cs2 b/dumps/scripts/3765.cs2 new file mode 100644 index 0000000..3548733 --- /dev/null +++ b/dumps/scripts/3765.cs2 @@ -0,0 +1,4 @@ +void script_3765() { + script_304(45028607); + return; +} diff --git a/dumps/scripts/3766.cs2 b/dumps/scripts/3766.cs2 new file mode 100644 index 0000000..2c04707 --- /dev/null +++ b/dumps/scripts/3766.cs2 @@ -0,0 +1,4 @@ +void script_3766() { + script_304(50842728); + return; +} diff --git a/dumps/scripts/3767.cs2 b/dumps/scripts/3767.cs2 new file mode 100644 index 0000000..1bb7f6d --- /dev/null +++ b/dumps/scripts/3767.cs2 @@ -0,0 +1,4 @@ +void script_3767() { + script_304(50417032); + return; +} diff --git a/dumps/scripts/3768.cs2 b/dumps/scripts/3768.cs2 new file mode 100644 index 0000000..a5644f9 --- /dev/null +++ b/dumps/scripts/3768.cs2 @@ -0,0 +1,4 @@ +void script_3768() { + script_304(50367872); + return; +} diff --git a/dumps/scripts/3769.cs2 b/dumps/scripts/3769.cs2 new file mode 100644 index 0000000..09a4f1b --- /dev/null +++ b/dumps/scripts/3769.cs2 @@ -0,0 +1,4 @@ +void script_3769() { + script_304(50548092); + return; +} diff --git a/dumps/scripts/377.cs2 b/dumps/scripts/377.cs2 new file mode 100644 index 0000000..65d1d0d --- /dev/null +++ b/dumps/scripts/377.cs2 @@ -0,0 +1,22 @@ +void script_377(int arg0,int arg1) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + deleteExtraChild(); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(arg1, 1))) { + deleteExtraChild(); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(arg1, 2))) { + deleteExtraChild(); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(arg1, 3))) { + deleteExtraChild(); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(arg1, 4))) { + deleteExtraChild(); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(arg1, 5))) { + deleteExtraChild(); + } + script_383(); + return; +} diff --git a/dumps/scripts/3770.cs2 b/dumps/scripts/3770.cs2 new file mode 100644 index 0000000..9755708 --- /dev/null +++ b/dumps/scripts/3770.cs2 @@ -0,0 +1,4 @@ +void script_3770() { + script_304(46206364); + return; +} diff --git a/dumps/scripts/3771.cs2 b/dumps/scripts/3771.cs2 new file mode 100644 index 0000000..0708ccc --- /dev/null +++ b/dumps/scripts/3771.cs2 @@ -0,0 +1,4 @@ +void script_3771() { + script_304(47140248); + return; +} diff --git a/dumps/scripts/3772.cs2 b/dumps/scripts/3772.cs2 new file mode 100644 index 0000000..2ac5a23 --- /dev/null +++ b/dumps/scripts/3772.cs2 @@ -0,0 +1,4 @@ +void script_3772() { + script_304(47720380); + return; +} diff --git a/dumps/scripts/3773.cs2 b/dumps/scripts/3773.cs2 new file mode 100644 index 0000000..ecbe34f --- /dev/null +++ b/dumps/scripts/3773.cs2 @@ -0,0 +1,4 @@ +void script_3773() { + script_304(47386035); + return; +} diff --git a/dumps/scripts/3774.cs2 b/dumps/scripts/3774.cs2 new file mode 100644 index 0000000..cf7c0f3 --- /dev/null +++ b/dumps/scripts/3774.cs2 @@ -0,0 +1,4 @@ +void script_3774() { + script_304(46566848); + return; +} diff --git a/dumps/scripts/3775.cs2 b/dumps/scripts/3775.cs2 new file mode 100644 index 0000000..f8a3aaa --- /dev/null +++ b/dumps/scripts/3775.cs2 @@ -0,0 +1,4 @@ +void script_3775() { + script_304(48653768); + return; +} diff --git a/dumps/scripts/3776.cs2 b/dumps/scripts/3776.cs2 new file mode 100644 index 0000000..a51d7e0 --- /dev/null +++ b/dumps/scripts/3776.cs2 @@ -0,0 +1,4 @@ +void script_3776() { + script_304(49450762); + return; +} diff --git a/dumps/scripts/3777.cs2 b/dumps/scripts/3777.cs2 new file mode 100644 index 0000000..dbefdc0 --- /dev/null +++ b/dumps/scripts/3777.cs2 @@ -0,0 +1,4 @@ +void script_3777() { + script_304(50286352); + return; +} diff --git a/dumps/scripts/3778.cs2 b/dumps/scripts/3778.cs2 new file mode 100644 index 0000000..c0ea03c --- /dev/null +++ b/dumps/scripts/3778.cs2 @@ -0,0 +1,4 @@ +void script_3778() { + script_304(50630516); + return; +} diff --git a/dumps/scripts/3779.cs2 b/dumps/scripts/3779.cs2 new file mode 100644 index 0000000..8ffbda5 --- /dev/null +++ b/dumps/scripts/3779.cs2 @@ -0,0 +1,4 @@ +void script_3779() { + script_304(49237883); + return; +} diff --git a/dumps/scripts/378.cs2 b/dumps/scripts/378.cs2 new file mode 100644 index 0000000..31b3912 --- /dev/null +++ b/dumps/scripts/378.cs2 @@ -0,0 +1,6 @@ +void script_378(int arg0,int arg1,int arg2,string arg3) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1) || ((arg1 == -1) && setWidgetRegister(new WidgetPointer(arg0)))) { + script_379(script_1743(), getWidgetActualWidth(), script_1744(), arg2, arg3); + } + return; +} diff --git a/dumps/scripts/3780.cs2 b/dumps/scripts/3780.cs2 new file mode 100644 index 0000000..7b88eca --- /dev/null +++ b/dumps/scripts/3780.cs2 @@ -0,0 +1,4 @@ +void script_3780() { + script_304(49893206); + return; +} diff --git a/dumps/scripts/3781.cs2 b/dumps/scripts/3781.cs2 new file mode 100644 index 0000000..f7da7f2 --- /dev/null +++ b/dumps/scripts/3781.cs2 @@ -0,0 +1,4 @@ +void script_3781() { + script_304(54371714); + return; +} diff --git a/dumps/scripts/3782.cs2 b/dumps/scripts/3782.cs2 new file mode 100644 index 0000000..cec41a2 --- /dev/null +++ b/dumps/scripts/3782.cs2 @@ -0,0 +1,4 @@ +void script_3782() { + script_304(42093619); + return; +} diff --git a/dumps/scripts/3783.cs2 b/dumps/scripts/3783.cs2 new file mode 100644 index 0000000..e7fa79e --- /dev/null +++ b/dumps/scripts/3783.cs2 @@ -0,0 +1,4 @@ +void script_3783() { + script_304(42650630); + return; +} diff --git a/dumps/scripts/3784.cs2 b/dumps/scripts/3784.cs2 new file mode 100644 index 0000000..1a3d5ee --- /dev/null +++ b/dumps/scripts/3784.cs2 @@ -0,0 +1,4 @@ +void script_3784() { + script_304(45813279); + return; +} diff --git a/dumps/scripts/3785.cs2 b/dumps/scripts/3785.cs2 new file mode 100644 index 0000000..b2feda0 --- /dev/null +++ b/dumps/scripts/3785.cs2 @@ -0,0 +1,4 @@ +void script_3785() { + script_304(60313041); + return; +} diff --git a/dumps/scripts/3786.cs2 b/dumps/scripts/3786.cs2 new file mode 100644 index 0000000..d17f832 --- /dev/null +++ b/dumps/scripts/3786.cs2 @@ -0,0 +1,4 @@ +void script_3786(int arg0,int arg1) { + script_311(arg0, arg1, "Stagnant water"); + return; +} diff --git a/dumps/scripts/3787.cs2 b/dumps/scripts/3787.cs2 new file mode 100644 index 0000000..8a762d9 --- /dev/null +++ b/dumps/scripts/3787.cs2 @@ -0,0 +1,4 @@ +void script_3787(int arg0,int arg1) { + script_311(arg0, arg1, "Stonemason"); + return; +} diff --git a/dumps/scripts/3788.cs2 b/dumps/scripts/3788.cs2 new file mode 100644 index 0000000..dc61291 --- /dev/null +++ b/dumps/scripts/3788.cs2 @@ -0,0 +1,4 @@ +void script_3788(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(410, 596)); + return; +} diff --git a/dumps/scripts/3789.cs2 b/dumps/scripts/3789.cs2 new file mode 100644 index 0000000..2e5844a --- /dev/null +++ b/dumps/scripts/3789.cs2 @@ -0,0 +1,4 @@ +void script_3789(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(411, 596)); + return; +} diff --git a/dumps/scripts/379.cs2 b/dumps/scripts/379.cs2 new file mode 100644 index 0000000..e9f6c64 --- /dev/null +++ b/dumps/scripts/379.cs2 @@ -0,0 +1,110 @@ +void script_379(int arg0,int arg1,int arg2,int arg3,string arg4) { + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int stack_dump0; + ivar4 = add(getClientCycle(), 25); + if (globalint_1 < ivar4) { + globalint_1 = max(getClientCycle(), add(globalint_1, 2)); + return; + } + globalint_1 = ivar4; + arg3 = max(min(arg3, arg1), 0); + stack_dump0 = arg0; + globalint_773 = arg1; + globalint_2 = stack_dump0; + ivar5 = 0; + if (isWidgetHidden(new WidgetPointer(1028,125))) { + setWidgetPosition(getWidgetActualX(new WidgetPointer(1028,125)), max(subtract(arg2, getWidgetActualHeight(new WidgetPointer(1028,125))), 0), 0, 0, new WidgetPointer(1028,125)); + if (setWidgetRegister(new WidgetPointer(1028,125), 9)) { + ivar5 = subtract(add(arg0, arg3), add(script_3365(67371133), divide(getWidgetActualWidth(), 2))); + setWidgetPosition(min(max(ivar5, 5), subtract(getWidgetActualWidth(new WidgetPointer(1028,125)), add(getWidgetActualWidth(), 5))), 0, 0, 2); + } + return; + } + setWidgetIsHidden(false, new WidgetPointer(1028,125)); + deleteAllExtraChilds(new WidgetPointer(1028,125)); + ivar6 = getMaxLineWidth(getWidgetActualWidth(new WidgetPointer(1028,29)), 495, arg4); + ivar7 = add(multiply(getLineCount(ivar6, 495, arg4), 12), 3); + ivar8 = max(add(ivar6, 8), 45); + ivar9 = add(ivar7, 18); + ivar10 = max(subtract(ivar8, 14), 0); + ivar11 = max(subtract(ivar9, 25), 0); + setWidgetSize(ivar8, ivar9, 0, 0, new WidgetPointer(1028,125)); + createExtraChild(new WidgetPointer(1028,125), 3, getExtraChildGap(new WidgetPointer(1028,125))); + setWidgetSize(ivar10, ivar11, 0, 0); + setWidgetPosition(0, 7, 1, 0); + setWidgetFilled(1); + setWidgetRGB(new Color(227, 226, 225)); + createExtraChild(new WidgetPointer(1028,125), 5, getExtraChildGap(new WidgetPointer(1028,125))); + setWidgetSize(ivar10, 7, 0, 0); + setWidgetPosition(0, 0, 1, 0); + cs2method1107(1); + setWidgetSprite(3476); + createExtraChild(new WidgetPointer(1028,125), 5, getExtraChildGap(new WidgetPointer(1028,125))); + setWidgetSize(ivar10, 7, 0, 0); + setWidgetPosition(0, 11, 1, 2); + cs2method1107(1); + setWidgetVFlip(1); + setWidgetSprite(3476); + createExtraChild(new WidgetPointer(1028,125), 5, getExtraChildGap(new WidgetPointer(1028,125))); + setWidgetSize(7, ivar11, 0, 0); + setWidgetPosition(0, 7, 0, 0); + cs2method1107(1); + setWidgetSprite(3475); + createExtraChild(new WidgetPointer(1028,125), 5, getExtraChildGap(new WidgetPointer(1028,125))); + setWidgetSize(7, ivar11, 0, 0); + setWidgetPosition(0, 7, 2, 0); + cs2method1107(1); + setWidgetHFlip(1); + setWidgetSprite(3475); + createExtraChild(new WidgetPointer(1028,125), 5, getExtraChildGap(new WidgetPointer(1028,125))); + setWidgetSize(7, 7, 0, 0); + setWidgetPosition(0, 0, 0, 0); + setWidgetSprite(3474); + createExtraChild(new WidgetPointer(1028,125), 5, getExtraChildGap(new WidgetPointer(1028,125))); + setWidgetSize(7, 7, 0, 0); + setWidgetPosition(0, 0, 2, 0); + setWidgetHFlip(1); + setWidgetSprite(3474); + createExtraChild(new WidgetPointer(1028,125), 5, getExtraChildGap(new WidgetPointer(1028,125))); + setWidgetSize(7, 7, 0, 0); + setWidgetPosition(0, 11, 0, 2); + setWidgetVFlip(1); + setWidgetSprite(3474); + createExtraChild(new WidgetPointer(1028,125), 5, getExtraChildGap(new WidgetPointer(1028,125))); + setWidgetSize(7, 7, 0, 0); + setWidgetPosition(0, 11, 2, 2); + setWidgetHFlip(1); + setWidgetVFlip(1); + setWidgetSprite(3474); + createExtraChild(new WidgetPointer(1028,125), 5, getExtraChildGap(new WidgetPointer(1028,125))); + setWidgetSize(11, 12, 0, 0); + setWidgetSprite(3473); + createExtraChild(new WidgetPointer(1028,125), 4, getExtraChildGap(new WidgetPointer(1028,125))); + setWidgetSize(ivar6, ivar7, 0, 0); + setWidgetPosition(0, 3, 1, 0); + setWidgetRGB(new Color(0, 0, 0)); + setWidgetFont(3793); + setWidgetTextAlignment(1, 0, 0); + setWidgetText(arg4); + ivar10 = divide(ivar8, 2); + ivar5 = subtract(add(arg0, arg3), ivar10); + ivar12 = 0; + if (ivar5 < 0) { + ivar12 = subtract(0, ivar5); + } else { + if (add(ivar5, ivar8) > getWidgetActualWidth(new WidgetPointer(1028,28))) { + ivar12 = subtract(getWidgetActualWidth(new WidgetPointer(1028,28)), add(ivar5, ivar8)); + } + } + setWidgetPosition(add(ivar5, ivar12), max(subtract(arg2, ivar9), 0), 0, 0, new WidgetPointer(1028,125)); + setWidgetPosition(subtract(0, ivar12), 0, 1, 2); + return; +} diff --git a/dumps/scripts/3790.cs2 b/dumps/scripts/3790.cs2 new file mode 100644 index 0000000..2cf390b --- /dev/null +++ b/dumps/scripts/3790.cs2 @@ -0,0 +1,4 @@ +void script_3790(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(412, 596)); + return; +} diff --git a/dumps/scripts/3791.cs2 b/dumps/scripts/3791.cs2 new file mode 100644 index 0000000..1815f38 --- /dev/null +++ b/dumps/scripts/3791.cs2 @@ -0,0 +1,4 @@ +void script_3791(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(413, 596)); + return; +} diff --git a/dumps/scripts/3792.cs2 b/dumps/scripts/3792.cs2 new file mode 100644 index 0000000..57fc026 --- /dev/null +++ b/dumps/scripts/3792.cs2 @@ -0,0 +1,4 @@ +void script_3792(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(414, 596)); + return; +} diff --git a/dumps/scripts/3793.cs2 b/dumps/scripts/3793.cs2 new file mode 100644 index 0000000..2c5ec9c --- /dev/null +++ b/dumps/scripts/3793.cs2 @@ -0,0 +1,4 @@ +void script_3793(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(415, 596)); + return; +} diff --git a/dumps/scripts/3794.cs2 b/dumps/scripts/3794.cs2 new file mode 100644 index 0000000..c83b710 --- /dev/null +++ b/dumps/scripts/3794.cs2 @@ -0,0 +1,4 @@ +void script_3794(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(416, 596)); + return; +} diff --git a/dumps/scripts/3795.cs2 b/dumps/scripts/3795.cs2 new file mode 100644 index 0000000..e270dcf --- /dev/null +++ b/dumps/scripts/3795.cs2 @@ -0,0 +1,4 @@ +void script_3795(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(418, 596)); + return; +} diff --git a/dumps/scripts/3796.cs2 b/dumps/scripts/3796.cs2 new file mode 100644 index 0000000..4b73fb7 --- /dev/null +++ b/dumps/scripts/3796.cs2 @@ -0,0 +1,4 @@ +void script_3796(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(419, 596)); + return; +} diff --git a/dumps/scripts/3797.cs2 b/dumps/scripts/3797.cs2 new file mode 100644 index 0000000..6cad70c --- /dev/null +++ b/dumps/scripts/3797.cs2 @@ -0,0 +1,4 @@ +void script_3797(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(420, 596)); + return; +} diff --git a/dumps/scripts/3798.cs2 b/dumps/scripts/3798.cs2 new file mode 100644 index 0000000..567b3c0 --- /dev/null +++ b/dumps/scripts/3798.cs2 @@ -0,0 +1,4 @@ +void script_3798(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(421, 596)); + return; +} diff --git a/dumps/scripts/3799.cs2 b/dumps/scripts/3799.cs2 new file mode 100644 index 0000000..1bbc9b3 --- /dev/null +++ b/dumps/scripts/3799.cs2 @@ -0,0 +1,4 @@ +void script_3799(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(422, 596)); + return; +} diff --git a/dumps/scripts/38.cs2 b/dumps/scripts/38.cs2 new file mode 100644 index 0000000..e8a0376 --- /dev/null +++ b/dumps/scripts/38.cs2 @@ -0,0 +1,4 @@ +void script_38(int arg0,int arg1,int arg2,int arg3,string arg4) { + script_569(arg0, -1, arg1, arg2, arg3, arg4); + return; +} diff --git a/dumps/scripts/380.cs2 b/dumps/scripts/380.cs2 new file mode 100644 index 0000000..efddc13 --- /dev/null +++ b/dumps/scripts/380.cs2 @@ -0,0 +1,4 @@ +void script_380() { + script_304(40637496); + return; +} diff --git a/dumps/scripts/3800.cs2 b/dumps/scripts/3800.cs2 new file mode 100644 index 0000000..30cca26 --- /dev/null +++ b/dumps/scripts/3800.cs2 @@ -0,0 +1,4 @@ +void script_3800(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(423, 596)); + return; +} diff --git a/dumps/scripts/3801.cs2 b/dumps/scripts/3801.cs2 new file mode 100644 index 0000000..63928f6 --- /dev/null +++ b/dumps/scripts/3801.cs2 @@ -0,0 +1,4 @@ +void script_3801(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(424, 596)); + return; +} diff --git a/dumps/scripts/3802.cs2 b/dumps/scripts/3802.cs2 new file mode 100644 index 0000000..12198c0 --- /dev/null +++ b/dumps/scripts/3802.cs2 @@ -0,0 +1,4 @@ +void script_3802(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(425, 596)); + return; +} diff --git a/dumps/scripts/3803.cs2 b/dumps/scripts/3803.cs2 new file mode 100644 index 0000000..408900d --- /dev/null +++ b/dumps/scripts/3803.cs2 @@ -0,0 +1,4 @@ +void script_3803(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(426, 596)); + return; +} diff --git a/dumps/scripts/3804.cs2 b/dumps/scripts/3804.cs2 new file mode 100644 index 0000000..c31472e --- /dev/null +++ b/dumps/scripts/3804.cs2 @@ -0,0 +1,4 @@ +void script_3804(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(427, 596)); + return; +} diff --git a/dumps/scripts/3805.cs2 b/dumps/scripts/3805.cs2 new file mode 100644 index 0000000..5ed714c --- /dev/null +++ b/dumps/scripts/3805.cs2 @@ -0,0 +1,4 @@ +void script_3805(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(428, 596)); + return; +} diff --git a/dumps/scripts/3806.cs2 b/dumps/scripts/3806.cs2 new file mode 100644 index 0000000..0808f91 --- /dev/null +++ b/dumps/scripts/3806.cs2 @@ -0,0 +1,4 @@ +void script_3806(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(429, 596)); + return; +} diff --git a/dumps/scripts/3807.cs2 b/dumps/scripts/3807.cs2 new file mode 100644 index 0000000..9e7ba02 --- /dev/null +++ b/dumps/scripts/3807.cs2 @@ -0,0 +1,4 @@ +void script_3807(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(430, 596)); + return; +} diff --git a/dumps/scripts/3808.cs2 b/dumps/scripts/3808.cs2 new file mode 100644 index 0000000..b6c378f --- /dev/null +++ b/dumps/scripts/3808.cs2 @@ -0,0 +1,4 @@ +void script_3808(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(431, 596)); + return; +} diff --git a/dumps/scripts/3809.cs2 b/dumps/scripts/3809.cs2 new file mode 100644 index 0000000..dc4b878 --- /dev/null +++ b/dumps/scripts/3809.cs2 @@ -0,0 +1,4 @@ +void script_3809(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(432, 596)); + return; +} diff --git a/dumps/scripts/381.cs2 b/dumps/scripts/381.cs2 new file mode 100644 index 0000000..7930034 --- /dev/null +++ b/dumps/scripts/381.cs2 @@ -0,0 +1,100 @@ +void script_381(int arg0,int arg1,int arg2,string arg3) { + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int stack_dump0; + ivar3 = add(getClientCycle(), 25); + if (globalint_1 < ivar3) { + globalint_1 = max(getClientCycle(), add(globalint_1, 2)); + return; + } + globalint_1 = ivar3; + if (isWidgetHidden(new WidgetPointer(1028,125))) { + return; + } + ivar4 = 0; + if (setWidgetRegister(new WidgetPointer(arg0), arg1) || ((arg1 == -1) && setWidgetRegister(new WidgetPointer(arg0)))) { + stack_dump0 = script_1743(); + globalint_773 = getWidgetActualWidth(); + globalint_2 = stack_dump0; + arg2 = max(min(arg2, getWidgetActualHeight()), 0); + ivar4 = add(script_1744(), arg2); + } else { + return; + } + setWidgetIsHidden(false, new WidgetPointer(1028,125)); + deleteAllExtraChilds(new WidgetPointer(1028,125)); + ivar5 = getMaxLineWidth(getWidgetActualWidth(new WidgetPointer(1028,29)), 495, arg3); + ivar6 = add(multiply(getLineCount(ivar5, 495, arg3), 12), 5); + ivar7 = add(ivar5, 19); + ivar8 = max(add(ivar6, 8), 17); + ivar9 = max(subtract(ivar7, 25), 0); + ivar10 = max(subtract(ivar8, 14), 0); + setWidgetSize(ivar7, ivar8, 0, 0, new WidgetPointer(1028,125)); + setWidgetPosition(subtract(globalint_2, ivar7), subtract(ivar4, divide(ivar8, 2)), 0, 0, new WidgetPointer(1028,125)); + createExtraChild(new WidgetPointer(1028,125), 3, getExtraChildGap(new WidgetPointer(1028,125))); + setWidgetSize(ivar9, ivar10, 0, 0); + setWidgetPosition(7, 0, 0, 1); + setWidgetFilled(1); + setWidgetRGB(new Color(227, 226, 225)); + createExtraChild(new WidgetPointer(1028,125), 5, getExtraChildGap(new WidgetPointer(1028,125))); + setWidgetSize(ivar9, 7, 0, 0); + setWidgetPosition(7, 0, 0, 0); + cs2method1107(1); + setWidgetSprite(3476); + createExtraChild(new WidgetPointer(1028,125), 5, getExtraChildGap(new WidgetPointer(1028,125))); + setWidgetSize(ivar9, 7, 0, 0); + setWidgetPosition(7, 0, 0, 2); + cs2method1107(1); + setWidgetVFlip(1); + setWidgetSprite(3476); + createExtraChild(new WidgetPointer(1028,125), 5, getExtraChildGap(new WidgetPointer(1028,125))); + setWidgetSize(7, ivar10, 0, 0); + setWidgetPosition(0, 0, 0, 1); + cs2method1107(1); + setWidgetSprite(3475); + createExtraChild(new WidgetPointer(1028,125), 5, getExtraChildGap(new WidgetPointer(1028,125))); + setWidgetSize(7, ivar10, 0, 0); + setWidgetPosition(12, 0, 2, 1); + cs2method1107(1); + setWidgetHFlip(1); + setWidgetSprite(3475); + createExtraChild(new WidgetPointer(1028,125), 5, getExtraChildGap(new WidgetPointer(1028,125))); + setWidgetSize(7, 7, 0, 0); + setWidgetPosition(0, 0, 0, 0); + setWidgetSprite(3474); + createExtraChild(new WidgetPointer(1028,125), 5, getExtraChildGap(new WidgetPointer(1028,125))); + setWidgetSize(7, 7, 0, 0); + setWidgetPosition(12, 0, 2, 0); + setWidgetHFlip(1); + setWidgetSprite(3474); + createExtraChild(new WidgetPointer(1028,125), 5, getExtraChildGap(new WidgetPointer(1028,125))); + setWidgetSize(7, 7, 0, 0); + setWidgetPosition(0, 0, 0, 2); + setWidgetVFlip(1); + setWidgetSprite(3474); + createExtraChild(new WidgetPointer(1028,125), 5, getExtraChildGap(new WidgetPointer(1028,125))); + setWidgetSize(7, 7, 0, 0); + setWidgetPosition(12, 0, 2, 2); + setWidgetHFlip(1); + setWidgetVFlip(1); + setWidgetSprite(3474); + createExtraChild(new WidgetPointer(1028,125), 5, getExtraChildGap(new WidgetPointer(1028,125))); + setWidgetSize(12, 11, 0, 0); + setWidgetPosition(0, 0, 2, 1); + setWidgetSprite(3473); + cs2method1106(16384); + createExtraChild(new WidgetPointer(1028,125), 4, getExtraChildGap(new WidgetPointer(1028,125))); + setWidgetSize(ivar5, ivar6, 0, 0); + setWidgetPosition(3, 0, 0, 1); + setWidgetRGB(new Color(0, 0, 0)); + setWidgetFont(3793); + setWidgetTextAlignment(1, 0, 0); + setWidgetText(arg3); + return; +} diff --git a/dumps/scripts/3810.cs2 b/dumps/scripts/3810.cs2 new file mode 100644 index 0000000..6606968 --- /dev/null +++ b/dumps/scripts/3810.cs2 @@ -0,0 +1,4 @@ +void script_3810(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(433, 596)); + return; +} diff --git a/dumps/scripts/3811.cs2 b/dumps/scripts/3811.cs2 new file mode 100644 index 0000000..5c6bb97 --- /dev/null +++ b/dumps/scripts/3811.cs2 @@ -0,0 +1,4 @@ +void script_3811(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(434, 596)); + return; +} diff --git a/dumps/scripts/3812.cs2 b/dumps/scripts/3812.cs2 new file mode 100644 index 0000000..8818f0b --- /dev/null +++ b/dumps/scripts/3812.cs2 @@ -0,0 +1,4 @@ +void script_3812(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(435, 596)); + return; +} diff --git a/dumps/scripts/3813.cs2 b/dumps/scripts/3813.cs2 new file mode 100644 index 0000000..18db6b9 --- /dev/null +++ b/dumps/scripts/3813.cs2 @@ -0,0 +1,4 @@ +void script_3813(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(436, 596)); + return; +} diff --git a/dumps/scripts/3814.cs2 b/dumps/scripts/3814.cs2 new file mode 100644 index 0000000..aef0d8e --- /dev/null +++ b/dumps/scripts/3814.cs2 @@ -0,0 +1,4 @@ +void script_3814(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(437, 596)); + return; +} diff --git a/dumps/scripts/3815.cs2 b/dumps/scripts/3815.cs2 new file mode 100644 index 0000000..ecba47e --- /dev/null +++ b/dumps/scripts/3815.cs2 @@ -0,0 +1,4 @@ +void script_3815(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(438, 596)); + return; +} diff --git a/dumps/scripts/3816.cs2 b/dumps/scripts/3816.cs2 new file mode 100644 index 0000000..cf3e8ec --- /dev/null +++ b/dumps/scripts/3816.cs2 @@ -0,0 +1,4 @@ +void script_3816(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(439, 596)); + return; +} diff --git a/dumps/scripts/3817.cs2 b/dumps/scripts/3817.cs2 new file mode 100644 index 0000000..86c514b --- /dev/null +++ b/dumps/scripts/3817.cs2 @@ -0,0 +1,4 @@ +void script_3817(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(440, 596)); + return; +} diff --git a/dumps/scripts/3818.cs2 b/dumps/scripts/3818.cs2 new file mode 100644 index 0000000..158a273 --- /dev/null +++ b/dumps/scripts/3818.cs2 @@ -0,0 +1,4 @@ +void script_3818(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(441, 596)); + return; +} diff --git a/dumps/scripts/3819.cs2 b/dumps/scripts/3819.cs2 new file mode 100644 index 0000000..a05b5f7 --- /dev/null +++ b/dumps/scripts/3819.cs2 @@ -0,0 +1,4 @@ +void script_3819(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(442, 596)); + return; +} diff --git a/dumps/scripts/382.cs2 b/dumps/scripts/382.cs2 new file mode 100644 index 0000000..5ab8046 --- /dev/null +++ b/dumps/scripts/382.cs2 @@ -0,0 +1,4 @@ +void script_382() { + script_383(); + return; +} diff --git a/dumps/scripts/3820.cs2 b/dumps/scripts/3820.cs2 new file mode 100644 index 0000000..b1ef935 --- /dev/null +++ b/dumps/scripts/3820.cs2 @@ -0,0 +1,4 @@ +void script_3820(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(443, 596)); + return; +} diff --git a/dumps/scripts/3821.cs2 b/dumps/scripts/3821.cs2 new file mode 100644 index 0000000..d2511d8 --- /dev/null +++ b/dumps/scripts/3821.cs2 @@ -0,0 +1,4 @@ +void script_3821(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(444, 596)); + return; +} diff --git a/dumps/scripts/3822.cs2 b/dumps/scripts/3822.cs2 new file mode 100644 index 0000000..93a4584 --- /dev/null +++ b/dumps/scripts/3822.cs2 @@ -0,0 +1,4 @@ +void script_3822(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(445, 596)); + return; +} diff --git a/dumps/scripts/3823.cs2 b/dumps/scripts/3823.cs2 new file mode 100644 index 0000000..8550390 --- /dev/null +++ b/dumps/scripts/3823.cs2 @@ -0,0 +1,4 @@ +void script_3823(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(446, 596)); + return; +} diff --git a/dumps/scripts/3824.cs2 b/dumps/scripts/3824.cs2 new file mode 100644 index 0000000..3cf8dcf --- /dev/null +++ b/dumps/scripts/3824.cs2 @@ -0,0 +1,4 @@ +void script_3824(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(447, 596)); + return; +} diff --git a/dumps/scripts/3825.cs2 b/dumps/scripts/3825.cs2 new file mode 100644 index 0000000..2cb8062 --- /dev/null +++ b/dumps/scripts/3825.cs2 @@ -0,0 +1,4 @@ +void script_3825(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(448, 596)); + return; +} diff --git a/dumps/scripts/3826.cs2 b/dumps/scripts/3826.cs2 new file mode 100644 index 0000000..e9bceb0 --- /dev/null +++ b/dumps/scripts/3826.cs2 @@ -0,0 +1,4 @@ +void script_3826(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(449, 596)); + return; +} diff --git a/dumps/scripts/3827.cs2 b/dumps/scripts/3827.cs2 new file mode 100644 index 0000000..8f1c8c1 --- /dev/null +++ b/dumps/scripts/3827.cs2 @@ -0,0 +1,4 @@ +void script_3827(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(450, 596)); + return; +} diff --git a/dumps/scripts/3828.cs2 b/dumps/scripts/3828.cs2 new file mode 100644 index 0000000..cfc93e3 --- /dev/null +++ b/dumps/scripts/3828.cs2 @@ -0,0 +1,4 @@ +void script_3828(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(451, 596)); + return; +} diff --git a/dumps/scripts/3829.cs2 b/dumps/scripts/3829.cs2 new file mode 100644 index 0000000..38b40fc --- /dev/null +++ b/dumps/scripts/3829.cs2 @@ -0,0 +1,4 @@ +void script_3829(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(452, 596)); + return; +} diff --git a/dumps/scripts/383.cs2 b/dumps/scripts/383.cs2 new file mode 100644 index 0000000..bb45b3c --- /dev/null +++ b/dumps/scripts/383.cs2 @@ -0,0 +1,9 @@ +void script_383() { + int stack_dump0; + deleteAllExtraChilds(new WidgetPointer(1028,125)); + setWidgetIsHidden(true, new WidgetPointer(1028,125)); + stack_dump0 = -1; + globalint_773 = -1; + globalint_2 = stack_dump0; + return; +} diff --git a/dumps/scripts/3830.cs2 b/dumps/scripts/3830.cs2 new file mode 100644 index 0000000..2d1f9cc --- /dev/null +++ b/dumps/scripts/3830.cs2 @@ -0,0 +1,4 @@ +void script_3830(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(453, 596)); + return; +} diff --git a/dumps/scripts/3831.cs2 b/dumps/scripts/3831.cs2 new file mode 100644 index 0000000..4902be3 --- /dev/null +++ b/dumps/scripts/3831.cs2 @@ -0,0 +1,4 @@ +void script_3831(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(454, 596)); + return; +} diff --git a/dumps/scripts/3832.cs2 b/dumps/scripts/3832.cs2 new file mode 100644 index 0000000..36c6f13 --- /dev/null +++ b/dumps/scripts/3832.cs2 @@ -0,0 +1,4 @@ +void script_3832(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(455, 596)); + return; +} diff --git a/dumps/scripts/3833.cs2 b/dumps/scripts/3833.cs2 new file mode 100644 index 0000000..89b0662 --- /dev/null +++ b/dumps/scripts/3833.cs2 @@ -0,0 +1,4 @@ +void script_3833(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(456, 596)); + return; +} diff --git a/dumps/scripts/3834.cs2 b/dumps/scripts/3834.cs2 new file mode 100644 index 0000000..98bc53e --- /dev/null +++ b/dumps/scripts/3834.cs2 @@ -0,0 +1,4 @@ +void script_3834(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(457, 596)); + return; +} diff --git a/dumps/scripts/3835.cs2 b/dumps/scripts/3835.cs2 new file mode 100644 index 0000000..6c056d1 --- /dev/null +++ b/dumps/scripts/3835.cs2 @@ -0,0 +1,4 @@ +void script_3835(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(459, 596)); + return; +} diff --git a/dumps/scripts/3836.cs2 b/dumps/scripts/3836.cs2 new file mode 100644 index 0000000..be20f23 --- /dev/null +++ b/dumps/scripts/3836.cs2 @@ -0,0 +1,4 @@ +void script_3836(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(460, 596)); + return; +} diff --git a/dumps/scripts/3837.cs2 b/dumps/scripts/3837.cs2 new file mode 100644 index 0000000..0f30111 --- /dev/null +++ b/dumps/scripts/3837.cs2 @@ -0,0 +1,4 @@ +void script_3837(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(458, 596)); + return; +} diff --git a/dumps/scripts/3838.cs2 b/dumps/scripts/3838.cs2 new file mode 100644 index 0000000..238dd9e --- /dev/null +++ b/dumps/scripts/3838.cs2 @@ -0,0 +1,4 @@ +void script_3838(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(461, 596)); + return; +} diff --git a/dumps/scripts/3839.cs2 b/dumps/scripts/3839.cs2 new file mode 100644 index 0000000..46fb3a5 --- /dev/null +++ b/dumps/scripts/3839.cs2 @@ -0,0 +1,4 @@ +void script_3839(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(463, 596)); + return; +} diff --git a/dumps/scripts/384.cs2 b/dumps/scripts/384.cs2 new file mode 100644 index 0000000..babaad7 --- /dev/null +++ b/dumps/scripts/384.cs2 @@ -0,0 +1,35 @@ +int script_384(int arg0,int arg1,int arg2) { + switch (arg0) { + case 0: + if (((boolean)arg2)) { + return getOtherCommonData(arg1, 1175); + } + return getOtherCommonData(arg1, 1169); + case 1: + if (((boolean)arg2)) { + return getOtherCommonData(arg1, 1176); + } + return getOtherCommonData(arg1, 1170); + case 2: + if (((boolean)arg2)) { + return getOtherCommonData(arg1, 1177); + } + return getOtherCommonData(arg1, 1171); + case 3: + if (((boolean)arg2)) { + return getOtherCommonData(arg1, 1178); + } + return getOtherCommonData(arg1, 1172); + case 4: + if (((boolean)arg2)) { + return getOtherCommonData(arg1, 1179); + } + return getOtherCommonData(arg1, 1173); + case 5: + if (((boolean)arg2)) { + return getOtherCommonData(arg1, 1180); + } + return getOtherCommonData(arg1, 1174); + } + return -1; +} diff --git a/dumps/scripts/3840.cs2 b/dumps/scripts/3840.cs2 new file mode 100644 index 0000000..2b7c8c8 --- /dev/null +++ b/dumps/scripts/3840.cs2 @@ -0,0 +1,4 @@ +void script_3840(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(464, 596)); + return; +} diff --git a/dumps/scripts/3841.cs2 b/dumps/scripts/3841.cs2 new file mode 100644 index 0000000..c7accdd --- /dev/null +++ b/dumps/scripts/3841.cs2 @@ -0,0 +1,4 @@ +void script_3841(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(465, 596)); + return; +} diff --git a/dumps/scripts/3842.cs2 b/dumps/scripts/3842.cs2 new file mode 100644 index 0000000..d361b45 --- /dev/null +++ b/dumps/scripts/3842.cs2 @@ -0,0 +1,4 @@ +void script_3842(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(466, 596)); + return; +} diff --git a/dumps/scripts/3843.cs2 b/dumps/scripts/3843.cs2 new file mode 100644 index 0000000..fbb4db7 --- /dev/null +++ b/dumps/scripts/3843.cs2 @@ -0,0 +1,4 @@ +void script_3843(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(467, 596)); + return; +} diff --git a/dumps/scripts/3844.cs2 b/dumps/scripts/3844.cs2 new file mode 100644 index 0000000..4ab6b04 --- /dev/null +++ b/dumps/scripts/3844.cs2 @@ -0,0 +1,4 @@ +void script_3844(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(468, 596)); + return; +} diff --git a/dumps/scripts/3845.cs2 b/dumps/scripts/3845.cs2 new file mode 100644 index 0000000..d6cb75b --- /dev/null +++ b/dumps/scripts/3845.cs2 @@ -0,0 +1,4 @@ +void script_3845(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(460, 596)); + return; +} diff --git a/dumps/scripts/3846.cs2 b/dumps/scripts/3846.cs2 new file mode 100644 index 0000000..52d7bd9 --- /dev/null +++ b/dumps/scripts/3846.cs2 @@ -0,0 +1,4 @@ +void script_3846(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(462, 596)); + return; +} diff --git a/dumps/scripts/3847.cs2 b/dumps/scripts/3847.cs2 new file mode 100644 index 0000000..80d66f6 --- /dev/null +++ b/dumps/scripts/3847.cs2 @@ -0,0 +1,4 @@ +void script_3847(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(469, 596)); + return; +} diff --git a/dumps/scripts/3848.cs2 b/dumps/scripts/3848.cs2 new file mode 100644 index 0000000..400d212 --- /dev/null +++ b/dumps/scripts/3848.cs2 @@ -0,0 +1,4 @@ +void script_3848() { + script_304(59823106); + return; +} diff --git a/dumps/scripts/3849.cs2 b/dumps/scripts/3849.cs2 new file mode 100644 index 0000000..6b49614 --- /dev/null +++ b/dumps/scripts/3849.cs2 @@ -0,0 +1,4 @@ +void script_3849() { + script_304(49374823); + return; +} diff --git a/dumps/scripts/385.cs2 b/dumps/scripts/385.cs2 new file mode 100644 index 0000000..2049b7a --- /dev/null +++ b/dumps/scripts/385.cs2 @@ -0,0 +1,119 @@ +void script_385(int arg0) { + flow_0: + if ((arg0 == globalint_543) && (arg0 != -1)) { + return; + } + globalint_543 = arg0; + SWITCH (arg0) { + case 1112: + GOTO flow_4 + case 1118: + GOTO flow_5 + case 1120: + GOTO flow_6 + case 1127: + GOTO flow_7 + case 1125: + GOTO flow_8 + case 1122: + GOTO flow_9 + case 1128: + GOTO flow_10 + case 1129: + GOTO flow_11 + case 1119: + GOTO flow_12 + case 1114: + GOTO flow_13 + case 1124: + GOTO flow_14 + case 1121: + GOTO flow_15 + case 1115: + GOTO flow_16 + case 1130: + GOTO flow_17 + case 1116: + GOTO flow_18 + case 1126: + GOTO flow_19 + case 1131: + GOTO flow_20 + case 1117: + GOTO flow_21 + case 1113: + GOTO flow_22 + case 1123: + GOTO flow_23 + case -1: + GOTO flow_25 + } + GOTO flow_24 + flow_4: + openInterface(67371042, 1033); + GOTO flow_26 + flow_5: + openInterface(67371042, 1043); + GOTO flow_26 + flow_6: + openInterface(67371042, 1032); + GOTO flow_26 + flow_7: + openInterface(67371042, 1038); + GOTO flow_26 + flow_8: + openInterface(67371042, 1034); + GOTO flow_26 + flow_9: + openInterface(67371042, 1036); + GOTO flow_26 + flow_10: + openInterface(67371042, 1044); + GOTO flow_26 + flow_11: + openInterface(67371042, 1042); + GOTO flow_26 + flow_12: + openInterface(67371042, 1041); + GOTO flow_26 + flow_13: + openInterface(67371042, 1029); + GOTO flow_26 + flow_14: + openInterface(67371042, 1030); + GOTO flow_26 + flow_15: + openInterface(67371042, 1031); + GOTO flow_26 + flow_16: + openInterface(67371042, 1046); + GOTO flow_26 + flow_17: + openInterface(67371042, 1047); + GOTO flow_26 + flow_18: + openInterface(67371042, 1045); + GOTO flow_26 + flow_19: + openInterface(67371042, 1049); + GOTO flow_26 + flow_20: + openInterface(67371042, 1035); + GOTO flow_26 + flow_21: + openInterface(67371042, 1039); + GOTO flow_26 + flow_22: + openInterface(67371042, 1048); + GOTO flow_26 + flow_23: + openInterface(67371042, 1037); + GOTO flow_26 + flow_24: + openInterface(67371042, 1033); + GOTO flow_26 + flow_25: + closeInterface(67371042); + flow_26: + return; +} diff --git a/dumps/scripts/3850.cs2 b/dumps/scripts/3850.cs2 new file mode 100644 index 0000000..f830cbe --- /dev/null +++ b/dumps/scripts/3850.cs2 @@ -0,0 +1,4 @@ +void script_3850() { + script_304(28972276); + return; +} diff --git a/dumps/scripts/3851.cs2 b/dumps/scripts/3851.cs2 new file mode 100644 index 0000000..afb3574 --- /dev/null +++ b/dumps/scripts/3851.cs2 @@ -0,0 +1,4 @@ +void script_3851() { + script_304(41536891); + return; +} diff --git a/dumps/scripts/3852.cs2 b/dumps/scripts/3852.cs2 new file mode 100644 index 0000000..b81f46b --- /dev/null +++ b/dumps/scripts/3852.cs2 @@ -0,0 +1,4 @@ +void script_3852(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(470, 596)); + return; +} diff --git a/dumps/scripts/3853.cs2 b/dumps/scripts/3853.cs2 new file mode 100644 index 0000000..5caad7c --- /dev/null +++ b/dumps/scripts/3853.cs2 @@ -0,0 +1,4 @@ +void script_3853(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(471, 596)); + return; +} diff --git a/dumps/scripts/3854.cs2 b/dumps/scripts/3854.cs2 new file mode 100644 index 0000000..74583e0 --- /dev/null +++ b/dumps/scripts/3854.cs2 @@ -0,0 +1,4 @@ +void script_3854(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(472, 596)); + return; +} diff --git a/dumps/scripts/3855.cs2 b/dumps/scripts/3855.cs2 new file mode 100644 index 0000000..5b3d840 --- /dev/null +++ b/dumps/scripts/3855.cs2 @@ -0,0 +1,4 @@ +void script_3855(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(473, 596)); + return; +} diff --git a/dumps/scripts/3856.cs2 b/dumps/scripts/3856.cs2 new file mode 100644 index 0000000..04d785b --- /dev/null +++ b/dumps/scripts/3856.cs2 @@ -0,0 +1,4 @@ +void script_3856(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(474, 596)); + return; +} diff --git a/dumps/scripts/3857.cs2 b/dumps/scripts/3857.cs2 new file mode 100644 index 0000000..d56ee69 --- /dev/null +++ b/dumps/scripts/3857.cs2 @@ -0,0 +1,4 @@ +void script_3857(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(475, 596)); + return; +} diff --git a/dumps/scripts/3858.cs2 b/dumps/scripts/3858.cs2 new file mode 100644 index 0000000..8ff4eff --- /dev/null +++ b/dumps/scripts/3858.cs2 @@ -0,0 +1,4 @@ +void script_3858(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(476, 596)); + return; +} diff --git a/dumps/scripts/3859.cs2 b/dumps/scripts/3859.cs2 new file mode 100644 index 0000000..e55cd68 --- /dev/null +++ b/dumps/scripts/3859.cs2 @@ -0,0 +1,4 @@ +void script_3859(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(480, 596)); + return; +} diff --git a/dumps/scripts/386.cs2 b/dumps/scripts/386.cs2 new file mode 100644 index 0000000..d7f8edf --- /dev/null +++ b/dumps/scripts/386.cs2 @@ -0,0 +1,29 @@ +void script_386(int arg0) { + int ivar1; + ivar1 = script_734(globalint_196); + if (((boolean)arg0) && (globalint_197 != 0)) { + script_391(); + setWidgetIsHidden(true, new WidgetPointer(1028,35)); + setWidgetIsHidden(true, new WidgetPointer(1028,115)); + setWidgetIsHidden(false, new WidgetPointer(1028,117)); + setWidgetIsHidden(false, new WidgetPointer(1028,116)); + setWidgetIsHidden(false, new WidgetPointer(1028,89)); + } else { + script_387(ivar1); + script_390(ivar1); + setWidgetIsHidden(false, new WidgetPointer(1028,35)); + if (((boolean)globalint_197)) { + setWidgetIsHidden(true, new WidgetPointer(1028,115)); + setWidgetIsHidden(true, new WidgetPointer(1028,117)); + } else if (((boolean)bitconfig_8246) && ((boolean)bitconfig_8247)) { + setWidgetIsHidden(true, new WidgetPointer(1028,117)); + } else { + setWidgetIsHidden(false, new WidgetPointer(1028,117)); + } + setWidgetIsHidden(false, new WidgetPointer(1028,115)); + setWidgetIsHidden(true, new WidgetPointer(1028,116)); + setWidgetIsHidden(true, new WidgetPointer(1028,89)); + } + script_383(); + return; +} diff --git a/dumps/scripts/3860.cs2 b/dumps/scripts/3860.cs2 new file mode 100644 index 0000000..f9a518e --- /dev/null +++ b/dumps/scripts/3860.cs2 @@ -0,0 +1,4 @@ +void script_3860(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(477, 596)); + return; +} diff --git a/dumps/scripts/3861.cs2 b/dumps/scripts/3861.cs2 new file mode 100644 index 0000000..0abea5f --- /dev/null +++ b/dumps/scripts/3861.cs2 @@ -0,0 +1,4 @@ +void script_3861(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(479, 596)); + return; +} diff --git a/dumps/scripts/3862.cs2 b/dumps/scripts/3862.cs2 new file mode 100644 index 0000000..122b9c7 --- /dev/null +++ b/dumps/scripts/3862.cs2 @@ -0,0 +1,4 @@ +void script_3862(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(481, 596)); + return; +} diff --git a/dumps/scripts/3863.cs2 b/dumps/scripts/3863.cs2 new file mode 100644 index 0000000..5ad4ab2 --- /dev/null +++ b/dumps/scripts/3863.cs2 @@ -0,0 +1,4 @@ +void script_3863(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(482, 596)); + return; +} diff --git a/dumps/scripts/3864.cs2 b/dumps/scripts/3864.cs2 new file mode 100644 index 0000000..ecf3cdb --- /dev/null +++ b/dumps/scripts/3864.cs2 @@ -0,0 +1,4 @@ +void script_3864(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(478, 596)); + return; +} diff --git a/dumps/scripts/3865.cs2 b/dumps/scripts/3865.cs2 new file mode 100644 index 0000000..299fb94 --- /dev/null +++ b/dumps/scripts/3865.cs2 @@ -0,0 +1,4 @@ +void script_3865(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(775, 596)); + return; +} diff --git a/dumps/scripts/3866.cs2 b/dumps/scripts/3866.cs2 new file mode 100644 index 0000000..8f1897e --- /dev/null +++ b/dumps/scripts/3866.cs2 @@ -0,0 +1,4 @@ +void script_3866(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(483, 596)); + return; +} diff --git a/dumps/scripts/3867.cs2 b/dumps/scripts/3867.cs2 new file mode 100644 index 0000000..97a58a0 --- /dev/null +++ b/dumps/scripts/3867.cs2 @@ -0,0 +1,4 @@ +void script_3867(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(485, 596)); + return; +} diff --git a/dumps/scripts/3868.cs2 b/dumps/scripts/3868.cs2 new file mode 100644 index 0000000..74cf16a --- /dev/null +++ b/dumps/scripts/3868.cs2 @@ -0,0 +1,4 @@ +void script_3868() { + script_303(54306188, 0); + return; +} diff --git a/dumps/scripts/3869.cs2 b/dumps/scripts/3869.cs2 new file mode 100644 index 0000000..e24ed13 --- /dev/null +++ b/dumps/scripts/3869.cs2 @@ -0,0 +1,4 @@ +void script_3869() { + script_303(52579471, 0); + return; +} diff --git a/dumps/scripts/387.cs2 b/dumps/scripts/387.cs2 new file mode 100644 index 0000000..0de5819 --- /dev/null +++ b/dumps/scripts/387.cs2 @@ -0,0 +1,162 @@ +void script_387(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + string svar0; + string svar1; + string svar2; + string svar3; + string stack_dump0; + svar0 = "Select Character"; + svar1 = "Select Style"; + svar2 = "Style"; + ivar1 = 0; + ivar1 = max(max(add(getTextWidth(468, svar0), 40), getTextWidth(468, svar1)), getTextWidth(468, svar2)); + setWidgetPosition(0, 0, 0, 0, new WidgetPointer(1028,36)); + script_362(67371044, ivar1, svar0); + script_362(67371045, ivar1, svar1); + ivar2 = getExtraChildGap(new WidgetPointer(1028,37)); + if (setWidgetRegister(new WidgetPointer(1028,37), subtract(ivar2, 1))) { + setWidgetHidden(1); + } + createExtraChild(new WidgetPointer(1028,37), 4, ivar2); + setWidgetSize(0, 0, 1, 1); + setWidgetPosition(0, 0, 1, 1); + setWidgetFont(468); + setWidgetRGB(new Color(36, 27, 18)); + setWidgetTextAlignment(1, 1, 0); + setWidgetUnknownBoolean(false); + setWidgetText(svar2); + setWidgetHidden(1); + stack_dump0 = cs2method2801(1, new WidgetPointer(1028,38)); + svar1 = cs2method2801(1, new WidgetPointer(1028,39)); + svar0 = stack_dump0; + ivar3 = getCommonDefinitionSize(3280); + ivar4 = 0; + ivar5 = 0; + ivar6 = 73; + ivar7 = 3278; + ivar2 = add(add(getWidgetActualX(new WidgetPointer(1028,36)), ivar1), 20); + ivar1 = add(max(getTextWidth(495, svar0), getTextWidth(495, svar1)), 30); + setWidgetPosition(ivar2, getWidgetActualY(new WidgetPointer(1028,38)), 0, 0, new WidgetPointer(1028,38)); + script_368(67371046, ivar1, svar0, ""); + ivar2 = add(add(ivar2, ivar1), 10); + setWidgetPosition(ivar2, getWidgetActualY(new WidgetPointer(1028,38)), 0, 0, new WidgetPointer(1028,39)); + script_368(67371047, ivar1, svar1, ""); + ivar4 = min(ivar3, getCommonDefinitionSize(ivar7)); + ivar5 = divide(add(ivar4, 1), 2); + ivar1 = max(add(multiply(ivar5, ivar6), subtract(89, ivar6)), multiplyDivide(4, 5, 765)); + setWidgetSize(ivar1, 26, 0, 1, new WidgetPointer(1028,35)); + setWidgetSize(ivar1, getWidgetActualHeight(new WidgetPointer(1028,35)), 0, 0, new WidgetPointer(1028,114)); + setWidgetSize(0, 180, 1, 0, new WidgetPointer(1028,47)); + setWidgetPosition(0, 237, 1, 0, new WidgetPointer(1028,71)); + setWidgetSize(subtract(ivar1, add(add(ivar2, getWidgetActualWidth(new WidgetPointer(1028,39))), 42)), getWidgetActualHeight(new WidgetPointer(1028,40)), 0, 0, new WidgetPointer(1028,40)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(1028,40)), getWidgetActualY(new WidgetPointer(1028,38)), 0, 0, new WidgetPointer(1028,40)); + script_389(); + ivar8 = subtract(globalint_197, 1); + if (ivar8 <= -1) { + setWidgetIsHidden(true, new WidgetPointer(1028,37)); + setWidgetIsHidden(true, new WidgetPointer(1028,115)); + setWidgetIsHidden(true, new WidgetPointer(1028,117)); + setWidgetIsHidden(true, new WidgetPointer(1028,112)); + setWidgetIsHidden(true, new WidgetPointer(1028,113)); + } else { + setWidgetIsHidden(false, new WidgetPointer(1028,37)); + setWidgetIsHidden(false, new WidgetPointer(1028,115)); + if (((boolean)bitconfig_8246) && ((boolean)bitconfig_8247)) { + setWidgetIsHidden(true, new WidgetPointer(1028,117)); + } else { + setWidgetIsHidden(false, new WidgetPointer(1028,117)); + } + setWidgetIsHidden(false, new WidgetPointer(1028,112)); + setWidgetIsHidden(false, new WidgetPointer(1028,113)); + } + ivar9 = -1; + svar3 = ""; + ivar10 = -1; + ivar11 = 0; + ivar12 = 1; + ivar13 = cs2method_3408(105, 74, ivar7, ivar8); + script_385(ivar13); + ivar2 = subtract(getWidgetActualHeight(new WidgetPointer(1028,47)), add(89, 17)); + while (ivar11 < ivar4) { + ivar9 = ((int)cs2method_3408(105, 73, 3280, ivar11)); + if (ivar9 != -1) { + if (ivar11 < ivar5) { + if (ivar11 == ivar8) { + setWidgetPosition(multiply(ivar6, ivar11), 0, 0, 0, new WidgetPointer(ivar9)); + } else { + setWidgetPosition(multiply(ivar6, ivar11), ivar2, 0, 2, new WidgetPointer(ivar9)); + } + if ((ivar11 <= ivar8) || (ivar8 <= -1)) { + cs2method202(ivar9); + } else { + cs2method203(ivar9); + } + } else { + if (ivar11 == ivar8) { + setWidgetPosition(multiply(ivar6, subtract(ivar11, ivar5)), 17, 0, 2, new WidgetPointer(ivar9)); + } else { + setWidgetPosition(multiply(ivar6, subtract(ivar11, ivar5)), 0, 0, 2, new WidgetPointer(ivar9)); + } + if ((ivar8 < ivar5) || (ivar11 <= ivar8)) { + cs2method202(ivar9); + } + } + setWidgetSize(89, 89, 0, 0, new WidgetPointer(ivar9)); + ivar13 = cs2method_3408(105, 74, ivar7, ivar11); + if (ivar13 != -1) { + if (((boolean)arg0)) { + svar3 = cs2method_3408(74, 115, 3279, ivar13); + ivar10 = getOtherCommonData(ivar13, 1162); + } else { + svar3 = getOtherCommonData(ivar13, 1160); + ivar10 = getOtherCommonData(ivar13, 1161); + } + if (ivar11 == ivar8) { + ivar12 = 1; + } else { + ivar12 = 0; + } + script_363(ivar9, ivar8, 3280, ivar10, 1, 51, 61, 2, ivar12, svar3, ""); + setScriptCallOnClickContextMenu(351, -2147483644, add(ivar11, 1), "ii", new WidgetPointer(ivar9)); + } else { + script_363(ivar9, -1, -1, -1, 0, 0, 0, 0, 0, "", ""); + } + } + ivar11 = add(ivar11, 1); + } + while (ivar11 < ivar3) { + ivar9 = ((int)cs2method_3408(105, 73, 3280, ivar11)); + if (ivar9 != -1) { + setWidgetIsHidden(true, new WidgetPointer(ivar9)); + } + ivar11 = add(ivar11, 1); + } + if (ivar8 >= ivar5) { + ivar11 = subtract(ivar4, 1); + while (ivar11 >= ivar8) { + ivar9 = ((int)cs2method_3408(105, 73, 3280, ivar11)); + if (ivar9 != -1) { + cs2method202(ivar9); + } + ivar11 = subtract(ivar11, 1); + } + } else { + ivar9 = ((int)cs2method_3408(105, 73, 3280, ivar8)); + if (ivar9 != -1) { + cs2method202(ivar9); + } + } + return; +} diff --git a/dumps/scripts/3870.cs2 b/dumps/scripts/3870.cs2 new file mode 100644 index 0000000..73514bd --- /dev/null +++ b/dumps/scripts/3870.cs2 @@ -0,0 +1,4 @@ +void script_3870() { + script_304(54306188); + return; +} diff --git a/dumps/scripts/3871.cs2 b/dumps/scripts/3871.cs2 new file mode 100644 index 0000000..0e70d2e --- /dev/null +++ b/dumps/scripts/3871.cs2 @@ -0,0 +1,4 @@ +void script_3871(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(283, 596)); + return; +} diff --git a/dumps/scripts/3872.cs2 b/dumps/scripts/3872.cs2 new file mode 100644 index 0000000..de91b72 --- /dev/null +++ b/dumps/scripts/3872.cs2 @@ -0,0 +1,4 @@ +void script_3872(int arg0,int arg1) { + script_311(arg0, arg1, "Map link"); + return; +} diff --git a/dumps/scripts/3873.cs2 b/dumps/scripts/3873.cs2 new file mode 100644 index 0000000..2554e9b --- /dev/null +++ b/dumps/scripts/3873.cs2 @@ -0,0 +1,4 @@ +void script_3873(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(417, 596)); + return; +} diff --git a/dumps/scripts/3874.cs2 b/dumps/scripts/3874.cs2 new file mode 100644 index 0000000..d03cf10 --- /dev/null +++ b/dumps/scripts/3874.cs2 @@ -0,0 +1,4 @@ +void script_3874(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(405, 596)); + return; +} diff --git a/dumps/scripts/3875.cs2 b/dumps/scripts/3875.cs2 new file mode 100644 index 0000000..71cc0b6 --- /dev/null +++ b/dumps/scripts/3875.cs2 @@ -0,0 +1,4 @@ +void script_3875(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(406, 596)); + return; +} diff --git a/dumps/scripts/3876.cs2 b/dumps/scripts/3876.cs2 new file mode 100644 index 0000000..045318c --- /dev/null +++ b/dumps/scripts/3876.cs2 @@ -0,0 +1,4 @@ +void script_3876(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(407, 596)); + return; +} diff --git a/dumps/scripts/3877.cs2 b/dumps/scripts/3877.cs2 new file mode 100644 index 0000000..b817e73 --- /dev/null +++ b/dumps/scripts/3877.cs2 @@ -0,0 +1,4 @@ +void script_3877(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(408, 596)); + return; +} diff --git a/dumps/scripts/3878.cs2 b/dumps/scripts/3878.cs2 new file mode 100644 index 0000000..169e159 --- /dev/null +++ b/dumps/scripts/3878.cs2 @@ -0,0 +1,4 @@ +void script_3878(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(409, 596)); + return; +} diff --git a/dumps/scripts/3879.cs2 b/dumps/scripts/3879.cs2 new file mode 100644 index 0000000..aaf06b9 --- /dev/null +++ b/dumps/scripts/3879.cs2 @@ -0,0 +1,4 @@ +void script_3879() { + script_304(40176799); + return; +} diff --git a/dumps/scripts/388.cs2 b/dumps/scripts/388.cs2 new file mode 100644 index 0000000..6145790 --- /dev/null +++ b/dumps/scripts/388.cs2 @@ -0,0 +1,4 @@ +void script_388() { + script_304(46271535); + return; +} diff --git a/dumps/scripts/3880.cs2 b/dumps/scripts/3880.cs2 new file mode 100644 index 0000000..7f306a7 --- /dev/null +++ b/dumps/scripts/3880.cs2 @@ -0,0 +1,4 @@ +void script_3880() { + script_304(54218108); + return; +} diff --git a/dumps/scripts/3881.cs2 b/dumps/scripts/3881.cs2 new file mode 100644 index 0000000..d31ad4b --- /dev/null +++ b/dumps/scripts/3881.cs2 @@ -0,0 +1,4 @@ +void script_3881() { + script_304(55036828); + return; +} diff --git a/dumps/scripts/3882.cs2 b/dumps/scripts/3882.cs2 new file mode 100644 index 0000000..6efe9d9 --- /dev/null +++ b/dumps/scripts/3882.cs2 @@ -0,0 +1,4 @@ +void script_3882() { + script_304(44443420); + return; +} diff --git a/dumps/scripts/3883.cs2 b/dumps/scripts/3883.cs2 new file mode 100644 index 0000000..aa1cbfa --- /dev/null +++ b/dumps/scripts/3883.cs2 @@ -0,0 +1,4 @@ +void script_3883() { + script_304(44918551); + return; +} diff --git a/dumps/scripts/3884.cs2 b/dumps/scripts/3884.cs2 new file mode 100644 index 0000000..6104596 --- /dev/null +++ b/dumps/scripts/3884.cs2 @@ -0,0 +1,4 @@ +void script_3884() { + script_304(44312331); + return; +} diff --git a/dumps/scripts/3885.cs2 b/dumps/scripts/3885.cs2 new file mode 100644 index 0000000..262dbd5 --- /dev/null +++ b/dumps/scripts/3885.cs2 @@ -0,0 +1,4 @@ +void script_3885() { + script_304(45836044); + return; +} diff --git a/dumps/scripts/3886.cs2 b/dumps/scripts/3886.cs2 new file mode 100644 index 0000000..854154d --- /dev/null +++ b/dumps/scripts/3886.cs2 @@ -0,0 +1,4 @@ +void script_3886() { + script_304(42116509); + return; +} diff --git a/dumps/scripts/3887.cs2 b/dumps/scripts/3887.cs2 new file mode 100644 index 0000000..1c12597 --- /dev/null +++ b/dumps/scripts/3887.cs2 @@ -0,0 +1,4 @@ +void script_3887() { + script_304(42132949); + return; +} diff --git a/dumps/scripts/3888.cs2 b/dumps/scripts/3888.cs2 new file mode 100644 index 0000000..c8c9de3 --- /dev/null +++ b/dumps/scripts/3888.cs2 @@ -0,0 +1,4 @@ +void script_3888() { + script_304(43165149); + return; +} diff --git a/dumps/scripts/3889.cs2 b/dumps/scripts/3889.cs2 new file mode 100644 index 0000000..87080dd --- /dev/null +++ b/dumps/scripts/3889.cs2 @@ -0,0 +1,4 @@ +void script_3889() { + script_304(44164564); + return; +} diff --git a/dumps/scripts/389.cs2 b/dumps/scripts/389.cs2 new file mode 100644 index 0000000..0745cff --- /dev/null +++ b/dumps/scripts/389.cs2 @@ -0,0 +1,42 @@ +void script_389() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + deleteAllExtraChilds(new WidgetPointer(1028,45)); + ivar0 = getWidgetActualWidth(new WidgetPointer(1028,45)); + ivar1 = getCommonDefinitionSize(748); + ivar2 = divide(subtract(ivar0, 22), ivar1); + ivar3 = add(divide(subtract(ivar0, multiply(ivar1, ivar2)), 2), 1); + ivar4 = add(ivar1, 6); + ivar5 = 0; + ivar6 = -1; + ivar7 = -1; + while (ivar5 < ivar1) { + createExtraChild(new WidgetPointer(1028,45), 3, ivar5); + setWidgetSize(subtract(ivar2, 2), 26, 0, 1); + setWidgetPosition(add(ivar3, multiply(ivar5, ivar2)), 5, 0, 2); + setWidgetFilled(1); + setWidgetRGB(new Color(cs2method_3408(105, 105, 746, ivar5))); + setWidgetContextMenuOption(1, cs2method_3408(105, 115, 747, ivar5)); + ivar6 = cs2method_3408(105, 105, 748, ivar5); + if (globalint_1019 == ivar6) { + ivar7 = ivar5; + } else { + setScriptCallOnClickContextMenu(357, -2147483644, ivar6, 4, "iii"); + setScriptCallOnMouseEntered(375, new WidgetPointer(-32768,3), new WidgetPointer(-32768,3), -2147483643, 14006640, 10913874, 1, ivar4, "IIiiiii"); + setScriptCallOnMouseExit(377, new WidgetPointer(-32768,3), ivar4, "Ii"); + } + ivar5 = add(ivar5, 1); + } + if (ivar7 != -1) { + script_376(67371053, 67371053, ivar7, 9878498, 2909586, 1, ivar1); + } else { + script_376(67371053, -1, -1, 0, 0, 1, ivar1); + } + return; +} diff --git a/dumps/scripts/3890.cs2 b/dumps/scripts/3890.cs2 new file mode 100644 index 0000000..9ce1a68 --- /dev/null +++ b/dumps/scripts/3890.cs2 @@ -0,0 +1,4 @@ +void script_3890() { + script_304(41985563); + return; +} diff --git a/dumps/scripts/3891.cs2 b/dumps/scripts/3891.cs2 new file mode 100644 index 0000000..1a1a147 --- /dev/null +++ b/dumps/scripts/3891.cs2 @@ -0,0 +1,4 @@ +void script_3891() { + script_304(44574254); + return; +} diff --git a/dumps/scripts/3892.cs2 b/dumps/scripts/3892.cs2 new file mode 100644 index 0000000..702fd20 --- /dev/null +++ b/dumps/scripts/3892.cs2 @@ -0,0 +1,4 @@ +void script_3892() { + script_304(42935876); + return; +} diff --git a/dumps/scripts/3893.cs2 b/dumps/scripts/3893.cs2 new file mode 100644 index 0000000..ff19081 --- /dev/null +++ b/dumps/scripts/3893.cs2 @@ -0,0 +1,4 @@ +void script_3893() { + script_304(53044866); + return; +} diff --git a/dumps/scripts/3894.cs2 b/dumps/scripts/3894.cs2 new file mode 100644 index 0000000..f081ff9 --- /dev/null +++ b/dumps/scripts/3894.cs2 @@ -0,0 +1,4 @@ +void script_3894() { + script_304(50751115); + return; +} diff --git a/dumps/scripts/3895.cs2 b/dumps/scripts/3895.cs2 new file mode 100644 index 0000000..2a07390 --- /dev/null +++ b/dumps/scripts/3895.cs2 @@ -0,0 +1,4 @@ +void script_3895() { + script_304(51062396); + return; +} diff --git a/dumps/scripts/3896.cs2 b/dumps/scripts/3896.cs2 new file mode 100644 index 0000000..3c3c41e --- /dev/null +++ b/dumps/scripts/3896.cs2 @@ -0,0 +1,4 @@ +void script_3896() { + script_304(50620147); + return; +} diff --git a/dumps/scripts/3897.cs2 b/dumps/scripts/3897.cs2 new file mode 100644 index 0000000..dedf919 --- /dev/null +++ b/dumps/scripts/3897.cs2 @@ -0,0 +1,4 @@ +void script_3897() { + script_304(52274793); + return; +} diff --git a/dumps/scripts/3898.cs2 b/dumps/scripts/3898.cs2 new file mode 100644 index 0000000..ac304c2 --- /dev/null +++ b/dumps/scripts/3898.cs2 @@ -0,0 +1,4 @@ +void script_3898() { + script_304(51078682); + return; +} diff --git a/dumps/scripts/3899.cs2 b/dumps/scripts/3899.cs2 new file mode 100644 index 0000000..85ba586 --- /dev/null +++ b/dumps/scripts/3899.cs2 @@ -0,0 +1,4 @@ +void script_3899() { + script_304(50488878); + return; +} diff --git a/dumps/scripts/39.cs2 b/dumps/scripts/39.cs2 new file mode 100644 index 0000000..2bc4171 --- /dev/null +++ b/dumps/scripts/39.cs2 @@ -0,0 +1,4 @@ +void script_39(int arg0,int arg1,int arg2,int arg3,string arg4) { + script_569(arg0, -1, arg1, arg2, arg3, arg4); + return; +} diff --git a/dumps/scripts/390.cs2 b/dumps/scripts/390.cs2 new file mode 100644 index 0000000..6be7728 --- /dev/null +++ b/dumps/scripts/390.cs2 @@ -0,0 +1,100 @@ +void script_390(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + string svar0; + int stack_dump0; + ivar1 = getCommonDefinitionSize(3281); + ivar2 = -1; + ivar3 = subtract(ivar1, 1); + while (ivar3 >= 0) { + ivar2 = ((int)cs2method_3408(105, 73, 3281, ivar3)); + if (ivar2 != -1) { + setWidgetIsHidden(true, new WidgetPointer(ivar2)); + } + ivar3 = subtract(ivar3, 1); + } + deleteAllExtraChilds(new WidgetPointer(1028,82)); + ivar4 = cs2method_3408(105, 74, 3278, subtract(globalint_197, 1)); + deleteAllExtraChilds(new WidgetPointer(1028,71)); + svar0 = "Please choose your character." + "
" + "
" + "Your choice will not affect your abilities." + "
" + "You can modify features like your hair style and clothing once you have chosen your character."; + if (ivar4 == -1) { + ivar1 = subtract(getWidgetActualWidth(new WidgetPointer(1028,82)), 16); + stack_dump0 = getMaxLineWidth(ivar1, 495, svar0); + ivar3 = add(multiply(getLineCount(ivar1, 495, svar0), 20), 3); + ivar1 = stack_dump0; + setWidgetSize(add(ivar1, 16), add(ivar3, 50), 0, 0, new WidgetPointer(1028,71)); + createExtraChild(new WidgetPointer(1028,71), 4, getExtraChildGap(new WidgetPointer(1028,71))); + setWidgetSize(ivar1, ivar3, 0, 0); + setWidgetPosition(0, 22, 1, 0); + setWidgetFont(3793); + setWidgetRGB(new Color(0, 0, 0)); + setWidgetUnknownBoolean(false); + setWidgetTextAlignment(1, 1, 20); + setWidgetText(svar0); + setWidgetIsHidden(false, new WidgetPointer(1028,71)); + return; + } + setWidgetIsHidden(true, new WidgetPointer(1028,71)); + ivar5 = 0; + ivar3 = 0; + ivar6 = script_384(0, ivar4, arg0); + ivar7 = subtract(globalint_86, 1); + ivar2 = ((int)cs2method_3408(105, 73, 3281, 0)); + while ((ivar6 != -1) && (ivar2 != -1)) { + setWidgetSize(98, 17, 0, 1, new WidgetPointer(ivar2)); + if (ivar3 == ivar7) { + ivar5 = 1; + } else { + ivar5 = 0; + } + script_363(ivar2, ivar7, 3281, getOtherCommonData(ivar6, 1181), 1, 85, 181, 1, ivar5, "", ""); + setWidgetContextMenuOption(1, new WidgetPointer(ivar2), "Select outfit"); + setScriptCallOnClickContextMenu(352, -2147483644, add(ivar3, 1), "ii", new WidgetPointer(ivar2)); + ivar3 = add(ivar3, 1); + ivar6 = script_384(ivar3, ivar4, arg0); + ivar2 = ((int)cs2method_3408(105, 73, 3281, ivar3)); + } + ivar8 = ivar3; + if (ivar8 <= 1) { + if (setWidgetRegister(new WidgetPointer(1028,37), subtract(getExtraChildGap(new WidgetPointer(1028,37)), 1))) { + setWidgetHidden(0); + } + if (setWidgetRegister(new WidgetPointer(1028,37), subtract(getExtraChildGap(new WidgetPointer(1028,37)), 2))) { + setWidgetHidden(1); + } + if (ivar8 <= 0) { + return; + } + } else { + if (setWidgetRegister(new WidgetPointer(1028,37), subtract(getExtraChildGap(new WidgetPointer(1028,37)), 1))) { + setWidgetHidden(1); + } + if (setWidgetRegister(new WidgetPointer(1028,37), subtract(getExtraChildGap(new WidgetPointer(1028,37)), 2))) { + setWidgetHidden(0); + } + } + ivar9 = min(divide(subtract(390, 98), max(subtract(ivar8, 1), 1)), multiplyDivide(33, 40, 89)); + ivar3 = 0; + while (ivar3 < ivar8) { + ivar2 = ((int)cs2method_3408(105, 73, 3281, ivar3)); + if (ivar3 == ivar7) { + setWidgetPosition(multiply(ivar3, ivar9), 0, 0, 0, new WidgetPointer(ivar2)); + } else { + setWidgetPosition(multiply(ivar3, ivar9), 0, 0, 2, new WidgetPointer(ivar2)); + } + if (ivar3 <= ivar7) { + cs2method202(ivar2); + } else { + cs2method203(ivar2); + } + ivar3 = add(ivar3, 1); + } + return; +} diff --git a/dumps/scripts/3900.cs2 b/dumps/scripts/3900.cs2 new file mode 100644 index 0000000..88f7819 --- /dev/null +++ b/dumps/scripts/3900.cs2 @@ -0,0 +1,4 @@ +void script_3900() { + script_304(50554312); + return; +} diff --git a/dumps/scripts/3901.cs2 b/dumps/scripts/3901.cs2 new file mode 100644 index 0000000..a133277 --- /dev/null +++ b/dumps/scripts/3901.cs2 @@ -0,0 +1,4 @@ +void script_3901() { + script_304(51062190); + return; +} diff --git a/dumps/scripts/3902.cs2 b/dumps/scripts/3902.cs2 new file mode 100644 index 0000000..471bd83 --- /dev/null +++ b/dumps/scripts/3902.cs2 @@ -0,0 +1,4 @@ +void script_3902() { + script_304(51619253); + return; +} diff --git a/dumps/scripts/3903.cs2 b/dumps/scripts/3903.cs2 new file mode 100644 index 0000000..8b99162 --- /dev/null +++ b/dumps/scripts/3903.cs2 @@ -0,0 +1,4 @@ +void script_3903() { + script_304(52602256); + return; +} diff --git a/dumps/scripts/3904.cs2 b/dumps/scripts/3904.cs2 new file mode 100644 index 0000000..fbbcad4 --- /dev/null +++ b/dumps/scripts/3904.cs2 @@ -0,0 +1,4 @@ +void script_3904() { + script_304(51946852); + return; +} diff --git a/dumps/scripts/3905.cs2 b/dumps/scripts/3905.cs2 new file mode 100644 index 0000000..ab23ca0 --- /dev/null +++ b/dumps/scripts/3905.cs2 @@ -0,0 +1,4 @@ +void script_3905() { + script_304(50865512); + return; +} diff --git a/dumps/scripts/3906.cs2 b/dumps/scripts/3906.cs2 new file mode 100644 index 0000000..2355565 --- /dev/null +++ b/dumps/scripts/3906.cs2 @@ -0,0 +1,4 @@ +void script_3906() { + script_304(47277637); + return; +} diff --git a/dumps/scripts/3907.cs2 b/dumps/scripts/3907.cs2 new file mode 100644 index 0000000..d3cc8f7 --- /dev/null +++ b/dumps/scripts/3907.cs2 @@ -0,0 +1,4 @@ +void script_3907() { + script_304(46196270); + return; +} diff --git a/dumps/scripts/3908.cs2 b/dumps/scripts/3908.cs2 new file mode 100644 index 0000000..e64499d --- /dev/null +++ b/dumps/scripts/3908.cs2 @@ -0,0 +1,4 @@ +void script_3908() { + script_304(49473035); + return; +} diff --git a/dumps/scripts/3909.cs2 b/dumps/scripts/3909.cs2 new file mode 100644 index 0000000..6d5a6b5 --- /dev/null +++ b/dumps/scripts/3909.cs2 @@ -0,0 +1,4 @@ +void script_3909() { + script_304(50128434); + return; +} diff --git a/dumps/scripts/391.cs2 b/dumps/scripts/391.cs2 new file mode 100644 index 0000000..b00d321 --- /dev/null +++ b/dumps/scripts/391.cs2 @@ -0,0 +1,357 @@ +void script_391() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + string svar0; + string svar1; + int stack_dump0; + ivar0 = -1; + ivar1 = -1; + ivar2 = -1; + ivar3 = -1; + ivar4 = -1; + ivar5 = -1; + ivar6 = -1; + ivar7 = -1; + ivar8 = -1; + ivar9 = -1; + ivar10 = -1; + svar0 = ""; + switch (globalint_1020) { + case 0: + ivar0 = 67371103; + ivar6 = 748; + ivar7 = 746; + ivar8 = 747; + ivar9 = 4; + ivar10 = globalint_1019; + svar0 = "Select skin colour:"; + setWidgetIsHidden(true, new WidgetPointer(1028,102)); + break; + case 1: + ivar0 = 67371104; + if (IsFemale()) { + ivar1 = 3302; + ivar2 = 3303; + ivar4 = 7; + } else { + ivar1 = 3304; + ivar2 = 3305; + ivar4 = 0; + } + ivar5 = globalint_1008; + ivar6 = 2345; + ivar7 = 2343; + ivar8 = 2344; + ivar9 = 0; + ivar10 = globalint_1015; + svar0 = "Select hairstyle:"; + setWidgetIsHidden(true, new WidgetPointer(1028,102)); + break; + case 2: + ivar0 = 67371108; + if (((int)IsFemale()) != 1) { + ivar1 = 3307; + ivar2 = 3306; + ivar3 = 2340; + ivar4 = 1; + ivar5 = globalint_1009; + ivar6 = 2345; + ivar7 = 2343; + ivar8 = 2344; + ivar9 = 0; + ivar10 = globalint_1015; + } + svar0 = "Select facial hair:"; + setWidgetIsHidden(true, new WidgetPointer(1028,102)); + break; + case 3: + ivar0 = 67371105; + if (IsFemale()) { + ivar1 = 3299; + ivar2 = 3298; + ivar3 = 1590; + ivar4 = 9; + } else { + ivar1 = 3287; + ivar2 = 3286; + ivar3 = 689; + ivar4 = 2; + } + ivar5 = globalint_1010; + ivar6 = 3283; + ivar7 = 2347; + ivar8 = 2348; + ivar9 = 1; + ivar10 = globalint_1016; + svar0 = "Select torso:"; + setWidgetIsHidden(false, new WidgetPointer(1028,102)); + break; + case 6: + ivar0 = 67371106; + if (IsFemale()) { + ivar1 = 3301; + ivar2 = 3300; + ivar3 = 1606; + ivar4 = 12; + } else { + ivar1 = 3289; + ivar2 = 3288; + ivar3 = 1585; + ivar4 = 5; + } + ivar5 = globalint_1013; + ivar6 = 3283; + ivar7 = 2347; + ivar8 = 2348; + ivar9 = 2; + ivar10 = globalint_1017; + svar0 = "Select legs:"; + setWidgetIsHidden(false, new WidgetPointer(1028,102)); + break; + case 7: + ivar0 = 67371107; + if (IsFemale()) { + ivar1 = 1137; + ivar2 = 3295; + ivar3 = 3294; + ivar4 = 13; + } else { + ivar1 = 1136; + ivar2 = 3292; + ivar3 = 3291; + ivar4 = 6; + } + ivar5 = globalint_1014; + ivar6 = 3297; + ivar7 = 753; + ivar8 = 3296; + ivar9 = 3; + ivar10 = globalint_1018; + svar0 = "Select footwear:"; + setWidgetIsHidden(false, new WidgetPointer(1028,102)); + } + deleteAllExtraChilds(new WidgetPointer(1028,94)); + setScriptCallOnMouseEntered(-1, "", new WidgetPointer(ivar0)); + setScriptCallOnMouseExit(382, "", new WidgetPointer(ivar0)); + script_376(67371102, ivar0, -1, 9878498, 2909586, 0, 0); + if (ivar0 != 67371103) { + setScriptCallOnMouseEntered(375, new WidgetPointer(1028,94), new WidgetPointer(-32768,3), -1, 14006640, 10913874, 0, 6, "IIiiiii", new WidgetPointer(1028,95)); + setScriptCallOnMouseExit(377, new WidgetPointer(1028,94), 6, "Ii", new WidgetPointer(1028,95)); + } + setScriptCallOnMouseOver(378, cs2method2801(1, new WidgetPointer(1028,95)), new WidgetPointer(-32768,3), -1, -2147483647, "sIii", new WidgetPointer(1028,95)); + if (ivar0 != 67371104) { + setScriptCallOnMouseEntered(375, new WidgetPointer(1028,94), new WidgetPointer(-32768,3), -1, 14006640, 10913874, 0, 6, "IIiiiii", new WidgetPointer(1028,96)); + setScriptCallOnMouseExit(377, new WidgetPointer(1028,94), 6, "Ii", new WidgetPointer(1028,96)); + } + setScriptCallOnMouseOver(378, cs2method2801(1, new WidgetPointer(1028,96)), new WidgetPointer(-32768,3), -1, -2147483647, "sIii", new WidgetPointer(1028,96)); + if (ivar0 != 67371108) { + setScriptCallOnMouseEntered(375, new WidgetPointer(1028,94), new WidgetPointer(-32768,3), -1, 14006640, 10913874, 0, 6, "IIiiiii", new WidgetPointer(1028,100)); + setScriptCallOnMouseExit(377, new WidgetPointer(1028,94), 6, "Ii", new WidgetPointer(1028,100)); + } + setScriptCallOnMouseOver(378, cs2method2801(1, new WidgetPointer(1028,100)), new WidgetPointer(-32768,3), -1, -2147483647, "sIii", new WidgetPointer(1028,100)); + if (ivar0 != 67371105) { + setScriptCallOnMouseEntered(375, new WidgetPointer(1028,94), new WidgetPointer(-32768,3), -1, 14006640, 10913874, 0, 6, "IIiiiii", new WidgetPointer(1028,97)); + setScriptCallOnMouseExit(377, new WidgetPointer(1028,94), 6, "Ii", new WidgetPointer(1028,97)); + } + setScriptCallOnMouseOver(378, cs2method2801(1, new WidgetPointer(1028,97)), new WidgetPointer(-32768,3), -1, -2147483647, "sIii", new WidgetPointer(1028,97)); + if (ivar0 != 67371106) { + setScriptCallOnMouseEntered(375, new WidgetPointer(1028,94), new WidgetPointer(-32768,3), -1, 14006640, 10913874, 0, 6, "IIiiiii", new WidgetPointer(1028,98)); + setScriptCallOnMouseExit(377, new WidgetPointer(1028,94), 6, "Ii", new WidgetPointer(1028,98)); + } + setScriptCallOnMouseOver(378, cs2method2801(1, new WidgetPointer(1028,98)), new WidgetPointer(-32768,3), -1, -2147483647, "sIii", new WidgetPointer(1028,98)); + if (ivar0 != 67371107) { + setScriptCallOnMouseEntered(375, new WidgetPointer(1028,94), new WidgetPointer(-32768,3), -1, 14006640, 10913874, 0, 6, "IIiiiii", new WidgetPointer(1028,99)); + setScriptCallOnMouseExit(377, new WidgetPointer(1028,94), 6, "Ii", new WidgetPointer(1028,99)); + } + setScriptCallOnMouseOver(378, cs2method2801(1, new WidgetPointer(1028,99)), new WidgetPointer(-32768,3), -1, -2147483647, "sIii", new WidgetPointer(1028,99)); + ivar11 = 0; + ivar12 = 0; + ivar13 = 0; + ivar14 = 0; + ivar15 = -1; + ivar16 = -1; + ivar17 = -1; + ivar18 = 0; + svar1 = ""; + deleteAllExtraChilds(new WidgetPointer(1028,107)); + deleteAllExtraChilds(new WidgetPointer(1028,104)); + if (((ivar1 != -1) && (ivar2 != -1)) && (ivar4 != -1)) { + ivar14 = divide(subtract(getWidgetActualWidth(new WidgetPointer(1028,107)), multiply(4, 65)), 3); + ivar12 = getCommonDefinitionSize(ivar1); + while (ivar11 < ivar12) { + createExtraChild(new WidgetPointer(1028,107), 5, ivar11); + setWidgetSize(65, 65, 0, 0); + setWidgetPosition(multiply(mod(ivar11, 4), add(65, ivar14)), multiply(divide(ivar11, 4), add(65, ivar14)), 0, 0); + setWidgetSprite(cs2method_3408(105, 100, ivar2, ivar11)); + if (((boolean)globalint_1020)) { + ivar15 = cs2method_3408(105, 74, ivar1, ivar11); + if (ivar15 != -1) { + svar1 = getOtherCommonData(ivar15, 792); + setWidgetContextMenuOption(1, svar1); + ivar16 = getOtherCommonData(ivar15, 788); + } else { + stack_dump0 = -1; + svar1 = ""; + ivar16 = stack_dump0; + } + } else { + svar1 = cs2method_3408(105, 115, ivar3, ivar11); + setWidgetContextMenuOption(1, svar1); + ivar16 = cs2method_3408(105, 75, ivar1, ivar11); + } + if (ivar5 == ivar16) { + ivar17 = ivar11; + ivar18 = getWidgetActualY(); + if (strLength(svar1) > 0) { + svar0 = svar0 + " " + svar1; + } + setScriptCallOnMouseExit(382, ""); + } else { + setScriptCallOnClickContextMenu(355, -2147483644, ivar16, ivar4, "iKi"); + setScriptCallOnMouseEntered(373, new WidgetPointer(-32768,3), -2147483643, add(ivar12, 1), 2, 1, "Iiii1"); + setScriptCallOnMouseExit(373, new WidgetPointer(-32768,3), -2147483643, add(ivar12, 1), 2, 0, "Iiii1"); + } + if (strLength(svar1) > 0) { + setScriptCallOnMouseOver(378, svar1, new WidgetPointer(-32768,3), -2147483643, -2147483647, "sIii"); + } + ivar13 = getWidgetActualY(); + ivar11 = add(ivar11, 1); + } + ivar13 = add(ivar13, 65); + createExtraChild(new WidgetPointer(1028,107), 3, ivar12); + if ((ivar17 != -1) && setWidgetRegister(new WidgetPointer(1028,107), ivar17)) { + setWidgetSize(subtract(getWidgetActualWidth(), 6), subtract(getWidgetActualHeight(), 6), 0, 0); + setWidgetPosition(add(getWidgetActualX(), 3), add(getWidgetActualY(), 3), 0, 0); + setWidgetRGB(new Color(0, 0, 0)); + cs2method2103(175); + setWidgetFilled(1); + } else { + setWidgetHidden(1); + } + } + ivar19 = 3466; + if (ivar13 > getWidgetActualHeight(new WidgetPointer(1028,107))) { + setWidgetScrollMax(0, ivar13, new WidgetPointer(1028,107)); + if (ivar18 < cs2method2601(new WidgetPointer(1028,107))) { + cs2method2100(0, subtract(ivar18, 15), new WidgetPointer(1028,107)); + } else { + if (add(ivar18, 65) >= add(cs2method2601(new WidgetPointer(1028,107)), getWidgetActualHeight(new WidgetPointer(1028,107)))) { + cs2method2100(0, subtract(add(add(ivar18, 65), 15), getWidgetActualHeight(new WidgetPointer(1028,107))), new WidgetPointer(1028,107)); + } + } + script_31(67371113, 67371115, 3471, 3468, 3469, 3470, 3465, 3464); + if (setWidgetRegister(new WidgetPointer(1028,105), 4)) { + setScriptCallOnMouseEntered(688, new WidgetPointer(-32768,3), -2147483643, ivar19, "Iid"); + ivar19 = 3467; + setScriptCallOnMouseEntered(688, new WidgetPointer(-32768,3), -2147483643, ivar19, "Iid"); + ivar19 = 3464; + setScriptCallOnMouseExit(688, new WidgetPointer(-32768,3), -2147483643, ivar19, "Iid"); + ivar19 = 3465; + setScriptCallOnMouseExit(688, new WidgetPointer(-32768,3), -2147483643, ivar19, "Iid"); + } + } else if (((boolean)globalint_1020)) { + script_374(67371115, 20, "Please choose your skin colour" + "
" + "from the selection on the right."); + } else { + if ((globalint_1020 == 2) && IsFemale()) { + script_374(67371115, 20, "Female characters cannot have" + "
" + "facial hair in RuneScape."); + } + } + cs2method2100(0, 0, new WidgetPointer(1028,107)); + setWidgetScrollMax(0, 0, new WidgetPointer(1028,107)); + deleteAllExtraChilds(new WidgetPointer(1028,105)); + script_374(67371112, 0, svar0); + deleteAllExtraChilds(new WidgetPointer(1028,111)); + ivar20 = -1; + ivar17 = -1; + ivar11 = 0; + ivar18 = 0; + ivar21 = 0; + if (((ivar6 != -1) && (ivar7 != -1)) && (ivar9 != -1)) { + ivar12 = getCommonDefinitionSize(ivar6); + ivar21 = add(ivar12, 6); + while (ivar11 < ivar12) { + createExtraChild(new WidgetPointer(1028,111), 3, ivar11); + setWidgetSize(15, subtract(17, 2), 1, 0); + setWidgetPosition(0, add(multiply(ivar11, 17), 1), 1, 0); + setWidgetFilled(1); + setWidgetRGB(new Color(cs2method_3408(105, 105, ivar7, ivar11))); + svar1 = cs2method_3408(105, 115, ivar8, ivar11); + setWidgetContextMenuOption(1, svar1); + ivar20 = cs2method_3408(105, 105, ivar6, ivar11); + if (ivar10 == ivar20) { + ivar17 = ivar11; + ivar18 = getWidgetActualY(); + setScriptCallOnMouseExit(382, ""); + } else { + setScriptCallOnClickContextMenu(357, -2147483644, ivar20, ivar9, "iii"); + setScriptCallOnMouseEntered(375, new WidgetPointer(-32768,3), new WidgetPointer(-32768,3), -2147483643, 14006640, 10913874, 1, ivar21, "IIiiiii"); + setScriptCallOnMouseExit(377, new WidgetPointer(-32768,3), ivar21, "Ii"); + } + if (strLength(svar1) > 0) { + setScriptCallOnMouseOver(381, svar1, new WidgetPointer(-32768,3), -2147483643, -2147483646, "sIii"); + } + ivar11 = add(ivar11, 1); + } + } else { + ivar12 = 0; + } + ivar13 = max(multiply(ivar12, 17), 0); + if (ivar13 > subtract(getWidgetActualHeight(new WidgetPointer(1028,108)), 12)) { + setWidgetSize(23, 12, 1, 1, new WidgetPointer(1028,111)); + setWidgetPosition(5, 0, 0, 1, new WidgetPointer(1028,111)); + setWidgetScrollMax(0, ivar13, new WidgetPointer(1028,111)); + if (ivar18 < cs2method2601(new WidgetPointer(1028,111))) { + cs2method2100(0, subtract(ivar18, 5), new WidgetPointer(1028,111)); + } else { + if (add(ivar18, 17) >= add(cs2method2601(new WidgetPointer(1028,111)), getWidgetActualHeight(new WidgetPointer(1028,111)))) { + cs2method2100(0, subtract(add(add(ivar18, 17), 5), getWidgetActualHeight(new WidgetPointer(1028,111))), new WidgetPointer(1028,111)); + } + } + setWidgetIsHidden(false, new WidgetPointer(1028,110)); + script_31(67371118, 67371119, 3471, 3468, 3469, 3470, 3465, 3464); + if (setWidgetRegister(new WidgetPointer(1028,110), 4)) { + ivar19 = 3466; + setScriptCallOnMouseEntered(688, new WidgetPointer(-32768,3), -2147483643, ivar19, "Iid"); + ivar19 = 3467; + setScriptCallOnMouseEntered(688, new WidgetPointer(-32768,3), -2147483643, ivar19, "Iid"); + ivar19 = 3464; + setScriptCallOnMouseExit(688, new WidgetPointer(-32768,3), -2147483643, ivar19, "Iid"); + ivar19 = 3465; + setScriptCallOnMouseExit(688, new WidgetPointer(-32768,3), -2147483643, ivar19, "Iid"); + } + } else { + setWidgetSize(10, 12, 1, 1, new WidgetPointer(1028,111)); + setWidgetPosition(0, 0, 1, 1, new WidgetPointer(1028,111)); + setWidgetScrollMax(0, 0, new WidgetPointer(1028,111)); + cs2method2100(0, 0, new WidgetPointer(1028,111)); + deleteAllExtraChilds(new WidgetPointer(1028,110)); + setWidgetIsHidden(true, new WidgetPointer(1028,110)); + } + if (ivar17 != -1) { + script_376(67371119, 67371119, ivar17, 9878498, 2909586, 1, ivar12); + } else { + script_376(67371119, -1, -1, 0, 0, 1, ivar12); + } + script_389(); + return; +} diff --git a/dumps/scripts/3910.cs2 b/dumps/scripts/3910.cs2 new file mode 100644 index 0000000..bdddfa4 --- /dev/null +++ b/dumps/scripts/3910.cs2 @@ -0,0 +1,4 @@ +void script_3910() { + script_304(49473146); + return; +} diff --git a/dumps/scripts/3911.cs2 b/dumps/scripts/3911.cs2 new file mode 100644 index 0000000..14af559 --- /dev/null +++ b/dumps/scripts/3911.cs2 @@ -0,0 +1,4 @@ +void script_3911() { + script_304(49096310); + return; +} diff --git a/dumps/scripts/3912.cs2 b/dumps/scripts/3912.cs2 new file mode 100644 index 0000000..bb2e173 --- /dev/null +++ b/dumps/scripts/3912.cs2 @@ -0,0 +1,4 @@ +void script_3912() { + script_304(28726389); + return; +} diff --git a/dumps/scripts/3913.cs2 b/dumps/scripts/3913.cs2 new file mode 100644 index 0000000..e6e8aad --- /dev/null +++ b/dumps/scripts/3913.cs2 @@ -0,0 +1,4 @@ +void script_3913() { + script_304(45426610); + return; +} diff --git a/dumps/scripts/3914.cs2 b/dumps/scripts/3914.cs2 new file mode 100644 index 0000000..3ab362a --- /dev/null +++ b/dumps/scripts/3914.cs2 @@ -0,0 +1,4 @@ +void script_3914() { + script_304(53007799); + return; +} diff --git a/dumps/scripts/3915.cs2 b/dumps/scripts/3915.cs2 new file mode 100644 index 0000000..86490cc --- /dev/null +++ b/dumps/scripts/3915.cs2 @@ -0,0 +1,4 @@ +void script_3915() { + script_304(52155741); + return; +} diff --git a/dumps/scripts/3916.cs2 b/dumps/scripts/3916.cs2 new file mode 100644 index 0000000..e695157 --- /dev/null +++ b/dumps/scripts/3916.cs2 @@ -0,0 +1,4 @@ +void script_3916() { + script_304(53237106); + return; +} diff --git a/dumps/scripts/3917.cs2 b/dumps/scripts/3917.cs2 new file mode 100644 index 0000000..b5eff24 --- /dev/null +++ b/dumps/scripts/3917.cs2 @@ -0,0 +1,4 @@ +void script_3917() { + script_304(53908898); + return; +} diff --git a/dumps/scripts/3918.cs2 b/dumps/scripts/3918.cs2 new file mode 100644 index 0000000..f080772 --- /dev/null +++ b/dumps/scripts/3918.cs2 @@ -0,0 +1,4 @@ +void script_3918() { + script_304(53957991); + return; +} diff --git a/dumps/scripts/3919.cs2 b/dumps/scripts/3919.cs2 new file mode 100644 index 0000000..1deddf2 --- /dev/null +++ b/dumps/scripts/3919.cs2 @@ -0,0 +1,4 @@ +void script_3919() { + script_304(44442972); + return; +} diff --git a/dumps/scripts/392.cs2 b/dumps/scripts/392.cs2 new file mode 100644 index 0000000..1bca2fd --- /dev/null +++ b/dumps/scripts/392.cs2 @@ -0,0 +1,14 @@ +void script_392(int arg0,int arg1) { + if (arg0 == -1) { + arg0 = 1112; + } + setWidgetModel(getOtherCommonData(arg0, 1166), new WidgetPointer(1028,113)); + if (((boolean)arg1)) { + setWidgetAnimation(getOtherCommonData(arg0, 1165), new WidgetPointer(1028,112)); + setWidgetAnimation(getOtherCommonData(arg0, 1168), new WidgetPointer(1028,113)); + } else { + setWidgetAnimation(getOtherCommonData(arg0, 1164), new WidgetPointer(1028,112)); + setWidgetAnimation(getOtherCommonData(arg0, 1167), new WidgetPointer(1028,113)); + } + return; +} diff --git a/dumps/scripts/3920.cs2 b/dumps/scripts/3920.cs2 new file mode 100644 index 0000000..30ed80f --- /dev/null +++ b/dumps/scripts/3920.cs2 @@ -0,0 +1,4 @@ +void script_3920() { + script_304(851289461); + return; +} diff --git a/dumps/scripts/3921.cs2 b/dumps/scripts/3921.cs2 new file mode 100644 index 0000000..408982b --- /dev/null +++ b/dumps/scripts/3921.cs2 @@ -0,0 +1,4 @@ +void script_3921() { + script_304(46425529); + return; +} diff --git a/dumps/scripts/3922.cs2 b/dumps/scripts/3922.cs2 new file mode 100644 index 0000000..17adf24 --- /dev/null +++ b/dumps/scripts/3922.cs2 @@ -0,0 +1,4 @@ +void script_3922() { + script_304(46802271); + return; +} diff --git a/dumps/scripts/3923.cs2 b/dumps/scripts/3923.cs2 new file mode 100644 index 0000000..0c1f634 --- /dev/null +++ b/dumps/scripts/3923.cs2 @@ -0,0 +1,4 @@ +void script_3923() { + script_304(46343475); + return; +} diff --git a/dumps/scripts/3924.cs2 b/dumps/scripts/3924.cs2 new file mode 100644 index 0000000..2af8267 --- /dev/null +++ b/dumps/scripts/3924.cs2 @@ -0,0 +1,4 @@ +void script_3924(int arg0,int arg1) { + script_41(49479737); + return; +} diff --git a/dumps/scripts/3925.cs2 b/dumps/scripts/3925.cs2 new file mode 100644 index 0000000..87224b1 --- /dev/null +++ b/dumps/scripts/3925.cs2 @@ -0,0 +1,6 @@ +void script_3925() { + setWidgetSprite(4031, new WidgetPointer(311,36)); + setWidgetSprite(4031, new WidgetPointer(311,38)); + setWidgetSprite(4037, new WidgetPointer(311,37)); + return; +} diff --git a/dumps/scripts/3926.cs2 b/dumps/scripts/3926.cs2 new file mode 100644 index 0000000..5d0dcf7 --- /dev/null +++ b/dumps/scripts/3926.cs2 @@ -0,0 +1,6 @@ +void script_3926() { + setWidgetSprite(4032, new WidgetPointer(311,36)); + setWidgetSprite(4032, new WidgetPointer(311,38)); + setWidgetSprite(4038, new WidgetPointer(311,37)); + return; +} diff --git a/dumps/scripts/3927.cs2 b/dumps/scripts/3927.cs2 new file mode 100644 index 0000000..39c3ddb --- /dev/null +++ b/dumps/scripts/3927.cs2 @@ -0,0 +1,7 @@ +void script_3927(int arg0) { + cs2method2309(1, 171, new WidgetPointer(arg0)); + cs2method2309(2, 171, new WidgetPointer(arg0)); + cs2method2309(3, 171, new WidgetPointer(arg0)); + cs2method2309(4, 171, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/3928.cs2 b/dumps/scripts/3928.cs2 new file mode 100644 index 0000000..91bddbf --- /dev/null +++ b/dumps/scripts/3928.cs2 @@ -0,0 +1,4 @@ +void script_3928(int arg0,int arg1,int arg2) { + script_3929(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/3929.cs2 b/dumps/scripts/3929.cs2 new file mode 100644 index 0000000..8848a40 --- /dev/null +++ b/dumps/scripts/3929.cs2 @@ -0,0 +1,34 @@ +void script_3929(int arg0,int arg1,int arg2) { + if (((boolean)arg2)) { + if (setWidgetRegister(new WidgetPointer(arg0), 0)) { + setWidgetSprite(4038); + } + if (setWidgetRegister(new WidgetPointer(arg0), 1)) { + setWidgetSprite(4032); + } + if (setWidgetRegister(new WidgetPointer(arg0), 2)) { + setWidgetSprite(4035); + } + } else if (cs2method7007() == arg1) { + if (setWidgetRegister(new WidgetPointer(arg0), 0)) { + setWidgetSprite(4039); + } + if (setWidgetRegister(new WidgetPointer(arg0), 1)) { + setWidgetSprite(4033); + } + if (setWidgetRegister(new WidgetPointer(arg0), 2)) { + setWidgetSprite(4036); + } + } else { + if (setWidgetRegister(new WidgetPointer(arg0), 0)) { + setWidgetSprite(4037); + } + if (setWidgetRegister(new WidgetPointer(arg0), 1)) { + setWidgetSprite(4031); + } + if (setWidgetRegister(new WidgetPointer(arg0), 2)) { + setWidgetSprite(4034); + } + } + return; +} diff --git a/dumps/scripts/393.cs2 b/dumps/scripts/393.cs2 new file mode 100644 index 0000000..b56694c --- /dev/null +++ b/dumps/scripts/393.cs2 @@ -0,0 +1,31 @@ +void script_393() { + setWidgetIsHidden(true, new WidgetPointer(1010,4)); + setWidgetIsHidden(true, new WidgetPointer(1010,20)); + setWidgetText(new WidgetPointer(1010,1), "Command Options"); + setWidgetPosition(0, 133, 0, 0, new WidgetPointer(1010,40)); + setWidgetSize(190, 116, 0, 0, new WidgetPointer(1010,40)); + setWidgetText(new WidgetPointer(1010,41), "Comm Orb Recharging"); + setWidgetPosition(0, 133, 0, 0, new WidgetPointer(1010,41)); + setWidgetSize(190, 116, 0, 0, new WidgetPointer(1010,41)); + setWidgetTextAlignment(1, 1, 0, new WidgetPointer(1010,41)); + setWidgetPosition(30, 152, 0, 0, new WidgetPointer(1010,34)); + setWidgetPosition(30, 200, 0, 0, new WidgetPointer(1010,37)); + setWidgetText(new WidgetPointer(1010,39), "Recharge"); + setWidgetContextMenuOption(1, new WidgetPointer(1010,39), "Recharge"); + setWidgetPosition(4, 148, 0, 0, new WidgetPointer(1010,31)); + setWidgetPosition(15, 204, 0, 0, new WidgetPointer(1010,25)); + setWidgetPosition(105, 204, 0, 0, new WidgetPointer(1010,28)); + setWidgetIsHidden(true, new WidgetPointer(1010,32)); + setWidgetIsHidden(true, new WidgetPointer(1019,5)); + setWidgetIsHidden(true, new WidgetPointer(1019,6)); + setWidgetIsHidden(true, new WidgetPointer(1019,9)); + setWidgetIsHidden(true, new WidgetPointer(1019,8)); + setWidgetText(new WidgetPointer(1019,3), "Retreat"); + setWidgetIsHidden(true, new WidgetPointer(1019,12)); + setWidgetText(new WidgetPointer(1019,16), "Retreat"); + setWidgetContextMenuOption(1, new WidgetPointer(1019,16), "Retreat"); + setWidgetPosition(30, 0, 0, 1, new WidgetPointer(1019,1)); + setWidgetPosition(0, 50, 0, 1, new WidgetPointer(1019,0)); + setWidgetText(new WidgetPointer(1019,0), "Force Savant to teleport you to safety and order your remaining troops to fall back."); + return; +} diff --git a/dumps/scripts/3930.cs2 b/dumps/scripts/3930.cs2 new file mode 100644 index 0000000..8f18a91 --- /dev/null +++ b/dumps/scripts/3930.cs2 @@ -0,0 +1,4 @@ +void script_3930(int arg0,int arg1,int arg2) { + script_3931(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/3931.cs2 b/dumps/scripts/3931.cs2 new file mode 100644 index 0000000..e5507a1 --- /dev/null +++ b/dumps/scripts/3931.cs2 @@ -0,0 +1,24 @@ +void script_3931(int arg0,int arg1,int arg2) { + if (((boolean)arg2)) { + if (setWidgetRegister(new WidgetPointer(arg0), 0)) { + setWidgetSprite(4038); + } + if (setWidgetRegister(new WidgetPointer(arg0), 1)) { + setWidgetSprite(4032); + } + if (setWidgetRegister(new WidgetPointer(arg0), 2)) { + setWidgetSprite(4035); + } + } else { + if (setWidgetRegister(new WidgetPointer(arg0), 0)) { + setWidgetSprite(4037); + } + if (setWidgetRegister(new WidgetPointer(arg0), 1)) { + setWidgetSprite(4031); + } + if (setWidgetRegister(new WidgetPointer(arg0), 2)) { + setWidgetSprite(4034); + } + } + return; +} diff --git a/dumps/scripts/3932.cs2 b/dumps/scripts/3932.cs2 new file mode 100644 index 0000000..0c72b92 --- /dev/null +++ b/dumps/scripts/3932.cs2 @@ -0,0 +1,37 @@ +void script_3932(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5,string arg6) { + deleteAllExtraChilds(new WidgetPointer(arg2)); + setWidgetSize(arg4, 27, 0, 0, new WidgetPointer(arg2)); + createExtraChild(new WidgetPointer(arg2), 5, getExtraChildGap(new WidgetPointer(arg2))); + setWidgetSize(6, 26, 1, 0); + setWidgetPosition(0, 0, 1, 1); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg2), 5, getExtraChildGap(new WidgetPointer(arg2))); + setWidgetSize(26, 26, 0, 0); + setWidgetPosition(0, 0, 0, 1); + createExtraChild(new WidgetPointer(arg2), 5, getExtraChildGap(new WidgetPointer(arg2))); + setWidgetSize(26, 26, 0, 0); + setWidgetPosition(3, 0, 2, 1); + createExtraChild(new WidgetPointer(arg2), 4, getExtraChildGap(new WidgetPointer(arg2))); + setWidgetSize(0, 0, 1, 1); + setWidgetPosition(0, -3, 1, 1); + setWidgetFont(3793); + setWidgetRGB(new Color(235, 224, 188)); + setWidgetTextAlignment(1, 1, 0); + setWidgetUnknownBoolean(false); + setWidgetText(arg5); + script_3929(arg2, arg3, 0); + if (arg3 == -1) { + setScriptCallOnMouseExit(3930, new WidgetPointer(arg2), arg3, 0, "Ii1", new WidgetPointer(arg2)); + setScriptCallOnMouseEntered(3930, new WidgetPointer(arg2), arg3, 1, "Ii1", new WidgetPointer(arg2)); + } else { + setScriptCallOnMouseExit(3928, new WidgetPointer(arg2), arg3, 0, "Ii1", new WidgetPointer(arg2)); + setScriptCallOnMouseEntered(3928, new WidgetPointer(arg2), arg3, 1, "Ii1", new WidgetPointer(arg2)); + } + if (((boolean)arg0)) { + setScriptCallOnMousePressed(3388, arg3, arg0, arg1, "ii1", new WidgetPointer(arg2)); + } else { + setWidgetContextMenuOption(1, new WidgetPointer(arg2), arg5); + setScriptCallOnClickContextMenu(3388, arg3, arg0, arg1, "ii1", new WidgetPointer(arg2)); + } + return; +} diff --git a/dumps/scripts/3933.cs2 b/dumps/scripts/3933.cs2 new file mode 100644 index 0000000..482407b --- /dev/null +++ b/dumps/scripts/3933.cs2 @@ -0,0 +1,11 @@ +void script_3933(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + setWidgetRGB(new Color(arg1), new WidgetPointer(arg0)); + if (((boolean)arg2)) { + setWidgetSprite(cs2method_3408(105, 100, 3480, arg3), new WidgetPointer(arg4)); + } else if (arg5 == arg3) { + setWidgetSprite(cs2method_3408(105, 100, 736, arg3), new WidgetPointer(arg4)); + } else { + setWidgetSprite(cs2method_3408(105, 100, 735, arg3), new WidgetPointer(arg4)); + } + return; +} diff --git a/dumps/scripts/3934.cs2 b/dumps/scripts/3934.cs2 new file mode 100644 index 0000000..4934b3a --- /dev/null +++ b/dumps/scripts/3934.cs2 @@ -0,0 +1,4 @@ +void script_3934(int arg0) { + script_3213(arg0, ""); + return; +} diff --git a/dumps/scripts/3935.cs2 b/dumps/scripts/3935.cs2 new file mode 100644 index 0000000..462a363 --- /dev/null +++ b/dumps/scripts/3935.cs2 @@ -0,0 +1,3 @@ +void script_3935() { + return; +} diff --git a/dumps/scripts/3936.cs2 b/dumps/scripts/3936.cs2 new file mode 100644 index 0000000..adb0f1d --- /dev/null +++ b/dumps/scripts/3936.cs2 @@ -0,0 +1,16 @@ +int script_3936(string arg0) { + int ivar0; + int ivar1; + ivar0 = strLength(arg0); + if (ivar0 > 320) { + return 0; + } + ivar1 = 0; + while (ivar1 < ivar0) { + if (strIndexof(0, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!#$%&'*+-/=?^_.{}~@", substr(ivar1, add(ivar1, 1), arg0)) == -1) { + return 0; + } + ivar1 = add(ivar1, 1); + } + return 1; +} diff --git a/dumps/scripts/3937.cs2 b/dumps/scripts/3937.cs2 new file mode 100644 index 0000000..f372c37 --- /dev/null +++ b/dumps/scripts/3937.cs2 @@ -0,0 +1,15 @@ +void script_3937(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7) { + if (arg0 != -1) { + setWidgetSprite(arg1, new WidgetPointer(arg0)); + } + if (arg2 != -1) { + setWidgetSprite(arg3, new WidgetPointer(arg2)); + } + if (arg4 != -1) { + setWidgetSprite(arg5, new WidgetPointer(arg4)); + } + if (arg6 != -1) { + setWidgetSprite(arg7, new WidgetPointer(arg6)); + } + return; +} diff --git a/dumps/scripts/3938.cs2 b/dumps/scripts/3938.cs2 new file mode 100644 index 0000000..2e4091a --- /dev/null +++ b/dumps/scripts/3938.cs2 @@ -0,0 +1,10 @@ +void script_3938() { + if (((boolean)globalint_1411)) { + globalint_1411 = 0; + setWidgetSprite(4085, new WidgetPointer(673,41)); + } else { + globalint_1411 = 1; + setWidgetSprite(4087, new WidgetPointer(673,41)); + } + return; +} diff --git a/dumps/scripts/3939.cs2 b/dumps/scripts/3939.cs2 new file mode 100644 index 0000000..9926c7b --- /dev/null +++ b/dumps/scripts/3939.cs2 @@ -0,0 +1,16 @@ +void script_3939(int arg0) { + if (((boolean)arg0)) { + setWidgetRGB(new Color(250, 250, 250), new WidgetPointer(673,42)); + if (((boolean)globalint_1411)) { + setWidgetSprite(4087, new WidgetPointer(673,41)); + } else { + setWidgetSprite(4085, new WidgetPointer(673,41)); + } + } else if (((boolean)globalint_1411)) { + setWidgetSprite(4086, new WidgetPointer(673,41)); + } else { + setWidgetSprite(4084, new WidgetPointer(673,41)); + } + setWidgetRGB(new Color(235, 224, 188), new WidgetPointer(673,42)); + return; +} diff --git a/dumps/scripts/394.cs2 b/dumps/scripts/394.cs2 new file mode 100644 index 0000000..94650ef --- /dev/null +++ b/dumps/scripts/394.cs2 @@ -0,0 +1,14 @@ +void script_394(int arg0) { + if (((boolean)globalint_1391)) { + cs2method2103(max(subtract(getWidgetShadeColor(new WidgetPointer(arg0)), 10), 0), new WidgetPointer(arg0)); + if (((boolean)getWidgetShadeColor(new WidgetPointer(arg0)))) { + globalint_1391 = 1; + } + } else { + cs2method2103(min(add(getWidgetShadeColor(new WidgetPointer(arg0)), 10), 255), new WidgetPointer(arg0)); + if (getWidgetShadeColor(new WidgetPointer(arg0)) == 255) { + globalint_1391 = 0; + } + } + return; +} diff --git a/dumps/scripts/3940.cs2 b/dumps/scripts/3940.cs2 new file mode 100644 index 0000000..3f77bf9 --- /dev/null +++ b/dumps/scripts/3940.cs2 @@ -0,0 +1,10 @@ +void script_3940() { + setScriptCallOnKeyPress(-1, "", new WidgetPointer(137,56)); + setScriptCallOnKeyPress(3944, -2147483640, false, 0, "iz1", new WidgetPointer(890,55)); + setScriptCallOnMousePressed(3217, -2147483647, new WidgetPointer(890,59), new WidgetPointer(890,60), new WidgetPointer(890,61), 16, "iIIIi", new WidgetPointer(890,60)); + globalint_1099 = 0; + globalstring_330 = ""; + globalint_1412 = 0; + script_3218(58327099, 58327100, 58327101, 16, globalstring_330); + return; +} diff --git a/dumps/scripts/3941.cs2 b/dumps/scripts/3941.cs2 new file mode 100644 index 0000000..0c0d100 --- /dev/null +++ b/dumps/scripts/3941.cs2 @@ -0,0 +1,4 @@ +void script_3941() { + setScriptCallOnKeyPress(73, -2147483640, false, "iz", new WidgetPointer(137,56)); + return; +} diff --git a/dumps/scripts/3942.cs2 b/dumps/scripts/3942.cs2 new file mode 100644 index 0000000..7e74174 --- /dev/null +++ b/dumps/scripts/3942.cs2 @@ -0,0 +1,4 @@ +void script_3942() { + script_2715(); + return; +} diff --git a/dumps/scripts/3943.cs2 b/dumps/scripts/3943.cs2 new file mode 100644 index 0000000..64e5bc8 --- /dev/null +++ b/dumps/scripts/3943.cs2 @@ -0,0 +1,16 @@ +void script_3943() { + setWidgetIsHidden(false, new WidgetPointer(1028,90)); + setWidgetIsHidden(true, new WidgetPointer(1028,35)); + setWidgetIsHidden(true, new WidgetPointer(1028,115)); + setWidgetIsHidden(true, new WidgetPointer(1028,117)); + setWidgetIsHidden(true, new WidgetPointer(1028,116)); + setWidgetIsHidden(true, new WidgetPointer(1028,89)); + script_383(); + setScriptCallOnKeyPress(3944, -2147483640, false, 1, "iz1", new WidgetPointer(1028,177)); + setScriptCallOnMousePressed(3217, -2147483647, new WidgetPointer(1028,181), new WidgetPointer(1028,182), new WidgetPointer(1028,183), 16, "iIIIi", new WidgetPointer(1028,182)); + globalint_1099 = 0; + globalstring_330 = ""; + globalint_1412 = 0; + script_3218(67371189, 67371190, 67371191, 16, globalstring_330); + return; +} diff --git a/dumps/scripts/3944.cs2 b/dumps/scripts/3944.cs2 new file mode 100644 index 0000000..01379a6 --- /dev/null +++ b/dumps/scripts/3944.cs2 @@ -0,0 +1,55 @@ +void script_3944(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + int stack_dump0; + int stack_dump1; + int stack_dump2; + int stack_dump3; + string stack_dump4; + cs2func_script_802_struct(1,1,0) structdump_5; + if (((boolean)globalint_1412)) { + return; + } + ivar3 = 67371189; + ivar4 = 67371190; + ivar5 = 67371191; + if (((boolean)arg2)) { + ivar3 = 58327099; + ivar4 = 58327100; + ivar5 = 58327101; + } + switch (arg0) { + case 13: + return; + case 84: + globalint_1412 = 1; + return; + case 102: + case 103: + case 98: + case 99: + case 96: + case 97: + globalint_1099 = script_1553(arg0, globalint_1099, globalstring_330); + script_3218(ivar3, ivar4, ivar5, 16, globalstring_330); + return; + } + if (((strLength(globalstring_330) >= 12) && (arg0 != 85)) && (arg0 != 101)) { + return; + } + if (((strIndexof(((char)arg1), 0, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 _-") != -1) || (arg0 == 85)) || (arg0 == 101)) { + stack_dump0 = globalint_1099; + stack_dump1 = 2; + stack_dump2 = arg0; + stack_dump3 = arg1; + stack_dump4 = globalstring_330; + structdump_5 = script_802(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + stack_dump4 = structdump_5.stringpart_0; + globalint_1099 = structdump_5.intpart_0; + globalstring_330 = stack_dump4; + setWidgetText(new WidgetPointer(ivar4), globalstring_330); + script_3218(ivar3, ivar4, ivar5, 16, globalstring_330); + } + return; +} diff --git a/dumps/scripts/3945.cs2 b/dumps/scripts/3945.cs2 new file mode 100644 index 0000000..cac37a1 --- /dev/null +++ b/dumps/scripts/3945.cs2 @@ -0,0 +1,76 @@ +void script_3945(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + flow_0: + if (((boolean)arg2)) { + globalint_1412 = 1; + } + SWITCH (arg0) { + case 1: + GOTO flow_5 + case 2: + GOTO flow_8 + case 3: + GOTO flow_11 + case 4: + GOTO flow_14 + case 5: + GOTO flow_17 + case 6: + GOTO flow_20 + } + if (((boolean)arg2)) { + sendStringInput(globalstring_330); + } + flow_4: + GOTO flow_23 + flow_5: + if (((boolean)arg2)) { + sendStringInput(globalstring_331); + } + globalstring_330 = globalstring_331; + GOTO flow_23 + flow_8: + if (((boolean)arg2)) { + sendStringInput(globalstring_332); + } + globalstring_330 = globalstring_332; + GOTO flow_23 + flow_11: + if (((boolean)arg2)) { + sendStringInput(globalstring_333); + } + globalstring_330 = globalstring_333; + GOTO flow_23 + flow_14: + if (((boolean)arg2)) { + sendStringInput(globalstring_334); + } + globalstring_330 = globalstring_334; + GOTO flow_23 + flow_17: + if (((boolean)arg2)) { + sendStringInput(globalstring_335); + } + globalstring_330 = globalstring_335; + GOTO flow_23 + flow_20: + if (((boolean)arg2)) { + sendStringInput(globalstring_336); + } + globalstring_330 = globalstring_336; + flow_23: + ivar3 = 67371189; + ivar4 = 67371190; + ivar5 = 67371191; + if (((boolean)arg1)) { + ivar3 = 58327099; + ivar4 = 58327100; + ivar5 = 58327101; + } + setWidgetText(new WidgetPointer(ivar4), globalstring_330); + globalint_1099 = strLength(globalstring_330); + script_3218(ivar3, ivar4, ivar5, 16, globalstring_330); + return; +} diff --git a/dumps/scripts/3946.cs2 b/dumps/scripts/3946.cs2 new file mode 100644 index 0000000..a471d89 --- /dev/null +++ b/dumps/scripts/3946.cs2 @@ -0,0 +1,4 @@ +void script_3946(int arg0,string arg1,string arg2,string arg3,string arg4,string arg5,string arg6) { + script_3947(arg0, arg1, arg2, arg3, arg4, arg5, arg6); + return; +} diff --git a/dumps/scripts/3947.cs2 b/dumps/scripts/3947.cs2 new file mode 100644 index 0000000..2671fc3 --- /dev/null +++ b/dumps/scripts/3947.cs2 @@ -0,0 +1,18 @@ +void script_3947(int arg0,string arg1,string arg2,string arg3,string arg4,string arg5,string arg6) { + if (((boolean)arg0)) { + setWidgetContextMenuOption(1, new WidgetPointer(1028,158), arg1); + setWidgetContextMenuOption(1, new WidgetPointer(1028,159), arg2); + setWidgetContextMenuOption(1, new WidgetPointer(1028,160), arg3); + setWidgetContextMenuOption(1, new WidgetPointer(1028,161), arg4); + setWidgetContextMenuOption(1, new WidgetPointer(1028,162), arg5); + setWidgetContextMenuOption(1, new WidgetPointer(1028,163), arg6); + } else { + setWidgetContextMenuOption(1, new WidgetPointer(890,37), arg1); + setWidgetContextMenuOption(1, new WidgetPointer(890,38), arg2); + setWidgetContextMenuOption(1, new WidgetPointer(890,39), arg3); + setWidgetContextMenuOption(1, new WidgetPointer(890,40), arg4); + setWidgetContextMenuOption(1, new WidgetPointer(890,41), arg5); + setWidgetContextMenuOption(1, new WidgetPointer(890,42), arg6); + } + return; +} diff --git a/dumps/scripts/3948.cs2 b/dumps/scripts/3948.cs2 new file mode 100644 index 0000000..2dbe234 --- /dev/null +++ b/dumps/scripts/3948.cs2 @@ -0,0 +1,4 @@ +void script_3948(int arg0) { + setWidgetPosition(getWidgetActualX(new WidgetPointer(890,52)), arg0, 1, 0, new WidgetPointer(890,52)); + return; +} diff --git a/dumps/scripts/3949.cs2 b/dumps/scripts/3949.cs2 new file mode 100644 index 0000000..5d7ace2 --- /dev/null +++ b/dumps/scripts/3949.cs2 @@ -0,0 +1,10 @@ +void script_3949(int arg0,int arg1) { + if (((boolean)arg1)) { + setWidgetRGB(new Color(250, 250, 250), new WidgetPointer(arg0)); + setWidgetText(new WidgetPointer(arg0), concat("", strRemoveEntities(getWidgetText(new WidgetPointer(arg0))))); + } else { + setWidgetRGB(new Color(235, 224, 188), new WidgetPointer(arg0)); + setWidgetText(new WidgetPointer(arg0), concat("", strRemoveEntities(getWidgetText(new WidgetPointer(arg0))))); + } + return; +} diff --git a/dumps/scripts/395.cs2 b/dumps/scripts/395.cs2 new file mode 100644 index 0000000..72b3dee --- /dev/null +++ b/dumps/scripts/395.cs2 @@ -0,0 +1,6 @@ +int script_395() { + if (add(getSkillActualLvl(0), getSkillActualLvl(2)) == 130) { + return 1; + } + return 0; +} diff --git a/dumps/scripts/3950.cs2 b/dumps/scripts/3950.cs2 new file mode 100644 index 0000000..51a5047 --- /dev/null +++ b/dumps/scripts/3950.cs2 @@ -0,0 +1,10 @@ +void script_3950(int arg0,int arg1) { + if (((boolean)arg1)) { + setWidgetRGB(new Color(250, 250, 250), new WidgetPointer(arg0)); + setWidgetText(new WidgetPointer(arg0), concat("", strRemoveEntities(getWidgetText(new WidgetPointer(arg0))))); + } else { + setWidgetRGB(new Color(205, 190, 154), new WidgetPointer(arg0)); + setWidgetText(new WidgetPointer(arg0), concat("", strRemoveEntities(getWidgetText(new WidgetPointer(arg0))))); + } + return; +} diff --git a/dumps/scripts/3951.cs2 b/dumps/scripts/3951.cs2 new file mode 100644 index 0000000..426aeef --- /dev/null +++ b/dumps/scripts/3951.cs2 @@ -0,0 +1,9 @@ +void script_3951() { + globalstring_337 = globalstring_331; + globalstring_338 = globalstring_332; + globalstring_339 = globalstring_333; + globalstring_340 = globalstring_334; + globalstring_341 = globalstring_335; + globalstring_342 = globalstring_336; + return; +} diff --git a/dumps/scripts/3952.cs2 b/dumps/scripts/3952.cs2 new file mode 100644 index 0000000..0eb2bae --- /dev/null +++ b/dumps/scripts/3952.cs2 @@ -0,0 +1,25 @@ +void script_3952(int arg0) { + globalstring_331 = globalstring_337; + globalstring_332 = globalstring_338; + globalstring_333 = globalstring_339; + globalstring_334 = globalstring_340; + globalstring_335 = globalstring_341; + globalstring_336 = globalstring_342; + if (((boolean)arg0)) { + setWidgetText(new WidgetPointer(1028,158), concat("", globalstring_331)); + setWidgetText(new WidgetPointer(1028,159), concat("", globalstring_332)); + setWidgetText(new WidgetPointer(1028,160), concat("", globalstring_333)); + setWidgetText(new WidgetPointer(1028,161), concat("", globalstring_334)); + setWidgetText(new WidgetPointer(1028,162), concat("", globalstring_335)); + setWidgetText(new WidgetPointer(1028,163), concat("", globalstring_336)); + } else { + setWidgetText(new WidgetPointer(890,37), concat("", globalstring_331)); + setWidgetText(new WidgetPointer(890,38), concat("", globalstring_332)); + setWidgetText(new WidgetPointer(890,39), concat("", globalstring_333)); + setWidgetText(new WidgetPointer(890,40), concat("", globalstring_334)); + setWidgetText(new WidgetPointer(890,41), concat("", globalstring_335)); + setWidgetText(new WidgetPointer(890,42), concat("", globalstring_336)); + } + script_3947(arg0, globalstring_331, globalstring_332, globalstring_333, globalstring_334, globalstring_335, globalstring_336); + return; +} diff --git a/dumps/scripts/3953.cs2 b/dumps/scripts/3953.cs2 new file mode 100644 index 0000000..6e82d75 --- /dev/null +++ b/dumps/scripts/3953.cs2 @@ -0,0 +1,22 @@ +void script_3953(int arg0) { + globalstring_327 = globalstring_326; + if (strLength(globalstring_326) <= 0) { + script_3213(44105841, "Please enter your Email address again here."); + return; + } + if (stringMethod4107(globalstring_122, globalstring_326) != 0) { + script_3213(44105841, "Please ensure both Email addresses match."); + return; + } + if (getWidgetSpriteId(new WidgetPointer(673,94)) == 4061) { + script_3213(44105841, getWidgetText(new WidgetPointer(673,137))); + return; + } + setWidgetSprite(4059, new WidgetPointer(673,113)); + setWidgetIsHidden(true, new WidgetPointer(673,118)); + setWidgetIsHidden(true, new WidgetPointer(673,31)); + if (((boolean)arg0)) { + script_2714(7, 1); + } + return; +} diff --git a/dumps/scripts/3954.cs2 b/dumps/scripts/3954.cs2 new file mode 100644 index 0000000..108eddb --- /dev/null +++ b/dumps/scripts/3954.cs2 @@ -0,0 +1,18 @@ +int script_3954(int arg0) { + globalint_1408 = globalint_1407; + if (globalint_1407 < 1) { + script_3213(44105777, "Please enter your age, in years, here."); + return 0; + } + if (globalint_1407 > 120) { + script_3213(44105777, "Please check the age entered and try again."); + return 0; + } + setWidgetSprite(4059, new WidgetPointer(673,49)); + setWidgetIsHidden(true, new WidgetPointer(673,125)); + setWidgetIsHidden(true, new WidgetPointer(673,31)); + if (((boolean)arg0)) { + script_2714(6, 1); + } + return 1; +} diff --git a/dumps/scripts/3955.cs2 b/dumps/scripts/3955.cs2 new file mode 100644 index 0000000..ffd8003 --- /dev/null +++ b/dumps/scripts/3955.cs2 @@ -0,0 +1,8 @@ +void script_3955(int arg0,int arg1) { + if (((mod(subtract(getClientCycle(), arg0), 40) < 20) && hasWindowFocus()) && ((boolean)globalint_1412)) { + setWidgetIsHidden(false, new WidgetPointer(arg1)); + } else { + setWidgetIsHidden(true, new WidgetPointer(arg1)); + } + return; +} diff --git a/dumps/scripts/3956.cs2 b/dumps/scripts/3956.cs2 new file mode 100644 index 0000000..4a92dca --- /dev/null +++ b/dumps/scripts/3956.cs2 @@ -0,0 +1,4 @@ +void script_3956() { + script_2007(48758898, 48758791, 1, 0); + return; +} diff --git a/dumps/scripts/3957.cs2 b/dumps/scripts/3957.cs2 new file mode 100644 index 0000000..d383a43 --- /dev/null +++ b/dumps/scripts/3957.cs2 @@ -0,0 +1,26 @@ +void script_3957(int arg0) { + int ivar1; + flow_0: + ivar1 = getWidgetSpriteId(new WidgetPointer(arg0)); + SWITCH (ivar1) { + case 4117: + GOTO flow_1 + case 4118: + GOTO flow_2 + case 4119: + GOTO flow_3 + } + return; + flow_1: + setWidgetSprite(4122, new WidgetPointer(arg0)); + GOTO flow_4 + flow_2: + setWidgetSprite(4123, new WidgetPointer(arg0)); + GOTO flow_4 + flow_3: + setWidgetSprite(4124, new WidgetPointer(arg0)); + flow_4: + setWidgetSize(133, 16, 0, 0, new WidgetPointer(744,81)); + setScriptCallOnGameloop(3961, 0, new WidgetPointer(744,7), "iI", new WidgetPointer(744,7)); + return; +} diff --git a/dumps/scripts/3958.cs2 b/dumps/scripts/3958.cs2 new file mode 100644 index 0000000..f8f6a59 --- /dev/null +++ b/dumps/scripts/3958.cs2 @@ -0,0 +1,4 @@ +void script_3958() { + setScriptCallOnGameloop(3961, 0, new WidgetPointer(744,7), "iI", new WidgetPointer(744,7)); + return; +} diff --git a/dumps/scripts/3959.cs2 b/dumps/scripts/3959.cs2 new file mode 100644 index 0000000..1257144 --- /dev/null +++ b/dumps/scripts/3959.cs2 @@ -0,0 +1,4 @@ +void script_3959(int arg0) { + script_3960(arg0); + return; +} diff --git a/dumps/scripts/396.cs2 b/dumps/scripts/396.cs2 new file mode 100644 index 0000000..5f2897f --- /dev/null +++ b/dumps/scripts/396.cs2 @@ -0,0 +1,27 @@ +void script_396() { + setWidgetText(new WidgetPointer(433,11), intToStr(bitconfig_2469)); + setWidgetText(new WidgetPointer(433,12), intToStr(bitconfig_2470)); + setWidgetText(new WidgetPointer(433,13), intToStr(bitconfig_2471)); + setWidgetText(new WidgetPointer(433,14), intToStr(bitconfig_2472)); + if (((boolean)bitconfig_2469)) { + setWidgetRGB(new Color(255, 0, 51), new WidgetPointer(433,11)); + } else { + setWidgetRGB(new Color(0, 192, 0), new WidgetPointer(433,11)); + } + if (((boolean)bitconfig_2470)) { + setWidgetRGB(new Color(255, 0, 51), new WidgetPointer(433,12)); + } else { + setWidgetRGB(new Color(0, 192, 0), new WidgetPointer(433,12)); + } + if (((boolean)bitconfig_2471)) { + setWidgetRGB(new Color(255, 0, 51), new WidgetPointer(433,13)); + } else { + setWidgetRGB(new Color(0, 192, 0), new WidgetPointer(433,13)); + } + if (((boolean)bitconfig_2472)) { + setWidgetRGB(new Color(255, 0, 51), new WidgetPointer(433,14)); + } else { + setWidgetRGB(new Color(0, 192, 0), new WidgetPointer(433,14)); + } + return; +} diff --git a/dumps/scripts/3960.cs2 b/dumps/scripts/3960.cs2 new file mode 100644 index 0000000..daf5c85 --- /dev/null +++ b/dumps/scripts/3960.cs2 @@ -0,0 +1,24 @@ +void script_3960(int arg0) { + int ivar1; + flow_0: + ivar1 = getWidgetSpriteId(new WidgetPointer(arg0)); + SWITCH (ivar1) { + case 4122: + GOTO flow_1 + case 4123: + GOTO flow_2 + case 4124: + GOTO flow_3 + } + return; + flow_1: + setWidgetSprite(4117, new WidgetPointer(arg0)); + GOTO flow_4 + flow_2: + setWidgetSprite(4118, new WidgetPointer(arg0)); + GOTO flow_4 + flow_3: + setWidgetSprite(4119, new WidgetPointer(arg0)); + flow_4: + return; +} diff --git a/dumps/scripts/3961.cs2 b/dumps/scripts/3961.cs2 new file mode 100644 index 0000000..c36934d --- /dev/null +++ b/dumps/scripts/3961.cs2 @@ -0,0 +1,11 @@ +void script_3961(int arg0,int arg1) { + if (arg0 < 50) { + arg0 = add(arg0, 1); + setScriptCallOnGameloop(3961, arg0, new WidgetPointer(arg1), "iI", new WidgetPointer(arg1)); + } else { + setWidgetSize(63, 16, 0, 0, new WidgetPointer(744,81)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg1)); + script_3960(48758892); + } + return; +} diff --git a/dumps/scripts/3962.cs2 b/dumps/scripts/3962.cs2 new file mode 100644 index 0000000..1103dfd --- /dev/null +++ b/dumps/scripts/3962.cs2 @@ -0,0 +1,4 @@ +void script_3962(int arg0,int arg1,int arg2,int arg3) { + script_3963(arg0, arg1, arg2, arg3); + return; +} diff --git a/dumps/scripts/3963.cs2 b/dumps/scripts/3963.cs2 new file mode 100644 index 0000000..f60bb16 --- /dev/null +++ b/dumps/scripts/3963.cs2 @@ -0,0 +1,16 @@ +void script_3963(int arg0,int arg1,int arg2,int arg3) { + string svar0; + svar0 = strRemoveEntities(getWidgetText(new WidgetPointer(arg1))); + if (arg0 != -1) { + if (((boolean)arg3)) { + setWidgetText(new WidgetPointer(arg1), "" + svar0 + ""); + setWidgetRGB(new Color(250, 250, 250), new WidgetPointer(arg1)); + setWidgetSize(getTextWidth(arg2, svar0), getWidgetActualHeight(new WidgetPointer(arg0)), 0, 0, new WidgetPointer(arg0)); + } else { + setWidgetText(new WidgetPointer(arg1), "" + svar0 + ""); + setWidgetRGB(new Color(200, 200, 200), new WidgetPointer(arg1)); + setWidgetSize(getTextWidth(arg2, svar0), getWidgetActualHeight(new WidgetPointer(arg0)), 0, 0, new WidgetPointer(arg0)); + } + } + return; +} diff --git a/dumps/scripts/3964.cs2 b/dumps/scripts/3964.cs2 new file mode 100644 index 0000000..4303094 --- /dev/null +++ b/dumps/scripts/3964.cs2 @@ -0,0 +1,10 @@ +void script_3964() { + if (((boolean)globalint_1414)) { + setWidgetText(new WidgetPointer(596,39), "Username:"); + } else if (globalint_1414 == 2) { + setWidgetText(new WidgetPointer(596,39), "Email:"); + } else { + setWidgetText(new WidgetPointer(596,39), "Login:"); + } + return; +} diff --git a/dumps/scripts/3965.cs2 b/dumps/scripts/3965.cs2 new file mode 100644 index 0000000..f61887a --- /dev/null +++ b/dumps/scripts/3965.cs2 @@ -0,0 +1,39 @@ +void script_3965(int arg0,int arg1,string arg2,string arg3) { + deleteAllExtraChilds(new WidgetPointer(arg0)); + setWidgetSize(arg1, 27, 0, 0, new WidgetPointer(arg0)); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(6, 25, 1, 0); + setWidgetPosition(0, 0, 1, 1); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(25, 25, 0, 0); + setWidgetPosition(0, 0, 0, 1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(25, 25, 0, 0); + setWidgetPosition(3, 0, 2, 1); + setWidgetHFlip(1); + createExtraChild(new WidgetPointer(arg0), 4, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(0, 0, 1, 1); + setWidgetPosition(1, 1, 1, 1); + setWidgetFont(3793); + setWidgetRGB(new Color(192, 177, 84)); + setWidgetTextAlignment(1, 1, 0); + setWidgetUnknownBoolean(false); + setWidgetText(arg2); + createExtraChild(new WidgetPointer(arg0), 4, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(0, 0, 1, 1); + setWidgetPosition(0, 0, 1, 1); + setWidgetFont(3793); + setWidgetRGB(new Color(0, 0, 0)); + setWidgetTextAlignment(1, 1, 0); + setWidgetUnknownBoolean(false); + setWidgetText(arg2); + script_3967(arg0, 0); + setWidgetContextMenuOption(1, new WidgetPointer(arg0), arg2); + setScriptCallOnMouseEntered(3966, new WidgetPointer(arg0), 1, "I1", new WidgetPointer(arg0)); + if (strLength(arg3) > 0) { + setScriptCallOnMouseOver(378, arg3, new WidgetPointer(-32768,3), -1, -2147483647, "sIii", new WidgetPointer(arg0)); + } + setScriptCallOnMouseExit(3966, new WidgetPointer(arg0), 0, "I1", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/3966.cs2 b/dumps/scripts/3966.cs2 new file mode 100644 index 0000000..35eef02 --- /dev/null +++ b/dumps/scripts/3966.cs2 @@ -0,0 +1,4 @@ +void script_3966(int arg0,int arg1) { + script_3967(arg0, arg1); + return; +} diff --git a/dumps/scripts/3967.cs2 b/dumps/scripts/3967.cs2 new file mode 100644 index 0000000..c7a786c --- /dev/null +++ b/dumps/scripts/3967.cs2 @@ -0,0 +1,25 @@ +void script_3967(int arg0,int arg1) { + if (((boolean)arg1)) { + if (setWidgetRegister(new WidgetPointer(arg0), 0)) { + setWidgetSprite(4053); + } + if (setWidgetRegister(new WidgetPointer(arg0), 1)) { + setWidgetSprite(4055); + } + if (setWidgetRegister(new WidgetPointer(arg0), 2)) { + setWidgetSprite(4055); + } + } else { + if (setWidgetRegister(new WidgetPointer(arg0), 0)) { + setWidgetSprite(4052); + } + if (setWidgetRegister(new WidgetPointer(arg0), 1)) { + setWidgetSprite(4054); + } + if (setWidgetRegister(new WidgetPointer(arg0), 2)) { + setWidgetSprite(4054); + } + script_383(); + } + return; +} diff --git a/dumps/scripts/3968.cs2 b/dumps/scripts/3968.cs2 new file mode 100644 index 0000000..adfd6be --- /dev/null +++ b/dumps/scripts/3968.cs2 @@ -0,0 +1,36 @@ +void script_3968() { + int ivar0; + int ivar1; + if (((boolean)globalint_1429) || (globalint_1425 == globalint_1426)) { + return; + } + globalint_1427 = 0; + ivar0 = cs2method_3408(105, 74, 3483, globalint_1425); + ivar1 = 1; + if (getDisplayMode() >= 2) { + if (isWidgetHidden(new WidgetPointer(746,26)) || (getWidgetSpriteId(new WidgetPointer(746,26)) == -1)) { + ivar1 = 0; + } + } else { + if (isWidgetHidden(new WidgetPointer(548,141)) || (getWidgetSpriteId(new WidgetPointer(548,141)) == -1)) { + ivar1 = 0; + } + } + if (standart_config_281 == 1000) { + setScriptCallOnClickContextMenu(3976, globalint_1425, 1, ivar1, "iii", new WidgetPointer(1055,2)); + } else { + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(1055,2)); + } + if (isWidgetHidden(new WidgetPointer(1055,12)) && isWidgetHidden(new WidgetPointer(1055,1))) { + if (ivar0 != -1) { + cs2method2103(255, new WidgetPointer(1055,13)); + setScriptCallOnGameloop(3969, "", new WidgetPointer(1055,12)); + setWidgetIsHidden(false, new WidgetPointer(1055,12)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1055,1)); + setWidgetIsHidden(true, new WidgetPointer(1055,12)); + } + } + globalint_1426 = globalint_1425; + return; +} diff --git a/dumps/scripts/3969.cs2 b/dumps/scripts/3969.cs2 new file mode 100644 index 0000000..cc56a97 --- /dev/null +++ b/dumps/scripts/3969.cs2 @@ -0,0 +1,60 @@ +void script_3969() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + ivar0 = getWidgetShadeColor(new WidgetPointer(1055,13)); + ivar1 = -1; + ivar2 = 0; + ivar3 = 0; + ivar4 = 0; + ivar5 = -1; + if (isWidgetHidden(new WidgetPointer(1055,1))) { + if (ivar0 > 0) { + ivar2 = multiplyDivide(ivar0, 255, 100); + ivar2 = subtract(100, ivar2); + ivar3 = add(multiplyDivide(270, 100, ivar2), 10); + ivar4 = add(multiplyDivide(100, 100, ivar2), 10); + setWidgetSize(min(ivar3, 270), min(ivar4, 100), 0, 0, new WidgetPointer(1055,13)); + ivar0 = max(subtract(ivar0, 8), 0); + cs2method2103(ivar0, new WidgetPointer(1055,13)); + } else if (ivar1 != -1) { + setWidgetFilled(1, new WidgetPointer(1055,13)); + cs2method2103(0, new WidgetPointer(1055,2)); + cs2method2103(0, new WidgetPointer(1055,3)); + cs2method2103(0, new WidgetPointer(1055,4)); + cs2method2103(0, new WidgetPointer(1055,5)); + cs2method2103(0, new WidgetPointer(1055,6)); + cs2method2103(0, new WidgetPointer(1055,7)); + cs2method2103(0, new WidgetPointer(1055,8)); + cs2method2103(0, new WidgetPointer(1055,9)); + cs2method2103(0, new WidgetPointer(1055,10)); + cs2method2103(0, new WidgetPointer(1055,11)); + setWidgetText(new WidgetPointer(1055,5), getOtherCommonData(ivar1, 1266)); + if (getOtherCommonData(ivar1, 1270) != 4094) { + ivar5 = getOtherCommonData(cs2method_3408(105, 74, 2252, getOtherCommonData(ivar1, 1270)), 952); + } else { + ivar5 = getOtherCommonData(ivar1, 1271); + } + setWidgetSprite(ivar5, new WidgetPointer(1055,3)); + setScriptCallOnGameloop(3970, "", new WidgetPointer(1055,0)); + setWidgetIsHidden(false, new WidgetPointer(1055,1)); + } else { + setScriptCallOnGameloop(-1, "", new WidgetPointer(1055,12)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(1055,0)); + setWidgetIsHidden(true, new WidgetPointer(1055,1)); + setWidgetIsHidden(true, new WidgetPointer(1055,12)); + } + ivar1 = cs2method_3408(105, 74, 3483, globalint_1425); + } else if (ivar0 < 255) { + ivar0 = min(add(ivar0, 8), 255); + cs2method2103(ivar0, new WidgetPointer(1055,13)); + } else { + setScriptCallOnGameloop(-1, "", new WidgetPointer(1055,12)); + setWidgetFilled(0, new WidgetPointer(1055,13)); + setWidgetIsHidden(true, new WidgetPointer(1055,12)); + } + return; +} diff --git a/dumps/scripts/397.cs2 b/dumps/scripts/397.cs2 new file mode 100644 index 0000000..0e75431 --- /dev/null +++ b/dumps/scripts/397.cs2 @@ -0,0 +1,10 @@ +void script_397() { + if ((globalint_743 == -1) && (standart_config_1109 != -1)) { + if (multiply(standart_config_1111, standart_config_1110) > getItemAmtInContainer(93, 995)) { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(449,25)); + } else { + setWidgetRGB(new Color(globalint_1241), new WidgetPointer(449,25)); + } + } + return; +} diff --git a/dumps/scripts/3970.cs2 b/dumps/scripts/3970.cs2 new file mode 100644 index 0000000..756640a --- /dev/null +++ b/dumps/scripts/3970.cs2 @@ -0,0 +1,24 @@ +void script_3970() { + int ivar0; + ivar0 = getWidgetShadeColor(new WidgetPointer(1055,3)); + if (globalint_1427 < 190) { + globalint_1427 = add(globalint_1427, 1); + } else if (ivar0 < 255) { + ivar0 = min(add(ivar0, 4), 255); + cs2method2103(ivar0, new WidgetPointer(1055,2)); + cs2method2103(ivar0, new WidgetPointer(1055,3)); + cs2method2103(ivar0, new WidgetPointer(1055,4)); + cs2method2103(ivar0, new WidgetPointer(1055,5)); + cs2method2103(ivar0, new WidgetPointer(1055,6)); + cs2method2103(ivar0, new WidgetPointer(1055,7)); + cs2method2103(ivar0, new WidgetPointer(1055,8)); + cs2method2103(ivar0, new WidgetPointer(1055,9)); + cs2method2103(ivar0, new WidgetPointer(1055,10)); + cs2method2103(ivar0, new WidgetPointer(1055,11)); + } else { + setScriptCallOnGameloop(-1, "", new WidgetPointer(1055,0)); + setWidgetIsHidden(true, new WidgetPointer(1055,1)); + globalint_1427 = 0; + } + return; +} diff --git a/dumps/scripts/3971.cs2 b/dumps/scripts/3971.cs2 new file mode 100644 index 0000000..448e2c5 --- /dev/null +++ b/dumps/scripts/3971.cs2 @@ -0,0 +1,156 @@ +void script_3971() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + string svar0; + ivar0 = -1; + ivar1 = 0; + ivar2 = 0; + ivar3 = -1; + ivar4 = -1; + ivar5 = 0; + ivar6 = -1; + ivar7 = -1; + ivar8 = -1; + ivar9 = -1; + ivar10 = -1; + ivar11 = -1; + ivar12 = 0; + svar0 = "null"; + setWidgetSprite(cs2method_3408(105, 100, 3491, bitconfig_8575), new WidgetPointer(1056,112)); + if (((boolean)bitconfig_9030)) { + setWidgetSprite(1820, new WidgetPointer(1056,112)); + } + while (ivar2 < 6) { + switch (ivar2) { + case 0: + ivar1 = bitconfig_8587; + ivar0 = cs2method_3408(105, 74, 3483, bitconfig_8587); + ivar4 = 69206080; + ivar9 = 69206117; + ivar7 = 69206116; + ivar10 = 69206115; + setScriptCallOnClickContextMenu(3976, bitconfig_8587, 1, -2147483644, "iii", new WidgetPointer(ivar10)); + break; + case 1: + ivar1 = bitconfig_8588; + ivar0 = cs2method_3408(105, 74, 3483, bitconfig_8588); + ivar4 = 69206160; + ivar9 = 69206162; + ivar7 = 69206161; + ivar10 = 69206158; + setScriptCallOnClickContextMenu(3976, bitconfig_8588, 2, -2147483644, "iii", new WidgetPointer(ivar10)); + break; + case 2: + ivar1 = bitconfig_8589; + ivar0 = cs2method_3408(105, 74, 3483, bitconfig_8589); + ivar4 = 69206165; + ivar9 = 69206167; + ivar7 = 69206166; + ivar10 = 69206163; + setScriptCallOnClickContextMenu(3976, bitconfig_8589, 3, -2147483644, "iii", new WidgetPointer(ivar10)); + break; + case 3: + ivar1 = bitconfig_8590; + ivar0 = cs2method_3408(105, 74, 3483, bitconfig_8590); + ivar4 = 69206170; + ivar9 = 69206172; + ivar7 = 69206171; + ivar10 = 69206168; + setScriptCallOnClickContextMenu(3976, bitconfig_8590, 4, -2147483644, "iii", new WidgetPointer(ivar10)); + break; + case 4: + ivar1 = bitconfig_8591; + ivar0 = cs2method_3408(105, 74, 3483, bitconfig_8591); + ivar4 = 69206175; + ivar9 = 69206177; + ivar7 = 69206176; + ivar10 = 69206173; + setScriptCallOnClickContextMenu(3976, bitconfig_8591, 5, -2147483644, "iii", new WidgetPointer(ivar10)); + break; + case 5: + ivar1 = bitconfig_8592; + ivar0 = cs2method_3408(105, 74, 3483, bitconfig_8592); + ivar4 = 69206181; + ivar9 = 69206183; + ivar7 = 69206182; + ivar10 = 69206178; + setScriptCallOnClickContextMenu(3976, bitconfig_8592, 6, -2147483644, "iii", new WidgetPointer(ivar10)); + } + svar0 = " -" + "
"; + svar0 = concat(getOtherCommonData(ivar0, 1266), svar0); + svar0 = concat(svar0, getOtherCommonData(ivar0, 1273)); + if ((bitconfig_4895 == 3) && ((standart_config_281 < 1000) || (bitconfig_6494 < 5))) { + svar0 = getOtherCommonData(ivar0, 1266); + } + if (((boolean)script_3999(ivar1))) { + setScriptCallOnMouseOver(3981, new WidgetPointer(ivar10), svar0, "Is", new WidgetPointer(ivar10)); + } else { + setScriptCallOnMouseOver(-1, "", new WidgetPointer(ivar10)); + } + ivar12 = add(ivar2, 1); + if ((bitconfig_8577 == ivar12) && ((boolean)script_3999(bitconfig_8576))) { + ivar0 = cs2method_3408(105, 74, 3483, bitconfig_8576); + setScriptCallOnClickContextMenu(3976, bitconfig_8576, ivar12, -2147483644, "iii", new WidgetPointer(ivar10)); + if (((boolean)script_3999(ivar1))) { + setScriptCallOnMouseOver(3981, new WidgetPointer(ivar10), svar0, "Is", new WidgetPointer(ivar10)); + } else { + setScriptCallOnMouseOver(-1, "", new WidgetPointer(ivar10)); + } + } + if (ivar0 != -1) { + ivar8 = cs2method_3408(105, 100, 3492, getOtherCommonData(ivar0, 1272)); + if (((boolean)script_3996(ivar1)) && ((boolean)script_3999(ivar1))) { + ivar8 = 4346; + } + setWidgetSprite(ivar8, new WidgetPointer(ivar9)); + ivar5 = getOtherCommonData(ivar0, 1293); + if ((ivar5 != 0) && (ivar5 != 63)) { + ivar6 = 4272; + } else { + ivar6 = -1; + } + setWidgetSprite(ivar6, new WidgetPointer(ivar7)); + if (getOtherCommonData(ivar0, 1270) != 4094) { + ivar3 = getOtherCommonData(cs2method_3408(105, 74, 2252, getOtherCommonData(ivar0, 1270)), 952); + } else { + ivar3 = getOtherCommonData(ivar0, 1271); + } + setWidgetSprite(ivar3, new WidgetPointer(ivar4)); + if (((ivar0 == 1645) || (ivar0 == 1642)) || (ivar0 == 1643)) { + setWidgetContextMenuOption(1, new WidgetPointer(ivar10), ""); + setWidgetContextMenuOption(2, new WidgetPointer(ivar10), ""); + } else { + setWidgetContextMenuOption(1, new WidgetPointer(ivar10), "Summary"); + setWidgetContextMenuOption(2, new WidgetPointer(ivar10), "Pin/Unpin Task"); + } + if (standart_config_281 < 1000) { + setWidgetContextMenuOption(2, new WidgetPointer(ivar10), ""); + } + } + ivar2 = add(ivar2, 1); + } + setWidgetIsHidden(false, new WidgetPointer(1056,111)); + setWidgetIsHidden(false, new WidgetPointer(1056,112)); + if (bitconfig_8575 == 61) { + setWidgetText(new WidgetPointer(1056,110), "Quest Area"); + setWidgetIsHidden(true, new WidgetPointer(1056,111)); + setWidgetIsHidden(true, new WidgetPointer(1056,112)); + } else if (((boolean)bitconfig_9030)) { + setWidgetText(new WidgetPointer(1056,110), "Introductory Tasks"); + } else { + setWidgetText(new WidgetPointer(1056,110), cs2method_3408(105, 115, 3487, bitconfig_8575)); + } + script_3975(); + return; +} diff --git a/dumps/scripts/3972.cs2 b/dumps/scripts/3972.cs2 new file mode 100644 index 0000000..e4e8b2d --- /dev/null +++ b/dumps/scripts/3972.cs2 @@ -0,0 +1,4 @@ +void script_3972() { + script_3973(globalint_1428); + return; +} diff --git a/dumps/scripts/3973.cs2 b/dumps/scripts/3973.cs2 new file mode 100644 index 0000000..852f6de --- /dev/null +++ b/dumps/scripts/3973.cs2 @@ -0,0 +1,24 @@ +void script_3973(int arg0) { + setWidgetIsHidden(true, new WidgetPointer(1056,92)); + setWidgetIsHidden(true, new WidgetPointer(1056,94)); + setWidgetIsHidden(false, new WidgetPointer(1056,125)); + setWidgetIsHidden(false, new WidgetPointer(1056,122)); + if (((boolean)arg0)) { + script_3977(globalint_1425); + } else if (((boolean)script_3999(bitconfig_8576))) { + if (((boolean)script_3999(bitconfig_8588)) && ((boolean)script_3999(bitconfig_8587))) { + script_3977(bitconfig_8587); + } else { + setWidgetIsHidden(true, new WidgetPointer(1056,122)); + } + } else { + script_3977(bitconfig_8576); + } + script_3975(); + if (((boolean)globalint_1421)) { + setWidgetIsHidden(true, new WidgetPointer(1056,171)); + } else { + setWidgetIsHidden(false, new WidgetPointer(1056,171)); + } + return; +} diff --git a/dumps/scripts/3974.cs2 b/dumps/scripts/3974.cs2 new file mode 100644 index 0000000..41176d4 --- /dev/null +++ b/dumps/scripts/3974.cs2 @@ -0,0 +1,4 @@ +void script_3974() { + script_3975(); + return; +} diff --git a/dumps/scripts/3975.cs2 b/dumps/scripts/3975.cs2 new file mode 100644 index 0000000..056f3a5 --- /dev/null +++ b/dumps/scripts/3975.cs2 @@ -0,0 +1,33 @@ +void script_3975() { + int ivar0; + ivar0 = -1; + setWidgetIsHidden(true, new WidgetPointer(1056,63)); + setWidgetIsHidden(true, new WidgetPointer(1056,143)); + setWidgetIsHidden(true, new WidgetPointer(1056,148)); + setWidgetIsHidden(true, new WidgetPointer(1056,153)); + setWidgetIsHidden(true, new WidgetPointer(1056,158)); + setWidgetIsHidden(true, new WidgetPointer(1056,164)); + switch (bitconfig_8577) { + case 1: + ivar0 = 69206079; + break; + case 2: + ivar0 = 69206159; + break; + case 3: + ivar0 = 69206164; + break; + case 4: + ivar0 = 69206169; + break; + case 5: + ivar0 = 69206174; + break; + case 6: + ivar0 = 69206180; + } + if (ivar0 != -1) { + setWidgetIsHidden(false, new WidgetPointer(ivar0)); + } + return; +} diff --git a/dumps/scripts/3976.cs2 b/dumps/scripts/3976.cs2 new file mode 100644 index 0000000..1e8b366 --- /dev/null +++ b/dumps/scripts/3976.cs2 @@ -0,0 +1,21 @@ +void script_3976(int arg0,int arg1,int arg2) { + if (arg2 != 1) { + return; + } + script_41(69206179); + globalint_1416 = arg1; + setWidgetIsHidden(true, new WidgetPointer(1056,92)); + setWidgetIsHidden(true, new WidgetPointer(1056,94)); + setWidgetIsHidden(false, new WidgetPointer(1056,125)); + setWidgetIsHidden(false, new WidgetPointer(1056,122)); + if (((boolean)script_3999(arg0))) { + if (bitconfig_8588 == 4094) { + script_3977(bitconfig_8587); + } else { + return; + } + } else { + script_3977(arg0); + } + return; +} diff --git a/dumps/scripts/3977.cs2 b/dumps/scripts/3977.cs2 new file mode 100644 index 0000000..c97061b --- /dev/null +++ b/dumps/scripts/3977.cs2 @@ -0,0 +1,266 @@ +void script_3977(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + string svar0; + string svar1; + string svar2; + string svar3; + string svar4; + string svar5; + int stack_dump0; + cs2func_script_3995_struct(2,1,0) structdump_1; + script_41(69206152); + if (((boolean)arg0) && (standart_config_281 < 1000)) { + arg0 = 4094; + } + if (((boolean)script_3999(arg0))) { + return; + } + ivar1 = -1; + svar0 = ""; + svar1 = ""; + svar2 = ""; + ivar2 = -1; + ivar3 = -1; + ivar1 = cs2method_3408(105, 74, 3483, arg0); + ivar4 = add(multiply(subtract(getOtherCommonData(ivar1, 1293), 1), 5), getOtherCommonData(ivar1, 1272)); + ivar5 = cs2method_3408(105, 74, 3494, ivar4); + if (ivar1 != -1) { + svar0 = getOtherCommonData(ivar1, 1266); + svar1 = getOtherCommonData(ivar1, 1273); + if ((arg0 > 419) && (arg0 < 424)) { + svar1 = concat(svar1, "
" + "
" + "Click on the Hints tab above if you wish to see more information on how to complete this Task."); + } else { + if (arg0 == 419) { + svar1 = concat(svar1, "
" + "
" + "Simply click on Jack to start a conversation - as a new player you will start just nearby."); + } + } + if (getOtherCommonData(ivar1, 1270) != 4094) { + svar2 = getOtherCommonData(cs2method_3408(105, 74, 2252, getOtherCommonData(ivar1, 1270)), 951); + ivar3 = getOtherCommonData(cs2method_3408(105, 74, 2252, getOtherCommonData(ivar1, 1270)), 952); + } else { + svar2 = getOtherCommonData(ivar1, 1292); + ivar3 = getOtherCommonData(ivar1, 1271); + } + setWidgetSprite(ivar3, new WidgetPointer(1056,135)); + setWidgetText(new WidgetPointer(1056,91), svar0); + setWidgetText(new WidgetPointer(1056,129), svar1); + setWidgetFont(495, new WidgetPointer(1056,129)); + setWidgetTextAlignment(0, 0, 0, new WidgetPointer(1056,129)); + } + svar3 = ""; + if (((boolean)stringMethod4107(svar2, "")) && (standart_config_281 == 1000)) { + if (bitconfig_8601 < 10) { + svar3 = "ten"; + } else if (bitconfig_8601 < 25) { + svar3 = "forty"; + } else if (bitconfig_8601 < 50) { + svar3 = "160"; + } else if (bitconfig_8601 < 100) { + svar3 = "640"; + } else { + svar3 = "2560"; + } + svar2 = "Completing this Task will earn you " + svar3 + " coins."; + } + setWidgetIsHidden(true, new WidgetPointer(1056,76)); + setWidgetIsHidden(true, new WidgetPointer(1056,77)); + setWidgetIsHidden(true, new WidgetPointer(1056,78)); + setWidgetIsHidden(true, new WidgetPointer(1056,79)); + setWidgetIsHidden(true, new WidgetPointer(1056,80)); + setWidgetIsHidden(true, new WidgetPointer(1056,81)); + setWidgetIsHidden(true, new WidgetPointer(1056,82)); + setWidgetIsHidden(true, new WidgetPointer(1056,83)); + setWidgetIsHidden(true, new WidgetPointer(1056,84)); + setWidgetIsHidden(true, new WidgetPointer(1056,85)); + setWidgetIsHidden(true, new WidgetPointer(1056,86)); + setWidgetIsHidden(true, new WidgetPointer(1056,87)); + ivar6 = 10; + ivar7 = 0; + ivar8 = 15; + ivar9 = 0; + svar4 = ""; + ivar10 = 0; + stack_dump0 = arg0; + structdump_1 = script_3995(stack_dump0); + ivar10 = structdump_1.intpart_1; + svar4 = structdump_1.stringpart_0; + ivar9 = structdump_1.intpart_0; + if ((((boolean)getLanguage()) || (getLanguage() == 3)) || (getLanguage() == 2)) { + setWidgetIsHidden(true, new WidgetPointer(1056,121)); + setWidgetIsHidden(true, new WidgetPointer(1056,141)); + } else { + if (((boolean)getLanguage())) { + setWidgetText(new WidgetPointer(1056,120), " Pin"); + setWidgetText(new WidgetPointer(1056,140), " Back"); + } + setWidgetIsHidden(false, new WidgetPointer(1056,121)); + setWidgetIsHidden(false, new WidgetPointer(1056,141)); + } + setWidgetIsHidden(true, new WidgetPointer(1056,88)); + if (stringMethod4107(getOtherCommonData(ivar1, 1274), "") != 0) { + if (getOtherCommonData(ivar1, 1282) != -1) { + ivar7 = arg0; + } else { + ivar7 = 4094; + } + ivar6 = script_3978(1, ivar6, 69206092, ivar7, 69206093, 69206139, getOtherCommonData(ivar1, 1274)); + } + if (stringMethod4107(getOtherCommonData(ivar1, 1275), "") != 0) { + if (getOtherCommonData(ivar1, 1283) != -1) { + ivar7 = arg0; + } else { + ivar7 = 4094; + } + ivar6 = script_3978(2, ivar6, 69206094, ivar7, 69206095, 69206139, getOtherCommonData(ivar1, 1275)); + } + if (stringMethod4107(getOtherCommonData(ivar1, 1276), "") != 0) { + if (getOtherCommonData(ivar1, 1284) != -1) { + ivar7 = arg0; + } else { + ivar7 = 4094; + } + ivar6 = script_3978(3, ivar6, 69206096, ivar7, 69206097, 69206139, getOtherCommonData(ivar1, 1276)); + } + if (stringMethod4107(getOtherCommonData(ivar1, 1277), "") != 0) { + if (getOtherCommonData(ivar1, 1285) != -1) { + ivar7 = arg0; + } else { + ivar7 = 4094; + } + ivar6 = script_3978(4, ivar6, 69206098, ivar7, 69206099, 69206139, getOtherCommonData(ivar1, 1277)); + } + if (stringMethod4107(getOtherCommonData(ivar1, 1278), "") != 0) { + if (getOtherCommonData(ivar1, 1286) != -1) { + ivar7 = arg0; + } else { + ivar7 = 4094; + } + ivar6 = script_3978(5, ivar6, 69206100, ivar7, 69206101, 69206139, getOtherCommonData(ivar1, 1278)); + } + if (stringMethod4107(getOtherCommonData(ivar1, 1279), "") != 0) { + if (getOtherCommonData(ivar1, 1287) != -1) { + ivar7 = arg0; + } else { + ivar7 = 4094; + } + ivar6 = script_3978(6, ivar6, 69206102, ivar7, 69206103, 69206139, getOtherCommonData(ivar1, 1279)); + } + ivar6 = max(ivar6, getWidgetActualHeight(new WidgetPointer(1056,123))); + setWidgetScrollMax(0, ivar6, new WidgetPointer(1056,123)); + script_31(69206140, 69206139, 4343, 4340, 4341, 4342, 4337, 4336); + if (ivar6 > getWidgetActualHeight(new WidgetPointer(1056,123))) { + setWidgetIsHidden(false, new WidgetPointer(1056,124)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1056,124)); + } + setWidgetIsHidden(true, new WidgetPointer(1056,66)); + setWidgetIsHidden(true, new WidgetPointer(1056,67)); + setWidgetIsHidden(true, new WidgetPointer(1056,68)); + setWidgetIsHidden(true, new WidgetPointer(1056,69)); + setWidgetIsHidden(true, new WidgetPointer(1056,70)); + setWidgetIsHidden(true, new WidgetPointer(1056,71)); + setWidgetIsHidden(true, new WidgetPointer(1056,72)); + setWidgetIsHidden(true, new WidgetPointer(1056,73)); + ivar6 = script_3978(0, 10, 69206081, 4094, -1, 69206090, svar2); + if ((ivar5 != -1) && (ivar5 != 1645)) { + ivar6 = script_3978(0, ivar6, 69206082, 4094, -1, 69206090, getOtherCommonData(ivar5, 1273)); + ivar6 = script_3978(0, ivar6, 69206083, 4094, -1, 69206090, getOtherCommonData(ivar5, 1292)); + if (stringMethod4107(getOtherCommonData(ivar5, 1274), "") != 0) { + ivar6 = script_3978(0, ivar6, 69206084, 4094, -1, 69206090, getOtherCommonData(ivar5, 1274)); + } + if (stringMethod4107(getOtherCommonData(ivar5, 1275), "") != 0) { + ivar6 = script_3978(0, ivar6, 69206085, 4094, -1, 69206090, getOtherCommonData(ivar5, 1275)); + } + if (stringMethod4107(getOtherCommonData(ivar5, 1276), "") != 0) { + ivar6 = script_3978(0, ivar6, 69206086, 4094, -1, 69206090, getOtherCommonData(ivar5, 1276)); + } + if (stringMethod4107(getOtherCommonData(ivar5, 1277), "") != 0) { + ivar6 = script_3978(0, ivar6, 69206087, 4094, -1, 69206090, getOtherCommonData(ivar5, 1277)); + } + if (stringMethod4107(getOtherCommonData(ivar5, 1278), "") != 0) { + ivar6 = script_3978(0, ivar6, 69206088, 4094, -1, 69206090, getOtherCommonData(ivar5, 1278)); + } + if (stringMethod4107(getOtherCommonData(ivar5, 1279), "") != 0) { + ivar6 = script_3978(0, ivar6, 69206089, 4094, -1, 69206090, getOtherCommonData(ivar5, 1279)); + } + } else { + if (bitconfig_8601 > bitconfig_8602) { + svar2 = "You have already earned a sum of money, which you may claim by talking to any Taskmaster or you can increase by completing more Tasks."; + ivar6 = script_3978(0, ivar6, 69206083, 4094, -1, 69206090, svar2); + } + } + ivar6 = max(ivar6, getWidgetActualHeight(new WidgetPointer(1056,74))); + setWidgetScrollMax(0, ivar6, new WidgetPointer(1056,74)); + script_31(69206111, 69206090, 4343, 4340, 4341, 4342, 4337, 4336); + if (ivar6 > getWidgetActualHeight(new WidgetPointer(1056,74))) { + setWidgetIsHidden(false, new WidgetPointer(1056,95)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1056,95)); + } + svar5 = ""; + ivar11 = 5; + if (script_3227(arg0) == 2) { + setWidgetIsHidden(true, new WidgetPointer(1056,88)); + setWidgetIsHidden(true, new WidgetPointer(1056,90)); + if ((standart_config_281 == 1000) || ((boolean)bitconfig_9029)) { + setWidgetIsHidden(false, new WidgetPointer(1056,130)); + } + if ((arg0 == 419) && ((boolean)bitconfig_9030)) { + svar5 = "Task complete! Click here to return to the task list."; + if (getDisplayMode() >= 2) { + if (getWidgetActualWidth(new WidgetPointer(746,2)) < 997) { + ivar11 = add(ivar11, 40); + } + script_4248(158, ivar11, 1, 16777215, 5631, svar5); + } else { + script_4247(175, -1, 1, 16777215, 5631, svar5); + } + } + } else if (getOtherCommonData(ivar1, 1267) == 60) { + setWidgetIsHidden(true, new WidgetPointer(1056,88)); + setWidgetIsHidden(true, new WidgetPointer(1056,130)); + if ((standart_config_281 < 135) && ((boolean)bitconfig_9029)) { + setWidgetIsHidden(true, new WidgetPointer(1056,90)); + } else { + setWidgetIsHidden(false, new WidgetPointer(1056,90)); + } + } else { + setWidgetIsHidden(false, new WidgetPointer(1056,90)); + if ((((boolean)script_3999(arg0)) && ((boolean)ivar9)) && (arg0 != bitconfig_8576)) { + setWidgetIsHidden(false, new WidgetPointer(1056,88)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1056,88)); + } + if (((arg0 == 420) || (arg0 == 363)) || ((arg0 == 419) && (standart_config_281 == 1000))) { + svar5 = "Click on the Hints tab for more on how to complete this Task."; + } else if (arg0 == 421) { + svar5 = "Remember, the Hints tab provides more details about a Task."; + } else { + svar5 = ""; + } + if (((boolean)bitconfig_9030)) { + svar5 = ""; + } + if (getDisplayMode() >= 2) { + if (getWidgetActualWidth(new WidgetPointer(746,2)) < 997) { + script_4248(196, 223, 1, 16777215, 5631, svar5); + } else { + script_4248(196, 183, 1, 16777215, 5631, svar5); + } + } else { + script_4247(217, 177, 1, 16777215, 5631, svar5); + } + } + setWidgetSize(0, add(15, ivar6), 1, 0, new WidgetPointer(1056,96)); + return; +} diff --git a/dumps/scripts/3978.cs2 b/dumps/scripts/3978.cs2 new file mode 100644 index 0000000..0b41a41 --- /dev/null +++ b/dumps/scripts/3978.cs2 @@ -0,0 +1,31 @@ +int script_3978(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,string arg6) { + int ivar6; + int ivar7; + int ivar8; + setWidgetIsHidden(false, new WidgetPointer(arg2)); + setWidgetText(new WidgetPointer(arg2), arg6); + setWidgetFont(495, new WidgetPointer(arg2)); + setWidgetTextAlignment(0, 1, 0, new WidgetPointer(arg2)); + ivar6 = subtract(getWidgetActualWidth(new WidgetPointer(arg5)), 18); + if (((boolean)script_3999(arg3))) { + ivar6 = add(ivar6, 9); + } + ivar7 = 0; + if (arg4 != -1) { + ivar7 = getWidgetActualHeight(new WidgetPointer(arg4)); + ivar6 = subtract(ivar6, 21); + } + ivar8 = max(add(ivar7, 5), multiply(15, getLineCount(ivar6, 495, arg6))); + setWidgetSize(ivar6, ivar8, 0, 0, new WidgetPointer(arg2)); + setWidgetPosition(9, arg1, 0, 0, new WidgetPointer(arg2)); + if (((boolean)script_3999(arg3)) && (arg4 != -1)) { + setWidgetIsHidden(false, new WidgetPointer(arg4)); + setWidgetPosition(2, add(arg1, divide(subtract(ivar8, getWidgetActualHeight(new WidgetPointer(arg4))), 2)), 2, 0, new WidgetPointer(arg4)); + if ((bitconfig_8578 == arg0) && (bitconfig_8594 == arg3)) { + setWidgetSprite(5623, new WidgetPointer(arg4)); + } else { + setWidgetSprite(5621, new WidgetPointer(arg4)); + } + } + return add(arg1, ivar8); +} diff --git a/dumps/scripts/3979.cs2 b/dumps/scripts/3979.cs2 new file mode 100644 index 0000000..c0930cf --- /dev/null +++ b/dumps/scripts/3979.cs2 @@ -0,0 +1,35 @@ +void script_3979(int arg0,int arg1) { + int ivar2; + string svar0; + bitconfig_8576 = arg0; + ivar2 = cs2method_3408(105, 74, 3483, arg0); + svar0 = " -" + "
"; + svar0 = concat(getOtherCommonData(ivar2, 1266), svar0); + svar0 = concat(svar0, getOtherCommonData(ivar2, 1273)); + if (((boolean)script_3999(arg0))) { + setScriptCallOnMouseOver(3981, new WidgetPointer(arg1), svar0, "Is", new WidgetPointer(arg1)); + } else { + setScriptCallOnMouseOver(-1, "", new WidgetPointer(arg1)); + } + switch (arg1) { + case 69206080: + bitconfig_8577 = 1; + break; + case 69206160: + bitconfig_8577 = 2; + break; + case 69206165: + bitconfig_8577 = 3; + break; + case 69206170: + bitconfig_8577 = 4; + break; + case 69206175: + bitconfig_8577 = 5; + break; + case 69206181: + bitconfig_8577 = 6; + } + script_3975(); + return; +} diff --git a/dumps/scripts/398.cs2 b/dumps/scripts/398.cs2 new file mode 100644 index 0000000..b440bf6 --- /dev/null +++ b/dumps/scripts/398.cs2 @@ -0,0 +1,44 @@ +void script_398() { + setWidgetNoOptions(new WidgetPointer(306,29)); + globalint_767 = 0; + globalint_761 = -1; + globalint_762 = -1; + globalint_763 = -1; + globalint_764 = -1; + globalint_765 = 0; + globalint_766 = 0; + setScriptCallOnGameloop(-1, "", new WidgetPointer(306,19)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(306,20)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(306,21)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(306,22)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(306,10)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(306,25)); + setWidgetText(new WidgetPointer(306,3), "Correct: " + intToStr(globalint_767) + "/" + intToStr(10)); + globalint_761 = cs2method_3408(105, 109, 208, 1); + if (globalint_761 != -1) { + setWidgetModel(globalint_761, new WidgetPointer(306,6)); + setWidget3DRotation(0, 0, 512, 0, 0, 800, new WidgetPointer(306,6)); + } + globalint_762 = cs2method_3408(105, 109, 208, 2); + if (globalint_762 != -1) { + setWidgetModel(globalint_762, new WidgetPointer(306,7)); + setWidget3DRotation(0, 0, 512, 0, 0, 800, new WidgetPointer(306,7)); + } + globalint_763 = cs2method_3408(105, 109, 208, 3); + if (globalint_763 != -1) { + setWidgetModel(globalint_763, new WidgetPointer(306,8)); + setWidget3DRotation(0, 0, 512, 0, 0, 800, new WidgetPointer(306,8)); + } + globalint_764 = cs2method_3408(105, 109, 208, 4); + if (globalint_764 != -1) { + setWidgetModel(globalint_764, new WidgetPointer(306,9)); + setWidget3DRotation(0, 0, 512, 0, 0, 800, new WidgetPointer(306,9)); + } + setWidgetPosition(subtract(0, getWidgetActualWidth(new WidgetPointer(306,6))), getWidgetActualY(new WidgetPointer(306,6)), 0, 0, new WidgetPointer(306,6)); + setWidgetPosition(subtract(0, getWidgetActualWidth(new WidgetPointer(306,7))), getWidgetActualY(new WidgetPointer(306,7)), 0, 0, new WidgetPointer(306,7)); + setWidgetPosition(subtract(0, getWidgetActualWidth(new WidgetPointer(306,8))), getWidgetActualY(new WidgetPointer(306,8)), 0, 0, new WidgetPointer(306,8)); + setWidgetPosition(subtract(0, getWidgetActualWidth(new WidgetPointer(306,9))), getWidgetActualY(new WidgetPointer(306,9)), 0, 0, new WidgetPointer(306,9)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(306,5)), 200, 0, 0, new WidgetPointer(306,10)); + setScriptCallOnGameloop(399, new WidgetPointer(306,6), "I", new WidgetPointer(306,19)); + return; +} diff --git a/dumps/scripts/3980.cs2 b/dumps/scripts/3980.cs2 new file mode 100644 index 0000000..616672a --- /dev/null +++ b/dumps/scripts/3980.cs2 @@ -0,0 +1,6 @@ +void script_3980() { + bitconfig_8576 = 4095; + bitconfig_8577 = 0; + script_3975(); + return; +} diff --git a/dumps/scripts/3981.cs2 b/dumps/scripts/3981.cs2 new file mode 100644 index 0000000..079098b --- /dev/null +++ b/dumps/scripts/3981.cs2 @@ -0,0 +1,4 @@ +void script_3981(int arg0,string arg1) { + script_3982(arg0, arg1); + return; +} diff --git a/dumps/scripts/3982.cs2 b/dumps/scripts/3982.cs2 new file mode 100644 index 0000000..170e349 --- /dev/null +++ b/dumps/scripts/3982.cs2 @@ -0,0 +1,95 @@ +void script_3982(int arg0,string arg1) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + ivar4 = 0; + ivar5 = 0; + ivar6 = 0; + ivar7 = 178; + ivar8 = 69206179; + ivar9 = 0; + ivar10 = 0; + ivar11 = -1; + if (setWidgetRegister(new WidgetPointer(arg0))) { + if (globalint_1 < add(getClientCycle(), 45)) { + if (globalint_1 < getClientCycle()) { + globalint_1 = getClientCycle(); + } + globalint_1 = add(globalint_1, 2); + return; + } + globalint_1 = add(getClientCycle(), 55); + if (globalint_2 != 1) { + ivar1 = add(getWidgetActualX(), 5); + ivar2 = add(add(getWidgetActualY(), getWidgetActualHeight()), 5); + ivar11 = 69206114; + if ((ivar11 != -1) && (ivar7 >= getWidgetActualWidth(new WidgetPointer(ivar11)))) { + ivar7 = getWidgetActualWidth(new WidgetPointer(ivar11)); + } + ivar9 = add(4, getMaxLineWidth(subtract(ivar7, 4), 495, arg1)); + ivar10 = add(4, multiply(16, getLineCount(subtract(ivar7, 4), 495, arg1))); + if (ivar11 != -1) { + ivar3 = subtract(ivar1, cs2method2600(new WidgetPointer(ivar11))); + ivar4 = subtract(ivar2, cs2method2601(new WidgetPointer(ivar11))); + if (ivar3 < 0) { + ivar1 = cs2method2600(new WidgetPointer(ivar11)); + ivar3 = 0; + } + if (ivar4 < 0) { + ivar2 = cs2method2601(new WidgetPointer(ivar11)); + ivar4 = 0; + } + if (ivar3 > 0) { + ivar5 = add(subtract(ivar3, getWidgetActualWidth(new WidgetPointer(ivar11))), ivar9); + if (ivar5 > 0) { + ivar1 = subtract(ivar1, ivar5); + } + } + if (ivar4 > 0) { + ivar6 = add(subtract(ivar4, getWidgetActualHeight(new WidgetPointer(ivar11))), ivar10); + if (ivar6 > 0) { + ivar2 = subtract(subtract(subtract(ivar2, ivar6), getWidgetActualHeight()), 10); + } + } + } + if (ivar1 < 0) { + ivar1 = 0; + } + if (ivar2 < 0) { + ivar2 = 0; + } + setWidgetSize(ivar9, ivar10, 0, 0, new WidgetPointer(ivar8)); + setWidgetPosition(ivar1, ivar2, 0, 0, new WidgetPointer(ivar8)); + deleteAllExtraChilds(new WidgetPointer(ivar8)); + createExtraChild(new WidgetPointer(ivar8), 3, 0); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(ivar8)), getWidgetActualHeight(new WidgetPointer(ivar8)), 0, 0); + setWidgetFilled(1); + setWidgetRGB(new Color(0, 0, 0)); + cs2method2103(80); + createExtraChild(new WidgetPointer(ivar8), 3, 1); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(ivar8)), getWidgetActualHeight(new WidgetPointer(ivar8)), 0, 0); + setWidgetFilled(0); + setWidgetRGB(new Color(0, 0, 0)); + createExtraChild(new WidgetPointer(ivar8), 4, 2); + setWidgetSize(subtract(ivar7, 4), getWidgetActualHeight(new WidgetPointer(ivar8)), 0, 0); + setWidgetPosition(2, 0, 0, 0); + setWidgetText(arg1); + setWidgetTextAlignment(0, 1, 16); + setWidgetFont(495); + setWidgetRGB(new Color(238, 238, 238)); + globalint_2 = 1; + } + } + return; +} diff --git a/dumps/scripts/3983.cs2 b/dumps/scripts/3983.cs2 new file mode 100644 index 0000000..d305110 --- /dev/null +++ b/dumps/scripts/3983.cs2 @@ -0,0 +1,6 @@ +void script_3983(int arg0,int arg1,int arg2) { + script_41(60096609); + script_4022(0); + script_3987(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/3984.cs2 b/dumps/scripts/3984.cs2 new file mode 100644 index 0000000..2b53732 --- /dev/null +++ b/dumps/scripts/3984.cs2 @@ -0,0 +1,6 @@ +void script_3984(int arg0,int arg1,int arg2) { + script_4022(0); + script_3987(arg0, arg1, arg2); + setWidgetIsHidden(true, new WidgetPointer(917,92)); + return; +} diff --git a/dumps/scripts/3985.cs2 b/dumps/scripts/3985.cs2 new file mode 100644 index 0000000..7278009 --- /dev/null +++ b/dumps/scripts/3985.cs2 @@ -0,0 +1,9 @@ +void script_3985() { + int ivar0; + ivar0 = 0; + if (((boolean)bitconfig_8579)) { + ivar0 = 1; + } + script_3987(999, ivar0, 999); + return; +} diff --git a/dumps/scripts/3986.cs2 b/dumps/scripts/3986.cs2 new file mode 100644 index 0000000..a211156 --- /dev/null +++ b/dumps/scripts/3986.cs2 @@ -0,0 +1,9 @@ +void script_3986() { + int ivar0; + ivar0 = 0; + if (((boolean)bitconfig_8580)) { + ivar0 = 1; + } + script_3987(999, 999, ivar0); + return; +} diff --git a/dumps/scripts/3987.cs2 b/dumps/scripts/3987.cs2 new file mode 100644 index 0000000..3e815e5 --- /dev/null +++ b/dumps/scripts/3987.cs2 @@ -0,0 +1,51 @@ +void script_3987(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + if (arg0 == 63) { + arg0 = bitconfig_8575; + } else { + if (arg0 == 999) { + arg0 = bitconfig_8582; + } + } + if (arg1 == 999) { + arg1 = bitconfig_8579; + } + if (arg2 == 999) { + arg2 = bitconfig_8580; + } + script_4017(arg0); + setWidgetSprite(cs2method_3408(105, 100, 3491, arg0), new WidgetPointer(917,120)); + setWidgetText(new WidgetPointer(917,121), cs2method_3408(105, 115, 3487, arg0)); + setWidgetIsHidden(false, new WidgetPointer(917,121)); + if (setWidgetRegister(new WidgetPointer(917,105))) { + cs2method1309(1, 172); + } + if (setWidgetRegister(new WidgetPointer(917,117))) { + cs2method1309(1, 56); + } + if (setWidgetRegister(new WidgetPointer(917,121))) { + cs2method1309(1, 56); + } + globalint_1422 = -1; + ivar3 = cs2method_3408(105, 105, 3482, arg0); + deleteAllExtraChilds(new WidgetPointer(917,98)); + setWidgetIsHidden(true, new WidgetPointer(917,119)); + setWidgetIsHidden(true, new WidgetPointer(917,115)); + ivar4 = 0; + setWidgetIsHidden(false, new WidgetPointer(917,91)); + if (((boolean)bitconfig_9030)) { + ivar4 = script_4243(); + setWidgetIsHidden(true, new WidgetPointer(917,91)); + } else if (ivar3 == 4091) { + ivar4 = script_3988(arg0); + } else { + ivar4 = script_3989(ivar3, arg1, arg2); + } + ivar5 = add(ivar4, getWidgetActualHeight(new WidgetPointer(917,99))); + ivar5 = max(ivar5, getWidgetActualHeight(new WidgetPointer(917,98))); + setWidgetScrollMax(0, ivar5, new WidgetPointer(917,98)); + script_31(60096612, 60096610, 4343, 4340, 4341, 4342, 4337, 4336); + return; +} diff --git a/dumps/scripts/3988.cs2 b/dumps/scripts/3988.cs2 new file mode 100644 index 0000000..f2d905a --- /dev/null +++ b/dumps/scripts/3988.cs2 @@ -0,0 +1,122 @@ +int script_3988(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + string svar0; + string svar1; + ivar1 = multiply(6, subtract(arg0, 1)); + ivar2 = 0; + ivar3 = 0; + ivar4 = -1; + svar0 = ""; + svar1 = ""; + ivar5 = 0; + ivar6 = -1; + ivar7 = -1; + ivar8 = 0; + ivar9 = 0; + ivar10 = 3484; + ivar11 = -1; + ivar12 = -1; + ivar13 = 0; + ivar14 = 23; + ivar15 = 23; + ivar16 = 0; + while (ivar9 < add(getCommonDefinitionSize(3485), 6)) { + ivar2 = cs2method_3408(105, 105, ivar10, ivar1); + ivar4 = cs2method_3408(105, 74, 3483, ivar2); + if (ivar4 == 1643) { + ivar1 = 0; + if (ivar10 == 3484) { + ivar10 = 3485; + } else { + return ivar15; + } + } else { + if (ivar4 != -1) { + svar0 = getOtherCommonData(ivar4, 1266); + ivar6 = getOtherCommonData(ivar4, 1271); + createExtraChild(new WidgetPointer(917,98), 5, ivar8); + ivar12 = 4041; + ivar11 = 4042; + setWidgetSprite(ivar12); + setScriptCallOnMouseEntered(4013, -2147483643, ivar11, "id"); + setScriptCallOnMouseExit(4013, -2147483643, ivar12, "id"); + setWidgetSize(add(70, 2), add(56, 1), 0, 0); + setWidgetPosition(subtract(ivar14, 1), subtract(ivar15, 1), 0, 0); + setWidgetContextMenuOption(1, "Summary for"); + if (bitconfig_8576 == ivar2) { + setWidgetContextMenuOption(2, "Unpin"); + } else { + if (script_3227(ivar2) != 2) { + setWidgetContextMenuOption(2, "Pin"); + } + } + cs2method1305(svar0); + setScriptCallOnClickContextMenu(3990, ivar2, -2147483643, -2147483644, "iii"); + if (((boolean)script_3999(ivar2))) { + svar1 = " -" + "
"; + svar1 = concat(getOtherCommonData(ivar4, 1266), svar1); + svar1 = concat(svar1, getOtherCommonData(ivar4, 1273)); + setScriptCallOnMouseOver(3998, ivar8, svar1, "is"); + } + if (((boolean)script_3994(ivar2)) && (ivar2 != 4094)) { + globalint_1422 = ivar8; + } + createExtraChild(new WidgetPointer(917,98), 5, add(ivar8, 1)); + setWidgetSize(50, 50, 0, 0); + setWidgetSprite(ivar6); + setWidgetPosition(add(ivar14, 2), add(ivar15, 2), 0, 0); + cs2method2103(ivar16); + createExtraChild(new WidgetPointer(917,98), 5, add(ivar8, 2)); + setWidgetSize(14, 18, 0, 0); + if (((boolean)script_3996(ivar2))) { + ivar7 = 4346; + setWidgetSize(11, 11, 0, 0); + } else { + ivar7 = -1; + } + setWidgetSprite(ivar7); + setWidgetPosition(subtract(add(ivar14, 70), 16), add(ivar15, 4), 0, 0); + createExtraChild(new WidgetPointer(917,98), 5, add(ivar8, 3)); + setWidgetSize(11, 11, 0, 0); + setWidgetPosition(subtract(add(ivar14, 70), 17), add(ivar15, 39), 0, 0); + if (((boolean)script_3994(ivar2))) { + setWidgetSprite(4296); + } + ivar9 = add(ivar9, 1); + ivar8 = multiply(ivar9, 4); + ivar14 = add(add(ivar14, 70), 23); + ivar13 = mod(add(ivar13, 1), 5); + if (((boolean)ivar13)) { + ivar15 = add(add(ivar15, 56), 23); + ivar14 = 23; + } + } + } + ivar1 = add(ivar1, 1); + if ((ivar10 == 3484) && (ivar1 == add(multiply(6, subtract(arg0, 1)), 5))) { + ivar1 = 1; + ivar10 = 3485; + } + } + if (ivar13 != 0) { + ivar15 = add(ivar15, 56); + } else { + ivar15 = subtract(ivar15, 23); + } + return ivar15; +} diff --git a/dumps/scripts/3989.cs2 b/dumps/scripts/3989.cs2 new file mode 100644 index 0000000..949a2e3 --- /dev/null +++ b/dumps/scripts/3989.cs2 @@ -0,0 +1,130 @@ +int script_3989(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + string svar0; + string svar1; + ivar3 = -1; + ivar4 = 0; + ivar5 = 0; + svar0 = ""; + svar1 = ""; + ivar6 = 0; + ivar7 = 0; + ivar8 = -1; + ivar9 = -1; + ivar10 = 0; + ivar11 = 0; + ivar12 = -1; + ivar13 = -1; + ivar14 = 0; + ivar15 = 23; + ivar16 = 0; + ivar17 = 23; + ivar18 = 0; + while ((arg0 != 450) && (arg0 != 4094)) { + ivar3 = cs2method_3408(105, 74, 3483, arg0); + if (ivar3 != -1) { + ivar4 = script_3227(arg0); + ivar5 = getOtherCommonData(ivar3, 1293); + if (((ivar4 != 2) || ((boolean)arg1)) && ((ivar5 != 63) || ((boolean)arg2))) { + svar0 = getOtherCommonData(ivar3, 1266); + ivar6 = getOtherCommonData(ivar3, 1267); + ivar7 = getOtherCommonData(ivar3, 1272); + if (getOtherCommonData(ivar3, 1270) != 4094) { + ivar8 = getOtherCommonData(cs2method_3408(105, 74, 2252, getOtherCommonData(ivar3, 1270)), 952); + } else { + ivar8 = getOtherCommonData(ivar3, 1271); + } + createExtraChild(new WidgetPointer(917,98), 5, ivar10); + if (ivar4 == 2) { + ivar13 = 4043; + ivar12 = 4043; + } else { + ivar13 = 4041; + ivar12 = 4042; + } + setWidgetSprite(ivar13); + setScriptCallOnMouseEntered(4013, -2147483643, ivar12, "id"); + setScriptCallOnMouseExit(4013, -2147483643, ivar13, "id"); + setWidgetSize(add(70, 2), add(56, 1), 0, 0); + setWidgetPosition(subtract(ivar15, 1), subtract(ivar17, 1), 0, 0); + setWidgetContextMenuOption(1, "Summary for"); + if (bitconfig_8576 == arg0) { + setWidgetContextMenuOption(2, "Unpin"); + } else { + if (script_3227(arg0) != 2) { + setWidgetContextMenuOption(2, "Pin"); + } + } + cs2method1305(svar0); + setScriptCallOnClickContextMenu(3990, arg0, -2147483643, -2147483644, "iii"); + if (((boolean)script_3999(arg0))) { + svar1 = " -" + "
"; + svar1 = concat(getOtherCommonData(ivar3, 1266), svar1); + svar1 = concat(svar1, getOtherCommonData(ivar3, 1273)); + setScriptCallOnMouseOver(3998, ivar10, svar1, "is"); + } + if (((boolean)script_3994(arg0)) && (arg0 != 4094)) { + globalint_1422 = ivar10; + } + createExtraChild(new WidgetPointer(917,98), 5, add(ivar10, 1)); + setWidgetSize(50, 50, 0, 0); + setWidgetSprite(ivar8); + setWidgetPosition(add(ivar15, 2), add(ivar17, 2), 0, 0); + cs2method2103(ivar18); + createExtraChild(new WidgetPointer(917,98), 5, add(ivar10, 2)); + if ((ivar5 != 0) && (ivar5 != 63)) { + ivar9 = 4272; + setWidgetSize(13, 13, 0, 0); + setWidgetSprite(ivar9); + setWidgetPosition(subtract(add(ivar15, 70), 17), add(ivar17, 4), 0, 0); + } + createExtraChild(new WidgetPointer(917,98), 5, add(ivar10, 3)); + if (((boolean)script_3994(arg0))) { + ivar9 = 4296; + setWidgetSize(11, 11, 0, 0); + ivar16 = 17; + } else if (((boolean)script_3996(arg0))) { + ivar9 = 4346; + setWidgetSize(11, 11, 0, 0); + ivar16 = 16; + } else { + ivar9 = cs2method_3408(105, 100, 3492, ivar7); + setWidgetSize(9, 11, 0, 0); + ivar16 = 15; + } + setWidgetSprite(ivar9); + setWidgetPosition(subtract(add(ivar15, 70), ivar16), add(ivar17, 39), 0, 0); + ivar11 = add(ivar11, 1); + ivar10 = multiply(ivar11, 4); + ivar15 = add(add(ivar15, 70), 23); + ivar14 = mod(add(ivar14, 1), 5); + if (((boolean)ivar14)) { + ivar17 = add(add(ivar17, 56), 23); + ivar15 = 23; + } + } + } + arg0 = getOtherCommonData(ivar3, 1269); + } + if (ivar14 != 0) { + ivar17 = add(ivar17, 56); + } else { + ivar17 = subtract(ivar17, 23); + } + return ivar17; +} diff --git a/dumps/scripts/399.cs2 b/dumps/scripts/399.cs2 new file mode 100644 index 0000000..7bc3e6c --- /dev/null +++ b/dumps/scripts/399.cs2 @@ -0,0 +1,11 @@ +void script_399(int arg0) { + if ((getWidgetActualX(new WidgetPointer(arg0)) < subtract(getWidgetActualWidth(new WidgetPointer(306,1)), 1)) || (subtract(getWidgetActualY(new WidgetPointer(arg0)), getWidgetActualHeight(new WidgetPointer(arg0))) > 110)) { + if (getWidgetActualX(new WidgetPointer(arg0)) == add(140, getWidgetActualWidth(new WidgetPointer(arg0)))) { + setScriptCallOnGameloop(1550, new WidgetPointer(306,7), "I", new WidgetPointer(306,20)); + } + setWidgetPosition(add(1, getWidgetActualX(new WidgetPointer(arg0))), getWidgetActualY(new WidgetPointer(arg0)), 0, 0, new WidgetPointer(arg0)); + } else { + script_1411(); + } + return; +} diff --git a/dumps/scripts/3990.cs2 b/dumps/scripts/3990.cs2 new file mode 100644 index 0000000..bbef85c --- /dev/null +++ b/dumps/scripts/3990.cs2 @@ -0,0 +1,15 @@ +void script_3990(int arg0,int arg1,int arg2) { + int ivar3; + if (arg2 != 1) { + return; + } + script_41(60096664); + ivar3 = script_3227(arg0); + if (ivar3 == 2) { + script_4014(arg1, 4043); + } else { + script_4014(arg1, 4041); + } + script_3991(arg0); + return; +} diff --git a/dumps/scripts/3991.cs2 b/dumps/scripts/3991.cs2 new file mode 100644 index 0000000..1e84194 --- /dev/null +++ b/dumps/scripts/3991.cs2 @@ -0,0 +1,240 @@ +void script_3991(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + string svar0; + string svar1; + string svar2; + string svar3; + string svar4; + string svar5; + string svar6; + int stack_dump0; + cs2func_script_3995_struct(2,1,0) structdump_1; + ivar1 = -1; + ivar2 = 0; + ivar3 = -1; + if (arg0 == 4095) { + arg0 = 4094; + } + svar0 = ""; + svar1 = ""; + svar2 = ""; + ivar4 = -1; + svar3 = ""; + ivar5 = -1; + svar4 = ""; + ivar6 = -1; + ivar7 = 0; + ivar8 = 0; + ivar1 = cs2method_3408(105, 74, 3483, arg0); + if (ivar1 != -1) { + svar0 = getOtherCommonData(ivar1, 1266); + svar1 = getOtherCommonData(ivar1, 1273); + ivar8 = getOtherCommonData(ivar1, 1293); + ivar7 = script_3227(arg0); + ivar2 = add(multiply(subtract(getOtherCommonData(ivar1, 1293), 1), 5), getOtherCommonData(ivar1, 1272)); + ivar3 = cs2method_3408(105, 74, 3494, ivar2); + ivar5 = cs2method_3408(105, 100, 3491, getOtherCommonData(ivar1, 1267)); + ivar4 = cs2method_3408(105, 100, 3492, getOtherCommonData(ivar1, 1272)); + svar3 = concat("Difficulty : ", cs2method_3408(105, 115, 3488, getOtherCommonData(ivar1, 1272))); + svar4 = concat("Area : ", cs2method_3408(105, 115, 3487, getOtherCommonData(ivar1, 1267))); + if (getOtherCommonData(ivar1, 1270) != 4094) { + ivar6 = getOtherCommonData(cs2method_3408(105, 74, 2252, getOtherCommonData(ivar1, 1270)), 952); + svar2 = getOtherCommonData(cs2method_3408(105, 74, 2252, getOtherCommonData(ivar1, 1270)), 951); + } else { + ivar6 = getOtherCommonData(ivar1, 1271); + svar2 = getOtherCommonData(ivar1, 1292); + } + } else { + svar0 = "Couldn't find the Task's struct."; + svar1 = "Couldn't find the Task's struct."; + svar2 = "Couldn't find the Task's struct."; + } + setWidgetText(new WidgetPointer(917,34), svar0); + setWidgetText(new WidgetPointer(917,63), svar1); + svar5 = ""; + if (((boolean)stringMethod4107(svar2, ""))) { + if (bitconfig_8601 < 10) { + svar5 = "ten"; + } else if (bitconfig_8601 < 25) { + svar5 = "forty"; + } else if (bitconfig_8601 < 50) { + svar5 = "160"; + } else if (bitconfig_8601 < 100) { + svar5 = "640"; + } else { + svar5 = "2560"; + } + svar2 = "Completing this Task will earn you " + svar5 + " coins."; + } + setWidgetText(new WidgetPointer(917,50), svar2); + setWidgetFont(495, new WidgetPointer(917,50)); + setWidgetTextAlignment(0, 1, 0, new WidgetPointer(917,50)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(917,50)), getLineCount(getWidgetActualWidth(new WidgetPointer(917,50)), 495, svar1), 0, 0, new WidgetPointer(917,50)); + setWidgetSprite(ivar6, new WidgetPointer(917,37)); + setWidgetSprite(ivar5, new WidgetPointer(917,39)); + setWidgetSprite(ivar4, new WidgetPointer(917,36)); + setWidgetText(new WidgetPointer(917,35), svar3); + setWidgetText(new WidgetPointer(917,38), svar4); + setWidgetIsHidden(true, new WidgetPointer(917,155)); + setWidgetIsHidden(true, new WidgetPointer(917,156)); + setWidgetIsHidden(true, new WidgetPointer(917,157)); + setWidgetIsHidden(true, new WidgetPointer(917,158)); + setWidgetIsHidden(true, new WidgetPointer(917,159)); + setWidgetIsHidden(true, new WidgetPointer(917,160)); + setWidgetIsHidden(true, new WidgetPointer(917,161)); + setWidgetIsHidden(true, new WidgetPointer(917,162)); + setWidgetIsHidden(true, new WidgetPointer(917,163)); + setWidgetIsHidden(true, new WidgetPointer(917,164)); + ivar9 = 0; + svar6 = ""; + ivar10 = 0; + stack_dump0 = arg0; + structdump_1 = script_3995(stack_dump0); + ivar10 = structdump_1.intpart_1; + svar6 = structdump_1.stringpart_0; + ivar9 = structdump_1.intpart_0; + setWidgetText(new WidgetPointer(917,1), svar6); + setWidgetRGB(new Color(ivar10), new WidgetPointer(917,1)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(917,1)), getLineCount(getWidgetActualWidth(new WidgetPointer(917,1)), 495, svar1), 0, 0, new WidgetPointer(917,1)); + setWidgetPosition(9, 16, 0, 0, new WidgetPointer(917,1)); + if (((boolean)ivar9) && (script_3227(arg0) != 2)) { + setWidgetIsHidden(false, new WidgetPointer(917,41)); + } else { + setWidgetIsHidden(true, new WidgetPointer(917,41)); + } + ivar11 = 34; + ivar12 = ivar11; + ivar13 = 0; + while (ivar13 < 10) { + ivar12 = script_3222(ivar11, arg0, ivar13, ((int)cs2method_3408(105, 73, 3493, ivar13))); + if (ivar12 == ivar11) { + ivar13 = 10; + } else { + ivar13 = add(ivar13, 1); + ivar11 = ivar12; + } + } + globalint_1420 = add(ivar11, 3); + ivar14 = 4094; + setWidgetIsHidden(true, new WidgetPointer(917,2)); + setWidgetIsHidden(true, new WidgetPointer(917,3)); + setWidgetIsHidden(true, new WidgetPointer(917,4)); + setWidgetIsHidden(true, new WidgetPointer(917,5)); + setWidgetIsHidden(true, new WidgetPointer(917,6)); + setWidgetIsHidden(true, new WidgetPointer(917,7)); + setWidgetIsHidden(true, new WidgetPointer(917,8)); + setWidgetIsHidden(true, new WidgetPointer(917,9)); + setWidgetIsHidden(true, new WidgetPointer(917,10)); + setWidgetIsHidden(true, new WidgetPointer(917,11)); + setWidgetIsHidden(true, new WidgetPointer(917,12)); + setWidgetIsHidden(true, new WidgetPointer(917,13)); + ivar11 = 10; + if ((stringMethod4107(getOtherCommonData(ivar1, 1274), "") != 0) && (arg0 != 4095)) { + if (getOtherCommonData(ivar1, 1282) != -1) { + ivar14 = arg0; + } + ivar11 = script_3992(1, ivar11, 60096514, ivar14, 60096515, 60096593, getOtherCommonData(ivar1, 1274)); + } + ivar14 = 4094; + if ((stringMethod4107(getOtherCommonData(ivar1, 1275), "") != 0) && (arg0 != 4095)) { + if (getOtherCommonData(ivar1, 1283) != -1) { + ivar14 = arg0; + } + ivar11 = script_3992(2, ivar11, 60096516, ivar14, 60096517, 60096593, getOtherCommonData(ivar1, 1275)); + } + ivar14 = 4094; + if ((stringMethod4107(getOtherCommonData(ivar1, 1276), "") != 0) && (arg0 != 4095)) { + if (getOtherCommonData(ivar1, 1284) != -1) { + ivar14 = arg0; + } + ivar11 = script_3992(3, ivar11, 60096518, ivar14, 60096519, 60096593, getOtherCommonData(ivar1, 1276)); + } + ivar14 = 4094; + if ((stringMethod4107(getOtherCommonData(ivar1, 1277), "") != 0) && (arg0 != 4095)) { + if (getOtherCommonData(ivar1, 1285) != -1) { + ivar14 = arg0; + } + ivar11 = script_3992(4, ivar11, 60096520, ivar14, 60096521, 60096593, getOtherCommonData(ivar1, 1277)); + } + ivar14 = 4094; + if ((stringMethod4107(getOtherCommonData(ivar1, 1278), "") != 0) && (arg0 != 4095)) { + if (getOtherCommonData(ivar1, 1286) != -1) { + ivar14 = arg0; + } + ivar11 = script_3992(5, ivar11, 60096522, ivar14, 60096523, 60096593, getOtherCommonData(ivar1, 1278)); + } + ivar14 = 4094; + if ((stringMethod4107(getOtherCommonData(ivar1, 1279), "") != 0) && (arg0 != 4095)) { + if (getOtherCommonData(ivar1, 1287) != -1) { + ivar14 = arg0; + } + ivar11 = script_3992(6, ivar11, 60096524, ivar14, 60096525, 60096593, getOtherCommonData(ivar1, 1279)); + } + globalint_1418 = add(ivar11, 3); + setWidgetIsHidden(true, new WidgetPointer(917,51)); + setWidgetIsHidden(true, new WidgetPointer(917,52)); + setWidgetIsHidden(true, new WidgetPointer(917,53)); + setWidgetIsHidden(true, new WidgetPointer(917,54)); + setWidgetIsHidden(true, new WidgetPointer(917,55)); + setWidgetIsHidden(true, new WidgetPointer(917,56)); + setWidgetIsHidden(true, new WidgetPointer(917,57)); + setWidgetIsHidden(true, new WidgetPointer(917,58)); + ivar11 = 10; + ivar11 = script_3992(0, ivar11, 60096562, 4094, -1, 60096597, svar2); + if ((ivar3 != -1) && (ivar3 != 1645)) { + ivar11 = script_3992(0, ivar11, 60096563, 4094, -1, 60096597, getOtherCommonData(ivar3, 1273)); + ivar11 = script_3992(0, ivar11, 60096564, 4094, -1, 60096597, getOtherCommonData(ivar3, 1292)); + if (stringMethod4107(getOtherCommonData(ivar3, 1274), "") != 0) { + ivar11 = script_3992(0, ivar11, 60096565, 4094, -1, 60096597, getOtherCommonData(ivar3, 1274)); + } + if (stringMethod4107(getOtherCommonData(ivar3, 1275), "") != 0) { + ivar11 = script_3992(0, ivar11, 60096566, 4094, -1, 60096597, getOtherCommonData(ivar3, 1275)); + } + if (stringMethod4107(getOtherCommonData(ivar3, 1276), "") != 0) { + ivar11 = script_3992(0, ivar11, 60096567, 4094, -1, 60096597, getOtherCommonData(ivar3, 1276)); + } + if (stringMethod4107(getOtherCommonData(ivar3, 1277), "") != 0) { + ivar11 = script_3992(0, ivar11, 60096568, 4094, -1, 60096597, getOtherCommonData(ivar3, 1277)); + } + if (stringMethod4107(getOtherCommonData(ivar3, 1278), "") != 0) { + ivar11 = script_3992(0, ivar11, 60096569, 4094, -1, 60096597, getOtherCommonData(ivar3, 1278)); + } + if (stringMethod4107(getOtherCommonData(ivar3, 1279), "") != 0) { + ivar11 = script_3992(0, ivar11, 60096570, 4094, -1, 60096597, getOtherCommonData(ivar3, 1279)); + } + } else { + if (bitconfig_8601 > bitconfig_8602) { + svar2 = "You're already owed a reward! You may claim it from Explorer Jack or any other taskmaster, or increase it by completing more Tasks. "; + if (standart_config_1959 > 0) { + svar2 = concat(svar2, "You are also owed one or more items."); + } + ivar11 = script_3992(0, ivar11, 60096564, 4094, -1, 60096597, svar2); + } + } + globalint_1419 = ivar11; + if (((boolean)script_3999(arg0))) { + script_4019(0); + setWidgetIsHidden(false, new WidgetPointer(917,92)); + setWidgetIsHidden(false, new WidgetPointer(917,83)); + setWidgetSprite(4320, new WidgetPointer(917,26)); + setWidgetSprite(4320, new WidgetPointer(917,28)); + setWidgetSprite(4321, new WidgetPointer(917,27)); + setWidgetIsHidden(true, new WidgetPointer(917,84)); + setWidgetIsHidden(true, new WidgetPointer(917,82)); + setWidgetIsHidden(true, new WidgetPointer(917,86)); + } + return; +} diff --git a/dumps/scripts/3992.cs2 b/dumps/scripts/3992.cs2 new file mode 100644 index 0000000..58a533c --- /dev/null +++ b/dumps/scripts/3992.cs2 @@ -0,0 +1,35 @@ +int script_3992(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,string arg6) { + int ivar6; + int ivar7; + int ivar8; + setWidgetIsHidden(false, new WidgetPointer(arg2)); + setWidgetText(new WidgetPointer(arg2), arg6); + setWidgetFont(495, new WidgetPointer(arg2)); + setWidgetTextAlignment(0, 1, 0, new WidgetPointer(arg2)); + ivar6 = subtract(getWidgetActualWidth(new WidgetPointer(arg5)), 34); + if (((boolean)script_3999(arg3))) { + ivar6 = add(ivar6, 9); + } + ivar7 = 0; + if (arg4 != -1) { + ivar7 = getWidgetActualHeight(new WidgetPointer(arg4)); + ivar6 = subtract(ivar6, 21); + } + ivar8 = max(add(ivar7, 5), multiply(15, getLineCount(ivar6, 495, arg6))); + setWidgetSize(ivar6, ivar8, 0, 0, new WidgetPointer(arg2)); + setWidgetPosition(9, arg1, 0, 0, new WidgetPointer(arg2)); + if (((boolean)script_3999(arg3)) && (arg4 != -1)) { + setWidgetIsHidden(false, new WidgetPointer(arg4)); + setWidgetPosition(16, add(arg1, divide(subtract(ivar8, getWidgetActualHeight(new WidgetPointer(arg4))), 2)), 2, 0, new WidgetPointer(arg4)); + if ((bitconfig_8578 == arg0) && (bitconfig_8594 == arg3)) { + setWidgetSprite(5623, new WidgetPointer(arg4)); + setScriptCallOnMouseEntered(4009, 0, 1, new WidgetPointer(arg4), "iiI", new WidgetPointer(arg4)); + setScriptCallOnMouseExit(4009, 1, 1, new WidgetPointer(arg4), "iiI", new WidgetPointer(arg4)); + } else { + setWidgetSprite(5621, new WidgetPointer(arg4)); + setScriptCallOnMouseEntered(4009, 0, 0, new WidgetPointer(arg4), "iiI", new WidgetPointer(arg4)); + setScriptCallOnMouseExit(4009, 1, 0, new WidgetPointer(arg4), "iiI", new WidgetPointer(arg4)); + } + } + return add(arg1, ivar8); +} diff --git a/dumps/scripts/3993.cs2 b/dumps/scripts/3993.cs2 new file mode 100644 index 0000000..0858c48 --- /dev/null +++ b/dumps/scripts/3993.cs2 @@ -0,0 +1,32 @@ +void script_3993() { + int ivar0; + int ivar1; + int ivar2; + ivar0 = 1; + ivar1 = -1; + while (ivar0 < subtract(getCommonDefinitionSize(3489), 1)) { + ivar1 = ((int)cs2method_3408(105, 73, 3489, ivar0)); + setWidgetPosition(14, multiply(subtract(ivar0, 1), getWidgetActualHeight(new WidgetPointer(ivar1))), 0, 0, new WidgetPointer(ivar1)); + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(ivar1)); + ivar1 = ((int)cs2method_3408(105, 73, 3490, ivar0)); + if (ivar1 != -1) { + setWidgetPosition(1, add(2, multiply(subtract(ivar0, 1), getWidgetActualHeight(new WidgetPointer(ivar1)))), 0, 0, new WidgetPointer(ivar1)); + } + ivar0 = add(ivar0, 1); + } + ivar1 = ((int)cs2method_3408(105, 73, 3489, 62)); + setWidgetPosition(14, multiply(subtract(ivar0, 1), getWidgetActualHeight(new WidgetPointer(ivar1))), 0, 0, new WidgetPointer(ivar1)); + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(ivar1)); + ivar1 = ((int)cs2method_3408(105, 73, 3490, 62)); + setWidgetPosition(1, add(2, multiply(subtract(ivar0, 1), getWidgetActualHeight(new WidgetPointer(ivar1)))), 0, 0, new WidgetPointer(ivar1)); + ivar0 = add(ivar0, 1); + ivar1 = ((int)cs2method_3408(105, 73, 3489, 0)); + setWidgetPosition(14, multiply(subtract(ivar0, 1), getWidgetActualHeight(new WidgetPointer(ivar1))), 0, 0, new WidgetPointer(ivar1)); + setWidgetRGB(new Color(255, 249, 235), new WidgetPointer(ivar1)); + ivar1 = ((int)cs2method_3408(105, 73, 3490, 0)); + setWidgetPosition(1, add(2, multiply(subtract(ivar0, 1), getWidgetActualHeight(new WidgetPointer(ivar1)))), 0, 0, new WidgetPointer(ivar1)); + ivar2 = multiply(ivar0, getWidgetActualHeight(new WidgetPointer(ivar1))); + setWidgetScrollMax(0, ivar2, new WidgetPointer(917,119)); + script_31(60096627, 60096631, 4288, 4286, 4285, 4287, 4290, 4289); + return; +} diff --git a/dumps/scripts/3994.cs2 b/dumps/scripts/3994.cs2 new file mode 100644 index 0000000..0694010 --- /dev/null +++ b/dumps/scripts/3994.cs2 @@ -0,0 +1,10 @@ +int script_3994(int arg0) { + int ivar1; + int ivar2; + ivar1 = cs2method_3408(105, 74, 3483, arg0); + ivar2 = getOtherCommonData(ivar1, 1268); + if (ivar2 == bitconfig_8576) { + return 1; + } + return 0; +} diff --git a/dumps/scripts/3995.cs2 b/dumps/scripts/3995.cs2 new file mode 100644 index 0000000..d18ec63 --- /dev/null +++ b/dumps/scripts/3995.cs2 @@ -0,0 +1,27 @@ +cs2func_script_3995_struct(2,1,0) script_3995(int arg0) { + if (arg0 >= 4091) { + return newstruct cs2func_script_3995_struct(0, 0, ""); + } + if ((arg0 >= 4000) && (arg0 <= 4027)) { + return newstruct cs2func_script_3995_struct(0, 0, ""); + } + if (((boolean)getOtherCommonData(cs2method_3408(105, 74, 3483, arg0), 1294))) { + return newstruct cs2func_script_3995_struct(1, 65280, "There are no requirements for this Task."); + } + if (script_3227(arg0) == 2) { + return newstruct cs2func_script_3995_struct(2, 65280, "You have completed this Task."); + } + if (((boolean)script_3994(arg0))) { + if (((boolean)script_3999(arg0))) { + return newstruct cs2func_script_3995_struct(0, 65280, ""); + } + return newstruct cs2func_script_3995_struct(1, 9393963, "You currently have this Task pinned."); + } + if (isMember() && (getOtherCommonData(cs2method_3408(105, 74, 3483, arg0), 1290) == 2)) { + return newstruct cs2func_script_3995_struct(0, 16711680, "This Task cannot be completed in the free game."); + } + if (((boolean)script_3224(arg0))) { + return newstruct cs2func_script_3995_struct(0, 16711680, "You lack one or more prerequisites needed to complete this Task."); + } + return newstruct cs2func_script_3995_struct(1, 65280, "You have the requirements to complete this Task."); +} diff --git a/dumps/scripts/3996.cs2 b/dumps/scripts/3996.cs2 new file mode 100644 index 0000000..ffbec1a --- /dev/null +++ b/dumps/scripts/3996.cs2 @@ -0,0 +1,24 @@ +int script_3996(int arg0) { + if (arg0 >= 4091) { + return 0; + } + if ((arg0 >= 4000) && (arg0 <= 4027)) { + return 0; + } + if (script_3227(arg0) == 2) { + return 2; + } + if (((boolean)script_3994(arg0))) { + if (((boolean)script_3999(arg0))) { + return 0; + } + return 1; + } + if (isMember() && (getOtherCommonData(cs2method_3408(105, 74, 3483, arg0), 1290) == 2)) { + return 0; + } + if (((boolean)script_3224(arg0))) { + return 0; + } + return 1; +} diff --git a/dumps/scripts/3997.cs2 b/dumps/scripts/3997.cs2 new file mode 100644 index 0000000..eda6d0c --- /dev/null +++ b/dumps/scripts/3997.cs2 @@ -0,0 +1,11 @@ +void script_3997() { + int ivar0; + setWidgetText(new WidgetPointer(917,112), intToStr(globalint_1423)); + setWidgetText(new WidgetPointer(917,110), intToStr(globalint_1424)); + setWidgetText(new WidgetPointer(917,150), intToStr(428)); + setWidgetText(new WidgetPointer(917,148), intToStr(bitconfig_8601)); + setWidgetText(new WidgetPointer(917,113), "Progress:"); + ivar0 = divide(multiply(globalint_1424, subtract(getWidgetActualWidth(new WidgetPointer(917,105)), 4)), max(globalint_1423, 1)); + setWidgetSize(ivar0, 16, 0, 0, new WidgetPointer(917,109)); + return; +} diff --git a/dumps/scripts/3998.cs2 b/dumps/scripts/3998.cs2 new file mode 100644 index 0000000..5121c6c --- /dev/null +++ b/dumps/scripts/3998.cs2 @@ -0,0 +1,84 @@ +void script_3998(int arg0,string arg1) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + flow_0: + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + ivar4 = 0; + ivar5 = 0; + ivar6 = 210; + ivar7 = 0; + ivar8 = 2; + ivar9 = -1; + IF (arg0 == -1) + GOTO flow_1 + GOTO flow_2 + flow_1: + IF (setWidgetRegister(new WidgetPointer(917,98))) + GOTO flow_3 + flow_2: + IF (setWidgetRegister(new WidgetPointer(917,98), arg0)) + GOTO flow_3 + GOTO flow_20 + flow_3: + if (globalint_1 < add(getClientCycle(), ivar8)) { + if (globalint_1 < getClientCycle()) { + globalint_1 = getClientCycle(); + } + globalint_1 = add(globalint_1, 2); + return; + } + globalint_1 = add(add(getClientCycle(), ivar8), 10); + if (globalint_2 != 1) { + ivar9 = getWidgetParentId(new WidgetPointer(917,101)); + if ((ivar9 != -1) && (ivar6 >= subtract(subtract(getWidgetActualWidth(new WidgetPointer(ivar9)), getWidgetActualWidth(new WidgetPointer(917,100))), 30))) { + ivar6 = subtract(subtract(getWidgetActualWidth(new WidgetPointer(ivar9)), getWidgetActualWidth(new WidgetPointer(917,100))), 30); + } + ivar5 = add(4, getMaxLineWidth(subtract(ivar6, 4), 495, arg1)); + ivar7 = add(4, multiply(16, getLineCount(subtract(ivar6, 4), 495, arg1))); + if (ivar9 != -1) { + ivar1 = add(getWidgetActualX(), 5); + if (add(add(ivar1, ivar5), 5) > getWidgetActualWidth(new WidgetPointer(917,98))) { + ivar1 = subtract(subtract(getWidgetActualWidth(new WidgetPointer(917,98)), ivar5), 5); + } + ivar2 = subtract(add(add(getWidgetActualY(), getWidgetActualHeight()), 5), cs2method2601(new WidgetPointer(917,98))); + } + if (ivar2 < 0) { + ivar2 = cs2method2601(new WidgetPointer(917,98)); + } else { + if (ivar2 > subtract(subtract(getWidgetActualHeight(new WidgetPointer(ivar9)), ivar7), 25)) { + ivar2 = subtract(subtract(getWidgetActualHeight(new WidgetPointer(ivar9)), ivar7), 25); + } + } + setWidgetSize(ivar5, ivar7, 0, 0, new WidgetPointer(917,101)); + setWidgetPosition(ivar1, ivar2, 0, 0, new WidgetPointer(917,101)); + deleteAllExtraChilds(new WidgetPointer(917,101)); + createExtraChild(new WidgetPointer(917,101), 3, 0); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(917,101)), getWidgetActualHeight(new WidgetPointer(917,101)), 0, 0); + setWidgetFilled(1); + setWidgetRGB(new Color(0, 0, 0)); + cs2method2103(90); + createExtraChild(new WidgetPointer(917,101), 3, 1); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(917,101)), getWidgetActualHeight(new WidgetPointer(917,101)), 0, 0); + setWidgetFilled(0); + setWidgetRGB(new Color(0, 0, 0)); + createExtraChild(new WidgetPointer(917,101), 4, 2); + setWidgetSize(subtract(ivar6, 4), getWidgetActualHeight(new WidgetPointer(917,101)), 0, 0); + setWidgetPosition(2, 0, 0, 0); + setWidgetText(arg1); + setWidgetTextAlignment(0, 1, 16); + setWidgetFont(495); + setWidgetRGB(new Color(238, 238, 238)); + globalint_2 = 1; + } + flow_20: + return; +} diff --git a/dumps/scripts/3999.cs2 b/dumps/scripts/3999.cs2 new file mode 100644 index 0000000..d0bc428 --- /dev/null +++ b/dumps/scripts/3999.cs2 @@ -0,0 +1,6 @@ +int script_3999(int arg0) { + if ((((((arg0 == 4091) || (arg0 == 4092)) || (arg0 == 450)) || (arg0 == 4094)) || (arg0 == 4095)) || (arg0 == 4093)) { + return 1; + } + return 0; +} diff --git a/dumps/scripts/4.cs2 b/dumps/scripts/4.cs2 new file mode 100644 index 0000000..2f7d1e9 --- /dev/null +++ b/dumps/scripts/4.cs2 @@ -0,0 +1,294 @@ +void script_4(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,string arg8) { + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + int ivar22; + int ivar23; + int ivar24; + int ivar25; + int ivar26; + int ivar27; + int ivar28; + int ivar29; + int ivar30; + int ivar31; + int ivar32; + string svar1; + string svar2; + int stack_dump0; + opcStruct5224(2,0,0) structdump_1; + opcStruct5224(2,0,0) structdump_2; + opcStruct5224(2,0,0) structdump_3; + opcStruct5224(2,0,0) structdump_4; + if ((arg1 == -1) || ((boolean)arg1)) { + deleteAllExtraChilds(new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(arg0)); + return; + } + ivar8 = 0; + ivar9 = 0; + stack_dump0 = arg1; + structdump_1 = cs2method5224(stack_dump0); + ivar9 = structdump_1.intpart_1; + ivar8 = structdump_1.intpart_0; + if ((ivar8 < 0) || (ivar9 < 0)) { + arg1 = addToCoordinate(0, extractX(arg1), script_686(subtract(extractZ(arg1), 1), 4), extractY(arg1)); + stack_dump0 = arg1; + structdump_2 = cs2method5224(stack_dump0); + ivar9 = structdump_2.intpart_1; + ivar8 = structdump_2.intpart_0; + if ((ivar8 < 0) || (ivar9 < 0)) { + arg1 = addToCoordinate(0, extractX(arg1), script_686(subtract(extractZ(arg1), 1), 4), extractY(arg1)); + stack_dump0 = arg1; + structdump_3 = cs2method5224(stack_dump0); + ivar9 = structdump_3.intpart_1; + ivar8 = structdump_3.intpart_0; + if ((ivar8 < 0) || (ivar9 < 0)) { + arg1 = addToCoordinate(0, extractX(arg1), script_686(subtract(extractZ(arg1), 1), 4), extractY(arg1)); + stack_dump0 = arg1; + structdump_4 = cs2method5224(stack_dump0); + ivar9 = structdump_4.intpart_1; + ivar8 = structdump_4.intpart_0; + if ((ivar8 < 0) || (ivar9 < 0)) { + deleteAllExtraChilds(new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(arg0)); + return; + } + } + } + } + setWidgetIsHidden(false, new WidgetPointer(arg0)); + ivar10 = getWidgetActualWidth(new WidgetPointer(arg3)); + ivar11 = getWidgetActualHeight(new WidgetPointer(arg3)); + if (arg2 == -1) { + arg2 = 280; + } + ivar8 = multiplyDivide(ivar10, subtract(arg6, arg7), subtract(ivar8, arg7)); + ivar9 = multiplyDivide(ivar11, subtract(arg4, arg5), subtract(ivar9, arg5)); + ivar8 = max(min(ivar8, ivar10), 0); + ivar9 = max(min(ivar9, ivar11), 0); + ivar8 = subtract(ivar8, divide(ivar10, 2)); + ivar9 = subtract(divide(ivar11, 2), ivar9); + setWidgetPosition(ivar8, ivar9, 1, 1, new WidgetPointer(arg0)); + ivar12 = getOtherCommonData(arg2, 132); + ivar13 = getOtherCommonData(arg2, 133); + ivar14 = -1; + if (ivar8 <= subtract(0, divide(ivar10, 2))) { + if (ivar9 <= subtract(0, divide(ivar11, 2))) { + ivar14 = 3; + } else if (ivar9 >= divide(ivar11, 2)) { + ivar14 = 1; + } else { + ivar14 = 2; + } + } else if (ivar8 >= divide(ivar10, 2)) { + if (ivar9 <= subtract(0, divide(ivar11, 2))) { + ivar14 = 5; + } else if (ivar9 >= divide(ivar11, 2)) { + ivar14 = 7; + } else { + ivar14 = 6; + } + } else if (ivar9 <= subtract(0, divide(ivar11, 2))) { + ivar14 = 4; + } else { + if (ivar9 >= divide(ivar11, 2)) { + ivar14 = 0; + } + } + ivar15 = 0; + ivar16 = 0; + ivar17 = 0; + ivar18 = 0; + svar1 = "Scroll map"; + svar2 = ""; + if (strLength(arg8) > 0) { + if (arg0 == 49479716) { + svar2 = "Your position"; + } else { + svar2 = strRemoveEntities(script_2332(arg8, "
", " ")); + } + svar1 = "Scroll map:"; + } + if (ivar14 == -1) { + script_2048(arg0, 0, getOtherCommonData(arg2, 130), ivar12, ivar13, 0, 0, 0, 0, 0, 0, 0, arg1, svar2, svar1); + ivar15 = divide(ivar13, 2); + ivar16 = divide(ivar13, 2); + ivar17 = divide(ivar12, 2); + ivar18 = divide(ivar12, 2); + script_2048(arg0, 1, getOtherCommonData(arg2, 131), ivar12, ivar13, 0, 0, 0, 0, 0, 0, 1, -1, "", ""); + } else { + ivar12 = getOtherCommonData(arg2, 136); + ivar13 = getOtherCommonData(arg2, 645); + switch (ivar14) { + case 0: + script_2048(arg0, 0, getOtherCommonData(arg2, 134), ivar12, ivar13, 0, subtract(0, divide(ivar13, 2)), 49152, 0, 0, 0, 0, arg1, svar2, svar1); + ivar15 = ivar13; + ivar16 = 0; + ivar17 = divide(ivar12, 2); + ivar18 = divide(ivar12, 2); + break; + case 1: + script_2048(arg0, 0, getOtherCommonData(arg2, 135), ivar12, ivar13, divide(ivar12, 2), subtract(0, divide(ivar13, 2)), 32768, 0, 0, 0, 0, arg1, svar2, svar1); + ivar15 = ivar13; + ivar16 = 0; + ivar17 = 0; + ivar18 = ivar12; + break; + case 2: + script_2048(arg0, 0, getOtherCommonData(arg2, 134), ivar12, ivar13, divide(ivar12, 2), 0, 32768, 0, 0, 0, 0, arg1, svar2, svar1); + ivar15 = divide(ivar13, 2); + ivar16 = divide(ivar13, 2); + ivar17 = 0; + ivar18 = ivar12; + break; + case 3: + script_2048(arg0, 0, getOtherCommonData(arg2, 135), ivar12, ivar13, divide(ivar12, 2), divide(ivar13, 2), 16384, 0, 0, 0, 0, arg1, svar2, svar1); + ivar15 = 0; + ivar16 = ivar13; + ivar17 = 0; + ivar18 = ivar12; + break; + case 4: + script_2048(arg0, 0, getOtherCommonData(arg2, 134), ivar12, ivar13, 0, divide(ivar13, 2), 16384, 0, 0, 0, 0, arg1, svar2, svar1); + ivar15 = 0; + ivar16 = ivar13; + ivar17 = divide(ivar12, 2); + ivar18 = divide(ivar12, 2); + break; + case 5: + script_2048(arg0, 0, getOtherCommonData(arg2, 135), ivar12, ivar13, subtract(0, divide(ivar12, 2)), divide(ivar13, 2), 0, 0, 0, 0, 0, arg1, svar2, svar1); + ivar15 = 0; + ivar16 = ivar13; + ivar17 = ivar12; + ivar18 = 0; + break; + case 6: + script_2048(arg0, 0, getOtherCommonData(arg2, 134), ivar12, ivar13, subtract(0, divide(ivar12, 2)), 0, 0, 0, 0, 0, 0, arg1, svar2, svar1); + ivar15 = divide(ivar13, 2); + ivar16 = divide(ivar13, 2); + ivar17 = ivar12; + ivar18 = 0; + break; + case 7: + script_2048(arg0, 0, getOtherCommonData(arg2, 135), ivar12, ivar13, subtract(0, divide(ivar12, 2)), subtract(0, divide(ivar13, 2)), 49152, 0, 0, 0, 0, arg1, svar2, svar1); + ivar15 = ivar13; + ivar16 = 0; + ivar17 = ivar12; + ivar18 = 0; + } + script_2050(arg0, 1); + } + ivar19 = 0; + ivar20 = 0; + ivar21 = 0; + ivar22 = 0; + ivar23 = 0; + ivar24 = 0; + ivar25 = 0; + ivar26 = 0; + ivar27 = -1; + ivar28 = -1; + ivar29 = -1; + ivar30 = 0; + if (strLength(arg8) > 0) { + ivar23 = getOtherCommonData(arg2, 650); + ivar24 = getOtherCommonData(arg2, 651); + ivar27 = getOtherCommonData(arg2, 647); + ivar28 = getOtherCommonData(arg2, 648); + ivar29 = getOtherCommonData(arg2, 649); + ivar19 = add(add(getMaxLineWidth(ivar10, 591, arg8), ivar23), ivar23); + ivar20 = add(add(add(multiply(getLineCount(ivar19, 591, arg8), 13), 2), ivar24), ivar24); + if (add(ivar15, ivar20) < add(ivar9, divide(ivar11, 2))) { + ivar22 = subtract(0, add(ivar15, divide(ivar20, 2))); + } else { + ivar22 = add(ivar16, divide(ivar20, 2)); + } + ivar30 = subtract(add(ivar8, divide(ivar10, 2)), divide(ivar19, 2)); + if (ivar30 <= 0) { + ivar21 = subtract(0, ivar30); + } else { + ivar30 = add(add(ivar8, divide(ivar10, 2)), divide(ivar19, 2)); + if (ivar30 >= ivar10) { + ivar21 = subtract(ivar10, ivar30); + } + } + ivar25 = divide(subtract(ivar19, ivar23), 2); + ivar26 = divide(subtract(ivar20, ivar24), 2); + script_2048(arg0, 2, getOtherCommonData(arg2, 646), subtract(ivar19, multiply(ivar23, 2)), subtract(ivar20, multiply(ivar24, 2)), ivar21, ivar22, 0, 1, 0, 0, 0, -1, "", ""); + script_2048(arg0, 3, ivar28, subtract(ivar19, multiply(ivar23, 2)), ivar24, ivar21, subtract(ivar22, ivar26), 0, 1, 0, 0, 0, -1, "", ""); + script_2048(arg0, 4, ivar28, subtract(ivar19, multiply(ivar23, 2)), ivar24, ivar21, add(ivar22, ivar26), 0, 1, 0, 1, 0, -1, "", ""); + script_2048(arg0, 5, ivar29, ivar23, subtract(ivar20, multiply(ivar24, 2)), subtract(ivar21, ivar25), ivar22, 0, 1, 0, 0, 0, -1, "", ""); + script_2048(arg0, 6, ivar29, ivar23, subtract(ivar20, multiply(ivar24, 2)), add(ivar21, ivar25), ivar22, 0, 1, 1, 0, 0, -1, "", ""); + script_2048(arg0, 7, ivar27, ivar23, ivar24, subtract(ivar21, ivar25), subtract(ivar22, ivar26), 0, 0, 0, 0, 0, -1, "", ""); + script_2048(arg0, 8, ivar27, ivar23, ivar24, add(ivar21, ivar25), subtract(ivar22, ivar26), 0, 0, 1, 0, 0, -1, "", ""); + script_2048(arg0, 9, ivar27, ivar23, ivar24, subtract(ivar21, ivar25), add(ivar22, ivar26), 0, 0, 0, 1, 0, -1, "", ""); + script_2048(arg0, 10, ivar27, ivar23, ivar24, add(ivar21, ivar25), add(ivar22, ivar26), 0, 0, 1, 1, 0, -1, "", ""); + script_2051(arg0, 11, ivar19, ivar20, add(ivar21, 1), add(ivar22, 1), getOtherCommonData(arg2, 653), -1, arg8, "", ""); + script_2051(arg0, 12, ivar19, ivar20, ivar21, ivar22, getOtherCommonData(arg2, 652), arg1, arg8, svar2, svar1); + } else { + if (setWidgetRegister(new WidgetPointer(arg0), 2)) { + deleteExtraChild(); + } + if (setWidgetRegister(new WidgetPointer(arg0), 3)) { + deleteExtraChild(); + } + if (setWidgetRegister(new WidgetPointer(arg0), 4)) { + deleteExtraChild(); + } + if (setWidgetRegister(new WidgetPointer(arg0), 5)) { + deleteExtraChild(); + } + if (setWidgetRegister(new WidgetPointer(arg0), 6)) { + deleteExtraChild(); + } + if (setWidgetRegister(new WidgetPointer(arg0), 7)) { + deleteExtraChild(); + } + if (setWidgetRegister(new WidgetPointer(arg0), 8)) { + deleteExtraChild(); + } + if (setWidgetRegister(new WidgetPointer(arg0), 9)) { + deleteExtraChild(); + } + if (setWidgetRegister(new WidgetPointer(arg0), 10)) { + deleteExtraChild(); + } + if (setWidgetRegister(new WidgetPointer(arg0), 11)) { + deleteExtraChild(); + } + if (setWidgetRegister(new WidgetPointer(arg0), 12)) { + deleteExtraChild(); + } + } + ivar31 = 0; + ivar32 = 0; + if (ivar21 < 0) { + ivar31 = max(subtract(0, subtract(ivar21, divide(ivar19, 2))), ivar17); + } else if (ivar19 > 0) { + ivar31 = max(add(ivar21, divide(ivar19, 2)), ivar18); + } else { + ivar31 = max(ivar17, ivar18); + } + if (ivar22 <= 0) { + ivar32 = max(add(ivar15, ivar20), ivar16); + } else { + ivar32 = add(ivar16, ivar20); + } + stack_dump0 = add(multiply(ivar31, 2), 2); + ivar32 = add(multiply(ivar32, 2), 2); + ivar31 = stack_dump0; + setWidgetSize(ivar31, ivar32, 0, 0, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/40.cs2 b/dumps/scripts/40.cs2 new file mode 100644 index 0000000..46e87d0 --- /dev/null +++ b/dumps/scripts/40.cs2 @@ -0,0 +1,4 @@ +void script_40(int arg0) { + script_41(arg0); + return; +} diff --git a/dumps/scripts/400.cs2 b/dumps/scripts/400.cs2 new file mode 100644 index 0000000..47a9d18 --- /dev/null +++ b/dumps/scripts/400.cs2 @@ -0,0 +1,31 @@ +string script_400(string arg0,string arg1,string arg2) { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + string svar3; + string svar4; + ivar0 = 0; + ivar1 = 0; + svar3 = ""; + svar4 = ""; + ivar2 = strLength(arg0); + ivar3 = strLength(arg1); + if (ivar2 > 0) { + ivar1 = strIndexof(ivar1, arg0, arg1); + while (ivar1 != -1) { + svar4 = substr(ivar0, ivar1, arg0); + if (stringMethod4107(svar4, "") != 0) { + svar3 = svar3 + svar4 + arg2; + } + ivar1 = add(ivar1, ivar3); + ivar0 = ivar1; + ivar1 = strIndexof(ivar1, arg0, arg1); + } + svar4 = substr(ivar0, ivar2, arg0); + if (stringMethod4107(svar4, "") != 0) { + svar3 = svar3 + svar4; + } + } + return svar3; +} diff --git a/dumps/scripts/4000.cs2 b/dumps/scripts/4000.cs2 new file mode 100644 index 0000000..575a0fe --- /dev/null +++ b/dumps/scripts/4000.cs2 @@ -0,0 +1,85 @@ +void script_4000(int arg0) { + int ivar1; + int ivar2; + int ivar3; + string svar0; + svar0 = ""; + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + switch (arg0) { + case 0: + setWidgetIsHidden(true, new WidgetPointer(1056,92)); + setWidgetIsHidden(true, new WidgetPointer(1056,94)); + setWidgetIsHidden(false, new WidgetPointer(1056,125)); + if (((boolean)stringMethod4107(getWidgetText(new WidgetPointer(1056,91)), getOtherCommonData(1753, 1266))) || (((boolean)stringMethod4107(getWidgetText(new WidgetPointer(1056,91)), getOtherCommonData(1752, 1266))) && (standart_config_281 == 1000))) { + svar0 = "Click on the Hints tab for more on how to complete this Task."; + } else { + if (((boolean)stringMethod4107(getWidgetText(new WidgetPointer(1056,91)), getOtherCommonData(1754, 1266))) || ((boolean)stringMethod4107(getWidgetText(new WidgetPointer(1056,91)), getOtherCommonData(1518, 1266)))) { + svar0 = "Remember, the Hints tab provides more details about a Task."; + } + } + if (getDisplayMode() >= 2) { + ivar1 = 196; + ivar2 = 183; + ivar3 = 1; + if (getWidgetActualWidth(new WidgetPointer(746,2)) < 997) { + ivar2 = add(ivar2, 40); + } + } else { + ivar1 = 217; + ivar2 = 177; + } + break; + case 1: + setWidgetIsHidden(true, new WidgetPointer(1056,92)); + setWidgetIsHidden(false, new WidgetPointer(1056,94)); + setWidgetIsHidden(true, new WidgetPointer(1056,125)); + if (((boolean)stringMethod4107(getWidgetText(new WidgetPointer(1056,91)), getOtherCommonData(1753, 1266))) || (((boolean)stringMethod4107(getWidgetText(new WidgetPointer(1056,91)), getOtherCommonData(1752, 1266))) && (standart_config_281 == 1000))) { + svar0 = "Click on the Hints tab for more on how to complete this Task."; + } else { + if (((boolean)stringMethod4107(getWidgetText(new WidgetPointer(1056,91)), getOtherCommonData(1754, 1266))) || ((boolean)stringMethod4107(getWidgetText(new WidgetPointer(1056,91)), getOtherCommonData(1518, 1266)))) { + svar0 = "Remember, the Hints tab provides more details about a Task."; + } + } + if (getDisplayMode() >= 2) { + ivar1 = 196; + ivar2 = 183; + ivar3 = 1; + if (getWidgetActualWidth(new WidgetPointer(746,2)) < 997) { + ivar2 = add(ivar2, 40); + } + } else { + ivar1 = 217; + ivar2 = 177; + } + break; + case 2: + setWidgetIsHidden(false, new WidgetPointer(1056,92)); + setWidgetIsHidden(true, new WidgetPointer(1056,94)); + setWidgetIsHidden(true, new WidgetPointer(1056,125)); + if (((boolean)stringMethod4107(getWidgetText(new WidgetPointer(1056,91)), getOtherCommonData(1753, 1266))) || ((boolean)stringMethod4107(getWidgetText(new WidgetPointer(1056,91)), getOtherCommonData(1754, 1266)))) { + svar0 = "The '?' icon will add an arrow to the screen which points to your destination."; + } + if (getDisplayMode() >= 2) { + ivar1 = 196; + ivar2 = 87; + ivar3 = 1; + if (getWidgetActualWidth(new WidgetPointer(746,2)) < 997) { + ivar2 = add(ivar2, 40); + } + } else { + ivar1 = 208; + ivar2 = 78; + } + } + if (((boolean)bitconfig_9030)) { + svar0 = ""; + } + if (((boolean)ivar3)) { + script_4247(ivar1, ivar2, 1, 16777215, 5631, svar0); + } else { + script_4248(ivar1, ivar2, 1, 16777215, 5631, svar0); + } + return; +} diff --git a/dumps/scripts/4001.cs2 b/dumps/scripts/4001.cs2 new file mode 100644 index 0000000..f809839 --- /dev/null +++ b/dumps/scripts/4001.cs2 @@ -0,0 +1,5 @@ +void script_4001() { + setWidgetIsHidden(true, new WidgetPointer(1056,122)); + script_4249(1); + return; +} diff --git a/dumps/scripts/4002.cs2 b/dumps/scripts/4002.cs2 new file mode 100644 index 0000000..6fbb284 --- /dev/null +++ b/dumps/scripts/4002.cs2 @@ -0,0 +1,46 @@ +void script_4002() { + int ivar0; + int ivar1; + int ivar2; + string svar0; + string svar1; + string svar2; + string svar3; + if (getDisplayMode() >= 2) { + if (isParent(new WidgetPointer(746,12), 917)) { + return; + } + } else { + if (isParent(new WidgetPointer(548,19), 917)) { + return; + } + } + svar0 = "Progress: "; + ivar0 = globalint_1424; + svar1 = ""; + ivar1 = globalint_1423; + svar2 = ""; + svar3 = cs2method_3408(105, 115, 3487, bitconfig_8575); + if (((boolean)bitconfig_9030)) { + ivar0 = bitconfig_9028; + ivar1 = getCommonDefinitionSize(3656); + svar3 = "Introductory Tasks"; + } + svar1 = intToStr(ivar0); + svar2 = intToStr(ivar1); + if (bitconfig_8575 == 61) { + svar3 = "Quest Area"; + setWidgetIsHidden(true, new WidgetPointer(1056,111)); + setWidgetIsHidden(true, new WidgetPointer(1056,112)); + } else { + setWidgetIsHidden(false, new WidgetPointer(1056,111)); + setWidgetIsHidden(false, new WidgetPointer(1056,112)); + } + ivar2 = divide(multiply(ivar0, subtract(getWidgetActualWidth(new WidgetPointer(1056,111)), 2)), max(1, ivar1)); + svar0 = concat(svar0, svar1); + setWidgetText(new WidgetPointer(1056,108), svar2); + setWidgetText(new WidgetPointer(1056,106), svar0); + setWidgetText(new WidgetPointer(1056,110), svar3); + setWidgetSize(ivar2, 18, 0, 0, new WidgetPointer(1056,105)); + return; +} diff --git a/dumps/scripts/4003.cs2 b/dumps/scripts/4003.cs2 new file mode 100644 index 0000000..0848c5a --- /dev/null +++ b/dumps/scripts/4003.cs2 @@ -0,0 +1,12 @@ +void script_4003(int arg0) { + if (((boolean)arg0)) { + setWidgetSprite(4318, new WidgetPointer(1056,93)); + setWidgetSprite(4318, new WidgetPointer(1056,168)); + setWidgetSprite(4319, new WidgetPointer(1056,169)); + } else { + setWidgetSprite(4316, new WidgetPointer(1056,93)); + setWidgetSprite(4316, new WidgetPointer(1056,168)); + setWidgetSprite(4317, new WidgetPointer(1056,169)); + } + return; +} diff --git a/dumps/scripts/4004.cs2 b/dumps/scripts/4004.cs2 new file mode 100644 index 0000000..cc7968b --- /dev/null +++ b/dumps/scripts/4004.cs2 @@ -0,0 +1,15 @@ +void script_4004(int arg0) { + if (((boolean)arg0)) { + setWidgetSprite(4324, new WidgetPointer(1056,138)); + setWidgetSprite(4324, new WidgetPointer(1056,139)); + setWidgetSprite(4325, new WidgetPointer(1056,137)); + setWidgetSprite(4309, new WidgetPointer(1056,141)); + } else { + setWidgetSprite(4322, new WidgetPointer(1056,138)); + setWidgetSprite(4322, new WidgetPointer(1056,139)); + setWidgetSprite(4323, new WidgetPointer(1056,137)); + setWidgetSprite(4308, new WidgetPointer(1056,141)); + script_41(69206152); + } + return; +} diff --git a/dumps/scripts/4005.cs2 b/dumps/scripts/4005.cs2 new file mode 100644 index 0000000..e30c911 --- /dev/null +++ b/dumps/scripts/4005.cs2 @@ -0,0 +1,15 @@ +void script_4005(int arg0) { + if (((boolean)arg0)) { + setWidgetSprite(4324, new WidgetPointer(1056,0)); + setWidgetSprite(4324, new WidgetPointer(1056,1)); + setWidgetSprite(4325, new WidgetPointer(1056,175)); + setWidgetSprite(4309, new WidgetPointer(1056,177)); + } else { + setWidgetSprite(4322, new WidgetPointer(1056,0)); + setWidgetSprite(4322, new WidgetPointer(1056,1)); + setWidgetSprite(4323, new WidgetPointer(1056,175)); + setWidgetSprite(4308, new WidgetPointer(1056,177)); + script_41(69206152); + } + return; +} diff --git a/dumps/scripts/4006.cs2 b/dumps/scripts/4006.cs2 new file mode 100644 index 0000000..2e380b7 --- /dev/null +++ b/dumps/scripts/4006.cs2 @@ -0,0 +1,13 @@ +void script_4006(int arg0) { + if (((boolean)arg0)) { + setWidgetSprite(4324, new WidgetPointer(1056,118)); + setWidgetSprite(4324, new WidgetPointer(1056,119)); + setWidgetSprite(4325, new WidgetPointer(1056,89)); + } else { + setWidgetSprite(4322, new WidgetPointer(1056,118)); + setWidgetSprite(4322, new WidgetPointer(1056,119)); + setWidgetSprite(4323, new WidgetPointer(1056,89)); + script_41(69206152); + } + return; +} diff --git a/dumps/scripts/4007.cs2 b/dumps/scripts/4007.cs2 new file mode 100644 index 0000000..2a2124a --- /dev/null +++ b/dumps/scripts/4007.cs2 @@ -0,0 +1,13 @@ +void script_4007(int arg0) { + if (((boolean)arg0)) { + setWidgetSprite(4324, new WidgetPointer(1056,114)); + setWidgetSprite(4324, new WidgetPointer(1056,115)); + setWidgetSprite(4325, new WidgetPointer(1056,116)); + } else { + setWidgetSprite(4322, new WidgetPointer(1056,114)); + setWidgetSprite(4322, new WidgetPointer(1056,115)); + setWidgetSprite(4323, new WidgetPointer(1056,116)); + script_41(69206152); + } + return; +} diff --git a/dumps/scripts/4008.cs2 b/dumps/scripts/4008.cs2 new file mode 100644 index 0000000..07aba83 --- /dev/null +++ b/dumps/scripts/4008.cs2 @@ -0,0 +1,5 @@ +void script_4008(int arg0,int arg1) { + setScriptCallOnMouseEntered(4009, 0, arg0, new WidgetPointer(arg1), "iiI", new WidgetPointer(arg1)); + setScriptCallOnMouseExit(4009, 1, arg0, new WidgetPointer(arg1), "iiI", new WidgetPointer(arg1)); + return; +} diff --git a/dumps/scripts/4009.cs2 b/dumps/scripts/4009.cs2 new file mode 100644 index 0000000..002bcf9 --- /dev/null +++ b/dumps/scripts/4009.cs2 @@ -0,0 +1,16 @@ +void script_4009(int arg0,int arg1,int arg2) { + if (((boolean)arg1)) { + if (((boolean)arg0)) { + setWidgetSprite(5624, new WidgetPointer(arg2)); + } else { + setWidgetSprite(5623, new WidgetPointer(arg2)); + script_41(69206152); + } + } else if (((boolean)arg0)) { + setWidgetSprite(5622, new WidgetPointer(arg2)); + } else { + setWidgetSprite(5621, new WidgetPointer(arg2)); + script_41(69206152); + } + return; +} diff --git a/dumps/scripts/401.cs2 b/dumps/scripts/401.cs2 new file mode 100644 index 0000000..0acbd22 --- /dev/null +++ b/dumps/scripts/401.cs2 @@ -0,0 +1,44 @@ +void script_401(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + string svar0; + svar0 = globalstring_320; + if ((strLength(globalstring_319) > 0) && ((boolean)standart_config_170)) { + svar0 = globalstring_319; + } + if (setWidgetRegister(new WidgetPointer(arg1), 0) && ((boolean)stringMethod4107(svar0, getWidgetText()))) { + return; + } + deleteAllExtraChilds(new WidgetPointer(arg0)); + deleteAllExtraChilds(new WidgetPointer(arg1)); + deleteAllExtraChilds(new WidgetPointer(arg2)); + ivar3 = getWidgetActualWidth(new WidgetPointer(arg0)); + ivar4 = 0; + cs2method2100(0, 0, new WidgetPointer(arg1)); + setWidgetPosition(ivar4, 0, 0, 1, new WidgetPointer(arg1)); + ivar5 = add(multiply(getLineCount(ivar3, 307, svar0), 12), 3); + if (ivar5 > getWidgetActualHeight(new WidgetPointer(arg0))) { + ivar3 = subtract(ivar3, add(getWidgetActualWidth(new WidgetPointer(arg2)), 5)); + setWidgetSize(ivar3, 0, 0, 1, new WidgetPointer(arg1)); + ivar5 = add(multiply(getLineCount(ivar3, 307, svar0), 12), 3); + setWidgetScrollMax(0, ivar5, new WidgetPointer(arg1)); + setWidgetIsHidden(false, new WidgetPointer(arg2)); + script_31(arg2, arg1, 792, 789, 790, 791, 773, 788); + } else { + ivar5 = getWidgetActualHeight(new WidgetPointer(arg0)); + setWidgetSize(ivar3, 0, 0, 1, new WidgetPointer(arg1)); + setWidgetScrollMax(0, 0, new WidgetPointer(arg1)); + setWidgetIsHidden(true, new WidgetPointer(arg2)); + } + createExtraChild(new WidgetPointer(arg1), 4, 0); + setWidgetSize(0, ivar5, 1, 0); + setWidgetPosition(0, 0, 1, 0); + setWidgetFont(307); + setWidgetTextAlignment(1, 1, 0); + setWidgetRGB(new Color(0, 0, 0)); + setWidgetUnknownBoolean(false); + setWidgetText(svar0); + setWidgetFont(307, new WidgetPointer(200,4)); + return; +} diff --git a/dumps/scripts/4010.cs2 b/dumps/scripts/4010.cs2 new file mode 100644 index 0000000..0ede7f1 --- /dev/null +++ b/dumps/scripts/4010.cs2 @@ -0,0 +1,54 @@ +void script_4010(int arg0) { + switch (arg0) { + case 0: + setWidgetSprite(4316, new WidgetPointer(1056,16)); + setWidgetSprite(4316, new WidgetPointer(1056,18)); + setWidgetSprite(4317, new WidgetPointer(1056,17)); + setWidgetSprite(4316, new WidgetPointer(1056,11)); + setWidgetSprite(4316, new WidgetPointer(1056,13)); + setWidgetSprite(4317, new WidgetPointer(1056,12)); + setWidgetSprite(4316, new WidgetPointer(1056,31)); + setWidgetSprite(4316, new WidgetPointer(1056,33)); + setWidgetSprite(4317, new WidgetPointer(1056,32)); + setWidgetSprite(4316, new WidgetPointer(1056,21)); + setWidgetSprite(4316, new WidgetPointer(1056,23)); + setWidgetSprite(4317, new WidgetPointer(1056,22)); + setWidgetSprite(4316, new WidgetPointer(1056,44)); + setWidgetSprite(4316, new WidgetPointer(1056,46)); + setWidgetSprite(4317, new WidgetPointer(1056,45)); + setWidgetSprite(4316, new WidgetPointer(1056,39)); + setWidgetSprite(4316, new WidgetPointer(1056,41)); + setWidgetSprite(4317, new WidgetPointer(1056,40)); + break; + case 1: + setWidgetSprite(4318, new WidgetPointer(1056,16)); + setWidgetSprite(4318, new WidgetPointer(1056,18)); + setWidgetSprite(4319, new WidgetPointer(1056,17)); + break; + case 2: + setWidgetSprite(4318, new WidgetPointer(1056,11)); + setWidgetSprite(4318, new WidgetPointer(1056,13)); + setWidgetSprite(4319, new WidgetPointer(1056,12)); + break; + case 3: + setWidgetSprite(4318, new WidgetPointer(1056,31)); + setWidgetSprite(4318, new WidgetPointer(1056,33)); + setWidgetSprite(4319, new WidgetPointer(1056,32)); + break; + case 4: + setWidgetSprite(4318, new WidgetPointer(1056,21)); + setWidgetSprite(4318, new WidgetPointer(1056,23)); + setWidgetSprite(4319, new WidgetPointer(1056,22)); + break; + case 5: + setWidgetSprite(4318, new WidgetPointer(1056,44)); + setWidgetSprite(4318, new WidgetPointer(1056,46)); + setWidgetSprite(4319, new WidgetPointer(1056,45)); + break; + case 6: + setWidgetSprite(4318, new WidgetPointer(1056,39)); + setWidgetSprite(4318, new WidgetPointer(1056,41)); + setWidgetSprite(4319, new WidgetPointer(1056,40)); + } + return; +} diff --git a/dumps/scripts/4011.cs2 b/dumps/scripts/4011.cs2 new file mode 100644 index 0000000..83351d0 --- /dev/null +++ b/dumps/scripts/4011.cs2 @@ -0,0 +1,14 @@ +void script_4011() { + if (((boolean)globalint_1421)) { + globalint_1421 = 1; + setWidgetSprite(4086, new WidgetPointer(1056,173)); + setScriptCallOnMouseEntered(4012, 0, 1, "ii", new WidgetPointer(1056,173)); + setScriptCallOnMouseExit(4012, 1, 1, "ii", new WidgetPointer(1056,173)); + } else { + globalint_1421 = 0; + setWidgetSprite(4084, new WidgetPointer(1056,173)); + setScriptCallOnMouseEntered(4012, 0, 0, "ii", new WidgetPointer(1056,173)); + setScriptCallOnMouseExit(4012, 1, 0, "ii", new WidgetPointer(1056,173)); + } + return; +} diff --git a/dumps/scripts/4012.cs2 b/dumps/scripts/4012.cs2 new file mode 100644 index 0000000..3c40a78 --- /dev/null +++ b/dumps/scripts/4012.cs2 @@ -0,0 +1,14 @@ +void script_4012(int arg0,int arg1) { + if (((boolean)arg1)) { + if (((boolean)arg0)) { + setWidgetSprite(4085, new WidgetPointer(1056,173)); + } else { + setWidgetSprite(4084, new WidgetPointer(1056,173)); + } + } else if (((boolean)arg0)) { + setWidgetSprite(4087, new WidgetPointer(1056,173)); + } else { + setWidgetSprite(4086, new WidgetPointer(1056,173)); + } + return; +} diff --git a/dumps/scripts/4013.cs2 b/dumps/scripts/4013.cs2 new file mode 100644 index 0000000..6390026 --- /dev/null +++ b/dumps/scripts/4013.cs2 @@ -0,0 +1,4 @@ +void script_4013(int arg0,int arg1) { + script_4014(arg0, arg1); + return; +} diff --git a/dumps/scripts/4014.cs2 b/dumps/scripts/4014.cs2 new file mode 100644 index 0000000..6c7a72a --- /dev/null +++ b/dumps/scripts/4014.cs2 @@ -0,0 +1,7 @@ +void script_4014(int arg0,int arg1) { + if (setWidgetRegister(new WidgetPointer(917,98), arg0) && isWidgetHidden(new WidgetPointer(917,119))) { + setWidgetSprite(arg1); + } + script_41(60096613); + return; +} diff --git a/dumps/scripts/4015.cs2 b/dumps/scripts/4015.cs2 new file mode 100644 index 0000000..903c961 --- /dev/null +++ b/dumps/scripts/4015.cs2 @@ -0,0 +1,10 @@ +void script_4015() { + if (isWidgetHidden(new WidgetPointer(917,119))) { + setWidgetIsHidden(false, new WidgetPointer(917,119)); + setWidgetIsHidden(false, new WidgetPointer(917,115)); + } else { + setWidgetIsHidden(true, new WidgetPointer(917,119)); + setWidgetIsHidden(true, new WidgetPointer(917,115)); + } + return; +} diff --git a/dumps/scripts/4016.cs2 b/dumps/scripts/4016.cs2 new file mode 100644 index 0000000..766b3ab --- /dev/null +++ b/dumps/scripts/4016.cs2 @@ -0,0 +1,7 @@ +void script_4016() { + script_4017(bitconfig_8582); + script_4028(0, bitconfig_8579); + script_4028(1, bitconfig_8580); + script_4253(); + return; +} diff --git a/dumps/scripts/4017.cs2 b/dumps/scripts/4017.cs2 new file mode 100644 index 0000000..4510c03 --- /dev/null +++ b/dumps/scripts/4017.cs2 @@ -0,0 +1,33 @@ +void script_4017(int arg0) { + string svar0; + string svar1; + setWidgetText(new WidgetPointer(917,121), cs2method_3408(105, 115, 3487, arg0)); + svar0 = "Click to hide completed Tasks."; + svar1 = "Click to hide Tasks which are not in a set."; + if (((boolean)bitconfig_8579)) { + setScriptCallOnClickContextMenu(3983, 999, 0, 999, "iii", new WidgetPointer(917,106)); + svar0 = "Click to show completed Tasks."; + } else { + setScriptCallOnClickContextMenu(3983, 999, 1, 999, "iii", new WidgetPointer(917,106)); + } + setScriptCallOnMouseOver(38, new WidgetPointer(917,94), new WidgetPointer(917,97), svar0, 45, 150, "IIsii", new WidgetPointer(917,106)); + if (((boolean)bitconfig_8580)) { + setScriptCallOnClickContextMenu(3983, 999, 999, 0, "iii", new WidgetPointer(917,114)); + svar1 = "Click to show Tasks which are not in a set."; + } else { + setScriptCallOnClickContextMenu(3983, 999, 999, 1, "iii", new WidgetPointer(917,114)); + } + setScriptCallOnMouseOver(38, new WidgetPointer(917,94), new WidgetPointer(917,97), svar1, 45, 150, "IIsii", new WidgetPointer(917,114)); + if (((boolean)globalint_1429)) { + setWidgetSprite(4086, new WidgetPointer(917,142)); + setScriptCallOnMouseEntered(4033, 0, 1, "ii", new WidgetPointer(917,142)); + setScriptCallOnMouseExit(4033, 1, 1, "ii", new WidgetPointer(917,142)); + setWidgetContextMenuOption(1, new WidgetPointer(917,142), "Turn-on"); + } else { + setWidgetSprite(4084, new WidgetPointer(917,142)); + setScriptCallOnMouseEntered(4033, 0, 0, "ii", new WidgetPointer(917,142)); + setScriptCallOnMouseExit(4033, 1, 0, "ii", new WidgetPointer(917,142)); + setWidgetContextMenuOption(1, new WidgetPointer(917,142), "Turn-off"); + } + return; +} diff --git a/dumps/scripts/4018.cs2 b/dumps/scripts/4018.cs2 new file mode 100644 index 0000000..d47eede --- /dev/null +++ b/dumps/scripts/4018.cs2 @@ -0,0 +1,4 @@ +void script_4018(int arg0) { + script_4019(arg0); + return; +} diff --git a/dumps/scripts/4019.cs2 b/dumps/scripts/4019.cs2 new file mode 100644 index 0000000..3c73f3f --- /dev/null +++ b/dumps/scripts/4019.cs2 @@ -0,0 +1,62 @@ +void script_4019(int arg0) { + switch (arg0) { + case 0: + setWidgetIsHidden(false, new WidgetPointer(917,83)); + setWidgetIsHidden(true, new WidgetPointer(917,84)); + setWidgetIsHidden(true, new WidgetPointer(917,82)); + setWidgetIsHidden(true, new WidgetPointer(917,86)); + setWidgetSprite(4320, new WidgetPointer(917,26)); + setWidgetSprite(4320, new WidgetPointer(917,28)); + setWidgetSprite(4321, new WidgetPointer(917,27)); + break; + case 1: + setWidgetIsHidden(true, new WidgetPointer(917,83)); + setWidgetIsHidden(false, new WidgetPointer(917,84)); + setWidgetIsHidden(true, new WidgetPointer(917,82)); + setWidgetIsHidden(true, new WidgetPointer(917,86)); + setWidgetSprite(4320, new WidgetPointer(917,22)); + setWidgetSprite(4320, new WidgetPointer(917,24)); + setWidgetSprite(4321, new WidgetPointer(917,23)); + setWidgetScrollMax(0, max(globalint_1419, getWidgetActualHeight(new WidgetPointer(917,85))), new WidgetPointer(917,85)); + script_31(60096655, 60096597, 4343, 4340, 4341, 4342, 4337, 4336); + if (globalint_1419 > getWidgetActualHeight(new WidgetPointer(917,85))) { + setWidgetIsHidden(false, new WidgetPointer(917,143)); + } else { + setWidgetIsHidden(true, new WidgetPointer(917,143)); + } + break; + case 2: + setWidgetIsHidden(true, new WidgetPointer(917,83)); + setWidgetIsHidden(true, new WidgetPointer(917,84)); + setWidgetIsHidden(false, new WidgetPointer(917,82)); + setWidgetIsHidden(true, new WidgetPointer(917,86)); + setWidgetSprite(4320, new WidgetPointer(917,18)); + setWidgetSprite(4320, new WidgetPointer(917,20)); + setWidgetSprite(4321, new WidgetPointer(917,19)); + setWidgetScrollMax(0, max(globalint_1418, getWidgetActualHeight(new WidgetPointer(917,61))), new WidgetPointer(917,61)); + script_31(60096574, 60096573, 4343, 4340, 4341, 4342, 4337, 4336); + if (globalint_1418 > getWidgetActualHeight(new WidgetPointer(917,61))) { + setWidgetIsHidden(false, new WidgetPointer(917,62)); + } else { + setWidgetIsHidden(true, new WidgetPointer(917,62)); + } + break; + case 3: + setWidgetIsHidden(true, new WidgetPointer(917,83)); + setWidgetIsHidden(true, new WidgetPointer(917,84)); + setWidgetIsHidden(true, new WidgetPointer(917,82)); + setWidgetIsHidden(false, new WidgetPointer(917,86)); + setWidgetSprite(4320, new WidgetPointer(917,14)); + setWidgetSprite(4320, new WidgetPointer(917,16)); + setWidgetSprite(4321, new WidgetPointer(917,15)); + setWidgetScrollMax(0, max(globalint_1420, getWidgetActualHeight(new WidgetPointer(917,88))), new WidgetPointer(917,88)); + script_31(60096601, 60096600, 4343, 4340, 4341, 4342, 4337, 4336); + if (globalint_1420 > getWidgetActualHeight(new WidgetPointer(917,88))) { + setWidgetIsHidden(false, new WidgetPointer(917,89)); + } else { + setWidgetIsHidden(true, new WidgetPointer(917,89)); + } + } + script_4026(0); + return; +} diff --git a/dumps/scripts/402.cs2 b/dumps/scripts/402.cs2 new file mode 100644 index 0000000..cbe8339 --- /dev/null +++ b/dumps/scripts/402.cs2 @@ -0,0 +1,5 @@ +void script_402() { + cs2method2103(0, new WidgetPointer(1010,10)); + globalint_1391 = 1; + return; +} diff --git a/dumps/scripts/4020.cs2 b/dumps/scripts/4020.cs2 new file mode 100644 index 0000000..5a8d89a --- /dev/null +++ b/dumps/scripts/4020.cs2 @@ -0,0 +1,4 @@ +void script_4020() { + setWidgetIsHidden(true, new WidgetPointer(917,92)); + return; +} diff --git a/dumps/scripts/4021.cs2 b/dumps/scripts/4021.cs2 new file mode 100644 index 0000000..3d92de2 --- /dev/null +++ b/dumps/scripts/4021.cs2 @@ -0,0 +1,4 @@ +void script_4021(int arg0) { + script_4022(arg0); + return; +} diff --git a/dumps/scripts/4022.cs2 b/dumps/scripts/4022.cs2 new file mode 100644 index 0000000..054b14a --- /dev/null +++ b/dumps/scripts/4022.cs2 @@ -0,0 +1,23 @@ +void script_4022(int arg0) { + int ivar1; + int ivar2; + ivar1 = 0; + ivar2 = -1; + while (ivar1 <= getCommonDefinitionSize(3489)) { + ivar2 = ((int)cs2method_3408(105, 73, 3489, ivar1)); + if (ivar2 != -1) { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(ivar2)); + } + ivar1 = add(ivar1, 1); + } + ivar2 = ((int)cs2method_3408(105, 73, 3489, 62)); + if (ivar2 != -1) { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(ivar2)); + } + if ((arg0 > 60) && (arg0 != 62)) { + return; + } + ivar2 = ((int)cs2method_3408(105, 73, 3489, arg0)); + setWidgetRGB(new Color(146, 125, 89), new WidgetPointer(ivar2)); + return; +} diff --git a/dumps/scripts/4023.cs2 b/dumps/scripts/4023.cs2 new file mode 100644 index 0000000..9b7ed5a --- /dev/null +++ b/dumps/scripts/4023.cs2 @@ -0,0 +1,15 @@ +void script_4023(int arg0) { + if (((boolean)arg0)) { + setWidgetSprite(4324, new WidgetPointer(917,43)); + setWidgetSprite(4324, new WidgetPointer(917,45)); + setWidgetSprite(4325, new WidgetPointer(917,44)); + setWidgetSprite(4309, new WidgetPointer(917,59)); + } else { + script_41(60096605); + setWidgetSprite(4322, new WidgetPointer(917,43)); + setWidgetSprite(4322, new WidgetPointer(917,45)); + setWidgetSprite(4323, new WidgetPointer(917,44)); + setWidgetSprite(4308, new WidgetPointer(917,59)); + } + return; +} diff --git a/dumps/scripts/4024.cs2 b/dumps/scripts/4024.cs2 new file mode 100644 index 0000000..8852c3a --- /dev/null +++ b/dumps/scripts/4024.cs2 @@ -0,0 +1,13 @@ +void script_4024(int arg0) { + if (((boolean)arg0)) { + setWidgetSprite(4324, new WidgetPointer(917,90)); + setWidgetSprite(4324, new WidgetPointer(917,144)); + setWidgetSprite(4325, new WidgetPointer(917,145)); + } else { + script_41(60096605); + setWidgetSprite(4322, new WidgetPointer(917,90)); + setWidgetSprite(4322, new WidgetPointer(917,144)); + setWidgetSprite(4323, new WidgetPointer(917,145)); + } + return; +} diff --git a/dumps/scripts/4025.cs2 b/dumps/scripts/4025.cs2 new file mode 100644 index 0000000..f144475 --- /dev/null +++ b/dumps/scripts/4025.cs2 @@ -0,0 +1,4 @@ +void script_4025(int arg0) { + script_4026(arg0); + return; +} diff --git a/dumps/scripts/4026.cs2 b/dumps/scripts/4026.cs2 new file mode 100644 index 0000000..0a9110d --- /dev/null +++ b/dumps/scripts/4026.cs2 @@ -0,0 +1,58 @@ +void script_4026(int arg0) { + switch (arg0) { + case 0: + if (isWidgetHidden(new WidgetPointer(917,83))) { + setWidgetSprite(4316, new WidgetPointer(917,26)); + setWidgetSprite(4316, new WidgetPointer(917,28)); + setWidgetSprite(4317, new WidgetPointer(917,27)); + } + if (isWidgetHidden(new WidgetPointer(917,84))) { + setWidgetSprite(4316, new WidgetPointer(917,22)); + setWidgetSprite(4316, new WidgetPointer(917,24)); + setWidgetSprite(4317, new WidgetPointer(917,23)); + } + if (isWidgetHidden(new WidgetPointer(917,82))) { + setWidgetSprite(4316, new WidgetPointer(917,18)); + setWidgetSprite(4316, new WidgetPointer(917,20)); + setWidgetSprite(4317, new WidgetPointer(917,19)); + } + if (isWidgetHidden(new WidgetPointer(917,86))) { + setWidgetSprite(4316, new WidgetPointer(917,14)); + setWidgetSprite(4316, new WidgetPointer(917,16)); + setWidgetSprite(4317, new WidgetPointer(917,15)); + } + break; + case 1: + if (isWidgetHidden(new WidgetPointer(917,83))) { + return; + } + setWidgetSprite(4318, new WidgetPointer(917,26)); + setWidgetSprite(4318, new WidgetPointer(917,28)); + setWidgetSprite(4319, new WidgetPointer(917,27)); + break; + case 2: + if (isWidgetHidden(new WidgetPointer(917,84))) { + return; + } + setWidgetSprite(4318, new WidgetPointer(917,22)); + setWidgetSprite(4318, new WidgetPointer(917,24)); + setWidgetSprite(4319, new WidgetPointer(917,23)); + break; + case 3: + if (isWidgetHidden(new WidgetPointer(917,82))) { + return; + } + setWidgetSprite(4318, new WidgetPointer(917,18)); + setWidgetSprite(4318, new WidgetPointer(917,20)); + setWidgetSprite(4319, new WidgetPointer(917,19)); + break; + case 4: + if (isWidgetHidden(new WidgetPointer(917,86))) { + return; + } + setWidgetSprite(4318, new WidgetPointer(917,14)); + setWidgetSprite(4318, new WidgetPointer(917,16)); + setWidgetSprite(4319, new WidgetPointer(917,15)); + } + return; +} diff --git a/dumps/scripts/4027.cs2 b/dumps/scripts/4027.cs2 new file mode 100644 index 0000000..632cc45 --- /dev/null +++ b/dumps/scripts/4027.cs2 @@ -0,0 +1,4 @@ +void script_4027(int arg0,int arg1) { + script_4028(arg0, arg1); + return; +} diff --git a/dumps/scripts/4028.cs2 b/dumps/scripts/4028.cs2 new file mode 100644 index 0000000..63cd951 --- /dev/null +++ b/dumps/scripts/4028.cs2 @@ -0,0 +1,22 @@ +void script_4028(int arg0,int arg1) { + if (((boolean)arg0)) { + if (((boolean)arg1)) { + setWidgetSprite(4302, new WidgetPointer(917,106)); + setScriptCallOnMouseEntered(4029, 0, "i", new WidgetPointer(917,106)); + setScriptCallOnMouseExit(4029, 1, "i", new WidgetPointer(917,106)); + } else { + setWidgetSprite(4300, new WidgetPointer(917,106)); + setScriptCallOnMouseEntered(4030, 0, "i", new WidgetPointer(917,106)); + setScriptCallOnMouseExit(4030, 1, "i", new WidgetPointer(917,106)); + } + } else if (((boolean)arg1)) { + setWidgetSprite(4299, new WidgetPointer(917,114)); + setScriptCallOnMouseEntered(4031, 0, "i", new WidgetPointer(917,114)); + setScriptCallOnMouseExit(4031, 1, "i", new WidgetPointer(917,114)); + } else { + setWidgetSprite(4297, new WidgetPointer(917,114)); + setScriptCallOnMouseEntered(4032, 0, "i", new WidgetPointer(917,114)); + setScriptCallOnMouseExit(4032, 1, "i", new WidgetPointer(917,114)); + } + return; +} diff --git a/dumps/scripts/4029.cs2 b/dumps/scripts/4029.cs2 new file mode 100644 index 0000000..8c9eeba --- /dev/null +++ b/dumps/scripts/4029.cs2 @@ -0,0 +1,9 @@ +void script_4029(int arg0) { + if (((boolean)arg0)) { + setWidgetSprite(4304, new WidgetPointer(917,106)); + } else { + setWidgetSprite(4302, new WidgetPointer(917,106)); + script_41(60096609); + } + return; +} diff --git a/dumps/scripts/403.cs2 b/dumps/scripts/403.cs2 new file mode 100644 index 0000000..6f8c4b7 --- /dev/null +++ b/dumps/scripts/403.cs2 @@ -0,0 +1,4 @@ +void script_403() { + script_304(49466746); + return; +} diff --git a/dumps/scripts/4030.cs2 b/dumps/scripts/4030.cs2 new file mode 100644 index 0000000..76ca255 --- /dev/null +++ b/dumps/scripts/4030.cs2 @@ -0,0 +1,9 @@ +void script_4030(int arg0) { + if (((boolean)arg0)) { + setWidgetSprite(4301, new WidgetPointer(917,106)); + } else { + setWidgetSprite(4300, new WidgetPointer(917,106)); + script_41(60096609); + } + return; +} diff --git a/dumps/scripts/4031.cs2 b/dumps/scripts/4031.cs2 new file mode 100644 index 0000000..fea3077 --- /dev/null +++ b/dumps/scripts/4031.cs2 @@ -0,0 +1,9 @@ +void script_4031(int arg0) { + if (((boolean)arg0)) { + setWidgetSprite(4303, new WidgetPointer(917,114)); + } else { + setWidgetSprite(4299, new WidgetPointer(917,114)); + script_41(60096609); + } + return; +} diff --git a/dumps/scripts/4032.cs2 b/dumps/scripts/4032.cs2 new file mode 100644 index 0000000..2bb11cf --- /dev/null +++ b/dumps/scripts/4032.cs2 @@ -0,0 +1,9 @@ +void script_4032(int arg0) { + if (((boolean)arg0)) { + setWidgetSprite(4298, new WidgetPointer(917,114)); + } else { + setWidgetSprite(4297, new WidgetPointer(917,114)); + script_41(60096609); + } + return; +} diff --git a/dumps/scripts/4033.cs2 b/dumps/scripts/4033.cs2 new file mode 100644 index 0000000..c606e95 --- /dev/null +++ b/dumps/scripts/4033.cs2 @@ -0,0 +1,19 @@ +void script_4033(int arg0,int arg1) { + int ivar2; + ivar2 = -1; + if (((boolean)arg1)) { + if (((boolean)arg0)) { + ivar2 = 4087; + } else { + ivar2 = 4086; + script_41(60096664); + } + } else if (((boolean)arg0)) { + ivar2 = 4085; + } else { + ivar2 = 4084; + script_41(60096664); + } + setWidgetSprite(ivar2, new WidgetPointer(917,142)); + return; +} diff --git a/dumps/scripts/4034.cs2 b/dumps/scripts/4034.cs2 new file mode 100644 index 0000000..0ffcfa6 --- /dev/null +++ b/dumps/scripts/4034.cs2 @@ -0,0 +1,16 @@ +void script_4034() { + if (((boolean)globalint_1429)) { + globalint_1429 = 1; + setWidgetSprite(4086, new WidgetPointer(917,142)); + setScriptCallOnMouseEntered(4033, 0, 1, "ii", new WidgetPointer(917,142)); + setScriptCallOnMouseExit(4033, 1, 1, "ii", new WidgetPointer(917,142)); + setWidgetContextMenuOption(1, new WidgetPointer(917,142), "Turn-on"); + } else { + globalint_1429 = 0; + setWidgetSprite(4084, new WidgetPointer(917,142)); + setScriptCallOnMouseEntered(4033, 0, 0, "ii", new WidgetPointer(917,142)); + setScriptCallOnMouseExit(4033, 1, 0, "ii", new WidgetPointer(917,142)); + setWidgetContextMenuOption(1, new WidgetPointer(917,142), "Turn-off"); + } + return; +} diff --git a/dumps/scripts/4035.cs2 b/dumps/scripts/4035.cs2 new file mode 100644 index 0000000..3a28319 --- /dev/null +++ b/dumps/scripts/4035.cs2 @@ -0,0 +1,59 @@ +int script_4035() { + int ivar0; + ivar0 = 88; + if (bitconfig_5387 == 250) { + ivar0 = add(ivar0, 5); + } + if (bitconfig_2561 >= 3) { + ivar0 = add(ivar0, 5); + } + if (standart_config_131 >= 9) { + ivar0 = add(ivar0, 5); + } + if (bitconfig_358 == 15) { + ivar0 = add(ivar0, 10); + } + if (bitconfig_6001 >= 45) { + ivar0 = add(ivar0, 10); + } + if (standart_config_150 >= 160) { + ivar0 = add(ivar0, 5); + } + if (standart_config_223 >= 9) { + ivar0 = add(ivar0, 5); + } + if (bitconfig_1990 >= 430) { + ivar0 = add(ivar0, 5); + } + if (bitconfig_1383 >= 4) { + ivar0 = add(ivar0, 5); + } + if (bitconfig_5075 == 20) { + ivar0 = add(ivar0, 5); + } + if (standart_config_14 >= 7) { + ivar0 = add(ivar0, 5); + } + if (standart_config_112 >= 7) { + ivar0 = add(ivar0, 5); + } + if (standart_config_302 >= 61) { + ivar0 = add(ivar0, 5); + } + if (standart_config_63 >= 6) { + ivar0 = add(ivar0, 5); + } + if ((standart_config_145 >= 7) || (standart_config_146 >= 4)) { + ivar0 = add(ivar0, 5); + } + if (bitconfig_1028 >= 70) { + ivar0 = add(ivar0, 5); + } + if (standart_config_26 >= 80) { + ivar0 = add(ivar0, 5); + } + if (bitconfig_3523 >= 150) { + ivar0 = add(ivar0, 5); + } + return ivar0; +} diff --git a/dumps/scripts/4036.cs2 b/dumps/scripts/4036.cs2 new file mode 100644 index 0000000..4c2cd52 --- /dev/null +++ b/dumps/scripts/4036.cs2 @@ -0,0 +1,81 @@ +int script_4036(int arg0) { + int ivar1; + ivar1 = 0; + switch (arg0) { + case 1: + ivar1 = ((int)isBitFlagged(standart_config_1966, arg0)); + break; + case 2: + ivar1 = ((int)isBitFlagged(standart_config_1966, arg0)); + break; + case 3: + ivar1 = ((int)isBitFlagged(standart_config_1966, arg0)); + break; + case 4: + ivar1 = ((int)isBitFlagged(standart_config_1966, arg0)); + break; + case 5: + ivar1 = ((int)isBitFlagged(standart_config_1966, arg0)); + break; + case 6: + ivar1 = ((int)isBitFlagged(standart_config_1966, arg0)); + break; + case 7: + ivar1 = ((int)isBitFlagged(standart_config_1966, arg0)); + break; + case 8: + ivar1 = ((int)isBitFlagged(standart_config_1966, arg0)); + break; + case 9: + ivar1 = ((int)isBitFlagged(standart_config_1966, arg0)); + break; + case 10: + ivar1 = ((int)isBitFlagged(standart_config_1966, arg0)); + break; + case 11: + ivar1 = ((int)isBitFlagged(standart_config_1966, arg0)); + break; + case 12: + ivar1 = ((int)isBitFlagged(standart_config_1966, arg0)); + break; + case 13: + ivar1 = ((int)isBitFlagged(standart_config_1966, arg0)); + break; + case 14: + ivar1 = ((int)isBitFlagged(standart_config_1966, arg0)); + break; + case 15: + ivar1 = ((int)isBitFlagged(standart_config_1966, arg0)); + break; + case 16: + ivar1 = ((int)isBitFlagged(standart_config_1966, arg0)); + break; + case 17: + ivar1 = ((int)isBitFlagged(standart_config_1966, arg0)); + break; + case 18: + ivar1 = ((int)isBitFlagged(standart_config_1966, arg0)); + break; + case 19: + ivar1 = ((int)isBitFlagged(standart_config_1966, arg0)); + break; + case 20: + ivar1 = ((int)isBitFlagged(standart_config_1966, arg0)); + break; + case 21: + ivar1 = ((int)isBitFlagged(standart_config_1966, arg0)); + break; + case 22: + ivar1 = ((int)isBitFlagged(standart_config_1966, arg0)); + break; + case 23: + ivar1 = ((int)isBitFlagged(standart_config_1966, arg0)); + break; + case 24: + ivar1 = ((int)isBitFlagged(standart_config_1966, arg0)); + break; + case 25: + ivar1 = ((int)isBitFlagged(standart_config_1966, arg0)); + } + return ivar1; +} diff --git a/dumps/scripts/4037.cs2 b/dumps/scripts/4037.cs2 new file mode 100644 index 0000000..2da78d7 --- /dev/null +++ b/dumps/scripts/4037.cs2 @@ -0,0 +1,237 @@ +cs2func_script_4037_struct(3,0,0) script_4037(int arg0) { + int ivar1; + int ivar2; + int ivar3; + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + switch (arg0) { + case 1: + ivar3 = ((int)isBitFlagged(standart_config_1968, arg0)); + break; + case 2: + ivar3 = ((int)isBitFlagged(standart_config_1968, arg0)); + break; + case 3: + ivar3 = ((int)isBitFlagged(standart_config_1968, arg0)); + break; + case 4: + ivar3 = ((int)isBitFlagged(standart_config_1968, arg0)); + break; + case 5: + ivar3 = ((int)isBitFlagged(standart_config_1968, arg0)); + break; + case 6: + ivar3 = ((int)isBitFlagged(standart_config_1968, arg0)); + break; + case 7: + ivar3 = ((int)isBitFlagged(standart_config_1968, arg0)); + break; + case 8: + ivar3 = ((int)isBitFlagged(standart_config_1968, arg0)); + break; + case 9: + ivar3 = ((int)isBitFlagged(standart_config_1968, arg0)); + break; + case 10: + ivar3 = ((int)isBitFlagged(standart_config_1968, arg0)); + break; + case 11: + ivar3 = ((int)isBitFlagged(standart_config_1968, arg0)); + break; + case 12: + ivar3 = ((int)isBitFlagged(standart_config_1968, arg0)); + break; + case 13: + ivar3 = ((int)isBitFlagged(standart_config_1968, arg0)); + break; + case 14: + ivar3 = ((int)isBitFlagged(standart_config_1968, arg0)); + break; + case 15: + ivar3 = ((int)isBitFlagged(standart_config_1968, arg0)); + break; + case 16: + ivar3 = ((int)isBitFlagged(standart_config_1968, arg0)); + break; + case 17: + ivar3 = ((int)isBitFlagged(standart_config_1968, arg0)); + break; + case 18: + ivar3 = ((int)isBitFlagged(standart_config_1968, arg0)); + break; + case 19: + ivar3 = ((int)isBitFlagged(standart_config_1968, arg0)); + break; + case 20: + ivar3 = ((int)isBitFlagged(standart_config_1968, arg0)); + break; + case 21: + ivar3 = ((int)isBitFlagged(standart_config_1968, arg0)); + break; + case 22: + ivar3 = ((int)isBitFlagged(standart_config_1968, arg0)); + break; + case 23: + ivar3 = ((int)isBitFlagged(standart_config_1968, arg0)); + break; + case 24: + ivar3 = ((int)isBitFlagged(standart_config_1968, arg0)); + break; + case 25: + ivar3 = ((int)isBitFlagged(standart_config_1968, arg0)); + } + switch (arg0) { + case 1: + ivar1 = standart_config_1969; + break; + case 2: + ivar1 = standart_config_1970; + break; + case 3: + ivar1 = standart_config_1971; + break; + case 4: + ivar1 = standart_config_1972; + break; + case 5: + ivar1 = standart_config_1973; + break; + case 6: + ivar1 = standart_config_1974; + break; + case 7: + ivar1 = standart_config_1975; + break; + case 8: + ivar1 = standart_config_1976; + break; + case 9: + ivar1 = standart_config_1977; + break; + case 10: + ivar1 = standart_config_1978; + break; + case 11: + ivar1 = standart_config_1979; + break; + case 12: + ivar1 = standart_config_1980; + break; + case 13: + ivar1 = standart_config_1981; + break; + case 14: + ivar1 = standart_config_1982; + break; + case 15: + ivar1 = standart_config_1983; + break; + case 16: + ivar1 = standart_config_1984; + break; + case 17: + ivar1 = standart_config_1985; + break; + case 18: + ivar1 = standart_config_1986; + break; + case 19: + ivar1 = standart_config_1987; + break; + case 20: + ivar1 = standart_config_1988; + break; + case 21: + ivar1 = standart_config_1989; + break; + case 22: + ivar1 = standart_config_1990; + break; + case 23: + ivar1 = standart_config_1991; + break; + case 24: + ivar1 = standart_config_1992; + break; + case 25: + ivar1 = standart_config_1993; + } + switch (arg0) { + case 1: + ivar2 = standart_config_1994; + break; + case 2: + ivar2 = standart_config_1995; + break; + case 3: + ivar2 = standart_config_1996; + break; + case 4: + ivar2 = standart_config_1997; + break; + case 5: + ivar2 = standart_config_1998; + break; + case 6: + ivar2 = standart_config_1999; + break; + case 7: + ivar2 = standart_config_2000; + break; + case 8: + ivar2 = standart_config_2001; + break; + case 9: + ivar2 = standart_config_2002; + break; + case 10: + ivar2 = standart_config_2003; + break; + case 11: + ivar2 = standart_config_2004; + break; + case 12: + ivar2 = standart_config_2005; + break; + case 13: + ivar2 = standart_config_2006; + break; + case 14: + ivar2 = standart_config_2007; + break; + case 15: + ivar2 = standart_config_2008; + break; + case 16: + ivar2 = standart_config_2009; + break; + case 17: + ivar2 = standart_config_2010; + break; + case 18: + ivar2 = standart_config_2011; + break; + case 19: + ivar2 = standart_config_2012; + break; + case 20: + ivar2 = standart_config_2013; + break; + case 21: + ivar2 = standart_config_2014; + break; + case 22: + ivar2 = standart_config_2015; + break; + case 23: + ivar2 = standart_config_2016; + break; + case 24: + ivar2 = standart_config_2017; + break; + case 25: + ivar2 = standart_config_2018; + } + return newstruct cs2func_script_4037_struct(ivar3, ivar1, ivar2); +} diff --git a/dumps/scripts/4038.cs2 b/dumps/scripts/4038.cs2 new file mode 100644 index 0000000..0b20481 --- /dev/null +++ b/dumps/scripts/4038.cs2 @@ -0,0 +1,37 @@ +void script_4038() { + int ivar0; + ivar0 = 0; + if (globalint_1407 < 9) { + switch (getAffid()) { + case 373: + case 254: + case 289: + case 290: + case 291: + case 257: + case 292: + case 293: + case 294: + case 295: + case 296: + case 13: + ivar0 = 0; + break; + default: + ivar0 = 1; + } + if (((boolean)ivar0)) { + cs2method5421(0, "redirect.ws?mod=create&ssl=true&dest=herotopia.ws#herotopia_info"); + return; + } + } + globalint_174 = 17; + setWidgetIsHidden(true, new WidgetPointer(673,57)); + setWidgetIsHidden(true, new WidgetPointer(673,56)); + setWidgetIsHidden(false, new WidgetPointer(673,58)); + setWidgetSprite(4129, new WidgetPointer(673,17)); + setWidgetSprite(4129, new WidgetPointer(673,14)); + setWidgetSprite(4129, new WidgetPointer(673,16)); + setWidgetSprite(4129, new WidgetPointer(673,15)); + return; +} diff --git a/dumps/scripts/4039.cs2 b/dumps/scripts/4039.cs2 new file mode 100644 index 0000000..be62b9e --- /dev/null +++ b/dumps/scripts/4039.cs2 @@ -0,0 +1,14 @@ +void script_4039(int arg0,int arg1) { + if (setWidgetRegister(new WidgetPointer(190,18), arg0)) { + if (((boolean)arg1)) { + setWidgetRGB(new Color(0, 255, 255)); + } else if (script_2193(arg0) == 2) { + setWidgetRGB(new Color(0, 255, 0)); + } else if (((boolean)script_2193(arg0))) { + setWidgetRGB(new Color(255, 255, 0)); + } else { + setWidgetRGB(new Color(255, 0, 0)); + } + } + return; +} diff --git a/dumps/scripts/404.cs2 b/dumps/scripts/404.cs2 new file mode 100644 index 0000000..75975a9 --- /dev/null +++ b/dumps/scripts/404.cs2 @@ -0,0 +1,4 @@ +void script_404(int arg0) { + setWidgetText(new WidgetPointer(arg0), "Conquest Ranking: " + intToStr(standart_config_1875)); + return; +} diff --git a/dumps/scripts/4040.cs2 b/dumps/scripts/4040.cs2 new file mode 100644 index 0000000..bf29e4e --- /dev/null +++ b/dumps/scripts/4040.cs2 @@ -0,0 +1,4 @@ +void script_4040() { + script_4041(); + return; +} diff --git a/dumps/scripts/4041.cs2 b/dumps/scripts/4041.cs2 new file mode 100644 index 0000000..bf20894 --- /dev/null +++ b/dumps/scripts/4041.cs2 @@ -0,0 +1,13 @@ +void script_4041() { + int ivar0; + ivar0 = 0; + if (getDisplayMode() < 2) { + setWidgetSize(0, 0, 1, 1, new WidgetPointer(906,256)); + } else { + setWidgetSize(956, 503, 0, 0, new WidgetPointer(906,256)); + } + if ((cs2method6139() == 2) && (getDisplayMode() != 1)) { + setWidgetSize(800, 503, 0, 0, new WidgetPointer(906,256)); + } + return; +} diff --git a/dumps/scripts/4042.cs2 b/dumps/scripts/4042.cs2 new file mode 100644 index 0000000..49e88ac --- /dev/null +++ b/dumps/scripts/4042.cs2 @@ -0,0 +1,83 @@ +void script_4042() { + switch (bitconfig_8648) { + case 1: + setWidgetPosition(-130, 0, 1, 0, cs2method_3408(105, 73, 755, 1)); + break; + case 2: + setWidgetPosition(-130, 0, 1, 0, cs2method_3408(105, 73, 755, 2)); + break; + case 3: + setWidgetPosition(-130, 0, 1, 0, cs2method_3408(105, 73, 755, 3)); + break; + case 4: + setWidgetPosition(-130, 0, 1, 0, cs2method_3408(105, 73, 755, 4)); + break; + case 5: + setWidgetPosition(-130, 0, 1, 0, cs2method_3408(105, 73, 755, 5)); + } + switch (bitconfig_8649) { + case 1: + setWidgetPosition(-65, 0, 1, 0, cs2method_3408(105, 73, 755, 1)); + break; + case 2: + setWidgetPosition(-65, 0, 1, 0, cs2method_3408(105, 73, 755, 2)); + break; + case 3: + setWidgetPosition(-65, 0, 1, 0, cs2method_3408(105, 73, 755, 3)); + break; + case 4: + setWidgetPosition(-65, 0, 1, 0, cs2method_3408(105, 73, 755, 4)); + break; + case 5: + setWidgetPosition(-65, 0, 1, 0, cs2method_3408(105, 73, 755, 5)); + } + switch (bitconfig_8650) { + case 1: + setWidgetPosition(0, 0, 1, 0, cs2method_3408(105, 73, 755, 1)); + break; + case 2: + setWidgetPosition(0, 0, 1, 0, cs2method_3408(105, 73, 755, 2)); + break; + case 3: + setWidgetPosition(0, 0, 1, 0, cs2method_3408(105, 73, 755, 3)); + break; + case 4: + setWidgetPosition(0, 0, 1, 0, cs2method_3408(105, 73, 755, 4)); + break; + case 5: + setWidgetPosition(0, 0, 1, 0, cs2method_3408(105, 73, 755, 5)); + } + switch (bitconfig_8651) { + case 1: + setWidgetPosition(65, 0, 1, 0, cs2method_3408(105, 73, 755, 1)); + break; + case 2: + setWidgetPosition(65, 0, 1, 0, cs2method_3408(105, 73, 755, 2)); + break; + case 3: + setWidgetPosition(65, 0, 1, 0, cs2method_3408(105, 73, 755, 3)); + break; + case 4: + setWidgetPosition(65, 0, 1, 0, cs2method_3408(105, 73, 755, 4)); + break; + case 5: + setWidgetPosition(65, 0, 1, 0, cs2method_3408(105, 73, 755, 5)); + } + switch (bitconfig_8652) { + case 1: + setWidgetPosition(130, 0, 1, 0, cs2method_3408(105, 73, 755, 1)); + break; + case 2: + setWidgetPosition(130, 0, 1, 0, cs2method_3408(105, 73, 755, 2)); + break; + case 3: + setWidgetPosition(130, 0, 1, 0, cs2method_3408(105, 73, 755, 3)); + break; + case 4: + setWidgetPosition(130, 0, 1, 0, cs2method_3408(105, 73, 755, 4)); + break; + case 5: + setWidgetPosition(130, 0, 1, 0, cs2method_3408(105, 73, 755, 5)); + } + return; +} diff --git a/dumps/scripts/4043.cs2 b/dumps/scripts/4043.cs2 new file mode 100644 index 0000000..9d0e162 --- /dev/null +++ b/dumps/scripts/4043.cs2 @@ -0,0 +1,28 @@ +void script_4043() { + if (((boolean)bitconfig_8655)) { + setWidgetIsHidden(true, new WidgetPointer(1057,35)); + } else { + setWidgetIsHidden(false, new WidgetPointer(1057,35)); + } + if (((boolean)bitconfig_8656)) { + setWidgetIsHidden(true, new WidgetPointer(1057,36)); + } else { + setWidgetIsHidden(false, new WidgetPointer(1057,36)); + } + if (((boolean)bitconfig_8657)) { + setWidgetIsHidden(true, new WidgetPointer(1057,37)); + } else { + setWidgetIsHidden(false, new WidgetPointer(1057,37)); + } + if (((boolean)bitconfig_8658)) { + setWidgetIsHidden(true, new WidgetPointer(1057,38)); + } else { + setWidgetIsHidden(false, new WidgetPointer(1057,38)); + } + if (((boolean)bitconfig_8659)) { + setWidgetIsHidden(true, new WidgetPointer(1057,39)); + } else { + setWidgetIsHidden(false, new WidgetPointer(1057,39)); + } + return; +} diff --git a/dumps/scripts/4044.cs2 b/dumps/scripts/4044.cs2 new file mode 100644 index 0000000..f0e08c5 --- /dev/null +++ b/dumps/scripts/4044.cs2 @@ -0,0 +1,4 @@ +void script_4044(int arg0) { + setWidgetText(new WidgetPointer(arg0), intToStr(bitconfig_8662)); + return; +} diff --git a/dumps/scripts/4045.cs2 b/dumps/scripts/4045.cs2 new file mode 100644 index 0000000..201f15f --- /dev/null +++ b/dumps/scripts/4045.cs2 @@ -0,0 +1,4 @@ +void script_4045(int arg0) { + setWidgetText(new WidgetPointer(arg0), intToStr(bitconfig_8663)); + return; +} diff --git a/dumps/scripts/4046.cs2 b/dumps/scripts/4046.cs2 new file mode 100644 index 0000000..c5ef41b --- /dev/null +++ b/dumps/scripts/4046.cs2 @@ -0,0 +1,4 @@ +void script_4046(int arg0) { + setWidgetText(new WidgetPointer(arg0), intToStr(bitconfig_8664)); + return; +} diff --git a/dumps/scripts/4047.cs2 b/dumps/scripts/4047.cs2 new file mode 100644 index 0000000..2b21595 --- /dev/null +++ b/dumps/scripts/4047.cs2 @@ -0,0 +1,4 @@ +void script_4047(int arg0) { + setWidgetText(new WidgetPointer(arg0), intToStr(bitconfig_8665)); + return; +} diff --git a/dumps/scripts/4048.cs2 b/dumps/scripts/4048.cs2 new file mode 100644 index 0000000..96ddded --- /dev/null +++ b/dumps/scripts/4048.cs2 @@ -0,0 +1,4 @@ +void script_4048(int arg0) { + setWidgetText(new WidgetPointer(arg0), intToStr(bitconfig_8666)); + return; +} diff --git a/dumps/scripts/4049.cs2 b/dumps/scripts/4049.cs2 new file mode 100644 index 0000000..ead50c9 --- /dev/null +++ b/dumps/scripts/4049.cs2 @@ -0,0 +1,8 @@ +void script_4049() { + script_4051(69271567, 0); + script_4051(69271576, 0); + script_4051(69271573, 0); + script_4051(69271564, 0); + script_4051(69271570, 0); + return; +} diff --git a/dumps/scripts/405.cs2 b/dumps/scripts/405.cs2 new file mode 100644 index 0000000..99a25f6 --- /dev/null +++ b/dumps/scripts/405.cs2 @@ -0,0 +1,6 @@ +void script_405(int arg0) { + cs2method2103(255, new WidgetPointer(arg0)); + setScriptCallOnGameloop(406, new WidgetPointer(-32768,3), "I", new WidgetPointer(arg0)); + setWidgetText(new WidgetPointer(arg0), "Conquest Ranking: " + intToStr(standart_config_1875)); + return; +} diff --git a/dumps/scripts/4050.cs2 b/dumps/scripts/4050.cs2 new file mode 100644 index 0000000..1c5525e --- /dev/null +++ b/dumps/scripts/4050.cs2 @@ -0,0 +1,7 @@ +void script_4050(int arg0,int arg1) { + if (((boolean)arg1)) { + playSoundEffect(10223, 1, 0); + } + script_4051(arg0, arg1); + return; +} diff --git a/dumps/scripts/4051.cs2 b/dumps/scripts/4051.cs2 new file mode 100644 index 0000000..bd531b2 --- /dev/null +++ b/dumps/scripts/4051.cs2 @@ -0,0 +1,13 @@ +void script_4051(int arg0,int arg1) { + setWidgetIsHidden(false, new WidgetPointer(arg0)); + cs2method2103(0, new WidgetPointer(arg0)); + if (((boolean)arg1)) { + setWidgetSprite(489, new WidgetPointer(arg0)); + setWidgetPosition(0, 22, 2, 0, new WidgetPointer(arg0)); + } else { + setWidgetSprite(534, new WidgetPointer(arg0)); + setWidgetPosition(0, subtract(1, getWidgetActualHeight(new WidgetPointer(arg0))), 2, 0, new WidgetPointer(arg0)); + } + setScriptCallOnGameloop(4052, new WidgetPointer(arg0), arg1, "Ii", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/4052.cs2 b/dumps/scripts/4052.cs2 new file mode 100644 index 0000000..fdff811 --- /dev/null +++ b/dumps/scripts/4052.cs2 @@ -0,0 +1,22 @@ +void script_4052(int arg0,int arg1) { + if (((boolean)arg1)) { + if (getWidgetActualY(new WidgetPointer(arg0)) < subtract(1, getWidgetActualHeight(new WidgetPointer(arg0)))) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(arg0)); + } else { + setWidgetPosition(0, subtract(getWidgetActualY(new WidgetPointer(arg0)), 1), 2, 0, new WidgetPointer(arg0)); + if (getWidgetShadeColor(new WidgetPointer(arg0)) < 245) { + cs2method2103(add(getWidgetShadeColor(new WidgetPointer(arg0)), 10), new WidgetPointer(arg0)); + } + } + } else if (getWidgetActualY(new WidgetPointer(arg0)) > 30) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(arg0)); + } else { + setWidgetPosition(0, add(getWidgetActualY(new WidgetPointer(arg0)), 1), 2, 0, new WidgetPointer(arg0)); + if (getWidgetShadeColor(new WidgetPointer(arg0)) < 245) { + cs2method2103(add(getWidgetShadeColor(new WidgetPointer(arg0)), 10), new WidgetPointer(arg0)); + } + } + return; +} diff --git a/dumps/scripts/4053.cs2 b/dumps/scripts/4053.cs2 new file mode 100644 index 0000000..e7d6708 --- /dev/null +++ b/dumps/scripts/4053.cs2 @@ -0,0 +1,22 @@ +void script_4053() { + switch (bitconfig_8661) { + case 0: + setWidgetText(new WidgetPointer(1057,26), "Using multiple token types"); + break; + case 1: + setWidgetText(new WidgetPointer(1057,26), "Using attack tokens"); + break; + case 2: + setWidgetText(new WidgetPointer(1057,26), "Using defence tokens"); + break; + case 3: + setWidgetText(new WidgetPointer(1057,26), "Using strength tokens"); + break; + case 4: + setWidgetText(new WidgetPointer(1057,26), "Using combat tokens"); + break; + case 5: + setWidgetText(new WidgetPointer(1057,26), "Using balance tokens"); + } + return; +} diff --git a/dumps/scripts/4054.cs2 b/dumps/scripts/4054.cs2 new file mode 100644 index 0000000..4697d8d --- /dev/null +++ b/dumps/scripts/4054.cs2 @@ -0,0 +1,4 @@ +void script_4054(int arg0) { + script_4055(arg0); + return; +} diff --git a/dumps/scripts/4055.cs2 b/dumps/scripts/4055.cs2 new file mode 100644 index 0000000..6511ed6 --- /dev/null +++ b/dumps/scripts/4055.cs2 @@ -0,0 +1,30 @@ +void script_4055(int arg0) { + if (((boolean)globalint_1432) || isWidgetHidden(new WidgetPointer(1058,9))) { + return; + } + if (isWidgetHidden(new WidgetPointer(1058,10)) && isWidgetHidden(new WidgetPointer(1058,9))) { + setWidgetIsHidden(false, new WidgetPointer(1058,9)); + setWidgetPosition(0, subtract(1, getWidgetActualHeight(new WidgetPointer(1058,9))), 1, 0, new WidgetPointer(1058,9)); + globalint_1432 = 1; + setWidgetNoOptions(new WidgetPointer(1058,2)); + setWidgetNoOptions(new WidgetPointer(1058,3)); + setScriptCallOnGameloop(4059, new WidgetPointer(1058,9), new WidgetPointer(arg0), "II", new WidgetPointer(arg0)); + } else { + globalint_1432 = 1; + setWidgetNoOptions(new WidgetPointer(1058,2)); + setWidgetNoOptions(new WidgetPointer(1058,3)); + setScriptCallOnGameloop(4058, new WidgetPointer(1058,10), new WidgetPointer(1058,9), new WidgetPointer(arg0), "III", new WidgetPointer(arg0)); + } + setWidgetSprite(4464, new WidgetPointer(1058,32)); + setWidgetSprite(2659, new WidgetPointer(1058,33)); + setWidgetSprite(2659, new WidgetPointer(1058,34)); + setWidgetSprite(4465, new WidgetPointer(1058,36)); + setWidgetSprite(2657, new WidgetPointer(1058,37)); + setWidgetSprite(2657, new WidgetPointer(1058,38)); + if (((((bitconfig_8662 < 30) || (bitconfig_8663 < 30)) || (bitconfig_8664 < 30)) || (bitconfig_8665 < 30)) || (bitconfig_8666 < 30)) { + script_4061(); + } else { + script_4062(); + } + return; +} diff --git a/dumps/scripts/4056.cs2 b/dumps/scripts/4056.cs2 new file mode 100644 index 0000000..71d29cb --- /dev/null +++ b/dumps/scripts/4056.cs2 @@ -0,0 +1,4 @@ +void script_4056(int arg0) { + script_4057(arg0); + return; +} diff --git a/dumps/scripts/4057.cs2 b/dumps/scripts/4057.cs2 new file mode 100644 index 0000000..38c0794 --- /dev/null +++ b/dumps/scripts/4057.cs2 @@ -0,0 +1,31 @@ +void script_4057(int arg0) { + if (((boolean)globalint_1432) || isWidgetHidden(new WidgetPointer(1058,10))) { + return; + } + if (isWidgetHidden(new WidgetPointer(1058,10)) && isWidgetHidden(new WidgetPointer(1058,9))) { + setWidgetIsHidden(false, new WidgetPointer(1058,10)); + setWidgetPosition(0, subtract(1, getWidgetActualHeight(new WidgetPointer(1058,10))), 1, 0, new WidgetPointer(1058,10)); + globalint_1432 = 1; + setWidgetNoOptions(new WidgetPointer(1058,2)); + setWidgetNoOptions(new WidgetPointer(1058,3)); + setScriptCallOnGameloop(4059, new WidgetPointer(1058,10), new WidgetPointer(arg0), "II", new WidgetPointer(arg0)); + } else { + globalint_1432 = 1; + setWidgetNoOptions(new WidgetPointer(1058,2)); + setWidgetNoOptions(new WidgetPointer(1058,3)); + setScriptCallOnGameloop(4058, new WidgetPointer(1058,9), new WidgetPointer(1058,10), new WidgetPointer(arg0), "III", new WidgetPointer(arg0)); + } + setWidgetSprite(4465, new WidgetPointer(1058,32)); + setWidgetSprite(2657, new WidgetPointer(1058,33)); + setWidgetSprite(2657, new WidgetPointer(1058,34)); + setWidgetSprite(4464, new WidgetPointer(1058,36)); + setWidgetSprite(2659, new WidgetPointer(1058,37)); + setWidgetSprite(2659, new WidgetPointer(1058,38)); + if ((((bitconfig_8662 < 200) && (bitconfig_8663 < 200)) && ((bitconfig_8664 < 200) && (bitconfig_8665 < 200))) && (bitconfig_8666 < 200)) { + script_4061(); + } else { + script_4062(); + } + globalint_1431 = 1; + return; +} diff --git a/dumps/scripts/4058.cs2 b/dumps/scripts/4058.cs2 new file mode 100644 index 0000000..f8e7b53 --- /dev/null +++ b/dumps/scripts/4058.cs2 @@ -0,0 +1,14 @@ +void script_4058(int arg0,int arg1,int arg2) { + int ivar3; + ivar3 = 5; + if (getWidgetActualY(new WidgetPointer(arg0)) > subtract(1, getWidgetActualHeight(new WidgetPointer(arg0)))) { + setWidgetPosition(0, subtract(getWidgetActualY(new WidgetPointer(arg0)), ivar3), 1, 0, new WidgetPointer(arg0)); + } else { + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg2)); + setWidgetIsHidden(true, new WidgetPointer(arg0)); + setWidgetIsHidden(false, new WidgetPointer(arg1)); + setWidgetPosition(0, subtract(1, getWidgetActualHeight(new WidgetPointer(arg1))), 1, 0, new WidgetPointer(arg1)); + setScriptCallOnGameloop(4059, new WidgetPointer(arg1), new WidgetPointer(arg2), "II", new WidgetPointer(arg2)); + } + return; +} diff --git a/dumps/scripts/4059.cs2 b/dumps/scripts/4059.cs2 new file mode 100644 index 0000000..ed4b5ac --- /dev/null +++ b/dumps/scripts/4059.cs2 @@ -0,0 +1,14 @@ +void script_4059(int arg0,int arg1) { + int ivar2; + ivar2 = 5; + if (getWidgetActualY(new WidgetPointer(arg0)) >= 0) { + setWidgetPosition(0, 0, 1, 0, new WidgetPointer(arg0)); + globalint_1432 = 0; + setWidgetContextMenuOption(1, new WidgetPointer(1058,2), "Select"); + setWidgetContextMenuOption(1, new WidgetPointer(1058,3), "Select"); + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg1)); + } else { + setWidgetPosition(0, add(getWidgetActualY(new WidgetPointer(arg0)), ivar2), 1, 0, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/406.cs2 b/dumps/scripts/406.cs2 new file mode 100644 index 0000000..52aa827 --- /dev/null +++ b/dumps/scripts/406.cs2 @@ -0,0 +1,8 @@ +void script_406(int arg0) { + if (getWidgetShadeColor(new WidgetPointer(arg0)) > 0) { + cs2method2103(max(subtract(getWidgetShadeColor(new WidgetPointer(arg0)), 1), 0), new WidgetPointer(arg0)); + } else { + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/4060.cs2 b/dumps/scripts/4060.cs2 new file mode 100644 index 0000000..71cd778 --- /dev/null +++ b/dumps/scripts/4060.cs2 @@ -0,0 +1,14 @@ +void script_4060() { + if (((boolean)bitconfig_8669)) { + if (((((bitconfig_8662 < 30) || (bitconfig_8663 < 30)) || (bitconfig_8664 < 30)) || (bitconfig_8665 < 30)) || (bitconfig_8666 < 30)) { + script_4061(); + } else { + script_4062(); + } + } else if ((((bitconfig_8662 < 200) && (bitconfig_8663 < 200)) && ((bitconfig_8664 < 200) && (bitconfig_8665 < 200))) && (bitconfig_8666 < 200)) { + script_4061(); + } else { + script_4062(); + } + return; +} diff --git a/dumps/scripts/4061.cs2 b/dumps/scripts/4061.cs2 new file mode 100644 index 0000000..dfbe573 --- /dev/null +++ b/dumps/scripts/4061.cs2 @@ -0,0 +1,5 @@ +void script_4061() { + setWidgetText(new WidgetPointer(1058,45), "Not Enough Tokens"); + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(1058,45)); + return; +} diff --git a/dumps/scripts/4062.cs2 b/dumps/scripts/4062.cs2 new file mode 100644 index 0000000..e2ecd04 --- /dev/null +++ b/dumps/scripts/4062.cs2 @@ -0,0 +1,5 @@ +void script_4062() { + setWidgetText(new WidgetPointer(1058,45), "Accept Token Options"); + setWidgetRGB(new Color(13, 0, 0), new WidgetPointer(1058,45)); + return; +} diff --git a/dumps/scripts/4063.cs2 b/dumps/scripts/4063.cs2 new file mode 100644 index 0000000..0a1dd80 --- /dev/null +++ b/dumps/scripts/4063.cs2 @@ -0,0 +1,22 @@ +void script_4063() { + if (((boolean)bitconfig_8669)) { + return; + } + switch (bitconfig_8668) { + case 1: + script_4065(69337113); + break; + case 4: + script_4065(69337112); + break; + case 5: + script_4065(69337110); + break; + case 3: + script_4065(69337111); + break; + case 2: + script_4065(69337114); + } + return; +} diff --git a/dumps/scripts/4064.cs2 b/dumps/scripts/4064.cs2 new file mode 100644 index 0000000..a75d25d --- /dev/null +++ b/dumps/scripts/4064.cs2 @@ -0,0 +1,8 @@ +void script_4064(int arg0) { + if (((boolean)globalint_1431)) { + return; + } + script_4065(arg0); + script_4069(); + return; +} diff --git a/dumps/scripts/4065.cs2 b/dumps/scripts/4065.cs2 new file mode 100644 index 0000000..3259fe6 --- /dev/null +++ b/dumps/scripts/4065.cs2 @@ -0,0 +1,55 @@ +void script_4065(int arg0) { + script_4066(); + switch (arg0) { + case 69337110: + setWidgetSprite(4444, new WidgetPointer(1058,19)); + setWidgetText(new WidgetPointer(1058,46), "Currently selected: Balance tokens - earned through the keg balancing minigame."); + setWidgetPosition(-160, 13, 1, 0, new WidgetPointer(arg0)); + if (bitconfig_8666 < 200) { + script_4061(); + } else { + script_4062(); + } + break; + case 69337111: + setWidgetSprite(4445, new WidgetPointer(1058,17)); + setWidgetText(new WidgetPointer(1058,46), "Currently selected: Strength tokens - earned through the shot put minigame."); + setWidgetPosition(-80, 13, 1, 0, new WidgetPointer(arg0)); + if (bitconfig_8662 < 200) { + script_4061(); + } else { + script_4062(); + } + break; + case 69337112: + setWidgetSprite(4446, new WidgetPointer(1058,15)); + setWidgetText(new WidgetPointer(1058,46), "Currently selected: Combat tokens - earned through the animator minigame."); + setWidgetPosition(0, 13, 1, 0, new WidgetPointer(arg0)); + if (bitconfig_8665 < 200) { + script_4061(); + } else { + script_4062(); + } + break; + case 69337114: + setWidgetSprite(4447, new WidgetPointer(1058,13)); + setWidgetText(new WidgetPointer(1058,46), "Currently selected: Defence tokens - earned through the catapult minigame."); + setWidgetPosition(80, 13, 1, 0, new WidgetPointer(arg0)); + if (bitconfig_8663 < 200) { + script_4061(); + } else { + script_4062(); + } + break; + case 69337113: + setWidgetSprite(4448, new WidgetPointer(1058,11)); + setWidgetText(new WidgetPointer(1058,46), "Currently selected: Attack tokens - earned through the dummy minigame."); + setWidgetPosition(160, 13, 1, 0, new WidgetPointer(arg0)); + if (bitconfig_8664 < 200) { + script_4061(); + } else { + script_4062(); + } + } + return; +} diff --git a/dumps/scripts/4066.cs2 b/dumps/scripts/4066.cs2 new file mode 100644 index 0000000..06429af --- /dev/null +++ b/dumps/scripts/4066.cs2 @@ -0,0 +1,13 @@ +void script_4066() { + setWidgetSprite(4459, new WidgetPointer(1058,19)); + setWidgetSprite(4460, new WidgetPointer(1058,17)); + setWidgetSprite(4461, new WidgetPointer(1058,15)); + setWidgetSprite(4462, new WidgetPointer(1058,13)); + setWidgetSprite(4463, new WidgetPointer(1058,11)); + setWidgetPosition(-160, 18, 1, 0, new WidgetPointer(1058,22)); + setWidgetPosition(-80, 18, 1, 0, new WidgetPointer(1058,23)); + setWidgetPosition(0, 18, 1, 0, new WidgetPointer(1058,24)); + setWidgetPosition(80, 18, 1, 0, new WidgetPointer(1058,26)); + setWidgetPosition(160, 18, 1, 0, new WidgetPointer(1058,25)); + return; +} diff --git a/dumps/scripts/4067.cs2 b/dumps/scripts/4067.cs2 new file mode 100644 index 0000000..0d082d2 --- /dev/null +++ b/dumps/scripts/4067.cs2 @@ -0,0 +1,19 @@ +void script_4067(int arg0) { + switch (arg0) { + case 69337110: + setWidgetPosition(-160, 13, 1, 0, new WidgetPointer(arg0)); + break; + case 69337111: + setWidgetPosition(-80, 13, 1, 0, new WidgetPointer(arg0)); + break; + case 69337112: + setWidgetPosition(0, 13, 1, 0, new WidgetPointer(arg0)); + break; + case 69337114: + setWidgetPosition(80, 13, 1, 0, new WidgetPointer(arg0)); + break; + case 69337113: + setWidgetPosition(160, 13, 1, 0, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/4068.cs2 b/dumps/scripts/4068.cs2 new file mode 100644 index 0000000..fefeabf --- /dev/null +++ b/dumps/scripts/4068.cs2 @@ -0,0 +1,29 @@ +void script_4068(int arg0) { + switch (arg0) { + case 69337110: + if (getWidgetSpriteId(new WidgetPointer(1058,19)) != 4444) { + setWidgetPosition(-160, 18, 1, 0, new WidgetPointer(arg0)); + } + break; + case 69337111: + if (getWidgetSpriteId(new WidgetPointer(1058,17)) != 4445) { + setWidgetPosition(-80, 18, 1, 0, new WidgetPointer(arg0)); + } + break; + case 69337112: + if (getWidgetSpriteId(new WidgetPointer(1058,15)) != 4446) { + setWidgetPosition(0, 18, 1, 0, new WidgetPointer(arg0)); + } + break; + case 69337114: + if (getWidgetSpriteId(new WidgetPointer(1058,13)) != 4447) { + setWidgetPosition(80, 18, 1, 0, new WidgetPointer(arg0)); + } + break; + case 69337113: + if (getWidgetSpriteId(new WidgetPointer(1058,11)) != 4448) { + setWidgetPosition(160, 18, 1, 0, new WidgetPointer(arg0)); + } + } + return; +} diff --git a/dumps/scripts/4069.cs2 b/dumps/scripts/4069.cs2 new file mode 100644 index 0000000..1340f57 --- /dev/null +++ b/dumps/scripts/4069.cs2 @@ -0,0 +1,5 @@ +void script_4069() { + globalint_1431 = 1; + setScriptCallOnGameloop(4070, getClientCycle(), "i", new WidgetPointer(1058,68)); + return; +} diff --git a/dumps/scripts/407.cs2 b/dumps/scripts/407.cs2 new file mode 100644 index 0000000..70fe39c --- /dev/null +++ b/dumps/scripts/407.cs2 @@ -0,0 +1,33 @@ +void script_407() { + int ivar0; + int ivar1; + int ivar2; + string svar0; + if (globalint_1362 < 1) { + return; + } + ivar0 = divide(multiply(globalint_1362, 6), 10); + ivar1 = 0; + ivar2 = 0; + svar0 = ""; + if (ivar0 < 60) { + ivar1 = ivar0; + } else { + ivar1 = mod(ivar0, 60); + ivar2 = divide(ivar0, 60); + } + if (ivar1 < 10) { + svar0 = concat("0", intToStr(ivar1)); + if (((boolean)ivar2) && ((boolean)globalint_1389)) { + globalint_1389 = 1; + if (((boolean)bitconfig_7511)) { + playSoundEffect2False(3434, 1, 0, 255); + } + } + } else { + svar0 = intToStr(ivar1); + } + setWidgetText(new WidgetPointer(1010,21), "Turn Time Left" + "
" + intToStr(ivar2) + ":" + svar0); + setWidgetText(new WidgetPointer(1013,24), intToStr(ivar2) + ":" + svar0); + return; +} diff --git a/dumps/scripts/4070.cs2 b/dumps/scripts/4070.cs2 new file mode 100644 index 0000000..73d584d --- /dev/null +++ b/dumps/scripts/4070.cs2 @@ -0,0 +1,7 @@ +void script_4070(int arg0) { + if (getClientCycle() > add(arg0, 25)) { + globalint_1431 = 0; + setScriptCallOnGameloop(-1, "", new WidgetPointer(1058,68)); + } + return; +} diff --git a/dumps/scripts/4071.cs2 b/dumps/scripts/4071.cs2 new file mode 100644 index 0000000..ec9321e --- /dev/null +++ b/dumps/scripts/4071.cs2 @@ -0,0 +1,12 @@ +void script_4071(int arg0) { + if (arg0 == 69337132) { + setWidgetIsHidden(false, new WidgetPointer(1058,31)); + } else if (arg0 == 69337090) { + setWidgetIsHidden(false, new WidgetPointer(1058,39)); + } else { + if (arg0 == 69337091) { + setWidgetIsHidden(false, new WidgetPointer(1058,35)); + } + } + return; +} diff --git a/dumps/scripts/4072.cs2 b/dumps/scripts/4072.cs2 new file mode 100644 index 0000000..f706ee7 --- /dev/null +++ b/dumps/scripts/4072.cs2 @@ -0,0 +1,12 @@ +void script_4072(int arg0) { + if (arg0 == 69337132) { + setWidgetIsHidden(true, new WidgetPointer(1058,31)); + } else if (arg0 == 69337090) { + setWidgetIsHidden(true, new WidgetPointer(1058,39)); + } else { + if (arg0 == 69337091) { + setWidgetIsHidden(true, new WidgetPointer(1058,35)); + } + } + return; +} diff --git a/dumps/scripts/4073.cs2 b/dumps/scripts/4073.cs2 new file mode 100644 index 0000000..eff824d --- /dev/null +++ b/dumps/scripts/4073.cs2 @@ -0,0 +1,10 @@ +void script_4073() { + if (((boolean)bitconfig_8669)) { + globalint_1432 = 0; + script_4057(69337090); + } else { + globalint_1432 = 0; + script_4055(69337091); + } + return; +} diff --git a/dumps/scripts/4074.cs2 b/dumps/scripts/4074.cs2 new file mode 100644 index 0000000..953d3f8 --- /dev/null +++ b/dumps/scripts/4074.cs2 @@ -0,0 +1,20 @@ +void script_4074(string arg0) { + int ivar0; + ivar0 = 0; + ivar0 = multiply(getLineCount(346, 495, arg0), 13); + if (ivar0 > 48) { + ivar0 = multiply(getLineCount(328, 495, arg0), 13); + } + if (ivar0 > 48) { + setWidgetScrollMax(0, ivar0, new WidgetPointer(178,65)); + script_31(11665471, 11665473, 792, 789, 790, 791, 773, 788); + setWidgetSize(334, 48, 0, 0, new WidgetPointer(178,65)); + setWidgetSize(16384, ivar0, 2, 0, new WidgetPointer(178,2)); + setWidgetSize(16384, ivar0, 2, 0, new WidgetPointer(178,3)); + setWidgetTextAlignment(0, 0, 0, new WidgetPointer(178,66)); + } else { + setWidgetSize(354, 48, 0, 0, new WidgetPointer(178,65)); + setWidgetTextAlignment(0, 1, 0, new WidgetPointer(178,66)); + } + return; +} diff --git a/dumps/scripts/4075.cs2 b/dumps/scripts/4075.cs2 new file mode 100644 index 0000000..155756a --- /dev/null +++ b/dumps/scripts/4075.cs2 @@ -0,0 +1,24 @@ +void script_4075(int arg0) { + switch (globalint_1433) { + case 1: + script_2766(0, 50, arg0); + break; + case 2: + script_2768(50, arg0); + cs2method5405(0, 2); + cs2method5405(1, 2); + cs2method5406(0, 0, script_4077(16, 11), 500, script_4077(16, 11), 500, 0); + cs2method5406(0, 1, script_4077(14, 12), 400, script_4077(14, 12), 400, 0); + cs2method5406(1, 0, script_4077(15, 15), 400, script_4077(15, 15), 400, 0); + cs2method5406(1, 1, script_4077(15, 15), 300, script_4077(15, 15), 300, 0); + cameraMethod5502(0, 0, 100, 100, 1, 0); + break; + case 3: + script_2766(0, 30, arg0); + break; + case 4: + cameraUnlock(); + script_2768(50, arg0); + } + return; +} diff --git a/dumps/scripts/4076.cs2 b/dumps/scripts/4076.cs2 new file mode 100644 index 0000000..fa4caf7 --- /dev/null +++ b/dumps/scripts/4076.cs2 @@ -0,0 +1,33 @@ +void script_4076(int arg0) { + switch (globalint_1434) { + case 1: + script_2766(0, 50, arg0); + break; + case 2: + script_2768(50, arg0); + cs2method5405(0, 2); + cs2method5405(1, 2); + cs2method5406(0, 0, script_4077(14, 6), 1200, script_4077(14, 6), 1200, 0); + cs2method5406(0, 1, script_4077(14, 4), 1100, script_4077(14, 4), 1100, 0); + cs2method5406(1, 0, script_4077(15, 15), 500, script_4077(15, 15), 500, 0); + cs2method5406(1, 1, script_4077(15, 14), 400, script_4077(15, 14), 400, 0); + cameraMethod5502(0, 0, 260, 260, 1, 0); + break; + case 3: + cs2method5405(0, 2); + cs2method5405(1, 2); + cs2method5406(0, 0, script_4077(14, 4), 1100, script_4077(14, 4), 1100, 0); + cs2method5406(0, 1, script_4077(14, 0), 900, script_4077(14, 0), 900, 0); + cs2method5406(1, 0, script_4077(15, 14), 400, script_4077(15, 14), 400, 0); + cs2method5406(1, 1, script_4077(15, 14), 300, script_4077(15, 14), 300, 0); + cameraMethod5502(0, 0, 250, 250, 1, 0); + break; + case 4: + script_2766(0, 30, arg0); + break; + case 5: + cameraUnlock(); + script_2768(50, arg0); + } + return; +} diff --git a/dumps/scripts/4077.cs2 b/dumps/scripts/4077.cs2 new file mode 100644 index 0000000..710baad --- /dev/null +++ b/dumps/scripts/4077.cs2 @@ -0,0 +1,5 @@ +int script_4077(int arg0,int arg1) { + int ivar2; + ivar2 = script_284(getMyPositionHash()); + return addToCoordinate(ivar2, arg0, 0, arg1); +} diff --git a/dumps/scripts/4078.cs2 b/dumps/scripts/4078.cs2 new file mode 100644 index 0000000..bddfdee --- /dev/null +++ b/dumps/scripts/4078.cs2 @@ -0,0 +1,4 @@ +void script_4078() { + script_4079(bitconfig_8697); + return; +} diff --git a/dumps/scripts/4079.cs2 b/dumps/scripts/4079.cs2 new file mode 100644 index 0000000..9664a34 --- /dev/null +++ b/dumps/scripts/4079.cs2 @@ -0,0 +1,14 @@ +void script_4079(int arg0) { + if (setWidgetRegister(new WidgetPointer(1064,2), 0)) { + if (arg0 <= 30) { + setWidgetSize(multiply(arg0, 8), 8, 0, 0); + } + } else { + createExtraChild(new WidgetPointer(1064,2), 3, 0); + setWidgetPosition(44, 44, 0, 0); + setWidgetSize(multiply(8, 30), 8, 0, 0); + setWidgetRGB(new Color(201, 108, 62)); + setWidgetFilled(1); + } + return; +} diff --git a/dumps/scripts/408.cs2 b/dumps/scripts/408.cs2 new file mode 100644 index 0000000..f6ade24 --- /dev/null +++ b/dumps/scripts/408.cs2 @@ -0,0 +1,22 @@ +void script_408(int arg0) { + if (globalint_1363 == arg0) { + return; + } + setScriptCallOnGlobalConfigChange(408, globalint_1363, 1363, 1, "iY", new WidgetPointer(1013,1)); + globalint_1389 = 0; + if (globalint_1363 == bitconfig_7510) { + setWidgetIsHidden(false, new WidgetPointer(1010,33)); + setWidgetIsHidden(true, new WidgetPointer(1010,32)); + setWidgetIsHidden(true, new WidgetPointer(1010,24)); + setWidgetText(new WidgetPointer(1013,26), "Your Turn"); + playSoundEffect2False(3439, 1, 0, 255); + } else { + setWidgetIsHidden(true, new WidgetPointer(1010,33)); + setWidgetIsHidden(true, new WidgetPointer(1010,24)); + setWidgetText(new WidgetPointer(1013,26), "Opponent's Turn"); + if (isWidgetHidden(new WidgetPointer(1010,7))) { + setWidgetIsHidden(false, new WidgetPointer(1010,32)); + } + } + return; +} diff --git a/dumps/scripts/4080.cs2 b/dumps/scripts/4080.cs2 new file mode 100644 index 0000000..8339ab6 --- /dev/null +++ b/dumps/scripts/4080.cs2 @@ -0,0 +1,12 @@ +void script_4080() { + if (setWidgetRegister(new WidgetPointer(1060,0))) { + setWidgetSprite(4032); + } + if (setWidgetRegister(new WidgetPointer(1060,2))) { + setWidgetSprite(4035); + } + if (setWidgetRegister(new WidgetPointer(1060,1))) { + setWidgetSprite(4038); + } + return; +} diff --git a/dumps/scripts/4081.cs2 b/dumps/scripts/4081.cs2 new file mode 100644 index 0000000..5f50309 --- /dev/null +++ b/dumps/scripts/4081.cs2 @@ -0,0 +1,12 @@ +void script_4081() { + if (setWidgetRegister(new WidgetPointer(1060,0))) { + setWidgetSprite(4031); + } + if (setWidgetRegister(new WidgetPointer(1060,2))) { + setWidgetSprite(4034); + } + if (setWidgetRegister(new WidgetPointer(1060,1))) { + setWidgetSprite(4037); + } + return; +} diff --git a/dumps/scripts/4082.cs2 b/dumps/scripts/4082.cs2 new file mode 100644 index 0000000..07eb19b --- /dev/null +++ b/dumps/scripts/4082.cs2 @@ -0,0 +1,12 @@ +void script_4082() { + if (setWidgetRegister(new WidgetPointer(1060,0))) { + setWidgetSprite(4033); + } + if (setWidgetRegister(new WidgetPointer(1060,2))) { + setWidgetSprite(4036); + } + if (setWidgetRegister(new WidgetPointer(1060,1))) { + setWidgetSprite(4039); + } + return; +} diff --git a/dumps/scripts/4083.cs2 b/dumps/scripts/4083.cs2 new file mode 100644 index 0000000..1535796 --- /dev/null +++ b/dumps/scripts/4083.cs2 @@ -0,0 +1,12 @@ +void script_4083() { + if (setWidgetRegister(new WidgetPointer(1061,3)) && (getWidgetSpriteId() == 4032)) { + setWidgetSprite(4031); + } + if (setWidgetRegister(new WidgetPointer(1061,4)) && (getWidgetSpriteId() == 4035)) { + setWidgetSprite(4034); + } + if (setWidgetRegister(new WidgetPointer(1061,5)) && (getWidgetSpriteId() == 4038)) { + setWidgetSprite(4037); + } + return; +} diff --git a/dumps/scripts/4084.cs2 b/dumps/scripts/4084.cs2 new file mode 100644 index 0000000..ebc8031 --- /dev/null +++ b/dumps/scripts/4084.cs2 @@ -0,0 +1,12 @@ +void script_4084() { + if (setWidgetRegister(new WidgetPointer(1061,3)) && (getWidgetSpriteId() != 4033)) { + setWidgetSprite(4032); + } + if (setWidgetRegister(new WidgetPointer(1061,4)) && (getWidgetSpriteId() != 4036)) { + setWidgetSprite(4035); + } + if (setWidgetRegister(new WidgetPointer(1061,5)) && (getWidgetSpriteId() != 4039)) { + setWidgetSprite(4038); + } + return; +} diff --git a/dumps/scripts/4085.cs2 b/dumps/scripts/4085.cs2 new file mode 100644 index 0000000..809e41d --- /dev/null +++ b/dumps/scripts/4085.cs2 @@ -0,0 +1,12 @@ +void script_4085() { + if (setWidgetRegister(new WidgetPointer(1061,3))) { + setWidgetSprite(4031); + } + if (setWidgetRegister(new WidgetPointer(1061,4))) { + setWidgetSprite(4034); + } + if (setWidgetRegister(new WidgetPointer(1061,5))) { + setWidgetSprite(4037); + } + return; +} diff --git a/dumps/scripts/4086.cs2 b/dumps/scripts/4086.cs2 new file mode 100644 index 0000000..d053388 --- /dev/null +++ b/dumps/scripts/4086.cs2 @@ -0,0 +1,12 @@ +void script_4086() { + if (setWidgetRegister(new WidgetPointer(1061,3))) { + setWidgetSprite(4033); + } + if (setWidgetRegister(new WidgetPointer(1061,4))) { + setWidgetSprite(4036); + } + if (setWidgetRegister(new WidgetPointer(1061,5))) { + setWidgetSprite(4039); + } + return; +} diff --git a/dumps/scripts/4087.cs2 b/dumps/scripts/4087.cs2 new file mode 100644 index 0000000..68b0de4 --- /dev/null +++ b/dumps/scripts/4087.cs2 @@ -0,0 +1,8 @@ +void script_4087(int arg0) { + if (((boolean)bitconfig_8701)) { + setWidgetSprite(3012, new WidgetPointer(arg0)); + } else { + setWidgetSprite(3010, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/4088.cs2 b/dumps/scripts/4088.cs2 new file mode 100644 index 0000000..d96f5ab --- /dev/null +++ b/dumps/scripts/4088.cs2 @@ -0,0 +1,8 @@ +void script_4088(int arg0) { + if (((boolean)bitconfig_8701)) { + setWidgetSprite(3012, new WidgetPointer(arg0)); + } else { + setWidgetSprite(3010, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/4089.cs2 b/dumps/scripts/4089.cs2 new file mode 100644 index 0000000..9ecbbd0 --- /dev/null +++ b/dumps/scripts/4089.cs2 @@ -0,0 +1,15 @@ +void script_4089() { + int ivar0; + ivar0 = 35913927; + if (getDisplayMode() >= 2) { + ivar0 = 48889943; + } + if ((isParent(new WidgetPointer(script_8(1)), 1056) && isWidgetOpen(new WidgetPointer(ivar0))) && (((boolean)script_2728()) && (bitconfig_8587 != 419))) { + setWidgetIsHidden(false, new WidgetPointer(746,130)); + setWidgetIsHidden(false, new WidgetPointer(548,137)); + } else { + setWidgetIsHidden(true, new WidgetPointer(746,130)); + setWidgetIsHidden(true, new WidgetPointer(548,137)); + } + return; +} diff --git a/dumps/scripts/409.cs2 b/dumps/scripts/409.cs2 new file mode 100644 index 0000000..85947fd --- /dev/null +++ b/dumps/scripts/409.cs2 @@ -0,0 +1,16 @@ +void script_409() { + globalint_1364 = add(globalint_1364, 1); + if (globalint_1364 == 50) { + setWidgetText(new WidgetPointer(1010,41), "Opponent's Turn"); + } else if (globalint_1364 == 100) { + setWidgetText(new WidgetPointer(1010,41), "Opponent's Turn."); + } else if (globalint_1364 == 150) { + setWidgetText(new WidgetPointer(1010,41), "Opponent's Turn.."); + } else { + if (globalint_1364 >= 200) { + setWidgetText(new WidgetPointer(1010,41), "Opponent's Turn..."); + globalint_1364 = 0; + } + } + return; +} diff --git a/dumps/scripts/4090.cs2 b/dumps/scripts/4090.cs2 new file mode 100644 index 0000000..1a70abd --- /dev/null +++ b/dumps/scripts/4090.cs2 @@ -0,0 +1,6 @@ +void script_4090(int arg0,int arg1,int arg2) { + setScriptCallOnSkillChange(4091, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), "III", new WidgetPointer(arg0)); + setScriptCallOnAnyWidgetOpenAndClose(4091, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), "III", new WidgetPointer(arg0)); + script_4092(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/4091.cs2 b/dumps/scripts/4091.cs2 new file mode 100644 index 0000000..e0d2d37 --- /dev/null +++ b/dumps/scripts/4091.cs2 @@ -0,0 +1,4 @@ +void script_4091(int arg0,int arg1,int arg2) { + script_4092(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/4092.cs2 b/dumps/scripts/4092.cs2 new file mode 100644 index 0000000..c7a0562 --- /dev/null +++ b/dumps/scripts/4092.cs2 @@ -0,0 +1,16 @@ +void script_4092(int arg0,int arg1,int arg2) { + if (((boolean)script_2728())) { + if ((arg1 != -1) && (getExtraChildGap(new WidgetPointer(arg1)) <= 0)) { + script_4093(arg0, arg1); + } + script_4089(); + } else { + if ((arg1 != -1) && (getExtraChildGap(new WidgetPointer(arg1)) > 0)) { + deleteAllExtraChilds(new WidgetPointer(arg1)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(arg1)); + } + setWidgetIsHidden(true, new WidgetPointer(arg2)); + } + return; +} diff --git a/dumps/scripts/4093.cs2 b/dumps/scripts/4093.cs2 new file mode 100644 index 0000000..bff4c80 --- /dev/null +++ b/dumps/scripts/4093.cs2 @@ -0,0 +1,34 @@ +void script_4093(int arg0,int arg1) { + string svar0; + deleteAllExtraChilds(new WidgetPointer(arg1)); + createExtraChild(new WidgetPointer(arg1), 5, getExtraChildGap(new WidgetPointer(arg1))); + setWidgetSize(8, 23, 0, 0); + setWidgetPosition(0, 0, 0, 0); + setWidgetSprite(4514); + createExtraChild(new WidgetPointer(arg1), 5, getExtraChildGap(new WidgetPointer(arg1))); + setWidgetSize(8, 23, 0, 0); + setWidgetPosition(0, 0, 2, 0); + setWidgetSprite(4516); + createExtraChild(new WidgetPointer(arg1), 5, getExtraChildGap(new WidgetPointer(arg1))); + setWidgetSize(16, 23, 1, 0); + setWidgetPosition(0, 0, 1, 0); + cs2method1107(1); + setWidgetSprite(4515); + createExtraChild(new WidgetPointer(arg1), 4, getExtraChildGap(new WidgetPointer(arg1))); + setWidgetSize(0, 23, 1, 0); + setWidgetPosition(0, 0, 1, 0); + setWidgetFont(494); + setWidgetTextAlignment(1, 1, 0); + setWidgetRGB(new Color(0, 0, 0)); + setWidgetUnknownBoolean(false); + svar0 = "Task List"; + setWidgetText(svar0); + setWidgetSize(add(getTextWidth(494, svar0), 10), 32, 0, 0, new WidgetPointer(arg1)); + createExtraChild(new WidgetPointer(arg1), 5, getExtraChildGap(new WidgetPointer(arg1))); + setWidgetSize(21, 11, 0, 0); + setWidgetPosition(0, 0, 1, 2); + setWidgetSprite(4517); + script_4096(arg1); + script_4095(arg0, arg1, script_3365(48889986), script_3366(48889986), ((int)isWidgetHidden(new WidgetPointer(746,86)))); + return; +} diff --git a/dumps/scripts/4094.cs2 b/dumps/scripts/4094.cs2 new file mode 100644 index 0000000..e0eb4c0 --- /dev/null +++ b/dumps/scripts/4094.cs2 @@ -0,0 +1,20 @@ +void script_4094(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + int ivar6; + int ivar7; + int ivar8; + flow_0: + ivar6 = script_3365(48889986); + ivar7 = script_3366(48889986); + ivar8 = ((int)isWidgetHidden(new WidgetPointer(746,86))); + IF ((ivar6 != arg3) || (ivar7 != arg4)) + GOTO flow_1 + IF ((script_42(ivar8) != script_42(arg5)) && setWidgetRegister(new WidgetPointer(arg1), arg2)) + GOTO flow_2 + GOTO flow_3 + flow_1: + flow_2: + script_4095(arg0, arg1, ivar6, ivar7, ivar8); + flow_3: + script_4096(arg1); + return; +} diff --git a/dumps/scripts/4095.cs2 b/dumps/scripts/4095.cs2 new file mode 100644 index 0000000..7e3d543 --- /dev/null +++ b/dumps/scripts/4095.cs2 @@ -0,0 +1,28 @@ +void script_4095(int arg0,int arg1,int arg2,int arg3,int arg4) { + int ivar5; + int ivar6; + int ivar7; + int ivar8; + ivar5 = getWidgetActualWidth(new WidgetPointer(arg1)); + ivar6 = add(arg2, divide(subtract(getWidgetActualWidth(new WidgetPointer(746,130)), ivar5), 2)); + ivar7 = 0; + ivar8 = 0; + if (((boolean)arg4)) { + ivar7 = subtract(add(ivar6, ivar5), script_3365(48889942)); + if (ivar7 > 0) { + ivar8 = min(ivar7, divide(getWidgetActualWidth(new WidgetPointer(746,40)), 2)); + ivar6 = subtract(ivar6, ivar8); + ivar7 = subtract(ivar7, ivar8); + if (ivar7 > 0) { + ivar8 = min(ivar7, subtract(divide(subtract(ivar5, getWidgetActualWidth()), 2), 4)); + ivar6 = subtract(ivar6, ivar8); + } else { + ivar8 = 0; + } + } + } + setWidgetPosition(ivar8, 0, 1, 2); + setWidgetPosition(ivar6, subtract(add(arg3, 5), getWidgetActualHeight(new WidgetPointer(arg1))), 0, 0, new WidgetPointer(arg1)); + setScriptCallOnGameloop(4094, new WidgetPointer(arg0), new WidgetPointer(arg1), getWidgetCustomChildArrayIndex(), arg2, arg3, arg4, "IIiii1", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/4096.cs2 b/dumps/scripts/4096.cs2 new file mode 100644 index 0000000..55d7e80 --- /dev/null +++ b/dumps/scripts/4096.cs2 @@ -0,0 +1,8 @@ +void script_4096(int arg0) { + if ((isWidgetHidden(new WidgetPointer(746,131)) && isWidgetHidden(new WidgetPointer(746,23))) && isParent(new WidgetPointer(746,91), 1056)) { + setWidgetIsHidden(false, new WidgetPointer(arg0)); + } else { + setWidgetIsHidden(true, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/4097.cs2 b/dumps/scripts/4097.cs2 new file mode 100644 index 0000000..9ee5c7f --- /dev/null +++ b/dumps/scripts/4097.cs2 @@ -0,0 +1,25 @@ +void script_4097(int arg0,int arg1,string arg2) { + deleteAllExtraChilds(new WidgetPointer(arg0)); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(8, arg1, 0, 0); + setWidgetPosition(0, 0, 0, 0); + setWidgetSprite(4514); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(8, arg1, 0, 0); + setWidgetPosition(0, 0, 2, 0); + setWidgetSprite(4516); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(16, arg1, 1, 0); + setWidgetPosition(0, 0, 1, 0); + setWidgetSprite(4515); + createExtraChild(new WidgetPointer(arg0), 4, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(20, arg1, 1, 0); + setWidgetPosition(0, 1, 1, 0); + setWidgetFont(494); + setWidgetTextAlignment(1, 1, 0); + setWidgetRGB(new Color(0, 0, 0)); + setWidgetUnknownBoolean(false); + setWidgetText(arg2); + setWidgetIsHidden(false, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/4098.cs2 b/dumps/scripts/4098.cs2 new file mode 100644 index 0000000..85748c0 --- /dev/null +++ b/dumps/scripts/4098.cs2 @@ -0,0 +1,210 @@ +int script_4098() { + flow_0: + SWITCH (standart_config_281) { + case 7: + GOTO flow_1 + case 9: + GOTO flow_2 + case 10: + GOTO flow_3 + case 15: + GOTO flow_4 + case 20: + GOTO flow_5 + case 25: + GOTO flow_6 + case 30: + GOTO flow_7 + case 35: + GOTO flow_8 + case 40: + GOTO flow_9 + case 45: + GOTO flow_10 + case 46: + GOTO flow_11 + case 47: + GOTO flow_12 + case 48: + GOTO flow_13 + case 49: + GOTO flow_14 + case 50: + GOTO flow_15 + case 55: + GOTO flow_16 + case 56: + GOTO flow_17 + case 57: + GOTO flow_18 + case 60: + GOTO flow_19 + case 62: + GOTO flow_20 + case 65: + GOTO flow_21 + case 70: + GOTO flow_22 + case 75: + GOTO flow_23 + case 80: + GOTO flow_24 + case 82: + GOTO flow_25 + case 83: + GOTO flow_26 + case 90: + GOTO flow_27 + case 93: + GOTO flow_28 + case 95: + GOTO flow_29 + case 96: + GOTO flow_30 + case 98: + GOTO flow_31 + case 100: + GOTO flow_32 + case 105: + GOTO flow_33 + case 110: + GOTO flow_34 + case 115: + GOTO flow_35 + case 120: + GOTO flow_36 + case 123: + GOTO flow_37 + case 125: + GOTO flow_38 + case 126: + GOTO flow_39 + case 127: + GOTO flow_40 + case 128: + GOTO flow_41 + case 130: + GOTO flow_42 + case 135: + GOTO flow_43 + case 140: + GOTO flow_44 + case 145: + GOTO flow_45 + case 150: + GOTO flow_46 + case 155: + GOTO flow_47 + case 160: + GOTO flow_48 + case 165: + GOTO flow_49 + case 170: + GOTO flow_50 + case 1000: + GOTO flow_51 + } + return 4094; + flow_1: + return 3500; + flow_2: + return 3500; + flow_3: + return 3501; + flow_4: + return 3502; + flow_5: + return 3503; + flow_6: + return 3503; + flow_7: + return 3503; + flow_8: + return 3504; + flow_9: + return 3504; + flow_10: + return 3505; + flow_11: + return 3505; + flow_12: + return 3505; + flow_13: + return 3505; + flow_14: + return 3505; + flow_15: + return 3506; + flow_16: + return 3506; + flow_17: + return 3506; + flow_18: + return 3506; + flow_19: + return 3508; + flow_20: + return 3509; + flow_21: + return 3507; + flow_22: + return 3523; + flow_23: + return 3507; + flow_24: + return 3510; + flow_25: + return 3510; + flow_26: + return 3510; + flow_27: + return 3510; + flow_28: + return 3511; + flow_29: + return 3511; + flow_30: + return 3512; + flow_31: + return 3512; + flow_32: + return 3512; + flow_33: + return 3512; + flow_34: + return 3512; + flow_35: + return 3512; + flow_36: + return 3513; + flow_37: + return 3513; + flow_38: + return 3513; + flow_39: + return 3513; + flow_40: + return 3513; + flow_41: + return 3514; + flow_42: + return 3514; + flow_43: + return 3514; + flow_44: + return 3514; + flow_45: + return 3514; + flow_46: + return 3514; + flow_47: + return 3514; + flow_48: + return 3514; + flow_49: + return 3514; + flow_50: + return 3519; + flow_51: + return 3521; +} diff --git a/dumps/scripts/4099.cs2 b/dumps/scripts/4099.cs2 new file mode 100644 index 0000000..816d9ce --- /dev/null +++ b/dumps/scripts/4099.cs2 @@ -0,0 +1,5 @@ +void script_4099() { + globalint_41 = -1; + script_1364(); + return; +} diff --git a/dumps/scripts/41.cs2 b/dumps/scripts/41.cs2 new file mode 100644 index 0000000..1c12b7d --- /dev/null +++ b/dumps/scripts/41.cs2 @@ -0,0 +1,5 @@ +void script_41(int arg0) { + deleteAllExtraChilds(new WidgetPointer(arg0)); + globalint_2 = 0; + return; +} diff --git a/dumps/scripts/410.cs2 b/dumps/scripts/410.cs2 new file mode 100644 index 0000000..6093e0f --- /dev/null +++ b/dumps/scripts/410.cs2 @@ -0,0 +1,61 @@ +void script_410(int arg0) { + if (globalint_1361 == arg0) { + return; + } + setScriptCallOnGlobalConfigChange(410, globalint_1361, 1361, 1, "iY", new WidgetPointer(1010,6)); + if (globalint_1363 == bitconfig_7510) { + setWidgetIsHidden(false, new WidgetPointer(1010,33)); + setWidgetIsHidden(true, new WidgetPointer(1010,24)); + } + if (((boolean)globalint_1361)) { + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(1010,12)); + setWidgetSprite(3745, new WidgetPointer(1010,13)); + setWidgetRGB(new Color(150, 150, 100), new WidgetPointer(1010,14)); + setWidgetSprite(3745, new WidgetPointer(1010,15)); + setWidgetRGB(new Color(150, 150, 100), new WidgetPointer(1010,16)); + setWidgetSprite(3745, new WidgetPointer(1010,17)); + setWidgetRGB(new Color(150, 150, 100), new WidgetPointer(1010,18)); + setWidgetSprite(3745, new WidgetPointer(1010,19)); + } else if (((boolean)globalint_1361)) { + if (((boolean)bitconfig_7511)) { + if (((boolean)rndExcl(2))) { + playSoundEffect2False(3436, 1, 0, 255); + } else { + playSoundEffect2False(3438, 1, 0, 255); + } + } + setWidgetRGB(new Color(0, 200, 0), new WidgetPointer(1010,12)); + setWidgetSprite(3746, new WidgetPointer(1010,13)); + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(1010,14)); + setWidgetSprite(3745, new WidgetPointer(1010,15)); + setWidgetRGB(new Color(150, 150, 100), new WidgetPointer(1010,16)); + setWidgetSprite(3745, new WidgetPointer(1010,17)); + setWidgetRGB(new Color(150, 150, 100), new WidgetPointer(1010,18)); + setWidgetSprite(3745, new WidgetPointer(1010,19)); + } else if (globalint_1361 == 2) { + if (((boolean)bitconfig_7511)) { + playSoundEffect2False(3437, 1, 0, 255); + } + setWidgetRGB(new Color(0, 200, 0), new WidgetPointer(1010,12)); + setWidgetSprite(3746, new WidgetPointer(1010,13)); + setWidgetRGB(new Color(0, 200, 0), new WidgetPointer(1010,14)); + setWidgetSprite(3746, new WidgetPointer(1010,15)); + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(1010,16)); + setWidgetSprite(3745, new WidgetPointer(1010,17)); + setWidgetRGB(new Color(150, 150, 100), new WidgetPointer(1010,18)); + setWidgetSprite(3745, new WidgetPointer(1010,19)); + } else { + if (((boolean)bitconfig_7511)) { + playSoundEffect2False(3441, 1, 0, 255); + } + setWidgetRGB(new Color(0, 200, 0), new WidgetPointer(1010,12)); + setWidgetSprite(3746, new WidgetPointer(1010,13)); + setWidgetRGB(new Color(0, 200, 0), new WidgetPointer(1010,14)); + setWidgetSprite(3746, new WidgetPointer(1010,15)); + setWidgetRGB(new Color(0, 200, 0), new WidgetPointer(1010,16)); + setWidgetSprite(3746, new WidgetPointer(1010,17)); + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(1010,18)); + setWidgetSprite(3745, new WidgetPointer(1010,19)); + } + return; +} diff --git a/dumps/scripts/4100.cs2 b/dumps/scripts/4100.cs2 new file mode 100644 index 0000000..f39765d --- /dev/null +++ b/dumps/scripts/4100.cs2 @@ -0,0 +1,5 @@ +void script_4100() { + globalint_41 = 1; + script_1364(); + return; +} diff --git a/dumps/scripts/4101.cs2 b/dumps/scripts/4101.cs2 new file mode 100644 index 0000000..0bd3298 --- /dev/null +++ b/dumps/scripts/4101.cs2 @@ -0,0 +1,4 @@ +void script_4101(int arg0) { + setWidgetIsHidden(((boolean)arg0), new WidgetPointer(1056,102)); + return; +} diff --git a/dumps/scripts/4102.cs2 b/dumps/scripts/4102.cs2 new file mode 100644 index 0000000..f75a8d8 --- /dev/null +++ b/dumps/scripts/4102.cs2 @@ -0,0 +1,14 @@ +void script_4102(int arg0) { + if (((boolean)arg0)) { + setWidgetSprite(4324, new WidgetPointer(320,206)); + setWidgetSprite(4324, new WidgetPointer(320,207)); + setWidgetSprite(4325, new WidgetPointer(320,208)); + setWidgetSprite(4309, new WidgetPointer(320,210)); + } else { + setWidgetSprite(4322, new WidgetPointer(320,206)); + setWidgetSprite(4322, new WidgetPointer(320,207)); + setWidgetSprite(4323, new WidgetPointer(320,208)); + setWidgetSprite(4308, new WidgetPointer(320,210)); + } + return; +} diff --git a/dumps/scripts/4103.cs2 b/dumps/scripts/4103.cs2 new file mode 100644 index 0000000..e4448a5 --- /dev/null +++ b/dumps/scripts/4103.cs2 @@ -0,0 +1,4 @@ +void script_4103() { + setWidgetIsHidden(true, new WidgetPointer(320,203)); + return; +} diff --git a/dumps/scripts/4104.cs2 b/dumps/scripts/4104.cs2 new file mode 100644 index 0000000..44fba65 --- /dev/null +++ b/dumps/scripts/4104.cs2 @@ -0,0 +1,4 @@ +void script_4104() { + cs2method5421(1, "golden_joystick.ws"); + return; +} diff --git a/dumps/scripts/4105.cs2 b/dumps/scripts/4105.cs2 new file mode 100644 index 0000000..f1070f0 --- /dev/null +++ b/dumps/scripts/4105.cs2 @@ -0,0 +1,68 @@ +void script_4105(int arg0,int arg1,int arg2,int arg3,int arg4) { + int ivar5; + string svar0; + if (globalint_729 > 1) { + setWidgetText(new WidgetPointer(arg0), formatNumber(globalint_729, 1) + " coins"); + } else if (((boolean)globalint_729)) { + setWidgetText(new WidgetPointer(arg0), "1 coin"); + } else if (((boolean)globalint_729)) { + setWidgetText(new WidgetPointer(arg0), "Nothing"); + } else { + setWidgetText(new WidgetPointer(arg0), "Lots!"); + } + if (globalint_697 > 1) { + setWidgetText(new WidgetPointer(arg1), formatNumber(globalint_697, 1) + " coins"); + } else if (((boolean)globalint_697)) { + setWidgetText(new WidgetPointer(arg1), "1 coin"); + } else if (((boolean)globalint_697)) { + setWidgetText(new WidgetPointer(arg1), "" + "Nothing" + ""); + } else { + setWidgetText(new WidgetPointer(arg1), "Lots!"); + } + svar0 = "" + "Unknown" + ""; + ivar5 = 0; + if (globalint_729 < 0) { + if (globalint_697 < 0) { + setWidgetText(new WidgetPointer(arg2), svar0); + setWidgetIsHidden(true, new WidgetPointer(arg3)); + } else { + setWidgetText(new WidgetPointer(arg2), svar0); + setWidgetIsHidden(false, new WidgetPointer(arg3)); + setWidgetSprite(1174, new WidgetPointer(arg3)); + setWidgetPosition(script_4106(arg4, svar0), 0, 0, 2, new WidgetPointer(arg3)); + } + } else if (globalint_697 < 0) { + svar0 = "Unknown"; + setWidgetText(new WidgetPointer(arg2), svar0); + setWidgetIsHidden(false, new WidgetPointer(arg3)); + setWidgetSprite(1172, new WidgetPointer(arg3)); + setWidgetPosition(script_4106(arg4, svar0), 0, 2, 2, new WidgetPointer(arg3)); + } else if (ivar5 > 0) { + if (((boolean)ivar5)) { + svar0 = "" + "1 coin" + ""; + } else { + svar0 = "" + formatNumber(ivar5, 1) + " coins" + ""; + } + setWidgetText(new WidgetPointer(arg2), svar0); + setWidgetIsHidden(false, new WidgetPointer(arg3)); + setWidgetSprite(1174, new WidgetPointer(arg3)); + setWidgetPosition(script_4106(arg4, svar0), 0, 0, 2, new WidgetPointer(arg3)); + } else if (ivar5 < 0) { + ivar5 = subtract(0, ivar5); + if (((boolean)ivar5)) { + svar0 = "1 coin"; + } else { + svar0 = formatNumber(ivar5, 1) + " coins"; + } + setWidgetText(new WidgetPointer(arg2), svar0); + setWidgetIsHidden(false, new WidgetPointer(arg3)); + setWidgetSprite(1172, new WidgetPointer(arg3)); + setWidgetPosition(script_4106(arg4, svar0), 0, 2, 2, new WidgetPointer(arg3)); + } else { + svar0 = "No net transfer"; + setWidgetText(new WidgetPointer(arg2), svar0); + setWidgetIsHidden(true, new WidgetPointer(arg3)); + } + ivar5 = subtract(globalint_729, globalint_697); + return; +} diff --git a/dumps/scripts/4106.cs2 b/dumps/scripts/4106.cs2 new file mode 100644 index 0000000..a5de3af --- /dev/null +++ b/dumps/scripts/4106.cs2 @@ -0,0 +1,3 @@ +int script_4106(int arg0,string arg1) { + return divide(add(getWidgetActualWidth(new WidgetPointer(arg0)), max(getTextWidth(495, arg1), getTextWidth(494, getWidgetText(new WidgetPointer(arg0))))), 2); +} diff --git a/dumps/scripts/4107.cs2 b/dumps/scripts/4107.cs2 new file mode 100644 index 0000000..6d94697 --- /dev/null +++ b/dumps/scripts/4107.cs2 @@ -0,0 +1,12 @@ +string script_4107(int arg0,int arg1) { + if (arg1 >= 10000000) { + return "" + getItemName(arg0) + "" + " x " + formatNumber(divide(arg1, 1000000), 1) + "M (" + formatNumber(arg1, 1) + ")"; + } + if (arg1 >= 10000) { + return "" + getItemName(arg0) + "" + " x " + formatNumber(divide(arg1, 1000), 1) + "K (" + formatNumber(arg1, 1) + ")"; + } + if (arg1 > 1) { + return "" + getItemName(arg0) + "" + " x " + formatNumber(arg1, 1); + } + return "" + getItemName(arg0) + ""; +} diff --git a/dumps/scripts/4108.cs2 b/dumps/scripts/4108.cs2 new file mode 100644 index 0000000..d77f686 --- /dev/null +++ b/dumps/scripts/4108.cs2 @@ -0,0 +1,4 @@ +void script_4108(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + script_4109(arg0, arg1, arg2, arg3, arg4, arg5); + return; +} diff --git a/dumps/scripts/4109.cs2 b/dumps/scripts/4109.cs2 new file mode 100644 index 0000000..9a0b0ce --- /dev/null +++ b/dumps/scripts/4109.cs2 @@ -0,0 +1,11 @@ +void script_4109(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + int ivar6; + int ivar7; + ivar6 = getWidgetActualWidth(new WidgetPointer(arg5)); + arg0 = max(min(arg0, subtract(getWidgetActualWidth(new WidgetPointer(arg4)), ivar6)), 0); + ivar7 = getWidgetActualX(new WidgetPointer(arg4)); + setWidgetSize(add(ivar7, arg0), 0, 0, 1, new WidgetPointer(arg2)); + setWidgetSize(add(add(ivar7, arg0), ivar6), 0, 1, 1, new WidgetPointer(arg3)); + setWidgetPosition(arg0, 0, 0, 1, new WidgetPointer(arg5)); + return; +} diff --git a/dumps/scripts/411.cs2 b/dumps/scripts/411.cs2 new file mode 100644 index 0000000..ca26237 --- /dev/null +++ b/dumps/scripts/411.cs2 @@ -0,0 +1,4 @@ +void script_411() { + script_304(49122684); + return; +} diff --git a/dumps/scripts/4110.cs2 b/dumps/scripts/4110.cs2 new file mode 100644 index 0000000..6c35e80 --- /dev/null +++ b/dumps/scripts/4110.cs2 @@ -0,0 +1,30 @@ +void script_4110() { + flow_0: + SWITCH (standart_config_1108) { + case 2: + GOTO flow_1 + case 5: + GOTO flow_2 + } + setWidgetIsHidden(false, new WidgetPointer(106,126)); + setWidgetIsHidden(true, new WidgetPointer(106,131)); + setWidgetIsHidden(true, new WidgetPointer(106,140)); + script_670(); + setWidgetText(new WidgetPointer(106,124), "First, you will see a selection of boxes. You can make several offers simultaneously, one in each box."); + GOTO flow_3 + flow_1: + setWidgetIsHidden(true, new WidgetPointer(106,126)); + setWidgetIsHidden(false, new WidgetPointer(106,131)); + setWidgetIsHidden(true, new WidgetPointer(106,140)); + script_671(); + setWidgetText(new WidgetPointer(106,124), "Each box has two buttons. One button is for offering to buy items, the other is for offering to sell items."); + GOTO flow_3 + flow_2: + setWidgetIsHidden(true, new WidgetPointer(106,126)); + setWidgetIsHidden(true, new WidgetPointer(106,131)); + setWidgetIsHidden(false, new WidgetPointer(106,140)); + script_672(); + setWidgetText(new WidgetPointer(106,124), "Now the offer is placed! You can return to the Grand Exchange at any time to check on the progress of your offers."); + flow_3: + return; +} diff --git a/dumps/scripts/4111.cs2 b/dumps/scripts/4111.cs2 new file mode 100644 index 0000000..232c589 --- /dev/null +++ b/dumps/scripts/4111.cs2 @@ -0,0 +1,23 @@ +void script_4111() { + if (standart_config_1108 <= 3) { + setWidgetText(new WidgetPointer(110,84), "If you selected the 'Buy' option, you would see this screen. You can choose an item to buy by clicking on the indicated box."); + setWidgetIsHidden(true, new WidgetPointer(110,85)); + setWidgetText(new WidgetPointer(110,27), "N/A"); + setWidgetIsHidden(false, new WidgetPointer(110,68)); + setWidgetText(new WidgetPointer(110,28), "Choose an item to exchange"); + setWidgetText(new WidgetPointer(110,33), "1"); + setWidgetText(new WidgetPointer(110,38), "1 gp"); + setWidgetText(new WidgetPointer(110,65), "1 gp"); + } else { + setWidgetText(new WidgetPointer(110,84), "You can set how many you wish to buy, and the price you're willing to pay, before clicking the 'Confirm Offer' button. We'll suggest a guide price for the item, but you can offer whatever you like."); + setWidgetIsHidden(false, new WidgetPointer(110,85)); + setItemOnWidgetMethod2205(1381, 1, new WidgetPointer(110,85)); + setWidgetText(new WidgetPointer(110,27), "1,281 gp"); + setWidgetIsHidden(true, new WidgetPointer(110,68)); + setWidgetText(new WidgetPointer(110,28), "Staff of air"); + setWidgetText(new WidgetPointer(110,33), "2"); + setWidgetText(new WidgetPointer(110,38), "1,281 gp"); + setWidgetText(new WidgetPointer(110,65), "2,562 gp"); + } + return; +} diff --git a/dumps/scripts/4112.cs2 b/dumps/scripts/4112.cs2 new file mode 100644 index 0000000..66636aa --- /dev/null +++ b/dumps/scripts/4112.cs2 @@ -0,0 +1,25 @@ +void script_4112(int arg0) { + int ivar1; + if (standart_config_1109 == -1) { + return; + } + ivar1 = 0; + if ((arg0 > 100) && (globalint_85 > 2045222520)) { + ivar1 = 2147483647; + } else if ((arg0 < 100) && (globalint_85 <= 1)) { + ivar1 = 1; + } else { + ivar1 = multiplyDivide(arg0, 100, globalint_85); + if (ivar1 == globalint_85) { + if (arg0 >= 100) { + ivar1 = add(ivar1, 1); + } else { + ivar1 = subtract(ivar1, 1); + } + } + } + globalint_85 = ivar1; + setWidgetText(new WidgetPointer(105,153), formatNumber(globalint_85, 1) + " gp"); + script_609(); + return; +} diff --git a/dumps/scripts/4113.cs2 b/dumps/scripts/4113.cs2 new file mode 100644 index 0000000..920fe2e --- /dev/null +++ b/dumps/scripts/4113.cs2 @@ -0,0 +1,4 @@ +void script_4113() { + script_4114(); + return; +} diff --git a/dumps/scripts/4114.cs2 b/dumps/scripts/4114.cs2 new file mode 100644 index 0000000..cffbfe2 --- /dev/null +++ b/dumps/scripts/4114.cs2 @@ -0,0 +1,39 @@ +void script_4114() { + int ivar0; + string svar0; + string svar1; + script_662(0); + script_662(1); + script_662(2); + script_662(3); + script_662(4); + script_662(5); + ivar0 = getItemIdInSlot(540, 0); + if (ivar0 == -1) { + setWidgetIsHidden(true, new WidgetPointer(109,45)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(109,1)), 225, 0, 0, new WidgetPointer(109,1)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(109,1)), 225, 0, 0, new WidgetPointer(109,0)); + return; + } + setWidgetIsHidden(false, new WidgetPointer(109,45)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(109,1)), 305, 0, 0, new WidgetPointer(109,1)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(109,1)), 305, 0, 0, new WidgetPointer(109,0)); + setItemOnWidgetMethod2200(ivar0, -1, new WidgetPointer(109,58)); + cs2method2305(new WidgetPointer(109,58), "" + getItemName(ivar0) + ""); + svar0 = "Lent item"; + svar1 = "Still on loan"; + setWidgetText(new WidgetPointer(109,57), svar0); + if ((standart_config_1267 != -1) || (standart_config_1269 > 0)) { + cs2method2103(200, new WidgetPointer(109,58)); + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(109,59)); + setWidgetContextMenuOption(1, new WidgetPointer(109,58), "Demand"); + } else { + cs2method2103(0, new WidgetPointer(109,58)); + setWidgetRGB(new Color(0, 223, 0), new WidgetPointer(109,59)); + svar1 = "Available"; + setWidgetContextMenuOption(1, new WidgetPointer(109,58), "Reclaim"); + } + setWidgetText(new WidgetPointer(109,59), svar1); + setWidgetSize(add(max(max(getTextWidth(495, svar0), getTextWidth(494, svar1)), getWidgetActualWidth(new WidgetPointer(109,58))), 30), getWidgetActualHeight(new WidgetPointer(109,45)), 0, 0, new WidgetPointer(109,45)); + return; +} diff --git a/dumps/scripts/4115.cs2 b/dumps/scripts/4115.cs2 new file mode 100644 index 0000000..5df1842 --- /dev/null +++ b/dumps/scripts/4115.cs2 @@ -0,0 +1,4 @@ +void script_4115() { + script_304(49794739); + return; +} diff --git a/dumps/scripts/4116.cs2 b/dumps/scripts/4116.cs2 new file mode 100644 index 0000000..f0a6bd2 --- /dev/null +++ b/dumps/scripts/4116.cs2 @@ -0,0 +1,4 @@ +void script_4116() { + script_304(50351681); + return; +} diff --git a/dumps/scripts/4117.cs2 b/dumps/scripts/4117.cs2 new file mode 100644 index 0000000..7e26fcf --- /dev/null +++ b/dumps/scripts/4117.cs2 @@ -0,0 +1,4 @@ +void script_4117() { + script_304(49466699); + return; +} diff --git a/dumps/scripts/4118.cs2 b/dumps/scripts/4118.cs2 new file mode 100644 index 0000000..1237327 --- /dev/null +++ b/dumps/scripts/4118.cs2 @@ -0,0 +1,4 @@ +void script_4118() { + script_304(27465183); + return; +} diff --git a/dumps/scripts/4119.cs2 b/dumps/scripts/4119.cs2 new file mode 100644 index 0000000..a349ff7 --- /dev/null +++ b/dumps/scripts/4119.cs2 @@ -0,0 +1,4 @@ +void script_4119() { + script_304(48408011); + return; +} diff --git a/dumps/scripts/412.cs2 b/dumps/scripts/412.cs2 new file mode 100644 index 0000000..c9aa8e6 --- /dev/null +++ b/dumps/scripts/412.cs2 @@ -0,0 +1,434 @@ +void script_412(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + flow_0: + ivar1 = cameraGetHrot(); + ivar2 = 0; + ivar3 = -1; + ivar4 = 0; + ivar5 = 0; + ivar6 = 0; + ivar7 = 0; + if (globalint_1360 < 10) { + globalint_1360 = add(globalint_1360, 1); + return; + } + if (globalint_1359 < 5) { + globalint_1359 = add(globalint_1359, 1); + return; + } + globalint_1359 = 0; + if (ivar1 < 128) { + ivar1 = 1; + } else if (ivar1 < 256) { + ivar1 = 2; + } else if (ivar1 < 384) { + ivar1 = 3; + } else if (ivar1 < 512) { + ivar1 = 4; + } else if (ivar1 < 640) { + ivar1 = 5; + } else if (ivar1 < 768) { + ivar1 = 6; + } else if (ivar1 < 896) { + ivar1 = 7; + } else if (ivar1 < 1024) { + ivar1 = 8; + } else if (ivar1 < 1152) { + ivar1 = 9; + } else if (ivar1 < 1280) { + ivar1 = 10; + } else if (ivar1 < 1408) { + ivar1 = 11; + } else if (ivar1 < 1536) { + ivar1 = 12; + } else if (ivar1 < 1664) { + ivar1 = 13; + } else if (ivar1 < 1792) { + ivar1 = 14; + } else if (ivar1 < 1920) { + ivar1 = 15; + } else { + ivar1 = 16; + } + SWITCH (arg0) { + case 1: + GOTO flow_37 + case 5: + GOTO flow_47 + case 7: + GOTO flow_57 + case 3: + GOTO flow_67 + case 2: + GOTO flow_77 + case 4: + GOTO flow_87 + case 8: + GOTO flow_97 + case 6: + GOTO flow_107 + } + return; + flow_37: + switch (ivar1) { + case 1: + case 16: + ivar2 = 1; + break; + case 2: + case 3: + ivar2 = 8; + break; + case 4: + case 5: + ivar2 = 7; + break; + case 6: + case 7: + ivar2 = 6; + break; + case 8: + case 9: + ivar2 = 5; + break; + case 10: + case 11: + ivar2 = 4; + break; + case 12: + case 13: + ivar2 = 3; + break; + case 14: + case 15: + ivar2 = 2; + } + GOTO flow_116 + flow_47: + switch (ivar1) { + case 1: + case 16: + ivar2 = 5; + break; + case 2: + case 3: + ivar2 = 4; + break; + case 4: + case 5: + ivar2 = 3; + break; + case 6: + case 7: + ivar2 = 2; + break; + case 8: + case 9: + ivar2 = 1; + break; + case 10: + case 11: + ivar2 = 8; + break; + case 12: + case 13: + ivar2 = 7; + break; + case 14: + case 15: + ivar2 = 6; + } + GOTO flow_116 + flow_57: + switch (ivar1) { + case 1: + case 16: + ivar2 = 7; + break; + case 2: + case 3: + ivar2 = 6; + break; + case 4: + case 5: + ivar2 = 5; + break; + case 6: + case 7: + ivar2 = 4; + break; + case 8: + case 9: + ivar2 = 3; + break; + case 10: + case 11: + ivar2 = 2; + break; + case 12: + case 13: + ivar2 = 1; + break; + case 14: + case 15: + ivar2 = 8; + } + GOTO flow_116 + flow_67: + switch (ivar1) { + case 1: + case 16: + ivar2 = 3; + break; + case 2: + case 3: + ivar2 = 2; + break; + case 4: + case 5: + ivar2 = 1; + break; + case 6: + case 7: + ivar2 = 8; + break; + case 8: + case 9: + ivar2 = 7; + break; + case 10: + case 11: + ivar2 = 6; + break; + case 12: + case 13: + ivar2 = 5; + break; + case 14: + case 15: + ivar2 = 4; + } + GOTO flow_116 + flow_77: + switch (ivar1) { + case 1: + case 16: + ivar2 = 2; + break; + case 2: + case 3: + ivar2 = 1; + break; + case 4: + case 5: + ivar2 = 8; + break; + case 6: + case 7: + ivar2 = 7; + break; + case 8: + case 9: + ivar2 = 6; + break; + case 10: + case 11: + ivar2 = 5; + break; + case 12: + case 13: + ivar2 = 4; + break; + case 14: + case 15: + ivar2 = 3; + } + GOTO flow_116 + flow_87: + switch (ivar1) { + case 1: + case 16: + ivar2 = 4; + break; + case 2: + case 3: + ivar2 = 3; + break; + case 4: + case 5: + ivar2 = 2; + break; + case 6: + case 7: + ivar2 = 1; + break; + case 8: + case 9: + ivar2 = 8; + break; + case 10: + case 11: + ivar2 = 7; + break; + case 12: + case 13: + ivar2 = 6; + break; + case 14: + case 15: + ivar2 = 5; + } + GOTO flow_116 + flow_97: + switch (ivar1) { + case 1: + case 16: + ivar2 = 8; + break; + case 2: + case 3: + ivar2 = 7; + break; + case 4: + case 5: + ivar2 = 6; + break; + case 6: + case 7: + ivar2 = 5; + break; + case 8: + case 9: + ivar2 = 4; + break; + case 10: + case 11: + ivar2 = 3; + break; + case 12: + case 13: + ivar2 = 2; + break; + case 14: + case 15: + ivar2 = 1; + } + GOTO flow_116 + flow_107: + switch (ivar1) { + case 1: + case 16: + ivar2 = 6; + break; + case 2: + case 3: + ivar2 = 5; + break; + case 4: + case 5: + ivar2 = 4; + break; + case 6: + case 7: + ivar2 = 3; + break; + case 8: + case 9: + ivar2 = 2; + break; + case 10: + case 11: + ivar2 = 1; + break; + case 12: + case 13: + ivar2 = 8; + break; + case 14: + case 15: + ivar2 = 7; + } + flow_116: + SWITCH (ivar2) { + case 1: + GOTO flow_117 + case 2: + GOTO flow_118 + case 3: + GOTO flow_119 + case 4: + GOTO flow_120 + case 5: + GOTO flow_121 + case 6: + GOTO flow_122 + case 7: + GOTO flow_123 + case 8: + GOTO flow_124 + } + return; + flow_117: + ivar3 = addToCoordinate(globalint_1353, 0, 0, 1); + GOTO flow_125 + flow_118: + ivar3 = addToCoordinate(globalint_1353, 1, 0, 1); + GOTO flow_125 + flow_119: + ivar3 = addToCoordinate(globalint_1353, 1, 0, 0); + GOTO flow_125 + flow_120: + ivar3 = addToCoordinate(globalint_1353, 1, 0, -1); + GOTO flow_125 + flow_121: + ivar3 = addToCoordinate(globalint_1353, 0, 0, -1); + GOTO flow_125 + flow_122: + ivar3 = addToCoordinate(globalint_1353, -1, 0, -1); + GOTO flow_125 + flow_123: + ivar3 = addToCoordinate(globalint_1353, -1, 0, 0); + GOTO flow_125 + flow_124: + ivar3 = addToCoordinate(globalint_1353, -1, 0, 1); + flow_125: + if (((boolean)globalint_1390)) { + ivar4 = 44; + ivar5 = 35; + ivar6 = 31; + ivar7 = 17; + } else { + ivar4 = 54; + ivar5 = 35; + ivar6 = 36; + ivar7 = 17; + } + if ((((mod(extractX(ivar3), 64) > ivar4) || (mod(extractY(ivar3), 64) > ivar6)) || (mod(extractX(ivar3), 64) < ivar5)) || (mod(extractY(ivar3), 64) < ivar7)) { + setWidgetRGB(new Color(100, 100, 100), new WidgetPointer(1013,19)); + setWidgetRGB(new Color(100, 100, 100), new WidgetPointer(1013,18)); + setWidgetRGB(new Color(100, 100, 100), new WidgetPointer(1013,20)); + setWidgetRGB(new Color(100, 100, 100), new WidgetPointer(1013,21)); + setWidgetRGB(new Color(100, 100, 100), new WidgetPointer(1013,17)); + setWidgetRGB(new Color(100, 100, 100), new WidgetPointer(1013,15)); + setWidgetRGB(new Color(100, 100, 100), new WidgetPointer(1013,16)); + setWidgetRGB(new Color(100, 100, 100), new WidgetPointer(1013,14)); + return; + } + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(1013,19)); + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(1013,18)); + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(1013,20)); + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(1013,21)); + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(1013,17)); + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(1013,15)); + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(1013,16)); + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(1013,14)); + globalint_1353 = ivar3; + cameraMethod5511(globalint_1353); + return; +} diff --git a/dumps/scripts/4120.cs2 b/dumps/scripts/4120.cs2 new file mode 100644 index 0000000..f3740a2 --- /dev/null +++ b/dumps/scripts/4120.cs2 @@ -0,0 +1,4 @@ +void script_4120() { + script_304(49768380); + return; +} diff --git a/dumps/scripts/4121.cs2 b/dumps/scripts/4121.cs2 new file mode 100644 index 0000000..274fa7d --- /dev/null +++ b/dumps/scripts/4121.cs2 @@ -0,0 +1,4 @@ +void script_4121() { + script_304(50407242); + return; +} diff --git a/dumps/scripts/4122.cs2 b/dumps/scripts/4122.cs2 new file mode 100644 index 0000000..41c1fb5 --- /dev/null +++ b/dumps/scripts/4122.cs2 @@ -0,0 +1,6 @@ +void script_4122(int arg0,int arg1,int arg2) { + if (standart_config_852 != -1) { + script_1163(arg0, arg1, arg2, 0, 180, getItemName(standart_config_852)); + } + return; +} diff --git a/dumps/scripts/4123.cs2 b/dumps/scripts/4123.cs2 new file mode 100644 index 0000000..312d831 --- /dev/null +++ b/dumps/scripts/4123.cs2 @@ -0,0 +1,6 @@ +void script_4123(int arg0,int arg1,int arg2) { + if (standart_config_853 != -1) { + script_1163(arg0, arg1, arg2, 0, 180, getItemName(standart_config_853)); + } + return; +} diff --git a/dumps/scripts/4124.cs2 b/dumps/scripts/4124.cs2 new file mode 100644 index 0000000..a095065 --- /dev/null +++ b/dumps/scripts/4124.cs2 @@ -0,0 +1,6 @@ +void script_4124(int arg0,int arg1,int arg2) { + if (standart_config_854 != -1) { + script_1163(arg0, arg1, arg2, 0, 180, getItemName(standart_config_854)); + } + return; +} diff --git a/dumps/scripts/4125.cs2 b/dumps/scripts/4125.cs2 new file mode 100644 index 0000000..d4948c3 --- /dev/null +++ b/dumps/scripts/4125.cs2 @@ -0,0 +1,25 @@ +void script_4125(int arg0,int arg1,int arg2,string arg3) { + int stack_dump0; + int stack_dump1; + int stack_dump2; + int stack_dump3; + string stack_dump4; + if (setWidgetRegister(new WidgetPointer(arg0))) { + stack_dump0 = arg0; + stack_dump1 = arg1; + stack_dump2 = arg2; + stack_dump3 = 718; + stack_dump4 = arg3; + /* + mgi.tools.jagdecs2.DecompilerException: opcode 1613 not decompileable + at mgi.tools.jagdecs2.FlowBlocksGenerator.analyzeSpecialCall(FlowBlocksGenerator.java:297) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:249) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return; +} diff --git a/dumps/scripts/4126.cs2 b/dumps/scripts/4126.cs2 new file mode 100644 index 0000000..ac4d7f2 --- /dev/null +++ b/dumps/scripts/4126.cs2 @@ -0,0 +1,123 @@ +string script_4126(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + string svar0; + string svar1; + int stack_dump0; + cs2func_script_2413_struct(3,0,0) structdump_1; + int stack_dump2; + int stack_dump3; + cs2func_script_4127_struct(3,0,0) structdump_4; + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + ivar4 = 1; + svar0 = ""; + svar1 = ""; + stack_dump0 = arg0; + structdump_1 = script_2413(stack_dump0); + ivar3 = structdump_1.intpart_2; + ivar2 = structdump_1.intpart_1; + ivar1 = structdump_1.intpart_0; + stack_dump0 = ivar1; + stack_dump2 = ivar2; + stack_dump3 = ivar3; + structdump_4 = script_4127(stack_dump0, stack_dump2, stack_dump3); + ivar3 = structdump_4.intpart_2; + ivar2 = structdump_4.intpart_1; + ivar1 = structdump_4.intpart_0; + if (((boolean)ivar3)) { + return "Black"; + } + if (ivar3 == 255) { + return "White"; + } + if (ivar3 < 97) { + svar0 = "Dark "; + } else if ((ivar3 == 127) && (ivar2 >= 240)) { + svar0 = "Vivid "; + } else if (ivar3 > 157) { + svar0 = "Light "; + } else { + ivar4 = 0; + } + switch (arg0) { + case 65535: + case 255: + case 65280: + case 16744448: + case 8388863: + case 4194559: + case 16711935: + case 16776960: + case 16711680: + svar0 = "Pure "; + ivar4 = 1; + } + if (((boolean)ivar4)) { + if (((boolean)ivar2)) { + svar1 = "grey"; + } + if (ivar1 < 10) { + svar1 = "red"; + } else if (ivar1 < 45) { + svar1 = "orange"; + } else if (ivar1 < 75) { + svar1 = "yellow"; + } else if (ivar1 < 140) { + svar1 = "green"; + } else if (ivar1 < 160) { + svar1 = "turquoise"; + } else if (ivar1 < 195) { + svar1 = "cyan"; + } else if (ivar1 < 250) { + svar1 = "blue"; + } else if (ivar1 < 265) { + svar1 = "indigo"; + } else if (ivar1 < 280) { + svar1 = "violet"; + } else if (ivar1 < 290) { + svar1 = "purple"; + } else if (ivar1 < 305) { + svar1 = "magenta"; + } else if (ivar1 < 345) { + svar1 = "pink"; + } else { + svar1 = "red"; + } + } else { + if (((boolean)ivar2)) { + svar1 = "Grey"; + } + if (ivar1 < 10) { + svar1 = "Red"; + } else if (ivar1 < 45) { + svar1 = "Orange"; + } else if (ivar1 < 75) { + svar1 = "Yellow"; + } else if (ivar1 < 140) { + svar1 = "Green"; + } else if (ivar1 < 160) { + svar1 = "Turquoise"; + } else if (ivar1 < 195) { + svar1 = "Cyan"; + } else if (ivar1 < 250) { + svar1 = "Blue"; + } else if (ivar1 < 265) { + svar1 = "Indigo"; + } else if (ivar1 < 280) { + svar1 = "Violet"; + } else if (ivar1 < 290) { + svar1 = "Purple"; + } else if (ivar1 < 305) { + svar1 = "Magenta"; + } else if (ivar1 < 345) { + svar1 = "Pink"; + } else { + svar1 = "Red"; + } + } + return svar0 + svar1 + "."; +} diff --git a/dumps/scripts/4127.cs2 b/dumps/scripts/4127.cs2 new file mode 100644 index 0000000..356ce31 --- /dev/null +++ b/dumps/scripts/4127.cs2 @@ -0,0 +1,31 @@ +cs2func_script_4127_struct(3,0,0) script_4127(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + ivar3 = min(arg0, min(arg1, arg2)); + ivar4 = max(arg0, max(arg1, arg2)); + ivar5 = subtract(ivar4, ivar3); + ivar6 = 0; + ivar7 = 0; + ivar8 = divide(add(ivar3, ivar4), 2); + if (ivar5 != 0) { + if (ivar8 < 128) { + ivar7 = multiplyDivide(ivar5, multiply(2, ivar8), 255); + } else { + ivar7 = multiplyDivide(ivar5, subtract(510, multiply(2, ivar8)), 255); + } + if (arg0 == ivar4) { + ivar6 = multiplyDivide(mod(add(multiplyDivide(subtract(arg1, arg2), ivar5, 10000), 60000), 60000), 10000, 60); + } + if (arg1 == ivar4) { + ivar6 = multiplyDivide(add(multiplyDivide(subtract(arg2, arg0), ivar5, 10000), 20000), 10000, 60); + } + if (arg2 == ivar4) { + ivar6 = multiplyDivide(add(multiplyDivide(subtract(arg0, arg1), ivar5, 10000), 40000), 10000, 60); + } + } + return newstruct cs2func_script_4127_struct(ivar6, ivar7, ivar8); +} diff --git a/dumps/scripts/4128.cs2 b/dumps/scripts/4128.cs2 new file mode 100644 index 0000000..ea962d9 --- /dev/null +++ b/dumps/scripts/4128.cs2 @@ -0,0 +1,15 @@ +void script_4128(int arg0) { + if (globalint_1452 <= 100) { + script_4130(arg0); + return; + } + if (globalint_1452 <= 200) { + script_4131(arg0, script_284(getMyPositionHash())); + return; + } + if (globalint_1452 <= 300) { + script_4132(arg0, script_284(getMyPositionHash())); + return; + } + return; +} diff --git a/dumps/scripts/4129.cs2 b/dumps/scripts/4129.cs2 new file mode 100644 index 0000000..6eb7f12 --- /dev/null +++ b/dumps/scripts/4129.cs2 @@ -0,0 +1,3 @@ +int script_4129(int arg0,int arg1) { + return addToCoordinate(arg1, subtract(extractX(arg0), extractX(57676160)), subtract(extractZ(arg0), extractZ(57676160)), subtract(extractY(arg0), extractY(57676160))); +} diff --git a/dumps/scripts/413.cs2 b/dumps/scripts/413.cs2 new file mode 100644 index 0000000..50513a2 --- /dev/null +++ b/dumps/scripts/413.cs2 @@ -0,0 +1,7 @@ +void script_413() { + cameraMethod5511(getMyPositionHash()); + globalint_1353 = getMyPositionHash(); + globalint_1359 = 0; + globalint_1360 = 0; + return; +} diff --git a/dumps/scripts/4130.cs2 b/dumps/scripts/4130.cs2 new file mode 100644 index 0000000..8f24af3 --- /dev/null +++ b/dumps/scripts/4130.cs2 @@ -0,0 +1,66 @@ +void script_4130(int arg0) { + int ivar1; + ivar1 = 0; + switch (globalint_1452) { + flow_1: + case 1: + createExtraChild(new WidgetPointer(arg0), 3, ivar1); + setWidgetFilled(1); + setWidgetRGB(new Color(238, 238, 170)); + setWidgetSize(30, 0, 0, 1); + setWidgetPosition(0, 0, 0, 0); + setWidgetHidden(1); + ivar1 = add(ivar1, 1); + createExtraChild(new WidgetPointer(arg0), 5, ivar1); + setWidgetSprite(3181); + setWidgetSize(30, 0, 0, 1); + setWidgetPosition(0, 0, 0, 0); + setWidgetHidden(1); + ivar1 = add(ivar1, 1); + createExtraChild(new WidgetPointer(arg0), 3, ivar1); + setWidgetFilled(1); + setWidgetRGB(new Color(238, 238, 170)); + setWidgetSize(30, 0, 0, 1); + setWidgetPosition(0, 0, 2, 2); + setWidgetHidden(1); + ivar1 = add(ivar1, 1); + createExtraChild(new WidgetPointer(arg0), 5, ivar1); + setWidgetSprite(3182); + setWidgetSize(30, 0, 0, 1); + setWidgetPosition(0, 0, 2, 2); + setWidgetHidden(1); + ivar1 = add(ivar1, 1); + script_665(0, 50, arg0, ivar1); + GOTO flow_14 + while (true) { + case 2: + if (ivar1 < 4) { + if (setWidgetRegister(new WidgetPointer(arg0), ivar1)) { + setWidgetHidden(0); + } + ivar1 = add(ivar1, 1); + } + } + flow_6: + script_667(50, arg0, ivar1); + break; + case 3: + script_665(0, 50, arg0, 4); + GOTO flow_14 + while (true) { + case 4: + if (ivar1 < 4) { + if (setWidgetRegister(new WidgetPointer(arg0), ivar1)) { + setWidgetHidden(1); + } + ivar1 = add(ivar1, 1); + } + } + script_667(50, arg0, ivar1); + break; + case 5: + deleteAllExtraChilds(new WidgetPointer(arg0)); + } + flow_14: + return; +} diff --git a/dumps/scripts/4131.cs2 b/dumps/scripts/4131.cs2 new file mode 100644 index 0000000..43b6050 --- /dev/null +++ b/dumps/scripts/4131.cs2 @@ -0,0 +1,51 @@ +void script_4131(int arg0,int arg1) { + switch (globalint_1452) { + case 101: + deleteAllExtraChilds(new WidgetPointer(arg0)); + script_4138(0, 50, arg0); + break; + case 102: + cs2method5405(0, 4); + cs2method5405(1, 4); + cs2method5406(0, 0, script_4129(58069409, arg1), 610, script_4129(58069409, arg1), 610, 0); + cs2method5406(1, 0, script_4129(58118559, arg1), 475, script_4129(58118559, arg1), 475, 0); + cs2method5406(0, 1, script_4129(58134945, arg1), 610, script_4129(58167712, arg1), 610, 0); + cs2method5406(1, 1, script_4129(58151326, arg1), 475, script_4129(58167709, arg1), 475, 0); + cs2method5406(0, 2, script_4129(58167711, arg1), 550, script_4129(58167711, arg1), 550, 0); + cs2method5406(1, 2, script_4129(58167708, arg1), 475, script_4129(58167708, arg1), 475, 0); + cs2method5406(0, 3, script_4129(58184098, arg1), 545, script_4129(58184099, arg1), 545, 0); + cs2method5406(1, 3, script_4129(58151338, arg1), 475, script_4129(58151338, arg1), 475, 0); + cameraMethod5502(0, 0, 1000, 1000, 1, 0); + script_4140(30, arg0); + break; + case 103: + cs2method5405(0, 3); + cs2method5405(1, 3); + cs2method5406(0, 0, script_4129(58167711, arg1), 550, script_4129(58167711, arg1), 550, 0); + cs2method5406(1, 0, script_4129(58167708, arg1), 475, script_4129(58167708, arg1), 475, 0); + cs2method5406(0, 1, script_4129(58184098, arg1), 545, script_4129(58184099, arg1), 545, 0); + cs2method5406(1, 1, script_4129(58151338, arg1), 475, script_4129(58151338, arg1), 475, 0); + cs2method5406(0, 2, script_4129(58167717, arg1), 520, script_4129(58167717, arg1), 520, 0); + cs2method5406(1, 2, script_4129(58151338, arg1), 475, script_4129(58151338, arg1), 475, 0); + cameraMethod5502(0, 0, 1000, 1000, 1, 0); + break; + case 104: + cs2method5405(0, 2); + cs2method5405(1, 2); + cs2method5406(0, 0, script_4129(58167717, arg1), 520, script_4129(58167717, arg1), 520, 0); + cs2method5406(1, 0, script_4129(58151338, arg1), 475, script_4129(58151338, arg1), 475, 0); + cs2method5406(0, 1, script_4129(58102180, arg1), 510, script_4129(58036639, arg1), 510, 0); + cs2method5406(1, 1, script_4129(58003872, arg1), 475, script_4129(58003872, arg1), 475, 0); + cameraMethod5502(0, 0, 1000, 1000, 1, 0); + break; + case 105: + script_4138(0, 50, arg0); + break; + case 106: + script_4140(50, arg0); + break; + case 107: + deleteAllExtraChilds(new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/4132.cs2 b/dumps/scripts/4132.cs2 new file mode 100644 index 0000000..3edb15a --- /dev/null +++ b/dumps/scripts/4132.cs2 @@ -0,0 +1,32 @@ +void script_4132(int arg0,int arg1) { + switch (globalint_1452) { + case 201: + deleteAllExtraChilds(new WidgetPointer(arg0)); + createExtraChild(new WidgetPointer(arg0), 3, 0); + setWidgetFilled(1); + setWidgetRGB(new Color(127, 0, 0)); + setWidgetSize(0, 0, 1, 1); + setWidgetPosition(0, 0, 0, 0); + cs2method2103(255); + script_665(0, 50, arg0, 1); + break; + case 202: + script_667(50, arg0, 1); + break; + case 203: + if (setWidgetRegister(new WidgetPointer(arg0), 0)) { + setScriptCallOnGameloop(4133, new WidgetPointer(arg0), 0, 3, -3, 150, 255, 50, 0, 3581, "Iiiiiiii\u00ab"); + } + break; + case 204: + deleteAllExtraChilds(new WidgetPointer(arg0)); + script_4138(0, 50, arg0); + break; + case 205: + script_4140(50, arg0); + break; + case 206: + deleteAllExtraChilds(new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/4133.cs2 b/dumps/scripts/4133.cs2 new file mode 100644 index 0000000..0c9eb9e --- /dev/null +++ b/dumps/scripts/4133.cs2 @@ -0,0 +1,36 @@ +void script_4133(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8) { + int ivar9; + int ivar10; + flow_0: + ivar9 = 0; + ivar10 = 0; + IF (arg1 == -1) + GOTO flow_1 + GOTO flow_2 + flow_1: + IF (setWidgetRegister(new WidgetPointer(arg0))) + GOTO flow_3 + flow_2: + IF (setWidgetRegister(new WidgetPointer(arg0), arg1)) + GOTO flow_3 + GOTO flow_13 + flow_3: + if (arg7 > 0) { + setScriptCallOnGameloop(4133, new WidgetPointer(arg0), arg1, arg2, arg3, arg4, arg5, arg6, subtract(arg7, 1), arg8, "Iiiiiiii\u00ab"); + return; + } + ivar9 = cs2method1609(); + ivar10 = min(max(add(ivar9, arg2), arg4), arg5); + if ((ivar10 == arg4) || (ivar10 == arg5)) { + if (ivar10 == arg5) { + arg7 = arg6; + } + if ((ivar10 == arg4) && (arg8 != -1)) { + playSoundEffect2False(arg8, 1, 50, 255); + } + setScriptCallOnGameloop(4133, new WidgetPointer(arg0), arg1, arg3, arg2, arg4, arg5, arg6, arg7, arg8, "Iiiiiiii\u00ab"); + } + cs2method2103(ivar10); + flow_13: + return; +} diff --git a/dumps/scripts/4134.cs2 b/dumps/scripts/4134.cs2 new file mode 100644 index 0000000..ff853d6 --- /dev/null +++ b/dumps/scripts/4134.cs2 @@ -0,0 +1,5 @@ +void script_4134(int arg0,int arg1,int arg2,int arg3) { + setWidgetSprite(arg1, new WidgetPointer(arg0)); + setWidgetSprite(arg3, new WidgetPointer(arg2)); + return; +} diff --git a/dumps/scripts/4135.cs2 b/dumps/scripts/4135.cs2 new file mode 100644 index 0000000..611edf2 --- /dev/null +++ b/dumps/scripts/4135.cs2 @@ -0,0 +1,6 @@ +void script_4135(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + setWidgetSprite(arg1, new WidgetPointer(arg0)); + setWidgetSprite(arg3, new WidgetPointer(arg2)); + setWidgetSprite(arg5, new WidgetPointer(arg4)); + return; +} diff --git a/dumps/scripts/4136.cs2 b/dumps/scripts/4136.cs2 new file mode 100644 index 0000000..0eca05c --- /dev/null +++ b/dumps/scripts/4136.cs2 @@ -0,0 +1,5 @@ +void script_4136() { + playSoundEffect2False(3549, 1, 0, 255, cs2method_4019(25, 25)); + script_675(); + return; +} diff --git a/dumps/scripts/4137.cs2 b/dumps/scripts/4137.cs2 new file mode 100644 index 0000000..71f44b7 --- /dev/null +++ b/dumps/scripts/4137.cs2 @@ -0,0 +1,5 @@ +void script_4137() { + playSoundEffect2False(3550, 1, 0, 255, cs2method_4019(25, 25)); + script_675(); + return; +} diff --git a/dumps/scripts/4138.cs2 b/dumps/scripts/4138.cs2 new file mode 100644 index 0000000..fd6751a --- /dev/null +++ b/dumps/scripts/4138.cs2 @@ -0,0 +1,11 @@ +void script_4138(int arg0,int arg1,int arg2) { + createExtraChild(new WidgetPointer(arg2), 3, 0); + cs2method2103(255); + setWidgetFilled(1); + setWidgetRGB(new Color(arg0)); + setWidgetSize(0, 0, 1, 1); + setWidgetPosition(0, 0, 1, 1); + arg1 = min(arg1, 250); + setScriptCallOnGameloop(4139, add(getClientCycle(), arg1), new WidgetPointer(arg2), "iI"); + return; +} diff --git a/dumps/scripts/4139.cs2 b/dumps/scripts/4139.cs2 new file mode 100644 index 0000000..8e6a8af --- /dev/null +++ b/dumps/scripts/4139.cs2 @@ -0,0 +1,14 @@ +void script_4139(int arg0,int arg1) { + int ivar2; + ivar2 = 0; + if (setWidgetRegister(new WidgetPointer(arg1), 0)) { + ivar2 = subtract(arg0, getClientCycle()); + if (ivar2 <= 0) { + cs2method2103(0); + setScriptCallOnGameloop(-1, ""); + return; + } + cs2method2103(max(subtract(cs2method1609(), divide(cs2method1609(), ivar2)), 1)); + } + return; +} diff --git a/dumps/scripts/414.cs2 b/dumps/scripts/414.cs2 new file mode 100644 index 0000000..f90d74c --- /dev/null +++ b/dumps/scripts/414.cs2 @@ -0,0 +1,48 @@ +void script_414(int arg0) { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(1013,19)); + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(1013,18)); + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(1013,20)); + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(1013,21)); + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(1013,17)); + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(1013,15)); + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(1013,16)); + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(1013,14)); + switch (arg0) { + case 66387971: + setWidgetIsHidden(false, new WidgetPointer(1013,19)); + break; + case 66387973: + setWidgetIsHidden(false, new WidgetPointer(1013,18)); + break; + case 66387970: + setWidgetIsHidden(false, new WidgetPointer(1013,20)); + break; + case 66387972: + setWidgetIsHidden(false, new WidgetPointer(1013,21)); + break; + case 66387978: + setWidgetIsHidden(false, new WidgetPointer(1013,17)); + break; + case 66387979: + setWidgetIsHidden(false, new WidgetPointer(1013,17)); + break; + case 66387980: + setWidgetIsHidden(false, new WidgetPointer(1013,15)); + break; + case 66387981: + setWidgetIsHidden(false, new WidgetPointer(1013,15)); + break; + case 66387974: + setWidgetIsHidden(false, new WidgetPointer(1013,16)); + break; + case 66387975: + setWidgetIsHidden(false, new WidgetPointer(1013,16)); + break; + case 66387976: + setWidgetIsHidden(false, new WidgetPointer(1013,14)); + break; + case 66387977: + setWidgetIsHidden(false, new WidgetPointer(1013,14)); + } + return; +} diff --git a/dumps/scripts/4140.cs2 b/dumps/scripts/4140.cs2 new file mode 100644 index 0000000..db86a63 --- /dev/null +++ b/dumps/scripts/4140.cs2 @@ -0,0 +1,10 @@ +void script_4140(int arg0,int arg1) { + if (setWidgetRegister(new WidgetPointer(arg1), 0)) { + setWidgetFilled(1); + setWidgetSize(0, 0, 1, 1); + setWidgetPosition(0, 0, 1, 1); + cs2method2103(0); + setScriptCallOnGameloop(4141, add(getClientCycle(), arg0), new WidgetPointer(arg1), "iI"); + } + return; +} diff --git a/dumps/scripts/4141.cs2 b/dumps/scripts/4141.cs2 new file mode 100644 index 0000000..5fcdc7d --- /dev/null +++ b/dumps/scripts/4141.cs2 @@ -0,0 +1,17 @@ +void script_4141(int arg0,int arg1) { + int ivar2; + int ivar3; + ivar2 = 0; + ivar3 = 0; + if (setWidgetRegister(new WidgetPointer(arg1), 0)) { + ivar2 = subtract(arg0, getClientCycle()); + if (ivar2 <= 0) { + setScriptCallOnGameloop(-1, ""); + deleteExtraChild(); + return; + } + ivar3 = subtract(255, cs2method1609()); + cs2method2103(min(add(cs2method1609(), divide(ivar3, ivar2)), 254)); + } + return; +} diff --git a/dumps/scripts/4142.cs2 b/dumps/scripts/4142.cs2 new file mode 100644 index 0000000..16ff667 --- /dev/null +++ b/dumps/scripts/4142.cs2 @@ -0,0 +1,4 @@ +void script_4142() { + script_4143(); + return; +} diff --git a/dumps/scripts/4143.cs2 b/dumps/scripts/4143.cs2 new file mode 100644 index 0000000..15dadd3 --- /dev/null +++ b/dumps/scripts/4143.cs2 @@ -0,0 +1,18 @@ +void script_4143() { + string svar0; + svar0 = "null"; + if (((boolean)bitconfig_8780)) { + setWidgetSprite(4584, new WidgetPointer(261,3)); + svar0 = "Toggle Profanity Filter" + "
" + "(filter is currently off)"; + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(261,22), svar0, 25, 180, "IIsii", new WidgetPointer(261,3)); + globalint_2 = 0; + } else { + if (((boolean)bitconfig_8780)) { + setWidgetSprite(4583, new WidgetPointer(261,3)); + svar0 = "Toggle Profanity Filter" + "
" + "(filter is currently on)"; + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(261,22), svar0, 25, 180, "IIsii", new WidgetPointer(261,3)); + globalint_2 = 0; + } + } + return; +} diff --git a/dumps/scripts/4144.cs2 b/dumps/scripts/4144.cs2 new file mode 100644 index 0000000..47581c6 --- /dev/null +++ b/dumps/scripts/4144.cs2 @@ -0,0 +1,16 @@ +void script_4144(int arg0,int arg1,int arg2) { + int ivar3; + ivar3 = add(multiply(getLineCount(getWidgetActualWidth(new WidgetPointer(arg1)), 495, globalstring_343), 12), 5); + setWidgetSize(0, ivar3, 1, 0, new WidgetPointer(arg1)); + setWidgetScrollMax(0, ivar3, new WidgetPointer(arg0)); + cs2method2100(0, 0, new WidgetPointer(arg0)); + setWidgetText(new WidgetPointer(arg1), globalstring_343); + if (ivar3 <= getWidgetActualHeight(new WidgetPointer(arg0))) { + deleteAllExtraChilds(new WidgetPointer(arg2)); + setWidgetIsHidden(true, new WidgetPointer(arg2)); + return; + } + setWidgetIsHidden(false, new WidgetPointer(arg2)); + script_31(arg2, arg0, 798, 795, 796, 797, 793, 794); + return; +} diff --git a/dumps/scripts/4145.cs2 b/dumps/scripts/4145.cs2 new file mode 100644 index 0000000..dff59b6 --- /dev/null +++ b/dumps/scripts/4145.cs2 @@ -0,0 +1,12 @@ +void script_4145(int arg0,int arg1) { + if (globalint_98 >= 1) { + setWidgetIsHidden(false, new WidgetPointer(arg0)); + cs2method2310(new WidgetPointer(arg0), "I don't know it."); + setWidgetPosition(0, subtract(0, divide(getWidgetActualHeight(new WidgetPointer(arg1)), 2)), 1, 1, new WidgetPointer(arg1)); + } else { + setWidgetIsHidden(true, new WidgetPointer(arg0)); + setWidgetNoOptions(new WidgetPointer(arg0)); + setWidgetPosition(0, 0, 1, 1, new WidgetPointer(arg1)); + } + return; +} diff --git a/dumps/scripts/4146.cs2 b/dumps/scripts/4146.cs2 new file mode 100644 index 0000000..e0b13f9 --- /dev/null +++ b/dumps/scripts/4146.cs2 @@ -0,0 +1,75 @@ +void script_4146() { + int ivar0; + ivar0 = 0; + if (isBitFlagged(globalint_98, 31)) { + setWidgetIsHidden(true, new WidgetPointer(14,13)); + setWidgetIsHidden(false, new WidgetPointer(14,31)); + script_915(917537); + script_915(917539); + } else { + flow_2: + setWidgetIsHidden(false, new WidgetPointer(14,13)); + setWidgetIsHidden(true, new WidgetPointer(14,31)); + script_1088(917518, 0); + script_1298(917520, 0, 0, 0); + script_1088(917525, 19); + ivar0 = subtract(getWidgetActualHeight(new WidgetPointer(14,16)), 14); + SWITCH (bitAnd(globalint_98, 3)) { + case 0: + GOTO flow_3 + case 3: + GOTO flow_5 + } + GOTO flow_4 + flow_3: + setWidgetText(new WidgetPointer(14,23), "No PIN set"); + ivar0 = divide(ivar0, 2); + script_4147(917522, ivar0, divide(subtract(0, ivar0), 2), "Set a PIN"); + script_4147(917523, ivar0, divide(ivar0, 2), "Change recovery delay"); + setWidgetIsHidden(true, new WidgetPointer(14,20)); + GOTO flow_6 + flow_4: + setWidgetText(new WidgetPointer(14,23), "You have a PIN"); + ivar0 = divide(ivar0, 3); + script_4147(917522, ivar0, subtract(0, ivar0), "Change your PIN"); + script_4147(917523, ivar0, 0, "Delete your PIN"); + script_4147(917524, ivar0, ivar0, "Change recovery delay"); + GOTO flow_6 + flow_5: + setWidgetText(new WidgetPointer(14,23), "PIN coming soon"); + ivar0 = min(ivar0, 50); + script_4147(917522, ivar0, 0, "Cancel the PIN"); + setWidgetIsHidden(true, new WidgetPointer(14,19)); + setWidgetIsHidden(true, new WidgetPointer(14,20)); + flow_6: + if (isBitFlagged(globalint_98, 10)) { + setWidgetText(new WidgetPointer(14,25), "7 days"); + } else { + setWidgetText(new WidgetPointer(14,25), "3 days"); + } + } + deleteAllExtraChilds(new WidgetPointer(14,28)); + createExtraChild(new WidgetPointer(14,28), 4, 0); + setWidgetFont(495); + setWidgetRGB(new Color(255, 152, 31)); + setWidgetUnknownBoolean(true); + setWidgetTextAlignment(0, 1, 0); + setWidgetText(globalstring_344); + if (add(multiply(getLineCount(subtract(getWidgetActualWidth(new WidgetPointer(getWidgetParentId(new WidgetPointer(14,28)))), 14), 495, globalstring_344), 12), 5) <= getWidgetActualHeight(new WidgetPointer(14,28))) { + setWidgetSize(14, 40, 1, 1, new WidgetPointer(14,28)); + setWidgetScrollMax(0, 0, new WidgetPointer(14,28)); + setWidgetPosition(0, 0, 1, 1); + setWidgetSize(0, 0, 1, 1); + setWidgetIsHidden(true, new WidgetPointer(14,29)); + return; + } + setWidgetSize(31, 40, 1, 1, new WidgetPointer(14,28)); + ivar0 = add(multiply(getLineCount(getWidgetActualWidth(new WidgetPointer(14,28)), 495, globalstring_344), 12), 5); + setWidgetScrollMax(0, ivar0, new WidgetPointer(14,28)); + cs2method2100(0, 0, new WidgetPointer(14,28)); + setWidgetPosition(0, 0, 1, 0); + setWidgetSize(0, ivar0, 1, 0); + setWidgetIsHidden(false, new WidgetPointer(14,29)); + script_31(917533, 917532, 792, 789, 790, 791, 773, 788); + return; +} diff --git a/dumps/scripts/4147.cs2 b/dumps/scripts/4147.cs2 new file mode 100644 index 0000000..cedf039 --- /dev/null +++ b/dumps/scripts/4147.cs2 @@ -0,0 +1,10 @@ +void script_4147(int arg0,int arg1,int arg2,string arg3) { + setWidgetIsHidden(false, new WidgetPointer(arg0)); + cs2method2310(new WidgetPointer(arg0), arg3); + setWidgetSize(16, arg1, 1, 0, new WidgetPointer(arg0)); + setWidgetPosition(0, arg2, 1, 1, new WidgetPointer(arg0)); + script_4149(arg0, 0, arg3); + setScriptCallOnMouseOver(4148, new WidgetPointer(arg0), arg3, 1, "Is1", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(4148, new WidgetPointer(arg0), arg3, 0, "Is1", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/4148.cs2 b/dumps/scripts/4148.cs2 new file mode 100644 index 0000000..7629fb1 --- /dev/null +++ b/dumps/scripts/4148.cs2 @@ -0,0 +1,4 @@ +void script_4148(int arg0,int arg1,string arg2) { + script_4149(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/4149.cs2 b/dumps/scripts/4149.cs2 new file mode 100644 index 0000000..cd72afd --- /dev/null +++ b/dumps/scripts/4149.cs2 @@ -0,0 +1,20 @@ +void script_4149(int arg0,int arg1,string arg2) { + if (((boolean)arg1)) { + script_1361(arg0); + } else { + script_915(arg0); + } + createExtraChild(new WidgetPointer(arg0), 4, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(0, 0, 1, 1); + setWidgetPosition(0, 0, 1, 1); + setWidgetFont(495); + setWidgetUnknownBoolean(true); + setWidgetTextAlignment(1, 1, 0); + if (((boolean)arg1)) { + setWidgetRGB(new Color(255, 255, 255)); + } else { + setWidgetRGB(new Color(255, 152, 31)); + } + setWidgetText(arg2); + return; +} diff --git a/dumps/scripts/415.cs2 b/dumps/scripts/415.cs2 new file mode 100644 index 0000000..14fc799 --- /dev/null +++ b/dumps/scripts/415.cs2 @@ -0,0 +1,12 @@ +void script_415() { + setWidgetIsHidden(true, new WidgetPointer(1013,19)); + setWidgetIsHidden(true, new WidgetPointer(1013,18)); + setWidgetIsHidden(true, new WidgetPointer(1013,20)); + setWidgetIsHidden(true, new WidgetPointer(1013,21)); + setWidgetIsHidden(true, new WidgetPointer(1013,17)); + setWidgetIsHidden(true, new WidgetPointer(1013,15)); + setWidgetIsHidden(true, new WidgetPointer(1013,16)); + setWidgetIsHidden(true, new WidgetPointer(1013,14)); + globalint_1360 = 0; + return; +} diff --git a/dumps/scripts/4150.cs2 b/dumps/scripts/4150.cs2 new file mode 100644 index 0000000..105834e --- /dev/null +++ b/dumps/scripts/4150.cs2 @@ -0,0 +1,4 @@ +void script_4150() { + script_71(4); + return; +} diff --git a/dumps/scripts/4151.cs2 b/dumps/scripts/4151.cs2 new file mode 100644 index 0000000..1de004b --- /dev/null +++ b/dumps/scripts/4151.cs2 @@ -0,0 +1,4 @@ +void script_4151(int arg0) { + script_4211(arg0, 4040, 920849, 11442273); + return; +} diff --git a/dumps/scripts/4152.cs2 b/dumps/scripts/4152.cs2 new file mode 100644 index 0000000..129323c --- /dev/null +++ b/dumps/scripts/4152.cs2 @@ -0,0 +1,4 @@ +void script_4152(int arg0,string arg1) { + script_4212(arg0, 4040, 920849, 11442273, arg1); + return; +} diff --git a/dumps/scripts/4153.cs2 b/dumps/scripts/4153.cs2 new file mode 100644 index 0000000..f811323 --- /dev/null +++ b/dumps/scripts/4153.cs2 @@ -0,0 +1,10 @@ +void script_4153() { + if (((boolean)bitconfig_4466)) { + setWidgetSprite(1135, new WidgetPointer(1108,33)); + } else { + if (((boolean)bitconfig_4466)) { + setWidgetSprite(1134, new WidgetPointer(1108,33)); + } + } + return; +} diff --git a/dumps/scripts/4154.cs2 b/dumps/scripts/4154.cs2 new file mode 100644 index 0000000..8b71656 --- /dev/null +++ b/dumps/scripts/4154.cs2 @@ -0,0 +1,4 @@ +void script_4154(int arg0) { + script_4155(arg0, 4597, 4596, 4607, 4606, 4617, 4616); + return; +} diff --git a/dumps/scripts/4155.cs2 b/dumps/scripts/4155.cs2 new file mode 100644 index 0000000..79c85e1 --- /dev/null +++ b/dumps/scripts/4155.cs2 @@ -0,0 +1,54 @@ +void script_4155(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6) { + setScriptCallOnMouseEntered(4159, new WidgetPointer(-32768,3), 0, 0, "Iii", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(4159, new WidgetPointer(-32768,3), 255, 0, "Iii", new WidgetPointer(arg0)); + deleteAllExtraChilds(new WidgetPointer(arg0)); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 1, 1); + setWidgetSize(24, 22, 1, 1); + setWidgetSprite(arg6); + cs2method2103(255); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 1, 0); + setWidgetSize(24, 12, 1, 0); + setWidgetSprite(arg2); + cs2method2103(255); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 1, 2); + setWidgetSize(24, 12, 1, 0); + setWidgetSprite(arg4); + cs2method2103(255); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 0, 1); + setWidgetSize(12, 24, 0, 1); + setWidgetSprite(arg5); + setWidgetHFlip(1); + cs2method2103(255); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 2, 1); + setWidgetSize(12, 24, 0, 1); + setWidgetSprite(arg5); + cs2method2103(255); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(12, 12, 0, 0); + setWidgetSprite(arg1); + setWidgetHFlip(1); + cs2method2103(255); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 0, 2); + setWidgetSize(12, 12, 0, 0); + setWidgetSprite(arg3); + setWidgetHFlip(1); + cs2method2103(255); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 2, 0); + setWidgetSize(12, 12, 0, 0); + setWidgetSprite(arg1); + cs2method2103(255); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 2, 2); + setWidgetSize(12, 12, 0, 0); + setWidgetSprite(arg3); + cs2method2103(255); + return; +} diff --git a/dumps/scripts/4156.cs2 b/dumps/scripts/4156.cs2 new file mode 100644 index 0000000..f558189 --- /dev/null +++ b/dumps/scripts/4156.cs2 @@ -0,0 +1,4 @@ +void script_4156(int arg0) { + script_4157(arg0); + return; +} diff --git a/dumps/scripts/4157.cs2 b/dumps/scripts/4157.cs2 new file mode 100644 index 0000000..fbd1b68 --- /dev/null +++ b/dumps/scripts/4157.cs2 @@ -0,0 +1,4 @@ +void script_4157(int arg0) { + script_4158(arg0, 4599, 4598, 4609, 4608, 4619, 4618); + return; +} diff --git a/dumps/scripts/4158.cs2 b/dumps/scripts/4158.cs2 new file mode 100644 index 0000000..6150323 --- /dev/null +++ b/dumps/scripts/4158.cs2 @@ -0,0 +1,54 @@ +void script_4158(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6) { + setScriptCallOnMousePressed(4162, new WidgetPointer(-32768,3), "I", new WidgetPointer(arg0)); + setScriptCallOnMouseReleased(4163, new WidgetPointer(-32768,3), "I", new WidgetPointer(arg0)); + deleteAllExtraChilds(new WidgetPointer(arg0)); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 1, 1); + setWidgetSize(24, 22, 1, 1); + setWidgetSprite(arg6); + cs2method2103(255); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 1, 0); + setWidgetSize(24, 12, 1, 0); + setWidgetSprite(arg2); + cs2method2103(255); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 1, 2); + setWidgetSize(24, 12, 1, 0); + setWidgetSprite(arg4); + cs2method2103(255); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 0, 1); + setWidgetSize(12, 24, 0, 1); + setWidgetSprite(arg5); + setWidgetHFlip(1); + cs2method2103(255); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 2, 1); + setWidgetSize(12, 24, 0, 1); + setWidgetSprite(arg5); + cs2method2103(255); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(12, 12, 0, 0); + setWidgetSprite(arg1); + setWidgetHFlip(1); + cs2method2103(255); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 0, 2); + setWidgetSize(12, 12, 0, 0); + setWidgetSprite(arg3); + setWidgetHFlip(1); + cs2method2103(255); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 2, 0); + setWidgetSize(12, 12, 0, 0); + setWidgetSprite(arg1); + cs2method2103(255); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 2, 2); + setWidgetSize(12, 12, 0, 0); + setWidgetSprite(arg3); + cs2method2103(255); + return; +} diff --git a/dumps/scripts/4159.cs2 b/dumps/scripts/4159.cs2 new file mode 100644 index 0000000..7102a6c --- /dev/null +++ b/dumps/scripts/4159.cs2 @@ -0,0 +1,4 @@ +void script_4159(int arg0,int arg1,int arg2) { + script_4160(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/416.cs2 b/dumps/scripts/416.cs2 new file mode 100644 index 0000000..2045210 --- /dev/null +++ b/dumps/scripts/416.cs2 @@ -0,0 +1,11 @@ +void script_416(int arg0) { + int ivar1; + ivar1 = getWidgetShadeColor(new WidgetPointer(arg0)); + ivar1 = add(ivar1, 2); + if (ivar1 < 255) { + cs2method2103(ivar1, new WidgetPointer(arg0)); + } else { + setWidgetIsHidden(true, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/4160.cs2 b/dumps/scripts/4160.cs2 new file mode 100644 index 0000000..f59ee31 --- /dev/null +++ b/dumps/scripts/4160.cs2 @@ -0,0 +1,39 @@ +void script_4160(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + flow_0: + if (arg2 > 0) { + setScriptCallOnGameloop(4159, new WidgetPointer(-32768,3), arg1, subtract(arg2, 1), "Iii", new WidgetPointer(arg0)); + return; + } + ivar3 = 0; + ivar4 = 0; + if (setWidgetRegister(new WidgetPointer(arg0), 0)) { + ivar3 = cs2method1609(); + if (((boolean)arg1)) { + ivar4 = subtract(ivar3, 22); + } else { + ivar4 = add(ivar3, 22); + } + ivar4 = max(ivar4, 0); + ivar4 = min(ivar4, 255); + } + IF (((boolean)ivar4)) + GOTO flow_8 + GOTO flow_9 + flow_8: + IF (((boolean)arg1)) + GOTO flow_11 + flow_9: + IF ((ivar4 == 255) && ((boolean)arg1)) + GOTO flow_11 + GOTO flow_12 + flow_11: + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + GOTO flow_13 + flow_12: + setScriptCallOnGameloop(4159, new WidgetPointer(-32768,3), arg1, 0, "Iii", new WidgetPointer(arg0)); + flow_13: + script_4161(arg0, ivar4); + return; +} diff --git a/dumps/scripts/4161.cs2 b/dumps/scripts/4161.cs2 new file mode 100644 index 0000000..aafdbbe --- /dev/null +++ b/dumps/scripts/4161.cs2 @@ -0,0 +1,11 @@ +void script_4161(int arg0,int arg1) { + int ivar2; + ivar2 = 0; + while (ivar2 < getExtraChildGap(new WidgetPointer(arg0))) { + if (setWidgetRegister(new WidgetPointer(arg0), ivar2)) { + cs2method2103(arg1); + } + ivar2 = add(ivar2, 1); + } + return; +} diff --git a/dumps/scripts/4162.cs2 b/dumps/scripts/4162.cs2 new file mode 100644 index 0000000..f506533 --- /dev/null +++ b/dumps/scripts/4162.cs2 @@ -0,0 +1,4 @@ +void script_4162(int arg0) { + script_4161(arg0, 0); + return; +} diff --git a/dumps/scripts/4163.cs2 b/dumps/scripts/4163.cs2 new file mode 100644 index 0000000..2ab5f38 --- /dev/null +++ b/dumps/scripts/4163.cs2 @@ -0,0 +1,4 @@ +void script_4163(int arg0) { + script_4161(arg0, 255); + return; +} diff --git a/dumps/scripts/4164.cs2 b/dumps/scripts/4164.cs2 new file mode 100644 index 0000000..25b68e6 --- /dev/null +++ b/dumps/scripts/4164.cs2 @@ -0,0 +1,4 @@ +void script_4164(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7) { + script_4165(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + return; +} diff --git a/dumps/scripts/4165.cs2 b/dumps/scripts/4165.cs2 new file mode 100644 index 0000000..3f90a0d --- /dev/null +++ b/dumps/scripts/4165.cs2 @@ -0,0 +1,7 @@ +void script_4165(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7) { + setWidgetSprite(arg1, new WidgetPointer(arg0)); + setWidgetSprite(arg3, new WidgetPointer(arg2)); + setWidgetSprite(arg5, new WidgetPointer(arg4)); + setWidgetSprite(arg7, new WidgetPointer(arg6)); + return; +} diff --git a/dumps/scripts/4166.cs2 b/dumps/scripts/4166.cs2 new file mode 100644 index 0000000..b1b1760 --- /dev/null +++ b/dumps/scripts/4166.cs2 @@ -0,0 +1,32 @@ +void script_4166(int arg0,int arg1,int arg2,int arg3,string arg4,string arg5) { + deleteAllExtraChilds(new WidgetPointer(arg0)); + script_4178(0, arg2, 0); + if (isMember() && ((boolean)arg3)) { + setWidgetIsHidden(true, new WidgetPointer(arg0)); + return; + } + createExtraChild(new WidgetPointer(arg0), 3, 0); + setWidgetSize(0, 0, 1, 1); + setWidgetPosition(0, 0, 1, 1); + setWidgetFilled(1); + setWidgetRGB(new Color(255, 0, 0)); + setWidgetHidden(1); + setScriptCallOnGameloop(4175, new WidgetPointer(-32768,3), getWidgetCustomChildArrayIndex(), arg2, 0, "Iii1", new WidgetPointer(arg0)); + createExtraChild(new WidgetPointer(arg0), 5, 1); + setWidgetSize(15, 15, 0, 0); + setWidgetPosition(10, 0, 0, 1); + script_4169(arg2); + setScriptCallOnConfigChange(4168, new WidgetPointer(-32768,3), getWidgetCustomChildArrayIndex(), arg2, 286, 1, "IiiY", new WidgetPointer(arg0)); + createExtraChild(new WidgetPointer(arg0), 4, 2); + setWidgetSize(35, 0, 1, 1); + setWidgetPosition(0, 0, 2, 1); + setWidgetFont(494); + setWidgetTextAlignment(0, 1, 0); + setWidgetRGB(new Color(255, 152, 31)); + setWidgetUnknownBoolean(true); + setWidgetText(arg4); + setScriptCallOnMouseEntered(1356, new WidgetPointer(-32768,3), getWidgetCustomChildArrayIndex(), 16777215, "Iii", new WidgetPointer(arg0)); + setScriptCallOnMouseOver(1160, new WidgetPointer(-32768,3), -1, new WidgetPointer(arg1), arg5, 25, 200, "IiIsii", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(4167, new WidgetPointer(-32768,3), getWidgetCustomChildArrayIndex(), new WidgetPointer(arg1), "IiI", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/4167.cs2 b/dumps/scripts/4167.cs2 new file mode 100644 index 0000000..308d345 --- /dev/null +++ b/dumps/scripts/4167.cs2 @@ -0,0 +1,7 @@ +void script_4167(int arg0,int arg1,int arg2) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetRGB(new Color(255, 152, 31)); + } + script_41(arg2); + return; +} diff --git a/dumps/scripts/4168.cs2 b/dumps/scripts/4168.cs2 new file mode 100644 index 0000000..88d2148 --- /dev/null +++ b/dumps/scripts/4168.cs2 @@ -0,0 +1,6 @@ +void script_4168(int arg0,int arg1,int arg2) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + script_4169(arg2); + } + return; +} diff --git a/dumps/scripts/4169.cs2 b/dumps/scripts/4169.cs2 new file mode 100644 index 0000000..fbcd550 --- /dev/null +++ b/dumps/scripts/4169.cs2 @@ -0,0 +1,8 @@ +void script_4169(int arg0) { + if (isBitFlagged(standart_config_286, arg0)) { + setWidgetSprite(1135); + } else { + setWidgetSprite(1134); + } + return; +} diff --git a/dumps/scripts/417.cs2 b/dumps/scripts/417.cs2 new file mode 100644 index 0000000..9adacf3 --- /dev/null +++ b/dumps/scripts/417.cs2 @@ -0,0 +1,13 @@ +void script_417(int arg0) { + int ivar1; + ivar1 = getWidgetShadeColor(new WidgetPointer(arg0)); + if (((boolean)globalint_1387)) { + ivar1 = add(ivar1, 2); + if (ivar1 < 255) { + cs2method2103(ivar1, new WidgetPointer(arg0)); + } else { + setWidgetIsHidden(true, new WidgetPointer(arg0)); + } + } + return; +} diff --git a/dumps/scripts/4170.cs2 b/dumps/scripts/4170.cs2 new file mode 100644 index 0000000..fdbd8ff --- /dev/null +++ b/dumps/scripts/4170.cs2 @@ -0,0 +1,26 @@ +void script_4170(int arg0,int arg1,int arg2,string arg3) { + deleteAllExtraChilds(new WidgetPointer(arg0)); + script_4178(1, arg2, 0); + createExtraChild(new WidgetPointer(arg0), 5, 0); + setWidgetSize(0, 0, 1, 1); + setWidgetPosition(0, 0, 1, 1); + setWidgetSprite(170); + setScriptCallOnMouseOver(1160, new WidgetPointer(-32768,3), -2147483643, new WidgetPointer(arg1), arg3, 25, 200, "IiIsii"); + setScriptCallOnMouseExit(40, new WidgetPointer(arg1), "I"); + createExtraChild(new WidgetPointer(arg0), 5, 1); + script_4172(arg2); + setScriptCallOnItemContainerUpdate(4171, new WidgetPointer(-32768,3), -2147483643, arg2, 94, 1, "IiiY"); + createExtraChild(new WidgetPointer(arg0), 5, 2); + setWidgetSize(0, 0, 1, 1); + setWidgetPosition(0, 0, 1, 1); + setWidgetSprite(1132); + script_4174(arg2); + setScriptCallOnConfigChange(4173, new WidgetPointer(-32768,3), getWidgetCustomChildArrayIndex(), arg2, 286, 1, "IiiY"); + createExtraChild(new WidgetPointer(arg0), 5, 3); + setWidgetSize(10, 32, 0, 0); + setWidgetPosition(0, 0, 1, 1); + setWidgetSprite(937); + setWidgetHidden(1); + setScriptCallOnGameloop(4175, new WidgetPointer(-32768,3), getWidgetCustomChildArrayIndex(), arg2, 1, "Iii1"); + return; +} diff --git a/dumps/scripts/4171.cs2 b/dumps/scripts/4171.cs2 new file mode 100644 index 0000000..157a788 --- /dev/null +++ b/dumps/scripts/4171.cs2 @@ -0,0 +1,6 @@ +void script_4171(int arg0,int arg1,int arg2) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + script_4172(arg2); + } + return; +} diff --git a/dumps/scripts/4172.cs2 b/dumps/scripts/4172.cs2 new file mode 100644 index 0000000..82f1290 --- /dev/null +++ b/dumps/scripts/4172.cs2 @@ -0,0 +1,18 @@ +void script_4172(int arg0) { + int ivar1; + ivar1 = getItemIdInSlot(94, arg0); + if (ivar1 != -1) { + setWidgetSize(36, 32, 0, 0); + setItemOnWidgetMethod1200(ivar1, getItemAmtInSlot(94, arg0)); + setWidgetShadowColor(new Color(48, 32, 32)); + setWidgetBorderThickness(1); + setWidgetPosition(2, 0, 1, 1); + } else { + setWidgetSize(32, 32, 0, 0); + setWidgetSprite(cs2method_3408(105, 100, 796, arg0)); + setWidgetShadowColor(new Color(0, 0, 0)); + setWidgetBorderThickness(0); + setWidgetPosition(0, 0, 1, 1); + } + return; +} diff --git a/dumps/scripts/4173.cs2 b/dumps/scripts/4173.cs2 new file mode 100644 index 0000000..0767228 --- /dev/null +++ b/dumps/scripts/4173.cs2 @@ -0,0 +1,6 @@ +void script_4173(int arg0,int arg1,int arg2) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + script_4174(arg2); + } + return; +} diff --git a/dumps/scripts/4174.cs2 b/dumps/scripts/4174.cs2 new file mode 100644 index 0000000..404796c --- /dev/null +++ b/dumps/scripts/4174.cs2 @@ -0,0 +1,8 @@ +void script_4174(int arg0) { + if (isBitFlagged(bitconfig_642, arg0)) { + setWidgetHidden(0); + } else { + setWidgetHidden(1); + } + return; +} diff --git a/dumps/scripts/4175.cs2 b/dumps/scripts/4175.cs2 new file mode 100644 index 0000000..9794ed6 --- /dev/null +++ b/dumps/scripts/4175.cs2 @@ -0,0 +1,19 @@ +void script_4175(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + ivar4 = subtract(getClientCycle(), script_4176(arg3, arg2)); + if ((ivar4 >= 255) || (ivar4 < 0)) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetHidden(1); + } + return; + } + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetHidden(0); + if (mod(ivar4, 40) > 20) { + cs2method2103(255); + } else { + cs2method2103(ivar4); + } + } + return; +} diff --git a/dumps/scripts/4176.cs2 b/dumps/scripts/4176.cs2 new file mode 100644 index 0000000..9a7df71 --- /dev/null +++ b/dumps/scripts/4176.cs2 @@ -0,0 +1,56 @@ +int script_4176(int arg0,int arg1) { + if (((boolean)arg0)) { + switch (arg1) { + case 0: + return globalint_1465; + case 1: + return globalint_1466; + case 2: + return globalint_1467; + case 3: + return globalint_740; + case 4: + return globalint_745; + case 5: + return globalint_780; + case 7: + return globalint_781; + case 9: + return globalint_782; + case 10: + return globalint_789; + case 12: + return globalint_1409; + case 13: + return globalint_1410; + } + } else { + switch (arg1) { + case 0: + return globalint_1453; + case 1: + return globalint_1454; + case 4: + return globalint_1455; + case 5: + return globalint_1456; + case 6: + return globalint_1457; + case 7: + return globalint_1458; + case 8: + return globalint_1459; + case 9: + return globalint_1460; + case 10: + return globalint_1461; + case 12: + return globalint_1462; + case 13: + return globalint_1463; + case 28: + return globalint_1464; + } + } + return -1; +} diff --git a/dumps/scripts/4177.cs2 b/dumps/scripts/4177.cs2 new file mode 100644 index 0000000..96d823d --- /dev/null +++ b/dumps/scripts/4177.cs2 @@ -0,0 +1,4 @@ +void script_4177(int arg0,int arg1,int arg2) { + script_4178(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/4178.cs2 b/dumps/scripts/4178.cs2 new file mode 100644 index 0000000..f630aad --- /dev/null +++ b/dumps/scripts/4178.cs2 @@ -0,0 +1,169 @@ +void script_4178(int arg0,int arg1,int arg2) { + if (((boolean)arg0)) { + switch (arg1) { + case 0: + if (((boolean)arg2)) { + globalint_1465 = getClientCycle(); + } else { + globalint_1465 = 0; + } + break; + case 1: + if (((boolean)arg2)) { + globalint_1466 = getClientCycle(); + } else { + globalint_1466 = 0; + } + break; + case 2: + if (((boolean)arg2)) { + globalint_1467 = getClientCycle(); + } else { + globalint_1467 = 0; + } + break; + case 3: + if (((boolean)arg2)) { + globalint_740 = getClientCycle(); + } else { + globalint_740 = 0; + } + break; + case 4: + if (((boolean)arg2)) { + globalint_745 = getClientCycle(); + } else { + globalint_745 = 0; + } + break; + case 5: + if (((boolean)arg2)) { + globalint_780 = getClientCycle(); + } else { + globalint_780 = 0; + } + break; + case 7: + if (((boolean)arg2)) { + globalint_781 = getClientCycle(); + } else { + globalint_781 = 0; + } + break; + case 9: + if (((boolean)arg2)) { + globalint_782 = getClientCycle(); + } else { + globalint_782 = 0; + } + break; + case 10: + if (((boolean)arg2)) { + globalint_789 = getClientCycle(); + } else { + globalint_789 = 0; + } + break; + case 12: + if (((boolean)arg2)) { + globalint_1409 = getClientCycle(); + } else { + globalint_1409 = 0; + } + break; + case 13: + if (((boolean)arg2)) { + globalint_1410 = getClientCycle(); + } else { + globalint_1410 = 0; + } + } + } else { + switch (arg1) { + case 0: + if (((boolean)arg2)) { + globalint_1453 = getClientCycle(); + } else { + globalint_1453 = 0; + } + break; + case 1: + if (((boolean)arg2)) { + globalint_1454 = getClientCycle(); + } else { + globalint_1454 = 0; + } + break; + case 4: + if (((boolean)arg2)) { + globalint_1455 = getClientCycle(); + } else { + globalint_1455 = 0; + } + break; + case 5: + if (((boolean)arg2)) { + globalint_1456 = getClientCycle(); + } else { + globalint_1456 = 0; + } + break; + case 6: + if (((boolean)arg2)) { + globalint_1457 = getClientCycle(); + } else { + globalint_1453 = 6; + } + break; + case 7: + if (((boolean)arg2)) { + globalint_1458 = getClientCycle(); + } else { + globalint_1453 = 7; + } + break; + case 8: + if (((boolean)arg2)) { + globalint_1459 = getClientCycle(); + } else { + globalint_1453 = 8; + } + break; + case 9: + if (((boolean)arg2)) { + globalint_1460 = getClientCycle(); + } else { + globalint_1453 = 9; + } + break; + case 10: + if (((boolean)arg2)) { + globalint_1461 = getClientCycle(); + } else { + globalint_1461 = 0; + } + break; + case 12: + if (((boolean)arg2)) { + globalint_1462 = getClientCycle(); + } else { + globalint_1462 = 0; + } + break; + case 13: + if (((boolean)arg2)) { + globalint_1463 = getClientCycle(); + } else { + globalint_1463 = 0; + } + break; + case 28: + if (((boolean)arg2)) { + globalint_1464 = getClientCycle(); + } else { + globalint_1464 = 0; + } + } + } + return; +} diff --git a/dumps/scripts/4179.cs2 b/dumps/scripts/4179.cs2 new file mode 100644 index 0000000..ffd222e --- /dev/null +++ b/dumps/scripts/4179.cs2 @@ -0,0 +1,121 @@ +void script_4179(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + string svar0; + ivar4 = script_4180(0, arg0, 0, "Boosted stats will be reset."); + if (bitconfig_642 > 0) { + ivar4 = script_4180(ivar4, arg0, 0, "Some worn items will be taken off."); + } + if (((boolean)bitconfig_4166)) { + ivar4 = script_4180(ivar4, arg0, 0, "Existing prayers will be stopped."); + } + if (ivar4 > getWidgetActualHeight(new WidgetPointer(arg0))) { + setWidgetScrollMax(0, ivar4, new WidgetPointer(arg0)); + script_31(arg1, arg0, 792, 789, 790, 791, 773, 788); + setWidgetIsHidden(false, new WidgetPointer(arg1)); + setWidgetPosition(0, 0, 0, 1, new WidgetPointer(arg0)); + } else { + setWidgetScrollMax(0, 0, new WidgetPointer(arg0)); + deleteAllExtraChilds(new WidgetPointer(arg1)); + setWidgetIsHidden(true, new WidgetPointer(arg1)); + setWidgetPosition(0, 0, 1, 1, new WidgetPointer(arg0)); + } + ivar5 = 0; + if (isMember() && ((((((((getItemAmtInContainer(93, 10148) > 0) || (getItemAmtInContainer(94, 10148) > 0)) || (getItemAmtInContainer(93, 10147) > 0)) || (getItemAmtInContainer(94, 10147) > 0)) || (getItemAmtInContainer(93, 10146) > 0)) || (getItemAmtInContainer(94, 10146) > 0)) || (getItemAmtInContainer(93, 10149) > 0)) || (getItemAmtInContainer(94, 10149) > 0))) { + ivar5 = 1; + } + ivar4 = 0; + if (((boolean)bitconfig_4159)) { + ivar4 = script_4180(ivar4, arg2, globalint_1453, "You cannot forfeit the duel."); + } + if (((boolean)bitconfig_4160)) { + ivar4 = script_4180(ivar4, arg2, globalint_1454, "You cannot move."); + } + if (((boolean)bitconfig_4275)) { + ivar4 = script_4180(ivar4, arg2, globalint_1464, "You can summon familiars."); + } + svar0 = "You cannot use Ranged attacks."; + if (((boolean)bitconfig_4161)) { + if (((boolean)ivar5)) { + svar0 = "You cannot use Ranged attacks " + "" + "or salamanders" + "" + "."; + } + ivar4 = script_4180(ivar4, arg2, globalint_1455, svar0); + } + svar0 = "You cannot use melee attacks."; + if (((boolean)bitconfig_4162)) { + if (((boolean)ivar5)) { + svar0 = "You cannot use melee attacks " + "" + "or salamanders" + "" + "."; + } + ivar4 = script_4180(ivar4, arg2, globalint_1456, svar0); + } + svar0 = "You cannot use Magic attacks."; + if (((boolean)bitconfig_4163)) { + if (((boolean)ivar5)) { + svar0 = "You cannot use Magic attacks " + "" + "or salamanders" + "" + "."; + } + ivar4 = script_4180(ivar4, arg2, globalint_1457, svar0); + } + if (((boolean)bitconfig_4169)) { + ivar4 = script_4180(ivar4, arg2, globalint_1463, "You cannot use special attacks."); + } + if (((boolean)bitconfig_4168)) { + ivar4 = script_4180(ivar4, arg2, globalint_1462, "You can only attack with 'fun' weapons."); + } + if (((boolean)bitconfig_4164)) { + ivar4 = script_4180(ivar4, arg2, globalint_1458, "You cannot use drinks."); + } + if (((boolean)bitconfig_4165)) { + ivar4 = script_4180(ivar4, arg2, globalint_1459, "You cannot use food."); + } + if (((boolean)bitconfig_4166)) { + ivar4 = script_4180(ivar4, arg2, globalint_1460, "You cannot use Prayer."); + } + if (((boolean)bitconfig_4167)) { + ivar4 = script_4180(ivar4, arg2, globalint_1461, "There will be obstacles in the arena."); + } + if (isBitFlagged(bitconfig_642, 0)) { + ivar4 = script_4180(ivar4, arg2, globalint_1465, "You cannot wear items on your head."); + } + if (isBitFlagged(bitconfig_642, 1)) { + ivar4 = script_4180(ivar4, arg2, globalint_1466, "You cannot wear items on your back, such as capes."); + } + if (isBitFlagged(bitconfig_642, 2)) { + ivar4 = script_4180(ivar4, arg2, globalint_1467, "You cannot wear items on your front, such as amulets."); + } + if (isBitFlagged(bitconfig_642, 3)) { + ivar4 = script_4180(ivar4, arg2, globalint_740, "You cannot wield items in your right hand."); + } + if (isBitFlagged(bitconfig_642, 4)) { + ivar4 = script_4180(ivar4, arg2, globalint_745, "You cannot wear items on your torso."); + } + if (isBitFlagged(bitconfig_642, 5)) { + ivar4 = script_4180(ivar4, arg2, globalint_780, "You cannot wield items in your left hand or use 2-handed weapons."); + } + if (isBitFlagged(bitconfig_642, 7)) { + ivar4 = script_4180(ivar4, arg2, globalint_781, "You cannot wear items on your legs."); + } + if (isBitFlagged(bitconfig_642, 9)) { + ivar4 = script_4180(ivar4, arg2, globalint_782, "You cannot wear items on your hands."); + } + if (isBitFlagged(bitconfig_642, 10)) { + ivar4 = script_4180(ivar4, arg2, globalint_789, "You cannot wear items on your feet."); + } + if (isBitFlagged(bitconfig_642, 12)) { + ivar4 = script_4180(ivar4, arg2, globalint_1409, "You cannot use your ring slot."); + } + if (isBitFlagged(bitconfig_642, 13)) { + ivar4 = script_4180(ivar4, arg2, globalint_1410, "You cannot use your quiver."); + } + if (ivar4 > getWidgetActualHeight(new WidgetPointer(arg2))) { + setWidgetScrollMax(0, ivar4, new WidgetPointer(arg2)); + script_31(arg3, arg2, 792, 789, 790, 791, 773, 788); + setWidgetIsHidden(false, new WidgetPointer(arg3)); + setWidgetPosition(0, 0, 0, 1, new WidgetPointer(arg2)); + } else { + setWidgetScrollMax(0, 0, new WidgetPointer(arg2)); + deleteAllExtraChilds(new WidgetPointer(arg3)); + setWidgetIsHidden(true, new WidgetPointer(arg3)); + setWidgetPosition(0, 0, 1, 1, new WidgetPointer(arg2)); + } + return; +} diff --git a/dumps/scripts/418.cs2 b/dumps/scripts/418.cs2 new file mode 100644 index 0000000..353019a --- /dev/null +++ b/dumps/scripts/418.cs2 @@ -0,0 +1,10 @@ +void script_418() { + if (((globalint_1354 == -1) || (globalint_1357 < 0)) || (globalint_1358 < 0)) { + return; + } + cameraMethod5511(globalint_1354); + globalint_1355 = cameraGetVrot(); + globalint_1356 = cameraGetHrot(); + setScriptCallOnGameloop(421, globalint_1357, globalint_1358, 0, "iii", new WidgetPointer(1013,0)); + return; +} diff --git a/dumps/scripts/4180.cs2 b/dumps/scripts/4180.cs2 new file mode 100644 index 0000000..8240f3d --- /dev/null +++ b/dumps/scripts/4180.cs2 @@ -0,0 +1,23 @@ +int script_4180(int arg0,int arg1,int arg2,string arg3) { + int ivar3; + int ivar4; + ivar3 = add(multiply(getLineCount(getWidgetActualWidth(new WidgetPointer(arg1)), 494, arg3), 10), 2); + ivar4 = subtract(getClientCycle(), arg2); + if ((arg2 > 0) && (ivar4 < 255)) { + createExtraChild(new WidgetPointer(arg1), 3, getExtraChildGap(new WidgetPointer(arg1))); + setWidgetSize(0, ivar3, 1, 0); + setWidgetPosition(0, arg0, 1, 0); + setWidgetFilled(1); + setWidgetRGB(new Color(255, 0, 0)); + cs2method2103(max(ivar4, 0)); + setScriptCallOnGameloop(4181, new WidgetPointer(-32768,3), -2147483643, "Ii"); + } + createExtraChild(new WidgetPointer(arg1), 4, getExtraChildGap(new WidgetPointer(arg1))); + setWidgetSize(0, ivar3, 1, 0); + setWidgetPosition(0, arg0, 1, 0); + setWidgetRGB(new Color(170, 170, 170)); + setWidgetFont(494); + setWidgetTextAlignment(1, 1, 0); + setWidgetText(arg3); + return add(add(arg0, ivar3), 2); +} diff --git a/dumps/scripts/4181.cs2 b/dumps/scripts/4181.cs2 new file mode 100644 index 0000000..bb4715d --- /dev/null +++ b/dumps/scripts/4181.cs2 @@ -0,0 +1,13 @@ +void script_4181(int arg0,int arg1) { + int ivar2; + ivar2 = 0; + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + ivar2 = add(cs2method1609(), 1); + if (ivar2 >= 255) { + deleteExtraChild(); + return; + } + cs2method2103(ivar2); + } + return; +} diff --git a/dumps/scripts/4182.cs2 b/dumps/scripts/4182.cs2 new file mode 100644 index 0000000..7190489 --- /dev/null +++ b/dumps/scripts/4182.cs2 @@ -0,0 +1,8 @@ +void script_4182() { + setWidgetText(new WidgetPointer(1072,53), intToStr(bitconfig_8857) + "/" + intToStr(4000)); + setWidgetText(new WidgetPointer(1072,57), intToStr(bitconfig_8859) + "/" + intToStr(4000)); + setWidgetText(new WidgetPointer(1072,61), intToStr(bitconfig_8862) + "/" + intToStr(4000)); + setWidgetText(new WidgetPointer(1072,65), intToStr(bitconfig_8863) + "/" + intToStr(4000)); + setWidgetText(new WidgetPointer(1072,49), intToStr(bitconfig_8865) + "/" + intToStr(8000)); + return; +} diff --git a/dumps/scripts/4183.cs2 b/dumps/scripts/4183.cs2 new file mode 100644 index 0000000..15ef09c --- /dev/null +++ b/dumps/scripts/4183.cs2 @@ -0,0 +1,82 @@ +void script_4183(int arg0) { + if (arg0 == 70254730) { + setWidgetIsHidden(false, new WidgetPointer(1072,135)); + setWidgetIsHidden(true, new WidgetPointer(1072,147)); + setWidgetIsHidden(true, new WidgetPointer(1072,159)); + setWidgetIsHidden(true, new WidgetPointer(1072,171)); + setWidgetModel(63848, new WidgetPointer(1072,48)); + setWidgetModel(63838, new WidgetPointer(1072,74)); + setWidgetModel(63824, new WidgetPointer(1072,80)); + setWidgetModel(63837, new WidgetPointer(1072,88)); + setWidgetModel(63823, new WidgetPointer(1072,93)); + setWidgetText(new WidgetPointer(1072,46), intToStr(1)); + setWidgetText(new WidgetPointer(1072,71), intToStr(1)); + setWidgetText(new WidgetPointer(1072,72), intToStr(2)); + setWidgetText(new WidgetPointer(1072,12), intToStr(1)); + setWidgetText(new WidgetPointer(1072,13), intToStr(4)); + setWidgetText(new WidgetPointer(1072,6), intToStr(1)); + setWidgetText(new WidgetPointer(1072,7), intToStr(6)); + setWidgetText(new WidgetPointer(1072,2), intToStr(1)); + setWidgetText(new WidgetPointer(1072,3), intToStr(8)); + } else if (arg0 == 70254742) { + setWidgetIsHidden(true, new WidgetPointer(1072,135)); + setWidgetIsHidden(false, new WidgetPointer(1072,147)); + setWidgetIsHidden(true, new WidgetPointer(1072,159)); + setWidgetIsHidden(true, new WidgetPointer(1072,171)); + setWidgetModel(63835, new WidgetPointer(1072,48)); + setWidgetModel(63825, new WidgetPointer(1072,74)); + setWidgetModel(63845, new WidgetPointer(1072,80)); + setWidgetModel(63828, new WidgetPointer(1072,88)); + setWidgetModel(63841, new WidgetPointer(1072,93)); + setWidgetText(new WidgetPointer(1072,46), intToStr(9)); + setWidgetText(new WidgetPointer(1072,71), intToStr(4)); + setWidgetText(new WidgetPointer(1072,72), intToStr(7)); + setWidgetText(new WidgetPointer(1072,12), intToStr(3)); + setWidgetText(new WidgetPointer(1072,13), intToStr(12)); + setWidgetText(new WidgetPointer(1072,6), intToStr(3)); + setWidgetText(new WidgetPointer(1072,7), intToStr(14)); + setWidgetText(new WidgetPointer(1072,2), intToStr(2)); + setWidgetText(new WidgetPointer(1072,3), intToStr(16)); + } else if (arg0 == 70254754) { + setWidgetIsHidden(true, new WidgetPointer(1072,135)); + setWidgetIsHidden(true, new WidgetPointer(1072,147)); + setWidgetIsHidden(false, new WidgetPointer(1072,159)); + setWidgetIsHidden(true, new WidgetPointer(1072,171)); + setWidgetModel(63827, new WidgetPointer(1072,48)); + setWidgetModel(63833, new WidgetPointer(1072,74)); + setWidgetModel(63831, new WidgetPointer(1072,80)); + setWidgetModel(63842, new WidgetPointer(1072,88)); + setWidgetModel(63856, new WidgetPointer(1072,93)); + setWidgetText(new WidgetPointer(1072,46), intToStr(12)); + setWidgetText(new WidgetPointer(1072,71), intToStr(9)); + setWidgetText(new WidgetPointer(1072,72), intToStr(17)); + setWidgetText(new WidgetPointer(1072,12), intToStr(6)); + setWidgetText(new WidgetPointer(1072,13), intToStr(24)); + setWidgetText(new WidgetPointer(1072,6), intToStr(4)); + setWidgetText(new WidgetPointer(1072,7), intToStr(22)); + setWidgetText(new WidgetPointer(1072,2), intToStr(4)); + setWidgetText(new WidgetPointer(1072,3), intToStr(30)); + } else { + if (arg0 == 70254766) { + setWidgetIsHidden(true, new WidgetPointer(1072,135)); + setWidgetIsHidden(true, new WidgetPointer(1072,147)); + setWidgetIsHidden(true, new WidgetPointer(1072,159)); + setWidgetIsHidden(false, new WidgetPointer(1072,171)); + setWidgetModel(63836, new WidgetPointer(1072,48)); + setWidgetModel(63851, new WidgetPointer(1072,74)); + setWidgetModel(63855, new WidgetPointer(1072,80)); + setWidgetModel(63832, new WidgetPointer(1072,88)); + setWidgetModel(63834, new WidgetPointer(1072,93)); + setWidgetText(new WidgetPointer(1072,46), intToStr(75)); + setWidgetText(new WidgetPointer(1072,71), intToStr(40)); + setWidgetText(new WidgetPointer(1072,72), intToStr(80)); + setWidgetText(new WidgetPointer(1072,12), intToStr(30)); + setWidgetText(new WidgetPointer(1072,13), intToStr(120)); + setWidgetText(new WidgetPointer(1072,6), intToStr(25)); + setWidgetText(new WidgetPointer(1072,7), intToStr(150)); + setWidgetText(new WidgetPointer(1072,2), intToStr(18)); + setWidgetText(new WidgetPointer(1072,3), intToStr(144)); + } + } + return; +} diff --git a/dumps/scripts/4184.cs2 b/dumps/scripts/4184.cs2 new file mode 100644 index 0000000..1981961 --- /dev/null +++ b/dumps/scripts/4184.cs2 @@ -0,0 +1,10 @@ +void script_4184(int arg0,int arg1) { + if (arg0 != 1) { + return; + } + bitconfig_8877 = max(min(add(bitconfig_8877, arg1), 28), 1); + setWidgetText(new WidgetPointer(1072,33), intToStr(bitconfig_8877)); + setScriptCallOnGameloop(4187, add(getClientCycle(), 15), "i", new WidgetPointer(1072,83)); + setWidgetIsHidden(false, new WidgetPointer(1072,83)); + return; +} diff --git a/dumps/scripts/4185.cs2 b/dumps/scripts/4185.cs2 new file mode 100644 index 0000000..08ed828 --- /dev/null +++ b/dumps/scripts/4185.cs2 @@ -0,0 +1,10 @@ +void script_4185(int arg0) { + if (arg0 == 70254623) { + setWidgetSprite(3865, new WidgetPointer(1072,31)); + } else { + if (arg0 == 70254624) { + setWidgetSprite(3866, new WidgetPointer(1072,32)); + } + } + return; +} diff --git a/dumps/scripts/4186.cs2 b/dumps/scripts/4186.cs2 new file mode 100644 index 0000000..0fdbac3 --- /dev/null +++ b/dumps/scripts/4186.cs2 @@ -0,0 +1,10 @@ +void script_4186(int arg0) { + if (arg0 == 70254623) { + setWidgetSprite(3863, new WidgetPointer(1072,31)); + } else { + if (arg0 == 70254624) { + setWidgetSprite(3864, new WidgetPointer(1072,32)); + } + } + return; +} diff --git a/dumps/scripts/4187.cs2 b/dumps/scripts/4187.cs2 new file mode 100644 index 0000000..53c2c92 --- /dev/null +++ b/dumps/scripts/4187.cs2 @@ -0,0 +1,8 @@ +void script_4187(int arg0) { + if (getClientCycle() < arg0) { + return; + } + setScriptCallOnGameloop(-1, "", new WidgetPointer(1072,83)); + setWidgetIsHidden(true, new WidgetPointer(1072,83)); + return; +} diff --git a/dumps/scripts/4188.cs2 b/dumps/scripts/4188.cs2 new file mode 100644 index 0000000..a243232 --- /dev/null +++ b/dumps/scripts/4188.cs2 @@ -0,0 +1,15 @@ +void script_4188(int arg0) { + if (arg0 == 70385726) { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(1074,57)); + } + if (arg0 == 70385727) { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(1074,58)); + } + if (arg0 == 70385728) { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(1074,59)); + } + if (arg0 == 70385729) { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(1074,60)); + } + return; +} diff --git a/dumps/scripts/4189.cs2 b/dumps/scripts/4189.cs2 new file mode 100644 index 0000000..bbddcc2 --- /dev/null +++ b/dumps/scripts/4189.cs2 @@ -0,0 +1,15 @@ +void script_4189(int arg0) { + if (arg0 == 70385726) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(1074,57)); + } + if (arg0 == 70385727) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(1074,58)); + } + if (arg0 == 70385728) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(1074,59)); + } + if (arg0 == 70385729) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(1074,60)); + } + return; +} diff --git a/dumps/scripts/419.cs2 b/dumps/scripts/419.cs2 new file mode 100644 index 0000000..51a9dea --- /dev/null +++ b/dumps/scripts/419.cs2 @@ -0,0 +1,4 @@ +void script_419() { + script_304(49466635); + return; +} diff --git a/dumps/scripts/4190.cs2 b/dumps/scripts/4190.cs2 new file mode 100644 index 0000000..c06b19d --- /dev/null +++ b/dumps/scripts/4190.cs2 @@ -0,0 +1,24 @@ +void script_4190() { + if (setWidgetRegister(new WidgetPointer(1074,94))) { + setWidgetVFlip(1); + } + if (setWidgetRegister(new WidgetPointer(1074,95))) { + setWidgetVFlip(1); + } + if (setWidgetRegister(new WidgetPointer(1074,96))) { + setWidgetVFlip(1); + } + if (setWidgetRegister(new WidgetPointer(1074,97))) { + setWidgetVFlip(1); + } + if (setWidgetRegister(new WidgetPointer(1074,98))) { + setWidgetVFlip(1); + } + if (setWidgetRegister(new WidgetPointer(1074,99))) { + setWidgetVFlip(1); + } + if (setWidgetRegister(new WidgetPointer(1074,100))) { + setWidgetVFlip(1); + } + return; +} diff --git a/dumps/scripts/4191.cs2 b/dumps/scripts/4191.cs2 new file mode 100644 index 0000000..4a73d9c --- /dev/null +++ b/dumps/scripts/4191.cs2 @@ -0,0 +1,45 @@ +void script_4191() { + if (setWidgetRegister(new WidgetPointer(1070,95))) { + setWidgetVFlip(1); + } + if (setWidgetRegister(new WidgetPointer(1070,96))) { + setWidgetVFlip(1); + } + if (setWidgetRegister(new WidgetPointer(1070,97))) { + setWidgetVFlip(1); + } + if (setWidgetRegister(new WidgetPointer(1070,98))) { + setWidgetVFlip(1); + } + if (setWidgetRegister(new WidgetPointer(1070,99))) { + setWidgetVFlip(1); + } + if (setWidgetRegister(new WidgetPointer(1070,100))) { + setWidgetVFlip(1); + } + if (setWidgetRegister(new WidgetPointer(1070,101))) { + setWidgetVFlip(1); + } + if (setWidgetRegister(new WidgetPointer(1070,81))) { + setWidgetVFlip(1); + } + if (setWidgetRegister(new WidgetPointer(1070,82))) { + setWidgetVFlip(1); + } + if (setWidgetRegister(new WidgetPointer(1070,83))) { + setWidgetVFlip(1); + } + if (setWidgetRegister(new WidgetPointer(1070,84))) { + setWidgetVFlip(1); + } + if (setWidgetRegister(new WidgetPointer(1070,85))) { + setWidgetVFlip(1); + } + if (setWidgetRegister(new WidgetPointer(1070,86))) { + setWidgetVFlip(1); + } + if (setWidgetRegister(new WidgetPointer(1070,87))) { + setWidgetVFlip(1); + } + return; +} diff --git a/dumps/scripts/4192.cs2 b/dumps/scripts/4192.cs2 new file mode 100644 index 0000000..639d287 --- /dev/null +++ b/dumps/scripts/4192.cs2 @@ -0,0 +1,24 @@ +void script_4192() { + if (setWidgetRegister(new WidgetPointer(1074,80))) { + setWidgetVFlip(1); + } + if (setWidgetRegister(new WidgetPointer(1074,81))) { + setWidgetVFlip(1); + } + if (setWidgetRegister(new WidgetPointer(1074,82))) { + setWidgetVFlip(1); + } + if (setWidgetRegister(new WidgetPointer(1074,83))) { + setWidgetVFlip(1); + } + if (setWidgetRegister(new WidgetPointer(1074,84))) { + setWidgetVFlip(1); + } + if (setWidgetRegister(new WidgetPointer(1074,85))) { + setWidgetVFlip(1); + } + if (setWidgetRegister(new WidgetPointer(1074,86))) { + setWidgetVFlip(1); + } + return; +} diff --git a/dumps/scripts/4193.cs2 b/dumps/scripts/4193.cs2 new file mode 100644 index 0000000..77815f0 --- /dev/null +++ b/dumps/scripts/4193.cs2 @@ -0,0 +1,68 @@ +void script_4193(int arg0) { + if (arg0 == 70385736) { + if (((boolean)bitconfig_8911)) { + setWidgetSprite(4701, new WidgetPointer(1074,34)); + } + } else if (arg0 == 70385765) { + if (((boolean)bitconfig_8912)) { + setWidgetSprite(4701, new WidgetPointer(1074,35)); + } + } else if (arg0 == 70385766) { + if (((boolean)bitconfig_8913)) { + setWidgetSprite(4701, new WidgetPointer(1074,36)); + } + } else if (arg0 == 70385767) { + if (((boolean)bitconfig_8914)) { + setWidgetSprite(4701, new WidgetPointer(1074,37)); + } + } else if (arg0 == 70385768) { + if (((boolean)bitconfig_8915)) { + setWidgetSprite(4701, new WidgetPointer(1074,38)); + } + } else if (arg0 == 70385769) { + if (((boolean)bitconfig_8916)) { + setWidgetSprite(4701, new WidgetPointer(1074,39)); + } + } else if (arg0 == 70385770) { + if (((boolean)bitconfig_8917)) { + setWidgetSprite(4701, new WidgetPointer(1074,40)); + } + } else if (arg0 == 70385771) { + if (((boolean)bitconfig_8918)) { + setWidgetSprite(4701, new WidgetPointer(1074,41)); + } + } else if (arg0 == 70385772) { + if (((boolean)bitconfig_8919)) { + setWidgetSprite(4701, new WidgetPointer(1074,42)); + } + } else if (arg0 == 70385773) { + if (((boolean)bitconfig_8920)) { + setWidgetSprite(4701, new WidgetPointer(1074,43)); + } + } else if (arg0 == 70385774) { + if (((boolean)bitconfig_8921)) { + setWidgetSprite(4701, new WidgetPointer(1074,44)); + } + } else if (arg0 == 70385775) { + if (((boolean)bitconfig_8922)) { + setWidgetSprite(4701, new WidgetPointer(1074,45)); + } + } else if (arg0 == 70385776) { + if (((boolean)bitconfig_8923)) { + setWidgetSprite(4701, new WidgetPointer(1074,46)); + } + } else if (arg0 == 70385777) { + if (((boolean)bitconfig_8924)) { + setWidgetSprite(4701, new WidgetPointer(1074,47)); + } + } else if (arg0 == 70385778) { + if (((boolean)bitconfig_8925)) { + setWidgetSprite(4701, new WidgetPointer(1074,48)); + } + } else { + if ((arg0 == 70385779) && ((boolean)bitconfig_8926)) { + setWidgetSprite(4701, new WidgetPointer(1074,49)); + } + } + return; +} diff --git a/dumps/scripts/4194.cs2 b/dumps/scripts/4194.cs2 new file mode 100644 index 0000000..8a784c8 --- /dev/null +++ b/dumps/scripts/4194.cs2 @@ -0,0 +1,68 @@ +void script_4194(int arg0) { + if (arg0 == 70385736) { + if (((boolean)bitconfig_8911)) { + setWidgetSprite(4700, new WidgetPointer(1074,34)); + } + } else if (arg0 == 70385765) { + if (((boolean)bitconfig_8912)) { + setWidgetSprite(4700, new WidgetPointer(1074,35)); + } + } else if (arg0 == 70385766) { + if (((boolean)bitconfig_8913)) { + setWidgetSprite(4700, new WidgetPointer(1074,36)); + } + } else if (arg0 == 70385767) { + if (((boolean)bitconfig_8914)) { + setWidgetSprite(4700, new WidgetPointer(1074,37)); + } + } else if (arg0 == 70385768) { + if (((boolean)bitconfig_8915)) { + setWidgetSprite(4700, new WidgetPointer(1074,38)); + } + } else if (arg0 == 70385769) { + if (((boolean)bitconfig_8916)) { + setWidgetSprite(4700, new WidgetPointer(1074,39)); + } + } else if (arg0 == 70385770) { + if (((boolean)bitconfig_8917)) { + setWidgetSprite(4700, new WidgetPointer(1074,40)); + } + } else if (arg0 == 70385771) { + if (((boolean)bitconfig_8918)) { + setWidgetSprite(4700, new WidgetPointer(1074,41)); + } + } else if (arg0 == 70385772) { + if (((boolean)bitconfig_8919)) { + setWidgetSprite(4700, new WidgetPointer(1074,42)); + } + } else if (arg0 == 70385773) { + if (((boolean)bitconfig_8920)) { + setWidgetSprite(4700, new WidgetPointer(1074,43)); + } + } else if (arg0 == 70385774) { + if (((boolean)bitconfig_8921)) { + setWidgetSprite(4700, new WidgetPointer(1074,44)); + } + } else if (arg0 == 70385775) { + if (((boolean)bitconfig_8922)) { + setWidgetSprite(4700, new WidgetPointer(1074,45)); + } + } else if (arg0 == 70385776) { + if (((boolean)bitconfig_8923)) { + setWidgetSprite(4700, new WidgetPointer(1074,46)); + } + } else if (arg0 == 70385777) { + if (((boolean)bitconfig_8924)) { + setWidgetSprite(4700, new WidgetPointer(1074,47)); + } + } else if (arg0 == 70385778) { + if (((boolean)bitconfig_8925)) { + setWidgetSprite(4700, new WidgetPointer(1074,48)); + } + } else { + if ((arg0 == 70385779) && ((boolean)bitconfig_8926)) { + setWidgetSprite(4700, new WidgetPointer(1074,49)); + } + } + return; +} diff --git a/dumps/scripts/4195.cs2 b/dumps/scripts/4195.cs2 new file mode 100644 index 0000000..2c1e5d4 --- /dev/null +++ b/dumps/scripts/4195.cs2 @@ -0,0 +1,47 @@ +void script_4195(int arg0) { + if ((arg0 == 58392625) || (arg0 == 58392626)) { + if (setWidgetRegister(new WidgetPointer(891,61))) { + setWidgetHidden(0); + } + if (setWidgetRegister(new WidgetPointer(891,49))) { + setWidgetSprite(5414); + } + if (setWidgetRegister(new WidgetPointer(891,50))) { + setWidgetSprite(5414); + } + } + if ((arg0 == 58392627) || (arg0 == 58392629)) { + if (setWidgetRegister(new WidgetPointer(891,62))) { + setWidgetHidden(0); + } + if (setWidgetRegister(new WidgetPointer(891,51))) { + setWidgetSprite(5414); + } + if (setWidgetRegister(new WidgetPointer(891,53))) { + setWidgetSprite(5414); + } + } + if (arg0 == 58392628) { + if (setWidgetRegister(new WidgetPointer(891,63))) { + setWidgetHidden(0); + } + if (setWidgetRegister(new WidgetPointer(891,52))) { + setWidgetSprite(5414); + } + if (setWidgetRegister(new WidgetPointer(891,53))) { + setWidgetSprite(5414); + } + } + if ((arg0 == 58392630) || (arg0 == 58392631)) { + if (setWidgetRegister(new WidgetPointer(891,64))) { + setWidgetHidden(0); + } + if (setWidgetRegister(new WidgetPointer(891,54))) { + setWidgetSprite(5414); + } + if (setWidgetRegister(new WidgetPointer(891,55))) { + setWidgetSprite(5414); + } + } + return; +} diff --git a/dumps/scripts/4196.cs2 b/dumps/scripts/4196.cs2 new file mode 100644 index 0000000..8eeeaf6 --- /dev/null +++ b/dumps/scripts/4196.cs2 @@ -0,0 +1,47 @@ +void script_4196(int arg0) { + if ((arg0 == 58392625) || (arg0 == 58392626)) { + if (setWidgetRegister(new WidgetPointer(891,61))) { + setWidgetHidden(1); + } + if (setWidgetRegister(new WidgetPointer(891,49))) { + setWidgetSprite(5413); + } + if (setWidgetRegister(new WidgetPointer(891,50))) { + setWidgetSprite(5413); + } + } + if ((arg0 == 58392627) || (arg0 == 58392629)) { + if (setWidgetRegister(new WidgetPointer(891,62))) { + setWidgetHidden(1); + } + if (setWidgetRegister(new WidgetPointer(891,51))) { + setWidgetSprite(5413); + } + if (setWidgetRegister(new WidgetPointer(891,53))) { + setWidgetSprite(5413); + } + } + if (arg0 == 58392628) { + if (setWidgetRegister(new WidgetPointer(891,63))) { + setWidgetHidden(1); + } + if (setWidgetRegister(new WidgetPointer(891,52))) { + setWidgetSprite(5413); + } + if (setWidgetRegister(new WidgetPointer(891,53))) { + setWidgetSprite(5413); + } + } + if ((arg0 == 58392630) || (arg0 == 58392631)) { + if (setWidgetRegister(new WidgetPointer(891,64))) { + setWidgetHidden(1); + } + if (setWidgetRegister(new WidgetPointer(891,54))) { + setWidgetSprite(5413); + } + if (setWidgetRegister(new WidgetPointer(891,55))) { + setWidgetSprite(5413); + } + } + return; +} diff --git a/dumps/scripts/4197.cs2 b/dumps/scripts/4197.cs2 new file mode 100644 index 0000000..1ba61ad --- /dev/null +++ b/dumps/scripts/4197.cs2 @@ -0,0 +1,9 @@ +void script_4197(int arg0) { + setWidgetIsHidden(true, new WidgetPointer(891,76)); + setWidgetIsHidden(false, new WidgetPointer(891,65)); + setWidgetSprite(5412, new WidgetPointer(arg0)); + setWidgetText(new WidgetPointer(891,75), "You are here."); + setWidgetText(new WidgetPointer(891,77), ""); + setWidgetText(new WidgetPointer(891,78), ""); + return; +} diff --git a/dumps/scripts/4198.cs2 b/dumps/scripts/4198.cs2 new file mode 100644 index 0000000..3d51d39 --- /dev/null +++ b/dumps/scripts/4198.cs2 @@ -0,0 +1,5 @@ +void script_4198(int arg0) { + setWidgetIsHidden(true, new WidgetPointer(891,65)); + setWidgetSprite(5411, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/4199.cs2 b/dumps/scripts/4199.cs2 new file mode 100644 index 0000000..29d874e --- /dev/null +++ b/dumps/scripts/4199.cs2 @@ -0,0 +1,31 @@ +void script_4199(int arg0) { + setWidgetSprite(5416, new WidgetPointer(arg0)); + setWidgetIsHidden(false, new WidgetPointer(891,76)); + setWidgetIsHidden(false, new WidgetPointer(891,65)); + if (arg0 == 58392632) { + setWidgetText(new WidgetPointer(891,75), "Cannon Room"); + setWidgetText(new WidgetPointer(891,77), "62+"); + setWidgetText(new WidgetPointer(891,78), "(Members only) Fix up broken cannons. This offers fast XP, for medium resource costs."); + } + if (arg0 == 58392633) { + setWidgetText(new WidgetPointer(891,75), "Burial Armour Room"); + setWidgetText(new WidgetPointer(891,77), "30-70"); + setWidgetText(new WidgetPointer(891,78), "Forge burial armour in line with the taskmaster's orders. Different XP rates at a range of resource costs."); + } + if (arg0 == 58392634) { + setWidgetText(new WidgetPointer(891,75), "Ceremonial Sword Room"); + setWidgetText(new WidgetPointer(891,77), "70+"); + setWidgetText(new WidgetPointer(891,78), "(Members Only) Smith beautiful ceremonial swords. High XP rate, for reasonably high resource costs."); + } + if (arg0 == 58392635) { + setWidgetText(new WidgetPointer(891,75), "Track Room"); + setWidgetText(new WidgetPointer(891,77), "1-30"); + setWidgetText(new WidgetPointer(891,78), "Build up sections of mine cart tracks. Low XP rate, no resource costs."); + } + if (arg0 == 58392636) { + setWidgetText(new WidgetPointer(891,75), "Reward Shop"); + setWidgetText(new WidgetPointer(891,77), "--"); + setWidgetText(new WidgetPointer(891,78), "Purchase unique rewards using respect earned in the workshop."); + } + return; +} diff --git a/dumps/scripts/42.cs2 b/dumps/scripts/42.cs2 new file mode 100644 index 0000000..8fa487b --- /dev/null +++ b/dumps/scripts/42.cs2 @@ -0,0 +1,6 @@ +int script_42(int arg0) { + if (((boolean)arg0)) { + return 1; + } + return 0; +} diff --git a/dumps/scripts/420.cs2 b/dumps/scripts/420.cs2 new file mode 100644 index 0000000..b982f56 --- /dev/null +++ b/dumps/scripts/420.cs2 @@ -0,0 +1,5 @@ +void script_420() { + cameraMethod5511(globalint_1353); + setScriptCallOnGameloop(421, globalint_1355, globalint_1356, 0, "iii", new WidgetPointer(1013,0)); + return; +} diff --git a/dumps/scripts/4200.cs2 b/dumps/scripts/4200.cs2 new file mode 100644 index 0000000..d20928f --- /dev/null +++ b/dumps/scripts/4200.cs2 @@ -0,0 +1,6 @@ +void script_4200(int arg0) { + setWidgetSprite(5415, new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(891,65)); + setWidgetIsHidden(true, new WidgetPointer(891,76)); + return; +} diff --git a/dumps/scripts/4201.cs2 b/dumps/scripts/4201.cs2 new file mode 100644 index 0000000..57bc134 --- /dev/null +++ b/dumps/scripts/4201.cs2 @@ -0,0 +1,4 @@ +void script_4201(int arg0,int arg1) { + script_4510(arg0, arg1); + return; +} diff --git a/dumps/scripts/4202.cs2 b/dumps/scripts/4202.cs2 new file mode 100644 index 0000000..677cf08 --- /dev/null +++ b/dumps/scripts/4202.cs2 @@ -0,0 +1,73 @@ +void script_4202(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + if ((arg0 == -1) || (arg1 == -1)) { + return; + } + ivar2 = getOtherCommonData(arg1, 1346); + ivar3 = getOtherCommonData(arg1, 1349); + ivar4 = getOtherCommonData(arg1, 1347); + ivar5 = getOtherCommonData(arg1, 1350); + ivar6 = getOtherCommonData(arg1, 1352); + ivar7 = getOtherCommonData(arg1, 1353); + ivar8 = getOtherCommonData(arg1, 1351); + ivar9 = getOtherCommonData(arg1, 1358); + ivar10 = getOtherCommonData(arg1, 1359); + deleteAllExtraChilds(new WidgetPointer(arg0)); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 1, 1); + setWidgetSize(24, 22, 1, 1); + setWidgetSprite(ivar8); + cs2method2103(ivar9); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 1, 0); + setWidgetSize(24, 12, 1, 0); + setWidgetSprite(ivar4); + cs2method2103(ivar9); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 1, 2); + setWidgetSize(24, 12, 1, 0); + setWidgetSprite(ivar6); + cs2method2103(ivar9); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 0, 1); + setWidgetSize(12, 24, 0, 1); + setWidgetSprite(ivar7); + setWidgetHFlip(1); + cs2method2103(ivar9); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 2, 1); + setWidgetSize(12, 24, 0, 1); + setWidgetSprite(ivar7); + cs2method2103(ivar9); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(12, 12, 0, 0); + setWidgetSprite(ivar3); + setWidgetHFlip(1); + cs2method2103(ivar9); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 0, 2); + setWidgetSize(12, 12, 0, 0); + setWidgetSprite(ivar5); + setWidgetHFlip(1); + cs2method2103(ivar9); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 2, 0); + setWidgetSize(12, 12, 0, 0); + setWidgetSprite(ivar3); + cs2method2103(ivar9); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 2, 2); + setWidgetSize(12, 12, 0, 0); + setWidgetSprite(ivar5); + cs2method2103(ivar9); + return; +} diff --git a/dumps/scripts/4203.cs2 b/dumps/scripts/4203.cs2 new file mode 100644 index 0000000..e81ff8e --- /dev/null +++ b/dumps/scripts/4203.cs2 @@ -0,0 +1,34 @@ +void script_4203(int arg0,int arg1) { + int ivar2; + if ((arg0 == -1) || (arg1 == -1)) { + return; + } + ivar2 = getOtherCommonData(arg1, 1346); + if (ivar2 == 2) { + setScriptCallOnMouseEntered(4159, new WidgetPointer(-32768,3), 0, 0, "Iii", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(4159, new WidgetPointer(-32768,3), 1, 0, "Iii", new WidgetPointer(arg0)); + } else { + if (ivar2 == 3) { + setScriptCallOnMousePressed(4162, new WidgetPointer(-32768,3), "I", new WidgetPointer(arg0)); + setScriptCallOnMouseReleased(4163, new WidgetPointer(-32768,3), "I", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(4163, new WidgetPointer(-32768,3), "I", new WidgetPointer(arg0)); + } + } + if (ivar2 == 5) { + deleteAllExtraChilds(new WidgetPointer(arg0)); + createExtraChild(new WidgetPointer(arg0), 3, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(0, 0, 1, 1); + setWidgetPosition(0, 0, 0, 0); + setWidgetRGB(new Color(0, 0, 0)); + cs2method2103(128); + setWidgetFilled(1); + setWidgetIsHidden(true, new WidgetPointer(arg0)); + cs2method2005(1, new WidgetPointer(arg0)); + } else { + script_4204(arg0, arg1); + } + if (ivar2 == 4) { + script_4161(arg0, 0); + } + return; +} diff --git a/dumps/scripts/4204.cs2 b/dumps/scripts/4204.cs2 new file mode 100644 index 0000000..070f1e8 --- /dev/null +++ b/dumps/scripts/4204.cs2 @@ -0,0 +1,30 @@ +void script_4204(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + if ((arg0 == -1) || (arg1 == -1)) { + return; + } + ivar2 = getOtherCommonData(arg1, 1348); + ivar3 = getOtherCommonData(arg1, 1355); + ivar4 = getOtherCommonData(arg1, 1356); + ivar5 = getOtherCommonData(arg1, 1358); + deleteAllExtraChilds(new WidgetPointer(arg0)); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 0, 1); + setWidgetSize(20, 20, 0, 0); + setWidgetSprite(ivar2); + cs2method2103(ivar5); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 1, 1); + setWidgetSize(40, 20, 1, 0); + setWidgetSprite(ivar3); + cs2method2103(ivar5); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 2, 1); + setWidgetSize(20, 20, 0, 0); + setWidgetSprite(ivar4); + cs2method2103(ivar5); + return; +} diff --git a/dumps/scripts/4205.cs2 b/dumps/scripts/4205.cs2 new file mode 100644 index 0000000..b10b598 --- /dev/null +++ b/dumps/scripts/4205.cs2 @@ -0,0 +1,4 @@ +void script_4205(int arg0,int arg1) { + script_4513(arg0, arg1); + return; +} diff --git a/dumps/scripts/4206.cs2 b/dumps/scripts/4206.cs2 new file mode 100644 index 0000000..ce45272 --- /dev/null +++ b/dumps/scripts/4206.cs2 @@ -0,0 +1,95 @@ +void script_4206(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + if ((arg0 == -1) || (arg1 == -1)) { + return; + } + ivar2 = getOtherCommonData(arg1, 1347); + ivar3 = getOtherCommonData(arg1, 1349); + ivar4 = getOtherCommonData(arg1, 1352); + ivar5 = getOtherCommonData(arg1, 1350); + ivar6 = getOtherCommonData(arg1, 1353); + ivar7 = getOtherCommonData(arg1, 1354); + ivar8 = getOtherCommonData(arg1, 1351); + ivar9 = getOtherCommonData(arg1, 1357); + ivar10 = getOtherCommonData(arg1, 1358); + deleteAllExtraChilds(new WidgetPointer(arg0)); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 1, 0); + setWidgetSize(14, 16384, 1, 2); + setWidgetSprite(ivar8); + cs2method1107(1); + cs2method2103(ivar10); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 1, 2); + setWidgetSize(14, 10000, 1, 2); + setWidgetSprite(ivar9); + cs2method1107(1); + cs2method2103(ivar10); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(7, 16384, 0, 2); + setWidgetSprite(ivar6); + cs2method2103(ivar10); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 2, 0); + setWidgetSize(7, 16384, 0, 2); + setWidgetSprite(ivar6); + setWidgetHFlip(1); + cs2method2103(ivar10); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(7, 7, 0, 0); + setWidgetSprite(ivar3); + cs2method2103(ivar10); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 1, 0); + setWidgetSize(14, 7, 1, 0); + setWidgetSprite(ivar2); + cs2method1107(1); + cs2method2103(ivar10); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 2, 0); + setWidgetSize(7, 7, 0, 0); + setWidgetSprite(ivar3); + cs2method2103(ivar10); + setWidgetHFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 0, 2); + setWidgetSize(7, 10000, 0, 2); + setWidgetSprite(ivar7); + cs2method1107(1); + cs2method2103(ivar10); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 2, 2); + setWidgetSize(7, 10000, 0, 2); + setWidgetSprite(ivar7); + cs2method1107(1); + setWidgetHFlip(1); + cs2method2103(ivar10); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 0, 2); + setWidgetSize(7, 7, 0, 0); + setWidgetSprite(ivar5); + cs2method2103(ivar10); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 1, 2); + setWidgetSize(14, 7, 1, 0); + setWidgetSprite(ivar4); + cs2method1107(1); + cs2method2103(ivar10); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 2, 2); + setWidgetSize(7, 7, 0, 0); + setWidgetSprite(ivar5); + cs2method2103(ivar10); + setWidgetHFlip(1); + return; +} diff --git a/dumps/scripts/4207.cs2 b/dumps/scripts/4207.cs2 new file mode 100644 index 0000000..56bc9e1 --- /dev/null +++ b/dumps/scripts/4207.cs2 @@ -0,0 +1,4 @@ +void script_4207(int arg0,int arg1) { + script_4208(arg0, arg1); + return; +} diff --git a/dumps/scripts/4208.cs2 b/dumps/scripts/4208.cs2 new file mode 100644 index 0000000..91b6f0f --- /dev/null +++ b/dumps/scripts/4208.cs2 @@ -0,0 +1,8 @@ +void script_4208(int arg0,int arg1) { + if (((boolean)arg1)) { + cs2method2103(0, new WidgetPointer(arg0)); + } else { + cs2method2103(255, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/4209.cs2 b/dumps/scripts/4209.cs2 new file mode 100644 index 0000000..9fafbbd --- /dev/null +++ b/dumps/scripts/4209.cs2 @@ -0,0 +1,4 @@ +void script_4209(int arg0,int arg1) { + script_5365(arg0, arg1); + return; +} diff --git a/dumps/scripts/421.cs2 b/dumps/scripts/421.cs2 new file mode 100644 index 0000000..b98af2c --- /dev/null +++ b/dumps/scripts/421.cs2 @@ -0,0 +1,101 @@ +void script_421(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int stack_dump0; + int stack_dump1; + cs2func_script_422_struct(2,0,0) structdump_2; + cs2func_script_422_struct(2,0,0) structdump_3; + cs2func_script_422_struct(2,0,0) structdump_4; + cs2func_script_422_struct(2,0,0) structdump_5; + ivar3 = 0; + ivar4 = 0; + ivar5 = 5; + ivar6 = 5; + ivar7 = 0; + ivar8 = 0; + ivar9 = 0; + ivar10 = 0; + if (cameraGetVrot() < arg0) { + ivar9 = subtract(arg0, cameraGetVrot()); + } else { + if (cameraGetVrot() > arg0) { + ivar9 = subtract(cameraGetVrot(), arg0); + } + } + if (cameraGetHrot() < arg1) { + ivar8 = subtract(arg1, cameraGetHrot()); + ivar7 = add(subtract(2047, arg1), cameraGetHrot()); + if (ivar7 > ivar8) { + ivar10 = ivar8; + stack_dump0 = ivar9; + stack_dump1 = ivar10; + structdump_2 = script_422(stack_dump0, stack_dump1); + ivar6 = structdump_2.intpart_1; + ivar5 = structdump_2.intpart_0; + cameraMethod5504(cameraGetVrot(), min(add(cameraGetHrot(), ivar6), arg1)); + } else { + ivar10 = ivar7; + stack_dump0 = ivar9; + stack_dump1 = ivar10; + structdump_3 = script_422(stack_dump0, stack_dump1); + ivar6 = structdump_3.intpart_1; + ivar5 = structdump_3.intpart_0; + if (((boolean)arg2)) { + cameraMethod5504(cameraGetVrot(), max(subtract(cameraGetHrot(), ivar6), 0)); + } else { + cameraMethod5504(cameraGetVrot(), max(subtract(cameraGetHrot(), ivar6), arg1)); + } + if (((boolean)cameraGetHrot()) && ((boolean)arg2)) { + cameraMethod5504(cameraGetVrot(), 2047); + setScriptCallOnGameloop(421, arg0, arg1, 1, "iii", new WidgetPointer(1013,0)); + } + } + } else if (cameraGetHrot() > arg1) { + ivar8 = add(subtract(2047, cameraGetHrot()), arg1); + ivar7 = subtract(cameraGetHrot(), arg1); + if (ivar7 > ivar8) { + ivar10 = ivar8; + stack_dump0 = ivar9; + stack_dump1 = ivar10; + structdump_4 = script_422(stack_dump0, stack_dump1); + ivar6 = structdump_4.intpart_1; + ivar5 = structdump_4.intpart_0; + if (((boolean)arg2)) { + cameraMethod5504(cameraGetVrot(), min(add(cameraGetHrot(), ivar6), 2047)); + } else { + cameraMethod5504(cameraGetVrot(), min(add(cameraGetHrot(), ivar6), arg1)); + } + if ((cameraGetHrot() == 2047) && ((boolean)arg2)) { + cameraMethod5504(cameraGetVrot(), 0); + setScriptCallOnGameloop(421, arg0, arg1, 1, "iii", new WidgetPointer(1013,0)); + } + } else { + ivar10 = ivar7; + stack_dump0 = ivar9; + stack_dump1 = ivar10; + structdump_5 = script_422(stack_dump0, stack_dump1); + ivar6 = structdump_5.intpart_1; + ivar5 = structdump_5.intpart_0; + cameraMethod5504(cameraGetVrot(), max(subtract(cameraGetHrot(), ivar6), arg1)); + } + } else { + ivar4 = 1; + } + if (cameraGetVrot() < arg0) { + cameraMethod5504(min(add(cameraGetVrot(), ivar5), arg0), cameraGetHrot()); + } else if (cameraGetVrot() > arg0) { + cameraMethod5504(max(subtract(cameraGetVrot(), ivar5), arg0), cameraGetHrot()); + } else { + ivar3 = 1; + } + if (((boolean)ivar3) && ((boolean)ivar4)) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(1013,0)); + } + return; +} diff --git a/dumps/scripts/4210.cs2 b/dumps/scripts/4210.cs2 new file mode 100644 index 0000000..0034e1c --- /dev/null +++ b/dumps/scripts/4210.cs2 @@ -0,0 +1,4 @@ +void script_4210(int arg0,int arg1,int arg2,int arg3) { + script_4211(arg0, arg1, arg2, arg3); + return; +} diff --git a/dumps/scripts/4211.cs2 b/dumps/scripts/4211.cs2 new file mode 100644 index 0000000..5d3d334 --- /dev/null +++ b/dumps/scripts/4211.cs2 @@ -0,0 +1,4 @@ +void script_4211(int arg0,int arg1,int arg2,int arg3) { + script_4212(arg0, arg1, arg2, arg3, getWidgetText(new WidgetPointer(arg0))); + return; +} diff --git a/dumps/scripts/4212.cs2 b/dumps/scripts/4212.cs2 new file mode 100644 index 0000000..3f0429d --- /dev/null +++ b/dumps/scripts/4212.cs2 @@ -0,0 +1,50 @@ +void script_4212(int arg0,int arg1,int arg2,int arg3,string arg4) { + int ivar4; + int ivar5; + int ivar6; + if (arg0 == -1) { + return; + } + ivar4 = getWidgetActualX(new WidgetPointer(arg0)); + ivar5 = getWidgetActualY(new WidgetPointer(arg0)); + ivar6 = getWidgetParentId(new WidgetPointer(arg0)); + setWidgetText(new WidgetPointer(arg0), arg4); + setWidgetFont(arg1, new WidgetPointer(arg0)); + deleteAllExtraChilds(new WidgetPointer(ivar6)); + createExtraChild(new WidgetPointer(ivar6), 4, getExtraChildGap(new WidgetPointer(ivar6))); + setWidgetPosition(0, -1, 1, 1); + setWidgetSize(0, 0, 1, 1); + setWidgetTextAlignment(1, 1, 0); + setWidgetRGB(new Color(arg3)); + setWidgetFont(arg1); + setWidgetText(arg4); + createExtraChild(new WidgetPointer(ivar6), 4, getExtraChildGap(new WidgetPointer(ivar6))); + setWidgetPosition(0, 1, 1, 1); + setWidgetSize(0, 0, 1, 1); + setWidgetTextAlignment(1, 1, 0); + setWidgetRGB(new Color(arg3)); + setWidgetFont(arg1); + setWidgetText(arg4); + createExtraChild(new WidgetPointer(ivar6), 4, getExtraChildGap(new WidgetPointer(ivar6))); + setWidgetPosition(-1, 0, 1, 1); + setWidgetSize(0, 0, 1, 1); + setWidgetTextAlignment(1, 1, 0); + setWidgetRGB(new Color(arg3)); + setWidgetFont(arg1); + setWidgetText(arg4); + createExtraChild(new WidgetPointer(ivar6), 4, getExtraChildGap(new WidgetPointer(ivar6))); + setWidgetPosition(1, 0, 1, 1); + setWidgetSize(0, 0, 1, 1); + setWidgetTextAlignment(1, 1, 0); + setWidgetRGB(new Color(arg3)); + setWidgetFont(arg1); + setWidgetText(arg4); + createExtraChild(new WidgetPointer(ivar6), 4, getExtraChildGap(new WidgetPointer(ivar6))); + setWidgetPosition(0, 0, 1, 1); + setWidgetSize(0, 0, 1, 1); + setWidgetTextAlignment(1, 1, 0); + setWidgetRGB(new Color(arg2)); + setWidgetFont(arg1); + setWidgetText(arg4); + return; +} diff --git a/dumps/scripts/4213.cs2 b/dumps/scripts/4213.cs2 new file mode 100644 index 0000000..8c8f6b4 --- /dev/null +++ b/dumps/scripts/4213.cs2 @@ -0,0 +1,4 @@ +void script_4213(int arg0) { + script_4408(arg0); + return; +} diff --git a/dumps/scripts/4214.cs2 b/dumps/scripts/4214.cs2 new file mode 100644 index 0000000..14d95b8 --- /dev/null +++ b/dumps/scripts/4214.cs2 @@ -0,0 +1,42 @@ +void script_4214(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + ivar3 = getWidgetShadeColor(new WidgetPointer(arg0)); + ivar4 = 0; + if (arg0 == -1) { + return; + } + if (((boolean)arg2)) { + flow_3: + if (((boolean)arg1)) { + ivar4 = add(ivar3, 22); + } else if (((boolean)arg1)) { + ivar4 = subtract(ivar3, 22); + } else { + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + return; + } + ivar4 = max(ivar4, 0); + ivar4 = min(ivar4, 255); + cs2method2103(ivar4, new WidgetPointer(arg0)); + IF (((boolean)arg1)) + GOTO flow_9 + GOTO flow_10 + flow_9: + IF (ivar4 == 255) + GOTO flow_12 + flow_10: + IF (((boolean)arg1) && ((boolean)ivar4)) + GOTO flow_12 + GOTO flow_13 + flow_12: + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + GOTO flow_14 + flow_13: + setScriptCallOnGameloop(4214, new WidgetPointer(arg0), arg1, 0, "Iii", new WidgetPointer(arg0)); + flow_14: + } else { + setScriptCallOnGameloop(4214, new WidgetPointer(arg0), arg1, subtract(arg2, 1), "Iii", new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/4215.cs2 b/dumps/scripts/4215.cs2 new file mode 100644 index 0000000..95af170 --- /dev/null +++ b/dumps/scripts/4215.cs2 @@ -0,0 +1,7 @@ +void script_4215() { + if (setWidgetRegister(new WidgetPointer(1071,0))) { + setWidgetSelfFull(); + setWidgetAnimation(41); + } + return; +} diff --git a/dumps/scripts/4216.cs2 b/dumps/scripts/4216.cs2 new file mode 100644 index 0000000..5e676f8 --- /dev/null +++ b/dumps/scripts/4216.cs2 @@ -0,0 +1,6 @@ +void script_4216(int arg0) { + if (setWidgetRegister(new WidgetPointer(1071,0))) { + setWidgetAnimation(arg0); + } + return; +} diff --git a/dumps/scripts/4217.cs2 b/dumps/scripts/4217.cs2 new file mode 100644 index 0000000..b2eae42 --- /dev/null +++ b/dumps/scripts/4217.cs2 @@ -0,0 +1,158 @@ +cs2func_script_4217_struct(2,0,0) script_4217() { + int ivar0; + int ivar1; + int stack_dump0; + ivar0 = 0; + ivar1 = 0; + ivar0 = add(ivar0, getSkillXp(7)); + if (ivar0 > 1000000000) { + stack_dump0 = add(ivar1, 1); + ivar0 = subtract(ivar0, 1000000000); + ivar1 = stack_dump0; + } + ivar0 = add(ivar0, getSkillXp(12)); + if (ivar0 > 1000000000) { + stack_dump0 = add(ivar1, 1); + ivar0 = subtract(ivar0, 1000000000); + ivar1 = stack_dump0; + } + ivar0 = add(ivar0, getSkillXp(11)); + if (ivar0 > 1000000000) { + stack_dump0 = add(ivar1, 1); + ivar0 = subtract(ivar0, 1000000000); + ivar1 = stack_dump0; + } + ivar0 = add(ivar0, getSkillXp(10)); + if (ivar0 > 1000000000) { + stack_dump0 = add(ivar1, 1); + ivar0 = subtract(ivar0, 1000000000); + ivar1 = stack_dump0; + } + ivar0 = add(ivar0, getSkillXp(6)); + if (ivar0 > 1000000000) { + stack_dump0 = add(ivar1, 1); + ivar0 = subtract(ivar0, 1000000000); + ivar1 = stack_dump0; + } + ivar0 = add(ivar0, getSkillXp(14)); + if (ivar0 > 1000000000) { + stack_dump0 = add(ivar1, 1); + ivar0 = subtract(ivar0, 1000000000); + ivar1 = stack_dump0; + } + ivar0 = add(ivar0, getSkillXp(5)); + if (ivar0 > 1000000000) { + stack_dump0 = add(ivar1, 1); + ivar0 = subtract(ivar0, 1000000000); + ivar1 = stack_dump0; + } + ivar0 = add(ivar0, getSkillXp(4)); + if (ivar0 > 1000000000) { + stack_dump0 = add(ivar1, 1); + ivar0 = subtract(ivar0, 1000000000); + ivar1 = stack_dump0; + } + ivar0 = add(ivar0, getSkillXp(20)); + if (ivar0 > 1000000000) { + stack_dump0 = add(ivar1, 1); + ivar0 = subtract(ivar0, 1000000000); + ivar1 = stack_dump0; + } + ivar0 = add(ivar0, getSkillXp(13)); + if (ivar0 > 1000000000) { + stack_dump0 = add(ivar1, 1); + ivar0 = subtract(ivar0, 1000000000); + ivar1 = stack_dump0; + } + ivar0 = add(ivar0, getSkillXp(8)); + if (ivar0 > 1000000000) { + stack_dump0 = add(ivar1, 1); + ivar0 = subtract(ivar0, 1000000000); + ivar1 = stack_dump0; + } + ivar0 = add(ivar0, getSkillXp(16)); + if (ivar0 > 1000000000) { + stack_dump0 = add(ivar1, 1); + ivar0 = subtract(ivar0, 1000000000); + ivar1 = stack_dump0; + } + ivar0 = add(ivar0, getSkillXp(15)); + if (ivar0 > 1000000000) { + stack_dump0 = add(ivar1, 1); + ivar0 = subtract(ivar0, 1000000000); + ivar1 = stack_dump0; + } + ivar0 = add(ivar0, getSkillXp(9)); + if (ivar0 > 1000000000) { + stack_dump0 = add(ivar1, 1); + ivar0 = subtract(ivar0, 1000000000); + ivar1 = stack_dump0; + } + ivar0 = add(ivar0, getSkillXp(17)); + if (ivar0 > 1000000000) { + stack_dump0 = add(ivar1, 1); + ivar0 = subtract(ivar0, 1000000000); + ivar1 = stack_dump0; + } + ivar0 = add(ivar0, getSkillXp(18)); + if (ivar0 > 1000000000) { + stack_dump0 = add(ivar1, 1); + ivar0 = subtract(ivar0, 1000000000); + ivar1 = stack_dump0; + } + ivar0 = add(ivar0, getSkillXp(0)); + if (ivar0 > 1000000000) { + stack_dump0 = add(ivar1, 1); + ivar0 = subtract(ivar0, 1000000000); + ivar1 = stack_dump0; + } + ivar0 = add(ivar0, getSkillXp(1)); + if (ivar0 > 1000000000) { + stack_dump0 = add(ivar1, 1); + ivar0 = subtract(ivar0, 1000000000); + ivar1 = stack_dump0; + } + ivar0 = add(ivar0, getSkillXp(2)); + if (ivar0 > 1000000000) { + stack_dump0 = add(ivar1, 1); + ivar0 = subtract(ivar0, 1000000000); + ivar1 = stack_dump0; + } + ivar0 = add(ivar0, getSkillXp(3)); + if (ivar0 > 1000000000) { + stack_dump0 = add(ivar1, 1); + ivar0 = subtract(ivar0, 1000000000); + ivar1 = stack_dump0; + } + ivar0 = add(ivar0, getSkillXp(19)); + if (ivar0 > 1000000000) { + stack_dump0 = add(ivar1, 1); + ivar0 = subtract(ivar0, 1000000000); + ivar1 = stack_dump0; + } + ivar0 = add(ivar0, getSkillXp(22)); + if (ivar0 > 1000000000) { + stack_dump0 = add(ivar1, 1); + ivar0 = subtract(ivar0, 1000000000); + ivar1 = stack_dump0; + } + ivar0 = add(ivar0, getSkillXp(21)); + if (ivar0 > 1000000000) { + stack_dump0 = add(ivar1, 1); + ivar0 = subtract(ivar0, 1000000000); + ivar1 = stack_dump0; + } + ivar0 = add(ivar0, getSkillXp(23)); + if (ivar0 > 1000000000) { + stack_dump0 = add(ivar1, 1); + ivar0 = subtract(ivar0, 1000000000); + ivar1 = stack_dump0; + } + ivar0 = add(ivar0, getSkillXp(24)); + if (ivar0 > 1000000000) { + stack_dump0 = add(ivar1, 1); + ivar0 = subtract(ivar0, 1000000000); + ivar1 = stack_dump0; + } + return newstruct cs2func_script_4217_struct(ivar0, ivar1); +} diff --git a/dumps/scripts/4218.cs2 b/dumps/scripts/4218.cs2 new file mode 100644 index 0000000..7febfe1 --- /dev/null +++ b/dumps/scripts/4218.cs2 @@ -0,0 +1,32 @@ +int script_4218() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + cs2func_script_4217_struct(2,0,0) structdump_0; + int stack_dump1; + ivar0 = 0; + ivar1 = 0; + structdump_0 = script_4217(); + ivar1 = structdump_0.intpart_1; + ivar0 = structdump_0.intpart_0; + ivar2 = subtract(standart_config_2068, ivar1); + ivar3 = subtract(standart_config_450, ivar0); + while ((ivar2 > 0) && (ivar3 <= 1000000000)) { + stack_dump1 = subtract(ivar2, 1); + ivar3 = add(ivar3, 1000000000); + ivar2 = stack_dump1; + } + while ((ivar2 < 0) && (ivar3 >= 1000000000)) { + stack_dump1 = add(ivar2, 1); + ivar3 = subtract(ivar3, 1000000000); + ivar2 = stack_dump1; + } + if (ivar2 < 0) { + return 0; + } + if (((boolean)ivar2) && (ivar3 <= 100000)) { + return max(ivar3, 0); + } + return 100000; +} diff --git a/dumps/scripts/4219.cs2 b/dumps/scripts/4219.cs2 new file mode 100644 index 0000000..0ad9f1e --- /dev/null +++ b/dumps/scripts/4219.cs2 @@ -0,0 +1,4 @@ +void script_4219() { + script_304(49735153); + return; +} diff --git a/dumps/scripts/422.cs2 b/dumps/scripts/422.cs2 new file mode 100644 index 0000000..7ec6531 --- /dev/null +++ b/dumps/scripts/422.cs2 @@ -0,0 +1,17 @@ +cs2func_script_422_struct(2,0,0) script_422(int arg0,int arg1) { + int ivar2; + int ivar3; + ivar2 = 5; + ivar3 = 5; + if ((arg0 <= ivar2) || (arg1 <= ivar3)) { + return newstruct cs2func_script_422_struct(ivar2, ivar3); + } + if (arg0 > arg1) { + ivar2 = multiply(ivar2, divide(arg0, arg1)); + } else { + if (arg1 > arg0) { + ivar3 = multiply(ivar3, divide(arg1, arg0)); + } + } + return newstruct cs2func_script_422_struct(ivar2, ivar3); +} diff --git a/dumps/scripts/4220.cs2 b/dumps/scripts/4220.cs2 new file mode 100644 index 0000000..9bbbb69 --- /dev/null +++ b/dumps/scripts/4220.cs2 @@ -0,0 +1,4 @@ +void script_4220() { + script_304(50154759); + return; +} diff --git a/dumps/scripts/4221.cs2 b/dumps/scripts/4221.cs2 new file mode 100644 index 0000000..1dfe2d0 --- /dev/null +++ b/dumps/scripts/4221.cs2 @@ -0,0 +1,4 @@ +void script_4221() { + script_304(49761550); + return; +} diff --git a/dumps/scripts/4222.cs2 b/dumps/scripts/4222.cs2 new file mode 100644 index 0000000..c40e9b0 --- /dev/null +++ b/dumps/scripts/4222.cs2 @@ -0,0 +1,37 @@ +void script_4222() { + if ((globalint_1468 > 100) && (globalint_1468 <= 355)) { + cs2method2103(subtract(255, subtract(globalint_1468, 100)), new WidgetPointer(1075,0)); + } + if ((globalint_1468 > 100) && (globalint_1468 <= 150)) { + setWidgetPosition(add(-35, subtract(globalint_1468, 100)), 122, 0, 0, new WidgetPointer(1075,4)); + } + if ((globalint_1468 > 200) && (globalint_1468 <= 455)) { + setWidgetPosition(add(-255, subtract(globalint_1468, 200)), 70, 0, 0, new WidgetPointer(1075,1)); + } + if ((globalint_1468 > 250) && (globalint_1468 <= 505)) { + setWidgetPosition(add(-255, subtract(globalint_1468, 250)), 85, 0, 0, new WidgetPointer(1075,2)); + } + if ((globalint_1468 > 300) && (globalint_1468 <= 555)) { + setWidgetPosition(add(-255, subtract(globalint_1468, 300)), 100, 0, 0, new WidgetPointer(1075,3)); + } + if ((globalint_1468 > 500) && (globalint_1468 <= 755)) { + setWidgetPosition(subtract(0, subtract(globalint_1468, 500)), 70, 0, 0, new WidgetPointer(1075,1)); + } + if ((globalint_1468 > 550) && (globalint_1468 <= 805)) { + setWidgetPosition(subtract(0, subtract(globalint_1468, 550)), 85, 0, 0, new WidgetPointer(1075,2)); + } + if ((globalint_1468 > 600) && (globalint_1468 <= 855)) { + setWidgetPosition(subtract(0, subtract(globalint_1468, 600)), 100, 0, 0, new WidgetPointer(1075,3)); + } + if (globalint_1468 == 700) { + setWidget3DRotation(0, 0, 0, 210, 0, 1750, new WidgetPointer(1075,4)); + } + if ((globalint_1468 > 700) && (globalint_1468 <= 955)) { + cs2method2103(subtract(globalint_1468, 700), new WidgetPointer(1075,0)); + } + if ((globalint_1468 > 700) && (globalint_1468 <= 750)) { + setWidgetPosition(subtract(0, subtract(globalint_1468, 700)), 122, 0, 0, new WidgetPointer(1075,4)); + } + globalint_1468 = add(globalint_1468, 1); + return; +} diff --git a/dumps/scripts/4223.cs2 b/dumps/scripts/4223.cs2 new file mode 100644 index 0000000..d09fdea --- /dev/null +++ b/dumps/scripts/4223.cs2 @@ -0,0 +1,18 @@ +void script_4223() { + cs2method2310(new WidgetPointer(944,79), "Make 100"); + cs2method2310(new WidgetPointer(944,80), "Make 50"); + cs2method2310(new WidgetPointer(944,81), "Make 10"); + cs2method2310(new WidgetPointer(944,26), "Make 100"); + cs2method2310(new WidgetPointer(944,27), "Make 50"); + cs2method2310(new WidgetPointer(944,28), "Make 10"); + cs2method2310(new WidgetPointer(944,32), "Make 100"); + cs2method2310(new WidgetPointer(944,33), "Make 50"); + cs2method2310(new WidgetPointer(944,34), "Make 10"); + cs2method2310(new WidgetPointer(944,38), "Make 100"); + cs2method2310(new WidgetPointer(944,39), "Make 50"); + cs2method2310(new WidgetPointer(944,40), "Make 10"); + cs2method2310(new WidgetPointer(944,44), "Make 100"); + cs2method2310(new WidgetPointer(944,45), "Make 50"); + cs2method2310(new WidgetPointer(944,46), "Make 10"); + return; +} diff --git a/dumps/scripts/4224.cs2 b/dumps/scripts/4224.cs2 new file mode 100644 index 0000000..afc5a45 --- /dev/null +++ b/dumps/scripts/4224.cs2 @@ -0,0 +1,10 @@ +void script_4224(int arg0) { + if (arg0 == 61145417) { + setWidgetIsHidden(true, new WidgetPointer(933,329)); + setWidgetIsHidden(false, new WidgetPointer(933,330)); + } else { + setWidgetIsHidden(true, new WidgetPointer(933,330)); + setWidgetIsHidden(false, new WidgetPointer(933,329)); + } + return; +} diff --git a/dumps/scripts/4225.cs2 b/dumps/scripts/4225.cs2 new file mode 100644 index 0000000..ea48381 --- /dev/null +++ b/dumps/scripts/4225.cs2 @@ -0,0 +1,7 @@ +void script_4225() { + setScriptCallOnMouseOver(4226, "", new WidgetPointer(746,190)); + setScriptCallOnMouseExit(40, new WidgetPointer(746,186), "I", new WidgetPointer(746,190)); + setScriptCallOnMouseOver(4226, "", new WidgetPointer(548,27)); + setScriptCallOnMouseExit(40, new WidgetPointer(548,23), "I", new WidgetPointer(548,27)); + return; +} diff --git a/dumps/scripts/4226.cs2 b/dumps/scripts/4226.cs2 new file mode 100644 index 0000000..900b384 --- /dev/null +++ b/dumps/scripts/4226.cs2 @@ -0,0 +1,3 @@ +void script_4226() { + return; +} diff --git a/dumps/scripts/4227.cs2 b/dumps/scripts/4227.cs2 new file mode 100644 index 0000000..bf04eec --- /dev/null +++ b/dumps/scripts/4227.cs2 @@ -0,0 +1,127 @@ +void script_4227(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + string svar0; + string svar1; + string stack_dump0; + int stack_dump1; + deleteAllExtraChilds(new WidgetPointer(arg0)); + ivar2 = 0; + ivar3 = divide(subtract(getWidgetActualWidth(new WidgetPointer(arg0)), multiply(125, 3)), 2); + ivar4 = getCommonDefinitionSize(828); + ivar5 = 0; + ivar6 = 0; + while (ivar2 < ivar4) { + createExtraChild(new WidgetPointer(arg0), 5, ivar2); + setWidgetSize(subtract(125, 4), subtract(125, 4), 0, 0); + if (((boolean)ivar5)) { + setWidgetPosition(2, add(ivar6, 2), 0, 0); + ivar5 = 1; + } else if (((boolean)ivar5)) { + setWidgetPosition(0, add(ivar6, 2), 1, 0); + ivar5 = 2; + } else { + setWidgetPosition(2, add(ivar6, 2), 2, 0); + ivar5 = 0; + ivar6 = add(add(ivar6, 125), ivar3); + } + setWidgetSprite(297); + cs2method1107(1); + ivar2 = add(ivar2, 1); + } + if (((boolean)ivar5)) { + ivar6 = max(subtract(ivar6, ivar3), 0); + } + setWidgetScrollMax(0, ivar6, new WidgetPointer(arg0)); + script_31(arg1, arg0, 792, 789, 790, 791, 773, 788); + ivar7 = -1; + svar0 = ""; + svar1 = ""; + ivar8 = 0; + ivar9 = 0; + ivar10 = subtract(125, 18); + ivar2 = 0; + while (ivar2 < ivar4) { + ivar7 = cs2method_3408(105, 79, 828, ivar2); + if ((ivar7 != -1) && setWidgetRegister(new WidgetPointer(arg0), ivar2)) { + stack_dump0 = getItemHashmapData(ivar7, 1367); + svar1 = getItemHashmapData(ivar7, 1368); + svar0 = stack_dump0; + ivar3 = getItemHashmapData(ivar7, 1366); + stack_dump1 = subtract(getWidgetActualX(), 2); + ivar6 = subtract(getWidgetActualY(), 2); + ivar5 = stack_dump1; + ivar8 = subtract(add(ivar5, 125), 9); + ivar9 = subtract(add(ivar6, 125), 9); + createExtraChild(new WidgetPointer(arg0), 6, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(75, 75, 0, 0); + setWidgetPosition(add(ivar5, 25), add(ivar6, 20), 0, 0); + setItemOnWidgetMethod1205(ivar7, 1); + createExtraChild(new WidgetPointer(arg0), 4, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(125, 20, 0, 0); + setWidgetPosition(ivar5, add(ivar6, 5), 0, 0); + setWidgetFont(494); + setWidgetTextAlignment(1, 1, 0); + setWidgetRGB(new Color(255, 152, 31)); + setWidgetUnknownBoolean(true); + setWidgetText(svar0); + createExtraChild(new WidgetPointer(arg0), 4, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(125, 20, 0, 0); + setWidgetPosition(ivar5, subtract(add(ivar6, 125), 25), 0, 0); + setWidgetFont(494); + setWidgetTextAlignment(1, 1, 0); + setWidgetRGB(new Color(255, 152, 31)); + setWidgetUnknownBoolean(true); + script_4229(ivar3, svar1); + setScriptCallOnConfigChange(4228, new WidgetPointer(-32768,3), -2147483643, ivar3, svar1, 294, 1, "IiisY"); + setScriptCallOnItemContainerUpdate(4228, new WidgetPointer(-32768,3), -2147483643, ivar3, svar1, 93, 94, 2, "IiisY"); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(9, 9, 0, 0); + setWidgetPosition(ivar5, ivar6, 0, 0); + setWidgetSprite(913); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(9, 9, 0, 0); + setWidgetPosition(ivar8, ivar6, 0, 0); + setWidgetSprite(914); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(9, 9, 0, 0); + setWidgetPosition(ivar5, ivar9, 0, 0); + setWidgetSprite(915); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(9, 9, 0, 0); + setWidgetPosition(ivar8, ivar9, 0, 0); + setWidgetSprite(916); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(9, ivar10, 0, 0); + setWidgetPosition(ivar5, add(ivar6, 9), 0, 0); + setWidgetSprite(917); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(ivar10, 9, 0, 0); + setWidgetPosition(add(ivar5, 9), ivar6, 0, 0); + setWidgetSprite(918); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(9, ivar10, 0, 0); + setWidgetPosition(ivar8, add(ivar6, 9), 0, 0); + setWidgetSprite(919); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(ivar10, 9, 0, 0); + setWidgetPosition(add(ivar5, 9), ivar9, 0, 0); + setWidgetSprite(920); + setWidgetContextMenuOption(1, "Claim"); + setWidgetContextMenuOption(10, "Examine"); + svar0 = script_2332(svar0, "
", " "); + cs2method1305("" + svar0); + setScriptCallOnMouseEntered(688, new WidgetPointer(-32768,3), -2147483643, 897, "Iid"); + setScriptCallOnMouseExit(688, new WidgetPointer(-32768,3), -2147483643, 297, "Iid"); + } + ivar2 = add(ivar2, 1); + } + return; +} diff --git a/dumps/scripts/4228.cs2 b/dumps/scripts/4228.cs2 new file mode 100644 index 0000000..303482b --- /dev/null +++ b/dumps/scripts/4228.cs2 @@ -0,0 +1,6 @@ +void script_4228(int arg0,int arg1,int arg2,string arg3) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + script_4229(arg2, arg3); + } + return; +} diff --git a/dumps/scripts/4229.cs2 b/dumps/scripts/4229.cs2 new file mode 100644 index 0000000..921469b --- /dev/null +++ b/dumps/scripts/4229.cs2 @@ -0,0 +1,15 @@ +void script_4229(int arg0,string arg1) { + flow_0: + IF (((getItemAmtInContainer(93, 2883) > 0) || (getItemIdInSlot(94, 3) == 2883)) || (getItemAmtInContainer(93, 4827) > 0)) + GOTO flow_1 + IF ((getItemIdInSlot(94, 3) == 4827) && (standart_config_294 >= arg0)) + GOTO flow_2 + GOTO flow_3 + flow_1: + flow_2: + setWidgetText(arg1 + "
" + "Kills: " + intToStr(arg0)); + return; + flow_3: + setWidgetText(arg1 + "
" + "" + "Kills: " + intToStr(arg0)); + return; +} diff --git a/dumps/scripts/423.cs2 b/dumps/scripts/423.cs2 new file mode 100644 index 0000000..687e2d8 --- /dev/null +++ b/dumps/scripts/423.cs2 @@ -0,0 +1,10 @@ +void script_423() { + if (globalint_1353 != -1) { + cameraMethod5511(globalint_1353); + } else { + if (globalint_1354 != -1) { + cameraMethod5511(globalint_1354); + } + } + return; +} diff --git a/dumps/scripts/4230.cs2 b/dumps/scripts/4230.cs2 new file mode 100644 index 0000000..ededc13 --- /dev/null +++ b/dumps/scripts/4230.cs2 @@ -0,0 +1,60 @@ +void script_4230(int arg0,int arg1,int arg2,int arg3,int arg4) { + if (arg0 < 1) { + setWidgetModel(20542, new WidgetPointer(495,2)); + setWidgetModel(20542, new WidgetPointer(495,15)); + setWidgetModel(20542, new WidgetPointer(495,28)); + setWidgetModel(20542, new WidgetPointer(495,41)); + } else { + setWidgetModel(20544, new WidgetPointer(495,2)); + setWidgetModel(20544, new WidgetPointer(495,15)); + setWidgetModel(20544, new WidgetPointer(495,28)); + setWidgetModel(20544, new WidgetPointer(495,41)); + } + if (arg1 < 1) { + setWidgetModel(20542, new WidgetPointer(495,3)); + setWidgetModel(20542, new WidgetPointer(495,16)); + setWidgetModel(20542, new WidgetPointer(495,29)); + setWidgetModel(20542, new WidgetPointer(495,42)); + } else { + setWidgetModel(20545, new WidgetPointer(495,3)); + setWidgetModel(20545, new WidgetPointer(495,16)); + setWidgetModel(20545, new WidgetPointer(495,29)); + setWidgetModel(20545, new WidgetPointer(495,42)); + } + if (arg2 < 1) { + setWidgetModel(20542, new WidgetPointer(495,4)); + setWidgetModel(20542, new WidgetPointer(495,17)); + setWidgetModel(20542, new WidgetPointer(495,30)); + setWidgetModel(20542, new WidgetPointer(495,43)); + } else { + setWidgetModel(20543, new WidgetPointer(495,4)); + setWidgetModel(20543, new WidgetPointer(495,17)); + setWidgetModel(20543, new WidgetPointer(495,30)); + setWidgetModel(20543, new WidgetPointer(495,43)); + } + if (arg4 != 10) { + setWidgetModel(20542, new WidgetPointer(495,53)); + } else { + if (arg3 < 1) { + setWidgetModel(20542, new WidgetPointer(495,53)); + } + } + setWidgetText(new WidgetPointer(495,57), intToStr(arg0)); + setWidgetText(new WidgetPointer(495,60), intToStr(arg0)); + setWidgetText(new WidgetPointer(495,63), intToStr(arg0)); + setWidgetText(new WidgetPointer(495,66), intToStr(arg0)); + setWidgetText(new WidgetPointer(495,58), intToStr(arg1)); + setWidgetText(new WidgetPointer(495,61), intToStr(arg1)); + setWidgetText(new WidgetPointer(495,64), intToStr(arg1)); + setWidgetText(new WidgetPointer(495,67), intToStr(arg1)); + setWidgetText(new WidgetPointer(495,59), intToStr(arg2)); + setWidgetText(new WidgetPointer(495,62), intToStr(arg2)); + setWidgetText(new WidgetPointer(495,65), intToStr(arg2)); + setWidgetText(new WidgetPointer(495,68), intToStr(arg2)); + if (arg4 != 10) { + setWidgetText(new WidgetPointer(495,69), "0"); + } else { + setWidgetText(new WidgetPointer(495,69), intToStr(arg3)); + } + return; +} diff --git a/dumps/scripts/4231.cs2 b/dumps/scripts/4231.cs2 new file mode 100644 index 0000000..e81a611 --- /dev/null +++ b/dumps/scripts/4231.cs2 @@ -0,0 +1,9 @@ +void script_4231(int arg0) { + if (setWidgetRegister(new WidgetPointer(arg0))) { + setScriptCallOnMousePressed(4209, new WidgetPointer(arg0), 0, "Ii"); + setScriptCallOnMouseDraggedOver(4209, new WidgetPointer(arg0), 0, "Ii"); + setScriptCallOnMouseReleased(4209, new WidgetPointer(arg0), 1, "Ii"); + cs2method2103(255); + } + return; +} diff --git a/dumps/scripts/4232.cs2 b/dumps/scripts/4232.cs2 new file mode 100644 index 0000000..ca03f76 --- /dev/null +++ b/dumps/scripts/4232.cs2 @@ -0,0 +1,8 @@ +void script_4232(int arg0) { + if (setWidgetRegister(new WidgetPointer(arg0))) { + setScriptCallOnMouseEntered(4209, new WidgetPointer(arg0), 0, "Ii"); + setScriptCallOnMouseExit(4209, new WidgetPointer(arg0), 1, "Ii"); + cs2method2103(255); + } + return; +} diff --git a/dumps/scripts/4233.cs2 b/dumps/scripts/4233.cs2 new file mode 100644 index 0000000..e122db9 --- /dev/null +++ b/dumps/scripts/4233.cs2 @@ -0,0 +1,5 @@ +void script_4233(int arg0,int arg1,int arg2,int arg3) { + setScriptCallOnGameloop(4234, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), getClientCycle(), arg3, "IIIii", new WidgetPointer(arg0)); + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/4234.cs2 b/dumps/scripts/4234.cs2 new file mode 100644 index 0000000..a741e02 --- /dev/null +++ b/dumps/scripts/4234.cs2 @@ -0,0 +1,20 @@ +void script_4234(int arg0,int arg1,int arg2,int arg3,int arg4) { + int ivar5; + int ivar6; + ivar5 = 0; + ivar6 = divide(65353, arg4); + ivar5 = max(0, subtract(arg4, subtract(getClientCycle(), arg3))); + if ((ivar5 >= divide(arg4, 2)) && (ivar5 <= arg4)) { + cs2method2106(min(multiply(ivar5, ivar6), 65353), new WidgetPointer(arg2)); + cs2method2106(0, new WidgetPointer(arg1)); + } else if ((ivar5 > 0) && (ivar5 < divide(arg4, 2))) { + cs2method2106(32768, new WidgetPointer(arg2)); + cs2method2106(min(add(32768, multiply(ivar5, ivar6)), 65353), new WidgetPointer(arg1)); + } else { + cs2method2106(32768, new WidgetPointer(arg2)); + cs2method2106(32768, new WidgetPointer(arg1)); + setScriptCallOnClickContextMenu(4233, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), arg4, "IIIi", new WidgetPointer(arg0)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/4235.cs2 b/dumps/scripts/4235.cs2 new file mode 100644 index 0000000..b59b9ab --- /dev/null +++ b/dumps/scripts/4235.cs2 @@ -0,0 +1,7 @@ +void script_4235() { + if (globalint_1494 > 100) { + globalint_1494 = 100; + } + setWidgetSize(multiplyDivide(globalint_1494, 100, 16384), 16384, 2, 2, new WidgetPointer(481,15)); + return; +} diff --git a/dumps/scripts/4236.cs2 b/dumps/scripts/4236.cs2 new file mode 100644 index 0000000..e957bc4 --- /dev/null +++ b/dumps/scripts/4236.cs2 @@ -0,0 +1,5 @@ +void script_4236(int arg0) { + setScriptCallOnUse(4239, "", new WidgetPointer(arg0)); + setScriptCallOnUseWith(4240, "", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/4237.cs2 b/dumps/scripts/4237.cs2 new file mode 100644 index 0000000..e180b32 --- /dev/null +++ b/dumps/scripts/4237.cs2 @@ -0,0 +1,8 @@ +void script_4237() { + if (((boolean)globalint_1495) && (bitconfig_8960 > 0)) { + globalint_1495 = getClientCycle(); + } else { + return; + } + return; +} diff --git a/dumps/scripts/4238.cs2 b/dumps/scripts/4238.cs2 new file mode 100644 index 0000000..f6e2ece --- /dev/null +++ b/dumps/scripts/4238.cs2 @@ -0,0 +1,21 @@ +void script_4238(int arg0,int arg1,int arg2) { + int ivar3; + ivar3 = 0; + if (globalint_1495 != 0) { + ivar3 = max(0, subtract(120, subtract(getClientCycle(), globalint_1495))); + } + if ((ivar3 >= 60) && (ivar3 <= 120)) { + cs2method2106(min(multiply(ivar3, 545), 65353), new WidgetPointer(arg2)); + cs2method2106(0, new WidgetPointer(arg1)); + } else if ((ivar3 > 0) && (ivar3 < 60)) { + cs2method2106(32768, new WidgetPointer(arg2)); + cs2method2106(min(add(32768, multiply(ivar3, 545)), 65353), new WidgetPointer(arg1)); + } else { + cs2method2106(32768, new WidgetPointer(arg2)); + cs2method2106(32768, new WidgetPointer(arg1)); + if (globalint_1495 != 0) { + globalint_1495 = 0; + } + } + return; +} diff --git a/dumps/scripts/4239.cs2 b/dumps/scripts/4239.cs2 new file mode 100644 index 0000000..6ef7584 --- /dev/null +++ b/dumps/scripts/4239.cs2 @@ -0,0 +1,5 @@ +void script_4239() { + setWidgetBorderThickness(2, new WidgetPointer(1078,23)); + script_4161(70647825, 0); + return; +} diff --git a/dumps/scripts/424.cs2 b/dumps/scripts/424.cs2 new file mode 100644 index 0000000..9784df8 --- /dev/null +++ b/dumps/scripts/424.cs2 @@ -0,0 +1,18 @@ +void script_424() { + int ivar0; + int ivar1; + string svar0; + ivar0 = divide(multiply(globalint_1365, 6), 10); + ivar1 = 0; + svar0 = "1 minute"; + if (ivar0 < 60) { + setWidgetText(new WidgetPointer(1027,24), "Your opponent has logged out." + "
" + "You may wait for them to return or end the Conquest now and be declared the winner."); + return; + } + if (ivar0 > 120) { + ivar1 = divide(ivar0, 60); + svar0 = intToStr(ivar1) + " minutes"; + } + setWidgetText(new WidgetPointer(1027,24), "Your opponent has been logged out for " + svar0 + "." + "
" + "You may wait for them to return or end the Conquest now and be declared the winner."); + return; +} diff --git a/dumps/scripts/4240.cs2 b/dumps/scripts/4240.cs2 new file mode 100644 index 0000000..518dfc7 --- /dev/null +++ b/dumps/scripts/4240.cs2 @@ -0,0 +1,5 @@ +void script_4240() { + setWidgetBorderThickness(0, new WidgetPointer(1078,23)); + script_4161(70647825, 255); + return; +} diff --git a/dumps/scripts/4241.cs2 b/dumps/scripts/4241.cs2 new file mode 100644 index 0000000..396ae15 --- /dev/null +++ b/dumps/scripts/4241.cs2 @@ -0,0 +1,4 @@ +void script_4241() { + setWidgetSize(multiplyDivide(bitconfig_8959, 10, 16384), 16384, 2, 2, new WidgetPointer(1078,7)); + return; +} diff --git a/dumps/scripts/4242.cs2 b/dumps/scripts/4242.cs2 new file mode 100644 index 0000000..d6b92d1 --- /dev/null +++ b/dumps/scripts/4242.cs2 @@ -0,0 +1,41 @@ +string script_4242(int arg0) { + switch (arg0) { + case 1: + return "You are more likely to hit with your melee attacks." + "
" + "
"; + case 2: + return "You are able to deal more damage with your melee attacks." + "
" + "
"; + case 5: + return "You are less likely to be hit by an enemy's attacks." + "
" + "
"; + case 3: + return "You are more likely to hit with your ranged attacks." + "
" + "
"; + case 7: + return "You are able to sustain your prayers for longer before needing to recharge." + "
" + "
"; + case 4: + return "Your ability to hit with and defend against magical attacks is improved." + "
" + "
"; + case 6: + return "Your maximum lifepoints have been increased by 10." + "
" + "
"; + case 8: + return "Your chance of failing agility shortcuts and obstacles is reduced." + "
" + "
"; + case 10: + return "You are more likely to succeed when picking pockets or locks." + "
" + "
"; + case 13: + return "You are more likely to succeed when attempting to mine ore." + "
" + "
"; + case 15: + return "You are more likely to succeed when attempting to catch a fish." + "
" + "
"; + case 16: + return "Your likelihood of burning food is decreased." + "
" + "
"; + case 17: + return "Your chance of success when lighting a fire is improved." + "
" + "
"; + case 18: + return "You are more likely to succeed when attempting to cut a log." + "
" + "
"; + case 12: + return "Your chance of crafting multiple runes from a single piece of essence is increased." + "
" + "
"; + case 21: + return "Your chance of successfully pruning diseased plants is increased." + "
" + "
"; + case 23: + return "Your chance of successfully trapping creatures is increased." + "
" + "
"; + case 24: + return "You are able to sustain your familiars for longer before needing to recharge." + "
" + "
"; + } + return ""; +} diff --git a/dumps/scripts/4243.cs2 b/dumps/scripts/4243.cs2 new file mode 100644 index 0000000..93c7393 --- /dev/null +++ b/dumps/scripts/4243.cs2 @@ -0,0 +1,174 @@ +int script_4243() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + string svar0; + string svar1; + ivar0 = 0; + ivar1 = 0; + ivar2 = 0; + ivar3 = -1; + svar0 = ""; + svar1 = ""; + ivar4 = 0; + ivar5 = -1; + ivar6 = -1; + ivar7 = 0; + ivar8 = 0; + ivar9 = 3656; + ivar10 = -1; + ivar11 = -1; + ivar12 = 0; + ivar13 = 23; + ivar14 = 23; + ivar15 = 0; + while (ivar0 < getCommonDefinitionSize(ivar9)) { + ivar1 = cs2method_3408(105, 105, ivar9, ivar0); + ivar3 = cs2method_3408(105, 74, 3483, ivar1); + if ((ivar3 != -1) && (script_3227(ivar1) != 2)) { + svar0 = getOtherCommonData(ivar3, 1266); + if (getOtherCommonData(ivar3, 1270) != 4094) { + ivar5 = getOtherCommonData(cs2method_3408(105, 74, 2252, getOtherCommonData(ivar3, 1270)), 952); + } else { + ivar5 = getOtherCommonData(ivar3, 1271); + } + createExtraChild(new WidgetPointer(917,98), 5, ivar7); + ivar11 = 4041; + ivar10 = 4042; + setWidgetSprite(ivar11); + setScriptCallOnMouseEntered(4013, -2147483643, ivar10, "id"); + setScriptCallOnMouseExit(4013, -2147483643, ivar11, "id"); + setWidgetSize(add(70, 2), add(56, 1), 0, 0); + setWidgetPosition(subtract(ivar13, 1), subtract(ivar14, 1), 0, 0); + setWidgetContextMenuOption(1, "Summary for"); + if (bitconfig_8576 == ivar1) { + setWidgetContextMenuOption(2, "Unpin"); + } else { + setWidgetContextMenuOption(2, "Pin"); + } + cs2method1305(svar0); + setScriptCallOnClickContextMenu(3990, ivar1, -2147483643, -2147483644, "iii"); + if (((boolean)script_3999(ivar1))) { + svar1 = " -" + "
"; + svar1 = concat(getOtherCommonData(ivar3, 1266), svar1); + svar1 = concat(svar1, getOtherCommonData(ivar3, 1273)); + setScriptCallOnMouseOver(3998, ivar7, svar1, "is"); + } + if (((boolean)script_3994(ivar1)) && (ivar1 != 4094)) { + globalint_1422 = ivar7; + } + createExtraChild(new WidgetPointer(917,98), 5, add(ivar7, 1)); + setWidgetSize(50, 50, 0, 0); + setWidgetSprite(ivar5); + setWidgetPosition(add(ivar13, 2), add(ivar14, 2), 0, 0); + cs2method2103(ivar15); + createExtraChild(new WidgetPointer(917,98), 5, add(ivar7, 2)); + setWidgetSize(14, 18, 0, 0); + if (((boolean)script_3996(ivar1))) { + ivar6 = 4346; + setWidgetSize(11, 11, 0, 0); + } else { + ivar6 = -1; + } + setWidgetSprite(ivar6); + setWidgetPosition(subtract(add(ivar13, 70), 16), add(ivar14, 4), 0, 0); + createExtraChild(new WidgetPointer(917,98), 5, add(ivar7, 3)); + setWidgetSize(11, 11, 0, 0); + setWidgetPosition(subtract(add(ivar13, 70), 17), add(ivar14, 39), 0, 0); + if (((boolean)script_3994(ivar1))) { + setWidgetSprite(4296); + } + ivar8 = add(ivar8, 1); + ivar7 = multiply(ivar8, 4); + ivar13 = add(add(ivar13, 70), 23); + ivar12 = mod(add(ivar12, 1), 5); + if (((boolean)ivar12)) { + ivar14 = add(add(ivar14, 56), 23); + ivar13 = 23; + } + } + ivar0 = add(ivar0, 1); + } + ivar0 = 0; + while (ivar0 < getCommonDefinitionSize(ivar9)) { + ivar1 = cs2method_3408(105, 105, ivar9, ivar0); + ivar3 = cs2method_3408(105, 74, 3483, ivar1); + if ((ivar3 != -1) && (script_3227(ivar1) == 2)) { + svar0 = getOtherCommonData(ivar3, 1266); + if (getOtherCommonData(ivar3, 1270) != 4094) { + ivar5 = getOtherCommonData(cs2method_3408(105, 74, 2252, getOtherCommonData(ivar3, 1270)), 952); + } else { + ivar5 = getOtherCommonData(ivar3, 1271); + } + createExtraChild(new WidgetPointer(917,98), 5, ivar7); + ivar11 = 4043; + ivar10 = 4043; + setWidgetSprite(ivar11); + setScriptCallOnMouseEntered(4013, -2147483643, ivar10, "id"); + setScriptCallOnMouseExit(4013, -2147483643, ivar11, "id"); + setWidgetSize(add(70, 2), add(56, 1), 0, 0); + setWidgetPosition(subtract(ivar13, 1), subtract(ivar14, 1), 0, 0); + setWidgetContextMenuOption(1, "Summary for"); + cs2method1305(svar0); + setScriptCallOnClickContextMenu(3990, ivar1, -2147483643, -2147483644, "iii"); + if (((boolean)script_3999(ivar1))) { + svar1 = " -" + "
"; + svar1 = concat(getOtherCommonData(ivar3, 1266), svar1); + svar1 = concat(svar1, getOtherCommonData(ivar3, 1273)); + setScriptCallOnMouseOver(3998, ivar7, svar1, "is"); + } + if (((boolean)script_3994(ivar1)) && (ivar1 != 4094)) { + globalint_1422 = ivar7; + } + createExtraChild(new WidgetPointer(917,98), 5, add(ivar7, 1)); + setWidgetSize(50, 50, 0, 0); + setWidgetSprite(ivar5); + setWidgetPosition(add(ivar13, 2), add(ivar14, 2), 0, 0); + cs2method2103(ivar15); + createExtraChild(new WidgetPointer(917,98), 5, add(ivar7, 2)); + setWidgetSize(14, 18, 0, 0); + if (((boolean)script_3996(ivar1))) { + ivar6 = 4346; + setWidgetSize(11, 11, 0, 0); + } else { + ivar6 = -1; + } + setWidgetSprite(ivar6); + setWidgetPosition(subtract(add(ivar13, 70), 16), add(ivar14, 4), 0, 0); + createExtraChild(new WidgetPointer(917,98), 5, add(ivar7, 3)); + setWidgetSize(11, 11, 0, 0); + setWidgetPosition(subtract(add(ivar13, 70), 17), add(ivar14, 39), 0, 0); + if (((boolean)script_3994(ivar1))) { + setWidgetSprite(4296); + } + ivar8 = add(ivar8, 1); + ivar7 = multiply(ivar8, 4); + ivar13 = add(add(ivar13, 70), 23); + ivar12 = mod(add(ivar12, 1), 5); + if (((boolean)ivar12)) { + ivar14 = add(add(ivar14, 56), 23); + ivar13 = 23; + } + } + ivar0 = add(ivar0, 1); + } + if (ivar12 != 0) { + ivar14 = add(ivar14, 56); + } else { + ivar14 = subtract(ivar14, 23); + } + return ivar14; +} diff --git a/dumps/scripts/4244.cs2 b/dumps/scripts/4244.cs2 new file mode 100644 index 0000000..06859a5 --- /dev/null +++ b/dumps/scripts/4244.cs2 @@ -0,0 +1,4 @@ +void script_4244() { + script_4248(0, 0, 0, 0, 494, ""); + return; +} diff --git a/dumps/scripts/4245.cs2 b/dumps/scripts/4245.cs2 new file mode 100644 index 0000000..a649a9b --- /dev/null +++ b/dumps/scripts/4245.cs2 @@ -0,0 +1,8 @@ +void script_4245(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5) { + if (getDisplayMode() >= 2) { + script_4248(arg0, arg1, arg2, arg3, arg4, arg5); + } else { + script_4247(arg0, arg1, arg2, arg3, arg4, arg5); + } + return; +} diff --git a/dumps/scripts/4246.cs2 b/dumps/scripts/4246.cs2 new file mode 100644 index 0000000..20b0f13 --- /dev/null +++ b/dumps/scripts/4246.cs2 @@ -0,0 +1,4 @@ +void script_4246() { + script_4249(1); + return; +} diff --git a/dumps/scripts/4247.cs2 b/dumps/scripts/4247.cs2 new file mode 100644 index 0000000..a8be7d9 --- /dev/null +++ b/dumps/scripts/4247.cs2 @@ -0,0 +1,37 @@ +void script_4247(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5) { + if (isParent(new WidgetPointer(script_8(1)), 1056)) { + arg5 = ""; + } + if ((((divide(extractX(getMyPositionHash()), 64) < 48) || (divide(extractX(getMyPositionHash()), 64) > 52)) || (divide(extractY(getMyPositionHash()), 64) < 48)) || (divide(extractY(getMyPositionHash()), 64) > 52)) { + arg5 = ""; + } + if (arg3 == -1) { + arg3 = 16777215; + } + if (arg4 == -1) { + arg4 = 5631; + } + setWidgetIsHidden(true, new WidgetPointer(746,185)); + setWidgetIsHidden(true, new WidgetPointer(548,196)); + if (((boolean)stringMethod4107(arg5, ""))) { + return; + } + setWidgetText(new WidgetPointer(548,236), arg5); + setWidgetPosition(arg0, arg1, 2, 2, new WidgetPointer(548,196)); + setWidgetRGB(new Color(arg3), new WidgetPointer(548,236)); + setWidgetFont(arg4, new WidgetPointer(548,236)); + if (((boolean)arg2)) { + setWidgetIsHidden(false, new WidgetPointer(548,238)); + setWidgetIsHidden(true, new WidgetPointer(548,239)); + } else { + setWidgetIsHidden(true, new WidgetPointer(548,238)); + setWidgetIsHidden(false, new WidgetPointer(548,239)); + } + setWidgetIsHidden(false, new WidgetPointer(548,196)); + if (((boolean)stringMethod4107(arg5, "The '?' icon will add an arrow to the screen which points to your destination.")) && ((boolean)getLanguage())) { + setWidgetIsHidden(false, new WidgetPointer(548,237)); + } else { + setWidgetIsHidden(true, new WidgetPointer(548,237)); + } + return; +} diff --git a/dumps/scripts/4248.cs2 b/dumps/scripts/4248.cs2 new file mode 100644 index 0000000..d0c5d6d --- /dev/null +++ b/dumps/scripts/4248.cs2 @@ -0,0 +1,34 @@ +void script_4248(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5) { + if (isParent(new WidgetPointer(script_8(1)), 1056)) { + arg5 = ""; + } + if (arg3 == -1) { + arg3 = 16777215; + } + if (arg4 == -1) { + arg4 = 5631; + } + setWidgetIsHidden(true, new WidgetPointer(746,185)); + setWidgetIsHidden(true, new WidgetPointer(548,196)); + if (((boolean)stringMethod4107(arg5, ""))) { + return; + } + setWidgetText(new WidgetPointer(746,241), arg5); + setWidgetPosition(arg0, arg1, 2, 2, new WidgetPointer(746,185)); + setWidgetRGB(new Color(arg3), new WidgetPointer(746,241)); + setWidgetFont(arg4, new WidgetPointer(746,241)); + if (((boolean)arg2)) { + setWidgetIsHidden(false, new WidgetPointer(746,243)); + setWidgetIsHidden(true, new WidgetPointer(746,244)); + } else { + setWidgetIsHidden(true, new WidgetPointer(746,243)); + setWidgetIsHidden(false, new WidgetPointer(746,244)); + } + setWidgetIsHidden(false, new WidgetPointer(746,185)); + if (((boolean)stringMethod4107(arg5, "The '?' icon will add an arrow to the screen which points to your destination.")) && ((boolean)getLanguage())) { + setWidgetIsHidden(false, new WidgetPointer(746,242)); + } else { + setWidgetIsHidden(true, new WidgetPointer(746,242)); + } + return; +} diff --git a/dumps/scripts/4249.cs2 b/dumps/scripts/4249.cs2 new file mode 100644 index 0000000..eeedfe8 --- /dev/null +++ b/dumps/scripts/4249.cs2 @@ -0,0 +1,72 @@ +void script_4249(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + string svar0; + if (((boolean)bitconfig_9030)) { + script_4248(0, 0, 0, 0, 5631, ""); + return; + } + if ((bitconfig_8587 == 419) && isWidgetHidden(new WidgetPointer(1056,130))) { + return; + } + svar0 = ""; + ivar1 = 0; + ivar2 = 0; + ivar3 = 1; + ivar4 = 0; + if (((boolean)arg0)) { + if ((bitconfig_8587 == 419) && isWidgetHidden(new WidgetPointer(1056,122))) { + svar0 = "Click on the first Task in the list for details of how to complete it."; + } else { + if ((bitconfig_8587 == 420) && isWidgetHidden(new WidgetPointer(1056,122))) { + svar0 = "Click on the Task which is now first in the list."; + } + } + if (getDisplayMode() >= 2) { + ivar1 = 180; + ivar2 = 165; + ivar4 = 1; + if (getWidgetActualWidth(new WidgetPointer(746,2)) < 997) { + ivar2 = add(ivar2, 40); + } + } else { + ivar1 = 207; + ivar2 = 156; + } + } else { + script_4089(); + if (bitconfig_8587 == 419) { + svar0 = "Click here to show the Task window."; + } + if (getDisplayMode() >= 2) { + if (getWidgetActualWidth(new WidgetPointer(746,2)) > 997) { + ivar1 = 288; + ivar2 = 39; + ivar3 = 2; + ivar4 = 1; + } else { + ivar1 = 51; + ivar2 = 77; + ivar3 = 2; + ivar4 = 1; + } + } else { + ivar1 = 210; + ivar2 = 254; + } + } + if (((boolean)bitconfig_9030)) { + svar0 = ""; + } + if (isParent(new WidgetPointer(548,8), 1079) || isParent(new WidgetPointer(746,9), 1079)) { + svar0 = ""; + } + if (((boolean)ivar4)) { + script_4247(ivar1, ivar2, ivar3, 16777215, 5631, svar0); + } else { + script_4248(ivar1, ivar2, ivar3, 16777215, 5631, svar0); + } + return; +} diff --git a/dumps/scripts/425.cs2 b/dumps/scripts/425.cs2 new file mode 100644 index 0000000..ba417b0 --- /dev/null +++ b/dumps/scripts/425.cs2 @@ -0,0 +1,13 @@ +void script_425() { + if (((boolean)globalint_1366)) { + setWidgetContextMenuOption(1, new WidgetPointer(1019,16), "Accept Victory"); + setWidgetText(new WidgetPointer(1019,16), "Accept Victory"); + setWidgetText(new WidgetPointer(1019,0), "Your opponent has logged out. You may end the Conquest now and be declared the winner."); + } else { + setWidgetContextMenuOption(1, new WidgetPointer(1019,16), "Resign"); + setWidgetText(new WidgetPointer(1019,16), "Resign"); + setWidgetText(new WidgetPointer(1019,0), "If you resign, the Conquest will end immediately."); + sendCloseWidgetPacket(); + } + return; +} diff --git a/dumps/scripts/4250.cs2 b/dumps/scripts/4250.cs2 new file mode 100644 index 0000000..668f2ec --- /dev/null +++ b/dumps/scripts/4250.cs2 @@ -0,0 +1,9 @@ +void script_4250() { + int ivar0; + ivar0 = getWidgetActualWidth(new WidgetPointer(548,2)); + if (getDisplayMode() >= 2) { + ivar0 = getWidgetActualWidth(new WidgetPointer(746,2)); + } + messageType0(intToStr(ivar0) + "."); + return; +} diff --git a/dumps/scripts/4251.cs2 b/dumps/scripts/4251.cs2 new file mode 100644 index 0000000..848ec43 --- /dev/null +++ b/dumps/scripts/4251.cs2 @@ -0,0 +1,44 @@ +void script_4251() { + int ivar0; + int ivar1; + int ivar2; + string svar0; + if (((boolean)bitconfig_9030)) { + return; + } + if (isWidgetHidden(new WidgetPointer(746,185))) { + return; + } + ivar0 = getWidgetActualX(new WidgetPointer(746,185)); + ivar1 = getWidgetActualY(new WidgetPointer(746,185)); + ivar2 = getWidgetActualWidth(new WidgetPointer(746,2)); + svar0 = getWidgetText(new WidgetPointer(746,241)); + if (ivar2 < 998) { + if (((boolean)stringMethod4107(svar0, "Click here to show the Task window."))) { + script_4248(51, 77, 2, 16777215, 5631, svar0); + } else if (((boolean)stringMethod4107(svar0, "Task complete! Click here to return to the task list."))) { + script_4248(158, 45, 1, 16777215, 5631, svar0); + } else if (((boolean)stringMethod4107(svar0, "Click on the first Task in the list for details of how to complete it.")) || ((boolean)stringMethod4107(svar0, "Click on the Task which is now first in the list."))) { + script_4248(180, 205, 1, 16777215, 5631, svar0); + } else if (((boolean)stringMethod4107(svar0, "Click on the Hints tab for more on how to complete this Task.")) || ((boolean)stringMethod4107(svar0, "Remember, the Hints tab provides more details about a Task."))) { + script_4248(196, 223, 1, 16777215, 5631, svar0); + } else { + if (((boolean)stringMethod4107(svar0, "The '?' icon will add an arrow to the screen which points to your destination."))) { + script_4248(196, 127, 1, 16777215, 5631, svar0); + } + } + } else if (((boolean)stringMethod4107(svar0, "Click here to show the Task window."))) { + script_4248(288, 39, 2, 16777215, 5631, svar0); + } else if (((boolean)stringMethod4107(svar0, "Task complete! Click here to return to the task list."))) { + script_4248(158, 5, 1, 16777215, 5631, svar0); + } else if (((boolean)stringMethod4107(svar0, "Click on the first Task in the list for details of how to complete it.")) || ((boolean)stringMethod4107(svar0, "Click on the Task which is now first in the list."))) { + script_4248(180, 165, 1, 16777215, 5631, svar0); + } else if (((boolean)stringMethod4107(svar0, "Click on the Hints tab for more on how to complete this Task.")) || ((boolean)stringMethod4107(svar0, "Remember, the Hints tab provides more details about a Task."))) { + script_4248(196, 183, 1, 16777215, 5631, svar0); + } else { + if (((boolean)stringMethod4107(svar0, "The '?' icon will add an arrow to the screen which points to your destination."))) { + script_4248(196, 87, 1, 16777215, 5631, svar0); + } + } + return; +} diff --git a/dumps/scripts/4252.cs2 b/dumps/scripts/4252.cs2 new file mode 100644 index 0000000..12c4d40 --- /dev/null +++ b/dumps/scripts/4252.cs2 @@ -0,0 +1,12 @@ +void script_4252(int arg0) { + if (((boolean)arg0)) { + setWidgetSprite(4318, new WidgetPointer(917,166)); + setWidgetSprite(4318, new WidgetPointer(917,167)); + setWidgetSprite(4319, new WidgetPointer(917,168)); + } else { + setWidgetSprite(4316, new WidgetPointer(917,166)); + setWidgetSprite(4316, new WidgetPointer(917,167)); + setWidgetSprite(4317, new WidgetPointer(917,168)); + } + return; +} diff --git a/dumps/scripts/4253.cs2 b/dumps/scripts/4253.cs2 new file mode 100644 index 0000000..0d70536 --- /dev/null +++ b/dumps/scripts/4253.cs2 @@ -0,0 +1,26 @@ +void script_4253() { + if (((boolean)bitconfig_9030)) { + setWidgetText(new WidgetPointer(917,169), "Tutorial is ON"); + } else { + setWidgetText(new WidgetPointer(917,169), "Tutorial is OFF"); + } + if ((bitconfig_9028 == getCommonDefinitionSize(3656)) || (bitconfig_8601 >= 60)) { + setWidgetIsHidden(true, new WidgetPointer(917,165)); + } else { + setWidgetIsHidden(false, new WidgetPointer(917,165)); + } + switch (getLanguage()) { + case 0: + setWidgetSize(77, 18, 0, 0, new WidgetPointer(917,165)); + break; + case 2: + setWidgetSize(112, 18, 0, 0, new WidgetPointer(917,165)); + break; + case 1: + setWidgetSize(135, 18, 0, 0, new WidgetPointer(917,165)); + break; + case 3: + setWidgetSize(109, 18, 0, 0, new WidgetPointer(917,165)); + } + return; +} diff --git a/dumps/scripts/4254.cs2 b/dumps/scripts/4254.cs2 new file mode 100644 index 0000000..67542ef --- /dev/null +++ b/dumps/scripts/4254.cs2 @@ -0,0 +1,4 @@ +void script_4254(int arg0,int arg1,int arg2,int arg3,string arg4) { + script_4212(arg0, arg1, arg2, arg3, arg4); + return; +} diff --git a/dumps/scripts/4255.cs2 b/dumps/scripts/4255.cs2 new file mode 100644 index 0000000..47feb62 --- /dev/null +++ b/dumps/scripts/4255.cs2 @@ -0,0 +1,4 @@ +void script_4255(int arg0,int arg1) { + setScriptCallOnGameloop(4159, new WidgetPointer(-32768,3), arg1, 0, "Iii", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/4256.cs2 b/dumps/scripts/4256.cs2 new file mode 100644 index 0000000..3befa1f --- /dev/null +++ b/dumps/scripts/4256.cs2 @@ -0,0 +1,3 @@ +void script_4256(int arg0) { + return; +} diff --git a/dumps/scripts/4257.cs2 b/dumps/scripts/4257.cs2 new file mode 100644 index 0000000..b9c7f24 --- /dev/null +++ b/dumps/scripts/4257.cs2 @@ -0,0 +1,10 @@ +void script_4257(int arg0) { + if (setWidgetRegister(new WidgetPointer(arg0))) { + setWidgetPosition(0, 0, 1, 1); + setWidgetSize(16, 15, 0, 0); + setWidgetSprite(5450); + setScriptCallOnClickContextMenu(29, ""); + setWidgetContextMenuOption(1, "Close"); + } + return; +} diff --git a/dumps/scripts/4258.cs2 b/dumps/scripts/4258.cs2 new file mode 100644 index 0000000..6cd4970 --- /dev/null +++ b/dumps/scripts/4258.cs2 @@ -0,0 +1,11 @@ +void script_4258(int arg0) { + if (setWidgetRegister(new WidgetPointer(arg0))) { + setWidgetPosition(0, 0, 1, 1); + setWidgetSize(16, 15, 0, 0); + setWidgetSprite(5451); + setScriptCallOnMouseEntered(4209, new WidgetPointer(arg0), 0, "Ii"); + setScriptCallOnMouseExit(4209, new WidgetPointer(arg0), 1, "Ii"); + cs2method2103(255); + } + return; +} diff --git a/dumps/scripts/4259.cs2 b/dumps/scripts/4259.cs2 new file mode 100644 index 0000000..e95dea2 --- /dev/null +++ b/dumps/scripts/4259.cs2 @@ -0,0 +1,4 @@ +void script_4259(int arg0) { + script_4211(arg0, 4040, 15458492, 5918266); + return; +} diff --git a/dumps/scripts/426.cs2 b/dumps/scripts/426.cs2 new file mode 100644 index 0000000..bbe13c2 --- /dev/null +++ b/dumps/scripts/426.cs2 @@ -0,0 +1,4 @@ +void script_426() { + script_304(50122034); + return; +} diff --git a/dumps/scripts/4260.cs2 b/dumps/scripts/4260.cs2 new file mode 100644 index 0000000..ce8d396 --- /dev/null +++ b/dumps/scripts/4260.cs2 @@ -0,0 +1,4 @@ +void script_4260(int arg0) { + script_4530(arg0); + return; +} diff --git a/dumps/scripts/4261.cs2 b/dumps/scripts/4261.cs2 new file mode 100644 index 0000000..b5b05d8 --- /dev/null +++ b/dumps/scripts/4261.cs2 @@ -0,0 +1,4 @@ +void script_4261(int arg0) { + script_4531(arg0); + return; +} diff --git a/dumps/scripts/4262.cs2 b/dumps/scripts/4262.cs2 new file mode 100644 index 0000000..dacedd4 --- /dev/null +++ b/dumps/scripts/4262.cs2 @@ -0,0 +1,4 @@ +void script_4262(int arg0) { + script_4532(arg0); + return; +} diff --git a/dumps/scripts/4263.cs2 b/dumps/scripts/4263.cs2 new file mode 100644 index 0000000..f5ef3e7 --- /dev/null +++ b/dumps/scripts/4263.cs2 @@ -0,0 +1,5 @@ +void script_4263(int arg0,int arg1,int arg2) { + setWidgetPosition(arg1, arg2, 0, 0, new WidgetPointer(arg0)); + setWidgetIsHidden(false, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/4264.cs2 b/dumps/scripts/4264.cs2 new file mode 100644 index 0000000..b9cc6a6 --- /dev/null +++ b/dumps/scripts/4264.cs2 @@ -0,0 +1,6 @@ +void script_4264(int arg0) { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(arg0)); + setScriptCallOnMouseEntered(4265, new WidgetPointer(arg0), 14516095, "Ii", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(4265, new WidgetPointer(arg0), 16711680, "Ii", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/4265.cs2 b/dumps/scripts/4265.cs2 new file mode 100644 index 0000000..7f48bdb --- /dev/null +++ b/dumps/scripts/4265.cs2 @@ -0,0 +1,4 @@ +void script_4265(int arg0,int arg1) { + setWidgetRGB(new Color(arg1), new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/4266.cs2 b/dumps/scripts/4266.cs2 new file mode 100644 index 0000000..205c6ae --- /dev/null +++ b/dumps/scripts/4266.cs2 @@ -0,0 +1,21 @@ +void script_4266() { + script_4267(); + script_4274(); + setWidgetText(new WidgetPointer(1083,85), ""); + setWidgetText(new WidgetPointer(1083,87), "Select a reward for more information."); + setWidgetText(new WidgetPointer(1083,89), ""); + setWidgetIsHidden(true, new WidgetPointer(1083,90)); + setWidgetIsHidden(true, new WidgetPointer(1083,164)); + setWidgetIsHidden(true, new WidgetPointer(1083,159)); + setWidgetIsHidden(false, new WidgetPointer(1083,157)); + setWidgetIsHidden(false, new WidgetPointer(1083,158)); + setWidgetIsHidden(false, new WidgetPointer(1083,165)); + if (bitconfig_9067 < 11) { + script_4270(); + setWidgetText(new WidgetPointer(1083,85), "Spells"); + } else { + script_4272(); + setWidgetText(new WidgetPointer(1083,85), "Wishes"); + } + return; +} diff --git a/dumps/scripts/4267.cs2 b/dumps/scripts/4267.cs2 new file mode 100644 index 0000000..b1119e8 --- /dev/null +++ b/dumps/scripts/4267.cs2 @@ -0,0 +1,50 @@ +void script_4267() { + int ivar0; + ivar0 = multiply(bitconfig_9065, 10); + setWidgetText(new WidgetPointer(1083,201), script_46(ivar0, ",")); + if (bitconfig_9067 > 0) { + setWidgetSprite(-1, new WidgetPointer(1083,139)); + } + if (bitconfig_9067 > 1) { + setWidgetSprite(-1, new WidgetPointer(1083,135)); + } + if (bitconfig_9067 > 2) { + setWidgetSprite(-1, new WidgetPointer(1083,131)); + } + if (bitconfig_9067 > 3) { + setWidgetSprite(-1, new WidgetPointer(1083,127)); + } + if (bitconfig_9067 > 4) { + setWidgetSprite(-1, new WidgetPointer(1083,123)); + } + if (bitconfig_9067 > 5) { + setWidgetSprite(-1, new WidgetPointer(1083,119)); + } + if (bitconfig_9067 > 6) { + setWidgetSprite(-1, new WidgetPointer(1083,115)); + } + if (bitconfig_9067 > 7) { + setWidgetSprite(-1, new WidgetPointer(1083,111)); + } + if (bitconfig_9067 > 8) { + setWidgetSprite(-1, new WidgetPointer(1083,437)); + } + if (bitconfig_9067 > 9) { + setWidgetSprite(-1, new WidgetPointer(1083,448)); + } + if (bitconfig_9067 > 10) { + setWidgetSprite(-1, new WidgetPointer(1083,459)); + setWidgetSprite(-1, new WidgetPointer(1083,135)); + setWidgetSprite(-1, new WidgetPointer(1083,216)); + setWidgetSprite(-1, new WidgetPointer(1083,220)); + setWidgetSprite(-1, new WidgetPointer(1083,224)); + setWidgetSprite(-1, new WidgetPointer(1083,228)); + setWidgetSprite(-1, new WidgetPointer(1083,232)); + setWidgetSprite(-1, new WidgetPointer(1083,236)); + setWidgetSprite(-1, new WidgetPointer(1083,498)); + setWidgetSprite(-1, new WidgetPointer(1083,507)); + setWidgetSprite(-1, new WidgetPointer(1083,517)); + setWidgetSprite(-1, new WidgetPointer(1083,557)); + } + return; +} diff --git a/dumps/scripts/4268.cs2 b/dumps/scripts/4268.cs2 new file mode 100644 index 0000000..5c8661e --- /dev/null +++ b/dumps/scripts/4268.cs2 @@ -0,0 +1,405 @@ +void script_4268(int arg0) { + switch (arg0) { + case 1: + setWidgetText(new WidgetPointer(1083,85), "Teleport to South Falador"); + break; + case 2: + setWidgetText(new WidgetPointer(1083,85), "Repair Rune Pouch"); + break; + case 3: + setWidgetText(new WidgetPointer(1083,85), "Teleport to North Ardougne"); + break; + case 4: + setWidgetText(new WidgetPointer(1083,85), "Remote Farming"); + break; + case 5: + setWidgetText(new WidgetPointer(1083,85), "Spiritualise Food"); + break; + case 6: + setWidgetText(new WidgetPointer(1083,85), "Make Leather"); + break; + case 7: + setWidgetText(new WidgetPointer(1083,85), "Disruption Shield"); + break; + case 8: + setWidgetText(new WidgetPointer(1083,85), "Vengeance Group"); + break; + case 9: + setWidgetText(new WidgetPointer(1083,85), "Let it Rain Seeds!"); + break; + case 10: + setWidgetText(new WidgetPointer(1083,85), "Gimme Herbs!"); + break; + case 11: + setWidgetText(new WidgetPointer(1083,85), "Vial My Herbs!"); + break; + case 12: + setWidgetText(new WidgetPointer(1083,85), "Turn Lunar Lumber into Runes!"); + break; + case 13: + setWidgetText(new WidgetPointer(1083,85), "Reduce the Fish I Burn!"); + break; + case 14: + setWidgetText(new WidgetPointer(1083,85), "More Planks, Please!"); + break; + case 15: + setWidgetText(new WidgetPointer(1083,85), "Teleport to Trollheim"); + break; + case 16: + setWidgetText(new WidgetPointer(1083,85), "Teleport Group to Trollheim"); + break; + case 17: + setWidgetText(new WidgetPointer(1083,85), "Borrowed Power"); + break; + case 18: + setWidgetText(new WidgetPointer(1083,85), "Let it Rain Awesome Seeds!"); + break; + case 19: + setWidgetText(new WidgetPointer(1083,85), "I'd Like a New Patch!"); + break; + case 20: + setWidgetText(new WidgetPointer(1083,85), "Give Me An Arcane Capacitor!"); + break; + case 21: + setWidgetText(new WidgetPointer(1083,85), "Protect A Patch For Me!"); + } + switch (arg0) { + case 1: + setWidgetText(new WidgetPointer(1083,87), "Teleports you to the south of Falador."); + break; + case 2: + setWidgetText(new WidgetPointer(1083,87), "Use on a degraded pouch to repair it and improve its strength, so it takes longer to degrade."); + break; + case 3: + setWidgetText(new WidgetPointer(1083,87), "Teleports you to the north of Ardougne."); + break; + case 4: + setWidgetText(new WidgetPointer(1083,87), "View the status of farming patches and cure any disease from a distance."); + break; + case 5: + setWidgetText(new WidgetPointer(1083,87), "Cast on ordinary food and feed it to your familiar to heal it, boost its combat stats and extend its timer."); + break; + case 6: + setWidgetText(new WidgetPointer(1083,87), "Cast on hides to turn them into leather. This will convert 5 hides at a time."); + break; + case 7: + setWidgetText(new WidgetPointer(1083,87), "Nullifies the next hit you receive from another player. This works against players only, not against monsters."); + break; + case 8: + setWidgetText(new WidgetPointer(1083,87), "When cast, those nearby get to rebound damage." + "
" + "After learning this last spell, your current produce will be reduced by " + script_46(multiply(cs2method_3408(105, 105, 3674, 7), 10), ",") + " and the remainder can be spent on wishes."); + break; + case 9: + setWidgetText(new WidgetPointer(1083,87), "Seeds will appear on the floor. Be quick to pick up the ones you want."); + break; + case 10: + setWidgetText(new WidgetPointer(1083,87), "Puts a load of grimy herbs in your inventory."); + break; + case 11: + setWidgetText(new WidgetPointer(1083,87), "Takes all the clean herbs in your inventory and turns them into unfinished potions of that herb type. This will work on noted herbs of up to 50 at a time."); + break; + case 12: + setWidgetText(new WidgetPointer(1083,87), "Turns all lunar lumber in your inventory into runes. You'll need a full inventory of logs."); + break; + case 13: + setWidgetText(new WidgetPointer(1083,87), "For the next thirty minutes, you'll find that you burn fewer fish."); + break; + case 14: + setWidgetText(new WidgetPointer(1083,87), "This will be active for the next twenty minutes: when casting Plank Make, you will have a chance of receiving additional planks."); + break; + case 15: + setWidgetText(new WidgetPointer(1083,87), "Teleports you to the farming patch in Trollheim."); + break; + case 16: + setWidgetText(new WidgetPointer(1083,87), "Teleports you and those nearby to the farming patch in Trollheim."); + break; + case 17: + setWidgetText(new WidgetPointer(1083,87), "Allows you to store and cast certain spells from the standard spellbook."); + break; + case 18: + setWidgetText(new WidgetPointer(1083,87), "High value seeds will appear on the floor. Be quick to pick up the ones you want."); + break; + case 19: + setWidgetText(new WidgetPointer(1083,87), "A new allotment patch will become available nearby. It will vanish if the patch is cleared."); + break; + case 20: + setWidgetText(new WidgetPointer(1083,87), "You'll be given an Arcane Capacitor, for use with the Borrowed Power spell."); + break; + case 21: + if (bitconfig_9067 < 11) { + setWidgetText(new WidgetPointer(1083,87), "Gives you a scroll which, when used on a fruit tree or tree patch, will protect that patch for the next 10 growths in that patch. "); + } else { + setWidgetText(new WidgetPointer(1083,87), "Gives you a scroll which, when used on a fruit tree or tree patch, will protect that patch for the next 10 growths in that patch. You will need to use the scroll on a patch that is currently growing something and you must have the produce in your inventory that would cover the cost of protecting that patch normally."); + } + } + switch (arg0) { + case 1: + if (bitconfig_9067 < 1) { + setWidgetText(new WidgetPointer(1083,89), "Requires level 72 Magic to cast. You must unlock the spells in order."); + } else { + setWidgetText(new WidgetPointer(1083,89), "Learned!"); + } + break; + case 2: + if (bitconfig_9067 < 2) { + setWidgetText(new WidgetPointer(1083,89), "Requires level 75 Magic to cast. You must unlock the spells in order."); + } else { + setWidgetText(new WidgetPointer(1083,89), "Learned!"); + } + break; + case 3: + if (bitconfig_9067 < 3) { + setWidgetText(new WidgetPointer(1083,89), "Requires level 76 Magic to cast. You must unlock the spells in order."); + } else { + setWidgetText(new WidgetPointer(1083,89), "Learned!"); + } + break; + case 4: + if (bitconfig_9067 < 4) { + setWidgetText(new WidgetPointer(1083,89), "Requires level 78 Magic to cast. You must unlock the spells in order."); + } else { + setWidgetText(new WidgetPointer(1083,89), "Learned!"); + } + break; + case 5: + if (bitconfig_9067 < 5) { + setWidgetText(new WidgetPointer(1083,89), "Requires level 80 Magic to cast. You must unlock the spells in order."); + } else { + setWidgetText(new WidgetPointer(1083,89), "Learned!"); + } + break; + case 6: + if (bitconfig_9067 < 6) { + setWidgetText(new WidgetPointer(1083,89), "Requires level 83 Magic to cast. You must unlock the spells in order."); + } else { + setWidgetText(new WidgetPointer(1083,89), "Learned!"); + } + break; + case 7: + if (bitconfig_9067 < 7) { + setWidgetText(new WidgetPointer(1083,89), "Requires level 90 Magic to cast. You must unlock the spells in order."); + } else { + setWidgetText(new WidgetPointer(1083,89), "Learned!"); + } + break; + case 8: + if (bitconfig_9067 < 8) { + setWidgetText(new WidgetPointer(1083,89), "Requires level 95 Magic to cast. You must unlock the spells in order."); + } else { + setWidgetText(new WidgetPointer(1083,89), "Learned!"); + } + break; + case 15: + if (bitconfig_9067 < 9) { + setWidgetText(new WidgetPointer(1083,89), "Requires level 92 Magic to cast. You must unlock the spells in order."); + } else { + setWidgetText(new WidgetPointer(1083,89), "Learned!"); + } + break; + case 16: + if (bitconfig_9067 < 10) { + setWidgetText(new WidgetPointer(1083,89), "Requires level 93 Magic to cast. You must unlock the spells in order."); + } else { + setWidgetText(new WidgetPointer(1083,89), "Learned!"); + } + break; + case 17: + if (bitconfig_9067 < 11) { + setWidgetText(new WidgetPointer(1083,89), "Requires level 99 Magic to cast. You must unlock the spells in order."); + } else { + setWidgetText(new WidgetPointer(1083,89), "Learned!"); + } + break; + default: + if (bitconfig_9067 < 11) { + setWidgetText(new WidgetPointer(1083,89), "You must unlock all the spells before you can use wishes."); + } + } + if ((arg0 < 9) || ((arg0 > 14) && (arg0 < 18))) { + setWidgetIsHidden(false, new WidgetPointer(1083,90)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1083,90)); + } + switch (arg0) { + case 1: + setWidgetSprite(4585, new WidgetPointer(1083,93)); + break; + case 2: + setWidgetSprite(4586, new WidgetPointer(1083,93)); + break; + case 3: + setWidgetSprite(4587, new WidgetPointer(1083,93)); + break; + case 4: + setWidgetSprite(4588, new WidgetPointer(1083,93)); + break; + case 5: + setWidgetSprite(4590, new WidgetPointer(1083,93)); + break; + case 6: + setWidgetSprite(4589, new WidgetPointer(1083,93)); + break; + case 7: + setWidgetSprite(4591, new WidgetPointer(1083,93)); + break; + case 8: + setWidgetSprite(4592, new WidgetPointer(1083,93)); + break; + case 15: + setWidgetSprite(7685, new WidgetPointer(1083,93)); + break; + case 16: + setWidgetSprite(7686, new WidgetPointer(1083,93)); + break; + case 17: + setWidgetSprite(7687, new WidgetPointer(1083,93)); + } + setWidgetIsHidden(true, new WidgetPointer(1083,94)); + setWidgetIsHidden(true, new WidgetPointer(1083,95)); + setWidgetIsHidden(true, new WidgetPointer(1083,96)); + setWidgetIsHidden(true, new WidgetPointer(1083,97)); + setWidgetIsHidden(true, new WidgetPointer(1083,98)); + setWidgetIsHidden(true, new WidgetPointer(1083,99)); + setWidgetIsHidden(true, new WidgetPointer(1083,100)); + setWidgetIsHidden(true, new WidgetPointer(1083,101)); + setWidgetIsHidden(true, new WidgetPointer(1083,102)); + setWidgetIsHidden(true, new WidgetPointer(1083,103)); + setWidgetIsHidden(true, new WidgetPointer(1083,104)); + setWidgetIsHidden(true, new WidgetPointer(1083,105)); + setWidgetIsHidden(true, new WidgetPointer(1083,106)); + setWidgetIsHidden(true, new WidgetPointer(1083,107)); + setWidgetIsHidden(true, new WidgetPointer(1083,460)); + setWidgetIsHidden(true, new WidgetPointer(1083,470)); + setWidgetIsHidden(true, new WidgetPointer(1083,480)); + setWidgetIsHidden(true, new WidgetPointer(1083,518)); + setWidgetIsHidden(true, new WidgetPointer(1083,528)); + setWidgetIsHidden(true, new WidgetPointer(1083,538)); + setWidgetIsHidden(true, new WidgetPointer(1083,558)); + switch (arg0) { + case 1: + if (bitconfig_9067 < 1) { + setWidgetIsHidden(false, new WidgetPointer(1083,94)); + } + break; + case 2: + if (bitconfig_9067 < 2) { + setWidgetIsHidden(false, new WidgetPointer(1083,95)); + } + break; + case 3: + if (bitconfig_9067 < 3) { + setWidgetIsHidden(false, new WidgetPointer(1083,96)); + } + break; + case 4: + if (bitconfig_9067 < 4) { + setWidgetIsHidden(false, new WidgetPointer(1083,97)); + } + break; + case 5: + if (bitconfig_9067 < 5) { + setWidgetIsHidden(false, new WidgetPointer(1083,98)); + } + break; + case 6: + if (bitconfig_9067 < 6) { + setWidgetIsHidden(false, new WidgetPointer(1083,99)); + } + break; + case 7: + if (bitconfig_9067 < 7) { + setWidgetIsHidden(false, new WidgetPointer(1083,100)); + } + break; + case 8: + if (bitconfig_9067 < 8) { + setWidgetIsHidden(false, new WidgetPointer(1083,101)); + } + break; + case 9: + if (bitconfig_9067 > 10) { + setWidgetIsHidden(false, new WidgetPointer(1083,102)); + } + break; + case 10: + if (bitconfig_9067 > 10) { + setWidgetIsHidden(false, new WidgetPointer(1083,103)); + } + break; + case 11: + if (bitconfig_9067 > 10) { + setWidgetIsHidden(false, new WidgetPointer(1083,104)); + } + break; + case 12: + if (bitconfig_9067 > 10) { + setWidgetIsHidden(false, new WidgetPointer(1083,105)); + } + break; + case 13: + if (bitconfig_9067 > 10) { + setWidgetIsHidden(false, new WidgetPointer(1083,106)); + } + break; + case 14: + if (bitconfig_9067 > 10) { + setWidgetIsHidden(false, new WidgetPointer(1083,107)); + } + break; + case 15: + if (bitconfig_9067 < 9) { + setWidgetIsHidden(false, new WidgetPointer(1083,460)); + } + break; + case 16: + if (bitconfig_9067 < 10) { + setWidgetIsHidden(false, new WidgetPointer(1083,470)); + } + break; + case 17: + if (bitconfig_9067 < 11) { + setWidgetIsHidden(false, new WidgetPointer(1083,480)); + } + break; + case 18: + if (bitconfig_9067 > 10) { + setWidgetIsHidden(false, new WidgetPointer(1083,518)); + } + break; + case 19: + if (bitconfig_9067 > 10) { + setWidgetIsHidden(false, new WidgetPointer(1083,528)); + } + break; + case 20: + if (bitconfig_9067 > 10) { + setWidgetIsHidden(false, new WidgetPointer(1083,538)); + } + break; + case 21: + if (bitconfig_9067 > 10) { + setWidgetIsHidden(false, new WidgetPointer(1083,558)); + } + } + setWidgetIsHidden(true, new WidgetPointer(1083,385)); + setWidgetIsHidden(true, new WidgetPointer(1083,72)); + setWidgetIsHidden(true, new WidgetPointer(1083,67)); + setWidgetIsHidden(true, new WidgetPointer(1083,62)); + setWidgetIsHidden(true, new WidgetPointer(1083,57)); + setWidgetIsHidden(true, new WidgetPointer(1083,52)); + setWidgetIsHidden(true, new WidgetPointer(1083,47)); + setWidgetIsHidden(true, new WidgetPointer(1083,42)); + setWidgetIsHidden(true, new WidgetPointer(1083,37)); + setWidgetIsHidden(true, new WidgetPointer(1083,32)); + setWidgetIsHidden(true, new WidgetPointer(1083,27)); + setWidgetIsHidden(true, new WidgetPointer(1083,22)); + setWidgetIsHidden(true, new WidgetPointer(1083,17)); + setWidgetIsHidden(true, new WidgetPointer(1083,12)); + setWidgetIsHidden(true, new WidgetPointer(1083,431)); + setWidgetIsHidden(true, new WidgetPointer(1083,442)); + setWidgetIsHidden(true, new WidgetPointer(1083,453)); + setWidgetIsHidden(true, new WidgetPointer(1083,493)); + setWidgetIsHidden(true, new WidgetPointer(1083,502)); + setWidgetIsHidden(true, new WidgetPointer(1083,512)); + setWidgetIsHidden(true, new WidgetPointer(1083,552)); + return; +} diff --git a/dumps/scripts/4269.cs2 b/dumps/scripts/4269.cs2 new file mode 100644 index 0000000..592e6d5 --- /dev/null +++ b/dumps/scripts/4269.cs2 @@ -0,0 +1,4 @@ +void script_4269() { + script_4270(); + return; +} diff --git a/dumps/scripts/427.cs2 b/dumps/scripts/427.cs2 new file mode 100644 index 0000000..71618f1 --- /dev/null +++ b/dumps/scripts/427.cs2 @@ -0,0 +1,184 @@ +void script_427(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + ivar1 = 0; + ivar2 = 0; + ivar3 = -1; + ivar4 = bitconfig_7539; + ivar5 = bitconfig_7540; + ivar6 = bitconfig_7541; + ivar7 = bitconfig_7542; + if (((boolean)arg0)) { + ivar4 = 1; + ivar5 = 3; + ivar6 = 5; + ivar7 = 6; + } + if (((boolean)ivar4)) { + setWidgetIsHidden(true, new WidgetPointer(1024,8)); + ivar1 = add(ivar1, 1); + } else { + ivar3 = script_488(ivar4); + if (ivar3 != -1) { + setWidgetIsHidden(false, new WidgetPointer(1024,8)); + cs2method2305(new WidgetPointer(1024,8), getOtherCommonData(ivar3, 1150)); + setWidgetText(new WidgetPointer(1024,75), getOtherCommonData(ivar3, 1150)); + setWidgetSprite(getOtherCommonData(ivar3, 1153), new WidgetPointer(1024,77)); + setWidgetText(new WidgetPointer(1024,76), intToStr(getOtherCommonData(ivar3, 1154))); + } + if (ivar4 == 9) { + setWidgetContextMenuOption(1, new WidgetPointer(1024,8), "Cast"); + } + } + if (((boolean)ivar5)) { + setWidgetIsHidden(true, new WidgetPointer(1024,9)); + ivar1 = add(ivar1, 1); + } else { + ivar3 = script_488(ivar5); + if (ivar3 != -1) { + setWidgetIsHidden(false, new WidgetPointer(1024,9)); + cs2method2305(new WidgetPointer(1024,9), getOtherCommonData(ivar3, 1150)); + setWidgetText(new WidgetPointer(1024,58), getOtherCommonData(ivar3, 1150)); + setWidgetSprite(getOtherCommonData(ivar3, 1153), new WidgetPointer(1024,60)); + setWidgetText(new WidgetPointer(1024,59), intToStr(getOtherCommonData(ivar3, 1154))); + } + if (ivar5 == 9) { + setWidgetContextMenuOption(1, new WidgetPointer(1024,9), "Cast"); + } + } + if (((boolean)ivar6)) { + setWidgetIsHidden(true, new WidgetPointer(1024,10)); + ivar1 = add(ivar1, 1); + } else { + ivar3 = script_488(ivar6); + if (ivar3 != -1) { + setWidgetIsHidden(false, new WidgetPointer(1024,10)); + cs2method2305(new WidgetPointer(1024,10), getOtherCommonData(ivar3, 1150)); + setWidgetText(new WidgetPointer(1024,41), getOtherCommonData(ivar3, 1150)); + setWidgetSprite(getOtherCommonData(ivar3, 1153), new WidgetPointer(1024,43)); + setWidgetText(new WidgetPointer(1024,42), intToStr(getOtherCommonData(ivar3, 1154))); + } + if (ivar6 == 9) { + setWidgetContextMenuOption(1, new WidgetPointer(1024,10), "Cast"); + } + } + if (((boolean)ivar7)) { + setWidgetIsHidden(true, new WidgetPointer(1024,11)); + ivar1 = add(ivar1, 1); + } else { + ivar3 = script_488(ivar7); + if (ivar3 != -1) { + setWidgetIsHidden(false, new WidgetPointer(1024,11)); + cs2method2305(new WidgetPointer(1024,11), getOtherCommonData(ivar3, 1150)); + setWidgetText(new WidgetPointer(1024,24), getOtherCommonData(ivar3, 1150)); + setWidgetSprite(getOtherCommonData(ivar3, 1153), new WidgetPointer(1024,26)); + setWidgetText(new WidgetPointer(1024,25), intToStr(getOtherCommonData(ivar3, 1154))); + } + if (ivar7 == 9) { + setWidgetContextMenuOption(1, new WidgetPointer(1024,11), "Cast"); + } + } + if (ivar1 == 4) { + setWidgetIsHidden(true, new WidgetPointer(1024,1)); + setWidgetIsHidden(false, new WidgetPointer(1024,2)); + } else if (ivar1 == 3) { + setWidgetIsHidden(false, new WidgetPointer(1024,1)); + setWidgetIsHidden(true, new WidgetPointer(1024,2)); + if (ivar4 != 0) { + setWidgetPosition(getWidgetActualX(new WidgetPointer(1024,8)), 102, 0, 0, new WidgetPointer(1024,8)); + setScriptCallOnMouseOver(432, new WidgetPointer(-32768,3), 6, "Ii", new WidgetPointer(1024,65)); + } else if (ivar5 != 0) { + setWidgetPosition(getWidgetActualX(new WidgetPointer(1024,9)), 102, 0, 0, new WidgetPointer(1024,9)); + setScriptCallOnMouseOver(432, new WidgetPointer(-32768,3), 6, "Ii", new WidgetPointer(1024,48)); + } else if (ivar6 != 0) { + setWidgetPosition(getWidgetActualX(new WidgetPointer(1024,10)), 102, 0, 0, new WidgetPointer(1024,10)); + setScriptCallOnMouseOver(432, new WidgetPointer(-32768,3), 6, "Ii", new WidgetPointer(1024,31)); + } else { + if (ivar7 != 0) { + setWidgetPosition(getWidgetActualX(new WidgetPointer(1024,11)), 102, 0, 0, new WidgetPointer(1024,11)); + setScriptCallOnMouseOver(432, new WidgetPointer(-32768,3), 6, "Ii", new WidgetPointer(1024,14)); + } + } + } else if (ivar1 == 2) { + setWidgetIsHidden(false, new WidgetPointer(1024,1)); + setWidgetIsHidden(true, new WidgetPointer(1024,2)); + if (ivar4 != 0) { + setWidgetPosition(getWidgetActualX(new WidgetPointer(1024,8)), 60, 0, 0, new WidgetPointer(1024,8)); + setScriptCallOnMouseOver(432, new WidgetPointer(-32768,3), 111, "Ii", new WidgetPointer(1024,65)); + ivar2 = add(ivar2, 1); + } + if (ivar5 != 0) { + if (((boolean)ivar2)) { + setWidgetPosition(getWidgetActualX(new WidgetPointer(1024,9)), 60, 0, 0, new WidgetPointer(1024,9)); + setScriptCallOnMouseOver(432, new WidgetPointer(-32768,3), 111, "Ii", new WidgetPointer(1024,48)); + } else { + setWidgetPosition(getWidgetActualX(new WidgetPointer(1024,9)), 145, 0, 0, new WidgetPointer(1024,9)); + setScriptCallOnMouseOver(432, new WidgetPointer(-32768,3), 49, "Ii", new WidgetPointer(1024,48)); + } + ivar2 = add(ivar2, 1); + } + if (ivar6 != 0) { + if (((boolean)ivar2)) { + setWidgetPosition(getWidgetActualX(new WidgetPointer(1024,10)), 60, 0, 0, new WidgetPointer(1024,10)); + setScriptCallOnMouseOver(432, new WidgetPointer(-32768,3), 111, "Ii", new WidgetPointer(1024,31)); + } else { + setWidgetPosition(getWidgetActualX(new WidgetPointer(1024,10)), 145, 0, 0, new WidgetPointer(1024,10)); + setScriptCallOnMouseOver(432, new WidgetPointer(-32768,3), 49, "Ii", new WidgetPointer(1024,31)); + } + ivar2 = add(ivar2, 1); + } + if (ivar7 != 0) { + setWidgetPosition(getWidgetActualX(new WidgetPointer(1024,11)), 145, 0, 0, new WidgetPointer(1024,11)); + setScriptCallOnMouseOver(432, new WidgetPointer(-32768,3), 49, "Ii", new WidgetPointer(1024,14)); + } + } else if (((boolean)ivar1)) { + setWidgetIsHidden(false, new WidgetPointer(1024,1)); + setWidgetIsHidden(true, new WidgetPointer(1024,2)); + if (ivar4 != 0) { + setWidgetPosition(getWidgetActualX(new WidgetPointer(1024,8)), 41, 0, 0, new WidgetPointer(1024,8)); + setScriptCallOnMouseOver(432, new WidgetPointer(-32768,3), 92, "Ii", new WidgetPointer(1024,65)); + ivar2 = add(ivar2, 1); + } + if (ivar5 != 0) { + if (((boolean)ivar2)) { + setWidgetPosition(getWidgetActualX(new WidgetPointer(1024,9)), 41, 0, 0, new WidgetPointer(1024,9)); + setScriptCallOnMouseOver(432, new WidgetPointer(-32768,3), 92, "Ii", new WidgetPointer(1024,48)); + } else { + setWidgetPosition(getWidgetActualX(new WidgetPointer(1024,9)), 102, 0, 0, new WidgetPointer(1024,9)); + setScriptCallOnMouseOver(432, new WidgetPointer(-32768,3), 6, "Ii", new WidgetPointer(1024,48)); + } + ivar2 = add(ivar2, 1); + } + if (ivar6 != 0) { + if (((boolean)ivar2)) { + setWidgetPosition(getWidgetActualX(new WidgetPointer(1024,10)), 102, 0, 0, new WidgetPointer(1024,10)); + setScriptCallOnMouseOver(432, new WidgetPointer(-32768,3), 6, "Ii", new WidgetPointer(1024,31)); + } else { + setWidgetPosition(getWidgetActualX(new WidgetPointer(1024,10)), 163, 0, 0, new WidgetPointer(1024,10)); + setScriptCallOnMouseOver(432, new WidgetPointer(-32768,3), 67, "Ii", new WidgetPointer(1024,31)); + } + ivar2 = add(ivar2, 1); + } + if (ivar7 != 0) { + setWidgetPosition(getWidgetActualX(new WidgetPointer(1024,11)), 163, 0, 0, new WidgetPointer(1024,11)); + setScriptCallOnMouseOver(432, new WidgetPointer(-32768,3), 67, "Ii", new WidgetPointer(1024,31)); + } + } else { + setWidgetIsHidden(false, new WidgetPointer(1024,1)); + setWidgetIsHidden(true, new WidgetPointer(1024,2)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(1024,8)), 29, 0, 0, new WidgetPointer(1024,8)); + setScriptCallOnMouseOver(432, new WidgetPointer(-32768,3), 80, "Ii", new WidgetPointer(1024,65)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(1024,9)), 78, 0, 0, new WidgetPointer(1024,9)); + setScriptCallOnMouseOver(432, new WidgetPointer(-32768,3), 129, "Ii", new WidgetPointer(1024,48)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(1024,10)), 127, 0, 0, new WidgetPointer(1024,10)); + setScriptCallOnMouseOver(432, new WidgetPointer(-32768,3), 31, "Ii", new WidgetPointer(1024,31)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(1024,11)), 176, 0, 0, new WidgetPointer(1024,11)); + setScriptCallOnMouseOver(432, new WidgetPointer(-32768,3), 80, "Ii", new WidgetPointer(1024,14)); + } + return; +} diff --git a/dumps/scripts/4270.cs2 b/dumps/scripts/4270.cs2 new file mode 100644 index 0000000..4d40ec9 --- /dev/null +++ b/dumps/scripts/4270.cs2 @@ -0,0 +1,31 @@ +void script_4270() { + setWidgetIsHidden(false, new WidgetPointer(1083,161)); + setWidgetIsHidden(true, new WidgetPointer(1083,162)); + setWidgetIsHidden(false, new WidgetPointer(1083,243)); + setWidgetIsHidden(true, new WidgetPointer(1083,253)); + setWidgetText(new WidgetPointer(1083,85), "Spells"); + setWidgetText(new WidgetPointer(1083,87), "Select a reward for more information."); + setWidgetText(new WidgetPointer(1083,89), ""); + setWidgetIsHidden(true, new WidgetPointer(1083,90)); + setWidgetIsHidden(true, new WidgetPointer(1083,94)); + setWidgetIsHidden(true, new WidgetPointer(1083,95)); + setWidgetIsHidden(true, new WidgetPointer(1083,96)); + setWidgetIsHidden(true, new WidgetPointer(1083,97)); + setWidgetIsHidden(true, new WidgetPointer(1083,98)); + setWidgetIsHidden(true, new WidgetPointer(1083,99)); + setWidgetIsHidden(true, new WidgetPointer(1083,100)); + setWidgetIsHidden(true, new WidgetPointer(1083,101)); + setWidgetIsHidden(true, new WidgetPointer(1083,102)); + setWidgetIsHidden(true, new WidgetPointer(1083,103)); + setWidgetIsHidden(true, new WidgetPointer(1083,104)); + setWidgetIsHidden(true, new WidgetPointer(1083,105)); + setWidgetIsHidden(true, new WidgetPointer(1083,106)); + setWidgetIsHidden(true, new WidgetPointer(1083,107)); + setWidgetIsHidden(true, new WidgetPointer(1083,164)); + setWidgetIsHidden(true, new WidgetPointer(1083,159)); + setWidgetIsHidden(false, new WidgetPointer(1083,157)); + setWidgetIsHidden(false, new WidgetPointer(1083,158)); + setWidgetIsHidden(false, new WidgetPointer(1083,165)); + setWidgetIsHidden(false, new WidgetPointer(1083,160)); + return; +} diff --git a/dumps/scripts/4271.cs2 b/dumps/scripts/4271.cs2 new file mode 100644 index 0000000..e926c84 --- /dev/null +++ b/dumps/scripts/4271.cs2 @@ -0,0 +1,4 @@ +void script_4271() { + script_4272(); + return; +} diff --git a/dumps/scripts/4272.cs2 b/dumps/scripts/4272.cs2 new file mode 100644 index 0000000..acd21c9 --- /dev/null +++ b/dumps/scripts/4272.cs2 @@ -0,0 +1,31 @@ +void script_4272() { + setWidgetIsHidden(true, new WidgetPointer(1083,161)); + setWidgetIsHidden(false, new WidgetPointer(1083,162)); + setWidgetIsHidden(true, new WidgetPointer(1083,243)); + setWidgetIsHidden(false, new WidgetPointer(1083,253)); + setWidgetText(new WidgetPointer(1083,85), "Wishes"); + setWidgetText(new WidgetPointer(1083,87), "Select a reward for more information."); + setWidgetText(new WidgetPointer(1083,89), ""); + setWidgetIsHidden(true, new WidgetPointer(1083,90)); + setWidgetIsHidden(true, new WidgetPointer(1083,94)); + setWidgetIsHidden(true, new WidgetPointer(1083,95)); + setWidgetIsHidden(true, new WidgetPointer(1083,96)); + setWidgetIsHidden(true, new WidgetPointer(1083,97)); + setWidgetIsHidden(true, new WidgetPointer(1083,98)); + setWidgetIsHidden(true, new WidgetPointer(1083,99)); + setWidgetIsHidden(true, new WidgetPointer(1083,100)); + setWidgetIsHidden(true, new WidgetPointer(1083,101)); + setWidgetIsHidden(true, new WidgetPointer(1083,102)); + setWidgetIsHidden(true, new WidgetPointer(1083,103)); + setWidgetIsHidden(true, new WidgetPointer(1083,104)); + setWidgetIsHidden(true, new WidgetPointer(1083,105)); + setWidgetIsHidden(true, new WidgetPointer(1083,106)); + setWidgetIsHidden(true, new WidgetPointer(1083,107)); + setWidgetIsHidden(true, new WidgetPointer(1083,164)); + setWidgetIsHidden(true, new WidgetPointer(1083,159)); + setWidgetIsHidden(false, new WidgetPointer(1083,157)); + setWidgetIsHidden(false, new WidgetPointer(1083,158)); + setWidgetIsHidden(false, new WidgetPointer(1083,165)); + setWidgetIsHidden(true, new WidgetPointer(1083,160)); + return; +} diff --git a/dumps/scripts/4273.cs2 b/dumps/scripts/4273.cs2 new file mode 100644 index 0000000..292407a --- /dev/null +++ b/dumps/scripts/4273.cs2 @@ -0,0 +1,56 @@ +void script_4273() { + setWidgetIsHidden(true, new WidgetPointer(1083,161)); + setWidgetIsHidden(true, new WidgetPointer(1083,160)); + setWidgetIsHidden(true, new WidgetPointer(1083,162)); + setWidgetIsHidden(false, new WidgetPointer(1083,164)); + setWidgetIsHidden(true, new WidgetPointer(1083,157)); + setWidgetIsHidden(true, new WidgetPointer(1083,158)); + setWidgetIsHidden(false, new WidgetPointer(1083,159)); + setWidgetIsHidden(true, new WidgetPointer(1083,243)); + setWidgetIsHidden(true, new WidgetPointer(1083,253)); + setWidgetIsHidden(false, new WidgetPointer(1083,394)); + setWidgetIsHidden(true, new WidgetPointer(1083,165)); + setWidgetText(new WidgetPointer(1083,415), intToStr(multiply(2, 10))); + if (getSkillActualLvl(6) < 83) { + setWidgetText(new WidgetPointer(1083,416), intToStr(multiply(divide(2, 2), 10)) + " (halved)"); + } else { + setWidgetText(new WidgetPointer(1083,416), intToStr(multiply(2, 10))); + } + if (getSkillActualLvl(6) < 80) { + setWidgetText(new WidgetPointer(1083,417), intToStr(multiply(divide(12, 2), 10)) + " (halved)"); + } else { + setWidgetText(new WidgetPointer(1083,417), intToStr(multiply(12, 10))); + } + if (getSkillActualLvl(6) < 86) { + setWidgetText(new WidgetPointer(1083,418), intToStr(multiply(divide(2, 2), 10)) + " (halved)"); + } else { + setWidgetText(new WidgetPointer(1083,418), intToStr(multiply(2, 10))); + } + if (getSkillActualLvl(6) < 91) { + setWidgetText(new WidgetPointer(1083,419), intToStr(multiply(divide(10, 2), 10)) + " (halved)"); + } else { + setWidgetText(new WidgetPointer(1083,419), intToStr(multiply(10, 10))); + } + setWidgetText(new WidgetPointer(1083,420), "Magic and Farming"); + if (getSkillActualLvl(6) < 83) { + setWidgetText(new WidgetPointer(1083,421), "Farming (no Magic)"); + } else { + setWidgetText(new WidgetPointer(1083,421), "Magic and Farming"); + } + if (getSkillActualLvl(6) < 80) { + setWidgetText(new WidgetPointer(1083,422), "Crafting (no Magic)"); + } else { + setWidgetText(new WidgetPointer(1083,422), "Magic and Crafting"); + } + if (getSkillActualLvl(6) < 86) { + setWidgetText(new WidgetPointer(1083,423), "Construction (no Magic)"); + } else { + setWidgetText(new WidgetPointer(1083,423), "Magic and Construction"); + } + if (getSkillActualLvl(6) < 91) { + setWidgetText(new WidgetPointer(1083,424), "Agility (no Magic)"); + } else { + setWidgetText(new WidgetPointer(1083,424), "Magic and Agility"); + } + return; +} diff --git a/dumps/scripts/4274.cs2 b/dumps/scripts/4274.cs2 new file mode 100644 index 0000000..ff1a557 --- /dev/null +++ b/dumps/scripts/4274.cs2 @@ -0,0 +1,24 @@ +void script_4274() { + setWidgetText(new WidgetPointer(1083,137), script_46(multiply(cs2method_3408(105, 105, 3674, 0), 10), ",")); + setWidgetText(new WidgetPointer(1083,133), script_46(multiply(cs2method_3408(105, 105, 3674, 1), 10), ",")); + setWidgetText(new WidgetPointer(1083,129), script_46(multiply(cs2method_3408(105, 105, 3674, 2), 10), ",")); + setWidgetText(new WidgetPointer(1083,125), script_46(multiply(cs2method_3408(105, 105, 3674, 3), 10), ",")); + setWidgetText(new WidgetPointer(1083,121), script_46(multiply(cs2method_3408(105, 105, 3674, 4), 10), ",")); + setWidgetText(new WidgetPointer(1083,117), script_46(multiply(cs2method_3408(105, 105, 3674, 5), 10), ",")); + setWidgetText(new WidgetPointer(1083,113), script_46(multiply(cs2method_3408(105, 105, 3674, 6), 10), ",")); + setWidgetText(new WidgetPointer(1083,109), script_46(multiply(cs2method_3408(105, 105, 3674, 7), 10), ",")); + setWidgetText(new WidgetPointer(1083,223), script_46(multiply(550, 10), ",")); + setWidgetText(new WidgetPointer(1083,219), script_46(multiply(1800, 10), ",")); + setWidgetText(new WidgetPointer(1083,215), script_46(multiply(1800, 10), ",")); + setWidgetText(new WidgetPointer(1083,227), script_46(multiply(550, 10), ",")); + setWidgetText(new WidgetPointer(1083,235), script_46(multiply(1800, 10), ",")); + setWidgetText(new WidgetPointer(1083,231), script_46(multiply(1800, 10), ",")); + setWidgetText(new WidgetPointer(1083,435), script_46(multiply(cs2method_3408(105, 105, 3674, 8), 10), ",")); + setWidgetText(new WidgetPointer(1083,446), script_46(multiply(cs2method_3408(105, 105, 3674, 9), 10), ",")); + setWidgetText(new WidgetPointer(1083,457), script_46(multiply(cs2method_3408(105, 105, 3674, 10), 10), ",")); + setWidgetText(new WidgetPointer(1083,497), script_46(multiply(5500, 10), ",")); + setWidgetText(new WidgetPointer(1083,506), script_46(multiply(1800, 10), ",")); + setWidgetText(new WidgetPointer(1083,516), script_46(multiply(1800, 10), ",")); + setWidgetText(new WidgetPointer(1083,556), script_46(multiply(3700, 10), ",")); + return; +} diff --git a/dumps/scripts/4275.cs2 b/dumps/scripts/4275.cs2 new file mode 100644 index 0000000..ebbbefb --- /dev/null +++ b/dumps/scripts/4275.cs2 @@ -0,0 +1,7 @@ +void script_4275() { + setWidgetAnimation(8016, new WidgetPointer(1081,7)); + setWidgetAnimation(8016, new WidgetPointer(1081,2)); + setWidgetAnimation(4407, new WidgetPointer(1081,1)); + setWidgetAnimation(8016, new WidgetPointer(1081,0)); + return; +} diff --git a/dumps/scripts/4276.cs2 b/dumps/scripts/4276.cs2 new file mode 100644 index 0000000..65470be --- /dev/null +++ b/dumps/scripts/4276.cs2 @@ -0,0 +1,4 @@ +void script_4276() { + setScriptCallOnConfigChange(4277, 2151, 1, "Y", new WidgetPointer(1088,13)); + return; +} diff --git a/dumps/scripts/4277.cs2 b/dumps/scripts/4277.cs2 new file mode 100644 index 0000000..170d005 --- /dev/null +++ b/dumps/scripts/4277.cs2 @@ -0,0 +1,19 @@ +void script_4277() { + int ivar0; + string svar0; + string svar1; + ivar0 = divide(multiply(bitconfig_9186, 6), 10); + svar0 = intToStr(divide(ivar0, 60)); + svar1 = intToStr(mod(ivar0, 60)); + if (strLength(svar1) < 2) { + svar1 = concat("0", svar1); + } + if (((boolean)bitconfig_9187)) { + setWidgetText(new WidgetPointer(1088,12), "Match Starts In:"); + setWidgetText(new WidgetPointer(1088,13), svar0 + ":" + svar1); + } else { + setWidgetText(new WidgetPointer(1088,12), "Time Remaining:"); + setWidgetText(new WidgetPointer(1088,13), svar0 + ":" + svar1); + } + return; +} diff --git a/dumps/scripts/4278.cs2 b/dumps/scripts/4278.cs2 new file mode 100644 index 0000000..ce6c6f2 --- /dev/null +++ b/dumps/scripts/4278.cs2 @@ -0,0 +1,4 @@ +void script_4278() { + script_4212(71172125, 4040, 15458492, 5918266, "Refresh"); + return; +} diff --git a/dumps/scripts/4279.cs2 b/dumps/scripts/4279.cs2 new file mode 100644 index 0000000..8460f2b --- /dev/null +++ b/dumps/scripts/4279.cs2 @@ -0,0 +1,4 @@ +void script_4279() { + script_4212(71172125, 4040, 15458492, 5918266, "Log In"); + return; +} diff --git a/dumps/scripts/428.cs2 b/dumps/scripts/428.cs2 new file mode 100644 index 0000000..b3cd505 --- /dev/null +++ b/dumps/scripts/428.cs2 @@ -0,0 +1,4 @@ +void script_428() { + setWidgetText(new WidgetPointer(1024,5), "Command Points: " + intToStr(bitconfig_7514)); + return; +} diff --git a/dumps/scripts/4280.cs2 b/dumps/scripts/4280.cs2 new file mode 100644 index 0000000..d9ed7a0 --- /dev/null +++ b/dumps/scripts/4280.cs2 @@ -0,0 +1,4 @@ +void script_4280() { + script_4212(71172125, 4040, 15458492, 5918266, "Confirm"); + return; +} diff --git a/dumps/scripts/4281.cs2 b/dumps/scripts/4281.cs2 new file mode 100644 index 0000000..0625a46 --- /dev/null +++ b/dumps/scripts/4281.cs2 @@ -0,0 +1,8 @@ +void script_4281() { + if (cs2method3700()) { + script_4283(); + } else { + setScriptCallOnClanChatSettingsStuff(4282, "", new WidgetPointer(1095,8)); + } + return; +} diff --git a/dumps/scripts/4282.cs2 b/dumps/scripts/4282.cs2 new file mode 100644 index 0000000..f807637 --- /dev/null +++ b/dumps/scripts/4282.cs2 @@ -0,0 +1,6 @@ +void script_4282() { + if (cs2method3700()) { + script_4283(); + } + return; +} diff --git a/dumps/scripts/4283.cs2 b/dumps/scripts/4283.cs2 new file mode 100644 index 0000000..a860ed7 --- /dev/null +++ b/dumps/scripts/4283.cs2 @@ -0,0 +1,8 @@ +void script_4283() { + setWidgetText(new WidgetPointer(1095,28), cs2method3702()); + script_4332(71761970, 71761980); + script_4334(71761990, 71761991); + script_4329(71761949); + setWidgetIsHidden(true, new WidgetPointer(1095,5)); + return; +} diff --git a/dumps/scripts/4284.cs2 b/dumps/scripts/4284.cs2 new file mode 100644 index 0000000..974be26 --- /dev/null +++ b/dumps/scripts/4284.cs2 @@ -0,0 +1,6 @@ +void script_4284(int arg0,int arg1,int arg2) { + setScriptCallOnKeyPress(4285, new WidgetPointer(arg0), new WidgetPointer(arg1), false, -2147483640, new WidgetPointer(arg2), "IIziI", new WidgetPointer(arg0)); + setScriptCallOnMousePressed(4286, new WidgetPointer(arg0), new WidgetPointer(arg2), -2147483647, "IIi", new WidgetPointer(arg0)); + setScriptCallOnGameloop(1400, getClientCycle(), new WidgetPointer(arg2), "iI", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/4285.cs2 b/dumps/scripts/4285.cs2 new file mode 100644 index 0000000..0dccd2c --- /dev/null +++ b/dumps/scripts/4285.cs2 @@ -0,0 +1,40 @@ +void script_4285(int arg0,int arg1,int arg2,int arg3,int arg4) { + globalstring_348 = getWidgetText(new WidgetPointer(arg0)); + switch (arg3) { + case 84: + if (stringMethod4107("", globalstring_348) != 0) { + script_4288(); + } + break; + case 102: + case 103: + case 98: + case 99: + case 96: + case 97: + if (isHoldingCtrl()) { + return; + } + script_1553(arg3, globalint_1504, globalstring_348); + break; + case 85: + if (strLength(globalstring_348) > 0) { + globalstring_348 = substr(0, subtract(strLength(globalstring_348), 1), globalstring_348); + } + break; + default: + if (strLength(globalstring_348) < 20) { + globalstring_348 = script_74(0, arg3, arg2, globalstring_348); + } + } + globalint_1504 = script_1552(globalint_1504, 5631, arg0, -1, globalstring_348); + setWidgetPosition(globalint_1504, getWidgetActualY(new WidgetPointer(arg4)), 0, 0, new WidgetPointer(arg4)); + setWidgetText(new WidgetPointer(arg1), intToStr(strLength(globalstring_348)) + "/20"); + if (strLength(globalstring_348) >= 15) { + setWidgetRGB(new Color(221, 0, 0), new WidgetPointer(arg1)); + } else { + setWidgetRGB(new Color(31, 29, 25), new WidgetPointer(arg1)); + } + setWidgetText(new WidgetPointer(arg0), globalstring_348); + return; +} diff --git a/dumps/scripts/4286.cs2 b/dumps/scripts/4286.cs2 new file mode 100644 index 0000000..52feb00 --- /dev/null +++ b/dumps/scripts/4286.cs2 @@ -0,0 +1,6 @@ +void script_4286(int arg0,int arg1,int arg2) { + globalstring_348 = getWidgetText(new WidgetPointer(arg0)); + globalint_1504 = script_1552(arg2, 5631, arg0, -1, globalstring_348); + setWidgetPosition(globalint_1504, 5, 0, 0, new WidgetPointer(arg1)); + return; +} diff --git a/dumps/scripts/4287.cs2 b/dumps/scripts/4287.cs2 new file mode 100644 index 0000000..17cd656 --- /dev/null +++ b/dumps/scripts/4287.cs2 @@ -0,0 +1,4 @@ +void script_4287() { + script_4288(); + return; +} diff --git a/dumps/scripts/4288.cs2 b/dumps/scripts/4288.cs2 new file mode 100644 index 0000000..0d97a8c --- /dev/null +++ b/dumps/scripts/4288.cs2 @@ -0,0 +1,4 @@ +void script_4288() { + sendStringInput(globalstring_348); + return; +} diff --git a/dumps/scripts/4289.cs2 b/dumps/scripts/4289.cs2 new file mode 100644 index 0000000..1ffe923 --- /dev/null +++ b/dumps/scripts/4289.cs2 @@ -0,0 +1,11 @@ +void script_4289() { + if (cs2method3701()) { + script_4291(); + } else { + setScriptCallOnClanChatSettingsStuff(4290, "", new WidgetPointer(1096,151)); + } + if (globalint_1516 == -1) { + globalint_1516 = 0; + } + return; +} diff --git a/dumps/scripts/429.cs2 b/dumps/scripts/429.cs2 new file mode 100644 index 0000000..430cb6c --- /dev/null +++ b/dumps/scripts/429.cs2 @@ -0,0 +1,159 @@ +void script_429(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + flow_0: + ivar1 = 0; + ivar2 = 0; + ivar3 = -1; + ivar4 = -1; + ivar5 = -1; + ivar6 = -1; + ivar7 = 0; + ivar8 = -1; + SWITCH (arg0) { + case 67108940: + GOTO flow_1 + case 67108942: + GOTO flow_1 + case 67108925: + GOTO flow_5 + case 67108923: + GOTO flow_5 + case 67108908: + GOTO flow_9 + case 67108906: + GOTO flow_9 + case 67108889: + GOTO flow_13 + case 67108891: + GOTO flow_13 + } + return; + flow_1: + if (((boolean)globalint_1388)) { + ivar1 = 1; + } else { + ivar1 = bitconfig_7539; + } + ivar3 = 67108941; + ivar4 = 67108943; + ivar5 = 67108939; + ivar6 = 67108940; + ivar8 = 67108942; + GOTO flow_17 + flow_5: + if (((boolean)globalint_1388)) { + ivar1 = 3; + } else { + ivar1 = bitconfig_7540; + } + ivar3 = 67108924; + ivar4 = 67108926; + ivar5 = 67108922; + ivar6 = 67108923; + ivar8 = 67108925; + GOTO flow_17 + flow_9: + if (((boolean)globalint_1388)) { + ivar1 = 5; + } else { + ivar1 = bitconfig_7541; + } + ivar3 = 67108907; + ivar4 = 67108909; + ivar5 = 67108905; + ivar6 = 67108906; + ivar8 = 67108908; + GOTO flow_17 + flow_13: + if (((boolean)globalint_1388)) { + ivar1 = 6; + } else { + ivar1 = bitconfig_7542; + } + ivar3 = 67108890; + ivar4 = 67108892; + ivar5 = 67108888; + ivar6 = 67108889; + ivar8 = 67108891; + flow_17: + SWITCH (ivar1) { + case 1: + GOTO flow_18 + case 2: + GOTO flow_19 + case 3: + GOTO flow_20 + case 4: + GOTO flow_21 + case 5: + GOTO flow_22 + case 6: + GOTO flow_23 + case 7: + GOTO flow_24 + case 8: + GOTO flow_25 + case 9: + GOTO flow_26 + } + return; + flow_18: + ivar2 = globalint_1378; + ivar7 = getOtherCommonData(293, 1154); + GOTO flow_27 + flow_19: + ivar2 = globalint_1379; + ivar7 = getOtherCommonData(299, 1154); + GOTO flow_27 + flow_20: + ivar2 = globalint_1380; + ivar7 = getOtherCommonData(300, 1154); + GOTO flow_27 + flow_21: + ivar2 = globalint_1386; + ivar7 = getOtherCommonData(301, 1154); + GOTO flow_27 + flow_22: + ivar2 = globalint_1381; + ivar7 = getOtherCommonData(305, 1154); + GOTO flow_27 + flow_23: + ivar2 = globalint_1383; + ivar7 = getOtherCommonData(1044, 1154); + GOTO flow_27 + flow_24: + ivar2 = globalint_1384; + ivar7 = getOtherCommonData(1045, 1154); + GOTO flow_27 + flow_25: + ivar2 = globalint_1385; + ivar7 = getOtherCommonData(1046, 1154); + GOTO flow_27 + flow_26: + ivar2 = globalint_1382; + ivar7 = getOtherCommonData(1047, 1154); + flow_27: + if ((ivar2 > 0) || (bitconfig_7514 < ivar7)) { + if (ivar2 > 0) { + setWidgetText(new WidgetPointer(ivar8), intToStr(ivar2)); + } + setWidgetRGB(new Color(40, 40, 40), new WidgetPointer(ivar3)); + setWidgetIsHidden(false, new WidgetPointer(ivar4)); + setWidgetRGB(new Color(125, 125, 125), new WidgetPointer(ivar5)); + setWidgetRGB(new Color(125, 125, 125), new WidgetPointer(ivar6)); + } else { + setWidgetText(new WidgetPointer(ivar8), ""); + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(ivar3)); + setWidgetIsHidden(true, new WidgetPointer(ivar4)); + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(ivar5)); + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(ivar6)); + } + return; +} diff --git a/dumps/scripts/4290.cs2 b/dumps/scripts/4290.cs2 new file mode 100644 index 0000000..787ff13 --- /dev/null +++ b/dumps/scripts/4290.cs2 @@ -0,0 +1,7 @@ +void script_4290() { + if (cs2method3701()) { + script_4291(); + } + script_4295(); + return; +} diff --git a/dumps/scripts/4291.cs2 b/dumps/scripts/4291.cs2 new file mode 100644 index 0000000..b71b25d --- /dev/null +++ b/dumps/scripts/4291.cs2 @@ -0,0 +1,81 @@ +void script_4291() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int stack_dump0; + int stack_dump1; + int stack_dump2; + int stack_dump3; + int stack_dump4; + setScriptCallOnClanChatSettingsStuff(4300, "", new WidgetPointer(1096,36)); + setScriptCallOnGlobalConfigChange(4300, 1516, 1, "Y", new WidgetPointer(1096,36)); + setScriptCallOnGameloop(4319, 0, 1, "ii", new WidgetPointer(1096,50)); + setScriptCallOnClanChatSettingsStuff(4294, "", new WidgetPointer(1096,50)); + setScriptCallOnClanChatDeltaStuff(4294, "", new WidgetPointer(1096,50)); + setScriptCallOnGlobalConfigChange(118, 1500, 1501, 1502, 1503, 4, "Y", new WidgetPointer(1096,50)); + setScriptCallOnGlobalStringChange(118, 347, 1, "Y", new WidgetPointer(1096,50)); + switch (getLanguage()) { + case 1: + script_4499(3727, 1, getCommonDefinitionSize(3727), 10, 71827715, 71827725, 71827727, 71827726, 71827818, ""); + break; + case 2: + script_4499(3728, 1, getCommonDefinitionSize(3727), 10, 71827715, 71827725, 71827727, 71827726, 71827818, ""); + break; + case 3: + script_4499(3729, 1, getCommonDefinitionSize(3727), 10, 71827715, 71827725, 71827727, 71827726, 71827818, ""); + break; + default: + script_4499(3720, 1, getCommonDefinitionSize(3720), 10, 71827715, 71827725, 71827727, 71827726, 71827818, ""); + } + script_4328(71827829); + setScriptCallOnClanChatSettingsStuff(5226, "", new WidgetPointer(1096,373)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(1096,50)), 115, 0, 0, new WidgetPointer(1096,50)); + setWidgetIsHidden(true, new WidgetPointer(1096,363)); + setWidgetIsHidden(false, new WidgetPointer(1096,108)); + ivar0 = 71827491; + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + ivar4 = 218; + ivar5 = 23; + while (ivar1 < 500) { + if (mod(ivar1, 2) != 0) { + ivar2 = ivar4; + } else { + ivar2 = 0; + } + ivar3 = multiply(divide(ivar1, 2), ivar5); + createExtraChild(new WidgetPointer(ivar0), 3, ivar1); + setWidgetPosition(ivar2, ivar3, 0, 0); + setWidgetSize(divide(16384, 2), ivar5, 2, 0); + setWidgetFilled(1); + if (mod(divide(ivar1, 2), 2) != 0) { + setWidgetRGB(new Color(35, 34, 32)); + } else { + setWidgetRGB(new Color(28, 27, 25)); + } + ivar1 = add(ivar1, 1); + } + if (citadelConfigsInitialized()) { + stack_dump0 = 4514; + stack_dump1 = 0; + stack_dump2 = 105; + stack_dump3 = 115; + stack_dump4 = 4514; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + script_4499(4514, 0, -1, 4, 71827675, 71827685, 71827687, 71827686, 71827818, "N/A"); + script_4499(4255, 0, -1, 4, 71827660, 71827670, 71827672, 71827671, 71827818, "N/A"); + return; +} diff --git a/dumps/scripts/4292.cs2 b/dumps/scripts/4292.cs2 new file mode 100644 index 0000000..cabd25a --- /dev/null +++ b/dumps/scripts/4292.cs2 @@ -0,0 +1,11 @@ +int script_4292() { + int ivar0; + ivar0 = -1; + if (cs2method3751()) { + ivar0 = cs2method3760(strRemoveEntities(cs2method5020())); + if (cs2method3757(ivar0) >= 100) { + return 1; + } + } + return 0; +} diff --git a/dumps/scripts/4293.cs2 b/dumps/scripts/4293.cs2 new file mode 100644 index 0000000..f818a72 --- /dev/null +++ b/dumps/scripts/4293.cs2 @@ -0,0 +1,11 @@ +int script_4293() { + int ivar0; + ivar0 = -1; + if (cs2method3751()) { + ivar0 = cs2method3760(strRemoveEntities(cs2method5020())); + if (ivar0 != -1) { + return cs2method3757(ivar0); + } + } + return -1; +} diff --git a/dumps/scripts/4294.cs2 b/dumps/scripts/4294.cs2 new file mode 100644 index 0000000..63f4bee --- /dev/null +++ b/dumps/scripts/4294.cs2 @@ -0,0 +1,4 @@ +void script_4294() { + script_4295(); + return; +} diff --git a/dumps/scripts/4295.cs2 b/dumps/scripts/4295.cs2 new file mode 100644 index 0000000..e70a65e --- /dev/null +++ b/dumps/scripts/4295.cs2 @@ -0,0 +1,166 @@ +void script_4295() { + int ivar0; + int ivar1; + int stack_dump0; + int stack_dump1; + int stack_dump2; + int stack_dump3; + ivar0 = 0; + ivar1 = 0; + if (cs2method3701()) { + if (cs2method3703()) { + ivar1 = 1; + } else { + if (cs2method3703()) { + ivar1 = 0; + } + } + ivar0 = clanconfig_0; + ivar0 = add(divide(ivar0, 10), 72); + script_4501(71827692, cs2method_3408(105, 115, 3711, ivar0)); + script_4501(71827836, cs2method_3408(105, 115, 3797, globalint_1516)); + script_4501(71827660, cs2method_3408(105, 115, 4255, clanbitconfig_292)); + script_4329(71827772); + if (((boolean)clanbitconfig_6)) { + script_4501(71827743, "Not set"); + } else { + script_4501(71827743, cs2method_3408(105, 115, 3700, clanbitconfig_6)); + } + if (((boolean)clanbitconfig_5)) { + if (((boolean)script_4292())) { + setWidgetIsHidden(false, new WidgetPointer(1096,255)); + setWidgetIsHidden(true, new WidgetPointer(1096,257)); + setWidgetIsHidden(true, new WidgetPointer(1096,256)); + setWidgetIsHidden(true, new WidgetPointer(1096,258)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1096,255)); + setWidgetIsHidden(true, new WidgetPointer(1096,257)); + setWidgetIsHidden(false, new WidgetPointer(1096,256)); + setWidgetIsHidden(true, new WidgetPointer(1096,258)); + } + } else if (((boolean)script_4292())) { + setWidgetIsHidden(true, new WidgetPointer(1096,255)); + setWidgetIsHidden(false, new WidgetPointer(1096,257)); + setWidgetIsHidden(true, new WidgetPointer(1096,256)); + setWidgetIsHidden(true, new WidgetPointer(1096,258)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1096,255)); + setWidgetIsHidden(true, new WidgetPointer(1096,257)); + setWidgetIsHidden(true, new WidgetPointer(1096,256)); + setWidgetIsHidden(false, new WidgetPointer(1096,258)); + } + if (((boolean)clanbitconfig_4)) { + if (((boolean)script_4292())) { + setWidgetIsHidden(false, new WidgetPointer(1096,251)); + setWidgetIsHidden(true, new WidgetPointer(1096,253)); + setWidgetIsHidden(true, new WidgetPointer(1096,252)); + setWidgetIsHidden(true, new WidgetPointer(1096,254)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1096,251)); + setWidgetIsHidden(true, new WidgetPointer(1096,253)); + setWidgetIsHidden(false, new WidgetPointer(1096,252)); + setWidgetIsHidden(true, new WidgetPointer(1096,254)); + } + } else if (((boolean)script_4292())) { + setWidgetIsHidden(true, new WidgetPointer(1096,251)); + setWidgetIsHidden(false, new WidgetPointer(1096,253)); + setWidgetIsHidden(true, new WidgetPointer(1096,252)); + setWidgetIsHidden(true, new WidgetPointer(1096,254)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1096,251)); + setWidgetIsHidden(true, new WidgetPointer(1096,253)); + setWidgetIsHidden(true, new WidgetPointer(1096,252)); + setWidgetIsHidden(false, new WidgetPointer(1096,254)); + } + if (cs2method3703()) { + if (((boolean)script_4292())) { + setWidgetIsHidden(false, new WidgetPointer(1096,794)); + setWidgetIsHidden(true, new WidgetPointer(1096,749)); + setWidgetIsHidden(true, new WidgetPointer(1096,748)); + setWidgetIsHidden(true, new WidgetPointer(1096,750)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1096,794)); + setWidgetIsHidden(true, new WidgetPointer(1096,749)); + setWidgetIsHidden(false, new WidgetPointer(1096,748)); + setWidgetIsHidden(true, new WidgetPointer(1096,750)); + } + } else if (((boolean)script_4292())) { + setWidgetIsHidden(true, new WidgetPointer(1096,794)); + setWidgetIsHidden(false, new WidgetPointer(1096,749)); + setWidgetIsHidden(true, new WidgetPointer(1096,748)); + setWidgetIsHidden(true, new WidgetPointer(1096,750)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1096,794)); + setWidgetIsHidden(true, new WidgetPointer(1096,749)); + setWidgetIsHidden(true, new WidgetPointer(1096,748)); + setWidgetIsHidden(false, new WidgetPointer(1096,750)); + } + if (cs2method3704() == -1) { + if (((boolean)script_4292())) { + setWidgetIsHidden(false, new WidgetPointer(1096,798)); + setWidgetIsHidden(true, new WidgetPointer(1096,796)); + setWidgetIsHidden(true, new WidgetPointer(1096,795)); + setWidgetIsHidden(true, new WidgetPointer(1096,797)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1096,798)); + setWidgetIsHidden(true, new WidgetPointer(1096,796)); + setWidgetIsHidden(false, new WidgetPointer(1096,795)); + setWidgetIsHidden(true, new WidgetPointer(1096,797)); + } + } else if (((boolean)script_4292())) { + setWidgetIsHidden(true, new WidgetPointer(1096,798)); + setWidgetIsHidden(false, new WidgetPointer(1096,796)); + setWidgetIsHidden(true, new WidgetPointer(1096,795)); + setWidgetIsHidden(true, new WidgetPointer(1096,797)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1096,798)); + setWidgetIsHidden(true, new WidgetPointer(1096,796)); + setWidgetIsHidden(true, new WidgetPointer(1096,795)); + setWidgetIsHidden(false, new WidgetPointer(1096,797)); + } + if (citadelConfigsInitialized()) { + stack_dump0 = 71827675; + stack_dump1 = 105; + stack_dump2 = 115; + stack_dump3 = 4514; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + script_4501(71827675, "N/A"); + script_4501(71827660, "N/A"); + if (((boolean)script_4292())) { + setWidgetIsHidden(true, new WidgetPointer(1096,243)); + setWidgetIsHidden(true, new WidgetPointer(1096,293)); + } else { + setWidgetIsHidden(false, new WidgetPointer(1096,243)); + setWidgetIsHidden(false, new WidgetPointer(1096,293)); + } + script_4301(); + if (((boolean)script_4292())) { + setWidgetIsHidden(true, new WidgetPointer(1096,279)); + setWidgetIsHidden(true, new WidgetPointer(1096,265)); + setWidgetIsHidden(true, new WidgetPointer(1096,138)); + setWidgetIsHidden(true, new WidgetPointer(1096,127)); + setWidgetIsHidden(true, new WidgetPointer(1096,170)); + setWidgetIsHidden(true, new WidgetPointer(1096,374)); + setWidgetIsHidden(true, new WidgetPointer(1096,311)); + } else { + setWidgetIsHidden(false, new WidgetPointer(1096,279)); + setWidgetIsHidden(false, new WidgetPointer(1096,265)); + setWidgetIsHidden(false, new WidgetPointer(1096,138)); + setWidgetIsHidden(false, new WidgetPointer(1096,127)); + setWidgetIsHidden(false, new WidgetPointer(1096,170)); + setWidgetIsHidden(false, new WidgetPointer(1096,374)); + setWidgetIsHidden(false, new WidgetPointer(1096,311)); + } + } + script_4310(); + return; +} diff --git a/dumps/scripts/4296.cs2 b/dumps/scripts/4296.cs2 new file mode 100644 index 0000000..605ea62 --- /dev/null +++ b/dumps/scripts/4296.cs2 @@ -0,0 +1,4 @@ +void script_4296() { + script_4297(); + return; +} diff --git a/dumps/scripts/4297.cs2 b/dumps/scripts/4297.cs2 new file mode 100644 index 0000000..bf44285 --- /dev/null +++ b/dumps/scripts/4297.cs2 @@ -0,0 +1,10 @@ +void script_4297() { + flow_0: + setWidgetIsHidden(false, new WidgetPointer(1096,82)); + setWidgetIsHidden(true, new WidgetPointer(1096,81)); + IF (cs2method3701()) + GOTO flow_1 + GOTO flow_1 + flow_1: + return; +} diff --git a/dumps/scripts/4298.cs2 b/dumps/scripts/4298.cs2 new file mode 100644 index 0000000..24de388 --- /dev/null +++ b/dumps/scripts/4298.cs2 @@ -0,0 +1,4 @@ +void script_4298() { + script_4299(); + return; +} diff --git a/dumps/scripts/4299.cs2 b/dumps/scripts/4299.cs2 new file mode 100644 index 0000000..ccfc3e4 --- /dev/null +++ b/dumps/scripts/4299.cs2 @@ -0,0 +1,5 @@ +void script_4299() { + setWidgetIsHidden(false, new WidgetPointer(1096,81)); + setWidgetIsHidden(true, new WidgetPointer(1096,82)); + return; +} diff --git a/dumps/scripts/43.cs2 b/dumps/scripts/43.cs2 new file mode 100644 index 0000000..3b73043 --- /dev/null +++ b/dumps/scripts/43.cs2 @@ -0,0 +1,26 @@ +void script_43() { + int ivar0; + int ivar1; + int ivar2; + ivar0 = 0; + ivar1 = 0; + ivar2 = 0; + while (ivar0 < getItemContainerLength(141)) { + createExtraChild(new WidgetPointer(364,4), 5, ivar0); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(multiply(40, ivar1), multiply(40, ivar2), 0, 0); + if (getItemIdInSlot(141, ivar0) != -1) { + setItemOnWidgetMethod1200(getItemIdInSlot(141, ivar0), getItemAmtInSlot(141, ivar0)); + cs2method1305("" + getItemName(getItemIdInSlot(141, ivar0))); + setWidgetContextMenuOption(1, "Examine"); + setWidgetBorderThickness(1); + } + ivar0 = add(ivar0, 1); + ivar1 = add(ivar1, 1); + if (ivar1 == 3) { + ivar1 = 0; + ivar2 = add(ivar2, 1); + } + } + return; +} diff --git a/dumps/scripts/430.cs2 b/dumps/scripts/430.cs2 new file mode 100644 index 0000000..659132a --- /dev/null +++ b/dumps/scripts/430.cs2 @@ -0,0 +1,122 @@ +void script_430(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + flow_0: + ivar2 = 0; + ivar3 = 0; + ivar4 = 0; + ivar5 = -1; + ivar6 = 0; + SWITCH (arg0) { + case 67108872: + GOTO flow_1 + case 67108873: + GOTO flow_5 + case 67108874: + GOTO flow_9 + case 67108875: + GOTO flow_13 + } + return; + flow_1: + if (((boolean)globalint_1388)) { + ivar2 = 1; + } else { + ivar2 = bitconfig_7539; + } + ivar5 = 67108939; + GOTO flow_17 + flow_5: + if (((boolean)globalint_1388)) { + ivar2 = 3; + } else { + ivar2 = bitconfig_7540; + } + ivar5 = 67108922; + GOTO flow_17 + flow_9: + if (((boolean)globalint_1388)) { + ivar2 = 5; + } else { + ivar2 = bitconfig_7541; + } + ivar5 = 67108905; + GOTO flow_17 + flow_13: + if (((boolean)globalint_1388)) { + ivar2 = 6; + } else { + ivar2 = bitconfig_7542; + } + ivar5 = 67108888; + flow_17: + SWITCH (ivar2) { + case 1: + GOTO flow_18 + case 2: + GOTO flow_19 + case 3: + GOTO flow_20 + case 4: + GOTO flow_21 + case 5: + GOTO flow_22 + case 6: + GOTO flow_23 + case 7: + GOTO flow_24 + case 8: + GOTO flow_25 + case 9: + GOTO flow_26 + } + return; + flow_18: + ivar4 = globalint_1378; + ivar6 = getOtherCommonData(293, 1154); + GOTO flow_27 + flow_19: + ivar4 = globalint_1379; + ivar6 = getOtherCommonData(299, 1154); + GOTO flow_27 + flow_20: + ivar4 = globalint_1380; + ivar6 = getOtherCommonData(300, 1154); + GOTO flow_27 + flow_21: + ivar4 = globalint_1386; + ivar6 = getOtherCommonData(301, 1154); + GOTO flow_27 + flow_22: + ivar4 = globalint_1381; + ivar6 = getOtherCommonData(305, 1154); + GOTO flow_27 + flow_23: + ivar4 = globalint_1383; + ivar6 = getOtherCommonData(1044, 1154); + GOTO flow_27 + flow_24: + ivar4 = globalint_1384; + ivar6 = getOtherCommonData(1045, 1154); + GOTO flow_27 + flow_25: + ivar4 = globalint_1385; + ivar6 = getOtherCommonData(1046, 1154); + GOTO flow_27 + flow_26: + ivar4 = globalint_1382; + ivar6 = getOtherCommonData(1047, 1154); + flow_27: + if (((boolean)ivar4) && (bitconfig_7514 >= ivar6)) { + if (((boolean)arg1)) { + ivar3 = 16777215; + } else { + ivar3 = 16750623; + } + setWidgetRGB(new Color(ivar3), new WidgetPointer(ivar5)); + } + return; +} diff --git a/dumps/scripts/4300.cs2 b/dumps/scripts/4300.cs2 new file mode 100644 index 0000000..f7f0a19 --- /dev/null +++ b/dumps/scripts/4300.cs2 @@ -0,0 +1,6 @@ +void script_4300() { + if (cs2method3701()) { + script_4301(); + } + return; +} diff --git a/dumps/scripts/4301.cs2 b/dumps/scripts/4301.cs2 new file mode 100644 index 0000000..89c0031 --- /dev/null +++ b/dumps/scripts/4301.cs2 @@ -0,0 +1,206 @@ +void script_4301() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + int ivar22; + int ivar23; + int ivar24; + int ivar25; + int ivar26; + int ivar27; + int ivar28; + int ivar29; + int ivar30; + int ivar31; + int ivar32; + int ivar33; + int ivar34; + int ivar35; + int ivar36; + int ivar37; + int ivar38; + int ivar39; + string svar0; + string svar1; + int stack_dump0; + ivar0 = 71827492; + ivar1 = 71827493; + ivar2 = 71827494; + ivar3 = 71827495; + ivar4 = 71827531; + ivar5 = 71827532; + ivar6 = 71827817; + ivar7 = 71828240; + ivar8 = 218; + ivar9 = divide(16384, 2); + ivar10 = 3; + ivar11 = 4; + ivar12 = 200; + ivar13 = 3; + ivar14 = 16; + ivar15 = 23; + ivar16 = 177; + ivar17 = 4; + ivar18 = 157; + ivar19 = 4; + ivar20 = 137; + ivar21 = 4; + ivar22 = 15; + ivar23 = 15; + ivar24 = 0; + ivar25 = 0; + ivar26 = 0; + ivar27 = 0; + svar0 = "0"; + ivar28 = 9; + ivar29 = 23; + ivar30 = 0; + ivar31 = divide(getWidgetActualHeight(new WidgetPointer(ivar0)), ivar15); + ivar32 = multiply(ivar31, 2); + ivar33 = -1; + ivar34 = -1; + ivar35 = 0; + ivar36 = 0; + deleteAllExtraChilds(new WidgetPointer(ivar0)); + deleteAllExtraChilds(new WidgetPointer(ivar1)); + deleteAllExtraChilds(new WidgetPointer(ivar2)); + deleteAllExtraChilds(new WidgetPointer(ivar3)); + deleteAllExtraChilds(new WidgetPointer(ivar6)); + deleteAllExtraChilds(new WidgetPointer(ivar7)); + svar1 = ""; + ivar37 = -1; + ivar27 = cs2method3709(); + while (ivar26 < ivar27) { + ivar25 = multiply(divide(ivar37, 2), ivar15); + svar0 = cs2method3710(ivar26); + ivar34 = cs2method3711(ivar26); + if (subtract(globalint_1516, 1) != ivar34) { + ivar36 = 1; + if (((boolean)globalint_1516) || (globalint_1516 == -1)) { + ivar36 = 0; + } + } else { + ivar36 = 0; + } + createExtraChild(new WidgetPointer(ivar0), 4, ivar26); + if (((boolean)ivar36)) { + setWidgetFont(3793); + setWidgetSize(ivar9, ivar15, 2, 0); + ivar33 = -1; + if (cs2method3751() && (cs2method3760(svar0) > -1)) { + ivar33 = cs2method3758(cs2method3760(svar0)); + } + if (ivar33 == getWorldId()) { + setWidgetRGB(new Color(60, 183, 30)); + } else if (ivar33 > 0) { + setWidgetRGB(new Color(255, 255, 100)); + } else { + setWidgetRGB(new Color(190, 178, 140)); + } + setWidgetUnknownBoolean(true); + setWidgetText(svar0); + } + createExtraChild(new WidgetPointer(ivar2), 5, ivar26); + if (((boolean)ivar36)) { + setWidgetSize(ivar22, ivar23, 0, 0); + setWidgetSprite(cs2method_3408(105, 100, 3712, ivar34)); + svar1 = cs2method_3408(105, 115, 3714, ivar34); + setScriptCallOnMouseOver(4538, new WidgetPointer(1096,104), new WidgetPointer(ivar2), ivar26, svar1, 120, 3793, 3793, 16777215, 13, 4, 3, -2147483647, -2147483646, "IIisifdiiiiii"); + setScriptCallOnMouseExit(40, new WidgetPointer(1096,104), "I"); + } + createExtraChild(new WidgetPointer(ivar6), 5, ivar26); + if (((boolean)ivar36)) { + setWidgetSize(ivar22, ivar23, 0, 0); + switch (ivar34) { + case 0: + ivar35 = clanbitconfig_178; + break; + case 1: + ivar35 = clanbitconfig_179; + break; + case 2: + ivar35 = clanbitconfig_180; + break; + case 3: + ivar35 = clanbitconfig_181; + break; + case 4: + ivar35 = clanbitconfig_182; + break; + case 5: + ivar35 = clanbitconfig_183; + } + if (((boolean)ivar35) || (ivar34 >= 100)) { + setWidgetSprite(6235); + svar1 = "Rated Clan" + "
" + "Wars Leader"; + setScriptCallOnMouseOver(4538, new WidgetPointer(1096,104), new WidgetPointer(ivar6), ivar26, svar1, 120, 3793, 3793, 16777215, 13, 4, 3, -2147483647, -2147483646, "IIisifdiiiiii"); + setScriptCallOnMouseExit(40, new WidgetPointer(1096,104), "I"); + } + } + createExtraChild(new WidgetPointer(ivar7), 5, ivar26); + if (((boolean)ivar36)) { + setWidgetSize(ivar22, ivar23, 0, 0); + } + createExtraChild(new WidgetPointer(ivar3), 5, ivar26); + if (((boolean)ivar36)) { + setWidgetSize(ivar28, ivar29, 0, 0); + setWidgetSprite(6034); + setWidgetContextMenuOption(1, "Show details"); + setScriptCallOnClickContextMenu(4303, ""); + } + ivar26 = add(ivar26, 1); + } + ivar38 = 0; + ivar26 = 0; + ivar39 = 0; + while (ivar26 < ivar27) { + stack_dump0 = ivar26; + cs2method3718(); + ivar39 = stack_dump0; + if (setWidgetRegister(new WidgetPointer(ivar0), ivar39) && (stringMethod4107(getWidgetText(), "") != 0)) { + if (mod(ivar38, 2) != 0) { + ivar24 = ivar8; + } else { + ivar24 = 0; + } + ivar25 = multiply(divide(ivar38, 2), ivar15); + setWidgetPosition(add(ivar10, ivar24), add(ivar11, ivar25), 0, 0); + if (setWidgetRegister(new WidgetPointer(ivar2), ivar39)) { + setWidgetPosition(add(ivar16, ivar24), add(ivar17, ivar25), 0, 0); + } + if (setWidgetRegister(new WidgetPointer(ivar3), ivar39)) { + setWidgetPosition(add(ivar12, ivar24), ivar25, 0, 0); + } + if (setWidgetRegister(new WidgetPointer(ivar6), ivar39)) { + setWidgetPosition(add(ivar18, ivar24), add(ivar19, ivar25), 0, 0); + } + if (setWidgetRegister(new WidgetPointer(ivar7), ivar39)) { + setWidgetPosition(add(ivar20, ivar24), add(ivar21, ivar25), 0, 0); + } + ivar38 = add(ivar38, 1); + } + ivar26 = add(ivar26, 1); + } + globalint_1517 = ivar38; + script_4318(); + return; +} diff --git a/dumps/scripts/4302.cs2 b/dumps/scripts/4302.cs2 new file mode 100644 index 0000000..9bb46a9 --- /dev/null +++ b/dumps/scripts/4302.cs2 @@ -0,0 +1,6 @@ +void script_4302() { + if (cs2method3701()) { + script_4318(); + } + return; +} diff --git a/dumps/scripts/4303.cs2 b/dumps/scripts/4303.cs2 new file mode 100644 index 0000000..3e07c30 --- /dev/null +++ b/dumps/scripts/4303.cs2 @@ -0,0 +1,4 @@ +void script_4303() { + script_4305(); + return; +} diff --git a/dumps/scripts/4304.cs2 b/dumps/scripts/4304.cs2 new file mode 100644 index 0000000..0745c13 --- /dev/null +++ b/dumps/scripts/4304.cs2 @@ -0,0 +1,4 @@ +void script_4304() { + script_4305(); + return; +} diff --git a/dumps/scripts/4305.cs2 b/dumps/scripts/4305.cs2 new file mode 100644 index 0000000..ff6b6dd --- /dev/null +++ b/dumps/scripts/4305.cs2 @@ -0,0 +1,5 @@ +void script_4305() { + setWidgetIsHidden(false, new WidgetPointer(1096,70)); + script_4307(); + return; +} diff --git a/dumps/scripts/4306.cs2 b/dumps/scripts/4306.cs2 new file mode 100644 index 0000000..fad334f --- /dev/null +++ b/dumps/scripts/4306.cs2 @@ -0,0 +1,5 @@ +void script_4306() { + setWidgetIsHidden(true, new WidgetPointer(1096,70)); + setWidgetText(new WidgetPointer(1096,59), "Loading, please wait."); + return; +} diff --git a/dumps/scripts/4307.cs2 b/dumps/scripts/4307.cs2 new file mode 100644 index 0000000..8b25a6b --- /dev/null +++ b/dumps/scripts/4307.cs2 @@ -0,0 +1,11 @@ +void script_4307() { + globalint_1500 = -1; + globalint_1501 = -1; + bitconfig_9591 = -1; + bitconfig_9593 = -1; + bitconfig_9592 = -1; + bitconfig_9594 = -1; + globalstring_347 = ""; + globalint_1568 = -1; + return; +} diff --git a/dumps/scripts/4308.cs2 b/dumps/scripts/4308.cs2 new file mode 100644 index 0000000..ecb44be --- /dev/null +++ b/dumps/scripts/4308.cs2 @@ -0,0 +1,4 @@ +void script_4308(int arg0) { + script_1558(arg0); + return; +} diff --git a/dumps/scripts/4309.cs2 b/dumps/scripts/4309.cs2 new file mode 100644 index 0000000..6d34d3b --- /dev/null +++ b/dumps/scripts/4309.cs2 @@ -0,0 +1,6 @@ +int script_4309() { + if ((((globalint_1500 != -1) && (globalint_1501 != -1)) && ((bitconfig_9591 != -1) && (bitconfig_9593 != -1))) && (((bitconfig_9592 != -1) && (bitconfig_9594 != -1)) && ((globalint_1568 != -1) && (stringMethod4107(globalstring_347, "") != 0)))) { + return 1; + } + return 0; +} diff --git a/dumps/scripts/431.cs2 b/dumps/scripts/431.cs2 new file mode 100644 index 0000000..df029b8 --- /dev/null +++ b/dumps/scripts/431.cs2 @@ -0,0 +1,117 @@ +void script_431(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + flow_0: + ivar2 = -1; + ivar3 = -1; + ivar4 = 0; + ivar5 = -1; + ivar6 = -1; + SWITCH (arg0) { + case 67108872: + GOTO flow_1 + case 67108873: + GOTO flow_5 + case 67108874: + GOTO flow_9 + case 67108875: + GOTO flow_13 + } + return; + flow_1: + ivar2 = 67108944; + ivar3 = 67108945; + if (((boolean)globalint_1388)) { + ivar4 = 1; + } else { + ivar4 = bitconfig_7539; + } + GOTO flow_16 + flow_5: + ivar2 = 67108927; + ivar3 = 67108928; + if (((boolean)globalint_1388)) { + ivar4 = 3; + } else { + ivar4 = bitconfig_7540; + } + GOTO flow_16 + flow_9: + ivar2 = 67108910; + ivar3 = 67108911; + if (((boolean)globalint_1388)) { + ivar4 = 5; + } else { + ivar4 = bitconfig_7541; + } + GOTO flow_16 + flow_13: + ivar2 = 67108893; + ivar3 = 67108894; + if (((boolean)globalint_1388)) { + ivar4 = 6; + } else { + ivar4 = bitconfig_7542; + } + flow_16: + SWITCH (ivar4) { + case 1: + GOTO flow_17 + case 2: + GOTO flow_18 + case 3: + GOTO flow_19 + case 4: + GOTO flow_20 + case 5: + GOTO flow_21 + case 6: + GOTO flow_22 + case 7: + GOTO flow_23 + case 8: + GOTO flow_24 + case 9: + GOTO flow_25 + } + return; + flow_17: + ivar5 = 293; + GOTO flow_26 + flow_18: + ivar5 = 299; + GOTO flow_26 + flow_19: + ivar5 = 300; + GOTO flow_26 + flow_20: + ivar5 = 301; + GOTO flow_26 + flow_21: + ivar5 = 305; + GOTO flow_26 + flow_22: + ivar5 = 1044; + GOTO flow_26 + flow_23: + ivar5 = 1045; + GOTO flow_26 + flow_24: + ivar5 = 1046; + GOTO flow_26 + flow_25: + ivar5 = 1047; + flow_26: + if (((boolean)arg1)) { + setWidgetIsHidden(false, new WidgetPointer(ivar2)); + setWidgetIsHidden(false, new WidgetPointer(ivar3)); + cs2method2308(getOtherCommonData(ivar5, 1157), getOtherCommonData(ivar5, 1157), new WidgetPointer(arg0)); + } else { + setWidgetIsHidden(true, new WidgetPointer(ivar2)); + setWidgetIsHidden(true, new WidgetPointer(ivar3)); + } + return; +} diff --git a/dumps/scripts/4310.cs2 b/dumps/scripts/4310.cs2 new file mode 100644 index 0000000..3caeef4 --- /dev/null +++ b/dumps/scripts/4310.cs2 @@ -0,0 +1,7 @@ +void script_4310() { + if (((boolean)script_4309())) { + script_4306(); + } + script_4311(); + return; +} diff --git a/dumps/scripts/4311.cs2 b/dumps/scripts/4311.cs2 new file mode 100644 index 0000000..3381a11 --- /dev/null +++ b/dumps/scripts/4311.cs2 @@ -0,0 +1,122 @@ +void script_4311() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + ivar0 = 0; + ivar1 = script_4293(); + ivar2 = -1; + if (((boolean)script_4309())) { + ivar2 = globalint_1500; + } + setWidgetText(new WidgetPointer(1096,55), "Settings for: " + globalstring_347); + setWidgetIsHidden(true, new WidgetPointer(1096,751)); + setWidgetIsHidden(true, new WidgetPointer(1096,752)); + setWidgetIsHidden(true, new WidgetPointer(1096,754)); + setWidgetIsHidden(true, new WidgetPointer(1096,753)); + setWidgetIsHidden(true, new WidgetPointer(1096,157)); + setWidgetIsHidden(true, new WidgetPointer(1096,158)); + setWidgetIsHidden(true, new WidgetPointer(1096,160)); + setWidgetIsHidden(true, new WidgetPointer(1096,159)); + setWidgetIsHidden(true, new WidgetPointer(1096,376)); + setWidgetIsHidden(true, new WidgetPointer(1096,377)); + setWidgetIsHidden(true, new WidgetPointer(1096,379)); + setWidgetIsHidden(true, new WidgetPointer(1096,378)); + setWidgetIsHidden(true, new WidgetPointer(1096,780)); + setWidgetIsHidden(true, new WidgetPointer(1096,781)); + setWidgetIsHidden(true, new WidgetPointer(1096,783)); + setWidgetIsHidden(true, new WidgetPointer(1096,782)); + setWidgetIsHidden(true, new WidgetPointer(1096,69)); + setWidgetIsHidden(false, new WidgetPointer(1096,329)); + setWidgetIsHidden(false, new WidgetPointer(1096,341)); + setWidgetIsHidden(false, new WidgetPointer(1096,279)); + setWidgetIsHidden(false, new WidgetPointer(1096,265)); + ivar3 = 3720; + if (((boolean)getLanguage())) { + ivar3 = 3727; + } else if (getLanguage() == 2) { + ivar3 = 3728; + } else { + if (getLanguage() == 3) { + ivar3 = 3729; + } + } + if (((boolean)script_4309())) { + if (((boolean)globalint_1568)) { + setWidgetIsHidden(false, new WidgetPointer(1096,69)); + } + if (((boolean)script_4292())) { + if ((ivar1 > ivar2) || (ivar1 == 126)) { + setWidgetIsHidden(true, new WidgetPointer(1096,329)); + setWidgetIsHidden(true, new WidgetPointer(1096,341)); + setWidgetIsHidden(true, new WidgetPointer(1096,279)); + setWidgetIsHidden(true, new WidgetPointer(1096,265)); + if (ivar1 != 126) { + if (((boolean)globalint_1565)) { + setWidgetIsHidden(false, new WidgetPointer(1096,157)); + } else { + setWidgetIsHidden(false, new WidgetPointer(1096,159)); + } + if (((boolean)globalint_1566)) { + setWidgetIsHidden(false, new WidgetPointer(1096,376)); + } else { + setWidgetIsHidden(false, new WidgetPointer(1096,378)); + } + if (((boolean)globalint_1567)) { + setWidgetIsHidden(false, new WidgetPointer(1096,780)); + } else { + setWidgetIsHidden(false, new WidgetPointer(1096,782)); + } + } else { + setWidgetIsHidden(false, new WidgetPointer(1096,160)); + setWidgetIsHidden(false, new WidgetPointer(1096,379)); + setWidgetIsHidden(false, new WidgetPointer(1096,783)); + } + } else { + if (((boolean)globalint_1565)) { + setWidgetIsHidden(false, new WidgetPointer(1096,158)); + } else { + setWidgetIsHidden(false, new WidgetPointer(1096,160)); + } + if (((boolean)globalint_1566)) { + setWidgetIsHidden(false, new WidgetPointer(1096,377)); + } else { + setWidgetIsHidden(false, new WidgetPointer(1096,379)); + } + if (((boolean)globalint_1567)) { + setWidgetIsHidden(false, new WidgetPointer(1096,781)); + } else { + setWidgetIsHidden(false, new WidgetPointer(1096,783)); + } + } + } else { + if (((boolean)globalint_1564)) { + setWidgetIsHidden(false, new WidgetPointer(1096,752)); + } else { + setWidgetIsHidden(false, new WidgetPointer(1096,754)); + } + if (((boolean)globalint_1565)) { + setWidgetIsHidden(false, new WidgetPointer(1096,158)); + } else { + setWidgetIsHidden(false, new WidgetPointer(1096,160)); + } + if (((boolean)globalint_1566)) { + setWidgetIsHidden(false, new WidgetPointer(1096,377)); + } else { + setWidgetIsHidden(false, new WidgetPointer(1096,379)); + } + if (((boolean)globalint_1567)) { + setWidgetIsHidden(false, new WidgetPointer(1096,781)); + } else { + setWidgetIsHidden(false, new WidgetPointer(1096,783)); + } + } + script_4501(71827729, cs2method_3408(105, 115, 3715, globalint_1500)); + if (((boolean)stringMethod4107("", cs2method_3408(105, 115, ivar3, globalint_1501)))) { + script_4501(71827715, cs2method_3408(105, 115, ivar3, subtract(globalint_1501, 1))); + } else { + script_4501(71827715, cs2method_3408(105, 115, ivar3, globalint_1501)); + } + } + return; +} diff --git a/dumps/scripts/4312.cs2 b/dumps/scripts/4312.cs2 new file mode 100644 index 0000000..1d40987 --- /dev/null +++ b/dumps/scripts/4312.cs2 @@ -0,0 +1,4 @@ +void script_4312() { + script_4313(); + return; +} diff --git a/dumps/scripts/4313.cs2 b/dumps/scripts/4313.cs2 new file mode 100644 index 0000000..e3c5856 --- /dev/null +++ b/dumps/scripts/4313.cs2 @@ -0,0 +1,4 @@ +void script_4313() { + script_4311(); + return; +} diff --git a/dumps/scripts/4314.cs2 b/dumps/scripts/4314.cs2 new file mode 100644 index 0000000..496104d --- /dev/null +++ b/dumps/scripts/4314.cs2 @@ -0,0 +1,4 @@ +void script_4314() { + setScriptCallOnGameloop(4319, 0, 0, "ii", new WidgetPointer(1096,50)); + return; +} diff --git a/dumps/scripts/4315.cs2 b/dumps/scripts/4315.cs2 new file mode 100644 index 0000000..bb08ebe --- /dev/null +++ b/dumps/scripts/4315.cs2 @@ -0,0 +1,4 @@ +void script_4315() { + setScriptCallOnGameloop(4319, 0, 1, "ii", new WidgetPointer(1096,50)); + return; +} diff --git a/dumps/scripts/4316.cs2 b/dumps/scripts/4316.cs2 new file mode 100644 index 0000000..fb5f5a9 --- /dev/null +++ b/dumps/scripts/4316.cs2 @@ -0,0 +1,6 @@ +void script_4316() { + setWidgetScrollMax(0, 0, new WidgetPointer(1091,6)); + cs2method2100(0, 0, new WidgetPointer(1091,6)); + script_31(71499781, 71499782, 5666, 5663, 5664, 5665, 5686, 5685); + return; +} diff --git a/dumps/scripts/4317.cs2 b/dumps/scripts/4317.cs2 new file mode 100644 index 0000000..e2fe58c --- /dev/null +++ b/dumps/scripts/4317.cs2 @@ -0,0 +1,27 @@ +void script_4317(int arg0,int arg1) { + int ivar2; + ivar2 = 0; + if (cs2method3751()) { + if ((arg1 < 0) || (arg1 >= cs2method3755())) { + globalint_1518 = -1; + globalstring_126 = ""; + messageType0("That person isn't in your clan channel."); + return; + } + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + ivar2 = getWidgetActualY(); + } + globalint_1518 = arg1; + globalstring_126 = cs2method3756(arg1); + if (setWidgetRegister(new WidgetPointer(1110,20))) { + setWidgetSize(1, 19, 0, 0); + setWidgetPosition(0, ivar2, 2, 0); + setScriptCallOnGameloop(4629, 1, "i"); + setWidgetIsHidden(false, new WidgetPointer(1110,13)); + setWidgetPosition(0, ivar2, 2, 0, new WidgetPointer(1110,13)); + } + } else { + messageType0("You must be in your clan channel to do that."); + } + return; +} diff --git a/dumps/scripts/4318.cs2 b/dumps/scripts/4318.cs2 new file mode 100644 index 0000000..a28726f --- /dev/null +++ b/dumps/scripts/4318.cs2 @@ -0,0 +1,23 @@ +void script_4318() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + ivar0 = 71827531; + ivar1 = 71827532; + ivar2 = 23; + ivar3 = max(getWidgetActualHeight(new WidgetPointer(ivar1)), multiply(add(divide(globalint_1517, 2), 1), ivar2)); + ivar4 = cs2method2601(new WidgetPointer(ivar1)); + if (ivar3 > getWidgetActualHeight(new WidgetPointer(1096,76))) { + setWidgetScrollMax(getWidgetActualWidth(new WidgetPointer(ivar1)), ivar3, new WidgetPointer(ivar1)); + cs2method2100(0, ivar4, new WidgetPointer(ivar1)); + setWidgetIsHidden(false, new WidgetPointer(ivar0)); + script_31(ivar0, ivar1, 5666, 5663, 5664, 5665, 5686, 5685); + } else { + setWidgetScrollMax(getWidgetActualWidth(new WidgetPointer(ivar1)), getWidgetActualHeight(new WidgetPointer(ivar1)), new WidgetPointer(ivar1)); + cs2method2100(0, 0, new WidgetPointer(ivar1)); + script_31(ivar0, ivar1, 5666, 5663, 5664, 5665, 5686, 5685); + } + return; +} diff --git a/dumps/scripts/4319.cs2 b/dumps/scripts/4319.cs2 new file mode 100644 index 0000000..479d1d8 --- /dev/null +++ b/dumps/scripts/4319.cs2 @@ -0,0 +1,52 @@ +void script_4319(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + ivar2 = 0; + ivar3 = 0; + ivar4 = 71827506; + ivar5 = 71827505; + ivar6 = 71827530; + ivar7 = 71827612; + ivar8 = 71827501; + ivar9 = 71827532; + if (arg0 > 0) { + ivar2 = subtract(arg0, 1); + } else { + ivar2 = 0; + ivar3 = getWidgetActualHeight(new WidgetPointer(ivar4)); + if (((boolean)arg1)) { + ivar3 = add(ivar3, 6); + setWidgetVFlip(0, new WidgetPointer(ivar6)); + setWidgetVFlip(0, new WidgetPointer(ivar7)); + setWidgetContextMenuOption(1, new WidgetPointer(ivar8), "Hide"); + setScriptCallOnClickContextMenu(4319, 0, 1, "ii", new WidgetPointer(ivar8)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1096,68)); + ivar3 = subtract(ivar3, 6); + setWidgetVFlip(1, new WidgetPointer(ivar6)); + setWidgetVFlip(1, new WidgetPointer(ivar7)); + setWidgetContextMenuOption(1, new WidgetPointer(ivar8), "Show"); + setScriptCallOnClickContextMenu(4319, 0, 0, "ii", new WidgetPointer(ivar8)); + } + ivar3 = min(ivar3, 224); + ivar3 = max(ivar3, 115); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(ivar4)), ivar3, 0, 0, new WidgetPointer(ivar4)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(ivar5)), subtract(ivar3, 62), 0, 1, new WidgetPointer(ivar5)); + if (((boolean)arg1) && (ivar3 >= 224)) { + setWidgetIsHidden(false, new WidgetPointer(1096,68)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(ivar4)); + } else if (((boolean)arg1) && (ivar3 <= 115)) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(ivar4)); + } else { + setScriptCallOnGameloop(4319, ivar2, arg1, "ii", new WidgetPointer(ivar4)); + } + script_4302(); + } + return; +} diff --git a/dumps/scripts/432.cs2 b/dumps/scripts/432.cs2 new file mode 100644 index 0000000..3b0603e --- /dev/null +++ b/dumps/scripts/432.cs2 @@ -0,0 +1,57 @@ +void script_432(int arg0,int arg1) { + int ivar2; + int ivar3; + flow_0: + ivar2 = -1; + ivar3 = 67108949; + SWITCH (arg0) { + case 67108929: + GOTO flow_1 + case 67108912: + GOTO flow_5 + case 67108895: + GOTO flow_9 + case 67108878: + GOTO flow_13 + } + return; + flow_1: + if (((boolean)globalint_1388)) { + ivar2 = 293; + } else { + ivar2 = script_488(bitconfig_7539); + } + GOTO flow_16 + flow_5: + if (((boolean)globalint_1388)) { + ivar2 = 300; + } else { + ivar2 = script_488(bitconfig_7540); + } + GOTO flow_16 + flow_9: + if (((boolean)globalint_1388)) { + ivar2 = 305; + } else { + ivar2 = script_488(bitconfig_7541); + } + GOTO flow_16 + flow_13: + if (((boolean)globalint_1388)) { + ivar2 = 1044; + } else { + ivar2 = script_488(bitconfig_7542); + } + flow_16: + if (ivar2 != -1) { + setWidgetText(new WidgetPointer(1024,92), getOtherCommonData(ivar2, 1150)); + setWidgetText(new WidgetPointer(1024,93), getOtherCommonData(ivar2, 1151)); + setWidgetText(new WidgetPointer(1024,94), "Cost: " + intToStr(getOtherCommonData(ivar2, 1154))); + setWidgetText(new WidgetPointer(1024,95), "Cooldown: " + intToStr(getOtherCommonData(ivar2, 1155))); + setWidgetPosition(getWidgetActualX(new WidgetPointer(ivar3)), arg1, 0, 0, new WidgetPointer(ivar3)); + setWidgetIsHidden(false, new WidgetPointer(ivar3)); + } else { + setWidgetIsHidden(true, new WidgetPointer(ivar3)); + } + return; +} diff --git a/dumps/scripts/4320.cs2 b/dumps/scripts/4320.cs2 new file mode 100644 index 0000000..2b6a0fc --- /dev/null +++ b/dumps/scripts/4320.cs2 @@ -0,0 +1,4 @@ +void script_4320() { + script_4321(); + return; +} diff --git a/dumps/scripts/4321.cs2 b/dumps/scripts/4321.cs2 new file mode 100644 index 0000000..f9df9df --- /dev/null +++ b/dumps/scripts/4321.cs2 @@ -0,0 +1,9 @@ +void script_4321() { + script_4307(); + script_4311(); + setWidgetIsHidden(false, new WidgetPointer(1096,70)); + setWidgetText(new WidgetPointer(1096,59), "Please select a clanmate to view."); + script_4501(71827729, ""); + script_4501(71827715, ""); + return; +} diff --git a/dumps/scripts/4322.cs2 b/dumps/scripts/4322.cs2 new file mode 100644 index 0000000..54c78eb --- /dev/null +++ b/dumps/scripts/4322.cs2 @@ -0,0 +1,55 @@ +void script_4322(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + deleteAllExtraChilds(new WidgetPointer(arg2)); + deleteAllExtraChilds(new WidgetPointer(arg3)); + ivar4 = 0; + ivar5 = 0; + ivar6 = 8; + ivar7 = 8; + ivar8 = 50; + ivar9 = 36; + ivar10 = 0; + ivar11 = 0; + ivar12 = divide(subtract(getWidgetActualWidth(new WidgetPointer(arg0)), multiply(ivar6, 2)), add(ivar6, ivar8)); + ivar13 = getCommonDefinitionSize(3722); + ivar14 = getCommonDefinitionSize(3721); + ivar15 = min(ivar13, ivar14); + while (ivar4 < ivar15) { + ivar10 = add(ivar6, multiply(add(ivar8, ivar6), subtract(ivar4, multiply(ivar5, ivar12)))); + ivar11 = add(ivar7, multiply(ivar5, add(ivar9, ivar7))); + createExtraChild(new WidgetPointer(arg2), 5, ivar4); + setWidgetSize(ivar8, ivar9, 0, 0); + setWidgetPosition(ivar10, ivar11, 0, 0); + setWidgetSprite(6036); + setScriptCallOnConfigChange(4324, ivar15, 2149, 1, "iY"); + setScriptCallOnMouseEntered(4326, ivar4, new WidgetPointer(arg2), "iI"); + setScriptCallOnMouseExit(4327, ivar4, new WidgetPointer(arg2), "iI"); + createExtraChild(new WidgetPointer(arg3), 5, ivar4); + setWidgetSize(subtract(ivar8, 8), subtract(ivar9, 8), 0, 0); + setWidgetPosition(add(ivar10, 4), add(ivar11, 4), 0, 0); + setWidgetSprite(cs2method_3408(105, 100, 3721, ivar4)); + setWidgetContextMenuOption(1, "Select"); + setScriptCallOnClickContextMenu(4323, ivar4, new WidgetPointer(arg2), ivar15, "iIi"); + setScriptCallOnMouseOver(568, new WidgetPointer(arg3), ivar4, new WidgetPointer(1089,37), cs2method_3408(105, 115, 3722, ivar4), 20, 350, "IiIsii"); + setScriptCallOnMouseExit(40, new WidgetPointer(1089,37), "I"); + ivar4 = add(ivar4, 1); + if (((boolean)mod(ivar4, ivar12))) { + ivar5 = add(ivar5, 1); + } + } + cs2method2100(0, 0, new WidgetPointer(arg0)); + setWidgetScrollMax(0, add(ivar7, multiply(add(ivar5, 1), add(ivar7, ivar9))), new WidgetPointer(arg0)); + script_31(arg1, arg0, 5666, 5663, 5664, 5665, 5686, 5685); + return; +} diff --git a/dumps/scripts/4323.cs2 b/dumps/scripts/4323.cs2 new file mode 100644 index 0000000..169ed33 --- /dev/null +++ b/dumps/scripts/4323.cs2 @@ -0,0 +1,4 @@ +void script_4323(int arg0,int arg1,int arg2) { + script_4325(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/4324.cs2 b/dumps/scripts/4324.cs2 new file mode 100644 index 0000000..f6820f1 --- /dev/null +++ b/dumps/scripts/4324.cs2 @@ -0,0 +1,4 @@ +void script_4324(int arg0) { + script_4325(standart_config_2149, 71368704, arg0); + return; +} diff --git a/dumps/scripts/4325.cs2 b/dumps/scripts/4325.cs2 new file mode 100644 index 0000000..861b774 --- /dev/null +++ b/dumps/scripts/4325.cs2 @@ -0,0 +1,14 @@ +void script_4325(int arg0,int arg1,int arg2) { + int ivar3; + ivar3 = 0; + while (ivar3 < arg2) { + if (setWidgetRegister(new WidgetPointer(arg1), ivar3)) { + setWidgetSprite(6036); + } + ivar3 = add(ivar3, 1); + } + if (setWidgetRegister(new WidgetPointer(arg1), arg0)) { + setWidgetSprite(6039); + } + return; +} diff --git a/dumps/scripts/4326.cs2 b/dumps/scripts/4326.cs2 new file mode 100644 index 0000000..d2b32cb --- /dev/null +++ b/dumps/scripts/4326.cs2 @@ -0,0 +1,6 @@ +void script_4326(int arg0,int arg1) { + if (setWidgetRegister(new WidgetPointer(arg1), arg0)) { + setWidgetSprite(6037); + } + return; +} diff --git a/dumps/scripts/4327.cs2 b/dumps/scripts/4327.cs2 new file mode 100644 index 0000000..c126472 --- /dev/null +++ b/dumps/scripts/4327.cs2 @@ -0,0 +1,10 @@ +void script_4327(int arg0,int arg1) { + if (setWidgetRegister(new WidgetPointer(arg1), arg0)) { + if ((arg1 == 71368704) && (standart_config_2149 == arg0)) { + setWidgetSprite(6039); + } else { + setWidgetSprite(6036); + } + } + return; +} diff --git a/dumps/scripts/4328.cs2 b/dumps/scripts/4328.cs2 new file mode 100644 index 0000000..81dde4b --- /dev/null +++ b/dumps/scripts/4328.cs2 @@ -0,0 +1,8 @@ +void script_4328(int arg0) { + if (((boolean)clanbitconfig_11)) { + setWidgetSprite(cs2method_3408(105, 100, 3721, clanbitconfig_7), new WidgetPointer(arg0)); + } else { + setWidgetSprite(cs2method_3408(105, 100, 3721, 0), new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/4329.cs2 b/dumps/scripts/4329.cs2 new file mode 100644 index 0000000..f59b1d8 --- /dev/null +++ b/dumps/scripts/4329.cs2 @@ -0,0 +1,13 @@ +void script_4329(int arg0) { + if (clanlongconfig_2 != -1L) { + setWidgetText(new WidgetPointer(arg0), toBase36(clanlongconfig_2)); + setScriptCallOnMouseEntered(45, new WidgetPointer(arg0), 255, "Ii", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(45, new WidgetPointer(arg0), 15393218, "Ii", new WidgetPointer(arg0)); + cs2method2314(175, new WidgetPointer(arg0)); + setScriptCallOnMousePressed(4330, clanlongconfig_2, "\u00a7", new WidgetPointer(arg0)); + cs2method2305(new WidgetPointer(arg0), "Visit Clan Forum"); + } else { + setWidgetText(new WidgetPointer(arg0), ""); + } + return; +} diff --git a/dumps/scripts/433.cs2 b/dumps/scripts/433.cs2 new file mode 100644 index 0000000..f3fb288 --- /dev/null +++ b/dumps/scripts/433.cs2 @@ -0,0 +1,4 @@ +void script_433() { + setWidgetIsHidden(true, new WidgetPointer(1024,85)); + return; +} diff --git a/dumps/scripts/4330.cs2 b/dumps/scripts/4330.cs2 new file mode 100644 index 0000000..35051af --- /dev/null +++ b/dumps/scripts/4330.cs2 @@ -0,0 +1,4 @@ +void script_4330(long arg0) { + cs2method5400(0, "clan-forum", "threads.ws?threadid=" + toBase36(arg0)); + return; +} diff --git a/dumps/scripts/4331.cs2 b/dumps/scripts/4331.cs2 new file mode 100644 index 0000000..1e10f92 --- /dev/null +++ b/dumps/scripts/4331.cs2 @@ -0,0 +1,10 @@ +void script_4331(int arg0,int arg1) { + int ivar2; + int ivar3; + ivar2 = -1; + ivar3 = -1; + if (cs2method3700()) { + script_4332(arg0, arg1); + } + return; +} diff --git a/dumps/scripts/4332.cs2 b/dumps/scripts/4332.cs2 new file mode 100644 index 0000000..5231e7b --- /dev/null +++ b/dumps/scripts/4332.cs2 @@ -0,0 +1,26 @@ +void script_4332(int arg0,int arg1) { + int ivar2; + int ivar3; + int stack_dump0; + int stack_dump1; + int stack_dump2; + cs2func_script_4384_struct(2,0,0) structdump_3; + ivar2 = -1; + ivar3 = -1; + stack_dump0 = clanbitconfig_14; + stack_dump1 = clanbitconfig_15; + stack_dump2 = 1; + structdump_3 = script_4384(stack_dump0, stack_dump1, stack_dump2); + ivar3 = structdump_3.intpart_1; + ivar2 = structdump_3.intpart_0; + setWidgetSprite(ivar2, new WidgetPointer(arg0)); + setWidgetSprite(ivar3, new WidgetPointer(arg1)); + if (cs2method3709() >= 5) { + setWidgetRGB(new Color(getColorRelatedMethod4020(clanconfig_16)), new WidgetPointer(arg0)); + setWidgetRGB(new Color(getColorRelatedMethod4020(clanconfig_17)), new WidgetPointer(arg1)); + } else { + setWidgetRGB(new Color(getColorRelatedMethod4020(6716)), new WidgetPointer(arg0)); + setWidgetRGB(new Color(getColorRelatedMethod4020(6716)), new WidgetPointer(arg1)); + } + return; +} diff --git a/dumps/scripts/4333.cs2 b/dumps/scripts/4333.cs2 new file mode 100644 index 0000000..1d0abcf --- /dev/null +++ b/dumps/scripts/4333.cs2 @@ -0,0 +1,6 @@ +void script_4333(int arg0,int arg1) { + if (cs2method3700()) { + script_4334(arg0, arg1); + } + return; +} diff --git a/dumps/scripts/4334.cs2 b/dumps/scripts/4334.cs2 new file mode 100644 index 0000000..d19e1b6 --- /dev/null +++ b/dumps/scripts/4334.cs2 @@ -0,0 +1,10 @@ +void script_4334(int arg0,int arg1) { + if (cs2method3709() >= 5) { + setWidgetRGB(new Color(getColorRelatedMethod4020(clanconfig_18)), new WidgetPointer(arg0)); + setWidgetRGB(new Color(getColorRelatedMethod4020(clanconfig_19)), new WidgetPointer(arg1)); + } else { + setWidgetRGB(new Color(getColorRelatedMethod4020(42550)), new WidgetPointer(arg0)); + setWidgetRGB(new Color(getColorRelatedMethod4020(39382)), new WidgetPointer(arg1)); + } + return; +} diff --git a/dumps/scripts/4335.cs2 b/dumps/scripts/4335.cs2 new file mode 100644 index 0000000..2f99468 --- /dev/null +++ b/dumps/scripts/4335.cs2 @@ -0,0 +1,6 @@ +void script_4335(int arg0) { + if (cs2method3700()) { + script_4336(arg0); + } + return; +} diff --git a/dumps/scripts/4336.cs2 b/dumps/scripts/4336.cs2 new file mode 100644 index 0000000..bf62035 --- /dev/null +++ b/dumps/scripts/4336.cs2 @@ -0,0 +1,8 @@ +void script_4336(int arg0) { + if (((boolean)clanbitconfig_9) && (cs2method3709() >= 5)) { + setWidgetText(new WidgetPointer(arg0), strRemoveEntities(clanstringconfig_1)); + return; + } + setWidgetText(new WidgetPointer(arg0), ""); + return; +} diff --git a/dumps/scripts/4337.cs2 b/dumps/scripts/4337.cs2 new file mode 100644 index 0000000..80534e4 --- /dev/null +++ b/dumps/scripts/4337.cs2 @@ -0,0 +1,23 @@ +string script_4337(int arg0) { + int ivar1; + int ivar2; + string svar0; + string svar1; + string svar2; + svar0 = "+"; + if (arg0 < 0) { + svar0 = "-"; + arg0 = subtract(0, arg0); + } + ivar1 = divide(arg0, 60); + ivar2 = mod(arg0, 60); + svar1 = intToStr(ivar1); + if (ivar1 < 10) { + svar1 = "0" + intToStr(ivar1); + } + svar2 = intToStr(ivar2); + if (ivar2 < 10) { + svar2 = "0" + intToStr(ivar2); + } + return svar0 + svar1 + ":" + svar2; +} diff --git a/dumps/scripts/4338.cs2 b/dumps/scripts/4338.cs2 new file mode 100644 index 0000000..ce2852b --- /dev/null +++ b/dumps/scripts/4338.cs2 @@ -0,0 +1,14 @@ +string script_4338(int arg0) { + string svar0; + svar0 = ""; + if (arg0 < 10) { + svar0 = concat(arg0, "00:0"); + } else if (arg0 < 60) { + svar0 = concat(arg0, "00:"); + } else if (arg0 < 959) { + svar0 = "0" + intToStr(divide(arg0, 100)) + ":" + intToStr(mod(arg0, 100)); + } else { + svar0 = intToStr(divide(arg0, 100)) + ":" + intToStr(mod(arg0, 100)); + } + return svar0; +} diff --git a/dumps/scripts/4339.cs2 b/dumps/scripts/4339.cs2 new file mode 100644 index 0000000..b5bf61e --- /dev/null +++ b/dumps/scripts/4339.cs2 @@ -0,0 +1,4 @@ +void script_4339(int arg0,int arg1,int arg2) { + setScriptCallOnClanChatSettingsStuff(5230, arg0, new WidgetPointer(arg1), new WidgetPointer(arg2), "iII", new WidgetPointer(arg2)); + return; +} diff --git a/dumps/scripts/434.cs2 b/dumps/scripts/434.cs2 new file mode 100644 index 0000000..8b06586 --- /dev/null +++ b/dumps/scripts/434.cs2 @@ -0,0 +1,10 @@ +void script_434() { + if (((boolean)bitconfig_7509)) { + setWidgetSprite(1135, new WidgetPointer(1026,21)); + setWidgetSprite(1134, new WidgetPointer(1026,23)); + } else { + setWidgetSprite(1134, new WidgetPointer(1026,21)); + setWidgetSprite(1135, new WidgetPointer(1026,23)); + } + return; +} diff --git a/dumps/scripts/4340.cs2 b/dumps/scripts/4340.cs2 new file mode 100644 index 0000000..2a84b8e --- /dev/null +++ b/dumps/scripts/4340.cs2 @@ -0,0 +1,38 @@ +void script_4340(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + int ivar6; + int ivar7; + string svar0; + string svar1; + int stack_dump0; + int stack_dump1; + int stack_dump2; + cs2func_script_4341_struct(0,2,0) structdump_3; + ivar4 = divide(divide(arg0, 60), 24); + ivar5 = subtract(arg0, multiply(multiply(ivar4, 24), 60)); + ivar6 = divide(ivar5, 60); + ivar7 = mod(ivar5, 60); + svar0 = ""; + if (ivar6 < 10) { + svar0 = "0" + intToStr(ivar6); + } else { + svar0 = intToStr(ivar6); + } + svar1 = ""; + if (ivar7 < 10) { + svar1 = "0" + intToStr(ivar7); + } else { + svar1 = intToStr(ivar7); + } + setWidgetText(new WidgetPointer(arg2), svar0 + ":" + svar1); + setScriptCallOnGameloop(4342, ivar6, ivar7, arg1, new WidgetPointer(arg2), new WidgetPointer(arg3), "iiiII", new WidgetPointer(arg2)); + stack_dump0 = arg1; + stack_dump1 = ivar6; + stack_dump2 = ivar7; + structdump_3 = script_4341(stack_dump0, stack_dump1, stack_dump2); + svar1 = structdump_3.stringpart_1; + svar0 = structdump_3.stringpart_0; + setWidgetText(new WidgetPointer(arg3), svar0 + ":" + svar1); + return; +} diff --git a/dumps/scripts/4341.cs2 b/dumps/scripts/4341.cs2 new file mode 100644 index 0000000..971f74f --- /dev/null +++ b/dumps/scripts/4341.cs2 @@ -0,0 +1,34 @@ +cs2func_script_4341_struct(0,2,0) script_4341(int arg0,int arg1,int arg2) { + int ivar3; + string svar0; + string svar1; + string svar2; + svar0 = intToStr(arg1); + svar1 = intToStr(arg2); + ivar3 = 0; + svar2 = ""; + ivar3 = add(add(multiply(60, arg1), arg0), arg2); + if (ivar3 < 0) { + ivar3 = add(1440, ivar3); + } + arg2 = mod(ivar3, 60); + arg1 = divide(ivar3, 60); + if (arg1 > 23) { + arg1 = subtract(arg1, 24); + } else { + if (arg1 < 0) { + arg1 = subtract(24, arg1); + } + } + if (arg1 < 10) { + svar0 = "0" + intToStr(arg1); + } else { + svar0 = intToStr(arg1); + } + if (arg2 < 10) { + svar1 = "0" + intToStr(arg2); + } else { + svar1 = intToStr(arg2); + } + return newstruct cs2func_script_4341_struct(svar0, svar1); +} diff --git a/dumps/scripts/4342.cs2 b/dumps/scripts/4342.cs2 new file mode 100644 index 0000000..fe2815f --- /dev/null +++ b/dumps/scripts/4342.cs2 @@ -0,0 +1,70 @@ +void script_4342(int arg0,int arg1,int arg2,int arg3,int arg4) { + string svar0; + string svar1; + int stack_dump0; + int stack_dump1; + int stack_dump2; + cs2func_script_4341_struct(0,2,0) structdump_3; + cs2func_script_4341_struct(0,2,0) structdump_4; + svar0 = ""; + svar1 = ""; + if (((boolean)mod(getClientCycle(), 3000))) { + arg1 = add(arg1, 1); + if (arg1 >= 60) { + arg1 = 0; + arg0 = add(arg0, 1); + if (arg0 >= 24) { + arg0 = 0; + } + } + if (arg0 < 10) { + svar0 = "0" + intToStr(arg0); + } else { + svar0 = intToStr(arg0); + } + if (arg1 < 10) { + svar1 = "0" + intToStr(arg1); + } else { + svar1 = intToStr(arg1); + } + setWidgetText(new WidgetPointer(arg3), svar0 + ":" + svar1); + setScriptCallOnGameloop(4342, arg0, arg1, arg2, new WidgetPointer(arg3), new WidgetPointer(arg4), "iiiII", new WidgetPointer(arg3)); + stack_dump0 = arg2; + stack_dump1 = arg0; + stack_dump2 = arg1; + structdump_3 = script_4341(stack_dump0, stack_dump1, stack_dump2); + svar1 = structdump_3.stringpart_1; + svar0 = structdump_3.stringpart_0; + setWidgetText(new WidgetPointer(arg4), svar0 + ":" + svar1); + } else { + if (((boolean)mod(getClientCycle(), 50))) { + if (arg0 < 10) { + svar0 = "0" + intToStr(arg0); + } else { + svar0 = intToStr(arg0); + } + if (arg1 < 10) { + svar1 = "0" + intToStr(arg1); + } else { + svar1 = intToStr(arg1); + } + if (((boolean)mod(getClientCycle(), 100))) { + setWidgetText(new WidgetPointer(arg3), svar0 + ":" + svar1); + } else { + setWidgetText(new WidgetPointer(arg3), svar0 + " " + svar1); + } + stack_dump0 = arg2; + stack_dump1 = arg0; + stack_dump2 = arg1; + structdump_4 = script_4341(stack_dump0, stack_dump1, stack_dump2); + svar1 = structdump_4.stringpart_1; + svar0 = structdump_4.stringpart_0; + if (((boolean)mod(getClientCycle(), 100))) { + setWidgetText(new WidgetPointer(arg4), svar0 + ":" + svar1); + } else { + setWidgetText(new WidgetPointer(arg4), svar0 + " " + svar1); + } + } + } + return; +} diff --git a/dumps/scripts/4343.cs2 b/dumps/scripts/4343.cs2 new file mode 100644 index 0000000..9d092cb --- /dev/null +++ b/dumps/scripts/4343.cs2 @@ -0,0 +1,95 @@ +void script_4343(int arg0) { + string svar0; + string svar1; + string svar2; + string svar3; + string svar4; + string svar5; + string svar6; + string svar7; + string svar8; + string svar9; + string svar10; + cs2func_script_4721_struct(0,10,0) structdump_0; + svar0 = ""; + svar1 = ""; + svar2 = ""; + svar3 = ""; + svar4 = ""; + svar5 = ""; + svar6 = ""; + svar7 = ""; + svar8 = ""; + svar9 = ""; + svar10 = ""; + structdump_0 = script_4721(); + svar9 = structdump_0.stringpart_9; + svar8 = structdump_0.stringpart_8; + svar7 = structdump_0.stringpart_7; + svar6 = structdump_0.stringpart_6; + svar5 = structdump_0.stringpart_5; + svar4 = structdump_0.stringpart_4; + svar3 = structdump_0.stringpart_3; + svar2 = structdump_0.stringpart_2; + svar1 = structdump_0.stringpart_1; + svar0 = structdump_0.stringpart_0; + if (stringMethod4107(svar0, "") != 0) { + svar10 = svar0; + } + if (stringMethod4107(svar1, "") != 0) { + if (strLength(svar10) > 0) { + svar10 = concat(svar10, ", "); + } + svar10 = concat(svar10, svar1); + } + if (stringMethod4107(svar2, "") != 0) { + if (strLength(svar10) > 0) { + svar10 = concat(svar10, ", "); + } + svar10 = concat(svar10, svar2); + } + if (stringMethod4107(svar3, "") != 0) { + if (strLength(svar10) > 0) { + svar10 = concat(svar10, ", "); + } + svar10 = concat(svar10, svar3); + } + if (stringMethod4107(svar4, "") != 0) { + if (strLength(svar10) > 0) { + svar10 = concat(svar10, ", "); + } + svar10 = concat(svar10, svar4); + } + if (stringMethod4107(svar5, "") != 0) { + if (strLength(svar10) > 0) { + svar10 = concat(svar10, ", "); + } + svar10 = concat(svar10, svar5); + } + if (stringMethod4107(svar6, "") != 0) { + if (strLength(svar10) > 0) { + svar10 = concat(svar10, ", "); + } + svar10 = concat(svar10, svar6); + } + if (stringMethod4107(svar7, "") != 0) { + if (strLength(svar10) > 0) { + svar10 = concat(svar10, ", "); + } + svar10 = concat(svar10, svar7); + } + if (stringMethod4107(svar8, "") != 0) { + if (strLength(svar10) > 0) { + svar10 = concat(svar10, ", "); + } + svar10 = concat(svar10, svar8); + } + if (stringMethod4107(svar9, "") != 0) { + if (strLength(svar10) > 0) { + svar10 = concat(svar10, ", "); + } + svar10 = concat(svar10, svar9); + } + setWidgetText(new WidgetPointer(arg0), svar10); + return; +} diff --git a/dumps/scripts/4344.cs2 b/dumps/scripts/4344.cs2 new file mode 100644 index 0000000..39e0e98 --- /dev/null +++ b/dumps/scripts/4344.cs2 @@ -0,0 +1,225 @@ +cs2func_script_4344_struct(5,0,0) script_4344(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9) { + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + string svar0; + int stack_dump0; + int stack_dump1; + int stack_dump2; + int stack_dump3; + int stack_dump4; + int stack_dump5; + int stack_dump6; + int stack_dump7; + int stack_dump8; + int stack_dump9; + int stack_dump10; + cs2func_script_5351_struct(5,0,0) structdump_11; + flow_0: + ivar10 = 74907707; + ivar11 = 0; + ivar12 = -1; + svar0 = ""; + ivar13 = 0; + ivar14 = 5182; + globalarray_0 = new int[getCommonDefinitionSize(ivar14)]; + ivar15 = 0; + ivar16 = -1; + ivar17 = 0; + while (ivar17 < getCommonDefinitionSize(ivar14)) { + globalarray_0[ivar17] = cs2method_3408(105, 74, ivar14, ivar17); + ivar17 = add(ivar17, 1); + } + ivar17 = 0; + ivar15 = 1; + ivar18 = 0; + ivar19 = 0; + SWITCH (globalint_1659) { + case 1: + GOTO flow_18 + case 2: + GOTO flow_32 + case 3: + GOTO flow_40 + } + while (((boolean)ivar15)) { + ivar15 = 0; + ivar17 = subtract(getCommonDefinitionSize(ivar14), 1); + while (ivar17 > 0) { + if (getOtherCommonData(globalarray_0[ivar17], 1933) > 0) { + ivar18 = getOtherCommonData(globalarray_0[ivar17], 1933); + } else { + ivar18 = getOtherCommonData(globalarray_0[ivar17], 1932); + } + if (getOtherCommonData(globalarray_0[subtract(ivar17, 1)], 1933) > 0) { + ivar19 = getOtherCommonData(globalarray_0[subtract(ivar17, 1)], 1933); + } else { + ivar19 = getOtherCommonData(globalarray_0[subtract(ivar17, 1)], 1932); + } + if (ivar18 < ivar19) { + ivar15 = 1; + ivar16 = globalarray_0[subtract(ivar17, 1)]; + globalarray_0[subtract(ivar17, 1)] = globalarray_0[ivar17]; + globalarray_0[ivar17] = ivar16; + } + ivar17 = subtract(ivar17, 1); + } + } + flow_17: + GOTO flow_47 + flow_18: + IF (((boolean)ivar15)) + GOTO flow_19 + GOTO flow_31 + flow_19: + ivar15 = 0; + ivar17 = subtract(getCommonDefinitionSize(ivar14), 1); + while (ivar17 > 0) { + if (getOtherCommonData(globalarray_0[ivar17], 1933) > 0) { + ivar18 = getOtherCommonData(globalarray_0[ivar17], 1933); + } else { + ivar18 = getOtherCommonData(globalarray_0[ivar17], 1932); + } + if (getOtherCommonData(globalarray_0[subtract(ivar17, 1)], 1933) > 0) { + ivar19 = getOtherCommonData(globalarray_0[subtract(ivar17, 1)], 1933); + } else { + ivar19 = getOtherCommonData(globalarray_0[subtract(ivar17, 1)], 1932); + } + if (ivar18 > ivar19) { + ivar15 = 1; + ivar16 = globalarray_0[subtract(ivar17, 1)]; + globalarray_0[subtract(ivar17, 1)] = globalarray_0[ivar17]; + globalarray_0[ivar17] = ivar16; + } + ivar17 = subtract(ivar17, 1); + } + GOTO flow_18 + flow_31: + GOTO flow_47 + flow_32: + IF (((boolean)ivar15)) + GOTO flow_33 + GOTO flow_39 + flow_33: + ivar15 = 0; + ivar17 = subtract(getCommonDefinitionSize(ivar14), 1); + while (ivar17 > 0) { + if (stringMethod4107(getOtherCommonData(globalarray_0[ivar17], 1930), getOtherCommonData(globalarray_0[subtract(ivar17, 1)], 1930)) < 0) { + ivar15 = 1; + ivar16 = globalarray_0[subtract(ivar17, 1)]; + globalarray_0[subtract(ivar17, 1)] = globalarray_0[ivar17]; + globalarray_0[ivar17] = ivar16; + } + ivar17 = subtract(ivar17, 1); + } + GOTO flow_32 + flow_39: + GOTO flow_47 + flow_40: + IF (((boolean)ivar15)) + GOTO flow_41 + GOTO flow_47 + flow_41: + ivar15 = 0; + ivar17 = subtract(getCommonDefinitionSize(ivar14), 1); + while (ivar17 > 0) { + if (stringMethod4107(getOtherCommonData(globalarray_0[ivar17], 1930), getOtherCommonData(globalarray_0[subtract(ivar17, 1)], 1930)) > 0) { + ivar15 = 1; + ivar16 = globalarray_0[subtract(ivar17, 1)]; + globalarray_0[subtract(ivar17, 1)] = globalarray_0[ivar17]; + globalarray_0[ivar17] = ivar16; + } + ivar17 = subtract(ivar17, 1); + } + GOTO flow_40 + flow_47: + ivar17 = 0; + ivar20 = 1; + while (ivar20 <= 3) { + createExtraChild(new WidgetPointer(ivar10), 4, arg5); + arg5 = add(arg5, 1); + if (((boolean)ivar20)) { + setWidgetPosition(11, arg4, 0, 0); + } else { + arg2 = add(add(arg2, arg3), arg4); + setWidgetPosition(11, arg2, 0, 0); + } + ivar11 = getWidgetActualY(); + setWidgetSize(subtract(getWidgetActualWidth(new WidgetPointer(ivar10)), 20), 13, 0, 0); + switch (ivar20) { + case 1: + setWidgetText("Tier 1"); + break; + case 2: + setWidgetText("Tier 2"); + break; + case 3: + setWidgetText("Tier 3"); + break; + case 4: + setWidgetText("Tier 4"); + } + setWidgetFont(4040); + setWidgetUnknownBoolean(true); + setWidgetRGB(new Color(230, 190, 120)); + setWidgetTextAlignment(0, 1, 13); + if (((boolean)ivar20)) { + createExtraChild(new WidgetPointer(ivar10), 4, arg5); + arg5 = add(arg5, 1); + setWidgetPosition(7, ivar11, 2, 0); + setWidgetSize(subtract(getWidgetActualWidth(new WidgetPointer(ivar10)), 20), 13, 0, 0); + setWidgetText("Scroll Down For More Tiers"); + setWidgetFont(4040); + setWidgetUnknownBoolean(true); + setWidgetRGB(new Color(230, 190, 120)); + setWidgetTextAlignment(2, 1, 13); + } + createExtraChild(new WidgetPointer(ivar10), 3, arg5); + arg5 = add(arg5, 1); + if (((boolean)ivar20)) { + setWidgetPosition(11, 23, 0, 0); + } else { + arg2 = add(arg2, 17); + setWidgetPosition(11, arg2, 0, 0); + } + setWidgetSize(subtract(getWidgetActualWidth(new WidgetPointer(ivar10)), 20), 1, 0, 0); + setWidgetRGB(new Color(230, 190, 120)); + arg2 = add(getWidgetActualY(), getWidgetActualHeight()); + ivar17 = 0; + arg0 = 0; + arg1 = arg4; + while (ivar17 < getCommonDefinitionSize(ivar14)) { + ivar12 = globalarray_0[ivar17]; + if (getOtherCommonData(ivar12, 1993) == ivar20) { + stack_dump0 = ivar12; + stack_dump1 = arg0; + stack_dump2 = arg1; + stack_dump3 = arg2; + stack_dump4 = arg3; + stack_dump5 = arg4; + stack_dump6 = arg5; + stack_dump7 = arg6; + stack_dump8 = arg7; + stack_dump9 = arg8; + stack_dump10 = arg9; + structdump_11 = script_5351(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4, stack_dump5, stack_dump6, stack_dump7, stack_dump8, stack_dump9, stack_dump10); + arg5 = structdump_11.intpart_4; + arg3 = structdump_11.intpart_3; + arg2 = structdump_11.intpart_2; + arg1 = structdump_11.intpart_1; + arg0 = structdump_11.intpart_0; + } + ivar17 = add(ivar17, 1); + } + ivar20 = add(ivar20, 1); + } + return newstruct cs2func_script_4344_struct(arg0, arg1, arg2, arg3, arg5); +} diff --git a/dumps/scripts/4345.cs2 b/dumps/scripts/4345.cs2 new file mode 100644 index 0000000..bdbc493 --- /dev/null +++ b/dumps/scripts/4345.cs2 @@ -0,0 +1,11 @@ +string script_4345(int arg0,int arg1) { + int ivar2; + ivar2 = -1; + if ((arg0 > 0) && (arg1 > 0)) { + ivar2 = cs2method_3408(105, 103, 3703, arg0); + if (ivar2 != -1) { + return cs2method_3408(105, 115, ivar2, arg1); + } + } + return ""; +} diff --git a/dumps/scripts/4346.cs2 b/dumps/scripts/4346.cs2 new file mode 100644 index 0000000..60be561 --- /dev/null +++ b/dumps/scripts/4346.cs2 @@ -0,0 +1,13 @@ +void script_4346() { + script_4586(71893069, 71893169, bitconfig_9155, bitconfig_9156); + script_4586(71893080, 71893180, bitconfig_9157, bitconfig_9158); + script_4586(71893091, 71893181, bitconfig_9159, bitconfig_9160); + script_4586(71893102, 71893182, bitconfig_9161, bitconfig_9162); + script_4586(71893113, 71893183, bitconfig_9163, bitconfig_9164); + script_4586(71893124, 71893184, bitconfig_9165, bitconfig_9166); + script_4586(71893135, 71893185, bitconfig_9167, bitconfig_9168); + script_4586(71893146, 71893186, bitconfig_9169, bitconfig_9170); + script_4586(71893157, 71893187, bitconfig_9171, bitconfig_9172); + script_4586(71893179, 71893188, bitconfig_9173, bitconfig_9174); + return; +} diff --git a/dumps/scripts/4347.cs2 b/dumps/scripts/4347.cs2 new file mode 100644 index 0000000..80c0809 --- /dev/null +++ b/dumps/scripts/4347.cs2 @@ -0,0 +1,17 @@ +void script_4347() { + int ivar0; + ivar0 = -1; + if (standart_config_2136 > 0) { + ivar0 = cs2method_3408(105, 103, 3703, standart_config_2136); + if (ivar0 != -1) { + setWidgetIsHidden(true, new WidgetPointer(1097,219)); + cs2method2100(0, 0, new WidgetPointer(1097,224)); + script_4499(ivar0, 1, getCommonDefinitionSize(ivar0), 7, 71893205, 71893215, 71893217, 71893216, 71893222, "Select a keyword"); + } + } else { + setWidgetIsHidden(false, new WidgetPointer(1097,219)); + script_4501(71893205, "Select a keyword"); + script_4501(71893191, "Select a category"); + } + return; +} diff --git a/dumps/scripts/4348.cs2 b/dumps/scripts/4348.cs2 new file mode 100644 index 0000000..1006fe7 --- /dev/null +++ b/dumps/scripts/4348.cs2 @@ -0,0 +1,312 @@ +void script_4348() { + int ivar0; + int ivar1; + int ivar2; + int stack_dump0; + ddmmyyyy(3,0,0) structdump_1; + ddmmyyyy(3,0,0) structdump_2; + ddmmyyyy(3,0,0) structdump_3; + ddmmyyyy(3,0,0) structdump_4; + ddmmyyyy(3,0,0) structdump_5; + ddmmyyyy(3,0,0) structdump_6; + ddmmyyyy(3,0,0) structdump_7; + ddmmyyyy(3,0,0) structdump_8; + ivar0 = 0; + ivar1 = 0; + ivar2 = 0; + script_4501(71958746, "Day"); + script_4501(71958734, "Month"); + script_4501(71958724, "Year"); + script_4501(71958776, "World"); + script_4501(71958671, "Select Event Type"); + script_4501(71958686, "Select Event Place"); + script_4501(71958701, "Select Event Attendees"); + cs2method2100(0, 0, new WidgetPointer(1098,184)); + script_157(71958711, 71958712, 0, 1); + cs2method2100(0, 0, new WidgetPointer(1098,169)); + script_157(71958696, 71958697, 0, 1); + cs2method2100(0, 0, new WidgetPointer(1098,154)); + script_157(71958681, 71958682, 0, 1); + if (((boolean)bitconfig_9140)) { + setWidgetText(new WidgetPointer(1098,41), "All events relative to clan time"); + } else { + setWidgetText(new WidgetPointer(1098,41), "All events relative to game time"); + } + switch (standart_config_2128) { + case 1: + if (bitconfig_9115 > 0) { + stack_dump0 = bitconfig_9115; + structdump_1 = daysSinceReleaseToDMY(stack_dump0); + ivar2 = structdump_1.intpart_2; + ivar1 = structdump_1.intpart_1; + ivar0 = structdump_1.intpart_0; + ivar1 = add(ivar1, 1); + ivar2 = max(11, subtract(ivar2, 2000)); + } + if (ivar0 > 0) { + script_4501(71958746, cs2method_3408(105, 115, 3697, ivar0)); + } + if (ivar1 > 0) { + script_4501(71958734, cs2method_3408(105, 115, 3698, ivar1)); + } + if (ivar2 > 0) { + script_4501(71958724, cs2method_3408(105, 115, 3699, ivar2)); + } + script_4501(71958760, cs2method_3408(105, 115, 3695, bitconfig_9123)); + if (bitconfig_9107 > 0) { + script_4501(71958776, cs2method_3408(105, 115, 3700, bitconfig_9107)); + } + if (bitconfig_9091 > 0) { + script_4501(71958671, cs2method_3408(105, 115, 3687, bitconfig_9091)); + } + if (bitconfig_9099 > 0) { + script_4501(71958686, cs2method_3408(105, 115, 3696, bitconfig_9099)); + } + if (standart_config_2120 >= 0) { + script_4501(71958701, cs2method_3408(105, 115, 3725, standart_config_2120)); + } + script_4358(71958797); + break; + case 2: + if (bitconfig_9116 > 0) { + stack_dump0 = bitconfig_9116; + structdump_2 = daysSinceReleaseToDMY(stack_dump0); + ivar2 = structdump_2.intpart_2; + ivar1 = structdump_2.intpart_1; + ivar0 = structdump_2.intpart_0; + ivar1 = add(ivar1, 1); + ivar2 = max(11, subtract(ivar2, 2000)); + } + if (ivar0 > 0) { + script_4501(71958746, cs2method_3408(105, 115, 3697, ivar0)); + } + if (ivar1 > 0) { + script_4501(71958734, cs2method_3408(105, 115, 3698, ivar1)); + } + if (ivar2 > 0) { + script_4501(71958724, cs2method_3408(105, 115, 3699, ivar2)); + } + script_4501(71958760, cs2method_3408(105, 115, 3695, bitconfig_9124)); + if (bitconfig_9108 > 0) { + script_4501(71958776, cs2method_3408(105, 115, 3700, bitconfig_9108)); + } + if (bitconfig_9092 > 0) { + script_4501(71958671, cs2method_3408(105, 115, 3687, bitconfig_9092)); + } + if (bitconfig_9100 > 0) { + script_4501(71958686, cs2method_3408(105, 115, 3696, bitconfig_9100)); + } + if (standart_config_2121 >= 0) { + script_4501(71958701, cs2method_3408(105, 115, 3725, standart_config_2121)); + } + script_4358(71958806); + break; + case 3: + if (bitconfig_9117 > 0) { + stack_dump0 = bitconfig_9117; + structdump_3 = daysSinceReleaseToDMY(stack_dump0); + ivar2 = structdump_3.intpart_2; + ivar1 = structdump_3.intpart_1; + ivar0 = structdump_3.intpart_0; + ivar1 = add(ivar1, 1); + ivar2 = max(11, subtract(ivar2, 2000)); + } + if (ivar0 > 0) { + script_4501(71958746, cs2method_3408(105, 115, 3697, ivar0)); + } + if (ivar1 > 0) { + script_4501(71958734, cs2method_3408(105, 115, 3698, ivar1)); + } + if (ivar2 > 0) { + script_4501(71958724, cs2method_3408(105, 115, 3699, ivar2)); + } + script_4501(71958760, cs2method_3408(105, 115, 3695, bitconfig_9125)); + if (bitconfig_9109 > 0) { + script_4501(71958776, cs2method_3408(105, 115, 3700, bitconfig_9109)); + } + if (bitconfig_9093 > 0) { + script_4501(71958671, cs2method_3408(105, 115, 3687, bitconfig_9093)); + } + if (bitconfig_9101 > 0) { + script_4501(71958686, cs2method_3408(105, 115, 3696, bitconfig_9101)); + } + if (standart_config_2122 >= 0) { + script_4501(71958701, cs2method_3408(105, 115, 3725, standart_config_2122)); + } + script_4358(71958815); + break; + case 4: + if (bitconfig_9118 > 0) { + stack_dump0 = bitconfig_9118; + structdump_4 = daysSinceReleaseToDMY(stack_dump0); + ivar2 = structdump_4.intpart_2; + ivar1 = structdump_4.intpart_1; + ivar0 = structdump_4.intpart_0; + ivar1 = add(ivar1, 1); + ivar2 = max(11, subtract(ivar2, 2000)); + } + if (ivar0 > 0) { + script_4501(71958746, cs2method_3408(105, 115, 3697, ivar0)); + } + if (ivar1 > 0) { + script_4501(71958734, cs2method_3408(105, 115, 3698, ivar1)); + } + if (ivar2 > 0) { + script_4501(71958724, cs2method_3408(105, 115, 3699, ivar2)); + } + script_4501(71958760, cs2method_3408(105, 115, 3695, bitconfig_9126)); + if (bitconfig_9110 > 0) { + script_4501(71958776, cs2method_3408(105, 115, 3700, bitconfig_9110)); + } + if (bitconfig_9094 > 0) { + script_4501(71958671, cs2method_3408(105, 115, 3687, bitconfig_9094)); + } + if (bitconfig_9102 > 0) { + script_4501(71958686, cs2method_3408(105, 115, 3696, bitconfig_9102)); + } + if (standart_config_2123 >= 0) { + script_4501(71958701, cs2method_3408(105, 115, 3725, standart_config_2123)); + } + script_4358(71958824); + break; + case 5: + if (bitconfig_9119 > 0) { + stack_dump0 = bitconfig_9119; + structdump_5 = daysSinceReleaseToDMY(stack_dump0); + ivar2 = structdump_5.intpart_2; + ivar1 = structdump_5.intpart_1; + ivar0 = structdump_5.intpart_0; + ivar1 = add(ivar1, 1); + ivar2 = max(11, subtract(ivar2, 2000)); + } + if (ivar0 > 0) { + script_4501(71958746, cs2method_3408(105, 115, 3697, ivar0)); + } + if (ivar1 > 0) { + script_4501(71958734, cs2method_3408(105, 115, 3698, ivar1)); + } + if (ivar2 > 0) { + script_4501(71958724, cs2method_3408(105, 115, 3699, ivar2)); + } + script_4501(71958760, cs2method_3408(105, 115, 3695, bitconfig_9127)); + if (bitconfig_9111 > 0) { + script_4501(71958776, cs2method_3408(105, 115, 3700, bitconfig_9111)); + } + if (bitconfig_9095 > 0) { + script_4501(71958671, cs2method_3408(105, 115, 3687, bitconfig_9095)); + } + if (bitconfig_9103 > 0) { + script_4501(71958686, cs2method_3408(105, 115, 3696, bitconfig_9103)); + } + if (standart_config_2124 >= 0) { + script_4501(71958701, cs2method_3408(105, 115, 3725, standart_config_2124)); + } + script_4358(71958833); + break; + case 6: + if (bitconfig_9120 > 0) { + stack_dump0 = bitconfig_9120; + structdump_6 = daysSinceReleaseToDMY(stack_dump0); + ivar2 = structdump_6.intpart_2; + ivar1 = structdump_6.intpart_1; + ivar0 = structdump_6.intpart_0; + ivar1 = add(ivar1, 1); + ivar2 = max(11, subtract(ivar2, 2000)); + } + if (ivar0 > 0) { + script_4501(71958746, cs2method_3408(105, 115, 3697, ivar0)); + } + if (ivar1 > 0) { + script_4501(71958734, cs2method_3408(105, 115, 3698, ivar1)); + } + if (ivar2 > 0) { + script_4501(71958724, cs2method_3408(105, 115, 3699, ivar2)); + } + script_4501(71958760, cs2method_3408(105, 115, 3695, bitconfig_9128)); + if (bitconfig_9112 > 0) { + script_4501(71958776, cs2method_3408(105, 115, 3700, bitconfig_9112)); + } + if (bitconfig_9096 > 0) { + script_4501(71958671, cs2method_3408(105, 115, 3687, bitconfig_9096)); + } + if (bitconfig_9104 > 0) { + script_4501(71958686, cs2method_3408(105, 115, 3696, bitconfig_9104)); + } + if (standart_config_2125 >= 0) { + script_4501(71958701, cs2method_3408(105, 115, 3725, standart_config_2125)); + } + script_4358(71958842); + break; + case 7: + if (bitconfig_9121 > 0) { + stack_dump0 = bitconfig_9121; + structdump_7 = daysSinceReleaseToDMY(stack_dump0); + ivar2 = structdump_7.intpart_2; + ivar1 = structdump_7.intpart_1; + ivar0 = structdump_7.intpart_0; + ivar1 = add(ivar1, 1); + ivar2 = max(11, subtract(ivar2, 2000)); + } + if (ivar0 > 0) { + script_4501(71958746, cs2method_3408(105, 115, 3697, ivar0)); + } + if (ivar1 > 0) { + script_4501(71958734, cs2method_3408(105, 115, 3698, ivar1)); + } + if (ivar2 > 0) { + script_4501(71958724, cs2method_3408(105, 115, 3699, ivar2)); + } + script_4501(71958760, cs2method_3408(105, 115, 3695, bitconfig_9129)); + if (bitconfig_9113 > 0) { + script_4501(71958776, cs2method_3408(105, 115, 3700, bitconfig_9113)); + } + if (bitconfig_9097 > 0) { + script_4501(71958671, cs2method_3408(105, 115, 3687, bitconfig_9097)); + } + if (bitconfig_9105 > 0) { + script_4501(71958686, cs2method_3408(105, 115, 3696, bitconfig_9105)); + } + if (standart_config_2126 >= 0) { + script_4501(71958701, cs2method_3408(105, 115, 3725, standart_config_2126)); + } + script_4358(71958851); + break; + case 8: + if (bitconfig_9122 > 0) { + stack_dump0 = bitconfig_9122; + structdump_8 = daysSinceReleaseToDMY(stack_dump0); + ivar2 = structdump_8.intpart_2; + ivar1 = structdump_8.intpart_1; + ivar0 = structdump_8.intpart_0; + ivar1 = add(ivar1, 1); + ivar2 = max(11, subtract(ivar2, 2000)); + } + if (ivar0 > 0) { + script_4501(71958746, cs2method_3408(105, 115, 3697, ivar0)); + } + if (ivar1 > 0) { + script_4501(71958734, cs2method_3408(105, 115, 3698, ivar1)); + } + if (ivar2 > 0) { + script_4501(71958724, cs2method_3408(105, 115, 3699, ivar2)); + } + script_4501(71958760, cs2method_3408(105, 115, 3695, bitconfig_9130)); + if (bitconfig_9114 > 0) { + script_4501(71958776, cs2method_3408(105, 115, 3700, bitconfig_9114)); + } + if (bitconfig_9098 > 0) { + script_4501(71958671, cs2method_3408(105, 115, 3687, bitconfig_9098)); + } + if (bitconfig_9106 > 0) { + script_4501(71958686, cs2method_3408(105, 115, 3696, bitconfig_9106)); + } + if (standart_config_2127 >= 0) { + script_4501(71958701, cs2method_3408(105, 115, 3725, standart_config_2127)); + } + script_4358(71958860); + } + script_4353(71958575); + script_4356(71958577); + script_4350(); + return; +} diff --git a/dumps/scripts/4349.cs2 b/dumps/scripts/4349.cs2 new file mode 100644 index 0000000..9f579d7 --- /dev/null +++ b/dumps/scripts/4349.cs2 @@ -0,0 +1,4 @@ +void script_4349() { + script_4350(); + return; +} diff --git a/dumps/scripts/435.cs2 b/dumps/scripts/435.cs2 new file mode 100644 index 0000000..96aa8aa --- /dev/null +++ b/dumps/scripts/435.cs2 @@ -0,0 +1,4 @@ +void script_435() { + script_304(41111302); + return; +} diff --git a/dumps/scripts/4350.cs2 b/dumps/scripts/4350.cs2 new file mode 100644 index 0000000..c72caf8 --- /dev/null +++ b/dumps/scripts/4350.cs2 @@ -0,0 +1,67 @@ +void script_4350() { + int ivar0; + int ivar1; + ivar0 = -1; + ivar1 = 0; + switch (standart_config_2128) { + case 1: + ivar1 = bitconfig_9091; + break; + case 2: + ivar1 = bitconfig_9092; + break; + case 3: + ivar1 = bitconfig_9093; + break; + case 4: + ivar1 = bitconfig_9094; + break; + case 5: + ivar1 = bitconfig_9095; + break; + case 6: + ivar1 = bitconfig_9096; + break; + case 7: + ivar1 = bitconfig_9097; + break; + case 8: + ivar1 = bitconfig_9098; + } + if (ivar1 > 0) { + ivar0 = cs2method_3408(105, 103, 3689, ivar1); + if (ivar0 != -1) { + setWidgetIsHidden(true, new WidgetPointer(1098,135)); + cs2method2100(0, 0, new WidgetPointer(1098,140)); + switch (standart_config_2128) { + case 1: + script_4499(ivar0, 1, getCommonDefinitionSize(ivar0), 4, 71958657, 71958667, 71958669, 71958668, 71958791, cs2method_3408(105, 115, ivar0, bitconfig_9131)); + break; + case 2: + script_4499(ivar0, 1, getCommonDefinitionSize(ivar0), 4, 71958657, 71958667, 71958669, 71958668, 71958791, cs2method_3408(105, 115, ivar0, bitconfig_9132)); + break; + case 3: + script_4499(ivar0, 1, getCommonDefinitionSize(ivar0), 4, 71958657, 71958667, 71958669, 71958668, 71958791, cs2method_3408(105, 115, ivar0, bitconfig_9133)); + break; + case 4: + script_4499(ivar0, 1, getCommonDefinitionSize(ivar0), 4, 71958657, 71958667, 71958669, 71958668, 71958791, cs2method_3408(105, 115, ivar0, bitconfig_9134)); + break; + case 5: + script_4499(ivar0, 1, getCommonDefinitionSize(ivar0), 4, 71958657, 71958667, 71958669, 71958668, 71958791, cs2method_3408(105, 115, ivar0, bitconfig_9135)); + break; + case 6: + script_4499(ivar0, 1, getCommonDefinitionSize(ivar0), 4, 71958657, 71958667, 71958669, 71958668, 71958791, cs2method_3408(105, 115, ivar0, bitconfig_9136)); + break; + case 7: + script_4499(ivar0, 1, getCommonDefinitionSize(ivar0), 4, 71958657, 71958667, 71958669, 71958668, 71958791, cs2method_3408(105, 115, ivar0, bitconfig_9137)); + break; + case 8: + script_4499(ivar0, 1, getCommonDefinitionSize(ivar0), 4, 71958657, 71958667, 71958669, 71958668, 71958791, cs2method_3408(105, 115, ivar0, bitconfig_9138)); + } + return; + } + } + script_4501(71958657, "Select a sub-type"); + setWidgetIsHidden(false, new WidgetPointer(1098,135)); + return; +} diff --git a/dumps/scripts/4351.cs2 b/dumps/scripts/4351.cs2 new file mode 100644 index 0000000..20c5d35 --- /dev/null +++ b/dumps/scripts/4351.cs2 @@ -0,0 +1,9 @@ +void script_4351(int arg0) { + if (bitconfig_9139 == standart_config_2128) { + bitconfig_9139 = 0; + } else { + bitconfig_9139 = standart_config_2128; + } + script_4353(arg0); + return; +} diff --git a/dumps/scripts/4352.cs2 b/dumps/scripts/4352.cs2 new file mode 100644 index 0000000..29c0297 --- /dev/null +++ b/dumps/scripts/4352.cs2 @@ -0,0 +1,4 @@ +void script_4352(int arg0) { + script_4353(arg0); + return; +} diff --git a/dumps/scripts/4353.cs2 b/dumps/scripts/4353.cs2 new file mode 100644 index 0000000..352e923 --- /dev/null +++ b/dumps/scripts/4353.cs2 @@ -0,0 +1,8 @@ +void script_4353(int arg0) { + if (bitconfig_9139 == standart_config_2128) { + setWidgetSprite(5916, new WidgetPointer(arg0)); + } else { + setWidgetSprite(5920, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/4354.cs2 b/dumps/scripts/4354.cs2 new file mode 100644 index 0000000..dff4c3e --- /dev/null +++ b/dumps/scripts/4354.cs2 @@ -0,0 +1,61 @@ +void script_4354(int arg0) { + switch (standart_config_2128) { + case 1: + if (((boolean)bitconfig_9141)) { + bitconfig_9141 = 1; + } else { + bitconfig_9141 = 0; + } + break; + case 2: + if (((boolean)bitconfig_9142)) { + bitconfig_9142 = 1; + } else { + bitconfig_9142 = 0; + } + break; + case 3: + if (((boolean)bitconfig_9143)) { + bitconfig_9143 = 1; + } else { + bitconfig_9143 = 0; + } + break; + case 4: + if (((boolean)bitconfig_9144)) { + bitconfig_9144 = 1; + } else { + bitconfig_9144 = 0; + } + break; + case 5: + if (((boolean)bitconfig_9145)) { + bitconfig_9145 = 1; + } else { + bitconfig_9145 = 0; + } + break; + case 6: + if (((boolean)bitconfig_9146)) { + bitconfig_9146 = 1; + } else { + bitconfig_9146 = 0; + } + break; + case 7: + if (((boolean)bitconfig_9147)) { + bitconfig_9147 = 1; + } else { + bitconfig_9147 = 0; + } + break; + case 8: + if (((boolean)bitconfig_9148)) { + bitconfig_9148 = 1; + } else { + bitconfig_9148 = 0; + } + } + script_4356(arg0); + return; +} diff --git a/dumps/scripts/4355.cs2 b/dumps/scripts/4355.cs2 new file mode 100644 index 0000000..b01b730 --- /dev/null +++ b/dumps/scripts/4355.cs2 @@ -0,0 +1,4 @@ +void script_4355(int arg0) { + script_4356(arg0); + return; +} diff --git a/dumps/scripts/4356.cs2 b/dumps/scripts/4356.cs2 new file mode 100644 index 0000000..026d570 --- /dev/null +++ b/dumps/scripts/4356.cs2 @@ -0,0 +1,60 @@ +void script_4356(int arg0) { + switch (standart_config_2128) { + case 1: + if (((boolean)bitconfig_9141)) { + setWidgetSprite(5920, new WidgetPointer(arg0)); + } else { + setWidgetSprite(5916, new WidgetPointer(arg0)); + } + break; + case 2: + if (((boolean)bitconfig_9142)) { + setWidgetSprite(5920, new WidgetPointer(arg0)); + } else { + setWidgetSprite(5916, new WidgetPointer(arg0)); + } + break; + case 3: + if (((boolean)bitconfig_9143)) { + setWidgetSprite(5920, new WidgetPointer(arg0)); + } else { + setWidgetSprite(5916, new WidgetPointer(arg0)); + } + break; + case 4: + if (((boolean)bitconfig_9144)) { + setWidgetSprite(5920, new WidgetPointer(arg0)); + } else { + setWidgetSprite(5916, new WidgetPointer(arg0)); + } + break; + case 5: + if (((boolean)bitconfig_9145)) { + setWidgetSprite(5920, new WidgetPointer(arg0)); + } else { + setWidgetSprite(5916, new WidgetPointer(arg0)); + } + break; + case 6: + if (((boolean)bitconfig_9146)) { + setWidgetSprite(5920, new WidgetPointer(arg0)); + } else { + setWidgetSprite(5916, new WidgetPointer(arg0)); + } + break; + case 7: + if (((boolean)bitconfig_9147)) { + setWidgetSprite(5920, new WidgetPointer(arg0)); + } else { + setWidgetSprite(5916, new WidgetPointer(arg0)); + } + break; + case 8: + if (((boolean)bitconfig_9148)) { + setWidgetSprite(5920, new WidgetPointer(arg0)); + } else { + setWidgetSprite(5916, new WidgetPointer(arg0)); + } + } + return; +} diff --git a/dumps/scripts/4357.cs2 b/dumps/scripts/4357.cs2 new file mode 100644 index 0000000..4a6dc68 --- /dev/null +++ b/dumps/scripts/4357.cs2 @@ -0,0 +1,4 @@ +void script_4357(int arg0) { + script_4358(arg0); + return; +} diff --git a/dumps/scripts/4358.cs2 b/dumps/scripts/4358.cs2 new file mode 100644 index 0000000..11e0d7d --- /dev/null +++ b/dumps/scripts/4358.cs2 @@ -0,0 +1,36 @@ +void script_4358(int arg0) { + setWidgetIsHidden(true, new WidgetPointer(1098,268)); + setWidgetIsHidden(true, new WidgetPointer(1098,277)); + setWidgetIsHidden(true, new WidgetPointer(1098,286)); + setWidgetIsHidden(true, new WidgetPointer(1098,295)); + setWidgetIsHidden(true, new WidgetPointer(1098,304)); + setWidgetIsHidden(true, new WidgetPointer(1098,313)); + setWidgetIsHidden(true, new WidgetPointer(1098,322)); + setWidgetIsHidden(true, new WidgetPointer(1098,331)); + switch (arg0) { + case 71958797: + setWidgetIsHidden(false, new WidgetPointer(1098,268)); + break; + case 71958806: + setWidgetIsHidden(false, new WidgetPointer(1098,277)); + break; + case 71958815: + setWidgetIsHidden(false, new WidgetPointer(1098,286)); + break; + case 71958824: + setWidgetIsHidden(false, new WidgetPointer(1098,295)); + break; + case 71958833: + setWidgetIsHidden(false, new WidgetPointer(1098,304)); + break; + case 71958842: + setWidgetIsHidden(false, new WidgetPointer(1098,313)); + break; + case 71958851: + setWidgetIsHidden(false, new WidgetPointer(1098,322)); + break; + case 71958860: + setWidgetIsHidden(false, new WidgetPointer(1098,331)); + } + return; +} diff --git a/dumps/scripts/4359.cs2 b/dumps/scripts/4359.cs2 new file mode 100644 index 0000000..e445f98 --- /dev/null +++ b/dumps/scripts/4359.cs2 @@ -0,0 +1,8 @@ +void script_4359(int arg0) { + if (cs2method3700()) { + script_4361(arg0); + } else { + setScriptCallOnClanChatSettingsStuff(4360, new WidgetPointer(arg0), "I", new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/436.cs2 b/dumps/scripts/436.cs2 new file mode 100644 index 0000000..eaa09cd --- /dev/null +++ b/dumps/scripts/436.cs2 @@ -0,0 +1,10 @@ +void script_436(int arg0) { + if (arg0 == 67239958) { + setWidgetSprite(1135, new WidgetPointer(1026,21)); + setWidgetSprite(1134, new WidgetPointer(1026,23)); + } else { + setWidgetSprite(1134, new WidgetPointer(1026,21)); + setWidgetSprite(1135, new WidgetPointer(1026,23)); + } + return; +} diff --git a/dumps/scripts/4360.cs2 b/dumps/scripts/4360.cs2 new file mode 100644 index 0000000..556fe8a --- /dev/null +++ b/dumps/scripts/4360.cs2 @@ -0,0 +1,6 @@ +void script_4360(int arg0) { + if (cs2method3700()) { + script_4361(arg0); + } + return; +} diff --git a/dumps/scripts/4361.cs2 b/dumps/scripts/4361.cs2 new file mode 100644 index 0000000..72ed5db --- /dev/null +++ b/dumps/scripts/4361.cs2 @@ -0,0 +1,15 @@ +void script_4361(int arg0) { + script_4332(72024111, 72024121); + script_4334(72024131, 72024132); + script_4336(72024078); + script_4362(1, 72024162, 72024070, 72024071, clanbitconfig_98, clanbitconfig_106, clanbitconfig_74, clanbitconfig_114, clanbitconfig_82, clanbitconfig_90, clanconfig_65, clanbitconfig_132, clanlongconfig_122); + script_4362(2, 72024188, 72024189, 72024190, clanbitconfig_99, clanbitconfig_107, clanbitconfig_75, clanbitconfig_115, clanbitconfig_83, clanbitconfig_91, clanconfig_66, clanbitconfig_133, clanlongconfig_123); + script_4362(3, 72024191, 72024192, 72024193, clanbitconfig_100, clanbitconfig_108, clanbitconfig_76, clanbitconfig_116, clanbitconfig_84, clanbitconfig_92, clanconfig_67, clanbitconfig_134, clanlongconfig_124); + script_4362(4, 72024194, 72024195, 72024196, clanbitconfig_101, clanbitconfig_109, clanbitconfig_77, clanbitconfig_117, clanbitconfig_85, clanbitconfig_93, clanconfig_68, clanbitconfig_135, clanlongconfig_125); + script_4362(5, 72024197, 72024198, 72024199, clanbitconfig_102, clanbitconfig_110, clanbitconfig_78, clanbitconfig_118, clanbitconfig_86, clanbitconfig_94, clanconfig_69, clanbitconfig_136, clanlongconfig_126); + script_4362(6, 72024200, 72024201, 72024202, clanbitconfig_103, clanbitconfig_111, clanbitconfig_79, clanbitconfig_119, clanbitconfig_87, clanbitconfig_95, clanconfig_70, clanbitconfig_137, clanlongconfig_127); + script_4362(7, 72024203, 72024204, 72024205, clanbitconfig_104, clanbitconfig_112, clanbitconfig_80, clanbitconfig_120, clanbitconfig_88, clanbitconfig_96, clanconfig_71, clanbitconfig_138, clanlongconfig_128); + script_4362(8, 72024206, 72024207, 72024208, clanbitconfig_105, clanbitconfig_113, clanbitconfig_81, clanbitconfig_121, clanbitconfig_89, clanbitconfig_97, clanconfig_72, clanbitconfig_139, clanlongconfig_129); + setWidgetIsHidden(true, new WidgetPointer(1099,13)); + return; +} diff --git a/dumps/scripts/4362.cs2 b/dumps/scripts/4362.cs2 new file mode 100644 index 0000000..3b8ab37 --- /dev/null +++ b/dumps/scripts/4362.cs2 @@ -0,0 +1,27 @@ +void script_4362(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,long arg12) { + int ivar12; + string svar0; + if ((((boolean)arg9) || ((boolean)arg8)) || ((boolean)arg6)) { + setWidgetSprite(5936, new WidgetPointer(arg2)); + return; + } + ivar12 = cs2method_3408(105, 103, 3689, arg6); + svar0 = timeToStr(arg4) + " at " + cs2method_3408(105, 115, 3695, arg5); + if (((boolean)clanbitconfig_5)) { + svar0 = svar0 + " Game Time"; + } else { + svar0 = svar0 + " Clan Local Time"; + } + svar0 = svar0 + "
" + "
" + "World " + intToStr(arg9) + " at " + "
" + cs2method_3408(105, 115, 3696, arg8) + "
" + "
" + cs2method_3408(105, 115, 3687, arg6); + if ((ivar12 != -1) && (arg7 > 0)) { + svar0 = svar0 + "
" + cs2method_3408(105, 115, ivar12, arg7); + } + svar0 = svar0 + "
" + "
" + "Open to " + cs2method_3408(105, 115, 3716, arg10); + if (((boolean)arg11)) { + svar0 = svar0 + "
" + "Attendance is mandatory"; + } + setScriptCallOnClickContextMenu(4363, arg0, svar0, arg12, new WidgetPointer(arg2), arg4, arg5, arg9, arg8, arg6, "is\u00a7Iiiiii", new WidgetPointer(arg1)); + setWidgetSprite(cs2method_3408(105, 100, 3688, arg6), new WidgetPointer(arg3)); + setWidgetSprite(5932, new WidgetPointer(arg2)); + return; +} diff --git a/dumps/scripts/4363.cs2 b/dumps/scripts/4363.cs2 new file mode 100644 index 0000000..8bfea8f --- /dev/null +++ b/dumps/scripts/4363.cs2 @@ -0,0 +1,54 @@ +void script_4363(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,string arg7,long arg8) { + setWidgetText(new WidgetPointer(1099,109), arg7); + setWidgetSprite(5933, new WidgetPointer(arg1)); + if (arg8 != -1L) { + setScriptCallOnClickContextMenu(4330, arg8, "\u00a7", new WidgetPointer(1099,165)); + setWidgetIsHidden(true, new WidgetPointer(1099,168)); + } else { + setWidgetNoOptions(new WidgetPointer(1099,165)); + setWidgetIsHidden(false, new WidgetPointer(1099,168)); + } + if (cs2method3700()) { + if (((script_4616(arg2, arg3) > 0) && (arg4 > 0)) && ((arg5 > 0) && (arg6 > 0))) { + setWidgetIsHidden(false, new WidgetPointer(1099,110)); + } + script_4621(72024064); + } else { + setWidgetIsHidden(true, new WidgetPointer(1099,110)); + } + standart_config_2128 = arg0; + switch (arg0) { + case 1: + setWidgetSprite(5935, new WidgetPointer(1099,6)); + break; + case 2: + setWidgetSprite(5935, new WidgetPointer(1099,125)); + break; + case 3: + setWidgetSprite(5935, new WidgetPointer(1099,128)); + break; + case 4: + setWidgetSprite(5935, new WidgetPointer(1099,131)); + break; + case 5: + setWidgetSprite(5935, new WidgetPointer(1099,134)); + break; + case 6: + setWidgetSprite(5935, new WidgetPointer(1099,137)); + break; + case 7: + setWidgetSprite(5935, new WidgetPointer(1099,140)); + break; + case 8: + setWidgetSprite(5935, new WidgetPointer(1099,143)); + } + script_4624(72024070, 1); + script_4624(72024189, 2); + script_4624(72024192, 3); + script_4624(72024195, 4); + script_4624(72024198, 5); + script_4624(72024201, 6); + script_4624(72024204, 7); + script_4624(72024207, 8); + return; +} diff --git a/dumps/scripts/4364.cs2 b/dumps/scripts/4364.cs2 new file mode 100644 index 0000000..1d83e50 --- /dev/null +++ b/dumps/scripts/4364.cs2 @@ -0,0 +1,4 @@ +void script_4364() { + script_304(48146389); + return; +} diff --git a/dumps/scripts/4365.cs2 b/dumps/scripts/4365.cs2 new file mode 100644 index 0000000..2eec5ec --- /dev/null +++ b/dumps/scripts/4365.cs2 @@ -0,0 +1,5 @@ +void script_4365(int arg0) { + setWidgetIsHidden(true, new WidgetPointer(arg0)); + setWidgetText(new WidgetPointer(1099,109), ""); + return; +} diff --git a/dumps/scripts/4366.cs2 b/dumps/scripts/4366.cs2 new file mode 100644 index 0000000..3278fcc --- /dev/null +++ b/dumps/scripts/4366.cs2 @@ -0,0 +1,4 @@ +void script_4366() { + script_4367(); + return; +} diff --git a/dumps/scripts/4367.cs2 b/dumps/scripts/4367.cs2 new file mode 100644 index 0000000..74af767 --- /dev/null +++ b/dumps/scripts/4367.cs2 @@ -0,0 +1,12 @@ +void script_4367() { + string svar0; + svar0 = replaceLtGt(cs2method5432()); + if (strLength(svar0) <= 13) { + globalstring_346 = svar0; + globalint_1498 = strLength(globalstring_346); + globalint_1498 = script_1552(globalint_1498, 5631, 72089638, -1, globalstring_346); + setWidgetPosition(globalint_1498, getWidgetActualY(new WidgetPointer(1100,39)), 0, 0, new WidgetPointer(1100,39)); + setWidgetText(new WidgetPointer(1100,38), globalstring_346); + } + return; +} diff --git a/dumps/scripts/4368.cs2 b/dumps/scripts/4368.cs2 new file mode 100644 index 0000000..66f58c6 --- /dev/null +++ b/dumps/scripts/4368.cs2 @@ -0,0 +1,6 @@ +void script_4368(int arg0,int arg1) { + setScriptCallOnKeyPress(4369, new WidgetPointer(arg0), false, -2147483640, new WidgetPointer(arg1), "IziI", new WidgetPointer(arg0)); + setScriptCallOnMousePressed(4370, new WidgetPointer(arg0), new WidgetPointer(arg1), -2147483647, "IIi", new WidgetPointer(arg0)); + setScriptCallOnGameloop(1400, getClientCycle(), new WidgetPointer(arg1), "iI", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/4369.cs2 b/dumps/scripts/4369.cs2 new file mode 100644 index 0000000..825460b --- /dev/null +++ b/dumps/scripts/4369.cs2 @@ -0,0 +1,36 @@ +void script_4369(int arg0,int arg1,int arg2,int arg3) { + globalstring_346 = getWidgetText(new WidgetPointer(arg0)); + switch (arg2) { + case 84: + script_4372(1); + break; + case 102: + case 103: + case 98: + case 99: + case 96: + case 97: + if (isHoldingCtrl()) { + return; + } + script_1553(arg2, globalint_1498, globalstring_346); + break; + case 85: + if (strLength(globalstring_346) > 0) { + globalstring_346 = substr(0, subtract(strLength(globalstring_346), 1), globalstring_346); + } + break; + default: + if ((arg2 == 67) && isHoldingShift()) { + script_4367(); + return; + } + if (strLength(globalstring_346) < 13) { + globalstring_346 = script_74(0, arg2, arg1, globalstring_346); + } + } + globalint_1498 = script_1552(globalint_1498, 5631, arg0, -1, globalstring_346); + setWidgetPosition(globalint_1498, getWidgetActualY(new WidgetPointer(arg3)), 0, 0, new WidgetPointer(arg3)); + setWidgetText(new WidgetPointer(arg0), globalstring_346); + return; +} diff --git a/dumps/scripts/437.cs2 b/dumps/scripts/437.cs2 new file mode 100644 index 0000000..ebaa472 --- /dev/null +++ b/dumps/scripts/437.cs2 @@ -0,0 +1,28 @@ +void script_437() { + setWidgetSprite(1134, new WidgetPointer(1022,42)); + setWidgetSprite(1134, new WidgetPointer(1022,43)); + setWidgetSprite(1134, new WidgetPointer(1022,44)); + setWidgetSprite(1134, new WidgetPointer(1022,45)); + setWidgetSprite(1134, new WidgetPointer(1022,46)); + setWidgetSprite(1134, new WidgetPointer(1022,47)); + switch (bitconfig_8087) { + case 0: + setWidgetSprite(1135, new WidgetPointer(1022,42)); + break; + case 1: + setWidgetSprite(1135, new WidgetPointer(1022,43)); + break; + case 2: + setWidgetSprite(1135, new WidgetPointer(1022,44)); + break; + case 3: + setWidgetSprite(1135, new WidgetPointer(1022,45)); + break; + case 4: + setWidgetSprite(1135, new WidgetPointer(1022,46)); + break; + case 5: + setWidgetSprite(1135, new WidgetPointer(1022,47)); + } + return; +} diff --git a/dumps/scripts/4370.cs2 b/dumps/scripts/4370.cs2 new file mode 100644 index 0000000..c5afebe --- /dev/null +++ b/dumps/scripts/4370.cs2 @@ -0,0 +1,6 @@ +void script_4370(int arg0,int arg1,int arg2) { + globalstring_346 = getWidgetText(new WidgetPointer(arg0)); + globalint_1498 = script_1552(globalint_1498, 5631, arg0, -1, globalstring_346); + setWidgetPosition(globalint_1498, 5, 0, 0, new WidgetPointer(arg1)); + return; +} diff --git a/dumps/scripts/4371.cs2 b/dumps/scripts/4371.cs2 new file mode 100644 index 0000000..fb3616d --- /dev/null +++ b/dumps/scripts/4371.cs2 @@ -0,0 +1,4 @@ +void script_4371(int arg0) { + script_4372(arg0); + return; +} diff --git a/dumps/scripts/4372.cs2 b/dumps/scripts/4372.cs2 new file mode 100644 index 0000000..3ff2e53 --- /dev/null +++ b/dumps/scripts/4372.cs2 @@ -0,0 +1,8 @@ +void script_4372(int arg0) { + if (((boolean)arg0)) { + sendUnknownPacketMethod3117(globalstring_346); + } else { + sendUnknownPacketMethod3117(""); + } + return; +} diff --git a/dumps/scripts/4373.cs2 b/dumps/scripts/4373.cs2 new file mode 100644 index 0000000..aa24af0 --- /dev/null +++ b/dumps/scripts/4373.cs2 @@ -0,0 +1,4 @@ +void script_4373() { + script_4374(); + return; +} diff --git a/dumps/scripts/4374.cs2 b/dumps/scripts/4374.cs2 new file mode 100644 index 0000000..86bee37 --- /dev/null +++ b/dumps/scripts/4374.cs2 @@ -0,0 +1,5 @@ +void script_4374() { + setWidgetIsHidden(false, new WidgetPointer(1101,53)); + setWidgetIsHidden(false, new WidgetPointer(1101,32)); + return; +} diff --git a/dumps/scripts/4375.cs2 b/dumps/scripts/4375.cs2 new file mode 100644 index 0000000..bac3b91 --- /dev/null +++ b/dumps/scripts/4375.cs2 @@ -0,0 +1,4 @@ +void script_4375() { + script_4376(); + return; +} diff --git a/dumps/scripts/4376.cs2 b/dumps/scripts/4376.cs2 new file mode 100644 index 0000000..7e82a87 --- /dev/null +++ b/dumps/scripts/4376.cs2 @@ -0,0 +1,5 @@ +void script_4376() { + setWidgetIsHidden(true, new WidgetPointer(1101,53)); + setWidgetIsHidden(true, new WidgetPointer(1101,32)); + return; +} diff --git a/dumps/scripts/4377.cs2 b/dumps/scripts/4377.cs2 new file mode 100644 index 0000000..547f310 --- /dev/null +++ b/dumps/scripts/4377.cs2 @@ -0,0 +1,37 @@ +void script_4377() { + int ivar0; + int ivar1; + int ivar2; + if (standart_config_2134 == globalint_1499) { + setWidgetText(new WidgetPointer(1101,82), "You have voted."); + } else { + setWidgetText(new WidgetPointer(1101,82), "You have not yet voted." + "
" + "How would you like to vote?"); + } + if (((boolean)bitconfig_9151)) { + setWidgetText(new WidgetPointer(1101,12), "Results of last vote:"); + } else if (((boolean)bitconfig_9154) || ((boolean)bitconfig_9154)) { + setWidgetText(new WidgetPointer(1101,12), "Vote open for less than a minute."); + } else { + setWidgetText(new WidgetPointer(1101,12), "Vote open for less than " + intToStr(bitconfig_9154) + " minutes."); + } + ivar0 = add(bitconfig_9149, bitconfig_9150); + ivar1 = 0; + ivar2 = 0; + if (ivar0 > 0) { + if (ivar0 == bitconfig_9149) { + ivar1 = 100; + } else if (ivar0 == bitconfig_9150) { + ivar2 = 100; + } else if (((boolean)bitconfig_9150)) { + ivar2 = 0; + } else { + ivar2 = subtract(100, ivar1); + } + ivar1 = divide(multiply(100, bitconfig_9149), ivar0); + } + setWidgetText(new WidgetPointer(1101,7), intToStr(bitconfig_9149)); + setWidgetText(new WidgetPointer(1101,8), intToStr(bitconfig_9150)); + script_4542(ivar1, 72155195, 72155200); + script_4542(ivar2, 72155205, 72155210); + return; +} diff --git a/dumps/scripts/4378.cs2 b/dumps/scripts/4378.cs2 new file mode 100644 index 0000000..52c4908 --- /dev/null +++ b/dumps/scripts/4378.cs2 @@ -0,0 +1,6 @@ +void script_4378(int arg0,int arg1,int arg2) { + setScriptCallOnKeyPress(4379, new WidgetPointer(arg0), new WidgetPointer(arg1), false, -2147483640, new WidgetPointer(arg2), "IIziI", new WidgetPointer(arg0)); + setScriptCallOnMousePressed(4380, new WidgetPointer(arg0), new WidgetPointer(arg2), -2147483647, "IIi", new WidgetPointer(arg0)); + setScriptCallOnGameloop(1400, getClientCycle(), new WidgetPointer(arg2), "iI", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/4379.cs2 b/dumps/scripts/4379.cs2 new file mode 100644 index 0000000..f56d69b --- /dev/null +++ b/dumps/scripts/4379.cs2 @@ -0,0 +1,38 @@ +void script_4379(int arg0,int arg1,int arg2,int arg3,int arg4) { + globalstring_345 = getWidgetText(new WidgetPointer(arg0)); + switch (arg3) { + case 84: + script_4382(); + break; + case 102: + case 103: + case 98: + case 99: + case 96: + case 97: + if (isHoldingCtrl()) { + return; + } + script_1553(arg3, globalint_1496, globalstring_345); + break; + case 85: + if (strLength(globalstring_345) > 0) { + globalstring_345 = substr(0, subtract(strLength(globalstring_345), 1), globalstring_345); + } + break; + default: + if (strLength(globalstring_345) < 80) { + globalstring_345 = script_74(0, arg3, arg2, globalstring_345); + } + } + globalint_1496 = script_1552(globalint_1496, 5631, arg0, -1, globalstring_345); + setWidgetPosition(globalint_1496, getWidgetActualY(new WidgetPointer(arg4)), 0, 0, new WidgetPointer(arg4)); + setWidgetText(new WidgetPointer(arg1), intToStr(strLength(globalstring_345)) + "/80"); + if (strLength(globalstring_345) >= 70) { + setWidgetRGB(new Color(221, 0, 0), new WidgetPointer(arg1)); + } else { + setWidgetRGB(new Color(31, 29, 25), new WidgetPointer(arg1)); + } + setWidgetText(new WidgetPointer(arg0), globalstring_345); + return; +} diff --git a/dumps/scripts/438.cs2 b/dumps/scripts/438.cs2 new file mode 100644 index 0000000..3da59ac --- /dev/null +++ b/dumps/scripts/438.cs2 @@ -0,0 +1,28 @@ +void script_438(int arg0) { + setWidgetSprite(1134, new WidgetPointer(1022,42)); + setWidgetSprite(1134, new WidgetPointer(1022,43)); + setWidgetSprite(1134, new WidgetPointer(1022,44)); + setWidgetSprite(1134, new WidgetPointer(1022,45)); + setWidgetSprite(1134, new WidgetPointer(1022,46)); + setWidgetSprite(1134, new WidgetPointer(1022,47)); + switch (arg0) { + case 66977840: + setWidgetSprite(1135, new WidgetPointer(1022,42)); + break; + case 66977841: + setWidgetSprite(1135, new WidgetPointer(1022,43)); + break; + case 66977842: + setWidgetSprite(1135, new WidgetPointer(1022,44)); + break; + case 66977843: + setWidgetSprite(1135, new WidgetPointer(1022,45)); + break; + case 66977844: + setWidgetSprite(1135, new WidgetPointer(1022,46)); + break; + case 66977845: + setWidgetSprite(1135, new WidgetPointer(1022,47)); + } + return; +} diff --git a/dumps/scripts/4380.cs2 b/dumps/scripts/4380.cs2 new file mode 100644 index 0000000..a0b8e71 --- /dev/null +++ b/dumps/scripts/4380.cs2 @@ -0,0 +1,6 @@ +void script_4380(int arg0,int arg1,int arg2) { + globalstring_345 = getWidgetText(new WidgetPointer(arg0)); + globalint_1496 = script_1552(arg2, 5631, arg0, -1, globalstring_345); + setWidgetPosition(globalint_1496, 5, 0, 0, new WidgetPointer(arg1)); + return; +} diff --git a/dumps/scripts/4381.cs2 b/dumps/scripts/4381.cs2 new file mode 100644 index 0000000..d7e2eef --- /dev/null +++ b/dumps/scripts/4381.cs2 @@ -0,0 +1,4 @@ +void script_4381() { + script_4382(); + return; +} diff --git a/dumps/scripts/4382.cs2 b/dumps/scripts/4382.cs2 new file mode 100644 index 0000000..54c427a --- /dev/null +++ b/dumps/scripts/4382.cs2 @@ -0,0 +1,4 @@ +void script_4382() { + sendStringInput(strRemoveEntities(globalstring_345)); + return; +} diff --git a/dumps/scripts/4383.cs2 b/dumps/scripts/4383.cs2 new file mode 100644 index 0000000..471e110 --- /dev/null +++ b/dumps/scripts/4383.cs2 @@ -0,0 +1,18 @@ +cs2func_script_4383_struct(2,0,0) script_4383(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + ivar3 = cs2method_3408(105, 120, 3685, arg0); + ivar4 = cs2method_3408(105, 120, 3685, arg1); + if (((boolean)arg2) && (((boolean)clanbitconfig_10) || (cs2method3709() < 5))) { + ivar3 = 1080; + ivar4 = 1017; + } else { + if (ivar3 == -1) { + ivar3 = 1080; + } + if (ivar4 == -1) { + ivar4 = 1017; + } + } + return newstruct cs2func_script_4383_struct(ivar3, ivar4); +} diff --git a/dumps/scripts/4384.cs2 b/dumps/scripts/4384.cs2 new file mode 100644 index 0000000..1825684 --- /dev/null +++ b/dumps/scripts/4384.cs2 @@ -0,0 +1,18 @@ +cs2func_script_4384_struct(2,0,0) script_4384(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + ivar3 = cs2method_3408(105, 100, 3686, arg0); + ivar4 = cs2method_3408(105, 100, 3686, arg1); + if (((boolean)arg2) && (((boolean)clanbitconfig_10) || (cs2method3709() < 5))) { + ivar3 = 5723; + ivar4 = 5789; + } else { + if (ivar3 == -1) { + ivar3 = 5723; + } + if (ivar4 == -1) { + ivar4 = 5789; + } + } + return newstruct cs2func_script_4384_struct(ivar3, ivar4); +} diff --git a/dumps/scripts/4385.cs2 b/dumps/scripts/4385.cs2 new file mode 100644 index 0000000..943ce59 --- /dev/null +++ b/dumps/scripts/4385.cs2 @@ -0,0 +1,6 @@ +void script_4385() { + setScriptCallOnConfigChange(4390, new WidgetPointer(1105,56), 2093, 2094, 2095, 2096, 2097, 5, "IY", new WidgetPointer(1105,55)); + script_4391(72417336); + script_4392(72417336); + return; +} diff --git a/dumps/scripts/4386.cs2 b/dumps/scripts/4386.cs2 new file mode 100644 index 0000000..8218223 --- /dev/null +++ b/dumps/scripts/4386.cs2 @@ -0,0 +1,4 @@ +void script_4386(int arg0,int arg1,int arg2,int arg3) { + script_4393(arg0, arg1, arg2, arg3, 3686); + return; +} diff --git a/dumps/scripts/4387.cs2 b/dumps/scripts/4387.cs2 new file mode 100644 index 0000000..d9dfebd --- /dev/null +++ b/dumps/scripts/4387.cs2 @@ -0,0 +1,4 @@ +void script_4387(int arg0,int arg1,int arg2,int arg3) { + script_4393(arg0, arg1, arg2, arg3, 3686); + return; +} diff --git a/dumps/scripts/4388.cs2 b/dumps/scripts/4388.cs2 new file mode 100644 index 0000000..6a32605 --- /dev/null +++ b/dumps/scripts/4388.cs2 @@ -0,0 +1,23 @@ +void script_4388(int arg0,int arg1) { + int ivar2; + int ivar3; + int stack_dump0; + int stack_dump1; + int stack_dump2; + cs2func_script_4384_struct(2,0,0) structdump_3; + ivar2 = -1; + ivar3 = -1; + if (cs2method3701()) { + stack_dump0 = bitconfig_9086; + stack_dump1 = bitconfig_9087; + stack_dump2 = 0; + structdump_3 = script_4384(stack_dump0, stack_dump1, stack_dump2); + ivar3 = structdump_3.intpart_1; + ivar2 = structdump_3.intpart_0; + setWidgetSprite(ivar2, new WidgetPointer(arg0)); + setWidgetSprite(ivar3, new WidgetPointer(arg1)); + setWidgetRGB(new Color(getColorRelatedMethod4020(standart_config_2094)), new WidgetPointer(arg0)); + setWidgetRGB(new Color(getColorRelatedMethod4020(standart_config_2095)), new WidgetPointer(arg1)); + } + return; +} diff --git a/dumps/scripts/4389.cs2 b/dumps/scripts/4389.cs2 new file mode 100644 index 0000000..b3f5dee --- /dev/null +++ b/dumps/scripts/4389.cs2 @@ -0,0 +1,5 @@ +void script_4389(int arg0,int arg1) { + setWidgetRGB(new Color(getColorRelatedMethod4020(standart_config_2096)), new WidgetPointer(arg0)); + setWidgetRGB(new Color(getColorRelatedMethod4020(standart_config_2097)), new WidgetPointer(arg1)); + return; +} diff --git a/dumps/scripts/439.cs2 b/dumps/scripts/439.cs2 new file mode 100644 index 0000000..8cb3cdd --- /dev/null +++ b/dumps/scripts/439.cs2 @@ -0,0 +1,22 @@ +void script_439(int arg0) { + switch (bitconfig_8087) { + case 0: + setWidgetText(new WidgetPointer(arg0), "0:30"); + break; + case 1: + setWidgetText(new WidgetPointer(arg0), "1:00"); + break; + case 2: + setWidgetText(new WidgetPointer(arg0), "1:30"); + break; + case 3: + setWidgetText(new WidgetPointer(arg0), "2:00"); + break; + case 4: + setWidgetText(new WidgetPointer(arg0), "2:30"); + break; + case 5: + setWidgetText(new WidgetPointer(arg0), "3:00"); + } + return; +} diff --git a/dumps/scripts/4390.cs2 b/dumps/scripts/4390.cs2 new file mode 100644 index 0000000..ad444ed --- /dev/null +++ b/dumps/scripts/4390.cs2 @@ -0,0 +1,5 @@ +void script_4390(int arg0) { + script_4391(arg0); + script_4392(arg0); + return; +} diff --git a/dumps/scripts/4391.cs2 b/dumps/scripts/4391.cs2 new file mode 100644 index 0000000..18d4420 --- /dev/null +++ b/dumps/scripts/4391.cs2 @@ -0,0 +1,21 @@ +void script_4391(int arg0) { + int ivar1; + int ivar2; + int stack_dump0; + int stack_dump1; + int stack_dump2; + cs2func_script_4383_struct(2,0,0) structdump_3; + ivar1 = -1; + ivar2 = -1; + if (cs2method3701()) { + stack_dump0 = bitconfig_9086; + stack_dump1 = bitconfig_9087; + stack_dump2 = 0; + structdump_3 = script_4383(stack_dump0, stack_dump1, stack_dump2); + ivar2 = structdump_3.intpart_1; + ivar1 = structdump_3.intpart_0; + doWidgetType19Task(0, 1024, ivar1, new WidgetPointer(arg0)); + doWidgetType19Task(1, 1057, ivar2, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/4392.cs2 b/dumps/scripts/4392.cs2 new file mode 100644 index 0000000..368544b --- /dev/null +++ b/dumps/scripts/4392.cs2 @@ -0,0 +1,15 @@ +void script_4392(int arg0) { + if (standart_config_2094 > 0) { + doWidgetType18Task(0, 31690, standart_config_2094, new WidgetPointer(arg0)); + } + if (standart_config_2095 > 0) { + doWidgetType18Task(1, 60362, standart_config_2095, new WidgetPointer(arg0)); + } + if (standart_config_2096 > 0) { + doWidgetType18Task(3, 55246, standart_config_2096, new WidgetPointer(arg0)); + } + if (standart_config_2097 > 0) { + doWidgetType18Task(4, 17358, standart_config_2097, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/4393.cs2 b/dumps/scripts/4393.cs2 new file mode 100644 index 0000000..dc57444 --- /dev/null +++ b/dumps/scripts/4393.cs2 @@ -0,0 +1,52 @@ +void script_4393(int arg0,int arg1,int arg2,int arg3,int arg4) { + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + deleteAllExtraChilds(new WidgetPointer(arg0)); + deleteAllExtraChilds(new WidgetPointer(arg1)); + ivar5 = 0; + ivar6 = 0; + ivar7 = 2; + ivar8 = 5; + ivar9 = 60; + ivar10 = 60; + ivar11 = 0; + ivar12 = 0; + ivar13 = divide(subtract(getWidgetActualWidth(new WidgetPointer(arg0)), ivar7), add(ivar7, ivar10)); + ivar14 = 0; + ivar15 = getCommonDefinitionSize(arg4); + while (ivar5 < ivar15) { + ivar11 = multiply(add(ivar10, ivar7), subtract(ivar5, multiply(ivar6, ivar13))); + ivar12 = multiply(ivar6, add(ivar9, ivar8)); + createExtraChild(new WidgetPointer(arg1), 5, ivar5); + setWidgetSize(ivar10, ivar9, 0, 0); + setWidgetPosition(ivar11, ivar12, 0, 0); + setWidgetSprite(5523); + setScriptCallOnConfigChange(4395, ivar15, 2093, 1, "iY"); + setScriptCallOnMouseEntered(4396, -2147483643, new WidgetPointer(arg1), "iI"); + setScriptCallOnMouseExit(4397, -2147483643, new WidgetPointer(arg1), "iI"); + ivar14 = add(add(getWidgetActualY(), getWidgetActualHeight()), ivar8); + createExtraChild(new WidgetPointer(arg0), 5, ivar5); + setWidgetSize(subtract(ivar10, 10), subtract(ivar9, 10), 0, 0); + setWidgetPosition(add(ivar11, 5), add(ivar12, 5), 0, 0); + setWidgetSprite(cs2method_3408(105, 100, arg4, add(ivar5, 1))); + setWidgetContextMenuOption(1, "Select"); + setScriptCallOnClickContextMenu(4394, -2147483643, new WidgetPointer(arg1), ivar15, "iIi"); + ivar5 = add(ivar5, 1); + if (((boolean)mod(ivar5, ivar13))) { + ivar6 = add(ivar6, 1); + } + } + cs2method2100(0, 0, new WidgetPointer(arg2)); + setWidgetScrollMax(0, ivar14, new WidgetPointer(arg2)); + script_31(arg3, arg2, 5666, 5663, 5664, 5665, 5686, 5685); + return; +} diff --git a/dumps/scripts/4394.cs2 b/dumps/scripts/4394.cs2 new file mode 100644 index 0000000..522daf0 --- /dev/null +++ b/dumps/scripts/4394.cs2 @@ -0,0 +1,4 @@ +void script_4394(int arg0,int arg1,int arg2) { + script_4398(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/4395.cs2 b/dumps/scripts/4395.cs2 new file mode 100644 index 0000000..3e702c1 --- /dev/null +++ b/dumps/scripts/4395.cs2 @@ -0,0 +1,9 @@ +void script_4395(int arg0) { + if (bitconfig_9086 > 0) { + script_4398(subtract(bitconfig_9086, 1), 72417345, arg0); + } + if (bitconfig_9087 > 0) { + script_4398(subtract(bitconfig_9087, 1), 72417342, arg0); + } + return; +} diff --git a/dumps/scripts/4396.cs2 b/dumps/scripts/4396.cs2 new file mode 100644 index 0000000..db1c389 --- /dev/null +++ b/dumps/scripts/4396.cs2 @@ -0,0 +1,6 @@ +void script_4396(int arg0,int arg1) { + if (setWidgetRegister(new WidgetPointer(arg1), arg0)) { + setWidgetSprite(5524); + } + return; +} diff --git a/dumps/scripts/4397.cs2 b/dumps/scripts/4397.cs2 new file mode 100644 index 0000000..6fa10e4 --- /dev/null +++ b/dumps/scripts/4397.cs2 @@ -0,0 +1,24 @@ +void script_4397(int arg0,int arg1) { + flow_0: + IF (setWidgetRegister(new WidgetPointer(arg1), arg0)) + GOTO flow_1 + GOTO flow_7 + flow_1: + IF (arg1 == 72417345) + GOTO flow_2 + GOTO flow_3 + flow_2: + IF (subtract(bitconfig_9086, 1) == arg0) + GOTO flow_5 + flow_3: + IF ((arg1 == 72417342) && (subtract(bitconfig_9087, 1) == arg0)) + GOTO flow_5 + GOTO flow_6 + flow_5: + setWidgetSprite(5526); + GOTO flow_7 + flow_6: + setWidgetSprite(5523); + flow_7: + return; +} diff --git a/dumps/scripts/4398.cs2 b/dumps/scripts/4398.cs2 new file mode 100644 index 0000000..d06dc4a --- /dev/null +++ b/dumps/scripts/4398.cs2 @@ -0,0 +1,14 @@ +void script_4398(int arg0,int arg1,int arg2) { + int ivar3; + ivar3 = 0; + while (ivar3 < arg2) { + if (setWidgetRegister(new WidgetPointer(arg1), ivar3)) { + setWidgetSprite(5523); + } + ivar3 = add(ivar3, 1); + } + if (setWidgetRegister(new WidgetPointer(arg1), arg0)) { + setWidgetSprite(5526); + } + return; +} diff --git a/dumps/scripts/4399.cs2 b/dumps/scripts/4399.cs2 new file mode 100644 index 0000000..a7de279 --- /dev/null +++ b/dumps/scripts/4399.cs2 @@ -0,0 +1,4 @@ +void script_4399(int arg0) { + script_4400(arg0); + return; +} diff --git a/dumps/scripts/44.cs2 b/dumps/scripts/44.cs2 new file mode 100644 index 0000000..a11b77a --- /dev/null +++ b/dumps/scripts/44.cs2 @@ -0,0 +1,4 @@ +void script_44(int arg0,int arg1) { + setWidgetSprite(arg1, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/440.cs2 b/dumps/scripts/440.cs2 new file mode 100644 index 0000000..c327720 --- /dev/null +++ b/dumps/scripts/440.cs2 @@ -0,0 +1,28 @@ +void script_440() { + setWidgetSprite(1134, new WidgetPointer(1016,24)); + setWidgetSprite(1134, new WidgetPointer(1016,25)); + setWidgetSprite(1134, new WidgetPointer(1016,26)); + setWidgetSprite(1134, new WidgetPointer(1016,27)); + setWidgetSprite(1134, new WidgetPointer(1016,28)); + setWidgetSprite(1134, new WidgetPointer(1016,29)); + switch (bitconfig_8087) { + case 0: + setWidgetSprite(1135, new WidgetPointer(1016,24)); + break; + case 1: + setWidgetSprite(1135, new WidgetPointer(1016,25)); + break; + case 2: + setWidgetSprite(1135, new WidgetPointer(1016,26)); + break; + case 3: + setWidgetSprite(1135, new WidgetPointer(1016,27)); + break; + case 4: + setWidgetSprite(1135, new WidgetPointer(1016,28)); + break; + case 5: + setWidgetSprite(1135, new WidgetPointer(1016,29)); + } + return; +} diff --git a/dumps/scripts/4400.cs2 b/dumps/scripts/4400.cs2 new file mode 100644 index 0000000..cf2a2c8 --- /dev/null +++ b/dumps/scripts/4400.cs2 @@ -0,0 +1,26 @@ +void script_4400(int arg0) { + setWidgetIsHidden(true, new WidgetPointer(1105,64)); + setWidgetIsHidden(true, new WidgetPointer(1105,67)); + setWidgetIsHidden(true, new WidgetPointer(1105,68)); + setWidgetIsHidden(true, new WidgetPointer(1105,69)); + setWidgetIsHidden(true, new WidgetPointer(1105,70)); + setWidgetIsHidden(true, new WidgetPointer(1105,167)); + setWidgetIsHidden(true, new WidgetPointer(1105,179)); + setWidgetIsHidden(true, new WidgetPointer(1105,191)); + switch (arg0) { + case 72417450: + setWidgetIsHidden(false, new WidgetPointer(1105,64)); + setWidgetIsHidden(false, new WidgetPointer(1105,67)); + setWidgetIsHidden(false, new WidgetPointer(1105,167)); + break; + case 72417462: + setWidgetIsHidden(false, new WidgetPointer(1105,68)); + setWidgetIsHidden(false, new WidgetPointer(1105,69)); + setWidgetIsHidden(false, new WidgetPointer(1105,179)); + break; + case 72417474: + setWidgetIsHidden(false, new WidgetPointer(1105,70)); + setWidgetIsHidden(false, new WidgetPointer(1105,191)); + } + return; +} diff --git a/dumps/scripts/4401.cs2 b/dumps/scripts/4401.cs2 new file mode 100644 index 0000000..e88b246 --- /dev/null +++ b/dumps/scripts/4401.cs2 @@ -0,0 +1,4 @@ +void script_4401(int arg0) { + setWidgetRGB(new Color(getColorRelatedMethod4020(standart_config_2094)), new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/4402.cs2 b/dumps/scripts/4402.cs2 new file mode 100644 index 0000000..6f3485e --- /dev/null +++ b/dumps/scripts/4402.cs2 @@ -0,0 +1,4 @@ +void script_4402(int arg0) { + setWidgetRGB(new Color(getColorRelatedMethod4020(standart_config_2095)), new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/4403.cs2 b/dumps/scripts/4403.cs2 new file mode 100644 index 0000000..6539976 --- /dev/null +++ b/dumps/scripts/4403.cs2 @@ -0,0 +1,4 @@ +void script_4403(int arg0) { + setWidgetRGB(new Color(getColorRelatedMethod4020(standart_config_2096)), new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/4404.cs2 b/dumps/scripts/4404.cs2 new file mode 100644 index 0000000..b962dcd --- /dev/null +++ b/dumps/scripts/4404.cs2 @@ -0,0 +1,4 @@ +void script_4404(int arg0) { + setWidgetRGB(new Color(getColorRelatedMethod4020(standart_config_2097)), new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/4405.cs2 b/dumps/scripts/4405.cs2 new file mode 100644 index 0000000..2bd6b46 --- /dev/null +++ b/dumps/scripts/4405.cs2 @@ -0,0 +1,11 @@ +int script_4405() { + int ivar0; + int ivar1; + ivar0 = getWidgetActualY(); + ivar1 = getWidgetParentId(); + while (ivar1 != -1) { + ivar0 = subtract(add(ivar0, getWidgetActualY(new WidgetPointer(ivar1))), cs2method2601(new WidgetPointer(ivar1))); + ivar1 = getWidgetParentId(new WidgetPointer(ivar1)); + } + return ivar0; +} diff --git a/dumps/scripts/4406.cs2 b/dumps/scripts/4406.cs2 new file mode 100644 index 0000000..df7fc1a --- /dev/null +++ b/dumps/scripts/4406.cs2 @@ -0,0 +1,4 @@ +void script_4406(int arg0,int arg1,int arg2) { + script_4407(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/4407.cs2 b/dumps/scripts/4407.cs2 new file mode 100644 index 0000000..556de17 --- /dev/null +++ b/dumps/scripts/4407.cs2 @@ -0,0 +1,6 @@ +void script_4407(int arg0,int arg1,int arg2) { + if ((arg1 >= 1) && (arg1 <= 10)) { + cs2method2309(arg1, arg2, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/4408.cs2 b/dumps/scripts/4408.cs2 new file mode 100644 index 0000000..805d417 --- /dev/null +++ b/dumps/scripts/4408.cs2 @@ -0,0 +1,4 @@ +void script_4408(int arg0) { + cs2method2309(1, 36, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/4409.cs2 b/dumps/scripts/4409.cs2 new file mode 100644 index 0000000..b20a2cd --- /dev/null +++ b/dumps/scripts/4409.cs2 @@ -0,0 +1,127 @@ +void script_4409(int arg0) { + int ivar1; + ivar1 = script_284(getMyPositionHash()); + switch (globalint_1007) { + case 1: + script_2766(0, 50, arg0); + break; + case 11: + if (getDisplayMode() >= 2) { + setScriptCallOnConfigChange(5210, new WidgetPointer(-32768,3), 466, 1, "IY", new WidgetPointer(746,7)); + script_5211(1); + } + script_2768(50, arg0); + cs2method5405(0, 2); + cs2method5405(1, 2); + cs2method5406(0, 0, addToCoordinate(ivar1, 28, 0, 27), 900, addToCoordinate(ivar1, 28, 0, 27), 900, 0); + cs2method5406(0, 1, addToCoordinate(ivar1, 28, 0, 27), 750, addToCoordinate(ivar1, 28, 0, 27), 750, 0); + cs2method5406(1, 0, addToCoordinate(ivar1, 23, 0, 8), 200, addToCoordinate(ivar1, 23, 0, 8), 200, 0); + cs2method5406(1, 1, addToCoordinate(ivar1, 23, 0, 8), 250, addToCoordinate(ivar1, 23, 0, 8), 250, 0); + cameraMethod5502(0, 0, 50, 0, 1, 0); + break; + case 12: + script_2766(0, 50, arg0); + break; + case 21: + script_2768(50, arg0); + cs2method5405(0, 2); + cs2method5405(1, 2); + cs2method5406(0, 0, addToCoordinate(ivar1, 16, 0, 26), 900, addToCoordinate(ivar1, 16, 0, 26), 900, 0); + cs2method5406(0, 1, addToCoordinate(ivar1, 16, 0, 26), 900, addToCoordinate(ivar1, 16, 0, 26), 900, 0); + cs2method5406(1, 0, addToCoordinate(ivar1, 24, 0, 37), 500, addToCoordinate(ivar1, 24, 0, 37), 500, 0); + cs2method5406(1, 1, addToCoordinate(ivar1, 24, 0, 37), 500, addToCoordinate(ivar1, 24, 0, 37), 500, 0); + cameraMethod5502(0, 0, 100, 0, 1, 0); + break; + case 22: + script_2766(0, 50, arg0); + break; + case 31: + script_2768(50, arg0); + cs2method5405(0, 2); + cs2method5405(1, 2); + cs2method5406(0, 0, addToCoordinate(ivar1, 31, 0, 11), 700, addToCoordinate(ivar1, 31, 0, 11), 700, 0); + cs2method5406(0, 1, addToCoordinate(ivar1, 24, 0, 11), 800, addToCoordinate(ivar1, 24, 0, 11), 800, 0); + cs2method5406(1, 0, addToCoordinate(ivar1, 28, 0, 19), 350, addToCoordinate(ivar1, 28, 0, 19), 350, 0); + cs2method5406(1, 1, addToCoordinate(ivar1, 28, 0, 19), 350, addToCoordinate(ivar1, 28, 0, 19), 350, 0); + cameraMethod5502(0, 0, 50, 0, 1, 0); + break; + case 32: + script_2766(0, 50, arg0); + break; + case 41: + script_2768(50, arg0); + cs2method5405(0, 2); + cs2method5405(1, 2); + cs2method5406(0, 0, addToCoordinate(ivar1, 37, 0, 41), 1200, addToCoordinate(ivar1, 37, 0, 41), 1200, 0); + cs2method5406(0, 1, addToCoordinate(ivar1, 37, 0, 41), 800, addToCoordinate(ivar1, 37, 0, 41), 800, 0); + cs2method5406(1, 0, addToCoordinate(ivar1, 27, 0, 49), 700, addToCoordinate(ivar1, 27, 0, 49), 700, 0); + cs2method5406(1, 1, addToCoordinate(ivar1, 27, 0, 49), 650, addToCoordinate(ivar1, 27, 0, 49), 650, 0); + cameraMethod5502(0, 0, 50, 0, 1, 0); + break; + case 42: + script_2766(0, 50, arg0); + break; + case 51: + script_2768(50, arg0); + cs2method5405(0, 2); + cs2method5405(1, 2); + cs2method5406(0, 0, addToCoordinate(ivar1, 37, 0, 9), 1300, addToCoordinate(ivar1, 37, 0, 9), 1300, 0); + cs2method5406(0, 1, addToCoordinate(ivar1, 37, 0, 9), 1300, addToCoordinate(ivar1, 37, 0, 9), 1300, 0); + cs2method5406(1, 0, addToCoordinate(ivar1, 27, 0, 17), 700, addToCoordinate(ivar1, 27, 0, 17), 700, 0); + cs2method5406(1, 1, addToCoordinate(ivar1, 27, 0, 17), 700, addToCoordinate(ivar1, 27, 0, 17), 700, 0); + cameraMethod5502(0, 0, 50, 0, 1, 0); + break; + case 52: + script_2766(0, 50, arg0); + break; + case 61: + script_2768(50, arg0); + cs2method5405(0, 2); + cs2method5405(1, 2); + cs2method5406(0, 0, addToCoordinate(ivar1, 33, 0, 30), 600, addToCoordinate(ivar1, 33, 0, 30), 600, 0); + cs2method5406(0, 1, addToCoordinate(ivar1, 33, 0, 30), 550, addToCoordinate(ivar1, 33, 0, 30), 550, 0); + cs2method5406(1, 0, addToCoordinate(ivar1, 24, 0, 33), 180, addToCoordinate(ivar1, 24, 0, 33), 180, 0); + cs2method5406(1, 1, addToCoordinate(ivar1, 24, 0, 33), 180, addToCoordinate(ivar1, 24, 0, 33), 180, 0); + cameraMethod5502(0, 0, 30, 0, 1, 0); + break; + case 62: + script_2766(0, 50, arg0); + break; + case 71: + script_2768(50, arg0); + cs2method5405(0, 2); + cs2method5405(1, 2); + cs2method5406(0, 0, addToCoordinate(ivar1, 18, 1, 34), 1000, addToCoordinate(ivar1, 18, 1, 34), 1000, 0); + cs2method5406(0, 1, addToCoordinate(ivar1, 18, 1, 44), 1000, addToCoordinate(ivar1, 18, 1, 44), 1000, 0); + cs2method5406(1, 0, addToCoordinate(ivar1, 24, 1, 39), 800, addToCoordinate(ivar1, 24, 1, 39), 800, 0); + cs2method5406(1, 1, addToCoordinate(ivar1, 24, 1, 39), 700, addToCoordinate(ivar1, 24, 1, 39), 700, 0); + cameraMethod5502(0, 0, 80, 0, 1, 0); + break; + case 72: + script_2766(0, 50, arg0); + break; + case 81: + script_2768(50, arg0); + cs2method5405(0, 2); + cs2method5405(1, 2); + cs2method5406(0, 0, addToCoordinate(ivar1, 15, 1, 18), 700, addToCoordinate(ivar1, 15, 1, 18), 700, 0); + cs2method5406(0, 1, addToCoordinate(ivar1, 15, 1, 18), 700, addToCoordinate(ivar1, 15, 1, 18), 700, 0); + cs2method5406(1, 0, addToCoordinate(ivar1, 24, 1, 30), 300, addToCoordinate(ivar1, 24, 1, 30), 300, 0); + cs2method5406(1, 1, addToCoordinate(ivar1, 24, 1, 12), 600, addToCoordinate(ivar1, 24, 1, 12), 600, 0); + cameraMethod5502(0, 0, 300, 0, 1, 0); + break; + case 82: + script_2766(0, 50, arg0); + break; + case 999: + script_2766(0, 50, arg0); + break; + case 1000: + cs2method5512(); + script_2768(50, arg0); + break; + default: + cs2method5512(); + } + return; +} diff --git a/dumps/scripts/441.cs2 b/dumps/scripts/441.cs2 new file mode 100644 index 0000000..9b25b2f --- /dev/null +++ b/dumps/scripts/441.cs2 @@ -0,0 +1,4 @@ +void script_441() { + script_304(42929944); + return; +} diff --git a/dumps/scripts/4410.cs2 b/dumps/scripts/4410.cs2 new file mode 100644 index 0000000..aad4b7f --- /dev/null +++ b/dumps/scripts/4410.cs2 @@ -0,0 +1,6 @@ +void script_4410(int arg0,int arg1,int arg2) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setScriptCallOnGameloop(4411, new WidgetPointer(arg0), arg1, arg2, 0, "Iiii"); + } + return; +} diff --git a/dumps/scripts/4411.cs2 b/dumps/scripts/4411.cs2 new file mode 100644 index 0000000..72a4c5c --- /dev/null +++ b/dumps/scripts/4411.cs2 @@ -0,0 +1,45 @@ +void script_4411(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + if (arg0 == -1) { + return; + } + ivar4 = 0; + ivar5 = 0; + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + ivar4 = cs2method1609(); + if (((boolean)arg3)) { + flow_4: + if (((boolean)arg2)) { + ivar5 = add(ivar4, 22); + } else if (((boolean)arg2)) { + ivar5 = subtract(ivar4, 22); + } else { + setScriptCallOnGameloop(-1, ""); + return; + } + ivar5 = max(ivar5, 0); + ivar5 = min(ivar5, 255); + cs2method2103(ivar5); + IF (((boolean)arg2)) + GOTO flow_10 + GOTO flow_11 + flow_10: + IF (ivar5 == 255) + GOTO flow_13 + flow_11: + IF (((boolean)arg2) && ((boolean)ivar5)) + GOTO flow_13 + GOTO flow_14 + flow_13: + setScriptCallOnGameloop(-1, ""); + GOTO flow_15 + flow_14: + setScriptCallOnGameloop(4411, new WidgetPointer(arg0), arg1, arg2, 0, "Iiii"); + flow_15: + } else { + setScriptCallOnGameloop(4411, new WidgetPointer(arg0), arg1, arg2, subtract(arg3, 1), "Iiii", new WidgetPointer(arg0)); + } + } + return; +} diff --git a/dumps/scripts/4412.cs2 b/dumps/scripts/4412.cs2 new file mode 100644 index 0000000..1f64751 --- /dev/null +++ b/dumps/scripts/4412.cs2 @@ -0,0 +1,25 @@ +void script_4412(int arg0,int arg1) { + int ivar2; + if ((arg0 == -1) || (arg1 == -1)) { + return; + } + ivar2 = getOtherCommonData(arg1, 1346); + if (ivar2 == 2) { + setScriptCallOnMouseEntered(4159, new WidgetPointer(-32768,3), 0, 0, "Iii", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(4159, new WidgetPointer(-32768,3), 1, 0, "Iii", new WidgetPointer(arg0)); + } else if (ivar2 == 3) { + setScriptCallOnMousePressed(4162, new WidgetPointer(-32768,3), "I", new WidgetPointer(arg0)); + setScriptCallOnMouseReleased(4163, new WidgetPointer(-32768,3), "I", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(4163, new WidgetPointer(-32768,3), "I", new WidgetPointer(arg0)); + } else { + if (ivar2 == 5) { + return; + } + } + script_5154(arg0, arg1); + if (ivar2 == 4) { + script_4161(arg0, 0); + setWidgetIsHidden(true, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/4413.cs2 b/dumps/scripts/4413.cs2 new file mode 100644 index 0000000..651ab3a --- /dev/null +++ b/dumps/scripts/4413.cs2 @@ -0,0 +1,8 @@ +void script_4413() { + if (cs2method3700()) { + script_4415(); + } else { + setScriptCallOnClanChatSettingsStuff(4414, "", new WidgetPointer(1107,170)); + } + return; +} diff --git a/dumps/scripts/4414.cs2 b/dumps/scripts/4414.cs2 new file mode 100644 index 0000000..ddcb9d3 --- /dev/null +++ b/dumps/scripts/4414.cs2 @@ -0,0 +1,6 @@ +void script_4414() { + if (cs2method3700()) { + script_4415(); + } + return; +} diff --git a/dumps/scripts/4415.cs2 b/dumps/scripts/4415.cs2 new file mode 100644 index 0000000..dc520eb --- /dev/null +++ b/dumps/scripts/4415.cs2 @@ -0,0 +1,25 @@ +void script_4415() { + setWidgetText(new WidgetPointer(1107,173), cs2method3702()); + setWidgetText(new WidgetPointer(1107,19), "Game time:" + "
" + script_4337(clanconfig_0)); + setWidgetText(new WidgetPointer(1107,35), cs2method3710(cs2method3715())); + if (clanbitconfig_6 > 0) { + setWidgetText(new WidgetPointer(1107,36), intToStr(clanbitconfig_6)); + } + setWidgetText(new WidgetPointer(1107,37), intToStr(cs2method3709())); + if (((boolean)clanbitconfig_4)) { + setWidgetText(new WidgetPointer(1107,5), "This clan is not recruiting."); + } else { + if (((boolean)clanbitconfig_4)) { + setWidgetText(new WidgetPointer(1107,5), "This clan is recruiting."); + } + } + script_4332(72548454, 72548464); + script_4334(72548359, 72548360); + script_4336(72548446); + script_4343(72548447); + script_4329(72548390); + script_4328(72548551); + script_4420(); + setWidgetIsHidden(true, new WidgetPointer(1107,151)); + return; +} diff --git a/dumps/scripts/4416.cs2 b/dumps/scripts/4416.cs2 new file mode 100644 index 0000000..60354db --- /dev/null +++ b/dumps/scripts/4416.cs2 @@ -0,0 +1,6 @@ +void script_4416(int arg0,int arg1,int arg2) { + setWidgetSprite(5866, new WidgetPointer(arg1)); + setWidgetSprite(5866, new WidgetPointer(arg2)); + setWidgetSprite(5865, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/4417.cs2 b/dumps/scripts/4417.cs2 new file mode 100644 index 0000000..1868a35 --- /dev/null +++ b/dumps/scripts/4417.cs2 @@ -0,0 +1,6 @@ +void script_4417(int arg0,int arg1,int arg2) { + setWidgetSprite(5864, new WidgetPointer(arg1)); + setWidgetSprite(5864, new WidgetPointer(arg2)); + setWidgetSprite(5863, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/4418.cs2 b/dumps/scripts/4418.cs2 new file mode 100644 index 0000000..aa6f958 --- /dev/null +++ b/dumps/scripts/4418.cs2 @@ -0,0 +1,11 @@ +void script_4418() { + string svar0; + svar0 = strRemoveEntities(getWidgetText(new WidgetPointer(1107,98))); + if (isFriend(svar0)) { + messageType0("Attempting to add " + svar0 + " to your Friends List."); + cs2method3605(svar0); + } else { + messageType0("You've already added " + svar0 + " to your friends list."); + } + return; +} diff --git a/dumps/scripts/4419.cs2 b/dumps/scripts/4419.cs2 new file mode 100644 index 0000000..b6fd08b --- /dev/null +++ b/dumps/scripts/4419.cs2 @@ -0,0 +1,16 @@ +void script_4419(int arg0) { + if (getWidgetActualHeight(new WidgetPointer(getWidgetParentId(new WidgetPointer(arg0)))) > 69) { + script_4544(arg0, -1, -1, -1, 14, 70, 3, 1); + setWidgetSprite(6169, new WidgetPointer(1107,58)); + setWidgetSprite(6169, new WidgetPointer(1107,59)); + cs2method2005(0, new WidgetPointer(1107,40)); + } else { + if (getWidgetActualHeight(new WidgetPointer(getWidgetParentId(new WidgetPointer(arg0)))) == 14) { + script_4544(arg0, -1, -1, -1, 14, 70, 3, 1); + setWidgetSprite(6168, new WidgetPointer(1107,58)); + setWidgetSprite(6168, new WidgetPointer(1107,59)); + cs2method2005(1, new WidgetPointer(1107,40)); + } + } + return; +} diff --git a/dumps/scripts/442.cs2 b/dumps/scripts/442.cs2 new file mode 100644 index 0000000..a5b3bb3 --- /dev/null +++ b/dumps/scripts/442.cs2 @@ -0,0 +1,28 @@ +void script_442(int arg0) { + setWidgetSprite(1134, new WidgetPointer(1016,24)); + setWidgetSprite(1134, new WidgetPointer(1016,25)); + setWidgetSprite(1134, new WidgetPointer(1016,26)); + setWidgetSprite(1134, new WidgetPointer(1016,27)); + setWidgetSprite(1134, new WidgetPointer(1016,28)); + setWidgetSprite(1134, new WidgetPointer(1016,29)); + switch (arg0) { + case 66584606: + setWidgetSprite(1135, new WidgetPointer(1016,24)); + break; + case 66584607: + setWidgetSprite(1135, new WidgetPointer(1016,25)); + break; + case 66584608: + setWidgetSprite(1135, new WidgetPointer(1016,26)); + break; + case 66584609: + setWidgetSprite(1135, new WidgetPointer(1016,27)); + break; + case 66584610: + setWidgetSprite(1135, new WidgetPointer(1016,28)); + break; + case 66584611: + setWidgetSprite(1135, new WidgetPointer(1016,29)); + } + return; +} diff --git a/dumps/scripts/4420.cs2 b/dumps/scripts/4420.cs2 new file mode 100644 index 0000000..89863d1 --- /dev/null +++ b/dumps/scripts/4420.cs2 @@ -0,0 +1,45 @@ +void script_4420() { + setWidgetText(new WidgetPointer(1107,60), "Event"); + setWidgetIsHidden(false, new WidgetPointer(1107,58)); + setWidgetIsHidden(false, new WidgetPointer(1107,59)); + switch (clanbitconfig_130) { + case 1: + script_4421(72548402, 72548403, clanbitconfig_98, clanbitconfig_106, clanbitconfig_82, clanbitconfig_90, clanbitconfig_74, clanbitconfig_114, clanconfig_65, clanbitconfig_132, clanlongconfig_122); + break; + case 2: + script_4421(72548402, 72548403, clanbitconfig_99, clanbitconfig_107, clanbitconfig_83, clanbitconfig_91, clanbitconfig_75, clanbitconfig_115, clanconfig_66, clanbitconfig_133, clanlongconfig_123); + break; + case 3: + script_4421(72548402, 72548403, clanbitconfig_100, clanbitconfig_108, clanbitconfig_84, clanbitconfig_92, clanbitconfig_76, clanbitconfig_116, clanconfig_67, clanbitconfig_134, clanlongconfig_124); + break; + case 4: + script_4421(72548402, 72548403, clanbitconfig_101, clanbitconfig_109, clanbitconfig_85, clanbitconfig_93, clanbitconfig_77, clanbitconfig_117, clanconfig_68, clanbitconfig_135, clanlongconfig_125); + break; + case 5: + script_4421(72548402, 72548403, clanbitconfig_102, clanbitconfig_110, clanbitconfig_86, clanbitconfig_94, clanbitconfig_78, clanbitconfig_118, clanconfig_69, clanbitconfig_136, clanlongconfig_126); + break; + case 6: + script_4421(72548402, 72548403, clanbitconfig_103, clanbitconfig_111, clanbitconfig_87, clanbitconfig_95, clanbitconfig_79, clanbitconfig_119, clanconfig_70, clanbitconfig_137, clanlongconfig_127); + break; + case 7: + script_4421(72548402, 72548403, clanbitconfig_104, clanbitconfig_112, clanbitconfig_88, clanbitconfig_96, clanbitconfig_80, clanbitconfig_120, clanconfig_71, clanbitconfig_138, clanlongconfig_128); + break; + case 8: + script_4421(72548402, 72548403, clanbitconfig_105, clanbitconfig_113, clanbitconfig_89, clanbitconfig_97, clanbitconfig_81, clanbitconfig_121, clanconfig_72, clanbitconfig_139, clanlongconfig_129); + break; + default: + setScriptCallOnMouseEntered(-1, "", new WidgetPointer(1107,54)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(1107,54)); + setScriptCallOnMouseEntered(-1, "", new WidgetPointer(1107,56)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(1107,55)); + setScriptCallOnMouseEntered(-1, "", new WidgetPointer(1107,56)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(1107,56)); + setWidgetText(new WidgetPointer(1107,60), "Events (none)"); + setWidgetIsHidden(true, new WidgetPointer(1107,58)); + setWidgetIsHidden(true, new WidgetPointer(1107,59)); + setWidgetText(new WidgetPointer(1107,50), ""); + setWidgetText(new WidgetPointer(1107,51), ""); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(1107,57)); + } + return; +} diff --git a/dumps/scripts/4421.cs2 b/dumps/scripts/4421.cs2 new file mode 100644 index 0000000..b02cdd8 --- /dev/null +++ b/dumps/scripts/4421.cs2 @@ -0,0 +1,36 @@ +void script_4421(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,long arg10) { + int ivar10; + string svar0; + ivar10 = cs2method_3408(105, 103, 3689, arg6); + svar0 = ""; + if (((arg2 >= getCurrentDaysSinceLaunch()) && (arg5 > 0)) && ((arg4 > 0) && (arg6 > 0))) { + svar0 = timeToStr(arg2) + "
" + cs2method_3408(105, 115, 3695, arg3); + if (((boolean)clanbitconfig_5)) { + svar0 = svar0 + " Game time:"; + } else { + svar0 = svar0 + " Clan time:"; + } + if (arg5 > 0) { + svar0 = svar0 + "
" + "World " + intToStr(arg5); + } + svar0 = svar0 + "
" + cs2method_3408(105, 115, 3696, arg4); + setWidgetText(new WidgetPointer(arg0), svar0); + svar0 = cs2method_3408(105, 115, 3687, arg6); + if ((ivar10 != -1) && (arg7 > 0)) { + svar0 = svar0 + "
" + cs2method_3408(105, 115, ivar10, arg7); + } + svar0 = svar0 + "
" + "Open to: " + cs2method_3408(105, 115, 3716, arg8); + if (((boolean)arg9)) { + svar0 = svar0 + "
" + "Attendance is mandatory."; + } + setWidgetText(new WidgetPointer(arg1), svar0); + if (arg10 != -1L) { + setWidgetIsHidden(false, new WidgetPointer(1107,146)); + setScriptCallOnClickContextMenu(4330, arg10, "\u00a7", new WidgetPointer(1107,146)); + } else { + setScriptCallOnMousePressed(-1, "", new WidgetPointer(1107,146)); + setWidgetIsHidden(true, new WidgetPointer(1107,52)); + } + } + return; +} diff --git a/dumps/scripts/4422.cs2 b/dumps/scripts/4422.cs2 new file mode 100644 index 0000000..d92c51b --- /dev/null +++ b/dumps/scripts/4422.cs2 @@ -0,0 +1,5 @@ +void script_4422() { + setWidgetIsHidden(true, new WidgetPointer(1107,96)); + setWidgetSize(446, getWidgetActualHeight(new WidgetPointer(1107,91)), 0, 0, new WidgetPointer(1107,91)); + return; +} diff --git a/dumps/scripts/4423.cs2 b/dumps/scripts/4423.cs2 new file mode 100644 index 0000000..4655fe3 --- /dev/null +++ b/dumps/scripts/4423.cs2 @@ -0,0 +1,5 @@ +void script_4423() { + setWidgetIsHidden(false, new WidgetPointer(1107,96)); + setWidgetSize(332, getWidgetActualHeight(new WidgetPointer(1107,91)), 0, 0, new WidgetPointer(1107,91)); + return; +} diff --git a/dumps/scripts/4424.cs2 b/dumps/scripts/4424.cs2 new file mode 100644 index 0000000..b6c5e87 --- /dev/null +++ b/dumps/scripts/4424.cs2 @@ -0,0 +1,32 @@ +void script_4424(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + ivar4 = divide(add(arg2, arg3), 2); + ivar5 = globalarray_0[ivar4]; + globalarray_0[ivar4] = globalarray_0[arg3]; + globalarray_0[arg3] = ivar5; + ivar6 = arg2; + ivar7 = arg2; + ivar8 = -1; + while (ivar7 < arg3) { + if ((setWidgetRegister(new WidgetPointer(arg1), ivar5) && setWidgetRegister(new WidgetPointer(arg1), globalarray_0[ivar7])) && (stringMethod4107(lower(getWidgetText()), lower(getWidgetText())) < bitAnd(ivar7, 1))) { + ivar8 = globalarray_0[ivar7]; + globalarray_0[ivar7] = globalarray_0[ivar6]; + globalarray_0[ivar6] = ivar8; + ivar6 = add(ivar6, 1); + } + ivar7 = add(ivar7, 1); + } + globalarray_0[arg3] = globalarray_0[ivar6]; + globalarray_0[ivar6] = ivar5; + if (arg2 < subtract(ivar6, 1)) { + script_4424(0, arg1, arg2, subtract(ivar6, 1)); + } + if (add(ivar6, 1) < arg3) { + script_4424(0, arg1, add(ivar6, 1), arg3); + } + return; +} diff --git a/dumps/scripts/4425.cs2 b/dumps/scripts/4425.cs2 new file mode 100644 index 0000000..ecac0bf --- /dev/null +++ b/dumps/scripts/4425.cs2 @@ -0,0 +1,32 @@ +void script_4425(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + ivar4 = divide(add(arg2, arg3), 2); + ivar5 = globalarray_0[ivar4]; + globalarray_0[ivar4] = globalarray_0[arg3]; + globalarray_0[arg3] = ivar5; + ivar6 = arg2; + ivar7 = arg2; + ivar8 = -1; + while (ivar7 < arg3) { + if ((setWidgetRegister(new WidgetPointer(arg1), ivar5) && setWidgetRegister(new WidgetPointer(arg1), globalarray_0[ivar7])) && (stringMethod4107(lower(getWidgetText()), lower(getWidgetText())) < bitAnd(ivar7, 1))) { + ivar8 = globalarray_0[ivar7]; + globalarray_0[ivar7] = globalarray_0[ivar6]; + globalarray_0[ivar6] = ivar8; + ivar6 = add(ivar6, 1); + } + ivar7 = add(ivar7, 1); + } + globalarray_0[arg3] = globalarray_0[ivar6]; + globalarray_0[ivar6] = ivar5; + if (arg2 < subtract(ivar6, 1)) { + script_4425(0, arg1, arg2, subtract(ivar6, 1)); + } + if (add(ivar6, 1) < arg3) { + script_4425(0, arg1, add(ivar6, 1), arg3); + } + return; +} diff --git a/dumps/scripts/4426.cs2 b/dumps/scripts/4426.cs2 new file mode 100644 index 0000000..162c3e7 --- /dev/null +++ b/dumps/scripts/4426.cs2 @@ -0,0 +1,5 @@ +void script_4426(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7) { + script_2732(arg0, arg1, bitconfig_9188, 2); + setScriptCallOnClickContextMenu(4427, -2147483644, arg1, new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), new WidgetPointer(arg6), new WidgetPointer(arg7), "iiIIIIII", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/4427.cs2 b/dumps/scripts/4427.cs2 new file mode 100644 index 0000000..c622601 --- /dev/null +++ b/dumps/scripts/4427.cs2 @@ -0,0 +1,12 @@ +void script_4427(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7) { + if (arg0 != 1) { + return; + } + if (bitconfig_9188 == arg1) { + return; + } + bitconfig_9188 = arg1; + playSoundEffect(2266, 1, 0); + script_2735(arg2, arg3, arg4, arg5, arg6, arg7); + return; +} diff --git a/dumps/scripts/4428.cs2 b/dumps/scripts/4428.cs2 new file mode 100644 index 0000000..863d3a8 --- /dev/null +++ b/dumps/scripts/4428.cs2 @@ -0,0 +1,39 @@ +void script_4428() { + int ivar0; + int ivar1; + int ivar2; + ivar0 = 72745013; + setScriptCallOnGameloop(4431, new WidgetPointer(-32768,3), "I", new WidgetPointer(ivar0)); + if (cs2method3751()) { + globalint_53 = 0; + setScriptCallOnClanListChange(4449, new WidgetPointer(-32768,3), "I", new WidgetPointer(ivar0)); + setScriptCallOnFriendListChange(4449, new WidgetPointer(-32768,3), "I", new WidgetPointer(ivar0)); + setWidgetScrollMax(0, 0, new WidgetPointer(ivar0)); + cs2method2100(0, 0, new WidgetPointer(ivar0)); + cs2method2314(149, new WidgetPointer(1110,27)); + setWidgetIsHidden(false, new WidgetPointer(1110,22)); + script_4470(); + script_4436(ivar0, globalint_1035); + script_4447(); + } + deleteAllExtraChilds(new WidgetPointer(1110,12)); + deleteAllExtraChilds(new WidgetPointer(1110,4)); + ivar1 = 0; + ivar2 = divide(add(500, 100), 2); + while (ivar1 < ivar2) { + createExtraChild(new WidgetPointer(1110,12), 3, ivar1); + createExtraChild(new WidgetPointer(1110,4), 3, ivar1); + setWidgetSize(0, 19, 1, 0); + setWidgetSize(0, 19, 1, 0); + setWidgetPosition(0, multiply(multiply(ivar1, 2), 19), 1, 0); + setWidgetPosition(0, getWidgetActualY(), 1, 0); + setWidgetRGB(new Color(35, 34, 32)); + setWidgetRGB(new Color(35, 34, 32)); + setWidgetFilled(1); + setWidgetFilled(1); + cs2method2103(128); + cs2method2103(128); + ivar1 = add(ivar1, 1); + } + return; +} diff --git a/dumps/scripts/4429.cs2 b/dumps/scripts/4429.cs2 new file mode 100644 index 0000000..1ffe646 --- /dev/null +++ b/dumps/scripts/4429.cs2 @@ -0,0 +1,6 @@ +void script_4429(int arg0,int arg1) { + setWidgetIsHidden(false, new WidgetPointer(1110,89)); + setWidgetSprite(6244, new WidgetPointer(arg1)); + setScriptCallOnUseWith(4430, new WidgetPointer(arg0), new WidgetPointer(arg1), "II", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/443.cs2 b/dumps/scripts/443.cs2 new file mode 100644 index 0000000..4ffcbaa --- /dev/null +++ b/dumps/scripts/443.cs2 @@ -0,0 +1,84 @@ +void script_443() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + ivar0 = 5; + ivar1 = 5; + ivar2 = 0; + ivar3 = 0; + ivar4 = 1; + ivar5 = 0; + ivar6 = 1; + ivar7 = 0; + ivar8 = 0; + while (ivar0 < 270) { + while (ivar1 < 200) { + createExtraChild(new WidgetPointer(1022,19), 5, ivar2); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(ivar1, ivar0, 0, 0); + if (getItemIdInSlot(583, ivar2) != -1) { + setItemOnWidgetMethod1200(getItemIdInSlot(583, ivar2), getItemAmtInSlot(583, ivar2)); + cs2method1305("" + getItemName(getItemIdInSlot(583, ivar2))); + setWidgetContextMenuOption(1, "Remove 1"); + setWidgetContextMenuOption(2, "Remove 5"); + setWidgetContextMenuOption(3, "Remove 10"); + setWidgetContextMenuOption(4, "Remove All"); + setWidgetContextMenuOption(5, "Remove X"); + setWidgetContextMenuOption(10, "Examine"); + setWidgetBorderThickness(1); + ivar3 = add(ivar3, 1); + if (ivar3 > 5) { + ivar4 = add(ivar4, 1); + ivar3 = 1; + } + } + createExtraChild(new WidgetPointer(1022,14), 5, ivar2); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(ivar1, ivar0, 0, 0); + if (getItemIdInSlotSplit(583, ivar2) != -1) { + setItemOnWidgetMethod1200(getItemIdInSlotSplit(583, ivar2), getItemAmtInSlotSplit(583, ivar2)); + cs2method1305("" + getItemName(getItemIdInSlotSplit(583, ivar2))); + setWidgetContextMenuOption(1, "Examine"); + setWidgetBorderThickness(1); + ivar5 = add(ivar5, 1); + if (ivar5 > 5) { + ivar6 = add(ivar6, 1); + ivar5 = 1; + } + } + ivar1 = add(ivar1, 40); + ivar2 = add(ivar2, 1); + } + ivar0 = add(ivar0, 40); + ivar1 = 5; + } + ivar7 = add(multiply(ivar4, 40), 5); + if (ivar7 > getWidgetActualHeight(new WidgetPointer(1022,19))) { + setWidgetScrollMax(0, ivar7, new WidgetPointer(1022,19)); + script_31(66977812, 66977811, 2598, 2595, 2596, 2597, 2593, 2594); + setWidgetPosition(6, getWidgetActualY(new WidgetPointer(1022,19)), 0, 0, new WidgetPointer(1022,19)); + } else { + setWidgetScrollMax(0, 0, new WidgetPointer(1022,19)); + cs2method2100(0, 0, new WidgetPointer(1022,19)); + deleteAllExtraChilds(new WidgetPointer(1022,20)); + setWidgetPosition(16, getWidgetActualY(new WidgetPointer(1022,19)), 0, 0, new WidgetPointer(1022,19)); + } + ivar8 = add(multiply(ivar6, 40), 5); + if (ivar8 > getWidgetActualHeight(new WidgetPointer(1022,14))) { + setWidgetScrollMax(0, ivar8, new WidgetPointer(1022,14)); + script_31(66977808, 66977806, 2598, 2595, 2596, 2597, 2593, 2594); + setWidgetPosition(6, getWidgetActualY(new WidgetPointer(1022,14)), 0, 0, new WidgetPointer(1022,14)); + } else { + setWidgetScrollMax(0, 0, new WidgetPointer(1022,14)); + cs2method2100(0, 0, new WidgetPointer(1022,14)); + deleteAllExtraChilds(new WidgetPointer(1022,16)); + setWidgetPosition(16, getWidgetActualY(new WidgetPointer(1022,14)), 0, 0, new WidgetPointer(1022,14)); + } + return; +} diff --git a/dumps/scripts/4430.cs2 b/dumps/scripts/4430.cs2 new file mode 100644 index 0000000..4f19c11 --- /dev/null +++ b/dumps/scripts/4430.cs2 @@ -0,0 +1,6 @@ +void script_4430(int arg0,int arg1) { + setWidgetSprite(6242, new WidgetPointer(arg1)); + setScriptCallOnUseWith(-1, "", new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(1110,89)); + return; +} diff --git a/dumps/scripts/4431.cs2 b/dumps/scripts/4431.cs2 new file mode 100644 index 0000000..92ce9a8 --- /dev/null +++ b/dumps/scripts/4431.cs2 @@ -0,0 +1,18 @@ +void script_4431(int arg0) { + string svar0; + svar0 = ""; + if (cs2method3751()) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + script_4434(); + setScriptCallOnClanChatSettingsStuff(4433, "", new WidgetPointer(1110,3)); + setScriptCallOnClanChatDeltaStuff(4433, "", new WidgetPointer(1110,3)); + setWidgetSprite(6255, new WidgetPointer(1110,86)); + } else { + script_4437(); + svar0 = "Join Clan Chat channel."; + setScriptCallOnMouseOver(4538, new WidgetPointer(1110,60), new WidgetPointer(-32768,3), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1110,85)); + setWidgetContextMenuOption(1, new WidgetPointer(1110,85), "Join Clan Chat channel"); + script_4589(); + } + return; +} diff --git a/dumps/scripts/4432.cs2 b/dumps/scripts/4432.cs2 new file mode 100644 index 0000000..dcb83a5 --- /dev/null +++ b/dumps/scripts/4432.cs2 @@ -0,0 +1,4 @@ +void script_4432() { + script_4589(); + return; +} diff --git a/dumps/scripts/4433.cs2 b/dumps/scripts/4433.cs2 new file mode 100644 index 0000000..aa6d522 --- /dev/null +++ b/dumps/scripts/4433.cs2 @@ -0,0 +1,8 @@ +void script_4433() { + if (cs2method3751()) { + script_4434(); + } else { + script_4589(); + } + return; +} diff --git a/dumps/scripts/4434.cs2 b/dumps/scripts/4434.cs2 new file mode 100644 index 0000000..8b8b3ab --- /dev/null +++ b/dumps/scripts/4434.cs2 @@ -0,0 +1,5 @@ +void script_4434() { + script_4436(72744974, globalint_1035); + script_4462(); + return; +} diff --git a/dumps/scripts/4435.cs2 b/dumps/scripts/4435.cs2 new file mode 100644 index 0000000..ef16c39 --- /dev/null +++ b/dumps/scripts/4435.cs2 @@ -0,0 +1,9 @@ +void script_4435(int arg0) { + if (cs2method3751()) { + if (arg0 <= -1) { + arg0 = globalint_1035; + } + script_4436(72744974, arg0); + } + return; +} diff --git a/dumps/scripts/4436.cs2 b/dumps/scripts/4436.cs2 new file mode 100644 index 0000000..a1f2795 --- /dev/null +++ b/dumps/scripts/4436.cs2 @@ -0,0 +1,248 @@ +void script_4436(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + int ivar22; + int ivar23; + int ivar24; + int ivar25; + int ivar26; + int ivar27; + int ivar28; + int ivar29; + string svar0; + string svar1; + string svar2; + string svar3; + string svar4; + int stack_dump0; + if (globalint_1512 != 1) { + globalint_1512 = 1; + } + ivar2 = 72744974; + ivar3 = 72744975; + ivar4 = 72744977; + ivar5 = 72744978; + ivar6 = 72744987; + ivar7 = 72744979; + ivar8 = 72744985; + ivar9 = 72744989; + ivar10 = 72744976; + ivar11 = getWidgetActualWidth(new WidgetPointer(ivar6)); + if (arg1 <= -1) { + arg1 = getWidgetActualX(new WidgetPointer(ivar6)); + } + arg1 = max(min(arg1, subtract(getWidgetActualWidth(new WidgetPointer(ivar7)), ivar11)), 0); + globalint_1035 = arg1; + setWidgetPosition(arg1, 0, 0, 1, new WidgetPointer(ivar6)); + cs2method2314(149, new WidgetPointer(ivar6)); + setWidgetIsHidden(false, new WidgetPointer(ivar6)); + deleteAllExtraChilds(new WidgetPointer(ivar2)); + deleteAllExtraChilds(new WidgetPointer(ivar3)); + deleteAllExtraChilds(new WidgetPointer(ivar4)); + deleteAllExtraChilds(new WidgetPointer(ivar5)); + deleteAllExtraChilds(new WidgetPointer(ivar10)); + setWidgetSprite(6255, new WidgetPointer(1110,86)); + setWidgetIsHidden(false, new WidgetPointer(1110,22)); + script_4470(); + svar0 = "Leave your clan chat channel."; + setScriptCallOnMouseOver(4538, new WidgetPointer(1110,60), new WidgetPointer(-32768,3), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1110,85)); + setWidgetContextMenuOption(1, new WidgetPointer(1110,85), "Leave Clan Chat channel"); + ivar12 = 0; + ivar13 = 0; + ivar14 = 0; + svar1 = ""; + ivar15 = 19; + ivar16 = divide(getWidgetActualHeight(new WidgetPointer(ivar8)), ivar15); + svar2 = ""; + ivar17 = 0; + svar3 = ""; + ivar18 = 0; + ivar19 = 0; + svar4 = ""; + ivar20 = 0; + ivar21 = script_3365(ivar7); + ivar22 = subtract(add(arg1, ivar21), script_3365(ivar2)); + ivar23 = subtract(getWidgetActualWidth(new WidgetPointer(ivar4)), add(add(arg1, subtract(ivar21, script_3365(ivar4))), ivar11)); + setWidgetSize(ivar23, 0, 0, 1, new WidgetPointer(ivar4)); + setWidgetSize(ivar23, 0, 0, 1, new WidgetPointer(ivar5)); + setWidgetIsHidden(false, new WidgetPointer(ivar9)); + setScriptCallOnClanChatDeltaStuff(4435, -1, "i", new WidgetPointer(arg0)); + setWidgetText(new WidgetPointer(1110,26), cs2method3752()); + setWidgetText(new WidgetPointer(1110,62), ""); + setWidgetIsHidden(true, new WidgetPointer(1110,67)); + ivar24 = cs2method3760(strRemoveEntities(cs2method5020())); + if (ivar24 == -1) { + return; + } + ivar25 = cs2method3757(ivar24); + ivar14 = cs2method3755(); + ivar12 = 0; + while (ivar12 < ivar14) { + ivar13 = multiply(ivar12, ivar15); + svar2 = strRemoveEntities(cs2method3756(ivar12)); + ivar20 = cs2method3757(ivar12); + createExtraChild(new WidgetPointer(ivar2), 4, getExtraChildGap(new WidgetPointer(ivar2))); + setWidgetTextAlignment(0, 1, 0); + setWidgetPosition(0, ivar13, 0, 0); + setWidgetSize(ivar22, ivar15, 0, 0); + setWidgetRGB(new Color(164, 153, 125)); + setWidgetFont(3793); + setWidgetUnknownBoolean(true); + if (stringMethod4107(svar2, strRemoveEntities(cs2method5020())) != 0) { + cs2method1305(svar2); + if (isFriend(svar2)) { + setWidgetContextMenuOption(1, "Message"); + setWidgetContextMenuOption(7, "Remove friend"); + } else if (cs2method3623(svar2)) { + setWidgetContextMenuOption(8, "Remove ignore"); + } else { + setWidgetContextMenuOption(5, "Add friend"); + setWidgetContextMenuOption(6, "Add ignore"); + } + if (ivar25 >= 100) { + setWidgetContextMenuOption(9, "Temp-ban"); + } + setScriptCallOnClickContextMenu(4472, svar2, -2147483644, ivar12, "sii"); + } + svar1 = "\u00a0\u00a0\u00a0" + svar2; + if (getTextWidth(3793, svar1) > ivar22) { + while ((getTextWidth(3793, svar1 + "...") > ivar22) && (strLength(svar1) > 0)) { + svar1 = substr(0, subtract(strLength(svar1), 1), svar1); + } + svar1 = svar1 + "..."; + setScriptCallOnMouseOver(1594, new WidgetPointer(1110,60), new WidgetPointer(-32768,3), -2147483643, svar2, -2147483647, -2147483646, "IIisii"); + setScriptCallOnMouseExit(40, new WidgetPointer(1110,60), "I"); + } + setWidgetText(svar1); + setWidgetUnknownBoolean(true); + ivar17 = cs2method3758(ivar12); + if ((ivar17 >= 1100) && (ivar17 < 5001)) { + svar3 = "Lobby"; + svar4 = "Lobby"; + ivar18 = 0; + } else if ((ivar17 >= 5001) && (ivar17 < 6000)) { + svar3 = "Classic " + intToStr(subtract(ivar17, 5000)); + svar4 = "Classic " + intToStr(subtract(ivar17, 5000)); + ivar18 = 0; + } else { + svar3 = intToStr(ivar17); + svar4 = "World " + intToStr(ivar17); + ivar18 = add(add(2, 24), 2); + } + ivar19 = getTextWidth(3793, svar3); + createExtraChild(new WidgetPointer(ivar5), 5, getExtraChildGap(new WidgetPointer(ivar5))); + if (ivar23 >= add(ivar19, ivar18)) { + if (ivar18 > 0) { + setWidgetSprite(2173); + setWidgetSize(24, 12, 0, 0); + setWidgetPosition(2, add(ivar13, 1), 0, 0); + setScriptCallOnMouseOver(1594, new WidgetPointer(1110,60), new WidgetPointer(-32768,3), -2147483643, svar4, -2147483647, -2147483646, "IIisii"); + setScriptCallOnMouseExit(40, new WidgetPointer(1110,60), "I"); + } + } else { + ivar18 = 0; + } + if (ivar23 >= ivar19) { + } else { + setScriptCallOnMouseOver(1594, new WidgetPointer(1110,60), new WidgetPointer(-32768,3), -2147483643, svar4, -2147483647, -2147483646, "IIisii"); + setScriptCallOnMouseExit(40, new WidgetPointer(1110,60), "I"); + svar3 = "..."; + } + createExtraChild(new WidgetPointer(ivar4), 4, getExtraChildGap(new WidgetPointer(ivar4))); + setWidgetSize(ivar23, ivar15, 0, 0); + setWidgetPosition(add(ivar18, 2), ivar13, 0, 0); + setWidgetFont(3793); + setWidgetUnknownBoolean(true); + setWidgetTextAlignment(0, 1, 0); + setWidgetText(svar3); + if (ivar17 == getWorldId()) { + setWidgetRGB(new Color(60, 183, 30)); + } else { + setWidgetRGB(new Color(255, 255, 100)); + } + setScriptCallOnMouseOver(1594, new WidgetPointer(1110,60), new WidgetPointer(-32768,3), -2147483643, svar4, -2147483647, -2147483646, "IIisii"); + setScriptCallOnMouseExit(40, new WidgetPointer(1110,60), "I"); + createExtraChild(new WidgetPointer(ivar3), 5, getExtraChildGap(new WidgetPointer(ivar3))); + if (ivar20 == 127) { + setWidgetPosition(3, 3, 0, 0); + setWidgetSize(9, 9, 0, 0); + } else { + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(15, 15, 0, 0); + } + setWidgetSprite(cs2method_3408(105, 100, 3712, ivar20)); + createExtraChild(new WidgetPointer(ivar10), 5, getExtraChildGap(new WidgetPointer(ivar10))); + setWidgetPosition(0, 0, 2, 0); + setWidgetSize(9, ivar15, 0, 0); + setWidgetSprite(6032); + setScriptCallOnClickContextMenu(4317, new WidgetPointer(-32768,3), -2147483643, "Ii"); + setWidgetContextMenuOption(1, "Show options"); + ivar12 = add(ivar12, 1); + } + ivar12 = 0; + ivar26 = 0; + while (ivar12 < ivar14) { + stack_dump0 = ivar12; + cs2method3761(); + ivar26 = stack_dump0; + if (setWidgetRegister(new WidgetPointer(ivar2), ivar26) && (stringMethod4107(getWidgetText(), "") != 0)) { + ivar13 = multiply(ivar12, ivar15); + setWidgetPosition(getWidgetActualX(), ivar13, 0, 0); + if (setWidgetRegister(new WidgetPointer(ivar3), ivar26)) { + setWidgetPosition(getWidgetActualX(), add(add(getWidgetActualY(), ivar13), 3), 0, 0); + } + if (setWidgetRegister(new WidgetPointer(ivar4), ivar26)) { + setWidgetPosition(getWidgetActualX(), ivar13, 0, 0); + } + if (setWidgetRegister(new WidgetPointer(ivar5), ivar26)) { + setWidgetPosition(getWidgetActualX(), add(ivar13, 5), 0, 0); + } + if (setWidgetRegister(new WidgetPointer(ivar10), ivar26)) { + setWidgetPosition(getWidgetActualX(), add(ivar13, 2), 0, 0); + } + } + ivar12 = add(ivar12, 1); + } + ivar27 = 0; + ivar28 = -1; + if (globalint_1518 >= 0) { + ivar28 = cs2method3760(globalstring_126); + if (ivar28 >= 0) { + globalint_1518 = ivar28; + if (setWidgetRegister(new WidgetPointer(ivar10), globalint_1518)) { + ivar27 = getWidgetActualY(); + setWidgetPosition(0, ivar27, 2, 0, new WidgetPointer(1110,20)); + setWidgetPosition(0, ivar27, 2, 0, new WidgetPointer(1110,13)); + } + } else { + globalint_1518 = -1; + globalstring_126 = ""; + setWidgetIsHidden(false, new WidgetPointer(1110,13)); + script_4628(); + } + } + ivar29 = cs2method2601(new WidgetPointer(ivar8)); + setWidgetScrollMax(getWidgetActualWidth(new WidgetPointer(ivar8)), multiply(ivar15, max(ivar14, ivar16)), new WidgetPointer(ivar8)); + ivar29 = min(ivar29, getWidgetScrollMaxV(new WidgetPointer(ivar8))); + cs2method2100(0, ivar29, new WidgetPointer(ivar8)); + script_31(72744989, ivar8, 5666, 5663, 5664, 5665, 5686, 5685); + return; +} diff --git a/dumps/scripts/4437.cs2 b/dumps/scripts/4437.cs2 new file mode 100644 index 0000000..0e81ecc --- /dev/null +++ b/dumps/scripts/4437.cs2 @@ -0,0 +1,14 @@ +void script_4437() { + setWidgetIsHidden(true, new WidgetPointer(1110,27)); + setWidgetNoOptions(new WidgetPointer(1110,27)); + cs2method2100(0, 0, new WidgetPointer(1110,25)); + setWidgetIsHidden(false, new WidgetPointer(1110,29)); + script_31(72744989, 72744985, 5666, 5663, 5664, 5665, 5686, 5685); + setWidgetSprite(6256, new WidgetPointer(1110,86)); + setWidgetIsHidden(true, new WidgetPointer(1110,13)); + setWidgetSize(1, 19, 0, 0, new WidgetPointer(1110,20)); + globalint_1518 = -1; + globalstring_126 = ""; + setWidgetText(new WidgetPointer(1110,26), ""); + return; +} diff --git a/dumps/scripts/4438.cs2 b/dumps/scripts/4438.cs2 new file mode 100644 index 0000000..0263774 --- /dev/null +++ b/dumps/scripts/4438.cs2 @@ -0,0 +1,4 @@ +void script_4438() { + script_4441(0); + return; +} diff --git a/dumps/scripts/4439.cs2 b/dumps/scripts/4439.cs2 new file mode 100644 index 0000000..259d215 --- /dev/null +++ b/dumps/scripts/4439.cs2 @@ -0,0 +1,4 @@ +void script_4439() { + script_4441(8); + return; +} diff --git a/dumps/scripts/444.cs2 b/dumps/scripts/444.cs2 new file mode 100644 index 0000000..d22cc48 --- /dev/null +++ b/dumps/scripts/444.cs2 @@ -0,0 +1,120 @@ +void script_444() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + string svar0; + string svar1; + ivar0 = 0; + ivar1 = 0; + ivar2 = -1; + svar0 = ""; + svar1 = ""; + globalarray_0 = new int[getItemContainerLength(583)]; + globalarray_1 = new int[getItemContainerLength(583)]; + ivar3 = 0; + ivar4 = 99; + ivar5 = 0; + while (ivar0 < getItemContainerLength(583)) { + ivar2 = getItemIdInSlot(583, ivar0); + ivar1 = getItemAmtInSlot(583, ivar0); + if (ivar2 != -1) { + ivar4 = 99; + ivar5 = 0; + while (ivar5 < getItemContainerLength(583)) { + if (globalarray_0[ivar5] != -1) { + if (globalarray_0[ivar5] == ivar2) { + ivar4 = ivar5; + ivar5 = getItemContainerLength(583); + } + ivar5 = add(ivar5, 1); + } else { + ivar5 = getItemContainerLength(583); + } + } + if (ivar4 == 99) { + globalarray_0[ivar3] = ivar2; + globalarray_0[ivar3] = ivar1; + ivar3 = add(ivar3, 1); + } else { + globalarray_0[ivar4] = add(globalarray_1[ivar4], ivar1); + } + } + ivar0 = add(ivar0, 1); + } + ivar3 = 0; + while (ivar3 < getItemContainerLength(583)) { + ivar2 = globalarray_0[ivar3]; + if (ivar2 != -1) { + ivar1 = globalarray_1[ivar3]; + svar0 = concat(svar0, script_446(ivar1, ivar2)); + } else { + ivar3 = getItemContainerLength(583); + } + ivar3 = add(ivar3, 1); + } + ivar0 = 0; + ivar3 = 0; + while (ivar3 < getItemContainerLength(583)) { + globalarray_0[ivar3] = -1; + globalarray_0[ivar3] = 0; + ivar3 = add(ivar3, 1); + } + ivar3 = 0; + ivar5 = 0; + while (ivar0 < getItemContainerLength(583)) { + ivar2 = getItemIdInSlotSplit(583, ivar0); + ivar1 = getItemAmtInSlotSplit(583, ivar0); + if (ivar2 != -1) { + ivar4 = 99; + ivar5 = 0; + while (ivar5 < getItemContainerLength(583)) { + if (globalarray_0[ivar5] != -1) { + if (globalarray_0[ivar5] == ivar2) { + ivar4 = ivar5; + ivar5 = getItemContainerLength(583); + } + ivar5 = add(ivar5, 1); + } else { + ivar5 = getItemContainerLength(583); + } + } + if (ivar4 == 99) { + globalarray_0[ivar3] = ivar2; + globalarray_0[ivar3] = ivar1; + ivar3 = add(ivar3, 1); + } else { + globalarray_0[ivar4] = add(globalarray_1[ivar4], ivar1); + } + } + ivar0 = add(ivar0, 1); + } + ivar3 = 0; + while (ivar3 < getItemContainerLength(583)) { + ivar2 = globalarray_0[ivar3]; + if (ivar2 != -1) { + ivar1 = globalarray_1[ivar3]; + svar1 = concat(svar1, script_446(ivar1, ivar2)); + } else { + ivar3 = getItemContainerLength(583); + } + ivar3 = add(ivar3, 1); + } + if (strLength(svar0) > 0) { + setWidgetText(new WidgetPointer(1023,14), svar0); + script_447(67043343, 67043341, 67043342); + setWidgetIsHidden(true, new WidgetPointer(1023,12)); + } else { + setWidgetIsHidden(false, new WidgetPointer(1023,12)); + } + if (strLength(svar1) > 0) { + setWidgetText(new WidgetPointer(1023,21), svar1); + script_447(67043350, 67043348, 67043349); + setWidgetIsHidden(true, new WidgetPointer(1023,19)); + } else { + setWidgetIsHidden(false, new WidgetPointer(1023,19)); + } + return; +} diff --git a/dumps/scripts/4440.cs2 b/dumps/scripts/4440.cs2 new file mode 100644 index 0000000..24ed591 --- /dev/null +++ b/dumps/scripts/4440.cs2 @@ -0,0 +1,4 @@ +void script_4440(int arg0) { + script_4441(arg0); + return; +} diff --git a/dumps/scripts/4441.cs2 b/dumps/scripts/4441.cs2 new file mode 100644 index 0000000..e1b5293 --- /dev/null +++ b/dumps/scripts/4441.cs2 @@ -0,0 +1,12 @@ +void script_4441(int arg0) { + string svar0; + string svar1; + script_4445(); + svar0 = ""; + svar1 = ""; + if ((arg0 > 0) && (arg0 < 8)) { + return; + } + svar0 = concat(svar0, "To join a clan channel as a" + "
" + "guest, use the button in the top-left" + "
" + "and enter the name of" + "
" + "the clan you wish to chat in." + "
" + "
" + "To talk, start your chat with ///." + "
" + "If you belong to another clan, you" + "
" + "can still talk to them by" + "
" + "starting your chat with //."); + return; +} diff --git a/dumps/scripts/4442.cs2 b/dumps/scripts/4442.cs2 new file mode 100644 index 0000000..b2e2f24 --- /dev/null +++ b/dumps/scripts/4442.cs2 @@ -0,0 +1,3 @@ +string script_4442() { + return "You are not currently" + "
" + "a guest in a Clan Chat." + "
" + "
" + "To join a Clan Chat as a" + "
" + "guest, click the join icon" + "
" + "and enter the name of" + "
" + "the clan you wish to chat with."; +} diff --git a/dumps/scripts/4443.cs2 b/dumps/scripts/4443.cs2 new file mode 100644 index 0000000..f160159 --- /dev/null +++ b/dumps/scripts/4443.cs2 @@ -0,0 +1,8 @@ +void script_4443(int arg0) { + if (cs2method3750()) { + script_4444(arg0); + } else { + script_4445(); + } + return; +} diff --git a/dumps/scripts/4444.cs2 b/dumps/scripts/4444.cs2 new file mode 100644 index 0000000..ad89d1b --- /dev/null +++ b/dumps/scripts/4444.cs2 @@ -0,0 +1,216 @@ +void script_4444(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + int ivar22; + int ivar23; + int ivar24; + int ivar25; + string svar0; + string svar1; + string svar2; + string svar3; + string svar4; + int stack_dump0; + ivar1 = 9; + ivar2 = 23; + script_4445(); + setWidgetSprite(6255, new WidgetPointer(1110,96)); + setWidgetIsHidden(true, new WidgetPointer(1110,64)); + setWidgetText(new WidgetPointer(1110,70), ""); + if (globalint_1513 != 1) { + globalint_1513 = 1; + } + ivar3 = 72744965; + ivar4 = 72744968; + ivar5 = 72744966; + ivar6 = 72744967; + ivar7 = 72744998; + ivar8 = 72744997; + ivar9 = 72744969; + ivar10 = 72745023; + deleteAllExtraChilds(new WidgetPointer(ivar3)); + deleteAllExtraChilds(new WidgetPointer(ivar4)); + deleteAllExtraChilds(new WidgetPointer(ivar5)); + deleteAllExtraChilds(new WidgetPointer(ivar6)); + ivar11 = 0; + ivar12 = cs2method3755(); + ivar13 = getWidgetActualWidth(new WidgetPointer(ivar7)); + if (arg0 <= -1) { + arg0 = getWidgetActualX(new WidgetPointer(ivar7)); + } + arg0 = max(min(arg0, subtract(getWidgetActualWidth(new WidgetPointer(ivar8)), ivar13)), 0); + globalint_1506 = arg0; + setWidgetPosition(arg0, 0, 0, 1, new WidgetPointer(ivar7)); + setWidgetIsHidden(false, new WidgetPointer(ivar7)); + cs2method2314(149, new WidgetPointer(ivar7)); + ivar11 = 0; + ivar14 = 2; + svar0 = ""; + ivar15 = 19; + ivar16 = divide(getWidgetActualHeight(new WidgetPointer(ivar3)), ivar15); + svar1 = ""; + ivar17 = 0; + svar2 = ""; + ivar18 = 0; + ivar19 = 0; + svar3 = ""; + ivar20 = -1; + ivar21 = script_3365(ivar8); + ivar22 = subtract(add(arg0, ivar21), script_3365(ivar3)); + ivar23 = subtract(getWidgetActualWidth(new WidgetPointer(ivar5)), add(add(arg0, subtract(ivar21, script_3365(ivar5))), ivar13)); + setWidgetContextMenuOption(1, new WidgetPointer(1110,95), "Leave chat"); + setWidgetSprite(6255, new WidgetPointer(1110,96)); + setWidgetSize(ivar23, 0, 0, 1, new WidgetPointer(ivar5)); + setWidgetSize(ivar23, 0, 0, 1, new WidgetPointer(ivar6)); + setWidgetText(new WidgetPointer(1110,65), cs2method3752()); + svar4 = "Leave another" + "
" + "clan's clanchat."; + setScriptCallOnMouseOver(4538, new WidgetPointer(1110,60), new WidgetPointer(-32768,3), -1, svar4, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1110,95)); + setWidgetContextMenuOption(1, new WidgetPointer(1110,95), "Leave Clan Chat channel"); + while (ivar11 < ivar12) { + svar1 = cs2method3756(ivar11); + ivar20 = cs2method3757(ivar11); + createExtraChild(new WidgetPointer(ivar3), 4, getExtraChildGap(new WidgetPointer(ivar3))); + setWidgetTextAlignment(0, 1, 0); + setWidgetPosition(0, ivar14, 0, 0); + setWidgetSize(ivar22, ivar15, 0, 0); + setWidgetRGB(new Color(164, 153, 125)); + setWidgetFont(3793); + setWidgetUnknownBoolean(true); + setWidgetText(svar1); + if (stringMethod4107(svar1, strRemoveEntities(cs2method5020())) != 0) { + if (isFriend(svar1)) { + setWidgetContextMenuOption(1, "Message"); + setWidgetContextMenuOption(7, "Remove friend " + svar1); + } else if (cs2method3623(svar1)) { + setWidgetContextMenuOption(8, "Remove ignore " + svar1); + } else { + setWidgetContextMenuOption(5, "Add friend " + svar1); + setWidgetContextMenuOption(6, "Add ignore " + svar1); + } + } + setScriptCallOnClickContextMenu(4472, svar1, -2147483644, ivar11, "sii"); + svar0 = "\u00a0\u00a0\u00a0" + svar1; + if (getTextWidth(3793, svar0) > ivar22) { + while ((getTextWidth(3793, svar0 + "...") > ivar22) && (strLength(svar0) > 0)) { + svar0 = substr(0, subtract(strLength(svar0), 1), svar0); + } + svar0 = svar0 + "..."; + setScriptCallOnMouseOver(1594, new WidgetPointer(1110,60), new WidgetPointer(-32768,3), -2147483643, svar1, -2147483647, -2147483646, "IIisii"); + setScriptCallOnMouseExit(40, new WidgetPointer(1110,60), "I"); + } + setWidgetText(svar0); + setWidgetUnknownBoolean(true); + ivar17 = cs2method3758(ivar11); + if ((ivar17 >= 1100) && (ivar17 < 5001)) { + svar2 = "Lobby"; + svar3 = "Lobby"; + ivar18 = 0; + } else if ((ivar17 >= 5001) && (ivar17 < 6000)) { + svar2 = "Classic " + intToStr(subtract(ivar17, 5000)); + svar3 = "Classic " + intToStr(subtract(ivar17, 5000)); + ivar18 = 0; + } else { + svar2 = intToStr(ivar17); + svar3 = "World " + intToStr(ivar17); + ivar18 = add(add(2, 24), 2); + } + ivar19 = getTextWidth(3793, svar2); + createExtraChild(new WidgetPointer(ivar6), 5, getExtraChildGap(new WidgetPointer(ivar6))); + if (ivar23 >= add(ivar19, ivar18)) { + if (ivar18 > 0) { + setWidgetSprite(2173); + setWidgetSize(24, 12, 0, 0); + setWidgetPosition(2, add(ivar14, 1), 0, 0); + setScriptCallOnMouseOver(1594, new WidgetPointer(1110,60), new WidgetPointer(-32768,3), -2147483643, svar3, -2147483647, -2147483646, "IIisii"); + setScriptCallOnMouseExit(40, new WidgetPointer(1110,60), "I"); + } + } else { + ivar18 = 0; + } + if (ivar23 >= ivar19) { + } else { + setScriptCallOnMouseOver(1594, new WidgetPointer(1110,60), new WidgetPointer(-32768,3), -2147483643, svar3, -2147483647, -2147483646, "IIisii"); + setScriptCallOnMouseExit(40, new WidgetPointer(1110,60), "I"); + svar2 = "..."; + } + createExtraChild(new WidgetPointer(ivar5), 4, getExtraChildGap(new WidgetPointer(ivar5))); + setWidgetSize(ivar23, ivar15, 0, 0); + setWidgetPosition(add(ivar18, 2), ivar14, 0, 0); + setWidgetFont(3793); + setWidgetUnknownBoolean(true); + setWidgetTextAlignment(0, 0, 0); + setWidgetText(svar2); + if (ivar17 == getWorldId()) { + setWidgetRGB(new Color(60, 183, 30)); + } else { + setWidgetRGB(new Color(255, 255, 100)); + } + setScriptCallOnMouseOver(1594, new WidgetPointer(1110,60), new WidgetPointer(-32768,3), -2147483643, svar3, -2147483647, -2147483646, "IIisii"); + setScriptCallOnMouseExit(40, new WidgetPointer(1110,60), "I"); + createExtraChild(new WidgetPointer(ivar4), 5, getExtraChildGap(new WidgetPointer(ivar4))); + if (ivar20 == 127) { + setWidgetPosition(3, 3, 0, 0); + setWidgetSize(9, 9, 0, 0); + } else { + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(15, 15, 0, 0); + } + setWidgetSprite(cs2method_3408(105, 100, 3712, ivar20)); + ivar11 = add(ivar11, 1); + } + ivar11 = 0; + ivar24 = 0; + while (ivar11 < ivar12) { + stack_dump0 = ivar11; + cs2method3761(); + ivar24 = stack_dump0; + if (setWidgetRegister(new WidgetPointer(ivar3), ivar24) && (stringMethod4107(getWidgetText(), "") != 0)) { + ivar14 = multiply(ivar11, ivar15); + setWidgetPosition(getWidgetActualX(), ivar14, 0, 0); + if (setWidgetRegister(new WidgetPointer(ivar4), ivar24)) { + setWidgetPosition(getWidgetActualX(), add(add(getWidgetActualY(), ivar14), 3), 0, 0); + } + if (setWidgetRegister(new WidgetPointer(ivar5), ivar24)) { + setWidgetPosition(getWidgetActualX(), ivar14, 0, 0); + } + if (setWidgetRegister(new WidgetPointer(ivar6), ivar24)) { + setWidgetPosition(getWidgetActualX(), add(ivar14, 2), 0, 0); + } + } + ivar11 = add(ivar11, 1); + } + if (multiply(ivar11, 19) > getWidgetActualHeight(new WidgetPointer(ivar9))) { + setWidgetScrollMax(0, multiply(ivar11, 19), new WidgetPointer(ivar9)); + } else { + setWidgetScrollMax(0, 0, new WidgetPointer(ivar9)); + } + ivar25 = cs2method2601(new WidgetPointer(ivar9)); + setWidgetScrollMax(getWidgetActualWidth(new WidgetPointer(ivar9)), multiply(ivar15, ivar12), new WidgetPointer(ivar9)); + ivar25 = min(ivar25, getWidgetScrollMaxV(new WidgetPointer(ivar9))); + cs2method2100(0, ivar25, new WidgetPointer(ivar9)); + script_31(ivar10, ivar9, 5666, 5663, 5664, 5665, 5686, 5685); + setScriptCallOnClanChatDeltaStuff(4443, -1, "i", new WidgetPointer(ivar3)); + setScriptCallOnClanChatSettingsStuff(4443, -1, "i", new WidgetPointer(ivar3)); + setWidgetScrollMax(getWidgetActualWidth(new WidgetPointer(1110,25)), multiply(ivar15, ivar12), new WidgetPointer(1110,25)); + script_31(72744989, 72744985, 5666, 5663, 5664, 5665, 5686, 5685); + return; +} diff --git a/dumps/scripts/4445.cs2 b/dumps/scripts/4445.cs2 new file mode 100644 index 0000000..723f070 --- /dev/null +++ b/dumps/scripts/4445.cs2 @@ -0,0 +1,17 @@ +void script_4445() { + string svar0; + deleteAllExtraChilds(new WidgetPointer(1110,5)); + deleteAllExtraChilds(new WidgetPointer(1110,8)); + deleteAllExtraChilds(new WidgetPointer(1110,6)); + deleteAllExtraChilds(new WidgetPointer(1110,7)); + deleteAllExtraChilds(new WidgetPointer(1110,4)); + setWidgetContextMenuOption(1, new WidgetPointer(1110,95), "Join chat"); + setWidgetSprite(6256, new WidgetPointer(1110,96)); + setWidgetIsHidden(true, new WidgetPointer(1110,38)); + setWidgetIsHidden(false, new WidgetPointer(1110,64)); + setWidgetText(new WidgetPointer(1110,65), ""); + svar0 = "Join another" + "
" + "clan's clanchat."; + setScriptCallOnMouseOver(4538, new WidgetPointer(1110,60), new WidgetPointer(-32768,3), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1110,95)); + setWidgetContextMenuOption(1, new WidgetPointer(1110,95), "Join Clan Chat channel"); + return; +} diff --git a/dumps/scripts/4446.cs2 b/dumps/scripts/4446.cs2 new file mode 100644 index 0000000..098ca05 --- /dev/null +++ b/dumps/scripts/4446.cs2 @@ -0,0 +1,4 @@ +void script_4446(int arg0) { + script_4447(); + return; +} diff --git a/dumps/scripts/4447.cs2 b/dumps/scripts/4447.cs2 new file mode 100644 index 0000000..7b7e521 --- /dev/null +++ b/dumps/scripts/4447.cs2 @@ -0,0 +1,3 @@ +void script_4447() { + return; +} diff --git a/dumps/scripts/4448.cs2 b/dumps/scripts/4448.cs2 new file mode 100644 index 0000000..9881b54 --- /dev/null +++ b/dumps/scripts/4448.cs2 @@ -0,0 +1,3 @@ +void script_4448(int arg0) { + return; +} diff --git a/dumps/scripts/4449.cs2 b/dumps/scripts/4449.cs2 new file mode 100644 index 0000000..9163f45 --- /dev/null +++ b/dumps/scripts/4449.cs2 @@ -0,0 +1,10 @@ +void script_4449(int arg0) { + if (cs2method5428(72744974, -1)) { + setScriptCallOnGameloop(4450, "", new WidgetPointer(1110,14)); + return; + } + if (cs2method3751()) { + script_4451(); + } + return; +} diff --git a/dumps/scripts/445.cs2 b/dumps/scripts/445.cs2 new file mode 100644 index 0000000..963e93d --- /dev/null +++ b/dumps/scripts/445.cs2 @@ -0,0 +1,4 @@ +void script_445() { + script_304(39341872); + return; +} diff --git a/dumps/scripts/4450.cs2 b/dumps/scripts/4450.cs2 new file mode 100644 index 0000000..7761149 --- /dev/null +++ b/dumps/scripts/4450.cs2 @@ -0,0 +1,10 @@ +void script_4450() { + if (cs2method5428(72744974, -1)) { + return; + } + setScriptCallOnGameloop(-1, "", new WidgetPointer(1110,14)); + if (cs2method3751()) { + script_4451(); + } + return; +} diff --git a/dumps/scripts/4451.cs2 b/dumps/scripts/4451.cs2 new file mode 100644 index 0000000..14047f7 --- /dev/null +++ b/dumps/scripts/4451.cs2 @@ -0,0 +1,4 @@ +void script_4451() { + script_4436(72744974, getWidgetActualX(new WidgetPointer(1110,27))); + return; +} diff --git a/dumps/scripts/4452.cs2 b/dumps/scripts/4452.cs2 new file mode 100644 index 0000000..c610a36 --- /dev/null +++ b/dumps/scripts/4452.cs2 @@ -0,0 +1,6 @@ +void script_4452(int arg0) { + if (cs2method3751()) { + script_4436(72744974, arg0); + } + return; +} diff --git a/dumps/scripts/4453.cs2 b/dumps/scripts/4453.cs2 new file mode 100644 index 0000000..e2fe68d --- /dev/null +++ b/dumps/scripts/4453.cs2 @@ -0,0 +1,4 @@ +void script_4453() { + setScriptCallOnGameloop(4454, new WidgetPointer(1110,5), getClientCycle(), "Ii", new WidgetPointer(1110,52)); + return; +} diff --git a/dumps/scripts/4454.cs2 b/dumps/scripts/4454.cs2 new file mode 100644 index 0000000..0a450d4 --- /dev/null +++ b/dumps/scripts/4454.cs2 @@ -0,0 +1,13 @@ +void script_4454(int arg0,int arg1) { + if (cs2method3750()) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(1110,52)); + script_4444(globalint_1506); + } else { + setWidgetSprite(6256, new WidgetPointer(1110,96)); + if (subtract(getClientCycle(), arg1) > 200) { + script_4445(); + setScriptCallOnGameloop(4454, new WidgetPointer(arg0), getClientCycle(), "Ii", new WidgetPointer(1110,52)); + } + } + return; +} diff --git a/dumps/scripts/4455.cs2 b/dumps/scripts/4455.cs2 new file mode 100644 index 0000000..a89a3b8 --- /dev/null +++ b/dumps/scripts/4455.cs2 @@ -0,0 +1,4 @@ +void script_4455() { + script_4456(); + return; +} diff --git a/dumps/scripts/4456.cs2 b/dumps/scripts/4456.cs2 new file mode 100644 index 0000000..747d30b --- /dev/null +++ b/dumps/scripts/4456.cs2 @@ -0,0 +1,9 @@ +void script_4456() { + setWidgetIsHidden(false, new WidgetPointer(1110,34)); + setWidgetIsHidden(true, new WidgetPointer(1110,36)); + setWidgetIsHidden(true, new WidgetPointer(1110,35)); + setWidgetIsHidden(false, new WidgetPointer(1110,57)); + setWidgetIsHidden(true, new WidgetPointer(1110,59)); + setWidgetIsHidden(true, new WidgetPointer(1110,55)); + return; +} diff --git a/dumps/scripts/4457.cs2 b/dumps/scripts/4457.cs2 new file mode 100644 index 0000000..79943a1 --- /dev/null +++ b/dumps/scripts/4457.cs2 @@ -0,0 +1,4 @@ +void script_4457() { + script_4458(); + return; +} diff --git a/dumps/scripts/4458.cs2 b/dumps/scripts/4458.cs2 new file mode 100644 index 0000000..b52ba03 --- /dev/null +++ b/dumps/scripts/4458.cs2 @@ -0,0 +1,9 @@ +void script_4458() { + setWidgetIsHidden(true, new WidgetPointer(1110,34)); + setWidgetIsHidden(false, new WidgetPointer(1110,36)); + setWidgetIsHidden(true, new WidgetPointer(1110,35)); + setWidgetIsHidden(true, new WidgetPointer(1110,57)); + setWidgetIsHidden(false, new WidgetPointer(1110,59)); + setWidgetIsHidden(true, new WidgetPointer(1110,55)); + return; +} diff --git a/dumps/scripts/4459.cs2 b/dumps/scripts/4459.cs2 new file mode 100644 index 0000000..abfa79a --- /dev/null +++ b/dumps/scripts/4459.cs2 @@ -0,0 +1,4 @@ +void script_4459() { + script_4460(); + return; +} diff --git a/dumps/scripts/446.cs2 b/dumps/scripts/446.cs2 new file mode 100644 index 0000000..e23591c --- /dev/null +++ b/dumps/scripts/446.cs2 @@ -0,0 +1,19 @@ +string script_446(int arg0,int arg1) { + string svar0; + string svar1; + string svar2; + svar0 = ""; + svar1 = ""; + svar2 = ""; + if (itemIsStackable(arg1)) { + svar2 = concat(svar2, "" + getItemName(arg1) + "" + " x " + "" + intToStr(arg0) + "
"); + } else if (arg0 < 100000) { + svar0 = script_46(arg0, ","); + svar2 = concat(svar2, "" + getItemName(arg1) + "" + " x " + "" + svar0 + "
"); + } else { + svar0 = script_46(arg0, ","); + svar1 = script_46(divide(arg0, 1000), ","); + svar2 = concat(svar2, "" + getItemName(arg1) + "" + " x " + "" + svar1 + "K (" + svar0 + ")" + "
"); + } + return svar2; +} diff --git a/dumps/scripts/4460.cs2 b/dumps/scripts/4460.cs2 new file mode 100644 index 0000000..7f06beb --- /dev/null +++ b/dumps/scripts/4460.cs2 @@ -0,0 +1,10 @@ +void script_4460() { + setWidgetIsHidden(true, new WidgetPointer(1110,34)); + setWidgetIsHidden(true, new WidgetPointer(1110,36)); + setWidgetIsHidden(false, new WidgetPointer(1110,35)); + setWidgetIsHidden(true, new WidgetPointer(1110,57)); + setWidgetIsHidden(true, new WidgetPointer(1110,59)); + setWidgetIsHidden(false, new WidgetPointer(1110,55)); + script_4462(); + return; +} diff --git a/dumps/scripts/4461.cs2 b/dumps/scripts/4461.cs2 new file mode 100644 index 0000000..ef72018 --- /dev/null +++ b/dumps/scripts/4461.cs2 @@ -0,0 +1,4 @@ +void script_4461() { + script_4462(); + return; +} diff --git a/dumps/scripts/4462.cs2 b/dumps/scripts/4462.cs2 new file mode 100644 index 0000000..6122133 --- /dev/null +++ b/dumps/scripts/4462.cs2 @@ -0,0 +1,78 @@ +void script_4462() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + string svar0; + ivar0 = 0; + ivar1 = 0; + ivar2 = 19; + svar0 = ""; + ivar3 = 72744971; + ivar4 = 72745001; + ivar5 = 72745000; + ivar6 = 72744970; + ivar7 = divide(getWidgetActualHeight(new WidgetPointer(ivar4)), 19); + ivar8 = 0; + deleteAllExtraChilds(new WidgetPointer(ivar3)); + deleteAllExtraChilds(new WidgetPointer(ivar6)); + if (cs2method3701()) { + setWidgetText(new WidgetPointer(1110,72), ""); + setWidgetIsHidden(true, new WidgetPointer(1110,42)); + ivar1 = cs2method3712(); + while (ivar0 < ivar1) { + ivar8 = multiply(ivar0, 19); + svar0 = cs2method3713(ivar0); + createExtraChild(new WidgetPointer(ivar3), 4, getExtraChildGap(new WidgetPointer(ivar3))); + setWidgetText(svar0); + setWidgetPosition(0, multiply(ivar0, ivar2), 0, 0); + setWidgetSize(16384, ivar2, 2, 0); + setWidgetRGB(new Color(164, 153, 125)); + setWidgetFont(3793); + setWidgetUnknownBoolean(true); + cs2method1305("" + svar0); + setWidgetContextMenuOption(1, "Remove ban"); + setScriptCallOnClickContextMenu(4580, ""); + setWidgetTextAlignment(0, 0, 0); + if (mod(ivar0, 2) != 0) { + createExtraChild(new WidgetPointer(ivar6), 3, getExtraChildGap(new WidgetPointer(ivar6))); + setWidgetSize(16384, ivar2, 2, 0); + setWidgetPosition(0, multiply(ivar0, ivar2), 0, 0); + setWidgetRGB(new Color(35, 34, 32)); + setWidgetFilled(1); + cs2method2103(128); + } + ivar0 = add(ivar0, 1); + } + while (ivar0 < ivar7) { + ivar8 = multiply(ivar0, ivar2); + if (mod(ivar0, 2) != 0) { + createExtraChild(new WidgetPointer(ivar6), 3, getExtraChildGap(new WidgetPointer(ivar6))); + setWidgetSize(16384, ivar2, 2, 0); + setWidgetPosition(0, ivar8, 0, 0); + setWidgetRGB(new Color(35, 34, 32)); + setWidgetFilled(1); + cs2method2103(128); + } + ivar0 = add(ivar0, 1); + } + } else { + setWidgetIsHidden(false, new WidgetPointer(1110,42)); + setWidgetText(new WidgetPointer(1110,72), "You must be part of a clan to" + "
" + "view the ban list."); + deleteAllExtraChilds(new WidgetPointer(ivar3)); + deleteAllExtraChilds(new WidgetPointer(ivar6)); + } + setWidgetIsHidden(false, new WidgetPointer(ivar5)); + ivar9 = cs2method2601(new WidgetPointer(1110,41)); + setWidgetScrollMax(getWidgetActualWidth(new WidgetPointer(1110,41)), multiply(ivar2, max(ivar1, ivar7)), new WidgetPointer(1110,41)); + ivar9 = min(ivar9, getWidgetScrollMaxV(new WidgetPointer(1110,41))); + cs2method2100(0, ivar9, new WidgetPointer(1110,41)); + script_31(72745000, 72745001, 5666, 5663, 5664, 5665, 5686, 5685); + return; +} diff --git a/dumps/scripts/4463.cs2 b/dumps/scripts/4463.cs2 new file mode 100644 index 0000000..9206dc4 --- /dev/null +++ b/dumps/scripts/4463.cs2 @@ -0,0 +1,33 @@ +void script_4463(int arg0,int arg1) { + int ivar2; + string svar0; + svar0 = ""; + ivar2 = 0; + if (cs2method3751()) { + if (cs2method3701()) { + svar0 = cs2method3756(arg0); + if (((boolean)arg1)) { + if (isFriend(svar0)) { + ivar2 = 1; + } else { + message(0, 0, "You only message people on your Friends List."); + } + } else { + if (arg1 == 8) { + script_4466(svar0); + } + } + } else { + messageType0("You must be in a clan to do that."); + } + } else { + messageType0("You must be in a clan to do that."); + } + if (((boolean)ivar2)) { + globalint_1650 = 1; + globalstring_23 = svar0; + script_1558(0); + return; + } + return; +} diff --git a/dumps/scripts/4464.cs2 b/dumps/scripts/4464.cs2 new file mode 100644 index 0000000..9c4134a --- /dev/null +++ b/dumps/scripts/4464.cs2 @@ -0,0 +1,17 @@ +int script_4464() { + int ivar0; + ivar0 = -1; + if (cs2method3701()) { + if (cs2method3751()) { + ivar0 = cs2method3717(strRemoveEntities(cs2method5020())); + if ((ivar0 != -1) && (cs2method3757(ivar0) >= cs2method3705())) { + return 1; + } + } else { + messageType0("You must be in a clan to do that."); + } + } else { + messageType0("You must be in a clan to do that."); + } + return 0; +} diff --git a/dumps/scripts/4465.cs2 b/dumps/scripts/4465.cs2 new file mode 100644 index 0000000..410deb1 --- /dev/null +++ b/dumps/scripts/4465.cs2 @@ -0,0 +1,8 @@ +void script_4465(string arg0) { + if (cs2method3751()) { + script_4466(arg0); + } else { + messageType0("You must be in your clan channel to do that."); + } + return; +} diff --git a/dumps/scripts/4466.cs2 b/dumps/scripts/4466.cs2 new file mode 100644 index 0000000..45696ce --- /dev/null +++ b/dumps/scripts/4466.cs2 @@ -0,0 +1,45 @@ +void script_4466(string arg0) { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + ivar0 = -1; + ivar1 = -1; + ivar2 = -1; + ivar3 = -1; + ivar0 = cs2method3760(arg0); + if (ivar0 >= 0) { + if (ivar0 == -1) { + return; + } + ivar1 = cs2method3757(ivar0); + ivar2 = cs2method3760(strRemoveEntities(cs2method5020())); + if (ivar2 >= 0) { + if (ivar2 == ivar0) { + message(43, 0, "You cannot temporarily ban yourself."); + return; + } + ivar3 = cs2method3757(ivar2); + if (ivar2 == -1) { + return; + } + if (ivar3 >= cs2method3753()) { + if (ivar1 > -1) { + message(43, 0, "You can only temporarily ban guests."); + message(43, 0, "A clan admin can remove your clanmate."); + } else if (ivar3 > ivar1) { + cs2method3759(cs2method3760(arg0)); + cs2method5006(2); + cs2method5008("[Attempting to kick/ban " + arg0 + " from this channel.]"); + } else { + message(43, 0, "You can only kick people with a lower rank than yourself."); + } + } else { + message(43, 0, "You do not have sufficient rank to kick."); + } + } + } else { + message(43, 0, "Could not find that guest to kick from your Clan Chat."); + } + return; +} diff --git a/dumps/scripts/4467.cs2 b/dumps/scripts/4467.cs2 new file mode 100644 index 0000000..dcbe684 --- /dev/null +++ b/dumps/scripts/4467.cs2 @@ -0,0 +1,16 @@ +int script_4467() { + int ivar0; + int ivar1; + ivar0 = -1; + ivar1 = -1; + if (cs2method3751()) { + ivar1 = cs2method3760(strRemoveEntities(cs2method5020())); + if (ivar1 >= 0) { + ivar0 = cs2method3757(ivar1); + if (ivar0 >= cs2method3753()) { + return 1; + } + } + } + return 0; +} diff --git a/dumps/scripts/4468.cs2 b/dumps/scripts/4468.cs2 new file mode 100644 index 0000000..1de2e32 --- /dev/null +++ b/dumps/scripts/4468.cs2 @@ -0,0 +1,14 @@ +int script_4468() { + int ivar0; + int ivar1; + ivar0 = -1; + ivar1 = -1; + ivar1 = cs2method3760(strRemoveEntities(cs2method5020())); + if (ivar1 >= 0) { + ivar0 = cs2method3757(ivar1); + if (ivar0 >= cs2method3753()) { + return 1; + } + } + return 0; +} diff --git a/dumps/scripts/4469.cs2 b/dumps/scripts/4469.cs2 new file mode 100644 index 0000000..a60f138 --- /dev/null +++ b/dumps/scripts/4469.cs2 @@ -0,0 +1,13 @@ +void script_4469() { + int ivar0; + int ivar1; + ivar0 = 0; + ivar1 = 0; + if (((boolean)script_4467())) { + setWidgetIsHidden(false, new WidgetPointer(1110,22)); + setWidgetIsHidden(true, new WidgetPointer(1110,110)); + } else { + script_4471(); + } + return; +} diff --git a/dumps/scripts/447.cs2 b/dumps/scripts/447.cs2 new file mode 100644 index 0000000..791137a --- /dev/null +++ b/dumps/scripts/447.cs2 @@ -0,0 +1,17 @@ +void script_447(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + string svar0; + svar0 = getWidgetText(new WidgetPointer(arg2)); + ivar3 = getWidgetActualWidth(new WidgetPointer(arg2)); + ivar4 = getLineCount(ivar3, 494, svar0); + ivar5 = add(multiply(ivar4, 10), 5); + if (ivar5 > getWidgetActualHeight(new WidgetPointer(arg1))) { + setWidgetScrollMax(0, ivar5, new WidgetPointer(arg1)); + script_31(arg0, arg1, 2598, 2595, 2596, 2597, 2593, 2594); + setWidgetTextAlignment(1, 0, 0, new WidgetPointer(arg2)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg2)), ivar5, 0, 0, new WidgetPointer(arg2)); + } + return; +} diff --git a/dumps/scripts/4470.cs2 b/dumps/scripts/4470.cs2 new file mode 100644 index 0000000..5aff04e --- /dev/null +++ b/dumps/scripts/4470.cs2 @@ -0,0 +1,13 @@ +void script_4470() { + int ivar0; + int ivar1; + ivar0 = 0; + ivar1 = 0; + if (((boolean)script_4468())) { + setWidgetIsHidden(false, new WidgetPointer(1110,22)); + setWidgetIsHidden(true, new WidgetPointer(1110,110)); + return; + } + script_4471(); + return; +} diff --git a/dumps/scripts/4471.cs2 b/dumps/scripts/4471.cs2 new file mode 100644 index 0000000..0b1b4cd --- /dev/null +++ b/dumps/scripts/4471.cs2 @@ -0,0 +1,4 @@ +void script_4471() { + setWidgetIsHidden(false, new WidgetPointer(1110,110)); + return; +} diff --git a/dumps/scripts/4472.cs2 b/dumps/scripts/4472.cs2 new file mode 100644 index 0000000..c8881a2 --- /dev/null +++ b/dumps/scripts/4472.cs2 @@ -0,0 +1,38 @@ +void script_4472(int arg0,int arg1,string arg2) { + int ivar2; + int ivar3; + int ivar4; + ivar2 = -1; + ivar3 = -1; + ivar4 = -1; + switch (arg0) { + case 1: + globalint_1650 = 1; + globalstring_23 = arg2; + script_1558(0); + return; + case 5: + messageType0("Attempting to add " + arg2 + " to your Friends List."); + arg2 = strRemoveEntities(arg2); + cs2method3605(arg2); + break; + case 6: + messageType0("Attempting to add " + arg2 + " to your Ignore List."); + arg2 = strRemoveEntities(arg2); + cs2method3607(arg2); + break; + case 7: + messageType0("Attempting to remove " + arg2 + " from your Friends List."); + arg2 = strRemoveEntities(arg2); + cs2method3606(arg2); + break; + case 8: + messageType0("Attempting to remove " + arg2 + " from your Ignore List."); + arg2 = strRemoveEntities(arg2); + cs2method3608(arg2); + break; + case 9: + script_4465(arg2); + } + return; +} diff --git a/dumps/scripts/4473.cs2 b/dumps/scripts/4473.cs2 new file mode 100644 index 0000000..a18502e --- /dev/null +++ b/dumps/scripts/4473.cs2 @@ -0,0 +1,4 @@ +void script_4473(int arg0,int arg1) { + script_4474(arg0, arg1); + return; +} diff --git a/dumps/scripts/4474.cs2 b/dumps/scripts/4474.cs2 new file mode 100644 index 0000000..f3599e7 --- /dev/null +++ b/dumps/scripts/4474.cs2 @@ -0,0 +1,4 @@ +void script_4474(int arg0,int arg1) { + script_4493(arg0, arg1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1); + return; +} diff --git a/dumps/scripts/4475.cs2 b/dumps/scripts/4475.cs2 new file mode 100644 index 0000000..228bf70 --- /dev/null +++ b/dumps/scripts/4475.cs2 @@ -0,0 +1,4 @@ +void script_4475(int arg0,int arg1,int arg2) { + script_4476(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/4476.cs2 b/dumps/scripts/4476.cs2 new file mode 100644 index 0000000..f5052f8 --- /dev/null +++ b/dumps/scripts/4476.cs2 @@ -0,0 +1,4 @@ +void script_4476(int arg0,int arg1,int arg2) { + script_4493(arg0, arg1, arg2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1); + return; +} diff --git a/dumps/scripts/4477.cs2 b/dumps/scripts/4477.cs2 new file mode 100644 index 0000000..2857038 --- /dev/null +++ b/dumps/scripts/4477.cs2 @@ -0,0 +1,4 @@ +void script_4477(int arg0,int arg1,int arg2,int arg3) { + script_4478(arg0, arg1, arg2, arg3); + return; +} diff --git a/dumps/scripts/4478.cs2 b/dumps/scripts/4478.cs2 new file mode 100644 index 0000000..a30b9e2 --- /dev/null +++ b/dumps/scripts/4478.cs2 @@ -0,0 +1,4 @@ +void script_4478(int arg0,int arg1,int arg2,int arg3) { + script_4493(arg0, arg1, arg2, arg3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1); + return; +} diff --git a/dumps/scripts/4479.cs2 b/dumps/scripts/4479.cs2 new file mode 100644 index 0000000..c1b413f --- /dev/null +++ b/dumps/scripts/4479.cs2 @@ -0,0 +1,4 @@ +void script_4479(int arg0,int arg1,int arg2,int arg3,int arg4) { + script_4480(arg0, arg1, arg2, arg3, arg4); + return; +} diff --git a/dumps/scripts/448.cs2 b/dumps/scripts/448.cs2 new file mode 100644 index 0000000..dfba800 --- /dev/null +++ b/dumps/scripts/448.cs2 @@ -0,0 +1,8 @@ +void script_448() { + if (((boolean)bitconfig_7537)) { + setWidgetSprite(3745, new WidgetPointer(1019,10)); + } else { + setWidgetSprite(3746, new WidgetPointer(1019,10)); + } + return; +} diff --git a/dumps/scripts/4480.cs2 b/dumps/scripts/4480.cs2 new file mode 100644 index 0000000..bd9edc3 --- /dev/null +++ b/dumps/scripts/4480.cs2 @@ -0,0 +1,4 @@ +void script_4480(int arg0,int arg1,int arg2,int arg3,int arg4) { + script_4493(arg0, arg1, arg2, arg3, arg4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1); + return; +} diff --git a/dumps/scripts/4481.cs2 b/dumps/scripts/4481.cs2 new file mode 100644 index 0000000..9070e71 --- /dev/null +++ b/dumps/scripts/4481.cs2 @@ -0,0 +1,4 @@ +void script_4481(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + script_4482(arg0, arg1, arg2, arg3, arg4, arg5); + return; +} diff --git a/dumps/scripts/4482.cs2 b/dumps/scripts/4482.cs2 new file mode 100644 index 0000000..6057407 --- /dev/null +++ b/dumps/scripts/4482.cs2 @@ -0,0 +1,4 @@ +void script_4482(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + script_4493(arg0, arg1, arg2, arg3, arg4, arg5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1); + return; +} diff --git a/dumps/scripts/4483.cs2 b/dumps/scripts/4483.cs2 new file mode 100644 index 0000000..1d517cf --- /dev/null +++ b/dumps/scripts/4483.cs2 @@ -0,0 +1,4 @@ +void script_4483(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10) { + script_4484(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + return; +} diff --git a/dumps/scripts/4484.cs2 b/dumps/scripts/4484.cs2 new file mode 100644 index 0000000..948eb85 --- /dev/null +++ b/dumps/scripts/4484.cs2 @@ -0,0 +1,4 @@ +void script_4484(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10) { + script_4493(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1); + return; +} diff --git a/dumps/scripts/4485.cs2 b/dumps/scripts/4485.cs2 new file mode 100644 index 0000000..7152697 --- /dev/null +++ b/dumps/scripts/4485.cs2 @@ -0,0 +1,4 @@ +void script_4485(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12,int arg13,int arg14,int arg15) { + script_4486(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); + return; +} diff --git a/dumps/scripts/4486.cs2 b/dumps/scripts/4486.cs2 new file mode 100644 index 0000000..546f5d7 --- /dev/null +++ b/dumps/scripts/4486.cs2 @@ -0,0 +1,4 @@ +void script_4486(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12,int arg13,int arg14,int arg15) { + script_4493(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1); + return; +} diff --git a/dumps/scripts/4487.cs2 b/dumps/scripts/4487.cs2 new file mode 100644 index 0000000..f84d0e5 --- /dev/null +++ b/dumps/scripts/4487.cs2 @@ -0,0 +1,4 @@ +void script_4487(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12,int arg13,int arg14,int arg15,int arg16,int arg17,int arg18,int arg19,int arg20) { + script_4488(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19, arg20); + return; +} diff --git a/dumps/scripts/4488.cs2 b/dumps/scripts/4488.cs2 new file mode 100644 index 0000000..2ea6248 --- /dev/null +++ b/dumps/scripts/4488.cs2 @@ -0,0 +1,4 @@ +void script_4488(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12,int arg13,int arg14,int arg15,int arg16,int arg17,int arg18,int arg19,int arg20) { + script_4493(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19, arg20, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1); + return; +} diff --git a/dumps/scripts/4489.cs2 b/dumps/scripts/4489.cs2 new file mode 100644 index 0000000..f7391ad --- /dev/null +++ b/dumps/scripts/4489.cs2 @@ -0,0 +1,4 @@ +void script_4489(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12,int arg13,int arg14,int arg15,int arg16,int arg17,int arg18,int arg19,int arg20,int arg21,int arg22,int arg23,int arg24,int arg25) { + script_4490(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19, arg20, arg21, arg22, arg23, arg24, arg25); + return; +} diff --git a/dumps/scripts/449.cs2 b/dumps/scripts/449.cs2 new file mode 100644 index 0000000..d4bd21f --- /dev/null +++ b/dumps/scripts/449.cs2 @@ -0,0 +1,4 @@ +void script_449() { + script_304(35082088); + return; +} diff --git a/dumps/scripts/4490.cs2 b/dumps/scripts/4490.cs2 new file mode 100644 index 0000000..261d001 --- /dev/null +++ b/dumps/scripts/4490.cs2 @@ -0,0 +1,4 @@ +void script_4490(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12,int arg13,int arg14,int arg15,int arg16,int arg17,int arg18,int arg19,int arg20,int arg21,int arg22,int arg23,int arg24,int arg25) { + script_4493(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19, arg20, arg21, arg22, arg23, arg24, arg25, -1, -1, -1, -1, -1); + return; +} diff --git a/dumps/scripts/4491.cs2 b/dumps/scripts/4491.cs2 new file mode 100644 index 0000000..93f38c5 --- /dev/null +++ b/dumps/scripts/4491.cs2 @@ -0,0 +1,4 @@ +void script_4491(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12,int arg13,int arg14,int arg15,int arg16,int arg17,int arg18,int arg19,int arg20,int arg21,int arg22,int arg23,int arg24,int arg25,int arg26,int arg27,int arg28,int arg29,int arg30) { + script_4492(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19, arg20, arg21, arg22, arg23, arg24, arg25, arg26, arg27, arg28, arg29, arg30); + return; +} diff --git a/dumps/scripts/4492.cs2 b/dumps/scripts/4492.cs2 new file mode 100644 index 0000000..0c75d41 --- /dev/null +++ b/dumps/scripts/4492.cs2 @@ -0,0 +1,4 @@ +void script_4492(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12,int arg13,int arg14,int arg15,int arg16,int arg17,int arg18,int arg19,int arg20,int arg21,int arg22,int arg23,int arg24,int arg25,int arg26,int arg27,int arg28,int arg29,int arg30) { + script_4493(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19, arg20, arg21, arg22, arg23, arg24, arg25, arg26, arg27, arg28, arg29, arg30); + return; +} diff --git a/dumps/scripts/4493.cs2 b/dumps/scripts/4493.cs2 new file mode 100644 index 0000000..459e4a1 --- /dev/null +++ b/dumps/scripts/4493.cs2 @@ -0,0 +1,96 @@ +void script_4493(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12,int arg13,int arg14,int arg15,int arg16,int arg17,int arg18,int arg19,int arg20,int arg21,int arg22,int arg23,int arg24,int arg25,int arg26,int arg27,int arg28,int arg29,int arg30) { + if (arg0 != -1) { + setWidgetIsHidden(true, new WidgetPointer(arg0)); + } + if (arg1 != -1) { + script_4504(arg1); + } + if (arg2 != -1) { + script_4504(arg2); + } + if (arg3 != -1) { + script_4504(arg3); + } + if (arg4 != -1) { + script_4504(arg4); + } + if (arg5 != -1) { + script_4504(arg5); + } + if (arg6 != -1) { + script_4504(arg6); + } + if (arg7 != -1) { + script_4504(arg7); + } + if (arg8 != -1) { + script_4504(arg8); + } + if (arg9 != -1) { + script_4504(arg9); + } + if (arg10 != -1) { + script_4504(arg10); + } + if (arg11 != -1) { + script_4504(arg11); + } + if (arg12 != -1) { + script_4504(arg12); + } + if (arg13 != -1) { + script_4504(arg13); + } + if (arg14 != -1) { + script_4504(arg14); + } + if (arg15 != -1) { + script_4504(arg15); + } + if (arg16 != -1) { + script_4504(arg16); + } + if (arg17 != -1) { + script_4504(arg17); + } + if (arg18 != -1) { + script_4504(arg18); + } + if (arg19 != -1) { + script_4504(arg19); + } + if (arg20 != -1) { + script_4504(arg20); + } + if (arg21 != -1) { + script_4504(arg21); + } + if (arg22 != -1) { + script_4504(arg22); + } + if (arg23 != -1) { + script_4504(arg23); + } + if (arg24 != -1) { + script_4504(arg24); + } + if (arg25 != -1) { + script_4504(arg25); + } + if (arg26 != -1) { + script_4504(arg26); + } + if (arg27 != -1) { + script_4504(arg27); + } + if (arg28 != -1) { + script_4504(arg28); + } + if (arg29 != -1) { + script_4504(arg29); + } + if (arg30 != -1) { + script_4504(arg30); + } + return; +} diff --git a/dumps/scripts/4494.cs2 b/dumps/scripts/4494.cs2 new file mode 100644 index 0000000..ffecec7 --- /dev/null +++ b/dumps/scripts/4494.cs2 @@ -0,0 +1,23 @@ +void script_4494(int arg0,int arg1) { + int ivar2; + if ((arg0 == -1) || (arg1 == -1)) { + return; + } + ivar2 = getOtherCommonData(arg1, 1346); + if (ivar2 == 2) { + setScriptCallOnMouseEntered(4159, new WidgetPointer(-32768,3), 0, 0, "Iii", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(4159, new WidgetPointer(-32768,3), 1, 0, "Iii", new WidgetPointer(arg0)); + } else if (ivar2 == 3) { + setScriptCallOnMousePressed(4162, new WidgetPointer(-32768,3), "I", new WidgetPointer(arg0)); + setScriptCallOnMouseReleased(4163, new WidgetPointer(-32768,3), "I", new WidgetPointer(arg0)); + } else if (ivar2 == 4) { + script_4208(arg0, 0); + setWidgetIsHidden(true, new WidgetPointer(arg0)); + } else { + if (ivar2 == 5) { + return; + } + } + script_4496(arg0, arg1); + return; +} diff --git a/dumps/scripts/4495.cs2 b/dumps/scripts/4495.cs2 new file mode 100644 index 0000000..e376ede --- /dev/null +++ b/dumps/scripts/4495.cs2 @@ -0,0 +1,4 @@ +void script_4495(int arg0,int arg1) { + script_4762(arg0, arg1); + return; +} diff --git a/dumps/scripts/4496.cs2 b/dumps/scripts/4496.cs2 new file mode 100644 index 0000000..7a77368 --- /dev/null +++ b/dumps/scripts/4496.cs2 @@ -0,0 +1,30 @@ +void script_4496(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + if ((arg0 == -1) || (arg1 == -1)) { + return; + } + ivar2 = getOtherCommonData(arg1, 1379); + ivar3 = getOtherCommonData(arg1, 1380); + ivar4 = getOtherCommonData(arg1, 1381); + ivar5 = getOtherCommonData(arg1, 1358); + deleteAllExtraChilds(new WidgetPointer(arg0)); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 0, 1); + setWidgetSize(20, 20, 0, 0); + setWidgetSprite(ivar2); + cs2method2103(ivar5); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 1, 1); + setWidgetSize(multiply(20, 2), 20, 1, 0); + setWidgetSprite(ivar3); + cs2method2103(ivar5); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 2, 1); + setWidgetSize(20, 20, 0, 0); + setWidgetSprite(ivar4); + cs2method2103(ivar5); + return; +} diff --git a/dumps/scripts/4497.cs2 b/dumps/scripts/4497.cs2 new file mode 100644 index 0000000..9182290 --- /dev/null +++ b/dumps/scripts/4497.cs2 @@ -0,0 +1,4 @@ +void script_4497(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,string arg8) { + script_4499(arg0, 0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + return; +} diff --git a/dumps/scripts/4498.cs2 b/dumps/scripts/4498.cs2 new file mode 100644 index 0000000..541332d --- /dev/null +++ b/dumps/scripts/4498.cs2 @@ -0,0 +1,4 @@ +void script_4498(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,string arg8) { + script_4499(arg0, 1, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + return; +} diff --git a/dumps/scripts/4499.cs2 b/dumps/scripts/4499.cs2 new file mode 100644 index 0000000..d265c31 --- /dev/null +++ b/dumps/scripts/4499.cs2 @@ -0,0 +1,85 @@ +void script_4499(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,string arg9) { + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + if (arg2 == -1) { + arg2 = subtract(getCommonDefinitionSize(arg0), 1); + } else { + arg2 = arg2; + } + deleteAllExtraChilds(new WidgetPointer(arg7)); + ivar9 = 0; + ivar10 = 5; + ivar11 = 0; + while (ivar9 <= arg2) { + createExtraChild(new WidgetPointer(arg7), 4, ivar9); + setWidgetText(cs2method_3408(105, 115, arg0, ivar9)); + if (((boolean)strLength(cs2method_3408(105, 115, arg0, ivar9)))) { + setWidgetPosition(5, ivar10, 0, 0); + setWidgetSize(5, 0, 1, 0); + setWidgetHidden(1); + } else { + setWidgetPosition(5, ivar10, 0, 0); + setWidgetSize(5, 15, 1, 0); + setWidgetFont(3793); + setWidgetRGB(new Color(111, 99, 79)); + setWidgetUnknownBoolean(true); + setScriptCallOnMouseEntered(4502, new WidgetPointer(arg6), new WidgetPointer(arg7), -2147483643, "IIi"); + ivar11 = add(ivar11, 1); + } + ivar10 = add(ivar10, getWidgetActualHeight()); + ivar9 = add(1, ivar9); + } + if (((boolean)arg1)) { + script_4508(arg7, subtract(ivar9, 1)); + } + arg3 = min(ivar11, arg3); + arg3 = max(arg3, 1); + ivar12 = multiply(15, arg3); + ivar13 = add(ivar12, multiply(5, 2)); + ivar14 = getWidgetParentId(new WidgetPointer(arg7)); + if (ivar14 == -1) { + return; + } + ivar15 = getWidgetParentId(new WidgetPointer(ivar14)); + if (ivar15 == -1) { + return; + } + ivar16 = getWidgetParentId(new WidgetPointer(ivar15)); + if (ivar16 == -1) { + return; + } + setWidgetSize(getWidgetActualWidth(new WidgetPointer(ivar15)), add(ivar13, getWidgetActualHeight(new WidgetPointer(arg4))), 0, 0, new WidgetPointer(ivar15)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(ivar15)), ivar13, 0, 0, new WidgetPointer(ivar14)); + if (getWidgetParentId(new WidgetPointer(ivar15)) == -1) { + return; + } + if (getWidgetActualHeight(new WidgetPointer(ivar16)) < getWidgetActualHeight(new WidgetPointer(ivar15))) { + return; + } + if ((getWidgetActualHeight(new WidgetPointer(ivar16)) < add(getWidgetActualY(new WidgetPointer(ivar15)), getWidgetActualHeight(new WidgetPointer(ivar15)))) && (subtract(add(getWidgetActualY(new WidgetPointer(ivar15)), getWidgetActualHeight(new WidgetPointer(arg4))), getWidgetActualHeight(new WidgetPointer(ivar15))) < 0)) { + return; + } + if (add(getWidgetActualY(new WidgetPointer(ivar15)), ivar13) > getWidgetActualHeight(new WidgetPointer(getWidgetParentId(new WidgetPointer(ivar15))))) { + setWidgetPosition(getWidgetActualX(new WidgetPointer(ivar15)), subtract(getWidgetActualY(new WidgetPointer(ivar15)), subtract(getWidgetActualHeight(new WidgetPointer(ivar15)), getWidgetActualHeight(new WidgetPointer(arg4)))), 0, 0, new WidgetPointer(ivar15)); + setWidgetPosition(0, 0, 0, 0, new WidgetPointer(ivar14)); + setWidgetPosition(0, 0, 0, 2, new WidgetPointer(arg4)); + } else { + setWidgetPosition(0, 0, 0, 0, new WidgetPointer(arg4)); + setWidgetPosition(0, 0, 0, 2, new WidgetPointer(ivar14)); + } + setWidgetIsHidden(true, new WidgetPointer(ivar14)); + setScriptCallOnMousePressed(4505, new WidgetPointer(arg7), new WidgetPointer(arg4), new WidgetPointer(arg8), "III", new WidgetPointer(arg4)); + setWidgetSize(0, 15, 1, 0, new WidgetPointer(arg6)); + setWidgetIsHidden(true, new WidgetPointer(arg6)); + setWidgetScrollMax(0, add(ivar10, 5), new WidgetPointer(arg7)); + deleteAllExtraChilds(new WidgetPointer(arg5)); + script_31(arg5, arg7, 5666, 5663, 5664, 5665, 5686, 5685); + script_4501(arg4, arg9); + return; +} diff --git a/dumps/scripts/45.cs2 b/dumps/scripts/45.cs2 new file mode 100644 index 0000000..55cb9b3 --- /dev/null +++ b/dumps/scripts/45.cs2 @@ -0,0 +1,4 @@ +void script_45(int arg0,int arg1) { + setWidgetRGB(new Color(arg1), new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/450.cs2 b/dumps/scripts/450.cs2 new file mode 100644 index 0000000..79ea1db --- /dev/null +++ b/dumps/scripts/450.cs2 @@ -0,0 +1,4 @@ +void script_450() { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(1019,11)); + return; +} diff --git a/dumps/scripts/4500.cs2 b/dumps/scripts/4500.cs2 new file mode 100644 index 0000000..c7aabbc --- /dev/null +++ b/dumps/scripts/4500.cs2 @@ -0,0 +1,4 @@ +void script_4500(int arg0,string arg1) { + script_4501(arg0, arg1); + return; +} diff --git a/dumps/scripts/4501.cs2 b/dumps/scripts/4501.cs2 new file mode 100644 index 0000000..4a6bbdb --- /dev/null +++ b/dumps/scripts/4501.cs2 @@ -0,0 +1,11 @@ +void script_4501(int arg0,string arg1) { + deleteAllExtraChilds(new WidgetPointer(arg0)); + createExtraChild(new WidgetPointer(arg0), 4, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetText(arg1); + setWidgetFont(3793); + setWidgetPosition(5, 0, 0, 1); + setWidgetSize(5, 16384, 1, 2); + setWidgetTextAlignment(0, 1, 0); + setWidgetRGB(new Color(0, 0, 0)); + return; +} diff --git a/dumps/scripts/4502.cs2 b/dumps/scripts/4502.cs2 new file mode 100644 index 0000000..36d919e --- /dev/null +++ b/dumps/scripts/4502.cs2 @@ -0,0 +1,7 @@ +void script_4502(int arg0,int arg1,int arg2) { + if (setWidgetRegister(new WidgetPointer(arg1), arg2) && (strLength(getWidgetText()) > 0)) { + setWidgetIsHidden(false, new WidgetPointer(arg0)); + setWidgetPosition(0, getWidgetActualY(), 0, 0, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/4503.cs2 b/dumps/scripts/4503.cs2 new file mode 100644 index 0000000..6e52b28 --- /dev/null +++ b/dumps/scripts/4503.cs2 @@ -0,0 +1,4 @@ +void script_4503(int arg0) { + script_4504(arg0); + return; +} diff --git a/dumps/scripts/4504.cs2 b/dumps/scripts/4504.cs2 new file mode 100644 index 0000000..b334d68 --- /dev/null +++ b/dumps/scripts/4504.cs2 @@ -0,0 +1,17 @@ +void script_4504(int arg0) { + int ivar1; + int ivar2; + ivar1 = getWidgetParentId(new WidgetPointer(arg0)); + if (ivar1 == -1) { + return; + } + ivar2 = subtract(getExtraChildGap(new WidgetPointer(ivar1)), 1); + while (ivar2 >= 0) { + if (setWidgetRegister(new WidgetPointer(ivar1), ivar2)) { + setWidgetNoOptions(); + } + ivar2 = subtract(ivar2, 1); + } + setWidgetIsHidden(true, new WidgetPointer(ivar1)); + return; +} diff --git a/dumps/scripts/4505.cs2 b/dumps/scripts/4505.cs2 new file mode 100644 index 0000000..5c3d5dd --- /dev/null +++ b/dumps/scripts/4505.cs2 @@ -0,0 +1,4 @@ +void script_4505(int arg0,int arg1,int arg2) { + script_4506(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/4506.cs2 b/dumps/scripts/4506.cs2 new file mode 100644 index 0000000..5a8540f --- /dev/null +++ b/dumps/scripts/4506.cs2 @@ -0,0 +1,32 @@ +void script_4506(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + int ivar6; + ivar3 = getWidgetParentId(new WidgetPointer(arg0)); + if (ivar3 == -1) { + return; + } + ivar4 = getWidgetParentId(new WidgetPointer(ivar3)); + if (ivar4 == -1) { + return; + } + ivar5 = getWidgetParentId(new WidgetPointer(arg1)); + if (ivar5 == -1) { + return; + } + setWidgetIsHidden(false, new WidgetPointer(ivar3)); + cs2method2005(1, new WidgetPointer(ivar3)); + if (arg2 != -1) { + setWidgetIsHidden(false, new WidgetPointer(arg2)); + } + ivar6 = subtract(getExtraChildGap(new WidgetPointer(arg0)), 1); + while (ivar6 >= 0) { + if (setWidgetRegister(new WidgetPointer(arg0), ivar6) && (strLength(getWidgetText()) > 0)) { + setWidgetContextMenuOption(1, "Select"); + setScriptCallOnClickContextMenu(4507, -2147483643, new WidgetPointer(arg0), new WidgetPointer(arg1), "iII"); + } + ivar6 = subtract(ivar6, 1); + } + return; +} diff --git a/dumps/scripts/4507.cs2 b/dumps/scripts/4507.cs2 new file mode 100644 index 0000000..da3fb4c --- /dev/null +++ b/dumps/scripts/4507.cs2 @@ -0,0 +1,16 @@ +void script_4507(int arg0,int arg1,int arg2) { + string svar0; + svar0 = ""; + if (setWidgetRegister(new WidgetPointer(arg1), arg0)) { + svar0 = getWidgetText(); + } + deleteAllExtraChilds(new WidgetPointer(arg2)); + createExtraChild(new WidgetPointer(arg2), 4, getExtraChildGap(new WidgetPointer(arg2))); + setWidgetText(svar0); + setWidgetFont(3793); + setWidgetPosition(5, 0, 0, 1); + setWidgetSize(5, 16384, 1, 2); + setWidgetTextAlignment(0, 1, 0); + setWidgetRGB(new Color(0, 0, 0)); + return; +} diff --git a/dumps/scripts/4508.cs2 b/dumps/scripts/4508.cs2 new file mode 100644 index 0000000..a88d107 --- /dev/null +++ b/dumps/scripts/4508.cs2 @@ -0,0 +1,28 @@ +void script_4508(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + ivar2 = 0; + globalarray_0 = new int[arg1]; + ivar3 = 0; + ivar4 = 5; + while (ivar2 <= arg1) { + if (setWidgetRegister(new WidgetPointer(arg0), ivar2) && (strLength(getWidgetText()) > 0)) { + globalarray_0[ivar3] = ivar2; + ivar3 = add(ivar3, 1); + } + ivar2 = add(ivar2, 1); + } + if (ivar3 > 1) { + script_4424(0, arg0, 0, subtract(ivar3, 1)); + } + ivar2 = 0; + while (ivar2 < ivar3) { + if (setWidgetRegister(new WidgetPointer(arg0), globalarray_0[ivar2])) { + setWidgetPosition(5, ivar4, 0, 0); + ivar4 = add(ivar4, getWidgetActualHeight()); + } + ivar2 = add(ivar2, 1); + } + return; +} diff --git a/dumps/scripts/4509.cs2 b/dumps/scripts/4509.cs2 new file mode 100644 index 0000000..61c92e4 --- /dev/null +++ b/dumps/scripts/4509.cs2 @@ -0,0 +1,11 @@ +void script_4509(int arg0) { + int ivar1; + int ivar2; + ivar1 = 535; + ivar2 = 536; + setWidgetSprite(ivar1, new WidgetPointer(arg0)); + setScriptCallOnMouseEntered(44, new WidgetPointer(-32768,3), ivar2, "Id", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(44, new WidgetPointer(-32768,3), ivar1, "Id", new WidgetPointer(arg0)); + setScriptCallOnClickContextMenu(29, "", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/451.cs2 b/dumps/scripts/451.cs2 new file mode 100644 index 0000000..3bdbb1e --- /dev/null +++ b/dumps/scripts/451.cs2 @@ -0,0 +1,4 @@ +void script_451() { + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(1019,11)); + return; +} diff --git a/dumps/scripts/4510.cs2 b/dumps/scripts/4510.cs2 new file mode 100644 index 0000000..7c8dec0 --- /dev/null +++ b/dumps/scripts/4510.cs2 @@ -0,0 +1,21 @@ +void script_4510(int arg0,int arg1) { + int ivar2; + if ((arg0 == -1) || (arg1 == -1)) { + return; + } + ivar2 = getOtherCommonData(arg1, 1346); + if (ivar2 == 2) { + setScriptCallOnMouseEntered(4159, new WidgetPointer(-32768,3), 0, 0, "Iii", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(4159, new WidgetPointer(-32768,3), 255, 0, "Iii", new WidgetPointer(arg0)); + } else if (ivar2 == 3) { + setScriptCallOnMousePressed(4162, new WidgetPointer(-32768,3), "I", new WidgetPointer(arg0)); + setScriptCallOnMouseReleased(4163, new WidgetPointer(-32768,3), "I", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(4163, new WidgetPointer(-32768,3), "I", new WidgetPointer(arg0)); + } else { + if (ivar2 == 5) { + return; + } + } + script_4202(arg0, arg1); + return; +} diff --git a/dumps/scripts/4511.cs2 b/dumps/scripts/4511.cs2 new file mode 100644 index 0000000..259848d --- /dev/null +++ b/dumps/scripts/4511.cs2 @@ -0,0 +1,25 @@ +void script_4511(int arg0,int arg1) { + int ivar2; + if ((arg0 == -1) || (arg1 == -1)) { + return; + } + ivar2 = getOtherCommonData(arg1, 1346); + if (ivar2 == 2) { + setScriptCallOnMouseEntered(4159, new WidgetPointer(-32768,3), 0, 0, "Iii", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(4159, new WidgetPointer(-32768,3), 1, 0, "Iii", new WidgetPointer(arg0)); + } else if (ivar2 == 3) { + setScriptCallOnMousePressed(4162, new WidgetPointer(-32768,3), "I", new WidgetPointer(arg0)); + setScriptCallOnMouseReleased(4163, new WidgetPointer(-32768,3), "I", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(4163, new WidgetPointer(-32768,3), "I", new WidgetPointer(arg0)); + } else { + if (ivar2 == 5) { + return; + } + } + script_4512(arg0, arg1); + if (ivar2 == 4) { + script_4161(arg0, 0); + setWidgetIsHidden(true, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/4512.cs2 b/dumps/scripts/4512.cs2 new file mode 100644 index 0000000..89c5f20 --- /dev/null +++ b/dumps/scripts/4512.cs2 @@ -0,0 +1,16 @@ +void script_4512(int arg0,int arg1) { + int ivar2; + int ivar3; + if ((arg0 == -1) || (arg1 == -1)) { + return; + } + ivar2 = getOtherCommonData(arg1, 1351); + ivar3 = getOtherCommonData(arg1, 1358); + deleteAllExtraChilds(new WidgetPointer(arg0)); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 1, 1); + setWidgetSize(60, 60, 0, 0); + setWidgetSprite(ivar2); + cs2method2103(ivar3); + return; +} diff --git a/dumps/scripts/4513.cs2 b/dumps/scripts/4513.cs2 new file mode 100644 index 0000000..e4675f6 --- /dev/null +++ b/dumps/scripts/4513.cs2 @@ -0,0 +1,25 @@ +void script_4513(int arg0,int arg1) { + int ivar2; + if ((arg0 == -1) || (arg1 == -1)) { + return; + } + ivar2 = getOtherCommonData(arg1, 1346); + if (ivar2 == 2) { + setScriptCallOnMouseEntered(4159, new WidgetPointer(-32768,3), 0, 0, "Iii", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(4159, new WidgetPointer(-32768,3), 1, 0, "Iii", new WidgetPointer(arg0)); + } else if (ivar2 == 3) { + setScriptCallOnMousePressed(4162, new WidgetPointer(-32768,3), "I", new WidgetPointer(arg0)); + setScriptCallOnMouseReleased(4163, new WidgetPointer(-32768,3), "I", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(4163, new WidgetPointer(-32768,3), "I", new WidgetPointer(arg0)); + } else { + if (ivar2 == 5) { + return; + } + } + script_4206(arg0, arg1); + if ((ivar2 == 4) || (ivar2 == 5)) { + script_4161(arg0, 0); + setWidgetIsHidden(true, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/4514.cs2 b/dumps/scripts/4514.cs2 new file mode 100644 index 0000000..79129ac --- /dev/null +++ b/dumps/scripts/4514.cs2 @@ -0,0 +1,25 @@ +void script_4514(int arg0,int arg1) { + int ivar2; + if ((arg0 == -1) || (arg1 == -1)) { + return; + } + ivar2 = getOtherCommonData(arg1, 1346); + if (ivar2 == 2) { + setScriptCallOnMouseEntered(4159, new WidgetPointer(-32768,3), 0, 0, "Iii", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(4159, new WidgetPointer(-32768,3), 1, 0, "Iii", new WidgetPointer(arg0)); + } else if (ivar2 == 3) { + setScriptCallOnMousePressed(4162, new WidgetPointer(-32768,3), "I", new WidgetPointer(arg0)); + setScriptCallOnMouseReleased(4163, new WidgetPointer(-32768,3), "I", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(4163, new WidgetPointer(-32768,3), "I", new WidgetPointer(arg0)); + } else { + if (ivar2 == 5) { + return; + } + } + script_4515(arg0, arg1); + if (ivar2 == 4) { + script_4161(arg0, 0); + setWidgetIsHidden(true, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/4515.cs2 b/dumps/scripts/4515.cs2 new file mode 100644 index 0000000..e15d186 --- /dev/null +++ b/dumps/scripts/4515.cs2 @@ -0,0 +1,95 @@ +void script_4515(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + if ((arg0 == -1) || (arg1 == -1)) { + return; + } + ivar2 = getOtherCommonData(arg1, 1347); + ivar3 = getOtherCommonData(arg1, 1349); + ivar4 = getOtherCommonData(arg1, 1352); + ivar5 = getOtherCommonData(arg1, 1350); + ivar6 = getOtherCommonData(arg1, 1353); + ivar7 = getOtherCommonData(arg1, 1354); + ivar8 = getOtherCommonData(arg1, 1351); + ivar9 = getOtherCommonData(arg1, 1357); + ivar10 = getOtherCommonData(arg1, 1358); + deleteAllExtraChilds(new WidgetPointer(arg0)); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 1, 0); + setWidgetSize(14, 16384, 1, 2); + setWidgetSprite(ivar8); + cs2method1107(1); + cs2method2103(ivar10); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 1, 2); + setWidgetSize(14, 10000, 1, 2); + setWidgetSprite(ivar9); + cs2method1107(1); + cs2method2103(ivar10); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(7, 16384, 0, 2); + setWidgetSprite(ivar6); + cs2method2103(ivar10); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 2, 0); + setWidgetSize(7, 16384, 0, 2); + setWidgetSprite(ivar6); + setWidgetHFlip(1); + cs2method2103(ivar10); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(7, 7, 0, 0); + setWidgetSprite(ivar3); + cs2method2103(ivar10); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 1, 0); + setWidgetSize(14, 7, 1, 0); + setWidgetSprite(ivar2); + cs2method1107(1); + cs2method2103(ivar10); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 2, 0); + setWidgetSize(7, 7, 0, 0); + setWidgetSprite(ivar3); + cs2method2103(ivar10); + setWidgetHFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 0, 2); + setWidgetSize(7, 10000, 0, 2); + setWidgetSprite(ivar7); + cs2method1107(1); + cs2method2103(ivar10); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 2, 2); + setWidgetSize(7, 10000, 0, 2); + setWidgetSprite(ivar7); + cs2method1107(1); + setWidgetHFlip(1); + cs2method2103(ivar10); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 0, 2); + setWidgetSize(7, 7, 0, 0); + setWidgetSprite(ivar5); + cs2method2103(ivar10); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 1, 2); + setWidgetSize(14, 7, 1, 0); + setWidgetSprite(ivar4); + cs2method1107(1); + cs2method2103(ivar10); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 2, 2); + setWidgetSize(7, 7, 0, 0); + setWidgetSprite(ivar5); + cs2method2103(ivar10); + setWidgetHFlip(1); + return; +} diff --git a/dumps/scripts/4516.cs2 b/dumps/scripts/4516.cs2 new file mode 100644 index 0000000..e58ac7e --- /dev/null +++ b/dumps/scripts/4516.cs2 @@ -0,0 +1,4 @@ +void script_4516(int arg0) { + script_4211(arg0, 4040, 16, 7961468); + return; +} diff --git a/dumps/scripts/4517.cs2 b/dumps/scripts/4517.cs2 new file mode 100644 index 0000000..41b5706 --- /dev/null +++ b/dumps/scripts/4517.cs2 @@ -0,0 +1,4 @@ +void script_4517(int arg0,string arg1) { + script_4212(arg0, 4040, 16, 7961468, arg1); + return; +} diff --git a/dumps/scripts/4518.cs2 b/dumps/scripts/4518.cs2 new file mode 100644 index 0000000..70fc8c5 --- /dev/null +++ b/dumps/scripts/4518.cs2 @@ -0,0 +1,4 @@ +void script_4518(int arg0,string arg1) { + script_4212(arg0, 4040, 15458492, 5918266, arg1); + return; +} diff --git a/dumps/scripts/4519.cs2 b/dumps/scripts/4519.cs2 new file mode 100644 index 0000000..4b42401 --- /dev/null +++ b/dumps/scripts/4519.cs2 @@ -0,0 +1,4 @@ +void script_4519(int arg0) { + script_4521(arg0, 6004, 6005, 6006); + return; +} diff --git a/dumps/scripts/452.cs2 b/dumps/scripts/452.cs2 new file mode 100644 index 0000000..311a160 --- /dev/null +++ b/dumps/scripts/452.cs2 @@ -0,0 +1,8 @@ +void script_452() { + if (((boolean)bitconfig_7537)) { + setWidgetSprite(3745, new WidgetPointer(1008,31)); + } else { + setWidgetSprite(3746, new WidgetPointer(1008,31)); + } + return; +} diff --git a/dumps/scripts/4520.cs2 b/dumps/scripts/4520.cs2 new file mode 100644 index 0000000..8e00436 --- /dev/null +++ b/dumps/scripts/4520.cs2 @@ -0,0 +1,4 @@ +void script_4520(int arg0) { + script_4521(arg0, 6009, 6010, 6011); + return; +} diff --git a/dumps/scripts/4521.cs2 b/dumps/scripts/4521.cs2 new file mode 100644 index 0000000..7439ebc --- /dev/null +++ b/dumps/scripts/4521.cs2 @@ -0,0 +1,25 @@ +void script_4521(int arg0,int arg1,int arg2,int arg3) { + if (arg0 == -1) { + return; + } + deleteAllExtraChilds(new WidgetPointer(arg0)); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(16384, 16384, 2, 2); + setWidgetPosition(0, 0, 1, 1); + setWidgetSprite(arg1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(16384, 16384, 2, 2); + setWidgetPosition(0, 0, 1, 1); + setWidgetSprite(arg2); + cs2method2103(255); + setScriptCallOnMouseEntered(4209, new WidgetPointer(-32768,3), 0, "Ii"); + setScriptCallOnMouseExit(4209, new WidgetPointer(-32768,3), 1, "Ii"); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(16384, 16384, 2, 2); + setWidgetPosition(0, 0, 1, 1); + setWidgetSprite(arg3); + cs2method2103(255); + setScriptCallOnMousePressed(4207, new WidgetPointer(-32768,3), 0, "Ii"); + setScriptCallOnMouseReleased(4207, new WidgetPointer(-32768,3), 255, "Ii"); + return; +} diff --git a/dumps/scripts/4522.cs2 b/dumps/scripts/4522.cs2 new file mode 100644 index 0000000..3f2921c --- /dev/null +++ b/dumps/scripts/4522.cs2 @@ -0,0 +1,4 @@ +void script_4522(int arg0) { + script_4524(arg0, 6008); + return; +} diff --git a/dumps/scripts/4523.cs2 b/dumps/scripts/4523.cs2 new file mode 100644 index 0000000..2c1f55a --- /dev/null +++ b/dumps/scripts/4523.cs2 @@ -0,0 +1,4 @@ +void script_4523(int arg0) { + script_4524(arg0, 6013); + return; +} diff --git a/dumps/scripts/4524.cs2 b/dumps/scripts/4524.cs2 new file mode 100644 index 0000000..2d2fe6d --- /dev/null +++ b/dumps/scripts/4524.cs2 @@ -0,0 +1,9 @@ +void script_4524(int arg0,int arg1) { + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(16384, 16384, 2, 2); + setWidgetPosition(0, 0, 1, 1); + setWidgetSprite(arg1); + cs2method2005(1, new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/4525.cs2 b/dumps/scripts/4525.cs2 new file mode 100644 index 0000000..ad9ccb0 --- /dev/null +++ b/dumps/scripts/4525.cs2 @@ -0,0 +1,4 @@ +void script_4525(int arg0,int arg1) { + script_4526(arg0, arg1); + return; +} diff --git a/dumps/scripts/4526.cs2 b/dumps/scripts/4526.cs2 new file mode 100644 index 0000000..760f5a5 --- /dev/null +++ b/dumps/scripts/4526.cs2 @@ -0,0 +1,25 @@ +void script_4526(int arg0,int arg1) { + int ivar2; + if ((arg0 == -1) || (arg1 == -1)) { + return; + } + ivar2 = getOtherCommonData(arg1, 1346); + if (ivar2 == 2) { + setScriptCallOnMouseEntered(4159, new WidgetPointer(-32768,3), 0, 0, "Iii", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(4159, new WidgetPointer(-32768,3), 255, 0, "Iii", new WidgetPointer(arg0)); + } else if (ivar2 == 3) { + setScriptCallOnMousePressed(4162, new WidgetPointer(-32768,3), "I", new WidgetPointer(arg0)); + setScriptCallOnMouseReleased(4163, new WidgetPointer(-32768,3), "I", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(4163, new WidgetPointer(-32768,3), "I", new WidgetPointer(arg0)); + } else { + if (ivar2 == 5) { + return; + } + } + script_4527(arg0, arg1); + if (ivar2 == 4) { + script_4161(arg0, 0); + setWidgetIsHidden(true, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/4527.cs2 b/dumps/scripts/4527.cs2 new file mode 100644 index 0000000..859e253 --- /dev/null +++ b/dumps/scripts/4527.cs2 @@ -0,0 +1,81 @@ +void script_4527(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + if ((arg0 == -1) || (arg1 == -1)) { + return; + } + ivar2 = getOtherCommonData(arg1, 1346); + ivar3 = getOtherCommonData(arg1, 1349); + ivar4 = getOtherCommonData(arg1, 1347); + ivar5 = getOtherCommonData(arg1, 1350); + ivar6 = getOtherCommonData(arg1, 1352); + ivar7 = getOtherCommonData(arg1, 1353); + ivar8 = getOtherCommonData(arg1, 1351); + ivar9 = getOtherCommonData(arg1, 1358); + ivar10 = getOtherCommonData(arg1, 1359); + deleteAllExtraChilds(new WidgetPointer(arg0)); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 1, 1); + setWidgetSize(24, 18, 1, 1); + setWidgetSprite(ivar8); + cs2method2103(ivar9); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 1, 0); + setWidgetSize(24, 9, 1, 0); + setWidgetSprite(ivar4); + cs2method2103(ivar9); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 1, 2); + setWidgetSize(24, 9, 1, 0); + setWidgetSprite(ivar6); + cs2method2103(ivar9); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 0, 1); + setWidgetSize(12, 5, 0, 1); + setWidgetSprite(ivar7); + cs2method2103(ivar9); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 2, 1); + setWidgetSize(12, 5, 0, 1); + setWidgetSprite(ivar7); + setWidgetHFlip(1); + cs2method2103(ivar9); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(12, 9, 0, 0); + setWidgetSprite(ivar3); + cs2method2103(ivar9); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 0, 2); + setWidgetSize(12, 9, 0, 0); + setWidgetSprite(ivar5); + cs2method2103(ivar9); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 2, 0); + setWidgetSize(12, 9, 0, 0); + setWidgetSprite(ivar3); + setWidgetHFlip(1); + cs2method2103(ivar9); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 2, 2); + setWidgetSize(12, 9, 0, 0); + setWidgetSprite(ivar5); + setWidgetHFlip(1); + cs2method2103(ivar9); + if (ivar2 == 4) { + setWidgetIsHidden(true, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/4528.cs2 b/dumps/scripts/4528.cs2 new file mode 100644 index 0000000..5d539a3 --- /dev/null +++ b/dumps/scripts/4528.cs2 @@ -0,0 +1,4 @@ +void script_4528(int arg0,int arg1,int arg2) { + script_4529(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/4529.cs2 b/dumps/scripts/4529.cs2 new file mode 100644 index 0000000..bd7207a --- /dev/null +++ b/dumps/scripts/4529.cs2 @@ -0,0 +1,52 @@ +void script_4529(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + if ((arg0 == -1) || (arg2 == -1)) { + return; + } + ivar3 = getOtherCommonData(arg2, 1346); + ivar4 = getOtherCommonData(arg2, 1388); + ivar5 = getOtherCommonData(arg2, 1389); + ivar6 = -1; + ivar7 = -1; + ivar8 = -1; + ivar9 = -1; + if (((boolean)ivar3)) { + ivar6 = getOtherCommonData(arg2, 1393); + ivar7 = getOtherCommonData(arg2, 1394); + ivar8 = getOtherCommonData(arg2, 1395); + ivar9 = getOtherCommonData(arg2, 1396); + script_31(arg0, arg1, ivar6, ivar7, ivar8, ivar9, ivar4, ivar5); + } else { + if ((ivar3 == 2) || (ivar3 == 3)) { + deleteAllExtraChilds(new WidgetPointer(arg0)); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 1, 0); + setWidgetSize(16, 16, 0, 0); + setWidgetSprite(ivar4); + cs2method2103(255); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 1, 2); + setWidgetSize(16, 16, 0, 0); + setWidgetSprite(ivar5); + cs2method2103(255); + if (ivar3 == 2) { + setScriptCallOnMouseEntered(4159, new WidgetPointer(-32768,3), 0, 0, "Iii", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(4159, new WidgetPointer(-32768,3), 1, 0, "Iii", new WidgetPointer(arg0)); + } else { + if (ivar3 == 3) { + setScriptCallOnMousePressed(4162, new WidgetPointer(-32768,3), "I", new WidgetPointer(arg0)); + setScriptCallOnMouseDragged(4162, new WidgetPointer(-32768,3), "I", new WidgetPointer(arg0)); + setScriptCallOnMouseReleased(4163, new WidgetPointer(-32768,3), "I", new WidgetPointer(arg0)); + setScriptCallOnMouseDragReleased(4163, new WidgetPointer(-32768,3), "I", new WidgetPointer(arg0)); + } + } + } + } + return; +} diff --git a/dumps/scripts/453.cs2 b/dumps/scripts/453.cs2 new file mode 100644 index 0000000..a5c5728 --- /dev/null +++ b/dumps/scripts/453.cs2 @@ -0,0 +1,4 @@ +void script_453() { + script_304(47812258); + return; +} diff --git a/dumps/scripts/4530.cs2 b/dumps/scripts/4530.cs2 new file mode 100644 index 0000000..de220e7 --- /dev/null +++ b/dumps/scripts/4530.cs2 @@ -0,0 +1,55 @@ +void script_4530(int arg0) { + int ivar1; + int ivar2; + ivar1 = 4; + ivar2 = 4; + deleteAllExtraChilds(new WidgetPointer(arg0)); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(multiply(ivar1, 2), multiply(ivar2, 2), 1, 1); + setWidgetPosition(0, 0, 1, 1); + setWidgetSprite(5470); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(multiply(ivar1, 2), ivar2, 1, 0); + setWidgetPosition(0, 0, 1, 0); + setWidgetSprite(5472); + cs2method1107(1); + setWidgetVFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(multiply(ivar1, 2), ivar2, 1, 0); + setWidgetPosition(0, 0, 1, 2); + setWidgetSprite(5472); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(ivar1, multiply(ivar2, 2), 0, 1); + setWidgetPosition(0, 0, 0, 1); + setWidgetSprite(5473); + cs2method1107(1); + setWidgetHFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(ivar1, multiply(ivar2, 2), 0, 1); + setWidgetPosition(0, 0, 2, 1); + setWidgetSprite(5473); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(ivar1, ivar2, 0, 0); + setWidgetPosition(0, 0, 0, 0); + setWidgetSprite(5633); + setWidgetHFlip(1); + setWidgetVFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(ivar1, ivar2, 0, 0); + setWidgetPosition(0, 0, 2, 0); + setWidgetSprite(5633); + setWidgetVFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(ivar1, ivar2, 0, 0); + setWidgetPosition(0, 0, 0, 2); + setWidgetSprite(5633); + setWidgetHFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(ivar1, ivar2, 0, 0); + setWidgetPosition(0, 0, 2, 2); + setWidgetSprite(5633); + return; +} diff --git a/dumps/scripts/4531.cs2 b/dumps/scripts/4531.cs2 new file mode 100644 index 0000000..344dc72 --- /dev/null +++ b/dumps/scripts/4531.cs2 @@ -0,0 +1,135 @@ +void script_4531(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + if (arg0 == -1) { + return; + } + ivar1 = 4; + ivar2 = 4; + ivar3 = 4; + ivar4 = 4; + ivar5 = 29; + ivar6 = 8; + ivar7 = 56; + ivar8 = 7; + ivar9 = 120; + ivar10 = 64; + ivar11 = 53; + ivar12 = 8; + ivar13 = 68; + ivar14 = 43; + if (setWidgetRegister(new WidgetPointer(arg0))) { + setWidgetPosition(0, 0, 1, 1); + setWidgetSize(multiply(ivar1, 2), multiply(ivar2, 2), 1, 1); + } + deleteAllExtraChilds(new WidgetPointer(arg0)); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(multiply(ivar12, 2), ivar4, 1, 0); + setWidgetPosition(0, ivar5, 1, 0); + setWidgetSprite(5472); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(multiply(ivar12, 2), ivar4, 1, 0); + setWidgetPosition(0, ivar8, 1, 2); + setWidgetSprite(5472); + cs2method1107(1); + setWidgetVFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(ivar3, add(ivar5, ivar8), 0, 1); + setWidgetPosition(ivar12, ivar5, 0, 0); + setWidgetSprite(5473); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(ivar3, add(ivar5, ivar8), 0, 1); + setWidgetPosition(ivar12, ivar5, 2, 0); + setWidgetSprite(5473); + cs2method1107(1); + setWidgetHFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(multiply(add(ivar6, ivar7), 2), ivar5, 1, 0); + setWidgetPosition(0, 0, 1, 0); + setWidgetSprite(5465); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(ivar7, ivar5, 0, 0); + setWidgetPosition(ivar12, 0, 0, 0); + setWidgetSprite(5466); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(ivar7, ivar5, 0, 0); + setWidgetPosition(ivar12, 0, 2, 0); + setWidgetSprite(5466); + setWidgetHFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(multiply(add(ivar10, ivar9), 2), ivar8, 1, 0); + setWidgetPosition(0, 0, 1, 2); + setWidgetSprite(5632); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(ivar9, ivar8, 0, 0); + setWidgetPosition(ivar10, 0, 0, 2); + setWidgetSprite(5460); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(ivar9, ivar8, 0, 0); + setWidgetPosition(ivar10, 0, 2, 2); + setWidgetSprite(5634); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(ivar12, add(add(add(ivar5, ivar11), ivar13), ivar14), 0, 1); + setWidgetPosition(0, add(ivar5, ivar13), 0, 0); + setWidgetSprite(5468); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(ivar12, ivar13, 0, 0); + setWidgetPosition(0, ivar5, 0, 0); + setWidgetSprite(5464); + setWidgetHFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(ivar12, ivar14, 0, 0); + setWidgetPosition(0, ivar11, 0, 2); + setWidgetSprite(5469); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(ivar12, add(add(add(ivar5, ivar11), ivar13), ivar14), 0, 1); + setWidgetPosition(0, add(ivar5, ivar13), 2, 0); + setWidgetSprite(5468); + cs2method1107(1); + setWidgetHFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(ivar12, ivar13, 0, 0); + setWidgetPosition(0, ivar5, 2, 0); + setWidgetSprite(5464); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(ivar12, ivar14, 0, 0); + setWidgetPosition(0, ivar11, 2, 2); + setWidgetSprite(5469); + setWidgetHFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(ivar6, ivar5, 0, 0); + setWidgetPosition(0, 0, 0, 0); + setWidgetSprite(5467); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(ivar6, ivar5, 0, 0); + setWidgetPosition(0, 0, 2, 0); + setWidgetSprite(5467); + setWidgetHFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(ivar10, ivar11, 0, 0); + setWidgetPosition(0, 0, 0, 2); + setWidgetSprite(5461); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(ivar10, ivar11, 0, 0); + setWidgetPosition(0, 0, 2, 2); + setWidgetSprite(5461); + setWidgetHFlip(1); + return; +} diff --git a/dumps/scripts/4532.cs2 b/dumps/scripts/4532.cs2 new file mode 100644 index 0000000..9b38bc3 --- /dev/null +++ b/dumps/scripts/4532.cs2 @@ -0,0 +1,13 @@ +void script_4532(int arg0) { + int ivar1; + ivar1 = getWidgetParentId(new WidgetPointer(arg0)); + if (ivar1 == -1) { + return; + } + if (setWidgetRegister(new WidgetPointer(ivar1))) { + setWidgetPosition(0, 4, 1, 0); + setWidgetSize(16384, 23, 2, 0); + } + script_4211(arg0, 5419, 15458492, 0); + return; +} diff --git a/dumps/scripts/4533.cs2 b/dumps/scripts/4533.cs2 new file mode 100644 index 0000000..76351bf --- /dev/null +++ b/dumps/scripts/4533.cs2 @@ -0,0 +1,4 @@ +void script_4533(int arg0,string arg1) { + script_4212(arg0, 5419, 15458492, 0, arg1); + return; +} diff --git a/dumps/scripts/4534.cs2 b/dumps/scripts/4534.cs2 new file mode 100644 index 0000000..ad09ac9 --- /dev/null +++ b/dumps/scripts/4534.cs2 @@ -0,0 +1,45 @@ +void script_4534(int arg0) { + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(10, 10, 1, 0); + setWidgetPosition(0, 0, 1, 0); + setWidgetSprite(5474); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(10, 10, 1, 0); + setWidgetPosition(0, 0, 1, 2); + setWidgetSprite(5474); + cs2method1107(1); + setWidgetVFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(10, 10, 0, 1); + setWidgetPosition(0, 0, 0, 1); + setWidgetSprite(5476); + cs2method1107(1); + setWidgetHFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(10, 10, 0, 1); + setWidgetPosition(0, 0, 2, 1); + setWidgetSprite(5476); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(10, 10, 0, 0); + setWidgetPosition(0, 0, 0, 0); + setWidgetSprite(5475); + setWidgetHFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(10, 10, 0, 0); + setWidgetPosition(0, 0, 2, 0); + setWidgetSprite(5475); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(10, 10, 0, 0); + setWidgetPosition(0, 0, 0, 2); + setWidgetSprite(5475); + setWidgetHFlip(1); + setWidgetVFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(10, 10, 0, 0); + setWidgetPosition(0, 0, 2, 2); + setWidgetSprite(5475); + setWidgetVFlip(1); + return; +} diff --git a/dumps/scripts/4535.cs2 b/dumps/scripts/4535.cs2 new file mode 100644 index 0000000..130afa6 --- /dev/null +++ b/dumps/scripts/4535.cs2 @@ -0,0 +1,44 @@ +void script_4535(int arg0) { + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(10, 5, 1, 0); + setWidgetPosition(0, 0, 1, 0); + setWidgetSprite(6143); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(10, 5, 1, 0); + setWidgetPosition(0, 0, 1, 2); + setWidgetSprite(6147); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(5, 10, 0, 1); + setWidgetPosition(0, 0, 0, 1); + setWidgetSprite(6145); + cs2method1107(1); + setWidgetHFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(5, 10, 0, 1); + setWidgetPosition(0, 0, 2, 1); + setWidgetSprite(6145); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(5, 5, 0, 0); + setWidgetPosition(0, 0, 0, 0); + setWidgetSprite(6144); + setWidgetHFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(5, 5, 0, 0); + setWidgetPosition(0, 0, 2, 0); + setWidgetSprite(6144); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(5, 5, 0, 0); + setWidgetPosition(0, 0, 0, 2); + setWidgetSprite(6144); + setWidgetHFlip(1); + setWidgetVFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(5, 5, 0, 0); + setWidgetPosition(0, 0, 2, 2); + setWidgetSprite(6144); + setWidgetVFlip(1); + return; +} diff --git a/dumps/scripts/4536.cs2 b/dumps/scripts/4536.cs2 new file mode 100644 index 0000000..a9e8ba6 --- /dev/null +++ b/dumps/scripts/4536.cs2 @@ -0,0 +1,4 @@ +void script_4536(int arg0) { + script_4537(arg0); + return; +} diff --git a/dumps/scripts/4537.cs2 b/dumps/scripts/4537.cs2 new file mode 100644 index 0000000..e685c57 --- /dev/null +++ b/dumps/scripts/4537.cs2 @@ -0,0 +1,50 @@ +void script_4537(int arg0) { + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(40, 52, 1, 1); + setWidgetPosition(0, 0, 1, 1); + setWidgetSprite(6098); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(40, 26, 1, 0); + setWidgetPosition(0, 0, 1, 0); + setWidgetSprite(6096); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(40, 26, 1, 0); + setWidgetPosition(0, 0, 1, 2); + setWidgetSprite(6096); + cs2method1107(1); + setWidgetVFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(10, 52, 0, 1); + setWidgetPosition(0, 0, 0, 1); + setWidgetSprite(6097); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(10, 52, 0, 1); + setWidgetPosition(0, 0, 2, 1); + setWidgetSprite(6097); + cs2method1107(1); + setWidgetHFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(20, 26, 0, 0); + setWidgetPosition(0, 0, 0, 0); + setWidgetSprite(6095); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(20, 26, 0, 0); + setWidgetPosition(0, 0, 2, 0); + setWidgetSprite(6095); + setWidgetHFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(20, 26, 0, 0); + setWidgetPosition(0, 0, 0, 2); + setWidgetSprite(6095); + setWidgetVFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(20, 26, 0, 0); + setWidgetPosition(0, 0, 2, 2); + setWidgetSprite(6095); + setWidgetVFlip(1); + setWidgetHFlip(1); + return; +} diff --git a/dumps/scripts/4538.cs2 b/dumps/scripts/4538.cs2 new file mode 100644 index 0000000..c216ced --- /dev/null +++ b/dumps/scripts/4538.cs2 @@ -0,0 +1,4 @@ +void script_4538(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,string arg12) { + script_4539(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); + return; +} diff --git a/dumps/scripts/4539.cs2 b/dumps/scripts/4539.cs2 new file mode 100644 index 0000000..6c7e1dc --- /dev/null +++ b/dumps/scripts/4539.cs2 @@ -0,0 +1,65 @@ +void script_4539(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,string arg12) { + int ivar12; + int ivar13; + flow_0: + if (((boolean)script_4761(25))) { + return; + } + ivar12 = 0; + ivar13 = 0; + IF (setWidgetRegister(new WidgetPointer(arg0), subtract(getExtraChildGap(new WidgetPointer(arg0)), 1))) + GOTO flow_3 + GOTO flow_18 + flow_3: + IF (setWidgetRegister(new WidgetPointer(arg1), arg2)) + GOTO flow_5 + IF (((arg2 == -1) && setWidgetRegister(new WidgetPointer(arg1))) && (getWidgetSpriteId() == 5613)) + GOTO flow_6 + GOTO flow_18 + flow_5: + flow_6: + switch (arg9) { + case 3: + if (((boolean)getWidgetModelId())) { + ivar13 = getWidgetActualHeight(new WidgetPointer(arg0)); + ivar12 = subtract(add(script_1744(), arg11), add(script_3366(arg0), divide(ivar13, 2))); + ivar13 = divide(subtract(ivar13, 35), 2); + ivar12 = max(min(ivar12, ivar13), subtract(0, ivar13)); + setWidgetPosition(0, ivar12, 2, 1); + return; + } + break; + case 1: + if (getWidgetModelId() == 32768) { + ivar13 = getWidgetActualHeight(new WidgetPointer(arg0)); + ivar12 = subtract(add(script_1744(), arg11), add(script_3366(arg0), divide(ivar13, 2))); + ivar13 = divide(subtract(ivar13, 35), 2); + ivar12 = max(min(ivar12, ivar13), subtract(0, ivar13)); + setWidgetPosition(0, ivar12, 0, 1); + return; + } + break; + case 0: + if (getWidgetModelId() == 49152) { + ivar13 = getWidgetActualWidth(new WidgetPointer(arg0)); + ivar12 = subtract(add(script_1743(), arg10), add(script_3365(arg0), divide(ivar13, 2))); + ivar13 = divide(subtract(ivar13, 35), 2); + ivar12 = max(min(ivar12, ivar13), subtract(0, ivar13)); + setWidgetPosition(ivar12, 0, 1, 2); + return; + } + break; + default: + if (getWidgetModelId() == 16384) { + ivar13 = getWidgetActualWidth(new WidgetPointer(arg0)); + ivar12 = subtract(add(script_1743(), arg10), add(script_3365(arg0), divide(ivar13, 2))); + ivar13 = divide(subtract(ivar13, 35), 2); + ivar12 = max(min(ivar12, ivar13), subtract(0, ivar13)); + setWidgetPosition(ivar12, 0, 1, 0); + return; + } + } + flow_18: + script_4540(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); + return; +} diff --git a/dumps/scripts/454.cs2 b/dumps/scripts/454.cs2 new file mode 100644 index 0000000..736a406 --- /dev/null +++ b/dumps/scripts/454.cs2 @@ -0,0 +1,4 @@ +void script_454() { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(1008,32)); + return; +} diff --git a/dumps/scripts/4540.cs2 b/dumps/scripts/4540.cs2 new file mode 100644 index 0000000..7bc4031 --- /dev/null +++ b/dumps/scripts/4540.cs2 @@ -0,0 +1,397 @@ +void script_4540(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,string arg12) { + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + int ivar22; + int ivar23; + int ivar24; + int ivar25; + int ivar26; + int ivar27; + int stack_dump0; + int stack_dump1; + int stack_dump2; + flow_0: + setWidgetIsHidden(false, new WidgetPointer(arg0)); + deleteAllExtraChilds(new WidgetPointer(arg0)); + if ((arg4 == -1) || (arg5 == -1)) { + stack_dump0 = 5631; + arg5 = 5631; + arg4 = stack_dump0; + } + if (arg6 == -1) { + arg6 = 16777215; + } + ivar12 = min(getMaxLineWidth(arg3, arg4, arg12), arg3); + ivar13 = add(multiply(max(getLineCount(ivar12, arg4, arg12), 1), arg7), arg8); + ivar14 = add(ivar12, 12); + ivar15 = add(ivar13, 12); + switch (arg9) { + case 1: + case 3: + ivar14 = add(ivar14, 23); + break; + case 0: + ivar15 = add(ivar15, 22); + break; + case 2: + ivar15 = add(ivar15, 23); + } + stack_dump0 = max(ivar14, 45); + ivar15 = max(ivar15, 45); + ivar14 = stack_dump0; + setWidgetSize(ivar14, ivar15, 0, 0, new WidgetPointer(arg0)); + createExtraChild(new WidgetPointer(arg0), 3, getExtraChildGap(new WidgetPointer(arg0))); + switch (arg9) { + case 3: + setWidgetSize(25, 2, 1, 1); + setWidgetPosition(1, 0, 0, 1); + break; + case 1: + setWidgetSize(25, 2, 1, 1); + setWidgetPosition(1, 0, 2, 1); + break; + case 0: + setWidgetSize(2, 24, 1, 1); + setWidgetPosition(0, 1, 1, 0); + break; + case 2: + setWidgetSize(2, 25, 1, 1); + setWidgetPosition(0, 1, 1, 2); + break; + default: + setWidgetSize(2, 2, 1, 1); + setWidgetPosition(0, 0, 1, 1); + } + setWidgetRGB(new Color(0, 0, 0)); + setWidgetFilled(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + SWITCH (arg9) { + case 3: + GOTO flow_15 + case 1: + GOTO flow_16 + case 2: + GOTO flow_18 + } + GOTO flow_17 + flow_15: + setWidgetSize(27, 10, 1, 0); + setWidgetPosition(2, 0, 0, 0); + GOTO flow_19 + flow_16: + setWidgetSize(27, 10, 1, 0); + setWidgetPosition(2, 0, 2, 0); + GOTO flow_19 + flow_17: + setWidgetSize(4, 10, 1, 0); + setWidgetPosition(0, 0, 1, 0); + GOTO flow_19 + flow_18: + setWidgetSize(4, 10, 1, 0); + setWidgetPosition(0, 23, 1, 0); + flow_19: + setWidgetSprite(4649); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + switch (arg9) { + case 3: + setWidgetSize(27, 10, 1, 0); + setWidgetPosition(2, 0, 0, 2); + break; + case 1: + setWidgetSize(27, 10, 1, 0); + setWidgetPosition(2, 0, 2, 2); + break; + case 0: + setWidgetSize(4, 10, 1, 0); + setWidgetPosition(0, 22, 1, 2); + break; + default: + setWidgetSize(4, 10, 1, 0); + setWidgetPosition(0, 0, 1, 2); + } + setWidgetSprite(4649); + cs2method1107(1); + setWidgetVFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + SWITCH (arg9) { + case 1: + GOTO flow_25 + case 0: + GOTO flow_26 + case 2: + GOTO flow_27 + } + setWidgetSize(10, 4, 0, 1); + setWidgetPosition(0, 0, 0, 1); + GOTO flow_28 + flow_25: + setWidgetSize(10, 4, 0, 1); + setWidgetPosition(23, 0, 0, 1); + GOTO flow_28 + flow_26: + setWidgetSize(10, 26, 0, 1); + setWidgetPosition(0, 2, 0, 0); + GOTO flow_28 + flow_27: + setWidgetSize(10, 27, 0, 1); + setWidgetPosition(0, 2, 0, 2); + flow_28: + setWidgetSprite(4651); + cs2method1107(1); + setWidgetHFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + SWITCH (arg9) { + case 3: + GOTO flow_29 + case 0: + GOTO flow_31 + case 2: + GOTO flow_32 + } + GOTO flow_30 + flow_29: + setWidgetSize(10, 4, 0, 1); + setWidgetPosition(23, 0, 2, 1); + GOTO flow_33 + flow_30: + setWidgetSize(10, 4, 0, 1); + setWidgetPosition(0, 0, 2, 1); + GOTO flow_33 + flow_31: + setWidgetSize(10, 26, 0, 1); + setWidgetPosition(0, 2, 2, 0); + GOTO flow_33 + flow_32: + setWidgetSize(10, 27, 0, 1); + setWidgetPosition(0, 2, 2, 2); + flow_33: + setWidgetSprite(4651); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(10, 10, 0, 0); + SWITCH (arg9) { + case 1: + GOTO flow_34 + case 2: + GOTO flow_36 + } + GOTO flow_35 + flow_34: + setWidgetPosition(23, 0, 0, 0); + GOTO flow_37 + flow_35: + setWidgetPosition(0, 0, 0, 0); + GOTO flow_37 + flow_36: + setWidgetPosition(0, 23, 0, 0); + flow_37: + setWidgetSprite(4650); + setWidgetHFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(10, 10, 0, 0); + SWITCH (arg9) { + case 3: + GOTO flow_38 + case 2: + GOTO flow_40 + } + GOTO flow_39 + flow_38: + setWidgetPosition(23, 0, 2, 0); + GOTO flow_41 + flow_39: + setWidgetPosition(0, 0, 2, 0); + GOTO flow_41 + flow_40: + setWidgetPosition(0, 23, 2, 0); + flow_41: + setWidgetSprite(4650); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(10, 10, 0, 0); + switch (arg9) { + case 1: + setWidgetPosition(23, 0, 0, 2); + break; + case 0: + setWidgetPosition(0, 22, 0, 2); + break; + default: + setWidgetPosition(0, 0, 0, 2); + } + setWidgetSprite(4650); + setWidgetHFlip(1); + setWidgetVFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(10, 10, 0, 0); + switch (arg9) { + case 3: + setWidgetPosition(23, 0, 2, 2); + break; + case 0: + setWidgetPosition(0, 22, 2, 2); + break; + default: + setWidgetPosition(0, 0, 2, 2); + } + setWidgetSprite(4650); + setWidgetVFlip(1); + createExtraChild(new WidgetPointer(arg0), 4, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(ivar12, ivar13, 0, 0); + switch (arg9) { + case 3: + setWidgetPosition(6, 0, 0, 1); + break; + case 1: + setWidgetPosition(6, 0, 2, 1); + break; + case 0: + setWidgetPosition(0, 6, 1, 0); + break; + case 2: + setWidgetPosition(0, 6, 1, 2); + break; + default: + setWidgetPosition(0, 0, 1, 1); + } + setWidgetRGB(new Color(arg6)); + setWidgetFont(arg5); + setWidgetTextAlignment(1, 1, arg7); + setWidgetText(arg12); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSprite(5613); + ivar16 = 0; + ivar17 = 0; + ivar18 = 0; + ivar19 = 0; + ivar20 = getWidgetParentId(new WidgetPointer(arg0)); + if (ivar20 != -1) { + stack_dump0 = script_3365(ivar20); + ivar18 = script_3366(ivar20); + ivar16 = stack_dump0; + stack_dump0 = add(ivar16, getWidgetActualWidth(new WidgetPointer(ivar20))); + ivar19 = add(ivar18, getWidgetActualHeight(new WidgetPointer(ivar20))); + ivar17 = stack_dump0; + } else if (ivar20 != -1) { + stack_dump0 = getWidgetActualWidth(new WidgetPointer(ivar20)); + ivar19 = getWidgetActualHeight(new WidgetPointer(ivar20)); + ivar17 = stack_dump0; + } else { + stack_dump0 = 765; + ivar19 = 503; + ivar17 = stack_dump0; + } + ivar21 = 0; + ivar22 = 0; + ivar23 = 0; + ivar24 = 0; + ivar25 = 0; + ivar26 = 0; + ivar27 = 0; + if (setWidgetRegister(new WidgetPointer(arg1), arg2) || ((arg2 == -1) && setWidgetRegister(new WidgetPointer(arg1)))) { + stack_dump0 = script_1743(); + stack_dump1 = script_1744(); + stack_dump2 = getWidgetActualWidth(); + ivar24 = getWidgetActualHeight(); + stack_dump0 = stack_dump0; + stack_dump1 = stack_dump1; + ivar23 = stack_dump2; + stack_dump0 = stack_dump0; + ivar22 = stack_dump1; + ivar21 = stack_dump0; + switch (arg9) { + case 3: + stack_dump0 = subtract(ivar21, ivar14); + ivar26 = subtract(add(ivar22, arg11), divide(ivar15, 2)); + ivar25 = stack_dump0; + if (ivar26 < ivar18) { + ivar27 = subtract(ivar26, ivar18); + ivar26 = subtract(ivar26, ivar27); + ivar27 = max(ivar27, subtract(0, divide(subtract(ivar15, 35), 2))); + } else { + if (add(ivar26, ivar15) > ivar19) { + ivar27 = subtract(add(ivar26, ivar15), ivar19); + ivar26 = subtract(ivar26, ivar27); + ivar27 = min(ivar27, divide(subtract(ivar15, 35), 2)); + } + } + setWidgetSize(25, 24, 0, 0); + setWidgetPosition(0, ivar27, 2, 1); + break; + case 1: + stack_dump0 = add(ivar21, ivar23); + ivar26 = subtract(add(ivar22, arg11), divide(ivar15, 2)); + ivar25 = stack_dump0; + if (ivar26 < ivar18) { + ivar27 = subtract(ivar26, ivar18); + ivar26 = subtract(ivar26, ivar27); + ivar27 = max(ivar27, subtract(0, divide(subtract(ivar15, 35), 2))); + } else { + if (add(ivar26, ivar15) > ivar19) { + ivar27 = subtract(add(ivar26, ivar15), ivar19); + ivar26 = subtract(ivar26, ivar27); + ivar27 = min(ivar27, divide(subtract(ivar15, 35), 2)); + } + } + setWidgetSize(25, 24, 0, 0); + cs2method1106(32768); + setWidgetPosition(0, ivar27, 0, 1); + break; + case 0: + stack_dump0 = subtract(add(ivar21, arg10), divide(ivar14, 2)); + ivar26 = subtract(ivar22, ivar15); + ivar25 = stack_dump0; + if (ivar25 < ivar16) { + ivar27 = subtract(ivar25, ivar16); + ivar25 = subtract(ivar25, ivar27); + ivar27 = max(ivar27, subtract(0, divide(subtract(ivar14, 35), 2))); + } else { + if (add(ivar25, ivar14) > ivar17) { + ivar27 = subtract(add(ivar25, ivar14), ivar17); + ivar25 = subtract(ivar25, ivar27); + ivar27 = min(ivar27, divide(subtract(ivar14, 35), 2)); + } + } + setWidgetSize(24, 25, 0, 0); + cs2method1106(49152); + setWidgetPosition(ivar27, 0, 1, 2); + break; + case 2: + stack_dump0 = subtract(add(ivar21, arg10), divide(ivar14, 2)); + ivar26 = add(ivar22, ivar24); + ivar25 = stack_dump0; + if (ivar25 < ivar16) { + ivar27 = subtract(ivar25, ivar16); + ivar25 = subtract(ivar25, ivar27); + ivar27 = max(ivar27, subtract(0, divide(subtract(ivar14, 35), 2))); + } else { + if (add(ivar25, ivar14) > ivar17) { + ivar27 = subtract(add(ivar25, ivar14), ivar17); + ivar25 = subtract(ivar25, ivar27); + ivar27 = min(ivar27, divide(subtract(ivar14, 35), 2)); + } + } + setWidgetSize(24, 25, 0, 0); + cs2method1106(16384); + setWidgetPosition(ivar27, 0, 1, 0); + break; + default: + setWidgetHidden(1); + stack_dump0 = subtract(arg10, divide(ivar14, 2)); + ivar26 = subtract(arg11, divide(ivar15, 2)); + ivar25 = stack_dump0; + } + } else { + setWidgetIsHidden(true, new WidgetPointer(arg0)); + } + setWidgetPosition(subtract(ivar25, ivar16), subtract(ivar26, ivar18), 0, 0, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/4541.cs2 b/dumps/scripts/4541.cs2 new file mode 100644 index 0000000..15aac61 --- /dev/null +++ b/dumps/scripts/4541.cs2 @@ -0,0 +1,4 @@ +void script_4541(int arg0,int arg1,int arg2) { + script_4542(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/4542.cs2 b/dumps/scripts/4542.cs2 new file mode 100644 index 0000000..dce46ef --- /dev/null +++ b/dumps/scripts/4542.cs2 @@ -0,0 +1,12 @@ +void script_4542(int arg0,int arg1,int arg2) { + int ivar3; + arg0 = min(100, arg0); + arg0 = max(0, arg0); + if (arg1 == -1) { + return; + } + ivar3 = divide(multiply(arg0, 16384), 100); + setWidgetSize(ivar3, getWidgetActualHeight(new WidgetPointer(arg1)), 2, 0, new WidgetPointer(arg1)); + script_4212(arg2, 3793, 14014931, 0, intToStr(arg0) + "%"); + return; +} diff --git a/dumps/scripts/4543.cs2 b/dumps/scripts/4543.cs2 new file mode 100644 index 0000000..25f3588 --- /dev/null +++ b/dumps/scripts/4543.cs2 @@ -0,0 +1,4 @@ +void script_4543(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7) { + script_4544(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + return; +} diff --git a/dumps/scripts/4544.cs2 b/dumps/scripts/4544.cs2 new file mode 100644 index 0000000..61c9711 --- /dev/null +++ b/dumps/scripts/4544.cs2 @@ -0,0 +1,27 @@ +void script_4544(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7) { + int ivar8; + ivar8 = getWidgetParentId(new WidgetPointer(arg0)); + if (ivar8 == -1) { + return; + } + if (((boolean)arg6) || ((boolean)arg6)) { + if (getWidgetActualWidth(new WidgetPointer(ivar8)) == arg4) { + setScriptCallOnGameloop(4545, new WidgetPointer(-32768,3), arg5, arg6, new WidgetPointer(arg1), arg2, arg7, "IiiIdi", new WidgetPointer(ivar8)); + } else { + if (getWidgetActualWidth(new WidgetPointer(ivar8)) == arg5) { + setScriptCallOnGameloop(4546, new WidgetPointer(-32768,3), arg4, arg6, new WidgetPointer(arg1), arg3, arg7, "IiiIdi", new WidgetPointer(ivar8)); + } + } + } else { + if ((arg6 == 2) || (arg6 == 3)) { + if (getWidgetActualHeight(new WidgetPointer(ivar8)) == arg4) { + setScriptCallOnGameloop(4545, new WidgetPointer(-32768,3), arg5, arg6, new WidgetPointer(arg1), arg2, arg7, "IiiIdi", new WidgetPointer(ivar8)); + } else { + if (getWidgetActualHeight(new WidgetPointer(ivar8)) == arg5) { + setScriptCallOnGameloop(4546, new WidgetPointer(-32768,3), arg4, arg6, new WidgetPointer(arg1), arg3, arg7, "IiiIdi", new WidgetPointer(ivar8)); + } + } + } + } + return; +} diff --git a/dumps/scripts/4545.cs2 b/dumps/scripts/4545.cs2 new file mode 100644 index 0000000..f079e38 --- /dev/null +++ b/dumps/scripts/4545.cs2 @@ -0,0 +1,41 @@ +void script_4545(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + flow_0: + IF (((boolean)arg2)) + GOTO flow_1 + IF (((boolean)arg2) && (add(getWidgetActualWidth(new WidgetPointer(arg0)), arg5) >= arg1)) + GOTO flow_2 + GOTO flow_5 + flow_1: + flow_2: + setWidgetSize(arg1, getWidgetActualHeight(new WidgetPointer(arg0)), 0, 0, new WidgetPointer(arg0)); + if (arg4 != -1) { + setWidgetSprite(arg4, new WidgetPointer(arg3)); + } + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + return; + flow_5: + IF (arg2 == 2) + GOTO flow_6 + IF ((arg2 == 3) && (add(getWidgetActualHeight(new WidgetPointer(arg0)), arg5) >= arg1)) + GOTO flow_7 + GOTO flow_10 + flow_6: + flow_7: + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg0)), arg1, 0, 0, new WidgetPointer(arg0)); + if (arg4 != -1) { + setWidgetSprite(arg4, new WidgetPointer(arg3)); + } + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + return; + flow_10: + switch (arg2) { + case 0: + case 1: + setWidgetSize(add(getWidgetActualWidth(new WidgetPointer(arg0)), arg5), getWidgetActualHeight(new WidgetPointer(arg0)), 0, 0, new WidgetPointer(arg0)); + break; + case 2: + case 3: + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg0)), add(getWidgetActualHeight(new WidgetPointer(arg0)), arg5), 0, 0, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/4546.cs2 b/dumps/scripts/4546.cs2 new file mode 100644 index 0000000..508b6ab --- /dev/null +++ b/dumps/scripts/4546.cs2 @@ -0,0 +1,41 @@ +void script_4546(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + flow_0: + IF (((boolean)arg2)) + GOTO flow_1 + IF (((boolean)arg2) && (add(getWidgetActualWidth(new WidgetPointer(arg0)), arg5) <= arg1)) + GOTO flow_2 + GOTO flow_5 + flow_1: + flow_2: + setWidgetSize(arg1, getWidgetActualHeight(new WidgetPointer(arg0)), 0, 0, new WidgetPointer(arg0)); + if (arg4 != -1) { + setWidgetSprite(arg4, new WidgetPointer(arg3)); + } + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + return; + flow_5: + IF (arg2 == 2) + GOTO flow_6 + IF ((arg2 == 3) && (add(getWidgetActualHeight(new WidgetPointer(arg0)), arg5) <= arg1)) + GOTO flow_7 + GOTO flow_10 + flow_6: + flow_7: + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg0)), arg1, 0, 0, new WidgetPointer(arg0)); + if (arg4 != -1) { + setWidgetSprite(arg4, new WidgetPointer(arg3)); + } + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + return; + flow_10: + switch (arg2) { + case 0: + case 1: + setWidgetSize(subtract(getWidgetActualWidth(new WidgetPointer(arg0)), arg5), getWidgetActualHeight(new WidgetPointer(arg0)), 0, 0, new WidgetPointer(arg0)); + break; + case 2: + case 3: + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg0)), subtract(getWidgetActualHeight(new WidgetPointer(arg0)), arg5), 0, 0, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/4547.cs2 b/dumps/scripts/4547.cs2 new file mode 100644 index 0000000..3e3bdc7 --- /dev/null +++ b/dumps/scripts/4547.cs2 @@ -0,0 +1,13 @@ +void script_4547(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + deleteAllExtraChilds(new WidgetPointer(arg0)); + deleteAllExtraChilds(new WidgetPointer(arg1)); + deleteAllExtraChilds(new WidgetPointer(arg2)); + deleteAllExtraChilds(new WidgetPointer(arg3)); + setWidgetIsHidden(false, new WidgetPointer(912,39)); + setWidgetText(new WidgetPointer(912,17), "Not in chat"); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(912,38)), getWidgetActualHeight(new WidgetPointer(912,37)), 0, 0, new WidgetPointer(912,38)); + setWidgetScrollMax(0, 0, new WidgetPointer(912,45)); + cs2method2100(0, 0, new WidgetPointer(912,45)); + script_72(59768878, 59768877, 0); + return; +} diff --git a/dumps/scripts/4548.cs2 b/dumps/scripts/4548.cs2 new file mode 100644 index 0000000..7fc1b51 --- /dev/null +++ b/dumps/scripts/4548.cs2 @@ -0,0 +1,12 @@ +void script_4548() { + int ivar0; + int ivar1; + ivar0 = 0; + ivar1 = 0; + if (((boolean)script_4467())) { + setWidgetIsHidden(false, new WidgetPointer(912,44)); + return; + } + script_2447(); + return; +} diff --git a/dumps/scripts/4549.cs2 b/dumps/scripts/4549.cs2 new file mode 100644 index 0000000..16dac43 --- /dev/null +++ b/dumps/scripts/4549.cs2 @@ -0,0 +1,43 @@ +void script_4549() { + int ivar0; + int ivar1; + int ivar2; + ivar0 = -1; + ivar1 = -1; + ivar2 = -1; + if (cs2method3751()) { + ivar0 = cs2method3760(cs2method5015()); + if (ivar0 == -1) { + return; + } + ivar1 = cs2method3757(ivar0); + ivar2 = cs2method3753(); + } else { + messageType0("You must be in a clan to do that."); + } + if (ivar1 >= 0) { + if (ivar1 < ivar2) { + return; + } + if (((boolean)globalint_1413)) { + return; + } + if (((boolean)globalint_11)) { + script_675(); + } + if (getDisplayMode() >= 2) { + setWidgetIsHidden(false, new WidgetPointer(746,73)); + } + setWidgetIsHidden(false, new WidgetPointer(752,3)); + setWidgetIsHidden(true, new WidgetPointer(752,7)); + setWidgetIsHidden(true, new WidgetPointer(752,8)); + setWidgetText(new WidgetPointer(752,4), "Enter the player to ban from the channel:"); + globalint_5 = 16; + script_1564(""); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(752,3)); + script_2026(); + setScriptCallOnKeyPress(112, -2147483640, false, "iz", new WidgetPointer(752,5)); + script_1188(); + } + return; +} diff --git a/dumps/scripts/455.cs2 b/dumps/scripts/455.cs2 new file mode 100644 index 0000000..c819a74 --- /dev/null +++ b/dumps/scripts/455.cs2 @@ -0,0 +1,4 @@ +void script_455() { + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(1008,32)); + return; +} diff --git a/dumps/scripts/4550.cs2 b/dumps/scripts/4550.cs2 new file mode 100644 index 0000000..97fe66f --- /dev/null +++ b/dumps/scripts/4550.cs2 @@ -0,0 +1,6 @@ +int script_4550(int arg0) { + if ((isParent(new WidgetPointer(753,4), arg0) || isParent(new WidgetPointer(746,12), arg0)) || isParent(new WidgetPointer(548,19), arg0)) { + return 1; + } + return 0; +} diff --git a/dumps/scripts/4551.cs2 b/dumps/scripts/4551.cs2 new file mode 100644 index 0000000..60e48ff --- /dev/null +++ b/dumps/scripts/4551.cs2 @@ -0,0 +1,8 @@ +void script_4551() { + setScriptCallOnFriendListChange(128, "", new WidgetPointer(550,4)); + script_31(36044831, 36044803, 5666, 5663, 5664, 5665, 5686, 5685); + setWidgetScrollMax(0, 0, new WidgetPointer(550,3)); + cs2method2100(0, 0, new WidgetPointer(550,3)); + script_129(); + return; +} diff --git a/dumps/scripts/4552.cs2 b/dumps/scripts/4552.cs2 new file mode 100644 index 0000000..22a24b1 --- /dev/null +++ b/dumps/scripts/4552.cs2 @@ -0,0 +1,28 @@ +void script_4552() { + int ivar0; + int ivar1; + int ivar2; + setWidgetText(new WidgetPointer(550,19), "Friends List" + "
" + "RuneScape " + intToStr(getWorldId())); + setScriptCallOnFriendListChange(124, "", new WidgetPointer(550,6)); + setWidgetScrollMax(0, 0, new WidgetPointer(550,11)); + cs2method2100(0, 0, new WidgetPointer(550,11)); + script_31(36044812, 36044811, 5666, 5663, 5664, 5665, 5686, 5685); + ivar0 = 36044800; + deleteAllExtraChilds(new WidgetPointer(ivar0)); + ivar1 = 0; + ivar2 = 0; + while (ivar2 < 200) { + ivar1 = add(multiply(ivar2, 15), 5); + if (mod(ivar2, 2) != 0) { + createExtraChild(new WidgetPointer(ivar0), 3, getExtraChildGap(new WidgetPointer(ivar0))); + setWidgetSize(16384, 15, 2, 0); + setWidgetPosition(0, ivar1, 0, 0); + setWidgetRGB(new Color(35, 34, 32)); + setWidgetFilled(1); + cs2method2103(128); + } + ivar2 = add(ivar2, 1); + } + script_125(globalint_1036); + return; +} diff --git a/dumps/scripts/4553.cs2 b/dumps/scripts/4553.cs2 new file mode 100644 index 0000000..647d3c5 --- /dev/null +++ b/dumps/scripts/4553.cs2 @@ -0,0 +1,16 @@ +void script_4553(int arg0) { + if (((boolean)arg0)) { + setWidgetIsHidden(true, new WidgetPointer(550,9)); + setWidgetIsHidden(false, new WidgetPointer(550,30)); + setWidgetIsHidden(true, new WidgetPointer(550,48)); + setWidgetIsHidden(false, new WidgetPointer(550,50)); + script_4551(); + } else { + setWidgetIsHidden(true, new WidgetPointer(550,30)); + setWidgetIsHidden(false, new WidgetPointer(550,9)); + setWidgetIsHidden(true, new WidgetPointer(550,50)); + setWidgetIsHidden(false, new WidgetPointer(550,48)); + script_4552(); + } + return; +} diff --git a/dumps/scripts/4554.cs2 b/dumps/scripts/4554.cs2 new file mode 100644 index 0000000..400cfb6 --- /dev/null +++ b/dumps/scripts/4554.cs2 @@ -0,0 +1,27 @@ +void script_4554(int arg0) { + setWidgetSize(subtract(getWidgetActualX(new WidgetPointer(589,45)), getWidgetActualX(new WidgetPointer(589,43))), 0, 0, 1, new WidgetPointer(589,55)); + setWidgetSize(subtract(subtract(getWidgetActualWidth(new WidgetPointer(589,51)), getWidgetActualWidth(new WidgetPointer(589,55))), 2), 0, 0, 1, new WidgetPointer(589,57)); + setWidgetScrollMax(0, 0, new WidgetPointer(589,51)); + cs2method2100(0, 0, new WidgetPointer(589,51)); + script_31(38600756, 38600755, 792, 789, 790, 791, 773, 788); + setWidgetScrollMax(0, 0, new WidgetPointer(589,23)); + cs2method2100(0, 0, new WidgetPointer(589,23)); + script_31(38600728, 38600727, 792, 789, 790, 791, 773, 788); + setScriptCallOnClanListChange(4558, new WidgetPointer(589,55), new WidgetPointer(589,56), new WidgetPointer(589,57), new WidgetPointer(589,53), new WidgetPointer(589,51), new WidgetPointer(589,52), "IIIIII", new WidgetPointer(589,51)); + setScriptCallOnFriendListChange(4558, new WidgetPointer(589,55), new WidgetPointer(589,56), new WidgetPointer(589,57), new WidgetPointer(589,53), new WidgetPointer(589,51), new WidgetPointer(589,52), "IIIIII", new WidgetPointer(589,51)); + script_4559(38600759, 38600760, 38600761, 38600757, 38600755, 38600756); + if (cs2method3612() > 0) { + setWidgetText(new WidgetPointer(589,41), "Leave chat channel"); + setWidgetContextMenuOption(1, new WidgetPointer(589,39), "Leave chat channel"); + } else { + setWidgetText(new WidgetPointer(589,41), "Join chat channel"); + setWidgetContextMenuOption(1, new WidgetPointer(589,39), "Join chat channel"); + } + globalstring_349 = ""; + script_3024(38600735); + globalint_1507 = strLength(globalstring_349); + setScriptCallOnMousePressed(4570, -2147483647, new WidgetPointer(589,27), new WidgetPointer(589,28), "iII", new WidgetPointer(589,27)); + script_4571(38600731, 38600732, globalstring_349); + setWidgetIsHidden(true, new WidgetPointer(589,28)); + return; +} diff --git a/dumps/scripts/4555.cs2 b/dumps/scripts/4555.cs2 new file mode 100644 index 0000000..8a61ac7 --- /dev/null +++ b/dumps/scripts/4555.cs2 @@ -0,0 +1,53 @@ +void script_4555(int arg0,int arg1) { + int stack_dump0; + int stack_dump1; + int stack_dump2; + int stack_dump3; + string stack_dump4; + cs2func_script_802_struct(1,1,0) structdump_5; + if (((cs2method3612() <= 0) || cs2method6900()) || ((boolean)script_5280())) { + return; + } + switch (arg0) { + case 84: + if (cs2method3612() > 0) { + if (strLength(globalstring_349) > 0) { + cs2method5006(1); + cs2method5008(globalstring_349); + } + } else { + message(11, 0, "You are not in a Friends Chat Channel."); + } + globalstring_349 = ""; + setWidgetText(new WidgetPointer(589,27), replaceLtGt(globalstring_349)); + globalint_1507 = strLength(globalstring_349); + script_4571(38600731, 38600732, globalstring_349); + break; + case 102: + case 103: + case 98: + case 99: + case 96: + case 97: + globalint_1507 = script_1553(arg0, globalint_1507, globalstring_349); + script_4571(38600731, 38600732, globalstring_349); + break; + case 85: + case 101: + case -1: + if ((isValidChar(((char)arg1)) || (arg0 == 85)) || (arg0 == 101)) { + stack_dump0 = globalint_1507; + stack_dump1 = 0; + stack_dump2 = arg0; + stack_dump3 = arg1; + stack_dump4 = globalstring_349; + structdump_5 = script_802(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + stack_dump4 = structdump_5.stringpart_0; + globalint_1507 = structdump_5.intpart_0; + globalstring_349 = stack_dump4; + setWidgetText(new WidgetPointer(589,27), replaceLtGt(globalstring_349)); + script_4571(38600731, 38600732, globalstring_349); + } + } + return; +} diff --git a/dumps/scripts/4556.cs2 b/dumps/scripts/4556.cs2 new file mode 100644 index 0000000..307f9d9 --- /dev/null +++ b/dumps/scripts/4556.cs2 @@ -0,0 +1,11 @@ +void script_4556(int arg0) { + if (((boolean)arg0) && cs2method6900()) { + setScriptCallOnKeyPress(4555, -2147483640, false, "iz", new WidgetPointer(589,26)); + setScriptCallOnGameloop(4572, getClientCycle(), new WidgetPointer(589,28), "iI", new WidgetPointer(589,27)); + } else { + setScriptCallOnKeyPress(-1, "", new WidgetPointer(589,26)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(589,27)); + setWidgetText(new WidgetPointer(589,27), replaceLtGt(globalstring_349)); + } + return; +} diff --git a/dumps/scripts/4557.cs2 b/dumps/scripts/4557.cs2 new file mode 100644 index 0000000..b1a0205 --- /dev/null +++ b/dumps/scripts/4557.cs2 @@ -0,0 +1,8 @@ +void script_4557() { + if (cs2method3612() > 0) { + sendUnknownVarByteEmptyFriendPacketMethod3620(); + } else { + script_3015(5, "Join Chat Channel", "", "", ""); + } + return; +} diff --git a/dumps/scripts/4558.cs2 b/dumps/scripts/4558.cs2 new file mode 100644 index 0000000..60f1c35 --- /dev/null +++ b/dumps/scripts/4558.cs2 @@ -0,0 +1,4 @@ +void script_4558(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + script_4559(arg0, arg1, arg2, arg3, arg4, arg5); + return; +} diff --git a/dumps/scripts/4559.cs2 b/dumps/scripts/4559.cs2 new file mode 100644 index 0000000..b247e3d --- /dev/null +++ b/dumps/scripts/4559.cs2 @@ -0,0 +1,135 @@ +void script_4559(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + string svar0; + string svar1; + string svar2; + if (cs2method5428(arg3, -1)) { + setScriptCallOnGameloop(4558, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), "IIIIII", new WidgetPointer(arg4)); + return; + } + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg4)); + deleteAllExtraChilds(new WidgetPointer(arg0)); + deleteAllExtraChilds(new WidgetPointer(arg1)); + deleteAllExtraChilds(new WidgetPointer(arg2)); + deleteAllExtraChilds(new WidgetPointer(arg3)); + ivar6 = 0; + ivar7 = cs2method3612(); + ivar8 = 0; + svar0 = ""; + ivar9 = 15; + ivar10 = 17; + ivar11 = 0; + ivar12 = 0; + ivar13 = 0; + ivar14 = 0; + ivar15 = 0; + ivar16 = 0; + svar1 = ""; + svar2 = ""; + ivar17 = 0; + if (ivar7 <= 0) { + setWidgetText(new WidgetPointer(589,19), "Not in chat"); + setWidgetText(new WidgetPointer(589,20), "None"); + setWidgetText(new WidgetPointer(589,41), "Join Chat Channel"); + setWidgetContextMenuOption(1, new WidgetPointer(589,39), "Join Chat Channel"); + script_4560(arg3, "You are not currently in a Friends Chat channel." + "
" + "
" + "Use the button below if you wish to join a chat channel."); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(589,45)), getWidgetActualHeight(new WidgetPointer(589,44)), 0, 0, new WidgetPointer(589,45)); + setWidgetScrollMax(0, 0, new WidgetPointer(589,51)); + cs2method2100(0, 0, new WidgetPointer(589,51)); + script_72(38600756, 38600755, 0); + } else { + setWidgetText(new WidgetPointer(589,19), cs2method3611()); + setWidgetText(new WidgetPointer(589,20), cs2method3625()); + setWidgetText(new WidgetPointer(589,41), "Leave chat channel"); + setWidgetContextMenuOption(1, new WidgetPointer(589,39), "Leave chat channel"); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(589,45)), 4, 0, 1, new WidgetPointer(589,45)); + while (ivar8 < ivar7) { + ivar16 = cs2method3615(ivar8); + svar2 = cs2method3632(ivar8); + svar0 = cs2method3613(ivar8); + script_2996(arg3, ivar8, getWidgetActualWidth(new WidgetPointer(arg3)), ivar9, 0, ivar12, 0, 1, 0); + if (((boolean)mod(ivar8, 2))) { + setWidgetRGB(new Color(32, 25, 17)); + } else { + setWidgetRGB(new Color(41, 32, 22)); + } + svar1 = "Rank: " + script_196(ivar16); + setScriptCallOnMouseEntered(4561, new WidgetPointer(arg3), ivar8, svar1, "Iis"); + setScriptCallOnMouseExit(4563, new WidgetPointer(arg3), ivar8, "Ii"); + if (cs2method3624(ivar8)) { + setScriptCallOnClickContextMenu(4564, svar2, -2147483644, "si"); + if (isFriend(strRemoveEntities(svar2))) { + setWidgetContextMenuOption(8, "Remove friend " + svar0); + } else if (cs2method3623(strRemoveEntities(svar2))) { + setWidgetContextMenuOption(9, "Remove ignore " + svar0); + } else { + setWidgetContextMenuOption(6, "Add friend " + svar0); + setWidgetContextMenuOption(7, "Add ignore " + svar0); + } + } + if ((cs2method3618() >= cs2method3616()) && (cs2method3618() > ivar16)) { + setWidgetContextMenuOption(10, "Kick/ban " + svar0); + } + script_2994(arg1, ivar8, 9, 9, 5, add(ivar12, 2), script_1599(ivar16), 0, 0, 0, 0); + script_2995(arg0, ivar8, 0, ivar9, ivar10, ivar12, 16777215, 494, 0, 1, 0, 1, svar0); + setWidgetSize(ivar10, ivar9, 1, 0); + cs2method1126(1); + ivar13 = cs2method3614(ivar8); + if (((boolean)ivar13)) { + svar0 = "Offline"; + ivar11 = 16711680; + } else if (ivar13 == getWorldId()) { + ivar11 = 65280; + } else { + ivar11 = 16776960; + } + svar0 = cs2method3626(ivar8); + script_2995(arg2, ivar8, 0, ivar9, 5, ivar12, ivar11, 494, 0, 1, 0, 1, svar0); + setWidgetSize(5, ivar9, 1, 0); + cs2method1126(1); + ivar12 = add(ivar12, ivar9); + ivar8 = add(ivar8, 1); + } + ivar14 = add(divide(getWidgetActualHeight(new WidgetPointer(arg4)), ivar9), 1); + if (ivar14 > ivar7) { + while (ivar8 < ivar14) { + script_2996(arg3, ivar8, getWidgetActualWidth(new WidgetPointer(arg3)), ivar9, 0, ivar12, 0, 1, 0); + if (((boolean)mod(ivar8, 2))) { + setWidgetRGB(new Color(32, 25, 17)); + } else { + setWidgetRGB(new Color(41, 32, 22)); + } + ivar12 = add(ivar12, ivar9); + ivar8 = add(ivar8, 1); + } + ivar15 = getWidgetActualHeight(new WidgetPointer(arg4)); + } else { + ivar15 = ivar12; + } + if (ivar14 <= ivar7) { + ivar17 = cs2method2601(new WidgetPointer(589,51)); + setWidgetScrollMax(0, ivar15, new WidgetPointer(589,51)); + if (ivar17 > ivar15) { + ivar17 = ivar15; + } + script_72(38600756, 38600755, ivar17); + } else { + setWidgetScrollMax(0, 0, new WidgetPointer(589,51)); + cs2method2100(0, 0, new WidgetPointer(589,51)); + script_72(38600756, 38600755, 0); + } + } + script_4573(); + return; +} diff --git a/dumps/scripts/456.cs2 b/dumps/scripts/456.cs2 new file mode 100644 index 0000000..a448b2a --- /dev/null +++ b/dumps/scripts/456.cs2 @@ -0,0 +1,4 @@ +void script_456() { + setWidgetContextMenuOption(1, new WidgetPointer(1019,16), "Exit Tutorial"); + return; +} diff --git a/dumps/scripts/4560.cs2 b/dumps/scripts/4560.cs2 new file mode 100644 index 0000000..64812f9 --- /dev/null +++ b/dumps/scripts/4560.cs2 @@ -0,0 +1,5 @@ +void script_4560(int arg0,string arg1) { + script_2995(arg0, 0, 0, 0, 0, 0, 16777215, 494, 1, 1, 0, 1, arg1); + setWidgetSize(0, 0, 1, 1); + return; +} diff --git a/dumps/scripts/4561.cs2 b/dumps/scripts/4561.cs2 new file mode 100644 index 0000000..41224b0 --- /dev/null +++ b/dumps/scripts/4561.cs2 @@ -0,0 +1,10 @@ +void script_4561(int arg0,int arg1,string arg2) { + int ivar2; + ivar2 = 38600758; + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetIsHidden(false, new WidgetPointer(ivar2)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(ivar2)), getWidgetActualY(), 0, 0, new WidgetPointer(ivar2)); + setScriptCallOnMouseOver(4562, new WidgetPointer(arg0), arg1, add(getClientCycle(), 25), arg2, -2147483647, -2147483646, "Iiisii"); + } + return; +} diff --git a/dumps/scripts/4562.cs2 b/dumps/scripts/4562.cs2 new file mode 100644 index 0000000..1cc9415 --- /dev/null +++ b/dumps/scripts/4562.cs2 @@ -0,0 +1,22 @@ +void script_4562(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5) { + int ivar5; + int ivar6; + ivar5 = 0; + ivar6 = 0; + if ((getClientCycle() > arg2) && setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetIsHidden(false, new WidgetPointer(589,34)); + setWidgetText(new WidgetPointer(589,38), arg5); + setWidgetSize(add(multiply(getWidgetActualX(new WidgetPointer(589,38)), 2), getTextWidth(495, arg5)), getWidgetActualHeight(new WidgetPointer(589,34)), 0, 0, new WidgetPointer(589,34)); + ivar5 = subtract(add(add(getWidgetActualX(), arg3), 3), cs2method2600(new WidgetPointer(arg0))); + ivar6 = subtract(subtract(subtract(add(add(add(getWidgetActualY(), arg4), getWidgetActualY(new WidgetPointer(589,43))), getWidgetActualY(new WidgetPointer(589,51))), 3), getWidgetActualHeight(new WidgetPointer(589,34))), cs2method2601(new WidgetPointer(589,51))); + if (add(ivar5, getWidgetActualWidth(new WidgetPointer(589,34))) > getWidgetActualWidth(new WidgetPointer(589,32))) { + ivar5 = subtract(getWidgetActualWidth(new WidgetPointer(589,32)), getWidgetActualWidth(new WidgetPointer(589,34))); + } + if (ivar6 < 0) { + ivar6 = 0; + } + setWidgetPosition(ivar5, ivar6, 0, 0, new WidgetPointer(589,34)); + setScriptCallOnMouseOver(-1, ""); + } + return; +} diff --git a/dumps/scripts/4563.cs2 b/dumps/scripts/4563.cs2 new file mode 100644 index 0000000..65cf0cf --- /dev/null +++ b/dumps/scripts/4563.cs2 @@ -0,0 +1,8 @@ +void script_4563(int arg0,int arg1) { + setWidgetIsHidden(true, new WidgetPointer(589,54)); + setWidgetIsHidden(true, new WidgetPointer(589,34)); + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setScriptCallOnMouseOver(-1, ""); + } + return; +} diff --git a/dumps/scripts/4564.cs2 b/dumps/scripts/4564.cs2 new file mode 100644 index 0000000..ec9697f --- /dev/null +++ b/dumps/scripts/4564.cs2 @@ -0,0 +1,19 @@ +void script_4564(int arg0,string arg1) { + switch (arg0) { + case 6: + cs2method3605(strRemoveEntities(arg1)); + break; + case 7: + cs2method3607(strRemoveEntities(arg1)); + break; + case 8: + cs2method3606(strRemoveEntities(arg1)); + break; + case 9: + cs2method3608(strRemoveEntities(arg1)); + break; + case 10: + script_1633(arg1); + } + return; +} diff --git a/dumps/scripts/4565.cs2 b/dumps/scripts/4565.cs2 new file mode 100644 index 0000000..929e465 --- /dev/null +++ b/dumps/scripts/4565.cs2 @@ -0,0 +1,7 @@ +void script_4565(int arg0) { + setScriptCallOnFriendListChange(4566, new WidgetPointer(arg0), "I", new WidgetPointer(arg0)); + setScriptCallOnClanListChange(4566, new WidgetPointer(arg0), "I", new WidgetPointer(arg0)); + setScriptCallOnMessage(4566, new WidgetPointer(arg0), "I", new WidgetPointer(arg0)); + script_4567(arg0); + return; +} diff --git a/dumps/scripts/4566.cs2 b/dumps/scripts/4566.cs2 new file mode 100644 index 0000000..ef1ee11 --- /dev/null +++ b/dumps/scripts/4566.cs2 @@ -0,0 +1,4 @@ +void script_4566(int arg0) { + script_4567(arg0); + return; +} diff --git a/dumps/scripts/4567.cs2 b/dumps/scripts/4567.cs2 new file mode 100644 index 0000000..5976478 --- /dev/null +++ b/dumps/scripts/4567.cs2 @@ -0,0 +1,70 @@ +void script_4567(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + string svar0; + string svar1; + string svar2; + string svar3; + if (cs2method5428(38600727, -1)) { + setScriptCallOnGameloop(4566, new WidgetPointer(arg0), "I", new WidgetPointer(arg0)); + return; + } + deleteAllExtraChilds(new WidgetPointer(589,23)); + svar0 = ""; + svar1 = ""; + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + svar2 = ""; + svar3 = ""; + while (ivar1 < 100) { + ivar3 = cs2method5004(ivar1); + svar2 = cs2method5010(ivar1); + svar3 = cs2method5019(ivar1); + switch (ivar3) { + case 26: + case 11: + ivar2 = script_4568(ivar2, 0, ivar3, cs2method5003(ivar1), "", ""); + break; + case 9: + ivar2 = script_4568(ivar2, 1, ivar3, "[" + svar0 + cs2method5011(ivar1) + "" + "] " + svar2 + ": " + svar1 + cs2method5003(ivar1), svar2, svar3); + break; + case 20: + ivar2 = script_4568(ivar2, 1, ivar3, "[" + svar0 + cs2method5011(ivar1) + "" + "] " + svar2 + ": " + svar1 + cs2method5003(ivar1), svar2, svar3); + break; + case 115: + ivar2 = script_4568(ivar2, 0, ivar3, "" + cs2method5003(ivar1) + "", "", ""); + } + ivar1 = add(ivar1, 1); + } + ivar4 = divide(getWidgetActualHeight(new WidgetPointer(589,23)), 15); + ivar1 = 0; + ivar5 = 0; + if (ivar2 < ivar4) { + ivar5 = subtract(ivar4, ivar2); + while (ivar1 < ivar5) { + ivar2 = script_4568(ivar2, 0, 0, "", "", ""); + ivar1 = add(ivar1, 1); + } + } + ivar6 = 0; + ivar7 = 0; + while (ivar7 <= ivar2) { + if (setWidgetRegister(new WidgetPointer(589,23), ivar7)) { + ivar6 = add(ivar6, getWidgetActualHeight()); + } + ivar7 = add(ivar7, 1); + } + ivar8 = max(ivar6, multiply(ivar4, 15)); + setWidgetScrollMax(0, ivar8, new WidgetPointer(589,23)); + script_72(38600728, 38600727, subtract(add(globalint_1508, getWidgetScrollMaxV(new WidgetPointer(589,23))), globalint_1509)); + globalint_1508 = cs2method2601(new WidgetPointer(589,23)); + globalint_1509 = getWidgetScrollMaxV(new WidgetPointer(589,23)); + return; +} diff --git a/dumps/scripts/4568.cs2 b/dumps/scripts/4568.cs2 new file mode 100644 index 0000000..68aafc7 --- /dev/null +++ b/dumps/scripts/4568.cs2 @@ -0,0 +1,46 @@ +int script_4568(int arg0,int arg1,int arg2,string arg3,string arg4,string arg5) { + int ivar3; + int ivar4; + int ivar5; + int ivar6; + ivar3 = getWidgetActualWidth(new WidgetPointer(589,23)); + ivar4 = multiply(max(getLineCount(ivar3, 494, arg3), 1), 15); + createExtraChild(new WidgetPointer(589,23), 4, arg0); + setWidgetPosition(0, multiply(arg0, 15), 0, 2); + setWidgetSize(0, ivar4, 1, 0); + setWidgetRGB(new Color(255, 255, 255)); + setWidgetFont(494); + setWidgetText(arg3); + setWidgetTextAlignment(0, 0, 15); + ivar5 = 0; + ivar6 = 0; + while (ivar6 < arg0) { + if (setWidgetRegister(new WidgetPointer(589,23), ivar6)) { + ivar5 = add(ivar5, getWidgetActualHeight()); + } + ivar6 = add(ivar6, 1); + } + setWidgetPosition(0, ivar5, 0, 2); + if (((boolean)arg1)) { + cs2method1305(strRemoveEntities(arg4)); + setScriptCallOnClickContextMenu(4569, -2147483644, arg4, arg5, "iss"); + switch (arg2) { + case 9: + case 20: + if (stringMethod4107(strRemoveEntities(cs2method5020()), strRemoveEntities(arg5)) != 0) { + if (isFriend(strRemoveEntities(arg5)) && cs2method3623(strRemoveEntities(arg5))) { + setWidgetContextMenuOption(1, "Add friend"); + setWidgetContextMenuOption(2, "Add ignore"); + } else { + if (isFriend(strRemoveEntities(arg5)) && cs2method6900()) { + setWidgetContextMenuOption(3, "Message"); + } + } + if (((boolean)script_1891())) { + setWidgetContextMenuOption(10, "Kick/ban"); + } + } + } + } + return add(arg0, 1); +} diff --git a/dumps/scripts/4569.cs2 b/dumps/scripts/4569.cs2 new file mode 100644 index 0000000..60da131 --- /dev/null +++ b/dumps/scripts/4569.cs2 @@ -0,0 +1,23 @@ +void script_4569(int arg0,string arg1,string arg2) { + switch (arg0) { + case 1: + if (isFriend(strRemoveEntities(arg2))) { + cs2method3605(strRemoveEntities(arg2)); + } + break; + case 2: + if (isFriend(strRemoveEntities(arg2))) { + cs2method3607(strRemoveEntities(arg2)); + } + break; + case 3: + script_3015(0, "Send message to " + arg1, "", arg2, ""); + break; + case 5: + script_3177(0, arg1); + break; + case 10: + script_1633(strRemoveEntities(arg2)); + } + return; +} diff --git a/dumps/scripts/457.cs2 b/dumps/scripts/457.cs2 new file mode 100644 index 0000000..668a7f2 --- /dev/null +++ b/dumps/scripts/457.cs2 @@ -0,0 +1,4 @@ +void script_457() { + script_304(52481120); + return; +} diff --git a/dumps/scripts/4570.cs2 b/dumps/scripts/4570.cs2 new file mode 100644 index 0000000..481710d --- /dev/null +++ b/dumps/scripts/4570.cs2 @@ -0,0 +1,5 @@ +void script_4570(int arg0,int arg1,int arg2) { + globalint_1507 = script_1401(arg0, 494, getWidgetActualX(new WidgetPointer(arg1)), globalstring_349); + script_4571(arg1, arg2, globalstring_349); + return; +} diff --git a/dumps/scripts/4571.cs2 b/dumps/scripts/4571.cs2 new file mode 100644 index 0000000..747c85e --- /dev/null +++ b/dumps/scripts/4571.cs2 @@ -0,0 +1,10 @@ +void script_4571(int arg0,int arg1,string arg2) { + setWidgetPosition(script_1551(globalint_1507, 494, getWidgetActualX(new WidgetPointer(arg0)), arg2), 1, 0, 1, new WidgetPointer(arg1)); + if (hasWindowFocus()) { + setWidgetIsHidden(false, new WidgetPointer(arg1)); + } else { + setWidgetIsHidden(true, new WidgetPointer(arg1)); + } + setScriptCallOnGameloop(4572, getClientCycle(), new WidgetPointer(arg1), "iI", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/4572.cs2 b/dumps/scripts/4572.cs2 new file mode 100644 index 0000000..6a86de9 --- /dev/null +++ b/dumps/scripts/4572.cs2 @@ -0,0 +1,13 @@ +void script_4572(int arg0,int arg1) { + if (cs2method3612() <= 0) { + setWidgetText(new WidgetPointer(589,27), ""); + setWidgetIsHidden(true, new WidgetPointer(arg1)); + return; + } + if ((mod(subtract(getClientCycle(), arg0), 40) < 20) && hasWindowFocus()) { + setWidgetIsHidden(false, new WidgetPointer(arg1)); + } else { + setWidgetIsHidden(true, new WidgetPointer(arg1)); + } + return; +} diff --git a/dumps/scripts/4573.cs2 b/dumps/scripts/4573.cs2 new file mode 100644 index 0000000..9d7cfda --- /dev/null +++ b/dumps/scripts/4573.cs2 @@ -0,0 +1,12 @@ +void script_4573() { + int ivar0; + int ivar1; + ivar0 = 0; + ivar1 = 0; + if (((boolean)script_1891())) { + setWidgetIsHidden(false, new WidgetPointer(589,50)); + return; + } + script_4574(); + return; +} diff --git a/dumps/scripts/4574.cs2 b/dumps/scripts/4574.cs2 new file mode 100644 index 0000000..d2ba5d7 --- /dev/null +++ b/dumps/scripts/4574.cs2 @@ -0,0 +1,5 @@ +void script_4574() { + setWidgetIsHidden(true, new WidgetPointer(589,50)); + setWidgetIsHidden(true, new WidgetPointer(589,4)); + return; +} diff --git a/dumps/scripts/4575.cs2 b/dumps/scripts/4575.cs2 new file mode 100644 index 0000000..30f6979 --- /dev/null +++ b/dumps/scripts/4575.cs2 @@ -0,0 +1,7 @@ +void script_4575() { + if (((boolean)script_1891())) { + script_41(38600739); + script_3015(9, "Kick/ban from chat channel", "", "", ""); + } + return; +} diff --git a/dumps/scripts/4576.cs2 b/dumps/scripts/4576.cs2 new file mode 100644 index 0000000..6ba964e --- /dev/null +++ b/dumps/scripts/4576.cs2 @@ -0,0 +1,4 @@ +void script_4576(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(1813, 596)); + return; +} diff --git a/dumps/scripts/4577.cs2 b/dumps/scripts/4577.cs2 new file mode 100644 index 0000000..66a935f --- /dev/null +++ b/dumps/scripts/4577.cs2 @@ -0,0 +1,4 @@ +void script_4577(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(1814, 596)); + return; +} diff --git a/dumps/scripts/4578.cs2 b/dumps/scripts/4578.cs2 new file mode 100644 index 0000000..6ac0ff3 --- /dev/null +++ b/dumps/scripts/4578.cs2 @@ -0,0 +1,4 @@ +void script_4578(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(1815, 596)); + return; +} diff --git a/dumps/scripts/4579.cs2 b/dumps/scripts/4579.cs2 new file mode 100644 index 0000000..5c34e32 --- /dev/null +++ b/dumps/scripts/4579.cs2 @@ -0,0 +1,4 @@ +void script_4579(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(1816, 596)); + return; +} diff --git a/dumps/scripts/458.cs2 b/dumps/scripts/458.cs2 new file mode 100644 index 0000000..f2d2cff --- /dev/null +++ b/dumps/scripts/458.cs2 @@ -0,0 +1,4 @@ +void script_458(int arg0) { + setWidgetText(new WidgetPointer(arg0), intToStr(bitconfig_2086)); + return; +} diff --git a/dumps/scripts/4580.cs2 b/dumps/scripts/4580.cs2 new file mode 100644 index 0000000..f5bd6a3 --- /dev/null +++ b/dumps/scripts/4580.cs2 @@ -0,0 +1,3 @@ +void script_4580() { + return; +} diff --git a/dumps/scripts/4581.cs2 b/dumps/scripts/4581.cs2 new file mode 100644 index 0000000..80ae63d --- /dev/null +++ b/dumps/scripts/4581.cs2 @@ -0,0 +1,16 @@ +void script_4581(int arg0) { + int ivar1; + int ivar2; + ivar1 = -1; + ivar2 = -1; + if (cs2method3751() && cs2method3701()) { + ivar1 = cs2method3760(strRemoveEntities(cs2method5020())); + if (ivar1 >= 0) { + ivar2 = cs2method3757(ivar1); + if (ivar2 >= 100) { + globalstring_350 = cs2method3713(arg0); + } + } + } + return; +} diff --git a/dumps/scripts/4582.cs2 b/dumps/scripts/4582.cs2 new file mode 100644 index 0000000..ad92b79 --- /dev/null +++ b/dumps/scripts/4582.cs2 @@ -0,0 +1,24 @@ +string script_4582(int arg0,int arg1,int arg2) { + if (arg0 > 0) { + if (arg1 > 0) { + if (arg2 > 0) { + return intToStr(arg0) + " " + script_4583(arg0, "day", "days") + ", " + intToStr(arg1) + " " + script_4583(arg0, "hour", "hours") + " and " + intToStr(arg2) + " " + script_4583(arg0, "minute", "minutes"); + } + return intToStr(arg0) + " " + script_4583(arg0, "day", "days") + " and " + intToStr(arg1) + " " + script_4583(arg0, "hour", "hours"); + } + if (arg2 > 0) { + return intToStr(arg0) + " " + script_4583(arg0, "day", "days") + " and " + intToStr(arg2) + " " + script_4583(arg0, "minute", "minutes"); + } + return intToStr(arg0) + " " + script_4583(arg0, "day", "days"); + } + if (arg1 > 0) { + if (arg2 > 0) { + return script_4583(arg0, "hour", "hours") + " and " + intToStr(arg2) + " " + script_4583(arg0, "minute", "minutes"); + } + return intToStr(arg1) + " " + script_4583(arg0, "hour", "hours"); + } + if (arg2 > 0) { + return intToStr(arg2) + " " + script_4583(arg0, "minute", "minutes"); + } + return ""; +} diff --git a/dumps/scripts/4583.cs2 b/dumps/scripts/4583.cs2 new file mode 100644 index 0000000..a124e81 --- /dev/null +++ b/dumps/scripts/4583.cs2 @@ -0,0 +1,6 @@ +string script_4583(int arg0,string arg1,string arg2) { + if (((boolean)arg0)) { + return arg1; + } + return arg2; +} diff --git a/dumps/scripts/4584.cs2 b/dumps/scripts/4584.cs2 new file mode 100644 index 0000000..086fd9a --- /dev/null +++ b/dumps/scripts/4584.cs2 @@ -0,0 +1,5 @@ +void script_4584(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7) { + script_2732(arg0, arg1, bitconfig_9191, 3); + setScriptCallOnClickContextMenu(4585, -2147483644, arg1, new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), new WidgetPointer(arg6), new WidgetPointer(arg7), "iiIIIIII", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/4585.cs2 b/dumps/scripts/4585.cs2 new file mode 100644 index 0000000..e55628d --- /dev/null +++ b/dumps/scripts/4585.cs2 @@ -0,0 +1,12 @@ +void script_4585(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7) { + if (arg0 != 1) { + return; + } + if (bitconfig_9191 == arg1) { + return; + } + bitconfig_9191 = arg1; + playSoundEffect(2266, 1, 0); + script_2735(arg2, arg3, arg4, arg5, arg6, arg7); + return; +} diff --git a/dumps/scripts/4586.cs2 b/dumps/scripts/4586.cs2 new file mode 100644 index 0000000..709881b --- /dev/null +++ b/dumps/scripts/4586.cs2 @@ -0,0 +1,15 @@ +void script_4586(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + ivar4 = -1; + if ((arg2 > 0) && (arg3 > 0)) { + ivar4 = cs2method_3408(105, 103, 3703, arg2); + if (ivar4 != -1) { + setWidgetText(new WidgetPointer(arg0), cs2method_3408(105, 115, ivar4, arg3)); + setWidgetIsHidden(false, new WidgetPointer(arg1)); + return; + } + } + setWidgetText(new WidgetPointer(arg0), ""); + setWidgetIsHidden(true, new WidgetPointer(arg1)); + return; +} diff --git a/dumps/scripts/4587.cs2 b/dumps/scripts/4587.cs2 new file mode 100644 index 0000000..59e73ee --- /dev/null +++ b/dumps/scripts/4587.cs2 @@ -0,0 +1,4 @@ +void script_4587(int arg0,int arg1) { + setWidgetSprite(arg1, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/4588.cs2 b/dumps/scripts/4588.cs2 new file mode 100644 index 0000000..7c94f55 --- /dev/null +++ b/dumps/scripts/4588.cs2 @@ -0,0 +1,6 @@ +void script_4588(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + setWidgetSprite(arg1, new WidgetPointer(arg0)); + setWidgetSprite(arg3, new WidgetPointer(arg2)); + setWidgetSprite(arg5, new WidgetPointer(arg4)); + return; +} diff --git a/dumps/scripts/4589.cs2 b/dumps/scripts/4589.cs2 new file mode 100644 index 0000000..96d1a5b --- /dev/null +++ b/dumps/scripts/4589.cs2 @@ -0,0 +1,25 @@ +void script_4589() { + string svar0; + deleteAllExtraChilds(new WidgetPointer(1110,14)); + deleteAllExtraChilds(new WidgetPointer(1110,12)); + deleteAllExtraChilds(new WidgetPointer(1110,15)); + deleteAllExtraChilds(new WidgetPointer(1110,17)); + deleteAllExtraChilds(new WidgetPointer(1110,18)); + deleteAllExtraChilds(new WidgetPointer(1110,16)); + setWidgetIsHidden(true, new WidgetPointer(1110,27)); + setWidgetIsHidden(false, new WidgetPointer(1110,67)); + setWidgetText(new WidgetPointer(1110,62), "You are not currently in a Clan Chat channel."); + setWidgetIsHidden(true, new WidgetPointer(1110,29)); + setWidgetIsHidden(false, new WidgetPointer(1110,22)); + script_4469(); + setWidgetSprite(6256, new WidgetPointer(1110,86)); + setWidgetIsHidden(true, new WidgetPointer(1110,13)); + setWidgetSize(1, 19, 0, 0, new WidgetPointer(1110,20)); + globalint_1518 = -1; + globalstring_126 = ""; + setWidgetText(new WidgetPointer(1110,26), ""); + svar0 = "Join your clan chat channel."; + setScriptCallOnMouseOver(4538, new WidgetPointer(1110,60), new WidgetPointer(-32768,3), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1110,85)); + setWidgetContextMenuOption(1, new WidgetPointer(1110,85), "Join Clan Chat channel"); + return; +} diff --git a/dumps/scripts/459.cs2 b/dumps/scripts/459.cs2 new file mode 100644 index 0000000..40f3fdb --- /dev/null +++ b/dumps/scripts/459.cs2 @@ -0,0 +1,10 @@ +void script_459(int arg0) { + if (getSkillActualLvl(0) < 25) { + setWidgetText(new WidgetPointer(arg0), "" + "An Attack level of " + intToStr(25) + " is required." + ""); + } else if (bitconfig_2086 < 1) { + setWidgetText(new WidgetPointer(arg0), "" + "1 Commendation required." + ""); + } else { + setWidgetText(new WidgetPointer(arg0), intToStr(multiply(divide(pow(getSkillActualLvl(0), 2), 600), 35)) + " XP per Commendation."); + } + return; +} diff --git a/dumps/scripts/4590.cs2 b/dumps/scripts/4590.cs2 new file mode 100644 index 0000000..900972f --- /dev/null +++ b/dumps/scripts/4590.cs2 @@ -0,0 +1,29 @@ +cs2func_script_4590_struct(6,0,0) script_4590() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + ivar0 = -1; + ivar1 = -1; + ivar2 = -1; + ivar3 = -1; + ivar4 = -1; + ivar5 = -1; + if (cs2method3751()) { + ivar2 = cs2method3754(); + ivar0 = cs2method3760(strRemoveEntities(cs2method5020())); + if (ivar0 >= 0) { + ivar1 = cs2method3757(ivar0); + } + } + if (cs2method3750()) { + ivar5 = cs2method3754(); + ivar3 = cs2method3760(strRemoveEntities(cs2method5020())); + if (ivar3 >= 0) { + ivar4 = cs2method3757(ivar3); + } + } + return newstruct cs2func_script_4590_struct(ivar0, ivar1, ivar2, ivar3, ivar4, ivar5); +} diff --git a/dumps/scripts/4591.cs2 b/dumps/scripts/4591.cs2 new file mode 100644 index 0000000..ee6517a --- /dev/null +++ b/dumps/scripts/4591.cs2 @@ -0,0 +1,27 @@ +string script_4591(string arg0) { + int ivar0; + int ivar1; + arg0 = lower(strRemoveEntities(arg0)); + ivar0 = strLength(arg0); + ivar1 = 0; + arg0 = script_2332(arg0, "_", "\u00a0"); + arg0 = script_2332(arg0, "-", "\u00a0"); + arg0 = script_2332(arg0, " ", "\u00a0"); + while (((boolean)strIndexof(0, arg0, " ")) && (ivar0 > 0)) { + arg0 = substr(1, ivar0, arg0); + ivar0 = strLength(arg0); + } + while ((strIndexof(subtract(ivar0, 1), arg0, " ") == subtract(ivar0, 1)) && (ivar0 > 0)) { + arg0 = substr(0, subtract(ivar0, 1), arg0); + ivar0 = strLength(arg0); + } + while (((boolean)strIndexof(0, arg0, "\u00a0")) && (ivar0 > 0)) { + arg0 = substr(1, ivar0, arg0); + ivar0 = strLength(arg0); + } + while ((strIndexof(subtract(ivar0, 1), arg0, "\u00a0") == subtract(ivar0, 1)) && (ivar0 > 0)) { + arg0 = substr(0, subtract(ivar0, 1), arg0); + ivar0 = strLength(arg0); + } + return arg0; +} diff --git a/dumps/scripts/4592.cs2 b/dumps/scripts/4592.cs2 new file mode 100644 index 0000000..7b5e362 --- /dev/null +++ b/dumps/scripts/4592.cs2 @@ -0,0 +1,225 @@ +void script_4592() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + deleteAllExtraChilds(new WidgetPointer(17,17)); + deleteAllExtraChilds(new WidgetPointer(17,20)); + deleteAllExtraChilds(new WidgetPointer(17,22)); + deleteAllExtraChilds(new WidgetPointer(17,15)); + if (((boolean)bitconfig_9226)) { + setWidgetText(new WidgetPointer(17,12), "If you die in the Wilderness..."); + } else { + setWidgetText(new WidgetPointer(17,12), "Items kept on death"); + } + if (bitconfig_9226 == 2) { + createExtraChild(new WidgetPointer(17,15), 4, 0); + script_4595(); + setWidgetText(globalstring_351); + setScriptCallOnGlobalStringChange(4596, new WidgetPointer(-32768,3), -2147483643, 351, 1, "IiY"); + return; + } + if (((getContainerFreeSlots(93) >= getItemContainerLength(93)) && (getContainerFreeSlots(94) >= getItemContainerLength(94))) && ((getContainerFreeSlots(530) >= getItemContainerLength(530)) || isMember())) { + createExtraChild(new WidgetPointer(17,15), 4, 0); + script_4595(); + setWidgetText("You have no items to lose."); + return; + } + ivar0 = getWidgetActualWidth(new WidgetPointer(17,15)); + ivar1 = max(divide(ivar0, 36), 1); + ivar2 = max(divide(subtract(ivar0, multiply(36, ivar1)), max(subtract(ivar1, 1), 1)), 2); + ivar3 = max(divide(ivar2, 2), add(subtract(36, 32), 1)); + globalarray_0 = new int[4]; + globalarray_1 = new int[3]; + globalarray_2 = new int[3]; + globalarray_3 = new int[3]; + if (bitconfig_9227 > 0) { + if (((boolean)bitconfig_9226)) { + if (((boolean)bitconfig_9229)) { + globalarray_0[0] = script_4593(1114128, "You may choose " + intToStr(bitconfig_9227) + " of the following items to keep, and all others will be dropped." + "
" + "The " + "" + "highlighted" + "" + " items will be chosen by default."); + } else { + globalarray_0[0] = script_4593(1114128, "You may choose " + intToStr(bitconfig_9227) + " of the following items to keep, unless you become skulled, and all others will be dropped." + "
" + "The " + "" + "highlighted" + "" + " items are chosen by default."); + } + } else if (((boolean)bitconfig_9229)) { + globalarray_0[0] = script_4593(1114128, "You will keep the following items:"); + } else { + globalarray_0[0] = script_4593(1114128, "You will keep the following items, unless you become skulled:"); + } + } else { + globalarray_0[0] = script_4593(1114128, "You will drop the following items:"); + } + if (((boolean)bitconfig_9226)) { + globalarray_0[1] = script_4593(1114131, "You will keep the following items automatically:"); + } else { + globalarray_0[1] = script_4593(1114131, "You will drop the following items:"); + } + globalarray_0[2] = script_4593(1114133, "The following items are always lost:"); + globalarray_4 = new int[4]; + globalarray_0[0] = script_750(bitconfig_9222); + globalarray_0[1] = script_750(bitconfig_9223); + globalarray_0[2] = script_750(bitconfig_9224); + globalarray_0[3] = script_750(bitconfig_9225); + ivar4 = add(getItemContainerLength(93), getItemContainerLength(94)); + deleteAllExtraChilds(new WidgetPointer(17,18)); + ivar5 = 0; + while ((ivar5 < bitconfig_9227) && (ivar5 < 4)) { + if (globalarray_4[ivar5] != -1) { + createExtraChild(new WidgetPointer(17,18), 3, getExtraChildGap(new WidgetPointer(17,18))); + createExtraChild(new WidgetPointer(17,18), 3, getExtraChildGap(new WidgetPointer(17,18))); + setWidgetSize(36, 36, 0, 0); + setWidgetSize(36, 36, 0, 0); + setWidgetPosition(add(globalarray_1[0], 1), add(globalarray_2[0], 1), 0, 0); + setWidgetPosition(globalarray_1[0], globalarray_2[0], 0, 0); + setWidgetRGB(new Color(128, 128, 0)); + setWidgetRGB(new Color(190, 190, 0)); + setWidgetFilled(0); + setWidgetFilled(0); + cs2method2103(150); + cs2method2103(0); + script_4594(globalarray_4[ivar5], -1, globalarray_1[0], globalarray_2[0], 1114130); + globalarray_0[0] = add(add(globalarray_1[0], 36), ivar2); + if (add(globalarray_1[0], 36) >= ivar0) { + globalarray_0[0] = 0; + globalarray_0[0] = add(add(globalarray_2[0], 32), ivar3); + } + globalarray_0[0] = add(globalarray_3[0], 1); + } else { + createExtraChild(new WidgetPointer(17,18), 3, getExtraChildGap(new WidgetPointer(17,18))); + setWidgetHidden(1); + createExtraChild(new WidgetPointer(17,18), 3, getExtraChildGap(new WidgetPointer(17,18))); + setWidgetHidden(1); + createExtraChild(new WidgetPointer(17,18), 3, getExtraChildGap(new WidgetPointer(17,18))); + setWidgetHidden(1); + } + ivar5 = add(ivar5, 1); + } + ivar5 = 0; + ivar6 = -1; + ivar7 = 0; + ivar8 = 0; + ivar9 = 0; + while (ivar5 <= ivar4) { + ivar6 = script_750(ivar5); + if (ivar6 != -1) { + ivar7 = script_1393(ivar5); + ivar8 = 0; + while ((ivar8 < 4) && (ivar7 > 0)) { + if (globalarray_4[ivar8] == ivar6) { + ivar7 = subtract(ivar7, 1); + globalarray_0[ivar8] = -1; + } + ivar8 = add(ivar8, 1); + } + if (ivar7 > 0) { + ivar9 = getItemHashmapData(getRealItem(ivar6), 1397); + if (ivar9 == -1) { + script_4594(-1, -1, -1, -1, 1114129); + script_4594(-1, -1, -1, -1, 1114132); + script_4594(ivar6, ivar7, globalarray_1[2], globalarray_2[2], 1114134); + globalarray_0[2] = add(add(globalarray_1[2], 36), ivar2); + if (add(globalarray_1[2], 36) >= ivar0) { + globalarray_0[2] = 0; + globalarray_0[2] = add(add(globalarray_2[2], 32), ivar3); + } + globalarray_0[2] = add(globalarray_3[2], 1); + } else if (((boolean)ivar9) || (bitconfig_9226 != 0)) { + script_4594(-1, -1, -1, -1, 1114129); + script_4594(ivar6, ivar7, globalarray_1[1], globalarray_2[1], 1114132); + script_4594(-1, -1, -1, -1, 1114134); + globalarray_0[1] = add(add(globalarray_1[1], 36), ivar2); + if (add(globalarray_1[1], 36) >= ivar0) { + globalarray_0[1] = 0; + globalarray_0[1] = add(add(globalarray_2[1], 32), ivar3); + } + globalarray_0[1] = add(globalarray_3[1], 1); + } else { + script_4594(ivar6, ivar7, globalarray_1[0], globalarray_2[0], 1114129); + script_4594(-1, -1, -1, -1, 1114132); + script_4594(-1, -1, -1, -1, 1114134); + globalarray_0[0] = add(add(globalarray_1[0], 36), ivar2); + if (add(globalarray_1[0], 36) >= ivar0) { + globalarray_0[0] = 0; + globalarray_0[0] = add(add(globalarray_2[0], 32), ivar3); + } + globalarray_0[0] = add(globalarray_3[0], 1); + } + } else { + script_4594(-1, -1, -1, -1, 1114129); + script_4594(-1, -1, -1, -1, 1114132); + script_4594(-1, -1, -1, -1, 1114134); + } + } else { + script_4594(-1, -1, -1, -1, 1114129); + script_4594(-1, -1, -1, -1, 1114132); + script_4594(-1, -1, -1, -1, 1114134); + } + ivar5 = add(ivar5, 1); + } + if (globalarray_1[0] > 0) { + globalarray_0[0] = add(add(globalarray_2[0], 32), ivar3); + } else { + if (globalarray_3[0] <= 0) { + globalarray_0[0] = 0; + globalarray_0[0] = 0; + } + } + if (globalarray_1[1] > 0) { + globalarray_0[1] = add(add(globalarray_2[1], 32), ivar3); + } else { + if (globalarray_3[1] <= 0) { + globalarray_0[1] = 0; + globalarray_0[1] = 0; + } + } + if (globalarray_1[2] > 0) { + globalarray_0[2] = add(add(globalarray_2[2], 32), ivar3); + } else { + if (globalarray_3[2] <= 0) { + globalarray_0[2] = 0; + globalarray_0[2] = 0; + } + } + ivar10 = 0; + setWidgetSize(0, globalarray_0[0], 1, 0, new WidgetPointer(17,16)); + setWidgetPosition(0, ivar10, 1, 0, new WidgetPointer(17,16)); + ivar10 = add(ivar10, globalarray_0[0]); + setWidgetSize(0, globalarray_2[0], 1, 0, new WidgetPointer(17,17)); + setWidgetPosition(0, ivar10, 1, 0, new WidgetPointer(17,17)); + ivar10 = add(add(ivar10, globalarray_2[0]), 5); + setWidgetSize(0, globalarray_0[1], 1, 0, new WidgetPointer(17,19)); + setWidgetPosition(0, ivar10, 1, 0, new WidgetPointer(17,19)); + ivar10 = add(ivar10, globalarray_0[1]); + setWidgetSize(0, globalarray_2[1], 1, 0, new WidgetPointer(17,20)); + setWidgetPosition(0, ivar10, 1, 0, new WidgetPointer(17,20)); + ivar10 = add(add(ivar10, globalarray_2[1]), 5); + setWidgetSize(0, globalarray_0[2], 1, 0, new WidgetPointer(17,21)); + setWidgetPosition(0, ivar10, 1, 0, new WidgetPointer(17,21)); + ivar10 = add(ivar10, globalarray_0[2]); + setWidgetSize(0, globalarray_2[2], 1, 0, new WidgetPointer(17,22)); + setWidgetPosition(0, ivar10, 1, 0, new WidgetPointer(17,22)); + ivar10 = add(ivar10, globalarray_2[2]); + if ((getContainerFreeSlots(530) < getItemContainerLength(530)) && isMember()) { + globalarray_0[3] = script_4593(1114135, "You have items stored on your " + "" + "beast of burden" + "" + " that will be dropped if either of you dies."); + } + setWidgetSize(0, globalarray_0[3], 1, 0, new WidgetPointer(17,23)); + setWidgetPosition(0, ivar10, 1, 0, new WidgetPointer(17,23)); + ivar10 = add(ivar10, globalarray_0[3]); + setWidgetScrollMax(0, ivar10, new WidgetPointer(17,15)); + if (ivar10 > getWidgetActualHeight(new WidgetPointer(17,15))) { + script_31(1114136, 1114127, 792, 789, 790, 791, 773, 788); + setWidgetIsHidden(false, new WidgetPointer(17,24)); + setWidgetPosition(0, 0, 0, 1, new WidgetPointer(17,15)); + } else { + setWidgetIsHidden(true, new WidgetPointer(17,24)); + setWidgetPosition(0, 0, 1, 1, new WidgetPointer(17,15)); + cs2method2100(0, 0, new WidgetPointer(17,15)); + } + return; +} diff --git a/dumps/scripts/4593.cs2 b/dumps/scripts/4593.cs2 new file mode 100644 index 0000000..f472ce2 --- /dev/null +++ b/dumps/scripts/4593.cs2 @@ -0,0 +1,7 @@ +int script_4593(int arg0,string arg1) { + int ivar1; + ivar1 = add(multiply(getLineCount(getWidgetActualWidth(new WidgetPointer(arg0)), 495, arg1), 15), 5); + setWidgetIsHidden(false, new WidgetPointer(arg0)); + setWidgetText(new WidgetPointer(arg0), arg1); + return ivar1; +} diff --git a/dumps/scripts/4594.cs2 b/dumps/scripts/4594.cs2 new file mode 100644 index 0000000..0f4fd69 --- /dev/null +++ b/dumps/scripts/4594.cs2 @@ -0,0 +1,19 @@ +void script_4594(int arg0,int arg1,int arg2,int arg3,int arg4) { + createExtraChild(new WidgetPointer(arg4), 5, getExtraChildGap(new WidgetPointer(arg4))); + if ((arg2 != -1) && (arg3 != -1)) { + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(add(arg2, 2), add(arg3, 2), 0, 0); + if (arg1 <= 0) { + setItemOnWidgetMethod1205(arg0, 1); + } else { + setItemOnWidgetMethod1200(arg0, arg1); + } + setWidgetContextMenuOption(10, "Examine"); + setWidgetShadowColor(new Color(48, 32, 32)); + setWidgetBorderThickness(1); + cs2method1305("" + getItemName(arg0) + ""); + } else { + setWidgetHidden(1); + } + return; +} diff --git a/dumps/scripts/4595.cs2 b/dumps/scripts/4595.cs2 new file mode 100644 index 0000000..52fee80 --- /dev/null +++ b/dumps/scripts/4595.cs2 @@ -0,0 +1,19 @@ +void script_4595() { + setWidgetIsHidden(true, new WidgetPointer(17,17)); + setWidgetIsHidden(true, new WidgetPointer(17,16)); + setWidgetIsHidden(true, new WidgetPointer(17,20)); + setWidgetIsHidden(true, new WidgetPointer(17,19)); + setWidgetIsHidden(true, new WidgetPointer(17,22)); + setWidgetIsHidden(true, new WidgetPointer(17,21)); + setWidgetIsHidden(true, new WidgetPointer(17,24)); + setWidgetScrollMax(0, 0, new WidgetPointer(17,15)); + setWidgetPosition(0, 0, 1, 1, new WidgetPointer(17,15)); + cs2method2100(0, 0, new WidgetPointer(17,15)); + setWidgetSize(0, 0, 1, 1); + setWidgetPosition(0, 0, 1, 1); + setWidgetFont(495); + setWidgetTextAlignment(1, 1, 0); + setWidgetRGB(new Color(255, 152, 31)); + setWidgetUnknownBoolean(true); + return; +} diff --git a/dumps/scripts/4596.cs2 b/dumps/scripts/4596.cs2 new file mode 100644 index 0000000..d165734 --- /dev/null +++ b/dumps/scripts/4596.cs2 @@ -0,0 +1,6 @@ +void script_4596(int arg0,int arg1) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetText(globalstring_351); + } + return; +} diff --git a/dumps/scripts/4597.cs2 b/dumps/scripts/4597.cs2 new file mode 100644 index 0000000..b008e5e --- /dev/null +++ b/dumps/scripts/4597.cs2 @@ -0,0 +1,49 @@ +void script_4597() { + int ivar0; + string svar0; + string svar1; + svar0 = "What if I entered the Wilderness?"; + svar1 = "Back"; + ivar0 = 0; + if (bitconfig_9226 >= 2) { + setWidgetIsHidden(true, new WidgetPointer(17,28)); + setWidgetSize(16, 0, 1, 1, new WidgetPointer(17,26)); + setWidgetSize(16, 0, 0, 1, new WidgetPointer(17,27)); + } else if (((boolean)bitconfig_9226)) { + setWidgetText(new WidgetPointer(17,30), svar1); + } else { + setWidgetText(new WidgetPointer(17,30), svar0); + } + ivar0 = max(getLineCount(getWidgetActualWidth(new WidgetPointer(17,30)), 495, svar0), getLineCount(getWidgetActualWidth(new WidgetPointer(17,30)), 495, svar1)); + ivar0 = add(multiply(ivar0, 12), 10); + setWidgetSize(10, ivar0, 1, 0, new WidgetPointer(17,28)); + setWidgetIsHidden(false, new WidgetPointer(17,28)); + ivar0 = add(ivar0, 5); + setWidgetSize(16, ivar0, 1, 1, new WidgetPointer(17,26)); + setWidgetSize(16, ivar0, 0, 1, new WidgetPointer(17,27)); + script_680(1114141); + setScriptCallOnMouseEntered(95, new WidgetPointer(17,29), "I", new WidgetPointer(17,28)); + setScriptCallOnMouseExit(93, new WidgetPointer(17,29), "I", new WidgetPointer(17,28)); + deleteAllExtraChilds(new WidgetPointer(17,26)); + ivar0 = add(multiply(getLineCount(getWidgetActualWidth(new WidgetPointer(17,26)), 494, globalstring_352), 10), 2); + createExtraChild(new WidgetPointer(17,26), 4, 0); + setWidgetSize(0, ivar0, 1, 0); + setWidgetPosition(0, 0, 1, 0); + setWidgetFont(494); + setWidgetTextAlignment(1, 1, 0); + setWidgetRGB(new Color(255, 152, 31)); + setWidgetUnknownBoolean(true); + setWidgetText(globalstring_352); + if (ivar0 > getWidgetActualHeight(new WidgetPointer(17,26))) { + setWidgetScrollMax(0, ivar0, new WidgetPointer(17,26)); + script_31(1114139, 1114138, 792, 789, 790, 791, 773, 788); + setWidgetIsHidden(false, new WidgetPointer(17,27)); + setWidgetPosition(0, 0, 0, 0, new WidgetPointer(17,26)); + } else { + setWidgetScrollMax(0, 0, new WidgetPointer(17,26)); + setWidgetIsHidden(true, new WidgetPointer(17,27)); + setWidgetPosition(0, 0, 1, 0, new WidgetPointer(17,26)); + cs2method2100(0, 0, new WidgetPointer(17,26)); + } + return; +} diff --git a/dumps/scripts/4598.cs2 b/dumps/scripts/4598.cs2 new file mode 100644 index 0000000..64c0994 --- /dev/null +++ b/dumps/scripts/4598.cs2 @@ -0,0 +1,40 @@ +void script_4598(int arg0) { + int ivar1; + string svar0; + deleteAllExtraChilds(new WidgetPointer(16,20)); + script_4534(1048596); + deleteAllExtraChilds(new WidgetPointer(16,39)); + script_4534(1048615); + deleteAllExtraChilds(new WidgetPointer(16,59)); + script_4535(1048635); + script_4513(1048584, 1746); + script_4510(1048644, 1736); + script_4510(1048645, 1737); + script_4530(1048578); + script_4531(1048648); + script_4532(1048650); + script_4530(1048653); + script_4531(1048657); + script_4599(11694, 1, 1048590, "A beautiful, heavy sword."); + script_4599(20151, 1, 1048591, "An ancient ranger's body armour."); + script_4599(20167, 1, 1048592, "An ancient mage's robe legs."); + script_4599(2667, 1, 1048607, "A rune kiteshield in the colours of Saradomin."); + script_4599(4587, 1, 1048608, "A vicious, curved sword."); + script_4599(1955, 1, 1048609, "Keeps the doctor away."); + script_4599(11235, 1, 1048610, "A bow from a darker dimension."); + script_4599(560, 1337, 1048611, "Used for medium level missile spells."); + script_4599(4151, 1, 1048612, "A weapon from the Abyss."); + script_4599(995, 6969, 1048624, "Lovely money!"); + script_4599(11279, 1, 1048625, "The severed head of the great dragon Elvarg!"); + script_4599(2347, 1, 1048626, "Good for hitting things!"); + script_4599(14090, 1, 1048627, "This cat definitely likes you."); + svar0 = cs2method_3408(105, 115, 3796, 0); + setWidgetText(new WidgetPointer(16,63), svar0); + ivar1 = add(max(getTextWidth(494, getWidgetText(new WidgetPointer(16,58))), getTextWidth(494, svar0)), 26); + setWidgetSize(ivar1, getWidgetActualHeight(new WidgetPointer(16,52)), 0, 0, new WidgetPointer(16,52)); + setWidgetSize(ivar1, getWidgetActualHeight(new WidgetPointer(16,59)), 0, 0, new WidgetPointer(16,59)); + setWidgetPosition(max(subtract(add(ivar1, 1), divide(subtract(getWidgetActualWidth(new WidgetPointer(16,3)), getWidgetActualWidth(new WidgetPointer(16,4))), 2)), 0), 0, 1, 0, new WidgetPointer(16,4)); + setScriptCallOnGlobalConfigChange(4601, new WidgetPointer(arg0), 1514, 1, "IY", new WidgetPointer(arg0)); + script_4602(globalint_1514, arg0); + return; +} diff --git a/dumps/scripts/4599.cs2 b/dumps/scripts/4599.cs2 new file mode 100644 index 0000000..7c96f28 --- /dev/null +++ b/dumps/scripts/4599.cs2 @@ -0,0 +1,12 @@ +void script_4599(int arg0,int arg1,int arg2,string arg3) { + if (arg1 > 1) { + setItemOnWidgetMethod2212(arg0, arg1, new WidgetPointer(arg2)); + } else { + setItemOnWidgetMethod2205(arg0, 1, new WidgetPointer(arg2)); + } + setScriptCallOnClickContextMenu(1620, new WidgetPointer(-32768,3), -2147483643, 100, 0, 8, "Iiiii", new WidgetPointer(arg2)); + setWidgetContextMenuOption(10, new WidgetPointer(arg2), "Examine"); + cs2method2305(new WidgetPointer(arg2), "" + getItemName(arg0) + ""); + setScriptCallOnClickContextMenu(4600, -2147483644, arg3, "is", new WidgetPointer(arg2)); + return; +} diff --git a/dumps/scripts/46.cs2 b/dumps/scripts/46.cs2 new file mode 100644 index 0000000..025ce33 --- /dev/null +++ b/dumps/scripts/46.cs2 @@ -0,0 +1,20 @@ +string script_46(int arg0,string arg1) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + ivar1 = divide(arg0, 1000000000); + ivar2 = divide(subtract(arg0, multiply(ivar1, 1000000000)), 1000000); + ivar3 = divide(subtract(arg0, add(multiply(ivar1, 1000000000), multiply(ivar2, 1000000))), 1000); + ivar4 = subtract(arg0, add(add(multiply(ivar1, 1000000000), multiply(ivar2, 1000000)), multiply(ivar3, 1000))); + if (ivar1 > 0) { + return intToStr(ivar1) + arg1 + script_47(ivar2) + arg1 + script_47(ivar3) + arg1 + script_47(ivar4); + } + if (ivar2 > 0) { + return intToStr(ivar2) + arg1 + script_47(ivar3) + arg1 + script_47(ivar4); + } + if (ivar3 > 0) { + return intToStr(ivar3) + arg1 + script_47(ivar4); + } + return intToStr(arg0); +} diff --git a/dumps/scripts/460.cs2 b/dumps/scripts/460.cs2 new file mode 100644 index 0000000..b493978 --- /dev/null +++ b/dumps/scripts/460.cs2 @@ -0,0 +1,10 @@ +void script_460(int arg0) { + if (getSkillActualLvl(2) < 25) { + setWidgetText(new WidgetPointer(arg0), "" + "A Strength level of " + intToStr(25) + " is required." + ""); + } else if (bitconfig_2086 < 1) { + setWidgetText(new WidgetPointer(arg0), "" + "1 Commendation required." + ""); + } else { + setWidgetText(new WidgetPointer(arg0), intToStr(multiply(divide(pow(getSkillActualLvl(2), 2), 600), 35)) + " XP per Commendation."); + } + return; +} diff --git a/dumps/scripts/4600.cs2 b/dumps/scripts/4600.cs2 new file mode 100644 index 0000000..ceab24c --- /dev/null +++ b/dumps/scripts/4600.cs2 @@ -0,0 +1,6 @@ +void script_4600(int arg0,string arg1) { + if (arg0 == 10) { + message(27, 0, arg1); + } + return; +} diff --git a/dumps/scripts/4601.cs2 b/dumps/scripts/4601.cs2 new file mode 100644 index 0000000..493c936 --- /dev/null +++ b/dumps/scripts/4601.cs2 @@ -0,0 +1,4 @@ +void script_4601(int arg0) { + script_4602(globalint_1514, arg0); + return; +} diff --git a/dumps/scripts/4602.cs2 b/dumps/scripts/4602.cs2 new file mode 100644 index 0000000..230ffce --- /dev/null +++ b/dumps/scripts/4602.cs2 @@ -0,0 +1,75 @@ +void script_4602(int arg0,int arg1) { + flow_0: + SWITCH (arg0) { + case 1: + GOTO flow_1 + case 2: + GOTO flow_2 + case 3: + GOTO flow_3 + case 4: + GOTO flow_4 + case 5: + GOTO flow_5 + } + setWidgetIsHidden(true, new WidgetPointer(16,1)); + setWidgetIsHidden(true, new WidgetPointer(16,52)); + setWidgetIsHidden(true, new WidgetPointer(16,59)); + setWidgetIsHidden(true, new WidgetPointer(16,37)); + setWidgetIsHidden(true, new WidgetPointer(16,4)); + setWidgetIsHidden(true, new WidgetPointer(16,18)); + setWidgetIsHidden(true, new WidgetPointer(16,64)); + setWidgetIsHidden(true, new WidgetPointer(16,76)); + GOTO flow_6 + flow_1: + setWidgetIsHidden(false, new WidgetPointer(16,1)); + setWidgetIsHidden(false, new WidgetPointer(16,52)); + setWidgetIsHidden(false, new WidgetPointer(16,59)); + setWidgetIsHidden(true, new WidgetPointer(16,37)); + setWidgetIsHidden(true, new WidgetPointer(16,4)); + setWidgetIsHidden(true, new WidgetPointer(16,18)); + setWidgetIsHidden(true, new WidgetPointer(16,64)); + setWidgetIsHidden(true, new WidgetPointer(16,76)); + GOTO flow_6 + flow_2: + setWidgetIsHidden(true, new WidgetPointer(16,1)); + setWidgetIsHidden(true, new WidgetPointer(16,52)); + setWidgetIsHidden(true, new WidgetPointer(16,59)); + setWidgetIsHidden(true, new WidgetPointer(16,37)); + setWidgetIsHidden(true, new WidgetPointer(16,4)); + setWidgetIsHidden(true, new WidgetPointer(16,18)); + setWidgetIsHidden(true, new WidgetPointer(16,64)); + setWidgetIsHidden(false, new WidgetPointer(16,76)); + GOTO flow_6 + flow_3: + setWidgetIsHidden(false, new WidgetPointer(16,1)); + setWidgetIsHidden(false, new WidgetPointer(16,52)); + setWidgetIsHidden(true, new WidgetPointer(16,59)); + setWidgetIsHidden(false, new WidgetPointer(16,37)); + setWidgetIsHidden(true, new WidgetPointer(16,4)); + setWidgetIsHidden(true, new WidgetPointer(16,18)); + setWidgetIsHidden(true, new WidgetPointer(16,64)); + setWidgetIsHidden(true, new WidgetPointer(16,76)); + GOTO flow_6 + flow_4: + setWidgetIsHidden(false, new WidgetPointer(16,1)); + setWidgetIsHidden(false, new WidgetPointer(16,52)); + setWidgetIsHidden(true, new WidgetPointer(16,59)); + setWidgetIsHidden(false, new WidgetPointer(16,37)); + setWidgetIsHidden(false, new WidgetPointer(16,4)); + setWidgetIsHidden(false, new WidgetPointer(16,18)); + setWidgetIsHidden(true, new WidgetPointer(16,64)); + setWidgetIsHidden(true, new WidgetPointer(16,76)); + GOTO flow_6 + flow_5: + setWidgetIsHidden(false, new WidgetPointer(16,1)); + setWidgetIsHidden(false, new WidgetPointer(16,52)); + setWidgetIsHidden(true, new WidgetPointer(16,59)); + setWidgetIsHidden(false, new WidgetPointer(16,37)); + setWidgetIsHidden(false, new WidgetPointer(16,4)); + setWidgetIsHidden(false, new WidgetPointer(16,18)); + setWidgetIsHidden(false, new WidgetPointer(16,64)); + setWidgetIsHidden(true, new WidgetPointer(16,76)); + flow_6: + return; +} diff --git a/dumps/scripts/4603.cs2 b/dumps/scripts/4603.cs2 new file mode 100644 index 0000000..4b542b5 --- /dev/null +++ b/dumps/scripts/4603.cs2 @@ -0,0 +1,4 @@ +void script_4603(int arg0) { + globalint_1497 = arg0; + return; +} diff --git a/dumps/scripts/4604.cs2 b/dumps/scripts/4604.cs2 new file mode 100644 index 0000000..cb2590b --- /dev/null +++ b/dumps/scripts/4604.cs2 @@ -0,0 +1,27 @@ +void script_4604(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + setWidgetRGB(new Color(getColorRelatedMethod4020(standart_config_2174)), new WidgetPointer(arg2)); + ivar3 = getWidgetActualHeight(new WidgetPointer(arg1)); + ivar4 = 1; + if (bitconfig_9258 > 0) { + ivar4 = max(min(subtract(ivar3, multiply(bitconfig_9258, 2)), ivar3), 0); + } + script_4610(ivar4); + ivar5 = getWidgetActualHeight(new WidgetPointer(arg0)); + ivar6 = 0; + if (bitconfig_9259 > 0) { + ivar6 = max(min(subtract(ivar5, multiply(bitconfig_9259, divide(ivar5, 8))), ivar5), 0); + ivar6 = max(min(subtract(ivar6, divide(ivar5, 16)), ivar5), 0); + } + ivar7 = 0; + if (bitconfig_9260 > 0) { + ivar7 = max(min(multiply(bitconfig_9260, divide(ivar5, 128)), ivar5), 0); + } + setWidgetRGB(new Color(bitconfig_9258), new WidgetPointer(arg0)); + script_4609(ivar7, ivar6); + return; +} diff --git a/dumps/scripts/4605.cs2 b/dumps/scripts/4605.cs2 new file mode 100644 index 0000000..22c77c2 --- /dev/null +++ b/dumps/scripts/4605.cs2 @@ -0,0 +1,11 @@ +void script_4605(int arg0,int arg1,int arg2,int arg3,int arg4) { + int ivar5; + int ivar6; + ivar5 = getWidgetActualHeight(new WidgetPointer(arg1)); + ivar6 = divide(multiply(subtract(ivar5, arg4), 64), ivar5); + setWidgetRGB(new Color(ivar6), new WidgetPointer(arg0)); + bitconfig_9258 = mod(ivar6, 64); + script_4610(arg4); + setWidgetRGB(new Color(getColorRelatedMethod4020(standart_config_2174)), new WidgetPointer(arg2)); + return; +} diff --git a/dumps/scripts/4606.cs2 b/dumps/scripts/4606.cs2 new file mode 100644 index 0000000..573d7b5 --- /dev/null +++ b/dumps/scripts/4606.cs2 @@ -0,0 +1,13 @@ +void script_4606(int arg0,int arg1,int arg2,int arg3,int arg4) { + int ivar5; + int ivar6; + int ivar7; + ivar5 = getWidgetActualHeight(new WidgetPointer(arg0)); + ivar6 = divide(multiply(subtract(ivar5, arg4), 8), ivar5); + ivar7 = divide(multiply(arg3, 128), getWidgetActualWidth(new WidgetPointer(arg0))); + bitconfig_9259 = mod(ivar6, 8); + bitconfig_9260 = mod(ivar7, 128); + script_4609(arg3, arg4); + setWidgetRGB(new Color(getColorRelatedMethod4020(standart_config_2174)), new WidgetPointer(arg2)); + return; +} diff --git a/dumps/scripts/4607.cs2 b/dumps/scripts/4607.cs2 new file mode 100644 index 0000000..9ab14af --- /dev/null +++ b/dumps/scripts/4607.cs2 @@ -0,0 +1,4 @@ +void script_4607() { + sendColorPickerPacket(standart_config_2174); + return; +} diff --git a/dumps/scripts/4608.cs2 b/dumps/scripts/4608.cs2 new file mode 100644 index 0000000..02dae6d --- /dev/null +++ b/dumps/scripts/4608.cs2 @@ -0,0 +1,4 @@ +void script_4608() { + sendColorPickerPacket(globalint_1497); + return; +} diff --git a/dumps/scripts/4609.cs2 b/dumps/scripts/4609.cs2 new file mode 100644 index 0000000..6e0314f --- /dev/null +++ b/dumps/scripts/4609.cs2 @@ -0,0 +1,4 @@ +void script_4609(int arg0,int arg1) { + setWidgetPosition(arg0, arg1, 0, 0, new WidgetPointer(19,20)); + return; +} diff --git a/dumps/scripts/461.cs2 b/dumps/scripts/461.cs2 new file mode 100644 index 0000000..6737174 --- /dev/null +++ b/dumps/scripts/461.cs2 @@ -0,0 +1,4 @@ +void script_461() { + script_304(53415011); + return; +} diff --git a/dumps/scripts/4610.cs2 b/dumps/scripts/4610.cs2 new file mode 100644 index 0000000..126bfe7 --- /dev/null +++ b/dumps/scripts/4610.cs2 @@ -0,0 +1,4 @@ +void script_4610(int arg0) { + setWidgetPosition(0, add(arg0, 1), 0, 0, new WidgetPointer(19,19)); + return; +} diff --git a/dumps/scripts/4611.cs2 b/dumps/scripts/4611.cs2 new file mode 100644 index 0000000..10de266 --- /dev/null +++ b/dumps/scripts/4611.cs2 @@ -0,0 +1,5 @@ +void script_4611() { + setScriptCallOnConfigChange(4612, new WidgetPointer(20,55), 2172, 2173, 2174, 3, "IY", new WidgetPointer(20,55)); + script_4613(1310775); + return; +} diff --git a/dumps/scripts/4612.cs2 b/dumps/scripts/4612.cs2 new file mode 100644 index 0000000..449f793 --- /dev/null +++ b/dumps/scripts/4612.cs2 @@ -0,0 +1,4 @@ +void script_4612(int arg0) { + script_4613(arg0); + return; +} diff --git a/dumps/scripts/4613.cs2 b/dumps/scripts/4613.cs2 new file mode 100644 index 0000000..6857348 --- /dev/null +++ b/dumps/scripts/4613.cs2 @@ -0,0 +1,10 @@ +void script_4613(int arg0) { + if ((((boolean)bitconfig_9254) && ((boolean)bitconfig_9255)) && (((boolean)bitconfig_9256) && ((boolean)bitconfig_9257))) { + return; + } + doWidgetType18Task(0, 65214, bitconfig_9254, new WidgetPointer(arg0)); + doWidgetType18Task(1, 65200, bitconfig_9255, new WidgetPointer(arg0)); + doWidgetType18Task(3, 65186, bitconfig_9256, new WidgetPointer(arg0)); + doWidgetType18Task(4, 62995, bitconfig_9257, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/4614.cs2 b/dumps/scripts/4614.cs2 new file mode 100644 index 0000000..1c0b368 --- /dev/null +++ b/dumps/scripts/4614.cs2 @@ -0,0 +1,16 @@ +void script_4614(int arg0) { + switch (arg0) { + case 1310722: + setWidgetRGB(new Color(getColorRelatedMethod4020(bitconfig_9254)), new WidgetPointer(arg0)); + break; + case 1310728: + setWidgetRGB(new Color(getColorRelatedMethod4020(bitconfig_9255)), new WidgetPointer(arg0)); + break; + case 1310731: + setWidgetRGB(new Color(getColorRelatedMethod4020(bitconfig_9256)), new WidgetPointer(arg0)); + break; + case 1310725: + setWidgetRGB(new Color(getColorRelatedMethod4020(bitconfig_9257)), new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/4615.cs2 b/dumps/scripts/4615.cs2 new file mode 100644 index 0000000..4a7b615 --- /dev/null +++ b/dumps/scripts/4615.cs2 @@ -0,0 +1,40 @@ +void script_4615(int arg0) { + switch (arg0) { + case 1310735: + setWidgetRGB(new Color(getColorRelatedMethod4020(bitconfig_9255)), new WidgetPointer(arg0)); + break; + case 1310875: + setWidgetRGB(new Color(getColorRelatedMethod4020(bitconfig_9254)), new WidgetPointer(arg0)); + break; + case 1310889: + setWidgetRGB(new Color(getColorRelatedMethod4020(bitconfig_9254)), new WidgetPointer(arg0)); + break; + case 1310903: + setWidgetRGB(new Color(getColorRelatedMethod4020(bitconfig_9254)), new WidgetPointer(arg0)); + break; + case 1310737: + setWidgetRGB(new Color(getColorRelatedMethod4020(bitconfig_9256)), new WidgetPointer(arg0)); + break; + case 1310877: + setWidgetRGB(new Color(getColorRelatedMethod4020(bitconfig_9256)), new WidgetPointer(arg0)); + break; + case 1310891: + setWidgetRGB(new Color(getColorRelatedMethod4020(bitconfig_9255)), new WidgetPointer(arg0)); + break; + case 1310905: + setWidgetRGB(new Color(getColorRelatedMethod4020(bitconfig_9255)), new WidgetPointer(arg0)); + break; + case 1310739: + setWidgetRGB(new Color(getColorRelatedMethod4020(bitconfig_9257)), new WidgetPointer(arg0)); + break; + case 1310879: + setWidgetRGB(new Color(getColorRelatedMethod4020(bitconfig_9257)), new WidgetPointer(arg0)); + break; + case 1310893: + setWidgetRGB(new Color(getColorRelatedMethod4020(bitconfig_9257)), new WidgetPointer(arg0)); + break; + case 1310907: + setWidgetRGB(new Color(getColorRelatedMethod4020(bitconfig_9256)), new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/4616.cs2 b/dumps/scripts/4616.cs2 new file mode 100644 index 0000000..aae54aa --- /dev/null +++ b/dumps/scripts/4616.cs2 @@ -0,0 +1,12 @@ +int script_4616(int arg0,int arg1) { + int ivar2; + ivar2 = 0; + ivar2 = script_4617(arg0, arg1); + if (ivar2 == getMinute()) { + return 0; + } + if (ivar2 > getMinute()) { + return 1; + } + return -1; +} diff --git a/dumps/scripts/4617.cs2 b/dumps/scripts/4617.cs2 new file mode 100644 index 0000000..192f8c1 --- /dev/null +++ b/dumps/scripts/4617.cs2 @@ -0,0 +1,15 @@ +int script_4617(int arg0,int arg1) { + int ivar2; + int ivar3; + int stack_dump0; + int stack_dump1; + cs2func_script_4618_struct(2,0,0) structdump_2; + ivar2 = arg0; + ivar3 = arg1; + stack_dump0 = arg0; + stack_dump1 = arg1; + structdump_2 = script_4618(stack_dump0, stack_dump1); + ivar3 = structdump_2.intpart_1; + ivar2 = structdump_2.intpart_0; + return add(daysSinceReleaseToMillis(ivar2), ivar3); +} diff --git a/dumps/scripts/4618.cs2 b/dumps/scripts/4618.cs2 new file mode 100644 index 0000000..4d34909 --- /dev/null +++ b/dumps/scripts/4618.cs2 @@ -0,0 +1,31 @@ +cs2func_script_4618_struct(2,0,0) script_4618(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + if (((boolean)arg0)) { + return newstruct cs2func_script_4618_struct(0, 0); + } + ivar2 = arg0; + ivar3 = arg1; + ivar4 = 0; + if (((boolean)clanbitconfig_5)) { + ivar4 = max(clanconfig_0, subtract(0, clanconfig_0)); + } + ivar3 = add(multiply(divide(arg1, 10), 60), multiply(mod(arg1, 10), 10)); + if (((boolean)clanbitconfig_5)) { + if (clanconfig_0 < 0) { + if (add(ivar3, ivar4) >= 1440) { + ivar2 = add(ivar2, 1); + ivar3 = subtract(add(ivar3, ivar4), 1440); + } else { + ivar3 = add(ivar3, ivar4); + } + } else if (subtract(ivar3, ivar4) < 0) { + ivar2 = subtract(ivar2, 1); + ivar3 = subtract(add(1440, arg1), ivar4); + } else { + ivar3 = subtract(ivar3, ivar4); + } + } + return newstruct cs2func_script_4618_struct(ivar2, ivar3); +} diff --git a/dumps/scripts/4619.cs2 b/dumps/scripts/4619.cs2 new file mode 100644 index 0000000..1d1ff59 --- /dev/null +++ b/dumps/scripts/4619.cs2 @@ -0,0 +1,61 @@ +void script_4619(int arg0) { + switch (standart_config_2128) { + case 1: + if (((boolean)bitconfig_9261)) { + bitconfig_9261 = 1; + } else { + bitconfig_9261 = 0; + } + break; + case 2: + if (((boolean)bitconfig_9262)) { + bitconfig_9262 = 1; + } else { + bitconfig_9262 = 0; + } + break; + case 3: + if (((boolean)bitconfig_9263)) { + bitconfig_9263 = 1; + } else { + bitconfig_9263 = 0; + } + break; + case 4: + if (((boolean)bitconfig_9264)) { + bitconfig_9264 = 1; + } else { + bitconfig_9264 = 0; + } + break; + case 5: + if (((boolean)bitconfig_9265)) { + bitconfig_9265 = 1; + } else { + bitconfig_9265 = 0; + } + break; + case 6: + if (((boolean)bitconfig_9266)) { + bitconfig_9266 = 1; + } else { + bitconfig_9266 = 0; + } + break; + case 7: + if (((boolean)bitconfig_9267)) { + bitconfig_9267 = 1; + } else { + bitconfig_9267 = 0; + } + break; + case 8: + if (((boolean)bitconfig_9268)) { + bitconfig_9268 = 1; + } else { + bitconfig_9268 = 0; + } + } + script_4621(arg0); + return; +} diff --git a/dumps/scripts/462.cs2 b/dumps/scripts/462.cs2 new file mode 100644 index 0000000..ef8fb16 --- /dev/null +++ b/dumps/scripts/462.cs2 @@ -0,0 +1,10 @@ +void script_462(int arg0) { + if (getSkillActualLvl(1) < 25) { + setWidgetText(new WidgetPointer(arg0), "" + "A Defence level of " + intToStr(25) + " is required." + ""); + } else if (bitconfig_2086 < 1) { + setWidgetText(new WidgetPointer(arg0), "" + "1 Commendation required." + ""); + } else { + setWidgetText(new WidgetPointer(arg0), intToStr(multiply(divide(pow(getSkillActualLvl(1), 2), 600), 35)) + " XP per Commendation."); + } + return; +} diff --git a/dumps/scripts/4620.cs2 b/dumps/scripts/4620.cs2 new file mode 100644 index 0000000..60b7dba --- /dev/null +++ b/dumps/scripts/4620.cs2 @@ -0,0 +1,4 @@ +void script_4620(int arg0) { + script_4621(arg0); + return; +} diff --git a/dumps/scripts/4621.cs2 b/dumps/scripts/4621.cs2 new file mode 100644 index 0000000..f4282be --- /dev/null +++ b/dumps/scripts/4621.cs2 @@ -0,0 +1,60 @@ +void script_4621(int arg0) { + switch (standart_config_2128) { + case 1: + if (((boolean)bitconfig_9261)) { + setWidgetSprite(5920, new WidgetPointer(arg0)); + } else { + setWidgetSprite(5916, new WidgetPointer(arg0)); + } + break; + case 2: + if (((boolean)bitconfig_9262)) { + setWidgetSprite(5920, new WidgetPointer(arg0)); + } else { + setWidgetSprite(5916, new WidgetPointer(arg0)); + } + break; + case 3: + if (((boolean)bitconfig_9263)) { + setWidgetSprite(5920, new WidgetPointer(arg0)); + } else { + setWidgetSprite(5916, new WidgetPointer(arg0)); + } + break; + case 4: + if (((boolean)bitconfig_9264)) { + setWidgetSprite(5920, new WidgetPointer(arg0)); + } else { + setWidgetSprite(5916, new WidgetPointer(arg0)); + } + break; + case 5: + if (((boolean)bitconfig_9265)) { + setWidgetSprite(5920, new WidgetPointer(arg0)); + } else { + setWidgetSprite(5916, new WidgetPointer(arg0)); + } + break; + case 6: + if (((boolean)bitconfig_9266)) { + setWidgetSprite(5920, new WidgetPointer(arg0)); + } else { + setWidgetSprite(5916, new WidgetPointer(arg0)); + } + break; + case 7: + if (((boolean)bitconfig_9267)) { + setWidgetSprite(5920, new WidgetPointer(arg0)); + } else { + setWidgetSprite(5916, new WidgetPointer(arg0)); + } + break; + case 8: + if (((boolean)bitconfig_9268)) { + setWidgetSprite(5920, new WidgetPointer(arg0)); + } else { + setWidgetSprite(5916, new WidgetPointer(arg0)); + } + } + return; +} diff --git a/dumps/scripts/4622.cs2 b/dumps/scripts/4622.cs2 new file mode 100644 index 0000000..c8aae63 --- /dev/null +++ b/dumps/scripts/4622.cs2 @@ -0,0 +1,7 @@ +void script_4622(int arg0) { + if (getWidgetSpriteId(new WidgetPointer(arg0)) == 5936) { + return; + } + setWidgetSprite(5933, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/4623.cs2 b/dumps/scripts/4623.cs2 new file mode 100644 index 0000000..468f445 --- /dev/null +++ b/dumps/scripts/4623.cs2 @@ -0,0 +1,4 @@ +void script_4623(int arg0,int arg1) { + script_4624(arg0, arg1); + return; +} diff --git a/dumps/scripts/4624.cs2 b/dumps/scripts/4624.cs2 new file mode 100644 index 0000000..630a266 --- /dev/null +++ b/dumps/scripts/4624.cs2 @@ -0,0 +1,11 @@ +void script_4624(int arg0,int arg1) { + if (getWidgetSpriteId(new WidgetPointer(arg0)) == 5936) { + return; + } + if (arg1 == standart_config_2128) { + setWidgetSprite(5935, new WidgetPointer(arg0)); + } else { + setWidgetSprite(5932, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/4625.cs2 b/dumps/scripts/4625.cs2 new file mode 100644 index 0000000..c2b9f54 --- /dev/null +++ b/dumps/scripts/4625.cs2 @@ -0,0 +1,8 @@ +void script_4625() { + if ((stringMethod4107(globalstring_353, "") != 0) && (stringMethod4107(globalstring_353, "null") != 0)) { + globalstring_354 = globalstring_353; + } else { + globalstring_354 = ""; + } + return; +} diff --git a/dumps/scripts/4626.cs2 b/dumps/scripts/4626.cs2 new file mode 100644 index 0000000..0473a37 --- /dev/null +++ b/dumps/scripts/4626.cs2 @@ -0,0 +1,4 @@ +void script_4626() { + script_304(35673632); + return; +} diff --git a/dumps/scripts/4627.cs2 b/dumps/scripts/4627.cs2 new file mode 100644 index 0000000..8d37e3d --- /dev/null +++ b/dumps/scripts/4627.cs2 @@ -0,0 +1,4 @@ +void script_4627() { + script_4628(); + return; +} diff --git a/dumps/scripts/4628.cs2 b/dumps/scripts/4628.cs2 new file mode 100644 index 0000000..2e74fc9 --- /dev/null +++ b/dumps/scripts/4628.cs2 @@ -0,0 +1,8 @@ +void script_4628() { + globalint_1518 = -1; + globalstring_126 = ""; + if (setWidgetRegister(new WidgetPointer(1110,20))) { + setScriptCallOnGameloop(4629, 0, "i"); + } + return; +} diff --git a/dumps/scripts/4629.cs2 b/dumps/scripts/4629.cs2 new file mode 100644 index 0000000..0642a05 --- /dev/null +++ b/dumps/scripts/4629.cs2 @@ -0,0 +1,22 @@ +void script_4629(int arg0) { + int ivar1; + ivar1 = 0; + if (setWidgetRegister(new WidgetPointer(1110,20))) { + if (((boolean)arg0)) { + ivar1 = add(getWidgetActualWidth(), 3); + ivar1 = min(31, ivar1); + if (ivar1 == 31) { + setScriptCallOnGameloop(-1, ""); + } + } else { + ivar1 = subtract(getWidgetActualWidth(), 3); + ivar1 = max(1, ivar1); + if (((boolean)ivar1)) { + setScriptCallOnGameloop(-1, ""); + setWidgetIsHidden(true, new WidgetPointer(1110,13)); + } + } + setWidgetSize(ivar1, 19, 0, 0); + } + return; +} diff --git a/dumps/scripts/463.cs2 b/dumps/scripts/463.cs2 new file mode 100644 index 0000000..9e30262 --- /dev/null +++ b/dumps/scripts/463.cs2 @@ -0,0 +1,10 @@ +void script_463(int arg0) { + if (getSkillActualLvl(3) < 25) { + setWidgetText(new WidgetPointer(arg0), "" + "A Constitution level of " + intToStr(25) + " is required." + ""); + } else if (bitconfig_2086 < 1) { + setWidgetText(new WidgetPointer(arg0), "" + "1 Commendation required." + ""); + } else { + setWidgetText(new WidgetPointer(arg0), intToStr(multiply(divide(pow(getSkillActualLvl(3), 2), 600), 35)) + " XP per Commendation."); + } + return; +} diff --git a/dumps/scripts/4630.cs2 b/dumps/scripts/4630.cs2 new file mode 100644 index 0000000..1c2e300 --- /dev/null +++ b/dumps/scripts/4630.cs2 @@ -0,0 +1,4 @@ +void script_4630() { + script_4465(globalstring_126); + return; +} diff --git a/dumps/scripts/4631.cs2 b/dumps/scripts/4631.cs2 new file mode 100644 index 0000000..cd034ef --- /dev/null +++ b/dumps/scripts/4631.cs2 @@ -0,0 +1,4 @@ +void script_4631() { + script_4632(globalint_1519); + return; +} diff --git a/dumps/scripts/4632.cs2 b/dumps/scripts/4632.cs2 new file mode 100644 index 0000000..2b616eb --- /dev/null +++ b/dumps/scripts/4632.cs2 @@ -0,0 +1,107 @@ +void script_4632(int arg0) { + int ivar1; + int ivar2; + int ivar3; + string svar0; + string svar1; + string svar2; + string svar3; + string svar4; + string svar5; + ivar1 = -1; + ivar2 = -1; + svar0 = ""; + svar1 = ""; + svar2 = ""; + svar3 = ""; + svar4 = ""; + svar5 = ""; + if (globalint_1520 > 2000000) { + svar1 = "over " + formatNumber(2000000, 1); + } else { + svar1 = formatNumber(globalint_1520, 1); + } + ivar1 = min(2147483647, divide(divide(multiply(1000, globalint_1520), max(1, globalint_1521)), 1000)); + ivar2 = mod(divide(multiply(1000, globalint_1520), max(1, globalint_1521)), 1000); + if (((boolean)ivar2)) { + svar0 = intToStr(ivar1); + } else { + svar0 = concat(intToStr(ivar1), "."); + if (ivar2 < 100) { + svar0 = concat(svar0, "0"); + } + if (ivar2 < 10) { + svar0 = concat(svar0, "0"); + } + svar0 = concat(svar0, intToStr(ivar2)); + if (((boolean)mod(ivar2, 10))) { + svar0 = substr(0, subtract(strLength(svar0), 2), svar0); + } + if (((boolean)mod(ivar2, 100))) { + svar0 = substr(0, subtract(strLength(svar0), 2), svar0); + } + } + svar3 = formatNumber(globalint_1522, 1); + if (((boolean)arg0)) { + if (globalint_1520 > 2000) { + svar5 = "Behold " + globalstring_127 + ", champion of " + svar1 + " bouts in the Duel Arena!"; + } else if (((boolean)globalint_1520)) { + svar5 = "Here stands " + globalstring_127 + ", once victor of a duel."; + } else { + svar5 = "Here stands " + globalstring_127 + ", victor of " + svar1 + " duels."; + } + svar2 = globalstring_127 + " defeats " + svar0 + " opponents for every loss!"; + if (globalint_1522 > 250) { + svar3 = "over " + formatNumber(250, 1); + } + svar4 = globalstring_127 + " has vanquished " + formatNumber(globalint_1522, 1) + " opponents in a row."; + } else { + if (((boolean)arg0)) { + if (globalint_1520 > 2000) { + svar5 = "Behold " + globalstring_127 + ", taker of " + svar1 + " heads in the Wilderness!"; + } else { + svar5 = "Here stands " + globalstring_127 + ", who has killed " + svar1 + " opponents in the Wilderness."; + } + svar2 = "Vanquisher of " + svar0 + " foes for every fall!"; + if (globalint_1522 > 250) { + svar3 = "Over " + formatNumber(250, 1); + } + svar4 = svar3 + " victims in succession have rendered their souls to " + globalstring_127 + "."; + } + } + setWidgetText(new WidgetPointer(21,1), svar5); + setWidgetText(new WidgetPointer(21,3), svar4); + setWidgetText(new WidgetPointer(21,2), svar2); + setWidgetText(new WidgetPointer(21,4), "Highest value Wilderness kill:" + "
" + formatNumber(standart_config_2185, 1) + " coins."); + setWidgetIsHidden(false, new WidgetPointer(21,18)); + setWidgetIsHidden(false, new WidgetPointer(21,49)); + setWidgetIsHidden(true, new WidgetPointer(21,2)); + setWidgetIsHidden(true, new WidgetPointer(21,3)); + if (((boolean)globalint_1524)) { + setWidgetIsHidden(false, new WidgetPointer(21,2)); + if (globalint_1522 > 1) { + setWidgetIsHidden(false, new WidgetPointer(21,3)); + } + } + setWidgetIsHidden(true, new WidgetPointer(21,4)); + if (((boolean)arg0) && (standart_config_2185 > 0)) { + setWidgetIsHidden(false, new WidgetPointer(21,4)); + } + ivar3 = getWidgetActualHeight(new WidgetPointer(21,17)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(21,18)), getWidgetActualY(new WidgetPointer(21,4)), 0, 0, new WidgetPointer(21,18)); + if (isWidgetHidden(new WidgetPointer(21,4))) { + setWidgetIsHidden(true, new WidgetPointer(21,18)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(21,3)), 0, 0, 2, new WidgetPointer(21,3)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(21,2)), getWidgetActualHeight(new WidgetPointer(21,3)), 0, 2, new WidgetPointer(21,2)); + } else { + ivar3 = subtract(ivar3, getWidgetActualHeight(new WidgetPointer(21,4))); + } + setWidgetPosition(getWidgetActualX(new WidgetPointer(21,18)), getWidgetActualY(new WidgetPointer(21,2)), 0, 0, new WidgetPointer(21,49)); + if (isWidgetHidden(new WidgetPointer(21,3))) { + ivar3 = subtract(ivar3, add(getWidgetActualHeight(new WidgetPointer(21,3)), getWidgetActualHeight(new WidgetPointer(21,2)))); + } else { + setWidgetIsHidden(true, new WidgetPointer(21,49)); + } + setWidgetSize(getWidgetActualWidth(new WidgetPointer(21,1)), ivar3, 0, 0, new WidgetPointer(21,1)); + return; +} diff --git a/dumps/scripts/4633.cs2 b/dumps/scripts/4633.cs2 new file mode 100644 index 0000000..ea06da6 --- /dev/null +++ b/dumps/scripts/4633.cs2 @@ -0,0 +1,4 @@ +void script_4633() { + script_4634(1); + return; +} diff --git a/dumps/scripts/4634.cs2 b/dumps/scripts/4634.cs2 new file mode 100644 index 0000000..09d4c7e --- /dev/null +++ b/dumps/scripts/4634.cs2 @@ -0,0 +1,57 @@ +void script_4634(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + ivar1 = -1; + script_1174(11); + switch (arg0) { + case 1: + ivar1 = 0; + } + globalint_1100 = -1; + ivar2 = 0; + ivar3 = 0; + ivar4 = 0; + ivar5 = 0; + if ((((boolean)cs2method5420()) && ((boolean)script_2727())) && ((boolean)globalint_547)) { + globalint_174 = 12; + setWidgetIsHidden(false, new WidgetPointer(744,28)); + playMusicEffect(349, 0); + script_3412(48758826, 48758827); + ivar4 = getWidgetActualWidth(new WidgetPointer(744,43)); + ivar5 = getWidgetActualWidth(new WidgetPointer(744,43)); + ivar2 = max(337, add(getTextWidth(591, getWidgetText(new WidgetPointer(744,42))), 31)); + ivar5 = max(152, multiply(getLineCount(ivar4, 496, getWidgetText(new WidgetPointer(744,43))), 16)); + ivar3 = max(252, add(ivar5, 100)); + setWidgetSize(ivar4, ivar5, 0, 0, new WidgetPointer(744,43)); + setWidgetSize(ivar2, ivar3, 0, 0, new WidgetPointer(744,28)); + setWidgetIsHidden(true, new WidgetPointer(744,26)); + setWidgetIsHidden(true, new WidgetPointer(744,27)); + return; + } + globalint_200 = 0; + globalint_201 = 0; + ivar6 = 39059516; + ivar7 = 39059501; + if (hasSSKey()) { + ivar6 = 63897649; + ivar7 = 63897644; + } + setWidgetText(new WidgetPointer(ivar6), "Logging in..."); + setScriptCallOnMousePressed(-1, "", new WidgetPointer(ivar7)); + script_2950(-3, 0, 1, -1, 1, 1, 0, "Logging In - Please Wait", "Abort Login", ""); + setScriptCallOnMousePressed(4635, "", new WidgetPointer(596,15)); + setWidgetIsHidden(false, new WidgetPointer(596,9)); + globalint_1100 = -3; + cs2method5632(ivar1); + if (hasSSKey()) { + setScriptCallOnGameloop(2946, arg0, "i", new WidgetPointer(975,26)); + } else { + setScriptCallOnGameloop(2946, arg0, "i", new WidgetPointer(596,7)); + } + return; +} diff --git a/dumps/scripts/4635.cs2 b/dumps/scripts/4635.cs2 new file mode 100644 index 0000000..0535d99 --- /dev/null +++ b/dumps/scripts/4635.cs2 @@ -0,0 +1,4 @@ +void script_4635() { + script_4636(); + return; +} diff --git a/dumps/scripts/4636.cs2 b/dumps/scripts/4636.cs2 new file mode 100644 index 0000000..9d7e567 --- /dev/null +++ b/dumps/scripts/4636.cs2 @@ -0,0 +1,24 @@ +void script_4636() { + int ivar0; + int ivar1; + int ivar2; + ivar0 = 39059516; + ivar1 = 39059501; + ivar2 = 39059515; + if (hasSSKey()) { + ivar0 = 63897649; + ivar1 = 63897644; + } + setWidgetText(new WidgetPointer(ivar0), "Log In"); + setWidgetText(new WidgetPointer(ivar2), "Log In"); + setScriptCallOnMousePressed(2944, "", new WidgetPointer(ivar1)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(ivar1)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(596,7)); + if (isLoggingIn()) { + cancelLogin(); + } + resetRCs(); + script_2954(); + script_2940(13); + return; +} diff --git a/dumps/scripts/4637.cs2 b/dumps/scripts/4637.cs2 new file mode 100644 index 0000000..b39167f --- /dev/null +++ b/dumps/scripts/4637.cs2 @@ -0,0 +1,79 @@ +void script_4637(int arg0) { + int ivar1; + int ivar2; + string svar0; + svar0 = ""; + setWidgetIsHidden(false, new WidgetPointer(153,52)); + setWidgetText(new WidgetPointer(153,50), ""); + switch (arg0) { + case 1: + if (isWidgetHidden(new WidgetPointer(153,102))) { + return; + } + svar0 = "Three's Company" + "
" + "
"; + if (((boolean)script_4643(1))) { + svar0 = concat(svar0, "" + "Attack 30, Ranged 30, Magic 30 required to play the unabridged version." + "
" + "
"); + } + svar0 = concat(svar0, "Manage a party of adventurers in this saga. " + "
" + "
" + "+ Select 'Switch' to change to a target character. " + "
" + "+ Select 'Mark' on an enemy to focus your allies' attacks on that target." + "
" + "+ Human enemies will focus their attacks on you, animals will attack your allies."); + createExtraChild(new WidgetPointer(153,42), 4, 0); + break; + case 2: + if (isWidgetHidden(new WidgetPointer(153,115))) { + return; + } + svar0 = "Vengeance" + "
" + "
"; + if (((boolean)script_4643(2))) { + svar0 = concat(svar0, "" + "Agility 55, Thieving 55 required to play the unabridged version." + "
" + "
"); + } + svar0 = concat(svar0, "A tragic tale of grief, warped into furious vengeance." + "
" + "
" + "+ At some point in this saga, you will become poisoned. Keep an eye on your health. You will not take poison damage whilst in a conversation." + "
" + "+ Look for alternative methods of defeating your human foes. Your environment may offer more indirect solutions." + "
" + "+ Hellhounds will drop antipoison elixirs that will lessen your suffering temporarily." + "
" + "+ Spiders drop food, but their bites may negate the effect of an antipoison elixir." + "
" + "+ Choices you make in the saga will lead you towards 'noble' or 'ruthless' vengeance. Each has a different special attack. The further along that path you are, the more potent the special attack."); + break; + case 3: + if (isWidgetHidden(new WidgetPointer(153,141))) { + return; + } + svar0 = "Learn the story behind the lonely death of Tobias Scutter, adventurer."; + break; + case 4: + if (isWidgetHidden(new WidgetPointer(153,128))) { + return; + } + svar0 = "Thok It To 'Em" + "
" + "
"; + if (((boolean)script_4643(4))) { + svar0 = concat(svar0, "" + "Stregth 70 required to play the unabridged version." + "
" + "
"); + } + svar0 = concat(svar0, "Control mighty Thok, Fremennik warrior." + "
" + "
" + "+ Thok heals damage and recovers special attack by killing enemies. Bosses provide greater health and special attack boosts than normal enemies." + "
" + "+ Thok can eat food raw. He likes the taste." + "
" + "+ Thok will randomly choose a special attack when you perform one. These include the awe-inspiring 'Northern Kiss'."); + break; + case 5: + if (isWidgetHidden(new WidgetPointer(153,169))) { + return; + } + svar0 = "Love stories are so often tied to tragedy, and few are as tragic as this tale of two sorcerors."; + break; + case 6: + if (isWidgetHidden(new WidgetPointer(153,155))) { + return; + } + svar0 = "Sometimes it's good to be bad. The necrolord is a twisted and cruel individual with dark aspirations."; + } + setWidgetText(new WidgetPointer(153,44), svar0); + ivar1 = getLineCount(366, 495, svar0); + ivar2 = multiply(ivar1, 15); + if (setWidgetRegister(new WidgetPointer(153,42), 0)) { + if (((boolean)arg0)) { + setWidgetPosition(5, add(ivar2, 7), 0, 0); + setWidgetSize(366, 15, 0, 0); + setWidgetTextAlignment(1, 1, 0); + svar0 = "All three characters must survive."; + setWidgetText(svar0); + setWidgetFont(496); + setWidgetRGB(new Color(203, 107, 61)); + ivar2 = add(ivar2, 24); + } else { + deleteExtraChild(); + } + } + setWidgetScrollMax(0, ivar2, new WidgetPointer(153,42)); + script_72(10027051, 10027050, 0); + script_4638(arg0); + return; +} diff --git a/dumps/scripts/4638.cs2 b/dumps/scripts/4638.cs2 new file mode 100644 index 0000000..83b8306 --- /dev/null +++ b/dumps/scripts/4638.cs2 @@ -0,0 +1,28 @@ +void script_4638(int arg0) { + setWidgetIsHidden(true, new WidgetPointer(153,97)); + setWidgetIsHidden(true, new WidgetPointer(153,110)); + setWidgetIsHidden(true, new WidgetPointer(153,123)); + setWidgetIsHidden(true, new WidgetPointer(153,136)); + setWidgetIsHidden(true, new WidgetPointer(153,164)); + setWidgetIsHidden(true, new WidgetPointer(153,150)); + switch (arg0) { + case 1: + setWidgetIsHidden(false, new WidgetPointer(153,97)); + break; + case 2: + setWidgetIsHidden(false, new WidgetPointer(153,110)); + break; + case 4: + setWidgetIsHidden(false, new WidgetPointer(153,123)); + break; + case 3: + setWidgetIsHidden(false, new WidgetPointer(153,136)); + break; + case 5: + setWidgetIsHidden(false, new WidgetPointer(153,164)); + break; + case 6: + setWidgetIsHidden(false, new WidgetPointer(153,150)); + } + return; +} diff --git a/dumps/scripts/4639.cs2 b/dumps/scripts/4639.cs2 new file mode 100644 index 0000000..2944989 --- /dev/null +++ b/dumps/scripts/4639.cs2 @@ -0,0 +1,21 @@ +void script_4639() { + if (isBitFlagged(standart_config_2189, 1)) { + setWidgetIsHidden(false, new WidgetPointer(153,102)); + } + if (isBitFlagged(standart_config_2189, 2)) { + setWidgetIsHidden(false, new WidgetPointer(153,115)); + } + if (isBitFlagged(standart_config_2189, 3)) { + setWidgetIsHidden(false, new WidgetPointer(153,141)); + } + if (isBitFlagged(standart_config_2189, 4)) { + setWidgetIsHidden(false, new WidgetPointer(153,128)); + } + if (isBitFlagged(standart_config_2189, 5)) { + setWidgetIsHidden(false, new WidgetPointer(153,169)); + } + if (isBitFlagged(standart_config_2189, 6)) { + setWidgetIsHidden(false, new WidgetPointer(153,155)); + } + return; +} diff --git a/dumps/scripts/464.cs2 b/dumps/scripts/464.cs2 new file mode 100644 index 0000000..e7ad4a4 --- /dev/null +++ b/dumps/scripts/464.cs2 @@ -0,0 +1,10 @@ +void script_464(int arg0) { + if (getSkillActualLvl(4) < 25) { + setWidgetText(new WidgetPointer(arg0), "" + "A Ranged level of " + intToStr(25) + " is required." + ""); + } else if (bitconfig_2086 < 1) { + setWidgetText(new WidgetPointer(arg0), "" + "1 Commendation required." + ""); + } else { + setWidgetText(new WidgetPointer(arg0), intToStr(multiply(divide(pow(getSkillActualLvl(4), 2), 600), 32)) + " XP per Commendation."); + } + return; +} diff --git a/dumps/scripts/4640.cs2 b/dumps/scripts/4640.cs2 new file mode 100644 index 0000000..99e884d --- /dev/null +++ b/dumps/scripts/4640.cs2 @@ -0,0 +1,18 @@ +void script_4640(int arg0) { + if (((boolean)arg0)) { + setWidgetSprite(4601, new WidgetPointer(153,66)); + setWidgetSprite(4601, new WidgetPointer(153,68)); + setWidgetSprite(4600, new WidgetPointer(153,67)); + setWidgetSprite(4607, new WidgetPointer(153,70)); + setWidgetSprite(4607, new WidgetPointer(153,69)); + setWidgetSprite(4606, new WidgetPointer(153,71)); + } else { + setWidgetSprite(4595, new WidgetPointer(153,66)); + setWidgetSprite(4595, new WidgetPointer(153,68)); + setWidgetSprite(4594, new WidgetPointer(153,67)); + setWidgetSprite(4605, new WidgetPointer(153,70)); + setWidgetSprite(4605, new WidgetPointer(153,69)); + setWidgetSprite(4604, new WidgetPointer(153,71)); + } + return; +} diff --git a/dumps/scripts/4641.cs2 b/dumps/scripts/4641.cs2 new file mode 100644 index 0000000..6e74c91 --- /dev/null +++ b/dumps/scripts/4641.cs2 @@ -0,0 +1,25 @@ +void script_4641() { + script_4639(); + if (isBitFlagged(standart_config_2189, 1)) { + setWidgetSprite(6268, new WidgetPointer(153,15)); + setScriptCallOnClickContextMenu(4637, 1, "i", new WidgetPointer(153,98)); + script_4645(1); + } else { + setWidgetSprite(6271, new WidgetPointer(153,15)); + } + if (isBitFlagged(standart_config_2189, 2)) { + setWidgetSprite(6270, new WidgetPointer(153,12)); + setScriptCallOnClickContextMenu(4637, 2, "i", new WidgetPointer(153,111)); + script_4645(2); + } else { + setWidgetSprite(6271, new WidgetPointer(153,12)); + } + if (isBitFlagged(standart_config_2189, 4)) { + setWidgetSprite(6269, new WidgetPointer(153,9)); + setScriptCallOnClickContextMenu(4637, 4, "i", new WidgetPointer(153,124)); + script_4645(4); + } else { + setWidgetSprite(6271, new WidgetPointer(153,9)); + } + return; +} diff --git a/dumps/scripts/4642.cs2 b/dumps/scripts/4642.cs2 new file mode 100644 index 0000000..10ef194 --- /dev/null +++ b/dumps/scripts/4642.cs2 @@ -0,0 +1,23 @@ +void script_4642() { + string svar0; + if (((boolean)standart_config_2192)) { + return; + } + svar0 = "null"; + switch (standart_config_2192) { + case 1: + svar0 = "Abridged: 750 Dungeoneering XP. 75 Dungeoneering tokens." + "
" + "Unabridged: 3750 XP in a choice of Attack, Ranged or Magic."; + break; + case 2: + svar0 = "Abridged: 2410 Dungeoneering XP. 241 Dungeoneering tokens." + "
" + "Unabridged: 25415 XP in either Agility or Thieving."; + break; + case 4: + svar0 = "Abridged: 37080 Dungeoneering XP. 3708 Dungeoneering tokens." + "
" + "Unabridged: 75765 Strength XP."; + break; + default: + return; + } + setWidgetIsHidden(true, new WidgetPointer(153,52)); + setWidgetText(new WidgetPointer(153,50), svar0); + return; +} diff --git a/dumps/scripts/4643.cs2 b/dumps/scripts/4643.cs2 new file mode 100644 index 0000000..7947af1 --- /dev/null +++ b/dumps/scripts/4643.cs2 @@ -0,0 +1,27 @@ +int script_4643(int arg0) { + flow_0: + SWITCH (arg0) { + case 1: + GOTO flow_1 + case 4: + GOTO flow_7 + case 2: + GOTO flow_11 + } + return 0; + flow_1: + if (((getSkillActualLvl(0) >= 30) && (getSkillActualLvl(6) >= 30)) && (getSkillActualLvl(4) >= 30)) { + return 1; + } + return 0; + flow_7: + if (getSkillActualLvl(2) >= 70) { + return 1; + } + return 0; + flow_11: + if ((getSkillActualLvl(16) >= 55) && (getSkillActualLvl(17) >= 55)) { + return 1; + } + return 0; +} diff --git a/dumps/scripts/4644.cs2 b/dumps/scripts/4644.cs2 new file mode 100644 index 0000000..0a2f6b9 --- /dev/null +++ b/dumps/scripts/4644.cs2 @@ -0,0 +1,37 @@ +cs2func_script_4644_struct(2,0,0) script_4644(int arg0) { + flow_0: + SWITCH (arg0) { + case 1: + GOTO flow_1 + case 2: + GOTO flow_6 + case 4: + GOTO flow_11 + } + return newstruct cs2func_script_4644_struct(0, 0); + flow_1: + if (((boolean)bitconfig_9315)) { + if (((boolean)bitconfig_9314)) { + return newstruct cs2func_script_4644_struct(1, 1); + } + return newstruct cs2func_script_4644_struct(1, 0); + } + GOTO flow_15 + flow_6: + if (((boolean)bitconfig_9317)) { + if (((boolean)bitconfig_9316)) { + return newstruct cs2func_script_4644_struct(1, 1); + } + return newstruct cs2func_script_4644_struct(1, 0); + } + GOTO flow_15 + flow_11: + if (((boolean)bitconfig_9319)) { + if (((boolean)bitconfig_9318)) { + return newstruct cs2func_script_4644_struct(1, 1); + } + return newstruct cs2func_script_4644_struct(1, 0); + } + flow_15: + return newstruct cs2func_script_4644_struct(0, 0); +} diff --git a/dumps/scripts/4645.cs2 b/dumps/scripts/4645.cs2 new file mode 100644 index 0000000..7044b08 --- /dev/null +++ b/dumps/scripts/4645.cs2 @@ -0,0 +1,81 @@ +void script_4645(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int stack_dump0; + cs2func_script_4644_struct(2,0,0) structdump_1; + flow_0: + ivar1 = -1; + ivar2 = -1; + ivar3 = 0; + ivar4 = 0; + stack_dump0 = arg0; + structdump_1 = script_4644(stack_dump0); + ivar4 = structdump_1.intpart_1; + ivar3 = structdump_1.intpart_0; + SWITCH (arg0) { + case 1: + GOTO flow_1 + case 2: + GOTO flow_2 + case 4: + GOTO flow_3 + case 3: + GOTO flow_4 + case 6: + GOTO flow_5 + case 5: + GOTO flow_6 + } + return; + flow_1: + ivar1 = 10027024; + ivar2 = 10027179; + GOTO flow_7 + flow_2: + ivar1 = 10027021; + ivar2 = 10027022; + GOTO flow_7 + flow_3: + ivar1 = 10027018; + ivar2 = 10027019; + GOTO flow_7 + flow_4: + ivar1 = 10027015; + ivar2 = 10027016; + GOTO flow_7 + flow_5: + ivar1 = 10027012; + ivar2 = 10027013; + GOTO flow_7 + flow_6: + ivar1 = 10027009; + ivar2 = 10027010; + flow_7: + if (((boolean)script_4643(arg0))) { + if (((boolean)ivar3)) { + if (((boolean)ivar4)) { + setWidgetSprite(6274, new WidgetPointer(ivar1)); + setWidgetIsHidden(false, new WidgetPointer(ivar1)); + setWidgetSprite(6275, new WidgetPointer(ivar2)); + setWidgetIsHidden(false, new WidgetPointer(ivar2)); + } else { + setWidgetSprite(6272, new WidgetPointer(ivar1)); + setWidgetIsHidden(false, new WidgetPointer(ivar1)); + setWidgetSprite(6275, new WidgetPointer(ivar2)); + setWidgetIsHidden(false, new WidgetPointer(ivar2)); + } + } else { + setWidgetSprite(6272, new WidgetPointer(ivar1)); + setWidgetIsHidden(false, new WidgetPointer(ivar1)); + } + } else if (((boolean)ivar3)) { + setWidgetSprite(6275, new WidgetPointer(ivar1)); + setWidgetIsHidden(false, new WidgetPointer(ivar1)); + } else { + setWidgetSprite(6273, new WidgetPointer(ivar1)); + setWidgetIsHidden(false, new WidgetPointer(ivar1)); + } + return; +} diff --git a/dumps/scripts/4646.cs2 b/dumps/scripts/4646.cs2 new file mode 100644 index 0000000..45c349e --- /dev/null +++ b/dumps/scripts/4646.cs2 @@ -0,0 +1,22 @@ +void script_4646() { + flow_0: + SWITCH (bitconfig_9306) { + case 1: + GOTO flow_1 + case 2: + GOTO flow_2 + case 4: + GOTO flow_3 + } + return; + flow_1: + script_4647(); + GOTO flow_4 + flow_2: + script_4648(); + GOTO flow_4 + flow_3: + script_4649(); + flow_4: + return; +} diff --git a/dumps/scripts/4647.cs2 b/dumps/scripts/4647.cs2 new file mode 100644 index 0000000..2d4366b --- /dev/null +++ b/dumps/scripts/4647.cs2 @@ -0,0 +1,124 @@ +void script_4647() { + setWidgetIsHidden(true, new WidgetPointer(173,2)); + setWidgetIsHidden(true, new WidgetPointer(173,3)); + setWidgetIsHidden(false, new WidgetPointer(173,1)); + setWidgetIsHidden(false, new WidgetPointer(173,62)); + setWidgetIsHidden(false, new WidgetPointer(173,63)); + if (isBitFlagged(standart_config_2194, 0)) { + setWidgetIsHidden(false, new WidgetPointer(173,64)); + } else { + setWidgetIsHidden(false, new WidgetPointer(173,64)); + setWidgetSprite(2808, new WidgetPointer(173,64)); + } + if (isBitFlagged(standart_config_2194, 1)) { + setWidgetIsHidden(false, new WidgetPointer(173,66)); + } else if (isBitFlagged(standart_config_2194, 0)) { + setWidgetIsHidden(false, new WidgetPointer(173,66)); + setWidgetSprite(2808, new WidgetPointer(173,66)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,66)); + } + if (isBitFlagged(standart_config_2194, 2)) { + setWidgetIsHidden(false, new WidgetPointer(173,67)); + } else if (isBitFlagged(standart_config_2194, 1)) { + setWidgetIsHidden(false, new WidgetPointer(173,67)); + setWidgetSprite(2807, new WidgetPointer(173,67)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,67)); + } + if (isBitFlagged(standart_config_2194, 3)) { + setWidgetIsHidden(false, new WidgetPointer(173,68)); + } else if (isBitFlagged(standart_config_2194, 2)) { + setWidgetIsHidden(false, new WidgetPointer(173,68)); + setWidgetSprite(2807, new WidgetPointer(173,68)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,68)); + } + if (isBitFlagged(standart_config_2194, 4)) { + setWidgetIsHidden(false, new WidgetPointer(173,69)); + } else if (isBitFlagged(standart_config_2194, 3)) { + setWidgetIsHidden(false, new WidgetPointer(173,69)); + setWidgetSprite(2806, new WidgetPointer(173,69)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,69)); + } + if (isBitFlagged(standart_config_2194, 5)) { + setWidgetIsHidden(false, new WidgetPointer(173,72)); + } else { + setWidgetSprite(2807, new WidgetPointer(173,72)); + } + if (isBitFlagged(standart_config_2194, 6)) { + setWidgetIsHidden(false, new WidgetPointer(173,73)); + } else if (isBitFlagged(standart_config_2194, 5)) { + setWidgetIsHidden(false, new WidgetPointer(173,73)); + setWidgetSprite(2808, new WidgetPointer(173,73)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,73)); + } + if (isBitFlagged(standart_config_2194, 7)) { + setWidgetIsHidden(false, new WidgetPointer(173,65)); + } else { + setWidgetSprite(2806, new WidgetPointer(173,65)); + } + if (isBitFlagged(standart_config_2194, 8)) { + setWidgetIsHidden(false, new WidgetPointer(173,74)); + } else if (isBitFlagged(standart_config_2194, 7)) { + setWidgetIsHidden(false, new WidgetPointer(173,74)); + setWidgetSprite(2807, new WidgetPointer(173,74)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,74)); + } + if (isBitFlagged(standart_config_2194, 9)) { + setWidgetIsHidden(false, new WidgetPointer(173,75)); + } else if (isBitFlagged(standart_config_2194, 8)) { + setWidgetIsHidden(false, new WidgetPointer(173,75)); + setWidgetSprite(2807, new WidgetPointer(173,75)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,75)); + } + if (isBitFlagged(standart_config_2194, 10)) { + setWidgetIsHidden(false, new WidgetPointer(173,77)); + } else if (isBitFlagged(standart_config_2194, 9)) { + setWidgetIsHidden(false, new WidgetPointer(173,77)); + setWidgetSprite(2807, new WidgetPointer(173,77)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,77)); + } + if (isBitFlagged(standart_config_2194, 11)) { + setWidgetIsHidden(false, new WidgetPointer(173,78)); + } else if (isBitFlagged(standart_config_2194, 9)) { + setWidgetIsHidden(false, new WidgetPointer(173,78)); + setWidgetSprite(2808, new WidgetPointer(173,78)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,78)); + } + if (isBitFlagged(standart_config_2194, 12)) { + setWidgetIsHidden(false, new WidgetPointer(173,79)); + } else if (isBitFlagged(standart_config_2194, 11)) { + setWidgetIsHidden(false, new WidgetPointer(173,79)); + setWidgetSprite(2807, new WidgetPointer(173,79)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,79)); + } + if (isBitFlagged(standart_config_2194, 13)) { + setWidgetIsHidden(false, new WidgetPointer(173,76)); + } else if (isBitFlagged(standart_config_2194, 9)) { + setWidgetIsHidden(false, new WidgetPointer(173,76)); + setWidgetSprite(2806, new WidgetPointer(173,76)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,76)); + } + if (isBitFlagged(standart_config_2194, 14)) { + setWidgetIsHidden(false, new WidgetPointer(173,70)); + setWidgetIsHidden(false, new WidgetPointer(173,71)); + } else if (isBitFlagged(standart_config_2194, 7)) { + setWidgetIsHidden(false, new WidgetPointer(173,70)); + setWidgetSprite(2806, new WidgetPointer(173,70)); + setWidgetIsHidden(true, new WidgetPointer(173,71)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,70)); + setWidgetIsHidden(true, new WidgetPointer(173,71)); + } + script_4653(); + return; +} diff --git a/dumps/scripts/4648.cs2 b/dumps/scripts/4648.cs2 new file mode 100644 index 0000000..66af6e9 --- /dev/null +++ b/dumps/scripts/4648.cs2 @@ -0,0 +1,91 @@ +void script_4648() { + setWidgetIsHidden(true, new WidgetPointer(173,1)); + setWidgetIsHidden(true, new WidgetPointer(173,3)); + setWidgetIsHidden(false, new WidgetPointer(173,2)); + setWidgetIsHidden(false, new WidgetPointer(173,42)); + setWidgetIsHidden(false, new WidgetPointer(173,58)); + if (isBitFlagged(standart_config_2194, 1)) { + setWidgetIsHidden(false, new WidgetPointer(173,43)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,43)); + } + if (isBitFlagged(standart_config_2194, 2)) { + setWidgetIsHidden(false, new WidgetPointer(173,44)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,44)); + } + if (isBitFlagged(standart_config_2194, 3)) { + setWidgetIsHidden(false, new WidgetPointer(173,45)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,45)); + } + if (isBitFlagged(standart_config_2194, 4)) { + setWidgetIsHidden(false, new WidgetPointer(173,46)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,46)); + } + if (isBitFlagged(standart_config_2194, 5)) { + setWidgetIsHidden(false, new WidgetPointer(173,47)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,47)); + } + if (isBitFlagged(standart_config_2194, 6)) { + setWidgetIsHidden(false, new WidgetPointer(173,48)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,48)); + } + if (isBitFlagged(standart_config_2194, 7)) { + setWidgetIsHidden(false, new WidgetPointer(173,49)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,49)); + } + if (isBitFlagged(standart_config_2194, 8)) { + setWidgetIsHidden(false, new WidgetPointer(173,51)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,51)); + } + if (isBitFlagged(standart_config_2194, 9)) { + setWidgetIsHidden(false, new WidgetPointer(173,50)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,50)); + } + if (isBitFlagged(standart_config_2194, 10)) { + setWidgetIsHidden(false, new WidgetPointer(173,52)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,52)); + } + if (isBitFlagged(standart_config_2194, 11)) { + setWidgetIsHidden(false, new WidgetPointer(173,56)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,56)); + } + if (isBitFlagged(standart_config_2194, 12)) { + setWidgetIsHidden(false, new WidgetPointer(173,55)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,55)); + } + if (isBitFlagged(standart_config_2194, 13)) { + setWidgetIsHidden(false, new WidgetPointer(173,54)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,54)); + } + if (isBitFlagged(standart_config_2194, 14)) { + setWidgetIsHidden(false, new WidgetPointer(173,53)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,53)); + } + if (isBitFlagged(standart_config_2194, 15)) { + setWidgetIsHidden(false, new WidgetPointer(173,60)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,60)); + } + if (isBitFlagged(standart_config_2194, 16)) { + setWidgetIsHidden(false, new WidgetPointer(173,57)); + setWidgetIsHidden(false, new WidgetPointer(173,59)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,57)); + setWidgetIsHidden(true, new WidgetPointer(173,59)); + } + script_4653(); + return; +} diff --git a/dumps/scripts/4649.cs2 b/dumps/scripts/4649.cs2 new file mode 100644 index 0000000..3eeecc6 --- /dev/null +++ b/dumps/scripts/4649.cs2 @@ -0,0 +1,22 @@ +void script_4649() { + flow_0: + SWITCH (bitconfig_9367) { + case 1: + GOTO flow_1 + case 2: + GOTO flow_2 + case 3: + GOTO flow_3 + } + return; + flow_1: + script_4650(); + GOTO flow_4 + flow_2: + script_4652(); + GOTO flow_4 + flow_3: + script_4651(); + flow_4: + return; +} diff --git a/dumps/scripts/465.cs2 b/dumps/scripts/465.cs2 new file mode 100644 index 0000000..ddbc6fb --- /dev/null +++ b/dumps/scripts/465.cs2 @@ -0,0 +1,4 @@ +void script_465() { + script_304(46966115); + return; +} diff --git a/dumps/scripts/4650.cs2 b/dumps/scripts/4650.cs2 new file mode 100644 index 0000000..41c8b8c --- /dev/null +++ b/dumps/scripts/4650.cs2 @@ -0,0 +1,10 @@ +void script_4650() { + setWidgetIsHidden(true, new WidgetPointer(173,1)); + setWidgetIsHidden(true, new WidgetPointer(173,2)); + setWidgetIsHidden(false, new WidgetPointer(173,3)); + setWidgetIsHidden(true, new WidgetPointer(173,8)); + setWidgetIsHidden(true, new WidgetPointer(173,9)); + setWidgetIsHidden(false, new WidgetPointer(173,4)); + script_4653(); + return; +} diff --git a/dumps/scripts/4651.cs2 b/dumps/scripts/4651.cs2 new file mode 100644 index 0000000..8aa5809 --- /dev/null +++ b/dumps/scripts/4651.cs2 @@ -0,0 +1,10 @@ +void script_4651() { + setWidgetIsHidden(true, new WidgetPointer(173,1)); + setWidgetIsHidden(true, new WidgetPointer(173,2)); + setWidgetIsHidden(false, new WidgetPointer(173,3)); + setWidgetIsHidden(true, new WidgetPointer(173,4)); + setWidgetIsHidden(true, new WidgetPointer(173,9)); + setWidgetIsHidden(false, new WidgetPointer(173,8)); + script_4653(); + return; +} diff --git a/dumps/scripts/4652.cs2 b/dumps/scripts/4652.cs2 new file mode 100644 index 0000000..cee833b --- /dev/null +++ b/dumps/scripts/4652.cs2 @@ -0,0 +1,124 @@ +void script_4652() { + setWidgetIsHidden(true, new WidgetPointer(173,1)); + setWidgetIsHidden(true, new WidgetPointer(173,2)); + setWidgetIsHidden(false, new WidgetPointer(173,3)); + setWidgetIsHidden(true, new WidgetPointer(173,4)); + setWidgetIsHidden(true, new WidgetPointer(173,8)); + setWidgetIsHidden(false, new WidgetPointer(173,9)); + setWidgetIsHidden(false, new WidgetPointer(173,10)); + setWidgetIsHidden(false, new WidgetPointer(173,33)); + if (isBitFlagged(standart_config_2194, 0)) { + setWidgetIsHidden(false, new WidgetPointer(173,11)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,11)); + } + if (isBitFlagged(standart_config_2194, 1)) { + setWidgetIsHidden(false, new WidgetPointer(173,12)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,12)); + } + if (isBitFlagged(standart_config_2194, 2)) { + setWidgetIsHidden(false, new WidgetPointer(173,15)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,15)); + } + if (isBitFlagged(standart_config_2194, 3)) { + setWidgetIsHidden(false, new WidgetPointer(173,16)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,16)); + } + if (isBitFlagged(standart_config_2194, 4)) { + setWidgetIsHidden(false, new WidgetPointer(173,17)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,17)); + } + if (isBitFlagged(standart_config_2194, 5)) { + setWidgetIsHidden(false, new WidgetPointer(173,18)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,18)); + } + if (isBitFlagged(standart_config_2194, 6)) { + setWidgetIsHidden(false, new WidgetPointer(173,19)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,19)); + } + if (isBitFlagged(standart_config_2194, 7)) { + setWidgetIsHidden(false, new WidgetPointer(173,20)); + setWidgetIsHidden(false, new WidgetPointer(173,34)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,20)); + setWidgetIsHidden(true, new WidgetPointer(173,34)); + } + if (isBitFlagged(standart_config_2194, 8)) { + setWidgetIsHidden(false, new WidgetPointer(173,21)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,21)); + } + if (isBitFlagged(standart_config_2194, 9)) { + setWidgetIsHidden(false, new WidgetPointer(173,22)); + setWidgetIsHidden(false, new WidgetPointer(173,35)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,22)); + setWidgetIsHidden(true, new WidgetPointer(173,35)); + } + if (isBitFlagged(standart_config_2194, 10)) { + setWidgetIsHidden(false, new WidgetPointer(173,23)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,23)); + } + if (isBitFlagged(standart_config_2194, 11)) { + setWidgetIsHidden(false, new WidgetPointer(173,24)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,24)); + } + if (isBitFlagged(standart_config_2194, 12)) { + setWidgetIsHidden(false, new WidgetPointer(173,25)); + setWidgetIsHidden(false, new WidgetPointer(173,26)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,25)); + setWidgetIsHidden(true, new WidgetPointer(173,26)); + } + if (isBitFlagged(standart_config_2194, 13)) { + setWidgetIsHidden(false, new WidgetPointer(173,27)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,27)); + } + if (isBitFlagged(standart_config_2194, 14)) { + setWidgetIsHidden(false, new WidgetPointer(173,28)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,28)); + } + if (isBitFlagged(standart_config_2194, 15)) { + setWidgetIsHidden(false, new WidgetPointer(173,31)); + setWidgetIsHidden(false, new WidgetPointer(173,36)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,31)); + setWidgetIsHidden(true, new WidgetPointer(173,36)); + } + if (isBitFlagged(standart_config_2194, 16)) { + setWidgetIsHidden(false, new WidgetPointer(173,29)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,29)); + } + if (isBitFlagged(standart_config_2194, 17)) { + setWidgetIsHidden(false, new WidgetPointer(173,30)); + setWidgetIsHidden(false, new WidgetPointer(173,37)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,30)); + setWidgetIsHidden(true, new WidgetPointer(173,37)); + } + if (isBitFlagged(standart_config_2194, 18)) { + setWidgetIsHidden(false, new WidgetPointer(173,13)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,13)); + } + if (isBitFlagged(standart_config_2194, 19)) { + setWidgetIsHidden(false, new WidgetPointer(173,14)); + setWidgetIsHidden(false, new WidgetPointer(173,32)); + } else { + setWidgetIsHidden(true, new WidgetPointer(173,14)); + setWidgetIsHidden(true, new WidgetPointer(173,32)); + } + script_4653(); + return; +} diff --git a/dumps/scripts/4653.cs2 b/dumps/scripts/4653.cs2 new file mode 100644 index 0000000..0c27f26 --- /dev/null +++ b/dumps/scripts/4653.cs2 @@ -0,0 +1,7 @@ +void script_4653() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + return; +} diff --git a/dumps/scripts/4654.cs2 b/dumps/scripts/4654.cs2 new file mode 100644 index 0000000..63cf017 --- /dev/null +++ b/dumps/scripts/4654.cs2 @@ -0,0 +1,33 @@ +void script_4654(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + if ((arg0 == -1) || (arg1 == -1)) { + return; + } + ivar3 = 0; + ivar4 = 0; + ivar5 = 11337808; + if (((boolean)bitconfig_9306)) { + ivar5 = 11337808; + } + if (bitconfig_9306 == 2) { + ivar5 = 11337789; + } + if (bitconfig_9306 == 4) { + if (((boolean)bitconfig_9367)) { + ivar5 = 11337735; + } + if (bitconfig_9367 == 2) { + ivar5 = 11337766; + } + if (bitconfig_9367 == 3) { + ivar5 = 11337769; + } + } + createExtraChild(new WidgetPointer(ivar5), 5, 0); + setWidgetSprite(2825); + setWidgetPosition(add(add(multiply(arg0, 32), 10), ivar3), add(add(multiply(arg1, 32), 10), ivar4), 0, 2); + setWidgetSize(11, 11, 0, 0); + return; +} diff --git a/dumps/scripts/4655.cs2 b/dumps/scripts/4655.cs2 new file mode 100644 index 0000000..0a4d87a --- /dev/null +++ b/dumps/scripts/4655.cs2 @@ -0,0 +1,12 @@ +void script_4655() { + int ivar0; + setWidgetText(new WidgetPointer(77,14), globalstring_315); + if (globalint_1233 > 200) { + globalint_1233 = 200; + } + ivar0 = globalint_1233; + ivar0 = add(divide(multiply(ivar0, 37), 40), 14); + setWidgetSize(ivar0, 18, 1, 0, new WidgetPointer(77,16)); + setWidgetPosition(add(ivar0, 1), 15, 0, 0, new WidgetPointer(77,17)); + return; +} diff --git a/dumps/scripts/4656.cs2 b/dumps/scripts/4656.cs2 new file mode 100644 index 0000000..d4ae06b --- /dev/null +++ b/dumps/scripts/4656.cs2 @@ -0,0 +1,6 @@ +void script_4656(int arg0) { + SWITCH (globalint_1532) { + } + cameraUnlock(); + return; +} diff --git a/dumps/scripts/4657.cs2 b/dumps/scripts/4657.cs2 new file mode 100644 index 0000000..57e61d5 --- /dev/null +++ b/dumps/scripts/4657.cs2 @@ -0,0 +1,14 @@ +void script_4657(int arg0) { + int ivar1; + ivar1 = script_284(getMyPositionHash()); + cs2method5405(0, 3); + cs2method5405(1, 3); + cs2method5406(0, 0, addToCoordinate(ivar1, 23, 0, 25), 700, addToCoordinate(ivar1, 23, 0, 25), 700, 0); + cs2method5406(1, 0, addToCoordinate(ivar1, 30, 0, 33), 400, addToCoordinate(ivar1, 30, 0, 22), 400, 0); + cs2method5406(0, 1, addToCoordinate(ivar1, 23, 0, 25), 700, addToCoordinate(ivar1, 23, 0, 25), 700, 0); + cs2method5406(1, 1, addToCoordinate(ivar1, 27, 0, 29), 500, addToCoordinate(ivar1, 27, 0, 29), 500, 0); + cs2method5406(0, 2, addToCoordinate(ivar1, 23, 0, 25), 700, addToCoordinate(ivar1, 23, 0, 25), 700, 0); + cs2method5406(1, 2, addToCoordinate(ivar1, 31, 0, 33), 400, addToCoordinate(ivar1, 31, 0, 33), 400, 0); + cameraMethod5502(0, 0, 1000000, 1000000, 1, 0); + return; +} diff --git a/dumps/scripts/4658.cs2 b/dumps/scripts/4658.cs2 new file mode 100644 index 0000000..2baaa62 --- /dev/null +++ b/dumps/scripts/4658.cs2 @@ -0,0 +1,12 @@ +void script_4658(int arg0) { + int ivar1; + ivar1 = divide(standart_config_2201, 3); + setWidgetText(new WidgetPointer(arg0), intToStr(standart_config_2201)); + script_4542(ivar1, 1441832, 1441837); + if (standart_config_2201 <= 100) { + setWidgetAnimation(9777, new WidgetPointer(22,2)); + } else { + setWidgetAnimation(9804, new WidgetPointer(22,2)); + } + return; +} diff --git a/dumps/scripts/4659.cs2 b/dumps/scripts/4659.cs2 new file mode 100644 index 0000000..a41cf87 --- /dev/null +++ b/dumps/scripts/4659.cs2 @@ -0,0 +1,12 @@ +void script_4659(int arg0) { + int ivar1; + ivar1 = divide(standart_config_2202, 3); + script_4542(ivar1, 1441856, 1441861); + setWidgetText(new WidgetPointer(arg0), intToStr(standart_config_2202)); + if (standart_config_2202 <= 100) { + setWidgetAnimation(9777, new WidgetPointer(22,70)); + } else { + setWidgetAnimation(9804, new WidgetPointer(22,70)); + } + return; +} diff --git a/dumps/scripts/466.cs2 b/dumps/scripts/466.cs2 new file mode 100644 index 0000000..f43681a --- /dev/null +++ b/dumps/scripts/466.cs2 @@ -0,0 +1,10 @@ +void script_466(int arg0) { + if (getSkillActualLvl(6) < 25) { + setWidgetText(new WidgetPointer(arg0), "" + "A Magic level of " + intToStr(25) + " is required." + ""); + } else if (bitconfig_2086 < 1) { + setWidgetText(new WidgetPointer(arg0), "" + "1 Commendation required." + ""); + } else { + setWidgetText(new WidgetPointer(arg0), intToStr(multiply(divide(pow(getSkillActualLvl(6), 2), 600), 32)) + " XP per Commendation."); + } + return; +} diff --git a/dumps/scripts/4660.cs2 b/dumps/scripts/4660.cs2 new file mode 100644 index 0000000..85e9ac5 --- /dev/null +++ b/dumps/scripts/4660.cs2 @@ -0,0 +1,12 @@ +void script_4660(int arg0) { + int ivar1; + ivar1 = divide(standart_config_2203, 3); + setWidgetText(new WidgetPointer(arg0), intToStr(standart_config_2203)); + script_4542(ivar1, 1441888, 1441893); + if (standart_config_2203 <= 100) { + setWidgetAnimation(9777, new WidgetPointer(22,0)); + } else { + setWidgetAnimation(9804, new WidgetPointer(22,0)); + } + return; +} diff --git a/dumps/scripts/4661.cs2 b/dumps/scripts/4661.cs2 new file mode 100644 index 0000000..a1ba3a0 --- /dev/null +++ b/dumps/scripts/4661.cs2 @@ -0,0 +1,50 @@ +cs2func_script_4661_struct(2,0,0) script_4661() { + flow_0: + SWITCH (standart_config_2192) { + case 0: + GOTO flow_1 + case 1: + GOTO flow_2 + case 2: + GOTO flow_3 + case 3: + GOTO flow_4 + case 4: + GOTO flow_5 + case 5: + GOTO flow_6 + case 6: + GOTO flow_7 + case 7: + GOTO flow_8 + case 8: + GOTO flow_9 + case 9: + GOTO flow_10 + case 10: + GOTO flow_11 + } + return newstruct cs2func_script_4661_struct(0, 0); + flow_1: + return newstruct cs2func_script_4661_struct(1, 5); + flow_2: + return newstruct cs2func_script_4661_struct(1, 4); + flow_3: + return newstruct cs2func_script_4661_struct(1, 3); + flow_4: + return newstruct cs2func_script_4661_struct(1, 2); + flow_5: + return newstruct cs2func_script_4661_struct(1, 1); + flow_6: + return newstruct cs2func_script_4661_struct(0, 0); + flow_7: + return newstruct cs2func_script_4661_struct(2, 1); + flow_8: + return newstruct cs2func_script_4661_struct(2, 2); + flow_9: + return newstruct cs2func_script_4661_struct(2, 3); + flow_10: + return newstruct cs2func_script_4661_struct(2, 4); + flow_11: + return newstruct cs2func_script_4661_struct(2, 5); +} diff --git a/dumps/scripts/4662.cs2 b/dumps/scripts/4662.cs2 new file mode 100644 index 0000000..2364d33 --- /dev/null +++ b/dumps/scripts/4662.cs2 @@ -0,0 +1,51 @@ +void script_4662(int arg0,int arg1) { + int ivar2; + int ivar3; + cs2func_script_4661_struct(2,0,0) structdump_0; + ivar2 = 0; + ivar3 = 0; + structdump_0 = script_4661(); + ivar3 = structdump_0.intpart_1; + ivar2 = structdump_0.intpart_0; + if (((boolean)ivar2) && (ivar3 >= 3)) { + switch (arg0) { + case 1507330: + setWidgetRGB(new Color(arg1), new WidgetPointer(arg0)); + break; + case 1507331: + setWidgetRGB(new Color(arg1), new WidgetPointer(arg0)); + break; + case 1507332: + return; + case 1507333: + return; + } + } else if ((ivar2 == 2) && (ivar3 >= 3)) { + switch (arg0) { + case 1507332: + setWidgetRGB(new Color(arg1), new WidgetPointer(arg0)); + break; + case 1507333: + setWidgetRGB(new Color(arg1), new WidgetPointer(arg0)); + break; + case 1507330: + return; + case 1507331: + return; + } + } else { + switch (arg0) { + case 1507331: + setWidgetRGB(new Color(arg1), new WidgetPointer(arg0)); + break; + case 1507332: + setWidgetRGB(new Color(arg1), new WidgetPointer(arg0)); + break; + case 1507330: + return; + case 1507333: + return; + } + } + return; +} diff --git a/dumps/scripts/4663.cs2 b/dumps/scripts/4663.cs2 new file mode 100644 index 0000000..b016a2b --- /dev/null +++ b/dumps/scripts/4663.cs2 @@ -0,0 +1,33 @@ +void script_4663(int arg0) { + flow_0: + SWITCH (globalint_1534) { + case 1: + GOTO flow_1 + case 2: + GOTO flow_2 + case 3: + GOTO flow_3 + case 4: + GOTO flow_4 + case 5: + GOTO flow_5 + } + cameraUnlock(); + GOTO flow_6 + flow_1: + script_4664(arg0); + GOTO flow_6 + flow_2: + script_4665(arg0); + GOTO flow_6 + flow_3: + script_4666(arg0); + GOTO flow_6 + flow_4: + script_4667(arg0); + GOTO flow_6 + flow_5: + script_4668(arg0); + flow_6: + return; +} diff --git a/dumps/scripts/4664.cs2 b/dumps/scripts/4664.cs2 new file mode 100644 index 0000000..49675dc --- /dev/null +++ b/dumps/scripts/4664.cs2 @@ -0,0 +1,12 @@ +void script_4664(int arg0) { + int ivar1; + ivar1 = script_284(getMyPositionHash()); + cs2method5405(0, 2); + cs2method5405(1, 2); + cs2method5406(0, 0, addToCoordinate(ivar1, 7, 0, 35), 700, addToCoordinate(ivar1, 7, 0, 35), 700, 0); + cs2method5406(1, 0, addToCoordinate(ivar1, 8, 0, 30), 500, addToCoordinate(ivar1, 8, 0, 30), 500, 0); + cs2method5406(0, 1, addToCoordinate(ivar1, 7, 0, 30), 900, addToCoordinate(ivar1, 7, 0, 30), 900, 0); + cs2method5406(1, 1, addToCoordinate(ivar1, 8, 0, 22), 400, addToCoordinate(ivar1, 8, 0, 22), 400, 0); + cameraMethod5502(0, 0, 100, 300, 1, 0); + return; +} diff --git a/dumps/scripts/4665.cs2 b/dumps/scripts/4665.cs2 new file mode 100644 index 0000000..7320048 --- /dev/null +++ b/dumps/scripts/4665.cs2 @@ -0,0 +1,12 @@ +void script_4665(int arg0) { + int ivar1; + ivar1 = script_284(getMyPositionHash()); + cs2method5405(0, 2); + cs2method5405(1, 2); + cs2method5406(0, 0, addToCoordinate(ivar1, 7, 0, 30), 900, addToCoordinate(ivar1, 7, 0, 30), 900, 0); + cs2method5406(1, 0, addToCoordinate(ivar1, 8, 0, 22), 400, addToCoordinate(ivar1, 8, 0, 22), 400, 0); + cs2method5406(0, 1, addToCoordinate(ivar1, 7, 0, 30), 700, addToCoordinate(ivar1, 7, 0, 30), 700, 0); + cs2method5406(1, 1, addToCoordinate(ivar1, 8, 0, 22), 200, addToCoordinate(ivar1, 8, 0, 22), 200, 0); + cameraMethod5502(0, 0, 200, 200, 1, 0); + return; +} diff --git a/dumps/scripts/4666.cs2 b/dumps/scripts/4666.cs2 new file mode 100644 index 0000000..f393478 --- /dev/null +++ b/dumps/scripts/4666.cs2 @@ -0,0 +1,16 @@ +void script_4666(int arg0) { + int ivar1; + ivar1 = script_284(getMyPositionHash()); + cs2method5405(0, 4); + cs2method5405(1, 4); + cs2method5406(0, 0, addToCoordinate(ivar1, 7, 0, 30), 700, addToCoordinate(ivar1, 7, 0, 30), 700, 0); + cs2method5406(1, 0, addToCoordinate(ivar1, 8, 0, 22), 200, addToCoordinate(ivar1, 8, 0, 22), 200, 0); + cs2method5406(0, 1, addToCoordinate(ivar1, 0, 0, 15), 800, addToCoordinate(ivar1, 0, 0, 15), 800, 0); + cs2method5406(1, 1, addToCoordinate(ivar1, 8, 0, 22), 300, addToCoordinate(ivar1, 8, 0, 22), 300, 0); + cs2method5406(0, 2, addToCoordinate(ivar1, 7, 0, 15), 600, addToCoordinate(ivar1, 7, 0, 15), 600, 0); + cs2method5406(1, 2, addToCoordinate(ivar1, 8, 0, 22), 100, addToCoordinate(ivar1, 8, 0, 22), 100, 0); + cs2method5406(0, 3, addToCoordinate(ivar1, 15, 0, 15), 800, addToCoordinate(ivar1, 15, 0, 15), 800, 0); + cs2method5406(1, 3, addToCoordinate(ivar1, 8, 0, 22), 300, addToCoordinate(ivar1, 8, 0, 22), 300, 0); + cameraMethod5502(0, 0, 100, 400, 1, 0); + return; +} diff --git a/dumps/scripts/4667.cs2 b/dumps/scripts/4667.cs2 new file mode 100644 index 0000000..b0aa011 --- /dev/null +++ b/dumps/scripts/4667.cs2 @@ -0,0 +1,4 @@ +void script_4667(int arg0) { + cameraMethod5502(0, 1, 100, 400, 1, 0); + return; +} diff --git a/dumps/scripts/4668.cs2 b/dumps/scripts/4668.cs2 new file mode 100644 index 0000000..2a9df39 --- /dev/null +++ b/dumps/scripts/4668.cs2 @@ -0,0 +1,4 @@ +void script_4668(int arg0) { + cameraMethod5502(0, 2, 100, 400, 1, 0); + return; +} diff --git a/dumps/scripts/4669.cs2 b/dumps/scripts/4669.cs2 new file mode 100644 index 0000000..9e91038 --- /dev/null +++ b/dumps/scripts/4669.cs2 @@ -0,0 +1,13 @@ +void script_4669(int arg0) { + flow_0: + SWITCH (globalint_1525) { + case 1: + GOTO flow_1 + } + cameraUnlock(); + GOTO flow_2 + flow_1: + script_4670(arg0); + flow_2: + return; +} diff --git a/dumps/scripts/467.cs2 b/dumps/scripts/467.cs2 new file mode 100644 index 0000000..0f2dcb7 --- /dev/null +++ b/dumps/scripts/467.cs2 @@ -0,0 +1,10 @@ +void script_467(int arg0) { + if (getSkillActualLvl(5) < 25) { + setWidgetText(new WidgetPointer(arg0), "" + "A Prayer level of " + intToStr(25) + " is required." + ""); + } else if (bitconfig_2086 < 1) { + setWidgetText(new WidgetPointer(arg0), "" + "1 Commendation required." + ""); + } else { + setWidgetText(new WidgetPointer(arg0), intToStr(multiply(divide(pow(getSkillActualLvl(5), 2), 600), 18)) + " XP per Commendation."); + } + return; +} diff --git a/dumps/scripts/4670.cs2 b/dumps/scripts/4670.cs2 new file mode 100644 index 0000000..ae92f7b --- /dev/null +++ b/dumps/scripts/4670.cs2 @@ -0,0 +1,12 @@ +void script_4670(int arg0) { + int ivar1; + ivar1 = script_284(addToCoordinate(getMyPositionHash(), -16, 0, 0)); + cs2method5405(0, 2); + cs2method5405(1, 2); + cs2method5406(0, 0, addToCoordinate(ivar1, 52, 0, 58), 700, addToCoordinate(ivar1, 52, 0, 58), 700, 0); + cs2method5406(1, 0, addToCoordinate(ivar1, 55, 0, 62), 500, addToCoordinate(ivar1, 55, 0, 62), 500, 0); + cs2method5406(0, 1, addToCoordinate(ivar1, 52, 0, 55), 900, addToCoordinate(ivar1, 52, 0, 55), 900, 0); + cs2method5406(1, 1, addToCoordinate(ivar1, 55, 0, 63), 400, addToCoordinate(ivar1, 55, 0, 63), 400, 0); + cameraMethod5502(0, 0, 100, 300, 1, 0); + return; +} diff --git a/dumps/scripts/4671.cs2 b/dumps/scripts/4671.cs2 new file mode 100644 index 0000000..14039bb --- /dev/null +++ b/dumps/scripts/4671.cs2 @@ -0,0 +1,13 @@ +void script_4671(int arg0) { + globalint_1526 = 0; + globalint_1527 = 0; + globalint_1528 = 0; + globalint_1529 = 0; + globalint_1530 = 0; + globalint_1531 = 0; + script_4672(bitconfig_9306); + script_4677(); + script_4673(bitconfig_9306); + setScriptCallOnGameloop(4675, "", new WidgetPointer(102,62)); + return; +} diff --git a/dumps/scripts/4672.cs2 b/dumps/scripts/4672.cs2 new file mode 100644 index 0000000..7ec4ecd --- /dev/null +++ b/dumps/scripts/4672.cs2 @@ -0,0 +1,17 @@ +void script_4672(int arg0) { + int ivar1; + ivar1 = -1; + switch (arg0) { + case 1: + ivar1 = 1823; + break; + case 2: + ivar1 = 55612; + setWidgetAnimation(9804, new WidgetPointer(102,54)); + break; + case 4: + ivar1 = 55626; + } + setWidgetModel(ivar1, new WidgetPointer(102,54)); + return; +} diff --git a/dumps/scripts/4673.cs2 b/dumps/scripts/4673.cs2 new file mode 100644 index 0000000..7e6c83c --- /dev/null +++ b/dumps/scripts/4673.cs2 @@ -0,0 +1,12 @@ +void script_4673(int arg0) { + if (arg0 != 2) { + setWidgetIsHidden(true, new WidgetPointer(102,60)); + setWidgetIsHidden(false, new WidgetPointer(102,61)); + setScriptCallOnGameloop(4674, "", new WidgetPointer(102,61)); + } else { + setWidgetIsHidden(true, new WidgetPointer(102,61)); + setWidgetIsHidden(false, new WidgetPointer(102,60)); + setScriptCallOnGameloop(4674, "", new WidgetPointer(102,60)); + } + return; +} diff --git a/dumps/scripts/4674.cs2 b/dumps/scripts/4674.cs2 new file mode 100644 index 0000000..120dcc7 --- /dev/null +++ b/dumps/scripts/4674.cs2 @@ -0,0 +1,104 @@ +void script_4674() { + int ivar0; + ivar0 = bitconfig_9306; + if (((globalint_1526 >= 20) && (globalint_1527 >= 30)) && ((globalint_1528 >= 40) && (globalint_1529 >= 50))) { + return; + } + if (globalint_1526 < 20) { + globalint_1526 = add(globalint_1526, 1); + } + if (globalint_1527 < 30) { + globalint_1527 = add(globalint_1527, 1); + } + if (globalint_1528 < 40) { + globalint_1528 = add(globalint_1528, 1); + } + if (globalint_1529 < 50) { + globalint_1529 = add(globalint_1529, 1); + } + switch (ivar0) { + case 1: + if (globalint_1526 >= 20) { + if (((boolean)bitconfig_9320)) { + setWidgetSprite(5917, new WidgetPointer(102,150)); + } else { + setWidgetSprite(5921, new WidgetPointer(102,150)); + } + } + if (globalint_1527 >= 30) { + if (((boolean)bitconfig_9321)) { + setWidgetSprite(5917, new WidgetPointer(102,151)); + } else { + setWidgetSprite(5921, new WidgetPointer(102,151)); + } + } + if (globalint_1528 >= 40) { + if (((boolean)bitconfig_9322)) { + setWidgetSprite(5917, new WidgetPointer(102,152)); + } else { + setWidgetSprite(5921, new WidgetPointer(102,152)); + } + } + if (globalint_1529 >= 50) { + if (((boolean)bitconfig_9323)) { + setWidgetSprite(5917, new WidgetPointer(102,153)); + } else { + setWidgetSprite(5921, new WidgetPointer(102,153)); + } + } + break; + case 4: + if (globalint_1526 >= 20) { + if (((boolean)bitconfig_9324)) { + setWidgetSprite(5917, new WidgetPointer(102,150)); + } else { + setWidgetSprite(5921, new WidgetPointer(102,150)); + } + } + if (globalint_1527 >= 30) { + if (((boolean)bitconfig_9325)) { + setWidgetSprite(5917, new WidgetPointer(102,151)); + } else { + setWidgetSprite(5921, new WidgetPointer(102,151)); + } + } + if (globalint_1528 >= 40) { + if (((boolean)bitconfig_9326)) { + setWidgetSprite(5917, new WidgetPointer(102,152)); + } else { + setWidgetSprite(5921, new WidgetPointer(102,152)); + } + } + if (globalint_1529 >= 50) { + if (((boolean)bitconfig_9327)) { + setWidgetSprite(5917, new WidgetPointer(102,153)); + } else { + setWidgetSprite(5921, new WidgetPointer(102,153)); + } + } + break; + case 2: + if (globalint_1526 >= 20) { + if (((boolean)bitconfig_9331)) { + setWidgetSprite(5917, new WidgetPointer(102,64)); + } else { + setWidgetSprite(5921, new WidgetPointer(102,64)); + } + } + if (globalint_1527 >= 30) { + if (((boolean)bitconfig_9333)) { + setWidgetSprite(5917, new WidgetPointer(102,148)); + } else { + setWidgetSprite(5921, new WidgetPointer(102,148)); + } + } + if (globalint_1528 >= 40) { + if (((boolean)bitconfig_9332)) { + setWidgetSprite(5917, new WidgetPointer(102,149)); + } else { + setWidgetSprite(5921, new WidgetPointer(102,149)); + } + } + } + return; +} diff --git a/dumps/scripts/4675.cs2 b/dumps/scripts/4675.cs2 new file mode 100644 index 0000000..735ea22 --- /dev/null +++ b/dumps/scripts/4675.cs2 @@ -0,0 +1,38 @@ +void script_4675() { + int ivar0; + int ivar1; + ivar0 = multiply(bitconfig_9298, 10); + ivar1 = 0; + if (globalint_1530 < ivar0) { + globalint_1530 = add(globalint_1530, 1); + playSoundEffect2False(5251, 1, 0, 255); + } + script_4542(globalint_1530, 6684772, 6684777); + switch (bitconfig_9306) { + case 1: + ivar1 = multiply(bitconfig_9308, 10); + break; + case 2: + ivar1 = multiply(bitconfig_9309, 10); + break; + case 3: + ivar1 = multiply(bitconfig_9310, 10); + break; + case 4: + ivar1 = multiply(bitconfig_9311, 10); + break; + case 5: + ivar1 = multiply(bitconfig_9312, 10); + break; + case 6: + ivar1 = multiply(bitconfig_9313, 10); + } + if ((globalint_1530 >= ivar0) && (globalint_1531 >= ivar1)) { + script_4676(bitconfig_9306); + } + if (globalint_1531 < ivar1) { + globalint_1531 = add(globalint_1531, 1); + } + script_4542(globalint_1531, 6684782, 6684787); + return; +} diff --git a/dumps/scripts/4676.cs2 b/dumps/scripts/4676.cs2 new file mode 100644 index 0000000..8e0d77e --- /dev/null +++ b/dumps/scripts/4676.cs2 @@ -0,0 +1,73 @@ +void script_4676(int arg0) { + switch (arg0) { + case 1: + if (((boolean)bitconfig_9314)) { + setWidgetIsHidden(true, new WidgetPointer(102,15)); + setWidgetIsHidden(true, new WidgetPointer(102,17)); + } else { + if (((bitconfig_9298 == 10) && (getSkillActualLvl(6) >= 30)) && ((getSkillActualLvl(4) >= 30) && (getSkillActualLvl(0) >= 30))) { + setWidgetIsHidden(false, new WidgetPointer(102,70)); + setWidgetIsHidden(false, new WidgetPointer(102,15)); + setWidgetIsHidden(false, new WidgetPointer(102,17)); + if (((boolean)bitconfig_9315)) { + setWidgetText(new WidgetPointer(102,70), "You receive two new books."); + } + } + } + if (((boolean)bitconfig_9315)) { + setWidgetIsHidden(true, new WidgetPointer(102,14)); + setWidgetIsHidden(true, new WidgetPointer(102,16)); + } else { + setWidgetIsHidden(false, new WidgetPointer(102,70)); + setWidgetIsHidden(false, new WidgetPointer(102,14)); + setWidgetIsHidden(false, new WidgetPointer(102,16)); + } + break; + case 2: + if (((boolean)bitconfig_9316)) { + setWidgetIsHidden(true, new WidgetPointer(102,15)); + setWidgetIsHidden(true, new WidgetPointer(102,17)); + } else { + if (((bitconfig_9298 == 10) && (getSkillActualLvl(16) >= 55)) && (getSkillActualLvl(17) >= 55)) { + setWidgetIsHidden(false, new WidgetPointer(102,70)); + setWidgetIsHidden(false, new WidgetPointer(102,15)); + setWidgetIsHidden(false, new WidgetPointer(102,17)); + if (((boolean)bitconfig_9317)) { + setWidgetText(new WidgetPointer(102,70), "You receive two new books."); + } + } + } + if (((boolean)bitconfig_9317)) { + setWidgetIsHidden(true, new WidgetPointer(102,14)); + setWidgetIsHidden(true, new WidgetPointer(102,16)); + } else { + setWidgetIsHidden(false, new WidgetPointer(102,70)); + setWidgetIsHidden(false, new WidgetPointer(102,14)); + setWidgetIsHidden(false, new WidgetPointer(102,16)); + } + break; + case 4: + if (((boolean)bitconfig_9318)) { + setWidgetIsHidden(true, new WidgetPointer(102,15)); + setWidgetIsHidden(true, new WidgetPointer(102,17)); + } else { + if ((bitconfig_9298 == 10) && (getSkillActualLvl(2) >= 70)) { + setWidgetIsHidden(false, new WidgetPointer(102,70)); + setWidgetIsHidden(false, new WidgetPointer(102,15)); + setWidgetIsHidden(false, new WidgetPointer(102,17)); + if (((boolean)bitconfig_9319)) { + setWidgetText(new WidgetPointer(102,70), "You receive two new books."); + } + } + } + if (((boolean)bitconfig_9319)) { + setWidgetIsHidden(true, new WidgetPointer(102,14)); + setWidgetIsHidden(true, new WidgetPointer(102,16)); + } else { + setWidgetIsHidden(false, new WidgetPointer(102,70)); + setWidgetIsHidden(false, new WidgetPointer(102,14)); + setWidgetIsHidden(false, new WidgetPointer(102,16)); + } + } + return; +} diff --git a/dumps/scripts/4677.cs2 b/dumps/scripts/4677.cs2 new file mode 100644 index 0000000..57da6db --- /dev/null +++ b/dumps/scripts/4677.cs2 @@ -0,0 +1,37 @@ +void script_4677() { + switch (bitconfig_9306) { + case 1: + if (bitconfig_9298 == 10) { + if (((getSkillActualLvl(6) >= 30) && (getSkillActualLvl(4) >= 30)) && (getSkillActualLvl(0) >= 30)) { + setWidgetText(new WidgetPointer(102,55), "Carn is no more, his behemoth has been dealt with, and Linza has her ore. The tales of Great Ozan can continue!"); + } else { + setWidgetText(new WidgetPointer(102,55), "Carn has been defeated and Linza appreciates her new ore. The story still feels incomplete, somehow."); + } + } else { + setWidgetText(new WidgetPointer(102,55), "Carn's defeated, but the story still feels incomplete somehow."); + } + break; + case 2: + if (bitconfig_9298 == 10) { + if ((getSkillActualLvl(16) >= 55) && (getSkillActualLvl(17) >= 55)) { + setWidgetText(new WidgetPointer(102,55), "I have become Vengeance: death to those who callously disregard life. They, and everyone like them, will pay for what they have done."); + } else { + setWidgetText(new WidgetPointer(102,55), "Am I done now? No, there's more that must be done. Vengeance has not yet been satisfied."); + } + } else { + setWidgetText(new WidgetPointer(102,55), "I killed them...but in doing so I never thought to check for survivors. Am I a monster?"); + } + break; + case 4: + if (bitconfig_9298 == 10) { + if (getSkillActualLvl(2) >= 70) { + setWidgetText(new WidgetPointer(102,55), "Ha! Thok stronger than squishy monsters in dungeon! None are as mighty as Thok."); + } else { + setWidgetText(new WidgetPointer(102,55), "Odd... Thok remember being much stronger in dungeon."); + } + } else { + setWidgetText(new WidgetPointer(102,55), "Thok save Marm, but Thok not show how mighty Thok is. Thok need to do more."); + } + } + return; +} diff --git a/dumps/scripts/4678.cs2 b/dumps/scripts/4678.cs2 new file mode 100644 index 0000000..c94f55b --- /dev/null +++ b/dumps/scripts/4678.cs2 @@ -0,0 +1,10 @@ +void script_4678(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + ivar2 = getWidgetActualWidth(new WidgetPointer(arg1)); + ivar3 = divide(ivar2, cs2method_3408(105, 105, 3840, bitconfig_9373)); + ivar4 = multiply(bitconfig_9376, ivar3); + setWidgetSize(ivar4, getWidgetActualHeight(new WidgetPointer(arg0)), 0, 0, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/4679.cs2 b/dumps/scripts/4679.cs2 new file mode 100644 index 0000000..7ccc8f7 --- /dev/null +++ b/dumps/scripts/4679.cs2 @@ -0,0 +1,11 @@ +void script_4679() { + if (cs2method_3408(105, 105, 3839, globalint_1535) < 1) { + setWidgetPosition(10, 26, 0, 0, new WidgetPointer(302,23)); + setWidgetIsHidden(true, new WidgetPointer(302,24)); + setWidgetText(new WidgetPointer(302,11), "Difficulty: " + intToStr(globalint_1535) + "/10"); + } else { + setWidgetIsHidden(false, new WidgetPointer(302,24)); + setWidgetText(new WidgetPointer(302,11), "Difficulty: " + intToStr(globalint_1535) + "/10"); + } + return; +} diff --git a/dumps/scripts/468.cs2 b/dumps/scripts/468.cs2 new file mode 100644 index 0000000..da36472 --- /dev/null +++ b/dumps/scripts/468.cs2 @@ -0,0 +1,16 @@ +void script_468(int arg0,int arg1) { + if (((((((getSkillActualLvl(0) < 42) || (getSkillActualLvl(2) < 42)) || (getSkillActualLvl(1) < 42)) || (getSkillActualLvl(3) < 42)) || (getSkillActualLvl(4) < 42)) || (getSkillActualLvl(6) < 42)) || (getSkillActualLvl(5) < 22)) { + setWidgetText(new WidgetPointer(arg0), "" + "Higher levels required...(show)" + ""); + return; + } + if ((arg0 == 66257161) && (standart_config_1875 < 1250)) { + setWidgetText(new WidgetPointer(arg0), "" + "1250 Conquest ranking required." + ""); + return; + } + if (bitconfig_2086 < arg1) { + setWidgetText(new WidgetPointer(arg0), "" + intToStr(arg1) + " Commendations required." + ""); + } else { + setWidgetText(new WidgetPointer(arg0), intToStr(arg1) + " Commendations."); + } + return; +} diff --git a/dumps/scripts/4680.cs2 b/dumps/scripts/4680.cs2 new file mode 100644 index 0000000..82a2c60 --- /dev/null +++ b/dumps/scripts/4680.cs2 @@ -0,0 +1,8 @@ +void script_4680() { + int ivar0; + int ivar1; + ivar0 = getWidgetActualWidth(new WidgetPointer(302,77)); + ivar1 = multiplyDivide(globalint_1536, 10000, ivar0); + setWidgetSize(ivar1, getWidgetActualHeight(new WidgetPointer(302,77)), 0, 0, new WidgetPointer(302,78)); + return; +} diff --git a/dumps/scripts/4681.cs2 b/dumps/scripts/4681.cs2 new file mode 100644 index 0000000..a861a09 --- /dev/null +++ b/dumps/scripts/4681.cs2 @@ -0,0 +1,11 @@ +void script_4681() { + int ivar0; + ivar0 = 0; + ivar0 = add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(bitconfig_9436, bitconfig_9437), bitconfig_9438), bitconfig_9439), bitconfig_9440), bitconfig_9441), bitconfig_9442), bitconfig_9443), bitconfig_9444), bitconfig_9445), bitconfig_9446), bitconfig_9447), bitconfig_9448), bitconfig_9449), bitconfig_9450), bitconfig_9451), bitconfig_9452), bitconfig_9453), bitconfig_9454), bitconfig_9455), bitconfig_9456), bitconfig_9457), bitconfig_9458), bitconfig_9459), bitconfig_9460), bitconfig_9461), bitconfig_9462); + if (ivar0 == 26) { + setWidgetText(new WidgetPointer(314,13), "Final wreck to loot!"); + } else { + setWidgetText(new WidgetPointer(314,13), "Wrecks looted: " + intToStr(ivar0) + "/27"); + } + return; +} diff --git a/dumps/scripts/4682.cs2 b/dumps/scripts/4682.cs2 new file mode 100644 index 0000000..cde91cf --- /dev/null +++ b/dumps/scripts/4682.cs2 @@ -0,0 +1,4 @@ +void script_4682() { + cs2method5421(1, "javadownload.ws"); + return; +} diff --git a/dumps/scripts/4683.cs2 b/dumps/scripts/4683.cs2 new file mode 100644 index 0000000..83dd3ca --- /dev/null +++ b/dumps/scripts/4683.cs2 @@ -0,0 +1,4 @@ +void script_4683() { + cs2method5421(1, "download.ws"); + return; +} diff --git a/dumps/scripts/4684.cs2 b/dumps/scripts/4684.cs2 new file mode 100644 index 0000000..54928b5 --- /dev/null +++ b/dumps/scripts/4684.cs2 @@ -0,0 +1,5 @@ +void script_4684() { + cs2method2005(0, new WidgetPointer(744,116)); + closeInterface(48758900); + return; +} diff --git a/dumps/scripts/4685.cs2 b/dumps/scripts/4685.cs2 new file mode 100644 index 0000000..64feb60 --- /dev/null +++ b/dumps/scripts/4685.cs2 @@ -0,0 +1,26 @@ +void script_4685() { + int ivar0; + int ivar1; + string svar0; + string svar1; + svar0 = intToStr(bitconfig_9467); + svar1 = "Waiting for next wave..."; + if (globalint_1537 != 0) { + setWidgetIsHidden(false, new WidgetPointer(447,14)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(447,1)), 79, 0, 0, new WidgetPointer(447,1)); + } else { + setWidgetIsHidden(true, new WidgetPointer(447,14)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(447,1)), 45, 0, 0, new WidgetPointer(447,1)); + } + ivar0 = 0; + ivar1 = 0; + ivar0 = script_4699(29294603, 29294604, 29294605, "Wave", svar0); + if (globalint_1537 != 0) { + ivar1 = script_4699(29294606, 29294608, 29294609, "Waiting?", svar1); + } + ivar0 = max(ivar0, ivar1); + if (ivar0 > getWidgetActualWidth(new WidgetPointer(447,1))) { + setWidgetSize(add(ivar0, 5), getWidgetActualHeight(new WidgetPointer(447,1)), 0, 0, new WidgetPointer(447,1)); + } + return; +} diff --git a/dumps/scripts/4686.cs2 b/dumps/scripts/4686.cs2 new file mode 100644 index 0000000..980b2db --- /dev/null +++ b/dumps/scripts/4686.cs2 @@ -0,0 +1,17 @@ +void script_4686() { + if (globalint_1538 >= 160) { + return; + } + if (((boolean)globalint_1539)) { + globalint_1538 = 160; + setWidgetPosition(0, 75, 0, 0, new WidgetPointer(447,15)); + return; + } + if (globalint_1538 == 158) { + setWidgetIsHidden(true, new WidgetPointer(447,15)); + } else { + setWidgetPosition(subtract(-2, globalint_1538), 75, 0, 0, new WidgetPointer(447,15)); + globalint_1538 = add(globalint_1538, 2); + } + return; +} diff --git a/dumps/scripts/4687.cs2 b/dumps/scripts/4687.cs2 new file mode 100644 index 0000000..f02c5f0 --- /dev/null +++ b/dumps/scripts/4687.cs2 @@ -0,0 +1,4 @@ +void script_4687() { + setWidgetText(new WidgetPointer(551,22), "Morale: " + intToStr(bitconfig_9465)); + return; +} diff --git a/dumps/scripts/4688.cs2 b/dumps/scripts/4688.cs2 new file mode 100644 index 0000000..5b06faf --- /dev/null +++ b/dumps/scripts/4688.cs2 @@ -0,0 +1,83 @@ +void script_4688() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + ivar0 = 0; + ivar1 = 0; + ivar2 = -1; + ivar3 = -1; + ivar4 = -1; + ivar5 = -1; + ivar6 = -1; + ivar7 = 1; + while (ivar7 < 5) { + switch (ivar7) { + case 1: + ivar6 = 36110354; + ivar0 = globalint_1549; + ivar1 = cs2method_3408(105, 105, 3856, ivar7); + ivar2 = 36110353; + ivar3 = 36110355; + ivar4 = 36110351; + ivar5 = 36110352; + break; + case 2: + ivar6 = 36110380; + ivar0 = globalint_1550; + ivar1 = cs2method_3408(105, 105, 3856, ivar7); + ivar2 = 36110379; + ivar3 = 36110381; + ivar4 = 36110377; + ivar5 = 36110378; + break; + case 3: + ivar6 = 36110394; + ivar0 = globalint_1551; + ivar1 = cs2method_3408(105, 105, 3856, ivar7); + ivar2 = 36110393; + ivar3 = 36110395; + ivar4 = 36110391; + ivar5 = 36110392; + break; + case 4: + ivar6 = 36110408; + ivar0 = globalint_1552; + ivar1 = cs2method_3408(105, 105, 3856, ivar7); + ivar2 = 36110407; + ivar3 = 36110409; + ivar4 = 36110405; + ivar5 = 36110406; + break; + default: + return; + } + if (setWidgetRegister(new WidgetPointer(ivar6))) { + if (ivar0 > 0) { + setWidgetHidden(0); + setWidgetFilled(1); + setWidgetSize(getWidgetActualWidth(), divide(multiply(ivar0, 26), 100), 0, 0); + } else { + setWidgetHidden(1); + setWidgetFilled(0); + setWidgetSize(getWidgetActualWidth(), 26, 0, 0); + } + } + if ((ivar0 > 0) || (bitconfig_9465 < ivar1)) { + setWidgetIsHidden(false, new WidgetPointer(ivar3)); + setWidgetRGB(new Color(125, 125, 125), new WidgetPointer(ivar4)); + setWidgetRGB(new Color(125, 125, 125), new WidgetPointer(ivar5)); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(ivar2)); + setWidgetIsHidden(true, new WidgetPointer(ivar3)); + setWidgetRGB(new Color(235, 224, 188), new WidgetPointer(ivar4)); + setWidgetRGB(new Color(235, 224, 188), new WidgetPointer(ivar5)); + } + ivar7 = add(ivar7, 1); + } + return; +} diff --git a/dumps/scripts/4689.cs2 b/dumps/scripts/4689.cs2 new file mode 100644 index 0000000..c18180c --- /dev/null +++ b/dumps/scripts/4689.cs2 @@ -0,0 +1,23 @@ +void script_4689() { + setWidgetIsHidden(false, new WidgetPointer(551,9)); + setWidgetText(new WidgetPointer(551,15), cs2method_3408(105, 115, 3855, 1)); + setWidgetSprite(6188, new WidgetPointer(551,17)); + setWidgetText(new WidgetPointer(551,16), intToStr(cs2method_3408(105, 105, 3856, 1))); + setWidgetIsHidden(false, new WidgetPointer(551,33)); + setWidgetText(new WidgetPointer(551,41), cs2method_3408(105, 115, 3855, 2)); + setWidgetSprite(6189, new WidgetPointer(551,43)); + setWidgetText(new WidgetPointer(551,42), intToStr(cs2method_3408(105, 105, 3856, 2))); + setWidgetIsHidden(false, new WidgetPointer(551,47)); + setWidgetText(new WidgetPointer(551,55), cs2method_3408(105, 115, 3855, 3)); + setWidgetSprite(6190, new WidgetPointer(551,57)); + setWidgetText(new WidgetPointer(551,56), intToStr(cs2method_3408(105, 105, 3856, 3))); + setWidgetIsHidden(false, new WidgetPointer(551,61)); + setWidgetText(new WidgetPointer(551,69), cs2method_3408(105, 115, 3855, 4)); + setWidgetSprite(6191, new WidgetPointer(551,71)); + setWidgetText(new WidgetPointer(551,70), intToStr(cs2method_3408(105, 105, 3856, 4))); + setScriptCallOnMouseOver(4692, new WidgetPointer(-32768,3), 80, "Ii", new WidgetPointer(551,10)); + setScriptCallOnMouseOver(4692, new WidgetPointer(-32768,3), 129, "Ii", new WidgetPointer(551,36)); + setScriptCallOnMouseOver(4692, new WidgetPointer(-32768,3), 31, "Ii", new WidgetPointer(551,50)); + setScriptCallOnMouseOver(4692, new WidgetPointer(-32768,3), 80, "Ii", new WidgetPointer(551,64)); + return; +} diff --git a/dumps/scripts/469.cs2 b/dumps/scripts/469.cs2 new file mode 100644 index 0000000..d19dfb0 --- /dev/null +++ b/dumps/scripts/469.cs2 @@ -0,0 +1,4 @@ +void script_469() { + script_304(41962744); + return; +} diff --git a/dumps/scripts/4690.cs2 b/dumps/scripts/4690.cs2 new file mode 100644 index 0000000..f75335d --- /dev/null +++ b/dumps/scripts/4690.cs2 @@ -0,0 +1,57 @@ +void script_4690(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + flow_0: + ivar2 = 15458492; + ivar3 = 0; + ivar4 = -1; + ivar5 = 0; + ivar6 = 0; + ivar7 = 0; + SWITCH (arg0) { + case 36110345: + GOTO flow_1 + case 36110369: + GOTO flow_2 + case 36110383: + GOTO flow_3 + case 36110397: + GOTO flow_4 + } + return; + flow_1: + ivar3 = globalint_1549; + ivar4 = 36110351; + ivar6 = globalint_1549; + ivar7 = cs2method_3408(105, 105, 3856, 1); + GOTO flow_5 + flow_2: + ivar3 = globalint_1550; + ivar4 = 36110377; + ivar6 = globalint_1550; + ivar7 = cs2method_3408(105, 105, 3856, 2); + GOTO flow_5 + flow_3: + ivar3 = globalint_1551; + ivar4 = 36110391; + ivar6 = globalint_1551; + ivar7 = cs2method_3408(105, 105, 3856, 3); + GOTO flow_5 + flow_4: + ivar3 = globalint_1552; + ivar4 = 36110405; + ivar6 = globalint_1552; + ivar7 = cs2method_3408(105, 105, 3856, 4); + flow_5: + if (((boolean)ivar6) && (bitconfig_9465 >= ivar7)) { + if (((boolean)arg1)) { + ivar2 = 16777215; + } + setWidgetRGB(new Color(ivar2), new WidgetPointer(ivar4)); + } + return; +} diff --git a/dumps/scripts/4691.cs2 b/dumps/scripts/4691.cs2 new file mode 100644 index 0000000..b751577 --- /dev/null +++ b/dumps/scripts/4691.cs2 @@ -0,0 +1,5 @@ +void script_4691(int arg0) { + setWidgetIsHidden(true, new WidgetPointer(551,23)); + setWidgetRGB(new Color(40, 36, 37), new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/4692.cs2 b/dumps/scripts/4692.cs2 new file mode 100644 index 0000000..aafa66f --- /dev/null +++ b/dumps/scripts/4692.cs2 @@ -0,0 +1,54 @@ +void script_4692(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + string svar0; + string svar1; + string svar2; + ivar2 = 36110359; + ivar3 = -1; + svar0 = ""; + svar1 = ""; + ivar4 = 0; + ivar5 = 0; + svar2 = ""; + ivar6 = 0; + switch (arg0) { + case 36110346: + ivar6 = 1; + svar1 = "Nothing breaks for 30 seconds."; + break; + case 36110372: + ivar6 = 2; + svar1 = "Kill twice as many trolls when repairing things."; + break; + case 36110386: + ivar6 = 3; + svar1 = "Fix twice as fast and counter-acts troll magic run energy effects."; + break; + case 36110400: + ivar6 = 4; + svar1 = "Broken things don't hurt gatehouse health for 30 seconds."; + break; + default: + setWidgetIsHidden(true, new WidgetPointer(ivar2)); + return; + } + setWidgetText(new WidgetPointer(551,29), cs2method_3408(105, 115, 3855, ivar6)); + setWidgetText(new WidgetPointer(551,30), svar1); + setWidgetText(new WidgetPointer(551,31), "Cost: " + intToStr(cs2method_3408(105, 105, 3856, ivar6))); + ivar5 = cs2method_3408(105, 105, 3857, ivar6); + if (ivar5 == 50) { + svar2 = "30 sec"; + } + if (ivar5 == 100) { + svar2 = "1 min"; + } + setWidgetText(new WidgetPointer(551,32), "Cooldown: " + svar2); + setWidgetRGB(new Color(54, 53, 54), new WidgetPointer(arg0)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(ivar2)), arg1, 0, 0, new WidgetPointer(ivar2)); + setWidgetIsHidden(false, new WidgetPointer(ivar2)); + return; +} diff --git a/dumps/scripts/4693.cs2 b/dumps/scripts/4693.cs2 new file mode 100644 index 0000000..70baeac --- /dev/null +++ b/dumps/scripts/4693.cs2 @@ -0,0 +1,5 @@ +void script_4693(int arg0) { + setWidgetIsHidden(true, new WidgetPointer(551,23)); + setWidgetRGB(new Color(40, 36, 37), new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/4694.cs2 b/dumps/scripts/4694.cs2 new file mode 100644 index 0000000..226cb7f --- /dev/null +++ b/dumps/scripts/4694.cs2 @@ -0,0 +1,24 @@ +void script_4694(int arg0) { + if (((boolean)globalint_1548)) { + setWidgetPosition(getWidgetActualWidth(new WidgetPointer(500,2)), 63, 0, 0, new WidgetPointer(arg0)); + } + if (globalint_1548 == 2) { + setWidgetPosition(getWidgetActualWidth(new WidgetPointer(500,2)), 93, 0, 0, new WidgetPointer(arg0)); + } + if (globalint_1548 == 3) { + setWidgetPosition(getWidgetActualWidth(new WidgetPointer(500,2)), 123, 0, 0, new WidgetPointer(arg0)); + } + if (globalint_1548 == 4) { + setWidgetPosition(getWidgetActualWidth(new WidgetPointer(500,2)), 153, 0, 0, new WidgetPointer(arg0)); + } + if (globalint_1548 == 5) { + setWidgetPosition(getWidgetActualWidth(new WidgetPointer(500,2)), 183, 0, 0, new WidgetPointer(arg0)); + } + if (globalint_1548 == 6) { + setWidgetPosition(getWidgetActualWidth(new WidgetPointer(500,2)), 213, 0, 0, new WidgetPointer(arg0)); + } + if (globalint_1548 == 7) { + setWidgetPosition(getWidgetActualWidth(new WidgetPointer(500,2)), 213, 0, 0, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/4695.cs2 b/dumps/scripts/4695.cs2 new file mode 100644 index 0000000..f203c3b --- /dev/null +++ b/dumps/scripts/4695.cs2 @@ -0,0 +1,17 @@ +void script_4695(int arg0,int arg1) { + int ivar2; + ivar2 = getClientCycle(); + if ((ivar2 >= add(arg0, 15)) || ((boolean)arg0)) { + cs2method2103(arg1, new WidgetPointer(500,11)); + arg0 = ivar2; + if (((boolean)globalint_1548)) { + arg1 = 255; + } else if (arg1 == 255) { + arg1 = 0; + } else { + arg1 = 255; + } + } + setScriptCallOnGameloop(4695, arg0, arg1, "ii", new WidgetPointer(500,11)); + return; +} diff --git a/dumps/scripts/4696.cs2 b/dumps/scripts/4696.cs2 new file mode 100644 index 0000000..20a3205 --- /dev/null +++ b/dumps/scripts/4696.cs2 @@ -0,0 +1,7 @@ +void script_4696() { + setScriptCallOnGameloop(4697, 0, "i", new WidgetPointer(500,8)); + if (isWidgetHidden(new WidgetPointer(500,11))) { + setScriptCallOnGameloop(4695, 0, 0, "ii", new WidgetPointer(500,11)); + } + return; +} diff --git a/dumps/scripts/4697.cs2 b/dumps/scripts/4697.cs2 new file mode 100644 index 0000000..4a7ab78 --- /dev/null +++ b/dumps/scripts/4697.cs2 @@ -0,0 +1,110 @@ +void script_4697(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + string svar0; + string svar1; + string svar2; + string svar3; + string svar4; + string svar5; + ivar1 = getClientCycle(); + svar0 = ""; + svar1 = ""; + svar2 = ""; + svar3 = ""; + svar4 = ""; + svar5 = ""; + ivar2 = 0; + ivar3 = 0; + ivar4 = 0; + ivar5 = 1; + if ((ivar1 >= add(arg0, 200)) || ((boolean)arg0)) { + arg0 = ivar1; + if (globalint_1540 < 1) { + svar0 = "Destroyed"; + } else if (globalint_1540 < divide(5, 2)) { + svar0 = "Under attack"; + } else if (globalint_1540 < 5) { + svar0 = "Unlit ammo"; + } else { + svar0 = "Fine"; + } + if (globalint_1541 < 1) { + svar1 = "Empty"; + } else if (globalint_1541 < divide(10, 2)) { + svar1 = "Low"; + } else if (globalint_1541 < 10) { + svar1 = "Almost full"; + } else { + svar1 = "Full"; + } + if (((boolean)globalint_1542)) { + svar2 = "1 broken"; + } else if (globalint_1542 > 0) { + svar2 = intToStr(globalint_1542) + " broken"; + } else { + svar2 = "Repaired"; + } + if (((boolean)globalint_1543)) { + svar3 = intToStr(ivar5) + " broken"; + } else if (globalint_1543 > 0) { + svar3 = intToStr(globalint_1543) + " broken"; + } else { + svar3 = "Repaired"; + } + ivar2 = divide(globalint_1545, 2); + setWidgetSize(divide(multiply(ivar2, 16384), 100), getWidgetActualHeight(new WidgetPointer(500,12)), 2, 0, new WidgetPointer(500,12)); + if (ivar2 < 97) { + setWidgetIsHidden(true, new WidgetPointer(500,13)); + } + svar4 = intToStr(multiply(globalint_1544, 10)); + setWidgetText(new WidgetPointer(500,29), intToStr(globalint_1546) + " min"); + if (globalint_1547 != 0) { + setWidgetIsHidden(false, new WidgetPointer(500,10)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(500,2)), 253, 0, 0, new WidgetPointer(500,2)); + switch (globalint_1547) { + case 1: + svar5 = "Clobbering Time!"; + break; + case 2: + svar5 = "Slow-mo"; + break; + case 3: + svar5 = "No Well"; + break; + case 4: + svar5 = "Oil Spill"; + break; + case 5: + svar5 = "Fire in the Hole!"; + break; + case 6: + svar5 = "Armoured Trolls"; + } + } else { + setWidgetIsHidden(true, new WidgetPointer(500,10)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(500,2)), 225, 0, 0, new WidgetPointer(500,2)); + } + ivar3 = script_4699(32768008, 32768021, 32768022, "Ballista", svar0); + ivar4 = script_4699(32768005, 32768019, 32768020, "Oil", svar1); + ivar3 = max(ivar3, ivar4); + ivar4 = script_4699(32768006, 32768039, 32768040, "Barricades", svar2); + ivar3 = max(ivar3, ivar4); + ivar4 = script_4699(32768007, 32768017, 32768018, "Walls", svar3); + ivar3 = max(ivar3, ivar4); + ivar4 = script_4699(32768009, 32768041, 32768042, "Trolls", svar4); + ivar3 = max(ivar3, ivar4); + if (globalint_1547 != 0) { + ivar4 = script_4699(32768010, 32768015, 32768016, "Troll Attack", svar5); + ivar3 = max(ivar3, ivar4); + } + if (add(ivar3, 15) > getWidgetActualWidth(new WidgetPointer(500,2))) { + setWidgetSize(add(ivar3, 15), getWidgetActualHeight(new WidgetPointer(500,2)), 0, 0, new WidgetPointer(500,2)); + } + } + setScriptCallOnGameloop(4697, arg0, "i", new WidgetPointer(500,8)); + return; +} diff --git a/dumps/scripts/4698.cs2 b/dumps/scripts/4698.cs2 new file mode 100644 index 0000000..9778adb --- /dev/null +++ b/dumps/scripts/4698.cs2 @@ -0,0 +1,10 @@ +void script_4698() { + int ivar0; + ivar0 = 0; + ivar0 = divide(globalint_1545, 2); + setWidgetSize(divide(multiply(ivar0, 16384), 100), getWidgetActualHeight(new WidgetPointer(500,12)), 2, 0, new WidgetPointer(500,12)); + if (ivar0 < 97) { + setWidgetIsHidden(true, new WidgetPointer(500,13)); + } + return; +} diff --git a/dumps/scripts/4699.cs2 b/dumps/scripts/4699.cs2 new file mode 100644 index 0000000..864b5ee --- /dev/null +++ b/dumps/scripts/4699.cs2 @@ -0,0 +1,51 @@ +int script_4699(int arg0,int arg1,int arg2,string arg3,string arg4) { + int ivar3; + int ivar4; + ivar3 = max(add(getTextWidth(3793, arg3), 30), 75); + ivar4 = max(add(getTextWidth(3793, arg4), 30), 120); + setWidgetSize(add(ivar3, ivar4), getWidgetActualHeight(new WidgetPointer(arg0)), 0, 0, new WidgetPointer(arg0)); + deleteAllExtraChilds(new WidgetPointer(arg1)); + setWidgetSize(ivar3, 27, 0, 0, new WidgetPointer(arg1)); + createExtraChild(new WidgetPointer(arg1), 5, getExtraChildGap(new WidgetPointer(arg1))); + setWidgetSize(6, 23, 1, 0); + setWidgetPosition(0, 0, 1, 1); + cs2method1107(1); + setWidgetSprite(5668); + createExtraChild(new WidgetPointer(arg1), 5, getExtraChildGap(new WidgetPointer(arg1))); + setWidgetSize(8, 23, 0, 0); + setWidgetPosition(0, 0, 0, 1); + setWidgetSprite(5667); + createExtraChild(new WidgetPointer(arg1), 4, getExtraChildGap(new WidgetPointer(arg1))); + setWidgetSize(0, 0, 1, 1); + setWidgetPosition(0, 0, 1, 1); + setWidgetFont(3793); + setWidgetRGB(new Color(235, 224, 188)); + setWidgetTextAlignment(1, 1, 0); + setWidgetUnknownBoolean(false); + setWidgetText(arg3); + deleteAllExtraChilds(new WidgetPointer(arg2)); + setWidgetSize(ivar4, 27, 0, 0, new WidgetPointer(arg2)); + setWidgetPosition(subtract(ivar3, 4), 0, 0, 1, new WidgetPointer(arg2)); + createExtraChild(new WidgetPointer(arg2), 5, getExtraChildGap(new WidgetPointer(arg2))); + setWidgetSize(10, 27, 1, 0); + setWidgetPosition(0, 0, 1, 1); + cs2method1107(1); + setWidgetSprite(6084); + createExtraChild(new WidgetPointer(arg2), 5, getExtraChildGap(new WidgetPointer(arg2))); + setWidgetSize(11, 27, 0, 0); + setWidgetPosition(0, 0, 0, 1); + setWidgetSprite(6083); + createExtraChild(new WidgetPointer(arg2), 5, getExtraChildGap(new WidgetPointer(arg2))); + setWidgetSize(11, 27, 0, 0); + setWidgetPosition(0, 0, 2, 1); + setWidgetSprite(6086); + createExtraChild(new WidgetPointer(arg2), 4, getExtraChildGap(new WidgetPointer(arg2))); + setWidgetSize(0, 0, 1, 1); + setWidgetPosition(0, 0, 1, 1); + setWidgetFont(3793); + setWidgetRGB(new Color(235, 224, 188)); + setWidgetTextAlignment(1, 1, 0); + setWidgetUnknownBoolean(false); + setWidgetText(arg4); + return add(ivar3, ivar4); +} diff --git a/dumps/scripts/47.cs2 b/dumps/scripts/47.cs2 new file mode 100644 index 0000000..932aa3a --- /dev/null +++ b/dumps/scripts/47.cs2 @@ -0,0 +1,12 @@ +string script_47(int arg0) { + if (arg0 > 99) { + return intToStr(arg0); + } + if (arg0 > 9) { + return "0" + intToStr(arg0); + } + if (arg0 >= 0) { + return "00" + intToStr(arg0); + } + return intToStr(arg0); +} diff --git a/dumps/scripts/470.cs2 b/dumps/scripts/470.cs2 new file mode 100644 index 0000000..0c21a0b --- /dev/null +++ b/dumps/scripts/470.cs2 @@ -0,0 +1,8 @@ +void script_470(int arg0,int arg1) { + if (bitconfig_2086 < arg1) { + setWidgetText(new WidgetPointer(arg0), "" + intToStr(arg1) + " Commendations required." + ""); + } else { + setWidgetText(new WidgetPointer(arg0), intToStr(arg1) + " Commendations."); + } + return; +} diff --git a/dumps/scripts/4700.cs2 b/dumps/scripts/4700.cs2 new file mode 100644 index 0000000..9b79ac9 --- /dev/null +++ b/dumps/scripts/4700.cs2 @@ -0,0 +1,4 @@ +void script_4700() { + setScriptCallOnGameloop(-1, "", new WidgetPointer(744,17)); + return; +} diff --git a/dumps/scripts/4701.cs2 b/dumps/scripts/4701.cs2 new file mode 100644 index 0000000..fa8cbdd --- /dev/null +++ b/dumps/scripts/4701.cs2 @@ -0,0 +1,36 @@ +void script_4701(int arg0,int arg1,int arg2,string arg3) { + globalint_1553 = arg1; + globalint_1554 = arg2; + globalstring_128 = arg3; + if (((boolean)arg0)) { + if ((globalint_1100 == 43) || (globalint_1100 == 42)) { + script_2190(0, 12, 1, "Leave queue", "Are you sure you wish to leave the queue, you will lose your position if you do.", "", ""); + return; + } + script_3141(arg2, arg3); + if ((arg1 > -1) && setWidgetRegister(new WidgetPointer(910,64), arg1)) { + setWidgetIsHidden(false, new WidgetPointer(910,67)); + setWidgetPosition(0, getWidgetActualY(), 0, 0, new WidgetPointer(910,67)); + } + if (getWorldId() == globalint_998) { + if (setWidgetRegister(new WidgetPointer(910,21), 3)) { + setWidgetHidden(0); + } + } else { + if (setWidgetRegister(new WidgetPointer(910,21), 3)) { + setWidgetHidden(1); + } + } + if (getWorldId() == globalint_999) { + if (setWidgetRegister(new WidgetPointer(910,22), 3)) { + setWidgetHidden(0); + } + } else { + if (setWidgetRegister(new WidgetPointer(910,22), 3)) { + setWidgetHidden(1); + } + } + script_3064(1); + } + return; +} diff --git a/dumps/scripts/4702.cs2 b/dumps/scripts/4702.cs2 new file mode 100644 index 0000000..6891cb6 --- /dev/null +++ b/dumps/scripts/4702.cs2 @@ -0,0 +1,5 @@ +void script_4702() { + cancelLogin(); + globalint_1100 = -1; + return; +} diff --git a/dumps/scripts/4703.cs2 b/dumps/scripts/4703.cs2 new file mode 100644 index 0000000..e6b504b --- /dev/null +++ b/dumps/scripts/4703.cs2 @@ -0,0 +1,16 @@ +void script_4703() { + setWidgetIsHidden(true, new WidgetPointer(744,103)); + setWidgetSprite(4129, new WidgetPointer(744,97)); + globalint_1100 = -1; + script_2954(); + resetRCs(); + setWidgetText(new WidgetPointer(975,49), "Play Game"); + setWidgetText(new WidgetPointer(596,60), "Play Game"); + setWidgetText(new WidgetPointer(975,48), "Play Game"); + setWidgetText(new WidgetPointer(596,59), "Play Game"); + setScriptCallOnMousePressed(2944, "", new WidgetPointer(975,44)); + setScriptCallOnMousePressed(2944, "", new WidgetPointer(596,45)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(975,26)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(596,7)); + return; +} diff --git a/dumps/scripts/4704.cs2 b/dumps/scripts/4704.cs2 new file mode 100644 index 0000000..66f5cde --- /dev/null +++ b/dumps/scripts/4704.cs2 @@ -0,0 +1,190 @@ +void script_4704() { + int ivar0; + int ivar1; + int ivar2; + loginResponse(3,0,0) structdump_0; + ivar0 = 0; + ivar1 = 0; + ivar2 = -1; + structdump_0 = getLoginResponse(); + ivar2 = structdump_0.intpart_2; + ivar1 = structdump_0.intpart_1; + ivar0 = structdump_0.intpart_0; + switch (ivar0) { + case 0: + break; + case 1: + break; + case 2: + break; + case 3: + messageType0("Your password has been updated. Please leave the world and log in again."); + break; + case 4: + messageType0("Your account has been disabled. Check your Message Centre for details."); + break; + case 5: + messageType0("Your account has not logged out from its last session. Try again in a few minutes."); + break; + case 6: + messageType0("RuneScape has been updated! Please try again in a few minutes."); + break; + case 7: + messageType0("This world is full. Please try back later."); + break; + case 8: + messageType0("Unable to connect: login server offline."); + break; + case 9: + messageType0("Login limit exceeded: too many connections from your address."); + break; + case 10: + messageType0("Unable to connect: bad session id."); + break; + case 11: + messageType0("Your password is an extremely common choice, and is not secure. You must change it."); + break; + case 12: + messageType0("You need a member's account to log in to this world."); + break; + case 13: + messageType0("Could not complete login. Please try back later."); + break; + case 14: + messageType0("The server is being updated. Please wait a few minutes and try again."); + break; + case 15: + break; + case 16: + messageType0("Too many incorrect logins from your address. Please wait 5 minutes before trying again."); + break; + case 17: + messageType0("You are standing in a members-only area. To play on this world, move to a free area first."); + break; + case 18: + messageType0("Your account has been locked. If you have not received an account recovery email, please select 'Recover Account'."); + break; + case 19: + messageType0("Fullscreen is currently a members-only feature. To log in, either exit fullscreen via the options menu or use a member's account."); + break; + case 20: + messageType0("Invalid loginserver requested. Please try back later."); + break; + case 21: + break; + case 22: + messageType0("Malformed login packet. Please try again."); + break; + case 23: + messageType0("No reply from login server. Please wait a minute and try again."); + break; + case 24: + messageType0("Error loading your profile. Please contact customer support."); + break; + case 25: + messageType0("Unexpected loginserver response. Please try back later."); + break; + case 26: + messageType0("This computer's address has been blocked, as it was used to break our rules."); + break; + case 27: + messageType0("Service unavailable."); + break; + case 28: + break; + case 29: + switch (getDetailedRC()) { + case 0: + messageType0("You must have a Combat Level of at least 20 (not including Summoning) to enter a PvP world."); + break; + case 1: + messageType0("You are currently carrying lent items and cannot enter a PvP world."); + break; + case 2: + messageType0("You must be standing in the Wilderness or Edgeville to enter this bounty world."); + break; + case 3: + messageType0("You must have a total skill level of 1,000 or greater to enter this world."); + break; + case 5: + messageType0("You must have a total skill level of 1,500 or greater to enter this world."); + break; + case 4: + messageType0("You must move to a safe area before you can log in to a PvP or bounty world."); + break; + default: + messageType0("Unexpected server response. Please try back later."); + } + break; + case 30: + messageType0("This is not a member's account. Please choose a 'free' world from the website to play on this account."); + break; + case 31: + break; + case 32: + messageType0("Your account has negative membership credit. Please log into the billing system to add credit to your account."); + break; + case 33: + break; + case 34: + break; + case 35: + break; + case 36: + break; + case 37: + messageType0("Your account is currently inaccessible. Please try again in a few minutes."); + break; + case 38: + break; + case 39: + messageType0("The instance you tried to join no longer exists. Please try back later."); + break; + case 40: + messageType0("You need a member's account to log in to this instance."); + break; + case 41: + messageType0("The instance you tried to join is full. Please try back later."); + break; + case 42: + break; + case 43: + break; + case 44: + messageType0("Our systems are currently unavailable. Please try again in a few minutes."); + break; + case 45: + switch (ivar2) { + case 0: + switch (ivar1) { + case 0: + messageType0("You must be near the TzHaar Fight Pits entrance to enter a global match."); + break; + default: + messageType0("Unable to log in. Please try back later."); + } + break; + case 1: + switch (ivar1) { + case 1: + messageType0("There was an error connecting to your meeting room. Please try again."); + break; + case 2: + messageType0("You need a higher rank to enter that private tent."); + break; + case 3: + messageType0("You need an invitation to enter that private room."); + break; + default: + messageType0("Unable to log in. Please try back later."); + } + break; + default: + messageType0("Unable to log in. Please try back later."); + } + break; + case 46: + messageType0("This instance is marked for deletion/rebuild. Please try again in a few minutes."); + } + return; +} diff --git a/dumps/scripts/4705.cs2 b/dumps/scripts/4705.cs2 new file mode 100644 index 0000000..f72bef6 --- /dev/null +++ b/dumps/scripts/4705.cs2 @@ -0,0 +1,16 @@ +cs2func_script_4705_struct(3,0,0) script_4705(int arg0) { + int ivar1; + int ivar2; + int ivar3; + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + ivar3 = divide(multiply(arg0, 6), 10); + ivar2 = divide(ivar3, 60); + ivar3 = mod(ivar3, 60); + if (ivar2 > 59) { + ivar1 = divide(ivar2, 60); + ivar2 = mod(ivar2, 60); + } + return newstruct cs2func_script_4705_struct(ivar1, ivar2, ivar3); +} diff --git a/dumps/scripts/4706.cs2 b/dumps/scripts/4706.cs2 new file mode 100644 index 0000000..75e6533 --- /dev/null +++ b/dumps/scripts/4706.cs2 @@ -0,0 +1,4 @@ +void script_4706(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7) { + script_4709(arg0, arg1, arg2, 0, arg3, arg4, arg5, arg6, arg7, 897, 788, 788, 1040, 16777215, 16711680, 16776960, 494, 792, 789, 790, 791, 773, 788); + return; +} diff --git a/dumps/scripts/4707.cs2 b/dumps/scripts/4707.cs2 new file mode 100644 index 0000000..c725d70 --- /dev/null +++ b/dumps/scripts/4707.cs2 @@ -0,0 +1,4 @@ +void script_4707(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8) { + script_4709(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, 897, 788, 788, 1040, 16777215, 16711680, 16776960, 494, 792, 789, 790, 791, 773, 788); + return; +} diff --git a/dumps/scripts/4708.cs2 b/dumps/scripts/4708.cs2 new file mode 100644 index 0000000..cbe55de --- /dev/null +++ b/dumps/scripts/4708.cs2 @@ -0,0 +1,4 @@ +void script_4708(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8) { + script_4709(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, 897, 788, 788, 1040, 16777215, 16711680, 16776960, 494, 792, 789, 790, 791, 773, 788); + return; +} diff --git a/dumps/scripts/4709.cs2 b/dumps/scripts/4709.cs2 new file mode 100644 index 0000000..f62f4ce --- /dev/null +++ b/dumps/scripts/4709.cs2 @@ -0,0 +1,78 @@ +void script_4709(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12,int arg13,int arg14,int arg15,int arg16,int arg17,int arg18,int arg19,int arg20,int arg21,int arg22) { + int ivar23; + int ivar24; + int ivar25; + int ivar26; + string svar0; + int stack_dump0; + int stack_dump1; + int stack_dump2; + int stack_dump3; + int stack_dump4; + int stack_dump5; + int stack_dump6; + int stack_dump7; + int stack_dump8; + int stack_dump9; + int stack_dump10; + int stack_dump11; + cs2func_script_4710_struct(2,0,0) structdump_12; + ivar23 = 0; + ivar24 = 0; + stack_dump0 = arg1; + stack_dump1 = arg2; + stack_dump2 = arg5; + stack_dump3 = arg6; + stack_dump4 = arg7; + stack_dump5 = arg8; + stack_dump6 = 897; + stack_dump7 = 788; + stack_dump8 = 788; + stack_dump9 = 16777215; + stack_dump10 = 16776960; + stack_dump11 = 494; + structdump_12 = script_4710(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4, stack_dump5, stack_dump6, stack_dump7, stack_dump8, stack_dump9, stack_dump10, stack_dump11); + ivar23 = structdump_12.intpart_1; + ivar24 = structdump_12.intpart_0; + createExtraChild(new WidgetPointer(arg6), 5, getExtraChildGap(new WidgetPointer(arg6))); + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg6)), getWidgetActualHeight(new WidgetPointer(arg6)), 0, 0); + setWidgetSprite(arg12); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg6), 3, getExtraChildGap(new WidgetPointer(arg6))); + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg6)), getWidgetActualHeight(new WidgetPointer(arg6)), 0, 0); + setWidgetRGB(new Color(0, 0, 0)); + setWidgetScrollMax(getWidgetActualWidth(new WidgetPointer(arg7)), multiply(arg4, 15), new WidgetPointer(arg7)); + ivar25 = arg3; + ivar26 = -1; + svar0 = ""; + while (ivar25 <= arg4) { + ivar26 = getExtraChildGap(new WidgetPointer(arg7)); + svar0 = cs2method_3408(105, 115, arg1, ivar25); + createExtraChild(new WidgetPointer(arg7), 4, ivar26); + setWidgetText(svar0); + setWidgetTextAlignment(0, 1, 0); + setWidgetPosition(5, multiply(ivar26, 15), 0, 0); + setWidgetSize(subtract(getWidgetActualWidth(new WidgetPointer(arg7)), 16), 15, 0, 0); + setWidgetUnknownBoolean(false); + setWidgetFont(arg16); + setWidgetContextMenuOption(1, "Select"); + setScriptCallOnClickContextMenu(4713, arg0, -2147483643, "gi"); + if (ivar25 > arg4) { + setWidgetRGB(new Color(arg14)); + setScriptCallOnMouseExit(1354, new WidgetPointer(arg7), ivar26, arg14, "Iii"); + setScriptCallOnMousePressed(4715, new WidgetPointer(arg6), new WidgetPointer(arg7), new WidgetPointer(arg8), new WidgetPointer(arg5), ivar23, ivar24, svar0, arg14, "IIIIiisi"); + } else { + setWidgetRGB(new Color(arg13)); + setScriptCallOnMouseExit(1354, new WidgetPointer(arg7), ivar26, arg13, "Iii"); + setScriptCallOnMousePressed(4715, new WidgetPointer(arg6), new WidgetPointer(arg7), new WidgetPointer(arg8), new WidgetPointer(arg5), ivar23, ivar24, svar0, arg13, "IIIIiisi"); + } + setScriptCallOnMouseEntered(1353, new WidgetPointer(arg7), ivar26, arg15, "Iii"); + ivar25 = add(ivar25, 1); + } + if (arg8 != -1) { + script_31(arg8, arg7, arg17, arg18, arg19, arg20, arg21, arg22); + } + return; +} diff --git a/dumps/scripts/471.cs2 b/dumps/scripts/471.cs2 new file mode 100644 index 0000000..3b9c25a --- /dev/null +++ b/dumps/scripts/471.cs2 @@ -0,0 +1,12 @@ +void script_471(int arg0,int arg1) { + if (getSkillActualLvl(15) < 25) { + setWidgetText(new WidgetPointer(arg0), "" + "A Herblore level of " + intToStr(25) + " is required." + ""); + return; + } + if (bitconfig_2086 < arg1) { + setWidgetText(new WidgetPointer(arg0), "" + intToStr(arg1) + " Commendations required." + ""); + } else { + setWidgetText(new WidgetPointer(arg0), intToStr(arg1) + " Commendations."); + } + return; +} diff --git a/dumps/scripts/4710.cs2 b/dumps/scripts/4710.cs2 new file mode 100644 index 0000000..c93b3ad --- /dev/null +++ b/dumps/scripts/4710.cs2 @@ -0,0 +1,36 @@ +cs2func_script_4710_struct(2,0,0) script_4710(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11) { + int ivar12; + int ivar13; + deleteAllExtraChilds(new WidgetPointer(arg2)); + createExtraChild(new WidgetPointer(arg2), 5, 0); + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg2)), getWidgetActualHeight(new WidgetPointer(arg2)), 0, 0); + setWidgetSprite(arg6); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg2), 3, getExtraChildGap(new WidgetPointer(arg2))); + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg2)), getWidgetActualHeight(new WidgetPointer(arg2)), 0, 0); + setWidgetRGB(new Color(0, 0, 0)); + ivar12 = 1; + createExtraChild(new WidgetPointer(arg2), 5, ivar12); + setWidgetPosition(subtract(getWidgetActualWidth(new WidgetPointer(arg2)), 16), 0, 0, 0); + setWidgetSize(16, getWidgetActualHeight(new WidgetPointer(arg2)), 0, 0); + setWidgetSprite(arg7); + cs2method1107(0); + setScriptCallOnMouseEntered(1351, new WidgetPointer(arg2), ivar12, arg8, "Iid"); + setScriptCallOnMouseExit(1352, new WidgetPointer(arg2), ivar12, arg7, "Iid"); + ivar13 = getExtraChildGap(new WidgetPointer(arg2)); + setScriptCallOnMousePressed(4711, new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), ivar12, "IIIIi"); + createExtraChild(new WidgetPointer(arg2), 4, ivar13); + setWidgetText(cs2method_3408(105, 115, arg0, arg1)); + setWidgetPosition(5, 0, 0, 0); + setWidgetSize(subtract(getWidgetActualWidth(new WidgetPointer(arg2)), 22), getWidgetActualHeight(new WidgetPointer(arg2)), 0, 0); + setWidgetUnknownBoolean(false); + setWidgetFont(arg11); + setWidgetTextAlignment(0, 1, 0); + setWidgetRGB(new Color(arg9)); + setScriptCallOnMouseExit(1354, new WidgetPointer(arg2), ivar13, arg9, "Iii"); + setScriptCallOnMouseEntered(1353, new WidgetPointer(arg2), ivar13, arg10, "Iii"); + setScriptCallOnMousePressed(4711, new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), ivar12, "IIIIi"); + return newstruct cs2func_script_4710_struct(ivar12, ivar13); +} diff --git a/dumps/scripts/4711.cs2 b/dumps/scripts/4711.cs2 new file mode 100644 index 0000000..51f9e09 --- /dev/null +++ b/dumps/scripts/4711.cs2 @@ -0,0 +1,8 @@ +void script_4711(int arg0,int arg1,int arg2,int arg3,int arg4) { + if (isWidgetHidden(new WidgetPointer(arg1))) { + script_4712(arg0, arg1, arg2, arg3, arg4); + } else { + script_4714(arg0, arg1, arg2, arg3, arg4); + } + return; +} diff --git a/dumps/scripts/4712.cs2 b/dumps/scripts/4712.cs2 new file mode 100644 index 0000000..4bb61ba --- /dev/null +++ b/dumps/scripts/4712.cs2 @@ -0,0 +1,11 @@ +void script_4712(int arg0,int arg1,int arg2,int arg3,int arg4) { + if (setWidgetRegister(new WidgetPointer(arg0), arg4)) { + setWidgetVFlip(1); + } + if (arg3 != -1) { + setWidgetIsHidden(false, new WidgetPointer(arg3)); + } + setWidgetIsHidden(false, new WidgetPointer(arg1)); + setWidgetIsHidden(false, new WidgetPointer(arg2)); + return; +} diff --git a/dumps/scripts/4713.cs2 b/dumps/scripts/4713.cs2 new file mode 100644 index 0000000..7ea0c62 --- /dev/null +++ b/dumps/scripts/4713.cs2 @@ -0,0 +1,4 @@ +void script_4713(int arg0,int arg1) { + script_4716(38666248, 38666247, arg0, -5, 10, arg1); + return; +} diff --git a/dumps/scripts/4714.cs2 b/dumps/scripts/4714.cs2 new file mode 100644 index 0000000..09bad99 --- /dev/null +++ b/dumps/scripts/4714.cs2 @@ -0,0 +1,11 @@ +void script_4714(int arg0,int arg1,int arg2,int arg3,int arg4) { + if (setWidgetRegister(new WidgetPointer(arg0), arg4)) { + setWidgetVFlip(0); + } + setWidgetIsHidden(true, new WidgetPointer(arg1)); + setWidgetIsHidden(true, new WidgetPointer(arg2)); + if (arg3 != -1) { + setWidgetIsHidden(true, new WidgetPointer(arg3)); + } + return; +} diff --git a/dumps/scripts/4715.cs2 b/dumps/scripts/4715.cs2 new file mode 100644 index 0000000..d4b35e8 --- /dev/null +++ b/dumps/scripts/4715.cs2 @@ -0,0 +1,9 @@ +void script_4715(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,string arg7) { + if (setWidgetRegister(new WidgetPointer(arg3), arg4)) { + setWidgetText(arg7); + setWidgetRGB(new Color(arg6)); + setScriptCallOnMouseExit(1354, new WidgetPointer(arg3), arg4, arg6, "Iii"); + } + script_4714(arg3, arg0, arg1, arg2, arg5); + return; +} diff --git a/dumps/scripts/4716.cs2 b/dumps/scripts/4716.cs2 new file mode 100644 index 0000000..98dcbf8 --- /dev/null +++ b/dumps/scripts/4716.cs2 @@ -0,0 +1,83 @@ +void script_4716(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + string svar0; + ivar6 = 48; + ivar7 = 48; + ivar8 = 0; + ivar9 = 0; + ivar10 = -1; + ivar11 = -1; + ivar12 = -1; + svar0 = ""; + ivar13 = 1; + ivar14 = 0; + ivar15 = 0; + ivar16 = 0; + ivar17 = 0; + ivar18 = 1; + if (getWidgetScrollMaxH(new WidgetPointer(arg0)) > 0) { + ivar16 = getWidgetScrollMaxH(new WidgetPointer(arg0)); + } else { + ivar16 = getWidgetActualWidth(new WidgetPointer(arg0)); + } + ivar16 = divide(ivar16, add(ivar6, arg3)); + while (ivar8 < getCommonDefinitionSize(arg2)) { + ivar18 = 0; + ivar10 = cs2method_3408(105, 74, arg2, ivar8); + if (setWidgetRegister(new WidgetPointer(arg0), ivar8)) { + ivar13 = script_4718(ivar10); + if (((boolean)arg5)) { + ivar18 = 1; + } else if (((boolean)arg5)) { + if (((boolean)ivar13)) { + ivar18 = 1; + } + } else if (arg5 == getOtherCommonData(ivar10, 1422)) { + ivar18 = 1; + } else if (arg5 == getOtherCommonData(ivar10, 1423)) { + ivar18 = 1; + } else if (arg5 == getOtherCommonData(ivar10, 1424)) { + ivar18 = 1; + } else if (arg5 == getOtherCommonData(ivar10, 1425)) { + ivar18 = 1; + } else { + if (arg5 == getOtherCommonData(ivar10, 1426)) { + ivar18 = 1; + } + } + if (((boolean)ivar18)) { + setWidgetHidden(0); + ivar14 = multiply(add(ivar6, arg3), mod(ivar9, ivar16)); + ivar15 = multiply(divide(ivar9, ivar16), add(ivar7, arg4)); + setWidgetPosition(ivar14, ivar15, 0, 0); + ivar9 = add(ivar9, 1); + } else { + setWidgetHidden(1); + } + } + ivar8 = add(ivar8, 1); + } + if (add(add(arg4, ivar15), ivar7) > getWidgetActualHeight(new WidgetPointer(arg0))) { + setWidgetScrollMax(0, add(ivar7, ivar15), new WidgetPointer(arg0)); + setWidgetIsHidden(false, new WidgetPointer(arg1)); + script_31(arg1, arg0, 792, 789, 790, 791, 773, 788); + } else { + setWidgetScrollMax(0, 0, new WidgetPointer(arg0)); + cs2method2100(0, 0, new WidgetPointer(arg0)); + deleteAllExtraChilds(new WidgetPointer(arg1)); + setWidgetIsHidden(true, new WidgetPointer(arg1)); + } + return; +} diff --git a/dumps/scripts/4717.cs2 b/dumps/scripts/4717.cs2 new file mode 100644 index 0000000..7c4c651 --- /dev/null +++ b/dumps/scripts/4717.cs2 @@ -0,0 +1,70 @@ +void script_4717(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + string svar0; + string svar1; + deleteAllExtraChilds(new WidgetPointer(arg0)); + ivar4 = 48; + ivar5 = 48; + ivar6 = 0; + ivar7 = -1; + ivar8 = -1; + ivar9 = -1; + svar0 = ""; + svar1 = ""; + ivar10 = 1; + ivar11 = -1; + ivar12 = 0; + setWidgetText(new WidgetPointer(590,20), "1"); + switch (arg3) { + case 3874: + ivar11 = 3873; + break; + default: + ivar11 = 3873; + } + while (ivar6 < getCommonDefinitionSize(arg3)) { + ivar7 = cs2method_3408(105, 74, arg3, ivar6); + ivar8 = getOtherCommonData(ivar7, 1420); + ivar10 = script_4718(ivar7); + svar0 = getOtherCommonData(ivar7, 1419); + createExtraChild(new WidgetPointer(arg0), 5, ivar6); + setWidgetSize(ivar4, ivar5, 0, 0); + setWidgetPosition(0, 0, 0, 0); + if (((boolean)ivar10)) { + ivar8 = getOtherCommonData(ivar7, 1421); + } + if (ivar7 == 1783) { + if (((int)IsFemale()) > 0) { + ivar7 = 1789; + ivar8 = getOtherCommonData(ivar7, 1420); + svar0 = getOtherCommonData(ivar7, 1419); + svar1 = "Curtsy"; + setWidgetContextMenuOption(1, "Curtsy"); + setWidgetContextMenuOption(2, "Bow"); + setScriptCallOnMouseOver(568, new WidgetPointer(-32768,3), -2147483643, new WidgetPointer(arg2), svar1, 25, 190, "IiIsii"); + } else { + setWidgetContextMenuOption(1, "Bow"); + setWidgetContextMenuOption(2, "Curtsy"); + svar1 = "Bow"; + setScriptCallOnMouseOver(568, new WidgetPointer(-32768,3), -2147483643, new WidgetPointer(arg2), svar1, 25, 190, "IiIsii"); + } + } else { + setWidgetContextMenuOption(1, svar0); + setScriptCallOnMouseOver(568, new WidgetPointer(-32768,3), -2147483643, new WidgetPointer(arg2), svar0, 25, 190, "IiIsii"); + } + setWidgetSprite(ivar8); + setScriptCallOnMouseExit(40, new WidgetPointer(arg2), "I"); + ivar6 = add(ivar6, 1); + } + script_4716(38666248, 38666247, arg3, -5, 10, ivar12); + script_4709(arg3, ivar11, ivar12, 0, getCommonDefinitionSize(ivar11), 38666254, 38666252, 38666253, 38666255, 897, 788, 788, 1040, 16777215, 16711680, 16776960, 494, 792, 789, 790, 791, 773, 788); + return; +} diff --git a/dumps/scripts/4718.cs2 b/dumps/scripts/4718.cs2 new file mode 100644 index 0000000..0d2e4ac --- /dev/null +++ b/dumps/scripts/4718.cs2 @@ -0,0 +1,241 @@ +int script_4718(int arg0) { + switch (arg0) { + case 1817: + if (((boolean)bitconfig_1368)) { + return 0; + } + return 1; + case 1818: + if (((boolean)bitconfig_1369)) { + return 0; + } + return 1; + case 1819: + if (((boolean)bitconfig_1370)) { + return 0; + } + return 1; + case 1806: + if (((boolean)bitconfig_1367)) { + return 0; + } + return 1; + case 1832: + if (((boolean)bitconfig_1371)) { + return 0; + } + return 1; + case 1837: + if (((boolean)bitconfig_2310)) { + return 0; + } + return 1; + case 1839: + if (((boolean)bitconfig_2312)) { + return 0; + } + return 1; + case 1836: + if (((boolean)bitconfig_2309)) { + return 0; + } + return 1; + case 1838: + if (((boolean)bitconfig_2311)) { + return 0; + } + return 1; + case 1834: + if (((boolean)bitconfig_1921)) { + return 0; + } + return 1; + case 1833: + if (((boolean)bitconfig_1920)) { + return 0; + } + return 1; + case 1840: + if (((boolean)bitconfig_2055)) { + return 0; + } + return 1; + case 1855: + if (((boolean)bitconfig_2787)) { + return 0; + } + return 1; + case 1835: + if (bitconfig_4075 != 12) { + return 0; + } + return 1; + case 1841: + if (((boolean)bitconfig_4202)) { + return 0; + } + return 1; + case 1842: + if (((boolean)bitconfig_4394)) { + return 0; + } + return 1; + case 1843: + if (((boolean)bitconfig_4476)) { + return 0; + } + return 1; + case 1844: + if (((boolean)bitconfig_4884)) { + return 0; + } + return 1; + case 1845: + if (((boolean)bitconfig_5490)) { + return 0; + } + return 1; + case 1846: + if (((boolean)bitconfig_5732)) { + return 0; + } + return 1; + case 1847: + if (((boolean)bitconfig_5641)) { + return 0; + } + return 1; + case 1849: + if (((boolean)bitconfig_6936)) { + return 0; + } + return 1; + case 1850: + if (((boolean)bitconfig_6095)) { + return 0; + } + return 1; + case 1851: + if (bitconfig_8300 != 20) { + return 0; + } + return 1; + case 1852: + if (((boolean)bitconfig_8688)) { + return 0; + } + return 1; + case 1853: + if (bitconfig_8601 != 428) { + return 0; + } + return 1; + case 1830: + case 1831: + if (bitconfig_532 < 7) { + return 0; + } + return 1; + case 1848: + if (((bitconfig_6014 < 85) && (bitconfig_7322 < 18)) && ((boolean)bitconfig_9194)) { + return 0; + } + return 1; + case 1854: + if (((boolean)bitconfig_9194)) { + return 0; + } + return 1; + case 2658: + if (isBitFlagged(standart_config_2230, 0)) { + return 0; + } + return 1; + case 2654: + if (isBitFlagged(standart_config_2230, 1)) { + return 0; + } + return 1; + case 2651: + if (isBitFlagged(standart_config_2230, 2)) { + return 0; + } + return 1; + case 2652: + if (isBitFlagged(standart_config_2230, 3)) { + return 0; + } + return 1; + case 2657: + if (isBitFlagged(standart_config_2230, 4)) { + return 0; + } + return 1; + case 2661: + if (isBitFlagged(standart_config_2230, 5)) { + return 0; + } + return 1; + case 2653: + if (isBitFlagged(standart_config_2230, 6)) { + return 0; + } + return 1; + case 2650: + if (isBitFlagged(standart_config_2230, 7)) { + return 0; + } + return 1; + case 2659: + if (isBitFlagged(standart_config_2230, 8)) { + return 0; + } + return 1; + case 2660: + if (isBitFlagged(standart_config_2230, 9)) { + return 0; + } + return 1; + case 2655: + if (isBitFlagged(standart_config_2230, 10)) { + return 0; + } + return 1; + case 2656: + if (isBitFlagged(standart_config_2230, 11)) { + return 0; + } + return 1; + case 2662: + if (isBitFlagged(standart_config_2230, 12)) { + return 0; + } + return 1; + case 2663: + if (isBitFlagged(standart_config_2230, 13)) { + return 0; + } + return 1; + case 2664: + if (isBitFlagged(standart_config_2230, 14)) { + return 0; + } + return 1; + case 2665: + if (isBitFlagged(standart_config_2230, 15)) { + return 0; + } + return 1; + case 2666: + if (isBitFlagged(standart_config_2230, 16)) { + return 0; + } + return 1; + case 2667: + if (isBitFlagged(standart_config_2230, 17)) { + return 0; + } + return 1; + } + return 1; +} diff --git a/dumps/scripts/4719.cs2 b/dumps/scripts/4719.cs2 new file mode 100644 index 0000000..3c83451 --- /dev/null +++ b/dumps/scripts/4719.cs2 @@ -0,0 +1,12 @@ +void script_4719(int arg0) { + if (arg0 == 40763415) { + setWidgetSprite(6359, new WidgetPointer(622,24)); + setWidgetSprite(6358, new WidgetPointer(622,25)); + setWidgetSprite(6360, new WidgetPointer(622,26)); + } else { + setWidgetSprite(6374, new WidgetPointer(622,29)); + setWidgetSprite(6373, new WidgetPointer(622,30)); + setWidgetSprite(6375, new WidgetPointer(622,31)); + } + return; +} diff --git a/dumps/scripts/472.cs2 b/dumps/scripts/472.cs2 new file mode 100644 index 0000000..cd7ce5a --- /dev/null +++ b/dumps/scripts/472.cs2 @@ -0,0 +1,12 @@ +void script_472(int arg0,int arg1) { + if (getSkillActualLvl(14) < 25) { + setWidgetText(new WidgetPointer(arg0), "" + "A Mining level of " + intToStr(25) + " is required." + ""); + return; + } + if (bitconfig_2086 < arg1) { + setWidgetText(new WidgetPointer(arg0), "" + intToStr(arg1) + " Commendations required." + ""); + } else { + setWidgetText(new WidgetPointer(arg0), intToStr(arg1) + " Commendations."); + } + return; +} diff --git a/dumps/scripts/4720.cs2 b/dumps/scripts/4720.cs2 new file mode 100644 index 0000000..8352e24 --- /dev/null +++ b/dumps/scripts/4720.cs2 @@ -0,0 +1,12 @@ +void script_4720(int arg0) { + if (arg0 == 40763415) { + setWidgetSprite(6356, new WidgetPointer(622,24)); + setWidgetSprite(6355, new WidgetPointer(622,25)); + setWidgetSprite(6357, new WidgetPointer(622,26)); + } else { + setWidgetSprite(6371, new WidgetPointer(622,29)); + setWidgetSprite(6370, new WidgetPointer(622,30)); + setWidgetSprite(6372, new WidgetPointer(622,31)); + } + return; +} diff --git a/dumps/scripts/4721.cs2 b/dumps/scripts/4721.cs2 new file mode 100644 index 0000000..07ab9ae --- /dev/null +++ b/dumps/scripts/4721.cs2 @@ -0,0 +1,33 @@ +cs2func_script_4721_struct(0,10,0) script_4721() { + string svar0; + string svar1; + string svar2; + string svar3; + string svar4; + string svar5; + string svar6; + string svar7; + string svar8; + string svar9; + svar0 = ""; + svar1 = ""; + svar2 = ""; + svar3 = ""; + svar4 = ""; + svar5 = ""; + svar6 = ""; + svar7 = ""; + svar8 = ""; + svar9 = ""; + svar0 = script_4345(clanbitconfig_25, clanbitconfig_26); + svar1 = script_4345(clanbitconfig_27, clanbitconfig_28); + svar2 = script_4345(clanbitconfig_29, clanbitconfig_30); + svar3 = script_4345(clanbitconfig_31, clanbitconfig_32); + svar4 = script_4345(clanbitconfig_33, clanbitconfig_34); + svar5 = script_4345(clanbitconfig_35, clanbitconfig_36); + svar6 = script_4345(clanbitconfig_37, clanbitconfig_38); + svar7 = script_4345(clanbitconfig_39, clanbitconfig_40); + svar8 = script_4345(clanbitconfig_41, clanbitconfig_42); + svar9 = script_4345(clanbitconfig_43, clanbitconfig_44); + return newstruct cs2func_script_4721_struct(svar0, svar1, svar2, svar3, svar4, svar5, svar6, svar7, svar8, svar9); +} diff --git a/dumps/scripts/4722.cs2 b/dumps/scripts/4722.cs2 new file mode 100644 index 0000000..9c9097e --- /dev/null +++ b/dumps/scripts/4722.cs2 @@ -0,0 +1,73 @@ +cs2func_script_4722_struct(1,1,0) script_4722(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + int ivar22; + int ivar23; + int ivar24; + int ivar25; + int ivar26; + int ivar27; + int ivar28; + string svar0; + svar0 = ""; + ivar2 = 0; + ivar3 = 0; + ivar4 = 0; + ivar5 = 0; + ivar6 = 0; + ivar7 = 0; + ivar8 = 0; + ivar9 = 0; + ivar10 = 0; + ivar11 = 0; + ivar12 = 0; + ivar13 = 0; + ivar14 = 0; + ivar15 = 0; + ivar16 = 0; + ivar17 = 0; + ivar18 = 0; + ivar19 = 0; + ivar20 = 0; + ivar21 = 0; + ivar22 = 0; + ivar23 = 0; + ivar24 = 0; + ivar25 = 0; + ivar26 = 0; + ivar27 = -1; + ivar28 = -1; + if (citadelConfigsInitialized()) { + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + if (((boolean)ivar26)) { + return newstruct cs2func_script_4722_struct(0, svar0); + } + return newstruct cs2func_script_4722_struct(1, svar0); +} diff --git a/dumps/scripts/4723.cs2 b/dumps/scripts/4723.cs2 new file mode 100644 index 0000000..852f874 --- /dev/null +++ b/dumps/scripts/4723.cs2 @@ -0,0 +1,47 @@ +cs2func_script_4723_struct(1,1,0) script_4723(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int stack_dump0; + int stack_dump1; + int stack_dump2; + ivar2 = 0; + ivar3 = 0; + ivar4 = 0; + ivar5 = 0; + ivar6 = 0; + ivar7 = 0; + ivar8 = 0; + ivar9 = 0; + ivar10 = 0; + ivar11 = 0; + ivar12 = 0; + ivar13 = -1; + if (citadelConfigsInitialized()) { + stack_dump0 = 105; + stack_dump1 = 74; + stack_dump2 = 4013; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + if (((boolean)ivar12)) { + return newstruct cs2func_script_4723_struct(0, "Downgrading this building would violate the requirements for your citadel walls."); + } + return newstruct cs2func_script_4723_struct(1, ""); +} diff --git a/dumps/scripts/4724.cs2 b/dumps/scripts/4724.cs2 new file mode 100644 index 0000000..ec0d7a0 --- /dev/null +++ b/dumps/scripts/4724.cs2 @@ -0,0 +1,574 @@ +cs2func_script_4724_struct(6,0,0) script_4724(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + int ivar22; + int ivar23; + int ivar24; + int ivar25; + int ivar26; + int ivar27; + int ivar28; + int ivar29; + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + ivar4 = 0; + ivar5 = 0; + ivar6 = 0; + ivar7 = 0; + ivar8 = 0; + ivar9 = 0; + ivar10 = 0; + ivar11 = 0; + ivar12 = 0; + if (citadelConfigsInitialized()) { + switch (arg0) { + case 1: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 2: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 3: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + switch (ivar3) { + case 21: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 22: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 23: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 24: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 25: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 26: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 27: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 28: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 31: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 32: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 33: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 34: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 35: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 41: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 42: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 43: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 44: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 45: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 51: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 100: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 101: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 102: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 103: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 104: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 105: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 106: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 107: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 108: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 109: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 110: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 111: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 112: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 113: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + } + ivar13 = 1; + ivar14 = 0; + ivar15 = 0; + ivar16 = 0; + ivar17 = 0; + ivar18 = 0; + ivar19 = 0; + ivar20 = 0; + ivar21 = 0; + ivar22 = 0; + ivar23 = 0; + ivar24 = 0; + ivar25 = 0; + ivar26 = -1; + ivar27 = -1; + ivar28 = -1; + ivar29 = -1; + ivar28 = cs2method_3408(105, 103, 4043, ivar1); + if (ivar28 == -1) { + return newstruct cs2func_script_4724_struct(0, 0, 0, 0, 0, 0); + } + ivar29 = cs2method_3408(105, 103, ivar28, ivar2); + if (ivar29 == -1) { + return newstruct cs2func_script_4724_struct(0, 0, 0, 0, 0, 0); + } + while (ivar13 <= 3) { + ivar26 = cs2method_3408(105, 103, ivar29, ivar13); + if (ivar26 != -1) { + switch (ivar13) { + case 1: + ivar27 = cs2method_3408(105, 74, ivar26, ivar4); + break; + case 2: + ivar27 = cs2method_3408(105, 74, ivar26, ivar5); + break; + case 3: + ivar27 = cs2method_3408(105, 74, ivar26, ivar6); + } + if (ivar27 != -1) { + if (((boolean)getOtherCommonData(ivar27, 1571))) { + ivar14 = add(ivar14, getOtherCommonData(ivar27, 1573)); + } else if (getOtherCommonData(ivar27, 1571) == 2) { + ivar15 = add(ivar15, getOtherCommonData(ivar27, 1573)); + } else if (getOtherCommonData(ivar27, 1571) == 5) { + ivar16 = add(ivar16, getOtherCommonData(ivar27, 1573)); + } else if (getOtherCommonData(ivar27, 1571) == 9) { + ivar17 = add(ivar17, getOtherCommonData(ivar27, 1573)); + } else if (getOtherCommonData(ivar27, 1571) == 8) { + ivar18 = add(ivar18, getOtherCommonData(ivar27, 1573)); + } else { + if (getOtherCommonData(ivar27, 1571) == 7) { + ivar19 = add(ivar19, getOtherCommonData(ivar27, 1573)); + } + } + if (((boolean)getOtherCommonData(ivar27, 1575))) { + ivar14 = add(ivar14, getOtherCommonData(ivar27, 1577)); + } else if (getOtherCommonData(ivar27, 1575) == 2) { + ivar15 = add(ivar15, getOtherCommonData(ivar27, 1577)); + } else if (getOtherCommonData(ivar27, 1575) == 5) { + ivar16 = add(ivar16, getOtherCommonData(ivar27, 1577)); + } else if (getOtherCommonData(ivar27, 1575) == 9) { + ivar17 = add(ivar17, getOtherCommonData(ivar27, 1577)); + } else if (getOtherCommonData(ivar27, 1575) == 8) { + ivar18 = add(ivar18, getOtherCommonData(ivar27, 1577)); + } else { + if (getOtherCommonData(ivar27, 1575) == 7) { + ivar19 = add(ivar19, getOtherCommonData(ivar27, 1577)); + } + } + if (((boolean)getOtherCommonData(ivar27, 1579))) { + ivar14 = add(ivar14, getOtherCommonData(ivar27, 1581)); + } else if (getOtherCommonData(ivar27, 1579) == 2) { + ivar15 = add(ivar15, getOtherCommonData(ivar27, 1581)); + } else if (getOtherCommonData(ivar27, 1579) == 5) { + ivar16 = add(ivar16, getOtherCommonData(ivar27, 1581)); + } else if (getOtherCommonData(ivar27, 1579) == 9) { + ivar17 = add(ivar17, getOtherCommonData(ivar27, 1581)); + } else if (getOtherCommonData(ivar27, 1579) == 8) { + ivar18 = add(ivar18, getOtherCommonData(ivar27, 1581)); + } else { + if (getOtherCommonData(ivar27, 1579) == 7) { + ivar19 = add(ivar19, getOtherCommonData(ivar27, 1581)); + } + } + } + } + ivar26 = -1; + ivar13 = add(ivar13, 1); + } + ivar13 = 1; + if ((ivar7 == ivar1) && (ivar8 == ivar2)) { + ivar28 = cs2method_3408(105, 103, 4043, ivar7); + ivar29 = cs2method_3408(105, 103, ivar28, ivar8); + while (ivar13 <= 3) { + ivar26 = cs2method_3408(105, 103, ivar29, ivar13); + if (ivar26 != -1) { + switch (ivar13) { + case 1: + ivar27 = cs2method_3408(105, 74, ivar26, ivar10); + break; + case 2: + ivar27 = cs2method_3408(105, 74, ivar26, ivar11); + break; + case 3: + ivar27 = cs2method_3408(105, 74, ivar26, ivar12); + } + if (ivar27 != -1) { + if (((boolean)getOtherCommonData(ivar27, 1571))) { + ivar20 = add(ivar20, getOtherCommonData(ivar27, 1573)); + } else if (getOtherCommonData(ivar27, 1571) == 2) { + ivar21 = add(ivar21, getOtherCommonData(ivar27, 1573)); + } else if (getOtherCommonData(ivar27, 1571) == 5) { + ivar22 = add(ivar22, getOtherCommonData(ivar27, 1573)); + } else if (getOtherCommonData(ivar27, 1571) == 9) { + ivar23 = add(ivar23, getOtherCommonData(ivar27, 1573)); + } else if (getOtherCommonData(ivar27, 1571) == 8) { + ivar24 = add(ivar24, getOtherCommonData(ivar27, 1573)); + } else { + if (getOtherCommonData(ivar27, 1571) == 7) { + ivar25 = add(ivar25, getOtherCommonData(ivar27, 1573)); + } + } + if (((boolean)getOtherCommonData(ivar27, 1575))) { + ivar20 = add(ivar20, getOtherCommonData(ivar27, 1577)); + } else if (getOtherCommonData(ivar27, 1575) == 2) { + ivar21 = add(ivar21, getOtherCommonData(ivar27, 1577)); + } else if (getOtherCommonData(ivar27, 1575) == 5) { + ivar22 = add(ivar22, getOtherCommonData(ivar27, 1577)); + } else if (getOtherCommonData(ivar27, 1575) == 9) { + ivar23 = add(ivar23, getOtherCommonData(ivar27, 1577)); + } else if (getOtherCommonData(ivar27, 1575) == 8) { + ivar24 = add(ivar24, getOtherCommonData(ivar27, 1577)); + } else { + if (getOtherCommonData(ivar27, 1575) == 7) { + ivar25 = add(ivar25, getOtherCommonData(ivar27, 1577)); + } + } + if (((boolean)getOtherCommonData(ivar27, 1579))) { + ivar20 = add(ivar20, getOtherCommonData(ivar27, 1581)); + } else if (getOtherCommonData(ivar27, 1579) == 2) { + ivar21 = add(ivar21, getOtherCommonData(ivar27, 1581)); + } else if (getOtherCommonData(ivar27, 1579) == 5) { + ivar22 = add(ivar22, getOtherCommonData(ivar27, 1581)); + } else if (getOtherCommonData(ivar27, 1579) == 9) { + ivar23 = add(ivar23, getOtherCommonData(ivar27, 1581)); + } else if (getOtherCommonData(ivar27, 1579) == 8) { + ivar24 = add(ivar24, getOtherCommonData(ivar27, 1581)); + } else { + if (getOtherCommonData(ivar27, 1579) == 7) { + ivar25 = add(ivar25, getOtherCommonData(ivar27, 1581)); + } + } + } + } + ivar26 = -1; + ivar13 = add(ivar13, 1); + } + } + ivar14 = max(0, subtract(ivar14, ivar20)); + ivar15 = max(0, subtract(ivar15, ivar21)); + ivar16 = max(0, subtract(ivar16, ivar22)); + ivar17 = max(0, subtract(ivar17, ivar23)); + ivar18 = max(0, subtract(ivar18, ivar24)); + ivar19 = max(0, subtract(ivar19, ivar25)); + return newstruct cs2func_script_4724_struct(ivar14, ivar15, ivar16, ivar17, ivar18, ivar19); +} diff --git a/dumps/scripts/4725.cs2 b/dumps/scripts/4725.cs2 new file mode 100644 index 0000000..7d35a26 --- /dev/null +++ b/dumps/scripts/4725.cs2 @@ -0,0 +1,86 @@ +void script_4725() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + string svar0; + ivar0 = 20316177; + ivar1 = 20316179; + ivar2 = 20316171; + ivar3 = 20316172; + ivar4 = 20316174; + ivar5 = 20316173; + ivar6 = 20316178; + svar0 = ""; + deleteAllExtraChilds(new WidgetPointer(ivar2)); + deleteAllExtraChilds(new WidgetPointer(ivar5)); + ivar7 = 15; + ivar8 = 1; + ivar9 = 0; + ivar10 = -1; + ivar11 = -1; + while (ivar8 <= 15) { + ivar9 = getExtraChildGap(new WidgetPointer(ivar2)); + createExtraChild(new WidgetPointer(ivar2), 4, ivar9); + setWidgetSize(5, ivar7, 1, 0); + setWidgetPosition(5, multiply(ivar9, ivar7), 0, 0); + setWidgetText(script_5329(ivar8)); + setWidgetFont(3793); + setWidgetRGB(new Color(190, 178, 140)); + setWidgetUnknownBoolean(true); + setWidgetTextAlignment(0, 1, 0); + ivar10 = 7715; + ivar11 = 7716; + createExtraChild(new WidgetPointer(ivar5), 5, ivar9); + setWidgetSprite(ivar10); + setWidgetContextMenuOption(1, "Target"); + setWidgetSize(12, 13, 0, 0); + setWidgetPosition(18, add(1, multiply(ivar9, ivar7)), 2, 0); + setScriptCallOnMouseEntered(5336, new WidgetPointer(-32768,3), -2147483643, ivar11, "Iid"); + setScriptCallOnMouseExit(5336, new WidgetPointer(-32768,3), -2147483643, ivar10, "Iid"); + cs2method1306("Add Actor"); + cs2method1308(176, -1); + createExtraChild(new WidgetPointer(ivar6), 3, getExtraChildGap(new WidgetPointer(ivar6))); + setWidgetSize(12, 13, 0, 0); + setWidgetPosition(18, add(1, multiply(ivar9, ivar7)), 2, 0); + svar0 = "Add someone to the actor list. Click this, then click on the person you would like to add."; + setScriptCallOnMouseOver(4538, new WidgetPointer(310,26), new WidgetPointer(-32768,3), -2147483643, svar0, 90, 3793, 3793, 16777215, 13, 4, 3, -2147483647, -2147483646, "IIisifdiiiiii"); + setScriptCallOnMouseExit(40, new WidgetPointer(310,26), "I"); + ivar10 = 7718; + ivar11 = 7719; + createExtraChild(new WidgetPointer(ivar4), 5, ivar9); + setWidgetSprite(ivar10); + setWidgetContextMenuOption(1, "Remove"); + setWidgetSize(12, 13, 0, 0); + setWidgetPosition(3, add(1, multiply(ivar9, ivar7)), 2, 0); + setScriptCallOnMouseEntered(5336, new WidgetPointer(-32768,3), -2147483643, ivar11, "Iid"); + setScriptCallOnMouseExit(5336, new WidgetPointer(-32768,3), -2147483643, ivar10, "Iid"); + createExtraChild(new WidgetPointer(ivar6), 3, getExtraChildGap(new WidgetPointer(ivar6))); + setWidgetSize(12, 13, 0, 0); + setWidgetPosition(3, add(1, multiply(ivar9, ivar7)), 2, 0); + svar0 = "Add someone to the actor list. Click this, then click on the person you would like to add."; + svar0 = "Remove this person from the actor list."; + setScriptCallOnMouseOver(4538, new WidgetPointer(310,26), new WidgetPointer(-32768,3), -2147483643, svar0, 90, 3793, 3793, 16777215, 13, 4, 3, -2147483647, -2147483646, "IIisifdiiiiii"); + setScriptCallOnMouseExit(40, new WidgetPointer(310,26), "I"); + ivar8 = add(ivar8, 1); + } + if (((boolean)globalint_1606)) { + ivar10 = 6009; + ivar11 = 6010; + } else { + ivar10 = 6004; + ivar11 = 6005; + } + setWidgetSprite(ivar10, new WidgetPointer(310,20)); + setScriptCallOnMouseEntered(44, new WidgetPointer(-32768,3), ivar11, "Id", new WidgetPointer(310,20)); + setScriptCallOnMouseExit(44, new WidgetPointer(-32768,3), ivar10, "Id", new WidgetPointer(310,20)); + return; +} diff --git a/dumps/scripts/4726.cs2 b/dumps/scripts/4726.cs2 new file mode 100644 index 0000000..57bbf6f --- /dev/null +++ b/dumps/scripts/4726.cs2 @@ -0,0 +1,234 @@ +cs2func_script_4726_struct(5,0,0) script_4726(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10) { + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + string svar0; + string svar1; + string svar2; + int stack_dump0; + int stack_dump1; + int stack_dump2; + int stack_dump3; + int stack_dump4; + int stack_dump5; + int stack_dump6; + int stack_dump7; + int stack_dump8; + int stack_dump9; + int stack_dump10; + cs2func_script_5351_struct(5,0,0) structdump_11; + flow_0: + ivar11 = 74907707; + ivar12 = 0; + ivar13 = -1; + svar0 = ""; + ivar14 = 0; + globalarray_0 = new int[getCommonDefinitionSize(arg0)]; + ivar15 = 0; + ivar16 = -1; + ivar17 = 0; + while (ivar17 < getCommonDefinitionSize(arg0)) { + globalarray_0[ivar17] = cs2method_3408(105, 74, arg0, ivar17); + ivar17 = add(ivar17, 1); + } + ivar17 = 0; + ivar15 = 1; + ivar18 = 0; + ivar19 = 0; + svar1 = ""; + svar2 = ""; + ivar20 = 0; + ivar21 = 0; + SWITCH (globalint_1659) { + case 1: + GOTO flow_18 + case 2: + GOTO flow_32 + case 3: + GOTO flow_61 + } + while (((boolean)ivar15)) { + ivar15 = 0; + ivar17 = subtract(getCommonDefinitionSize(arg0), 1); + while (ivar17 > 0) { + if (getOtherCommonData(globalarray_0[ivar17], 1933) > 0) { + ivar18 = getOtherCommonData(globalarray_0[ivar17], 1933); + } else { + ivar18 = getOtherCommonData(globalarray_0[ivar17], 1932); + } + if (getOtherCommonData(globalarray_0[subtract(ivar17, 1)], 1933) > 0) { + ivar19 = getOtherCommonData(globalarray_0[subtract(ivar17, 1)], 1933); + } else { + ivar19 = getOtherCommonData(globalarray_0[subtract(ivar17, 1)], 1932); + } + if (ivar18 < ivar19) { + ivar15 = 1; + ivar16 = globalarray_0[subtract(ivar17, 1)]; + globalarray_0[subtract(ivar17, 1)] = globalarray_0[ivar17]; + globalarray_0[ivar17] = ivar16; + } + ivar17 = subtract(ivar17, 1); + } + } + flow_17: + GOTO flow_89 + flow_18: + IF (((boolean)ivar15)) + GOTO flow_19 + GOTO flow_31 + flow_19: + ivar15 = 0; + ivar17 = subtract(getCommonDefinitionSize(arg0), 1); + while (ivar17 > 0) { + if (getOtherCommonData(globalarray_0[ivar17], 1933) > 0) { + ivar18 = getOtherCommonData(globalarray_0[ivar17], 1933); + } else { + ivar18 = getOtherCommonData(globalarray_0[ivar17], 1932); + } + if (getOtherCommonData(globalarray_0[subtract(ivar17, 1)], 1933) > 0) { + ivar19 = getOtherCommonData(globalarray_0[subtract(ivar17, 1)], 1933); + } else { + ivar19 = getOtherCommonData(globalarray_0[subtract(ivar17, 1)], 1932); + } + if (ivar18 > ivar19) { + ivar15 = 1; + ivar16 = globalarray_0[subtract(ivar17, 1)]; + globalarray_0[subtract(ivar17, 1)] = globalarray_0[ivar17]; + globalarray_0[ivar17] = ivar16; + } + ivar17 = subtract(ivar17, 1); + } + GOTO flow_18 + flow_31: + GOTO flow_89 + flow_32: + IF (((boolean)ivar15)) + GOTO flow_33 + GOTO flow_60 + flow_33: + ivar15 = 0; + ivar17 = subtract(getCommonDefinitionSize(arg0), 1); + while (ivar17 > 0) { + if (getOtherCommonData(globalarray_0[ivar17], 1937) == 4) { + ivar20 = 0; + ivar21 = 0; + while ((ivar20 < getCommonDefinitionSize(5184)) && ((boolean)ivar21)) { + if (cs2method_3408(105, 74, 5184, ivar20) == globalarray_0[ivar17]) { + if (IsFemale()) { + svar1 = cs2method_3408(105, 115, 5186, ivar20); + } else { + svar1 = cs2method_3408(105, 115, 5187, ivar20); + } + ivar21 = 1; + } + ivar20 = add(ivar20, 1); + } + ivar20 = 0; + ivar21 = 0; + while ((ivar20 < getCommonDefinitionSize(5184)) && ((boolean)ivar21)) { + if (cs2method_3408(105, 74, 5184, ivar20) == globalarray_0[subtract(ivar17, 1)]) { + if (IsFemale()) { + svar2 = cs2method_3408(105, 115, 5186, ivar20); + } else { + svar2 = cs2method_3408(105, 115, 5187, ivar20); + } + ivar21 = 1; + } + ivar20 = add(ivar20, 1); + } + } else { + svar1 = getOtherCommonData(globalarray_0[ivar17], 1930); + svar2 = getOtherCommonData(globalarray_0[subtract(ivar17, 1)], 1930); + } + if (stringMethod4107(svar1, svar2) < 0) { + ivar15 = 1; + ivar16 = globalarray_0[subtract(ivar17, 1)]; + globalarray_0[subtract(ivar17, 1)] = globalarray_0[ivar17]; + globalarray_0[ivar17] = ivar16; + } + ivar17 = subtract(ivar17, 1); + } + GOTO flow_32 + flow_60: + GOTO flow_89 + flow_61: + IF (((boolean)ivar15)) + GOTO flow_62 + GOTO flow_89 + flow_62: + ivar15 = 0; + ivar17 = subtract(getCommonDefinitionSize(arg0), 1); + while (ivar17 > 0) { + if (getOtherCommonData(globalarray_0[ivar17], 1937) == 4) { + ivar20 = 0; + ivar21 = 0; + while ((ivar20 < getCommonDefinitionSize(5184)) && ((boolean)ivar21)) { + if (cs2method_3408(105, 74, 5184, ivar20) == globalarray_0[ivar17]) { + if (IsFemale()) { + svar1 = cs2method_3408(105, 115, 5186, ivar20); + } else { + svar1 = cs2method_3408(105, 115, 5187, ivar20); + } + ivar21 = 1; + } + ivar20 = add(ivar20, 1); + } + ivar20 = 0; + ivar21 = 0; + while ((ivar20 < getCommonDefinitionSize(5184)) && ((boolean)ivar21)) { + if (cs2method_3408(105, 74, 5184, ivar20) == globalarray_0[subtract(ivar17, 1)]) { + if (IsFemale()) { + svar2 = cs2method_3408(105, 115, 5186, ivar20); + } else { + svar2 = cs2method_3408(105, 115, 5187, ivar20); + } + ivar21 = 1; + } + ivar20 = add(ivar20, 1); + } + } else { + svar1 = getOtherCommonData(globalarray_0[ivar17], 1930); + svar2 = getOtherCommonData(globalarray_0[subtract(ivar17, 1)], 1930); + } + if (stringMethod4107(svar1, svar2) > 0) { + ivar15 = 1; + ivar16 = globalarray_0[subtract(ivar17, 1)]; + globalarray_0[subtract(ivar17, 1)] = globalarray_0[ivar17]; + globalarray_0[ivar17] = ivar16; + } + ivar17 = subtract(ivar17, 1); + } + GOTO flow_61 + flow_89: + ivar17 = 0; + while (ivar17 < getCommonDefinitionSize(arg0)) { + ivar13 = globalarray_0[ivar17]; + stack_dump0 = ivar13; + stack_dump1 = arg1; + stack_dump2 = arg2; + stack_dump3 = arg3; + stack_dump4 = arg4; + stack_dump5 = arg5; + stack_dump6 = arg6; + stack_dump7 = arg7; + stack_dump8 = arg8; + stack_dump9 = arg9; + stack_dump10 = arg10; + structdump_11 = script_5351(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4, stack_dump5, stack_dump6, stack_dump7, stack_dump8, stack_dump9, stack_dump10); + arg6 = structdump_11.intpart_4; + arg4 = structdump_11.intpart_3; + arg3 = structdump_11.intpart_2; + arg2 = structdump_11.intpart_1; + arg1 = structdump_11.intpart_0; + ivar17 = add(ivar17, 1); + } + return newstruct cs2func_script_4726_struct(arg1, arg2, arg3, arg4, arg6); +} diff --git a/dumps/scripts/4727.cs2 b/dumps/scripts/4727.cs2 new file mode 100644 index 0000000..487c89b --- /dev/null +++ b/dumps/scripts/4727.cs2 @@ -0,0 +1,353 @@ +cs2func_script_4727_struct(5,0,0) script_4727(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9) { + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + string svar0; + string svar1; + int stack_dump0; + int stack_dump1; + int stack_dump2; + int stack_dump3; + int stack_dump4; + int stack_dump5; + int stack_dump6; + int stack_dump7; + int stack_dump8; + int stack_dump9; + int stack_dump10; + cs2func_script_5351_struct(5,0,0) structdump_11; + flow_0: + ivar10 = -1; + ivar11 = -1; + ivar12 = 0; + ivar13 = -1; + ivar14 = 0; + ivar15 = 0; + ivar16 = 0; + ivar17 = 0; + while (ivar16 < 5) { + switch (ivar16) { + case 0: + ivar10 = 5182; + break; + case 1: + ivar10 = 3875; + break; + case 2: + if (IsFemale()) { + ivar10 = 5189; + } else { + ivar10 = 5188; + } + break; + case 3: + ivar10 = 5184; + break; + case 4: + ivar10 = 5183; + } + ivar14 = 0; + while (ivar14 < getCommonDefinitionSize(ivar10)) { + switch (ivar16) { + case 0: + if (isBitFlagged(standart_config_2391, ivar14)) { + ivar15 = add(ivar15, 1); + } + break; + case 1: + if (isBitFlagged(standart_config_2392, ivar14)) { + ivar15 = add(ivar15, 1); + } + break; + case 2: + if (isBitFlagged(standart_config_2393, ivar14)) { + ivar15 = add(ivar15, 1); + } + break; + case 3: + if (isBitFlagged(standart_config_2394, ivar14)) { + ivar15 = add(ivar15, 1); + } + break; + case 4: + if (isBitFlagged(standart_config_2394, add(ivar14, 16))) { + ivar15 = add(ivar15, 1); + } + } + ivar14 = add(ivar14, 1); + } + ivar16 = add(ivar16, 1); + } + if (ivar15 < 1) { + return newstruct cs2func_script_4727_struct(arg0, arg1, arg2, arg3, arg5); + } + globalarray_0 = new int[ivar15]; + ivar17 = subtract(ivar15, 1); + ivar16 = 0; + while (ivar16 < 5) { + switch (ivar16) { + case 0: + ivar10 = 5182; + break; + case 1: + ivar10 = 3875; + break; + case 2: + if (IsFemale()) { + ivar10 = 5189; + } else { + ivar10 = 5188; + } + break; + case 3: + ivar10 = 5184; + break; + case 4: + ivar10 = 5183; + } + ivar14 = 0; + while (ivar14 < getCommonDefinitionSize(ivar10)) { + ivar11 = cs2method_3408(105, 74, ivar10, ivar14); + switch (ivar16) { + case 0: + if (isBitFlagged(standart_config_2391, ivar14)) { + globalarray_0[ivar17] = ivar11; + ivar17 = max(subtract(ivar17, 1), 0); + } + break; + case 1: + if (isBitFlagged(standart_config_2392, ivar14)) { + globalarray_0[ivar17] = ivar11; + ivar17 = max(subtract(ivar17, 1), 0); + } + break; + case 2: + if (isBitFlagged(standart_config_2393, ivar14)) { + globalarray_0[ivar17] = ivar11; + ivar17 = max(subtract(ivar17, 1), 0); + } + break; + case 3: + if (isBitFlagged(standart_config_2394, ivar14)) { + globalarray_0[ivar17] = ivar11; + ivar17 = max(subtract(ivar17, 1), 0); + } + break; + case 4: + if (isBitFlagged(standart_config_2394, add(ivar14, 16))) { + globalarray_0[ivar17] = ivar11; + ivar17 = max(subtract(ivar17, 1), 0); + } + } + ivar14 = add(ivar14, 1); + } + ivar16 = add(ivar16, 1); + } + ivar14 = 0; + ivar12 = 1; + ivar18 = 0; + ivar19 = 0; + svar0 = ""; + svar1 = ""; + ivar20 = 0; + ivar21 = 0; + SWITCH (globalint_1659) { + case 1: + GOTO flow_77 + case 2: + GOTO flow_91 + case 3: + GOTO flow_123 + } + while (((boolean)ivar12)) { + ivar12 = 0; + ivar14 = subtract(ivar15, 1); + while (ivar14 > 0) { + if (getOtherCommonData(globalarray_0[ivar14], 1933) > 0) { + ivar18 = getOtherCommonData(globalarray_0[ivar14], 1933); + } else { + ivar18 = getOtherCommonData(globalarray_0[ivar14], 1932); + } + if (getOtherCommonData(globalarray_0[subtract(ivar14, 1)], 1933) > 0) { + ivar19 = getOtherCommonData(globalarray_0[subtract(ivar14, 1)], 1933); + } else { + ivar19 = getOtherCommonData(globalarray_0[subtract(ivar14, 1)], 1932); + } + if (ivar18 < ivar19) { + ivar12 = 1; + ivar13 = globalarray_0[subtract(ivar14, 1)]; + globalarray_0[subtract(ivar14, 1)] = globalarray_0[ivar14]; + globalarray_0[ivar14] = ivar13; + } + ivar14 = subtract(ivar14, 1); + } + } + flow_76: + GOTO flow_154 + flow_77: + IF (((boolean)ivar12)) + GOTO flow_78 + GOTO flow_90 + flow_78: + ivar12 = 0; + ivar14 = subtract(ivar15, 1); + while (ivar14 > 0) { + if (getOtherCommonData(globalarray_0[ivar14], 1933) > 0) { + ivar18 = getOtherCommonData(globalarray_0[ivar14], 1933); + } else { + ivar18 = getOtherCommonData(globalarray_0[ivar14], 1932); + } + if (getOtherCommonData(globalarray_0[subtract(ivar14, 1)], 1933) > 0) { + ivar19 = getOtherCommonData(globalarray_0[subtract(ivar14, 1)], 1933); + } else { + ivar19 = getOtherCommonData(globalarray_0[subtract(ivar14, 1)], 1932); + } + if (ivar18 > ivar19) { + ivar12 = 1; + ivar13 = globalarray_0[subtract(ivar14, 1)]; + globalarray_0[subtract(ivar14, 1)] = globalarray_0[ivar14]; + globalarray_0[ivar14] = ivar13; + } + ivar14 = subtract(ivar14, 1); + } + GOTO flow_77 + flow_90: + GOTO flow_154 + flow_91: + IF (((boolean)ivar12)) + GOTO flow_92 + GOTO flow_122 + flow_92: + ivar12 = 0; + ivar14 = subtract(ivar15, 1); + while (ivar14 > 0) { + if (getOtherCommonData(globalarray_0[ivar14], 1937) == 4) { + ivar20 = 0; + ivar21 = 0; + while ((ivar20 < getCommonDefinitionSize(5184)) && ((boolean)ivar21)) { + if (cs2method_3408(105, 74, 5184, ivar20) == globalarray_0[ivar14]) { + if (IsFemale()) { + svar0 = cs2method_3408(105, 115, 5186, ivar20); + } else { + svar0 = cs2method_3408(105, 115, 5187, ivar20); + } + ivar21 = 1; + } + ivar20 = add(ivar20, 1); + } + } else { + svar0 = getOtherCommonData(globalarray_0[ivar14], 1930); + } + if (getOtherCommonData(globalarray_0[subtract(ivar14, 1)], 1937) == 4) { + ivar20 = 0; + ivar21 = 0; + while ((ivar20 < getCommonDefinitionSize(5184)) && ((boolean)ivar21)) { + if (cs2method_3408(105, 74, 5184, ivar20) == globalarray_0[subtract(ivar14, 1)]) { + if (IsFemale()) { + svar1 = cs2method_3408(105, 115, 5186, ivar20); + } else { + svar1 = cs2method_3408(105, 115, 5187, ivar20); + } + ivar21 = 1; + } + ivar20 = add(ivar20, 1); + } + } else { + svar1 = getOtherCommonData(globalarray_0[subtract(ivar14, 1)], 1930); + } + if (stringMethod4107(svar0, svar1) < 0) { + ivar12 = 1; + ivar13 = globalarray_0[subtract(ivar14, 1)]; + globalarray_0[subtract(ivar14, 1)] = globalarray_0[ivar14]; + globalarray_0[ivar14] = ivar13; + } + ivar14 = subtract(ivar14, 1); + } + GOTO flow_91 + flow_122: + GOTO flow_154 + flow_123: + IF (((boolean)ivar12)) + GOTO flow_124 + GOTO flow_154 + flow_124: + ivar12 = 0; + ivar14 = subtract(ivar15, 1); + while (ivar14 > 0) { + if (getOtherCommonData(globalarray_0[ivar14], 1937) == 4) { + ivar20 = 0; + ivar21 = 0; + while ((ivar20 < getCommonDefinitionSize(5184)) && ((boolean)ivar21)) { + if (cs2method_3408(105, 74, 5184, ivar20) == globalarray_0[ivar14]) { + if (IsFemale()) { + svar0 = cs2method_3408(105, 115, 5186, ivar20); + } else { + svar0 = cs2method_3408(105, 115, 5187, ivar20); + } + ivar21 = 1; + } + ivar20 = add(ivar20, 1); + } + } else { + svar0 = getOtherCommonData(globalarray_0[ivar14], 1930); + } + if (getOtherCommonData(globalarray_0[subtract(ivar14, 1)], 1937) == 4) { + ivar20 = 0; + ivar21 = 0; + while ((ivar20 < getCommonDefinitionSize(5184)) && ((boolean)ivar21)) { + if (cs2method_3408(105, 74, 5184, ivar20) == globalarray_0[subtract(ivar14, 1)]) { + if (IsFemale()) { + svar1 = cs2method_3408(105, 115, 5186, ivar20); + } else { + svar1 = cs2method_3408(105, 115, 5187, ivar20); + } + ivar21 = 1; + } + ivar20 = add(ivar20, 1); + } + } else { + svar1 = getOtherCommonData(globalarray_0[subtract(ivar14, 1)], 1930); + } + if (stringMethod4107(svar0, svar1) > 0) { + ivar12 = 1; + ivar13 = globalarray_0[subtract(ivar14, 1)]; + globalarray_0[subtract(ivar14, 1)] = globalarray_0[ivar14]; + globalarray_0[ivar14] = ivar13; + } + ivar14 = subtract(ivar14, 1); + } + GOTO flow_123 + flow_154: + ivar14 = 0; + while (ivar14 < ivar15) { + ivar11 = globalarray_0[ivar14]; + stack_dump0 = ivar11; + stack_dump1 = arg0; + stack_dump2 = arg1; + stack_dump3 = arg2; + stack_dump4 = arg3; + stack_dump5 = arg4; + stack_dump6 = arg5; + stack_dump7 = arg6; + stack_dump8 = arg7; + stack_dump9 = arg8; + stack_dump10 = arg9; + structdump_11 = script_5351(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4, stack_dump5, stack_dump6, stack_dump7, stack_dump8, stack_dump9, stack_dump10); + arg5 = structdump_11.intpart_4; + arg3 = structdump_11.intpart_3; + arg2 = structdump_11.intpart_2; + arg1 = structdump_11.intpart_1; + arg0 = structdump_11.intpart_0; + ivar14 = add(ivar14, 1); + } + return newstruct cs2func_script_4727_struct(arg0, arg1, arg2, arg3, arg5); +} diff --git a/dumps/scripts/4728.cs2 b/dumps/scripts/4728.cs2 new file mode 100644 index 0000000..4ba0514 --- /dev/null +++ b/dumps/scripts/4728.cs2 @@ -0,0 +1,16 @@ +void script_4728(int arg0) { + if (citadelConfigsInitialized()) { + script_4896(); + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + messageType0("Clan stronghold information not yet available."); + return; +} diff --git a/dumps/scripts/4729.cs2 b/dumps/scripts/4729.cs2 new file mode 100644 index 0000000..d83064e --- /dev/null +++ b/dumps/scripts/4729.cs2 @@ -0,0 +1,79 @@ +cs2func_script_4729_struct(0,8,0) script_4729() { + string svar0; + string svar1; + string svar2; + string svar3; + string svar4; + string svar5; + string svar6; + string svar7; + flow_0: + svar0 = ""; + svar1 = ""; + svar2 = ""; + svar3 = ""; + svar4 = ""; + svar5 = ""; + svar6 = ""; + svar7 = ""; + SWITCH (getLanguage()) { + case 1: + GOTO flow_1 + case 2: + GOTO flow_2 + case 3: + GOTO flow_3 + case 4: + GOTO flow_4 + } + svar0 = "/p"; + svar1 = "/c"; + svar2 = "/f"; + svar3 = "/g"; + svar4 = "\\p"; + svar5 = "\\c"; + svar6 = "\\f"; + svar7 = "\\g"; + GOTO flow_5 + flow_1: + svar0 = "/a"; + svar1 = "/c"; + svar2 = "/f"; + svar3 = "/g"; + svar4 = "\\a"; + svar5 = "\\c"; + svar6 = "\\f"; + svar7 = "\\g"; + GOTO flow_5 + flow_2: + svar0 = "/p"; + svar1 = "/c"; + svar2 = "/a"; + svar3 = "/i"; + svar4 = "\\p"; + svar5 = "\\c"; + svar6 = "\\a"; + svar7 = "\\i"; + GOTO flow_5 + flow_3: + svar0 = "/p"; + svar1 = "/c"; + svar2 = "/f"; + svar3 = "/g"; + svar4 = "\\p"; + svar5 = "\\c"; + svar6 = "\\f"; + svar7 = "\\g"; + GOTO flow_5 + flow_4: + svar0 = "/p"; + svar1 = "/c"; + svar2 = "/f"; + svar3 = "/g"; + svar4 = "\\p"; + svar5 = "\\c"; + svar6 = "\\f"; + svar7 = "\\g"; + flow_5: + return newstruct cs2func_script_4729_struct(svar0, svar4, svar1, svar5, svar2, svar6, svar3, svar7); +} diff --git a/dumps/scripts/473.cs2 b/dumps/scripts/473.cs2 new file mode 100644 index 0000000..1b8c43c --- /dev/null +++ b/dumps/scripts/473.cs2 @@ -0,0 +1,12 @@ +void script_473(int arg0,int arg1) { + if (getSkillActualLvl(19) < 25) { + setWidgetText(new WidgetPointer(arg0), "" + "A Farming level of " + intToStr(25) + " is required." + ""); + return; + } + if (bitconfig_2086 < arg1) { + setWidgetText(new WidgetPointer(arg0), "" + intToStr(arg1) + " Commendations required." + ""); + } else { + setWidgetText(new WidgetPointer(arg0), intToStr(arg1) + " Commendations."); + } + return; +} diff --git a/dumps/scripts/4730.cs2 b/dumps/scripts/4730.cs2 new file mode 100644 index 0000000..fd22179 --- /dev/null +++ b/dumps/scripts/4730.cs2 @@ -0,0 +1,115 @@ +int script_4730(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + if (strLength(globalstring_1) >= 3) { + if (((boolean)stringMethod4107(substr(0, 3, globalstring_1), "///"))) { + if (arg0 >= 0) { + if (arg1 >= arg2) { + cs2method5006(3); + globalstring_1 = substr(3, strLength(globalstring_1), globalstring_1); + if (stringMethod4107(globalstring_1, "") != 0) { + cs2method5008(globalstring_1); + } + cs2method5006(globalint_1651); + return 1; + } + message(43, 0, "Guests cannot chat in this Clan Chat channel."); + globalstring_1 = ""; + globalint_1028 = 0; + script_1558(0); + return 1; + } + globalint_41 = 0; + script_181(0); + script_178(); + script_84(); + script_89(); + messageType0("You aren't a guest in a visited Clan Chat channel."); + globalstring_1 = ""; + globalint_1028 = 0; + return 1; + } + if (((boolean)stringMethod4107(substr(0, 2, globalstring_1), "//"))) { + if (arg3 >= 0) { + if (arg4 >= arg5) { + cs2method5006(2); + globalstring_1 = substr(2, strLength(globalstring_1), globalstring_1); + if (stringMethod4107(globalstring_1, "") != 0) { + cs2method5008(globalstring_1); + } + cs2method5006(globalint_1651); + return 1; + } + message(43, 0, "Your rank is not high enough to talk in your clan chat."); + globalstring_1 = ""; + globalint_1028 = 0; + script_1558(0); + return 1; + } + globalint_41 = 0; + script_181(0); + script_178(); + script_84(); + script_89(); + messageType0("You aren't in a Clan Chat channel."); + globalstring_1 = ""; + globalint_1028 = 0; + return 1; + } + if (((boolean)stringMethod4107(substr(0, 1, globalstring_1), "/"))) { + cs2method5006(1); + globalstring_1 = substr(1, strLength(globalstring_1), globalstring_1); + if (stringMethod4107(globalstring_1, "") != 0) { + cs2method5008(globalstring_1); + } + cs2method5006(globalint_1651); + return 1; + } + } else if (strLength(globalstring_1) >= 2) { + if (((boolean)stringMethod4107(substr(0, 2, globalstring_1), "//"))) { + if (arg3 >= 0) { + if (arg4 >= arg5) { + cs2method5006(2); + globalstring_1 = substr(2, strLength(globalstring_1), globalstring_1); + if (stringMethod4107(globalstring_1, "") != 0) { + cs2method5008(globalstring_1); + } + cs2method5006(globalint_1651); + return 1; + } + message(43, 0, "Your rank is not high enough to talk in your clan chat."); + globalstring_1 = ""; + globalint_1028 = 0; + script_1558(0); + return 1; + } + globalint_41 = 0; + script_181(0); + script_178(); + script_84(); + script_89(); + messageType0("You aren't in a Clan Chat channel."); + globalstring_1 = ""; + globalint_1028 = 0; + return 1; + } + if (((boolean)stringMethod4107(substr(0, 1, globalstring_1), "/"))) { + cs2method5006(1); + globalstring_1 = substr(1, strLength(globalstring_1), globalstring_1); + if (stringMethod4107(globalstring_1, "") != 0) { + cs2method5008(globalstring_1); + } + cs2method5006(globalint_1651); + return 1; + } + } else { + if ((strLength(globalstring_1) >= 1) && ((boolean)stringMethod4107(substr(0, 1, globalstring_1), "/"))) { + cs2method5006(1); + globalstring_1 = substr(1, strLength(globalstring_1), globalstring_1); + if (stringMethod4107(globalstring_1, "") != 0) { + cs2method5008(globalstring_1); + } + cs2method5006(globalint_1651); + return 1; + } + } + return 0; +} diff --git a/dumps/scripts/4731.cs2 b/dumps/scripts/4731.cs2 new file mode 100644 index 0000000..b2ffe1d --- /dev/null +++ b/dumps/scripts/4731.cs2 @@ -0,0 +1,23 @@ +void script_4731(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + pressedButtons(3,0,0) structdump_0; + ivar2 = 0; + ivar3 = 0; + ivar4 = 0; + structdump_0 = getPressedMouseButtons(); + ivar4 = structdump_0.intpart_2; + ivar3 = structdump_0.intpart_1; + ivar2 = structdump_0.intpart_0; + ivar5 = add(cameraGetHrot(), multiply(subtract(globalint_1653, arg0), 2)); + ivar6 = subtract(cameraGetVrot(), subtract(globalint_1654, arg1)); + if ((((boolean)ivar3) && (globalint_173 != 1)) && ((bitconfig_542 != 1) && minimapSettingIs1())) { + cameraMethod5504(ivar6, ivar5); + } + globalint_1653 = arg0; + globalint_1654 = arg1; + return; +} diff --git a/dumps/scripts/4732.cs2 b/dumps/scripts/4732.cs2 new file mode 100644 index 0000000..5ffec65 --- /dev/null +++ b/dumps/scripts/4732.cs2 @@ -0,0 +1,8 @@ +void script_4732(int arg0,int arg1) { + if (isBitFlagged(standart_config_2396, arg1)) { + setWidgetSprite(6004, new WidgetPointer(arg0)); + } else { + setWidgetSprite(6011, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/4733.cs2 b/dumps/scripts/4733.cs2 new file mode 100644 index 0000000..fa90540 --- /dev/null +++ b/dumps/scripts/4733.cs2 @@ -0,0 +1,41 @@ +int script_4733(int arg0) { + int ivar1; + int ivar2; + ivar1 = divide(arg0, 32); + ivar2 = mod(arg0, 32); + switch (ivar1) { + case 0: + return isBitFlagged(globalint_700, ivar2); + case 1: + return isBitFlagged(globalint_701, ivar2); + case 2: + return isBitFlagged(globalint_702, ivar2); + case 3: + return isBitFlagged(globalint_703, ivar2); + case 4: + return isBitFlagged(globalint_704, ivar2); + case 5: + return isBitFlagged(globalint_705, ivar2); + case 6: + return isBitFlagged(globalint_706, ivar2); + case 7: + return isBitFlagged(globalint_707, ivar2); + case 8: + return isBitFlagged(globalint_708, ivar2); + case 9: + return isBitFlagged(globalint_709, ivar2); + case 10: + return isBitFlagged(globalint_710, ivar2); + case 11: + return isBitFlagged(globalint_711, ivar2); + case 12: + return isBitFlagged(globalint_712, ivar2); + case 13: + return isBitFlagged(globalint_713, ivar2); + case 14: + return isBitFlagged(globalint_714, ivar2); + case 15: + return isBitFlagged(globalint_715, ivar2); + } + return 0; +} diff --git a/dumps/scripts/4734.cs2 b/dumps/scripts/4734.cs2 new file mode 100644 index 0000000..02f3978 --- /dev/null +++ b/dumps/scripts/4734.cs2 @@ -0,0 +1,5 @@ +void script_4734() { + script_4736(74973184, 74973185); + script_4738(74973184, 74973185); + return; +} diff --git a/dumps/scripts/4735.cs2 b/dumps/scripts/4735.cs2 new file mode 100644 index 0000000..8488b8c --- /dev/null +++ b/dumps/scripts/4735.cs2 @@ -0,0 +1,4 @@ +void script_4735(int arg0,int arg1) { + script_4736(arg0, arg1); + return; +} diff --git a/dumps/scripts/4736.cs2 b/dumps/scripts/4736.cs2 new file mode 100644 index 0000000..3a3c479 --- /dev/null +++ b/dumps/scripts/4736.cs2 @@ -0,0 +1,24 @@ +void script_4736(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + ivar2 = getItemContainerLength(95); + ivar3 = -1; + if (bitconfig_9903 > 0) { + ivar3 = cs2method_3408(105, 118, 3879, bitconfig_9903); + if (ivar3 != -1) { + ivar2 = getItemContainerLength(ivar3); + } + } + cs2method2100(0, 0, new WidgetPointer(arg0)); + deleteAllExtraChilds(new WidgetPointer(arg0)); + ivar4 = 0; + while (ivar4 < ivar2) { + createExtraChild(new WidgetPointer(arg0), 5, ivar4); + setWidgetSize(0, 0, 0, 0); + setWidgetPosition(0, 0, 0, 0); + setWidgetHidden(1); + ivar4 = add(ivar4, 1); + } + return; +} diff --git a/dumps/scripts/4737.cs2 b/dumps/scripts/4737.cs2 new file mode 100644 index 0000000..69d0dfb --- /dev/null +++ b/dumps/scripts/4737.cs2 @@ -0,0 +1,8 @@ +void script_4737(int arg0) { + if (setWidgetRegister(new WidgetPointer(1144,0), 0)) { + script_4738(74973184, 74973185); + } + setWidgetIsHidden(true, new WidgetPointer(1144,45)); + setWidgetIsHidden(true, new WidgetPointer(1144,9)); + return; +} diff --git a/dumps/scripts/4738.cs2 b/dumps/scripts/4738.cs2 new file mode 100644 index 0000000..6e26892 --- /dev/null +++ b/dumps/scripts/4738.cs2 @@ -0,0 +1,73 @@ +void script_4738(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + ivar2 = divide(36, 4); + ivar3 = 0; + ivar4 = -1; + ivar5 = 0; + ivar6 = 0; + ivar7 = 0; + ivar8 = cs2method_3408(105, 118, 3879, bitconfig_9903); + ivar9 = 0; + while (ivar3 < getItemContainerLength(ivar8)) { + if (setWidgetRegister(new WidgetPointer(arg0), ivar3)) { + ivar4 = getItemIdInSlot(ivar8, ivar3); + ivar5 = getItemAmtInContainer(ivar8, ivar4); + if (((ivar4 != -1) && ((boolean)script_4733(ivar3))) && (ivar5 > 0)) { + ivar9 = add(ivar9, ivar5); + if (add(ivar7, 36) >= getWidgetActualWidth(new WidgetPointer(arg0))) { + ivar7 = 0; + ivar6 = add(add(ivar6, ivar2), 36); + } + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(ivar7, ivar6, 0, 0); + setWidgetHidden(0); + setItemOnWidgetMethod1200(ivar4, ivar5); + setWidgetShadowColor(new Color(51, 51, 51)); + setWidgetBorderThickness(1); + setWidgetContextMenuOption(1, "Delete"); + setWidgetContextMenuOption(10, "Examine"); + cs2method1305("" + getItemName(ivar4)); + ivar7 = add(add(ivar7, ivar2), 36); + setScriptCallOnClickContextMenu(4739, new WidgetPointer(-32768,3), -2147483643, -2147483644, "Iii"); + setScriptCallOnMouseEntered(4745, new WidgetPointer(-32768,3), -2147483643, "Ii"); + setScriptCallOnMouseExit(4746, new WidgetPointer(-32768,3), -2147483643, "Ii"); + } else { + setWidgetSize(0, 0, 0, 0); + setWidgetPosition(0, 0, 0, 0); + setWidgetHidden(1); + setScriptCallOnClickContextMenu(-1, ""); + } + } + ivar3 = add(ivar3, 1); + } + ivar10 = 0; + if (((boolean)ivar9)) { + ivar10 = 1; + } + setWidgetText(new WidgetPointer(1144,22), "Found " + "" + intToStr(ivar9) + "" + " " + chooseString(ivar10, "item", "items") + " of junk in your " + cs2method_3408(118, 115, 3882, ivar8)); + if (ivar7 > 0) { + ivar6 = add(ivar6, 32); + } + if (ivar6 > getWidgetActualHeight(new WidgetPointer(arg0))) { + setWidgetScrollMax(0, ivar6, new WidgetPointer(arg0)); + setWidgetPosition(-8, getWidgetActualY(new WidgetPointer(arg0)), 1, 0, new WidgetPointer(arg0)); + script_31(arg1, arg0, 792, 789, 790, 791, 773, 788); + if (setWidgetRegister(new WidgetPointer(arg1), 1)) { + script_37(arg1, arg0, cs2method2601(new WidgetPointer(arg0)), 1); + } + } else { + setWidgetScrollMax(0, 0, new WidgetPointer(arg0)); + cs2method2100(0, 0, new WidgetPointer(arg0)); + deleteAllExtraChilds(new WidgetPointer(arg1)); + setWidgetPosition(0, getWidgetActualY(new WidgetPointer(arg0)), 1, 0, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/4739.cs2 b/dumps/scripts/4739.cs2 new file mode 100644 index 0000000..fcda2ab --- /dev/null +++ b/dumps/scripts/4739.cs2 @@ -0,0 +1,19 @@ +void script_4739(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + ivar3 = 0; + ivar4 = -1; + ivar5 = -1; + if (bitconfig_9903 != 0) { + ivar5 = cs2method_3408(105, 118, 3879, bitconfig_9903); + if (((boolean)arg2) && setWidgetRegister(new WidgetPointer(1144,0), arg1)) { + ivar4 = getItemIdInSlot(ivar5, arg1); + if (ivar4 != -1) { + bitconfig_9904 = arg1; + script_4741(); + } + } + } + return; +} diff --git a/dumps/scripts/474.cs2 b/dumps/scripts/474.cs2 new file mode 100644 index 0000000..c76774c --- /dev/null +++ b/dumps/scripts/474.cs2 @@ -0,0 +1,12 @@ +void script_474(int arg0,int arg1) { + if (bitconfig_4302 < 110) { + setWidgetText(new WidgetPointer(arg0), "" + "Completion of Wolf Whistle required." + ""); + return; + } + if (bitconfig_2086 < arg1) { + setWidgetText(new WidgetPointer(arg0), "" + intToStr(arg1) + " Commendations required." + ""); + } else { + setWidgetText(new WidgetPointer(arg0), intToStr(arg1) + " Commendations."); + } + return; +} diff --git a/dumps/scripts/4740.cs2 b/dumps/scripts/4740.cs2 new file mode 100644 index 0000000..cebc07e --- /dev/null +++ b/dumps/scripts/4740.cs2 @@ -0,0 +1,4 @@ +void script_4740() { + script_4741(); + return; +} diff --git a/dumps/scripts/4741.cs2 b/dumps/scripts/4741.cs2 new file mode 100644 index 0000000..f31468e --- /dev/null +++ b/dumps/scripts/4741.cs2 @@ -0,0 +1,30 @@ +void script_4741() { + int ivar0; + int ivar1; + int ivar2; + ivar0 = 0; + ivar1 = -1; + ivar2 = -1; + if ((bitconfig_9904 < 99999) && (bitconfig_9903 != 0)) { + ivar2 = cs2method_3408(105, 118, 3879, bitconfig_9903); + if (setWidgetRegister(new WidgetPointer(1144,0), bitconfig_9904)) { + ivar0 = getItemAmtInSlot(ivar2, bitconfig_9904); + if (ivar0 > 0) { + ivar1 = getItemIdInSlot(ivar2, bitconfig_9904); + if (ivar1 != -1) { + setWidgetIsHidden(true, new WidgetPointer(1144,23)); + setWidgetIsHidden(false, new WidgetPointer(1144,22)); + setWidgetIsHidden(false, new WidgetPointer(1144,9)); + setWidgetIsHidden(false, new WidgetPointer(1144,45)); + if (((boolean)ivar0)) { + setWidgetText(new WidgetPointer(1144,55), "Are you sure you want to delete " + "" + getItemName(ivar1) + "" + "?"); + } else { + setWidgetText(new WidgetPointer(1144,55), "Are you sure you want to delete " + "" + getItemName(ivar1) + "" + " (" + "" + intToStr(ivar0) + "" + " items)?"); + } + setItemOnWidgetMethod2200(ivar1, ivar0, new WidgetPointer(1144,56)); + } + } + } + } + return; +} diff --git a/dumps/scripts/4742.cs2 b/dumps/scripts/4742.cs2 new file mode 100644 index 0000000..c53a95c --- /dev/null +++ b/dumps/scripts/4742.cs2 @@ -0,0 +1,6 @@ +void script_4742(int arg0) { + bitconfig_9904 = 99999; + setWidgetIsHidden(true, new WidgetPointer(1144,9)); + setWidgetIsHidden(true, new WidgetPointer(1144,45)); + return; +} diff --git a/dumps/scripts/4743.cs2 b/dumps/scripts/4743.cs2 new file mode 100644 index 0000000..125640e --- /dev/null +++ b/dumps/scripts/4743.cs2 @@ -0,0 +1,6 @@ +void script_4743() { + setWidgetSprite(4666, new WidgetPointer(556,8)); + setWidgetSprite(4664, new WidgetPointer(556,9)); + setWidgetSprite(4664, new WidgetPointer(556,10)); + return; +} diff --git a/dumps/scripts/4744.cs2 b/dumps/scripts/4744.cs2 new file mode 100644 index 0000000..8ce6e53 --- /dev/null +++ b/dumps/scripts/4744.cs2 @@ -0,0 +1,6 @@ +void script_4744() { + setWidgetSprite(4665, new WidgetPointer(556,8)); + setWidgetSprite(4663, new WidgetPointer(556,9)); + setWidgetSprite(4663, new WidgetPointer(556,10)); + return; +} diff --git a/dumps/scripts/4745.cs2 b/dumps/scripts/4745.cs2 new file mode 100644 index 0000000..a03e508 --- /dev/null +++ b/dumps/scripts/4745.cs2 @@ -0,0 +1,23 @@ +void script_4745(int arg0,int arg1) { + int ivar2; + int ivar3; + string svar0; + ivar2 = -1; + ivar3 = -1; + svar0 = "null"; + if (bitconfig_9903 != 0) { + ivar2 = cs2method_3408(105, 118, 3879, bitconfig_9903); + if (arg1 < getItemContainerLength(ivar2)) { + ivar3 = getItemIdInSlot(ivar2, arg1); + if (ivar3 != -1) { + svar0 = script_4747(ivar3); + if (strLength(svar0) > 0) { + setWidgetText(new WidgetPointer(1144,23), svar0); + setWidgetIsHidden(false, new WidgetPointer(1144,23)); + setWidgetIsHidden(true, new WidgetPointer(1144,22)); + } + } + } + } + return; +} diff --git a/dumps/scripts/4746.cs2 b/dumps/scripts/4746.cs2 new file mode 100644 index 0000000..dfb60fe --- /dev/null +++ b/dumps/scripts/4746.cs2 @@ -0,0 +1,5 @@ +void script_4746(int arg0,int arg1) { + setWidgetIsHidden(true, new WidgetPointer(1144,23)); + setWidgetIsHidden(false, new WidgetPointer(1144,22)); + return; +} diff --git a/dumps/scripts/4747.cs2 b/dumps/scripts/4747.cs2 new file mode 100644 index 0000000..5a75899 --- /dev/null +++ b/dumps/scripts/4747.cs2 @@ -0,0 +1,883 @@ +string script_4747(int arg0) { + flow_0: + SWITCH (arg0) { + case 7464: + GOTO flow_1 + case 5507: + GOTO flow_1 + case 5508: + GOTO flow_1 + case 15671: + GOTO flow_2 + case 15672: + GOTO flow_3 + case 2399: + GOTO flow_4 + case 2400: + GOTO flow_4 + case 2401: + GOTO flow_4 + case 1536: + GOTO flow_5 + case 1537: + GOTO flow_5 + case 1538: + GOTO flow_5 + case 1535: + GOTO flow_5 + case 1548: + GOTO flow_9 + case 1544: + GOTO flow_9 + case 1545: + GOTO flow_9 + case 1546: + GOTO flow_9 + case 1547: + GOTO flow_9 + case 1543: + GOTO flow_9 + case 1542: + GOTO flow_10 + case 271: + GOTO flow_11 + case 274: + GOTO flow_12 + case 272: + GOTO flow_12 + case 275: + GOTO flow_13 + case 276: + GOTO flow_14 + case 277: + GOTO flow_15 + case 666: + GOTO flow_16 + case 668: + GOTO flow_17 + case 667: + GOTO flow_18 + case 432: + GOTO flow_19 + case 433: + GOTO flow_20 + case 7956: + GOTO flow_21 + case 7957: + GOTO flow_22 + case 2418: + GOTO flow_23 + case 2421: + GOTO flow_24 + case 2419: + GOTO flow_24 + case 2423: + GOTO flow_25 + case 2424: + GOTO flow_26 + case 964: + GOTO flow_27 + case 755: + GOTO flow_28 + case 756: + GOTO flow_29 + case 753: + GOTO flow_30 + case 290: + GOTO flow_31 + case 291: + GOTO flow_32 + case 761: + GOTO flow_33 + case 763: + GOTO flow_34 + case 765: + GOTO flow_34 + case 769: + GOTO flow_35 + case 1549: + GOTO flow_36 + case 300: + GOTO flow_37 + case 14062: + GOTO flow_38 + case 14064: + GOTO flow_39 + case 14065: + GOTO flow_40 + case 14066: + GOTO flow_41 + case 14067: + GOTO flow_42 + case 14068: + GOTO flow_43 + case 14069: + GOTO flow_44 + case 14070: + GOTO flow_45 + case 14071: + GOTO flow_46 + case 14072: + GOTO flow_47 + case 14073: + GOTO flow_48 + case 14074: + GOTO flow_49 + case 14075: + GOTO flow_50 + case 9590: + GOTO flow_51 + case 9589: + GOTO flow_51 + case 9591: + GOTO flow_52 + case 524: + GOTO flow_53 + case 525: + GOTO flow_53 + case 522: + GOTO flow_53 + case 523: + GOTO flow_53 + case 12546: + GOTO flow_53 + case 2409: + GOTO flow_54 + case 2408: + GOTO flow_55 + case 2410: + GOTO flow_56 + case 2411: + GOTO flow_57 + case 11211: + GOTO flow_58 + case 11210: + GOTO flow_58 + case 11203: + GOTO flow_58 + case 11202: + GOTO flow_58 + case 11204: + GOTO flow_58 + case 11198: + GOTO flow_58 + case 11196: + GOTO flow_58 + case 11197: + GOTO flow_58 + case 1584: + GOTO flow_59 + case 463: + GOTO flow_60 + case 462: + GOTO flow_60 + case 461: + GOTO flow_60 + case 460: + GOTO flow_60 + case 459: + GOTO flow_60 + case 458: + GOTO flow_60 + case 457: + GOTO flow_60 + case 456: + GOTO flow_60 + case 774: + GOTO flow_61 + case 773: + GOTO flow_61 + case 1856: + GOTO flow_62 + case 1858: + GOTO flow_63 + case 1857: + GOTO flow_63 + case 90: + GOTO flow_64 + case 83: + GOTO flow_65 + case 21: + GOTO flow_66 + case 20: + GOTO flow_66 + case 23: + GOTO flow_66 + case 22: + GOTO flow_66 + case 15: + GOTO flow_67 + case 17: + GOTO flow_68 + case 18: + GOTO flow_69 + case 19: + GOTO flow_70 + case 587: + GOTO flow_71 + case 588: + GOTO flow_71 + case 77: + GOTO flow_72 + case 76: + GOTO flow_73 + case 2403: + GOTO flow_74 + case 2404: + GOTO flow_75 + case 1508: + GOTO flow_76 + case 1503: + GOTO flow_77 + case 1509: + GOTO flow_78 + case 1510: + GOTO flow_79 + case 1466: + GOTO flow_80 + case 9665: + GOTO flow_81 + case 292: + GOTO flow_82 + case 298: + GOTO flow_83 + case 296: + GOTO flow_84 + case 297: + GOTO flow_84 + case 423: + GOTO flow_85 + case 425: + GOTO flow_86 + case 424: + GOTO flow_86 + case 422: + GOTO flow_86 + case 420: + GOTO flow_87 + case 415: + GOTO flow_88 + case 417: + GOTO flow_88 + case 416: + GOTO flow_88 + case 419: + GOTO flow_88 + case 418: + GOTO flow_88 + case 783: + GOTO flow_89 + case 784: + GOTO flow_90 + case 785: + GOTO flow_91 + case 786: + GOTO flow_92 + case 793: + GOTO flow_93 + case 788: + GOTO flow_94 + case 794: + GOTO flow_95 + case 787: + GOTO flow_96 + case 791: + GOTO flow_97 + case 790: + GOTO flow_97 + case 789: + GOTO flow_97 + case 792: + GOTO flow_97 + case 2529: + GOTO flow_98 + case 1484: + GOTO flow_98 + case 1483: + GOTO flow_98 + case 1482: + GOTO flow_98 + case 1481: + GOTO flow_98 + case 1486: + GOTO flow_99 + case 1493: + GOTO flow_100 + case 1490: + GOTO flow_100 + case 1488: + GOTO flow_100 + case 1489: + GOTO flow_100 + case 1487: + GOTO flow_100 + case 1494: + GOTO flow_101 + case 1500: + GOTO flow_102 + case 1502: + GOTO flow_103 + case 1501: + GOTO flow_103 + case 1498: + GOTO flow_103 + case 1499: + GOTO flow_103 + case 1496: + GOTO flow_103 + case 1497: + GOTO flow_103 + case 603: + GOTO flow_104 + case 602: + GOTO flow_104 + case 1852: + GOTO flow_105 + case 1851: + GOTO flow_106 + case 1841: + GOTO flow_107 + case 1842: + GOTO flow_108 + case 1849: + GOTO flow_109 + case 1855: + GOTO flow_110 + case 9904: + GOTO flow_111 + case 2388: + GOTO flow_112 + case 2387: + GOTO flow_112 + case 2386: + GOTO flow_112 + case 2385: + GOTO flow_112 + case 2384: + GOTO flow_112 + case 2374: + GOTO flow_113 + case 2375: + GOTO flow_113 + case 2373: + GOTO flow_113 + case 2382: + GOTO flow_114 + case 2383: + GOTO flow_114 + case 2380: + GOTO flow_114 + case 2381: + GOTO flow_114 + case 2378: + GOTO flow_115 + case 2379: + GOTO flow_115 + case 2377: + GOTO flow_115 + case 2397: + GOTO flow_115 + case 2395: + GOTO flow_115 + case 2394: + GOTO flow_115 + case 2393: + GOTO flow_115 + case 0: + GOTO flow_116 + case 1: + GOTO flow_117 + case 1822: + GOTO flow_118 + case 715: + GOTO flow_119 + case 714: + GOTO flow_119 + case 750: + GOTO flow_120 + case 717: + GOTO flow_121 + case 719: + GOTO flow_121 + case 718: + GOTO flow_121 + case 729: + GOTO flow_121 + case 720: + GOTO flow_121 + case 9716: + GOTO flow_122 + case 2888: + GOTO flow_123 + case 2889: + GOTO flow_123 + case 2954: + GOTO flow_124 + case 2953: + GOTO flow_124 + case 2967: + GOTO flow_125 + case 3103: + GOTO flow_126 + case 3102: + GOTO flow_126 + case 3104: + GOTO flow_127 + case 3112: + GOTO flow_128 + case 3113: + GOTO flow_128 + case 3110: + GOTO flow_128 + case 3111: + GOTO flow_128 + case 3109: + GOTO flow_128 + case 3207: + GOTO flow_129 + case 3206: + GOTO flow_129 + case 3208: + GOTO flow_130 + case 3267: + GOTO flow_131 + case 3268: + GOTO flow_132 + case 3395: + GOTO flow_133 + case 10830: + GOTO flow_134 + case 10835: + GOTO flow_135 + case 10834: + GOTO flow_135 + case 10833: + GOTO flow_135 + case 10832: + GOTO flow_135 + case 10831: + GOTO flow_135 + case 10842: + GOTO flow_136 + case 3846: + GOTO flow_137 + case 3847: + GOTO flow_137 + case 3845: + GOTO flow_137 + case 3895: + GOTO flow_138 + case 3894: + GOTO flow_138 + case 3896: + GOTO flow_139 + case 4073: + GOTO flow_140 + case 4193: + GOTO flow_141 + case 4192: + GOTO flow_141 + case 4189: + GOTO flow_141 + case 4190: + GOTO flow_141 + case 4191: + GOTO flow_141 + case 4204: + GOTO flow_142 + case 4206: + GOTO flow_143 + case 4205: + GOTO flow_143 + case 4238: + GOTO flow_144 + case 4272: + GOTO flow_145 + case 4249: + GOTO flow_145 + case 4248: + GOTO flow_145 + case 4247: + GOTO flow_145 + case 4273: + GOTO flow_146 + case 4415: + GOTO flow_147 + case 4490: + GOTO flow_148 + case 4496: + GOTO flow_149 + case 4568: + GOTO flow_150 + case 4597: + GOTO flow_151 + case 4598: + GOTO flow_151 + case 4606: + GOTO flow_152 + case 4615: + GOTO flow_153 + case 4616: + GOTO flow_153 + case 4617: + GOTO flow_154 + case 4623: + GOTO flow_155 + case 4619: + GOTO flow_156 + case 4684: + GOTO flow_157 + case 4686: + GOTO flow_158 + case 4814: + GOTO flow_159 + case 4815: + GOTO flow_159 + case 4817: + GOTO flow_159 + case 6072: + GOTO flow_160 + case 6077: + GOTO flow_161 + case 6079: + GOTO flow_161 + case 6073: + GOTO flow_161 + case 6075: + GOTO flow_161 + case 6104: + GOTO flow_162 + case 6083: + GOTO flow_162 + case 6546: + GOTO flow_163 + case 6545: + GOTO flow_163 + } + return "You should get rid of the " + getItemName(arg0); + flow_1: + return "That's my book! What's it doing in your bank?"; + flow_2: + return "You have Roddeck's book on dragon rearing in your bank. I don't think it's a great discourse on the subject, to be quite honest."; + flow_3: + return "I see you're hanging on to Roddeck's diary. It's got a seeking spell on it, you know. If you get rid of it, it'll find its way back to him."; + flow_4: + return "You've killed Delrith, so you don't need any of the little grey keys that you collected to get Silverlight."; + flow_5: + if (((boolean)bitconfig_3741)) { + return "You've opened a secret passageway to Crandor Island, so you won't need the map that showed you how to get there by sea."; + } + return "Ned knows the way to Crandor now, so you don't need the map any more. Also, if you go there, look around for secret passages. There might be another way to get back to Crandor."; + flow_9: + return "The coloured keys from Melzar's maze are very pretty, but you don't really need to keep them. If you ever go there again, the creatures in the maze will drop more coloured keys for you."; + flow_10: + return "You don't really need to keep the key to Melzar's Maze. If you ever go there again, you can ask for a new one from the Guildmaster of the Champions' Guild."; + flow_11: + return "Since you've already helped to repair Professor Oddenstein's machine, you can get rid of the pressure gauge."; + flow_12: + return "You really don't need to keep fish food in your bank."; + flow_13: + return "The little key that opens a closet in Draynor Manor? I think you can afford to get rid of it."; + flow_14: + return "You aren't going to need that rubber tube again."; + flow_15: + return "No need to keep that oil can."; + flow_16: + return "That's a nice picture of Sir Vyvin, but you don't really need it."; + flow_17: + return "Blurite ore's handy for making ceremonial swords, but you've already done that quest. Members can make crossbows and bolts out of it, but it has no other use."; + flow_18: + return "You don't really need a copy of Sir Vyvin's sword, although it's a fairly nice weapon."; + flow_19: + return "I see you've got the key to One-Eyed Hector's chest. That's not much use to you."; + flow_20: + return "You've already found the pirate's treasure, so you can get rid of the pirate's message."; + flow_21: + return "You've already found the pirate's treasure, so you can get rid of the pirate's casket."; + flow_22: + return "You've already found the pirate's treasure, so you can get rid of the pirate's apron."; + flow_23: + return "You aren't going to need to get back into Prince Ali's cell."; + flow_24: + return "You don't need a wig. Your head looks fine."; + flow_25: + return "I can't imagine why you've kept the imprint of Lady Keli's key."; + flow_26: + return "If you want to change your appearance, go to the Makeover Mage. You don't need this skin paste."; + flow_27: + return "I suggest you get rid of the skull. It's unhygienic."; + flow_28: + return "You have a message from Juliet to Romeo. There's no point in keeping that now that they've split up."; + flow_29: + return "A potion made from cadava berries? There's not much you can do with one of those."; + flow_30: + return "If you get rid of those cadava berries, you'll still be able to pick more near Varrock, and you'll save bank space."; + flow_31: + return "Sedridor's research into the mysteries of the runes is very interesting, but you don't need it."; + flow_32: + return "Aubury's notes won't be of any further use to you. You can't even read them!"; + flow_33: + return "You won't need Jonny the Beard's intelligence report now that you've found the Shield of Arrav."; + flow_34: + return "You don't need to keep bits of the Shield of Arrav now that you've completed that quest."; + flow_35: + return "You can get rid of the little certificate from the Museum of Varrock. You've already been rewarded for taking one to the King."; + flow_36: + return "Now that you've slain Count Draynor, you don't need that stake. It's not much use against other vampyres."; + flow_37: + return "Ugh... A rat's tail! Get rid of it!"; + flow_38: + return "I don't think you'll need the broom ointment."; + flow_39: + return "That newt doesn't look very useful."; + flow_40: + return "You probably won't need the 'Newts' label."; + flow_41: + return "You probably won't need the 'Toads' label."; + flow_42: + return "You certainly won't need the 'Newts & Toads' label."; + flow_43: + return "Betty's wand? I don't think you should be messing around with that."; + flow_44: + return "There's no point in hanging on to that slate."; + flow_45: + return "You shouldn't be keeping that reptile in there."; + flow_46: + return "You shouldn't be keeping that blackbird in there."; + flow_47: + return "You shouldn't be keeping that bat in there."; + flow_48: + return "You shouldn't be keeping that spider in there."; + flow_49: + return "You shouldn't be keeping that rat in there."; + flow_50: + return "You shouldn't be keeping that snail in there."; + flow_51: + return "You don't need to keep the dossier from the White Knight."; + flow_52: + return "You completed the Black Knights' fortress; you don't need this old cauldron anymore."; + flow_53: + return "You have completed the druidic ritual. You don't need the enchanted meat any longer."; + flow_54: + return "You don't need the witch's door key any longer."; + flow_55: + return "You don't need to keep the witch's diary. You can get it from the bookshelf again, if you need to."; + flow_56: + return "You don't need the magnet. You opened the witch's back door."; + flow_57: + return "You don't really need the witch's shed key any more."; + flow_58: + return "You don't need that grim looking item."; + flow_59: + return "You've already given the id papers to Grip. This must be a forgery!"; + flow_60: + return "You don't need that scorpion cage anymore."; + flow_61: + return "You've obtained Avan's part of the crest. You don't need the perfect ruby jewellery."; + flow_62: + return "You've already read from the Ardougne tourist guide."; + flow_63: + return "You've finished the Tribal Totem quest. Why do you still have this?"; + flow_64: + return "You've given this blanket to the monk already. Did you steal it back again?"; + flow_65: + return "You already fixed the lever in The Temple of Ikov."; + flow_66: + return "You've finished the Clock Tower quest. You don't need that cog."; + flow_67: + return "You completed the Holy Grail quest. You don't need Sir Galahad's table napkin."; + flow_68: + return "You completed the Holy Grail quest. You don't need the grail bell anymore."; + flow_69: + return "You completed the Holy Grail quest. You have no need of King Arthur's golden feather."; + flow_70: + return "You completed the Holy Grail quest. Why do you have the grail?"; + flow_71: + return "You have finished with Tree Gnome Village. You don't need the orbs."; + flow_72: + return "You already got the keys from the lazy guard. You don't need the brew."; + flow_73: + return "You have already used the keys from the lazy guard."; + flow_74: + return "You already completed the Hazeel Cult Quest; no need to hang onto one of those scrolls."; + flow_75: + return "You have already opened the chest in the Carnillean household."; + flow_76: + return "You have already made Bravek a hangover cure. You don't need his scrawled note."; + flow_77: + return "You have no need of a warrant to the plague house."; + flow_78: + return "You have already given this book to Ted Rehnison. You don't need it."; + flow_79: + return "You have already shown Elena's picture to Jethick."; + flow_80: + return "Yuck! A sea slug! Get rid of it!"; + flow_81: + return "A sea slug torch... Fascinating! You don't need it; lit, unlit, smouldering or otherwise."; + flow_82: + return "You have completed the Waterfall quest, so you don't need the book about Baxtorian."; + flow_83: + return "You have completed the Waterfall quest, so you don't need this key."; + flow_84: + return "You have finished the Waterfall quest, so you certainly don't need that urn; empty or full."; + flow_85: + return "You've freed Elena already, so you don't need the key."; + flow_86: + return "You have already distracted the guards with the pigeons."; + flow_87: + return "You've already retreived Elena's distillator."; + flow_88: + return "Guidor has already tested the plague sample. you don't need that any more."; + flow_89: + return "You have given the bark sample to Hazelmere already."; + flow_90: + return "You have already translated the ancient message told to you by Hazelmere."; + flow_91: + return "You have completed the Grand Tree quest. You have no need of Glough's Journal."; + flow_92: + return "You have completed the Grand Tree quest. You have no need of Hazelmere's scroll."; + flow_93: + return "You have completed the Grand Tree quest. You don't need this rock."; + flow_94: + return "You have already searched the Glough's chest. You have no possible use for the key."; + flow_95: + return "You have already given the invasion plans to the King."; + flow_96: + return "You have completed the Grand Tree quest. You don't need to hold on to this lumber order."; + flow_97: + return "You have already opened the watchtower entrance; you don't need twigs."; + flow_98: + return "The orbs are pretty, but you have already found your way down the well in the underground pass."; + flow_99: + return "Railings... Useful for poking undead in cages, I guess, but of no value otherwise."; + flow_100: + return "You have already passed the gate of Zamorak. You don't need this."; + flow_101: + return "You have killed Iban. You have little use for his journal."; + flow_102: + return "You have already done all you can with Iban's shadow."; + flow_103: + return "You have completed the four tasks with the doll."; + flow_104: + return "The professor has already fixed his telescope. You don't need this."; + flow_105: + return "You have already opened the Captain's chest with the copied key."; + flow_106: + return "A pineapple! How wonderful... You don't need it."; + flow_107: + return "You have already returned Ana to the Shantay Pass. You don't need to carry the barrel around."; + flow_108: + return "You have already returned Ana to the Shantay Pass. You don't need to carry the barrel around... or Ana."; + flow_109: + GOTO flow_164 + flow_110: + return "You don't need that rock unless you plan on being caught by the guards agasin."; + flow_111: + return "The book on sailing is rather dull."; + flow_112: + return "You have already given evidence to the wizard."; + flow_113: + return "You have already received the ogre relic. You don't need these relic parts."; + flow_114: + return "You have already used the powering crystals."; + flow_115: + return "You have already received the powering crystals from this item."; + flow_116: + return "You have already returned the dwarf remains to Captain Lawgof."; + flow_117: + return "You have already returned the dwarven toolkit to Captain Lawgof."; + flow_118: + return "You have already solved the murder mystery. You don't need this fingerprint."; + flow_119: + return "You have already presented the Radimus notes."; + flow_120: + return "You have already presented the gilded totem."; + flow_121: + return "You have freed Ungadulu from possession. You don't have any use for the scrawled notes, books, tomes or pictures of dirty old bowls."; + flow_122: + return "What are you going to do with that rock?"; + flow_123: + return "You do not need the Elemental workshop bowl."; + flow_124: + return "You have doused the vampyre's coffin already. You don't need this old bucket of stale water."; + flow_125: + return "You don't need Filliman's Journal."; + flow_126: + return "You have already recovered the combination for Denulf."; + flow_127: + return "You have already recovered the secret way map for Denulf."; + flow_128: + return "You don't need those coloured cannonballs"; + flow_129: + return "You don't need the king's summons or messages."; + flow_130: + return "You can get rid of the crystal pendant. It has served it's purpose."; + flow_131: + return "You don't need that dirty old druid's robe."; + flow_132: + return "Argh! Is that a man in your backpack? Wait...no! It's a fake man, you crafty so-and-so. Still, you don't need it."; + flow_133: + return "You have already sold the apothecary this book."; + flow_134: + return "You've already given King Sorvott's decree to Burgher."; + flow_135: + return "You have already collected King Sorvott IV's window taxes."; + flow_136: + return "You have already handed in the troll's talking head to the Burgher."; + flow_137: + return "You have completed the Horror from the Deep quest. You probably don't need this book."; + flow_138: + return "You have already given the Etceteria anthem to Queen Sigrid."; + flow_139: + return "You have already given the treaty to King Vargas to sign."; + flow_140: + return "A damp tinderbox; not at all useful for anything."; + flow_141: + return "You already retrieved the lightning conductor mould from the chimney. You don't need this brush."; + flow_142: + return "You don't need the dusty old letter from the clock."; + flow_143: + return "You have already planted this seed for Eluned."; + flow_144: + return "Yuck! An ectoplasm puddle."; + flow_145: + return "You have already given that to the crone."; + flow_146: + return "You have already made the toy boat. You don't need this key."; + flow_147: + return "You already have an axe that's been sharpened by Brian. You don't need this blunt one."; + flow_148: + return "You have already spread enough mud over that poor tree."; + flow_149: + return "A broken stick. Really? You kept a broken stick?"; + flow_150: + return "You have already retrieved the schematic from that book."; + flow_151: + return "You have already solved the safe combination."; + flow_152: + return "You have already caught the snake with this basket."; + flow_153: + return "You have already found out about the golem. You don't need the note or letter."; + flow_154: + return "You have already retrieved the statuette from the display case."; + flow_155: + return "You have already reprogrammed the golem. You don't need this pen."; + flow_156: + return "You have already opened the golem's head. You don't need this key."; + flow_157: + return "You don't need more linen for mummification, however much you might like to."; + flow_158: + return "You don't need the book on embalming."; + flow_159: + return "You have already shown the portrait to Zavistic Rarve."; + flow_160: + return "You have already washed the mourner's top."; + flow_161: + return "You have finished the Mourning's End quest. You don't need the mourner's books."; + flow_162: + return "You have finished the Mourning's End quest. You don't need that key."; + flow_163: + return "You have already completed all the chores for Bob."; + flow_164: + return ""; +} diff --git a/dumps/scripts/4748.cs2 b/dumps/scripts/4748.cs2 new file mode 100644 index 0000000..bceab54 --- /dev/null +++ b/dumps/scripts/4748.cs2 @@ -0,0 +1,4 @@ +void script_4748() { + setWidgetIsHidden(true, new WidgetPointer(993,261)); + return; +} diff --git a/dumps/scripts/4749.cs2 b/dumps/scripts/4749.cs2 new file mode 100644 index 0000000..918cdf8 --- /dev/null +++ b/dumps/scripts/4749.cs2 @@ -0,0 +1,4 @@ +void script_4749() { + script_4750(); + return; +} diff --git a/dumps/scripts/475.cs2 b/dumps/scripts/475.cs2 new file mode 100644 index 0000000..550f477 --- /dev/null +++ b/dumps/scripts/475.cs2 @@ -0,0 +1,5 @@ +void script_475(int arg0,int arg1) { + script_679(arg0); + script_41(arg1); + return; +} diff --git a/dumps/scripts/4750.cs2 b/dumps/scripts/4750.cs2 new file mode 100644 index 0000000..b3fc479 --- /dev/null +++ b/dumps/scripts/4750.cs2 @@ -0,0 +1,12 @@ +void script_4750() { + int ivar0; + int ivar1; + if (getDisplayMode() <= 1) { + setWidgetPosition(0, 0, 1, 1, new WidgetPointer(933,1)); + return; + } + ivar0 = divide(subtract(getWidgetActualWidth(new WidgetPointer(933,0)), getWidgetActualWidth(new WidgetPointer(933,1))), 2); + ivar1 = divide(subtract(getWidgetActualHeight(new WidgetPointer(933,0)), getWidgetActualHeight(new WidgetPointer(933,1))), 2); + setWidgetPosition(max(ivar0, 223), max(ivar1, 165), 2, 2, new WidgetPointer(933,1)); + return; +} diff --git a/dumps/scripts/4751.cs2 b/dumps/scripts/4751.cs2 new file mode 100644 index 0000000..48c28b7 --- /dev/null +++ b/dumps/scripts/4751.cs2 @@ -0,0 +1,4 @@ +void script_4751(int arg0,int arg1) { + script_311(arg0, arg1, getOtherCommonData(2722, 596)); + return; +} diff --git a/dumps/scripts/4752.cs2 b/dumps/scripts/4752.cs2 new file mode 100644 index 0000000..fb12ee1 --- /dev/null +++ b/dumps/scripts/4752.cs2 @@ -0,0 +1,8 @@ +void script_4752() { + if (isWidgetHidden(new WidgetPointer(1143,6))) { + setWidgetIsHidden(false, new WidgetPointer(1143,6)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1143,6)); + } + return; +} diff --git a/dumps/scripts/4753.cs2 b/dumps/scripts/4753.cs2 new file mode 100644 index 0000000..9a5b925 --- /dev/null +++ b/dumps/scripts/4753.cs2 @@ -0,0 +1,4 @@ +void script_4753() { + setWidgetIsHidden(true, new WidgetPointer(1143,6)); + return; +} diff --git a/dumps/scripts/4754.cs2 b/dumps/scripts/4754.cs2 new file mode 100644 index 0000000..8c5bec8 --- /dev/null +++ b/dumps/scripts/4754.cs2 @@ -0,0 +1,16 @@ +int script_4754(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + ivar3 = 0; + if (setWidgetRegister(new WidgetPointer(arg0), 1)) { + ivar3 = getWidgetActualHeight(); + } + ivar4 = subtract(getWidgetActualHeight(new WidgetPointer(arg0)), ivar3); + arg1 = multiply(ivar4, divide(arg1, ivar4)); + if (((boolean)arg2)) { + arg1 = add(arg1, ivar4); + } else { + arg1 = subtract(arg1, ivar4); + } + return arg1; +} diff --git a/dumps/scripts/4755.cs2 b/dumps/scripts/4755.cs2 new file mode 100644 index 0000000..30cbc26 --- /dev/null +++ b/dumps/scripts/4755.cs2 @@ -0,0 +1,24 @@ +void script_4755(int arg0) { + int ivar1; + ivar1 = multiplyDivide(16384, 900, standart_config_2243); + ivar1 = min(max(ivar1, 0), 16384); + setWidgetSize(ivar1, 0, 2, 1, new WidgetPointer(642,66)); + setWidgetText(new WidgetPointer(arg0), intToStr(standart_config_2243)); + if (standart_config_2243 >= 700) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(642,67)); + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(642,69)); + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(642,68)); + setWidgetAnimation(2602, new WidgetPointer(642,38)); + } else if (standart_config_2243 <= 300) { + setWidgetRGB(new Color(255, 34, 102), new WidgetPointer(642,67)); + setWidgetRGB(new Color(255, 34, 102), new WidgetPointer(642,69)); + setWidgetRGB(new Color(255, 34, 102), new WidgetPointer(642,68)); + setWidgetAnimation(2601, new WidgetPointer(642,38)); + } else { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(642,67)); + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(642,69)); + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(642,68)); + setWidgetAnimation(9804, new WidgetPointer(642,38)); + } + return; +} diff --git a/dumps/scripts/4756.cs2 b/dumps/scripts/4756.cs2 new file mode 100644 index 0000000..1add4c9 --- /dev/null +++ b/dumps/scripts/4756.cs2 @@ -0,0 +1,24 @@ +void script_4756(int arg0) { + int ivar1; + ivar1 = multiplyDivide(16384, 1200, standart_config_2244); + ivar1 = min(max(ivar1, 0), 16384); + setWidgetSize(ivar1, 0, 2, 1, new WidgetPointer(642,90)); + setWidgetText(new WidgetPointer(arg0), intToStr(standart_config_2244)); + if (standart_config_2244 >= 700) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(642,91)); + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(642,93)); + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(642,92)); + setWidgetAnimation(2602, new WidgetPointer(642,96)); + } else if (standart_config_2244 <= 300) { + setWidgetRGB(new Color(255, 34, 102), new WidgetPointer(642,91)); + setWidgetRGB(new Color(255, 34, 102), new WidgetPointer(642,93)); + setWidgetRGB(new Color(255, 34, 102), new WidgetPointer(642,92)); + setWidgetAnimation(2601, new WidgetPointer(642,96)); + } else { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(642,91)); + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(642,93)); + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(642,92)); + setWidgetAnimation(9804, new WidgetPointer(642,96)); + } + return; +} diff --git a/dumps/scripts/4757.cs2 b/dumps/scripts/4757.cs2 new file mode 100644 index 0000000..7931141 --- /dev/null +++ b/dumps/scripts/4757.cs2 @@ -0,0 +1,19 @@ +void script_4757(int arg0) { + int ivar1; + ivar1 = multiplyDivide(16384, 1600, standart_config_2245); + ivar1 = min(max(ivar1, 0), 16384); + setWidgetSize(ivar1, 0, 2, 1, new WidgetPointer(642,123)); + setWidgetText(new WidgetPointer(arg0), intToStr(standart_config_2245)); + if (standart_config_2245 <= 300) { + setWidgetRGB(new Color(255, 34, 102), new WidgetPointer(642,124)); + setWidgetRGB(new Color(255, 34, 102), new WidgetPointer(642,126)); + setWidgetRGB(new Color(255, 34, 102), new WidgetPointer(642,125)); + setWidgetAnimation(2601, new WidgetPointer(642,104)); + } else { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(642,124)); + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(642,126)); + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(642,125)); + setWidgetAnimation(9804, new WidgetPointer(642,104)); + } + return; +} diff --git a/dumps/scripts/4758.cs2 b/dumps/scripts/4758.cs2 new file mode 100644 index 0000000..b700729 --- /dev/null +++ b/dumps/scripts/4758.cs2 @@ -0,0 +1,4 @@ +void script_4758(int arg0) { + script_4530(arg0); + return; +} diff --git a/dumps/scripts/4759.cs2 b/dumps/scripts/4759.cs2 new file mode 100644 index 0000000..0c3a994 --- /dev/null +++ b/dumps/scripts/4759.cs2 @@ -0,0 +1,4 @@ +void script_4759(int arg0) { + script_4760(arg0); + return; +} diff --git a/dumps/scripts/476.cs2 b/dumps/scripts/476.cs2 new file mode 100644 index 0000000..a394b91 --- /dev/null +++ b/dumps/scripts/476.cs2 @@ -0,0 +1,5 @@ +void script_476() { + setWidgetSize(getWidgetActualWidth(new WidgetPointer(1011,386)), add(multiply(getLineCount(subtract(getWidgetActualWidth(new WidgetPointer(1011,386)), 10), 494, getWidgetText(new WidgetPointer(1011,387))), 10), 10), 0, 0, new WidgetPointer(1011,386)); + setWidgetIsHidden(true, new WidgetPointer(1011,386)); + return; +} diff --git a/dumps/scripts/4760.cs2 b/dumps/scripts/4760.cs2 new file mode 100644 index 0000000..863ca5c --- /dev/null +++ b/dumps/scripts/4760.cs2 @@ -0,0 +1,137 @@ +void script_4760(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + if (arg0 == -1) { + return; + } + ivar1 = 4; + ivar2 = 4; + ivar3 = 4; + ivar4 = 4; + ivar5 = 7; + ivar6 = 8; + ivar7 = 56; + ivar8 = 7; + ivar9 = 120; + ivar10 = 64; + ivar11 = 53; + ivar12 = 8; + ivar13 = 68; + ivar14 = 43; + if (setWidgetRegister(new WidgetPointer(arg0))) { + setWidgetPosition(0, 0, 1, 1); + setWidgetSize(multiply(ivar1, 2), multiply(ivar2, 2), 1, 1); + } + deleteAllExtraChilds(new WidgetPointer(arg0)); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(multiply(ivar12, 2), ivar4, 1, 0); + setWidgetPosition(0, ivar5, 1, 0); + setWidgetSprite(5472); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(multiply(ivar12, 2), ivar4, 1, 0); + setWidgetPosition(0, ivar8, 1, 2); + setWidgetSprite(5472); + cs2method1107(1); + setWidgetVFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(ivar3, add(ivar5, ivar8), 0, 1); + setWidgetPosition(ivar12, ivar5, 0, 0); + setWidgetSprite(5473); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(ivar3, add(ivar5, ivar8), 0, 1); + setWidgetPosition(ivar12, ivar5, 2, 0); + setWidgetSprite(5473); + cs2method1107(1); + setWidgetHFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(multiply(add(ivar6, ivar7), 2), ivar5, 1, 0); + setWidgetPosition(0, 0, 1, 0); + setWidgetSprite(5632); + cs2method1107(1); + setWidgetVFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(ivar7, ivar5, 0, 0); + setWidgetPosition(ivar12, 0, 0, 0); + setWidgetSprite(5460); + setWidgetVFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(ivar7, ivar5, 0, 0); + setWidgetPosition(ivar12, 0, 2, 0); + setWidgetSprite(5634); + setWidgetHFlip(1); + setWidgetVFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(multiply(add(ivar10, ivar9), 2), ivar8, 1, 0); + setWidgetPosition(0, 0, 1, 2); + setWidgetSprite(5632); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(ivar9, ivar8, 0, 0); + setWidgetPosition(ivar10, 0, 0, 2); + setWidgetSprite(5460); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(ivar9, ivar8, 0, 0); + setWidgetPosition(ivar10, 0, 2, 2); + setWidgetSprite(5634); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(ivar12, add(add(add(ivar5, ivar11), ivar13), ivar14), 0, 1); + setWidgetPosition(0, add(ivar5, ivar13), 0, 0); + setWidgetSprite(5468); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(ivar12, ivar13, 0, 0); + setWidgetPosition(0, ivar5, 0, 0); + setWidgetSprite(5464); + setWidgetHFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(ivar12, ivar14, 0, 0); + setWidgetPosition(0, ivar11, 0, 2); + setWidgetSprite(5469); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(ivar12, add(add(add(ivar5, ivar11), ivar13), ivar14), 0, 1); + setWidgetPosition(0, add(ivar5, ivar13), 2, 0); + setWidgetSprite(5468); + cs2method1107(1); + setWidgetHFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(ivar12, ivar13, 0, 0); + setWidgetPosition(0, ivar5, 2, 0); + setWidgetSprite(5464); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(ivar12, ivar14, 0, 0); + setWidgetPosition(0, ivar11, 2, 2); + setWidgetSprite(5469); + setWidgetHFlip(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(ivar6, ivar5, 0, 0); + setWidgetPosition(0, 0, 0, 0); + setWidgetSprite(6059); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(ivar6, ivar5, 0, 0); + setWidgetPosition(0, 0, 2, 0); + setWidgetSprite(6060); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(ivar10, ivar11, 0, 0); + setWidgetPosition(0, 0, 0, 2); + setWidgetSprite(5461); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetSize(ivar10, ivar11, 0, 0); + setWidgetPosition(0, 0, 2, 2); + setWidgetSprite(5461); + setWidgetHFlip(1); + return; +} diff --git a/dumps/scripts/4761.cs2 b/dumps/scripts/4761.cs2 new file mode 100644 index 0000000..bd9a0d8 --- /dev/null +++ b/dumps/scripts/4761.cs2 @@ -0,0 +1,11 @@ +int script_4761(int arg0) { + if (globalint_1 < add(getClientCycle(), arg0)) { + if (globalint_1 < getClientCycle()) { + globalint_1 = getClientCycle(); + } + globalint_1 = add(globalint_1, 2); + return 0; + } + globalint_1 = add(add(getClientCycle(), arg0), 10); + return 1; +} diff --git a/dumps/scripts/4762.cs2 b/dumps/scripts/4762.cs2 new file mode 100644 index 0000000..e04beb6 --- /dev/null +++ b/dumps/scripts/4762.cs2 @@ -0,0 +1,64 @@ +void script_4762(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + if ((arg0 == -1) || (arg1 == -1)) { + return; + } + ivar2 = getOtherCommonData(arg1, 1385); + ivar3 = getOtherCommonData(arg1, 1382); + ivar4 = getOtherCommonData(arg1, 1386); + ivar5 = getOtherCommonData(arg1, 1383); + ivar6 = getOtherCommonData(arg1, 1384); + ivar7 = getOtherCommonData(arg1, 1387); + ivar8 = getOtherCommonData(arg1, 1358); + deleteAllExtraChilds(new WidgetPointer(arg0)); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 1, 0); + setWidgetSize(multiply(5, 2), 5, 1, 0); + setWidgetSprite(ivar3); + cs2method2103(ivar8); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 1, 2); + setWidgetSize(multiply(5, 2), 5, 1, 0); + setWidgetSprite(ivar5); + cs2method2103(ivar8); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 0, 1); + setWidgetSize(5, multiply(5, 2), 0, 1); + setWidgetSprite(ivar6); + setWidgetHFlip(1); + cs2method2103(ivar8); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 2, 1); + setWidgetSize(5, multiply(5, 2), 0, 1); + setWidgetSprite(ivar6); + cs2method2103(ivar8); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(5, 5, 0, 0); + setWidgetSprite(ivar2); + setWidgetHFlip(1); + cs2method2103(ivar8); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 0, 2); + setWidgetSize(5, 5, 0, 0); + setWidgetSprite(ivar4); + setWidgetHFlip(1); + cs2method2103(ivar8); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 2, 0); + setWidgetSize(5, 5, 0, 0); + setWidgetSprite(ivar2); + cs2method2103(ivar8); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 2, 2); + setWidgetSize(5, 5, 0, 0); + setWidgetSprite(ivar4); + cs2method2103(ivar8); + return; +} diff --git a/dumps/scripts/4763.cs2 b/dumps/scripts/4763.cs2 new file mode 100644 index 0000000..60cc823 --- /dev/null +++ b/dumps/scripts/4763.cs2 @@ -0,0 +1,4 @@ +void script_4763() { + script_4768(); + return; +} diff --git a/dumps/scripts/4764.cs2 b/dumps/scripts/4764.cs2 new file mode 100644 index 0000000..cbbc5b3 --- /dev/null +++ b/dumps/scripts/4764.cs2 @@ -0,0 +1,4 @@ +void script_4764() { + script_304(49341501); + return; +} diff --git a/dumps/scripts/4765.cs2 b/dumps/scripts/4765.cs2 new file mode 100644 index 0000000..c9e2d83 --- /dev/null +++ b/dumps/scripts/4765.cs2 @@ -0,0 +1,4 @@ +void script_4765() { + script_304(49554440); + return; +} diff --git a/dumps/scripts/4766.cs2 b/dumps/scripts/4766.cs2 new file mode 100644 index 0000000..c9a03aa --- /dev/null +++ b/dumps/scripts/4766.cs2 @@ -0,0 +1,4 @@ +void script_4766() { + script_304(48302987); + return; +} diff --git a/dumps/scripts/4767.cs2 b/dumps/scripts/4767.cs2 new file mode 100644 index 0000000..ad15a80 --- /dev/null +++ b/dumps/scripts/4767.cs2 @@ -0,0 +1,4 @@ +void script_4767() { + script_304(48270150); + return; +} diff --git a/dumps/scripts/4768.cs2 b/dumps/scripts/4768.cs2 new file mode 100644 index 0000000..73660a0 --- /dev/null +++ b/dumps/scripts/4768.cs2 @@ -0,0 +1,30 @@ +void script_4768() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + ivar0 = 1; + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + ivar4 = 0; + ivar5 = 0; + ivar6 = 0; + ivar7 = 0; + if (citadelConfigsInitialized()) { + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return; +} diff --git a/dumps/scripts/4769.cs2 b/dumps/scripts/4769.cs2 new file mode 100644 index 0000000..9a65ff7 --- /dev/null +++ b/dumps/scripts/4769.cs2 @@ -0,0 +1,176 @@ +cs2func_script_4769_struct(8,0,0) script_4769(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8) { + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + int ivar22; + int ivar23; + int ivar24; + int ivar25; + int ivar26; + int ivar27; + int ivar28; + int ivar29; + int ivar30; + int ivar31; + int ivar32; + int ivar33; + int ivar34; + int ivar35; + int ivar36; + int ivar37; + int ivar38; + int ivar39; + int ivar40; + int ivar41; + int ivar42; + int stack_dump0; + int stack_dump1; + int stack_dump2; + int stack_dump3; + int stack_dump4; + int stack_dump5; + int stack_dump6; + int stack_dump7; + cs2func_script_4795_struct(32,0,0) structdump_8; + ivar9 = 0; + ivar10 = 0; + ivar11 = 0; + ivar12 = 0; + ivar13 = -1; + ivar14 = -1; + ivar15 = 0; + ivar16 = 0; + ivar17 = 0; + ivar18 = 0; + ivar19 = 0; + ivar20 = 0; + ivar21 = 0; + ivar22 = 0; + ivar23 = 0; + ivar24 = 0; + ivar25 = 0; + ivar26 = 0; + ivar27 = 0; + ivar28 = 0; + ivar29 = 0; + ivar30 = 0; + ivar31 = 0; + ivar32 = 0; + ivar33 = 0; + ivar34 = 0; + ivar35 = 0; + ivar36 = 0; + ivar37 = 0; + ivar38 = 0; + ivar39 = 0; + ivar40 = 0; + if (((boolean)arg0)) { + ivar11 = 300; + ivar13 = 73072707; + ivar14 = 73072706; + } else if (arg0 == 2) { + ivar11 = 600; + ivar13 = 73072705; + ivar14 = 73072704; + } else { + ivar11 = 900; + ivar13 = 73072703; + ivar14 = 73072702; + globalint_1561 = 0; + globalint_1562 = 0; + } + while ((arg1 <= 31) && ((boolean)ivar12)) { + ivar10 = script_4790(arg1); + if ((ivar10 > ivar11) || ((boolean)ivar10)) { + ivar12 = 1; + } else { + stack_dump0 = arg1; + stack_dump1 = arg2; + stack_dump2 = arg3; + stack_dump3 = arg4; + stack_dump4 = arg5; + stack_dump5 = arg6; + stack_dump6 = arg7; + stack_dump7 = arg8; + structdump_8 = script_4795(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4, stack_dump5, stack_dump6, stack_dump7); + ivar39 = structdump_8.intpart_31; + ivar38 = structdump_8.intpart_30; + ivar37 = structdump_8.intpart_29; + ivar36 = structdump_8.intpart_28; + ivar35 = structdump_8.intpart_27; + ivar34 = structdump_8.intpart_26; + ivar33 = structdump_8.intpart_25; + ivar32 = structdump_8.intpart_24; + ivar31 = structdump_8.intpart_23; + ivar30 = structdump_8.intpart_22; + ivar29 = structdump_8.intpart_21; + ivar28 = structdump_8.intpart_20; + ivar27 = structdump_8.intpart_19; + ivar26 = structdump_8.intpart_18; + ivar25 = structdump_8.intpart_17; + ivar24 = structdump_8.intpart_16; + ivar23 = structdump_8.intpart_15; + ivar22 = structdump_8.intpart_14; + ivar21 = structdump_8.intpart_13; + ivar20 = structdump_8.intpart_12; + ivar19 = structdump_8.intpart_11; + ivar18 = structdump_8.intpart_10; + ivar17 = structdump_8.intpart_9; + ivar16 = structdump_8.intpart_8; + ivar15 = structdump_8.intpart_7; + arg8 = structdump_8.intpart_6; + arg7 = structdump_8.intpart_5; + arg6 = structdump_8.intpart_4; + arg5 = structdump_8.intpart_3; + arg4 = structdump_8.intpart_2; + arg3 = structdump_8.intpart_1; + arg2 = structdump_8.intpart_0; + if (((boolean)add(add(add(add(add(ivar15, ivar16), ivar17), ivar18), ivar19), ivar20))) { + ivar40 = 0; + } else if (add(add(add(add(add(ivar33, ivar34), ivar35), ivar36), ivar37), ivar38) > 0) { + ivar40 = 3; + } else if (add(add(add(add(add(ivar27, ivar28), ivar29), ivar30), ivar31), ivar32) > 0) { + ivar40 = 2; + } else { + if (add(add(add(add(add(ivar21, ivar22), ivar23), ivar24), ivar25), ivar26) > 0) { + ivar40 = 1; + } + } + stack_dump0 = ivar13; + stack_dump1 = ivar9; + stack_dump2 = ivar10; + stack_dump3 = ivar39; + stack_dump4 = ivar40; + stack_dump5 = arg1; + /* + mgi.tools.jagdecs2.DecompilerException: No documentation for:CALL_CS2 4770 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:178) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + } + ivar41 = 38; + ivar42 = multiply(divide(ivar9, 8), ivar41); + if (ivar9 > 0) { + ivar9 = script_4771(ivar13, ivar9); + } + ivar42 = add(ivar42, 10); + setWidgetScrollMax(getWidgetActualWidth(new WidgetPointer(ivar13)), ivar42, new WidgetPointer(ivar13)); + cs2method2100(0, 0, new WidgetPointer(ivar13)); + script_31(ivar14, ivar13, 5666, 5663, 5664, 5665, 5686, 5685); + return newstruct cs2func_script_4769_struct(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); +} diff --git a/dumps/scripts/477.cs2 b/dumps/scripts/477.cs2 new file mode 100644 index 0000000..f2eeb33 --- /dev/null +++ b/dumps/scripts/477.cs2 @@ -0,0 +1,17 @@ +void script_477(int arg0) { + int ivar1; + int ivar2; + ivar1 = getWidgetActualX(new WidgetPointer(arg0)); + ivar2 = add(getWidgetActualY(new WidgetPointer(arg0)), getWidgetActualHeight(new WidgetPointer(arg0))); + if (((((((getSkillActualLvl(0) < 42) || (getSkillActualLvl(2) < 42)) || (getSkillActualLvl(1) < 42)) || (getSkillActualLvl(3) < 42)) || (getSkillActualLvl(4) < 42)) || (getSkillActualLvl(6) < 42)) || (getSkillActualLvl(5) < 22)) { + if (add(ivar1, getWidgetActualWidth(new WidgetPointer(1011,386))) >= add(getWidgetActualX(new WidgetPointer(1011,55)), getWidgetActualWidth(new WidgetPointer(1011,55)))) { + ivar1 = subtract(getWidgetActualX(new WidgetPointer(arg0)), subtract(getWidgetActualWidth(new WidgetPointer(1011,386)), getWidgetActualWidth(new WidgetPointer(arg0)))); + } + if (add(ivar2, getWidgetActualHeight(new WidgetPointer(1011,386))) >= add(getWidgetActualY(new WidgetPointer(1011,55)), getWidgetActualHeight(new WidgetPointer(1011,55)))) { + ivar2 = subtract(getWidgetActualY(new WidgetPointer(arg0)), getWidgetActualHeight(new WidgetPointer(1011,386))); + } + setWidgetPosition(ivar1, ivar2, 0, 0, new WidgetPointer(1011,386)); + setWidgetIsHidden(false, new WidgetPointer(1011,386)); + } + return; +} diff --git a/dumps/scripts/4770.cs2 b/dumps/scripts/4770.cs2 new file mode 100644 index 0000000..41041b5 --- /dev/null +++ b/dumps/scripts/4770.cs2 @@ -0,0 +1,37 @@ +?? script_4770(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + string svar0; + string svar1; + string svar2; + string svar3; + ivar6 = divide(arg1, 8); + ivar7 = 38; + ivar8 = 7438; + ivar9 = 5465; + ivar10 = -1; + svar0 = ""; + ivar11 = 0; + ivar12 = 0; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ +} diff --git a/dumps/scripts/4771.cs2 b/dumps/scripts/4771.cs2 new file mode 100644 index 0000000..823f3d5 --- /dev/null +++ b/dumps/scripts/4771.cs2 @@ -0,0 +1,29 @@ +int script_4771(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + ivar2 = 38; + ivar3 = divide(arg1, 8); + ivar4 = 5470; + createExtraChild(new WidgetPointer(arg0), 3, arg1); + setWidgetPosition(2, multiply(ivar2, ivar3), 0, 0); + setWidgetSize(4, 10, 1, 0); + if (((boolean)mod(ivar3, 2))) { + setWidgetRGB(new Color(24, 23, 21)); + } else { + setWidgetRGB(new Color(33, 31, 28)); + } + setWidgetFilled(1); + ivar5 = add(arg1, 1); + setScriptCallOnMouseEntered(4779, new WidgetPointer(arg0), ivar5, 1, "Iii"); + setScriptCallOnMouseExit(4779, new WidgetPointer(arg0), ivar5, 0, "Iii"); + arg1 = add(arg1, 1); + createExtraChild(new WidgetPointer(arg0), 5, arg1); + setWidgetSprite(ivar4); + setWidgetSize(4, 10, 1, 0); + setWidgetPosition(2, multiply(ivar2, ivar3), 0, 0); + setWidgetHidden(1); + arg1 = add(arg1, 1); + return arg1; +} diff --git a/dumps/scripts/4772.cs2 b/dumps/scripts/4772.cs2 new file mode 100644 index 0000000..dfc201e --- /dev/null +++ b/dumps/scripts/4772.cs2 @@ -0,0 +1,38 @@ +void script_4772(int arg0) { + switch (arg0) { + case 1: + setWidgetIsHidden(false, new WidgetPointer(1115,33)); + setWidgetIsHidden(true, new WidgetPointer(1115,49)); + setWidgetIsHidden(true, new WidgetPointer(1115,50)); + setWidgetIsHidden(false, new WidgetPointer(1115,0)); + setWidgetIsHidden(true, new WidgetPointer(1115,1)); + setWidgetIsHidden(true, new WidgetPointer(1115,2)); + setWidgetIsHidden(true, new WidgetPointer(1115,26)); + setWidgetIsHidden(false, new WidgetPointer(1115,27)); + setWidgetIsHidden(false, new WidgetPointer(1115,28)); + break; + case 2: + setWidgetIsHidden(true, new WidgetPointer(1115,33)); + setWidgetIsHidden(false, new WidgetPointer(1115,49)); + setWidgetIsHidden(true, new WidgetPointer(1115,50)); + setWidgetIsHidden(true, new WidgetPointer(1115,0)); + setWidgetIsHidden(false, new WidgetPointer(1115,1)); + setWidgetIsHidden(true, new WidgetPointer(1115,2)); + setWidgetIsHidden(false, new WidgetPointer(1115,26)); + setWidgetIsHidden(true, new WidgetPointer(1115,27)); + setWidgetIsHidden(false, new WidgetPointer(1115,28)); + break; + case 3: + setWidgetIsHidden(true, new WidgetPointer(1115,33)); + setWidgetIsHidden(true, new WidgetPointer(1115,49)); + setWidgetIsHidden(false, new WidgetPointer(1115,50)); + setWidgetIsHidden(true, new WidgetPointer(1115,0)); + setWidgetIsHidden(true, new WidgetPointer(1115,1)); + setWidgetIsHidden(false, new WidgetPointer(1115,2)); + setWidgetIsHidden(false, new WidgetPointer(1115,26)); + setWidgetIsHidden(false, new WidgetPointer(1115,27)); + setWidgetIsHidden(true, new WidgetPointer(1115,28)); + } + script_4775(); + return; +} diff --git a/dumps/scripts/4773.cs2 b/dumps/scripts/4773.cs2 new file mode 100644 index 0000000..ef5fcb4 --- /dev/null +++ b/dumps/scripts/4773.cs2 @@ -0,0 +1,24 @@ +void script_4773(int arg0,int arg1,int arg2) { + int stack_dump0; + int stack_dump1; + int stack_dump2; + if (citadelConfigsInitialized() && (bitconfig_9555 == arg0)) { + if (((boolean)globalint_1560)) { + script_4768(); + stack_dump0 = arg0; + stack_dump1 = arg1; + stack_dump2 = arg2; + /* + mgi.tools.jagdecs2.DecompilerException: No documentation for:CALL_CS2 4777 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:178) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + globalint_1560 = 0; + } + return; +} diff --git a/dumps/scripts/4774.cs2 b/dumps/scripts/4774.cs2 new file mode 100644 index 0000000..93f6807 --- /dev/null +++ b/dumps/scripts/4774.cs2 @@ -0,0 +1,6 @@ +void script_4774(int arg0) { + if (arg0 == bitconfig_9555) { + script_4775(); + } + return; +} diff --git a/dumps/scripts/4775.cs2 b/dumps/scripts/4775.cs2 new file mode 100644 index 0000000..13edb41 --- /dev/null +++ b/dumps/scripts/4775.cs2 @@ -0,0 +1,10 @@ +void script_4775() { + setWidgetText(new WidgetPointer(1115,37), ""); + setWidgetIsHidden(true, new WidgetPointer(1115,34)); + setWidgetIsHidden(true, new WidgetPointer(1115,80)); + setWidgetIsHidden(true, new WidgetPointer(1115,42)); + setWidgetIsHidden(true, new WidgetPointer(1115,41)); + setWidgetIsHidden(true, new WidgetPointer(1115,119)); + setWidgetText(new WidgetPointer(1115,79), ""); + return; +} diff --git a/dumps/scripts/4776.cs2 b/dumps/scripts/4776.cs2 new file mode 100644 index 0000000..868565e --- /dev/null +++ b/dumps/scripts/4776.cs2 @@ -0,0 +1,20 @@ +void script_4776(int arg0,int arg1,int arg2) { + int stack_dump0; + int stack_dump1; + int stack_dump2; + if (citadelConfigsInitialized()) { + stack_dump0 = arg0; + stack_dump1 = arg1; + stack_dump2 = arg2; + /* + mgi.tools.jagdecs2.DecompilerException: No documentation for:CALL_CS2 4777 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:178) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return; +} diff --git a/dumps/scripts/4777.cs2 b/dumps/scripts/4777.cs2 new file mode 100644 index 0000000..bbf4379 --- /dev/null +++ b/dumps/scripts/4777.cs2 @@ -0,0 +1,61 @@ +?? script_4777(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + int ivar22; + int ivar23; + int ivar24; + int ivar25; + int ivar26; + int ivar27; + int ivar28; + int ivar29; + int ivar30; + int ivar31; + int ivar32; + int ivar33; + int ivar34; + int ivar35; + int ivar36; + int ivar37; + int ivar38; + int ivar39; + int ivar40; + int ivar41; + int ivar42; + string svar0; + string svar1; + string svar2; + string svar3; + ivar3 = -1; + svar0 = ""; + svar1 = ""; + ivar4 = 0; + ivar5 = 0; + ivar6 = 0; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ +} diff --git a/dumps/scripts/4778.cs2 b/dumps/scripts/4778.cs2 new file mode 100644 index 0000000..6557e76 --- /dev/null +++ b/dumps/scripts/4778.cs2 @@ -0,0 +1,3 @@ +void script_4778(int arg0,int arg1) { + return; +} diff --git a/dumps/scripts/4779.cs2 b/dumps/scripts/4779.cs2 new file mode 100644 index 0000000..94b136c --- /dev/null +++ b/dumps/scripts/4779.cs2 @@ -0,0 +1,10 @@ +void script_4779(int arg0,int arg1,int arg2) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + if (((boolean)arg2)) { + setWidgetHidden(1); + } else { + setWidgetHidden(0); + } + } + return; +} diff --git a/dumps/scripts/478.cs2 b/dumps/scripts/478.cs2 new file mode 100644 index 0000000..a190aca --- /dev/null +++ b/dumps/scripts/478.cs2 @@ -0,0 +1,4 @@ +void script_478() { + setWidgetIsHidden(true, new WidgetPointer(1011,386)); + return; +} diff --git a/dumps/scripts/4780.cs2 b/dumps/scripts/4780.cs2 new file mode 100644 index 0000000..b61e082 --- /dev/null +++ b/dumps/scripts/4780.cs2 @@ -0,0 +1,11 @@ +void script_4780(int arg0,int arg1,int arg2) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + if (((boolean)arg2)) { + setWidgetSprite(7546); + } else { + setWidgetSprite(7545); + script_41(73072826); + } + } + return; +} diff --git a/dumps/scripts/4781.cs2 b/dumps/scripts/4781.cs2 new file mode 100644 index 0000000..80da2f0 --- /dev/null +++ b/dumps/scripts/4781.cs2 @@ -0,0 +1,11 @@ +void script_4781(int arg0,int arg1,int arg2) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + if (((boolean)arg2)) { + setWidgetSprite(7543); + } else { + setWidgetSprite(7542); + script_41(73072826); + } + } + return; +} diff --git a/dumps/scripts/4782.cs2 b/dumps/scripts/4782.cs2 new file mode 100644 index 0000000..bfdf03c --- /dev/null +++ b/dumps/scripts/4782.cs2 @@ -0,0 +1,30 @@ +void script_4782(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + ivar3 = -1; + ivar4 = -1; + switch (arg1) { + case 1: + ivar3 = 7541; + ivar4 = 7537; + break; + case 2: + ivar3 = 7540; + ivar4 = 7536; + break; + case 3: + ivar3 = 7539; + ivar4 = 7535; + break; + case 4: + ivar3 = 7538; + ivar4 = 7534; + } + if (((boolean)arg2)) { + setWidgetSprite(ivar3, new WidgetPointer(arg0)); + } else { + setWidgetSprite(ivar4, new WidgetPointer(arg0)); + script_41(73072826); + } + return; +} diff --git a/dumps/scripts/4783.cs2 b/dumps/scripts/4783.cs2 new file mode 100644 index 0000000..27817c5 --- /dev/null +++ b/dumps/scripts/4783.cs2 @@ -0,0 +1,4 @@ +void script_4783(int arg0,int arg1,string arg2) { + script_4784(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/4784.cs2 b/dumps/scripts/4784.cs2 new file mode 100644 index 0000000..0f09675 --- /dev/null +++ b/dumps/scripts/4784.cs2 @@ -0,0 +1,17 @@ +void script_4784(int arg0,int arg1,string arg2) { + int ivar2; + int ivar3; + int ivar4; + ivar2 = 2; + ivar3 = divide(getWidgetActualWidth(new WidgetPointer(arg0)), 2); + ivar4 = getWidgetActualY(new WidgetPointer(arg0)); + if ((arg1 != -1) && setWidgetRegister(new WidgetPointer(arg0), arg1)) { + ivar3 = divide(getWidgetActualWidth(), 2); + ivar4 = getWidgetActualY(); + } + if (subtract(ivar4, cs2method2601(new WidgetPointer(arg0))) > 114) { + ivar2 = 0; + } + script_4539(73072826, arg0, arg1, 150, -1, -1, -1, 13, 4, ivar2, ivar3, ivar4, arg2); + return; +} diff --git a/dumps/scripts/4785.cs2 b/dumps/scripts/4785.cs2 new file mode 100644 index 0000000..ac59412 --- /dev/null +++ b/dumps/scripts/4785.cs2 @@ -0,0 +1,11 @@ +?? script_4785() { + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ +} diff --git a/dumps/scripts/4786.cs2 b/dumps/scripts/4786.cs2 new file mode 100644 index 0000000..1e40310 --- /dev/null +++ b/dumps/scripts/4786.cs2 @@ -0,0 +1,65 @@ +int script_4786(int arg0) { + switch (arg0) { + case 1: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 2: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 3: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 4: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 5: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 6: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return 0; +} diff --git a/dumps/scripts/4787.cs2 b/dumps/scripts/4787.cs2 new file mode 100644 index 0000000..6e0ee74 --- /dev/null +++ b/dumps/scripts/4787.cs2 @@ -0,0 +1,77 @@ +int script_4787(int arg0) { + switch (arg0) { + case 0: + return 1; + case 1: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 2: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 3: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 4: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 5: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 6: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 7: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return 0; +} diff --git a/dumps/scripts/4788.cs2 b/dumps/scripts/4788.cs2 new file mode 100644 index 0000000..1da757c --- /dev/null +++ b/dumps/scripts/4788.cs2 @@ -0,0 +1,11 @@ +?? script_4788() { + /* + mgi.tools.jagdecs2.DecompilerException: No documentation for:CALL_CS2 4785 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:178) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ +} diff --git a/dumps/scripts/4789.cs2 b/dumps/scripts/4789.cs2 new file mode 100644 index 0000000..c462c44 --- /dev/null +++ b/dumps/scripts/4789.cs2 @@ -0,0 +1,16 @@ +int script_4789(int arg0) { + int ivar1; + int ivar2; + int ivar3; + ivar1 = 4; + ivar2 = 0; + ivar3 = 0; + while (ivar1 <= 15) { + ivar2 = script_4949(ivar1); + if (ivar2 == arg0) { + return script_4959(ivar1); + } + ivar1 = add(ivar1, 1); + } + return 0; +} diff --git a/dumps/scripts/479.cs2 b/dumps/scripts/479.cs2 new file mode 100644 index 0000000..058b0b1 --- /dev/null +++ b/dumps/scripts/479.cs2 @@ -0,0 +1,4 @@ +void script_479() { + setWidgetText(new WidgetPointer(1015,12), intToStr(bitconfig_7513)); + return; +} diff --git a/dumps/scripts/4790.cs2 b/dumps/scripts/4790.cs2 new file mode 100644 index 0000000..cd72349 --- /dev/null +++ b/dumps/scripts/4790.cs2 @@ -0,0 +1,317 @@ +int script_4790(int arg0) { + int ivar1; + ivar1 = 0; + switch (arg0) { + case 1: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 2: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 3: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 4: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 5: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 6: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 7: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 8: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 9: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 10: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 11: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 12: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 13: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 14: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 15: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 16: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 17: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 18: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 19: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 20: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 21: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 22: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 23: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 24: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 25: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 26: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 27: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 28: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 29: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 30: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 31: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return ivar1; +} diff --git a/dumps/scripts/4791.cs2 b/dumps/scripts/4791.cs2 new file mode 100644 index 0000000..0be3110 --- /dev/null +++ b/dumps/scripts/4791.cs2 @@ -0,0 +1,256 @@ +cs2func_script_4791_struct(7,1,0) script_4791(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + string svar0; + ivar1 = -1; + svar0 = ""; + ivar2 = 0; + ivar3 = cs2method_3408(105, 74, 4008, arg0); + if (ivar3 == -1) { + messageType0("Clan Build Tick : Job ID " + intToStr(arg0) + " has no associated struct. Please report this as a bug, quoting this line."); + return newstruct cs2func_script_4791_struct(-1, 0, 0, 0, 0, 0, 0, ""); + } + ivar4 = getOtherCommonData(ivar3, 1481); + ivar5 = getOtherCommonData(ivar3, 1482); + ivar6 = 0; + ivar7 = 0; + ivar8 = 0; + ivar9 = -1; + ivar10 = 0; + ivar11 = -1; + ivar12 = -1; + ivar13 = 0; + if (citadelConfigsInitialized()) { + switch (ivar4) { + case 1: + svar0 = "Stronghold"; + ivar1 = 7418; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 2: + svar0 = "Storehouse"; + ivar1 = 7419; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 3: + svar0 = "Battlefield"; + ivar1 = 7417; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 4: + switch (ivar5) { + case 1: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 2: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 3: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 4: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 5: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 6: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 7: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 8: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 9: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 10: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 11: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 12: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + messageType0("Clan Build Tick : No skill plot found with index " + intToStr(ivar5) + ". Please report this as a bug, quoting this line."); + svar0 = cs2method_3408(105, 115, 4287, ivar8); + ivar1 = cs2method_3408(105, 100, 4288, ivar8); + break; + case 5: + switch (ivar5) { + case 1: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 2: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 3: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + messageType0("Clan Build Tick : No cosmetic job slot found with index " + intToStr(ivar5) + ". Please report this as a bug, quoting this line."); + ivar9 = script_4820(ivar5); + ivar11 = script_4823(ivar5); + ivar12 = script_4826(ivar5); + if (((arg0 == 16) || (arg0 == 17)) || (arg0 == 18)) { + svar0 = "Reset hotspot (slot " + intToStr(ivar5) + ")."; + ivar1 = 6496; + } else { + svar0 = cs2method_3408(105, 115, ivar11, ivar8); + ivar1 = cs2method_3408(105, 100, ivar12, ivar8); + } + break; + default: + messageType0("Clan Build Tick : Unexpected job building class " + intToStr(ivar4) + ". Please report this as a bug, quoting this line."); + return newstruct cs2func_script_4791_struct(-1, 0, 0, 0, 0, 0, 0, ""); + } + } else { + messageType0("Clan Build Tick : Could not access clan profile."); + return newstruct cs2func_script_4791_struct(-1, 0, 0, 0, 0, 0, 0, ""); + } + if ((arg0 > 600) && (ivar4 != 5)) { + ivar6 = add(ivar6, 1); + } + return newstruct cs2func_script_4791_struct(ivar1, ivar6, ivar7, ivar2, ivar4, ivar5, ivar8, svar0); +} diff --git a/dumps/scripts/4792.cs2 b/dumps/scripts/4792.cs2 new file mode 100644 index 0000000..7048dd1 --- /dev/null +++ b/dumps/scripts/4792.cs2 @@ -0,0 +1,117 @@ +cs2func_script_4792_struct(6,0,0) script_4792(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + int ivar22; + string svar0; + int stack_dump0; + cs2func_script_4791_struct(7,1,0) structdump_1; + ivar2 = 0; + ivar3 = 0; + ivar4 = 0; + ivar5 = 0; + ivar6 = 0; + ivar7 = 0; + ivar8 = 0; + ivar9 = 0; + ivar10 = 0; + ivar11 = 0; + ivar12 = 0; + ivar13 = 0; + ivar14 = cs2method_3408(105, 74, 4008, arg0); + ivar15 = 0; + ivar16 = 0; + ivar17 = 0; + ivar18 = 0; + ivar19 = 0; + ivar20 = 0; + ivar21 = -1; + svar0 = ""; + if ((arg0 < 1) || (arg0 > 900)) { + messageType0("Clan Build Tick : Attempting to look up build cost for invalid job " + intToStr(arg0) + "."); + return newstruct cs2func_script_4792_struct(0, 0, 0, 0, 0, 0); + } + stack_dump0 = arg0; + structdump_1 = script_4791(stack_dump0); + ivar10 = structdump_1.intpart_6; + ivar9 = structdump_1.intpart_5; + ivar8 = structdump_1.intpart_4; + ivar13 = structdump_1.intpart_3; + ivar12 = structdump_1.intpart_2; + ivar11 = structdump_1.intpart_1; + svar0 = structdump_1.stringpart_0; + ivar21 = structdump_1.intpart_0; + ivar22 = -1; + if (arg0 < 600) { + switch (ivar8) { + case 1: + ivar22 = 2021; + break; + case 2: + ivar22 = 2022; + break; + case 3: + ivar22 = 2023; + break; + case 4: + ivar22 = cs2method_3408(105, 74, 4010, ivar10); + break; + case 5: + ivar22 = ivar14; + } + } else { + switch (ivar8) { + case 1: + ivar22 = 2031; + break; + case 2: + ivar22 = 2032; + break; + case 3: + ivar22 = 2033; + break; + case 4: + ivar22 = cs2method_3408(105, 74, 4009, ivar10); + break; + case 5: + ivar22 = ivar14; + } + } + if (((boolean)arg1)) { + return newstruct cs2func_script_4792_struct(0, 0, 0, 0, 0, 0); + } + switch (arg1) { + case 1: + return newstruct cs2func_script_4792_struct(getOtherCommonData(ivar22, 1483), getOtherCommonData(ivar22, 1490), getOtherCommonData(ivar22, 1497), getOtherCommonData(ivar22, 1504), getOtherCommonData(ivar22, 1511), getOtherCommonData(ivar22, 1518)); + case 2: + return newstruct cs2func_script_4792_struct(getOtherCommonData(ivar22, 1484), getOtherCommonData(ivar22, 1491), getOtherCommonData(ivar22, 1498), getOtherCommonData(ivar22, 1505), getOtherCommonData(ivar22, 1512), getOtherCommonData(ivar22, 1519)); + case 3: + return newstruct cs2func_script_4792_struct(getOtherCommonData(ivar22, 1485), getOtherCommonData(ivar22, 1492), getOtherCommonData(ivar22, 1499), getOtherCommonData(ivar22, 1506), getOtherCommonData(ivar22, 1513), getOtherCommonData(ivar22, 1520)); + case 4: + return newstruct cs2func_script_4792_struct(getOtherCommonData(ivar22, 1486), getOtherCommonData(ivar22, 1493), getOtherCommonData(ivar22, 1500), getOtherCommonData(ivar22, 1507), getOtherCommonData(ivar22, 1514), getOtherCommonData(ivar22, 1521)); + case 5: + return newstruct cs2func_script_4792_struct(getOtherCommonData(ivar22, 1487), getOtherCommonData(ivar22, 1494), getOtherCommonData(ivar22, 1501), getOtherCommonData(ivar22, 1508), getOtherCommonData(ivar22, 1515), getOtherCommonData(ivar22, 1522)); + case 6: + return newstruct cs2func_script_4792_struct(getOtherCommonData(ivar22, 1488), getOtherCommonData(ivar22, 1495), getOtherCommonData(ivar22, 1502), getOtherCommonData(ivar22, 1509), getOtherCommonData(ivar22, 1516), getOtherCommonData(ivar22, 1523)); + case 7: + return newstruct cs2func_script_4792_struct(getOtherCommonData(ivar22, 1489), getOtherCommonData(ivar22, 1496), getOtherCommonData(ivar22, 1503), getOtherCommonData(ivar22, 1510), getOtherCommonData(ivar22, 1517), getOtherCommonData(ivar22, 1524)); + } + return newstruct cs2func_script_4792_struct(0, 0, 0, 0, 0, 0); +} diff --git a/dumps/scripts/4793.cs2 b/dumps/scripts/4793.cs2 new file mode 100644 index 0000000..1c96040 --- /dev/null +++ b/dumps/scripts/4793.cs2 @@ -0,0 +1,200 @@ +cs2func_script_4793_struct(6,0,0) script_4793(int arg0,int arg1) { + switch (arg0) { + flow_1: + case 1: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 2: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 3: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 4: + switch (arg1) { + case 1: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 2: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 3: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 4: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 5: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 6: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 7: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 8: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 9: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 10: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 11: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 12: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + break; + case 5: + SWITCH (arg1) { + case 1: + GOTO flow_19 + case 2: + GOTO flow_20 + case 3: + GOTO flow_21 + } + break; + flow_19: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + flow_20: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + flow_21: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return newstruct cs2func_script_4793_struct(0, 0, 0, 0, 0, 0); +} diff --git a/dumps/scripts/4794.cs2 b/dumps/scripts/4794.cs2 new file mode 100644 index 0000000..ea0f884 --- /dev/null +++ b/dumps/scripts/4794.cs2 @@ -0,0 +1,108 @@ +cs2func_script_4794_struct(25,0,0) script_4794(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7) { + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + int ivar22; + int ivar23; + int ivar24; + int ivar25; + int ivar26; + int ivar27; + int ivar28; + int ivar29; + int ivar30; + int ivar31; + int ivar32; + int ivar33; + int stack_dump0; + int stack_dump1; + int stack_dump2; + int stack_dump3; + int stack_dump4; + int stack_dump5; + int stack_dump6; + int stack_dump7; + cs2func_script_4795_struct(32,0,0) structdump_8; + ivar8 = 1; + ivar9 = 0; + ivar10 = 0; + ivar11 = 0; + ivar12 = 0; + ivar13 = 0; + ivar14 = 0; + ivar15 = 0; + ivar16 = 0; + ivar17 = 0; + ivar18 = 0; + ivar19 = 0; + ivar20 = 0; + ivar21 = 0; + ivar22 = 0; + ivar23 = 0; + ivar24 = 0; + ivar25 = 0; + ivar26 = 0; + ivar27 = 0; + ivar28 = 0; + ivar29 = 0; + ivar30 = 0; + ivar31 = 0; + ivar32 = 0; + ivar33 = 0; + while ((ivar8 <= arg0) && (ivar8 != 0)) { + stack_dump0 = ivar8; + stack_dump1 = arg1; + stack_dump2 = arg2; + stack_dump3 = arg3; + stack_dump4 = arg4; + stack_dump5 = arg5; + stack_dump6 = arg6; + stack_dump7 = arg7; + structdump_8 = script_4795(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4, stack_dump5, stack_dump6, stack_dump7); + ivar27 = structdump_8.intpart_31; + ivar26 = structdump_8.intpart_30; + ivar25 = structdump_8.intpart_29; + ivar24 = structdump_8.intpart_28; + ivar23 = structdump_8.intpart_27; + ivar22 = structdump_8.intpart_26; + ivar21 = structdump_8.intpart_25; + ivar33 = structdump_8.intpart_24; + ivar32 = structdump_8.intpart_23; + ivar31 = structdump_8.intpart_22; + ivar30 = structdump_8.intpart_21; + ivar29 = structdump_8.intpart_20; + ivar28 = structdump_8.intpart_19; + ivar20 = structdump_8.intpart_18; + ivar19 = structdump_8.intpart_17; + ivar18 = structdump_8.intpart_16; + ivar17 = structdump_8.intpart_15; + ivar16 = structdump_8.intpart_14; + ivar15 = structdump_8.intpart_13; + ivar14 = structdump_8.intpart_12; + ivar13 = structdump_8.intpart_11; + ivar12 = structdump_8.intpart_10; + ivar11 = structdump_8.intpart_9; + ivar10 = structdump_8.intpart_8; + ivar9 = structdump_8.intpart_7; + arg7 = structdump_8.intpart_6; + arg6 = structdump_8.intpart_5; + arg5 = structdump_8.intpart_4; + arg4 = structdump_8.intpart_3; + arg3 = structdump_8.intpart_2; + arg2 = structdump_8.intpart_1; + arg1 = structdump_8.intpart_0; + ivar8 = add(ivar8, 1); + } + return newstruct cs2func_script_4794_struct(ivar9, ivar10, ivar11, ivar12, ivar13, ivar14, ivar15, ivar16, ivar17, ivar18, ivar19, ivar20, ivar28, ivar29, ivar30, ivar31, ivar32, ivar33, ivar21, ivar22, ivar23, ivar24, ivar25, ivar26, ivar27); +} diff --git a/dumps/scripts/4795.cs2 b/dumps/scripts/4795.cs2 new file mode 100644 index 0000000..84e0ce2 --- /dev/null +++ b/dumps/scripts/4795.cs2 @@ -0,0 +1,211 @@ +cs2func_script_4795_struct(32,0,0) script_4795(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7) { + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + int ivar22; + int ivar23; + int ivar24; + int ivar25; + int ivar26; + int ivar27; + int ivar28; + int ivar29; + int ivar30; + int ivar31; + int ivar32; + int ivar33; + int ivar34; + int ivar35; + int ivar36; + int ivar37; + int ivar38; + int ivar39; + int ivar40; + int ivar41; + int ivar42; + int ivar43; + int ivar44; + int ivar45; + int ivar46; + string svar0; + int stack_dump0; + cs2func_script_4791_struct(7,1,0) structdump_1; + cs2func_script_4724_struct(6,0,0) structdump_2; + cs2func_script_4724_struct(6,0,0) structdump_3; + cs2func_script_4724_struct(6,0,0) structdump_4; + int stack_dump5; + cs2func_script_4792_struct(6,0,0) structdump_6; + cs2func_script_4793_struct(6,0,0) structdump_7; + ivar8 = 0; + ivar9 = 0; + ivar10 = 0; + ivar11 = 0; + ivar12 = 0; + ivar13 = 0; + ivar14 = 0; + ivar15 = 0; + ivar16 = 0; + ivar17 = 0; + ivar18 = 0; + ivar19 = 0; + ivar20 = 0; + ivar21 = 0; + ivar22 = 0; + ivar23 = 0; + ivar24 = 0; + ivar25 = 0; + ivar26 = 0; + ivar27 = script_4790(arg0); + ivar28 = -1; + svar0 = ""; + ivar29 = 0; + ivar30 = 0; + ivar31 = 0; + ivar32 = 0; + ivar33 = 0; + ivar34 = 0; + if ((ivar27 < 1) || (ivar27 > 900)) { + messageType0("Clan Build Tick : Check resources for invalid job " + intToStr(ivar27) + " at position " + intToStr(arg0) + "."); + return newstruct cs2func_script_4795_struct(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + } + stack_dump0 = ivar27; + structdump_1 = script_4791(stack_dump0); + ivar33 = structdump_1.intpart_6; + ivar32 = structdump_1.intpart_5; + ivar29 = structdump_1.intpart_4; + ivar34 = structdump_1.intpart_3; + ivar31 = structdump_1.intpart_2; + ivar30 = structdump_1.intpart_1; + svar0 = structdump_1.stringpart_0; + ivar28 = structdump_1.intpart_0; + if ((ivar27 > 300) && (ivar27 < 600)) { + ivar30 = subtract(ivar30, ivar31); + } + if (ivar27 == 616) { + stack_dump0 = 1; + structdump_2 = script_4724(stack_dump0); + ivar13 = structdump_2.intpart_5; + ivar12 = structdump_2.intpart_4; + ivar11 = structdump_2.intpart_3; + ivar10 = structdump_2.intpart_2; + ivar9 = structdump_2.intpart_1; + ivar8 = structdump_2.intpart_0; + } else if (ivar27 == 617) { + stack_dump0 = 2; + structdump_3 = script_4724(stack_dump0); + ivar13 = structdump_3.intpart_5; + ivar12 = structdump_3.intpart_4; + ivar11 = structdump_3.intpart_3; + ivar10 = structdump_3.intpart_2; + ivar9 = structdump_3.intpart_1; + ivar8 = structdump_3.intpart_0; + } else if (ivar27 == 618) { + stack_dump0 = 3; + structdump_4 = script_4724(stack_dump0); + ivar13 = structdump_4.intpart_5; + ivar12 = structdump_4.intpart_4; + ivar11 = structdump_4.intpart_3; + ivar10 = structdump_4.intpart_2; + ivar9 = structdump_4.intpart_1; + ivar8 = structdump_4.intpart_0; + } else { + stack_dump0 = ivar27; + stack_dump5 = ivar30; + structdump_6 = script_4792(stack_dump0, stack_dump5); + ivar13 = structdump_6.intpart_5; + ivar12 = structdump_6.intpart_4; + ivar11 = structdump_6.intpart_3; + ivar10 = structdump_6.intpart_2; + ivar9 = structdump_6.intpart_1; + ivar8 = structdump_6.intpart_0; + } + if (((ivar34 == 2) && (ivar27 > 300)) && (ivar27 < 600)) { + ivar8 = multiply(ivar8, 2); + ivar9 = multiply(ivar9, 2); + ivar10 = multiply(ivar10, 2); + ivar11 = multiply(ivar11, 2); + ivar12 = multiply(ivar12, 2); + ivar13 = multiply(ivar13, 2); + } + if (ivar27 < 300) { + return newstruct cs2func_script_4795_struct(arg1, arg2, arg3, arg4, arg5, arg6, arg7, ivar8, ivar9, ivar10, ivar11, ivar12, ivar13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + } + ivar35 = ivar8; + ivar36 = ivar9; + ivar37 = ivar10; + ivar38 = ivar11; + ivar39 = ivar12; + ivar40 = ivar13; + if (ivar27 > 600) { + stack_dump0 = ivar29; + stack_dump5 = ivar32; + structdump_7 = script_4793(stack_dump0, stack_dump5); + ivar19 = structdump_7.intpart_5; + ivar18 = structdump_7.intpart_4; + ivar17 = structdump_7.intpart_3; + ivar16 = structdump_7.intpart_2; + ivar15 = structdump_7.intpart_1; + ivar14 = structdump_7.intpart_0; + } + ivar35 = max(0, subtract(ivar35, ivar14)); + ivar36 = max(0, subtract(ivar36, ivar15)); + ivar37 = max(0, subtract(ivar37, ivar16)); + ivar38 = max(0, subtract(ivar38, ivar17)); + ivar39 = max(0, subtract(ivar39, ivar18)); + ivar40 = max(0, subtract(ivar40, ivar19)); + if (((((boolean)ivar35) && ((boolean)ivar36)) && (((boolean)ivar37) && ((boolean)ivar38))) && (((boolean)ivar39) && ((boolean)ivar40))) { + return newstruct cs2func_script_4795_struct(arg1, arg2, arg3, arg4, arg5, arg6, arg7, ivar8, ivar9, ivar10, ivar11, ivar12, ivar13, ivar14, ivar15, ivar16, ivar17, ivar18, ivar19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100); + } + ivar41 = min(ivar35, arg1); + ivar42 = min(ivar36, arg2); + ivar43 = min(ivar37, arg3); + ivar44 = min(ivar38, arg4); + ivar45 = min(ivar39, arg5); + ivar46 = min(ivar40, arg6); + ivar35 = max(0, subtract(ivar35, ivar41)); + ivar36 = max(0, subtract(ivar36, ivar42)); + ivar37 = max(0, subtract(ivar37, ivar43)); + ivar38 = max(0, subtract(ivar38, ivar44)); + ivar39 = max(0, subtract(ivar39, ivar45)); + ivar40 = max(0, subtract(ivar40, ivar46)); + arg1 = max(0, subtract(arg1, ivar41)); + arg2 = max(0, subtract(arg2, ivar42)); + arg3 = max(0, subtract(arg3, ivar43)); + arg4 = max(0, subtract(arg4, ivar44)); + arg5 = max(0, subtract(arg5, ivar45)); + arg6 = max(0, subtract(arg6, ivar46)); + if (((((boolean)ivar35) && ((boolean)ivar36)) && (((boolean)ivar37) && ((boolean)ivar38))) && (((boolean)ivar39) && ((boolean)ivar40))) { + return newstruct cs2func_script_4795_struct(arg1, arg2, arg3, arg4, arg5, arg6, arg7, ivar8, ivar9, ivar10, ivar11, ivar12, ivar13, ivar14, ivar15, ivar16, ivar17, ivar18, ivar19, ivar41, ivar42, ivar43, ivar44, ivar45, ivar46, 0, 0, 0, 0, 0, 0, 100); + } + ivar20 = min(ivar35, divide(arg7, 1)); + ivar35 = max(0, subtract(ivar35, ivar20)); + arg7 = subtract(arg7, multiply(ivar20, 1)); + ivar21 = min(ivar36, divide(arg7, 1)); + ivar36 = max(0, subtract(ivar36, ivar21)); + arg7 = subtract(arg7, multiply(ivar21, 1)); + ivar22 = min(ivar37, divide(arg7, 3)); + ivar37 = max(0, subtract(ivar37, ivar22)); + arg7 = subtract(arg7, multiply(ivar22, 3)); + ivar23 = min(ivar38, divide(arg7, 1)); + ivar38 = max(0, subtract(ivar38, ivar23)); + arg7 = subtract(arg7, multiply(ivar23, 1)); + ivar24 = min(ivar39, divide(arg7, 1)); + ivar39 = max(0, subtract(ivar39, ivar24)); + arg7 = subtract(arg7, multiply(ivar24, 1)); + ivar25 = min(ivar40, divide(arg7, 3)); + ivar40 = max(0, subtract(ivar40, ivar25)); + arg7 = subtract(arg7, multiply(ivar25, 3)); + ivar26 = script_4796(ivar35, ivar8, ivar36, ivar9, ivar37, ivar10, ivar38, ivar11, ivar39, ivar12, ivar40, ivar13); + return newstruct cs2func_script_4795_struct(arg1, arg2, arg3, arg4, arg5, arg6, arg7, ivar8, ivar9, ivar10, ivar11, ivar12, ivar13, ivar14, ivar15, ivar16, ivar17, ivar18, ivar19, ivar41, ivar42, ivar43, ivar44, ivar45, ivar46, ivar20, ivar21, ivar22, ivar23, ivar24, ivar25, ivar26); +} diff --git a/dumps/scripts/4796.cs2 b/dumps/scripts/4796.cs2 new file mode 100644 index 0000000..254a749 --- /dev/null +++ b/dumps/scripts/4796.cs2 @@ -0,0 +1,93 @@ +int script_4796(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11) { + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + flow_0: + ivar12 = 0; + ivar13 = 0; + ivar14 = 0; + ivar15 = 0; + ivar16 = 0; + ivar17 = 0; + ivar18 = 0; + ivar19 = 0; + if (arg1 > 0) { + ivar14 = divide(multiply(arg0, 1000), arg1); + ivar12 = add(ivar12, 1); + } + if (arg3 > 0) { + ivar15 = divide(multiply(arg2, 1000), arg3); + ivar12 = add(ivar12, 1); + } + if (arg5 > 0) { + ivar16 = divide(multiply(arg4, 1000), arg5); + ivar12 = add(ivar12, 1); + } + if (arg7 > 0) { + ivar17 = divide(multiply(arg6, 1000), arg7); + ivar12 = add(ivar12, 1); + } + if (arg9 > 0) { + ivar18 = divide(multiply(arg8, 1000), arg9); + ivar12 = add(ivar12, 1); + } + if (arg11 > 0) { + ivar19 = divide(multiply(arg10, 1000), arg11); + ivar12 = add(ivar12, 1); + } + ivar12 = max(ivar12, 1); + ivar20 = divide(add(add(add(add(add(ivar14, ivar15), ivar16), ivar17), ivar18), ivar19), multiply(ivar12, 10)); + ivar13 = subtract(100, ivar20); + IF (ivar13 == 100) + GOTO flow_13 + GOTO flow_26 + flow_13: + IF (arg0 != arg1) + GOTO flow_14 + GOTO flow_15 + flow_14: + IF (arg0 != 0) + GOTO flow_25 + flow_15: + IF (arg2 != arg3) + GOTO flow_16 + GOTO flow_17 + flow_16: + IF (arg2 != 0) + GOTO flow_25 + flow_17: + IF (arg4 != arg5) + GOTO flow_18 + GOTO flow_19 + flow_18: + IF (arg4 != 0) + GOTO flow_25 + flow_19: + IF (arg6 != arg7) + GOTO flow_20 + GOTO flow_21 + flow_20: + IF (arg6 != 0) + GOTO flow_25 + flow_21: + IF (arg8 != arg9) + GOTO flow_22 + GOTO flow_23 + flow_22: + IF (arg8 != 0) + GOTO flow_25 + flow_23: + IF ((arg10 != arg11) && (arg10 != 0)) + GOTO flow_25 + GOTO flow_26 + flow_25: + ivar13 = 99; + flow_26: + return ivar13; +} diff --git a/dumps/scripts/4797.cs2 b/dumps/scripts/4797.cs2 new file mode 100644 index 0000000..c9adf07 --- /dev/null +++ b/dumps/scripts/4797.cs2 @@ -0,0 +1,106 @@ +cs2func_script_4797_struct(6,0,0) script_4797() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + string svar0; + int stack_dump0; + cs2func_script_4791_struct(7,1,0) structdump_1; + int stack_dump2; + cs2func_script_4792_struct(6,0,0) structdump_3; + flow_0: + ivar0 = 0; + ivar1 = 1; + ivar2 = 0; + ivar3 = 0; + ivar4 = 0; + ivar5 = 0; + ivar6 = 0; + ivar7 = 0; + ivar8 = 0; + ivar9 = 0; + ivar10 = 0; + ivar11 = 0; + ivar12 = 0; + ivar13 = 0; + ivar14 = 0; + ivar15 = 0; + ivar16 = 0; + ivar17 = 0; + ivar18 = 0; + ivar19 = 0; + ivar20 = 0; + ivar21 = -1; + svar0 = ""; + IF (citadelConfigsInitialized() && (ivar1 <= 31)) + GOTO flow_2 + GOTO flow_11 + flow_1: + flow_2: + IF (((boolean)ivar8)) + GOTO flow_3 + GOTO flow_11 + flow_3: + ivar0 = script_4790(ivar1); + if (ivar0 > 600) { + ivar8 = 1; + } else if (ivar0 < 300) { + } else { + stack_dump0 = ivar0; + structdump_1 = script_4791(stack_dump0); + ivar4 = structdump_1.intpart_6; + ivar3 = structdump_1.intpart_5; + ivar2 = structdump_1.intpart_4; + ivar7 = structdump_1.intpart_3; + ivar6 = structdump_1.intpart_2; + ivar5 = structdump_1.intpart_1; + svar0 = structdump_1.stringpart_0; + ivar21 = structdump_1.intpart_0; + ivar5 = subtract(ivar5, ivar6); + stack_dump0 = ivar0; + stack_dump2 = ivar5; + structdump_3 = script_4792(stack_dump0, stack_dump2); + ivar11 = structdump_3.intpart_5; + ivar13 = structdump_3.intpart_4; + ivar12 = structdump_3.intpart_3; + ivar11 = structdump_3.intpart_2; + ivar10 = structdump_3.intpart_1; + ivar9 = structdump_3.intpart_0; + if (ivar7 == 2) { + ivar9 = multiply(ivar9, 2); + ivar10 = multiply(ivar10, 2); + ivar11 = multiply(ivar11, 2); + ivar12 = multiply(ivar12, 2); + ivar13 = multiply(ivar13, 2); + ivar14 = multiply(ivar14, 2); + } + ivar15 = add(ivar15, ivar9); + ivar16 = add(ivar16, ivar10); + ivar17 = add(ivar17, ivar11); + ivar18 = add(ivar18, ivar12); + ivar19 = add(ivar19, ivar13); + ivar20 = add(ivar20, ivar14); + } + ivar1 = add(ivar1, 1); + GOTO flow_1 + flow_11: + return newstruct cs2func_script_4797_struct(ivar15, ivar16, ivar17, ivar18, ivar19, ivar20); +} diff --git a/dumps/scripts/4798.cs2 b/dumps/scripts/4798.cs2 new file mode 100644 index 0000000..222f883 --- /dev/null +++ b/dumps/scripts/4798.cs2 @@ -0,0 +1,50 @@ +int script_4798(int arg0) { + int ivar1; + int ivar2; + int stack_dump0; + ivar1 = 604; + ivar2 = 0; + if (arg0 == 603) { + stack_dump0 = 602; + /* + mgi.tools.jagdecs2.DecompilerException: No documentation for:CALL_CS2 4800 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:178) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + if (arg0 == 602) { + stack_dump0 = 603; + /* + mgi.tools.jagdecs2.DecompilerException: No documentation for:CALL_CS2 4800 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:178) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + if ((arg0 >= 604) && (arg0 <= 615)) { + while (ivar1 <= 615) { + if (ivar1 != arg0) { + stack_dump0 = ivar1; + /* + mgi.tools.jagdecs2.DecompilerException: No documentation for:CALL_CS2 4800 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:178) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + ivar1 = add(ivar1, 1); + } + return 0; + } + return 0; +} diff --git a/dumps/scripts/4799.cs2 b/dumps/scripts/4799.cs2 new file mode 100644 index 0000000..a849f30 --- /dev/null +++ b/dumps/scripts/4799.cs2 @@ -0,0 +1,16 @@ +int script_4799() { + int ivar0; + int ivar1; + int ivar2; + ivar0 = 0; + ivar1 = 0; + ivar2 = 1; + while (ivar2 <= 31) { + ivar0 = script_4790(ivar2); + if ((ivar0 >= 604) && (ivar0 <= 615)) { + ivar1 = add(ivar1, 1); + } + ivar2 = add(ivar2, 1); + } + return ivar1; +} diff --git a/dumps/scripts/48.cs2 b/dumps/scripts/48.cs2 new file mode 100644 index 0000000..c612447 --- /dev/null +++ b/dumps/scripts/48.cs2 @@ -0,0 +1,7 @@ +void script_48() { + if ((((boolean)globalint_1034) && ((boolean)globalint_1027)) && (strLength(globalstring_202) > 0)) { + sendUnknownFriendPacketMethod3619(globalstring_202); + globalint_1034 = 2; + } + return; +} diff --git a/dumps/scripts/480.cs2 b/dumps/scripts/480.cs2 new file mode 100644 index 0000000..bf92bc1 --- /dev/null +++ b/dumps/scripts/480.cs2 @@ -0,0 +1,63 @@ +void script_480() { + setWidgetText(new WidgetPointer(1015,144), script_483(bitconfig_7520)); + if (bitconfig_7520 > 0) { + setWidgetRGB(new Color(230, 202, 152), new WidgetPointer(1015,144)); + } else { + setWidgetRGB(new Color(88, 80, 66), new WidgetPointer(1015,144)); + } + setWidgetText(new WidgetPointer(1015,146), script_483(bitconfig_7521)); + if (bitconfig_7521 > 0) { + setWidgetRGB(new Color(230, 202, 152), new WidgetPointer(1015,146)); + } else { + setWidgetRGB(new Color(88, 80, 66), new WidgetPointer(1015,146)); + } + setWidgetText(new WidgetPointer(1015,148), script_483(bitconfig_7526)); + if (bitconfig_7526 > 0) { + setWidgetRGB(new Color(230, 202, 152), new WidgetPointer(1015,148)); + } else { + setWidgetRGB(new Color(88, 80, 66), new WidgetPointer(1015,148)); + } + setWidgetText(new WidgetPointer(1015,150), script_483(bitconfig_7527)); + if (bitconfig_7527 > 0) { + setWidgetRGB(new Color(230, 202, 152), new WidgetPointer(1015,150)); + } else { + setWidgetRGB(new Color(88, 80, 66), new WidgetPointer(1015,150)); + } + setWidgetText(new WidgetPointer(1015,152), script_483(bitconfig_7530)); + if (bitconfig_7530 > 0) { + setWidgetRGB(new Color(230, 202, 152), new WidgetPointer(1015,152)); + } else { + setWidgetRGB(new Color(88, 80, 66), new WidgetPointer(1015,152)); + } + setWidgetText(new WidgetPointer(1015,154), script_483(bitconfig_7531)); + if (bitconfig_7531 > 0) { + setWidgetRGB(new Color(230, 202, 152), new WidgetPointer(1015,154)); + } else { + setWidgetRGB(new Color(88, 80, 66), new WidgetPointer(1015,154)); + } + setWidgetText(new WidgetPointer(1015,156), script_483(bitconfig_7532)); + if (bitconfig_7532 > 0) { + setWidgetRGB(new Color(230, 202, 152), new WidgetPointer(1015,156)); + } else { + setWidgetRGB(new Color(88, 80, 66), new WidgetPointer(1015,156)); + } + setWidgetText(new WidgetPointer(1015,158), script_483(bitconfig_7533)); + if (bitconfig_7533 > 0) { + setWidgetRGB(new Color(230, 202, 152), new WidgetPointer(1015,158)); + } else { + setWidgetRGB(new Color(88, 80, 66), new WidgetPointer(1015,158)); + } + setWidgetText(new WidgetPointer(1015,160), script_483(bitconfig_7534)); + if (bitconfig_7534 > 0) { + setWidgetRGB(new Color(230, 202, 152), new WidgetPointer(1015,160)); + } else { + setWidgetRGB(new Color(88, 80, 66), new WidgetPointer(1015,160)); + } + setWidgetText(new WidgetPointer(1015,162), script_483(bitconfig_7535)); + if (bitconfig_7535 > 0) { + setWidgetRGB(new Color(230, 202, 152), new WidgetPointer(1015,162)); + } else { + setWidgetRGB(new Color(88, 80, 66), new WidgetPointer(1015,162)); + } + return; +} diff --git a/dumps/scripts/4800.cs2 b/dumps/scripts/4800.cs2 new file mode 100644 index 0000000..8cb077f --- /dev/null +++ b/dumps/scripts/4800.cs2 @@ -0,0 +1,13 @@ +?? script_4800(int arg0) { + int stack_dump0; + stack_dump0 = arg0; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ +} diff --git a/dumps/scripts/4801.cs2 b/dumps/scripts/4801.cs2 new file mode 100644 index 0000000..0ef5927 --- /dev/null +++ b/dumps/scripts/4801.cs2 @@ -0,0 +1,29 @@ +void script_4801(int arg0) { + flow_0: + SWITCH (arg0) { + case 1: + GOTO flow_1 + case 2: + GOTO flow_2 + case 3: + GOTO flow_3 + } + globalint_1659 = 0; + setWidgetText(new WidgetPointer(1143,11), "Price: Low-High"); + GOTO flow_4 + flow_1: + globalint_1659 = 1; + setWidgetText(new WidgetPointer(1143,11), "Price: High-Low"); + GOTO flow_4 + flow_2: + globalint_1659 = 2; + setWidgetText(new WidgetPointer(1143,11), "Name: A-Z"); + GOTO flow_4 + flow_3: + globalint_1659 = 3; + setWidgetText(new WidgetPointer(1143,11), "Name: Z-A"); + flow_4: + setWidgetIsHidden(true, new WidgetPointer(1143,6)); + script_5350(bitconfig_9487, 74907774); + return; +} diff --git a/dumps/scripts/4802.cs2 b/dumps/scripts/4802.cs2 new file mode 100644 index 0000000..9a153ac --- /dev/null +++ b/dumps/scripts/4802.cs2 @@ -0,0 +1,4 @@ +void script_4802() { + script_4804(); + return; +} diff --git a/dumps/scripts/4803.cs2 b/dumps/scripts/4803.cs2 new file mode 100644 index 0000000..6131d0e --- /dev/null +++ b/dumps/scripts/4803.cs2 @@ -0,0 +1,44 @@ +void script_4803(int arg0) { + int ivar1; + int ivar2; + int ivar3; + ivar1 = script_4819(bitconfig_9558); + ivar2 = cs2method_3408(105, 105, ivar1, arg0); + switch (bitconfig_9558) { + case 1: + if (ivar2 != bitconfig_9562) { + bitconfig_9562 = ivar2; + bitconfig_9563 = 1; + bitconfig_9567 = 0; + bitconfig_9568 = 0; + bitconfig_9569 = 0; + } + break; + case 2: + if (ivar2 != bitconfig_9571) { + bitconfig_9571 = ivar2; + bitconfig_9572 = 1; + bitconfig_9576 = 0; + bitconfig_9577 = 0; + bitconfig_9578 = 0; + } + break; + case 3: + if (ivar2 != bitconfig_9580) { + bitconfig_9580 = ivar2; + bitconfig_9581 = 1; + bitconfig_9585 = 0; + bitconfig_9586 = 0; + bitconfig_9587 = 0; + } + } + ivar3 = 0; + if (((boolean)script_4828(bitconfig_9558))) { + ivar3 = multiply(28, subtract(arg0, 1)); + setWidgetIsHidden(false, new WidgetPointer(1092,938)); + setWidgetPosition(0, ivar3, 0, 0, new WidgetPointer(1092,938)); + } + script_4846(1); + script_4804(); + return; +} diff --git a/dumps/scripts/4804.cs2 b/dumps/scripts/4804.cs2 new file mode 100644 index 0000000..45d47e9 --- /dev/null +++ b/dumps/scripts/4804.cs2 @@ -0,0 +1,120 @@ +void script_4804() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + ivar0 = script_4828(bitconfig_9558); + if (((boolean)ivar0)) { + script_4842(1); + script_4842(2); + script_4842(3); + switch (bitconfig_9558) { + case 1: + script_4846(bitconfig_9563); + break; + case 2: + script_4846(bitconfig_9572); + break; + case 3: + script_4846(bitconfig_9581); + } + } else { + script_4843(1); + script_4843(2); + script_4843(3); + } + script_4807(); + ivar1 = -1; + ivar2 = -1; + ivar3 = -1; + ivar4 = -1; + ivar5 = 0; + ivar6 = 1; + ivar7 = 1; + ivar8 = 0; + switch (bitconfig_9558) { + case 1: + ivar5 = bitconfig_9562; + ivar8 = bitconfig_9566; + break; + case 2: + ivar5 = bitconfig_9571; + ivar8 = bitconfig_9575; + break; + case 3: + ivar5 = bitconfig_9580; + ivar8 = bitconfig_9584; + } + if (((boolean)ivar5) && ((boolean)ivar8)) { + script_4940(); + return; + } + script_4942(); + ivar9 = script_4825(bitconfig_9558); + ivar10 = script_4822(bitconfig_9558); + if (((boolean)ivar8)) { + script_4846(1); + setWidgetSprite(-1, new WidgetPointer(1092,980)); + setWidgetText(new WidgetPointer(1092,981), "Reset Hotspot to its default state"); + setWidgetText(new WidgetPointer(1092,1153), ""); + setWidgetText(new WidgetPointer(1092,1154), ""); + setWidgetText(new WidgetPointer(1092,1155), ""); + setWidgetText(new WidgetPointer(1092,1073), ""); + setWidgetText(new WidgetPointer(1092,1074), ""); + setWidgetText(new WidgetPointer(1092,1075), ""); + setWidgetText(new WidgetPointer(1092,987), ""); + setWidgetText(new WidgetPointer(1092,988), ""); + setWidgetText(new WidgetPointer(1092,989), ""); + script_4805(1, 1); + script_4805(2, 1); + script_4805(3, 1); + script_4805(1, 2); + script_4805(2, 2); + script_4805(3, 2); + script_4805(1, 3); + script_4805(2, 3); + script_4805(3, 3); + } else { + if (ivar9 != -1) { + setWidgetSprite(cs2method_3408(105, 100, ivar9, ivar5), new WidgetPointer(1092,980)); + } + if (ivar10 != -1) { + setWidgetText(new WidgetPointer(1092,981), cs2method_3408(105, 115, ivar10, ivar5)); + } + ivar1 = cs2method_3408(105, 103, 4043, ivar5); + if ((ivar1 == -1) && ((boolean)ivar8)) { + return; + } + while (ivar6 <= 3) { + ivar2 = cs2method_3408(105, 103, ivar1, ivar6); + if (ivar2 != -1) { + while (ivar7 <= 3) { + ivar3 = cs2method_3408(105, 103, ivar2, ivar7); + if (ivar3 != -1) { + script_4806(ivar3, ivar6, ivar7, ivar0, ivar5); + } else { + script_4805(ivar6, ivar7); + } + ivar3 = -1; + ivar7 = add(ivar7, 1); + } + } else { + script_4842(ivar6); + } + ivar7 = 1; + ivar6 = add(ivar6, 1); + } + script_4838(); + script_4810(); + } + script_4809(); + script_4814(); + return; +} diff --git a/dumps/scripts/4805.cs2 b/dumps/scripts/4805.cs2 new file mode 100644 index 0000000..771eb6b --- /dev/null +++ b/dumps/scripts/4805.cs2 @@ -0,0 +1,45 @@ +void script_4805(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int stack_dump0; + int stack_dump1; + cs2func_script_4818_struct(11,0,0) structdump_2; + ivar2 = -1; + ivar3 = -1; + ivar4 = -1; + ivar5 = -1; + ivar6 = -1; + ivar7 = -1; + ivar8 = -1; + ivar9 = -1; + ivar10 = -1; + ivar11 = -1; + ivar12 = -1; + stack_dump0 = arg0; + stack_dump1 = arg1; + structdump_2 = script_4818(stack_dump0, stack_dump1); + ivar12 = structdump_2.intpart_10; + ivar11 = structdump_2.intpart_9; + ivar10 = structdump_2.intpart_8; + ivar9 = structdump_2.intpart_7; + ivar8 = structdump_2.intpart_6; + ivar7 = structdump_2.intpart_5; + ivar6 = structdump_2.intpart_4; + ivar5 = structdump_2.intpart_3; + ivar4 = structdump_2.intpart_2; + ivar3 = structdump_2.intpart_1; + ivar2 = structdump_2.intpart_0; + setWidgetSize(0, 0, 1, 0, new WidgetPointer(ivar2)); + setWidgetIntegerNode(1564, 0, new WidgetPointer(ivar2)); + setWidgetIsHidden(true, new WidgetPointer(ivar2)); + return; +} diff --git a/dumps/scripts/4806.cs2 b/dumps/scripts/4806.cs2 new file mode 100644 index 0000000..c3c9168 --- /dev/null +++ b/dumps/scripts/4806.cs2 @@ -0,0 +1,188 @@ +void script_4806(int arg0,int arg1,int arg2,int arg3,int arg4) { + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int stack_dump0; + int stack_dump1; + cs2func_script_4818_struct(11,0,0) structdump_2; + ivar5 = -1; + ivar6 = -1; + ivar7 = -1; + ivar8 = -1; + ivar9 = -1; + ivar10 = -1; + ivar11 = -1; + ivar12 = -1; + ivar13 = -1; + ivar14 = -1; + ivar15 = -1; + stack_dump0 = arg1; + stack_dump1 = arg2; + structdump_2 = script_4818(stack_dump0, stack_dump1); + ivar15 = structdump_2.intpart_10; + ivar14 = structdump_2.intpart_9; + ivar13 = structdump_2.intpart_8; + ivar12 = structdump_2.intpart_7; + ivar11 = structdump_2.intpart_6; + ivar10 = structdump_2.intpart_5; + ivar9 = structdump_2.intpart_4; + ivar8 = structdump_2.intpart_3; + ivar7 = structdump_2.intpart_2; + ivar6 = structdump_2.intpart_1; + ivar5 = structdump_2.intpart_0; + switch (arg2) { + case 1: + setWidgetText(new WidgetPointer(ivar15), cs2method_3408(105, 115, 4044, arg4)); + break; + case 2: + setWidgetText(new WidgetPointer(ivar15), cs2method_3408(105, 115, 4045, arg4)); + break; + case 3: + setWidgetText(new WidgetPointer(ivar15), cs2method_3408(105, 115, 4046, arg4)); + } + setWidgetIsHidden(false, new WidgetPointer(ivar5)); + ivar16 = 0; + ivar17 = 1; + ivar18 = -1; + ivar19 = 0; + switch (bitconfig_9558) { + flow_5: + case 1: + switch (arg2) { + case 1: + ivar19 = bitconfig_9567; + break; + case 2: + ivar19 = bitconfig_9568; + break; + case 3: + ivar19 = bitconfig_9569; + } + break; + case 2: + switch (arg2) { + case 1: + ivar19 = bitconfig_9576; + break; + case 2: + ivar19 = bitconfig_9577; + break; + case 3: + ivar19 = bitconfig_9578; + } + break; + case 3: + SWITCH (arg2) { + case 1: + GOTO flow_16 + case 2: + GOTO flow_17 + case 3: + GOTO flow_18 + } + break; + flow_16: + ivar19 = bitconfig_9585; + break; + flow_17: + ivar19 = bitconfig_9586; + break; + flow_18: + ivar19 = bitconfig_9587; + } + while (ivar17 <= getCommonDefinitionSize(arg0)) { + ivar18 = cs2method_3408(105, 74, arg0, ivar17); + if (ivar18 != -1) { + createExtraChild(new WidgetPointer(ivar14), 3, ivar16); + setWidgetSize(0, 26, 1, 0); + setWidgetPosition(0, multiply(ivar16, 27), 0, 0); + setWidgetFilled(1); + setWidgetRGB(new Color(44, 40, 32)); + createExtraChild(new WidgetPointer(ivar6), 5, ivar16); + setWidgetSprite(getOtherCommonData(ivar18, 1565)); + setWidgetSize(22, 22, 0, 0); + setWidgetPosition(0, add(2, multiply(ivar16, 27)), 0, 0); + setScriptCallOnMouseOver(4812, getOtherCommonData(ivar18, 1566), getOtherCommonData(ivar18, 1565), getOtherCommonData(ivar18, 1567), 25, "sdii"); + setScriptCallOnMouseExit(4813, ""); + createExtraChild(new WidgetPointer(ivar7), 5, ivar16); + setWidgetSprite(getOtherCommonData(ivar18, 1572)); + setWidgetSize(20, 20, 0, 0); + setWidgetPosition(1, add(2, multiply(ivar16, 27)), 0, 0); + setScriptCallOnMouseExit(40, new WidgetPointer(1092,1254), "I"); + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,1254), new WidgetPointer(-32768,3), -2147483643, getOtherCommonData(ivar18, 1570), 120, 3793, 3793, 16777215, 13, 4, 2, -2147483647, -2147483646, "IIisifdiiiiii"); + createExtraChild(new WidgetPointer(ivar10), 4, ivar16); + setWidgetText(intToStr(getOtherCommonData(ivar18, 1573))); + setWidgetSize(0, 26, 1, 0); + setWidgetPosition(0, multiply(ivar16, 27), 0, 0); + setWidgetUnknownBoolean(false); + setWidgetFont(494); + setWidgetTextAlignment(1, 1, 0); + setWidgetRGB(new Color(255, 255, 255)); + if (ivar8 != -1) { + createExtraChild(new WidgetPointer(ivar8), 5, ivar16); + setWidgetSprite(getOtherCommonData(ivar18, 1576)); + setWidgetSize(20, 20, 0, 0); + setWidgetPosition(1, add(2, multiply(ivar16, 27)), 0, 0); + setScriptCallOnMouseExit(40, new WidgetPointer(1092,1254), "I"); + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,1254), new WidgetPointer(-32768,3), -2147483643, getOtherCommonData(ivar18, 1574), 120, 3793, 3793, 16777215, 13, 4, 2, -2147483647, -2147483646, "IIisifdiiiiii"); + } + if (ivar11 != -1) { + createExtraChild(new WidgetPointer(ivar11), 4, ivar16); + setWidgetText(intToStr(getOtherCommonData(ivar18, 1577))); + setWidgetSize(0, 26, 1, 0); + setWidgetPosition(0, multiply(ivar16, 27), 0, 0); + setWidgetUnknownBoolean(false); + setWidgetFont(494); + setWidgetTextAlignment(1, 1, 0); + setWidgetRGB(new Color(255, 255, 255)); + } + if (ivar9 != -1) { + createExtraChild(new WidgetPointer(ivar9), 5, ivar16); + setWidgetSprite(getOtherCommonData(ivar18, 1580)); + setWidgetSize(20, 20, 0, 0); + setWidgetPosition(0, add(2, multiply(ivar16, 27)), 0, 0); + setScriptCallOnMouseExit(40, new WidgetPointer(1092,1254), "I"); + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,1254), new WidgetPointer(-32768,3), -2147483643, getOtherCommonData(ivar18, 1578), 120, 3793, 3793, 16777215, 13, 4, 2, -2147483647, -2147483646, "IIisifdiiiiii"); + } + if (ivar12 != -1) { + createExtraChild(new WidgetPointer(ivar12), 4, ivar16); + setWidgetText(intToStr(getOtherCommonData(ivar18, 1581))); + setWidgetSize(0, 26, 1, 0); + setWidgetPosition(0, multiply(ivar16, 27), 0, 0); + setWidgetUnknownBoolean(false); + setWidgetFont(494); + setWidgetTextAlignment(1, 1, 0); + setWidgetRGB(new Color(255, 255, 255)); + } + createExtraChild(new WidgetPointer(ivar13), 5, ivar16); + setWidgetSize(16, 16, 0, 0); + setWidgetPosition(1, add(5, multiply(ivar16, 27)), 0, 0); + if (((boolean)arg3)) { + setWidgetContextMenuOption(1, "Select"); + setScriptCallOnClickContextMenu(4832, new WidgetPointer(-32768,3), -2147483643, "Ii"); + } + if (ivar19 == add(ivar16, 1)) { + setWidgetSprite(6004); + } else { + setWidgetSprite(6009); + } + ivar16 = add(ivar16, 1); + } + ivar17 = add(ivar17, 1); + ivar18 = -1; + } + setWidgetIntegerNode(1564, multiply(ivar16, 27), new WidgetPointer(ivar5)); + return; +} diff --git a/dumps/scripts/4807.cs2 b/dumps/scripts/4807.cs2 new file mode 100644 index 0000000..f1ecf45 --- /dev/null +++ b/dumps/scripts/4807.cs2 @@ -0,0 +1,75 @@ +void script_4807() { + deleteAllExtraChilds(new WidgetPointer(1092,1180)); + deleteAllExtraChilds(new WidgetPointer(1092,1191)); + deleteAllExtraChilds(new WidgetPointer(1092,1190)); + deleteAllExtraChilds(new WidgetPointer(1092,1189)); + deleteAllExtraChilds(new WidgetPointer(1092,1188)); + deleteAllExtraChilds(new WidgetPointer(1092,1182)); + deleteAllExtraChilds(new WidgetPointer(1092,1168)); + deleteAllExtraChilds(new WidgetPointer(1092,1179)); + deleteAllExtraChilds(new WidgetPointer(1092,1178)); + deleteAllExtraChilds(new WidgetPointer(1092,1177)); + deleteAllExtraChilds(new WidgetPointer(1092,1176)); + deleteAllExtraChilds(new WidgetPointer(1092,1170)); + deleteAllExtraChilds(new WidgetPointer(1092,1156)); + deleteAllExtraChilds(new WidgetPointer(1092,1167)); + deleteAllExtraChilds(new WidgetPointer(1092,1166)); + deleteAllExtraChilds(new WidgetPointer(1092,1165)); + deleteAllExtraChilds(new WidgetPointer(1092,1164)); + deleteAllExtraChilds(new WidgetPointer(1092,1158)); + deleteAllExtraChilds(new WidgetPointer(1092,1104)); + deleteAllExtraChilds(new WidgetPointer(1092,1117)); + deleteAllExtraChilds(new WidgetPointer(1092,1116)); + deleteAllExtraChilds(new WidgetPointer(1092,1114)); + deleteAllExtraChilds(new WidgetPointer(1092,1115)); + deleteAllExtraChilds(new WidgetPointer(1092,1113)); + deleteAllExtraChilds(new WidgetPointer(1092,1112)); + deleteAllExtraChilds(new WidgetPointer(1092,1106)); + deleteAllExtraChilds(new WidgetPointer(1092,1090)); + deleteAllExtraChilds(new WidgetPointer(1092,1103)); + deleteAllExtraChilds(new WidgetPointer(1092,1102)); + deleteAllExtraChilds(new WidgetPointer(1092,1100)); + deleteAllExtraChilds(new WidgetPointer(1092,1101)); + deleteAllExtraChilds(new WidgetPointer(1092,1099)); + deleteAllExtraChilds(new WidgetPointer(1092,1098)); + deleteAllExtraChilds(new WidgetPointer(1092,1092)); + deleteAllExtraChilds(new WidgetPointer(1092,1076)); + deleteAllExtraChilds(new WidgetPointer(1092,1089)); + deleteAllExtraChilds(new WidgetPointer(1092,1088)); + deleteAllExtraChilds(new WidgetPointer(1092,1086)); + deleteAllExtraChilds(new WidgetPointer(1092,1087)); + deleteAllExtraChilds(new WidgetPointer(1092,1085)); + deleteAllExtraChilds(new WidgetPointer(1092,1084)); + deleteAllExtraChilds(new WidgetPointer(1092,1078)); + deleteAllExtraChilds(new WidgetPointer(1092,1022)); + deleteAllExtraChilds(new WidgetPointer(1092,1037)); + deleteAllExtraChilds(new WidgetPointer(1092,1036)); + deleteAllExtraChilds(new WidgetPointer(1092,1034)); + deleteAllExtraChilds(new WidgetPointer(1092,1032)); + deleteAllExtraChilds(new WidgetPointer(1092,1035)); + deleteAllExtraChilds(new WidgetPointer(1092,1033)); + deleteAllExtraChilds(new WidgetPointer(1092,1031)); + deleteAllExtraChilds(new WidgetPointer(1092,1030)); + deleteAllExtraChilds(new WidgetPointer(1092,1024)); + deleteAllExtraChilds(new WidgetPointer(1092,1006)); + deleteAllExtraChilds(new WidgetPointer(1092,1021)); + deleteAllExtraChilds(new WidgetPointer(1092,1020)); + deleteAllExtraChilds(new WidgetPointer(1092,1018)); + deleteAllExtraChilds(new WidgetPointer(1092,1016)); + deleteAllExtraChilds(new WidgetPointer(1092,1019)); + deleteAllExtraChilds(new WidgetPointer(1092,1017)); + deleteAllExtraChilds(new WidgetPointer(1092,1015)); + deleteAllExtraChilds(new WidgetPointer(1092,1014)); + deleteAllExtraChilds(new WidgetPointer(1092,1008)); + deleteAllExtraChilds(new WidgetPointer(1092,990)); + deleteAllExtraChilds(new WidgetPointer(1092,1005)); + deleteAllExtraChilds(new WidgetPointer(1092,1004)); + deleteAllExtraChilds(new WidgetPointer(1092,1002)); + deleteAllExtraChilds(new WidgetPointer(1092,1000)); + deleteAllExtraChilds(new WidgetPointer(1092,1003)); + deleteAllExtraChilds(new WidgetPointer(1092,1001)); + deleteAllExtraChilds(new WidgetPointer(1092,999)); + deleteAllExtraChilds(new WidgetPointer(1092,998)); + deleteAllExtraChilds(new WidgetPointer(1092,992)); + return; +} diff --git a/dumps/scripts/4808.cs2 b/dumps/scripts/4808.cs2 new file mode 100644 index 0000000..2b94690 --- /dev/null +++ b/dumps/scripts/4808.cs2 @@ -0,0 +1,4 @@ +void script_4808() { + script_4809(); + return; +} diff --git a/dumps/scripts/4809.cs2 b/dumps/scripts/4809.cs2 new file mode 100644 index 0000000..ac4aeba --- /dev/null +++ b/dumps/scripts/4809.cs2 @@ -0,0 +1,20 @@ +void script_4809() { + setWidgetIsHidden(true, new WidgetPointer(1092,1209)); + setWidgetIsHidden(true, new WidgetPointer(1092,1135)); + setWidgetIsHidden(true, new WidgetPointer(1092,1055)); + setWidgetIsHidden(true, new WidgetPointer(1092,1193)); + setWidgetIsHidden(true, new WidgetPointer(1092,1119)); + setWidgetIsHidden(true, new WidgetPointer(1092,1039)); + if (((boolean)script_4828(bitconfig_9558))) { + setWidgetIsHidden(false, new WidgetPointer(1092,1193)); + setWidgetIsHidden(false, new WidgetPointer(1092,1119)); + setWidgetIsHidden(false, new WidgetPointer(1092,1039)); + } else { + setWidgetIsHidden(false, new WidgetPointer(1092,1209)); + setWidgetIsHidden(false, new WidgetPointer(1092,1135)); + setWidgetIsHidden(false, new WidgetPointer(1092,1055)); + } + script_4840(); + script_4814(); + return; +} diff --git a/dumps/scripts/481.cs2 b/dumps/scripts/481.cs2 new file mode 100644 index 0000000..f4f9bd7 --- /dev/null +++ b/dumps/scripts/481.cs2 @@ -0,0 +1,67 @@ +void script_481() { + flow_0: + setWidgetSprite(3255, new WidgetPointer(1015,143)); + setWidgetSprite(3255, new WidgetPointer(1015,145)); + setWidgetSprite(3255, new WidgetPointer(1015,147)); + setWidgetSprite(3255, new WidgetPointer(1015,149)); + setWidgetSprite(3255, new WidgetPointer(1015,151)); + setWidgetSprite(3255, new WidgetPointer(1015,153)); + setWidgetSprite(3255, new WidgetPointer(1015,155)); + setWidgetSprite(3255, new WidgetPointer(1015,157)); + setWidgetSprite(3255, new WidgetPointer(1015,159)); + setWidgetSprite(3255, new WidgetPointer(1015,161)); + SWITCH (bitconfig_7512) { + case 1: + GOTO flow_1 + case 2: + GOTO flow_2 + case 3: + GOTO flow_3 + case 4: + GOTO flow_4 + case 5: + GOTO flow_5 + case 6: + GOTO flow_6 + case 7: + GOTO flow_7 + case 8: + GOTO flow_8 + case 9: + GOTO flow_9 + case 10: + GOTO flow_10 + } + return; + flow_1: + setWidgetSprite(3257, new WidgetPointer(1015,143)); + GOTO flow_11 + flow_2: + setWidgetSprite(3257, new WidgetPointer(1015,145)); + GOTO flow_11 + flow_3: + setWidgetSprite(3257, new WidgetPointer(1015,147)); + GOTO flow_11 + flow_4: + setWidgetSprite(3257, new WidgetPointer(1015,149)); + GOTO flow_11 + flow_5: + setWidgetSprite(3257, new WidgetPointer(1015,151)); + GOTO flow_11 + flow_6: + setWidgetSprite(3257, new WidgetPointer(1015,153)); + GOTO flow_11 + flow_7: + setWidgetSprite(3257, new WidgetPointer(1015,155)); + GOTO flow_11 + flow_8: + setWidgetSprite(3257, new WidgetPointer(1015,157)); + GOTO flow_11 + flow_9: + setWidgetSprite(3257, new WidgetPointer(1015,159)); + GOTO flow_11 + flow_10: + setWidgetSprite(3257, new WidgetPointer(1015,161)); + flow_11: + return; +} diff --git a/dumps/scripts/4810.cs2 b/dumps/scripts/4810.cs2 new file mode 100644 index 0000000..9591bfa --- /dev/null +++ b/dumps/scripts/4810.cs2 @@ -0,0 +1,97 @@ +void script_4810() { + int ivar0; + ivar0 = 1; + setWidgetPosition(4, ivar0, 0, 0, new WidgetPointer(1092,1153)); + ivar0 = add(ivar0, 13); + setWidgetPosition(0, ivar0, 0, 0, new WidgetPointer(1092,1180)); + ivar0 = add(add(ivar0, 1), getWidgetActualHeight(new WidgetPointer(1092,1180))); + if (getWidgetActualHeight(new WidgetPointer(1092,1168)) > 0) { + setWidgetIsHidden(false, new WidgetPointer(1092,1154)); + setWidgetPosition(4, ivar0, 0, 0, new WidgetPointer(1092,1154)); + ivar0 = add(ivar0, 13); + setWidgetPosition(0, ivar0, 0, 0, new WidgetPointer(1092,1168)); + ivar0 = add(add(ivar0, 1), getWidgetActualHeight(new WidgetPointer(1092,1168))); + } else { + setWidgetIsHidden(true, new WidgetPointer(1092,1154)); + setWidgetPosition(0, ivar0, 0, 0, new WidgetPointer(1092,1168)); + } + if (getWidgetActualHeight(new WidgetPointer(1092,1156)) > 0) { + setWidgetIsHidden(false, new WidgetPointer(1092,1155)); + setWidgetPosition(4, ivar0, 0, 0, new WidgetPointer(1092,1155)); + ivar0 = add(ivar0, 13); + setWidgetPosition(0, ivar0, 0, 0, new WidgetPointer(1092,1156)); + ivar0 = add(add(ivar0, 1), getWidgetActualHeight(new WidgetPointer(1092,1156))); + } else { + setWidgetIsHidden(true, new WidgetPointer(1092,1155)); + setWidgetPosition(0, ivar0, 0, 0, new WidgetPointer(1092,1156)); + } + setWidgetPosition(0, ivar0, 0, 0, new WidgetPointer(1092,1192)); + ivar0 = add(add(ivar0, 1), getWidgetActualHeight(new WidgetPointer(1092,1192))); + setWidgetScrollMax(0, ivar0, new WidgetPointer(1092,1152)); + if (isWidgetHidden(new WidgetPointer(1092,1152))) { + script_31(71566296, 71566464, 5666, 5663, 5664, 5665, 5686, 5685); + } + ivar0 = 1; + setWidgetPosition(4, ivar0, 0, 0, new WidgetPointer(1092,1073)); + ivar0 = add(ivar0, 13); + setWidgetPosition(0, ivar0, 0, 0, new WidgetPointer(1092,1104)); + ivar0 = add(add(ivar0, 1), getWidgetActualHeight(new WidgetPointer(1092,1104))); + if (getWidgetActualHeight(new WidgetPointer(1092,1090)) > 0) { + setWidgetIsHidden(false, new WidgetPointer(1092,1074)); + setWidgetPosition(4, ivar0, 0, 0, new WidgetPointer(1092,1074)); + ivar0 = add(ivar0, 13); + setWidgetPosition(0, ivar0, 0, 0, new WidgetPointer(1092,1090)); + ivar0 = add(add(ivar0, 1), getWidgetActualHeight(new WidgetPointer(1092,1090))); + } else { + setWidgetIsHidden(true, new WidgetPointer(1092,1074)); + setWidgetPosition(0, ivar0, 0, 0, new WidgetPointer(1092,1090)); + } + if (getWidgetActualHeight(new WidgetPointer(1092,1076)) > 0) { + setWidgetIsHidden(false, new WidgetPointer(1092,1075)); + setWidgetPosition(4, ivar0, 0, 0, new WidgetPointer(1092,1075)); + ivar0 = add(ivar0, 13); + setWidgetPosition(0, ivar0, 0, 0, new WidgetPointer(1092,1076)); + ivar0 = add(add(ivar0, 1), getWidgetActualHeight(new WidgetPointer(1092,1076))); + } else { + setWidgetIsHidden(true, new WidgetPointer(1092,1075)); + setWidgetPosition(0, ivar0, 0, 0, new WidgetPointer(1092,1076)); + } + setWidgetPosition(0, ivar0, 0, 0, new WidgetPointer(1092,1118)); + ivar0 = add(add(ivar0, 1), getWidgetActualHeight(new WidgetPointer(1092,1118))); + setWidgetScrollMax(0, ivar0, new WidgetPointer(1092,1072)); + if (isWidgetHidden(new WidgetPointer(1092,1072))) { + script_31(71566296, 71566384, 5666, 5663, 5664, 5665, 5686, 5685); + } + ivar0 = 1; + setWidgetPosition(4, ivar0, 0, 0, new WidgetPointer(1092,987)); + ivar0 = add(ivar0, 13); + setWidgetPosition(0, ivar0, 0, 0, new WidgetPointer(1092,1022)); + ivar0 = add(add(ivar0, 1), getWidgetActualHeight(new WidgetPointer(1092,1022))); + if (getWidgetActualHeight(new WidgetPointer(1092,1006)) > 0) { + setWidgetIsHidden(false, new WidgetPointer(1092,988)); + setWidgetPosition(4, ivar0, 0, 0, new WidgetPointer(1092,988)); + ivar0 = add(ivar0, 13); + setWidgetPosition(0, ivar0, 0, 0, new WidgetPointer(1092,1006)); + ivar0 = add(add(ivar0, 1), getWidgetActualHeight(new WidgetPointer(1092,1006))); + } else { + setWidgetIsHidden(true, new WidgetPointer(1092,988)); + setWidgetPosition(0, ivar0, 0, 0, new WidgetPointer(1092,1006)); + } + if (getWidgetActualHeight(new WidgetPointer(1092,990)) > 0) { + setWidgetIsHidden(false, new WidgetPointer(1092,989)); + setWidgetPosition(4, ivar0, 0, 0, new WidgetPointer(1092,989)); + ivar0 = add(ivar0, 13); + setWidgetPosition(0, ivar0, 0, 0, new WidgetPointer(1092,990)); + ivar0 = add(add(ivar0, 1), getWidgetActualHeight(new WidgetPointer(1092,990))); + } else { + setWidgetIsHidden(true, new WidgetPointer(1092,989)); + setWidgetPosition(0, ivar0, 0, 0, new WidgetPointer(1092,990)); + } + setWidgetPosition(0, ivar0, 0, 0, new WidgetPointer(1092,1038)); + ivar0 = add(add(ivar0, 1), getWidgetActualHeight(new WidgetPointer(1092,1038))); + setWidgetScrollMax(0, ivar0, new WidgetPointer(1092,986)); + if (isWidgetHidden(new WidgetPointer(1092,986))) { + script_31(71566296, 71566298, 5666, 5663, 5664, 5665, 5686, 5685); + } + return; +} diff --git a/dumps/scripts/4811.cs2 b/dumps/scripts/4811.cs2 new file mode 100644 index 0000000..f9dac0c --- /dev/null +++ b/dumps/scripts/4811.cs2 @@ -0,0 +1,4 @@ +void script_4811(int arg0) { + script_4940(); + return; +} diff --git a/dumps/scripts/4812.cs2 b/dumps/scripts/4812.cs2 new file mode 100644 index 0000000..264b7fe --- /dev/null +++ b/dumps/scripts/4812.cs2 @@ -0,0 +1,13 @@ +void script_4812(int arg0,int arg1,int arg2,string arg3) { + if (((boolean)script_4761(arg2))) { + return; + } + if (globalint_2 != 1) { + arg3 = arg3 + "
" + "Requires tier " + intToStr(arg1) + " resources."; + setWidgetSprite(arg0, new WidgetPointer(1092,1266)); + setWidgetText(new WidgetPointer(1092,1267), arg3); + setWidgetIsHidden(false, new WidgetPointer(1092,1255)); + globalint_2 = 1; + } + return; +} diff --git a/dumps/scripts/4813.cs2 b/dumps/scripts/4813.cs2 new file mode 100644 index 0000000..7f5794a --- /dev/null +++ b/dumps/scripts/4813.cs2 @@ -0,0 +1,7 @@ +void script_4813() { + setWidgetSprite(-1, new WidgetPointer(1092,1266)); + setWidgetText(new WidgetPointer(1092,1267), ""); + setWidgetIsHidden(true, new WidgetPointer(1092,1255)); + globalint_2 = 0; + return; +} diff --git a/dumps/scripts/4814.cs2 b/dumps/scripts/4814.cs2 new file mode 100644 index 0000000..2e96070 --- /dev/null +++ b/dumps/scripts/4814.cs2 @@ -0,0 +1,249 @@ +void script_4814() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + string svar0; + ivar0 = 0; + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + svar0 = ""; + setWidgetText(new WidgetPointer(1092,1212), ""); + setWidgetText(new WidgetPointer(1092,1138), ""); + setWidgetText(new WidgetPointer(1092,1058), ""); + setWidgetIsHidden(false, new WidgetPointer(1092,1210)); + setWidgetIsHidden(false, new WidgetPointer(1092,1136)); + setWidgetIsHidden(false, new WidgetPointer(1092,1056)); + setWidgetIsHidden(true, new WidgetPointer(1092,1212)); + setWidgetIsHidden(true, new WidgetPointer(1092,1138)); + setWidgetIsHidden(true, new WidgetPointer(1092,1058)); + setScriptCallOnMouseExit(40, new WidgetPointer(1092,327), "I", new WidgetPointer(1092,1223)); + setScriptCallOnMouseExit(40, new WidgetPointer(1092,327), "I", new WidgetPointer(1092,1149)); + setScriptCallOnMouseExit(40, new WidgetPointer(1092,327), "I", new WidgetPointer(1092,1069)); + setScriptCallOnMouseExit(40, new WidgetPointer(1092,327), "I", new WidgetPointer(1092,1207)); + setScriptCallOnMouseExit(40, new WidgetPointer(1092,327), "I", new WidgetPointer(1092,1133)); + setScriptCallOnMouseExit(40, new WidgetPointer(1092,327), "I", new WidgetPointer(1092,1053)); + setScriptCallOnMouseExit(40, new WidgetPointer(1092,327), "I", new WidgetPointer(1092,1220)); + setScriptCallOnMouseExit(40, new WidgetPointer(1092,327), "I", new WidgetPointer(1092,1146)); + setScriptCallOnMouseExit(40, new WidgetPointer(1092,327), "I", new WidgetPointer(1092,1066)); + setScriptCallOnMouseExit(40, new WidgetPointer(1092,327), "I", new WidgetPointer(1092,1204)); + setScriptCallOnMouseExit(40, new WidgetPointer(1092,327), "I", new WidgetPointer(1092,1130)); + setScriptCallOnMouseExit(40, new WidgetPointer(1092,327), "I", new WidgetPointer(1092,1050)); + if (citadelConfigsInitialized()) { + if (((boolean)script_5008()) || ((boolean)script_5144(-1))) { + setWidgetIsHidden(false, new WidgetPointer(1092,1223)); + setWidgetIsHidden(false, new WidgetPointer(1092,1149)); + setWidgetIsHidden(false, new WidgetPointer(1092,1069)); + setWidgetIsHidden(false, new WidgetPointer(1092,1207)); + setWidgetIsHidden(false, new WidgetPointer(1092,1133)); + setWidgetIsHidden(false, new WidgetPointer(1092,1053)); + svar0 = "Your rank may not currently make alterations to this item"; + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1223), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1223)); + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1149), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1149)); + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1069), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1069)); + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1207), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1207)); + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1133), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1133)); + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1053), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1053)); + } else { + switch (bitconfig_9558) { + case 1: + ivar0 = bitconfig_9563; + break; + case 2: + ivar0 = bitconfig_9572; + break; + case 3: + ivar0 = bitconfig_9581; + } + switch (script_4829(bitconfig_9558)) { + flow_8: + case 1: + svar0 = "You may submit this customisation to the build queue."; + switch (ivar0) { + case 1: + setWidgetIsHidden(true, new WidgetPointer(1092,1212)); + setWidgetIsHidden(false, new WidgetPointer(1092,1210)); + setWidgetIsHidden(true, new WidgetPointer(1092,1223)); + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1220), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1220)); + break; + case 2: + setWidgetIsHidden(true, new WidgetPointer(1092,1138)); + setWidgetIsHidden(false, new WidgetPointer(1092,1136)); + setWidgetIsHidden(true, new WidgetPointer(1092,1149)); + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1146), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1146)); + break; + case 3: + setWidgetIsHidden(true, new WidgetPointer(1092,1058)); + setWidgetIsHidden(false, new WidgetPointer(1092,1056)); + setWidgetIsHidden(true, new WidgetPointer(1092,1069)); + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1066), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1066)); + } + break; + case 2: + switch (ivar0) { + case 1: + svar0 = "Your citadel can not produce the resouces with which to purchase this customisation."; + setWidgetText(new WidgetPointer(1092,1212), svar0); + setWidgetIsHidden(false, new WidgetPointer(1092,1223)); + setWidgetIsHidden(false, new WidgetPointer(1092,1212)); + setWidgetIsHidden(true, new WidgetPointer(1092,1210)); + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1223), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1223)); + svar0 = "You may cancel this customisation from the build queue but you will lose any resources already spent."; + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1204), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1204)); + svar0 = "You do not have the rank to cancel this job."; + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1207), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1207)); + break; + case 2: + svar0 = "Your citadel can not produce the resouces with which to purchase this customisation."; + setWidgetText(new WidgetPointer(1092,1138), svar0); + setWidgetIsHidden(false, new WidgetPointer(1092,1149)); + setWidgetIsHidden(false, new WidgetPointer(1092,1138)); + setWidgetIsHidden(true, new WidgetPointer(1092,1136)); + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1149), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1149)); + svar0 = "You may cancel this customisation from the build queue but you will lose any resources already spent."; + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1130), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1130)); + svar0 = "You do not have the rank to cancel this job."; + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1133), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1133)); + break; + case 3: + svar0 = "Your citadel can not produce the resouces with which to purchase this customisation."; + setWidgetText(new WidgetPointer(1092,1058), svar0); + setWidgetIsHidden(false, new WidgetPointer(1092,1069)); + setWidgetIsHidden(false, new WidgetPointer(1092,1058)); + setWidgetIsHidden(true, new WidgetPointer(1092,1056)); + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1069), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1069)); + svar0 = "You may cancel this customisation from the build queue but you will lose any resources already spent."; + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1050), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1050)); + svar0 = "You do not have the rank to cancel this job."; + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1053), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1053)); + } + break; + case 3: + switch (ivar0) { + case 1: + svar0 = "Select valid options for each part of the customisation before adding to the build queue."; + setWidgetText(new WidgetPointer(1092,1212), svar0); + setWidgetIsHidden(false, new WidgetPointer(1092,1223)); + setWidgetIsHidden(false, new WidgetPointer(1092,1212)); + setWidgetIsHidden(true, new WidgetPointer(1092,1210)); + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1223), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1223)); + svar0 = "You may cancel this customisation from the build queue but you will lose any resources already spent."; + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1204), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1204)); + svar0 = "You do not have the rank to cancel this job."; + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1207), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1207)); + break; + case 2: + svar0 = "You must select valid options for each part of the customisation before you can add it to the build queue."; + setWidgetText(new WidgetPointer(1092,1138), svar0); + setWidgetIsHidden(false, new WidgetPointer(1092,1149)); + setWidgetIsHidden(false, new WidgetPointer(1092,1138)); + setWidgetIsHidden(true, new WidgetPointer(1092,1136)); + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1149), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1149)); + svar0 = "You may cancel this customisation from the build queue but you will lose any resources already spent."; + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1130), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1130)); + svar0 = "You do not have the rank to cancel this job."; + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1133), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1133)); + break; + case 3: + svar0 = "You must select valid options for each part of the customisation before you can add it to the build queue."; + setWidgetText(new WidgetPointer(1092,1058), svar0); + setWidgetIsHidden(false, new WidgetPointer(1092,1069)); + setWidgetIsHidden(false, new WidgetPointer(1092,1058)); + setWidgetIsHidden(true, new WidgetPointer(1092,1056)); + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1069), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1069)); + svar0 = "You may cancel this customisation from the build queue but you will lose any resources already spent."; + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1050), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1050)); + svar0 = "You do not have the rank to cancel this job."; + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1053), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1053)); + } + break; + case 4: + switch (ivar0) { + case 1: + svar0 = "The selection you have chosen is already built in the citadel."; + setWidgetText(new WidgetPointer(1092,1212), svar0); + setWidgetIsHidden(false, new WidgetPointer(1092,1223)); + setWidgetIsHidden(false, new WidgetPointer(1092,1212)); + setWidgetIsHidden(true, new WidgetPointer(1092,1210)); + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1223), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1223)); + svar0 = "You may cancel this customisation from the build queue but you will lose any resources already spent."; + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1204), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1204)); + svar0 = "You do not have the rank to cancel this job."; + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1207), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1207)); + break; + case 2: + svar0 = "The selection you have chosen is already built in the citadel."; + setWidgetText(new WidgetPointer(1092,1138), svar0); + setWidgetIsHidden(false, new WidgetPointer(1092,1149)); + setWidgetIsHidden(false, new WidgetPointer(1092,1138)); + setWidgetIsHidden(true, new WidgetPointer(1092,1136)); + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1149), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1149)); + svar0 = "You may cancel this customisation from the build queue but you will lose any resources already spent."; + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1130), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1130)); + svar0 = "You do not have the rank to cancel this job."; + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1133), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1133)); + break; + case 3: + svar0 = "The selection you have chosen is already built in the citadel."; + setWidgetText(new WidgetPointer(1092,1058), svar0); + setWidgetIsHidden(false, new WidgetPointer(1092,1069)); + setWidgetIsHidden(false, new WidgetPointer(1092,1058)); + setWidgetIsHidden(true, new WidgetPointer(1092,1056)); + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1069), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1069)); + svar0 = "You may cancel this customisation from the build queue but you will lose any resources already spent."; + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1050), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1050)); + svar0 = "You do not have the rank to cancel this job."; + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1053), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1053)); + } + break; + case 5: + SWITCH (ivar0) { + case 1: + GOTO flow_29 + case 2: + GOTO flow_30 + case 3: + GOTO flow_31 + } + break; + flow_29: + svar0 = "This hotspot is currently queued to be reset, you may cancel this reset at no cost."; + setWidgetText(new WidgetPointer(1092,1212), svar0); + setWidgetIsHidden(false, new WidgetPointer(1092,1223)); + setWidgetIsHidden(false, new WidgetPointer(1092,1212)); + setWidgetIsHidden(true, new WidgetPointer(1092,1210)); + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1149), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1223)); + svar0 = "This hotspot is currently queued to be reset, you may cancel this reset at no cost."; + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1204), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1204)); + svar0 = "You do not have the rank to cancel this job."; + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1207), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1207)); + break; + flow_30: + svar0 = "This hotspot is currently queued to be reset, you may cancel this reset at no cost."; + setWidgetText(new WidgetPointer(1092,1138), svar0); + setWidgetIsHidden(false, new WidgetPointer(1092,1149)); + setWidgetIsHidden(false, new WidgetPointer(1092,1138)); + setWidgetIsHidden(true, new WidgetPointer(1092,1136)); + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1149), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1149)); + svar0 = "This hotspot is currently queued to be reset, you may cancel this reset at no cost."; + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1130), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1130)); + svar0 = "You do not have the rank to cancel this job."; + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1133), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1133)); + break; + flow_31: + svar0 = "This hotspot is currently queued to be reset, you may cancel this reset at no cost."; + setWidgetText(new WidgetPointer(1092,1058), svar0); + setWidgetIsHidden(false, new WidgetPointer(1092,1069)); + setWidgetIsHidden(false, new WidgetPointer(1092,1058)); + setWidgetIsHidden(true, new WidgetPointer(1092,1056)); + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1069), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1069)); + svar0 = "This hotspot is currently queued to be reset, you may cancel this reset at no cost."; + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1050), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1050)); + svar0 = "You do not have the rank to cancel this job."; + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,1053), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,1053)); + } + } + } + return; +} diff --git a/dumps/scripts/4815.cs2 b/dumps/scripts/4815.cs2 new file mode 100644 index 0000000..b78c094 --- /dev/null +++ b/dumps/scripts/4815.cs2 @@ -0,0 +1,42 @@ +int script_4815(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int stack_dump0; + int stack_dump1; + cs2func_script_4818_struct(11,0,0) structdump_2; + ivar2 = -1; + ivar3 = -1; + ivar4 = -1; + ivar5 = -1; + ivar6 = -1; + ivar7 = -1; + ivar8 = -1; + ivar9 = -1; + ivar10 = -1; + ivar11 = -1; + ivar12 = -1; + stack_dump0 = arg0; + stack_dump1 = arg1; + structdump_2 = script_4818(stack_dump0, stack_dump1); + ivar12 = structdump_2.intpart_10; + ivar11 = structdump_2.intpart_9; + ivar10 = structdump_2.intpart_8; + ivar9 = structdump_2.intpart_7; + ivar8 = structdump_2.intpart_6; + ivar7 = structdump_2.intpart_5; + ivar6 = structdump_2.intpart_4; + ivar5 = structdump_2.intpart_3; + ivar4 = structdump_2.intpart_2; + ivar3 = structdump_2.intpart_1; + ivar2 = structdump_2.intpart_0; + return ivar2; +} diff --git a/dumps/scripts/4816.cs2 b/dumps/scripts/4816.cs2 new file mode 100644 index 0000000..b667294 --- /dev/null +++ b/dumps/scripts/4816.cs2 @@ -0,0 +1,42 @@ +int script_4816(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int stack_dump0; + int stack_dump1; + cs2func_script_4818_struct(11,0,0) structdump_2; + ivar2 = -1; + ivar3 = -1; + ivar4 = -1; + ivar5 = -1; + ivar6 = -1; + ivar7 = -1; + ivar8 = -1; + ivar9 = -1; + ivar10 = -1; + ivar11 = -1; + ivar12 = -1; + stack_dump0 = arg0; + stack_dump1 = arg1; + structdump_2 = script_4818(stack_dump0, stack_dump1); + ivar12 = structdump_2.intpart_10; + ivar11 = structdump_2.intpart_9; + ivar10 = structdump_2.intpart_8; + ivar9 = structdump_2.intpart_7; + ivar8 = structdump_2.intpart_6; + ivar7 = structdump_2.intpart_5; + ivar6 = structdump_2.intpart_4; + ivar5 = structdump_2.intpart_3; + ivar4 = structdump_2.intpart_2; + ivar3 = structdump_2.intpart_1; + ivar2 = structdump_2.intpart_0; + return getWidgetParentId(new WidgetPointer(ivar2)); +} diff --git a/dumps/scripts/4817.cs2 b/dumps/scripts/4817.cs2 new file mode 100644 index 0000000..d028f88 --- /dev/null +++ b/dumps/scripts/4817.cs2 @@ -0,0 +1,42 @@ +int script_4817(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int stack_dump0; + int stack_dump1; + cs2func_script_4818_struct(11,0,0) structdump_2; + ivar2 = -1; + ivar3 = -1; + ivar4 = -1; + ivar5 = -1; + ivar6 = -1; + ivar7 = -1; + ivar8 = -1; + ivar9 = -1; + ivar10 = -1; + ivar11 = -1; + ivar12 = -1; + stack_dump0 = arg0; + stack_dump1 = arg1; + structdump_2 = script_4818(stack_dump0, stack_dump1); + ivar12 = structdump_2.intpart_10; + ivar11 = structdump_2.intpart_9; + ivar10 = structdump_2.intpart_8; + ivar9 = structdump_2.intpart_7; + ivar8 = structdump_2.intpart_6; + ivar7 = structdump_2.intpart_5; + ivar6 = structdump_2.intpart_4; + ivar5 = structdump_2.intpart_3; + ivar4 = structdump_2.intpart_2; + ivar3 = structdump_2.intpart_1; + ivar2 = structdump_2.intpart_0; + return ivar10; +} diff --git a/dumps/scripts/4818.cs2 b/dumps/scripts/4818.cs2 new file mode 100644 index 0000000..ab3889b --- /dev/null +++ b/dumps/scripts/4818.cs2 @@ -0,0 +1,160 @@ +cs2func_script_4818_struct(11,0,0) script_4818(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + ivar2 = -1; + ivar3 = -1; + ivar4 = -1; + ivar5 = -1; + ivar6 = -1; + ivar7 = -1; + ivar8 = -1; + ivar9 = -1; + ivar10 = -1; + ivar11 = -1; + ivar12 = -1; + switch (arg0) { + flow_1: + case 1: + switch (arg1) { + case 1: + ivar2 = 71566492; + ivar3 = 71566503; + ivar4 = 71566502; + ivar5 = -1; + ivar6 = -1; + ivar7 = 71566501; + ivar8 = -1; + ivar9 = -1; + ivar10 = 71566500; + ivar11 = 71566494; + ivar12 = 71566465; + break; + case 2: + ivar2 = 71566480; + ivar3 = 71566491; + ivar4 = 71566490; + ivar5 = -1; + ivar6 = -1; + ivar7 = 71566489; + ivar8 = -1; + ivar9 = -1; + ivar10 = 71566488; + ivar11 = 71566482; + ivar12 = 71566466; + break; + case 3: + ivar2 = 71566468; + ivar3 = 71566479; + ivar4 = 71566478; + ivar5 = -1; + ivar6 = -1; + ivar7 = 71566477; + ivar8 = -1; + ivar9 = -1; + ivar10 = 71566476; + ivar11 = 71566470; + ivar12 = 71566467; + } + break; + case 2: + switch (arg1) { + case 1: + ivar2 = 71566416; + ivar3 = 71566429; + ivar4 = 71566428; + ivar5 = 71566426; + ivar6 = -1; + ivar7 = 71566427; + ivar8 = 71566425; + ivar9 = -1; + ivar10 = 71566424; + ivar11 = 71566418; + ivar12 = 71566385; + break; + case 2: + ivar2 = 71566402; + ivar3 = 71566415; + ivar4 = 71566414; + ivar5 = 71566412; + ivar6 = -1; + ivar7 = 71566413; + ivar8 = 71566411; + ivar9 = -1; + ivar10 = 71566410; + ivar11 = 71566404; + ivar12 = 71566386; + break; + case 3: + ivar2 = 71566388; + ivar3 = 71566401; + ivar4 = 71566400; + ivar5 = 71566398; + ivar6 = -1; + ivar7 = 71566399; + ivar8 = 71566397; + ivar9 = -1; + ivar10 = 71566396; + ivar11 = 71566390; + ivar12 = 71566387; + } + break; + case 3: + SWITCH (arg1) { + case 1: + GOTO flow_12 + case 2: + GOTO flow_13 + case 3: + GOTO flow_14 + } + break; + flow_12: + ivar2 = 71566334; + ivar3 = 71566349; + ivar4 = 71566348; + ivar5 = 71566346; + ivar6 = 71566344; + ivar7 = 71566347; + ivar8 = 71566345; + ivar9 = 71566343; + ivar10 = 71566342; + ivar11 = 71566336; + ivar12 = 71566299; + break; + flow_13: + ivar2 = 71566318; + ivar3 = 71566333; + ivar4 = 71566332; + ivar5 = 71566330; + ivar6 = 71566328; + ivar7 = 71566331; + ivar8 = 71566329; + ivar9 = 71566327; + ivar10 = 71566326; + ivar11 = 71566320; + ivar12 = 71566300; + break; + flow_14: + ivar2 = 71566302; + ivar3 = 71566317; + ivar4 = 71566316; + ivar5 = 71566314; + ivar6 = 71566312; + ivar7 = 71566315; + ivar8 = 71566313; + ivar9 = 71566311; + ivar10 = 71566310; + ivar11 = 71566304; + ivar12 = 71566301; + } + return newstruct cs2func_script_4818_struct(ivar2, ivar3, ivar4, ivar5, ivar6, ivar7, ivar8, ivar9, ivar10, ivar11, ivar12); +} diff --git a/dumps/scripts/4819.cs2 b/dumps/scripts/4819.cs2 new file mode 100644 index 0000000..0c5684c --- /dev/null +++ b/dumps/scripts/4819.cs2 @@ -0,0 +1,11 @@ +int script_4819(int arg0) { + switch (arg0) { + case 1: + return script_4821(bitconfig_9570); + case 2: + return script_4821(bitconfig_9579); + case 3: + return script_4821(bitconfig_9588); + } + return -1; +} diff --git a/dumps/scripts/482.cs2 b/dumps/scripts/482.cs2 new file mode 100644 index 0000000..66f97c4 --- /dev/null +++ b/dumps/scripts/482.cs2 @@ -0,0 +1,57 @@ +void script_482() { + flow_0: + SWITCH (bitconfig_7512) { + case 1: + GOTO flow_1 + case 2: + GOTO flow_2 + case 3: + GOTO flow_3 + case 4: + GOTO flow_4 + case 5: + GOTO flow_5 + case 6: + GOTO flow_6 + case 7: + GOTO flow_7 + case 8: + GOTO flow_8 + case 9: + GOTO flow_9 + case 10: + GOTO flow_10 + } + return; + flow_1: + setWidgetSprite(3257, new WidgetPointer(1015,143)); + GOTO flow_11 + flow_2: + setWidgetSprite(3257, new WidgetPointer(1015,145)); + GOTO flow_11 + flow_3: + setWidgetSprite(3257, new WidgetPointer(1015,147)); + GOTO flow_11 + flow_4: + setWidgetSprite(3257, new WidgetPointer(1015,149)); + GOTO flow_11 + flow_5: + setWidgetSprite(3257, new WidgetPointer(1015,151)); + GOTO flow_11 + flow_6: + setWidgetSprite(3257, new WidgetPointer(1015,153)); + GOTO flow_11 + flow_7: + setWidgetSprite(3257, new WidgetPointer(1015,155)); + GOTO flow_11 + flow_8: + setWidgetSprite(3257, new WidgetPointer(1015,157)); + GOTO flow_11 + flow_9: + setWidgetSprite(3257, new WidgetPointer(1015,159)); + GOTO flow_11 + flow_10: + setWidgetSprite(3257, new WidgetPointer(1015,161)); + flow_11: + return; +} diff --git a/dumps/scripts/4820.cs2 b/dumps/scripts/4820.cs2 new file mode 100644 index 0000000..fecd967 --- /dev/null +++ b/dumps/scripts/4820.cs2 @@ -0,0 +1,35 @@ +int script_4820(int arg0) { + switch (arg0) { + case 1: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 2: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 3: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return -1; +} diff --git a/dumps/scripts/4821.cs2 b/dumps/scripts/4821.cs2 new file mode 100644 index 0000000..1793e30 --- /dev/null +++ b/dumps/scripts/4821.cs2 @@ -0,0 +1,56 @@ +int script_4821(int arg0) { + switch (arg0) { + case 21: + case 23: + case 22: + case 25: + case 24: + case 27: + case 26: + case 28: + return 4047; + case 31: + case 34: + case 35: + case 32: + case 33: + return 4050; + case 42: + case 43: + case 41: + case 44: + case 45: + return 4053; + case 51: + return 4056; + case 100: + return 4062; + case 101: + return 4065; + case 102: + return 4068; + case 103: + return 4071; + case 104: + return 4074; + case 105: + return 4077; + case 106: + return 4080; + case 107: + return 4083; + case 108: + return 4086; + case 109: + return 4089; + case 110: + return 4092; + case 111: + return 4095; + case 112: + return 4098; + case 113: + return 4101; + } + return -1; +} diff --git a/dumps/scripts/4822.cs2 b/dumps/scripts/4822.cs2 new file mode 100644 index 0000000..2399900 --- /dev/null +++ b/dumps/scripts/4822.cs2 @@ -0,0 +1,11 @@ +int script_4822(int arg0) { + switch (arg0) { + case 1: + return script_4824(bitconfig_9570); + case 2: + return script_4824(bitconfig_9579); + case 3: + return script_4824(bitconfig_9588); + } + return -1; +} diff --git a/dumps/scripts/4823.cs2 b/dumps/scripts/4823.cs2 new file mode 100644 index 0000000..4a0f800 --- /dev/null +++ b/dumps/scripts/4823.cs2 @@ -0,0 +1,35 @@ +int script_4823(int arg0) { + switch (arg0) { + case 1: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 2: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 3: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return -1; +} diff --git a/dumps/scripts/4824.cs2 b/dumps/scripts/4824.cs2 new file mode 100644 index 0000000..c05355b --- /dev/null +++ b/dumps/scripts/4824.cs2 @@ -0,0 +1,56 @@ +int script_4824(int arg0) { + switch (arg0) { + case 21: + case 23: + case 22: + case 25: + case 24: + case 27: + case 26: + case 28: + return 4048; + case 31: + case 34: + case 35: + case 32: + case 33: + return 4051; + case 42: + case 43: + case 41: + case 44: + case 45: + return 4054; + case 51: + return 4057; + case 100: + return 4063; + case 101: + return 4066; + case 102: + return 4069; + case 103: + return 4072; + case 104: + return 4075; + case 105: + return 4078; + case 106: + return 4081; + case 107: + return 4084; + case 108: + return 4087; + case 109: + return 4090; + case 110: + return 4093; + case 111: + return 4096; + case 112: + return 4099; + case 113: + return 4102; + } + return -1; +} diff --git a/dumps/scripts/4825.cs2 b/dumps/scripts/4825.cs2 new file mode 100644 index 0000000..755e153 --- /dev/null +++ b/dumps/scripts/4825.cs2 @@ -0,0 +1,11 @@ +int script_4825(int arg0) { + switch (arg0) { + case 1: + return script_4827(bitconfig_9570); + case 2: + return script_4827(bitconfig_9579); + case 3: + return script_4827(bitconfig_9588); + } + return -1; +} diff --git a/dumps/scripts/4826.cs2 b/dumps/scripts/4826.cs2 new file mode 100644 index 0000000..781cb8e --- /dev/null +++ b/dumps/scripts/4826.cs2 @@ -0,0 +1,35 @@ +int script_4826(int arg0) { + switch (arg0) { + case 1: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 2: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 3: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return -1; +} diff --git a/dumps/scripts/4827.cs2 b/dumps/scripts/4827.cs2 new file mode 100644 index 0000000..bae3d59 --- /dev/null +++ b/dumps/scripts/4827.cs2 @@ -0,0 +1,56 @@ +int script_4827(int arg0) { + switch (arg0) { + case 21: + case 23: + case 22: + case 25: + case 24: + case 27: + case 26: + case 28: + return 4049; + case 31: + case 34: + case 35: + case 32: + case 33: + return 4052; + case 42: + case 43: + case 41: + case 44: + case 45: + return 4055; + case 51: + return 4058; + case 100: + return 4064; + case 101: + return 4067; + case 102: + return 4070; + case 103: + return 4073; + case 104: + return 4076; + case 105: + return 4079; + case 106: + return 4082; + case 107: + return 4085; + case 108: + return 4088; + case 109: + return 4091; + case 110: + return 4094; + case 111: + return 4097; + case 112: + return 4100; + case 113: + return 4103; + } + return -1; +} diff --git a/dumps/scripts/4828.cs2 b/dumps/scripts/4828.cs2 new file mode 100644 index 0000000..2653eb1 --- /dev/null +++ b/dumps/scripts/4828.cs2 @@ -0,0 +1,19 @@ +int script_4828(int arg0) { + switch (bitconfig_9558) { + case 1: + if (((boolean)bitconfig_9559)) { + return 1; + } + break; + case 2: + if (((boolean)bitconfig_9560)) { + return 1; + } + break; + case 3: + if (((boolean)bitconfig_9561)) { + return 1; + } + } + return 0; +} diff --git a/dumps/scripts/4829.cs2 b/dumps/scripts/4829.cs2 new file mode 100644 index 0000000..e9fb479 --- /dev/null +++ b/dumps/scripts/4829.cs2 @@ -0,0 +1,411 @@ +int script_4829(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int stack_dump0; + ivar1 = script_4830(arg0); + if (ivar1 != 1) { + return ivar1; + } + ivar2 = 0; + ivar3 = 0; + ivar4 = 0; + ivar5 = 0; + ivar6 = 0; + ivar7 = 0; + switch (arg0) { + case 1: + ivar2 = bitconfig_9570; + ivar3 = bitconfig_9562; + ivar7 = bitconfig_9563; + ivar4 = bitconfig_9567; + ivar5 = bitconfig_9568; + ivar6 = bitconfig_9569; + break; + case 2: + ivar2 = bitconfig_9579; + ivar3 = bitconfig_9571; + ivar7 = bitconfig_9572; + ivar4 = bitconfig_9576; + ivar5 = bitconfig_9577; + ivar6 = bitconfig_9578; + break; + case 3: + ivar2 = bitconfig_9588; + ivar3 = bitconfig_9580; + ivar7 = bitconfig_9581; + ivar4 = bitconfig_9585; + ivar5 = bitconfig_9586; + ivar6 = bitconfig_9587; + } + switch (ivar2) { + case 100: + stack_dump0 = ivar3; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 101: + stack_dump0 = ivar3; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 102: + stack_dump0 = ivar3; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 103: + stack_dump0 = ivar3; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 104: + stack_dump0 = ivar3; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 105: + stack_dump0 = ivar3; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 106: + stack_dump0 = ivar3; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 107: + stack_dump0 = ivar3; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 108: + stack_dump0 = ivar3; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 109: + stack_dump0 = ivar3; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 110: + stack_dump0 = ivar3; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 111: + stack_dump0 = ivar3; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 112: + stack_dump0 = ivar3; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 113: + stack_dump0 = ivar3; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 21: + stack_dump0 = ivar3; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 22: + stack_dump0 = ivar3; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 23: + stack_dump0 = ivar3; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 24: + stack_dump0 = ivar3; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 25: + stack_dump0 = ivar3; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 26: + stack_dump0 = ivar3; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 27: + stack_dump0 = ivar3; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 28: + stack_dump0 = ivar3; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 31: + stack_dump0 = ivar3; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 32: + stack_dump0 = ivar3; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 33: + stack_dump0 = ivar3; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 34: + stack_dump0 = ivar3; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 35: + stack_dump0 = ivar3; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 41: + stack_dump0 = ivar3; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 42: + stack_dump0 = ivar3; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 43: + stack_dump0 = ivar3; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 44: + stack_dump0 = ivar3; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 45: + stack_dump0 = ivar3; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 51: + stack_dump0 = ivar3; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return ivar1; +} diff --git a/dumps/scripts/483.cs2 b/dumps/scripts/483.cs2 new file mode 100644 index 0000000..7cd79f0 --- /dev/null +++ b/dumps/scripts/483.cs2 @@ -0,0 +1,34 @@ +string script_483(int arg0) { + flow_0: + SWITCH (arg0) { + case 1: + GOTO flow_1 + case 2: + GOTO flow_2 + case 3: + GOTO flow_3 + case 4: + GOTO flow_4 + case 5: + GOTO flow_5 + case 6: + GOTO flow_6 + case 7: + GOTO flow_7 + } + return "No Troop"; + flow_1: + return "Scout"; + flow_2: + return "Foot Soldier"; + flow_3: + return "Halberdier"; + flow_4: + return "Archer"; + flow_5: + return "Mage"; + flow_6: + return "Knight"; + flow_7: + return "Champion"; +} diff --git a/dumps/scripts/4830.cs2 b/dumps/scripts/4830.cs2 new file mode 100644 index 0000000..e6e9eea --- /dev/null +++ b/dumps/scripts/4830.cs2 @@ -0,0 +1,84 @@ +int script_4830(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + ivar1 = -1; + ivar2 = -1; + ivar3 = -1; + ivar4 = -1; + ivar5 = -1; + ivar6 = 0; + ivar7 = 0; + ivar8 = 0; + ivar9 = 0; + ivar10 = 0; + ivar11 = 0; + ivar12 = 0; + switch (arg0) { + case 1: + ivar6 = bitconfig_9562; + ivar7 = bitconfig_9563; + ivar9 = bitconfig_9567; + ivar10 = bitconfig_9568; + ivar11 = bitconfig_9569; + ivar12 = bitconfig_9566; + break; + case 2: + ivar6 = bitconfig_9571; + ivar7 = bitconfig_9572; + ivar9 = bitconfig_9576; + ivar10 = bitconfig_9577; + ivar11 = bitconfig_9578; + ivar12 = bitconfig_9575; + break; + case 3: + ivar6 = bitconfig_9580; + ivar7 = bitconfig_9581; + ivar9 = bitconfig_9585; + ivar10 = bitconfig_9586; + ivar11 = bitconfig_9587; + ivar12 = bitconfig_9584; + } + if (((boolean)ivar12)) { + return 5; + } + if (((boolean)ivar6)) { + return -1; + } + ivar1 = cs2method_3408(105, 103, 4043, ivar6); + if (ivar1 == -1) { + return -1; + } + if ((ivar7 > 0) && (ivar7 <= 3)) { + ivar2 = cs2method_3408(105, 103, ivar1, ivar7); + if (ivar2 != -1) { + ivar3 = cs2method_3408(105, 103, ivar2, 1); + ivar4 = cs2method_3408(105, 103, ivar2, 2); + ivar5 = cs2method_3408(105, 103, ivar2, 3); + if (ivar3 != -1) { + if ((ivar9 > 0) && (ivar9 <= getCommonDefinitionSize(ivar3))) { + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return 3; + } + } + } + return -1; +} diff --git a/dumps/scripts/4831.cs2 b/dumps/scripts/4831.cs2 new file mode 100644 index 0000000..9fccbea --- /dev/null +++ b/dumps/scripts/4831.cs2 @@ -0,0 +1,98 @@ +void script_4831(int arg0) { + if (isWidgetHidden(new WidgetPointer(arg0))) { + return; + } + script_4834(arg0); + switch (bitconfig_9558) { + flow_3: + case 1: + switch (arg0) { + case 71566342: + case 71566424: + case 71566500: + if ((bitconfig_9567 > 0) && setWidgetRegister(new WidgetPointer(arg0), subtract(bitconfig_9567, 1))) { + setWidgetSprite(6004); + } + break; + case 71566326: + case 71566488: + case 71566410: + if ((bitconfig_9568 > 0) && setWidgetRegister(new WidgetPointer(arg0), subtract(bitconfig_9568, 1))) { + setWidgetSprite(6004); + } + break; + case 71566476: + case 71566310: + case 71566396: + if ((bitconfig_9569 > 0) && setWidgetRegister(new WidgetPointer(arg0), subtract(bitconfig_9569, 1))) { + setWidgetSprite(6004); + } + } + break; + case 2: + switch (arg0) { + case 71566342: + case 71566424: + case 71566500: + if ((bitconfig_9576 > 0) && setWidgetRegister(new WidgetPointer(arg0), subtract(bitconfig_9576, 1))) { + setWidgetSprite(6004); + } + break; + case 71566326: + case 71566488: + case 71566410: + if ((bitconfig_9577 > 0) && setWidgetRegister(new WidgetPointer(arg0), subtract(bitconfig_9577, 1))) { + setWidgetSprite(6004); + } + break; + case 71566476: + case 71566310: + case 71566396: + if ((bitconfig_9578 > 0) && setWidgetRegister(new WidgetPointer(arg0), subtract(bitconfig_9578, 1))) { + setWidgetSprite(6004); + } + } + break; + case 3: + SWITCH (arg0) { + case 71566342: + GOTO flow_30 + case 71566424: + GOTO flow_30 + case 71566500: + GOTO flow_30 + case 71566326: + GOTO flow_34 + case 71566488: + GOTO flow_34 + case 71566410: + GOTO flow_34 + case 71566476: + GOTO flow_38 + case 71566310: + GOTO flow_38 + case 71566396: + GOTO flow_38 + } + break; + flow_30: + if ((bitconfig_9585 > 0) && setWidgetRegister(new WidgetPointer(arg0), subtract(bitconfig_9585, 1))) { + setWidgetSprite(6004); + } + break; + flow_34: + if ((bitconfig_9586 > 0) && setWidgetRegister(new WidgetPointer(arg0), subtract(bitconfig_9586, 1))) { + setWidgetSprite(6004); + } + break; + flow_38: + if ((bitconfig_9587 > 0) && setWidgetRegister(new WidgetPointer(arg0), subtract(bitconfig_9587, 1))) { + setWidgetSprite(6004); + } + } + script_4838(); + script_4810(); + script_4840(); + script_4814(); + return; +} diff --git a/dumps/scripts/4832.cs2 b/dumps/scripts/4832.cs2 new file mode 100644 index 0000000..ad6e469 --- /dev/null +++ b/dumps/scripts/4832.cs2 @@ -0,0 +1,84 @@ +void script_4832(int arg0,int arg1) { + script_4834(arg0); + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + if (getWidgetSpriteId() == 6009) { + switch (bitconfig_9558) { + flow_3: + case 1: + switch (arg0) { + case 71566342: + case 71566424: + case 71566500: + bitconfig_9567 = add(1, arg1); + break; + case 71566326: + case 71566488: + case 71566410: + bitconfig_9568 = add(1, arg1); + break; + case 71566476: + case 71566310: + case 71566396: + bitconfig_9569 = add(1, arg1); + } + break; + case 2: + switch (arg0) { + case 71566342: + case 71566424: + case 71566500: + bitconfig_9576 = add(1, arg1); + break; + case 71566326: + case 71566488: + case 71566410: + bitconfig_9577 = add(1, arg1); + break; + case 71566476: + case 71566310: + case 71566396: + bitconfig_9578 = add(1, arg1); + } + break; + case 3: + SWITCH (arg0) { + case 71566342: + GOTO flow_14 + case 71566424: + GOTO flow_14 + case 71566500: + GOTO flow_14 + case 71566326: + GOTO flow_15 + case 71566488: + GOTO flow_15 + case 71566410: + GOTO flow_15 + case 71566476: + GOTO flow_16 + case 71566310: + GOTO flow_16 + case 71566396: + GOTO flow_16 + } + break; + flow_14: + bitconfig_9585 = add(1, arg1); + break; + flow_15: + bitconfig_9586 = add(1, arg1); + break; + flow_16: + bitconfig_9587 = add(1, arg1); + } + setWidgetSprite(6004); + } else { + script_4834(arg0); + } + } + script_4838(); + script_4810(); + script_4840(); + script_4814(); + return; +} diff --git a/dumps/scripts/4833.cs2 b/dumps/scripts/4833.cs2 new file mode 100644 index 0000000..ca44f00 --- /dev/null +++ b/dumps/scripts/4833.cs2 @@ -0,0 +1,37 @@ +void script_4833(int arg0) { + int ivar1; + ivar1 = -1; + switch (arg0) { + case 71566495: + ivar1 = 71566500; + break; + case 71566419: + ivar1 = 71566424; + break; + case 71566337: + ivar1 = 71566342; + break; + case 71566483: + ivar1 = 71566488; + break; + case 71566405: + ivar1 = 71566410; + break; + case 71566321: + ivar1 = 71566326; + break; + case 71566471: + ivar1 = 71566476; + break; + case 71566391: + ivar1 = 71566396; + break; + case 71566305: + ivar1 = 71566310; + } + script_4834(ivar1); + script_4838(); + script_4810(); + script_4814(); + return; +} diff --git a/dumps/scripts/4834.cs2 b/dumps/scripts/4834.cs2 new file mode 100644 index 0000000..cfdf626 --- /dev/null +++ b/dumps/scripts/4834.cs2 @@ -0,0 +1,11 @@ +void script_4834(int arg0) { + int ivar1; + ivar1 = subtract(getExtraChildGap(new WidgetPointer(arg0)), 1); + while (ivar1 >= 0) { + if (setWidgetRegister(new WidgetPointer(arg0), ivar1)) { + setWidgetSprite(6009); + } + ivar1 = subtract(ivar1, 1); + } + return; +} diff --git a/dumps/scripts/4835.cs2 b/dumps/scripts/4835.cs2 new file mode 100644 index 0000000..c8cc03e --- /dev/null +++ b/dumps/scripts/4835.cs2 @@ -0,0 +1,33 @@ +void script_4835() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + ivar0 = -1; + ivar1 = -1; + ivar2 = -1; + switch (bitconfig_9558) { + case 1: + ivar0 = script_4817(bitconfig_9563, 1); + ivar1 = script_4817(bitconfig_9563, 2); + ivar2 = script_4817(bitconfig_9563, 3); + break; + case 2: + ivar0 = script_4817(bitconfig_9572, 1); + ivar1 = script_4817(bitconfig_9572, 2); + ivar2 = script_4817(bitconfig_9572, 3); + break; + case 3: + ivar0 = script_4817(bitconfig_9581, 1); + ivar1 = script_4817(bitconfig_9581, 2); + ivar2 = script_4817(bitconfig_9581, 3); + } + ivar3 = subtract(getExtraChildGap(new WidgetPointer(ivar0)), 1); + while (ivar3 >= 0) { + if (setWidgetRegister(new WidgetPointer(ivar0), ivar3)) { + setWidgetSprite(6009); + } + ivar3 = subtract(ivar3, 1); + } + return; +} diff --git a/dumps/scripts/4836.cs2 b/dumps/scripts/4836.cs2 new file mode 100644 index 0000000..9291eec --- /dev/null +++ b/dumps/scripts/4836.cs2 @@ -0,0 +1,6 @@ +void script_4836(int arg0,int arg1,int arg2) { + setWidgetSprite(5907, new WidgetPointer(arg0)); + setWidgetSprite(5902, new WidgetPointer(arg1)); + setWidgetSprite(5912, new WidgetPointer(arg2)); + return; +} diff --git a/dumps/scripts/4837.cs2 b/dumps/scripts/4837.cs2 new file mode 100644 index 0000000..0359216 --- /dev/null +++ b/dumps/scripts/4837.cs2 @@ -0,0 +1,6 @@ +void script_4837(int arg0,int arg1,int arg2) { + setWidgetSprite(5906, new WidgetPointer(arg0)); + setWidgetSprite(5901, new WidgetPointer(arg1)); + setWidgetSprite(5911, new WidgetPointer(arg2)); + return; +} diff --git a/dumps/scripts/4838.cs2 b/dumps/scripts/4838.cs2 new file mode 100644 index 0000000..f327827 --- /dev/null +++ b/dumps/scripts/4838.cs2 @@ -0,0 +1,44 @@ +void script_4838() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + ivar0 = -1; + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + ivar4 = 1; + switch (bitconfig_9558) { + case 1: + ivar1 = bitconfig_9567; + ivar2 = bitconfig_9568; + ivar3 = bitconfig_9569; + ivar4 = bitconfig_9563; + break; + case 2: + ivar1 = bitconfig_9576; + ivar2 = bitconfig_9577; + ivar3 = bitconfig_9578; + ivar4 = bitconfig_9572; + break; + case 3: + ivar1 = bitconfig_9585; + ivar2 = bitconfig_9586; + ivar3 = bitconfig_9587; + ivar4 = bitconfig_9581; + } + ivar0 = script_4815(ivar4, 1); + if (ivar0 != -1) { + script_4839(ivar0, multiply(subtract(ivar1, 1), 27)); + } + ivar0 = script_4815(ivar4, 2); + if (ivar0 != -1) { + script_4839(ivar0, multiply(subtract(ivar2, 1), 27)); + } + ivar0 = script_4815(ivar4, 3); + if (ivar0 != -1) { + script_4839(ivar0, multiply(subtract(ivar3, 1), 27)); + } + return; +} diff --git a/dumps/scripts/4839.cs2 b/dumps/scripts/4839.cs2 new file mode 100644 index 0000000..d86d4a4 --- /dev/null +++ b/dumps/scripts/4839.cs2 @@ -0,0 +1,60 @@ +void script_4839(int arg0,int arg1) { + int ivar2; + int ivar3; + int stack_dump0; + int stack_dump1; + ivar2 = 0; + ivar3 = -1; + switch (arg0) { + case 71566492: + ivar3 = 71566495; + ivar2 = getExtraChildGap(new WidgetPointer(1092,1188)); + break; + case 71566416: + ivar3 = 71566419; + ivar2 = getExtraChildGap(new WidgetPointer(1092,1112)); + break; + case 71566334: + ivar3 = 71566337; + ivar2 = getExtraChildGap(new WidgetPointer(1092,1030)); + break; + case 71566480: + ivar3 = 71566483; + ivar2 = getExtraChildGap(new WidgetPointer(1092,1176)); + break; + case 71566402: + ivar3 = 71566405; + ivar2 = getExtraChildGap(new WidgetPointer(1092,1098)); + break; + case 71566318: + ivar3 = 71566321; + ivar2 = getExtraChildGap(new WidgetPointer(1092,1014)); + break; + case 71566468: + ivar3 = 71566471; + ivar2 = getExtraChildGap(new WidgetPointer(1092,1164)); + break; + case 71566388: + ivar3 = 71566391; + ivar2 = getExtraChildGap(new WidgetPointer(1092,1084)); + break; + case 71566302: + ivar3 = 71566305; + ivar2 = getExtraChildGap(new WidgetPointer(1092,998)); + } + if (setWidgetRegister(new WidgetPointer(arg0))) { + stack_dump0 = 0; + stack_dump1 = 1564; + /* + mgi.tools.jagdecs2.DecompilerException: opcode 1613 not decompileable + at mgi.tools.jagdecs2.FlowBlocksGenerator.analyzeSpecialCall(FlowBlocksGenerator.java:297) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:249) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return; +} diff --git a/dumps/scripts/484.cs2 b/dumps/scripts/484.cs2 new file mode 100644 index 0000000..584d42f --- /dev/null +++ b/dumps/scripts/484.cs2 @@ -0,0 +1,189 @@ +void script_484(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + string svar0; + flow_0: + ivar1 = -1; + ivar2 = -1; + ivar3 = 0; + ivar4 = 0; + ivar5 = 0; + svar0 = ""; + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(arg0)); + SWITCH (bitconfig_7512) { + case 1: + GOTO flow_1 + case 2: + GOTO flow_2 + case 3: + GOTO flow_3 + case 4: + GOTO flow_4 + case 5: + GOTO flow_5 + case 6: + GOTO flow_6 + case 7: + GOTO flow_7 + case 8: + GOTO flow_8 + case 9: + GOTO flow_9 + case 10: + GOTO flow_10 + } + return; + flow_1: + ivar1 = script_486(bitconfig_7520); + GOTO flow_11 + flow_2: + ivar1 = script_486(bitconfig_7521); + GOTO flow_11 + flow_3: + ivar1 = script_486(bitconfig_7526); + GOTO flow_11 + flow_4: + ivar1 = script_486(bitconfig_7527); + GOTO flow_11 + flow_5: + ivar1 = script_486(bitconfig_7530); + GOTO flow_11 + flow_6: + ivar1 = script_486(bitconfig_7531); + GOTO flow_11 + flow_7: + ivar1 = script_486(bitconfig_7532); + GOTO flow_11 + flow_8: + ivar1 = script_486(bitconfig_7533); + GOTO flow_11 + flow_9: + ivar1 = script_486(bitconfig_7534); + GOTO flow_11 + flow_10: + ivar1 = script_486(bitconfig_7535); + flow_11: + SWITCH (arg0) { + case 66519173: + GOTO flow_12 + case 66519159: + GOTO flow_13 + case 66519161: + GOTO flow_14 + case 66519163: + GOTO flow_15 + case 66519165: + GOTO flow_16 + case 66519167: + GOTO flow_17 + case 66519169: + GOTO flow_18 + case 66519171: + GOTO flow_19 + } + return; + flow_12: + ivar2 = script_486(0); + GOTO flow_20 + flow_13: + ivar2 = script_486(1); + GOTO flow_20 + flow_14: + ivar2 = script_486(2); + GOTO flow_20 + flow_15: + ivar2 = script_486(3); + GOTO flow_20 + flow_16: + ivar2 = script_486(4); + GOTO flow_20 + flow_17: + ivar2 = script_486(5); + GOTO flow_20 + flow_18: + ivar2 = script_486(6); + GOTO flow_20 + flow_19: + ivar2 = script_486(7); + flow_20: + if (ivar1 == -1) { + setWidgetIsHidden(true, new WidgetPointer(1015,135)); + setWidgetIsHidden(false, new WidgetPointer(1015,115)); + setWidgetSprite(getNpcNodemapData(ivar2, 1148), new WidgetPointer(1015,2)); + setWidgetText(new WidgetPointer(1015,0), getNpcNodemapData(ivar2, 1139)); + setWidgetText(new WidgetPointer(1015,138), "Movement: " + intToStr(getNpcNodemapData(ivar2, 1134))); + setWidgetText(new WidgetPointer(1015,139), "Damage: " + intToStr(multiply(getNpcNodemapData(ivar2, 1135), 100))); + setWidgetText(new WidgetPointer(1015,140), "Health: " + intToStr(multiply(getNpcNodemapData(ivar2, 1136), 100))); + setWidgetText(new WidgetPointer(1015,141), "Range: " + intToStr(getNpcNodemapData(ivar2, 1137))); + setWidgetText(new WidgetPointer(1015,142), "Cost: " + intToStr(getNpcNodemapData(ivar2, 1138))); + } else { + if (ivar1 != ivar2) { + setWidgetSprite(getNpcNodemapData(ivar2, 1148), new WidgetPointer(1015,2)); + setWidgetText(new WidgetPointer(1015,0), concat(getWidgetText(new WidgetPointer(1015,0)), " ~ " + getNpcNodemapData(ivar2, 1139))); + ivar3 = getNpcNodemapData(ivar1, 1134); + ivar4 = getNpcNodemapData(ivar2, 1134); + if (ivar3 < ivar4) { + ivar5 = subtract(ivar4, ivar3); + svar0 = " ~ " + intToStr(getNpcNodemapData(ivar2, 1134)) + " (" + "" + "+" + intToStr(ivar5) + "" + ")"; + } else if (ivar3 > ivar4) { + ivar5 = subtract(ivar3, ivar4); + svar0 = " ~ " + intToStr(getNpcNodemapData(ivar2, 1134)) + " (" + "" + "-" + intToStr(ivar5) + "" + ")"; + } else { + svar0 = " ~ " + intToStr(getNpcNodemapData(ivar2, 1134)); + } + setWidgetText(new WidgetPointer(1015,138), concat(getWidgetText(new WidgetPointer(1015,138)), svar0)); + ivar3 = getNpcNodemapData(ivar1, 1135); + ivar4 = getNpcNodemapData(ivar2, 1135); + if (ivar3 < ivar4) { + ivar5 = subtract(ivar4, ivar3); + svar0 = " ~ " + intToStr(multiply(getNpcNodemapData(ivar2, 1135), 100)) + " (" + "" + "+" + intToStr(multiply(ivar5, 100)) + "" + ")"; + } else if (ivar3 > ivar4) { + ivar5 = subtract(ivar3, ivar4); + svar0 = " ~ " + intToStr(multiply(getNpcNodemapData(ivar2, 1135), 100)) + " (" + "" + "-" + intToStr(multiply(ivar5, 100)) + "" + ")"; + } else { + svar0 = " ~ " + intToStr(multiply(getNpcNodemapData(ivar2, 1135), 100)); + } + setWidgetText(new WidgetPointer(1015,139), concat(getWidgetText(new WidgetPointer(1015,139)), svar0)); + ivar3 = getNpcNodemapData(ivar1, 1136); + ivar4 = getNpcNodemapData(ivar2, 1136); + if (ivar3 < ivar4) { + ivar5 = subtract(ivar4, ivar3); + svar0 = " ~ " + intToStr(multiply(getNpcNodemapData(ivar2, 1136), 100)) + " (" + "" + "+" + intToStr(multiply(ivar5, 100)) + "" + ")"; + } else if (ivar3 > ivar4) { + ivar5 = subtract(ivar3, ivar4); + svar0 = " ~ " + intToStr(multiply(getNpcNodemapData(ivar2, 1136), 100)) + " (" + "" + "-" + intToStr(multiply(ivar5, 100)) + "" + ")"; + } else { + svar0 = " ~ " + intToStr(multiply(getNpcNodemapData(ivar2, 1136), 100)); + } + setWidgetText(new WidgetPointer(1015,140), concat(getWidgetText(new WidgetPointer(1015,140)), svar0)); + ivar3 = getNpcNodemapData(ivar1, 1137); + ivar4 = getNpcNodemapData(ivar2, 1137); + if (ivar3 < ivar4) { + ivar5 = subtract(ivar4, ivar3); + svar0 = " ~ " + intToStr(getNpcNodemapData(ivar2, 1137)) + " (" + "" + "+" + intToStr(ivar5) + "" + ")"; + } else if (ivar3 > ivar4) { + ivar5 = subtract(ivar3, ivar4); + svar0 = " ~ " + intToStr(getNpcNodemapData(ivar2, 1137)) + " (" + "" + "-" + intToStr(ivar5) + "" + ")"; + } else { + svar0 = " ~ " + intToStr(getNpcNodemapData(ivar2, 1137)); + } + setWidgetText(new WidgetPointer(1015,141), concat(getWidgetText(new WidgetPointer(1015,141)), svar0)); + ivar3 = getNpcNodemapData(ivar1, 1138); + ivar4 = getNpcNodemapData(ivar2, 1138); + if (ivar3 < ivar4) { + ivar5 = subtract(ivar4, ivar3); + svar0 = " ~ " + intToStr(getNpcNodemapData(ivar2, 1138)) + " (" + "" + "+" + intToStr(ivar5) + "" + ")"; + } else if (ivar3 > ivar4) { + ivar5 = subtract(ivar3, ivar4); + svar0 = " ~ " + intToStr(getNpcNodemapData(ivar2, 1138)) + " (" + "" + "-" + intToStr(ivar5) + "" + ")"; + } else { + svar0 = " ~ " + intToStr(getNpcNodemapData(ivar2, 1138)); + } + setWidgetText(new WidgetPointer(1015,142), concat(getWidgetText(new WidgetPointer(1015,142)), svar0)); + } + } + return; +} diff --git a/dumps/scripts/4840.cs2 b/dumps/scripts/4840.cs2 new file mode 100644 index 0000000..9ddcd97 --- /dev/null +++ b/dumps/scripts/4840.cs2 @@ -0,0 +1,104 @@ +void script_4840() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int stack_dump0; + cs2func_script_4841_struct(6,0,0) structdump_1; + ivar0 = 0; + switch (bitconfig_9558) { + case 1: + ivar0 = bitconfig_9563; + break; + case 2: + ivar0 = bitconfig_9572; + break; + case 3: + ivar0 = bitconfig_9581; + } + if (((boolean)ivar0)) { + return; + } + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + ivar4 = 0; + ivar5 = 0; + ivar6 = 0; + ivar7 = -1; + ivar8 = -1; + ivar9 = -1; + stack_dump0 = bitconfig_9558; + structdump_1 = script_4841(stack_dump0); + ivar6 = structdump_1.intpart_5; + ivar5 = structdump_1.intpart_4; + ivar4 = structdump_1.intpart_3; + ivar3 = structdump_1.intpart_2; + ivar2 = structdump_1.intpart_1; + ivar1 = structdump_1.intpart_0; + ivar10 = cs2method_3408(105, 100, 4286, ivar1); + ivar11 = cs2method_3408(105, 100, 4286, ivar3); + ivar12 = cs2method_3408(105, 100, 4286, ivar5); + switch (ivar0) { + case 1: + if (ivar2 > 0) { + setWidgetText(new WidgetPointer(1092,47), intToStr(ivar2)); + } else { + setWidgetText(new WidgetPointer(1092,47), ""); + } + ivar7 = 71565356; + ivar8 = 71565357; + ivar9 = 71565358; + break; + case 2: + if (ivar2 > 0) { + setWidgetText(new WidgetPointer(1092,56), intToStr(ivar2)); + } else { + setWidgetText(new WidgetPointer(1092,56), ""); + } + if (ivar4 > 0) { + setWidgetText(new WidgetPointer(1092,57), intToStr(ivar4)); + } else { + setWidgetText(new WidgetPointer(1092,57), ""); + } + ivar7 = 71565365; + ivar8 = 71565366; + ivar9 = 71565367; + break; + case 3: + if (ivar2 > 0) { + setWidgetText(new WidgetPointer(1092,65), intToStr(ivar2)); + } else { + setWidgetText(new WidgetPointer(1092,65), ""); + } + if (ivar4 > 0) { + setWidgetText(new WidgetPointer(1092,67), intToStr(ivar4)); + } else { + setWidgetText(new WidgetPointer(1092,67), ""); + } + if (ivar6 > 0) { + setWidgetText(new WidgetPointer(1092,66), intToStr(ivar6)); + } else { + setWidgetText(new WidgetPointer(1092,66), ""); + } + ivar7 = 71565374; + ivar8 = 71565375; + ivar9 = 71565376; + break; + default: + return; + } + setWidgetSprite(ivar10, new WidgetPointer(ivar7)); + setWidgetSprite(ivar11, new WidgetPointer(ivar8)); + setWidgetSprite(ivar12, new WidgetPointer(ivar9)); + return; +} diff --git a/dumps/scripts/4841.cs2 b/dumps/scripts/4841.cs2 new file mode 100644 index 0000000..8a362a3 --- /dev/null +++ b/dumps/scripts/4841.cs2 @@ -0,0 +1,99 @@ +cs2func_script_4841_struct(6,0,0) script_4841(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + ivar4 = 0; + ivar5 = 0; + ivar6 = 0; + if (citadelConfigsInitialized()) { + switch (arg0) { + case 1: + ivar3 = bitconfig_9570; + ivar1 = bitconfig_9562; + ivar2 = bitconfig_9563; + ivar4 = bitconfig_9567; + ivar5 = bitconfig_9568; + ivar6 = bitconfig_9569; + break; + case 2: + ivar3 = bitconfig_9579; + ivar1 = bitconfig_9571; + ivar2 = bitconfig_9572; + ivar4 = bitconfig_9576; + ivar5 = bitconfig_9577; + ivar6 = bitconfig_9578; + break; + case 3: + ivar3 = bitconfig_9588; + ivar1 = bitconfig_9580; + ivar2 = bitconfig_9581; + ivar4 = bitconfig_9585; + ivar5 = bitconfig_9586; + ivar6 = bitconfig_9587; + } + } + ivar7 = 1; + ivar8 = 1; + ivar9 = -1; + ivar10 = -1; + ivar11 = -1; + ivar12 = -1; + ivar13 = 0; + ivar14 = 0; + ivar15 = 0; + ivar16 = 0; + ivar17 = 0; + ivar18 = 0; + ivar11 = cs2method_3408(105, 103, 4043, ivar1); + if (ivar11 == -1) { + return newstruct cs2func_script_4841_struct(0, 0, 0, 0, 0, 0); + } + ivar12 = cs2method_3408(105, 103, ivar11, ivar2); + if (ivar12 == -1) { + return newstruct cs2func_script_4841_struct(0, 0, 0, 0, 0, 0); + } + while (ivar7 <= 3) { + ivar9 = cs2method_3408(105, 103, ivar12, ivar7); + if (ivar9 != -1) { + switch (ivar7) { + case 1: + ivar10 = cs2method_3408(105, 74, ivar9, ivar4); + break; + case 2: + ivar10 = cs2method_3408(105, 74, ivar9, ivar5); + break; + case 3: + ivar10 = cs2method_3408(105, 74, ivar9, ivar6); + } + if (ivar10 != -1) { + ivar13 = getOtherCommonData(ivar10, 1571); + ivar16 = add(ivar16, getOtherCommonData(ivar10, 1573)); + ivar14 = getOtherCommonData(ivar10, 1575); + ivar17 = add(ivar17, getOtherCommonData(ivar10, 1577)); + ivar15 = getOtherCommonData(ivar10, 1579); + ivar18 = add(ivar18, getOtherCommonData(ivar10, 1581)); + } + } + ivar9 = -1; + ivar7 = add(ivar7, 1); + } + return newstruct cs2func_script_4841_struct(ivar13, ivar16, ivar14, ivar17, ivar15, ivar18); +} diff --git a/dumps/scripts/4842.cs2 b/dumps/scripts/4842.cs2 new file mode 100644 index 0000000..724d04d --- /dev/null +++ b/dumps/scripts/4842.cs2 @@ -0,0 +1,13 @@ +void script_4842(int arg0) { + switch (arg0) { + case 1: + setWidgetIsHidden(false, new WidgetPointer(1092,1253)); + break; + case 2: + setWidgetIsHidden(false, new WidgetPointer(1092,1244)); + break; + case 3: + setWidgetIsHidden(false, new WidgetPointer(1092,1235)); + } + return; +} diff --git a/dumps/scripts/4843.cs2 b/dumps/scripts/4843.cs2 new file mode 100644 index 0000000..f2888c0 --- /dev/null +++ b/dumps/scripts/4843.cs2 @@ -0,0 +1,13 @@ +void script_4843(int arg0) { + switch (arg0) { + case 1: + setWidgetIsHidden(true, new WidgetPointer(1092,1253)); + break; + case 2: + setWidgetIsHidden(true, new WidgetPointer(1092,1244)); + break; + case 3: + setWidgetIsHidden(true, new WidgetPointer(1092,1235)); + } + return; +} diff --git a/dumps/scripts/4844.cs2 b/dumps/scripts/4844.cs2 new file mode 100644 index 0000000..9ef9cd2 --- /dev/null +++ b/dumps/scripts/4844.cs2 @@ -0,0 +1,19 @@ +void script_4844(int arg0) { + switch (bitconfig_9558) { + case 1: + if (arg0 == bitconfig_9563) { + script_4846(arg0); + } + break; + case 2: + if (arg0 == bitconfig_9572) { + script_4846(arg0); + } + break; + case 3: + if (arg0 == bitconfig_9581) { + script_4846(arg0); + } + } + return; +} diff --git a/dumps/scripts/4845.cs2 b/dumps/scripts/4845.cs2 new file mode 100644 index 0000000..d84cf59 --- /dev/null +++ b/dumps/scripts/4845.cs2 @@ -0,0 +1,17 @@ +void script_4845(int arg0) { + if (((boolean)script_4828(bitconfig_9558))) { + return; + } + switch (bitconfig_9558) { + case 1: + bitconfig_9563 = arg0; + break; + case 2: + bitconfig_9572 = arg0; + break; + case 3: + bitconfig_9581 = arg0; + } + script_4846(arg0); + return; +} diff --git a/dumps/scripts/4846.cs2 b/dumps/scripts/4846.cs2 new file mode 100644 index 0000000..9fb92eb --- /dev/null +++ b/dumps/scripts/4846.cs2 @@ -0,0 +1,29 @@ +void script_4846(int arg0) { + setWidgetIsHidden(true, new WidgetPointer(1092,1249)); + setWidgetIsHidden(true, new WidgetPointer(1092,1240)); + setWidgetIsHidden(true, new WidgetPointer(1092,1231)); + setWidgetIsHidden(true, new WidgetPointer(1092,1152)); + setWidgetIsHidden(true, new WidgetPointer(1092,1072)); + setWidgetIsHidden(true, new WidgetPointer(1092,986)); + switch (arg0) { + case 1: + setWidgetIsHidden(false, new WidgetPointer(1092,1249)); + setWidgetIsHidden(false, new WidgetPointer(1092,1152)); + setWidgetSprite(7287, new WidgetPointer(1092,1265)); + break; + case 2: + setWidgetIsHidden(false, new WidgetPointer(1092,1240)); + setWidgetIsHidden(false, new WidgetPointer(1092,1072)); + setWidgetSprite(7288, new WidgetPointer(1092,1265)); + break; + case 3: + setWidgetIsHidden(false, new WidgetPointer(1092,1231)); + setWidgetIsHidden(false, new WidgetPointer(1092,986)); + setWidgetSprite(7289, new WidgetPointer(1092,1265)); + } + script_4838(); + script_4810(); + script_4840(); + script_4814(); + return; +} diff --git a/dumps/scripts/4847.cs2 b/dumps/scripts/4847.cs2 new file mode 100644 index 0000000..dad543e --- /dev/null +++ b/dumps/scripts/4847.cs2 @@ -0,0 +1,5 @@ +void script_4847(int arg0) { + bitconfig_9558 = arg0; + script_4849(); + return; +} diff --git a/dumps/scripts/4848.cs2 b/dumps/scripts/4848.cs2 new file mode 100644 index 0000000..dc84a89 --- /dev/null +++ b/dumps/scripts/4848.cs2 @@ -0,0 +1,6 @@ +void script_4848(int arg0) { + if (arg0 == bitconfig_9558) { + script_4849(); + } + return; +} diff --git a/dumps/scripts/4849.cs2 b/dumps/scripts/4849.cs2 new file mode 100644 index 0000000..0cdebd2 --- /dev/null +++ b/dumps/scripts/4849.cs2 @@ -0,0 +1,51 @@ +void script_4849() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + ivar0 = 71566248; + ivar1 = 71566247; + ivar2 = 71566260; + ivar3 = 71566261; + ivar4 = 71566249; + ivar5 = 71566250; + setWidgetIsHidden(true, new WidgetPointer(1092,973)); + setWidgetIsHidden(true, new WidgetPointer(1092,964)); + setWidgetIsHidden(true, new WidgetPointer(1092,955)); + switch (bitconfig_9558) { + case 1: + setWidgetIsHidden(false, new WidgetPointer(1092,973)); + if (((boolean)bitconfig_9570)) { + script_4940(); + script_4850(ivar0, ivar1, ivar2, ivar3, ivar4, ivar5); + } else { + script_4942(); + script_4851(ivar0, ivar1, ivar2, ivar3, ivar4, ivar5); + } + break; + case 2: + setWidgetIsHidden(false, new WidgetPointer(1092,964)); + if (((boolean)bitconfig_9579)) { + script_4940(); + script_4850(ivar0, ivar1, ivar2, ivar3, ivar4, ivar5); + } else { + script_4942(); + script_4851(ivar0, ivar1, ivar2, ivar3, ivar4, ivar5); + } + break; + case 3: + setWidgetIsHidden(false, new WidgetPointer(1092,955)); + if (((boolean)bitconfig_9588)) { + script_4940(); + script_4850(ivar0, ivar1, ivar2, ivar3, ivar4, ivar5); + } else { + script_4942(); + script_4851(ivar0, ivar1, ivar2, ivar3, ivar4, ivar5); + } + } + script_4804(); + script_4852(); + return; +} diff --git a/dumps/scripts/485.cs2 b/dumps/scripts/485.cs2 new file mode 100644 index 0000000..4b953b0 --- /dev/null +++ b/dumps/scripts/485.cs2 @@ -0,0 +1,74 @@ +void script_485(int arg0) { + int ivar1; + int ivar2; + flow_0: + ivar1 = -1; + ivar2 = 0; + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(arg0)); + SWITCH (bitconfig_7512) { + case 1: + GOTO flow_1 + case 2: + GOTO flow_2 + case 3: + GOTO flow_3 + case 4: + GOTO flow_4 + case 5: + GOTO flow_5 + case 6: + GOTO flow_6 + case 7: + GOTO flow_7 + case 8: + GOTO flow_8 + case 9: + GOTO flow_9 + case 10: + GOTO flow_10 + } + return; + flow_1: + ivar1 = script_486(bitconfig_7520); + GOTO flow_11 + flow_2: + ivar1 = script_486(bitconfig_7521); + GOTO flow_11 + flow_3: + ivar1 = script_486(bitconfig_7526); + GOTO flow_11 + flow_4: + ivar1 = script_486(bitconfig_7527); + GOTO flow_11 + flow_5: + ivar1 = script_486(bitconfig_7530); + GOTO flow_11 + flow_6: + ivar1 = script_486(bitconfig_7531); + GOTO flow_11 + flow_7: + ivar1 = script_486(bitconfig_7532); + GOTO flow_11 + flow_8: + ivar1 = script_486(bitconfig_7533); + GOTO flow_11 + flow_9: + ivar1 = script_486(bitconfig_7534); + GOTO flow_11 + flow_10: + ivar1 = script_486(bitconfig_7535); + flow_11: + if (ivar1 == -1) { + setWidgetIsHidden(false, new WidgetPointer(1015,135)); + setWidgetIsHidden(true, new WidgetPointer(1015,115)); + } else { + setWidgetSprite(getNpcNodemapData(ivar1, 1148), new WidgetPointer(1015,2)); + setWidgetText(new WidgetPointer(1015,0), getNpcNodemapData(ivar1, 1139)); + setWidgetText(new WidgetPointer(1015,138), "Movement: " + intToStr(getNpcNodemapData(ivar1, 1134))); + setWidgetText(new WidgetPointer(1015,139), "Damage: " + intToStr(multiply(getNpcNodemapData(ivar1, 1135), 100))); + setWidgetText(new WidgetPointer(1015,140), "Health: " + intToStr(multiply(getNpcNodemapData(ivar1, 1136), 100))); + setWidgetText(new WidgetPointer(1015,141), "Range: " + intToStr(getNpcNodemapData(ivar1, 1137))); + setWidgetText(new WidgetPointer(1015,142), "Cost: " + intToStr(getNpcNodemapData(ivar1, 1138))); + } + return; +} diff --git a/dumps/scripts/4850.cs2 b/dumps/scripts/4850.cs2 new file mode 100644 index 0000000..9b18544 --- /dev/null +++ b/dumps/scripts/4850.cs2 @@ -0,0 +1,17 @@ +void script_4850(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + deleteAllExtraChilds(new WidgetPointer(arg2)); + deleteAllExtraChilds(new WidgetPointer(arg3)); + deleteAllExtraChilds(new WidgetPointer(arg4)); + setWidgetIsHidden(true, new WidgetPointer(arg5)); + cs2method2100(0, 0, new WidgetPointer(arg0)); + setWidgetScrollMax(0, 0, new WidgetPointer(arg0)); + script_31(arg1, arg0, 5666, 5663, 5664, 5665, 5686, 5685); + createExtraChild(new WidgetPointer(arg2), 4, 0); + setWidgetSize(10, 10, 1, 1); + setWidgetPosition(0, 0, 1, 1); + setWidgetText("Please select a hotspot to customise from the map on the right."); + setWidgetRGB(new Color(229, 225, 187)); + setWidgetFont(495); + setWidgetTextAlignment(1, 1, 0); + return; +} diff --git a/dumps/scripts/4851.cs2 b/dumps/scripts/4851.cs2 new file mode 100644 index 0000000..e385cf2 --- /dev/null +++ b/dumps/scripts/4851.cs2 @@ -0,0 +1,124 @@ +void script_4851(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + setWidgetIsHidden(true, new WidgetPointer(1092,938)); + deleteAllExtraChilds(new WidgetPointer(arg2)); + deleteAllExtraChilds(new WidgetPointer(arg3)); + deleteAllExtraChilds(new WidgetPointer(arg4)); + ivar6 = 0; + ivar7 = 0; + ivar8 = 1; + ivar9 = 0; + ivar10 = 28; + ivar11 = -1; + ivar12 = -1; + ivar13 = -1; + ivar14 = 0; + ivar15 = 0; + switch (bitconfig_9558) { + case 1: + ivar14 = bitconfig_9562; + ivar15 = bitconfig_9566; + break; + case 2: + ivar14 = bitconfig_9571; + ivar15 = bitconfig_9575; + break; + case 3: + ivar14 = bitconfig_9580; + ivar15 = bitconfig_9584; + } + createExtraChild(new WidgetPointer(arg4), 3, 0); + setWidgetHidden(1); + createExtraChild(new WidgetPointer(arg2), 4, 0); + setWidgetHidden(1); + createExtraChild(new WidgetPointer(arg3), 5, 0); + setWidgetHidden(1); + if (((boolean)ivar15)) { + ivar11 = script_4819(bitconfig_9558); + ivar12 = script_4822(bitconfig_9558); + ivar13 = script_4825(bitconfig_9558); + if (((ivar11 == -1) || (ivar12 == -1)) || (ivar13 == -1)) { + return; + } + ivar6 = min(min(getCommonDefinitionSize(ivar11), getCommonDefinitionSize(ivar13)), getCommonDefinitionSize(ivar12)); + while (ivar8 <= ivar6) { + ivar7 = cs2method_3408(105, 105, ivar11, ivar8); + createExtraChild(new WidgetPointer(arg4), 3, ivar8); + setWidgetSize(0, ivar10, 1, 0); + setWidgetFilled(1); + if (((boolean)mod(ivar8, 2))) { + setWidgetRGB(new Color(32, 31, 26)); + setScriptCallOnMouseExit(1356, new WidgetPointer(-32768,3), -2147483643, 2105114, "Iii"); + } else { + setWidgetRGB(new Color(26, 23, 18)); + setScriptCallOnMouseExit(1356, new WidgetPointer(-32768,3), -2147483643, 1709842, "Iii"); + } + setWidgetPosition(0, ivar9, 0, 0); + if (((boolean)script_4828(bitconfig_9558))) { + setScriptCallOnClickContextMenu(4803, ivar8, "i"); + setWidgetContextMenuOption(1, "Select"); + setScriptCallOnMouseEntered(1356, new WidgetPointer(-32768,3), -2147483643, 4537648, "Iii"); + } + if (ivar14 == ivar7) { + setWidgetIsHidden(false, new WidgetPointer(1092,938)); + setWidgetPosition(0, ivar9, 0, 0, new WidgetPointer(1092,938)); + } + createExtraChild(new WidgetPointer(arg2), 4, ivar8); + setWidgetSize(30, ivar10, 1, 0); + setWidgetPosition(30, ivar9, 0, 0); + setWidgetText(cs2method_3408(105, 115, ivar12, ivar7)); + setWidgetRGB(new Color(229, 225, 187)); + setWidgetFont(494); + setWidgetTextAlignment(0, 1, 0); + createExtraChild(new WidgetPointer(arg3), 5, ivar8); + setWidgetSize(22, 22, 0, 0); + setWidgetPosition(5, add(4, ivar9), 0, 0); + setWidgetSprite(cs2method_3408(105, 100, ivar13, ivar7)); + ivar9 = multiply(ivar10, ivar8); + ivar8 = add(ivar8, 1); + } + } else { + createExtraChild(new WidgetPointer(arg4), 3, ivar8); + setWidgetSize(0, ivar10, 1, 0); + setWidgetFilled(1); + if (((boolean)mod(ivar8, 2))) { + setWidgetRGB(new Color(32, 31, 26)); + setScriptCallOnMouseExit(1356, new WidgetPointer(-32768,3), -2147483643, 2105114, "Iii"); + } else { + setWidgetRGB(new Color(26, 23, 18)); + setScriptCallOnMouseExit(1356, new WidgetPointer(-32768,3), -2147483643, 1709842, "Iii"); + } + setWidgetPosition(0, ivar9, 0, 0); + setScriptCallOnClickContextMenu(4803, ivar8, "i"); + setWidgetContextMenuOption(1, "Select"); + setScriptCallOnMouseEntered(1356, new WidgetPointer(-32768,3), -2147483643, 4537648, "Iii"); + setWidgetIsHidden(false, new WidgetPointer(1092,938)); + setWidgetPosition(0, ivar9, 0, 0, new WidgetPointer(1092,938)); + createExtraChild(new WidgetPointer(arg2), 4, ivar8); + setWidgetSize(30, ivar10, 1, 0); + setWidgetPosition(30, ivar9, 0, 0); + setWidgetText("Reset hotspot"); + setWidgetRGB(new Color(229, 225, 187)); + setWidgetFont(494); + setWidgetTextAlignment(0, 1, 0); + createExtraChild(new WidgetPointer(arg3), 5, ivar8); + setWidgetSize(22, 22, 0, 0); + setWidgetPosition(5, add(4, ivar9), 0, 0); + setWidgetSprite(6496); + cs2method1106(49149); + ivar9 = multiply(ivar10, ivar8); + } + cs2method2100(0, 0, new WidgetPointer(arg0)); + setWidgetScrollMax(0, ivar9, new WidgetPointer(arg0)); + script_31(arg1, arg0, 5666, 5663, 5664, 5665, 5686, 5685); + return; +} diff --git a/dumps/scripts/4852.cs2 b/dumps/scripts/4852.cs2 new file mode 100644 index 0000000..1d67ba3 --- /dev/null +++ b/dumps/scripts/4852.cs2 @@ -0,0 +1,35 @@ +void script_4852() { + int ivar0; + string svar0; + int stack_dump0; + ivar0 = -1; + svar0 = "This build slot is available, select your options and click the buy button."; + if (citadelConfigsInitialized()) { + ivar0 = script_4825(1); + cs2method2106(0, new WidgetPointer(1092,976)); + cs2method2106(0, new WidgetPointer(1092,967)); + cs2method2106(0, new WidgetPointer(1092,958)); + if (bitconfig_9562 > 0) { + stack_dump0 = bitconfig_9562; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return; +} diff --git a/dumps/scripts/4853.cs2 b/dumps/scripts/4853.cs2 new file mode 100644 index 0000000..da72d6d --- /dev/null +++ b/dumps/scripts/4853.cs2 @@ -0,0 +1,29 @@ +void script_4853() { + script_4863(); + switch (bitconfig_9552) { + case 0: + setWidgetIsHidden(true, new WidgetPointer(1092,197)); + if (isWidgetHidden(new WidgetPointer(1092,210))) { + setWidgetIsHidden(false, new WidgetPointer(1092,197)); + } + break; + case 1: + script_4860(); + script_4862(); + break; + case 2: + script_4860(); + break; + case 4: + script_4860(); + script_4861(); + break; + case 3: + script_5170(); + script_4860(); + script_4858(); + } + script_4856(); + script_4857(); + return; +} diff --git a/dumps/scripts/4854.cs2 b/dumps/scripts/4854.cs2 new file mode 100644 index 0000000..2ec42f8 --- /dev/null +++ b/dumps/scripts/4854.cs2 @@ -0,0 +1,22 @@ +void script_4854() { + setWidgetIsHidden(false, new WidgetPointer(1092,0)); + setWidgetIsHidden(false, new WidgetPointer(1092,1)); + setWidgetIsHidden(false, new WidgetPointer(1092,2)); + setWidgetIsHidden(false, new WidgetPointer(1092,3)); + setWidgetIsHidden(false, new WidgetPointer(1092,4)); + setWidgetIsHidden(false, new WidgetPointer(1092,5)); + setWidgetIsHidden(false, new WidgetPointer(1092,6)); + setWidgetIsHidden(false, new WidgetPointer(1092,7)); + setWidgetIsHidden(false, new WidgetPointer(1092,8)); + setWidgetIsHidden(false, new WidgetPointer(1092,10)); + setWidgetIsHidden(false, new WidgetPointer(1092,11)); + setWidgetIsHidden(false, new WidgetPointer(1092,12)); + setWidgetIsHidden(false, new WidgetPointer(1092,12)); + setWidgetIsHidden(false, new WidgetPointer(1092,13)); + setWidgetIsHidden(false, new WidgetPointer(1092,14)); + setWidgetIsHidden(false, new WidgetPointer(1092,15)); + setWidgetIsHidden(false, new WidgetPointer(1092,16)); + setWidgetIsHidden(false, new WidgetPointer(1092,17)); + setWidgetIsHidden(false, new WidgetPointer(1092,18)); + return; +} diff --git a/dumps/scripts/4855.cs2 b/dumps/scripts/4855.cs2 new file mode 100644 index 0000000..acea978 --- /dev/null +++ b/dumps/scripts/4855.cs2 @@ -0,0 +1,22 @@ +void script_4855() { + setWidgetIsHidden(true, new WidgetPointer(1092,0)); + setWidgetIsHidden(true, new WidgetPointer(1092,1)); + setWidgetIsHidden(true, new WidgetPointer(1092,2)); + setWidgetIsHidden(true, new WidgetPointer(1092,3)); + setWidgetIsHidden(true, new WidgetPointer(1092,4)); + setWidgetIsHidden(true, new WidgetPointer(1092,5)); + setWidgetIsHidden(true, new WidgetPointer(1092,6)); + setWidgetIsHidden(true, new WidgetPointer(1092,7)); + setWidgetIsHidden(true, new WidgetPointer(1092,8)); + setWidgetIsHidden(true, new WidgetPointer(1092,10)); + setWidgetIsHidden(true, new WidgetPointer(1092,11)); + setWidgetIsHidden(true, new WidgetPointer(1092,12)); + setWidgetIsHidden(true, new WidgetPointer(1092,12)); + setWidgetIsHidden(true, new WidgetPointer(1092,13)); + setWidgetIsHidden(true, new WidgetPointer(1092,14)); + setWidgetIsHidden(true, new WidgetPointer(1092,15)); + setWidgetIsHidden(true, new WidgetPointer(1092,16)); + setWidgetIsHidden(true, new WidgetPointer(1092,17)); + setWidgetIsHidden(true, new WidgetPointer(1092,18)); + return; +} diff --git a/dumps/scripts/4856.cs2 b/dumps/scripts/4856.cs2 new file mode 100644 index 0000000..1abce2d --- /dev/null +++ b/dumps/scripts/4856.cs2 @@ -0,0 +1,14 @@ +void script_4856() { + if (citadelConfigsInitialized()) { + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return; +} diff --git a/dumps/scripts/4857.cs2 b/dumps/scripts/4857.cs2 new file mode 100644 index 0000000..13a6ee1 --- /dev/null +++ b/dumps/scripts/4857.cs2 @@ -0,0 +1,15 @@ +void script_4857() { + if (citadelConfigsInitialized()) { + script_4854(); + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return; +} diff --git a/dumps/scripts/4858.cs2 b/dumps/scripts/4858.cs2 new file mode 100644 index 0000000..5f885a4 --- /dev/null +++ b/dumps/scripts/4858.cs2 @@ -0,0 +1,24 @@ +void script_4858() { + int ivar0; + ivar0 = 0; + if (citadelConfigsInitialized()) { + setWidgetIsHidden(true, new WidgetPointer(1092,213)); + setWidgetIsHidden(true, new WidgetPointer(1092,214)); + setWidgetIsHidden(true, new WidgetPointer(1092,215)); + ivar0 = script_4948(bitconfig_9550); + if (ivar0 <= 0) { + return; + } + setWidgetIsHidden(true, new WidgetPointer(script_4968(ivar0))); + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return; +} diff --git a/dumps/scripts/4859.cs2 b/dumps/scripts/4859.cs2 new file mode 100644 index 0000000..5b62428 --- /dev/null +++ b/dumps/scripts/4859.cs2 @@ -0,0 +1,17 @@ +void script_4859() { + int ivar0; + ivar0 = -1; + if (citadelConfigsInitialized()) { + script_4855(); + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return; +} diff --git a/dumps/scripts/486.cs2 b/dumps/scripts/486.cs2 new file mode 100644 index 0000000..2a221c7 --- /dev/null +++ b/dumps/scripts/486.cs2 @@ -0,0 +1,55 @@ +int script_486(int arg0) { + flow_0: + SWITCH (arg0) { + case 1: + GOTO flow_1 + case 2: + GOTO flow_5 + case 3: + GOTO flow_9 + case 4: + GOTO flow_13 + case 5: + GOTO flow_17 + case 6: + GOTO flow_21 + case 7: + GOTO flow_25 + } + return -1; + flow_1: + if (((boolean)bitconfig_7510)) { + return 12200; + } + return 12197; + flow_5: + if (((boolean)bitconfig_7510)) { + return 12205; + } + return 12202; + flow_9: + if (((boolean)bitconfig_7510)) { + return 12210; + } + return 12207; + flow_13: + if (((boolean)bitconfig_7510)) { + return 12215; + } + return 12212; + flow_17: + if (((boolean)bitconfig_7510)) { + return 12219; + } + return 12216; + flow_21: + if (((boolean)bitconfig_7510)) { + return 12223; + } + return 12220; + flow_25: + if (((boolean)bitconfig_7510)) { + return 12227; + } + return 12224; +} diff --git a/dumps/scripts/4860.cs2 b/dumps/scripts/4860.cs2 new file mode 100644 index 0000000..295a4f2 --- /dev/null +++ b/dumps/scripts/4860.cs2 @@ -0,0 +1,37 @@ +void script_4860() { + setWidgetIsHidden(true, new WidgetPointer(1092,1371)); + setWidgetIsHidden(true, new WidgetPointer(1092,1364)); + setWidgetIsHidden(true, new WidgetPointer(1092,1357)); + setWidgetIsHidden(true, new WidgetPointer(1092,1273)); + setWidgetIsHidden(true, new WidgetPointer(1092,1280)); + setWidgetIsHidden(true, new WidgetPointer(1092,1287)); + setWidgetIsHidden(true, new WidgetPointer(1092,1294)); + setWidgetIsHidden(true, new WidgetPointer(1092,1301)); + setWidgetIsHidden(true, new WidgetPointer(1092,1308)); + setWidgetIsHidden(true, new WidgetPointer(1092,1315)); + setWidgetIsHidden(true, new WidgetPointer(1092,1322)); + setWidgetIsHidden(true, new WidgetPointer(1092,1329)); + setWidgetIsHidden(true, new WidgetPointer(1092,1336)); + setWidgetIsHidden(true, new WidgetPointer(1092,1343)); + setWidgetIsHidden(true, new WidgetPointer(1092,1350)); + setWidgetIsHidden(true, new WidgetPointer(1092,1378)); + setWidgetIsHidden(true, new WidgetPointer(1092,1384)); + setWidgetIsHidden(true, new WidgetPointer(1092,1390)); + setWidgetIsHidden(true, new WidgetPointer(1092,1396)); + setWidgetIsHidden(true, new WidgetPointer(1092,1402)); + setWidgetIsHidden(true, new WidgetPointer(1092,1408)); + setWidgetIsHidden(true, new WidgetPointer(1092,1415)); + setWidgetIsHidden(true, new WidgetPointer(1092,1421)); + setWidgetIsHidden(true, new WidgetPointer(1092,1427)); + setWidgetIsHidden(true, new WidgetPointer(1092,1433)); + setWidgetIsHidden(true, new WidgetPointer(1092,1439)); + setWidgetIsHidden(true, new WidgetPointer(1092,1445)); + setWidgetIsHidden(true, new WidgetPointer(1092,1451)); + setWidgetIsHidden(true, new WidgetPointer(1092,1457)); + setWidgetIsHidden(true, new WidgetPointer(1092,1463)); + setWidgetIsHidden(true, new WidgetPointer(1092,1469)); + setWidgetIsHidden(true, new WidgetPointer(1092,1475)); + setWidgetIsHidden(true, new WidgetPointer(1092,1481)); + setWidgetIsHidden(true, new WidgetPointer(1092,1487)); + return; +} diff --git a/dumps/scripts/4861.cs2 b/dumps/scripts/4861.cs2 new file mode 100644 index 0000000..1fb645a --- /dev/null +++ b/dumps/scripts/4861.cs2 @@ -0,0 +1,17 @@ +void script_4861() { + if (citadelConfigsInitialized()) { + setWidgetIsHidden(false, new WidgetPointer(1092,1371)); + setWidgetIsHidden(false, new WidgetPointer(1092,1364)); + setWidgetIsHidden(false, new WidgetPointer(1092,1357)); + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return; +} diff --git a/dumps/scripts/4862.cs2 b/dumps/scripts/4862.cs2 new file mode 100644 index 0000000..125ac56 --- /dev/null +++ b/dumps/scripts/4862.cs2 @@ -0,0 +1,98 @@ +void script_4862() { + if (citadelConfigsInitialized()) { + if (script_4949(4) <= 0) { + setWidgetIsHidden(true, new WidgetPointer(1092,184)); + } + if (script_4949(5) <= 0) { + setWidgetIsHidden(true, new WidgetPointer(1092,185)); + } + if (script_4949(6) <= 0) { + setWidgetIsHidden(true, new WidgetPointer(1092,186)); + } + if (script_4949(7) <= 0) { + setWidgetIsHidden(true, new WidgetPointer(1092,187)); + } + if (script_4949(8) <= 0) { + setWidgetIsHidden(true, new WidgetPointer(1092,188)); + } + if (script_4949(9) <= 0) { + setWidgetIsHidden(true, new WidgetPointer(1092,189)); + } + if (script_4949(10) <= 0) { + setWidgetIsHidden(true, new WidgetPointer(1092,190)); + } + if (script_4949(11) <= 0) { + setWidgetIsHidden(true, new WidgetPointer(1092,191)); + } + if (script_4949(12) <= 0) { + setWidgetIsHidden(true, new WidgetPointer(1092,192)); + } + if (script_4949(13) <= 0) { + setWidgetIsHidden(true, new WidgetPointer(1092,193)); + } + if (script_4949(14) <= 0) { + setWidgetIsHidden(true, new WidgetPointer(1092,194)); + } + if (script_4949(15) <= 0) { + setWidgetIsHidden(true, new WidgetPointer(1092,195)); + } + if (script_4949(16) <= 0) { + setWidgetIsHidden(true, new WidgetPointer(1092,0)); + } + if (script_4949(17) <= 0) { + setWidgetIsHidden(true, new WidgetPointer(1092,1)); + } + if (script_4949(18) <= 0) { + setWidgetIsHidden(true, new WidgetPointer(1092,2)); + } + if (script_4949(19) <= 0) { + setWidgetIsHidden(true, new WidgetPointer(1092,3)); + } + if (script_4949(20) <= 0) { + setWidgetIsHidden(true, new WidgetPointer(1092,4)); + } + if (script_4949(21) <= 0) { + setWidgetIsHidden(true, new WidgetPointer(1092,5)); + } + if (script_4949(22) <= 0) { + setWidgetIsHidden(true, new WidgetPointer(1092,6)); + } + if (script_4949(23) <= 0) { + setWidgetIsHidden(true, new WidgetPointer(1092,7)); + } + if (script_4949(24) <= 0) { + setWidgetIsHidden(true, new WidgetPointer(1092,8)); + } + if (script_4949(25) <= 0) { + setWidgetIsHidden(true, new WidgetPointer(1092,9)); + } + if (script_4949(26) <= 0) { + setWidgetIsHidden(true, new WidgetPointer(1092,10)); + } + if (script_4949(27) <= 0) { + setWidgetIsHidden(true, new WidgetPointer(1092,11)); + } + if (script_4949(28) <= 0) { + setWidgetIsHidden(true, new WidgetPointer(1092,12)); + } + if (script_4949(29) <= 0) { + setWidgetIsHidden(true, new WidgetPointer(1092,13)); + } + if (script_4949(30) <= 0) { + setWidgetIsHidden(true, new WidgetPointer(1092,14)); + } + if (script_4949(31) <= 0) { + setWidgetIsHidden(true, new WidgetPointer(1092,15)); + } + if (script_4949(32) <= 0) { + setWidgetIsHidden(true, new WidgetPointer(1092,16)); + } + if (script_4949(33) <= 0) { + setWidgetIsHidden(true, new WidgetPointer(1092,17)); + } + if (script_4949(34) <= 0) { + setWidgetIsHidden(true, new WidgetPointer(1092,18)); + } + } + return; +} diff --git a/dumps/scripts/4863.cs2 b/dumps/scripts/4863.cs2 new file mode 100644 index 0000000..35ad061 --- /dev/null +++ b/dumps/scripts/4863.cs2 @@ -0,0 +1,37 @@ +void script_4863() { + setWidgetIsHidden(false, new WidgetPointer(1092,213)); + setWidgetIsHidden(false, new WidgetPointer(1092,214)); + setWidgetIsHidden(false, new WidgetPointer(1092,215)); + setWidgetIsHidden(false, new WidgetPointer(1092,184)); + setWidgetIsHidden(false, new WidgetPointer(1092,185)); + setWidgetIsHidden(false, new WidgetPointer(1092,186)); + setWidgetIsHidden(false, new WidgetPointer(1092,187)); + setWidgetIsHidden(false, new WidgetPointer(1092,188)); + setWidgetIsHidden(false, new WidgetPointer(1092,189)); + setWidgetIsHidden(false, new WidgetPointer(1092,190)); + setWidgetIsHidden(false, new WidgetPointer(1092,191)); + setWidgetIsHidden(false, new WidgetPointer(1092,192)); + setWidgetIsHidden(false, new WidgetPointer(1092,193)); + setWidgetIsHidden(false, new WidgetPointer(1092,194)); + setWidgetIsHidden(false, new WidgetPointer(1092,195)); + setWidgetIsHidden(false, new WidgetPointer(1092,0)); + setWidgetIsHidden(false, new WidgetPointer(1092,1)); + setWidgetIsHidden(false, new WidgetPointer(1092,2)); + setWidgetIsHidden(false, new WidgetPointer(1092,3)); + setWidgetIsHidden(false, new WidgetPointer(1092,4)); + setWidgetIsHidden(false, new WidgetPointer(1092,5)); + setWidgetIsHidden(false, new WidgetPointer(1092,6)); + setWidgetIsHidden(false, new WidgetPointer(1092,7)); + setWidgetIsHidden(false, new WidgetPointer(1092,8)); + setWidgetIsHidden(false, new WidgetPointer(1092,9)); + setWidgetIsHidden(false, new WidgetPointer(1092,10)); + setWidgetIsHidden(false, new WidgetPointer(1092,11)); + setWidgetIsHidden(false, new WidgetPointer(1092,12)); + setWidgetIsHidden(false, new WidgetPointer(1092,13)); + setWidgetIsHidden(false, new WidgetPointer(1092,14)); + setWidgetIsHidden(false, new WidgetPointer(1092,15)); + setWidgetIsHidden(false, new WidgetPointer(1092,16)); + setWidgetIsHidden(false, new WidgetPointer(1092,17)); + setWidgetIsHidden(false, new WidgetPointer(1092,18)); + return; +} diff --git a/dumps/scripts/4864.cs2 b/dumps/scripts/4864.cs2 new file mode 100644 index 0000000..71559f3 --- /dev/null +++ b/dumps/scripts/4864.cs2 @@ -0,0 +1,150 @@ +void script_4864() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + int ivar22; + int ivar23; + int ivar24; + int ivar25; + int ivar26; + int ivar27; + int ivar28; + int ivar29; + int ivar30; + int ivar31; + int ivar32; + int ivar33; + int ivar34; + int ivar35; + int ivar36; + int ivar37; + string svar0; + string svar1; + string svar2; + string svar3; + string svar4; + string svar5; + cs2func_script_4797_struct(6,0,0) structdump_0; + int stack_dump1; + cs2func_script_4791_struct(7,1,0) structdump_2; + int stack_dump3; + cs2func_script_4792_struct(6,0,0) structdump_4; + script_4865(); + ivar0 = 0; + ivar1 = 0; + ivar2 = 0; + ivar3 = 1; + ivar4 = 0; + ivar5 = 0; + ivar6 = 0; + ivar7 = 0; + ivar8 = 0; + ivar9 = 0; + ivar10 = 0; + ivar11 = 0; + ivar12 = 0; + ivar13 = 0; + ivar14 = 0; + ivar15 = 0; + ivar16 = 0; + ivar17 = 0; + ivar18 = 0; + ivar19 = 0; + ivar20 = 0; + ivar21 = 0; + ivar22 = 0; + ivar23 = 0; + ivar24 = 0; + ivar25 = 0; + ivar26 = -1; + svar0 = ""; + ivar27 = 0; + ivar28 = 0; + ivar29 = 0; + ivar30 = 0; + ivar31 = 0; + ivar32 = 0; + ivar33 = 0; + ivar34 = 0; + svar1 = ""; + svar2 = "You do not have permission from your clan to set the primary resource target."; + svar3 = "Toggle whether this resource is the primary resource target."; + svar4 = "You do not have permission from your clan to set resource target amounts."; + svar5 = "Set a target amount of this resource to be collected."; + ivar35 = -1; + globalarray_0 = new int[10]; + ivar36 = 0; + ivar37 = 0; + if (citadelConfigsInitialized()) { + structdump_0 = script_4797(); + ivar15 = structdump_0.intpart_5; + ivar16 = structdump_0.intpart_4; + ivar17 = structdump_0.intpart_3; + ivar14 = structdump_0.intpart_2; + ivar13 = structdump_0.intpart_1; + ivar12 = structdump_0.intpart_0; + while (ivar3 <= 31) { + ivar4 = script_4790(ivar3); + if (ivar4 > 0) { + stack_dump1 = ivar4; + structdump_2 = script_4791(stack_dump1); + ivar32 = structdump_2.intpart_6; + ivar31 = structdump_2.intpart_5; + ivar30 = structdump_2.intpart_4; + ivar29 = structdump_2.intpart_3; + ivar28 = structdump_2.intpart_2; + ivar27 = structdump_2.intpart_1; + svar0 = structdump_2.stringpart_0; + ivar26 = structdump_2.intpart_0; + stack_dump1 = ivar4; + stack_dump3 = ivar27; + structdump_4 = script_4792(stack_dump1, stack_dump3); + ivar9 = structdump_4.intpart_5; + ivar11 = structdump_4.intpart_4; + ivar10 = structdump_4.intpart_3; + ivar8 = structdump_4.intpart_2; + ivar7 = structdump_4.intpart_1; + ivar6 = structdump_4.intpart_0; + ivar5 = script_4975(ivar4); + if (ivar5 == 3) { + ivar18 = add(ivar18, ivar6); + ivar19 = add(ivar19, ivar7); + ivar20 = add(ivar20, ivar8); + ivar23 = add(ivar23, ivar11); + ivar22 = add(ivar22, ivar10); + ivar21 = add(ivar21, ivar9); + } + } + ivar3 = add(ivar3, 1); + } + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return; +} diff --git a/dumps/scripts/4865.cs2 b/dumps/scripts/4865.cs2 new file mode 100644 index 0000000..46ac61e --- /dev/null +++ b/dumps/scripts/4865.cs2 @@ -0,0 +1,5 @@ +void script_4865() { + int ivar0; + ivar0 = add(0, 1); + return; +} diff --git a/dumps/scripts/4866.cs2 b/dumps/scripts/4866.cs2 new file mode 100644 index 0000000..7c20302 --- /dev/null +++ b/dumps/scripts/4866.cs2 @@ -0,0 +1,100 @@ +?? script_4866(int arg0,int arg1,int arg2,int arg3,int arg4) { + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + int ivar22; + int ivar23; + int ivar24; + int ivar25; + int ivar26; + string svar0; + string svar1; + int stack_dump0; + cs2func_script_5223_struct(2,0,0) structdump_1; + ivar5 = script_4867(arg0); + ivar6 = script_4868(arg0); + ivar7 = script_4869(arg0); + ivar8 = script_4870(arg0); + ivar9 = getWidgetParentUid(new WidgetPointer(ivar6)); + ivar10 = getWidgetParentUid(new WidgetPointer(ivar9)); + ivar11 = getWidgetParentUid(new WidgetPointer(ivar10)); + ivar12 = 1; + if (citadelConfigsInitialized()) { + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + ivar13 = script_5215(arg0); + ivar14 = getWidgetActualWidth(new WidgetPointer(getWidgetParentUid(new WidgetPointer(ivar6)))); + arg1 = divide(arg1, 100); + arg4 = max(arg4, ivar13); + ivar15 = divide(multiply(arg1, ivar14), arg4); + ivar16 = divide(multiply(ivar13, ivar14), arg4); + ivar17 = divide(multiply(arg2, ivar14), arg4); + ivar18 = divide(multiply(arg3, ivar14), arg4); + ivar19 = subtract(arg1, add(arg2, arg3)); + ivar20 = divide(multiply(ivar19, ivar14), arg4); + setWidgetText(new WidgetPointer(ivar5), intToStr(arg1)); + ivar21 = 0; + setWidgetSize(min(subtract(ivar17, 2), ivar15), getWidgetActualHeight(new WidgetPointer(ivar6)), 0, 0, new WidgetPointer(ivar6)); + setWidgetPosition(1, 0, 0, 0, new WidgetPointer(ivar6)); + setWidgetSize(min(ivar18, subtract(ivar15, ivar17)), getWidgetActualHeight(new WidgetPointer(ivar7)), 0, 0, new WidgetPointer(ivar7)); + setWidgetPosition(ivar17, 0, 0, 0, new WidgetPointer(ivar7)); + setWidgetSize(min(subtract(ivar20, 2), subtract(ivar15, add(ivar17, ivar18))), getWidgetActualHeight(new WidgetPointer(ivar8)), 0, 0, new WidgetPointer(ivar8)); + setWidgetPosition(add(add(ivar17, ivar18), 1), 0, 0, 0, new WidgetPointer(ivar8)); + ivar22 = -1; + ivar23 = -1; + ivar24 = 7317; + ivar25 = 7314; + stack_dump0 = arg0; + structdump_1 = script_5223(stack_dump0); + ivar23 = structdump_1.intpart_1; + ivar22 = structdump_1.intpart_0; + if ((ivar22 != -1) && (ivar23 != -1)) { + ivar16 = add(ivar16, 82); + ivar16 = subtract(ivar16, divide(getWidgetActualWidth(new WidgetPointer(ivar23)), 2)); + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + svar0 = cs2method_3408(105, 115, 4285, arg0); + svar1 = svar0 + "
" + "Total : " + intToStr(arg1) + "
" + "Upkeep : " + intToStr(arg2) + "
" + "Upgrades : " + intToStr(arg3) + "
" + "Surplus : " + intToStr(ivar19); + if (ivar13 > 0) { + svar1 = concat(svar1, "
" + "Goal: " + intToStr(ivar13)); + } + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ +} diff --git a/dumps/scripts/4867.cs2 b/dumps/scripts/4867.cs2 new file mode 100644 index 0000000..c07e50f --- /dev/null +++ b/dumps/scripts/4867.cs2 @@ -0,0 +1,25 @@ +int script_4867(int arg0) { + switch (arg0) { + case 1: + return 71565436; + case 2: + return 71566947; + case 3: + return 71566962; + case 4: + return 71566977; + case 5: + return 71566992; + case 6: + return 71567037; + case 7: + return 71567052; + case 8: + return 71567022; + case 9: + return 71567006; + case 10: + return 71567067; + } + return -1; +} diff --git a/dumps/scripts/4868.cs2 b/dumps/scripts/4868.cs2 new file mode 100644 index 0000000..8f4135e --- /dev/null +++ b/dumps/scripts/4868.cs2 @@ -0,0 +1,25 @@ +int script_4868(int arg0) { + switch (arg0) { + case 1: + return 71565418; + case 2: + return 71566937; + case 3: + return 71566952; + case 4: + return 71566967; + case 5: + return 71566982; + case 6: + return 71567027; + case 7: + return 71567042; + case 8: + return 71567012; + case 9: + return 71566997; + case 10: + return 71567057; + } + return -1; +} diff --git a/dumps/scripts/4869.cs2 b/dumps/scripts/4869.cs2 new file mode 100644 index 0000000..e1944a5 --- /dev/null +++ b/dumps/scripts/4869.cs2 @@ -0,0 +1,25 @@ +int script_4869(int arg0) { + switch (arg0) { + case 1: + return 71565419; + case 2: + return 71566938; + case 3: + return 71566953; + case 4: + return 71566968; + case 5: + return 71566983; + case 6: + return 71567028; + case 7: + return 71567043; + case 8: + return 71567013; + case 9: + return 71566998; + case 10: + return 71567058; + } + return -1; +} diff --git a/dumps/scripts/487.cs2 b/dumps/scripts/487.cs2 new file mode 100644 index 0000000..f59822c --- /dev/null +++ b/dumps/scripts/487.cs2 @@ -0,0 +1,31 @@ +void script_487() { + flow_0: + setWidgetSprite(3263, new WidgetPointer(1015,95)); + setWidgetSprite(3263, new WidgetPointer(1015,89)); + setWidgetSprite(3263, new WidgetPointer(1015,83)); + setWidgetSprite(3263, new WidgetPointer(1015,77)); + SWITCH (bitconfig_7515) { + case 1: + GOTO flow_1 + case 2: + GOTO flow_2 + case 3: + GOTO flow_3 + case 4: + GOTO flow_4 + } + return; + flow_1: + setWidgetSprite(3265, new WidgetPointer(1015,95)); + GOTO flow_5 + flow_2: + setWidgetSprite(3265, new WidgetPointer(1015,89)); + GOTO flow_5 + flow_3: + setWidgetSprite(3265, new WidgetPointer(1015,83)); + GOTO flow_5 + flow_4: + setWidgetSprite(3265, new WidgetPointer(1015,77)); + flow_5: + return; +} diff --git a/dumps/scripts/4870.cs2 b/dumps/scripts/4870.cs2 new file mode 100644 index 0000000..9720749 --- /dev/null +++ b/dumps/scripts/4870.cs2 @@ -0,0 +1,25 @@ +int script_4870(int arg0) { + switch (arg0) { + case 1: + return 71565420; + case 2: + return 71566939; + case 3: + return 71566954; + case 4: + return 71566969; + case 5: + return 71566984; + case 6: + return 71567029; + case 7: + return 71567044; + case 8: + return 71567014; + case 9: + return 71566999; + case 10: + return 71567059; + } + return -1; +} diff --git a/dumps/scripts/4871.cs2 b/dumps/scripts/4871.cs2 new file mode 100644 index 0000000..e5a64b0 --- /dev/null +++ b/dumps/scripts/4871.cs2 @@ -0,0 +1,25 @@ +int script_4871(int arg0) { + switch (arg0) { + case 1: + return 71565381; + case 2: + return 71565399; + case 3: + return 71565397; + case 4: + return 71565383; + case 5: + return 71565387; + case 6: + return 71565395; + case 7: + return 71565391; + case 8: + return 71565389; + case 9: + return 71565385; + case 10: + return 71565393; + } + return -1; +} diff --git a/dumps/scripts/4872.cs2 b/dumps/scripts/4872.cs2 new file mode 100644 index 0000000..00e9ceb --- /dev/null +++ b/dumps/scripts/4872.cs2 @@ -0,0 +1,25 @@ +int script_4872(int arg0) { + switch (arg0) { + case 1: + return 71565400; + case 2: + return 71567130; + case 3: + return 71567131; + case 4: + return 71567132; + case 5: + return 71567133; + case 6: + return 71567136; + case 7: + return 71567137; + case 8: + return 71567135; + case 9: + return 71567134; + case 10: + return 71567138; + } + return -1; +} diff --git a/dumps/scripts/4873.cs2 b/dumps/scripts/4873.cs2 new file mode 100644 index 0000000..b916e68 --- /dev/null +++ b/dumps/scripts/4873.cs2 @@ -0,0 +1,4 @@ +void script_4873(int arg0) { + script_4874(arg0); + return; +} diff --git a/dumps/scripts/4874.cs2 b/dumps/scripts/4874.cs2 new file mode 100644 index 0000000..128c046 --- /dev/null +++ b/dumps/scripts/4874.cs2 @@ -0,0 +1,12 @@ +void script_4874(int arg0) { + int ivar1; + bitconfig_9553 = arg0; + ivar1 = add(0, 1); + while (ivar1 <= 10) { + setWidgetIsHidden(true, new WidgetPointer(script_4871(ivar1))); + ivar1 = add(ivar1, 1); + } + setWidgetIsHidden(false, new WidgetPointer(script_4871(arg0))); + script_4864(); + return; +} diff --git a/dumps/scripts/4875.cs2 b/dumps/scripts/4875.cs2 new file mode 100644 index 0000000..39c1dbd --- /dev/null +++ b/dumps/scripts/4875.cs2 @@ -0,0 +1,4 @@ +void script_4875(int arg0) { + script_4876(arg0); + return; +} diff --git a/dumps/scripts/4876.cs2 b/dumps/scripts/4876.cs2 new file mode 100644 index 0000000..19934d5 --- /dev/null +++ b/dumps/scripts/4876.cs2 @@ -0,0 +1,10 @@ +void script_4876(int arg0) { + int ivar1; + ivar1 = add(0, 1); + while (ivar1 <= 10) { + setWidgetIsHidden(true, new WidgetPointer(script_4872(ivar1))); + ivar1 = add(ivar1, 1); + } + setWidgetIsHidden(false, new WidgetPointer(script_4872(arg0))); + return; +} diff --git a/dumps/scripts/4877.cs2 b/dumps/scripts/4877.cs2 new file mode 100644 index 0000000..f6620b5 --- /dev/null +++ b/dumps/scripts/4877.cs2 @@ -0,0 +1,4 @@ +void script_4877(int arg0) { + script_4876(arg0); + return; +} diff --git a/dumps/scripts/4878.cs2 b/dumps/scripts/4878.cs2 new file mode 100644 index 0000000..bdc96f4 --- /dev/null +++ b/dumps/scripts/4878.cs2 @@ -0,0 +1,3 @@ +void script_4878(int arg0) { + return; +} diff --git a/dumps/scripts/4879.cs2 b/dumps/scripts/4879.cs2 new file mode 100644 index 0000000..1ee30a5 --- /dev/null +++ b/dumps/scripts/4879.cs2 @@ -0,0 +1,4 @@ +void script_4879(int arg0) { + script_4880(arg0); + return; +} diff --git a/dumps/scripts/488.cs2 b/dumps/scripts/488.cs2 new file mode 100644 index 0000000..feb2458 --- /dev/null +++ b/dumps/scripts/488.cs2 @@ -0,0 +1,42 @@ +int script_488(int arg0) { + flow_0: + SWITCH (arg0) { + case 1: + GOTO flow_1 + case 2: + GOTO flow_2 + case 3: + GOTO flow_3 + case 4: + GOTO flow_4 + case 5: + GOTO flow_5 + case 6: + GOTO flow_6 + case 7: + GOTO flow_7 + case 8: + GOTO flow_8 + case 9: + GOTO flow_9 + } + return -1; + flow_1: + return 293; + flow_2: + return 299; + flow_3: + return 300; + flow_4: + return 301; + flow_5: + return 305; + flow_6: + return 1044; + flow_7: + return 1045; + flow_8: + return 1046; + flow_9: + return 1047; +} diff --git a/dumps/scripts/4880.cs2 b/dumps/scripts/4880.cs2 new file mode 100644 index 0000000..c96dd2e --- /dev/null +++ b/dumps/scripts/4880.cs2 @@ -0,0 +1,141 @@ +void script_4880(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + string svar0; + svar0 = ""; + ivar1 = 0; + ivar2 = 0; + ivar3 = 3; + ivar4 = 0; + ivar5 = 2236962; + ivar6 = -1; + ivar7 = 0; + ivar8 = script_4964(arg0); + ivar9 = 0; + ivar10 = 0; + switch (arg0) { + case 71566780: + case 71566750: + case 71566707: + case 71566744: + case 71566713: + case 71566774: + case 71566768: + case 71566738: + case 71566719: + case 71566689: + case 71566792: + case 71566732: + case 71566798: + case 71566762: + case 71566695: + case 71566786: + case 71566756: + case 71566726: + case 71566701: + ivar10 = 1; + } + if (citadelConfigsInitialized()) { + deleteAllExtraChilds(new WidgetPointer(arg0)); + script_4407(arg0, 1, 178); + createExtraChild(new WidgetPointer(arg0), 3, 0); + setWidgetSize(20, 20, 0, 0); + setWidgetPosition(0, 0, 1, 1); + setWidgetRGB(new Color(85, 51, 51)); + setWidgetFilled(1); + if (((boolean)ivar10)) { + cs2method2103(255); + setWidgetHidden(1); + } + ivar4 = getExtraChildGap(new WidgetPointer(arg0)); + createExtraChild(new WidgetPointer(arg0), 3, 1); + setWidgetSize(20, 20, 0, 0); + setWidgetPosition(0, 0, 1, 1); + setWidgetRGB(new Color(238, 204, 238)); + if (((boolean)ivar10)) { + cs2method2103(255); + } + ivar7 = script_4971(ivar8); + ivar6 = script_5171(ivar7); + createExtraChild(new WidgetPointer(arg0), 5, 2); + setWidgetSize(18, 18, 0, 0); + setWidgetPosition(0, 0, 1, 1); + if (((boolean)ivar10)) { + cs2method2103(255); + } + switch (ivar8) { + case 35: + case 38: + case 39: + case 36: + case 37: + case 42: + case 43: + case 40: + case 41: + case 46: + case 47: + case 44: + case 45: + case 48: + ivar2 = 1; + ivar3 = 1; + break; + default: + ivar2 = 0; + ivar3 = 3; + } + if (ivar9 > 0) { + ivar1 = 1; + ivar5 = 12303291; + } else { + ivar1 = 0; + ivar5 = 2236962; + } + if (((boolean)ivar2)) { + if (((boolean)ivar1)) { + svar0 = "Build over the existing blanket change."; + } else { + svar0 = "Build a new blanket change."; + } + } else { + switch (ivar8) { + case 25: + case 24: + case 27: + case 26: + case 28: + if (((boolean)ivar1)) { + svar0 = "Build over the existing statue."; + } else { + svar0 = "Build a new statue."; + } + break; + default: + if (((boolean)ivar1)) { + svar0 = "Build over the existing customisation."; + } else { + svar0 = "Build a new customisation."; + } + } + } + } + ivar11 = script_5216(ivar8); + if (((boolean)ivar2)) { + setWidgetIsHidden(true, new WidgetPointer(getWidgetParentUid(new WidgetPointer(arg0)))); + if (ivar11 != -1) { + setScriptCallOnMouseOver(4882, new WidgetPointer(-32768,3), svar0, ivar3, "Isi", new WidgetPointer(ivar11)); + } + } + setScriptCallOnMouseOver(4882, new WidgetPointer(-32768,3), svar0, ivar3, "Isi", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/4881.cs2 b/dumps/scripts/4881.cs2 new file mode 100644 index 0000000..f330aa6 --- /dev/null +++ b/dumps/scripts/4881.cs2 @@ -0,0 +1,22 @@ +void script_4881() { + script_4880(71566689); + script_4880(71566695); + script_4880(71566701); + script_4880(71566707); + script_4880(71566713); + script_4880(71566719); + script_4880(71566726); + script_4880(71566732); + script_4880(71566738); + script_4880(71566744); + script_4880(71566750); + script_4880(71566756); + script_4880(71566762); + script_4880(71566768); + script_4880(71566774); + script_4880(71566780); + script_4880(71566786); + script_4880(71566792); + script_4880(71566798); + return; +} diff --git a/dumps/scripts/4882.cs2 b/dumps/scripts/4882.cs2 new file mode 100644 index 0000000..dd3d847 --- /dev/null +++ b/dumps/scripts/4882.cs2 @@ -0,0 +1,4 @@ +void script_4882(int arg0,int arg1,string arg2) { + script_4883(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/4883.cs2 b/dumps/scripts/4883.cs2 new file mode 100644 index 0000000..44f125b --- /dev/null +++ b/dumps/scripts/4883.cs2 @@ -0,0 +1,202 @@ +void script_4883(int arg0,int arg1,string arg2) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + string svar1; + ivar2 = script_4964(arg0); + ivar3 = script_4971(ivar2); + ivar4 = getWidgetParentUid(new WidgetPointer(arg0)); + ivar5 = getWidgetParentUid(new WidgetPointer(ivar4)); + ivar6 = script_5216(ivar2); + if (ivar6 == -1) { + ivar6 = arg0; + } + svar1 = ""; + ivar7 = 0; + if (citadelConfigsInitialized()) { + switch (arg0) { + case 71566805: + arg1 = 1; + arg2 = "Build a new party room chair customisation."; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 71566821: + arg1 = 1; + arg2 = "Build a new party room table customisation."; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 71566813: + arg1 = 1; + arg2 = "Build a new flag customisation."; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 71566829: + arg1 = 1; + arg2 = "Build a new potted plant customisation."; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 71566837: + arg1 = 1; + arg2 = "Build a new sundial customisation."; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 71566845: + arg1 = 1; + arg2 = "Build a new keep flag customisation."; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 71566853: + arg1 = 1; + arg2 = "Build a new keep tapestry customisation."; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 71566861: + arg1 = 1; + arg2 = "Build a new keep banner customisation."; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 71566869: + arg1 = 1; + arg2 = "Build a new keep shield customisation."; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 71566877: + arg1 = 1; + arg2 = "Build a new keep fireplace customisation."; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 71566885: + arg1 = 1; + arg2 = "Build a new keep lower window customisation."; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 71566893: + arg1 = 1; + arg2 = "Build a new keep upper window customisation."; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 71566901: + arg1 = 1; + arg2 = "Build a new keep door customisation."; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 71566909: + arg1 = 1; + arg2 = "Build a new keep wall pattern customisation."; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + arg2 = "Build over: " + script_4914(ivar3); + if (((boolean)ivar7)) { + arg2 = "Build over " + script_4914(ivar3); + } + if (getWidgetActualX(new WidgetPointer(ivar4)) < subtract(divide(getWidgetActualWidth(new WidgetPointer(ivar5)), 2), 30)) { + arg1 = 1; + } + } + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,300), new WidgetPointer(arg0), -1, arg2, 120, 3793, 3793, 16777215, 13, 4, arg1, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(arg0)); + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,300), new WidgetPointer(arg0), -1, arg2, 120, 3793, 3793, 16777215, 13, 4, arg1, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(ivar6)); + setScriptCallOnMouseExit(40, new WidgetPointer(1092,300), "I", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/4884.cs2 b/dumps/scripts/4884.cs2 new file mode 100644 index 0000000..03f6f1e --- /dev/null +++ b/dumps/scripts/4884.cs2 @@ -0,0 +1,4 @@ +void script_4884(int arg0) { + script_4885(arg0); + return; +} diff --git a/dumps/scripts/4885.cs2 b/dumps/scripts/4885.cs2 new file mode 100644 index 0000000..b3cb095 --- /dev/null +++ b/dumps/scripts/4885.cs2 @@ -0,0 +1,64 @@ +void script_4885(int arg0) { + int ivar1; + int ivar2; + int ivar3; + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + if (citadelConfigsInitialized()) { + ivar2 = script_4964(arg0); + ivar3 = script_4971(ivar2); + if (((boolean)script_4886(ivar3))) { + return; + } + if (((bitconfig_9570 == ivar3) || (bitconfig_9579 == ivar3)) || (bitconfig_9588 == ivar3)) { + return; + } + switch (ivar2) { + case 35: + case 38: + case 39: + case 36: + case 37: + case 42: + case 43: + case 40: + case 41: + case 46: + case 47: + case 44: + case 45: + case 48: + ivar1 = 0; + break; + default: + ivar1 = 1; + } + if ((bitconfig_9558 > 0) && ((boolean)script_4828(bitconfig_9558))) { + switch (bitconfig_9558) { + case 1: + bitconfig_9570 = ivar3; + bitconfig_9564 = ivar1; + break; + case 2: + bitconfig_9579 = ivar3; + bitconfig_9573 = ivar1; + break; + case 3: + bitconfig_9588 = ivar3; + bitconfig_9582 = ivar1; + } + return; + } + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return; +} diff --git a/dumps/scripts/4886.cs2 b/dumps/scripts/4886.cs2 new file mode 100644 index 0000000..9eef488 --- /dev/null +++ b/dumps/scripts/4886.cs2 @@ -0,0 +1,28 @@ +int script_4886(int arg0) { + int ivar1; + switch (arg0) { + case 34: + case 35: + case 32: + case 33: + case 21: + case 22: + case 42: + case 41: + case 31: + return 1; + } + ivar1 = 0; + if (citadelConfigsInitialized()) { + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return 0; +} diff --git a/dumps/scripts/4887.cs2 b/dumps/scripts/4887.cs2 new file mode 100644 index 0000000..1b1018b --- /dev/null +++ b/dumps/scripts/4887.cs2 @@ -0,0 +1,4 @@ +void script_4887(int arg0) { + script_4888(arg0); + return; +} diff --git a/dumps/scripts/4888.cs2 b/dumps/scripts/4888.cs2 new file mode 100644 index 0000000..968f7d2 --- /dev/null +++ b/dumps/scripts/4888.cs2 @@ -0,0 +1,10 @@ +void script_4888(int arg0) { + script_4944(); + script_4933(); + script_4899(2); + setWidgetIsHidden(false, new WidgetPointer(1092,303)); + setWidgetIsHidden(false, new WidgetPointer(1092,260)); + bitconfig_9558 = arg0; + script_4849(); + return; +} diff --git a/dumps/scripts/4889.cs2 b/dumps/scripts/4889.cs2 new file mode 100644 index 0000000..49bb056 --- /dev/null +++ b/dumps/scripts/4889.cs2 @@ -0,0 +1,26 @@ +?? script_4889() { + string svar0; + svar0 = ""; + setWidgetIsHidden(true, new WidgetPointer(1092,1493)); + setWidgetIsHidden(true, new WidgetPointer(1092,1509)); + setWidgetIsHidden(true, new WidgetPointer(1092,1501)); + setWidgetIsHidden(true, new WidgetPointer(1092,1517)); + setWidgetIsHidden(true, new WidgetPointer(1092,1525)); + setWidgetIsHidden(true, new WidgetPointer(1092,1533)); + setWidgetIsHidden(true, new WidgetPointer(1092,1541)); + setWidgetIsHidden(true, new WidgetPointer(1092,1549)); + setWidgetIsHidden(true, new WidgetPointer(1092,1557)); + setWidgetIsHidden(true, new WidgetPointer(1092,1565)); + setWidgetIsHidden(true, new WidgetPointer(1092,1573)); + setWidgetIsHidden(true, new WidgetPointer(1092,1581)); + setWidgetIsHidden(true, new WidgetPointer(1092,1589)); + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ +} diff --git a/dumps/scripts/489.cs2 b/dumps/scripts/489.cs2 new file mode 100644 index 0000000..6b228d7 --- /dev/null +++ b/dumps/scripts/489.cs2 @@ -0,0 +1,42 @@ +int script_489(int arg0) { + flow_0: + SWITCH (arg0) { + case 1: + GOTO flow_1 + case 2: + GOTO flow_2 + case 3: + GOTO flow_3 + case 4: + GOTO flow_4 + case 5: + GOTO flow_5 + case 6: + GOTO flow_6 + case 7: + GOTO flow_7 + case 8: + GOTO flow_8 + case 9: + GOTO flow_9 + } + return -1; + flow_1: + return 66519098; + flow_2: + return 66519100; + flow_3: + return 66519102; + flow_4: + return 66519104; + flow_5: + return 66519108; + flow_6: + return 66519110; + flow_7: + return 66519112; + flow_8: + return 66519114; + flow_9: + return 66519106; +} diff --git a/dumps/scripts/4890.cs2 b/dumps/scripts/4890.cs2 new file mode 100644 index 0000000..305f939 --- /dev/null +++ b/dumps/scripts/4890.cs2 @@ -0,0 +1,7 @@ +void script_4890(int arg0) { + script_4896(); + script_4897(arg0); + bitconfig_9548 = arg0; + script_4895(); + return; +} diff --git a/dumps/scripts/4891.cs2 b/dumps/scripts/4891.cs2 new file mode 100644 index 0000000..63ff816 --- /dev/null +++ b/dumps/scripts/4891.cs2 @@ -0,0 +1,4 @@ +void script_4891() { + script_4895(); + return; +} diff --git a/dumps/scripts/4892.cs2 b/dumps/scripts/4892.cs2 new file mode 100644 index 0000000..f2f9618 --- /dev/null +++ b/dumps/scripts/4892.cs2 @@ -0,0 +1,14 @@ +void script_4892() { + if (citadelConfigsInitialized()) { + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return; +} diff --git a/dumps/scripts/4893.cs2 b/dumps/scripts/4893.cs2 new file mode 100644 index 0000000..c264b6f --- /dev/null +++ b/dumps/scripts/4893.cs2 @@ -0,0 +1,5 @@ +void script_4893() { + bitconfig_9549 = 1; + script_4895(); + return; +} diff --git a/dumps/scripts/4894.cs2 b/dumps/scripts/4894.cs2 new file mode 100644 index 0000000..8a83974 --- /dev/null +++ b/dumps/scripts/4894.cs2 @@ -0,0 +1,5 @@ +void script_4894() { + bitconfig_9549 = 0; + script_4895(); + return; +} diff --git a/dumps/scripts/4895.cs2 b/dumps/scripts/4895.cs2 new file mode 100644 index 0000000..954d8e0 --- /dev/null +++ b/dumps/scripts/4895.cs2 @@ -0,0 +1,25 @@ +void script_4895() { + int ivar0; + int stack_dump0; + ivar0 = 0; + if (citadelConfigsInitialized()) { + stack_dump0 = bitconfig_9548; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + if (((boolean)ivar0)) { + setWidgetIsHidden(true, new WidgetPointer(1092,419)); + setWidgetIsHidden(true, new WidgetPointer(1092,427)); + } else { + setWidgetIsHidden(false, new WidgetPointer(1092,419)); + setWidgetIsHidden(false, new WidgetPointer(1092,427)); + } + return; +} diff --git a/dumps/scripts/4896.cs2 b/dumps/scripts/4896.cs2 new file mode 100644 index 0000000..36e95ee --- /dev/null +++ b/dumps/scripts/4896.cs2 @@ -0,0 +1,7 @@ +void script_4896() { + setWidgetIsHidden(true, new WidgetPointer(1092,557)); + setWidgetIsHidden(true, new WidgetPointer(1092,564)); + setWidgetIsHidden(true, new WidgetPointer(1092,578)); + setWidgetIsHidden(true, new WidgetPointer(1092,571)); + return; +} diff --git a/dumps/scripts/4897.cs2 b/dumps/scripts/4897.cs2 new file mode 100644 index 0000000..3304d18 --- /dev/null +++ b/dumps/scripts/4897.cs2 @@ -0,0 +1,19 @@ +void script_4897(int arg0) { + switch (arg0) { + case 0: + setWidgetIsHidden(false, new WidgetPointer(1092,557)); + break; + case 1: + setWidgetIsHidden(false, new WidgetPointer(1092,564)); + break; + case 2: + setWidgetIsHidden(false, new WidgetPointer(1092,578)); + break; + case 3: + setWidgetIsHidden(false, new WidgetPointer(1092,571)); + break; + default: + return; + } + return; +} diff --git a/dumps/scripts/4898.cs2 b/dumps/scripts/4898.cs2 new file mode 100644 index 0000000..e07707c --- /dev/null +++ b/dumps/scripts/4898.cs2 @@ -0,0 +1,4 @@ +void script_4898(int arg0) { + script_4899(arg0); + return; +} diff --git a/dumps/scripts/4899.cs2 b/dumps/scripts/4899.cs2 new file mode 100644 index 0000000..5675296 --- /dev/null +++ b/dumps/scripts/4899.cs2 @@ -0,0 +1,66 @@ +void script_4899(int arg0) { + bitconfig_9552 = arg0; + script_4935(); + script_4940(); + switch (arg0) { + case 0: + setWidgetIsHidden(true, new WidgetPointer(1092,212)); + setWidgetIsHidden(true, new WidgetPointer(1092,217)); + setWidgetIsHidden(true, new WidgetPointer(1092,216)); + setWidgetText(new WidgetPointer(1092,859), ""); + setWidgetIsHidden(true, new WidgetPointer(1092,847)); + script_4913(); + break; + case 1: + setWidgetIsHidden(false, new WidgetPointer(1092,212)); + setWidgetIsHidden(true, new WidgetPointer(1092,217)); + setWidgetIsHidden(true, new WidgetPointer(1092,216)); + setWidgetText(new WidgetPointer(1092,859), ""); + setWidgetIsHidden(true, new WidgetPointer(1092,847)); + setWidgetIsHidden(true, new WidgetPointer(1092,197)); + script_5009(); + script_5011(); + break; + case 2: + script_4860(); + script_4863(); + script_4859(); + setWidgetIsHidden(true, new WidgetPointer(1092,212)); + setWidgetIsHidden(false, new WidgetPointer(1092,217)); + setWidgetIsHidden(false, new WidgetPointer(1092,216)); + setWidgetText(new WidgetPointer(1092,859), ""); + setWidgetIsHidden(true, new WidgetPointer(1092,847)); + setWidgetIsHidden(true, new WidgetPointer(1092,197)); + script_5009(); + break; + case 4: + setWidgetIsHidden(false, new WidgetPointer(1092,212)); + setWidgetIsHidden(true, new WidgetPointer(1092,217)); + setWidgetIsHidden(true, new WidgetPointer(1092,216)); + setWidgetText(new WidgetPointer(1092,859), "Please select an available spot from the map."); + setWidgetIsHidden(false, new WidgetPointer(1092,847)); + setWidgetIsHidden(true, new WidgetPointer(1092,197)); + script_5010(); + script_4935(); + break; + case 3: + setWidgetIsHidden(false, new WidgetPointer(1092,212)); + setWidgetIsHidden(true, new WidgetPointer(1092,217)); + setWidgetIsHidden(true, new WidgetPointer(1092,216)); + setWidgetText(new WidgetPointer(1092,859), "Please select a spot from the map."); + setWidgetIsHidden(false, new WidgetPointer(1092,847)); + setWidgetIsHidden(true, new WidgetPointer(1092,197)); + script_5010(); + break; + case 5: + setWidgetIsHidden(true, new WidgetPointer(1092,212)); + setWidgetIsHidden(false, new WidgetPointer(1092,217)); + setWidgetIsHidden(false, new WidgetPointer(1092,216)); + setWidgetText(new WidgetPointer(1092,859), "Please select an available spot from the map."); + setWidgetIsHidden(false, new WidgetPointer(1092,847)); + setWidgetIsHidden(true, new WidgetPointer(1092,197)); + script_5009(); + } + script_4853(); + return; +} diff --git a/dumps/scripts/49.cs2 b/dumps/scripts/49.cs2 new file mode 100644 index 0000000..0df10fa --- /dev/null +++ b/dumps/scripts/49.cs2 @@ -0,0 +1,18 @@ +void script_49(int arg0,int arg1,int arg2) { + if (((boolean)script_2296(arg2))) { + if (setWidgetRegister(new WidgetPointer(arg0), arg2)) { + setWidgetContextMenuOption(1, "Deactivate"); + } + if (setWidgetRegister(new WidgetPointer(arg1), arg2)) { + setWidgetSprite(155); + } + } else { + if (setWidgetRegister(new WidgetPointer(arg0), arg2)) { + setWidgetContextMenuOption(1, "Activate"); + } + if (setWidgetRegister(new WidgetPointer(arg1), arg2)) { + setWidgetSprite(-1); + } + } + return; +} diff --git a/dumps/scripts/490.cs2 b/dumps/scripts/490.cs2 new file mode 100644 index 0000000..a3c1806 --- /dev/null +++ b/dumps/scripts/490.cs2 @@ -0,0 +1,76 @@ +void script_490() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + ivar0 = script_488(bitconfig_7539); + ivar1 = script_488(bitconfig_7540); + ivar2 = script_488(bitconfig_7541); + ivar3 = script_488(bitconfig_7542); + ivar4 = script_489(bitconfig_7539); + ivar5 = script_489(bitconfig_7540); + ivar6 = script_489(bitconfig_7541); + ivar7 = script_489(bitconfig_7542); + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(1015,58)); + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(1015,60)); + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(1015,62)); + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(1015,64)); + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(1015,68)); + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(1015,70)); + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(1015,72)); + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(1015,74)); + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(1015,66)); + if (ivar4 != -1) { + setWidgetRGB(new Color(88, 80, 66), new WidgetPointer(ivar4)); + } + if (ivar5 != -1) { + setWidgetRGB(new Color(88, 80, 66), new WidgetPointer(ivar5)); + } + if (ivar6 != -1) { + setWidgetRGB(new Color(88, 80, 66), new WidgetPointer(ivar6)); + } + if (ivar7 != -1) { + setWidgetRGB(new Color(88, 80, 66), new WidgetPointer(ivar7)); + } + if (ivar0 == -1) { + setWidgetIsHidden(true, new WidgetPointer(1015,96)); + setWidgetIsHidden(false, new WidgetPointer(1015,97)); + } else { + setWidgetIsHidden(false, new WidgetPointer(1015,96)); + setWidgetIsHidden(true, new WidgetPointer(1015,97)); + setWidgetText(new WidgetPointer(1015,100), getOtherCommonData(ivar0, 1150)); + setWidgetSprite(getOtherCommonData(ivar0, 1153), new WidgetPointer(1015,99)); + } + if (ivar1 == -1) { + setWidgetIsHidden(true, new WidgetPointer(1015,90)); + setWidgetIsHidden(false, new WidgetPointer(1015,93)); + } else { + setWidgetIsHidden(false, new WidgetPointer(1015,90)); + setWidgetIsHidden(true, new WidgetPointer(1015,93)); + setWidgetText(new WidgetPointer(1015,92), getOtherCommonData(ivar1, 1150)); + setWidgetSprite(getOtherCommonData(ivar1, 1153), new WidgetPointer(1015,91)); + } + if (ivar2 == -1) { + setWidgetIsHidden(true, new WidgetPointer(1015,84)); + setWidgetIsHidden(false, new WidgetPointer(1015,87)); + } else { + setWidgetIsHidden(false, new WidgetPointer(1015,84)); + setWidgetIsHidden(true, new WidgetPointer(1015,87)); + setWidgetText(new WidgetPointer(1015,86), getOtherCommonData(ivar2, 1150)); + setWidgetSprite(getOtherCommonData(ivar2, 1153), new WidgetPointer(1015,85)); + } + if (ivar3 == -1) { + setWidgetIsHidden(true, new WidgetPointer(1015,78)); + setWidgetIsHidden(false, new WidgetPointer(1015,81)); + } else { + setWidgetIsHidden(false, new WidgetPointer(1015,78)); + setWidgetIsHidden(true, new WidgetPointer(1015,81)); + setWidgetText(new WidgetPointer(1015,80), getOtherCommonData(ivar3, 1150)); + setWidgetSprite(getOtherCommonData(ivar3, 1153), new WidgetPointer(1015,79)); + } + return; +} diff --git a/dumps/scripts/4900.cs2 b/dumps/scripts/4900.cs2 new file mode 100644 index 0000000..fafed22 --- /dev/null +++ b/dumps/scripts/4900.cs2 @@ -0,0 +1,6 @@ +void script_4900() { + script_4901(); + script_4902(); + script_4903(); + return; +} diff --git a/dumps/scripts/4901.cs2 b/dumps/scripts/4901.cs2 new file mode 100644 index 0000000..b1c830b --- /dev/null +++ b/dumps/scripts/4901.cs2 @@ -0,0 +1,24 @@ +void script_4901() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + ivar0 = -1; + ivar1 = -1; + ivar2 = -1; + ivar3 = -1; + ivar4 = 1; + if (citadelConfigsInitialized()) { + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return; +} diff --git a/dumps/scripts/4902.cs2 b/dumps/scripts/4902.cs2 new file mode 100644 index 0000000..1d10ddc --- /dev/null +++ b/dumps/scripts/4902.cs2 @@ -0,0 +1,18 @@ +void script_4902() { + int ivar0; + int ivar1; + ivar0 = 1; + ivar1 = 0; + if (citadelConfigsInitialized()) { + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return; +} diff --git a/dumps/scripts/4903.cs2 b/dumps/scripts/4903.cs2 new file mode 100644 index 0000000..b1ff47d --- /dev/null +++ b/dumps/scripts/4903.cs2 @@ -0,0 +1,18 @@ +void script_4903() { + int ivar0; + int ivar1; + ivar0 = 1; + ivar1 = 0; + if (citadelConfigsInitialized()) { + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return; +} diff --git a/dumps/scripts/4904.cs2 b/dumps/scripts/4904.cs2 new file mode 100644 index 0000000..9821c2c --- /dev/null +++ b/dumps/scripts/4904.cs2 @@ -0,0 +1,7 @@ +int script_4904(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + ivar3 = cs2method_3408(105, 103, 3997, arg0); + ivar4 = cs2method_3408(105, 103, ivar3, arg1); + return cs2method_3408(105, 100, ivar4, arg2); +} diff --git a/dumps/scripts/4905.cs2 b/dumps/scripts/4905.cs2 new file mode 100644 index 0000000..c120ada --- /dev/null +++ b/dumps/scripts/4905.cs2 @@ -0,0 +1,40 @@ +void script_4905() { + if (citadelConfigsInitialized()) { + script_4906(1); + script_4906(2); + script_4906(3); + script_4906(4); + script_4906(5); + script_4906(6); + script_4906(7); + script_4906(8); + script_4906(9); + script_4906(10); + script_4906(11); + script_4906(12); + script_4906(13); + script_4906(14); + script_4906(15); + script_4906(16); + script_4906(17); + script_4906(18); + script_4906(19); + script_4906(20); + script_4906(21); + script_4906(22); + script_4906(23); + script_4906(24); + script_4906(25); + script_4906(26); + script_4906(27); + script_4906(28); + script_4906(29); + script_4906(30); + script_4906(31); + script_4906(32); + script_4906(33); + script_4906(34); + script_5221(); + } + return; +} diff --git a/dumps/scripts/4906.cs2 b/dumps/scripts/4906.cs2 new file mode 100644 index 0000000..8f43dd5 --- /dev/null +++ b/dumps/scripts/4906.cs2 @@ -0,0 +1,48 @@ +void script_4906(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + ivar1 = -1; + ivar2 = -1; + ivar3 = 0; + ivar4 = script_4968(arg0); + ivar5 = -1; + ivar6 = -1; + ivar7 = 1; + ivar8 = 0; + ivar9 = 0; + ivar10 = -1; + if (citadelConfigsInitialized()) { + if (isWidgetHidden(new WidgetPointer(1092,209))) { + ivar7 = 0; + } + if (((boolean)ivar7)) { + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return; +} diff --git a/dumps/scripts/4907.cs2 b/dumps/scripts/4907.cs2 new file mode 100644 index 0000000..0676dbe --- /dev/null +++ b/dumps/scripts/4907.cs2 @@ -0,0 +1,53 @@ +void script_4907() { + if (citadelConfigsInitialized()) { + script_4908(1); + script_4908(2); + script_4908(3); + script_4908(4); + script_4908(5); + script_4908(6); + script_4908(7); + script_4908(8); + script_4908(9); + script_4908(10); + script_4908(11); + script_4908(12); + script_4908(13); + script_4908(14); + script_4908(15); + script_4908(35); + script_4908(36); + script_4908(37); + script_4908(38); + script_4908(39); + script_4908(40); + script_4908(41); + script_4908(42); + script_4908(43); + script_4908(44); + script_4908(45); + script_4908(46); + script_4908(47); + script_4908(48); + script_4908(16); + script_4908(17); + script_4908(18); + script_4908(19); + script_4908(20); + script_4908(21); + script_4908(22); + script_4908(23); + script_4908(24); + script_4908(25); + script_4908(26); + script_4908(27); + script_4908(28); + script_4908(29); + script_4908(30); + script_4908(31); + script_4908(32); + script_4908(33); + script_4908(34); + } + return; +} diff --git a/dumps/scripts/4908.cs2 b/dumps/scripts/4908.cs2 new file mode 100644 index 0000000..6dc298b --- /dev/null +++ b/dumps/scripts/4908.cs2 @@ -0,0 +1,56 @@ +void script_4908(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + ivar1 = -1; + ivar2 = 0; + ivar3 = 0; + ivar4 = 0; + ivar5 = 0; + ivar6 = script_4950(arg0); + ivar7 = 0; + ivar8 = 0; + ivar9 = 0; + ivar10 = 0; + ivar11 = -1; + ivar12 = -1; + ivar13 = -1; + ivar14 = 1; + if (citadelConfigsInitialized()) { + if (isWidgetHidden(new WidgetPointer(1092,209))) { + ivar14 = 0; + } + if (((boolean)ivar14)) { + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return; +} diff --git a/dumps/scripts/4909.cs2 b/dumps/scripts/4909.cs2 new file mode 100644 index 0000000..51ed479 --- /dev/null +++ b/dumps/scripts/4909.cs2 @@ -0,0 +1,28 @@ +cs2func_script_4909_struct(2,0,0) script_4909(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + ivar1 = 0; + ivar2 = 0; + ivar3 = 216; + ivar4 = 216; + ivar5 = 127; + if (arg0 == -1) { + return newstruct cs2func_script_4909_struct(0, 0); + } + ivar6 = extractX(arg0); + if ((ivar6 > ivar5) || (ivar6 < 0)) { + return newstruct cs2func_script_4909_struct(-1, -1); + } + ivar7 = subtract(ivar5, extractY(arg0)); + if ((ivar7 > 127) || (ivar7 < 0)) { + return newstruct cs2func_script_4909_struct(-1, -1); + } + ivar1 = divide(multiply(ivar6, ivar3), ivar5); + ivar2 = divide(multiply(ivar7, ivar4), ivar5); + return newstruct cs2func_script_4909_struct(ivar1, ivar2); +} diff --git a/dumps/scripts/491.cs2 b/dumps/scripts/491.cs2 new file mode 100644 index 0000000..4e45dcc --- /dev/null +++ b/dumps/scripts/491.cs2 @@ -0,0 +1,16 @@ +void script_491(int arg0) { + switch (arg0) { + case 66519136: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(1015,100)); + break; + case 66519130: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(1015,92)); + break; + case 66519124: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(1015,86)); + break; + case 66519118: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(1015,80)); + } + return; +} diff --git a/dumps/scripts/4910.cs2 b/dumps/scripts/4910.cs2 new file mode 100644 index 0000000..78a643f --- /dev/null +++ b/dumps/scripts/4910.cs2 @@ -0,0 +1,35 @@ +void script_4910(int arg0) { + int ivar1; + int ivar2; + int ivar3; + ivar1 = 0; + ivar2 = 24; + ivar3 = 24; + if (getWidgetActualWidth(new WidgetPointer(arg0)) < ivar2) { + setWidgetSize(ivar2, getWidgetActualHeight(new WidgetPointer(arg0)), 0, 0, new WidgetPointer(arg0)); + } + if (getWidgetActualHeight(new WidgetPointer(arg0)) < ivar3) { + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg0)), ivar3, 0, 0, new WidgetPointer(arg0)); + } + deleteAllExtraChilds(new WidgetPointer(arg0)); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 1, 1); + setWidgetSize(ivar2, ivar3, 0, 0); + setWidgetSprite(7599); + ivar1 = getExtraChildGap(new WidgetPointer(arg0)); + createExtraChild(new WidgetPointer(arg0), 5, ivar1); + setWidgetPosition(0, 0, 1, 1); + setWidgetSize(ivar2, ivar3, 0, 0); + setWidgetSprite(7600); + setScriptCallOnMouseEntered(4410, new WidgetPointer(arg0), ivar1, 0, "Iii"); + setScriptCallOnMouseExit(4410, new WidgetPointer(arg0), ivar1, 1, "Iii"); + cs2method2103(255); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 1, 1); + setWidgetSize(ivar2, ivar3, 0, 0); + setWidgetSprite(7601); + setScriptCallOnMousePressed(4207, new WidgetPointer(-32768,3), 0, "Ii"); + setScriptCallOnMouseReleased(4207, new WidgetPointer(-32768,3), 1, "Ii"); + cs2method2103(255); + return; +} diff --git a/dumps/scripts/4911.cs2 b/dumps/scripts/4911.cs2 new file mode 100644 index 0000000..bf3f398 --- /dev/null +++ b/dumps/scripts/4911.cs2 @@ -0,0 +1,8 @@ +void script_4911() { + setWidgetIsHidden(true, new WidgetPointer(1092,210)); + setWidgetIsHidden(false, new WidgetPointer(1092,209)); + script_4905(); + script_4907(); + script_4853(); + return; +} diff --git a/dumps/scripts/4912.cs2 b/dumps/scripts/4912.cs2 new file mode 100644 index 0000000..a67f467 --- /dev/null +++ b/dumps/scripts/4912.cs2 @@ -0,0 +1,8 @@ +void script_4912() { + setWidgetIsHidden(true, new WidgetPointer(1092,209)); + setWidgetIsHidden(false, new WidgetPointer(1092,210)); + script_4905(); + script_4907(); + script_4853(); + return; +} diff --git a/dumps/scripts/4913.cs2 b/dumps/scripts/4913.cs2 new file mode 100644 index 0000000..741d765 --- /dev/null +++ b/dumps/scripts/4913.cs2 @@ -0,0 +1,20 @@ +void script_4913() { + script_4407(71565508, 1, 179); + script_4407(71566229, 1, 179); + script_4407(71566230, 1, 179); + script_4407(71566231, 1, 179); + script_4407(71566232, 1, 179); + script_4407(71566233, 1, 179); + script_4407(71566234, 1, 179); + script_4407(71566235, 1, 179); + script_4407(71566236, 1, 179); + script_4407(71566237, 1, 179); + script_4407(71566238, 1, 179); + script_4407(71566239, 1, 179); + script_4407(71566240, 1, 179); + script_4407(71566241, 1, 179); + script_4407(71566242, 1, 179); + script_4407(71566243, 1, 179); + script_4407(71566244, 1, 179); + return; +} diff --git a/dumps/scripts/4914.cs2 b/dumps/scripts/4914.cs2 new file mode 100644 index 0000000..317f94e --- /dev/null +++ b/dumps/scripts/4914.cs2 @@ -0,0 +1,369 @@ +string script_4914(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + string svar0; + ivar1 = script_4824(arg0); + svar0 = ""; + ivar2 = 0; + ivar3 = 0; + ivar4 = 0; + switch (arg0) { + case 21: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 22: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 23: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 24: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 25: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 26: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 27: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 28: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 31: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 32: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 33: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 34: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 35: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 41: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 42: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 43: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 44: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 45: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 51: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 100: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 101: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 102: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 103: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 104: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 105: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 106: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 107: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 108: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 109: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 110: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 111: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 112: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 113: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + if (ivar3 <= 0) { + return "empty customisation"; + } + ivar5 = cs2method_3408(105, 103, 4043, ivar3); + if (ivar5 == -1) { + return ""; + } + ivar6 = cs2method_3408(105, 103, ivar5, ivar2); + if (ivar6 == -1) { + return ""; + } + ivar7 = cs2method_3408(105, 103, ivar6, 1); + if (ivar7 == -1) { + return ""; + } + ivar8 = cs2method_3408(105, 74, ivar7, ivar4); + if (ivar8 == -1) { + return ""; + } + svar0 = getOtherCommonData(ivar8, 1566); + return svar0; +} diff --git a/dumps/scripts/4915.cs2 b/dumps/scripts/4915.cs2 new file mode 100644 index 0000000..99e0a00 --- /dev/null +++ b/dumps/scripts/4915.cs2 @@ -0,0 +1,6 @@ +void script_4915() { + setScriptCallOnGameloop(4916, "", new WidgetPointer(1092,319)); + script_4993(); + script_4853(); + return; +} diff --git a/dumps/scripts/4916.cs2 b/dumps/scripts/4916.cs2 new file mode 100644 index 0000000..e43b74e --- /dev/null +++ b/dumps/scripts/4916.cs2 @@ -0,0 +1,7 @@ +void script_4916() { + if (citadelConfigsInitialized()) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(1092,319)); + script_4917(); + } + return; +} diff --git a/dumps/scripts/4917.cs2 b/dumps/scripts/4917.cs2 new file mode 100644 index 0000000..b754bba --- /dev/null +++ b/dumps/scripts/4917.cs2 @@ -0,0 +1,16 @@ +void script_4917() { + setScriptCallOnCitadelConfigChange(4918, "", new WidgetPointer(1092,319)); + if (citadelConfigsInitialized()) { + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + messageType0("Clan stronghold information not yet available."); + return; +} diff --git a/dumps/scripts/4918.cs2 b/dumps/scripts/4918.cs2 new file mode 100644 index 0000000..e20f635 --- /dev/null +++ b/dumps/scripts/4918.cs2 @@ -0,0 +1,23 @@ +void script_4918() { + if (citadelConfigsInitialized()) { + script_4919(); + script_4900(); + script_4905(); + script_4907(); + script_5012(); + script_4895(); + script_4864(); + script_4994(); + /* + mgi.tools.jagdecs2.DecompilerException: No documentation for:CALL_CS2 4889 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:178) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + script_675(); + return; +} diff --git a/dumps/scripts/4919.cs2 b/dumps/scripts/4919.cs2 new file mode 100644 index 0000000..7096348 --- /dev/null +++ b/dumps/scripts/4919.cs2 @@ -0,0 +1,32 @@ +void script_4919() { + int ivar0; + ivar0 = 0; + if (citadelConfigsInitialized()) { + if (bitconfig_9550 > 0) { + if (isWidgetHidden(new WidgetPointer(1092,259))) { + script_4989(script_4948(bitconfig_9550)); + } + } else { + script_5007(); + script_4935(); + script_4905(); + script_4907(); + script_5012(); + script_4895(); + script_4864(); + script_4994(); + /* + mgi.tools.jagdecs2.DecompilerException: No documentation for:CALL_CS2 4889 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:178) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + script_4853(); + return; + } + return; +} diff --git a/dumps/scripts/492.cs2 b/dumps/scripts/492.cs2 new file mode 100644 index 0000000..8415e77 --- /dev/null +++ b/dumps/scripts/492.cs2 @@ -0,0 +1,16 @@ +void script_492(int arg0) { + switch (arg0) { + case 66519136: + setWidgetRGB(new Color(230, 202, 152), new WidgetPointer(1015,100)); + break; + case 66519130: + setWidgetRGB(new Color(230, 202, 152), new WidgetPointer(1015,92)); + break; + case 66519124: + setWidgetRGB(new Color(230, 202, 152), new WidgetPointer(1015,86)); + break; + case 66519118: + setWidgetRGB(new Color(230, 202, 152), new WidgetPointer(1015,80)); + } + return; +} diff --git a/dumps/scripts/4920.cs2 b/dumps/scripts/4920.cs2 new file mode 100644 index 0000000..54957a6 --- /dev/null +++ b/dumps/scripts/4920.cs2 @@ -0,0 +1,39 @@ +void script_4920() { + string svar0; + string svar1; + flow_0: + svar0 = ""; + IF ((((boolean)globalint_1557) && (globalint_1558 < 6)) && (((boolean)globalint_1558) && (globalint_1559 < 20))) + GOTO flow_4 + GOTO flow_5 + flow_4: + GOTO flow_5 + flow_5: + if ((((boolean)globalint_1557) && ((boolean)globalint_1558)) && ((boolean)globalint_1559)) { + setWidgetText(new WidgetPointer(1092,1831), "Due!"); + return; + } + if (globalint_1557 > 0) { + svar0 = concat(svar0, intToStr(globalint_1557) + "d "); + } + if (globalint_1558 > 0) { + svar0 = concat(svar0, intToStr(globalint_1558) + "h "); + } + if (globalint_1559 > 0) { + svar0 = concat(svar0, intToStr(globalint_1559) + "m"); + } + setWidgetText(new WidgetPointer(1092,1831), svar0); + svar1 = ""; + if (citadelConfigsInitialized()) { + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return; +} diff --git a/dumps/scripts/4921.cs2 b/dumps/scripts/4921.cs2 new file mode 100644 index 0000000..ad970e6 --- /dev/null +++ b/dumps/scripts/4921.cs2 @@ -0,0 +1,4 @@ +void script_4921(int arg0) { + script_4922(arg0); + return; +} diff --git a/dumps/scripts/4922.cs2 b/dumps/scripts/4922.cs2 new file mode 100644 index 0000000..2862829 --- /dev/null +++ b/dumps/scripts/4922.cs2 @@ -0,0 +1,6 @@ +void script_4922(int arg0) { + if (((bitconfig_9570 != arg0) && (bitconfig_9579 != arg0)) && (bitconfig_9588 != arg0)) { + script_4942(); + } + return; +} diff --git a/dumps/scripts/4923.cs2 b/dumps/scripts/4923.cs2 new file mode 100644 index 0000000..0de206d --- /dev/null +++ b/dumps/scripts/4923.cs2 @@ -0,0 +1,4 @@ +void script_4923(int arg0) { + script_4728(arg0); + return; +} diff --git a/dumps/scripts/4924.cs2 b/dumps/scripts/4924.cs2 new file mode 100644 index 0000000..d47f111 --- /dev/null +++ b/dumps/scripts/4924.cs2 @@ -0,0 +1,4 @@ +void script_4924() { + setWidgetIsHidden(false, new WidgetPointer(908,36)); + return; +} diff --git a/dumps/scripts/4925.cs2 b/dumps/scripts/4925.cs2 new file mode 100644 index 0000000..62823af --- /dev/null +++ b/dumps/scripts/4925.cs2 @@ -0,0 +1,4 @@ +void script_4925() { + script_4926(); + return; +} diff --git a/dumps/scripts/4926.cs2 b/dumps/scripts/4926.cs2 new file mode 100644 index 0000000..aab4e88 --- /dev/null +++ b/dumps/scripts/4926.cs2 @@ -0,0 +1,10 @@ +void script_4926() { + bitconfig_9552 = 0; + script_4944(); + script_4933(); + setWidgetIsHidden(false, new WidgetPointer(1092,301)); + setWidgetIsHidden(false, new WidgetPointer(1092,258)); + script_4899(0); + setWidgetIsHidden(false, new WidgetPointer(1092,299)); + return; +} diff --git a/dumps/scripts/4927.cs2 b/dumps/scripts/4927.cs2 new file mode 100644 index 0000000..16d093d --- /dev/null +++ b/dumps/scripts/4927.cs2 @@ -0,0 +1,4 @@ +void script_4927() { + script_4928(); + return; +} diff --git a/dumps/scripts/4928.cs2 b/dumps/scripts/4928.cs2 new file mode 100644 index 0000000..26278ff --- /dev/null +++ b/dumps/scripts/4928.cs2 @@ -0,0 +1,9 @@ +void script_4928() { + script_4944(); + script_4933(); + bitconfig_9552 = 1; + script_4899(1); + setWidgetIsHidden(false, new WidgetPointer(1092,302)); + setWidgetIsHidden(false, new WidgetPointer(1092,259)); + return; +} diff --git a/dumps/scripts/4929.cs2 b/dumps/scripts/4929.cs2 new file mode 100644 index 0000000..2bc0dee --- /dev/null +++ b/dumps/scripts/4929.cs2 @@ -0,0 +1,4 @@ +void script_4929() { + script_4930(); + return; +} diff --git a/dumps/scripts/493.cs2 b/dumps/scripts/493.cs2 new file mode 100644 index 0000000..f77a589 --- /dev/null +++ b/dumps/scripts/493.cs2 @@ -0,0 +1,128 @@ +void script_493(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + flow_0: + ivar2 = 0; + ivar3 = 0; + ivar4 = -1; + SWITCH (arg0) { + case 66519098: + GOTO flow_1 + case 66519100: + GOTO flow_2 + case 66519102: + GOTO flow_3 + case 66519104: + GOTO flow_4 + case 66519108: + GOTO flow_5 + case 66519110: + GOTO flow_6 + case 66519112: + GOTO flow_7 + case 66519114: + GOTO flow_8 + case 66519106: + GOTO flow_9 + } + return; + flow_1: + ivar2 = 1; + GOTO flow_10 + flow_2: + ivar2 = 2; + GOTO flow_10 + flow_3: + ivar2 = 3; + GOTO flow_10 + flow_4: + ivar2 = 4; + GOTO flow_10 + flow_5: + ivar2 = 5; + GOTO flow_10 + flow_6: + ivar2 = 6; + GOTO flow_10 + flow_7: + ivar2 = 7; + GOTO flow_10 + flow_8: + ivar2 = 8; + GOTO flow_10 + flow_9: + ivar2 = 9; + flow_10: + if (((boolean)arg1)) { + ivar3 = 16777215; + } else { + ivar3 = 16750623; + } + if (((bitconfig_7539 != ivar2) && (bitconfig_7540 != ivar2)) && ((bitconfig_7541 != ivar2) && (bitconfig_7542 != ivar2))) { + setWidgetRGB(new Color(ivar3), new WidgetPointer(arg0)); + if (((boolean)arg1)) { + ivar4 = script_488(ivar2); + if (ivar4 != -1) { + setWidgetIsHidden(true, new WidgetPointer(1015,49)); + setWidgetIsHidden(false, new WidgetPointer(1015,50)); + setWidgetIsHidden(false, new WidgetPointer(1015,51)); + setWidgetIsHidden(false, new WidgetPointer(1015,52)); + setWidgetIsHidden(false, new WidgetPointer(1015,53)); + setWidgetIsHidden(false, new WidgetPointer(1015,54)); + setWidgetText(new WidgetPointer(1015,51), getOtherCommonData(ivar4, 1150)); + setWidgetSprite(getOtherCommonData(ivar4, 1153), new WidgetPointer(1015,50)); + setWidgetText(new WidgetPointer(1015,52), getOtherCommonData(ivar4, 1151)); + setWidgetText(new WidgetPointer(1015,53), concat("Cooldown: ", intToStr(getOtherCommonData(ivar4, 1155)))); + setWidgetText(new WidgetPointer(1015,54), concat("Cost: ", intToStr(getOtherCommonData(ivar4, 1154)))); + } + } else { + flow_21: + SWITCH (bitconfig_7515) { + case 1: + GOTO flow_22 + case 2: + GOTO flow_23 + case 3: + GOTO flow_24 + case 4: + GOTO flow_25 + } + ivar4 = -1; + GOTO flow_26 + flow_22: + ivar4 = script_488(bitconfig_7539); + GOTO flow_26 + flow_23: + ivar4 = script_488(bitconfig_7540); + GOTO flow_26 + flow_24: + ivar4 = script_488(bitconfig_7541); + GOTO flow_26 + flow_25: + ivar4 = script_488(bitconfig_7542); + flow_26: + if (ivar4 == -1) { + setWidgetIsHidden(false, new WidgetPointer(1015,49)); + setWidgetIsHidden(true, new WidgetPointer(1015,50)); + setWidgetIsHidden(true, new WidgetPointer(1015,51)); + setWidgetIsHidden(true, new WidgetPointer(1015,52)); + setWidgetIsHidden(true, new WidgetPointer(1015,53)); + setWidgetIsHidden(true, new WidgetPointer(1015,54)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1015,49)); + setWidgetIsHidden(false, new WidgetPointer(1015,50)); + setWidgetIsHidden(false, new WidgetPointer(1015,51)); + setWidgetIsHidden(false, new WidgetPointer(1015,52)); + setWidgetIsHidden(false, new WidgetPointer(1015,53)); + setWidgetIsHidden(false, new WidgetPointer(1015,54)); + setWidgetText(new WidgetPointer(1015,51), getOtherCommonData(ivar4, 1150)); + setWidgetSprite(getOtherCommonData(ivar4, 1153), new WidgetPointer(1015,50)); + setWidgetText(new WidgetPointer(1015,52), getOtherCommonData(ivar4, 1151)); + setWidgetText(new WidgetPointer(1015,53), concat("Cooldown: ", intToStr(getOtherCommonData(ivar4, 1155)))); + setWidgetText(new WidgetPointer(1015,54), concat("Cost: ", intToStr(getOtherCommonData(ivar4, 1154)))); + } + } + } + return; +} diff --git a/dumps/scripts/4930.cs2 b/dumps/scripts/4930.cs2 new file mode 100644 index 0000000..a263a34 --- /dev/null +++ b/dumps/scripts/4930.cs2 @@ -0,0 +1,10 @@ +void script_4930() { + script_4944(); + script_4933(); + bitconfig_9552 = 2; + script_4899(2); + setWidgetIsHidden(false, new WidgetPointer(1092,303)); + setWidgetIsHidden(false, new WidgetPointer(1092,260)); + script_4849(); + return; +} diff --git a/dumps/scripts/4931.cs2 b/dumps/scripts/4931.cs2 new file mode 100644 index 0000000..b916452 --- /dev/null +++ b/dumps/scripts/4931.cs2 @@ -0,0 +1,4 @@ +void script_4931() { + script_4932(); + return; +} diff --git a/dumps/scripts/4932.cs2 b/dumps/scripts/4932.cs2 new file mode 100644 index 0000000..7719bda --- /dev/null +++ b/dumps/scripts/4932.cs2 @@ -0,0 +1,7 @@ +void script_4932() { + script_4944(); + script_4933(); + setWidgetIsHidden(false, new WidgetPointer(1092,304)); + setWidgetIsHidden(false, new WidgetPointer(1092,256)); + return; +} diff --git a/dumps/scripts/4933.cs2 b/dumps/scripts/4933.cs2 new file mode 100644 index 0000000..93abb60 --- /dev/null +++ b/dumps/scripts/4933.cs2 @@ -0,0 +1,15 @@ +void script_4933() { + setWidgetIsHidden(true, new WidgetPointer(1092,299)); + setWidgetIsHidden(true, new WidgetPointer(1092,301)); + setWidgetIsHidden(true, new WidgetPointer(1092,302)); + setWidgetIsHidden(true, new WidgetPointer(1092,303)); + setWidgetIsHidden(true, new WidgetPointer(1092,304)); + setWidgetIsHidden(true, new WidgetPointer(1092,258)); + setWidgetIsHidden(true, new WidgetPointer(1092,259)); + setWidgetIsHidden(true, new WidgetPointer(1092,260)); + setWidgetIsHidden(true, new WidgetPointer(1092,256)); + setWidgetIsHidden(true, new WidgetPointer(1092,212)); + setWidgetIsHidden(true, new WidgetPointer(1092,217)); + setWidgetIsHidden(true, new WidgetPointer(1092,216)); + return; +} diff --git a/dumps/scripts/4934.cs2 b/dumps/scripts/4934.cs2 new file mode 100644 index 0000000..cc35a85 --- /dev/null +++ b/dumps/scripts/4934.cs2 @@ -0,0 +1,4 @@ +void script_4934() { + script_4935(); + return; +} diff --git a/dumps/scripts/4935.cs2 b/dumps/scripts/4935.cs2 new file mode 100644 index 0000000..383a63c --- /dev/null +++ b/dumps/scripts/4935.cs2 @@ -0,0 +1,7 @@ +void script_4935() { + int ivar0; + ivar0 = 71565520; + setScriptCallOnGameloop(4938, 1, "i", new WidgetPointer(ivar0)); + script_5220(); + return; +} diff --git a/dumps/scripts/4936.cs2 b/dumps/scripts/4936.cs2 new file mode 100644 index 0000000..bfcc8c3 --- /dev/null +++ b/dumps/scripts/4936.cs2 @@ -0,0 +1,4 @@ +void script_4936() { + script_4937(); + return; +} diff --git a/dumps/scripts/4937.cs2 b/dumps/scripts/4937.cs2 new file mode 100644 index 0000000..5457ef1 --- /dev/null +++ b/dumps/scripts/4937.cs2 @@ -0,0 +1,7 @@ +void script_4937() { + int ivar0; + ivar0 = 71565520; + setScriptCallOnGameloop(4938, 0, "i", new WidgetPointer(ivar0)); + script_5220(); + return; +} diff --git a/dumps/scripts/4938.cs2 b/dumps/scripts/4938.cs2 new file mode 100644 index 0000000..ce3cda8 --- /dev/null +++ b/dumps/scripts/4938.cs2 @@ -0,0 +1,30 @@ +void script_4938(int arg0) { + int ivar1; + int ivar2; + int ivar3; + ivar1 = 0; + ivar2 = 0; + ivar3 = 71565520; + if (((boolean)arg0) && ((boolean)bitconfig_9552)) { + ivar1 = add(getWidgetActualX(new WidgetPointer(ivar3)), 12); + ivar2 = 0; + ivar1 = min(ivar1, ivar2); + if (isWidgetHidden(new WidgetPointer(1092,260))) { + ivar1 = max(ivar1, -226); + } + } else { + ivar1 = subtract(getWidgetActualX(new WidgetPointer(ivar3)), 12); + if (isWidgetHidden(new WidgetPointer(1092,260))) { + ivar2 = -295; + } else { + ivar2 = -226; + } + ivar1 = max(ivar1, ivar2); + } + setWidgetPosition(ivar1, getWidgetActualY(new WidgetPointer(ivar3)), 0, 0, new WidgetPointer(ivar3)); + if (ivar1 == ivar2) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(ivar3)); + script_5220(); + } + return; +} diff --git a/dumps/scripts/4939.cs2 b/dumps/scripts/4939.cs2 new file mode 100644 index 0000000..0a4b5c0 --- /dev/null +++ b/dumps/scripts/4939.cs2 @@ -0,0 +1,4 @@ +void script_4939() { + script_4940(); + return; +} diff --git a/dumps/scripts/494.cs2 b/dumps/scripts/494.cs2 new file mode 100644 index 0000000..fbd3bc7 --- /dev/null +++ b/dumps/scripts/494.cs2 @@ -0,0 +1,8 @@ +void script_494(int arg0,int arg1) { + if (((boolean)arg1)) { + setWidgetSprite(786, new WidgetPointer(arg0)); + } else { + setWidgetSprite(785, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/4940.cs2 b/dumps/scripts/4940.cs2 new file mode 100644 index 0000000..f4a4687 --- /dev/null +++ b/dumps/scripts/4940.cs2 @@ -0,0 +1,7 @@ +void script_4940() { + int ivar0; + ivar0 = 71566040; + setScriptCallOnGameloop(4943, 1, "i", new WidgetPointer(ivar0)); + script_5220(); + return; +} diff --git a/dumps/scripts/4941.cs2 b/dumps/scripts/4941.cs2 new file mode 100644 index 0000000..7c2a63b --- /dev/null +++ b/dumps/scripts/4941.cs2 @@ -0,0 +1,4 @@ +void script_4941() { + script_4942(); + return; +} diff --git a/dumps/scripts/4942.cs2 b/dumps/scripts/4942.cs2 new file mode 100644 index 0000000..e8e7cce --- /dev/null +++ b/dumps/scripts/4942.cs2 @@ -0,0 +1,7 @@ +void script_4942() { + int ivar0; + ivar0 = 71566040; + setScriptCallOnGameloop(4943, 0, "i", new WidgetPointer(ivar0)); + script_5220(); + return; +} diff --git a/dumps/scripts/4943.cs2 b/dumps/scripts/4943.cs2 new file mode 100644 index 0000000..5c4574b --- /dev/null +++ b/dumps/scripts/4943.cs2 @@ -0,0 +1,23 @@ +void script_4943(int arg0) { + int ivar1; + int ivar2; + int ivar3; + ivar1 = 0; + ivar2 = 0; + ivar3 = 71566040; + if (((boolean)arg0) && (bitconfig_9552 == 2)) { + ivar1 = add(getWidgetActualX(new WidgetPointer(ivar3)), 12); + ivar2 = 156; + } else { + ivar1 = subtract(getWidgetActualX(new WidgetPointer(ivar3)), 12); + ivar2 = -150; + } + ivar1 = max(ivar1, -150); + ivar1 = min(ivar1, 156); + setWidgetPosition(ivar1, getWidgetActualY(new WidgetPointer(ivar3)), 0, 0, new WidgetPointer(ivar3)); + if (ivar1 == ivar2) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(ivar3)); + script_5220(); + } + return; +} diff --git a/dumps/scripts/4944.cs2 b/dumps/scripts/4944.cs2 new file mode 100644 index 0000000..26a365d --- /dev/null +++ b/dumps/scripts/4944.cs2 @@ -0,0 +1,6 @@ +void script_4944() { + script_4935(); + script_4940(); + script_5220(); + return; +} diff --git a/dumps/scripts/4945.cs2 b/dumps/scripts/4945.cs2 new file mode 100644 index 0000000..6863669 --- /dev/null +++ b/dumps/scripts/4945.cs2 @@ -0,0 +1,14 @@ +int script_4945(int arg0) { + if (citadelConfigsInitialized()) { + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return -1; +} diff --git a/dumps/scripts/4946.cs2 b/dumps/scripts/4946.cs2 new file mode 100644 index 0000000..52e2171 --- /dev/null +++ b/dumps/scripts/4946.cs2 @@ -0,0 +1,127 @@ +int script_4946(int arg0) { + if (citadelConfigsInitialized()) { + switch (arg0) { + case 1: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 2: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 3: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 4: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 5: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 6: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 7: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 8: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 9: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 10: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 11: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 12: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + } + return -1; +} diff --git a/dumps/scripts/4947.cs2 b/dumps/scripts/4947.cs2 new file mode 100644 index 0000000..965591f --- /dev/null +++ b/dumps/scripts/4947.cs2 @@ -0,0 +1,35 @@ +int script_4947(int arg0) { + switch (arg0) { + case 1: + return 1; + case 2: + return 1; + case 3: + return 1; + case 4: + return 1; + case 5: + return 2; + case 6: + return 3; + case 7: + return 4; + case 8: + return 5; + case 9: + return 6; + case 10: + return 7; + case 11: + return 8; + case 12: + return 9; + case 13: + return 10; + case 14: + return 11; + case 15: + return 12; + } + return -1; +} diff --git a/dumps/scripts/4948.cs2 b/dumps/scripts/4948.cs2 new file mode 100644 index 0000000..62f3419 --- /dev/null +++ b/dumps/scripts/4948.cs2 @@ -0,0 +1,97 @@ +int script_4948(int arg0) { + int ivar1; + ivar1 = script_4951(arg0); + if (citadelConfigsInitialized()) { + if (((boolean)ivar1)) { + return 1; + } + if (ivar1 == 2) { + return 2; + } + if (ivar1 == 3) { + return 3; + } + if (ivar1 == 4) { + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + if ((ivar1 == 5) || (ivar1 == 6)) { + switch (arg0) { + case 16: + return 16; + case 17: + return 17; + case 18: + return 18; + case 19: + return 19; + case 20: + return 20; + case 21: + return 21; + case 22: + return 22; + case 23: + return 23; + case 24: + return 24; + case 25: + return 25; + case 26: + return 26; + case 27: + return 27; + case 28: + return 28; + case 29: + return 29; + case 30: + return 30; + case 31: + return 31; + case 32: + return 32; + case 33: + return 33; + case 34: + return 34; + case 35: + return 35; + case 36: + return 36; + case 37: + return 40; + case 38: + return 38; + case 39: + return 39; + case 40: + return 40; + case 41: + return 41; + case 42: + return 42; + case 43: + return 43; + case 44: + return 44; + case 45: + return 45; + case 46: + return 46; + case 47: + return 47; + case 48: + return 48; + } + } + } + return -1; +} diff --git a/dumps/scripts/4949.cs2 b/dumps/scripts/4949.cs2 new file mode 100644 index 0000000..4a93765 --- /dev/null +++ b/dumps/scripts/4949.cs2 @@ -0,0 +1,423 @@ +int script_4949(int arg0) { + if (citadelConfigsInitialized()) { + switch (arg0) { + case 1: + return 17; + case 2: + return 18; + case 3: + return 19; + case 4: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 5: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 6: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 7: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 8: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 9: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 10: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 11: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 12: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 13: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 14: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 15: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 16: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 17: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 18: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 19: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 20: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 21: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 22: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 23: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 24: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 25: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 26: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 27: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 28: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 29: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 30: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 31: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 32: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 33: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 34: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 35: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 36: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 37: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 40: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 38: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 39: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 41: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 42: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 43: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 44: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + } + return -1; +} diff --git a/dumps/scripts/495.cs2 b/dumps/scripts/495.cs2 new file mode 100644 index 0000000..6420e93 --- /dev/null +++ b/dumps/scripts/495.cs2 @@ -0,0 +1,64 @@ +void script_495(int arg0) { + int ivar1; + flow_0: + ivar1 = 0; + SWITCH (arg0) { + case 66519184: + GOTO flow_1 + case 66519186: + GOTO flow_2 + case 66519188: + GOTO flow_3 + case 66519190: + GOTO flow_4 + case 66519192: + GOTO flow_5 + case 66519194: + GOTO flow_6 + case 66519196: + GOTO flow_7 + case 66519198: + GOTO flow_8 + case 66519200: + GOTO flow_9 + case 66519202: + GOTO flow_10 + } + return; + flow_1: + ivar1 = bitconfig_7520; + GOTO flow_11 + flow_2: + ivar1 = bitconfig_7521; + GOTO flow_11 + flow_3: + ivar1 = bitconfig_7526; + GOTO flow_11 + flow_4: + ivar1 = bitconfig_7527; + GOTO flow_11 + flow_5: + ivar1 = bitconfig_7530; + GOTO flow_11 + flow_6: + ivar1 = bitconfig_7531; + GOTO flow_11 + flow_7: + ivar1 = bitconfig_7532; + GOTO flow_11 + flow_8: + ivar1 = bitconfig_7533; + GOTO flow_11 + flow_9: + ivar1 = bitconfig_7534; + GOTO flow_11 + flow_10: + ivar1 = bitconfig_7535; + flow_11: + if (((boolean)ivar1)) { + setWidgetRGB(new Color(88, 80, 66), new WidgetPointer(arg0)); + } else { + setWidgetRGB(new Color(230, 202, 152), new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/4950.cs2 b/dumps/scripts/4950.cs2 new file mode 100644 index 0000000..67621f0 --- /dev/null +++ b/dumps/scripts/4950.cs2 @@ -0,0 +1,59 @@ +int script_4950(int arg0) { + switch (arg0) { + case 1: + return 1; + case 2: + return 2; + case 3: + return 3; + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + return 4; + case 35: + case 38: + case 39: + case 36: + case 37: + case 42: + case 43: + case 40: + case 41: + case 46: + case 47: + case 44: + case 45: + case 48: + return 6; + case 17: + case 16: + case 19: + case 18: + case 21: + case 20: + case 23: + case 22: + case 25: + case 24: + case 27: + case 26: + case 29: + case 28: + case 31: + case 30: + case 34: + case 32: + case 33: + return 5; + } + return 0; +} diff --git a/dumps/scripts/4951.cs2 b/dumps/scripts/4951.cs2 new file mode 100644 index 0000000..98c3f8c --- /dev/null +++ b/dumps/scripts/4951.cs2 @@ -0,0 +1,54 @@ +int script_4951(int arg0) { + switch (arg0) { + case 17: + return 1; + case 18: + return 2; + case 19: + return 3; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + return 4; + case 102: + case 103: + case 100: + case 101: + case 110: + case 111: + case 108: + case 109: + case 106: + case 107: + case 104: + case 105: + case 113: + case 112: + return 6; + case 21: + case 23: + case 22: + case 25: + case 24: + case 27: + case 26: + case 28: + case 31: + case 34: + case 35: + case 32: + case 33: + case 42: + case 43: + case 41: + case 44: + case 45: + case 51: + return 5; + } + return 0; +} diff --git a/dumps/scripts/4952.cs2 b/dumps/scripts/4952.cs2 new file mode 100644 index 0000000..c782dc6 --- /dev/null +++ b/dumps/scripts/4952.cs2 @@ -0,0 +1,157 @@ +int script_4952(int arg0) { + if (citadelConfigsInitialized()) { + switch (arg0) { + case 1: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 2: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 3: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 4: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 5: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 6: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 7: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 8: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 9: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 10: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 11: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 12: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 13: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 14: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 15: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + } + return 0; +} diff --git a/dumps/scripts/4953.cs2 b/dumps/scripts/4953.cs2 new file mode 100644 index 0000000..cfcaafb --- /dev/null +++ b/dumps/scripts/4953.cs2 @@ -0,0 +1,16 @@ +int script_4953(int arg0) { + int ivar1; + ivar1 = -1; + if (citadelConfigsInitialized()) { + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return ivar1; +} diff --git a/dumps/scripts/4954.cs2 b/dumps/scripts/4954.cs2 new file mode 100644 index 0000000..5a2b6f0 --- /dev/null +++ b/dumps/scripts/4954.cs2 @@ -0,0 +1,25 @@ +int script_4954(int arg0) { + switch (arg0) { + case 17: + return 2031; + case 18: + return 2032; + case 19: + return 2033; + case 1: + return 2034; + case 2: + return 2035; + case 3: + return 2037; + case 4: + return 2038; + case 5: + return 2039; + case 6: + return 2036; + case 7: + return 2040; + } + return -1; +} diff --git a/dumps/scripts/4955.cs2 b/dumps/scripts/4955.cs2 new file mode 100644 index 0000000..67761e1 --- /dev/null +++ b/dumps/scripts/4955.cs2 @@ -0,0 +1,25 @@ +int script_4955(int arg0) { + switch (arg0) { + case 17: + return 2021; + case 18: + return 2022; + case 19: + return 2023; + case 1: + return 2024; + case 2: + return 2025; + case 3: + return 2027; + case 4: + return 2028; + case 5: + return 2029; + case 6: + return 2026; + case 7: + return 2030; + } + return -1; +} diff --git a/dumps/scripts/4956.cs2 b/dumps/scripts/4956.cs2 new file mode 100644 index 0000000..988638a --- /dev/null +++ b/dumps/scripts/4956.cs2 @@ -0,0 +1,13 @@ +cs2func_script_4956_struct(5,0,0) script_4956(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + ivar1 = script_4948(arg0); + ivar2 = script_4959(ivar1); + ivar3 = script_4980(arg0); + ivar4 = script_4954(arg0); + ivar5 = script_4955(arg0); + return newstruct cs2func_script_4956_struct(ivar1, ivar2, ivar4, ivar5, ivar3); +} diff --git a/dumps/scripts/4957.cs2 b/dumps/scripts/4957.cs2 new file mode 100644 index 0000000..7cf872f --- /dev/null +++ b/dumps/scripts/4957.cs2 @@ -0,0 +1,11 @@ +cs2func_script_4957_struct(4,0,0) script_4957(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + ivar1 = script_4960(arg0); + ivar2 = script_4980(arg0); + ivar3 = script_4954(arg0); + ivar4 = script_4955(arg0); + return newstruct cs2func_script_4957_struct(ivar1, ivar3, ivar4, ivar2); +} diff --git a/dumps/scripts/4958.cs2 b/dumps/scripts/4958.cs2 new file mode 100644 index 0000000..64f8ad7 --- /dev/null +++ b/dumps/scripts/4958.cs2 @@ -0,0 +1,13 @@ +cs2func_script_4958_struct(5,0,0) script_4958(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + ivar1 = script_4949(arg0); + ivar2 = script_4959(arg0); + ivar3 = script_4980(ivar1); + ivar4 = script_4954(ivar1); + ivar5 = script_4955(ivar1); + return newstruct cs2func_script_4958_struct(ivar1, ivar2, ivar4, ivar5, ivar3); +} diff --git a/dumps/scripts/4959.cs2 b/dumps/scripts/4959.cs2 new file mode 100644 index 0000000..88d5ff8 --- /dev/null +++ b/dumps/scripts/4959.cs2 @@ -0,0 +1,487 @@ +int script_4959(int arg0) { + if (citadelConfigsInitialized()) { + switch (arg0) { + case 1: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 2: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 3: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 4: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 5: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 6: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 7: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 8: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 9: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 10: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 11: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 12: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 13: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 14: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 15: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 16: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 17: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 18: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 19: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 20: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 21: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 22: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 23: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 24: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 25: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 26: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 27: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 28: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 29: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 30: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 31: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 32: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 33: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 34: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 35: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 36: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 37: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 38: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 39: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 40: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 41: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 42: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 43: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 44: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 45: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 46: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 47: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 48: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + } + return 0; +} diff --git a/dumps/scripts/496.cs2 b/dumps/scripts/496.cs2 new file mode 100644 index 0000000..334eef7 --- /dev/null +++ b/dumps/scripts/496.cs2 @@ -0,0 +1,4 @@ +void script_496(int arg0) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/4960.cs2 b/dumps/scripts/4960.cs2 new file mode 100644 index 0000000..d6a50da --- /dev/null +++ b/dumps/scripts/4960.cs2 @@ -0,0 +1,12 @@ +int script_4960(int arg0) { + int ivar1; + ivar1 = 0; + if (citadelConfigsInitialized()) { + ivar1 = script_4948(arg0); + if (ivar1 <= 0) { + return 0; + } + return script_4959(ivar1); + } + return 0; +} diff --git a/dumps/scripts/4961.cs2 b/dumps/scripts/4961.cs2 new file mode 100644 index 0000000..6d33656 --- /dev/null +++ b/dumps/scripts/4961.cs2 @@ -0,0 +1,105 @@ +int script_4961(int arg0,int arg1) { + if (((boolean)arg1)) { + switch (arg0) { + case 1: + return 1; + case 2: + return 3; + case 3: + return 2; + case 4: + return 4; + case 5: + return 5; + case 6: + return 6; + case 7: + return 7; + case 8: + return 8; + case 9: + return 9; + case 10: + return 10; + case 11: + return 11; + case 12: + return 12; + case 13: + return 13; + case 14: + return 14; + case 15: + return 15; + } + } else if (arg1 == 2) { + switch (arg0) { + case 1: + return 301; + case 2: + return 303; + case 3: + return 302; + case 4: + return 304; + case 5: + return 305; + case 6: + return 306; + case 7: + return 307; + case 8: + return 308; + case 9: + return 309; + case 10: + return 310; + case 11: + return 311; + case 12: + return 312; + case 13: + return 313; + case 14: + return 314; + case 15: + return 315; + } + } else { + if (arg1 == 3) { + switch (arg0) { + case 1: + return 601; + case 2: + return 603; + case 3: + return 602; + case 4: + return 604; + case 5: + return 605; + case 6: + return 606; + case 7: + return 607; + case 8: + return 608; + case 9: + return 609; + case 10: + return 610; + case 11: + return 611; + case 12: + return 612; + case 13: + return 613; + case 14: + return 614; + case 15: + return 615; + } + } + } + return -1; +} diff --git a/dumps/scripts/4962.cs2 b/dumps/scripts/4962.cs2 new file mode 100644 index 0000000..933a695 --- /dev/null +++ b/dumps/scripts/4962.cs2 @@ -0,0 +1,17 @@ +int script_4962(int arg0) { + int ivar1; + ivar1 = -1; + if (citadelConfigsInitialized()) { + ivar1 = script_4971(arg0); + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return 0; +} diff --git a/dumps/scripts/4963.cs2 b/dumps/scripts/4963.cs2 new file mode 100644 index 0000000..1908670 --- /dev/null +++ b/dumps/scripts/4963.cs2 @@ -0,0 +1,25 @@ +int script_4963(int arg0) { + switch (arg0) { + case 71566050: + return 17; + case 71566061: + return 18; + case 71566072: + return 19; + case 71566083: + return 1; + case 71566094: + return 2; + case 71566105: + return 3; + case 71566116: + return 4; + case 71566127: + return 6; + case 71566138: + return 7; + case 71566150: + return 5; + } + return -1; +} diff --git a/dumps/scripts/4964.cs2 b/dumps/scripts/4964.cs2 new file mode 100644 index 0000000..1a6e979 --- /dev/null +++ b/dumps/scripts/4964.cs2 @@ -0,0 +1,101 @@ +int script_4964(int arg0) { + switch (arg0) { + case 71566682: + return 1; + case 71566675: + return 2; + case 71566668: + return 3; + case 71566584: + return 4; + case 71566591: + return 5; + case 71566598: + return 6; + case 71566605: + return 7; + case 71566612: + return 8; + case 71566619: + return 9; + case 71566626: + return 10; + case 71566633: + return 11; + case 71566640: + return 12; + case 71566647: + return 13; + case 71566654: + return 14; + case 71566661: + return 15; + case 71566689: + return 16; + case 71566695: + return 17; + case 71566701: + return 18; + case 71566707: + return 19; + case 71566713: + return 20; + case 71566719: + return 21; + case 71566726: + return 22; + case 71566732: + return 23; + case 71566738: + return 24; + case 71566744: + return 25; + case 71566750: + return 26; + case 71566756: + return 27; + case 71566762: + return 28; + case 71566768: + return 29; + case 71566774: + return 30; + case 71566780: + return 31; + case 71566786: + return 32; + case 71566792: + return 33; + case 71566798: + return 34; + case 71566805: + return 35; + case 71566821: + return 36; + case 71566813: + return 37; + case 71566829: + return 38; + case 71566837: + return 39; + case 71566845: + return 40; + case 71566853: + return 41; + case 71566861: + return 42; + case 71566869: + return 43; + case 71566877: + return 44; + case 71566885: + return 45; + case 71566893: + return 46; + case 71566901: + return 47; + case 71566909: + return 48; + } + return 0; +} diff --git a/dumps/scripts/4965.cs2 b/dumps/scripts/4965.cs2 new file mode 100644 index 0000000..4971bcc --- /dev/null +++ b/dumps/scripts/4965.cs2 @@ -0,0 +1,9 @@ +int script_4965(int arg0) { + int ivar1; + ivar1 = -1; + if (citadelConfigsInitialized()) { + ivar1 = script_4948(arg0); + return script_4959(arg0); + } + return 0; +} diff --git a/dumps/scripts/4966.cs2 b/dumps/scripts/4966.cs2 new file mode 100644 index 0000000..21d9e06 --- /dev/null +++ b/dumps/scripts/4966.cs2 @@ -0,0 +1,101 @@ +int script_4966(int arg0) { + switch (arg0) { + case 71566682: + return 1; + case 71566675: + return 2; + case 71566668: + return 3; + case 71566584: + return 4; + case 71566591: + return 5; + case 71566598: + return 6; + case 71566605: + return 7; + case 71566612: + return 8; + case 71566619: + return 9; + case 71566626: + return 10; + case 71566633: + return 11; + case 71566640: + return 12; + case 71566647: + return 13; + case 71566654: + return 14; + case 71566661: + return 15; + case 71566805: + return 35; + case 71566821: + return 36; + case 71566813: + return 37; + case 71566829: + return 38; + case 71566837: + return 39; + case 71566845: + return 40; + case 71566853: + return 41; + case 71566861: + return 42; + case 71566869: + return 43; + case 71566877: + return 44; + case 71566885: + return 45; + case 71566893: + return 46; + case 71566901: + return 47; + case 71566909: + return 48; + case 71566689: + return 16; + case 71566695: + return 17; + case 71566701: + return 18; + case 71566707: + return 19; + case 71566713: + return 20; + case 71566719: + return 21; + case 71566726: + return 22; + case 71566732: + return 23; + case 71566738: + return 24; + case 71566744: + return 25; + case 71566750: + return 26; + case 71566756: + return 27; + case 71566762: + return 28; + case 71566768: + return 29; + case 71566774: + return 30; + case 71566780: + return 31; + case 71566786: + return 32; + case 71566792: + return 33; + case 71566798: + return 34; + } + return 0; +} diff --git a/dumps/scripts/4967.cs2 b/dumps/scripts/4967.cs2 new file mode 100644 index 0000000..c92d5ef --- /dev/null +++ b/dumps/scripts/4967.cs2 @@ -0,0 +1,29 @@ +int script_4967(int arg0) { + switch (arg0) { + case 4: + return 1; + case 5: + return 2; + case 6: + return 3; + case 7: + return 4; + case 8: + return 5; + case 9: + return 6; + case 10: + return 7; + case 11: + return 8; + case 12: + return 9; + case 13: + return 10; + case 14: + return 11; + case 15: + return 12; + } + return -1; +} diff --git a/dumps/scripts/4968.cs2 b/dumps/scripts/4968.cs2 new file mode 100644 index 0000000..3a15f6f --- /dev/null +++ b/dumps/scripts/4968.cs2 @@ -0,0 +1,73 @@ +int script_4968(int arg0) { + switch (arg0) { + case 1: + return 71565525; + case 2: + return 71565526; + case 3: + return 71565527; + case 4: + return 71565496; + case 5: + return 71565497; + case 6: + return 71565498; + case 7: + return 71565499; + case 8: + return 71565500; + case 9: + return 71565501; + case 10: + return 71565502; + case 11: + return 71565503; + case 12: + return 71565504; + case 13: + return 71565505; + case 14: + return 71565506; + case 15: + return 71565507; + case 16: + return 71565478; + case 17: + return 71565479; + case 18: + return 71565480; + case 19: + return 71565481; + case 20: + return 71565482; + case 21: + return 71565483; + case 22: + return 71565484; + case 23: + return 71565485; + case 24: + return 71565486; + case 25: + return 71565487; + case 26: + return 71565488; + case 27: + return 71565489; + case 28: + return 71565490; + case 29: + return 71565491; + case 30: + return 71565492; + case 31: + return 71565493; + case 32: + return 71565494; + case 33: + return 71565495; + case 34: + return 71565530; + } + return -1; +} diff --git a/dumps/scripts/4969.cs2 b/dumps/scripts/4969.cs2 new file mode 100644 index 0000000..3e8a145 --- /dev/null +++ b/dumps/scripts/4969.cs2 @@ -0,0 +1,39 @@ +int script_4969(int arg0) { + switch (arg0) { + case 101: + return 71566240; + case 100: + return 71566241; + case 102: + return 71566242; + case 103: + return 71566243; + case 3: + return 71566244; + case 4: + return 71565508; + case 5: + return 71566229; + case 6: + return 71566230; + case 7: + return 71566231; + case 8: + return 71566232; + case 9: + return 71566233; + case 10: + return 71566234; + case 11: + return 71566235; + case 12: + return 71566236; + case 13: + return 71566237; + case 14: + return 71566238; + case 15: + return 71566239; + } + return -1; +} diff --git a/dumps/scripts/497.cs2 b/dumps/scripts/497.cs2 new file mode 100644 index 0000000..8d1b19c --- /dev/null +++ b/dumps/scripts/497.cs2 @@ -0,0 +1,57 @@ +void script_497() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + string svar0; + string svar1; + string svar2; + string svar3; + ivar0 = 0; + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + svar0 = ""; + svar1 = ""; + svar2 = ""; + svar3 = ""; + if (globalint_1367 != -1) { + ivar0 = getNpcNodemapData(globalint_1367, 1134); + if (globalint_1368 > ivar0) { + svar0 = "Movement: " + "" + intToStr(globalint_1368) + "" + "/" + intToStr(ivar0); + } else if (globalint_1368 < ivar0) { + svar0 = "Movement: " + "" + intToStr(globalint_1368) + "" + "/" + intToStr(ivar0); + } else { + svar0 = "Movement: " + intToStr(globalint_1368) + "/" + intToStr(ivar0); + } + ivar1 = getNpcNodemapData(globalint_1367, 1135); + if (globalint_1369 > ivar1) { + svar1 = "Damage: " + "" + intToStr(multiply(globalint_1369, 100)) + "" + "/" + intToStr(multiply(ivar1, 100)); + } else if (globalint_1369 < ivar1) { + svar1 = "Damage: " + "" + intToStr(multiply(globalint_1369, 100)) + "" + "/" + intToStr(multiply(ivar1, 100)); + } else { + svar1 = "Damage: " + intToStr(multiply(globalint_1369, 100)) + "/" + intToStr(multiply(ivar1, 100)); + } + ivar2 = getNpcNodemapData(globalint_1367, 1136); + if (globalint_1370 > ivar2) { + svar2 = "Health: " + "" + intToStr(multiply(globalint_1370, 100)) + "" + "/" + intToStr(multiply(ivar2, 100)); + } else if (globalint_1370 < ivar2) { + svar2 = "Health: " + "" + intToStr(multiply(globalint_1370, 100)) + "" + "/" + intToStr(multiply(ivar2, 100)); + } else { + svar2 = "Health: " + intToStr(multiply(globalint_1370, 100)) + "/" + intToStr(multiply(ivar2, 100)); + } + ivar3 = getNpcNodemapData(globalint_1367, 1137); + if (globalint_1371 > ivar3) { + svar3 = "Range: " + "" + intToStr(globalint_1371) + "" + "/" + intToStr(ivar3); + } else if (globalint_1371 < ivar3) { + svar3 = "Range: " + "" + intToStr(globalint_1371) + "" + "/" + intToStr(ivar3); + } else { + svar3 = "Range: " + intToStr(globalint_1371) + "/" + intToStr(ivar3); + } + setWidgetText(new WidgetPointer(1012,8), svar0); + setWidgetText(new WidgetPointer(1012,9), svar1); + setWidgetText(new WidgetPointer(1012,10), svar2); + setWidgetText(new WidgetPointer(1012,11), svar3); + } + return; +} diff --git a/dumps/scripts/4970.cs2 b/dumps/scripts/4970.cs2 new file mode 100644 index 0000000..e0ee2b5 --- /dev/null +++ b/dumps/scripts/4970.cs2 @@ -0,0 +1,71 @@ +int script_4970(int arg0) { + switch (arg0) { + case 21: + return 16; + case 22: + return 17; + case 23: + return 18; + case 24: + return 19; + case 25: + return 20; + case 26: + return 21; + case 27: + return 22; + case 28: + return 23; + case 31: + return 24; + case 32: + return 25; + case 33: + return 26; + case 34: + return 27; + case 35: + return 28; + case 41: + return 29; + case 42: + return 30; + case 43: + return 31; + case 44: + return 32; + case 45: + return 33; + case 51: + return 34; + case 100: + return 35; + case 101: + return 36; + case 102: + return 37; + case 103: + return 38; + case 104: + return 39; + case 105: + return 40; + case 106: + return 41; + case 107: + return 42; + case 108: + return 43; + case 109: + return 44; + case 110: + return 45; + case 111: + return 46; + case 112: + return 47; + case 113: + return 48; + } + return -1; +} diff --git a/dumps/scripts/4971.cs2 b/dumps/scripts/4971.cs2 new file mode 100644 index 0000000..fc3dc9c --- /dev/null +++ b/dumps/scripts/4971.cs2 @@ -0,0 +1,71 @@ +int script_4971(int arg0) { + switch (arg0) { + case 16: + return 21; + case 17: + return 22; + case 18: + return 23; + case 19: + return 24; + case 20: + return 25; + case 21: + return 26; + case 22: + return 27; + case 23: + return 28; + case 24: + return 31; + case 25: + return 32; + case 26: + return 33; + case 27: + return 34; + case 28: + return 35; + case 29: + return 41; + case 30: + return 42; + case 31: + return 43; + case 32: + return 44; + case 33: + return 45; + case 34: + return 51; + case 35: + return 100; + case 36: + return 101; + case 37: + return 102; + case 38: + return 103; + case 39: + return 104; + case 40: + return 105; + case 41: + return 106; + case 42: + return 107; + case 43: + return 108; + case 44: + return 109; + case 45: + return 110; + case 46: + return 111; + case 47: + return 112; + case 48: + return 113; + } + return -1; +} diff --git a/dumps/scripts/4972.cs2 b/dumps/scripts/4972.cs2 new file mode 100644 index 0000000..97d7776 --- /dev/null +++ b/dumps/scripts/4972.cs2 @@ -0,0 +1,101 @@ +int script_4972(int arg0) { + switch (arg0) { + case 1: + return 71566682; + case 2: + return 71566675; + case 3: + return 71566668; + case 4: + return 71566584; + case 5: + return 71566591; + case 6: + return 71566598; + case 7: + return 71566605; + case 8: + return 71566612; + case 9: + return 71566619; + case 10: + return 71566626; + case 11: + return 71566633; + case 12: + return 71566640; + case 13: + return 71566647; + case 14: + return 71566654; + case 15: + return 71566661; + case 16: + return 71566689; + case 17: + return 71566695; + case 18: + return 71566701; + case 19: + return 71566707; + case 20: + return 71566713; + case 21: + return 71566719; + case 22: + return 71566726; + case 23: + return 71566732; + case 24: + return 71566738; + case 25: + return 71566744; + case 26: + return 71566750; + case 27: + return 71566756; + case 28: + return 71566762; + case 29: + return 71566768; + case 30: + return 71566774; + case 31: + return 71566780; + case 32: + return 71566786; + case 33: + return 71566792; + case 34: + return 71566798; + case 35: + return 71566805; + case 36: + return 71566821; + case 37: + return 71566813; + case 38: + return 71566829; + case 39: + return 71566837; + case 40: + return 71566845; + case 41: + return 71566853; + case 42: + return 71566861; + case 43: + return 71566869; + case 44: + return 71566877; + case 45: + return 71566885; + case 46: + return 71566893; + case 47: + return 71566901; + case 48: + return 71566909; + } + return -1; +} diff --git a/dumps/scripts/4973.cs2 b/dumps/scripts/4973.cs2 new file mode 100644 index 0000000..2d437dd --- /dev/null +++ b/dumps/scripts/4973.cs2 @@ -0,0 +1,173 @@ +int script_4973(int arg0) { + int ivar1; + int ivar2; + ivar1 = 0; + ivar2 = 0; + if (citadelConfigsInitialized()) { + ivar1 = script_4949(arg0); + switch (arg0) { + case 1: + return 7431; + case 2: + return 7430; + case 3: + return 7433; + case 4: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 5: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 6: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 7: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 8: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 9: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 10: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 11: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 12: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 13: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 14: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 15: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 17: + case 16: + case 19: + case 18: + case 21: + case 20: + case 23: + case 22: + case 25: + case 24: + case 27: + case 26: + case 29: + case 28: + case 31: + case 30: + case 34: + case 32: + case 33: + return script_4974(ivar1); + case 35: + case 38: + case 39: + case 36: + case 37: + case 42: + case 43: + case 40: + case 41: + case 46: + case 47: + case 44: + case 45: + case 48: + return cs2method_3408(105, 100, 4061, ivar1); + } + } + return -1; +} diff --git a/dumps/scripts/4974.cs2 b/dumps/scripts/4974.cs2 new file mode 100644 index 0000000..ed3329c --- /dev/null +++ b/dumps/scripts/4974.cs2 @@ -0,0 +1,60 @@ +int script_4974(int arg0) { + switch (arg0) { + case 17: + return 7431; + case 18: + return 7430; + case 19: + return 7433; + case 1: + return 7422; + case 2: + return 7424; + case 3: + return 7423; + case 4: + return 7426; + case 5: + return 7427; + case 6: + return 7425; + case 7: + return 7428; + case 102: + case 103: + case 100: + case 101: + case 110: + case 111: + case 108: + case 109: + case 106: + case 107: + case 104: + case 105: + case 113: + case 112: + return cs2method_3408(105, 100, 4061, arg0); + case 21: + case 23: + case 22: + case 25: + case 24: + case 27: + case 26: + case 28: + case 31: + case 34: + case 35: + case 32: + case 33: + case 42: + case 43: + case 41: + case 44: + case 45: + case 51: + return 7434; + } + return -1; +} diff --git a/dumps/scripts/4975.cs2 b/dumps/scripts/4975.cs2 new file mode 100644 index 0000000..c7d1a47 --- /dev/null +++ b/dumps/scripts/4975.cs2 @@ -0,0 +1,12 @@ +int script_4975(int arg0) { + if ((arg0 > 0) && (arg0 < 300)) { + return 1; + } + if ((arg0 > 300) && (arg0 < 600)) { + return 2; + } + if (arg0 > 600) { + return 3; + } + return 0; +} diff --git a/dumps/scripts/4976.cs2 b/dumps/scripts/4976.cs2 new file mode 100644 index 0000000..aee0387 --- /dev/null +++ b/dumps/scripts/4976.cs2 @@ -0,0 +1,19 @@ +int script_4976(int arg0) { + switch (arg0) { + case 1: + return 100000; + case 2: + return 120000; + case 3: + return 140000; + case 4: + return 170000; + case 5: + return 200000; + case 6: + return 235000; + case 7: + return 270000; + } + return 0; +} diff --git a/dumps/scripts/4977.cs2 b/dumps/scripts/4977.cs2 new file mode 100644 index 0000000..a52eb46 --- /dev/null +++ b/dumps/scripts/4977.cs2 @@ -0,0 +1,33 @@ +int script_4977(int arg0) { + switch (arg0) { + case 35: + return 7232; + case 36: + return 7229; + case 37: + return 7072; + case 38: + return 7131; + case 39: + return 7222; + case 40: + return 7115; + case 41: + return 7238; + case 42: + return 7032; + case 43: + return 7138; + case 44: + return 7277; + case 45: + return 7262; + case 46: + return 7258; + case 47: + return 7254; + case 48: + return 7267; + } + return -1; +} diff --git a/dumps/scripts/4978.cs2 b/dumps/scripts/4978.cs2 new file mode 100644 index 0000000..50e7a44 --- /dev/null +++ b/dumps/scripts/4978.cs2 @@ -0,0 +1,127 @@ +int script_4978(int arg0) { + if (citadelConfigsInitialized()) { + switch (arg0) { + case 4: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 5: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 6: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 7: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 8: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 9: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 10: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 11: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 12: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 13: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 14: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 15: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + } + return -1; +} diff --git a/dumps/scripts/4979.cs2 b/dumps/scripts/4979.cs2 new file mode 100644 index 0000000..287a6f5 --- /dev/null +++ b/dumps/scripts/4979.cs2 @@ -0,0 +1,19 @@ +int script_4979(int arg0) { + switch (arg0) { + case 1: + return 1; + case 2: + return 2; + case 3: + return 3; + case 4: + return 3; + case 7: + return 5; + case 5: + return 5; + case 6: + return 6; + } + return 0; +} diff --git a/dumps/scripts/498.cs2 b/dumps/scripts/498.cs2 new file mode 100644 index 0000000..9445a93 --- /dev/null +++ b/dumps/scripts/498.cs2 @@ -0,0 +1,244 @@ +void script_498(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + ivar6 = 0; + ivar7 = 0; + ivar8 = 0; + ivar9 = 0; + ivar10 = 0; + ivar11 = 0; + ivar12 = 0; + ivar13 = -1; + if ((((arg0 == globalint_1372) && (arg1 == globalint_1373)) && ((arg2 == globalint_1374) && (arg3 == globalint_1375))) && ((arg4 == globalint_1376) && (arg5 == globalint_1377))) { + return; + } + setScriptCallOnGlobalConfigChange(498, globalint_1372, globalint_1373, globalint_1374, globalint_1375, globalint_1376, globalint_1377, 1372, 1373, 1374, 1375, 1376, 1377, 6, "iiiiiiY", new WidgetPointer(1012,0)); + if (globalint_1367 != -1) { + ivar6 = add(add(add(add(add(globalint_1372, globalint_1373), globalint_1374), globalint_1375), globalint_1376), globalint_1377); + if (((boolean)ivar6)) { + setWidgetIsHidden(true, new WidgetPointer(1012,14)); + setWidgetIsHidden(false, new WidgetPointer(1012,29)); + } else { + setWidgetIsHidden(false, new WidgetPointer(1012,14)); + setWidgetIsHidden(true, new WidgetPointer(1012,29)); + } + if (((boolean)ivar6)) { + setWidgetIsHidden(false, new WidgetPointer(1012,15)); + setWidgetPosition(82, getWidgetActualY(new WidgetPointer(1012,15)), 0, 0, new WidgetPointer(1012,15)); + if (((boolean)globalint_1372)) { + ivar13 = 293; + } else if (((boolean)globalint_1373)) { + ivar13 = 299; + } else if (((boolean)globalint_1374)) { + ivar13 = 305; + } else if (((boolean)globalint_1375)) { + ivar13 = 1044; + } else if (((boolean)globalint_1376)) { + ivar13 = 1045; + } else { + ivar13 = 1046; + } + setWidgetSprite(getOtherCommonData(ivar13, 1153), new WidgetPointer(1012,15)); + setScriptCallOnMouseOver(499, getOtherCommonData(ivar13, 1149), "i", new WidgetPointer(1012,15)); + setWidgetIsHidden(true, new WidgetPointer(1012,16)); + setWidgetIsHidden(true, new WidgetPointer(1012,17)); + setWidgetIsHidden(true, new WidgetPointer(1012,18)); + setWidgetIsHidden(true, new WidgetPointer(1012,19)); + } else if (ivar6 == 2) { + setWidgetIsHidden(false, new WidgetPointer(1012,15)); + setWidgetPosition(50, getWidgetActualY(new WidgetPointer(1012,15)), 0, 0, new WidgetPointer(1012,15)); + if (((boolean)globalint_1372)) { + ivar13 = 293; + } else if (((boolean)globalint_1373)) { + ivar13 = 299; + ivar8 = 1; + } else if (((boolean)globalint_1374)) { + ivar13 = 305; + ivar9 = 1; + } else if (((boolean)globalint_1375)) { + ivar13 = 1044; + ivar10 = 1; + } else { + ivar13 = 1045; + ivar11 = 1; + } + setWidgetSprite(getOtherCommonData(ivar13, 1153), new WidgetPointer(1012,15)); + setScriptCallOnMouseOver(499, getOtherCommonData(ivar13, 1149), "i", new WidgetPointer(1012,15)); + setWidgetIsHidden(false, new WidgetPointer(1012,16)); + setWidgetPosition(115, getWidgetActualY(new WidgetPointer(1012,16)), 0, 0, new WidgetPointer(1012,16)); + if (((boolean)globalint_1373) && ((boolean)ivar8)) { + ivar13 = 299; + } else if (((boolean)globalint_1374) && ((boolean)ivar9)) { + ivar13 = 305; + } else if (((boolean)globalint_1375) && ((boolean)ivar10)) { + ivar13 = 1044; + } else if (((boolean)globalint_1376) && ((boolean)ivar11)) { + ivar13 = 1045; + } else { + ivar13 = 1046; + } + setWidgetSprite(getOtherCommonData(ivar13, 1153), new WidgetPointer(1012,16)); + setScriptCallOnMouseOver(499, getOtherCommonData(ivar13, 1149), "i", new WidgetPointer(1012,16)); + setWidgetIsHidden(true, new WidgetPointer(1012,17)); + setWidgetIsHidden(true, new WidgetPointer(1012,18)); + setWidgetIsHidden(true, new WidgetPointer(1012,19)); + } else if (ivar6 == 3) { + setWidgetIsHidden(false, new WidgetPointer(1012,15)); + setWidgetPosition(30, getWidgetActualY(new WidgetPointer(1012,15)), 0, 0, new WidgetPointer(1012,15)); + if (((boolean)globalint_1372)) { + ivar13 = 293; + } else if (((boolean)globalint_1373)) { + ivar13 = 299; + ivar8 = 1; + } else if (((boolean)globalint_1374)) { + ivar13 = 305; + ivar9 = 1; + } else { + ivar13 = 1044; + ivar10 = 1; + } + setWidgetSprite(getOtherCommonData(ivar13, 1153), new WidgetPointer(1012,15)); + setScriptCallOnMouseOver(499, getOtherCommonData(ivar13, 1149), "i", new WidgetPointer(1012,15)); + setWidgetIsHidden(false, new WidgetPointer(1012,16)); + setWidgetPosition(80, getWidgetActualY(new WidgetPointer(1012,16)), 0, 0, new WidgetPointer(1012,16)); + if (((boolean)globalint_1373) && ((boolean)ivar8)) { + ivar13 = 299; + } else if (((boolean)globalint_1374) && ((boolean)ivar9)) { + ivar13 = 305; + ivar9 = 1; + } else if (((boolean)globalint_1375) && ((boolean)ivar10)) { + ivar13 = 1044; + ivar10 = 1; + } else { + ivar13 = 1045; + ivar11 = 1; + } + setWidgetSprite(getOtherCommonData(ivar13, 1153), new WidgetPointer(1012,16)); + setScriptCallOnMouseOver(499, getOtherCommonData(ivar13, 1149), "i", new WidgetPointer(1012,16)); + setWidgetIsHidden(false, new WidgetPointer(1012,17)); + setWidgetPosition(130, getWidgetActualY(new WidgetPointer(1012,17)), 0, 0, new WidgetPointer(1012,17)); + if (((boolean)globalint_1374) && ((boolean)ivar9)) { + ivar13 = 305; + } else if (((boolean)globalint_1375) && ((boolean)ivar10)) { + ivar13 = 1044; + } else if (((boolean)globalint_1376) && ((boolean)ivar11)) { + ivar13 = 1045; + } else { + ivar13 = 1046; + } + setWidgetSprite(getOtherCommonData(ivar13, 1153), new WidgetPointer(1012,17)); + setScriptCallOnMouseOver(499, getOtherCommonData(ivar13, 1149), "i", new WidgetPointer(1012,17)); + setWidgetIsHidden(true, new WidgetPointer(1012,18)); + setWidgetIsHidden(true, new WidgetPointer(1012,19)); + } else if (ivar6 == 4) { + setWidgetIsHidden(false, new WidgetPointer(1012,15)); + setWidgetPosition(18, getWidgetActualY(new WidgetPointer(1012,15)), 0, 0, new WidgetPointer(1012,15)); + if (((boolean)globalint_1372)) { + ivar13 = 293; + } else if (((boolean)globalint_1373)) { + ivar13 = 299; + ivar8 = 1; + } else { + ivar13 = 305; + ivar9 = 1; + } + setWidgetSprite(getOtherCommonData(ivar13, 1153), new WidgetPointer(1012,15)); + setScriptCallOnMouseOver(499, getOtherCommonData(ivar13, 1149), "i", new WidgetPointer(1012,15)); + setWidgetIsHidden(false, new WidgetPointer(1012,16)); + setWidgetPosition(61, getWidgetActualY(new WidgetPointer(1012,16)), 0, 0, new WidgetPointer(1012,16)); + if (((boolean)globalint_1373) && ((boolean)ivar8)) { + ivar13 = 299; + } else if (((boolean)globalint_1374) && ((boolean)ivar9)) { + ivar13 = 305; + ivar9 = 1; + } else { + ivar13 = 1044; + ivar10 = 1; + } + setWidgetSprite(getOtherCommonData(ivar13, 1153), new WidgetPointer(1012,16)); + setScriptCallOnMouseOver(499, getOtherCommonData(ivar13, 1149), "i", new WidgetPointer(1012,16)); + setWidgetIsHidden(false, new WidgetPointer(1012,17)); + setWidgetPosition(104, getWidgetActualY(new WidgetPointer(1012,17)), 0, 0, new WidgetPointer(1012,17)); + if (((boolean)globalint_1374) && ((boolean)ivar9)) { + ivar13 = 305; + } else if (((boolean)globalint_1375) && ((boolean)ivar10)) { + ivar13 = 1044; + ivar10 = 1; + } else { + ivar13 = 1045; + ivar11 = 1; + } + setWidgetSprite(getOtherCommonData(ivar13, 1153), new WidgetPointer(1012,17)); + setScriptCallOnMouseOver(499, getOtherCommonData(ivar13, 1149), "i", new WidgetPointer(1012,17)); + setWidgetIsHidden(false, new WidgetPointer(1012,18)); + setWidgetPosition(147, getWidgetActualY(new WidgetPointer(1012,18)), 0, 0, new WidgetPointer(1012,18)); + if (((boolean)globalint_1375) && ((boolean)ivar10)) { + ivar13 = 1044; + } else if (((boolean)globalint_1376) && ((boolean)ivar11)) { + ivar13 = 1045; + } else { + ivar13 = 1046; + } + setWidgetSprite(getOtherCommonData(ivar13, 1153), new WidgetPointer(1012,18)); + setScriptCallOnMouseOver(499, getOtherCommonData(ivar13, 1149), "i", new WidgetPointer(1012,18)); + setWidgetIsHidden(true, new WidgetPointer(1012,19)); + } else { + setWidgetIsHidden(false, new WidgetPointer(1012,15)); + setWidgetPosition(11, getWidgetActualY(new WidgetPointer(1012,15)), 0, 0, new WidgetPointer(1012,15)); + if (((boolean)globalint_1372)) { + ivar13 = 293; + } else { + ivar13 = 299; + ivar8 = 1; + } + setWidgetSprite(getOtherCommonData(ivar13, 1153), new WidgetPointer(1012,15)); + setScriptCallOnMouseOver(499, getOtherCommonData(ivar13, 1149), "i", new WidgetPointer(1012,15)); + setWidgetIsHidden(false, new WidgetPointer(1012,16)); + setWidgetPosition(47, getWidgetActualY(new WidgetPointer(1012,16)), 0, 0, new WidgetPointer(1012,16)); + if (((boolean)globalint_1373) && ((boolean)ivar8)) { + ivar13 = 299; + } else { + ivar13 = 305; + ivar9 = 1; + } + setWidgetSprite(getOtherCommonData(ivar13, 1153), new WidgetPointer(1012,16)); + setScriptCallOnMouseOver(499, getOtherCommonData(ivar13, 1149), "i", new WidgetPointer(1012,16)); + setWidgetIsHidden(false, new WidgetPointer(1012,17)); + setWidgetPosition(83, getWidgetActualY(new WidgetPointer(1012,17)), 0, 0, new WidgetPointer(1012,17)); + if (((boolean)globalint_1374) && ((boolean)ivar9)) { + ivar13 = 305; + } else { + ivar13 = 1044; + ivar10 = 1; + } + setWidgetSprite(getOtherCommonData(ivar13, 1153), new WidgetPointer(1012,17)); + setScriptCallOnMouseOver(499, getOtherCommonData(ivar13, 1149), "i", new WidgetPointer(1012,17)); + setWidgetIsHidden(false, new WidgetPointer(1012,18)); + setWidgetPosition(119, getWidgetActualY(new WidgetPointer(1012,18)), 0, 0, new WidgetPointer(1012,18)); + if (((boolean)globalint_1375) && ((boolean)ivar10)) { + ivar13 = 1044; + } else { + ivar13 = 1045; + ivar11 = 1; + } + setWidgetSprite(getOtherCommonData(ivar13, 1153), new WidgetPointer(1012,18)); + setScriptCallOnMouseOver(499, getOtherCommonData(ivar13, 1149), "i", new WidgetPointer(1012,18)); + setWidgetIsHidden(false, new WidgetPointer(1012,19)); + setWidgetPosition(155, getWidgetActualY(new WidgetPointer(1012,19)), 0, 0, new WidgetPointer(1012,19)); + if (((boolean)globalint_1376) && ((boolean)ivar11)) { + ivar13 = 1045; + } else { + ivar13 = 1046; + } + setWidgetSprite(getOtherCommonData(ivar13, 1153), new WidgetPointer(1012,19)); + setScriptCallOnMouseOver(499, getOtherCommonData(ivar13, 1149), "i", new WidgetPointer(1012,19)); + } + } + return; +} diff --git a/dumps/scripts/4980.cs2 b/dumps/scripts/4980.cs2 new file mode 100644 index 0000000..e5da54e --- /dev/null +++ b/dumps/scripts/4980.cs2 @@ -0,0 +1,175 @@ +int script_4980(int arg0) { + int ivar1; + int ivar2; + int ivar3; + ivar1 = 0; + ivar2 = 0; + ivar3 = 1; + if (citadelConfigsInitialized()) { + ivar1 = script_4948(arg0); + if (ivar1 <= 0) { + return 0; + } + ivar2 = script_4959(ivar1); + if (((boolean)ivar2)) { + return 0; + } + switch (ivar1) { + case 1: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 2: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 3: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 4: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 5: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 6: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 7: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 8: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 9: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 10: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 11: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 12: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 13: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 14: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 15: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + if (ivar3 > 0) { + return 4; + } + return 3; + } + return 0; +} diff --git a/dumps/scripts/4981.cs2 b/dumps/scripts/4981.cs2 new file mode 100644 index 0000000..eb51ddc --- /dev/null +++ b/dumps/scripts/4981.cs2 @@ -0,0 +1,99 @@ +void script_4981(int arg0,int arg1,int arg2,int arg3,int arg4) { + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + int ivar22; + int ivar23; + int ivar24; + int ivar25; + string svar0; + string svar1; + string svar2; + string svar3; + string svar4; + string svar5; + string svar6; + string svar7; + if (arg2 == -1) { + return; + } + if (arg3 == -1) { + return; + } + if ((arg1 < 0) || (arg1 > 7)) { + return; + } + ivar5 = 0; + switch (arg0) { + case 17: + case 1: + case 19: + case 18: + ivar5 = 1; + } + ivar6 = script_5169(arg0); + ivar7 = -1; + ivar8 = -1; + ivar9 = -1; + ivar10 = -1; + ivar11 = -1; + ivar12 = -1; + ivar13 = -1; + ivar14 = -1; + ivar15 = -1; + ivar16 = -1; + ivar17 = 0; + ivar18 = -1; + ivar19 = -1; + ivar20 = 0; + svar0 = ""; + ivar21 = 1; + svar1 = ""; + ivar22 = 0; + ivar23 = 0; + ivar24 = 0; + ivar25 = 0; + svar2 = "This building cannot be upgraded."; + svar3 = "This building cannot be downgraded."; + svar4 = "There is no upgrade to cancel."; + svar5 = "There is no downgrade to cancel."; + svar6 = "This building is already marked to be moved."; + svar7 = "There is no move order to cancel."; + setWidgetIsHidden(true, new WidgetPointer(1092,879)); + setWidgetIsHidden(true, new WidgetPointer(1092,891)); + setWidgetIsHidden(true, new WidgetPointer(1092,903)); + setWidgetIsHidden(true, new WidgetPointer(1092,915)); + setWidgetIsHidden(true, new WidgetPointer(1092,1804)); + setWidgetIsHidden(true, new WidgetPointer(1092,1816)); + if (citadelConfigsInitialized() && cs2method3701()) { + ivar18 = cs2method3717(cs2method5020()); + if (ivar18 < 0) { + return; + } + ivar19 = cs2method3711(ivar18); + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return; +} diff --git a/dumps/scripts/4982.cs2 b/dumps/scripts/4982.cs2 new file mode 100644 index 0000000..449ecc0 --- /dev/null +++ b/dumps/scripts/4982.cs2 @@ -0,0 +1,242 @@ +void script_4982(int arg0,int arg1,int arg2,int arg3,int arg4) { + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + int ivar22; + int ivar23; + ivar5 = 0; + ivar6 = 0; + ivar7 = 0; + ivar8 = 0; + ivar9 = 0; + ivar10 = 0; + ivar11 = 0; + ivar12 = 0; + ivar13 = 0; + ivar14 = 0; + ivar15 = 0; + ivar16 = 0; + ivar17 = 0; + ivar18 = 0; + ivar19 = 0; + ivar20 = 0; + ivar21 = 0; + ivar22 = 0; + ivar23 = subtract(arg2, arg4); + ivar23 = max(ivar23, 0); + if (citadelConfigsInitialized()) { + switch (arg2) { + case 0: + ivar17 = getOtherCommonData(arg0, 1483); + ivar18 = getOtherCommonData(arg0, 1490); + ivar19 = getOtherCommonData(arg0, 1497); + ivar20 = getOtherCommonData(arg0, 1504); + ivar21 = getOtherCommonData(arg0, 1511); + ivar22 = getOtherCommonData(arg0, 1518); + break; + case 1: + ivar17 = getOtherCommonData(arg0, 1484); + ivar18 = getOtherCommonData(arg0, 1491); + ivar19 = getOtherCommonData(arg0, 1498); + ivar20 = getOtherCommonData(arg0, 1505); + ivar21 = getOtherCommonData(arg0, 1512); + ivar22 = getOtherCommonData(arg0, 1519); + break; + case 2: + ivar17 = getOtherCommonData(arg0, 1485); + ivar18 = getOtherCommonData(arg0, 1492); + ivar19 = getOtherCommonData(arg0, 1499); + ivar20 = getOtherCommonData(arg0, 1506); + ivar21 = getOtherCommonData(arg0, 1513); + ivar22 = getOtherCommonData(arg0, 1520); + break; + case 3: + ivar17 = getOtherCommonData(arg0, 1486); + ivar18 = getOtherCommonData(arg0, 1493); + ivar19 = getOtherCommonData(arg0, 1500); + ivar20 = getOtherCommonData(arg0, 1507); + ivar21 = getOtherCommonData(arg0, 1514); + ivar22 = getOtherCommonData(arg0, 1521); + break; + case 4: + ivar17 = getOtherCommonData(arg0, 1487); + ivar18 = getOtherCommonData(arg0, 1494); + ivar19 = getOtherCommonData(arg0, 1501); + ivar20 = getOtherCommonData(arg0, 1508); + ivar21 = getOtherCommonData(arg0, 1515); + ivar22 = getOtherCommonData(arg0, 1522); + break; + case 5: + ivar17 = getOtherCommonData(arg0, 1488); + ivar18 = getOtherCommonData(arg0, 1495); + ivar19 = getOtherCommonData(arg0, 1502); + ivar20 = getOtherCommonData(arg0, 1509); + ivar21 = getOtherCommonData(arg0, 1516); + ivar22 = getOtherCommonData(arg0, 1523); + break; + case 6: + ivar17 = getOtherCommonData(arg0, 1489); + ivar18 = getOtherCommonData(arg0, 1496); + ivar19 = getOtherCommonData(arg0, 1503); + ivar20 = getOtherCommonData(arg0, 1510); + ivar21 = getOtherCommonData(arg0, 1517); + ivar22 = getOtherCommonData(arg0, 1524); + } + switch (arg2) { + case 1: + ivar5 = getOtherCommonData(arg1, 1483); + ivar6 = getOtherCommonData(arg1, 1490); + ivar7 = getOtherCommonData(arg1, 1497); + ivar8 = getOtherCommonData(arg1, 1504); + ivar9 = getOtherCommonData(arg1, 1511); + ivar10 = getOtherCommonData(arg1, 1518); + break; + case 2: + ivar5 = getOtherCommonData(arg1, 1484); + ivar6 = getOtherCommonData(arg1, 1491); + ivar7 = getOtherCommonData(arg1, 1498); + ivar8 = getOtherCommonData(arg1, 1505); + ivar9 = getOtherCommonData(arg1, 1512); + ivar10 = getOtherCommonData(arg1, 1519); + break; + case 3: + ivar5 = getOtherCommonData(arg1, 1485); + ivar6 = getOtherCommonData(arg1, 1492); + ivar7 = getOtherCommonData(arg1, 1499); + ivar8 = getOtherCommonData(arg1, 1506); + ivar9 = getOtherCommonData(arg1, 1513); + ivar10 = getOtherCommonData(arg1, 1520); + break; + case 4: + ivar5 = getOtherCommonData(arg1, 1486); + ivar6 = getOtherCommonData(arg1, 1493); + ivar7 = getOtherCommonData(arg1, 1500); + ivar8 = getOtherCommonData(arg1, 1507); + ivar9 = getOtherCommonData(arg1, 1514); + ivar10 = getOtherCommonData(arg1, 1521); + break; + case 5: + ivar5 = getOtherCommonData(arg1, 1487); + ivar6 = getOtherCommonData(arg1, 1494); + ivar7 = getOtherCommonData(arg1, 1501); + ivar8 = getOtherCommonData(arg1, 1508); + ivar9 = getOtherCommonData(arg1, 1515); + ivar10 = getOtherCommonData(arg1, 1522); + break; + case 6: + ivar5 = getOtherCommonData(arg1, 1488); + ivar6 = getOtherCommonData(arg1, 1495); + ivar7 = getOtherCommonData(arg1, 1502); + ivar8 = getOtherCommonData(arg1, 1509); + ivar9 = getOtherCommonData(arg1, 1516); + ivar10 = getOtherCommonData(arg1, 1523); + break; + case 7: + ivar5 = getOtherCommonData(arg1, 1489); + ivar6 = getOtherCommonData(arg1, 1496); + ivar7 = getOtherCommonData(arg1, 1503); + ivar8 = getOtherCommonData(arg1, 1510); + ivar9 = getOtherCommonData(arg1, 1517); + ivar10 = getOtherCommonData(arg1, 1524); + } + if (ivar23 > 0) { + switch (ivar23) { + case 1: + ivar11 = getOtherCommonData(arg1, 1483); + ivar12 = getOtherCommonData(arg1, 1490); + ivar13 = getOtherCommonData(arg1, 1497); + ivar14 = getOtherCommonData(arg1, 1504); + ivar15 = getOtherCommonData(arg1, 1511); + ivar16 = getOtherCommonData(arg1, 1518); + break; + case 2: + ivar11 = getOtherCommonData(arg1, 1484); + ivar12 = getOtherCommonData(arg1, 1491); + ivar13 = getOtherCommonData(arg1, 1498); + ivar14 = getOtherCommonData(arg1, 1505); + ivar15 = getOtherCommonData(arg1, 1512); + ivar16 = getOtherCommonData(arg1, 1519); + break; + case 3: + ivar11 = getOtherCommonData(arg1, 1485); + ivar12 = getOtherCommonData(arg1, 1492); + ivar13 = getOtherCommonData(arg1, 1499); + ivar14 = getOtherCommonData(arg1, 1506); + ivar15 = getOtherCommonData(arg1, 1513); + ivar16 = getOtherCommonData(arg1, 1520); + break; + case 4: + ivar11 = getOtherCommonData(arg1, 1486); + ivar12 = getOtherCommonData(arg1, 1493); + ivar13 = getOtherCommonData(arg1, 1500); + ivar14 = getOtherCommonData(arg1, 1507); + ivar15 = getOtherCommonData(arg1, 1514); + ivar16 = getOtherCommonData(arg1, 1521); + break; + case 5: + ivar11 = getOtherCommonData(arg1, 1487); + ivar12 = getOtherCommonData(arg1, 1494); + ivar13 = getOtherCommonData(arg1, 1501); + ivar14 = getOtherCommonData(arg1, 1508); + ivar15 = getOtherCommonData(arg1, 1515); + ivar16 = getOtherCommonData(arg1, 1522); + break; + case 6: + ivar11 = getOtherCommonData(arg1, 1488); + ivar12 = getOtherCommonData(arg1, 1495); + ivar13 = getOtherCommonData(arg1, 1502); + ivar14 = getOtherCommonData(arg1, 1509); + ivar15 = getOtherCommonData(arg1, 1516); + ivar16 = getOtherCommonData(arg1, 1523); + } + } else { + ivar11 = 0; + ivar12 = 0; + ivar13 = 0; + ivar14 = 0; + ivar15 = 0; + ivar16 = 0; + } + if (((boolean)arg3) && ((boolean)arg2)) { + ivar5 = multiply(ivar5, 2); + ivar6 = multiply(ivar6, 2); + ivar7 = multiply(ivar7, 2); + ivar8 = multiply(ivar8, 2); + ivar9 = multiply(ivar9, 2); + ivar10 = multiply(ivar10, 2); + } + setWidgetText(new WidgetPointer(1092,477), intToStr(ivar5)); + setWidgetText(new WidgetPointer(1092,484), intToStr(ivar6)); + setWidgetText(new WidgetPointer(1092,491), intToStr(ivar7)); + setWidgetText(new WidgetPointer(1092,498), intToStr(ivar8)); + setWidgetText(new WidgetPointer(1092,505), intToStr(ivar9)); + setWidgetText(new WidgetPointer(1092,513), intToStr(ivar10)); + setWidgetText(new WidgetPointer(1092,610), intToStr(ivar17)); + setWidgetText(new WidgetPointer(1092,618), intToStr(ivar18)); + setWidgetText(new WidgetPointer(1092,626), intToStr(ivar19)); + setWidgetText(new WidgetPointer(1092,634), intToStr(ivar20)); + setWidgetText(new WidgetPointer(1092,644), intToStr(ivar21)); + setWidgetText(new WidgetPointer(1092,651), intToStr(ivar22)); + setWidgetText(new WidgetPointer(1092,660), intToStr(ivar11)); + setWidgetText(new WidgetPointer(1092,668), intToStr(ivar12)); + setWidgetText(new WidgetPointer(1092,676), intToStr(ivar13)); + setWidgetText(new WidgetPointer(1092,684), intToStr(ivar14)); + setWidgetText(new WidgetPointer(1092,694), intToStr(ivar15)); + setWidgetText(new WidgetPointer(1092,701), intToStr(ivar16)); + } + return; +} diff --git a/dumps/scripts/4983.cs2 b/dumps/scripts/4983.cs2 new file mode 100644 index 0000000..07da0ec --- /dev/null +++ b/dumps/scripts/4983.cs2 @@ -0,0 +1,3 @@ +void script_4983() { + return; +} diff --git a/dumps/scripts/4984.cs2 b/dumps/scripts/4984.cs2 new file mode 100644 index 0000000..8d4f103 --- /dev/null +++ b/dumps/scripts/4984.cs2 @@ -0,0 +1,4 @@ +void script_4984() { + script_4985(); + return; +} diff --git a/dumps/scripts/4985.cs2 b/dumps/scripts/4985.cs2 new file mode 100644 index 0000000..a2ba47f --- /dev/null +++ b/dumps/scripts/4985.cs2 @@ -0,0 +1,20 @@ +void script_4985() { + int ivar0; + flow_0: + ivar0 = -1; + IF (citadelConfigsInitialized() && (bitconfig_9550 > 0)) + GOTO flow_2 + GOTO flow_5 + flow_2: + ivar0 = script_4948(bitconfig_9550); + IF (ivar0 <= 0) + GOTO flow_3 + GOTO flow_4 + flow_3: + script_4899(4); + GOTO flow_4 + flow_4: + GOTO flow_5 + flow_5: + return; +} diff --git a/dumps/scripts/4986.cs2 b/dumps/scripts/4986.cs2 new file mode 100644 index 0000000..8787da0 --- /dev/null +++ b/dumps/scripts/4986.cs2 @@ -0,0 +1,4 @@ +void script_4986(int arg0) { + script_4987(arg0); + return; +} diff --git a/dumps/scripts/4987.cs2 b/dumps/scripts/4987.cs2 new file mode 100644 index 0000000..f877102 --- /dev/null +++ b/dumps/scripts/4987.cs2 @@ -0,0 +1,42 @@ +void script_4987(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int stack_dump0; + cs2func_script_4958_struct(5,0,0) structdump_1; + ivar1 = 0; + ivar2 = 0; + ivar3 = -1; + ivar4 = -1; + ivar5 = 0; + ivar6 = script_4966(arg0); + if (citadelConfigsInitialized()) { + ivar1 = script_4949(ivar6); + bitconfig_9550 = ivar1; + } + if (((boolean)bitconfig_9552) || (bitconfig_9552 == 2)) { + stack_dump0 = ivar6; + structdump_1 = script_4958(stack_dump0); + ivar5 = structdump_1.intpart_4; + ivar4 = structdump_1.intpart_3; + ivar3 = structdump_1.intpart_2; + ivar2 = structdump_1.intpart_1; + ivar1 = structdump_1.intpart_0; + script_4988(bitconfig_9550); + script_4937(); + } else { + if ((bitconfig_9552 == 4) || (bitconfig_9552 == 3)) { + bitconfig_9550 = script_4949(ivar6); + script_4988(bitconfig_9550); + script_4937(); + script_4905(); + script_4907(); + bitconfig_9552 = 1; + script_4899(1); + } + } + return; +} diff --git a/dumps/scripts/4988.cs2 b/dumps/scripts/4988.cs2 new file mode 100644 index 0000000..640065a --- /dev/null +++ b/dumps/scripts/4988.cs2 @@ -0,0 +1,23 @@ +void script_4988(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int stack_dump0; + cs2func_script_4957_struct(4,0,0) structdump_1; + ivar1 = -1; + ivar2 = -1; + ivar3 = -1; + ivar4 = -1; + if (citadelConfigsInitialized()) { + stack_dump0 = arg0; + structdump_1 = script_4957(stack_dump0); + ivar2 = structdump_1.intpart_3; + ivar4 = structdump_1.intpart_2; + ivar3 = structdump_1.intpart_1; + ivar1 = structdump_1.intpart_0; + script_4981(arg0, ivar1, ivar3, ivar4, ivar2); + script_4937(); + } + return; +} diff --git a/dumps/scripts/4989.cs2 b/dumps/scripts/4989.cs2 new file mode 100644 index 0000000..21d12ca --- /dev/null +++ b/dumps/scripts/4989.cs2 @@ -0,0 +1,26 @@ +void script_4989(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int stack_dump0; + cs2func_script_4958_struct(5,0,0) structdump_1; + ivar1 = -1; + ivar2 = -1; + ivar3 = -1; + ivar4 = -1; + ivar5 = -1; + stack_dump0 = arg0; + structdump_1 = script_4958(stack_dump0); + ivar3 = structdump_1.intpart_4; + ivar5 = structdump_1.intpart_3; + ivar4 = structdump_1.intpart_2; + ivar2 = structdump_1.intpart_1; + ivar1 = structdump_1.intpart_0; + script_4988(bitconfig_9550); + script_4937(); + bitconfig_9550 = ivar1; + bitconfig_9551 = script_4945(ivar1); + return; +} diff --git a/dumps/scripts/499.cs2 b/dumps/scripts/499.cs2 new file mode 100644 index 0000000..060ef0f --- /dev/null +++ b/dumps/scripts/499.cs2 @@ -0,0 +1,14 @@ +void script_499(int arg0) { + int ivar1; + int ivar2; + ivar1 = script_488(arg0); + ivar2 = 66322452; + if (ivar1 != -1) { + setWidgetText(new WidgetPointer(1012,27), getOtherCommonData(ivar1, 1150)); + setWidgetText(new WidgetPointer(1012,28), getOtherCommonData(ivar1, 1152)); + setWidgetIsHidden(false, new WidgetPointer(ivar2)); + } else { + setWidgetIsHidden(true, new WidgetPointer(ivar2)); + } + return; +} diff --git a/dumps/scripts/4990.cs2 b/dumps/scripts/4990.cs2 new file mode 100644 index 0000000..2879c9a --- /dev/null +++ b/dumps/scripts/4990.cs2 @@ -0,0 +1,26 @@ +void script_4990(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int stack_dump0; + cs2func_script_4958_struct(5,0,0) structdump_1; + ivar1 = -1; + ivar2 = -1; + ivar3 = -1; + ivar4 = -1; + ivar5 = -1; + stack_dump0 = arg0; + structdump_1 = script_4958(stack_dump0); + ivar3 = structdump_1.intpart_4; + ivar5 = structdump_1.intpart_3; + ivar4 = structdump_1.intpart_2; + ivar2 = structdump_1.intpart_1; + ivar1 = structdump_1.intpart_0; + script_4988(bitconfig_9550); + script_4937(); + bitconfig_9550 = ivar1; + bitconfig_9551 = ivar2; + return; +} diff --git a/dumps/scripts/4991.cs2 b/dumps/scripts/4991.cs2 new file mode 100644 index 0000000..164d4f3 --- /dev/null +++ b/dumps/scripts/4991.cs2 @@ -0,0 +1,20 @@ +void script_4991() { + int ivar0; + int ivar1; + script_4993(); + script_4994(); + ivar0 = -1; + ivar1 = 0; + if (citadelConfigsInitialized()) { + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return; +} diff --git a/dumps/scripts/4992.cs2 b/dumps/scripts/4992.cs2 new file mode 100644 index 0000000..b938ce6 --- /dev/null +++ b/dumps/scripts/4992.cs2 @@ -0,0 +1,97 @@ +int script_4992(int arg0,int arg1) { + if (arg1 >= 1) { + switch (arg0) { + case 17: + case 1: + case 19: + case 18: + return 1; + } + } + if (arg1 >= 2) { + switch (arg0) { + case 17: + case 1: + case 2: + case 19: + case 18: + case 7: + return 1; + } + } + if (arg1 >= 3) { + switch (arg0) { + case 17: + case 1: + case 2: + case 19: + case 3: + case 18: + case 4: + case 5: + case 6: + case 7: + return 1; + } + } + if (arg1 >= 4) { + switch (arg0) { + case 17: + case 1: + case 2: + case 19: + case 3: + case 18: + case 4: + case 5: + case 6: + case 7: + return 1; + } + } + if (arg1 >= 5) { + switch (arg0) { + case 17: + case 1: + case 2: + case 19: + case 3: + case 18: + case 4: + case 5: + case 7: + return 1; + } + } + if (arg1 >= 6) { + switch (arg0) { + case 17: + case 1: + case 2: + case 19: + case 3: + case 18: + case 4: + case 5: + case 6: + case 7: + return 1; + } + } + if (arg1 >= 7) { + switch (arg0) { + case 17: + case 1: + case 2: + case 19: + case 3: + case 18: + case 4: + case 5: + case 6: + case 7: + return 1; + } + } + return 0; +} diff --git a/dumps/scripts/4993.cs2 b/dumps/scripts/4993.cs2 new file mode 100644 index 0000000..c674513 --- /dev/null +++ b/dumps/scripts/4993.cs2 @@ -0,0 +1,13 @@ +void script_4993() { + setWidgetIsHidden(true, new WidgetPointer(1092,198)); + setWidgetIsHidden(true, new WidgetPointer(1092,199)); + setWidgetIsHidden(true, new WidgetPointer(1092,200)); + setWidgetIsHidden(true, new WidgetPointer(1092,201)); + setWidgetIsHidden(true, new WidgetPointer(1092,202)); + setWidgetIsHidden(true, new WidgetPointer(1092,203)); + setWidgetIsHidden(true, new WidgetPointer(1092,204)); + setWidgetIsHidden(true, new WidgetPointer(1092,205)); + setWidgetIsHidden(true, new WidgetPointer(1092,206)); + setWidgetIsHidden(true, new WidgetPointer(1092,833)); + return; +} diff --git a/dumps/scripts/4994.cs2 b/dumps/scripts/4994.cs2 new file mode 100644 index 0000000..58d0640 --- /dev/null +++ b/dumps/scripts/4994.cs2 @@ -0,0 +1,100 @@ +void script_4994() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + int ivar22; + int ivar23; + int ivar24; + int ivar25; + int ivar26; + int ivar27; + string stack_dump0; + ivar0 = -1; + ivar1 = -1; + ivar2 = -1; + ivar3 = -1; + ivar4 = -1; + ivar5 = -1; + ivar6 = -1; + ivar7 = -1; + ivar8 = -1; + ivar9 = -1; + ivar10 = -1; + ivar11 = -1; + ivar12 = -1; + ivar13 = -1; + ivar14 = -1; + ivar15 = -1; + ivar16 = -1; + ivar17 = -1; + ivar18 = -1; + ivar19 = -1; + ivar20 = -1; + ivar21 = -1; + ivar22 = -1; + ivar23 = -1; + ivar24 = -1; + ivar25 = -1; + ivar26 = -1; + ivar27 = -1; + if (citadelConfigsInitialized()) { + ivar0 = script_4948(1); + ivar1 = script_4948(2); + ivar2 = script_4948(3); + ivar3 = script_4948(4); + ivar4 = script_4948(7); + ivar5 = script_4948(6); + ivar6 = script_4948(5); + ivar7 = script_4959(ivar0); + ivar8 = script_4959(ivar1); + ivar9 = script_4959(ivar2); + ivar10 = script_4959(ivar3); + ivar11 = script_4959(ivar4); + ivar12 = script_4959(ivar5); + ivar13 = script_4959(ivar6); + ivar14 = script_4961(ivar0, 3); + ivar15 = script_4961(ivar1, 3); + ivar16 = script_4961(ivar2, 3); + ivar17 = script_4961(ivar3, 3); + ivar18 = script_4961(ivar4, 3); + ivar19 = script_4961(ivar5, 3); + ivar20 = script_4961(ivar6, 3); + ivar21 = script_4953(ivar14); + ivar22 = script_4953(ivar15); + ivar23 = script_4953(ivar16); + ivar24 = script_4953(ivar17); + ivar25 = script_4953(ivar18); + ivar26 = script_4953(ivar19); + ivar27 = script_4953(ivar20); + stack_dump0 = "Tier "; + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return; +} diff --git a/dumps/scripts/4995.cs2 b/dumps/scripts/4995.cs2 new file mode 100644 index 0000000..2754c5d --- /dev/null +++ b/dumps/scripts/4995.cs2 @@ -0,0 +1,4 @@ +void script_4995(int arg0) { + script_4996(arg0); + return; +} diff --git a/dumps/scripts/4996.cs2 b/dumps/scripts/4996.cs2 new file mode 100644 index 0000000..3834187 --- /dev/null +++ b/dumps/scripts/4996.cs2 @@ -0,0 +1,39 @@ +void script_4996(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + ivar1 = -1; + ivar2 = -1; + ivar3 = 0; + ivar4 = -1; + ivar5 = -1; + ivar6 = -1; + setWidgetIsHidden(false, new WidgetPointer(1092,289)); + if (citadelConfigsInitialized()) { + script_4899(1); + ivar2 = script_4963(arg0); + bitconfig_9550 = ivar2; + if (ivar2 <= 0) { + messageType0("You must first select a building."); + return; + } + ivar1 = script_4948(ivar2); + ivar4 = script_4954(ivar2); + if (ivar4 == -1) { + return; + } + ivar5 = script_4955(ivar2); + if (ivar5 == -1) { + return; + } + if (ivar1 > 0) { + ivar3 = script_4959(ivar1); + } + script_4988(bitconfig_9550); + script_4937(); + } + return; +} diff --git a/dumps/scripts/4997.cs2 b/dumps/scripts/4997.cs2 new file mode 100644 index 0000000..8fc9018 --- /dev/null +++ b/dumps/scripts/4997.cs2 @@ -0,0 +1,6 @@ +void script_4997() { + script_5001(); + setWidgetIsHidden(false, new WidgetPointer(1092,232)); + setWidgetIsHidden(false, new WidgetPointer(1092,507)); + return; +} diff --git a/dumps/scripts/4998.cs2 b/dumps/scripts/4998.cs2 new file mode 100644 index 0000000..672b158 --- /dev/null +++ b/dumps/scripts/4998.cs2 @@ -0,0 +1,6 @@ +void script_4998() { + script_5001(); + setWidgetIsHidden(false, new WidgetPointer(1092,234)); + setWidgetIsHidden(false, new WidgetPointer(1092,602)); + return; +} diff --git a/dumps/scripts/4999.cs2 b/dumps/scripts/4999.cs2 new file mode 100644 index 0000000..b29f1b1 --- /dev/null +++ b/dumps/scripts/4999.cs2 @@ -0,0 +1,6 @@ +void script_4999() { + script_5001(); + setWidgetIsHidden(false, new WidgetPointer(1092,236)); + setWidgetIsHidden(false, new WidgetPointer(1092,652)); + return; +} diff --git a/dumps/scripts/5.cs2 b/dumps/scripts/5.cs2 new file mode 100644 index 0000000..4b2f5f6 --- /dev/null +++ b/dumps/scripts/5.cs2 @@ -0,0 +1,16 @@ +void script_5() { + int ivar0; + int ivar1; + ivar0 = 30; + if (((boolean)bitconfig_6840)) { + ivar0 = 20; + } + ivar1 = 0; + while (ivar1 < ivar0) { + if ((setWidgetRegister(new WidgetPointer(271,7), ivar1) && ((boolean)script_2297(ivar1))) && ((boolean)script_2295(ivar1))) { + setWidgetSprite(155); + } + ivar1 = add(ivar1, 1); + } + return; +} diff --git a/dumps/scripts/50.cs2 b/dumps/scripts/50.cs2 new file mode 100644 index 0000000..27baf00 --- /dev/null +++ b/dumps/scripts/50.cs2 @@ -0,0 +1,4 @@ +void script_50() { + script_2303(); + return; +} diff --git a/dumps/scripts/500.cs2 b/dumps/scripts/500.cs2 new file mode 100644 index 0000000..369e569 --- /dev/null +++ b/dumps/scripts/500.cs2 @@ -0,0 +1,4 @@ +void script_500() { + setWidgetIsHidden(true, new WidgetPointer(1012,20)); + return; +} diff --git a/dumps/scripts/5000.cs2 b/dumps/scripts/5000.cs2 new file mode 100644 index 0000000..ecd658b --- /dev/null +++ b/dumps/scripts/5000.cs2 @@ -0,0 +1,6 @@ +void script_5000() { + script_5001(); + setWidgetIsHidden(false, new WidgetPointer(1092,238)); + setWidgetIsHidden(false, new WidgetPointer(1092,702)); + return; +} diff --git a/dumps/scripts/5001.cs2 b/dumps/scripts/5001.cs2 new file mode 100644 index 0000000..ea19586 --- /dev/null +++ b/dumps/scripts/5001.cs2 @@ -0,0 +1,11 @@ +void script_5001() { + setWidgetIsHidden(true, new WidgetPointer(1092,232)); + setWidgetIsHidden(true, new WidgetPointer(1092,507)); + setWidgetIsHidden(true, new WidgetPointer(1092,234)); + setWidgetIsHidden(true, new WidgetPointer(1092,602)); + setWidgetIsHidden(true, new WidgetPointer(1092,236)); + setWidgetIsHidden(true, new WidgetPointer(1092,652)); + setWidgetIsHidden(true, new WidgetPointer(1092,238)); + setWidgetIsHidden(true, new WidgetPointer(1092,702)); + return; +} diff --git a/dumps/scripts/5002.cs2 b/dumps/scripts/5002.cs2 new file mode 100644 index 0000000..02073a9 --- /dev/null +++ b/dumps/scripts/5002.cs2 @@ -0,0 +1,56 @@ +void script_5002(int arg0) { + int ivar1; + int ivar2; + script_4408(arg0); + deleteAllExtraChilds(new WidgetPointer(arg0)); + createExtraChild(new WidgetPointer(arg0), 3, 0); + setWidgetSize(20, 20, 0, 0); + setWidgetPosition(0, 0, 1, 1); + setWidgetRGB(new Color(85, 51, 51)); + setWidgetFilled(1); + cs2method2103(155); + createExtraChild(new WidgetPointer(arg0), 3, 1); + setWidgetSize(20, 20, 0, 0); + setWidgetPosition(0, 0, 1, 1); + setWidgetRGB(new Color(238, 204, 238)); + createExtraChild(new WidgetPointer(arg0), 5, 2); + setWidgetSize(18, 18, 0, 0); + setWidgetPosition(0, 0, 1, 1); + ivar1 = script_4964(arg0); + ivar2 = 0; + if (citadelConfigsInitialized()) { + ivar2 = script_4949(ivar1); + switch (ivar2) { + case 17: + setWidgetSprite(7431); + break; + case 18: + setWidgetSprite(7430); + break; + case 19: + setWidgetSprite(7433); + break; + case 1: + setWidgetSprite(7422); + break; + case 2: + setWidgetSprite(7423); + break; + case 3: + setWidgetSprite(7424); + break; + case 4: + setWidgetSprite(7425); + break; + case 5: + setWidgetSprite(7426); + break; + case 6: + setWidgetSprite(7427); + break; + case 7: + setWidgetSprite(7428); + } + } + return; +} diff --git a/dumps/scripts/5003.cs2 b/dumps/scripts/5003.cs2 new file mode 100644 index 0000000..af2ce81 --- /dev/null +++ b/dumps/scripts/5003.cs2 @@ -0,0 +1,4 @@ +void script_5003() { + setWidgetIsHidden(true, new WidgetPointer(908,36)); + return; +} diff --git a/dumps/scripts/5004.cs2 b/dumps/scripts/5004.cs2 new file mode 100644 index 0000000..ee01d8b --- /dev/null +++ b/dumps/scripts/5004.cs2 @@ -0,0 +1,14 @@ +void script_5004() { + int ivar0; + int ivar1; + ivar0 = 0; + ivar1 = 0; + if (citadelConfigsInitialized()) { + ivar0 = script_4948(bitconfig_9550); + ivar1 = script_4978(ivar0); + if ((ivar1 == ivar0) || (ivar1 <= 0)) { + script_4899(3); + } + } + return; +} diff --git a/dumps/scripts/5005.cs2 b/dumps/scripts/5005.cs2 new file mode 100644 index 0000000..e4bd368 --- /dev/null +++ b/dumps/scripts/5005.cs2 @@ -0,0 +1,28 @@ +void script_5005() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + ivar0 = bitconfig_9550; + ivar1 = ivar0; + ivar2 = 1; + ivar3 = 0; + ivar4 = 0; + ivar5 = 0; + ivar6 = 100; + if (citadelConfigsInitialized()) { + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return; +} diff --git a/dumps/scripts/5006.cs2 b/dumps/scripts/5006.cs2 new file mode 100644 index 0000000..e89718a --- /dev/null +++ b/dumps/scripts/5006.cs2 @@ -0,0 +1,28 @@ +void script_5006() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + ivar0 = bitconfig_9550; + ivar1 = ivar0; + ivar2 = 1; + ivar3 = 0; + ivar4 = 0; + ivar5 = 0; + ivar6 = 100; + if (citadelConfigsInitialized()) { + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return; +} diff --git a/dumps/scripts/5007.cs2 b/dumps/scripts/5007.cs2 new file mode 100644 index 0000000..0655acf --- /dev/null +++ b/dumps/scripts/5007.cs2 @@ -0,0 +1,27 @@ +void script_5007() { + setWidgetText(new WidgetPointer(1092,477), intToStr(0)); + setWidgetText(new WidgetPointer(1092,484), intToStr(0)); + setWidgetText(new WidgetPointer(1092,491), intToStr(0)); + setWidgetText(new WidgetPointer(1092,498), intToStr(0)); + setWidgetText(new WidgetPointer(1092,505), intToStr(0)); + setWidgetText(new WidgetPointer(1092,513), intToStr(0)); + setWidgetText(new WidgetPointer(1092,610), intToStr(0)); + setWidgetText(new WidgetPointer(1092,618), intToStr(0)); + setWidgetText(new WidgetPointer(1092,626), intToStr(0)); + setWidgetText(new WidgetPointer(1092,634), intToStr(0)); + setWidgetText(new WidgetPointer(1092,644), intToStr(0)); + setWidgetText(new WidgetPointer(1092,651), intToStr(0)); + setWidgetText(new WidgetPointer(1092,660), intToStr(0)); + setWidgetText(new WidgetPointer(1092,668), intToStr(0)); + setWidgetText(new WidgetPointer(1092,676), intToStr(0)); + setWidgetText(new WidgetPointer(1092,684), intToStr(0)); + setWidgetText(new WidgetPointer(1092,694), intToStr(0)); + setWidgetText(new WidgetPointer(1092,701), intToStr(0)); + setWidgetText(new WidgetPointer(1092,295), ""); + setWidgetText(new WidgetPointer(1092,239), ""); + setWidgetIsHidden(false, new WidgetPointer(1092,903)); + setWidgetIsHidden(false, new WidgetPointer(1092,915)); + setWidgetIsHidden(false, new WidgetPointer(1092,879)); + setWidgetIsHidden(false, new WidgetPointer(1092,891)); + return; +} diff --git a/dumps/scripts/5008.cs2 b/dumps/scripts/5008.cs2 new file mode 100644 index 0000000..54940b0 --- /dev/null +++ b/dumps/scripts/5008.cs2 @@ -0,0 +1,25 @@ +int script_5008() { + int ivar0; + int ivar1; + int ivar2; + ivar0 = -1; + ivar1 = -1; + ivar2 = 0; + if (cs2method3701()) { + ivar0 = cs2method3717(cs2method5020()); + if (ivar0 < 0) { + return 0; + } + ivar1 = cs2method3711(ivar0); + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return 0; +} diff --git a/dumps/scripts/5009.cs2 b/dumps/scripts/5009.cs2 new file mode 100644 index 0000000..217c3d7 --- /dev/null +++ b/dumps/scripts/5009.cs2 @@ -0,0 +1,18 @@ +void script_5009() { + script_4407(71566682, 1, 180); + script_4407(71566675, 1, 180); + script_4407(71566668, 1, 180); + script_4407(71566584, 1, 180); + script_4407(71566591, 1, 180); + script_4407(71566598, 1, 180); + script_4407(71566605, 1, 180); + script_4407(71566612, 1, 180); + script_4407(71566619, 1, 180); + script_4407(71566626, 1, 180); + script_4407(71566633, 1, 180); + script_4407(71566640, 1, 180); + script_4407(71566647, 1, 180); + script_4407(71566654, 1, 180); + script_4407(71566661, 1, 180); + return; +} diff --git a/dumps/scripts/501.cs2 b/dumps/scripts/501.cs2 new file mode 100644 index 0000000..58ce38e --- /dev/null +++ b/dumps/scripts/501.cs2 @@ -0,0 +1,8 @@ +void script_501(int arg0) { + if (((boolean)arg0)) { + setWidgetIsHidden(false, new WidgetPointer(1012,7)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1012,7)); + } + return; +} diff --git a/dumps/scripts/5010.cs2 b/dumps/scripts/5010.cs2 new file mode 100644 index 0000000..b3acac8 --- /dev/null +++ b/dumps/scripts/5010.cs2 @@ -0,0 +1,15 @@ +void script_5010() { + script_4407(71566584, 1, 178); + script_4407(71566591, 1, 178); + script_4407(71566598, 1, 178); + script_4407(71566605, 1, 178); + script_4407(71566612, 1, 178); + script_4407(71566619, 1, 178); + script_4407(71566626, 1, 178); + script_4407(71566633, 1, 178); + script_4407(71566640, 1, 178); + script_4407(71566647, 1, 178); + script_4407(71566654, 1, 178); + script_4407(71566661, 1, 178); + return; +} diff --git a/dumps/scripts/5011.cs2 b/dumps/scripts/5011.cs2 new file mode 100644 index 0000000..e9a9f3d --- /dev/null +++ b/dumps/scripts/5011.cs2 @@ -0,0 +1,13 @@ +void script_5011() { + script_4407(71566050, 1, 180); + script_4407(71566061, 1, 180); + script_4407(71566072, 1, 180); + script_4407(71566083, 1, 180); + script_4407(71566094, 1, 180); + script_4407(71566105, 1, 180); + script_4407(71566116, 1, 180); + script_4407(71566127, 1, 180); + script_4407(71566150, 1, 180); + script_4407(71566138, 1, 180); + return; +} diff --git a/dumps/scripts/5012.cs2 b/dumps/scripts/5012.cs2 new file mode 100644 index 0000000..02d5c5c --- /dev/null +++ b/dumps/scripts/5012.cs2 @@ -0,0 +1,6 @@ +void script_5012() { + script_5015(); + script_5014(); + script_5227(); + return; +} diff --git a/dumps/scripts/5013.cs2 b/dumps/scripts/5013.cs2 new file mode 100644 index 0000000..afa482f --- /dev/null +++ b/dumps/scripts/5013.cs2 @@ -0,0 +1,20 @@ +void script_5013() { + setWidgetIsHidden(true, new WidgetPointer(1092,196)); + setWidgetIsHidden(true, new WidgetPointer(1092,917)); + setWidgetIsHidden(true, new WidgetPointer(1092,918)); + setWidgetIsHidden(true, new WidgetPointer(1092,919)); + setWidgetIsHidden(true, new WidgetPointer(1092,920)); + setWidgetIsHidden(true, new WidgetPointer(1092,921)); + setWidgetIsHidden(true, new WidgetPointer(1092,922)); + setWidgetIsHidden(true, new WidgetPointer(1092,923)); + setWidgetIsHidden(true, new WidgetPointer(1092,924)); + setWidgetIsHidden(true, new WidgetPointer(1092,925)); + setWidgetIsHidden(true, new WidgetPointer(1092,926)); + setWidgetIsHidden(true, new WidgetPointer(1092,927)); + setWidgetIsHidden(true, new WidgetPointer(1092,928)); + setWidgetIsHidden(true, new WidgetPointer(1092,929)); + setWidgetIsHidden(true, new WidgetPointer(1092,930)); + setWidgetIsHidden(true, new WidgetPointer(1092,932)); + setWidgetIsHidden(true, new WidgetPointer(1092,931)); + return; +} diff --git a/dumps/scripts/5014.cs2 b/dumps/scripts/5014.cs2 new file mode 100644 index 0000000..a5d55bc --- /dev/null +++ b/dumps/scripts/5014.cs2 @@ -0,0 +1,125 @@ +void script_5014() { + script_5013(); + setWidgetIsHidden(false, new WidgetPointer(1092,928)); + setWidgetIsHidden(false, new WidgetPointer(1092,929)); + setWidgetIsHidden(false, new WidgetPointer(1092,930)); + setWidgetIsHidden(false, new WidgetPointer(1092,932)); + setWidgetIsHidden(false, new WidgetPointer(1092,931)); + if ((script_4949(4) > 0) && (script_4959(4) > 0)) { + setWidgetIsHidden(false, new WidgetPointer(1092,196)); + } + if ((script_4949(5) > 0) && (script_4959(5) > 0)) { + setWidgetIsHidden(false, new WidgetPointer(1092,917)); + } + if (script_4949(6) > 0) { + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + if (script_4949(7) > 0) { + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + if (script_4949(8) > 0) { + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + if (script_4949(9) > 0) { + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + if (script_4949(10) > 0) { + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + if (script_4949(11) > 0) { + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + if (script_4949(12) > 0) { + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + if (script_4949(13) > 0) { + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + if (script_4949(14) > 0) { + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + if (script_4949(15) > 0) { + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return; +} diff --git a/dumps/scripts/5015.cs2 b/dumps/scripts/5015.cs2 new file mode 100644 index 0000000..47c62ad --- /dev/null +++ b/dumps/scripts/5015.cs2 @@ -0,0 +1,20 @@ +void script_5015() { + script_5016(102); + script_5016(103); + script_5016(100); + script_5016(101); + script_5016(3); + script_5016(4); + script_5016(5); + script_5016(6); + script_5016(7); + script_5016(8); + script_5016(9); + script_5016(10); + script_5016(11); + script_5016(12); + script_5016(13); + script_5016(14); + script_5016(15); + return; +} diff --git a/dumps/scripts/5016.cs2 b/dumps/scripts/5016.cs2 new file mode 100644 index 0000000..6bd7019 --- /dev/null +++ b/dumps/scripts/5016.cs2 @@ -0,0 +1,24 @@ +void script_5016(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + ivar1 = -1; + ivar2 = 0; + ivar3 = script_4969(arg0); + ivar4 = -1; + ivar5 = -1; + if (citadelConfigsInitialized()) { + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return; +} diff --git a/dumps/scripts/5017.cs2 b/dumps/scripts/5017.cs2 new file mode 100644 index 0000000..498163b --- /dev/null +++ b/dumps/scripts/5017.cs2 @@ -0,0 +1,12 @@ +void script_5017(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6) { + setWidgetSprite(arg2, new WidgetPointer(arg0)); + setWidgetSprite(arg3, new WidgetPointer(arg1)); + if (arg6 >= 5) { + setWidgetRGB(new Color(getColorRelatedMethod4020(arg4)), new WidgetPointer(arg0)); + setWidgetRGB(new Color(getColorRelatedMethod4020(arg5)), new WidgetPointer(arg1)); + } else { + setWidgetRGB(new Color(getColorRelatedMethod4020(6716)), new WidgetPointer(arg0)); + setWidgetRGB(new Color(getColorRelatedMethod4020(6716)), new WidgetPointer(arg1)); + } + return; +} diff --git a/dumps/scripts/5018.cs2 b/dumps/scripts/5018.cs2 new file mode 100644 index 0000000..d1cbd37 --- /dev/null +++ b/dumps/scripts/5018.cs2 @@ -0,0 +1,10 @@ +void script_5018(int arg0,int arg1,int arg2,int arg3,int arg4) { + if (arg4 >= 5) { + setWidgetRGB(new Color(getColorRelatedMethod4020(arg2)), new WidgetPointer(arg0)); + setWidgetRGB(new Color(getColorRelatedMethod4020(arg3)), new WidgetPointer(arg1)); + } else { + setWidgetRGB(new Color(getColorRelatedMethod4020(42550)), new WidgetPointer(arg0)); + setWidgetRGB(new Color(getColorRelatedMethod4020(39382)), new WidgetPointer(arg1)); + } + return; +} diff --git a/dumps/scripts/5019.cs2 b/dumps/scripts/5019.cs2 new file mode 100644 index 0000000..6a67ca9 --- /dev/null +++ b/dumps/scripts/5019.cs2 @@ -0,0 +1,2007 @@ +cs2func_script_5019_struct(4,0,0) script_5019(int arg0) { + switch (arg0) { + case 0: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 1: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 2: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 3: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 4: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 5: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 6: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 7: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 8: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 9: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 10: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 11: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 12: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 13: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 14: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 15: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 16: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 17: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 18: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 19: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 20: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 21: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 22: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 23: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 24: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 25: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 26: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 27: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 28: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 29: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 30: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 31: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 32: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 33: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 34: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 35: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 36: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 37: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 38: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 39: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 40: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 41: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 42: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 43: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 44: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 45: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 46: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 47: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 48: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 49: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 50: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 51: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 52: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 53: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 54: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 55: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 56: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 57: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 58: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 59: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 60: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 61: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 62: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 63: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 64: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 65: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 66: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 67: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 68: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 69: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 70: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 71: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 72: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 73: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 74: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 75: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 76: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 77: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 78: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 79: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 80: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 81: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 82: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 83: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 84: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 85: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 86: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 87: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 88: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 89: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 90: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 91: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 92: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 93: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 94: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 95: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 96: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 97: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 98: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 99: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 100: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 101: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 102: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 103: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 104: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 105: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 106: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 107: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 108: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 109: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 110: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 111: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 112: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 113: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 114: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 115: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 116: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 117: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 118: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 119: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 120: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 121: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 122: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 123: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 124: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 125: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 126: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 127: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 128: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 129: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 130: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 131: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 132: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 133: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 134: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 135: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 136: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 137: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 138: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 139: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 140: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 141: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 142: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 143: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 144: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 145: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 146: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 147: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 148: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 149: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 150: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 151: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 152: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 153: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 154: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 155: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 156: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 157: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 158: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 159: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 160: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 161: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 162: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 163: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 164: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 165: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 166: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 167: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 168: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 169: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 170: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 171: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 172: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 173: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 174: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 175: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 176: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 177: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 178: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 179: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 180: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 181: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 182: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 183: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 184: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 185: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 186: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 187: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 188: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 189: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 190: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 191: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 192: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 193: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 194: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 195: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 196: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 197: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 198: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 199: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 200: + return newstruct cs2func_script_5019_struct(0, -1, -1, -1); + } + return newstruct cs2func_script_5019_struct(0, -1, -1, -1); +} diff --git a/dumps/scripts/502.cs2 b/dumps/scripts/502.cs2 new file mode 100644 index 0000000..ced36c7 --- /dev/null +++ b/dumps/scripts/502.cs2 @@ -0,0 +1,160 @@ +void script_502(int arg0,int arg1) { + flow_0: + if ((arg0 == 66650268) && ((boolean)bitconfig_7520)) { + return; + } + if ((arg0 == 66650269) && ((boolean)bitconfig_7521)) { + return; + } + if ((arg0 == 66650270) && ((boolean)bitconfig_7526)) { + return; + } + if ((arg0 == 66650271) && ((boolean)bitconfig_7527)) { + return; + } + if ((arg0 == 66650272) && ((boolean)bitconfig_7530)) { + return; + } + if ((arg0 == 66650273) && ((boolean)bitconfig_7531)) { + return; + } + if ((arg0 == 66650274) && ((boolean)bitconfig_7532)) { + return; + } + if ((arg0 == 66650275) && ((boolean)bitconfig_7533)) { + return; + } + if ((arg0 == 66650276) && ((boolean)bitconfig_7534)) { + return; + } + if ((arg0 == 66650277) && ((boolean)bitconfig_7535)) { + return; + } + SWITCH (arg1) { + case 66650279: + GOTO flow_31 + case 66650278: + GOTO flow_31 + case 66650281: + GOTO flow_31 + case 66650280: + GOTO flow_31 + case 66650283: + GOTO flow_31 + case 66650282: + GOTO flow_31 + case 66650285: + GOTO flow_31 + case 66650284: + GOTO flow_31 + case 66650287: + GOTO flow_31 + case 66650286: + GOTO flow_31 + case 66650288: + GOTO flow_31 + case 66650289: + GOTO flow_31 + case 66650290: + GOTO flow_31 + case 66650291: + GOTO flow_31 + case 66650292: + GOTO flow_31 + case 66650293: + GOTO flow_31 + case 66650294: + GOTO flow_31 + case 66650295: + GOTO flow_31 + case 66650296: + GOTO flow_31 + case 66650297: + GOTO flow_31 + case 66650298: + GOTO flow_31 + case 66650299: + GOTO flow_31 + case 66650300: + GOTO flow_31 + case 66650301: + GOTO flow_31 + case 66650302: + GOTO flow_31 + case 66650303: + GOTO flow_31 + case 66650337: + GOTO flow_31 + case 66650336: + GOTO flow_31 + case 66650311: + GOTO flow_31 + case 66650310: + GOTO flow_31 + case 66650309: + GOTO flow_31 + case 66650308: + GOTO flow_31 + case 66650307: + GOTO flow_31 + case 66650306: + GOTO flow_31 + case 66650305: + GOTO flow_31 + case 66650304: + GOTO flow_31 + case 66650319: + GOTO flow_31 + case 66650318: + GOTO flow_31 + case 66650317: + GOTO flow_31 + case 66650316: + GOTO flow_31 + case 66650315: + GOTO flow_31 + case 66650314: + GOTO flow_31 + case 66650313: + GOTO flow_31 + case 66650312: + GOTO flow_31 + case 66650326: + GOTO flow_31 + case 66650327: + GOTO flow_31 + case 66650324: + GOTO flow_31 + case 66650325: + GOTO flow_31 + case 66650322: + GOTO flow_31 + case 66650323: + GOTO flow_31 + case 66650320: + GOTO flow_31 + case 66650321: + GOTO flow_31 + case 66650334: + GOTO flow_31 + case 66650335: + GOTO flow_31 + case 66650332: + GOTO flow_31 + case 66650333: + GOTO flow_31 + case 66650330: + GOTO flow_31 + case 66650331: + GOTO flow_31 + case 66650328: + GOTO flow_31 + case 66650329: + GOTO flow_31 + } + return; + flow_31: + setWidgetIsHidden(true, new WidgetPointer(arg0)); + globalint_1387 = 1; + return; +} diff --git a/dumps/scripts/5020.cs2 b/dumps/scripts/5020.cs2 new file mode 100644 index 0000000..6f03d58 --- /dev/null +++ b/dumps/scripts/5020.cs2 @@ -0,0 +1,3 @@ +int script_5020(int arg0) { + return max(bitAnd(arg0, 127), 1); +} diff --git a/dumps/scripts/5021.cs2 b/dumps/scripts/5021.cs2 new file mode 100644 index 0000000..0ccb98f --- /dev/null +++ b/dumps/scripts/5021.cs2 @@ -0,0 +1,3 @@ +int script_5021(int arg0) { + return max(bitAnd(divide(arg0, pow(2, 7)), 127), 1); +} diff --git a/dumps/scripts/5022.cs2 b/dumps/scripts/5022.cs2 new file mode 100644 index 0000000..63fba80 --- /dev/null +++ b/dumps/scripts/5022.cs2 @@ -0,0 +1,3 @@ +int script_5022(int arg0) { + return divide(arg0, pow(2, 14)); +} diff --git a/dumps/scripts/5023.cs2 b/dumps/scripts/5023.cs2 new file mode 100644 index 0000000..8f8d2ae --- /dev/null +++ b/dumps/scripts/5023.cs2 @@ -0,0 +1,3 @@ +int script_5023(int arg0) { + return bitAnd(arg0, 255); +} diff --git a/dumps/scripts/5024.cs2 b/dumps/scripts/5024.cs2 new file mode 100644 index 0000000..436239b --- /dev/null +++ b/dumps/scripts/5024.cs2 @@ -0,0 +1,3 @@ +int script_5024(int arg0) { + return bitAnd(divide(arg0, pow(2, 8)), 63); +} diff --git a/dumps/scripts/5025.cs2 b/dumps/scripts/5025.cs2 new file mode 100644 index 0000000..066658b --- /dev/null +++ b/dumps/scripts/5025.cs2 @@ -0,0 +1,3 @@ +int script_5025(int arg0) { + return divide(arg0, pow(2, 14)); +} diff --git a/dumps/scripts/5026.cs2 b/dumps/scripts/5026.cs2 new file mode 100644 index 0000000..e67fb2b --- /dev/null +++ b/dumps/scripts/5026.cs2 @@ -0,0 +1,3 @@ +int script_5026(int arg0) { + return bitAnd(arg0, 255); +} diff --git a/dumps/scripts/5027.cs2 b/dumps/scripts/5027.cs2 new file mode 100644 index 0000000..f18199e --- /dev/null +++ b/dumps/scripts/5027.cs2 @@ -0,0 +1,3 @@ +int script_5027(int arg0) { + return bitAnd(divide(arg0, pow(2, 8)), 31); +} diff --git a/dumps/scripts/5028.cs2 b/dumps/scripts/5028.cs2 new file mode 100644 index 0000000..57f99cf --- /dev/null +++ b/dumps/scripts/5028.cs2 @@ -0,0 +1,3 @@ +int script_5028(int arg0) { + return divide(arg0, pow(2, 13)); +} diff --git a/dumps/scripts/5029.cs2 b/dumps/scripts/5029.cs2 new file mode 100644 index 0000000..91b2712 --- /dev/null +++ b/dumps/scripts/5029.cs2 @@ -0,0 +1,3 @@ +int script_5029(int arg0) { + return bitAnd(arg0, 255); +} diff --git a/dumps/scripts/503.cs2 b/dumps/scripts/503.cs2 new file mode 100644 index 0000000..461a8bf --- /dev/null +++ b/dumps/scripts/503.cs2 @@ -0,0 +1,53 @@ +void script_503() { + if (((boolean)bitconfig_7516)) { + setWidgetIsHidden(false, new WidgetPointer(1017,156)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1017,156)); + } + if (((boolean)bitconfig_7517)) { + setWidgetIsHidden(false, new WidgetPointer(1017,157)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1017,157)); + } + if (((boolean)bitconfig_7518)) { + setWidgetIsHidden(false, new WidgetPointer(1017,158)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1017,158)); + } + if (((boolean)bitconfig_7519)) { + setWidgetIsHidden(false, new WidgetPointer(1017,159)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1017,159)); + } + if (((boolean)bitconfig_7522)) { + setWidgetIsHidden(false, new WidgetPointer(1017,160)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1017,160)); + } + if (((boolean)bitconfig_7523)) { + setWidgetIsHidden(false, new WidgetPointer(1017,161)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1017,161)); + } + if (((boolean)bitconfig_7524)) { + setWidgetIsHidden(false, new WidgetPointer(1017,162)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1017,162)); + } + if (((boolean)bitconfig_7525)) { + setWidgetIsHidden(false, new WidgetPointer(1017,163)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1017,163)); + } + if (((boolean)bitconfig_7528)) { + setWidgetIsHidden(false, new WidgetPointer(1017,164)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1017,164)); + } + if (((boolean)bitconfig_7529)) { + setWidgetIsHidden(false, new WidgetPointer(1017,165)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1017,165)); + } + return; +} diff --git a/dumps/scripts/5030.cs2 b/dumps/scripts/5030.cs2 new file mode 100644 index 0000000..1d12a68 --- /dev/null +++ b/dumps/scripts/5030.cs2 @@ -0,0 +1,3 @@ +int script_5030(int arg0) { + return bitAnd(divide(arg0, pow(2, 8)), 63); +} diff --git a/dumps/scripts/5031.cs2 b/dumps/scripts/5031.cs2 new file mode 100644 index 0000000..7d901ad --- /dev/null +++ b/dumps/scripts/5031.cs2 @@ -0,0 +1,3 @@ +int script_5031(int arg0) { + return bitAnd(arg0, 255); +} diff --git a/dumps/scripts/5032.cs2 b/dumps/scripts/5032.cs2 new file mode 100644 index 0000000..095906b --- /dev/null +++ b/dumps/scripts/5032.cs2 @@ -0,0 +1,3 @@ +int script_5032(int arg0) { + return bitAnd(divide(arg0, pow(2, 8)), 15); +} diff --git a/dumps/scripts/5033.cs2 b/dumps/scripts/5033.cs2 new file mode 100644 index 0000000..65cef3c --- /dev/null +++ b/dumps/scripts/5033.cs2 @@ -0,0 +1,3 @@ +int script_5033(int arg0) { + return divide(arg0, pow(2, 12)); +} diff --git a/dumps/scripts/5034.cs2 b/dumps/scripts/5034.cs2 new file mode 100644 index 0000000..6942bbd --- /dev/null +++ b/dumps/scripts/5034.cs2 @@ -0,0 +1,3 @@ +int script_5034(int arg0) { + return bitAnd(arg0, 63); +} diff --git a/dumps/scripts/5035.cs2 b/dumps/scripts/5035.cs2 new file mode 100644 index 0000000..ddb85ba --- /dev/null +++ b/dumps/scripts/5035.cs2 @@ -0,0 +1,3 @@ +int script_5035(int arg0) { + return bitAnd(divide(arg0, pow(2, 6)), 15); +} diff --git a/dumps/scripts/5036.cs2 b/dumps/scripts/5036.cs2 new file mode 100644 index 0000000..16d0493 --- /dev/null +++ b/dumps/scripts/5036.cs2 @@ -0,0 +1,3 @@ +int script_5036(int arg0) { + return divide(arg0, pow(2, 10)); +} diff --git a/dumps/scripts/5037.cs2 b/dumps/scripts/5037.cs2 new file mode 100644 index 0000000..190ec25 --- /dev/null +++ b/dumps/scripts/5037.cs2 @@ -0,0 +1,112 @@ +void script_5037(int arg0) { + int ivar1; + int ivar2; + setWidgetIsHidden(false, new WidgetPointer(1111,9)); + setWidgetIsHidden(true, new WidgetPointer(1111,1)); + script_4510(72810501, 1736); + script_4510(72810502, 1737); + script_4211(72810504, 4040, 15458492, 5918266); + setScriptCallOnCitadelConfigChange(5039, "", new WidgetPointer(arg0)); + setScriptCallOnMouseScroll(5042, new WidgetPointer(arg0), -2147483646, "Ii", new WidgetPointer(1111,15)); + setScriptCallOnClickContextMenu(5042, new WidgetPointer(arg0), 1, "Ii", new WidgetPointer(1111,46)); + setScriptCallOnClickContextMenu(5042, new WidgetPointer(arg0), -1, "Ii", new WidgetPointer(1111,53)); + setScriptCallOnMouseDragReleased(5043, new WidgetPointer(arg0), new WidgetPointer(-32768,3), -2147483647, "IIi", new WidgetPointer(1111,51)); + ivar1 = 0; + ivar2 = pow(112, 2); + while (ivar1 < ivar2) { + createExtraChild(new WidgetPointer(1111,16), 3, ivar1); + setWidgetRGB(new Color(31, 31, 38)); + setWidgetFilled(1); + setWidgetContextMenuOption(1, "Set"); + setWidgetContextMenuOption(10, "Teleport"); + cs2method1304(5); + cs2method1302(2); + setScriptCallOnMouseDragged(5054, -2147483647, -2147483646, "ii"); + ivar1 = add(ivar1, 1); + } + script_5040(); + createExtraChild(new WidgetPointer(1111,19), 5, 0); + createExtraChild(new WidgetPointer(1111,20), 5, 0); + setWidgetPosition(0, 0, 1, 1); + setWidgetPosition(0, 0, 1, 1); + setWidgetSize(0, 32, 1, 1); + setWidgetSize(32, 0, 1, 1); + setWidgetSprite(5666); + setWidgetSprite(7605); + cs2method1107(1); + cs2method1107(1); + setScriptCallOnMousePressed(5052, new WidgetPointer(-32768,3), 1, "I1"); + setScriptCallOnMousePressed(5052, new WidgetPointer(-32768,3), 0, "I1"); + createExtraChild(new WidgetPointer(1111,19), 5, 1); + createExtraChild(new WidgetPointer(1111,20), 5, 1); + setWidgetPosition(0, 0, 1, 0); + setWidgetPosition(0, 0, 0, 1); + setWidgetSize(0, 16, 1, 0); + setWidgetSize(16, 0, 0, 1); + setWidgetSprite(5686); + setWidgetSprite(5686); + cs2method1106(16384); + setScriptCallOnMouseDraggedOver(5049, -4, 1, 1, "ii1"); + setScriptCallOnMouseDraggedOver(5049, -4, 1, 0, "ii1"); + createExtraChild(new WidgetPointer(1111,19), 5, 2); + createExtraChild(new WidgetPointer(1111,20), 5, 2); + setWidgetPosition(0, 0, 1, 2); + setWidgetPosition(0, 0, 2, 1); + setWidgetSize(0, 16, 1, 0); + setWidgetSize(16, 0, 0, 1); + setWidgetSprite(5685); + setWidgetSprite(5685); + cs2method1106(16384); + setScriptCallOnMouseDraggedOver(5049, 4, 1, 1, "ii1"); + setScriptCallOnMouseDraggedOver(5049, 4, 1, 0, "ii1"); + createExtraChild(new WidgetPointer(1111,19), 5, 3); + createExtraChild(new WidgetPointer(1111,20), 5, 3); + setWidgetSprite(5664); + setWidgetSprite(7603); + cs2method1107(1); + cs2method1107(1); + cs2method1301(72810515, 0); + cs2method1301(72810516, 0); + cs2method1302(1); + cs2method1302(1); + setScriptCallOnMouseDragged(5051, new WidgetPointer(-32768,3), -2147483646, 0, 1, "Ii11"); + setScriptCallOnMouseDragged(5051, new WidgetPointer(-32768,3), -2147483647, 0, 0, "Ii11"); + setScriptCallOnMouseDragReleased(5051, new WidgetPointer(-32768,3), -2147483646, 1, 1, "Ii11"); + setScriptCallOnMouseDragReleased(5051, new WidgetPointer(-32768,3), -2147483647, 1, 0, "Ii11"); + createExtraChild(new WidgetPointer(1111,19), 5, 4); + createExtraChild(new WidgetPointer(1111,20), 5, 4); + setWidgetSize(0, 5, 1, 0); + setWidgetSize(5, 0, 0, 1); + setWidgetSprite(5663); + setWidgetSprite(7602); + createExtraChild(new WidgetPointer(1111,19), 5, 5); + createExtraChild(new WidgetPointer(1111,20), 5, 5); + setWidgetSize(0, 5, 1, 0); + setWidgetSize(5, 0, 0, 1); + setWidgetSprite(5665); + setWidgetSprite(7604); + setScriptCallOnMouseScroll(5049, -2147483646, 20, 1, "ii1", new WidgetPointer(1111,19)); + setScriptCallOnMouseScroll(5049, -2147483646, 20, 0, "ii1", new WidgetPointer(1111,20)); + createExtraChild(new WidgetPointer(1111,15), 3, 0); + setWidgetFilled(0); + setWidgetHidden(1); + setScriptCallOnGameloop(5074, new WidgetPointer(-32768,3), getWidgetCustomChildArrayIndex(), "Ii", new WidgetPointer(1111,15)); + setScriptCallOnGlobalConfigChange(5074, new WidgetPointer(-32768,3), getWidgetCustomChildArrayIndex(), 1065, 1, "IiY", new WidgetPointer(1111,15)); + setScriptCallOnClickContextMenu(5075, new WidgetPointer(1111,15), getWidgetCustomChildArrayIndex(), "Ii", new WidgetPointer(1111,54)); + if ((globalint_1396 < 3) || (globalint_1396 > 21)) { + globalint_1396 = add(3, divide(subtract(21, 3), 4)); + } + script_5047(globalint_1396, 0, 112, 0, 0); + script_5048(); + script_5073(1); + script_5055(1, 3944, 72810564, 72810553, 72810554, "Architecture"); + script_5055(2, 3945, 72810565, 72810556, 72810557, "Toys"); + script_5055(3, 3946, 72810566, 72810559, 72810560, "Hazards"); + script_5055(4, 3947, 72810567, 72810562, 72810563, "Monsters"); + globalint_768 = 1; + script_5065(1); + setScriptCallOnConfigChange(5066, 1736, 1, "Y", new WidgetPointer(arg0)); + script_5067(); + script_5076(72810511, 0); + return; +} diff --git a/dumps/scripts/5038.cs2 b/dumps/scripts/5038.cs2 new file mode 100644 index 0000000..0f1bedb --- /dev/null +++ b/dumps/scripts/5038.cs2 @@ -0,0 +1,11 @@ +void script_5038(int arg0) { + playSoundEffect2False(6185, 1, 0, 200); + if (((boolean)arg0)) { + setWidgetIsHidden(true, new WidgetPointer(1111,9)); + setWidgetIsHidden(false, new WidgetPointer(1111,1)); + } else { + setWidgetIsHidden(false, new WidgetPointer(1111,9)); + setWidgetIsHidden(true, new WidgetPointer(1111,1)); + } + return; +} diff --git a/dumps/scripts/5039.cs2 b/dumps/scripts/5039.cs2 new file mode 100644 index 0000000..a17f2c5 --- /dev/null +++ b/dumps/scripts/5039.cs2 @@ -0,0 +1,5 @@ +void script_5039() { + script_5040(); + script_5048(); + return; +} diff --git a/dumps/scripts/504.cs2 b/dumps/scripts/504.cs2 new file mode 100644 index 0000000..7ddb5d9 --- /dev/null +++ b/dumps/scripts/504.cs2 @@ -0,0 +1,6 @@ +void script_504() { + script_505(); + script_1371(); + script_1381(); + return; +} diff --git a/dumps/scripts/5040.cs2 b/dumps/scripts/5040.cs2 new file mode 100644 index 0000000..a558a74 --- /dev/null +++ b/dumps/scripts/5040.cs2 @@ -0,0 +1,53 @@ +void script_5040() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int stack_dump0; + cs2func_script_5019_struct(4,0,0) structdump_1; + deleteAllExtraChilds(new WidgetPointer(1111,18)); + ivar0 = 0; + ivar1 = 0; + ivar2 = -1; + ivar3 = -1; + ivar4 = -1; + ivar5 = -1; + ivar6 = 200; + if (citadelConfigsInitialized()) { + while (ivar0 < 200) { + createExtraChild(new WidgetPointer(1111,18), 5, ivar0); + stack_dump0 = ivar0; + structdump_1 = script_5019(stack_dump0); + ivar5 = structdump_1.intpart_3; + ivar4 = structdump_1.intpart_2; + ivar3 = structdump_1.intpart_1; + ivar1 = structdump_1.intpart_0; + if (ivar1 != 0) { + ivar2 = cs2method_3408(105, 74, 3943, ivar1); + if (ivar2 != -1) { + setWidgetSprite(getOtherCommonData(ivar2, 1465)); + if (((boolean)getOtherCommonData(ivar2, 1466))) { + cs2method1107(1); + } else { + cs2method1107(0); + } + script_5041(ivar2, ivar3, ivar4, ivar5); + ivar6 = subtract(ivar6, 1); + } else { + setWidgetHidden(1); + } + } else { + setWidgetHidden(1); + } + ivar0 = add(ivar0, 1); + } + setWidgetText(new WidgetPointer(1111,93), intToStr(ivar6)); + } else { + setWidgetText(new WidgetPointer(1111,93), "..."); + } + script_41(72810627); + return; +} diff --git a/dumps/scripts/5041.cs2 b/dumps/scripts/5041.cs2 new file mode 100644 index 0000000..4738f5a --- /dev/null +++ b/dumps/scripts/5041.cs2 @@ -0,0 +1,94 @@ +void script_5041(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + string svar0; + setWidgetContextMenuOption(6, "Delete"); + setWidgetIntegerNode(1474, arg1); + setWidgetIntegerNode(1475, arg2); + svar0 = getOtherCommonData(arg0, 1463); + cs2method1305("" + svar0); + ivar4 = -1; + switch (getOtherCommonData(arg0, 1466)) { + case 1: + setWidgetIntegerNode(1476, script_5020(arg3)); + setWidgetIntegerNode(1477, script_5021(arg3)); + ivar4 = getOtherCommonData(arg0, 1470); + if (ivar4 != -1) { + svar0 = concat(svar0, "
" + cs2method_3408(105, 115, ivar4, -1) + " " + cs2method_3408(105, 115, ivar4, script_5022(arg3))); + } + break; + case 2: + ivar4 = getOtherCommonData(arg0, 1470); + if (ivar4 != -1) { + svar0 = concat(svar0, "
" + cs2method_3408(105, 115, ivar4, -1) + " " + cs2method_3408(105, 115, ivar4, script_5023(arg3))); + } + ivar4 = getOtherCommonData(arg0, 1471); + if (ivar4 != -1) { + svar0 = concat(svar0, "
" + cs2method_3408(105, 115, ivar4, -1) + " " + cs2method_3408(105, 115, ivar4, script_5024(arg3))); + } + ivar4 = getOtherCommonData(arg0, 1472); + if (ivar4 != -1) { + svar0 = concat(svar0, "
" + cs2method_3408(105, 115, ivar4, -1) + " " + cs2method_3408(105, 115, ivar4, script_5025(arg3))); + } + break; + case 3: + ivar4 = getOtherCommonData(arg0, 1470); + if (ivar4 != -1) { + svar0 = concat(svar0, "
" + cs2method_3408(105, 115, ivar4, -1) + " " + cs2method_3408(105, 115, ivar4, script_5026(arg3))); + } + ivar4 = getOtherCommonData(arg0, 1471); + if (ivar4 != -1) { + svar0 = concat(svar0, "
" + cs2method_3408(105, 115, ivar4, -1) + " " + cs2method_3408(105, 115, ivar4, script_5027(arg3))); + } + ivar4 = getOtherCommonData(arg0, 1472); + if (ivar4 != -1) { + svar0 = concat(svar0, "
" + cs2method_3408(105, 115, ivar4, -1) + " " + cs2method_3408(105, 115, ivar4, script_5028(arg3))); + } + break; + case 4: + ivar4 = getOtherCommonData(arg0, 1470); + if (ivar4 != -1) { + svar0 = concat(svar0, "
" + cs2method_3408(105, 115, ivar4, -1) + " " + cs2method_3408(105, 115, ivar4, script_5029(arg3))); + } + ivar4 = getOtherCommonData(arg0, 1471); + if (ivar4 != -1) { + svar0 = concat(svar0, "
" + cs2method_3408(105, 115, ivar4, -1) + " " + cs2method_3408(105, 115, ivar4, script_5030(arg3))); + } + break; + case 5: + ivar4 = getOtherCommonData(arg0, 1470); + if (ivar4 != -1) { + svar0 = concat(svar0, "
" + cs2method_3408(105, 115, ivar4, -1) + " " + cs2method_3408(105, 115, ivar4, script_5031(arg3))); + } + ivar4 = getOtherCommonData(arg0, 1471); + if (ivar4 != -1) { + svar0 = concat(svar0, "
" + cs2method_3408(105, 115, ivar4, -1) + " " + cs2method_3408(105, 115, ivar4, script_5032(arg3))); + } + ivar4 = getOtherCommonData(arg0, 1472); + if (ivar4 != -1) { + svar0 = concat(svar0, "
" + cs2method_3408(105, 115, ivar4, -1) + " " + cs2method_3408(105, 115, ivar4, script_5033(arg3))); + } + break; + case 6: + ivar4 = getOtherCommonData(arg0, 1470); + if (ivar4 != -1) { + svar0 = concat(svar0, "
" + cs2method_3408(105, 115, ivar4, -1) + " " + cs2method_3408(105, 115, ivar4, script_5034(arg3))); + } + ivar4 = getOtherCommonData(arg0, 1471); + if (ivar4 != -1) { + svar0 = concat(svar0, "
" + cs2method_3408(105, 115, ivar4, -1) + " " + cs2method_3408(105, 115, ivar4, script_5035(arg3))); + } + ivar4 = getOtherCommonData(arg0, 1472); + if (ivar4 != -1) { + svar0 = concat(svar0, "
" + cs2method_3408(105, 115, ivar4, -1) + " " + cs2method_3408(105, 115, ivar4, script_5036(arg3))); + } + break; + default: + ivar4 = getOtherCommonData(arg0, 1470); + if (ivar4 != -1) { + svar0 = concat(svar0, "
" + cs2method_3408(105, 115, ivar4, -1) + " " + cs2method_3408(105, 115, ivar4, arg3)); + } + } + setScriptCallOnMouseOver(5077, new WidgetPointer(-32768,3), -2147483643, svar0, -2147483647, -2147483646, "Iisii"); + setScriptCallOnMouseExit(40, new WidgetPointer(1111,131), "I"); + return; +} diff --git a/dumps/scripts/5042.cs2 b/dumps/scripts/5042.cs2 new file mode 100644 index 0000000..ff6b80d --- /dev/null +++ b/dumps/scripts/5042.cs2 @@ -0,0 +1,29 @@ +void script_5042(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int stack_dump0; + ivar2 = subtract(getLastMouseY(), script_3365(72810511)); + ivar3 = subtract(getLastMouseX(), script_3366(72810511)); + ivar4 = getWidgetActualWidth(new WidgetPointer(1111,15)); + ivar5 = getWidgetActualHeight(new WidgetPointer(1111,15)); + if ((((ivar2 > ivar4) || (ivar2 < 0)) || (ivar3 > ivar5)) || (ivar3 < 0)) { + stack_dump0 = divide(ivar4, 2); + ivar3 = divide(ivar5, 2); + ivar2 = stack_dump0; + } + ivar2 = add(ivar2, cs2method2600(new WidgetPointer(1111,15))); + ivar3 = add(ivar3, cs2method2601(new WidgetPointer(1111,15))); + ivar6 = multiply(globalint_1396, add(add(112, 2), 2)); + globalint_1396 = max(min(subtract(globalint_1396, arg1), 21), 3); + ivar7 = multiply(globalint_1396, add(add(112, 2), 2)); + ivar8 = subtract(multiplyDivide(ivar7, ivar6, ivar2), ivar2); + ivar9 = subtract(multiplyDivide(ivar7, ivar6, ivar3), ivar3); + script_5044(arg0, ivar8, ivar9); + return; +} diff --git a/dumps/scripts/5043.cs2 b/dumps/scripts/5043.cs2 new file mode 100644 index 0000000..8eee2f3 --- /dev/null +++ b/dumps/scripts/5043.cs2 @@ -0,0 +1,5 @@ +void script_5043(int arg0,int arg1,int arg2) { + globalint_1396 = max(min(add(3, multiplyDivide(add(arg2, divide(getWidgetActualWidth(new WidgetPointer(arg1)), 2)), getWidgetActualWidth(new WidgetPointer(getWidgetParentId(new WidgetPointer(arg1)))), add(subtract(21, 3), 1))), 21), 3); + script_5044(arg0, 0, 0); + return; +} diff --git a/dumps/scripts/5044.cs2 b/dumps/scripts/5044.cs2 new file mode 100644 index 0000000..1703c31 --- /dev/null +++ b/dumps/scripts/5044.cs2 @@ -0,0 +1,5 @@ +void script_5044(int arg0,int arg1,int arg2) { + script_5045(arg0, arg1, arg2); + script_5048(); + return; +} diff --git a/dumps/scripts/5045.cs2 b/dumps/scripts/5045.cs2 new file mode 100644 index 0000000..ad88526 --- /dev/null +++ b/dumps/scripts/5045.cs2 @@ -0,0 +1,4 @@ +void script_5045(int arg0,int arg1,int arg2) { + setScriptCallOnGameloop(5046, new WidgetPointer(arg0), globalint_1396, 0, arg1, arg2, "Iiiii", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/5046.cs2 b/dumps/scripts/5046.cs2 new file mode 100644 index 0000000..1bef3f6 --- /dev/null +++ b/dumps/scripts/5046.cs2 @@ -0,0 +1,13 @@ +void script_5046(int arg0,int arg1,int arg2,int arg3,int arg4) { + if (arg2 < 1) { + script_5047(arg1, 0, 40, arg3, arg4); + setScriptCallOnGameloop(5046, new WidgetPointer(arg0), globalint_1396, 1, arg3, arg4, "Iiiii", new WidgetPointer(arg0)); + } else if (arg2 < 2) { + script_5047(arg1, 40, 80, arg3, arg4); + setScriptCallOnGameloop(5046, new WidgetPointer(arg0), globalint_1396, 2, arg3, arg4, "Iiiii", new WidgetPointer(arg0)); + } else { + script_5047(arg1, 80, 112, arg3, arg4); + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/5047.cs2 b/dumps/scripts/5047.cs2 new file mode 100644 index 0000000..ec7744e --- /dev/null +++ b/dumps/scripts/5047.cs2 @@ -0,0 +1,44 @@ +void script_5047(int arg0,int arg1,int arg2,int arg3,int arg4) { + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + ivar5 = multiply(arg0, add(add(112, 2), 2)); + setWidgetScrollMax(ivar5, ivar5, new WidgetPointer(1111,15)); + ivar6 = subtract(ivar5, getWidgetActualWidth(new WidgetPointer(1111,15))); + if (cs2method2600(new WidgetPointer(1111,15)) > ivar6) { + cs2method2100(ivar6, cs2method2601(new WidgetPointer(1111,15)), new WidgetPointer(1111,15)); + } + if (cs2method2601(new WidgetPointer(1111,15)) > ivar6) { + cs2method2100(cs2method2600(new WidgetPointer(1111,15)), ivar6, new WidgetPointer(1111,15)); + } + setWidgetSize(ivar5, ivar5, 0, 0, new WidgetPointer(1111,16)); + setWidgetSize(ivar5, ivar5, 0, 0, new WidgetPointer(1111,18)); + ivar7 = 0; + ivar8 = subtract(arg0, 1); + ivar9 = 0; + ivar10 = arg1; + while (ivar10 < arg2) { + ivar9 = subtract(ivar5, multiply(add(add(ivar10, 2), 1), arg0)); + while (ivar7 < 112) { + if (setWidgetRegister(new WidgetPointer(1111,16), add(multiply(ivar10, 112), ivar7))) { + setWidgetSize(ivar8, ivar8, 0, 0); + setWidgetPosition(multiply(add(ivar7, 2), arg0), ivar9, 0, 0); + cs2method1303(divide(arg0, 2)); + } + ivar7 = add(ivar7, 1); + } + ivar7 = 0; + ivar10 = add(ivar10, 1); + } + if (arg1 <= 0) { + script_5053(arg3, arg4); + ivar9 = subtract(multiply(arg0, 2), 3); + setWidgetPosition(ivar9, ivar9, 0, 0, new WidgetPointer(1111,17)); + ivar9 = add(multiply(arg0, 112), 5); + setWidgetSize(ivar9, ivar9, 0, 0, new WidgetPointer(1111,17)); + } + return; +} diff --git a/dumps/scripts/5048.cs2 b/dumps/scripts/5048.cs2 new file mode 100644 index 0000000..012a500 --- /dev/null +++ b/dumps/scripts/5048.cs2 @@ -0,0 +1,27 @@ +void script_5048() { + int ivar0; + int ivar1; + int stack_dump0; + int stack_dump1; + ivar0 = multiply(globalint_1396, add(add(112, 2), 2)); + ivar1 = 0; + while (ivar1 < 200) { + if (setWidgetRegister(new WidgetPointer(1111,18), ivar1)) { + stack_dump0 = globalint_1396; + stack_dump1 = 1476; + /* + mgi.tools.jagdecs2.DecompilerException: opcode 1613 not decompileable + at mgi.tools.jagdecs2.FlowBlocksGenerator.analyzeSpecialCall(FlowBlocksGenerator.java:297) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:249) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + ivar1 = add(ivar1, 1); + } + setWidgetPosition(multiplyDivide(max(subtract(globalint_1396, 3), 0), max(subtract(21, 3), 1), subtract(getWidgetActualWidth(new WidgetPointer(getWidgetParentId(new WidgetPointer(1111,51)))), getWidgetActualWidth(new WidgetPointer(1111,51)))), 0, 0, 1, new WidgetPointer(1111,51)); + return; +} diff --git a/dumps/scripts/5049.cs2 b/dumps/scripts/5049.cs2 new file mode 100644 index 0000000..58aae53 --- /dev/null +++ b/dumps/scripts/5049.cs2 @@ -0,0 +1,4 @@ +void script_5049(int arg0,int arg1,int arg2) { + script_5050(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/505.cs2 b/dumps/scripts/505.cs2 new file mode 100644 index 0000000..5da2f98 --- /dev/null +++ b/dumps/scripts/505.cs2 @@ -0,0 +1,13 @@ +void script_505() { + setWidgetText(new WidgetPointer(1017,156), script_483(bitconfig_7520)); + setWidgetText(new WidgetPointer(1017,157), script_483(bitconfig_7521)); + setWidgetText(new WidgetPointer(1017,158), script_483(bitconfig_7526)); + setWidgetText(new WidgetPointer(1017,159), script_483(bitconfig_7527)); + setWidgetText(new WidgetPointer(1017,160), script_483(bitconfig_7530)); + setWidgetText(new WidgetPointer(1017,161), script_483(bitconfig_7531)); + setWidgetText(new WidgetPointer(1017,162), script_483(bitconfig_7532)); + setWidgetText(new WidgetPointer(1017,163), script_483(bitconfig_7533)); + setWidgetText(new WidgetPointer(1017,164), script_483(bitconfig_7534)); + setWidgetText(new WidgetPointer(1017,165), script_483(bitconfig_7535)); + return; +} diff --git a/dumps/scripts/5050.cs2 b/dumps/scripts/5050.cs2 new file mode 100644 index 0000000..f44cb43 --- /dev/null +++ b/dumps/scripts/5050.cs2 @@ -0,0 +1,10 @@ +void script_5050(int arg0,int arg1,int arg2) { + arg0 = multiply(arg0, arg1); + if (((boolean)arg2)) { + cs2method2100(cs2method2600(new WidgetPointer(1111,15)), max(add(cs2method2601(new WidgetPointer(1111,15)), arg0), 0), new WidgetPointer(1111,15)); + } else { + cs2method2100(max(add(cs2method2600(new WidgetPointer(1111,15)), arg0), 0), cs2method2601(new WidgetPointer(1111,15)), new WidgetPointer(1111,15)); + } + script_5053(0, 0); + return; +} diff --git a/dumps/scripts/5051.cs2 b/dumps/scripts/5051.cs2 new file mode 100644 index 0000000..6e6d31b --- /dev/null +++ b/dumps/scripts/5051.cs2 @@ -0,0 +1,27 @@ +void script_5051(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + ivar4 = getWidgetActualWidth(new WidgetPointer(1111,15)); + if (setWidgetRegister(new WidgetPointer(arg0), 3)) { + if (((boolean)arg3)) { + if (setWidgetRegister(new WidgetPointer(arg0), 4)) { + setWidgetPosition(0, add(arg1, 16), 1, 0); + } + if (setWidgetRegister(new WidgetPointer(arg0), 5)) { + setWidgetPosition(0, subtract(add(add(arg1, 16), getWidgetActualHeight()), getWidgetActualHeight()), 1, 0); + } + cs2method2100(cs2method2600(new WidgetPointer(1111,15)), multiplyDivide(arg1, max(subtract(subtract(ivar4, 32), getWidgetActualHeight()), 1), subtract(getWidgetScrollMaxV(new WidgetPointer(1111,15)), ivar4)), new WidgetPointer(1111,15)); + } else { + if (setWidgetRegister(new WidgetPointer(arg0), 4)) { + setWidgetPosition(add(arg1, 16), 0, 0, 1); + } + if (setWidgetRegister(new WidgetPointer(arg0), 5)) { + setWidgetPosition(subtract(add(add(arg1, 16), getWidgetActualWidth()), getWidgetActualWidth()), 0, 0, 1); + } + cs2method2100(multiplyDivide(arg1, max(subtract(subtract(ivar4, 32), getWidgetActualWidth()), 1), subtract(getWidgetScrollMaxH(new WidgetPointer(1111,15)), ivar4)), cs2method2601(new WidgetPointer(1111,15)), new WidgetPointer(1111,15)); + } + } + if (((boolean)arg2)) { + script_5053(0, 0); + } + return; +} diff --git a/dumps/scripts/5052.cs2 b/dumps/scripts/5052.cs2 new file mode 100644 index 0000000..3a8bee8 --- /dev/null +++ b/dumps/scripts/5052.cs2 @@ -0,0 +1,10 @@ +void script_5052(int arg0,int arg1) { + if (setWidgetRegister(new WidgetPointer(arg0), 3)) { + if (((boolean)arg1)) { + cs2method3109(0, divide(getWidgetActualHeight(), 2)); + } else { + cs2method3109(divide(getWidgetActualWidth(), 2), 0); + } + } + return; +} diff --git a/dumps/scripts/5053.cs2 b/dumps/scripts/5053.cs2 new file mode 100644 index 0000000..7c69825 --- /dev/null +++ b/dumps/scripts/5053.cs2 @@ -0,0 +1,32 @@ +void script_5053(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + cs2method2100(add(cs2method2600(new WidgetPointer(1111,15)), arg0), add(cs2method2601(new WidgetPointer(1111,15)), arg1), new WidgetPointer(1111,15)); + ivar2 = getWidgetScrollMaxH(new WidgetPointer(1111,15)); + ivar3 = getWidgetActualWidth(new WidgetPointer(1111,15)); + ivar4 = subtract(ivar3, 32); + ivar5 = min(max(multiplyDivide(ivar3, ivar2, ivar4), 10), ivar4); + ivar6 = multiplyDivide(cs2method2601(new WidgetPointer(1111,15)), max(subtract(ivar2, ivar3), 1), subtract(ivar4, ivar5)); + ivar7 = multiplyDivide(cs2method2600(new WidgetPointer(1111,15)), max(subtract(ivar2, ivar3), 1), subtract(ivar4, ivar5)); + ivar6 = add(max(min(ivar6, subtract(ivar4, ivar5)), 0), 16); + ivar7 = add(max(min(ivar7, subtract(ivar4, ivar5)), 0), 16); + if (setWidgetRegister(new WidgetPointer(1111,19), 3) && setWidgetRegister(new WidgetPointer(1111,20), 3)) { + setWidgetSize(0, ivar5, 1, 0); + setWidgetSize(ivar5, 0, 0, 1); + setWidgetPosition(0, ivar6, 1, 0); + setWidgetPosition(ivar7, 0, 0, 1); + } + if (setWidgetRegister(new WidgetPointer(1111,19), 4) && setWidgetRegister(new WidgetPointer(1111,20), 4)) { + setWidgetPosition(0, ivar6, 1, 0); + setWidgetPosition(ivar7, 0, 0, 1); + } + if (setWidgetRegister(new WidgetPointer(1111,19), 5) && setWidgetRegister(new WidgetPointer(1111,20), 5)) { + setWidgetPosition(0, subtract(add(ivar6, ivar5), getWidgetActualHeight()), 1, 0); + setWidgetPosition(subtract(add(ivar7, ivar5), getWidgetActualWidth()), 0, 0, 1); + } + return; +} diff --git a/dumps/scripts/5054.cs2 b/dumps/scripts/5054.cs2 new file mode 100644 index 0000000..d30c0f0 --- /dev/null +++ b/dumps/scripts/5054.cs2 @@ -0,0 +1,19 @@ +void script_5054(int arg0,int arg1) { + arg0 = subtract(arg0, cs2method2600(new WidgetPointer(1111,15))); + arg1 = subtract(arg1, cs2method2601(new WidgetPointer(1111,15))); + if (arg0 < 10) { + script_5050(-10, 1, 0); + } else { + if (arg0 > subtract(getWidgetActualWidth(new WidgetPointer(1111,15)), add(globalint_1396, 10))) { + script_5050(10, 1, 0); + } + } + if (arg1 < 10) { + script_5050(-10, 1, 1); + } else { + if (arg1 > subtract(getWidgetActualHeight(new WidgetPointer(1111,15)), add(globalint_1396, 10))) { + script_5050(10, 1, 1); + } + } + return; +} diff --git a/dumps/scripts/5055.cs2 b/dumps/scripts/5055.cs2 new file mode 100644 index 0000000..1412643 --- /dev/null +++ b/dumps/scripts/5055.cs2 @@ -0,0 +1,154 @@ +void script_5055(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5) { + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int stack_dump0; + deleteAllExtraChilds(new WidgetPointer(arg2)); + createExtraChild(new WidgetPointer(arg2), 5, getExtraChildGap(new WidgetPointer(arg2))); + setWidgetSize(40, 0, 1, 1); + setWidgetPosition(0, 0, 1, 1); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg2), 5, getExtraChildGap(new WidgetPointer(arg2))); + setWidgetSize(20, 0, 0, 1); + setWidgetPosition(0, 0, 0, 1); + createExtraChild(new WidgetPointer(arg2), 5, getExtraChildGap(new WidgetPointer(arg2))); + setWidgetSize(20, 0, 0, 1); + setWidgetPosition(0, 0, 2, 1); + createExtraChild(new WidgetPointer(arg2), 5, getExtraChildGap(new WidgetPointer(arg2))); + setWidgetSize(10, 10, 0, 0); + setWidgetPosition(7, 0, 0, 1); + createExtraChild(new WidgetPointer(arg2), 4, getExtraChildGap(new WidgetPointer(arg2))); + setWidgetSize(20, 0, 1, 1); + setWidgetPosition(0, 1, 2, 1); + setWidgetFont(494); + setWidgetTextAlignment(0, 1, 0); + setWidgetRGB(new Color(255, 239, 95)); + setWidgetUnknownBoolean(true); + setWidgetText(arg5); + setScriptCallOnMousePressed(5064, arg0, "i", new WidgetPointer(arg2)); + deleteAllExtraChilds(new WidgetPointer(arg3)); + deleteAllExtraChilds(new WidgetPointer(arg4)); + ivar5 = 0; + ivar6 = getCommonDefinitionSize(3943); + while (ivar5 < ivar6) { + createExtraChild(new WidgetPointer(arg3), 3, getExtraChildGap(new WidgetPointer(arg3))); + setWidgetHidden(1); + createExtraChild(new WidgetPointer(arg3), 3, getExtraChildGap(new WidgetPointer(arg3))); + setWidgetHidden(1); + createExtraChild(new WidgetPointer(arg3), 5, getExtraChildGap(new WidgetPointer(arg3))); + setWidgetHidden(1); + createExtraChild(new WidgetPointer(arg3), 5, getExtraChildGap(new WidgetPointer(arg3))); + setWidgetHidden(1); + createExtraChild(new WidgetPointer(arg3), 5, getExtraChildGap(new WidgetPointer(arg3))); + setWidgetHidden(1); + createExtraChild(new WidgetPointer(arg3), 5, getExtraChildGap(new WidgetPointer(arg3))); + setWidgetHidden(1); + createExtraChild(new WidgetPointer(arg3), 5, getExtraChildGap(new WidgetPointer(arg3))); + setWidgetHidden(1); + createExtraChild(new WidgetPointer(arg3), 5, getExtraChildGap(new WidgetPointer(arg3))); + setWidgetHidden(1); + createExtraChild(new WidgetPointer(arg3), 5, getExtraChildGap(new WidgetPointer(arg3))); + setWidgetHidden(1); + createExtraChild(new WidgetPointer(arg3), 3, getExtraChildGap(new WidgetPointer(arg3))); + setWidgetHidden(1); + createExtraChild(new WidgetPointer(arg3), 5, getExtraChildGap(new WidgetPointer(arg3))); + setWidgetHidden(1); + createExtraChild(new WidgetPointer(arg3), 4, getExtraChildGap(new WidgetPointer(arg3))); + setWidgetHidden(1); + ivar5 = add(ivar5, 1); + } + ivar7 = -1; + ivar8 = -1; + ivar9 = 0; + stack_dump0 = 0; + ivar6 = getCommonDefinitionSize(arg1); + ivar5 = stack_dump0; + while (ivar5 < ivar6) { + ivar7 = cs2method_3408(105, 105, arg1, ivar5); + ivar8 = cs2method_3408(105, 74, 3943, ivar7); + if (ivar8 != -1) { + if (setWidgetRegister(new WidgetPointer(arg3), multiply(ivar7, 12))) { + setWidgetSize(24, 26, 1, 0); + setWidgetPosition(0, ivar9, 0, 0); + cs2method2103(255); + setWidgetContextMenuOption(1, "Select"); + setScriptCallOnClickContextMenu(5070, -2147483644, ivar7, 0, "ii1"); + setWidgetHidden(0); + } + if (setWidgetRegister(new WidgetPointer(arg3), add(multiply(ivar7, 12), 1))) { + setWidgetSize(24, 26, 0, 0); + setWidgetPosition(0, ivar9, 2, 0); + cs2method2103(255); + setWidgetContextMenuOption(1, "Select & open settings"); + setScriptCallOnClickContextMenu(5070, -2147483644, ivar7, 1, "ii1"); + setWidgetHidden(0); + } + if (setWidgetRegister(new WidgetPointer(arg3), add(multiply(ivar7, 12), 2))) { + setWidgetSize(40, 26, 1, 0); + setWidgetPosition(8, ivar9, 0, 0); + setWidgetHidden(0); + } + if (setWidgetRegister(new WidgetPointer(arg3), add(multiply(ivar7, 12), 3))) { + setWidgetSize(8, 26, 0, 0); + setWidgetPosition(0, ivar9, 0, 0); + setWidgetHidden(0); + } + if (setWidgetRegister(new WidgetPointer(arg3), add(multiply(ivar7, 12), 4))) { + setWidgetSize(8, 26, 0, 0); + setWidgetPosition(24, ivar9, 2, 0); + setWidgetHidden(0); + } + if (setWidgetRegister(new WidgetPointer(arg3), add(multiply(ivar7, 12), 5))) { + setWidgetSize(8, 26, 0, 0); + setWidgetPosition(8, ivar9, 2, 0); + setWidgetHidden(0); + } + if (setWidgetRegister(new WidgetPointer(arg3), add(multiply(ivar7, 12), 6))) { + setWidgetSize(8, 26, 0, 0); + setWidgetPosition(16, ivar9, 2, 0); + setWidgetHidden(0); + } + if (setWidgetRegister(new WidgetPointer(arg3), add(multiply(ivar7, 12), 7))) { + setWidgetSize(8, 26, 0, 0); + setWidgetPosition(0, ivar9, 2, 0); + setWidgetHidden(0); + } + if (setWidgetRegister(new WidgetPointer(arg3), add(multiply(ivar7, 12), 8))) { + setWidgetSize(20, 20, 0, 0); + setWidgetPosition(3, add(ivar9, 3), 0, 0); + setWidgetSprite(getOtherCommonData(ivar8, 1465)); + setWidgetHidden(0); + } + if (setWidgetRegister(new WidgetPointer(arg3), add(multiply(ivar7, 12), 9))) { + setWidgetSize(21, 21, 0, 0); + setWidgetPosition(2, add(ivar9, 2), 0, 0); + setWidgetRGB(new Color(239, 223, 207)); + setWidgetFilled(0); + setWidgetHidden(0); + } + if (setWidgetRegister(new WidgetPointer(arg3), add(multiply(ivar7, 12), 10))) { + setWidgetSize(17, 17, 0, 0); + setWidgetPosition(4, add(ivar9, 4), 2, 0); + setWidgetHidden(0); + } + if (setWidgetRegister(new WidgetPointer(arg3), add(multiply(ivar7, 12), 11))) { + setWidgetSize(53, 26, 1, 0); + setWidgetPosition(24, ivar9, 2, 0); + setWidgetFont(494); + setWidgetTextAlignment(0, 1, 0); + setWidgetRGB(new Color(255, 239, 223)); + setWidgetUnknownBoolean(true); + setWidgetText(getOtherCommonData(ivar8, 1463)); + setWidgetHidden(0); + } + ivar9 = add(ivar9, 26); + } + ivar5 = add(ivar5, 1); + } + setWidgetScrollMax(0, ivar9, new WidgetPointer(arg3)); + cs2method2100(0, 0, new WidgetPointer(arg3)); + script_31(arg4, arg3, 6507, 6504, 6505, 6506, 6499, 6498); + return; +} diff --git a/dumps/scripts/5056.cs2 b/dumps/scripts/5056.cs2 new file mode 100644 index 0000000..1d7665d --- /dev/null +++ b/dumps/scripts/5056.cs2 @@ -0,0 +1,26 @@ +void script_5056(int arg0,int arg1) { + if (((boolean)arg1)) { + if (setWidgetRegister(new WidgetPointer(arg0), 0)) { + setWidgetSprite(7571); + } + if (setWidgetRegister(new WidgetPointer(arg0), 1)) { + setWidgetSprite(7570); + } + if (setWidgetRegister(new WidgetPointer(arg0), 2)) { + setWidgetSprite(7572); + } + if (setWidgetRegister(new WidgetPointer(arg0), 3)) { + setWidgetSprite(7577); + } + setScriptCallOnMouseOver(-1, "", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg0)); + } else { + script_5058(arg0, 0); + if (setWidgetRegister(new WidgetPointer(arg0), 3)) { + setWidgetSprite(7576); + } + setScriptCallOnMouseOver(5057, new WidgetPointer(-32768,3), 1, "I1", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(5057, new WidgetPointer(-32768,3), 0, "I1", new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/5057.cs2 b/dumps/scripts/5057.cs2 new file mode 100644 index 0000000..f585a10 --- /dev/null +++ b/dumps/scripts/5057.cs2 @@ -0,0 +1,4 @@ +void script_5057(int arg0,int arg1) { + script_5058(arg0, arg1); + return; +} diff --git a/dumps/scripts/5058.cs2 b/dumps/scripts/5058.cs2 new file mode 100644 index 0000000..e05ddab --- /dev/null +++ b/dumps/scripts/5058.cs2 @@ -0,0 +1,24 @@ +void script_5058(int arg0,int arg1) { + if (((boolean)arg1)) { + if (setWidgetRegister(new WidgetPointer(arg0), 0)) { + setWidgetSprite(7565); + } + if (setWidgetRegister(new WidgetPointer(arg0), 1)) { + setWidgetSprite(7564); + } + if (setWidgetRegister(new WidgetPointer(arg0), 2)) { + setWidgetSprite(7566); + } + } else { + if (setWidgetRegister(new WidgetPointer(arg0), 0)) { + setWidgetSprite(7562); + } + if (setWidgetRegister(new WidgetPointer(arg0), 1)) { + setWidgetSprite(7561); + } + if (setWidgetRegister(new WidgetPointer(arg0), 2)) { + setWidgetSprite(7563); + } + } + return; +} diff --git a/dumps/scripts/5059.cs2 b/dumps/scripts/5059.cs2 new file mode 100644 index 0000000..199fda0 --- /dev/null +++ b/dumps/scripts/5059.cs2 @@ -0,0 +1,55 @@ +void script_5059(int arg0,int arg1,int arg2) { + int ivar3; + ivar3 = multiply(arg1, 12); + if (((boolean)arg2)) { + if (setWidgetRegister(new WidgetPointer(arg0), add(ivar3, 2))) { + setWidgetSprite(7555); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(ivar3, 3))) { + setWidgetSprite(7554); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(ivar3, 4))) { + setWidgetSprite(7556); + } + if (setWidgetRegister(new WidgetPointer(arg0), ivar3)) { + setScriptCallOnMouseEntered(-1, ""); + setScriptCallOnMouseExit(-1, ""); + } + if (isWidgetHidden(new WidgetPointer(1111,21))) { + script_5063(arg0, arg1, 0); + if (setWidgetRegister(new WidgetPointer(arg0), add(ivar3, 1))) { + setScriptCallOnMouseEntered(5061, new WidgetPointer(-32768,3), arg1, 1, 0, "Ii11"); + setScriptCallOnMouseExit(5061, new WidgetPointer(-32768,3), arg1, 0, 0, "Ii11"); + } + } else { + if (setWidgetRegister(new WidgetPointer(arg0), add(ivar3, 5))) { + setWidgetSprite(7555); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(ivar3, 6))) { + setWidgetSprite(7554); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(ivar3, 7))) { + setWidgetSprite(7556); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(ivar3, 10))) { + setWidgetSprite(7408); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(ivar3, 1))) { + setScriptCallOnMouseEntered(-1, ""); + setScriptCallOnMouseExit(-1, ""); + } + } + } else { + script_5062(arg0, arg1, 0); + script_5063(arg0, arg1, 0); + if (setWidgetRegister(new WidgetPointer(arg0), ivar3)) { + setScriptCallOnMouseEntered(5060, new WidgetPointer(-32768,3), arg1, 1, "Ii1"); + setScriptCallOnMouseExit(5060, new WidgetPointer(-32768,3), arg1, 0, "Ii1"); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(ivar3, 1))) { + setScriptCallOnMouseEntered(5061, new WidgetPointer(-32768,3), arg1, 1, 1, "Ii11"); + setScriptCallOnMouseExit(5061, new WidgetPointer(-32768,3), arg1, 0, 1, "Ii11"); + } + } + return; +} diff --git a/dumps/scripts/506.cs2 b/dumps/scripts/506.cs2 new file mode 100644 index 0000000..673b259 --- /dev/null +++ b/dumps/scripts/506.cs2 @@ -0,0 +1,29 @@ +int script_506(int arg0) { + int ivar1; + ivar1 = cs2method5004(arg0); + if ((globalint_41 == 5) && (strLength(globalstring_0) > 0)) { + switch (ivar1) { + case 1: + case 19: + case 2: + case 18: + case 3: + case 6: + case 7: + case 42: + case 41: + if (((boolean)stringMethod4107(strRemoveEntities(cs2method5010(arg0)), globalstring_0)) || ((boolean)stringMethod4107(strRemoveEntities(cs2method5010(arg0)), cs2method5015()))) { + if (((boolean)cs2method5016())) { + return 1; + } + if (((boolean)cs2method5016()) && isFriend(cs2method5019(arg0))) { + return 1; + } + if (((boolean)ivar1) || (ivar1 == 7)) { + return 1; + } + } + } + } + return 0; +} diff --git a/dumps/scripts/5060.cs2 b/dumps/scripts/5060.cs2 new file mode 100644 index 0000000..ab908d3 --- /dev/null +++ b/dumps/scripts/5060.cs2 @@ -0,0 +1,4 @@ +void script_5060(int arg0,int arg1,int arg2) { + script_5062(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/5061.cs2 b/dumps/scripts/5061.cs2 new file mode 100644 index 0000000..28294d1 --- /dev/null +++ b/dumps/scripts/5061.cs2 @@ -0,0 +1,7 @@ +void script_5061(int arg0,int arg1,int arg2,int arg3) { + script_5063(arg0, arg1, arg2); + if (((boolean)arg3)) { + script_5062(arg0, arg1, arg2); + } + return; +} diff --git a/dumps/scripts/5062.cs2 b/dumps/scripts/5062.cs2 new file mode 100644 index 0000000..9a021ba --- /dev/null +++ b/dumps/scripts/5062.cs2 @@ -0,0 +1,26 @@ +void script_5062(int arg0,int arg1,int arg2) { + int ivar3; + ivar3 = multiply(arg1, 12); + if (((boolean)arg2)) { + if (setWidgetRegister(new WidgetPointer(arg0), add(ivar3, 2))) { + setWidgetSprite(7552); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(ivar3, 3))) { + setWidgetSprite(7551); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(ivar3, 4))) { + setWidgetSprite(7553); + } + } else { + if (setWidgetRegister(new WidgetPointer(arg0), add(ivar3, 2))) { + setWidgetSprite(7549); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(ivar3, 3))) { + setWidgetSprite(7548); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(ivar3, 4))) { + setWidgetSprite(7550); + } + } + return; +} diff --git a/dumps/scripts/5063.cs2 b/dumps/scripts/5063.cs2 new file mode 100644 index 0000000..bd4cb8e --- /dev/null +++ b/dumps/scripts/5063.cs2 @@ -0,0 +1,29 @@ +void script_5063(int arg0,int arg1,int arg2) { + int ivar3; + ivar3 = multiply(arg1, 12); + if (((boolean)arg2)) { + if (setWidgetRegister(new WidgetPointer(arg0), add(ivar3, 5))) { + setWidgetSprite(7552); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(ivar3, 6))) { + setWidgetSprite(7551); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(ivar3, 7))) { + setWidgetSprite(7553); + } + } else { + if (setWidgetRegister(new WidgetPointer(arg0), add(ivar3, 5))) { + setWidgetSprite(7549); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(ivar3, 6))) { + setWidgetSprite(7548); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(ivar3, 7))) { + setWidgetSprite(7550); + } + } + if (setWidgetRegister(new WidgetPointer(arg0), add(ivar3, 10))) { + setWidgetSprite(7409); + } + return; +} diff --git a/dumps/scripts/5064.cs2 b/dumps/scripts/5064.cs2 new file mode 100644 index 0000000..5603b3e --- /dev/null +++ b/dumps/scripts/5064.cs2 @@ -0,0 +1,7 @@ +void script_5064(int arg0) { + if (arg0 != -1) { + globalint_768 = arg0; + } + script_5065(0); + return; +} diff --git a/dumps/scripts/5065.cs2 b/dumps/scripts/5065.cs2 new file mode 100644 index 0000000..74245f5 --- /dev/null +++ b/dumps/scripts/5065.cs2 @@ -0,0 +1,124 @@ +void script_5065(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int stack_dump0; + int stack_dump1; + flow_0: + ivar1 = getWidgetActualHeight(new WidgetPointer(1111,68)); + setWidgetSize(0, ivar1, 1, 0, new WidgetPointer(1111,69)); + setWidgetSize(0, ivar1, 1, 0, new WidgetPointer(1111,70)); + setWidgetSize(0, ivar1, 1, 0, new WidgetPointer(1111,71)); + ivar2 = getWidgetActualHeight(new WidgetPointer(1111,55)); + ivar3 = 0; + ivar4 = 0; + ivar5 = 0; + SWITCH (globalint_768) { + case 2: + GOTO flow_1 + case 3: + GOTO flow_2 + case 4: + GOTO flow_3 + } + globalint_768 = 1; + ivar3 = subtract(ivar2, multiply(ivar1, 3)); + ivar4 = subtract(ivar2, multiply(ivar1, 2)); + ivar5 = subtract(ivar2, ivar1); + script_5056(72810564, 1); + script_5056(72810565, 0); + script_5056(72810566, 0); + script_5056(72810567, 0); + GOTO flow_4 + flow_1: + ivar3 = ivar1; + ivar4 = subtract(ivar2, multiply(ivar1, 2)); + ivar5 = subtract(ivar2, ivar1); + script_5056(72810564, 0); + script_5056(72810565, 1); + script_5056(72810566, 0); + script_5056(72810567, 0); + GOTO flow_4 + flow_2: + ivar3 = ivar1; + ivar4 = multiply(ivar1, 2); + ivar5 = subtract(ivar2, ivar1); + script_5056(72810564, 0); + script_5056(72810565, 0); + script_5056(72810566, 1); + script_5056(72810567, 0); + GOTO flow_4 + flow_3: + ivar3 = ivar1; + ivar4 = multiply(ivar1, 2); + ivar5 = multiply(ivar1, 3); + script_5056(72810564, 0); + script_5056(72810565, 0); + script_5056(72810566, 0); + script_5056(72810567, 1); + flow_4: + ivar6 = 0; + ivar7 = 0; + ivar8 = 0; + ivar9 = 0; + ivar10 = 0; + if (((boolean)arg0)) { + stack_dump0 = ivar3; + stack_dump1 = ivar4; + ivar8 = ivar5; + stack_dump0 = stack_dump0; + ivar7 = stack_dump1; + ivar6 = stack_dump0; + } else { + ivar9 = getWidgetActualY(new WidgetPointer(1111,69)); + if (ivar9 != ivar3) { + ivar6 = add(ivar9, max(min(subtract(ivar3, ivar9), 3), -3)); + ivar10 = 1; + } else { + ivar6 = ivar3; + } + ivar9 = getWidgetActualY(new WidgetPointer(1111,70)); + if (ivar9 != ivar4) { + ivar7 = add(ivar9, max(min(subtract(ivar4, ivar9), 3), -3)); + ivar10 = 1; + } else { + ivar7 = ivar4; + } + ivar9 = getWidgetActualY(new WidgetPointer(1111,71)); + if (ivar9 != ivar5) { + ivar8 = add(ivar9, max(min(subtract(ivar5, ivar9), 3), -3)); + ivar10 = 1; + } else { + ivar8 = ivar5; + } + } + setWidgetPosition(0, 0, 1, 0, new WidgetPointer(1111,68)); + setWidgetPosition(0, ivar6, 1, 0, new WidgetPointer(1111,69)); + setWidgetPosition(0, ivar7, 1, 0, new WidgetPointer(1111,70)); + setWidgetPosition(0, ivar8, 1, 0, new WidgetPointer(1111,71)); + setWidgetPosition(0, ivar1, 1, 0, new WidgetPointer(1111,56)); + setWidgetPosition(0, add(ivar6, ivar1), 1, 0, new WidgetPointer(1111,59)); + setWidgetPosition(0, add(ivar7, ivar1), 1, 0, new WidgetPointer(1111,62)); + setWidgetPosition(0, add(ivar8, ivar1), 1, 0, new WidgetPointer(1111,65)); + setWidgetSize(0, subtract(ivar6, ivar1), 1, 0, new WidgetPointer(1111,56)); + setWidgetSize(0, subtract(ivar7, add(ivar6, ivar1)), 1, 0, new WidgetPointer(1111,59)); + setWidgetSize(0, subtract(ivar8, add(ivar7, ivar1)), 1, 0, new WidgetPointer(1111,62)); + setWidgetSize(0, add(ivar8, ivar1), 1, 1, new WidgetPointer(1111,65)); + script_72(72810554, 72810553, cs2method2601(new WidgetPointer(1111,57))); + script_72(72810557, 72810556, cs2method2601(new WidgetPointer(1111,60))); + script_72(72810560, 72810559, cs2method2601(new WidgetPointer(1111,63))); + script_72(72810563, 72810562, cs2method2601(new WidgetPointer(1111,66))); + if (((boolean)ivar10)) { + setScriptCallOnGameloop(5064, -1, "i", new WidgetPointer(1111,55)); + } else { + setScriptCallOnGameloop(-1, "", new WidgetPointer(1111,55)); + } + return; +} diff --git a/dumps/scripts/5066.cs2 b/dumps/scripts/5066.cs2 new file mode 100644 index 0000000..d9a1519 --- /dev/null +++ b/dumps/scripts/5066.cs2 @@ -0,0 +1,4 @@ +void script_5066() { + script_5067(); + return; +} diff --git a/dumps/scripts/5067.cs2 b/dumps/scripts/5067.cs2 new file mode 100644 index 0000000..bad108d --- /dev/null +++ b/dumps/scripts/5067.cs2 @@ -0,0 +1,87 @@ +void script_5067() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + string svar0; + ivar0 = 0; + ivar1 = getCommonDefinitionSize(3943); + ivar2 = 0; + while (ivar0 < ivar1) { + if (bitconfig_9516 == ivar0) { + ivar2 = 1; + } else { + ivar2 = 0; + } + if (commonIntegerExists('i', 3944, ivar0)) { + script_5059(72810553, ivar0, ivar2); + } + if (commonIntegerExists('i', 3945, ivar0)) { + script_5059(72810556, ivar0, ivar2); + } + if (commonIntegerExists('i', 3946, ivar0)) { + script_5059(72810559, ivar0, ivar2); + } + if (commonIntegerExists('i', 3947, ivar0)) { + script_5059(72810562, ivar0, ivar2); + } + ivar0 = add(ivar0, 1); + } + deleteAllExtraChilds(new WidgetPointer(1111,30)); + deleteAllExtraChilds(new WidgetPointer(1111,31)); + deleteAllExtraChilds(new WidgetPointer(1111,32)); + deleteAllExtraChilds(new WidgetPointer(1111,33)); + ivar3 = 0; + ivar4 = cs2method_3408(105, 74, 3943, bitconfig_9516); + svar0 = ""; + ivar5 = -1; + if (ivar4 != -1) { + setWidgetText(new WidgetPointer(1111,29), getOtherCommonData(ivar4, 1463)); + setWidgetSprite(getOtherCommonData(ivar4, 1465), new WidgetPointer(1111,27)); + svar0 = getOtherCommonData(ivar4, 1464); + if (((boolean)getOtherCommonData(ivar4, 1466)) && (ivar4 != 1918)) { + svar0 = concat(svar0, "
" + "
" + "Drag your mouse over the grid to fill an area with this element."); + } + ivar3 = add(ivar3, script_5068(ivar3, svar0)); + ivar5 = getOtherCommonData(ivar4, 1470); + if (ivar5 != -1) { + ivar3 = add(ivar3, 5); + ivar3 = add(ivar3, script_5068(ivar3, cs2method_3408(105, 115, ivar5, -1))); + setWidgetPosition(0, ivar3, 1, 0, new WidgetPointer(1111,31)); + ivar3 = add(ivar3, script_5069(ivar5, 72810527, 1, bitconfig_9517)); + } else { + setWidgetSize(0, 0, 1, 0, new WidgetPointer(1111,31)); + } + ivar5 = getOtherCommonData(ivar4, 1471); + if (ivar5 != -1) { + ivar3 = add(ivar3, 5); + ivar3 = add(ivar3, script_5068(ivar3, cs2method_3408(105, 115, ivar5, -1))); + setWidgetPosition(0, ivar3, 1, 0, new WidgetPointer(1111,32)); + ivar3 = add(ivar3, script_5069(ivar5, 72810528, 2, bitconfig_9518)); + } else { + setWidgetSize(0, 0, 1, 0, new WidgetPointer(1111,32)); + } + ivar5 = getOtherCommonData(ivar4, 1472); + if (ivar5 != -1) { + ivar3 = add(ivar3, 5); + ivar3 = add(ivar3, script_5068(ivar3, cs2method_3408(105, 115, ivar5, -1))); + setWidgetPosition(0, ivar3, 1, 0, new WidgetPointer(1111,33)); + ivar3 = add(ivar3, script_5069(ivar5, 72810529, 3, bitconfig_9519)); + } else { + setWidgetSize(0, 0, 1, 0, new WidgetPointer(1111,33)); + } + } else { + setWidgetText(new WidgetPointer(1111,29), ""); + setWidgetSprite(-1, new WidgetPointer(1111,27)); + } + if (ivar3 > getWidgetActualHeight(new WidgetPointer(1111,30))) { + setWidgetScrollMax(0, ivar3, new WidgetPointer(1111,30)); + } else { + setWidgetScrollMax(0, 0, new WidgetPointer(1111,30)); + } + cs2method2100(0, min(cs2method2601(new WidgetPointer(1111,30)), ivar3), new WidgetPointer(1111,30)); + script_31(72810530, 72810526, 6507, 6504, 6505, 6506, 6499, 6498); + return; +} diff --git a/dumps/scripts/5068.cs2 b/dumps/scripts/5068.cs2 new file mode 100644 index 0000000..6f0ba3a --- /dev/null +++ b/dumps/scripts/5068.cs2 @@ -0,0 +1,12 @@ +int script_5068(int arg0,string arg1) { + int ivar1; + createExtraChild(new WidgetPointer(1111,30), 4, getExtraChildGap(new WidgetPointer(1111,30))); + setWidgetFont(494); + setWidgetTextAlignment(0, 1, 0); + setWidgetRGB(new Color(223, 207, 191)); + ivar1 = add(multiply(getLineCount(getWidgetActualWidth(new WidgetPointer(1111,30)), 494, arg1), 10), 2); + setWidgetSize(0, ivar1, 1, 0); + setWidgetText(arg1); + setWidgetPosition(0, arg0, 1, 0); + return ivar1; +} diff --git a/dumps/scripts/5069.cs2 b/dumps/scripts/5069.cs2 new file mode 100644 index 0000000..afc8a62 --- /dev/null +++ b/dumps/scripts/5069.cs2 @@ -0,0 +1,39 @@ +int script_5069(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + int ivar6; + ivar4 = min(getCommonDefinitionSize(arg0), 256); + ivar5 = 0; + ivar6 = 0; + while (ivar5 < ivar4) { + createExtraChild(new WidgetPointer(arg1), 3, getExtraChildGap(new WidgetPointer(arg1))); + setWidgetSize(0, 14, 1, 0); + setWidgetPosition(0, ivar6, 1, 0); + cs2method2103(255); + setWidgetContextMenuOption(1, "Select"); + createExtraChild(new WidgetPointer(arg1), 5, getExtraChildGap(new WidgetPointer(arg1))); + setWidgetSize(12, 12, 0, 0); + setWidgetPosition(0, add(ivar6, 1), 0, 0); + if (arg3 == ivar5) { + setWidgetSprite(5924); + } else { + setWidgetSprite(5928); + } + createExtraChild(new WidgetPointer(arg1), 4, getExtraChildGap(new WidgetPointer(arg1))); + setWidgetSize(17, 14, 1, 0); + setWidgetPosition(0, ivar6, 2, 0); + setWidgetFont(494); + setWidgetRGB(new Color(223, 207, 191)); + setWidgetUnknownBoolean(true); + setWidgetTextAlignment(0, 1, 0); + setWidgetText(cs2method_3408(105, 115, arg0, ivar5)); + setScriptCallOnMouseEntered(1356, new WidgetPointer(-32768,3), getWidgetCustomChildArrayIndex(), 16777215, "Iii"); + setScriptCallOnMouseExit(1356, new WidgetPointer(-32768,3), getWidgetCustomChildArrayIndex(), 14667711, "Iii"); + setScriptCallOnClickContextMenu(5071, -2147483644, arg2, ivar5, arg0, "iiig"); + ivar6 = add(ivar6, 15); + ivar5 = add(ivar5, 1); + } + ivar6 = max(subtract(ivar6, 1), 0); + setWidgetSize(0, ivar6, 1, 0, new WidgetPointer(arg1)); + return ivar6; +} diff --git a/dumps/scripts/507.cs2 b/dumps/scripts/507.cs2 new file mode 100644 index 0000000..64fbe8f --- /dev/null +++ b/dumps/scripts/507.cs2 @@ -0,0 +1,8 @@ +void script_507(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6) { + setScriptCallOnItemContainerUpdate(712, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), new WidgetPointer(arg6), 541, 1, "IIIIIIIY", new WidgetPointer(arg0)); + setScriptCallOnConfigChange(712, new WidgetPointer(arg0), new WidgetPointer(arg1), new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), new WidgetPointer(arg6), 259, 1, "IIIIIIIY", new WidgetPointer(arg0)); + script_1086(arg0, 0, 0, 0); + script_1086(arg4, 0, 0, 0); + script_713(arg0, arg1, arg2, arg3, arg4, arg5, arg6); + return; +} diff --git a/dumps/scripts/5070.cs2 b/dumps/scripts/5070.cs2 new file mode 100644 index 0000000..f3bda06 --- /dev/null +++ b/dumps/scripts/5070.cs2 @@ -0,0 +1,27 @@ +void script_5070(int arg0,int arg1,int arg2) { + int stack_dump0; + int stack_dump1; + if ((arg0 != 1) || (cs2method_3408(105, 74, 3943, arg1) == -1)) { + return; + } + playSoundEffect2False(6185, 1, 0, 200); + if (arg1 == bitconfig_9516) { + arg2 = ((int)isWidgetHidden(new WidgetPointer(1111,21))); + } else { + cs2method2100(0, 0, new WidgetPointer(1111,30)); + stack_dump0 = 0; + stack_dump1 = 0; + bitconfig_9519 = 0; + stack_dump0 = stack_dump0; + bitconfig_9518 = stack_dump1; + bitconfig_9517 = stack_dump0; + } + bitconfig_9516 = arg1; + if (((boolean)arg2)) { + script_5073(0); + } else { + script_5073(1); + } + script_5067(); + return; +} diff --git a/dumps/scripts/5071.cs2 b/dumps/scripts/5071.cs2 new file mode 100644 index 0000000..0b93cd0 --- /dev/null +++ b/dumps/scripts/5071.cs2 @@ -0,0 +1,24 @@ +void script_5071(int arg0,int arg1,int arg2,int arg3) { + if ((arg0 != 1) || (arg3 == -1)) { + return; + } + if (arg2 >= min(getCommonDefinitionSize(arg3), 256)) { + return; + } + switch (arg1) { + case 1: + bitconfig_9517 = arg2; + break; + case 2: + bitconfig_9518 = arg2; + break; + case 3: + bitconfig_9519 = arg2; + break; + default: + return; + } + playSoundEffect2False(6185, 1, 0, 200); + script_5067(); + return; +} diff --git a/dumps/scripts/5072.cs2 b/dumps/scripts/5072.cs2 new file mode 100644 index 0000000..b260d4e --- /dev/null +++ b/dumps/scripts/5072.cs2 @@ -0,0 +1,6 @@ +void script_5072(int arg0) { + playSoundEffect2False(6185, 1, 0, 200); + script_5073(arg0); + script_5067(); + return; +} diff --git a/dumps/scripts/5073.cs2 b/dumps/scripts/5073.cs2 new file mode 100644 index 0000000..5890f3d --- /dev/null +++ b/dumps/scripts/5073.cs2 @@ -0,0 +1,9 @@ +void script_5073(int arg0) { + setWidgetIsHidden(((boolean)arg0), new WidgetPointer(1111,21)); + if (((boolean)arg0)) { + setWidgetIsHidden(false, new WidgetPointer(1111,120)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1111,120)); + } + return; +} diff --git a/dumps/scripts/5074.cs2 b/dumps/scripts/5074.cs2 new file mode 100644 index 0000000..5296665 --- /dev/null +++ b/dumps/scripts/5074.cs2 @@ -0,0 +1,32 @@ +void script_5074(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int stack_dump0; + ivar2 = 0; + ivar3 = 0; + ivar4 = 0; + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + if (globalint_1065 == -1) { + setWidgetHidden(1); + return; + } + stack_dump0 = subtract(extractX(getMyPositionHash()), extractX(globalint_1065)); + ivar3 = subtract(extractY(getMyPositionHash()), extractY(globalint_1065)); + ivar2 = stack_dump0; + if ((((ivar2 < 0) || (ivar2 >= 112)) || (ivar3 < 0)) || (ivar3 >= 112)) { + setWidgetHidden(1); + return; + } + ivar4 = add(globalint_1396, 1); + setWidgetHidden(0); + setWidgetPosition(subtract(multiply(add(ivar2, 2), globalint_1396), 1), subtract(getWidgetScrollMaxV(new WidgetPointer(arg0)), add(multiply(add(ivar3, 2), globalint_1396), ivar4)), 0, 0); + setWidgetSize(ivar4, ivar4, 0, 0); + if (mod(getClientCycle(), 40) < 20) { + setWidgetRGB(new Color(143, 143, 143)); + } else { + setWidgetRGB(new Color(221, 221, 0)); + } + } + return; +} diff --git a/dumps/scripts/5075.cs2 b/dumps/scripts/5075.cs2 new file mode 100644 index 0000000..6d8b7a5 --- /dev/null +++ b/dumps/scripts/5075.cs2 @@ -0,0 +1,5 @@ +void script_5075(int arg0,int arg1) { + playSoundEffect2False(6185, 1, 0, 200); + script_5076(arg0, arg1); + return; +} diff --git a/dumps/scripts/5076.cs2 b/dumps/scripts/5076.cs2 new file mode 100644 index 0000000..314e798 --- /dev/null +++ b/dumps/scripts/5076.cs2 @@ -0,0 +1,21 @@ +void script_5076(int arg0,int arg1) { + int ivar2; + int ivar3; + ivar2 = 0; + ivar3 = 0; + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + if (isWidgetHidden()) { + ivar2 = divide(subtract(getWidgetScrollMaxH(new WidgetPointer(1111,15)), getWidgetActualWidth(new WidgetPointer(1111,15))), 2); + ivar3 = ivar2; + } else { + ivar2 = subtract(add(getWidgetActualX(), divide(getWidgetActualWidth(), 2)), divide(getWidgetActualWidth(new WidgetPointer(1111,15)), 2)); + ivar3 = subtract(add(getWidgetActualY(), divide(getWidgetActualHeight(), 2)), divide(getWidgetActualHeight(new WidgetPointer(1111,15)), 2)); + } + } else { + ivar2 = divide(subtract(getWidgetScrollMaxH(new WidgetPointer(1111,15)), getWidgetActualWidth(new WidgetPointer(1111,15))), 2); + ivar3 = ivar2; + } + cs2method2100(ivar2, ivar3, new WidgetPointer(1111,15)); + script_5053(0, 0); + return; +} diff --git a/dumps/scripts/5077.cs2 b/dumps/scripts/5077.cs2 new file mode 100644 index 0000000..2ff823f --- /dev/null +++ b/dumps/scripts/5077.cs2 @@ -0,0 +1,59 @@ +void script_5077(int arg0,int arg1,int arg2,int arg3,string arg4) { + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int stack_dump0; + if (isWidgetHidden(new WidgetPointer(1111,21)) || isWidgetHidden(new WidgetPointer(1111,9))) { + script_41(72810627); + return; + } + if (((boolean)script_4761(25))) { + return; + } + ivar4 = 0; + ivar5 = 0; + ivar6 = 0; + ivar7 = 0; + ivar8 = 0; + ivar9 = 0; + ivar10 = script_3365(72810505); + ivar11 = script_3366(72810505); + ivar12 = getWidgetActualWidth(new WidgetPointer(1111,9)); + ivar13 = getWidgetActualHeight(new WidgetPointer(1111,9)); + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + stack_dump0 = script_1743(); + ivar5 = script_1744(); + ivar4 = stack_dump0; + stack_dump0 = subtract(ivar4, ivar10); + ivar6 = subtract(ivar5, ivar11); + ivar9 = stack_dump0; + stack_dump0 = add(ivar9, getWidgetActualWidth()); + ivar7 = add(ivar6, getWidgetActualHeight()); + ivar8 = stack_dump0; + if (subtract(ivar13, ivar7) > 150) { + script_4540(72810627, arg0, arg1, ivar12, 494, 494, -1, 10, 2, 2, arg2, arg3, arg4); + return; + } + if (ivar6 > 125) { + script_4540(72810627, arg0, arg1, ivar12, 494, 494, -1, 10, 2, 0, arg2, arg3, arg4); + return; + } + if (subtract(ivar12, ivar8) > 150) { + script_4540(72810627, arg0, arg1, ivar12, 494, 494, -1, 10, 2, 1, arg2, arg3, arg4); + return; + } + if (ivar9 > 225) { + script_4540(72810627, arg0, arg1, ivar12, 494, 494, -1, 10, 2, 3, arg2, arg3, arg4); + return; + } + script_4540(72810627, arg0, arg1, ivar12, 494, 494, -1, 10, 2, -1, add(ivar4, arg2), add(ivar5, arg3), arg4); + } + return; +} diff --git a/dumps/scripts/5078.cs2 b/dumps/scripts/5078.cs2 new file mode 100644 index 0000000..5523e31 --- /dev/null +++ b/dumps/scripts/5078.cs2 @@ -0,0 +1,154 @@ +void script_5078(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int stack_dump0; + script_4762(73007134, 1788); + deleteAllExtraChilds(new WidgetPointer(1114,5)); + ivar1 = 0; + ivar2 = getCommonDefinitionSize(3921); + ivar3 = -1; + ivar4 = 0; + ivar5 = 0; + ivar6 = 0; + globalarray_0 = new int[add(ivar2, 1)]; + ivar7 = 1; + while (ivar1 < ivar2) { + ivar3 = cs2method_3408(105, 103, 3921, ivar1); + if (ivar3 != -1) { + stack_dump0 = 0; + ivar5 = getCommonDefinitionSize(ivar3); + ivar4 = stack_dump0; + while (ivar4 < ivar5) { + ivar6 = max(ivar6, getTextWidth(494, cs2method_3408(105, 115, ivar3, ivar4))); + ivar4 = add(ivar4, 1); + } + globalarray_0[ivar7] = add(globalarray_0[subtract(ivar7, 1)], ivar5); + ivar7 = add(ivar7, 1); + } + ivar1 = add(ivar1, 1); + } + ivar8 = add(ivar6, 28); + ivar1 = 0; + ivar9 = 0; + ivar10 = 0; + while (ivar1 < ivar2) { + ivar3 = cs2method_3408(105, 103, 3921, ivar1); + if (ivar3 != -1) { + createExtraChild(new WidgetPointer(1114,5), 3, getExtraChildGap(new WidgetPointer(1114,5))); + setWidgetSize(0, 33, 1, 0); + setWidgetPosition(0, ivar9, 0, 0); + setWidgetFilled(1); + if (((boolean)mod(ivar1, 2))) { + setWidgetRGB(new Color(33, 31, 28)); + } else { + setWidgetRGB(new Color(24, 23, 21)); + } + createExtraChild(new WidgetPointer(1114,5), 4, getExtraChildGap(new WidgetPointer(1114,5))); + setWidgetSize(add(ivar8, 15), 33, 1, 0); + setWidgetPosition(5, ivar9, 0, 0); + setWidgetFont(494); + setWidgetTextAlignment(0, 1, 0); + setWidgetRGB(new Color(233, 226, 180)); + setWidgetUnknownBoolean(true); + setWidgetText(cs2method_3408(105, 115, ivar3, -1)); + createExtraChild(new WidgetPointer(1114,5), 3, getExtraChildGap(new WidgetPointer(1114,5))); + setWidgetSize(ivar8, 21, 0, 0); + setWidgetPosition(6, add(ivar9, 6), 2, 0); + cs2method2103(255); + createExtraChild(new WidgetPointer(1114,5), 5, getExtraChildGap(new WidgetPointer(1114,5))); + setWidgetSize(subtract(getWidgetActualWidth(), 40), getWidgetActualHeight(), 0, 0); + setWidgetPosition(26, getWidgetActualY(), 2, 0); + if (((boolean)globalint_1095)) { + setWidgetSprite(6132); + } else { + setWidgetSprite(6141); + } + createExtraChild(new WidgetPointer(1114,5), 5, getExtraChildGap(new WidgetPointer(1114,5))); + setWidgetSize(subtract(getWidgetActualWidth(), 40), getWidgetActualHeight(), 0, 0); + setWidgetPosition(26, getWidgetActualY(), 2, 0); + if (((boolean)globalint_1095)) { + setWidgetSprite(6135); + cs2method2103(255); + } else { + setWidgetHidden(1); + } + createExtraChild(new WidgetPointer(1114,5), 5, getExtraChildGap(new WidgetPointer(1114,5))); + setWidgetSize(20, getWidgetActualHeight(), 0, 0); + setWidgetPosition(getWidgetActualX(), getWidgetActualY(), 0, 0); + if (((boolean)globalint_1095)) { + setWidgetSprite(6131); + } else { + setWidgetSprite(6140); + } + createExtraChild(new WidgetPointer(1114,5), 5, getExtraChildGap(new WidgetPointer(1114,5))); + setWidgetSize(20, getWidgetActualHeight(), 0, 0); + setWidgetPosition(getWidgetActualX(), getWidgetActualY(), 0, 0); + if (((boolean)globalint_1095)) { + setWidgetSprite(6134); + cs2method2103(255); + } else { + setWidgetHidden(1); + } + createExtraChild(new WidgetPointer(1114,5), 5, getExtraChildGap(new WidgetPointer(1114,5))); + setWidgetSize(20, getWidgetActualHeight(), 0, 0); + setWidgetPosition(6, getWidgetActualY(), 2, 0); + if (((boolean)globalint_1095)) { + setWidgetSprite(6133); + } else { + setWidgetSprite(6142); + } + createExtraChild(new WidgetPointer(1114,5), 5, getExtraChildGap(new WidgetPointer(1114,5))); + setWidgetSize(20, getWidgetActualHeight(), 0, 0); + setWidgetPosition(6, getWidgetActualY(), 2, 0); + if (((boolean)globalint_1095)) { + setWidgetSprite(6136); + cs2method2103(255); + } else { + setWidgetHidden(1); + } + createExtraChild(new WidgetPointer(1114,5), 4, getExtraChildGap(new WidgetPointer(1114,5))); + setWidgetSize(ivar6, 21, 0, 0); + setWidgetPosition(30, getWidgetActualY(), 2, 0); + setWidgetFont(494); + setWidgetTextAlignment(1, 1, 0); + setWidgetRGB(new Color(37, 30, 20)); + setWidgetUnknownBoolean(false); + setWidgetText(""); + ivar9 = add(ivar9, 33); + if (((boolean)globalint_1095)) { + setScriptCallOnMouseEntered(5086, new WidgetPointer(-32768,3), ivar1, 0, "Iii"); + setScriptCallOnMouseExit(5086, new WidgetPointer(-32768,3), ivar1, 1, "Iii"); + setScriptCallOnMouseReleased(5086, new WidgetPointer(-32768,3), ivar1, 255, "Iii"); + if (ivar3 == 3922) { + setScriptCallOnMousePressed(5081, new WidgetPointer(-32768,3), ivar1, ivar3, globalarray_0[ivar1], min(subtract(globalarray_0[add(ivar1, 1)], globalarray_0[ivar1]), bitconfig_9544), ivar10, ivar8, "Iigiiii"); + } else { + setScriptCallOnMousePressed(5081, new WidgetPointer(-32768,3), ivar1, ivar3, globalarray_0[ivar1], subtract(globalarray_0[add(ivar1, 1)], globalarray_0[ivar1]), ivar10, ivar8, "Iigiiii"); + } + } + } + ivar1 = add(ivar1, 1); + } + if (ivar9 > getWidgetActualHeight(new WidgetPointer(1114,5))) { + setWidgetScrollMax(0, ivar9, new WidgetPointer(1114,5)); + cs2method2100(0, cs2method2601(new WidgetPointer(1114,5)), new WidgetPointer(1114,5)); + } else { + setWidgetScrollMax(0, 0, new WidgetPointer(1114,5)); + cs2method2100(0, 0, new WidgetPointer(1114,5)); + } + script_31(73007110, 73007109, 6507, 6504, 6505, 6506, 6499, 6498); + script_5080(73007109); + setScriptCallOnMousePressed(5084, new WidgetPointer(1114,5), "I", new WidgetPointer(1114,28)); + setScriptCallOnGlobalConfigChange(5078, new WidgetPointer(-32768,3), 1095, 1, "IY", new WidgetPointer(arg0)); + setScriptCallOnConfigChange(5078, new WidgetPointer(-32768,3), 1734, 1, "IY", new WidgetPointer(arg0)); + setScriptCallOnConfigChange(5079, new WidgetPointer(-32768,3), 1736, 1, "IY", new WidgetPointer(1114,5)); + setScriptCallOnGlobalStringChange(5079, new WidgetPointer(-32768,3), 129, 1, "IY", new WidgetPointer(1114,5)); + return; +} diff --git a/dumps/scripts/5079.cs2 b/dumps/scripts/5079.cs2 new file mode 100644 index 0000000..ba88e92 --- /dev/null +++ b/dumps/scripts/5079.cs2 @@ -0,0 +1,4 @@ +void script_5079(int arg0) { + script_5080(arg0); + return; +} diff --git a/dumps/scripts/508.cs2 b/dumps/scripts/508.cs2 new file mode 100644 index 0000000..71884a0 --- /dev/null +++ b/dumps/scripts/508.cs2 @@ -0,0 +1,23 @@ +void script_508() { + globalint_6 = 0; + if ((getBlackmarks() == 5) || (getBlackmarks() == 6)) { + setWidgetText(new WidgetPointer(594,83), "Suggest to mute this player for 48 hours"); + setWidgetText(new WidgetPointer(594,10), "Suggest to mute this player for 48 hours"); + setWidgetText(new WidgetPointer(594,60), "Suggest to mute this player for 48 hours"); + } else { + setWidgetText(new WidgetPointer(594,83), "Mute this player for 48 hours"); + setWidgetText(new WidgetPointer(594,10), "Mute this player for 48 hours"); + setWidgetText(new WidgetPointer(594,60), "Mute this player for 48 hours"); + } + globalint_11 = 1; + if (getLanguage() != 1) { + script_216(); + script_246(); + return; + } + setScriptCallOnGlobalStringChange(218, 24, 1, "Y", new WidgetPointer(594,32)); + globalint_792 = -1; + script_224(); + script_216(); + return; +} diff --git a/dumps/scripts/5080.cs2 b/dumps/scripts/5080.cs2 new file mode 100644 index 0000000..7215f0a --- /dev/null +++ b/dumps/scripts/5080.cs2 @@ -0,0 +1,47 @@ +void script_5080(int arg0) { + int ivar1; + int ivar2; + int ivar3; + ivar1 = 0; + ivar2 = getCommonDefinitionSize(3921); + ivar3 = -1; + while (ivar1 < ivar2) { + ivar3 = cs2method_3408(105, 103, 3921, ivar1); + if ((ivar3 != -1) && setWidgetRegister(new WidgetPointer(arg0), add(multiply(ivar1, 10), 9))) { + setWidgetText(cs2method_3408(105, 115, ivar3, script_5089(ivar3))); + } + ivar1 = add(ivar1, 1); + } + switch (bitconfig_9539) { + case 1: + if (((boolean)globalint_1095)) { + setWidgetText(new WidgetPointer(1114,8), "Press 'Confirm' when you've made your choices."); + } else { + setWidgetText(new WidgetPointer(1114,8), "Waiting for the battle's initiator to choose the rules..."); + } + break; + case 2: + if (((boolean)globalint_1095)) { + setWidgetText(new WidgetPointer(1114,8), "Press 'Confirm' when you've made your choices."); + } else { + setWidgetText(new WidgetPointer(1114,8), "Waiting for " + globalstring_129 + " to choose the rules..."); + } + break; + case 3: + setWidgetText(new WidgetPointer(1114,8), "Loading elements..."); + break; + case 4: + setWidgetText(new WidgetPointer(1114,8), "Building elements..."); + break; + case 5: + setWidgetText(new WidgetPointer(1114,8), "Failed to build battlefield."); + break; + case 6: + setWidgetText(new WidgetPointer(1114,8), "Initialising build mode."); + break; + default: + setWidgetText(new WidgetPointer(1114,8), "Loading..."); + } + script_5085(arg0); + return; +} diff --git a/dumps/scripts/5081.cs2 b/dumps/scripts/5081.cs2 new file mode 100644 index 0000000..ca9399a --- /dev/null +++ b/dumps/scripts/5081.cs2 @@ -0,0 +1,76 @@ +void script_5081(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6) { + int ivar7; + int ivar8; + int ivar9; + int ivar10; + if (((boolean)globalint_1095) || (globalint_1095 == -1)) { + script_5085(arg0); + return; + } + playSoundEffect2False(6185, 1, 0, 200); + setWidgetIsHidden(false, new WidgetPointer(1114,28)); + globalint_160 = arg1; + ivar7 = multiply(arg1, 10); + if (setWidgetRegister(new WidgetPointer(arg0), ivar7)) { + setScriptCallOnGameloop(-1, ""); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(ivar7, 3))) { + setWidgetSprite(6138); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(ivar7, 5))) { + setWidgetSprite(6137); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(ivar7, 7))) { + setWidgetSprite(6139); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(ivar7, 4))) { + cs2method2103(255); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(ivar7, 6))) { + cs2method2103(255); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(ivar7, 8))) { + cs2method2103(255); + } + deleteAllExtraChilds(new WidgetPointer(1114,32)); + ivar8 = 0; + while (ivar8 < arg3) { + createExtraChild(new WidgetPointer(1114,32), 3, getExtraChildGap(new WidgetPointer(1114,32))); + setWidgetHidden(1); + ivar8 = add(ivar8, 1); + } + ivar9 = script_5089(arg2); + ivar10 = 0; + ivar8 = 0; + while (ivar8 < arg4) { + if (ivar9 != ivar8) { + createExtraChild(new WidgetPointer(1114,32), 4, getExtraChildGap(new WidgetPointer(1114,32))); + setWidgetSize(0, 12, 1, 0); + setWidgetPosition(0, ivar10, 0, 0); + setWidgetFont(494); + setWidgetTextAlignment(1, 1, 0); + setWidgetRGB(new Color(37, 30, 20)); + setWidgetUnknownBoolean(false); + setWidgetText(cs2method_3408(105, 115, arg2, ivar8)); + setScriptCallOnMouseEntered(1356, new WidgetPointer(-32768,3), -2147483643, 16777215, "Iii"); + setScriptCallOnMouseExit(1356, new WidgetPointer(-32768,3), -2147483643, 2432532, "Iii"); + setWidgetContextMenuOption(1, "Select"); + setScriptCallOnClickContextMenu(5084, new WidgetPointer(arg0), "I"); + ivar10 = add(ivar10, getWidgetActualHeight()); + } else { + createExtraChild(new WidgetPointer(1114,32), 3, getExtraChildGap(new WidgetPointer(1114,32))); + setWidgetHidden(1); + } + ivar8 = add(ivar8, 1); + } + setWidgetIntegerNode(1476, arg6, new WidgetPointer(1114,29)); + setWidgetIntegerNode(1477, ivar10, new WidgetPointer(1114,29)); + setWidgetScrollMax(0, ivar10, new WidgetPointer(1114,32)); + script_5082(arg0); + if (arg4 > 4) { + script_31(73007137, 73007136, 6507, 6504, 6505, 6506, 6499, 6498); + } else { + deleteAllExtraChilds(new WidgetPointer(1114,33)); + } + return; +} diff --git a/dumps/scripts/5082.cs2 b/dumps/scripts/5082.cs2 new file mode 100644 index 0000000..665fd5b --- /dev/null +++ b/dumps/scripts/5082.cs2 @@ -0,0 +1,37 @@ +void script_5082(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int stack_dump0; + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + if ((globalint_160 != -1) && setWidgetRegister(new WidgetPointer(arg0), add(multiply(globalint_160, 10), 2))) { + ivar1 = subtract(add(script_4405(), getWidgetActualHeight()), script_3366(73007132)); + if (ivar1 >= getWidgetActualHeight(new WidgetPointer(arg0))) { + setWidgetIsHidden(true, new WidgetPointer(1114,29)); + } else if (ivar1 <= 0) { + setWidgetIsHidden(true, new WidgetPointer(1114,29)); + } else { + setWidgetIsHidden(false, new WidgetPointer(1114,29)); + setWidgetPosition(subtract(script_1815(), script_3365(73007132)), ivar1, 0, 0, new WidgetPointer(1114,29)); + if (setWidgetRegister(new WidgetPointer(1114,29))) { + stack_dump0 = 1477; + /* + mgi.tools.jagdecs2.DecompilerException: opcode 1613 not decompileable + at mgi.tools.jagdecs2.FlowBlocksGenerator.analyzeSpecialCall(FlowBlocksGenerator.java:297) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:249) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + setScriptCallOnGameloop(5083, new WidgetPointer(-32768,3), globalint_160, add(getClientCycle(), 2), "Iii", new WidgetPointer(1114,29)); + } + } else { + setWidgetIsHidden(true, new WidgetPointer(1114,29)); + } + return; +} diff --git a/dumps/scripts/5083.cs2 b/dumps/scripts/5083.cs2 new file mode 100644 index 0000000..7d73653 --- /dev/null +++ b/dumps/scripts/5083.cs2 @@ -0,0 +1,10 @@ +void script_5083(int arg0,int arg1,int arg2) { + if (getClientCycle() < arg2) { + return; + } + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + if (arg1 == globalint_160) { + script_72(73007137, 73007136, cs2method2601(new WidgetPointer(1114,32))); + } + return; +} diff --git a/dumps/scripts/5084.cs2 b/dumps/scripts/5084.cs2 new file mode 100644 index 0000000..ff8ebf1 --- /dev/null +++ b/dumps/scripts/5084.cs2 @@ -0,0 +1,5 @@ +void script_5084(int arg0) { + playSoundEffect2False(6185, 1, 0, 200); + script_5085(arg0); + return; +} diff --git a/dumps/scripts/5085.cs2 b/dumps/scripts/5085.cs2 new file mode 100644 index 0000000..6a72d83 --- /dev/null +++ b/dumps/scripts/5085.cs2 @@ -0,0 +1,34 @@ +void script_5085(int arg0) { + int ivar1; + int ivar2; + setWidgetIsHidden(true, new WidgetPointer(1114,28)); + globalint_160 = -1; + deleteAllExtraChilds(new WidgetPointer(1114,32)); + ivar1 = 0; + ivar2 = getCommonDefinitionSize(3921); + while (ivar1 < ivar2) { + if (((boolean)globalint_1095)) { + if (setWidgetRegister(new WidgetPointer(arg0), add(multiply(ivar1, 10), 3))) { + setWidgetSprite(6132); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(multiply(ivar1, 10), 5))) { + setWidgetSprite(6131); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(multiply(ivar1, 10), 7))) { + setWidgetSprite(6133); + } + } else { + if (setWidgetRegister(new WidgetPointer(arg0), add(multiply(ivar1, 10), 3))) { + setWidgetSprite(6141); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(multiply(ivar1, 10), 5))) { + setWidgetSprite(6140); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(multiply(ivar1, 10), 7))) { + setWidgetSprite(6142); + } + } + ivar1 = add(ivar1, 1); + } + return; +} diff --git a/dumps/scripts/5086.cs2 b/dumps/scripts/5086.cs2 new file mode 100644 index 0000000..9bb4888 --- /dev/null +++ b/dumps/scripts/5086.cs2 @@ -0,0 +1,25 @@ +void script_5086(int arg0,int arg1,int arg2) { + int ivar3; + if (arg1 == globalint_160) { + arg2 = 255; + } + ivar3 = multiply(arg1, 10); + if (setWidgetRegister(new WidgetPointer(arg0), ivar3)) { + if (arg2 == 255) { + setScriptCallOnGameloop(-1, ""); + if (setWidgetRegister(new WidgetPointer(arg0), add(ivar3, 4))) { + cs2method2103(255); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(ivar3, 6))) { + cs2method2103(255); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(ivar3, 8))) { + cs2method2103(255); + } + } else { + setScriptCallOnGameloop(5087, new WidgetPointer(-32768,3), -2147483643, arg2, "Iii"); + script_5088(arg0, arg2); + } + } + return; +} diff --git a/dumps/scripts/5087.cs2 b/dumps/scripts/5087.cs2 new file mode 100644 index 0000000..0aef353 --- /dev/null +++ b/dumps/scripts/5087.cs2 @@ -0,0 +1,6 @@ +void script_5087(int arg0,int arg1,int arg2) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + script_5088(arg0, arg2); + } + return; +} diff --git a/dumps/scripts/5088.cs2 b/dumps/scripts/5088.cs2 new file mode 100644 index 0000000..7ac8f16 --- /dev/null +++ b/dumps/scripts/5088.cs2 @@ -0,0 +1,33 @@ +void script_5088(int arg0,int arg1) { + int ivar2; + ivar2 = 0; + if (setWidgetRegister(new WidgetPointer(arg0), add(getWidgetCustomChildArrayIndex(), 4))) { + ivar2 = cs2method1609(); + if (((boolean)arg1)) { + ivar2 = max(subtract(ivar2, 22), 0); + cs2method2103(ivar2); + if (setWidgetRegister(new WidgetPointer(arg0), add(getWidgetCustomChildArrayIndex(), 6))) { + cs2method2103(ivar2); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(getWidgetCustomChildArrayIndex(), 8))) { + cs2method2103(ivar2); + } + if (ivar2 <= 0) { + setScriptCallOnGameloop(-1, ""); + } + } else { + ivar2 = min(add(ivar2, 22), 255); + cs2method2103(ivar2); + if (setWidgetRegister(new WidgetPointer(arg0), add(getWidgetCustomChildArrayIndex(), 6))) { + cs2method2103(ivar2); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(getWidgetCustomChildArrayIndex(), 8))) { + cs2method2103(ivar2); + } + if (ivar2 >= 255) { + setScriptCallOnGameloop(-1, ""); + } + } + } + return; +} diff --git a/dumps/scripts/5089.cs2 b/dumps/scripts/5089.cs2 new file mode 100644 index 0000000..15250d5 --- /dev/null +++ b/dumps/scripts/5089.cs2 @@ -0,0 +1,41 @@ +int script_5089(int arg0) { + switch (arg0) { + case 3922: + return bitconfig_9537; + case 3923: + return bitconfig_9533; + case 3924: + return bitconfig_9534; + case 3939: + return bitconfig_9532; + case 3925: + return bitconfig_9520; + case 3926: + return bitconfig_9521; + case 3927: + return bitconfig_9522; + case 3929: + return bitconfig_9523; + case 3931: + return bitconfig_9524; + case 3932: + return bitconfig_9525; + case 3933: + return bitconfig_9526; + case 3934: + return bitconfig_9527; + case 3935: + return bitconfig_9528; + case 3936: + return bitconfig_9529; + case 3937: + return bitconfig_9530; + case 3938: + return bitconfig_9531; + case 3941: + return bitconfig_9535; + case 3942: + return bitconfig_9536; + } + return 0; +} diff --git a/dumps/scripts/509.cs2 b/dumps/scripts/509.cs2 new file mode 100644 index 0000000..8cdcb72 --- /dev/null +++ b/dumps/scripts/509.cs2 @@ -0,0 +1,24 @@ +void script_509(int arg0) { + string svar0; + svar0 = ""; + if (arg0 == 40173577) { + svar0 = getItemName(standart_config_1065); + if (standart_config_1065 == -1) { + svar0 = "Empty"; + } + } else if (arg0 == 40173578) { + svar0 = getItemName(standart_config_1066); + if (standart_config_1066 == -1) { + svar0 = "Empty"; + } + } else { + if (arg0 == 40173579) { + svar0 = getItemName(standart_config_1067); + if (standart_config_1067 == -1) { + svar0 = "Empty"; + } + } + } + script_39(arg0, 40173592, 25, 199, svar0); + return; +} diff --git a/dumps/scripts/5090.cs2 b/dumps/scripts/5090.cs2 new file mode 100644 index 0000000..d8a7b50 --- /dev/null +++ b/dumps/scripts/5090.cs2 @@ -0,0 +1,7 @@ +void script_5090(int arg0) { + script_4534(72876034); + script_5092(); + setScriptCallOnConfigChange(5091, 1736, 1735, 2, "Y", new WidgetPointer(arg0)); + setScriptCallOnGlobalConfigChange(5091, 786, 788, 787, 3, "Y", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/5091.cs2 b/dumps/scripts/5091.cs2 new file mode 100644 index 0000000..819f67f --- /dev/null +++ b/dumps/scripts/5091.cs2 @@ -0,0 +1,4 @@ +void script_5091() { + script_5092(); + return; +} diff --git a/dumps/scripts/5092.cs2 b/dumps/scripts/5092.cs2 new file mode 100644 index 0000000..363e9f0 --- /dev/null +++ b/dumps/scripts/5092.cs2 @@ -0,0 +1,215 @@ +void script_5092() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + string svar0; + string svar1; + string svar2; + string svar3; + string svar4; + string svar5; + string svar6; + string svar7; + string stack_dump0; + int stack_dump1; + deleteAllExtraChilds(new WidgetPointer(1112,4)); + svar0 = ""; + svar1 = ""; + svar2 = ""; + svar3 = ""; + svar4 = ""; + svar5 = ""; + svar6 = ""; + svar7 = ""; + ivar0 = 0; + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + ivar4 = 0; + ivar5 = 0; + ivar6 = 0; + ivar7 = 0; + ivar8 = 0; + if (bitconfig_9540 != 3) { + if (bitconfig_9520 > 0) { + svar0 = "
" + "Members:" + "
" + "Score:"; + svar3 = svar0; + svar1 = "
" + formatNumber(bitAnd(globalint_788, 1023), 1); + svar4 = "
" + formatNumber(bitAnd(divide(globalint_788, pow(2, 10)), 1023), 1); + svar1 = svar1 + "
" + formatNumber(bitAnd(globalint_786, 65535), 1); + ivar8 = divide(globalint_786, pow(2, 16)); + if (ivar8 < 0) { + ivar8 = add(pow(2, 16), ivar8); + } + svar4 = svar4 + "
" + formatNumber(ivar8, 1); + ivar8 = cs2method_3408(105, 105, 3928, bitconfig_9521); + if (ivar8 < 2147483647) { + svar1 = svar1 + " / " + formatNumber(ivar8, 1); + svar4 = svar4 + " / " + formatNumber(ivar8, 1); + } + if (bitconfig_9520 < 2) { + svar6 = "
" + "
" + "
" + "Neutral players:"; + svar7 = "
" + "
" + "
" + formatNumber(divide(globalint_788, pow(2, 20)), 1); + } else { + stack_dump0 = "
" + "
" + "
"; + svar7 = "
" + "
" + "
"; + svar6 = stack_dump0; + } + if (((boolean)bitconfig_9540)) { + stack_dump0 = "Your team:"; + svar5 = "Blue team:"; + svar2 = stack_dump0; + } else if (bitconfig_9540 == 2) { + stack_dump0 = "Red team:"; + svar5 = "Your team:"; + svar2 = stack_dump0; + } else { + stack_dump0 = "Red team:"; + svar5 = "Blue team:"; + svar2 = stack_dump0; + if (bitconfig_9520 < 2) { + svar6 = svar6 + "
" + "Your score:"; + svar7 = svar7 + "
" + formatNumber(bitconfig_9541, 1); + ivar8 = cs2method_3408(105, 105, 3928, bitconfig_9522); + if (ivar8 < 2147483647) { + svar7 = svar7 + " / " + formatNumber(ivar8, 1); + } + } + } + } else { + stack_dump0 = "Score:"; + svar7 = formatNumber(bitconfig_9541, 1); + svar6 = stack_dump0; + } + ivar8 = cs2method_3408(105, 105, 3940, bitconfig_9532); + if (ivar8 != 0) { + svar6 = svar6 + "
" + "Reward for pking:"; + if (ivar8 > 0) { + svar7 = svar7 + "
" + intToStr(ivar8); + } else { + svar7 = svar7 + "
" + "A key"; + } + } + if (globalint_787 < 0) { + svar6 = svar6 + "
" + "Scoring begins in:"; + if (globalint_787 <= -2147483648) { + svar7 = svar7 + "
" + "-"; + } else { + ivar6 = subtract(0, globalint_787); + } + } + if ((bitconfig_9523 > 0) && (globalint_787 > 0)) { + svar6 = svar6 + "
" + "Time remaining:"; + ivar6 = globalint_787; + } + ivar5 = add(multiply(getLineCount(2147483647, 494, svar6), 10), 2); + ivar0 = add(add(getMaxLineWidth(2147483647, 494, svar0), 3), getMaxLineWidth(2147483647, 494, svar1)); + ivar0 = max(ivar0, getMaxLineWidth(2147483647, 494, svar2)); + ivar1 = add(add(getMaxLineWidth(2147483647, 494, svar3), 3), getMaxLineWidth(2147483647, 494, svar4)); + ivar1 = max(ivar1, getMaxLineWidth(2147483647, 494, svar5)); + ivar3 = add(add(getMaxLineWidth(2147483647, 494, svar6), 3), max(getMaxLineWidth(2147483647, 494, svar7), 40)); + ivar2 = add(add(ivar0, 5), ivar1); + ivar4 = max(ivar3, ivar2); + ivar2 = divide(subtract(ivar4, ivar2), 2); + stack_dump1 = add(ivar0, ivar2); + ivar1 = add(ivar1, ivar2); + ivar0 = stack_dump1; + setWidgetSize(add(ivar4, 8), add(ivar5, 8), 0, 0, new WidgetPointer(1112,1)); + createExtraChild(new WidgetPointer(1112,4), 4, getExtraChildGap(new WidgetPointer(1112,4))); + createExtraChild(new WidgetPointer(1112,4), 4, getExtraChildGap(new WidgetPointer(1112,4))); + setWidgetSize(ivar0, 0, 0, 1); + setWidgetSize(ivar0, 0, 0, 1); + setWidgetPosition(0, 0, 0, 1); + setWidgetPosition(0, 0, 0, 1); + setWidgetFont(494); + setWidgetFont(494); + setWidgetUnknownBoolean(true); + setWidgetUnknownBoolean(true); + setWidgetTextAlignment(0, 0, 0); + setWidgetTextAlignment(2, 0, 0); + setWidgetRGB(new Color(255, 0, 0)); + setWidgetRGB(new Color(255, 0, 0)); + setWidgetText(svar0); + setWidgetText(svar1); + createExtraChild(new WidgetPointer(1112,4), 4, getExtraChildGap(new WidgetPointer(1112,4))); + setWidgetSize(ivar0, 0, 0, 1); + setWidgetPosition(0, 0, 0, 1); + setWidgetFont(494); + setWidgetUnknownBoolean(true); + setWidgetTextAlignment(1, 0, 0); + setWidgetRGB(new Color(255, 0, 0)); + setWidgetText(svar2); + createExtraChild(new WidgetPointer(1112,4), 4, getExtraChildGap(new WidgetPointer(1112,4))); + createExtraChild(new WidgetPointer(1112,4), 4, getExtraChildGap(new WidgetPointer(1112,4))); + setWidgetSize(ivar1, 0, 0, 1); + setWidgetSize(ivar1, 0, 0, 1); + setWidgetPosition(0, 0, 2, 1); + setWidgetPosition(0, 0, 2, 1); + setWidgetFont(494); + setWidgetFont(494); + setWidgetUnknownBoolean(true); + setWidgetUnknownBoolean(true); + setWidgetTextAlignment(0, 0, 0); + setWidgetTextAlignment(2, 0, 0); + setWidgetRGB(new Color(127, 127, 255)); + setWidgetRGB(new Color(127, 127, 255)); + setWidgetText(svar3); + setWidgetText(svar4); + createExtraChild(new WidgetPointer(1112,4), 4, getExtraChildGap(new WidgetPointer(1112,4))); + setWidgetSize(ivar1, 0, 0, 1); + setWidgetPosition(0, 0, 2, 1); + setWidgetFont(494); + setWidgetUnknownBoolean(true); + setWidgetTextAlignment(1, 0, 0); + setWidgetRGB(new Color(127, 127, 255)); + setWidgetText(svar5); + if (strLength(svar0) > 0) { + createExtraChild(new WidgetPointer(1112,4), 9, getExtraChildGap(new WidgetPointer(1112,4))); + createExtraChild(new WidgetPointer(1112,4), 9, getExtraChildGap(new WidgetPointer(1112,4))); + setWidgetSize(0, 27, 0, 0); + setWidgetSize(0, 27, 0, 0); + setWidgetPosition(add(ivar0, 2), 3, 0, 0); + setWidgetPosition(add(getWidgetActualX(), 1), add(getWidgetActualY(), 1), 0, 0); + setWidgetRGB(new Color(127, 127, 127)); + setWidgetRGB(new Color(63, 63, 63)); + } + createExtraChild(new WidgetPointer(1112,4), 4, getExtraChildGap(new WidgetPointer(1112,4))); + createExtraChild(new WidgetPointer(1112,4), 4, getExtraChildGap(new WidgetPointer(1112,4))); + setWidgetSize(ivar3, 0, 0, 1); + setWidgetSize(ivar3, 0, 0, 1); + setWidgetPosition(0, 0, 1, 1); + setWidgetPosition(0, 0, 1, 1); + setWidgetFont(494); + setWidgetFont(494); + setWidgetUnknownBoolean(true); + setWidgetUnknownBoolean(true); + setWidgetTextAlignment(0, 0, 0); + setWidgetTextAlignment(2, 0, 0); + setWidgetRGB(new Color(207, 207, 207)); + setWidgetRGB(new Color(207, 207, 207)); + setWidgetText(svar6); + setWidgetText(svar7); + if (ivar6 > 0) { + createExtraChild(new WidgetPointer(1112,4), 4, getExtraChildGap(new WidgetPointer(1112,4))); + setWidgetSize(ivar3, 12, 0, 0); + setWidgetPosition(divide(max(subtract(ivar4, ivar3), 0), 2), 0, 2, 2); + setWidgetFont(494); + setWidgetUnknownBoolean(true); + setWidgetTextAlignment(2, 0, 0); + setWidgetRGB(new Color(207, 207, 207)); + ivar7 = multiply(ivar6, 30); + if ((ivar7 > globalint_995) || (add(ivar7, 29) < globalint_995)) { + globalint_995 = add(ivar7, 15); + } + setWidgetText(script_5094()); + setScriptCallOnGameloop(5093, new WidgetPointer(-32768,3), -2147483643, "Ii"); + } + } + return; +} diff --git a/dumps/scripts/5093.cs2 b/dumps/scripts/5093.cs2 new file mode 100644 index 0000000..05ec013 --- /dev/null +++ b/dumps/scripts/5093.cs2 @@ -0,0 +1,7 @@ +void script_5093(int arg0,int arg1) { + globalint_995 = max(subtract(globalint_995, 1), 0); + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetText(script_5094()); + } + return; +} diff --git a/dumps/scripts/5094.cs2 b/dumps/scripts/5094.cs2 new file mode 100644 index 0000000..eac2c4a --- /dev/null +++ b/dumps/scripts/5094.cs2 @@ -0,0 +1,27 @@ +string script_5094() { + int ivar0; + int ivar1; + int ivar2; + string svar0; + string svar1; + int stack_dump0; + ivar0 = divide(globalint_995, 50); + ivar1 = divide(ivar0, 60); + ivar2 = divide(ivar1, 60); + stack_dump0 = mod(ivar1, 60); + ivar0 = mod(ivar0, 60); + ivar1 = stack_dump0; + svar0 = ""; + svar1 = ""; + if (ivar1 < 10) { + svar1 = "0" + intToStr(ivar1); + } else { + svar1 = intToStr(ivar1); + } + if (ivar0 < 10) { + svar0 = "0" + intToStr(ivar0); + } else { + svar0 = intToStr(ivar0); + } + return intToStr(ivar2) + ":" + svar1 + ":" + svar0; +} diff --git a/dumps/scripts/5095.cs2 b/dumps/scripts/5095.cs2 new file mode 100644 index 0000000..781e303 --- /dev/null +++ b/dumps/scripts/5095.cs2 @@ -0,0 +1,6 @@ +void script_5095(int arg0) { + setScriptCallOnConfigChange(5096, 1736, 1735, 2, "Y", new WidgetPointer(arg0)); + setScriptCallOnGlobalStringChange(5096, 129, 1, "Y", new WidgetPointer(arg0)); + script_5097(); + return; +} diff --git a/dumps/scripts/5096.cs2 b/dumps/scripts/5096.cs2 new file mode 100644 index 0000000..9404380 --- /dev/null +++ b/dumps/scripts/5096.cs2 @@ -0,0 +1,4 @@ +void script_5096() { + script_5097(); + return; +} diff --git a/dumps/scripts/5097.cs2 b/dumps/scripts/5097.cs2 new file mode 100644 index 0000000..0c5ab92 --- /dev/null +++ b/dumps/scripts/5097.cs2 @@ -0,0 +1,62 @@ +void script_5097() { + switch (bitconfig_9539) { + case 1: + setWidgetText(new WidgetPointer(1113,4), "Unable to load your clan data."); + setWidgetText(new WidgetPointer(1113,6), "Sorry!"); + setWidgetSprite(7532, new WidgetPointer(1113,7)); + setWidgetText(new WidgetPointer(1113,8), "Please try again later when the system is less busy."); + break; + case 2: + setWidgetText(new WidgetPointer(1113,4), "And the winner is:"); + setWidgetText(new WidgetPointer(1113,6), "" + "Red Team!" + ""); + setWidgetSprite(7531, new WidgetPointer(1113,7)); + if (((boolean)bitconfig_9540)) { + setWidgetText(new WidgetPointer(1113,8), "Congratulations, your team won!"); + } else if (bitconfig_9540 == 2) { + setWidgetText(new WidgetPointer(1113,8), "Oh dear, better luck next time."); + } else { + setWidgetText(new WidgetPointer(1113,8), "Better luck next time to the Blue Team."); + } + break; + case 3: + setWidgetText(new WidgetPointer(1113,4), "And the winner is:"); + setWidgetText(new WidgetPointer(1113,6), "" + "Blue Team!" + ""); + setWidgetSprite(7530, new WidgetPointer(1113,7)); + if (bitconfig_9540 == 2) { + setWidgetText(new WidgetPointer(1113,8), "Congratulations, your team won!"); + } else if (((boolean)bitconfig_9540)) { + setWidgetText(new WidgetPointer(1113,8), "Oh dear, better luck next time."); + } else { + setWidgetText(new WidgetPointer(1113,8), "Better luck next time to the Red Team."); + } + break; + case 5: + setWidgetText(new WidgetPointer(1113,4), "And the result is:"); + setWidgetText(new WidgetPointer(1113,6), "It's a draw!"); + setWidgetSprite(7532, new WidgetPointer(1113,7)); + setWidgetText(new WidgetPointer(1113,8), "Well done, everyone!"); + break; + case 4: + setWidgetText(new WidgetPointer(1113,4), "And the winner is:"); + if (strLength(globalstring_129) > 0) { + setWidgetText(new WidgetPointer(1113,6), globalstring_129); + } else { + setWidgetText(new WidgetPointer(1113,6), "... missing!"); + } + setWidgetSprite(7532, new WidgetPointer(1113,7)); + setWidgetText(new WidgetPointer(1113,8), "Better luck next time to everyone else."); + break; + case 6: + setWidgetText(new WidgetPointer(1113,4), "And the winner is:"); + setWidgetText(new WidgetPointer(1113,6), "YOU!"); + setWidgetSprite(7532, new WidgetPointer(1113,7)); + setWidgetText(new WidgetPointer(1113,8), "Congratulations!"); + break; + default: + setWidgetText(new WidgetPointer(1113,4), ""); + setWidgetText(new WidgetPointer(1113,6), ""); + setWidgetSprite(-1, new WidgetPointer(1113,7)); + setWidgetText(new WidgetPointer(1113,8), ""); + } + return; +} diff --git a/dumps/scripts/5098.cs2 b/dumps/scripts/5098.cs2 new file mode 100644 index 0000000..3222aa7 --- /dev/null +++ b/dumps/scripts/5098.cs2 @@ -0,0 +1,3 @@ +void script_5098() { + return; +} diff --git a/dumps/scripts/5099.cs2 b/dumps/scripts/5099.cs2 new file mode 100644 index 0000000..85c2caa --- /dev/null +++ b/dumps/scripts/5099.cs2 @@ -0,0 +1,31 @@ +void script_5099(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,string arg10) { + switch (arg0) { + case 1: + script_5100(1, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, 73138333, 73138179, 73138211, 73138229, 73138210, 73138228, 73138236, 73138238, 73138248, 73138257, 73138258, arg10); + break; + case 2: + script_5100(2, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, 73138378, 73138179, 73138339, 73138381, 73138338, 73138379, 73138367, 73138342, 73138353, 73138363, 73138364, arg10); + break; + case 3: + script_5100(3, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, 73138427, 73138179, 73138388, 73138430, 73138387, 73138428, 73138416, 73138391, 73138402, 73138412, 73138413, arg10); + break; + case 4: + script_5100(4, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, 73138476, 73138179, 73138437, 73138479, 73138436, 73138477, 73138465, 73138440, 73138451, 73138461, 73138462, arg10); + break; + case 5: + script_5100(5, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, 73138525, 73138179, 73138486, 73138528, 73138485, 73138526, 73138514, 73138489, 73138500, 73138510, 73138511, arg10); + break; + case 6: + script_5100(6, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, 73138574, 73138179, 73138535, 73138577, 73138534, 73138575, 73138563, 73138538, 73138549, 73138559, 73138560, arg10); + break; + case 7: + script_5100(7, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, 73138623, 73138179, 73138584, 73138626, 73138583, 73138624, 73138612, 73138587, 73138598, 73138608, 73138609, arg10); + break; + case 8: + script_5100(8, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, 73138672, 73138179, 73138633, 73138675, 73138632, 73138673, 73138661, 73138636, 73138647, 73138657, 73138658, arg10); + break; + case 9: + script_5100(9, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, 73138721, 73138179, 73138682, 73138724, 73138681, 73138722, 73138710, 73138685, 73138696, 73138706, 73138707, arg10); + } + return; +} diff --git a/dumps/scripts/51.cs2 b/dumps/scripts/51.cs2 new file mode 100644 index 0000000..9ececb4 --- /dev/null +++ b/dumps/scripts/51.cs2 @@ -0,0 +1,4 @@ +void script_51() { + cs2method5424(2828060, 0, 7301469, 0, 2026, 2027, 2029, 2028, 2030, 13023381, 15656390); + return; +} diff --git a/dumps/scripts/510.cs2 b/dumps/scripts/510.cs2 new file mode 100644 index 0000000..dc79498 --- /dev/null +++ b/dumps/scripts/510.cs2 @@ -0,0 +1,4 @@ +void script_510() { + globalint_51 = getWidget3DDistance(new WidgetPointer(605,0)); + return; +} diff --git a/dumps/scripts/5100.cs2 b/dumps/scripts/5100.cs2 new file mode 100644 index 0000000..e495ee8 --- /dev/null +++ b/dumps/scripts/5100.cs2 @@ -0,0 +1,32 @@ +void script_5100(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12,int arg13,int arg14,int arg15,int arg16,int arg17,int arg18,int arg19,int arg20,string arg21) { + setWidgetIsHidden(true, new WidgetPointer(arg13)); + setWidgetIsHidden(false, new WidgetPointer(arg12)); + setWidgetIsHidden(true, new WidgetPointer(arg15)); + setWidgetContextMenuOption(1, new WidgetPointer(arg14), "Details"); + setWidgetText(new WidgetPointer(arg16), arg21); + switch (arg7) { + case -2: + setWidgetSprite(6194, new WidgetPointer(arg10)); + break; + case -1: + setWidgetSprite(6195, new WidgetPointer(arg10)); + break; + case 0: + setWidgetSprite(6196, new WidgetPointer(arg10)); + break; + case 1: + setWidgetSprite(6197, new WidgetPointer(arg10)); + break; + case 2: + setWidgetSprite(6198, new WidgetPointer(arg10)); + } + setWidgetSprite(arg1, new WidgetPointer(arg17)); + setWidgetSprite(arg2, new WidgetPointer(arg18)); + setWidgetRGB(new Color(getColorRelatedMethod4020(arg3)), new WidgetPointer(arg17)); + setWidgetRGB(new Color(getColorRelatedMethod4020(arg4)), new WidgetPointer(arg18)); + setWidgetRGB(new Color(getColorRelatedMethod4020(arg5)), new WidgetPointer(arg19)); + setWidgetRGB(new Color(getColorRelatedMethod4020(arg6)), new WidgetPointer(arg20)); + setScriptCallOnClickContextMenu(5111, arg0, arg8, "i1", new WidgetPointer(arg14)); + setWidgetIsHidden(true, new WidgetPointer(arg13)); + return; +} diff --git a/dumps/scripts/5101.cs2 b/dumps/scripts/5101.cs2 new file mode 100644 index 0000000..9b7e1ee --- /dev/null +++ b/dumps/scripts/5101.cs2 @@ -0,0 +1,31 @@ +void script_5101(int arg0) { + switch (arg0) { + case 1: + script_5102(73138228, 73138229, 73138266); + break; + case 2: + script_5102(73138379, 73138381, 73138382); + break; + case 3: + script_5102(73138428, 73138430, 73138431); + break; + case 4: + script_5102(73138477, 73138479, 73138480); + break; + case 5: + script_5102(73138526, 73138528, 73138529); + break; + case 6: + script_5102(73138575, 73138577, 73138578); + break; + case 7: + script_5102(73138624, 73138626, 73138627); + break; + case 8: + script_5102(73138673, 73138675, 73138676); + break; + case 9: + script_5102(73138722, 73138724, 73138725); + } + return; +} diff --git a/dumps/scripts/5102.cs2 b/dumps/scripts/5102.cs2 new file mode 100644 index 0000000..8dbe94b --- /dev/null +++ b/dumps/scripts/5102.cs2 @@ -0,0 +1,6 @@ +void script_5102(int arg0,int arg1,int arg2) { + setWidgetIsHidden(false, new WidgetPointer(arg1)); + setWidgetText(new WidgetPointer(arg2), "Clan settings prevent viewing this relationship"); + setWidgetIsHidden(false, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/5103.cs2 b/dumps/scripts/5103.cs2 new file mode 100644 index 0000000..10ab137 --- /dev/null +++ b/dumps/scripts/5103.cs2 @@ -0,0 +1,31 @@ +void script_5103(int arg0,int arg1) { + switch (arg0) { + case 1: + script_5104(arg1, 73138211, 73138229, 73138266, 73138210, 73138228); + break; + case 2: + script_5104(arg1, 73138339, 73138381, 73138382, 73138338, 73138379); + break; + case 3: + script_5104(arg1, 73138388, 73138430, 73138431, 73138387, 73138428); + break; + case 4: + script_5104(arg1, 73138437, 73138479, 73138480, 73138436, 73138477); + break; + case 5: + script_5104(arg1, 73138486, 73138528, 73138529, 73138485, 73138526); + break; + case 6: + script_5104(arg1, 73138535, 73138577, 73138578, 73138534, 73138575); + break; + case 7: + script_5104(arg1, 73138584, 73138626, 73138627, 73138583, 73138624); + break; + case 8: + script_5104(arg1, 73138633, 73138675, 73138676, 73138632, 73138673); + break; + case 9: + script_5104(arg1, 73138682, 73138724, 73138725, 73138681, 73138722); + } + return; +} diff --git a/dumps/scripts/5104.cs2 b/dumps/scripts/5104.cs2 new file mode 100644 index 0000000..a151e04 --- /dev/null +++ b/dumps/scripts/5104.cs2 @@ -0,0 +1,14 @@ +void script_5104(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + setWidgetIsHidden(true, new WidgetPointer(arg1)); + setWidgetIsHidden(false, new WidgetPointer(arg2)); + if (((boolean)arg0)) { + setWidgetText(new WidgetPointer(arg3), "Click to add" + "
" + "clan relationship"); + setWidgetContextMenuOption(1, new WidgetPointer(arg4), "Add"); + setWidgetIsHidden(true, new WidgetPointer(arg5)); + } else { + setWidgetText(new WidgetPointer(arg3), "No clan set"); + setWidgetNoOptions(new WidgetPointer(arg4)); + setWidgetIsHidden(false, new WidgetPointer(arg5)); + } + return; +} diff --git a/dumps/scripts/5105.cs2 b/dumps/scripts/5105.cs2 new file mode 100644 index 0000000..32e5e01 --- /dev/null +++ b/dumps/scripts/5105.cs2 @@ -0,0 +1,4 @@ +void script_5105() { + script_5106(); + return; +} diff --git a/dumps/scripts/5106.cs2 b/dumps/scripts/5106.cs2 new file mode 100644 index 0000000..28ef478 --- /dev/null +++ b/dumps/scripts/5106.cs2 @@ -0,0 +1,49 @@ +void script_5106() { + setWidgetIsHidden(true, new WidgetPointer(1116,33)); + setWidgetIsHidden(true, new WidgetPointer(1116,161)); + setWidgetIsHidden(true, new WidgetPointer(1116,210)); + setWidgetIsHidden(true, new WidgetPointer(1116,259)); + setWidgetIsHidden(true, new WidgetPointer(1116,308)); + setWidgetIsHidden(true, new WidgetPointer(1116,357)); + setWidgetIsHidden(true, new WidgetPointer(1116,406)); + setWidgetIsHidden(true, new WidgetPointer(1116,455)); + setWidgetIsHidden(true, new WidgetPointer(1116,504)); + switch (standart_config_2317) { + case 1: + setWidgetIsHidden(false, new WidgetPointer(1116,33)); + script_5107(standart_config_2307); + break; + case 2: + setWidgetIsHidden(false, new WidgetPointer(1116,161)); + script_5107(standart_config_2308); + break; + case 3: + setWidgetIsHidden(false, new WidgetPointer(1116,210)); + script_5107(standart_config_2309); + break; + case 4: + setWidgetIsHidden(false, new WidgetPointer(1116,259)); + script_5107(standart_config_2310); + break; + case 5: + setWidgetIsHidden(false, new WidgetPointer(1116,308)); + script_5107(standart_config_2311); + break; + case 6: + setWidgetIsHidden(false, new WidgetPointer(1116,357)); + script_5107(standart_config_2312); + break; + case 7: + setWidgetIsHidden(false, new WidgetPointer(1116,406)); + script_5107(standart_config_2313); + break; + case 8: + setWidgetIsHidden(false, new WidgetPointer(1116,455)); + script_5107(standart_config_2314); + break; + case 9: + setWidgetIsHidden(false, new WidgetPointer(1116,504)); + script_5107(standart_config_2315); + } + return; +} diff --git a/dumps/scripts/5107.cs2 b/dumps/scripts/5107.cs2 new file mode 100644 index 0000000..083ada4 --- /dev/null +++ b/dumps/scripts/5107.cs2 @@ -0,0 +1,24 @@ +void script_5107(int arg0) { + setWidgetIsHidden(true, new WidgetPointer(1116,115)); + setWidgetIsHidden(true, new WidgetPointer(1116,122)); + setWidgetIsHidden(true, new WidgetPointer(1116,108)); + setWidgetIsHidden(true, new WidgetPointer(1116,101)); + setWidgetIsHidden(true, new WidgetPointer(1116,94)); + switch (arg0) { + case -2: + setWidgetIsHidden(false, new WidgetPointer(1116,115)); + break; + case -1: + setWidgetIsHidden(false, new WidgetPointer(1116,122)); + break; + case 0: + setWidgetIsHidden(false, new WidgetPointer(1116,108)); + break; + case 1: + setWidgetIsHidden(false, new WidgetPointer(1116,101)); + break; + case 2: + setWidgetIsHidden(false, new WidgetPointer(1116,94)); + } + return; +} diff --git a/dumps/scripts/5108.cs2 b/dumps/scripts/5108.cs2 new file mode 100644 index 0000000..bea6690 --- /dev/null +++ b/dumps/scripts/5108.cs2 @@ -0,0 +1,12 @@ +void script_5108(int arg0) { + if (((boolean)arg0)) { + setWidgetSize(0, 20, 1, 1, new WidgetPointer(1116,50)); + setWidgetIsHidden(false, new WidgetPointer(1116,40)); + script_5110(1); + } else { + setWidgetSize(0, 0, 1, 1, new WidgetPointer(1116,50)); + setWidgetIsHidden(true, new WidgetPointer(1116,40)); + script_5110(0); + } + return; +} diff --git a/dumps/scripts/5109.cs2 b/dumps/scripts/5109.cs2 new file mode 100644 index 0000000..cb58e9a --- /dev/null +++ b/dumps/scripts/5109.cs2 @@ -0,0 +1,4 @@ +void script_5109(int arg0) { + script_5110(arg0); + return; +} diff --git a/dumps/scripts/511.cs2 b/dumps/scripts/511.cs2 new file mode 100644 index 0000000..8d85b51 --- /dev/null +++ b/dumps/scripts/511.cs2 @@ -0,0 +1,9 @@ +void script_511() { + if (globalint_51 > 170) { + globalint_51 = subtract(globalint_51, 1); + setWidget3DRotation(0, 0, 0, 0, 0, globalint_51, new WidgetPointer(605,0)); + } else { + setWidgetModel(-1, new WidgetPointer(605,0)); + } + return; +} diff --git a/dumps/scripts/5110.cs2 b/dumps/scripts/5110.cs2 new file mode 100644 index 0000000..0a38580 --- /dev/null +++ b/dumps/scripts/5110.cs2 @@ -0,0 +1,14 @@ +void script_5110(int arg0) { + if (((boolean)arg0)) { + setWidgetIsHidden(false, new WidgetPointer(1116,561)); + setWidgetIsHidden(true, new WidgetPointer(1116,553)); + setWidgetIsHidden(false, new WidgetPointer(1116,3)); + setWidgetIsHidden(true, new WidgetPointer(1116,4)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1116,561)); + setWidgetIsHidden(false, new WidgetPointer(1116,553)); + setWidgetIsHidden(true, new WidgetPointer(1116,3)); + setWidgetIsHidden(false, new WidgetPointer(1116,4)); + } + return; +} diff --git a/dumps/scripts/5111.cs2 b/dumps/scripts/5111.cs2 new file mode 100644 index 0000000..513a04a --- /dev/null +++ b/dumps/scripts/5111.cs2 @@ -0,0 +1,10 @@ +void script_5111(int arg0,int arg1) { + standart_config_2317 = arg0; + if (((boolean)arg1)) { + script_5108(1); + } else { + script_5108(0); + } + script_5113(arg1); + return; +} diff --git a/dumps/scripts/5112.cs2 b/dumps/scripts/5112.cs2 new file mode 100644 index 0000000..de91361 --- /dev/null +++ b/dumps/scripts/5112.cs2 @@ -0,0 +1,4 @@ +void script_5112(int arg0,int arg1) { + script_5113(arg1); + return; +} diff --git a/dumps/scripts/5113.cs2 b/dumps/scripts/5113.cs2 new file mode 100644 index 0000000..64fac76 --- /dev/null +++ b/dumps/scripts/5113.cs2 @@ -0,0 +1,31 @@ +void script_5113(int arg0) { + switch (standart_config_2317) { + case 1: + script_5114(73138236, 73138238, 73138248, 73138257, 73138258, 73138333, arg0); + break; + case 2: + script_5114(73138367, 73138342, 73138353, 73138363, 73138364, 73138378, arg0); + break; + case 3: + script_5114(73138416, 73138391, 73138402, 73138412, 73138413, 73138427, arg0); + break; + case 4: + script_5114(73138465, 73138440, 73138451, 73138461, 73138462, 73138476, arg0); + break; + case 5: + script_5114(73138514, 73138489, 73138500, 73138510, 73138511, 73138525, arg0); + break; + case 6: + script_5114(73138563, 73138538, 73138549, 73138559, 73138560, 73138574, arg0); + break; + case 7: + script_5114(73138612, 73138587, 73138598, 73138608, 73138609, 73138623, arg0); + break; + case 8: + script_5114(73138661, 73138636, 73138647, 73138657, 73138658, 73138672, arg0); + break; + case 9: + script_5114(73138710, 73138685, 73138696, 73138706, 73138707, 73138721, arg0); + } + return; +} diff --git a/dumps/scripts/5114.cs2 b/dumps/scripts/5114.cs2 new file mode 100644 index 0000000..b0eb3c2 --- /dev/null +++ b/dumps/scripts/5114.cs2 @@ -0,0 +1,51 @@ +void script_5114(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6) { + string svar0; + setWidgetIsHidden(true, new WidgetPointer(1116,85)); + setWidgetText(new WidgetPointer(1116,600), getWidgetText(new WidgetPointer(arg0))); + setWidgetSprite(getWidgetSpriteId(new WidgetPointer(arg1)), new WidgetPointer(1116,602)); + setWidgetSprite(getWidgetSpriteId(new WidgetPointer(arg2)), new WidgetPointer(1116,615)); + setWidgetRGB(getWidgetRGB(new WidgetPointer(arg1)), new WidgetPointer(1116,602)); + setWidgetRGB(getWidgetRGB(new WidgetPointer(arg2)), new WidgetPointer(1116,615)); + setWidgetRGB(getWidgetRGB(new WidgetPointer(arg3)), new WidgetPointer(1116,611)); + setWidgetRGB(getWidgetRGB(new WidgetPointer(arg4)), new WidgetPointer(1116,612)); + svar0 = ""; + switch (getWidgetSpriteId(new WidgetPointer(arg5))) { + case 6194: + setWidgetSprite(6199, new WidgetPointer(1116,591)); + svar0 = "This clan is flagged as a nemesis."; + break; + case 6195: + setWidgetSprite(6200, new WidgetPointer(1116,591)); + svar0 = "This clan is flagged as an enemy."; + break; + case 6196: + setWidgetSprite(6201, new WidgetPointer(1116,591)); + svar0 = "This clan is flagged as neutral."; + break; + case 6197: + setWidgetSprite(6202, new WidgetPointer(1116,591)); + svar0 = "This clan is flagged as a friend."; + break; + case 6198: + setWidgetSprite(6203, new WidgetPointer(1116,591)); + svar0 = "This clan is flagged as an ally."; + } + setScriptCallOnMouseOver(4538, new WidgetPointer(1116,51), new WidgetPointer(1116,591), -1, svar0, 180, 3793, 3793, 16777215, 13, 4, 3, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1116,591)); + setScriptCallOnMouseExit(40, new WidgetPointer(1116,51), "I", new WidgetPointer(1116,591)); + script_5106(); + if (((boolean)arg6)) { + if (isWidgetHidden(new WidgetPointer(1116,3))) { + setWidgetIsHidden(false, new WidgetPointer(1116,4)); + } else { + setWidgetIsHidden(false, new WidgetPointer(1116,3)); + } + setWidgetIsHidden(true, new WidgetPointer(1116,115)); + setWidgetIsHidden(true, new WidgetPointer(1116,122)); + setWidgetIsHidden(true, new WidgetPointer(1116,108)); + setWidgetIsHidden(true, new WidgetPointer(1116,101)); + setWidgetIsHidden(true, new WidgetPointer(1116,94)); + } else { + setWidgetIsHidden(false, new WidgetPointer(1116,40)); + } + return; +} diff --git a/dumps/scripts/5115.cs2 b/dumps/scripts/5115.cs2 new file mode 100644 index 0000000..1bc4e62 --- /dev/null +++ b/dumps/scripts/5115.cs2 @@ -0,0 +1,8 @@ +void script_5115(int arg0,int arg1) { + if (((boolean)arg1)) { + setWidgetSprite(7436, new WidgetPointer(arg0)); + } else { + setWidgetSprite(7435, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/5116.cs2 b/dumps/scripts/5116.cs2 new file mode 100644 index 0000000..cea50d6 --- /dev/null +++ b/dumps/scripts/5116.cs2 @@ -0,0 +1,7 @@ +int script_5116(int arg0,int arg1) { + int ivar2; + int ivar3; + ivar2 = 4515; + ivar3 = cs2method_3408(105, 103, ivar2, arg0); + return cs2method_3408(105, 74, ivar3, arg1); +} diff --git a/dumps/scripts/5117.cs2 b/dumps/scripts/5117.cs2 new file mode 100644 index 0000000..2b269c4 --- /dev/null +++ b/dumps/scripts/5117.cs2 @@ -0,0 +1,5 @@ +int script_5117(int arg0,int arg1) { + int ivar2; + ivar2 = cs2method_3408(105, 103, 4520, arg0); + return cs2method_3408(105, 74, ivar2, arg1); +} diff --git a/dumps/scripts/5118.cs2 b/dumps/scripts/5118.cs2 new file mode 100644 index 0000000..93512f1 --- /dev/null +++ b/dumps/scripts/5118.cs2 @@ -0,0 +1,53 @@ +void script_5118(int arg0) { + int ivar1; + int ivar2; + int ivar3; + string svar0; + script_4534(73334787); + script_4534(73334791); + globalint_777 = -1; + svar0 = ""; + ivar1 = 0; + ivar2 = 0; + ivar3 = add(126, 1); + while (ivar2 <= ivar3) { + createExtraChild(new WidgetPointer(1119,11), 3, getExtraChildGap(new WidgetPointer(1119,11))); + setWidgetSize(0, 14, 1, 0); + setWidgetPosition(0, ivar1, 1, 0); + cs2method2103(255); + createExtraChild(new WidgetPointer(1119,11), 5, getExtraChildGap(new WidgetPointer(1119,11))); + setWidgetSize(12, 12, 0, 0); + setWidgetPosition(5, add(ivar1, 1), 0, 0); + svar0 = cs2method_3408(105, 115, 3725, ivar2); + if (strLength(svar0) > 0) { + createExtraChild(new WidgetPointer(1119,11), 4, getExtraChildGap(new WidgetPointer(1119,11))); + setWidgetSize(22, 14, 1, 0); + setWidgetPosition(0, ivar1, 2, 0); + setWidgetTextAlignment(0, 1, 0); + setWidgetFont(494); + setWidgetUnknownBoolean(true); + setWidgetText(svar0); + setWidgetContextMenuOption(1, svar0); + setScriptCallOnClickContextMenu(5119, ivar2, "i"); + ivar1 = add(ivar1, getWidgetActualHeight()); + } else { + setWidgetHidden(1); + setWidgetHidden(1); + createExtraChild(new WidgetPointer(1119,11), 4, getExtraChildGap(new WidgetPointer(1119,11))); + setWidgetHidden(1); + } + ivar2 = add(ivar2, 1); + } + if (ivar1 > getWidgetActualHeight(new WidgetPointer(1119,11))) { + setWidgetScrollMax(0, ivar1, new WidgetPointer(1119,11)); + } else { + setWidgetScrollMax(0, 0, new WidgetPointer(1119,11)); + } + cs2method2100(0, 0, new WidgetPointer(1119,11)); + script_31(73334796, 73334795, 6507, 6504, 6505, 6506, 6499, 6498); + script_5121(); + setScriptCallOnConfigChange(5120, 1734, 1, "Y", new WidgetPointer(arg0)); + script_5124(); + setScriptCallOnGlobalConfigChange(5123, 696, 1, "Y", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/5119.cs2 b/dumps/scripts/5119.cs2 new file mode 100644 index 0000000..8596dc7 --- /dev/null +++ b/dumps/scripts/5119.cs2 @@ -0,0 +1,8 @@ +void script_5119(int arg0) { + if (globalint_777 != arg0) { + playSoundEffect2False(6185, 1, 0, 200); + globalint_777 = arg0; + } + script_5121(); + return; +} diff --git a/dumps/scripts/512.cs2 b/dumps/scripts/512.cs2 new file mode 100644 index 0000000..25a398c --- /dev/null +++ b/dumps/scripts/512.cs2 @@ -0,0 +1,4 @@ +void script_512() { + globalint_50 = getWidget3DDistance(new WidgetPointer(605,1)); + return; +} diff --git a/dumps/scripts/5120.cs2 b/dumps/scripts/5120.cs2 new file mode 100644 index 0000000..b85c49f --- /dev/null +++ b/dumps/scripts/5120.cs2 @@ -0,0 +1,4 @@ +void script_5120() { + script_5121(); + return; +} diff --git a/dumps/scripts/5121.cs2 b/dumps/scripts/5121.cs2 new file mode 100644 index 0000000..8209c93 --- /dev/null +++ b/dumps/scripts/5121.cs2 @@ -0,0 +1,72 @@ +void script_5121() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + deleteAllExtraChilds(new WidgetPointer(1119,19)); + ivar0 = 0; + ivar1 = add(126, 1); + ivar2 = -1; + ivar3 = -1; + while (ivar0 <= ivar1) { + if (ivar0 > bitconfig_9545) { + if (setWidgetRegister(new WidgetPointer(1119,11), multiply(ivar0, 3)) && isWidgetHidden()) { + removeAllEventListeners(); + if (setWidgetRegister(new WidgetPointer(1119,11), add(multiply(ivar0, 3), 1))) { + if (globalint_777 == ivar0) { + setWidgetSprite(5918); + } else { + setWidgetSprite(5922); + } + } + if (setWidgetRegister(new WidgetPointer(1119,11), add(multiply(ivar0, 3), 2))) { + setWidgetRGB(new Color(127, 127, 127)); + } + } + } else if (globalint_777 == ivar0) { + ivar2 = 5917; + ivar3 = 5916; + if (setWidgetRegister(new WidgetPointer(1119,11), multiply(ivar0, 3)) && isWidgetHidden()) { + setScriptCallOnMouseEntered(5122, new WidgetPointer(-32768,3), -2147483643, ivar2, 16777215, "Iidi"); + setScriptCallOnMouseExit(5122, new WidgetPointer(-32768,3), -2147483643, ivar3, 14671823, "Iidi"); + if (setWidgetRegister(new WidgetPointer(1119,11), add(multiply(ivar0, 3), 1))) { + setWidgetSprite(ivar3); + } + if (setWidgetRegister(new WidgetPointer(1119,11), add(multiply(ivar0, 3), 2))) { + setWidgetRGB(new Color(223, 223, 207)); + } + } + } else { + ivar2 = 5921; + ivar3 = 5920; + if (setWidgetRegister(new WidgetPointer(1119,11), multiply(ivar0, 3)) && isWidgetHidden()) { + setScriptCallOnMouseEntered(5122, new WidgetPointer(-32768,3), -2147483643, ivar2, 16777215, "Iidi"); + setScriptCallOnMouseExit(5122, new WidgetPointer(-32768,3), -2147483643, ivar3, 13615023, "Iidi"); + if (setWidgetRegister(new WidgetPointer(1119,11), add(multiply(ivar0, 3), 1))) { + setWidgetSprite(ivar3); + } + if (setWidgetRegister(new WidgetPointer(1119,11), add(multiply(ivar0, 3), 2))) { + setWidgetRGB(new Color(207, 191, 175)); + } + } + } + if (ivar0 <= globalint_777) { + createExtraChild(new WidgetPointer(1119,19), 3, ivar0); + if (ivar0 == globalint_777) { + setWidgetSize(0, 0, 1, 1); + setWidgetPosition(0, 0, 1, 1); + cs2method2103(255); + setWidgetContextMenuOption(1, "Confirm"); + } else { + setWidgetHidden(1); + } + } + ivar0 = add(ivar0, 1); + } + if (globalint_777 >= 0) { + setWidgetIsHidden(true, new WidgetPointer(1119,22)); + } else { + setWidgetIsHidden(false, new WidgetPointer(1119,22)); + } + return; +} diff --git a/dumps/scripts/5122.cs2 b/dumps/scripts/5122.cs2 new file mode 100644 index 0000000..d011ba5 --- /dev/null +++ b/dumps/scripts/5122.cs2 @@ -0,0 +1,9 @@ +void script_5122(int arg0,int arg1,int arg2,int arg3) { + if (setWidgetRegister(new WidgetPointer(arg0), add(arg1, 1))) { + setWidgetSprite(arg2); + } + if (setWidgetRegister(new WidgetPointer(arg0), add(arg1, 2))) { + setWidgetRGB(new Color(arg3)); + } + return; +} diff --git a/dumps/scripts/5123.cs2 b/dumps/scripts/5123.cs2 new file mode 100644 index 0000000..4b0668c --- /dev/null +++ b/dumps/scripts/5123.cs2 @@ -0,0 +1,4 @@ +void script_5123() { + script_5124(); + return; +} diff --git a/dumps/scripts/5124.cs2 b/dumps/scripts/5124.cs2 new file mode 100644 index 0000000..eba2fa6 --- /dev/null +++ b/dumps/scripts/5124.cs2 @@ -0,0 +1,4 @@ +void script_5124() { + setWidgetText(new WidgetPointer(1119,6), cs2method_3408(105, 115, 3725, globalint_696)); + return; +} diff --git a/dumps/scripts/5125.cs2 b/dumps/scripts/5125.cs2 new file mode 100644 index 0000000..e880250 --- /dev/null +++ b/dumps/scripts/5125.cs2 @@ -0,0 +1,4 @@ +void script_5125() { + script_5126(); + return; +} diff --git a/dumps/scripts/5126.cs2 b/dumps/scripts/5126.cs2 new file mode 100644 index 0000000..28d8e57 --- /dev/null +++ b/dumps/scripts/5126.cs2 @@ -0,0 +1,5 @@ +void script_5126() { + setWidgetIsHidden(false, new WidgetPointer(1096,33)); + script_4307(); + return; +} diff --git a/dumps/scripts/5127.cs2 b/dumps/scripts/5127.cs2 new file mode 100644 index 0000000..bd6bf92 --- /dev/null +++ b/dumps/scripts/5127.cs2 @@ -0,0 +1,6 @@ +void script_5127() { + setWidgetIsHidden(true, new WidgetPointer(1096,33)); + setWidgetIsHidden(false, new WidgetPointer(1096,398)); + setWidgetText(new WidgetPointer(1096,406), "Loading, please wait."); + return; +} diff --git a/dumps/scripts/5128.cs2 b/dumps/scripts/5128.cs2 new file mode 100644 index 0000000..7e4e7e3 --- /dev/null +++ b/dumps/scripts/5128.cs2 @@ -0,0 +1,4 @@ +void script_5128() { + script_5129(); + return; +} diff --git a/dumps/scripts/5129.cs2 b/dumps/scripts/5129.cs2 new file mode 100644 index 0000000..91e14c8 --- /dev/null +++ b/dumps/scripts/5129.cs2 @@ -0,0 +1,6 @@ +void script_5129() { + if (cs2method3701()) { + script_5132(); + } + return; +} diff --git a/dumps/scripts/513.cs2 b/dumps/scripts/513.cs2 new file mode 100644 index 0000000..4308563 --- /dev/null +++ b/dumps/scripts/513.cs2 @@ -0,0 +1,4 @@ +void script_513() { + globalint_51 = 1; + return; +} diff --git a/dumps/scripts/5130.cs2 b/dumps/scripts/5130.cs2 new file mode 100644 index 0000000..9d00fdd --- /dev/null +++ b/dumps/scripts/5130.cs2 @@ -0,0 +1,26 @@ +void script_5130() { + globalint_1569 = -1; + globalint_1571 = -1; + globalint_1570 = -1; + globalint_1572 = -1; + globalint_1574 = -1; + globalint_1573 = -1; + globalint_1575 = -1; + globalint_1576 = -1; + globalint_1577 = -1; + globalint_1578 = -1; + globalint_1579 = -1; + globalint_1580 = -1; + globalint_1581 = -1; + globalint_1582 = -1; + globalint_1583 = -1; + globalint_1584 = -1; + globalint_1585 = -1; + globalint_1586 = -1; + globalint_1587 = -1; + globalint_1588 = -1; + globalint_1589 = -1; + globalint_1649 = -1; + globalint_1590 = -1; + return; +} diff --git a/dumps/scripts/5131.cs2 b/dumps/scripts/5131.cs2 new file mode 100644 index 0000000..91c2a05 --- /dev/null +++ b/dumps/scripts/5131.cs2 @@ -0,0 +1,6 @@ +int script_5131() { + if ((((((globalint_1572 != -1) && (globalint_1574 != -1)) && ((globalint_1576 != -1) && (globalint_1577 != -1))) && (((globalint_1578 != -1) && (globalint_1579 != -1)) && ((globalint_1580 != -1) && (globalint_1581 != -1)))) && ((((globalint_1582 != -1) && (globalint_1583 != -1)) && ((globalint_1584 != -1) && (globalint_1585 != -1))) && (((globalint_1586 != -1) && (globalint_1587 != -1)) && ((globalint_1588 != -1) && (globalint_1589 != -1))))) && ((((globalint_1649 != -1) && (globalint_1590 != -1)) && ((globalint_1569 != -1) && (globalint_1571 != -1))) && (((globalint_1570 != -1) && (globalint_1573 != -1)) && (globalint_1575 != -1)))) { + return 1; + } + return 0; +} diff --git a/dumps/scripts/5132.cs2 b/dumps/scripts/5132.cs2 new file mode 100644 index 0000000..e2d7a8d --- /dev/null +++ b/dumps/scripts/5132.cs2 @@ -0,0 +1,7 @@ +void script_5132() { + if (((boolean)script_5131())) { + script_5127(); + script_5133(); + } + return; +} diff --git a/dumps/scripts/5133.cs2 b/dumps/scripts/5133.cs2 new file mode 100644 index 0000000..e759d11 --- /dev/null +++ b/dumps/scripts/5133.cs2 @@ -0,0 +1,226 @@ +void script_5133() { + int ivar0; + int ivar1; + string svar0; + ivar0 = 0; + ivar1 = script_4293(); + if (((boolean)script_5131())) { + setWidgetIsHidden(true, new WidgetPointer(1096,417)); + setWidgetIsHidden(true, new WidgetPointer(1096,425)); + setWidgetIsHidden(true, new WidgetPointer(1096,433)); + setWidgetIsHidden(true, new WidgetPointer(1096,441)); + setWidgetIsHidden(true, new WidgetPointer(1096,449)); + setWidgetIsHidden(true, new WidgetPointer(1096,457)); + setWidgetIsHidden(true, new WidgetPointer(1096,465)); + setWidgetIsHidden(true, new WidgetPointer(1096,473)); + setWidgetIsHidden(true, new WidgetPointer(1096,481)); + setWidgetIsHidden(true, new WidgetPointer(1096,489)); + setWidgetIsHidden(true, new WidgetPointer(1096,497)); + switch (globalint_1569) { + case 0: + setWidgetIsHidden(false, new WidgetPointer(1096,417)); + if (ivar1 >= 100) { + ivar0 = 1; + } + break; + case 1: + setWidgetIsHidden(false, new WidgetPointer(1096,425)); + if (ivar1 >= 100) { + ivar0 = 1; + } + break; + case 2: + setWidgetIsHidden(false, new WidgetPointer(1096,433)); + if (ivar1 >= 100) { + ivar0 = 1; + } + break; + case 3: + setWidgetIsHidden(false, new WidgetPointer(1096,441)); + if (ivar1 >= 100) { + ivar0 = 1; + } + break; + case 4: + setWidgetIsHidden(false, new WidgetPointer(1096,449)); + if (ivar1 >= 100) { + ivar0 = 1; + } + break; + case 5: + setWidgetIsHidden(false, new WidgetPointer(1096,457)); + if (ivar1 >= 100) { + ivar0 = 1; + } + break; + case 100: + setWidgetIsHidden(false, new WidgetPointer(1096,465)); + if (ivar1 > globalint_1569) { + ivar0 = 1; + } + break; + case 101: + setWidgetIsHidden(false, new WidgetPointer(1096,473)); + if (ivar1 > globalint_1569) { + ivar0 = 1; + } + break; + case 102: + setWidgetIsHidden(false, new WidgetPointer(1096,481)); + if (ivar1 > globalint_1569) { + ivar0 = 1; + } + break; + case 103: + setWidgetIsHidden(false, new WidgetPointer(1096,489)); + if (ivar1 > globalint_1569) { + ivar0 = 1; + } + break; + case 125: + setWidgetIsHidden(false, new WidgetPointer(1096,497)); + if (ivar1 > globalint_1569) { + ivar0 = 1; + } + break; + case 126: + ivar0 = 0; + break; + case 127: + ivar0 = 0; + break; + default: + if (ivar1 >= 100) { + ivar0 = 1; + } + } + } + svar0 = ""; + setWidgetIsHidden(false, new WidgetPointer(1096,584)); + setWidgetIsHidden(false, new WidgetPointer(1096,596)); + setWidgetIsHidden(false, new WidgetPointer(1096,629)); + setWidgetIsHidden(false, new WidgetPointer(1096,640)); + setWidgetIsHidden(false, new WidgetPointer(1096,662)); + setWidgetIsHidden(false, new WidgetPointer(1096,509)); + setWidgetIsHidden(false, new WidgetPointer(1096,618)); + setWidgetIsHidden(false, new WidgetPointer(1096,607)); + setWidgetIsHidden(false, new WidgetPointer(1096,651)); + setWidgetIsHidden(false, new WidgetPointer(1096,573)); + setWidgetIsHidden(false, new WidgetPointer(1096,560)); + setWidgetIsHidden(false, new WidgetPointer(1096,778)); + setWidgetIsHidden(false, new WidgetPointer(1096,765)); + setWidgetIsHidden(false, new WidgetPointer(1096,674)); + setWidgetIsHidden(false, new WidgetPointer(1096,685)); + setWidgetIsHidden(false, new WidgetPointer(1096,697)); + setWidgetIsHidden(false, new WidgetPointer(1096,710)); + setWidgetIsHidden(false, new WidgetPointer(1096,722)); + setWidgetIsHidden(false, new WidgetPointer(1096,819)); + setWidgetIsHidden(false, new WidgetPointer(1096,734)); + setWidgetIsHidden(false, new WidgetPointer(1096,808)); + setWidgetIsHidden(false, new WidgetPointer(1096,746)); + if (((boolean)ivar0)) { + setWidgetIsHidden(true, new WidgetPointer(1096,584)); + setWidgetIsHidden(true, new WidgetPointer(1096,596)); + if (globalint_1569 >= 100) { + setWidgetIsHidden(true, new WidgetPointer(1096,629)); + } else { + svar0 = "Only admins and above may upgrade the citadel."; + setScriptCallOnMouseOver(5138, svar0, new WidgetPointer(-32768,3), "sI", new WidgetPointer(1096,629)); + } + if (globalint_1569 >= 100) { + setWidgetIsHidden(true, new WidgetPointer(1096,640)); + } else { + svar0 = "Only admins and above may downgrade the citadel."; + setScriptCallOnMouseOver(5138, svar0, new WidgetPointer(-32768,3), "sI", new WidgetPointer(1096,640)); + } + if (globalint_1569 >= 100) { + setWidgetIsHidden(true, new WidgetPointer(1096,662)); + } + setWidgetIsHidden(true, new WidgetPointer(1096,509)); + if (globalint_1569 >= 100) { + setWidgetIsHidden(true, new WidgetPointer(1096,618)); + } else { + svar0 = "Only admins and above may change the noticeboard."; + setScriptCallOnMouseOver(5138, svar0, new WidgetPointer(-32768,3), "sI", new WidgetPointer(1096,618)); + } + if (globalint_1569 >= 100) { + setWidgetIsHidden(true, new WidgetPointer(1096,607)); + } else { + svar0 = "Only admins and above may change the signpost."; + setScriptCallOnMouseOver(5139, svar0, new WidgetPointer(-32768,3), "sI", new WidgetPointer(1096,607)); + } + setWidgetIsHidden(true, new WidgetPointer(1096,651)); + if (globalint_1569 >= 100) { + setWidgetIsHidden(true, new WidgetPointer(1096,573)); + } else { + svar0 = "Only admins and above may change who may lock the citadel."; + setScriptCallOnMouseOver(5138, svar0, new WidgetPointer(-32768,3), "sI", new WidgetPointer(1096,573)); + } + if (globalint_1569 >= 100) { + setWidgetIsHidden(true, new WidgetPointer(1096,560)); + } else { + svar0 = "Only admins and above may change who may lock the keep."; + setScriptCallOnMouseOver(5138, svar0, new WidgetPointer(-32768,3), "sI", new WidgetPointer(1096,560)); + } + if (((boolean)script_5149(ivar1))) { + setWidgetIsHidden(true, new WidgetPointer(1096,778)); + } else { + svar0 = "Your rank does not have permission to change citadel access."; + setScriptCallOnMouseOver(5138, svar0, new WidgetPointer(-32768,3), "sI", new WidgetPointer(1096,778)); + } + if (((boolean)script_5148(ivar1))) { + setWidgetIsHidden(true, new WidgetPointer(1096,765)); + } else { + svar0 = "Your rank does not have permission to change keep access."; + setScriptCallOnMouseOver(5138, svar0, new WidgetPointer(-32768,3), "sI", new WidgetPointer(1096,765)); + } + setWidgetIsHidden(true, new WidgetPointer(1096,674)); + setWidgetIsHidden(true, new WidgetPointer(1096,685)); + setWidgetIsHidden(true, new WidgetPointer(1096,697)); + setWidgetIsHidden(true, new WidgetPointer(1096,710)); + setWidgetIsHidden(true, new WidgetPointer(1096,722)); + setWidgetIsHidden(true, new WidgetPointer(1096,819)); + if (globalint_1569 >= 100) { + setWidgetIsHidden(true, new WidgetPointer(1096,734)); + } else { + svar0 = "Only admins and above may set gathering goals."; + setScriptCallOnMouseOver(5138, svar0, new WidgetPointer(-32768,3), "sI", new WidgetPointer(1096,734)); + } + if (globalint_1569 >= 103) { + setWidgetIsHidden(true, new WidgetPointer(1096,808)); + } else { + svar0 = "Only overseers and above may set the citadel's language."; + setScriptCallOnMouseOver(5139, svar0, new WidgetPointer(-32768,3), "sI", new WidgetPointer(1096,808)); + } + if (globalint_1569 >= 103) { + setWidgetIsHidden(true, new WidgetPointer(1096,746)); + } else { + svar0 = "Only overseers and above may move the build tick."; + setScriptCallOnMouseOver(5138, svar0, new WidgetPointer(-32768,3), "sI", new WidgetPointer(1096,746)); + } + } else { + svar0 = "Your rank is not high enough to alter this permission."; + setScriptCallOnMouseOver(5138, svar0, new WidgetPointer(-32768,3), "sI", new WidgetPointer(1096,629)); + setScriptCallOnMouseOver(5138, svar0, new WidgetPointer(-32768,3), "sI", new WidgetPointer(1096,640)); + setScriptCallOnMouseOver(5138, svar0, new WidgetPointer(-32768,3), "sI", new WidgetPointer(1096,662)); + setScriptCallOnMouseOver(5139, svar0, new WidgetPointer(-32768,3), "sI", new WidgetPointer(1096,509)); + setScriptCallOnMouseOver(5138, svar0, new WidgetPointer(-32768,3), "sI", new WidgetPointer(1096,618)); + setScriptCallOnMouseOver(5139, svar0, new WidgetPointer(-32768,3), "sI", new WidgetPointer(1096,607)); + setScriptCallOnMouseOver(5139, svar0, new WidgetPointer(-32768,3), "sI", new WidgetPointer(1096,651)); + setScriptCallOnMouseOver(5138, svar0, new WidgetPointer(-32768,3), "sI", new WidgetPointer(1096,573)); + setScriptCallOnMouseOver(5138, svar0, new WidgetPointer(-32768,3), "sI", new WidgetPointer(1096,560)); + setScriptCallOnMouseOver(5138, svar0, new WidgetPointer(-32768,3), "sI", new WidgetPointer(1096,778)); + setScriptCallOnMouseOver(5138, svar0, new WidgetPointer(-32768,3), "sI", new WidgetPointer(1096,765)); + setScriptCallOnMouseOver(5138, svar0, new WidgetPointer(-32768,3), "sI", new WidgetPointer(1096,674)); + setScriptCallOnMouseOver(5139, svar0, new WidgetPointer(-32768,3), "sI", new WidgetPointer(1096,685)); + setScriptCallOnMouseOver(5138, svar0, new WidgetPointer(-32768,3), "sI", new WidgetPointer(1096,697)); + setScriptCallOnMouseOver(5138, svar0, new WidgetPointer(-32768,3), "sI", new WidgetPointer(1096,710)); + setScriptCallOnMouseOver(5139, svar0, new WidgetPointer(-32768,3), "sI", new WidgetPointer(1096,722)); + setScriptCallOnMouseOver(5139, svar0, new WidgetPointer(-32768,3), "sI", new WidgetPointer(1096,819)); + setScriptCallOnMouseOver(5138, svar0, new WidgetPointer(-32768,3), "sI", new WidgetPointer(1096,734)); + setScriptCallOnMouseOver(5139, svar0, new WidgetPointer(-32768,3), "sI", new WidgetPointer(1096,808)); + setScriptCallOnMouseOver(5138, svar0, new WidgetPointer(-32768,3), "sI", new WidgetPointer(1096,746)); + } + script_5135(); + return; +} diff --git a/dumps/scripts/5134.cs2 b/dumps/scripts/5134.cs2 new file mode 100644 index 0000000..4e0b79a --- /dev/null +++ b/dumps/scripts/5134.cs2 @@ -0,0 +1,4 @@ +void script_5134() { + script_5135(); + return; +} diff --git a/dumps/scripts/5135.cs2 b/dumps/scripts/5135.cs2 new file mode 100644 index 0000000..91dd0be --- /dev/null +++ b/dumps/scripts/5135.cs2 @@ -0,0 +1,115 @@ +void script_5135() { + if (((boolean)script_5131())) { + if (((boolean)globalint_1571)) { + setWidgetIsHidden(false, new WidgetPointer(1096,581)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1096,581)); + } + if (((boolean)globalint_1570)) { + setWidgetIsHidden(false, new WidgetPointer(1096,593)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1096,593)); + } + if (((boolean)globalint_1572)) { + setWidgetIsHidden(false, new WidgetPointer(1096,557)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1096,557)); + } + if (((boolean)globalint_1574)) { + setWidgetIsHidden(false, new WidgetPointer(1096,570)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1096,570)); + } + if (((boolean)globalint_1573)) { + setWidgetIsHidden(false, new WidgetPointer(1096,762)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1096,762)); + } + if (((boolean)globalint_1575)) { + setWidgetIsHidden(false, new WidgetPointer(1096,775)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1096,775)); + } + if (((boolean)globalint_1576)) { + setWidgetIsHidden(false, new WidgetPointer(1096,507)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1096,507)); + } + if (((boolean)globalint_1577)) { + setWidgetIsHidden(false, new WidgetPointer(1096,671)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1096,671)); + } + if (((boolean)globalint_1578)) { + setWidgetIsHidden(false, new WidgetPointer(1096,682)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1096,682)); + } + if (((boolean)globalint_1579)) { + setWidgetIsHidden(false, new WidgetPointer(1096,694)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1096,694)); + } + if (((boolean)globalint_1580)) { + setWidgetIsHidden(false, new WidgetPointer(1096,707)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1096,707)); + } + if (((boolean)globalint_1581)) { + setWidgetIsHidden(false, new WidgetPointer(1096,719)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1096,719)); + } + if (((boolean)globalint_1582)) { + setWidgetIsHidden(false, new WidgetPointer(1096,816)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1096,816)); + } + if (((boolean)globalint_1583)) { + setWidgetIsHidden(false, new WidgetPointer(1096,615)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1096,615)); + } + if (((boolean)globalint_1584)) { + setWidgetIsHidden(false, new WidgetPointer(1096,604)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1096,604)); + } + if (((boolean)globalint_1585)) { + setWidgetIsHidden(false, new WidgetPointer(1096,648)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1096,648)); + } + if (((boolean)globalint_1586)) { + setWidgetIsHidden(false, new WidgetPointer(1096,626)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1096,626)); + } + if (((boolean)globalint_1587)) { + setWidgetIsHidden(false, new WidgetPointer(1096,637)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1096,637)); + } + if (((boolean)globalint_1588)) { + setWidgetIsHidden(false, new WidgetPointer(1096,659)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1096,659)); + } + if (((boolean)globalint_1589)) { + setWidgetIsHidden(false, new WidgetPointer(1096,731)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1096,731)); + } + if (((boolean)globalint_1649)) { + setWidgetIsHidden(false, new WidgetPointer(1096,805)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1096,805)); + } + if (((boolean)globalint_1590)) { + setWidgetIsHidden(false, new WidgetPointer(1096,743)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1096,743)); + } + } + return; +} diff --git a/dumps/scripts/5136.cs2 b/dumps/scripts/5136.cs2 new file mode 100644 index 0000000..ffe78bf --- /dev/null +++ b/dumps/scripts/5136.cs2 @@ -0,0 +1,4 @@ +void script_5136(int arg0) { + script_5137(arg0); + return; +} diff --git a/dumps/scripts/5137.cs2 b/dumps/scripts/5137.cs2 new file mode 100644 index 0000000..27abe99 --- /dev/null +++ b/dumps/scripts/5137.cs2 @@ -0,0 +1,21 @@ +void script_5137(int arg0) { + setWidgetIsHidden(true, new WidgetPointer(1096,513)); + setWidgetIsHidden(true, new WidgetPointer(1096,522)); + setWidgetIsHidden(true, new WidgetPointer(1096,530)); + setWidgetIsHidden(true, new WidgetPointer(1096,538)); + setWidgetIsHidden(true, new WidgetPointer(1096,546)); + if (((boolean)arg0)) { + setWidgetIsHidden(false, new WidgetPointer(1096,513)); + } else if (arg0 == 2) { + setWidgetIsHidden(false, new WidgetPointer(1096,522)); + } else if (arg0 == 3) { + setWidgetIsHidden(false, new WidgetPointer(1096,530)); + } else if (arg0 == 4) { + setWidgetIsHidden(false, new WidgetPointer(1096,538)); + } else { + if (arg0 == 5) { + setWidgetIsHidden(false, new WidgetPointer(1096,546)); + } + } + return; +} diff --git a/dumps/scripts/5138.cs2 b/dumps/scripts/5138.cs2 new file mode 100644 index 0000000..30dc4a8 --- /dev/null +++ b/dumps/scripts/5138.cs2 @@ -0,0 +1,6 @@ +void script_5138(int arg0,string arg1) { + int ivar1; + ivar1 = add(getWidgetActualX(new WidgetPointer(arg0)), divide(getWidgetActualWidth(new WidgetPointer(arg0)), 2)); + script_4539(71827560, arg0, -1, 150, -1, -1, -1, 13, 4, 2, ivar1, getWidgetActualY(new WidgetPointer(arg0)), arg1); + return; +} diff --git a/dumps/scripts/5139.cs2 b/dumps/scripts/5139.cs2 new file mode 100644 index 0000000..1adeda0 --- /dev/null +++ b/dumps/scripts/5139.cs2 @@ -0,0 +1,6 @@ +void script_5139(int arg0,string arg1) { + int ivar1; + ivar1 = add(getWidgetActualX(new WidgetPointer(arg0)), divide(getWidgetActualWidth(new WidgetPointer(arg0)), 2)); + script_4539(71827560, arg0, -1, 150, -1, -1, -1, 13, 4, 0, ivar1, getWidgetActualY(new WidgetPointer(arg0)), arg1); + return; +} diff --git a/dumps/scripts/514.cs2 b/dumps/scripts/514.cs2 new file mode 100644 index 0000000..c49f9a4 --- /dev/null +++ b/dumps/scripts/514.cs2 @@ -0,0 +1,20 @@ +void script_514() { + int ivar0; + int ivar1; + ivar0 = 0; + ivar1 = 0; + if (getDisplayMode() >= 2) { + ivar0 = getWidgetActualWidth(new WidgetPointer(746,9)); + ivar1 = getWidgetActualHeight(new WidgetPointer(746,9)); + if (globalint_51 < ivar0) { + globalint_51 = add(globalint_51, 15); + setWidgetSize(globalint_51, ivar1, 0, 0, new WidgetPointer(610,1)); + } + } else { + if (globalint_51 < 512) { + globalint_51 = add(globalint_51, 15); + setWidgetSize(globalint_51, 334, 0, 0, new WidgetPointer(610,1)); + } + } + return; +} diff --git a/dumps/scripts/5140.cs2 b/dumps/scripts/5140.cs2 new file mode 100644 index 0000000..6fdae9a --- /dev/null +++ b/dumps/scripts/5140.cs2 @@ -0,0 +1,65 @@ +void script_5140(int arg0) { + switch (arg0) { + case 71827963: + globalint_1576 = -1; + break; + case 71828013: + globalint_1572 = -1; + break; + case 71828026: + globalint_1574 = -1; + break; + case 71828218: + globalint_1573 = -1; + break; + case 71828231: + globalint_1575 = -1; + break; + case 71828127: + globalint_1577 = -1; + break; + case 71828138: + globalint_1578 = -1; + break; + case 71828150: + globalint_1579 = -1; + break; + case 71828163: + globalint_1580 = -1; + break; + case 71828175: + globalint_1581 = -1; + break; + case 71828272: + globalint_1582 = -1; + break; + case 71828071: + globalint_1583 = -1; + break; + case 71828060: + globalint_1584 = -1; + break; + case 71828104: + globalint_1585 = -1; + break; + case 71828082: + globalint_1586 = -1; + break; + case 71828093: + globalint_1587 = -1; + break; + case 71828115: + globalint_1588 = -1; + break; + case 71828187: + globalint_1589 = -1; + break; + case 71828261: + globalint_1649 = -1; + break; + case 71828199: + globalint_1590 = -1; + } + script_5141(arg0); + return; +} diff --git a/dumps/scripts/5141.cs2 b/dumps/scripts/5141.cs2 new file mode 100644 index 0000000..8c9264b --- /dev/null +++ b/dumps/scripts/5141.cs2 @@ -0,0 +1,8 @@ +void script_5141(int arg0) { + if (isWidgetHidden(new WidgetPointer(arg0))) { + setWidgetIsHidden(false, new WidgetPointer(arg0)); + } else { + setWidgetIsHidden(true, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/5142.cs2 b/dumps/scripts/5142.cs2 new file mode 100644 index 0000000..df2dfe9 --- /dev/null +++ b/dumps/scripts/5142.cs2 @@ -0,0 +1,11 @@ +void script_5142(int arg0) { + switch (arg0) { + case 71828049: + globalint_1570 = -1; + break; + case 71828037: + globalint_1571 = -1; + } + setWidgetIsHidden(false, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/5143.cs2 b/dumps/scripts/5143.cs2 new file mode 100644 index 0000000..9833356 --- /dev/null +++ b/dumps/scripts/5143.cs2 @@ -0,0 +1,10 @@ +void script_5143(int arg0,int arg1) { + if (isWidgetHidden(new WidgetPointer(arg0))) { + setWidgetIsHidden(false, new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(arg1)); + } else { + setWidgetIsHidden(true, new WidgetPointer(arg0)); + setWidgetIsHidden(false, new WidgetPointer(arg1)); + } + return; +} diff --git a/dumps/scripts/5144.cs2 b/dumps/scripts/5144.cs2 new file mode 100644 index 0000000..014d81f --- /dev/null +++ b/dumps/scripts/5144.cs2 @@ -0,0 +1,6 @@ +int script_5144(int arg0) { + if (cs2method3701()) { + return script_5145(arg0); + } + return 0; +} diff --git a/dumps/scripts/5145.cs2 b/dumps/scripts/5145.cs2 new file mode 100644 index 0000000..0374df7 --- /dev/null +++ b/dumps/scripts/5145.cs2 @@ -0,0 +1,41 @@ +int script_5145(int arg0) { + int ivar1; + int ivar2; + ivar1 = -1; + ivar1 = cs2method3717(strRemoveEntities(cs2method5020())); + if (ivar1 < 0) { + return 0; + } + if (arg0 == -1) { + arg0 = cs2method3711(ivar1); + } + ivar2 = 0; + if (citadelConfigsInitialized()) { + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + switch (arg0) { + case 100: + return clanbitconfig_248; + case 101: + return clanbitconfig_249; + case 102: + return clanbitconfig_250; + case 103: + return clanbitconfig_251; + case 125: + return clanbitconfig_252; + case 126: + return 1; + case 127: + return 1; + } + return 0; +} diff --git a/dumps/scripts/5146.cs2 b/dumps/scripts/5146.cs2 new file mode 100644 index 0000000..47f57af --- /dev/null +++ b/dumps/scripts/5146.cs2 @@ -0,0 +1,6 @@ +int script_5146(int arg0) { + if (cs2method3701()) { + return script_5147(arg0); + } + return 0; +} diff --git a/dumps/scripts/5147.cs2 b/dumps/scripts/5147.cs2 new file mode 100644 index 0000000..6db5338 --- /dev/null +++ b/dumps/scripts/5147.cs2 @@ -0,0 +1,41 @@ +int script_5147(int arg0) { + int ivar1; + int ivar2; + ivar1 = -1; + ivar1 = cs2method3717(strRemoveEntities(cs2method5020())); + if (ivar1 < 0) { + return 0; + } + if (arg0 == -1) { + arg0 = cs2method3711(ivar1); + } + ivar2 = 0; + if (citadelConfigsInitialized()) { + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + switch (arg0) { + case 100: + return clanbitconfig_253; + case 101: + return clanbitconfig_254; + case 102: + return clanbitconfig_255; + case 103: + return clanbitconfig_256; + case 125: + return clanbitconfig_257; + case 126: + return 1; + case 127: + return 1; + } + return 0; +} diff --git a/dumps/scripts/5148.cs2 b/dumps/scripts/5148.cs2 new file mode 100644 index 0000000..60fe462 --- /dev/null +++ b/dumps/scripts/5148.cs2 @@ -0,0 +1,40 @@ +int script_5148(int arg0) { + int ivar1; + ivar1 = -1; + ivar1 = cs2method3717(strRemoveEntities(cs2method5020())); + if (ivar1 < 0) { + return 0; + } + if (arg0 == -1) { + arg0 = cs2method3711(ivar1); + } + switch (arg0) { + case 0: + return 0; + case 1: + return 0; + case 2: + return 0; + case 3: + return 0; + case 4: + return 0; + case 5: + return 0; + case 100: + return clanbitconfig_146; + case 101: + return clanbitconfig_147; + case 102: + return clanbitconfig_148; + case 103: + return clanbitconfig_149; + case 125: + return clanbitconfig_150; + case 126: + return 1; + case 127: + return 1; + } + return 0; +} diff --git a/dumps/scripts/5149.cs2 b/dumps/scripts/5149.cs2 new file mode 100644 index 0000000..60d5443 --- /dev/null +++ b/dumps/scripts/5149.cs2 @@ -0,0 +1,40 @@ +int script_5149(int arg0) { + int ivar1; + ivar1 = -1; + ivar1 = cs2method3717(strRemoveEntities(cs2method5020())); + if (ivar1 < 0) { + return 0; + } + if (arg0 == -1) { + arg0 = cs2method3711(ivar1); + } + switch (arg0) { + case 0: + return 0; + case 1: + return 0; + case 2: + return 0; + case 3: + return 0; + case 4: + return 0; + case 5: + return 0; + case 100: + return clanbitconfig_151; + case 101: + return clanbitconfig_152; + case 102: + return clanbitconfig_153; + case 103: + return clanbitconfig_154; + case 125: + return clanbitconfig_155; + case 126: + return 1; + case 127: + return 1; + } + return 0; +} diff --git a/dumps/scripts/515.cs2 b/dumps/scripts/515.cs2 new file mode 100644 index 0000000..d2c6ed7 --- /dev/null +++ b/dumps/scripts/515.cs2 @@ -0,0 +1,6 @@ +void script_515() { + globalint_51 = 300; + globalint_50 = 0; + globalint_52 = 0; + return; +} diff --git a/dumps/scripts/5150.cs2 b/dumps/scripts/5150.cs2 new file mode 100644 index 0000000..7ff7f76 --- /dev/null +++ b/dumps/scripts/5150.cs2 @@ -0,0 +1,8 @@ +void script_5150(int arg0) { + string svar0; + svar0 = "It would be advisable to retrieve items you have dropped and do not wish to lose."; + if (setWidgetRegister(new WidgetPointer(arg0))) { + setScriptCallOnMouseOver(4538, new WidgetPointer(800,1), new WidgetPointer(-32768,3), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, 2, -2147483647, -2147483646, "IIisifdiiiiii"); + } + return; +} diff --git a/dumps/scripts/5151.cs2 b/dumps/scripts/5151.cs2 new file mode 100644 index 0000000..fe8954d --- /dev/null +++ b/dumps/scripts/5151.cs2 @@ -0,0 +1,4 @@ +void script_5151() { + setScriptCallOnGameloop(5152, "", new WidgetPointer(800,6)); + return; +} diff --git a/dumps/scripts/5152.cs2 b/dumps/scripts/5152.cs2 new file mode 100644 index 0000000..dcec5ff --- /dev/null +++ b/dumps/scripts/5152.cs2 @@ -0,0 +1,28 @@ +void script_5152() { + int ivar0; + int ivar1; + int ivar2; + string svar0; + ivar0 = 0; + ivar1 = 0; + ivar2 = 0; + svar0 = ""; + globalint_1563 = max(subtract(globalint_1563, 1), 0); + if (((boolean)mod(globalint_1563, 50))) { + ivar2 = divide(globalint_1563, 50); + ivar1 = mod(ivar2, 60); + ivar0 = divide(ivar2, 60); + svar0 = intToStr(ivar0) + ":"; + if (ivar1 < 10) { + svar0 = concat(svar0, "0" + intToStr(ivar1)); + } else { + svar0 = concat(svar0, intToStr(ivar1)); + } + setWidgetText(new WidgetPointer(800,6), svar0); + } + if (globalint_1563 <= 0) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(800,6)); + sendCloseWidgetPacket(); + } + return; +} diff --git a/dumps/scripts/5153.cs2 b/dumps/scripts/5153.cs2 new file mode 100644 index 0000000..5d806a9 --- /dev/null +++ b/dumps/scripts/5153.cs2 @@ -0,0 +1,9 @@ +void script_5153(int arg0) { + if (((boolean)arg0)) { + setWidgetSprite(7543, new WidgetPointer(800,8)); + } else { + setWidgetSprite(7542, new WidgetPointer(800,8)); + script_41(52428801); + } + return; +} diff --git a/dumps/scripts/5154.cs2 b/dumps/scripts/5154.cs2 new file mode 100644 index 0000000..bd676d9 --- /dev/null +++ b/dumps/scripts/5154.cs2 @@ -0,0 +1,33 @@ +void script_5154(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + if ((arg0 == -1) || (arg1 == -1)) { + return; + } + ivar2 = getOtherCommonData(arg1, 1348); + ivar3 = getOtherCommonData(arg1, 1355); + ivar4 = getOtherCommonData(arg1, 1356); + ivar5 = getOtherCommonData(arg1, 1358); + deleteAllExtraChilds(new WidgetPointer(arg0)); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 0, 1); + setWidgetSize(8, 20, 0, 0); + setWidgetSprite(ivar2); + cs2method2103(ivar5); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 1, 1); + setWidgetSize(16, 20, 1, 0); + setWidgetSprite(ivar3); + cs2method2103(ivar5); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 2, 1); + setWidgetSize(8, 20, 0, 0); + setWidgetSprite(ivar4); + cs2method2103(ivar5); + cs2method1107(1); + return; +} diff --git a/dumps/scripts/5155.cs2 b/dumps/scripts/5155.cs2 new file mode 100644 index 0000000..d4a17dd --- /dev/null +++ b/dumps/scripts/5155.cs2 @@ -0,0 +1,25 @@ +void script_5155(int arg0,int arg1) { + int ivar2; + if ((arg0 == -1) || (arg1 == -1)) { + return; + } + ivar2 = getOtherCommonData(arg1, 1346); + if (ivar2 == 2) { + setScriptCallOnMouseEntered(4159, new WidgetPointer(-32768,3), 0, 0, "Iii", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(4159, new WidgetPointer(-32768,3), 1, 0, "Iii", new WidgetPointer(arg0)); + } else if (ivar2 == 3) { + setScriptCallOnMousePressed(4162, new WidgetPointer(-32768,3), "I", new WidgetPointer(arg0)); + setScriptCallOnMouseReleased(4163, new WidgetPointer(-32768,3), "I", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(4163, new WidgetPointer(-32768,3), "I", new WidgetPointer(arg0)); + } else { + if (ivar2 == 5) { + return; + } + } + script_5156(arg0, arg1); + if (ivar2 == 4) { + script_4161(arg0, 0); + setWidgetIsHidden(true, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/5156.cs2 b/dumps/scripts/5156.cs2 new file mode 100644 index 0000000..0a49c7a --- /dev/null +++ b/dumps/scripts/5156.cs2 @@ -0,0 +1,19 @@ +void script_5156(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + if ((arg0 == -1) || (arg1 == -1)) { + return; + } + ivar2 = getOtherCommonData(arg1, 1351); + ivar3 = getOtherCommonData(arg1, 1358); + ivar4 = getOtherCommonData(arg1, 1872); + deleteAllExtraChilds(new WidgetPointer(arg0)); + createExtraChild(new WidgetPointer(arg0), 5, getExtraChildGap(new WidgetPointer(arg0))); + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(9, 60, 0, 0); + setWidgetSprite(ivar2); + cs2method2103(ivar3); + setWidgetHFlip(ivar4); + return; +} diff --git a/dumps/scripts/5157.cs2 b/dumps/scripts/5157.cs2 new file mode 100644 index 0000000..dccd98a --- /dev/null +++ b/dumps/scripts/5157.cs2 @@ -0,0 +1,4 @@ +void script_5157(int arg0) { + globalint_1591 = arg0; + return; +} diff --git a/dumps/scripts/5158.cs2 b/dumps/scripts/5158.cs2 new file mode 100644 index 0000000..e04ab31 --- /dev/null +++ b/dumps/scripts/5158.cs2 @@ -0,0 +1,27 @@ +void script_5158(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + setWidgetRGB(new Color(getColorRelatedMethod4020(standart_config_2347)), new WidgetPointer(arg2)); + ivar3 = getWidgetActualHeight(new WidgetPointer(arg1)); + ivar4 = 1; + if (bitconfig_9642 > 0) { + ivar4 = max(min(subtract(ivar3, multiply(bitconfig_9642, 2)), ivar3), 0); + } + script_5168(ivar4); + ivar5 = getWidgetActualHeight(new WidgetPointer(arg0)); + ivar6 = 0; + if (bitconfig_9643 > 0) { + ivar6 = max(min(subtract(ivar5, multiply(bitconfig_9643, divide(ivar5, 8))), ivar5), 0); + ivar6 = max(min(subtract(ivar6, divide(ivar5, 16)), ivar5), 0); + } + ivar7 = 0; + if (bitconfig_9644 > 0) { + ivar7 = max(min(multiply(bitconfig_9644, divide(ivar5, 128)), ivar5), 0); + } + setWidgetRGB(new Color(bitconfig_9642), new WidgetPointer(arg0)); + script_5167(ivar7, ivar6); + return; +} diff --git a/dumps/scripts/5159.cs2 b/dumps/scripts/5159.cs2 new file mode 100644 index 0000000..8dc67cb --- /dev/null +++ b/dumps/scripts/5159.cs2 @@ -0,0 +1,6 @@ +void script_5159(int arg0,int arg1,int arg2,int arg3,int arg4) { + globalint_1592 = arg3; + globalint_1593 = arg4; + script_5161(arg0, arg1, arg2, arg3, arg4); + return; +} diff --git a/dumps/scripts/516.cs2 b/dumps/scripts/516.cs2 new file mode 100644 index 0000000..7e0d1d4 --- /dev/null +++ b/dumps/scripts/516.cs2 @@ -0,0 +1,11 @@ +void script_516() { + if (globalint_52 < 300) { + globalint_52 = add(globalint_52, 1); + } + if ((globalint_51 > 0) && ((boolean)mod(globalint_52, 3))) { + globalint_51 = subtract(globalint_51, 3); + globalint_50 = add(globalint_50, 1); + setWidget3DRotation(0, globalint_50, 0, 0, 0, globalint_51, new WidgetPointer(615,0)); + } + return; +} diff --git a/dumps/scripts/5160.cs2 b/dumps/scripts/5160.cs2 new file mode 100644 index 0000000..fea5838 --- /dev/null +++ b/dumps/scripts/5160.cs2 @@ -0,0 +1,8 @@ +void script_5160(int arg0,int arg1,int arg2,int arg3,int arg4) { + if ((globalint_1592 != arg3) || (globalint_1593 != arg4)) { + globalint_1592 = arg3; + globalint_1593 = arg4; + script_5161(arg0, arg1, arg2, arg3, arg4); + } + return; +} diff --git a/dumps/scripts/5161.cs2 b/dumps/scripts/5161.cs2 new file mode 100644 index 0000000..3e3a892 --- /dev/null +++ b/dumps/scripts/5161.cs2 @@ -0,0 +1,11 @@ +void script_5161(int arg0,int arg1,int arg2,int arg3,int arg4) { + int ivar5; + int ivar6; + ivar5 = getWidgetActualHeight(new WidgetPointer(arg1)); + ivar6 = divide(multiply(subtract(ivar5, arg4), 64), ivar5); + setWidgetRGB(new Color(ivar6), new WidgetPointer(arg0)); + bitconfig_9642 = mod(ivar6, 64); + script_5168(arg4); + setWidgetRGB(new Color(getColorRelatedMethod4020(standart_config_2347)), new WidgetPointer(arg2)); + return; +} diff --git a/dumps/scripts/5162.cs2 b/dumps/scripts/5162.cs2 new file mode 100644 index 0000000..a6c6389 --- /dev/null +++ b/dumps/scripts/5162.cs2 @@ -0,0 +1,6 @@ +void script_5162(int arg0,int arg1,int arg2,int arg3,int arg4) { + globalint_1592 = arg3; + globalint_1593 = arg4; + script_5164(arg0, arg1, arg2, arg3, arg4); + return; +} diff --git a/dumps/scripts/5163.cs2 b/dumps/scripts/5163.cs2 new file mode 100644 index 0000000..c189a45 --- /dev/null +++ b/dumps/scripts/5163.cs2 @@ -0,0 +1,8 @@ +void script_5163(int arg0,int arg1,int arg2,int arg3,int arg4) { + if ((globalint_1592 != arg3) || (globalint_1593 != arg4)) { + globalint_1592 = arg3; + globalint_1593 = arg4; + script_5164(arg0, arg1, arg2, arg3, arg4); + } + return; +} diff --git a/dumps/scripts/5164.cs2 b/dumps/scripts/5164.cs2 new file mode 100644 index 0000000..53d586c --- /dev/null +++ b/dumps/scripts/5164.cs2 @@ -0,0 +1,13 @@ +void script_5164(int arg0,int arg1,int arg2,int arg3,int arg4) { + int ivar5; + int ivar6; + int ivar7; + ivar5 = getWidgetActualHeight(new WidgetPointer(arg0)); + ivar6 = divide(multiply(subtract(ivar5, arg4), 8), ivar5); + ivar7 = divide(multiply(arg3, 128), getWidgetActualWidth(new WidgetPointer(arg0))); + bitconfig_9643 = mod(ivar6, 8); + bitconfig_9644 = mod(ivar7, 128); + script_5167(arg3, arg4); + setWidgetRGB(new Color(getColorRelatedMethod4020(standart_config_2347)), new WidgetPointer(arg2)); + return; +} diff --git a/dumps/scripts/5165.cs2 b/dumps/scripts/5165.cs2 new file mode 100644 index 0000000..75409e2 --- /dev/null +++ b/dumps/scripts/5165.cs2 @@ -0,0 +1,5 @@ +void script_5165() { + standart_config_2347 = max(0, min(standart_config_2347, 65535)); + sendColorPickerPacket(standart_config_2347); + return; +} diff --git a/dumps/scripts/5166.cs2 b/dumps/scripts/5166.cs2 new file mode 100644 index 0000000..b9b7146 --- /dev/null +++ b/dumps/scripts/5166.cs2 @@ -0,0 +1,5 @@ +void script_5166() { + globalint_1591 = max(0, min(globalint_1591, 65535)); + sendColorPickerPacket(globalint_1591); + return; +} diff --git a/dumps/scripts/5167.cs2 b/dumps/scripts/5167.cs2 new file mode 100644 index 0000000..cea2135 --- /dev/null +++ b/dumps/scripts/5167.cs2 @@ -0,0 +1,4 @@ +void script_5167(int arg0,int arg1) { + setWidgetPosition(arg0, arg1, 0, 0, new WidgetPointer(1106,20)); + return; +} diff --git a/dumps/scripts/5168.cs2 b/dumps/scripts/5168.cs2 new file mode 100644 index 0000000..6d61ebc --- /dev/null +++ b/dumps/scripts/5168.cs2 @@ -0,0 +1,4 @@ +void script_5168(int arg0) { + setWidgetPosition(0, add(arg0, 1), 0, 0, new WidgetPointer(1106,19)); + return; +} diff --git a/dumps/scripts/5169.cs2 b/dumps/scripts/5169.cs2 new file mode 100644 index 0000000..cb9e255 --- /dev/null +++ b/dumps/scripts/5169.cs2 @@ -0,0 +1,175 @@ +int script_5169(int arg0) { + int ivar1; + int ivar2; + int ivar3; + ivar1 = 0; + ivar2 = 0; + ivar3 = 1; + if (citadelConfigsInitialized()) { + ivar1 = script_4948(arg0); + if (ivar1 <= 0) { + return 0; + } + ivar2 = script_4959(ivar1); + if (((boolean)ivar2)) { + return 0; + } + switch (ivar1) { + case 1: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 2: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 3: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 4: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 5: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 6: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 7: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 8: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 9: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 10: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 11: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 12: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 13: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 14: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 15: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + if (ivar3 > 0) { + return 1; + } + return 0; + } + return 0; +} diff --git a/dumps/scripts/517.cs2 b/dumps/scripts/517.cs2 new file mode 100644 index 0000000..aa94374 --- /dev/null +++ b/dumps/scripts/517.cs2 @@ -0,0 +1,23 @@ +void script_517() { + int ivar0; + string svar0; + svar0 = "" + "Lots!"; + if ((standart_config_1801 >= -1) && (standart_config_1801 < 2147483647)) { + svar0 = formatNumber(divide(standart_config_1801, 10), 1); + } + ivar0 = getTextWidth(495, svar0); + setWidgetSize(max(add(ivar0, 38), 90), 106, 0, 0, new WidgetPointer(548,22)); + setWidgetSize(max(add(ivar0, 40), 90), 106, 0, 0, new WidgetPointer(746,184)); + setWidgetText(new WidgetPointer(746,201), svar0); + setWidgetText(new WidgetPointer(548,38), svar0); + if (((boolean)getLanguage())) { + setWidgetSprite(3066, new WidgetPointer(548,25)); + setWidgetSprite(3066, new WidgetPointer(746,188)); + } + if (((boolean)globalint_1602)) { + } else { + script_3367(); + } + script_3337(); + return; +} diff --git a/dumps/scripts/5170.cs2 b/dumps/scripts/5170.cs2 new file mode 100644 index 0000000..b199d81 --- /dev/null +++ b/dumps/scripts/5170.cs2 @@ -0,0 +1,19 @@ +void script_5170() { + setWidgetIsHidden(false, new WidgetPointer(1092,184)); + setWidgetIsHidden(false, new WidgetPointer(1092,185)); + setWidgetIsHidden(false, new WidgetPointer(1092,186)); + setWidgetIsHidden(false, new WidgetPointer(1092,187)); + setWidgetIsHidden(false, new WidgetPointer(1092,188)); + setWidgetIsHidden(false, new WidgetPointer(1092,189)); + setWidgetIsHidden(false, new WidgetPointer(1092,190)); + setWidgetIsHidden(false, new WidgetPointer(1092,191)); + setWidgetIsHidden(false, new WidgetPointer(1092,192)); + setWidgetIsHidden(false, new WidgetPointer(1092,193)); + setWidgetIsHidden(false, new WidgetPointer(1092,194)); + setWidgetIsHidden(false, new WidgetPointer(1092,195)); + setWidgetIsHidden(false, new WidgetPointer(1092,186)); + setWidgetIsHidden(false, new WidgetPointer(1092,213)); + setWidgetIsHidden(false, new WidgetPointer(1092,214)); + setWidgetIsHidden(false, new WidgetPointer(1092,215)); + return; +} diff --git a/dumps/scripts/5171.cs2 b/dumps/scripts/5171.cs2 new file mode 100644 index 0000000..47b44d4 --- /dev/null +++ b/dumps/scripts/5171.cs2 @@ -0,0 +1,351 @@ +int script_5171(int arg0) { + int ivar1; + int ivar2; + int ivar3; + ivar1 = script_4827(arg0); + if (ivar1 == -1) { + return -1; + } + ivar2 = -1; + ivar3 = 0; + switch (arg0) { + case 21: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 22: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 23: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 24: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 25: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 26: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 27: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 28: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 31: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 32: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 33: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 34: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 35: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 41: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 42: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 43: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 44: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 45: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 51: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 100: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 101: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 102: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 103: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 104: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 105: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 106: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 107: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 108: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 109: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 110: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 111: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 112: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 113: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:107 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + if (ivar3 <= 0) { + return -1; + } + if (ivar1 == -1) { + return -1; + } + ivar2 = cs2method_3408(105, 100, ivar1, ivar3); + return ivar2; +} diff --git a/dumps/scripts/5172.cs2 b/dumps/scripts/5172.cs2 new file mode 100644 index 0000000..b9ef3b4 --- /dev/null +++ b/dumps/scripts/5172.cs2 @@ -0,0 +1,26 @@ +cs2func_script_5172_struct(2,0,0) script_5172() { + int ivar0; + ivar0 = add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(add(bitconfig_4949, bitconfig_4950), bitconfig_4951), bitconfig_4952), bitconfig_4953), bitconfig_4954), bitconfig_4955), bitconfig_4956), bitconfig_4957), bitconfig_4958), bitconfig_4959), bitconfig_4960), bitconfig_4961), bitconfig_4962), bitconfig_4963), bitconfig_4964), bitconfig_4965), bitconfig_4966), bitconfig_4967), bitconfig_4968), bitconfig_4969), bitconfig_4970), bitconfig_4971), bitconfig_4972), bitconfig_4973), bitconfig_4974), bitconfig_4975), bitconfig_4976), bitconfig_4977), bitconfig_4978), bitconfig_4979), bitconfig_4980), bitconfig_4981), bitconfig_4982), bitconfig_4983), bitconfig_4984), bitconfig_4985), bitconfig_4986), bitconfig_4987), bitconfig_4988), bitconfig_4989), bitconfig_4991), bitconfig_4992), bitconfig_4993), bitconfig_4994), bitconfig_4995), bitconfig_4996), bitconfig_4997), bitconfig_4998), bitconfig_4999), bitconfig_5998), bitconfig_5001), bitconfig_5002), bitconfig_5003), bitconfig_8180), bitconfig_8181), bitconfig_8188), bitconfig_8191), bitconfig_8192), bitconfig_8193), bitconfig_8194), bitconfig_8517), bitconfig_8518), bitconfig_8519), bitconfig_8520), bitconfig_8521), bitconfig_8522), bitconfig_8523), bitconfig_8524), bitconfig_8525), bitconfig_8526), bitconfig_8527), bitconfig_8528), bitconfig_8529), bitconfig_8530), bitconfig_8531), bitconfig_8532), bitconfig_8533), bitconfig_8534), bitconfig_8535), bitconfig_8536), bitconfig_8537), bitconfig_8538), bitconfig_8539), bitconfig_8540), bitconfig_8541), bitconfig_8542), bitconfig_8543), bitconfig_8544), bitconfig_8545), bitconfig_8546), bitconfig_8547), bitconfig_8548), bitconfig_8549), bitconfig_8550), bitconfig_8551), bitconfig_8552), bitconfig_8553), bitconfig_8554), bitconfig_8555), bitconfig_8556), bitconfig_8557), bitconfig_8558), bitconfig_8559), bitconfig_8560), bitconfig_8561), bitconfig_8562), bitconfig_8563), bitconfig_8564), bitconfig_8565), bitconfig_8566), bitconfig_8567), bitconfig_8568), bitconfig_8569), bitconfig_8570), bitconfig_8571), bitconfig_8572), bitconfig_8573), bitconfig_8574), bitconfig_8781), bitconfig_9010), bitconfig_9015), bitconfig_9016), bitconfig_9018), bitconfig_9019), bitconfig_9027); + if (bitconfig_9011 == 3) { + ivar0 = add(ivar0, 1); + } + if (bitconfig_9013 == 3) { + ivar0 = add(ivar0, 1); + } + if (bitconfig_7238 == 60) { + ivar0 = add(ivar0, 1); + } + if (standart_config_107 == 5) { + ivar0 = add(ivar0, 1); + } + if (bitconfig_5733 > 59) { + ivar0 = add(ivar0, 1); + } + if (standart_config_63 == 6) { + ivar0 = add(ivar0, 1); + } + if (standart_config_29 == 2) { + ivar0 = add(ivar0, 1); + } + return newstruct cs2func_script_5172_struct(ivar0, 133); +} diff --git a/dumps/scripts/5173.cs2 b/dumps/scripts/5173.cs2 new file mode 100644 index 0000000..fd6d365 --- /dev/null +++ b/dumps/scripts/5173.cs2 @@ -0,0 +1,13 @@ +cs2func_script_5173_struct(2,0,0) script_5173() { + int ivar0; + int ivar1; + int stack_dump0; + cs2func_script_5175_struct(2,0,0) structdump_1; + ivar0 = 0; + ivar1 = 0; + stack_dump0 = 2; + structdump_1 = script_5175(stack_dump0); + ivar1 = structdump_1.intpart_1; + ivar0 = structdump_1.intpart_0; + return newstruct cs2func_script_5173_struct(ivar0, ivar1); +} diff --git a/dumps/scripts/5174.cs2 b/dumps/scripts/5174.cs2 new file mode 100644 index 0000000..7e31c9b --- /dev/null +++ b/dumps/scripts/5174.cs2 @@ -0,0 +1,13 @@ +cs2func_script_5174_struct(2,0,0) script_5174() { + int ivar0; + int ivar1; + int stack_dump0; + cs2func_script_5175_struct(2,0,0) structdump_1; + ivar0 = 0; + ivar1 = 0; + stack_dump0 = 3; + structdump_1 = script_5175(stack_dump0); + ivar1 = structdump_1.intpart_1; + ivar0 = structdump_1.intpart_0; + return newstruct cs2func_script_5174_struct(ivar0, ivar1); +} diff --git a/dumps/scripts/5175.cs2 b/dumps/scripts/5175.cs2 new file mode 100644 index 0000000..6e1d5a9 --- /dev/null +++ b/dumps/scripts/5175.cs2 @@ -0,0 +1,21 @@ +cs2func_script_5175_struct(2,0,0) script_5175(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + ivar4 = -1; + while (ivar1 <= 428) { + ivar4 = cs2method_3408(105, 74, 3483, ivar1); + if ((getOtherCommonData(ivar4, 1267) == arg0) && ((boolean)getOtherCommonData(ivar4, 1322))) { + ivar3 = add(ivar3, 1); + if (script_3227(ivar1) == 2) { + ivar2 = add(ivar2, 1); + } + } + ivar1 = add(ivar1, 1); + } + return newstruct cs2func_script_5175_struct(ivar2, ivar3); +} diff --git a/dumps/scripts/5176.cs2 b/dumps/scripts/5176.cs2 new file mode 100644 index 0000000..fbd0260 --- /dev/null +++ b/dumps/scripts/5176.cs2 @@ -0,0 +1,294 @@ +void script_5176() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + int ivar22; + int ivar23; + int ivar24; + int ivar25; + int ivar26; + int ivar27; + ivar0 = -1; + ivar1 = 60; + ivar2 = 120; + ivar3 = 34; + ivar4 = 60; + ivar5 = 10; + ivar6 = 6; + ivar7 = 60; + ivar8 = 60; + ivar9 = ivar6; + ivar10 = 0; + ivar11 = -1; + ivar12 = -1; + ivar13 = subtract(ivar3, 21); + ivar14 = 3; + ivar15 = 0; + ivar16 = 0; + ivar17 = 0; + ivar18 = 5523; + ivar19 = 5524; + ivar20 = 5525; + ivar21 = 5526; + ivar22 = 5527; + ivar23 = -1; + ivar24 = 0; + ivar25 = cs2method_3408(105, 105, 4848, bitconfig_9646); + ivar26 = cs2method_3408(105, 74, 4849, ivar25); + while (ivar26 != -1) { + if (((boolean)getOtherCommonData(ivar26, 1882))) { + createExtraChild(new WidgetPointer(1122,88), 5, ivar10); + setWidgetPosition(ivar9, 0, 0, 0); + setWidgetSize(ivar1, ivar4, 0, 0); + if (ivar25 == globalint_1596) { + ivar23 = ivar21; + } else { + ivar23 = ivar18; + } + setWidgetSprite(ivar23); + setScriptCallOnMouseEntered(688, new WidgetPointer(-32768,3), -2147483643, ivar19, "Iid"); + setScriptCallOnMouseExit(688, new WidgetPointer(-32768,3), -2147483643, ivar23, "Iid"); + setScriptCallOnMousePressed(688, new WidgetPointer(-32768,3), -2147483643, ivar20, "Iid"); + setScriptCallOnMouseReleased(688, new WidgetPointer(-32768,3), -2147483643, ivar23, "Iid"); + setWidgetContextMenuOption(1, "Goal details"); + setScriptCallOnClickContextMenu(5179, ivar25, "i"); + ivar10 = add(ivar10, 1); + createExtraChild(new WidgetPointer(1122,88), 5, ivar10); + setWidgetPosition(ivar9, 0, 0, 0); + setWidgetSprite(getOtherCommonData(ivar26, 1881)); + setWidgetSize(ivar1, ivar4, 0, 0); + ivar9 = add(add(ivar9, ivar1), ivar5); + } else { + ivar12 = ivar10; + createExtraChild(new WidgetPointer(1122,88), 5, ivar10); + setWidgetPosition(ivar9, 0, 0, 0); + setWidgetSize(7, 7, 0, 0); + ivar10 = add(ivar10, 1); + createExtraChild(new WidgetPointer(1122,88), 5, ivar10); + setWidgetPosition(add(ivar9, 7), 0, 0, 0); + setWidgetSize(subtract(ivar2, 14), 7, 0, 0); + ivar10 = add(ivar10, 1); + createExtraChild(new WidgetPointer(1122,88), 5, ivar10); + setWidgetPosition(subtract(add(ivar9, ivar2), 7), 0, 0, 0); + setWidgetSize(7, 7, 0, 0); + setWidgetHFlip(1); + ivar10 = add(ivar10, 1); + createExtraChild(new WidgetPointer(1122,88), 5, ivar10); + setWidgetPosition(ivar9, 7, 0, 0); + setWidgetSize(7, 7, 0, 0); + ivar10 = add(ivar10, 1); + createExtraChild(new WidgetPointer(1122,88), 5, ivar10); + setWidgetPosition(add(ivar9, 7), 7, 0, 0); + setWidgetSize(subtract(ivar2, 14), 7, 0, 0); + ivar10 = add(ivar10, 1); + createExtraChild(new WidgetPointer(1122,88), 5, ivar10); + setWidgetPosition(subtract(add(ivar9, ivar2), 7), 7, 0, 0); + setWidgetSize(7, 7, 0, 0); + setWidgetHFlip(1); + ivar10 = add(ivar10, 1); + createExtraChild(new WidgetPointer(1122,88), 5, ivar10); + setWidgetPosition(ivar9, 14, 0, 0); + setWidgetSize(7, ivar13, 0, 0); + ivar10 = add(ivar10, 1); + createExtraChild(new WidgetPointer(1122,88), 5, ivar10); + setWidgetPosition(add(ivar9, 7), 14, 0, 0); + setWidgetSize(subtract(ivar2, 14), ivar13, 0, 0); + ivar10 = add(ivar10, 1); + createExtraChild(new WidgetPointer(1122,88), 5, ivar10); + setWidgetPosition(subtract(add(ivar9, ivar2), 7), 14, 0, 0); + setWidgetSize(7, ivar13, 0, 0); + setWidgetHFlip(1); + ivar10 = add(ivar10, 1); + createExtraChild(new WidgetPointer(1122,88), 5, ivar10); + setWidgetPosition(ivar9, subtract(ivar3, 7), 0, 0); + setWidgetSize(7, 7, 0, 0); + ivar10 = add(ivar10, 1); + createExtraChild(new WidgetPointer(1122,88), 5, ivar10); + setWidgetPosition(add(ivar9, 7), subtract(ivar3, 7), 0, 0); + setWidgetSize(subtract(ivar2, 14), 7, 0, 0); + ivar10 = add(ivar10, 1); + createExtraChild(new WidgetPointer(1122,88), 5, ivar10); + setWidgetPosition(subtract(add(ivar9, ivar2), 7), subtract(ivar3, 7), 0, 0); + setWidgetSize(7, 7, 0, 0); + setWidgetHFlip(1); + ivar10 = add(ivar10, 1); + createExtraChild(new WidgetPointer(1122,88), 5, ivar10); + setWidgetPosition(add(ivar9, ivar14), ivar3, 0, 0); + setWidgetSize(7, subtract(subtract(ivar4, ivar3), 7), 0, 0); + ivar10 = add(ivar10, 1); + createExtraChild(new WidgetPointer(1122,88), 5, ivar10); + setWidgetPosition(add(add(ivar9, ivar14), 7), ivar3, 0, 0); + setWidgetSize(subtract(subtract(subtract(ivar2, 14), ivar14), ivar14), subtract(subtract(ivar4, ivar3), 7), 0, 0); + ivar10 = add(ivar10, 1); + createExtraChild(new WidgetPointer(1122,88), 5, ivar10); + setWidgetPosition(subtract(subtract(add(ivar9, ivar2), 7), ivar14), ivar3, 0, 0); + setWidgetSize(7, subtract(subtract(ivar4, ivar3), 7), 0, 0); + setWidgetHFlip(1); + ivar10 = add(ivar10, 1); + createExtraChild(new WidgetPointer(1122,88), 5, ivar10); + setWidgetPosition(add(ivar9, ivar14), subtract(ivar4, 7), 0, 0); + setWidgetSize(7, 7, 0, 0); + ivar10 = add(ivar10, 1); + createExtraChild(new WidgetPointer(1122,88), 5, ivar10); + setWidgetPosition(add(add(ivar9, ivar14), 7), subtract(ivar4, 7), 0, 0); + setWidgetSize(subtract(subtract(subtract(ivar2, 14), ivar14), ivar14), 7, 0, 0); + ivar10 = add(ivar10, 1); + createExtraChild(new WidgetPointer(1122,88), 5, ivar10); + setWidgetPosition(subtract(subtract(add(ivar9, ivar2), 7), ivar14), subtract(ivar4, 7), 0, 0); + setWidgetSize(7, 7, 0, 0); + setWidgetHFlip(1); + ivar10 = add(ivar10, 1); + createExtraChild(new WidgetPointer(1122,88), 4, ivar10); + setWidgetPosition(ivar9, 0, 0, 0); + setWidgetSize(ivar2, ivar3, 0, 0); + setWidgetText("Tasks Complete"); + setWidgetTextAlignment(1, 1, 0); + setWidgetRGB(new Color(235, 224, 188)); + setWidgetFont(3793); + ivar10 = add(ivar10, 1); + switch (ivar25) { + case 4: + ivar15 = 56; + if (((boolean)script_5200(ivar25))) { + ivar16 = 56; + } else { + ivar16 = globalint_1594; + } + break; + case 8: + ivar15 = 17; + if (((boolean)script_5200(ivar25))) { + ivar16 = 17; + } else { + ivar16 = globalint_1594; + } + break; + case 12: + ivar15 = 11; + if (((boolean)script_5200(ivar25))) { + ivar16 = 11; + } else { + ivar16 = globalint_1594; + } + } + createExtraChild(new WidgetPointer(1122,88), 5, ivar10); + setWidgetPosition(add(add(ivar9, ivar14), 7), ivar3, 0, 0); + setWidgetSize(subtract(subtract(subtract(ivar2, ivar14), ivar14), 14), subtract(subtract(ivar4, ivar3), 7), 0, 0); + setWidgetSprite(7536); + ivar10 = add(ivar10, 1); + ivar17 = divide(multiply(subtract(subtract(subtract(ivar2, ivar14), ivar14), 14), ivar16), ivar15); + createExtraChild(new WidgetPointer(1122,88), 5, ivar10); + setWidgetPosition(add(add(ivar9, ivar14), 7), ivar3, 0, 0); + setWidgetSize(ivar17, subtract(subtract(ivar4, ivar3), 7), 0, 0); + setWidgetSprite(7540); + ivar10 = add(ivar10, 1); + createExtraChild(new WidgetPointer(1122,88), 4, ivar10); + setWidgetPosition(ivar9, ivar3, 0, 0); + setWidgetSize(ivar2, subtract(subtract(ivar4, ivar3), 7), 0, 0); + setWidgetText(intToStr(ivar16) + " of " + intToStr(ivar15)); + setWidgetTextAlignment(1, 1, 0); + setWidgetRGB(new Color(235, 224, 188)); + setWidgetFont(3793); + ivar10 = add(ivar10, 1); + createExtraChild(new WidgetPointer(1122,88), 3, ivar10); + setWidgetPosition(ivar9, 0, 0, 0); + setWidgetSize(ivar2, ivar4, 0, 0); + setWidgetFilled(1); + setWidgetRGB(new Color(0, 0, 0)); + cs2method2103(255); + if (ivar25 == globalint_1596) { + ivar24 = 4; + } else { + ivar24 = 1; + } + setScriptCallOnMouseEntered(5177, ivar12, 2, "ii"); + setScriptCallOnMouseExit(5177, ivar12, ivar24, "ii"); + setScriptCallOnMousePressed(5177, ivar12, 3, "ii"); + setScriptCallOnMouseReleased(5177, ivar12, ivar24, "ii"); + setWidgetContextMenuOption(1, "Goal details"); + setScriptCallOnClickContextMenu(5179, ivar25, "i"); + ivar9 = add(add(ivar9, ivar2), ivar5); + } + if (((boolean)script_5200(ivar25))) { + ivar10 = add(ivar10, 1); + createExtraChild(new WidgetPointer(1122,88), 5, ivar10); + setWidgetSize(ivar7, ivar8, 0, 0); + setWidgetPosition(subtract(subtract(ivar9, ivar5), ivar7), subtract(ivar4, ivar7), 0, 0); + setWidgetSprite(7465); + } + ivar25 = getOtherCommonData(ivar26, 1878); + ivar26 = cs2method_3408(105, 74, 4849, ivar25); + ivar10 = add(ivar10, 1); + } + ivar25 = 14; + ivar26 = cs2method_3408(105, 74, 4849, ivar25); + while (ivar26 != -1) { + createExtraChild(new WidgetPointer(1122,88), 5, ivar10); + setWidgetSize(ivar1, ivar4, 0, 0); + setWidgetPosition(ivar9, 0, 0, 0); + if (ivar25 == globalint_1596) { + ivar23 = ivar21; + } else { + ivar23 = ivar18; + } + setWidgetSprite(ivar23); + setScriptCallOnMouseEntered(688, new WidgetPointer(-32768,3), -2147483643, ivar19, "Iid"); + setScriptCallOnMouseExit(688, new WidgetPointer(-32768,3), -2147483643, ivar23, "Iid"); + setScriptCallOnMousePressed(688, new WidgetPointer(-32768,3), -2147483643, ivar20, "Iid"); + setScriptCallOnMouseReleased(688, new WidgetPointer(-32768,3), -2147483643, ivar23, "Iid"); + setWidgetContextMenuOption(1, "Goal details"); + if (globalint_1595 > 3) { + setScriptCallOnClickContextMenu(5179, ivar25, "i"); + ivar10 = add(ivar10, 1); + createExtraChild(new WidgetPointer(1122,88), 5, ivar10); + setWidgetSprite(getOtherCommonData(ivar26, 1881)); + setWidgetSize(ivar1, ivar4, 0, 0); + setWidgetPosition(ivar9, 0, 0, 0); + if (((boolean)script_5200(ivar25))) { + ivar10 = add(ivar10, 1); + createExtraChild(new WidgetPointer(1122,88), 5, ivar10); + setWidgetSize(ivar7, ivar8, 0, 0); + setWidgetPosition(subtract(add(ivar9, ivar1), ivar7), subtract(ivar4, ivar7), 0, 0); + setWidgetSprite(7465); + } + } else { + setScriptCallOnClickContextMenu(5179, 13, "i"); + ivar10 = add(ivar10, 1); + createExtraChild(new WidgetPointer(1122,88), 5, ivar10); + setWidgetSprite(7454); + setWidgetSize(ivar1, ivar4, 0, 0); + setWidgetPosition(ivar9, 0, 0, 0); + } + ivar25 = getOtherCommonData(ivar26, 1878); + ivar26 = cs2method_3408(105, 74, 4849, ivar25); + ivar10 = add(ivar10, 1); + ivar9 = add(add(ivar9, ivar1), ivar5); + } + ivar27 = add(subtract(ivar9, ivar5), ivar6); + if (ivar27 > getWidgetActualWidth(new WidgetPointer(1122,88))) { + setWidgetScrollMax(ivar27, getWidgetActualHeight(new WidgetPointer(1122,88)), new WidgetPointer(1122,88)); + cs2method2100(0, 0, new WidgetPointer(1122,88)); + } + script_5182(); + script_5178(ivar12, 1); + return; +} diff --git a/dumps/scripts/5177.cs2 b/dumps/scripts/5177.cs2 new file mode 100644 index 0000000..2698317 --- /dev/null +++ b/dumps/scripts/5177.cs2 @@ -0,0 +1,4 @@ +void script_5177(int arg0,int arg1) { + script_5178(arg0, arg1); + return; +} diff --git a/dumps/scripts/5178.cs2 b/dumps/scripts/5178.cs2 new file mode 100644 index 0000000..46a9c58 --- /dev/null +++ b/dumps/scripts/5178.cs2 @@ -0,0 +1,228 @@ +void script_5178(int arg0,int arg1) { + switch (arg1) { + case 1: + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 0))) { + setWidgetSprite(5528); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 1))) { + setWidgetSprite(5529); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 2))) { + setWidgetSprite(5528); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 3))) { + setWidgetSprite(5538); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 4))) { + setWidgetSprite(5539); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 5))) { + setWidgetSprite(5538); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 6))) { + setWidgetSprite(5548); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 7))) { + setWidgetSprite(5549); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 8))) { + setWidgetSprite(5548); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 9))) { + setWidgetSprite(5558); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 10))) { + setWidgetSprite(5559); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 11))) { + setWidgetSprite(5558); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 12))) { + setWidgetSprite(5552); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 13))) { + setWidgetSprite(5553); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 14))) { + setWidgetSprite(5552); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 15))) { + setWidgetSprite(5562); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 16))) { + setWidgetSprite(5563); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 17))) { + setWidgetSprite(5562); + } + break; + case 2: + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 0))) { + setWidgetSprite(5530); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 1))) { + setWidgetSprite(5531); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 2))) { + setWidgetSprite(5530); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 3))) { + setWidgetSprite(5540); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 4))) { + setWidgetSprite(5541); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 5))) { + setWidgetSprite(5540); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 6))) { + setWidgetSprite(5550); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 7))) { + setWidgetSprite(5551); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 8))) { + setWidgetSprite(5550); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 9))) { + setWidgetSprite(5560); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 10))) { + setWidgetSprite(5561); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 11))) { + setWidgetSprite(5560); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 12))) { + setWidgetSprite(5550); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 13))) { + setWidgetSprite(5551); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 14))) { + setWidgetSprite(5550); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 15))) { + setWidgetSprite(5560); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 16))) { + setWidgetSprite(5561); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 17))) { + setWidgetSprite(5560); + } + break; + case 3: + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 0))) { + setWidgetSprite(5532); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 1))) { + setWidgetSprite(5533); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 2))) { + setWidgetSprite(5532); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 3))) { + setWidgetSprite(5542); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 4))) { + setWidgetSprite(5543); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 5))) { + setWidgetSprite(5542); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 6))) { + setWidgetSprite(5552); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 7))) { + setWidgetSprite(5553); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 8))) { + setWidgetSprite(5552); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 9))) { + setWidgetSprite(5562); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 10))) { + setWidgetSprite(5563); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 11))) { + setWidgetSprite(5562); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 12))) { + setWidgetSprite(5556); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 13))) { + setWidgetSprite(5557); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 14))) { + setWidgetSprite(5556); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 15))) { + setWidgetSprite(5566); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 16))) { + setWidgetSprite(5567); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 17))) { + setWidgetSprite(5566); + } + break; + case 4: + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 0))) { + setWidgetSprite(5534); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 1))) { + setWidgetSprite(5535); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 2))) { + setWidgetSprite(5534); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 3))) { + setWidgetSprite(5544); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 4))) { + setWidgetSprite(5545); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 5))) { + setWidgetSprite(5544); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 6))) { + setWidgetSprite(5554); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 7))) { + setWidgetSprite(5555); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 8))) { + setWidgetSprite(5554); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 9))) { + setWidgetSprite(5564); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 10))) { + setWidgetSprite(5565); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 11))) { + setWidgetSprite(5564); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 12))) { + setWidgetSprite(5554); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 13))) { + setWidgetSprite(5555); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 14))) { + setWidgetSprite(5554); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 15))) { + setWidgetSprite(5564); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 16))) { + setWidgetSprite(5565); + } + if (setWidgetRegister(new WidgetPointer(1122,88), add(arg0, 17))) { + setWidgetSprite(5564); + } + } + return; +} diff --git a/dumps/scripts/5179.cs2 b/dumps/scripts/5179.cs2 new file mode 100644 index 0000000..ed38fd2 --- /dev/null +++ b/dumps/scripts/5179.cs2 @@ -0,0 +1,4 @@ +void script_5179(int arg0) { + script_5180(arg0); + return; +} diff --git a/dumps/scripts/518.cs2 b/dumps/scripts/518.cs2 new file mode 100644 index 0000000..749d53e --- /dev/null +++ b/dumps/scripts/518.cs2 @@ -0,0 +1,5 @@ +void script_518() { + script_1593(globalint_1505); + script_1600(); + return; +} diff --git a/dumps/scripts/5180.cs2 b/dumps/scripts/5180.cs2 new file mode 100644 index 0000000..da8294e --- /dev/null +++ b/dumps/scripts/5180.cs2 @@ -0,0 +1,60 @@ +void script_5180(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + string svar0; + string svar1; + string svar2; + string svar3; + ivar1 = cs2method_3408(105, 74, 4849, arg0); + svar0 = ""; + svar1 = ""; + svar2 = ""; + if (ivar1 == -1) { + svar1 = "Select a goal from the list above."; + if (arg0 > -1) { + return; + } + } else { + svar0 = getOtherCommonData(ivar1, 1879); + svar1 = getOtherCommonData(ivar1, 1880); + if (arg0 != 13) { + if (((boolean)script_5200(arg0))) { + svar2 = "" + "COMPLETED" + ""; + } else { + svar2 = "" + "INCOMPLETE" + ""; + } + } + script_5204(); + } + svar3 = ""; + svar3 = concat("Goal: ", svar0); + if (strLength(svar2) > 0) { + svar3 = concat(svar3, "
" + "Status: "); + svar3 = concat(svar3, svar2); + } + svar3 = concat(svar3, "
"); + svar3 = concat(svar3, svar1); + ivar2 = 10; + ivar3 = 16; + ivar4 = subtract(getWidgetActualWidth(new WidgetPointer(1122,62)), multiply(ivar2, 2)); + ivar5 = getLineCount(ivar4, 495, svar3); + setWidgetTextAlignment(0, 0, ivar3, new WidgetPointer(1122,63)); + ivar6 = multiply(ivar3, ivar5); + setWidgetPosition(ivar2, ivar2, 0, 0, new WidgetPointer(1122,63)); + setWidgetSize(ivar4, ivar6, 0, 0, new WidgetPointer(1122,63)); + setWidgetText(new WidgetPointer(1122,63), svar3); + ivar7 = add(add(ivar6, ivar2), ivar2); + if (ivar7 < getWidgetActualHeight(new WidgetPointer(1122,62))) { + ivar7 = getWidgetActualHeight(new WidgetPointer(1122,62)); + } + setWidgetScrollMax(getWidgetActualWidth(new WidgetPointer(1122,62)), ivar7, new WidgetPointer(1122,62)); + script_31(73531519, 73531454, 5666, 5663, 5664, 5665, 5686, 5685); + globalint_1596 = arg0; + script_5176(); + return; +} diff --git a/dumps/scripts/5181.cs2 b/dumps/scripts/5181.cs2 new file mode 100644 index 0000000..b49c795 --- /dev/null +++ b/dumps/scripts/5181.cs2 @@ -0,0 +1,8 @@ +void script_5181(int arg0) { + if (((boolean)getWidgetScrollMaxH(new WidgetPointer(1122,88)))) { + return; + } + cs2method2100(add(cs2method2600(new WidgetPointer(1122,88)), multiply(8, arg0)), 0, new WidgetPointer(1122,88)); + script_5182(); + return; +} diff --git a/dumps/scripts/5182.cs2 b/dumps/scripts/5182.cs2 new file mode 100644 index 0000000..36f2485 --- /dev/null +++ b/dumps/scripts/5182.cs2 @@ -0,0 +1,16 @@ +void script_5182() { + if (((boolean)getWidgetScrollMaxH(new WidgetPointer(1122,88)))) { + setWidgetIsHidden(false, new WidgetPointer(1122,87)); + setWidgetIsHidden(false, new WidgetPointer(1122,367)); + } else if (((boolean)cs2method2600(new WidgetPointer(1122,88)))) { + setWidgetIsHidden(false, new WidgetPointer(1122,87)); + setWidgetIsHidden(true, new WidgetPointer(1122,367)); + } else if (cs2method2600(new WidgetPointer(1122,88)) == subtract(getWidgetScrollMaxH(new WidgetPointer(1122,88)), getWidgetActualWidth(new WidgetPointer(1122,88)))) { + setWidgetIsHidden(true, new WidgetPointer(1122,87)); + setWidgetIsHidden(false, new WidgetPointer(1122,367)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1122,87)); + setWidgetIsHidden(true, new WidgetPointer(1122,367)); + } + return; +} diff --git a/dumps/scripts/5183.cs2 b/dumps/scripts/5183.cs2 new file mode 100644 index 0000000..edfe34e --- /dev/null +++ b/dumps/scripts/5183.cs2 @@ -0,0 +1,7 @@ +int script_5183(int arg0,int arg1,int arg2,int arg3) { + standart_config_2347 = arg0; + bitconfig_9642 = min(63, max(0, add(bitconfig_9642, arg1))); + bitconfig_9643 = min(7, max(0, add(bitconfig_9643, arg2))); + bitconfig_9644 = min(127, max(0, add(bitconfig_9644, arg3))); + return standart_config_2347; +} diff --git a/dumps/scripts/5184.cs2 b/dumps/scripts/5184.cs2 new file mode 100644 index 0000000..44dfc78 --- /dev/null +++ b/dumps/scripts/5184.cs2 @@ -0,0 +1,15 @@ +void script_5184() { + script_5192(); + script_5190(1, 0); + switch (bitconfig_9646) { + case 1: + setWidgetText(new WidgetPointer(1122,71), "Lumbridge herald cape"); + break; + case 2: + setWidgetText(new WidgetPointer(1122,71), "Varrock herald cape"); + break; + case 3: + setWidgetText(new WidgetPointer(1122,71), "Falador herald cape"); + } + return; +} diff --git a/dumps/scripts/5185.cs2 b/dumps/scripts/5185.cs2 new file mode 100644 index 0000000..a5009d4 --- /dev/null +++ b/dumps/scripts/5185.cs2 @@ -0,0 +1,4 @@ +void script_5185() { + script_5186(); + return; +} diff --git a/dumps/scripts/5186.cs2 b/dumps/scripts/5186.cs2 new file mode 100644 index 0000000..5ea6bdb --- /dev/null +++ b/dumps/scripts/5186.cs2 @@ -0,0 +1,8 @@ +void script_5186() { + setWidgetIsHidden(true, new WidgetPointer(1122,72)); + setWidgetIsHidden(false, new WidgetPointer(1122,77)); + setWidgetIsHidden(false, new WidgetPointer(1122,73)); + setWidgetIsHidden(true, new WidgetPointer(1122,192)); + setWidgetIsHidden(false, new WidgetPointer(1122,46)); + return; +} diff --git a/dumps/scripts/5187.cs2 b/dumps/scripts/5187.cs2 new file mode 100644 index 0000000..5ef6c85 --- /dev/null +++ b/dumps/scripts/5187.cs2 @@ -0,0 +1,4 @@ +void script_5187() { + script_5188(); + return; +} diff --git a/dumps/scripts/5188.cs2 b/dumps/scripts/5188.cs2 new file mode 100644 index 0000000..1ab7537 --- /dev/null +++ b/dumps/scripts/5188.cs2 @@ -0,0 +1,8 @@ +void script_5188() { + setWidgetIsHidden(false, new WidgetPointer(1122,72)); + setWidgetIsHidden(true, new WidgetPointer(1122,77)); + setWidgetIsHidden(true, new WidgetPointer(1122,73)); + setWidgetIsHidden(false, new WidgetPointer(1122,192)); + setWidgetIsHidden(true, new WidgetPointer(1122,46)); + return; +} diff --git a/dumps/scripts/5189.cs2 b/dumps/scripts/5189.cs2 new file mode 100644 index 0000000..47ea920 --- /dev/null +++ b/dumps/scripts/5189.cs2 @@ -0,0 +1,5 @@ +void script_5189(int arg0,int arg1) { + script_5186(); + script_5190(arg0, arg1); + return; +} diff --git a/dumps/scripts/519.cs2 b/dumps/scripts/519.cs2 new file mode 100644 index 0000000..e376d1c --- /dev/null +++ b/dumps/scripts/519.cs2 @@ -0,0 +1,24 @@ +int script_519() { + int ivar0; + ivar0 = 0; + ivar0 = add(ivar0, bitconfig_3579); + ivar0 = add(ivar0, bitconfig_3580); + ivar0 = add(ivar0, bitconfig_3581); + ivar0 = add(ivar0, bitconfig_3582); + ivar0 = add(ivar0, bitconfig_3583); + ivar0 = add(ivar0, bitconfig_3584); + ivar0 = add(ivar0, bitconfig_3585); + ivar0 = add(ivar0, bitconfig_3586); + ivar0 = add(ivar0, bitconfig_3587); + ivar0 = add(ivar0, bitconfig_3588); + ivar0 = add(ivar0, bitconfig_3589); + ivar0 = add(ivar0, bitconfig_3590); + ivar0 = add(ivar0, bitconfig_3591); + ivar0 = add(ivar0, bitconfig_3592); + ivar0 = add(ivar0, bitconfig_3593); + ivar0 = add(ivar0, bitconfig_3594); + ivar0 = add(ivar0, bitconfig_3595); + ivar0 = add(ivar0, bitconfig_3597); + ivar0 = add(ivar0, bitconfig_3596); + return ivar0; +} diff --git a/dumps/scripts/5190.cs2 b/dumps/scripts/5190.cs2 new file mode 100644 index 0000000..292a168 --- /dev/null +++ b/dumps/scripts/5190.cs2 @@ -0,0 +1,17 @@ +void script_5190(int arg0,int arg1) { + int ivar2; + int ivar3; + ivar2 = 25; + ivar3 = multiply(getWidgetActualWidth(new WidgetPointer(1122,73)), arg0); + if (((boolean)arg1)) { + cs2method2100(ivar3, 0, new WidgetPointer(1122,74)); + setWidgetIsHidden(true, new WidgetPointer(1122,75)); + return; + } + setWidgetIsHidden(false, new WidgetPointer(1122,75)); + if (ivar3 < cs2method2600(new WidgetPointer(1122,74))) { + ivar2 = subtract(0, ivar2); + } + setScriptCallOnGameloop(5191, ivar3, ivar2, "ii", new WidgetPointer(1122,74)); + return; +} diff --git a/dumps/scripts/5191.cs2 b/dumps/scripts/5191.cs2 new file mode 100644 index 0000000..8df979b --- /dev/null +++ b/dumps/scripts/5191.cs2 @@ -0,0 +1,20 @@ +void script_5191(int arg0,int arg1) { + flow_0: + cs2method2100(add(cs2method2600(new WidgetPointer(1122,74)), arg1), 0, new WidgetPointer(1122,74)); + IF (arg1 < 0) + GOTO flow_1 + GOTO flow_2 + flow_1: + IF (cs2method2600(new WidgetPointer(1122,74)) <= arg0) + GOTO flow_4 + flow_2: + IF ((arg1 > 0) && (cs2method2600(new WidgetPointer(1122,74)) >= arg0)) + GOTO flow_4 + GOTO flow_5 + flow_4: + cs2method2100(arg0, 0, new WidgetPointer(1122,74)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(1122,74)); + setWidgetIsHidden(true, new WidgetPointer(1122,75)); + flow_5: + return; +} diff --git a/dumps/scripts/5192.cs2 b/dumps/scripts/5192.cs2 new file mode 100644 index 0000000..3f53d8e --- /dev/null +++ b/dumps/scripts/5192.cs2 @@ -0,0 +1,10 @@ +void script_5192() { + globalint_1595 = script_5193(); + globalint_1594 = script_5194(); + globalint_1596 = -1; + script_5176(); + script_5195(); + script_5196(); + script_5180(-1); + return; +} diff --git a/dumps/scripts/5193.cs2 b/dumps/scripts/5193.cs2 new file mode 100644 index 0000000..92cb4a0 --- /dev/null +++ b/dumps/scripts/5193.cs2 @@ -0,0 +1,11 @@ +int script_5193() { + switch (bitconfig_9646) { + case 1: + return bitconfig_9647; + case 2: + return bitconfig_9648; + case 3: + return bitconfig_9649; + } + return -1; +} diff --git a/dumps/scripts/5194.cs2 b/dumps/scripts/5194.cs2 new file mode 100644 index 0000000..47ff242 --- /dev/null +++ b/dumps/scripts/5194.cs2 @@ -0,0 +1,26 @@ +int script_5194() { + int ivar0; + int ivar1; + cs2func_script_5172_struct(2,0,0) structdump_0; + cs2func_script_5173_struct(2,0,0) structdump_1; + cs2func_script_5174_struct(2,0,0) structdump_2; + ivar0 = -1; + ivar1 = -1; + switch (bitconfig_9646) { + case 1: + structdump_0 = script_5172(); + ivar1 = structdump_0.intpart_1; + ivar0 = structdump_0.intpart_0; + break; + case 2: + structdump_1 = script_5173(); + ivar1 = structdump_1.intpart_1; + ivar0 = structdump_1.intpart_0; + break; + case 3: + structdump_2 = script_5174(); + ivar1 = structdump_2.intpart_1; + ivar0 = structdump_2.intpart_0; + } + return ivar0; +} diff --git a/dumps/scripts/5195.cs2 b/dumps/scripts/5195.cs2 new file mode 100644 index 0000000..515596a --- /dev/null +++ b/dumps/scripts/5195.cs2 @@ -0,0 +1,58 @@ +void script_5195() { + setWidgetIsHidden(true, new WidgetPointer(1122,67)); + setWidgetIsHidden(true, new WidgetPointer(1122,168)); + setWidgetIsHidden(true, new WidgetPointer(1122,169)); + setWidgetIsHidden(true, new WidgetPointer(1122,170)); + setWidgetRGB(new Color(181, 157, 105), new WidgetPointer(1122,69)); + setWidgetRGB(new Color(120, 102, 75), new WidgetPointer(1122,155)); + setWidgetRGB(new Color(120, 102, 75), new WidgetPointer(1122,159)); + setWidgetRGB(new Color(120, 102, 75), new WidgetPointer(1122,163)); + setWidgetRGB(new Color(120, 102, 75), new WidgetPointer(1122,167)); + setWidgetSprite(7653, new WidgetPointer(1122,31)); + setWidgetSprite(7652, new WidgetPointer(1122,153)); + setWidgetSprite(7652, new WidgetPointer(1122,157)); + setWidgetSprite(7652, new WidgetPointer(1122,161)); + setWidgetSprite(7652, new WidgetPointer(1122,165)); + setWidgetIsHidden(true, new WidgetPointer(1122,32)); + setWidgetIsHidden(true, new WidgetPointer(1122,154)); + setWidgetIsHidden(true, new WidgetPointer(1122,158)); + setWidgetIsHidden(true, new WidgetPointer(1122,162)); + setWidgetIsHidden(true, new WidgetPointer(1122,166)); + if (globalint_1595 >= 1) { + setWidgetIsHidden(false, new WidgetPointer(1122,67)); + setWidgetSprite(7653, new WidgetPointer(1122,153)); + setWidgetRGB(new Color(181, 157, 105), new WidgetPointer(1122,155)); + } + if (globalint_1595 >= 2) { + setWidgetIsHidden(false, new WidgetPointer(1122,168)); + setWidgetSprite(7653, new WidgetPointer(1122,157)); + setWidgetRGB(new Color(181, 157, 105), new WidgetPointer(1122,159)); + } + if (globalint_1595 >= 3) { + setWidgetIsHidden(false, new WidgetPointer(1122,169)); + setWidgetSprite(7653, new WidgetPointer(1122,161)); + setWidgetRGB(new Color(181, 157, 105), new WidgetPointer(1122,163)); + } + if (globalint_1595 >= 4) { + setWidgetIsHidden(false, new WidgetPointer(1122,170)); + setWidgetSprite(7653, new WidgetPointer(1122,165)); + setWidgetRGB(new Color(181, 157, 105), new WidgetPointer(1122,167)); + } + switch (globalint_1595) { + case 0: + setWidgetIsHidden(false, new WidgetPointer(1122,32)); + break; + case 1: + setWidgetIsHidden(false, new WidgetPointer(1122,154)); + break; + case 2: + setWidgetIsHidden(false, new WidgetPointer(1122,158)); + break; + case 3: + setWidgetIsHidden(false, new WidgetPointer(1122,162)); + break; + case 4: + setWidgetIsHidden(false, new WidgetPointer(1122,166)); + } + return; +} diff --git a/dumps/scripts/5196.cs2 b/dumps/scripts/5196.cs2 new file mode 100644 index 0000000..9db5fad --- /dev/null +++ b/dumps/scripts/5196.cs2 @@ -0,0 +1,28 @@ +void script_5196() { + setWidgetIsHidden(true, new WidgetPointer(1122,61)); + setWidgetIsHidden(true, new WidgetPointer(1122,252)); + setWidgetIsHidden(true, new WidgetPointer(1122,264)); + setWidgetIsHidden(true, new WidgetPointer(1122,276)); + setWidgetIsHidden(true, new WidgetPointer(1122,288)); + setWidgetIsHidden(true, new WidgetPointer(1122,233)); + setWidgetIsHidden(true, new WidgetPointer(1122,242)); + setWidgetIsHidden(true, new WidgetPointer(1122,357)); + setWidgetIsHidden(false, new WidgetPointer(1122,79)); + if (globalint_1595 < 4) { + setWidgetIsHidden(false, new WidgetPointer(1122,288)); + setWidgetIsHidden(false, new WidgetPointer(1122,242)); + } + if (globalint_1595 < 3) { + setWidgetIsHidden(false, new WidgetPointer(1122,276)); + setWidgetIsHidden(false, new WidgetPointer(1122,357)); + } + if (globalint_1595 < 2) { + setWidgetIsHidden(false, new WidgetPointer(1122,264)); + setWidgetIsHidden(false, new WidgetPointer(1122,233)); + setWidgetIsHidden(true, new WidgetPointer(1122,79)); + } + if (globalint_1595 < 1) { + setWidgetIsHidden(false, new WidgetPointer(1122,252)); + } + return; +} diff --git a/dumps/scripts/5197.cs2 b/dumps/scripts/5197.cs2 new file mode 100644 index 0000000..b49e0b0 --- /dev/null +++ b/dumps/scripts/5197.cs2 @@ -0,0 +1,17 @@ +void script_5197(int arg0,int arg1,int arg2) { + if (((boolean)arg2)) { + setWidgetIsHidden(true, new WidgetPointer(1122,57)); + setWidgetIsHidden(true, new WidgetPointer(1122,248)); + setWidgetIsHidden(true, new WidgetPointer(1122,260)); + setWidgetIsHidden(true, new WidgetPointer(1122,272)); + setWidgetIsHidden(true, new WidgetPointer(1122,284)); + setWidgetIsHidden(false, new WidgetPointer(arg0)); + } else if (arg1 == bitconfig_9674) { + setWidgetIsHidden(false, new WidgetPointer(arg0)); + } else { + setWidgetIsHidden(true, new WidgetPointer(arg0)); + } + globalint_1600 = arg1; + script_5202(1); + return; +} diff --git a/dumps/scripts/5198.cs2 b/dumps/scripts/5198.cs2 new file mode 100644 index 0000000..70f164f --- /dev/null +++ b/dumps/scripts/5198.cs2 @@ -0,0 +1,13 @@ +void script_5198() { + setWidgetRGB(new Color(getColorRelatedMethod4020(bitconfig_9671)), new WidgetPointer(1122,111)); + setWidgetRGB(new Color(getColorRelatedMethod4020(bitconfig_9672)), new WidgetPointer(1122,118)); + setWidgetRGB(new Color(getColorRelatedMethod4020(bitconfig_9673)), new WidgetPointer(1122,120)); + setWidgetRGB(new Color(getColorRelatedMethod4020(bitconfig_9672)), new WidgetPointer(1122,313)); + setWidgetRGB(new Color(getColorRelatedMethod4020(bitconfig_9671)), new WidgetPointer(1122,320)); + setWidgetRGB(new Color(getColorRelatedMethod4020(bitconfig_9673)), new WidgetPointer(1122,322)); + setWidgetRGB(new Color(getColorRelatedMethod4020(bitconfig_9673)), new WidgetPointer(1122,341)); + setWidgetRGB(new Color(getColorRelatedMethod4020(bitconfig_9673)), new WidgetPointer(1122,359)); + setWidgetRGB(new Color(getColorRelatedMethod4020(bitconfig_9671)), new WidgetPointer(1122,348)); + setWidgetRGB(new Color(getColorRelatedMethod4020(bitconfig_9672)), new WidgetPointer(1122,350)); + return; +} diff --git a/dumps/scripts/5199.cs2 b/dumps/scripts/5199.cs2 new file mode 100644 index 0000000..1800c93 --- /dev/null +++ b/dumps/scripts/5199.cs2 @@ -0,0 +1,6 @@ +void script_5199(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + setWidgetSprite(arg1, new WidgetPointer(arg0)); + setWidgetSprite(arg3, new WidgetPointer(arg2)); + setWidgetSprite(arg5, new WidgetPointer(arg4)); + return; +} diff --git a/dumps/scripts/52.cs2 b/dumps/scripts/52.cs2 new file mode 100644 index 0000000..5c08405 --- /dev/null +++ b/dumps/scripts/52.cs2 @@ -0,0 +1,10 @@ +void script_52(int arg0,int arg1,int arg2,int arg3,int arg4) { + if (setWidgetRegister(new WidgetPointer(arg3), arg4)) { + if (getSkillActualLvl(5) < arg0) { + setWidgetSprite(arg1); + } else { + setWidgetSprite(arg2); + } + } + return; +} diff --git a/dumps/scripts/520.cs2 b/dumps/scripts/520.cs2 new file mode 100644 index 0000000..2dbc237 --- /dev/null +++ b/dumps/scripts/520.cs2 @@ -0,0 +1,32 @@ +void script_520(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + ivar4 = divide(add(arg1, arg2), 2); + ivar5 = globalarray_0[ivar4]; + globalarray_0[ivar4] = globalarray_0[arg2]; + globalarray_0[arg2] = ivar5; + ivar6 = arg1; + ivar7 = arg1; + ivar8 = -1; + while (ivar7 < arg2) { + if (stringMethod4107(lower(cs2method_3408(105, 115, arg3, globalarray_0[ivar7])), lower(cs2method_3408(105, 115, arg3, ivar5))) < bitAnd(ivar7, 1)) { + ivar8 = globalarray_0[ivar7]; + globalarray_0[ivar7] = globalarray_0[ivar6]; + globalarray_0[ivar6] = ivar8; + ivar6 = add(ivar6, 1); + } + ivar7 = add(ivar7, 1); + } + globalarray_0[arg2] = globalarray_0[ivar6]; + globalarray_0[ivar6] = ivar5; + if (arg1 < subtract(ivar6, 1)) { + script_520(0, arg1, subtract(ivar6, 1), arg3); + } + if (add(ivar6, 1) < arg2) { + script_520(0, add(ivar6, 1), arg2, arg3); + } + return; +} diff --git a/dumps/scripts/5200.cs2 b/dumps/scripts/5200.cs2 new file mode 100644 index 0000000..200e4b4 --- /dev/null +++ b/dumps/scripts/5200.cs2 @@ -0,0 +1,70 @@ +int script_5200(int arg0) { + switch (arg0) { + case 1: + if (bitconfig_7238 >= 60) { + return 1; + } + return 0; + case 2: + if (bitconfig_5733 >= 60) { + return 1; + } + return 0; + case 3: + if (bitconfig_6914 >= 3) { + return 1; + } + return 0; + case 4: + if (globalint_1594 >= 56) { + return 1; + } + return 0; + case 5: + if (bitconfig_5730 >= 100) { + return 1; + } + return 0; + case 6: + if ((standart_config_145 >= 7) || (standart_config_146 >= 4)) { + return 1; + } + return 0; + case 7: + if (bitconfig_2561 >= 3) { + return 1; + } + return 0; + case 8: + if (globalint_1594 >= 17) { + return 1; + } + return 0; + case 9: + if (bitconfig_2378 >= 6) { + return 1; + } + return 0; + case 10: + if (standart_config_122 >= 7) { + return 1; + } + return 0; + case 11: + if (standart_config_130 >= 4) { + return 1; + } + return 0; + case 12: + if (globalint_1594 >= 11) { + return 1; + } + return 0; + case 14: + if (standart_config_176 >= 10) { + return 1; + } + return 0; + } + return 0; +} diff --git a/dumps/scripts/5201.cs2 b/dumps/scripts/5201.cs2 new file mode 100644 index 0000000..e67fe9f --- /dev/null +++ b/dumps/scripts/5201.cs2 @@ -0,0 +1,4 @@ +void script_5201() { + script_5202(1); + return; +} diff --git a/dumps/scripts/5202.cs2 b/dumps/scripts/5202.cs2 new file mode 100644 index 0000000..c00eef1 --- /dev/null +++ b/dumps/scripts/5202.cs2 @@ -0,0 +1,59 @@ +void script_5202(int arg0) { + if (((boolean)arg0)) { + globalint_1597 = bitconfig_9671; + globalint_1598 = bitconfig_9672; + globalint_1599 = bitconfig_9673; + globalint_1600 = bitconfig_9674; + globalint_1601 = bitconfig_9675; + } + switch (globalint_1600) { + case 0: + setWidgetModel(43803, new WidgetPointer(1122,80)); + break; + case 1: + setWidgetModel(43796, new WidgetPointer(1122,80)); + break; + case 2: + setWidgetModel(43790, new WidgetPointer(1122,80)); + break; + case 3: + setWidgetModel(43779, new WidgetPointer(1122,80)); + break; + case 4: + setWidgetModel(43795, new WidgetPointer(1122,80)); + } + switch (bitconfig_9646) { + case 1: + doWidgetType19Task(2, 1303, 1298, new WidgetPointer(1122,80)); + break; + case 2: + doWidgetType19Task(2, 1303, 1303, new WidgetPointer(1122,80)); + break; + case 3: + doWidgetType19Task(2, 1303, 1301, new WidgetPointer(1122,80)); + } + switch (globalint_1601) { + case 0: + doWidgetType19Task(1, 1304, 1299, new WidgetPointer(1122,80)); + break; + case 1: + doWidgetType19Task(1, 1304, 1304, new WidgetPointer(1122,80)); + break; + case 2: + doWidgetType19Task(1, 1304, 1300, new WidgetPointer(1122,80)); + break; + case 3: + doWidgetType19Task(1, 1304, 1296, new WidgetPointer(1122,80)); + break; + case 4: + doWidgetType19Task(1, 1304, 1302, new WidgetPointer(1122,80)); + break; + case 5: + doWidgetType19Task(1, 1304, 1297, new WidgetPointer(1122,80)); + } + doWidgetType18Task(0, 41506, globalint_1597, new WidgetPointer(1122,80)); + doWidgetType18Task(1, 41497, script_5183(globalint_1597, 0, 0, -9), new WidgetPointer(1122,80)); + doWidgetType18Task(2, 13434, globalint_1598, new WidgetPointer(1122,80)); + doWidgetType18Task(3, 7102, globalint_1599, new WidgetPointer(1122,80)); + return; +} diff --git a/dumps/scripts/5203.cs2 b/dumps/scripts/5203.cs2 new file mode 100644 index 0000000..c185071 --- /dev/null +++ b/dumps/scripts/5203.cs2 @@ -0,0 +1,4 @@ +void script_5203() { + script_5204(); + return; +} diff --git a/dumps/scripts/5204.cs2 b/dumps/scripts/5204.cs2 new file mode 100644 index 0000000..4a089e4 --- /dev/null +++ b/dumps/scripts/5204.cs2 @@ -0,0 +1,4 @@ +void script_5204() { + playSoundEffect2False(6185, 1, 0, 200, 127); + return; +} diff --git a/dumps/scripts/5205.cs2 b/dumps/scripts/5205.cs2 new file mode 100644 index 0000000..220321d --- /dev/null +++ b/dumps/scripts/5205.cs2 @@ -0,0 +1,4 @@ +void script_5205() { + script_5206(); + return; +} diff --git a/dumps/scripts/5206.cs2 b/dumps/scripts/5206.cs2 new file mode 100644 index 0000000..732136b --- /dev/null +++ b/dumps/scripts/5206.cs2 @@ -0,0 +1,105 @@ +void script_5206() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + ivar0 = 60; + ivar1 = subtract(getWidgetActualWidth(new WidgetPointer(1122,93)), multiply(ivar0, 4)); + ivar2 = divide(ivar1, 5); + ivar3 = add(ivar2, divide(subtract(ivar1, multiply(ivar2, 5)), 2)); + ivar4 = 0; + ivar5 = 0; + ivar6 = 5523; + ivar7 = 5524; + ivar8 = 5525; + ivar9 = 5526; + ivar10 = 5527; + ivar11 = cs2method2600(new WidgetPointer(1122,93)); + ivar12 = cs2method2601(new WidgetPointer(1122,93)); + deleteAllExtraChilds(new WidgetPointer(1122,93)); + ivar13 = 0; + ivar14 = 0; + ivar15 = getCommonDefinitionSize(4850); + ivar16 = -1; + while (ivar13 < ivar15) { + ivar16 = cs2method_3408(105, 74, 4850, ivar13); + if ((ivar13 != 0) && (ivar16 == -1)) { + return; + } + ivar4 = add(ivar3, multiply(mod(ivar13, 4), add(ivar2, ivar0))); + ivar5 = add(ivar2, multiply(divide(ivar13, 4), add(ivar2, ivar0))); + createExtraChild(new WidgetPointer(1122,93), 5, ivar14); + setWidgetPosition(ivar4, ivar5, 0, 0); + setWidgetSize(ivar0, ivar0, 0, 0); + if (bitconfig_9675 == ivar13) { + setWidgetSprite(ivar9); + ivar14 = add(ivar14, 1); + createExtraChild(new WidgetPointer(1122,93), 5, ivar14); + setWidgetPosition(ivar4, ivar5, 0, 0); + setWidgetSize(ivar0, ivar0, 0, 0); + setWidgetSprite(getOtherCommonData(ivar16, 1883)); + ivar14 = add(ivar14, 1); + createExtraChild(new WidgetPointer(1122,93), 5, ivar14); + setWidgetPosition(ivar4, ivar5, 0, 0); + setWidgetSize(ivar0, ivar0, 0, 0); + setWidgetSprite(-1); + } else if (((boolean)getOtherCommonData(ivar16, 1885)) || ((boolean)script_5200(getOtherCommonData(ivar16, 1885)))) { + setWidgetSprite(ivar6); + setScriptCallOnMouseEntered(688, new WidgetPointer(-32768,3), -2147483643, ivar7, "Iid"); + setScriptCallOnMouseExit(688, new WidgetPointer(-32768,3), -2147483643, ivar6, "Iid"); + setScriptCallOnMousePressed(688, new WidgetPointer(-32768,3), -2147483643, ivar8, "Iid"); + setScriptCallOnMouseReleased(688, new WidgetPointer(-32768,3), -2147483643, ivar6, "Iid"); + setWidgetContextMenuOption(1, "Select crest"); + setScriptCallOnClickContextMenu(5207, new WidgetPointer(-32768,3), -2147483643, ivar13, "Iii"); + ivar14 = add(ivar14, 1); + createExtraChild(new WidgetPointer(1122,93), 5, ivar14); + setWidgetPosition(ivar4, ivar5, 0, 0); + setWidgetSize(ivar0, ivar0, 0, 0); + setWidgetSprite(getOtherCommonData(ivar16, 1883)); + ivar14 = add(ivar14, 1); + createExtraChild(new WidgetPointer(1122,93), 5, ivar14); + setWidgetPosition(ivar4, ivar5, 0, 0); + setWidgetSize(ivar0, ivar0, 0, 0); + setWidgetSprite(-1); + } else { + setWidgetSprite(ivar10); + ivar14 = add(ivar14, 1); + createExtraChild(new WidgetPointer(1122,93), 5, ivar14); + setWidgetPosition(ivar4, ivar5, 0, 0); + setWidgetSize(ivar0, ivar0, 0, 0); + setWidgetSprite(getOtherCommonData(ivar16, 1883)); + cs2method2103(196); + ivar14 = add(ivar14, 1); + createExtraChild(new WidgetPointer(1122,93), 5, ivar14); + setWidgetPosition(ivar4, ivar5, 0, 0); + setWidgetSize(ivar0, ivar0, 0, 0); + setWidgetSprite(7454); + } + ivar14 = add(ivar14, 1); + ivar13 = add(ivar13, 1); + } + ivar17 = divide(ivar15, 4); + if (mod(ivar15, 4) != 0) { + ivar17 = add(ivar17, 1); + } + ivar18 = add(multiply(ivar17, add(ivar0, ivar2)), ivar2); + setWidgetScrollMax(getWidgetActualWidth(new WidgetPointer(1122,93)), ivar18, new WidgetPointer(1122,93)); + cs2method2100(ivar11, ivar12, new WidgetPointer(1122,93)); + script_31(73531486, 73531485, 5666, 5663, 5664, 5665, 5686, 5685); + return; +} diff --git a/dumps/scripts/5207.cs2 b/dumps/scripts/5207.cs2 new file mode 100644 index 0000000..bcb81fe --- /dev/null +++ b/dumps/scripts/5207.cs2 @@ -0,0 +1,23 @@ +void script_5207(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + ivar3 = 0; + ivar4 = 5526; + ivar5 = 5523; + while (ivar3 < getExtraChildGap(new WidgetPointer(arg0))) { + if (setWidgetRegister(new WidgetPointer(arg0), ivar3) && (getWidgetSpriteId() == ivar4)) { + removeAllEventListeners(); + setWidgetSprite(ivar5); + } + ivar3 = add(ivar3, 1); + } + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + removeAllEventListeners(); + setWidgetSprite(ivar4); + } + globalint_1601 = ivar3; + script_5202(0); + script_5204(); + return; +} diff --git a/dumps/scripts/5208.cs2 b/dumps/scripts/5208.cs2 new file mode 100644 index 0000000..50ad4b0 --- /dev/null +++ b/dumps/scripts/5208.cs2 @@ -0,0 +1,4 @@ +void script_5208() { + cs2method5400(1, "friend-referral", "splash.ws"); + return; +} diff --git a/dumps/scripts/5209.cs2 b/dumps/scripts/5209.cs2 new file mode 100644 index 0000000..2801897 --- /dev/null +++ b/dumps/scripts/5209.cs2 @@ -0,0 +1,7 @@ +void script_5209() { + string svar0; + svar0 = "Pin this skill plot's information to this side interface?"; + setScriptCallOnMouseOver(4538, new WidgetPointer(1117,0), new WidgetPointer(1117,133), -1, svar0, 160, 3793, 3793, 16777215, 13, 4, 0, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1117,133)); + setScriptCallOnMouseExit(40, new WidgetPointer(1117,0), "I", new WidgetPointer(1117,133)); + return; +} diff --git a/dumps/scripts/521.cs2 b/dumps/scripts/521.cs2 new file mode 100644 index 0000000..7209b6e --- /dev/null +++ b/dumps/scripts/521.cs2 @@ -0,0 +1,12 @@ +void script_521() { + globalint_54 = getSkillXp(20); + globalint_55 = getSkillXp(12); + globalint_57 = getSkillXp(9); + globalint_58 = getSkillXp(7); + globalint_60 = getSkillXp(22); + globalint_61 = getSkillXp(15); + globalint_64 = getSkillXp(6); + globalint_66 = getSkillXp(13); + globalint_62 = getSkillXp(19); + return; +} diff --git a/dumps/scripts/5210.cs2 b/dumps/scripts/5210.cs2 new file mode 100644 index 0000000..dbba6d4 --- /dev/null +++ b/dumps/scripts/5210.cs2 @@ -0,0 +1,9 @@ +void script_5210(int arg0) { + if (((boolean)bitconfig_6448)) { + script_5211(1); + return; + } + script_5211(0); + setScriptCallOnConfigChange(-1, "", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/5211.cs2 b/dumps/scripts/5211.cs2 new file mode 100644 index 0000000..be31aba --- /dev/null +++ b/dumps/scripts/5211.cs2 @@ -0,0 +1,8 @@ +void script_5211(int arg0) { + setWidgetIsHidden(((boolean)arg0), new WidgetPointer(746,13)); + setWidgetIsHidden(((boolean)arg0), new WidgetPointer(746,227)); + if (((boolean)arg0)) { + setWidgetIsHidden(((boolean)arg0), new WidgetPointer(746,184)); + } + return; +} diff --git a/dumps/scripts/5212.cs2 b/dumps/scripts/5212.cs2 new file mode 100644 index 0000000..ac74ddb --- /dev/null +++ b/dumps/scripts/5212.cs2 @@ -0,0 +1,8 @@ +void script_5212(int arg0) { + if (bitconfig_9511 == 2000) { + setWidgetText(new WidgetPointer(arg0), "" + intToStr(bitconfig_9511) + "/" + intToStr(2000) + ""); + } else { + setWidgetText(new WidgetPointer(arg0), "" + intToStr(bitconfig_9511) + "/" + intToStr(2000) + ""); + } + return; +} diff --git a/dumps/scripts/5213.cs2 b/dumps/scripts/5213.cs2 new file mode 100644 index 0000000..0228f84 --- /dev/null +++ b/dumps/scripts/5213.cs2 @@ -0,0 +1,43 @@ +int script_5213(int arg0) { + switch (arg0) { + case 16: + return 71565312; + case 17: + return 71565313; + case 18: + return 71565314; + case 19: + return 71565315; + case 20: + return 71565316; + case 21: + return 71565317; + case 22: + return 71565318; + case 23: + return 71565319; + case 24: + return 71565320; + case 25: + return 71565321; + case 26: + return 71565322; + case 27: + return 71565323; + case 28: + return 71565324; + case 29: + return 71565325; + case 30: + return 71565326; + case 31: + return 71565327; + case 32: + return 71565328; + case 33: + return 71565329; + case 34: + return 71565330; + } + return -1; +} diff --git a/dumps/scripts/5214.cs2 b/dumps/scripts/5214.cs2 new file mode 100644 index 0000000..6f7f8de --- /dev/null +++ b/dumps/scripts/5214.cs2 @@ -0,0 +1,27 @@ +int script_5214(int arg0) { + if (citadelConfigsInitialized()) { + switch (arg0) { + case 1: + return 1; + case 2: + return 2; + case 3: + return 3; + case 4: + return 3; + case 5: + return 3; + case 6: + return 4; + case 7: + return 4; + case 8: + return 5; + case 10: + return 5; + case 9: + return 6; + } + } + return 0; +} diff --git a/dumps/scripts/5215.cs2 b/dumps/scripts/5215.cs2 new file mode 100644 index 0000000..dd9f07f --- /dev/null +++ b/dumps/scripts/5215.cs2 @@ -0,0 +1,105 @@ +int script_5215(int arg0) { + switch (arg0) { + case 1: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 2: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 3: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 4: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 5: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 6: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 7: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 8: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 10: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + case 9: + /* + mgi.tools.jagdecs2.DecompilerException: TODO citadel configs method:106 + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:230) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + return -1; +} diff --git a/dumps/scripts/5216.cs2 b/dumps/scripts/5216.cs2 new file mode 100644 index 0000000..1c743db --- /dev/null +++ b/dumps/scripts/5216.cs2 @@ -0,0 +1,43 @@ +int script_5216(int arg0) { + switch (arg0) { + case 16: + return 71566685; + case 17: + return 71565347; + case 18: + return 71565346; + case 19: + return 71565345; + case 20: + return 71565344; + case 21: + return 71565343; + case 22: + return 71566722; + case 23: + return 71565342; + case 24: + return 71565341; + case 25: + return 71565340; + case 26: + return 71565339; + case 27: + return 71565338; + case 28: + return 71565337; + case 29: + return 71565336; + case 30: + return 71565335; + case 31: + return 71565334; + case 32: + return 71565333; + case 33: + return 71565332; + case 34: + return 71565331; + } + return -1; +} diff --git a/dumps/scripts/5217.cs2 b/dumps/scripts/5217.cs2 new file mode 100644 index 0000000..7f280eb --- /dev/null +++ b/dumps/scripts/5217.cs2 @@ -0,0 +1,8 @@ +void script_5217(int arg0,int arg1,int arg2,int arg3) { + script_4526(arg0, arg1); + setScriptCallOnMouseEntered(-1, "", new WidgetPointer(arg0)); + setScriptCallOnMouseEntered(-1, "", new WidgetPointer(arg3)); + setScriptCallOnMouseEntered(5218, new WidgetPointer(arg0), new WidgetPointer(arg3), 0, 0, new WidgetPointer(arg2), "IIiiI", new WidgetPointer(arg2)); + setScriptCallOnMouseExit(5218, new WidgetPointer(arg0), new WidgetPointer(arg3), 1, 0, new WidgetPointer(arg2), "IIiiI", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/5218.cs2 b/dumps/scripts/5218.cs2 new file mode 100644 index 0000000..ac53d06 --- /dev/null +++ b/dumps/scripts/5218.cs2 @@ -0,0 +1,32 @@ +void script_5218(int arg0,int arg1,int arg2,int arg3,int arg4) { + int ivar5; + int ivar6; + ivar5 = 0; + ivar6 = 0; + setWidgetIsHidden(false, new WidgetPointer(getWidgetParentUid(new WidgetPointer(arg0)))); + if (arg3 > 0) { + setScriptCallOnGameloop(5218, new WidgetPointer(arg0), new WidgetPointer(arg1), arg2, subtract(arg3, 1), new WidgetPointer(arg4), "IIiiI", new WidgetPointer(arg4)); + return; + } + if (setWidgetRegister(new WidgetPointer(arg0), 0)) { + ivar5 = cs2method1609(); + if (((boolean)arg2)) { + ivar6 = subtract(ivar5, 22); + } else { + ivar6 = add(ivar5, 22); + } + ivar6 = max(ivar6, 0); + ivar6 = min(ivar6, 255); + } + script_4161(arg0, ivar6); + script_4161(arg1, ivar6); + if (((boolean)ivar6) && ((boolean)arg2)) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg4)); + } else if ((ivar6 == 255) && ((boolean)arg2)) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg4)); + setWidgetIsHidden(true, new WidgetPointer(getWidgetParentUid(new WidgetPointer(arg0)))); + } else { + setScriptCallOnGameloop(5218, new WidgetPointer(arg0), new WidgetPointer(arg1), arg2, 0, new WidgetPointer(arg4), "IIiiI", new WidgetPointer(arg4)); + } + return; +} diff --git a/dumps/scripts/5219.cs2 b/dumps/scripts/5219.cs2 new file mode 100644 index 0000000..6399bde --- /dev/null +++ b/dumps/scripts/5219.cs2 @@ -0,0 +1,4 @@ +void script_5219(int arg0) { + script_41(arg0); + return; +} diff --git a/dumps/scripts/522.cs2 b/dumps/scripts/522.cs2 new file mode 100644 index 0000000..0809d67 --- /dev/null +++ b/dumps/scripts/522.cs2 @@ -0,0 +1,11 @@ +void script_522(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + ivar2 = getSkillXp(arg1); + ivar3 = getSkillXp(arg1); + ivar2 = script_523(arg1); + ivar4 = subtract(ivar3, ivar2); + setWidgetText(new WidgetPointer(arg0), intToStr(ivar4)); + return; +} diff --git a/dumps/scripts/5220.cs2 b/dumps/scripts/5220.cs2 new file mode 100644 index 0000000..8dd01b6 --- /dev/null +++ b/dumps/scripts/5220.cs2 @@ -0,0 +1,9 @@ +void script_5220() { + script_5219(71565612); + script_5219(71565639); + script_5219(71565573); + script_5219(71566566); + script_5219(71565555); + script_5219(71565569); + return; +} diff --git a/dumps/scripts/5221.cs2 b/dumps/scripts/5221.cs2 new file mode 100644 index 0000000..6d70056 --- /dev/null +++ b/dumps/scripts/5221.cs2 @@ -0,0 +1,18 @@ +void script_5221() { + script_5222(1); + script_5222(2); + script_5222(3); + script_5222(4); + script_5222(5); + script_5222(6); + script_5222(7); + script_5222(8); + script_5222(9); + script_5222(10); + script_5222(11); + script_5222(12); + script_5222(13); + script_5222(14); + script_5222(15); + return; +} diff --git a/dumps/scripts/5222.cs2 b/dumps/scripts/5222.cs2 new file mode 100644 index 0000000..741dde2 --- /dev/null +++ b/dumps/scripts/5222.cs2 @@ -0,0 +1,39 @@ +void script_5222(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + string svar0; + string svar1; + ivar1 = script_4949(arg0); + ivar2 = script_4959(arg0); + ivar3 = script_4972(arg0); + if (ivar3 == -1) { + return; + } + ivar4 = getWidgetParentUid(new WidgetPointer(ivar3)); + ivar5 = getWidgetParentUid(new WidgetPointer(ivar4)); + svar0 = ""; + svar1 = "Empty skill plot"; + ivar6 = 3; + if (((boolean)arg0)) { + svar0 = "Citadel : Tier " + intToStr(ivar2); + } else if (arg0 == 2) { + svar0 = "Storehouse : Tier " + intToStr(ivar2); + } else if (arg0 == 3) { + svar0 = "Battlefield : Tier " + intToStr(ivar2); + } else if (ivar2 > 0) { + svar0 = svar1 + " : Tier " + intToStr(ivar2); + } else { + svar0 = "Empty skill plot"; + } + svar1 = cs2method_3408(105, 115, 4287, ivar1); + if (getWidgetActualX(new WidgetPointer(ivar4)) < subtract(divide(getWidgetActualWidth(new WidgetPointer(ivar5)), 2), 50)) { + ivar6 = 1; + } + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(ivar3), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, ivar6, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(ivar3)); + setScriptCallOnMouseExit(40, new WidgetPointer(1092,327), "I", new WidgetPointer(ivar3)); + return; +} diff --git a/dumps/scripts/5223.cs2 b/dumps/scripts/5223.cs2 new file mode 100644 index 0000000..e56e94c --- /dev/null +++ b/dumps/scripts/5223.cs2 @@ -0,0 +1,25 @@ +cs2func_script_5223_struct(2,0,0) script_5223(int arg0) { + switch (arg0) { + case 1: + return newstruct cs2func_script_5223_struct(71565435, 71565424); + case 2: + return newstruct cs2func_script_5223_struct(71566946, 71566936); + case 3: + return newstruct cs2func_script_5223_struct(71566961, 71566951); + case 4: + return newstruct cs2func_script_5223_struct(71566976, 71566966); + case 5: + return newstruct cs2func_script_5223_struct(71566991, 71566981); + case 6: + return newstruct cs2func_script_5223_struct(71567036, 71567026); + case 7: + return newstruct cs2func_script_5223_struct(71567051, 71567041); + case 8: + return newstruct cs2func_script_5223_struct(71567021, 71567011); + case 9: + return newstruct cs2func_script_5223_struct(71567007, 71566996); + case 10: + return newstruct cs2func_script_5223_struct(71567066, 71567056); + } + return newstruct cs2func_script_5223_struct(-1, -1); +} diff --git a/dumps/scripts/5224.cs2 b/dumps/scripts/5224.cs2 new file mode 100644 index 0000000..d334098 --- /dev/null +++ b/dumps/scripts/5224.cs2 @@ -0,0 +1,6 @@ +int script_5224(int arg0) { + if (cs2method3701()) { + return script_5225(arg0); + } + return 0; +} diff --git a/dumps/scripts/5225.cs2 b/dumps/scripts/5225.cs2 new file mode 100644 index 0000000..ec3c40c --- /dev/null +++ b/dumps/scripts/5225.cs2 @@ -0,0 +1,28 @@ +int script_5225(int arg0) { + int ivar1; + ivar1 = -1; + ivar1 = cs2method3717(strRemoveEntities(cs2method5020())); + if (ivar1 < 0) { + return 0; + } + if (arg0 == -1) { + arg0 = cs2method3711(ivar1); + } + switch (arg0) { + case 100: + return clanbitconfig_263; + case 101: + return clanbitconfig_264; + case 102: + return clanbitconfig_265; + case 103: + return clanbitconfig_266; + case 125: + return clanbitconfig_267; + case 126: + return 1; + case 127: + return 1; + } + return 0; +} diff --git a/dumps/scripts/5226.cs2 b/dumps/scripts/5226.cs2 new file mode 100644 index 0000000..3bbaadf --- /dev/null +++ b/dumps/scripts/5226.cs2 @@ -0,0 +1,6 @@ +void script_5226() { + if (cs2method3701()) { + script_4328(71827829); + } + return; +} diff --git a/dumps/scripts/5227.cs2 b/dumps/scripts/5227.cs2 new file mode 100644 index 0000000..2daf9d6 --- /dev/null +++ b/dumps/scripts/5227.cs2 @@ -0,0 +1,62 @@ +void script_5227() { + int ivar0; + int ivar1; + string svar0; + script_5228(4); + script_5228(5); + script_5228(6); + script_5228(7); + script_5228(8); + script_5228(9); + script_5228(10); + script_5228(11); + script_5228(12); + script_5228(13); + script_5228(14); + script_5228(15); + ivar0 = getWidgetParentUid(new WidgetPointer(1092,928)); + if (ivar0 == -1) { + return; + } + ivar1 = 2; + if (getWidgetActualY(new WidgetPointer(1092,928)) > divide(getWidgetActualHeight(new WidgetPointer(ivar0)), 2)) { + ivar1 = 0; + } + svar0 = "Teleport to the keep."; + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,928), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, ivar1, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,928)); + setScriptCallOnMouseExit(40, new WidgetPointer(1092,327), "I", new WidgetPointer(1092,928)); + setWidgetContextMenuOption(1, new WidgetPointer(1092,928), "Teleport to keep"); + ivar1 = 2; + if (getWidgetActualY(new WidgetPointer(1092,931)) > divide(getWidgetActualHeight(new WidgetPointer(ivar0)), 2)) { + ivar1 = 0; + } + svar0 = "Teleport to the town square."; + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,931), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, ivar1, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,931)); + setScriptCallOnMouseExit(40, new WidgetPointer(1092,327), "I", new WidgetPointer(1092,931)); + setWidgetContextMenuOption(1, new WidgetPointer(1092,931), "Teleport to town square"); + ivar1 = 2; + if (getWidgetActualY(new WidgetPointer(1092,929)) > divide(getWidgetActualHeight(new WidgetPointer(ivar0)), 2)) { + ivar1 = 0; + } + svar0 = "Teleport to the portal."; + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,929), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, ivar1, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,929)); + setScriptCallOnMouseExit(40, new WidgetPointer(1092,327), "I", new WidgetPointer(1092,929)); + setWidgetContextMenuOption(1, new WidgetPointer(1092,929), "Teleport to portal"); + ivar1 = 2; + if (getWidgetActualY(new WidgetPointer(1092,930)) > divide(getWidgetActualHeight(new WidgetPointer(ivar0)), 2)) { + ivar1 = 0; + } + svar0 = "Teleport to the welcome area."; + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,930), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, ivar1, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,930)); + setScriptCallOnMouseExit(40, new WidgetPointer(1092,327), "I", new WidgetPointer(1092,930)); + setWidgetContextMenuOption(1, new WidgetPointer(1092,930), "Teleport to welcome area"); + ivar1 = 2; + if (getWidgetActualY(new WidgetPointer(1092,932)) > divide(getWidgetActualHeight(new WidgetPointer(ivar0)), 2)) { + ivar1 = 0; + } + svar0 = "Teleport to the battlefield."; + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(1092,932), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, ivar1, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(1092,932)); + setScriptCallOnMouseExit(40, new WidgetPointer(1092,327), "I", new WidgetPointer(1092,932)); + setWidgetContextMenuOption(1, new WidgetPointer(1092,930), "Teleport to welcome area"); + return; +} diff --git a/dumps/scripts/5228.cs2 b/dumps/scripts/5228.cs2 new file mode 100644 index 0000000..f819f5e --- /dev/null +++ b/dumps/scripts/5228.cs2 @@ -0,0 +1,32 @@ +void script_5228(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + string svar0; + ivar1 = 0; + svar0 = ""; + ivar2 = script_4969(arg0); + ivar3 = -1; + ivar4 = 2; + if (ivar2 == -1) { + return; + } + if (citadelConfigsInitialized()) { + ivar1 = script_4949(arg0); + if (ivar1 > 0) { + svar0 = "Teleport to the " + cs2method_3408(105, 115, 4287, ivar1) + " skill plot."; + ivar3 = getWidgetParentUid(new WidgetPointer(ivar2)); + if (getWidgetActualY(new WidgetPointer(ivar2)) > divide(getWidgetActualHeight(new WidgetPointer(ivar3)), 2)) { + ivar4 = 0; + } + setScriptCallOnMouseOver(4538, new WidgetPointer(1092,327), new WidgetPointer(ivar2), -1, svar0, 120, 3793, 3793, 16777215, 13, 4, ivar4, -2147483647, -2147483646, "IIisifdiiiiii", new WidgetPointer(ivar2)); + setScriptCallOnMouseExit(40, new WidgetPointer(1092,327), "I", new WidgetPointer(ivar2)); + setWidgetContextMenuOption(1, new WidgetPointer(ivar2), "Teleport to " + cs2method_3408(105, 115, 4287, ivar1)); + return; + } + } + setScriptCallOnMouseOver(-1, "", new WidgetPointer(ivar2)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(ivar2)); + return; +} diff --git a/dumps/scripts/5229.cs2 b/dumps/scripts/5229.cs2 new file mode 100644 index 0000000..2fc3f46 --- /dev/null +++ b/dumps/scripts/5229.cs2 @@ -0,0 +1,4 @@ +void script_5229(int arg0,int arg1) { + script_337(arg0, arg1, 1); + return; +} diff --git a/dumps/scripts/523.cs2 b/dumps/scripts/523.cs2 new file mode 100644 index 0000000..9863fd1 --- /dev/null +++ b/dumps/scripts/523.cs2 @@ -0,0 +1,30 @@ +int script_523(int arg0) { + if (arg0 == 20) { + return globalint_54; + } + if (arg0 == 12) { + return globalint_55; + } + if (arg0 == 9) { + return globalint_57; + } + if (arg0 == 7) { + return globalint_58; + } + if (arg0 == 22) { + return globalint_60; + } + if (arg0 == 15) { + return globalint_61; + } + if (arg0 == 6) { + return globalint_64; + } + if (arg0 == 13) { + return globalint_66; + } + if (arg0 == 19) { + return globalint_62; + } + return 0; +} diff --git a/dumps/scripts/5230.cs2 b/dumps/scripts/5230.cs2 new file mode 100644 index 0000000..b9339c7 --- /dev/null +++ b/dumps/scripts/5230.cs2 @@ -0,0 +1,7 @@ +void script_5230(int arg0,int arg1,int arg2) { + if (cs2method3700()) { + script_4340(arg0, clanconfig_0, arg1, arg2); + setScriptCallOnClanChatSettingsStuff(-1, "", new WidgetPointer(arg2)); + } + return; +} diff --git a/dumps/scripts/5231.cs2 b/dumps/scripts/5231.cs2 new file mode 100644 index 0000000..3bfbb95 --- /dev/null +++ b/dumps/scripts/5231.cs2 @@ -0,0 +1,47 @@ +void script_5231(int arg0) { + flow_0: + SWITCH (globalint_1007) { + case 0: + GOTO flow_1 + case 1: + GOTO flow_2 + case 2: + GOTO flow_3 + case 3: + GOTO flow_6 + } + deleteAllExtraChilds(new WidgetPointer(arg0)); + cs2method5512(); + GOTO flow_8 + flow_1: + script_2766(0, 30, arg0); + GOTO flow_8 + flow_2: + cs2method5405(0, 5); + cs2method5405(1, 5); + cs2method5406(0, 0, 51875191, 1600, 51875191, 1600, 0); + cs2method5406(1, 0, 51858819, 600, 51858818, 600, 0); + cs2method5406(0, 1, 51875206, 2100, 51875209, 2100, 0); + cs2method5406(1, 1, 51858831, 600, 51858836, 600, 0); + cs2method5406(0, 2, 51907986, 1400, 51907987, 1400, 0); + cs2method5406(1, 2, 51744156, 400, 51678621, 400, 0); + cs2method5406(0, 3, 51793308, 700, 51776926, 700, 0); + cs2method5406(1, 3, 51596695, 300, 51613076, 300, 0); + cs2method5406(0, 4, 51694999, 500, 51678614, 500, 0); + cs2method5406(1, 4, 51826061, 300, 51858830, 300, 0); + cameraMethod5502(0, 0, 0, 0, 1, 0); + script_2768(30, arg0); + GOTO flow_8 + flow_3: + if (cs2method5407(0) == 5) { + cameraMethod5502(0, 0, 300, 800, 1, 0); + setScriptCallOnMinimapRelatedSetting3(5232, new WidgetPointer(arg0), 1, "Ii", new WidgetPointer(arg0)); + } + GOTO flow_8 + flow_6: + if (cs2method5407(0) == 5) { + cameraMethod5502(0, 3, 500, 400, 1, 3); + } + flow_8: + return; +} diff --git a/dumps/scripts/5232.cs2 b/dumps/scripts/5232.cs2 new file mode 100644 index 0000000..d2fd6c4 --- /dev/null +++ b/dumps/scripts/5232.cs2 @@ -0,0 +1,14 @@ +void script_5232(int arg0,int arg1) { + if ((cs2method5407(0) == 5) && (globalint_1007 == 2)) { + if (((boolean)arg1)) { + cameraMethod5502(0, 1, 800, 700, 1, 1); + setScriptCallOnMinimapRelatedSetting3(5232, new WidgetPointer(arg0), 2, "Ii", new WidgetPointer(arg0)); + return; + } + if (arg1 == 2) { + cameraMethod5502(0, 2, 700, 40, 1, 2); + } + } + setScriptCallOnMinimapRelatedSetting3(-1, "", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/5233.cs2 b/dumps/scripts/5233.cs2 new file mode 100644 index 0000000..15a9583 --- /dev/null +++ b/dumps/scripts/5233.cs2 @@ -0,0 +1,4 @@ +void script_5233(int arg0,int arg1) { + script_2010(arg0, arg1, "Level 21 Agility"); + return; +} diff --git a/dumps/scripts/5234.cs2 b/dumps/scripts/5234.cs2 new file mode 100644 index 0000000..d900c3b --- /dev/null +++ b/dumps/scripts/5234.cs2 @@ -0,0 +1,13 @@ +void script_5234(int arg0) { + switch (arg0) { + case 73793656: + setWidgetIsHidden(false, new WidgetPointer(1126,121)); + break; + case 73793729: + setWidgetIsHidden(false, new WidgetPointer(1126,194)); + break; + case 73793731: + setWidgetIsHidden(false, new WidgetPointer(1126,196)); + } + return; +} diff --git a/dumps/scripts/5235.cs2 b/dumps/scripts/5235.cs2 new file mode 100644 index 0000000..a8d63e0 --- /dev/null +++ b/dumps/scripts/5235.cs2 @@ -0,0 +1,13 @@ +void script_5235(int arg0) { + switch (arg0) { + case 73793656: + setWidgetIsHidden(true, new WidgetPointer(1126,121)); + break; + case 73793729: + setWidgetIsHidden(true, new WidgetPointer(1126,194)); + break; + case 73793731: + setWidgetIsHidden(true, new WidgetPointer(1126,196)); + } + return; +} diff --git a/dumps/scripts/5236.cs2 b/dumps/scripts/5236.cs2 new file mode 100644 index 0000000..b87d1a2 --- /dev/null +++ b/dumps/scripts/5236.cs2 @@ -0,0 +1,8 @@ +void script_5236() { + int ivar0; + ivar0 = subtract(120, multiplyDivide(120, 100, globalint_1186)); + if (getWidgetActualWidth(new WidgetPointer(1126,124)) < ivar0) { + setWidgetSize(add(getWidgetActualWidth(new WidgetPointer(1126,124)), 1), getWidgetActualHeight(new WidgetPointer(1126,124)), 0, 0, new WidgetPointer(1126,124)); + } + return; +} diff --git a/dumps/scripts/5237.cs2 b/dumps/scripts/5237.cs2 new file mode 100644 index 0000000..7daf4a1 --- /dev/null +++ b/dumps/scripts/5237.cs2 @@ -0,0 +1,5 @@ +void script_5237() { + setWidgetSize(0, getWidgetActualHeight(new WidgetPointer(1126,124)), 0, 0, new WidgetPointer(1126,124)); + setWidgetIsHidden(true, new WidgetPointer(1126,47)); + return; +} diff --git a/dumps/scripts/5238.cs2 b/dumps/scripts/5238.cs2 new file mode 100644 index 0000000..16d24f6 --- /dev/null +++ b/dumps/scripts/5238.cs2 @@ -0,0 +1,30 @@ +void script_5238(int arg0) { + int ivar1; + string svar0; + svar0 = "Ability"; + ivar1 = cs2method_3408(105, 74, 5033, bitconfig_9712); + setWidgetIsHidden(true, new WidgetPointer(1126,4)); + setWidgetIsHidden(true, new WidgetPointer(1126,5)); + setWidgetIsHidden(true, new WidgetPointer(1126,6)); + setWidgetIsHidden(true, new WidgetPointer(1126,7)); + switch (arg0) { + case 1: + svar0 = getOtherCommonData(ivar1, 1900); + setWidgetIsHidden(false, new WidgetPointer(1126,4)); + break; + case 2: + svar0 = getOtherCommonData(ivar1, 1903); + setWidgetIsHidden(false, new WidgetPointer(1126,5)); + break; + case 3: + svar0 = getOtherCommonData(ivar1, 1906); + setWidgetIsHidden(false, new WidgetPointer(1126,6)); + break; + case 4: + svar0 = getOtherCommonData(ivar1, 1909); + setWidgetIsHidden(false, new WidgetPointer(1126,7)); + } + setWidgetText(new WidgetPointer(1126,49), svar0); + setWidgetIsHidden(false, new WidgetPointer(1126,47)); + return; +} diff --git a/dumps/scripts/5239.cs2 b/dumps/scripts/5239.cs2 new file mode 100644 index 0000000..c5b27b1 --- /dev/null +++ b/dumps/scripts/5239.cs2 @@ -0,0 +1,4 @@ +void script_5239() { + setWidgetIsHidden(true, new WidgetPointer(1126,47)); + return; +} diff --git a/dumps/scripts/524.cs2 b/dumps/scripts/524.cs2 new file mode 100644 index 0000000..735d334 --- /dev/null +++ b/dumps/scripts/524.cs2 @@ -0,0 +1,46 @@ +void script_524(int arg0,int arg1) { + int ivar2; + ivar2 = 0; + if (bitconfig_4103 >= 300000) { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(arg0)); + return; + } + if (arg0 == 19726381) { + ivar2 = bitconfig_4090; + } + if (arg0 == 19726383) { + ivar2 = bitconfig_4091; + } + if (arg0 == 19726385) { + ivar2 = bitconfig_4093; + } + if (arg0 == 19726387) { + ivar2 = bitconfig_4095; + } + if (arg0 == 19726389) { + ivar2 = bitconfig_4096; + } + if (arg0 == 19726391) { + ivar2 = bitconfig_4098; + } + if (arg0 == 19726393) { + ivar2 = bitconfig_4100; + } + if (arg0 == 19726395) { + ivar2 = bitconfig_4101; + } + if (arg0 == 19726397) { + ivar2 = bitconfig_4102; + } + if ((arg0 == 19726419) || (arg0 == 19726420)) { + ivar2 = 1; + } + if (((boolean)ivar2)) { + setWidgetRGB(new Color(250, 180, 50), new WidgetPointer(arg0)); + setWidgetRGB(new Color(250, 180, 50), new WidgetPointer(arg1)); + } else { + setWidgetRGB(new Color(96, 96, 96), new WidgetPointer(arg0)); + setWidgetRGB(new Color(96, 96, 96), new WidgetPointer(arg1)); + } + return; +} diff --git a/dumps/scripts/5240.cs2 b/dumps/scripts/5240.cs2 new file mode 100644 index 0000000..09830aa --- /dev/null +++ b/dumps/scripts/5240.cs2 @@ -0,0 +1,12 @@ +void script_5240(int arg0) { + if (((boolean)globalint_1184)) { + if (arg0 == 73793728) { + setWidgetRGB(new Color(235, 224, 188), new WidgetPointer(arg0)); + } + } else { + if (arg0 == 73793723) { + setWidgetRGB(new Color(235, 224, 188), new WidgetPointer(arg0)); + } + } + return; +} diff --git a/dumps/scripts/5241.cs2 b/dumps/scripts/5241.cs2 new file mode 100644 index 0000000..483d0e6 --- /dev/null +++ b/dumps/scripts/5241.cs2 @@ -0,0 +1,12 @@ +void script_5241(int arg0) { + if (((boolean)globalint_1184)) { + if (arg0 == 73793728) { + setWidgetRGB(new Color(153, 145, 122), new WidgetPointer(arg0)); + } + } else { + if (arg0 == 73793723) { + setWidgetRGB(new Color(153, 145, 122), new WidgetPointer(arg0)); + } + } + return; +} diff --git a/dumps/scripts/5242.cs2 b/dumps/scripts/5242.cs2 new file mode 100644 index 0000000..7310528 --- /dev/null +++ b/dumps/scripts/5242.cs2 @@ -0,0 +1,23 @@ +void script_5242(int arg0) { + playSoundEffect2False(6185, 1, 0, 127); + if (arg0 == 73793723) { + setWidgetRGB(new Color(153, 145, 122), new WidgetPointer(1126,192)); + setWidgetRGB(new Color(235, 224, 188), new WidgetPointer(1126,187)); + setWidgetSprite(459, new WidgetPointer(1126,189)); + setWidgetSprite(460, new WidgetPointer(1126,190)); + setWidgetSprite(459, new WidgetPointer(1126,191)); + setWidgetSprite(454, new WidgetPointer(1126,0)); + setWidgetSprite(456, new WidgetPointer(1126,1)); + setWidgetSprite(454, new WidgetPointer(1126,186)); + } else { + setWidgetRGB(new Color(153, 145, 122), new WidgetPointer(1126,187)); + setWidgetRGB(new Color(235, 224, 188), new WidgetPointer(1126,192)); + setWidgetSprite(454, new WidgetPointer(1126,189)); + setWidgetSprite(456, new WidgetPointer(1126,190)); + setWidgetSprite(454, new WidgetPointer(1126,191)); + setWidgetSprite(459, new WidgetPointer(1126,0)); + setWidgetSprite(460, new WidgetPointer(1126,1)); + setWidgetSprite(459, new WidgetPointer(1126,186)); + } + return; +} diff --git a/dumps/scripts/5243.cs2 b/dumps/scripts/5243.cs2 new file mode 100644 index 0000000..1faa9dc --- /dev/null +++ b/dumps/scripts/5243.cs2 @@ -0,0 +1,12 @@ +void script_5243(int arg0) { + if (((boolean)arg0)) { + setWidgetSprite(6379, new WidgetPointer(1128,329)); + setWidgetSprite(6380, new WidgetPointer(1128,330)); + setWidgetSprite(6381, new WidgetPointer(1128,331)); + } else { + setWidgetSprite(6379, new WidgetPointer(1128,0)); + setWidgetSprite(6380, new WidgetPointer(1128,1)); + setWidgetSprite(6381, new WidgetPointer(1128,2)); + } + return; +} diff --git a/dumps/scripts/5244.cs2 b/dumps/scripts/5244.cs2 new file mode 100644 index 0000000..061baa3 --- /dev/null +++ b/dumps/scripts/5244.cs2 @@ -0,0 +1,12 @@ +void script_5244(int arg0) { + if (((boolean)arg0)) { + setWidgetSprite(6370, new WidgetPointer(1128,329)); + setWidgetSprite(6371, new WidgetPointer(1128,330)); + setWidgetSprite(6372, new WidgetPointer(1128,331)); + } else { + setWidgetSprite(6370, new WidgetPointer(1128,0)); + setWidgetSprite(6371, new WidgetPointer(1128,1)); + setWidgetSprite(6372, new WidgetPointer(1128,2)); + } + return; +} diff --git a/dumps/scripts/5245.cs2 b/dumps/scripts/5245.cs2 new file mode 100644 index 0000000..5549ff7 --- /dev/null +++ b/dumps/scripts/5245.cs2 @@ -0,0 +1,40 @@ +void script_5245() { + int ivar0; + int ivar1; + ivar0 = 0; + ivar1 = 0; + if (getWidgetSpriteId(new WidgetPointer(1128,4)) == 6007) { + ivar0 = add(ivar0, 20); + ivar1 = add(ivar1, 20); + } + if (getWidgetSpriteId(new WidgetPointer(1128,104)) == 6007) { + ivar0 = add(ivar0, 20); + ivar1 = add(ivar1, 20); + } + if (getWidgetSpriteId(new WidgetPointer(1128,142)) == 6007) { + ivar0 = add(ivar0, 30); + ivar1 = add(ivar1, 20); + } + if (getWidgetSpriteId(new WidgetPointer(1128,179)) == 6007) { + ivar0 = add(ivar0, 28); + ivar1 = add(ivar1, 20); + } + if (getWidgetSpriteId(new WidgetPointer(1128,216)) == 6007) { + ivar0 = add(ivar0, 24); + ivar1 = add(ivar1, 20); + } + if (getWidgetSpriteId(new WidgetPointer(1128,253)) == 6007) { + ivar0 = add(ivar0, 26); + ivar1 = add(ivar1, 20); + } + if (getWidgetSpriteId(new WidgetPointer(1128,290)) == 6007) { + ivar0 = add(ivar0, 200); + ivar1 = add(ivar1, 200); + } + if ((bitconfig_5505 < ivar0) || (bitconfig_5505 < ivar1)) { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(1128,13)); + } else { + setWidgetRGB(new Color(168, 141, 101), new WidgetPointer(1128,13)); + } + return; +} diff --git a/dumps/scripts/5246.cs2 b/dumps/scripts/5246.cs2 new file mode 100644 index 0000000..4039bc7 --- /dev/null +++ b/dumps/scripts/5246.cs2 @@ -0,0 +1,4 @@ +void script_5246() { + script_41(73924683); + return; +} diff --git a/dumps/scripts/5247.cs2 b/dumps/scripts/5247.cs2 new file mode 100644 index 0000000..2f5792e --- /dev/null +++ b/dumps/scripts/5247.cs2 @@ -0,0 +1,18 @@ +void script_5247() { + setWidgetIsHidden(true, new WidgetPointer(1128,97)); + setWidgetSprite(6009, new WidgetPointer(1128,4)); + setWidgetIsHidden(true, new WidgetPointer(1128,127)); + setWidgetSprite(6009, new WidgetPointer(1128,104)); + setWidgetIsHidden(true, new WidgetPointer(1128,165)); + setWidgetSprite(6009, new WidgetPointer(1128,142)); + setWidgetIsHidden(true, new WidgetPointer(1128,202)); + setWidgetSprite(6009, new WidgetPointer(1128,179)); + setWidgetIsHidden(true, new WidgetPointer(1128,239)); + setWidgetSprite(6009, new WidgetPointer(1128,216)); + setWidgetIsHidden(true, new WidgetPointer(1128,276)); + setWidgetSprite(6009, new WidgetPointer(1128,253)); + setWidgetIsHidden(true, new WidgetPointer(1128,313)); + setWidgetSprite(6009, new WidgetPointer(1128,290)); + setWidgetText(new WidgetPointer(1128,13), intToStr(bitconfig_5505)); + return; +} diff --git a/dumps/scripts/5248.cs2 b/dumps/scripts/5248.cs2 new file mode 100644 index 0000000..5fd92c8 --- /dev/null +++ b/dumps/scripts/5248.cs2 @@ -0,0 +1,4 @@ +void script_5248() { + setWidgetText(new WidgetPointer(1128,13), intToStr(bitconfig_5505)); + return; +} diff --git a/dumps/scripts/5249.cs2 b/dumps/scripts/5249.cs2 new file mode 100644 index 0000000..95ef9f9 --- /dev/null +++ b/dumps/scripts/5249.cs2 @@ -0,0 +1,44 @@ +void script_5249() { + setWidgetIsHidden(true, new WidgetPointer(1127,64)); + setWidgetIsHidden(true, new WidgetPointer(1127,65)); + setWidgetIsHidden(true, new WidgetPointer(1127,66)); + setWidgetIsHidden(true, new WidgetPointer(1127,9)); + setWidgetIsHidden(true, new WidgetPointer(1127,10)); + setWidgetIsHidden(true, new WidgetPointer(1127,11)); + setWidgetIsHidden(true, new WidgetPointer(1127,61)); + setWidgetIsHidden(true, new WidgetPointer(1127,62)); + setWidgetIsHidden(true, new WidgetPointer(1127,63)); + setWidgetIsHidden(true, new WidgetPointer(1127,67)); + setWidgetIsHidden(true, new WidgetPointer(1127,68)); + setWidgetIsHidden(true, new WidgetPointer(1127,69)); + setWidgetIsHidden(true, new WidgetPointer(1127,70)); + setWidgetIsHidden(true, new WidgetPointer(1127,71)); + setWidgetIsHidden(true, new WidgetPointer(1127,72)); + switch (standart_config_2373) { + case 1: + setWidgetIsHidden(false, new WidgetPointer(1127,64)); + setWidgetIsHidden(false, new WidgetPointer(1127,65)); + setWidgetIsHidden(false, new WidgetPointer(1127,66)); + break; + case 2: + setWidgetIsHidden(false, new WidgetPointer(1127,9)); + setWidgetIsHidden(false, new WidgetPointer(1127,10)); + setWidgetIsHidden(false, new WidgetPointer(1127,11)); + break; + case 3: + setWidgetIsHidden(false, new WidgetPointer(1127,61)); + setWidgetIsHidden(false, new WidgetPointer(1127,62)); + setWidgetIsHidden(false, new WidgetPointer(1127,63)); + break; + case 5: + setWidgetIsHidden(false, new WidgetPointer(1127,67)); + setWidgetIsHidden(false, new WidgetPointer(1127,68)); + setWidgetIsHidden(false, new WidgetPointer(1127,69)); + break; + case 4: + setWidgetIsHidden(false, new WidgetPointer(1127,70)); + setWidgetIsHidden(false, new WidgetPointer(1127,71)); + setWidgetIsHidden(false, new WidgetPointer(1127,72)); + } + return; +} diff --git a/dumps/scripts/525.cs2 b/dumps/scripts/525.cs2 new file mode 100644 index 0000000..fc7c70a --- /dev/null +++ b/dumps/scripts/525.cs2 @@ -0,0 +1,4 @@ +void script_525(int arg0,int arg1) { + setWidgetText(new WidgetPointer(arg0), intToStr(getSkillCurrentLvl(arg1))); + return; +} diff --git a/dumps/scripts/5250.cs2 b/dumps/scripts/5250.cs2 new file mode 100644 index 0000000..2be2d44 --- /dev/null +++ b/dumps/scripts/5250.cs2 @@ -0,0 +1,74 @@ +void script_5250(int arg0) { + switch (standart_config_2373) { + case 2: + if (((boolean)arg0)) { + setWidgetText(new WidgetPointer(1127,18), "Battle-mage Helm"); + setWidgetText(new WidgetPointer(1127,17), "Strong against melee and magical attacks, weak against ranged."); + } + if (arg0 == 2) { + setWidgetText(new WidgetPointer(1127,18), "Trickster Hood"); + setWidgetText(new WidgetPointer(1127,17), "Strong against ranged and magical attacks, weak against melee."); + } + if (arg0 == 3) { + setWidgetText(new WidgetPointer(1127,18), "Vanguard Helm"); + setWidgetText(new WidgetPointer(1127,17), "Strong against melee and ranged attacks, weak against magic."); + } + break; + case 1: + if (((boolean)arg0)) { + setWidgetText(new WidgetPointer(1127,18), "Battle-mage robe legs"); + setWidgetText(new WidgetPointer(1127,17), "Strong against melee and magical attacks, weak against ranged."); + } + if (arg0 == 2) { + setWidgetText(new WidgetPointer(1127,18), "Trickster robe legs"); + setWidgetText(new WidgetPointer(1127,17), "Strong against ranged and magical attacks, weak against melee."); + } + if (arg0 == 3) { + setWidgetText(new WidgetPointer(1127,18), "Vanguard leg armour"); + setWidgetText(new WidgetPointer(1127,17), "Strong against melee and ranged attacks, weak against magic."); + } + break; + case 3: + if (((boolean)arg0)) { + setWidgetText(new WidgetPointer(1127,18), "Battle-mage robe"); + setWidgetText(new WidgetPointer(1127,17), "Strong against melee and magical attacks, weak against ranged."); + } + if (arg0 == 2) { + setWidgetText(new WidgetPointer(1127,18), "Trickster robe"); + setWidgetText(new WidgetPointer(1127,17), "Strong against ranged and magical attacks, weak against melee."); + } + if (arg0 == 3) { + setWidgetText(new WidgetPointer(1127,18), "Vanguard body armour"); + setWidgetText(new WidgetPointer(1127,17), "Strong against melee and ranged attacks, weak against magic."); + } + break; + case 5: + if (((boolean)arg0)) { + setWidgetText(new WidgetPointer(1127,18), "Battle-mage gloves"); + setWidgetText(new WidgetPointer(1127,17), "Strong against melee and magical attacks, weak against ranged."); + } + if (arg0 == 2) { + setWidgetText(new WidgetPointer(1127,18), "Trickster gloves"); + setWidgetText(new WidgetPointer(1127,17), "Strong against ranged and magical attacks, weak against melee."); + } + if (arg0 == 3) { + setWidgetText(new WidgetPointer(1127,18), "Vanguard gloves"); + setWidgetText(new WidgetPointer(1127,17), "Strong against melee and ranged attacks, weak against magic."); + } + break; + case 4: + if (((boolean)arg0)) { + setWidgetText(new WidgetPointer(1127,18), "Battle-mage boots"); + setWidgetText(new WidgetPointer(1127,17), "Strong against melee and magical attacks, weak against ranged."); + } + if (arg0 == 2) { + setWidgetText(new WidgetPointer(1127,18), "Trickster boots"); + setWidgetText(new WidgetPointer(1127,17), "Strong against ranged and magical attacks, weak against melee."); + } + if (arg0 == 3) { + setWidgetText(new WidgetPointer(1127,18), "Vanguard boots"); + setWidgetText(new WidgetPointer(1127,17), "Strong against melee and ranged attacks, weak against magic."); + } + } + return; +} diff --git a/dumps/scripts/5251.cs2 b/dumps/scripts/5251.cs2 new file mode 100644 index 0000000..3c3cab3 --- /dev/null +++ b/dumps/scripts/5251.cs2 @@ -0,0 +1,5 @@ +void script_5251() { + setWidgetText(new WidgetPointer(1127,18), "You have received a piece of Hybrid Armour!"); + setWidgetText(new WidgetPointer(1127,17), "Select which reward you would prefer"); + return; +} diff --git a/dumps/scripts/5252.cs2 b/dumps/scripts/5252.cs2 new file mode 100644 index 0000000..f02cefa --- /dev/null +++ b/dumps/scripts/5252.cs2 @@ -0,0 +1,5 @@ +void script_5252() { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,137)); + setWidgetIsHidden(false, new WidgetPointer(779,136)); + return; +} diff --git a/dumps/scripts/5253.cs2 b/dumps/scripts/5253.cs2 new file mode 100644 index 0000000..9b83a9c --- /dev/null +++ b/dumps/scripts/5253.cs2 @@ -0,0 +1,5 @@ +void script_5253() { + setWidgetRGB(new Color(150, 150, 150), new WidgetPointer(779,137)); + setWidgetIsHidden(true, new WidgetPointer(779,136)); + return; +} diff --git a/dumps/scripts/5254.cs2 b/dumps/scripts/5254.cs2 new file mode 100644 index 0000000..929bf46 --- /dev/null +++ b/dumps/scripts/5254.cs2 @@ -0,0 +1,4 @@ +void script_5254(int arg0) { + script_4534(arg0); + return; +} diff --git a/dumps/scripts/5255.cs2 b/dumps/scripts/5255.cs2 new file mode 100644 index 0000000..0a62c49 --- /dev/null +++ b/dumps/scripts/5255.cs2 @@ -0,0 +1,3 @@ +int script_5255() { + return multiply(max(getSkillActualLvl(5), 1), 10); +} diff --git a/dumps/scripts/5256.cs2 b/dumps/scripts/5256.cs2 new file mode 100644 index 0000000..9f6d650 --- /dev/null +++ b/dumps/scripts/5256.cs2 @@ -0,0 +1,3 @@ +int script_5256() { + return bitconfig_9816; +} diff --git a/dumps/scripts/5257.cs2 b/dumps/scripts/5257.cs2 new file mode 100644 index 0000000..0ca6aef --- /dev/null +++ b/dumps/scripts/5257.cs2 @@ -0,0 +1,4 @@ +void script_5257(int arg0,int arg1) { + script_5264(arg0, arg1); + return; +} diff --git a/dumps/scripts/5258.cs2 b/dumps/scripts/5258.cs2 new file mode 100644 index 0000000..1eca7da --- /dev/null +++ b/dumps/scripts/5258.cs2 @@ -0,0 +1,4 @@ +void script_5258() { + script_5259(add(bitconfig_9763, bitconfig_9771)); + return; +} diff --git a/dumps/scripts/5259.cs2 b/dumps/scripts/5259.cs2 new file mode 100644 index 0000000..b9f77ef --- /dev/null +++ b/dumps/scripts/5259.cs2 @@ -0,0 +1,33 @@ +void script_5259(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + ivar1 = 74252290; + ivar2 = 0; + ivar3 = 0; + ivar4 = 126; + ivar5 = 99; + if (((boolean)arg0)) { + setWidgetSize(getWidgetActualWidth(new WidgetPointer(ivar1)), 0, 0, 0, new WidgetPointer(ivar1)); + } + if (arg0 < 61) { + ivar2 = multiplyDivide(arg0, 61, 100); + ivar3 = multiplyDivide(ivar4, 100, ivar2); + if (((boolean)ivar3)) { + setWidgetSize(getWidgetActualWidth(new WidgetPointer(ivar1)), 1, 0, 0, new WidgetPointer(ivar1)); + } else { + setScriptCallOnGameloop(5260, ivar3, "i", new WidgetPointer(ivar1)); + } + } else { + arg0 = subtract(arg0, 60); + ivar2 = multiplyDivide(arg0, 140, 100); + ivar3 = add(ivar4, multiplyDivide(ivar5, 100, ivar2)); + if (isWidgetHidden(new WidgetPointer(ivar1))) { + messageType0("Hidden."); + } + setScriptCallOnGameloop(5260, ivar3, "i", new WidgetPointer(ivar1)); + } + return; +} diff --git a/dumps/scripts/526.cs2 b/dumps/scripts/526.cs2 new file mode 100644 index 0000000..cd5c186 --- /dev/null +++ b/dumps/scripts/526.cs2 @@ -0,0 +1,9 @@ +void script_526(int arg0,int arg1,int arg2) { + setWidgetIsHidden(((boolean)arg0), new WidgetPointer(arg1)); + if (((boolean)arg0)) { + setWidgetFilled(0, new WidgetPointer(arg2)); + } + script_41(19726421); + globalint_1 = 0; + return; +} diff --git a/dumps/scripts/5260.cs2 b/dumps/scripts/5260.cs2 new file mode 100644 index 0000000..0a613f0 --- /dev/null +++ b/dumps/scripts/5260.cs2 @@ -0,0 +1,11 @@ +void script_5260(int arg0) { + int ivar1; + ivar1 = 74252290; + if (getWidgetActualHeight(new WidgetPointer(ivar1)) >= arg0) { + setWidgetSize(getWidgetActualWidth(new WidgetPointer(ivar1)), arg0, 0, 0, new WidgetPointer(ivar1)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(ivar1)); + } else { + setWidgetSize(getWidgetActualWidth(new WidgetPointer(ivar1)), add(getWidgetActualHeight(new WidgetPointer(ivar1)), 1), 0, 0, new WidgetPointer(ivar1)); + } + return; +} diff --git a/dumps/scripts/5261.cs2 b/dumps/scripts/5261.cs2 new file mode 100644 index 0000000..cc52eb5 --- /dev/null +++ b/dumps/scripts/5261.cs2 @@ -0,0 +1,16 @@ +void script_5261(int arg0) { + switch (arg0) { + case 74186762: + setWidgetIsHidden(false, new WidgetPointer(1132,22)); + setWidgetText(new WidgetPointer(1132,23), "4"); + setWidgetIsHidden(false, new WidgetPointer(1132,23)); + setScriptCallOnGameloop(5262, 4, 0, new WidgetPointer(1132,10), "iiI", new WidgetPointer(arg0)); + break; + case 74186763: + setWidgetIsHidden(false, new WidgetPointer(1132,27)); + setWidgetText(new WidgetPointer(1132,28), "2"); + setWidgetIsHidden(false, new WidgetPointer(1132,28)); + setScriptCallOnGameloop(5262, 2, 0, new WidgetPointer(1132,11), "iiI", new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/5262.cs2 b/dumps/scripts/5262.cs2 new file mode 100644 index 0000000..7668b05 --- /dev/null +++ b/dumps/scripts/5262.cs2 @@ -0,0 +1,36 @@ +void script_5262(int arg0,int arg1,int arg2) { + if (arg1 == 50) { + if (((boolean)arg0)) { + switch (arg2) { + case 74186762: + setWidgetIsHidden(true, new WidgetPointer(1132,22)); + setWidgetIsHidden(true, new WidgetPointer(1132,23)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg2)); + break; + case 74186763: + setWidgetIsHidden(true, new WidgetPointer(1132,27)); + setWidgetIsHidden(true, new WidgetPointer(1132,28)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg2)); + } + } else { + switch (arg2) { + case 74186762: + setWidgetText(new WidgetPointer(1132,23), intToStr(subtract(arg0, 1))); + setScriptCallOnGameloop(5262, subtract(arg0, 1), 0, new WidgetPointer(arg2), "iiI", new WidgetPointer(arg2)); + break; + case 74186763: + setWidgetText(new WidgetPointer(1132,28), intToStr(subtract(arg0, 1))); + setScriptCallOnGameloop(5262, subtract(arg0, 1), 0, new WidgetPointer(arg2), "iiI", new WidgetPointer(arg2)); + } + } + } else { + switch (arg2) { + case 74186762: + setScriptCallOnGameloop(5262, arg0, add(arg1, 1), new WidgetPointer(1132,10), "iiI", new WidgetPointer(arg2)); + break; + case 74186763: + setScriptCallOnGameloop(5262, arg0, add(arg1, 1), new WidgetPointer(1132,11), "iiI", new WidgetPointer(arg2)); + } + } + return; +} diff --git a/dumps/scripts/5263.cs2 b/dumps/scripts/5263.cs2 new file mode 100644 index 0000000..d702b6e --- /dev/null +++ b/dumps/scripts/5263.cs2 @@ -0,0 +1,18 @@ +void script_5263(int arg0) { + int ivar1; + int ivar2; + ivar1 = 28180558; + ivar2 = 28180559; + if (((boolean)bitconfig_9814)) { + setWidgetPosition(getWidgetActualX(new WidgetPointer(arg0)), getWidgetActualY(new WidgetPointer(arg0)), 0, 0, new WidgetPointer(ivar1)); + setWidgetIsHidden(true, new WidgetPointer(arg0)); + setWidgetIsHidden(false, new WidgetPointer(ivar1)); + } else { + if (((boolean)bitconfig_9815)) { + setWidgetPosition(getWidgetActualX(new WidgetPointer(arg0)), getWidgetActualY(new WidgetPointer(arg0)), 0, 0, new WidgetPointer(ivar2)); + setWidgetIsHidden(true, new WidgetPointer(arg0)); + setWidgetIsHidden(false, new WidgetPointer(ivar2)); + } + } + return; +} diff --git a/dumps/scripts/5264.cs2 b/dumps/scripts/5264.cs2 new file mode 100644 index 0000000..010b481 --- /dev/null +++ b/dumps/scripts/5264.cs2 @@ -0,0 +1,15 @@ +void script_5264(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + setWidgetSize(getTextWidth(495, intToStr(script_5255()) + " / " + intToStr(script_5255())), getWidgetActualHeight(new WidgetPointer(arg0)), 0, 0, new WidgetPointer(arg0)); + ivar2 = 190; + ivar3 = 8; + ivar4 = add(add(getWidgetActualWidth(new WidgetPointer(arg0)), getWidgetActualWidth(new WidgetPointer(arg1))), ivar3); + ivar5 = divide(subtract(ivar2, ivar4), 2); + setWidgetPosition(ivar5, getWidgetActualY(new WidgetPointer(arg1)), 0, 0, new WidgetPointer(arg1)); + ivar5 = add(add(ivar5, getWidgetActualWidth(new WidgetPointer(arg1))), ivar3); + setWidgetPosition(ivar5, getWidgetActualY(new WidgetPointer(arg0)), 0, 0, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/5265.cs2 b/dumps/scripts/5265.cs2 new file mode 100644 index 0000000..1875980 --- /dev/null +++ b/dumps/scripts/5265.cs2 @@ -0,0 +1,9 @@ +void script_5265() { + if (((boolean)bitconfig_9822)) { + setWidgetIsHidden(false, new WidgetPointer(1137,5)); + setWidgetIsHidden(true, new WidgetPointer(1137,62)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1137,5)); + } + return; +} diff --git a/dumps/scripts/5266.cs2 b/dumps/scripts/5266.cs2 new file mode 100644 index 0000000..a199416 --- /dev/null +++ b/dumps/scripts/5266.cs2 @@ -0,0 +1,5 @@ +void script_5266() { + setWidgetIsHidden(false, new WidgetPointer(1137,5)); + setWidgetIsHidden(false, new WidgetPointer(1137,62)); + return; +} diff --git a/dumps/scripts/5267.cs2 b/dumps/scripts/5267.cs2 new file mode 100644 index 0000000..dac794d --- /dev/null +++ b/dumps/scripts/5267.cs2 @@ -0,0 +1,6 @@ +void script_5267() { + setWidgetIsHidden(true, new WidgetPointer(1137,5)); + script_5219(74514438); + deleteAllExtraChilds(new WidgetPointer(1137,109)); + return; +} diff --git a/dumps/scripts/5268.cs2 b/dumps/scripts/5268.cs2 new file mode 100644 index 0000000..6e0874c --- /dev/null +++ b/dumps/scripts/5268.cs2 @@ -0,0 +1,31 @@ +void script_5268(int arg0,string arg1,string arg2) { + int ivar1; + int ivar2; + ivar1 = getExtraChildGap(new WidgetPointer(1137,109)); + ivar2 = multiply(divide(ivar1, 2), 20); + createExtraChild(new WidgetPointer(1137,109), 4, ivar1); + setWidgetText(arg1); + arg2 = concat(arg2, "" + chooseString(arg0, " Teams: Yes.", " Teams: No.")); + setScriptCallOnMouseOver(1160, new WidgetPointer(-32768,3), -1, new WidgetPointer(1137,6), arg2, 25, 519, "IiIsii"); + setWidgetSize(8100, 20, 2, 0); + setScriptCallOnClickContextMenu(5267, ""); + if (((boolean)mod(ivar1, 2))) { + setWidgetPosition(2, ivar2, 0, 0); + } else { + setWidgetPosition(2, ivar2, 2, 0); + } + setWidgetFont(494); + setWidgetRGB(new Color(0, 255, 0)); + setWidgetUnknownBoolean(true); + setScriptCallOnMouseEntered(1356, new WidgetPointer(-32768,3), -2147483643, 16777215, "Iii"); + setScriptCallOnMouseExit(1949, new WidgetPointer(-32768,3), -2147483643, 65280, new WidgetPointer(1137,6), "IiiI"); + setWidgetContextMenuOption(1, "Select"); + if ((ivar1 >= 10) && ((boolean)mod(ivar1, 2))) { + setWidgetIsHidden(false, new WidgetPointer(1137,110)); + setWidgetSize(18, 2, 1, 1, new WidgetPointer(1137,109)); + setWidgetScrollMax(0, add(ivar2, 20), new WidgetPointer(1137,109)); + script_31(74514542, 74514541, 792, 789, 790, 791, 773, 788); + script_72(74514542, 74514541, multiply(divide(subtract(bitconfig_9822, 1), 2), 20)); + } + return; +} diff --git a/dumps/scripts/5269.cs2 b/dumps/scripts/5269.cs2 new file mode 100644 index 0000000..79a0cfc --- /dev/null +++ b/dumps/scripts/5269.cs2 @@ -0,0 +1,86 @@ +void script_5269(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12,int arg13,int arg14,int arg15,int arg16,int arg17,int arg18,int arg19,int arg20,int arg21,int arg22,int arg23,int arg24,int arg25,int arg26,int arg27,string arg28,string arg29,string arg30,string arg31,string arg32,string arg33,string arg34,string arg35,string arg36,string arg37) { + int ivar28; + int ivar29; + int ivar30; + ivar28 = 0; + ivar29 = 0; + ivar30 = 0; + setWidgetText(new WidgetPointer(1137,43), arg28); + setScriptCallOnMouseOver(1160, new WidgetPointer(-32768,3), -1, new WidgetPointer(1137,6), arg29, 25, 519, "IiIsii", new WidgetPointer(1137,30)); + setScriptCallOnMouseExit(40, new WidgetPointer(1137,6), "I", new WidgetPointer(1137,6)); + setWidgetText(new WidgetPointer(1137,48), intToStr(arg25)); + setWidgetText(new WidgetPointer(1137,39), intToStr(add(arg26, arg27))); + deleteAllExtraChilds(new WidgetPointer(1137,28)); + deleteAllExtraChilds(new WidgetPointer(1137,83)); + deleteAllExtraChilds(new WidgetPointer(1137,94)); + if (((boolean)arg0)) { + setWidgetIsHidden(true, new WidgetPointer(1137,15)); + setWidgetIsHidden(false, new WidgetPointer(1137,16)); + setWidgetIsHidden(false, new WidgetPointer(1137,17)); + setWidgetText(new WidgetPointer(1137,67), intToStr(arg26)); + setWidgetText(new WidgetPointer(1137,73), intToStr(arg27)); + if (arg1 != -1) { + ivar28 = script_5271(74514515, arg2, arg3, ivar28, arg30); + } + if (arg4 != -1) { + ivar28 = script_5271(74514515, arg5, arg6, ivar28, arg31); + } + if (arg7 != -1) { + ivar28 = script_5271(74514515, arg8, arg9, ivar28, arg32); + } + if (arg10 != -1) { + ivar28 = script_5271(74514515, arg11, arg12, ivar28, arg33); + } + if (arg13 != -1) { + ivar29 = script_5271(74514526, arg14, arg15, ivar29, arg34); + } + if (arg16 != -1) { + ivar29 = script_5271(74514526, arg17, arg18, ivar29, arg35); + } + if (arg19 != -1) { + ivar29 = script_5271(74514526, arg20, arg21, ivar29, arg36); + } + if (arg22 != -1) { + ivar29 = script_5271(74514526, arg23, arg24, ivar29, arg37); + } + while (ivar30 < ivar28) { + ivar30 = script_5272(74514515, ivar30, ivar28); + } + ivar30 = 0; + while (ivar30 < ivar29) { + ivar30 = script_5272(74514526, ivar30, ivar29); + } + } else { + setWidgetIsHidden(false, new WidgetPointer(1137,15)); + setWidgetIsHidden(true, new WidgetPointer(1137,16)); + setWidgetIsHidden(true, new WidgetPointer(1137,17)); + if (arg1 != -1) { + ivar28 = script_5271(74514460, arg2, arg3, ivar28, arg30); + } + if (arg4 != -1) { + ivar28 = script_5271(74514460, arg5, arg6, ivar28, arg31); + } + if (arg7 != -1) { + ivar28 = script_5271(74514460, arg8, arg9, ivar28, arg32); + } + if (arg10 != -1) { + ivar28 = script_5271(74514460, arg11, arg12, ivar28, arg33); + } + if (arg13 != -1) { + ivar28 = script_5271(74514460, arg14, arg15, ivar28, arg34); + } + if (arg16 != -1) { + ivar28 = script_5271(74514460, arg17, arg18, ivar28, arg35); + } + if (arg19 != -1) { + ivar28 = script_5271(74514460, arg20, arg21, ivar28, arg36); + } + if (arg22 != -1) { + ivar28 = script_5271(74514460, arg23, arg24, ivar28, arg37); + } + while (ivar30 < ivar28) { + ivar30 = script_5272(74514460, ivar30, ivar28); + } + } + return; +} diff --git a/dumps/scripts/527.cs2 b/dumps/scripts/527.cs2 new file mode 100644 index 0000000..f8120cc --- /dev/null +++ b/dumps/scripts/527.cs2 @@ -0,0 +1,12 @@ +void script_527() { + script_528(bitconfig_4090, 215, 1103, 19726399, 19726350); + script_528(bitconfig_4091, 207, 1095, 19726400, 19726352); + script_528(bitconfig_4093, 208, 1096, 19726401, 19726354); + script_528(bitconfig_4095, 221, 1109, 19726402, 19726356); + script_528(bitconfig_4096, 217, 1105, 19726403, 19726358); + script_528(bitconfig_4098, 202, 1090, 19726404, 19726360); + script_528(bitconfig_4100, 210, 1098, 19726405, 19726362); + script_528(bitconfig_4101, 212, 1100, 19726406, 19726364); + script_528(bitconfig_4102, 205, 1093, 19726407, 19726366); + return; +} diff --git a/dumps/scripts/5270.cs2 b/dumps/scripts/5270.cs2 new file mode 100644 index 0000000..c14fb34 --- /dev/null +++ b/dumps/scripts/5270.cs2 @@ -0,0 +1,7 @@ +void script_5270(int arg0,int arg1,int arg2) { + setWidgetText(new WidgetPointer(1137,48), intToStr(arg0)); + setWidgetText(new WidgetPointer(1137,39), intToStr(add(arg1, arg2))); + setWidgetText(new WidgetPointer(1137,67), intToStr(arg1)); + setWidgetText(new WidgetPointer(1137,73), intToStr(arg2)); + return; +} diff --git a/dumps/scripts/5271.cs2 b/dumps/scripts/5271.cs2 new file mode 100644 index 0000000..b0d50f6 --- /dev/null +++ b/dumps/scripts/5271.cs2 @@ -0,0 +1,36 @@ +int script_5271(int arg0,int arg1,int arg2,int arg3,string arg4) { + string svar1; + string svar2; + string svar3; + svar1 = ""; + if (arg1 == -1) { + svar1 = "Your coord"; + } else if (arg1 == -2) { + svar1 = "Safe Clanwars"; + } else { + svar1 = script_2055(arg1); + } + svar2 = " - "; + if (getWidgetActualWidth(new WidgetPointer(arg0)) < 260) { + svar2 = "
"; + } + svar3 = "max"; + if (arg2 >= 0) { + svar3 = intToStr(arg2); + } + createExtraChild(new WidgetPointer(arg0), 4, arg3); + setWidgetText(arg4 + svar2 + "@ " + svar1 + " - Max: " + svar3); + setWidgetUnknownBoolean(true); + setWidgetRGB(new Color(204, 204, 204)); + setWidgetTextAlignment(1, 1, 0); + setScriptCallOnMouseEntered(1356, new WidgetPointer(-32768,3), -2147483643, 16777215, "Iii"); + setScriptCallOnMouseExit(1356, new WidgetPointer(-32768,3), -2147483643, 13421772, "Iii"); + setWidgetContextMenuOption(1, "Spawn"); + setWidgetContextMenuOption(2, "Pick spawn number"); + setWidgetContextMenuOption(3, "Kill"); + createExtraChild(new WidgetPointer(arg0), 3, add(arg3, 1)); + setWidgetRGB(new Color(255, 255, 255)); + cs2method2103(226); + setWidgetFilled(1); + return add(arg3, 2); +} diff --git a/dumps/scripts/5272.cs2 b/dumps/scripts/5272.cs2 new file mode 100644 index 0000000..171d175 --- /dev/null +++ b/dumps/scripts/5272.cs2 @@ -0,0 +1,55 @@ +int script_5272(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + ivar3 = 0; + arg2 = divide(arg2, 2); + ivar4 = arg2; + ivar5 = getWidgetActualHeight(new WidgetPointer(arg0)); + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + if (getWidgetActualWidth(new WidgetPointer(arg0)) < 260) { + if (arg2 == 4) { + setWidgetFont(494); + } else if (((boolean)arg2)) { + setWidgetFont(496); + } else { + setWidgetFont(495); + } + } else if (arg2 >= 7) { + setWidgetFont(494); + } else if (arg2 <= 4) { + setWidgetFont(496); + } else { + setWidgetFont(495); + } + if (arg2 > 4) { + ivar4 = script_5276(arg2, 2); + ivar3 = divide(multiply(divide(arg1, 4), ivar5), ivar4); + if (((boolean)mod(divide(arg1, 2), 2))) { + setWidgetPosition(2, ivar3, 0, 0); + } else { + setWidgetPosition(2, ivar3, 2, 0); + } + setWidgetSize(subtract(divide(getWidgetActualWidth(new WidgetPointer(arg0)), 2), 4), divide(ivar5, ivar4), 0, 0); + } else { + ivar3 = divide(multiply(divide(arg1, 2), ivar5), arg2); + setWidgetPosition(2, ivar3, 0, 0); + setWidgetSize(6, divide(ivar5, arg2), 1, 0); + } + } + arg1 = add(arg1, 1); + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + if (arg2 > 4) { + if (((boolean)mod(divide(arg1, 2), 2))) { + setWidgetPosition(2, add(ivar3, 1), 0, 0); + } else { + setWidgetPosition(2, add(ivar3, 1), 2, 0); + } + setWidgetSize(subtract(divide(getWidgetActualWidth(new WidgetPointer(arg0)), 2), 4), subtract(divide(ivar5, ivar4), 2), 0, 0); + } else { + setWidgetPosition(2, add(ivar3, 1), 0, 0); + setWidgetSize(4, subtract(divide(ivar5, arg2), 2), 1, 0); + } + } + return add(arg1, 1); +} diff --git a/dumps/scripts/5273.cs2 b/dumps/scripts/5273.cs2 new file mode 100644 index 0000000..d11fa3e --- /dev/null +++ b/dumps/scripts/5273.cs2 @@ -0,0 +1,8 @@ +void script_5273(int arg0,string arg1) { + setWidgetIsHidden(false, new WidgetPointer(1137,7)); + setWidgetText(new WidgetPointer(1137,10), arg1); + if (setWidgetRegister(new WidgetPointer(1137,7))) { + setWidgetIntegerNode(1103, arg0); + } + return; +} diff --git a/dumps/scripts/5274.cs2 b/dumps/scripts/5274.cs2 new file mode 100644 index 0000000..1cb75f4 --- /dev/null +++ b/dumps/scripts/5274.cs2 @@ -0,0 +1,22 @@ +void script_5274() { + int ivar0; + int stack_dump0; + ivar0 = 0; + if (setWidgetRegister(new WidgetPointer(1137,7))) { + stack_dump0 = 1103; + /* + mgi.tools.jagdecs2.DecompilerException: opcode 1613 not decompileable + at mgi.tools.jagdecs2.FlowBlocksGenerator.analyzeSpecialCall(FlowBlocksGenerator.java:297) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processFlowBlock(FlowBlocksGenerator.java:249) + at mgi.tools.jagdecs2.FlowBlocksGenerator.processGeneration(FlowBlocksGenerator.java:52) + at mgi.tools.jagdecs2.FlowBlocksGenerator.generate(FlowBlocksGenerator.java:35) + at mgi.tools.jagdecs2.CS2Decompiler.decompile(CS2Decompiler.java:40) + at tests.Main.main(Main.java:45) + + */ + } + if (((boolean)ivar0)) { + setWidgetIsHidden(true, new WidgetPointer(1137,7)); + } + return; +} diff --git a/dumps/scripts/5275.cs2 b/dumps/scripts/5275.cs2 new file mode 100644 index 0000000..43cc00c --- /dev/null +++ b/dumps/scripts/5275.cs2 @@ -0,0 +1,147 @@ +void script_5275(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + string svar0; + int stack_dump0; + int stack_dump1; + int stack_dump2; + cs2func_script_788_struct(2,0,0) structdump_3; + cs2func_script_788_struct(2,0,0) structdump_4; + ivar1 = 0; + ivar2 = -1; + ivar3 = -1; + ivar4 = 1; + svar0 = ""; + ivar5 = -1; + ivar6 = -1; + ivar7 = -1; + ivar8 = -1; + switch (bitconfig_9828) { + case 0: + return; + case 1: + ivar5 = 52948; + ivar6 = 808; + ivar7 = 5138; + ivar8 = 5139; + break; + case 2: + ivar5 = 52954; + ivar6 = 808; + ivar7 = 5134; + ivar8 = 5135; + break; + case 3: + ivar5 = 52984; + ivar6 = 808; + ivar7 = 5136; + ivar8 = 5137; + } + deleteAllExtraChilds(new WidgetPointer(1138,5)); + createExtraChild(new WidgetPointer(1138,5), 6, getExtraChildGap(new WidgetPointer(1138,5))); + setWidgetSize(0, 0, 1, 1); + setWidgetPosition(0, 0, 1, 1); + setWidgetModel(ivar5); + setWidget3DRotation(0, 125, 0, 0, 0, 375); + setWidgetAnimation(ivar6); + script_2647(74579973); + deleteAllExtraChilds(new WidgetPointer(1138,7)); + while (ivar1 < getItemContainerLength(94)) { + ivar4 = 1; + switch (ivar1) { + case 0: + ivar2 = 74579981; + break; + case 1: + ivar2 = 74579983; + break; + case 2: + ivar2 = 74579984; + break; + case 3: + ivar2 = 74579986; + break; + case 4: + ivar2 = 74579987; + break; + case 5: + ivar2 = 74579988; + break; + case 7: + ivar2 = 74579989; + break; + case 9: + ivar2 = 74579991; + break; + case 10: + ivar2 = 74579990; + break; + case 12: + ivar2 = 74579992; + break; + case 13: + ivar2 = 74579985; + ivar4 = 900; + break; + case 14: + ivar2 = 74579982; + break; + default: + ivar2 = -1; + } + createExtraChild(new WidgetPointer(1138,7), 5, ivar1); + if (ivar2 != -1) { + ivar3 = cs2method_3408(105, 111, ivar8, ivar1); + if (ivar3 != -1) { + setWidgetSize(36, 32, 0, 0); + stack_dump0 = ivar2; + stack_dump1 = 2; + stack_dump2 = 2; + structdump_3 = script_788(stack_dump0, stack_dump1, stack_dump2); + setWidgetPosition(structdump_3.intpart_0, structdump_3.intpart_1, 0, 0); + setItemOnWidgetMethod1200(ivar3, ivar4); + cs2method1305(concat("", getItemName(ivar3))); + setWidgetContextMenuOption(1, "Information"); + setWidgetShadowColor(new Color(48, 32, 32)); + setWidgetBorderThickness(1); + setScriptCallOnClickContextMenu(1620, new WidgetPointer(-32768,3), -2147483643, 100, 0, 8, "Iiiii"); + } else { + setWidgetSize(32, 32, 0, 0); + stack_dump0 = ivar2; + stack_dump1 = 2; + stack_dump2 = 2; + structdump_4 = script_788(stack_dump0, stack_dump1, stack_dump2); + setWidgetPosition(structdump_4.intpart_0, structdump_4.intpart_1, 0, 0); + setWidgetSprite(cs2method_3408(105, 100, 796, ivar1)); + } + } else { + setWidgetHidden(1); + } + ivar1 = add(ivar1, 1); + } + setWidgetText(new WidgetPointer(1138,29), concatSignedInt(cs2method_3408(105, 105, ivar7, 0), "Stab: ")); + setWidgetText(new WidgetPointer(1138,30), concatSignedInt(cs2method_3408(105, 105, ivar7, 1), "Slash: ")); + setWidgetText(new WidgetPointer(1138,31), concatSignedInt(cs2method_3408(105, 105, ivar7, 2), "Crush: ")); + setWidgetText(new WidgetPointer(1138,32), concatSignedInt(cs2method_3408(105, 105, ivar7, 3), "Magic: ")); + setWidgetText(new WidgetPointer(1138,33), concatSignedInt(cs2method_3408(105, 105, ivar7, 4), "Ranged: ")); + setWidgetText(new WidgetPointer(1138,34), concatSignedInt(cs2method_3408(105, 105, ivar7, 5), "Stab: ")); + setWidgetText(new WidgetPointer(1138,35), concatSignedInt(cs2method_3408(105, 105, ivar7, 6), "Slash: ")); + setWidgetText(new WidgetPointer(1138,36), concatSignedInt(cs2method_3408(105, 105, ivar7, 7), "Crush: ")); + setWidgetText(new WidgetPointer(1138,38), concatSignedInt(cs2method_3408(105, 105, ivar7, 9), "Ranged: ")); + setWidgetText(new WidgetPointer(1138,39), concatSignedInt(cs2method_3408(105, 105, ivar7, 10), "Summoning: ")); + setWidgetText(new WidgetPointer(1138,37), concatSignedInt(cs2method_3408(105, 105, ivar7, 8), "Magic: ")); + setWidgetText(new WidgetPointer(1138,40), concat(concatSignedInt(cs2method_3408(105, 105, ivar7, 11), "Absorb Melee: "), "%")); + setWidgetText(new WidgetPointer(1138,41), concat(concatSignedInt(cs2method_3408(105, 105, ivar7, 12), "Absorb Magic: "), "%")); + setWidgetText(new WidgetPointer(1138,42), concat(concatSignedInt(cs2method_3408(105, 105, ivar7, 13), "Absorb Ranged: "), "%")); + setWidgetText(new WidgetPointer(1138,43), concatSignedInt(cs2method_3408(105, 105, ivar7, 14), "Strength: ")); + setWidgetText(new WidgetPointer(1138,44), concatSignedInt(cs2method_3408(105, 105, ivar7, 15), "Ranged Strength: ")); + setWidgetText(new WidgetPointer(1138,45), concatSignedInt(cs2method_3408(105, 105, ivar7, 16), "Prayer: ")); + setWidgetText(new WidgetPointer(1138,46), concat(concatSignedInt(cs2method_3408(105, 105, ivar7, 17), "Magic Damage: "), "%")); + return; +} diff --git a/dumps/scripts/5276.cs2 b/dumps/scripts/5276.cs2 new file mode 100644 index 0000000..f534785 --- /dev/null +++ b/dumps/scripts/5276.cs2 @@ -0,0 +1,6 @@ +int script_5276(int arg0,int arg1) { + if (mod(arg0, arg1) > 0) { + return add(divide(arg0, arg1), 1); + } + return divide(arg0, arg1); +} diff --git a/dumps/scripts/5277.cs2 b/dumps/scripts/5277.cs2 new file mode 100644 index 0000000..2df4dd2 --- /dev/null +++ b/dumps/scripts/5277.cs2 @@ -0,0 +1,7 @@ +void script_5277(int arg0) { + script_5279(arg0); + setScriptCallOnConfigChange(5278, new WidgetPointer(arg0), 1734, 1, "IY", new WidgetPointer(arg0)); + script_5291(); + setScriptCallOnConfigChange(5290, 2387, 1, "Y", new WidgetPointer(getWidgetParentId(new WidgetPointer(arg0)))); + return; +} diff --git a/dumps/scripts/5278.cs2 b/dumps/scripts/5278.cs2 new file mode 100644 index 0000000..495f5fa --- /dev/null +++ b/dumps/scripts/5278.cs2 @@ -0,0 +1,4 @@ +void script_5278(int arg0) { + script_5279(arg0); + return; +} diff --git a/dumps/scripts/5279.cs2 b/dumps/scripts/5279.cs2 new file mode 100644 index 0000000..78c87b6 --- /dev/null +++ b/dumps/scripts/5279.cs2 @@ -0,0 +1,55 @@ +void script_5279(int arg0) { + int ivar1; + ivar1 = script_734(bitconfig_9897); + setWidgetIsHidden(((boolean)ivar1), new WidgetPointer(388,17)); + setWidgetIsHidden(((boolean)ivar1), new WidgetPointer(388,30)); + setWidgetIsHidden(((boolean)ivar1), new WidgetPointer(388,43)); + setWidgetIsHidden(((boolean)ivar1), new WidgetPointer(388,56)); + setWidgetIsHidden(((boolean)ivar1), new WidgetPointer(388,69)); + setWidgetIsHidden(((boolean)ivar1), new WidgetPointer(388,107)); + setWidgetIsHidden(((boolean)ivar1), new WidgetPointer(388,121)); + setWidgetIsHidden(((boolean)ivar1), new WidgetPointer(388,135)); + setWidgetIsHidden(((boolean)ivar1), new WidgetPointer(388,148)); + setWidgetIsHidden(((boolean)ivar1), new WidgetPointer(388,163)); + setWidgetIsHidden(((boolean)ivar1), new WidgetPointer(388,177)); + setWidgetIsHidden(((boolean)ivar1), new WidgetPointer(388,191)); + setWidgetIsHidden(((boolean)ivar1), new WidgetPointer(388,205)); + setWidgetIsHidden(((boolean)ivar1), new WidgetPointer(388,90)); + if (((boolean)ivar1)) { + setWidgetText(new WidgetPointer(arg0), "Theatre Options"); + setScriptCallOnClickContextMenu(5293, -2147483644, 1, 0, "ii1", new WidgetPointer(388,104)); + setScriptCallOnClickContextMenu(5293, -2147483644, 2, 0, "ii1", new WidgetPointer(388,117)); + setScriptCallOnClickContextMenu(5293, -2147483644, 3, 0, "ii1", new WidgetPointer(388,131)); + setScriptCallOnClickContextMenu(5293, -2147483644, 4, 0, "ii1", new WidgetPointer(388,145)); + setScriptCallOnClickContextMenu(5293, -2147483644, 5, 0, "ii1", new WidgetPointer(388,159)); + setScriptCallOnClickContextMenu(5293, -2147483644, 6, 0, "ii1", new WidgetPointer(388,173)); + setScriptCallOnClickContextMenu(5293, -2147483644, 7, 0, "ii1", new WidgetPointer(388,187)); + setScriptCallOnClickContextMenu(5293, -2147483644, 8, 0, "ii1", new WidgetPointer(388,201)); + setScriptCallOnClickContextMenu(5293, -2147483644, 1, 1, "ii1", new WidgetPointer(388,14)); + setScriptCallOnClickContextMenu(5293, -2147483644, 2, 1, "ii1", new WidgetPointer(388,27)); + setScriptCallOnClickContextMenu(5293, -2147483644, 3, 1, "ii1", new WidgetPointer(388,40)); + setScriptCallOnClickContextMenu(5293, -2147483644, 4, 1, "ii1", new WidgetPointer(388,53)); + setScriptCallOnClickContextMenu(5293, -2147483644, 5, 1, "ii1", new WidgetPointer(388,66)); + } else { + if (((boolean)bitconfig_9887) || ((boolean)bitconfig_9896)) { + setWidgetText(new WidgetPointer(arg0), "Waiting on technician to select options..."); + } else { + setWidgetText(new WidgetPointer(arg0), "Waiting on technician to unlock theatre..."); + } + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(388,104)); + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(388,117)); + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(388,131)); + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(388,145)); + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(388,159)); + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(388,173)); + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(388,187)); + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(388,201)); + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(388,14)); + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(388,27)); + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(388,40)); + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(388,53)); + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(388,66)); + } + script_4532(arg0); + return; +} diff --git a/dumps/scripts/528.cs2 b/dumps/scripts/528.cs2 new file mode 100644 index 0000000..8c3697d --- /dev/null +++ b/dumps/scripts/528.cs2 @@ -0,0 +1,10 @@ +void script_528(int arg0,int arg1,int arg2,int arg3,int arg4) { + if (((boolean)arg0)) { + setWidgetSprite(arg1, new WidgetPointer(arg3)); + setWidgetIsHidden(false, new WidgetPointer(arg4)); + } else { + setWidgetSprite(arg2, new WidgetPointer(arg3)); + setWidgetIsHidden(true, new WidgetPointer(arg4)); + } + return; +} diff --git a/dumps/scripts/5280.cs2 b/dumps/scripts/5280.cs2 new file mode 100644 index 0000000..00f0b17 --- /dev/null +++ b/dumps/scripts/5280.cs2 @@ -0,0 +1,15 @@ +int script_5280() { + if (isWidgetOpen(new WidgetPointer(906,80))) { + return 1; + } + if (isWidgetOpen(new WidgetPointer(906,54))) { + return 1; + } + if (isWidgetOpen(new WidgetPointer(906,72))) { + return 1; + } + if (isWidgetOpen(new WidgetPointer(906,64))) { + return 1; + } + return 0; +} diff --git a/dumps/scripts/5281.cs2 b/dumps/scripts/5281.cs2 new file mode 100644 index 0000000..893110b --- /dev/null +++ b/dumps/scripts/5281.cs2 @@ -0,0 +1,11 @@ +void script_5281() { + playSoundEffect2False(7536, 1, 0, 200, cs2method_4019(20, 20)); + if (isWidgetHidden(new WidgetPointer(1141,3))) { + setWidgetIsHidden(false, new WidgetPointer(1141,3)); + setWidgetIsHidden(true, new WidgetPointer(1141,4)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1141,3)); + setWidgetIsHidden(false, new WidgetPointer(1141,4)); + } + return; +} diff --git a/dumps/scripts/5282.cs2 b/dumps/scripts/5282.cs2 new file mode 100644 index 0000000..ebc85e2 --- /dev/null +++ b/dumps/scripts/5282.cs2 @@ -0,0 +1,8 @@ +void script_5282() { + if (getWidgetActualX(new WidgetPointer(555,48)) > 29) { + playSoundEffect2False(7557, 1, 0, 200, cs2method_4019(20, 20)); + setWidgetPosition(subtract(getWidgetActualX(new WidgetPointer(555,48)), 10), getWidgetActualY(new WidgetPointer(555,48)), 0, 0, new WidgetPointer(555,48)); + setWidgetPosition(subtract(getWidgetActualX(new WidgetPointer(555,49)), 10), getWidgetActualY(new WidgetPointer(555,49)), 0, 0, new WidgetPointer(555,49)); + } + return; +} diff --git a/dumps/scripts/5283.cs2 b/dumps/scripts/5283.cs2 new file mode 100644 index 0000000..d9ef90a --- /dev/null +++ b/dumps/scripts/5283.cs2 @@ -0,0 +1,8 @@ +void script_5283() { + if (getWidgetActualX(new WidgetPointer(555,48)) < 455) { + playSoundEffect2False(7557, 1, 0, 200, cs2method_4019(20, 20)); + setWidgetPosition(add(getWidgetActualX(new WidgetPointer(555,48)), 10), getWidgetActualY(new WidgetPointer(555,48)), 0, 0, new WidgetPointer(555,48)); + setWidgetPosition(add(getWidgetActualX(new WidgetPointer(555,49)), 10), getWidgetActualY(new WidgetPointer(555,49)), 0, 0, new WidgetPointer(555,49)); + } + return; +} diff --git a/dumps/scripts/5284.cs2 b/dumps/scripts/5284.cs2 new file mode 100644 index 0000000..4783fd6 --- /dev/null +++ b/dumps/scripts/5284.cs2 @@ -0,0 +1,8 @@ +void script_5284() { + if (getWidgetActualY(new WidgetPointer(555,48)) > -86) { + playSoundEffect2False(7557, 1, 0, 200, cs2method_4019(20, 20)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(555,48)), subtract(getWidgetActualY(new WidgetPointer(555,48)), 10), 0, 0, new WidgetPointer(555,48)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(555,49)), subtract(getWidgetActualY(new WidgetPointer(555,49)), 10), 0, 0, new WidgetPointer(555,49)); + } + return; +} diff --git a/dumps/scripts/5285.cs2 b/dumps/scripts/5285.cs2 new file mode 100644 index 0000000..cba89e2 --- /dev/null +++ b/dumps/scripts/5285.cs2 @@ -0,0 +1,8 @@ +void script_5285() { + if (getWidgetActualY(new WidgetPointer(555,48)) < 170) { + playSoundEffect2False(7557, 1, 0, 200, cs2method_4019(20, 20)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(555,48)), add(getWidgetActualY(new WidgetPointer(555,48)), 10), 0, 0, new WidgetPointer(555,48)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(555,49)), add(getWidgetActualY(new WidgetPointer(555,49)), 10), 0, 0, new WidgetPointer(555,49)); + } + return; +} diff --git a/dumps/scripts/5286.cs2 b/dumps/scripts/5286.cs2 new file mode 100644 index 0000000..17c9e39 --- /dev/null +++ b/dumps/scripts/5286.cs2 @@ -0,0 +1,11 @@ +void script_5286() { + playSoundEffect2False(7536, 1, 0, 200, cs2method_4019(20, 20)); + if (isWidgetHidden(new WidgetPointer(555,48))) { + setWidgetIsHidden(false, new WidgetPointer(555,48)); + setWidgetIsHidden(true, new WidgetPointer(555,49)); + } else { + setWidgetIsHidden(false, new WidgetPointer(555,49)); + setWidgetIsHidden(true, new WidgetPointer(555,48)); + } + return; +} diff --git a/dumps/scripts/5287.cs2 b/dumps/scripts/5287.cs2 new file mode 100644 index 0000000..14141e9 --- /dev/null +++ b/dumps/scripts/5287.cs2 @@ -0,0 +1,24 @@ +void script_5287() { + playSoundEffect2False(7513, 1, 0, 200, cs2method_4019(20, 20)); + if (cs2method2613(new WidgetPointer(555,48)) == 32768) { + cs2method2106(49152, new WidgetPointer(555,49)); + cs2method2106(49152, new WidgetPointer(555,48)); + return; + } + if (cs2method2613(new WidgetPointer(555,48)) == 16384) { + cs2method2106(32768, new WidgetPointer(555,49)); + cs2method2106(32768, new WidgetPointer(555,48)); + return; + } + if (((boolean)cs2method2613(new WidgetPointer(555,48)))) { + cs2method2106(16384, new WidgetPointer(555,49)); + cs2method2106(16384, new WidgetPointer(555,48)); + return; + } + if (cs2method2613(new WidgetPointer(555,48)) == 49152) { + cs2method2106(0, new WidgetPointer(555,49)); + cs2method2106(0, new WidgetPointer(555,48)); + return; + } + return; +} diff --git a/dumps/scripts/5288.cs2 b/dumps/scripts/5288.cs2 new file mode 100644 index 0000000..082e673 --- /dev/null +++ b/dumps/scripts/5288.cs2 @@ -0,0 +1,24 @@ +void script_5288() { + playSoundEffect2False(7513, 1, 0, 200, cs2method_4019(20, 20)); + if (((boolean)cs2method2613(new WidgetPointer(555,48)))) { + cs2method2106(49152, new WidgetPointer(555,49)); + cs2method2106(49152, new WidgetPointer(555,48)); + return; + } + if (cs2method2613(new WidgetPointer(555,48)) == 49152) { + cs2method2106(32768, new WidgetPointer(555,49)); + cs2method2106(32768, new WidgetPointer(555,48)); + return; + } + if (cs2method2613(new WidgetPointer(555,48)) == 32768) { + cs2method2106(16384, new WidgetPointer(555,49)); + cs2method2106(16384, new WidgetPointer(555,48)); + return; + } + if (cs2method2613(new WidgetPointer(555,48)) == 16384) { + cs2method2106(0, new WidgetPointer(555,49)); + cs2method2106(0, new WidgetPointer(555,48)); + return; + } + return; +} diff --git a/dumps/scripts/5289.cs2 b/dumps/scripts/5289.cs2 new file mode 100644 index 0000000..1fd3756 --- /dev/null +++ b/dumps/scripts/5289.cs2 @@ -0,0 +1,5 @@ +void script_5289() { + playSoundEffect2False(7557, 1, 0, 200, cs2method_4019(20, 20)); + script_675(); + return; +} diff --git a/dumps/scripts/529.cs2 b/dumps/scripts/529.cs2 new file mode 100644 index 0000000..01a01fe --- /dev/null +++ b/dumps/scripts/529.cs2 @@ -0,0 +1,27 @@ +void script_529(int arg0) { + int ivar1; + string svar0; + string svar1; + int stack_dump0; + cs2func_script_530_struct(1,1,0) structdump_1; + svar0 = "null"; + ivar1 = 0; + svar1 = "null"; + if (arg0 == 19726347) { + svar0 = "This is the total XP you have gained through the Assist System in the past 24 hours. There is a limit to the XP you can gain within 24 hours, but this amount gets reset once the day has passed."; + script_39(arg0, 19726421, 25, 180, svar0); + return; + } + stack_dump0 = arg0; + structdump_1 = script_530(stack_dump0); + svar1 = structdump_1.stringpart_0; + ivar1 = structdump_1.intpart_0; + if (((boolean)ivar1)) { + svar0 = "Assist with " + svar1 + " while using the Assist System (ON)."; + } else { + svar0 = "Assist with " + svar1 + " while using the Assist System (OFF)."; + } + script_39(arg0, 19726421, 25, 180, svar0); + globalint_2 = 0; + return; +} diff --git a/dumps/scripts/5290.cs2 b/dumps/scripts/5290.cs2 new file mode 100644 index 0000000..9c9c8d6 --- /dev/null +++ b/dumps/scripts/5290.cs2 @@ -0,0 +1,4 @@ +void script_5290() { + script_5291(); + return; +} diff --git a/dumps/scripts/5291.cs2 b/dumps/scripts/5291.cs2 new file mode 100644 index 0000000..6c9a2c6 --- /dev/null +++ b/dumps/scripts/5291.cs2 @@ -0,0 +1,16 @@ +void script_5291() { + script_5292(bitconfig_9887, 1, 25428071); + script_5292(bitconfig_9887, 2, 25428084); + script_5292(bitconfig_9887, 3, 25428098); + script_5292(bitconfig_9887, 4, 25428112); + script_5292(bitconfig_9887, 5, 25428126); + script_5292(bitconfig_9887, 6, 25428140); + script_5292(bitconfig_9887, 7, 25428154); + script_5292(bitconfig_9887, 8, 25428168); + script_5292(bitconfig_9896, 1, 25427981); + script_5292(bitconfig_9896, 2, 25427994); + script_5292(bitconfig_9896, 3, 25428007); + script_5292(bitconfig_9896, 4, 25428020); + script_5292(bitconfig_9896, 5, 25428033); + return; +} diff --git a/dumps/scripts/5292.cs2 b/dumps/scripts/5292.cs2 new file mode 100644 index 0000000..8c2715c --- /dev/null +++ b/dumps/scripts/5292.cs2 @@ -0,0 +1,8 @@ +void script_5292(int arg0,int arg1,int arg2) { + if (arg0 == arg1) { + setWidgetIsHidden(false, new WidgetPointer(arg2)); + } else { + setWidgetIsHidden(true, new WidgetPointer(arg2)); + } + return; +} diff --git a/dumps/scripts/5293.cs2 b/dumps/scripts/5293.cs2 new file mode 100644 index 0000000..0f94d58 --- /dev/null +++ b/dumps/scripts/5293.cs2 @@ -0,0 +1,13 @@ +void script_5293(int arg0,int arg1,int arg2) { + if (arg0 != 1) { + return; + } + playSoundEffect2False(6185, 1, 0, 200); + if (((boolean)arg2)) { + bitconfig_9896 = arg1; + } else { + bitconfig_9887 = arg1; + } + script_5291(); + return; +} diff --git a/dumps/scripts/5294.cs2 b/dumps/scripts/5294.cs2 new file mode 100644 index 0000000..41d67d4 --- /dev/null +++ b/dumps/scripts/5294.cs2 @@ -0,0 +1,5 @@ +void script_5294(int arg0,int arg1) { + setWidgetIsHidden(false, new WidgetPointer(arg1)); + setScriptCallOnUseWith(5295, new WidgetPointer(arg0), new WidgetPointer(arg1), "II", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/5295.cs2 b/dumps/scripts/5295.cs2 new file mode 100644 index 0000000..f48de50 --- /dev/null +++ b/dumps/scripts/5295.cs2 @@ -0,0 +1,5 @@ +void script_5295(int arg0,int arg1) { + setWidgetIsHidden(true, new WidgetPointer(arg1)); + setScriptCallOnUseWith(-1, "", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/5296.cs2 b/dumps/scripts/5296.cs2 new file mode 100644 index 0000000..9845306 --- /dev/null +++ b/dumps/scripts/5296.cs2 @@ -0,0 +1,9 @@ +void script_5296() { + if (((boolean)bitconfig_9888)) { + bitconfig_9888 = 0; + } else { + bitconfig_9888 = 1; + } + script_5301(); + return; +} diff --git a/dumps/scripts/5297.cs2 b/dumps/scripts/5297.cs2 new file mode 100644 index 0000000..1087a95 --- /dev/null +++ b/dumps/scripts/5297.cs2 @@ -0,0 +1,9 @@ +void script_5297() { + if (((boolean)bitconfig_9889)) { + bitconfig_9889 = 0; + } else { + bitconfig_9889 = 1; + } + script_5301(); + return; +} diff --git a/dumps/scripts/5298.cs2 b/dumps/scripts/5298.cs2 new file mode 100644 index 0000000..67966d5 --- /dev/null +++ b/dumps/scripts/5298.cs2 @@ -0,0 +1,9 @@ +void script_5298() { + if (((boolean)bitconfig_9890)) { + bitconfig_9890 = 0; + } else { + bitconfig_9890 = 1; + } + script_5301(); + return; +} diff --git a/dumps/scripts/5299.cs2 b/dumps/scripts/5299.cs2 new file mode 100644 index 0000000..b62e091 --- /dev/null +++ b/dumps/scripts/5299.cs2 @@ -0,0 +1,9 @@ +void script_5299() { + if (((boolean)bitconfig_9891)) { + bitconfig_9891 = 0; + } else { + bitconfig_9891 = 1; + } + script_5301(); + return; +} diff --git a/dumps/scripts/53.cs2 b/dumps/scripts/53.cs2 new file mode 100644 index 0000000..fbc4bde --- /dev/null +++ b/dumps/scripts/53.cs2 @@ -0,0 +1,8 @@ +void script_53(int arg0,int arg1,int arg2) { + setWidgetText(new WidgetPointer(arg0), intToStr(script_5256()) + " / " + intToStr(script_5255())); + setWidgetSize(getTextWidth(495, getWidgetText(new WidgetPointer(arg0))), getWidgetActualHeight(new WidgetPointer(arg0)), 0, 0, new WidgetPointer(arg0)); + if (((boolean)arg2)) { + script_5264(arg0, arg1); + } + return; +} diff --git a/dumps/scripts/530.cs2 b/dumps/scripts/530.cs2 new file mode 100644 index 0000000..df46f88 --- /dev/null +++ b/dumps/scripts/530.cs2 @@ -0,0 +1,30 @@ +cs2func_script_530_struct(1,1,0) script_530(int arg0) { + if (arg0 == 19726410) { + return newstruct cs2func_script_530_struct(bitconfig_4090, "Runecrafting"); + } + if (arg0 == 19726411) { + return newstruct cs2func_script_530_struct(bitconfig_4091, "Crafting"); + } + if (arg0 == 19726412) { + return newstruct cs2func_script_530_struct(bitconfig_4093, "Fletching"); + } + if (arg0 == 19726413) { + return newstruct cs2func_script_530_struct(bitconfig_4095, "Construction"); + } + if (arg0 == 19726414) { + return newstruct cs2func_script_530_struct(bitconfig_4096, "Farming"); + } + if (arg0 == 19726415) { + return newstruct cs2func_script_530_struct(bitconfig_4098, "Magic"); + } + if (arg0 == 19726416) { + return newstruct cs2func_script_530_struct(bitconfig_4100, "Smithing"); + } + if (arg0 == 19726417) { + return newstruct cs2func_script_530_struct(bitconfig_4101, "Cooking"); + } + if (arg0 == 19726418) { + return newstruct cs2func_script_530_struct(bitconfig_4102, "Herblore"); + } + return newstruct cs2func_script_530_struct(0, ""); +} diff --git a/dumps/scripts/5300.cs2 b/dumps/scripts/5300.cs2 new file mode 100644 index 0000000..97781d4 --- /dev/null +++ b/dumps/scripts/5300.cs2 @@ -0,0 +1,4 @@ +void script_5300() { + script_5301(); + return; +} diff --git a/dumps/scripts/5301.cs2 b/dumps/scripts/5301.cs2 new file mode 100644 index 0000000..2b22ab1 --- /dev/null +++ b/dumps/scripts/5301.cs2 @@ -0,0 +1,31 @@ +void script_5301() { + if (((boolean)bitconfig_9888)) { + setWidgetRGB(new Color(170, 170, 0), new WidgetPointer(824,13)); + setWidgetText(new WidgetPointer(824,59), "On"); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(824,13)); + setWidgetText(new WidgetPointer(824,59), "Off"); + } + if (((boolean)bitconfig_9889)) { + setWidgetRGB(new Color(170, 170, 0), new WidgetPointer(824,100)); + setWidgetText(new WidgetPointer(824,101), "On"); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(824,100)); + setWidgetText(new WidgetPointer(824,101), "Off"); + } + if (((boolean)bitconfig_9890)) { + setWidgetRGB(new Color(170, 170, 0), new WidgetPointer(824,153)); + setWidgetText(new WidgetPointer(824,154), "On"); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(824,153)); + setWidgetText(new WidgetPointer(824,154), "Off"); + } + if (((boolean)bitconfig_9891)) { + setWidgetRGB(new Color(170, 170, 0), new WidgetPointer(824,190)); + setWidgetText(new WidgetPointer(824,191), "On"); + } else { + setWidgetRGB(new Color(0, 0, 0), new WidgetPointer(824,190)); + setWidgetText(new WidgetPointer(824,191), "Off"); + } + return; +} diff --git a/dumps/scripts/5302.cs2 b/dumps/scripts/5302.cs2 new file mode 100644 index 0000000..9ee8a4e --- /dev/null +++ b/dumps/scripts/5302.cs2 @@ -0,0 +1,12 @@ +void script_5302(int arg0,int arg1) { + if (isWidgetHidden(new WidgetPointer(arg0))) { + script_5306(); + setWidgetIsHidden(false, new WidgetPointer(arg0)); + setWidgetSprite(6169, new WidgetPointer(arg1)); + } else { + setWidgetIsHidden(true, new WidgetPointer(arg0)); + setWidgetSprite(6168, new WidgetPointer(arg1)); + script_5219(54001697); + } + return; +} diff --git a/dumps/scripts/5303.cs2 b/dumps/scripts/5303.cs2 new file mode 100644 index 0000000..e9460da --- /dev/null +++ b/dumps/scripts/5303.cs2 @@ -0,0 +1,4 @@ +void script_5303(int arg0) { + setWidgetIsHidden(true, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/5304.cs2 b/dumps/scripts/5304.cs2 new file mode 100644 index 0000000..34e6fde --- /dev/null +++ b/dumps/scripts/5304.cs2 @@ -0,0 +1,86 @@ +void script_5304(int arg0) { + if (arg0 == 54001714) { + switch (bitconfig_9892) { + case 0: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(arg0)); + break; + case 1: + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(arg0)); + break; + case 2: + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(arg0)); + break; + case 3: + setWidgetRGB(new Color(0, 0, 255), new WidgetPointer(arg0)); + break; + case 4: + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(arg0)); + break; + default: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(arg0)); + } + } else if (arg0 == 54001784) { + switch (bitconfig_9893) { + case 0: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(arg0)); + break; + case 1: + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(arg0)); + break; + case 2: + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(arg0)); + break; + case 3: + setWidgetRGB(new Color(0, 0, 255), new WidgetPointer(arg0)); + break; + case 4: + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(arg0)); + break; + default: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(arg0)); + } + } else if (arg0 == 54001837) { + switch (bitconfig_9894) { + case 0: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(arg0)); + break; + case 1: + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(arg0)); + break; + case 2: + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(arg0)); + break; + case 3: + setWidgetRGB(new Color(0, 0, 255), new WidgetPointer(arg0)); + break; + case 4: + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(arg0)); + break; + default: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(arg0)); + } + } else { + if (arg0 == 54001874) { + switch (bitconfig_9895) { + case 0: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(arg0)); + break; + case 1: + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(arg0)); + break; + case 2: + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(arg0)); + break; + case 3: + setWidgetRGB(new Color(0, 0, 255), new WidgetPointer(arg0)); + break; + case 4: + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(arg0)); + break; + default: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(arg0)); + } + } + } + return; +} diff --git a/dumps/scripts/5305.cs2 b/dumps/scripts/5305.cs2 new file mode 100644 index 0000000..3d71277 --- /dev/null +++ b/dumps/scripts/5305.cs2 @@ -0,0 +1,4 @@ +void script_5305() { + script_5306(); + return; +} diff --git a/dumps/scripts/5306.cs2 b/dumps/scripts/5306.cs2 new file mode 100644 index 0000000..ddf9584 --- /dev/null +++ b/dumps/scripts/5306.cs2 @@ -0,0 +1,11 @@ +void script_5306() { + setWidgetIsHidden(true, new WidgetPointer(824,8)); + setWidgetSprite(6168, new WidgetPointer(824,74)); + setWidgetIsHidden(true, new WidgetPointer(824,9)); + setWidgetSprite(6168, new WidgetPointer(824,127)); + setWidgetIsHidden(true, new WidgetPointer(824,10)); + setWidgetSprite(6168, new WidgetPointer(824,180)); + setWidgetIsHidden(true, new WidgetPointer(824,11)); + setWidgetSprite(6168, new WidgetPointer(824,217)); + return; +} diff --git a/dumps/scripts/5307.cs2 b/dumps/scripts/5307.cs2 new file mode 100644 index 0000000..a1ea805 --- /dev/null +++ b/dumps/scripts/5307.cs2 @@ -0,0 +1,4 @@ +void script_5307() { + script_5308(); + return; +} diff --git a/dumps/scripts/5308.cs2 b/dumps/scripts/5308.cs2 new file mode 100644 index 0000000..27580ad --- /dev/null +++ b/dumps/scripts/5308.cs2 @@ -0,0 +1,78 @@ +void script_5308() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + string svar0; + ivar0 = 0; + ivar1 = 0; + svar0 = ""; + ivar2 = -1; + ivar3 = 0; + ivar4 = 7287; + ivar5 = 7706; + ivar6 = 7289; + ivar7 = 2; + ivar8 = 54; + deleteAllExtraChilds(new WidgetPointer(823,3)); + deleteAllExtraChilds(new WidgetPointer(823,4)); + while (ivar0 < getCommonDefinitionSize(840)) { + ivar3 = cs2method_3408(105, 105, 840, ivar0); + ivar2 = cs2method_3408(105, 74, 5173, ivar3); + if (ivar2 == -1) { + return; + } + svar0 = getOtherCommonData(ivar2, 1974) + "
" + getOtherCommonData(ivar2, 1975); + createExtraChild(new WidgetPointer(823,3), 5, ivar0); + setWidgetSprite(ivar4); + setWidgetSize(ivar8, ivar8, 0, 0); + if (((boolean)mod(ivar0, 3))) { + setWidgetPosition(ivar7, add(ivar7, multiply(ivar1, add(54, ivar7))), 0, 0); + } else if (((boolean)mod(ivar0, 3))) { + setWidgetPosition(add(multiply(ivar7, 2), ivar8), add(ivar7, multiply(ivar1, add(54, ivar7))), 0, 0); + } else { + setWidgetPosition(add(multiply(ivar7, 3), multiply(ivar8, 2)), add(ivar7, multiply(ivar1, add(54, ivar7))), 0, 0); + } + if (((boolean)ivar3)) { + setWidgetContextMenuOption(1, getOtherCommonData(ivar2, 1974)); + } else { + setScriptCallOnUse(5309, -2147483643, "i"); + setScriptCallOnUseWith(44, new WidgetPointer(-32768,3), ivar4, "Id"); + if (((boolean)ivar3)) { + cs2method1306(getOtherCommonData(ivar2, 1974)); + } else if (ivar3 == 2) { + cs2method1306(getOtherCommonData(ivar2, 1974)); + } else { + cs2method1306("Place " + getOtherCommonData(ivar2, 1974)); + } + cs2method1308(176, -1); + } + setScriptCallOnMouseEntered(44, new WidgetPointer(-32768,3), ivar5, "Id"); + setScriptCallOnMouseOver(5334, new WidgetPointer(823,3), ivar0, new WidgetPointer(823,15), svar0, 20, 200, "IiIsii"); + setScriptCallOnMouseExit(299, new WidgetPointer(823,15), new WidgetPointer(-32768,3), ivar4, "IId"); + createExtraChild(new WidgetPointer(823,4), 5, ivar0); + setWidgetSprite(getOtherCommonData(ivar2, 1983)); + setWidgetSize(50, 50, 0, 0); + if (((boolean)mod(ivar0, 3))) { + setWidgetPosition(add(ivar7, 2), add(add(2, ivar7), multiply(ivar1, add(54, ivar7))), 0, 0); + } else if (((boolean)mod(ivar0, 3))) { + setWidgetPosition(add(2, add(multiply(ivar7, 2), ivar8)), add(add(2, ivar7), multiply(ivar1, add(54, ivar7))), 0, 0); + } else { + setWidgetPosition(add(2, add(multiply(ivar7, 3), multiply(ivar8, 2))), add(add(2, ivar7), multiply(ivar1, add(54, ivar7))), 0, 0); + } + if (mod(ivar0, 3) == 2) { + ivar1 = add(ivar1, 1); + } + ivar0 = add(ivar0, 1); + } + ivar1 = add(ivar1, 1); + cs2method2100(0, 0, new WidgetPointer(823,9)); + setWidgetScrollMax(0, add(ivar7, multiply(ivar1, add(54, ivar7))), new WidgetPointer(823,9)); + script_31(53936138, 53936137, 6507, 6504, 6505, 6506, 6499, 6498); + return; +} diff --git a/dumps/scripts/5309.cs2 b/dumps/scripts/5309.cs2 new file mode 100644 index 0000000..1707a70 --- /dev/null +++ b/dumps/scripts/5309.cs2 @@ -0,0 +1,21 @@ +void script_5309(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + ivar1 = 7287; + ivar2 = 7706; + ivar3 = 7289; + ivar4 = 0; + while (ivar4 < getCommonDefinitionSize(840)) { + if (setWidgetRegister(new WidgetPointer(823,3), ivar4)) { + if (ivar4 != arg0) { + setWidgetSprite(ivar1); + } else { + setWidgetSprite(ivar1); + } + } + ivar4 = add(ivar4, 1); + } + return; +} diff --git a/dumps/scripts/531.cs2 b/dumps/scripts/531.cs2 new file mode 100644 index 0000000..dd352f4 --- /dev/null +++ b/dumps/scripts/531.cs2 @@ -0,0 +1,76 @@ +void script_531(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + ivar4 = -1; + ivar5 = 0; + ivar6 = -1; + ivar7 = -1; + ivar8 = -1; + ivar9 = 0; + if (((arg0 == -1) || (arg1 == -1)) || (arg2 == -1)) { + return; + } + if (arg0 == 19726399) { + ivar5 = script_543(bitconfig_4090); + ivar7 = 19726381; + ivar8 = 19726382; + } + if (arg0 == 19726400) { + ivar5 = script_543(bitconfig_4091); + ivar7 = 19726383; + ivar8 = 19726384; + } + if (arg0 == 19726401) { + ivar5 = script_543(bitconfig_4093); + ivar7 = 19726385; + ivar8 = 19726386; + } + if (arg0 == 19726402) { + ivar5 = script_543(bitconfig_4095); + ivar7 = 19726387; + ivar8 = 19726388; + } + if (arg0 == 19726403) { + ivar5 = script_543(bitconfig_4096); + ivar7 = 19726389; + ivar8 = 19726390; + } + if (arg0 == 19726404) { + ivar5 = script_543(bitconfig_4098); + ivar7 = 19726391; + ivar8 = 19726392; + } + if (arg0 == 19726405) { + ivar5 = script_543(bitconfig_4100); + ivar7 = 19726393; + ivar8 = 19726394; + } + if (arg0 == 19726406) { + ivar5 = script_543(bitconfig_4101); + ivar7 = 19726395; + ivar8 = 19726396; + } + if (arg0 == 19726407) { + ivar5 = script_543(bitconfig_4102); + ivar7 = 19726397; + ivar8 = 19726398; + } + if (((boolean)ivar5)) { + ivar4 = arg1; + ivar9 = 0; + setWidgetRGB(new Color(250, 180, 50), new WidgetPointer(ivar7)); + setWidgetRGB(new Color(250, 180, 50), new WidgetPointer(ivar8)); + } else { + ivar4 = arg2; + ivar9 = 1; + setWidgetRGB(new Color(96, 96, 96), new WidgetPointer(ivar7)); + setWidgetRGB(new Color(96, 96, 96), new WidgetPointer(ivar8)); + } + setWidgetSprite(ivar4, new WidgetPointer(arg0)); + setWidgetIsHidden(((boolean)ivar9), new WidgetPointer(arg3)); + return; +} diff --git a/dumps/scripts/5310.cs2 b/dumps/scripts/5310.cs2 new file mode 100644 index 0000000..0d195af --- /dev/null +++ b/dumps/scripts/5310.cs2 @@ -0,0 +1,4 @@ +void script_5310() { + script_5311(20906006, 20906007, 20906008, 20906009); + return; +} diff --git a/dumps/scripts/5311.cs2 b/dumps/scripts/5311.cs2 new file mode 100644 index 0000000..bc8f97d --- /dev/null +++ b/dumps/scripts/5311.cs2 @@ -0,0 +1,51 @@ +void script_5311(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + ivar4 = 0; + ivar5 = getCommonDefinitionSize(5177); + ivar6 = getCommonDefinitionSize(5176); + globalarray_0 = new int[min(ivar5, ivar6)]; + ivar7 = 0; + while (ivar4 < min(ivar5, ivar6)) { + if (setWidgetRegister(new WidgetPointer(arg1), ivar4) && (strLength(getWidgetText()) > 0)) { + globalarray_0[ivar7] = ivar4; + ivar7 = add(ivar7, 1); + } + ivar4 = add(ivar4, 1); + } + if (ivar7 > 1) { + if (((boolean)globalint_1607)) { + script_4425(0, arg1, 0, subtract(ivar7, 1)); + globalint_1607 = -1; + } else { + script_4424(0, arg1, 0, subtract(ivar7, 1)); + globalint_1607 = 1; + } + } + ivar8 = 15; + ivar4 = 0; + while (ivar4 < ivar7) { + if (setWidgetRegister(new WidgetPointer(arg1), globalarray_0[ivar4])) { + setWidgetPosition(2, multiply(ivar8, ivar4), 0, 0); + if (setWidgetRegister(new WidgetPointer(arg2), globalarray_0[ivar4])) { + setWidgetPosition(140, add(multiply(ivar8, ivar4), 1), 0, 0); + } + if (setWidgetRegister(new WidgetPointer(arg3), globalarray_0[ivar4])) { + setWidgetPosition(152, add(multiply(ivar8, ivar4), 1), 0, 0); + } + if (setWidgetRegister(new WidgetPointer(arg0), globalarray_0[ivar4])) { + setWidgetPosition(0, multiply(ivar8, ivar4), 0, 0); + if (((boolean)mod(ivar4, 2))) { + setWidgetRGB(new Color(34, 34, 34)); + } else { + setWidgetRGB(new Color(17, 17, 17)); + } + } + } + ivar4 = add(ivar4, 1); + } + return; +} diff --git a/dumps/scripts/5312.cs2 b/dumps/scripts/5312.cs2 new file mode 100644 index 0000000..1373405 --- /dev/null +++ b/dumps/scripts/5312.cs2 @@ -0,0 +1,17 @@ +void script_5312(int arg0) { + setWidgetIsHidden(false, new WidgetPointer(319,7)); + setWidgetIsHidden(false, new WidgetPointer(319,8)); + script_5313(20905991, 20906006, 20906007, 20906008, 20906009); + setWidgetIsHidden(false, new WidgetPointer(319,6)); + setWidgetIsHidden(false, new WidgetPointer(319,9)); + script_5315(20905990, 20906002, 20906003, 20906004, 20906005); + setWidgetIsHidden(true, new WidgetPointer(319,6)); + setWidgetIsHidden(true, new WidgetPointer(319,9)); + setWidgetIsHidden(true, new WidgetPointer(319,10)); + setWidgetIsHidden(false, new WidgetPointer(319,12)); + globalint_1607 = -1; + script_5311(20906006, 20906007, 20906008, 20906009); + setWidgetIsHidden(false, new WidgetPointer(319,38)); + setWidgetIsHidden(true, new WidgetPointer(319,30)); + return; +} diff --git a/dumps/scripts/5313.cs2 b/dumps/scripts/5313.cs2 new file mode 100644 index 0000000..77e3f95 --- /dev/null +++ b/dumps/scripts/5313.cs2 @@ -0,0 +1,59 @@ +void script_5313(int arg0,int arg1,int arg2,int arg3,int arg4) { + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + ivar5 = 0; + ivar6 = 15; + ivar7 = getCommonDefinitionSize(5177); + ivar8 = getCommonDefinitionSize(5176); + ivar9 = -1; + deleteAllExtraChilds(new WidgetPointer(arg1)); + deleteAllExtraChilds(new WidgetPointer(arg3)); + deleteAllExtraChilds(new WidgetPointer(arg4)); + deleteAllExtraChilds(new WidgetPointer(arg2)); + while (ivar5 < min(ivar7, ivar8)) { + createExtraChild(new WidgetPointer(arg1), 3, ivar5); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg0)), ivar6, 0, 0); + setWidgetPosition(0, multiply(ivar5, ivar6), 0, 0); + if (((boolean)mod(ivar5, 2))) { + setWidgetRGB(new Color(34, 34, 34)); + } else { + setWidgetRGB(new Color(17, 17, 17)); + } + setWidgetFilled(1); + setWidgetContextMenuOption(1, "Sort"); + createExtraChild(new WidgetPointer(arg3), 5, ivar5); + setWidgetSprite(7712); + setWidgetContextMenuOption(1, "Play"); + setWidgetSize(12, 13, 0, 0); + setWidgetPosition(138, add(1, multiply(ivar5, ivar6)), 0, 0); + ivar9 = 7713; + setScriptCallOnMouseEntered(5336, new WidgetPointer(-32768,3), -2147483643, ivar9, "Iid"); + ivar9 = 7712; + setScriptCallOnMouseExit(5336, new WidgetPointer(-32768,3), -2147483643, ivar9, "Iid"); + createExtraChild(new WidgetPointer(arg4), 5, ivar5); + setWidgetSprite(7715); + setWidgetContextMenuOption(1, "Bookmark"); + setWidgetSize(12, 13, 0, 0); + setWidgetPosition(151, multiply(ivar5, ivar6), 0, 0); + ivar9 = 7716; + setScriptCallOnMouseEntered(5336, new WidgetPointer(-32768,3), -2147483643, ivar9, "Iid"); + ivar9 = 7715; + setScriptCallOnMouseExit(5336, new WidgetPointer(-32768,3), -2147483643, ivar9, "Iid"); + createExtraChild(new WidgetPointer(arg2), 4, ivar5); + setWidgetText(cs2method_3408(105, 115, 5177, ivar5)); + setWidgetFont(494); + setWidgetPosition(2, multiply(ivar5, ivar6), 0, 0); + setWidgetSize(subtract(getWidgetActualWidth(new WidgetPointer(arg0)), 24), 15, 0, 0); + setWidgetRGB(new Color(221, 221, 221)); + setWidgetTextAlignment(0, 1, 0); + setWidgetUnknownBoolean(false); + ivar5 = add(ivar5, 1); + } + cs2method2100(0, 0, new WidgetPointer(arg0)); + setWidgetScrollMax(0, add(2, multiply(ivar5, ivar6)), new WidgetPointer(arg0)); + script_31(20905992, arg0, 6507, 6504, 6505, 6506, 6499, 6498); + return; +} diff --git a/dumps/scripts/5314.cs2 b/dumps/scripts/5314.cs2 new file mode 100644 index 0000000..aa00c07 --- /dev/null +++ b/dumps/scripts/5314.cs2 @@ -0,0 +1,4 @@ +void script_5314(int arg0,int arg1,int arg2,int arg3,int arg4) { + script_5315(arg0, arg1, arg2, arg3, arg4); + return; +} diff --git a/dumps/scripts/5315.cs2 b/dumps/scripts/5315.cs2 new file mode 100644 index 0000000..5321d13 --- /dev/null +++ b/dumps/scripts/5315.cs2 @@ -0,0 +1,76 @@ +void script_5315(int arg0,int arg1,int arg2,int arg3,int arg4) { + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + ivar5 = 0; + ivar6 = 15; + ivar7 = getCommonDefinitionSize(5177); + ivar8 = getCommonDefinitionSize(5176); + ivar9 = 0; + ivar10 = -1; + deleteAllExtraChilds(new WidgetPointer(arg1)); + deleteAllExtraChilds(new WidgetPointer(arg2)); + deleteAllExtraChilds(new WidgetPointer(arg3)); + deleteAllExtraChilds(new WidgetPointer(arg4)); + while (ivar5 < 40) { + ivar9 = subtract(script_5319(ivar5), 1); + createExtraChild(new WidgetPointer(arg1), 3, ivar5); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg0)), ivar6, 0, 0); + setWidgetPosition(0, multiply(ivar5, ivar6), 0, 0); + if (((boolean)mod(ivar5, 2))) { + setWidgetRGB(new Color(34, 34, 34)); + } else { + setWidgetRGB(new Color(17, 17, 17)); + } + setWidgetFilled(1); + createExtraChild(new WidgetPointer(arg3), 5, ivar5); + setWidgetSprite(7712); + setWidgetContextMenuOption(1, "Play"); + setWidgetSize(12, 13, 0, 0); + setWidgetPosition(138, add(1, multiply(ivar5, ivar6)), 0, 0); + ivar10 = 7713; + setScriptCallOnMouseEntered(5336, new WidgetPointer(-32768,3), -2147483643, ivar10, "Iid"); + ivar10 = 7712; + setScriptCallOnMouseExit(5336, new WidgetPointer(-32768,3), -2147483643, ivar10, "Iid"); + if (ivar9 < 0) { + setWidgetHidden(1); + } + createExtraChild(new WidgetPointer(arg4), 5, ivar5); + setWidgetSprite(7718); + setWidgetContextMenuOption(1, "Remove"); + setWidgetSize(12, 13, 0, 0); + setWidgetPosition(151, add(1, multiply(ivar5, ivar6)), 0, 0); + ivar10 = 7719; + setScriptCallOnMouseEntered(5336, new WidgetPointer(-32768,3), -2147483643, ivar10, "Iid"); + ivar10 = 7718; + setScriptCallOnMouseExit(5336, new WidgetPointer(-32768,3), -2147483643, ivar10, "Iid"); + if (ivar9 < 0) { + setWidgetHidden(1); + } + createExtraChild(new WidgetPointer(arg2), 4, ivar5); + setWidgetFont(494); + setWidgetPosition(2, multiply(ivar5, ivar6), 0, 0); + setWidgetSize(subtract(getWidgetActualWidth(new WidgetPointer(arg0)), 24), 15, 0, 0); + setWidgetRGB(new Color(221, 221, 221)); + setWidgetTextAlignment(0, 1, 0); + setWidgetUnknownBoolean(false); + if (ivar9 >= 0) { + setWidgetText(cs2method_3408(105, 115, 5177, ivar9)); + } else { + setWidgetText(""); + } + cs2method1301(arg2, -1); + cs2method1302(1); + cs2method1303(3); + cs2method1304(20); + setScriptCallOnMouseDragReleased(5316, new WidgetPointer(-32768,3), -2147483643, -2147483641, "Iii"); + ivar5 = add(ivar5, 1); + } + cs2method2100(0, 0, new WidgetPointer(arg0)); + setWidgetScrollMax(0, add(2, multiply(ivar5, ivar6)), new WidgetPointer(arg0)); + script_31(20905993, arg0, 792, 789, 790, 791, 773, 788); + return; +} diff --git a/dumps/scripts/5316.cs2 b/dumps/scripts/5316.cs2 new file mode 100644 index 0000000..dcbe2e7 --- /dev/null +++ b/dumps/scripts/5316.cs2 @@ -0,0 +1,7 @@ +void script_5316(int arg0,int arg1,int arg2) { + if ((((arg1 >= 0) && (arg1 < 40)) && ((arg2 >= 0) && (arg2 < 40))) && (setWidgetRegister(new WidgetPointer(arg0), arg1) && setWidgetRegister(new WidgetPointer(arg0), arg2))) { + setWidgetPosition(0, getWidgetActualY(), 0, 0); + setWidgetPosition(0, getWidgetActualY(), 0, 0); + } + return; +} diff --git a/dumps/scripts/5317.cs2 b/dumps/scripts/5317.cs2 new file mode 100644 index 0000000..70a9b34 --- /dev/null +++ b/dumps/scripts/5317.cs2 @@ -0,0 +1,22 @@ +void script_5317() { + if (isWidgetHidden(new WidgetPointer(319,38))) { + setWidgetIsHidden(false, new WidgetPointer(319,38)); + setWidgetIsHidden(true, new WidgetPointer(319,30)); + setWidgetIsHidden(true, new WidgetPointer(319,6)); + setWidgetIsHidden(true, new WidgetPointer(319,9)); + setWidgetIsHidden(true, new WidgetPointer(319,10)); + setWidgetIsHidden(false, new WidgetPointer(319,7)); + setWidgetIsHidden(false, new WidgetPointer(319,8)); + setWidgetIsHidden(false, new WidgetPointer(319,12)); + } else { + setWidgetIsHidden(true, new WidgetPointer(319,38)); + setWidgetIsHidden(false, new WidgetPointer(319,30)); + setWidgetIsHidden(false, new WidgetPointer(319,6)); + setWidgetIsHidden(false, new WidgetPointer(319,9)); + setWidgetIsHidden(false, new WidgetPointer(319,10)); + setWidgetIsHidden(true, new WidgetPointer(319,7)); + setWidgetIsHidden(true, new WidgetPointer(319,8)); + setWidgetIsHidden(true, new WidgetPointer(319,12)); + } + return; +} diff --git a/dumps/scripts/5318.cs2 b/dumps/scripts/5318.cs2 new file mode 100644 index 0000000..daae314 --- /dev/null +++ b/dumps/scripts/5318.cs2 @@ -0,0 +1,124 @@ +void script_5318(int arg0,int arg1) { + switch (arg0) { + case 0: + globalint_1608 = arg1; + break; + case 1: + globalint_1609 = arg1; + break; + case 2: + globalint_1610 = arg1; + break; + case 3: + globalint_1611 = arg1; + break; + case 4: + globalint_1612 = arg1; + break; + case 5: + globalint_1613 = arg1; + break; + case 6: + globalint_1614 = arg1; + break; + case 7: + globalint_1615 = arg1; + break; + case 8: + globalint_1616 = arg1; + break; + case 9: + globalint_1617 = arg1; + break; + case 10: + globalint_1618 = arg1; + break; + case 11: + globalint_1619 = arg1; + break; + case 12: + globalint_1620 = arg1; + break; + case 13: + globalint_1621 = arg1; + break; + case 14: + globalint_1622 = arg1; + break; + case 15: + globalint_1623 = arg1; + break; + case 16: + globalint_1624 = arg1; + break; + case 17: + globalint_1625 = arg1; + break; + case 18: + globalint_1626 = arg1; + break; + case 19: + globalint_1627 = arg1; + break; + case 20: + globalint_1628 = arg1; + break; + case 21: + globalint_1629 = arg1; + break; + case 22: + globalint_1630 = arg1; + break; + case 23: + globalint_1631 = arg1; + break; + case 24: + globalint_1632 = arg1; + break; + case 25: + globalint_1633 = arg1; + break; + case 26: + globalint_1634 = arg1; + break; + case 27: + globalint_1635 = arg1; + break; + case 28: + globalint_1636 = arg1; + break; + case 29: + globalint_1637 = arg1; + break; + case 30: + globalint_1638 = arg1; + break; + case 31: + globalint_1639 = arg1; + break; + case 32: + globalint_1640 = arg1; + break; + case 33: + globalint_1641 = arg1; + break; + case 34: + globalint_1642 = arg1; + break; + case 35: + globalint_1643 = arg1; + break; + case 36: + globalint_1644 = arg1; + break; + case 37: + globalint_1645 = arg1; + break; + case 38: + globalint_1646 = arg1; + break; + case 39: + globalint_1647 = arg1; + } + return; +} diff --git a/dumps/scripts/5319.cs2 b/dumps/scripts/5319.cs2 new file mode 100644 index 0000000..5a30b0b --- /dev/null +++ b/dumps/scripts/5319.cs2 @@ -0,0 +1,85 @@ +int script_5319(int arg0) { + switch (arg0) { + case 0: + return globalint_1608; + case 1: + return globalint_1609; + case 2: + return globalint_1610; + case 3: + return globalint_1611; + case 4: + return globalint_1612; + case 5: + return globalint_1613; + case 6: + return globalint_1614; + case 7: + return globalint_1615; + case 8: + return globalint_1616; + case 9: + return globalint_1617; + case 10: + return globalint_1618; + case 11: + return globalint_1619; + case 12: + return globalint_1620; + case 13: + return globalint_1621; + case 14: + return globalint_1622; + case 15: + return globalint_1623; + case 16: + return globalint_1624; + case 17: + return globalint_1625; + case 18: + return globalint_1626; + case 19: + return globalint_1627; + case 20: + return globalint_1628; + case 21: + return globalint_1629; + case 22: + return globalint_1630; + case 23: + return globalint_1631; + case 24: + return globalint_1632; + case 25: + return globalint_1633; + case 26: + return globalint_1634; + case 27: + return globalint_1635; + case 28: + return globalint_1636; + case 29: + return globalint_1637; + case 30: + return globalint_1638; + case 31: + return globalint_1639; + case 32: + return globalint_1640; + case 33: + return globalint_1641; + case 34: + return globalint_1642; + case 35: + return globalint_1643; + case 36: + return globalint_1644; + case 37: + return globalint_1645; + case 38: + return globalint_1646; + case 39: + return globalint_1647; + } + return 0; +} diff --git a/dumps/scripts/532.cs2 b/dumps/scripts/532.cs2 new file mode 100644 index 0000000..b89af3b --- /dev/null +++ b/dumps/scripts/532.cs2 @@ -0,0 +1,4 @@ +void script_532(int arg0,int arg1) { + setWidgetText(new WidgetPointer(arg0), intToStr(getSkillActualLvl(arg1))); + return; +} diff --git a/dumps/scripts/5320.cs2 b/dumps/scripts/5320.cs2 new file mode 100644 index 0000000..fc5bb3c --- /dev/null +++ b/dumps/scripts/5320.cs2 @@ -0,0 +1,4 @@ +void script_5320() { + script_5324(bitconfig_9887); + return; +} diff --git a/dumps/scripts/5321.cs2 b/dumps/scripts/5321.cs2 new file mode 100644 index 0000000..1b034dc --- /dev/null +++ b/dumps/scripts/5321.cs2 @@ -0,0 +1,4 @@ +void script_5321() { + script_5324(bitconfig_9887); + return; +} diff --git a/dumps/scripts/5322.cs2 b/dumps/scripts/5322.cs2 new file mode 100644 index 0000000..f4cd735 --- /dev/null +++ b/dumps/scripts/5322.cs2 @@ -0,0 +1,36 @@ +void script_5322(int arg0) { + switch (arg0) { + case 52232219: + bitconfig_9887 = 1; + script_5324(1); + break; + case 52232233: + bitconfig_9887 = 2; + script_5324(2); + break; + case 52232247: + bitconfig_9887 = 3; + script_5324(3); + break; + case 52232261: + bitconfig_9887 = 4; + script_5324(4); + break; + case 52232275: + bitconfig_9887 = 5; + script_5324(5); + break; + case 52232289: + bitconfig_9887 = 6; + script_5324(6); + break; + case 52232303: + bitconfig_9887 = 7; + script_5324(7); + break; + case 52232317: + bitconfig_9887 = 8; + script_5324(8); + } + return; +} diff --git a/dumps/scripts/5323.cs2 b/dumps/scripts/5323.cs2 new file mode 100644 index 0000000..7b57aeb --- /dev/null +++ b/dumps/scripts/5323.cs2 @@ -0,0 +1,11 @@ +void script_5323() { + setWidgetIsHidden(true, new WidgetPointer(797,27)); + setWidgetIsHidden(true, new WidgetPointer(797,40)); + setWidgetIsHidden(true, new WidgetPointer(797,54)); + setWidgetIsHidden(true, new WidgetPointer(797,68)); + setWidgetIsHidden(true, new WidgetPointer(797,82)); + setWidgetIsHidden(true, new WidgetPointer(797,96)); + setWidgetIsHidden(true, new WidgetPointer(797,110)); + setWidgetIsHidden(true, new WidgetPointer(797,124)); + return; +} diff --git a/dumps/scripts/5324.cs2 b/dumps/scripts/5324.cs2 new file mode 100644 index 0000000..a9e67f3 --- /dev/null +++ b/dumps/scripts/5324.cs2 @@ -0,0 +1,29 @@ +void script_5324(int arg0) { + script_5323(); + switch (arg0) { + case 1: + setWidgetIsHidden(false, new WidgetPointer(797,27)); + break; + case 2: + setWidgetIsHidden(false, new WidgetPointer(797,40)); + break; + case 3: + setWidgetIsHidden(false, new WidgetPointer(797,54)); + break; + case 4: + setWidgetIsHidden(false, new WidgetPointer(797,68)); + break; + case 5: + setWidgetIsHidden(false, new WidgetPointer(797,82)); + break; + case 6: + setWidgetIsHidden(false, new WidgetPointer(797,96)); + break; + case 7: + setWidgetIsHidden(false, new WidgetPointer(797,110)); + break; + case 8: + setWidgetIsHidden(false, new WidgetPointer(797,124)); + } + return; +} diff --git a/dumps/scripts/5325.cs2 b/dumps/scripts/5325.cs2 new file mode 100644 index 0000000..3fafbb5 --- /dev/null +++ b/dumps/scripts/5325.cs2 @@ -0,0 +1,4 @@ +void script_5325(int arg0) { + script_5326(arg0); + return; +} diff --git a/dumps/scripts/5326.cs2 b/dumps/scripts/5326.cs2 new file mode 100644 index 0000000..08da1db --- /dev/null +++ b/dumps/scripts/5326.cs2 @@ -0,0 +1,12 @@ +void script_5326(int arg0) { + int ivar1; + int ivar2; + ivar1 = 20316177; + ivar2 = 20316179; + script_5330(); + setScriptCallOnGlobalStringChange(5327, 139, 141, 191, 192, 193, 289, 290, 291, 297, 298, 299, 300, 301, 302, 303, 15, "Y", new WidgetPointer(arg0)); + setScriptCallOnGlobalConfigChange(5327, 1606, 1, "Y", new WidgetPointer(arg0)); + script_31(ivar2, ivar1, 5666, 5663, 5664, 5665, 5686, 5685); + script_4725(); + return; +} diff --git a/dumps/scripts/5327.cs2 b/dumps/scripts/5327.cs2 new file mode 100644 index 0000000..d873758 --- /dev/null +++ b/dumps/scripts/5327.cs2 @@ -0,0 +1,4 @@ +void script_5327() { + script_4725(); + return; +} diff --git a/dumps/scripts/5328.cs2 b/dumps/scripts/5328.cs2 new file mode 100644 index 0000000..6beb9b9 --- /dev/null +++ b/dumps/scripts/5328.cs2 @@ -0,0 +1,50 @@ +void script_5328() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + ivar0 = 0; + ivar1 = 1; + ivar2 = divide(subtract(getWidgetActualWidth(new WidgetPointer(951,24)), multiply(subtract(8, 1), ivar1)), 8); + ivar3 = subtract(multiply(add(ivar2, ivar1), 8), ivar1); + setWidgetSize(add(ivar3, 12), getWidgetActualHeight(new WidgetPointer(951,2)), 0, 0, new WidgetPointer(951,2)); + deleteAllExtraChilds(new WidgetPointer(951,24)); + ivar4 = 0; + while (ivar0 < 8) { + createExtraChild(new WidgetPointer(951,24), 5, multiply(ivar0, 6)); + setWidgetSprite(5610); + setWidgetSize(6, 0, 0, 1); + setWidgetPosition(ivar4, 0, 0, 0); + setWidgetRGB(new Color(83, 83, 83)); + createExtraChild(new WidgetPointer(951,24), 5, add(multiply(ivar0, 6), 1)); + setWidgetSprite(5611); + setWidgetSize(subtract(ivar2, 12), 0, 0, 1); + setWidgetPosition(add(ivar4, 6), 0, 0, 0); + setWidgetHidden(0); + setWidgetRGB(new Color(83, 83, 83)); + createExtraChild(new WidgetPointer(951,24), 5, add(multiply(ivar0, 6), 2)); + setWidgetSprite(5612); + setWidgetSize(6, 0, 0, 1); + setWidgetPosition(subtract(add(ivar4, ivar2), 6), 0, 0, 0); + setWidgetRGB(new Color(83, 83, 83)); + createExtraChild(new WidgetPointer(951,24), 5, add(multiply(ivar0, 6), 3)); + setWidgetSprite(5610); + setWidgetSize(6, 0, 0, 1); + setWidgetPosition(ivar4, 0, 0, 0); + createExtraChild(new WidgetPointer(951,24), 5, add(multiply(ivar0, 6), 4)); + setWidgetSprite(5611); + setWidgetSize(subtract(ivar2, 12), 0, 0, 1); + setWidgetPosition(add(ivar4, 6), 0, 0, 0); + setWidgetHidden(0); + createExtraChild(new WidgetPointer(951,24), 5, add(multiply(ivar0, 6), 5)); + setWidgetSprite(5612); + setWidgetSize(6, 0, 0, 1); + setWidgetPosition(subtract(add(ivar4, ivar2), 6), 0, 0, 0); + ivar4 = add(add(ivar4, ivar1), ivar2); + ivar0 = add(ivar0, 1); + } + globalint_1657 = -1; + globalint_1658 = 0; + return; +} diff --git a/dumps/scripts/5329.cs2 b/dumps/scripts/5329.cs2 new file mode 100644 index 0000000..9482156 --- /dev/null +++ b/dumps/scripts/5329.cs2 @@ -0,0 +1,35 @@ +string script_5329(int arg0) { + switch (arg0) { + case 1: + return globalstring_139; + case 2: + return globalstring_141; + case 3: + return globalstring_191; + case 4: + return globalstring_192; + case 5: + return globalstring_193; + case 6: + return globalstring_289; + case 7: + return globalstring_290; + case 8: + return globalstring_291; + case 9: + return globalstring_297; + case 10: + return globalstring_298; + case 11: + return globalstring_299; + case 12: + return globalstring_300; + case 13: + return globalstring_301; + case 14: + return globalstring_302; + case 15: + return globalstring_303; + } + return ""; +} diff --git a/dumps/scripts/533.cs2 b/dumps/scripts/533.cs2 new file mode 100644 index 0000000..31c5344 --- /dev/null +++ b/dumps/scripts/533.cs2 @@ -0,0 +1,4 @@ +void script_533(int arg0) { + setWidgetFilled(1, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/5330.cs2 b/dumps/scripts/5330.cs2 new file mode 100644 index 0000000..423cd69 --- /dev/null +++ b/dumps/scripts/5330.cs2 @@ -0,0 +1,18 @@ +void script_5330() { + globalstring_139 = ""; + globalstring_141 = ""; + globalstring_191 = ""; + globalstring_192 = ""; + globalstring_193 = ""; + globalstring_289 = ""; + globalstring_290 = ""; + globalstring_291 = ""; + globalstring_297 = ""; + globalstring_298 = ""; + globalstring_299 = ""; + globalstring_300 = ""; + globalstring_301 = ""; + globalstring_302 = ""; + globalstring_303 = ""; + return; +} diff --git a/dumps/scripts/5331.cs2 b/dumps/scripts/5331.cs2 new file mode 100644 index 0000000..9b11353 --- /dev/null +++ b/dumps/scripts/5331.cs2 @@ -0,0 +1,9 @@ +void script_5331() { + if (((boolean)globalint_1606)) { + globalint_1606 = 0; + } else { + globalint_1606 = 1; + } + script_4725(); + return; +} diff --git a/dumps/scripts/5332.cs2 b/dumps/scripts/5332.cs2 new file mode 100644 index 0000000..9e168e7 --- /dev/null +++ b/dumps/scripts/5332.cs2 @@ -0,0 +1,4 @@ +void script_5332(int arg0,int arg1,int arg2,int arg3,string arg4) { + script_5335(arg0, -1, arg1, arg2, arg3, 1, arg4); + return; +} diff --git a/dumps/scripts/5333.cs2 b/dumps/scripts/5333.cs2 new file mode 100644 index 0000000..ec5c4bb --- /dev/null +++ b/dumps/scripts/5333.cs2 @@ -0,0 +1,5 @@ +void script_5333(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5) { + setWidgetSprite(arg4, new WidgetPointer(arg0)); + script_5335(arg0, -1, arg1, arg2, arg3, 1, arg5); + return; +} diff --git a/dumps/scripts/5334.cs2 b/dumps/scripts/5334.cs2 new file mode 100644 index 0000000..938b40e --- /dev/null +++ b/dumps/scripts/5334.cs2 @@ -0,0 +1,4 @@ +void script_5334(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5) { + script_5335(arg0, arg1, arg2, arg3, arg4, 1, arg5); + return; +} diff --git a/dumps/scripts/5335.cs2 b/dumps/scripts/5335.cs2 new file mode 100644 index 0000000..4f37afd --- /dev/null +++ b/dumps/scripts/5335.cs2 @@ -0,0 +1,158 @@ +void script_5335(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,string arg6) { + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + flow_0: + ivar6 = 0; + ivar7 = 0; + ivar8 = 0; + ivar9 = 0; + ivar10 = 0; + ivar11 = 0; + ivar12 = 0; + ivar13 = 0; + ivar14 = -1; + IF (arg1 == -1) + GOTO flow_1 + GOTO flow_2 + flow_1: + IF (setWidgetRegister(new WidgetPointer(arg0))) + GOTO flow_3 + flow_2: + IF (setWidgetRegister(new WidgetPointer(arg0), arg1)) + GOTO flow_3 + GOTO flow_37 + flow_3: + if (((boolean)script_4761(arg3))) { + return; + } + if (globalint_2 != 1) { + ivar6 = add(getWidgetActualX(), 5); + ivar7 = add(add(getWidgetActualY(), getWidgetActualHeight()), 5); + ivar14 = getWidgetParentId(new WidgetPointer(arg2)); + if ((ivar14 != -1) && (arg4 >= getWidgetActualWidth(new WidgetPointer(ivar14)))) { + arg4 = getWidgetActualWidth(new WidgetPointer(ivar14)); + } + if (((boolean)arg5)) { + ivar12 = add(4, getMaxLineWidth(subtract(arg4, 4), 495, arg6)); + ivar13 = add(4, multiply(16, getLineCount(subtract(arg4, 4), 495, arg6))); + } else { + ivar12 = add(12, getMaxLineWidth(subtract(arg4, 12), 3793, arg6)); + ivar13 = add(12, multiply(16, getLineCount(subtract(arg4, 12), 3793, arg6))); + } + if (ivar14 != -1) { + ivar8 = subtract(ivar6, cs2method2600(new WidgetPointer(ivar14))); + ivar9 = subtract(ivar7, cs2method2601(new WidgetPointer(ivar14))); + if (ivar8 < 0) { + ivar6 = cs2method2600(new WidgetPointer(ivar14)); + ivar8 = 0; + } + if (ivar9 < 0) { + ivar7 = cs2method2601(new WidgetPointer(ivar14)); + ivar9 = 0; + } + if (ivar8 > 0) { + ivar10 = add(subtract(ivar8, getWidgetActualWidth(new WidgetPointer(ivar14))), ivar12); + if (ivar10 > 0) { + ivar6 = subtract(ivar6, ivar10); + } + } + if (ivar9 > 0) { + ivar11 = add(subtract(ivar9, getWidgetActualHeight(new WidgetPointer(ivar14))), ivar13); + if (ivar11 > 0) { + ivar7 = subtract(subtract(subtract(ivar7, ivar11), getWidgetActualHeight()), 10); + } + } + } + if (ivar6 < 0) { + ivar6 = 0; + } + if (ivar7 < 0) { + ivar7 = 0; + } + setWidgetSize(ivar12, ivar13, 0, 0, new WidgetPointer(arg2)); + setWidgetPosition(ivar6, ivar7, 0, 0, new WidgetPointer(arg2)); + deleteAllExtraChilds(new WidgetPointer(arg2)); + createExtraChild(new WidgetPointer(arg2), 3, 0); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg2)), getWidgetActualHeight(new WidgetPointer(arg2)), 0, 0); + setWidgetFilled(1); + if (((boolean)arg5)) { + setWidgetRGB(new Color(255, 255, 160)); + } else { + setWidgetRGB(new Color(0, 0, 0)); + } + if (((boolean)arg5)) { + createExtraChild(new WidgetPointer(arg2), 3, 1); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg2)), getWidgetActualHeight(new WidgetPointer(arg2)), 0, 0); + setWidgetFilled(0); + setWidgetRGB(new Color(0, 0, 0)); + } else { + createExtraChild(new WidgetPointer(arg2), 5, getExtraChildGap(new WidgetPointer(arg2))); + setWidgetSize(4, 10, 1, 0); + setWidgetPosition(0, 0, 1, 0); + setWidgetSprite(4649); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg2), 5, getExtraChildGap(new WidgetPointer(arg2))); + setWidgetSize(4, 10, 1, 0); + setWidgetPosition(0, 0, 1, 2); + setWidgetSprite(4649); + cs2method1107(1); + setWidgetVFlip(1); + createExtraChild(new WidgetPointer(arg2), 5, getExtraChildGap(new WidgetPointer(arg2))); + setWidgetSize(10, 4, 0, 1); + setWidgetPosition(0, 0, 0, 1); + setWidgetSprite(4651); + cs2method1107(1); + setWidgetHFlip(1); + createExtraChild(new WidgetPointer(arg2), 5, getExtraChildGap(new WidgetPointer(arg2))); + setWidgetSize(10, 4, 0, 1); + setWidgetPosition(0, 0, 2, 1); + setWidgetSprite(4651); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg2), 5, getExtraChildGap(new WidgetPointer(arg2))); + setWidgetSize(10, 10, 0, 0); + setWidgetPosition(0, 0, 0, 0); + setWidgetSprite(4650); + setWidgetHFlip(1); + createExtraChild(new WidgetPointer(arg2), 5, getExtraChildGap(new WidgetPointer(arg2))); + setWidgetSize(10, 10, 0, 0); + setWidgetPosition(0, 0, 2, 0); + setWidgetSprite(4650); + createExtraChild(new WidgetPointer(arg2), 5, getExtraChildGap(new WidgetPointer(arg2))); + setWidgetSize(10, 10, 0, 0); + setWidgetPosition(0, 0, 0, 2); + setWidgetSprite(4650); + setWidgetHFlip(1); + setWidgetVFlip(1); + createExtraChild(new WidgetPointer(arg2), 5, getExtraChildGap(new WidgetPointer(arg2))); + setWidgetSize(10, 10, 0, 0); + setWidgetPosition(0, 0, 2, 2); + setWidgetSprite(4650); + setWidgetVFlip(1); + } + createExtraChild(new WidgetPointer(arg2), 4, getExtraChildGap(new WidgetPointer(arg2))); + setWidgetText(arg6); + if (((boolean)arg5)) { + setWidgetSize(subtract(arg4, 4), getWidgetActualHeight(new WidgetPointer(arg2)), 0, 0); + setWidgetPosition(2, 0, 0, 0); + setWidgetTextAlignment(0, 1, 16); + setWidgetFont(495); + setWidgetRGB(new Color(0, 0, 0)); + } else { + setWidgetSize(subtract(getWidgetActualWidth(new WidgetPointer(arg2)), 12), subtract(getWidgetActualHeight(new WidgetPointer(arg2)), 12), 0, 0); + setWidgetPosition(6, 6, 0, 0); + setWidgetTextAlignment(1, 1, 13); + setWidgetRGB(new Color(255, 255, 255)); + setWidgetFont(3793); + } + globalint_2 = 1; + } + flow_37: + return; +} diff --git a/dumps/scripts/5336.cs2 b/dumps/scripts/5336.cs2 new file mode 100644 index 0000000..5c29b6f --- /dev/null +++ b/dumps/scripts/5336.cs2 @@ -0,0 +1,6 @@ +void script_5336(int arg0,int arg1,int arg2) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetSprite(arg2); + } + return; +} diff --git a/dumps/scripts/5337.cs2 b/dumps/scripts/5337.cs2 new file mode 100644 index 0000000..4266c17 --- /dev/null +++ b/dumps/scripts/5337.cs2 @@ -0,0 +1,4 @@ +void script_5337(int arg0,string arg1) { + cs2method5421(arg0, arg1); + return; +} diff --git a/dumps/scripts/5338.cs2 b/dumps/scripts/5338.cs2 new file mode 100644 index 0000000..73b0ab4 --- /dev/null +++ b/dumps/scripts/5338.cs2 @@ -0,0 +1,4 @@ +void script_5338(int arg0,string arg1,string arg2) { + script_5339(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/5339.cs2 b/dumps/scripts/5339.cs2 new file mode 100644 index 0000000..3ff532c --- /dev/null +++ b/dumps/scripts/5339.cs2 @@ -0,0 +1,4 @@ +void script_5339(int arg0,string arg1,string arg2) { + cs2method5400(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/534.cs2 b/dumps/scripts/534.cs2 new file mode 100644 index 0000000..9788f30 --- /dev/null +++ b/dumps/scripts/534.cs2 @@ -0,0 +1,4 @@ +void script_534(int arg0) { + setWidgetFilled(0, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/5340.cs2 b/dumps/scripts/5340.cs2 new file mode 100644 index 0000000..e936c79 --- /dev/null +++ b/dumps/scripts/5340.cs2 @@ -0,0 +1,4 @@ +void script_5340() { + script_5341(); + return; +} diff --git a/dumps/scripts/5341.cs2 b/dumps/scripts/5341.cs2 new file mode 100644 index 0000000..d240cb3 --- /dev/null +++ b/dumps/scripts/5341.cs2 @@ -0,0 +1,8 @@ +void script_5341() { + if (isWidgetOpen(new WidgetPointer(746,1)) || isWidgetOpen(new WidgetPointer(548,240))) { + return; + } + setWidgetIsHidden(true, new WidgetPointer(746,245)); + setWidgetIsHidden(true, new WidgetPointer(548,240)); + return; +} diff --git a/dumps/scripts/5342.cs2 b/dumps/scripts/5342.cs2 new file mode 100644 index 0000000..764c0a1 --- /dev/null +++ b/dumps/scripts/5342.cs2 @@ -0,0 +1,13 @@ +void script_5342(int arg0) { + if (arg0 == -1) { + arg0 = 70; + } else if (arg0 > 255) { + arg0 = 255; + } else { + if (arg0 < 0) { + arg0 = 0; + } + } + cs2method2103(arg0, new WidgetPointer(746,0)); + return; +} diff --git a/dumps/scripts/5343.cs2 b/dumps/scripts/5343.cs2 new file mode 100644 index 0000000..4cc8f97 --- /dev/null +++ b/dumps/scripts/5343.cs2 @@ -0,0 +1,6 @@ +void script_5343(int arg0,int arg1,int arg2) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetSprite(arg2); + } + return; +} diff --git a/dumps/scripts/5344.cs2 b/dumps/scripts/5344.cs2 new file mode 100644 index 0000000..532dc0f --- /dev/null +++ b/dumps/scripts/5344.cs2 @@ -0,0 +1,10 @@ +void script_5344(int arg0,int arg1,int arg2,int arg3) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + if (getWidgetSpriteId() == arg2) { + setWidgetSprite(arg3); + } else { + setWidgetSprite(arg2); + } + } + return; +} diff --git a/dumps/scripts/5345.cs2 b/dumps/scripts/5345.cs2 new file mode 100644 index 0000000..a98c649 --- /dev/null +++ b/dumps/scripts/5345.cs2 @@ -0,0 +1,27 @@ +void script_5345() { + flow_0: + setWidgetIsHidden(true, new WidgetPointer(622,6)); + setWidgetIsHidden(true, new WidgetPointer(622,7)); + setWidgetIsHidden(true, new WidgetPointer(622,9)); + setWidgetIsHidden(true, new WidgetPointer(622,8)); + SWITCH (getLanguage()) { + case 1: + GOTO flow_1 + case 2: + GOTO flow_2 + case 3: + GOTO flow_3 + } + setWidgetIsHidden(false, new WidgetPointer(622,6)); + GOTO flow_4 + flow_1: + setWidgetIsHidden(false, new WidgetPointer(622,9)); + GOTO flow_4 + flow_2: + setWidgetIsHidden(false, new WidgetPointer(622,7)); + GOTO flow_4 + flow_3: + setWidgetIsHidden(false, new WidgetPointer(622,8)); + flow_4: + return; +} diff --git a/dumps/scripts/5346.cs2 b/dumps/scripts/5346.cs2 new file mode 100644 index 0000000..9971900 --- /dev/null +++ b/dumps/scripts/5346.cs2 @@ -0,0 +1,20 @@ +void script_5346(int arg0) { + int ivar1; + int ivar2; + ivar1 = 74907756; + ivar2 = getWidgetShadeColor(new WidgetPointer(ivar1)); + if (((boolean)arg0)) { + ivar2 = min(add(ivar2, 1), 255); + cs2method2103(ivar2, new WidgetPointer(ivar1)); + if (ivar2 == 255) { + setScriptCallOnGameloop(5346, 0, "1", new WidgetPointer(ivar1)); + } + } else { + ivar2 = max(subtract(ivar2, 1), 0); + cs2method2103(ivar2, new WidgetPointer(ivar1)); + if (((boolean)ivar2)) { + setScriptCallOnGameloop(5346, 1, "1", new WidgetPointer(ivar1)); + } + } + return; +} diff --git a/dumps/scripts/5347.cs2 b/dumps/scripts/5347.cs2 new file mode 100644 index 0000000..faa943b --- /dev/null +++ b/dumps/scripts/5347.cs2 @@ -0,0 +1,58 @@ +void script_5347() { + int ivar0; + int ivar1; + flow_0: + ivar0 = -1; + ivar1 = -1; + SWITCH (getLanguage()) { + case 1: + GOTO flow_1 + case 2: + GOTO flow_2 + case 3: + GOTO flow_3 + } + ivar0 = 7790; + ivar1 = 7791; + GOTO flow_4 + flow_1: + ivar0 = 7794; + ivar1 = 7795; + GOTO flow_4 + flow_2: + ivar0 = 7792; + ivar1 = 7793; + GOTO flow_4 + flow_3: + ivar0 = 7796; + ivar1 = 7797; + flow_4: + SWITCH (globalint_1659) { + case 0: + GOTO flow_5 + case 1: + GOTO flow_6 + case 2: + GOTO flow_7 + case 3: + GOTO flow_8 + } + setWidgetText(new WidgetPointer(1143,11), "Sort By..."); + GOTO flow_9 + flow_5: + setWidgetText(new WidgetPointer(1143,11), "Price: Low-High"); + GOTO flow_9 + flow_6: + setWidgetText(new WidgetPointer(1143,11), "Price: High-Low"); + GOTO flow_9 + flow_7: + setWidgetText(new WidgetPointer(1143,11), "Name: A-Z"); + GOTO flow_9 + flow_8: + setWidgetText(new WidgetPointer(1143,11), "Name: Z-A"); + flow_9: + setWidgetIsHidden(true, new WidgetPointer(1143,6)); + setWidgetSprite(ivar0, new WidgetPointer(1143,70)); + setWidgetSprite(ivar1, new WidgetPointer(1143,71)); + return; +} diff --git a/dumps/scripts/5348.cs2 b/dumps/scripts/5348.cs2 new file mode 100644 index 0000000..b45708d --- /dev/null +++ b/dumps/scripts/5348.cs2 @@ -0,0 +1,12 @@ +void script_5348(int arg0) { + string svar0; + svar0 = ""; + if (globalint_1648 > 0) { + svar0 = formatNumber(globalint_1648, 1); + } else { + globalint_1648 = 0; + svar0 = "0"; + } + setWidgetText(new WidgetPointer(arg0), svar0); + return; +} diff --git a/dumps/scripts/5349.cs2 b/dumps/scripts/5349.cs2 new file mode 100644 index 0000000..b18154a --- /dev/null +++ b/dumps/scripts/5349.cs2 @@ -0,0 +1,4 @@ +void script_5349(int arg0,int arg1) { + script_5350(arg0, arg1); + return; +} diff --git a/dumps/scripts/535.cs2 b/dumps/scripts/535.cs2 new file mode 100644 index 0000000..c9ac2e4 --- /dev/null +++ b/dumps/scripts/535.cs2 @@ -0,0 +1,4 @@ +void script_535(int arg0) { + setWidgetText(new WidgetPointer(arg0), intToStr(divide(bitconfig_4103, 10))); + return; +} diff --git a/dumps/scripts/5350.cs2 b/dumps/scripts/5350.cs2 new file mode 100644 index 0000000..568e4ce --- /dev/null +++ b/dumps/scripts/5350.cs2 @@ -0,0 +1,442 @@ +void script_5350(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + int ivar22; + int ivar23; + int ivar24; + int ivar25; + int ivar26; + int ivar27; + int ivar28; + int ivar29; + int ivar30; + int ivar31; + int ivar32; + int ivar33; + int ivar34; + int ivar35; + int ivar36; + string svar0; + string svar1; + string svar2; + int stack_dump0; + int stack_dump1; + int stack_dump2; + int stack_dump3; + int stack_dump4; + int stack_dump5; + int stack_dump6; + int stack_dump7; + int stack_dump8; + int stack_dump9; + cs2func_script_5352_struct(5,0,0) structdump_10; + cs2func_script_5353_struct(5,0,0) structdump_11; + cs2func_script_4727_struct(5,0,0) structdump_12; + cs2func_script_4344_struct(5,0,0) structdump_13; + int stack_dump14; + cs2func_script_4726_struct(5,0,0) structdump_15; + ivar2 = 5181; + svar0 = "Home"; + ivar3 = 0; + if (((boolean)bitconfig_9487)) { + ivar2 = 5182; + svar0 = "Auras"; + ivar3 = 1; + } else if (bitconfig_9487 == 2) { + ivar2 = 3875; + svar0 = "Emotes"; + ivar3 = 2; + } else if (bitconfig_9487 == 3) { + if (IsFemale()) { + ivar2 = 5189; + } else { + ivar2 = 5188; + } + svar0 = "Costumes"; + ivar3 = 3; + } else if (bitconfig_9487 == 4) { + ivar2 = 5184; + svar0 = "Titles"; + ivar3 = 4; + } else if (bitconfig_9487 == 5) { + ivar2 = 5183; + svar0 = "Re-colour"; + ivar3 = 5; + } else if (bitconfig_9487 == 6) { + svar0 = "Special Offers"; + ivar3 = 6; + } else if (bitconfig_9487 == 7) { + svar0 = "Limited Edition"; + ivar3 = 7; + } else { + if (bitconfig_9487 == 8) { + svar0 = "My Favourites"; + ivar3 = 8; + } + } + ivar4 = 74907774; + ivar5 = cs2method2601(new WidgetPointer(ivar4)); + ivar6 = 74907708; + ivar7 = 74907709; + ivar8 = 74907707; + ivar9 = 74907693; + ivar10 = 74907694; + ivar11 = 74907695; + ivar12 = 74907696; + ivar13 = 74907697; + ivar14 = 74907688; + ivar15 = 74907689; + ivar16 = 74907690; + ivar17 = 74907691; + ivar18 = 74907692; + deleteAllExtraChilds(new WidgetPointer(ivar4)); + deleteAllExtraChilds(new WidgetPointer(ivar6)); + deleteAllExtraChilds(new WidgetPointer(ivar7)); + deleteAllExtraChilds(new WidgetPointer(ivar8)); + deleteAllExtraChilds(new WidgetPointer(ivar9)); + deleteAllExtraChilds(new WidgetPointer(ivar10)); + deleteAllExtraChilds(new WidgetPointer(ivar11)); + deleteAllExtraChilds(new WidgetPointer(ivar12)); + deleteAllExtraChilds(new WidgetPointer(ivar13)); + deleteAllExtraChilds(new WidgetPointer(ivar14)); + deleteAllExtraChilds(new WidgetPointer(ivar15)); + deleteAllExtraChilds(new WidgetPointer(ivar16)); + deleteAllExtraChilds(new WidgetPointer(ivar17)); + deleteAllExtraChilds(new WidgetPointer(ivar18)); + setWidgetIsHidden(true, new WidgetPointer(1143,62)); + setWidgetText(new WidgetPointer(1143,63), concat("Now Viewing: ", svar0)); + ivar19 = 0; + ivar20 = 6; + ivar21 = ivar20; + ivar22 = ivar20; + ivar23 = 0; + ivar24 = -1; + ivar25 = 7835; + ivar26 = 7836; + ivar27 = 7837; + ivar28 = 0; + ivar29 = 0; + ivar30 = 0; + ivar31 = 0; + ivar32 = 0; + svar1 = ""; + ivar33 = -1; + ivar34 = 0; + ivar35 = 0; + svar2 = "See More"; + ivar36 = 0; + if (((boolean)ivar3)) { + flow_20: + ivar25 = 7826; + ivar26 = 7827; + ivar27 = 7828; + ivar20 = 20; + ivar21 = 0; + ivar22 = ivar20; + createExtraChild(new WidgetPointer(ivar8), 5, ivar19); + ivar19 = add(ivar19, 1); + setWidgetPosition(17, 24, 0, 0); + setWidgetSprite(7803); + ivar34 = 311; + ivar35 = 311; + setWidgetSize(ivar34, ivar35, 0, 0); + setWidgetContextMenuOption(1, svar2); + createExtraChild(new WidgetPointer(ivar8), 5, ivar19); + ivar19 = add(ivar19, 1); + setWidgetSprite(7805); + setWidgetSize(141, 219, 0, 0); + setWidgetPosition(17, 24, 0, 0); + setWidgetPosition(add(getWidgetActualX(), divide(subtract(ivar34, getWidgetActualWidth()), 2)), add(add(getWidgetActualY(), 20), divide(subtract(ivar35, getWidgetActualHeight()), 2)), 0, 0); + createExtraChild(new WidgetPointer(ivar8), 5, ivar19); + ivar19 = add(ivar19, 1); + setWidgetPosition(0, 62, 0, 0); + setWidgetSize(348, 34, 0, 0); + SWITCH (getLanguage()) { + case 1: + GOTO flow_21 + case 2: + GOTO flow_22 + case 3: + GOTO flow_23 + } + setWidgetSprite(7806); + GOTO flow_24 + flow_21: + setWidgetSprite(7808); + GOTO flow_24 + flow_22: + setWidgetSprite(7807); + GOTO flow_24 + flow_23: + setWidgetSprite(7809); + flow_24: + createExtraChild(new WidgetPointer(ivar8), 4, ivar19); + ivar19 = add(ivar19, 1); + setWidgetPosition(165, 275, 0, 0); + setWidgetText(svar2); + setWidgetFont(4040); + setWidgetUnknownBoolean(true); + setWidgetRGB(new Color(229, 189, 89)); + setWidgetTextAlignment(2, 1, 13); + setWidgetSize(122, 24, 0, 0); + while (ivar36 < getCommonDefinitionSize(ivar2)) { + ivar24 = cs2method_3408(105, 74, ivar2, ivar36); + createExtraChild(new WidgetPointer(ivar8), 5, ivar19); + ivar19 = add(ivar19, 1); + setWidgetPosition(ivar21, ivar22, 2, 0); + setWidgetSprite(ivar27); + ivar28 = 68; + ivar29 = 92; + ivar21 = add(ivar21, ivar28); + setWidgetSize(ivar28, ivar29, 0, 0); + switch (getOtherCommonData(ivar24, 1937)) { + case 1: + ivar33 = ivar9; + break; + case 2: + ivar33 = ivar10; + break; + case 3: + ivar33 = ivar11; + break; + case 4: + ivar33 = ivar12; + break; + case 5: + ivar33 = ivar13; + } + createExtraChild(new WidgetPointer(ivar33), 4, getExtraChildGap(new WidgetPointer(ivar33))); + setWidgetPosition(subtract(ivar21, ivar28), ivar22, 2, 0); + setWidgetSize(multiply(ivar28, 3), ivar29, 0, 0); + setWidgetContextMenuOption(1, svar2); + setScriptCallOnMouseEntered(5360, new WidgetPointer(ivar8), add(ivar19, 1), ivar19, subtract(ivar19, 1), 1, "Iiii1"); + setScriptCallOnMouseExit(5360, new WidgetPointer(ivar8), add(ivar19, 1), ivar19, subtract(ivar19, 1), 0, "Iiii1"); + createExtraChild(new WidgetPointer(ivar8), 5, ivar19); + ivar19 = add(ivar19, 1); + setWidgetPosition(ivar21, ivar22, 2, 0); + ivar21 = add(ivar21, ivar28); + setWidgetSprite(ivar26); + setWidgetSize(ivar28, ivar29, 0, 0); + createExtraChild(new WidgetPointer(ivar8), 5, ivar19); + ivar19 = add(ivar19, 1); + setWidgetPosition(ivar21, ivar22, 2, 0); + ivar21 = add(ivar21, ivar28); + setWidgetSprite(ivar25); + setWidgetSize(ivar28, ivar29, 0, 0); + createExtraChild(new WidgetPointer(ivar8), 5, ivar19); + ivar19 = add(ivar19, 1); + if (((boolean)getOtherCommonData(ivar24, 1937))) { + setItemOnWidgetMethod1200(getOtherCommonData(ivar24, 1935), -1); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(subtract(ivar21, 63), add(ivar22, 29), 2, 0); + } else if (getOtherCommonData(ivar24, 1937) == 2) { + setWidgetSprite(getOtherCommonData(ivar24, 1420)); + setWidgetSize(48, 48, 0, 0); + setWidgetPosition(subtract(ivar21, 65), add(ivar22, 21), 2, 0); + } else if (getOtherCommonData(ivar24, 1937) == 3) { + setWidgetSprite(getOtherCommonData(ivar24, 1441)); + setWidgetSize(40, 50, 0, 0); + setWidgetPosition(subtract(ivar21, 61), add(ivar22, 20), 2, 0); + } else if (getOtherCommonData(ivar24, 1937) == 4) { + setWidgetSprite(7883); + setWidgetSize(42, 42, 0, 0); + setWidgetPosition(subtract(ivar21, 63), add(ivar22, 25), 2, 0); + } else { + if (getOtherCommonData(ivar24, 1937) == 5) { + setItemOnWidgetMethod1200(getOtherCommonData(ivar24, 1935), -1); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(subtract(ivar21, 62), add(ivar22, 29), 2, 0); + } + } + if (getOtherCommonData(ivar24, 1933) > 0) { + createExtraChild(new WidgetPointer(ivar8), 5, ivar19); + ivar19 = add(ivar19, 1); + setWidgetPosition(subtract(ivar21, 44), add(ivar22, 4), 2, 0); + setWidgetSprite(6348); + setWidgetSize(40, 34, 0, 0); + } + createExtraChild(new WidgetPointer(ivar8), 4, ivar19); + ivar19 = add(ivar19, 1); + setWidgetPosition(13, add(ivar22, 13), 2, 0); + if (getOtherCommonData(ivar24, 1937) == 4) { + ivar32 = cs2method_3408(74, 105, 5185, ivar24); + if (IsFemale()) { + setWidgetText(cs2method_3408(105, 115, 3886, ivar32)); + } else { + setWidgetText(cs2method_3408(105, 115, 3887, ivar32)); + } + setWidgetText(substr(0, subtract(strLength(getWidgetText()), 1), getWidgetText())); + } else { + setWidgetText(getOtherCommonData(ivar24, 1930)); + } + if (getOtherCommonData(ivar24, 1933) > 0) { + setWidgetText(concat(getWidgetText(), "
" + formatNumber(getOtherCommonData(ivar24, 1933), 1) + " Points")); + } else { + setWidgetText(concat(getWidgetText(), "
" + formatNumber(getOtherCommonData(ivar24, 1932), 1) + " Points")); + } + setWidgetFont(4040); + setWidgetUnknownBoolean(true); + setWidgetRGB(new Color(230, 190, 120)); + setWidgetTextAlignment(1, 1, 13); + setWidgetSize(122, 60, 0, 0); + createExtraChild(new WidgetPointer(ivar8), 4, ivar19); + ivar19 = add(ivar19, 1); + setWidgetPosition(13, add(add(add(ivar22, 13), 24), 24), 2, 0); + setWidgetText(svar2); + setWidgetFont(3793); + setWidgetUnknownBoolean(true); + setWidgetRGB(new Color(230, 190, 120)); + setWidgetTextAlignment(2, 1, 12); + setWidgetSize(122, 24, 0, 0); + ivar22 = add(add(ivar22, ivar29), ivar20); + ivar21 = 0; + ivar36 = add(ivar36, 1); + } + } else if (ivar3 == 6) { + stack_dump0 = ivar30; + stack_dump1 = ivar21; + stack_dump2 = ivar22; + stack_dump3 = ivar29; + stack_dump4 = ivar20; + stack_dump5 = ivar19; + stack_dump6 = ivar31; + stack_dump7 = ivar25; + stack_dump8 = ivar26; + stack_dump9 = ivar27; + structdump_10 = script_5352(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4, stack_dump5, stack_dump6, stack_dump7, stack_dump8, stack_dump9); + ivar19 = structdump_10.intpart_4; + ivar29 = structdump_10.intpart_3; + ivar22 = structdump_10.intpart_2; + ivar21 = structdump_10.intpart_1; + ivar30 = structdump_10.intpart_0; + svar1 = "There Are No Items Currently On Special Offer"; + ivar23 = add(add(ivar22, ivar29), ivar20); + } else if (ivar3 == 7) { + stack_dump0 = ivar30; + stack_dump1 = ivar21; + stack_dump2 = ivar22; + stack_dump3 = ivar29; + stack_dump4 = ivar20; + stack_dump5 = ivar19; + stack_dump6 = ivar31; + stack_dump7 = ivar25; + stack_dump8 = ivar26; + stack_dump9 = ivar27; + structdump_11 = script_5353(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4, stack_dump5, stack_dump6, stack_dump7, stack_dump8, stack_dump9); + ivar19 = structdump_11.intpart_4; + ivar29 = structdump_11.intpart_3; + ivar22 = structdump_11.intpart_2; + ivar21 = structdump_11.intpart_1; + ivar30 = structdump_11.intpart_0; + svar1 = "There Are No Limited Edition Items Currently Available"; + ivar23 = add(add(ivar22, ivar29), ivar20); + } else if (ivar3 == 8) { + stack_dump0 = ivar30; + stack_dump1 = ivar21; + stack_dump2 = ivar22; + stack_dump3 = ivar29; + stack_dump4 = ivar20; + stack_dump5 = ivar19; + stack_dump6 = ivar31; + stack_dump7 = ivar25; + stack_dump8 = ivar26; + stack_dump9 = ivar27; + structdump_12 = script_4727(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4, stack_dump5, stack_dump6, stack_dump7, stack_dump8, stack_dump9); + ivar19 = structdump_12.intpart_4; + ivar29 = structdump_12.intpart_3; + ivar22 = structdump_12.intpart_2; + ivar21 = structdump_12.intpart_1; + ivar30 = structdump_12.intpart_0; + svar1 = "Your Favourites List Is Currently Empty"; + ivar23 = add(add(ivar22, ivar29), ivar20); + } else if (((boolean)ivar3)) { + stack_dump0 = ivar30; + stack_dump1 = ivar21; + stack_dump2 = ivar22; + stack_dump3 = ivar29; + stack_dump4 = ivar20; + stack_dump5 = ivar19; + stack_dump6 = ivar31; + stack_dump7 = ivar25; + stack_dump8 = ivar26; + stack_dump9 = ivar27; + structdump_13 = script_4344(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4, stack_dump5, stack_dump6, stack_dump7, stack_dump8, stack_dump9); + ivar19 = structdump_13.intpart_4; + ivar29 = structdump_13.intpart_3; + ivar22 = structdump_13.intpart_2; + ivar21 = structdump_13.intpart_1; + ivar30 = structdump_13.intpart_0; + svar1 = "There Are No Items Currently Available In This Category"; + ivar23 = add(add(ivar22, ivar29), ivar20); + } else { + stack_dump0 = ivar2; + stack_dump1 = ivar30; + stack_dump2 = ivar21; + stack_dump3 = ivar22; + stack_dump4 = ivar29; + stack_dump5 = ivar20; + stack_dump6 = ivar19; + stack_dump7 = ivar31; + stack_dump8 = ivar25; + stack_dump9 = ivar26; + stack_dump14 = ivar27; + structdump_15 = script_4726(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4, stack_dump5, stack_dump6, stack_dump7, stack_dump8, stack_dump9, stack_dump14); + ivar19 = structdump_15.intpart_4; + ivar29 = structdump_15.intpart_3; + ivar22 = structdump_15.intpart_2; + ivar21 = structdump_15.intpart_1; + ivar30 = structdump_15.intpart_0; + svar1 = "There Are No Items Currently Available In This Category"; + ivar23 = add(add(ivar22, ivar29), ivar20); + } + if (((boolean)ivar19)) { + createExtraChild(new WidgetPointer(ivar8), 4, ivar19); + ivar19 = add(ivar19, 1); + setWidgetPosition(0, 0, 1, 1); + setWidgetText(svar1); + setWidgetFont(4040); + setWidgetUnknownBoolean(true); + setWidgetRGB(new Color(230, 190, 120)); + setWidgetTextAlignment(1, 1, 13); + setWidgetSize(0, 0, 1, 1); + } + if (ivar23 > getWidgetActualHeight(new WidgetPointer(ivar4))) { + setWidgetScrollMax(getWidgetActualWidth(new WidgetPointer(ivar4)), ivar23, new WidgetPointer(ivar4)); + if (bitconfig_9487 == arg0) { + cs2method2100(0, ivar5, new WidgetPointer(ivar4)); + } else { + cs2method2100(0, 0, new WidgetPointer(ivar4)); + } + setWidgetSize(getWidgetActualWidth(new WidgetPointer(ivar4)), ivar23, 0, 0, new WidgetPointer(ivar6)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(ivar4)), ivar23, 0, 0, new WidgetPointer(ivar7)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(ivar4)), ivar23, 0, 0, new WidgetPointer(ivar8)); + script_31(74907779, ivar4, 7900, 7897, 7898, 7899, 7902, 7901); + } else { + setWidgetScrollMax(getWidgetActualWidth(new WidgetPointer(ivar4)), getWidgetActualHeight(new WidgetPointer(ivar4)), new WidgetPointer(ivar4)); + cs2method2100(0, 0, new WidgetPointer(ivar4)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(ivar4)), getWidgetActualHeight(new WidgetPointer(ivar4)), 0, 0, new WidgetPointer(ivar6)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(ivar4)), getWidgetActualHeight(new WidgetPointer(ivar4)), 0, 0, new WidgetPointer(ivar7)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(ivar4)), getWidgetActualHeight(new WidgetPointer(ivar4)), 0, 0, new WidgetPointer(ivar8)); + deleteAllExtraChilds(new WidgetPointer(1143,131)); + } + setScriptCallOnConfigChange(5349, ivar3, new WidgetPointer(arg1), 2226, 2391, 2392, 2393, 2394, 5, "iIY", new WidgetPointer(arg1)); + return; +} diff --git a/dumps/scripts/5351.cs2 b/dumps/scripts/5351.cs2 new file mode 100644 index 0000000..bdf3503 --- /dev/null +++ b/dumps/scripts/5351.cs2 @@ -0,0 +1,347 @@ +cs2func_script_5351_struct(5,0,0) script_5351(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10) { + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + int ivar22; + int ivar23; + int ivar24; + int ivar25; + int ivar26; + int ivar27; + int ivar28; + int ivar29; + int ivar30; + int ivar31; + int ivar32; + int ivar33; + int ivar34; + int ivar35; + int ivar36; + int ivar37; + int ivar38; + int ivar39; + int ivar40; + int ivar41; + string svar0; + string svar1; + ivar11 = 0; + ivar12 = 0; + ivar13 = 74907774; + ivar14 = 74907707; + ivar15 = 74907693; + ivar16 = 74907694; + ivar17 = 74907695; + ivar18 = 74907696; + ivar19 = 74907697; + ivar20 = 74907688; + ivar21 = 74907689; + ivar22 = 74907690; + ivar23 = 74907691; + ivar24 = 74907692; + ivar25 = -1; + ivar26 = 0; + ivar27 = -1; + ivar28 = 0; + ivar29 = -1; + ivar30 = -1; + ivar31 = -1; + svar0 = ""; + ivar32 = 0; + ivar33 = 7874; + ivar34 = 7875; + ivar35 = 7877; + ivar36 = 7877; + ivar37 = 7875; + ivar38 = 7877; + ivar39 = 7874; + ivar40 = 15122040; + ivar41 = 0; + svar1 = "Over"; + if (arg0 != -1) { + if (arg1 >= 3) { + arg2 = arg5; + arg3 = add(add(arg3, arg4), arg5); + arg1 = 0; + } + switch (getOtherCommonData(arg0, 1937)) { + case 1: + ivar25 = ivar15; + ivar27 = 5182; + break; + case 2: + ivar25 = ivar16; + ivar27 = 3875; + break; + case 3: + ivar25 = ivar17; + if (IsFemale()) { + ivar27 = 5189; + } else { + ivar27 = 5188; + } + break; + case 4: + ivar25 = ivar18; + ivar27 = 5184; + break; + case 5: + ivar25 = ivar19; + ivar27 = 5183; + } + ivar26 = 0; + while ((arg0 != cs2method_3408(105, 74, ivar27, ivar26)) && (ivar26 < getCommonDefinitionSize(ivar27))) { + ivar26 = add(ivar26, 1); + } + ivar32 = ivar26; + createExtraChild(new WidgetPointer(ivar14), 5, arg6); + arg6 = add(arg6, 1); + setWidgetPosition(arg2, arg3, 0, 0); + setWidgetSprite(arg8); + ivar12 = 58; + arg4 = 68; + arg2 = add(arg2, ivar12); + setWidgetSize(ivar12, arg4, 0, 0); + createExtraChild(new WidgetPointer(ivar14), 4, arg6); + arg6 = add(arg6, 1); + setWidgetPosition(subtract(arg2, ivar12), arg3, 0, 0); + setWidgetSize(multiply(ivar12, 3), arg4, 0, 0); + setScriptCallOnMouseEntered(5359, new WidgetPointer(ivar14), -2147483643, arg0, 1, "IiJ1"); + setScriptCallOnMouseExit(5359, new WidgetPointer(ivar14), -2147483643, arg0, 0, "IiJ1"); + createExtraChild(new WidgetPointer(ivar14), 5, arg6); + arg6 = add(arg6, 1); + setWidgetPosition(arg2, arg3, 0, 0); + arg2 = add(arg2, ivar12); + setWidgetSprite(arg9); + setWidgetSize(ivar12, arg4, 0, 0); + createExtraChild(new WidgetPointer(ivar14), 5, arg6); + arg6 = add(arg6, 1); + setWidgetPosition(arg2, arg3, 0, 0); + arg2 = add(arg2, ivar12); + arg2 = add(arg2, arg5); + setWidgetSprite(arg10); + setWidgetSize(ivar12, arg4, 0, 0); + switch (getOtherCommonData(arg0, 1937)) { + case 1: + ivar28 = ((int)isBitFlagged(standart_config_2229, ivar32)); + break; + case 2: + ivar28 = ((int)isBitFlagged(standart_config_2230, ivar32)); + ivar41 = 1; + break; + case 3: + ivar28 = ((int)isBitFlagged(standart_config_2231, ivar32)); + break; + case 4: + ivar28 = ((int)isBitFlagged(standart_config_2232, ivar32)); + break; + case 5: + ivar28 = ((int)isBitFlagged(standart_config_2232, add(ivar32, 16))); + ivar41 = 1; + } + if (((boolean)ivar28)) { + ivar29 = 7891; + ivar30 = 7893; + ivar31 = 7895; + svar0 = "Buy"; + } else { + ivar29 = 7892; + ivar30 = 7894; + ivar31 = 7896; + svar0 = "Reclaim"; + if (((boolean)ivar41)) { + svar0 = "Unlocked"; + } + } + createExtraChild(new WidgetPointer(ivar14), 5, arg6); + arg6 = add(arg6, 1); + setWidgetPosition(subtract(arg2, 103), add(arg3, 50), 0, 0); + setWidgetSprite(ivar29); + setWidgetSize(90, 23, 0, 0); + createExtraChild(new WidgetPointer(ivar14), 5, arg6); + if (((boolean)ivar28) && ((boolean)ivar41)) { + } else { + setScriptCallOnMouseEntered(4410, new WidgetPointer(ivar14), arg6, 0, "Iii"); + setScriptCallOnMouseExit(4410, new WidgetPointer(ivar14), arg6, 1, "Iii"); + } + arg6 = add(arg6, 1); + setWidgetPosition(subtract(arg2, 103), add(arg3, 50), 0, 0); + setWidgetSprite(ivar30); + setWidgetSize(90, 23, 0, 0); + cs2method2103(255); + createExtraChild(new WidgetPointer(ivar14), 5, arg6); + if (((boolean)ivar28) && ((boolean)ivar41)) { + } else { + setScriptCallOnMousePressed(5362, new WidgetPointer(ivar14), arg6, 0, "Iii"); + setScriptCallOnMouseReleased(5362, new WidgetPointer(ivar14), arg6, 1, "Iii"); + } + arg6 = add(arg6, 1); + setWidgetPosition(subtract(arg2, 103), add(arg3, 50), 0, 0); + setWidgetSprite(ivar31); + setWidgetSize(90, 23, 0, 0); + cs2method2103(255); + ivar26 = 0; + while (ivar26 < ivar32) { + if (setWidgetRegister(new WidgetPointer(ivar25), ivar26)) { + createExtraChild(new WidgetPointer(ivar25), 4, ivar26); + setWidgetHidden(1); + } + ivar26 = add(ivar26, 1); + } + createExtraChild(new WidgetPointer(ivar25), 4, ivar32); + setWidgetPosition(subtract(arg2, 103), add(arg3, 50), 0, 0); + setWidgetText(svar0); + setWidgetFont(3793); + setWidgetUnknownBoolean(true); + setWidgetRGB(new Color(ivar40)); + setWidgetTextAlignment(1, 1, 0); + setWidgetSize(90, 23, 0, 0); + if (((boolean)ivar28) && ((boolean)ivar41)) { + } else { + setWidgetContextMenuOption(1, svar0); + } + createExtraChild(new WidgetPointer(ivar14), 4, arg6); + arg6 = add(arg6, 1); + setWidgetPosition(subtract(arg2, 120), add(arg3, 10), 0, 0); + if (getOtherCommonData(arg0, 1937) == 4) { + ivar11 = cs2method_3408(74, 105, 5185, arg0); + if (IsFemale()) { + setWidgetText(cs2method_3408(105, 115, 3886, ivar11)); + } else { + setWidgetText(cs2method_3408(105, 115, 3887, ivar11)); + } + setWidgetText(substr(0, subtract(strLength(getWidgetText()), 1), getWidgetText())); + } else { + setWidgetText(getOtherCommonData(arg0, 1930)); + } + setWidgetFont(3793); + setWidgetUnknownBoolean(true); + setWidgetRGB(new Color(ivar40)); + setWidgetTextAlignment(1, 1, 12); + setWidgetSize(107, 24, 0, 0); + if (getLineCount(getWidgetActualWidth(), getWidgetFont(), getWidgetText()) > 1) { + arg7 = 0; + } else { + arg7 = -5; + } + createExtraChild(new WidgetPointer(ivar14), 4, arg6); + arg6 = add(arg6, 1); + setWidgetPosition(subtract(arg2, 117), add(add(arg3, 34), arg7), 0, 0); + setWidgetFont(4040); + setWidgetUnknownBoolean(true); + if (getOtherCommonData(arg0, 1933) > 0) { + setWidgetText(concat(formatNumber(getOtherCommonData(arg0, 1933), 1), " Points")); + setWidgetRGB(new Color(86, 165, 204)); + } else { + setWidgetText(concat(formatNumber(getOtherCommonData(arg0, 1932), 1), " Points")); + setWidgetRGB(new Color(219, 144, 0)); + } + setWidgetTextAlignment(1, 1, 13); + setWidgetSize(79, 19, 0, 0); + switch (getOtherCommonData(arg0, 1937)) { + case 1: + ivar25 = ivar20; + break; + case 2: + ivar25 = ivar21; + break; + case 3: + ivar25 = ivar22; + break; + case 4: + ivar25 = ivar23; + break; + case 5: + ivar25 = ivar24; + } + switch (getOtherCommonData(arg0, 1937)) { + case 1: + ivar28 = ((int)isBitFlagged(standart_config_2391, ivar32)); + break; + case 2: + ivar28 = ((int)isBitFlagged(standart_config_2392, ivar32)); + break; + case 3: + ivar28 = ((int)isBitFlagged(standart_config_2393, ivar32)); + break; + case 4: + ivar28 = ((int)isBitFlagged(standart_config_2394, ivar32)); + break; + case 5: + ivar28 = ((int)isBitFlagged(standart_config_2394, add(ivar32, 16))); + } + ivar26 = 0; + while (ivar26 < ivar32) { + if (setWidgetRegister(new WidgetPointer(ivar25), ivar26)) { + createExtraChild(new WidgetPointer(ivar25), 4, ivar26); + setWidgetHidden(1); + } + ivar26 = add(ivar26, 1); + } + createExtraChild(new WidgetPointer(ivar25), 5, ivar32); + setWidgetPosition(subtract(arg2, 36), add(add(arg3, 33), arg7), 0, 0); + if (((boolean)ivar28)) { + ivar33 = ivar39; + ivar34 = ivar37; + ivar35 = ivar36; + setWidgetContextMenuOption(1, "Add to Favourites"); + if (bitconfig_9487 != 8) { + setScriptCallOnClickContextMenu(5354, new WidgetPointer(ivar25), ivar32, ivar35, ivar36, ivar38, ivar37, ivar39, "Iiddddd"); + } + } else { + ivar33 = ivar38; + ivar34 = ivar36; + ivar35 = ivar37; + setWidgetContextMenuOption(1, "Remove from Favourites"); + if (bitconfig_9487 != 8) { + setScriptCallOnClickContextMenu(5354, new WidgetPointer(ivar25), ivar32, ivar35, ivar36, ivar38, ivar37, ivar39, "Iiddddd"); + } + } + setWidgetSprite(ivar33); + setWidgetSize(21, 21, 0, 0); + setScriptCallOnMouseEntered(5343, new WidgetPointer(ivar25), ivar32, ivar34, "Iid"); + setScriptCallOnMouseExit(5343, new WidgetPointer(ivar25), ivar32, ivar33, "Iid"); + ivar32 = add(ivar32, 1); + createExtraChild(new WidgetPointer(ivar14), 5, arg6); + arg6 = add(arg6, 1); + if (((boolean)getOtherCommonData(arg0, 1937))) { + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(subtract(arg2, 162), add(arg3, 18), 0, 0); + setItemOnWidgetMethod1200(getOtherCommonData(arg0, 1935), -1); + } else if (getOtherCommonData(arg0, 1937) == 2) { + setWidgetSprite(getOtherCommonData(arg0, 1420)); + setWidgetSize(48, 48, 0, 0); + setWidgetPosition(subtract(arg2, 170), add(arg3, 11), 0, 0); + } else if (getOtherCommonData(arg0, 1937) == 3) { + setWidgetSprite(getOtherCommonData(arg0, 1441)); + setWidgetSize(40, 50, 0, 0); + setWidgetPosition(subtract(arg2, 166), add(arg3, 10), 0, 0); + } else if (getOtherCommonData(arg0, 1937) == 4) { + setWidgetSprite(7883); + setWidgetSize(42, 42, 0, 0); + setWidgetPosition(subtract(arg2, 166), add(arg3, 14), 0, 0); + } else { + if (getOtherCommonData(arg0, 1937) == 5) { + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(subtract(arg2, 161), add(arg3, 18), 0, 0); + setItemOnWidgetMethod1200(getOtherCommonData(arg0, 1935), -1); + } + } + if (getOtherCommonData(arg0, 1933) > 0) { + createExtraChild(new WidgetPointer(ivar14), 5, arg6); + arg6 = add(arg6, 1); + setWidgetPosition(subtract(arg2, 175), add(arg3, 5), 0, 0); + setWidgetSprite(6348); + setWidgetSize(40, 34, 0, 0); + } + arg1 = add(arg1, 1); + } + return newstruct cs2func_script_5351_struct(arg1, arg2, arg3, arg4, arg6); +} diff --git a/dumps/scripts/5352.cs2 b/dumps/scripts/5352.cs2 new file mode 100644 index 0000000..c104f7e --- /dev/null +++ b/dumps/scripts/5352.cs2 @@ -0,0 +1,304 @@ +cs2func_script_5352_struct(5,0,0) script_5352(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9) { + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + string svar0; + string svar1; + int stack_dump0; + int stack_dump1; + int stack_dump2; + int stack_dump3; + int stack_dump4; + int stack_dump5; + int stack_dump6; + int stack_dump7; + int stack_dump8; + int stack_dump9; + int stack_dump10; + cs2func_script_5351_struct(5,0,0) structdump_11; + flow_0: + ivar10 = -1; + ivar11 = -1; + ivar12 = 0; + ivar13 = -1; + ivar14 = 0; + ivar15 = 0; + ivar16 = 0; + ivar17 = 0; + while (ivar16 < 5) { + switch (ivar16) { + case 0: + ivar10 = 5182; + break; + case 1: + ivar10 = 3875; + break; + case 2: + if (IsFemale()) { + ivar10 = 5189; + } else { + ivar10 = 5188; + } + break; + case 3: + ivar10 = 5184; + break; + case 4: + ivar10 = 5183; + } + ivar14 = 0; + while (ivar14 < getCommonDefinitionSize(ivar10)) { + ivar11 = cs2method_3408(105, 74, ivar10, ivar14); + if (getOtherCommonData(ivar11, 1933) > 0) { + ivar15 = add(ivar15, 1); + } + ivar14 = add(ivar14, 1); + } + ivar16 = add(ivar16, 1); + } + if (ivar15 < 1) { + return newstruct cs2func_script_5352_struct(arg0, arg1, arg2, arg3, arg5); + } + globalarray_0 = new int[ivar15]; + ivar17 = subtract(ivar15, 1); + ivar16 = 0; + while (ivar16 < 5) { + switch (ivar16) { + case 0: + ivar10 = 5182; + break; + case 1: + ivar10 = 3875; + break; + case 2: + if (IsFemale()) { + ivar10 = 5189; + } else { + ivar10 = 5188; + } + break; + case 3: + ivar10 = 5184; + break; + case 4: + ivar10 = 5183; + } + ivar14 = 0; + while (ivar14 < getCommonDefinitionSize(ivar10)) { + ivar11 = cs2method_3408(105, 74, ivar10, ivar14); + if (getOtherCommonData(ivar11, 1933) > 0) { + globalarray_0[ivar17] = ivar11; + ivar17 = max(subtract(ivar17, 1), 0); + } + ivar14 = add(ivar14, 1); + } + ivar16 = add(ivar16, 1); + } + ivar14 = 0; + ivar12 = 1; + ivar18 = 0; + ivar19 = 0; + svar0 = ""; + svar1 = ""; + ivar20 = 0; + ivar21 = 0; + SWITCH (globalint_1659) { + case 1: + GOTO flow_51 + case 2: + GOTO flow_65 + case 3: + GOTO flow_97 + } + while (((boolean)ivar12)) { + ivar12 = 0; + ivar14 = subtract(ivar15, 1); + while (ivar14 > 0) { + if (getOtherCommonData(globalarray_0[ivar14], 1933) > 0) { + ivar18 = getOtherCommonData(globalarray_0[ivar14], 1933); + } else { + ivar18 = getOtherCommonData(globalarray_0[ivar14], 1932); + } + if (getOtherCommonData(globalarray_0[subtract(ivar14, 1)], 1933) > 0) { + ivar19 = getOtherCommonData(globalarray_0[subtract(ivar14, 1)], 1933); + } else { + ivar19 = getOtherCommonData(globalarray_0[subtract(ivar14, 1)], 1932); + } + if (ivar18 < ivar19) { + ivar12 = 1; + ivar13 = globalarray_0[subtract(ivar14, 1)]; + globalarray_0[subtract(ivar14, 1)] = globalarray_0[ivar14]; + globalarray_0[ivar14] = ivar13; + } + ivar14 = subtract(ivar14, 1); + } + } + flow_50: + GOTO flow_128 + flow_51: + IF (((boolean)ivar12)) + GOTO flow_52 + GOTO flow_64 + flow_52: + ivar12 = 0; + ivar14 = subtract(ivar15, 1); + while (ivar14 > 0) { + if (getOtherCommonData(globalarray_0[ivar14], 1933) > 0) { + ivar18 = getOtherCommonData(globalarray_0[ivar14], 1933); + } else { + ivar18 = getOtherCommonData(globalarray_0[ivar14], 1932); + } + if (getOtherCommonData(globalarray_0[subtract(ivar14, 1)], 1933) > 0) { + ivar19 = getOtherCommonData(globalarray_0[subtract(ivar14, 1)], 1933); + } else { + ivar19 = getOtherCommonData(globalarray_0[subtract(ivar14, 1)], 1932); + } + if (ivar18 > ivar19) { + ivar12 = 1; + ivar13 = globalarray_0[subtract(ivar14, 1)]; + globalarray_0[subtract(ivar14, 1)] = globalarray_0[ivar14]; + globalarray_0[ivar14] = ivar13; + } + ivar14 = subtract(ivar14, 1); + } + GOTO flow_51 + flow_64: + GOTO flow_128 + flow_65: + IF (((boolean)ivar12)) + GOTO flow_66 + GOTO flow_96 + flow_66: + ivar12 = 0; + ivar14 = subtract(ivar15, 1); + while (ivar14 > 0) { + if (getOtherCommonData(globalarray_0[ivar14], 1937) == 4) { + ivar20 = 0; + ivar21 = 0; + while ((ivar20 < getCommonDefinitionSize(5184)) && ((boolean)ivar21)) { + if (cs2method_3408(105, 74, 5184, ivar20) == globalarray_0[ivar14]) { + if (IsFemale()) { + svar0 = cs2method_3408(105, 115, 5186, ivar20); + } else { + svar0 = cs2method_3408(105, 115, 5187, ivar20); + } + ivar21 = 1; + } + ivar20 = add(ivar20, 1); + } + } else { + svar0 = getOtherCommonData(globalarray_0[ivar14], 1930); + } + if (getOtherCommonData(globalarray_0[subtract(ivar14, 1)], 1937) == 4) { + ivar20 = 0; + ivar21 = 0; + while ((ivar20 < getCommonDefinitionSize(5184)) && ((boolean)ivar21)) { + if (cs2method_3408(105, 74, 5184, ivar20) == globalarray_0[subtract(ivar14, 1)]) { + if (IsFemale()) { + svar1 = cs2method_3408(105, 115, 5186, ivar20); + } else { + svar1 = cs2method_3408(105, 115, 5187, ivar20); + } + ivar21 = 1; + } + ivar20 = add(ivar20, 1); + } + } else { + svar1 = getOtherCommonData(globalarray_0[subtract(ivar14, 1)], 1930); + } + if (stringMethod4107(svar0, svar1) < 0) { + ivar12 = 1; + ivar13 = globalarray_0[subtract(ivar14, 1)]; + globalarray_0[subtract(ivar14, 1)] = globalarray_0[ivar14]; + globalarray_0[ivar14] = ivar13; + } + ivar14 = subtract(ivar14, 1); + } + GOTO flow_65 + flow_96: + GOTO flow_128 + flow_97: + IF (((boolean)ivar12)) + GOTO flow_98 + GOTO flow_128 + flow_98: + ivar12 = 0; + ivar14 = subtract(ivar15, 1); + while (ivar14 > 0) { + if (getOtherCommonData(globalarray_0[ivar14], 1937) == 4) { + ivar20 = 0; + ivar21 = 0; + while ((ivar20 < getCommonDefinitionSize(5184)) && ((boolean)ivar21)) { + if (cs2method_3408(105, 74, 5184, ivar20) == globalarray_0[ivar14]) { + if (IsFemale()) { + svar0 = cs2method_3408(105, 115, 5186, ivar20); + } else { + svar0 = cs2method_3408(105, 115, 5187, ivar20); + } + ivar21 = 1; + } + ivar20 = add(ivar20, 1); + } + } else { + svar0 = getOtherCommonData(globalarray_0[ivar14], 1930); + } + if (getOtherCommonData(globalarray_0[subtract(ivar14, 1)], 1937) == 4) { + ivar20 = 0; + ivar21 = 0; + while ((ivar20 < getCommonDefinitionSize(5184)) && ((boolean)ivar21)) { + if (cs2method_3408(105, 74, 5184, ivar20) == globalarray_0[subtract(ivar14, 1)]) { + if (IsFemale()) { + svar1 = cs2method_3408(105, 115, 5186, ivar20); + } else { + svar1 = cs2method_3408(105, 115, 5187, ivar20); + } + ivar21 = 1; + } + ivar20 = add(ivar20, 1); + } + } else { + svar1 = getOtherCommonData(globalarray_0[subtract(ivar14, 1)], 1930); + } + if (stringMethod4107(svar0, svar1) > 0) { + ivar12 = 1; + ivar13 = globalarray_0[subtract(ivar14, 1)]; + globalarray_0[subtract(ivar14, 1)] = globalarray_0[ivar14]; + globalarray_0[ivar14] = ivar13; + } + ivar14 = subtract(ivar14, 1); + } + GOTO flow_97 + flow_128: + ivar14 = 0; + while (ivar14 < ivar15) { + ivar11 = globalarray_0[ivar14]; + stack_dump0 = ivar11; + stack_dump1 = arg0; + stack_dump2 = arg1; + stack_dump3 = arg2; + stack_dump4 = arg3; + stack_dump5 = arg4; + stack_dump6 = arg5; + stack_dump7 = arg6; + stack_dump8 = arg7; + stack_dump9 = arg8; + stack_dump10 = arg9; + structdump_11 = script_5351(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4, stack_dump5, stack_dump6, stack_dump7, stack_dump8, stack_dump9, stack_dump10); + arg5 = structdump_11.intpart_4; + arg3 = structdump_11.intpart_3; + arg2 = structdump_11.intpart_2; + arg1 = structdump_11.intpart_1; + arg0 = structdump_11.intpart_0; + ivar14 = add(ivar14, 1); + } + return newstruct cs2func_script_5352_struct(arg0, arg1, arg2, arg3, arg5); +} diff --git a/dumps/scripts/5353.cs2 b/dumps/scripts/5353.cs2 new file mode 100644 index 0000000..a735d41 --- /dev/null +++ b/dumps/scripts/5353.cs2 @@ -0,0 +1,304 @@ +cs2func_script_5353_struct(5,0,0) script_5353(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9) { + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + string svar0; + string svar1; + int stack_dump0; + int stack_dump1; + int stack_dump2; + int stack_dump3; + int stack_dump4; + int stack_dump5; + int stack_dump6; + int stack_dump7; + int stack_dump8; + int stack_dump9; + int stack_dump10; + cs2func_script_5351_struct(5,0,0) structdump_11; + flow_0: + ivar10 = -1; + ivar11 = -1; + ivar12 = 0; + ivar13 = -1; + ivar14 = 0; + ivar15 = 0; + ivar16 = 0; + ivar17 = 0; + while (ivar16 < 5) { + switch (ivar16) { + case 0: + ivar10 = 5182; + break; + case 1: + ivar10 = 3875; + break; + case 2: + if (IsFemale()) { + ivar10 = 5189; + } else { + ivar10 = 5188; + } + break; + case 3: + ivar10 = 5184; + break; + case 4: + ivar10 = 5183; + } + ivar14 = 0; + while (ivar14 < getCommonDefinitionSize(ivar10)) { + ivar11 = cs2method_3408(105, 74, ivar10, ivar14); + if (((boolean)getOtherCommonData(ivar11, 1934))) { + ivar15 = add(ivar15, 1); + } + ivar14 = add(ivar14, 1); + } + ivar16 = add(ivar16, 1); + } + if (ivar15 < 1) { + return newstruct cs2func_script_5353_struct(arg0, arg1, arg2, arg3, arg5); + } + globalarray_0 = new int[ivar15]; + ivar17 = subtract(ivar15, 1); + ivar16 = 0; + while (ivar16 < 5) { + switch (ivar16) { + case 0: + ivar10 = 5182; + break; + case 1: + ivar10 = 3875; + break; + case 2: + if (IsFemale()) { + ivar10 = 5189; + } else { + ivar10 = 5188; + } + break; + case 3: + ivar10 = 5184; + break; + case 4: + ivar10 = 5183; + } + ivar14 = 0; + while (ivar14 < getCommonDefinitionSize(ivar10)) { + ivar11 = cs2method_3408(105, 74, ivar10, ivar14); + if (((boolean)getOtherCommonData(ivar11, 1934))) { + globalarray_0[ivar17] = ivar11; + ivar17 = max(subtract(ivar17, 1), 0); + } + ivar14 = add(ivar14, 1); + } + ivar16 = add(ivar16, 1); + } + ivar14 = 0; + ivar12 = 1; + ivar18 = 0; + ivar19 = 0; + svar0 = ""; + svar1 = ""; + ivar20 = 0; + ivar21 = 0; + SWITCH (globalint_1659) { + case 1: + GOTO flow_51 + case 2: + GOTO flow_65 + case 3: + GOTO flow_97 + } + while (((boolean)ivar12)) { + ivar12 = 0; + ivar14 = subtract(ivar15, 1); + while (ivar14 > 0) { + if (getOtherCommonData(globalarray_0[ivar14], 1933) > 0) { + ivar18 = getOtherCommonData(globalarray_0[ivar14], 1933); + } else { + ivar18 = getOtherCommonData(globalarray_0[ivar14], 1932); + } + if (getOtherCommonData(globalarray_0[subtract(ivar14, 1)], 1933) > 0) { + ivar19 = getOtherCommonData(globalarray_0[subtract(ivar14, 1)], 1933); + } else { + ivar19 = getOtherCommonData(globalarray_0[subtract(ivar14, 1)], 1932); + } + if (ivar18 < ivar19) { + ivar12 = 1; + ivar13 = globalarray_0[subtract(ivar14, 1)]; + globalarray_0[subtract(ivar14, 1)] = globalarray_0[ivar14]; + globalarray_0[ivar14] = ivar13; + } + ivar14 = subtract(ivar14, 1); + } + } + flow_50: + GOTO flow_128 + flow_51: + IF (((boolean)ivar12)) + GOTO flow_52 + GOTO flow_64 + flow_52: + ivar12 = 0; + ivar14 = subtract(ivar15, 1); + while (ivar14 > 0) { + if (getOtherCommonData(globalarray_0[ivar14], 1933) > 0) { + ivar18 = getOtherCommonData(globalarray_0[ivar14], 1933); + } else { + ivar18 = getOtherCommonData(globalarray_0[ivar14], 1932); + } + if (getOtherCommonData(globalarray_0[subtract(ivar14, 1)], 1933) > 0) { + ivar19 = getOtherCommonData(globalarray_0[subtract(ivar14, 1)], 1933); + } else { + ivar19 = getOtherCommonData(globalarray_0[subtract(ivar14, 1)], 1932); + } + if (ivar18 > ivar19) { + ivar12 = 1; + ivar13 = globalarray_0[subtract(ivar14, 1)]; + globalarray_0[subtract(ivar14, 1)] = globalarray_0[ivar14]; + globalarray_0[ivar14] = ivar13; + } + ivar14 = subtract(ivar14, 1); + } + GOTO flow_51 + flow_64: + GOTO flow_128 + flow_65: + IF (((boolean)ivar12)) + GOTO flow_66 + GOTO flow_96 + flow_66: + ivar12 = 0; + ivar14 = subtract(ivar15, 1); + while (ivar14 > 0) { + if (getOtherCommonData(globalarray_0[ivar14], 1937) == 4) { + ivar20 = 0; + ivar21 = 0; + while ((ivar20 < getCommonDefinitionSize(5184)) && ((boolean)ivar21)) { + if (cs2method_3408(105, 74, 5184, ivar20) == globalarray_0[ivar14]) { + if (IsFemale()) { + svar0 = cs2method_3408(105, 115, 5186, ivar20); + } else { + svar0 = cs2method_3408(105, 115, 5187, ivar20); + } + ivar21 = 1; + } + ivar20 = add(ivar20, 1); + } + } else { + svar0 = getOtherCommonData(globalarray_0[ivar14], 1930); + } + if (getOtherCommonData(globalarray_0[subtract(ivar14, 1)], 1937) == 4) { + ivar20 = 0; + ivar21 = 0; + while ((ivar20 < getCommonDefinitionSize(5184)) && ((boolean)ivar21)) { + if (cs2method_3408(105, 74, 5184, ivar20) == globalarray_0[subtract(ivar14, 1)]) { + if (IsFemale()) { + svar1 = cs2method_3408(105, 115, 5186, ivar20); + } else { + svar1 = cs2method_3408(105, 115, 5187, ivar20); + } + ivar21 = 1; + } + ivar20 = add(ivar20, 1); + } + } else { + svar1 = getOtherCommonData(globalarray_0[subtract(ivar14, 1)], 1930); + } + if (stringMethod4107(svar0, svar1) < 0) { + ivar12 = 1; + ivar13 = globalarray_0[subtract(ivar14, 1)]; + globalarray_0[subtract(ivar14, 1)] = globalarray_0[ivar14]; + globalarray_0[ivar14] = ivar13; + } + ivar14 = subtract(ivar14, 1); + } + GOTO flow_65 + flow_96: + GOTO flow_128 + flow_97: + IF (((boolean)ivar12)) + GOTO flow_98 + GOTO flow_128 + flow_98: + ivar12 = 0; + ivar14 = subtract(ivar15, 1); + while (ivar14 > 0) { + if (getOtherCommonData(globalarray_0[ivar14], 1937) == 4) { + ivar20 = 0; + ivar21 = 0; + while ((ivar20 < getCommonDefinitionSize(5184)) && ((boolean)ivar21)) { + if (cs2method_3408(105, 74, 5184, ivar20) == globalarray_0[ivar14]) { + if (IsFemale()) { + svar0 = cs2method_3408(105, 115, 5186, ivar20); + } else { + svar0 = cs2method_3408(105, 115, 5187, ivar20); + } + ivar21 = 1; + } + ivar20 = add(ivar20, 1); + } + } else { + svar0 = getOtherCommonData(globalarray_0[ivar14], 1930); + } + if (getOtherCommonData(globalarray_0[subtract(ivar14, 1)], 1937) == 4) { + ivar20 = 0; + ivar21 = 0; + while ((ivar20 < getCommonDefinitionSize(5184)) && ((boolean)ivar21)) { + if (cs2method_3408(105, 74, 5184, ivar20) == globalarray_0[subtract(ivar14, 1)]) { + if (IsFemale()) { + svar1 = cs2method_3408(105, 115, 5186, ivar20); + } else { + svar1 = cs2method_3408(105, 115, 5187, ivar20); + } + ivar21 = 1; + } + ivar20 = add(ivar20, 1); + } + } else { + svar1 = getOtherCommonData(globalarray_0[subtract(ivar14, 1)], 1930); + } + if (stringMethod4107(svar0, svar1) > 0) { + ivar12 = 1; + ivar13 = globalarray_0[subtract(ivar14, 1)]; + globalarray_0[subtract(ivar14, 1)] = globalarray_0[ivar14]; + globalarray_0[ivar14] = ivar13; + } + ivar14 = subtract(ivar14, 1); + } + GOTO flow_97 + flow_128: + ivar14 = 0; + while (ivar14 < ivar15) { + ivar11 = globalarray_0[ivar14]; + stack_dump0 = ivar11; + stack_dump1 = arg0; + stack_dump2 = arg1; + stack_dump3 = arg2; + stack_dump4 = arg3; + stack_dump5 = arg4; + stack_dump6 = arg5; + stack_dump7 = arg6; + stack_dump8 = arg7; + stack_dump9 = arg8; + stack_dump10 = arg9; + structdump_11 = script_5351(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4, stack_dump5, stack_dump6, stack_dump7, stack_dump8, stack_dump9, stack_dump10); + arg5 = structdump_11.intpart_4; + arg3 = structdump_11.intpart_3; + arg2 = structdump_11.intpart_2; + arg1 = structdump_11.intpart_1; + arg0 = structdump_11.intpart_0; + ivar14 = add(ivar14, 1); + } + return newstruct cs2func_script_5353_struct(arg0, arg1, arg2, arg3, arg5); +} diff --git a/dumps/scripts/5354.cs2 b/dumps/scripts/5354.cs2 new file mode 100644 index 0000000..6d637b2 --- /dev/null +++ b/dumps/scripts/5354.cs2 @@ -0,0 +1,13 @@ +void script_5354(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetSprite(arg2); + if (arg2 == arg3) { + setScriptCallOnMouseEntered(5343, new WidgetPointer(arg0), arg1, arg3, "Iid"); + setScriptCallOnMouseExit(5343, new WidgetPointer(arg0), arg1, arg4, "Iid"); + } else { + setScriptCallOnMouseEntered(5343, new WidgetPointer(arg0), arg1, arg5, "Iid"); + setScriptCallOnMouseExit(5343, new WidgetPointer(arg0), arg1, arg6, "Iid"); + } + } + return; +} diff --git a/dumps/scripts/5355.cs2 b/dumps/scripts/5355.cs2 new file mode 100644 index 0000000..e342385 --- /dev/null +++ b/dumps/scripts/5355.cs2 @@ -0,0 +1,160 @@ +void script_5355(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + string svar0; + flow_0: + ivar2 = 0; + ivar3 = 0; + ivar4 = 0; + ivar5 = 0; + ivar6 = 0; + ivar7 = 0; + ivar8 = 0; + ivar9 = 0; + ivar10 = 0; + ivar11 = -1; + svar0 = getOtherCommonData(arg0, 1930); + IF ((getOtherCommonData(arg0, 1937) == 4) && (ivar9 < getCommonDefinitionSize(5184))) + GOTO flow_2 + GOTO flow_9 + flow_1: + flow_2: + IF (((boolean)ivar10)) + GOTO flow_3 + GOTO flow_9 + flow_3: + if (cs2method_3408(105, 74, 5184, ivar9) == arg0) { + if (IsFemale()) { + svar0 = cs2method_3408(105, 115, 5187, ivar9); + } else { + svar0 = cs2method_3408(105, 115, 5186, ivar9); + } + ivar10 = 1; + } + ivar9 = add(ivar9, 1); + GOTO flow_1 + flow_9: + setWidgetText(new WidgetPointer(1143,25), svar0); + if (((boolean)arg1)) { + setWidgetIsHidden(true, new WidgetPointer(1143,26)); + setWidgetIsHidden(true, new WidgetPointer(1143,27)); + setWidgetIsHidden(true, new WidgetPointer(1143,19)); + setWidgetPosition(0, 186, 1, 0, new WidgetPointer(1143,28)); + setWidgetPosition(0, 228, 1, 0, new WidgetPointer(1143,32)); + setWidgetText(new WidgetPointer(1143,186), "Reclaim"); + setWidgetContextMenuOption(1, new WidgetPointer(1143,186), "Reclaim"); + } else if (getOtherCommonData(arg0, 1933) > 0) { + setWidgetText(new WidgetPointer(1143,27), concat("Item Cost: ", formatNumber(getOtherCommonData(arg0, 1933), 1))); + } else { + setWidgetText(new WidgetPointer(1143,27), concat("Item Cost: ", formatNumber(getOtherCommonData(arg0, 1932), 1))); + } + setWidgetIsHidden(false, new WidgetPointer(1143,26)); + setWidgetIsHidden(false, new WidgetPointer(1143,27)); + setWidgetIsHidden(false, new WidgetPointer(1143,19)); + setWidgetPosition(0, 239, 1, 0, new WidgetPointer(1143,28)); + setWidgetPosition(0, 266, 1, 0, new WidgetPointer(1143,32)); + setWidgetText(new WidgetPointer(1143,186), "Buy"); + setWidgetContextMenuOption(1, new WidgetPointer(1143,186), "Buy"); + setWidgetText(new WidgetPointer(1143,26), concat("My Points: ", formatNumber(globalint_1648, 1))); + setWidgetIsHidden(false, new WidgetPointer(1143,28)); + setWidgetIsHidden(false, new WidgetPointer(1143,29)); + if (getOtherCommonData(arg0, 1950) != -1) { + ivar2 = 5; + } else if (getOtherCommonData(arg0, 1949) != -1) { + ivar2 = 4; + } else if (getOtherCommonData(arg0, 1948) != -1) { + ivar2 = 3; + } else if (getOtherCommonData(arg0, 1947) != -1) { + ivar2 = 2; + } else { + ivar2 = 1; + setWidgetIsHidden(true, new WidgetPointer(1143,28)); + setWidgetIsHidden(true, new WidgetPointer(1143,29)); + setWidgetPosition(0, 260, 1, 0, new WidgetPointer(1143,32)); + } + ivar6 = 63; + ivar7 = 57; + ivar5 = divide(subtract(getWidgetActualWidth(new WidgetPointer(1143,32)), multiply(ivar2, ivar6)), add(ivar2, 1)); + ivar8 = ivar5; + deleteAllExtraChilds(new WidgetPointer(1143,32)); + deleteAllExtraChilds(new WidgetPointer(1143,20)); + ivar9 = 0; + while (ivar9 < ivar2) { + switch (ivar9) { + case 0: + ivar11 = arg0; + break; + case 1: + ivar11 = getOtherCommonData(arg0, 1947); + break; + case 2: + ivar11 = getOtherCommonData(arg0, 1948); + break; + case 3: + ivar11 = getOtherCommonData(arg0, 1949); + break; + case 4: + ivar11 = getOtherCommonData(arg0, 1950); + } + createExtraChild(new WidgetPointer(1143,32), 3, ivar3); + ivar3 = add(ivar3, 1); + setWidgetRGB(new Color(0, 0, 0)); + setWidgetSize(ivar6, ivar7, 0, 0); + setWidgetPosition(ivar8, 0, 0, 0); + cs2method2103(100); + setWidgetFilled(1); + if (ivar2 > 1) { + createExtraChild(new WidgetPointer(1143,20), 4, ivar4); + setWidgetSize(ivar6, ivar7, 0, 0); + setWidgetPosition(ivar8, 0, 0, 0); + setWidgetContextMenuOption(1, "Select"); + setScriptCallOnClickContextMenu(5358, ivar4, new WidgetPointer(1143,32), "iI"); + ivar4 = add(ivar4, 1); + } + createExtraChild(new WidgetPointer(1143,32), 5, ivar3); + setWidgetSprite(7766); + setWidgetSize(ivar6, ivar7, 0, 0); + setWidgetPosition(ivar8, 0, 0, 0); + if (ivar2 > 1) { + setScriptCallOnMouseEntered(5356, ivar3, new WidgetPointer(1143,32), ivar11, "iIJ"); + setScriptCallOnMouseExit(5357, ivar3, new WidgetPointer(1143,32), "iI"); + } + ivar3 = add(ivar3, 1); + createExtraChild(new WidgetPointer(1143,32), 5, ivar3); + ivar3 = add(ivar3, 1); + if (((boolean)getOtherCommonData(ivar11, 1937))) { + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(add(add(ivar8, divide(subtract(ivar6, getWidgetActualWidth()), 2)), 2), add(divide(subtract(ivar7, getWidgetActualHeight()), 2), 1), 0, 0); + setItemOnWidgetMethod1200(getOtherCommonData(ivar11, 1935), -1); + } else if (getOtherCommonData(ivar11, 1937) == 2) { + setWidgetSprite(getOtherCommonData(ivar11, 1420)); + setWidgetSize(48, 48, 0, 0); + setWidgetPosition(add(ivar8, divide(subtract(ivar6, getWidgetActualWidth()), 2)), divide(subtract(ivar7, getWidgetActualHeight()), 2), 0, 0); + } else if (getOtherCommonData(ivar11, 1937) == 3) { + setWidgetSprite(getOtherCommonData(ivar11, 1441)); + setWidgetSize(40, 50, 0, 0); + setWidgetPosition(add(ivar8, divide(subtract(ivar6, getWidgetActualWidth()), 2)), divide(subtract(ivar7, getWidgetActualHeight()), 2), 0, 0); + } else if (getOtherCommonData(ivar11, 1937) == 4) { + setWidgetSprite(7883); + setWidgetSize(42, 42, 0, 0); + setWidgetPosition(add(add(ivar8, divide(subtract(ivar6, getWidgetActualWidth()), 2)), 1), add(divide(subtract(ivar7, getWidgetActualHeight()), 2), 1), 0, 0); + } else { + if (getOtherCommonData(ivar11, 1937) == 5) { + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(add(ivar8, divide(subtract(ivar6, getWidgetActualWidth()), 2)), divide(subtract(ivar7, getWidgetActualHeight()), 2), 0, 0); + setItemOnWidgetMethod1200(getOtherCommonData(ivar11, 1935), -1); + } + } + ivar8 = add(add(ivar8, ivar6), ivar5); + ivar9 = add(ivar9, 1); + } + return; +} diff --git a/dumps/scripts/5356.cs2 b/dumps/scripts/5356.cs2 new file mode 100644 index 0000000..dd89721 --- /dev/null +++ b/dumps/scripts/5356.cs2 @@ -0,0 +1,7 @@ +void script_5356(int arg0,int arg1,int arg2) { + if (setWidgetRegister(new WidgetPointer(arg1), arg0)) { + setWidgetSprite(7767); + setWidgetText(new WidgetPointer(1143,29), getOtherCommonData(arg2, 1994)); + } + return; +} diff --git a/dumps/scripts/5357.cs2 b/dumps/scripts/5357.cs2 new file mode 100644 index 0000000..1b062ca --- /dev/null +++ b/dumps/scripts/5357.cs2 @@ -0,0 +1,7 @@ +void script_5357(int arg0,int arg1) { + if (setWidgetRegister(new WidgetPointer(arg1), arg0)) { + setWidgetSprite(7766); + setWidgetText(new WidgetPointer(1143,29), ""); + } + return; +} diff --git a/dumps/scripts/5358.cs2 b/dumps/scripts/5358.cs2 new file mode 100644 index 0000000..88b0de9 --- /dev/null +++ b/dumps/scripts/5358.cs2 @@ -0,0 +1,46 @@ +void script_5358(int arg0,int arg1) { + switch (arg0) { + case 0: + arg0 = 1; + break; + case 1: + arg0 = 4; + break; + case 2: + arg0 = 7; + break; + case 3: + arg0 = 10; + break; + case 4: + arg0 = 13; + break; + default: + return; + } + if (setWidgetRegister(new WidgetPointer(arg1), 1)) { + setWidgetSprite(7766); + setScriptCallOnMouseExit(5357, 1, new WidgetPointer(arg1), "iI"); + } + if (setWidgetRegister(new WidgetPointer(arg1), 4)) { + setWidgetSprite(7766); + setScriptCallOnMouseExit(5357, 4, new WidgetPointer(arg1), "iI"); + } + if (setWidgetRegister(new WidgetPointer(arg1), 7)) { + setWidgetSprite(7766); + setScriptCallOnMouseExit(5357, 7, new WidgetPointer(arg1), "iI"); + } + if (setWidgetRegister(new WidgetPointer(arg1), 10)) { + setWidgetSprite(7766); + setScriptCallOnMouseExit(5357, 10, new WidgetPointer(arg1), "iI"); + } + if (setWidgetRegister(new WidgetPointer(arg1), 13)) { + setWidgetSprite(7766); + setScriptCallOnMouseExit(5357, 13, new WidgetPointer(arg1), "iI"); + } + if (setWidgetRegister(new WidgetPointer(arg1), arg0)) { + setWidgetSprite(7767); + setScriptCallOnMouseExit(-1, ""); + } + return; +} diff --git a/dumps/scripts/5359.cs2 b/dumps/scripts/5359.cs2 new file mode 100644 index 0000000..7d092ff --- /dev/null +++ b/dumps/scripts/5359.cs2 @@ -0,0 +1,124 @@ +void script_5359(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + string svar0; + string svar1; + string svar2; + string svar3; + string svar4; + ivar4 = 0; + ivar5 = 0; + ivar6 = 0; + ivar7 = 0; + ivar8 = 4; + ivar9 = getOtherCommonData(arg2, 1935); + ivar10 = 0; + ivar11 = 0; + ivar12 = 0; + svar0 = ""; + svar1 = ""; + svar2 = ""; + svar3 = ""; + svar4 = ""; + ivar13 = 0; + ivar14 = 0; + if ((((boolean)arg3) && (getOtherCommonData(arg2, 1937) != 2)) && setWidgetRegister(new WidgetPointer(arg0), arg1)) { + ivar4 = getWidgetActualX(); + ivar5 = getWidgetActualY(); + ivar6 = getWidgetActualWidth(); + ivar4 = add(ivar4, ivar6); + ivar5 = add(ivar5, ivar8); + setWidgetPosition(ivar4, ivar5, 0, 0, new WidgetPointer(1143,62)); + setWidgetText(new WidgetPointer(1143,130), getOtherCommonData(arg2, 1931)); + if (((boolean)getOtherCommonData(arg2, 1937))) { + ivar10 = divide(getItemHashmapData(ivar9, 1430), 100); + svar0 = "Duration: " + intToStr(ivar10) + " mins."; + ivar11 = divide(getItemHashmapData(ivar9, 1429), 100); + svar1 = "Recharge: " + intToStr(ivar11) + " mins."; + if (ivar10 > 60) { + ivar12 = mod(ivar10, 60); + ivar10 = divide(ivar10, 60); + if (ivar12 > 0) { + if (ivar10 > 1) { + svar0 = "Duration: " + intToStr(ivar10) + " hours, " + intToStr(ivar12) + " mins."; + } else { + svar0 = "Duration: 1 hour, " + intToStr(ivar12) + " mins."; + } + } else if (ivar10 > 1) { + svar0 = "Duration: " + intToStr(ivar10) + " hours."; + } else { + svar0 = "Duration: 1 hour."; + } + } + if (ivar11 > 60) { + ivar12 = mod(ivar11, 60); + ivar11 = divide(ivar11, 60); + if (ivar12 > 0) { + if (ivar11 > 1) { + svar1 = "Recharge: " + intToStr(ivar11) + " hours, " + intToStr(ivar12) + " mins."; + } else { + svar1 = "Recharge: 1 hour, " + intToStr(ivar12) + " mins."; + } + } else if (ivar11 > 1) { + svar1 = "Recharge: " + intToStr(ivar11) + " hours."; + } else { + svar1 = "Recharge: 1 hour."; + } + } + svar2 = "
" + "
" + svar0 + "
" + svar1; + setWidgetText(new WidgetPointer(1143,130), concat(getWidgetText(new WidgetPointer(1143,130)), svar2)); + } else { + if (getOtherCommonData(arg2, 1937) == 4) { + while ((ivar13 < getCommonDefinitionSize(5184)) && ((boolean)ivar14)) { + if (cs2method_3408(105, 74, 5184, ivar13) == arg2) { + svar4 = cs2method_3408(105, 115, 5187, ivar13); + svar3 = cs2method_3408(105, 115, 5186, ivar13); + ivar14 = 1; + } + ivar13 = add(ivar13, 1); + } + svar3 = concat("Male Title: ", svar3); + svar4 = concat("Female Title: ", svar4); + setWidgetText(new WidgetPointer(1143,130), svar3 + "
" + svar4); + } + } + ivar7 = getLineCount(getWidgetActualWidth(new WidgetPointer(1143,130)), getWidgetFont(new WidgetPointer(1143,130)), getWidgetText(new WidgetPointer(1143,130))); + ivar7 = add(multiply(ivar7, 13), multiply(ivar8, 2)); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(1143,62)), ivar7, 0, 0, new WidgetPointer(1143,62)); + setWidgetIsHidden(false, new WidgetPointer(1143,62)); + if (add(getWidgetActualWidth(new WidgetPointer(1143,62)), getWidgetActualX(new WidgetPointer(1143,62))) > getWidgetActualWidth(new WidgetPointer(1143,126))) { + ivar4 = add(subtract(getWidgetActualX(), getWidgetActualWidth(new WidgetPointer(1143,62))), 2); + setWidgetPosition(ivar4, ivar5, 0, 0, new WidgetPointer(1143,62)); + setWidgetPosition(12, getWidgetActualY(new WidgetPointer(1143,12)), 2, 0, new WidgetPointer(1143,12)); + setWidgetPosition(10, getWidgetActualY(new WidgetPointer(1143,127)), 2, 0, new WidgetPointer(1143,127)); + setWidgetPosition(11, getWidgetActualY(new WidgetPointer(1143,128)), 2, 0, new WidgetPointer(1143,128)); + setWidgetPosition(14, getWidgetActualY(new WidgetPointer(1143,130)), 2, 0, new WidgetPointer(1143,130)); + setWidgetPosition(0, 10, 2, 0, new WidgetPointer(1143,129)); + setWidgetHFlip(1, new WidgetPointer(1143,129)); + } else { + setWidgetPosition(12, getWidgetActualY(new WidgetPointer(1143,12)), 0, 0, new WidgetPointer(1143,12)); + setWidgetPosition(10, getWidgetActualY(new WidgetPointer(1143,127)), 0, 0, new WidgetPointer(1143,127)); + setWidgetPosition(11, getWidgetActualY(new WidgetPointer(1143,128)), 0, 0, new WidgetPointer(1143,128)); + setWidgetPosition(14, getWidgetActualY(new WidgetPointer(1143,130)), 0, 0, new WidgetPointer(1143,130)); + setWidgetPosition(0, 10, 0, 0, new WidgetPointer(1143,129)); + setWidgetHFlip(0, new WidgetPointer(1143,129)); + } + if (getWidgetActualHeight(new WidgetPointer(1143,62)) < add(getWidgetActualHeight(new WidgetPointer(1143,129)), 40)) { + setWidgetPosition(getWidgetActualX(new WidgetPointer(1143,129)), 0, 0, 1, new WidgetPointer(1143,129)); + } else { + setWidgetPosition(getWidgetActualX(new WidgetPointer(1143,129)), 10, 0, 0, new WidgetPointer(1143,129)); + } + return; + } + setWidgetIsHidden(true, new WidgetPointer(1143,62)); + return; +} diff --git a/dumps/scripts/536.cs2 b/dumps/scripts/536.cs2 new file mode 100644 index 0000000..6edefb1 --- /dev/null +++ b/dumps/scripts/536.cs2 @@ -0,0 +1,4 @@ +void script_536() { + setScriptCallOnGameloop(537, getClientCycle(), add(getClientCycle(), 25), "ii", new WidgetPointer(745,2)); + return; +} diff --git a/dumps/scripts/5360.cs2 b/dumps/scripts/5360.cs2 new file mode 100644 index 0000000..c51511e --- /dev/null +++ b/dumps/scripts/5360.cs2 @@ -0,0 +1,24 @@ +void script_5360(int arg0,int arg1,int arg2,int arg3,int arg4) { + if (((boolean)arg4)) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetSprite(7829); + } + if (setWidgetRegister(new WidgetPointer(arg0), arg2)) { + setWidgetSprite(7830); + } + if (setWidgetRegister(new WidgetPointer(arg0), arg3)) { + setWidgetSprite(7831); + } + } else { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetSprite(7826); + } + if (setWidgetRegister(new WidgetPointer(arg0), arg2)) { + setWidgetSprite(7827); + } + if (setWidgetRegister(new WidgetPointer(arg0), arg3)) { + setWidgetSprite(7828); + } + } + return; +} diff --git a/dumps/scripts/5361.cs2 b/dumps/scripts/5361.cs2 new file mode 100644 index 0000000..13b7c55 --- /dev/null +++ b/dumps/scripts/5361.cs2 @@ -0,0 +1,6 @@ +void script_5361(int arg0,int arg1,int arg2,int arg3) { + script_4208(arg0, arg3); + script_4208(arg1, arg3); + script_4208(arg2, arg3); + return; +} diff --git a/dumps/scripts/5362.cs2 b/dumps/scripts/5362.cs2 new file mode 100644 index 0000000..e8c7c81 --- /dev/null +++ b/dumps/scripts/5362.cs2 @@ -0,0 +1,4 @@ +void script_5362(int arg0,int arg1,int arg2) { + script_5363(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/5363.cs2 b/dumps/scripts/5363.cs2 new file mode 100644 index 0000000..c84cbc4 --- /dev/null +++ b/dumps/scripts/5363.cs2 @@ -0,0 +1,10 @@ +void script_5363(int arg0,int arg1,int arg2) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + if (((boolean)arg2)) { + cs2method2103(0); + } else { + cs2method2103(255); + } + } + return; +} diff --git a/dumps/scripts/5364.cs2 b/dumps/scripts/5364.cs2 new file mode 100644 index 0000000..f930622 --- /dev/null +++ b/dumps/scripts/5364.cs2 @@ -0,0 +1,6 @@ +void script_5364(int arg0,int arg1,int arg2,int arg3) { + script_5365(arg0, arg3); + script_5365(arg1, arg3); + script_5365(arg2, arg3); + return; +} diff --git a/dumps/scripts/5365.cs2 b/dumps/scripts/5365.cs2 new file mode 100644 index 0000000..ef0a669 --- /dev/null +++ b/dumps/scripts/5365.cs2 @@ -0,0 +1,4 @@ +void script_5365(int arg0,int arg1) { + setScriptCallOnGameloop(4214, new WidgetPointer(arg0), arg1, 0, "Iii", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/5366.cs2 b/dumps/scripts/5366.cs2 new file mode 100644 index 0000000..eb68cee --- /dev/null +++ b/dumps/scripts/5366.cs2 @@ -0,0 +1,32 @@ +void script_5366() { + int ivar0; + int ivar1; + int ivar2; + ivar0 = divide(100, 8); + ivar1 = divide(globalint_1655, ivar0); + if (((boolean)mod(globalint_1655, ivar0))) { + ivar1 = subtract(ivar1, 1); + } + ivar2 = 0; + while (ivar2 < 8) { + if (ivar2 > ivar1) { + script_5367(add(multiply(ivar2, 6), 3), 0); + script_5367(add(multiply(ivar2, 6), 4), 0); + script_5367(add(multiply(ivar2, 6), 5), 0); + } else if (ivar2 < ivar1) { + script_5367(add(multiply(ivar2, 6), 3), 2); + script_5367(add(multiply(ivar2, 6), 4), 2); + script_5367(add(multiply(ivar2, 6), 5), 2); + } else { + if ((ivar2 == ivar1) && (ivar2 != globalint_1657)) { + globalint_1658 = 0; + globalint_1657 = ivar2; + script_5367(add(multiply(ivar2, 6), 3), 1); + script_5367(add(multiply(ivar2, 6), 4), 1); + script_5367(add(multiply(ivar2, 6), 5), 1); + } + } + ivar2 = add(ivar2, 1); + } + return; +} diff --git a/dumps/scripts/5367.cs2 b/dumps/scripts/5367.cs2 new file mode 100644 index 0000000..6eb8265 --- /dev/null +++ b/dumps/scripts/5367.cs2 @@ -0,0 +1,19 @@ +void script_5367(int arg0,int arg1) { + if (setWidgetRegister(new WidgetPointer(951,24), arg0)) { + switch (arg1) { + case 0: + setWidgetHidden(1); + setScriptCallOnGameloop(-1, ""); + break; + case 1: + setWidgetHidden(0); + setScriptCallOnGameloop(5368, -2147483643, "i"); + break; + case 2: + setWidgetHidden(0); + setScriptCallOnGameloop(-1, ""); + cs2method2103(0); + } + } + return; +} diff --git a/dumps/scripts/5368.cs2 b/dumps/scripts/5368.cs2 new file mode 100644 index 0000000..5a16e18 --- /dev/null +++ b/dumps/scripts/5368.cs2 @@ -0,0 +1,10 @@ +void script_5368(int arg0) { + int ivar1; + globalint_1658 = add(globalint_1658, 1); + ivar1 = divide(multiply(globalint_1658, 255), globalint_1656); + ivar1 = min(255, max(0, ivar1)); + if (setWidgetRegister(new WidgetPointer(951,24), arg0)) { + cs2method2103(ivar1); + } + return; +} diff --git a/dumps/scripts/5369.cs2 b/dumps/scripts/5369.cs2 new file mode 100644 index 0000000..5d030f3 --- /dev/null +++ b/dumps/scripts/5369.cs2 @@ -0,0 +1,4 @@ +void script_5369(int arg0) { + setWidgetText(new WidgetPointer(arg0), intToStr(add(rndExcl(9), 1))); + return; +} diff --git a/dumps/scripts/537.cs2 b/dumps/scripts/537.cs2 new file mode 100644 index 0000000..b262890 --- /dev/null +++ b/dumps/scripts/537.cs2 @@ -0,0 +1,29 @@ +void script_537(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + ivar2 = 0; + ivar3 = add(arg1, 25); + ivar4 = subtract(getClientCycle(), arg0); + if (getClientCycle() >= arg1) { + if (getClientCycle() < ivar3) { + ivar2 = divide(255, subtract(ivar3, arg1)); + ivar2 = subtract(255, multiply(ivar2, subtract(getClientCycle(), arg1))); + cs2method2103(ivar2, new WidgetPointer(745,2)); + return; + } + setScriptCallOnGameloop(-1, "", new WidgetPointer(745,2)); + cs2method2103(0, new WidgetPointer(745,2)); + return; + } + if (ivar4 <= 5) { + cs2method2103(0, new WidgetPointer(745,2)); + } else if (ivar4 <= 10) { + cs2method2103(85, new WidgetPointer(745,2)); + } else if (ivar4 <= 15) { + cs2method2103(200, new WidgetPointer(745,2)); + } else { + cs2method2103(85, new WidgetPointer(745,2)); + } + return; +} diff --git a/dumps/scripts/5370.cs2 b/dumps/scripts/5370.cs2 new file mode 100644 index 0000000..fc1897e --- /dev/null +++ b/dumps/scripts/5370.cs2 @@ -0,0 +1,37 @@ +void script_5370(int arg0,int arg1,string arg2,string arg3) { + int ivar2; + int ivar3; + if (((boolean)arg0)) { + setWidgetIsHidden(true, new WidgetPointer(951,14)); + } else { + setWidgetIsHidden(false, new WidgetPointer(951,14)); + } + if (((boolean)arg1)) { + setWidgetIsHidden(true, new WidgetPointer(951,2)); + } else { + setWidgetIsHidden(false, new WidgetPointer(951,2)); + } + setWidgetText(new WidgetPointer(951,48), arg2); + setWidgetText(new WidgetPointer(951,51), arg3); + ivar2 = getTextWidth(4040, arg3); + setWidgetSize(add(ivar2, 16), getWidgetActualHeight(new WidgetPointer(951,1)), 0, 0, new WidgetPointer(951,1)); + ivar2 = getTextWidth(4040, arg2); + setWidgetSize(add(ivar2, 16), getWidgetActualHeight(new WidgetPointer(951,3)), 0, 0, new WidgetPointer(951,3)); + ivar2 = max(getWidgetActualWidth(new WidgetPointer(951,1)), getWidgetActualWidth(new WidgetPointer(951,3))); + if (((boolean)arg1)) { + ivar2 = max(ivar2, getWidgetActualWidth(new WidgetPointer(951,2))); + } + if (((boolean)arg0)) { + ivar2 = max(ivar2, getWidgetActualWidth(new WidgetPointer(951,14))); + } + setWidgetSize(add(ivar2, 48), getWidgetActualHeight(new WidgetPointer(951,49)), 0, 0, new WidgetPointer(951,49)); + ivar3 = add(getWidgetActualHeight(new WidgetPointer(951,1)), getWidgetActualHeight(new WidgetPointer(951,3))); + if (((boolean)arg1)) { + ivar3 = add(ivar3, getWidgetActualHeight(new WidgetPointer(951,2))); + } + setWidgetSize(getWidgetActualWidth(new WidgetPointer(951,49)), ivar3, 0, 0, new WidgetPointer(951,49)); + if (((boolean)arg0)) { + setWidgetPosition(0, add(7, getWidgetActualHeight(new WidgetPointer(951,49))), 1, 0, new WidgetPointer(951,14)); + } + return; +} diff --git a/dumps/scripts/5371.cs2 b/dumps/scripts/5371.cs2 new file mode 100644 index 0000000..d9d69e4 --- /dev/null +++ b/dumps/scripts/5371.cs2 @@ -0,0 +1,73 @@ +void script_5371(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + if (arg0 < 1) { + setWidgetText(new WidgetPointer(951,53), "-"); + } + if (arg0 < 2) { + setWidgetText(new WidgetPointer(951,55), "-"); + } + if (arg0 < 3) { + setWidgetText(new WidgetPointer(951,57), "-"); + } + if (arg0 < 4) { + setWidgetText(new WidgetPointer(951,59), "-"); + } + if (arg0 < 5) { + setWidgetText(new WidgetPointer(951,61), "-"); + } + if (arg0 < 6) { + setWidgetText(new WidgetPointer(951,63), "-"); + } + switch (arg0) { + case 0: + setWidgetText(new WidgetPointer(951,25), intToStr(arg1)); + break; + case 1: + setWidgetText(new WidgetPointer(951,53), intToStr(arg1)); + break; + case 2: + setWidgetText(new WidgetPointer(951,55), intToStr(arg1)); + break; + case 3: + setWidgetText(new WidgetPointer(951,57), intToStr(arg1)); + break; + case 4: + setWidgetText(new WidgetPointer(951,59), intToStr(arg1)); + break; + case 5: + setWidgetText(new WidgetPointer(951,61), intToStr(arg1)); + break; + case 6: + setWidgetText(new WidgetPointer(951,63), intToStr(arg1)); + } + switch (arg0) { + case 0: + script_5373(62324789, arg2); + break; + case 1: + script_5373(62324791, arg2); + break; + case 2: + script_5373(62324793, arg2); + break; + case 3: + script_5373(62324795, arg2); + break; + case 4: + script_5373(62324797, arg2); + break; + case 5: + script_5373(62324799, arg2); + } + ivar3 = subtract(multiply(63, arg0), 189); + ivar4 = add(ivar3, 63); + setScriptCallOnGameloop(5372, new WidgetPointer(951,36), ivar3, "Ii", new WidgetPointer(951,36)); + setScriptCallOnGameloop(5372, new WidgetPointer(951,34), ivar4, "Ii", new WidgetPointer(951,34)); + ivar5 = subtract(add(getWidgetActualX(new WidgetPointer(951,36)), divide(getWidgetActualWidth(new WidgetPointer(951,36)), 2)), divide(getWidgetActualWidth(new WidgetPointer(951,14)), 2)); + if (ivar5 < ivar3) { + playSoundEffect2False(7717, 1, 0, 180); + } + return; +} diff --git a/dumps/scripts/5372.cs2 b/dumps/scripts/5372.cs2 new file mode 100644 index 0000000..d682340 --- /dev/null +++ b/dumps/scripts/5372.cs2 @@ -0,0 +1,13 @@ +void script_5372(int arg0,int arg1) { + int ivar2; + int ivar3; + ivar2 = 3; + ivar3 = subtract(add(getWidgetActualX(new WidgetPointer(arg0)), divide(getWidgetActualWidth(new WidgetPointer(arg0)), 2)), divide(getWidgetActualWidth(new WidgetPointer(951,14)), 2)); + if (ivar3 >= arg1) { + setWidgetPosition(arg1, getWidgetActualY(new WidgetPointer(arg0)), 1, 0, new WidgetPointer(arg0)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + } else { + setWidgetPosition(add(ivar3, ivar2), getWidgetActualY(new WidgetPointer(arg0)), 1, 0, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/5373.cs2 b/dumps/scripts/5373.cs2 new file mode 100644 index 0000000..c65c07c --- /dev/null +++ b/dumps/scripts/5373.cs2 @@ -0,0 +1,12 @@ +void script_5373(int arg0,int arg1) { + if (arg1 == -1) { + playSoundEffect2False(7715, 45, 0, 100); + setScriptCallOnGameloop(5369, new WidgetPointer(arg0), "I", new WidgetPointer(arg0)); + } else if (arg1 == -2) { + setWidgetText(new WidgetPointer(arg0), "-"); + } else { + setWidgetText(new WidgetPointer(arg0), intToStr(arg1)); + } + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/5374.cs2 b/dumps/scripts/5374.cs2 new file mode 100644 index 0000000..0f2946a --- /dev/null +++ b/dumps/scripts/5374.cs2 @@ -0,0 +1,4 @@ +void script_5374(int arg0) { + globalint_1656 = divide(multiply(multiply(arg0, 10), 50), multiply(6, 8)); + return; +} diff --git a/dumps/scripts/5375.cs2 b/dumps/scripts/5375.cs2 new file mode 100644 index 0000000..7434cae --- /dev/null +++ b/dumps/scripts/5375.cs2 @@ -0,0 +1,4 @@ +void script_5375() { + cs2method2005(0, new WidgetPointer(969,0)); + return; +} diff --git a/dumps/scripts/5376.cs2 b/dumps/scripts/5376.cs2 new file mode 100644 index 0000000..78dc206 --- /dev/null +++ b/dumps/scripts/5376.cs2 @@ -0,0 +1,17 @@ +void script_5376() { + int ivar0; + ivar0 = 0; + while (ivar0 < 8) { + if (setWidgetRegister(new WidgetPointer(951,24), add(multiply(ivar0, 6), 3))) { + setScriptCallOnGameloop(-1, ""); + } + if (setWidgetRegister(new WidgetPointer(951,24), add(multiply(ivar0, 6), 4))) { + setScriptCallOnGameloop(-1, ""); + } + if (setWidgetRegister(new WidgetPointer(951,24), add(multiply(ivar0, 6), 5))) { + setScriptCallOnGameloop(-1, ""); + } + ivar0 = add(ivar0, 1); + } + return; +} diff --git a/dumps/scripts/538.cs2 b/dumps/scripts/538.cs2 new file mode 100644 index 0000000..b2f1983 --- /dev/null +++ b/dumps/scripts/538.cs2 @@ -0,0 +1,5 @@ +void script_538(int arg0,int arg1,int arg2) { + setScriptCallOnItemContainerUpdate(2348, new WidgetPointer(arg0), arg1, arg2, 93, 1, "IoiY", new WidgetPointer(arg0)); + script_2349(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/539.cs2 b/dumps/scripts/539.cs2 new file mode 100644 index 0000000..3ee4609 --- /dev/null +++ b/dumps/scripts/539.cs2 @@ -0,0 +1,5 @@ +void script_539(int arg0,int arg1) { + setScriptCallOnItemContainerUpdate(2350, new WidgetPointer(arg0), arg1, 93, 1, "IoY", new WidgetPointer(arg0)); + script_2351(arg0, arg1); + return; +} diff --git a/dumps/scripts/54.cs2 b/dumps/scripts/54.cs2 new file mode 100644 index 0000000..62b8c6a --- /dev/null +++ b/dumps/scripts/54.cs2 @@ -0,0 +1,14 @@ +void script_54(int arg0) { + int ivar1; + int ivar2; + int ivar3; + ivar1 = extractY(getMyPositionHash()); + ivar2 = add(divide(subtract(ivar1, 9920), 8), 1); + ivar3 = add(divide(subtract(ivar1, 3520), 8), 1); + if (ivar1 > 6400) { + setWidgetText(new WidgetPointer(arg0), "Level: " + intToStr(ivar2)); + } else { + setWidgetText(new WidgetPointer(arg0), "Level: " + intToStr(ivar3)); + } + return; +} diff --git a/dumps/scripts/540.cs2 b/dumps/scripts/540.cs2 new file mode 100644 index 0000000..0da53d9 --- /dev/null +++ b/dumps/scripts/540.cs2 @@ -0,0 +1,8 @@ +void script_540(int arg0,int arg1) { + if ((getSkillCurrentLvl(6) >= arg1) || (((boolean)bitconfig_4089) && (standart_config_1092 >= arg1))) { + setWidgetRGB(new Color(0, 204, 0), new WidgetPointer(arg0)); + } else { + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/541.cs2 b/dumps/scripts/541.cs2 new file mode 100644 index 0000000..fc9a3c2 --- /dev/null +++ b/dumps/scripts/541.cs2 @@ -0,0 +1,8 @@ +void script_541(int arg0,int arg1) { + if ((getSkillCurrentLvl(12) >= arg1) || (((boolean)bitconfig_4089) && (standart_config_1093 >= arg1))) { + setWidgetRGB(new Color(0, 204, 0), new WidgetPointer(arg0)); + } else { + setWidgetRGB(new Color(255, 152, 31), new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/542.cs2 b/dumps/scripts/542.cs2 new file mode 100644 index 0000000..05792af --- /dev/null +++ b/dumps/scripts/542.cs2 @@ -0,0 +1,8 @@ +void script_542(int arg0,int arg1) { + if ((getSkillCurrentLvl(12) >= arg1) || (((boolean)bitconfig_4089) && (standart_config_1093 >= arg1))) { + setWidgetIsHidden(false, new WidgetPointer(arg0)); + } else { + setWidgetIsHidden(true, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/543.cs2 b/dumps/scripts/543.cs2 new file mode 100644 index 0000000..8263938 --- /dev/null +++ b/dumps/scripts/543.cs2 @@ -0,0 +1,6 @@ +int script_543(int arg0) { + if (((boolean)arg0)) { + return 1; + } + return 0; +} diff --git a/dumps/scripts/544.cs2 b/dumps/scripts/544.cs2 new file mode 100644 index 0000000..8aa8b2c --- /dev/null +++ b/dumps/scripts/544.cs2 @@ -0,0 +1,6 @@ +void script_544(int arg0) { + int ivar1; + ivar1 = script_2761(); + setWidgetText(new WidgetPointer(arg0), "Total level: " + intToStr(ivar1)); + return; +} diff --git a/dumps/scripts/545.cs2 b/dumps/scripts/545.cs2 new file mode 100644 index 0000000..930e38f --- /dev/null +++ b/dumps/scripts/545.cs2 @@ -0,0 +1,5 @@ +void script_545(int arg0,int arg1,int arg2) { + globalint_80 = getSkillActualLvl(arg1); + script_547(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/546.cs2 b/dumps/scripts/546.cs2 new file mode 100644 index 0000000..f058aef --- /dev/null +++ b/dumps/scripts/546.cs2 @@ -0,0 +1,5 @@ +void script_546(int arg0) { + globalint_80 = 0; + deleteAllExtraChilds(new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/547.cs2 b/dumps/scripts/547.cs2 new file mode 100644 index 0000000..2f8a917 --- /dev/null +++ b/dumps/scripts/547.cs2 @@ -0,0 +1,328 @@ +void script_547(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + int ivar22; + int ivar23; + int ivar24; + int ivar25; + int ivar26; + string svar0; + string svar1; + string svar2; + string svar3; + string svar4; + string svar5; + int stack_dump0; + cs2func_script_4037_struct(3,0,0) structdump_1; + svar0 = ""; + svar1 = ""; + ivar3 = 2; + if ((getSkillActualLvl(arg1) < 99) || ((arg1 == 24) && (getSkillActualLvl(arg1) < 120))) { + svar0 = script_46(cs2method_3408(105, 105, 716, add(getSkillActualLvl(arg1), 1)), ","); + svar1 = script_46(subtract(cs2method_3408(105, 105, 716, add(getSkillActualLvl(arg1), 1)), getSkillXp(arg1)), ","); + ivar3 = 4; + } + ivar4 = script_4036(cs2method_3408(83, 105, 1482, arg1)); + if (((boolean)ivar4)) { + ivar3 = add(ivar3, 3); + } + ivar5 = 0; + ivar6 = 0; + ivar7 = 0; + stack_dump0 = cs2method_3408(83, 105, 1482, arg1); + structdump_1 = script_4037(stack_dump0); + ivar6 = structdump_1.intpart_2; + ivar5 = structdump_1.intpart_1; + ivar7 = structdump_1.intpart_0; + svar2 = script_46(ivar5, ","); + svar3 = cs2method_3408(83, 115, 680, arg1) + ": " + intToStr(getSkillCurrentLvl(arg1)) + "/" + intToStr(getSkillActualLvl(arg1)); + svar4 = script_46(getSkillXp(arg1), ","); + ivar8 = ivar5; + if (((boolean)ivar7)) { + ivar8 = cs2method_3408(105, 105, 716, ivar5); + } + ivar9 = max(0, subtract(ivar8, getSkillXp(arg1))); + svar5 = script_46(ivar9, ","); + if ((((boolean)getSkillActualLvl(arg1)) && (cs2method_3408(83, 83, 744, arg1) == -1)) && isSiteSettingsMembers()) { + ivar3 = 1; + svar3 = "Members' Skill"; + } + ivar10 = add(getMaxLineWidth(190, 495, svar3), 10); + ivar11 = getMaxLineWidth(190, 495, "Current Xp:"); + ivar12 = getMaxLineWidth(190, 495, svar4); + ivar13 = add(add(ivar11, 10), ivar12); + ivar14 = 0; + ivar15 = 0; + ivar10 = max(ivar10, ivar13); + if ((getSkillActualLvl(arg1) < 99) || ((arg1 == 24) && (getSkillActualLvl(arg1) < 120))) { + ivar11 = getMaxLineWidth(190, 495, "Next level:"); + ivar12 = getMaxLineWidth(190, 495, svar0); + ivar13 = add(add(ivar11, 3), ivar12); + } else { + ivar13 = 0; + } + ivar10 = max(ivar10, ivar13); + if ((getSkillActualLvl(arg1) < 99) || ((arg1 == 24) && (getSkillActualLvl(arg1) < 120))) { + ivar11 = getMaxLineWidth(190, 495, "Remainder:"); + ivar12 = getMaxLineWidth(190, 495, svar1); + ivar13 = add(add(ivar11, 3), ivar12); + } else { + ivar13 = 0; + } + ivar10 = max(ivar10, ivar13); + if (((boolean)ivar4)) { + if (((boolean)ivar7)) { + ivar11 = getMaxLineWidth(190, 495, "Target lvl:"); + ivar12 = getMaxLineWidth(190, 495, svar2); + } else { + ivar11 = getMaxLineWidth(190, 495, "Target xp:"); + ivar12 = getMaxLineWidth(190, 495, svar2); + } + ivar13 = add(add(ivar11, 3), ivar12); + } else { + ivar13 = 0; + } + ivar10 = max(ivar10, ivar13); + if (((boolean)ivar4)) { + ivar11 = getMaxLineWidth(190, 495, "Remainder:"); + ivar12 = getMaxLineWidth(190, 495, svar5); + ivar13 = add(add(ivar11, 3), ivar12); + } else { + ivar13 = 0; + } + ivar10 = max(ivar10, ivar13); + ivar11 = add(script_3365(arg0), 40); + ivar12 = add(script_3366(arg0), 50); + if (add(add(ivar11, ivar10), 4) > 190) { + ivar11 = subtract(190, add(ivar10, 4)); + } + if (add(add(ivar12, multiply(ivar3, 14)), 4) > getWidgetActualHeight(new WidgetPointer(arg2))) { + ivar12 = subtract(script_3366(arg0), add(multiply(ivar3, 14), 4)); + } + if ((((boolean)getSkillActualLvl(arg1)) && (cs2method_3408(83, 83, 744, arg1) == -1)) && isSiteSettingsMembers()) { + createExtraChild(new WidgetPointer(arg2), 3, 0); + setWidgetSize(add(ivar10, 4), add(4, multiply(ivar3, 14)), 0, 0); + setWidgetPosition(ivar11, ivar12, 0, 0); + setWidgetFilled(1); + setWidgetRGB(new Color(255, 255, 160)); + createExtraChild(new WidgetPointer(arg2), 3, 1); + setWidgetSize(add(ivar10, 4), add(4, multiply(ivar3, 14)), 0, 0); + setWidgetPosition(ivar11, ivar12, 0, 0); + setWidgetFilled(0); + setWidgetRGB(new Color(0, 0, 0)); + createExtraChild(new WidgetPointer(arg2), 4, 2); + setWidgetPosition(add(ivar11, 2), add(ivar12, 2), 0, 0); + setWidgetSize(ivar10, 16, 0, 0); + setWidgetFont(495); + setWidgetTextAlignment(0, 0, 0); + setWidgetUnknownBoolean(false); + setWidgetText(svar3); + return; + } + ivar16 = 0; + ivar17 = 2; + ivar18 = 0; + ivar19 = 0; + ivar20 = 0; + ivar21 = 0; + ivar22 = 0; + createExtraChild(new WidgetPointer(arg2), 3, ivar16); + ivar23 = add(4, multiply(ivar3, 14)); + if (((boolean)ivar4)) { + ivar23 = add(ivar23, 6); + } + setWidgetSize(add(ivar10, 4), ivar23, 0, 0); + setWidgetPosition(ivar11, ivar12, 0, 0); + setWidgetFilled(1); + setWidgetRGB(new Color(255, 255, 160)); + ivar16 = add(ivar16, 1); + createExtraChild(new WidgetPointer(arg2), 3, ivar16); + setWidgetSize(add(ivar10, 4), ivar23, 0, 0); + setWidgetPosition(ivar11, ivar12, 0, 0); + setWidgetFilled(0); + setWidgetRGB(new Color(0, 0, 0)); + ivar16 = add(ivar16, 1); + createExtraChild(new WidgetPointer(arg2), 4, ivar16); + ivar18 = ivar16; + setWidgetPosition(add(ivar11, 2), add(ivar12, ivar17), 0, 0); + setWidgetSize(ivar10, 16, 0, 0); + setWidgetFont(495); + setWidgetTextAlignment(0, 0, 0); + setWidgetUnknownBoolean(false); + setWidgetText(svar3); + ivar16 = add(ivar16, 1); + ivar17 = add(ivar17, 14); + createExtraChild(new WidgetPointer(arg2), 4, ivar16); + setWidgetPosition(add(ivar11, 2), add(ivar12, ivar17), 0, 0); + setWidgetSize(ivar10, 16, 0, 0); + setWidgetFont(495); + setWidgetTextAlignment(0, 0, 0); + setWidgetUnknownBoolean(false); + setWidgetText("Current Xp:"); + ivar16 = add(ivar16, 1); + createExtraChild(new WidgetPointer(arg2), 4, ivar16); + ivar19 = ivar16; + setWidgetPosition(add(ivar11, 2), add(ivar12, ivar17), 0, 0); + setWidgetSize(ivar10, 16, 0, 0); + setWidgetFont(495); + setWidgetTextAlignment(2, 0, 0); + setWidgetUnknownBoolean(false); + setWidgetText(svar4); + ivar16 = add(ivar16, 1); + ivar17 = add(ivar17, 14); + ivar24 = 0; + ivar25 = 0; + if ((getSkillActualLvl(arg1) < 99) || ((arg1 == 24) && (getSkillActualLvl(arg1) < 120))) { + createExtraChild(new WidgetPointer(arg2), 4, ivar16); + setWidgetPosition(add(ivar11, 2), add(ivar12, ivar17), 0, 0); + setWidgetSize(ivar10, 16, 0, 0); + setWidgetFont(495); + setWidgetTextAlignment(0, 0, 0); + setWidgetUnknownBoolean(false); + setWidgetText("Next level:"); + ivar16 = add(ivar16, 1); + createExtraChild(new WidgetPointer(arg2), 4, ivar16); + setWidgetPosition(add(ivar11, 2), add(ivar12, ivar17), 0, 0); + setWidgetSize(ivar10, 16, 0, 0); + setWidgetFont(495); + setWidgetTextAlignment(2, 0, 0); + setWidgetUnknownBoolean(false); + setWidgetText(svar0); + ivar16 = add(ivar16, 1); + ivar17 = add(ivar17, 14); + createExtraChild(new WidgetPointer(arg2), 4, ivar16); + setWidgetPosition(add(ivar11, 2), add(ivar12, ivar17), 0, 0); + setWidgetSize(ivar10, 16, 0, 0); + setWidgetFont(495); + setWidgetTextAlignment(0, 0, 0); + setWidgetUnknownBoolean(false); + setWidgetText("Remainder:"); + ivar16 = add(ivar16, 1); + createExtraChild(new WidgetPointer(arg2), 4, ivar16); + ivar20 = ivar16; + setWidgetPosition(add(ivar11, 2), add(ivar12, ivar17), 0, 0); + setWidgetSize(ivar10, 16, 0, 0); + setWidgetFont(495); + setWidgetTextAlignment(2, 0, 0); + setWidgetUnknownBoolean(false); + setWidgetText(svar1); + ivar16 = add(ivar16, 1); + ivar17 = add(ivar17, 14); + } + ivar26 = 0; + if (((boolean)ivar4)) { + createExtraChild(new WidgetPointer(arg2), 4, ivar16); + setWidgetPosition(add(ivar11, 2), add(ivar12, ivar17), 0, 0); + setWidgetSize(ivar10, 16, 0, 0); + setWidgetFont(495); + setWidgetTextAlignment(0, 0, 0); + setWidgetUnknownBoolean(false); + if (((boolean)ivar7)) { + setWidgetText("Target lvl:"); + } else { + setWidgetText("Target XP:"); + } + ivar16 = add(ivar16, 1); + createExtraChild(new WidgetPointer(arg2), 4, ivar16); + setWidgetPosition(add(ivar11, 2), add(ivar12, ivar17), 0, 0); + setWidgetSize(ivar10, 16, 0, 0); + setWidgetFont(495); + setWidgetTextAlignment(2, 0, 0); + setWidgetUnknownBoolean(false); + if (((boolean)ivar7)) { + setWidgetText(svar2); + } else { + setWidgetText(svar2); + } + ivar16 = add(ivar16, 1); + ivar17 = add(ivar17, 14); + createExtraChild(new WidgetPointer(arg2), 4, ivar16); + setWidgetPosition(add(ivar11, 2), add(ivar12, ivar17), 0, 0); + setWidgetSize(ivar10, 16, 0, 0); + setWidgetFont(495); + setWidgetTextAlignment(0, 0, 0); + setWidgetUnknownBoolean(false); + setWidgetText("Remainder:"); + ivar16 = add(ivar16, 1); + createExtraChild(new WidgetPointer(arg2), 4, ivar16); + setWidgetPosition(add(ivar11, 2), add(ivar12, ivar17), 0, 0); + setWidgetSize(ivar10, 16, 0, 0); + setWidgetFont(495); + setWidgetTextAlignment(2, 0, 0); + setWidgetUnknownBoolean(false); + setWidgetText(svar5); + ivar21 = ivar16; + ivar16 = add(ivar16, 1); + ivar17 = add(ivar17, 17); + createExtraChild(new WidgetPointer(arg2), 3, ivar16); + setWidgetPosition(add(ivar11, 4), add(ivar12, ivar17), 0, 0); + setWidgetSize(subtract(ivar10, 4), 16, 0, 0); + setWidgetFilled(1); + setWidgetRGB(new Color(255, 0, 0)); + ivar16 = add(ivar16, 1); + createExtraChild(new WidgetPointer(arg2), 3, ivar16); + ivar26 = ivar16; + setWidgetPosition(add(ivar11, 4), add(ivar12, ivar17), 0, 0); + setWidgetFilled(1); + setWidgetRGB(new Color(0, 255, 0)); + ivar16 = add(ivar16, 1); + if (((boolean)ivar7)) { + ivar24 = cs2method_3408(105, 105, 716, ivar6); + ivar25 = cs2method_3408(105, 105, 716, ivar5); + if (subtract(ivar25, ivar24) != 0) { + ivar14 = multiplyDivide(subtract(getSkillXp(arg1), ivar24), subtract(ivar25, ivar24), 100); + } else { + ivar14 = -1; + } + } else if (subtract(ivar5, ivar6) != 0) { + ivar14 = multiplyDivide(subtract(getSkillXp(arg1), ivar6), subtract(ivar5, ivar6), 100); + } else { + ivar14 = -1; + } + if (ivar14 > 100) { + ivar14 = 100; + } + ivar14 = max(ivar14, 0); + ivar15 = multiply(ivar14, add(4, ivar10)); + ivar15 = divide(ivar15, 100); + setWidgetSize(ivar15, 16, 0, 0); + createExtraChild(new WidgetPointer(arg2), 3, ivar16); + setWidgetPosition(add(ivar11, 4), add(ivar12, ivar17), 0, 0); + setWidgetSize(subtract(ivar10, 4), 16, 0, 0); + ivar16 = add(ivar16, 1); + createExtraChild(new WidgetPointer(arg2), 4, ivar16); + setWidgetSize(getTextWidth(495, intToStr(ivar14) + "%"), 16, 0, 0); + setWidgetPosition(add(subtract(add(ivar11, divide(ivar10, 2)), divide(getWidgetActualWidth(), 2)), 2), add(add(ivar12, ivar17), 1), 0, 0); + setWidgetFont(495); + setWidgetTextAlignment(1, 0, 0); + setWidgetUnknownBoolean(false); + setWidgetRGB(new Color(255, 255, 255)); + if (ivar14 > 47) { + setWidgetRGB(new Color(0, 0, 0)); + } + setWidgetText(intToStr(ivar14) + "%"); + ivar22 = ivar16; + ivar16 = add(ivar16, 1); + } + if (setWidgetRegister(new WidgetPointer(arg2), 0)) { + setScriptCallOnSkillChange(548, ivar18, ivar19, ivar20, ivar21, ivar22, ivar26, ivar10, arg1, new WidgetPointer(arg0), new WidgetPointer(arg2), arg1, 1, "iiiiiiiSIIY"); + } + return; +} diff --git a/dumps/scripts/548.cs2 b/dumps/scripts/548.cs2 new file mode 100644 index 0000000..4adee97 --- /dev/null +++ b/dumps/scripts/548.cs2 @@ -0,0 +1,87 @@ +void script_548(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9) { + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + string svar0; + string svar1; + int stack_dump0; + cs2func_script_4037_struct(3,0,0) structdump_1; + if (((boolean)globalint_80)) { + return; + } + ivar10 = 0; + ivar11 = 0; + ivar12 = 0; + ivar13 = 0; + ivar14 = 0; + ivar15 = 0; + ivar16 = 0; + ivar17 = 0; + ivar18 = 0; + svar0 = ""; + svar1 = cs2method_3408(83, 115, 680, arg7) + ": " + intToStr(getSkillCurrentLvl(arg7)) + "/" + intToStr(getSkillActualLvl(arg7)); + if ((setWidgetRegister(new WidgetPointer(arg9), arg0) && (getMaxLineWidth(190, 495, svar1) < getWidgetActualWidth())) && (globalint_80 == getSkillActualLvl(arg7))) { + setWidgetText(svar1); + if (setWidgetRegister(new WidgetPointer(arg9), arg1)) { + setWidgetText(script_46(getSkillXp(arg7), ",")); + } + if ((getSkillActualLvl(arg7) < 99) && setWidgetRegister(new WidgetPointer(arg9), arg2)) { + setWidgetText(script_46(subtract(cs2method_3408(105, 105, 716, add(getSkillActualLvl(arg7), 1)), getSkillXp(arg7)), ",")); + } + if (((boolean)script_4036(cs2method_3408(83, 105, 1482, arg7)))) { + stack_dump0 = cs2method_3408(83, 105, 1482, arg7); + structdump_1 = script_4037(stack_dump0); + ivar11 = structdump_1.intpart_2; + ivar10 = structdump_1.intpart_1; + ivar12 = structdump_1.intpart_0; + ivar17 = ivar10; + if (((boolean)ivar12)) { + ivar17 = cs2method_3408(105, 105, 716, ivar10); + } + ivar18 = max(0, subtract(ivar17, getSkillXp(arg7))); + svar0 = script_46(ivar18, ","); + if (setWidgetRegister(new WidgetPointer(arg9), arg5)) { + if (((boolean)ivar12)) { + ivar15 = cs2method_3408(105, 105, 716, ivar11); + ivar16 = cs2method_3408(105, 105, 716, ivar10); + if (subtract(ivar16, ivar15) != 0) { + ivar13 = multiplyDivide(subtract(getSkillXp(arg7), ivar15), subtract(ivar16, ivar15), 100); + } else { + ivar13 = -1; + } + } else if (subtract(ivar10, ivar11) != 0) { + ivar13 = multiplyDivide(subtract(getSkillXp(arg7), ivar11), subtract(ivar10, ivar11), 100); + } else { + ivar13 = -1; + } + if (ivar13 > 100) { + ivar13 = 100; + } + ivar13 = max(ivar13, 0); + ivar14 = multiply(ivar13, subtract(arg6, 4)); + ivar14 = divide(ivar14, 100); + setWidgetSize(ivar14, 16, 0, 0); + if (setWidgetRegister(new WidgetPointer(arg9), arg4)) { + if (ivar13 > 47) { + setWidgetRGB(new Color(0, 0, 0)); + } + setWidgetText(intToStr(ivar13) + "%"); + } + if (setWidgetRegister(new WidgetPointer(arg9), arg3)) { + setWidgetText(svar0); + } + } + } + return; + } + deleteAllExtraChilds(new WidgetPointer(arg9)); + globalint_80 = getSkillActualLvl(arg7); + script_547(arg8, arg7, arg9); + return; +} diff --git a/dumps/scripts/549.cs2 b/dumps/scripts/549.cs2 new file mode 100644 index 0000000..9bd9b17 --- /dev/null +++ b/dumps/scripts/549.cs2 @@ -0,0 +1,13 @@ +void script_549() { + int ivar0; + if (bitconfig_4109 == 15) { + playSoundEffect(4020, 1, 0); + return; + } + bitconfig_4109 = add(bitconfig_4109, 1); + ivar0 = multiply(subtract(15, bitconfig_4109), 6); + setWidgetPosition(0, ivar0, 0, 0, new WidgetPointer(624,15)); + setWidgetText(new WidgetPointer(624,70), intToStr(bitconfig_4109)); + playSoundEffect(4026, 1, 0); + return; +} diff --git a/dumps/scripts/55.cs2 b/dumps/scripts/55.cs2 new file mode 100644 index 0000000..2e241bc --- /dev/null +++ b/dumps/scripts/55.cs2 @@ -0,0 +1,15 @@ +int script_55() { + int ivar0; + ivar0 = 0; + ivar0 = add(ivar0, bitconfig_3566); + ivar0 = add(ivar0, bitconfig_3567); + ivar0 = add(ivar0, bitconfig_3568); + ivar0 = add(ivar0, bitconfig_3569); + ivar0 = add(ivar0, bitconfig_3570); + ivar0 = add(ivar0, bitconfig_3571); + ivar0 = add(ivar0, bitconfig_3572); + ivar0 = add(ivar0, bitconfig_3573); + ivar0 = add(ivar0, bitconfig_3574); + ivar0 = add(ivar0, bitconfig_3575); + return ivar0; +} diff --git a/dumps/scripts/550.cs2 b/dumps/scripts/550.cs2 new file mode 100644 index 0000000..194f1d4 --- /dev/null +++ b/dumps/scripts/550.cs2 @@ -0,0 +1,13 @@ +void script_550() { + int ivar0; + if (((boolean)bitconfig_4109)) { + playSoundEffect(4020, 1, 0); + return; + } + bitconfig_4109 = subtract(bitconfig_4109, 1); + ivar0 = multiply(subtract(15, bitconfig_4109), 6); + setWidgetPosition(0, ivar0, 0, 0, new WidgetPointer(624,15)); + setWidgetText(new WidgetPointer(624,70), intToStr(bitconfig_4109)); + playSoundEffect(4026, 1, 0); + return; +} diff --git a/dumps/scripts/551.cs2 b/dumps/scripts/551.cs2 new file mode 100644 index 0000000..c1aaffa --- /dev/null +++ b/dumps/scripts/551.cs2 @@ -0,0 +1,13 @@ +void script_551() { + int ivar0; + if (bitconfig_4110 == 15) { + playSoundEffect(4020, 1, 0); + return; + } + bitconfig_4110 = add(bitconfig_4110, 1); + ivar0 = multiply(subtract(15, bitconfig_4110), 6); + setWidgetPosition(0, ivar0, 0, 0, new WidgetPointer(624,17)); + setWidgetText(new WidgetPointer(624,71), intToStr(bitconfig_4110)); + playSoundEffect(4026, 1, 0); + return; +} diff --git a/dumps/scripts/552.cs2 b/dumps/scripts/552.cs2 new file mode 100644 index 0000000..328bfeb --- /dev/null +++ b/dumps/scripts/552.cs2 @@ -0,0 +1,13 @@ +void script_552() { + int ivar0; + if (((boolean)bitconfig_4110)) { + playSoundEffect(4020, 1, 0); + return; + } + bitconfig_4110 = subtract(bitconfig_4110, 1); + ivar0 = multiply(subtract(15, bitconfig_4110), 6); + setWidgetPosition(0, ivar0, 0, 0, new WidgetPointer(624,17)); + setWidgetText(new WidgetPointer(624,71), intToStr(bitconfig_4110)); + playSoundEffect(4026, 1, 0); + return; +} diff --git a/dumps/scripts/553.cs2 b/dumps/scripts/553.cs2 new file mode 100644 index 0000000..2e98af5 --- /dev/null +++ b/dumps/scripts/553.cs2 @@ -0,0 +1,13 @@ +void script_553() { + int ivar0; + if (bitconfig_4111 == 15) { + playSoundEffect(4020, 1, 0); + return; + } + bitconfig_4111 = add(bitconfig_4111, 1); + ivar0 = multiply(subtract(15, bitconfig_4111), 6); + setWidgetPosition(0, ivar0, 0, 0, new WidgetPointer(624,19)); + setWidgetText(new WidgetPointer(624,72), intToStr(bitconfig_4111)); + playSoundEffect(4026, 1, 0); + return; +} diff --git a/dumps/scripts/554.cs2 b/dumps/scripts/554.cs2 new file mode 100644 index 0000000..5e8934b --- /dev/null +++ b/dumps/scripts/554.cs2 @@ -0,0 +1,13 @@ +void script_554() { + int ivar0; + if (((boolean)bitconfig_4111)) { + playSoundEffect(4020, 1, 0); + return; + } + bitconfig_4111 = subtract(bitconfig_4111, 1); + ivar0 = multiply(subtract(15, bitconfig_4111), 6); + setWidgetPosition(0, ivar0, 0, 0, new WidgetPointer(624,19)); + setWidgetText(new WidgetPointer(624,72), intToStr(bitconfig_4111)); + playSoundEffect(4026, 1, 0); + return; +} diff --git a/dumps/scripts/555.cs2 b/dumps/scripts/555.cs2 new file mode 100644 index 0000000..7f73992 --- /dev/null +++ b/dumps/scripts/555.cs2 @@ -0,0 +1,13 @@ +void script_555() { + int ivar0; + ivar0 = multiply(subtract(15, bitconfig_4109), 6); + setWidgetPosition(0, ivar0, 0, 0, new WidgetPointer(624,15)); + setWidgetText(new WidgetPointer(624,70), intToStr(bitconfig_4109)); + ivar0 = multiply(subtract(15, bitconfig_4110), 6); + setWidgetPosition(0, ivar0, 0, 0, new WidgetPointer(624,17)); + setWidgetText(new WidgetPointer(624,71), intToStr(bitconfig_4110)); + ivar0 = multiply(subtract(15, bitconfig_4111), 6); + setWidgetPosition(0, ivar0, 0, 0, new WidgetPointer(624,19)); + setWidgetText(new WidgetPointer(624,72), intToStr(bitconfig_4111)); + return; +} diff --git a/dumps/scripts/556.cs2 b/dumps/scripts/556.cs2 new file mode 100644 index 0000000..760ba06 --- /dev/null +++ b/dumps/scripts/556.cs2 @@ -0,0 +1,4 @@ +void script_556(int arg0) { + script_558(arg0); + return; +} diff --git a/dumps/scripts/557.cs2 b/dumps/scripts/557.cs2 new file mode 100644 index 0000000..c7efae2 --- /dev/null +++ b/dumps/scripts/557.cs2 @@ -0,0 +1,4 @@ +void script_557() { + script_558(bitconfig_4122); + return; +} diff --git a/dumps/scripts/558.cs2 b/dumps/scripts/558.cs2 new file mode 100644 index 0000000..034f8b1 --- /dev/null +++ b/dumps/scripts/558.cs2 @@ -0,0 +1,39 @@ +void script_558(int arg0) { + if (((boolean)arg0)) { + setWidgetSprite(181, new WidgetPointer(625,69)); + setWidgetModel(29248, new WidgetPointer(625,39)); + } else { + setWidgetSprite(180, new WidgetPointer(625,69)); + } + if (arg0 == 2) { + setWidgetSprite(181, new WidgetPointer(625,72)); + setWidgetModel(29242, new WidgetPointer(625,39)); + } else { + setWidgetSprite(180, new WidgetPointer(625,72)); + } + if (arg0 == 3) { + setWidgetSprite(181, new WidgetPointer(625,75)); + setWidgetModel(29237, new WidgetPointer(625,39)); + } else { + setWidgetSprite(180, new WidgetPointer(625,75)); + } + if (arg0 == 4) { + setWidgetSprite(181, new WidgetPointer(625,78)); + setWidgetModel(29245, new WidgetPointer(625,39)); + } else { + setWidgetSprite(180, new WidgetPointer(625,78)); + } + if (arg0 == 5) { + setWidgetSprite(181, new WidgetPointer(625,81)); + setWidgetModel(29246, new WidgetPointer(625,39)); + } else { + setWidgetSprite(180, new WidgetPointer(625,81)); + } + if (arg0 == 6) { + setWidgetSprite(181, new WidgetPointer(625,84)); + setWidgetModel(29241, new WidgetPointer(625,39)); + } else { + setWidgetSprite(180, new WidgetPointer(625,84)); + } + return; +} diff --git a/dumps/scripts/559.cs2 b/dumps/scripts/559.cs2 new file mode 100644 index 0000000..48322d0 --- /dev/null +++ b/dumps/scripts/559.cs2 @@ -0,0 +1,17 @@ +void script_559(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + ivar1 = getWidgetActualWidth(new WidgetPointer(arg0)); + ivar2 = getWidgetActualHeight(new WidgetPointer(arg0)); + ivar3 = subtract(ivar1, 2); + ivar4 = subtract(ivar2, 2); + ivar5 = getExtraChildGap(new WidgetPointer(arg0)); + script_98(arg0, ivar5, 1076, 0, 0, ivar1, 2); + script_98(arg0, add(ivar5, 1), 1076, 1, ivar4, subtract(ivar1, 1), 2); + script_98(arg0, add(ivar5, 2), 1077, 0, 1, 2, subtract(ivar2, 3)); + script_98(arg0, add(ivar5, 3), 1077, ivar3, 1, 2, subtract(ivar2, 2)); + return; +} diff --git a/dumps/scripts/56.cs2 b/dumps/scripts/56.cs2 new file mode 100644 index 0000000..3743526 --- /dev/null +++ b/dumps/scripts/56.cs2 @@ -0,0 +1,35 @@ +void script_56(int arg0) { + int ivar1; + deleteAllExtraChilds(new WidgetPointer(18,13)); + script_4534(1179661); + deleteAllExtraChilds(new WidgetPointer(18,21)); + script_4534(1179669); + deleteAllExtraChilds(new WidgetPointer(18,29)); + createExtraChild(new WidgetPointer(18,29), 5, getExtraChildGap(new WidgetPointer(18,29))); + setWidgetSize(40, 0, 1, 1); + setWidgetPosition(0, 0, 1, 0); + cs2method1107(1); + createExtraChild(new WidgetPointer(18,29), 5, getExtraChildGap(new WidgetPointer(18,29))); + setWidgetSize(20, 0, 0, 1); + setWidgetPosition(0, 0, 0, 1); + createExtraChild(new WidgetPointer(18,29), 5, getExtraChildGap(new WidgetPointer(18,29))); + setWidgetSize(20, 0, 0, 1); + setWidgetPosition(0, 0, 2, 1); + createExtraChild(new WidgetPointer(18,29), 4, getExtraChildGap(new WidgetPointer(18,29))); + setWidgetSize(26, 0, 1, 1); + setWidgetPosition(4, 0, 0, 1); + setWidgetFont(494); + setWidgetRGB(new Color(40, 37, 33)); + setWidgetTextAlignment(1, 1, 0); + ivar1 = getWidgetCustomChildArrayIndex(); + setScriptCallOnConfigChange(58, ivar1, 1747, 1737, 105, 496, 1050, 1600, 6, "iY", new WidgetPointer(arg0)); + setScriptCallOnItemContainerUpdate(58, ivar1, 93, 94, 2, "iY", new WidgetPointer(arg0)); + script_59(ivar1); + setWidgetPosition(script_3365(1179675), subtract(add(script_3366(1179675), getWidgetActualHeight(new WidgetPointer(18,27))), 1), 0, 0, new WidgetPointer(18,43)); + deleteAllExtraChilds(new WidgetPointer(18,43)); + script_4535(1179691); + script_746(0); + setScriptCallOnMousePressed(745, 1, "1", new WidgetPointer(18,29)); + setScriptCallOnMousePressed(745, 0, "1", new WidgetPointer(18,42)); + return; +} diff --git a/dumps/scripts/560.cs2 b/dumps/scripts/560.cs2 new file mode 100644 index 0000000..5381934 --- /dev/null +++ b/dumps/scripts/560.cs2 @@ -0,0 +1,5 @@ +void script_560(int arg0) { + setWidgetIsHidden(false, new WidgetPointer(825,68)); + setWidgetModel(arg0, new WidgetPointer(825,68)); + return; +} diff --git a/dumps/scripts/561.cs2 b/dumps/scripts/561.cs2 new file mode 100644 index 0000000..85c0466 --- /dev/null +++ b/dumps/scripts/561.cs2 @@ -0,0 +1,13 @@ +void script_561() { + if (((boolean)bitconfig_4157)) { + setWidgetSprite(1135, new WidgetPointer(640,22)); + } else { + setWidgetSprite(1134, new WidgetPointer(640,22)); + } + if (bitconfig_4157 == 2) { + setWidgetSprite(1135, new WidgetPointer(640,21)); + } else { + setWidgetSprite(1134, new WidgetPointer(640,21)); + } + return; +} diff --git a/dumps/scripts/562.cs2 b/dumps/scripts/562.cs2 new file mode 100644 index 0000000..95af699 --- /dev/null +++ b/dumps/scripts/562.cs2 @@ -0,0 +1,6 @@ +void script_562(int arg0) { + if (getWidgetSpriteId(new WidgetPointer(arg0)) == 5455) { + setWidgetSprite(5456, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/563.cs2 b/dumps/scripts/563.cs2 new file mode 100644 index 0000000..b49fb73 --- /dev/null +++ b/dumps/scripts/563.cs2 @@ -0,0 +1,90 @@ +void script_563() { + int ivar0; + int ivar1; + ivar0 = 50; + ivar1 = 45; + setWidgetText(new WidgetPointer(641,4), intToStr(bitconfig_4143)); + if (((boolean)bitconfig_4144)) { + setWidgetSprite(223, new WidgetPointer(641,27)); + setWidgetPosition(ivar0, ivar1, 0, 0, new WidgetPointer(641,27)); + setWidgetIsHidden(false, new WidgetPointer(641,12)); + ivar1 = add(ivar1, 29); + } else { + setWidgetIsHidden(true, new WidgetPointer(641,12)); + } + if (((boolean)bitconfig_4145)) { + setWidgetSprite(225, new WidgetPointer(641,28)); + setWidgetPosition(ivar0, ivar1, 0, 0, new WidgetPointer(641,28)); + setWidgetIsHidden(false, new WidgetPointer(641,13)); + ivar1 = add(ivar1, 29); + } else { + setWidgetIsHidden(true, new WidgetPointer(641,13)); + } + if (((boolean)bitconfig_4146)) { + setWidgetSprite(201, new WidgetPointer(641,29)); + setWidgetPosition(ivar0, ivar1, 0, 0, new WidgetPointer(641,29)); + setWidgetIsHidden(false, new WidgetPointer(641,14)); + ivar1 = add(ivar1, 29); + } else { + setWidgetIsHidden(true, new WidgetPointer(641,14)); + } + if (((boolean)bitconfig_4147)) { + setWidgetSprite(226, new WidgetPointer(641,30)); + setWidgetPosition(ivar0, ivar1, 0, 0, new WidgetPointer(641,30)); + setWidgetIsHidden(false, new WidgetPointer(641,15)); + ivar1 = add(ivar1, 29); + } else { + setWidgetIsHidden(true, new WidgetPointer(641,15)); + } + if (((boolean)bitconfig_4151)) { + setWidgetSprite(203, new WidgetPointer(641,32)); + setWidgetPosition(ivar0, ivar1, 0, 0, new WidgetPointer(641,32)); + setWidgetIsHidden(false, new WidgetPointer(641,17)); + ivar1 = add(ivar1, 29); + } else { + setWidgetIsHidden(true, new WidgetPointer(641,17)); + } + if (((boolean)bitconfig_4152)) { + setWidgetSprite(227, new WidgetPointer(641,33)); + setWidgetPosition(ivar0, ivar1, 0, 0, new WidgetPointer(641,33)); + setWidgetIsHidden(false, new WidgetPointer(641,18)); + ivar1 = add(ivar1, 29); + } else { + setWidgetIsHidden(true, new WidgetPointer(641,18)); + } + if (((boolean)bitconfig_4276)) { + setWidgetSprite(222, new WidgetPointer(641,31)); + setWidgetPosition(ivar0, ivar1, 0, 0, new WidgetPointer(641,31)); + setWidgetIsHidden(false, new WidgetPointer(641,16)); + ivar1 = add(ivar1, 29); + } else { + setWidgetIsHidden(true, new WidgetPointer(641,16)); + } + ivar0 = 8; + ivar1 = 45; + if (((boolean)bitconfig_4148)) { + setWidgetSprite(200, new WidgetPointer(641,34)); + setWidgetPosition(ivar0, ivar1, 0, 0, new WidgetPointer(641,34)); + setWidgetIsHidden(false, new WidgetPointer(641,19)); + ivar1 = add(ivar1, 29); + } else { + setWidgetIsHidden(true, new WidgetPointer(641,19)); + } + if (((boolean)bitconfig_4149)) { + setWidgetSprite(197, new WidgetPointer(641,35)); + setWidgetPosition(ivar0, ivar1, 0, 0, new WidgetPointer(641,35)); + setWidgetIsHidden(false, new WidgetPointer(641,20)); + ivar1 = add(ivar1, 29); + } else { + setWidgetIsHidden(true, new WidgetPointer(641,20)); + } + if (((boolean)bitconfig_4150)) { + setWidgetSprite(202, new WidgetPointer(641,36)); + setWidgetPosition(ivar0, ivar1, 0, 0, new WidgetPointer(641,36)); + setWidgetIsHidden(false, new WidgetPointer(641,21)); + ivar1 = add(ivar1, 29); + } else { + setWidgetIsHidden(true, new WidgetPointer(641,21)); + } + return; +} diff --git a/dumps/scripts/564.cs2 b/dumps/scripts/564.cs2 new file mode 100644 index 0000000..3335098 --- /dev/null +++ b/dumps/scripts/564.cs2 @@ -0,0 +1,11 @@ +void script_564() { + if (globalint_1037 > subtract(getWidgetActualHeight(new WidgetPointer(746,3)), 117)) { + script_1652(1); + } else { + script_1650(); + } + cs2method2301(48889930, -1, new WidgetPointer(746,75)); + setScriptCallOnMouseDragged(1649, -2147483646, 0, "i1", new WidgetPointer(746,75)); + setScriptCallOnMouseDragReleased(1649, -2147483646, 1, "i1", new WidgetPointer(746,75)); + return; +} diff --git a/dumps/scripts/565.cs2 b/dumps/scripts/565.cs2 new file mode 100644 index 0000000..cb1f7db --- /dev/null +++ b/dumps/scripts/565.cs2 @@ -0,0 +1,112 @@ +void script_565() { + int ivar0; + int ivar1; + string svar0; + ivar0 = 50; + ivar1 = 45; + svar0 = script_20(bitconfig_4138); + if (bitconfig_4140 > 0) { + setWidgetIsHidden(false, new WidgetPointer(635,33)); + setWidgetText(new WidgetPointer(635,35), intToStr(bitconfig_4140)); + setWidgetText(new WidgetPointer(635,32), intToStr(bitconfig_4143)); + setWidgetText(new WidgetPointer(635,30), svar0 + " Coins"); + if (((boolean)bitconfig_4144)) { + setWidgetSprite(223, new WidgetPointer(635,15)); + setWidgetPosition(ivar0, ivar1, 0, 0, new WidgetPointer(635,15)); + setWidgetIsHidden(false, new WidgetPointer(635,2)); + ivar1 = add(ivar1, 29); + } else { + setWidgetIsHidden(true, new WidgetPointer(635,2)); + } + if (((boolean)bitconfig_4145)) { + setWidgetSprite(225, new WidgetPointer(635,16)); + setWidgetPosition(ivar0, ivar1, 0, 0, new WidgetPointer(635,16)); + setWidgetIsHidden(false, new WidgetPointer(635,3)); + ivar1 = add(ivar1, 29); + } else { + setWidgetIsHidden(true, new WidgetPointer(635,3)); + } + if (((boolean)bitconfig_4146)) { + setWidgetSprite(201, new WidgetPointer(635,17)); + setWidgetPosition(ivar0, ivar1, 0, 0, new WidgetPointer(635,17)); + setWidgetIsHidden(false, new WidgetPointer(635,4)); + ivar1 = add(ivar1, 29); + } else { + setWidgetIsHidden(true, new WidgetPointer(635,4)); + } + if (((boolean)bitconfig_4147)) { + setWidgetSprite(226, new WidgetPointer(635,18)); + setWidgetPosition(ivar0, ivar1, 0, 0, new WidgetPointer(635,18)); + setWidgetIsHidden(false, new WidgetPointer(635,5)); + ivar1 = add(ivar1, 29); + } else { + setWidgetIsHidden(true, new WidgetPointer(635,5)); + } + if (((boolean)bitconfig_4151)) { + setWidgetSprite(203, new WidgetPointer(635,20)); + setWidgetPosition(ivar0, ivar1, 0, 0, new WidgetPointer(635,20)); + setWidgetIsHidden(false, new WidgetPointer(635,7)); + ivar1 = add(ivar1, 29); + } else { + setWidgetIsHidden(true, new WidgetPointer(635,7)); + } + if (((boolean)bitconfig_4152)) { + setWidgetSprite(227, new WidgetPointer(635,21)); + setWidgetPosition(ivar0, ivar1, 0, 0, new WidgetPointer(635,21)); + setWidgetIsHidden(false, new WidgetPointer(635,8)); + ivar1 = add(ivar1, 29); + } else { + setWidgetIsHidden(true, new WidgetPointer(635,8)); + } + if (((boolean)bitconfig_4276)) { + setWidgetSprite(222, new WidgetPointer(635,19)); + setWidgetPosition(ivar0, ivar1, 0, 0, new WidgetPointer(635,19)); + setWidgetIsHidden(false, new WidgetPointer(635,6)); + ivar1 = add(ivar1, 29); + } else { + setWidgetIsHidden(true, new WidgetPointer(635,6)); + } + ivar0 = 8; + ivar1 = 45; + if (((boolean)bitconfig_4148)) { + setWidgetSprite(200, new WidgetPointer(635,22)); + setWidgetPosition(ivar0, ivar1, 0, 0, new WidgetPointer(635,22)); + setWidgetIsHidden(false, new WidgetPointer(635,9)); + ivar1 = add(ivar1, 29); + } else { + setWidgetIsHidden(true, new WidgetPointer(635,9)); + } + if (((boolean)bitconfig_4149)) { + setWidgetSprite(197, new WidgetPointer(635,23)); + setWidgetPosition(ivar0, ivar1, 0, 0, new WidgetPointer(635,23)); + setWidgetIsHidden(false, new WidgetPointer(635,10)); + ivar1 = add(ivar1, 29); + } else { + setWidgetIsHidden(true, new WidgetPointer(635,10)); + } + if (((boolean)bitconfig_4150)) { + setWidgetSprite(202, new WidgetPointer(635,24)); + setWidgetPosition(ivar0, ivar1, 0, 0, new WidgetPointer(635,24)); + setWidgetIsHidden(false, new WidgetPointer(635,11)); + ivar1 = add(ivar1, 29); + } else { + setWidgetIsHidden(true, new WidgetPointer(635,11)); + } + } else { + setWidgetSprite(-1, new WidgetPointer(635,15)); + setWidgetSprite(-1, new WidgetPointer(635,16)); + setWidgetSprite(-1, new WidgetPointer(635,17)); + setWidgetSprite(-1, new WidgetPointer(635,18)); + setWidgetSprite(-1, new WidgetPointer(635,20)); + setWidgetSprite(-1, new WidgetPointer(635,21)); + setWidgetSprite(-1, new WidgetPointer(635,22)); + setWidgetSprite(-1, new WidgetPointer(635,24)); + setWidgetSprite(-1, new WidgetPointer(635,23)); + setWidgetSprite(-1, new WidgetPointer(635,19)); + setWidgetText(new WidgetPointer(635,32), " "); + setWidgetText(new WidgetPointer(635,30), " "); + setWidgetText(new WidgetPointer(635,26), " "); + setWidgetIsHidden(true, new WidgetPointer(635,33)); + } + return; +} diff --git a/dumps/scripts/566.cs2 b/dumps/scripts/566.cs2 new file mode 100644 index 0000000..b39dfda --- /dev/null +++ b/dumps/scripts/566.cs2 @@ -0,0 +1,6 @@ +void script_566(int arg0) { + if (getWidgetSpriteId(new WidgetPointer(arg0)) == 5456) { + setWidgetSprite(5455, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/567.cs2 b/dumps/scripts/567.cs2 new file mode 100644 index 0000000..1321719 --- /dev/null +++ b/dumps/scripts/567.cs2 @@ -0,0 +1,172 @@ +void script_567(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + ivar4 = 0; + if (arg0 == 70254793) { + switch (bitconfig_8876) { + case 0: + ivar1 = 1; + break; + case 1: + ivar1 = 9; + break; + case 2: + ivar1 = 12; + break; + case 3: + ivar1 = 75; + } + ivar3 = multiply(ivar1, bitconfig_8877); + if (subtract(bitconfig_8857, ivar3) > 0) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(1072,53)); + ivar3 = subtract(bitconfig_8857, ivar3); + } else { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(1072,53)); + ivar3 = 0; + } + } else if (arg0 == 70254805) { + switch (bitconfig_8876) { + case 0: + ivar1 = 1; + ivar2 = 2; + break; + case 1: + ivar1 = 4; + ivar2 = 7; + break; + case 2: + ivar1 = 9; + ivar2 = 17; + break; + case 3: + ivar1 = 40; + ivar2 = 80; + } + ivar3 = multiply(ivar1, bitconfig_8877); + if (subtract(bitconfig_8857, ivar3) > 0) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(1072,53)); + ivar3 = subtract(bitconfig_8857, ivar3); + } else { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(1072,53)); + ivar3 = 0; + } + ivar4 = multiply(ivar2, bitconfig_8877); + if (subtract(bitconfig_8865, ivar4) > 0) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(1072,49)); + ivar4 = subtract(bitconfig_8865, ivar4); + } else { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(1072,49)); + ivar4 = 0; + } + } else if (arg0 == 70254817) { + switch (bitconfig_8876) { + case 0: + ivar1 = 1; + ivar2 = 4; + break; + case 1: + ivar1 = 3; + ivar2 = 12; + break; + case 2: + ivar1 = 6; + ivar2 = 24; + break; + case 3: + ivar1 = 30; + ivar2 = 120; + } + ivar3 = multiply(ivar1, bitconfig_8877); + if (subtract(bitconfig_8859, ivar3) > 0) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(1072,57)); + ivar3 = subtract(bitconfig_8859, ivar3); + } else { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(1072,57)); + ivar3 = 0; + } + ivar4 = multiply(ivar2, bitconfig_8877); + if (subtract(bitconfig_8865, ivar4) > 0) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(1072,49)); + ivar4 = subtract(bitconfig_8865, ivar4); + } else { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(1072,49)); + ivar4 = 0; + } + } else if (arg0 == 70254829) { + switch (bitconfig_8876) { + case 0: + ivar1 = 1; + ivar2 = 6; + break; + case 1: + ivar1 = 3; + ivar2 = 14; + break; + case 2: + ivar1 = 4; + ivar2 = 22; + break; + case 3: + ivar1 = 25; + ivar2 = 150; + } + ivar3 = multiply(ivar1, bitconfig_8877); + if (subtract(bitconfig_8862, ivar3) > 0) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(1072,61)); + ivar3 = subtract(bitconfig_8862, ivar3); + } else { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(1072,61)); + ivar3 = 0; + } + ivar4 = multiply(ivar2, bitconfig_8877); + if (subtract(bitconfig_8865, ivar4) > 0) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(1072,49)); + ivar4 = subtract(bitconfig_8865, ivar4); + } else { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(1072,49)); + ivar4 = 0; + } + } else { + if (arg0 == 70254841) { + switch (bitconfig_8876) { + case 0: + ivar1 = 1; + ivar2 = 8; + break; + case 1: + ivar1 = 2; + ivar2 = 16; + break; + case 2: + ivar1 = 4; + ivar2 = 30; + break; + case 3: + ivar1 = 18; + ivar2 = 144; + } + ivar3 = multiply(ivar1, bitconfig_8877); + if (subtract(bitconfig_8863, ivar3) > 0) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(1072,65)); + ivar3 = subtract(bitconfig_8863, ivar3); + } else { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(1072,65)); + ivar3 = 0; + } + ivar4 = multiply(ivar2, bitconfig_8877); + if (subtract(bitconfig_8865, ivar4) > 0) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(1072,49)); + ivar4 = subtract(bitconfig_8865, ivar4); + } else { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(1072,49)); + ivar4 = 0; + } + } + } + return; +} diff --git a/dumps/scripts/568.cs2 b/dumps/scripts/568.cs2 new file mode 100644 index 0000000..45b2240 --- /dev/null +++ b/dumps/scripts/568.cs2 @@ -0,0 +1,4 @@ +void script_568(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5) { + script_569(arg0, arg1, arg2, arg3, arg4, arg5); + return; +} diff --git a/dumps/scripts/569.cs2 b/dumps/scripts/569.cs2 new file mode 100644 index 0000000..548818c --- /dev/null +++ b/dumps/scripts/569.cs2 @@ -0,0 +1,4 @@ +void script_569(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5) { + script_5335(arg0, arg1, arg2, arg3, arg4, 0, arg5); + return; +} diff --git a/dumps/scripts/57.cs2 b/dumps/scripts/57.cs2 new file mode 100644 index 0000000..96dc53a --- /dev/null +++ b/dumps/scripts/57.cs2 @@ -0,0 +1,15 @@ +int script_57() { + int ivar0; + ivar0 = 0; + ivar0 = add(ivar0, 5); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 5); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + return ivar0; +} diff --git a/dumps/scripts/570.cs2 b/dumps/scripts/570.cs2 new file mode 100644 index 0000000..c3aca6a --- /dev/null +++ b/dumps/scripts/570.cs2 @@ -0,0 +1,17 @@ +void script_570(string arg0) { + setWidgetIsHidden(true, new WidgetPointer(752,8)); + setWidgetIsHidden(true, new WidgetPointer(752,3)); + setWidgetIsHidden(false, new WidgetPointer(752,7)); + setScriptCallOnKeyPress(574, -2147483640, false, "iz", new WidgetPointer(389,9)); + setWidgetText(new WidgetPointer(389,6), arg0); + setWidgetIsHidden(false, new WidgetPointer(389,5)); + setItemOnWidgetMethod2200(-1, -1, new WidgetPointer(389,15)); + script_1188(); + globalstring_22 = ""; + setWidgetText(new WidgetPointer(389,9), "*"); + deleteAllExtraChilds(new WidgetPointer(389,4)); + setWidgetScrollMax(0, 15, new WidgetPointer(389,4)); + script_31(25493512, 25493508, 792, 789, 790, 791, 773, 788); + setScriptCallOnWindowPaneRefresh(572, "", new WidgetPointer(389,9)); + return; +} diff --git a/dumps/scripts/571.cs2 b/dumps/scripts/571.cs2 new file mode 100644 index 0000000..6c3ae81 --- /dev/null +++ b/dumps/scripts/571.cs2 @@ -0,0 +1,4 @@ +void script_571() { + script_573(); + return; +} diff --git a/dumps/scripts/572.cs2 b/dumps/scripts/572.cs2 new file mode 100644 index 0000000..c5f13e3 --- /dev/null +++ b/dumps/scripts/572.cs2 @@ -0,0 +1,4 @@ +void script_572() { + script_573(); + return; +} diff --git a/dumps/scripts/573.cs2 b/dumps/scripts/573.cs2 new file mode 100644 index 0000000..21e5154 --- /dev/null +++ b/dumps/scripts/573.cs2 @@ -0,0 +1,13 @@ +void script_573() { + deleteAllExtraChilds(new WidgetPointer(389,4)); + setWidgetIsHidden(false, new WidgetPointer(752,8)); + setWidgetIsHidden(true, new WidgetPointer(752,3)); + setWidgetIsHidden(true, new WidgetPointer(752,7)); + setScriptCallOnKeyPress(-1, "", new WidgetPointer(389,9)); + setScriptCallOnWindowPaneRefresh(-1, "", new WidgetPointer(389,9)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(389,9)); + if (getDisplayMode() >= 2) { + script_1364(); + } + return; +} diff --git a/dumps/scripts/574.cs2 b/dumps/scripts/574.cs2 new file mode 100644 index 0000000..9bd1814 --- /dev/null +++ b/dumps/scripts/574.cs2 @@ -0,0 +1,18 @@ +void script_574(int arg0,int arg1) { + string svar0; + if (arg0 == 84) { + globalint_81 = 0; + setScriptCallOnGameloop(-1, "", new WidgetPointer(389,9)); + script_576(); + return; + } + svar0 = script_74(0, arg0, arg1, globalstring_22); + if (((boolean)stringMethod4107(globalstring_22, svar0))) { + return; + } + globalstring_22 = svar0; + setWidgetText(new WidgetPointer(389,9), replaceLtGt(globalstring_22) + "*"); + globalint_81 = 50; + setScriptCallOnGameloop(575, "", new WidgetPointer(389,9)); + return; +} diff --git a/dumps/scripts/575.cs2 b/dumps/scripts/575.cs2 new file mode 100644 index 0000000..d1b1d29 --- /dev/null +++ b/dumps/scripts/575.cs2 @@ -0,0 +1,9 @@ +void script_575() { + globalint_81 = subtract(globalint_81, 1); + if (globalint_81 > 0) { + return; + } + setScriptCallOnGameloop(-1, "", new WidgetPointer(389,9)); + script_576(); + return; +} diff --git a/dumps/scripts/576.cs2 b/dumps/scripts/576.cs2 new file mode 100644 index 0000000..2283351 --- /dev/null +++ b/dumps/scripts/576.cs2 @@ -0,0 +1,13 @@ +void script_576() { + setItemOnWidgetMethod2200(-1, -1, new WidgetPointer(389,15)); + deleteAllExtraChilds(new WidgetPointer(389,4)); + if (strLength(globalstring_22) > 0) { + setWidgetIsHidden(true, new WidgetPointer(389,5)); + script_577(globalstring_22); + } else { + setWidgetIsHidden(false, new WidgetPointer(389,5)); + setWidgetScrollMax(0, 15, new WidgetPointer(389,4)); + script_578(); + } + return; +} diff --git a/dumps/scripts/577.cs2 b/dumps/scripts/577.cs2 new file mode 100644 index 0000000..ae17b03 --- /dev/null +++ b/dumps/scripts/577.cs2 @@ -0,0 +1,55 @@ +void script_577(string arg0) { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + ivar0 = cs2method4210(1, arg0); + ivar1 = getWidgetActualWidth(new WidgetPointer(389,4)); + ivar2 = subtract(ivar1, 8); + if (ivar0 == -1) { + createExtraChild(new WidgetPointer(389,4), 4, 0); + setWidgetPosition(0, 48, 0, 0); + setWidgetSize(ivar1, 16, 0, 0); + setWidgetFont(494); + setWidgetText("Too many results. Please refine your search."); + setWidgetTextAlignment(1, 1, 0); + setWidgetRGB(new Color(160, 90, 0)); + setWidgetUnknownBoolean(false); + setWidgetScrollMax(0, 15, new WidgetPointer(389,4)); + script_578(); + return; + } + if (((boolean)ivar0)) { + createExtraChild(new WidgetPointer(389,4), 4, 0); + setWidgetPosition(0, 48, 0, 0); + setWidgetSize(ivar1, 16, 0, 0); + setWidgetFont(494); + setWidgetText("No matching items found."); + setWidgetTextAlignment(1, 1, 0); + setWidgetRGB(new Color(160, 90, 0)); + setWidgetUnknownBoolean(false); + setWidgetScrollMax(0, 15, new WidgetPointer(389,4)); + script_578(); + return; + } + ivar3 = 1; + ivar4 = cs2method4211(); + createExtraChild(new WidgetPointer(389,4), 3, 0); + while (ivar4 != -1) { + createExtraChild(new WidgetPointer(389,4), 4, ivar3); + setWidgetPosition(4, multiply(15, subtract(ivar3, 1)), 0, 0); + setWidgetSize(ivar2, 15, 0, 0); + setWidgetRGB(new Color(160, 90, 0)); + setWidgetText(getItemName(ivar4)); + setWidgetFont(495); + setWidgetUnknownBoolean(false); + setScriptCallOnMouseEntered(579, ivar3, ivar4, "io"); + setScriptCallOnMousePressed(580, ivar4, "o"); + ivar4 = cs2method4211(); + ivar3 = add(ivar3, 1); + } + setWidgetScrollMax(0, multiply(15, subtract(ivar3, 1)), new WidgetPointer(389,4)); + script_578(); + return; +} diff --git a/dumps/scripts/578.cs2 b/dumps/scripts/578.cs2 new file mode 100644 index 0000000..82c1fe6 --- /dev/null +++ b/dumps/scripts/578.cs2 @@ -0,0 +1,22 @@ +void script_578() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + ivar0 = getWidgetActualHeight(new WidgetPointer(389,4)); + ivar1 = getWidgetScrollMaxV(new WidgetPointer(389,4)); + if (ivar1 < 15) { + ivar1 = 15; + setWidgetScrollMax(0, 15, new WidgetPointer(389,4)); + } + ivar2 = subtract(ivar1, ivar0); + if (ivar2 < 0) { + ivar2 = 0; + } + ivar3 = cs2method2601(new WidgetPointer(389,4)); + if (ivar3 > ivar2) { + ivar3 = ivar2; + } + script_72(25493512, 25493508, ivar3); + return; +} diff --git a/dumps/scripts/579.cs2 b/dumps/scripts/579.cs2 new file mode 100644 index 0000000..cfa0dde --- /dev/null +++ b/dumps/scripts/579.cs2 @@ -0,0 +1,11 @@ +void script_579(int arg0,int arg1) { + if (setWidgetRegister(new WidgetPointer(389,4), 0)) { + setWidgetPosition(0, multiply(15, subtract(arg0, 1)), 0, 0); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(389,4)), 15, 0, 0); + setWidgetRGB(new Color(0, 0, 0)); + cs2method2103(220); + setWidgetFilled(1); + } + setItemOnWidgetMethod2200(arg1, -1, new WidgetPointer(389,15)); + return; +} diff --git a/dumps/scripts/58.cs2 b/dumps/scripts/58.cs2 new file mode 100644 index 0000000..f046bb5 --- /dev/null +++ b/dumps/scripts/58.cs2 @@ -0,0 +1,4 @@ +void script_58(int arg0) { + script_59(arg0); + return; +} diff --git a/dumps/scripts/580.cs2 b/dumps/scripts/580.cs2 new file mode 100644 index 0000000..331f8a3 --- /dev/null +++ b/dumps/scripts/580.cs2 @@ -0,0 +1,5 @@ +void script_580(int arg0) { + sendUnknownPacketMethod3110(arg0); + script_573(); + return; +} diff --git a/dumps/scripts/581.cs2 b/dumps/scripts/581.cs2 new file mode 100644 index 0000000..6ea7dee --- /dev/null +++ b/dumps/scripts/581.cs2 @@ -0,0 +1,4 @@ +void script_581(int arg0) { + script_582(arg0); + return; +} diff --git a/dumps/scripts/582.cs2 b/dumps/scripts/582.cs2 new file mode 100644 index 0000000..bd76366 --- /dev/null +++ b/dumps/scripts/582.cs2 @@ -0,0 +1,32 @@ +void script_582(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + ivar1 = getWidgetActualWidth(new WidgetPointer(arg0)); + ivar2 = getWidgetActualHeight(new WidgetPointer(arg0)); + ivar3 = subtract(ivar1, 32); + ivar4 = subtract(ivar2, 32); + ivar5 = subtract(ivar1, 64); + ivar6 = subtract(ivar2, 64); + if (ivar5 < 0) { + ivar5 = 0; + } + if (ivar6 < 0) { + ivar6 = 0; + } + ivar7 = getExtraChildGap(new WidgetPointer(arg0)); + script_98(arg0, ivar7, 1136, 7, 7, subtract(ivar1, 14), subtract(ivar2, 14)); + script_98(arg0, add(ivar7, 1), 958, 0, 0, 32, 32); + script_98(arg0, add(ivar7, 2), 959, ivar3, 0, 32, 32); + script_98(arg0, add(ivar7, 3), 960, 0, ivar4, 32, 32); + script_98(arg0, add(ivar7, 4), 961, ivar3, ivar4, 32, 32); + script_98(arg0, add(ivar7, 5), 954, 32, 0, ivar5, 32); + script_98(arg0, add(ivar7, 6), 955, 0, 32, 32, ivar6); + script_98(arg0, add(ivar7, 7), 956, 32, ivar4, ivar5, 32); + script_98(arg0, add(ivar7, 8), 957, ivar3, 32, 32, ivar6); + return; +} diff --git a/dumps/scripts/583.cs2 b/dumps/scripts/583.cs2 new file mode 100644 index 0000000..f954715 --- /dev/null +++ b/dumps/scripts/583.cs2 @@ -0,0 +1,4 @@ +void script_583(int arg0,string arg1) { + script_584(arg0, arg1); + return; +} diff --git a/dumps/scripts/584.cs2 b/dumps/scripts/584.cs2 new file mode 100644 index 0000000..b2e4e7b --- /dev/null +++ b/dumps/scripts/584.cs2 @@ -0,0 +1,40 @@ +void script_584(int arg0,string arg1) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + ivar1 = getWidgetActualWidth(new WidgetPointer(arg0)); + ivar2 = getWidgetActualHeight(new WidgetPointer(arg0)); + ivar3 = subtract(ivar1, 32); + ivar4 = subtract(ivar2, 32); + ivar5 = subtract(ivar1, 64); + ivar6 = subtract(ivar2, 64); + if (ivar5 < 0) { + ivar5 = 0; + } + if (ivar6 < 0) { + ivar6 = 0; + } + ivar7 = getExtraChildGap(new WidgetPointer(arg0)); + script_98(arg0, ivar7, 856, 0, 0, 32, 32); + script_98(arg0, add(ivar7, 1), 857, ivar3, 0, 32, 32); + script_98(arg0, add(ivar7, 2), 858, 0, ivar4, 32, 32); + script_98(arg0, add(ivar7, 3), 859, ivar3, ivar4, 32, 32); + script_98(arg0, add(ivar7, 4), 1121, 32, 0, ivar5, 3); + script_98(arg0, add(ivar7, 5), 1121, 32, subtract(ivar2, 3), ivar5, 3); + script_98(arg0, add(ivar7, 6), 1122, 0, 32, 3, ivar6); + script_98(arg0, add(ivar7, 7), 1122, subtract(ivar1, 3), 32, 3, ivar6); + script_98(arg0, add(ivar7, 8), 1121, 2, 22, subtract(ivar1, 5), 3); + createExtraChild(new WidgetPointer(arg0), 4, add(ivar7, 9)); + setWidgetPosition(3, 3, 0, 0); + setWidgetSize(subtract(ivar1, 6), 15, 0, 0); + setWidgetText(arg1); + setWidgetFont(496); + setWidgetUnknownBoolean(true); + setWidgetRGB(new Color(204, 153, 0)); + setWidgetTextAlignment(1, 1, 0); + return; +} diff --git a/dumps/scripts/585.cs2 b/dumps/scripts/585.cs2 new file mode 100644 index 0000000..eeb7b96 --- /dev/null +++ b/dumps/scripts/585.cs2 @@ -0,0 +1,6 @@ +void script_585() { + setScriptCallOnConfigChange(588, 1109, 1, "Y", new WidgetPointer(105,127)); + setScriptCallOnGrandExchangeUpdate(586, "", new WidgetPointer(105,15)); + script_621(); + return; +} diff --git a/dumps/scripts/586.cs2 b/dumps/scripts/586.cs2 new file mode 100644 index 0000000..8e6490d --- /dev/null +++ b/dumps/scripts/586.cs2 @@ -0,0 +1,4 @@ +void script_586() { + script_621(); + return; +} diff --git a/dumps/scripts/587.cs2 b/dumps/scripts/587.cs2 new file mode 100644 index 0000000..595b9cf --- /dev/null +++ b/dumps/scripts/587.cs2 @@ -0,0 +1,4 @@ +void script_587() { + script_621(); + return; +} diff --git a/dumps/scripts/588.cs2 b/dumps/scripts/588.cs2 new file mode 100644 index 0000000..83585c0 --- /dev/null +++ b/dumps/scripts/588.cs2 @@ -0,0 +1,6 @@ +void script_588() { + globalint_82 = 0; + globalint_83 = 0; + script_621(); + return; +} diff --git a/dumps/scripts/589.cs2 b/dumps/scripts/589.cs2 new file mode 100644 index 0000000..7a81abb --- /dev/null +++ b/dumps/scripts/589.cs2 @@ -0,0 +1,4 @@ +void script_589() { + script_621(); + return; +} diff --git a/dumps/scripts/59.cs2 b/dumps/scripts/59.cs2 new file mode 100644 index 0000000..44d3d04 --- /dev/null +++ b/dumps/scripts/59.cs2 @@ -0,0 +1,311 @@ +void script_59(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + int ivar22; + int ivar23; + string svar0; + string svar1; + int stack_dump0; + if (bitconfig_9227 > 1) { + setWidgetText(new WidgetPointer(18,12), "Select " + intToStr(bitconfig_9227) + " items to keep. The rest will be dropped."); + } else if (((boolean)bitconfig_9227)) { + setWidgetText(new WidgetPointer(18,12), "Select an item to keep. The rest will be dropped."); + } else { + setWidgetText(new WidgetPointer(18,12), "These items will be dropped."); + } + globalarray_0 = new int[4]; + globalarray_0[0] = script_750(bitconfig_9222); + globalarray_0[1] = script_750(bitconfig_9223); + globalarray_0[2] = script_750(bitconfig_9224); + globalarray_0[3] = script_750(bitconfig_9225); + deleteAllExtraChilds(new WidgetPointer(18,9)); + deleteAllExtraChilds(new WidgetPointer(18,8)); + ivar1 = 15; + ivar2 = -1; + ivar3 = 6014; + ivar4 = 6015; + ivar5 = -1; + while ((ivar5 < bitconfig_9227) && (ivar5 < 4)) { + ivar5 = max(ivar5, 0); + createExtraChild(new WidgetPointer(18,8), 5, getExtraChildGap(new WidgetPointer(18,8))); + setWidgetSize(36, 36, 0, 0); + setWidgetPosition(ivar1, 0, 0, 1); + setWidgetSprite(ivar3); + ivar2 = globalarray_0[ivar5]; + createExtraChild(new WidgetPointer(18,9), 5, getExtraChildGap(new WidgetPointer(18,9))); + if (((boolean)bitconfig_9227)) { + setWidgetSize(36, 36, 0, 0); + setWidgetPosition(ivar1, 0, 0, 1); + setWidgetSprite(1132); + } else { + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(add(ivar1, 2), 0, 0, 1); + if (ivar2 != -1) { + setItemOnWidgetMethod1205(ivar2, 1); + setWidgetContextMenuOption(1, "Unprotect"); + setWidgetContextMenuOption(10, "Examine"); + setWidgetShadowColor(new Color(48, 32, 32)); + setWidgetBorderThickness(1); + cs2method1305("" + getItemName(ivar2) + ""); + cs2method1301(1179650, -1); + cs2method1302(2); + cs2method1303(5); + cs2method1304(5); + setScriptCallOnClickContextMenu(1620, new WidgetPointer(-32768,3), -2147483643, 100, 0, 8, "Iiiii"); + setScriptCallOnMouseDragReleased(744, new WidgetPointer(-32768,3), -2147483643, new WidgetPointer(-32768,6), -2147483641, arg0, "IiIii"); + } + setScriptCallOnMouseEntered(688, new WidgetPointer(-32768,3), -2147483643, ivar4, "Iid"); + setScriptCallOnMouseExit(688, new WidgetPointer(-32768,3), -2147483643, ivar3, "Iid"); + } + ivar1 = add(add(ivar1, max(getWidgetActualWidth(), getWidgetActualWidth())), 10); + ivar5 = add(ivar5, 1); + } + ivar1 = add(ivar1, 9); + setWidgetSize(ivar1, getWidgetActualHeight(new WidgetPointer(18,3)), 0, 0, new WidgetPointer(18,3)); + deleteAllExtraChilds(new WidgetPointer(18,16)); + deleteAllExtraChilds(new WidgetPointer(18,17)); + deleteAllExtraChilds(new WidgetPointer(18,24)); + deleteAllExtraChilds(new WidgetPointer(18,25)); + ivar6 = 0; + ivar7 = 0; + ivar8 = 0; + ivar9 = 0; + ivar10 = 0; + ivar11 = 0; + ivar12 = getWidgetActualWidth(new WidgetPointer(18,2)); + ivar13 = subtract(ivar12, add(max(getWidgetActualWidth(new WidgetPointer(18,18)), getWidgetActualWidth(new WidgetPointer(18,26))), 4)); + ivar14 = max(divide(ivar13, 36), 1); + ivar15 = divide(subtract(ivar13, multiply(36, ivar14)), max(subtract(ivar14, 1), 1)); + ivar16 = max(divide(ivar15, 2), 4); + ivar17 = add(getItemContainerLength(93), getItemContainerLength(94)); + ivar18 = 0; + ivar19 = 0; + ivar5 = 0; + while (ivar5 <= ivar17) { + ivar2 = script_750(ivar5); + createExtraChild(new WidgetPointer(18,17), 5, ivar5); + createExtraChild(new WidgetPointer(18,25), 5, ivar5); + if (ivar2 != -1) { + ivar18 = script_1393(ivar5); + ivar19 = 0; + while ((ivar19 < 4) && (ivar18 > 0)) { + if (globalarray_0[ivar19] == ivar2) { + ivar18 = subtract(ivar18, 1); + globalarray_0[ivar19] = -1; + } + ivar19 = add(ivar19, 1); + } + if (ivar18 > 0) { + if (((boolean)getItemHashmapData(getRealItem(ivar2), 1397))) { + setWidgetSize(36, 32, 0, 0); + setItemOnWidgetMethod1200(ivar2, ivar18); + setWidgetShadowColor(new Color(48, 32, 32)); + setWidgetBorderThickness(1); + setWidgetContextMenuOption(10, "Examine"); + cs2method1305("" + getItemName(ivar2) + ""); + ivar10 = multiply(ivar8, add(36, ivar15)); + ivar11 = multiply(ivar9, add(32, ivar16)); + setWidgetPosition(add(ivar10, 2), add(ivar11, 2), 0, 0); + ivar8 = add(ivar8, 1); + if (ivar8 >= ivar14) { + stack_dump0 = 0; + ivar9 = add(ivar9, 1); + ivar8 = stack_dump0; + } + setWidgetHidden(1); + createExtraChild(new WidgetPointer(18,24), 5, getExtraChildGap(new WidgetPointer(18,24))); + setWidgetSize(36, 36, 0, 0); + setWidgetPosition(ivar10, ivar11, 0, 0); + setWidgetSprite(6016); + } else { + setWidgetSize(36, 32, 0, 0); + setItemOnWidgetMethod1200(ivar2, ivar18); + setWidgetShadowColor(new Color(48, 32, 32)); + setWidgetBorderThickness(1); + setWidgetContextMenuOption(1, "Protect"); + setWidgetContextMenuOption(10, "Examine"); + cs2method1305("" + getItemName(ivar2) + ""); + ivar10 = multiply(ivar6, add(36, ivar15)); + ivar11 = multiply(ivar7, add(32, ivar16)); + setWidgetPosition(add(ivar10, 2), add(ivar11, 2), 0, 0); + cs2method1301(1179650, -1); + cs2method1302(2); + cs2method1303(5); + cs2method1304(5); + setScriptCallOnClickContextMenu(1620, new WidgetPointer(-32768,3), -2147483643, 100, 0, 8, "Iiiii"); + setScriptCallOnMouseDragReleased(744, new WidgetPointer(-32768,3), -2147483643, new WidgetPointer(-32768,6), -2147483641, arg0, "IiIii"); + ivar6 = add(ivar6, 1); + if (ivar6 >= ivar14) { + stack_dump0 = 0; + ivar7 = add(ivar7, 1); + ivar6 = stack_dump0; + } + setWidgetHidden(1); + createExtraChild(new WidgetPointer(18,16), 5, getExtraChildGap(new WidgetPointer(18,16))); + setWidgetSize(36, 36, 0, 0); + setWidgetPosition(ivar10, ivar11, 0, 0); + setWidgetSprite(ivar3); + setScriptCallOnMouseEntered(688, new WidgetPointer(-32768,3), -2147483643, ivar4, "Iid"); + setScriptCallOnMouseExit(688, new WidgetPointer(-32768,3), -2147483643, ivar3, "Iid"); + } + } else { + setWidgetHidden(1); + setWidgetHidden(1); + } + } else { + setWidgetHidden(1); + setWidgetHidden(1); + } + ivar5 = add(ivar5, 1); + } + if (ivar6 <= 0) { + ivar7 = max(subtract(ivar7, 1), 0); + } + if (ivar8 <= 0) { + ivar9 = max(subtract(ivar9, 1), 0); + } + ivar20 = multiply(add(ivar7, 1), add(32, ivar16)); + ivar21 = multiply(add(ivar9, 1), add(32, ivar16)); + if ((ivar7 < 2) && (ivar7 <= ivar9)) { + setWidgetSize(0, add(add(ivar20, getWidgetActualHeight(new WidgetPointer(18,12))), 6), 1, 0, new WidgetPointer(18,11)); + setWidgetSize(0, add(getWidgetActualHeight(new WidgetPointer(18,11)), 3), 1, 1, new WidgetPointer(18,19)); + } else { + if ((ivar9 < 2) && (ivar9 <= ivar7)) { + setWidgetSize(0, add(add(ivar21, getWidgetActualHeight(new WidgetPointer(18,20))), 6), 1, 0, new WidgetPointer(18,19)); + setWidgetSize(0, add(getWidgetActualHeight(new WidgetPointer(18,19)), 3), 1, 1, new WidgetPointer(18,11)); + } + } + if ((ivar6 <= 0) && (ivar7 <= 0)) { + createExtraChild(new WidgetPointer(18,17), 4, getExtraChildGap(new WidgetPointer(18,17))); + setWidgetSize(0, 0, 1, 1); + setWidgetPosition(0, 0, 1, 0); + setWidgetRGB(new Color(255, 255, 255)); + setWidgetUnknownBoolean(true); + setWidgetFont(495); + setWidgetTextAlignment(1, 1, 0); + setWidgetText("You haven't got any more items to choose."); + } + if (ivar20 > getWidgetActualHeight(new WidgetPointer(18,15))) { + setWidgetScrollMax(0, ivar20, new WidgetPointer(18,15)); + setWidgetSize(0, ivar20, 1, 0, new WidgetPointer(18,17)); + setWidgetSize(0, ivar20, 1, 0, new WidgetPointer(18,16)); + script_31(1179666, 1179663, 6507, 6504, 6505, 6506, 6499, 6498); + setWidgetIsHidden(false, new WidgetPointer(18,18)); + setWidgetPosition(2, 0, 0, 1, new WidgetPointer(18,15)); + } else { + setWidgetScrollMax(0, 0, new WidgetPointer(18,15)); + setWidgetSize(0, 0, 1, 1, new WidgetPointer(18,17)); + setWidgetSize(0, 0, 1, 1, new WidgetPointer(18,16)); + cs2method2100(0, 0, new WidgetPointer(18,15)); + deleteAllExtraChilds(new WidgetPointer(18,18)); + setWidgetIsHidden(true, new WidgetPointer(18,18)); + setWidgetPosition(0, 0, 1, 1, new WidgetPointer(18,15)); + } + if (ivar21 > getWidgetActualHeight(new WidgetPointer(18,23))) { + setWidgetScrollMax(0, ivar21, new WidgetPointer(18,23)); + setWidgetSize(0, ivar21, 1, 0, new WidgetPointer(18,25)); + setWidgetSize(0, ivar21, 1, 0, new WidgetPointer(18,24)); + script_31(1179674, 1179671, 6507, 6504, 6505, 6506, 6499, 6498); + setWidgetIsHidden(false, new WidgetPointer(18,26)); + setWidgetPosition(2, 0, 0, 1, new WidgetPointer(18,23)); + } else { + setWidgetScrollMax(0, 0, new WidgetPointer(18,23)); + setWidgetSize(0, 0, 1, 1, new WidgetPointer(18,25)); + setWidgetSize(0, 0, 1, 1, new WidgetPointer(18,24)); + cs2method2100(0, 0, new WidgetPointer(18,23)); + deleteAllExtraChilds(new WidgetPointer(18,26)); + setWidgetIsHidden(true, new WidgetPointer(18,26)); + setWidgetPosition(0, 0, 1, 1, new WidgetPointer(18,23)); + } + deleteAllExtraChilds(new WidgetPointer(18,45)); + if (standart_config_105 != -1) { + setWidgetIsHidden(true, new WidgetPointer(18,27)); + setWidgetIsHidden(true, new WidgetPointer(18,42)); + setWidgetPosition(0, 0, 1, 0, new WidgetPointer(18,3)); + return; + } + setWidgetIsHidden(false, new WidgetPointer(18,27)); + svar0 = "Your hub (" + cs2method_3408(105, 115, 3792, bitconfig_9231) + ")"; + svar1 = ""; + ivar22 = 0; + ivar5 = -1; + ivar17 = getCommonDefinitionSize(3796); + ivar7 = 2; + ivar23 = 0; + while (ivar5 <= ivar17) { + createExtraChild(new WidgetPointer(18,45), 4, add(ivar5, 1)); + ivar23 = 0; + switch (ivar5) { + case 0: + case -1: + ivar23 = 1; + break; + case 1: + if (((boolean)bitconfig_668) && isMember()) { + ivar23 = 1; + } + break; + case 2: + if (((boolean)bitconfig_3910) && isMember()) { + ivar23 = 1; + } + break; + case 3: + if (((boolean)bitconfig_6982) && isMember()) { + ivar23 = 1; + } + } + if (((boolean)ivar23)) { + if (ivar5 == -1) { + svar1 = svar0; + } else { + svar1 = cs2method_3408(105, 115, 3796, ivar5); + } + ivar22 = max(ivar22, getTextWidth(494, svar1)); + if (subtract(bitconfig_9228, 1) != ivar5) { + setWidgetSize(0, 15, 1, 0); + setWidgetPosition(0, ivar7, 1, 0); + setWidgetFont(494); + setWidgetTextAlignment(1, 1, 0); + setWidgetRGB(new Color(235, 224, 188)); + setScriptCallOnMouseEntered(743, new WidgetPointer(-32768,3), -2147483643, 1, "Ii1"); + setScriptCallOnMouseExit(743, new WidgetPointer(-32768,3), -2147483643, 0, "Ii1"); + setWidgetText(svar1); + setWidgetContextMenuOption(1, "Select"); + setScriptCallOnClickContextMenu(747, -2147483644, svar1, arg0, "isi"); + ivar7 = add(ivar7, getWidgetActualHeight()); + } else { + if (setWidgetRegister(new WidgetPointer(18,29), arg0)) { + setWidgetText(svar1); + } + } + } else { + setWidgetHidden(1); + } + ivar5 = add(ivar5, 1); + } + ivar22 = add(ivar22, 28); + setWidgetSize(ivar22, getWidgetActualHeight(new WidgetPointer(18,27)), 0, 0, new WidgetPointer(18,27)); + setWidgetSize(ivar22, add(ivar7, 6), 0, 0, new WidgetPointer(18,43)); + setWidgetPosition(max(subtract(add(ivar22, 1), divide(subtract(ivar12, ivar1), 2)), 0), 0, 1, 0, new WidgetPointer(18,3)); + return; +} diff --git a/dumps/scripts/590.cs2 b/dumps/scripts/590.cs2 new file mode 100644 index 0000000..3292b51 --- /dev/null +++ b/dumps/scripts/590.cs2 @@ -0,0 +1,13 @@ +void script_590(int arg0,int arg1) { + if (((boolean)arg1)) { + standart_config_1112 = arg0; + standart_config_1109 = -1; + if (getGENotStarted(arg0)) { + standart_config_1113 = -1; + standart_config_1111 = 1; + standart_config_1110 = 0; + } + script_621(); + } + return; +} diff --git a/dumps/scripts/591.cs2 b/dumps/scripts/591.cs2 new file mode 100644 index 0000000..fee4a06 --- /dev/null +++ b/dumps/scripts/591.cs2 @@ -0,0 +1,7 @@ +void script_591() { + standart_config_1112 = -1; + standart_config_1113 = -1; + standart_config_1109 = -1; + script_621(); + return; +} diff --git a/dumps/scripts/592.cs2 b/dumps/scripts/592.cs2 new file mode 100644 index 0000000..666a744 --- /dev/null +++ b/dumps/scripts/592.cs2 @@ -0,0 +1,5 @@ +void script_592() { + standart_config_1113 = 0; + script_621(); + return; +} diff --git a/dumps/scripts/593.cs2 b/dumps/scripts/593.cs2 new file mode 100644 index 0000000..1c4e612 --- /dev/null +++ b/dumps/scripts/593.cs2 @@ -0,0 +1,87 @@ +void script_593(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + string svar0; + string svar1; + ivar1 = cs2method_3408(105, 118, 1079, standart_config_1112); + ivar2 = getItemIdInSlot(ivar1, 0); + setItemOnWidgetMethod2200(ivar2, getItemAmtInSlot(ivar1, 0), new WidgetPointer(105,206)); + setWidgetNoOptions(new WidgetPointer(105,206)); + if (ivar2 != -1) { + if (getNotedItem(ivar2) != ivar2) { + if (getItemAmtInSlot(ivar1, 0) > 1) { + setWidgetContextMenuOption(1, new WidgetPointer(105,206), "Collect-notes"); + setWidgetContextMenuOption(2, new WidgetPointer(105,206), "Collect-items"); + } else { + setWidgetContextMenuOption(1, new WidgetPointer(105,206), "Collect-items"); + setWidgetContextMenuOption(2, new WidgetPointer(105,206), "Collect-notes"); + } + } else { + setWidgetContextMenuOption(1, new WidgetPointer(105,206), "Collect"); + } + cs2method2305(new WidgetPointer(105,206), getItemName(ivar2)); + } else { + cs2method2305(new WidgetPointer(105,206), ""); + } + ivar3 = getItemIdInSlot(ivar1, 1); + setItemOnWidgetMethod2200(ivar3, getItemAmtInSlot(ivar1, 1), new WidgetPointer(105,208)); + setWidgetNoOptions(new WidgetPointer(105,208)); + if (ivar3 != -1) { + if (getNotedItem(ivar3) != ivar3) { + if (getItemAmtInSlot(ivar1, 1) > 1) { + setWidgetContextMenuOption(1, new WidgetPointer(105,208), "Collect-notes"); + setWidgetContextMenuOption(2, new WidgetPointer(105,208), "Collect-items"); + } else { + setWidgetContextMenuOption(1, new WidgetPointer(105,208), "Collect-items"); + setWidgetContextMenuOption(2, new WidgetPointer(105,208), "Collect-notes"); + } + } else { + setWidgetContextMenuOption(1, new WidgetPointer(105,208), "Collect"); + } + cs2method2305(new WidgetPointer(105,208), getItemName(ivar3)); + } else { + cs2method2305(new WidgetPointer(105,208), ""); + } + setScriptCallOnItemContainerUpdate(589, ivar1, 1, "Y", new WidgetPointer(105,197)); + ivar4 = getGEIsSelling(arg0); + ivar5 = getGEItemAmt(arg0); + ivar6 = getGEItemAmtTransfered(arg0); + ivar7 = getGECashTransfered(arg0); + svar0 = formatNumber(ivar6, 1); + svar1 = formatNumber(ivar7, 1); + deleteAllExtraChilds(new WidgetPointer(105,199)); + if (setWidgetRegister(new WidgetPointer(105,199))) { + if (getGEIsStatus1(arg0)) { + createExtraChild(new WidgetPointer(105,199), 4, 0); + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(getWidgetActualWidth(), getWidgetActualHeight(), 0, 0); + setWidgetFont(494); + setWidgetRGB(new Color(219, 216, 132)); + setWidgetText("Submitting offer..."); + setWidgetTextAlignment(1, 1, 0); + } else { + script_652(0, 0, getWidgetActualWidth(), getWidgetActualHeight(), arg0, 6881479, 0, 6881490, 2); + } + } + if (getGEIsDone(arg0)) { + if (((boolean)ivar4)) { + setWidgetText(new WidgetPointer(105,198), "You bought a total of " + "" + svar0 + "" + "
" + "for a total price of " + "" + svar1 + "" + " gp."); + } else { + setWidgetText(new WidgetPointer(105,198), "You sold a total of " + "" + svar0 + "" + "
" + "for a total price of " + "" + svar1 + "" + " gp."); + } + setWidgetIsHidden(true, new WidgetPointer(105,200)); + } else { + if (((boolean)ivar4)) { + setWidgetText(new WidgetPointer(105,198), "You have bought a total of " + "" + svar0 + "" + " so far" + "
" + "for a total price of " + "" + svar1 + "" + " gp."); + } else { + setWidgetText(new WidgetPointer(105,198), "You have sold a total of " + "" + svar0 + "" + " so far" + "
" + "for a total price of " + "" + svar1 + "" + " gp."); + } + setWidgetIsHidden(false, new WidgetPointer(105,200)); + } + return; +} diff --git a/dumps/scripts/594.cs2 b/dumps/scripts/594.cs2 new file mode 100644 index 0000000..0c869da --- /dev/null +++ b/dumps/scripts/594.cs2 @@ -0,0 +1,121 @@ +void script_594(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + int ivar6; + int ivar7; + string svar0; + string svar1; + string svar2; + setItemOnWidgetMethod2200(arg1, -1, new WidgetPointer(105,139)); + svar0 = "null"; + svar1 = "null"; + svar2 = "null"; + if (((boolean)arg0)) { + setWidgetText(new WidgetPointer(105,134), "Buy Offer"); + setWidgetSprite(1157, new WidgetPointer(105,135)); + setWidgetText(new WidgetPointer(105,160), "+1"); + setWidgetContextMenuOption(1, new WidgetPointer(105,160), "Add 1"); + svar2 = "Add 1 to quantity"; + setScriptCallOnMouseOver(649, new WidgetPointer(-32768,3), new WidgetPointer(105,210), svar2, 25, 300, "IIsii", new WidgetPointer(105,160)); + setWidgetText(new WidgetPointer(105,162), "+10"); + setWidgetContextMenuOption(1, new WidgetPointer(105,162), "Add 10"); + svar2 = "Add 10 to quantity"; + setScriptCallOnMouseOver(649, new WidgetPointer(-32768,3), new WidgetPointer(105,210), svar2, 25, 300, "IIsii", new WidgetPointer(105,162)); + setWidgetText(new WidgetPointer(105,164), "+100"); + setWidgetContextMenuOption(1, new WidgetPointer(105,164), "Add 100"); + svar2 = "Add 100 to quantity"; + setScriptCallOnMouseOver(649, new WidgetPointer(-32768,3), new WidgetPointer(105,210), svar2, 25, 300, "IIsii", new WidgetPointer(105,164)); + setWidgetText(new WidgetPointer(105,166), "+1K"); + setWidgetContextMenuOption(1, new WidgetPointer(105,166), "Add 1000"); + svar2 = "Add 1,000 to quantity"; + setScriptCallOnMouseOver(649, new WidgetPointer(-32768,3), new WidgetPointer(105,210), svar2, 25, 300, "IIsii", new WidgetPointer(105,166)); + } else { + setWidgetText(new WidgetPointer(105,134), "Sell Offer"); + setWidgetSprite(1156, new WidgetPointer(105,135)); + setWidgetText(new WidgetPointer(105,160), "1"); + setWidgetContextMenuOption(1, new WidgetPointer(105,160), "Sell 1"); + svar2 = "Sell 1"; + setScriptCallOnMouseOver(649, new WidgetPointer(-32768,3), new WidgetPointer(105,210), svar2, 25, 300, "IIsii", new WidgetPointer(105,160)); + setWidgetText(new WidgetPointer(105,162), "10"); + setWidgetContextMenuOption(1, new WidgetPointer(105,162), "Sell 10"); + svar2 = "Sell 10"; + setScriptCallOnMouseOver(649, new WidgetPointer(-32768,3), new WidgetPointer(105,210), svar2, 25, 300, "IIsii", new WidgetPointer(105,162)); + setWidgetText(new WidgetPointer(105,164), "100"); + setWidgetContextMenuOption(1, new WidgetPointer(105,164), "Sell 100"); + svar2 = "Sell 100"; + setScriptCallOnMouseOver(649, new WidgetPointer(-32768,3), new WidgetPointer(105,210), svar2, 25, 300, "IIsii", new WidgetPointer(105,164)); + setWidgetText(new WidgetPointer(105,166), "ALL"); + setWidgetContextMenuOption(1, new WidgetPointer(105,166), "Sell All"); + svar2 = "Sell all"; + setScriptCallOnMouseOver(649, new WidgetPointer(-32768,3), new WidgetPointer(105,210), svar2, 25, 300, "IIsii", new WidgetPointer(105,166)); + } + if (arg1 == -1) { + setWidgetText(new WidgetPointer(105,142), "Choose an item to exchange"); + setWidgetText(new WidgetPointer(105,141), "N/A"); + setWidgetText(new WidgetPointer(105,143), ""); + if (((boolean)standart_config_1113)) { + if (getWidgetShadeColor(new WidgetPointer(105,138)) == 255) { + setScriptCallOnGameloop(634, new WidgetPointer(105,138), 0, 255, 5, "Iiii", new WidgetPointer(105,138)); + } + } else { + if (((boolean)standart_config_1113)) { + setWidgetIsHidden(false, new WidgetPointer(107,0)); + cs2method2103(255, new WidgetPointer(105,138)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(105,138)); + if (getWidgetShadeColor(new WidgetPointer(107,1)) == 245) { + setScriptCallOnGameloop(634, new WidgetPointer(107,1), 155, 255, 2, "Iiii", new WidgetPointer(107,1)); + setScriptCallOnGameloop(634, new WidgetPointer(107,2), 155, 255, 2, "Iiii", new WidgetPointer(107,2)); + setScriptCallOnGameloop(634, new WidgetPointer(107,3), 155, 255, 2, "Iiii", new WidgetPointer(107,3)); + setScriptCallOnGameloop(634, new WidgetPointer(107,4), 155, 255, 2, "Iiii", new WidgetPointer(107,4)); + setScriptCallOnGameloop(634, new WidgetPointer(107,5), 145, 245, 2, "Iiii", new WidgetPointer(107,5)); + setScriptCallOnGameloop(634, new WidgetPointer(107,6), 145, 245, 2, "Iiii", new WidgetPointer(107,6)); + setScriptCallOnGameloop(634, new WidgetPointer(107,7), 145, 245, 2, "Iiii", new WidgetPointer(107,7)); + setScriptCallOnGameloop(634, new WidgetPointer(107,8), 135, 235, 2, "Iiii", new WidgetPointer(107,8)); + setScriptCallOnGameloop(634, new WidgetPointer(107,9), 135, 235, 2, "Iiii", new WidgetPointer(107,9)); + setScriptCallOnGameloop(634, new WidgetPointer(107,10), 135, 235, 2, "Iiii", new WidgetPointer(107,10)); + setScriptCallOnGameloop(634, new WidgetPointer(107,11), 125, 225, 2, "Iiii", new WidgetPointer(107,11)); + setScriptCallOnGameloop(634, new WidgetPointer(107,12), 125, 225, 2, "Iiii", new WidgetPointer(107,12)); + setScriptCallOnGameloop(634, new WidgetPointer(107,13), 125, 225, 2, "Iiii", new WidgetPointer(107,13)); + setScriptCallOnGameloop(634, new WidgetPointer(107,14), 115, 215, 2, "Iiii", new WidgetPointer(107,14)); + setScriptCallOnGameloop(634, new WidgetPointer(107,15), 115, 215, 2, "Iiii", new WidgetPointer(107,15)); + setScriptCallOnGameloop(634, new WidgetPointer(107,16), 115, 215, 2, "Iiii", new WidgetPointer(107,16)); + setScriptCallOnGameloop(634, new WidgetPointer(107,17), 110, 210, 2, "Iiii", new WidgetPointer(107,17)); + } + } + } + } else { + setWidgetText(new WidgetPointer(105,142), getItemName(arg1)); + if (standart_config_1109 != -1) { + svar0 = formatNumber(standart_config_1114, 1); + setWidgetText(new WidgetPointer(105,141), svar0 + " gp"); + } else { + setWidgetText(new WidgetPointer(105,143), "Retrieving details..."); + setWidgetText(new WidgetPointer(105,141), "N/A"); + } + cs2method2103(255, new WidgetPointer(105,138)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(105,138)); + setWidgetIsHidden(true, new WidgetPointer(107,0)); + } + ivar4 = 0; + ivar5 = 0; + ivar6 = 0; + ivar7 = 0; + if (setWidgetRegister(new WidgetPointer(105,141)) && setWidgetRegister(new WidgetPointer(105,140))) { + ivar5 = getWidgetActualWidth(); + ivar6 = getMaxLineWidth(ivar5, 494, getWidgetText()); + ivar7 = getWidgetActualWidth(); + ivar4 = subtract(add(52, divide(subtract(ivar5, ivar6), 2)), subtract(ivar7, 5)); + setWidgetPosition(ivar4, getWidgetActualY(), 0, 0); + } + if (globalint_82 <= 0) { + svar0 = formatNumber(arg2, 1); + setWidgetText(new WidgetPointer(105,148), svar0); + globalint_84 = standart_config_1110; + } + if (globalint_83 <= 0) { + svar0 = formatNumber(arg3, 1); + setWidgetText(new WidgetPointer(105,153), svar0 + " gp"); + globalint_85 = standart_config_1111; + } + return; +} diff --git a/dumps/scripts/595.cs2 b/dumps/scripts/595.cs2 new file mode 100644 index 0000000..299a34d --- /dev/null +++ b/dumps/scripts/595.cs2 @@ -0,0 +1,5 @@ +void script_595() { + standart_config_1113 = 1; + script_621(); + return; +} diff --git a/dumps/scripts/596.cs2 b/dumps/scripts/596.cs2 new file mode 100644 index 0000000..19b7010 --- /dev/null +++ b/dumps/scripts/596.cs2 @@ -0,0 +1,11 @@ +void script_596() { + string svar0; + svar0 = "null"; + if (globalint_84 > 0) { + globalint_84 = subtract(globalint_84, 1); + svar0 = formatNumber(globalint_84, 1); + setWidgetText(new WidgetPointer(105,148), svar0); + script_602(); + } + return; +} diff --git a/dumps/scripts/597.cs2 b/dumps/scripts/597.cs2 new file mode 100644 index 0000000..49409c5 --- /dev/null +++ b/dumps/scripts/597.cs2 @@ -0,0 +1,11 @@ +void script_597() { + string svar0; + svar0 = "null"; + if (globalint_84 < 2147483647) { + globalint_84 = add(globalint_84, 1); + svar0 = formatNumber(globalint_84, 1); + setWidgetText(new WidgetPointer(105,148), svar0); + script_602(); + } + return; +} diff --git a/dumps/scripts/598.cs2 b/dumps/scripts/598.cs2 new file mode 100644 index 0000000..2bfb0d3 --- /dev/null +++ b/dumps/scripts/598.cs2 @@ -0,0 +1,12 @@ +void script_598() { + if (((boolean)standart_config_1113)) { + if (globalint_84 <= 2147483646) { + globalint_84 = add(globalint_84, 1); + } + } else { + globalint_84 = 1; + } + setWidgetText(new WidgetPointer(105,148), formatNumber(globalint_84, 1)); + script_602(); + return; +} diff --git a/dumps/scripts/599.cs2 b/dumps/scripts/599.cs2 new file mode 100644 index 0000000..e9b47c2 --- /dev/null +++ b/dumps/scripts/599.cs2 @@ -0,0 +1,12 @@ +void script_599() { + if (((boolean)standart_config_1113)) { + if (globalint_84 <= 2147483637) { + globalint_84 = add(globalint_84, 10); + } + } else { + globalint_84 = 10; + } + setWidgetText(new WidgetPointer(105,148), formatNumber(globalint_84, 1)); + script_602(); + return; +} diff --git a/dumps/scripts/6.cs2 b/dumps/scripts/6.cs2 new file mode 100644 index 0000000..41b43a9 --- /dev/null +++ b/dumps/scripts/6.cs2 @@ -0,0 +1,17 @@ +void script_6(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12,int arg13,string arg14,string arg15) { + if (isMember() && ((arg0 == 12648496) || (arg0 == 28180519))) { + arg14 = "Lumbridge Home Teleport"; + } + cs2method2305(new WidgetPointer(arg0), "" + arg14); + script_21(arg0, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); + doWidgetType21Task(0, new WidgetPointer(arg0)); + setScriptCallOnMouseOver(10, new WidgetPointer(arg0), new WidgetPointer(arg1), arg4, arg14, arg15, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, "IIissoioioioi", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(11, new WidgetPointer(arg1), "I", new WidgetPointer(arg0)); + if (cs2method2800(new WidgetPointer(arg0)) != 0) { + setScriptCallOnUse(17, new WidgetPointer(arg0), "I", new WidgetPointer(arg0)); + setScriptCallOnUseWith(18, new WidgetPointer(arg0), "I", new WidgetPointer(arg0)); + } + setScriptCallOnItemContainerUpdate(16, new WidgetPointer(arg0), arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, 93, 1, "Iddi1oioioioiY", new WidgetPointer(arg0)); + setScriptCallOnSkillChange(16, new WidgetPointer(arg0), arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, 6, 1, "Iddi1oioioioiY", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/60.cs2 b/dumps/scripts/60.cs2 new file mode 100644 index 0000000..370fa75 --- /dev/null +++ b/dumps/scripts/60.cs2 @@ -0,0 +1,27 @@ +void script_60() { + int ivar0; + int ivar1; + int ivar2; + ivar0 = 3; + ivar1 = 5; + ivar2 = 0; + while (ivar0 < 255) { + while (ivar1 < 235) { + createExtraChild(new WidgetPointer(260,42), 5, ivar2); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(ivar1, ivar0, 0, 0); + if (getItemIdInSlot(514, ivar2) != -1) { + setItemOnWidgetMethod1200(getItemIdInSlot(514, ivar2), getItemAmtInSlot(514, ivar2)); + cs2method1305(getItemName(getItemIdInSlot(514, ivar2))); + setWidgetContextMenuOption(1, "Withdraw"); + setWidgetShadowColor(new Color(17, 17, 17)); + setWidgetBorderThickness(1); + } + ivar1 = add(ivar1, 40); + ivar2 = add(ivar2, 1); + } + ivar0 = add(ivar0, 44); + ivar1 = 5; + } + return; +} diff --git a/dumps/scripts/600.cs2 b/dumps/scripts/600.cs2 new file mode 100644 index 0000000..ec4879e --- /dev/null +++ b/dumps/scripts/600.cs2 @@ -0,0 +1,12 @@ +void script_600() { + if (((boolean)standart_config_1113)) { + if (globalint_84 <= 2147483547) { + globalint_84 = add(globalint_84, 100); + } + } else { + globalint_84 = 100; + } + setWidgetText(new WidgetPointer(105,148), formatNumber(globalint_84, 1)); + script_602(); + return; +} diff --git a/dumps/scripts/601.cs2 b/dumps/scripts/601.cs2 new file mode 100644 index 0000000..e5b0e39 --- /dev/null +++ b/dumps/scripts/601.cs2 @@ -0,0 +1,4 @@ +void script_601(int arg0) { + script_1593(arg0); + return; +} diff --git a/dumps/scripts/602.cs2 b/dumps/scripts/602.cs2 new file mode 100644 index 0000000..09f9cba --- /dev/null +++ b/dumps/scripts/602.cs2 @@ -0,0 +1,9 @@ +void script_602() { + if (globalint_82 <= 0) { + globalint_82 = 100; + } else { + globalint_82 = add(globalint_82, 10); + } + setScriptCallOnGameloop(603, "", new WidgetPointer(105,148)); + return; +} diff --git a/dumps/scripts/603.cs2 b/dumps/scripts/603.cs2 new file mode 100644 index 0000000..4a6ab85 --- /dev/null +++ b/dumps/scripts/603.cs2 @@ -0,0 +1,8 @@ +void script_603() { + if (globalint_82 <= 0) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(105,148)); + script_621(); + } + globalint_82 = subtract(globalint_82, 1); + return; +} diff --git a/dumps/scripts/604.cs2 b/dumps/scripts/604.cs2 new file mode 100644 index 0000000..2df6e2a --- /dev/null +++ b/dumps/scripts/604.cs2 @@ -0,0 +1,9 @@ +void script_604() { + if (standart_config_1109 == -1) { + return; + } + globalint_85 = max(subtract(globalint_85, 1), 1); + setWidgetText(new WidgetPointer(105,153), formatNumber(globalint_85, 1) + " gp"); + script_609(); + return; +} diff --git a/dumps/scripts/605.cs2 b/dumps/scripts/605.cs2 new file mode 100644 index 0000000..68e8e6b --- /dev/null +++ b/dumps/scripts/605.cs2 @@ -0,0 +1,11 @@ +void script_605() { + if (standart_config_1109 == -1) { + return; + } + if (globalint_85 < 2147483647) { + globalint_85 = add(globalint_85, 1); + setWidgetText(new WidgetPointer(105,153), formatNumber(globalint_85, 1) + " gp"); + script_609(); + } + return; +} diff --git a/dumps/scripts/606.cs2 b/dumps/scripts/606.cs2 new file mode 100644 index 0000000..4dbce53 --- /dev/null +++ b/dumps/scripts/606.cs2 @@ -0,0 +1,15 @@ +void script_606() { + int ivar0; + int ivar1; + createExtraChild(new WidgetPointer(662,74), 5, 0); + setWidgetSize(32, 36, 0, 0); + setWidgetPosition(0, 0, 0, 0); + createExtraChild(new WidgetPointer(747,17), 5, 0); + setWidgetSize(57, 34, 0, 0); + setWidgetPosition(0, 0, 0, 0); + ivar0 = 1194; + ivar1 = 1195; + script_659(43384905, ivar0, ivar1, getItemHashmapData(standart_config_448, 394), cs2method_3408(111, 111, 1283, standart_config_448), 1, -1, 0, -1, 0, -1, 0, globalstring_204, globalstring_205); + script_608(); + return; +} diff --git a/dumps/scripts/607.cs2 b/dumps/scripts/607.cs2 new file mode 100644 index 0000000..1f72407 --- /dev/null +++ b/dumps/scripts/607.cs2 @@ -0,0 +1,16 @@ +void script_607() { + int ivar0; + if (standart_config_1109 == -1) { + globalint_85 = 1; + return; + } + ivar0 = standart_config_1114; + if (ivar0 < 0) { + globalint_85 = 1; + } else { + globalint_85 = standart_config_1114; + } + setWidgetText(new WidgetPointer(105,153), formatNumber(globalint_85, 1) + " gp"); + script_609(); + return; +} diff --git a/dumps/scripts/608.cs2 b/dumps/scripts/608.cs2 new file mode 100644 index 0000000..7d8cc00 --- /dev/null +++ b/dumps/scripts/608.cs2 @@ -0,0 +1,17 @@ +void script_608() { + if (setWidgetRegister(new WidgetPointer(662,74), 0)) { + cs2method1305("" + globalstring_204); + cs2method1306("Cast"); + if (((boolean)globalint_1436)) { + setWidgetContextMenuOption(1, "Cast"); + } + } + if (setWidgetRegister(new WidgetPointer(747,17), 0)) { + cs2method1305("" + globalstring_204); + cs2method1306("Cast"); + if (((boolean)globalint_1436)) { + setWidgetContextMenuOption(1, "Cast"); + } + } + return; +} diff --git a/dumps/scripts/609.cs2 b/dumps/scripts/609.cs2 new file mode 100644 index 0000000..d7a8ead --- /dev/null +++ b/dumps/scripts/609.cs2 @@ -0,0 +1,9 @@ +void script_609() { + if (globalint_83 <= 0) { + globalint_83 = 100; + } else { + globalint_83 = add(globalint_83, 10); + } + setScriptCallOnGameloop(610, "", new WidgetPointer(105,153)); + return; +} diff --git a/dumps/scripts/61.cs2 b/dumps/scripts/61.cs2 new file mode 100644 index 0000000..2679c05 --- /dev/null +++ b/dumps/scripts/61.cs2 @@ -0,0 +1,63 @@ +void script_61() { + int ivar0; + ivar0 = 0; + while (ivar0 < 5) { + createExtraChild(new WidgetPointer(260,45), 5, ivar0); + setWidgetSize(36, 32, 0, 0); + if (((boolean)ivar0)) { + setWidgetPosition(0, 43, 0, 0); + } + if (((boolean)ivar0)) { + setWidgetPosition(50, 2, 0, 0); + } + if (ivar0 == 2) { + setWidgetPosition(50, 43, 0, 0); + } + if (ivar0 == 3) { + setWidgetPosition(50, 85, 0, 0); + } + if (ivar0 == 4) { + setWidgetPosition(50, 125, 0, 0); + } + if (getItemIdInSlot(515, ivar0) != -1) { + setItemOnWidgetMethod1200(getItemIdInSlot(515, ivar0), getItemAmtInSlot(515, ivar0)); + cs2method1305(getItemName(getItemIdInSlot(515, ivar0))); + setWidgetContextMenuOption(1, "Deposit"); + setWidgetShadowColor(new Color(17, 17, 17)); + setWidgetBorderThickness(1); + if (((boolean)ivar0)) { + setWidgetSprite(-1, new WidgetPointer(260,40)); + } + if (((boolean)ivar0)) { + setWidgetSprite(-1, new WidgetPointer(260,36)); + } + if (ivar0 == 2) { + setWidgetSprite(-1, new WidgetPointer(260,37)); + } + if (ivar0 == 3) { + setWidgetSprite(-1, new WidgetPointer(260,38)); + } + if (ivar0 == 4) { + setWidgetSprite(-1, new WidgetPointer(260,39)); + } + } else { + if (((boolean)ivar0)) { + setWidgetSprite(159, new WidgetPointer(260,40)); + } + if (((boolean)ivar0)) { + setWidgetSprite(156, new WidgetPointer(260,36)); + } + if (ivar0 == 2) { + setWidgetSprite(161, new WidgetPointer(260,37)); + } + if (ivar0 == 3) { + setWidgetSprite(163, new WidgetPointer(260,38)); + } + if (ivar0 == 4) { + setWidgetSprite(165, new WidgetPointer(260,39)); + } + } + ivar0 = add(ivar0, 1); + } + return; +} diff --git a/dumps/scripts/610.cs2 b/dumps/scripts/610.cs2 new file mode 100644 index 0000000..faba8a2 --- /dev/null +++ b/dumps/scripts/610.cs2 @@ -0,0 +1,8 @@ +void script_610() { + if (globalint_83 <= 0) { + setScriptCallOnGameloop(-1, "", new WidgetPointer(105,153)); + script_621(); + } + globalint_83 = subtract(globalint_83, 1); + return; +} diff --git a/dumps/scripts/611.cs2 b/dumps/scripts/611.cs2 new file mode 100644 index 0000000..e9f1ab5 --- /dev/null +++ b/dumps/scripts/611.cs2 @@ -0,0 +1,4 @@ +void script_611(int arg0) { + setWidgetSprite(1160, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/612.cs2 b/dumps/scripts/612.cs2 new file mode 100644 index 0000000..38875cc --- /dev/null +++ b/dumps/scripts/612.cs2 @@ -0,0 +1,5 @@ +void script_612(int arg0) { + setWidgetSprite(1153, new WidgetPointer(arg0)); + script_41(6881490); + return; +} diff --git a/dumps/scripts/613.cs2 b/dumps/scripts/613.cs2 new file mode 100644 index 0000000..907d71c --- /dev/null +++ b/dumps/scripts/613.cs2 @@ -0,0 +1,4 @@ +void script_613(int arg0) { + setWidgetSprite(1159, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/614.cs2 b/dumps/scripts/614.cs2 new file mode 100644 index 0000000..c368bc0 --- /dev/null +++ b/dumps/scripts/614.cs2 @@ -0,0 +1,5 @@ +void script_614(int arg0) { + setWidgetSprite(1152, new WidgetPointer(arg0)); + script_41(6881490); + return; +} diff --git a/dumps/scripts/615.cs2 b/dumps/scripts/615.cs2 new file mode 100644 index 0000000..b842503 --- /dev/null +++ b/dumps/scripts/615.cs2 @@ -0,0 +1,4 @@ +void script_615(int arg0) { + setWidgetSprite(1149, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/616.cs2 b/dumps/scripts/616.cs2 new file mode 100644 index 0000000..33c5052 --- /dev/null +++ b/dumps/scripts/616.cs2 @@ -0,0 +1,5 @@ +void script_616(int arg0) { + setWidgetSprite(1147, new WidgetPointer(arg0)); + script_41(6881490); + return; +} diff --git a/dumps/scripts/617.cs2 b/dumps/scripts/617.cs2 new file mode 100644 index 0000000..6ee7982 --- /dev/null +++ b/dumps/scripts/617.cs2 @@ -0,0 +1,4 @@ +void script_617(int arg0) { + setWidgetSprite(1166, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/618.cs2 b/dumps/scripts/618.cs2 new file mode 100644 index 0000000..5728ab5 --- /dev/null +++ b/dumps/scripts/618.cs2 @@ -0,0 +1,5 @@ +void script_618(int arg0) { + setWidgetSprite(1165, new WidgetPointer(arg0)); + script_41(6881490); + return; +} diff --git a/dumps/scripts/619.cs2 b/dumps/scripts/619.cs2 new file mode 100644 index 0000000..e623c7b --- /dev/null +++ b/dumps/scripts/619.cs2 @@ -0,0 +1,4 @@ +void script_619(int arg0) { + cs2method2103(255, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/62.cs2 b/dumps/scripts/62.cs2 new file mode 100644 index 0000000..ae957e3 --- /dev/null +++ b/dumps/scripts/62.cs2 @@ -0,0 +1,32 @@ +void script_62(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + ivar4 = divide(add(arg1, arg2), 2); + ivar5 = globalarray_0[ivar4]; + globalarray_0[ivar4] = globalarray_0[arg2]; + globalarray_0[arg2] = ivar5; + ivar6 = arg1; + ivar7 = arg1; + ivar8 = -1; + while (ivar7 < arg2) { + if (stringMethod4107(lower(cs2method_3408(73, 115, arg3, globalarray_0[ivar7])), lower(cs2method_3408(73, 115, arg3, ivar5))) < bitAnd(ivar7, 1)) { + ivar8 = globalarray_0[ivar7]; + globalarray_0[ivar7] = globalarray_0[ivar6]; + globalarray_0[ivar6] = ivar8; + ivar6 = add(ivar6, 1); + } + ivar7 = add(ivar7, 1); + } + globalarray_0[arg2] = globalarray_0[ivar6]; + globalarray_0[ivar6] = ivar5; + if (arg1 < subtract(ivar6, 1)) { + script_62(0, arg1, subtract(ivar6, 1), arg3); + } + if (add(ivar6, 1) < arg2) { + script_62(0, add(ivar6, 1), arg2, arg3); + } + return; +} diff --git a/dumps/scripts/620.cs2 b/dumps/scripts/620.cs2 new file mode 100644 index 0000000..29d7de1 --- /dev/null +++ b/dumps/scripts/620.cs2 @@ -0,0 +1,4 @@ +void script_620(int arg0) { + cs2method2103(128, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/621.cs2 b/dumps/scripts/621.cs2 new file mode 100644 index 0000000..648f03d --- /dev/null +++ b/dumps/scripts/621.cs2 @@ -0,0 +1,78 @@ +void script_621() { + int ivar0; + string svar0; + flow_0: + ivar0 = 0; + svar0 = "null"; + script_622(); + IF ((standart_config_1112 == -1) || (getGENotStarted(standart_config_1112) && (standart_config_1113 == -1))) + GOTO flow_2 + GOTO flow_3 + flow_2: + script_41(6881490); + setWidgetIsHidden(false, new WidgetPointer(105,17)); + script_628(); + setScriptCallOnItemContainerUpdate(-1, "", new WidgetPointer(105,197)); + globalint_83 = 0; + globalint_82 = 0; + GOTO flow_26 + flow_3: + IF (ivar0 < 6) + GOTO flow_4 + GOTO flow_5 + flow_4: + script_41(((int)script_626(ivar0))); + ivar0 = add(ivar0, 1); + GOTO flow_3 + flow_5: + if (getGENotStarted(standart_config_1112)) { + setWidgetIsHidden(false, new WidgetPointer(105,127)); + setWidgetIsHidden(false, new WidgetPointer(105,197)); + script_594(getGEIsSelling(standart_config_1112), getGEItem(standart_config_1112), getGEItemAmt(standart_config_1112), getGEItemPrice(standart_config_1112)); + script_593(standart_config_1112); + if (((boolean)getGEIsSelling(standart_config_1112))) { + svar0 = "Maximum total cost of purchase"; + } else { + svar0 = "Minimum total value of sale"; + } + setScriptCallOnMouseOver(649, new WidgetPointer(105,185), new WidgetPointer(105,210), svar0, 25, 300, "IIsii", new WidgetPointer(105,185)); + svar0 = formatNumber(multiply(getGEItemAmt(standart_config_1112), getGEItemPrice(standart_config_1112)), 1); + setWidgetText(new WidgetPointer(105,185), svar0 + " gp"); + } else { + setWidgetIsHidden(false, new WidgetPointer(105,127)); + setWidgetIsHidden(false, new WidgetPointer(105,154)); + if (((boolean)standart_config_1113)) { + setWidgetIsHidden(false, new WidgetPointer(105,188)); + if (standart_config_1109 != -1) { + setWidgetIsHidden(true, new WidgetPointer(105,191)); + setWidgetIsHidden(true, new WidgetPointer(105,192)); + } else { + setWidgetIsHidden(false, new WidgetPointer(105,191)); + setWidgetIsHidden(false, new WidgetPointer(105,192)); + } + svar0 = "Maximum total cost of purchase"; + } else { + setWidgetIsHidden(false, new WidgetPointer(105,193)); + if (standart_config_1109 != -1) { + setWidgetIsHidden(true, new WidgetPointer(105,195)); + } else { + setWidgetIsHidden(false, new WidgetPointer(105,195)); + } + svar0 = "Minimum total value of sale"; + } + setScriptCallOnMouseOver(649, new WidgetPointer(105,185), new WidgetPointer(105,210), svar0, 25, 300, "IIsii", new WidgetPointer(105,185)); + if (standart_config_1111 > 0) { + if (standart_config_1110 > divide(2147483647, standart_config_1111)) { + setWidgetText(new WidgetPointer(105,185), "Too high!"); + } else { + svar0 = formatNumber(multiply(standart_config_1110, standart_config_1111), 1); + setWidgetText(new WidgetPointer(105,185), svar0 + " gp"); + } + } else { + setWidgetText(new WidgetPointer(105,185), "0 gp"); + } + script_594(standart_config_1113, standart_config_1109, standart_config_1110, standart_config_1111); + } + flow_26: + return; +} diff --git a/dumps/scripts/622.cs2 b/dumps/scripts/622.cs2 new file mode 100644 index 0000000..1e4b54e --- /dev/null +++ b/dumps/scripts/622.cs2 @@ -0,0 +1,18 @@ +void script_622() { + if (((boolean)standart_config_1118)) { + setWidgetIsHidden(false, new WidgetPointer(105,17)); + setWidgetIsHidden(false, new WidgetPointer(105,127)); + setWidgetIsHidden(false, new WidgetPointer(105,154)); + setWidgetIsHidden(false, new WidgetPointer(105,188)); + setWidgetIsHidden(false, new WidgetPointer(105,193)); + setWidgetIsHidden(false, new WidgetPointer(105,197)); + } else { + setWidgetIsHidden(true, new WidgetPointer(105,17)); + setWidgetIsHidden(true, new WidgetPointer(105,127)); + setWidgetIsHidden(true, new WidgetPointer(105,154)); + setWidgetIsHidden(true, new WidgetPointer(105,188)); + setWidgetIsHidden(true, new WidgetPointer(105,193)); + setWidgetIsHidden(true, new WidgetPointer(105,197)); + } + return; +} diff --git a/dumps/scripts/623.cs2 b/dumps/scripts/623.cs2 new file mode 100644 index 0000000..4f0ffdb --- /dev/null +++ b/dumps/scripts/623.cs2 @@ -0,0 +1,3 @@ +WidgetPointer script_623(int arg0) { + return cs2method_3408(105, 73, 1073, arg0); +} diff --git a/dumps/scripts/624.cs2 b/dumps/scripts/624.cs2 new file mode 100644 index 0000000..89cac1c --- /dev/null +++ b/dumps/scripts/624.cs2 @@ -0,0 +1,3 @@ +WidgetPointer script_624(int arg0) { + return cs2method_3408(105, 73, 1077, arg0); +} diff --git a/dumps/scripts/625.cs2 b/dumps/scripts/625.cs2 new file mode 100644 index 0000000..5549fba --- /dev/null +++ b/dumps/scripts/625.cs2 @@ -0,0 +1,3 @@ +WidgetPointer script_625(int arg0) { + return cs2method_3408(105, 73, 1075, arg0); +} diff --git a/dumps/scripts/626.cs2 b/dumps/scripts/626.cs2 new file mode 100644 index 0000000..0bce59c --- /dev/null +++ b/dumps/scripts/626.cs2 @@ -0,0 +1,3 @@ +WidgetPointer script_626(int arg0) { + return cs2method_3408(105, 73, 1074, arg0); +} diff --git a/dumps/scripts/627.cs2 b/dumps/scripts/627.cs2 new file mode 100644 index 0000000..6d35be7 --- /dev/null +++ b/dumps/scripts/627.cs2 @@ -0,0 +1,3 @@ +WidgetPointer script_627(int arg0) { + return cs2method_3408(105, 73, 1076, arg0); +} diff --git a/dumps/scripts/628.cs2 b/dumps/scripts/628.cs2 new file mode 100644 index 0000000..80f7456 --- /dev/null +++ b/dumps/scripts/628.cs2 @@ -0,0 +1,9 @@ +void script_628() { + int ivar0; + ivar0 = 0; + while (ivar0 < 6) { + script_651(ivar0); + ivar0 = add(ivar0, 1); + } + return; +} diff --git a/dumps/scripts/629.cs2 b/dumps/scripts/629.cs2 new file mode 100644 index 0000000..98493d0 --- /dev/null +++ b/dumps/scripts/629.cs2 @@ -0,0 +1,4 @@ +void script_629(int arg0) { + script_630(arg0); + return; +} diff --git a/dumps/scripts/63.cs2 b/dumps/scripts/63.cs2 new file mode 100644 index 0000000..2fee087 --- /dev/null +++ b/dumps/scripts/63.cs2 @@ -0,0 +1,4 @@ +void script_63(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7) { + script_31(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + return; +} diff --git a/dumps/scripts/630.cs2 b/dumps/scripts/630.cs2 new file mode 100644 index 0000000..f9c8715 --- /dev/null +++ b/dumps/scripts/630.cs2 @@ -0,0 +1,6 @@ +void script_630(int arg0) { + if (getGENotStarted(arg0) && setWidgetRegister(script_623(arg0), 0)) { + cs2method2103(230); + } + return; +} diff --git a/dumps/scripts/631.cs2 b/dumps/scripts/631.cs2 new file mode 100644 index 0000000..77b85f5 --- /dev/null +++ b/dumps/scripts/631.cs2 @@ -0,0 +1,4 @@ +void script_631(int arg0) { + script_632(arg0); + return; +} diff --git a/dumps/scripts/632.cs2 b/dumps/scripts/632.cs2 new file mode 100644 index 0000000..780c935 --- /dev/null +++ b/dumps/scripts/632.cs2 @@ -0,0 +1,6 @@ +void script_632(int arg0) { + if (getGENotStarted(arg0) && setWidgetRegister(script_623(arg0), 0)) { + cs2method2103(255); + } + return; +} diff --git a/dumps/scripts/633.cs2 b/dumps/scripts/633.cs2 new file mode 100644 index 0000000..e031d1c --- /dev/null +++ b/dumps/scripts/633.cs2 @@ -0,0 +1,9 @@ +void script_633(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + ivar4 = add(getWidgetShadeColor(new WidgetPointer(arg0)), arg3); + cs2method2103(ivar4, new WidgetPointer(arg0)); + if (ivar4 >= arg2) { + setScriptCallOnGameloop(634, new WidgetPointer(arg0), arg1, arg2, arg3, "Iiii", new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/634.cs2 b/dumps/scripts/634.cs2 new file mode 100644 index 0000000..fd128a8 --- /dev/null +++ b/dumps/scripts/634.cs2 @@ -0,0 +1,9 @@ +void script_634(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + ivar4 = subtract(getWidgetShadeColor(new WidgetPointer(arg0)), arg3); + cs2method2103(ivar4, new WidgetPointer(arg0)); + if (ivar4 <= arg1) { + setScriptCallOnGameloop(633, new WidgetPointer(arg0), arg1, arg2, arg3, "Iiii", new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/635.cs2 b/dumps/scripts/635.cs2 new file mode 100644 index 0000000..39c1974 --- /dev/null +++ b/dumps/scripts/635.cs2 @@ -0,0 +1,4 @@ +void script_635(int arg0) { + script_636(arg0); + return; +} diff --git a/dumps/scripts/636.cs2 b/dumps/scripts/636.cs2 new file mode 100644 index 0000000..77b1c50 --- /dev/null +++ b/dumps/scripts/636.cs2 @@ -0,0 +1,4 @@ +void script_636(int arg0) { + setWidgetSprite(1171, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/637.cs2 b/dumps/scripts/637.cs2 new file mode 100644 index 0000000..35cdf02 --- /dev/null +++ b/dumps/scripts/637.cs2 @@ -0,0 +1,4 @@ +void script_637(int arg0) { + script_638(arg0); + return; +} diff --git a/dumps/scripts/638.cs2 b/dumps/scripts/638.cs2 new file mode 100644 index 0000000..8315a08 --- /dev/null +++ b/dumps/scripts/638.cs2 @@ -0,0 +1,10 @@ +void script_638(int arg0) { + int ivar1; + setWidgetSprite(1170, new WidgetPointer(arg0)); + ivar1 = 0; + while (ivar1 < 6) { + script_41(((int)script_626(ivar1))); + ivar1 = add(ivar1, 1); + } + return; +} diff --git a/dumps/scripts/639.cs2 b/dumps/scripts/639.cs2 new file mode 100644 index 0000000..3b7e639 --- /dev/null +++ b/dumps/scripts/639.cs2 @@ -0,0 +1,4 @@ +void script_639(int arg0) { + script_640(arg0); + return; +} diff --git a/dumps/scripts/64.cs2 b/dumps/scripts/64.cs2 new file mode 100644 index 0000000..f59bad2 --- /dev/null +++ b/dumps/scripts/64.cs2 @@ -0,0 +1,7 @@ +void script_64() { + setWidgetText(new WidgetPointer(532,1), intToStr(bitconfig_3637) + "/" + intToStr(183)); + if (bitconfig_3637 == 183) { + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(532,1)); + } + return; +} diff --git a/dumps/scripts/640.cs2 b/dumps/scripts/640.cs2 new file mode 100644 index 0000000..9c0213a --- /dev/null +++ b/dumps/scripts/640.cs2 @@ -0,0 +1,4 @@ +void script_640(int arg0) { + setWidgetSprite(1169, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/641.cs2 b/dumps/scripts/641.cs2 new file mode 100644 index 0000000..fd39fd8 --- /dev/null +++ b/dumps/scripts/641.cs2 @@ -0,0 +1,4 @@ +void script_641(int arg0) { + script_642(arg0); + return; +} diff --git a/dumps/scripts/642.cs2 b/dumps/scripts/642.cs2 new file mode 100644 index 0000000..95c9f58 --- /dev/null +++ b/dumps/scripts/642.cs2 @@ -0,0 +1,10 @@ +void script_642(int arg0) { + int ivar1; + setWidgetSprite(1168, new WidgetPointer(arg0)); + ivar1 = 0; + while (ivar1 < 6) { + script_41(((int)script_626(ivar1))); + ivar1 = add(ivar1, 1); + } + return; +} diff --git a/dumps/scripts/643.cs2 b/dumps/scripts/643.cs2 new file mode 100644 index 0000000..9474866 --- /dev/null +++ b/dumps/scripts/643.cs2 @@ -0,0 +1,4 @@ +void script_643(int arg0) { + script_644(arg0); + return; +} diff --git a/dumps/scripts/644.cs2 b/dumps/scripts/644.cs2 new file mode 100644 index 0000000..dc4cfac --- /dev/null +++ b/dumps/scripts/644.cs2 @@ -0,0 +1,4 @@ +void script_644(int arg0) { + setWidgetSprite(1749, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/645.cs2 b/dumps/scripts/645.cs2 new file mode 100644 index 0000000..ecdfccf --- /dev/null +++ b/dumps/scripts/645.cs2 @@ -0,0 +1,4 @@ +void script_645(int arg0) { + script_646(arg0); + return; +} diff --git a/dumps/scripts/646.cs2 b/dumps/scripts/646.cs2 new file mode 100644 index 0000000..ccb029b --- /dev/null +++ b/dumps/scripts/646.cs2 @@ -0,0 +1,5 @@ +void script_646(int arg0) { + setWidgetSprite(1146, new WidgetPointer(arg0)); + script_41(6881490); + return; +} diff --git a/dumps/scripts/647.cs2 b/dumps/scripts/647.cs2 new file mode 100644 index 0000000..2e27e0a --- /dev/null +++ b/dumps/scripts/647.cs2 @@ -0,0 +1,15 @@ +void script_647(int arg0,int arg1,int arg2,int arg3,string arg4) { + int ivar4; + ivar4 = 0; + if (((boolean)globalint_2) && (ivar4 < 6)) { + while (true) { + script_41(((int)script_626(ivar4))); + ivar4 = add(ivar4, 1); + } + } + if (isWidgetHidden(new WidgetPointer(105,17))) { + return; + } + script_39(arg0, arg1, arg2, arg3, arg4); + return; +} diff --git a/dumps/scripts/648.cs2 b/dumps/scripts/648.cs2 new file mode 100644 index 0000000..652ba83 --- /dev/null +++ b/dumps/scripts/648.cs2 @@ -0,0 +1,15 @@ +void script_648(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5) { + int ivar5; + ivar5 = 0; + if (((boolean)globalint_2) && (ivar5 < 6)) { + while (true) { + script_41(((int)script_626(ivar5))); + ivar5 = add(ivar5, 1); + } + } + if (isWidgetHidden(new WidgetPointer(105,17))) { + return; + } + script_569(arg0, arg1, arg2, arg3, arg4, arg5); + return; +} diff --git a/dumps/scripts/649.cs2 b/dumps/scripts/649.cs2 new file mode 100644 index 0000000..c34bab7 --- /dev/null +++ b/dumps/scripts/649.cs2 @@ -0,0 +1,7 @@ +void script_649(int arg0,int arg1,int arg2,int arg3,string arg4) { + if (isWidgetHidden(new WidgetPointer(105,17))) { + return; + } + script_39(arg0, arg1, arg2, arg3, arg4); + return; +} diff --git a/dumps/scripts/65.cs2 b/dumps/scripts/65.cs2 new file mode 100644 index 0000000..d77bf7e --- /dev/null +++ b/dumps/scripts/65.cs2 @@ -0,0 +1,4 @@ +void script_65(int arg0,int arg1,int arg2,int arg3) { + setScriptCallOnGameloop(66, arg0, arg1, arg2, new WidgetPointer(arg3), "iiiI", new WidgetPointer(arg3)); + return; +} diff --git a/dumps/scripts/650.cs2 b/dumps/scripts/650.cs2 new file mode 100644 index 0000000..bbc1252 --- /dev/null +++ b/dumps/scripts/650.cs2 @@ -0,0 +1,7 @@ +void script_650(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5) { + if (isWidgetHidden(new WidgetPointer(105,17))) { + return; + } + script_569(arg0, arg1, arg2, arg3, arg4, arg5); + return; +} diff --git a/dumps/scripts/651.cs2 b/dumps/scripts/651.cs2 new file mode 100644 index 0000000..b069241 --- /dev/null +++ b/dumps/scripts/651.cs2 @@ -0,0 +1,151 @@ +void script_651(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + string svar0; + string svar1; + string svar2; + string svar3; + ivar1 = ((int)script_623(arg0)); + deleteAllExtraChilds(new WidgetPointer(ivar1)); + ivar2 = getWidgetActualWidth(new WidgetPointer(ivar1)); + ivar3 = getWidgetActualHeight(new WidgetPointer(ivar1)); + ivar4 = getGEIsSelling(arg0); + ivar5 = getGEItemAmt(arg0); + ivar6 = getGEItemAmtTransfered(arg0); + ivar7 = getGEItem(arg0); + ivar8 = getGEItemPrice(arg0); + svar0 = ""; + if (getGENotStarted(arg0)) { + svar0 = "Empty"; + } else if (((boolean)getGEIsSelling(arg0))) { + svar0 = "Buy"; + } else { + svar0 = "Sell"; + } + createExtraChild(new WidgetPointer(ivar1), 3, 0); + setWidgetSize(ivar2, ivar3, 0, 0); + setWidgetPosition(0, 0, 0, 0); + setWidgetFilled(1); + setWidgetRGB(new Color(255, 255, 255)); + cs2method2103(255); + script_584(ivar1, svar0); + ivar9 = getExtraChildGap(new WidgetPointer(ivar1)); + setScriptCallOnMouseEntered(629, arg0, "i", new WidgetPointer(ivar1)); + setScriptCallOnMouseExit(631, arg0, "i", new WidgetPointer(ivar1)); + if (getGENotStarted(arg0)) { + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(ivar1)); + setWidgetContextMenuOption(1, new WidgetPointer(ivar1), ""); + setWidgetContextMenuOption(2, new WidgetPointer(ivar1), ""); + if (arg0 >= 2) { + if (isSiteSettingsMembers()) { + setWidgetIsHidden(true, script_624(arg0)); + } else { + setWidgetIsHidden(false, script_624(arg0)); + } + } + } else if (getGEIsDone(arg0)) { + setWidgetContextMenuOption(2, new WidgetPointer(ivar1), "Abort Offer"); + } else { + setWidgetContextMenuOption(2, new WidgetPointer(ivar1), ""); + } + setWidgetContextMenuOption(1, new WidgetPointer(ivar1), "View Offer"); + svar1 = formatNumber(ivar5, 1); + svar2 = formatNumber(ivar8, 1); + ivar10 = 0; + ivar11 = 0; + ivar12 = ((int)script_627(arg0)); + setWidgetIsHidden(true, new WidgetPointer(ivar12)); + ivar13 = ((int)script_626(arg0)); + ivar14 = ((int)script_625(arg0)); + svar3 = ""; + ivar15 = 0; + ivar16 = 0; + if (getGENotStarted(arg0)) { + if ((arg0 < 2) || isSiteSettingsMembers()) { + setWidgetIsHidden(false, new WidgetPointer(ivar12)); + } + } else { + ivar10 = 7; + ivar11 = subtract(ivar3, 30); + if (getGEIsStatus1(arg0)) { + ivar9 = getExtraChildGap(new WidgetPointer(ivar1)); + createExtraChild(new WidgetPointer(ivar1), 4, ivar9); + setWidgetPosition(ivar10, ivar11, 0, 0); + setWidgetSize(subtract(ivar2, 14), 15, 0, 0); + setWidgetFont(494); + setWidgetRGB(new Color(219, 216, 132)); + setWidgetText("Submitting..."); + setWidgetTextAlignment(1, 1, 0); + } else { + script_652(ivar10, ivar11, subtract(ivar2, 14), 15, arg0, ivar1, ivar9, ivar13, 1); + } + ivar9 = getExtraChildGap(new WidgetPointer(ivar1)); + createExtraChild(new WidgetPointer(ivar1), 5, ivar9); + ivar9 = add(ivar9, 1); + setWidgetPosition(6, 30, 0, 0); + setWidgetSize(40, 36, 0, 0); + setWidgetSprite(1137); + createExtraChild(new WidgetPointer(ivar1), 5, ivar9); + setWidgetPosition(8, 32, 0, 0); + setWidgetSize(36, 32, 0, 0); + setItemOnWidgetMethod1200(ivar7, ivar5); + setWidgetShadowColor(new Color(0, 0, 0)); + svar0 = formatNumber(ivar5, 1); + setScriptCallOnMouseOver(648, new WidgetPointer(ivar1), ivar9, new WidgetPointer(ivar13), svar0, 25, 106, "IiIsii"); + setScriptCallOnMouseExit(40, new WidgetPointer(ivar13), "I"); + ivar9 = add(ivar9, 1); + createExtraChild(new WidgetPointer(ivar1), 4, ivar9); + setWidgetPosition(48, 30, 0, 0); + svar0 = getItemName(ivar7); + ivar16 = subtract(ivar2, 53); + ivar15 = getMaxLineWidth(ivar16, 494, svar0); + if (ivar15 > ivar16) { + ivar10 = strLength(svar0); + while ((ivar15 > ivar16) && (ivar10 > 0)) { + ivar10 = subtract(ivar10, 1); + svar0 = substr(0, ivar10, svar0) + "..."; + ivar15 = getMaxLineWidth(ivar16, 494, svar0); + } + } + ivar9 = add(ivar9, 1); + ivar3 = multiply(getLineCount(ivar16, 494, svar0), 11); + if (ivar3 < 22) { + ivar3 = 22; + } + setWidgetSize(ivar16, ivar3, 0, 0); + setWidgetRGB(new Color(204, 153, 0)); + setWidgetFont(494); + setWidgetTextAlignment(0, 0, 0); + setWidgetUnknownBoolean(true); + setWidgetText(svar0); + createExtraChild(new WidgetPointer(ivar1), 4, ivar9); + ivar9 = add(ivar9, 1); + setWidgetPosition(48, add(32, ivar3), 0, 0); + setWidgetSize(subtract(ivar2, 53), 15, 0, 0); + setWidgetRGB(new Color(189, 187, 91)); + setWidgetFont(494); + setWidgetTextAlignment(0, 0, 15); + setWidgetUnknownBoolean(true); + setWidgetText(svar2 + " gp"); + createExtraChild(new WidgetPointer(ivar1), 5, ivar9); + setWidgetPosition(4, 2, 2, 0); + setWidgetSize(20, 20, 0, 0); + setWidgetSprite(-1); + ivar9 = add(ivar9, 1); + } + return; +} diff --git a/dumps/scripts/652.cs2 b/dumps/scripts/652.cs2 new file mode 100644 index 0000000..53e718f --- /dev/null +++ b/dumps/scripts/652.cs2 @@ -0,0 +1,74 @@ +void script_652(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8) { + int ivar9; + int ivar10; + int ivar11; + int ivar12; + string svar0; + createExtraChild(new WidgetPointer(arg5), 3, arg6); + setWidgetPosition(arg0, arg1, 0, 0); + setWidgetSize(arg2, arg3, 0, 0); + setWidgetRGB(new Color(0, 0, 0)); + setWidgetFilled(0); + svar0 = "null"; + if (getGENotStarted(arg4)) { + if (getGEIsDone(arg4)) { + if (getGEItemAmtTransfered(arg4) == getGEItemAmt(arg4)) { + svar0 = "Completed"; + } else { + svar0 = "Aborted"; + } + } else { + svar0 = "In progress"; + } + if (arg7 != -1) { + if (((boolean)arg8)) { + setScriptCallOnMouseOver(648, new WidgetPointer(arg5), arg6, new WidgetPointer(arg7), svar0, 25, 106, "IiIsii"); + } else if (arg8 == 2) { + setScriptCallOnMouseOver(649, new WidgetPointer(arg5), new WidgetPointer(arg7), svar0, 25, 106, "IIsii"); + } else { + setScriptCallOnMouseOver(568, new WidgetPointer(arg5), arg6, new WidgetPointer(arg7), svar0, 25, 106, "IiIsii"); + } + setScriptCallOnMouseExit(40, new WidgetPointer(arg7), "I"); + } + } + ivar9 = add(arg0, 1); + ivar10 = add(arg1, 1); + ivar11 = subtract(arg2, 2); + ivar12 = subtract(arg3, 2); + createExtraChild(new WidgetPointer(arg5), 3, add(arg6, 1)); + setWidgetPosition(ivar9, ivar10, 0, 0); + setWidgetSize(ivar11, ivar12, 0, 0); + setWidgetRGB(new Color(48, 37, 32)); + cs2method2103(100); + setWidgetFilled(1); + createExtraChild(new WidgetPointer(arg5), 3, add(arg6, 2)); + if (getGENotStarted(arg4)) { + setWidgetPosition(add(arg0, 1), add(arg1, 1), 0, 0); + cs2method2103(0); + setWidgetFilled(1); + if (getGEIsDone(arg4)) { + setWidgetSize(ivar11, ivar12, 0, 0); + if (getGEItemAmtTransfered(arg4) == getGEItemAmt(arg4)) { + setWidgetRGB(new Color(63, 130, 30)); + } else { + setWidgetRGB(new Color(138, 0, 16)); + } + } else { + setWidgetSize(multiplyDivide(getGEItemAmtTransfered(arg4), getGEItemAmt(arg4), ivar11), ivar12, 0, 0); + setWidgetRGB(new Color(198, 139, 1)); + } + } + createExtraChild(new WidgetPointer(arg5), 3, add(arg6, 3)); + setWidgetPosition(ivar9, ivar10, 0, 0); + setWidgetSize(ivar11, 3, 0, 0); + setWidgetFilled(1); + cs2method2103(200); + setWidgetRGB(new Color(0, 0, 0)); + createExtraChild(new WidgetPointer(arg5), 3, add(arg6, 4)); + setWidgetPosition(ivar9, add(ivar10, 3), 0, 0); + setWidgetSize(3, subtract(ivar12, 3), 0, 0); + setWidgetFilled(1); + cs2method2103(200); + setWidgetRGB(new Color(0, 0, 0)); + return; +} diff --git a/dumps/scripts/653.cs2 b/dumps/scripts/653.cs2 new file mode 100644 index 0000000..f9092e4 --- /dev/null +++ b/dumps/scripts/653.cs2 @@ -0,0 +1,5 @@ +void script_653(int arg0) { + script_680(arg0); + script_41(6881490); + return; +} diff --git a/dumps/scripts/654.cs2 b/dumps/scripts/654.cs2 new file mode 100644 index 0000000..70875cb --- /dev/null +++ b/dumps/scripts/654.cs2 @@ -0,0 +1,7 @@ +void script_654() { + setScriptCallOnItemContainerUpdate(4113, 523, 524, 525, 526, 527, 528, 540, 7, "Y", new WidgetPointer(109,16)); + setScriptCallOnGrandExchangeUpdate(4113, "", new WidgetPointer(109,16)); + setScriptCallOnConfigChange(4113, 1267, 1269, 2, "Y", new WidgetPointer(109,16)); + script_4114(); + return; +} diff --git a/dumps/scripts/655.cs2 b/dumps/scripts/655.cs2 new file mode 100644 index 0000000..77fb135 --- /dev/null +++ b/dumps/scripts/655.cs2 @@ -0,0 +1,4 @@ +void script_655() { + script_656(); + return; +} diff --git a/dumps/scripts/656.cs2 b/dumps/scripts/656.cs2 new file mode 100644 index 0000000..c0d2a91 --- /dev/null +++ b/dumps/scripts/656.cs2 @@ -0,0 +1,9 @@ +void script_656() { + if (setWidgetRegister(new WidgetPointer(662,74), 0)) { + deleteExtraChild(); + } + if (setWidgetRegister(new WidgetPointer(747,17), 0)) { + deleteExtraChild(); + } + return; +} diff --git a/dumps/scripts/657.cs2 b/dumps/scripts/657.cs2 new file mode 100644 index 0000000..007142e --- /dev/null +++ b/dumps/scripts/657.cs2 @@ -0,0 +1,9 @@ +void script_657(int arg0) { + if (setWidgetRegister(new WidgetPointer(arg0), 0)) { + setWidgetBorderThickness(2); + if (bitAnd(getWidgetAMaskBit11to17(), 32) != 0) { + script_71(4); + } + } + return; +} diff --git a/dumps/scripts/658.cs2 b/dumps/scripts/658.cs2 new file mode 100644 index 0000000..cc91c5e --- /dev/null +++ b/dumps/scripts/658.cs2 @@ -0,0 +1,6 @@ +void script_658(int arg0) { + if (setWidgetRegister(new WidgetPointer(arg0), 0)) { + setWidgetBorderThickness(0); + } + return; +} diff --git a/dumps/scripts/659.cs2 b/dumps/scripts/659.cs2 new file mode 100644 index 0000000..2194479 --- /dev/null +++ b/dumps/scripts/659.cs2 @@ -0,0 +1,15 @@ +void script_659(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,string arg12,string arg13) { + if (setWidgetRegister(new WidgetPointer(662,74), 0)) { + setScriptCallOnUse(657, new WidgetPointer(-32768,3), "I"); + setScriptCallOnUseWith(658, new WidgetPointer(-32768,3), "I"); + setScriptCallOnItemContainerUpdate(660, new WidgetPointer(662,74), new WidgetPointer(arg0), arg1, arg2, arg3, arg12, arg13, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, 93, 1, "IIddissoioioioiY"); + setScriptCallOnSkillChange(660, new WidgetPointer(662,74), new WidgetPointer(arg0), arg1, arg2, arg3, arg12, arg13, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, 23, 1, "IIddissoioioioiY"); + setScriptCallOnConfigChange(660, new WidgetPointer(662,74), new WidgetPointer(arg0), arg1, arg2, arg3, arg12, arg13, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, 1175, 448, 2, "IIddissoioioioiY"); + script_661(43384906, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); + } + if (setWidgetRegister(new WidgetPointer(747,17), 0)) { + setScriptCallOnUse(697, new WidgetPointer(747,6), "I"); + setScriptCallOnUseWith(698, new WidgetPointer(747,6), "I"); + } + return; +} diff --git a/dumps/scripts/66.cs2 b/dumps/scripts/66.cs2 new file mode 100644 index 0000000..cd84ad6 --- /dev/null +++ b/dumps/scripts/66.cs2 @@ -0,0 +1,4 @@ +void script_66(int arg0,int arg1,int arg2,int arg3) { + setWidget3DRotation(0, 0, bitAnd(add(getWidgetRotateX(new WidgetPointer(arg3)), arg0), 2047), bitAnd(add(getWidgetRotateY(new WidgetPointer(arg3)), arg1), 2047), bitAnd(add(cs2method2607(new WidgetPointer(arg3)), arg2), 2047), getWidget3DDistance(new WidgetPointer(arg3)), new WidgetPointer(arg3)); + return; +} diff --git a/dumps/scripts/660.cs2 b/dumps/scripts/660.cs2 new file mode 100644 index 0000000..f9d3551 --- /dev/null +++ b/dumps/scripts/660.cs2 @@ -0,0 +1,4 @@ +void script_660(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12,string arg13,string arg14) { + script_661(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + return; +} diff --git a/dumps/scripts/661.cs2 b/dumps/scripts/661.cs2 new file mode 100644 index 0000000..4c6891c --- /dev/null +++ b/dumps/scripts/661.cs2 @@ -0,0 +1,59 @@ +void script_661(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12,string arg13,string arg14) { + cs2func_script_3357_struct(2,1,0) structdump_0; + cs2func_script_3358_struct(2,1,0) structdump_1; + cs2func_script_3359_struct(2,1,0) structdump_2; + cs2func_script_3360_struct(2,1,0) structdump_3; + cs2func_script_3361_struct(2,1,0) structdump_4; + cs2func_script_3362_struct(2,1,0) structdump_5; + cs2func_script_775_struct(2,1,0) structdump_6; + if (setWidgetRegister(new WidgetPointer(arg0), 0)) { + switch (arg5) { + case 18027: + structdump_0 = script_3357(); + arg5 = structdump_0.intpart_1; + arg13 = structdump_0.stringpart_0; + arg4 = structdump_0.intpart_0; + break; + case 18037: + structdump_1 = script_3358(); + arg5 = structdump_1.intpart_1; + arg13 = structdump_1.stringpart_0; + arg4 = structdump_1.intpart_0; + break; + case 18047: + structdump_2 = script_3359(); + arg5 = structdump_2.intpart_1; + arg13 = structdump_2.stringpart_0; + arg4 = structdump_2.intpart_0; + break; + case 18057: + structdump_3 = script_3360(); + arg5 = structdump_3.intpart_1; + arg13 = structdump_3.stringpart_0; + arg4 = structdump_3.intpart_0; + break; + case 18067: + structdump_4 = script_3361(); + arg5 = structdump_4.intpart_1; + arg13 = structdump_4.stringpart_0; + arg4 = structdump_4.intpart_0; + break; + case 18077: + structdump_5 = script_3362(); + arg5 = structdump_5.intpart_1; + arg13 = structdump_5.stringpart_0; + arg4 = structdump_5.intpart_0; + break; + case 12461: + structdump_6 = script_775(); + arg5 = structdump_6.intpart_1; + arg13 = structdump_6.stringpart_0; + arg4 = structdump_6.intpart_0; + } + arg13 = concat(arg13, " (" + intToStr(bitconfig_4288) + " Special Move points)"); + script_664(43384906, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); + setScriptCallOnMouseOver(10, new WidgetPointer(-32768,3), new WidgetPointer(662,73), arg4, arg13, arg14, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, "IIissoioioioi"); + setScriptCallOnMouseExit(778, new WidgetPointer(662,73), "I"); + } + return; +} diff --git a/dumps/scripts/662.cs2 b/dumps/scripts/662.cs2 new file mode 100644 index 0000000..c56411e --- /dev/null +++ b/dumps/scripts/662.cs2 @@ -0,0 +1,139 @@ +void script_662(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + string svar0; + flow_0: + ivar1 = ((int)cs2method_3408(105, 73, 1080, arg0)); + ivar2 = ((int)cs2method_3408(105, 73, 1081, arg0)); + ivar3 = cs2method_3408(105, 118, 1079, arg0); + deleteAllExtraChilds(new WidgetPointer(ivar1)); + ivar4 = getWidgetActualWidth(new WidgetPointer(ivar1)); + ivar5 = getWidgetActualHeight(new WidgetPointer(ivar1)); + ivar6 = subtract(divide(ivar4, 2), 40); + ivar7 = subtract(ivar5, 47); + ivar8 = getItemIdInSlot(ivar3, 0); + ivar9 = getItemIdInSlot(ivar3, 1); + ivar10 = ((int)cs2method_3408(105, 73, 1082, arg0)); + if (ivar10 != -1) { + if (isSiteSettingsMembers() || getGENotStarted(arg0)) { + setWidgetIsHidden(true, new WidgetPointer(ivar10)); + } else { + setWidgetIsHidden(false, new WidgetPointer(ivar10)); + } + } + script_98(ivar1, 0, 1138, subtract(ivar6, 2), subtract(ivar7, 2), 40, 36); + ivar11 = 1140; + IF (ivar10 == -1) + GOTO flow_5 + IF (isWidgetHidden(new WidgetPointer(ivar10)) && setWidgetRegister(new WidgetPointer(ivar1), 0)) + GOTO flow_6 + GOTO flow_14 + flow_5: + flow_6: + setScriptCallOnMouseEntered(688, new WidgetPointer(-32768,3), -2147483643, ivar11, "Iid"); + ivar11 = 1138; + setScriptCallOnMouseExit(688, new WidgetPointer(-32768,3), -2147483643, ivar11, "Iid"); + if (ivar8 != -1) { + if (getNotedItem(ivar8) != ivar8) { + if (getItemAmtInSlot(ivar3, 0) > 1) { + setWidgetContextMenuOption(1, "Collect-notes"); + setWidgetContextMenuOption(2, "Collect-items"); + } else { + setWidgetContextMenuOption(1, "Collect-items"); + setWidgetContextMenuOption(2, "Collect-notes"); + } + } else { + setWidgetContextMenuOption(1, "Collect"); + } + cs2method1305(getItemName(ivar8)); + } + flow_14: + createExtraChild(new WidgetPointer(ivar1), 5, 1); + setWidgetPosition(ivar6, ivar7, 0, 0); + setWidgetSize(36, 32, 0, 0); + setWidgetShadowColor(new Color(51, 51, 51)); + setItemOnWidgetMethod1200(ivar8, getItemAmtInSlot(ivar3, 0)); + ivar6 = add(divide(ivar4, 2), 4); + script_98(ivar1, 2, 1138, subtract(ivar6, 2), subtract(ivar7, 2), 40, 36); + IF (ivar10 == -1) + GOTO flow_15 + IF (isWidgetHidden(new WidgetPointer(ivar10)) && setWidgetRegister(new WidgetPointer(ivar1), 2)) + GOTO flow_16 + GOTO flow_24 + flow_15: + flow_16: + ivar11 = 1140; + setScriptCallOnMouseEntered(688, new WidgetPointer(-32768,3), -2147483643, ivar11, "Iid"); + ivar11 = 1138; + setScriptCallOnMouseExit(688, new WidgetPointer(-32768,3), -2147483643, ivar11, "Iid"); + if (ivar9 != -1) { + if (getNotedItem(ivar9) != ivar9) { + if (getItemAmtInSlot(ivar3, 1) > 1) { + setWidgetContextMenuOption(1, "Collect-notes"); + setWidgetContextMenuOption(2, "Collect-items"); + } else { + setWidgetContextMenuOption(1, "Collect-items"); + setWidgetContextMenuOption(2, "Collect-notes"); + } + } else { + setWidgetContextMenuOption(1, "Collect"); + } + cs2method1305(getItemName(ivar9)); + } + flow_24: + createExtraChild(new WidgetPointer(ivar1), 5, 3); + setWidgetPosition(ivar6, ivar7, 0, 0); + setWidgetSize(36, 32, 0, 0); + setWidgetShadowColor(new Color(51, 51, 51)); + setItemOnWidgetMethod1200(ivar9, getItemAmtInSlot(ivar3, 1)); + script_652(11, 11, subtract(ivar4, 65), 16, arg0, ivar1, 4, ivar2, 0); + createExtraChild(new WidgetPointer(ivar1), 3, 9); + ivar6 = subtract(ivar4, 30); + setWidgetPosition(ivar6, 11, 0, 0); + setWidgetSize(18, 16, 0, 0); + setWidgetRGB(new Color(0, 0, 0)); + cs2method2103(160); + setWidgetFilled(1); + createExtraChild(new WidgetPointer(ivar1), 6, 10); + ivar12 = getGEItem(arg0); + if (getGENotStarted(arg0)) { + setWidgetPosition(ivar6, 11, 0, 0); + setWidgetSize(18, 16, 0, 0); + setItemOnWidgetMethod1200(ivar12, 0); + setScriptCallOnMouseOver(568, new WidgetPointer(ivar1), 10, new WidgetPointer(ivar2), getItemName(ivar12), 25, 106, "IiIsii"); + setScriptCallOnMouseExit(40, new WidgetPointer(ivar2), "I"); + } + createExtraChild(new WidgetPointer(ivar1), 3, 11); + ivar6 = subtract(ivar4, 50); + setWidgetPosition(ivar6, 11, 0, 0); + setWidgetSize(18, 16, 0, 0); + setWidgetRGB(new Color(0, 0, 0)); + cs2method2103(160); + setWidgetFilled(1); + createExtraChild(new WidgetPointer(ivar1), 5, 12); + svar0 = "null"; + if (getGENotStarted(arg0)) { + setWidgetPosition(ivar6, 12, 0, 0); + setWidgetSize(16, 14, 0, 0); + if (((boolean)getGEIsSelling(arg0))) { + setWidgetSprite(1157); + svar0 = "Buy"; + } else { + setWidgetSprite(1156); + svar0 = "Sell"; + } + setScriptCallOnMouseOver(568, new WidgetPointer(ivar1), 12, new WidgetPointer(ivar2), svar0, 25, 106, "IiIsii"); + setScriptCallOnMouseExit(40, new WidgetPointer(ivar2), "I"); + } + return; +} diff --git a/dumps/scripts/663.cs2 b/dumps/scripts/663.cs2 new file mode 100644 index 0000000..9e707e6 --- /dev/null +++ b/dumps/scripts/663.cs2 @@ -0,0 +1,24 @@ +void script_663(int arg0,int arg1) { + setWidgetFont(764, new WidgetPointer(arg1)); + setWidgetTextAlignment(1, 1, 0, new WidgetPointer(arg1)); + if (((boolean)bitconfig_4191)) { + setWidgetModel(30184, new WidgetPointer(arg0)); + setWidget3DRotation(0, 0, 0, 0, 0, 365, new WidgetPointer(arg0)); + setWidgetPosition(2, 84, 0, 0, new WidgetPointer(arg0)); + setWidgetSize(509, 156, 0, 0, new WidgetPointer(arg0)); + setWidgetPosition(15, 89, 0, 0, new WidgetPointer(arg1)); + setWidgetSize(487, 143, 0, 0, new WidgetPointer(arg1)); + setWidgetRGB(new Color(script_693(43, 26, 11)), new WidgetPointer(arg1)); + } else { + if (((boolean)bitconfig_4191)) { + setWidgetModel(30183, new WidgetPointer(arg0)); + setWidget3DRotation(0, 0, 0, 0, 0, 344, new WidgetPointer(arg0)); + setWidgetPosition(3, 90, 0, 0, new WidgetPointer(arg0)); + setWidgetSize(509, 156, 0, 0, new WidgetPointer(arg0)); + setWidgetPosition(4, 88, 0, 0, new WidgetPointer(arg1)); + setWidgetSize(506, 139, 0, 0, new WidgetPointer(arg1)); + setWidgetRGB(new Color(script_693(85, 85, 65)), new WidgetPointer(arg1)); + } + } + return; +} diff --git a/dumps/scripts/664.cs2 b/dumps/scripts/664.cs2 new file mode 100644 index 0000000..31ddb81 --- /dev/null +++ b/dumps/scripts/664.cs2 @@ -0,0 +1,26 @@ +void script_664(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11) { + if (isWidgetHidden(new WidgetPointer(arg0)) && setWidgetRegister(new WidgetPointer(arg0), 0)) { + if ((arg4 != -1) && (script_19(arg4, 43384906) < arg5)) { + setWidgetSprite(arg2); + return; + } + if ((arg6 != -1) && (script_19(arg6, 43384906) < arg7)) { + setWidgetSprite(arg2); + return; + } + if ((arg8 != -1) && (script_19(arg8, 43384906) < arg9)) { + setWidgetSprite(arg2); + return; + } + if ((arg10 != -1) && (script_19(arg10, 43384906) < arg11)) { + setWidgetSprite(arg2); + return; + } + if (getSkillActualLvl(23) < arg3) { + setWidgetSprite(arg2); + } else { + setWidgetSprite(arg1); + } + } + return; +} diff --git a/dumps/scripts/665.cs2 b/dumps/scripts/665.cs2 new file mode 100644 index 0000000..9e033d2 --- /dev/null +++ b/dumps/scripts/665.cs2 @@ -0,0 +1,11 @@ +void script_665(int arg0,int arg1,int arg2,int arg3) { + createExtraChild(new WidgetPointer(arg2), 3, arg3); + cs2method2103(255); + setWidgetFilled(1); + setWidgetRGB(new Color(arg0)); + setWidgetSize(0, 0, 1, 1); + setWidgetPosition(0, 0, 1, 1); + arg1 = min(arg1, 250); + setScriptCallOnGameloop(666, add(getClientCycle(), arg1), new WidgetPointer(arg2), arg3, "iIi"); + return; +} diff --git a/dumps/scripts/666.cs2 b/dumps/scripts/666.cs2 new file mode 100644 index 0000000..994b5c8 --- /dev/null +++ b/dumps/scripts/666.cs2 @@ -0,0 +1,14 @@ +void script_666(int arg0,int arg1,int arg2) { + int ivar3; + ivar3 = 0; + if (setWidgetRegister(new WidgetPointer(arg1), arg2)) { + ivar3 = subtract(arg0, getClientCycle()); + if (ivar3 <= 0) { + cs2method2103(0); + setScriptCallOnGameloop(-1, ""); + return; + } + cs2method2103(max(subtract(cs2method1609(), divide(cs2method1609(), ivar3)), 1)); + } + return; +} diff --git a/dumps/scripts/667.cs2 b/dumps/scripts/667.cs2 new file mode 100644 index 0000000..71b531d --- /dev/null +++ b/dumps/scripts/667.cs2 @@ -0,0 +1,10 @@ +void script_667(int arg0,int arg1,int arg2) { + if (setWidgetRegister(new WidgetPointer(arg1), arg2)) { + setWidgetFilled(1); + setWidgetSize(0, 0, 1, 1); + setWidgetPosition(0, 0, 1, 1); + cs2method2103(0); + setScriptCallOnGameloop(668, add(getClientCycle(), arg0), new WidgetPointer(arg1), arg2, "iIi"); + } + return; +} diff --git a/dumps/scripts/668.cs2 b/dumps/scripts/668.cs2 new file mode 100644 index 0000000..b73887b --- /dev/null +++ b/dumps/scripts/668.cs2 @@ -0,0 +1,17 @@ +void script_668(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + ivar3 = 0; + ivar4 = 0; + if (setWidgetRegister(new WidgetPointer(arg1), arg2)) { + ivar3 = subtract(arg0, getClientCycle()); + if (ivar3 <= 0) { + setScriptCallOnGameloop(-1, ""); + deleteExtraChild(); + return; + } + ivar4 = subtract(255, cs2method1609()); + cs2method2103(min(add(cs2method1609(), divide(ivar4, ivar3)), 254)); + } + return; +} diff --git a/dumps/scripts/669.cs2 b/dumps/scripts/669.cs2 new file mode 100644 index 0000000..6c0883e --- /dev/null +++ b/dumps/scripts/669.cs2 @@ -0,0 +1,19 @@ +int script_669(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + ivar3 = 0; + ivar4 = 0; + if (((boolean)arg1)) { + return 0; + } + if (((boolean)arg0) || ((boolean)arg2)) { + return 0; + } + if (divide(arg0, arg1) >= divide(2147483647, arg2)) { + return 2147483647; + } + if (mod(multiply(mod(arg0, arg1), mod(arg2, arg1)), arg1) > divide(arg1, 2)) { + return add(multiplyDivide(arg0, arg1, arg2), 1); + } + return multiplyDivide(arg0, arg1, arg2); +} diff --git a/dumps/scripts/67.cs2 b/dumps/scripts/67.cs2 new file mode 100644 index 0000000..1d9c72f --- /dev/null +++ b/dumps/scripts/67.cs2 @@ -0,0 +1,4 @@ +void script_67(int arg0,int arg1) { + setWidgetModel(arg1, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/670.cs2 b/dumps/scripts/670.cs2 new file mode 100644 index 0000000..8ad9099 --- /dev/null +++ b/dumps/scripts/670.cs2 @@ -0,0 +1,9 @@ +void script_670() { + int ivar0; + ivar0 = 0; + while (ivar0 < 6) { + script_673(ivar0, 0, 0, 0, 0, -1, 0, 1, 0, -1); + ivar0 = add(ivar0, 1); + } + return; +} diff --git a/dumps/scripts/671.cs2 b/dumps/scripts/671.cs2 new file mode 100644 index 0000000..f3e1d69 --- /dev/null +++ b/dumps/scripts/671.cs2 @@ -0,0 +1,10 @@ +void script_671() { + int ivar0; + script_673(0, 0, 0, 0, 0, -1, 0, 1, 0, 0); + ivar0 = 1; + while (ivar0 < 6) { + script_673(ivar0, 0, 0, 0, 0, -1, 0, 1, 0, -1); + ivar0 = add(ivar0, 1); + } + return; +} diff --git a/dumps/scripts/672.cs2 b/dumps/scripts/672.cs2 new file mode 100644 index 0000000..3c932a6 --- /dev/null +++ b/dumps/scripts/672.cs2 @@ -0,0 +1,10 @@ +void script_672() { + int ivar0; + script_673(0, 0, 2, 0, 0, 1381, 1281, 0, 0, -1); + ivar0 = 1; + while (ivar0 < 6) { + script_673(ivar0, 0, 0, 0, 0, -1, 0, 1, 0, -1); + ivar0 = add(ivar0, 1); + } + return; +} diff --git a/dumps/scripts/673.cs2 b/dumps/scripts/673.cs2 new file mode 100644 index 0000000..fdb438b --- /dev/null +++ b/dumps/scripts/673.cs2 @@ -0,0 +1,97 @@ +void script_673(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9) { + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + string svar0; + string svar1; + string svar2; + string svar3; + ivar10 = ((int)cs2method_3408(105, 73, 1083, arg0)); + deleteAllExtraChilds(new WidgetPointer(ivar10)); + ivar11 = getWidgetActualWidth(new WidgetPointer(ivar10)); + ivar12 = getWidgetActualHeight(new WidgetPointer(ivar10)); + svar0 = ""; + if (((boolean)arg7)) { + svar0 = "Empty"; + } else if (((boolean)arg1)) { + svar0 = "Buy"; + } else { + svar0 = "Sell"; + } + createExtraChild(new WidgetPointer(ivar10), 3, 0); + setWidgetSize(ivar11, ivar12, 0, 0); + setWidgetPosition(0, 0, 0, 0); + setWidgetFilled(1); + setWidgetRGB(new Color(255, 255, 255)); + cs2method2103(255); + script_584(ivar10, svar0); + ivar13 = getExtraChildGap(new WidgetPointer(ivar10)); + if (((boolean)arg7)) { + if ((arg0 < 2) || isSiteSettingsMembers()) { + if ((arg9 == arg0) && setWidgetRegister(new WidgetPointer(ivar10), 0)) { + cs2method2103(230); + } + } else { + setWidgetIsHidden(false, cs2method_3408(105, 73, 1085, arg0)); + } + } + svar1 = script_46(arg2, ","); + svar2 = script_46(arg6, ","); + ivar14 = 0; + ivar15 = 0; + ivar16 = ((int)cs2method_3408(105, 73, 1084, arg0)); + setWidgetIsHidden(true, new WidgetPointer(ivar16)); + svar3 = ""; + if (((boolean)arg7)) { + if ((arg0 < 2) || isSiteSettingsMembers()) { + if (arg0 == arg9) { + setWidgetIsHidden(false, new WidgetPointer(ivar16)); + } else { + createExtraChild(new WidgetPointer(ivar10), 5, ivar13); + setWidgetSprite(1155); + setWidgetSize(16, 14, 0, 0); + setWidgetPosition(5, 29, 0, 0); + ivar13 = add(ivar13, 1); + } + } + } else { + ivar14 = 7; + ivar15 = subtract(ivar12, 30); + script_674(ivar14, ivar15, subtract(ivar11, 14), 15, arg0, ivar10, ivar13, 1, arg7, arg8, arg2, arg3); + ivar13 = getExtraChildGap(new WidgetPointer(ivar10)); + createExtraChild(new WidgetPointer(ivar10), 5, ivar13); + ivar13 = add(ivar13, 1); + setWidgetPosition(6, 30, 0, 0); + setWidgetSize(40, 36, 0, 0); + setWidgetSprite(1137); + createExtraChild(new WidgetPointer(ivar10), 5, ivar13); + setWidgetPosition(8, 32, 0, 0); + setWidgetSize(36, 32, 0, 0); + setItemOnWidgetMethod1200(arg5, arg2); + setWidgetShadowColor(new Color(0, 0, 0)); + ivar13 = add(ivar13, 1); + createExtraChild(new WidgetPointer(ivar10), 4, ivar13); + ivar13 = add(ivar13, 1); + setWidgetPosition(48, 30, 0, 0); + setWidgetSize(subtract(ivar11, 53), 22, 0, 0); + setWidgetRGB(new Color(204, 153, 0)); + setWidgetFont(494); + setWidgetTextAlignment(0, 0, 0); + setWidgetUnknownBoolean(true); + setWidgetText(getItemName(arg5)); + createExtraChild(new WidgetPointer(ivar10), 4, ivar13); + ivar13 = add(ivar13, 1); + setWidgetPosition(48, 54, 0, 0); + setWidgetSize(subtract(ivar11, 53), 15, 0, 0); + setWidgetRGB(new Color(189, 187, 91)); + setWidgetFont(494); + setWidgetTextAlignment(0, 0, 15); + setWidgetUnknownBoolean(true); + setWidgetText(svar2 + " gp"); + } + return; +} diff --git a/dumps/scripts/674.cs2 b/dumps/scripts/674.cs2 new file mode 100644 index 0000000..613fd43 --- /dev/null +++ b/dumps/scripts/674.cs2 @@ -0,0 +1,51 @@ +void script_674(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11) { + int ivar12; + int ivar13; + int ivar14; + int ivar15; + createExtraChild(new WidgetPointer(arg5), 3, arg6); + setWidgetPosition(arg0, arg1, 0, 0); + setWidgetSize(arg2, arg3, 0, 0); + setWidgetRGB(new Color(0, 0, 0)); + setWidgetFilled(0); + ivar12 = add(arg0, 1); + ivar13 = add(arg1, 1); + ivar14 = subtract(arg2, 2); + ivar15 = subtract(arg3, 2); + createExtraChild(new WidgetPointer(arg5), 3, add(arg6, 1)); + setWidgetPosition(ivar12, ivar13, 0, 0); + setWidgetSize(ivar14, ivar15, 0, 0); + setWidgetRGB(new Color(48, 37, 32)); + cs2method2103(100); + setWidgetFilled(1); + createExtraChild(new WidgetPointer(arg5), 3, add(arg6, 2)); + if (((boolean)arg8)) { + setWidgetPosition(add(arg0, 1), add(arg1, 1), 0, 0); + cs2method2103(0); + setWidgetFilled(1); + if (((boolean)arg9)) { + setWidgetSize(ivar14, ivar15, 0, 0); + if (arg11 == arg10) { + setWidgetRGB(new Color(63, 130, 30)); + } else { + setWidgetRGB(new Color(138, 0, 16)); + } + } else { + setWidgetSize(multiplyDivide(arg11, arg10, ivar14), ivar15, 0, 0); + setWidgetRGB(new Color(198, 139, 1)); + } + } + createExtraChild(new WidgetPointer(arg5), 3, add(arg6, 3)); + setWidgetPosition(ivar12, ivar13, 0, 0); + setWidgetSize(ivar14, 3, 0, 0); + setWidgetFilled(1); + cs2method2103(200); + setWidgetRGB(new Color(0, 0, 0)); + createExtraChild(new WidgetPointer(arg5), 3, add(arg6, 4)); + setWidgetPosition(ivar12, add(ivar13, 3), 0, 0); + setWidgetSize(3, subtract(ivar15, 3), 0, 0); + setWidgetFilled(1); + cs2method2103(200); + setWidgetRGB(new Color(0, 0, 0)); + return; +} diff --git a/dumps/scripts/675.cs2 b/dumps/scripts/675.cs2 new file mode 100644 index 0000000..d99234d --- /dev/null +++ b/dumps/scripts/675.cs2 @@ -0,0 +1,6 @@ +void script_675() { + sendCloseWidgetPacket(); + script_1364(); + globalint_199 = -1; + return; +} diff --git a/dumps/scripts/676.cs2 b/dumps/scripts/676.cs2 new file mode 100644 index 0000000..0d3c331 --- /dev/null +++ b/dumps/scripts/676.cs2 @@ -0,0 +1,118 @@ +void script_676() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + ivar0 = 0; + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + ivar4 = 0; + ivar5 = 0; + ivar2 = divide(subtract(getWidgetActualWidth(new WidgetPointer(645,16)), multiply(36, 10)), subtract(10, 1)); + ivar3 = divide(subtract(getWidgetActualHeight(new WidgetPointer(645,16)), 128), 3); + while (((boolean)ivar4)) { + if (cs2method_3408(105, 79, 1087, add(ivar0, 1)) != 11760) { + if (cs2method_3408(105, 79, 1087, add(ivar0, 1)) == 11846) { + ivar5 = add(ivar5, 2); + } + if (cs2method_3408(105, 79, 1087, add(ivar0, 1)) == 11858) { + ivar5 = add(ivar5, 4); + } + if (cs2method_3408(105, 79, 1087, add(ivar0, 1)) == 11864) { + ivar5 = add(ivar5, 6); + } + if (cs2method_3408(105, 79, 1087, add(ivar0, 1)) == 11872) { + ivar5 = add(ivar5, 6); + } + if (cs2method_3408(105, 79, 1087, add(ivar0, 1)) == 19520) { + ivar5 = add(ivar5, 5); + } + if (cs2method_3408(105, 79, 1087, add(ivar0, 1)) == 11902) { + ivar5 = add(ivar5, 8); + } + if (cs2method_3408(105, 79, 1087, add(ivar0, 1)) == 11908) { + ivar5 = add(ivar5, 7); + } + if (cs2method_3408(105, 79, 1087, add(ivar0, 1)) == 11926) { + ivar5 = add(ivar5, 8); + } + if (cs2method_3408(105, 79, 1087, add(ivar0, 1)) == 11942) { + ivar5 = add(ivar5, 6); + } + if (cs2method_3408(105, 79, 1087, add(ivar0, 1)) == 11967) { + ivar5 = add(ivar5, 7); + } + if (cs2method_3408(105, 79, 1087, add(ivar0, 1)) == 14525) { + ivar5 = add(ivar5, 9); + } + createExtraChild(new WidgetPointer(645,16), 5, ivar0); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(multiply(add(36, ivar2), mod(ivar5, 10)), multiply(divide(ivar5, 10), add(32, ivar3)), 0, 0); + setItemOnWidgetMethod1200(cs2method_3408(105, 79, 1087, add(ivar0, 1)), -1); + cs2method1305("" + getItemName(cs2method_3408(105, 79, 1087, add(ivar0, 1)))); + setWidgetContextMenuOption(1, "Components"); + setWidgetContextMenuOption(2, "Exchange"); + setWidgetContextMenuOption(3, "Examine"); + setWidgetShadowColor(new Color(51, 51, 51)); + setWidgetBorderThickness(1); + ivar0 = add(ivar0, 1); + ivar5 = add(ivar5, 1); + } else { + ivar4 = 1; + } + } + ivar1 = ivar0; + ivar0 = 0; + ivar5 = 0; + ivar4 = 0; + while (((boolean)ivar4)) { + if (cs2method_3408(105, 79, 1087, add(ivar0, 1)) != 11760) { + if (cs2method_3408(105, 79, 1087, add(ivar0, 1)) == 11846) { + ivar5 = add(ivar5, 2); + } + if (cs2method_3408(105, 79, 1087, add(ivar0, 1)) == 11858) { + ivar5 = add(ivar5, 4); + } + if (cs2method_3408(105, 79, 1087, add(ivar0, 1)) == 11864) { + ivar5 = add(ivar5, 6); + } + if (cs2method_3408(105, 79, 1087, add(ivar0, 1)) == 11872) { + ivar5 = add(ivar5, 6); + } + if (cs2method_3408(105, 79, 1087, add(ivar0, 1)) == 19520) { + ivar5 = add(ivar5, 5); + } + if (cs2method_3408(105, 79, 1087, add(ivar0, 1)) == 11902) { + ivar5 = add(ivar5, 8); + } + if (cs2method_3408(105, 79, 1087, add(ivar0, 1)) == 11908) { + ivar5 = add(ivar5, 7); + } + if (cs2method_3408(105, 79, 1087, add(ivar0, 1)) == 11926) { + ivar5 = add(ivar5, 8); + } + if (cs2method_3408(105, 79, 1087, add(ivar0, 1)) == 11942) { + ivar5 = add(ivar5, 6); + } + if (cs2method_3408(105, 79, 1087, add(ivar0, 1)) == 11967) { + ivar5 = add(ivar5, 7); + } + if (cs2method_3408(105, 79, 1087, add(ivar0, 1)) == 14525) { + ivar5 = add(ivar5, 9); + } + createExtraChild(new WidgetPointer(645,16), 5, ivar1); + setWidgetSize(12, 6, 0, 0); + setWidgetPosition(multiply(add(36, ivar2), mod(ivar5, 10)), multiply(divide(ivar5, 10), add(32, ivar3)), 0, 0); + setWidgetSprite(1066); + } else { + ivar4 = 1; + } + ivar0 = add(ivar0, 1); + ivar5 = add(ivar5, 1); + ivar1 = add(ivar1, 1); + } + return; +} diff --git a/dumps/scripts/677.cs2 b/dumps/scripts/677.cs2 new file mode 100644 index 0000000..0594304 --- /dev/null +++ b/dumps/scripts/677.cs2 @@ -0,0 +1,11 @@ +void script_677(int arg0) { + if (arg0 <= 9) { + setWidgetScrollMax(358, 225, new WidgetPointer(156,2)); + setWidgetIsHidden(true, new WidgetPointer(156,1)); + } else { + setWidgetIsHidden(false, new WidgetPointer(156,1)); + setWidgetScrollMax(358, add(multiply(arg0, 20), 30), new WidgetPointer(156,2)); + script_72(10223617, 10223618, 0); + } + return; +} diff --git a/dumps/scripts/678.cs2 b/dumps/scripts/678.cs2 new file mode 100644 index 0000000..da91d9e --- /dev/null +++ b/dumps/scripts/678.cs2 @@ -0,0 +1,9 @@ +void script_678() { + script_31(42401811, 42401815, 792, 789, 790, 791, 773, 788); + cs2method2100(0, 0, new WidgetPointer(647,19)); + script_157(42401811, 42401815, 0, 1); + script_31(42401812, 42401816, 792, 789, 790, 791, 773, 788); + cs2method2100(0, 0, new WidgetPointer(647,20)); + script_157(42401812, 42401816, 0, 1); + return; +} diff --git a/dumps/scripts/679.cs2 b/dumps/scripts/679.cs2 new file mode 100644 index 0000000..14b3a31 --- /dev/null +++ b/dumps/scripts/679.cs2 @@ -0,0 +1,24 @@ +void script_679(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + deleteAllExtraChilds(new WidgetPointer(arg0)); + ivar1 = getWidgetActualWidth(new WidgetPointer(arg0)); + ivar2 = getWidgetActualHeight(new WidgetPointer(arg0)); + ivar3 = subtract(ivar1, 9); + ivar4 = subtract(ivar2, 9); + ivar5 = subtract(ivar1, 18); + ivar6 = subtract(ivar2, 18); + script_98(arg0, 0, 913, 0, 0, 9, 9); + script_98(arg0, 1, 914, ivar3, 0, 9, 9); + script_98(arg0, 2, 915, 0, ivar4, 9, 9); + script_98(arg0, 3, 916, ivar3, ivar4, 9, 9); + script_98(arg0, 4, 917, 0, 9, 9, ivar6); + script_98(arg0, 5, 918, 9, 0, ivar5, 9); + script_98(arg0, 6, 919, ivar3, 9, 9, ivar6); + script_98(arg0, 7, 920, 9, ivar4, ivar5, 9); + return; +} diff --git a/dumps/scripts/68.cs2 b/dumps/scripts/68.cs2 new file mode 100644 index 0000000..cff7ccb --- /dev/null +++ b/dumps/scripts/68.cs2 @@ -0,0 +1,4 @@ +void script_68(int arg0,string arg1) { + setWidgetText(new WidgetPointer(arg0), arg1); + return; +} diff --git a/dumps/scripts/680.cs2 b/dumps/scripts/680.cs2 new file mode 100644 index 0000000..13351ee --- /dev/null +++ b/dumps/scripts/680.cs2 @@ -0,0 +1,25 @@ +void script_680(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + deleteAllExtraChilds(new WidgetPointer(arg0)); + ivar1 = getWidgetActualWidth(new WidgetPointer(arg0)); + ivar2 = getWidgetActualHeight(new WidgetPointer(arg0)); + ivar3 = subtract(ivar1, 9); + ivar4 = subtract(ivar2, 9); + ivar5 = subtract(ivar1, 18); + ivar6 = subtract(ivar2, 18); + script_98(arg0, 0, 297, 0, 0, ivar1, ivar2); + script_98(arg0, 1, 913, 0, 0, 9, 9); + script_98(arg0, 2, 914, ivar3, 0, 9, 9); + script_98(arg0, 3, 915, 0, ivar4, 9, 9); + script_98(arg0, 4, 916, ivar3, ivar4, 9, 9); + script_98(arg0, 5, 917, 0, 9, 9, ivar6); + script_98(arg0, 6, 918, 9, 0, ivar5, 9); + script_98(arg0, 7, 919, ivar3, 9, 9, ivar6); + script_98(arg0, 8, 920, 9, ivar4, ivar5, 9); + return; +} diff --git a/dumps/scripts/681.cs2 b/dumps/scripts/681.cs2 new file mode 100644 index 0000000..2b822fc --- /dev/null +++ b/dumps/scripts/681.cs2 @@ -0,0 +1,30 @@ +void script_681(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + int ivar6; + int ivar7; + int ivar8; + int ivar9; + deleteAllExtraChilds(new WidgetPointer(arg0)); + cs2method2100(0, 0, new WidgetPointer(arg0)); + deleteAllExtraChilds(new WidgetPointer(arg1)); + deleteAllExtraChilds(new WidgetPointer(arg2)); + setWidgetText(new WidgetPointer(arg4), "Gravestones"); + setWidgetText(new WidgetPointer(arg5), "Please make your selection from the list."); + setWidgetText(new WidgetPointer(arg3), ""); + script_682(arg0, 0, 0, arg2, arg3, arg4, arg5); + ivar6 = 1; + ivar7 = 0; + while (ivar7 <= 26) { + if (isBitFlagged(bitconfig_4191, ivar7)) { + script_682(arg0, add(ivar7, 1), ivar6, arg2, arg3, arg4, arg5); + ivar6 = add(ivar6, 1); + } + ivar7 = add(ivar7, 1); + } + ivar8 = divide(subtract(getWidgetActualWidth(new WidgetPointer(arg0)), 164), 2); + ivar9 = add(ivar8, multiply(add(146, ivar8), ivar6)); + if (ivar9 > getWidgetActualHeight(new WidgetPointer(arg0))) { + setWidgetScrollMax(0, ivar9, new WidgetPointer(arg0)); + script_31(arg1, arg0, 792, 789, 790, 791, 773, 788); + } + return; +} diff --git a/dumps/scripts/682.cs2 b/dumps/scripts/682.cs2 new file mode 100644 index 0000000..3fde8de --- /dev/null +++ b/dumps/scripts/682.cs2 @@ -0,0 +1,46 @@ +void script_682(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6) { + int ivar7; + int ivar8; + ivar7 = divide(subtract(getWidgetActualWidth(new WidgetPointer(arg0)), 164), 2); + ivar8 = add(ivar7, multiply(add(146, ivar7), arg2)); + createExtraChild(new WidgetPointer(arg0), 3, multiply(arg2, 6)); + setWidgetSize(164, 146, 0, 0); + setWidgetPosition(ivar7, ivar8, 0, 0); + if (bitconfig_4190 == arg1) { + setWidgetRGB(new Color(127, 0, 0)); + } else { + setWidgetRGB(new Color(0, 0, 0)); + } + cs2method2103(200); + setWidgetFilled(1); + setWidgetContextMenuOption(1, "Choose"); + cs2method1305("" + cs2method_3408(105, 115, 1099, arg1) + ""); + setScriptCallOnClickContextMenu(687, arg1, new WidgetPointer(arg0), -2147483643, new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), new WidgetPointer(arg6), "iIiIIII"); + createExtraChild(new WidgetPointer(arg0), 6, add(multiply(arg2, 6), 1)); + setWidgetSize(164, 146, 0, 0); + setWidgetPosition(ivar7, ivar8, 0, 0); + script_683(arg1); + createExtraChild(new WidgetPointer(arg0), 5, add(multiply(arg2, 6), 2)); + setWidgetSize(165, 32, 0, 0); + cs2method1107(1); + setWidgetSprite(1074); + setWidgetPosition(ivar7, subtract(ivar8, 17), 0, 0); + createExtraChild(new WidgetPointer(arg0), 5, add(multiply(arg2, 6), 3)); + setWidgetSize(165, 32, 0, 0); + cs2method1107(1); + setWidgetVFlip(1); + setWidgetSprite(1074); + setWidgetPosition(ivar7, add(ivar8, 130), 0, 0); + createExtraChild(new WidgetPointer(arg0), 5, add(multiply(arg2, 6), 4)); + setWidgetSize(32, 144, 0, 0); + cs2method1107(1); + setWidgetSprite(1075); + setWidgetPosition(subtract(ivar7, 14), add(ivar8, 1), 0, 0); + createExtraChild(new WidgetPointer(arg0), 5, add(multiply(arg2, 6), 5)); + setWidgetSize(32, 144, 0, 0); + cs2method1107(1); + setWidgetHFlip(1); + setWidgetSprite(1075); + setWidgetPosition(add(ivar7, 147), add(ivar8, 1), 0, 0); + return; +} diff --git a/dumps/scripts/683.cs2 b/dumps/scripts/683.cs2 new file mode 100644 index 0000000..a9353e0 --- /dev/null +++ b/dumps/scripts/683.cs2 @@ -0,0 +1,90 @@ +void script_683(int arg0) { + setWidgetNpcHead(cs2method_3408(105, 110, 1098, arg0)); + if (((boolean)arg0)) { + script_684(0, 63); + setWidget3DRotation(0, 0, 0, 0, 0, 528); + setScriptCallOnGameloop(685, new WidgetPointer(-32768,3), -2147483643, 0, 0, 256, 2, "Iiiiii"); + return; + } + if (((boolean)arg0)) { + script_684(-31, 58); + setWidget3DRotation(0, 0, 0, 0, 0, 400); + setScriptCallOnGameloop(685, new WidgetPointer(-32768,3), -2147483643, 0, 0, 256, 3, "Iiiiii"); + setWidgetAnimation(7375); + return; + } + if (arg0 == 2) { + script_684(0, 58); + setWidget3DRotation(0, 0, 0, 0, 0, 528); + setScriptCallOnGameloop(685, new WidgetPointer(-32768,3), -2147483643, 0, 0, 256, 2, "Iiiiii"); + return; + } + if (arg0 == 3) { + script_684(0, 48); + setWidget3DRotation(0, 0, 52, 0, 0, 650); + setScriptCallOnGameloop(685, new WidgetPointer(-32768,3), -2147483643, 0, 0, 256, 2, "Iiiiii"); + return; + } + if (arg0 == 4) { + script_684(0, 62); + setWidget3DRotation(0, 0, 35, 0, 0, 528); + setScriptCallOnGameloop(685, new WidgetPointer(-32768,3), -2147483643, 0, 0, 256, 2, "Iiiiii"); + return; + } + if (arg0 == 5) { + script_684(-3, 60); + setWidget3DRotation(0, 0, 35, 0, 0, 656); + setScriptCallOnGameloop(685, new WidgetPointer(-32768,3), -2147483643, 0, 0, 512, 3, "Iiiiii"); + return; + } + if (arg0 == 6) { + script_684(0, 68); + setWidget3DRotation(0, 0, 35, 0, 0, 720); + setScriptCallOnGameloop(685, new WidgetPointer(-32768,3), -2147483643, 0, 0, 256, 2, "Iiiiii"); + return; + } + if (arg0 == 7) { + script_684(0, 61); + setWidget3DRotation(0, 0, 35, 0, 0, 584); + setScriptCallOnGameloop(685, new WidgetPointer(-32768,3), -2147483643, 0, 0, 256, 2, "Iiiiii"); + return; + } + if (arg0 == 8) { + script_684(0, 67); + setWidget3DRotation(0, 0, 35, 0, 0, 840); + setScriptCallOnGameloop(685, new WidgetPointer(-32768,3), -2147483643, 0, 0, 256, 2, "Iiiiii"); + return; + } + if (arg0 == 9) { + script_684(0, 65); + setWidget3DRotation(0, 0, 35, 0, 0, 614); + setScriptCallOnGameloop(685, new WidgetPointer(-32768,3), -2147483643, 0, 0, 256, 2, "Iiiiii"); + return; + } + if (arg0 == 10) { + script_684(0, 69); + setWidget3DRotation(0, 0, 35, 0, 0, 755); + setScriptCallOnGameloop(685, new WidgetPointer(-32768,3), -2147483643, 35, 0, 256, 2, "Iiiiii"); + return; + } + if (arg0 == 11) { + script_684(0, 68); + setWidget3DRotation(0, 0, 35, 0, 0, 671); + setScriptCallOnGameloop(685, new WidgetPointer(-32768,3), -2147483643, 35, 0, 256, 2, "Iiiiii"); + return; + } + if (arg0 == 12) { + script_684(0, 70); + setWidget3DRotation(0, 0, 35, 1891, 0, 1277); + setScriptCallOnGameloop(685, new WidgetPointer(-32768,3), -2147483643, 35, 0, 256, 2, "Iiiiii"); + return; + } + if (arg0 == 13) { + script_684(0, 70); + setWidget3DRotation(0, 0, 35, 1891, 0, 1277); + setScriptCallOnGameloop(685, new WidgetPointer(-32768,3), -2147483643, 35, 0, 256, 2, "Iiiiii"); + return; + } + setWidget3DRotation(0, 0, 0, 0, 0, 2000); + return; +} diff --git a/dumps/scripts/684.cs2 b/dumps/scripts/684.cs2 new file mode 100644 index 0000000..40c8d93 --- /dev/null +++ b/dumps/scripts/684.cs2 @@ -0,0 +1,4 @@ +void script_684(int arg0,int arg1) { + setWidgetPosition(add(getWidgetActualX(), arg0), add(getWidgetActualY(), arg1), 0, 0); + return; +} diff --git a/dumps/scripts/685.cs2 b/dumps/scripts/685.cs2 new file mode 100644 index 0000000..dffc644 --- /dev/null +++ b/dumps/scripts/685.cs2 @@ -0,0 +1,16 @@ +void script_685(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5) { + arg3 = mod(add(arg3, arg5), multiply(arg4, 4)); + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + if (arg3 <= arg4) { + setWidget3DRotation(0, 0, getWidgetRotateX(), mod(add(arg2, arg3), 2048), cs2method1607(), getWidget3DDistance()); + } else if (arg3 <= multiply(arg4, 2)) { + setWidget3DRotation(0, 0, getWidgetRotateX(), mod(subtract(add(arg2, arg4), subtract(arg3, arg4)), 2048), cs2method1607(), getWidget3DDistance()); + } else if (arg3 <= multiply(arg4, 3)) { + setWidget3DRotation(0, 0, getWidgetRotateX(), script_686(subtract(arg2, subtract(arg3, multiply(arg4, 2))), 2048), cs2method1607(), getWidget3DDistance()); + } else { + setWidget3DRotation(0, 0, getWidgetRotateX(), script_686(add(subtract(arg2, arg4), subtract(arg3, multiply(arg4, 3))), 2048), cs2method1607(), getWidget3DDistance()); + } + setScriptCallOnGameloop(685, new WidgetPointer(-32768,3), -2147483643, arg2, arg3, arg4, arg5, "Iiiiii"); + } + return; +} diff --git a/dumps/scripts/686.cs2 b/dumps/scripts/686.cs2 new file mode 100644 index 0000000..93be6ff --- /dev/null +++ b/dumps/scripts/686.cs2 @@ -0,0 +1,6 @@ +int script_686(int arg0,int arg1) { + while (arg0 < 0) { + arg0 = add(arg0, arg1); + } + return arg0; +} diff --git a/dumps/scripts/687.cs2 b/dumps/scripts/687.cs2 new file mode 100644 index 0000000..f3f7421 --- /dev/null +++ b/dumps/scripts/687.cs2 @@ -0,0 +1,81 @@ +void script_687(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6) { + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + string svar0; + deleteAllExtraChilds(new WidgetPointer(arg3)); + ivar7 = 0; + while (ivar7 <= 27) { + if (setWidgetRegister(new WidgetPointer(arg1), multiply(ivar7, 6))) { + cs2method2103(200); + } + ivar7 = add(ivar7, 1); + } + if (setWidgetRegister(new WidgetPointer(arg1), arg2)) { + cs2method2103(150); + } + setWidgetText(new WidgetPointer(arg5), cs2method_3408(105, 115, 1099, arg0)); + ivar8 = cs2method_3408(105, 110, 1098, arg0); + ivar9 = 0; + ivar10 = 0; + svar0 = cs2method_3408(105, 115, 1100, arg0); + if (ivar8 != -1) { + ivar7 = getNpcNodemapData(ivar8, 356); + ivar9 = divide(ivar7, 100); + ivar10 = multiplyDivide(mod(ivar7, 100), 100, 60); + if (ivar10 < 10) { + svar0 = svar0 + "
" + "
" + "Initial duration: " + intToStr(ivar9) + ":0" + intToStr(ivar10); + } else { + svar0 = svar0 + "
" + "
" + "Initial duration: " + intToStr(ivar9) + ":" + intToStr(ivar10); + } + } + setWidgetText(new WidgetPointer(arg6), svar0); + ivar7 = cs2method_3408(105, 105, 1101, arg0); + if (ivar7 < 0) { + setWidgetText(new WidgetPointer(arg4), "" + "Unavailable" + ""); + return; + } + if (((boolean)ivar7)) { + svar0 = "(No charge)"; + } else if (((boolean)ivar7)) { + if (getItemAmtInContainer(93, 995) >= 1) { + svar0 = "1 coin"; + } else { + svar0 = "" + "1 coin" + ""; + } + } else if (getItemAmtInContainer(93, 995) >= ivar7) { + svar0 = formatNumber(ivar7, 1) + " coins"; + if (getMaxLineWidth(getWidgetActualWidth(new WidgetPointer(arg4)), 496, svar0) > subtract(getWidgetActualWidth(new WidgetPointer(arg4)), 5)) { + svar0 = formatNumber(ivar7, 1) + "
" + "coins"; + } + } else { + svar0 = "" + formatNumber(ivar7, 1) + " coins" + ""; + if (getMaxLineWidth(getWidgetActualWidth(new WidgetPointer(arg4)), 496, svar0) > subtract(getWidgetActualWidth(new WidgetPointer(arg4)), 5)) { + svar0 = "" + formatNumber(ivar7, 1) + "" + "
" + "" + "coins" + ""; + } + } + setWidgetText(new WidgetPointer(arg4), concat("Confirm:" + "
", svar0)); + ivar7 = 0; + ivar11 = -1; + while (ivar7 <= 27) { + createExtraChild(new WidgetPointer(arg3), 5, ivar7); + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg3)), getWidgetActualHeight(new WidgetPointer(arg3)), 0, 0); + if (ivar7 == arg0) { + setWidgetSprite(833); + setWidgetHidden(0); + ivar11 = 834; + setScriptCallOnMouseEntered(688, new WidgetPointer(-32768,3), -2147483643, ivar11, "Iid"); + ivar11 = 833; + setScriptCallOnMouseExit(688, new WidgetPointer(-32768,3), -2147483643, ivar11, "Iid"); + setWidgetContextMenuOption(1, "Confirm:"); + cs2method1305("" + cs2method_3408(105, 115, 1099, arg0) + ""); + } else { + setWidgetHidden(1); + } + ivar7 = add(ivar7, 1); + } + return; +} diff --git a/dumps/scripts/688.cs2 b/dumps/scripts/688.cs2 new file mode 100644 index 0000000..167bff0 --- /dev/null +++ b/dumps/scripts/688.cs2 @@ -0,0 +1,6 @@ +void script_688(int arg0,int arg1,int arg2) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + setWidgetSprite(arg2); + } + return; +} diff --git a/dumps/scripts/689.cs2 b/dumps/scripts/689.cs2 new file mode 100644 index 0000000..0e074ca --- /dev/null +++ b/dumps/scripts/689.cs2 @@ -0,0 +1,24 @@ +int script_689() { + int ivar0; + ivar0 = 0; + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + ivar0 = add(ivar0, 1); + return ivar0; +} diff --git a/dumps/scripts/69.cs2 b/dumps/scripts/69.cs2 new file mode 100644 index 0000000..91929f8 --- /dev/null +++ b/dumps/scripts/69.cs2 @@ -0,0 +1,4 @@ +void script_69(int arg0,int arg1) { + setWidgetIsHidden(((boolean)arg0), new WidgetPointer(arg1)); + return; +} diff --git a/dumps/scripts/690.cs2 b/dumps/scripts/690.cs2 new file mode 100644 index 0000000..6e5ca1e --- /dev/null +++ b/dumps/scripts/690.cs2 @@ -0,0 +1,4 @@ +void script_690() { + setWidgetText(new WidgetPointer(667,25), intToStr(getPlayerWeight()) + " kg"); + return; +} diff --git a/dumps/scripts/691.cs2 b/dumps/scripts/691.cs2 new file mode 100644 index 0000000..3a45461 --- /dev/null +++ b/dumps/scripts/691.cs2 @@ -0,0 +1,5 @@ +void script_691(int arg0,int arg1,int arg2,int arg3) { + setWidgetSprite(arg2, new WidgetPointer(arg0)); + cs2method2103(arg3, new WidgetPointer(arg1)); + return; +} diff --git a/dumps/scripts/692.cs2 b/dumps/scripts/692.cs2 new file mode 100644 index 0000000..55129c8 --- /dev/null +++ b/dumps/scripts/692.cs2 @@ -0,0 +1,13 @@ +void script_692(int arg0,int arg1,int arg2) { + switch (bitconfig_5367) { + case 0: + script_1839(1, arg0, arg1, arg2); + break; + case 1: + script_1839(2, arg0, arg1, arg2); + break; + default: + script_1839(0, arg0, arg1, arg2); + } + return; +} diff --git a/dumps/scripts/693.cs2 b/dumps/scripts/693.cs2 new file mode 100644 index 0000000..3d830cb --- /dev/null +++ b/dumps/scripts/693.cs2 @@ -0,0 +1,114 @@ +int script_693(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + ivar3 = 0; + ivar4 = 0; + ivar5 = 0; + ivar6 = 0; + ivar7 = 0; + ivar8 = 0; + ivar9 = 0; + ivar10 = 0; + if (arg0 > 255) { + ivar3 = 255; + } else if (arg0 < 0) { + ivar3 = 0; + } else { + ivar3 = arg0; + } + if (arg1 > 255) { + ivar4 = 255; + } else if (arg1 < 0) { + ivar4 = 0; + } else { + ivar4 = arg1; + } + if (arg2 > 255) { + ivar5 = 255; + } else if (arg2 < 0) { + ivar5 = 0; + } else { + ivar5 = arg2; + } + if (isBitFlagged(ivar3, 0)) { + ivar6 = flagBit(ivar6, 16); + } + if (isBitFlagged(ivar3, 1)) { + ivar6 = flagBit(ivar6, 17); + } + if (isBitFlagged(ivar3, 2)) { + ivar6 = flagBit(ivar6, 18); + } + if (isBitFlagged(ivar3, 3)) { + ivar6 = flagBit(ivar6, 19); + } + if (isBitFlagged(ivar3, 4)) { + ivar6 = flagBit(ivar6, 20); + } + if (isBitFlagged(ivar3, 5)) { + ivar6 = flagBit(ivar6, 21); + } + if (isBitFlagged(ivar3, 6)) { + ivar6 = flagBit(ivar6, 22); + } + if (isBitFlagged(ivar3, 7)) { + ivar6 = flagBit(ivar6, 23); + } + if (isBitFlagged(ivar4, 0)) { + ivar7 = flagBit(ivar7, 8); + } + if (isBitFlagged(ivar4, 1)) { + ivar7 = flagBit(ivar7, 9); + } + if (isBitFlagged(ivar4, 2)) { + ivar7 = flagBit(ivar7, 10); + } + if (isBitFlagged(ivar4, 3)) { + ivar7 = flagBit(ivar7, 11); + } + if (isBitFlagged(ivar4, 4)) { + ivar7 = flagBit(ivar7, 12); + } + if (isBitFlagged(ivar4, 5)) { + ivar7 = flagBit(ivar7, 13); + } + if (isBitFlagged(ivar4, 6)) { + ivar7 = flagBit(ivar7, 14); + } + if (isBitFlagged(ivar4, 7)) { + ivar7 = flagBit(ivar7, 15); + } + if (isBitFlagged(ivar5, 0)) { + ivar8 = flagBit(ivar8, 0); + } + if (isBitFlagged(ivar5, 1)) { + ivar8 = flagBit(ivar8, 1); + } + if (isBitFlagged(ivar5, 2)) { + ivar8 = flagBit(ivar8, 2); + } + if (isBitFlagged(ivar5, 3)) { + ivar8 = flagBit(ivar8, 3); + } + if (isBitFlagged(ivar5, 4)) { + ivar8 = flagBit(ivar8, 4); + } + if (isBitFlagged(ivar5, 5)) { + ivar8 = flagBit(ivar8, 5); + } + if (isBitFlagged(ivar5, 6)) { + ivar8 = flagBit(ivar8, 6); + } + if (isBitFlagged(ivar5, 7)) { + ivar8 = flagBit(ivar8, 7); + } + ivar9 = bitOr(ivar6, ivar7); + ivar10 = bitOr(ivar9, ivar8); + return ivar10; +} diff --git a/dumps/scripts/694.cs2 b/dumps/scripts/694.cs2 new file mode 100644 index 0000000..290e6ba --- /dev/null +++ b/dumps/scripts/694.cs2 @@ -0,0 +1,36 @@ +int script_694(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int stack_dump0; + cs2func_script_2413_struct(3,0,0) structdump_1; + cs2func_script_2413_struct(3,0,0) structdump_2; + ivar2 = 0; + ivar3 = 0; + ivar4 = 0; + ivar5 = 0; + ivar6 = 0; + ivar7 = 0; + stack_dump0 = arg0; + structdump_1 = script_2413(stack_dump0); + ivar4 = structdump_1.intpart_2; + ivar3 = structdump_1.intpart_1; + ivar2 = structdump_1.intpart_0; + stack_dump0 = arg1; + structdump_2 = script_2413(stack_dump0); + ivar7 = structdump_2.intpart_2; + ivar6 = structdump_2.intpart_1; + ivar5 = structdump_2.intpart_0; + ivar2 = add(ivar2, ivar5); + ivar3 = add(ivar3, ivar6); + ivar4 = add(ivar4, ivar7); + ivar8 = max(ivar2, max(ivar3, ivar4)); + ivar5 = script_669(255, ivar8, ivar2); + ivar6 = script_669(255, ivar8, ivar3); + ivar7 = script_669(255, ivar8, ivar4); + return script_693(ivar5, ivar6, ivar7); +} diff --git a/dumps/scripts/695.cs2 b/dumps/scripts/695.cs2 new file mode 100644 index 0000000..15ff910 --- /dev/null +++ b/dumps/scripts/695.cs2 @@ -0,0 +1,5 @@ +void script_695(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,string arg6,string arg7,string arg8,string arg9,string arg10,string arg11,string arg12,string arg13,string arg14) { + script_160(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); + setScriptCallOnItemContainerUpdate(159, new WidgetPointer(arg0), arg1, arg2, arg3, arg4, new WidgetPointer(arg5), arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg1, 1, "IviiiIsssssssssY", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/696.cs2 b/dumps/scripts/696.cs2 new file mode 100644 index 0000000..7c3ec7d --- /dev/null +++ b/dumps/scripts/696.cs2 @@ -0,0 +1,6 @@ +void script_696() { + script_675(); + messageType0("Cancelled."); + playSoundEffect(1042, 1, 0); + return; +} diff --git a/dumps/scripts/697.cs2 b/dumps/scripts/697.cs2 new file mode 100644 index 0000000..786abba --- /dev/null +++ b/dumps/scripts/697.cs2 @@ -0,0 +1,9 @@ +void script_697(int arg0) { + if (setWidgetRegister(new WidgetPointer(arg0))) { + setWidgetBorderThickness(2); + } + if (setWidgetRegister(new WidgetPointer(662,74), 0) && (bitAnd(getWidgetAMaskBit11to17(), 32) != 0)) { + script_71(4); + } + return; +} diff --git a/dumps/scripts/698.cs2 b/dumps/scripts/698.cs2 new file mode 100644 index 0000000..197b18d --- /dev/null +++ b/dumps/scripts/698.cs2 @@ -0,0 +1,6 @@ +void script_698(int arg0) { + if (setWidgetRegister(new WidgetPointer(arg0))) { + setWidgetBorderThickness(0); + } + return; +} diff --git a/dumps/scripts/699.cs2 b/dumps/scripts/699.cs2 new file mode 100644 index 0000000..c2834f5 --- /dev/null +++ b/dumps/scripts/699.cs2 @@ -0,0 +1,31 @@ +void script_699(int arg0,int arg1) { + int ivar2; + int ivar3; + ivar2 = 0; + ivar3 = 0; + if (setWidgetRegister(new WidgetPointer(arg1))) { + ivar2 = getWidgetActualX(); + if (arg0 < 5) { + ivar2 = getWidgetActualX(); + if (((boolean)script_700(arg0))) { + ivar3 = -57; + } else if (((boolean)script_700(arg0))) { + ivar3 = -68; + } else { + ivar3 = -79; + } + setWidgetPosition(ivar2, ivar3, 0, 1); + } else { + ivar3 = getWidgetActualY(); + if (((boolean)script_700(arg0))) { + ivar2 = -42; + } else if (((boolean)script_700(arg0))) { + ivar2 = -53; + } else { + ivar2 = -64; + } + setWidgetPosition(ivar2, ivar3, 1, 0); + } + } + return; +} diff --git a/dumps/scripts/7.cs2 b/dumps/scripts/7.cs2 new file mode 100644 index 0000000..a757228 --- /dev/null +++ b/dumps/scripts/7.cs2 @@ -0,0 +1,18 @@ +void script_7() { + int ivar0; + int ivar1; + ivar0 = subtract(globalint_10, 100); + globalint_10 = 0; + if ((ivar0 < -1) || (ivar0 == script_1305())) { + return; + } + ivar1 = script_8(ivar0); + if (ivar1 == -1) { + return; + } + if (isWidgetOpen(new WidgetPointer(ivar1))) { + return; + } + script_71(ivar0); + return; +} diff --git a/dumps/scripts/70.cs2 b/dumps/scripts/70.cs2 new file mode 100644 index 0000000..2d85e82 --- /dev/null +++ b/dumps/scripts/70.cs2 @@ -0,0 +1,8 @@ +void script_70() { + if (standart_config_560 < 1) { + setWidgetText(new WidgetPointer(373,1), "You're the Winner!"); + } else { + setWidgetText(new WidgetPointer(373,1), "Foes Remaining: " + intToStr(standart_config_560)); + } + return; +} diff --git a/dumps/scripts/700.cs2 b/dumps/scripts/700.cs2 new file mode 100644 index 0000000..1684358 --- /dev/null +++ b/dumps/scripts/700.cs2 @@ -0,0 +1,21 @@ +int script_700(int arg0) { + switch (arg0) { + case 1: + return bitconfig_1000; + case 2: + return bitconfig_1001; + case 3: + return bitconfig_1002; + case 4: + return bitconfig_1003; + case 5: + return bitconfig_1004; + case 6: + return bitconfig_1005; + case 7: + return bitconfig_1006; + case 8: + return bitconfig_1009; + } + return 0; +} diff --git a/dumps/scripts/701.cs2 b/dumps/scripts/701.cs2 new file mode 100644 index 0000000..3f05e35 --- /dev/null +++ b/dumps/scripts/701.cs2 @@ -0,0 +1,29 @@ +void script_701() { + int ivar0; + int ivar1; + int ivar2; + ivar0 = 0; + ivar1 = 0; + ivar2 = 0; + while (ivar0 < getItemContainerLength(93)) { + createExtraChild(new WidgetPointer(478,14), 5, ivar0); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(multiply(40, ivar1), multiply(40, ivar2), 0, 0); + if (getItemIdInSlot(93, ivar0) != -1) { + setItemOnWidgetMethod1200(getItemIdInSlot(93, ivar0), getItemAmtInSlot(93, ivar0)); + cs2method1305(getItemName(getItemIdInSlot(93, ivar0))); + setWidgetContextMenuOption(1, "Deposit"); + setWidgetContextMenuOption(2, "Examine"); + setScriptCallOnMouseDragReleased(703, new WidgetPointer(-32768,3), -2147483643, new WidgetPointer(-32768,6), -2147483641, "IiIi"); + cs2method1303(5); + cs2method1304(10); + } + ivar0 = add(ivar0, 1); + ivar1 = add(ivar1, 1); + if (ivar1 == 8) { + ivar1 = 0; + ivar2 = add(ivar2, 1); + } + } + return; +} diff --git a/dumps/scripts/702.cs2 b/dumps/scripts/702.cs2 new file mode 100644 index 0000000..e90a8f4 --- /dev/null +++ b/dumps/scripts/702.cs2 @@ -0,0 +1,4 @@ +void script_702(int arg0,string arg1) { + script_5337(arg0, arg1); + return; +} diff --git a/dumps/scripts/703.cs2 b/dumps/scripts/703.cs2 new file mode 100644 index 0000000..d8f6635 --- /dev/null +++ b/dumps/scripts/703.cs2 @@ -0,0 +1,13 @@ +void script_703(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + ivar4 = 0; + ivar5 = 0; + if (setWidgetRegister(new WidgetPointer(arg0), arg1) && setWidgetRegister(new WidgetPointer(arg2), arg3)) { + ivar4 = getWidgetActualX(); + ivar5 = getWidgetActualY(); + setWidgetPosition(getWidgetActualX(), getWidgetActualY(), 0, 0); + setWidgetPosition(ivar4, ivar5, 0, 0); + } + return; +} diff --git a/dumps/scripts/704.cs2 b/dumps/scripts/704.cs2 new file mode 100644 index 0000000..c409541 --- /dev/null +++ b/dumps/scripts/704.cs2 @@ -0,0 +1,23 @@ +int script_704(int arg0) { + switch (arg0) { + case 1: + return globalint_203; + case 2: + return globalint_204; + case 3: + return globalint_205; + case 4: + return globalint_206; + case 5: + return globalint_207; + case 6: + return globalint_208; + case 7: + return globalint_209; + case 8: + return globalint_210; + case 9: + return globalint_211; + } + return 0; +} diff --git a/dumps/scripts/705.cs2 b/dumps/scripts/705.cs2 new file mode 100644 index 0000000..5193a22 --- /dev/null +++ b/dumps/scripts/705.cs2 @@ -0,0 +1,31 @@ +void script_705(int arg0,int arg1) { + switch (arg0) { + case 1: + globalint_203 = arg1; + break; + case 2: + globalint_204 = arg1; + break; + case 3: + globalint_205 = arg1; + break; + case 4: + globalint_206 = arg1; + break; + case 5: + globalint_207 = arg1; + break; + case 6: + globalint_208 = arg1; + break; + case 7: + globalint_209 = arg1; + break; + case 8: + globalint_210 = arg1; + break; + case 9: + globalint_211 = arg1; + } + return; +} diff --git a/dumps/scripts/706.cs2 b/dumps/scripts/706.cs2 new file mode 100644 index 0000000..9440b34 --- /dev/null +++ b/dumps/scripts/706.cs2 @@ -0,0 +1,26 @@ +int script_706(int arg0) { + if ((arg0 < 1) || (arg0 > 9)) { + return 0; + } + switch (arg0) { + case 1: + return subtract(subtract(subtract(subtract(subtract(subtract(subtract(subtract(516, bitconfig_4885), bitconfig_4886), bitconfig_4887), bitconfig_4888), bitconfig_4889), bitconfig_4890), bitconfig_4891), bitconfig_4892); + case 2: + return bitconfig_4885; + case 3: + return bitconfig_4886; + case 4: + return bitconfig_4887; + case 5: + return bitconfig_4888; + case 6: + return bitconfig_4889; + case 7: + return bitconfig_4890; + case 8: + return bitconfig_4891; + case 9: + return bitconfig_4892; + } + return 0; +} diff --git a/dumps/scripts/707.cs2 b/dumps/scripts/707.cs2 new file mode 100644 index 0000000..edea5af --- /dev/null +++ b/dumps/scripts/707.cs2 @@ -0,0 +1,10 @@ +void script_707() { + if (getDisplayMode() >= 2) { + setWidgetPosition(220, 11, 2, 0, new WidgetPointer(680,19)); + } else { + setWidgetPosition(12, 11, 2, 0, new WidgetPointer(680,19)); + } + globalint_215 = 255; + globalint_216 = 0; + return; +} diff --git a/dumps/scripts/708.cs2 b/dumps/scripts/708.cs2 new file mode 100644 index 0000000..bd60730 --- /dev/null +++ b/dumps/scripts/708.cs2 @@ -0,0 +1,10 @@ +void script_708(int arg0) { + if (bitconfig_5032 < 80) { + setScriptCallOnGameloop(709, new WidgetPointer(arg0), "I", new WidgetPointer(arg0)); + } else { + if (bitconfig_5331 < 35) { + setScriptCallOnGameloop(709, new WidgetPointer(arg0), "I", new WidgetPointer(arg0)); + } + } + return; +} diff --git a/dumps/scripts/709.cs2 b/dumps/scripts/709.cs2 new file mode 100644 index 0000000..ec32b1c --- /dev/null +++ b/dumps/scripts/709.cs2 @@ -0,0 +1,8 @@ +void script_709(int arg0) { + if (getDisplayMode() >= 2) { + setWidgetSize(getWidgetActualWidth(new WidgetPointer(746,9)), getWidgetActualHeight(new WidgetPointer(746,9)), 0, 0, new WidgetPointer(arg0)); + } else { + setWidgetSize(getWidgetActualWidth(new WidgetPointer(548,8)), getWidgetActualHeight(new WidgetPointer(548,8)), 0, 0, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/71.cs2 b/dumps/scripts/71.cs2 new file mode 100644 index 0000000..6d74a37 --- /dev/null +++ b/dumps/scripts/71.cs2 @@ -0,0 +1,35 @@ +void script_71(int arg0) { + int ivar1; + ivar1 = script_1305(); + if ((arg0 == -1) && ((boolean)bitconfig_9030)) { + arg0 = 1; + } + globalint_168 = arg0; + if (arg0 == -1) { + if (getDisplayMode() >= 2) { + script_1306(); + } else { + return; + } + } + if (((boolean)script_2709()) && (((arg0 == 9) || (arg0 == 11)) || (arg0 == 10))) { + return; + } + if (ivar1 > -1) { + if (ivar1 == arg0) { + if (getDisplayMode() >= 2) { + script_1306(); + script_1387(arg0); + } else { + return; + } + } else { + script_1306(); + script_1387(arg0); + } + } else { + script_1306(); + script_1387(arg0); + } + return; +} diff --git a/dumps/scripts/710.cs2 b/dumps/scripts/710.cs2 new file mode 100644 index 0000000..5266fb7 --- /dev/null +++ b/dumps/scripts/710.cs2 @@ -0,0 +1,6 @@ +void script_710() { + if (globalint_41 == 5) { + script_84(); + } + return; +} diff --git a/dumps/scripts/711.cs2 b/dumps/scripts/711.cs2 new file mode 100644 index 0000000..c69cc8a --- /dev/null +++ b/dumps/scripts/711.cs2 @@ -0,0 +1,160 @@ +void script_711() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + string svar0; + string svar1; + setScriptCallOnClickContextMenu(2023, -2147483644, 1, "ii", new WidgetPointer(916,19)); + setScriptCallOnClickContextMenu(2023, -2147483644, -1, "ii", new WidgetPointer(916,20)); + script_2020(1, 41, 60030981, "1"); + script_2020(5, 41, 60030982, "5"); + script_2020(10, 41, 60030983, "10"); + ivar0 = getWidgetActualWidth(new WidgetPointer(916,9)); + ivar1 = getWidgetActualWidth(new WidgetPointer(905,3)); + ivar2 = subtract(subtract(ivar1, ivar0), add(multiply(41, 3), multiply(5, 2))); + ivar3 = 0; + ivar4 = 0; + svar0 = "All"; + svar1 = "Custom"; + if (((boolean)script_1103())) { + ivar3 = add(max(getTextWidth(494, svar0), getTextWidth(494, svar1)), 20); + script_2020(bitconfig_8094, ivar3, 60030984, svar0); + script_2020(-1, ivar3, 59310086, svar1); + ivar2 = subtract(ivar2, add(multiply(ivar3, 2), 5)); + ivar4 = multiplyDivide(2, 5, ivar2); + setWidgetPosition(ivar4, 0, 0, 1, new WidgetPointer(916,8)); + ivar4 = add(add(ivar4, ivar3), 5); + setWidgetPosition(ivar4, 0, 0, 1, new WidgetPointer(905,6)); + ivar4 = add(ivar4, ivar3); + ivar4 = add(ivar4, divide(ivar2, 5)); + setWidgetPosition(ivar4, 0, 0, 1, new WidgetPointer(916,5)); + ivar4 = add(add(ivar4, 41), 5); + setWidgetPosition(ivar4, 0, 0, 1, new WidgetPointer(916,6)); + ivar4 = add(add(ivar4, 41), 5); + setWidgetPosition(ivar4, 0, 0, 1, new WidgetPointer(916,7)); + } else { + setWidgetIsHidden(true, new WidgetPointer(916,8)); + setWidgetIsHidden(true, new WidgetPointer(905,6)); + ivar4 = divide(ivar2, 2); + setWidgetPosition(ivar4, 0, 0, 1, new WidgetPointer(916,5)); + ivar4 = add(add(ivar4, 41), 5); + setWidgetPosition(ivar4, 0, 0, 1, new WidgetPointer(916,6)); + ivar4 = add(add(ivar4, 41), 5); + setWidgetPosition(ivar4, 0, 0, 1, new WidgetPointer(916,7)); + } + setWidgetPosition(subtract(ivar0, 5), 0, 2, 1, new WidgetPointer(916,2)); + setWidgetPosition(ivar0, 0, 2, 1, new WidgetPointer(905,5)); + ivar5 = subtract(ivar1, ivar0); + if (((boolean)globalint_92)) { + setWidgetSize(add(ivar5, 5), 0, 0, 1, new WidgetPointer(916,2)); + setWidgetSize(ivar5, 0, 0, 1, new WidgetPointer(905,5)); + script_2192(0, ivar5); + } else { + setWidgetSize(5, 0, 0, 1, new WidgetPointer(916,2)); + setWidgetSize(0, 0, 0, 1, new WidgetPointer(905,5)); + script_2192(1, ivar5); + } + setWidgetSize(add(multiply(getWidgetActualX(new WidgetPointer(916,1)), 2), ivar0), 0, 1, 1, new WidgetPointer(916,1)); + svar1 = "Show/Hide additional number buttons"; + ivar6 = 3883; + setScriptCallOnMouseOver(1160, new WidgetPointer(-32768,3), -1, new WidgetPointer(905,29), svar1, 25, 519, "IiIsii", new WidgetPointer(916,21)); + setScriptCallOnMouseExit(299, new WidgetPointer(905,29), new WidgetPointer(916,22), ivar6, "IId", new WidgetPointer(916,21)); + ivar2 = divide(subtract(70, 56), 2); + ivar3 = 0; + if (globalint_755 != -1) { + ivar3 = getMaxLineWidth(2147483647, 494, globalstring_132); + } + if (globalint_756 != -1) { + ivar3 = max(getMaxLineWidth(2147483647, 494, globalstring_133), ivar3); + } + if (globalint_757 != -1) { + ivar3 = max(getMaxLineWidth(2147483647, 494, globalstring_134), ivar3); + } + if (globalint_758 != -1) { + ivar3 = max(getMaxLineWidth(2147483647, 494, globalstring_135), ivar3); + } + if (globalint_759 != -1) { + ivar3 = max(getMaxLineWidth(2147483647, 494, globalstring_136), ivar3); + } + if (globalint_760 != -1) { + ivar3 = max(getMaxLineWidth(2147483647, 494, globalstring_137), ivar3); + } + if (globalint_1139 != -1) { + ivar3 = max(getMaxLineWidth(2147483647, 494, globalstring_280), ivar3); + } + if (globalint_1140 != -1) { + ivar3 = max(getMaxLineWidth(2147483647, 494, globalstring_281), ivar3); + } + if (globalint_1141 != -1) { + ivar3 = max(getMaxLineWidth(2147483647, 494, globalstring_282), ivar3); + } + if (globalint_1142 != -1) { + ivar3 = max(getMaxLineWidth(2147483647, 494, globalstring_283), ivar3); + } + if (globalint_120 != -1) { + ivar3 = max(getMaxLineWidth(2147483647, 494, globalstring_275), ivar3); + } + if (globalint_185 != -1) { + ivar3 = max(getMaxLineWidth(2147483647, 494, globalstring_316), ivar3); + } + if (globalint_87 != -1) { + ivar3 = max(getMaxLineWidth(2147483647, 494, globalstring_317), ivar3); + } + if (globalint_90 != -1) { + ivar3 = max(getMaxLineWidth(2147483647, 494, globalstring_318), ivar3); + } + ivar3 = add(ivar3, 4); + ivar3 = max(add(ivar3, multiply(4, 2)), 56); + ivar4 = script_1883(ivar2, ivar3, ivar2, globalint_755, 59310094, globalstring_132); + ivar4 = script_1883(ivar4, ivar3, ivar2, globalint_756, 59310095, globalstring_133); + ivar4 = script_1883(ivar4, ivar3, ivar2, globalint_757, 59310096, globalstring_134); + ivar4 = script_1883(ivar4, ivar3, ivar2, globalint_758, 59310097, globalstring_135); + ivar4 = script_1883(ivar4, ivar3, ivar2, globalint_759, 59310098, globalstring_136); + ivar4 = script_1883(ivar4, ivar3, ivar2, globalint_760, 59310099, globalstring_137); + ivar4 = script_1883(ivar4, ivar3, ivar2, globalint_1139, 59310100, globalstring_280); + ivar4 = script_1883(ivar4, ivar3, ivar2, globalint_1140, 59310101, globalstring_281); + ivar4 = script_1883(ivar4, ivar3, ivar2, globalint_1141, 59310102, globalstring_282); + ivar4 = script_1883(ivar4, ivar3, ivar2, globalint_1142, 59310103, globalstring_283); + ivar4 = script_1883(ivar4, ivar3, ivar2, globalint_120, 59310104, globalstring_275); + ivar4 = script_1883(ivar4, ivar3, ivar2, globalint_185, 59310105, globalstring_316); + ivar4 = script_1883(ivar4, ivar3, ivar2, globalint_87, 59310106, globalstring_317); + ivar4 = script_1883(ivar4, ivar3, ivar2, globalint_90, 59310107, globalstring_318); + script_2047(); + ivar3 = subtract(getWidgetActualWidth(new WidgetPointer(905,7)), 50); + ivar7 = 3877; + ivar6 = 3879; + ivar8 = 3878; + ivar9 = 3880; + if (ivar4 > ivar3) { + setWidgetSize(ivar3, 0, 0, 1, new WidgetPointer(905,13)); + setWidgetScrollMax(ivar4, 0, new WidgetPointer(905,13)); + cs2method2100(globalint_93, 0, new WidgetPointer(905,13)); + setScriptCallOnMouseOver(2369, new WidgetPointer(-32768,3), ivar8, -4, "Idi", new WidgetPointer(905,11)); + setScriptCallOnMouseOver(2369, new WidgetPointer(-32768,3), ivar9, 4, "Idi", new WidgetPointer(905,12)); + setScriptCallOnMouseDraggedOver(2369, new WidgetPointer(-32768,3), ivar8, -6, "Idi", new WidgetPointer(905,11)); + setScriptCallOnMouseDraggedOver(2369, new WidgetPointer(-32768,3), ivar9, 6, "Idi", new WidgetPointer(905,12)); + setScriptCallOnMouseExit(44, new WidgetPointer(-32768,3), ivar7, "Id", new WidgetPointer(905,11)); + setScriptCallOnMouseExit(44, new WidgetPointer(-32768,3), ivar6, "Id", new WidgetPointer(905,12)); + script_2370(); + } else { + setWidgetSize(ivar4, 0, 0, 1, new WidgetPointer(905,13)); + setWidgetScrollMax(0, 0, new WidgetPointer(905,13)); + cs2method2100(0, 0, new WidgetPointer(905,13)); + removeAllEventListeners(new WidgetPointer(905,11)); + removeAllEventListeners(new WidgetPointer(905,12)); + cs2method2103(150, new WidgetPointer(905,11)); + cs2method2103(150, new WidgetPointer(905,12)); + } + setWidgetSprite(ivar7, new WidgetPointer(905,11)); + setWidgetSprite(ivar6, new WidgetPointer(905,12)); + setScriptCallOnGlobalConfigChange(711, 754, 1, "Y", new WidgetPointer(905,2)); + setScriptCallOnConfigChange(2025, 1363, 1, "Y", new WidgetPointer(905,2)); + return; +} diff --git a/dumps/scripts/712.cs2 b/dumps/scripts/712.cs2 new file mode 100644 index 0000000..ee980d7 --- /dev/null +++ b/dumps/scripts/712.cs2 @@ -0,0 +1,4 @@ +void script_712(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6) { + script_713(arg0, arg1, arg2, arg3, arg4, arg5, arg6); + return; +} diff --git a/dumps/scripts/713.cs2 b/dumps/scripts/713.cs2 new file mode 100644 index 0000000..685bc1f --- /dev/null +++ b/dumps/scripts/713.cs2 @@ -0,0 +1,60 @@ +void script_713(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6) { + int ivar7; + ivar7 = getItemIdInSlot(541, 0); + if (ivar7 != -1) { + setItemOnWidgetMethod2205(ivar7, 1, new WidgetPointer(arg1)); + setWidgetBorderThickness(1, new WidgetPointer(arg1)); + setWidgetShadowColor(new Color(51, 51, 51), new WidgetPointer(arg1)); + setWidgetContextMenuOption(1, new WidgetPointer(arg1), "Remove"); + setWidgetContextMenuOption(10, new WidgetPointer(arg1), "Examine"); + cs2method2305(new WidgetPointer(arg1), "" + getItemName(ivar7) + ""); + if (((boolean)bitconfig_5026)) { + setWidgetText(new WidgetPointer(arg2), "" + "Until" + "" + "
" + "" + "logout" + ""); + setWidgetNoOptions(new WidgetPointer(arg2)); + setWidgetContextMenuOption(2, new WidgetPointer(arg2), "Specify"); + } else { + if (((boolean)bitconfig_5026)) { + setWidgetText(new WidgetPointer(arg2), "1 hour"); + } else { + setWidgetText(new WidgetPointer(arg2), intToStr(bitconfig_5026) + " hours"); + } + setWidgetContextMenuOption(1, new WidgetPointer(arg2), "'Until logout'"); + setWidgetContextMenuOption(2, new WidgetPointer(arg2), "Edit"); + } + cs2method2305(new WidgetPointer(arg2), "" + "Duration" + ""); + script_679(arg3); + setScriptCallOnMouseOver(94, new WidgetPointer(arg3), "I", new WidgetPointer(arg3)); + setScriptCallOnMouseExit(92, new WidgetPointer(arg3), "I", new WidgetPointer(arg3)); + } else { + setItemOnWidgetMethod2205(-1, 0, new WidgetPointer(arg1)); + setWidgetText(new WidgetPointer(arg2), ""); + setWidgetNoOptions(new WidgetPointer(arg1)); + setWidgetNoOptions(new WidgetPointer(arg2)); + cs2method2305(new WidgetPointer(arg1), ""); + cs2method2305(new WidgetPointer(arg2), ""); + deleteAllExtraChilds(new WidgetPointer(arg3)); + setScriptCallOnMouseOver(-1, "", new WidgetPointer(arg3)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg3)); + } + ivar7 = getItemIdInSlotSplit(541, 0); + if (ivar7 != -1) { + setItemOnWidgetMethod2205(ivar7, 1, new WidgetPointer(arg5)); + setWidgetBorderThickness(1, new WidgetPointer(arg5)); + setWidgetShadowColor(new Color(51, 51, 51), new WidgetPointer(arg5)); + setWidgetContextMenuOption(10, new WidgetPointer(arg5), "Examine"); + cs2method2305(new WidgetPointer(arg5), "" + getItemName(ivar7) + ""); + if (((boolean)bitconfig_5070)) { + setWidgetText(new WidgetPointer(arg6), "" + "Until" + "" + "
" + "" + "logout" + ""); + } else if (((boolean)bitconfig_5070)) { + setWidgetText(new WidgetPointer(arg6), "1 hour"); + } else { + setWidgetText(new WidgetPointer(arg6), intToStr(bitconfig_5070) + " hours"); + } + } else { + setItemOnWidgetMethod2205(-1, 0, new WidgetPointer(arg5)); + setWidgetText(new WidgetPointer(arg6), ""); + setWidgetNoOptions(new WidgetPointer(arg5)); + cs2method2305(new WidgetPointer(arg5), ""); + } + return; +} diff --git a/dumps/scripts/714.cs2 b/dumps/scripts/714.cs2 new file mode 100644 index 0000000..5050fcc --- /dev/null +++ b/dumps/scripts/714.cs2 @@ -0,0 +1,9 @@ +void script_714(int arg0) { + createExtraChild(new WidgetPointer(arg0), 5, 4); + setWidgetSprite(937); + setWidgetSize(10, 32, 0, 0); + setWidgetPosition(0, 0, 1, 1); + setWidgetHidden(0); + setScriptCallOnGameloop(144, new WidgetPointer(arg0), 4, getClientCycle(), add(getClientCycle(), 750), "Iiii"); + return; +} diff --git a/dumps/scripts/715.cs2 b/dumps/scripts/715.cs2 new file mode 100644 index 0000000..36fdc76 --- /dev/null +++ b/dumps/scripts/715.cs2 @@ -0,0 +1,46 @@ +int script_715(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int stack_dump0; + cs2func_script_2413_struct(3,0,0) structdump_1; + cs2func_script_2413_struct(3,0,0) structdump_2; + int stack_dump3; + int stack_dump4; + cs2func_script_4127_struct(3,0,0) structdump_5; + ivar4 = 0; + ivar5 = 0; + ivar6 = 0; + ivar7 = 0; + ivar8 = 0; + ivar9 = 0; + stack_dump0 = arg0; + structdump_1 = script_2413(stack_dump0); + ivar6 = structdump_1.intpart_2; + ivar5 = structdump_1.intpart_1; + ivar4 = structdump_1.intpart_0; + stack_dump0 = arg2; + structdump_2 = script_2413(stack_dump0); + ivar9 = structdump_2.intpart_2; + ivar8 = structdump_2.intpart_1; + ivar7 = structdump_2.intpart_0; + ivar4 = add(multiply(ivar4, arg1), multiply(ivar7, arg3)); + ivar5 = add(multiply(ivar5, arg1), multiply(ivar8, arg3)); + ivar6 = add(multiply(ivar6, arg1), multiply(ivar9, arg3)); + ivar10 = max(ivar4, max(ivar5, ivar6)); + ivar7 = script_669(255, ivar10, ivar4); + ivar8 = script_669(255, ivar10, ivar5); + ivar9 = script_669(255, ivar10, ivar6); + stack_dump0 = ivar7; + stack_dump3 = ivar8; + stack_dump4 = ivar9; + structdump_5 = script_4127(stack_dump0, stack_dump3, stack_dump4); + ivar6 = structdump_5.intpart_2; + ivar5 = structdump_5.intpart_1; + ivar4 = structdump_5.intpart_0; + return script_693(ivar7, ivar8, ivar9); +} diff --git a/dumps/scripts/716.cs2 b/dumps/scripts/716.cs2 new file mode 100644 index 0000000..2484a03 --- /dev/null +++ b/dumps/scripts/716.cs2 @@ -0,0 +1,15 @@ +void script_716(int arg0) { + if (arg0 == 50724876) { + setWidgetModel(41312, new WidgetPointer(774,11)); + playSoundEffect(5111, 1, 0); + } else if (arg0 == 50724877) { + setWidgetModel(41303, new WidgetPointer(774,11)); + playSoundEffect(5112, 1, 0); + } else { + if (arg0 == 50724878) { + setWidgetModel(41305, new WidgetPointer(774,11)); + playSoundEffect(5110, 1, 0); + } + } + return; +} diff --git a/dumps/scripts/717.cs2 b/dumps/scripts/717.cs2 new file mode 100644 index 0000000..0628b79 --- /dev/null +++ b/dumps/scripts/717.cs2 @@ -0,0 +1,4 @@ +void script_717() { + setWidgetModel(41313, new WidgetPointer(774,11)); + return; +} diff --git a/dumps/scripts/718.cs2 b/dumps/scripts/718.cs2 new file mode 100644 index 0000000..ae4ecdd --- /dev/null +++ b/dumps/scripts/718.cs2 @@ -0,0 +1,34 @@ +int script_718(int arg0) { + flow_0: + SWITCH (arg0) { + case 1: + GOTO flow_1 + case 2: + GOTO flow_2 + case 3: + GOTO flow_3 + case 4: + GOTO flow_4 + case 5: + GOTO flow_5 + case 6: + GOTO flow_6 + case 7: + GOTO flow_7 + } + return 16777215; + flow_1: + return 16711680; + flow_2: + return 16744448; + flow_3: + return 16776960; + flow_4: + return 65280; + flow_5: + return 255; + flow_6: + return 4194559; + flow_7: + return 8388863; +} diff --git a/dumps/scripts/719.cs2 b/dumps/scripts/719.cs2 new file mode 100644 index 0000000..0423ec7 --- /dev/null +++ b/dumps/scripts/719.cs2 @@ -0,0 +1,5 @@ +void script_719(int arg0,int arg1) { + setItemOnWidgetMethod2205(standart_config_850, 1, new WidgetPointer(arg0)); + setItemOnWidgetMethod2205(standart_config_855, 1, new WidgetPointer(arg1)); + return; +} diff --git a/dumps/scripts/72.cs2 b/dumps/scripts/72.cs2 new file mode 100644 index 0000000..9058f4d --- /dev/null +++ b/dumps/scripts/72.cs2 @@ -0,0 +1,23 @@ +void script_72(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + int ivar6; + ivar3 = getWidgetScrollMaxV(new WidgetPointer(arg1)); + ivar4 = getWidgetActualHeight(new WidgetPointer(arg0)); + ivar5 = subtract(ivar4, 32); + ivar6 = 0; + if (ivar3 > 0) { + ivar6 = divide(multiply(ivar5, ivar4), ivar3); + } else { + ivar6 = ivar5; + } + if (ivar6 < 10) { + ivar6 = 10; + } + if (setWidgetRegister(new WidgetPointer(arg0), 1)) { + setWidgetSize(16, ivar6, 0, 0); + script_37(arg0, arg1, arg2, 1); + } + return; +} diff --git a/dumps/scripts/720.cs2 b/dumps/scripts/720.cs2 new file mode 100644 index 0000000..8ca2a50 --- /dev/null +++ b/dumps/scripts/720.cs2 @@ -0,0 +1,3 @@ +void script_720() { + return; +} diff --git a/dumps/scripts/721.cs2 b/dumps/scripts/721.cs2 new file mode 100644 index 0000000..5164880 --- /dev/null +++ b/dumps/scripts/721.cs2 @@ -0,0 +1,4 @@ +void script_721() { + script_722(); + return; +} diff --git a/dumps/scripts/722.cs2 b/dumps/scripts/722.cs2 new file mode 100644 index 0000000..e8ee706 --- /dev/null +++ b/dumps/scripts/722.cs2 @@ -0,0 +1,190 @@ +void script_722() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + opcStruct6203(2,0,0) structdump_0; + ivar0 = 0; + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + ivar4 = 0; + if (getDisplayMode() >= 2) { + structdump_0 = cs2method6203(); + setWidgetSize(structdump_0.intpart_0, structdump_0.intpart_1, 0, 0, new WidgetPointer(746,9)); + script_1658(); + script_1650(); + ivar0 = getWidgetActualWidth(new WidgetPointer(746,3)); + ivar1 = getWidgetActualHeight(new WidgetPointer(746,3)); + ivar2 = divide(subtract(ivar0, 512), 2); + if (isParent(new WidgetPointer(746,12), 762)) { + if (((boolean)bitconfig_8348)) { + setWidgetSize(10, 10, 0, 0, new WidgetPointer(746,12)); + } else { + ivar4 = subtract(ivar1, 185); + ivar3 = 175; + if (ivar4 > 942) { + ivar4 = 942; + ivar3 = add(divide(subtract(subtract(ivar1, 175), ivar4), 2), 175); + } else { + if (ivar4 < 334) { + ivar4 = 334; + ivar3 = divide(subtract(ivar1, 334), 2); + } + } + setWidgetSize(512, ivar4, 0, 0, new WidgetPointer(746,12)); + script_1654(); + } + } else { + setWidgetSize(512, 334, 0, 0, new WidgetPointer(746,12)); + ivar3 = divide(subtract(ivar1, 334), 2); + } + if (ivar2 < 223) { + ivar2 = 223; + } + if (ivar3 < 165) { + ivar3 = 165; + } + setWidgetPosition(ivar2, ivar3, 2, 2, new WidgetPointer(746,12)); + if (isParent(new WidgetPointer(746,9), 667)) { + setWidgetSize(512, 334, 0, 0, new WidgetPointer(746,9)); + setWidgetPosition(ivar2, max(divide(subtract(ivar1, 334), 2), ivar3), 2, 2, new WidgetPointer(746,9)); + setWidgetSize(219, 164, 1, 1, new WidgetPointer(746,10)); + setWidgetPosition(0, 0, 0, 0, new WidgetPointer(746,10)); + } else if (isParent(new WidgetPointer(746,10), 667)) { + setWidgetSize(512, 334, 0, 0, new WidgetPointer(746,10)); + setWidgetPosition(ivar2, max(divide(subtract(ivar1, 334), 2), ivar3), 2, 2, new WidgetPointer(746,10)); + setWidgetSize(0, 0, 1, 1, new WidgetPointer(746,9)); + setWidgetPosition(0, 0, 1, 1, new WidgetPointer(746,9)); + } else { + setWidgetSize(219, 164, 1, 1, new WidgetPointer(746,10)); + setWidgetPosition(0, 0, 0, 0, new WidgetPointer(746,10)); + setWidgetSize(0, 0, 1, 1, new WidgetPointer(746,9)); + setWidgetPosition(0, 0, 1, 1, new WidgetPointer(746,9)); + } + if (ivar0 < 996) { + setWidgetPosition(0, 74, 2, 2, new WidgetPointer(746,79)); + setWidgetSize(240, 74, 0, 0, new WidgetPointer(746,20)); + setWidgetPosition(4, 42, 2, 2, new WidgetPointer(746,30)); + setWidgetPosition(34, 43, 2, 2, new WidgetPointer(746,29)); + setWidgetPosition(64, 43, 2, 2, new WidgetPointer(746,28)); + setWidgetPosition(94, 43, 2, 2, new WidgetPointer(746,27)); + setWidgetPosition(124, 43, 2, 2, new WidgetPointer(746,26)); + setWidgetPosition(154, 43, 2, 2, new WidgetPointer(746,25)); + setWidgetPosition(184, 44, 2, 2, new WidgetPointer(746,131)); + setWidgetPosition(214, 43, 2, 2, new WidgetPointer(746,24)); + setWidgetPosition(0, 37, 2, 2, new WidgetPointer(746,62)); + setWidgetPosition(30, 37, 2, 2, new WidgetPointer(746,61)); + setWidgetPosition(60, 37, 2, 2, new WidgetPointer(746,60)); + setWidgetPosition(90, 37, 2, 2, new WidgetPointer(746,59)); + setWidgetPosition(120, 37, 2, 2, new WidgetPointer(746,58)); + setWidgetPosition(150, 37, 2, 2, new WidgetPointer(746,57)); + setWidgetPosition(180, 37, 2, 2, new WidgetPointer(746,56)); + setWidgetPosition(210, 37, 2, 2, new WidgetPointer(746,55)); + setWidgetPosition(0, 37, 2, 2, new WidgetPointer(746,46)); + setWidgetPosition(30, 37, 2, 2, new WidgetPointer(746,45)); + setWidgetPosition(60, 37, 2, 2, new WidgetPointer(746,44)); + setWidgetPosition(90, 37, 2, 2, new WidgetPointer(746,43)); + setWidgetPosition(120, 37, 2, 2, new WidgetPointer(746,42)); + setWidgetPosition(150, 37, 2, 2, new WidgetPointer(746,41)); + setWidgetPosition(180, 37, 2, 2, new WidgetPointer(746,40)); + setWidgetPosition(210, 37, 2, 2, new WidgetPointer(746,39)); + setWidgetSize(249, 78, 0, 0, new WidgetPointer(746,71)); + setWidgetPosition(0, 0, 0, 0, new WidgetPointer(746,133)); + setWidgetPosition(30, 0, 0, 0, new WidgetPointer(746,135)); + setWidgetPosition(60, 0, 0, 0, new WidgetPointer(746,137)); + setWidgetPosition(90, 0, 0, 0, new WidgetPointer(746,139)); + setWidgetPosition(120, 0, 0, 0, new WidgetPointer(746,141)); + setWidgetPosition(150, 0, 0, 0, new WidgetPointer(746,143)); + setWidgetPosition(180, 0, 0, 0, new WidgetPointer(746,145)); + setWidgetPosition(210, 0, 0, 0, new WidgetPointer(746,147)); + setWidgetPosition(0, 0, 0, 0, new WidgetPointer(746,132)); + setWidgetPosition(30, 0, 0, 0, new WidgetPointer(746,134)); + setWidgetPosition(60, 0, 0, 0, new WidgetPointer(746,136)); + setWidgetPosition(90, 0, 0, 0, new WidgetPointer(746,138)); + setWidgetPosition(120, 0, 0, 0, new WidgetPointer(746,140)); + setWidgetPosition(150, 0, 0, 0, new WidgetPointer(746,142)); + setWidgetPosition(180, 0, 0, 0, new WidgetPointer(746,144)); + setWidgetPosition(210, 0, 0, 0, new WidgetPointer(746,146)); + } else { + setWidgetPosition(0, 37, 2, 2, new WidgetPointer(746,79)); + setWidgetSize(480, 37, 0, 0, new WidgetPointer(746,20)); + setWidgetPosition(244, 6, 2, 2, new WidgetPointer(746,30)); + setWidgetPosition(274, 7, 2, 2, new WidgetPointer(746,29)); + setWidgetPosition(305, 7, 2, 2, new WidgetPointer(746,28)); + setWidgetPosition(334, 6, 2, 2, new WidgetPointer(746,27)); + setWidgetPosition(364, 6, 2, 2, new WidgetPointer(746,26)); + setWidgetPosition(394, 6, 2, 2, new WidgetPointer(746,25)); + setWidgetPosition(424, 7, 2, 2, new WidgetPointer(746,131)); + setWidgetPosition(454, 6, 2, 2, new WidgetPointer(746,24)); + setWidgetPosition(240, 0, 2, 2, new WidgetPointer(746,62)); + setWidgetPosition(270, 0, 2, 2, new WidgetPointer(746,61)); + setWidgetPosition(300, 0, 2, 2, new WidgetPointer(746,60)); + setWidgetPosition(330, 0, 2, 2, new WidgetPointer(746,59)); + setWidgetPosition(360, 0, 2, 2, new WidgetPointer(746,58)); + setWidgetPosition(390, 0, 2, 2, new WidgetPointer(746,57)); + setWidgetPosition(420, 0, 2, 2, new WidgetPointer(746,56)); + setWidgetPosition(450, 0, 2, 2, new WidgetPointer(746,55)); + setWidgetPosition(240, 0, 2, 2, new WidgetPointer(746,46)); + setWidgetPosition(270, 0, 2, 2, new WidgetPointer(746,45)); + setWidgetPosition(300, 0, 2, 2, new WidgetPointer(746,44)); + setWidgetPosition(330, 0, 2, 2, new WidgetPointer(746,43)); + setWidgetPosition(360, 0, 2, 2, new WidgetPointer(746,42)); + setWidgetPosition(390, 0, 2, 2, new WidgetPointer(746,41)); + setWidgetPosition(420, 0, 2, 2, new WidgetPointer(746,40)); + setWidgetPosition(450, 0, 2, 2, new WidgetPointer(746,39)); + setWidgetSize(489, 42, 0, 0, new WidgetPointer(746,71)); + setWidgetPosition(0, 0, 0, 0, new WidgetPointer(746,133)); + setWidgetPosition(30, 0, 0, 0, new WidgetPointer(746,135)); + setWidgetPosition(60, 0, 0, 0, new WidgetPointer(746,137)); + setWidgetPosition(90, 0, 0, 0, new WidgetPointer(746,139)); + setWidgetPosition(120, 0, 0, 0, new WidgetPointer(746,141)); + setWidgetPosition(150, 0, 0, 0, new WidgetPointer(746,143)); + setWidgetPosition(180, 0, 0, 0, new WidgetPointer(746,145)); + setWidgetPosition(210, 0, 0, 0, new WidgetPointer(746,147)); + setWidgetPosition(0, 0, 0, 0, new WidgetPointer(746,132)); + setWidgetPosition(30, 0, 0, 0, new WidgetPointer(746,134)); + setWidgetPosition(60, 0, 0, 0, new WidgetPointer(746,136)); + setWidgetPosition(90, 0, 0, 0, new WidgetPointer(746,138)); + setWidgetPosition(120, 0, 0, 0, new WidgetPointer(746,140)); + setWidgetPosition(150, 0, 0, 0, new WidgetPointer(746,142)); + setWidgetPosition(180, 0, 0, 0, new WidgetPointer(746,144)); + setWidgetPosition(210, 0, 0, 0, new WidgetPointer(746,146)); + } + script_4251(); + } else if (isParent(new WidgetPointer(548,19), 762) && ((boolean)bitconfig_8348)) { + setWidgetSize(10, 10, 0, 0, new WidgetPointer(548,19)); + cs2method202(35913738); + cs2method202(35913739); + cs2method202(35913740); + cs2method202(35913743); + cs2method202(35913744); + cs2method202(35913745); + cs2method202(35913746); + cs2method202(35913748); + cs2method202(35913749); + cs2method202(35913750); + cs2method202(35913768); + cs2method202(35913736); + cs2method202(35913737); + cs2method202(35913747); + } else { + setWidgetSize(512, 334, 0, 0, new WidgetPointer(548,19)); + cs2method202(35913736); + cs2method202(35913737); + cs2method202(35913738); + cs2method202(35913739); + cs2method202(35913740); + cs2method202(35913743); + cs2method202(35913744); + cs2method202(35913745); + cs2method202(35913746); + cs2method202(35913747); + cs2method202(35913748); + cs2method202(35913749); + cs2method202(35913750); + cs2method202(35913768); + } + return; +} diff --git a/dumps/scripts/723.cs2 b/dumps/scripts/723.cs2 new file mode 100644 index 0000000..0608942 --- /dev/null +++ b/dumps/scripts/723.cs2 @@ -0,0 +1,4 @@ +void script_723() { + script_776(); + return; +} diff --git a/dumps/scripts/724.cs2 b/dumps/scripts/724.cs2 new file mode 100644 index 0000000..2927a8b --- /dev/null +++ b/dumps/scripts/724.cs2 @@ -0,0 +1,45 @@ +void script_724(int arg0,int arg1,int arg2,string arg3) { + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + if ((arg0 == 48824321) && ((boolean)globalint_616)) { + return; + } + ivar3 = 0; + ivar4 = 0; + ivar5 = 0; + ivar6 = -1; + ivar7 = -1; + ivar8 = -1; + if (globalint_1 < add(getClientCycle(), 25)) { + if (globalint_1 < getClientCycle()) { + globalint_1 = getClientCycle(); + } + globalint_1 = add(globalint_1, 2); + return; + } + globalint_1 = add(add(getClientCycle(), 25), 10); + if (globalint_2 != 1) { + ivar5 = add(getMaxLineWidth(1000, 495, arg3), 8); + if (getDisplayMode() < 2) { + ivar6 = 35913744; + ivar8 = 35913953; + ivar7 = 35913743; + } else { + ivar6 = 48889872; + ivar8 = 48890023; + ivar7 = 48889871; + } + ivar3 = subtract(add(add(getWidgetActualX(new WidgetPointer(ivar7)), getWidgetActualX(new WidgetPointer(arg0))), arg1), ivar5); + ivar4 = subtract(add(add(getWidgetActualY(new WidgetPointer(ivar7)), getWidgetActualY(new WidgetPointer(arg0))), arg2), 17); + setWidgetIsHidden(false, new WidgetPointer(ivar6)); + setWidgetSize(ivar5, 17, 0, 0, new WidgetPointer(ivar6)); + setWidgetPosition(ivar3, ivar4, 0, 0, new WidgetPointer(ivar6)); + setWidgetText(new WidgetPointer(ivar8), arg3); + globalint_2 = 1; + } + return; +} diff --git a/dumps/scripts/725.cs2 b/dumps/scripts/725.cs2 new file mode 100644 index 0000000..bdf1970 --- /dev/null +++ b/dumps/scripts/725.cs2 @@ -0,0 +1,5 @@ +void script_725(int arg0,int arg1) { + globalint_199 = -1; + setScriptCallOnGlobalConfigChange(726, new WidgetPointer(arg0), new WidgetPointer(arg1), 199, 213, 2, "IIY", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/726.cs2 b/dumps/scripts/726.cs2 new file mode 100644 index 0000000..4a54050 --- /dev/null +++ b/dumps/scripts/726.cs2 @@ -0,0 +1,36 @@ +void script_726(int arg0,int arg1) { + if (isWidgetOpen(new WidgetPointer(arg1)) || (globalint_199 == -1)) { + deleteAllExtraChilds(new WidgetPointer(arg0)); + globalint_199 = -1; + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + setScriptCallOnWidgetResize(-1, "", new WidgetPointer(arg0)); + return; + } + setScriptCallOnGameloop(727, new WidgetPointer(arg0), new WidgetPointer(arg1), "II", new WidgetPointer(arg0)); + setScriptCallOnWidgetResize(726, new WidgetPointer(arg0), new WidgetPointer(arg1), "II", new WidgetPointer(arg0)); + createExtraChild(new WidgetPointer(arg0), 3, 0); + setWidgetPosition(0, 0, 3, 3); + setWidgetSize(getWidgetActualX(new WidgetPointer(arg1)), 16384, 0, 2); + setWidgetRGB(new Color(globalint_199)); + cs2method2103(globalint_213); + setWidgetFilled(1); + createExtraChild(new WidgetPointer(arg0), 3, 1); + setWidgetPosition(0, 0, 5, 3); + setWidgetSize(subtract(getWidgetActualWidth(new WidgetPointer(arg0)), add(getWidgetActualX(new WidgetPointer(arg1)), getWidgetActualWidth(new WidgetPointer(arg1)))), 16384, 0, 2); + setWidgetRGB(new Color(globalint_199)); + cs2method2103(globalint_213); + setWidgetFilled(1); + createExtraChild(new WidgetPointer(arg0), 3, 2); + setWidgetPosition(getWidgetActualX(new WidgetPointer(arg1)), 0, 0, 3); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg1)), getWidgetActualY(new WidgetPointer(arg1)), 0, 0); + setWidgetRGB(new Color(globalint_199)); + cs2method2103(globalint_213); + setWidgetFilled(1); + createExtraChild(new WidgetPointer(arg0), 3, 3); + setWidgetPosition(getWidgetActualX(new WidgetPointer(arg1)), 0, 0, 5); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg1)), subtract(getWidgetActualHeight(new WidgetPointer(arg0)), add(getWidgetActualY(new WidgetPointer(arg1)), getWidgetActualHeight(new WidgetPointer(arg1)))), 0, 0); + setWidgetRGB(new Color(globalint_199)); + cs2method2103(globalint_213); + setWidgetFilled(1); + return; +} diff --git a/dumps/scripts/727.cs2 b/dumps/scripts/727.cs2 new file mode 100644 index 0000000..71e26e3 --- /dev/null +++ b/dumps/scripts/727.cs2 @@ -0,0 +1,10 @@ +void script_727(int arg0,int arg1) { + if (isWidgetOpen(new WidgetPointer(arg1)) && (globalint_199 != -1)) { + return; + } + deleteAllExtraChilds(new WidgetPointer(arg0)); + globalint_199 = -1; + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + setScriptCallOnWidgetResize(-1, "", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/728.cs2 b/dumps/scripts/728.cs2 new file mode 100644 index 0000000..92b9164 --- /dev/null +++ b/dumps/scripts/728.cs2 @@ -0,0 +1,16 @@ +void script_728() { + setWidgetIsHidden(true, new WidgetPointer(780,35)); + setWidgetIsHidden(true, new WidgetPointer(780,36)); + setWidgetIsHidden(true, new WidgetPointer(780,37)); + setWidgetIsHidden(true, new WidgetPointer(780,38)); + setWidgetIsHidden(true, new WidgetPointer(780,39)); + setWidgetIsHidden(true, new WidgetPointer(780,40)); + setWidgetIsHidden(true, new WidgetPointer(780,41)); + setWidgetIsHidden(true, new WidgetPointer(780,42)); + setWidgetIsHidden(true, new WidgetPointer(780,44)); + setWidgetIsHidden(true, new WidgetPointer(780,47)); + setWidgetIsHidden(true, new WidgetPointer(780,48)); + setWidgetIsHidden(true, new WidgetPointer(780,43)); + setWidgetText(new WidgetPointer(780,33), "Use a talisman to display the altar location."); + return; +} diff --git a/dumps/scripts/729.cs2 b/dumps/scripts/729.cs2 new file mode 100644 index 0000000..810e774 --- /dev/null +++ b/dumps/scripts/729.cs2 @@ -0,0 +1,173 @@ +void script_729() { + script_730(1438, 51052561, 51052560); + script_730(1448, 51052575, 51052574); + script_730(1444, 51052579, 51052578); + script_730(1440, 51052569, 51052568); + script_730(1442, 51052571, 51052570); + script_730(1446, 51052563, 51052562); + script_730(1452, 51052565, 51052564); + script_730(1458, 51052573, 51052572); + script_730(1462, 51052577, 51052576); + script_730(1454, 51052567, 51052566); + script_730(13625, 51052597, 51052596); + script_730(13624, 51052603, 51052602); + script_730(13627, 51052609, 51052608); + script_730(13628, 51052615, 51052614); + script_730(13615, 51052599, 51052598); + script_730(13614, 51052605, 51052604); + script_730(13617, 51052611, 51052610); + script_730(13618, 51052617, 51052616); + script_730(13620, 51052601, 51052600); + script_730(13619, 51052607, 51052606); + script_730(13622, 51052613, 51052612); + script_730(13623, 51052619, 51052618); + script_730(13599, 51052635, 51052634); + script_730(13602, 51052645, 51052644); + script_730(13601, 51052657, 51052656); + script_730(13603, 51052647, 51052646); + script_730(13600, 51052651, 51052650); + script_730(13604, 51052637, 51052636); + script_730(13608, 51052649, 51052648); + script_730(13606, 51052639, 51052638); + script_730(13605, 51052641, 51052640); + script_730(13607, 51052653, 51052652); + script_730(13609, 51052643, 51052642); + script_730(13610, 51052659, 51052658); + script_730(13598, 51052661, 51052660); + script_730(13611, 51052655, 51052654); + script_730(13629, 51052665, 51052664); + script_730(1437, 51052667, 51052666); + setWidgetText(new WidgetPointer(779,123), "1 token each"); + script_730(21517, 51052714, 51052713); + script_730(21516, 51052716, 51052715); + script_730(21518, 51052718, 51052717); + script_730(21519, 51052720, 51052719); + switch (standart_config_1278) { + case 1438: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,16)); + break; + case 1440: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,24)); + break; + case 1442: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,26)); + break; + case 1444: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,34)); + break; + case 1448: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,30)); + break; + case 1446: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,18)); + break; + case 1458: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,28)); + break; + case 1452: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,20)); + break; + case 1462: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,32)); + break; + case 1454: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,22)); + break; + case 13625: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,52)); + break; + case 13624: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,58)); + break; + case 13627: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,64)); + break; + case 13628: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,70)); + break; + case 13615: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,54)); + break; + case 13614: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,60)); + break; + case 13617: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,66)); + break; + case 13618: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,72)); + break; + case 13620: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,56)); + break; + case 13619: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,62)); + break; + case 13622: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,68)); + break; + case 13623: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,74)); + break; + case 13599: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,90)); + break; + case 13601: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,112)); + break; + case 13602: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,100)); + break; + case 13603: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,102)); + break; + case 13600: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,106)); + break; + case 13604: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,92)); + break; + case 13608: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,104)); + break; + case 13606: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,94)); + break; + case 13607: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,108)); + break; + case 13605: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,96)); + break; + case 13609: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,98)); + break; + case 13610: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,114)); + break; + case 13598: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,116)); + break; + case 13611: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,110)); + break; + case 13629: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,120)); + break; + case 1437: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,122)); + break; + case 21517: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,169)); + break; + case 21516: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,171)); + break; + case 21518: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,173)); + break; + case 21519: + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(779,175)); + } + return; +} diff --git a/dumps/scripts/73.cs2 b/dumps/scripts/73.cs2 new file mode 100644 index 0000000..69641cd --- /dev/null +++ b/dumps/scripts/73.cs2 @@ -0,0 +1,564 @@ +void script_73(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + string svar0; + string svar1; + string svar2; + string svar3; + string svar4; + string svar5; + string svar6; + string svar7; + cs2func_script_4590_struct(6,0,0) structdump_0; + cs2func_script_4729_struct(0,8,0) structdump_1; + cs2func_script_4590_struct(6,0,0) structdump_2; + int stack_dump3; + int stack_dump4; + int stack_dump5; + int stack_dump6; + string stack_dump7; + cs2func_script_802_struct(1,1,0) structdump_8; + cs2func_script_802_struct(1,1,0) structdump_9; + if (((boolean)script_2709())) { + if (arg0 == 84) { + messageType0("Chat is not available until your Date of Birth is recorded. Please enter your DOB above."); + } + return; + } + if (arg0 == 9) { + if (globalint_132 != -1) { + script_1052(globalint_133, globalint_132, globalstring_29); + } + return; + } + if (arg0 == 10) { + if (script_1036() != -1) { + script_1051(0, ""); + } + return; + } + ivar2 = 0; + if (arg0 == 80) { + if (strLength(globalstring_276) > 0) { + ivar2 = cs2method3628(globalstring_276); + if (ivar2 != -1) { + if (isMuteRelatedMethod3329() && cs2method6900()) { + globalint_1650 = 1; + globalstring_23 = globalstring_276; + script_1558(0); + return; + } + if (cs2method3627(ivar2)) { + script_1050(1, globalstring_276); + } else { + script_1050(3, globalstring_276); + } + return; + } + if (globalint_183 > subtract(getClientCycle(), 100)) { + return; + } + messageType0("That player is not on your Friends list."); + globalint_183 = getClientCycle(); + return; + } + if (globalint_183 > subtract(getClientCycle(), 100)) { + return; + } + messageType0("You haven't received any messages to which you can reply."); + globalint_183 = getClientCycle(); + return; + } + ivar3 = 0; + ivar4 = 0; + if (arg0 == 11) { + ivar3 = 150; + ivar4 = subtract(getClientCycle(), globalint_158); + if (ivar4 > 1500) { + globalint_159 = 0; + } + if (globalint_159 >= 7) { + ivar3 = 600; + } else if (globalint_159 >= 5) { + ivar3 = 450; + } else { + if (globalint_159 >= 3) { + ivar3 = 300; + } + } + if (ivar4 >= ivar3) { + globalint_158 = getClientCycle(); + globalint_159 = add(globalint_159, 1); + if (globalint_130 != -1) { + script_1069(); + } + return; + } + } + ivar5 = 0; + ivar6 = -1; + ivar7 = -1; + ivar8 = -1; + ivar9 = -1; + ivar10 = -1; + ivar11 = -1; + if (getClientRights() > 0) { + if (arg0 == 104) { + script_75(); + } else { + if (arg0 == 105) { + script_76(); + } + } + } else { + if (cs2method6900() || isMuteRelatedMethod3329()) { + if (arg0 == 84) { + structdump_0 = script_4590(); + ivar11 = structdump_0.intpart_5; + ivar10 = structdump_0.intpart_4; + ivar9 = structdump_0.intpart_3; + ivar8 = structdump_0.intpart_2; + ivar7 = structdump_0.intpart_1; + ivar6 = structdump_0.intpart_0; + if (globalint_41 == 4) { + script_1050(2, ""); + } + if (globalint_41 == 7) { + if (ivar6 >= 0) { + if (ivar7 >= ivar8) { + script_1050(8, ""); + return; + } + message(43, 0, "Your rank is not high enough to talk in your clan chat."); + return; + } + globalint_41 = 0; + script_181(0); + script_178(); + script_84(); + script_89(); + messageType0("You aren't in a Clan Chat channel."); + return; + } + script_1050(0, ""); + return; + } + return; + } + } + ivar12 = 0; + ivar13 = 0; + ivar14 = 0; + svar0 = ""; + svar1 = ""; + svar2 = ""; + svar3 = ""; + svar4 = ""; + svar5 = ""; + svar6 = ""; + svar7 = ""; + structdump_1 = script_4729(); + svar7 = structdump_1.stringpart_7; + svar3 = structdump_1.stringpart_6; + svar6 = structdump_1.stringpart_5; + svar2 = structdump_1.stringpart_4; + svar5 = structdump_1.stringpart_3; + svar1 = structdump_1.stringpart_2; + svar4 = structdump_1.stringpart_1; + svar0 = structdump_1.stringpart_0; + switch (arg0) { + case 84: + structdump_2 = script_4590(); + ivar11 = structdump_2.intpart_5; + ivar10 = structdump_2.intpart_4; + ivar9 = structdump_2.intpart_3; + ivar8 = structdump_2.intpart_2; + ivar7 = structdump_2.intpart_1; + ivar6 = structdump_2.intpart_0; + if (strLength(globalstring_1) <= 0) { + globalint_1650 = 0; + globalstring_1 = ""; + if (globalint_41 == 4) { + script_1050(2, ""); + return; + } + if (globalint_41 == 7) { + if (ivar6 >= 0) { + if (ivar7 >= ivar8) { + script_1050(8, ""); + return; + } + message(43, 0, "Your rank is not high enough to talk in your clan chat."); + return; + } + globalint_41 = 0; + script_181(0); + script_178(); + script_84(); + script_89(); + messageType0("You aren't in a Clan Chat channel."); + return; + } + script_1050(0, ""); + return; + } + if (((boolean)stringMethod4107("/", globalstring_1))) { + globalstring_1 = ""; + script_1050(2, ""); + return; + } + if (((boolean)stringMethod4107("//", globalstring_1))) { + globalstring_1 = ""; + if (ivar6 >= 0) { + if (ivar7 >= ivar8) { + script_1050(8, ""); + return; + } + message(43, 0, "Your rank is not high enough to talk in your clan chat."); + return; + } + globalint_41 = 0; + script_181(0); + script_178(); + script_84(); + script_89(); + messageType0("You aren't in a Clan Chat channel."); + return; + } + if (((boolean)stringMethod4107("///", globalstring_1))) { + globalstring_1 = ""; + if (ivar9 >= 0) { + if (ivar10 >= ivar11) { + script_1050(10, ""); + return; + } + message(43, 0, "Guests cannot chat in this Clan Chat channel."); + return; + } + globalint_41 = 0; + script_181(0); + script_178(); + script_84(); + script_89(); + messageType0("You aren't a guest in a visited Clan Chat channel."); + return; + } + if ((getClientRights() > 0) && ((boolean)strIndexof(0, globalstring_1, "::"))) { + messageType0("" + "Use the reverse apostrophe (`) key to open the console to enter that command."); + messageType0("" + "It is usually located under the ESC key."); + globalstring_1 = ""; + script_1558(0); + return; + } + if (((boolean)stringMethod4107(svar1, lower(globalstring_1))) || ((boolean)stringMethod4107(svar5, lower(globalstring_1)))) { + globalint_1650 = 0; + globalint_1651 = 2; + cs2method5006(2); + globalstring_1 = ""; + globalint_1028 = 0; + globalint_1652 = 1; + script_1558(0); + return; + } + if (((boolean)stringMethod4107(svar3, lower(globalstring_1))) || ((boolean)stringMethod4107(svar7, lower(globalstring_1)))) { + globalint_1650 = 0; + globalint_1651 = 3; + cs2method5006(3); + globalstring_1 = ""; + globalint_1028 = 0; + globalint_1652 = 1; + script_1558(0); + return; + } + if (((boolean)stringMethod4107(svar2, lower(globalstring_1))) || ((boolean)stringMethod4107(svar6, lower(globalstring_1)))) { + globalint_1650 = 0; + globalint_1651 = 1; + cs2method5006(1); + globalstring_1 = ""; + globalint_1028 = 0; + globalint_1652 = 1; + script_1558(0); + return; + } + if (((boolean)stringMethod4107(svar0, lower(globalstring_1))) || ((boolean)stringMethod4107(svar4, lower(globalstring_1)))) { + globalint_1650 = 0; + globalint_1651 = 0; + cs2method5006(0); + globalstring_1 = ""; + globalint_1028 = 0; + globalint_1652 = 1; + script_1558(0); + return; + } + if (((boolean)globalint_1650) && (stringMethod4107(substr(0, 1, globalstring_1), "/") != 0)) { + cs2method5009(globalstring_23, globalstring_1); + globalint_1650 = 0; + globalstring_1 = ""; + return; + } + globalint_1650 = 0; + if (((boolean)globalint_1651)) { + if (((boolean)script_4730(ivar9, ivar10, ivar11, ivar6, ivar7, ivar8))) { + if (((boolean)stringMethod4107("", cs2method3611()))) { + globalstring_1 = ""; + globalint_41 = 0; + globalint_1651 = 0; + cs2method5006(0); + script_181(0); + script_178(); + script_84(); + script_89(); + messageType0("You aren't in a Friends Chat channel."); + return; + } + cs2method5006(1); + cs2method5008(globalstring_1); + globalstring_1 = ""; + } + } else if (globalint_1651 == 2) { + if (((boolean)script_4730(ivar9, ivar10, ivar11, ivar6, ivar7, ivar8))) { + if (ivar6 >= 0) { + if (ivar7 >= ivar8) { + cs2method5006(2); + cs2method5008(globalstring_1); + globalstring_1 = ""; + } else { + message(43, 0, "Your rank is not high enough to talk in your clan chat."); + globalstring_1 = ""; + cs2method5006(0); + globalint_1651 = 0; + script_1558(0); + return; + } + } else { + globalint_41 = 0; + globalint_1651 = 0; + cs2method5006(0); + script_181(0); + script_178(); + script_84(); + script_89(); + messageType0("You aren't in a Clan Chat channel."); + globalstring_1 = ""; + return; + } + } + } else if (globalint_1651 == 3) { + if (((boolean)script_4730(ivar9, ivar10, ivar11, ivar6, ivar7, ivar8))) { + if (ivar9 >= 0) { + if (ivar10 >= ivar11) { + if (((boolean)stringMethod4107(globalstring_1, ""))) { + return; + } + cs2method5006(3); + cs2method5008(globalstring_1); + globalstring_1 = ""; + } else { + message(43, 0, "Guests cannot chat in this Clan Chat channel."); + globalstring_1 = ""; + cs2method5006(0); + globalint_1651 = 0; + script_1558(0); + return; + } + } else { + globalint_41 = 0; + cs2method5006(0); + globalint_1651 = 0; + script_181(0); + script_178(); + script_84(); + script_89(); + messageType0("You aren't a guest in a visited Clan Chat channel."); + globalstring_1 = ""; + return; + } + } + } else { + if (((boolean)stringMethod4107(substr(0, 1, globalstring_1), "/"))) { + cs2method5006(1); + globalstring_1 = substr(1, strLength(globalstring_1), globalstring_1); + if (((boolean)stringMethod4107(globalstring_1, ""))) { + return; + } + if (((boolean)stringMethod4107(substr(0, 1, globalstring_1), "/"))) { + globalstring_1 = substr(1, strLength(globalstring_1), globalstring_1); + if (((boolean)stringMethod4107(substr(0, 1, globalstring_1), "/"))) { + if (ivar9 >= 0) { + if (ivar10 >= ivar11) { + cs2method5006(3); + globalstring_1 = substr(1, strLength(globalstring_1), globalstring_1); + if (((boolean)stringMethod4107(globalstring_1, ""))) { + return; + } + } else { + message(43, 0, "Guests cannot chat in this Clan Chat channel."); + globalstring_1 = ""; + cs2method5006(0); + script_1558(0); + return; + } + } else { + globalint_41 = 0; + cs2method5006(0); + script_181(0); + script_178(); + script_84(); + script_89(); + messageType0("You aren't a guest in a visited Clan Chat channel."); + globalstring_1 = ""; + return; + } + } else if (ivar6 >= 0) { + if (ivar7 >= ivar8) { + cs2method5006(2); + if (((boolean)stringMethod4107(globalstring_1, ""))) { + return; + } + } else { + message(43, 0, "Your rank is not high enough to talk in your clan chat."); + globalstring_1 = ""; + cs2method5006(0); + script_1558(0); + return; + } + } else { + globalint_41 = 0; + cs2method5006(0); + script_181(0); + script_178(); + script_84(); + script_89(); + messageType0("You aren't in a Clan Chat channel."); + globalstring_1 = ""; + return; + } + } else { + if (((boolean)stringMethod4107("", cs2method3611()))) { + globalstring_1 = ""; + globalint_41 = 0; + globalint_1651 = 0; + cs2method5006(0); + script_181(0); + script_178(); + script_84(); + script_89(); + messageType0("You aren't in a Friends Chat channel."); + return; + } + cs2method5006(1); + } + } + cs2method5008(globalstring_1); + cs2method5006(0); + } + script_77(globalstring_1); + globalstring_1 = ""; + break; + case 102: + case 103: + case 98: + case 99: + case 96: + case 97: + if (isHoldingCtrl()) { + return; + } + globalint_1028 = script_1553(arg0, globalint_1028, globalstring_1); + break; + case 13: + if (((boolean)globalint_1650)) { + if (strLength(globalstring_1) < 1) { + globalint_1650 = 0; + } else { + globalstring_1 = ""; + globalint_1028 = 0; + } + } else if (strLength(globalstring_1) < 1) { + globalint_1651 = 0; + cs2method5006(0); + } else { + globalstring_1 = ""; + globalint_1028 = 0; + } + break; + case 83: + if (((boolean)stringMethod4107(svar1, lower(globalstring_1))) || ((boolean)stringMethod4107(svar5, lower(globalstring_1)))) { + globalint_1651 = 2; + globalint_1650 = 0; + cs2method5006(2); + globalstring_1 = ""; + globalint_1028 = 0; + globalint_1652 = 1; + script_1558(0); + return; + } + if (((boolean)stringMethod4107(svar3, lower(globalstring_1))) || ((boolean)stringMethod4107(svar7, lower(globalstring_1)))) { + globalint_1651 = 3; + globalint_1650 = 0; + cs2method5006(3); + globalstring_1 = ""; + globalint_1028 = 0; + globalint_1652 = 1; + script_1558(0); + return; + } + if (((boolean)stringMethod4107(svar2, lower(globalstring_1))) || ((boolean)stringMethod4107(svar6, lower(globalstring_1)))) { + globalint_1651 = 1; + globalint_1650 = 0; + cs2method5006(1); + globalstring_1 = ""; + globalint_1028 = 0; + globalint_1652 = 1; + script_1558(0); + return; + } + if (((boolean)stringMethod4107(svar0, lower(globalstring_1))) || ((boolean)stringMethod4107(svar4, lower(globalstring_1)))) { + globalint_1651 = 0; + globalint_1650 = 0; + cs2method5006(0); + globalstring_1 = ""; + globalint_1028 = 0; + globalint_1652 = 1; + script_1558(0); + return; + } + stack_dump3 = globalint_1028; + stack_dump4 = 0; + stack_dump5 = arg0; + stack_dump6 = arg1; + stack_dump7 = globalstring_1; + structdump_8 = script_802(stack_dump3, stack_dump4, stack_dump5, stack_dump6, stack_dump7); + stack_dump7 = structdump_8.stringpart_0; + globalint_1028 = structdump_8.intpart_0; + globalstring_1 = stack_dump7; + break; + default: + if (((boolean)globalint_1652)) { + globalint_1652 = 0; + return; + } + stack_dump3 = globalint_1028; + stack_dump4 = 0; + stack_dump5 = arg0; + stack_dump6 = arg1; + stack_dump7 = globalstring_1; + structdump_9 = script_802(stack_dump3, stack_dump4, stack_dump5, stack_dump6, stack_dump7); + stack_dump7 = structdump_9.stringpart_0; + globalint_1028 = structdump_9.intpart_0; + globalstring_1 = stack_dump7; + } + script_1558(0); + return; +} diff --git a/dumps/scripts/730.cs2 b/dumps/scripts/730.cs2 new file mode 100644 index 0000000..46e20ee --- /dev/null +++ b/dumps/scripts/730.cs2 @@ -0,0 +1,13 @@ +void script_730(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + ivar3 = getItemAmtInContainer(93, 13650); + ivar4 = cs2method_3408(111, 105, 1680, arg0); + setWidgetText(new WidgetPointer(arg1), intToStr(ivar4) + " tokens"); + if ((ivar4 > ivar3) || (isMembersItem(arg0) && isMember())) { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(arg2)); + } else { + setWidgetRGB(new Color(1, 184, 1), new WidgetPointer(arg2)); + } + return; +} diff --git a/dumps/scripts/731.cs2 b/dumps/scripts/731.cs2 new file mode 100644 index 0000000..ca90327 --- /dev/null +++ b/dumps/scripts/731.cs2 @@ -0,0 +1,14 @@ +void script_731() { + setWidgetModel(-1, new WidgetPointer(781,15)); + setWidgetModel(-1, new WidgetPointer(781,16)); + setWidgetModel(-1, new WidgetPointer(781,17)); + setWidgetModel(-1, new WidgetPointer(781,18)); + setWidgetModel(-1, new WidgetPointer(781,19)); + setWidgetModel(-1, new WidgetPointer(781,20)); + setWidgetModel(-1, new WidgetPointer(781,21)); + setWidgetModel(-1, new WidgetPointer(781,22)); + setWidgetAnimation(10139, new WidgetPointer(781,33)); + setWidgetAnimation(10139, new WidgetPointer(781,42)); + setWidgetIsHidden(true, new WidgetPointer(781,1)); + return; +} diff --git a/dumps/scripts/732.cs2 b/dumps/scripts/732.cs2 new file mode 100644 index 0000000..fe86890 --- /dev/null +++ b/dumps/scripts/732.cs2 @@ -0,0 +1,10 @@ +void script_732(int arg0) { + if (((boolean)bitconfig_278)) { + setWidgetAnimation(1377, new WidgetPointer(arg0)); + } else if (((boolean)bitconfig_278)) { + setWidgetAnimation(2114, new WidgetPointer(arg0)); + } else { + setWidgetAnimation(2116, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/733.cs2 b/dumps/scripts/733.cs2 new file mode 100644 index 0000000..1c6f2fa --- /dev/null +++ b/dumps/scripts/733.cs2 @@ -0,0 +1,10 @@ +void script_733(int arg0) { + if (((boolean)bitconfig_278)) { + setWidgetAnimation(1378, new WidgetPointer(arg0)); + } else if (((boolean)bitconfig_278)) { + setWidgetAnimation(2115, new WidgetPointer(arg0)); + } else { + setWidgetAnimation(2117, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/734.cs2 b/dumps/scripts/734.cs2 new file mode 100644 index 0000000..a540311 --- /dev/null +++ b/dumps/scripts/734.cs2 @@ -0,0 +1,6 @@ +int script_734(int arg0) { + if (arg0 >= 1) { + return 1; + } + return 0; +} diff --git a/dumps/scripts/735.cs2 b/dumps/scripts/735.cs2 new file mode 100644 index 0000000..55880a0 --- /dev/null +++ b/dumps/scripts/735.cs2 @@ -0,0 +1,7 @@ +void script_735(int arg0,int arg1,int arg2,int arg3) { + script_41(arg0); + if (setWidgetRegister(new WidgetPointer(arg1), arg2)) { + setWidgetSprite(arg3); + } + return; +} diff --git a/dumps/scripts/736.cs2 b/dumps/scripts/736.cs2 new file mode 100644 index 0000000..17935ab --- /dev/null +++ b/dumps/scripts/736.cs2 @@ -0,0 +1,90 @@ +void script_736(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int stack_dump0; + ivar4 = 48889937; + ivar5 = 35913917; + ivar6 = 35913930; + if (arg0 == -1) { + setWidgetIsHidden(true, new WidgetPointer(ivar4)); + setWidgetPosition(0, 0, 0, 0, new WidgetPointer(ivar4)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(746,21)); + setWidgetIsHidden(true, new WidgetPointer(ivar5)); + setWidgetIsHidden(true, new WidgetPointer(ivar6)); + setWidgetPosition(0, 0, 0, 0, new WidgetPointer(ivar5)); + setWidgetPosition(0, 0, 0, 0, new WidgetPointer(ivar6)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(548,116)); + return; + } + setWidgetIsHidden(false, new WidgetPointer(ivar4)); + script_2755(arg0, arg1, ivar4); + setScriptCallOnGameloop(2754, new WidgetPointer(arg0), arg1, new WidgetPointer(ivar4), "IiI", new WidgetPointer(746,21)); + ivar7 = 0; + ivar8 = 0; + ivar9 = 0; + ivar10 = 0; + if (setWidgetRegister(new WidgetPointer(arg2), arg3) || ((arg3 == -1) && setWidgetRegister(new WidgetPointer(arg2)))) { + stack_dump0 = script_1743(); + ivar8 = script_1744(); + ivar7 = stack_dump0; + stack_dump0 = getWidgetActualWidth(); + ivar10 = getWidgetActualHeight(); + ivar9 = stack_dump0; + } else { + return; + } + ivar11 = getWidgetParentId(new WidgetPointer(ivar5)); + ivar12 = 0; + ivar13 = 0; + ivar14 = 0; + ivar15 = 0; + ivar16 = 0; + ivar17 = 0; + stack_dump0 = script_3365(ivar11); + ivar13 = script_3366(ivar11); + ivar12 = stack_dump0; + stack_dump0 = getWidgetActualWidth(new WidgetPointer(ivar11)); + ivar15 = getWidgetActualHeight(new WidgetPointer(ivar11)); + ivar14 = stack_dump0; + stack_dump0 = add(ivar12, ivar14); + ivar17 = add(ivar13, ivar15); + ivar16 = stack_dump0; + ivar18 = 0; + ivar19 = 0; + if (((add(ivar7, ivar9) >= ivar12) && (ivar7 <= ivar16)) && ((add(ivar8, ivar10) >= ivar13) && (ivar8 <= ivar17))) { + ivar4 = ivar5; + } else { + ivar4 = ivar6; + ivar11 = getWidgetParentId(new WidgetPointer(ivar6)); + stack_dump0 = script_3365(ivar11); + ivar13 = script_3366(ivar11); + ivar12 = stack_dump0; + stack_dump0 = getWidgetActualWidth(new WidgetPointer(ivar11)); + ivar15 = getWidgetActualHeight(new WidgetPointer(ivar11)); + ivar14 = stack_dump0; + stack_dump0 = add(ivar12, ivar14); + ivar17 = add(ivar13, ivar15); + ivar16 = stack_dump0; + } + stack_dump0 = subtract(ivar7, ivar12); + ivar19 = subtract(ivar8, ivar13); + ivar18 = stack_dump0; + setWidgetIsHidden(false, new WidgetPointer(ivar4)); + script_1176(ivar4, ivar7, ivar8, ivar9, ivar10, ivar18, ivar19, ivar12, ivar13, ivar14, ivar15); + setScriptCallOnGameloop(836, new WidgetPointer(ivar4), ivar7, ivar8, ivar9, ivar10, ivar18, ivar19, ivar12, ivar13, ivar14, ivar15, "Iiiiiiiiiii", new WidgetPointer(548,116)); + return; +} diff --git a/dumps/scripts/737.cs2 b/dumps/scripts/737.cs2 new file mode 100644 index 0000000..1e2ea04 --- /dev/null +++ b/dumps/scripts/737.cs2 @@ -0,0 +1,38 @@ +void script_737(int arg0) { + int ivar1; + ivar1 = -1; + if (((boolean)globalint_99)) { + globalint_99 = arg0; + return; + } + if (((boolean)globalint_100)) { + globalint_100 = arg0; + return; + } + if (((boolean)globalint_101)) { + globalint_101 = arg0; + if ((script_739(globalint_99) == script_739(globalint_100)) && (script_739(globalint_99) == script_739(globalint_101))) { + ivar1 = cs2method_3408(105, 109, 1152, script_739(globalint_99)); + setWidgetModel(ivar1, cs2method_3408(105, 73, 1153, globalint_99)); + setWidgetModel(ivar1, cs2method_3408(105, 73, 1153, globalint_100)); + setWidgetModel(ivar1, cs2method_3408(105, 73, 1153, globalint_101)); + globalint_104 = flagBit(globalint_104, script_739(globalint_99)); + globalint_99 = 0; + globalint_100 = 0; + globalint_101 = 0; + globalint_102 = add(globalint_102, 1); + globalint_105 = subtract(globalint_105, 1); + script_738(); + } + return; + } + setWidgetModel(31025, cs2method_3408(105, 73, 1153, globalint_99)); + setWidgetModel(31025, cs2method_3408(105, 73, 1153, globalint_100)); + setWidgetModel(31025, cs2method_3408(105, 73, 1153, globalint_101)); + globalint_99 = arg0; + globalint_100 = 0; + globalint_101 = 0; + globalint_105 = subtract(globalint_105, 1); + script_738(); + return; +} diff --git a/dumps/scripts/738.cs2 b/dumps/scripts/738.cs2 new file mode 100644 index 0000000..11c8d1a --- /dev/null +++ b/dumps/scripts/738.cs2 @@ -0,0 +1,9 @@ +void script_738() { + string svar0; + string svar1; + svar0 = intToStr(divide(globalint_105, 10)); + svar1 = intToStr(mod(globalint_105, 10)); + setWidgetText(new WidgetPointer(269,48), svar0); + setWidgetText(new WidgetPointer(269,49), svar1); + return; +} diff --git a/dumps/scripts/739.cs2 b/dumps/scripts/739.cs2 new file mode 100644 index 0000000..fad7588 --- /dev/null +++ b/dumps/scripts/739.cs2 @@ -0,0 +1,38 @@ +int script_739(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + arg0 = subtract(arg0, 1); + ivar1 = 1; + ivar2 = 1; + ivar3 = 0; + globalarray_0 = new int[36]; + ivar4 = 0; + if (globalint_103 != bitconfig_4227) { + globalint_103 = bitconfig_4227; + } + ivar3 = globalint_103; + while (ivar1 <= 12) { + while (ivar2 <= 3) { + ivar4 = mod(ivar3, 36); + while (globalarray_0[ivar4] != 0) { + ivar4 = add(ivar4, 1); + if (ivar4 == 36) { + ivar4 = 0; + } + } + if (ivar4 == arg0) { + return ivar1; + } + globalarray_0[ivar4] = ivar1; + ivar3 = multiply(ivar3, ivar3); + ivar3 = subtract(ivar3, multiply(divide(ivar3, 1000000), 1000000)); + ivar3 = divide(ivar3, 100); + ivar2 = add(ivar2, 1); + } + ivar1 = add(ivar1, 1); + ivar2 = 1; + } + return 0; +} diff --git a/dumps/scripts/74.cs2 b/dumps/scripts/74.cs2 new file mode 100644 index 0000000..4cb6549 --- /dev/null +++ b/dumps/scripts/74.cs2 @@ -0,0 +1,21 @@ +string script_74(int arg0,int arg1,int arg2,string arg3) { + int ivar3; + string svar1; + int stack_dump0; + int stack_dump1; + int stack_dump2; + int stack_dump3; + string stack_dump4; + cs2func_script_802_struct(1,1,0) structdump_5; + svar1 = ""; + ivar3 = -1; + stack_dump0 = ivar3; + stack_dump1 = arg0; + stack_dump2 = arg1; + stack_dump3 = arg2; + stack_dump4 = arg3; + structdump_5 = script_802(stack_dump0, stack_dump1, stack_dump2, stack_dump3, stack_dump4); + ivar3 = structdump_5.intpart_0; + svar1 = structdump_5.stringpart_0; + return svar1; +} diff --git a/dumps/scripts/740.cs2 b/dumps/scripts/740.cs2 new file mode 100644 index 0000000..b01a854 --- /dev/null +++ b/dumps/scripts/740.cs2 @@ -0,0 +1,12 @@ +void script_740() { + globalint_106 = 0; + globalint_106 = 0; + globalint_99 = 0; + globalint_100 = 0; + globalint_101 = 0; + globalint_104 = 0; + globalint_102 = 0; + globalint_105 = 20; + script_738(); + return; +} diff --git a/dumps/scripts/741.cs2 b/dumps/scripts/741.cs2 new file mode 100644 index 0000000..b6d36bf --- /dev/null +++ b/dumps/scripts/741.cs2 @@ -0,0 +1,29 @@ +void script_741() { + int ivar0; + int ivar1; + int ivar2; + flow_0: + ivar0 = standart_config_1163; + if (((boolean)ivar0)) { + return; + } + ivar1 = script_739(ivar0); + ivar2 = cs2method_3408(105, 109, 1151, ivar1); + if (isBitFlagged(globalint_104, ivar1)) { + return; + } + if (((ivar0 == globalint_99) || (ivar0 == globalint_100)) || (ivar0 == globalint_101)) { + return; + } + setWidgetModel(ivar2, cs2method_3408(105, 73, 1153, ivar0)); + script_737(ivar0); + IF (globalint_102 == 12) + GOTO flow_7 + GOTO flow_7 + flow_7: + if (((boolean)globalint_105)) { + messageType0("The mechanism issues forth a whine and shuts down."); + script_675(); + } + return; +} diff --git a/dumps/scripts/742.cs2 b/dumps/scripts/742.cs2 new file mode 100644 index 0000000..c264662 --- /dev/null +++ b/dumps/scripts/742.cs2 @@ -0,0 +1,38 @@ +void script_742() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + ivar0 = standart_config_1164; + ivar1 = 0; + if (((boolean)ivar0)) { + return; + } + if (ivar0 == 10) { + globalint_105 = subtract(globalint_105, 1); + if (bitconfig_4228 != globalint_105) { + if (bitconfig_4228 > globalint_105) { + ivar1 = 1; + messageType0("Part of the mechanism jams due to your frenzied manipulation."); + } + globalint_105 = bitconfig_4228; + } + if (((boolean)globalint_105)) { + messageType0("The mechanism issues forth a whine and shuts down."); + script_675(); + } + script_738(); + return; + } + ivar0 = subtract(ivar0, 1); + if (isBitFlagged(globalint_106, ivar0)) { + return; + } + globalint_106 = flagBit(globalint_106, ivar0); + globalint_105 = add(globalint_105, 5); + script_738(); + ivar2 = cs2method_3408(105, 109, 1155, ivar0); + ivar3 = ((int)cs2method_3408(105, 73, 1154, ivar0)); + setWidgetModel(ivar2, new WidgetPointer(ivar3)); + return; +} diff --git a/dumps/scripts/743.cs2 b/dumps/scripts/743.cs2 new file mode 100644 index 0000000..c042fe5 --- /dev/null +++ b/dumps/scripts/743.cs2 @@ -0,0 +1,12 @@ +void script_743(int arg0,int arg1,int arg2) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1)) { + if (((boolean)arg2)) { + setWidgetPosition(getWidgetActualX(), getWidgetActualY(), 0, 0, new WidgetPointer(18,46)); + setWidgetSize(getWidgetActualWidth(), getWidgetActualHeight(), 0, 0, new WidgetPointer(18,46)); + setWidgetIsHidden(false, new WidgetPointer(18,46)); + } else { + setWidgetIsHidden(true, new WidgetPointer(18,46)); + } + } + return; +} diff --git a/dumps/scripts/744.cs2 b/dumps/scripts/744.cs2 new file mode 100644 index 0000000..66c4201 --- /dev/null +++ b/dumps/scripts/744.cs2 @@ -0,0 +1,31 @@ +void script_744(int arg0,int arg1,int arg2,int arg3,int arg4) { + int ivar5; + int ivar6; + int stack_dump0; + ivar5 = -1; + ivar6 = -1; + if (arg0 == 1179657) { + if (arg2 == 1179657) { + if (setWidgetRegister(new WidgetPointer(arg0), arg1) && setWidgetRegister(new WidgetPointer(arg2), arg3)) { + stack_dump0 = getWidgetItemId(); + ivar6 = getWidgetItemId(); + ivar5 = stack_dump0; + setItemOnWidgetMethod1205(ivar6, 1); + setItemOnWidgetMethod1205(ivar5, 1); + cs2method1305("" + getItemName(ivar6) + ""); + cs2method1305("" + getItemName(ivar5) + ""); + } + return; + } + if (arg2 == 1179665) { + script_1535(arg1, 0); + script_59(arg4); + } + return; + } + if ((arg0 == 1179665) && (arg2 == 1179657)) { + script_1535(arg3, arg1); + script_59(arg4); + } + return; +} diff --git a/dumps/scripts/745.cs2 b/dumps/scripts/745.cs2 new file mode 100644 index 0000000..04693b6 --- /dev/null +++ b/dumps/scripts/745.cs2 @@ -0,0 +1,4 @@ +void script_745(int arg0) { + script_746(arg0); + return; +} diff --git a/dumps/scripts/746.cs2 b/dumps/scripts/746.cs2 new file mode 100644 index 0000000..a9bbeb9 --- /dev/null +++ b/dumps/scripts/746.cs2 @@ -0,0 +1,14 @@ +void script_746(int arg0) { + if (((boolean)arg0)) { + setWidgetIsHidden(false, new WidgetPointer(18,42)); + setScriptCallOnMouseEntered(-1, "", new WidgetPointer(18,29)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(18,29)); + } else { + setWidgetIsHidden(true, new WidgetPointer(18,42)); + setScriptCallOnMouseEntered(748, 1, "1", new WidgetPointer(18,29)); + setScriptCallOnMouseExit(748, 0, "1", new WidgetPointer(18,29)); + } + script_749(0); + script_41(1179689); + return; +} diff --git a/dumps/scripts/747.cs2 b/dumps/scripts/747.cs2 new file mode 100644 index 0000000..ddcc1d2 --- /dev/null +++ b/dumps/scripts/747.cs2 @@ -0,0 +1,9 @@ +void script_747(int arg0,int arg1,string arg2) { + if (arg0 != 1) { + return; + } + if (setWidgetRegister(new WidgetPointer(18,29), arg1)) { + setWidgetText(arg2); + } + return; +} diff --git a/dumps/scripts/748.cs2 b/dumps/scripts/748.cs2 new file mode 100644 index 0000000..ef3cf61 --- /dev/null +++ b/dumps/scripts/748.cs2 @@ -0,0 +1,4 @@ +void script_748(int arg0) { + script_749(arg0); + return; +} diff --git a/dumps/scripts/749.cs2 b/dumps/scripts/749.cs2 new file mode 100644 index 0000000..1a669d8 --- /dev/null +++ b/dumps/scripts/749.cs2 @@ -0,0 +1,24 @@ +void script_749(int arg0) { + if (((boolean)arg0)) { + if (setWidgetRegister(new WidgetPointer(18,29), 0)) { + setWidgetSprite(6135); + } + if (setWidgetRegister(new WidgetPointer(18,29), 1)) { + setWidgetSprite(6134); + } + if (setWidgetRegister(new WidgetPointer(18,29), 2)) { + setWidgetSprite(6136); + } + } else { + if (setWidgetRegister(new WidgetPointer(18,29), 0)) { + setWidgetSprite(6132); + } + if (setWidgetRegister(new WidgetPointer(18,29), 1)) { + setWidgetSprite(6131); + } + if (setWidgetRegister(new WidgetPointer(18,29), 2)) { + setWidgetSprite(6133); + } + } + return; +} diff --git a/dumps/scripts/75.cs2 b/dumps/scripts/75.cs2 new file mode 100644 index 0000000..45f3f77 --- /dev/null +++ b/dumps/scripts/75.cs2 @@ -0,0 +1,21 @@ +void script_75() { + int ivar0; + string svar0; + ivar0 = globalint_3; + svar0 = "null"; + if (ivar0 == -1) { + ivar0 = globalint_4; + } + if (globalint_3 != globalint_4) { + ivar0 = subtract(ivar0, 1); + if (ivar0 < 0) { + ivar0 = 19; + } + svar0 = script_79(ivar0); + if (strLength(svar0) > 0) { + globalstring_1 = svar0; + globalint_3 = ivar0; + } + } + return; +} diff --git a/dumps/scripts/750.cs2 b/dumps/scripts/750.cs2 new file mode 100644 index 0000000..b323dd0 --- /dev/null +++ b/dumps/scripts/750.cs2 @@ -0,0 +1,16 @@ +int script_750(int arg0) { + int ivar1; + if (arg0 <= 0) { + return -1; + } + arg0 = subtract(arg0, 1); + ivar1 = getItemContainerLength(94); + if (arg0 < ivar1) { + return getItemIdInSlot(94, arg0); + } + arg0 = subtract(arg0, ivar1); + if (arg0 < getItemContainerLength(93)) { + return getItemIdInSlot(93, arg0); + } + return -1; +} diff --git a/dumps/scripts/751.cs2 b/dumps/scripts/751.cs2 new file mode 100644 index 0000000..49ea84e --- /dev/null +++ b/dumps/scripts/751.cs2 @@ -0,0 +1,51 @@ +void script_751() { + int ivar0; + int ivar1; + string svar0; + ivar0 = -1; + svar0 = ""; + ivar1 = -1; + if ((standart_config_1174 != -1) && (standart_config_1174 != 0)) { + svar0 = cs2method_3408(110, 115, 1279, standart_config_1174); + setWidgetNpcHead(standart_config_1174, new WidgetPointer(662,1)); + } else { + if (cs2method_3408(111, 110, 1320, standart_config_448) != 6988) { + standart_config_1174 = cs2method_3408(111, 110, 1320, standart_config_448); + svar0 = cs2method_3408(110, 115, 1279, standart_config_1174); + setWidgetNpcHead(standart_config_1174, new WidgetPointer(662,1)); + } + } + if (((boolean)stringMethod4107(svar0, "Animal"))) { + setWidgetText(new WidgetPointer(662,54), getItemName(standart_config_448)); + } else { + setWidgetText(new WidgetPointer(662,54), svar0); + } + if (bitconfig_4282 > 50) { + bitconfig_4282 = subtract(bitconfig_4282, 50); + ivar0 = cs2method_3408(105, 65, 1275, bitconfig_4282); + setWidgetAnimation(ivar0, new WidgetPointer(662,1)); + } else { + ivar0 = cs2method_3408(105, 65, 1276, bitconfig_4282); + setWidgetAnimation(ivar0, new WidgetPointer(662,1)); + } + if (cs2method_3408(111, 111, 1283, standart_config_448) != 526) { + setWidgetIsHidden(true, new WidgetPointer(662,71)); + if (((int)cs2method_3408(110, 73, 1282, standart_config_1174)) != 43384877) { + setWidgetIsHidden(false, new WidgetPointer(662,72)); + setWidgetIsHidden(false, new WidgetPointer(662,66)); + setWidgetIsHidden(false, cs2method_3408(110, 73, 1282, standart_config_1174)); + setWidgetIsHidden(false, cs2method_3408(110, 73, 1092, standart_config_1174)); + setWidgetSprite(1802, new WidgetPointer(747,3)); + } else { + setWidgetIsHidden(true, new WidgetPointer(662,66)); + } + } else { + setWidgetIsHidden(false, new WidgetPointer(662,71)); + setWidgetIsHidden(true, new WidgetPointer(662,66)); + if ((standart_config_448 != -1) && (getItemHashmapData(standart_config_448, 394) != 0)) { + setWidgetIsHidden(false, cs2method_3408(110, 73, 1092, standart_config_1174)); + } + } + script_2671(); + return; +} diff --git a/dumps/scripts/752.cs2 b/dumps/scripts/752.cs2 new file mode 100644 index 0000000..131ecdd --- /dev/null +++ b/dumps/scripts/752.cs2 @@ -0,0 +1,12 @@ +void script_752() { + if (((boolean)bitconfig_4534) && ((boolean)bitconfig_4290)) { + setWidgetText(new WidgetPointer(662,43), "---"); + return; + } + if (((boolean)bitconfig_4290)) { + setWidgetText(new WidgetPointer(662,43), intToStr(bitconfig_4534) + ".00"); + } else { + setWidgetText(new WidgetPointer(662,43), intToStr(bitconfig_4534) + ".30"); + } + return; +} diff --git a/dumps/scripts/753.cs2 b/dumps/scripts/753.cs2 new file mode 100644 index 0000000..15d7847 --- /dev/null +++ b/dumps/scripts/753.cs2 @@ -0,0 +1,20 @@ +void script_753() { + if (bitconfig_4286 != 101) { + setWidgetText(new WidgetPointer(662,48), intToStr(bitconfig_4286) + "%"); + if (bitconfig_4286 > 74) { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(662,48)); + } else { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(662,48)); + } + } else { + setWidgetText(new WidgetPointer(662,48), "NA"); + } + if (bitconfig_4285 != 101) { + setWidgetText(new WidgetPointer(662,45), intToStr(bitconfig_4285) + "%"); + setWidgetText(new WidgetPointer(662,46), intToStr(bitconfig_4285) + "%"); + } else { + setWidgetText(new WidgetPointer(662,45), "NA"); + setWidgetText(new WidgetPointer(662,46), "NA"); + } + return; +} diff --git a/dumps/scripts/754.cs2 b/dumps/scripts/754.cs2 new file mode 100644 index 0000000..08b7eb7 --- /dev/null +++ b/dumps/scripts/754.cs2 @@ -0,0 +1,8 @@ +void script_754(int arg0,int arg1) { + if (((boolean)arg1)) { + setWidgetText(new WidgetPointer(662,43), intToStr(arg0) + ".00"); + } else { + setWidgetText(new WidgetPointer(662,43), intToStr(arg0) + ".30"); + } + return; +} diff --git a/dumps/scripts/755.cs2 b/dumps/scripts/755.cs2 new file mode 100644 index 0000000..5f5475d --- /dev/null +++ b/dumps/scripts/755.cs2 @@ -0,0 +1,4 @@ +void script_755() { + setWidgetText(new WidgetPointer(662,41), intToStr(getSkillCurrentLvl(23)) + "/" + intToStr(getSkillActualLvl(23))); + return; +} diff --git a/dumps/scripts/756.cs2 b/dumps/scripts/756.cs2 new file mode 100644 index 0000000..8fccc9b --- /dev/null +++ b/dumps/scripts/756.cs2 @@ -0,0 +1,106 @@ +void script_756() { + if (standart_config_1177 > 60) { + standart_config_1177 = 60; + } + if (standart_config_1177 == 60) { + setWidgetIsHidden(false, new WidgetPointer(662,39)); + } else { + setWidgetIsHidden(true, new WidgetPointer(662,39)); + } + if (standart_config_1177 >= 57) { + setWidgetIsHidden(false, new WidgetPointer(662,38)); + } else { + setWidgetIsHidden(true, new WidgetPointer(662,38)); + } + if (standart_config_1177 >= 54) { + setWidgetIsHidden(false, new WidgetPointer(662,37)); + } else { + setWidgetIsHidden(true, new WidgetPointer(662,37)); + } + if (standart_config_1177 >= 51) { + setWidgetIsHidden(false, new WidgetPointer(662,36)); + } else { + setWidgetIsHidden(true, new WidgetPointer(662,36)); + } + if (standart_config_1177 >= 48) { + setWidgetIsHidden(false, new WidgetPointer(662,35)); + } else { + setWidgetIsHidden(true, new WidgetPointer(662,35)); + } + if (standart_config_1177 >= 45) { + setWidgetIsHidden(false, new WidgetPointer(662,34)); + } else { + setWidgetIsHidden(true, new WidgetPointer(662,34)); + } + if (standart_config_1177 >= 42) { + setWidgetIsHidden(false, new WidgetPointer(662,33)); + } else { + setWidgetIsHidden(true, new WidgetPointer(662,33)); + } + if (standart_config_1177 >= 39) { + setWidgetIsHidden(false, new WidgetPointer(662,32)); + } else { + setWidgetIsHidden(true, new WidgetPointer(662,32)); + } + if (standart_config_1177 >= 36) { + setWidgetIsHidden(false, new WidgetPointer(662,31)); + } else { + setWidgetIsHidden(true, new WidgetPointer(662,31)); + } + if (standart_config_1177 >= 33) { + setWidgetIsHidden(false, new WidgetPointer(662,30)); + } else { + setWidgetIsHidden(true, new WidgetPointer(662,30)); + } + if (standart_config_1177 >= 30) { + setWidgetIsHidden(false, new WidgetPointer(662,29)); + } else { + setWidgetIsHidden(true, new WidgetPointer(662,29)); + } + if (standart_config_1177 >= 27) { + setWidgetIsHidden(false, new WidgetPointer(662,28)); + } else { + setWidgetIsHidden(true, new WidgetPointer(662,28)); + } + if (standart_config_1177 >= 24) { + setWidgetIsHidden(false, new WidgetPointer(662,27)); + } else { + setWidgetIsHidden(true, new WidgetPointer(662,27)); + } + if (standart_config_1177 >= 21) { + setWidgetIsHidden(false, new WidgetPointer(662,26)); + } else { + setWidgetIsHidden(true, new WidgetPointer(662,26)); + } + if (standart_config_1177 >= 18) { + setWidgetIsHidden(false, new WidgetPointer(662,25)); + } else { + setWidgetIsHidden(true, new WidgetPointer(662,25)); + } + if (standart_config_1177 >= 15) { + setWidgetIsHidden(false, new WidgetPointer(662,24)); + } else { + setWidgetIsHidden(true, new WidgetPointer(662,24)); + } + if (standart_config_1177 >= 12) { + setWidgetIsHidden(false, new WidgetPointer(662,23)); + } else { + setWidgetIsHidden(true, new WidgetPointer(662,23)); + } + if (standart_config_1177 >= 9) { + setWidgetIsHidden(false, new WidgetPointer(662,22)); + } else { + setWidgetIsHidden(true, new WidgetPointer(662,22)); + } + if (standart_config_1177 >= 6) { + setWidgetIsHidden(false, new WidgetPointer(662,21)); + } else { + setWidgetIsHidden(true, new WidgetPointer(662,21)); + } + if (standart_config_1177 >= 3) { + setWidgetIsHidden(false, new WidgetPointer(662,20)); + } else { + setWidgetIsHidden(true, new WidgetPointer(662,20)); + } + return; +} diff --git a/dumps/scripts/757.cs2 b/dumps/scripts/757.cs2 new file mode 100644 index 0000000..d160b12 --- /dev/null +++ b/dumps/scripts/757.cs2 @@ -0,0 +1,5 @@ +void script_757(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5,string arg6,string arg7,string arg8,string arg9,string arg10) { + script_759(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + setScriptCallOnItemContainerUpdate(758, new WidgetPointer(arg0), arg1, arg2, arg5, arg6, arg7, arg8, arg9, arg10, arg3, arg4, 93, 1, "IiissssssiiY", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/758.cs2 b/dumps/scripts/758.cs2 new file mode 100644 index 0000000..d4d35e5 --- /dev/null +++ b/dumps/scripts/758.cs2 @@ -0,0 +1,4 @@ +void script_758(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5,string arg6,string arg7,string arg8,string arg9,string arg10) { + script_759(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + return; +} diff --git a/dumps/scripts/759.cs2 b/dumps/scripts/759.cs2 new file mode 100644 index 0000000..16baffa --- /dev/null +++ b/dumps/scripts/759.cs2 @@ -0,0 +1,298 @@ +void script_759(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5,string arg6,string arg7,string arg8,string arg9,string arg10) { + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + int ivar22; + int ivar23; + int ivar24; + int ivar25; + int ivar26; + int ivar27; + int ivar28; + int ivar29; + int ivar30; + int ivar31; + int ivar32; + int ivar33; + int ivar34; + int ivar35; + int ivar36; + string svar6; + int stack_dump0; + cs2func_script_767_struct(20,0,0) structdump_1; + deleteAllExtraChilds(new WidgetPointer(arg0)); + setWidgetScrollMax(0, multiply(add(divide(subtract(arg4, arg3), arg1), 1), 57), new WidgetPointer(arg0)); + ivar5 = 0; + ivar6 = arg3; + ivar7 = 0; + ivar8 = arg4; + ivar9 = 0; + ivar10 = -1; + ivar11 = -1; + ivar12 = -1; + ivar13 = -1; + ivar14 = -1; + ivar15 = -1; + ivar16 = -1; + ivar17 = -1; + ivar18 = -1; + ivar19 = -1; + ivar20 = -1; + ivar21 = 0; + ivar22 = 0; + ivar23 = 0; + ivar24 = 0; + ivar25 = 0; + ivar26 = 0; + ivar27 = 0; + ivar28 = 0; + ivar29 = 0; + ivar30 = 0; + svar6 = "hello"; + ivar31 = 0; + globalarray_0 = new int[10]; + ivar32 = -1; + ivar33 = 0; + ivar34 = 0; + ivar35 = 0; + ivar36 = 1; + while (ivar5 <= subtract(arg4, arg3)) { + ivar36 = 1; + ivar32 = cs2method_3408(105, 111, 1182, ivar6); + if (((boolean)bitconfig_8701)) { + if (getItemHashmapData(ivar32, 697) != -1) { + switch (getItemHashmapData(ivar32, 697)) { + case 6287: + if (add(getItemAmtInContainer(93, 6287), getItemAmtInContainer(93, 7801)) < getItemHashmapData(ivar32, 698)) { + ivar36 = 0; + } + break; + case 6979: + if (add(add(getItemAmtInContainer(93, 6979), getItemAmtInContainer(93, 6981)), getItemAmtInContainer(93, 6983)) < getItemHashmapData(ivar32, 698)) { + ivar36 = 0; + } + break; + case 2462: + if (add(add(add(add(add(add(getItemAmtInContainer(93, 2462), getItemAmtInContainer(93, 2460)), getItemAmtInContainer(93, 2464)), getItemAmtInContainer(93, 2466)), getItemAmtInContainer(93, 2468)), getItemAmtInContainer(93, 2470)), getItemAmtInContainer(93, 2472)) < getItemHashmapData(ivar32, 698)) { + ivar36 = 0; + } + break; + default: + if (getItemAmtInContainer(93, getItemHashmapData(ivar32, 697)) < getItemHashmapData(ivar32, 698)) { + ivar36 = 0; + } + } + } + if ((getItemHashmapData(ivar32, 699) != -1) && ((boolean)ivar36)) { + switch (getItemHashmapData(ivar32, 699)) { + case 6287: + if (add(getItemAmtInContainer(93, 6287), getItemAmtInContainer(93, 7801)) < getItemHashmapData(ivar32, 700)) { + ivar36 = 0; + } + break; + case 6979: + if (add(add(getItemAmtInContainer(93, 6979), getItemAmtInContainer(93, 6981)), getItemAmtInContainer(93, 6983)) < getItemHashmapData(ivar32, 700)) { + ivar36 = 0; + } + break; + case 2462: + if (add(add(add(add(add(add(getItemAmtInContainer(93, 2462), getItemAmtInContainer(93, 2460)), getItemAmtInContainer(93, 2464)), getItemAmtInContainer(93, 2466)), getItemAmtInContainer(93, 2468)), getItemAmtInContainer(93, 2470)), getItemAmtInContainer(93, 2472)) < getItemHashmapData(ivar32, 700)) { + ivar36 = 0; + } + break; + default: + if (getItemAmtInContainer(93, getItemHashmapData(ivar32, 699)) < getItemHashmapData(ivar32, 700)) { + ivar36 = 0; + } + } + } + if ((getItemHashmapData(ivar32, 701) != -1) && ((boolean)ivar36)) { + switch (getItemHashmapData(ivar32, 701)) { + case 6287: + if (add(getItemAmtInContainer(93, 6287), getItemAmtInContainer(93, 7801)) < getItemHashmapData(ivar32, 702)) { + ivar36 = 0; + } + break; + case 6979: + if (add(add(getItemAmtInContainer(93, 6979), getItemAmtInContainer(93, 6981)), getItemAmtInContainer(93, 6983)) < getItemHashmapData(ivar32, 702)) { + ivar36 = 0; + } + break; + case 2462: + if (add(add(add(add(add(add(getItemAmtInContainer(93, 2462), getItemAmtInContainer(93, 2460)), getItemAmtInContainer(93, 2464)), getItemAmtInContainer(93, 2466)), getItemAmtInContainer(93, 2468)), getItemAmtInContainer(93, 2470)), getItemAmtInContainer(93, 2472)) < getItemHashmapData(ivar32, 702)) { + ivar36 = 0; + } + break; + default: + if (getItemAmtInContainer(93, getItemHashmapData(ivar32, 701)) < getItemHashmapData(ivar32, 702)) { + ivar36 = 0; + } + } + } + if ((getItemHashmapData(ivar32, 703) != -1) && ((boolean)ivar36)) { + switch (getItemHashmapData(ivar32, 703)) { + case 6287: + if (add(getItemAmtInContainer(93, 6287), getItemAmtInContainer(93, 7801)) < getItemHashmapData(ivar32, 704)) { + ivar36 = 0; + } + break; + case 6979: + if (add(add(getItemAmtInContainer(93, 6979), getItemAmtInContainer(93, 6981)), getItemAmtInContainer(93, 6983)) < getItemHashmapData(ivar32, 704)) { + ivar36 = 0; + } + break; + case 2462: + if (add(add(add(add(add(add(getItemAmtInContainer(93, 2462), getItemAmtInContainer(93, 2460)), getItemAmtInContainer(93, 2464)), getItemAmtInContainer(93, 2466)), getItemAmtInContainer(93, 2468)), getItemAmtInContainer(93, 2470)), getItemAmtInContainer(93, 2472)) < getItemHashmapData(ivar32, 704)) { + ivar36 = 0; + } + break; + default: + if (getItemAmtInContainer(93, getItemHashmapData(ivar32, 703)) < getItemHashmapData(ivar32, 704)) { + ivar36 = 0; + } + } + } + if ((getItemHashmapData(ivar32, 705) != -1) && ((boolean)ivar36)) { + switch (getItemHashmapData(ivar32, 705)) { + case 6287: + if (add(getItemAmtInContainer(93, 6287), getItemAmtInContainer(93, 7801)) < getItemHashmapData(ivar32, 706)) { + ivar36 = 0; + } + break; + case 6979: + if (add(add(getItemAmtInContainer(93, 6979), getItemAmtInContainer(93, 6981)), getItemAmtInContainer(93, 6983)) < getItemHashmapData(ivar32, 706)) { + ivar36 = 0; + } + break; + case 2462: + if (add(add(add(add(add(add(getItemAmtInContainer(93, 2462), getItemAmtInContainer(93, 2460)), getItemAmtInContainer(93, 2464)), getItemAmtInContainer(93, 2466)), getItemAmtInContainer(93, 2468)), getItemAmtInContainer(93, 2470)), getItemAmtInContainer(93, 2472)) < getItemHashmapData(ivar32, 706)) { + ivar36 = 0; + } + break; + default: + if (getItemAmtInContainer(93, getItemHashmapData(ivar32, 705)) < getItemHashmapData(ivar32, 706)) { + ivar36 = 0; + } + } + } + if ((getItemHashmapData(ivar32, 707) != -1) && ((boolean)ivar36)) { + switch (getItemHashmapData(ivar32, 707)) { + case 6287: + if (add(getItemAmtInContainer(93, 6287), getItemAmtInContainer(93, 7801)) < getItemHashmapData(ivar32, 708)) { + ivar36 = 0; + } + break; + case 6979: + if (add(add(getItemAmtInContainer(93, 6979), getItemAmtInContainer(93, 6981)), getItemAmtInContainer(93, 6983)) < getItemHashmapData(ivar32, 708)) { + ivar36 = 0; + } + break; + case 2462: + if (add(add(add(add(add(add(getItemAmtInContainer(93, 2462), getItemAmtInContainer(93, 2460)), getItemAmtInContainer(93, 2464)), getItemAmtInContainer(93, 2466)), getItemAmtInContainer(93, 2468)), getItemAmtInContainer(93, 2470)), getItemAmtInContainer(93, 2472)) < getItemHashmapData(ivar32, 708)) { + ivar36 = 0; + } + break; + default: + if (getItemAmtInContainer(93, getItemHashmapData(ivar32, 707)) < getItemHashmapData(ivar32, 708)) { + ivar36 = 0; + } + } + } + } + if (((boolean)ivar36)) { + ivar33 = add(add(16, multiply(mod(ivar7, arg1), 48)), multiply(mod(ivar7, arg1), 5)); + ivar34 = add(multiply(divide(ivar7, arg1), 52), multiply(divide(ivar7, arg1), 5)); + createExtraChild(new WidgetPointer(arg0), 5, ivar35); + ivar35 = add(ivar35, 1); + setWidgetSize(48, 52, 0, 0); + setWidgetPosition(ivar33, ivar34, 0, 0); + setWidgetSprite(2205); + setScriptCallOnMouseEntered(2724, new WidgetPointer(-32768,3), ivar35, 0, "Ii1"); + setScriptCallOnMouseExit(2724, new WidgetPointer(-32768,3), ivar35, 1, "Ii1"); + createExtraChild(new WidgetPointer(arg0), 5, ivar35); + ivar35 = add(ivar35, 1); + setWidgetSize(48, 52, 0, 0); + setWidgetPosition(ivar33, ivar34, 0, 0); + setWidgetSprite(2206); + setWidgetHidden(1); + createExtraChild(new WidgetPointer(arg0), 5, ivar35); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(add(ivar33, 6), add(ivar34, 4), 0, 0); + if (ivar32 == 12292) { + script_760(ivar32, ivar32, arg0, ivar35, arg5, arg6, arg7, arg8, arg9, arg10); + } else if (((boolean)script_766(ivar32)) && (getSkillActualLvl(23) >= cs2method_3408(111, 105, 1185, ivar32))) { + script_760(ivar32, ivar32, arg0, ivar35, arg5, arg6, arg7, arg8, arg9, arg10); + } else { + script_760(cs2method_3408(105, 111, 1183, ivar6), ivar32, arg0, ivar35, arg5, arg6, arg7, arg8, arg9, arg10); + } + if (ivar32 == 12292) { + setScriptCallOnMouseOver(782, -2147483643, new WidgetPointer(79,31), new WidgetPointer(79,16), ivar31, svar6, "iIIis"); + setScriptCallOnMouseExit(40, new WidgetPointer(79,31), "I"); + } else { + svar6 = cs2method_3408(111, 115, 1187, ivar32); + ivar31 = cs2method_3408(111, 105, 1185, ivar32); + stack_dump0 = ivar32; + structdump_1 = script_767(stack_dump0); + ivar30 = structdump_1.intpart_19; + ivar29 = structdump_1.intpart_18; + ivar28 = structdump_1.intpart_17; + ivar27 = structdump_1.intpart_16; + ivar26 = structdump_1.intpart_15; + ivar25 = structdump_1.intpart_14; + ivar24 = structdump_1.intpart_13; + ivar23 = structdump_1.intpart_12; + ivar22 = structdump_1.intpart_11; + ivar21 = structdump_1.intpart_10; + ivar20 = structdump_1.intpart_9; + ivar19 = structdump_1.intpart_8; + ivar18 = structdump_1.intpart_7; + ivar17 = structdump_1.intpart_6; + ivar16 = structdump_1.intpart_5; + ivar15 = structdump_1.intpart_4; + ivar14 = structdump_1.intpart_3; + ivar13 = structdump_1.intpart_2; + ivar12 = structdump_1.intpart_1; + ivar11 = structdump_1.intpart_0; + setScriptCallOnMouseOver(770, -2147483643, new WidgetPointer(79,31), new WidgetPointer(79,16), ivar31, svar6, ivar11, 1, ivar12, ivar22, ivar13, ivar23, ivar14, ivar24, ivar15, ivar25, ivar16, ivar26, ivar17, ivar27, ivar18, ivar28, ivar19, ivar29, ivar20, ivar30, "iIIisoioioioioioioioioioi"); + setScriptCallOnMouseExit(40, new WidgetPointer(79,31), "I"); + } + ivar35 = add(ivar35, 1); + createExtraChild(new WidgetPointer(arg0), 5, ivar35); + ivar35 = add(ivar35, 1); + setWidgetSize(12, 12, 0, 0); + setWidgetPosition(add(ivar33, 2), add(ivar34, 38), 0, 0); + setItemOnWidgetMethod1205(12183, 1); + createExtraChild(new WidgetPointer(arg0), 4, ivar35); + ivar35 = add(ivar35, 1); + setWidgetSize(31, 12, 0, 0); + setWidgetPosition(add(ivar33, 13), add(ivar34, 39), 0, 0); + setWidgetFont(494); + setWidgetRGB(new Color(255, 255, 255)); + setWidgetTextAlignment(2, 1, 0); + if (getItemHashmapData(ivar32, 541) < 1) { + setWidgetText("--"); + } else { + setWidgetText(script_940(getItemHashmapData(ivar32, 541))); + } + setWidgetUnknownBoolean(true); + ivar7 = add(ivar7, 1); + } + ivar5 = add(ivar5, 1); + ivar6 = add(ivar6, 1); + } + return; +} diff --git a/dumps/scripts/76.cs2 b/dumps/scripts/76.cs2 new file mode 100644 index 0000000..0c8bef0 --- /dev/null +++ b/dumps/scripts/76.cs2 @@ -0,0 +1,20 @@ +void script_76() { + string svar0; + svar0 = "null"; + if (globalint_3 != -1) { + globalint_3 = add(globalint_3, 1); + if (globalint_3 >= 20) { + globalint_3 = 0; + } + if (globalint_3 == globalint_4) { + globalstring_1 = ""; + globalint_3 = -1; + } else { + svar0 = script_79(globalint_3); + if (strLength(svar0) > 0) { + globalstring_1 = svar0; + } + } + } + return; +} diff --git a/dumps/scripts/760.cs2 b/dumps/scripts/760.cs2 new file mode 100644 index 0000000..8ed6eeb --- /dev/null +++ b/dumps/scripts/760.cs2 @@ -0,0 +1,28 @@ +void script_760(int arg0,int arg1,int arg2,int arg3,string arg4,string arg5,string arg6,string arg7,string arg8,string arg9) { + if (setWidgetRegister(new WidgetPointer(arg2), arg3)) { + if (arg0 != -1) { + setItemOnWidgetMethod1200(arg0, -1); + cs2method1305(getItemName(arg1)); + setWidgetContextMenuOption(1, arg4); + setWidgetContextMenuOption(2, arg5); + setWidgetContextMenuOption(3, arg6); + setWidgetContextMenuOption(4, arg7); + setWidgetContextMenuOption(5, arg8); + setWidgetContextMenuOption(6, "Examine" + ""); + setWidgetContextMenuOption(7, arg9); + setWidgetShadowColor(new Color(51, 51, 51)); + setWidgetBorderThickness(1); + } else { + setItemOnWidgetMethod1200(-1, 0); + cs2method1305(""); + setWidgetContextMenuOption(1, ""); + setWidgetContextMenuOption(2, ""); + setWidgetContextMenuOption(3, ""); + setWidgetContextMenuOption(4, ""); + setWidgetContextMenuOption(5, ""); + setWidgetContextMenuOption(6, ""); + setWidgetContextMenuOption(7, ""); + } + } + return; +} diff --git a/dumps/scripts/761.cs2 b/dumps/scripts/761.cs2 new file mode 100644 index 0000000..4189c24 --- /dev/null +++ b/dumps/scripts/761.cs2 @@ -0,0 +1,15 @@ +int script_761(int arg0) { + if (((boolean)arg0)) { + return 36; + } + if (((boolean)arg0)) { + return 147; + } + if (arg0 == 2) { + return 258; + } + if (arg0 == 3) { + return 369; + } + return 0; +} diff --git a/dumps/scripts/762.cs2 b/dumps/scripts/762.cs2 new file mode 100644 index 0000000..ec0039a --- /dev/null +++ b/dumps/scripts/762.cs2 @@ -0,0 +1,15 @@ +int script_762(int arg0) { + if (((boolean)arg0)) { + return 6; + } + if (((boolean)arg0)) { + return 117; + } + if (arg0 == 2) { + return 228; + } + if (arg0 == 3) { + return 340; + } + return 0; +} diff --git a/dumps/scripts/763.cs2 b/dumps/scripts/763.cs2 new file mode 100644 index 0000000..351ffe6 --- /dev/null +++ b/dumps/scripts/763.cs2 @@ -0,0 +1,5 @@ +void script_763(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5,string arg6,string arg7,string arg8,string arg9) { + script_765(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + setScriptCallOnItemContainerUpdate(764, new WidgetPointer(arg0), arg1, arg2, arg5, arg6, arg7, arg8, arg9, arg3, arg4, 93, 1, "IiisssssiiY", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/764.cs2 b/dumps/scripts/764.cs2 new file mode 100644 index 0000000..cd25ce3 --- /dev/null +++ b/dumps/scripts/764.cs2 @@ -0,0 +1,4 @@ +void script_764(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5,string arg6,string arg7,string arg8,string arg9) { + script_765(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + return; +} diff --git a/dumps/scripts/765.cs2 b/dumps/scripts/765.cs2 new file mode 100644 index 0000000..8ad7b94 --- /dev/null +++ b/dumps/scripts/765.cs2 @@ -0,0 +1,89 @@ +void script_765(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5,string arg6,string arg7,string arg8,string arg9) { + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + string svar5; + deleteAllExtraChilds(new WidgetPointer(arg0)); + ivar5 = 0; + ivar6 = 0; + setWidgetScrollMax(0, multiply(add(divide(subtract(arg4, arg3), arg1), 1), 57), new WidgetPointer(arg0)); + ivar7 = 0; + ivar8 = arg3; + ivar9 = 0; + ivar10 = arg4; + ivar11 = 0; + ivar12 = -1; + ivar13 = -1; + ivar14 = -1; + svar5 = "hello"; + ivar15 = 0; + ivar16 = 0; + while (ivar7 <= subtract(arg4, arg3)) { + if (((boolean)bitconfig_8701) || (getItemAmtInContainer(93, cs2method_3408(105, 111, 1182, ivar8)) > 0)) { + ivar5 = add(add(16, multiply(mod(ivar9, arg1), 48)), multiply(mod(ivar9, arg1), 5)); + ivar6 = add(multiply(divide(ivar9, arg1), 52), multiply(divide(ivar9, arg1), 5)); + createExtraChild(new WidgetPointer(arg0), 5, ivar16); + ivar16 = add(ivar16, 1); + setWidgetSize(48, 52, 0, 0); + setWidgetPosition(ivar5, ivar6, 0, 0); + setWidgetSprite(2205); + setScriptCallOnMouseEntered(2724, new WidgetPointer(-32768,3), ivar16, 0, "Ii1"); + setScriptCallOnMouseExit(2724, new WidgetPointer(-32768,3), ivar16, 1, "Ii1"); + createExtraChild(new WidgetPointer(arg0), 5, ivar16); + ivar16 = add(ivar16, 1); + setWidgetSize(48, 52, 0, 0); + setWidgetPosition(ivar5, ivar6, 0, 0); + setWidgetSprite(2206); + setWidgetHidden(1); + createExtraChild(new WidgetPointer(arg0), 5, ivar16); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(add(ivar5, 6), add(ivar6, 4), 0, 0); + ivar13 = cs2method_3408(105, 111, 1277, ivar8); + ivar14 = cs2method_3408(105, 111, 1188, ivar8); + if (ivar14 == 12421) { + script_760(ivar14, ivar14, arg0, ivar16, arg5, arg6, arg7, arg8, arg9, ""); + } else if (((boolean)script_768(ivar14, ivar13)) && (getSkillActualLvl(23) >= cs2method_3408(111, 105, 1185, ivar13))) { + script_760(ivar14, ivar14, arg0, ivar16, arg5, arg6, arg7, arg8, arg9, ""); + } else { + script_760(cs2method_3408(105, 111, 1184, ivar8), ivar14, arg0, ivar16, arg5, arg6, arg7, arg8, arg9, ""); + } + if (ivar14 == 12421) { + setScriptCallOnMouseOver(782, -2147483643, new WidgetPointer(79,31), new WidgetPointer(79,17), ivar15, svar5, "iIIis"); + setScriptCallOnMouseExit(40, new WidgetPointer(79,31), "I"); + } else { + svar5 = cs2method_3408(111, 115, 1187, ivar14); + ivar15 = cs2method_3408(111, 105, 1185, ivar13); + setScriptCallOnMouseOver(770, -2147483643, new WidgetPointer(79,31), new WidgetPointer(79,17), ivar15, svar5, ivar13, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, "iIIisoioioioioioioioioioi"); + setScriptCallOnMouseExit(40, new WidgetPointer(79,31), "I"); + } + ivar16 = add(ivar16, 1); + createExtraChild(new WidgetPointer(arg0), 5, ivar16); + ivar16 = add(ivar16, 1); + setWidgetSize(12, 12, 0, 0); + setWidgetPosition(add(ivar5, 2), add(ivar6, 38), 0, 0); + setItemOnWidgetMethod1205(ivar13, 1); + createExtraChild(new WidgetPointer(arg0), 4, ivar16); + ivar16 = add(ivar16, 1); + setWidgetSize(31, 12, 0, 0); + setWidgetPosition(add(ivar5, 13), add(ivar6, 39), 0, 0); + setWidgetFont(494); + setWidgetRGB(new Color(255, 255, 255)); + setWidgetTextAlignment(2, 1, 0); + setWidgetText("1"); + setWidgetUnknownBoolean(true); + ivar9 = add(ivar9, 1); + } + ivar7 = add(ivar7, 1); + ivar8 = add(ivar8, 1); + } + return; +} diff --git a/dumps/scripts/766.cs2 b/dumps/scripts/766.cs2 new file mode 100644 index 0000000..c0152f4 --- /dev/null +++ b/dumps/scripts/766.cs2 @@ -0,0 +1,150 @@ +int script_766(int arg0) { + if ((getItemHashmapData(arg0, 538) != -1) && (getItemAmtInContainer(93, getItemHashmapData(arg0, 538)) < getItemHashmapData(arg0, 539))) { + return 0; + } + if ((getItemHashmapData(arg0, 540) != -1) && (getItemAmtInContainer(93, getItemHashmapData(arg0, 540)) < getItemHashmapData(arg0, 541))) { + return 0; + } + if ((getItemHashmapData(arg0, 542) != -1) && (getItemAmtInContainer(93, getItemHashmapData(arg0, 542)) < getItemHashmapData(arg0, 543))) { + return 0; + } + if (getItemHashmapData(arg0, 697) != -1) { + switch (getItemHashmapData(arg0, 697)) { + case 6287: + if (add(getItemAmtInContainer(93, 6287), getItemAmtInContainer(93, 7801)) < getItemHashmapData(arg0, 698)) { + return 0; + } + break; + case 6979: + if (add(add(getItemAmtInContainer(93, 6979), getItemAmtInContainer(93, 6981)), getItemAmtInContainer(93, 6983)) < getItemHashmapData(arg0, 698)) { + return 0; + } + break; + case 2462: + if (add(add(add(add(add(add(getItemAmtInContainer(93, 2462), getItemAmtInContainer(93, 2460)), getItemAmtInContainer(93, 2464)), getItemAmtInContainer(93, 2466)), getItemAmtInContainer(93, 2468)), getItemAmtInContainer(93, 2470)), getItemAmtInContainer(93, 2472)) < getItemHashmapData(arg0, 698)) { + return 0; + } + break; + default: + if (getItemAmtInContainer(93, getItemHashmapData(arg0, 697)) < getItemHashmapData(arg0, 698)) { + return 0; + } + } + } + if (getItemHashmapData(arg0, 699) != -1) { + switch (getItemHashmapData(arg0, 699)) { + case 6287: + if (add(getItemAmtInContainer(93, 6287), getItemAmtInContainer(93, 7801)) < getItemHashmapData(arg0, 700)) { + return 0; + } + break; + case 6979: + if (add(add(getItemAmtInContainer(93, 6979), getItemAmtInContainer(93, 6981)), getItemAmtInContainer(93, 6983)) < getItemHashmapData(arg0, 700)) { + return 0; + } + break; + case 2462: + if (add(add(add(add(add(add(getItemAmtInContainer(93, 2462), getItemAmtInContainer(93, 2460)), getItemAmtInContainer(93, 2464)), getItemAmtInContainer(93, 2466)), getItemAmtInContainer(93, 2468)), getItemAmtInContainer(93, 2470)), getItemAmtInContainer(93, 2472)) < getItemHashmapData(arg0, 700)) { + return 0; + } + break; + default: + if (getItemAmtInContainer(93, getItemHashmapData(arg0, 699)) < getItemHashmapData(arg0, 700)) { + return 0; + } + } + } + if (getItemHashmapData(arg0, 701) != -1) { + switch (getItemHashmapData(arg0, 701)) { + case 6287: + if (add(getItemAmtInContainer(93, 6287), getItemAmtInContainer(93, 7801)) < getItemHashmapData(arg0, 702)) { + return 0; + } + break; + case 6979: + if (add(add(getItemAmtInContainer(93, 6979), getItemAmtInContainer(93, 6981)), getItemAmtInContainer(93, 6983)) < getItemHashmapData(arg0, 702)) { + return 0; + } + break; + case 2462: + if (add(add(add(add(add(add(getItemAmtInContainer(93, 2462), getItemAmtInContainer(93, 2460)), getItemAmtInContainer(93, 2464)), getItemAmtInContainer(93, 2466)), getItemAmtInContainer(93, 2468)), getItemAmtInContainer(93, 2470)), getItemAmtInContainer(93, 2472)) < getItemHashmapData(arg0, 702)) { + return 0; + } + break; + default: + if (getItemAmtInContainer(93, getItemHashmapData(arg0, 701)) < getItemHashmapData(arg0, 702)) { + return 0; + } + } + } + if (getItemHashmapData(arg0, 703) != -1) { + switch (getItemHashmapData(arg0, 703)) { + case 6287: + if (add(getItemAmtInContainer(93, 6287), getItemAmtInContainer(93, 7801)) < getItemHashmapData(arg0, 704)) { + return 0; + } + break; + case 6979: + if (add(add(getItemAmtInContainer(93, 6979), getItemAmtInContainer(93, 6981)), getItemAmtInContainer(93, 6983)) < getItemHashmapData(arg0, 704)) { + return 0; + } + break; + case 2462: + if (add(add(add(add(add(add(getItemAmtInContainer(93, 2462), getItemAmtInContainer(93, 2460)), getItemAmtInContainer(93, 2464)), getItemAmtInContainer(93, 2466)), getItemAmtInContainer(93, 2468)), getItemAmtInContainer(93, 2470)), getItemAmtInContainer(93, 2472)) < getItemHashmapData(arg0, 704)) { + return 0; + } + break; + default: + if (getItemAmtInContainer(93, getItemHashmapData(arg0, 703)) < getItemHashmapData(arg0, 704)) { + return 0; + } + } + } + if (getItemHashmapData(arg0, 705) != -1) { + switch (getItemHashmapData(arg0, 705)) { + case 6287: + if (add(getItemAmtInContainer(93, 6287), getItemAmtInContainer(93, 7801)) < getItemHashmapData(arg0, 706)) { + return 0; + } + break; + case 6979: + if (add(add(getItemAmtInContainer(93, 6979), getItemAmtInContainer(93, 6981)), getItemAmtInContainer(93, 6983)) < getItemHashmapData(arg0, 706)) { + return 0; + } + break; + case 2462: + if (add(add(add(add(add(add(getItemAmtInContainer(93, 2462), getItemAmtInContainer(93, 2460)), getItemAmtInContainer(93, 2464)), getItemAmtInContainer(93, 2466)), getItemAmtInContainer(93, 2468)), getItemAmtInContainer(93, 2470)), getItemAmtInContainer(93, 2472)) < getItemHashmapData(arg0, 706)) { + return 0; + } + break; + default: + if (getItemAmtInContainer(93, getItemHashmapData(arg0, 705)) < getItemHashmapData(arg0, 706)) { + return 0; + } + } + } + if (getItemHashmapData(arg0, 707) != -1) { + switch (getItemHashmapData(arg0, 707)) { + case 6287: + if (add(getItemAmtInContainer(93, 6287), getItemAmtInContainer(93, 7801)) < getItemHashmapData(arg0, 708)) { + return 0; + } + break; + case 6979: + if (add(add(getItemAmtInContainer(93, 6979), getItemAmtInContainer(93, 6981)), getItemAmtInContainer(93, 6983)) < getItemHashmapData(arg0, 708)) { + return 0; + } + break; + case 2462: + if (add(add(add(add(add(add(getItemAmtInContainer(93, 2462), getItemAmtInContainer(93, 2460)), getItemAmtInContainer(93, 2464)), getItemAmtInContainer(93, 2466)), getItemAmtInContainer(93, 2468)), getItemAmtInContainer(93, 2470)), getItemAmtInContainer(93, 2472)) < getItemHashmapData(arg0, 708)) { + return 0; + } + break; + default: + if (getItemAmtInContainer(93, getItemHashmapData(arg0, 707)) < getItemHashmapData(arg0, 708)) { + return 0; + } + } + } + return 1; +} diff --git a/dumps/scripts/767.cs2 b/dumps/scripts/767.cs2 new file mode 100644 index 0000000..c830c69 --- /dev/null +++ b/dumps/scripts/767.cs2 @@ -0,0 +1,52 @@ +cs2func_script_767_struct(20,0,0) script_767(int arg0) { + int ivar1; + globalarray_0 = new int[10]; + globalarray_1 = new int[10]; + ivar1 = 0; + if (getItemHashmapData(arg0, 538) != -1) { + globalarray_0[ivar1] = getItemHashmapData(arg0, 538); + globalarray_0[ivar1] = getItemHashmapData(arg0, 539); + ivar1 = add(ivar1, 1); + } + if (getItemHashmapData(arg0, 540) != -1) { + globalarray_0[ivar1] = getItemHashmapData(arg0, 540); + globalarray_0[ivar1] = getItemHashmapData(arg0, 541); + ivar1 = add(ivar1, 1); + } + if (getItemHashmapData(arg0, 542) != -1) { + globalarray_0[ivar1] = getItemHashmapData(arg0, 542); + globalarray_0[ivar1] = getItemHashmapData(arg0, 543); + ivar1 = add(ivar1, 1); + } + if (getItemHashmapData(arg0, 697) != -1) { + globalarray_0[ivar1] = getItemHashmapData(arg0, 697); + globalarray_0[ivar1] = getItemHashmapData(arg0, 698); + ivar1 = add(ivar1, 1); + } + if (getItemHashmapData(arg0, 699) != -1) { + globalarray_0[ivar1] = getItemHashmapData(arg0, 699); + globalarray_0[ivar1] = getItemHashmapData(arg0, 700); + ivar1 = add(ivar1, 1); + } + if (getItemHashmapData(arg0, 701) != -1) { + globalarray_0[ivar1] = getItemHashmapData(arg0, 701); + globalarray_0[ivar1] = getItemHashmapData(arg0, 702); + ivar1 = add(ivar1, 1); + } + if (getItemHashmapData(arg0, 703) != -1) { + globalarray_0[ivar1] = getItemHashmapData(arg0, 703); + globalarray_0[ivar1] = getItemHashmapData(arg0, 704); + ivar1 = add(ivar1, 1); + } + if (getItemHashmapData(arg0, 705) != -1) { + globalarray_0[ivar1] = getItemHashmapData(arg0, 705); + globalarray_0[ivar1] = getItemHashmapData(arg0, 706); + ivar1 = add(ivar1, 1); + } + if (getItemHashmapData(arg0, 707) != -1) { + globalarray_0[ivar1] = getItemHashmapData(arg0, 707); + globalarray_0[ivar1] = getItemHashmapData(arg0, 708); + ivar1 = add(ivar1, 1); + } + return newstruct cs2func_script_767_struct(globalarray_0[0], globalarray_0[1], globalarray_0[2], globalarray_0[3], globalarray_0[4], globalarray_0[5], globalarray_0[6], globalarray_0[7], globalarray_0[8], globalarray_0[9], globalarray_1[0], globalarray_1[1], globalarray_1[2], globalarray_1[3], globalarray_1[4], globalarray_1[5], globalarray_1[6], globalarray_1[7], globalarray_1[8], globalarray_1[9]); +} diff --git a/dumps/scripts/768.cs2 b/dumps/scripts/768.cs2 new file mode 100644 index 0000000..474ffb4 --- /dev/null +++ b/dumps/scripts/768.cs2 @@ -0,0 +1,6 @@ +int script_768(int arg0,int arg1) { + if (getItemAmtInContainer(93, arg1) < 1) { + return 0; + } + return 1; +} diff --git a/dumps/scripts/769.cs2 b/dumps/scripts/769.cs2 new file mode 100644 index 0000000..e6f3e84 --- /dev/null +++ b/dumps/scripts/769.cs2 @@ -0,0 +1,26 @@ +void script_769() { + int ivar0; + int ivar1; + ivar0 = cs2method_3408(111, 111, 1283, standart_config_448); + if (ivar0 == 526) { + setWidgetText(new WidgetPointer(662,66), "0"); + return; + } + ivar1 = getItemAmtInContainer(93, ivar0); + if (ivar1 > 0) { + if (ivar1 > 1000000) { + ivar1 = divide(ivar1, 1000000); + setWidgetText(new WidgetPointer(662,66), intToStr(ivar1) + "M"); + return; + } + if (ivar1 > 1000) { + ivar1 = divide(ivar1, 1000); + setWidgetText(new WidgetPointer(662,66), intToStr(ivar1) + "K"); + return; + } + setWidgetText(new WidgetPointer(662,66), intToStr(getItemAmtInContainer(93, ivar0))); + return; + } + setWidgetText(new WidgetPointer(662,66), "0"); + return; +} diff --git a/dumps/scripts/77.cs2 b/dumps/scripts/77.cs2 new file mode 100644 index 0000000..64586b8 --- /dev/null +++ b/dumps/scripts/77.cs2 @@ -0,0 +1,9 @@ +void script_77(string arg0) { + script_78(globalint_4, arg0); + globalint_4 = add(globalint_4, 1); + if (globalint_4 >= 20) { + globalint_4 = 0; + } + globalint_3 = -1; + return; +} diff --git a/dumps/scripts/770.cs2 b/dumps/scripts/770.cs2 new file mode 100644 index 0000000..95735f8 --- /dev/null +++ b/dumps/scripts/770.cs2 @@ -0,0 +1,231 @@ +void script_770(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12,int arg13,int arg14,int arg15,int arg16,int arg17,int arg18,int arg19,int arg20,int arg21,int arg22,int arg23,string arg24) { + int ivar24; + int ivar25; + int ivar26; + int ivar27; + int ivar28; + int ivar29; + int ivar30; + int ivar31; + deleteAllExtraChilds(new WidgetPointer(arg1)); + ivar24 = getLineCount(177, 495, "Level " + intToStr(arg3) + ": " + arg24); + ivar25 = add(2, multiply(13, ivar24)); + ivar26 = add(2, multiply(13, getLineCount(177, 494, "To craft this you need"))); + ivar27 = add(add(add(add(add(2, ivar25), ivar26), 32), 14), 2); + ivar28 = 5; + ivar29 = 5; + ivar30 = 1; + ivar31 = 1; + if (setWidgetRegister(new WidgetPointer(arg2), arg0)) { + if (arg4 == -1) { + ivar27 = subtract(subtract(ivar27, 32), 14); + } + if (ivar24 > 1) { + if (arg12 != -1) { + ivar27 = add(ivar27, 57); + } + } else { + if (arg12 != -1) { + ivar27 = add(add(ivar27, 32), 14); + } + } + ivar28 = add(subtract(getWidgetActualY(), cs2method2601(new WidgetPointer(arg2))), 110); + if (ivar28 > 200) { + ivar28 = add(subtract(subtract(getWidgetActualY(), cs2method2601(new WidgetPointer(arg2))), ivar27), 45); + } + ivar29 = subtract(getWidgetActualX(), 60); + if (ivar29 < 0) { + ivar29 = 5; + } + if (ivar29 > 270) { + ivar29 = 285; + } + createExtraChild(new WidgetPointer(arg1), 3, 0); + setWidgetPosition(ivar29, ivar28, 0, 0); + setWidgetSize(180, ivar27, 0, 0); + setWidgetFilled(1); + setWidgetRGB(new Color(0, 0, 0)); + cs2method2103(42); + createExtraChild(new WidgetPointer(arg1), 3, 1); + setWidgetPosition(add(ivar29, 1), add(ivar28, 1), 0, 0); + setWidgetSize(179, subtract(ivar27, 1), 0, 0); + setWidgetFilled(0); + setWidgetRGB(new Color(46, 43, 35)); + createExtraChild(new WidgetPointer(arg1), 3, 2); + setWidgetPosition(ivar29, ivar28, 0, 0); + setWidgetSize(179, subtract(ivar27, 1), 0, 0); + setWidgetFilled(0); + setWidgetRGB(new Color(114, 100, 81)); + createExtraChild(new WidgetPointer(arg1), 4, 3); + setWidgetPosition(add(ivar29, 2), add(ivar28, 2), 0, 0); + setWidgetSize(177, ivar25, 0, 0); + setWidgetTextAlignment(1, 1, 0); + setWidgetFont(495); + setWidgetRGB(new Color(255, 152, 31)); + setWidgetUnknownBoolean(false); + setWidgetText("Level " + intToStr(arg3) + ": " + arg24); + createExtraChild(new WidgetPointer(arg1), 4, 4); + setWidgetPosition(ivar29, add(add(ivar28, 2), ivar25), 0, 0); + setWidgetSize(177, ivar26, 0, 0); + setWidgetTextAlignment(1, 1, 0); + setWidgetFont(494); + setWidgetRGB(new Color(175, 106, 26)); + setWidgetUnknownBoolean(false); + setWidgetText("This item requires"); + if (arg6 != -1) { + ivar30 = 2; + } + if (arg8 != -1) { + ivar30 = 3; + } + if (arg10 != -1) { + ivar30 = 4; + } + ivar31 = divide(subtract(190, multiply(ivar30, 35)), add(ivar30, 1)); + if (arg4 != -1) { + createExtraChild(new WidgetPointer(arg1), 5, 5); + setWidgetPosition(add(ivar29, ivar31), add(add(add(ivar28, 2), ivar25), ivar26), 0, 0); + setWidgetSize(35, 32, 0, 0); + setItemOnWidgetMethod1200(arg4, -1); + createExtraChild(new WidgetPointer(arg1), 4, 6); + setWidgetPosition(add(ivar29, ivar31), add(add(add(add(ivar28, 2), ivar25), ivar26), 32), 0, 0); + setWidgetSize(35, 14, 0, 0); + setWidgetTextAlignment(1, 1, 0); + setWidgetFont(494); + if (script_771(arg4) >= arg5) { + setWidgetRGB(new Color(0, 255, 0)); + } else { + setWidgetRGB(new Color(255, 0, 0)); + } + setWidgetUnknownBoolean(false); + setWidgetText(script_781(script_771(arg4)) + "/" + intToStr(arg5)); + } + if (arg6 != -1) { + createExtraChild(new WidgetPointer(arg1), 5, 7); + setWidgetPosition(add(add(ivar29, multiply(ivar31, 2)), 35), add(add(add(ivar28, 2), ivar25), ivar26), 0, 0); + setWidgetSize(35, 32, 0, 0); + setItemOnWidgetMethod1200(arg6, -1); + createExtraChild(new WidgetPointer(arg1), 4, 8); + setWidgetPosition(add(add(ivar29, multiply(ivar31, 2)), 35), add(add(add(add(ivar28, 2), ivar25), ivar26), 32), 0, 0); + setWidgetSize(35, 14, 0, 0); + setWidgetTextAlignment(1, 1, 0); + setWidgetFont(494); + if (script_771(arg6) >= arg7) { + setWidgetRGB(new Color(0, 255, 0)); + } else { + setWidgetRGB(new Color(255, 0, 0)); + } + setWidgetUnknownBoolean(false); + setWidgetText(script_780(script_771(arg6)) + "/" + intToStr(arg7)); + } + if (arg8 != -1) { + createExtraChild(new WidgetPointer(arg1), 5, 9); + setWidgetPosition(add(add(ivar29, multiply(ivar31, 3)), 70), add(add(add(ivar28, 2), ivar25), ivar26), 0, 0); + setWidgetSize(35, 32, 0, 0); + setItemOnWidgetMethod1200(arg8, -1); + createExtraChild(new WidgetPointer(arg1), 4, 10); + setWidgetPosition(add(add(ivar29, multiply(ivar31, 3)), 70), add(add(add(add(ivar28, 2), ivar25), ivar26), 32), 0, 0); + setWidgetSize(35, 14, 0, 0); + setWidgetTextAlignment(1, 1, 0); + setWidgetFont(494); + if (script_771(arg8) >= arg9) { + setWidgetRGB(new Color(0, 255, 0)); + } else { + setWidgetRGB(new Color(255, 0, 0)); + } + setWidgetUnknownBoolean(false); + setWidgetText(script_780(script_771(arg8)) + "/" + intToStr(arg9)); + } + if (arg10 != -1) { + createExtraChild(new WidgetPointer(arg1), 5, 11); + setWidgetPosition(add(add(ivar29, multiply(ivar31, 4)), 105), add(add(add(ivar28, 2), ivar25), ivar26), 0, 0); + setWidgetSize(35, 32, 0, 0); + setItemOnWidgetMethod1200(arg10, -1); + createExtraChild(new WidgetPointer(arg1), 4, 12); + setWidgetPosition(add(add(ivar29, multiply(ivar31, 4)), 105), add(add(add(add(ivar28, 2), ivar25), ivar26), 32), 0, 0); + setWidgetSize(35, 14, 0, 0); + setWidgetTextAlignment(1, 1, 0); + setWidgetFont(494); + if (script_771(arg10) >= arg11) { + setWidgetRGB(new Color(0, 255, 0)); + } else { + setWidgetRGB(new Color(255, 0, 0)); + } + setWidgetUnknownBoolean(false); + setWidgetText(script_780(script_771(arg10)) + "/" + intToStr(arg11)); + } + if (arg12 != -1) { + createExtraChild(new WidgetPointer(arg1), 5, 13); + setWidgetPosition(add(ivar29, ivar31), add(add(add(ivar28, 16), multiply(2, ivar25)), multiply(2, ivar26)), 0, 0); + setWidgetSize(35, 32, 0, 0); + setItemOnWidgetMethod1200(arg12, -1); + createExtraChild(new WidgetPointer(arg1), 4, 14); + setWidgetPosition(add(ivar29, ivar31), add(add(add(add(ivar28, 16), multiply(2, ivar25)), multiply(2, ivar26)), 32), 0, 0); + setWidgetSize(35, 14, 0, 0); + setWidgetTextAlignment(1, 1, 0); + setWidgetFont(494); + if (script_771(arg12) >= arg13) { + setWidgetRGB(new Color(0, 255, 0)); + } else { + setWidgetRGB(new Color(255, 0, 0)); + } + setWidgetUnknownBoolean(false); + setWidgetText(script_780(script_771(arg12)) + "/" + intToStr(arg13)); + } + if (arg14 != -1) { + createExtraChild(new WidgetPointer(arg1), 5, 15); + setWidgetPosition(add(add(ivar29, multiply(ivar31, 2)), 35), add(add(add(ivar28, 16), multiply(2, ivar25)), multiply(2, ivar26)), 0, 0); + setWidgetSize(35, 32, 0, 0); + setItemOnWidgetMethod1200(arg14, -1); + createExtraChild(new WidgetPointer(arg1), 4, 16); + setWidgetPosition(add(add(ivar29, multiply(ivar31, 2)), 35), add(add(add(add(ivar28, 16), multiply(2, ivar25)), multiply(2, ivar26)), 32), 0, 0); + setWidgetSize(35, 14, 0, 0); + setWidgetTextAlignment(1, 1, 0); + setWidgetFont(494); + if (script_771(arg14) >= arg15) { + setWidgetRGB(new Color(0, 255, 0)); + } else { + setWidgetRGB(new Color(255, 0, 0)); + } + setWidgetUnknownBoolean(false); + setWidgetText(script_780(script_771(arg14)) + "/" + intToStr(arg15)); + } + if (arg16 != -1) { + createExtraChild(new WidgetPointer(arg1), 5, 15); + setWidgetPosition(add(add(add(ivar29, multiply(ivar31, 3)), 35), 2), add(add(add(ivar28, 16), multiply(2, ivar25)), multiply(2, ivar26)), 0, 0); + setWidgetSize(35, 32, 0, 0); + setItemOnWidgetMethod1200(arg16, -1); + createExtraChild(new WidgetPointer(arg1), 4, 16); + setWidgetPosition(add(add(add(ivar29, multiply(ivar31, 3)), 35), 2), add(add(add(add(ivar28, 16), multiply(2, ivar25)), multiply(2, ivar26)), 32), 0, 0); + setWidgetSize(35, 14, 0, 0); + setWidgetTextAlignment(1, 1, 0); + setWidgetFont(494); + if (script_771(arg16) >= arg17) { + setWidgetRGB(new Color(0, 255, 0)); + } else { + setWidgetRGB(new Color(255, 0, 0)); + } + setWidgetUnknownBoolean(false); + setWidgetText(script_780(script_771(arg16)) + "/" + intToStr(arg17)); + } + if (arg18 != -1) { + createExtraChild(new WidgetPointer(arg1), 5, 15); + setWidgetPosition(add(add(add(ivar29, multiply(ivar31, 4)), 35), 3), add(add(add(ivar28, 16), multiply(2, ivar25)), multiply(2, ivar26)), 0, 0); + setWidgetSize(35, 32, 0, 0); + setItemOnWidgetMethod1200(arg18, -1); + createExtraChild(new WidgetPointer(arg1), 4, 16); + setWidgetPosition(add(add(add(ivar29, multiply(ivar31, 4)), 35), 3), add(add(add(add(ivar28, 16), multiply(2, ivar25)), multiply(2, ivar26)), 32), 0, 0); + setWidgetSize(35, 14, 0, 0); + setWidgetTextAlignment(1, 1, 0); + setWidgetFont(494); + if (script_771(arg18) >= arg19) { + setWidgetRGB(new Color(0, 255, 0)); + } else { + setWidgetRGB(new Color(255, 0, 0)); + } + setWidgetUnknownBoolean(false); + setWidgetText(script_780(script_771(arg18)) + "/" + intToStr(arg19)); + } + } + return; +} diff --git a/dumps/scripts/771.cs2 b/dumps/scripts/771.cs2 new file mode 100644 index 0000000..7ab2abe --- /dev/null +++ b/dumps/scripts/771.cs2 @@ -0,0 +1,11 @@ +int script_771(int arg0) { + switch (arg0) { + case 6287: + return add(getItemAmtInContainer(93, 6287), getItemAmtInContainer(93, 7801)); + case 6979: + return add(add(getItemAmtInContainer(93, 6979), getItemAmtInContainer(93, 6981)), getItemAmtInContainer(93, 6983)); + case 2462: + return add(add(add(add(add(add(getItemAmtInContainer(93, 2462), getItemAmtInContainer(93, 2460)), getItemAmtInContainer(93, 2464)), getItemAmtInContainer(93, 2466)), getItemAmtInContainer(93, 2468)), getItemAmtInContainer(93, 2470)), getItemAmtInContainer(93, 2472)); + } + return script_1(93, arg0); +} diff --git a/dumps/scripts/772.cs2 b/dumps/scripts/772.cs2 new file mode 100644 index 0000000..cf44870 --- /dev/null +++ b/dumps/scripts/772.cs2 @@ -0,0 +1,5 @@ +void script_772(int arg0) { + script_1184(arg0); + setScriptCallOnGeneralDataChange(838, new WidgetPointer(arg0), "I", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/773.cs2 b/dumps/scripts/773.cs2 new file mode 100644 index 0000000..9a1f22c --- /dev/null +++ b/dumps/scripts/773.cs2 @@ -0,0 +1,34 @@ +void script_773(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12) { + if (isWidgetHidden(new WidgetPointer(arg1))) { + if ((arg5 != -1) && (script_19(arg5, arg0) < arg6)) { + setWidgetSprite(arg3, new WidgetPointer(arg0)); + return; + } + if ((arg7 != -1) && (script_19(arg7, arg0) < arg8)) { + setWidgetSprite(arg3, new WidgetPointer(arg0)); + return; + } + if ((arg9 != -1) && (script_19(arg9, arg0) < arg10)) { + setWidgetSprite(arg3, new WidgetPointer(arg0)); + return; + } + if ((arg11 != -1) && (script_19(arg11, arg0) < arg12)) { + setWidgetSprite(arg3, new WidgetPointer(arg0)); + return; + } + if (getSkillActualLvl(23) < arg4) { + if (((boolean)bitconfig_4089)) { + if ((standart_config_1092 < arg4) || ((boolean)cs2method_3408(73, 105, 1061, arg0))) { + setWidgetSprite(arg3, new WidgetPointer(arg0)); + return; + } + } else { + setWidgetSprite(arg3, new WidgetPointer(arg0)); + return; + } + } else { + setWidgetSprite(arg2, new WidgetPointer(arg0)); + } + } + return; +} diff --git a/dumps/scripts/774.cs2 b/dumps/scripts/774.cs2 new file mode 100644 index 0000000..f9ee065 --- /dev/null +++ b/dumps/scripts/774.cs2 @@ -0,0 +1,5 @@ +void script_774(int arg0,int arg1) { + setItemOnWidgetMethod2205(standart_config_851, 1, new WidgetPointer(arg0)); + setItemOnWidgetMethod2205(standart_config_852, 1, new WidgetPointer(arg1)); + return; +} diff --git a/dumps/scripts/775.cs2 b/dumps/scripts/775.cs2 new file mode 100644 index 0000000..ac6d95e --- /dev/null +++ b/dumps/scripts/775.cs2 @@ -0,0 +1,30 @@ +cs2func_script_775_struct(2,1,0) script_775() { + flow_0: + SWITCH (standart_config_448) { + case 12073: + GOTO flow_1 + case 12075: + GOTO flow_2 + case 12077: + GOTO flow_3 + case 12079: + GOTO flow_4 + case 12081: + GOTO flow_5 + case 12083: + GOTO flow_6 + } + return newstruct cs2func_script_775_struct(36, 12461, "Bronze Bull Rush"); + flow_1: + return newstruct cs2func_script_775_struct(36, 12461, "Bronze Bull Rush"); + flow_2: + return newstruct cs2func_script_775_struct(46, 12462, "Iron Bull Rush"); + flow_3: + return newstruct cs2func_script_775_struct(56, 12463, "Steel Bull Rush"); + flow_4: + return newstruct cs2func_script_775_struct(66, 12464, "Mithril Bull Rush"); + flow_5: + return newstruct cs2func_script_775_struct(76, 12465, "Adamant Bull Rush"); + flow_6: + return newstruct cs2func_script_775_struct(86, 12466, "Rune Bull Rush"); +} diff --git a/dumps/scripts/776.cs2 b/dumps/scripts/776.cs2 new file mode 100644 index 0000000..43a3441 --- /dev/null +++ b/dumps/scripts/776.cs2 @@ -0,0 +1,40 @@ +void script_776() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + string svar0; + string svar1; + string svar2; + ivar0 = 0; + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + svar0 = "Hello"; + svar1 = "00:00"; + svar2 = "1.1x"; + if (((boolean)bitconfig_7232)) { + ivar0 = divide(bitconfig_7233, 60); + ivar1 = mod(bitconfig_7233, 60); + ivar2 = divide(script_338(16), 1000); + ivar3 = divide(mod(script_338(16), 1000), 100); + if (ivar1 < 10) { + if (ivar0 < 10) { + svar1 = "0" + intToStr(ivar0) + ":0" + intToStr(ivar1); + } else { + svar1 = intToStr(ivar0) + ":0" + intToStr(ivar1); + } + } else if (ivar0 < 10) { + svar1 = "0" + intToStr(ivar0) + ":" + intToStr(ivar1); + } else { + svar1 = intToStr(ivar0) + ":" + intToStr(ivar1); + } + svar2 = intToStr(ivar2) + "." + intToStr(ivar3) + "x"; + svar0 = "Multiplier:" + "" + svar2 + "" + "
" + "Elapsed:" + "" + svar1 + "" + "
" + "Bonus:" + "" + intToStr(divide(standart_config_1878, 10)) + "xp" + ""; + setScriptCallOnMouseOver(38, new WidgetPointer(746,190), new WidgetPointer(746,186), svar0, 0, 500, "IIsii", new WidgetPointer(746,190)); + setScriptCallOnMouseExit(40, new WidgetPointer(746,186), "I", new WidgetPointer(746,190)); + setScriptCallOnMouseOver(38, new WidgetPointer(548,27), new WidgetPointer(548,23), svar0, 0, 500, "IIsii", new WidgetPointer(548,27)); + setScriptCallOnMouseExit(40, new WidgetPointer(548,23), "I", new WidgetPointer(548,27)); + } + return; +} diff --git a/dumps/scripts/777.cs2 b/dumps/scripts/777.cs2 new file mode 100644 index 0000000..155b663 --- /dev/null +++ b/dumps/scripts/777.cs2 @@ -0,0 +1,48 @@ +void script_777(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + deleteAllExtraChilds(new WidgetPointer(arg1)); + ivar4 = add(2, multiply(13, getLineCount(125, 495, intToStr(standart_config_1177) + "/60 special move points remaining"))); + ivar5 = add(add(add(add(2, ivar4), 32), 14), 2); + ivar6 = 5; + ivar7 = 5; + ivar8 = 1; + ivar9 = 1; + ivar5 = subtract(subtract(ivar5, 32), 14); + ivar6 = getWidgetActualY(new WidgetPointer(arg0)); + if (ivar6 == 224) { + ivar6 = 180; + } + ivar7 = subtract(getWidgetActualX(new WidgetPointer(arg0)), 60); + if (ivar7 < 0) { + ivar7 = 5; + } + createExtraChild(new WidgetPointer(arg1), 3, 0); + setWidgetPosition(ivar7, ivar6, 0, 0); + setWidgetSize(128, ivar5, 0, 0); + setWidgetFilled(1); + setWidgetRGB(new Color(255, 255, 160)); + createExtraChild(new WidgetPointer(arg1), 3, 1); + setWidgetPosition(add(ivar7, 1), add(ivar6, 1), 0, 0); + setWidgetSize(127, subtract(ivar5, 1), 0, 0); + setWidgetFilled(0); + setWidgetRGB(new Color(0, 0, 0)); + createExtraChild(new WidgetPointer(arg1), 3, 2); + setWidgetPosition(ivar7, ivar6, 0, 0); + setWidgetSize(127, subtract(ivar5, 1), 0, 0); + setWidgetFilled(0); + setWidgetRGB(new Color(0, 0, 0)); + createExtraChild(new WidgetPointer(arg1), 4, 3); + setWidgetPosition(add(ivar7, 2), add(ivar6, 2), 0, 0); + setWidgetSize(125, ivar4, 0, 0); + setWidgetTextAlignment(1, 1, 0); + setWidgetFont(495); + setWidgetRGB(new Color(0, 0, 0)); + setWidgetUnknownBoolean(false); + setWidgetText(intToStr(standart_config_1177) + "/60 special move points remaining"); + return; +} diff --git a/dumps/scripts/778.cs2 b/dumps/scripts/778.cs2 new file mode 100644 index 0000000..f9f6aab --- /dev/null +++ b/dumps/scripts/778.cs2 @@ -0,0 +1,4 @@ +void script_778(int arg0) { + deleteAllExtraChilds(new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/779.cs2 b/dumps/scripts/779.cs2 new file mode 100644 index 0000000..a739e81 --- /dev/null +++ b/dumps/scripts/779.cs2 @@ -0,0 +1,57 @@ +void script_779(int arg0,int arg1,int arg2,int arg3,string arg4) { + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + deleteAllExtraChilds(new WidgetPointer(arg1)); + if (((boolean)stringMethod4107(arg4, "Call familiar")) && (cs2method_3408(111, 111, 1283, standart_config_448) == 526)) { + arg4 = "Call pet"; + } + if (((boolean)stringMethod4107(arg4, "Dismiss familiar")) && (cs2method_3408(111, 111, 1283, standart_config_448) == 526)) { + arg4 = "Dismiss pet"; + } + ivar4 = add(2, multiply(13, getLineCount(125, 495, arg4))); + ivar5 = add(add(add(add(2, ivar4), 32), 14), 2); + ivar6 = 5; + ivar7 = 5; + ivar8 = 1; + ivar9 = 1; + ivar5 = subtract(subtract(ivar5, 32), 14); + ivar6 = getWidgetActualY(new WidgetPointer(arg0)); + if ((ivar6 == 225) && (getWidgetActualX(new WidgetPointer(arg0)) == 83)) { + ivar6 = 180; + } + ivar7 = subtract(getWidgetActualX(new WidgetPointer(arg0)), 60); + if (ivar7 < 0) { + ivar7 = 5; + } + if (ivar7 > 70) { + ivar7 = 65; + } + createExtraChild(new WidgetPointer(arg1), 3, 0); + setWidgetPosition(ivar7, ivar6, 0, 0); + setWidgetSize(128, ivar5, 0, 0); + setWidgetFilled(1); + setWidgetRGB(new Color(255, 255, 160)); + createExtraChild(new WidgetPointer(arg1), 3, 1); + setWidgetPosition(add(ivar7, 1), add(ivar6, 1), 0, 0); + setWidgetSize(127, subtract(ivar5, 1), 0, 0); + setWidgetFilled(0); + setWidgetRGB(new Color(0, 0, 0)); + createExtraChild(new WidgetPointer(arg1), 3, 2); + setWidgetPosition(ivar7, ivar6, 0, 0); + setWidgetSize(127, subtract(ivar5, 1), 0, 0); + setWidgetFilled(0); + setWidgetRGB(new Color(0, 0, 0)); + createExtraChild(new WidgetPointer(arg1), 4, 3); + setWidgetPosition(add(ivar7, 2), add(ivar6, 2), 0, 0); + setWidgetSize(125, ivar4, 0, 0); + setWidgetTextAlignment(1, 1, 0); + setWidgetFont(495); + setWidgetRGB(new Color(0, 0, 0)); + setWidgetUnknownBoolean(false); + setWidgetText(arg4); + return; +} diff --git a/dumps/scripts/78.cs2 b/dumps/scripts/78.cs2 new file mode 100644 index 0000000..4da0c4b --- /dev/null +++ b/dumps/scripts/78.cs2 @@ -0,0 +1,58 @@ +void script_78(int arg0,string arg1) { + if (arg0 < 10) { + if (arg0 < 5) { + if (((boolean)arg0)) { + globalstring_2 = arg1; + } else if (((boolean)arg0)) { + globalstring_3 = arg1; + } else if (arg0 == 2) { + globalstring_4 = arg1; + } else if (arg0 == 3) { + globalstring_5 = arg1; + } else { + if (arg0 == 4) { + globalstring_6 = arg1; + } + } + } else if (arg0 == 5) { + globalstring_7 = arg1; + } else if (arg0 == 6) { + globalstring_8 = arg1; + } else if (arg0 == 7) { + globalstring_9 = arg1; + } else if (arg0 == 8) { + globalstring_10 = arg1; + } else { + if (arg0 == 9) { + globalstring_11 = arg1; + } + } + } else if (arg0 < 15) { + if (arg0 == 10) { + globalstring_12 = arg1; + } else if (arg0 == 11) { + globalstring_13 = arg1; + } else if (arg0 == 12) { + globalstring_14 = arg1; + } else if (arg0 == 13) { + globalstring_15 = arg1; + } else { + if (arg0 == 14) { + globalstring_16 = arg1; + } + } + } else if (arg0 == 15) { + globalstring_17 = arg1; + } else if (arg0 == 16) { + globalstring_18 = arg1; + } else if (arg0 == 17) { + globalstring_19 = arg1; + } else if (arg0 == 18) { + globalstring_20 = arg1; + } else { + if (arg0 == 19) { + globalstring_21 = arg1; + } + } + return; +} diff --git a/dumps/scripts/780.cs2 b/dumps/scripts/780.cs2 new file mode 100644 index 0000000..f8cf487 --- /dev/null +++ b/dumps/scripts/780.cs2 @@ -0,0 +1,9 @@ +string script_780(int arg0) { + if (arg0 >= 999999) { + return "*"; + } + if (arg0 >= 10000) { + return concat(intToStr(divide(arg0, 1000)), "K"); + } + return intToStr(arg0); +} diff --git a/dumps/scripts/781.cs2 b/dumps/scripts/781.cs2 new file mode 100644 index 0000000..f9a319e --- /dev/null +++ b/dumps/scripts/781.cs2 @@ -0,0 +1,6 @@ +string script_781(int arg0) { + if (arg0 >= 1000) { + return "*"; + } + return intToStr(arg0); +} diff --git a/dumps/scripts/782.cs2 b/dumps/scripts/782.cs2 new file mode 100644 index 0000000..77c02cc --- /dev/null +++ b/dumps/scripts/782.cs2 @@ -0,0 +1,56 @@ +void script_782(int arg0,int arg1,int arg2,int arg3,string arg4) { + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + deleteAllExtraChilds(new WidgetPointer(arg1)); + ivar4 = add(2, multiply(13, getLineCount(177, 495, "This space is reserved"))); + ivar5 = add(2, multiply(13, getLineCount(177, 494, "You cannot make this pouch."))); + ivar6 = add(add(add(add(add(2, ivar4), ivar5), 32), 14), 2); + ivar7 = 5; + ivar8 = 5; + ivar9 = 1; + ivar10 = 1; + if (setWidgetRegister(new WidgetPointer(arg2), arg0)) { + ivar6 = subtract(subtract(ivar6, 32), 14); + ivar7 = add(subtract(getWidgetActualY(), cs2method2601(new WidgetPointer(arg2))), 110); + if (ivar7 > 200) { + ivar7 = add(subtract(subtract(getWidgetActualY(), cs2method2601(new WidgetPointer(arg2))), ivar6), 45); + } + ivar8 = subtract(getWidgetActualX(), 60); + if (ivar8 < 0) { + ivar8 = 5; + } + if (ivar8 > 270) { + ivar8 = 285; + } + createExtraChild(new WidgetPointer(arg1), 3, 0); + setWidgetPosition(ivar8, ivar7, 0, 0); + setWidgetSize(180, ivar6, 0, 0); + setWidgetFilled(1); + setWidgetRGB(new Color(0, 0, 0)); + cs2method2103(42); + createExtraChild(new WidgetPointer(arg1), 3, 1); + setWidgetPosition(add(ivar8, 1), add(ivar7, 1), 0, 0); + setWidgetSize(179, subtract(ivar6, 1), 0, 0); + setWidgetFilled(0); + setWidgetRGB(new Color(46, 43, 35)); + createExtraChild(new WidgetPointer(arg1), 3, 2); + setWidgetPosition(ivar8, ivar7, 0, 0); + setWidgetSize(179, subtract(ivar6, 1), 0, 0); + setWidgetFilled(0); + setWidgetRGB(new Color(114, 100, 81)); + createExtraChild(new WidgetPointer(arg1), 4, 3); + setWidgetPosition(add(ivar8, 2), add(ivar7, 2), 0, 0); + setWidgetSize(177, ivar4, 0, 0); + setWidgetTextAlignment(1, 1, 0); + setWidgetFont(495); + setWidgetRGB(new Color(255, 152, 31)); + setWidgetUnknownBoolean(false); + setWidgetText("This space is reserved."); + } + return; +} diff --git a/dumps/scripts/783.cs2 b/dumps/scripts/783.cs2 new file mode 100644 index 0000000..0479771 --- /dev/null +++ b/dumps/scripts/783.cs2 @@ -0,0 +1,15 @@ +void script_783() { + if (bitconfig_4762 != globalint_155) { + globalint_155 = bitconfig_4762; + if (((boolean)bitconfig_4762)) { + script_1029(1484, 9); + } else if (bitconfig_4762 == 2) { + script_1032(1486, 0, 7); + } else { + if (bitconfig_4762 == 3) { + script_1030(1485); + } + } + } + return; +} diff --git a/dumps/scripts/784.cs2 b/dumps/scripts/784.cs2 new file mode 100644 index 0000000..ebe52c7 --- /dev/null +++ b/dumps/scripts/784.cs2 @@ -0,0 +1,4 @@ +void script_784(int arg0,int arg1,int arg2) { + script_1032(arg0, arg1, arg2); + return; +} diff --git a/dumps/scripts/785.cs2 b/dumps/scripts/785.cs2 new file mode 100644 index 0000000..8cc079c --- /dev/null +++ b/dumps/scripts/785.cs2 @@ -0,0 +1,86 @@ +void script_785(int arg0) { + globalint_988 = 0; + globalint_989 = 0; + globalint_990 = 0; + globalint_991 = 0; + switch (arg0) { + case 12582919: + globalint_988 = 1; + if (((boolean)bitconfig_6459)) { + setWidgetSprite(1702, new WidgetPointer(arg0)); + } + break; + case 12582921: + globalint_989 = 1; + if (((boolean)bitconfig_6462)) { + setWidgetSprite(1702, new WidgetPointer(arg0)); + } + break; + case 12582923: + globalint_990 = 1; + if (((boolean)bitconfig_6461)) { + setWidgetSprite(1702, new WidgetPointer(arg0)); + } + break; + case 12582925: + globalint_991 = 1; + if (((boolean)bitconfig_6460)) { + setWidgetSprite(1702, new WidgetPointer(arg0)); + } + break; + case 28180485: + globalint_988 = 1; + if (((boolean)bitconfig_6463)) { + setWidgetSprite(1702, new WidgetPointer(arg0)); + } + break; + case 28180489: + globalint_990 = 1; + if (((boolean)bitconfig_6464)) { + setWidgetSprite(1702, new WidgetPointer(arg0)); + } + break; + case 28180487: + globalint_989 = 1; + if (((boolean)bitconfig_6465)) { + setWidgetSprite(1702, new WidgetPointer(arg0)); + } + break; + case 12648453: + globalint_988 = 1; + if (((boolean)bitconfig_6466)) { + setWidgetSprite(1702, new WidgetPointer(arg0)); + } + break; + case 12648455: + globalint_989 = 1; + if (((boolean)bitconfig_6467)) { + setWidgetSprite(1702, new WidgetPointer(arg0)); + } + break; + case 62259207: + globalint_988 = 1; + if (((boolean)bitconfig_7348)) { + setWidgetSprite(1702, new WidgetPointer(arg0)); + } + break; + case 62259209: + globalint_989 = 1; + if (((boolean)bitconfig_7351)) { + setWidgetSprite(1702, new WidgetPointer(arg0)); + } + break; + case 62259211: + globalint_990 = 1; + if (((boolean)bitconfig_7350)) { + setWidgetSprite(1702, new WidgetPointer(arg0)); + } + break; + case 62259213: + globalint_991 = 1; + if (((boolean)bitconfig_7349)) { + setWidgetSprite(1702, new WidgetPointer(arg0)); + } + } + return; +} diff --git a/dumps/scripts/786.cs2 b/dumps/scripts/786.cs2 new file mode 100644 index 0000000..79c51ef --- /dev/null +++ b/dumps/scripts/786.cs2 @@ -0,0 +1,20 @@ +void script_786(int arg0) { + if (arg0 == 70254793) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(1072,53)); + } else if (arg0 == 70254805) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(1072,53)); + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(1072,49)); + } else if (arg0 == 70254817) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(1072,57)); + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(1072,49)); + } else if (arg0 == 70254829) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(1072,61)); + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(1072,49)); + } else { + if (arg0 == 70254841) { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(1072,65)); + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(1072,49)); + } + } + return; +} diff --git a/dumps/scripts/787.cs2 b/dumps/scripts/787.cs2 new file mode 100644 index 0000000..73e2ee5 --- /dev/null +++ b/dumps/scripts/787.cs2 @@ -0,0 +1,23 @@ +void script_787(int arg0) { + deleteAllExtraChilds(new WidgetPointer(667,5)); + script_1516(43712517, 375, 125); + script_2647(43712517); + script_2373(arg0, -1); + script_2947(); + script_680(43712577); + setScriptCallOnMouseEntered(95, new WidgetPointer(-32768,3), "I", new WidgetPointer(667,65)); + setScriptCallOnMouseExit(93, new WidgetPointer(-32768,3), "I", new WidgetPointer(667,65)); + setScriptCallOnGlobalStringChange(2782, 321, 322, 323, 324, 325, 5, "Y", new WidgetPointer(arg0)); + if (((boolean)bitconfig_4894)) { + setWidgetIsHidden(false, new WidgetPointer(667,49)); + } else { + setWidgetIsHidden(true, new WidgetPointer(667,49)); + } + script_2957(43712562); + setScriptCallOnMouseEntered(1413, new WidgetPointer(-32768,3), "I", new WidgetPointer(667,50)); + setScriptCallOnMouseExit(1414, new WidgetPointer(-32768,3), "I", new WidgetPointer(667,50)); + setScriptCallOnConfigChange(2371, 1248, 1, "Y", new WidgetPointer(arg0)); + setScriptCallOnGeneralDataChange(690, "", new WidgetPointer(667,25)); + setScriptCallOnGeneralDataChange(690, "", new WidgetPointer(762,121)); + return; +} diff --git a/dumps/scripts/788.cs2 b/dumps/scripts/788.cs2 new file mode 100644 index 0000000..d5c675b --- /dev/null +++ b/dumps/scripts/788.cs2 @@ -0,0 +1,3 @@ +cs2func_script_788_struct(2,0,0) script_788(int arg0,int arg1,int arg2) { + return newstruct cs2func_script_788_struct(add(getWidgetActualX(new WidgetPointer(arg0)), arg1), add(getWidgetActualY(new WidgetPointer(arg0)), arg2)); +} diff --git a/dumps/scripts/789.cs2 b/dumps/scripts/789.cs2 new file mode 100644 index 0000000..e10ac1d --- /dev/null +++ b/dumps/scripts/789.cs2 @@ -0,0 +1,48 @@ +void script_789(int arg0) { + flow_0: + IF ((((((((arg0 == 74645541) || (arg0 == 74645542)) || (arg0 == 74645543)) || (arg0 == 74645545)) || (arg0 == 74645553)) || (arg0 == 74645555)) || (arg0 == 74645556)) || (arg0 == 74645554)) + GOTO flow_1 + IF ((arg0 == 74645557) && isMember()) + GOTO flow_2 + GOTO flow_3 + flow_1: + flow_2: + return; + flow_3: + if ((arg0 == 74645557) && (bitconfig_4302 < 110)) { + return; + } + if ((arg0 == 74645542) && (standart_config_80 < 4)) { + return; + } + if ((arg0 == 74645556) && ((boolean)bitconfig_2187)) { + return; + } + setWidgetIsHidden(true, new WidgetPointer(1139,4)); + setWidgetIsHidden(true, new WidgetPointer(1139,21)); + setWidgetIsHidden(true, new WidgetPointer(1139,22)); + setWidgetIsHidden(true, new WidgetPointer(1139,23)); + setWidgetIsHidden(true, new WidgetPointer(1139,24)); + setWidgetIsHidden(true, new WidgetPointer(1139,25)); + setWidgetIsHidden(true, new WidgetPointer(1139,27)); + setWidgetIsHidden(true, new WidgetPointer(1139,5)); + setWidgetIsHidden(true, new WidgetPointer(1139,6)); + setWidgetIsHidden(true, new WidgetPointer(1139,8)); + setWidgetIsHidden(true, new WidgetPointer(1139,26)); + setWidgetIsHidden(true, new WidgetPointer(1139,9)); + setWidgetIsHidden(true, new WidgetPointer(1139,12)); + setWidgetIsHidden(true, new WidgetPointer(1139,13)); + setWidgetIsHidden(true, new WidgetPointer(1139,7)); + setWidgetIsHidden(true, new WidgetPointer(1139,15)); + setWidgetIsHidden(true, new WidgetPointer(1139,16)); + setWidgetIsHidden(true, new WidgetPointer(1139,17)); + setWidgetIsHidden(true, new WidgetPointer(1139,18)); + setWidgetIsHidden(true, new WidgetPointer(1139,10)); + setWidgetIsHidden(true, new WidgetPointer(1139,11)); + setWidgetIsHidden(true, new WidgetPointer(1139,19)); + setWidgetIsHidden(true, new WidgetPointer(1139,14)); + setWidgetIsHidden(true, new WidgetPointer(1139,20)); + setWidgetIsHidden(true, new WidgetPointer(1139,28)); + setWidgetIsHidden(false, new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/79.cs2 b/dumps/scripts/79.cs2 new file mode 100644 index 0000000..400ffba --- /dev/null +++ b/dumps/scripts/79.cs2 @@ -0,0 +1,70 @@ +string script_79(int arg0) { + if (arg0 < 10) { + if (arg0 < 5) { + if (((boolean)arg0)) { + return globalstring_2; + } + if (((boolean)arg0)) { + return globalstring_3; + } + if (arg0 == 2) { + return globalstring_4; + } + if (arg0 == 3) { + return globalstring_5; + } + if (arg0 == 4) { + return globalstring_6; + } + } else { + if (arg0 == 5) { + return globalstring_7; + } + if (arg0 == 6) { + return globalstring_8; + } + if (arg0 == 7) { + return globalstring_9; + } + if (arg0 == 8) { + return globalstring_10; + } + if (arg0 == 9) { + return globalstring_11; + } + } + } else if (arg0 < 15) { + if (arg0 == 10) { + return globalstring_12; + } + if (arg0 == 11) { + return globalstring_13; + } + if (arg0 == 12) { + return globalstring_14; + } + if (arg0 == 13) { + return globalstring_15; + } + if (arg0 == 14) { + return globalstring_16; + } + } else { + if (arg0 == 15) { + return globalstring_17; + } + if (arg0 == 16) { + return globalstring_18; + } + if (arg0 == 17) { + return globalstring_19; + } + if (arg0 == 18) { + return globalstring_20; + } + if (arg0 == 19) { + return globalstring_21; + } + } + return ""; +} diff --git a/dumps/scripts/790.cs2 b/dumps/scripts/790.cs2 new file mode 100644 index 0000000..4847c31 --- /dev/null +++ b/dumps/scripts/790.cs2 @@ -0,0 +1,128 @@ +void script_790() { + if (((boolean)standart_config_261)) { + setWidgetIsHidden(false, new WidgetPointer(1139,4)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1139,4)); + } + if (standart_config_261 == 2) { + setWidgetIsHidden(false, new WidgetPointer(1139,21)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1139,21)); + } + if (standart_config_261 == 3) { + setWidgetIsHidden(false, new WidgetPointer(1139,22)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1139,22)); + } + if (standart_config_261 == 4) { + setWidgetIsHidden(false, new WidgetPointer(1139,23)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1139,23)); + } + if (standart_config_261 == 5) { + setWidgetIsHidden(false, new WidgetPointer(1139,24)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1139,24)); + } + if (standart_config_261 == 6) { + setWidgetIsHidden(false, new WidgetPointer(1139,25)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1139,25)); + } + if (standart_config_261 == 7) { + setWidgetIsHidden(false, new WidgetPointer(1139,27)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1139,27)); + } + if (standart_config_261 == 8) { + setWidgetIsHidden(false, new WidgetPointer(1139,5)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1139,5)); + } + if (standart_config_261 == 9) { + setWidgetIsHidden(false, new WidgetPointer(1139,6)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1139,6)); + } + if (standart_config_261 == 10) { + setWidgetIsHidden(false, new WidgetPointer(1139,8)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1139,8)); + } + if (standart_config_261 == 11) { + setWidgetIsHidden(false, new WidgetPointer(1139,26)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1139,26)); + } + if (standart_config_261 == 12) { + setWidgetIsHidden(false, new WidgetPointer(1139,9)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1139,9)); + } + if (standart_config_261 == 13) { + setWidgetIsHidden(false, new WidgetPointer(1139,12)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1139,12)); + } + if (standart_config_261 == 14) { + setWidgetIsHidden(false, new WidgetPointer(1139,13)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1139,13)); + } + if (standart_config_261 == 15) { + setWidgetIsHidden(false, new WidgetPointer(1139,7)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1139,7)); + } + if (standart_config_261 == 16) { + setWidgetIsHidden(false, new WidgetPointer(1139,15)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1139,15)); + } + if (standart_config_261 == 17) { + setWidgetIsHidden(false, new WidgetPointer(1139,16)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1139,16)); + } + if (standart_config_261 == 18) { + setWidgetIsHidden(false, new WidgetPointer(1139,17)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1139,17)); + } + if (standart_config_261 == 19) { + setWidgetIsHidden(false, new WidgetPointer(1139,18)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1139,18)); + } + if (standart_config_261 == 20) { + setWidgetIsHidden(false, new WidgetPointer(1139,10)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1139,10)); + } + if (standart_config_261 == 21) { + setWidgetIsHidden(false, new WidgetPointer(1139,11)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1139,11)); + } + if (standart_config_261 == 22) { + setWidgetIsHidden(false, new WidgetPointer(1139,19)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1139,19)); + } + if (standart_config_261 == 23) { + setWidgetIsHidden(false, new WidgetPointer(1139,14)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1139,14)); + } + if (standart_config_261 == 24) { + setWidgetIsHidden(false, new WidgetPointer(1139,20)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1139,20)); + } + if (standart_config_261 == 25) { + setWidgetIsHidden(false, new WidgetPointer(1139,28)); + } else { + setWidgetIsHidden(true, new WidgetPointer(1139,28)); + } + return; +} diff --git a/dumps/scripts/791.cs2 b/dumps/scripts/791.cs2 new file mode 100644 index 0000000..4ab4506 --- /dev/null +++ b/dumps/scripts/791.cs2 @@ -0,0 +1,5 @@ +void script_791(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5,string arg6,string arg7,string arg8,string arg9) { + script_793(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + setScriptCallOnItemContainerUpdate(792, new WidgetPointer(arg0), arg1, arg2, arg5, arg6, arg7, arg8, arg9, arg3, arg4, 93, 1, "IiisssssiiY", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/792.cs2 b/dumps/scripts/792.cs2 new file mode 100644 index 0000000..592ca2a --- /dev/null +++ b/dumps/scripts/792.cs2 @@ -0,0 +1,4 @@ +void script_792(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5,string arg6,string arg7,string arg8,string arg9) { + script_793(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + return; +} diff --git a/dumps/scripts/793.cs2 b/dumps/scripts/793.cs2 new file mode 100644 index 0000000..ac7e718 --- /dev/null +++ b/dumps/scripts/793.cs2 @@ -0,0 +1,127 @@ +void script_793(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5,string arg6,string arg7,string arg8,string arg9) { + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + int ivar22; + int ivar23; + int ivar24; + int ivar25; + int ivar26; + int ivar27; + int ivar28; + int ivar29; + int ivar30; + int ivar31; + int ivar32; + int ivar33; + int ivar34; + string svar5; + deleteAllExtraChilds(new WidgetPointer(arg0)); + ivar5 = 0; + ivar6 = 0; + setWidgetScrollMax(0, multiply(add(divide(subtract(arg4, arg3), arg1), 1), 57), new WidgetPointer(arg0)); + ivar7 = 0; + ivar8 = 1; + ivar9 = 0; + ivar10 = 0; + ivar11 = -1; + ivar12 = 12525; + ivar13 = 12530; + ivar14 = 2859; + ivar15 = 12527; + ivar16 = -1; + ivar17 = -1; + ivar18 = -1; + ivar19 = -1; + ivar20 = -1; + ivar21 = -1; + ivar22 = 1; + ivar23 = 7; + ivar24 = 1; + ivar25 = 1; + ivar26 = 0; + ivar27 = 0; + ivar28 = 0; + ivar29 = 0; + ivar30 = 0; + ivar31 = 0; + svar5 = "hello"; + ivar32 = 0; + globalarray_0 = new int[10]; + ivar33 = -1; + ivar34 = 0; + while (ivar7 <= subtract(arg4, arg3)) { + ivar5 = add(add(16, multiply(mod(ivar7, arg1), 48)), multiply(mod(ivar7, arg1), 5)); + ivar6 = add(multiply(divide(ivar7, arg1), 52), multiply(divide(ivar7, arg1), 5)); + createExtraChild(new WidgetPointer(arg0), 5, ivar34); + ivar34 = add(ivar34, 1); + setWidgetSize(48, 52, 0, 0); + setWidgetPosition(ivar5, ivar6, 0, 0); + setWidgetSprite(2205); + setScriptCallOnMouseEntered(2724, new WidgetPointer(-32768,3), ivar34, 0, "Ii1"); + setScriptCallOnMouseExit(2724, new WidgetPointer(-32768,3), ivar34, 1, "Ii1"); + createExtraChild(new WidgetPointer(arg0), 5, ivar34); + ivar34 = add(ivar34, 1); + setWidgetSize(48, 52, 0, 0); + setWidgetPosition(ivar5, ivar6, 0, 0); + setWidgetSprite(2206); + setWidgetHidden(1); + createExtraChild(new WidgetPointer(arg0), 5, ivar34); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(add(ivar5, 6), add(ivar6, 4), 0, 0); + ivar33 = cs2method_3408(105, 111, 1182, ivar8); + if (((boolean)ivar8)) { + if (((boolean)script_795(ivar33))) { + script_794(ivar33, ivar33, arg0, ivar34, arg5, arg6, arg7, arg8, arg9); + } else { + script_794(cs2method_3408(105, 111, 1183, ivar8), ivar33, arg0, ivar34, arg5, arg6, arg7, arg8, arg9); + } + } else if (ivar33 == 12292) { + script_794(ivar33, ivar33, arg0, ivar34, arg5, arg6, arg7, arg8, arg9); + } else { + script_794(cs2method_3408(105, 111, 1183, ivar8), ivar33, arg0, ivar34, arg5, arg6, arg7, arg8, arg9); + } + svar5 = cs2method_3408(111, 115, 1187, ivar33); + ivar32 = cs2method_3408(111, 105, 1185, ivar33); + if (((boolean)ivar8)) { + setScriptCallOnMouseOver(770, -2147483643, new WidgetPointer(672,24), new WidgetPointer(672,16), ivar32, svar5, ivar12, 1, ivar13, ivar23, ivar14, ivar24, ivar15, ivar25, ivar16, ivar26, ivar17, ivar27, ivar18, ivar28, ivar19, ivar29, ivar20, ivar30, ivar21, ivar31, "iIIisoioioioioioioioioioi"); + setScriptCallOnMouseExit(40, new WidgetPointer(672,24), "I"); + } else { + svar5 = "You do not have access to this type of Summoning pouch."; + setScriptCallOnMouseOver(800, -2147483643, new WidgetPointer(672,24), new WidgetPointer(672,16), ivar32, svar5, "iIIis"); + setScriptCallOnMouseExit(40, new WidgetPointer(672,24), "I"); + } + ivar34 = add(ivar34, 1); + createExtraChild(new WidgetPointer(arg0), 5, ivar34); + ivar34 = add(ivar34, 1); + setWidgetSize(12, 12, 0, 0); + setWidgetPosition(add(ivar5, 2), add(ivar6, 38), 0, 0); + setItemOnWidgetMethod1205(12183, 1); + createExtraChild(new WidgetPointer(arg0), 4, ivar34); + ivar34 = add(ivar34, 1); + setWidgetSize(31, 12, 0, 0); + setWidgetPosition(add(ivar5, 13), add(ivar6, 39), 0, 0); + setWidgetFont(494); + setWidgetRGB(new Color(255, 255, 255)); + setWidgetTextAlignment(2, 1, 0); + setWidgetText(script_940(getItemHashmapData(ivar33, 541))); + setWidgetUnknownBoolean(true); + ivar7 = add(ivar7, 1); + ivar8 = add(ivar8, 1); + } + return; +} diff --git a/dumps/scripts/794.cs2 b/dumps/scripts/794.cs2 new file mode 100644 index 0000000..12cf292 --- /dev/null +++ b/dumps/scripts/794.cs2 @@ -0,0 +1,26 @@ +void script_794(int arg0,int arg1,int arg2,int arg3,string arg4,string arg5,string arg6,string arg7,string arg8) { + if (setWidgetRegister(new WidgetPointer(arg2), arg3)) { + if (arg0 != -1) { + setItemOnWidgetMethod1200(arg0, -1); + cs2method1305(getItemName(arg1)); + setWidgetContextMenuOption(1, arg4); + setWidgetContextMenuOption(2, arg5); + setWidgetContextMenuOption(3, arg6); + setWidgetContextMenuOption(4, arg7); + setWidgetContextMenuOption(5, arg8); + setWidgetContextMenuOption(6, "Examine" + ""); + setWidgetShadowColor(new Color(51, 51, 51)); + setWidgetBorderThickness(1); + } else { + setItemOnWidgetMethod1200(-1, 0); + cs2method1305(""); + setWidgetContextMenuOption(1, ""); + setWidgetContextMenuOption(2, ""); + setWidgetContextMenuOption(3, ""); + setWidgetContextMenuOption(4, ""); + setWidgetContextMenuOption(5, ""); + setWidgetContextMenuOption(6, ""); + } + } + return; +} diff --git a/dumps/scripts/795.cs2 b/dumps/scripts/795.cs2 new file mode 100644 index 0000000..a7fd745 --- /dev/null +++ b/dumps/scripts/795.cs2 @@ -0,0 +1,15 @@ +int script_795(int arg0) { + if (getItemAmtInContainer(93, 2859) < 1) { + return 0; + } + if (getItemAmtInContainer(93, 12530) < 1) { + return 0; + } + if (getItemAmtInContainer(93, 12527) < 1) { + return 0; + } + if (getItemAmtInContainer(93, 12525) < 1) { + return 0; + } + return 1; +} diff --git a/dumps/scripts/796.cs2 b/dumps/scripts/796.cs2 new file mode 100644 index 0000000..66d77df --- /dev/null +++ b/dumps/scripts/796.cs2 @@ -0,0 +1,5 @@ +void script_796(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5,string arg6,string arg7,string arg8,string arg9) { + script_798(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + setScriptCallOnItemContainerUpdate(797, new WidgetPointer(arg0), arg1, arg2, arg5, arg6, arg7, arg8, arg9, arg3, arg4, 93, 1, "IiisssssiiY", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/797.cs2 b/dumps/scripts/797.cs2 new file mode 100644 index 0000000..07fe31a --- /dev/null +++ b/dumps/scripts/797.cs2 @@ -0,0 +1,4 @@ +void script_797(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5,string arg6,string arg7,string arg8,string arg9) { + script_798(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + return; +} diff --git a/dumps/scripts/798.cs2 b/dumps/scripts/798.cs2 new file mode 100644 index 0000000..da2abf5 --- /dev/null +++ b/dumps/scripts/798.cs2 @@ -0,0 +1,89 @@ +void script_798(int arg0,int arg1,int arg2,int arg3,int arg4,string arg5,string arg6,string arg7,string arg8,string arg9) { + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + string svar5; + deleteAllExtraChilds(new WidgetPointer(arg0)); + ivar5 = 0; + ivar6 = 0; + setWidgetScrollMax(0, multiply(add(divide(subtract(arg4, arg3), arg1), 1), 57), new WidgetPointer(arg0)); + ivar7 = 0; + ivar8 = 1; + ivar9 = 0; + ivar10 = 0; + ivar11 = -1; + ivar12 = -1; + ivar13 = -1; + svar5 = "hello"; + ivar14 = 0; + ivar15 = 0; + while (ivar7 <= subtract(arg4, arg3)) { + ivar5 = add(add(16, multiply(mod(ivar7, arg1), 48)), multiply(mod(ivar7, arg1), 5)); + ivar6 = add(multiply(divide(ivar7, arg1), 52), multiply(divide(ivar7, arg1), 5)); + createExtraChild(new WidgetPointer(arg0), 5, ivar15); + ivar15 = add(ivar15, 1); + setWidgetSize(48, 52, 0, 0); + setWidgetPosition(ivar5, ivar6, 0, 0); + setWidgetSprite(2205); + setScriptCallOnMouseEntered(2724, new WidgetPointer(-32768,3), ivar15, 0, "Ii1"); + setScriptCallOnMouseExit(2724, new WidgetPointer(-32768,3), ivar15, 1, "Ii1"); + createExtraChild(new WidgetPointer(arg0), 5, ivar15); + ivar15 = add(ivar15, 1); + setWidgetSize(48, 52, 0, 0); + setWidgetPosition(ivar5, ivar6, 0, 0); + setWidgetSprite(2206); + setWidgetHidden(1); + createExtraChild(new WidgetPointer(arg0), 5, ivar15); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(add(ivar5, 6), add(ivar6, 4), 0, 0); + ivar12 = cs2method_3408(105, 111, 1277, ivar8); + ivar13 = cs2method_3408(105, 111, 1188, ivar8); + if (((boolean)ivar8)) { + if (((boolean)script_799(ivar13))) { + script_760(ivar13, ivar13, arg0, ivar15, arg5, arg6, arg7, arg8, arg9, ""); + } else { + script_760(cs2method_3408(105, 111, 1184, ivar8), ivar13, arg0, ivar15, arg5, arg6, arg7, arg8, arg9, ""); + } + } else if (ivar13 == 12421) { + script_760(ivar13, ivar13, arg0, ivar15, arg5, arg6, arg7, arg8, arg9, ""); + } else { + script_760(cs2method_3408(105, 111, 1184, ivar8), ivar13, arg0, ivar15, arg5, arg6, arg7, arg8, arg9, ""); + } + svar5 = cs2method_3408(111, 115, 1187, ivar13); + ivar14 = cs2method_3408(111, 105, 1185, ivar12); + if (((boolean)ivar8)) { + setScriptCallOnMouseOver(770, -2147483643, new WidgetPointer(666,23), new WidgetPointer(666,16), ivar14, svar5, 12526, 1, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, "iIIisoioioioioioioioioioi"); + setScriptCallOnMouseExit(40, new WidgetPointer(666,23), "I"); + } else { + svar5 = "You do not have access to this type of scroll."; + setScriptCallOnMouseOver(800, -2147483643, new WidgetPointer(666,23), new WidgetPointer(666,16), ivar14, svar5, "iIIis"); + setScriptCallOnMouseExit(40, new WidgetPointer(666,23), "I"); + } + ivar15 = add(ivar15, 1); + createExtraChild(new WidgetPointer(arg0), 5, ivar15); + ivar15 = add(ivar15, 1); + setWidgetSize(12, 12, 0, 0); + setWidgetPosition(add(ivar5, 2), add(ivar6, 38), 0, 0); + setItemOnWidgetMethod1205(ivar12, 1); + createExtraChild(new WidgetPointer(arg0), 4, ivar15); + ivar15 = add(ivar15, 1); + setWidgetSize(31, 12, 0, 0); + setWidgetPosition(add(ivar5, 13), add(ivar6, 39), 0, 0); + setWidgetFont(494); + setWidgetRGB(new Color(255, 255, 255)); + setWidgetTextAlignment(2, 1, 0); + setWidgetText("1"); + setWidgetUnknownBoolean(true); + ivar7 = add(ivar7, 1); + ivar8 = add(ivar8, 1); + } + return; +} diff --git a/dumps/scripts/799.cs2 b/dumps/scripts/799.cs2 new file mode 100644 index 0000000..d514120 --- /dev/null +++ b/dumps/scripts/799.cs2 @@ -0,0 +1,6 @@ +int script_799(int arg0) { + if (getItemAmtInContainer(93, 12526) < 1) { + return 0; + } + return 1; +} diff --git a/dumps/scripts/8.cs2 b/dumps/scripts/8.cs2 new file mode 100644 index 0000000..8beb0e5 --- /dev/null +++ b/dumps/scripts/8.cs2 @@ -0,0 +1,82 @@ +int script_8(int arg0) { + if (getDisplayMode() >= 2) { + switch (arg0) { + case 0: + return 48889946; + case 1: + return 48889947; + case 2: + return 48889948; + case 3: + return 48889949; + case 4: + return 48889950; + case 5: + return 48889951; + case 6: + return 48889952; + case 7: + return 48889953; + case 8: + return 48889954; + case 9: + return 48889955; + case 10: + return 48889956; + case 11: + return 48889957; + case 12: + return 48889958; + case 13: + return 48889959; + case 14: + return 48889960; + case 15: + return 48889961; + case 95: + return 48889963; + case 99: + return 48889964; + } + } else { + switch (arg0) { + case 0: + return 35913932; + case 1: + return 35913933; + case 2: + return 35913934; + case 3: + return 35913935; + case 4: + return 35913936; + case 5: + return 35913937; + case 6: + return 35913938; + case 7: + return 35913939; + case 8: + return 35913940; + case 9: + return 35913941; + case 10: + return 35913942; + case 11: + return 35913943; + case 12: + return 35913944; + case 13: + return 35913945; + case 14: + return 35913946; + case 15: + return 35913947; + case 95: + return 35913949; + case 99: + return 35913950; + } + } + return -1; +} diff --git a/dumps/scripts/80.cs2 b/dumps/scripts/80.cs2 new file mode 100644 index 0000000..6345795 --- /dev/null +++ b/dumps/scripts/80.cs2 @@ -0,0 +1,30 @@ +void script_80(int arg0) { + int ivar1; + int ivar2; + int ivar3; + ivar1 = 0; + ivar2 = 0; + ivar3 = 0; + while (ivar1 < getItemContainerLength(140)) { + createExtraChild(new WidgetPointer(arg0), 6, ivar1); + setWidgetSize(49, 49, 0, 0); + setWidgetPosition(multiply(56, ivar2), multiply(56, ivar3), 0, 0); + if (getItemIdInSlot(140, ivar1) != -1) { + setItemOnWidgetMethod1200(getItemIdInSlot(140, ivar1), getItemAmtInSlot(140, ivar1)); + setWidget3DRotation(0, 0, 512, 0, 0, 1340); + cs2method1111(1); + cs2method1305(getItemName(getItemIdInSlot(140, ivar1))); + setWidgetContextMenuOption(1, "Move"); + setScriptCallOnClickContextMenu(106, new WidgetPointer(-32768,3), ivar1, -2147483644, "Iii"); + } else { + setWidgetHidden(1); + } + ivar1 = add(ivar1, 1); + ivar2 = add(ivar2, 1); + if (ivar2 == 5) { + ivar2 = 0; + ivar3 = add(ivar3, 1); + } + } + return; +} diff --git a/dumps/scripts/800.cs2 b/dumps/scripts/800.cs2 new file mode 100644 index 0000000..53e5c0d --- /dev/null +++ b/dumps/scripts/800.cs2 @@ -0,0 +1,56 @@ +void script_800(int arg0,int arg1,int arg2,int arg3,string arg4) { + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + deleteAllExtraChilds(new WidgetPointer(arg1)); + ivar4 = add(2, multiply(13, getLineCount(177, 495, "Level " + intToStr(arg3) + ": " + arg4))); + ivar5 = add(2, multiply(13, getLineCount(177, 494, "You cannot make this Summoning pouch."))); + ivar6 = add(add(add(add(add(2, ivar4), ivar5), 32), 14), 2); + ivar7 = 5; + ivar8 = 5; + ivar9 = 1; + ivar10 = 1; + if (setWidgetRegister(new WidgetPointer(arg2), arg0)) { + ivar6 = subtract(subtract(ivar6, 32), 14); + ivar7 = add(subtract(getWidgetActualY(), cs2method2601(new WidgetPointer(arg2))), 110); + if (ivar7 > 200) { + ivar7 = add(subtract(subtract(getWidgetActualY(), cs2method2601(new WidgetPointer(arg2))), ivar6), 45); + } + ivar8 = subtract(getWidgetActualX(), 60); + if (ivar8 < 0) { + ivar8 = 5; + } + if (ivar8 > 270) { + ivar8 = 285; + } + createExtraChild(new WidgetPointer(arg1), 3, 0); + setWidgetPosition(ivar8, ivar7, 0, 0); + setWidgetSize(180, ivar6, 0, 0); + setWidgetFilled(1); + setWidgetRGB(new Color(0, 0, 0)); + cs2method2103(42); + createExtraChild(new WidgetPointer(arg1), 3, 1); + setWidgetPosition(add(ivar8, 1), add(ivar7, 1), 0, 0); + setWidgetSize(179, subtract(ivar6, 1), 0, 0); + setWidgetFilled(0); + setWidgetRGB(new Color(46, 43, 35)); + createExtraChild(new WidgetPointer(arg1), 3, 2); + setWidgetPosition(ivar8, ivar7, 0, 0); + setWidgetSize(179, subtract(ivar6, 1), 0, 0); + setWidgetFilled(0); + setWidgetRGB(new Color(114, 100, 81)); + createExtraChild(new WidgetPointer(arg1), 4, 3); + setWidgetPosition(add(ivar8, 2), add(ivar7, 2), 0, 0); + setWidgetSize(177, ivar4, 0, 0); + setWidgetTextAlignment(1, 1, 0); + setWidgetFont(495); + setWidgetRGB(new Color(255, 152, 31)); + setWidgetUnknownBoolean(false); + setWidgetText(arg4); + } + return; +} diff --git a/dumps/scripts/801.cs2 b/dumps/scripts/801.cs2 new file mode 100644 index 0000000..bc433df --- /dev/null +++ b/dumps/scripts/801.cs2 @@ -0,0 +1,9 @@ +void script_801(int arg0,int arg1) { + setWidgetRGB(new Color(script_805(arg1)), new WidgetPointer(arg0)); + if (arg1 == 5) { + setWidgetText(new WidgetPointer(arg0), intToStr(bitconfig_9816)); + } else { + setWidgetText(new WidgetPointer(arg0), intToStr(getSkillCurrentLvl(arg1))); + } + return; +} diff --git a/dumps/scripts/802.cs2 b/dumps/scripts/802.cs2 new file mode 100644 index 0000000..10c4e8b --- /dev/null +++ b/dumps/scripts/802.cs2 @@ -0,0 +1,154 @@ +cs2func_script_802_struct(1,1,0) script_802(int arg0,int arg1,int arg2,int arg3,string arg4) { + int ivar4; + int ivar5; + int ivar6; + int ivar7; + string svar1; + string svar2; + ivar4 = strLength(arg4); + if (arg0 <= -1) { + arg0 = ivar4; + } else { + arg0 = min(arg0, ivar4); + } + svar1 = ""; + if (arg0 > 0) { + svar1 = substr(0, arg0, arg4); + } + svar2 = ""; + if (arg0 < ivar4) { + svar2 = substr(arg0, ivar4, arg4); + } + ivar5 = 0; + ivar6 = 0; + ivar7 = 0; + if (arg2 == 85) { + ivar5 = strLength(svar1); + if (ivar5 > 1) { + svar1 = substr(0, subtract(ivar5, 1), svar1); + } else { + svar1 = ""; + ivar7 = 1; + } + arg4 = concat(svar1, svar2); + arg0 = max(subtract(arg0, 1), 0); + } else if (arg2 == 101) { + ivar5 = strLength(svar2); + if (ivar5 > 1) { + svar2 = substr(1, ivar5, svar2); + } else { + svar2 = ""; + ivar7 = 1; + } + arg4 = concat(svar1, svar2); + } else { + if (isValidChar(((char)arg3))) { + switch (arg1) { + flow_19: + case 0: + if (((boolean)globalint_1650)) { + ivar6 = 255; + } else { + ivar6 = 80; + } + if (ivar4 < ivar6) { + arg4 = concat(concatChar(((char)arg3), svar1), svar2); + arg0 = add(arg0, 1); + } else { + ivar7 = 1; + } + break; + case 1: + if (isDigit(((char)arg3)) && (ivar4 < 10)) { + arg4 = concat(concatChar(((char)arg3), svar1), svar2); + arg0 = add(arg0, 1); + } else { + ivar7 = 1; + } + break; + case 2: + if (ivar4 < 12) { + arg4 = concat(concatChar(((char)arg3), svar1), svar2); + arg0 = add(arg0, 1); + } else { + ivar7 = 1; + } + break; + case 3: + if (ivar4 < 320) { + arg4 = concat(concatChar(((char)arg3), svar1), svar2); + arg0 = add(arg0, 1); + } else { + ivar7 = 1; + } + break; + case 4: + IF (isAlphaNumeric(((char)arg3))) + GOTO flow_40 + IF ((strIndexof(((char)arg3), 0, " '&,.!-\u00e0\u00c0\u00e1\u00c1\u00e2\u00c2\u00e3\u00c3\u00e4\u00c4\u00e5\u00c5\u00e7\u00c7\u00e8\u00c8\u00e9\u00c9\u00ea\u00ca\u00eb\u00cb\u00ec\u00cc\u00ed\u00cd\u00ee\u00ce\u00ef\u00cf\u00f1\u00d1\u00f2\u00d2\u00f3\u00d3\u00f4\u00d4\u00f5\u00d5\u00f6\u00d6\u00f9\u00d9\u00fa\u00da\u00fb\u00db\u00fc\u00dc\u00fd\u00dd\u00ff") != -1) && (ivar4 < 50)) + GOTO flow_41 + GOTO flow_42 + flow_40: + flow_41: + arg4 = concat(concatChar(((char)arg3), svar1), svar2); + arg0 = add(arg0, 1); + GOTO flow_43 + flow_42: + ivar7 = 1; + flow_43: + break; + case 5: + if (ivar4 < 50) { + arg4 = concat(concatChar(((char)arg3), svar1), svar2); + arg0 = add(arg0, 1); + } else { + ivar7 = 1; + } + break; + case 6: + switch (getLanguage()) { + flow_49: + case 1: + IF (isDigit(((char)arg3))) + GOTO flow_51 + IF (((strIndexof(((char)arg3), 0, "KkMmTt") != -1) && (ivar4 > 0)) && (ivar4 < 10)) + GOTO flow_52 + GOTO flow_61 + flow_51: + flow_52: + if ((((strIndexof(0, arg4, "K") == -1) && (strIndexof(0, arg4, "k") == -1)) && ((strIndexof(0, arg4, "M") == -1) && (strIndexof(0, arg4, "m") == -1))) && ((strIndexof(0, arg4, "T") == -1) && (strIndexof(0, arg4, "t") == -1))) { + arg4 = concat(concatChar(((char)arg3), svar1), svar2); + arg0 = add(arg0, 1); + } else { + ivar7 = 1; + } + GOTO flow_62 + flow_61: + ivar7 = 1; + flow_62: + break; + } + IF (isDigit(((char)arg3))) + GOTO flow_65 + IF (((strIndexof(((char)arg3), 0, "KkMm") != -1) && (ivar4 > 0)) && (ivar4 < 10)) + GOTO flow_66 + GOTO flow_73 + flow_65: + flow_66: + if (((strIndexof(0, arg4, "K") == -1) && (strIndexof(0, arg4, "k") == -1)) && ((strIndexof(0, arg4, "M") == -1) && (strIndexof(0, arg4, "m") == -1))) { + arg4 = concat(concatChar(((char)arg3), svar1), svar2); + arg0 = add(arg0, 1); + } else { + ivar7 = 1; + } + break; + flow_73: + ivar7 = 1; + } + } + } + if (((boolean)ivar7)) { + playSoundEffect2False(4173, 1, 0, 255); + } + return newstruct cs2func_script_802_struct(arg0, arg4); +} diff --git a/dumps/scripts/803.cs2 b/dumps/scripts/803.cs2 new file mode 100644 index 0000000..69ba61a --- /dev/null +++ b/dumps/scripts/803.cs2 @@ -0,0 +1,146 @@ +void script_803() { + string svar0; + svar0 = cs2method_3408(105, 115, 1711, bitconfig_5145); + switch (bitconfig_5145) { + case 1: + setWidgetIsHidden(false, new WidgetPointer(575,17)); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(575,2), svar0, 25, 130, "IIsii", new WidgetPointer(575,17)); + break; + case 2: + setWidgetIsHidden(false, new WidgetPointer(575,18)); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(575,2), svar0, 25, 160, "IIsii", new WidgetPointer(575,18)); + break; + case 3: + setWidgetIsHidden(false, new WidgetPointer(575,19)); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(575,2), svar0, 25, 200, "IIsii", new WidgetPointer(575,19)); + break; + case 4: + setWidgetIsHidden(false, new WidgetPointer(575,20)); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(575,2), svar0, 25, 200, "IIsii", new WidgetPointer(575,20)); + break; + case 5: + setWidgetIsHidden(false, new WidgetPointer(575,21)); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(575,2), svar0, 25, 200, "IIsii", new WidgetPointer(575,21)); + break; + case 6: + setWidgetIsHidden(false, new WidgetPointer(575,22)); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(575,2), svar0, 25, 200, "IIsii", new WidgetPointer(575,22)); + break; + case 7: + setWidgetIsHidden(false, new WidgetPointer(575,23)); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(575,2), svar0, 25, 200, "IIsii", new WidgetPointer(575,23)); + break; + case 8: + setWidgetIsHidden(false, new WidgetPointer(575,24)); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(575,2), svar0, 25, 200, "IIsii", new WidgetPointer(575,24)); + break; + case 9: + setWidgetIsHidden(false, new WidgetPointer(575,25)); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(575,2), svar0, 25, 200, "IIsii", new WidgetPointer(575,25)); + break; + case 10: + setWidgetIsHidden(false, new WidgetPointer(575,26)); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(575,2), svar0, 25, 200, "IIsii", new WidgetPointer(575,26)); + break; + case 11: + setWidgetIsHidden(false, new WidgetPointer(575,27)); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(575,2), svar0, 25, 200, "IIsii", new WidgetPointer(575,27)); + break; + case 12: + setWidgetIsHidden(false, new WidgetPointer(575,28)); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(575,2), svar0, 25, 200, "IIsii", new WidgetPointer(575,28)); + break; + default: + return; + } + globalint_2 = 0; + switch (bitconfig_5145) { + case 1: + if (((boolean)bitconfig_5168)) { + script_804(); + } else { + script_813(bitconfig_5145); + } + break; + case 2: + if (((boolean)bitconfig_5169)) { + script_804(); + } else { + script_813(bitconfig_5145); + } + break; + case 3: + if (((boolean)bitconfig_5170)) { + script_804(); + } else { + script_813(bitconfig_5145); + } + break; + case 4: + if (((boolean)bitconfig_5171)) { + script_804(); + } else { + script_813(bitconfig_5145); + } + break; + case 5: + if (((boolean)bitconfig_5172)) { + script_804(); + } else { + script_813(bitconfig_5145); + } + break; + case 6: + if (((boolean)bitconfig_5173)) { + script_804(); + } else { + script_813(bitconfig_5145); + } + break; + case 7: + if (((boolean)bitconfig_5174)) { + script_804(); + } else { + script_813(bitconfig_5145); + } + break; + case 8: + if (((boolean)bitconfig_5175)) { + script_804(); + } else { + script_813(bitconfig_5145); + } + break; + case 9: + if (((boolean)bitconfig_5176)) { + script_804(); + } else { + script_813(bitconfig_5145); + } + break; + case 10: + if (((boolean)bitconfig_5177)) { + script_804(); + } else { + script_813(bitconfig_5145); + } + break; + case 11: + if (((boolean)bitconfig_5178)) { + script_804(); + } else { + script_813(bitconfig_5145); + } + break; + case 12: + if (((boolean)bitconfig_5179)) { + script_804(); + } else { + script_813(bitconfig_5145); + } + break; + default: + return; + } + return; +} diff --git a/dumps/scripts/804.cs2 b/dumps/scripts/804.cs2 new file mode 100644 index 0000000..c6cda54 --- /dev/null +++ b/dumps/scripts/804.cs2 @@ -0,0 +1,23 @@ +void script_804() { + int ivar0; + setWidgetModel(cs2method_3408(105, 109, 1696, bitconfig_5146), new WidgetPointer(575,3)); + setWidgetModel(cs2method_3408(105, 109, 1696, bitconfig_5147), new WidgetPointer(575,4)); + setWidgetModel(cs2method_3408(105, 109, 1696, bitconfig_5148), new WidgetPointer(575,5)); + setWidgetModel(cs2method_3408(105, 109, 1696, bitconfig_5149), new WidgetPointer(575,6)); + setWidgetModel(cs2method_3408(105, 109, 1696, bitconfig_5150), new WidgetPointer(575,7)); + setWidgetModel(cs2method_3408(105, 109, 1696, bitconfig_5151), new WidgetPointer(575,8)); + setWidgetModel(cs2method_3408(105, 109, 1696, bitconfig_5152), new WidgetPointer(575,9)); + setWidgetModel(cs2method_3408(105, 109, 1696, bitconfig_5153), new WidgetPointer(575,10)); + setWidgetModel(cs2method_3408(105, 109, 1696, bitconfig_5154), new WidgetPointer(575,11)); + setWidgetModel(cs2method_3408(105, 109, 1696, bitconfig_5155), new WidgetPointer(575,12)); + setWidgetModel(cs2method_3408(105, 109, 1696, bitconfig_5156), new WidgetPointer(575,13)); + setWidgetModel(cs2method_3408(105, 109, 1696, bitconfig_5157), new WidgetPointer(575,14)); + setWidgetModel(cs2method_3408(105, 109, 1696, bitconfig_5158), new WidgetPointer(575,15)); + setWidgetModel(cs2method_3408(105, 109, 1696, bitconfig_5159), new WidgetPointer(575,16)); + ivar0 = 14; + while (ivar0 > 0) { + script_1421(ivar0); + ivar0 = subtract(ivar0, 1); + } + return; +} diff --git a/dumps/scripts/805.cs2 b/dumps/scripts/805.cs2 new file mode 100644 index 0000000..bfe6820 --- /dev/null +++ b/dumps/scripts/805.cs2 @@ -0,0 +1,16 @@ +int script_805(int arg0) { + int ivar1; + int ivar2; + ivar1 = script_807(arg0); + ivar2 = 5592405; + if (ivar1 > 75) { + ivar2 = 65280; + } else if (ivar1 > 50) { + ivar2 = 16776960; + } else if (ivar1 > 25) { + ivar2 = 16750623; + } else { + ivar2 = 16711680; + } + return ivar2; +} diff --git a/dumps/scripts/806.cs2 b/dumps/scripts/806.cs2 new file mode 100644 index 0000000..4df09ff --- /dev/null +++ b/dumps/scripts/806.cs2 @@ -0,0 +1,14 @@ +int script_806() { + int ivar0; + ivar0 = 5592405; + if (getRunEnergy() > 75) { + ivar0 = 65280; + } else if (getRunEnergy() > 50) { + ivar0 = 16776960; + } else if (getRunEnergy() > 25) { + ivar0 = 16750623; + } else { + ivar0 = 16711680; + } + return ivar0; +} diff --git a/dumps/scripts/807.cs2 b/dumps/scripts/807.cs2 new file mode 100644 index 0000000..ce8770d --- /dev/null +++ b/dumps/scripts/807.cs2 @@ -0,0 +1,12 @@ +int script_807(int arg0) { + int ivar1; + ivar1 = 0; + if (getSkillActualLvl(arg0) > 0) { + if (arg0 == 5) { + ivar1 = divide(multiply(100, bitconfig_9816), script_5255()); + } else { + ivar1 = divide(multiply(100, getSkillCurrentLvl(arg0)), getSkillActualLvl(arg0)); + } + } + return ivar1; +} diff --git a/dumps/scripts/808.cs2 b/dumps/scripts/808.cs2 new file mode 100644 index 0000000..7319f8b --- /dev/null +++ b/dumps/scripts/808.cs2 @@ -0,0 +1,42 @@ +void script_808() { + int ivar0; + int ivar1; + setWidgetIsHidden(false, new WidgetPointer(748,7)); + ivar0 = multiplyDivide(bitconfig_7198, script_2916(), 100); + ivar1 = mod(getClientCycle(), 32); + if (ivar0 > 25) { + globalint_615 = 0; + if (((script_2916() < 200) && (bitconfig_7198 < 45)) && ((ivar0 < 100) && (getSkillActualLvl(3) > 0))) { + script_1888(); + } else { + globalint_1025 = 0; + } + if (getWidgetShadeColor(new WidgetPointer(748,7)) != 0) { + cs2method2103(0, new WidgetPointer(748,7)); + } else { + return; + } + } else { + if (((boolean)ivar1)) { + if (globalint_615 <= 0) { + globalint_615 = getClientCycle(); + } + if (subtract(getClientCycle(), globalint_615) < 1500) { + playSoundEffect(5644, 1, 0); + } + if (getSkillActualLvl(3) > 0) { + script_1888(); + } + } + if (ivar1 < 8) { + cs2method2103(0, new WidgetPointer(748,7)); + } else if (ivar1 < 16) { + cs2method2103(85, new WidgetPointer(748,7)); + } else if (ivar1 < 24) { + cs2method2103(255, new WidgetPointer(748,7)); + } else { + cs2method2103(85, new WidgetPointer(748,7)); + } + } + return; +} diff --git a/dumps/scripts/809.cs2 b/dumps/scripts/809.cs2 new file mode 100644 index 0000000..008ba8b --- /dev/null +++ b/dumps/scripts/809.cs2 @@ -0,0 +1,4 @@ +void script_809() { + script_810(); + return; +} diff --git a/dumps/scripts/81.cs2 b/dumps/scripts/81.cs2 new file mode 100644 index 0000000..10ef9a5 --- /dev/null +++ b/dumps/scripts/81.cs2 @@ -0,0 +1,8 @@ +void script_81(int arg0) { + if (cs2method5428(49283081, -1)) { + setScriptCallOnGameloop(1559, arg0, "1", new WidgetPointer(752,9)); + return; + } + script_1560(arg0); + return; +} diff --git a/dumps/scripts/810.cs2 b/dumps/scripts/810.cs2 new file mode 100644 index 0000000..63e18cb --- /dev/null +++ b/dumps/scripts/810.cs2 @@ -0,0 +1,21 @@ +void script_810() { + if (isMember() && ((boolean)bitconfig_4280)) { + setWidgetIsHidden(false, new WidgetPointer(747,2)); + setWidgetIsHidden(false, new WidgetPointer(747,3)); + setWidgetIsHidden(false, new WidgetPointer(747,6)); + setWidgetIsHidden(false, new WidgetPointer(747,4)); + setWidgetIsHidden(false, new WidgetPointer(747,7)); + script_817(23); + setWidgetIsHidden(false, new WidgetPointer(747,5)); + setWidgetRGB(new Color(script_805(23)), new WidgetPointer(747,5)); + setWidgetText(new WidgetPointer(747,5), intToStr(getSkillCurrentLvl(23))); + } else { + setWidgetIsHidden(true, new WidgetPointer(747,2)); + setWidgetIsHidden(true, new WidgetPointer(747,3)); + setWidgetIsHidden(true, new WidgetPointer(747,5)); + setWidgetIsHidden(true, new WidgetPointer(747,6)); + setWidgetIsHidden(true, new WidgetPointer(747,4)); + setWidgetIsHidden(true, new WidgetPointer(747,7)); + } + return; +} diff --git a/dumps/scripts/811.cs2 b/dumps/scripts/811.cs2 new file mode 100644 index 0000000..b1fee06 --- /dev/null +++ b/dumps/scripts/811.cs2 @@ -0,0 +1,26 @@ +void script_811(int arg0) { + int ivar1; + ivar1 = 0; + if (arg0 > 1) { + return; + } + if (getDisplayMode() >= 2) { + ivar1 = ((int)isWidgetHidden(new WidgetPointer(746,184))); + } else { + ivar1 = ((int)isWidgetHidden(new WidgetPointer(548,22))); + } + if (((boolean)ivar1)) { + script_3337(); + setWidgetIsHidden(true, new WidgetPointer(548,24)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(548,22)); + setWidgetIsHidden(true, new WidgetPointer(746,187)); + setScriptCallOnGameloop(-1, "", new WidgetPointer(746,184)); + setWidgetIsHidden(false, new WidgetPointer(746,184)); + setWidgetIsHidden(false, new WidgetPointer(548,22)); + } else { + setWidgetIsHidden(true, new WidgetPointer(746,184)); + setWidgetIsHidden(true, new WidgetPointer(548,22)); + } + script_776(); + return; +} diff --git a/dumps/scripts/812.cs2 b/dumps/scripts/812.cs2 new file mode 100644 index 0000000..7e07e95 --- /dev/null +++ b/dumps/scripts/812.cs2 @@ -0,0 +1,32 @@ +void script_812(int arg0) { + setWidgetHidden(1); + if (arg0 == -1) { + return; + } + if (getItemHashmapData(arg0, 740) > 1) { + if (((boolean)script_925(arg0)) && ((boolean)script_926(arg0))) { + return; + } + setWidgetHidden(0); + return; + } + if (((boolean)getItemHashmapData(arg0, 740))) { + if (((boolean)script_925(arg0))) { + return; + } + setWidgetHidden(0); + return; + } + if (((boolean)script_928(arg0))) { + if (((boolean)script_926(arg0))) { + return; + } + setWidgetHidden(0); + return; + } + if (((boolean)script_925(arg0))) { + return; + } + setWidgetHidden(0); + return; +} diff --git a/dumps/scripts/813.cs2 b/dumps/scripts/813.cs2 new file mode 100644 index 0000000..244a1f8 --- /dev/null +++ b/dumps/scripts/813.cs2 @@ -0,0 +1,60 @@ +void script_813(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int stack_dump0; + cs2func_script_814_struct(3,0,0) structdump_1; + cs2func_script_814_struct(3,0,0) structdump_2; + cs2func_script_814_struct(3,0,0) structdump_3; + ivar1 = arg0; + ivar2 = -1; + ivar3 = 0; + ivar4 = -1; + stack_dump0 = arg0; + structdump_1 = script_814(stack_dump0); + ivar2 = structdump_1.intpart_2; + ivar4 = structdump_1.intpart_1; + ivar3 = structdump_1.intpart_0; + setWidgetModel(ivar2, new WidgetPointer(ivar4)); + script_1421(arg0); + ivar1 = subtract(arg0, 1); + while (ivar1 > 0) { + stack_dump0 = ivar1; + structdump_2 = script_814(stack_dump0); + ivar2 = structdump_2.intpart_2; + ivar4 = structdump_2.intpart_1; + ivar3 = structdump_2.intpart_0; + setWidgetModel(ivar2, new WidgetPointer(ivar4)); + script_1421(ivar1); + if (ivar3 > 1) { + ivar1 = subtract(ivar1, 1); + } else { + ivar1 = subtract(ivar1, 1); + while (ivar1 > 0) { + script_818(ivar1); + ivar1 = subtract(ivar1, 1); + } + } + } + ivar1 = add(arg0, 1); + while (ivar1 <= 14) { + stack_dump0 = ivar1; + structdump_3 = script_814(stack_dump0); + ivar2 = structdump_3.intpart_2; + ivar4 = structdump_3.intpart_1; + ivar3 = structdump_3.intpart_0; + setWidgetModel(ivar2, new WidgetPointer(ivar4)); + script_1421(ivar1); + if (ivar3 > 1) { + ivar1 = add(ivar1, 1); + } else { + ivar1 = add(ivar1, 1); + while (ivar1 <= 14) { + script_818(ivar1); + ivar1 = add(ivar1, 1); + } + } + } + return; +} diff --git a/dumps/scripts/814.cs2 b/dumps/scripts/814.cs2 new file mode 100644 index 0000000..76aaa47 --- /dev/null +++ b/dumps/scripts/814.cs2 @@ -0,0 +1,33 @@ +cs2func_script_814_struct(3,0,0) script_814(int arg0) { + switch (arg0) { + case 1: + return newstruct cs2func_script_814_struct(bitconfig_5146, 37683203, cs2method_3408(105, 109, 1696, bitconfig_5146)); + case 2: + return newstruct cs2func_script_814_struct(bitconfig_5147, 37683204, cs2method_3408(105, 109, 1696, bitconfig_5147)); + case 3: + return newstruct cs2func_script_814_struct(bitconfig_5148, 37683205, cs2method_3408(105, 109, 1696, bitconfig_5148)); + case 4: + return newstruct cs2func_script_814_struct(bitconfig_5149, 37683206, cs2method_3408(105, 109, 1696, bitconfig_5149)); + case 5: + return newstruct cs2func_script_814_struct(bitconfig_5150, 37683207, cs2method_3408(105, 109, 1696, bitconfig_5150)); + case 6: + return newstruct cs2func_script_814_struct(bitconfig_5151, 37683208, cs2method_3408(105, 109, 1696, bitconfig_5151)); + case 7: + return newstruct cs2func_script_814_struct(bitconfig_5152, 37683209, cs2method_3408(105, 109, 1696, bitconfig_5152)); + case 8: + return newstruct cs2func_script_814_struct(bitconfig_5153, 37683210, cs2method_3408(105, 109, 1696, bitconfig_5153)); + case 9: + return newstruct cs2func_script_814_struct(bitconfig_5154, 37683211, cs2method_3408(105, 109, 1696, bitconfig_5154)); + case 10: + return newstruct cs2func_script_814_struct(bitconfig_5155, 37683212, cs2method_3408(105, 109, 1696, bitconfig_5155)); + case 11: + return newstruct cs2func_script_814_struct(bitconfig_5156, 37683213, cs2method_3408(105, 109, 1696, bitconfig_5156)); + case 12: + return newstruct cs2func_script_814_struct(bitconfig_5157, 37683214, cs2method_3408(105, 109, 1696, bitconfig_5157)); + case 13: + return newstruct cs2func_script_814_struct(bitconfig_5158, 37683215, cs2method_3408(105, 109, 1696, bitconfig_5158)); + case 14: + return newstruct cs2func_script_814_struct(bitconfig_5159, 37683216, cs2method_3408(105, 109, 1696, bitconfig_5159)); + } + return newstruct cs2func_script_814_struct(-1, -1, -1); +} diff --git a/dumps/scripts/815.cs2 b/dumps/scripts/815.cs2 new file mode 100644 index 0000000..e9b5d36 --- /dev/null +++ b/dumps/scripts/815.cs2 @@ -0,0 +1,4 @@ +void script_815() { + script_817(23); + return; +} diff --git a/dumps/scripts/816.cs2 b/dumps/scripts/816.cs2 new file mode 100644 index 0000000..e2c0452 --- /dev/null +++ b/dumps/scripts/816.cs2 @@ -0,0 +1,4 @@ +void script_816(int arg0,int arg1) { + script_817(arg1); + return; +} diff --git a/dumps/scripts/817.cs2 b/dumps/scripts/817.cs2 new file mode 100644 index 0000000..460ec92 --- /dev/null +++ b/dumps/scripts/817.cs2 @@ -0,0 +1,31 @@ +void script_817(int arg0) { + int ivar1; + int ivar2; + int ivar3; + ivar1 = 31; + ivar2 = 0; + ivar3 = 31; + if (arg0 == 5) { + if (bitconfig_9816 >= script_5255()) { + ivar2 = 0; + } else if (((boolean)getSkillActualLvl(arg0)) || (getSkillActualLvl(arg0) == -1)) { + ivar2 = 0; + } else { + ivar2 = subtract(ivar1, divide(multiply(ivar1, bitconfig_9816), script_5255())); + } + } else if (getSkillCurrentLvl(arg0) >= getSkillActualLvl(arg0)) { + ivar2 = 0; + } else if (((boolean)getSkillActualLvl(arg0)) || (getSkillActualLvl(arg0) == -1)) { + ivar2 = 0; + } else { + ivar2 = subtract(ivar1, divide(multiply(ivar1, getSkillCurrentLvl(arg0)), getSkillActualLvl(arg0))); + } + if (arg0 == 5) { + setWidgetSize(ivar3, ivar2, 0, 0, new WidgetPointer(749,3)); + } else { + if (arg0 == 23) { + setWidgetSize(ivar3, ivar2, 0, 0, new WidgetPointer(747,4)); + } + } + return; +} diff --git a/dumps/scripts/818.cs2 b/dumps/scripts/818.cs2 new file mode 100644 index 0000000..d4bf8d7 --- /dev/null +++ b/dumps/scripts/818.cs2 @@ -0,0 +1,63 @@ +void script_818(int arg0) { + string svar0; + svar0 = "No information is available about this beacon."; + switch (arg0) { + case 1: + setWidgetModel(41805, new WidgetPointer(575,3)); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(575,2), svar0, 25, 130, "IIsii", new WidgetPointer(575,3)); + break; + case 2: + setWidgetModel(41805, new WidgetPointer(575,4)); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(575,2), svar0, 25, 160, "IIsii", new WidgetPointer(575,4)); + break; + case 3: + setWidgetModel(41805, new WidgetPointer(575,5)); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(575,2), svar0, 25, 200, "IIsii", new WidgetPointer(575,5)); + break; + case 4: + setWidgetModel(41805, new WidgetPointer(575,6)); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(575,2), svar0, 25, 200, "IIsii", new WidgetPointer(575,6)); + break; + case 5: + setWidgetModel(41805, new WidgetPointer(575,7)); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(575,2), svar0, 25, 200, "IIsii", new WidgetPointer(575,7)); + break; + case 6: + setWidgetModel(41805, new WidgetPointer(575,8)); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(575,2), svar0, 25, 200, "IIsii", new WidgetPointer(575,8)); + break; + case 7: + setWidgetModel(41805, new WidgetPointer(575,9)); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(575,2), svar0, 25, 200, "IIsii", new WidgetPointer(575,9)); + break; + case 8: + setWidgetModel(41805, new WidgetPointer(575,10)); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(575,2), svar0, 25, 200, "IIsii", new WidgetPointer(575,10)); + break; + case 9: + setWidgetModel(41805, new WidgetPointer(575,11)); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(575,2), svar0, 25, 200, "IIsii", new WidgetPointer(575,11)); + break; + case 10: + setWidgetModel(41805, new WidgetPointer(575,12)); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(575,2), svar0, 25, 200, "IIsii", new WidgetPointer(575,12)); + break; + case 11: + setWidgetModel(41805, new WidgetPointer(575,13)); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(575,2), svar0, 25, 200, "IIsii", new WidgetPointer(575,13)); + break; + case 12: + setWidgetModel(41805, new WidgetPointer(575,14)); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(575,2), svar0, 25, 200, "IIsii", new WidgetPointer(575,14)); + break; + case 13: + setWidgetModel(41805, new WidgetPointer(575,15)); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(575,2), svar0, 25, 200, "IIsii", new WidgetPointer(575,15)); + break; + case 14: + setWidgetModel(41805, new WidgetPointer(575,16)); + setScriptCallOnMouseOver(38, new WidgetPointer(-32768,3), new WidgetPointer(575,2), svar0, 25, 200, "IIsii", new WidgetPointer(575,16)); + } + globalint_2 = 0; + return; +} diff --git a/dumps/scripts/819.cs2 b/dumps/scripts/819.cs2 new file mode 100644 index 0000000..e2b48d9 --- /dev/null +++ b/dumps/scripts/819.cs2 @@ -0,0 +1,21 @@ +void script_819() { + if ((standart_config_1174 != -1) && (standart_config_1174 != 0)) { + setWidgetNpcHead(standart_config_1174, new WidgetPointer(663,3)); + } else { + setWidgetModel(-1, new WidgetPointer(663,3)); + } + if (((boolean)bitconfig_1049)) { + setWidgetText(new WidgetPointer(663,25), script_821()); + } else if (standart_config_448 != -1) { + setWidgetText(new WidgetPointer(663,25), getItemName(standart_config_448)); + } else { + setWidgetText(new WidgetPointer(663,25), ""); + } + if (bitconfig_4282 > 50) { + bitconfig_4282 = subtract(bitconfig_4282, 50); + setWidgetAnimation(cs2method_3408(105, 65, 1275, bitconfig_4282), new WidgetPointer(663,3)); + } else { + setWidgetAnimation(cs2method_3408(105, 65, 1276, bitconfig_4282), new WidgetPointer(663,3)); + } + return; +} diff --git a/dumps/scripts/82.cs2 b/dumps/scripts/82.cs2 new file mode 100644 index 0000000..097bd59 --- /dev/null +++ b/dumps/scripts/82.cs2 @@ -0,0 +1,6 @@ +void script_82() { + if (getSystemUpdateTimer() > 0) { + script_89(); + } + return; +} diff --git a/dumps/scripts/820.cs2 b/dumps/scripts/820.cs2 new file mode 100644 index 0000000..c7fa189 --- /dev/null +++ b/dumps/scripts/820.cs2 @@ -0,0 +1,18 @@ +void script_820() { + if (bitconfig_4286 != 101) { + setWidgetText(new WidgetPointer(663,19), intToStr(bitconfig_4286) + "%"); + if (bitconfig_4286 > 74) { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(663,19)); + } else { + setWidgetRGB(new Color(255, 255, 255), new WidgetPointer(663,19)); + } + } else { + setWidgetText(new WidgetPointer(663,19), "NA"); + } + if (bitconfig_4285 != 101) { + setWidgetText(new WidgetPointer(663,17), intToStr(bitconfig_4285) + "%"); + } else { + setWidgetText(new WidgetPointer(663,17), "NA"); + } + return; +} diff --git a/dumps/scripts/821.cs2 b/dumps/scripts/821.cs2 new file mode 100644 index 0000000..7159008 --- /dev/null +++ b/dumps/scripts/821.cs2 @@ -0,0 +1,11 @@ +string script_821() { + string svar0; + svar0 = ""; + svar0 = script_822(bitconfig_1043, 1, svar0); + svar0 = script_822(bitconfig_1044, 0, svar0); + svar0 = script_822(bitconfig_1045, 0, svar0); + svar0 = script_822(bitconfig_1046, 0, svar0); + svar0 = script_822(bitconfig_1047, 0, svar0); + svar0 = script_822(bitconfig_1048, 0, svar0); + return svar0; +} diff --git a/dumps/scripts/822.cs2 b/dumps/scripts/822.cs2 new file mode 100644 index 0000000..b8476ac --- /dev/null +++ b/dumps/scripts/822.cs2 @@ -0,0 +1,10 @@ +string script_822(int arg0,int arg1,string arg2) { + int ivar2; + ivar2 = arg0; + if (((boolean)arg1)) { + arg2 = script_823(ivar2, arg2); + } else { + arg2 = script_824(ivar2, arg2); + } + return arg2; +} diff --git a/dumps/scripts/823.cs2 b/dumps/scripts/823.cs2 new file mode 100644 index 0000000..a2c539e --- /dev/null +++ b/dumps/scripts/823.cs2 @@ -0,0 +1,111 @@ +string script_823(int arg0,string arg1) { + if (((boolean)arg0)) { + arg1 = concat(arg1, " "); + return arg1; + } + if (((boolean)arg0)) { + arg1 = concat(arg1, "A"); + return arg1; + } + if (arg0 == 2) { + arg1 = concat(arg1, "B"); + return arg1; + } + if (arg0 == 3) { + arg1 = concat(arg1, "C"); + return arg1; + } + if (arg0 == 4) { + arg1 = concat(arg1, "D"); + return arg1; + } + if (arg0 == 5) { + arg1 = concat(arg1, "E"); + return arg1; + } + if (arg0 == 6) { + arg1 = concat(arg1, "F"); + return arg1; + } + if (arg0 == 7) { + arg1 = concat(arg1, "G"); + return arg1; + } + if (arg0 == 8) { + arg1 = concat(arg1, "H"); + return arg1; + } + if (arg0 == 9) { + arg1 = concat(arg1, "I"); + return arg1; + } + if (arg0 == 10) { + arg1 = concat(arg1, "J"); + return arg1; + } + if (arg0 == 11) { + arg1 = concat(arg1, "K"); + return arg1; + } + if (arg0 == 12) { + arg1 = concat(arg1, "L"); + return arg1; + } + if (arg0 == 13) { + arg1 = concat(arg1, "M"); + return arg1; + } + if (arg0 == 14) { + arg1 = concat(arg1, "N"); + return arg1; + } + if (arg0 == 15) { + arg1 = concat(arg1, "O"); + return arg1; + } + if (arg0 == 16) { + arg1 = concat(arg1, "P"); + return arg1; + } + if (arg0 == 17) { + arg1 = concat(arg1, "Q"); + return arg1; + } + if (arg0 == 18) { + arg1 = concat(arg1, "R"); + return arg1; + } + if (arg0 == 19) { + arg1 = concat(arg1, "S"); + return arg1; + } + if (arg0 == 20) { + arg1 = concat(arg1, "T"); + return arg1; + } + if (arg0 == 21) { + arg1 = concat(arg1, "U"); + return arg1; + } + if (arg0 == 22) { + arg1 = concat(arg1, "V"); + return arg1; + } + if (arg0 == 23) { + arg1 = concat(arg1, "W"); + return arg1; + } + if (arg0 == 24) { + arg1 = concat(arg1, "X"); + return arg1; + } + if (arg0 == 25) { + arg1 = concat(arg1, "Y"); + return arg1; + } + if (arg0 == 26) { + arg1 = concat(arg1, "Z"); + return arg1; + } + return ""; +} diff --git a/dumps/scripts/824.cs2 b/dumps/scripts/824.cs2 new file mode 100644 index 0000000..9faf568 --- /dev/null +++ b/dumps/scripts/824.cs2 @@ -0,0 +1,111 @@ +string script_824(int arg0,string arg1) { + if (((boolean)arg0)) { + arg1 = concat(arg1, " "); + return arg1; + } + if (((boolean)arg0)) { + arg1 = concat(arg1, "a"); + return arg1; + } + if (arg0 == 2) { + arg1 = concat(arg1, "b"); + return arg1; + } + if (arg0 == 3) { + arg1 = concat(arg1, "c"); + return arg1; + } + if (arg0 == 4) { + arg1 = concat(arg1, "d"); + return arg1; + } + if (arg0 == 5) { + arg1 = concat(arg1, "e"); + return arg1; + } + if (arg0 == 6) { + arg1 = concat(arg1, "f"); + return arg1; + } + if (arg0 == 7) { + arg1 = concat(arg1, "g"); + return arg1; + } + if (arg0 == 8) { + arg1 = concat(arg1, "h"); + return arg1; + } + if (arg0 == 9) { + arg1 = concat(arg1, "i"); + return arg1; + } + if (arg0 == 10) { + arg1 = concat(arg1, "j"); + return arg1; + } + if (arg0 == 11) { + arg1 = concat(arg1, "k"); + return arg1; + } + if (arg0 == 12) { + arg1 = concat(arg1, "l"); + return arg1; + } + if (arg0 == 13) { + arg1 = concat(arg1, "m"); + return arg1; + } + if (arg0 == 14) { + arg1 = concat(arg1, "n"); + return arg1; + } + if (arg0 == 15) { + arg1 = concat(arg1, "o"); + return arg1; + } + if (arg0 == 16) { + arg1 = concat(arg1, "p"); + return arg1; + } + if (arg0 == 17) { + arg1 = concat(arg1, "q"); + return arg1; + } + if (arg0 == 18) { + arg1 = concat(arg1, "r"); + return arg1; + } + if (arg0 == 19) { + arg1 = concat(arg1, "s"); + return arg1; + } + if (arg0 == 20) { + arg1 = concat(arg1, "t"); + return arg1; + } + if (arg0 == 21) { + arg1 = concat(arg1, "u"); + return arg1; + } + if (arg0 == 22) { + arg1 = concat(arg1, "v"); + return arg1; + } + if (arg0 == 23) { + arg1 = concat(arg1, "w"); + return arg1; + } + if (arg0 == 24) { + arg1 = concat(arg1, "x"); + return arg1; + } + if (arg0 == 25) { + arg1 = concat(arg1, "y"); + return arg1; + } + if (arg0 == 26) { + arg1 = concat(arg1, "z"); + return arg1; + } + return ""; +} diff --git a/dumps/scripts/825.cs2 b/dumps/scripts/825.cs2 new file mode 100644 index 0000000..8f5ee45 --- /dev/null +++ b/dumps/scripts/825.cs2 @@ -0,0 +1,4 @@ +void script_825(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7) { + script_1657(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + return; +} diff --git a/dumps/scripts/826.cs2 b/dumps/scripts/826.cs2 new file mode 100644 index 0000000..920fe29 --- /dev/null +++ b/dumps/scripts/826.cs2 @@ -0,0 +1,7 @@ +void script_826() { + int ivar0; + ivar0 = getClientCycle(); + setScriptCallOnGameloop(827, ivar0, "i", new WidgetPointer(465,2)); + playSoundEffect(4437, 1, 58); + return; +} diff --git a/dumps/scripts/827.cs2 b/dumps/scripts/827.cs2 new file mode 100644 index 0000000..c1bfd18 --- /dev/null +++ b/dumps/scripts/827.cs2 @@ -0,0 +1,16 @@ +void script_827(int arg0) { + int ivar1; + ivar1 = 0; + if ((getClientCycle() >= add(arg0, 32)) && (getClientCycle() < add(arg0, 140))) { + setWidgetText(new WidgetPointer(465,2), "Varrock Herald"); + setWidgetText(new WidgetPointer(465,3), "Covering all of Misthalin and beyond."); + setWidgetText(new WidgetPointer(465,4), "1 gp"); + setWidgetText(new WidgetPointer(465,5), "Oo'glog Ogresses Open Health Spa!"); + } else { + setWidgetText(new WidgetPointer(465,2), " "); + setWidgetText(new WidgetPointer(465,3), " "); + setWidgetText(new WidgetPointer(465,4), " "); + setWidgetText(new WidgetPointer(465,5), " "); + } + return; +} diff --git a/dumps/scripts/828.cs2 b/dumps/scripts/828.cs2 new file mode 100644 index 0000000..1c72ac8 --- /dev/null +++ b/dumps/scripts/828.cs2 @@ -0,0 +1,51 @@ +void script_828() { + int ivar0; + int ivar1; + int ivar2; + script_2872(); + globalarray_0 = new int[add(1016, 1)]; + ivar0 = 0; + if (((boolean)globalint_89) || (globalint_89 == -1)) { + globalstring_196 = ""; + globalint_89 = 1; + } + while (ivar0 <= 1016) { + globalarray_0[ivar0] = ivar0; + createExtraChild(new WidgetPointer(187,1), 4, multiply(ivar0, 2)); + createExtraChild(new WidgetPointer(187,1), 5, add(multiply(ivar0, 2), 1)); + ivar0 = add(ivar0, 1); + } + script_520(0, 0, 1016, 1347); + setWidgetIntegerNode(1133, -1, new WidgetPointer(187,4)); + ivar0 = 0; + ivar1 = 0; + ivar2 = 0; + while (ivar1 <= 1016) { + ivar0 = globalarray_0[ivar1]; + if (setWidgetRegister(new WidgetPointer(187,1), multiply(ivar0, 2)) && setWidgetRegister(new WidgetPointer(187,1), add(multiply(ivar0, 2), 1))) { + if ((cs2method_3408(105, 77, 1351, ivar0) != 147) && ((boolean)cs2method_3408(105, 105, 1350, ivar0))) { + setWidgetTextAlignment(0, 1, 0); + setWidgetText(getCommonString(1345, ivar0)); + setWidgetSize(150, 15, 0, 0); + setScriptCallOnClickContextMenu(833, -2147483644, ivar0, "ii"); + cs2method1305(getCommonString(1345, ivar0)); + cs2method1305(getCommonString(1345, ivar0)); + setWidgetUnknownBoolean(false); + setWidgetFont(494); + setScriptCallOnMouseEntered(1356, new WidgetPointer(-32768,3), -2147483643, 16777215, "Iii"); + setWidgetSize(12, 12, 0, 0); + if (((boolean)ivar2)) { + setWidgetIntegerNode(1133, ivar0, new WidgetPointer(187,4)); + ivar2 = 1; + } + } + if (ivar1 < 1016) { + setWidgetIntegerNode(1133, globalarray_0[add(ivar1, 1)]); + } + } + ivar1 = add(ivar1, 1); + } + script_31(12255234, 12255233, 792, 789, 790, 791, 773, 788); + script_3680(); + return; +} diff --git a/dumps/scripts/829.cs2 b/dumps/scripts/829.cs2 new file mode 100644 index 0000000..3437311 --- /dev/null +++ b/dumps/scripts/829.cs2 @@ -0,0 +1,6 @@ +int script_829(int arg0,int arg1) { + if (arg0 == 845) { + return subtract(cs2method5302(), 1); + } + return subtract(getCommonDefinitionSize(arg1), 1); +} diff --git a/dumps/scripts/83.cs2 b/dumps/scripts/83.cs2 new file mode 100644 index 0000000..e12a258 --- /dev/null +++ b/dumps/scripts/83.cs2 @@ -0,0 +1,107 @@ +void script_83(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12,int arg13,int arg14,int arg15,int arg16,int arg17,int arg18,int arg19,int arg20,int arg21) { + int ivar22; + script_1298(arg0, 29, 50, 0); + script_1298(arg12, 0, 0, 0); + script_1298(arg9, 0, 0, 0); + script_1298(arg20, 0, 0, 0); + script_1298(arg15, 0, 0, 0); + script_2670(arg1, arg4, arg5, arg8, arg2, arg6, arg3, arg7, globalint_91); + setWidgetRGB(new Color(cs2method_3408(105, 105, 3724, bitconfig_3612)), new WidgetPointer(arg11)); + ivar22 = getDisplayMode(); + script_2730(arg10, arg11, ivar22); + setScriptCallOnGameloop(2729, new WidgetPointer(-32768,3), new WidgetPointer(arg10), new WidgetPointer(arg11), ivar22, "IIIi", new WidgetPointer(arg0)); + script_2731(64356369, 0, arg19, arg11, arg20, arg21, arg14, arg17); + script_2731(64356370, 1, arg19, arg11, arg20, arg21, arg14, arg17); + script_2731(64356371, 2, arg19, arg11, arg20, arg21, arg14, arg17); + script_2731(64356372, 3, arg19, arg11, arg20, arg21, arg14, arg17); + script_2731(64356373, 4, arg19, arg11, arg20, arg21, arg14, arg17); + script_2731(64356374, 5, arg19, arg11, arg20, arg21, arg14, arg17); + script_2731(64356375, 6, arg19, arg11, arg20, arg21, arg14, arg17); + script_2731(64356376, 7, arg19, arg11, arg20, arg21, arg14, arg17); + script_2731(64356377, 8, arg19, arg11, arg20, arg21, arg14, arg17); + script_2731(64356378, 9, arg19, arg11, arg20, arg21, arg14, arg17); + script_2731(64356379, 10, arg19, arg11, arg20, arg21, arg14, arg17); + script_2731(64356380, 11, arg19, arg11, arg20, arg21, arg14, arg17); + script_2731(64356381, 12, arg19, arg11, arg20, arg21, arg14, arg17); + script_2731(64356382, 13, arg19, arg11, arg20, arg21, arg14, arg17); + script_2731(64356383, 14, arg19, arg11, arg20, arg21, arg14, arg17); + script_2731(64356384, 15, arg19, arg11, arg20, arg21, arg14, arg17); + script_2731(64356385, 20, arg19, arg11, arg20, arg21, arg14, arg17); + script_2731(64356386, 17, arg19, arg11, arg20, arg21, arg14, arg17); + script_2731(64356387, 18, arg19, arg11, arg20, arg21, arg14, arg17); + script_2731(64356388, 19, arg19, arg11, arg20, arg21, arg14, arg17); + setWidgetRGB(new Color(cs2method_3408(105, 105, 3723, bitconfig_9188)), new WidgetPointer(arg14)); + script_2730(arg13, arg14, ivar22); + setScriptCallOnGameloop(2729, new WidgetPointer(-32768,3), new WidgetPointer(arg13), new WidgetPointer(arg14), ivar22, "IIIi", new WidgetPointer(arg0)); + script_4426(64356424, 0, arg19, arg11, arg20, arg21, arg14, arg17); + script_4426(64356425, 1, arg19, arg11, arg20, arg21, arg14, arg17); + script_4426(64356426, 2, arg19, arg11, arg20, arg21, arg14, arg17); + script_4426(64356427, 3, arg19, arg11, arg20, arg21, arg14, arg17); + script_4426(64356428, 4, arg19, arg11, arg20, arg21, arg14, arg17); + script_4426(64356429, 5, arg19, arg11, arg20, arg21, arg14, arg17); + script_4426(64356430, 6, arg19, arg11, arg20, arg21, arg14, arg17); + script_4426(64356431, 7, arg19, arg11, arg20, arg21, arg14, arg17); + script_4426(64356432, 8, arg19, arg11, arg20, arg21, arg14, arg17); + script_4426(64356433, 9, arg19, arg11, arg20, arg21, arg14, arg17); + script_4426(64356434, 10, arg19, arg11, arg20, arg21, arg14, arg17); + script_4426(64356435, 11, arg19, arg11, arg20, arg21, arg14, arg17); + script_4426(64356436, 12, arg19, arg11, arg20, arg21, arg14, arg17); + script_4426(64356437, 13, arg19, arg11, arg20, arg21, arg14, arg17); + script_4426(64356438, 14, arg19, arg11, arg20, arg21, arg14, arg17); + script_4426(64356439, 15, arg19, arg11, arg20, arg21, arg14, arg17); + script_4426(64356440, 20, arg19, arg11, arg20, arg21, arg14, arg17); + script_4426(64356441, 17, arg19, arg11, arg20, arg21, arg14, arg17); + script_4426(64356442, 18, arg19, arg11, arg20, arg21, arg14, arg17); + script_4426(64356443, 19, arg19, arg11, arg20, arg21, arg14, arg17); + setWidgetRGB(new Color(cs2method_3408(105, 105, 3726, bitconfig_9191)), new WidgetPointer(arg17)); + script_2730(arg16, arg17, ivar22); + setScriptCallOnGameloop(2729, new WidgetPointer(-32768,3), new WidgetPointer(arg16), new WidgetPointer(arg17), ivar22, "IIIi", new WidgetPointer(arg0)); + script_4584(64356449, 0, arg19, arg11, arg20, arg21, arg14, arg17); + script_4584(64356450, 1, arg19, arg11, arg20, arg21, arg14, arg17); + script_4584(64356451, 2, arg19, arg11, arg20, arg21, arg14, arg17); + script_4584(64356452, 3, arg19, arg11, arg20, arg21, arg14, arg17); + script_4584(64356453, 4, arg19, arg11, arg20, arg21, arg14, arg17); + script_4584(64356454, 5, arg19, arg11, arg20, arg21, arg14, arg17); + script_4584(64356455, 6, arg19, arg11, arg20, arg21, arg14, arg17); + script_4584(64356456, 7, arg19, arg11, arg20, arg21, arg14, arg17); + script_4584(64356457, 8, arg19, arg11, arg20, arg21, arg14, arg17); + script_4584(64356458, 9, arg19, arg11, arg20, arg21, arg14, arg17); + script_4584(64356459, 10, arg19, arg11, arg20, arg21, arg14, arg17); + script_4584(64356460, 11, arg19, arg11, arg20, arg21, arg14, arg17); + script_4584(64356461, 12, arg19, arg11, arg20, arg21, arg14, arg17); + script_4584(64356462, 13, arg19, arg11, arg20, arg21, arg14, arg17); + script_4584(64356463, 14, arg19, arg11, arg20, arg21, arg14, arg17); + script_4584(64356464, 15, arg19, arg11, arg20, arg21, arg14, arg17); + script_4584(64356465, 20, arg19, arg11, arg20, arg21, arg14, arg17); + script_4584(64356466, 17, arg19, arg11, arg20, arg21, arg14, arg17); + script_4584(64356467, 18, arg19, arg11, arg20, arg21, arg14, arg17); + script_4584(64356468, 19, arg19, arg11, arg20, arg21, arg14, arg17); + if (standart_config_287 <= 0) { + setWidgetIsHidden(true, new WidgetPointer(arg20)); + } else { + setWidgetIsHidden(false, new WidgetPointer(arg20)); + } + setWidgetRGB(new Color(cs2method_3408(105, 105, 3056, standart_config_287)), new WidgetPointer(arg21)); + setWidgetUnknownBoolean(((boolean)cs2method_3408(105, 49, 3057, standart_config_287)), new WidgetPointer(arg21)); + script_176(64356401, 1, arg19, arg11, arg20, arg21, arg14, arg17); + script_176(64356402, 2, arg19, arg11, arg20, arg21, arg14, arg17); + script_176(64356403, 3, arg19, arg11, arg20, arg21, arg14, arg17); + script_176(64356404, 4, arg19, arg11, arg20, arg21, arg14, arg17); + script_176(64356405, 5, arg19, arg11, arg20, arg21, arg14, arg17); + script_176(64356406, 6, arg19, arg11, arg20, arg21, arg14, arg17); + script_176(64356407, 7, arg19, arg11, arg20, arg21, arg14, arg17); + script_176(64356408, 8, arg19, arg11, arg20, arg21, arg14, arg17); + script_176(64356409, 9, arg19, arg11, arg20, arg21, arg14, arg17); + script_176(64356410, 10, arg19, arg11, arg20, arg21, arg14, arg17); + script_176(64356411, 11, arg19, arg11, arg20, arg21, arg14, arg17); + script_176(64356412, 12, arg19, arg11, arg20, arg21, arg14, arg17); + script_176(64356413, 13, arg19, arg11, arg20, arg21, arg14, arg17); + script_176(64356414, 14, arg19, arg11, arg20, arg21, arg14, arg17); + script_176(64356415, 15, arg19, arg11, arg20, arg21, arg14, arg17); + script_176(64356416, 16, arg19, arg11, arg20, arg21, arg14, arg17); + script_176(64356417, 17, arg19, arg11, arg20, arg21, arg14, arg17); + script_176(64356418, 18, arg19, arg11, arg20, arg21, arg14, arg17); + setScriptCallOnClickContextMenu(3417, -2147483644, 0, new WidgetPointer(arg19), new WidgetPointer(arg11), new WidgetPointer(arg20), new WidgetPointer(arg21), new WidgetPointer(arg14), new WidgetPointer(arg17), "iiIIIIII", new WidgetPointer(arg18)); + setScriptCallOnConfigChange(2734, new WidgetPointer(arg19), new WidgetPointer(arg11), new WidgetPointer(arg20), new WidgetPointer(arg21), new WidgetPointer(arg14), new WidgetPointer(arg17), 287, 1438, 2, "IIIIIIY", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/830.cs2 b/dumps/scripts/830.cs2 new file mode 100644 index 0000000..9798f59 --- /dev/null +++ b/dumps/scripts/830.cs2 @@ -0,0 +1,6 @@ +void script_830(int arg0,int arg1) { + setWidgetAnimation(3320, new WidgetPointer(arg1)); + setScriptCallOnConfigChange(831, new WidgetPointer(arg0), 425, 1, "IY", new WidgetPointer(arg0)); + script_834(arg0); + return; +} diff --git a/dumps/scripts/831.cs2 b/dumps/scripts/831.cs2 new file mode 100644 index 0000000..d4ab873 --- /dev/null +++ b/dumps/scripts/831.cs2 @@ -0,0 +1,4 @@ +void script_831(int arg0) { + script_834(arg0); + return; +} diff --git a/dumps/scripts/832.cs2 b/dumps/scripts/832.cs2 new file mode 100644 index 0000000..09fe5f2 --- /dev/null +++ b/dumps/scripts/832.cs2 @@ -0,0 +1,4 @@ +void script_832() { + script_3680(); + return; +} diff --git a/dumps/scripts/833.cs2 b/dumps/scripts/833.cs2 new file mode 100644 index 0000000..6fed272 --- /dev/null +++ b/dumps/scripts/833.cs2 @@ -0,0 +1,17 @@ +void script_833(int arg0,int arg1) { + if (arg0 == 2) { + script_3683(); + if (arg1 < 500) { + if (((boolean)script_837(arg1)) && ((boolean)cs2method_3408(105, 105, 1350, arg1))) { + messageType0("This track was unlocked " + getCommonString(1349, arg1)); + } else { + messageType0("This track unlocks " + getCommonString(1349, arg1)); + } + } else if (((boolean)script_837(arg1)) && ((boolean)cs2method_3408(105, 105, 1350, arg1))) { + messageType0("This track was unlocked " + getCommonString(952, arg1)); + } else { + messageType0("This track unlocks " + getCommonString(952, arg1)); + } + } + return; +} diff --git a/dumps/scripts/834.cs2 b/dumps/scripts/834.cs2 new file mode 100644 index 0000000..6cbb6cb --- /dev/null +++ b/dumps/scripts/834.cs2 @@ -0,0 +1,16 @@ +void script_834(int arg0) { + switch (bitconfig_278) { + case 1: + cs2method2103(200, new WidgetPointer(arg0)); + break; + case 2: + cs2method2103(150, new WidgetPointer(arg0)); + break; + case 3: + cs2method2103(50, new WidgetPointer(arg0)); + break; + default: + cs2method2103(255, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/835.cs2 b/dumps/scripts/835.cs2 new file mode 100644 index 0000000..4728f76 --- /dev/null +++ b/dumps/scripts/835.cs2 @@ -0,0 +1,8 @@ +void script_835(int arg0) { + setWidgetIsHidden(((boolean)arg0), new WidgetPointer(475,55)); + setWidgetIsHidden(((boolean)arg0), new WidgetPointer(475,57)); + setWidgetIsHidden(((boolean)arg0), new WidgetPointer(475,56)); + script_84(); + script_89(); + return; +} diff --git a/dumps/scripts/836.cs2 b/dumps/scripts/836.cs2 new file mode 100644 index 0000000..a96a9e0 --- /dev/null +++ b/dumps/scripts/836.cs2 @@ -0,0 +1,4 @@ +void script_836(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10) { + script_1176(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); + return; +} diff --git a/dumps/scripts/837.cs2 b/dumps/scripts/837.cs2 new file mode 100644 index 0000000..afa5a17 --- /dev/null +++ b/dumps/scripts/837.cs2 @@ -0,0 +1,99 @@ +int script_837(int arg0) { + if (arg0 < 32) { + return isBitFlagged(standart_config_20, bitAnd(arg0, 31)); + } + if (arg0 < 64) { + return isBitFlagged(standart_config_21, bitAnd(arg0, 31)); + } + if (arg0 < 96) { + return isBitFlagged(standart_config_22, bitAnd(arg0, 31)); + } + if (arg0 < 128) { + return isBitFlagged(standart_config_23, bitAnd(arg0, 31)); + } + if (arg0 < 160) { + return isBitFlagged(standart_config_24, bitAnd(arg0, 31)); + } + if (arg0 < 192) { + return isBitFlagged(standart_config_25, bitAnd(arg0, 31)); + } + if (arg0 < 224) { + return isBitFlagged(standart_config_298, bitAnd(arg0, 31)); + } + if (arg0 < 256) { + return isBitFlagged(standart_config_311, bitAnd(arg0, 31)); + } + if (arg0 < 288) { + return isBitFlagged(standart_config_346, bitAnd(arg0, 31)); + } + if (arg0 < 320) { + return isBitFlagged(standart_config_414, bitAnd(arg0, 31)); + } + if (arg0 < 352) { + return isBitFlagged(standart_config_464, bitAnd(arg0, 31)); + } + if (arg0 < 384) { + return isBitFlagged(standart_config_598, bitAnd(arg0, 31)); + } + if (arg0 < 416) { + return isBitFlagged(standart_config_662, bitAnd(arg0, 31)); + } + if (arg0 < 448) { + return isBitFlagged(standart_config_721, bitAnd(arg0, 31)); + } + if (arg0 < 480) { + return isBitFlagged(standart_config_906, bitAnd(arg0, 31)); + } + if (arg0 < 512) { + return isBitFlagged(standart_config_1009, bitAnd(arg0, 31)); + } + if (arg0 < 544) { + return isBitFlagged(standart_config_1104, bitAnd(arg0, 31)); + } + if (arg0 < 576) { + return isBitFlagged(standart_config_1136, bitAnd(arg0, 31)); + } + if (arg0 < 608) { + return isBitFlagged(standart_config_1180, bitAnd(arg0, 31)); + } + if (arg0 < 640) { + return isBitFlagged(standart_config_1202, bitAnd(arg0, 31)); + } + if (arg0 < 672) { + return isBitFlagged(standart_config_1381, bitAnd(arg0, 31)); + } + if (arg0 < 704) { + return isBitFlagged(standart_config_1394, bitAnd(arg0, 31)); + } + if (arg0 < 736) { + return isBitFlagged(standart_config_1434, bitAnd(arg0, 31)); + } + if (arg0 < 768) { + return isBitFlagged(standart_config_1596, bitAnd(arg0, 31)); + } + if (arg0 < 800) { + return isBitFlagged(standart_config_1618, bitAnd(arg0, 31)); + } + if (arg0 < 832) { + return isBitFlagged(standart_config_1619, bitAnd(arg0, 31)); + } + if (arg0 < 864) { + return isBitFlagged(standart_config_1620, bitAnd(arg0, 31)); + } + if (arg0 < 896) { + return 1; + } + if (arg0 < 928) { + return isBitFlagged(standart_config_1864, bitAnd(arg0, 31)); + } + if (arg0 < 960) { + return isBitFlagged(standart_config_1865, bitAnd(arg0, 31)); + } + if (arg0 < 992) { + return isBitFlagged(standart_config_2019, bitAnd(arg0, 31)); + } + if (arg0 < 1024) { + return isBitFlagged(standart_config_2246, bitAnd(arg0, 31)); + } + return -1; +} diff --git a/dumps/scripts/838.cs2 b/dumps/scripts/838.cs2 new file mode 100644 index 0000000..c9fe9c1 --- /dev/null +++ b/dumps/scripts/838.cs2 @@ -0,0 +1,4 @@ +void script_838(int arg0) { + script_1184(arg0); + return; +} diff --git a/dumps/scripts/839.cs2 b/dumps/scripts/839.cs2 new file mode 100644 index 0000000..f9261ea --- /dev/null +++ b/dumps/scripts/839.cs2 @@ -0,0 +1,9 @@ +void script_839() { + playSoundEffect(4501, 1, 0); + if (((boolean)bitconfig_4399)) { + script_841(1); + } else { + script_841(0); + } + return; +} diff --git a/dumps/scripts/84.cs2 b/dumps/scripts/84.cs2 new file mode 100644 index 0000000..253ed14 --- /dev/null +++ b/dumps/scripts/84.cs2 @@ -0,0 +1,357 @@ +void script_84() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + int ivar17; + int ivar18; + int ivar19; + int ivar20; + int ivar21; + string svar0; + string svar1; + string svar2; + string svar3; + string svar4; + ivar0 = -1; + ivar1 = -1; + ivar2 = 0; + ivar3 = 1; + ivar4 = 1; + if (globalint_41 == 3) { + ivar2 = 1; + } + deleteAllExtraChilds(new WidgetPointer(137,58)); + ivar5 = -1; + ivar6 = script_4467(); + ivar7 = -1; + ivar8 = script_1891(); + globalint_132 = -1; + svar0 = ""; + svar1 = ""; + svar2 = ""; + svar3 = ""; + ivar9 = 0; + ivar10 = 0; + ivar11 = 0; + ivar12 = 0; + svar4 = ""; + ivar13 = 0; + if (getDisplayMode() >= 2) { + svar0 = ""; + svar1 = ""; + svar2 = ""; + svar3 = ""; + ivar12 = 16777215; + svar4 = ""; + ivar13 = 1; + ivar10 = cs2method_3408(105, 105, 3724, bitconfig_3612); + ivar9 = cs2method_3408(105, 105, 3723, bitconfig_9188); + ivar11 = cs2method_3408(105, 105, 3726, bitconfig_9191); + } else { + ivar10 = cs2method_3408(105, 105, 3724, bitconfig_3612); + ivar9 = cs2method_3408(105, 105, 3723, bitconfig_9188); + ivar11 = cs2method_3408(105, 105, 3726, bitconfig_9191); + } + ivar14 = 0; + ivar15 = 0; + ivar16 = 0; + ivar17 = 0; + ivar18 = 0; + ivar19 = 0; + ivar20 = 2; + ivar21 = 2; + while (ivar18 < 100) { + if (((boolean)script_193(ivar18)) && ((boolean)script_90(ivar18, ivar2))) { + createExtraChild(new WidgetPointer(137,58), 4, ivar14); + ivar15 = ivar14; + ivar16 = 1; + ivar14 = add(ivar14, 1); + ivar17 = cs2method5004(ivar18); + setWidgetRGB(new Color(ivar12)); + setWidgetFont(495); + setWidgetTextAlignment(0, 0, 14); + setWidgetUnknownBoolean(((boolean)ivar13)); + setWidgetPosition(3, ivar21, 0, 2); + switch (ivar17) { + case 0: + case 4: + case 11: + case 27: + case 26: + case 29: + case 28: + case 31: + case 30: + case 103: + case 110: + case 43: + case 109: + case 104: + setWidgetText(cs2method5003(ivar18)); + if (((boolean)ivar3) && (((((((((boolean)ivar17) || (ivar17 == 4)) || (ivar17 == 27)) || (ivar17 == 28)) || (ivar17 == 29)) || (ivar17 == 26)) || (ivar17 == 30)) || (ivar17 == 31))) { + globalint_1269 = cs2method5024(ivar18); + ivar3 = 0; + } + break; + case 1: + case 2: + setWidgetText(cs2method5010(ivar18) + ": " + svar0 + cs2method5003(ivar18)); + break; + case 3: + setWidgetText("From " + cs2method5010(ivar18) + ": " + svar1 + cs2method5003(ivar18)); + break; + case 100: + setWidgetText(svar2 + cs2method5010(ivar18) + " " + cs2method5003(ivar18)); + break; + case 5: + setWidgetText(svar1 + cs2method5003(ivar18)); + break; + case 6: + setWidgetText("To " + cs2method5010(ivar18) + ": " + svar1 + cs2method5003(ivar18)); + break; + case 7: + setWidgetText("From " + cs2method5010(ivar18) + ": " + svar1 + cs2method5003(ivar18)); + break; + case 101: + setWidgetText("" + cs2method5010(ivar18) + " " + cs2method5003(ivar18)); + break; + case 41: + setWidgetRGB(new Color(ivar10)); + setWidgetText(svar4 + "[" + "" + svar0 + cs2method5011(ivar18) + "" + svar4 + "] " + cs2method5010(ivar18) + ": " + "" + cs2method5003(ivar18)); + break; + case 9: + setWidgetRGB(new Color(ivar9)); + setWidgetText(svar4 + "[" + "" + svar0 + cs2method5011(ivar18) + "" + svar4 + "] " + cs2method5010(ivar18) + ": " + "" + cs2method5003(ivar18)); + break; + case 44: + setWidgetRGB(new Color(ivar11)); + setWidgetText(svar4 + "[" + "" + svar0 + cs2method5011(ivar18) + "" + svar4 + "] " + cs2method5010(ivar18) + ": " + "" + cs2method5003(ivar18)); + break; + case 117: + setWidgetText("" + cs2method5003(ivar18)); + break; + case 102: + setWidgetText("" + cs2method5010(ivar18) + " " + cs2method5003(ivar18)); + break; + case 105: + setWidgetText("" + cs2method5010(ivar18) + " " + cs2method5003(ivar18)); + break; + case 106: + setWidgetText("" + cs2method5010(ivar18) + " " + cs2method5003(ivar18)); + break; + case 107: + setWidgetText("" + cs2method5010(ivar18) + " " + cs2method5003(ivar18)); + break; + case 118: + setWidgetText("" + cs2method5010(ivar18) + " " + cs2method5003(ivar18)); + break; + case 17: + if ((stringMethod4107(strRemoveEntities(cs2method5015()), strRemoveEntities(cs2method5010(ivar18))) != 0) && (cs2method5056(cs2method5012(ivar18)) > 0)) { + setWidgetText(cs2method5010(ivar18) + "" + ": " + svar0 + cs2method5003(ivar18)); + } else { + setWidgetText(cs2method5010(ivar18) + ": " + svar0 + cs2method5003(ivar18)); + } + break; + case 18: + if ((stringMethod4107(strRemoveEntities(cs2method5015()), strRemoveEntities(cs2method5010(ivar18))) != 0) && (cs2method5056(cs2method5012(ivar18)) > 0)) { + setWidgetText("From " + cs2method5010(ivar18) + "" + ": " + svar1 + cs2method5003(ivar18)); + } else { + setWidgetText("From " + cs2method5010(ivar18) + ": " + svar1 + cs2method5003(ivar18)); + } + break; + case 19: + setWidgetText("To " + cs2method5010(ivar18) + ": " + svar1 + cs2method5003(ivar18)); + break; + case 42: + setWidgetRGB(new Color(ivar10)); + if ((stringMethod4107(strRemoveEntities(cs2method5015()), strRemoveEntities(cs2method5010(ivar18))) != 0) && (cs2method5056(cs2method5012(ivar18)) > 0)) { + setWidgetText(svar4 + "[" + "" + svar0 + cs2method5011(ivar18) + "" + svar4 + "] " + cs2method5010(ivar18) + "" + ": " + "" + cs2method5003(ivar18)); + } else { + setWidgetText(svar4 + "[" + "" + svar0 + cs2method5011(ivar18) + "" + svar4 + "] " + cs2method5010(ivar18) + ": " + "" + cs2method5003(ivar18)); + } + break; + case 45: + setWidgetRGB(new Color(ivar11)); + if ((stringMethod4107(strRemoveEntities(cs2method5015()), strRemoveEntities(cs2method5010(ivar18))) != 0) && (cs2method5056(cs2method5012(ivar18)) > 0)) { + setWidgetText(svar4 + "[" + "" + svar0 + cs2method5011(ivar18) + "" + svar4 + "] " + cs2method5010(ivar18) + "" + ": " + "" + cs2method5003(ivar18)); + } else { + setWidgetText(svar4 + "[" + "" + svar0 + cs2method5011(ivar18) + "" + svar4 + "] " + cs2method5010(ivar18) + ": " + "" + cs2method5003(ivar18)); + } + break; + case 20: + setWidgetRGB(new Color(ivar9)); + if ((stringMethod4107(strRemoveEntities(cs2method5015()), strRemoveEntities(cs2method5010(ivar18))) != 0) && (cs2method5056(cs2method5012(ivar18)) > 0)) { + setWidgetText(svar4 + "[" + "" + svar0 + cs2method5011(ivar18) + "" + svar4 + "] " + cs2method5010(ivar18) + "" + ": " + "" + cs2method5003(ivar18)); + } else { + setWidgetText(svar4 + "[" + "" + svar0 + cs2method5011(ivar18) + "" + svar4 + "] " + cs2method5010(ivar18) + ": " + "" + cs2method5003(ivar18)); + } + break; + case 108: + setWidgetText("" + cs2method5010(ivar18) + " " + cs2method5003(ivar18)); + break; + case 111: + case 112: + setWidgetText("" + cs2method5010(ivar18) + " " + cs2method5003(ivar18)); + break; + case 114: + case 113: + setWidgetText("" + cs2method5010(ivar18) + " " + cs2method5003(ivar18)); + break; + case 115: + setWidgetText("" + cs2method5010(ivar18) + " " + cs2method5003(ivar18)); + break; + case 116: + setWidgetText(cs2method5003(ivar18)); + } + setWidgetNoOptions(); + setScriptCallOnClickContextMenu(86, -2147483644, cs2method5019(ivar18), ivar18, "isi"); + cs2method1305("" + strRemoveEntities(cs2method5010(ivar18))); + switch (ivar17) { + case 1: + case 2: + case 3: + case 6: + case 7: + case 9: + case 41: + case 44: + if (((boolean)stringMethod4107(strRemoveEntities(cs2method5015()), strRemoveEntities(cs2method5010(ivar18)))) || ((boolean)stringMethod4107(strRemoveEntities(cs2method5020()), strRemoveEntities(cs2method5010(ivar18))))) { + } else { + if (isFriend(cs2method5019(ivar18))) { + if (isMuteRelatedMethod3329() && cs2method6900()) { + setWidgetContextMenuOption(6, "Message"); + } + } else { + setWidgetContextMenuOption(6, "Add friend"); + setWidgetContextMenuOption(7, "Add ignore"); + } + if ((getClientRights() > 0) || (((int)hasMoreThen5Blackmarks()) > 0)) { + setWidgetContextMenuOption(8, "Report abuse"); + } + if ((ivar17 == 41) && ((boolean)ivar6)) { + setWidgetContextMenuOption(10, "Kick/ban"); + } + if ((ivar17 == 9) && ((boolean)ivar8)) { + setWidgetContextMenuOption(10, "Kick/ban"); + } + } + break; + case 100: + setWidgetContextMenuOption(1, "Accept trade"); + break; + case 101: + case 106: + case 107: + case 105: + case 118: + case 114: + case 113: + setWidgetContextMenuOption(2, "Accept challenge"); + break; + case 102: + setWidgetContextMenuOption(3, "Give assistance"); + break; + case 111: + setWidgetContextMenuOption(4, "Open invitation"); + break; + case 112: + setWidgetContextMenuOption(3, "Vote"); + break; + case 17: + case 18: + case 20: + case 42: + case 45: + if (((boolean)stringMethod4107(strRemoveEntities(cs2method5015()), strRemoveEntities(cs2method5010(ivar18)))) || ((boolean)stringMethod4107(strRemoveEntities(cs2method5020()), strRemoveEntities(cs2method5010(ivar18))))) { + } else { + if (isFriend(cs2method5019(ivar18))) { + if (isMuteRelatedMethod3329() && cs2method6900()) { + setWidgetContextMenuOption(6, "Message"); + } + } else { + setWidgetContextMenuOption(6, "Add friend"); + setWidgetContextMenuOption(7, "Add ignore"); + } + if ((ivar17 == 42) && ((boolean)ivar6)) { + setWidgetContextMenuOption(10, "Kick/ban"); + } + if ((ivar17 == 20) && ((boolean)ivar8)) { + setWidgetContextMenuOption(10, "Kick/ban"); + } + if (cs2method5056(cs2method5012(ivar18)) > 0) { + if (globalint_132 == -1) { + globalint_132 = cs2method5012(ivar18); + globalstring_29 = cs2method5010(ivar18); + if (ivar17 == 20) { + globalint_133 = 6; + setWidgetContextMenuOption(9, "Quick Response"); + } + if (ivar17 == 42) { + globalint_133 = 9; + setWidgetContextMenuOption(9, "Quick Response"); + } + if (ivar17 == 45) { + globalint_133 = 11; + setWidgetContextMenuOption(9, "Quick Response"); + } else if (ivar17 == 18) { + globalint_133 = 5; + if (isFriend(cs2method5019(ivar18))) { + setWidgetContextMenuOption(9, "Quick Response"); + } + } else { + globalint_133 = 4; + setWidgetContextMenuOption(9, "Quick Response"); + } + } else { + setWidgetContextMenuOption(9, "Quick Response"); + } + } + } + break; + case 108: + setWidgetContextMenuOption(10, "Accept alliance"); + break; + case 117: + setWidgetContextMenuOption(5, "View invite from"); + } + } else { + ivar16 = 0; + } + if (((boolean)ivar4)) { + switch (cs2method5004(ivar18)) { + case 18: + case 7: + case 3: + globalstring_276 = strRemoveEntities(cs2method5019(ivar18)); + ivar4 = 0; + } + } + if (setWidgetRegister(new WidgetPointer(137,58), ivar15) && ((boolean)ivar16)) { + ivar19 = max(getLineCount(484, getWidgetFont(), getWidgetText()), 1); + setWidgetSize(max(min(getMaxLineWidth(484, getWidgetFont(), getWidgetText()), 484), 1), multiply(14, ivar19), 0, 0); + ivar20 = add(ivar20, getWidgetActualHeight()); + ivar21 = add(ivar21, getWidgetActualHeight()); + } + ivar18 = add(ivar18, 1); + } + ivar20 = max(ivar20, getWidgetActualHeight(new WidgetPointer(137,58))); + setWidgetScrollMax(463, ivar20, new WidgetPointer(137,58)); + script_72(8978491, 8978490, subtract(add(globalint_7, getWidgetScrollMaxV(new WidgetPointer(137,58))), globalint_8)); + globalint_7 = cs2method2601(new WidgetPointer(137,58)); + globalint_8 = getWidgetScrollMaxV(new WidgetPointer(137,58)); + return; +} diff --git a/dumps/scripts/840.cs2 b/dumps/scripts/840.cs2 new file mode 100644 index 0000000..33c33c7 --- /dev/null +++ b/dumps/scripts/840.cs2 @@ -0,0 +1,4 @@ +void script_840() { + playSoundEffect(4501, 1, 0); + return; +} diff --git a/dumps/scripts/841.cs2 b/dumps/scripts/841.cs2 new file mode 100644 index 0000000..c0df992 --- /dev/null +++ b/dumps/scripts/841.cs2 @@ -0,0 +1,25 @@ +void script_841(int arg0) { + int ivar1; + ivar1 = 0; + bitconfig_4399 = arg0; + setWidgetIsHidden(true, cs2method_3408(105, 73, 1355, bitconfig_4398)); + setWidgetIsHidden(true, cs2method_3408(105, 73, 1358, bitconfig_4398)); + if (((boolean)arg0)) { + setWidgetIsHidden(false, new WidgetPointer(681,9)); + setWidgetIsHidden(true, new WidgetPointer(681,12)); + } else { + setWidgetIsHidden(false, new WidgetPointer(681,12)); + setWidgetIsHidden(true, new WidgetPointer(681,9)); + } + while (ivar1 < 10) { + if (script_855(ivar1) == arg0) { + if ((script_851(ivar1) != 7) || (script_852(ivar1) != 2)) { + setWidgetIsHidden(false, cs2method_3408(105, 73, 1354, ivar1)); + } + } else { + setWidgetIsHidden(true, cs2method_3408(105, 73, 1354, ivar1)); + } + ivar1 = add(ivar1, 1); + } + return; +} diff --git a/dumps/scripts/842.cs2 b/dumps/scripts/842.cs2 new file mode 100644 index 0000000..3f6f380 --- /dev/null +++ b/dumps/scripts/842.cs2 @@ -0,0 +1,4 @@ +void script_842() { + script_846(bitconfig_4398, 2); + return; +} diff --git a/dumps/scripts/843.cs2 b/dumps/scripts/843.cs2 new file mode 100644 index 0000000..036bc5d --- /dev/null +++ b/dumps/scripts/843.cs2 @@ -0,0 +1,4 @@ +void script_843() { + script_846(bitconfig_4398, 3); + return; +} diff --git a/dumps/scripts/844.cs2 b/dumps/scripts/844.cs2 new file mode 100644 index 0000000..20c9764 --- /dev/null +++ b/dumps/scripts/844.cs2 @@ -0,0 +1,4 @@ +void script_844() { + script_846(bitconfig_4398, 0); + return; +} diff --git a/dumps/scripts/845.cs2 b/dumps/scripts/845.cs2 new file mode 100644 index 0000000..ce90550 --- /dev/null +++ b/dumps/scripts/845.cs2 @@ -0,0 +1,4 @@ +void script_845() { + script_846(bitconfig_4398, 1); + return; +} diff --git a/dumps/scripts/846.cs2 b/dumps/scripts/846.cs2 new file mode 100644 index 0000000..f705dc7 --- /dev/null +++ b/dumps/scripts/846.cs2 @@ -0,0 +1,52 @@ +void script_846(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + ivar2 = ((int)cs2method_3408(105, 73, 1354, arg0)); + ivar3 = ((int)cs2method_3408(105, 73, 1355, arg0)); + ivar4 = 0; + ivar5 = 0; + ivar6 = getWidgetActualX(new WidgetPointer(ivar2)); + ivar7 = getWidgetActualY(new WidgetPointer(ivar2)); + ivar8 = getWidgetActualX(new WidgetPointer(ivar3)); + ivar9 = getWidgetActualY(new WidgetPointer(ivar3)); + ivar10 = getWidgetRotateY(new WidgetPointer(ivar2)); + ivar11 = add(multiply(15, 18), 65); + ivar12 = add(multiply(11, 18), -2); + ivar13 = 0; + ivar14 = 0; + if (arg0 != 10) { + if (((boolean)arg1) && (ivar6 > 65)) { + ivar13 = subtract(ivar13, 18); + playSoundEffect(4503, 1, 0); + } else if (((boolean)arg1) && (ivar6 < subtract(ivar11, 1))) { + ivar13 = add(ivar13, 18); + playSoundEffect(4503, 1, 0); + } else if ((arg1 == 2) && (ivar7 > -2)) { + ivar14 = subtract(ivar14, 18); + playSoundEffect(4503, 1, 0); + } else { + if ((arg1 == 3) && (ivar7 < ivar12)) { + ivar14 = add(ivar14, 18); + playSoundEffect(4503, 1, 0); + } + } + ivar6 = add(add(ivar6, ivar13), ivar4); + ivar7 = add(add(ivar7, ivar14), ivar5); + ivar8 = add(add(ivar8, ivar13), ivar4); + ivar9 = add(add(ivar9, ivar14), ivar5); + setWidgetPosition(ivar6, ivar7, 0, 0, new WidgetPointer(ivar2)); + setWidgetPosition(ivar8, ivar9, 0, 0, new WidgetPointer(ivar3)); + } + return; +} diff --git a/dumps/scripts/847.cs2 b/dumps/scripts/847.cs2 new file mode 100644 index 0000000..cbdd511 --- /dev/null +++ b/dumps/scripts/847.cs2 @@ -0,0 +1,4 @@ +void script_847() { + script_849(bitconfig_4398, 1); + return; +} diff --git a/dumps/scripts/848.cs2 b/dumps/scripts/848.cs2 new file mode 100644 index 0000000..daf7561 --- /dev/null +++ b/dumps/scripts/848.cs2 @@ -0,0 +1,4 @@ +void script_848() { + script_849(bitconfig_4398, 0); + return; +} diff --git a/dumps/scripts/849.cs2 b/dumps/scripts/849.cs2 new file mode 100644 index 0000000..8c4cec0 --- /dev/null +++ b/dumps/scripts/849.cs2 @@ -0,0 +1,63 @@ +void script_849(int arg0,int arg1) { + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + ivar2 = ((int)cs2method_3408(105, 73, 1354, arg0)); + ivar3 = ((int)cs2method_3408(105, 73, 1355, arg0)); + ivar4 = ((int)cs2method_3408(105, 73, 1358, arg0)); + ivar5 = script_853(arg0); + ivar6 = script_854(arg0); + ivar7 = 0; + ivar8 = 0; + ivar9 = 0; + ivar10 = 0; + ivar11 = getWidgetActualX(new WidgetPointer(ivar2)); + ivar12 = getWidgetActualY(new WidgetPointer(ivar2)); + ivar13 = getWidgetActualX(new WidgetPointer(ivar3)); + ivar14 = getWidgetActualY(new WidgetPointer(ivar3)); + ivar15 = getWidgetRotateY(new WidgetPointer(ivar2)); + if (arg0 != 10) { + playSoundEffect(4503, 1, 0); + if (((boolean)arg1)) { + ivar15 = add(ivar15, 512); + if (ivar15 >= 2047) { + ivar15 = 0; + } + } else { + ivar15 = subtract(ivar15, 512); + if (ivar15 < 0) { + ivar15 = 2047; + } + } + setWidget3DRotation(0, 0, 512, ivar15, 0, 3500, new WidgetPointer(ivar2)); + setWidget3DRotation(0, 0, 512, ivar15, 0, 3500, new WidgetPointer(ivar3)); + setWidget3DRotation(0, 0, 512, ivar15, 0, 3500, new WidgetPointer(ivar4)); + if (script_850(ivar5) != script_850(ivar6)) { + if ((ivar15 == 512) || (ivar15 == 1536)) { + ivar9 = 9; + ivar10 = 9; + } else { + ivar9 = -9; + ivar10 = -9; + } + ivar11 = add(add(ivar11, ivar9), ivar7); + ivar12 = add(add(ivar12, ivar10), ivar8); + ivar13 = add(add(ivar13, ivar9), ivar7); + ivar14 = add(add(ivar14, ivar10), ivar8); + } + setWidgetPosition(ivar11, ivar12, 0, 0, new WidgetPointer(ivar2)); + setWidgetPosition(ivar13, ivar14, 0, 0, new WidgetPointer(ivar3)); + } + return; +} diff --git a/dumps/scripts/85.cs2 b/dumps/scripts/85.cs2 new file mode 100644 index 0000000..645fb85 --- /dev/null +++ b/dumps/scripts/85.cs2 @@ -0,0 +1,5 @@ +void script_85(int arg0) { + setWidgetText(new WidgetPointer(arg0), ""); + setWidgetNoOptions(new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/850.cs2 b/dumps/scripts/850.cs2 new file mode 100644 index 0000000..484b1f5 --- /dev/null +++ b/dumps/scripts/850.cs2 @@ -0,0 +1,6 @@ +int script_850(int arg0) { + if (((boolean)mod(arg0, 2))) { + return 1; + } + return 0; +} diff --git a/dumps/scripts/851.cs2 b/dumps/scripts/851.cs2 new file mode 100644 index 0000000..b3d82ea --- /dev/null +++ b/dumps/scripts/851.cs2 @@ -0,0 +1,36 @@ +int script_851(int arg0) { + if (arg0 == 10) { + return 0; + } + if (((boolean)arg0)) { + return bitconfig_4400; + } + if (((boolean)arg0)) { + return bitconfig_4404; + } + if (arg0 == 2) { + return bitconfig_4408; + } + if (arg0 == 3) { + return bitconfig_4412; + } + if (arg0 == 4) { + return bitconfig_4416; + } + if (arg0 == 5) { + return bitconfig_4420; + } + if (arg0 == 6) { + return bitconfig_4424; + } + if (arg0 == 7) { + return bitconfig_4428; + } + if (arg0 == 8) { + return bitconfig_4432; + } + if (arg0 == 9) { + return bitconfig_4436; + } + return 0; +} diff --git a/dumps/scripts/852.cs2 b/dumps/scripts/852.cs2 new file mode 100644 index 0000000..d8854ae --- /dev/null +++ b/dumps/scripts/852.cs2 @@ -0,0 +1,36 @@ +int script_852(int arg0) { + if (arg0 == 10) { + return 0; + } + if (((boolean)arg0)) { + return bitconfig_4401; + } + if (((boolean)arg0)) { + return bitconfig_4405; + } + if (arg0 == 2) { + return bitconfig_4409; + } + if (arg0 == 3) { + return bitconfig_4413; + } + if (arg0 == 4) { + return bitconfig_4417; + } + if (arg0 == 5) { + return bitconfig_4421; + } + if (arg0 == 6) { + return bitconfig_4425; + } + if (arg0 == 7) { + return bitconfig_4431; + } + if (arg0 == 8) { + return bitconfig_4433; + } + if (arg0 == 9) { + return bitconfig_4437; + } + return 0; +} diff --git a/dumps/scripts/853.cs2 b/dumps/scripts/853.cs2 new file mode 100644 index 0000000..64b7d7f --- /dev/null +++ b/dumps/scripts/853.cs2 @@ -0,0 +1,36 @@ +int script_853(int arg0) { + if (arg0 == 10) { + return 0; + } + if (((boolean)arg0)) { + return 2; + } + if (((boolean)arg0)) { + return 3; + } + if (arg0 == 2) { + return 4; + } + if (arg0 == 3) { + return 5; + } + if (arg0 == 4) { + return 3; + } + if (arg0 == 5) { + return 4; + } + if (arg0 == 6) { + return 4; + } + if (arg0 == 7) { + return 3; + } + if (arg0 == 8) { + return 4; + } + if (arg0 == 9) { + return 3; + } + return 0; +} diff --git a/dumps/scripts/854.cs2 b/dumps/scripts/854.cs2 new file mode 100644 index 0000000..6bf8dcc --- /dev/null +++ b/dumps/scripts/854.cs2 @@ -0,0 +1,36 @@ +int script_854(int arg0) { + if (arg0 == 10) { + return 0; + } + if (((boolean)arg0)) { + return 1; + } + if (((boolean)arg0)) { + return 1; + } + if (arg0 == 2) { + return 1; + } + if (arg0 == 3) { + return 1; + } + if (arg0 == 4) { + return 2; + } + if (arg0 == 5) { + return 2; + } + if (arg0 == 6) { + return 2; + } + if (arg0 == 7) { + return 2; + } + if (arg0 == 8) { + return 2; + } + if (arg0 == 9) { + return 3; + } + return 0; +} diff --git a/dumps/scripts/855.cs2 b/dumps/scripts/855.cs2 new file mode 100644 index 0000000..dc20c91 --- /dev/null +++ b/dumps/scripts/855.cs2 @@ -0,0 +1,36 @@ +int script_855(int arg0) { + if (arg0 == 10) { + return 0; + } + if (((boolean)arg0)) { + return bitconfig_4403; + } + if (((boolean)arg0)) { + return bitconfig_4406; + } + if (arg0 == 2) { + return bitconfig_4411; + } + if (arg0 == 3) { + return bitconfig_4415; + } + if (arg0 == 4) { + return bitconfig_4419; + } + if (arg0 == 5) { + return bitconfig_4423; + } + if (arg0 == 6) { + return bitconfig_4427; + } + if (arg0 == 7) { + return bitconfig_4430; + } + if (arg0 == 8) { + return bitconfig_4435; + } + if (arg0 == 9) { + return bitconfig_4439; + } + return 0; +} diff --git a/dumps/scripts/856.cs2 b/dumps/scripts/856.cs2 new file mode 100644 index 0000000..a3cc1a0 --- /dev/null +++ b/dumps/scripts/856.cs2 @@ -0,0 +1,8 @@ +void script_856() { + playSoundEffect(2605, 1, 0); + if (bitconfig_4400 < subtract(7, 1)) { + globalint_108 = add(bitconfig_4400, 1); + script_861(); + } + return; +} diff --git a/dumps/scripts/857.cs2 b/dumps/scripts/857.cs2 new file mode 100644 index 0000000..6e44e5a --- /dev/null +++ b/dumps/scripts/857.cs2 @@ -0,0 +1,8 @@ +void script_857() { + playSoundEffect(2605, 1, 0); + if (bitconfig_4400 > 0) { + globalint_108 = subtract(bitconfig_4400, 1); + script_861(); + } + return; +} diff --git a/dumps/scripts/858.cs2 b/dumps/scripts/858.cs2 new file mode 100644 index 0000000..9c3c0c9 --- /dev/null +++ b/dumps/scripts/858.cs2 @@ -0,0 +1,4 @@ +void script_858() { + playSoundEffect(2605, 1, 0); + return; +} diff --git a/dumps/scripts/859.cs2 b/dumps/scripts/859.cs2 new file mode 100644 index 0000000..0ecbfcf --- /dev/null +++ b/dumps/scripts/859.cs2 @@ -0,0 +1,4 @@ +void script_859() { + playSoundEffect(2605, 1, 0); + return; +} diff --git a/dumps/scripts/86.cs2 b/dumps/scripts/86.cs2 new file mode 100644 index 0000000..558fcc4 --- /dev/null +++ b/dumps/scripts/86.cs2 @@ -0,0 +1,68 @@ +void script_86(int arg0,int arg1,string arg2) { + int ivar2; + arg2 = strRemoveEntities(arg2); + ivar2 = cs2method5004(arg1); + switch (arg0) { + case 1: + clickPlayerOption(4, arg2); + break; + case 2: + clickPlayerOption(1, arg2); + break; + case 3: + clickPlayerOption(7, arg2); + break; + case 4: + clickPlayerOption(1, arg2); + break; + case 5: + clickPlayerOption(9, arg2); + break; + case 6: + if (((boolean)script_2709())) { + messageType0("You cannot add a friend until you have entered your date of birth"); + return; + } + if (isFriend(arg2)) { + if (isMuteRelatedMethod3329() && cs2method6900()) { + globalint_1650 = 1; + globalstring_23 = arg2; + script_1558(0); + return; + } + } else { + cs2method3605(arg2); + } + break; + case 7: + cs2method3607(arg2); + break; + case 8: + globalstring_24 = arg2; + break; + case 9: + if (ivar2 == 17) { + script_1052(4, cs2method5012(arg1), cs2method5010(arg1)); + } else if (ivar2 == 18) { + script_1052(5, cs2method5012(arg1), cs2method5010(arg1)); + } else if (ivar2 == 20) { + script_1052(6, cs2method5012(arg1), cs2method5010(arg1)); + } else if (ivar2 == 42) { + script_1052(9, cs2method5012(arg1), cs2method5010(arg1)); + } else { + if (ivar2 == 45) { + script_1052(11, cs2method5012(arg1), cs2method5010(arg1)); + } + } + break; + case 10: + if ((ivar2 == 41) || (ivar2 == 42)) { + script_4465(arg2); + } else if ((ivar2 == 9) || (ivar2 == 20)) { + script_1633(arg2); + } else { + clickPlayerOption(5, arg2); + } + } + return; +} diff --git a/dumps/scripts/860.cs2 b/dumps/scripts/860.cs2 new file mode 100644 index 0000000..29c22d1 --- /dev/null +++ b/dumps/scripts/860.cs2 @@ -0,0 +1,4 @@ +void script_860() { + playSoundEffect(4502, 1, 0); + return; +} diff --git a/dumps/scripts/861.cs2 b/dumps/scripts/861.cs2 new file mode 100644 index 0000000..9e5a03b --- /dev/null +++ b/dumps/scripts/861.cs2 @@ -0,0 +1,28 @@ +void script_861() { + setWidgetIsHidden(false, new WidgetPointer(682,29)); + setWidgetIsHidden(true, new WidgetPointer(682,30)); + setWidgetIsHidden(true, new WidgetPointer(682,31)); + setWidgetIsHidden(true, new WidgetPointer(682,32)); + setWidgetIsHidden(true, new WidgetPointer(682,33)); + setWidgetIsHidden(true, new WidgetPointer(682,34)); + setWidgetIsHidden(true, new WidgetPointer(682,35)); + if (globalint_108 > 0) { + setWidgetIsHidden(false, new WidgetPointer(682,30)); + } + if (globalint_108 > 1) { + setWidgetIsHidden(false, new WidgetPointer(682,31)); + } + if (globalint_108 > 2) { + setWidgetIsHidden(false, new WidgetPointer(682,32)); + } + if (globalint_108 > 3) { + setWidgetIsHidden(false, new WidgetPointer(682,33)); + } + if (globalint_108 > 4) { + setWidgetIsHidden(false, new WidgetPointer(682,34)); + } + if (globalint_108 > 5) { + setWidgetIsHidden(false, new WidgetPointer(682,35)); + } + return; +} diff --git a/dumps/scripts/862.cs2 b/dumps/scripts/862.cs2 new file mode 100644 index 0000000..dac680d --- /dev/null +++ b/dumps/scripts/862.cs2 @@ -0,0 +1,4 @@ +void script_862() { + setWidgetText(new WidgetPointer(689,8), intToStr(bitconfig_4449)); + return; +} diff --git a/dumps/scripts/863.cs2 b/dumps/scripts/863.cs2 new file mode 100644 index 0000000..75c175d --- /dev/null +++ b/dumps/scripts/863.cs2 @@ -0,0 +1,21 @@ +void script_863() { + if (((boolean)bitconfig_7912) && ((boolean)bitconfig_7921)) { + setWidgetModel(cs2method_3408(105, 109, 5079, bitconfig_7919), new WidgetPointer(986,3)); + setWidgetIsHidden(true, new WidgetPointer(986,16)); + if (bitconfig_7920 != 0) { + setWidgetIsHidden(false, new WidgetPointer(986,5)); + } + if (((boolean)bitconfig_7920)) { + setWidgetPosition(30, 205, 0, 0, new WidgetPointer(986,5)); + } else if (bitconfig_7920 == 2) { + setWidgetPosition(112, 205, 0, 0, new WidgetPointer(986,5)); + } else if (bitconfig_7920 == 3) { + setWidgetPosition(196, 205, 0, 0, new WidgetPointer(986,5)); + } else { + setWidgetIsHidden(true, new WidgetPointer(986,5)); + } + } else { + setWidgetModel(-1, new WidgetPointer(986,3)); + } + return; +} diff --git a/dumps/scripts/864.cs2 b/dumps/scripts/864.cs2 new file mode 100644 index 0000000..407ecaf --- /dev/null +++ b/dumps/scripts/864.cs2 @@ -0,0 +1,16 @@ +void script_864(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10) { + int ivar11; + ivar11 = 0; + if (((boolean)arg6)) { + ivar11 = getTextWidth(468, getWidgetText(new WidgetPointer(arg5))); + } else { + ivar11 = getWidgetActualWidth(new WidgetPointer(arg5)); + } + if (((boolean)arg1) && (subtract(getWidgetActualWidth(new WidgetPointer(arg0)), ivar11) < arg7)) { + setScriptCallOnGameloop(2929, new WidgetPointer(arg0), arg1, new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), new WidgetPointer(arg5), arg6, arg7, arg8, arg9, arg10, "I1IIII1iiii", new WidgetPointer(arg2)); + return; + } + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg2)); + setScriptCallOnGameloop(2930, new WidgetPointer(arg0), arg1, ivar11, new WidgetPointer(arg2), new WidgetPointer(arg3), new WidgetPointer(arg4), arg7, arg8, arg9, arg10, "I1iIIIiiii", new WidgetPointer(arg0)); + return; +} diff --git a/dumps/scripts/865.cs2 b/dumps/scripts/865.cs2 new file mode 100644 index 0000000..d3dd469 --- /dev/null +++ b/dumps/scripts/865.cs2 @@ -0,0 +1,23 @@ +void script_865() { + int ivar0; + int ivar1; + ivar0 = 0; + ivar1 = 0; + if (((boolean)standart_config_1113)) { + if (globalint_84 <= 2147482647) { + globalint_84 = add(globalint_84, 1000); + } + } else { + ivar0 = getItemAmtInContainer(93, standart_config_1109); + if (standart_config_1109 != getNotedItem(standart_config_1109)) { + ivar1 = getItemAmtInContainer(93, getNotedItem(standart_config_1109)); + } + globalint_84 = ivar0; + if ((globalint_84 <= 1000000000) && (ivar1 <= 1000000000)) { + globalint_84 = add(globalint_84, ivar1); + } + } + setWidgetText(new WidgetPointer(105,148), formatNumber(globalint_84, 1)); + script_602(); + return; +} diff --git a/dumps/scripts/866.cs2 b/dumps/scripts/866.cs2 new file mode 100644 index 0000000..1f39a79 --- /dev/null +++ b/dumps/scripts/866.cs2 @@ -0,0 +1,5 @@ +void script_866(int arg0,int arg1) { + setItemOnWidgetMethod2205(standart_config_853, 1, new WidgetPointer(arg0)); + setItemOnWidgetMethod2205(standart_config_854, 1, new WidgetPointer(arg1)); + return; +} diff --git a/dumps/scripts/867.cs2 b/dumps/scripts/867.cs2 new file mode 100644 index 0000000..201ad48 --- /dev/null +++ b/dumps/scripts/867.cs2 @@ -0,0 +1,5 @@ +void script_867(int arg0,int arg1,int arg2,int arg3) { + setWidgetSprite(arg1, new WidgetPointer(arg0)); + setWidgetIsHidden(((boolean)arg3), new WidgetPointer(arg2)); + return; +} diff --git a/dumps/scripts/868.cs2 b/dumps/scripts/868.cs2 new file mode 100644 index 0000000..ace885e --- /dev/null +++ b/dumps/scripts/868.cs2 @@ -0,0 +1,44 @@ +void script_868(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12,int arg13) { + int ivar14; + int ivar15; + int ivar16; + int ivar17; + ivar14 = script_718(globalint_1441); + ivar15 = script_718(globalint_1442); + ivar16 = script_715(ivar14, globalint_1443, ivar15, globalint_1444); + if (setWidgetRegister(new WidgetPointer(arg0))) { + setWidgetStringNode(718, script_4126(ivar16)); + setWidgetRGB(new Color(ivar16)); + } + if (setWidgetRegister(new WidgetPointer(arg8))) { + setWidgetStringNode(718, script_4126(ivar16)); + setWidgetRGB(new Color(ivar16)); + } + if (setWidgetRegister(new WidgetPointer(arg1))) { + setWidgetStringNode(718, script_4126(ivar14)); + setWidgetRGB(new Color(ivar14)); + } + if (setWidgetRegister(new WidgetPointer(arg2))) { + setWidgetStringNode(718, script_4126(ivar15)); + setWidgetRGB(new Color(ivar15)); + } + setWidgetModel(cs2method_3408(105, 109, 1595, divide(globalint_1450, 10)), new WidgetPointer(arg10)); + setWidgetModel(cs2method_3408(105, 109, 1595, mod(globalint_1450, 10)), new WidgetPointer(arg11)); + ivar17 = add(multiply(globalint_1441, globalint_1443), multiply(globalint_1442, globalint_1444)); + if (globalint_1450 < ivar17) { + setWidgetSprite(4567, new WidgetPointer(arg13)); + } else if (globalint_1450 > ivar17) { + setWidgetSprite(4568, new WidgetPointer(arg13)); + } else { + setWidgetSprite(4565, new WidgetPointer(arg13)); + playSoundEffect2False(3559, 1, 0, 255); + } + if (ivar16 == 16711935) { + setWidgetSprite(4565, new WidgetPointer(arg12)); + playSoundEffect2False(3559, 1, 10, 255); + } else { + setWidgetSprite(4566, new WidgetPointer(arg12)); + } + script_2472(arg3, arg4, arg5, arg6, arg7, arg9, standart_config_851, standart_config_852, 1109); + return; +} diff --git a/dumps/scripts/869.cs2 b/dumps/scripts/869.cs2 new file mode 100644 index 0000000..169eb00 --- /dev/null +++ b/dumps/scripts/869.cs2 @@ -0,0 +1,44 @@ +void script_869(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12,int arg13) { + int ivar14; + int ivar15; + int ivar16; + int ivar17; + ivar14 = script_718(globalint_1445); + ivar15 = script_718(globalint_1446); + ivar16 = script_715(ivar14, globalint_1447, ivar15, globalint_1448); + if (setWidgetRegister(new WidgetPointer(arg0))) { + setWidgetStringNode(718, script_4126(ivar16)); + setWidgetRGB(new Color(ivar16)); + } + if (setWidgetRegister(new WidgetPointer(arg8))) { + setWidgetStringNode(718, script_4126(ivar16)); + setWidgetRGB(new Color(ivar16)); + } + if (setWidgetRegister(new WidgetPointer(arg1))) { + setWidgetStringNode(718, script_4126(ivar14)); + setWidgetRGB(new Color(ivar14)); + } + if (setWidgetRegister(new WidgetPointer(arg2))) { + setWidgetStringNode(718, script_4126(ivar15)); + setWidgetRGB(new Color(ivar15)); + } + setWidgetModel(cs2method_3408(105, 109, 1595, divide(globalint_1451, 10)), new WidgetPointer(arg10)); + setWidgetModel(cs2method_3408(105, 109, 1595, mod(globalint_1451, 10)), new WidgetPointer(arg11)); + ivar17 = add(multiply(globalint_1445, globalint_1447), multiply(globalint_1446, globalint_1448)); + if (globalint_1451 < ivar17) { + setWidgetSprite(4567, new WidgetPointer(arg13)); + } else if (globalint_1451 > ivar17) { + setWidgetSprite(4568, new WidgetPointer(arg13)); + } else { + setWidgetSprite(4565, new WidgetPointer(arg13)); + playSoundEffect2False(3559, 1, 0, 255); + } + if (ivar16 == 16776960) { + setWidgetSprite(4565, new WidgetPointer(arg12)); + playSoundEffect2False(3559, 1, 10, 255); + } else { + setWidgetSprite(4566, new WidgetPointer(arg12)); + } + script_2472(arg3, arg4, arg5, arg6, arg7, arg9, standart_config_853, standart_config_854, 1110); + return; +} diff --git a/dumps/scripts/87.cs2 b/dumps/scripts/87.cs2 new file mode 100644 index 0000000..936e2f3 --- /dev/null +++ b/dumps/scripts/87.cs2 @@ -0,0 +1,9 @@ +void script_87(int arg0) { + setWidgetText(new WidgetPointer(arg0), "Score: " + intToStr(bitconfig_2121)); + if (((boolean)bitconfig_2121)) { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(arg0)); + } else { + setWidgetRGB(new Color(255, 255, 0), new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/870.cs2 b/dumps/scripts/870.cs2 new file mode 100644 index 0000000..cac0f45 --- /dev/null +++ b/dumps/scripts/870.cs2 @@ -0,0 +1,7 @@ +void script_870(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7) { + script_31(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + if (setWidgetRegister(new WidgetPointer(arg0), 1)) { + script_157(arg0, arg1, globalint_109, 1); + } + return; +} diff --git a/dumps/scripts/871.cs2 b/dumps/scripts/871.cs2 new file mode 100644 index 0000000..03bd9e0 --- /dev/null +++ b/dumps/scripts/871.cs2 @@ -0,0 +1,24 @@ +void script_871() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + ivar0 = subtract(20, 0); + ivar1 = subtract(80, 0); + ivar2 = divide(ivar1, ivar0); + ivar3 = multiply(bitconfig_4523, ivar2); + ivar4 = divide(1024, ivar1); + globalint_111 = ivar3; + ivar5 = multiply(globalint_111, ivar4); + ivar5 = add(ivar5, 512); + ivar5 = subtract(2048, ivar5); + setWidget3DRotation(0, 0, 0, 0, ivar5, 388, new WidgetPointer(717,4)); + script_896(); + ivar6 = multiply(cs2method_3408(105, 105, 1422, bitconfig_4519), divide(1024, ivar0)); + ivar6 = add(ivar6, 512); + setWidget3DRotation(0, 0, 0, 0, ivar6, 365, new WidgetPointer(717,3)); + return; +} diff --git a/dumps/scripts/872.cs2 b/dumps/scripts/872.cs2 new file mode 100644 index 0000000..868c4c9 --- /dev/null +++ b/dumps/scripts/872.cs2 @@ -0,0 +1,7 @@ +void script_872(int arg0) { + setWidgetModel(32408, new WidgetPointer(arg0)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(697,4)); + setWidgetIsHidden(true, new WidgetPointer(697,5)); + return; +} diff --git a/dumps/scripts/873.cs2 b/dumps/scripts/873.cs2 new file mode 100644 index 0000000..fa21013 --- /dev/null +++ b/dumps/scripts/873.cs2 @@ -0,0 +1,7 @@ +void script_873(int arg0) { + setWidgetModel(32408, new WidgetPointer(arg0)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(697,3)); + setWidgetIsHidden(true, new WidgetPointer(697,5)); + return; +} diff --git a/dumps/scripts/874.cs2 b/dumps/scripts/874.cs2 new file mode 100644 index 0000000..600759d --- /dev/null +++ b/dumps/scripts/874.cs2 @@ -0,0 +1,7 @@ +void script_874(int arg0) { + setWidgetModel(32408, new WidgetPointer(arg0)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(697,3)); + setWidgetIsHidden(true, new WidgetPointer(697,4)); + return; +} diff --git a/dumps/scripts/875.cs2 b/dumps/scripts/875.cs2 new file mode 100644 index 0000000..d3e29eb --- /dev/null +++ b/dumps/scripts/875.cs2 @@ -0,0 +1,6 @@ +void script_875(int arg0) { + setWidgetModel(32408, new WidgetPointer(arg0)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(694,24)); + return; +} diff --git a/dumps/scripts/876.cs2 b/dumps/scripts/876.cs2 new file mode 100644 index 0000000..a896b4c --- /dev/null +++ b/dumps/scripts/876.cs2 @@ -0,0 +1,6 @@ +void script_876(int arg0) { + setWidgetModel(32408, new WidgetPointer(arg0)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(694,23)); + return; +} diff --git a/dumps/scripts/877.cs2 b/dumps/scripts/877.cs2 new file mode 100644 index 0000000..40cd864 --- /dev/null +++ b/dumps/scripts/877.cs2 @@ -0,0 +1,6 @@ +void script_877(int arg0) { + setWidgetModel(32408, new WidgetPointer(arg0)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(696,4)); + return; +} diff --git a/dumps/scripts/878.cs2 b/dumps/scripts/878.cs2 new file mode 100644 index 0000000..e385b00 --- /dev/null +++ b/dumps/scripts/878.cs2 @@ -0,0 +1,6 @@ +void script_878(int arg0) { + setWidgetModel(32408, new WidgetPointer(arg0)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(696,3)); + return; +} diff --git a/dumps/scripts/879.cs2 b/dumps/scripts/879.cs2 new file mode 100644 index 0000000..e793475 --- /dev/null +++ b/dumps/scripts/879.cs2 @@ -0,0 +1,6 @@ +void script_879(int arg0) { + setWidgetModel(32408, new WidgetPointer(arg0)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(707,4)); + return; +} diff --git a/dumps/scripts/88.cs2 b/dumps/scripts/88.cs2 new file mode 100644 index 0000000..1c7eade --- /dev/null +++ b/dumps/scripts/88.cs2 @@ -0,0 +1,30 @@ +void script_88(int arg0,int arg1,string arg2) { + arg2 = strRemoveEntities(arg2); + switch (arg0) { + case 7: + if (((boolean)script_2709())) { + messageType0("You cannot add a friend until you have entered your date of birth"); + return; + } + if (isFriend(arg2)) { + if (isMuteRelatedMethod3329() && cs2method6900()) { + globalint_1650 = 1; + globalstring_23 = arg2; + script_1558(0); + return; + } + } else { + cs2method3605(arg2); + } + break; + case 8: + cs2method3607(arg2); + break; + case 9: + script_1052(5, cs2method5012(arg1), arg2); + break; + case 10: + globalstring_24 = arg2; + } + return; +} diff --git a/dumps/scripts/880.cs2 b/dumps/scripts/880.cs2 new file mode 100644 index 0000000..4b4737a --- /dev/null +++ b/dumps/scripts/880.cs2 @@ -0,0 +1,6 @@ +void script_880(int arg0) { + setWidgetModel(32408, new WidgetPointer(arg0)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(707,3)); + return; +} diff --git a/dumps/scripts/881.cs2 b/dumps/scripts/881.cs2 new file mode 100644 index 0000000..5bc48f8 --- /dev/null +++ b/dumps/scripts/881.cs2 @@ -0,0 +1,6 @@ +void script_881(int arg0) { + setWidgetModel(32408, new WidgetPointer(arg0)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(699,4)); + return; +} diff --git a/dumps/scripts/882.cs2 b/dumps/scripts/882.cs2 new file mode 100644 index 0000000..806412f --- /dev/null +++ b/dumps/scripts/882.cs2 @@ -0,0 +1,6 @@ +void script_882(int arg0) { + setWidgetModel(32408, new WidgetPointer(arg0)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(699,3)); + return; +} diff --git a/dumps/scripts/883.cs2 b/dumps/scripts/883.cs2 new file mode 100644 index 0000000..eba84f5 --- /dev/null +++ b/dumps/scripts/883.cs2 @@ -0,0 +1,6 @@ +void script_883(int arg0) { + setWidgetModel(32408, new WidgetPointer(arg0)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(708,13)); + return; +} diff --git a/dumps/scripts/884.cs2 b/dumps/scripts/884.cs2 new file mode 100644 index 0000000..bb85cf1 --- /dev/null +++ b/dumps/scripts/884.cs2 @@ -0,0 +1,6 @@ +void script_884(int arg0) { + setWidgetModel(32408, new WidgetPointer(arg0)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(708,12)); + return; +} diff --git a/dumps/scripts/885.cs2 b/dumps/scripts/885.cs2 new file mode 100644 index 0000000..4d60518 --- /dev/null +++ b/dumps/scripts/885.cs2 @@ -0,0 +1,7 @@ +void script_885(int arg0) { + setWidgetModel(32408, new WidgetPointer(arg0)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(704,11)); + setWidgetIsHidden(true, new WidgetPointer(704,12)); + return; +} diff --git a/dumps/scripts/886.cs2 b/dumps/scripts/886.cs2 new file mode 100644 index 0000000..b44f29c --- /dev/null +++ b/dumps/scripts/886.cs2 @@ -0,0 +1,7 @@ +void script_886(int arg0) { + setWidgetModel(32408, new WidgetPointer(arg0)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(704,10)); + setWidgetIsHidden(true, new WidgetPointer(704,12)); + return; +} diff --git a/dumps/scripts/887.cs2 b/dumps/scripts/887.cs2 new file mode 100644 index 0000000..32ee488 --- /dev/null +++ b/dumps/scripts/887.cs2 @@ -0,0 +1,7 @@ +void script_887(int arg0) { + setWidgetModel(32408, new WidgetPointer(arg0)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(704,10)); + setWidgetIsHidden(true, new WidgetPointer(704,11)); + return; +} diff --git a/dumps/scripts/888.cs2 b/dumps/scripts/888.cs2 new file mode 100644 index 0000000..fa353e8 --- /dev/null +++ b/dumps/scripts/888.cs2 @@ -0,0 +1,7 @@ +void script_888(int arg0) { + setWidgetModel(32408, new WidgetPointer(arg0)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(705,11)); + setWidgetIsHidden(true, new WidgetPointer(705,12)); + return; +} diff --git a/dumps/scripts/889.cs2 b/dumps/scripts/889.cs2 new file mode 100644 index 0000000..fcc9ca7 --- /dev/null +++ b/dumps/scripts/889.cs2 @@ -0,0 +1,7 @@ +void script_889(int arg0) { + setWidgetModel(32408, new WidgetPointer(arg0)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(705,10)); + setWidgetIsHidden(true, new WidgetPointer(705,12)); + return; +} diff --git a/dumps/scripts/89.cs2 b/dumps/scripts/89.cs2 new file mode 100644 index 0000000..a6136c1 --- /dev/null +++ b/dumps/scripts/89.cs2 @@ -0,0 +1,165 @@ +void script_89() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + flow_0: + if (cs2method5428(49414144, -1)) { + setScriptCallOnGameloop(1562, "", new WidgetPointer(754,0)); + return; + } + ivar0 = 0; + ivar1 = -1; + ivar2 = 0; + ivar3 = 0; + if (getSystemUpdateTimer() > 0) { + ivar2 = mod(divide(getSystemUpdateTimer(), 50), 60); + ivar3 = divide(getSystemUpdateTimer(), 3000); + if (ivar2 < 10) { + setWidgetText(new WidgetPointer(754,5), "" + "System update in: " + intToStr(ivar3) + ":0" + intToStr(ivar2)); + } else { + setWidgetText(new WidgetPointer(754,5), "" + "System update in: " + intToStr(ivar3) + ":" + intToStr(ivar2)); + } + ivar0 = 1; + setWidgetNoOptions(new WidgetPointer(754,5)); + setScriptCallOnClickContextMenu(-1, "", new WidgetPointer(754,5)); + setWidgetUnknownBoolean(true, new WidgetPointer(754,5)); + } + ivar4 = 0; + ivar5 = 0; + ivar6 = cs2method_3408(105, 105, 3056, standart_config_287); + ivar7 = cs2method_3408(105, 49, 3057, standart_config_287); + IF (standart_config_287 > 0) + GOTO flow_8 + GOTO flow_43 + flow_8: + IF (getDisplayMode() < 2) + GOTO flow_9 + IF ((globalint_41 != -1) && (ivar4 < 100)) + GOTO flow_10 + GOTO flow_43 + flow_9: + flow_10: + IF (ivar0 < 5) + GOTO flow_11 + GOTO flow_43 + flow_11: + if (((boolean)script_91(ivar4))) { + ivar1 = ((int)cs2method_3408(105, 73, 580, ivar0)); + setWidgetRGB(new Color(ivar6), new WidgetPointer(ivar1)); + setWidgetUnknownBoolean(((boolean)ivar7), new WidgetPointer(ivar1)); + ivar5 = cs2method5004(ivar4); + switch (ivar5) { + case 18: + case 3: + case 7: + setWidgetText(new WidgetPointer(ivar1), "From " + cs2method5010(ivar4) + ": " + cs2method5003(ivar4)); + break; + case 5: + setWidgetText(new WidgetPointer(ivar1), cs2method5003(ivar4)); + break; + case 19: + case 6: + setWidgetText(new WidgetPointer(ivar1), "To " + cs2method5010(ivar4) + ": " + cs2method5003(ivar4)); + } + setWidgetNoOptions(new WidgetPointer(ivar1)); + setScriptCallOnClickContextMenu(88, -2147483644, cs2method5019(ivar4), ivar4, "isi", new WidgetPointer(ivar1)); + switch (ivar5) { + flow_17: + case 3: + case 6: + case 7: + cs2method2305(new WidgetPointer(ivar1), "" + strRemoveEntities(cs2method5010(ivar4))); + if (stringMethod4107(strRemoveEntities(cs2method5015()), strRemoveEntities(cs2method5010(ivar4))) != 0) { + if (isFriend(cs2method5019(ivar4))) { + if (isMuteRelatedMethod3329() && cs2method6900()) { + setWidgetContextMenuOption(7, new WidgetPointer(ivar1), "Message"); + } + } else { + setWidgetContextMenuOption(7, new WidgetPointer(ivar1), "Add friend"); + setWidgetContextMenuOption(8, new WidgetPointer(ivar1), "Add ignore"); + } + if ((getClientRights() > 0) || (((int)hasMoreThen5Blackmarks()) > 0)) { + setWidgetContextMenuOption(10, new WidgetPointer(ivar1), "Report abuse"); + } + } + break; + case 19: + case 18: + cs2method2305(new WidgetPointer(ivar1), "" + strRemoveEntities(cs2method5010(ivar4))); + IF (stringMethod4107(strRemoveEntities(cs2method5015()), strRemoveEntities(cs2method5010(ivar4))) != 0) + GOTO flow_28 + break; + flow_28: + if (isFriend(cs2method5019(ivar4))) { + if (isMuteRelatedMethod3329() && cs2method6900()) { + setWidgetContextMenuOption(7, new WidgetPointer(ivar1), "Message"); + } + } else { + setWidgetContextMenuOption(7, new WidgetPointer(ivar1), "Add friend"); + setWidgetContextMenuOption(8, new WidgetPointer(ivar1), "Add ignore"); + } + if ((ivar5 == 18) && (cs2method5056(cs2method5012(ivar4)) > 0)) { + if (globalint_132 == -1) { + globalint_132 = cs2method5012(ivar4); + globalstring_29 = cs2method5010(ivar4); + globalint_133 = 5; + if (isFriend(cs2method5019(ivar4))) { + setWidgetContextMenuOption(9, new WidgetPointer(ivar1), "Quick Response"); + } + } else { + setWidgetContextMenuOption(9, new WidgetPointer(ivar1), "Quick Response"); + } + } + } + ivar0 = add(ivar0, 1); + } + ivar4 = add(ivar4, 1); + GOTO flow_9 + flow_43: + IF (ivar0 < 5) + GOTO flow_44 + GOTO flow_45 + flow_44: + ivar1 = ((int)cs2method_3408(105, 73, 580, ivar0)); + setWidgetText(new WidgetPointer(ivar1), ""); + setWidgetNoOptions(new WidgetPointer(ivar1)); + ivar0 = add(ivar0, 1); + GOTO flow_43 + flow_45: + ivar8 = 0; + ivar9 = 0; + if (getDisplayMode() >= 2) { + ivar9 = 9; + } else { + ivar9 = 5; + } + ivar8 = subtract(512, ivar9); + ivar0 = 0; + while (ivar0 < 5) { + ivar1 = ((int)cs2method_3408(105, 73, 580, ivar0)); + setWidgetSize(max(min(getMaxLineWidth(ivar8, getWidgetFont(new WidgetPointer(ivar1)), getWidgetText(new WidgetPointer(ivar1))), ivar8), 1), multiply(max(getLineCount(ivar8, getWidgetFont(new WidgetPointer(ivar1)), getWidgetText(new WidgetPointer(ivar1))), 1), 14), 0, 0, new WidgetPointer(ivar1)); + ivar0 = add(ivar0, 1); + } + ivar10 = -1; + ivar0 = 0; + ivar1 = ((int)cs2method_3408(105, 73, 580, ivar0)); + setWidgetPosition(ivar9, 2, 0, 2, new WidgetPointer(ivar1)); + ivar0 = 1; + while (ivar0 < 5) { + ivar1 = ((int)cs2method_3408(105, 73, 580, ivar0)); + ivar10 = ((int)cs2method_3408(105, 73, 580, subtract(ivar0, 1))); + if ((ivar1 != -1) && (ivar10 != -1)) { + setWidgetPosition(ivar9, subtract(getWidgetActualY(new WidgetPointer(ivar10)), getWidgetActualHeight(new WidgetPointer(ivar1))), 0, 0, new WidgetPointer(ivar1)); + } + ivar0 = add(ivar0, 1); + } + return; +} diff --git a/dumps/scripts/890.cs2 b/dumps/scripts/890.cs2 new file mode 100644 index 0000000..f230f0d --- /dev/null +++ b/dumps/scripts/890.cs2 @@ -0,0 +1,7 @@ +void script_890(int arg0) { + setWidgetModel(32408, new WidgetPointer(arg0)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(705,10)); + setWidgetIsHidden(true, new WidgetPointer(705,11)); + return; +} diff --git a/dumps/scripts/891.cs2 b/dumps/scripts/891.cs2 new file mode 100644 index 0000000..74faced --- /dev/null +++ b/dumps/scripts/891.cs2 @@ -0,0 +1,6 @@ +void script_891(int arg0) { + setWidgetModel(32408, new WidgetPointer(arg0)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(710,10)); + return; +} diff --git a/dumps/scripts/892.cs2 b/dumps/scripts/892.cs2 new file mode 100644 index 0000000..73dfbb0 --- /dev/null +++ b/dumps/scripts/892.cs2 @@ -0,0 +1,6 @@ +void script_892(int arg0) { + setWidgetModel(32408, new WidgetPointer(arg0)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(710,9)); + return; +} diff --git a/dumps/scripts/893.cs2 b/dumps/scripts/893.cs2 new file mode 100644 index 0000000..f94a0ff --- /dev/null +++ b/dumps/scripts/893.cs2 @@ -0,0 +1,47 @@ +void script_893() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + if (globalint_112 < 10) { + globalint_112 = add(globalint_112, 1); + return; + } + globalint_112 = 0; + ivar0 = subtract(20, 0); + ivar1 = subtract(80, 0); + ivar2 = divide(ivar1, ivar0); + ivar3 = multiply(bitconfig_4523, ivar2); + if (globalint_111 < ivar3) { + globalint_111 = add(globalint_111, 1); + } else { + if (globalint_111 > ivar3) { + globalint_111 = subtract(globalint_111, 1); + } + } + if (((boolean)globalint_114)) { + if (globalint_113 > 0) { + globalint_113 = subtract(globalint_113, 1); + } else { + globalint_114 = 1; + } + } else if (globalint_113 < 4) { + globalint_113 = add(globalint_113, 1); + } else { + globalint_114 = 0; + } + ivar4 = add(globalint_111, add(globalint_113, 2)); + ivar5 = divide(1024, ivar1); + ivar4 = multiply(ivar4, ivar5); + ivar4 = add(ivar4, 512); + ivar4 = subtract(2048, ivar4); + setWidget3DRotation(0, 0, 0, 0, ivar4, 388, new WidgetPointer(717,4)); + ivar6 = multiply(cs2method_3408(105, 105, 1422, bitconfig_4519), divide(1024, ivar0)); + ivar6 = add(ivar6, 512); + ivar6 = subtract(2048, ivar6); + setWidget3DRotation(0, 0, 0, 0, ivar6, 365, new WidgetPointer(717,3)); + return; +} diff --git a/dumps/scripts/894.cs2 b/dumps/scripts/894.cs2 new file mode 100644 index 0000000..c5c8241 --- /dev/null +++ b/dumps/scripts/894.cs2 @@ -0,0 +1,4 @@ +void script_894() { + script_896(); + return; +} diff --git a/dumps/scripts/895.cs2 b/dumps/scripts/895.cs2 new file mode 100644 index 0000000..a9d81ec --- /dev/null +++ b/dumps/scripts/895.cs2 @@ -0,0 +1,4 @@ +void script_895() { + script_896(); + return; +} diff --git a/dumps/scripts/896.cs2 b/dumps/scripts/896.cs2 new file mode 100644 index 0000000..aac9f5a --- /dev/null +++ b/dumps/scripts/896.cs2 @@ -0,0 +1,13 @@ +void script_896() { + int ivar0; + int ivar1; + int ivar2; + ivar0 = divide(116, 12); + ivar1 = multiply(ivar0, bitconfig_4527); + ivar2 = multiply(ivar0, bitconfig_4526); + setWidgetPosition(getWidgetActualX(new WidgetPointer(717,8)), add(122, subtract(116, ivar1)), 0, 0, new WidgetPointer(717,8)); + setWidgetPosition(getWidgetActualX(new WidgetPointer(717,7)), add(122, subtract(116, ivar2)), 0, 0, new WidgetPointer(717,7)); + setWidgetSize(27, ivar1, 0, 0, new WidgetPointer(717,8)); + setWidgetSize(27, ivar2, 0, 0, new WidgetPointer(717,7)); + return; +} diff --git a/dumps/scripts/897.cs2 b/dumps/scripts/897.cs2 new file mode 100644 index 0000000..dc51a92 --- /dev/null +++ b/dumps/scripts/897.cs2 @@ -0,0 +1,4 @@ +void script_897() { + setWidgetIsHidden(false, new WidgetPointer(717,33)); + return; +} diff --git a/dumps/scripts/898.cs2 b/dumps/scripts/898.cs2 new file mode 100644 index 0000000..65cdda7 --- /dev/null +++ b/dumps/scripts/898.cs2 @@ -0,0 +1,4 @@ +void script_898() { + setWidgetIsHidden(true, new WidgetPointer(717,33)); + return; +} diff --git a/dumps/scripts/899.cs2 b/dumps/scripts/899.cs2 new file mode 100644 index 0000000..c56e2d6 --- /dev/null +++ b/dumps/scripts/899.cs2 @@ -0,0 +1,4 @@ +void script_899() { + setWidgetIsHidden(false, new WidgetPointer(717,35)); + return; +} diff --git a/dumps/scripts/9.cs2 b/dumps/scripts/9.cs2 new file mode 100644 index 0000000..0e88587 --- /dev/null +++ b/dumps/scripts/9.cs2 @@ -0,0 +1,18 @@ +void script_9(int arg0,int arg1,int arg2) { + if (((boolean)globalint_169)) { + setWidgetIsHidden(false, new WidgetPointer(arg0)); + setWidgetIsHidden(false, new WidgetPointer(arg1)); + setWidgetIsHidden(false, new WidgetPointer(arg2)); + script_680(arg0); + setScriptCallOnMouseEntered(95, new WidgetPointer(arg0), "I", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(93, new WidgetPointer(arg0), "I", new WidgetPointer(arg0)); + } else { + deleteAllExtraChilds(new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(arg0)); + setWidgetIsHidden(true, new WidgetPointer(arg1)); + setWidgetIsHidden(true, new WidgetPointer(arg2)); + setScriptCallOnMouseEntered(-1, "", new WidgetPointer(arg0)); + setScriptCallOnMouseExit(-1, "", new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/90.cs2 b/dumps/scripts/90.cs2 new file mode 100644 index 0000000..18da33c --- /dev/null +++ b/dumps/scripts/90.cs2 @@ -0,0 +1,129 @@ +int script_90(int arg0,int arg1) { + switch (cs2method5004(arg0)) { + case -1: + return 0; + case 0: + case 1: + case 4: + case 27: + case 26: + case 29: + case 28: + case 31: + case 30: + case 110: + case 117: + case 116: + case 115: + return 1; + case 109: + if (((boolean)bitconfig_6161)) { + return 0; + } + return 1; + case 2: + case 17: + if (((boolean)cs2method5000())) { + return 1; + } + if (((boolean)cs2method5000()) && isFriend(cs2method5019(arg0))) { + return 1; + } + return 0; + case 3: + case 18: + if (((standart_config_287 > 0) && (globalint_41 >= 0)) && (((boolean)arg1) && ((boolean)script_506(arg0)))) { + return 0; + } + if (((boolean)cs2method5005())) { + return 1; + } + if (((boolean)cs2method5005()) && isFriend(cs2method5019(arg0))) { + return 1; + } + return 0; + case 100: + case 101: + case 111: + case 108: + case 106: + case 105: + case 118: + case 114: + case 113: + case 112: + if (((boolean)cs2method5016())) { + return 1; + } + if (((boolean)cs2method5016()) && isFriend(cs2method5019(arg0))) { + return 1; + } + return 0; + case 5: + case 6: + case 19: + if (((standart_config_287 > 0) && (globalint_41 >= 0)) && (((boolean)arg1) && ((boolean)script_506(arg0)))) { + return 0; + } + if (cs2method5005() < 2) { + return 1; + } + return 0; + case 7: + if (((standart_config_287 > 0) && (globalint_41 >= 0)) && (((boolean)arg1) && ((boolean)script_506(arg0)))) { + return 0; + } + return 1; + case 42: + case 41: + case 107: + case 44: + case 45: + if (((boolean)standart_config_1054)) { + return 1; + } + if (((boolean)standart_config_1054) && isFriend(cs2method5019(arg0))) { + return 1; + } + return 0; + case 9: + case 20: + if (((boolean)standart_config_2159)) { + return 1; + } + if (((boolean)standart_config_2159) && isFriend(cs2method5019(arg0))) { + return 1; + } + return 0; + case 102: + if (((boolean)standart_config_1055)) { + return 1; + } + if (((boolean)standart_config_1055) && isFriend(cs2method5019(arg0))) { + return 1; + } + return 0; + case 11: + if (standart_config_2159 < 2) { + return 1; + } + return 0; + case 43: + case 46: + if (standart_config_1054 < 2) { + return 1; + } + return 0; + case 103: + if (cs2method5016() < 2) { + return 1; + } + return 0; + case 104: + if (standart_config_1055 < 2) { + return 1; + } + return 0; + } + return 1; +} diff --git a/dumps/scripts/900.cs2 b/dumps/scripts/900.cs2 new file mode 100644 index 0000000..0d596f0 --- /dev/null +++ b/dumps/scripts/900.cs2 @@ -0,0 +1,4 @@ +void script_900() { + setWidgetIsHidden(true, new WidgetPointer(717,35)); + return; +} diff --git a/dumps/scripts/901.cs2 b/dumps/scripts/901.cs2 new file mode 100644 index 0000000..c36dcd1 --- /dev/null +++ b/dumps/scripts/901.cs2 @@ -0,0 +1,5 @@ +void script_901() { + setWidget3DRotation(0, 0, 0, 0, 1024, 400, new WidgetPointer(717,14)); + setWidgetPosition(subtract(getWidgetActualX(new WidgetPointer(717,14)), 2), subtract(getWidgetActualY(new WidgetPointer(717,14)), 2), 0, 0, new WidgetPointer(717,14)); + return; +} diff --git a/dumps/scripts/902.cs2 b/dumps/scripts/902.cs2 new file mode 100644 index 0000000..e4d336b --- /dev/null +++ b/dumps/scripts/902.cs2 @@ -0,0 +1,5 @@ +void script_902() { + setWidget3DRotation(0, 0, 0, 0, 0, 400, new WidgetPointer(717,14)); + setWidgetPosition(add(getWidgetActualX(new WidgetPointer(717,14)), 2), add(getWidgetActualY(new WidgetPointer(717,14)), 2), 0, 0, new WidgetPointer(717,14)); + return; +} diff --git a/dumps/scripts/903.cs2 b/dumps/scripts/903.cs2 new file mode 100644 index 0000000..317ff5f --- /dev/null +++ b/dumps/scripts/903.cs2 @@ -0,0 +1,5 @@ +void script_903() { + setWidget3DRotation(0, 0, 0, 0, 1024, 400, new WidgetPointer(717,13)); + setWidgetPosition(subtract(getWidgetActualX(new WidgetPointer(717,13)), 2), subtract(getWidgetActualY(new WidgetPointer(717,13)), 2), 0, 0, new WidgetPointer(717,13)); + return; +} diff --git a/dumps/scripts/904.cs2 b/dumps/scripts/904.cs2 new file mode 100644 index 0000000..ef7e8f0 --- /dev/null +++ b/dumps/scripts/904.cs2 @@ -0,0 +1,5 @@ +void script_904() { + setWidget3DRotation(0, 0, 0, 0, 0, 400, new WidgetPointer(717,13)); + setWidgetPosition(add(getWidgetActualX(new WidgetPointer(717,13)), 2), add(getWidgetActualY(new WidgetPointer(717,13)), 2), 0, 0, new WidgetPointer(717,13)); + return; +} diff --git a/dumps/scripts/905.cs2 b/dumps/scripts/905.cs2 new file mode 100644 index 0000000..3b934f7 --- /dev/null +++ b/dumps/scripts/905.cs2 @@ -0,0 +1,4 @@ +void script_905() { + globalint_116 = 0; + return; +} diff --git a/dumps/scripts/906.cs2 b/dumps/scripts/906.cs2 new file mode 100644 index 0000000..39602a3 --- /dev/null +++ b/dumps/scripts/906.cs2 @@ -0,0 +1,4 @@ +void script_906() { + globalint_116 = 1; + return; +} diff --git a/dumps/scripts/907.cs2 b/dumps/scripts/907.cs2 new file mode 100644 index 0000000..c93bd2c --- /dev/null +++ b/dumps/scripts/907.cs2 @@ -0,0 +1,4 @@ +void script_907() { + globalint_116 = 0; + return; +} diff --git a/dumps/scripts/908.cs2 b/dumps/scripts/908.cs2 new file mode 100644 index 0000000..786f5a0 --- /dev/null +++ b/dumps/scripts/908.cs2 @@ -0,0 +1,4 @@ +void script_908() { + globalint_117 = 1; + return; +} diff --git a/dumps/scripts/909.cs2 b/dumps/scripts/909.cs2 new file mode 100644 index 0000000..ea6afe2 --- /dev/null +++ b/dumps/scripts/909.cs2 @@ -0,0 +1,4 @@ +void script_909() { + globalint_117 = 0; + return; +} diff --git a/dumps/scripts/91.cs2 b/dumps/scripts/91.cs2 new file mode 100644 index 0000000..1cb10e8 --- /dev/null +++ b/dumps/scripts/91.cs2 @@ -0,0 +1,23 @@ +int script_91(int arg0) { + switch (cs2method5004(arg0)) { + case 7: + return 1; + case 18: + case 3: + if (((boolean)cs2method5005())) { + return 1; + } + if (((boolean)cs2method5005()) && isFriend(cs2method5019(arg0))) { + return 1; + } + return 0; + case 19: + case 5: + case 6: + if (cs2method5005() < 2) { + return 1; + } + return 0; + } + return 0; +} diff --git a/dumps/scripts/910.cs2 b/dumps/scripts/910.cs2 new file mode 100644 index 0000000..215b7b4 --- /dev/null +++ b/dumps/scripts/910.cs2 @@ -0,0 +1,8 @@ +void script_910() { + if (((boolean)globalint_116) || ((boolean)globalint_117)) { + setWidgetBorderThickness(2, new WidgetPointer(716,31)); + } else { + setWidgetBorderThickness(0, new WidgetPointer(716,31)); + } + return; +} diff --git a/dumps/scripts/911.cs2 b/dumps/scripts/911.cs2 new file mode 100644 index 0000000..cf55f27 --- /dev/null +++ b/dumps/scripts/911.cs2 @@ -0,0 +1,12 @@ +void script_911() { + if (((boolean)bitconfig_4532) && (globalint_118 < 253)) { + globalint_118 = add(globalint_118, 3); + cs2method2103(subtract(255, globalint_118), new WidgetPointer(721,3)); + } else { + if (((boolean)bitconfig_4532) && (globalint_118 > 3)) { + globalint_118 = subtract(globalint_118, 3); + cs2method2103(subtract(255, globalint_118), new WidgetPointer(721,3)); + } + } + return; +} diff --git a/dumps/scripts/912.cs2 b/dumps/scripts/912.cs2 new file mode 100644 index 0000000..9f379ca --- /dev/null +++ b/dumps/scripts/912.cs2 @@ -0,0 +1,24 @@ +string script_912(int arg0) { + string svar0; + svar0 = cs2method_3408(111, 115, 1440, arg0); + if (stringMethod4107(svar0, "") != 0) { + return "
" + svar0; + } + switch (globalint_746) { + case 0: + if (getItemHashmapData(arg0, 1047) != 1) { + return "
" + cs2method_3408(105, 115, 1437, getItemHashmapData(arg0, 23)); + } + break; + case 1: + return "
" + cs2method_3408(105, 115, 1439, getItemHashmapData(arg0, 23)); + case 2: + case 5: + return "
" + cs2method_3408(105, 115, 1436, getItemHashmapData(arg0, 23)); + case 3: + return "
" + cs2method_3408(105, 115, 1438, getItemHashmapData(arg0, 23)); + case 4: + return "
" + "Requires an ogre composite bow."; + } + return ""; +} diff --git a/dumps/scripts/913.cs2 b/dumps/scripts/913.cs2 new file mode 100644 index 0000000..1be86a5 --- /dev/null +++ b/dumps/scripts/913.cs2 @@ -0,0 +1,6 @@ +string script_913(int arg0,int arg1,string arg2) { + if (arg0 < arg1) { + return "
" + "" + arg2; + } + return "
" + "" + arg2; +} diff --git a/dumps/scripts/914.cs2 b/dumps/scripts/914.cs2 new file mode 100644 index 0000000..89b3392 --- /dev/null +++ b/dumps/scripts/914.cs2 @@ -0,0 +1,3 @@ +string script_914() { + return script_2706(globalint_741); +} diff --git a/dumps/scripts/915.cs2 b/dumps/scripts/915.cs2 new file mode 100644 index 0000000..9822110 --- /dev/null +++ b/dumps/scripts/915.cs2 @@ -0,0 +1,25 @@ +void script_915(int arg0) { + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + deleteAllExtraChilds(new WidgetPointer(arg0)); + ivar1 = getWidgetActualWidth(new WidgetPointer(arg0)); + ivar2 = getWidgetActualHeight(new WidgetPointer(arg0)); + ivar3 = subtract(ivar1, 9); + ivar4 = subtract(ivar2, 9); + ivar5 = subtract(ivar1, 18); + ivar6 = subtract(ivar2, 18); + script_98(arg0, 0, 1040, 0, 0, ivar1, ivar2); + script_98(arg0, 1, 929, 0, 0, 9, 9); + script_98(arg0, 2, 930, ivar3, 0, 9, 9); + script_98(arg0, 3, 931, 0, ivar4, 9, 9); + script_98(arg0, 4, 932, ivar3, ivar4, 9, 9); + script_98(arg0, 5, 933, 0, 9, 9, ivar6); + script_98(arg0, 6, 934, 9, 0, ivar5, 9); + script_98(arg0, 7, 935, ivar3, 9, 9, ivar6); + script_98(arg0, 8, 936, 9, ivar4, ivar5, 9); + return; +} diff --git a/dumps/scripts/916.cs2 b/dumps/scripts/916.cs2 new file mode 100644 index 0000000..0d97ad9 --- /dev/null +++ b/dumps/scripts/916.cs2 @@ -0,0 +1,4 @@ +void script_916() { + script_917(); + return; +} diff --git a/dumps/scripts/917.cs2 b/dumps/scripts/917.cs2 new file mode 100644 index 0000000..cd6d6f4 --- /dev/null +++ b/dumps/scripts/917.cs2 @@ -0,0 +1,49 @@ +void script_917() { + int ivar0; + int ivar1; + int ivar2; + deleteAllExtraChilds(new WidgetPointer(449,8)); + globalint_742 = 0; + ivar0 = 0; + setWidgetRGB(new Color(globalint_1241), new WidgetPointer(449,2)); + setWidgetRGB(new Color(globalint_1241), new WidgetPointer(449,14)); + setWidgetRGB(new Color(globalint_1241), new WidgetPointer(449,22)); + setWidgetRGB(new Color(globalint_1241), new WidgetPointer(449,24)); + if (globalint_743 != -1) { + ivar0 = getItemAmtInContainer(93, globalint_743); + script_919(); + setWidgetIsHidden(false, new WidgetPointer(449,15)); + setWidgetSize(16384, 147, 2, 0, new WidgetPointer(449,6)); + } else if ((standart_config_1109 != -1) && (multiply(standart_config_1111, standart_config_1110) > ivar0)) { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(449,25)); + } else { + setWidgetRGB(new Color(globalint_1241), new WidgetPointer(449,25)); + } + ivar0 = getItemAmtInContainer(93, 995); + setItemOnWidgetMethod2205(-1, -1, new WidgetPointer(449,23)); + setWidgetIsHidden(true, new WidgetPointer(449,15)); + setWidgetSize(16384, 187, 2, 0, new WidgetPointer(449,6)); + if (((boolean)ivar0)) { + setWidgetText(new WidgetPointer(449,25), "You have no " + cs2method_3408(111, 115, 62, globalint_743) + "."); + } else if (((boolean)ivar0)) { + setWidgetText(new WidgetPointer(449,25), "You have one " + cs2method_3408(111, 115, 923, globalint_743) + "."); + } else { + setWidgetText(new WidgetPointer(449,25), "You have " + script_940(ivar0) + " " + cs2method_3408(111, 115, 62, globalint_743) + "."); + } + ivar1 = 181; + ivar2 = script_920(ivar1); + if (ivar2 > getWidgetActualHeight(new WidgetPointer(449,8))) { + ivar1 = 165; + deleteAllExtraChilds(new WidgetPointer(449,8)); + ivar2 = script_920(ivar1); + } else { + deleteAllExtraChilds(new WidgetPointer(449,9)); + } + setWidgetScrollMax(ivar1, ivar2, new WidgetPointer(449,8)); + setWidgetSize(ivar1, 6, 0, 1, new WidgetPointer(449,8)); + cs2method2100(0, 0, new WidgetPointer(449,8)); + if (ivar2 > getWidgetActualHeight(new WidgetPointer(449,8))) { + script_31(29425673, 29425672, 792, 789, 790, 791, 773, 788); + } + return; +} diff --git a/dumps/scripts/918.cs2 b/dumps/scripts/918.cs2 new file mode 100644 index 0000000..12616ca --- /dev/null +++ b/dumps/scripts/918.cs2 @@ -0,0 +1,4 @@ +void script_918() { + script_919(); + return; +} diff --git a/dumps/scripts/919.cs2 b/dumps/scripts/919.cs2 new file mode 100644 index 0000000..4fa89d7 --- /dev/null +++ b/dumps/scripts/919.cs2 @@ -0,0 +1,40 @@ +void script_919() { + int ivar0; + int ivar1; + string svar0; + ivar0 = getItemAmtInContainer(93, globalint_743); + svar0 = "Cost:"; + ivar1 = -1; + if (((boolean)globalint_744)) { + svar0 = "None available"; + } else if (globalint_744 == -1) { + svar0 = "Free sample!"; + } else { + ivar1 = globalint_744; + } + setWidgetText(new WidgetPointer(449,24), svar0); + if (ivar1 > ivar0) { + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(449,25)); + } else { + setWidgetRGB(new Color(globalint_1241), new WidgetPointer(449,25)); + } + if (ivar1 > -1) { + setItemOnWidgetMethod2212(globalint_743, ivar1, new WidgetPointer(449,23)); + } else { + setItemOnWidgetMethod2205(-1, -1, new WidgetPointer(449,23)); + } + if (globalint_744 == -1) { + setWidgetText(new WidgetPointer(449,22), "Take"); + setWidgetContextMenuOption(1, new WidgetPointer(449,21), "Take 1"); + setWidgetContextMenuOption(2, new WidgetPointer(449,21), "Take 5"); + setWidgetContextMenuOption(3, new WidgetPointer(449,21), "Take 10"); + setWidgetContextMenuOption(4, new WidgetPointer(449,21), "Take 50"); + } else { + setWidgetText(new WidgetPointer(449,22), "Buy"); + setWidgetContextMenuOption(1, new WidgetPointer(449,21), "Buy 1"); + setWidgetContextMenuOption(2, new WidgetPointer(449,21), "Buy 5"); + setWidgetContextMenuOption(3, new WidgetPointer(449,21), "Buy 10"); + setWidgetContextMenuOption(4, new WidgetPointer(449,21), "Buy 50"); + } + return; +} diff --git a/dumps/scripts/92.cs2 b/dumps/scripts/92.cs2 new file mode 100644 index 0000000..053cff2 --- /dev/null +++ b/dumps/scripts/92.cs2 @@ -0,0 +1,4 @@ +void script_92(int arg0) { + script_679(arg0); + return; +} diff --git a/dumps/scripts/920.cs2 b/dumps/scripts/920.cs2 new file mode 100644 index 0000000..bfa9cc4 --- /dev/null +++ b/dumps/scripts/920.cs2 @@ -0,0 +1,53 @@ +int script_920(int arg0) { + int ivar1; + string svar0; + globalint_742 = 0; + svar0 = ""; + ivar1 = 0; + if (globalint_741 != -1) { + if (((boolean)stringMethod4107(getItemOption(globalint_741, 2), "Wear")) || ((boolean)stringMethod4107(getItemOption(globalint_741, 2), "Wield"))) { + ivar1 = 1; + } + setItemOnWidgetMethod2205(globalint_741, -1, new WidgetPointer(449,13)); + setItemOnWidgetMethod2205(globalint_741, -1, new WidgetPointer(449,14)); + if (isMember() && isMembersItem(globalint_741)) { + script_922(1, arg0, "This is a members item. Additional information is not available on this world."); + } else { + svar0 = script_914(); + if (stringMethod4107(svar0, "") != 0) { + script_922(1, arg0, svar0); + globalint_742 = add(globalint_742, 1); + } + script_921(1, arg0, globalstring_25); + if (stringMethod4107(getItemHashmapData(globalint_741, 690), "") != 0) { + script_921(1, arg0, " "); + script_921(1, arg0, getItemHashmapData(globalint_741, 690)); + } + if (((boolean)mod(getItemHashmapData(globalint_741, 740), 2))) { + if ((stringMethod4107(globalstring_26, "") != 0) && ((boolean)ivar1)) { + script_921(0, arg0, globalstring_26); + } + if (stringMethod4107(globalstring_34, "") != 0) { + script_921(0, arg0, globalstring_34); + } + } else { + if (stringMethod4107(globalstring_34, "") != 0) { + script_921(0, arg0, globalstring_34); + } + if ((stringMethod4107(globalstring_26, "") != 0) && ((boolean)ivar1)) { + script_921(0, arg0, globalstring_26); + } + } + svar0 = script_912(globalint_741); + if (stringMethod4107(svar0, "") != 0) { + script_921(0, arg0, svar0); + } + if ((stringMethod4107(globalstring_35, "") != 0) && ((boolean)ivar1)) { + script_923(arg0, globalstring_35, globalstring_36, globalstring_52); + } + } + } else { + script_921(1, arg0, "Select an item to see its information."); + } + return add(multiply(6, 2), multiply(globalint_742, 11)); +} diff --git a/dumps/scripts/921.cs2 b/dumps/scripts/921.cs2 new file mode 100644 index 0000000..8f2201e --- /dev/null +++ b/dumps/scripts/921.cs2 @@ -0,0 +1,6 @@ +void script_921(int arg0,int arg1,string arg2) { + int ivar2; + ivar2 = getLineCount(arg1, 494, arg2); + script_924(ivar2, arg0, 1, 494, arg2); + return; +} diff --git a/dumps/scripts/922.cs2 b/dumps/scripts/922.cs2 new file mode 100644 index 0000000..e34d87e --- /dev/null +++ b/dumps/scripts/922.cs2 @@ -0,0 +1,62 @@ +void script_922(int arg0,int arg1,string arg2) { + int ivar2; + int ivar3; + ivar2 = getLineCount(135, 494, arg2); + ivar3 = add(6, multiply(globalint_742, 11)); + if (stringMethod4107(arg2, "") != 0) { + createExtraChild(new WidgetPointer(449,8), 4, getExtraChildGap(new WidgetPointer(449,8))); + setWidgetPosition(0, add(ivar3, 3), 1, 0); + setWidgetSize(135, multiply(11, ivar2), 0, 0); + setWidgetFont(494); + setWidgetRGB(new Color(198, 2, 2)); + setWidgetText(arg2); + setWidgetUnknownBoolean(true); + setWidgetTextAlignment(arg0, 0, 0); + globalint_742 = add(globalint_742, ivar2); + } + createExtraChild(new WidgetPointer(449,8), 5, getExtraChildGap(new WidgetPointer(449,8))); + setWidgetSize(12, 12, 0, 0); + setWidgetPosition(3, add(ivar3, 3), 0, 0); + setWidgetSprite(2180); + createExtraChild(new WidgetPointer(449,8), 5, getExtraChildGap(new WidgetPointer(449,8))); + setWidgetSize(12, 12, 0, 0); + setWidgetPosition(3, add(ivar3, 3), 2, 0); + setWidgetSprite(2180); + createExtraChild(new WidgetPointer(449,8), 5, getExtraChildGap(new WidgetPointer(449,8))); + setWidgetSize(4, 4, 0, 0); + setWidgetPosition(0, ivar3, 0, 0); + setWidgetSprite(2225); + createExtraChild(new WidgetPointer(449,8), 5, getExtraChildGap(new WidgetPointer(449,8))); + setWidgetSize(subtract(arg1, 8), 4, 0, 0); + setWidgetPosition(4, ivar3, 0, 0); + setWidgetSprite(2226); + cs2method1107(1); + createExtraChild(new WidgetPointer(449,8), 5, getExtraChildGap(new WidgetPointer(449,8))); + setWidgetSize(4, 4, 0, 0); + setWidgetPosition(0, ivar3, 2, 0); + setWidgetSprite(2227); + createExtraChild(new WidgetPointer(449,8), 5, getExtraChildGap(new WidgetPointer(449,8))); + setWidgetSize(4, subtract(multiply(11, ivar2), 2), 0, 0); + setWidgetPosition(-2, add(ivar3, 4), 2, 0); + setWidgetSprite(2228); + cs2method1107(1); + createExtraChild(new WidgetPointer(449,8), 5, getExtraChildGap(new WidgetPointer(449,8))); + setWidgetSize(4, 4, 0, 0); + setWidgetPosition(0, add(multiply(11, ivar2), 8), 2, 0); + setWidgetSprite(2230); + createExtraChild(new WidgetPointer(449,8), 5, getExtraChildGap(new WidgetPointer(449,8))); + setWidgetSize(subtract(arg1, 8), 4, 0, 0); + setWidgetPosition(4, add(multiply(11, ivar2), 10), 0, 0); + setWidgetSprite(2226); + cs2method1107(1); + createExtraChild(new WidgetPointer(449,8), 5, getExtraChildGap(new WidgetPointer(449,8))); + setWidgetSize(4, 4, 0, 0); + setWidgetPosition(0, add(multiply(11, ivar2), 8), 0, 0); + setWidgetSprite(2229); + createExtraChild(new WidgetPointer(449,8), 5, getExtraChildGap(new WidgetPointer(449,8))); + setWidgetSize(4, subtract(multiply(11, ivar2), 2), 0, 0); + setWidgetPosition(0, add(ivar3, 4), 0, 0); + setWidgetSprite(2228); + cs2method1107(1); + return; +} diff --git a/dumps/scripts/923.cs2 b/dumps/scripts/923.cs2 new file mode 100644 index 0000000..9029799 --- /dev/null +++ b/dumps/scripts/923.cs2 @@ -0,0 +1,17 @@ +void script_923(int arg0,string arg1,string arg2,string arg3) { + int ivar1; + int ivar2; + ivar1 = getLineCount(arg0, 494, arg1); + ivar2 = getLineCount(arg0, 494, arg2); + if (ivar2 > ivar1) { + ivar1 = ivar2; + } + ivar2 = getLineCount(arg0, 494, arg3); + if (ivar2 > ivar1) { + ivar1 = ivar2; + } + script_924(ivar1, 0, 0, 494, arg1); + script_924(ivar1, 1, 0, 494, arg2); + script_924(ivar1, 2, 1, 494, arg3); + return; +} diff --git a/dumps/scripts/924.cs2 b/dumps/scripts/924.cs2 new file mode 100644 index 0000000..0616a08 --- /dev/null +++ b/dumps/scripts/924.cs2 @@ -0,0 +1,17 @@ +void script_924(int arg0,int arg1,int arg2,int arg3,string arg4) { + int ivar4; + ivar4 = add(6, multiply(globalint_742, 11)); + if (stringMethod4107(arg4, "") != 0) { + createExtraChild(new WidgetPointer(449,8), 4, getExtraChildGap(new WidgetPointer(449,8))); + setWidgetPosition(0, ivar4, 0, 0); + setWidgetSize(16384, multiply(11, arg0), 2, 0); + setWidgetFont(arg3); + setWidgetRGB(new Color(globalint_1242)); + setWidgetText(arg4); + setWidgetTextAlignment(arg1, 0, 0); + if (((boolean)arg2)) { + globalint_742 = add(globalint_742, arg0); + } + } + return; +} diff --git a/dumps/scripts/925.cs2 b/dumps/scripts/925.cs2 new file mode 100644 index 0000000..a13d960 --- /dev/null +++ b/dumps/scripts/925.cs2 @@ -0,0 +1,15 @@ +int script_925(int arg0) { + if (((boolean)script_929(arg0))) { + return 0; + } + if (((boolean)script_930(arg0))) { + return 0; + } + if (((boolean)script_933(arg0))) { + return 0; + } + if (script_1432() < getItemHashmapData(arg0, 761)) { + return 0; + } + return 1; +} diff --git a/dumps/scripts/926.cs2 b/dumps/scripts/926.cs2 new file mode 100644 index 0000000..aa72a09 --- /dev/null +++ b/dumps/scripts/926.cs2 @@ -0,0 +1,12 @@ +int script_926(int arg0) { + if (((boolean)script_931(arg0))) { + return 0; + } + if (((boolean)script_932(arg0))) { + return 0; + } + if (((boolean)script_935(arg0))) { + return 0; + } + return 1; +} diff --git a/dumps/scripts/927.cs2 b/dumps/scripts/927.cs2 new file mode 100644 index 0000000..5761e58 --- /dev/null +++ b/dumps/scripts/927.cs2 @@ -0,0 +1,12 @@ +int script_927(int arg0) { + if (getItemHashmapData(arg0, 749) != -1) { + return 1; + } + if (getItemHashmapData(arg0, 743) > -1) { + return 1; + } + if (((boolean)getItemHashmapData(arg0, 741))) { + return 1; + } + return 0; +} diff --git a/dumps/scripts/928.cs2 b/dumps/scripts/928.cs2 new file mode 100644 index 0000000..bee497c --- /dev/null +++ b/dumps/scripts/928.cs2 @@ -0,0 +1,12 @@ +int script_928(int arg0) { + if (getItemHashmapData(arg0, 770) != -1) { + return 1; + } + if (getItemHashmapData(arg0, 764) > -1) { + return 1; + } + if (getItemHashmapData(arg0, 762) > 0) { + return 1; + } + return 0; +} diff --git a/dumps/scripts/929.cs2 b/dumps/scripts/929.cs2 new file mode 100644 index 0000000..68e72bf --- /dev/null +++ b/dumps/scripts/929.cs2 @@ -0,0 +1,109 @@ +int script_929(int arg0) { + int ivar1; + int ivar2; + flow_0: + ivar1 = getItemHashmapData(arg0, 823); + ivar2 = getItemHashmapData(arg0, 749); + if (ivar2 == -1) { + return 1; + } + IF (isBitFlagged(ivar1, 0)) + GOTO flow_3 + GOTO flow_4 + flow_3: + IF (getSkillActualLvl(ivar2) < getItemHashmapData(arg0, 750)) + GOTO flow_6 + flow_4: + IF (isBitFlagged(ivar1, 0) && (getSkillCurrentLvl(ivar2) < getItemHashmapData(arg0, 750))) + GOTO flow_6 + GOTO flow_7 + flow_6: + return 0; + flow_7: + ivar2 = getItemHashmapData(arg0, 751); + if (ivar2 == -1) { + return 1; + } + IF (isBitFlagged(ivar1, 1)) + GOTO flow_10 + GOTO flow_11 + flow_10: + IF (getSkillActualLvl(ivar2) < getItemHashmapData(arg0, 752)) + GOTO flow_13 + flow_11: + IF (isBitFlagged(ivar1, 1) && (getSkillCurrentLvl(ivar2) < getItemHashmapData(arg0, 752))) + GOTO flow_13 + GOTO flow_14 + flow_13: + return 0; + flow_14: + ivar2 = getItemHashmapData(arg0, 753); + if (ivar2 == -1) { + return 1; + } + IF (isBitFlagged(ivar1, 2)) + GOTO flow_17 + GOTO flow_18 + flow_17: + IF (getSkillActualLvl(ivar2) < getItemHashmapData(arg0, 754)) + GOTO flow_20 + flow_18: + IF (isBitFlagged(ivar1, 2) && (getSkillCurrentLvl(ivar2) < getItemHashmapData(arg0, 754))) + GOTO flow_20 + GOTO flow_21 + flow_20: + return 0; + flow_21: + ivar2 = getItemHashmapData(arg0, 755); + if (ivar2 == -1) { + return 1; + } + IF (isBitFlagged(ivar1, 3)) + GOTO flow_24 + GOTO flow_25 + flow_24: + IF (getSkillActualLvl(ivar2) < getItemHashmapData(arg0, 756)) + GOTO flow_27 + flow_25: + IF (isBitFlagged(ivar1, 3) && (getSkillCurrentLvl(ivar2) < getItemHashmapData(arg0, 756))) + GOTO flow_27 + GOTO flow_28 + flow_27: + return 0; + flow_28: + ivar2 = getItemHashmapData(arg0, 757); + if (ivar2 == -1) { + return 1; + } + IF (isBitFlagged(ivar1, 4)) + GOTO flow_31 + GOTO flow_32 + flow_31: + IF (getSkillActualLvl(ivar2) < getItemHashmapData(arg0, 758)) + GOTO flow_34 + flow_32: + IF (isBitFlagged(ivar1, 4) && (getSkillCurrentLvl(ivar2) < getItemHashmapData(arg0, 758))) + GOTO flow_34 + GOTO flow_35 + flow_34: + return 0; + flow_35: + ivar2 = getItemHashmapData(arg0, 759); + if (ivar2 == -1) { + return 1; + } + IF (isBitFlagged(ivar1, 5)) + GOTO flow_38 + GOTO flow_39 + flow_38: + IF (getSkillActualLvl(ivar2) < getItemHashmapData(arg0, 760)) + GOTO flow_41 + flow_39: + IF (isBitFlagged(ivar1, 5) && (getSkillCurrentLvl(ivar2) < getItemHashmapData(arg0, 760))) + GOTO flow_41 + GOTO flow_42 + flow_41: + return 0; + flow_42: + return 1; +} diff --git a/dumps/scripts/93.cs2 b/dumps/scripts/93.cs2 new file mode 100644 index 0000000..8891b35 --- /dev/null +++ b/dumps/scripts/93.cs2 @@ -0,0 +1,4 @@ +void script_93(int arg0) { + script_680(arg0); + return; +} diff --git a/dumps/scripts/930.cs2 b/dumps/scripts/930.cs2 new file mode 100644 index 0000000..4af3edb --- /dev/null +++ b/dumps/scripts/930.cs2 @@ -0,0 +1,46 @@ +int script_930(int arg0) { + int ivar1; + ivar1 = getItemHashmapData(arg0, 743); + if (ivar1 == -1) { + return 1; + } + if (((boolean)script_2156(ivar1))) { + return 0; + } + ivar1 = getItemHashmapData(arg0, 744); + if (ivar1 == -1) { + return 1; + } + if (((boolean)script_2156(ivar1))) { + return 0; + } + ivar1 = getItemHashmapData(arg0, 745); + if (ivar1 == -1) { + return 1; + } + if (((boolean)script_2156(ivar1))) { + return 0; + } + ivar1 = getItemHashmapData(arg0, 746); + if (ivar1 == -1) { + return 1; + } + if (((boolean)script_2156(ivar1))) { + return 0; + } + ivar1 = getItemHashmapData(arg0, 747); + if (ivar1 == -1) { + return 1; + } + if (((boolean)script_2156(ivar1))) { + return 0; + } + ivar1 = getItemHashmapData(arg0, 748); + if (ivar1 == -1) { + return 1; + } + if (((boolean)script_2156(ivar1))) { + return 0; + } + return 1; +} diff --git a/dumps/scripts/931.cs2 b/dumps/scripts/931.cs2 new file mode 100644 index 0000000..7b7016e --- /dev/null +++ b/dumps/scripts/931.cs2 @@ -0,0 +1,46 @@ +int script_931(int arg0) { + int ivar1; + ivar1 = getItemHashmapData(arg0, 770); + if (ivar1 == -1) { + return 1; + } + if (getSkillActualLvl(ivar1) < getItemHashmapData(arg0, 771)) { + return 0; + } + ivar1 = getItemHashmapData(arg0, 772); + if (ivar1 == -1) { + return 1; + } + if (getSkillActualLvl(ivar1) < getItemHashmapData(arg0, 773)) { + return 0; + } + ivar1 = getItemHashmapData(arg0, 774); + if (ivar1 == -1) { + return 1; + } + if (getSkillActualLvl(ivar1) < getItemHashmapData(arg0, 775)) { + return 0; + } + ivar1 = getItemHashmapData(arg0, 776); + if (ivar1 == -1) { + return 1; + } + if (getSkillActualLvl(ivar1) < getItemHashmapData(arg0, 777)) { + return 0; + } + ivar1 = getItemHashmapData(arg0, 778); + if (ivar1 == -1) { + return 1; + } + if (getSkillActualLvl(ivar1) < getItemHashmapData(arg0, 779)) { + return 0; + } + ivar1 = getItemHashmapData(arg0, 780); + if (ivar1 == -1) { + return 1; + } + if (getSkillActualLvl(ivar1) < getItemHashmapData(arg0, 781)) { + return 0; + } + return 1; +} diff --git a/dumps/scripts/932.cs2 b/dumps/scripts/932.cs2 new file mode 100644 index 0000000..bf5a9c0 --- /dev/null +++ b/dumps/scripts/932.cs2 @@ -0,0 +1,46 @@ +int script_932(int arg0) { + int ivar1; + ivar1 = getItemHashmapData(arg0, 764); + if (ivar1 == -1) { + return 1; + } + if (((boolean)script_2156(ivar1))) { + return 0; + } + ivar1 = getItemHashmapData(arg0, 765); + if (ivar1 == -1) { + return 1; + } + if (((boolean)script_2156(ivar1))) { + return 0; + } + ivar1 = getItemHashmapData(arg0, 766); + if (ivar1 == -1) { + return 1; + } + if (((boolean)script_2156(ivar1))) { + return 0; + } + ivar1 = getItemHashmapData(arg0, 767); + if (ivar1 == -1) { + return 1; + } + if (((boolean)script_2156(ivar1))) { + return 0; + } + ivar1 = getItemHashmapData(arg0, 768); + if (ivar1 == -1) { + return 1; + } + if (((boolean)script_2156(ivar1))) { + return 0; + } + ivar1 = getItemHashmapData(arg0, 769); + if (ivar1 == -1) { + return 1; + } + if (((boolean)script_2156(ivar1))) { + return 0; + } + return 1; +} diff --git a/dumps/scripts/933.cs2 b/dumps/scripts/933.cs2 new file mode 100644 index 0000000..66b5fce --- /dev/null +++ b/dumps/scripts/933.cs2 @@ -0,0 +1,42 @@ +int script_933(int arg0) { + switch (getItemHashmapData(arg0, 741)) { + case 1: + if (bitconfig_1852 < getItemHashmapData(arg0, 742)) { + return 0; + } + break; + case 2: + if (bitconfig_3763 < 2) { + return 0; + } + break; + case 3: + if (bitconfig_4310 < 10) { + return 0; + } + break; + case 4: + if (bitconfig_1990 < 280) { + return 0; + } + break; + case 5: + if (bitconfig_1850 < 4) { + return 0; + } + break; + case 6: + if (bitconfig_3550 < 8) { + return 0; + } + break; + case 7: + if (bitconfig_998 < 7) { + return 0; + } + break; + default: + return 1; + } + return -1; +} diff --git a/dumps/scripts/934.cs2 b/dumps/scripts/934.cs2 new file mode 100644 index 0000000..1436080 --- /dev/null +++ b/dumps/scripts/934.cs2 @@ -0,0 +1,28 @@ +string script_934(int arg0) { + int ivar1; + string svar0; + svar0 = ""; + ivar1 = getItemHashmapData(arg0, 742); + switch (getItemHashmapData(arg0, 741)) { + case 1: + if (((boolean)ivar1)) { + svar0 = "Rescued 1 dignitary in Recipe for Disaster"; + } else { + svar0 = "Rescued " + intToStr(ivar1) + " dignitaries in Recipe for Disaster"; + } + return script_913(bitconfig_1852, getItemHashmapData(arg0, 742), svar0); + case 2: + return script_913(bitconfig_3763, 2, "Barbarian spearmaking"); + case 3: + return script_913(bitconfig_4310, 10, "Complete: Chaos Tunnels"); + case 4: + return script_913(bitconfig_1990, 280, "Part of quest: In Aid of the Myreque"); + case 5: + return script_913(bitconfig_1850, 4, "Part of quest: Recipe for Disaster"); + case 6: + return script_913(bitconfig_3550, 8, "Part of quest: Another Slice of H.A.M."); + case 7: + return script_913(bitconfig_998, 7, "You need to complete the first puzzle in the Elemental Workshop IV Quest."); + } + return ""; +} diff --git a/dumps/scripts/935.cs2 b/dumps/scripts/935.cs2 new file mode 100644 index 0000000..5c9c8ac --- /dev/null +++ b/dumps/scripts/935.cs2 @@ -0,0 +1,17 @@ +int script_935(int arg0) { + switch (getItemHashmapData(arg0, 762)) { + case 1: + if (standart_config_322 < 10) { + return 0; + } + break; + case 2: + if (bitconfig_4310 < 10) { + return 0; + } + break; + default: + return 1; + } + return -1; +} diff --git a/dumps/scripts/936.cs2 b/dumps/scripts/936.cs2 new file mode 100644 index 0000000..a252367 --- /dev/null +++ b/dumps/scripts/936.cs2 @@ -0,0 +1,13 @@ +string script_936(int arg0) { + int ivar1; + string svar0; + svar0 = ""; + ivar1 = getItemHashmapData(arg0, 763); + switch (getItemHashmapData(arg0, 762)) { + case 1: + return script_913(standart_config_322, 10, "Part of quest: Tai Bwo Wannai Trio"); + case 2: + return script_913(bitconfig_4310, 10, "Complete: Chaos Tunnels"); + } + return ""; +} diff --git a/dumps/scripts/937.cs2 b/dumps/scripts/937.cs2 new file mode 100644 index 0000000..f3a7a0b --- /dev/null +++ b/dumps/scripts/937.cs2 @@ -0,0 +1,36 @@ +void script_937() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + deleteAllExtraChilds(new WidgetPointer(335,32)); + ivar0 = 0; + ivar1 = 0; + ivar2 = 4; + ivar3 = 7; + if (getWidgetScrollMaxH(new WidgetPointer(335,32)) > 0) { + ivar0 = divide(subtract(getWidgetScrollMaxH(new WidgetPointer(335,32)), multiply(36, ivar2)), subtract(ivar2, 1)); + } else { + ivar0 = divide(subtract(getWidgetActualWidth(new WidgetPointer(335,32)), multiply(36, ivar2)), subtract(ivar2, 1)); + } + if (getWidgetScrollMaxV(new WidgetPointer(335,32)) > 0) { + ivar1 = divide(subtract(getWidgetScrollMaxV(new WidgetPointer(335,32)), multiply(32, ivar3)), subtract(ivar3, 1)); + } else { + ivar1 = divide(subtract(getWidgetActualHeight(new WidgetPointer(335,32)), multiply(32, ivar3)), subtract(ivar3, 1)); + } + ivar4 = 0; + ivar5 = -1; + while (ivar4 < getItemContainerLength(90)) { + createExtraChild(new WidgetPointer(335,32), 3, ivar4); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(multiply(add(36, ivar0), mod(ivar4, ivar2)), multiply(divide(ivar4, ivar2), add(32, ivar1)), 0, 0); + setWidgetFilled(1); + setWidgetRGB(new Color(255, 0, 0)); + cs2method2103(255); + ivar4 = add(ivar4, 1); + } + setScriptCallOnItemContainerUpdate(938, 90, 1, "Y", new WidgetPointer(335,32)); + return; +} diff --git a/dumps/scripts/938.cs2 b/dumps/scripts/938.cs2 new file mode 100644 index 0000000..04994f1 --- /dev/null +++ b/dumps/scripts/938.cs2 @@ -0,0 +1,4 @@ +void script_938() { + script_939(); + return; +} diff --git a/dumps/scripts/939.cs2 b/dumps/scripts/939.cs2 new file mode 100644 index 0000000..c24046d --- /dev/null +++ b/dumps/scripts/939.cs2 @@ -0,0 +1,14 @@ +void script_939() { + int ivar0; + int ivar1; + ivar0 = 0; + ivar1 = -1; + while (ivar0 < getItemContainerLength(90)) { + if (setWidgetRegister(new WidgetPointer(335,32), ivar0)) { + ivar1 = getItemIdInSlotSplit(90, ivar0); + script_812(ivar1); + } + ivar0 = add(ivar0, 1); + } + return; +} diff --git a/dumps/scripts/94.cs2 b/dumps/scripts/94.cs2 new file mode 100644 index 0000000..6be2def --- /dev/null +++ b/dumps/scripts/94.cs2 @@ -0,0 +1,4 @@ +void script_94(int arg0) { + script_1360(arg0); + return; +} diff --git a/dumps/scripts/940.cs2 b/dumps/scripts/940.cs2 new file mode 100644 index 0000000..4055bc9 --- /dev/null +++ b/dumps/scripts/940.cs2 @@ -0,0 +1,12 @@ +string script_940(int arg0) { + if (arg0 < 0) { + return ""; + } + if (arg0 < 10000) { + return intToStr(arg0); + } + if (arg0 < 10000000) { + return concat(intToStr(divide(arg0, 1000)), "K"); + } + return concat(intToStr(divide(arg0, 1000000)), "M"); +} diff --git a/dumps/scripts/941.cs2 b/dumps/scripts/941.cs2 new file mode 100644 index 0000000..1358dea --- /dev/null +++ b/dumps/scripts/941.cs2 @@ -0,0 +1,86 @@ +void script_941(int arg0) { + globalint_988 = 0; + globalint_989 = 0; + globalint_990 = 0; + globalint_991 = 0; + switch (arg0) { + case 12582919: + script_41(12583008); + if (((boolean)bitconfig_6459)) { + setWidgetSprite(1701, new WidgetPointer(arg0)); + } + break; + case 12582921: + script_41(12583008); + if (((boolean)bitconfig_6462)) { + setWidgetSprite(1701, new WidgetPointer(arg0)); + } + break; + case 12582923: + script_41(12583008); + if (((boolean)bitconfig_6461)) { + setWidgetSprite(1701, new WidgetPointer(arg0)); + } + break; + case 12582925: + script_41(12583008); + if (((boolean)bitconfig_6460)) { + setWidgetSprite(1701, new WidgetPointer(arg0)); + } + break; + case 28180485: + script_41(28180545); + if (((boolean)bitconfig_6463)) { + setWidgetSprite(1701, new WidgetPointer(arg0)); + } + break; + case 28180489: + script_41(28180545); + if (((boolean)bitconfig_6464)) { + setWidgetSprite(1701, new WidgetPointer(arg0)); + } + break; + case 28180487: + script_41(28180545); + if (((boolean)bitconfig_6465)) { + setWidgetSprite(1701, new WidgetPointer(arg0)); + } + break; + case 12648453: + script_41(12648501); + if (((boolean)bitconfig_6466)) { + setWidgetSprite(1701, new WidgetPointer(arg0)); + } + break; + case 12648455: + script_41(12648501); + if (((boolean)bitconfig_6467)) { + setWidgetSprite(1701, new WidgetPointer(arg0)); + } + break; + case 62259207: + script_41(62259272); + if (((boolean)bitconfig_7348)) { + setWidgetSprite(1701, new WidgetPointer(arg0)); + } + break; + case 62259209: + script_41(62259272); + if (((boolean)bitconfig_7351)) { + setWidgetSprite(1701, new WidgetPointer(arg0)); + } + break; + case 62259211: + script_41(62259272); + if (((boolean)bitconfig_7350)) { + setWidgetSprite(1701, new WidgetPointer(arg0)); + } + break; + case 62259213: + script_41(62259272); + if (((boolean)bitconfig_7349)) { + setWidgetSprite(1701, new WidgetPointer(arg0)); + } + } + return; +} diff --git a/dumps/scripts/942.cs2 b/dumps/scripts/942.cs2 new file mode 100644 index 0000000..eedb60b --- /dev/null +++ b/dumps/scripts/942.cs2 @@ -0,0 +1,40 @@ +cs2func_script_942_struct(1,1,0) script_942(int arg0) { + if (standart_config_1469 == cs2method_3408(105, 99, 2536, arg0)) { + return newstruct cs2func_script_942_struct(0, "null"); + } + switch (arg0) { + case 0: + return newstruct cs2func_script_942_struct(1, cs2method_3408(105, 115, 2535, 0)); + case 1: + return newstruct cs2func_script_942_struct(1, cs2method_3408(105, 115, 2535, 1)); + case 2: + return newstruct cs2func_script_942_struct(1, cs2method_3408(105, 115, 2535, 2)); + case 3: + return newstruct cs2func_script_942_struct(1, cs2method_3408(105, 115, 2535, 3)); + case 4: + return newstruct cs2func_script_942_struct(1, cs2method_3408(105, 115, 2535, 4)); + case 5: + if (bitconfig_720 == 20) { + return newstruct cs2func_script_942_struct(1, cs2method_3408(105, 115, 2535, 5)); + } + break; + case 6: + if (bitconfig_722 == 20) { + return newstruct cs2func_script_942_struct(1, cs2method_3408(105, 115, 2535, 6)); + } + break; + case 7: + if (bitconfig_724 == 20) { + return newstruct cs2func_script_942_struct(1, cs2method_3408(105, 115, 2535, 7)); + } + break; + case 8: + if (bitconfig_3959 >= 3) { + return newstruct cs2func_script_942_struct(1, cs2method_3408(105, 115, 2535, 8)); + } + break; + default: + return newstruct cs2func_script_942_struct(-1, "null"); + } + return newstruct cs2func_script_942_struct(0, "null"); +} diff --git a/dumps/scripts/943.cs2 b/dumps/scripts/943.cs2 new file mode 100644 index 0000000..be8a450 --- /dev/null +++ b/dumps/scripts/943.cs2 @@ -0,0 +1,24 @@ +void script_943(int arg0,int arg1,int arg2,int arg3) { + int ivar4; + ivar4 = getOtherCommonData(cs2method_3408(105, 74, 169, arg0), 782); + if (isMember()) { + messageType0("More advanced grouping options are available on a members' world."); + } else if (standart_config_281 < 1000) { + messageType0("More advanced grouping options will be available when you've finished the Tutorial."); + } else { + if (globalint_693 == arg1) { + globalint_694 = mod(add(1, globalint_694), 2); + } else { + globalint_693 = arg1; + globalint_694 = 0; + } + script_2162(arg0, globalint_693, globalint_694, globalint_692, globalint_1103); + script_1349(12451856, 12451854, 12451855, -1, 1); + if (setWidgetRegister(new WidgetPointer(190,16), 2)) { + setWidgetText(cs2method_3408(105, 115, ivar4, arg1)); + setWidgetRGB(new Color(arg3)); + setScriptCallOnMouseExit(1354, new WidgetPointer(190,16), 2, arg3, "Iii"); + } + } + return; +} diff --git a/dumps/scripts/944.cs2 b/dumps/scripts/944.cs2 new file mode 100644 index 0000000..ea6f8a3 --- /dev/null +++ b/dumps/scripts/944.cs2 @@ -0,0 +1,4 @@ +void script_944(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12,int arg13,int arg14,int arg15,int arg16,int arg17,int arg18,int arg19) { + script_945(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19); + return; +} diff --git a/dumps/scripts/945.cs2 b/dumps/scripts/945.cs2 new file mode 100644 index 0000000..d1200c3 --- /dev/null +++ b/dumps/scripts/945.cs2 @@ -0,0 +1,43 @@ +void script_945(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12,int arg13,int arg14,int arg15,int arg16,int arg17,int arg18,int arg19,int arg20) { + int ivar21; + int ivar22; + int ivar23; + ivar21 = getOtherCommonData(cs2method_3408(105, 74, 169, arg0), 782); + deleteAllExtraChilds(new WidgetPointer(arg3)); + createExtraChild(new WidgetPointer(arg3), 5, 0); + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg3)), getWidgetActualHeight(new WidgetPointer(arg3)), 0, 0); + setWidgetSprite(arg7); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg3), 3, getExtraChildGap(new WidgetPointer(arg3))); + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg3)), getWidgetActualHeight(new WidgetPointer(arg3)), 0, 0); + setWidgetRGB(new Color(0, 0, 0)); + ivar22 = 1; + createExtraChild(new WidgetPointer(arg3), 5, ivar22); + setWidgetPosition(subtract(getWidgetActualWidth(new WidgetPointer(arg3)), 16), 0, 0, 0); + setWidgetSize(16, getWidgetActualHeight(new WidgetPointer(arg3)), 0, 0); + setWidgetSprite(arg8); + cs2method1107(0); + setScriptCallOnMouseEntered(1351, new WidgetPointer(arg3), ivar22, arg9, "Iid"); + setScriptCallOnMouseExit(1352, new WidgetPointer(arg3), ivar22, arg8, "Iid"); + ivar23 = getExtraChildGap(new WidgetPointer(arg3)); + setScriptCallOnMousePressed(946, arg0, arg2, new WidgetPointer(arg4), arg10, new WidgetPointer(arg5), new WidgetPointer(arg6), new WidgetPointer(arg3), arg11, arg12, arg13, arg14, ivar23, ivar22, arg15, arg16, arg17, arg18, arg19, arg20, "iiIdIIIiiidiidddddd"); + createExtraChild(new WidgetPointer(arg3), 4, ivar23); + setWidgetText(cs2method_3408(105, 115, ivar21, arg1)); + setWidgetPosition(5, 0, 0, 0); + setWidgetSize(subtract(getWidgetActualWidth(new WidgetPointer(arg3)), 22), getWidgetActualHeight(new WidgetPointer(arg3)), 0, 0); + setWidgetUnknownBoolean(false); + setWidgetFont(arg14); + setWidgetTextAlignment(0, 1, 0); + if (arg1 >= arg2) { + setWidgetRGB(new Color(arg12)); + setScriptCallOnMouseExit(1354, new WidgetPointer(arg3), ivar23, arg12, "Iii"); + } else { + setWidgetRGB(new Color(arg11)); + setScriptCallOnMouseExit(1354, new WidgetPointer(arg3), ivar23, arg11, "Iii"); + } + setScriptCallOnMouseEntered(1353, new WidgetPointer(arg3), ivar23, arg13, "Iii"); + setScriptCallOnMousePressed(946, arg0, arg2, new WidgetPointer(arg4), arg10, new WidgetPointer(arg5), new WidgetPointer(arg6), new WidgetPointer(arg3), arg11, arg12, arg13, arg14, ivar23, ivar22, arg15, arg16, arg17, arg18, arg19, arg20, "iiIdIIIiiidiidddddd"); + return; +} diff --git a/dumps/scripts/946.cs2 b/dumps/scripts/946.cs2 new file mode 100644 index 0000000..ee2a351 --- /dev/null +++ b/dumps/scripts/946.cs2 @@ -0,0 +1,9 @@ +void script_946(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12,int arg13,int arg14,int arg15,int arg16,int arg17,int arg18) { + if (isWidgetHidden(new WidgetPointer(arg2))) { + cs2method2100(0, 0, new WidgetPointer(arg4)); + script_947(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18); + } else { + script_1349(arg6, arg2, arg4, arg5, arg12); + } + return; +} diff --git a/dumps/scripts/947.cs2 b/dumps/scripts/947.cs2 new file mode 100644 index 0000000..a48b398 --- /dev/null +++ b/dumps/scripts/947.cs2 @@ -0,0 +1,56 @@ +void script_947(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12,int arg13,int arg14,int arg15,int arg16,int arg17,int arg18) { + int ivar19; + int ivar20; + int ivar21; + string svar0; + if (setWidgetRegister(new WidgetPointer(arg6), arg12)) { + setWidgetVFlip(1); + } + createExtraChild(new WidgetPointer(arg2), 5, getExtraChildGap(new WidgetPointer(arg2))); + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg2)), getWidgetActualHeight(new WidgetPointer(arg2)), 0, 0); + setWidgetSprite(arg3); + cs2method1107(1); + createExtraChild(new WidgetPointer(arg2), 3, getExtraChildGap(new WidgetPointer(arg2))); + setWidgetPosition(0, 0, 0, 0); + setWidgetSize(getWidgetActualWidth(new WidgetPointer(arg2)), getWidgetActualHeight(new WidgetPointer(arg2)), 0, 0); + setWidgetRGB(new Color(0, 0, 0)); + setWidgetScrollMax(getWidgetActualWidth(new WidgetPointer(arg4)), multiply(arg1, 15), new WidgetPointer(arg4)); + ivar19 = 0; + ivar20 = -1; + svar0 = ""; + ivar21 = getOtherCommonData(cs2method_3408(105, 74, 169, arg0), 782); + while (ivar19 <= arg1) { + ivar20 = getExtraChildGap(new WidgetPointer(arg4)); + svar0 = cs2method_3408(105, 115, ivar21, ivar19); + createExtraChild(new WidgetPointer(arg4), 4, ivar20); + cs2method1305(svar0); + if ((ivar20 == globalint_693) && ((boolean)globalint_694)) { + svar0 = concat(svar0, " (r)"); + } + setWidgetText(svar0); + setWidgetTextAlignment(0, 1, 0); + setWidgetPosition(5, multiply(ivar19, 15), 0, 0); + setWidgetSize(subtract(getWidgetActualWidth(new WidgetPointer(arg4)), 16), 15, 0, 0); + setWidgetUnknownBoolean(false); + setWidgetFont(arg10); + setWidgetContextMenuOption(1, "Select"); + setScriptCallOnClickContextMenu(943, arg0, -2147483643, -2147483644, arg7, "iiii"); + if (ivar19 >= arg1) { + setWidgetRGB(new Color(arg8)); + setScriptCallOnMouseExit(1354, new WidgetPointer(arg4), ivar20, arg8, "Iii"); + } else { + setWidgetRGB(new Color(arg7)); + setScriptCallOnMouseExit(1354, new WidgetPointer(arg4), ivar20, arg7, "Iii"); + } + setScriptCallOnMouseEntered(1353, new WidgetPointer(arg4), ivar20, arg9, "Iii"); + ivar19 = add(ivar19, 1); + } + if (arg5 != -1) { + script_31(arg5, arg4, arg13, arg14, arg15, arg16, arg17, arg18); + setWidgetIsHidden(false, new WidgetPointer(arg5)); + } + setWidgetIsHidden(false, new WidgetPointer(arg2)); + setWidgetIsHidden(false, new WidgetPointer(arg4)); + return; +} diff --git a/dumps/scripts/948.cs2 b/dumps/scripts/948.cs2 new file mode 100644 index 0000000..20d5a22 --- /dev/null +++ b/dumps/scripts/948.cs2 @@ -0,0 +1,6 @@ +void script_948() { + setScriptCallOnGameloop(-1, "", new WidgetPointer(894,5)); + setWidgetIsHidden(true, new WidgetPointer(894,7)); + setWidgetSprite(-1, new WidgetPointer(894,4)); + return; +} diff --git a/dumps/scripts/949.cs2 b/dumps/scripts/949.cs2 new file mode 100644 index 0000000..6e73b9e --- /dev/null +++ b/dumps/scripts/949.cs2 @@ -0,0 +1,23 @@ +void script_949() { + if (((boolean)globalint_1198)) { + setWidgetIsHidden(false, new WidgetPointer(933,322)); + setWidgetIsHidden(false, new WidgetPointer(933,323)); + } + if (((boolean)globalint_1199)) { + setWidgetIsHidden(false, new WidgetPointer(933,321)); + setWidgetIsHidden(false, new WidgetPointer(933,324)); + } + if (((boolean)globalint_1200)) { + setWidgetIsHidden(false, new WidgetPointer(933,320)); + setWidgetIsHidden(false, new WidgetPointer(933,325)); + } + if (((boolean)globalint_1201)) { + setWidgetIsHidden(false, new WidgetPointer(933,319)); + setWidgetIsHidden(false, new WidgetPointer(933,326)); + } + if (((boolean)globalint_1202)) { + setWidgetIsHidden(false, new WidgetPointer(933,318)); + setWidgetIsHidden(false, new WidgetPointer(933,327)); + } + return; +} diff --git a/dumps/scripts/95.cs2 b/dumps/scripts/95.cs2 new file mode 100644 index 0000000..928cefc --- /dev/null +++ b/dumps/scripts/95.cs2 @@ -0,0 +1,4 @@ +void script_95(int arg0) { + script_1361(arg0); + return; +} diff --git a/dumps/scripts/950.cs2 b/dumps/scripts/950.cs2 new file mode 100644 index 0000000..5c12d01 --- /dev/null +++ b/dumps/scripts/950.cs2 @@ -0,0 +1,13 @@ +void script_950() { + switch (globalint_1397) { + case 0: + setWidgetRGB(new Color(255, 180, 0), new WidgetPointer(933,323)); + break; + case 1: + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(933,323)); + break; + case 2: + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(933,323)); + } + return; +} diff --git a/dumps/scripts/951.cs2 b/dumps/scripts/951.cs2 new file mode 100644 index 0000000..5653681 --- /dev/null +++ b/dumps/scripts/951.cs2 @@ -0,0 +1,13 @@ +void script_951() { + switch (globalint_1398) { + case 0: + setWidgetRGB(new Color(255, 180, 0), new WidgetPointer(933,324)); + break; + case 1: + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(933,324)); + break; + case 2: + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(933,324)); + } + return; +} diff --git a/dumps/scripts/952.cs2 b/dumps/scripts/952.cs2 new file mode 100644 index 0000000..ada26f3 --- /dev/null +++ b/dumps/scripts/952.cs2 @@ -0,0 +1,13 @@ +void script_952() { + switch (globalint_1399) { + case 0: + setWidgetRGB(new Color(255, 180, 0), new WidgetPointer(933,325)); + break; + case 1: + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(933,325)); + break; + case 2: + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(933,325)); + } + return; +} diff --git a/dumps/scripts/953.cs2 b/dumps/scripts/953.cs2 new file mode 100644 index 0000000..ffe27f2 --- /dev/null +++ b/dumps/scripts/953.cs2 @@ -0,0 +1,13 @@ +void script_953() { + switch (globalint_1400) { + case 0: + setWidgetRGB(new Color(255, 180, 0), new WidgetPointer(933,326)); + break; + case 1: + setWidgetRGB(new Color(0, 255, 0), new WidgetPointer(933,326)); + break; + case 2: + setWidgetRGB(new Color(255, 0, 0), new WidgetPointer(933,326)); + } + return; +} diff --git a/dumps/scripts/954.cs2 b/dumps/scripts/954.cs2 new file mode 100644 index 0000000..acfa699 --- /dev/null +++ b/dumps/scripts/954.cs2 @@ -0,0 +1,4 @@ +void script_954() { + setWidgetSize(multiplyDivide(subtract(1000, bitconfig_4564), 1000, 182), 6, 0, 0, new WidgetPointer(730,29)); + return; +} diff --git a/dumps/scripts/955.cs2 b/dumps/scripts/955.cs2 new file mode 100644 index 0000000..e343c13 --- /dev/null +++ b/dumps/scripts/955.cs2 @@ -0,0 +1,6 @@ +void script_955() { + if (((((bitconfig_4540 == 3) && ((boolean)getItemAmtInContainer(94, 12845))) && (((boolean)getItemAmtInContainer(93, 12845)) && ((boolean)getItemAmtInContainer(94, 12846)))) && ((((boolean)getItemAmtInContainer(93, 12846)) && ((boolean)getItemAmtInContainer(94, 12847))) && (((boolean)getItemAmtInContainer(93, 12847)) && ((boolean)getItemAmtInContainer(94, 12848))))) && ((((boolean)getItemAmtInContainer(93, 12848)) && ((boolean)getItemAmtInContainer(94, 12849))) && ((boolean)getItemAmtInContainer(93, 12849)))) { + setWidgetIsHidden(false, new WidgetPointer(730,24)); + } + return; +} diff --git a/dumps/scripts/956.cs2 b/dumps/scripts/956.cs2 new file mode 100644 index 0000000..165703f --- /dev/null +++ b/dumps/scripts/956.cs2 @@ -0,0 +1,38 @@ +void script_956() { + cs2method2305(new WidgetPointer(732,2), "" + "Druidic Mage Top" + ""); + cs2method2305(new WidgetPointer(732,7), "" + "Druidic Mage Bottom" + ""); + cs2method2305(new WidgetPointer(732,12), "" + "Druidic Mage Hood" + ""); + cs2method2305(new WidgetPointer(732,19), "" + "Combat Robe Top" + ""); + cs2method2305(new WidgetPointer(732,24), "" + "Combat Robe Bottom" + ""); + cs2method2305(new WidgetPointer(732,29), "" + "Combat Hood" + ""); + cs2method2305(new WidgetPointer(732,36), "" + "Battle Robe Top" + ""); + cs2method2305(new WidgetPointer(732,41), "" + "Battle Robe Bottom" + ""); + cs2method2305(new WidgetPointer(732,46), "" + "Battle Hood" + ""); + cs2method2305(new WidgetPointer(732,53), "" + "Green D'Hide Coif" + ""); + cs2method2305(new WidgetPointer(732,58), "" + "Blue D'Hide Coif" + ""); + cs2method2305(new WidgetPointer(732,63), "" + "Red D'Hide Coif" + ""); + cs2method2305(new WidgetPointer(732,68), "" + "Black D'Hide Coif" + ""); + cs2method2305(new WidgetPointer(732,75), "" + "Bronze Gauntlets" + ""); + cs2method2305(new WidgetPointer(732,80), "" + "Iron Gauntlets" + ""); + cs2method2305(new WidgetPointer(732,85), "" + "Steel Gauntlets" + ""); + cs2method2305(new WidgetPointer(732,90), "" + "Black Gauntlets" + ""); + cs2method2305(new WidgetPointer(732,95), "" + "Mithril Gauntlets" + ""); + cs2method2305(new WidgetPointer(732,100), "" + "Adamant Gauntlets" + ""); + cs2method2305(new WidgetPointer(732,105), "" + "Rune Gauntlets" + ""); + cs2method2305(new WidgetPointer(732,110), "" + "Dragon Gauntlets" + ""); + cs2method2305(new WidgetPointer(732,117), "" + "Adamant Spikeshield" + ""); + cs2method2305(new WidgetPointer(732,122), "" + "Adamant Berserker Shield" + ""); + cs2method2305(new WidgetPointer(732,127), "" + "Rune Spikeshield" + ""); + cs2method2305(new WidgetPointer(732,132), "" + "Rune Berserker Shield" + ""); + cs2method2305(new WidgetPointer(732,139), "" + "Irit Gloves" + ""); + cs2method2305(new WidgetPointer(732,144), "" + "Avantoe Gloves" + ""); + cs2method2305(new WidgetPointer(732,149), "" + "Kwuarm Gloves" + ""); + cs2method2305(new WidgetPointer(732,154), "" + "Cadantine Gloves" + ""); + cs2method2305(new WidgetPointer(732,161), "" + "Swordfish Gloves" + ""); + cs2method2305(new WidgetPointer(732,166), "" + "Shark Gloves" + ""); + cs2method2305(new WidgetPointer(732,171), "" + "Dragon Slayer Gloves" + ""); + cs2method2305(new WidgetPointer(732,176), "" + "Air Runecrafting Gloves" + ""); + cs2method2305(new WidgetPointer(732,181), "" + "Water Runecrafting Gloves" + ""); + cs2method2305(new WidgetPointer(732,186), "" + "Earth Runecrafting Gloves" + ""); + return; +} diff --git a/dumps/scripts/957.cs2 b/dumps/scripts/957.cs2 new file mode 100644 index 0000000..6f0eccf --- /dev/null +++ b/dumps/scripts/957.cs2 @@ -0,0 +1,10 @@ +void script_957(int arg0,int arg1,int arg2) { + if (((boolean)bitconfig_4618)) { + script_959(arg0, arg1, 0); + setWidgetSprite(1156, new WidgetPointer(arg2)); + } else { + script_959(arg0, arg1, 1); + setWidgetSprite(1157, new WidgetPointer(arg2)); + } + return; +} diff --git a/dumps/scripts/958.cs2 b/dumps/scripts/958.cs2 new file mode 100644 index 0000000..5bdd901 --- /dev/null +++ b/dumps/scripts/958.cs2 @@ -0,0 +1,10 @@ +void script_958(int arg0,int arg1,int arg2) { + if (((boolean)bitconfig_4618)) { + script_959(arg0, arg1, 1); + setWidgetSprite(1157, new WidgetPointer(arg2)); + } else { + script_959(arg0, arg1, 0); + setWidgetSprite(1156, new WidgetPointer(arg2)); + } + return; +} diff --git a/dumps/scripts/959.cs2 b/dumps/scripts/959.cs2 new file mode 100644 index 0000000..7f6423b --- /dev/null +++ b/dumps/scripts/959.cs2 @@ -0,0 +1,112 @@ +void script_959(int arg0,int arg1,int arg2) { + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + string svar0; + deleteAllExtraChilds(new WidgetPointer(arg0)); + globalarray_0 = new WidgetPointer[64]; + ivar3 = 0; + ivar4 = -1; + ivar5 = 0; + while (ivar5 < 64) { + ivar4 = ((int)cs2method_3408(105, 73, 1467, ivar5)); + if (strLength(getWidgetText(new WidgetPointer(ivar4))) > 0) { + setWidgetIsHidden(false, new WidgetPointer(ivar4)); + globalarray_0[ivar3] = ivar4; + ivar3 = add(ivar3, 1); + } else { + setWidgetIsHidden(true, new WidgetPointer(ivar4)); + } + ivar5 = add(ivar5, 1); + } + if (ivar3 > 1) { + if (((boolean)arg2)) { + script_0(0, 0, subtract(ivar3, 1)); + } else { + script_62(0, 0, subtract(ivar3, 1), 1466); + } + } + ivar6 = 0; + ivar7 = 0; + ivar8 = getWidgetActualWidth(new WidgetPointer(ivar4)); + ivar5 = 0; + while (ivar5 < ivar3) { + ivar4 = globalarray_0[ivar5]; + ivar7 = getLineCount(ivar8, 495, getWidgetText(new WidgetPointer(ivar4))); + ivar7 = add(multiply(12, ivar7), 10); + setWidgetFont(495, new WidgetPointer(ivar4)); + setWidgetSize(ivar8, ivar7, 0, 0, new WidgetPointer(ivar4)); + setWidgetPosition(0, ivar6, 0, 0, new WidgetPointer(ivar4)); + createExtraChild(new WidgetPointer(arg0), 4, ivar5); + setWidgetSize(ivar8, ivar7, 0, 0); + setWidgetPosition(0, ivar6, 0, 0); + setWidgetFont(495); + setWidgetRGB(new Color(223, 15, 15)); + setWidgetUnknownBoolean(true); + setWidgetTextAlignment(0, 0, 0); + setWidgetText(cs2method_3408(73, 115, 1466, ivar4)); + ivar6 = add(ivar6, ivar7); + ivar5 = add(ivar5, 1); + } + ivar4 = ((int)cs2method_3408(105, 73, 1467, 64)); + svar0 = getWidgetText(new WidgetPointer(ivar4)); + if (strLength(svar0) > 0) { + if (ivar6 > 0) { + ivar6 = add(ivar6, 5); + } + ivar7 = getLineCount(ivar8, 495, svar0); + ivar7 = add(multiply(12, ivar7), 5); + setWidgetSize(ivar8, ivar7, 0, 0, new WidgetPointer(ivar4)); + setWidgetPosition(0, ivar6, 0, 0, new WidgetPointer(ivar4)); + setWidgetIsHidden(false, new WidgetPointer(ivar4)); + ivar6 = add(ivar6, ivar7); + } else { + setWidgetIsHidden(true, new WidgetPointer(ivar4)); + } + ivar4 = ((int)cs2method_3408(105, 73, 1467, 65)); + svar0 = getWidgetText(new WidgetPointer(ivar4)); + if (strLength(svar0) > 0) { + if (ivar6 > 0) { + ivar6 = add(ivar6, 5); + } + ivar7 = getLineCount(ivar8, 495, svar0); + ivar7 = add(multiply(12, ivar7), 5); + setWidgetSize(ivar8, ivar7, 0, 0, new WidgetPointer(ivar4)); + setWidgetPosition(0, ivar6, 0, 0, new WidgetPointer(ivar4)); + setWidgetIsHidden(false, new WidgetPointer(ivar4)); + ivar6 = add(ivar6, ivar7); + } else { + setWidgetIsHidden(true, new WidgetPointer(ivar4)); + } + ivar4 = ((int)cs2method_3408(105, 73, 1467, 66)); + svar0 = getWidgetText(new WidgetPointer(ivar4)); + if (strLength(svar0) > 0) { + if (ivar6 > 0) { + ivar6 = add(ivar6, 5); + } + ivar7 = getLineCount(ivar8, 495, svar0); + ivar7 = add(multiply(12, ivar7), 5); + setWidgetSize(ivar8, ivar7, 0, 0, new WidgetPointer(ivar4)); + setWidgetPosition(0, ivar6, 0, 0, new WidgetPointer(ivar4)); + setWidgetIsHidden(false, new WidgetPointer(ivar4)); + ivar6 = add(ivar6, ivar7); + } else { + setWidgetIsHidden(true, new WidgetPointer(ivar4)); + } + setWidgetScrollMax(ivar8, ivar6, new WidgetPointer(arg0)); + if (ivar6 > getWidgetActualHeight(new WidgetPointer(arg0))) { + setWidgetPosition(3, getWidgetActualY(new WidgetPointer(arg0)), 0, 0, new WidgetPointer(arg0)); + script_31(arg1, arg0, 792, 789, 790, 791, 773, 788); + if (setWidgetRegister(new WidgetPointer(arg1), 1)) { + script_157(arg1, arg0, globalint_121, 1); + } + } else { + cs2method2100(0, 0, new WidgetPointer(arg0)); + globalint_121 = 0; + setWidgetPosition(12, getWidgetActualY(new WidgetPointer(arg0)), 0, 0, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/96.cs2 b/dumps/scripts/96.cs2 new file mode 100644 index 0000000..9bab88e --- /dev/null +++ b/dumps/scripts/96.cs2 @@ -0,0 +1,4 @@ +void script_96(int arg0) { + script_1363(arg0); + return; +} diff --git a/dumps/scripts/960.cs2 b/dumps/scripts/960.cs2 new file mode 100644 index 0000000..7ab4bc5 --- /dev/null +++ b/dumps/scripts/960.cs2 @@ -0,0 +1,17 @@ +void script_960() { + script_333(44957699, 0, 4537650, 0, 0); + script_333(44957700, 4537650, 6052707, 0, 0); + setWidgetIsHidden(true, new WidgetPointer(686,9)); + script_680(44957710); + setScriptCallOnMouseEntered(95, new WidgetPointer(-32768,3), "I", new WidgetPointer(686,14)); + setScriptCallOnMouseExit(93, new WidgetPointer(-32768,3), "I", new WidgetPointer(686,14)); + setScriptCallOnClickContextMenu(69, 1, new WidgetPointer(686,9), "1I", new WidgetPointer(686,14)); + script_680(44957712); + setScriptCallOnMouseEntered(95, new WidgetPointer(-32768,3), "I", new WidgetPointer(686,16)); + setScriptCallOnMouseExit(93, new WidgetPointer(-32768,3), "I", new WidgetPointer(686,16)); + setScriptCallOnClickContextMenu(69, 1, new WidgetPointer(686,9), "1I", new WidgetPointer(686,16)); + script_2003(); + setScriptCallOnConfigChange(961, 1195, 1, "Y", new WidgetPointer(686,1)); + setScriptCallOnSkillChange(961, 19, 1, "Y", new WidgetPointer(686,1)); + return; +} diff --git a/dumps/scripts/961.cs2 b/dumps/scripts/961.cs2 new file mode 100644 index 0000000..45b7bd8 --- /dev/null +++ b/dumps/scripts/961.cs2 @@ -0,0 +1,4 @@ +void script_961() { + script_2003(); + return; +} diff --git a/dumps/scripts/962.cs2 b/dumps/scripts/962.cs2 new file mode 100644 index 0000000..f422adc --- /dev/null +++ b/dumps/scripts/962.cs2 @@ -0,0 +1,52 @@ +void script_962(int arg0) { + globalint_157 = 1; + if (globalint_125 >= subtract(getClientCycle(), 5)) { + return; + } + if (arg0 == 48103425) { + switch (globalint_122) { + case 0: + globalint_122 = 1536; + break; + case 512: + globalint_122 = 0; + break; + case 1024: + globalint_122 = 1024; + break; + default: + globalint_122 = 512; + } + } else if (arg0 == 48103430) { + switch (globalint_123) { + case 0: + globalint_123 = 1536; + break; + case 512: + globalint_123 = 0; + break; + case 1024: + globalint_123 = 1024; + break; + default: + globalint_123 = 512; + } + } else { + if (arg0 == 48103435) { + switch (globalint_124) { + case 0: + globalint_124 = 1536; + break; + case 512: + globalint_124 = 0; + break; + case 1024: + globalint_124 = 1024; + break; + default: + globalint_124 = 512; + } + } + } + return; +} diff --git a/dumps/scripts/963.cs2 b/dumps/scripts/963.cs2 new file mode 100644 index 0000000..c26d568 --- /dev/null +++ b/dumps/scripts/963.cs2 @@ -0,0 +1,52 @@ +void script_963(int arg0) { + globalint_157 = 1; + if (globalint_125 >= subtract(getClientCycle(), 5)) { + return; + } + if (arg0 == 48103425) { + switch (globalint_122) { + case 0: + globalint_122 = 512; + break; + case 512: + globalint_122 = 1024; + break; + case 1024: + globalint_122 = 1536; + break; + default: + globalint_122 = 0; + } + } else if (arg0 == 48103430) { + switch (globalint_123) { + case 0: + globalint_123 = 512; + break; + case 512: + globalint_123 = 1024; + break; + case 1024: + globalint_123 = 1536; + break; + default: + globalint_123 = 0; + } + } else { + if (arg0 == 48103435) { + switch (globalint_124) { + case 0: + globalint_124 = 512; + break; + case 512: + globalint_124 = 1024; + break; + case 1024: + globalint_124 = 1536; + break; + default: + globalint_124 = 0; + } + } + } + return; +} diff --git a/dumps/scripts/964.cs2 b/dumps/scripts/964.cs2 new file mode 100644 index 0000000..deb56ee --- /dev/null +++ b/dumps/scripts/964.cs2 @@ -0,0 +1,61 @@ +void script_964() { + flow_0: + SWITCH (bitconfig_2341) { + case 1: + GOTO flow_1 + case 2: + GOTO flow_2 + case 3: + GOTO flow_3 + } + globalint_122 = 0; + GOTO flow_4 + flow_1: + globalint_122 = 1536; + GOTO flow_4 + flow_2: + globalint_122 = 1024; + GOTO flow_4 + flow_3: + globalint_122 = 512; + flow_4: + SWITCH (bitconfig_2342) { + case 1: + GOTO flow_5 + case 2: + GOTO flow_6 + case 3: + GOTO flow_7 + } + globalint_123 = 0; + GOTO flow_8 + flow_5: + globalint_123 = 1536; + GOTO flow_8 + flow_6: + globalint_123 = 1024; + GOTO flow_8 + flow_7: + globalint_123 = 512; + flow_8: + SWITCH (bitconfig_2343) { + case 1: + GOTO flow_9 + case 2: + GOTO flow_10 + case 3: + GOTO flow_11 + } + globalint_124 = 0; + GOTO flow_12 + flow_9: + globalint_124 = 1536; + GOTO flow_12 + flow_10: + globalint_124 = 1024; + GOTO flow_12 + flow_11: + globalint_124 = 512; + flow_12: + return; +} diff --git a/dumps/scripts/965.cs2 b/dumps/scripts/965.cs2 new file mode 100644 index 0000000..4f17c78 --- /dev/null +++ b/dumps/scripts/965.cs2 @@ -0,0 +1,29 @@ +void script_965(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10,int arg11,int arg12,int arg13,int arg14,int arg15,int arg16) { + script_966(arg0, globalint_122); + script_966(arg1, globalint_122); + script_966(arg2, globalint_122); + script_966(arg3, globalint_122); + script_966(arg4, globalint_122); + script_966(arg5, globalint_123); + script_966(arg6, globalint_123); + script_966(arg7, globalint_123); + script_966(arg8, globalint_123); + script_966(arg9, globalint_123); + script_966(arg10, globalint_124); + script_966(arg11, globalint_124); + script_966(arg12, globalint_124); + script_966(arg13, globalint_124); + script_966(arg14, globalint_124); + if (globalint_125 < getClientCycle()) { + setWidgetIsHidden(false, new WidgetPointer(arg15)); + setWidgetIsHidden(true, new WidgetPointer(arg16)); + } else { + if ((globalint_156 <= getClientCycle()) && ((boolean)globalint_157)) { + playSoundEffect2False(7540, 1, 0, 100, cs2method_4019(15, 15)); + globalint_156 = add(getClientCycle(), 30); + } + setWidgetIsHidden(true, new WidgetPointer(arg15)); + setWidgetIsHidden(false, new WidgetPointer(arg16)); + } + return; +} diff --git a/dumps/scripts/966.cs2 b/dumps/scripts/966.cs2 new file mode 100644 index 0000000..abd26db --- /dev/null +++ b/dumps/scripts/966.cs2 @@ -0,0 +1,9 @@ +void script_966(int arg0,int arg1) { + int ivar2; + ivar2 = cs2method2607(new WidgetPointer(arg0)); + if (ivar2 != arg1) { + setWidget3DRotation(0, 0, getWidgetRotateX(new WidgetPointer(arg0)), getWidgetRotateY(new WidgetPointer(arg0)), script_967(ivar2, arg1), getWidget3DDistance(new WidgetPointer(arg0)), new WidgetPointer(arg0)); + globalint_125 = getClientCycle(); + } + return; +} diff --git a/dumps/scripts/967.cs2 b/dumps/scripts/967.cs2 new file mode 100644 index 0000000..cfc6af3 --- /dev/null +++ b/dumps/scripts/967.cs2 @@ -0,0 +1,18 @@ +int script_967(int arg0,int arg1) { + if (arg1 > arg0) { + if (subtract(arg1, arg0) <= 1024) { + return min(add(arg0, 6), arg1); + } + if (arg0 >= 6) { + return subtract(arg0, 6); + } + return max(script_686(subtract(arg0, 6), 2048), arg1); + } + if (subtract(arg0, arg1) <= 1024) { + return max(subtract(arg0, 6), arg1); + } + if (arg0 < subtract(2048, 6)) { + return add(arg0, 6); + } + return min(mod(add(arg0, 6), 2048), arg1); +} diff --git a/dumps/scripts/968.cs2 b/dumps/scripts/968.cs2 new file mode 100644 index 0000000..3fb31c6 --- /dev/null +++ b/dumps/scripts/968.cs2 @@ -0,0 +1,8 @@ +void script_968(int arg0) { + if (((boolean)script_970(arg0))) { + setScriptCallOnGameloop(969, new WidgetPointer(arg0), "I", new WidgetPointer(arg0)); + } else { + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/969.cs2 b/dumps/scripts/969.cs2 new file mode 100644 index 0000000..cba47d0 --- /dev/null +++ b/dumps/scripts/969.cs2 @@ -0,0 +1,20 @@ +void script_969(int arg0) { + int ivar1; + ivar1 = mod(getClientCycle(), 32); + if (((boolean)script_970(arg0))) { + if (getWidgetShadeColor(new WidgetPointer(arg0)) != 0) { + cs2method2103(0, new WidgetPointer(arg0)); + } else { + setScriptCallOnGameloop(-1, "", new WidgetPointer(arg0)); + } + } else if (ivar1 < 8) { + cs2method2103(0, new WidgetPointer(arg0)); + } else if (ivar1 < 16) { + cs2method2103(85, new WidgetPointer(arg0)); + } else if (ivar1 < 24) { + cs2method2103(255, new WidgetPointer(arg0)); + } else { + cs2method2103(85, new WidgetPointer(arg0)); + } + return; +} diff --git a/dumps/scripts/97.cs2 b/dumps/scripts/97.cs2 new file mode 100644 index 0000000..9d693bb --- /dev/null +++ b/dumps/scripts/97.cs2 @@ -0,0 +1,4 @@ +void script_97(int arg0) { + script_915(arg0); + return; +} diff --git a/dumps/scripts/970.cs2 b/dumps/scripts/970.cs2 new file mode 100644 index 0000000..ee2a079 --- /dev/null +++ b/dumps/scripts/970.cs2 @@ -0,0 +1,78 @@ +int script_970(int arg0) { + if ((arg0 == 20971715) && ((boolean)bitconfig_4732)) { + return 1; + } + if ((arg0 == 20971526) && ((boolean)bitconfig_4733)) { + return 1; + } + if ((arg0 == 20971543) && ((boolean)bitconfig_4734)) { + return 1; + } + if ((arg0 == 20971567) && ((boolean)bitconfig_4735)) { + return 1; + } + if ((arg0 == 20971591) && ((boolean)bitconfig_4736)) { + return 1; + } + if ((arg0 == 20971608) && ((boolean)bitconfig_4737)) { + return 1; + } + if ((arg0 == 20971708) && ((boolean)bitconfig_4738)) { + return 1; + } + if ((arg0 == 20971534) && ((boolean)bitconfig_4739)) { + return 1; + } + if ((arg0 == 20971551) && ((boolean)bitconfig_4740)) { + return 1; + } + if ((arg0 == 20971575) && ((boolean)bitconfig_4741)) { + return 1; + } + if ((arg0 == 20971599) && ((boolean)bitconfig_4742)) { + return 1; + } + if ((arg0 == 20971616) && ((boolean)bitconfig_4743)) { + return 1; + } + if ((arg0 == 20971701) && ((boolean)bitconfig_4744)) { + return 1; + } + if ((arg0 == 20971694) && ((boolean)bitconfig_4745)) { + return 1; + } + if ((arg0 == 20971559) && ((boolean)bitconfig_4746)) { + return 1; + } + if ((arg0 == 20971583) && ((boolean)bitconfig_4747)) { + return 1; + } + if ((arg0 == 20971687) && ((boolean)bitconfig_4748)) { + return 1; + } + if ((arg0 == 20971680) && ((boolean)bitconfig_4749)) { + return 1; + } + if ((arg0 == 20971625) && ((boolean)bitconfig_4750)) { + return 1; + } + if ((arg0 == 20971633) && ((boolean)bitconfig_4751)) { + return 1; + } + if ((arg0 == 20971641) && ((boolean)bitconfig_4752)) { + return 1; + } + if ((arg0 == 20971649) && ((boolean)bitconfig_4753)) { + return 1; + } + if ((arg0 == 20971657) && ((boolean)bitconfig_4754)) { + return 1; + } + if ((arg0 == 20971665) && ((boolean)bitconfig_4755)) { + return 1; + } + if ((arg0 == 20971673) && ((boolean)bitconfig_7756)) { + return 1; + } + return 0; +} diff --git a/dumps/scripts/971.cs2 b/dumps/scripts/971.cs2 new file mode 100644 index 0000000..adc1b2b --- /dev/null +++ b/dumps/scripts/971.cs2 @@ -0,0 +1,6 @@ +void script_971() { + if (bitconfig_4757 > 0) { + setWidgetSprite(cs2method_3408(105, 100, 1478, bitconfig_4757), new WidgetPointer(740,4)); + } + return; +} diff --git a/dumps/scripts/972.cs2 b/dumps/scripts/972.cs2 new file mode 100644 index 0000000..e5f24f9 --- /dev/null +++ b/dumps/scripts/972.cs2 @@ -0,0 +1,4 @@ +void script_972() { + script_973(); + return; +} diff --git a/dumps/scripts/973.cs2 b/dumps/scripts/973.cs2 new file mode 100644 index 0000000..84d9ee8 --- /dev/null +++ b/dumps/scripts/973.cs2 @@ -0,0 +1,284 @@ +void script_973() { + int ivar0; + int ivar1; + int ivar2; + int ivar3; + int ivar4; + int ivar5; + int ivar6; + int ivar7; + int ivar8; + int ivar9; + int ivar10; + int ivar11; + int ivar12; + int ivar13; + int ivar14; + int ivar15; + int ivar16; + string svar0; + string svar1; + string svar2; + int stack_dump0; + cs2func_script_976_struct(2,1,0) structdump_1; + int stack_dump2; + cs2func_script_1023_struct(2,1,0) structdump_3; + cs2func_script_12_struct(1,1,0) structdump_4; + cs2func_script_13_struct(1,1,0) structdump_5; + int stack_dump6; + cs2func_script_1567_struct(2,2,0) structdump_7; + cs2func_script_14_struct(2,2,0) structdump_8; + ivar0 = bitconfig_4729; + if ((bitconfig_4729 < 1) || (bitconfig_4729 > 25)) { + return; + } + svar0 = getCommonString(1477, ivar0); + ivar1 = cs2method_3408(105, 83, 681, ivar0); + ivar2 = cs2method_3408(105, 100, 1478, ivar0); + ivar3 = 1; + ivar4 = 1; + switch (ivar0) { + case 1: + ivar4 = globalint_1469; + break; + case 2: + ivar4 = globalint_1470; + break; + case 5: + ivar4 = globalint_1471; + break; + case 3: + ivar4 = globalint_1472; + break; + case 7: + ivar4 = globalint_1473; + break; + case 4: + ivar4 = globalint_1474; + break; + case 6: + ivar4 = globalint_1475; + break; + case 8: + ivar4 = globalint_1476; + break; + case 9: + ivar4 = globalint_1477; + break; + case 10: + ivar4 = globalint_1478; + break; + case 11: + ivar4 = globalint_1479; + break; + case 19: + ivar4 = globalint_1480; + break; + case 13: + ivar4 = globalint_1481; + break; + case 14: + ivar4 = globalint_1482; + break; + case 15: + ivar4 = globalint_1483; + break; + case 16: + ivar4 = globalint_1484; + break; + case 17: + ivar4 = globalint_1485; + break; + case 18: + ivar4 = globalint_1486; + break; + case 12: + ivar4 = globalint_1487; + break; + case 20: + ivar4 = globalint_1488; + break; + case 21: + ivar4 = globalint_1489; + break; + case 22: + ivar4 = globalint_1490; + break; + case 23: + ivar4 = globalint_1491; + break; + case 24: + ivar4 = globalint_1492; + break; + case 25: + ivar4 = globalint_1493; + } + if (add(ivar4, 1) != getSkillActualLvl(ivar1)) { + svar0 = getCommonString(3644, ivar0) + intToStr(subtract(getSkillActualLvl(ivar1), ivar4)) + getCommonString(3645, ivar0); + } + setWidgetText(new WidgetPointer(741,4), svar0); + setWidgetText(new WidgetPointer(741,6), "You have now reached level " + intToStr(getSkillActualLvl(ivar1)) + "."); + setWidgetSprite(ivar2, new WidgetPointer(741,7)); + ivar5 = 0; + ivar6 = 0; + ivar7 = 0; + svar1 = ""; + ivar8 = 0; + ivar9 = -1; + ivar10 = 2287; + ivar11 = ivar10; + ivar12 = 0; + deleteAllExtraChilds(new WidgetPointer(741,2)); + deleteAllExtraChilds(new WidgetPointer(741,3)); + if ((standart_config_281 < 1000) && (getSkillActualLvl(ivar1) == 3)) { + svar1 = "" + "You've now reached the highest skill level that you can achieve during the tutorial. Once you finish the tutorial, you can advance this skill even further!"; + ivar7 = script_974(ivar5, ivar6, 7620, ivar10, 0, 0, svar1); + setWidgetText(svar1); + ivar6 = script_975(ivar6, ivar7); + ivar5 = add(2, ivar5); + } + if (((boolean)bitconfig_4730)) { + svar1 = "" + "Well done! You've reached the total level " + intToStr(cs2method_3408(105, 105, 1475, bitconfig_4728)) + " milestone!"; + ivar7 = script_974(ivar5, ivar6, 7620, ivar10, 0, 0, svar1); + setWidgetText(svar1); + ivar6 = script_975(ivar6, ivar7); + ivar5 = add(2, ivar5); + } + ivar8 = 0; + svar1 = "null"; + ivar9 = 7620; + if (((((((((boolean)ivar0) || (ivar0 == 2)) || (ivar0 == 5)) || (ivar0 == 3)) || (ivar0 == 7)) || (ivar0 == 4)) || (ivar0 == 6)) || (ivar0 == 24)) { + if (((boolean)bitconfig_4731)) { + svar1 = "" + "Well done! You've reached the Combat level " + intToStr(cs2method_3408(105, 105, 1473, bitconfig_4727)) + " milestone!"; + ivar7 = script_974(ivar5, ivar6, 7620, ivar10, 0, 0, svar1); + setWidgetText(svar1); + ivar6 = script_975(ivar6, ivar7); + ivar5 = add(2, ivar5); + } + if (((boolean)bitconfig_5395) && (ivar9 != -1)) { + while (true) { + stack_dump0 = ivar8; + structdump_1 = script_976(stack_dump0); + svar1 = structdump_1.stringpart_0; + ivar9 = structdump_1.intpart_1; + ivar12 = structdump_1.intpart_0; + if (ivar12 == script_1432()) { + ivar7 = script_974(ivar5, ivar6, ivar9, ivar10, 0, 0, svar1); + setWidgetText(svar1); + ivar6 = script_975(ivar6, ivar7); + ivar5 = add(2, ivar5); + } + ivar8 = add(ivar8, 1); + } + } + } + svar1 = ""; + ivar9 = 7620; + ivar13 = 0; + ivar8 = 0; + while (ivar13 != -1) { + ivar13 = 0; + stack_dump0 = ivar1; + stack_dump2 = ivar8; + structdump_3 = script_1023(stack_dump0, stack_dump2); + ivar13 = structdump_3.intpart_1; + ivar9 = structdump_3.intpart_0; + svar1 = structdump_3.stringpart_0; + if (((boolean)ivar13)) { + ivar7 = script_974(ivar5, ivar6, ivar9, ivar10, 0, 0, svar1); + setWidgetText(svar1); + ivar6 = script_975(ivar6, ivar7); + ivar5 = add(2, ivar5); + ivar3 = 0; + } + ivar8 = add(ivar8, 1); + } + ivar11 = ivar10; + ivar9 = 7620; + svar1 = ""; + ivar8 = 0; + ivar14 = 0; + ivar15 = 0; + ivar16 = 0; + svar2 = ""; + stack_dump0 = ivar0; + structdump_4 = script_12(stack_dump0); + ivar14 = structdump_4.intpart_0; + svar0 = structdump_4.stringpart_0; + while (ivar8 < ivar14) { + flow_49: + stack_dump0 = ivar0; + stack_dump2 = ivar8; + structdump_5 = script_13(stack_dump0, stack_dump2); + ivar15 = structdump_5.intpart_0; + svar0 = structdump_5.stringpart_0; + ivar16 = 0; + ivar9 = 7620; + ivar11 = ivar10; + IF (((boolean)script_1566(ivar0, ivar8))) + GOTO flow_51 + GOTO flow_57 + flow_51: + IF (ivar11 != -1) + GOTO flow_52 + GOTO flow_56 + flow_52: + stack_dump0 = ivar0; + stack_dump2 = ivar8; + stack_dump6 = ivar16; + structdump_7 = script_1567(stack_dump0, stack_dump2, stack_dump6); + svar1 = structdump_7.stringpart_1; + svar2 = structdump_7.stringpart_0; + ivar11 = structdump_7.intpart_1; + ivar12 = structdump_7.intpart_0; + if ((ivar12 <= getSkillActualLvl(ivar1)) && (ivar12 > ivar4)) { + ivar7 = script_974(ivar5, ivar6, ivar9, ivar11, ivar0, ivar8, svar1); + setWidgetText(svar1); + ivar6 = script_975(ivar6, ivar7); + ivar5 = add(2, ivar5); + ivar3 = 0; + } + ivar16 = add(ivar16, 1); + GOTO flow_51 + flow_56: + ivar8 = add(ivar8, 1); + GOTO flow_63 + flow_57: + IF (ivar9 != -1) + GOTO flow_58 + GOTO flow_62 + flow_58: + stack_dump0 = ivar0; + stack_dump2 = ivar8; + stack_dump6 = ivar16; + structdump_8 = script_14(stack_dump0, stack_dump2, stack_dump6); + svar1 = structdump_8.stringpart_1; + svar2 = structdump_8.stringpart_0; + ivar9 = structdump_8.intpart_1; + ivar12 = structdump_8.intpart_0; + if ((ivar12 <= getSkillActualLvl(ivar1)) && (ivar12 > ivar4)) { + ivar7 = script_974(ivar5, ivar6, ivar9, ivar11, ivar0, ivar8, svar1); + setWidgetText(svar1); + ivar6 = script_975(ivar6, ivar7); + ivar5 = add(2, ivar5); + ivar3 = 0; + } + ivar16 = add(ivar16, 1); + GOTO flow_57 + flow_62: + ivar8 = add(ivar8, 1); + flow_63: + } + if (((boolean)ivar3)) { + svar1 = concat(script_4242(ivar0), "Check out the skill advance guide to see what you'll be able to do when you reach even higher levels..."); + ivar7 = script_974(ivar5, ivar6, 7620, ivar10, 0, 0, svar1); + setWidgetText(svar1); + ivar6 = script_975(ivar6, ivar7); + } + cs2method2100(0, 0, new WidgetPointer(741,2)); + setWidgetScrollMax(296, ivar6, new WidgetPointer(741,2)); + if (ivar6 > 160) { + script_31(48562179, 48562178, 798, 795, 796, 797, 793, 794); + } + return; +} diff --git a/dumps/scripts/974.cs2 b/dumps/scripts/974.cs2 new file mode 100644 index 0000000..1fab0cd --- /dev/null +++ b/dumps/scripts/974.cs2 @@ -0,0 +1,42 @@ +int script_974(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,string arg6) { + int ivar6; + int ivar7; + ivar6 = 0; + ivar7 = 2287; + createExtraChild(new WidgetPointer(741,2), 5, arg0); + if (((boolean)script_1566(arg4, arg5))) { + if (arg4 == 7) { + setWidgetSize(30, 30, 0, 0); + } else if (arg4 == 4) { + setWidgetSize(24, 24, 0, 0); + } else { + setWidgetSize(36, 32, 0, 0); + } + setWidgetBorderThickness(0); + if (arg3 != -1) { + setWidgetSprite(arg3); + } else { + setWidgetSprite(ivar7); + } + } else if ((arg2 == 18637) || (arg2 == 18638)) { + setWidgetSize(24, 24, 0, 0); + setWidgetBorderThickness(0); + if (arg2 == 18637) { + setWidgetSprite(3057); + } else { + setWidgetSprite(3056); + } + } else if (arg2 != -1) { + setItemOnWidgetMethod1200(arg2, -1); + } else { + setItemOnWidgetMethod1200(7620, -1); + } + setWidgetSize(36, 32, 0, 0); + setWidgetBorderThickness(1); + setWidgetShadowColor(new Color(96, 78, 50)); + setWidgetPosition(0, arg1, 0, 0); + createExtraChild(new WidgetPointer(741,2), 4, add(arg0, 1)); + ivar6 = getLineCount(300, 495, arg6); + setWidgetSize(300, multiply(ivar6, 16), 0, 0); + return ivar6; +} diff --git a/dumps/scripts/975.cs2 b/dumps/scripts/975.cs2 new file mode 100644 index 0000000..a9cfc91 --- /dev/null +++ b/dumps/scripts/975.cs2 @@ -0,0 +1,13 @@ +int script_975(int arg0,int arg1) { + setWidgetPosition(50, arg0, 0, 0); + setWidgetTextAlignment(0, 0, 16); + setWidgetRGB(new Color(70, 50, 10)); + setWidgetFont(495); + setWidgetUnknownBoolean(false); + if (multiply(arg1, 16) < 32) { + arg0 = add(arg0, 32); + } else { + arg0 = add(arg0, add(multiply(arg1, 16), 5)); + } + return arg0; +} diff --git a/dumps/scripts/976.cs2 b/dumps/scripts/976.cs2 new file mode 100644 index 0000000..6e204ce --- /dev/null +++ b/dumps/scripts/976.cs2 @@ -0,0 +1,25 @@ +cs2func_script_976_struct(2,1,0) script_976(int arg0) { + switch (arg0) { + case 0: + return newstruct cs2func_script_976_struct(3, 4155, "Members now have the Combat level required to request Slayer tasks from the Burthorpe Slayer Master."); + case 1: + return newstruct cs2func_script_976_struct(20, 4155, "Members now have the Combat level required to request Slayer tasks from Mazchna."); + case 2: + return newstruct cs2func_script_976_struct(40, 4155, "Members now have the Combat level required to request Slayer tasks from Vannaka."); + case 3: + return newstruct cs2func_script_976_struct(40, 11673, "Members now have the Combat level required to board the novice lander in Pest Control."); + case 4: + return newstruct cs2func_script_976_struct(70, 4155, "Members now have the Combat level required to request Slayer tasks from Chaeldar."); + case 5: + return newstruct cs2func_script_976_struct(70, 11673, "Members now have the Combat level required to board the intermediate lander in Pest Control."); + case 6: + return newstruct cs2func_script_976_struct(85, 6513, "Members now have the Combat level required to start Dream Mentor."); + case 7: + return newstruct cs2func_script_976_struct(85, 6513, "Members now have the Combat level required to start Smoking Kills."); + case 8: + return newstruct cs2func_script_976_struct(100, 4155, "Members now have the Combat level required to request Slayer tasks from the Shilo Village Slayer Master. (Level 50 Slayer is also required.)"); + case 9: + return newstruct cs2func_script_976_struct(100, 11673, "Members now have the Combat level required to board the veteran lander in Pest Control."); + } + return newstruct cs2func_script_976_struct(-1, -1, ""); +} diff --git a/dumps/scripts/977.cs2 b/dumps/scripts/977.cs2 new file mode 100644 index 0000000..49c4b70 --- /dev/null +++ b/dumps/scripts/977.cs2 @@ -0,0 +1,35 @@ +cs2func_script_977_struct(1,1,0) script_977(int arg0) { + switch (arg0) { + case 0: + return newstruct cs2func_script_977_struct(0, "Bronze"); + case 1: + return newstruct cs2func_script_977_struct(0, "Iron"); + case 2: + return newstruct cs2func_script_977_struct(0, "Steel"); + case 3: + return newstruct cs2func_script_977_struct(0, "Black"); + case 4: + return newstruct cs2func_script_977_struct(1, "White"); + case 5: + return newstruct cs2func_script_977_struct(0, "Mithril"); + case 6: + return newstruct cs2func_script_977_struct(0, "Adamant"); + case 7: + return newstruct cs2func_script_977_struct(0, "Rune"); + case 8: + return newstruct cs2func_script_977_struct(0, "Dragon"); + case 9: + return newstruct cs2func_script_977_struct(1, "Barrows"); + case 10: + return newstruct cs2func_script_977_struct(0, "Magic"); + case 11: + return newstruct cs2func_script_977_struct(0, "Equipment"); + case 12: + return newstruct cs2func_script_977_struct(1, "Minigames"); + case 13: + return newstruct cs2func_script_977_struct(0, "Dungeoneering"); + case 14: + return newstruct cs2func_script_977_struct(0, "Milestones"); + } + return newstruct cs2func_script_977_struct(-1, ""); +} diff --git a/dumps/scripts/978.cs2 b/dumps/scripts/978.cs2 new file mode 100644 index 0000000..4096274 --- /dev/null +++ b/dumps/scripts/978.cs2 @@ -0,0 +1,1269 @@ +cs2func_script_978_struct(2,2,0) script_978(int arg0,int arg1) { + switch (arg0) { + case 0: + switch (arg1) { + case 0: + return newstruct cs2func_script_978_struct(1, 1173, "Bronze square shield", "You can now wield " + "" + "bronze square shields" + "" + "."); + case 1: + return newstruct cs2func_script_978_struct(1, 1189, "Bronze kiteshield", "You can now wield " + "" + "bronze kiteshields" + "" + "."); + case 2: + return newstruct cs2func_script_978_struct(1, 1139, "Bronze medium helm", "You can now wear " + "" + "bronze medium helms" + "" + "."); + case 3: + return newstruct cs2func_script_978_struct(1, 1155, "Bronze full helm", "You can now wear " + "" + "bronze full helms" + "" + "."); + case 4: + return newstruct cs2func_script_978_struct(1, 1103, "Bronze chainbody", "You can now wear " + "" + "bronze chainbodies" + "" + "."); + case 5: + return newstruct cs2func_script_978_struct(1, 1117, "Bronze platebody", "You can now wear " + "" + "bronze platebodies" + "" + "."); + case 6: + return newstruct cs2func_script_978_struct(1, 1087, "Bronze plateskirt", "You can now wear " + "" + "bronze plateskirts" + "" + "."); + case 7: + return newstruct cs2func_script_978_struct(1, 1075, "Bronze platelegs", "You can now wear " + "" + "bronze platelegs" + "" + "."); + case 8: + return newstruct cs2func_script_978_struct(1, 4119, "Members: Bronze boots", "Members can now wear " + "" + "bronze boots" + "" + "."); + case 9: + return newstruct cs2func_script_978_struct(1, 8844, "Members: Bronze defender", "Members can now wield " + "" + "bronze defenders" + "" + "."); + case 10: + return newstruct cs2func_script_978_struct(1, 12985, "Bronze gauntlets", "You can now wear " + "" + "bronze gauntlets" + "" + "."); + } + break; + case 1: + switch (arg1) { + case 0: + return newstruct cs2func_script_978_struct(1, 1175, "Iron square shield", "You can now wield " + "" + "iron square shields" + "" + "."); + case 1: + return newstruct cs2func_script_978_struct(1, 1191, "Iron kiteshield", "You can now wield " + "" + "iron kiteshields" + "" + "."); + case 2: + return newstruct cs2func_script_978_struct(1, 1137, "Iron medium helm", "You can now wear " + "" + "iron medium helms" + "" + "."); + case 3: + return newstruct cs2func_script_978_struct(1, 1153, "Iron full helm", "You can now wear " + "" + "iron full helms" + "" + "."); + case 4: + return newstruct cs2func_script_978_struct(1, 1101, "Iron chainbody", "You can now wear " + "" + "iron chainbodies" + "" + "."); + case 5: + return newstruct cs2func_script_978_struct(1, 1115, "Iron platebody", "You can now wear " + "" + "iron platebodies" + "" + "."); + case 6: + return newstruct cs2func_script_978_struct(1, 1081, "Iron plateskirt", "You can now wear " + "" + "iron plateskirts" + "" + "."); + case 7: + return newstruct cs2func_script_978_struct(1, 1067, "Iron platelegs", "You can now wear " + "" + "iron platelegs" + "" + "."); + case 8: + return newstruct cs2func_script_978_struct(1, 4121, "Members: Iron boots", "Members can now wear " + "" + "iron boots" + "" + "."); + case 9: + return newstruct cs2func_script_978_struct(1, 8845, "Members: Iron defender", "Members can now wield " + "" + "iron defenders" + "" + "."); + case 10: + return newstruct cs2func_script_978_struct(1, 12988, "Iron gauntlets", "You can now wear " + "" + "iron gauntlets" + "" + "."); + } + break; + case 2: + switch (arg1) { + case 0: + return newstruct cs2func_script_978_struct(5, 1177, "Steel square shield", "You can now wield " + "" + "steel square shields" + "" + "."); + case 1: + return newstruct cs2func_script_978_struct(5, 1193, "Steel kiteshield", "You can now wield " + "" + "steel kiteshields" + "" + "."); + case 2: + return newstruct cs2func_script_978_struct(5, 1141, "Steel medium helm", "You can now wear " + "" + "steel medium helms" + "" + "."); + case 3: + return newstruct cs2func_script_978_struct(5, 1157, "Steel full helm", "You can now wear " + "" + "steel full helms" + "" + "."); + case 4: + return newstruct cs2func_script_978_struct(5, 1105, "Steel chainbody", "You can now wear " + "" + "steel chainbodies" + "" + "."); + case 5: + return newstruct cs2func_script_978_struct(5, 1119, "Steel platebody", "You can now wear " + "" + "steel platebodies" + "" + "."); + case 6: + return newstruct cs2func_script_978_struct(5, 1083, "Steel plateskirt", "You can now wear " + "" + "steel plateskirts" + "" + "."); + case 7: + return newstruct cs2func_script_978_struct(5, 1069, "Steel platelegs", "You can now wear " + "" + "steel platelegs" + "" + "."); + case 8: + return newstruct cs2func_script_978_struct(5, 4123, "Members: Steel boots", "Members can now wear " + "" + "steel boots" + "" + "."); + case 9: + return newstruct cs2func_script_978_struct(5, 8846, "Members: Steel defender" + "
" + " (with 5 Attack)", "Members now have the Defence level required to wield " + "" + "steel defenders" + "" + ". (They also need level 5 Attack.)"); + case 10: + return newstruct cs2func_script_978_struct(5, 12991, "Steel gauntlets", "You can now wear " + "" + "steel gauntlets" + "" + "."); + } + break; + case 3: + switch (arg1) { + case 0: + return newstruct cs2func_script_978_struct(10, 1179, "Black square shield", "You can now wield " + "" + "black square shields" + "" + "."); + case 1: + return newstruct cs2func_script_978_struct(10, 1195, "Black kiteshield", "You can now wield " + "" + "black kiteshields" + "" + "."); + case 2: + return newstruct cs2func_script_978_struct(10, 1151, "Black medium helm", "You can now wear " + "" + "black medium helms" + "" + "."); + case 3: + return newstruct cs2func_script_978_struct(10, 1165, "Black full helm", "You can now wear " + "" + "black full helms" + "" + "."); + case 4: + return newstruct cs2func_script_978_struct(10, 1107, "Black chainbody", "You can now wear " + "" + "black chainbodies" + "" + "."); + case 5: + return newstruct cs2func_script_978_struct(10, 1125, "Black platebody", "You can now wear " + "" + "black platebodies" + "" + "."); + case 6: + return newstruct cs2func_script_978_struct(10, 1089, "Black plateskirt", "You can now wear " + "" + "black plateskirts" + "" + "."); + case 7: + return newstruct cs2func_script_978_struct(10, 1077, "Black platelegs", "You can now wear " + "" + "black platelegs" + "" + "."); + case 8: + return newstruct cs2func_script_978_struct(10, 4125, "Members: Black boots", "Members can now wear " + "" + "black boots" + "" + "."); + case 9: + return newstruct cs2func_script_978_struct(10, 8847, "Members: Black defender" + "
" + " (with 10 Attack)", "Members now have the Defence level required to wield " + "" + "black defenders" + "" + ". (They also need level 10 Attack.)"); + case 10: + return newstruct cs2func_script_978_struct(10, 12994, "Black gauntlets", "You can now wear " + "" + "black gauntlets" + "" + "."); + case 11: + return newstruct cs2func_script_978_struct(40, 14494, "Members: Elite black full helm", "Members can now wear " + "" + "elite black full helms" + "" + "."); + case 12: + return newstruct cs2func_script_978_struct(40, 14492, "Members: Elite black platebody", "Members can now wear " + "" + "elite black platebodies" + "" + "."); + case 13: + return newstruct cs2func_script_978_struct(40, 14490, "Members: Elite black platelegs", "Members can now wear " + "" + "elite black platelegs" + "" + "."); + } + break; + case 4: + switch (arg1) { + case 0: + return newstruct cs2func_script_978_struct(-1, 7620, "To use any white equipment, you must have completed Wanted!.", ""); + case 1: + return newstruct cs2func_script_978_struct(10, 6631, "Members: White square shield", "Members can now wield " + "" + "white square shields" + "" + " (after finishing Wanted!)."); + case 2: + return newstruct cs2func_script_978_struct(10, 6633, "Members: White kiteshield", "Members can now wield " + "" + "white kiteshields" + "" + " (after finishing Wanted!)."); + case 3: + return newstruct cs2func_script_978_struct(10, 6621, "Members: White medium helm", "Members can now wear " + "" + "white medium helms" + "" + " (after finishing Wanted!)."); + case 4: + return newstruct cs2func_script_978_struct(10, 6623, "Members: White full helm", "Members can now wear " + "" + "white full helms" + "" + " (after finishing Wanted!)."); + case 5: + return newstruct cs2func_script_978_struct(10, 6615, "Members: White chainbody", "Members can now wear " + "" + "white chainbodies" + "" + " (after finishing Wanted!)."); + case 6: + return newstruct cs2func_script_978_struct(10, 6617, "Members: White platebody", "Members can now wear " + "" + "white platebodies" + "" + " (after finishing Wanted!)."); + case 7: + return newstruct cs2func_script_978_struct(10, 6627, "Members: White plateskirt", "Members can now wear " + "" + "white plateskirts" + "" + " (after finishing Wanted!)."); + case 8: + return newstruct cs2func_script_978_struct(10, 6625, "Members: White platelegs", "Members can now wear " + "" + "white platelegs" + "" + " (after finishing Wanted!)."); + case 9: + return newstruct cs2func_script_978_struct(10, 6619, "Members: White boots", "Members can now wear " + "" + "white boots" + "" + " (after finishing Wanted!)."); + case 10: + return newstruct cs2func_script_978_struct(10, 6629, "Members: White gloves", "Members can now wear " + "" + "white gloves" + "" + " (after finishing Wanted!)."); + } + break; + case 5: + switch (arg1) { + case 0: + return newstruct cs2func_script_978_struct(20, 1181, "Mithril square shield", "You can now wield " + "" + "mithril square shields" + "" + "."); + case 1: + return newstruct cs2func_script_978_struct(20, 1197, "Mithril kiteshield", "You can now wield " + "" + "mithril kiteshields" + "" + "."); + case 2: + return newstruct cs2func_script_978_struct(20, 1143, "Mithril medium helm", "You can now wear " + "" + "mithril medium helms" + "" + "."); + case 3: + return newstruct cs2func_script_978_struct(20, 1159, "Mithril full helm", "You can now wear " + "" + "mithril full helms" + "" + "."); + case 4: + return newstruct cs2func_script_978_struct(20, 1109, "Mithril chainbody", "You can now wear " + "" + "mithril chainbodies" + "" + "."); + case 5: + return newstruct cs2func_script_978_struct(20, 1121, "Mithril platebody", "You can now wear " + "" + "mithril platebodies" + "" + "."); + case 6: + return newstruct cs2func_script_978_struct(20, 1085, "Mithril plateskirt", "You can now wear " + "" + "mithril plateskirts" + "" + "."); + case 7: + return newstruct cs2func_script_978_struct(20, 1071, "Mithril platelegs", "You can now wear " + "" + "mithril platelegs" + "" + "."); + case 8: + return newstruct cs2func_script_978_struct(20, 4127, "Members: Mithril boots", "Members can now wear " + "" + "mithril boots" + "" + "."); + case 9: + return newstruct cs2func_script_978_struct(20, 8848, "Members: Defender" + "
" + " (with 20 Attack)", "Members now have the Defence level required to wield " + "" + "mithril defenders" + "" + ". (They also need level 20 Attack.)"); + case 10: + return newstruct cs2func_script_978_struct(20, 12997, "Mithril gauntlets", "You can now wear " + "" + "mithril gauntlets" + "" + "."); + } + break; + case 6: + switch (arg1) { + case 0: + return newstruct cs2func_script_978_struct(30, 1183, "Adamant square shield", "You can now wield " + "" + "adamant square shields" + "" + "."); + case 1: + return newstruct cs2func_script_978_struct(30, 1199, "Adamant kiteshield", "You can now wield " + "" + "adamant kiteshields" + "" + "."); + case 2: + return newstruct cs2func_script_978_struct(30, 1145, "Adamant medium helm", "You can now wear " + "" + "adamant medium helms" + "" + "."); + case 3: + return newstruct cs2func_script_978_struct(30, 1161, "Adamant full helm", "You can now wear " + "" + "adamant full helms" + "" + "."); + case 4: + return newstruct cs2func_script_978_struct(30, 1111, "Adamant chainbody", "You can now wear " + "" + "adamant chainbodies" + "" + "."); + case 5: + return newstruct cs2func_script_978_struct(30, 1123, "Adamant platebody", "You can now wear " + "" + "adamant platebodies" + "" + "."); + case 6: + return newstruct cs2func_script_978_struct(30, 1091, "Adamant plateskirt", "You can now wear " + "" + "adamant plateskirts" + "" + "."); + case 7: + return newstruct cs2func_script_978_struct(30, 1073, "Adamant platelegs", "You can now wear " + "" + "adamant platelegs" + "" + "."); + case 8: + return newstruct cs2func_script_978_struct(30, 4129, "Members: Adamant boots", "Members can now wear " + "" + "adamant boots" + "" + "."); + case 9: + return newstruct cs2func_script_978_struct(30, 8849, "Members: Adamant defender" + "
" + " (with 30 Attack)", "Members now have the Defence level required to wield " + "" + "adamant defenders" + "" + ". (They also need level 30 Attack.)"); + case 10: + return newstruct cs2func_script_978_struct(30, 13000, "Adamant gauntlets", "You can now wear " + "" + "adamant gauntlets" + "" + "."); + case 11: + return newstruct cs2func_script_978_struct(35, 12915, "Adamant berserker shield", "You can now wield " + "" + "adamant berserker shields" + "" + "."); + case 12: + return newstruct cs2func_script_978_struct(35, 12908, "Adamant spikeshield", "You can now wield " + "" + "adamant spikeshields" + "" + "."); + } + break; + case 7: + switch (arg1) { + case 0: + return newstruct cs2func_script_978_struct(40, 1185, "Rune square shield", "You can now wield " + "" + "rune square shields" + "" + "."); + case 1: + return newstruct cs2func_script_978_struct(40, 1201, "Rune kiteshield", "You can now wield " + "" + "rune kiteshields" + "" + "."); + case 2: + return newstruct cs2func_script_978_struct(40, 1147, "Rune medium helm", "You can now wear " + "" + "rune medium helms" + "" + "."); + case 3: + return newstruct cs2func_script_978_struct(40, 1163, "Rune full helm", "You can now wear " + "" + "rune full helms" + "" + "."); + case 4: + return newstruct cs2func_script_978_struct(40, 1113, "Rune chainbody", "You can now wear " + "" + "rune chainbodies" + "" + "."); + case 5: + return newstruct cs2func_script_978_struct(40, 1127, "Rune platebody" + "
" + " (after Dragon Slayer)", "You can now wear " + "" + "rune platebodies" + "" + " (after Dragon Slayer)."); + case 6: + return newstruct cs2func_script_978_struct(40, 1093, "Rune plateskirt", "You can now wear " + "" + "rune plateskirts" + "" + "."); + case 7: + return newstruct cs2func_script_978_struct(40, 1079, "Rune platelegs", "You can now wear " + "" + "rune platelegs" + "" + "."); + case 8: + return newstruct cs2func_script_978_struct(40, 4131, "Members: Rune boots", "Members can now wear " + "" + "rune boots" + "" + "."); + case 9: + return newstruct cs2func_script_978_struct(40, 8850, "Members: Rune defender" + "
" + " (with 40 Attack)", "Members now have the Defence level required to wield " + "" + "rune defenders" + "" + ". (They also need level 40 Attack.)"); + case 10: + return newstruct cs2func_script_978_struct(40, 13003, "Rune gauntlets", "You can now wear " + "" + "rune gauntlets" + "" + "."); + case 11: + return newstruct cs2func_script_978_struct(45, 12929, "Rune berserker shield", "You can now wield " + "" + "rune berserker shields" + "" + "."); + case 12: + return newstruct cs2func_script_978_struct(45, 12922, "Rune spikeshield", "You can now wield " + "" + "rune spikeshields" + "" + "."); + } + break; + case 8: + switch (arg1) { + case 0: + return newstruct cs2func_script_978_struct(60, 1187, "Members: Dragon square shield" + "
" + " (after Legends' Quest)", "Members can now wield " + "" + "dragon square shields" + "" + " (after Legends' Quest)."); + case 1: + return newstruct cs2func_script_978_struct(60, 1149, "Members: Dragon medium helm", "Members can now wear " + "" + "dragon medium helms" + "" + "."); + case 2: + return newstruct cs2func_script_978_struct(60, 11335, "Members: Dragon full helm", "Members can now wear " + "" + "dragon full helms" + "" + "."); + case 3: + return newstruct cs2func_script_978_struct(60, 3140, "Members: Dragon chainbody", "Members can now wear " + "" + "dragon chainbodies" + "" + "."); + case 4: + return newstruct cs2func_script_978_struct(60, 14479, "Members: Dragon platebody", "Members can now wear " + "" + "dragon platebodies" + "" + "."); + case 5: + return newstruct cs2func_script_978_struct(60, 4585, "Members: Dragon plateskirt", "Members can now wear " + "" + "dragon plateskirts" + "" + "."); + case 6: + return newstruct cs2func_script_978_struct(60, 4087, "Members: Dragon platelegs", "Members can now wear " + "" + "dragon platelegs" + "" + "."); + case 7: + return newstruct cs2func_script_978_struct(60, 13006, "Members: Dragon gauntlets", "Members can now wear " + "" + "dragon gauntlets" + "" + "."); + case 8: + return newstruct cs2func_script_978_struct(60, 11732, "Members: Dragon boots", "Members can now wear " + "" + "dragon boots" + "" + "."); + case 9: + return newstruct cs2func_script_978_struct(60, 20072, "Members: Dragon defender" + "
" + " (with 60 Attack)", "Members now have the Defence level required to wield " + "" + "dragon defenders" + "" + ". (They also need level 60 Attack.)"); + case 10: + return newstruct cs2func_script_978_struct(60, 13964, "Corrupt dragon square shield", "You can now wield " + "" + "corrupt dragon square shields" + "" + "."); + case 11: + return newstruct cs2func_script_978_struct(60, 13961, "Corrupt dragon medium helm", "You can now wear " + "" + "corrupt dragon medium helms" + "" + "."); + case 12: + return newstruct cs2func_script_978_struct(60, 13958, "Corrupt dragon chainbody", "You can now wear " + "" + "corrupt dragon chainbodies" + "" + "."); + case 13: + return newstruct cs2func_script_978_struct(60, 13967, "Corrupt dragon plateskirt", "You can now wear " + "" + "corrupt dragon plateskirts" + "" + "."); + case 14: + return newstruct cs2func_script_978_struct(60, 13970, "Corrupt dragon platelegs", "You can now wear " + "" + "corrupt dragon platelegs" + "" + "."); + } + break; + case 9: + switch (arg1) { + case 0: + return newstruct cs2func_script_978_struct(70, 4708, "Members: Ahrim's hood" + "
" + " (with 70 Magic)", "Members now have the Defence level required to wear " + "" + "Ahrim's hood" + "" + ". (They also need level 70 Magic.)"); + case 1: + return newstruct cs2func_script_978_struct(70, 4712, "Members: Ahrim's robe top" + "
" + " (with 70 Magic)", "Members now have the Defence level required to wear " + "" + "Ahrim's robe top" + "" + ". (They also need level 70 Magic.)"); + case 2: + return newstruct cs2func_script_978_struct(70, 4714, "Members: Ahrim's robe skirt" + "
" + " (with 70 Magic)", "Members now have the Defence level required to wear " + "" + "Ahrim's robe skirt" + "" + ". (They also need level 70 Magic.)"); + case 3: + return newstruct cs2func_script_978_struct(70, 4716, "Members: Dharok's helm", "Members can now wear " + "" + "Dharok's helm" + "" + "."); + case 4: + return newstruct cs2func_script_978_struct(70, 4720, "Members: Dharok's platebody", "Members can now wear " + "" + "Dharok's platebody" + "" + "."); + case 5: + return newstruct cs2func_script_978_struct(70, 4722, "Members: Dharok's platelegs", "Members can now wear " + "" + "Dharok's platelegs" + "" + "."); + case 6: + return newstruct cs2func_script_978_struct(70, 4724, "Members: Guthan's helm", "Members can now wear " + "" + "Guthan's helm" + "" + "."); + case 7: + return newstruct cs2func_script_978_struct(70, 4728, "Members: Guthan's platebody", "Members can now wear " + "" + "Guthan's platebody" + "" + "."); + case 8: + return newstruct cs2func_script_978_struct(70, 4730, "Members: Guthan's chainskirt", "Members can now wear " + "" + "Guthan's chainskirt" + "" + "."); + case 9: + return newstruct cs2func_script_978_struct(70, 4732, "Members: Karil's coif" + "
" + " (with 70 Ranged)", "Members now have the Defence level required to wear " + "" + "Karil's coif" + "" + ". (They also need level 70 Ranged.)"); + case 10: + return newstruct cs2func_script_978_struct(70, 4736, "Members: Karil's leather top" + "
" + " (with 70 Ranged)", "Members now have the Defence level required to wear " + "" + "Karil's leather top" + "" + ". (They also need level 70 Ranged.)"); + case 11: + return newstruct cs2func_script_978_struct(70, 4738, "Members: Karil's leather skirt" + "
" + " (with 70 Ranged)", "Members now have the Defence level required to wear " + "" + "Karil's leather skirt" + "" + ". (They also need level 70 Ranged.)"); + case 12: + return newstruct cs2func_script_978_struct(70, 4745, "Members: Torag's helm", "Members can now wear " + "" + "Torag's helm" + "" + "."); + case 13: + return newstruct cs2func_script_978_struct(70, 4749, "Members: Torag's platebody", "Members can now wear " + "" + "Torag's platebody" + "" + "."); + case 14: + return newstruct cs2func_script_978_struct(70, 4751, "Members: Torag's platelegs", "Members can now wear " + "" + "Torag's platelegs" + "" + "."); + case 15: + return newstruct cs2func_script_978_struct(70, 4753, "Members: Verac's helm", "Members can now wear " + "" + "Verac's helm" + "" + "."); + case 16: + return newstruct cs2func_script_978_struct(70, 4757, "Members: Verac's brassard", "Members can now wear " + "" + "Verac's brassard" + "" + "."); + case 17: + return newstruct cs2func_script_978_struct(70, 4759, "Members: Verac's plateskirt", "Members can now wear " + "" + "Verac's plateskirt" + "" + "."); + case 18: + return newstruct cs2func_script_978_struct(70, 21736, "Members: Akrisae's hood" + "
" + " (after Ritual of the Mahjarrat and with level 70 Prayer and 70 Magic)", "Members now have the Defence level required to wear " + "" + "Akrisae's hood" + "" + " (after Ritual of the Mahjarrat and with level 70 Prayer and 70 Magic)."); + case 19: + return newstruct cs2func_script_978_struct(70, 21752, "Members: Akrisae's robe top" + "
" + " (after Ritual of the Mahjarrat and with level 70 Prayer and 70 Magic)", "Members now have the Defence level required to wear " + "" + "Akrisae's robe top" + "" + " (after Ritual of the Mahjarrat and with level 70 Prayer and 70 Magic)."); + case 20: + return newstruct cs2func_script_978_struct(70, 21760, "Members: Akrisae's robe skirt" + "
" + " (after Ritual of the Mahjarrat and with level 70 Prayer and 70 Magic)", "Members now have the Defence level required to wear " + "" + "Akrisae's robe skirt" + "" + " (after Ritual of the Mahjarrat and with level 70 Prayer and 70 Magic)."); + } + break; + case 10: + switch (arg1) { + case 0: + return newstruct cs2func_script_978_struct(1, 6153, "Members: Skeletal gloves", "Members can now wear " + "" + "skeletal gloves" + "" + "."); + case 1: + return newstruct cs2func_script_978_struct(1, 6147, "Members: Skeletal boots", "Members can now wear " + "" + "skeletal boots" + "" + "."); + case 2: + return newstruct cs2func_script_978_struct(1, 2890, "Members: Elemental equipment" + "
" + " (after Elemental Workshop I)", "Members can now use " + "" + "elemental equipment" + "" + " (after Elemental Workshop I)."); + case 3: + return newstruct cs2func_script_978_struct(1, 9733, "Members: Mind equipment" + "
" + " (after Elemental Workshop II)", "Members can now use " + "" + "mind equipment" + "" + " (after Elemental Workshop II)."); + case 4: + return newstruct cs2func_script_978_struct(10, 12964, "Combat hood" + "
" + " (with 20 Magic)", "You now have the Defence level required to wear " + "" + "combat hoods" + "" + ". (You also need level 20 Magic.)"); + case 5: + return newstruct cs2func_script_978_struct(10, 12971, "Combat robe top" + "
" + " (with 20 Magic)", "You now have the Defence level required to wear " + "" + "combat robe tops" + "" + ". (You also need level 20 Magic.)"); + case 6: + return newstruct cs2func_script_978_struct(10, 12978, "Combat robe bottom" + "
" + " (with 20 Magic)", "You now have the Defence level required to wear " + "" + "combat robe bottoms" + "" + ". (You also need level 20 Magic.)"); + case 7: + return newstruct cs2func_script_978_struct(10, 12887, "Druidic mage hood" + "
" + " (with 20 Magic)", "You now have the Defence level required to wear " + "" + "druidic mage hoods" + "" + ". (You also need level 20 Magic.)"); + case 8: + return newstruct cs2func_script_978_struct(10, 12894, "Druidic mage top" + "
" + " (with 20 Magic)", "You now have the Defence level required to wear " + "" + "druidic mage tops" + "" + ". (You also need level 20 Magic.)"); + case 9: + return newstruct cs2func_script_978_struct(10, 12901, "Druidic mage bottom" + "
" + " (with 20 Magic)", "You now have the Defence level required to wear " + "" + "druidic mage bottoms" + "" + ". (You also need level 20 Magic.)"); + case 10: + return newstruct cs2func_script_978_struct(20, 7400, "Members: Enchanted hat" + "
" + " (with 40 Magic)", "Members now have the Defence level required to wear " + "" + "enchanted hats" + "" + ". (They also need level 40 Magic.)"); + case 11: + return newstruct cs2func_script_978_struct(20, 7399, "Members: Enchanted robe top" + "
" + " (with 40 Magic)", "Members now have the Defence level required to wear " + "" + "enchanted robe tops" + "" + ". (They also need level 40 Magic.)"); + case 12: + return newstruct cs2func_script_978_struct(20, 7398, "Members: Enchanted robe" + "
" + " (with 40 Magic)", "Members now have the Defence level required to wear " + "" + "enchanted robes" + "" + ". (They also need level 40 Magic.)"); + case 13: + return newstruct cs2func_script_978_struct(20, 4089, "Members: Mystic hat" + "
" + " (with 40 Magic)", "Members now have the Defence level required to wear " + "" + "mystic hats" + "" + ". (They also need level 40 Magic.)"); + case 14: + return newstruct cs2func_script_978_struct(20, 4091, "Members: Mystic robe top" + "
" + " (with 40 Magic)", "Members now have the Defence level required to wear " + "" + "mystic robe tops" + "" + ". (They also need level 40 Magic.)"); + case 15: + return newstruct cs2func_script_978_struct(20, 4093, "Members: Mystic robe" + "
" + " (with 40 Magic)", "Members now have the Defence level required to wear " + "" + "mystic robes" + "" + ". (They also need level 40 Magic.)"); + case 16: + return newstruct cs2func_script_978_struct(20, 4095, "Members: Mystic gloves" + "
" + " (with 40 Magic)", "Members now have the Defence level required to wear " + "" + "mystic gloves" + "" + ". (They also need level 40 Magic.)"); + case 17: + return newstruct cs2func_script_978_struct(20, 4097, "Members: Mystic boots" + "
" + " (with 40 Magic)", "Members now have the Defence level required to wear " + "" + "mystic boots" + "" + ". (They also need level 40 Magic.)"); + case 18: + return newstruct cs2func_script_978_struct(20, 14499, "Members: Dagon'hai hat" + "
" + " (with 40 Magic)", "Members now have the Defence level required to wear " + "" + "Dagon'hai hats" + "" + ". (They also need level 40 Magic.)"); + case 19: + return newstruct cs2func_script_978_struct(20, 14497, "Members: Dagon'hai robe top" + "
" + " (with 40 Magic)", "Members now have the Defence level required to wear " + "" + "Dagon'hai robe tops" + "" + ". (They also need level 40 Magic.)"); + case 20: + return newstruct cs2func_script_978_struct(20, 14501, "Members: Dagon'hai robe bottom" + "
" + " (with 40 Magic)", "Members now have the Defence level required to wear " + "" + "Dagon'hai robe bottoms" + "" + ". (They also need level 40 Magic.)"); + case 21: + return newstruct cs2func_script_978_struct(20, 13938, "Members: Corrupt Zuriel's hood" + "
" + " (with 20 Magic)", "Members now have the Defence level required to wear " + "" + "corrupt Zuriel's hood" + "" + ". (They also need level 20 Magic.)"); + case 22: + return newstruct cs2func_script_978_struct(20, 13932, "Members: Corrupt Zuriel's robe top" + "
" + " (with 20 Magic)", "Members now have the Defence level required to wear " + "" + "corrupt Zuriel's robe top" + "" + ". (They also need level 20 Magic.)"); + case 23: + return newstruct cs2func_script_978_struct(20, 13935, "Members: Corrupt Zuriel's robe bottom" + "
" + " (with 20 Magic)", "Members now have the Defence level required to wear " + "" + "corrupt Zuriel's robe bottom" + "" + ". (They also need level 20 Magic.)"); + case 24: + return newstruct cs2func_script_978_struct(20, 19323, "Members: Dragon staff" + "
" + " (with 40 Magic, 40 Attack and 60 Prayer)", "Members now have the Defence level required to wield " + "" + "dragon staves" + "" + ". (They also need level 40 Magic, level 40 Attack and level 60 Prayer.)"); + case 25: + return newstruct cs2func_script_978_struct(20, 19325, "Members: Penguin staff" + "
" + " (with 40 Magic, 40 Attack and 60 Prayer)", "Members now have the Defence level required to wield " + "" + "penguin staves" + "" + ". (They also need level 40 Magic, level 40 Attack and level 60 Prayer.)"); + case 26: + return newstruct cs2func_script_978_struct(20, 19327, "Members: Bat staff" + "
" + " (with 40 Magic, 40 Attack and 60 Prayer)", "Members now have the Defence level required to wield " + "" + "bat staves" + "" + ". (They also need level 40 Magic, level 40 Attack and level 60 Prayer.)"); + case 27: + return newstruct cs2func_script_978_struct(20, 19329, "Members: Wolf staff" + "
" + " (with 40 Magic, 40 Attack and 60 Prayer)", "Members now have the Defence level required to wield " + "" + "wolf staves" + "" + ". (They also need level 40 Magic, level 40 Attack and level 60 Prayer.)"); + case 28: + return newstruct cs2func_script_978_struct(20, 19331, "Members: Cat staff" + "
" + " (with 40 Magic, 40 Attack and 60 Prayer)", "Members now have the Defence level required to wield " + "" + "cat staves" + "" + ". (They also need level 40 Magic, level 40 Attack and level 60 Prayer.)"); + case 29: + return newstruct cs2func_script_978_struct(20, 21509, "Members: Necromancer hood" + "
" + " (with 40 Magic)", "Members now have the Defence level required to wear " + "" + "Necromancer hoods" + "" + ". (They also need level 40 Magic.)"); + case 30: + return newstruct cs2func_script_978_struct(20, 21508, "Members: Necromancer robe" + "
" + " (with 40 Magic)", "Members now have the Defence level required to wear " + "" + "Necromancer robes" + "" + ". (They also need level 40 Magic.)"); + case 31: + return newstruct cs2func_script_978_struct(20, 21510, "Members: Necromancer legs" + "
" + " (with 40 Magic)", "Members now have the Defence level required to wear " + "" + "Necromancer legs" + "" + ". (They also need level 40 Magic.)"); + case 32: + return newstruct cs2func_script_978_struct(25, 6918, "Members: Infinity hat" + "
" + " (with 50 Magic)", "Members now have the Defence level required to wear " + "" + "infinity hats" + "" + ". (They also need level 50 Magic.)"); + case 33: + return newstruct cs2func_script_978_struct(25, 6916, "Members: Infinity top" + "
" + " (with 50 Magic)", "Members now have the Defence level required to wear " + "" + "infinity tops" + "" + ". (They also need level 50 Magic.)"); + case 34: + return newstruct cs2func_script_978_struct(25, 6924, "Members: Infinity bottom" + "
" + " (with 50 Magic)", "Members now have the Defence level required to wear " + "" + "infinity robe bottoms" + "" + ". (They also need level 50 Magic.)"); + case 35: + return newstruct cs2func_script_978_struct(25, 6922, "Members: Infinity gloves" + "
" + " (with 50 Magic)", "Members now have the Defence level required to wear " + "" + "infinity gloves" + "" + ". (They also need level 50 Magic.)"); + case 36: + return newstruct cs2func_script_978_struct(25, 6920, "Members: Infinity boots" + "
" + " (with 50 Magic)", "Members now have the Defence level required to wear " + "" + "infinity boots" + "" + ". (They also need level 50 Magic.)"); + case 37: + return newstruct cs2func_script_978_struct(30, 10342, "Members: Third-Age mage hat" + "
" + " (with 65 Magic)", "Members now have the Defence level required to wear " + "" + "Third-Age mage hats" + "" + ". (They also need level 65 Magic.)"); + case 38: + return newstruct cs2func_script_978_struct(30, 10338, "Members: Third-Age robe top" + "
" + " (with 65 Magic)", "Members now have the Defence level required to wear " + "" + "Third-Age robe tops" + "" + ". (They also need level 65 Magic.)"); + case 39: + return newstruct cs2func_script_978_struct(30, 10340, "Members: Third-Age robe" + "
" + " (with 65 Magic)", "Members now have the Defence level required to wear " + "" + "Third-Age robes" + "" + ". (They also need level 65 Magic.)"); + case 40: + return newstruct cs2func_script_978_struct(30, 10344, "Members: Third-Age amulet" + "
" + " (with 65 Magic)", "Members now have the Defence level required to wear " + "" + "Third-Age amulets" + "" + ". (They also need level 65 Magic.)"); + case 41: + return newstruct cs2func_script_978_struct(33, 18695, "Members: Body equipment (after Elemental Workshop III and with 33 Smithing)", "Members now have the Defence level required to use " + "" + "body equipment" + "" + " (after Elemental Workshop III and with level 33 Smithing)."); + case 42: + return newstruct cs2func_script_978_struct(40, 3385, "Members: Splitbark helm" + "
" + " (with 40 Magic)", "Members now have the Defence level required to wear " + "" + "splitbark helms" + "" + ". (They also need level 40 Magic.)"); + case 43: + return newstruct cs2func_script_978_struct(40, 3387, "Members: Splitbark body" + "
" + " (with 40 Magic)", "Members now have the Defence level required to wear " + "" + "splitbark body" + "" + ". (They also need level 40 Magic.)"); + case 44: + return newstruct cs2func_script_978_struct(40, 3389, "Members: Splitbark legs" + "
" + " (with 40 Magic)", "Members now have the Defence level required to wear " + "" + "splitbark legs" + "" + ". (They also need level 40 Magic.)"); + case 45: + return newstruct cs2func_script_978_struct(40, 3391, "Members: Splitbark gauntlets" + "
" + " (with 40 Magic)", "Members now have the Defence level required to wear " + "" + "splitbark gauntlets" + "" + ". (They also need level 40 Magic.)"); + case 46: + return newstruct cs2func_script_978_struct(40, 3393, "Members: Splitbark boots" + "
" + " (with 40 Magic)", "Members now have the Defence level required to wear " + "" + "splitbark boots" + "" + ". (They also need level 40 Magic.)"); + case 47: + return newstruct cs2func_script_978_struct(40, 6137, "Members: Skeletal helm" + "
" + " (after Fremennik Trials, with 40 Magic)", "Members now have the Defence level required to wear " + "" + "skeletal helms" + "" + " (after Fremennik Trials and with level 40 Magic)."); + case 48: + return newstruct cs2func_script_978_struct(40, 6139, "Members: Skeletal top" + "
" + " (after Fremennik Trials, with 40 Magic)", "Members now have the Defence level required to wear " + "" + "skeletal tops" + "" + " (after Fremennik Trials and with level 40 Magic)."); + case 49: + return newstruct cs2func_script_978_struct(40, 6141, "Members: Skeletal bottoms" + "
" + " (after Fremennik Trials, with 40 Magic)", "Members now have the Defence level required to wear " + "" + "skeletal bottoms" + "" + " (after Fremennik Trials and with level 40 Magic)."); + case 50: + return newstruct cs2func_script_978_struct(40, 9096, "Members: Lunar helm" + "
" + " (after Lunar Diplomacy, with 65 Magic)", "Members now have the Defence level required to wear " + "" + "lunar helms" + "" + " (after Lunar Diplomacy and with level 65 Magic)."); + case 51: + return newstruct cs2func_script_978_struct(40, 9097, "Members: Lunar torso" + "
" + " (after Lunar Diplomacy, with 65 Magic)", "Members now have the Defence level required to wear " + "" + "lunar torsos" + "" + " (after Lunar Diplomacy and with level 65 Magic)."); + case 52: + return newstruct cs2func_script_978_struct(40, 9099, "Members: Lunar gloves" + "
" + " (after Lunar Diplomacy, with 65 Magic)", "Members now have the Defence level required to wear " + "" + "lunar gloves" + "" + " (after Lunar Diplomacy and with level 65 Magic)."); + case 53: + return newstruct cs2func_script_978_struct(40, 9098, "Members: Lunar legs" + "
" + " (after Lunar Diplomacy, with 65 Magic)", "Members now have the Defence level required to wear " + "" + "lunar legs" + "" + " (after Lunar Diplomacy and with level 65 Magic)."); + case 54: + return newstruct cs2func_script_978_struct(40, 9100, "Members: Lunar boots" + "
" + " (after Lunar Diplomacy, with 65 Magic)", "Members now have the Defence level required to wear " + "" + "lunar boots" + "" + " (after Lunar Diplomacy and with level 65 Magic)."); + case 55: + return newstruct cs2func_script_978_struct(40, 9101, "Members: Lunar cape" + "
" + " (after Lunar Diplomacy, with 65 Magic)", "Members now have the Defence level required to wear " + "" + "lunar capes" + "" + " (after Lunar Diplomacy and with level 65 Magic)."); + case 56: + return newstruct cs2func_script_978_struct(40, 14116, "Members: Sacred clay hat" + "
" + " (with 40 Magic)", "Members now have the Defence level required to wear " + "" + "sacred clay hats" + "" + ". (They also need level 40 Magic.)"); + case 57: + return newstruct cs2func_script_978_struct(40, 14114, "Members: Sacred clay robe top" + "
" + " (with 40 Magic)", "Members now have the Defence level required to wear " + "" + "sacred clay robe tops" + "" + ". (They also need level 40 Magic.)"); + case 58: + return newstruct cs2func_script_978_struct(40, 14115, "Members: Sacred clay robe bottom" + "
" + " (with 40 Magic)", "Members now have the Defence level required to wear " + "" + "sacred clay robe bottoms" + "" + ". (They also need level 40 Magic.)"); + case 59: + return newstruct cs2func_script_978_struct(40, 20436, "Members: Cosmic shield" + "
" + " (after Elemental Workshop IV)", "Members now have the Defence level required to wield " + "" + "cosmic shields" + "" + " (after Elemental Workshop IV)."); + case 60: + return newstruct cs2func_script_978_struct(40, 20440, "Members: Cosmic helmet" + "
" + " (after Elemental Workshop IV)", "Members now have the Defence level required to wear " + "" + "cosmic helmets" + "" + " (after Elemental Workshop IV)."); + case 61: + return newstruct cs2func_script_978_struct(40, 20444, "Members: Cosmic body" + "
" + " (after Elemental Workshop IV)", "Members now have the Defence level required to wear " + "" + "cosmic bodies" + "" + " (after Elemental Workshop IV)."); + case 62: + return newstruct cs2func_script_978_struct(40, 20464, "Members: Cosmic gloves" + "
" + " (after Elemental Workshop IV)", "Members now have the Defence level required to wear " + "" + "cosmic gloves" + "" + " (after Elemental Workshop IV)."); + case 63: + return newstruct cs2func_script_978_struct(40, 20454, "Members: Cosmic boots" + "
" + " (after Elemental Workshop IV)", "Members now have the Defence level required to wear " + "" + "cosmic boots" + "" + " (after Elemental Workshop IV)."); + case 64: + return newstruct cs2func_script_978_struct(45, 3755, "Members: Farseer helm" + "
" + " (after Fremennik Trials)", "Members can now wear " + "" + "farseer helms" + "" + " (after Fremennik Trials)."); + case 65: + return newstruct cs2func_script_978_struct(50, 12866, "Members: Battle hood" + "
" + " (with 60 Magic)", "Members now have the Defence level required to wear " + "" + "battle hoods" + "" + ". (They also need level 60 Magic.)"); + case 66: + return newstruct cs2func_script_978_struct(50, 12873, "Members: Battle robe top" + "
" + " (with 60 Magic)", "Members now have the Defence level required to wear " + "" + "battle robe tops" + "" + ". (They also need level 60 Magic.)"); + case 67: + return newstruct cs2func_script_978_struct(50, 12880, "Members: Battle robe bottom" + "
" + " (with 60 Magic)", "Members now have the Defence level required to wear " + "" + "battle robe bottoms" + "" + ". (They also need level 60 Magic.)"); + case 68: + return newstruct cs2func_script_978_struct(50, 20438, "Members: Chaos shield" + "
" + " (after Elemental Workshop IV)", "Members now have the Defence level required to wield " + "" + "chaos shields" + "" + " (after Elemental Workshop IV)."); + case 69: + return newstruct cs2func_script_978_struct(50, 20442, "Members: Chaos helmet" + "
" + " (after Elemental Workshop IV)", "Members now have the Defence level required to wear " + "" + "chaos helmets" + "" + " (after Elemental Workshop IV)."); + case 70: + return newstruct cs2func_script_978_struct(50, 20446, "Members: Chaos body" + "
" + " (after Elemental Workshop IV)", "Members now have the Defence level required to wear " + "" + "chaos bodies" + "" + " (after Elemental Workshop IV)."); + case 71: + return newstruct cs2func_script_978_struct(50, 20466, "Members: Chaos gloves" + "
" + " (after Elemental Workshop IV)", "Members now have the Defence level required to wear " + "" + "chaos gloves" + "" + " (after Elemental Workshop IV)."); + case 72: + return newstruct cs2func_script_978_struct(50, 20456, "Members: Chaos boots" + "
" + " (after Elemental Workshop IV)", "Members now have the Defence level required to wear " + "" + "chaos boots" + "" + " (after Elemental Workshop IV)."); + case 73: + return newstruct cs2func_script_978_struct(78, 13864, "Members: Zuriel's hood" + "
" + " (with 78 Magic)", "Members now have the Defence level required to wear " + "" + "Zuriel's hood" + "" + ". (They also need level 78 Magic.)"); + case 74: + return newstruct cs2func_script_978_struct(78, 13858, "Members: Zuriel's robe top" + "
" + " (with 78 Magic)", "Members now have the Defence level required to wear " + "" + "Zuriel's robe top" + "" + ". (They also need level 78 Magic.)"); + case 75: + return newstruct cs2func_script_978_struct(78, 13861, "Members: Zuriel's robe bottom" + "
" + " (with 78 Magic)", "Members now have the Defence level required to wear " + "" + "Zuriel's robe bottom" + "" + ". (They also need level 78 Magic.)"); + case 76: + return newstruct cs2func_script_978_struct(80, 20159, "Members: Virtus mask" + "
" + " (with 80 Magic and Constitution)", "Members can now wear " + "" + "virtus masks" + "" + ". (They also need level 80 Magic and Constitution.)"); + case 77: + return newstruct cs2func_script_978_struct(80, 20163, "Members: Virtus robe top" + "
" + " (with 80 Magic and Constitution)", "Members can now wear " + "" + "virtus robe tops" + "" + ". (They also need level 80 Magic and Constitution.)"); + case 78: + return newstruct cs2func_script_978_struct(80, 20167, "Members: Virtus robe legs" + "
" + " (with 80 Magic and Constitution)", "Members can now wear " + "" + "virtus robe legs" + "" + ". (They also need level 80 Magic and Constitution.)"); + } + break; + case 11: + switch (arg1) { + case 0: + return newstruct cs2func_script_978_struct(1, 1540, "Anti-dragonbreath shield", "You can now wield " + "" + "anti-dragonbreath shields" + "" + "."); + case 1: + return newstruct cs2func_script_978_struct(1, 6149, "Members: Spined gloves", "Members can now wear " + "" + "spined gloves" + "" + "."); + case 2: + return newstruct cs2func_script_978_struct(1, 6143, "Members: Spined boots", "Members can now wear " + "" + "spined boots" + "" + "."); + case 3: + return newstruct cs2func_script_978_struct(1, 6151, "Members: Rock-shell gloves", "Members can now wear " + "" + "rock-shell gloves" + "" + "."); + case 4: + return newstruct cs2func_script_978_struct(1, 6145, "Members: Rock-shell boots", "Members can now wear " + "" + "rock-shell boots" + "" + "."); + case 5: + return newstruct cs2func_script_978_struct(1, 75, "Members: Khazard armour", "Members can now wear " + "" + "Khazard armour" + "" + "."); + case 6: + return newstruct cs2func_script_978_struct(5, 4551, "Members: Spiny helmet", "Members now have the Defence level required to wear " + "" + "spiny helmets" + "" + " to ward off wall beast attacks."); + case 7: + return newstruct cs2func_script_978_struct(5, 4071, "Members: Basic decorative helm", "Members can now wear " + "" + "basic decorative helms" + "" + "."); + case 8: + return newstruct cs2func_script_978_struct(5, 4069, "Members: Basic decorative armour", "Members can now wear " + "" + "basic decorative platebodies" + "" + "."); + case 9: + return newstruct cs2func_script_978_struct(5, 4070, "Members: Basic decorative armour", "Members can now wear " + "" + "basic decorative platelegs" + "" + "."); + case 10: + return newstruct cs2func_script_978_struct(5, 4072, "Members: Basic decorative shield", "Members can now wear " + "" + "basic decorative shields" + "" + "."); + case 11: + return newstruct cs2func_script_978_struct(10, 15490, "Members: Focus sight" + "
" + " (with 20 Ranged)", "Members can now wear " + "" + "focus sights" + "" + "."); + case 12: + return newstruct cs2func_script_978_struct(10, 15488, "Members: Hexcrest" + "
" + " (with 20 Magic)", "Members can now wear " + "" + "hexcrests" + "" + "."); + case 13: + return newstruct cs2func_script_978_struct(10, 8921, "Members: Black mask" + "
" + " (with 20 Strength)", "Members can now wear " + "" + "black masks" + "" + "."); + case 14: + return newstruct cs2func_script_978_struct(10, 13263, "Members: Slayer helmet" + "
" + " (after Smoking Kills)", "Members can now wear " + "" + "slayer helmets" + "" + " (after Smoking Kills)."); + case 15: + return newstruct cs2func_script_978_struct(10, 15492, "Members: Full Slayer helmet" + "
" + " (after Smoking Kills with 20 Ranged, Magic and Strength)", "Members can now wear " + "" + "full slayer helmets" + "" + " (after Smoking Kills with 20 Ranged, Magic and Strength)."); + case 16: + return newstruct cs2func_script_978_struct(20, 1133, "Studded body" + "
" + " (with 20 Ranged)", "You now have the Defence level required to wear " + "" + "studded bodies" + "" + ". (You also need level 20 Ranged.)"); + case 17: + return newstruct cs2func_script_978_struct(20, 10822, "Members: Yak-hide bodies", "Members can now wear " + "" + "yak-hide bodies" + "" + "."); + case 18: + return newstruct cs2func_script_978_struct(20, 10824, "Members: Yak-hide legs", "Members can now wear " + "" + "yak-hide legs" + "" + "."); + case 19: + return newstruct cs2func_script_978_struct(20, 5574, "Members: Initiate sallet" + "
" + " (after Recruitment Drive, with 10 Prayer)", "Members now have the Defence level required to wear " + "" + "initiate sallets" + "" + " (after Recruitment Drive and with level 10 Prayer)."); + case 20: + return newstruct cs2func_script_978_struct(20, 5575, "Members: Initiate hauberk" + "
" + " (after Recruitment Drive, with 10 Prayer)", "Members now have the Defence level required to wear " + "" + "initiate hauberks" + "" + " (after Recruitment Drive and with level 10 Prayer)."); + case 21: + return newstruct cs2func_script_978_struct(20, 5576, "Members: Initiate cuisse" + "
" + " (after Recruitment Drive, with 10 Prayer)", "Members now have the Defence level required to wear " + "" + "initiate cuisses" + "" + " (after Recruitment Drive and with level 10 Prayer)."); + case 22: + return newstruct cs2func_script_978_struct(20, 4156, "Members: Mirror shield" + "
" + " (with 25 Slayer)", "Members now have the Defence level required to wield " + "" + "mirror shields" + "" + " to protect against cockatrices and basilisks. (They also need level 25 Slayer.)"); + case 23: + return newstruct cs2func_script_978_struct(20, 4506, "Members: Detailed decorative helm", "Members can now wear " + "" + "detailed decorative helms" + "" + "."); + case 24: + return newstruct cs2func_script_978_struct(20, 4504, "Members: Detailed decorative armour", "Members can now wear " + "" + "detailed decorative platebodies" + "" + "."); + case 25: + return newstruct cs2func_script_978_struct(20, 4505, "Members: Detailed decorative armour", "Members can now wear " + "" + "detailed decorative platelegs" + "" + "."); + case 26: + return newstruct cs2func_script_978_struct(20, 4507, "Members: Detailed decorative shield", "Members can now wear " + "" + "detailed decorative shields" + "" + "."); + case 27: + return newstruct cs2func_script_978_struct(20, 13950, "Members: Corrupt Morrigan's coif" + "
" + " (with 20 Ranged)", "Members now have the Defence level required to wield " + "" + "corrupt Morrigan's coif" + "" + ". (They also need level 20 Ranged.)"); + case 28: + return newstruct cs2func_script_978_struct(20, 13944, "Members: Corrupt Morrigan's leather body" + "
" + " (with 20 Ranged)", "Members now have the Defence level required to wield " + "" + "corrupt Morrigan's leather body" + "" + ". (They also need level 20 Ranged.)"); + case 29: + return newstruct cs2func_script_978_struct(20, 13947, "Members: Corrupt Morrigan's leather chaps" + "
" + " (with 20 Ranged)", "Members now have the Defence level required to wield " + "" + "corrupt Morrigan's leather chaps" + "" + ". (They also need level 20 Ranged.)"); + case 30: + return newstruct cs2func_script_978_struct(20, 13920, "Members: Corrupt Statius's full helm", "Members now have the Defence level required to wear " + "" + "corrupt Statius's full helm" + "" + "."); + case 31: + return newstruct cs2func_script_978_struct(20, 13908, "Members: Corrupt Statius's platebody", "Members now have the Defence level required to wear " + "" + "corrupt Statius's platebody" + "" + "."); + case 32: + return newstruct cs2func_script_978_struct(20, 13911, "Members: Corrupt Vesta's chainbody", "Members now have the Defence level required to wear " + "" + "corrupt Vesta's chainbody" + "" + "."); + case 33: + return newstruct cs2func_script_978_struct(20, 13914, "Members: Corrupt Statius's platelegs", "Members now have the Defence level required to wear " + "" + "corrupt Statius's platelegs" + "" + "."); + case 34: + return newstruct cs2func_script_978_struct(20, 13917, "Members: Corrupt Vesta's plateskirt", "Members now have the Defence level required to wear " + "" + "corrupt Vesta's plateskirt" + "" + "."); + case 35: + return newstruct cs2func_script_978_struct(25, 10826, "Members: Fremennik round shield", "Members can now wield Fremennik round shields" + "" + "."); + case 36: + return newstruct cs2func_script_978_struct(25, 10954, "Members: Frog-leather body" + "
" + " (with 25 Ranged)", "Members now have the Defence level required to wear " + "" + "frog-leather bodies" + "" + ". (They also need level 25 Ranged.)"); + case 37: + return newstruct cs2func_script_978_struct(25, 10956, "Members: Frog-leather chaps" + "
" + " (with 25 Ranged)", "Members now have the Defence level required to wear " + "" + "frog-leather chaps" + "" + ". (They also need level 25 Ranged.)"); + case 38: + return newstruct cs2func_script_978_struct(25, 10958, "Members: Frog-leather boots" + "
" + " (with 25 Ranged)", "Members now have the Defence level required to wear " + "" + "frog-leather boots" + "" + ". (They also need level 25 Ranged.)."); + case 39: + return newstruct cs2func_script_978_struct(30, 3758, "Members: Fremennik shield", "Members can now wield " + "" + "Fremennik shields" + "" + "."); + case 40: + return newstruct cs2func_script_978_struct(30, 3748, "Members: Fremennik helm", "Members can now wear " + "" + "Fremennik helms" + "" + "."); + case 41: + return newstruct cs2func_script_978_struct(30, 4567, "Members: Gold helmet", "Members can now wear " + "" + "gold helmets" + "" + "."); + case 42: + return newstruct cs2func_script_978_struct(30, 7917, "Members: Ram skull helm (after Rag and Bone Man)", "Members can now wear " + "" + "ram skull helms" + "" + " (after Rag and Bone Man)."); + case 43: + return newstruct cs2func_script_978_struct(30, 9672, "Members: Proselyte sallet" + "
" + " (after Slug Menace and with 20 Prayer)", "Members now have the Defence level required to wear " + "" + "proselyte sallets" + "" + " (after Slug Menace, with level 20 Prayer)."); + case 44: + return newstruct cs2func_script_978_struct(30, 9674, "Members: Proselyte hauberk" + "
" + " (after Slug Menace and with 20 Prayer)", "Members now have the Defence level required to wear " + "" + "proselyte hauberks" + "" + " (after Slug Menace, with level 20 Prayer)."); + case 45: + return newstruct cs2func_script_978_struct(30, 9678, "Members: Proselyte tasset" + "
" + " (after Slug Menace and with 20 Prayer)", "Members now have the Defence level required to wear " + "" + "proselyte tassets" + "" + " (after Slug Menace, with level 20 Prayer)."); + case 46: + return newstruct cs2func_script_978_struct(30, 9676, "Members: Proselyte cuisse" + "
" + " (after Slug Menace and with 20 Prayer)", "Members now have the Defence level required to wear " + "" + "proselyte cuisses" + "" + " (after Slug Menace, with level 20 Prayer)."); + case 47: + return newstruct cs2func_script_978_struct(30, 4511, "Members: Intricate decorative helm", "Members can now wear " + "" + "intricate decorative helms" + "" + "."); + case 48: + return newstruct cs2func_script_978_struct(30, 4509, "Members: Intricate decorative armour", "Members can now wear " + "" + "intricate decorative platebodies" + "" + "."); + case 49: + return newstruct cs2func_script_978_struct(30, 4510, "Members: Intricate decorative armour", "Members can now wear " + "" + "intricate decorative platelegs" + "" + "."); + case 50: + return newstruct cs2func_script_978_struct(30, 4512, "Members: Intricate decorative shield", "Members can now wear " + "" + "intricate decorative shields" + "" + "."); + case 51: + return newstruct cs2func_script_978_struct(30, 6326, "Members: Snakeskin bandana" + "
" + " (with 30 Ranged)", "Members now have the Defence level required to wear " + "" + "snakeskin bandanas" + "" + ". (They also need level 30 Ranged.)"); + case 52: + return newstruct cs2func_script_978_struct(30, 6322, "Members: Snakeskin body" + "
" + " (with 30 Ranged)", "Members now have the Defence level required to wear " + "" + "snakeskin bodies" + "" + ". (They also need level 30 Ranged.)"); + case 53: + return newstruct cs2func_script_978_struct(30, 6324, "Members: Snakeskin chaps" + "
" + " (with 30 Ranged)", "Members now have the Defence level required to wear " + "" + "snakeskin chaps" + "" + ". (They also need level 30 Ranged.)"); + case 54: + return newstruct cs2func_script_978_struct(30, 6330, "Members: Snakeskin vambraces" + "
" + " (with 30 Ranged)", "Members now have the Defence level required to wear " + "" + "snakeskin vambraces" + "" + ". (They also need level 30 Ranged.)"); + case 55: + return newstruct cs2func_script_978_struct(30, 6328, "Members: Snakeskin boots" + "
" + " (with 30 Ranged)", "Members now have the Defence level required to wear " + "" + "snakeskin boots" + "" + ". (They also need level 30 Ranged.)"); + case 56: + return newstruct cs2func_script_978_struct(35, 14936, "Members: Agile top" + "
" + " (with 35 Constitution)", "Members now have the Defence level required to wear " + "" + "Agile tops" + "" + ". (They also need level 35 Constitution.)"); + case 57: + return newstruct cs2func_script_978_struct(35, 14938, "Members: Agile legs" + "
" + " (with 35 Constitution)", "Members now have the Defence level required to wear " + "" + "Agile legs" + "" + ". (They also need level 35 Constitution.)"); + case 58: + return newstruct cs2func_script_978_struct(40, 1135, "Green dragonhide body" + "
" + " (after Dragon Slayer and with 40 Ranged)", "You now have the Defence level required to wear " + "" + "green dragonhide bodies" + "" + ". (You also need to have completed Dragon Slayer and have level 40 Ranged.)"); + case 59: + return newstruct cs2func_script_978_struct(40, 12936, "Green dragonhide coif" + "
" + " (with 40 Ranged)", "You now have the Defence level required to wear " + "" + "green dragonhide coifs" + "" + ". (You also need level 40 Ranged.)"); + case 60: + return newstruct cs2func_script_978_struct(40, 2499, "Members: Blue dragonhide body" + "
" + " (with 50 Ranged)", "Members now have the Defence level required to wear " + "" + "blue dragonhide bodies" + "" + ". (They also need level 50 Ranged.)"); + case 61: + return newstruct cs2func_script_978_struct(40, 12943, "Members: Blue dragonhide coif" + "
" + " (with 50 Ranged)", "Members now have the Defence level required to wear " + "" + "blue dragonhide coifs" + "" + ". (They also need level 50 Ranged.)"); + case 62: + return newstruct cs2func_script_978_struct(40, 2501, "Members: Red dragonhide body" + "
" + " (with 60 Ranged)", "Members now have the Defence level required to wear " + "" + "red dragonhide bodies" + "" + ". (They also need level 60 Ranged.)"); + case 63: + return newstruct cs2func_script_978_struct(40, 12950, "Members: Red dragonhide coif" + "
" + " (with 60 Ranged)", "Members now have the Defence level required to wear " + "" + "red dragonhide coifs" + "" + ". (They also need level 60 Ranged.)"); + case 64: + return newstruct cs2func_script_978_struct(40, 2503, "Members: Black dragonhide body" + "
" + " (with 70 Ranged)", "Members now have the Defence level required to wear " + "" + "black dragonhide bodies" + "" + ". (They also need level 70 Ranged.)"); + case 65: + return newstruct cs2func_script_978_struct(40, 12957, "Members: Black dragonhide coif" + "
" + " (with 70 Ranged)", "Members now have the Defence level required to wear " + "" + "black dragonhide coifs" + "" + ". (They also need level 70 Ranged.)"); + case 66: + return newstruct cs2func_script_978_struct(40, 10374, "Members: Blessed dragonhide coif" + "
" + " (with 70 Ranged)", "Members now have the Defence level required to wear " + "" + "blessed dragonhide coifs" + "" + ". (They also need level 70 Ranged.)"); + case 67: + return newstruct cs2func_script_978_struct(40, 6131, "Members: Spined helm" + "
" + " (after Fremennik Trials and with 40 Ranged)", "Members now have the Defence level required to wear " + "" + "spined helms" + "" + " (after Fremennik Trials and with level 40 Ranged)."); + case 68: + return newstruct cs2func_script_978_struct(40, 6133, "Members: Spined body" + "
" + " (after Fremennik Trials and with 40 Ranged)", "Members now have the Defence level required to wear " + "" + "spined bodies" + "" + " (after Fremennik Trials and with level 40 Ranged)."); + case 69: + return newstruct cs2func_script_978_struct(40, 6135, "Members: Spined chaps" + "
" + " (after Fremennik Trials and with 40 Ranged)", "Members now have the Defence level required to wear " + "" + "spined chaps" + "" + " (after Fremennik Trials and with level 40 Ranged)."); + case 70: + return newstruct cs2func_script_978_struct(40, 6128, "Members: Rock-shell helm" + "
" + " (after Fremennik Trials)", "Members now have the Defence level required to wear " + "" + "rock-shell helms" + "" + " (after Fremennik Trials)."); + case 71: + return newstruct cs2func_script_978_struct(40, 6129, "Members: Rock-shell plate" + "
" + " (after Fremennik Trials)", "Members now have the Defence level required to wear " + "" + "rock-shell plates" + "" + " (after Fremennik Trials)."); + case 72: + return newstruct cs2func_script_978_struct(40, 6130, "Members: Rock-shell legs" + "
" + " (after Fremennik Trials)", "Members now have the Defence level required to wear " + "" + "rock-shell legs" + "" + " (after Fremennik Trials)."); + case 73: + return newstruct cs2func_script_978_struct(40, 10551, "Members: Fighter torso", "Members can now wear " + "" + "fighter torsos" + "" + "."); + case 74: + return newstruct cs2func_script_978_struct(40, 10553, "Members: Penance gloves", "Members can now wear " + "" + "penance gloves" + "" + "."); + case 75: + return newstruct cs2func_script_978_struct(40, 10555, "Members: Penance skirt", "Members can now wear " + "" + "penance skirts" + "" + "."); + case 76: + return newstruct cs2func_script_978_struct(40, 10552, "Members: Runner boots", "Members can now wear " + "" + "runner boots" + "" + "."); + case 77: + return newstruct cs2func_script_978_struct(40, 10547, "Members: Healer hat", "Members can now wear " + "" + "healer hats" + "" + "."); + case 78: + return newstruct cs2func_script_978_struct(40, 10548, "Members: Fighter hat", "Members can now wear " + "" + "fighter hats" + "" + "."); + case 79: + return newstruct cs2func_script_978_struct(40, 10550, "Members: Ranger hat", "Members can now wear " + "" + "ranger hats" + "" + "."); + case 80: + return newstruct cs2func_script_978_struct(40, 10549, "Members: Runner hat", "Members can now wear " + "" + "runner hats" + "" + "."); + case 81: + return newstruct cs2func_script_978_struct(40, 13734, "Members: Spirit shield" + "
" + " (after Summer's End and with 55 Prayer)", "Members now have the Defence level required to wield " + "" + "spirit shields" + "" + " (after Summer's End, with level 55 Prayer)."); + case 82: + return newstruct cs2func_script_978_struct(40, 14096, "Members: Sacred clay helmet", "Members now have the Defence level required to wear " + "" + "sacred clay helmets" + "" + "."); + case 83: + return newstruct cs2func_script_978_struct(40, 14094, "Members: Sacred clay platebody", "Members now have the Defence level required to wear " + "" + "sacred clay platebodies" + "" + "."); + case 84: + return newstruct cs2func_script_978_struct(40, 14095, "Members: Sacred clay platelegs", "Members now have the Defence level required to wear " + "" + "sacred clay platelegs" + "" + "."); + case 85: + return newstruct cs2func_script_978_struct(40, 14120, "Members: Sacred clay coif" + "
" + " (with 40 Ranged)", "Members now have the Defence level required to wear " + "" + "sacred clay coifs" + "" + ". (They also need level 40 Ranged.)"); + case 86: + return newstruct cs2func_script_978_struct(40, 14118, "Members: Sacred clay body" + "
" + " (with 40 Ranged)", "Members now have the Defence level required to wear " + "" + "sacred clay bodies" + "" + ". (They also need level 40 Ranged.)"); + case 87: + return newstruct cs2func_script_978_struct(40, 14119, "Members: Sacred clay chaps" + "
" + " (with 40 Ranged)", "Members now have the Defence level required to wear " + "" + "sacred clay chaps" + "" + ". (They also need level 40 Ranged.)"); + case 88: + return newstruct cs2func_script_978_struct(40, 18708, "Members: Profound decorative helm", "Members can now wear " + "" + "profound decorative helms" + "" + "."); + case 89: + return newstruct cs2func_script_978_struct(40, 18706, "Members: Profound decorative armour", "Members can now wear " + "" + "profound decorative platebodies" + "" + "."); + case 90: + return newstruct cs2func_script_978_struct(40, 18707, "Members: Profound decorative armour", "Members can now wear " + "" + "profound decorative platelegs" + "" + "."); + case 91: + return newstruct cs2func_script_978_struct(40, 18709, "Members: Profound decorative shield", "Members can now wear " + "" + "profound decorative shields" + "" + "."); + case 92: + return newstruct cs2func_script_978_struct(40, 18747, "Members: Faithful shield", "Members now have the Defence level required to wear " + "" + "faithful shields" + "" + "."); + case 93: + return newstruct cs2func_script_978_struct(42, 11665, "Members: Void melee helm", "Members now have the Defence level required to wear " + "" + "Void melee helms" + "" + "."); + case 94: + return newstruct cs2func_script_978_struct(42, 11664, "Members: Void ranger helm", "Members now have the Defence level required to wear " + "" + "Void ranger helms" + "" + "."); + case 95: + return newstruct cs2func_script_978_struct(42, 11663, "Members: Void mage helm", "Members now have the Defence level required to wear " + "" + "Void mage helms" + "" + "."); + case 96: + return newstruct cs2func_script_978_struct(42, 8839, "Members: Void knight top", "Members now have the Defence level required to wear " + "" + "Void knight tops" + "" + "."); + case 97: + return newstruct cs2func_script_978_struct(42, 8840, "Members: Void knight robe", "Members now have the Defence level required to wear " + "" + "Void knight robes" + "" + "."); + case 98: + return newstruct cs2func_script_978_struct(42, 8842, "Members: Void knight gloves", "Members now have the Defence level required to wear " + "" + "Void knight gloves" + "" + "."); + case 99: + return newstruct cs2func_script_978_struct(42, 19712, "Members: Void knight deflector", "Members now have the Defence level required to wear " + "" + "Void knight deflectors" + "" + "."); + case 100: + return newstruct cs2func_script_978_struct(42, 8841, "Members: Void knight mace", "Members now have the Defence level required to wield " + "" + "Void knight maces" + "" + "."); + case 101: + return newstruct cs2func_script_978_struct(42, 7620, "Void knight equipment requires 42 Attack, Defence, Strength, Ranged, Magic and Constitution and 22 Prayer.", "" + "Void knight equipment" + "" + " requires 42 Attack, Defence, Strength, Ranged, Magic and Constitution and 22 Prayer."); + case 102: + return newstruct cs2func_script_978_struct(45, 3751, "Members: Berserker helm" + "
" + " (after Fremennik Trials)", "Members now have the Defence level required to wear " + "" + "berserker helms" + "" + " (after Fremennik Trials)."); + case 103: + return newstruct cs2func_script_978_struct(45, 3753, "Members: Warrior helm" + "
" + " (after Fremennik Trials)", "Members now have the Defence level required to wear " + "" + "warrior helms" + "" + " (after Fremennik Trials)."); + case 104: + return newstruct cs2func_script_978_struct(45, 3749, "Members: Archer helm" + "
" + " (after Fremennik Trials)", "Members now have the Defence level required to wear " + "" + "archer helms" + "" + " (after Fremennik Trials)."); + case 105: + return newstruct cs2func_script_978_struct(50, 11200, "Members: Dwarven helmet" + "
" + " (after Grim Tales)", "Members can now wear " + "" + "dwarven helmets" + "" + " (after Grim Tales)."); + case 106: + return newstruct cs2func_script_978_struct(50, 10589, "Members: Granite helm" + "
" + " (with 50 Strength)", "Members now have the Defence level required to wear " + "" + "granite helms" + "" + ". (They also need level 50 Strength.)"); + case 107: + return newstruct cs2func_script_978_struct(50, 10564, "Members: Granite body" + "
" + " (with 50 Strength)", "Members now have the Defence level required to wear " + "" + "granite bodies" + "" + ". (They also need level 50 Strength.)"); + case 108: + return newstruct cs2func_script_978_struct(50, 6809, "Members: Granite legs" + "
" + " (with 50 Strength)", "Members now have the Defence level required to wear " + "" + "granite legs" + "" + ". (They also need level 50 Strength.)"); + case 109: + return newstruct cs2func_script_978_struct(50, 3122, "Members: Granite shield" + "
" + " (with 50 Strength)", "Members now have the Defence level required to wield " + "" + "granite shields" + "" + ". (They also need level 50 Strength.)"); + case 110: + return newstruct cs2func_script_978_struct(50, 19893, "Spirit cape" + "
" + " (with 50 Summoning and 50 Dungeoneering)", "You can now wear " + "" + "spirit capes" + "" + ". (You also need level 50 Summoning and 50 Dungeoneering.)"); + case 111: + return newstruct cs2func_script_978_struct(55, 10828, "Members: Helm of Neitiznot" + "
" + " (after Fremennik Isles)", "Members now have the Defence level required to wear the " + "" + "Helm of Neitiznot" + "" + " (after Fremennik Isles)."); + case 112: + return newstruct cs2func_script_978_struct(60, 6524, "Members: TokTz-Ket-Xil", "Members can now wield " + "" + "TokTz-Ket-Xil" + "" + "."); + case 113: + return newstruct cs2func_script_978_struct(60, 18340, "Members: Anti-poison totem" + "
" + " (with 70 Herblore and 60 Dungeoneering)", "Members can now wield " + "" + "anti-poison totems" + "" + ". (They also need level 70 Herblore and level 60 Dungeoneering.)"); + case 114: + return newstruct cs2func_script_978_struct(65, 10350, "Members: Third-Age full helm", "Members can now wear " + "" + "Third-Age full helms" + "" + "."); + case 115: + return newstruct cs2func_script_978_struct(65, 10348, "Members: Third-Age platebody", "Members can now wear " + "" + "Third-Age platebodies" + "" + "."); + case 116: + return newstruct cs2func_script_978_struct(65, 10346, "Members: Third-Age platelegs", "Members can now wear " + "" + "Third-Age platelegs" + "" + "."); + case 117: + return newstruct cs2func_script_978_struct(65, 10352, "Members: Third-Age kiteshield", "Members can now wield " + "" + "Third-Age kiteshields" + "" + "."); + case 118: + return newstruct cs2func_script_978_struct(65, 11724, "Members: Bandos chestplate", "Members can now wear " + "" + "Bandos chestplates" + "" + "."); + case 119: + return newstruct cs2func_script_978_struct(65, 11726, "Members: Bandos tassets", "Members can now wear " + "" + "Bandos tassets" + "" + "."); + case 120: + return newstruct cs2func_script_978_struct(65, 11728, "Members: Bandos boots", "Members can now wear " + "" + "Bandos boots" + "" + "."); + case 121: + return newstruct cs2func_script_978_struct(65, 21527, "Members: Sacred Clay Shield", "Members can now equip " + "" + "Sacred clay shields" + "" + "."); + case 122: + return newstruct cs2func_script_978_struct(70, 4224, "Members: Crystal shield" + "
" + " (with 50 Agility)", "Members now have the Defence level required to wield " + "" + "crystal shields" + "" + ". (They also need level 50 Agility.)"); + case 123: + return newstruct cs2func_script_978_struct(70, 11718, "Members: Armadyl helmet" + "
" + " (with 70 Ranged)", "Members now have the Defence level required to wear Armadyl helmets. (They also need level 70 Ranged.)"); + case 124: + return newstruct cs2func_script_978_struct(70, 11720, "Members: Armadyl chestplate" + "
" + " (with 70 Ranged)", "Members now have the Defence level required to wear Armadyl chestplates. (They also need level 70 Ranged.)"); + case 125: + return newstruct cs2func_script_978_struct(70, 11722, "Members: Armadyl chainskirt" + "
" + " (with 70 Ranged)", "Members now have the Defence level required to wear Armadyl chainskirts. (They also need level 70 Ranged.)"); + case 126: + return newstruct cs2func_script_978_struct(70, 13736, "Members: Blessed spirit shield" + "
" + " (after Summer's End and with 60 Prayer)", "Members now have the Defence level required to wield " + "" + "blessed spirit shields" + "" + " (after Summer's End, with level 60 Prayer)."); + case 127: + return newstruct cs2func_script_978_struct(75, 11283, "Members: Dragonfire shield", "Members can now wield " + "" + "dragonfire shields" + "" + "."); + case 128: + return newstruct cs2func_script_978_struct(75, 13738, "Members: Arcane spirit shield" + "
" + " (after Summer's End and with 70 Prayer and 65 Magic)", "Members now have the Defence level required to wield " + "" + "arcane spirit shields" + "" + " (after Summer's End, with level 65 Magic and level 70 Prayer)."); + case 129: + return newstruct cs2func_script_978_struct(75, 13740, "Members: Divine spirit shield" + "
" + " (after Summer's End and with 75 Prayer)", "Members now have the Defence level required to wield " + "" + "divine spirit shields" + "" + " (after Summer's End, with level 75 Prayer)."); + case 130: + return newstruct cs2func_script_978_struct(75, 13742, "Members: Elysian spirit shield" + "
" + " (after Summer's End and with 75 Prayer)", "Members now have the Defence level required to wield " + "" + "elysian spirit shields" + "" + " (after Summer's End, with level 75 Prayer)."); + case 131: + return newstruct cs2func_script_978_struct(75, 13744, "Members: Spectral spirit shield" + "
" + " (after Summer's End and with 70 Prayer and 65 Magic)", "Members now have the Defence level required to wield " + "" + "spectral spirit shields" + "" + " (after Summer's End, with level 65 Magic and level 70 Prayer)."); + case 132: + return newstruct cs2func_script_978_struct(75, 21787, "Members: Steadfast boots" + "
" + " (with 75 Attack)", "Members now have the Defence level required to wear " + "" + "steadfast boots" + "" + " (with 75 Attack)."); + case 133: + return newstruct cs2func_script_978_struct(75, 21793, "Members: Ragefire boots" + "
" + " (with 75 Magic)", "Members now have the Defence level required to wear " + "" + "ragefire boots" + "" + " (with 75 Magic)."); + case 134: + return newstruct cs2func_script_978_struct(75, 21790, "Members: Glaiven boots" + "
" + " (with 75 Ranged)", "Members now have the Defence level required to wear " + "" + "glaiven boots" + "" + " (with 75 Ranged)."); + case 135: + return newstruct cs2func_script_978_struct(78, 13876, "Members: Morrigan's coif" + "
" + " (with 78 Ranged)", "Members now have the Defence level required to wear " + "" + "Morrigan's coif" + "" + ". (They also need level 78 Ranged.)"); + case 136: + return newstruct cs2func_script_978_struct(78, 13870, "Members: Morrigan's leather body" + "
" + " (with 78 Ranged)", "Members now have the Defence level required to wear " + "" + "Morrigan's leather body" + "" + ". (They also need level 78 Ranged.)"); + case 137: + return newstruct cs2func_script_978_struct(78, 13873, "Members: Morrigan's leather chaps" + "
" + " (with 78 Ranged)", "Members now have the Defence level required to wear " + "" + "Morrigan's leather chaps" + "" + ". (They also need level 78 Ranged.)"); + case 138: + return newstruct cs2func_script_978_struct(78, 13896, "Members: Statius's full helm", "Members now have the Defence level required to wear " + "" + "Statius's full helm" + "" + "."); + case 139: + return newstruct cs2func_script_978_struct(78, 13884, "Members: Statius's platebody", "Members now have the Defence level required to wear " + "" + "Statius's platebody" + "" + "."); + case 140: + return newstruct cs2func_script_978_struct(78, 13887, "Members: Vesta's chainbody", "Members now have the Defence level required to wear " + "" + "Vesta's chainbody" + "" + "."); + case 141: + return newstruct cs2func_script_978_struct(78, 13890, "Members: Statius's platelegs", "Members now have the Defence level required to wear " + "" + "Statius's platelegs" + "" + "."); + case 142: + return newstruct cs2func_script_978_struct(78, 13893, "Members: Vesta's plateskirt", "Members now have the Defence level required to wear " + "" + "Vesta's plateskirt" + "" + "."); + case 143: + return newstruct cs2func_script_978_struct(80, 18359, "Members: Chaotic kiteshield" + "
" + " (with 80 Dungeoneering)", "Members can now wield " + "" + "chaotic kiteshields" + "" + ". (They also need level 80 Dungeoneering.)"); + case 144: + return newstruct cs2func_script_978_struct(80, 18361, "Members: Eagle-eye kiteshield" + "
" + " (with 80 Dungeoneering)", "Members can now wield " + "" + "eagle-eye kiteshields" + "" + ". (They also need level 80 Dungeoneering.)"); + case 145: + return newstruct cs2func_script_978_struct(80, 18363, "Members: Farseer kiteshield" + "
" + " (with 80 Dungeoneering)", "Members can now wield " + "" + "farseer kiteshields" + "" + ". (They also need level 80 Dungeoneering.)"); + case 146: + return newstruct cs2func_script_978_struct(80, 20135, "Members: Torva full helm" + "
" + " (with 80 Strength and Constitution)", "Members can now wear " + "" + "torva full helms" + "" + ". (They also need level 80 Strength and Constitution.)"); + case 147: + return newstruct cs2func_script_978_struct(80, 20139, "Members: Torva platebody" + "
" + " (with 80 Strength and Constitution)", "Members can now wear " + "" + "torva platebodies" + "" + ". (They also need level 80 Strength and Constitution.)"); + case 148: + return newstruct cs2func_script_978_struct(80, 20143, "Members: Torva platelegs" + "
" + " (with 80 Strength and Constitution)", "Members can now wear " + "" + "torva platelegs" + "" + ". (They also need level 80 Strength and Constitution.)"); + case 149: + return newstruct cs2func_script_978_struct(80, 20147, "Members: Pernix cowl" + "
" + " (with 80 Ranged and Constitution)", "Members can now wear " + "" + "pernix cowls" + "" + ". (They also need level 80 Ranged and Constitution.)"); + case 150: + return newstruct cs2func_script_978_struct(80, 20151, "Members: Pernix body" + "
" + " (with 80 Ranged and Constitution)", "Members can now wear " + "" + "pernix bodies" + "" + ". (They also need level 80 Ranged and Constitution.)"); + case 151: + return newstruct cs2func_script_978_struct(80, 20155, "Members: Pernix chaps" + "
" + " (with 80 Ranged and Constitution)", "Members can now wear " + "" + "pernix chaps" + "" + ". (They also need level 80 Ranged and Constitution.)"); + } + break; + case 12: + switch (arg1) { + case 0: + return newstruct cs2func_script_978_struct(1, 14367, "Members: Stealing Creation - class 1 helmet", "Members can now wear " + "" + "class 1 helmets" + "" + " in Stealing Creation."); + case 1: + return newstruct cs2func_script_978_struct(1, 14357, "Members: Stealing Creation - class 1 platelegs", "Members can now wear " + "" + "class 1 platelegs" + "" + " in Stealing Creation."); + case 2: + return newstruct cs2func_script_978_struct(1, 14347, "Members: Stealing Creation - class 1 platebody", "Members can now wear " + "" + "class 1 platebodies" + "" + " in Stealing Creation."); + case 3: + return newstruct cs2func_script_978_struct(20, 14369, "Members: Stealing Creation - class 2 helmet", "Members can now wear " + "" + "class 2 helmets" + "" + " in Stealing Creation."); + case 4: + return newstruct cs2func_script_978_struct(20, 14359, "Members: Stealing Creation - class 2 platelegs", "Members can now wear " + "" + "class 2 platelegs" + "" + " in Stealing Creation."); + case 5: + return newstruct cs2func_script_978_struct(20, 14349, "Members: Stealing Creation - class 2 platebody", "Members can now wear " + "" + "class 2 platebodies" + "" + " in Stealing Creation."); + case 6: + return newstruct cs2func_script_978_struct(40, 14371, "Members: Stealing Creation - class 3 helmet", "Members can now wear " + "" + "class 3 helmets" + "" + " in Stealing Creation."); + case 7: + return newstruct cs2func_script_978_struct(40, 14361, "Members: Stealing Creation - class 3 platelegs", "Members can now wear " + "" + "class 3 platelegs" + "" + " in Stealing Creation."); + case 8: + return newstruct cs2func_script_978_struct(40, 14351, "Members: Stealing Creation - class 3 platebody", "Members can now wear " + "" + "class 3 platebodies" + "" + " in Stealing Creation."); + case 9: + return newstruct cs2func_script_978_struct(60, 14373, "Members: Stealing Creation - class 4 helmet", "Members can now wear " + "" + "class 4 helmets" + "" + " in Stealing Creation."); + case 10: + return newstruct cs2func_script_978_struct(60, 14363, "Members: Stealing Creation - class 4 platelegs", "Members can now wear " + "" + "class 4 platelegs" + "" + " in Stealing Creation."); + case 11: + return newstruct cs2func_script_978_struct(60, 14353, "Members: Stealing Creation - class 4 platebody", "Members can now wear " + "" + "class 4 platebodies" + "" + " in Stealing Creation."); + case 12: + return newstruct cs2func_script_978_struct(80, 14375, "Members: Stealing Creation - class 5 helmet", "Members can now wear " + "" + "class 5 helmets" + "" + " in Stealing Creation."); + case 13: + return newstruct cs2func_script_978_struct(80, 14365, "Members: Stealing Creation - class 5 platelegs", "Members can now wear " + "" + "class 5 platelegs" + "" + " in Stealing Creation."); + case 14: + return newstruct cs2func_script_978_struct(80, 14355, "Members: Stealing Creation - class 5 platebody", "Members can now wear " + "" + "class 5 platebodies" + "" + " in Stealing Creation."); + case 15: + return newstruct cs2func_script_978_struct(85, 21537, "Members: Battle-mage helm" + "
" + " (with 85 Magic and 85 Strength)", "Members now have the Defence requirement to wear " + "" + "Battle-mage helms" + "" + ". (They also need level 85 Magic and level 85 Strength.)"); + case 16: + return newstruct cs2func_script_978_struct(85, 21539, "Members: Battle-mage robe" + "
" + " (with 85 Magic and 85 Strength)", "Members now have the Defence requirement to wear " + "" + "Battle-mage robes" + "" + ". (They also need level 85 Magic and level 85 Strength.)"); + case 17: + return newstruct cs2func_script_978_struct(85, 21541, "Members: Battle-mage legs" + "
" + " (with 85 Magic and 85 Strength)", "Members now have the Defence requirement to wear " + "" + "Battle-mage legs" + "" + ". (They also need level 85 Magic and level 85 Strength.)"); + case 18: + return newstruct cs2func_script_978_struct(85, 21543, "Members: Battle-mage gloves" + "
" + " (with 85 Magic and 85 Strength)", "Members now have the Defence requirement to wear " + "" + "Battle-mage gloves" + "" + ". (They also need level 85 Magic and level 85 Strength.)"); + case 19: + return newstruct cs2func_script_978_struct(85, 21545, "Members: Battle-mage boots" + "
" + " (with 85 Magic and 85 Strength)", "Members now have the Defence requirement to wear " + "" + "Battle-mage boots" + "" + ". (They also need level 85 Magic and level 85 Strength.)"); + case 20: + return newstruct cs2func_script_978_struct(85, 21547, "Members: Trickster hood" + "
" + " (with 85 Magic and 85 Ranged)", "Members now have the Defence requirement to wear " + "" + "Trickster hoods" + "" + ". (They also need level 85 Magic and level 85 Ranged)"); + case 21: + return newstruct cs2func_script_978_struct(85, 21549, "Members: Trickster robe" + "
" + " (with 85 Magic and 85 Ranged)", "Members now have the Defence requirement to wear " + "" + "Trickster robes" + "" + ". (They also need level 85 Magic and level 85 Ranged)"); + case 22: + return newstruct cs2func_script_978_struct(85, 21551, "Members: Trickster legs" + "
" + " (with 85 Magic and 85 Ranged)", "Members now have the Defence requirement to wear " + "" + "Trickster legs" + "" + ". (They also need level 85 Magic and level 85 Ranged)"); + case 23: + return newstruct cs2func_script_978_struct(85, 21553, "Members: Trickster gloves" + "
" + " (with 85 Magic and 85 Ranged)", "Members now have the Defence requirement to wear " + "" + "Trickster gloves" + "" + ". (They also need level 85 Magic and level 85 Ranged)"); + case 24: + return newstruct cs2func_script_978_struct(85, 21555, "Members: Trickster boots" + "
" + " (with 85 Magic and 85 Ranged)", "Members now have the Defence requirement to wear " + "" + "Trickster boots" + "" + ". (They also need level 85 Magic and level 85 Ranged)"); + case 25: + return newstruct cs2func_script_978_struct(85, 21557, "Members: Vanguard helm" + "
" + " (with 85 Ranged and 85 Strength)", "Members now have the Defence requirement to wear " + "" + "Vanguard helms" + "" + ". (They also need level 85 Ranged and level 85 Strength.)"); + case 26: + return newstruct cs2func_script_978_struct(85, 21559, "Members: Vanguard body" + "
" + " (with 85 Ranged and 85 Strength)", "Members now have the Defence requirement to wear " + "" + "Vanguard body armour" + "" + ". (They also need level 85 Ranged and level 85 Strength.)"); + case 27: + return newstruct cs2func_script_978_struct(85, 21561, "Members: Vanguard legs" + "
" + " (with 85 Ranged and 85 Strength)", "Members now have the Defence requirement to wear " + "" + "Vanguard leg armour" + "" + ". (They also need level 85 Ranged and level 85 Strength.)"); + case 28: + return newstruct cs2func_script_978_struct(85, 21563, "Members: Vanguard gloves" + "
" + " (with 85 Ranged and 85 Strength)", "Members now have the Defence requirement to wear " + "" + "Vanguard gloves" + "" + ". (They also need level 85 Ranged and level 85 Strength.)"); + case 29: + return newstruct cs2func_script_978_struct(85, 21565, "Members: Vanguard boots" + "
" + " (with 85 Ranged and 85 Strength)", "Members now have the Defence requirement to wear " + "" + "Vanguard boots" + "" + ". (They also need level 85 Ranged and level 85 Strength.)"); + } + break; + case 13: + switch (arg1) { + case 0: + return newstruct cs2func_script_978_struct(1, 16691, "Novite full helm (Tier 1)", "You can now wear " + "" + "novite full helms" + "" + " within Daemonheim."); + case 1: + return newstruct cs2func_script_978_struct(1, 17239, "Novite platebody (Tier 1)", "You can now wear " + "" + "novite platebodies" + "" + " within Daemonheim."); + case 2: + return newstruct cs2func_script_978_struct(1, 16713, "Novite chainbody (Tier 1)", "You can now wear " + "" + "novite chainbodies" + "" + " within Daemonheim."); + case 3: + return newstruct cs2func_script_978_struct(1, 16669, "Novite platelegs (Tier 1)", "You can now wear " + "" + "novite platelegs" + "" + " within Daemonheim."); + case 4: + return newstruct cs2func_script_978_struct(1, 16647, "Novite plateskirt (Tier 1)", "You can now wear " + "" + "novite plateskirts" + "" + " within Daemonheim."); + case 5: + return newstruct cs2func_script_978_struct(1, 16273, "Novite gauntlets (Tier 1)", "You can now wear " + "" + "novite gauntlets" + "" + " within Daemonheim."); + case 6: + return newstruct cs2func_script_978_struct(1, 16339, "Novite boots (Tier 1)", "You can now wear " + "" + "novite boots" + "" + " within Daemonheim."); + case 7: + return newstruct cs2func_script_978_struct(1, 17341, "Novite kiteshield (Tier 1)", "You can now wield " + "" + "novite kiteshields" + "" + " within Daemonheim."); + case 8: + return newstruct cs2func_script_978_struct(1, 16735, "Salve hood (Tier 1)" + "
" + " (with 1 Magic)", "You can now wear " + "" + "salve hoods" + "" + " within Daemonheim. (You also need level 1 Magic.)"); + case 9: + return newstruct cs2func_script_978_struct(1, 17217, "Salve robe top (Tier 1)" + "
" + " (with 1 Magic)", "You can now wear " + "" + "salve robe tops" + "" + " within Daemonheim. (You also need level 1 Magic.)"); + case 10: + return newstruct cs2func_script_978_struct(1, 16845, "Salve robe bottom (Tier 1)" + "
" + " (with 1 Magic)", "You can now wear " + "" + "salve robe bottoms" + "" + " within Daemonheim. (You also need level 1 Magic.)"); + case 11: + return newstruct cs2func_script_978_struct(1, 17151, "Salve gloves (Tier 1)" + "
" + " (with 1 Magic)", "You can now wear " + "" + "salve gloves" + "" + " within Daemonheim. (You also need level 1 Magic.)"); + case 12: + return newstruct cs2func_script_978_struct(1, 16911, "Salve boots (Tier 1)" + "
" + " ( with 1 Magic)", "You can now wear " + "" + "salve boots" + "" + " within Daemonheim. (You also need level 1 Magic.)"); + case 13: + return newstruct cs2func_script_978_struct(1, 17041, "Protoleather coif (Tier 1)" + "
" + " (with 1 Ranged)", "You can now wear " + "" + "protoleather coifs" + "" + " within Daemonheim. (You also need level 1 Ranged.)"); + case 14: + return newstruct cs2func_script_978_struct(1, 17173, "Protoleather body (Tier 1)" + "
" + " (with 1 Ranged)", "You can now wear " + "" + "protoleather bodies" + "" + " within Daemonheim. (You also need level 1 Ranged.)"); + case 15: + return newstruct cs2func_script_978_struct(1, 17319, "Protoleather chaps (Tier 1)" + "
" + " (with 1 Ranged)", "You can now wear " + "" + "protoleather chaps" + "" + " within Daemonheim. (You also need level 1 Ranged.)"); + case 16: + return newstruct cs2func_script_978_struct(1, 17195, "Protoleather vambraces (Tier 1)" + "
" + " (with 1 Ranged)", "You can now wear " + "" + "protoleather vambraces" + "" + " within Daemonheim. (You also need level 1 Ranged.)"); + case 17: + return newstruct cs2func_script_978_struct(1, 17297, "Protoleather boots (Tier 1)" + "
" + " (with 1 Ranged)", "You can now wear " + "" + "protoleather boots" + "" + " within Daemonheim. (You also need level 1 Ranged.)"); + case 18: + return newstruct cs2func_script_978_struct(10, 16693, "Bathus full helm (Tier 2)", "You can now wear " + "" + "bathus full helms" + "" + " within Daemonheim."); + case 19: + return newstruct cs2func_script_978_struct(10, 17241, "Bathus platebody (Tier 2)", "You can now wear " + "" + "bathus platebodies" + "" + " within Daemonheim."); + case 20: + return newstruct cs2func_script_978_struct(10, 16715, "Bathus chainbody (Tier 2)", "You can now wear " + "" + "bathus chainbodies" + "" + " within Daemonheim."); + case 21: + return newstruct cs2func_script_978_struct(10, 16671, "Bathus platelegs (Tier 2)", "You can now wear " + "" + "bathus platelegs" + "" + " within Daemonheim."); + case 22: + return newstruct cs2func_script_978_struct(10, 16649, "Bathus plateskirt (Tier 2)", "You can now wear " + "" + "bathus plateskirts" + "" + " within Daemonheim."); + case 23: + return newstruct cs2func_script_978_struct(10, 16275, "Bathus gauntlets (Tier 2)", "You can now wear " + "" + "bathus gauntlets" + "" + " within Daemonheim."); + case 24: + return newstruct cs2func_script_978_struct(10, 16341, "Bathus boots (Tier 2)", "You can now wear " + "" + "bathus boots" + "" + " within Daemonheim."); + case 25: + return newstruct cs2func_script_978_struct(10, 17343, "Bathus kiteshield (Tier 2)", "You can now wield " + "" + "bathus kiteshields" + "" + " within Daemonheim."); + case 26: + return newstruct cs2func_script_978_struct(10, 16737, "Wildercress hood (Tier 2)" + "
" + " (with 10 Magic)", "You can now wear " + "" + "wildercress hoods" + "" + " within Daemonheim. (You also need level 10 Magic.)"); + case 27: + return newstruct cs2func_script_978_struct(10, 17219, "Wildercress robe top (Tier 2)" + "
" + " (with 10 Magic)", "You can now wear " + "" + "wildercress robe tops" + "" + " within Daemonheim. (You also need level 10 Magic.)"); + case 28: + return newstruct cs2func_script_978_struct(10, 16847, "Wildercress robe bottom (Tier 2)" + "
" + " (with 10 Magic)", "You can now wear " + "" + "wildercress robe bottoms" + "" + " within Daemonheim. (You also need level 10 Magic.)"); + case 29: + return newstruct cs2func_script_978_struct(10, 17153, "Wildercress gloves (Tier 2)" + "
" + " (with 10 Magic)", "You can now wear " + "" + "wildercress gloves" + "" + " within Daemonheim. (You also need level 10 Magic.)"); + case 30: + return newstruct cs2func_script_978_struct(10, 16913, "Wildercress boots (Tier 2)" + "
" + " (with 10 Magic)", "You can now wear " + "" + "wildercress boots" + "" + " within Daemonheim. (You also need level 10 Magic.)"); + case 31: + return newstruct cs2func_script_978_struct(10, 17043, "Subleather coif (Tier 2)" + "
" + " (with 10 Ranged)", "You can now wear " + "" + "subleather coifs" + "" + " within Daemonheim. (You also need level 10 Ranged.)"); + case 32: + return newstruct cs2func_script_978_struct(10, 17175, "Subleather body (Tier 2)" + "
" + " (with 10 Ranged)", "You can now wear " + "" + "subleather bodies" + "" + " within Daemonheim. (You also need level 10 Ranged.)"); + case 33: + return newstruct cs2func_script_978_struct(10, 17321, "Subleather chaps (Tier 2)" + "
" + " (with 10 Ranged)", "You can now wear " + "" + "subleather chaps" + "" + " within Daemonheim. (You also need level 10 Ranged.)"); + case 34: + return newstruct cs2func_script_978_struct(10, 17197, "Subleather vambraces (Tier 2)" + "
" + " (with 10 Ranged)", "You can now wear " + "" + "subleather vambraces" + "" + " within Daemonheim. (You also need level 10 Ranged.)"); + case 35: + return newstruct cs2func_script_978_struct(10, 17299, "Subleather boots (Tier 2)" + "
" + " (with 10 Ranged)", "You can now wear " + "" + "subleather boots" + "" + " within Daemonheim. (You also need level 10 Ranged.)"); + case 36: + return newstruct cs2func_script_978_struct(15, 17261, "Members: Silver precision bracelet ", "Members can now wear " + "" + "silver precision bracelets" + "" + " within Daemonheim."); + case 37: + return newstruct cs2func_script_978_struct(20, 16695, "Marmaros full helm (Tier 3)", "You can now wear " + "" + "marmaros full helms" + "" + " within Daemonheim."); + case 38: + return newstruct cs2func_script_978_struct(20, 17243, "Marmaros platebody (Tier 3)", "You can now wear " + "" + "marmaros platebodies" + "" + " within Daemonheim."); + case 39: + return newstruct cs2func_script_978_struct(20, 16717, "Marmaros chainbody (Tier 3)", "You can now wear " + "" + "marmaros chainbodies" + "" + " within Daemonheim."); + case 40: + return newstruct cs2func_script_978_struct(20, 16673, "Marmaros platelegs (Tier 3)", "You can now wear " + "" + "marmaros platelegs" + "" + " within Daemonheim."); + case 41: + return newstruct cs2func_script_978_struct(20, 16651, "Marmaros plateskirt (Tier 3)", "You can now wear " + "" + "marmaros plateskirts" + "" + " within Daemonheim."); + case 42: + return newstruct cs2func_script_978_struct(20, 16277, "Marmaros gauntlets (Tier 3)", "You can now wear " + "" + "marmaros gauntlets" + "" + " within Daemonheim."); + case 43: + return newstruct cs2func_script_978_struct(20, 16343, "Marmaros boots (Tier 3)", "You can now wear " + "" + "marmaros boots" + "" + " within Daemonheim."); + case 44: + return newstruct cs2func_script_978_struct(20, 17345, "Marmaros kiteshield (Tier 3)", "You can now wield " + "" + "marmaros kiteshields" + "" + " within Daemonheim."); + case 45: + return newstruct cs2func_script_978_struct(20, 16739, "Blightleaf hood (Tier 3)" + "
" + " (with 20 Magic)", "You can now wear " + "" + "blightleaf hoods" + "" + " within Daemonheim. (You also need level 20 Magic.)"); + case 46: + return newstruct cs2func_script_978_struct(20, 17221, "Blightleaf robe top (Tier 3)" + "
" + " (with 20 Magic)", "You can now wear " + "" + "blightleaf robe tops" + "" + " within Daemonheim. (You also need 20 Magic)."); + case 47: + return newstruct cs2func_script_978_struct(20, 16849, "Blightleaf robe bottom (Tier 3)" + "
" + " (with 20 Magic)", "You can now wear " + "" + "blightleaf robe bottoms" + "" + " within Daemonheim. (You also need level 20 Magic.)"); + case 48: + return newstruct cs2func_script_978_struct(20, 17155, "Blightleaf gloves (Tier 3)" + "
" + " (with 20 Magic)", "You can now wear " + "" + "blightleaf gloves" + "" + " within Daemonheim. (You also need level 20 Magic.)"); + case 49: + return newstruct cs2func_script_978_struct(20, 16915, "Blightleaf boots (Tier 3)" + "
" + " (with 20 Magic)", "You can now wear " + "" + "blightleaf boots" + "" + " within Daemonheim. (You also need level 20 Magic.)"); + case 50: + return newstruct cs2func_script_978_struct(20, 17045, "Paraleather coif (Tier 3)" + "
" + " (with 20 Ranged)", "You can now wear " + "" + "paraleather coifs" + "" + " within Daemonheim. (You also need level 20 Ranged.)"); + case 51: + return newstruct cs2func_script_978_struct(20, 17177, "Paraleather body (Tier 3)" + "
" + " (with 20 Ranged)", "You can now wear " + "" + "paraleather bodies" + "" + " within Daemonheim. (You also need level 20 Ranged.)"); + case 52: + return newstruct cs2func_script_978_struct(20, 17323, "Paraleather chaps (Tier 3)" + "
" + " (with 20 Ranged)", "You can now wear " + "" + "paraleather chaps" + "" + " within Daemonheim. (You also need level 20 Ranged.)"); + case 53: + return newstruct cs2func_script_978_struct(20, 17199, "Paraleather vambraces (Tier 3)" + "
" + " (with 20 Ranged)", "You can now wear " + "" + "paraleather vambraces" + "" + " within Daemonheim. (You also need level 20 Ranged.)"); + case 54: + return newstruct cs2func_script_978_struct(20, 17301, "Paraleather boots (Tier 3)" + "
" + " (with 20 Ranged)", "You can now wear " + "" + "paraleather boots" + "" + " within Daemonheim. (You also need level 20 Ranged.)"); + case 55: + return newstruct cs2func_script_978_struct(21, 17265, "Members: Sunstriker boots ", "Members can now wear " + "" + "sunstriker boots" + "" + " within Daemonheim."); + case 56: + return newstruct cs2func_script_978_struct(28, 17269, "Members: Incantor's boots ", "Members can now wear " + "" + "incantor's boots" + "" + " within Daemonheim."); + case 57: + return newstruct cs2func_script_978_struct(30, 16697, "Kratonite full helm (Tier 4)", "You can now wear " + "" + "kratonite full helms" + "" + " within Daemonheim."); + case 58: + return newstruct cs2func_script_978_struct(30, 17245, "Kratonite platebody (Tier 4)", "You can now wear " + "" + "kratonite platebodies" + "" + " within Daemonheim."); + case 59: + return newstruct cs2func_script_978_struct(30, 16719, "Kratonite chainbody (Tier 4)", "You can now wear " + "" + "kratonite chainbodies" + "" + " within Daemonheim."); + case 60: + return newstruct cs2func_script_978_struct(30, 16675, "Kratonite platelegs (Tier 4)", "You can now wear " + "" + "kratonite platelegs" + "" + " within Daemonheim."); + case 61: + return newstruct cs2func_script_978_struct(30, 16653, "Kratonite plateskirt (Tier 4)", "You can now wear " + "" + "kratonite plateskirts" + "" + " within Daemonheim."); + case 62: + return newstruct cs2func_script_978_struct(30, 16279, "Kratonite gauntlets (Tier 4)", "You can now wear " + "" + "kratonite gauntlets" + "" + " within Daemonheim."); + case 63: + return newstruct cs2func_script_978_struct(30, 16345, "Kratonite boots (Tier 4)", "You can now wear " + "" + "kratonite boots" + "" + " within Daemonheim."); + case 64: + return newstruct cs2func_script_978_struct(30, 17347, "Kratonite kiteshield (Tier 4)", "You can now wield " + "" + "kratonite kiteshields" + "" + " within Daemonheim."); + case 65: + return newstruct cs2func_script_978_struct(30, 16741, "Roseblood hood (Tier 4)" + "
" + " (with 30 Magic)", "You can now wear " + "" + "roseblood hoods" + "" + " within Daemonheim. (You also need level 30 Magic.)"); + case 66: + return newstruct cs2func_script_978_struct(30, 17223, "Roseblood robe top (Tier 4)" + "
" + " (with 30 Magic)", "You can now wear " + "" + "roseblood robe tops" + "" + " within Daemonheim. (You also need level 30 Magic.)"); + case 67: + return newstruct cs2func_script_978_struct(30, 16851, "Roseblood robe bottom (Tier 4)" + "
" + " (with 30 Magic)", "You can now wear " + "" + "roseblood robe bottoms" + "" + " within Daemonheim. (You also need level 30 Magic.)"); + case 68: + return newstruct cs2func_script_978_struct(30, 17157, "Roseblood gloves (Tier 4)" + "
" + " (with 30 Magic)", "You can now wear " + "" + "roseblood gloves" + "" + " within Daemonheim. (You also need 30 Magic)."); + case 69: + return newstruct cs2func_script_978_struct(30, 16917, "Roseblood boots (Tier 4)" + "
" + " (with 30 Magic)", "You can now wear " + "" + "roseblood boots" + "" + " within Daemonheim. (You also need level 30 Magic.)"); + case 70: + return newstruct cs2func_script_978_struct(30, 17047, "Archleather coif (Tier 4)" + "
" + " (with 30 Ranged)", "You can now wear " + "" + "archleather coifs" + "" + " within Daemonheim. (You also need level 30 Ranged.)"); + case 71: + return newstruct cs2func_script_978_struct(30, 17179, "Archleather body (Tier 4)" + "
" + " (with 30 Ranged)", "You can now wear " + "" + "archleather bodies" + "" + " within Daemonheim. (You also need level 30 Ranged.)"); + case 72: + return newstruct cs2func_script_978_struct(30, 17325, "Archleather chaps (Tier 4)" + "
" + " (with 30 Ranged)", "You can now wear " + "" + "archleather chaps" + "" + " within Daemonheim. (You also need level 30 Ranged.)"); + case 73: + return newstruct cs2func_script_978_struct(30, 17201, "Archleather vambraces (Tier 4)" + "
" + " (with 30 Ranged)", "You can now wear " + "" + "archleather vambraces" + "" + " within Daemonheim. (You also need level 30 Ranged.)"); + case 74: + return newstruct cs2func_script_978_struct(30, 17303, "Archleather boots (Tier 4)" + "
" + " (with 30 Ranged)", "You can now wear " + "" + "archleather boots" + "" + " within Daemonheim. (You also need level 30 Ranged.)"); + case 75: + return newstruct cs2func_script_978_struct(33, 17273, "Members: Flameburst defender" + "
" + " (with 33 Magic)", "Members can now wield " + "" + "flameburst defenders" + "" + " within Daemonheim. (They also need level 33 Magic.)"); + case 76: + return newstruct cs2func_script_978_struct(40, 16699, "Fractite full helm (Tier 5)", "You can now wear " + "" + "fractite full helms" + "" + " within Daemonheim."); + case 77: + return newstruct cs2func_script_978_struct(40, 17247, "Fractite platebody (Tier 5)", "You can now wear " + "" + "fractite platebodies" + "" + " within Daemonheim."); + case 78: + return newstruct cs2func_script_978_struct(40, 16721, "Fractite chainbody (Tier 5)", "You can now wear " + "" + "fractite chainbodies" + "" + " within Daemonheim."); + case 79: + return newstruct cs2func_script_978_struct(40, 16677, "Fractite platelegs (Tier 5)", "You can now wear " + "" + "fractite platelegs" + "" + " within Daemonheim."); + case 80: + return newstruct cs2func_script_978_struct(40, 16655, "Fractite plateskirt (Tier 5)", "You can now wear " + "" + "fractite plateskirts" + "" + " within Daemonheim."); + case 81: + return newstruct cs2func_script_978_struct(40, 16281, "Fractite gauntlets (Tier 5)", "You can now wear " + "" + "fractite gauntlets" + "" + " within Daemonheim."); + case 82: + return newstruct cs2func_script_978_struct(40, 16347, "Fractite boots (Tier 5)", "You can now wear " + "" + "fractite boots" + "" + " within Daemonheim."); + case 83: + return newstruct cs2func_script_978_struct(40, 17349, "Fractite kiteshield (Tier 5)", "You can now wield " + "" + "fractite kiteshields" + "" + " within Daemonheim."); + case 84: + return newstruct cs2func_script_978_struct(40, 16743, "Bryll hood (Tier 5)" + "
" + " (with 40 Magic)", "You can now wear " + "" + "bryll hoods" + "" + " within Daemonheim. (You also need level 40 Magic.)"); + case 85: + return newstruct cs2func_script_978_struct(40, 17225, "Bryll robe top (Tier 5)" + "
" + " (with 40 Magic)", "You can now wear " + "" + "bryll robe tops" + "" + " within Daemonheim. (You also need level 40 Magic.)"); + case 86: + return newstruct cs2func_script_978_struct(40, 16853, "Bryll robe bottom (Tier 5)" + "
" + " (with 40 Magic)", "You can now wear " + "" + "bryll robe bottoms" + "" + " within Daemonheim. (You also need level 40 Magic.)"); + case 87: + return newstruct cs2func_script_978_struct(40, 17159, "Bryll gloves (Tier 5)" + "
" + " (with 40 Magic)", "You can now wear " + "" + "bryll gloves" + "" + " within Daemonheim. (You also need level 40 Magic.)"); + case 88: + return newstruct cs2func_script_978_struct(40, 16919, "Bryll boots (Tier 5)" + "
" + " (with 40 Magic)", "You can now wear " + "" + "bryll boots" + "" + " within Daemonheim. (You also need level 40 Magic.)"); + case 89: + return newstruct cs2func_script_978_struct(40, 17049, "Dromoleather coif (Tier 5)" + "
" + " (with 40 Ranged)", "You can now wear " + "" + "dromoleather coifs" + "" + " within Daemonheim. (You also need level 40 Ranged.)"); + case 90: + return newstruct cs2func_script_978_struct(40, 17181, "Dromoleather body (Tier 5)" + "
" + " (with 40 Ranged)", "You can now wear " + "" + "dromoleather bodies" + "" + " within Daemonheim. (You also need level 40 Ranged.)"); + case 91: + return newstruct cs2func_script_978_struct(40, 17327, "Dromoleather chaps (Tier 5)" + "
" + " (with 40 Ranged)", "You can now wear " + "" + "dromoleather chaps" + "" + " within Daemonheim. (You also need level 40 Ranged.)"); + case 92: + return newstruct cs2func_script_978_struct(40, 17203, "Dromoleather vambraces (Tier 5)" + "
" + " (with 40 Ranged)", "You can now wear " + "" + "dromoleather vambraces" + "" + " within Daemonheim. (You also need level 40 Ranged.)"); + case 93: + return newstruct cs2func_script_978_struct(40, 17305, "Dromoleather boots (Tier 5)" + "
" + " (with 40 Ranged)", "You can now wear " + "" + "dromoleather boots" + "" + " within Daemonheim. (You also need level 40 Ranged.)"); + case 94: + return newstruct cs2func_script_978_struct(45, 17263, "Members: Golden precision bracelet ", "Members can now wear " + "" + "golden precision bracelets" + "" + " within Daemonheim."); + case 95: + return newstruct cs2func_script_978_struct(45, 17279, "Members: Shadow silk hood ", "Members can now wear " + "" + "shadow silk hoods" + "" + " within Daemonheim."); + case 96: + return newstruct cs2func_script_978_struct(48, 17267, "Members: Marksman boots ", "Members can now wear " + "" + "marksman boots" + "" + " within Daemonheim."); + case 97: + return newstruct cs2func_script_978_struct(50, 16701, "Members: Zephyrium full helm (Tier 6)", "Members can now wear " + "" + "zephyrium full helms" + "" + " within Daemonheim."); + case 98: + return newstruct cs2func_script_978_struct(50, 17249, "Members: Zephyrium platebody (Tier 6)", "Members can now wear " + "" + "zephyrium platebodies" + "" + " within Daemonheim."); + case 99: + return newstruct cs2func_script_978_struct(50, 16723, "Members: Zephyrium chainbody (Tier 6)", "Members can now wear " + "" + "zephyrium chainbodies" + "" + " within Daemonheim."); + case 100: + return newstruct cs2func_script_978_struct(50, 16679, "Members: Zephyrium platelegs (Tier 6)", "Members can now wear " + "" + "zephyrium platelegs" + "" + " within Daemonheim."); + case 101: + return newstruct cs2func_script_978_struct(50, 16657, "Members: Zephyrium plateskirt (Tier 6)", "Members can now wear " + "" + "zephyrium plateskirts" + "" + " within Daemonheim."); + case 102: + return newstruct cs2func_script_978_struct(50, 16283, "Members: Zephyrium gauntlets (Tier 6)", "Members can now wear " + "" + "zephyrium gauntlets" + "" + " within Daemonheim."); + case 103: + return newstruct cs2func_script_978_struct(50, 16349, "Members: Zephyrium boots (Tier 6)", "Members can now wear " + "" + "zephyrium boots" + "" + " within Daemonheim."); + case 104: + return newstruct cs2func_script_978_struct(50, 17351, "Members: Zephyrium kiteshield (Tier 6)", "Members can now wield " + "" + "zephyrium kiteshields" + "" + " within Daemonheim."); + case 105: + return newstruct cs2func_script_978_struct(50, 16745, "Members: Duskweed hood (Tier 6)" + "
" + " (with 50 Magic)", "Members can now wear " + "" + "duskweed hoods" + "" + " within Daemonheim. (They also need level 50 Magic.)"); + case 106: + return newstruct cs2func_script_978_struct(50, 17227, "Members: Duskweed robe top (Tier 6)" + "
" + " (with 50 Magic)", "Members can now wear " + "" + "duskweed robe tops" + "" + " within Daemonheim. (They also need level 50 Magic.)"); + case 107: + return newstruct cs2func_script_978_struct(50, 16855, "Members: Duskweed robe bottom (Tier 6)" + "
" + " (with 50 Magic)", "Members can now wear " + "" + "duskweed robe bottoms" + "" + " within Daemonheim. (They also need level 50 Magic.)"); + case 108: + return newstruct cs2func_script_978_struct(50, 17161, "Members: Duskweed gloves (Tier 6)" + "
" + " (with 50 Magic)", "Members can now wear " + "" + "duskweed gloves" + "" + " within Daemonheim. (They also need level 50 Magic.)"); + case 109: + return newstruct cs2func_script_978_struct(50, 16921, "Members: Duskweed boots (Tier 6)" + "
" + " (with 50 Magic)", "Members can now wear " + "" + "duskweed boots" + "" + " within Daemonheim. (They also need level 50 Magic.)"); + case 110: + return newstruct cs2func_script_978_struct(50, 17051, "Members: Spinoleather coif (Tier 6)" + "
" + " (with 50 Ranged)", "Members can now wear " + "" + "spinoleather coifs" + "" + " within Daemonheim. (They also need level 50 Ranged.)"); + case 111: + return newstruct cs2func_script_978_struct(50, 17183, "Members: Spinoleather body (Tier 6)" + "
" + " (with 50 Ranged)", "Members can now wear " + "" + "spinoleather bodies" + "" + " within Daemonheim. (They also need level 50 Ranged.)"); + case 112: + return newstruct cs2func_script_978_struct(50, 17329, "Members: Spinoleather chaps (Tier 6)" + "
" + " (with 50 Ranged)", "Members can now wear " + "" + "spinoleather chaps" + "" + " within Daemonheim. (They also need level 50 Ranged.)"); + case 113: + return newstruct cs2func_script_978_struct(50, 17205, "Members: Spinoleather vambraces (Tier 6)" + "
" + " (with 50 Ranged)", "Members can now wear " + "" + "spinoleather vambraces" + "" + " within Daemonheim. (They also need level 50 Ranged.)"); + case 114: + return newstruct cs2func_script_978_struct(50, 17307, "Members: Spinoleather boots (Tier 6)" + "
" + " (with 50 Ranged)", "Members can now wear " + "" + "spinoleather boots" + "" + " within Daemonheim. (They also need level 50 Ranged.)"); + case 115: + return newstruct cs2func_script_978_struct(54, 17271, "Members: Sorcerer's boots ", "Members can now wear " + "" + "sorcerer's boots" + "" + " within Daemonheim."); + case 116: + return newstruct cs2func_script_978_struct(57, 17281, "Members: Absorption boots" + "
" + " (with 57 Ranged) ", "Members can now wear " + "" + "absorption boots" + "" + " within Daemonheim. (They also need level 57 Ranged.)"); + case 117: + return newstruct cs2func_script_978_struct(60, 16703, "Members: Argonite full helm (Tier 7)", "Members can now wear " + "" + "argonite full helms" + "" + " within Daemonheim."); + case 118: + return newstruct cs2func_script_978_struct(60, 17251, "Members: Argonite platebody (Tier 7)", "Members can now wear " + "" + "argonite platebodies" + "" + " within Daemonheim."); + case 119: + return newstruct cs2func_script_978_struct(60, 16725, "Members: Argonite chainbody (Tier 7)", "Members can now wear " + "" + "argonite chainbodies" + "" + " within Daemonheim."); + case 120: + return newstruct cs2func_script_978_struct(60, 16681, "Members: Argonite platelegs (Tier 7)", "Members can now wear " + "" + "argonite platelegs" + "" + " within Daemonheim."); + case 121: + return newstruct cs2func_script_978_struct(60, 16659, "Members: Argonite plateskirt (Tier 7)", "Members can now wear " + "" + "argonite plateskirts" + "" + " within Daemonheim."); + case 122: + return newstruct cs2func_script_978_struct(60, 16285, "Members: Argonite gauntlets (Tier 7)", "Members can now wear " + "" + "argonite gauntlets" + "" + " within Daemonheim."); + case 123: + return newstruct cs2func_script_978_struct(60, 16351, "Members: Argonite boots (Tier 7)", "Members can now wear " + "" + "argonite boots" + "" + " within Daemonheim."); + case 124: + return newstruct cs2func_script_978_struct(60, 17353, "Members: Argonite kiteshield (Tier 7)", "Members can now wield " + "" + "argonite kiteshields" + "" + " within Daemonheim."); + case 125: + return newstruct cs2func_script_978_struct(60, 16747, "Members: Soulbell hood (Tier 7)" + "
" + " (with 60 Magic)", "Members can now wear " + "" + "soulbell hoods" + "" + " within Daemonheim. (They also need level 60 Magic.)"); + case 126: + return newstruct cs2func_script_978_struct(60, 17229, "Members: Soulbell robe top (Tier 7)" + "
" + " (with 60 Magic)", "Members can now wear " + "" + "soulbell robe tops" + "" + " within Daemonheim. (They also need level 60 Magic.)"); + case 127: + return newstruct cs2func_script_978_struct(60, 16857, "Members: Soulbell robe bottom (Tier 7)" + "
" + " (with 60 Magic)", "Members can now wear " + "" + "soulbell robe bottoms" + "" + " within Daemonheim. (They also need level 60 Magic.)"); + case 128: + return newstruct cs2func_script_978_struct(60, 17163, "Members: Soulbell gloves (Tier 7)" + "
" + " with 60 Magic)", "Members can now wear " + "" + "soulbell gloves" + "" + " within Daemonheim. (They also need level 60 Magic.)"); + case 129: + return newstruct cs2func_script_978_struct(60, 16923, "Members: Soulbell boots (Tier 7)" + "
" + " (with 60 Magic)", "Members can now wear " + "" + "soulbell boots" + "" + " within Daemonheim. (They also need level 60 Magic.)"); + case 130: + return newstruct cs2func_script_978_struct(60, 17053, "Members: Gallileather coif (Tier 7)" + "
" + " (with 60 Ranged)", "Members can now wear " + "" + "gallileather coifs" + "" + " within Daemonheim. (They also need level 60 Ranged.)"); + case 131: + return newstruct cs2func_script_978_struct(60, 17185, "Members: Gallileather body (Tier 7)" + "
" + " (with 60 Ranged)", "Members can now wear " + "" + "gallileather bodies" + "" + " within Daemonheim. (They also need level 60 Ranged.)"); + case 132: + return newstruct cs2func_script_978_struct(60, 17331, "Members: Gallileather chaps (Tier 7)" + "
" + " (with 60 Ranged)", "Members can now wear " + "" + "gallileather chaps" + "" + " within Daemonheim. (They also need level 60 Ranged.)"); + case 133: + return newstruct cs2func_script_978_struct(60, 17207, "Members: Gallileather vambraces (Tier 7)" + "
" + " (with 60 Ranged)", "Members can now wear " + "" + "gallileather vambraces" + "" + " within Daemonheim. (They also need level 60 Ranged.)"); + case 134: + return newstruct cs2func_script_978_struct(60, 17309, "Members: Gallileather boots (Tier 7)" + "
" + " (with 60 Ranged)", "Members can now wear " + "" + "gallileather boots" + "" + " within Daemonheim. (They also need level 60 Ranged.)"); + case 135: + return newstruct cs2func_script_978_struct(65, 17285, "Members: Protector's ward", "Members can now wield " + "" + "protector's wards" + "" + " within Daemonheim."); + case 136: + return newstruct cs2func_script_978_struct(70, 16705, "Members: Katagon full helm (Tier 8)", "Members can now wear " + "" + "katagon full helms" + "" + " within Daemonheim."); + case 137: + return newstruct cs2func_script_978_struct(70, 17253, "Members: Katagon platebody (Tier 8)", "Members can now wear " + "" + "katagon platebodies" + "" + " within Daemonheim."); + case 138: + return newstruct cs2func_script_978_struct(70, 16727, "Members: Katagon chainbody (Tier 8)", "Members can now wear " + "" + "katagon chainbodies" + "" + " within Daemonheim."); + case 139: + return newstruct cs2func_script_978_struct(70, 16683, "Members: Katagon platelegs (Tier 8)", "Members can now wear " + "" + "katagon platelegs" + "" + " within Daemonheim."); + case 140: + return newstruct cs2func_script_978_struct(70, 16661, "Members: Katagon plateskirt (Tier 8)", "Members can now wear " + "" + "katagon plateskirts" + "" + " within Daemonheim."); + case 141: + return newstruct cs2func_script_978_struct(70, 16287, "Members: Katagon gauntlets (Tier 8)", "Members can now wear " + "" + "katagon gauntlets" + "" + " within Daemonheim."); + case 142: + return newstruct cs2func_script_978_struct(70, 16353, "Members: Katagon boots (Tier 8)", "Members can now wear " + "" + "katagon boots" + "" + " within Daemonheim."); + case 143: + return newstruct cs2func_script_978_struct(70, 17355, "Members: Katagon kiteshield (Tier 8)", "Members can now wield " + "" + "katagon kiteshields" + "" + " within Daemonheim."); + case 144: + return newstruct cs2func_script_978_struct(70, 16749, "Members: Ectohood (Tier 8)" + "
" + " (with 70 Magic)", "Members can now wear " + "" + "ectohoods" + "" + " within Daemonheim. (They also need level 70 Magic.)"); + case 145: + return newstruct cs2func_script_978_struct(70, 17231, "Members: Ectorobe top (Tier 8)" + "
" + " (with 70 Magic)", "Members can now wear " + "" + "ectorobe tops" + "" + " within Daemonheim. (They also need level 70 Magic.)"); + case 146: + return newstruct cs2func_script_978_struct(70, 16859, "Members: Ectorobe bottom (Tier 8)" + "
" + " (with 70 Magic)", "Members can now wear " + "" + "ectorobe bottoms" + "" + " within Daemonheim. (They also need level 70 Magic.)"); + case 147: + return newstruct cs2func_script_978_struct(70, 17165, "Members: Ectogloves (Tier 8)" + "
" + " (with 70 Magic)", "Members can now wear " + "" + "ectogloves" + "" + " within Daemonheim. (They also need level 70 Magic.)"); + case 148: + return newstruct cs2func_script_978_struct(70, 16925, "Members: Ectoboots (Tier 8)" + "
" + " (with 70 Magic)", "Members can now wear " + "" + "ectoboots" + "" + " within Daemonheim. (They also need level 70 Magic.)"); + case 149: + return newstruct cs2func_script_978_struct(70, 17055, "Members: Stegoleather coif (Tier 8)" + "
" + " (with 70 Ranged)", "Members can now wear " + "" + "stegoleather coifs" + "" + " within Daemonheim. (They also need level 70 Ranged.)"); + case 150: + return newstruct cs2func_script_978_struct(70, 17187, "Members: Stegoleather body (Tier 8)" + "
" + " (with 70 Ranged)", "Members can now wear " + "" + "stegoleather bodies" + "" + " within Daemonheim. (They also need level 70 Ranged.)"); + case 151: + return newstruct cs2func_script_978_struct(70, 17333, "Members: Stegoleather chaps (Tier 8)" + "
" + " (with 70 Ranged)", "Members can now wear " + "" + "stegoleather chaps" + "" + " within Daemonheim. (They also need level 70 Ranged.)"); + case 152: + return newstruct cs2func_script_978_struct(70, 17209, "Members: Stegoleather vambraces (Tier 8)" + "
" + " (with 70 Ranged)", "Members can now wear " + "" + "stegoleather vambraces" + "" + " within Daemonheim. (They also need level 70 Ranged.)"); + case 153: + return newstruct cs2func_script_978_struct(70, 17311, "Members: Stegoleather boots (Tier 8)" + "
" + " (with 70 Ranged)", "Members can now wear " + "" + "stegoleather boots" + "" + " within Daemonheim. (They also need level 70 Ranged.)"); + case 154: + return newstruct cs2func_script_978_struct(80, 16707, "Members: Gorgonite full helm (Tier 9)", "Members can now wear " + "" + "gorgonite full helms" + "" + " within Daemonheim."); + case 155: + return newstruct cs2func_script_978_struct(80, 17255, "Members: Gorgonite platebody (Tier 9)", "Members can now wear " + "" + "gorgonite platebodies" + "" + " within Daemonheim."); + case 156: + return newstruct cs2func_script_978_struct(80, 16729, "Members: Gorgonite chainbody (Tier 9)", "Members can now wear " + "" + "gorgonite chainbodies" + "" + " within Daemonheim."); + case 157: + return newstruct cs2func_script_978_struct(80, 16685, "Members: Gorgonite platelegs (Tier 9)", "Members can now wear " + "" + "gorgonite platelegs" + "" + " within Daemonheim."); + case 158: + return newstruct cs2func_script_978_struct(80, 16663, "Members: Gorgonite plateskirt (Tier 9)", "Members can now wear " + "" + "gorgonite plateskirts" + "" + " within Daemonheim."); + case 159: + return newstruct cs2func_script_978_struct(80, 16289, "Members: Gorgonite gauntlets (Tier 9)", "Members can now wear " + "" + "gorgonite gauntlets" + "" + " within Daemonheim."); + case 160: + return newstruct cs2func_script_978_struct(80, 16355, "Members: Gorgonite boots (Tier 9)", "Members can now wear " + "" + "gorgonite boots" + "" + " within Daemonheim."); + case 161: + return newstruct cs2func_script_978_struct(80, 17357, "Members: Gorgonite kiteshield (Tier 9)", "Members can now wield " + "" + "gorgonite kiteshields" + "" + " within Daemonheim."); + case 162: + return newstruct cs2func_script_978_struct(80, 16751, "Members: Runic hood (Tier 9)" + "
" + " (with 80 Magic)", "Members can now wear " + "" + "runic hoods" + "" + " within Daemonheim. (They also need level 80 Magic.)"); + case 163: + return newstruct cs2func_script_978_struct(80, 17233, "Members: Runic robe top (Tier 9)" + "
" + " (with 80 Magic)", "Members can now wear " + "" + "runic robe tops" + "" + " within Daemonheim. (They also need level 80 Magic.)"); + case 164: + return newstruct cs2func_script_978_struct(80, 16861, "Members: Runic robe bottom (Tier 9)" + "
" + " (with 80 Magic)", "Members can now wear " + "" + "runic robe bottoms" + "" + " within Daemonheim. (They also need level 80 Magic.)"); + case 165: + return newstruct cs2func_script_978_struct(80, 17167, "Members: Runic gloves (Tier 9)" + "
" + " (with 80 Magic)", "Members can now wear " + "" + "runic gloves" + "" + " within Daemonheim. (They also need level 80 Magic.)"); + case 166: + return newstruct cs2func_script_978_struct(80, 16927, "Members: Runic boots (Tier 9)" + "
" + " (with 80 Magic)", "Members can now wear " + "" + "runic boots" + "" + " within Daemonheim. (They also need level 80 Magic.)"); + case 167: + return newstruct cs2func_script_978_struct(80, 17057, "Members: Megaleather coif (Tier 9)" + "
" + " (with 80 Ranged)", "Members can now wear " + "" + "megaleather coifs" + "" + " within Daemonheim. (They also need level 80 Ranged.)"); + case 168: + return newstruct cs2func_script_978_struct(80, 17189, "Members: Megaleather body (Tier 9)" + "
" + " (with 80 Ranged)", "Members can now wear " + "" + "megaleather bodies" + "" + " within Daemonheim. (They also need level 80 Ranged.)"); + case 169: + return newstruct cs2func_script_978_struct(80, 17335, "Members: Megaleather chaps (Tier 9)" + "
" + " (with 80 Ranged)", "Members can now wear " + "" + "megaleather chaps" + "" + " within Daemonheim. (They also need level 80 Ranged.)"); + case 170: + return newstruct cs2func_script_978_struct(80, 17211, "Members: Megaleather vambraces (Tier 9)" + "
" + " (with 80 Ranged)", "Members can now wear " + "" + "megaleather vambraces" + "" + " within Daemonheim. (They also need level 80 Ranged.)"); + case 171: + return newstruct cs2func_script_978_struct(80, 17313, "Members: Megaleather boots (Tier 9)" + "
" + " (with 80 Ranged)", "Members can now wear " + "" + "megaleather boots" + "" + " within Daemonheim. (They also need level 80 Ranged.)"); + case 172: + return newstruct cs2func_script_978_struct(83, 17283, "Members: Grounding boots" + "
" + " (with 83 Ranged) ", "Members can now wear " + "" + "grounding boots" + "" + " within Daemonheim. (They also need level 83 Ranged.)"); + case 173: + return newstruct cs2func_script_978_struct(90, 16709, "Members: Promethium full helm (Tier 10)", "Members can now wear " + "" + "promethium full helms" + "" + " within Daemonheim."); + case 174: + return newstruct cs2func_script_978_struct(90, 17257, "Members: Promethium platebody (Tier 10)", "Members can now wear " + "" + "promethium platebodies" + "" + " within Daemonheim."); + case 175: + return newstruct cs2func_script_978_struct(90, 16731, "Members: Promethium chainbody (Tier 10)", "Members can now wear " + "" + "promethium chainbodies" + "" + " within Daemonheim."); + case 176: + return newstruct cs2func_script_978_struct(90, 16687, "Members: Promethium platelegs (Tier 10)", "Members can now wear " + "" + "promethium platelegs" + "" + " within Daemonheim."); + case 177: + return newstruct cs2func_script_978_struct(90, 16665, "Members: Promethium plateskirt (Tier 10)", "Members can now wear " + "" + "promethium plateskirts" + "" + " within Daemonheim."); + case 178: + return newstruct cs2func_script_978_struct(90, 16291, "Members: Promethium gauntlets (Tier 10)", "Members can now wear " + "" + "promethium gauntlets" + "" + " within Daemonheim."); + case 179: + return newstruct cs2func_script_978_struct(90, 16357, "Members: Promethium boots (Tier 10)", "Members can now wear " + "" + "promethium boots" + "" + " within Daemonheim."); + case 180: + return newstruct cs2func_script_978_struct(90, 17359, "Members: Promethium kiteshield (Tier 10)", "Members can now wield " + "" + "promethium kiteshields" + "" + " within Daemonheim."); + case 181: + return newstruct cs2func_script_978_struct(90, 16753, "Members: Spiritbloom hood (Tier 10)" + "
" + " (with 90 Magic)", "Members can now wear " + "" + "spiritbloom hoods" + "" + " within Daemonheim. (They also need level 90 Magic.)"); + case 182: + return newstruct cs2func_script_978_struct(90, 17235, "Members: Spiritbloom robe top (Tier 10)" + "
" + " (with 90 Magic)", "Members can now wear " + "" + "spiritbloom robe tops" + "" + " within Daemonheim. (They also need level 90 Magic.)"); + case 183: + return newstruct cs2func_script_978_struct(90, 16863, "Members: Spiritbloom robe bottom (Tier 10)" + "
" + " (with 90 Magic)", "Members can now wear " + "" + "spiritbloom robe bottoms" + "" + " within Daemonheim. (They also need level 90 Magic.)"); + case 184: + return newstruct cs2func_script_978_struct(90, 17169, "Members: Spiritbloom gloves (Tier 10)" + "
" + " (with 90 Magic)", "Members can now wear " + "" + "spiritbloom gloves" + "" + " within Daemonheim. (They also need level 90 Magic.)"); + case 185: + return newstruct cs2func_script_978_struct(90, 16929, "Members: Spiritbloom boots (Tier 10)" + "
" + " (with 90 Magic)", "Members can now wear " + "" + "spiritbloom boots" + "" + " within Daemonheim. (They also need level 90 Magic.)"); + case 186: + return newstruct cs2func_script_978_struct(90, 17059, "Members: Tyrannoleather coif (Tier 10)" + "
" + " (with 90 Ranged)", "Members can now wear " + "" + "tyrannoleather coifs" + "" + " within Daemonheim. (They also need level 90 Ranged.)"); + case 187: + return newstruct cs2func_script_978_struct(90, 17191, "Members: Tyrannoleather body (Tier 10)" + "
" + " (with 90 Ranged)", "Members can now wear " + "" + "tyrannoleather bodies" + "" + " within Daemonheim. (They also need level 90 Ranged.)"); + case 188: + return newstruct cs2func_script_978_struct(90, 17337, "Members: Tyrannoleather chaps (Tier 10)" + "
" + " (with 90 Ranged)", "Members can now wear " + "" + "tyrannoleather chaps" + "" + " within Daemonheim. (They also need level 90 Ranged.)"); + case 189: + return newstruct cs2func_script_978_struct(90, 17213, "Members: Tyrannoleather vambraces (Tier 10)" + "
" + " (with 90 Ranged)", "Members can now wear " + "" + "tyrannoleather vambraces" + "" + " within Daemonheim. (They also need level 90 Ranged.)"); + case 190: + return newstruct cs2func_script_978_struct(90, 17315, "Members: Tyrannoleather boots (Tier 10)" + "
" + " (with 90 Ranged)", "Members can now wear " + "" + "tyrannoleather boots" + "" + " within Daemonheim. (They also need level 90 Ranged.)"); + case 191: + return newstruct cs2func_script_978_struct(94, 17287, "Members: Guardian's ward ", "Members can now wield " + "" + "guardian's wards" + "" + " within Daemonheim."); + case 192: + return newstruct cs2func_script_978_struct(99, 16711, "Members: Primal full helm (Tier 11)", "Members can now wear " + "" + "primal full helms" + "" + " within Daemonheim."); + case 193: + return newstruct cs2func_script_978_struct(99, 17259, "Members: Primal platebody (Tier 11)", "Members can now wear " + "" + "primal platebodies" + "" + " within Daemonheim."); + case 194: + return newstruct cs2func_script_978_struct(99, 16733, "Members: Primal chainbody (Tier 11)", "Members can now wear " + "" + "primal chainbodies" + "" + " within Daemonheim."); + case 195: + return newstruct cs2func_script_978_struct(99, 16689, "Members: Primal platelegs (Tier 11)", "Members can now wear " + "" + "primal platelegs" + "" + " within Daemonheim."); + case 196: + return newstruct cs2func_script_978_struct(99, 16667, "Members: Primal plateskirt (Tier 11)", "Members can now wear " + "" + "primal plateskirts" + "" + " within Daemonheim."); + case 197: + return newstruct cs2func_script_978_struct(99, 16293, "Members: Primal gauntlets (Tier 11)", "Members can now wear " + "" + "primal gauntlets" + "" + " within Daemonheim."); + case 198: + return newstruct cs2func_script_978_struct(99, 16359, "Members: Primal boots (Tier 11)", "Members can now wear " + "" + "primal boots" + "" + " within Daemonheim."); + case 199: + return newstruct cs2func_script_978_struct(99, 17361, "Members: Primal kiteshield (Tier 11)", "Members can now wield " + "" + "primal kiteshields" + "" + " within Daemonheim."); + case 200: + return newstruct cs2func_script_978_struct(99, 16755, "Members: Celestial hood (Tier 11)" + "
" + " (with 99 Magic)", "Members can now wear " + "" + "celestial hoods" + "" + " within Daemonheim. (They also need level 99 Magic.)"); + case 201: + return newstruct cs2func_script_978_struct(99, 17237, "Members: Celestial robe top (Tier 11)" + "
" + " (with 99 Magic)", "Members can now wear " + "" + "celestial robe tops" + "" + " within Daemonheim. (They also need level 99 Magic.)"); + case 202: + return newstruct cs2func_script_978_struct(99, 16865, "Members: Celestial robe bottom (Tier 11)" + "
" + " (with 99 Magic)", "Members can now wear " + "" + "celestial robe bottoms" + "" + " within Daemonheim. (They also need level 99 Magic.)"); + case 203: + return newstruct cs2func_script_978_struct(99, 17171, "Members: Celestial gloves (Tier 11)" + "
" + " (with 99 Magic)", "Members can now wear " + "" + "celestial gloves" + "" + " within Daemonheim. (They also need level 99 Magic.)"); + case 204: + return newstruct cs2func_script_978_struct(99, 16931, "Members: Celestial boots (Tier 11)" + "
" + " (with 99 Magic)", "Members can now wear " + "" + "celestial boots" + "" + " within Daemonheim. (They also need level 99 Magic.)"); + case 205: + return newstruct cs2func_script_978_struct(99, 17061, "Members: Sagittarian coif (Tier 11)" + "
" + " (with 99 Ranged)", "Members can now wear " + "" + "sagittarian coifs" + "" + " within Daemonheim. (They also need level 99 Ranged.)"); + case 206: + return newstruct cs2func_script_978_struct(99, 17193, "Members: Sagittarian body (Tier 11)" + "
" + " (with 99 Ranged)", "Members can now wear " + "" + "sagittarian bodies" + "" + " within Daemonheim. (They also need level 99 Ranged.)"); + case 207: + return newstruct cs2func_script_978_struct(99, 17339, "Members: Sagittarian chaps (Tier 11)" + "
" + " (with 99 Ranged)", "Members can now wear " + "" + "sagittarian chaps" + "" + " within Daemonheim. (They also need level 99 Ranged.)"); + case 208: + return newstruct cs2func_script_978_struct(99, 17215, "Members: Sagittarian vambraces (Tier 11)" + "
" + " (with 99 Ranged)", "Members can now wear " + "" + "sagittarian vambraces" + "" + " within Daemonheim. (They also need level 99 Ranged.)"); + case 209: + return newstruct cs2func_script_978_struct(99, 17317, "Members: Sagittarian boots (Tier 11)" + "
" + " (with 99 Ranged)", "Members can now wear " + "" + "sagittarian boots" + "" + " within Daemonheim. (They also need level 99 Ranged.)"); + } + break; + case 14: + if (((boolean)arg1)) { + return newstruct cs2func_script_978_struct(99, 9753, "Skill mastery", "" + "Congratulations! You are now a master of " + "" + "Defence" + "" + ". Members can visit the " + "" + "Melee Instructor" + "" + " in " + "" + "Lumbridge" + "" + ". He has something special that is only available to true masters of the " + "" + "Defence" + "" + " skill!"); + } + } + return newstruct cs2func_script_978_struct(0, -1, "", ""); +} diff --git a/dumps/scripts/979.cs2 b/dumps/scripts/979.cs2 new file mode 100644 index 0000000..a017417 --- /dev/null +++ b/dumps/scripts/979.cs2 @@ -0,0 +1,23 @@ +cs2func_script_979_struct(1,1,0) script_979(int arg0) { + switch (arg0) { + case 0: + return newstruct cs2func_script_979_struct(1, "Arrows"); + case 1: + return newstruct cs2func_script_979_struct(1, "Bows"); + case 2: + return newstruct cs2func_script_979_struct(1, "Bolts"); + case 3: + return newstruct cs2func_script_979_struct(1, "Darts"); + case 4: + return newstruct cs2func_script_979_struct(1, "Crossbows"); + case 5: + return newstruct cs2func_script_979_struct(1, "Other"); + case 6: + return newstruct cs2func_script_979_struct(1, "Minigames"); + case 7: + return newstruct cs2func_script_979_struct(1, "Dungeoneering"); + case 8: + return newstruct cs2func_script_979_struct(1, "Milestones"); + } + return newstruct cs2func_script_979_struct(-1, ""); +} diff --git a/dumps/scripts/98.cs2 b/dumps/scripts/98.cs2 new file mode 100644 index 0000000..37c04a2 --- /dev/null +++ b/dumps/scripts/98.cs2 @@ -0,0 +1,8 @@ +void script_98(int arg0,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6) { + createExtraChild(new WidgetPointer(arg0), 5, arg1); + setWidgetPosition(arg3, arg4, 0, 0); + setWidgetSize(arg5, arg6, 0, 0); + setWidgetSprite(arg2); + cs2method1107(1); + return; +} diff --git a/dumps/scripts/980.cs2 b/dumps/scripts/980.cs2 new file mode 100644 index 0000000..aa068e1 --- /dev/null +++ b/dumps/scripts/980.cs2 @@ -0,0 +1,359 @@ +cs2func_script_980_struct(2,2,0) script_980(int arg0,int arg1) { + switch (arg0) { + case 0: + switch (arg1) { + case 0: + return newstruct cs2func_script_980_struct(1, 882, "Bronze arrow", "You can now fletch " + "" + "bronze arrows" + "" + "."); + case 1: + return newstruct cs2func_script_980_struct(5, 2866, "Ogre arrow" + "
" + " (after starting Big Chompy Bird Hunting)", "You now have the Fletching level required to fletch " + "" + "ogre arrows" + "" + " (after starting Big Chompy Bird Hunting)."); + case 2: + return newstruct cs2func_script_980_struct(7, 4773, "Bronze 'brutal' arrow" + "
" + " (after starting Zogre Flesh Eaters)", "You now have the Fletching level required to fletch " + "" + "bronze 'brutal' arrows" + "" + " (after starting Zogre Flesh Eaters)."); + case 3: + return newstruct cs2func_script_980_struct(15, 884, "Iron arrow", "You can now fletch " + "" + "iron arrows" + "" + "."); + case 4: + return newstruct cs2func_script_980_struct(18, 4778, "Iron 'brutal' arrow" + "
" + " (after starting Zogre Flesh Eaters)", "You now have the Fletching level required to fletch " + "" + "iron 'brutal' arrows" + "" + " (after starting Zogre Flesh Eaters)."); + case 5: + return newstruct cs2func_script_980_struct(30, 886, "Steel arrow", "You can now fletch " + "" + "steel arrows" + "" + "."); + case 6: + return newstruct cs2func_script_980_struct(33, 4783, "Steel 'brutal' arrow" + "
" + " (after starting Zogre Flesh Eaters)", "You now have the Fletching level required to fletch " + "" + "steel 'brutal' arrows" + "" + " (after starting Zogre Flesh Eaters)."); + case 7: + return newstruct cs2func_script_980_struct(38, 4788, "Black 'brutal' arrow" + "
" + " (after starting Zogre Flesh Eaters)", "You now have the Fletching level required to fletch " + "" + "black 'brutal' arrows" + "" + " (after starting Zogre Flesh Eaters)."); + case 8: + return newstruct cs2func_script_980_struct(45, 888, "Mithril arrow", "You can now fletch " + "" + "mithril arrows" + "" + "."); + case 9: + return newstruct cs2func_script_980_struct(49, 4793, "Mithril 'brutal' arrow" + "
" + " (after starting Zogre Flesh Eaters)", "You now have the Fletching level required to fletch " + "" + "mithril 'brutal' arrows" + "" + " (after starting Zogre Flesh Eaters)."); + case 10: + return newstruct cs2func_script_980_struct(52, 13278, "Broad leaf arrows" + "
" + " (after Smoking Kills)", "You can now fletch " + "" + "broad leaf arrows" + "" + " (after Smoking Kills)."); + case 11: + return newstruct cs2func_script_980_struct(60, 890, "Adamant arrow", "You can now fletch " + "" + "adamant arrows" + "" + "."); + case 12: + return newstruct cs2func_script_980_struct(62, 4798, "Adamant 'brutal' arrow" + "
" + " (after starting Zogre Flesh Eaters)", "You now have the Fletching level required to fletch " + "" + "adamant 'brutal' arrows" + "" + " (after starting Zogre Flesh Eaters)."); + case 13: + return newstruct cs2func_script_980_struct(75, 892, "Rune arrow", "You can now fletch " + "" + "rune arrows" + "" + "."); + case 14: + return newstruct cs2func_script_980_struct(76, 21640, "Dragonbane arrows (after Ritual of the Mahjarrat)", "You can now fletch " + "" + "dragonbane arrowtips" + "" + " (after Ritual of the Mahjarrat)."); + case 15: + return newstruct cs2func_script_980_struct(76, 21645, "Wallasalkibane arrows (after Ritual of the Mahjarrat)", "You can now fletch " + "" + "wallasalkibane arrowtips" + "" + " (after Ritual of the Mahjarrat)."); + case 16: + return newstruct cs2func_script_980_struct(76, 21650, "Basiliskbane arrows (after Ritual of the Mahjarrat)", "You can now fletch " + "" + "basiliskbane arrowtips" + "" + " (after Ritual of the Mahjarrat)."); + case 17: + return newstruct cs2func_script_980_struct(76, 21655, "Abyssalbane arrows (after Ritual of the Mahjarrat)", "You can now fletch " + "" + "abyssalbane arrowtips" + "" + " (after Ritual of the Mahjarrat)."); + case 18: + return newstruct cs2func_script_980_struct(77, 4803, "Rune 'brutal' arrow" + "
" + " (after starting Zogre Flesh Eaters)", "You now have the Fletching level required to fletch " + "" + "rune 'brutal' arrows" + "" + " (after starting Zogre Flesh Eaters)."); + case 19: + return newstruct cs2func_script_980_struct(90, 11212, "Dragon arrow", "You can now fletch " + "" + "dragon arrows" + "" + "."); + } + break; + case 1: + switch (arg1) { + case 0: + return newstruct cs2func_script_980_struct(5, 841, "Shortbow", "You can now fletch " + "" + "shortbows" + "" + "."); + case 1: + return newstruct cs2func_script_980_struct(10, 839, "Longbow", "You can now fletch " + "" + "longbows" + "" + "."); + case 2: + return newstruct cs2func_script_980_struct(20, 843, "Oak shortbow", "You can now fletch " + "" + "oak shortbows" + "" + "."); + case 3: + return newstruct cs2func_script_980_struct(25, 845, "Oak longbow", "You can now fletch " + "" + "oak longbows" + "" + "."); + case 4: + return newstruct cs2func_script_980_struct(30, 4827, "Ogre composite bow" + "
" + " (after starting Zogre Flesh Eaters)", "You now have the Fletching level required to fletch " + "" + "ogre composite bows" + "" + " (after starting Zogre Flesh Eaters)."); + case 5: + return newstruct cs2func_script_980_struct(35, 849, "Willow shortbow", "You can now fletch " + "" + "willow shortbows" + "" + "."); + case 6: + return newstruct cs2func_script_980_struct(40, 847, "Willow longbow", "You can now fletch " + "" + "willow longbows" + "" + "."); + case 7: + return newstruct cs2func_script_980_struct(50, 853, "Maple shortbow", "You can now fletch " + "" + "maple shortbows" + "" + "."); + case 8: + return newstruct cs2func_script_980_struct(55, 851, "Maple longbow", "You can now fletch " + "" + "maple longbows" + "" + "."); + case 9: + return newstruct cs2func_script_980_struct(65, 857, "Yew shortbow", "You can now fletch " + "" + "yew shortbows" + "" + "."); + case 10: + return newstruct cs2func_script_980_struct(70, 855, "Yew longbow", "You can now fletch " + "" + "yew longbows" + "" + "."); + case 11: + return newstruct cs2func_script_980_struct(80, 861, "Magic shortbow", "You can now fletch " + "" + "magic shortbows" + "" + "."); + case 12: + return newstruct cs2func_script_980_struct(85, 859, "Magic longbow", "You can now fletch " + "" + "magic longbows" + "" + "."); + } + break; + case 2: + switch (arg1) { + case 0: + return newstruct cs2func_script_980_struct(9, 877, "Bronze bolt", "You can now fletch " + "" + "bronze bolts" + "" + "."); + case 1: + return newstruct cs2func_script_980_struct(11, 879, "Opal-tipped bronze bolt", "You can now fletch " + "" + "opal-tipped bronze bolts" + "" + "."); + case 2: + return newstruct cs2func_script_980_struct(24, 9139, "Blurite bolt" + "
" + " (after The Knight's Sword)", "You now have the Fletching level required to fletch " + "" + "blurite bolts" + "" + " (after The Knight's Sword)."); + case 3: + return newstruct cs2func_script_980_struct(26, 9335, "Jade-tipped blurite bolt" + "
" + " (after The Knight's Sword)", "You now have the Fletching level required to fletch " + "" + "jade-tipped blurite bolts" + "" + " (after The Knight's Sword)."); + case 4: + return newstruct cs2func_script_980_struct(32, 10158, "Kebbit-tipped hunting bolt", "You can now fletch " + "" + "kebbit-tipped hunting bolts" + "" + "."); + case 5: + return newstruct cs2func_script_980_struct(39, 9140, "Iron bolt", "You can now fletch " + "" + "iron bolts" + "" + "."); + case 6: + return newstruct cs2func_script_980_struct(41, 880, "Pearl-tipped iron bolt", "You can now fletch " + "" + "pearl-tipped iron bolts" + "" + "."); + case 7: + return newstruct cs2func_script_980_struct(42, 10159, "Long kebbit-tipped hunting bolt", "You can now fletch " + "" + "long kebbit-tipped hunting bolts" + "" + "."); + case 8: + return newstruct cs2func_script_980_struct(43, 9145, "Silver bolt", "You can now fletch " + "" + "silver bolts" + "" + "."); + case 9: + return newstruct cs2func_script_980_struct(46, 9141, "Steel bolt", "You can now fletch " + "" + "steel bolts" + "" + "."); + case 10: + return newstruct cs2func_script_980_struct(48, 9336, "Red topaz-tipped steel bolt", "You can now fletch " + "" + "red topaz-tipped steel bolts" + "" + "."); + case 11: + return newstruct cs2func_script_980_struct(51, 881, "Barbed bolts", "You can now fletch " + "" + "barbed bolts" + "" + "."); + case 12: + return newstruct cs2func_script_980_struct(54, 9142, "Mithril bolt", "You can now fletch " + "" + "mithril bolts" + "" + "."); + case 13: + return newstruct cs2func_script_980_struct(55, 13279, "Broad leaf bolts" + "
" + " (after Smoking Kills)", "You can now fletch " + "" + "broad leaf bolts" + "" + " (after Smoking Kills)."); + case 14: + return newstruct cs2func_script_980_struct(56, 9337, "Sapphire-tipped mithril bolt", "You can now fletch " + "" + "sapphire-tipped mithril bolts" + "" + "."); + case 15: + return newstruct cs2func_script_980_struct(58, 9338, "Emerald-tipped mithril bolt", "You can now fletch " + "" + "emerald-tipped mithril bolts" + "" + "."); + case 16: + return newstruct cs2func_script_980_struct(59, 9418, "Mithril grapple-tipped bolt", "You can now fletch " + "" + "mithril grapple-tipped bolts" + "" + "."); + case 17: + return newstruct cs2func_script_980_struct(61, 9143, "Adamantite bolt", "You can now fletch " + "" + "adamantite bolts" + "" + "."); + case 18: + return newstruct cs2func_script_980_struct(63, 9339, "Ruby-tipped adamantite bolt", "You can now fletch " + "" + "ruby-tipped adamantite bolts" + "" + "."); + case 19: + return newstruct cs2func_script_980_struct(65, 9340, "Diamond-tipped adamantite bolt", "You can now fletch " + "" + "diamond-tipped adamantite bolts" + "" + "."); + case 20: + return newstruct cs2func_script_980_struct(69, 9144, "Runite bolt", "You can now fletch " + "" + "runite bolts" + "" + "."); + case 21: + return newstruct cs2func_script_980_struct(71, 9341, "Dragonstone-tipped runite bolt", "You can now fletch " + "" + "dragonstone-tipped runite bolts" + "" + "."); + case 22: + return newstruct cs2func_script_980_struct(73, 9342, "Onyx-tipped runite bolt", "You can now fletch " + "" + "onyx-tipped runite bolts" + "" + "."); + case 23: + return newstruct cs2func_script_980_struct(80, 21660, "Dragonbane bolts (after Ritual of the Mahjarrat)", "You can now fletch " + "" + "dragonbane bolts" + "" + " (after Ritual of the Mahjarrat)."); + case 24: + return newstruct cs2func_script_980_struct(80, 21665, "Wallasalkibane bolts (after Ritual of the Mahjarrat)", "You can now fletch " + "" + "wallasalkibane bolts" + "" + " (after Ritual of the Mahjarrat)."); + case 25: + return newstruct cs2func_script_980_struct(80, 21670, "Basiliskbane bolts (after Ritual of the Mahjarrat)", "You can now fletch " + "" + "basiliskbane bolts" + "" + " (after Ritual of the Mahjarrat)."); + case 26: + return newstruct cs2func_script_980_struct(80, 21675, "Abyssalbane bolts (after Ritual of the Mahjarrat)", "You can now fletch " + "" + "abyssalbane bolts" + "" + " (after Ritual of the Mahjarrat)."); + } + break; + case 3: + switch (arg1) { + case 0: + return newstruct cs2func_script_980_struct(1, 806, "Bronze dart", "You can now fletch " + "" + "bronze darts" + "" + "."); + case 1: + return newstruct cs2func_script_980_struct(22, 807, "Iron dart", "You can now fletch " + "" + "iron darts" + "" + "."); + case 2: + return newstruct cs2func_script_980_struct(37, 808, "Steel dart", "You can now fletch " + "" + "steel darts" + "" + "."); + case 3: + return newstruct cs2func_script_980_struct(52, 809, "Mithril dart", "You can now fletch " + "" + "mithril darts" + "" + "."); + case 4: + return newstruct cs2func_script_980_struct(67, 810, "Adamant dart", "You can now fletch " + "" + "adamant darts" + "" + "."); + case 5: + return newstruct cs2func_script_980_struct(70, 21581, "Blisterwood stake", "You can now fletch " + "" + "blisterwood stakes" + "" + " (after The Branches of Darkmeyer)."); + case 6: + return newstruct cs2func_script_980_struct(81, 811, "Rune dart", "You can now fletch " + "" + "rune darts" + "" + "."); + case 7: + return newstruct cs2func_script_980_struct(95, 11230, "Dragon dart", "You can now fletch " + "" + "dragon darts" + "" + "."); + } + break; + case 4: + switch (arg1) { + case 0: + return newstruct cs2func_script_980_struct(9, 9440, "Bronze/wooden crossbow", "You can now fletch " + "" + "bronze and wooden crossbows" + "" + "."); + case 1: + return newstruct cs2func_script_980_struct(24, 9442, "Blurite/oak crossbow" + "
" + " (after The Knight's Sword)", "You now have the Fletching level required to fletch " + "" + "blurite and oak crossbows" + "" + " (after The Knight's Sword)."); + case 2: + return newstruct cs2func_script_980_struct(39, 9444, "Iron/willow crossbow", "You can now fletch " + "" + "iron and willow crossbows" + "" + "."); + case 3: + return newstruct cs2func_script_980_struct(46, 9446, "Steel/teak crossbow", "You can now fletch " + "" + "steel and teak crossbows" + "" + "."); + case 4: + return newstruct cs2func_script_980_struct(54, 9448, "Mithril/maple crossbow", "You can now fletch " + "" + "mithril and maple crossbows" + "" + "."); + case 5: + return newstruct cs2func_script_980_struct(61, 9450, "Adamantite/mahogany crossbow", "You can now fletch " + "" + "adamantite and mahogany crossbows" + "" + "."); + case 6: + return newstruct cs2func_script_980_struct(69, 9452, "Runite/yew crossbow", "You can now fletch " + "" + "runite and yew crossbows" + "" + "."); + } + break; + case 5: + switch (arg1) { + case 0: + return newstruct cs2func_script_980_struct(70, 21580, "Blisterwood staff", "You can now fletch " + "" + "blisterwood staves" + "" + " (after the Branches of Darkmeyer)."); + case 1: + return newstruct cs2func_script_980_struct(70, 21582, "Blisterwood polearm", "You can now fletch " + "" + "blisterwood polearms" + "" + " (after the Branches of Darkmeyer)."); + case 2: + return newstruct cs2func_script_980_struct(83, 21364, "Sagaie", "You can now fletch " + "" + "sagaies" + "" + "."); + case 3: + return newstruct cs2func_script_980_struct(87, 21365, "Bolas", "You can now fletch " + "" + "bolas" + "" + "."); + case 4: + return newstruct cs2func_script_980_struct(91, 18778, "Starved ancient effigies", "You can now investigate " + "" + "starved ancient effigies" + "" + " using your knowledge of Fletching."); + case 5: + return newstruct cs2func_script_980_struct(93, 18779, "Nourished ancient effigies", "You can now investigate " + "" + "nourished ancient effigies" + "" + " using your knowledge of Fletching."); + case 6: + return newstruct cs2func_script_980_struct(95, 18780, "Sated ancient effigies", "You can now investigate " + "" + "sated ancient effigies" + "" + " using your knowledge of Fletching."); + case 7: + return newstruct cs2func_script_980_struct(97, 18781, "Gorged ancient effigies", "You can now investigate " + "" + "gorged ancient effigies" + "" + " using your knowledge of Fletching."); + } + break; + case 6: + switch (arg1) { + case 0: + return newstruct cs2func_script_980_struct(1, 14192, "Stealing Creation - class 1 bow", "Members can now fletch " + "" + "class 1 bows" + "" + " in Stealing Creation."); + case 1: + return newstruct cs2func_script_980_struct(1, 14202, "Stealing Creation - class 1 arrow", "You can now fletch " + "" + "class 1 arrows" + "" + " in Stealing Creation."); + case 2: + return newstruct cs2func_script_980_struct(20, 14194, "Stealing Creation - class 2 bow", "Members can now fletch " + "" + "class 2 bows" + "" + " in Stealing Creation."); + case 3: + return newstruct cs2func_script_980_struct(20, 14203, "Stealing Creation - class 2 arrow", "You can now fletch " + "" + "class 2 arrows" + "" + " in Stealing Creation."); + case 4: + return newstruct cs2func_script_980_struct(40, 14196, "Stealing Creation - class 3 bow", "Members can now fletch " + "" + "class 3 bows" + "" + " in Stealing Creation."); + case 5: + return newstruct cs2func_script_980_struct(40, 14204, "Stealing Creation - class 3 arrow", "You can now fletch " + "" + "class 3 arrows" + "" + " in Stealing Creation."); + case 6: + return newstruct cs2func_script_980_struct(53, 14611, "Phoenix lair - cinnamon weaving ribbon", "Members can now fletch " + "" + "cinnamon weaving ribbon" + "" + " in the phoenix lair."); + case 7: + return newstruct cs2func_script_980_struct(53, 14612, "Phoenix lair - sassafras weaving ribbon", "Members can now fletch " + "" + "sassafras weaving ribbon" + "" + " in the phoenix lair."); + case 8: + return newstruct cs2func_script_980_struct(53, 14613, "Phoenix lair - ailanthus weaving ribbon", "Members can now fletch " + "" + "ailanthus weaving ribbon" + "" + " in the phoenix lair."); + case 9: + return newstruct cs2func_script_980_struct(53, 14614, "Phoenix lair - cedar weaving ribbon", "Members can now fletch " + "" + "cedar weaving ribbon" + "" + " in the phoenix lair."); + case 10: + return newstruct cs2func_script_980_struct(53, 14615, "Phoenix lair - mastic weaving ribbon", "Members can now fletch " + "" + "mastic weaving ribbon" + "" + " in the phoenix lair."); + case 11: + return newstruct cs2func_script_980_struct(60, 14198, "Stealing Creation - class 4 bow", "Members can now fletch " + "" + "class 4 bows" + "" + " in Stealing Creation."); + case 12: + return newstruct cs2func_script_980_struct(60, 14205, "Stealing Creation - class 4 arrow", "You can now fletch " + "" + "class 4 arrows" + "" + " in Stealing Creation."); + case 13: + return newstruct cs2func_script_980_struct(80, 14200, "Stealing Creation - class 5 bow", "Members can now fletch " + "" + "class 5 bows" + "" + " in Stealing Creation."); + case 14: + return newstruct cs2func_script_980_struct(80, 14206, "Stealing Creation - class 5 arrow", "You can now fletch " + "" + "class 5 arrows" + "" + " in Stealing Creation."); + } + break; + case 7: + switch (arg1) { + case 0: + return newstruct cs2func_script_980_struct(-1, 15707, "Dungeoneering skill tasks" + "
" + "As your Fletching level increases, you will be able to attempt higher-level fletching tasks within Daemonheim. You will also be more likely to succeed when attempting fletching tasks within Daemonheim.", ""); + case 1: + return newstruct cs2func_script_980_struct(1, 17742, "Tangle gum" + "
" + " 15 Arrow shafts", "You can now fletch " + "" + "tangle gum branches" + "" + " into " + "" + "15 arrow shafts" + "" + " within Daemonheim."); + case 2: + return newstruct cs2func_script_980_struct(1, 16427, "Novite arrows (Tier 1)", "You can now fletch " + "" + "novite arrows" + "" + " within Daemonheim."); + case 3: + return newstruct cs2func_script_980_struct(1, 16867, "Tangle gum shortbow (Tier 1)", "You can now fletch " + "" + "tangle gum shortbows" + "" + " within Daemonheim."); + case 4: + return newstruct cs2func_script_980_struct(3, 17756, "Tangle gum trap (Tier 1)", "You can now fletch " + "" + "tangle gum traps" + "" + " within Daemonheim."); + case 5: + return newstruct cs2func_script_980_struct(6, 16317, "Tangle gum longbow (Tier 1)", "You can now fletch " + "" + "tangle gum longbows" + "" + " within Daemonheim."); + case 6: + return newstruct cs2func_script_980_struct(8, 16977, "Tangle gum staff (Tier 1)", "You can now fletch " + "" + "tangle gum staves" + "" + " within Daemonheim."); + case 7: + return newstruct cs2func_script_980_struct(10, 17742, "Seeping elm" + "
" + " 21 Arrow shafts", "You can now fletch " + "" + "seeping elm branches" + "" + " into " + "" + "21 arrow shafts" + "" + " within Daemonheim."); + case 8: + return newstruct cs2func_script_980_struct(11, 16432, "Bathus arrows (Tier 2)", "You can now fletch " + "" + "bathus arrows" + "" + " within Daemonheim."); + case 9: + return newstruct cs2func_script_980_struct(11, 16869, "Seeping elm shortbow (Tier 2)", "You can now fletch " + "" + "seeping elm shortbows" + "" + " within Daemonheim."); + case 10: + return newstruct cs2func_script_980_struct(13, 17758, "Seeping elm trap (Tier 2)", "You can now fletch " + "" + "seeping elm traps" + "" + " within Daemonheim."); + case 11: + return newstruct cs2func_script_980_struct(16, 16319, "Seeping elm longbow (Tier 2)", "You can now fletch " + "" + "seeping elm longbows" + "" + " within Daemonheim."); + case 12: + return newstruct cs2func_script_980_struct(18, 16979, "Seeping elm staff (Tier 2)", "You can now fletch " + "" + "seeping elm staves" + "" + " within Daemonheim."); + case 13: + return newstruct cs2func_script_980_struct(20, 17742, "Blood spindle" + "
" + " 26 Arrow shafts", "You can now fletch " + "" + "blood spindle branches" + "" + " into " + "" + "26 arrow shafts" + "" + " within Daemonheim."); + case 14: + return newstruct cs2func_script_980_struct(21, 16871, "Blood spindle shortbow (Tier 3)", "You can now fletch " + "" + "blood spindle shortbows" + "" + " within Daemonheim."); + case 15: + return newstruct cs2func_script_980_struct(22, 16437, "Marmaros arrows (Tier 3)", "You can now fletch " + "" + "marmaros arrows" + "" + " within Daemonheim."); + case 16: + return newstruct cs2func_script_980_struct(23, 17760, "Blood spindle trap (Tier 3)", "You can now fletch " + "" + "blood spindle traps" + "" + " within Daemonheim."); + case 17: + return newstruct cs2func_script_980_struct(26, 16321, "Blood spindle longbow (Tier 3)", "You can now fletch " + "" + "blood spindle longbows" + "" + " within Daemonheim."); + case 18: + return newstruct cs2func_script_980_struct(28, 16981, "Blood spindle staff (Tier 3)", "You can now fletch " + "" + "blood spindle staves" + "" + " within Daemonheim."); + case 19: + return newstruct cs2func_script_980_struct(30, 17742, "Utuku" + "
" + " 32 Arrow shafts", "You can now fletch " + "" + "utuku branches" + "" + " into " + "" + "32 arrow shafts" + "" + " within Daemonheim."); + case 20: + return newstruct cs2func_script_980_struct(31, 16873, "Utuku shortbow (Tier 4)", "You can now fletch " + "" + "utuku shortbows" + "" + " within Daemonheim."); + case 21: + return newstruct cs2func_script_980_struct(33, 16442, "Kratonite arrows (Tier 4)", "You can now fletch " + "" + "kratonite arrows" + "" + " within Daemonheim."); + case 22: + return newstruct cs2func_script_980_struct(33, 17762, "Utuku trap (Tier 4)", "You can now fletch " + "" + "utuku traps" + "" + " within Daemonheim."); + case 23: + return newstruct cs2func_script_980_struct(36, 16323, "Utuku longbow (Tier 4)", "You can now fletch " + "" + "utuku longbows" + "" + " within Daemonheim."); + case 24: + return newstruct cs2func_script_980_struct(38, 16983, "Utuku staff (Tier 4)", "You can now fletch " + "" + "utuku staves" + "" + " within Daemonheim."); + case 25: + return newstruct cs2func_script_980_struct(40, 17742, "Spinebeam" + "
" + " 37 Arrow shafts", "You can now fletch " + "" + "spinebeam branches" + "" + " into " + "" + "37 arrow shafts" + "" + " within Daemonheim."); + case 26: + return newstruct cs2func_script_980_struct(41, 16875, "Spinebeam shortbow (Tier 5)", "You can now fletch " + "" + "spinebeam shortbows" + "" + " within Daemonheim."); + case 27: + return newstruct cs2func_script_980_struct(43, 17764, "Spinebeam trap (Tier 5)", "You can now fletch " + "" + "spinebeam traps" + "" + " within Daemonheim."); + case 28: + return newstruct cs2func_script_980_struct(44, 16447, "Fractite arrows (Tier 5)", "You can now fletch " + "" + "fractite arrows" + "" + " within Daemonheim."); + case 29: + return newstruct cs2func_script_980_struct(46, 16325, "Spinebeam longbow (Tier 5)", "You can now fletch " + "" + "spinebeam longbows" + "" + " within Daemonheim."); + case 30: + return newstruct cs2func_script_980_struct(48, 16985, "Spinebeam staff (Tier 5)", "You can now fletch " + "" + "spinebeam staves" + "" + " within Daemonheim."); + case 31: + return newstruct cs2func_script_980_struct(50, 17742, "Bovistrangler" + "
" + " 43 Arrow shafts", "You can now fletch " + "" + "bovistrangler branches" + "" + " into " + "" + "43 arrow shafts" + "" + " within Daemonheim."); + case 32: + return newstruct cs2func_script_980_struct(51, 16877, "Bovistrangler shortbow (Tier 6)", "You can now fletch " + "" + "bovistrangler shortbows" + "" + " within Daemonheim."); + case 33: + return newstruct cs2func_script_980_struct(53, 17766, "Bovistrangler trap (Tier 6)", "You can now fletch " + "" + "bovistrangler traps" + "" + " within Daemonheim."); + case 34: + return newstruct cs2func_script_980_struct(55, 16452, "Zephyrium arrows (Tier 6)", "You can now fletch " + "" + "zephyrium arrows" + "" + " within Daemonheim."); + case 35: + return newstruct cs2func_script_980_struct(56, 16327, "Bovistrangler longbow (Tier 6)", "You can now fletch " + "" + "bovistrangler longbows" + "" + " within Daemonheim."); + case 36: + return newstruct cs2func_script_980_struct(58, 16987, "Bovistrangler staff (Tier 6)", "You can now fletch " + "" + "bovistrangler staves" + "" + " within Daemonheim."); + case 37: + return newstruct cs2func_script_980_struct(60, 17742, "Thigat" + "
" + " 48 Arrow shafts", "You can now fletch " + "" + "thigat branches" + "" + " into " + "" + "48 arrow shafts" + "" + " within Daemonheim."); + case 38: + return newstruct cs2func_script_980_struct(61, 16879, "Thigat shortbow (Tier 7)", "You can now fletch " + "" + "thigat shortbows" + "" + " within Daemonheim."); + case 39: + return newstruct cs2func_script_980_struct(63, 17768, "Thigat trap (Tier 7)", "You can now fletch " + "" + "thigat traps" + "" + " within Daemonheim."); + case 40: + return newstruct cs2func_script_980_struct(66, 16457, "Argonite arrows (Tier 7)", "You can now fletch " + "" + "argonite arrows" + "" + " within Daemonheim."); + case 41: + return newstruct cs2func_script_980_struct(66, 16329, "Thigat longbow (Tier 7)", "You can now fletch " + "" + "thigat longbows" + "" + " within Daemonheim."); + case 42: + return newstruct cs2func_script_980_struct(68, 16989, "Thigat staff (Tier 7)", "You can now fletch " + "" + "thigat staves" + "" + " within Daemonheim."); + case 43: + return newstruct cs2func_script_980_struct(70, 17742, "Corpsethorn" + "
" + " 54 Arrow shafts", "You can now fletch " + "" + "corpsethorn branches" + "" + " into " + "" + "54 arrow shafts" + "" + " within Daemonheim."); + case 44: + return newstruct cs2func_script_980_struct(71, 16881, "Corpsethorn shortbow (Tier 8)", "You can now fletch " + "" + "corpsethorn shortbows" + "" + " within Daemonheim."); + case 45: + return newstruct cs2func_script_980_struct(73, 17770, "Corpsethorn trap (Tier 8)", "You can now fletch " + "" + "corpsethorn traps" + "" + " within Daemonheim."); + case 46: + return newstruct cs2func_script_980_struct(76, 16331, "Corpsethorn longbow (Tier 8)", "You can now fletch " + "" + "corpsethorn longbows" + "" + " within Daemonheim."); + case 47: + return newstruct cs2func_script_980_struct(77, 16462, "Katagon arrows (Tier 8)", "You can now fletch " + "" + "katagon arrows" + "" + " within Daemonheim."); + case 48: + return newstruct cs2func_script_980_struct(78, 16991, "Corpsethorn staff (Tier 8)", "You can now fletch " + "" + "corpsethorn staves" + "" + " within Daemonheim."); + case 49: + return newstruct cs2func_script_980_struct(80, 17742, "Entgallow" + "
" + " 59 Arrow shafts", "You can now fletch " + "" + "entgallow branches" + "" + " into " + "" + "59 arrow shafts" + "" + " within Daemonheim."); + case 50: + return newstruct cs2func_script_980_struct(81, 16883, "Entgallow shortbow (Tier 9)", "You can now fletch " + "" + "entgallow shortbows" + "" + " within Daemonheim."); + case 51: + return newstruct cs2func_script_980_struct(83, 17772, "Entgallow trap (Tier 9)", "You can now fletch " + "" + "entgallow traps" + "" + " within Daemonheim."); + case 52: + return newstruct cs2func_script_980_struct(86, 16333, "Entgallow longbow (Tier 9)", "You can now fletch " + "" + "entgallow longbows" + "" + " within Daemonheim."); + case 53: + return newstruct cs2func_script_980_struct(88, 16467, "Gorgonite arrows (Tier 9)", "You can now fletch " + "" + "gorgonite arrows" + "" + " within Daemonheim."); + case 54: + return newstruct cs2func_script_980_struct(88, 16993, "Entgallow staff (Tier 9)", "You can now fletch " + "" + "entgallow staves" + "" + " within Daemonheim."); + case 55: + return newstruct cs2func_script_980_struct(90, 17742, "Grave creeper" + "
" + " 65 Arrow shafts", "You can now fletch " + "" + "grave creeper branches" + "" + " into " + "" + "65 arrow shafts" + "" + " within Daemonheim."); + case 56: + return newstruct cs2func_script_980_struct(91, 16885, "Grave creeper shortbow (Tier 10)", "You can now fletch " + "" + "grave creeper shortbows" + "" + " within Daemonheim."); + case 57: + return newstruct cs2func_script_980_struct(93, 17774, "Grave creeper trap (Tier 10)", "You can now fletch " + "" + "grave creeper traps" + "" + " within Daemonheim."); + case 58: + return newstruct cs2func_script_980_struct(96, 16335, "Grave creeper longbow (Tier 10)", "You can now fletch " + "" + "grave creeper longbows" + "" + " within Daemonheim."); + case 59: + return newstruct cs2func_script_980_struct(98, 16995, "Grave creeper staff (Tier 10)", "You can now fletch " + "" + "grave creeper staves" + "" + " within Daemonheim."); + case 60: + return newstruct cs2func_script_980_struct(99, 16472, "Promethium arrows (Tier 10)", "You can now fletch promethium arrows" + "" + " within Daemonheim."); + } + break; + case 8: + if (((boolean)arg1)) { + return newstruct cs2func_script_980_struct(99, 9783, "Skill mastery", "" + "Congratulations! You are now a master of " + "" + "Fletching" + "" + ". Why not visit " + "" + "Hickton" + "" + " who runs the " + "" + "bow and arrow shop" + "" + " in " + "" + "Catherby" + "" + "? He has something special that is only available to true masters of the " + "" + "Fletching" + "" + " skill!"); + } + } + return newstruct cs2func_script_980_struct(0, -1, "", ""); +} diff --git a/dumps/scripts/981.cs2 b/dumps/scripts/981.cs2 new file mode 100644 index 0000000..b62ef4b --- /dev/null +++ b/dumps/scripts/981.cs2 @@ -0,0 +1,35 @@ +cs2func_script_981_struct(1,1,0) script_981(int arg0) { + switch (arg0) { + case 0: + return newstruct cs2func_script_981_struct(0, "Bronze"); + case 1: + return newstruct cs2func_script_981_struct(0, "Iron"); + case 2: + return newstruct cs2func_script_981_struct(0, "Steel"); + case 3: + return newstruct cs2func_script_981_struct(0, "Black"); + case 4: + return newstruct cs2func_script_981_struct(1, "White"); + case 5: + return newstruct cs2func_script_981_struct(0, "Mithril"); + case 6: + return newstruct cs2func_script_981_struct(0, "Adamant"); + case 7: + return newstruct cs2func_script_981_struct(0, "Rune"); + case 8: + return newstruct cs2func_script_981_struct(0, "Dragon"); + case 9: + return newstruct cs2func_script_981_struct(1, "Barrows"); + case 10: + return newstruct cs2func_script_981_struct(0, "Special"); + case 11: + return newstruct cs2func_script_981_struct(1, "Salamanders"); + case 12: + return newstruct cs2func_script_981_struct(1, "Minigames"); + case 13: + return newstruct cs2func_script_981_struct(0, "Dungeoneering"); + case 14: + return newstruct cs2func_script_981_struct(0, "Milestones"); + } + return newstruct cs2func_script_981_struct(-1, ""); +} diff --git a/dumps/scripts/982.cs2 b/dumps/scripts/982.cs2 new file mode 100644 index 0000000..81c5136 --- /dev/null +++ b/dumps/scripts/982.cs2 @@ -0,0 +1,780 @@ +cs2func_script_982_struct(2,2,0) script_982(int arg0,int arg1) { + switch (arg0) { + flow_1: + case 0: + switch (arg1) { + case 0: + return newstruct cs2func_script_982_struct(1, 1205, "Bronze dagger", "You can now wield " + "" + "bronze daggers" + "" + "."); + case 1: + return newstruct cs2func_script_982_struct(1, 1351, "Bronze hatchet", "You can now wield " + "" + "bronze hatchets" + "" + "."); + case 2: + return newstruct cs2func_script_982_struct(1, 1422, "Bronze mace", "You can now wield " + "" + "bronze maces" + "" + "."); + case 3: + return newstruct cs2func_script_982_struct(1, 3095, "Members: Bronze claws", "Members can now wield " + "" + "bronze claws" + "" + "."); + case 4: + return newstruct cs2func_script_982_struct(1, 1277, "Bronze sword", "You can now wield " + "" + "bronze swords" + "" + "."); + case 5: + return newstruct cs2func_script_982_struct(1, 1291, "Bronze longsword", "You can now wield " + "" + "bronze longswords" + "" + "."); + case 6: + return newstruct cs2func_script_982_struct(1, 1321, "Bronze scimitar", "You can now wield " + "" + "bronze scimitars" + "" + "."); + case 7: + return newstruct cs2func_script_982_struct(1, 1237, "Members: Bronze spear", "Members can now wield " + "" + "bronze spears" + "" + "."); + case 8: + return newstruct cs2func_script_982_struct(1, 1337, "Bronze warhammer", "You can now wield " + "" + "bronze warhammers" + "" + "."); + case 9: + return newstruct cs2func_script_982_struct(1, 1375, "Bronze battleaxe", "You can now wield " + "" + "bronze battleaxes" + "" + "."); + case 10: + return newstruct cs2func_script_982_struct(1, 1307, "Bronze two-handed sword", "You can now wield " + "" + "bronze two-handed swords" + "" + "."); + case 11: + return newstruct cs2func_script_982_struct(1, 3190, "Members: Bronze halberd", "Members can now wield " + "" + "bronze halberds" + "" + "."); + case 12: + return newstruct cs2func_script_982_struct(1, 8844, "Members: Bronze defender", "Members can now wield " + "" + "bronze defenders" + "" + "."); + } + break; + case 1: + switch (arg1) { + case 0: + return newstruct cs2func_script_982_struct(1, 1203, "Iron dagger", "You can now wield " + "" + "iron daggers" + "" + "."); + case 1: + return newstruct cs2func_script_982_struct(1, 1349, "Iron hatchet", "You can now wield " + "" + "iron hatchets" + "" + "."); + case 2: + return newstruct cs2func_script_982_struct(1, 1420, "Iron mace", "You can now wield " + "" + "iron maces" + "" + "."); + case 3: + return newstruct cs2func_script_982_struct(1, 3096, "Members: Iron claws", "Members can now wield " + "" + "iron claws" + "" + "."); + case 4: + return newstruct cs2func_script_982_struct(1, 1279, "Iron sword", "You can now wield " + "" + "iron swords" + "" + "."); + case 5: + return newstruct cs2func_script_982_struct(1, 1293, "Iron longsword", "You can now wield " + "" + "iron longswords" + "" + "."); + case 6: + return newstruct cs2func_script_982_struct(1, 1323, "Iron scimitar", "You can now wield " + "" + "iron scimitars" + "" + "."); + case 7: + return newstruct cs2func_script_982_struct(1, 20533, "Members: Iron Ceremonial Sword", "Members can now wield " + "" + "iron ceremonial swords" + "" + "."); + case 8: + return newstruct cs2func_script_982_struct(1, 1239, "Members: Iron spear", "Members can now wield " + "" + "iron spears" + "" + "."); + case 9: + return newstruct cs2func_script_982_struct(1, 1335, "Iron warhammer", "You can now wield " + "" + "iron warhammers" + "" + "."); + case 10: + return newstruct cs2func_script_982_struct(1, 1363, "Iron battleaxe", "You can now wield " + "" + "iron battleaxes" + "" + "."); + case 11: + return newstruct cs2func_script_982_struct(1, 1309, "Iron two-handed sword", "You can now wield " + "" + "iron two-handed swords" + "" + "."); + case 12: + return newstruct cs2func_script_982_struct(1, 3192, "Members: Iron halberd", "Members can now wield " + "" + "iron halberds" + "" + "."); + case 13: + return newstruct cs2func_script_982_struct(1, 8845, "Members: Iron defender", "Members can now wield " + "" + "iron defenders" + "" + "."); + } + break; + case 2: + switch (arg1) { + case 0: + return newstruct cs2func_script_982_struct(5, 1207, "Steel dagger", "You can now wield " + "" + "steel daggers" + "" + "."); + case 1: + return newstruct cs2func_script_982_struct(5, 1353, "Steel hatchet", "You can now wield " + "" + "steel hatchets" + "" + "."); + case 2: + return newstruct cs2func_script_982_struct(5, 1424, "Steel mace", "You can now wield " + "" + "steel maces" + "" + "."); + case 3: + return newstruct cs2func_script_982_struct(5, 3097, "Members: Steel claws", "Members can now wield " + "" + "steel claws" + "" + "."); + case 4: + return newstruct cs2func_script_982_struct(5, 1281, "Steel sword", "You can now wield " + "" + "steel swords" + "" + "."); + case 5: + return newstruct cs2func_script_982_struct(5, 1295, "Steel longsword", "You can now wield " + "" + "steel longswords" + "" + "."); + case 6: + return newstruct cs2func_script_982_struct(5, 1325, "Steel scimitar", "You can now wield " + "" + "steel scimitars" + "" + "."); + case 7: + return newstruct cs2func_script_982_struct(5, 20538, "Members: Steel Ceremonial Sword", "Members can now wield " + "" + "steel ceremonial swords" + "" + "."); + case 8: + return newstruct cs2func_script_982_struct(5, 1241, "Members: Steel spear", "Members can now wield " + "" + "steel spears" + "" + "."); + case 9: + return newstruct cs2func_script_982_struct(5, 1339, "Steel warhammer", "You can now wield " + "" + "steel warhammers" + "" + "."); + case 10: + return newstruct cs2func_script_982_struct(5, 1365, "Steel battleaxe", "You can now wield " + "" + "steel battleaxes" + "" + "."); + case 11: + return newstruct cs2func_script_982_struct(5, 1311, "Steel two-handed sword", "You can now wield " + "" + "steel two-handed swords" + "" + "."); + case 12: + return newstruct cs2func_script_982_struct(5, 3194, "Members: Steel halberd", "Members can now wield " + "" + "steel halberds" + "" + "."); + case 13: + return newstruct cs2func_script_982_struct(5, 8846, "Members: Steel defender" + "
" + " (with 5 Defence)", "Members now have the Attack level required to wield " + "" + "steel defenders" + "" + ". (They also need level 5 Defence.)"); + } + break; + case 3: + switch (arg1) { + case 0: + return newstruct cs2func_script_982_struct(10, 1217, "Black dagger", "You can now wield " + "" + "black daggers" + "" + "."); + case 1: + return newstruct cs2func_script_982_struct(10, 1361, "Black hatchet", "You can now wield " + "" + "black hatchets" + "" + "."); + case 2: + return newstruct cs2func_script_982_struct(10, 1426, "Black mace", "You can now wield " + "" + "black maces" + "" + "."); + case 3: + return newstruct cs2func_script_982_struct(10, 3098, "Members: Black claws", "Members can now wield " + "" + "black claws" + "" + "."); + case 4: + return newstruct cs2func_script_982_struct(10, 1283, "Black sword", "You can now wield " + "" + "black swords" + "" + "."); + case 5: + return newstruct cs2func_script_982_struct(10, 1297, "Black longsword", "You can now wield " + "" + "black longswords" + "" + "."); + case 6: + return newstruct cs2func_script_982_struct(10, 1327, "Black scimitar", "You can now wield " + "" + "black scimitars" + "" + "."); + case 7: + return newstruct cs2func_script_982_struct(10, 4580, "Members: Black spear", "Members can now wield " + "" + "black spears" + "" + "."); + case 8: + return newstruct cs2func_script_982_struct(10, 1341, "Black warhammer", "You can now wield " + "" + "black warhammers" + "" + "."); + case 9: + return newstruct cs2func_script_982_struct(10, 1367, "Black battleaxe", "You can now wield " + "" + "black battleaxes" + "" + "."); + case 10: + return newstruct cs2func_script_982_struct(10, 1313, "Black two-handed sword", "You can now wield " + "" + "black two-handed swords" + "" + "."); + case 11: + return newstruct cs2func_script_982_struct(10, 3196, "Members: Black halberd", "Members can now wield " + "" + "black halberds" + "" + "."); + case 12: + return newstruct cs2func_script_982_struct(10, 8847, "Members: Black defender" + "
" + " (with 10 Defence)", "Members now have the Attack level required to wield " + "" + "black defenders" + "" + ". (They also need level 10 Defence.)"); + } + break; + case 4: + switch (arg1) { + case 0: + return newstruct cs2func_script_982_struct(-1, 7620, "To wield any white equipment, you must have completed Wanted!.", ""); + case 1: + return newstruct cs2func_script_982_struct(10, 6591, "Members: White dagger", "Members can now wield " + "" + "white daggers" + "" + " (after finishing Wanted!)."); + case 2: + return newstruct cs2func_script_982_struct(10, 6601, "Members: White mace", "Members can now wield " + "" + "white maces" + "" + " (after finishing Wanted!)."); + case 3: + return newstruct cs2func_script_982_struct(10, 6587, "Members: White claws", "Members can now wield " + "" + "white claws" + "" + " (after finishing Wanted!)."); + case 4: + return newstruct cs2func_script_982_struct(10, 6605, "Members: White sword", "Members can now wield " + "" + "white swords" + "" + " (after finishing Wanted!)."); + case 5: + return newstruct cs2func_script_982_struct(10, 6607, "Members: White longsword", "Members can now wield " + "" + "white longswords" + "" + " (after finishing Wanted!)."); + case 6: + return newstruct cs2func_script_982_struct(10, 6611, "Members: White scimitar", "Members can now wield " + "" + "white scimitars" + "" + " (after finishing Wanted!)."); + case 7: + return newstruct cs2func_script_982_struct(10, 6613, "Members: White warhammer", "Members can now wield " + "" + "white warhammers" + "" + " (after finishing Wanted!)."); + case 8: + return newstruct cs2func_script_982_struct(10, 6589, "Members: White battleaxe", "Members can now wield " + "" + "white battleaxes" + "" + " (after finishing Wanted!)."); + case 9: + return newstruct cs2func_script_982_struct(10, 6609, "Members: White two-handed sword", "Members can now wield " + "" + "white two-handed swords" + "" + " (after finishing Wanted!)."); + case 10: + return newstruct cs2func_script_982_struct(10, 6599, "Members: White halberd", "Members can now wield " + "" + "white halberds" + "" + " (after finishing Wanted!)."); + } + break; + case 5: + switch (arg1) { + case 0: + return newstruct cs2func_script_982_struct(20, 1209, "Mithril dagger", "You can now wield mithril daggers" + "" + "."); + case 1: + return newstruct cs2func_script_982_struct(20, 1355, "Mithril hatchet", "You can now wield mithril hatchets" + "" + "."); + case 2: + return newstruct cs2func_script_982_struct(20, 1428, "Mithril mace", "You can now wield mithril maces" + "" + "."); + case 3: + return newstruct cs2func_script_982_struct(20, 3099, "Members: Mithril claws", "Members can now wield mithril claws" + "" + "."); + case 4: + return newstruct cs2func_script_982_struct(20, 1285, "Mithril sword", "You can now wield mithril swords" + "" + "."); + case 5: + return newstruct cs2func_script_982_struct(20, 1299, "Mithril longsword", "You can now wield mithril longswords" + "" + "."); + case 6: + return newstruct cs2func_script_982_struct(20, 1329, "Mithril scimitar", "You can now wield mithril scimitars" + "" + "."); + case 7: + return newstruct cs2func_script_982_struct(20, 20543, "Members: Mithril Ceremonial Sword", "Members can now wield " + "" + "mithril ceremonial swords" + "" + "."); + case 8: + return newstruct cs2func_script_982_struct(20, 1243, "Members: Mithril spear", "Members can now wield mithril spears" + "" + "."); + case 9: + return newstruct cs2func_script_982_struct(20, 1343, "Mithril warhammer", "You can now wield mithril warhammers" + "" + "."); + case 10: + return newstruct cs2func_script_982_struct(20, 1369, "Mithril battleaxe", "You can now wield mithril battleaxes" + "" + "."); + case 11: + return newstruct cs2func_script_982_struct(20, 1315, "Mithril two-handed sword", "You can now wield mithril two-handed swords" + "" + "."); + case 12: + return newstruct cs2func_script_982_struct(20, 3198, "Members: Mithril halberd", "Members can now wield mithril halberds" + "" + "."); + case 13: + return newstruct cs2func_script_982_struct(20, 8848, "Members: Mithril defender" + "
" + " (with 20 Defence)", "Members now have the Attack level required to wield mithril defenders" + "" + ". (They also need level 20 Defence.)"); + } + break; + case 6: + switch (arg1) { + case 0: + return newstruct cs2func_script_982_struct(30, 1211, "Adamant dagger", "You can now wield " + "" + "adamant daggers" + "" + "."); + case 1: + return newstruct cs2func_script_982_struct(30, 1357, "Adamant hatchet", "You can now wield " + "" + "adamant hatchets" + "" + "."); + case 2: + return newstruct cs2func_script_982_struct(30, 1430, "Adamant mace", "You can now wield " + "" + "adamant maces" + "" + "."); + case 3: + return newstruct cs2func_script_982_struct(30, 3100, "Members: Adamant claws", "Members can now wield " + "" + "adamant claws" + "" + "."); + case 4: + return newstruct cs2func_script_982_struct(30, 1287, "Adamant sword", "You can now wield " + "" + "adamant swords" + "" + "."); + case 5: + return newstruct cs2func_script_982_struct(30, 1301, "Adamant longsword", "You can now wield " + "" + "adamant longswords" + "" + "."); + case 6: + return newstruct cs2func_script_982_struct(30, 1331, "Adamant scimitar", "You can now wield " + "" + "adamant scimitars" + "" + "."); + case 7: + return newstruct cs2func_script_982_struct(30, 20548, "Members: Adamant Ceremonial Sword", "Members can now wield " + "" + "adamant ceremonial swords" + "" + "."); + case 8: + return newstruct cs2func_script_982_struct(30, 1245, "Members: Adamant spear", "Members can now wield " + "" + "adamant spears" + "" + "."); + case 9: + return newstruct cs2func_script_982_struct(30, 1345, "Adamant warhammer", "You can now wield " + "" + "adamant warhammers" + "" + "."); + case 10: + return newstruct cs2func_script_982_struct(30, 1371, "Adamant battleaxe", "You can now wield " + "" + "adamant battleaxes" + "" + "."); + case 11: + return newstruct cs2func_script_982_struct(30, 1317, "Adamant two-handed sword", "You can now wield " + "" + "adamant two-handed swords" + "" + "."); + case 12: + return newstruct cs2func_script_982_struct(30, 3200, "Members: Adamant halberd", "Members can now wield " + "" + "adamant halberds" + "" + "."); + case 13: + return newstruct cs2func_script_982_struct(30, 8849, "Members: Adamant defender" + "
" + " (with 30 Defence)", "Members now have the Attack level required to wield " + "" + "adamant defenders" + "" + ". (They also need level 30 Defence.)"); + } + break; + case 7: + switch (arg1) { + case 0: + return newstruct cs2func_script_982_struct(40, 1213, "Rune dagger", "You can now wield " + "" + "rune daggers" + "" + "."); + case 1: + return newstruct cs2func_script_982_struct(40, 1359, "Rune hatchet", "You can now wield " + "" + "rune hatchets" + "" + "."); + case 2: + return newstruct cs2func_script_982_struct(40, 1432, "Rune mace", "You can now wield " + "" + "rune maces" + "" + "."); + case 3: + return newstruct cs2func_script_982_struct(40, 3101, "Members: Rune claws", "Members can now wield " + "" + "rune claws" + "" + "."); + case 4: + return newstruct cs2func_script_982_struct(40, 1289, "Rune sword", "You can now wield " + "" + "rune swords" + "" + "."); + case 5: + return newstruct cs2func_script_982_struct(40, 1303, "Rune longsword", "You can now wield " + "" + "rune longswords" + "" + "."); + case 6: + return newstruct cs2func_script_982_struct(40, 1333, "Rune scimitar", "You can now wield " + "" + "rune scimitars" + "" + "."); + case 7: + return newstruct cs2func_script_982_struct(40, 20553, "Members: Rune Ceremonial Sword", "Members can now wield " + "" + "rune ceremonial swords" + "" + "."); + case 8: + return newstruct cs2func_script_982_struct(40, 1247, "Members: Rune spear", "Members can now wield " + "" + "rune spears" + "" + "."); + case 9: + return newstruct cs2func_script_982_struct(40, 1347, "Rune warhammer", "You can now wield " + "" + "rune warhammers" + "" + "."); + case 10: + return newstruct cs2func_script_982_struct(40, 1373, "Rune battleaxe", "You can now wield " + "" + "rune battleaxes" + "" + "."); + case 11: + return newstruct cs2func_script_982_struct(40, 1319, "Rune two-handed sword", "You can now wield " + "" + "rune two-handed swords" + "" + "."); + case 12: + return newstruct cs2func_script_982_struct(40, 3202, "Members: Rune halberd", "Members can now wield " + "" + "rune halberds" + "" + "."); + case 13: + return newstruct cs2func_script_982_struct(40, 8850, "Members: Rune defender" + "
" + " (with 40 Defence)", "Members now have the Attack level required to wield " + "" + "rune defenders" + "" + ". (They also need level 40 Defence.)"); + } + break; + case 8: + switch (arg1) { + case 0: + return newstruct cs2func_script_982_struct(60, 1215, "Members: Dragon dagger" + "
" + " (after Lost City)", "Members can now wield " + "" + "dragon daggers" + "" + " (after Lost City)."); + case 1: + return newstruct cs2func_script_982_struct(60, 6739, "Members: Dragon hatchet", "Members can now wield " + "" + "dragon hatchets" + "" + "."); + case 2: + return newstruct cs2func_script_982_struct(60, 1434, "Members: Dragon mace" + "
" + " (after Heroes' Quest)", "Members can now wield " + "" + "dragon maces" + "" + " (after Heroes' Quest)."); + case 3: + return newstruct cs2func_script_982_struct(60, 14484, "Members: Dragon claws", "Members can now wield " + "" + "dragon claws" + "" + "."); + case 4: + return newstruct cs2func_script_982_struct(60, 1305, "Members: Dragon longsword" + "
" + " (after Lost City)", "Members can now wield " + "" + "dragon longswords" + "" + " (after Lost City)."); + case 5: + return newstruct cs2func_script_982_struct(60, 4587, "Members: Dragon scimitar" + "
" + " (after Monkey Madness)", "Members can now wield " + "" + "dragon scimitars" + "" + " (after Monkey Madness)."); + case 6: + return newstruct cs2func_script_982_struct(60, 1249, "Members: Dragon spear", "Members can now wield " + "" + "dragon spears" + "" + "."); + case 7: + return newstruct cs2func_script_982_struct(60, 1377, "Members: Dragon battleaxe" + "
" + " (after Heroes' Quest)", "Members can now wield " + "" + "dragon battleaxes" + "" + " (after Heroes' Quest)."); + case 8: + return newstruct cs2func_script_982_struct(60, 7158, "Members: Dragon two-handed sword", "Members can now wield " + "" + "dragon two-handed swords" + "" + "."); + case 9: + return newstruct cs2func_script_982_struct(60, 3204, "Members: Dragon halberd" + "
" + " (after Regicide)", "Members can now wield " + "" + "dragon halberds" + "" + " (after Regicide)."); + case 10: + return newstruct cs2func_script_982_struct(60, 15259, "Members: Dragon pickaxe", "Members can now wield " + "" + "dragon pickaxes" + "" + "."); + case 11: + return newstruct cs2func_script_982_struct(60, 20072, "Members: Dragon defender" + "
" + " (with 60 Defence)", "Members now have the Attack level required to wield " + "" + "dragon defenders" + "" + ". (They also need level 60 Defence.)"); + case 12: + return newstruct cs2func_script_982_struct(60, 13976, "Corrupt dragon dagger", "You can now wield " + "" + "corrupt dragon daggers" + "" + "."); + case 13: + return newstruct cs2func_script_982_struct(60, 13985, "Corrupt dragon mace", "You can now wield " + "" + "corrupt dragon maces" + "" + "."); + case 14: + return newstruct cs2func_script_982_struct(60, 13982, "Corrupt dragon longsword", "You can now wield " + "" + "corrupt dragon longswords" + "" + "."); + case 15: + return newstruct cs2func_script_982_struct(60, 13979, "Corrupt dragon scimitar", "You can now wield " + "" + "corrupt dragon scimitars" + "" + "."); + case 16: + return newstruct cs2func_script_982_struct(60, 13988, "Corrupt dragon spear", "You can now wield " + "" + "corrupt dragon spears" + "" + "."); + case 17: + return newstruct cs2func_script_982_struct(60, 13973, "Corrupt dragon battleaxe", "You can now wield " + "" + "corrupt dragon battleaxes" + "" + "."); + } + break; + case 9: + switch (arg1) { + case 0: + return newstruct cs2func_script_982_struct(70, 4710, "Members: Ahrim's staff" + "
" + " (with 70 Magic)", "Members now have the Attack level required to wield " + "" + "Ahrim's staff" + "" + ". (They also need level 70 Magic.)"); + case 1: + return newstruct cs2func_script_982_struct(70, 4718, "Members: Dharok's greataxe" + "
" + " (with 70 Strength)", "Members now have the Attack level required to wield " + "" + "Dharok's greataxe" + "" + ". (They also need level 70 Strength.)"); + case 2: + return newstruct cs2func_script_982_struct(70, 4726, "Members: Guthan's spear", "Members can now wield " + "" + "Guthan's spear" + "" + "."); + case 3: + return newstruct cs2func_script_982_struct(70, 4747, "Members: Torag's hammers" + "
" + " (with 70 Strength)", "Members now have the Attack level required to wield " + "" + "Torag's hammers" + "" + ". (They also need level 70 Strength.)"); + case 4: + return newstruct cs2func_script_982_struct(70, 4755, "Members: Verac's flail", "Members can now wield " + "" + "Verac's flail" + "" + "."); + case 5: + return newstruct cs2func_script_982_struct(70, 21744, "Members: Akrisae's war mace" + "
" + " (After Ritual of the Mahjarrat and with level 70 Magic and 70 Prayer)", "Members now have the Attack level required to wield " + "" + "Akrisae's war mace" + "" + " (after Ritual of the Mahjarrat and with 70 Magic and 70 Prayer)."); + } + break; + case 10: + switch (arg1) { + case 0: + return newstruct cs2func_script_982_struct(1, 21340, "Members: Dwarven Army Axe", "Members can now wield a " + "" + "Dwarven Army Axe" + "" + "."); + case 1: + return newstruct cs2func_script_982_struct(1, 15596, "Reese's sword" + "
" + " (after The Blood Pact)", "You can now wield " + "" + "Reese's sword" + "" + " (after starting The Blood Pact)."); + case 2: + return newstruct cs2func_script_982_struct(1, 2402, "Silverlight" + "
" + " (after Demon Slayer)", "You can now wield " + "" + "Silverlight" + "" + " (after starting Demon Slayer)."); + case 3: + return newstruct cs2func_script_982_struct(1, 6746, "Members: Darklight" + "
" + " (after Shadow of the Storm)", "Members can now wield " + "" + "Darklight" + "" + " (after Shadow of the Storm)."); + case 4: + return newstruct cs2func_script_982_struct(1, 2952, "Members: Wolfbane Dagger" + "
" + " (after Priest in Peril)", "Members can now wield the " + "" + "Wolfbane Dagger" + "" + " (after Priest in Peril."); + case 5: + return newstruct cs2func_script_982_struct(1, 746, "Members: Dark Dagger", "Members can now wield the " + "" + "Dark Dagger" + "" + "."); + case 6: + return newstruct cs2func_script_982_struct(1, 667, "Faladian/Blurite Sword" + "
" + " (after starting The Knight's Sword)", "You can now wield the " + "" + "Faladian/Blurite Sword" + "" + " (after starting The Knight's Sword)."); + case 7: + return newstruct cs2func_script_982_struct(1, 10858, "Members: Shadow Sword", "Members can now wield the " + "" + "Shadow Sword" + "" + "."); + case 8: + return newstruct cs2func_script_982_struct(1, 5016, "Members: Bone spear", "Members can now wield " + "" + "bone spears" + "" + "."); + case 9: + return newstruct cs2func_script_982_struct(1, 5018, "Members: Bone club", "Members can now wield " + "" + "bone clubs" + "" + "."); + case 10: + return newstruct cs2func_script_982_struct(1, 8872, "Members: Bone dagger", "Members can now wield " + "" + "bone daggers" + "" + "."); + case 11: + return newstruct cs2func_script_982_struct(1, 6760, "Members: Guthix Mjolnir" + "
" + " (after Making History)", "Members can now wield the " + "" + "Guthix Mjolnir" + "" + " (after Making History)."); + case 12: + return newstruct cs2func_script_982_struct(1, 6762, "Members: Saradomin Mjolnir" + "
" + " (after Making History)", "Members can now wield the " + "" + "Saradomin Mjolnir" + "" + " after completing Making History."); + case 13: + return newstruct cs2func_script_982_struct(1, 6764, "Members: Zamorak Mjolnir" + "
" + " (after Making History)", "Members can now wield the " + "" + "Zamorak Mjolnir" + "" + " (after Making History)."); + case 14: + return newstruct cs2func_script_982_struct(1, 7668, "Members: Gadderhammer" + "
" + " (after starting In Aid of the Myreque)", "Members can now wield the " + "" + "Gadderhammer" + "" + " (after starting In Aid of the Myreque)."); + case 15: + return newstruct cs2func_script_982_struct(1, 10491, "Members: Blessed Axe" + "
" + " (after starting Animal Magnetism)", "Members can now wield the " + "" + "Blessed Axe" + "" + " (after starting Animal Magnetism)."); + case 16: + return newstruct cs2func_script_982_struct(1, 13661, "Members: Inferno Adze" + "
" + " (after All Fired Up and with 92 Firemaking)", "Members can now wield the " + "" + "Inferno Adze" + "" + " (after All Fired Up)."); + case 17: + return newstruct cs2func_script_982_struct(5, 4068, "Members: Basic decorative sword", "Members can now wield " + "" + "basic decorative swords" + "" + "."); + case 18: + return newstruct cs2func_script_982_struct(5, 12570, "Members: Ogre club", "Members can now wield " + "" + "ogre clubs" + "" + "."); + case 19: + return newstruct cs2func_script_982_struct(15, 11061, "Members: Ancient Mace" + "
" + " (after Another Slice of H.A.M. and with 25 Prayer)", "Members now have the Attack level required to wield the " + "" + "Ancient Mace" + "" + " (after Another Slice of H.A.M. and with level 25 Prayer)."); + case 20: + return newstruct cs2func_script_982_struct(20, 35, "Members: Excalibur" + "
" + " (after starting Merlin's Crystal)", "Members can now wield " + "" + "Excalibur" + "" + " (after starting Merlin's Crystal)."); + case 21: + return newstruct cs2func_script_982_struct(20, 4503, "Members: Detailed decorative sword", "Members can now wield " + "" + "detailed decorative swords" + "" + "."); + case 22: + return newstruct cs2func_script_982_struct(20, 13926, "Members: Corrupt Statius's warhammer", "Members now have the Attack level required to wield " + "" + "corrupt Statius's warhammer" + "" + "."); + case 23: + return newstruct cs2func_script_982_struct(20, 13923, "Members: Corrupt Vesta's longsword", "Members now have the Attack level required to wield " + "" + "corrupt Vesta's longsword" + "" + "."); + case 24: + return newstruct cs2func_script_982_struct(20, 13929, "Members: Corrupt Vesta's spear", "Members now have the Attack level required to wield " + "" + "corrupt Vesta's spear" + "" + "."); + case 25: + return newstruct cs2func_script_982_struct(20, 13941, "Members: Corrupt Zuriel's staff" + "
" + " (with 20 Magic)", "Members now have the Attack level required to wield " + "" + "corrupt Zuriel's staff" + "" + " (with level 20 Magic)."); + case 26: + return newstruct cs2func_script_982_struct(30, 1397, "Members: Air battlestaff" + "
" + " (with 30 Magic)", "Members now have the Attack level required to wield " + "" + "air battlestaves" + "" + ". (They also need level 30 Magic.)"); + case 27: + return newstruct cs2func_script_982_struct(30, 1399, "Members: Earth battlestaff" + "
" + " (with 30 Magic)", "Members now have the Attack level required to wield " + "" + "earth battlestaves" + "" + ". (They also need level 30 Magic.)"); + case 28: + return newstruct cs2func_script_982_struct(30, 1393, "Members: Fire battlestaff" + "
" + " (with 30 Magic)", "Members now have the Attack level required to wield " + "" + "fire battlestaves" + "" + ". (They also need level 30 Magic.)"); + case 29: + return newstruct cs2func_script_982_struct(30, 1395, "Members: Water battlestaff" + "
" + " (with 30 Magic)", "Members now have the Attack level required to wield " + "" + "water battlestaves" + "" + ". (They also need level 30 Magic.)"); + case 30: + return newstruct cs2func_script_982_struct(30, 3053, "Members: Lava battlestaff" + "
" + " (with 30 Magic)", "Members now have the Attack level required to wield " + "" + "lava battlestaves" + "" + ". (They also need level 30 Magic.)"); + case 31: + return newstruct cs2func_script_982_struct(30, 6562, "Members: Mud battlestaff" + "
" + " (with 30 Magic)", "Members now have the Attack level required to wield " + "" + "mud battlestaves" + "" + ". (They also need level 30 Magic.)"); + case 32: + return newstruct cs2func_script_982_struct(30, 21502, "Members: Skeletal battlestaves" + "
" + " (with 30 Magic)", "Members now have the Attack level required to wield " + "" + "skeletal battlestaves" + "" + ". (They also need level 30 Magic.)"); + case 33: + return newstruct cs2func_script_982_struct(30, 4508, "Members: Intricate decorative sword", "Members can now wield " + "" + "intricate decorative swords" + "" + "."); + case 34: + return newstruct cs2func_script_982_struct(30, 3757, "Members: Fremennik blade", "Members can now wield " + "" + "Fremennik blades" + "" + "."); + case 35: + return newstruct cs2func_script_982_struct(30, 21536, "Members: Sceptre of the gods" + "
" + " (with 30 Magic)", "Members can now wield " + "" + "the Sceptre of the gods" + "" + ". (They also need level 30 Magic.)"); + case 36: + return newstruct cs2func_script_982_struct(40, 18341, "Nature staff" + "
" + " (with 53 Magic and 53 Dungeoneering)", "You can now use " + "" + "nature staves" + "" + ". (You also need level 53 Magic and level 53 Dungeoneering.)"); + case 37: + return newstruct cs2func_script_982_struct(40, 18342, "Law staff" + "
" + " (with 45 Magic and 45 Dungeoneering)", "You can now use " + "" + "law staves" + "" + ". (You also need level 45 Magic and level 45 Dungeoneering.)"); + case 38: + return newstruct cs2func_script_982_struct(40, 1405, "Members: Mystic air staff" + "
" + " (with 40 Magic)", "Members now have the Attack level required to wield " + "" + "mystic air staves" + "" + ". (They also need level 40 Magic.)"); + case 39: + return newstruct cs2func_script_982_struct(40, 1407, "Members: Mystic earth staff" + "
" + " (with 40 Magic)", "Members now have the Attack level required to wield " + "" + "mystic earth staves" + "" + ". (They also need level 40 Magic.)"); + case 40: + return newstruct cs2func_script_982_struct(40, 1401, "Members: Mystic fire staff" + "
" + " (with 40 Magic)", "Members now have the Attack level required to wield " + "" + "mystic fire staves" + "" + ". (They also need level 40 Magic.)"); + case 41: + return newstruct cs2func_script_982_struct(40, 1403, "Members: Mystic water staff" + "
" + " (with 40 Magic)", "Members now have the Attack level required to wield " + "" + "mystic water staves" + "" + ". (They also need level 40 Magic.)"); + case 42: + return newstruct cs2func_script_982_struct(40, 3054, "Members: Mystic lava staff" + "
" + " (with 40 Magic)", "Members now have the Attack level required to wield " + "" + "mystic lava staves" + "" + ". (They also need level 40 Magic.)"); + case 43: + return newstruct cs2func_script_982_struct(40, 6563, "Members: Mystic mud staff" + "
" + " (with 40 Magic)", "Members now have the Attack level required to wield " + "" + "mystic mud staves" + "" + ". (They also need level 40 Magic.)"); + case 44: + return newstruct cs2func_script_982_struct(40, 21498, "Members: Necromancer staves" + "
" + " (with 40 Magic)", "Members now have the Attack level required to wield " + "" + "necromancer staves" + "" + ". (They also need level 40 Magic.)"); + case 45: + return newstruct cs2func_script_982_struct(40, 11738, "Members: Mystic steam staff" + "
" + " (with 40 Magic)", "Members now have the Attack level required to wield " + "" + "mystic steam staves" + "" + ". (They also need level 40 Magic.)"); + case 46: + return newstruct cs2func_script_982_struct(40, 11037, "Members: Brine sabre", "Members can now wield " + "" + "brine sabres" + "" + "."); + case 47: + return newstruct cs2func_script_982_struct(40, 14097, "Members: Sacred clay sword", "Members can now wield " + "" + "sacred clay swords" + "" + "."); + case 48: + return newstruct cs2func_script_982_struct(40, 4508, "Members: Profound decorative sword", "Members can now wield " + "" + "profound decorative swords" + "" + "."); + case 49: + return newstruct cs2func_script_982_struct(40, 19323, "Members: Dragon staff" + "
" + " (with 40 Magic, 60 Prayer and 20 Defence)", "Members now have the Attack level required to wield " + "" + "dragon staves" + "" + ". (They also need level 40 Magic, level 60 Prayer and level 20 Defence.)"); + case 50: + return newstruct cs2func_script_982_struct(40, 19325, "Members: Penguin staff" + "
" + " (with 40 Magic, 60 Prayer and 20 Defence)", "Members now have the Attack level required to wield " + "" + "penguin staves" + "" + ". (They also need level 40 Magic, level 60 Prayer and level 20 Defence.)"); + case 51: + return newstruct cs2func_script_982_struct(40, 19327, "Members: Bat staff" + "
" + " (with 40 Magic, 60 Prayer and 20 Defence)", "Members now have the Attack level required to wield " + "" + "bat staves" + "" + ". (They also need level 40 Magic, level 60 Prayer and level 20 Defence.)"); + case 52: + return newstruct cs2func_script_982_struct(40, 19329, "Members: Wolf staff" + "
" + " (with 40 Magic, 60 Prayer and 20 Defence)", "Members now have the Attack level required to wield " + "" + "wolf staves" + "" + ". (They also need level 40 Magic, level 60 Prayer and level 20 Defence.)"); + case 53: + return newstruct cs2func_script_982_struct(40, 19331, "Members: Cat staff" + "
" + " (with 40 Magic, 60 Prayer and 20 Defence)", "Members now have the Attack level required to wield " + "" + "cat staves" + "" + ". (They also need level 40 Magic, level 60 Prayer and level 20 Defence.)"); + case 54: + return newstruct cs2func_script_982_struct(40, 21777, "Members: Armadyl battlestaff" + "
" + " (with 77 Magic)", "Members now have the Attack level required to wield " + "" + "Armadyl battle staves" + "" + ". (They also need level 77 Magic.)"); + case 55: + return newstruct cs2func_script_982_struct(42, 11665, "Members: Void melee helm", "Members now have the Attack level required to wear " + "" + "Void melee helms" + "" + "."); + case 56: + return newstruct cs2func_script_982_struct(42, 11664, "Members: Void ranger helm", "Members now have the Attack level required to wear " + "" + "Void ranger helms" + "" + "."); + case 57: + return newstruct cs2func_script_982_struct(42, 11663, "Members: Void mage helm", "Members now have the Attack level required to wear " + "" + "Void mage helms" + "" + "."); + case 58: + return newstruct cs2func_script_982_struct(42, 8839, "Members: Void knight top", "Members now have the Attack level required to wear " + "" + "Void knight tops" + "" + "."); + case 59: + return newstruct cs2func_script_982_struct(42, 8840, "Members: Void knight robe", "Members now have the Attack level required to wear " + "" + "Void knight robes" + "" + "."); + case 60: + return newstruct cs2func_script_982_struct(42, 8842, "Members: Void knight gloves", "Members now have the Attack level required to wear " + "" + "Void knight gloves" + "" + "."); + case 61: + return newstruct cs2func_script_982_struct(42, 19712, "Members: Void knight deflector", "Members now have the Attack level required to wear " + "" + "Void knight deflectors" + "" + "."); + case 62: + return newstruct cs2func_script_982_struct(42, 8841, "Members: Void knight mace", "Members now have the Attack level required to wield " + "" + "Void knight maces" + "" + "."); + case 63: + return newstruct cs2func_script_982_struct(42, 7620, "Void knight equipment requires 42 Attack, Defence, Strength, Ranged, Magic and Constitution and 22 Prayer.", "" + "Void knight equipment" + "" + " requires 42 Attack, Defence, Strength, Ranged, Magic and Constitution and 22 Prayer."); + case 64: + return newstruct cs2func_script_982_struct(45, 18365, "Gravite rapier" + "
" + " (with 45 Dungeoneering)", "You can now wield " + "" + "gravite rapiers" + "" + ". (You also need level 45 Dungeoneering.)"); + case 65: + return newstruct cs2func_script_982_struct(45, 18367, "Gravite longsword" + "
" + " (with 45 Dungeoneering)", "You can now wield " + "" + "gravite longswords" + "" + ". (You also need level 45 Dungeoneering.)"); + case 66: + return newstruct cs2func_script_982_struct(45, 18369, "Gravite two-handed sword" + "
" + " (with 45 Dungeoneering)", "You can now wield " + "" + "gravite two-handed swords" + "" + ". (You also need level 45 Dungeoneering.)"); + case 67: + return newstruct cs2func_script_982_struct(50, 4158, "Members: Leaf-bladed spear" + "
" + " (with 55 Slayer)", "Members now have the Attack level required to wield " + "" + "leaf-bladed spears" + "" + ": melee weapons used for killing turoth and kurask. (They also need level 55 Slayer.)"); + case 68: + return newstruct cs2func_script_982_struct(50, 4675, "Members: Ancient Staff" + "
" + " (after Desert Treasure and with 50 Magic)", "Members now have the Attack level required to wield the " + "" + "Ancient Staff" + "" + " (after Desert Treasure and with level 50 Magic)."); + case 69: + return newstruct cs2func_script_982_struct(50, 1409, "Members: Iban's Staff" + "
" + " (after Underground Pass and with 50 Magic)", "Members now have the Attack level required to wield " + "" + "Iban's Staff" + "" + " (after Underground Pass and with level 50 Magic)."); + case 70: + return newstruct cs2func_script_982_struct(50, 4153, "Members: Granite maul" + "
" + " (with 50 Strength)", "Members can now wield " + "" + "granite mauls" + "" + ". (They also need level 50 Strength.)"); + case 71: + return newstruct cs2func_script_982_struct(50, 14679, "Members: Granite mace" + "
" + " (with 50 Strength)", "Members can now wield " + "" + "granite maces" + "" + ". (They also need level 50 Strength.)"); + case 72: + return newstruct cs2func_script_982_struct(50, 10581, "Members: Keris" + "
" + " (after Contact!)", "Members can now wield " + "" + "Keris" + "" + " (after Contact!)."); + case 73: + return newstruct cs2func_script_982_struct(50, 13290, "Members: Leaf-bladed swords" + "
" + " (with 55 Slayer)", "Members can now wield " + "" + "leaf-bladed swords" + "" + ". (They also need level 55 Slayer)."); + case 74: + return newstruct cs2func_script_982_struct(60, 10887, "Members: Barrelchest Anchor" + "
" + " (after Great Brain Robbery and with 40 Strength)", "Members now have the Attack level required to wield the " + "" + "Barrelchest Anchor" + "" + " (after Great Brain Robbery, with level 40 Strength)."); + case 75: + return newstruct cs2func_script_982_struct(60, 6523, "Members: TokTz-Xil-Ak", "Members can now wield " + "" + "TokTz-Xil-Ak" + "" + "."); + case 76: + return newstruct cs2func_script_982_struct(60, 6527, "Members: TzHaar-Ket-Em", "Members can now wield " + "" + "TzHaar-Ket-Em" + "" + "."); + case 77: + return newstruct cs2func_script_982_struct(60, 6525, "Members: TokTz-Xil-Ek", "Members can now wield " + "" + "TokTz-Xil-Ek" + "" + "."); + case 78: + return newstruct cs2func_script_982_struct(60, 6526, "Members: Toktz-Mej-Tal" + "
" + " (with 60 Magic)", "Members now have the Attack level required to wield " + "" + "Toktz-Mej-Tal" + "" + ". (They also need level 60 Magic.)"); + case 79: + return newstruct cs2func_script_982_struct(60, 20671, "Members: Brackish Blade", "Members can now wield " + "" + "Brackish Blades" + "" + "."); + case 80: + return newstruct cs2func_script_982_struct(62, 19669, "Members: Ring of vigour" + "
" + " (with 62 Dungeoneering)", "Members can now wear " + "" + "rings of vigour" + "" + ". (They also need level 62 Dungeoneering.)"); + case 81: + return newstruct cs2func_script_982_struct(70, 4151, "Members: Abyssal whip", "Members can now wield " + "" + "abyssal whips" + "" + "."); + case 82: + return newstruct cs2func_script_982_struct(70, 15485, "Members: Penance master trident (with 70 Magic)", "Members can now wield " + "" + "penance master tridents" + "" + ". (They also need level 70 Magic.)"); + case 83: + return newstruct cs2func_script_982_struct(70, 11730, "Members: Saradomin sword", "Members can now wield " + "" + "Saradomin swords" + "" + "."); + case 84: + return newstruct cs2func_script_982_struct(70, 11716, "Members: Zamorakian spear", "Members can now wield " + "" + "Zamorakian spears" + "" + "."); + case 85: + return newstruct cs2func_script_982_struct(70, 21582, "Members: Blisterwood polearm (after The Branches of Darkmeyer)", "Members can now wield " + "" + "blisterwood polearms" + "" + " (after The Branches of Darkmeyer.)"); + case 86: + return newstruct cs2func_script_982_struct(75, 11694, "Members: Armadyl godsword", "Members can now wield the " + "" + "Armadyl godsword" + "" + "."); + case 87: + return newstruct cs2func_script_982_struct(75, 11696, "Members: Bandos godsword", "Members can now wield the " + "" + "Bandos godsword" + "" + "."); + case 88: + return newstruct cs2func_script_982_struct(75, 11698, "Members: Saradomin godsword", "Members can now wield the " + "" + "Saradomin godsword" + "" + "."); + case 89: + return newstruct cs2func_script_982_struct(75, 11700, "Members: Zamorak godsword", "Members can now wield the " + "" + "Zamorak godsword" + "" + "."); + case 90: + return newstruct cs2func_script_982_struct(75, 15403, "Members: Balmung (after Blood Runs Deep and with 75 Strength)", "Members can now wield " + "" + "Balmung" + "" + " (after Blood Runs Deep, with 75 Strength)."); + case 91: + return newstruct cs2func_script_982_struct(75, 15486, "Members: Staff of Light (with 75 Magic)", "Members can now wield the " + "" + "Staff of Light" + "" + " (with 75 Magic)."); + case 92: + return newstruct cs2func_script_982_struct(75, 21787, "Members: Steadfast boots" + "
" + " (with 75 Defence)", "Members now have the Attack level required to wear " + "" + "steadfast boots" + "" + " (with 75 Defence)."); + case 93: + return newstruct cs2func_script_982_struct(78, 13902, "Members: Statius's warhammer", "Members now have the Attack level required to wield " + "" + "Statius's warhammer" + "" + "."); + case 94: + return newstruct cs2func_script_982_struct(78, 13899, "Members: Vesta's longsword", "Members now have the Attack level required to wield " + "" + "Vesta's longsword" + "" + "."); + case 95: + return newstruct cs2func_script_982_struct(78, 13905, "Members: Vesta's spear", "Members now have the Attack level required to wield " + "" + "Vesta's spear" + "" + "."); + case 96: + return newstruct cs2func_script_982_struct(78, 13867, "Members: Zuriel's staff" + "
" + " (with 78 Magic)", "Members now have the Attack level required to wield " + "" + "Zuriel's staff" + "" + " (with level 78 Magic)."); + case 97: + return newstruct cs2func_script_982_struct(80, 18349, "Members: Chaotic rapier" + "
" + " (with 80 Dungeoneering)", "Members can now wield " + "" + "chaotic rapiers" + "" + ". (They also need level 80 Dungeoneering.)"); + case 98: + return newstruct cs2func_script_982_struct(80, 18351, "Members: Chaotic longsword" + "
" + " (with 80 Dungeoneering)", "Members can now wield " + "" + "chaotic longswords" + "" + ". (They also need level 80 Dungeoneering.)"); + case 99: + return newstruct cs2func_script_982_struct(80, 18353, "Members: Chaotic maul" + "
" + " (with 80 Dungeoneering)", "Members can now wield " + "" + "chaotic mauls" + "" + ". (They also need level 80 Dungeoneering.)"); + case 100: + return newstruct cs2func_script_982_struct(85, 21371, "Members: Abyssal vine whip" + "
" + " (with 80 Slayer)", "Members now have the Attack level required to wield " + "" + "abyssal vine whips" + "" + ". (They also need level 80 Slayer.)"); + } + break; + case 11: + switch (arg1) { + case 0: + return newstruct cs2func_script_982_struct(30, 10149, "Members: Swamp lizard" + "
" + " (with 30 Magic and 30 Ranged)", "Members now have the Attack level required to wield " + "" + "swamp lizards" + "" + ". (They also need level 30 Magic and level 30 Ranged.)"); + case 1: + return newstruct cs2func_script_982_struct(50, 10146, "Members: Orange salamander" + "
" + " (with 50 Magic and 50 Ranged)", "Members now have the Attack level required to wield " + "" + "orange salamanders" + "" + ". (They also need level 50 Magic and level 50 Ranged.)"); + case 2: + return newstruct cs2func_script_982_struct(60, 10147, "Members: Red salamander" + "
" + " (with 60 Magic and 60 Ranged)", "Members now have the Attack level required to wield " + "" + "red salamanders" + "" + ". (They also need level 60 Magic and level 60 Ranged.)"); + case 3: + return newstruct cs2func_script_982_struct(70, 10148, "Members: Black salamander" + "
" + " (with 70 Magic and 70 Ranged)", "Members now have the Attack level required to wield " + "" + "black salamanders" + "" + ". (They also need level 70 Magic and level 70 Ranged.)"); + } + break; + case 12: + switch (arg1) { + case 0: + return newstruct cs2func_script_982_struct(1, 14297, "Members: Stealing Creation - class 1 dagger", "Members can now wield " + "" + "class 1 daggers" + "" + " in Stealing Creation."); + case 1: + return newstruct cs2func_script_982_struct(1, 14287, "Members: Stealing Creation - class 1 scimitar", "Members can now wield " + "" + "class 1 scimitars" + "" + " in Stealing Creation."); + case 2: + return newstruct cs2func_script_982_struct(1, 14307, "Members: Stealing Creation - class 1 warhammer", "Members can now wield " + "" + "class 1 warhammers" + "" + " in Stealing Creation."); + case 3: + return newstruct cs2func_script_982_struct(20, 14299, "Members: Stealing Creation - class 2 dagger", "Members can now wield " + "" + "class 2 daggers" + "" + " in Stealing Creation."); + case 4: + return newstruct cs2func_script_982_struct(20, 14289, "Members: Stealing Creation - class 2 scimitar", "Members can now wield " + "" + "class 2 scimitars" + "" + " in Stealing Creation."); + case 5: + return newstruct cs2func_script_982_struct(20, 14309, "Members: Stealing Creation - class 2 warhammer", "Members can now wield " + "" + "class 2 warhammers" + "" + " in Stealing Creation."); + case 6: + return newstruct cs2func_script_982_struct(40, 14301, "Members: Stealing Creation - class 3 dagger", "Members can now wield " + "" + "class 3 daggers" + "" + " in Stealing Creation."); + case 7: + return newstruct cs2func_script_982_struct(40, 14291, "Members: Stealing Creation - class 3 scimitar", "Members can now wield " + "" + "class 3 scimitars" + "" + " in Stealing Creation."); + case 8: + return newstruct cs2func_script_982_struct(40, 14311, "Members: Stealing Creation - class 3 warhammer", "Members can now wield " + "" + "class 3 warhammers" + "" + " in Stealing Creation."); + case 9: + return newstruct cs2func_script_982_struct(60, 14303, "Members: Stealing Creation - class 4 dagger", "Members can now wield " + "" + "class 4 daggers" + "" + " in Stealing Creation."); + case 10: + return newstruct cs2func_script_982_struct(60, 14293, "Members: Stealing Creation - class 4 scimitar", "Members can now wield " + "" + "class 4 scimitars" + "" + " in Stealing Creation."); + case 11: + return newstruct cs2func_script_982_struct(60, 14313, "Members: Stealing Creation - class 4 warhammer", "Members can now wield " + "" + "class 4 warhammers" + "" + " in Stealing Creation."); + case 12: + return newstruct cs2func_script_982_struct(80, 14305, "Members: Stealing Creation - class 5 dagger", "Members can now wield " + "" + "class 5 daggers" + "" + " in Stealing Creation."); + case 13: + return newstruct cs2func_script_982_struct(80, 14295, "Members: Stealing Creation - class 5 scimitar", "Members can now wield " + "" + "class 5 scimitars" + "" + " in Stealing Creation."); + case 14: + return newstruct cs2func_script_982_struct(80, 14315, "Members: Stealing Creation - class 5 warhammer", "Members can now wield " + "" + "class 5 warhammers" + "" + " in Stealing Creation."); + } + break; + case 13: + switch (arg1) { + case 0: + return newstruct cs2func_script_982_struct(1, 16757, "Novite dagger (Tier 1)", "You can now wield " + "" + "novite daggers" + "" + " within Daemonheim."); + case 1: + return newstruct cs2func_script_982_struct(1, 16935, "Novite rapier (Tier 1)", "You can now wield " + "" + "novite rapiers" + "" + " within Daemonheim."); + case 2: + return newstruct cs2func_script_982_struct(1, 16383, "Novite longsword (Tier 1)", "You can now wield " + "" + "novite longswords" + "" + " within Daemonheim."); + case 3: + return newstruct cs2func_script_982_struct(1, 15753, "Novite battleaxe (Tier 1)", "You can now wield " + "" + "novite battleaxes" + "" + " within Daemonheim."); + case 4: + return newstruct cs2func_script_982_struct(1, 16889, "Novite 2h swords (Tier 1)", "You can now wield " + "" + "novite 2h swords" + "" + " within Daemonheim."); + case 5: + return newstruct cs2func_script_982_struct(1, 17063, "Novite spears (Tier 1)", "You can now wield " + "" + "novite spears" + "" + " within Daemonheim."); + case 6: + return newstruct cs2func_script_982_struct(1, 17019, "Novite warhammer (Tier 1)", "You can now wield " + "" + "novite warhammers" + "" + " within Daemonheim."); + case 7: + return newstruct cs2func_script_982_struct(1, 16361, "Novite hatchet (Tier 1)", "You can now wield " + "" + "novite hatchets" + "" + " within Daemonheim."); + case 8: + return newstruct cs2func_script_982_struct(1, 16295, "Novite pickaxe (Tier 1)", "You can now wield " + "" + "novite pickaxes" + "" + " within Daemonheim."); + case 9: + return newstruct cs2func_script_982_struct(10, 16765, "Bathus dagger (Tier 2)", "You can now wield " + "" + "bathus daggers" + "" + " within Daemonheim."); + case 10: + return newstruct cs2func_script_982_struct(10, 16937, "Bathus rapier (Tier 2)", "You can now wield " + "" + "bathus rapiers" + "" + " within Daemonheim."); + case 11: + return newstruct cs2func_script_982_struct(10, 16385, "Bathus longsword (Tier 2)", "You can now wield " + "" + "bathus longswords" + "" + " within Daemonheim."); + case 12: + return newstruct cs2func_script_982_struct(10, 15755, "Bathus battleaxe (Tier 2)", "You can now wield " + "" + "bathus battleaxes" + "" + " within Daemonheim."); + case 13: + return newstruct cs2func_script_982_struct(10, 16891, "Bathus 2h swords (Tier 2)", "You can now wield " + "" + "bathus 2h swords" + "" + " within Daemonheim."); + case 14: + return newstruct cs2func_script_982_struct(10, 17071, "Bathus spears (Tier 2)", "You can now wield " + "" + "bathus spears" + "" + " within Daemonheim."); + case 15: + return newstruct cs2func_script_982_struct(10, 17021, "Bathus warhammer (Tier 2)", "You can now wield " + "" + "bathus warhammers" + "" + " within Daemonheim."); + case 16: + return newstruct cs2func_script_982_struct(10, 16363, "Bathus hatchet (Tier 2)", "You can now wield " + "" + "bathus hatchets" + "" + " within Daemonheim."); + case 17: + return newstruct cs2func_script_982_struct(10, 16297, "Bathus pickaxe (Tier 2)", "You can now wield " + "" + "bathus pickaxes" + "" + " within Daemonheim."); + case 18: + return newstruct cs2func_script_982_struct(20, 16773, "Marmaros dagger (Tier 3)", "You can now wield " + "" + "marmaros daggers" + "" + " within Daemonheim."); + case 19: + return newstruct cs2func_script_982_struct(20, 16939, "Marmaros rapier (Tier 3)", "You can now wield " + "" + "marmaros rapiers" + "" + " within Daemonheim."); + case 20: + return newstruct cs2func_script_982_struct(20, 16387, "Marmaros longsword (Tier 3)", "You can now wield " + "" + "marmaros longswords" + "" + " within Daemonheim."); + case 21: + return newstruct cs2func_script_982_struct(20, 15757, "Marmaros battleaxe (Tier 3)", "You can now wield " + "" + "marmaros battleaxes" + "" + " within Daemonheim."); + case 22: + return newstruct cs2func_script_982_struct(20, 16893, "Marmaros 2h swords (Tier 3)", "You can now wield " + "" + "marmaros 2h swords" + "" + " within Daemonheim."); + case 23: + return newstruct cs2func_script_982_struct(20, 17079, "Marmaros spears (Tier 3)", "You can now wield " + "" + "marmaros spears" + "" + " within Daemonheim."); + case 24: + return newstruct cs2func_script_982_struct(20, 17023, "Marmaros warhammer (Tier 3)", "You can now wield " + "" + "marmaros warhammers" + "" + " within Daemonheim."); + case 25: + return newstruct cs2func_script_982_struct(20, 16365, "Marmaros hatchet (Tier 3)", "You can now wield " + "" + "marmaros hatchets" + "" + " within Daemonheim."); + case 26: + return newstruct cs2func_script_982_struct(20, 16299, "Marmaros pickaxe (Tier 3)", "You can now wield " + "" + "marmaros pickaxes" + "" + " within Daemonheim."); + case 27: + return newstruct cs2func_script_982_struct(30, 16781, "Kratonite dagger (Tier 4)", "You can now wield " + "" + "kratonite daggers" + "" + " within Daemonheim."); + case 28: + return newstruct cs2func_script_982_struct(30, 16941, "Kratonite rapier (Tier 4)", "You can now wield " + "" + "kratonite rapiers" + "" + " within Daemonheim."); + case 29: + return newstruct cs2func_script_982_struct(30, 16389, "Kratonite longsword (Tier 4)", "You can now wield " + "" + "kratonite longswords" + "" + " within Daemonheim."); + case 30: + return newstruct cs2func_script_982_struct(30, 15759, "Kratonite battleaxe (Tier 4)", "You can now wield " + "" + "kratonite battleaxes" + "" + " within Daemonheim."); + case 31: + return newstruct cs2func_script_982_struct(30, 16895, "Kratonite 2h swords (Tier 4)", "You can now wield " + "" + "kratonite 2h swords" + "" + " within Daemonheim."); + case 32: + return newstruct cs2func_script_982_struct(30, 17087, "Kratonite spears (Tier 4)", "You can now wield " + "" + "kratonite spears" + "" + " within Daemonheim."); + case 33: + return newstruct cs2func_script_982_struct(30, 17025, "Kratonite warhammer (Tier 4)", "You can now wield " + "" + "kratonite warhammers" + "" + " within Daemonheim."); + case 34: + return newstruct cs2func_script_982_struct(30, 16367, "Kratonite hatchet (Tier 4)", "You can now wield " + "" + "kratonite hatchets" + "" + " within Daemonheim."); + case 35: + return newstruct cs2func_script_982_struct(30, 16301, "Kratonite pickaxe (Tier 4)", "You can now wield " + "" + "kratonite pickaxes" + "" + " within Daemonheim."); + case 36: + return newstruct cs2func_script_982_struct(36, 17275, "Members: Frostbite dagger" + "
" + " (with 36 Magic)", "Members can now wield " + "" + "frostbite daggers" + "" + " within Daemonheim. (They also need level 36 Magic.)"); + case 37: + return newstruct cs2func_script_982_struct(40, 16789, "Fractite dagger (Tier 5)", "You can now wield " + "" + "fractite daggers" + "" + " within Daemonheim."); + case 38: + return newstruct cs2func_script_982_struct(40, 16943, "Fractite rapier (Tier 5)", "You can now wield " + "" + "fractite rapiers" + "" + " within Daemonheim."); + case 39: + return newstruct cs2func_script_982_struct(40, 16391, "Fractite longsword (Tier 5)", "You can now wield " + "" + "fractite longswords" + "" + " within Daemonheim."); + case 40: + return newstruct cs2func_script_982_struct(40, 15761, "Fractite battleaxe (Tier 5)", "You can now wield " + "" + "fractite battleaxes" + "" + " within Daemonheim."); + case 41: + return newstruct cs2func_script_982_struct(40, 16897, "Fractite 2h swords (Tier 5)", "You can now wield " + "" + "fractite 2h swords" + "" + " within Daemonheim."); + case 42: + return newstruct cs2func_script_982_struct(40, 17095, "Fractite spears (Tier 5)", "You can now wield " + "" + "fractite spears" + "" + " within Daemonheim."); + case 43: + return newstruct cs2func_script_982_struct(40, 17027, "Fractite warhammer (Tier 5)", "You can now wield " + "" + "fractite warhammers" + "" + " within Daemonheim."); + case 44: + return newstruct cs2func_script_982_struct(40, 16369, "Fractite hatchet (Tier 5)", "You can now wield " + "" + "fractite hatchets" + "" + " within Daemonheim."); + case 45: + return newstruct cs2func_script_982_struct(40, 16303, "Fractite pickaxe (Tier 5)", "You can now wield " + "" + "fractite pickaxes" + "" + " within Daemonheim."); + case 46: + return newstruct cs2func_script_982_struct(50, 16797, "Members: Zephyrium dagger (Tier 6)", "Members can now wield " + "" + "zephyrium daggers" + "" + " within Daemonheim."); + case 47: + return newstruct cs2func_script_982_struct(50, 16945, "Members: Zephyrium rapier (Tier 6)", "Members can now wield " + "" + "zephyrium rapiers" + "" + " within Daemonheim."); + case 48: + return newstruct cs2func_script_982_struct(50, 16393, "Members: Zephyrium longsword (Tier 6)", "Members can now wield " + "" + "zephyrium longswords" + "" + " within Daemonheim."); + case 49: + return newstruct cs2func_script_982_struct(50, 15763, "Members: Zephyrium battleaxe (Tier 6)", "Members can now wield " + "" + "zephyrium battleaxes" + "" + " within Daemonheim."); + case 50: + return newstruct cs2func_script_982_struct(50, 16899, "Members: Zephyrium 2h swords (Tier 6)", "Members can now wield " + "" + "zephyrium 2h swords" + "" + " within Daemonheim."); + case 51: + return newstruct cs2func_script_982_struct(50, 17103, "Members: Zephyrium spears (Tier 6)", "Members can now wield " + "" + "zephyrium spears" + "" + " within Daemonheim."); + case 52: + return newstruct cs2func_script_982_struct(50, 17029, "Members: Zephyrium warhammer (Tier 6)", "Members can now wield " + "" + "zephyrium warhammers" + "" + " within Daemonheim."); + case 53: + return newstruct cs2func_script_982_struct(50, 16371, "Members: Zephyrium hatchet (Tier 6)", "Members can now wield " + "" + "zephyrium hatchets" + "" + " within Daemonheim."); + case 54: + return newstruct cs2func_script_982_struct(50, 16305, "Members: Zephyrium pickaxe (Tier 6)", "Members can now wield " + "" + "zephyrium pickaxes" + "" + " within Daemonheim."); + case 55: + return newstruct cs2func_script_982_struct(60, 16805, "Members: Argonite dagger (Tier 7)", "Members can now wield " + "" + "argonite daggers" + "" + " within Daemonheim."); + case 56: + return newstruct cs2func_script_982_struct(60, 16947, "Members: Argonite rapier (Tier 7)", "Members can now wield " + "" + "argonite rapiers" + "" + " within Daemonheim."); + case 57: + return newstruct cs2func_script_982_struct(60, 16395, "Members: Argonite longsword (Tier 7)", "Members can now wield " + "" + "argonite longswords" + "" + " within Daemonheim."); + case 58: + return newstruct cs2func_script_982_struct(60, 15765, "Members: Argonite battleaxe (Tier 7)", "Members can now wield " + "" + "argonite battleaxes" + "" + " within Daemonheim."); + case 59: + return newstruct cs2func_script_982_struct(60, 16901, "Members: Argonite 2h swords (Tier 7)", "Members can now wield " + "" + "argonite 2h swords" + "" + " within Daemonheim."); + case 60: + return newstruct cs2func_script_982_struct(60, 17111, "Members: Argonite spears (Tier 7)", "Members can now wield " + "" + "argonite spears" + "" + " within Daemonheim."); + case 61: + return newstruct cs2func_script_982_struct(60, 17031, "Members: Argonite warhammer (Tier 7)", "Members can now wield " + "" + "argonite warhammers" + "" + " within Daemonheim."); + case 62: + return newstruct cs2func_script_982_struct(60, 16373, "Members: Argonite hatchet (Tier 7)", "Members can now wield " + "" + "argonite hatchets" + "" + " within Daemonheim."); + case 63: + return newstruct cs2func_script_982_struct(60, 16307, "Members: Argonite pickaxe (Tier 7)", "Members can now wield " + "" + "argonite pickaxes" + "" + " within Daemonheim."); + case 64: + return newstruct cs2func_script_982_struct(68, 17275, "Members: Hailstorm dagger" + "
" + " (with 68 Magic)", "Members can now wield " + "" + "hailstorm daggers" + "" + " within Daemonheim. (They also need level 68 Magic)"); + case 65: + return newstruct cs2func_script_982_struct(68, 17293, "Members: Doomcore staff" + "
" + " (with 68 Magic)", "Members can now wield " + "" + "doomcore staves" + "" + " within Daemonheim. (They also need level 68 Magic.)"); + case 66: + return newstruct cs2func_script_982_struct(70, 16813, "Members: Katagon dagger (Tier 8)", "Members can now wield " + "" + "katagon daggers" + "" + " within Daemonheim."); + case 67: + return newstruct cs2func_script_982_struct(70, 16949, "Members: Katagon rapier (Tier 8)", "Members can now wield " + "" + "katagon rapiers" + "" + " within Daemonheim."); + case 68: + return newstruct cs2func_script_982_struct(70, 16397, "Members: Katagon longsword (Tier 8)", "Members can now wield " + "" + "katagon longswords" + "" + " within Daemonheim."); + case 69: + return newstruct cs2func_script_982_struct(70, 15767, "Members: Katagon battleaxe (Tier 8)", "Members can now wield " + "" + "katagon battleaxes" + "" + " within Daemonheim."); + case 70: + return newstruct cs2func_script_982_struct(70, 16903, "Members: Katagon 2h swords (Tier 8)", "Members can now wield " + "" + "katagon 2h swords" + "" + " within Daemonheim."); + case 71: + return newstruct cs2func_script_982_struct(70, 17119, "Members: Katagon spears (Tier 8)", "Members can now wield " + "" + "katagon spears" + "" + " within Daemonheim."); + case 72: + return newstruct cs2func_script_982_struct(70, 17033, "Members: Katagon warhammer (Tier 8)", "Members can now wield " + "" + "katagon warhammers" + "" + " within Daemonheim."); + case 73: + return newstruct cs2func_script_982_struct(70, 16375, "Members: Katagon hatchet (Tier 8)", "Members can now wield " + "" + "katagon hatchets" + "" + " within Daemonheim."); + case 74: + return newstruct cs2func_script_982_struct(70, 16309, "Members: Katagon pickaxe (Tier 8)", "Members can now wield " + "" + "katagon pickaxes" + "" + " within Daemonheim."); + case 75: + return newstruct cs2func_script_982_struct(80, 16821, "Members: Gorgonite dagger (Tier 9)", "Members can now wield " + "" + "gorgonite daggers" + "" + " within Daemonheim."); + case 76: + return newstruct cs2func_script_982_struct(80, 16951, "Members: Gorgonite rapier (Tier 9)", "Members can now wield " + "" + "gorgonite rapiers" + "" + " within Daemonheim."); + case 77: + return newstruct cs2func_script_982_struct(80, 16399, "Members: Gorgonite longsword (Tier 9)", "Members can now wield " + "" + "gorgonite longswords" + "" + " within Daemonheim."); + case 78: + return newstruct cs2func_script_982_struct(80, 15769, "Members: Gorgonite battleaxe (Tier 9)", "Members can now wield " + "" + "gorgonite battleaxes" + "" + " within Daemonheim."); + case 79: + return newstruct cs2func_script_982_struct(80, 16905, "Members: Gorgonite 2h swords (Tier 9)", "Members can now wield " + "" + "gorgonite 2h swords" + "" + " within Daemonheim."); + case 80: + return newstruct cs2func_script_982_struct(80, 17127, "Members: Gorgonite spears (Tier 9)", "Members can now wield " + "" + "gorgonite spears" + "" + " within Daemonheim."); + case 81: + return newstruct cs2func_script_982_struct(80, 17035, "Members: Gorgonite warhammer (Tier 9)", "Members can now wield " + "" + "gorgonite warhammers" + "" + " within Daemonheim."); + case 82: + return newstruct cs2func_script_982_struct(80, 16377, "Members: Gorgonite hatchet (Tier 9)", "Members can now wield " + "" + "gorgonite hatchets" + "" + " within Daemonheim."); + case 83: + return newstruct cs2func_script_982_struct(80, 16311, "Members: Gorgonite pickaxe (Tier 9)", "Members can now wield " + "" + "gorgonite pickaxes" + "" + " within Daemonheim."); + case 84: + return newstruct cs2func_script_982_struct(90, 16829, "Members: Promethium dagger (Tier 10)", "Members can now wield " + "" + "promethium daggers" + "" + " within Daemonheim."); + case 85: + return newstruct cs2func_script_982_struct(90, 16953, "Members: Promethium rapier (Tier 10)", "Members can now wield " + "" + "promethium rapiers" + "" + " within Daemonheim."); + case 86: + return newstruct cs2func_script_982_struct(90, 16401, "Members: Promethium longsword (Tier 10)", "Members can now wield " + "" + "promethium longswords" + "" + " within Daemonheim."); + case 87: + return newstruct cs2func_script_982_struct(90, 15771, "Members: Promethium battleaxe (Tier 10)", "Members can now wield " + "" + "promethium battleaxes" + "" + " within Daemonheim."); + case 88: + return newstruct cs2func_script_982_struct(90, 16907, "Members: Promethium 2h swords (Tier 10)", "Members can now wield " + "" + "promethium 2h swords" + "" + " within Daemonheim."); + case 89: + return newstruct cs2func_script_982_struct(90, 17135, "Members: Promethium spears (Tier 10)", "Members can now wield " + "" + "promethium spears" + "" + " within Daemonheim."); + case 90: + return newstruct cs2func_script_982_struct(90, 17037, "Members: Promethium warhammer (Tier 10)", "Members can now wield " + "" + "promethium warhammers" + "" + " within Daemonheim."); + case 91: + return newstruct cs2func_script_982_struct(90, 16379, "Members: Promethium hatchet (Tier 10)", "Members can now wield " + "" + "promethium hatchets" + "" + " within Daemonheim."); + case 92: + return newstruct cs2func_script_982_struct(90, 16313, "Members: Promethium pickaxe (Tier 10)", "Members can now wield " + "" + "promethium pickaxes" + "" + " within Daemonheim."); + case 93: + return newstruct cs2func_script_982_struct(99, 16837, "Members: Primal dagger (Tier 11)", "Members can now wield " + "" + "primal daggers" + "" + " within Daemonheim."); + case 94: + return newstruct cs2func_script_982_struct(99, 16955, "Members: Primal rapier (Tier 11)", "Members can now wield " + "" + "primal rapiers" + "" + " within Daemonheim."); + case 95: + return newstruct cs2func_script_982_struct(99, 16403, "Members: Primal longsword (Tier 11)", "Members can now wield " + "" + "primal longswords" + "" + " within Daemonheim."); + case 96: + return newstruct cs2func_script_982_struct(99, 15773, "Members: Primal battleaxe (Tier 11)", "Members can now wield " + "" + "primal battleaxes" + "" + " within Daemonheim."); + case 97: + return newstruct cs2func_script_982_struct(99, 16909, "Members: Primal 2h swords (Tier 11)", "Members can now wield " + "" + "primal 2h swords" + "" + " within Daemonheim."); + case 98: + return newstruct cs2func_script_982_struct(99, 17143, "Members: Primal spears (Tier 11)", "Members can now wield " + "" + "primal spears" + "" + " within Daemonheim."); + case 99: + return newstruct cs2func_script_982_struct(99, 17039, "Members: Primal warhammer (Tier 11)", "Members can now wield " + "" + "primal warhammers" + "" + " within Daemonheim."); + case 100: + return newstruct cs2func_script_982_struct(99, 16381, "Members: Primal hatchet (Tier 11)", "Members can now wield " + "" + "primal hatchets" + "" + " within Daemonheim."); + case 101: + return newstruct cs2func_script_982_struct(99, 16315, "Members: Primal pickaxe (Tier 11)", "Members can now wield " + "" + "primal pickaxes" + "" + " within Daemonheim."); + } + break; + case 14: + SWITCH (arg1) { + case 0: + GOTO flow_383 + case 1: + GOTO flow_384 + } + break; + flow_383: + return newstruct cs2func_script_982_struct(-1, 8855, "You can enter the Warriors' Guild when your Attack and Strength levels add up to 130 or more, or when you reach level 99 in either Attack or Strength.", ""); + flow_384: + return newstruct cs2func_script_982_struct(99, 9747, "Skill mastery", "" + "Congratulations! You are now a master of " + "" + "Attack" + "" + ". Members can visit " + "" + "Ajjat" + "" + " at the " + "" + "Warriors' Guild" + "" + ". He has something special that is only available to true masters of the " + "" + "Attack" + "" + " skill!"); + } + return newstruct cs2func_script_982_struct(0, -1, "", ""); +} diff --git a/dumps/scripts/983.cs2 b/dumps/scripts/983.cs2 new file mode 100644 index 0000000..230cdde --- /dev/null +++ b/dumps/scripts/983.cs2 @@ -0,0 +1,21 @@ +cs2func_script_983_struct(1,1,0) script_983(int arg0) { + switch (arg0) { + case 0: + return newstruct cs2func_script_983_struct(1, "Weaponry"); + case 1: + return newstruct cs2func_script_983_struct(1, "Armour"); + case 2: + return newstruct cs2func_script_983_struct(1, "Shortcuts"); + case 3: + return newstruct cs2func_script_983_struct(1, "Areas"); + case 4: + return newstruct cs2func_script_983_struct(1, "Barbarian"); + case 5: + return newstruct cs2func_script_983_struct(0, "Dungeoneering"); + case 6: + return newstruct cs2func_script_983_struct(0, "Milestones"); + case 7: + return newstruct cs2func_script_983_struct(1, "Minigames"); + } + return newstruct cs2func_script_983_struct(-1, ""); +} diff --git a/dumps/scripts/984.cs2 b/dumps/scripts/984.cs2 new file mode 100644 index 0000000..100cefd --- /dev/null +++ b/dumps/scripts/984.cs2 @@ -0,0 +1,202 @@ +cs2func_script_984_struct(2,2,0) script_984(int arg0,int arg1) { + switch (arg0) { + flow_1: + case 0: + switch (arg1) { + case 0: + return newstruct cs2func_script_984_struct(1, 21340, "Members: Dwarven Army Axe", "Members can now wield a " + "" + "Dwarven Army Axe" + "" + "."); + case 1: + return newstruct cs2func_script_984_struct(5, 3196, "Black halberd" + "
" + " (with 10 Attack)", "Members now have the Strength level required to wield " + "" + "black halberds" + "" + ". (You also need level 10 Attack.)"); + case 2: + return newstruct cs2func_script_984_struct(5, 6599, "White halberd" + "
" + " (with 10 Attack)", "Members now have the Strength level required to wield " + "" + "white halberds" + "" + ". (You also need level 10 Attack.)"); + case 3: + return newstruct cs2func_script_984_struct(10, 3198, "Mithril halberd" + "
" + " (with 20 Attack)", "Members now have the Strength level required to wield " + "" + "mithril halberds" + "" + ". (You also need level 20 Attack.)"); + case 4: + return newstruct cs2func_script_984_struct(15, 3200, "Adamant halberd" + "
" + " (with 30 Attack)", "Members now have the Strength level required to wield " + "" + "adamant halberds" + "" + ". (You also need level 30 Attack.)"); + case 5: + return newstruct cs2func_script_984_struct(20, 3202, "Rune halberd" + "
" + " (with 40 Attack)", "Members now have the Strength level required to wield " + "" + "rune halberds" + "" + ". (You also need level 40 Attack.)"); + case 6: + return newstruct cs2func_script_984_struct(30, 3204, "Dragon halberd" + "
" + " (with 60 Attack)", "Members now have the Strength level required to wield " + "" + "dragon halberds" + "" + ". (They also need level 60 Attack.)"); + case 7: + return newstruct cs2func_script_984_struct(42, 8841, "Members: Void knight mace", "Members now have the Strength level required to wield " + "" + "Void knight maces" + "" + "."); + case 8: + return newstruct cs2func_script_984_struct(50, 4153, "Granite maul" + "
" + " (with 50 Attack)", "Members now have the Strength level required to wield " + "" + "granite mauls" + "" + ". (They also need level 50 Attack.)"); + case 9: + return newstruct cs2func_script_984_struct(50, 14679, "Granite mace" + "
" + " (with 50 Attack)", "Members now have the Strength level required to wield " + "" + "granite maces" + "" + ". (They also need level 50 Attack.)"); + case 10: + return newstruct cs2func_script_984_struct(60, 6528, "Tzhaar-Ket-Om", "Members can now wield " + "" + "Tzhaar-Ket-Om" + "" + "."); + case 11: + return newstruct cs2func_script_984_struct(70, 4718, "Dharok's greataxe" + "
" + " (with 70 Attack)", "Members now have the Strength level required to wield " + "" + "Dharok's greataxe" + "" + ". (They also need level 70 Attack.)"); + case 12: + return newstruct cs2func_script_984_struct(70, 4747, "Torag's hammers" + "
" + " (with 70 Attack)", "Members now have the Strength level required to wield " + "" + "Torag's hammers" + "" + ". (They also need level 70 Attack.)"); + case 13: + return newstruct cs2func_script_984_struct(75, 15403, "Members: Balmung (after Blood Runs Deep and with 75 Attack)", "Members can now wield " + "" + "Balmung" + "" + " (after Blood Runs Deep, with 75 Attack)."); + } + break; + case 1: + switch (arg1) { + case 0: + return newstruct cs2func_script_984_struct(20, 8921, "Members: Black mask" + "
" + " (with 10 Defence)", "Members can now wear " + "" + "black masks (with 10 Defence)" + "" + "."); + case 1: + return newstruct cs2func_script_984_struct(20, 15492, "Members: Full Slayer helmet" + "
" + " (after Smoking Kills with 20 Ranged, Magic and 10 Defence)", "Members can now wear " + "" + "full slayer helmets" + "" + " (after Smoking Kills with 20 Ranged, Magic and 10 Defence)."); + case 2: + return newstruct cs2func_script_984_struct(42, 11665, "Members: Void melee helm", "Members now have the Strength level required to wear " + "" + "Void melee helms" + "" + "."); + case 3: + return newstruct cs2func_script_984_struct(42, 11664, "Members: Void ranger helm", "Members now have the Strength level required to wear " + "" + "Void ranger helms" + "" + "."); + case 4: + return newstruct cs2func_script_984_struct(42, 11663, "Members: Void mage helm", "Members now have the Strength level required to wear " + "" + "Void mage helms" + "" + "."); + case 5: + return newstruct cs2func_script_984_struct(42, 8839, "Members: Void knight top", "Members now have the Strength level required to wear " + "" + "Void knight tops" + "" + "."); + case 6: + return newstruct cs2func_script_984_struct(42, 8840, "Members: Void knight robe", "Members now have the Strength level required to wear " + "" + "Void knight robes" + "" + "."); + case 7: + return newstruct cs2func_script_984_struct(42, 8842, "Members: Void knight gloves", "Members now have the Strength level required to wear " + "" + "Void knight gloves" + "" + "."); + case 8: + return newstruct cs2func_script_984_struct(42, 19712, "Members: Void knight deflector", "Members now have the Strength level required to wear " + "" + "Void knight deflectors" + "" + "."); + case 9: + return newstruct cs2func_script_984_struct(42, 7620, "Void knight equipment requires 42 Attack, Defence, Strength, Ranged, Magic and Constitution and 22 Prayer.", "" + "Void knight equipment" + "" + " requires 42 Attack, Defence, Strength, Ranged, Magic and Constitution and 22 Prayer."); + case 10: + return newstruct cs2func_script_984_struct(50, 10589, "Granite helm" + "
" + " (with 50 Defence)", "Members now have the Strength level required to wear " + "" + "granite helms" + "" + ". (They also need level 50 Defence.)"); + case 11: + return newstruct cs2func_script_984_struct(50, 10564, "Granite body" + "
" + " (with 50 Defence)", "Members now have the Strength level required to wear " + "" + "granite bodies" + "" + ". (They also need level 50 Defence.)"); + case 12: + return newstruct cs2func_script_984_struct(50, 6809, "Granite legs" + "
" + " (with 50 Defence)", "Members now have the Strength level required to wear " + "" + "granite legs" + "" + ". (They also need level 50 Defence.)"); + case 13: + return newstruct cs2func_script_984_struct(50, 3122, "Granite shield" + "
" + " (with 50 Defence)", "Members now have the Strength level required to wield " + "" + "granite shields" + "" + ". (They also need level 50 Defence.)"); + case 14: + return newstruct cs2func_script_984_struct(80, 20135, "Members: Torva full helm" + "
" + " (with 80 Defence and Constitution)", "Members can now wear " + "" + "torva full helms" + "" + ". (They also need level 80 Defence and Constitution.)"); + case 15: + return newstruct cs2func_script_984_struct(80, 20139, "Members: Torva platebody" + "
" + " (with 80 Defence and Constitution)", "Members can now wear " + "" + "torva platebodies" + "" + ". (They also need level 80 Defence and Constitution.)"); + case 16: + return newstruct cs2func_script_984_struct(80, 20143, "Members: Torva platelegs" + "
" + " (with 80 Defence and Constitution)", "Members can now wear " + "" + "torva platelegs" + "" + ". (They also need level 80 Defence and Constitution.)"); + } + break; + case 2: + switch (arg1) { + case 0: + return newstruct cs2func_script_984_struct(19, 6515, "River crossing to Al Kharid" + "
" + " (with 8 Agility and 37 Ranged)", "You now have the Strength level required to cross the " + "" + "River Lum" + "" + " to " + "" + "Al Kharid" + "" + ". (You also need level 8 Agility and level 37 Ranged.)"); + case 1: + return newstruct cs2func_script_984_struct(21, 6515, "Karamja crossing, south of the volcano" + "
" + " (with 53 Agility and 42 Ranged)", "You now have the Strength level required to use the " + "" + "Karamja crossing, south of the volcano" + "" + ". (You also need level 53 Agility and level 42 Ranged."); + case 2: + return newstruct cs2func_script_984_struct(22, 6515, "Water Obelisk Island escape" + "
" + " (with 36 Agility and 39 Ranged)", "You now have the Strength level required to make the " + "" + "Water Obelisk Island escape" + "" + ". (You also need level 36 Agility and level 39 Ranged)."); + case 3: + return newstruct cs2func_script_984_struct(35, 6517, "Catherby cliff" + "
" + " (after Fishing Contest, with 32 Agility and 35 Ranged)", "You now have the Strength level required to scale " + "" + "Catherby cliff" + "" + " (after Fishing Contest, with level 32 Agility and level 35 Ranged)."); + case 4: + return newstruct cs2func_script_984_struct(37, 6517, "Falador wall" + "
" + " (with 11 Agility and 19 Ranged)", "You now have the Strength level required to scale " + "" + "Falador wall" + "" + ". (You also need level 11 Agility and level 19 Ranged.)"); + case 5: + return newstruct cs2func_script_984_struct(38, 6517, "Yanille wall" + "
" + " (with 39 Agility and 21 Ranged)", "You now have the Strength level required to scale " + "" + "Yanille wall" + "" + ". (You also need level 39 Agility and level 21 Ranged.)"); + case 6: + return newstruct cs2func_script_984_struct(60, 6515, "Cross Bandos's Throne Room " + "
" + " (after The Chosen Commander and with 60 Agility and 60 Ranged)", "Members now have the Strength level required to cross " + "" + "Bandos's throne room" + "" + " (after The Chosen Commander and with 60 Agility and 60 Ranged)."); + case 7: + return newstruct cs2func_script_984_struct(80, 6515, "Cross cave, south of Dorgesh-Kaan " + "
" + " (after Death to the Dorgeshuun, with 80 Agility and 80 Ranged)", "You now have the Strength level required to " + "" + "cross the cave, south of Dorgesh-Kaan" + "" + " (after Death to the Dorgeshuun, with 80 Agility and 80 Ranged)."); + } + break; + case 3: + if (((boolean)arg1)) { + return newstruct cs2func_script_984_struct(60, 4043, "God Wars Dungeon access via the Strength route", "You can now access the " + "" + "God Wars Dungeon" + "" + " via the " + "" + "Strength route" + "" + "."); + } + if (((boolean)arg1)) { + return newstruct cs2func_script_984_struct(70, 8122, "Bandos's Stronghold of the God Wars Dungeon", "You can now enter the " + "" + "Bandos's Stronghold" + "" + " of the " + "" + "God Wars Dungeon" + "" + "."); + } + break; + case 4: + switch (arg1) { + case 0: + return newstruct cs2func_script_984_struct(-1, 7620, "To start fishing like a barbarian, talk to Otto Godblessed when you have at least level 48 Fishing and level 15 Agility.", ""); + case 1: + return newstruct cs2func_script_984_struct(15, 11328, "Leaping trout" + "
" + " (with 15 Agility and 48 Fishing)", "Members versed in the art of barbarian fishing now have the Strength level required to catch " + "" + "leaping trout" + "" + ". (They also need level 15 Agility and level 48 Fishing.)"); + case 2: + return newstruct cs2func_script_984_struct(30, 11330, "Leaping salmon" + "
" + " (with 30 Agility and 58 Fishing)", "Members versed in the art of barbarian fishing now have the Strength level required to catch " + "" + "leaping salmon" + "" + ". (They also need level 30 Agility and level 58 Fishing.)"); + case 3: + return newstruct cs2func_script_984_struct(35, 11322, "Tuna" + "
" + " (with 55 Fishing)", "Members versed in the art of barbarian fishing now have the Strength level required to catch " + "" + "tuna" + "" + " without a harpoon. (They also need level 55 Fishing.)"); + case 4: + return newstruct cs2func_script_984_struct(45, 11332, "Leaping sturgeon" + "
" + " (with 45 Agility and 70 Fishing)", "Members versed in the art of barbarian fishing now have the Strength level required to catch " + "" + "leaping sturgeon" + "" + ". (They also need level 45 Agility and level 70 Fishing.)"); + case 5: + return newstruct cs2func_script_984_struct(50, 11321, "Swordfish" + "
" + " (with 70 Fishing)", "Members versed in the art of barbarian fishing now have the Strength level required to catch " + "" + "swordfish" + "" + " without a harpoon. (They also need level 70 Fishing.)"); + case 6: + return newstruct cs2func_script_984_struct(76, 11320, "Shark" + "
" + " (with 96 Fishing)", "Members versed in the art of barbarian fishing now have the Strength level required to catch " + "" + "shark" + "" + " without a harpoon. (They also need level 96 Fishing.)"); + } + break; + case 5: + switch (arg1) { + case 0: + return newstruct cs2func_script_984_struct(-1, 15707, "Dungeoneering skill tasks" + "
" + "As your Strength level increases, you will be able to attempt higher-level strength tasks within Daemonheim. You will also be more likely to succeed when attempting strength tasks within Daemonheim.", ""); + case 1: + return newstruct cs2func_script_984_struct(1, 16405, "Novite maul (Tier 1)", "You can now wield " + "" + "novite mauls" + "" + " within Daemonheim."); + case 2: + return newstruct cs2func_script_984_struct(10, 16407, "Bathus maul (Tier 2)", "You can now wield " + "" + "bathus mauls" + "" + " within Daemonheim."); + case 3: + return newstruct cs2func_script_984_struct(20, 16409, "Marmaros maul (Tier 3)", "You can now wield " + "" + "marmaros mauls" + "" + " within Daemonheim."); + case 4: + return newstruct cs2func_script_984_struct(30, 16411, "Kratonite maul (Tier 4)", "You can now wield " + "" + "kratonite mauls" + "" + " within Daemonheim."); + case 5: + return newstruct cs2func_script_984_struct(40, 16413, "Fractite maul (Tier 5)", "You can now wield " + "" + "fractite mauls" + "" + " within Daemonheim."); + case 6: + return newstruct cs2func_script_984_struct(50, 16415, "Members: Zephyrium maul (Tier 6)", "Members can now wield " + "" + "zephyrium mauls" + "" + " within Daemonheim."); + case 7: + return newstruct cs2func_script_984_struct(60, 16417, "Members: Argonite maul (Tier 7)", "Members can now wield " + "" + "argonite mauls" + "" + " within Daemonheim."); + case 8: + return newstruct cs2func_script_984_struct(70, 16419, "Members: Katagon maul (Tier 8)", "Members can now wield " + "" + "katagon mauls" + "" + " within Daemonheim."); + case 9: + return newstruct cs2func_script_984_struct(80, 16421, "Members: Gorgonite maul (Tier 9)", "Members can now wield " + "" + "gorgonite mauls" + "" + " within Daemonheim."); + case 10: + return newstruct cs2func_script_984_struct(90, 16423, "Members: Promethium maul (Tier 10)", "Members can now wield " + "" + "promethium mauls" + "" + " within Daemonheim."); + case 11: + return newstruct cs2func_script_984_struct(99, 16425, "Members: Primal maul (Tier 11)", "Members can now wield " + "" + "primal mauls" + "" + " within Daemonheim."); + } + break; + case 6: + if (((boolean)arg1)) { + return newstruct cs2func_script_984_struct(-1, 8855, "You can enter the Warriors' Guild when your Attack and Strength levels add up to 130 or more, or when you reach level 99 in either Attack or Strength.", ""); + } + if (((boolean)arg1)) { + return newstruct cs2func_script_984_struct(99, 9750, "Skill mastery", "" + "Congratulations! You are now a master of " + "" + "Strength" + "" + ". Members can visit " + "" + "the guard of the Strength training area" + "" + " at the " + "" + "Warriors' Guild" + "" + ". He has something special that is only available to true masters of the " + "" + "Strength" + "" + " skill!"); + } + break; + case 7: + SWITCH (arg1) { + case 0: + GOTO flow_80 + case 1: + GOTO flow_81 + case 2: + GOTO flow_82 + case 3: + GOTO flow_83 + case 4: + GOTO flow_84 + case 5: + GOTO flow_85 + case 6: + GOTO flow_86 + case 7: + GOTO flow_87 + case 8: + GOTO flow_88 + case 9: + GOTO flow_89 + } + break; + flow_80: + return newstruct cs2func_script_984_struct(85, 21537, "Members: Battle-mage helm" + "
" + " (with 85 Defence and 85 Magic)", "Members now have the Strength requirement to wear " + "" + "Battle-mage helms" + "" + ". (They also need level 85 Defence and level 85 Magic.)"); + flow_81: + return newstruct cs2func_script_984_struct(85, 21539, "Members: Battle-mage robe" + "
" + " (with 85 Defence and 85 Magic)", "Members now have the Strength requirement to wear " + "" + "Battle-mage robes" + "" + ". (They also need level 85 Defence and level 85 Magic.)"); + flow_82: + return newstruct cs2func_script_984_struct(85, 21541, "Members: Battle-mage legs" + "
" + " (with 85 Defence and 85 Magic)", "Members now have the Strength requirement to wear " + "" + "Battle-mage legs" + "" + ". (They also need level 85 Defence and level 85 Magic.)"); + flow_83: + return newstruct cs2func_script_984_struct(85, 21543, "Members: Battle-mage gloves" + "
" + " (with 85 Defence and 85 Magic)", "Members now have the Strength requirement to wear " + "" + "Battle-mage gloves" + "" + ". (They also need level 85 Defence and level 85 Magic.)"); + flow_84: + return newstruct cs2func_script_984_struct(85, 21545, "Members: Battle-mage boots" + "
" + " (with 85 Defence and 85 Magic)", "Members now have the Strength requirement to wear " + "" + "Battle-mage boots" + "" + ". (They also need level 85 Defence and level 85 Magic.)"); + flow_85: + return newstruct cs2func_script_984_struct(85, 21557, "Members: Vanguard helm" + "
" + " (with 85 Defence and 85 Ranged)", "Members now have the Strength requirement to wear " + "" + "Vanguard helms" + "" + ". (They also need level 85 Defence and level 85 Ranged.)"); + flow_86: + return newstruct cs2func_script_984_struct(85, 21559, "Members: Vanguard body" + "
" + " (with 85 Defence and 85 Ranged)", "Members now have the Strength requirement to wear " + "" + "Vanguard body armour" + "" + ". (They also need level 85 Defence and level 85 Ranged.)"); + flow_87: + return newstruct cs2func_script_984_struct(85, 21561, "Members: Vanguard legs" + "
" + " (with 85 Defence and 85 Ranged)", "Members now have the Strength requirement to wear " + "" + "Vanguard leg armour" + "" + ". (They also need level 85 Defence and level 85 Ranged.)"); + flow_88: + return newstruct cs2func_script_984_struct(85, 21563, "Members: Vanguard gloves" + "
" + " (with 85 Defence and 85 Ranged)", "Members now have the Strength requirement to wear " + "" + "Vanguard gloves" + "" + ". (They also need level 85 Defence and level 85 Ranged.)"); + flow_89: + return newstruct cs2func_script_984_struct(85, 21565, "Members: Vanguard boots" + "
" + " (with 85 Defence and 85 Ranged)", "Members now have the Strength requirement to wear " + "" + "Vanguard boots" + "" + ". (They also need level 85 Defence and level 85 Ranged.)"); + } + return newstruct cs2func_script_984_struct(0, -1, "", ""); +} diff --git a/dumps/scripts/985.cs2 b/dumps/scripts/985.cs2 new file mode 100644 index 0000000..df91c42 --- /dev/null +++ b/dumps/scripts/985.cs2 @@ -0,0 +1,23 @@ +cs2func_script_985_struct(1,1,0) script_985(int arg0) { + switch (arg0) { + case 0: + return newstruct cs2func_script_985_struct(0, "Firemaking"); + case 1: + return newstruct cs2func_script_985_struct(1, "Barbarian fires"); + case 2: + return newstruct cs2func_script_985_struct(1, "Pyre ships"); + case 3: + return newstruct cs2func_script_985_struct(0, "Equipment"); + case 4: + return newstruct cs2func_script_985_struct(1, "Beacons"); + case 5: + return newstruct cs2func_script_985_struct(0, "Other"); + case 6: + return newstruct cs2func_script_985_struct(1, "Minigames"); + case 7: + return newstruct cs2func_script_985_struct(0, "Dungeoneering"); + case 8: + return newstruct cs2func_script_985_struct(0, "Milestones"); + } + return newstruct cs2func_script_985_struct(-1, ""); +} diff --git a/dumps/scripts/986.cs2 b/dumps/scripts/986.cs2 new file mode 100644 index 0000000..fe44fee --- /dev/null +++ b/dumps/scripts/986.cs2 @@ -0,0 +1,245 @@ +cs2func_script_986_struct(2,2,0) script_986(int arg0,int arg1) { + switch (arg0) { + case 0: + switch (arg1) { + case 0: + return newstruct cs2func_script_986_struct(1, 1511, "Normal logs", "You can now light " + "" + "normal logs" + "" + "."); + case 1: + return newstruct cs2func_script_986_struct(1, 596, "Members: Torch", "Members can now light " + "" + "torches" + "" + "."); + case 2: + return newstruct cs2func_script_986_struct(1, 36, "Members: Candle", "Members can now light " + "" + "candles" + "" + "."); + case 3: + return newstruct cs2func_script_986_struct(1, 2862, "Members: Achey logs", "Members can now light " + "" + "achey logs" + "" + "."); + case 4: + return newstruct cs2func_script_986_struct(4, 4531, "Members: Candle lantern", "Members can now light " + "" + "candle lanterns" + "" + "."); + case 5: + return newstruct cs2func_script_986_struct(5, 3438, "Members: Pyre logs", "Members can now light " + "" + "pyre logs" + "" + "."); + case 6: + return newstruct cs2func_script_986_struct(12, 4524, "Members: Oil lamp", "Members can now light " + "" + "oil lamps" + "" + "."); + case 7: + return newstruct cs2func_script_986_struct(15, 1521, "Oak logs", "You can now light " + "" + "oak logs" + "" + "."); + case 8: + return newstruct cs2func_script_986_struct(20, 7225, "Members: Iron spit", "Members can now cook with " + "" + "iron spits" + "" + "."); + case 9: + return newstruct cs2func_script_986_struct(20, 3440, "Members: Oak pyre logs", "Members can now light " + "" + "oak pyre logs" + "" + "."); + case 10: + return newstruct cs2func_script_986_struct(26, 4539, "Members: Oil lantern", "Members can now light " + "" + "oil lanterns" + "" + "."); + case 11: + return newstruct cs2func_script_986_struct(30, 1519, "Willow logs", "You can now light " + "" + "willow logs" + "" + "."); + case 12: + return newstruct cs2func_script_986_struct(33, 7053, "Members: Harpie bug lantern (not a light source)", "Members can now light " + "" + "harpie bug lanterns" + "" + ". These are not a light source."); + case 13: + return newstruct cs2func_script_986_struct(35, 6333, "Members: Teak logs", "Members can now light " + "" + "teak logs" + "" + "."); + case 14: + return newstruct cs2func_script_986_struct(35, 3442, "Members: Willow pyre logs", "Members can now light " + "" + "willow pyre logs" + "" + "."); + case 15: + return newstruct cs2func_script_986_struct(40, 6211, "Members: Teak pyre logs", "Members can now light " + "" + "teak pyre logs" + "" + "."); + case 16: + return newstruct cs2func_script_986_struct(42, 10810, "Members: Arctic pine logs", "Members can now light " + "" + "arctic pine logs" + "" + "."); + case 17: + return newstruct cs2func_script_986_struct(45, 1517, "Maple logs", "You can now light " + "" + "maple logs" + "" + "."); + case 18: + return newstruct cs2func_script_986_struct(47, 10808, "Members: Arctic pine pyre logs", "Members can now light " + "" + "arctic pine pyre logs" + "" + "."); + case 19: + return newstruct cs2func_script_986_struct(49, 4550, "Members: Bullseye lantern", "Members can now light " + "" + "bullseye lanterns" + "" + "."); + case 20: + return newstruct cs2func_script_986_struct(49, 4702, "Members: Sapphire lantern", "Members can now light " + "" + "sapphire lanterns" + "" + "."); + case 21: + return newstruct cs2func_script_986_struct(49, 9065, "Members: Emerald lantern", "Members can now light " + "" + "emerald lanterns" + "" + "."); + case 22: + return newstruct cs2func_script_986_struct(50, 6332, "Members: Mahogany logs", "Members can now light " + "" + "mahogany logs" + "" + "."); + case 23: + return newstruct cs2func_script_986_struct(50, 3444, "Members: Maple pyre logs", "Members can now light " + "" + "maple pyre logs" + "" + "."); + case 24: + return newstruct cs2func_script_986_struct(52, 10973, "Members: Replace Dorgeshuun light orb", "Members can now replace " + "" + "Dorgeshuun light orbs" + "" + "."); + case 25: + return newstruct cs2func_script_986_struct(55, 6213, "Members: Mahogany pyre logs", "Members can now light " + "" + "mahogany pyre logs" + "" + "."); + case 26: + return newstruct cs2func_script_986_struct(58, 12581, "Members: Eucalyptus logs", "Members can now light " + "" + "eucalyptus logs" + "" + "."); + case 27: + return newstruct cs2func_script_986_struct(60, 1515, "Yew logs", "You can now light " + "" + "yew logs" + "" + "."); + case 28: + return newstruct cs2func_script_986_struct(63, 12583, "Members: Eucalyptus pyre logs", "Members can now light " + "" + "eucalyptus pyre logs" + "" + "."); + case 29: + return newstruct cs2func_script_986_struct(65, 5013, "Members: Cave goblin mining helmet", "Members can now light " + "" + "cave goblin mining helmets" + "" + "."); + case 30: + return newstruct cs2func_script_986_struct(65, 3446, "Members: Yew pyre logs", "Members can now light " + "" + "yew pyre logs" + "" + "."); + case 31: + return newstruct cs2func_script_986_struct(75, 1513, "Members: Magic logs", "Members can now light " + "" + "magic logs" + "" + "."); + case 32: + return newstruct cs2func_script_986_struct(76, 21600, "Members: Blisterwood logs", "Members can now light " + "" + "blisterwood logs" + "" + "."); + case 33: + return newstruct cs2func_script_986_struct(80, 3448, "Members: Magic pyre logs", "Members can now light " + "" + "magic pyre logs" + "" + "."); + case 34: + return newstruct cs2func_script_986_struct(83, 21350, "Members: Curly root", "Members can now light " + "" + "curly roots" + "" + " in the jadinko lair."); + } + break; + case 1: + switch (arg1) { + case 0: + return newstruct cs2func_script_986_struct(-1, 7620, "To start Firemaking in the manner of the barbarians, talk to Otto Godblessed when you have level 35 Firemaking or higher.", ""); + case 1: + return newstruct cs2func_script_986_struct(21, 1511, "Members: Normal Logs", "Members versed in the art of barbarian firemaking can now light " + "" + "normal logs" + "" + " without a tinderbox."); + case 2: + return newstruct cs2func_script_986_struct(21, 2862, "Members: Achey tree", "Members versed in the art of barbarian firemaking can now light " + "" + "achey tree logs" + "" + " without a tinderbox."); + case 3: + return newstruct cs2func_script_986_struct(35, 1521, "Members: Oak", "Members versed in the art of barbarian firemaking can now light " + "" + "oak logs" + "" + " without a tinderbox."); + case 4: + return newstruct cs2func_script_986_struct(50, 1519, "Members: Willow", "Members versed in the art of barbarian firemaking can now light " + "" + "willow logs" + "" + " without a tinderbox."); + case 5: + return newstruct cs2func_script_986_struct(55, 6333, "Members: Teak", "Members versed in the art of barbarian firemaking can now light " + "" + "teak logs" + "" + " without a tinderbox."); + case 6: + return newstruct cs2func_script_986_struct(62, 10810, "Members: Arctic pine", "Members versed in the art of barbarian firemaking can now light " + "" + "arctic pine logs" + "" + " without a tinderbox."); + case 7: + return newstruct cs2func_script_986_struct(65, 1517, "Members: Maple", "Members versed in the art of barbarian firemaking can now light " + "" + "maple logs" + "" + " without a tinderbox."); + case 8: + return newstruct cs2func_script_986_struct(70, 6332, "Members: Mahogany", "Members versed in the art of barbarian firemaking can now light " + "" + "mahogany logs" + "" + " without a tinderbox."); + case 9: + return newstruct cs2func_script_986_struct(78, 12581, "Members: Eucalyptus", "Members versed in the art of barbarian firemaking can now light " + "" + "eucalyptus logs" + "" + " without a tinderbox."); + case 10: + return newstruct cs2func_script_986_struct(80, 1515, "Members: Yew", "Members versed in the art of barbarian firemaking can now light " + "" + "yew logs" + "" + " without a tinderbox."); + case 11: + return newstruct cs2func_script_986_struct(95, 1513, "Members: Magic", "Members versed in the art of barbarian firemaking can now light " + "" + "magic logs" + "" + " without a tinderbox."); + } + break; + case 2: + switch (arg1) { + case 0: + return newstruct cs2func_script_986_struct(-1, 7620, "To start Firemaking in the manner of the barbarians, talk to Otto Godblessed when you have level 35 Firemaking or higher. Pyre ships can only be constructed and burnt where the ground is charred, around the lake next to Otto's hut.", ""); + case 1: + return newstruct cs2func_script_986_struct(11, 1511, "Members: Wood" + "
" + " (with 11 Crafting)", "Members versed in the art of barbarian firemaking now have the Firemaking level required to light pyre ships made out of " + "" + "logs" + "" + ". (They also need level 11 Crafting.)"); + case 2: + return newstruct cs2func_script_986_struct(11, 2862, "Members: Achey" + "
" + " (with 11 Crafting)", "Members versed in the art of barbarian firemaking now have the Firemaking level required to light pyre ships made out of " + "" + "achey tree logs" + "" + ". (They also need level 11 Crafting.)"); + case 3: + return newstruct cs2func_script_986_struct(25, 1521, "Members: Oak" + "
" + " (with 25 Crafting)", "Members versed in the art of barbarian firemaking now have the Firemaking level required to light pyre ships made out of " + "" + "oak logs" + "" + ". (They also need level 25 Crafting.)"); + case 4: + return newstruct cs2func_script_986_struct(40, 1519, "Members: Willow" + "
" + " (with 40 Crafting)", "Members versed in the art of barbarian firemaking now have the Firemaking level required to light pyre ships made out of " + "" + "willow logs" + "" + ". (They also need level 40 Crafting.)"); + case 5: + return newstruct cs2func_script_986_struct(45, 6333, "Members: Teak" + "
" + " (with 45 Crafting)", "Members versed in the art of barbarian firemaking now have the Firemaking level required to light pyre ships made out of " + "" + "teak logs" + "" + ". (They also need level 45 Crafting.)"); + case 6: + return newstruct cs2func_script_986_struct(52, 10810, "Members: Arctic pine" + "
" + " (with 52 Crafting)", "Members versed in the art of barbarian firemaking now have the Firemaking level required to light pyre ships made out of " + "" + "arctic pine logs" + "" + ". (They also need level 52 Crafting.)"); + case 7: + return newstruct cs2func_script_986_struct(55, 1517, "Members: Maple" + "
" + " (with 55 Crafting)", "Members versed in the art of barbarian firemaking now have the Firemaking level required to light pyre ships made out of " + "" + "maple logs" + "" + ". (They also need level 55 Crafting.)"); + case 8: + return newstruct cs2func_script_986_struct(60, 6332, "Members: Mahogany" + "
" + " (with 60 Crafting)", "Members versed in the art of barbarian firemaking now have the Firemaking level required to light pyre ships made out of " + "" + "mahogany logs" + "" + ". (They also need level 60 Crafting.)"); + case 9: + return newstruct cs2func_script_986_struct(68, 12581, "Members: Eucalyptus" + "
" + " (with 68 Crafting)", "Members versed in the art of barbarian firemaking now have the Firemaking level required to light pyre ships made out of " + "" + "eucalyptus logs" + "" + ". (They also need level 68 Crafting.)"); + case 10: + return newstruct cs2func_script_986_struct(70, 1515, "Members: Yew" + "
" + " (with 70 Crafting)", "Members versed in the art of barbarian firemaking now have the Firemaking level required to light pyre ships made out of " + "" + "yew logs" + "" + ". (They also need level 70 Crafting.)"); + case 11: + return newstruct cs2func_script_986_struct(85, 1513, "Members: Magic" + "
" + " (with 85 Crafting)", "Members versed in the art of barbarian firemaking now have the Firemaking level required to light pyre ships made out of " + "" + "magic logs" + "" + ". (They also need level 85 Crafting.)"); + } + break; + case 3: + switch (arg1) { + case 0: + return newstruct cs2func_script_986_struct(1, 590, "Tinderbox", "You can now light fires with a " + "" + "tinderbox" + "" + "."); + case 1: + return newstruct cs2func_script_986_struct(61, 15241, "Members: Chaos dwarf hand cannon" + "
" + " (after Forgiveness of a Chaos Dwarf and with 75 Ranged)", "Members now have the Firemaking level required to fire the " + "" + "chaos dwarf hand cannon" + "" + " (after Forgiveness of a Chaos Dwarf and with 75 Ranged)."); + case 2: + return newstruct cs2func_script_986_struct(62, 13659, "Members: Ring of Fire" + "
" + " (after All Fired Up)", "Members can now wear the " + "" + "Ring of Fire" + "" + " (after All Fired Up)."); + case 3: + return newstruct cs2func_script_986_struct(79, 13660, "Members: Flame Gloves" + "
" + " (after All Fired Up)", "Members can now wear the " + "" + "Flame Gloves" + "" + " (after All Fired Up)."); + case 4: + return newstruct cs2func_script_986_struct(92, 13661, "Members: Inferno Adze" + "
" + " (after All Fired Up)", "Members can now use the " + "" + "Inferno Adze" + "" + " (after All Fired Up)."); + } + break; + case 4: + switch (arg1) { + case 0: + return newstruct cs2func_script_986_struct(-1, 7620, "To use the beacons, you must have completed All Fired Up.", ""); + case 1: + return newstruct cs2func_script_986_struct(43, 13662, "Members: Beacon near the River Salve", "Members can now light the " + "" + "beacon" + "" + " near the " + "" + "River Salve" + "" + " (after All Fired Up)."); + case 2: + return newstruct cs2func_script_986_struct(43, 13662, "Members: Beacon near the Rag and Bone Man", "Members can now light the " + "" + "beacon" + "" + " near the " + "" + "Rag and Bone Man" + "" + " (after All Fired Up)."); + case 3: + return newstruct cs2func_script_986_struct(48, 13662, "Members: Beacon near the Jolly Boar", "Members can now light the " + "" + "beacon" + "" + " near the " + "" + "Jolly Boar" + "" + " (after All Fired Up)."); + case 4: + return newstruct cs2func_script_986_struct(53, 13662, "Members: Beacon north of Varrock Palace", "Members can now light the " + "" + "beacon" + "" + " north of " + "" + "Varrock Palace" + "" + " (after All Fired Up)."); + case 5: + return newstruct cs2func_script_986_struct(59, 13662, "Members: Beacon near the Grand Exchange", "Members can now light the " + "" + "beacon" + "" + " near the " + "" + "Grand Exchange" + "" + " (after All Fired Up)."); + case 6: + return newstruct cs2func_script_986_struct(62, 13662, "Members: Beacon near Edgeville", "Members can now light the " + "" + "beacon" + "" + " near " + "" + "Edgeville" + "" + " (after All Fired Up)."); + case 7: + return newstruct cs2func_script_986_struct(68, 13662, "Members: Beacon near the Monastery" + "
" + " (after joining the Monastery)", "Members can now light the " + "" + "beacon" + "" + " near " + "" + "the Monastery" + "" + " (after All Fired Up and after joining the Monastery)."); + case 8: + return newstruct cs2func_script_986_struct(72, 13662, "Members: Beacon near Goblin Village" + "
" + " (after Land of the Goblins)", "Members can now light the " + "" + "beacon" + "" + " near " + "" + "Goblin Village" + "" + " (after All Fired Up and Land of the Goblins)."); + case 9: + return newstruct cs2func_script_986_struct(76, 13662, "Members: Beacon near Burthorpe" + "
" + " (with 56 Smithing)", "Members now have the Firemaking level required to light the " + "" + "beacon" + "" + " near " + "" + "Burthorpe" + "" + ". (They also need level 56 Smithing and to have completed All Fired Up)."); + case 10: + return newstruct cs2func_script_986_struct(79, 13662, "Members: Beacon east of Death Plateau" + "
" + " (with 42 Construction)", "Members now have the Firemaking level required to light the " + "" + "beacon" + "" + " east of " + "" + "Death Plateau" + "" + ". (They also need level 42 Construction and to have completed All Fired Up)."); + case 11: + return newstruct cs2func_script_986_struct(83, 13662, "Members: Beacon near the Trollheim shortcut" + "
" + " (with 64 Agility)", "Members now have the Firemaking level required to light the " + "" + "beacon" + "" + " near the " + "" + "Trollheim shortcut" + "" + ". (They also need level 64 Agility and to have completed All Fired Up)."); + case 12: + return newstruct cs2func_script_986_struct(87, 13662, "Members: Beacon near the entrance to the God Wars Dungeon" + "
" + " (with 60 Crafting)", "Members now have the Firemaking level required to light the " + "" + "beacon" + "" + " near the entrance to the " + "" + "God Wars Dungeon" + "" + ". (They also need level 60 Crafting and to have completed All Fired Up)."); + case 13: + return newstruct cs2func_script_986_struct(89, 13662, "Members: Beacon near small temple in the Wilderness" + "
" + " (with 70 Smithing or 59 Construction)", "Members now have the Firemaking level required to light the " + "" + "beacon" + "" + " near the " + "" + "small temple in the Wilderness" + "" + ". (They will also need level 70 Smithing or level 59 Construction, and to have completed All Fired Up)."); + case 14: + return newstruct cs2func_script_986_struct(92, 13662, "Members: Beacon on the Frozen Waste Plateau", "Members can now light the " + "" + "beacon" + "" + " on the " + "" + "Frozen Waste Plateau" + "" + " (after All Fired Up)."); + } + break; + case 5: + switch (arg1) { + case 0: + return newstruct cs2func_script_986_struct(91, 18778, "Members: Starved ancient effigies", "Members can now investigate " + "" + "starved ancient effigies" + "" + " using their knowledge of Firemaking."); + case 1: + return newstruct cs2func_script_986_struct(93, 18779, "Members: Nourished ancient effigies", "Members can now investigate " + "" + "nourished ancient effigies" + "" + " using their knowledge of Firemaking."); + case 2: + return newstruct cs2func_script_986_struct(95, 18780, "Members: Sated ancient effigies", "Members can now investigate " + "" + "sated ancient effigies" + "" + " using their knowledge of Firemaking."); + case 3: + return newstruct cs2func_script_986_struct(97, 18781, "Members: Gorged ancient effigies", "Members can now investigate " + "" + "gorged ancient effigies" + "" + " using their knowledge of Firemaking."); + } + break; + case 6: + switch (arg1) { + case 0: + return newstruct cs2func_script_986_struct(1, 14667, "Members: Burn basic evil tree", "Members can now burn " + "" + "basic evil trees" + ""); + case 1: + return newstruct cs2func_script_986_struct(15, 14667, "Members: Burn evil oak tree", "Members can now burn " + "" + "evil oak trees" + ""); + case 2: + return newstruct cs2func_script_986_struct(30, 14667, "Members: Burn evil willow tree", "Members can now burn " + "" + "evil willow trees" + ""); + case 3: + return newstruct cs2func_script_986_struct(45, 14667, "Members: Burn evil maple tree", "Members can now burn " + "" + "evil maple trees" + ""); + case 4: + return newstruct cs2func_script_986_struct(55, 14619, "Members: Phoenix Lair - funeral pyre", "Members can now light the phoenix's " + "" + "funeral pyre" + "" + " in the phoenix lair."); + case 5: + return newstruct cs2func_script_986_struct(60, 14667, "Members: Burn evil yew tree", "Members can now burn " + "" + "evil yew trees" + ""); + case 6: + return newstruct cs2func_script_986_struct(75, 14667, "Members: Burn evil magic tree", "Members can now burn " + "" + "evil magic trees" + ""); + case 7: + return newstruct cs2func_script_986_struct(85, 14667, "Members: Burn elder evil tree", "Members can now burn " + "" + "elder evil trees" + ""); + } + break; + case 7: + switch (arg1) { + case 0: + return newstruct cs2func_script_986_struct(-1, 15707, "Dungeoneering skill tasks" + "
" + "As your Firemaking level increases, you will be able to attempt higher-level firemaking tasks within Daemonheim. You will also be more likely to succeed when attempting firemaking tasks within Daemonheim.", ""); + case 1: + return newstruct cs2func_script_986_struct(1, 17682, "Tangle gum branches (Tier 1)", "You can now light " + "" + "tangle gum branches" + "" + " within Daemonheim."); + case 2: + return newstruct cs2func_script_986_struct(10, 17684, "Seeping elm branches (Tier 2)", "You can now light " + "" + "seeping elm branches" + "" + " within Daemonheim."); + case 3: + return newstruct cs2func_script_986_struct(20, 17686, "Blood spindle branches (Tier 3)", "You can now light " + "" + "blood spindle branches" + "" + " within Daemonheim."); + case 4: + return newstruct cs2func_script_986_struct(30, 17688, "Utuku branches (Tier 4)", "You can now light " + "" + "utuku branches" + "" + " within Daemonheim."); + case 5: + return newstruct cs2func_script_986_struct(40, 17690, "Spinebeam branches (Tier 5)", "You can now light " + "" + "spinebeam branches" + "" + " within Daemonheim."); + case 6: + return newstruct cs2func_script_986_struct(50, 17692, "Members: Bovistrangler branches (Tier 6)", "Members can now light " + "" + "bovistrangler branches" + "" + " within Daemonheim."); + case 7: + return newstruct cs2func_script_986_struct(60, 17694, "Members: Thigat branches (Tier 7)", "Members can now light " + "" + "thigat branches" + "" + " within Daemonheim."); + case 8: + return newstruct cs2func_script_986_struct(70, 17696, "Members: Corpsethorn branches (Tier 8)", "Members can now light " + "" + "corpsethorn branches" + "" + " within Daemonheim."); + case 9: + return newstruct cs2func_script_986_struct(80, 17698, "Members: Entgallow branches (Tier 9)", "Members can now light " + "" + "entgallow branches" + "" + " within Daemonheim."); + case 10: + return newstruct cs2func_script_986_struct(90, 17700, "Members: Grave creeper branches (Tier 10)", "Members can now light " + "" + "grave creeper branches" + "" + " within Daemonheim."); + } + break; + case 8: + if (((boolean)arg1)) { + return newstruct cs2func_script_986_struct(99, 9804, "Skill mastery", "" + "Congratulations! You are now a master of " + "" + "Firemaking" + "" + ". Members can visit " + "" + "Ignatius" + "" + ", south of " + "" + "Seers' Village" + "" + ". He has something special that is only available to true masters of the " + "" + "Firemaking" + "" + " skill!"); + } + } + return newstruct cs2func_script_986_struct(0, -1, "", ""); +} diff --git a/dumps/scripts/987.cs2 b/dumps/scripts/987.cs2 new file mode 100644 index 0000000..35c3488 --- /dev/null +++ b/dumps/scripts/987.cs2 @@ -0,0 +1,15 @@ +cs2func_script_987_struct(1,1,0) script_987(int arg0) { + switch (arg0) { + case 0: + return newstruct cs2func_script_987_struct(1, "Equipment"); + case 1: + return newstruct cs2func_script_987_struct(1, "Monsters"); + case 2: + return newstruct cs2func_script_987_struct(1, "Slayer Masters"); + case 3: + return newstruct cs2func_script_987_struct(1, "Dungeoneering"); + case 4: + return newstruct cs2func_script_987_struct(1, "Milestones"); + } + return newstruct cs2func_script_987_struct(-1, ""); +} diff --git a/dumps/scripts/988.cs2 b/dumps/scripts/988.cs2 new file mode 100644 index 0000000..82f5e3e --- /dev/null +++ b/dumps/scripts/988.cs2 @@ -0,0 +1,201 @@ +cs2func_script_988_struct(2,2,0) script_988(int arg0,int arg1) { + switch (arg0) { + case 0: + switch (arg1) { + case 0: + return newstruct cs2func_script_988_struct(1, 4155, "Enchanted gem", "You can now use an " + "" + "enchanted gem" + "" + " to communicate with your Slayer Master."); + case 1: + return newstruct cs2func_script_988_struct(1, 4161, "Bag of salt", "You can now use " + "" + "bags of salt" + "" + " to finish off rock slugs."); + case 2: + return newstruct cs2func_script_988_struct(1, 6696, "Ice cooler", "You can now use " + "" + "ice coolers" + "" + "to finish off desert lizards."); + case 3: + return newstruct cs2func_script_988_struct(1, 4551, "Spiny helmet" + "
" + " (with 5 Defence)", "You now have the Slayer level required to wear a " + "" + "spiny helmet" + "" + " to fend off wall beast attacks. (You also need level 5 Defence."); + case 4: + return newstruct cs2func_script_988_struct(1, 4162, "Rock hammer", "You can now use " + "" + "rock hammers" + "" + " to kill weakened gargoyles."); + case 5: + return newstruct cs2func_script_988_struct(1, 15490, "Members: Focus sight" + "
" + " (with 20 Ranged and 10 Defence)", "Members can now wear " + "" + "focus sights" + "" + "."); + case 6: + return newstruct cs2func_script_988_struct(1, 15488, "Members: Hexcrest" + "
" + " (with 20 Magic and 10 Defence)", "Members can now wear " + "" + "hexcrests" + "" + "."); + case 7: + return newstruct cs2func_script_988_struct(1, 8921, "Members: Black mask" + "
" + " (with 20 Strength and 10 Defence)", "Members can now wear " + "" + "black masks" + "" + "."); + case 8: + return newstruct cs2func_script_988_struct(1, 13263, "Members: Slayer helmet" + "
" + " (after Smoking Kills)", "Members can now wear " + "" + "slayer helmets" + "" + " (after Smoking Kills)."); + case 9: + return newstruct cs2func_script_988_struct(1, 15492, "Members: Full Slayer helmet" + "
" + " (after Smoking Kills with 20 Ranged, Magic, Strength and 10 Defence)", "Members can now wear " + "" + "full slayer helmets" + "" + " (after Smoking Kills with 20 Ranged, Magic, Strength and 10 Defence)."); + case 10: + return newstruct cs2func_script_988_struct(10, 4164, "Face mask", "You can now wear the " + "" + "face mask" + "" + " needed to kill dust devils."); + case 11: + return newstruct cs2func_script_988_struct(15, 4166, "Earmuffs", "You can now wear " + "" + "earmuffs" + "" + " to protect yourself against banshees."); + case 12: + return newstruct cs2func_script_988_struct(25, 4156, "Mirror shield" + "
" + " (with 20 Defence)", "You now have the Slayer level required to wield " + "" + "mirror shields" + "" + " to protect yourself from cockatrices and basilisks. (You also need level 20 Defence.)"); + case 13: + return newstruct cs2func_script_988_struct(32, 6660, "Fishing explosive", "You can now use " + "" + "fishing explosives" + "" + " to lure mogres."); + case 14: + return newstruct cs2func_script_988_struct(33, 7053, "Harpie bug lantern" + "
" + " (not a light source)", "You can now use " + "" + "harpie bug lanterns" + "" + " to fend off harpie bug swarms so that you can attack."); + case 15: + return newstruct cs2func_script_988_struct(35, 8923, "Witchwood icon", "You can now wear " + "" + "witchwood icons" + "" + " to protect yourself from cave horrors."); + case 16: + return newstruct cs2func_script_988_struct(37, 7159, "Insulated boots", "You can now wear " + "" + "insulated boots" + "" + " to protect yourself from killerwatt shocks."); + case 17: + return newstruct cs2func_script_988_struct(39, 10952, "Slayer bell", "You can now use " + "" + "slayer bells" + "" + ", which allow molanisks to be attacked."); + case 18: + return newstruct cs2func_script_988_struct(42, 6720, "Slayer gloves", "You can now wear " + "" + "slayer gloves" + "" + " to protect yourself from fever spiders."); + case 19: + return newstruct cs2func_script_988_struct(55, 4158, "Leaf-bladed spear" + "
" + " (with 50 Attack)", "You now have the Slayer level required to wield " + "" + "leaf-bladed spears" + "" + ", melee weapons used for killing turoth and kurask. (You also need level 50 Attack.)"); + case 20: + return newstruct cs2func_script_988_struct(55, 4150, "Broad arrows" + "
" + " (with 50 Ranged)", "You now have the Slayer level required to fire " + "" + "broad arrows" + "" + ", ranged weapons used for killing turoth and kurask. (You also need level 50 Ranged.)"); + case 21: + return newstruct cs2func_script_988_struct(55, 13280, "Broad-tipped bolts" + "
" + " (with 50 Ranged)", "You now have the Slayer level required to fire " + "" + "broad bolts" + "" + ", ranged weapons used for killing turoth and kurask. (You also need level 50 Ranged.)"); + case 22: + return newstruct cs2func_script_988_struct(55, 4170, "Slayer's staff" + "
" + " (with 50 Magic)", "You now have the Slayer level required to wield " + "" + "slayer's staves" + "" + ", magic weapons used for killing turoth and kurask. (You also need level 50 Magic.)"); + case 23: + return newstruct cs2func_script_988_struct(55, 13290, "Leaf-bladed swords" + "
" + " (with 50 Attack)", "You now have the Slayer level required to wield " + "" + "leaf-bladed swords" + "" + ", melee weapons used for killing turoth and kurask (with level 50 Attack)."); + case 24: + return newstruct cs2func_script_988_struct(56, 11749, "Crystal chime", "You can now use a " + "" + "crystal chime" + "" + " to kill warped terrorbirds and warped tortoises."); + case 25: + return newstruct cs2func_script_988_struct(57, 7432, "Fungicide spray", "You can now use " + "" + "fungicide spray" + "" + " to finish off mutated zygomites."); + case 26: + return newstruct cs2func_script_988_struct(60, 4168, "Nose peg", "You can now wear a " + "" + "nosepeg" + "" + " to protect yourself from aberrant spectres."); + case 27: + return newstruct cs2func_script_988_struct(70, 12862, "Dragon slayer gloves", "You can now wear " + "" + "dragon slayer gloves" + "" + "."); + case 28: + return newstruct cs2func_script_988_struct(80, 21371, "Abyssal vine whip" + "
" + " (with 85 Attack)", "You now have the Slayer level required to wield " + "" + "abyssal vine whips" + "" + ". (You also need level 85 Attack.)"); + } + break; + case 1: + switch (arg1) { + case 0: + return newstruct cs2func_script_988_struct(5, 4133, "Crawling hand", "You can now slay " + "" + "crawling hands" + "" + "."); + case 1: + return newstruct cs2func_script_988_struct(7, 4521, "Cave bug", "You can now slay " + "" + "cave bugs" + "" + "."); + case 2: + return newstruct cs2func_script_988_struct(10, 4134, "Cave crawler", "You can now slay " + "" + "cave crawlers" + "" + "."); + case 3: + return newstruct cs2func_script_988_struct(15, 4135, "Banshee", "You can now slay " + "" + "banshees" + "" + "."); + case 4: + return newstruct cs2func_script_988_struct(17, 4520, "Cave slime", "You can now slay " + "" + "cave slimes" + "" + "."); + case 5: + return newstruct cs2func_script_988_struct(20, 4136, "Rockslug", "You can now slay " + "" + "rockslugs" + "" + "."); + case 6: + return newstruct cs2func_script_988_struct(22, 6695, "Desert lizard", "You can now slay " + "" + "desert lizards" + "" + "."); + case 7: + return newstruct cs2func_script_988_struct(25, 4137, "Cockatrice", "You can now slay " + "" + "cockatrices" + "" + "."); + case 8: + return newstruct cs2func_script_988_struct(30, 4138, "Pyrefiend", "You can now slay " + "" + "pyrefiends" + "" + "."); + case 9: + return newstruct cs2func_script_988_struct(32, 6661, "Mogre", "You can now slay " + "" + "mogres" + "" + "."); + case 10: + return newstruct cs2func_script_988_struct(33, 7050, "Harpie bug swarm", "You can now slay " + "" + "harpie bug swarms" + "" + "."); + case 11: + return newstruct cs2func_script_988_struct(35, 4519, "Wall beast", "You can now slay " + "" + "wall beasts" + "" + "."); + case 12: + return newstruct cs2func_script_988_struct(37, 7160, "Killerwatt", "You can now slay " + "" + "killerwatts" + "" + "."); + case 13: + return newstruct cs2func_script_988_struct(39, 10997, "Molanisk", "You can now slay " + "" + "molanisks" + "" + "."); + case 14: + return newstruct cs2func_script_988_struct(40, 4139, "Basilisk", "You can now slay " + "" + "basilisks" + "" + "."); + case 15: + return newstruct cs2func_script_988_struct(40, 10591, "Terror dog", "You can now slay " + "" + "terror dogs" + "" + "."); + case 16: + return newstruct cs2func_script_988_struct(42, 6709, "Fever spider", "You can now slay " + "" + "fever spiders" + "" + "."); + case 17: + return newstruct cs2func_script_988_struct(45, 4140, "Infernal mage", "You can now slay " + "" + "infernal mages" + "" + "."); + case 18: + return newstruct cs2func_script_988_struct(47, 11047, "Brine rat", "You can now slay " + "" + "brine rats" + "" + "."); + case 19: + return newstruct cs2func_script_988_struct(50, 4141, "Bloodveld", "You can now slay " + "" + "bloodvelds" + "" + "."); + case 20: + return newstruct cs2func_script_988_struct(51, 14618, "Phoenix" + "
" + " (after In Pyre Need)", "You can now slay the " + "" + "phoenix" + "" + "(after In Pyre Need)."); + case 21: + return newstruct cs2func_script_988_struct(52, 4142, "Jelly", "You can now slay " + "" + "jellies" + "" + "."); + case 22: + return newstruct cs2func_script_988_struct(55, 4143, "Turoth", "You can now slay " + "" + "turoths" + "" + "."); + case 23: + return newstruct cs2func_script_988_struct(56, 11752, "Warped terrorbird", "You can now slay " + "" + "warped terrorbirds" + "" + "."); + case 24: + return newstruct cs2func_script_988_struct(56, 11751, "Warped tortoise", "You can now slay " + "" + "warped tortoises" + "" + "."); + case 25: + return newstruct cs2func_script_988_struct(57, 7420, "Mutated zygomite", "You can now slay " + "" + "mutated zygomites" + "" + "."); + case 26: + return newstruct cs2func_script_988_struct(58, 8900, "Cave horror", "You can now slay " + "" + "cave horrors" + "" + "."); + case 27: + return newstruct cs2func_script_988_struct(59, 11779, "Wild jade vine" + "
" + " (after Back to My Roots)", "You now have the Slayer level required to slay " + "" + "wild jade vines" + "" + " (after Back to My Roots)."); + case 28: + return newstruct cs2func_script_988_struct(60, 4144, "Aberrant spectre", "You can now slay " + "" + "aberrant spectres" + "" + "."); + case 29: + return newstruct cs2func_script_988_struct(61, 12501, "'Rum'-pumped crab", "You can now slay " + "" + "'rum'-pumped crabs" + "" + "."); + case 30: + return newstruct cs2func_script_988_struct(63, 11742, "Spiritual ranger", "You can now slay " + "" + "spiritual rangers" + "" + "."); + case 31: + return newstruct cs2func_script_988_struct(65, 4145, "Dust devil", "You can now slay " + "" + "dust devils" + "" + "."); + case 32: + return newstruct cs2func_script_988_struct(68, 11744, "Spiritual warrior", "You can now slay " + "" + "spiritual warriors" + "" + "."); + case 33: + return newstruct cs2func_script_988_struct(70, 4146, "Kurask", "You can now slay " + "" + "kurask" + "" + "."); + case 34: + return newstruct cs2func_script_988_struct(72, 6811, "Skeletal wyvern", "You can now slay " + "" + "skeletal wyverns" + "" + "."); + case 35: + return newstruct cs2func_script_988_struct(73, 15499, "Jungle strykewyrm", "You can now slay " + "" + "jungle strykewyrms" + "" + "."); + case 36: + return newstruct cs2func_script_988_struct(75, 4147, "Gargoyle", "You can now slay " + "" + "gargoyles" + "" + "."); + case 37: + return newstruct cs2func_script_988_struct(77, 15498, "Desert strykewyrm", "You can now slay " + "" + "desert strykewyrms" + "" + "."); + case 38: + return newstruct cs2func_script_988_struct(78, 15125, "Aquanite", "You can now slay " + "" + "aquanites" + "" + "."); + case 39: + return newstruct cs2func_script_988_struct(80, 4148, "Nechryael", "You can now slay " + "" + "nechryaels" + "" + "."); + case 40: + return newstruct cs2func_script_988_struct(80, 21366, "Mutated jadinko baby", "You can now slay " + "" + "mutated jadinko babies" + "" + "."); + case 41: + return newstruct cs2func_script_988_struct(83, 11740, "Spiritual mage", "You can now slay " + "" + "spiritual mages" + "" + "."); + case 42: + return newstruct cs2func_script_988_struct(85, 4149, "Abyssal demon", "You can now slay " + "" + "abyssal demons" + "" + "."); + case 43: + return newstruct cs2func_script_988_struct(86, 21367, "Mutated jadinko guard", "You can now slay " + "" + "mutated jadinko guards" + "" + "."); + case 44: + return newstruct cs2func_script_988_struct(90, 6637, "Dark beast", "You can now slay " + "" + "dark beasts" + "" + "."); + case 45: + return newstruct cs2func_script_988_struct(91, 21368, "Mutated jadinko male", "You can now slay " + "" + "mutated jadinko males" + "" + "."); + case 46: + return newstruct cs2func_script_988_struct(93, 15500, "Ice strykewyrm", "You can now slay " + "" + "ice strykewyrms" + "" + "."); + } + break; + case 2: + switch (arg1) { + case 0: + return newstruct cs2func_script_988_struct(1, 4155, "Burthorpe" + "
" + " (with level 3 Combat)", "You can now receive " + "" + "Slayer assignments" + "" + " from the " + "" + "Burthorpe slayer master" + "" + "."); + case 1: + return newstruct cs2func_script_988_struct(1, 4155, "Canifis" + "
" + " (with level 20 Combat)", "You now have the Slayer level required to receive " + "" + "slayer assignments" + "" + " from the " + "" + "Canifis slayer master" + "" + ". (You also need level 20 Combat.)"); + case 2: + return newstruct cs2func_script_988_struct(1, 4155, "Edgeville Dungeon" + "
" + " (with level 40 Combat)", "You now have the Slayer level required to receive " + "" + "slayer assignments" + "" + " from the " + "" + "Edgeville Dungeon slayer master" + "" + ". (You also need level 40 Combat.)"); + case 3: + return newstruct cs2func_script_988_struct(1, 4155, "Zanaris" + "
" + " (with level 70 Combat)", "You now have the Slayer level required to receive " + "" + "slayer assignments" + "" + " from the " + "" + "Zanaris slayer master" + "" + ". (You also need level 70 Combat.)"); + case 4: + return newstruct cs2func_script_988_struct(35, 4155, "Pollnivneach" + "
" + " (after Smoking Kills)", "You now have the Slayer level required to receive " + "" + "slayer assignments" + "" + " from the " + "" + "Pollnivneach slayer master" + "" + " (after Smoking Kills)."); + case 5: + return newstruct cs2func_script_988_struct(50, 4155, "Shilo Village" + "
" + " (with level 100 Combat)", "You now have the Slayer level required to receive " + "" + "slayer assignments" + "" + " from the " + "" + "Shilo Village slayer master" + "" + ". (You also need level 100 Combat.)"); + case 6: + return newstruct cs2func_script_988_struct(75, 4155, "Ancient cavern" + "
" + " (with level 110 Combat)", "You now have the Slayer level required to receive " + "" + "slayer assignments" + "" + " from the " + "" + "Ancient Cavern slayer master" + "" + ". (You also need level 110 Combat.)"); + } + break; + case 3: + switch (arg1) { + case 0: + return newstruct cs2func_script_988_struct(41, 18504, "Night spider", "You can now slay " + "" + "night spiders" + "" + " within Daemonheim."); + case 1: + return newstruct cs2func_script_988_struct(63, 18506, "Spiritual guardian", "You can now slay " + "" + "spiritual guardians" + "" + " within Daemonheim."); + case 2: + return newstruct cs2func_script_988_struct(71, 18505, "Seeker", "You can now slay " + "" + "seekers" + "" + " within Daemonheim."); + case 3: + return newstruct cs2func_script_988_struct(90, 18503, "Edimmu", "You can now slay " + "" + "edimmu" + "" + " within Daemonheim."); + case 4: + return newstruct cs2func_script_988_struct(99, 18507, "Soulgazer", "You can now slay " + "" + "soulgazers" + "" + " within Daemonheim."); + } + break; + case 4: + if (((boolean)arg1)) { + return newstruct cs2func_script_988_struct(99, 9786, "Skill mastery", "" + "Congratulations! You are now a master of " + "" + "Slayer" + "" + ". Why not visit the " + "" + "ancient cavern Slayer Master" + "" + "? She has something special that is only available to true masters of the " + "" + "Slayer" + "" + " skill!"); + } + } + return newstruct cs2func_script_988_struct(0, -1, "", ""); +} diff --git a/dumps/scripts/989.cs2 b/dumps/scripts/989.cs2 new file mode 100644 index 0000000..204ea6c --- /dev/null +++ b/dumps/scripts/989.cs2 @@ -0,0 +1,21 @@ +cs2func_script_989_struct(1,1,0) script_989(int arg0) { + switch (arg0) { + case 0: + return newstruct cs2func_script_989_struct(0, "Trees"); + case 1: + return newstruct cs2func_script_989_struct(0, "Hatchets"); + case 2: + return newstruct cs2func_script_989_struct(0, "Canoes"); + case 3: + return newstruct cs2func_script_989_struct(1, "Woodcraft"); + case 4: + return newstruct cs2func_script_989_struct(0, "Other"); + case 5: + return newstruct cs2func_script_989_struct(1, "Minigames"); + case 6: + return newstruct cs2func_script_989_struct(0, "Dungeoneering"); + case 7: + return newstruct cs2func_script_989_struct(0, "Milestones"); + } + return newstruct cs2func_script_989_struct(-1, ""); +} diff --git a/dumps/scripts/99.cs2 b/dumps/scripts/99.cs2 new file mode 100644 index 0000000..3a6b9e6 --- /dev/null +++ b/dumps/scripts/99.cs2 @@ -0,0 +1,42 @@ +void script_99() { + int ivar0; + int ivar1; + int ivar2; + ivar0 = 5; + ivar1 = 5; + ivar2 = 0; + while (ivar0 < 125) { + while (ivar1 < 120) { + createExtraChild(new WidgetPointer(631,47), 5, ivar2); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(ivar1, ivar0, 0, 0); + if (getItemIdInSlot(134, ivar2) != -1) { + setItemOnWidgetMethod1200(getItemIdInSlot(134, ivar2), getItemAmtInSlot(134, ivar2)); + cs2method1305("" + getItemName(getItemIdInSlot(134, ivar2))); + setWidgetContextMenuOption(1, "Remove 1"); + setWidgetContextMenuOption(2, "Remove 5"); + setWidgetContextMenuOption(3, "Remove 10"); + setWidgetContextMenuOption(4, "Remove All"); + setWidgetContextMenuOption(5, "Remove X"); + setWidgetContextMenuOption(10, "Examine"); + setWidgetShadowColor(new Color(48, 32, 32)); + setWidgetBorderThickness(1); + } + createExtraChild(new WidgetPointer(631,49), 5, ivar2); + setWidgetSize(36, 32, 0, 0); + setWidgetPosition(ivar1, ivar0, 0, 0); + if (getItemIdInSlotSplit(134, ivar2) != -1) { + setItemOnWidgetMethod1200(getItemIdInSlotSplit(134, ivar2), getItemAmtInSlotSplit(134, ivar2)); + cs2method1305("" + getItemName(getItemIdInSlotSplit(134, ivar2))); + setWidgetContextMenuOption(1, "Examine"); + setWidgetShadowColor(new Color(48, 32, 32)); + setWidgetBorderThickness(1); + } + ivar1 = add(ivar1, 40); + ivar2 = add(ivar2, 1); + } + ivar0 = add(ivar0, 42); + ivar1 = 5; + } + return; +} diff --git a/dumps/scripts/990.cs2 b/dumps/scripts/990.cs2 new file mode 100644 index 0000000..fc3cc08 --- /dev/null +++ b/dumps/scripts/990.cs2 @@ -0,0 +1,206 @@ +cs2func_script_990_struct(2,2,0) script_990(int arg0,int arg1) { + switch (arg0) { + case 0: + switch (arg1) { + case 0: + return newstruct cs2func_script_990_struct(1, 1511, "Normal tree", "You can now chop down " + "" + "normal trees" + "" + "."); + case 1: + return newstruct cs2func_script_990_struct(1, 2862, "Members: Achey tree", "Members can now chop down " + "" + "achey trees" + "" + "."); + case 2: + return newstruct cs2func_script_990_struct(10, 6281, "Members: Light jungle" + "
" + " (after Jungle Potion)", "Members now have the Woodcutting level required to clear " + "" + "light jungle" + "" + " in Tai Bwo Wannai Clean-up (after Jungle Potion)."); + case 3: + return newstruct cs2func_script_990_struct(15, 1521, "Oak tree", "You can now chop down " + "" + "oak trees" + "" + "."); + case 4: + return newstruct cs2func_script_990_struct(20, 6283, "Members: Medium jungle" + "
" + " (after Jungle Potion)", "Members now have the Woodcutting level required to clear " + "" + "medium jungle" + "" + " in Tai Bwo Wannai Clean-up (after Jungle Potion)."); + case 5: + return newstruct cs2func_script_990_struct(30, 1519, "Willow tree", "You can now chop down " + "" + "willow trees" + "" + "."); + case 6: + return newstruct cs2func_script_990_struct(35, 6285, "Members: Dense jungle" + "
" + " (after Jungle Potion)", "Members now have the Woodcutting level required to clear " + "" + "dense jungle" + "" + " in Tai Bwo Wannai Clean-up (after Jungle Potion)."); + case 7: + return newstruct cs2func_script_990_struct(35, 6333, "Members: Teak tree" + "
" + " (after Jungle Potion)", "Members now have the Woodcutting level required to chop down " + "" + "teak trees" + "" + " (after Jungle Potion)."); + case 8: + return newstruct cs2func_script_990_struct(37, 13756, "Members: Cursed willow tree roots" + "
" + " (after starting Summer's End)", "Members now have the Woodcutting level required to chop " + "" + "cursed willow tree roots" + "" + " (after starting Summer's End)."); + case 9: + return newstruct cs2func_script_990_struct(45, 1517, "Maple tree", "You can now chop down " + "" + "maple trees" + "" + "."); + case 10: + return newstruct cs2func_script_990_struct(45, 3239, "Members: Hollow tree", "Members can now chop down " + "" + "hollow trees" + "" + "."); + case 11: + return newstruct cs2func_script_990_struct(50, 6332, "Members: Mahogany tree" + "
" + " (after Jungle Potion)", "Members now have the Woodcutting level required to chop down " + "" + "mahogany trees" + "" + " (after Jungle Potion)."); + case 12: + return newstruct cs2func_script_990_struct(54, 10810, "Members: Arctic pine tree", "Members can now chop down " + "" + "arctic pine trees" + "" + "."); + case 13: + return newstruct cs2func_script_990_struct(58, 12581, "Members: Eucalyptus tree", "Members can now chop down " + "" + "eucalyptus trees" + "" + "."); + case 14: + return newstruct cs2func_script_990_struct(60, 1515, "Yew tree", "You can now chop down " + "" + "yew trees" + "" + "."); + case 15: + return newstruct cs2func_script_990_struct(68, 15288, "Members: Choking ivy", "Members can now chop down " + "" + "choking ivy" + "" + "."); + case 16: + return newstruct cs2func_script_990_struct(75, 1513, "Members: Magic tree", "Members can now chop down " + "" + "magic trees" + "" + "."); + case 17: + return newstruct cs2func_script_990_struct(76, 21600, "Members: Blisterwood tree", "Members can now chop logs from the " + "" + "Blisterwood tree" + "" + "."); + case 18: + return newstruct cs2func_script_990_struct(80, 8794, "Members: Sawmill training", "Members can now participate in " + "" + "sawmill training" + "" + "."); + case 19: + return newstruct cs2func_script_990_struct(82, 13567, "Members: Cursed magic tree" + "
" + " (after Spirit of Summer)", "Members now have the Woodcutting level required to chop down " + "" + "cursed magic trees" + "" + " (after Spirit of Summer)."); + case 20: + return newstruct cs2func_script_990_struct(83, 21349, "Members: Straight root", "Members can now chop down " + "" + "straight roots" + "" + " in the jadinko lair."); + case 21: + return newstruct cs2func_script_990_struct(83, 21350, "Members: Curly root", "Members can now chop down " + "" + "curly roots" + "" + " in the jadinko lair."); + case 22: + return newstruct cs2func_script_990_struct(83, 21369, "Members: Mutated root", "Members can now chop down " + "" + "mutated roots" + "" + " in the jadinko lair."); + } + break; + case 1: + switch (arg1) { + case 0: + return newstruct cs2func_script_990_struct(1, 21340, "Members: Dwarven Army Axe", "Members can now use a " + "" + "Dwarven Army Axe" + "" + "."); + case 1: + return newstruct cs2func_script_990_struct(1, 1351, "Bronze hatchet", "You can now use " + "" + "bronze hatchets" + "" + "."); + case 2: + return newstruct cs2func_script_990_struct(1, 1349, "Iron hatchet", "You can now use " + "" + "iron hatchets" + "" + "."); + case 3: + return newstruct cs2func_script_990_struct(6, 1353, "Steel hatchet", "You can now use " + "" + "steel hatchets" + "" + "."); + case 4: + return newstruct cs2func_script_990_struct(6, 1361, "Black hatchet", "You can now use " + "" + "black hatchets" + "" + "."); + case 5: + return newstruct cs2func_script_990_struct(21, 1355, "Mithril hatchet", "You can now use " + "" + "mithril hatchets" + "" + "."); + case 6: + return newstruct cs2func_script_990_struct(31, 1357, "Adamant hatchet", "You can now use " + "" + "adamant hatchets" + "" + "."); + case 7: + return newstruct cs2func_script_990_struct(40, 14108, "Members: Sacred clay hatchet", "Members can now use " + "" + "sacred clay hatchets" + ""); + case 8: + return newstruct cs2func_script_990_struct(40, 14100, "Members: Volatile hatchet", "Members can now use " + "" + "volatile hatchets" + ""); + case 9: + return newstruct cs2func_script_990_struct(41, 1359, "Rune hatchet", "You can now use " + "" + "rune hatchets" + "" + "."); + case 10: + return newstruct cs2func_script_990_struct(61, 6739, "Members: Dragon hatchet", "Members can now use " + "" + "dragon hatchets" + "" + "."); + case 11: + return newstruct cs2func_script_990_struct(61, 13661, "Members: Inferno Adze" + "
" + " (after All Fired Up, with 92 Firemaking)", "Members can now use the " + "" + "Inferno Adze" + "" + " to chop down trees (after All Fired Up and with level 92 Firemaking)."); + } + break; + case 2: + switch (arg1) { + case 0: + return newstruct cs2func_script_990_struct(12, 7414, "Log canoe", "You can now make " + "" + "log canoes" + "" + "."); + case 1: + return newstruct cs2func_script_990_struct(27, 7414, "Dugout canoe", "You can now make " + "" + "dugout canoes" + "" + "."); + case 2: + return newstruct cs2func_script_990_struct(42, 7414, "Stable dugout canoe", "You can now make " + "" + "stable dugout canoes" + "" + "."); + case 3: + return newstruct cs2func_script_990_struct(57, 7414, "Waka canoe", "You can now make " + "" + "waka canoes" + "" + "."); + } + break; + case 3: + if (((boolean)arg1)) { + return newstruct cs2func_script_990_struct(44, 10939, "Lumberjack clothing", "Members can now wear the " + "" + "undead lumberjack" + "" + " clothing."); + } + if (((boolean)arg1)) { + return newstruct cs2func_script_990_struct(54, 10826, "Fremennik round shield", "Members can now make " + "" + "Fremennik round shields" + "" + "."); + } + if (arg1 == 2) { + return newstruct cs2func_script_990_struct(54, 10812, "Split arctic pine logs", "Members can now split " + "" + "arctic pine logs" + "" + "."); + } + break; + case 4: + switch (arg1) { + case 0: + return newstruct cs2func_script_990_struct(91, 18778, "Members: Starved ancient effigies", "Members can now investigate " + "" + "starved ancient effigies" + "" + " using their knowledge of Woodcutting."); + case 1: + return newstruct cs2func_script_990_struct(93, 18779, "Members: Nourished ancient effigies", "Members can now investigate " + "" + "nourished ancient effigies" + "" + " using their knowledge of Woodcutting."); + case 2: + return newstruct cs2func_script_990_struct(95, 18780, "Members: Sated ancient effigies", "Members can now investigate " + "" + "sated ancient effigies" + "" + " using their knowledge of Woodcutting."); + case 3: + return newstruct cs2func_script_990_struct(97, 18781, "Members: Gorged ancient effigies", "Members can now investigate " + "" + "gorged ancient effigies" + "" + " using their knowledge of Woodcutting."); + } + break; + case 5: + switch (arg1) { + case 0: + return newstruct cs2func_script_990_struct(1, 14667, "Chop basic evil tree", "Members can now chop " + "" + "basic evil trees" + ""); + case 1: + return newstruct cs2func_script_990_struct(1, 14132, "Stealing Creation - class 1 hatchet", "Members can now use " + "" + "class 1 hatchets" + "" + " in Stealing Creation."); + case 2: + return newstruct cs2func_script_990_struct(15, 14667, "Chop evil oak tree", "Members can now chop " + "" + "evil oak trees" + ""); + case 3: + return newstruct cs2func_script_990_struct(20, 14184, "Stealing Creation - woodcut class 2 sacred clay", "Members can now woodcut " + "" + "class 2 sacred clay" + "" + " in Stealing Creation."); + case 4: + return newstruct cs2func_script_990_struct(20, 14134, "Stealing Creation - class 2 hatchet", "Members can now use " + "" + "class 2 hatchets" + "" + " in Stealing Creation."); + case 5: + return newstruct cs2func_script_990_struct(30, 14667, "Chop evil willow tree", "Members can now chop " + "" + "evil willow trees" + ""); + case 6: + return newstruct cs2func_script_990_struct(40, 14186, "Stealing Creation - woodcut class 3 sacred clay", "Members can now woodcut " + "" + "class 3 sacred clay" + "" + " in Stealing Creation."); + case 7: + return newstruct cs2func_script_990_struct(40, 14136, "Stealing Creation - class 3 hatchet", "Members can now use " + "" + "class 3 hatchets" + "" + " in Stealing Creation."); + case 8: + return newstruct cs2func_script_990_struct(45, 14667, "Chop evil maple tree", "Members can now chop " + "" + "evil maple trees" + ""); + case 9: + return newstruct cs2func_script_990_struct(60, 14667, "Chop evil yew tree", "Members can now chop " + "" + "evil yew trees" + ""); + case 10: + return newstruct cs2func_script_990_struct(60, 14188, "Stealing Creation - woodcut class 4 sacred clay", "Members can now woodcut " + "" + "class 4 sacred clay" + "" + " in Stealing Creation."); + case 11: + return newstruct cs2func_script_990_struct(60, 14138, "Stealing Creation - class 4 hatchet", "Members can now use " + "" + "class 4 hatchets" + "" + " in Stealing Creation."); + case 12: + return newstruct cs2func_script_990_struct(75, 14667, "Chop evil magic tree", "Members can now chop " + "" + "evil magic trees" + ""); + case 13: + return newstruct cs2func_script_990_struct(80, 14190, "Stealing Creation - woodcut class 5 sacred clay", "Members can now woodcut " + "" + "class 5 sacred clay" + "" + " in Stealing Creation."); + case 14: + return newstruct cs2func_script_990_struct(80, 14140, "Stealing Creation - class 5 hatchet", "Members can now use " + "" + "class 5 hatchets" + "" + " in Stealing Creation."); + case 15: + return newstruct cs2func_script_990_struct(85, 14667, "Chop elder evil tree", "Members can now chop " + "" + "elder evil trees" + ""); + } + break; + case 6: + switch (arg1) { + case 0: + return newstruct cs2func_script_990_struct(-1, 15707, "Dungeoneering skill tasks" + "
" + "As your Woodcutting level increases, you will be able to attempt higher-level woodcutting tasks within Daemonheim. You will also be more likely to succeed when attempting woodcutting tasks within Daemonheim.", ""); + case 1: + return newstruct cs2func_script_990_struct(1, 17682, "Tangle gum tree (Tier 1)", "You can now chop down " + "" + "tangle gum trees" + "" + " within Daemonheim."); + case 2: + return newstruct cs2func_script_990_struct(1, 16361, "Novite hatchet (Tier 1)", "You can now use " + "" + "novite hatchets" + "" + " within Daemonheim."); + case 3: + return newstruct cs2func_script_990_struct(10, 17684, "Seeping elm tree (Tier 2)", "You can now chop " + "" + "seeping elm trees" + "" + " within Daemonheim."); + case 4: + return newstruct cs2func_script_990_struct(10, 16363, "Bathus hatchet (Tier 2)", "You can now use " + "" + "bathus hatchets" + "" + " within Daemonheim."); + case 5: + return newstruct cs2func_script_990_struct(20, 17686, "Blood spindle tree (Tier 3)", "You can now chop down " + "" + "blood spindle trees" + "" + " within Daemonheim."); + case 6: + return newstruct cs2func_script_990_struct(20, 16365, "Marmaros hatchet (Tier 3)", "You can now use " + "" + "marmaros hatchets" + "" + " within Daemonheim."); + case 7: + return newstruct cs2func_script_990_struct(30, 17688, "Utuku tree (Tier 4)", "You can now chop down " + "" + "utuku trees" + "" + " within Daemonheim."); + case 8: + return newstruct cs2func_script_990_struct(30, 16367, "Kratonite hatchet (Tier 4)", "You can now use " + "" + "kratonite hatchets" + "" + " within Daemonheim."); + case 9: + return newstruct cs2func_script_990_struct(40, 17690, "Spinebeam tree (Tier 5)", "You can now chop down " + "" + "spinebeam trees" + "" + " within Daemonheim."); + case 10: + return newstruct cs2func_script_990_struct(40, 16369, "Fractite hatchet (Tier 5)", "You can now use " + "" + "fractite hatchets" + "" + " within Daemonheim."); + case 11: + return newstruct cs2func_script_990_struct(50, 17692, "Members: Bovistrangler tree (Tier 6)", "Members can now chop down " + "" + "bovistrangler trees" + "" + " within Daemonheim."); + case 12: + return newstruct cs2func_script_990_struct(50, 16371, "Members: Zephyrium hatchet (Tier 6)", "Members can now use " + "" + "zephyrium hatchets" + "" + " within Daemonheim."); + case 13: + return newstruct cs2func_script_990_struct(60, 17694, "Members: Thigat tree (Tier 7)", "Members can now chop down " + "" + "thigat trees" + "" + " within Daemonheim."); + case 14: + return newstruct cs2func_script_990_struct(60, 16373, "Members: Argonite hatchet (Tier 7)", "Members can now use " + "" + "argonite hatchets" + "" + " within Daemonheim."); + case 15: + return newstruct cs2func_script_990_struct(70, 17696, "Members: Corpsethorn tree (Tier 8)", "Members can now chop down " + "" + "corpsethorn trees" + "" + " within Daemonheim."); + case 16: + return newstruct cs2func_script_990_struct(70, 16375, "Members: Katagon hatchet (Tier 8)", "Members can now use " + "" + "katagon hatchets" + "" + " within Daemonheim."); + case 17: + return newstruct cs2func_script_990_struct(80, 17698, "Members: Entgallow tree (Tier 9)", "Members can now chop down " + "" + "entgallow trees" + "" + " within Daemonheim."); + case 18: + return newstruct cs2func_script_990_struct(80, 16377, "Members: Gorgonite hatchet (Tier 9)", "Members can now use " + "" + "gorgonite hatchets" + "" + " within Daemonheim."); + case 19: + return newstruct cs2func_script_990_struct(90, 17700, "Members: Grave creeper tree (Tier 10)", "Members can now chop down " + "" + "grave creeper trees" + "" + " within Daemonheim."); + case 20: + return newstruct cs2func_script_990_struct(90, 16379, "Members: Promethium hatchet (Tier 10)", "Members can now use " + "" + "promethium hatchets" + "" + " within Daemonheim."); + case 21: + return newstruct cs2func_script_990_struct(99, 16381, "Members: Primal hatchet (Tier 11)", "Members can now use primal hatchets" + "" + " within Daemonheim."); + } + break; + case 7: + if (((boolean)arg1)) { + return newstruct cs2func_script_990_struct(99, 9807, "Skill mastery", "" + "Congratulations! You are now a master of " + "" + "Woodcutting" + "" + ". Members can visit " + "" + "Wilfred" + "" + ", just to the north of " + "" + "Falador" + "" + ". He has something special that is only available to true masters of the " + "" + "Woodcutting" + "" + " skill!"); + } + } + return newstruct cs2func_script_990_struct(0, -1, "", ""); +} diff --git a/dumps/scripts/991.cs2 b/dumps/scripts/991.cs2 new file mode 100644 index 0000000..c34ce77 --- /dev/null +++ b/dumps/scripts/991.cs2 @@ -0,0 +1,23 @@ +cs2func_script_991_struct(1,1,0) script_991(int arg0) { + switch (arg0) { + case 0: + return newstruct cs2func_script_991_struct(1, "Pickpocket"); + case 1: + return newstruct cs2func_script_991_struct(1, "Multiple Pickpocket"); + case 2: + return newstruct cs2func_script_991_struct(1, "Stalls"); + case 3: + return newstruct cs2func_script_991_struct(1, "Chests"); + case 4: + return newstruct cs2func_script_991_struct(1, "Miscellaneous"); + case 5: + return newstruct cs2func_script_991_struct(1, "Other"); + case 6: + return newstruct cs2func_script_991_struct(1, "Minigames"); + case 7: + return newstruct cs2func_script_991_struct(1, "Dungeoneering"); + case 8: + return newstruct cs2func_script_991_struct(1, "Milestones"); + } + return newstruct cs2func_script_991_struct(-1, ""); +} diff --git a/dumps/scripts/992.cs2 b/dumps/scripts/992.cs2 new file mode 100644 index 0000000..baa3083 --- /dev/null +++ b/dumps/scripts/992.cs2 @@ -0,0 +1,297 @@ +cs2func_script_992_struct(2,2,0) script_992(int arg0,int arg1) { + switch (arg0) { + case 0: + switch (arg1) { + case 0: + return newstruct cs2func_script_992_struct(1, 3241, "Man", "You can now pickpocket " + "" + "men" + "" + " and " + "" + "women" + "" + "."); + case 1: + return newstruct cs2func_script_992_struct(10, 3243, "Farmer", "You can now pickpocket " + "" + "farmers" + "" + "."); + case 2: + return newstruct cs2func_script_992_struct(15, 4295, "Female H.A.M. follower", "You can now pickpocket " + "" + "female H.A.M. followers" + "" + "."); + case 3: + return newstruct cs2func_script_992_struct(20, 4297, "Male H.A.M. follower", "You can now pickpocket " + "" + "male H.A.M. followers" + "" + "."); + case 4: + return newstruct cs2func_script_992_struct(25, 3245, "Warrior", "You can now pickpocket " + "" + "warriors" + "" + "."); + case 5: + return newstruct cs2func_script_992_struct(32, 3247, "Rogue", "You can now pickpocket " + "" + "rogues" + "" + "."); + case 6: + return newstruct cs2func_script_992_struct(36, 10998, "Cave goblin", "You can now pickpocket " + "" + "cave goblins" + "" + "."); + case 7: + return newstruct cs2func_script_992_struct(38, 5068, "Master farmer", "You can now pickpocket " + "" + "master farmers" + "" + "."); + case 8: + return newstruct cs2func_script_992_struct(40, 3249, "Guard", "You can now pickpocket " + "" + "guards" + "" + "."); + case 9: + return newstruct cs2func_script_992_struct(45, 3686, "Fremennik citizen", "You can now pickpocket " + "" + "Fremennik citizens" + "" + "."); + case 10: + return newstruct cs2func_script_992_struct(45, 6782, "Bearded Pollnivnian bandit", "You can now pickpocket " + "" + "bearded Pollnivnian bandits" + "" + "."); + case 11: + return newstruct cs2func_script_992_struct(53, 4625, "Desert bandit", "You can now pickpocket " + "" + "desert bandits" + "" + "."); + case 12: + return newstruct cs2func_script_992_struct(55, 3251, "Knight", "You can now pickpocket " + "" + "knights" + "" + "."); + case 13: + return newstruct cs2func_script_992_struct(55, 6781, "Pollnivnian bandit", "You can now pickpocket " + "" + "Pollnivnian bandits" + "" + "."); + case 14: + return newstruct cs2func_script_992_struct(65, 3253, "Watchman", "You can now pickpocket " + "" + "watchmen" + "" + "."); + case 15: + return newstruct cs2func_script_992_struct(65, 6780, "Menaphite thug", "You can now pickpocket " + "" + "Menaphite thugs" + "" + "."); + case 16: + return newstruct cs2func_script_992_struct(70, 3255, "Paladin", "You can now pickpocket " + "" + "paladins" + "" + "."); + case 17: + return newstruct cs2func_script_992_struct(75, 3257, "Gnome", "You can now pickpocket " + "" + "gnomes" + "" + "."); + case 18: + return newstruct cs2func_script_992_struct(80, 3259, "Hero", "You can now pickpocket " + "" + "heroes" + "" + "."); + case 19: + return newstruct cs2func_script_992_struct(85, 6105, "Elf", "You can now pickpocket " + "" + "elves" + "" + "."); + case 20: + return newstruct cs2func_script_992_struct(90, 15258, "Dwarf trader", "You can now pickpocket " + "" + "dwarven traders" + "" + "."); + } + break; + case 1: + switch (arg1) { + case 0: + return newstruct cs2func_script_992_struct(11, 3241, "Possibility of stealing double loot from a man", "You now have the Thieving level required to potentially steal double loot from " + "" + "men" + "" + " and " + "" + "women" + "" + "."); + case 1: + return newstruct cs2func_script_992_struct(20, 3243, "Possibility of stealing double loot from a farmer" + "
" + " (with 10 Agility)", "You now have the Thieving level required to potentially steal double loot from " + "" + "farmers" + "" + ". (You also need level 10 Agility.)"); + case 2: + return newstruct cs2func_script_992_struct(21, 3241, "Possibility of stealing triple loot from a man" + "
" + " (with 11 Agility)", "You now have the Thieving level required to potentially steal triple loot from " + "" + "men" + "" + " and " + "" + "women" + "" + ". (You also need level 11 Agility.)"); + case 3: + return newstruct cs2func_script_992_struct(25, 4295, "Possibility of stealing double loot from a female H.A.M. follower" + "
" + " (with 15 Agility)", "You now have the Thieving level required to potentially steal double loot from " + "" + "female H.A.M. followers" + "" + ". (You also need level 15 Agility.)"); + case 4: + return newstruct cs2func_script_992_struct(30, 3243, "Possibility of stealing triple loot from a farmer" + "
" + " (with 20 Agility)", "You now have the Thieving level required to potentially steal triple loot from " + "" + "farmers" + "" + ". (You also need level 20 Agility.)"); + case 5: + return newstruct cs2func_script_992_struct(30, 4297, "Possibility of stealing double loot from a male H.A.M. follower" + "
" + " (with 20 Agility)", "You now have the Thieving level required to potentially steal double loot from " + "" + "male H.A.M. followers" + "" + ". (You also need level 20 Agility.)"); + case 6: + return newstruct cs2func_script_992_struct(31, 3241, "Possibility of stealing quadruple loot from a man" + "
" + " (with 21 Agility)", "You now have the Thieving level required to potentially steal quadruple loot from " + "" + "men" + "" + " and " + "" + "women" + "" + ". (You also need level 21 Agility.)"); + case 7: + return newstruct cs2func_script_992_struct(35, 4295, "Possibility of stealing triple loot from a female H.A.M. follower" + "
" + " (with 25 Agility)", "You now have the Thieving level required to potentially steal triple loot from " + "" + "female H.A.M. followers" + "" + ". (You also need level 25 Agility.)"); + case 8: + return newstruct cs2func_script_992_struct(35, 3245, "Possibility of stealing double loot from a warrior" + "
" + " (with 25 Agility)", "You now have the Thieving level required to potentially steal double loot from " + "" + "warriors" + "" + ". (You also need level 25 Agility.)"); + case 9: + return newstruct cs2func_script_992_struct(40, 3243, "Possibility of stealing quadruple loot from a farmer" + "
" + " (with 30 Agility)", "You now have the Thieving level required to potentially steal quadruple loot from " + "" + "farmers" + "" + ". (You also need level 30 Agility.)"); + case 10: + return newstruct cs2func_script_992_struct(40, 4297, "Possibility of stealing triple loot from a male H.A.M. follower" + "
" + " (with 30 Agility)", "You now have the Thieving level required to potentially steal triple loot from " + "" + "male H.A.M. followers" + "" + ". (You also need level 30 Agility.)"); + case 11: + return newstruct cs2func_script_992_struct(42, 3247, "Possibility of stealing double loot from a rogue" + "
" + " (with 32 Agility)", "You now have the Thieving level required to potentially steal double loot from " + "" + "rogues" + "" + ". (You also need level 32 Agility.)"); + case 12: + return newstruct cs2func_script_992_struct(45, 4295, "Possibility of stealing quadruple loot from a female H.A.M. follower" + "
" + " (with 35 Agility)", "You now have the Thieving level required to potentially steal quadruple loot from " + "" + "female H.A.M. followers" + "" + ". (You also need level 35 Agility.)"); + case 13: + return newstruct cs2func_script_992_struct(45, 3245, "Possibility of stealing triple loot from a warrior" + "
" + " (with 35 Agility)", "You now have the Thieving level required to potentially steal triple loot from " + "" + "warriors" + "" + ". (You also need level 35 Agility.)"); + case 14: + return newstruct cs2func_script_992_struct(46, 10998, "Possibility of stealing double loot from a cave goblin" + "
" + " (with 36 Agility)", "You now have the Thieving level required to potentially steal double loot from " + "" + "cave goblins" + "" + ". (You also need level 36 Agility.)"); + case 15: + return newstruct cs2func_script_992_struct(48, 5068, "Possibility of stealing double loot from a master farmer" + "
" + " (with 38 Agility)", "You now have the Thieving level required to potentially steal double loot from " + "" + "master farmers" + "" + ". (You also need level 38 Agility.)"); + case 16: + return newstruct cs2func_script_992_struct(50, 4297, "Possibility of stealing quadruple loot from a male H.A.M. follower" + "
" + " (with 40 Agility)", "You now have the Thieving level required to potentially steal quadruple loot from " + "" + "male H.A.M. followers" + "" + ". (You also need level 40 Agility.)"); + case 17: + return newstruct cs2func_script_992_struct(50, 3249, "Possibility of stealing double loot from a guard" + "
" + " (with 40 Agility)", "You now have the Thieving level required to potentially steal double loot from " + "" + "guards" + "" + ". (You also need level 40 Agility.)"); + case 18: + return newstruct cs2func_script_992_struct(52, 3247, "Possibility of stealing triple loot from a rogue" + "
" + " (with 42 Agility)", "You now have the Thieving level required to potentially steal triple loot from " + "" + "rogues" + "" + ". (You also need level 42 Agility.)"); + case 19: + return newstruct cs2func_script_992_struct(55, 3245, "Possibility of stealing quadruple loot from a warrior" + "
" + " (with 45 Agility)", "You now have the Thieving level required to potentially steal quadruple loot from " + "" + "warriors" + "" + ". (You also need level 45 Agility.)"); + case 20: + return newstruct cs2func_script_992_struct(55, 3686, "Possibility of stealing double loot from a Fremennik citizen" + "
" + " (with 45 Agility)", "You now have the Thieving level required to potentially steal double loot from " + "" + "Fremennik citizens" + "" + ". (You also need level 45 Agility.)"); + case 21: + return newstruct cs2func_script_992_struct(55, 6782, "Possibility of stealing double loot from a bearded Pollnivnian bandit" + "
" + " (with 45 Agility)", "You now have the Thieving level required to potentially steal double loot from " + "" + "bearded Pollnivnian bandits" + "" + ". (You also need level 45 Agility.)"); + case 22: + return newstruct cs2func_script_992_struct(56, 10998, "Possibility of stealing triple loot from a cave goblin" + "
" + " (with 46 Agility)", "You now have the Thieving level required to potentially steal triple loot from " + "" + "cave goblins" + "" + ". (You also need level 46 Agility.)"); + case 23: + return newstruct cs2func_script_992_struct(58, 5068, "Possibility of stealing triple loot from a master farmer" + "
" + " (with 48 Agility)", "You now have the Thieving level required to potentially steal triple loot from " + "" + "master farmers" + "" + ". (You also need level 48 Agility.)"); + case 24: + return newstruct cs2func_script_992_struct(60, 3249, "Possibility of stealing triple loot from a guard" + "
" + " (with 50 Agility)", "You now have the Thieving level required to potentially steal triple loot from " + "" + "guards" + "" + ". (You also need level 50 Agility.)"); + case 25: + return newstruct cs2func_script_992_struct(62, 3247, "Possibility of stealing quadruple loot from a rogue" + "
" + " (with 52 Agility)", "You now have the Thieving level required to potentially steal quadruple loot from " + "" + "rogues" + "" + ". (You also need level 52 Agility.)"); + case 26: + return newstruct cs2func_script_992_struct(63, 4625, "Possibility of stealing double loot from a desert bandit" + "
" + " (with 53 Agility)", "You now have the Thieving level required to potentially steal double loot from " + "" + "desert bandits" + "" + ". (You also need level 53 Agility.)"); + case 27: + return newstruct cs2func_script_992_struct(65, 3686, "Possibility of stealing triple loot from a Fremennik citizen" + "
" + " (with 55 Agility)", "You now have the Thieving level required to potentially steal triple loot from " + "" + "Fremennik citizens" + "" + ". (You also need level 55 Agility.)"); + case 28: + return newstruct cs2func_script_992_struct(65, 6782, "Possibility of stealing triple loot from a bearded Pollnivnian bandit" + "
" + " (with 55 Agility)", "You now have the Thieving level required to potentially steal triple loot from " + "" + "bearded Pollnivnian bandits" + "" + ". (You also need level 55 Agility.)"); + case 29: + return newstruct cs2func_script_992_struct(65, 3251, "Possibility of stealing double loot from a knight" + "
" + " (with 55 Agility)", "You now have the Thieving level required to potentially steal double loot from " + "" + "knights" + "" + ". (You also need level 55 Agility.)"); + case 30: + return newstruct cs2func_script_992_struct(65, 6781, "Possibility of stealing double loot from a Pollnivnian bandit" + "
" + " (with 55 Agility)", "You now have the Thieving level required to potentially steal double loot from " + "" + "Pollnivnian bandits" + "" + ". (You also need level 55 Agility.)"); + case 31: + return newstruct cs2func_script_992_struct(66, 10998, "Possibility of stealing quadruple loot from a cave goblin" + "
" + " (with 56 Agility)", "You now have the Thieving level required to potentially steal quadruple loot from " + "" + "cave goblins" + "" + ". (You also need level 56 Agility.)"); + case 32: + return newstruct cs2func_script_992_struct(68, 5068, "Possibility of stealing quadruple loot from a master farmer" + "
" + " (with 58 Agility)", "You now have the Thieving level required to potentially steal quadruple loot from " + "" + "master farmers" + "" + ". (You also need level 58 Agility.)"); + case 33: + return newstruct cs2func_script_992_struct(70, 3249, "Possibility of stealing quadruple loot from a guard" + "
" + " (with 60 Agility)", "You now have the Thieving level required to potentially steal quadruple loot from " + "" + "guards" + "" + ". (You also need level 60 Agility.)"); + case 34: + return newstruct cs2func_script_992_struct(73, 4625, "Possibility of stealing triple loot from a desert bandit" + "
" + " (with 63 Agility)", "You now have the Thieving level required to potentially steal triple loot from " + "" + "desert bandits" + "" + ". (You also need level 63 Agility.)"); + case 35: + return newstruct cs2func_script_992_struct(75, 3686, "Possibility of stealing quadruple loot from a Fremennik citizen" + "
" + " (with 65 Agility)", "You now have the Thieving level required to potentially steal quadruple loot from " + "" + "Fremennik citizens" + "" + ". (You also need level 65 Agility.)"); + case 36: + return newstruct cs2func_script_992_struct(75, 6782, "Possibility of stealing quadruple loot from a bearded Pollnivnian bandit" + "
" + " (with 65 Agility)", "You now have the Thieving level required to potentially steal quadruple loot from " + "" + "bearded Pollnivnian bandits" + "" + ". (You also need level 65 Agility.)"); + case 37: + return newstruct cs2func_script_992_struct(75, 3251, "Possibility of stealing triple loot from a knight" + "
" + " (with 65 Agility)", "You now have the Thieving level required to potentially steal triple loot from " + "" + "knights" + "" + ". (You also need level 65 Agility.)"); + case 38: + return newstruct cs2func_script_992_struct(75, 6781, "Possibility of stealing triple loot from a Pollnivnian bandit" + "
" + " (with 65 Agility)", "You now have the Thieving level required to potentially steal triple loot from " + "" + "Pollnivnian bandits" + "" + ". (You also need level 65 Agility.)"); + case 39: + return newstruct cs2func_script_992_struct(75, 3253, "Possibility of stealing double loot from a watchman" + "
" + " (with 65 Agility)", "You now have the Thieving level required to potentially steal double loot from " + "" + "watchmen" + "" + ". (You also need level 65 Agility.)"); + case 40: + return newstruct cs2func_script_992_struct(75, 6780, "Possibility of stealing double loot from a Menaphite thug" + "
" + " (with 65 Agility)", "You now have the Thieving level required to potentially steal double loot from " + "" + "Menaphite thugs" + "" + ". (You also need level 65 Agility.)"); + case 41: + return newstruct cs2func_script_992_struct(80, 3255, "Possibility of stealing double loot from a paladin" + "
" + " (with 70 Agility)", "You now have the Thieving level required to potentially steal double loot from " + "" + "paladins" + "" + ". (You also need level 70 Agility.)"); + case 42: + return newstruct cs2func_script_992_struct(83, 4625, "Possibility of stealing quadruple loot from a desert bandit" + "
" + " (with 73 Agility)", "You now have the Thieving level required to potentially steal quadruple loot from " + "" + "desert bandits" + "" + ". (You also need level 73 Agility.)"); + case 43: + return newstruct cs2func_script_992_struct(85, 3251, "Possibility of stealing quadruple loot from a knight" + "
" + " (with 75 Agility)", "You now have the Thieving level required to potentially steal quadruple loot from " + "" + "knights" + "" + ". (You also need level 75 Agility.)"); + case 44: + return newstruct cs2func_script_992_struct(85, 6781, "Possibility of stealing quadruple loot from a Pollnivnian bandit" + "
" + " (with 75 Agility)", "You now have the Thieving level required to potentially steal quadruple loot from " + "" + "Pollnivnian bandits" + "" + ". (You also need level 75 Agility.)"); + case 45: + return newstruct cs2func_script_992_struct(85, 3253, "Possibility of stealing triple loot from a watchman" + "
" + " (with 75 Agility)", "You now have the Thieving level required to potentially steal triple loot from " + "" + "watchmen" + "" + ". (You also need level 75 Agility.)"); + case 46: + return newstruct cs2func_script_992_struct(85, 6780, "Possibility of stealing triple loot from a Menaphite thug" + "
" + " (with 75 Agility)", "You now have the Thieving level required to potentially steal triple loot from " + "" + "Menaphite thugs" + "" + ". (You also need level 75 Agility.)"); + case 47: + return newstruct cs2func_script_992_struct(85, 3257, "Possibility of stealing double loot from a gnome" + "
" + " (with 75 Agility)", "You now have the Thieving level required to potentially steal double loot from " + "" + "gnomes" + "" + ". (You also need level 75 Agility.)"); + case 48: + return newstruct cs2func_script_992_struct(90, 3255, "Possibility of stealing triple loot from a paladin" + "
" + " (with 80 Agility)", "You now have the Thieving level required to potentially steal triple loot from " + "" + "paladins" + "" + ". (You also need level 80 Agility.)"); + case 49: + return newstruct cs2func_script_992_struct(90, 3259, "Possibility of stealing double loot from a hero" + "
" + " (with 80 Agility)", "You now have the Thieving level required to potentially steal double loot from " + "" + "heroes" + "" + ". (You also need level 80 Agility.)"); + case 50: + return newstruct cs2func_script_992_struct(95, 3253, "Possibility of stealing quadruple loot from a watchman" + "
" + " (with 85 Agility)", "You now have the Thieving level required to potentially steal quadruple loot from " + "" + "watchmen" + "" + ". (You also need level 85 Agility.)"); + case 51: + return newstruct cs2func_script_992_struct(95, 6780, "Possibility of stealing quadruple loot from a Menaphite thug" + "
" + " (with 85 Agility)", "You now have the Thieving level required to potentially steal quadruple loot from " + "" + "Menaphite thugs" + "" + ". (You also need level 85 Agility.)"); + case 52: + return newstruct cs2func_script_992_struct(95, 3257, "Possibility of stealing triple loot from a gnome" + "
" + " (with 85 Agility)", "You now have the Thieving level required to potentially steal triple loot from " + "" + "gnomes" + "" + ". (You also need level 85 Agility.)"); + case 53: + return newstruct cs2func_script_992_struct(95, 6105, "Possibility of stealing double loot from an elf" + "
" + " (with 85 Agility)", "You now have the Thieving level required to potentially steal double loot from " + "" + "elves" + "" + ". (You also need level 85 Agility.)"); + } + break; + case 2: + switch (arg1) { + case 0: + return newstruct cs2func_script_992_struct(2, 1965, "Vegetable stall" + "
" + " (after Fremennik Trials)", "You now have the Thieving level required to steal from " + "" + "vegetable stalls" + "" + " (after Fremennik Trials)."); + case 1: + return newstruct cs2func_script_992_struct(5, 1891, "Baker's stall", "You can now steal from " + "" + "bakers' stalls" + "" + "."); + case 2: + return newstruct cs2func_script_992_struct(5, 1933, "Ape Atoll general stall" + "
" + " (after starting Monkey Madness)", "You now have the Thieving level required to steal from the " + "" + "general stall" + "" + " on Ape Atoll (after starting Monkey Madness)."); + case 3: + return newstruct cs2func_script_992_struct(5, 1978, "Tea stall", "You can now steal from " + "" + "tea stalls" + "" + "."); + case 4: + return newstruct cs2func_script_992_struct(5, 1755, "Crafting stall", "You can now steal from the " + "" + "crafting stalls" + "" + " in Keldagrim and, after starting Monkey Madness, the Ape Atoll."); + case 5: + return newstruct cs2func_script_992_struct(5, 1963, "Monkey food stall" + "
" + " (after starting Monkey Madness)", "You now have the Thieving level required to steal from the " + "" + "monkey food stall" + "" + " (after starting Monkey Madness)."); + case 6: + return newstruct cs2func_script_992_struct(15, 2379, "Rock cake stall", "You can now steal from " + "" + "rock cake stalls" + "" + "."); + case 7: + return newstruct cs2func_script_992_struct(20, 950, "Silk stall", "You can now steal from " + "" + "silk stalls" + "" + "."); + case 8: + return newstruct cs2func_script_992_struct(22, 7919, "Wine stall", "You can now steal from " + "" + "wine stalls" + "" + "."); + case 9: + return newstruct cs2func_script_992_struct(27, 5171, "Seed stall", "You can now steal from " + "" + "seed stalls" + "" + "."); + case 10: + return newstruct cs2func_script_992_struct(35, 948, "Fur stall", "You can now steal from " + "" + "fur stalls" + "" + "."); + case 11: + return newstruct cs2func_script_992_struct(42, 331, "Fish stall", "You can now steal from " + "" + "fish stalls" + "" + "."); + case 12: + return newstruct cs2func_script_992_struct(49, 9174, "Crossbow stall", "You can now steal from " + "" + "crossbow stalls" + "" + "."); + case 13: + return newstruct cs2func_script_992_struct(50, 442, "Silver stall", "You can now steal from " + "" + "silver stalls" + "" + "."); + case 14: + return newstruct cs2func_script_992_struct(63, 2773, "Customs evidence files" + "
" + " (after Rocking Out)", "You now have the Thieving level to steal from the " + "" + "customs evidence files" + "" + " of " + "" + "Rock Island Prison" + "" + " (after Rocking Out)."); + case 15: + return newstruct cs2func_script_992_struct(65, 556, "Magic stall", "You can now steal from " + "" + "magic stalls" + "" + "."); + case 16: + return newstruct cs2func_script_992_struct(65, 1323, "Scimitar stall", "You can now steal from " + "" + "scimitar stalls" + "" + "."); + case 17: + return newstruct cs2func_script_992_struct(65, 2007, "Spice stall", "You can now steal from " + "" + "spice stalls" + "" + "."); + case 18: + return newstruct cs2func_script_992_struct(75, 1607, "Gem stall", "You can now steal from " + "" + "gem stalls" + "" + "."); + } + break; + case 3: + switch (arg1) { + case 0: + return newstruct cs2func_script_992_struct(13, 1001, "Ardougne, Rellekka and the Wilderness", "You can now steal from certain " + "" + "chests" + "" + " in " + "" + "Ardougne" + "" + ", " + "" + "Rellekka" + "" + " and the " + "" + "Wilderness" + "" + "."); + case 1: + return newstruct cs2func_script_992_struct(28, 561, "Upstairs in Ardougne and Rellekka", "You can now steal from certain " + "" + "chests" + "" + " upstairs in " + "" + "Ardougne" + "" + " and " + "" + "Rellekka" + "" + "."); + case 2: + return newstruct cs2func_script_992_struct(43, 1001, "Upstairs in Ardougne", "You can now steal from certain " + "" + "chests" + "" + " upstairs in " + "" + "Ardougne" + "" + "."); + case 3: + return newstruct cs2func_script_992_struct(47, 41, "Hemenster", "You can now steal from certain " + "" + "chests" + "" + " in " + "" + "Hemenster" + "" + "."); + case 4: + return newstruct cs2func_script_992_struct(47, 1001, "Rellekka", "You can now steal from certain " + "" + "chests" + "" + " in " + "" + "Rellekka" + "" + "."); + case 5: + return newstruct cs2func_script_992_struct(52, 4522, "Dorgesh-Kaan (average chests)", "You can now steal from " + "" + "average chests" + "" + " in " + "" + "Dorgesh-Kaan" + "" + "."); + case 6: + return newstruct cs2func_script_992_struct(59, 565, "Chaos Druid Tower, north of Ardougne", "You can now steal from " + "" + "chests" + "" + " in the " + "" + "Chaos Druid Tower" + "" + ", north of " + "" + "Ardougne" + "" + "."); + case 7: + return newstruct cs2func_script_992_struct(72, 383, "King Lathas's castle in Ardougne", "You can now steal from " + "" + "chests" + "" + " in " + "" + "King Lathas's castle" + "" + " in " + "" + "Ardougne" + "" + "."); + case 8: + return newstruct cs2func_script_992_struct(78, 1623, "Dorgesh-Kaan (rich chests)", "You can now steal from " + "" + "rich chests" + "" + " in " + "" + "Dorgesh-Kaan" + "" + "."); + } + break; + case 4: + switch (arg1) { + case 0: + return newstruct cs2func_script_992_struct(15, 10593, "Cowbells from dairy cows (after starting Cold War)", "You now have the Thieving level required to steal " + "" + "cowbells" + "" + " from " + "" + "dairy cows" + "" + " (after starting Cold War)."); + case 1: + return newstruct cs2func_script_992_struct(20, 4834, "Zogre coffins at Jiggig", "You can now pick locks in " + "" + "zogre coffins" + "" + " at " + "" + "Jiggig" + "" + "."); + case 2: + return newstruct cs2func_script_992_struct(21, 21534, "Black Ibis Gear" + "
" + " (from Pyramid Plunder)", "You now have the Thieving level required to wear " + "" + "Black Ibis clothing" + "" + " found in Pyramid Plunder."); + case 3: + return newstruct cs2func_script_992_struct(30, 4599, "Blackjack lure and knockout" + "
" + " (after starting The Feud)", "Members now have the Thieving level required to use a " + "" + "blackjack" + "" + " to lure and knockout a target (after starting The Feud)."); + case 4: + return newstruct cs2func_script_992_struct(44, 10981, "Wire from the Dorgeshuun wire machine.", "You can now steal " + "" + "wire" + "" + " from the " + "" + "Dorgeshuun wire machine" + "" + "."); + case 5: + return newstruct cs2func_script_992_struct(82, 1523, "Pick lock to enter Agility Dungeon from Yanille", "You can now use your lock-picking skills to access the " + "" + "Agility Dungeon" + "" + " from " + "" + "Yanille" + "" + "."); + } + break; + case 5: + switch (arg1) { + case 0: + return newstruct cs2func_script_992_struct(91, 18778, "Starved ancient effigies", "You can now investigate " + "" + "starved ancient effigies" + "" + " using your knowledge of Thieving."); + case 1: + return newstruct cs2func_script_992_struct(93, 18779, "Nourished ancient effigies", "You can now investigate " + "" + "nourished ancient effigies" + "" + " using your knowledge of Thieving."); + case 2: + return newstruct cs2func_script_992_struct(95, 18780, "Sated ancient effigies", "You can now investigate " + "" + "sated ancient effigies" + "" + " using your knowledge of Thieving."); + case 3: + return newstruct cs2func_script_992_struct(97, 18781, "Gorged ancient effigies", "You can now investigate " + "" + "gorged ancient effigies" + "" + " using your knowledge of Thieving."); + } + break; + case 6: + switch (arg1) { + case 0: + return newstruct cs2func_script_992_struct(-1, 7620, "In Stealing Creation, you can pickpocket players 20 levels above your own.", ""); + case 1: + return newstruct cs2func_script_992_struct(1, 10855, "Sorceress's Garden - Winter", "You can now enter the " + "" + "winter garden" + "" + " in " + "" + "Sorceress's Garden" + "" + "."); + case 2: + return newstruct cs2func_script_992_struct(21, 9026, "Pyramid Plunder - Room 1", "You can now enter the " + "" + "first chamber" + "" + " of the " + "" + "Pyramid of Jalsavrah" + "" + " in " + "" + "Pyramid Plunder" + "" + "."); + case 3: + return newstruct cs2func_script_992_struct(25, 10853, "Sorceress's Garden - Spring", "You can now enter the " + "" + "spring garden" + "" + " in " + "" + "Sorceress's Garden" + "" + "."); + case 4: + return newstruct cs2func_script_992_struct(31, 9032, "Pyramid Plunder - Room 2", "You can now enter the " + "" + "second chamber" + "" + " of the " + "" + "Pyramid of Jalsavrah" + "" + " in " + "" + "Pyramid Plunder" + "" + "."); + case 5: + return newstruct cs2func_script_992_struct(41, 9036, "Pyramid Plunder - Room 3", "You can now enter the " + "" + "third chamber" + "" + " of the " + "" + "Pyramid of Jalsavrah" + "" + " in " + "" + "Pyramid Plunder" + "" + "."); + case 6: + return newstruct cs2func_script_992_struct(45, 10854, "Sorceress's Garden - Autumn", "You can now enter the " + "" + "autumn garden" + "" + " in " + "" + "Sorceress's Garden" + "" + "."); + case 7: + return newstruct cs2func_script_992_struct(50, 5559, "Rogues' Den" + "
" + " (with 50 Agility)", "You now have the Thieving level required to attempt the " + "" + "Rogues' Den" + "" + ", located below the Toad and Chicken in " + "" + "Burthorpe" + "" + ". (You also need level 50 Agility.)"); + case 8: + return newstruct cs2func_script_992_struct(51, 9042, "Pyramid Plunder - Room 4", "You can now enter the " + "" + "fourth chamber" + "" + " of the " + "" + "Pyramid of Jalsavrah" + "" + " in " + "" + "Pyramid Plunder" + "" + "."); + case 9: + return newstruct cs2func_script_992_struct(61, 9038, "Pyramid Plunder - Room 5", "You can now enter the " + "" + "fifth chamber" + "" + " of the " + "" + "Pyramid of Jalsavrah" + "" + " in " + "" + "Pyramid Plunder" + "" + "."); + case 10: + return newstruct cs2func_script_992_struct(65, 10852, "Sorceress's Garden - Summer", "You can now enter the " + "" + "summer garden" + "" + " in " + "" + "Sorceress's Garden" + "" + "."); + case 11: + return newstruct cs2func_script_992_struct(71, 9040, "Pyramid Plunder - Room 6", "You can now enter the " + "" + "sixth chamber" + "" + " of the " + "" + "Pyramid of Jalsavrah" + "" + " in " + "" + "Pyramid Plunder" + "" + "."); + case 12: + return newstruct cs2func_script_992_struct(81, 9028, "Pyramid Plunder - Room 7", "You can now enter the " + "" + "seventh chamber" + "" + " of the " + "" + "Pyramid of Jalsavrah" + "" + " in " + "" + "Pyramid Plunder" + "" + "."); + case 13: + return newstruct cs2func_script_992_struct(91, 9034, "Pyramid Plunder - Room 8", "You can now enter the " + "" + "eighth chamber" + "" + " of the " + "" + "Pyramid of Jalsavrah" + "" + " in " + "" + "Pyramid Plunder" + "" + "."); + } + break; + case 7: + switch (arg1) { + case 0: + return newstruct cs2func_script_992_struct(-1, 15707, "Dungeoneering skill tasks" + "
" + "
" + "As your Thieving level increases, you will be able to attempt higher-level Thieving tasks within Daemonheim." + "
" + "
" + "You will be more likely to succeed when attempting Thieving tasks within Daemonheim." + "
" + "
" + "You will also be able to open higher level " + "" + "locked chests" + "" + " within Daemonheim.", ""); + } + break; + case 8: + if (((boolean)arg1)) { + return newstruct cs2func_script_992_struct(99, 9777, "Skill mastery", "" + "Congratulations! You are now a master thief. Why not visit " + "" + "Martin Thwait" + "" + ", who runs a shop at the " + "" + "Rogues' Den" + "" + ". He has something special that is only available to true masters of the " + "" + "Thieving" + "" + " skill!"); + } + } + return newstruct cs2func_script_992_struct(0, -1, "", ""); +} diff --git a/dumps/scripts/993.cs2 b/dumps/scripts/993.cs2 new file mode 100644 index 0000000..85aebdc --- /dev/null +++ b/dumps/scripts/993.cs2 @@ -0,0 +1,12 @@ +cs2func_script_993_struct(1,1,0) script_993(int arg0) { + if (((boolean)arg0)) { + return newstruct cs2func_script_993_struct(0, "Constitution"); + } + if (((boolean)arg0)) { + return newstruct cs2func_script_993_struct(0, "Armour"); + } + if (arg0 == 2) { + return newstruct cs2func_script_993_struct(0, "Milestones"); + } + return newstruct cs2func_script_993_struct(-1, ""); +} diff --git a/dumps/scripts/994.cs2 b/dumps/scripts/994.cs2 new file mode 100644 index 0000000..ae8ed65 --- /dev/null +++ b/dumps/scripts/994.cs2 @@ -0,0 +1,78 @@ +cs2func_script_994_struct(2,2,0) script_994(int arg0,int arg1) { + switch (arg0) { + flow_1: + case 0: + switch (arg1) { + case 0: + return newstruct cs2func_script_994_struct(-1, 7620, "Your Constitution tells you how healthy your character can be. A character with low Constitution will only have a small number of life points when they're fully healed, whereas a character with high Constitution can have many more life points.", ""); + case 1: + return newstruct cs2func_script_994_struct(-1, 7620, "If you see any " + "" + "red 'hitsplats'" + "" + " during combat, the number shown corresponds to the number of life points lost as a result of that strike.", ""); + case 2: + return newstruct cs2func_script_994_struct(-1, 7620, "" + "Blue hitsplats" + "" + " mean no damage has been dealt.", ""); + case 3: + return newstruct cs2func_script_994_struct(-1, 7620, "" + "Green hitsplats" + "" + " are poison damage (members).", ""); + case 4: + return newstruct cs2func_script_994_struct(-1, 7620, "" + "Yellow hitsplats" + "" + " are disease damage (members).", ""); + case 5: + return newstruct cs2func_script_994_struct(-1, 7620, "" + "Pink hitsplats" + "" + " show life points restored through healing (while in Daemonheim).", ""); + } + break; + case 1: + switch (arg1) { + case 0: + return newstruct cs2func_script_994_struct(35, 14936, "Members: Agile top (with 35 Defence)", "Members now have the Constitution level required to wear " + "" + "agile tops" + "" + ". (They also need level 35 Defence.)"); + case 1: + return newstruct cs2func_script_994_struct(35, 14938, "Members: Agile legs (with 35 Defence)", "Members now have the Constitution level required to wear " + "" + "agile legs" + "" + ". (They also need level 35 Defence.)"); + case 2: + return newstruct cs2func_script_994_struct(42, 11665, "Members: Void melee helm", "Members now have the Constitution level required to wear " + "" + "Void melee helms" + "" + "."); + case 3: + return newstruct cs2func_script_994_struct(42, 11664, "Members: Void ranger helm", "Members now have the Constitution level required to wear " + "" + "Void ranger helms" + "" + "."); + case 4: + return newstruct cs2func_script_994_struct(42, 11663, "Members: Void mage helm", "Members now have the Constitution level required to wear " + "" + "Void mage helms" + "" + "."); + case 5: + return newstruct cs2func_script_994_struct(42, 8839, "Members: Void knight top", "Members now have the Constitution level required to wear " + "" + "Void knight tops" + "" + "."); + case 6: + return newstruct cs2func_script_994_struct(42, 8840, "Members: Void knight robe", "Members now have the Constitution level required to wear " + "" + "Void knight robes" + "" + "."); + case 7: + return newstruct cs2func_script_994_struct(42, 8842, "Members: Void knight gloves", "Members now have the Constitution level required to wear " + "" + "Void knight gloves" + "" + "."); + case 8: + return newstruct cs2func_script_994_struct(42, 19712, "Members: Void knight deflector", "Members now have the Constitution level required to wear " + "" + "Void knight deflectors" + "" + "."); + case 9: + return newstruct cs2func_script_994_struct(42, 8841, "Members: Void knight mace", "Members now have the Constitution level required to wield " + "" + "Void knight maces" + "" + "."); + case 10: + return newstruct cs2func_script_994_struct(42, 7620, "Void knight equipment requires 42 Attack, Defence, Strength, Ranged, Magic and Constitution and 22 Prayer.", "" + "Void knight equipment" + "" + " requires 42 Attack, Defence, Strength, Ranged, Magic and Constitution and 22 Prayer."); + case 11: + return newstruct cs2func_script_994_struct(80, 20135, "Members: Torva full helm" + "
" + " (with 80 Strength and Defence)", "Members can now wear " + "" + "torva full helms" + "" + ". (They also need level 80 Strength and Defence)"); + case 12: + return newstruct cs2func_script_994_struct(80, 20139, "Members: Torva platebody" + "
" + " (with 80 Strength and Defence)", "Members can now wear " + "" + "torva platebodies" + "" + ". (They also need level 80 Strength and Defence)"); + case 13: + return newstruct cs2func_script_994_struct(80, 20143, "Members: Torva platelegs" + "
" + " (with 80 Strength and Defence)", "Members can now wear " + "" + "torva platelegs" + "" + ". (They also need level 80 Strength and Defence)"); + case 14: + return newstruct cs2func_script_994_struct(80, 20159, "Members: Virtus mask" + "
" + " (with 80 Magic and Defence)", "Members can now wear " + "" + "virtus masks" + "" + ". (They also need level 80 Magic and Defence)"); + case 15: + return newstruct cs2func_script_994_struct(80, 20163, "Members: Virtus robe top" + "
" + " (with 80 Magic and Defence)", "Members can now wear " + "" + "virtus robe tops" + "" + ". (They also need level 80 Magic and Defence)"); + case 16: + return newstruct cs2func_script_994_struct(80, 20167, "Members: Virtus robe legs" + "
" + " (with 80 Magic and Defence)", "Members can now wear " + "" + "virtus robe legs" + "" + ". (They also need level 80 Magic and Defence)"); + case 17: + return newstruct cs2func_script_994_struct(80, 20147, "Members: Pernix cowl" + "
" + " (with 80 Ranged and Defence)", "Members can now wear " + "" + "pernix cowls" + "" + ". (They also need level 80 Ranged and Defence)"); + case 18: + return newstruct cs2func_script_994_struct(80, 20151, "Members: Pernix body" + "
" + " (with 80 Ranged and Defence)", "Members can now wear " + "" + "pernix bodies" + "" + ". (They also need level 80 Ranged and Defence)"); + case 19: + return newstruct cs2func_script_994_struct(80, 20155, "Members: Pernix chaps" + "
" + " (with 80 Ranged and Defence)", "Members can now wear " + "" + "pernix chaps" + "" + ". (They also need level 80 Ranged and Defence)"); + } + break; + case 2: + SWITCH (arg1) { + case 0: + GOTO flow_32 + case 1: + GOTO flow_33 + } + break; + flow_32: + return newstruct cs2func_script_994_struct(70, 8122, "Members: Zamorak's Fortress in the God Wars Dungeon", "Members can now access the " + "" + "Zamorak Fortress" + "" + " in the " + "" + "God Wars Dungeon" + "" + "."); + flow_33: + return newstruct cs2func_script_994_struct(99, 9768, "Skill mastery", "" + "Congratulations! You are now a master of " + "" + "Constitution" + "" + ". Members can visit " + "" + "Surgeon General Tafani" + "" + " at the " + "" + "Duel Arena Hospital" + "" + ". She has something special that is only available to true masters of the " + "" + "Constitution" + "" + " skill!"); + } + return newstruct cs2func_script_994_struct(0, -1, "", ""); +} diff --git a/dumps/scripts/995.cs2 b/dumps/scripts/995.cs2 new file mode 100644 index 0000000..8ba0db8 --- /dev/null +++ b/dumps/scripts/995.cs2 @@ -0,0 +1,27 @@ +cs2func_script_995_struct(1,1,0) script_995(int arg0) { + switch (arg0) { + case 0: + return newstruct cs2func_script_995_struct(0, "Normal Spells"); + case 1: + return newstruct cs2func_script_995_struct(1, "Ancient Magicks"); + case 2: + return newstruct cs2func_script_995_struct(1, "Lunar Spells"); + case 3: + return newstruct cs2func_script_995_struct(0, "Enchantment"); + case 4: + return newstruct cs2func_script_995_struct(0, "Armour"); + case 5: + return newstruct cs2func_script_995_struct(0, "Weapons"); + case 6: + return newstruct cs2func_script_995_struct(0, "Books and wands"); + case 7: + return newstruct cs2func_script_995_struct(1, "Salamanders"); + case 8: + return newstruct cs2func_script_995_struct(0, "Minigames"); + case 9: + return newstruct cs2func_script_995_struct(0, "Dungeoneering"); + case 10: + return newstruct cs2func_script_995_struct(0, "Milestones"); + } + return newstruct cs2func_script_995_struct(-1, ""); +} diff --git a/dumps/scripts/996.cs2 b/dumps/scripts/996.cs2 new file mode 100644 index 0000000..9d2aefd --- /dev/null +++ b/dumps/scripts/996.cs2 @@ -0,0 +1,624 @@ +cs2func_script_996_struct(2,2,0) script_996(int arg0,int arg1) { + switch (arg0) { + flow_1: + case 3: + switch (arg1) { + case 0: + return newstruct cs2func_script_996_struct(4, 9236, "Members: Opal-tipped bronze crossbow bolt", "Members can now enchant " + "" + "opal-tipped bronze crossbow bolts" + "" + "."); + case 1: + return newstruct cs2func_script_996_struct(7, 1607, "Sapphire items", "You can now enchant " + "" + "sapphire items" + "" + "."); + case 2: + return newstruct cs2func_script_996_struct(7, 9240, "Members: Sapphire-tipped mithril crossbow bolt", "Members can now enchant " + "" + "sapphire-tipped crossbow bolts" + "" + "."); + case 3: + return newstruct cs2func_script_996_struct(14, 9237, "Members: Jade-tipped blurite crossbow bolt", "Members can now enchant " + "" + "jade-tipped blurite crossbow bolts" + "" + "."); + case 4: + return newstruct cs2func_script_996_struct(24, 9238, "Members: Pearl-tipped iron crossbow bolt", "Members can now enchant " + "" + "pearl-tipped iron crossbow bolts" + "" + "."); + case 5: + return newstruct cs2func_script_996_struct(27, 1605, "Emerald items", "You can now enchant " + "" + "emerald items" + "" + "."); + case 6: + return newstruct cs2func_script_996_struct(27, 9241, "Members: Emerald-tipped mithril crossbow bolt", "Members can now enchant " + "" + "emerald-tipped mithril crossbow bolts" + "" + "."); + case 7: + return newstruct cs2func_script_996_struct(29, 9239, "Members: Red topaz-tipped steel crossbow bolt", "Members can now enchant " + "" + "red topaz-tipped steel crossbow bolts" + "" + "."); + case 8: + return newstruct cs2func_script_996_struct(49, 1603, "Ruby items", "You can now enchant " + "" + "ruby items" + "" + "."); + case 9: + return newstruct cs2func_script_996_struct(49, 9242, "Members: Ruby-tipped adamant crossbow bolt", "Members can now " + "" + "enchant ruby-tipped adamant crossbow bolts" + "" + "."); + case 10: + return newstruct cs2func_script_996_struct(56, 571, "Members: Charge water orbs", "Members can now charge " + "" + "water orbs" + "" + "."); + case 11: + return newstruct cs2func_script_996_struct(57, 1601, "Diamond items", "You can now enchant " + "" + "diamond items" + "" + "."); + case 12: + return newstruct cs2func_script_996_struct(57, 9243, "Members: Diamond-tipped adamant crossbow bolt", "Members can now enchant " + "" + "diamond-tipped adamant crossbow bolts" + "" + "."); + case 13: + return newstruct cs2func_script_996_struct(60, 575, "Members: Charge earth orbs", "Members can now charge " + "" + "earth orbs" + "" + "."); + case 14: + return newstruct cs2func_script_996_struct(63, 569, "Members: Charge fire orbs", "Members can now charge " + "" + "fire orbs" + "" + "."); + case 15: + return newstruct cs2func_script_996_struct(66, 573, "Members: Charge air orbs", "Members can now charge " + "" + "air orbs" + "" + "."); + case 16: + return newstruct cs2func_script_996_struct(68, 1615, "Members: Dragonstone items", "Members can now enchant " + "" + "dragonstone items" + "" + "."); + case 17: + return newstruct cs2func_script_996_struct(68, 9244, "Members: Dragonstone-tipped rune crossbow bolt", "Members can now enchant " + "" + "dragonstone-tipped rune crossbow bolts" + "" + "."); + case 18: + return newstruct cs2func_script_996_struct(87, 6573, "Members: Onyx items", "Members can now enchant " + "" + "onyx items" + "" + "."); + case 19: + return newstruct cs2func_script_996_struct(87, 9245, "Members: Onyx-tipped rune crossbow bolt", "Members can now enchant " + "" + "onyx-tipped rune crossbow bolts" + "" + "."); + } + break; + case 4: + switch (arg1) { + case 0: + return newstruct cs2func_script_996_struct(1, 3755, "Members: Farseer helm" + "
" + " (after Fremennik Trials and with 45 Defence)", "Members now have the Magic level required to wear " + "" + "farseer helms" + "" + " (after Fremennik Trials)."); + case 1: + return newstruct cs2func_script_996_struct(1, 6153, "Members: Skeletal gloves", "Members can now wear " + "" + "skeletal gloves" + "" + "."); + case 2: + return newstruct cs2func_script_996_struct(1, 6147, "Members: Skeletal boots", "Members can now wear " + "" + "skeletal boots" + "" + "."); + case 3: + return newstruct cs2func_script_996_struct(20, 2579, "Members: Wizard boots", "Members can now wear " + "" + "wizard boots."); + case 4: + return newstruct cs2func_script_996_struct(20, 12964, "Combat hood" + "
" + " (with level 10 Defence)", "You now have the Magic level required to wear " + "" + "combat hoods" + "" + ". (You also need level 10 Defence.)"); + case 5: + return newstruct cs2func_script_996_struct(20, 12971, "Combat robe top" + "
" + " (with level 10 Defence)", "You now have the Magic level required to wear " + "" + "combat robe tops" + "" + ". (You also need level 10 Defence.)"); + case 6: + return newstruct cs2func_script_996_struct(20, 12978, "Combat robe bottom" + "
" + " (with level 10 Defence)", "You now have the Magic level required to wear " + "" + "combat robe bottoms" + "" + ". (You also need level 10 Defence.)"); + case 7: + return newstruct cs2func_script_996_struct(20, 12887, "Druidic mage hood" + "
" + " (with level 10 Defence)", "You now have the Magic level required to wear " + "" + "druidic mage hoods" + "" + ". (You also need level 10 Defence.)"); + case 8: + return newstruct cs2func_script_996_struct(20, 12894, "Druidic mage top" + "
" + " (with level 10 Defence)", "You now have the Magic level required to wear " + "" + "druidic mage tops" + "" + ". (You also need level 10 Defence.)"); + case 9: + return newstruct cs2func_script_996_struct(20, 12901, "Druidic mage bottom" + "
" + " (with level 10 Defence)", "You now have the Magic level required to wear " + "" + "druidic mage bottoms" + "" + ". (You also need level 10 Defence.)"); + case 10: + return newstruct cs2func_script_996_struct(20, 13938, "Members: Corrupt Zuriel's hood" + "
" + " (with level 20 Defence)", "Members now have the Magic level required to wear " + "" + "corrupt Zuriel's hood" + "" + ". (They also need level 20 Defence.)"); + case 11: + return newstruct cs2func_script_996_struct(20, 13932, "Members: Corrupt Zuriel's robe top" + "
" + " (with level 20 Defence)", "Members now have the Magic level required to wear " + "" + "corrupt Zuriel's robe top" + "" + ". (They also need level 20 Defence.)"); + case 12: + return newstruct cs2func_script_996_struct(20, 13935, "Members: Corrupt Zuriel's robe bottom" + "
" + " (with level 20 Defence)", "Members now have the Magic level required to wear " + "" + "corrupt Zuriel's robe bottom" + "" + ". (They also need level 20 Defence.)"); + case 13: + return newstruct cs2func_script_996_struct(20, 15488, "Members: Hexcrest" + "
" + " (with 10 Defence)", "Members can now wear " + "" + "hexcrests" + "" + " (with 10 Defence)."); + case 14: + return newstruct cs2func_script_996_struct(20, 15492, "Members: Full Slayer helmet" + "
" + " (after Smoking Kills with 10 Defence, 20 Ranged and Strength)", "Members can now wear " + "" + "full slayer helmets" + "" + " (after Smoking Kills with 10 Defence, 20 Ranged and Strength)."); + case 15: + return newstruct cs2func_script_996_struct(20, 9733, "Members: Elemental mind equipment (After Elemental Workshop II and with level 30 Smithing)", "Members now have the Magic level required to wear " + "" + "Elemental mind equipment" + "" + ". (After Elemental Workshop II and with level 30 Smithing)"); + case 16: + return newstruct cs2func_script_996_struct(30, 18333, "Arcane pulse necklace" + "
" + " (with 30 Dungeoneering)", "You can now wear " + "" + "arcane pulse necklaces" + "" + ". (You also need level 30 Dungeoneering.)"); + case 17: + return newstruct cs2func_script_996_struct(40, 4089, "Members: Mystic hat" + "
" + " (with level 20 Defence)", "Members now have the Magic level required to wear " + "" + "mystic hats" + "" + ". (They also need level 20 Defence.)"); + case 18: + return newstruct cs2func_script_996_struct(40, 4091, "Members: Mystic robe top" + "
" + " (with level 20 Defence)", "Members now have the Magic level required to wear " + "" + "mystic robe tops" + "" + ". (They also need level 20 Defence.)"); + case 19: + return newstruct cs2func_script_996_struct(40, 4093, "Members: Mystic robe bottom" + "
" + " (with level 20 Defence)", "Members now have the Magic level required to wear " + "" + "mystic robe bottoms" + "" + ". (They also need level 20 Defence.)"); + case 20: + return newstruct cs2func_script_996_struct(40, 4095, "Members: Mystic gloves" + "
" + " (with level 20 Defence)", "Members now have the Magic level required to wear " + "" + "mystic gloves" + "" + ". (They also need level 20 Defence.)"); + case 21: + return newstruct cs2func_script_996_struct(40, 4097, "Members: Mystic boots" + "
" + " (with level 20 Defence)", "Members now have the Magic level required to wear " + "" + "mystic boots" + "" + ". (They also need level 20 Defence.)"); + case 22: + return newstruct cs2func_script_996_struct(40, 14499, "Members: Dagon'hai hat" + "
" + " (with level 20 Defence)", "Members now have the Magic level required to wear " + "" + "Dagon'hai hats" + "" + ". (They also need level 20 Defence.)"); + case 23: + return newstruct cs2func_script_996_struct(40, 14497, "Members: Dagon'hai robe top" + "
" + " (with level 20 Defence)", "Members now have the Magic level required to wear " + "" + "Dagon'hai robe tops" + "" + ". (They also need level 20 Defence.)"); + case 24: + return newstruct cs2func_script_996_struct(40, 14501, "Members: Dagon'hai robe bottom" + "
" + " (with level 20 Defence)", "Members now have the Magic level required to wear " + "" + "Dagon'hai robe bottoms" + "" + ". (They also need level 20 Defence.)"); + case 25: + return newstruct cs2func_script_996_struct(40, 21509, "Members: Necromancer hood" + "
" + " (with level 20 Defence)", "Members now have the Magic level required to wear " + "" + "Necromancer hoods" + "" + ". (They also need level 20 Defence.)"); + case 26: + return newstruct cs2func_script_996_struct(40, 21508, "Members: Necromancer robe" + "
" + " (with level 20 Defence)", "Members now have the Magic level required to wear " + "" + "Necromancer robes" + "" + ". (They also need level 20 Defence.)"); + case 27: + return newstruct cs2func_script_996_struct(40, 21510, "Members: Necromancer legs" + "
" + " (with level 20 Defence)", "Members now have the Magic level required to wear " + "" + "Necromancer legs" + "" + ". (They also need level 20 Defence.)"); + case 28: + return newstruct cs2func_script_996_struct(40, 7400, "Members: Enchanted hat" + "
" + " (with level 20 Defence)", "Members now have the Magic level required to wear " + "" + "enchanted hats" + "" + ". (They also need level 20 Defence.)"); + case 29: + return newstruct cs2func_script_996_struct(40, 7399, "Members: Enchanted top" + "
" + " (with level 20 Defence)", "Members now have the Magic level required to wear " + "" + "enchanted tops" + "" + ". (They also need level 20 Defence.)"); + case 30: + return newstruct cs2func_script_996_struct(40, 7398, "Members: Enchanted robe" + "
" + " (with level 20 Defence)", "Members now have the Magic level required to wear " + "" + "enchanted robes" + "" + ". (They also need level 20 Defence.)"); + case 31: + return newstruct cs2func_script_996_struct(40, 3385, "Members: Splitbark helm" + "
" + " (with level 40 Defence)", "Members now have the Magic level required to wear " + "" + "splitbark helms" + "" + ". (They also need level 40 Defence.)"); + case 32: + return newstruct cs2func_script_996_struct(40, 3387, "Members: Splitbark body" + "
" + " (with level 40 Defence)", "Members now have the Magic level required to wear " + "" + "splitbark bodies" + "" + ". (They also need level 40 Defence.)"); + case 33: + return newstruct cs2func_script_996_struct(40, 3389, "Members: Splitbark legs" + "
" + " (with level 40 Defence)", "Members now have the Magic level required to wear " + "" + "splitbark legs" + "" + ". (They also need level 40 Defence.)"); + case 34: + return newstruct cs2func_script_996_struct(40, 3391, "Members: Splitbark gauntlets" + "
" + " (with level 40 Defence)", "Members now have the Magic level required to wear " + "" + "splitbark gauntlets" + "" + ". (They also need level 40 Defence.)"); + case 35: + return newstruct cs2func_script_996_struct(40, 3393, "Members: Splitbark boots" + "
" + " (with level 40 Defence)", "Members now have the Magic level required to wear " + "" + "splitbark boots" + "" + ". (They also need level 40 Defence.)"); + case 36: + return newstruct cs2func_script_996_struct(40, 6137, "Members: Skeletal helmet" + "
" + " (after Fremennik Trials and with 40 Defence)", "Members now have the Magic level required to wear " + "" + "skeletal helmets" + "" + " (after Fremennik Trials and with level 40 Defence)."); + case 37: + return newstruct cs2func_script_996_struct(40, 6139, "Members: Skeletal top" + "
" + " (after Fremennik Trials and with 40 Defence)", "Members now have the Magic level required to wear " + "" + "skeletal tops" + "" + " (after Fremennik Trials and with level 40 Defence)."); + case 38: + return newstruct cs2func_script_996_struct(40, 6141, "Members: Skeletal bottoms" + "
" + " (after Fremennik Trials and with 40 Defence)", "Members now have the Magic level required to wear " + "" + "skeletal bottoms" + "" + " (after Fremennik Trials and with level 40 Defence)."); + case 39: + return newstruct cs2func_script_996_struct(40, 14116, "Members: Sacred clay hat" + "
" + " (with level 40 Defence)", "Members now have the Magic level required to wear " + "" + "sacred clay hats" + "" + ". (They also need level 40 Defence.)"); + case 40: + return newstruct cs2func_script_996_struct(40, 14114, "Members: Sacred clay robe top" + "
" + " (with level 40 Defence)", "Members now have the Magic level required to wear " + "" + "sacred clay robe tops" + "" + ". (They also need level 40 Defence.)"); + case 41: + return newstruct cs2func_script_996_struct(40, 14115, "Members: Sacred clay robe bottom" + "
" + " (with level 40 Defence)", "Members now have the Magic level required to wear " + "" + "sacred clay robe bottoms" + "" + ". (They also need level 40 Defence.)"); + case 42: + return newstruct cs2func_script_996_struct(40, 10454, "Members: Guthix mitre" + "
" + " (with 40 Prayer)", "Members now have the Magic level required to wear " + "" + "Guthix mitres" + "" + ". (They also need level 40 Prayer.)"); + case 43: + return newstruct cs2func_script_996_struct(40, 10452, "Members: Saradomin mitre" + "
" + " (with 40 Prayer)", "Members now have the Magic level required to wear " + "" + "Saradomin mitres" + "" + ". (They also need level 40 Prayer.)"); + case 44: + return newstruct cs2func_script_996_struct(40, 10456, "Members: Zamorak mitre" + "
" + " (with 40 Prayer)", "Members now have the Magic level required to wear " + "" + "Zamorak mitres" + "" + ". (They also need level 40 Prayer.)"); + case 45: + return newstruct cs2func_script_996_struct(40, 19374, "Members: Armadyl mitre" + "
" + " (with 40 Prayer)", "Members now have the Magic level required to wear " + "" + "Armadyl mitres" + "" + ". (They also need level 40 Prayer.)"); + case 46: + return newstruct cs2func_script_996_struct(40, 19376, "Members: Bandos mitre" + "
" + " (with 40 Prayer)", "Members now have the Magic level required to wear " + "" + "Bandos mitres" + "" + ". (They also need level 40 Prayer.)"); + case 47: + return newstruct cs2func_script_996_struct(40, 19378, "Members: Ancient mitre" + "
" + " (with 40 Prayer)", "Members now have the Magic level required to wear " + "" + "Ancient mitres" + "" + ". (They also need level 40 Prayer.)"); + case 48: + return newstruct cs2func_script_996_struct(42, 11665, "Members: Void melee helm", "Members now have the Magic level required to wear " + "" + "Void melee helms" + "" + "."); + case 49: + return newstruct cs2func_script_996_struct(42, 11664, "Members: Void ranger helm", "Members now have the Magic level required to wear " + "" + "Void ranger helms" + "" + "."); + case 50: + return newstruct cs2func_script_996_struct(42, 11663, "Members: Void mage helm", "Members now have the Magic level required to wear " + "" + "Void mage helms" + "" + "."); + case 51: + return newstruct cs2func_script_996_struct(42, 8839, "Members: Void knight top", "Members now have the Magic level required to wear " + "" + "Void knight tops" + "" + "."); + case 52: + return newstruct cs2func_script_996_struct(42, 8840, "Members: Void knight robe", "Members now have the Magic level required to wear " + "" + "Void knight robes" + "" + "."); + case 53: + return newstruct cs2func_script_996_struct(42, 8842, "Members: Void knight gloves", "Members now have the Magic level required to wear " + "" + "Void knight gloves" + "" + "."); + case 54: + return newstruct cs2func_script_996_struct(42, 19712, "Members: Void knight deflector", "Members now have the Magic level required to wear " + "" + "Void knight deflectors" + "" + "."); + case 55: + return newstruct cs2func_script_996_struct(42, 7620, "Void knight equipment requires 42 Attack, Defence, Strength, Ranged, Magic and Constitution and 22 Prayer.", "" + "Void knight equipment" + "" + " requires 42 Attack, Defence, Strength, Ranged, Magic and Constitution and 22 Prayer."); + case 56: + return newstruct cs2func_script_996_struct(50, 6918, "Members: Infinity hat" + "
" + " (with level 25 Defence)", "Members now have the Magic level required to wear " + "" + "infinity hats" + "" + ". (They also need level 25 Defence.)"); + case 57: + return newstruct cs2func_script_996_struct(50, 6916, "Members: Infinity top" + "
" + " (with level 25 Defence)", "Members now have the Magic level required to wear " + "" + "infinity tops" + "" + ". (They also need level 25 Defence.)"); + case 58: + return newstruct cs2func_script_996_struct(50, 6924, "Members: Infinity bottom" + "
" + " (with level 25 Defence)", "Members now have the Magic level required to wear " + "" + "infinity bottoms" + "" + ". (They also need level 25 Defence.)"); + case 59: + return newstruct cs2func_script_996_struct(50, 6920, "Members: Infinity boots" + "
" + " (with level 25 Defence)", "Members now have the Magic level required to wear " + "" + "infinity boots" + "" + ". (They also need level 25 Defence.)"); + case 60: + return newstruct cs2func_script_996_struct(50, 6922, "Members: Infinity gloves" + "
" + " (with level 25 Defence)", "Members now have the Magic level required to wear " + "" + "infinity gloves" + "" + ". (They also need level 25 Defence.)"); + case 61: + return newstruct cs2func_script_996_struct(50, 18334, "Arcane blast necklace" + "
" + " (with 50 Dungeoneering)", "You can now wear " + "" + "arcane blast necklaces" + "" + ". (You also need level 50 Dungeoneering.)"); + case 62: + return newstruct cs2func_script_996_struct(60, 2413, "Members: Guthix cape", "Members can now wear " + "" + "Guthix capes."); + case 63: + return newstruct cs2func_script_996_struct(60, 2412, "Members: Saradomin cape", "Members can now wear " + "" + "Saradomin capes."); + case 64: + return newstruct cs2func_script_996_struct(60, 2414, "Members: Zamorak cape", "Members can now wear " + "" + "Zamorak capes."); + case 65: + return newstruct cs2func_script_996_struct(60, 12866, "Members: Battle hood" + "
" + " (with level 50 Defence)", "Members now have the Magic level required to wear " + "" + "battle hoods" + "" + ". (They also need level 50 Defence.)"); + case 66: + return newstruct cs2func_script_996_struct(60, 12873, "Members: Battle robe top" + "
" + " (with level 50 Defence)", "Members now have the Magic level required to wear " + "" + "battle robe tops" + "" + ". (They also need level 50 Defence.)"); + case 67: + return newstruct cs2func_script_996_struct(60, 12880, "Members: Battle robe bottom" + "
" + " (with level 50 Defence)", "Members now have the Magic level required to wear " + "" + "battle robe bottoms" + "" + ". (They also need level 50 Defence.)"); + case 68: + return newstruct cs2func_script_996_struct(65, 10342, "Members: Third-Age mage hat" + "
" + " (with level 30 Defence)", "Members now have the Magic level required to wear " + "" + "Third-Age mage hats" + "" + ". (They also need level 30 Defence)"); + case 69: + return newstruct cs2func_script_996_struct(65, 10338, "Members: Third-Age robe top" + "
" + " (with level 30 Defence)", "Members now have the Magic level required to wear " + "" + "Third-Age robe tops" + "" + ". (They also need level 30 Defence)"); + case 70: + return newstruct cs2func_script_996_struct(65, 10340, "Members: Third-Age robe" + "
" + " (with level 30 Defence)", "Members now have the Magic level required to wear " + "" + "Third-Age robes" + "" + ". (They also need level 30 Defence)"); + case 71: + return newstruct cs2func_script_996_struct(65, 10344, "Members: Third-Age amulet" + "
" + " (with level 30 Defence)", "Members now have the Magic level required to wear " + "" + "Third-Age amulets" + "" + ". (They also need level 30 Defence)"); + case 72: + return newstruct cs2func_script_996_struct(65, 9096, "Members: Lunar helm" + "
" + " (with level 40 Defence)", "Members now have the Magic level required to wear " + "" + "lunar helms" + "" + ". (They also need level 40 Defence.)"); + case 73: + return newstruct cs2func_script_996_struct(65, 9097, "Members: Lunar torso" + "
" + " (with level 40 Defence)", "Members now have the Magic level required to wear " + "" + "lunar torsos" + "" + ". (They also need level 40 Defence.)"); + case 74: + return newstruct cs2func_script_996_struct(65, 9099, "Members: Lunar gloves" + "
" + " (with level 40 Defence)", "Members now have the Magic level required to wear " + "" + "lunar gloves" + "" + ". (They also need level 40 Defence.)"); + case 75: + return newstruct cs2func_script_996_struct(65, 9098, "Members: Lunar legs" + "
" + " (with level 40 Defence)", "Members now have the Magic level required to wear " + "" + "lunar legs" + "" + ". (They also need level 40 Defence.)"); + case 76: + return newstruct cs2func_script_996_struct(65, 9100, "Members: Lunar boots" + "
" + " (with level 40 Defence)", "Members now have the Magic level required to wear " + "" + "lunar boots" + "" + ". (They also need level 40 Defence.)"); + case 77: + return newstruct cs2func_script_996_struct(65, 9101, "Members: Lunar cape" + "
" + " (with level 40 Defence)", "Members now have the Magic level required to wear " + "" + "lunar capes" + "" + ". (They also need level 40 Defence.)"); + case 78: + return newstruct cs2func_script_996_struct(65, 13738, "Members: Arcane spirit shield" + "
" + " (after Summer's End and with 70 Prayer and 75 Defence)", "Members now have the Magic level required to wield " + "" + "arcane spirit shields" + "" + " (after Summer's End, with level 70 Prayer and 75 Defence)."); + case 79: + return newstruct cs2func_script_996_struct(65, 13744, "Members: Spectral spirit shield" + "
" + " (after Summer's End and with 70 Prayer and 75 Defence)", "Members now have the Magic level required to wield " + "" + "spectral spirit shields" + "" + " (after Summer's End, with level 70 Prayer and 75 Defence)."); + case 80: + return newstruct cs2func_script_996_struct(70, 4708, "Members: Ahrim's hood" + "
" + " (with level 70 Defence)", "Members now have the Magic level required to wear " + "" + "Ahrim's hood" + "" + ". (They also need level 70 Defence.)"); + case 81: + return newstruct cs2func_script_996_struct(70, 4712, "Members: Ahrim's robe top" + "
" + " (with level 70 Defence)", "Members now have the Magic level required to wear " + "" + "Ahrim's robe top" + "" + ". (They also need level 70 Defence.)"); + case 82: + return newstruct cs2func_script_996_struct(70, 4714, "Members: Ahrim's robe skirt" + "
" + " (with level 70 Defence)", "Members now have the Magic level required to wear " + "" + "Ahrim's robe skirt" + "" + ". (They also need level 70 Defence.)"); + case 83: + return newstruct cs2func_script_996_struct(70, 21736, "Members: Akrisae's hood" + "
" + " (after Ritual of the Mahjarrat and with level 70 Defence and 70 Prayer)", "Members now have the Magic level required to wear " + "" + "Akrisae's hood" + "" + " (after Ritual of the Mahjarrat and with level 70 Defence and 70 Prayer)."); + case 84: + return newstruct cs2func_script_996_struct(70, 21752, "Members: Akrisae's robe top" + "
" + " (after Ritual of the Mahjarrat and with level 70 Defence and 70 Prayer)", "Members now have the Magic level required to wear " + "" + "Akrisae's robe top" + "" + " (after Ritual of the Mahjarrat and with level 70 Defence and 70 Prayer)."); + case 85: + return newstruct cs2func_script_996_struct(70, 21760, "Members: Akrisae's robe skirt" + "
" + " (after Ritual of the Mahjarrat and with level 70 Defence and 70 Prayer)", "Members now have the Magic level required to wear " + "" + "Akrisae's robe skirt" + "" + " (after Ritual of the Mahjarrat and with level 70 Defence and 70 Prayer)."); + case 86: + return newstruct cs2func_script_996_struct(70, 18335, "Members: Arcane stream necklace" + "
" + " (with 70 Dungeoneering)", "Members can now wear " + "" + "arcane stream necklaces" + "" + ". (They also need level 70 Dungeoneering.)"); + case 87: + return newstruct cs2func_script_996_struct(75, 21793, "Members: Ragefire boots" + "
" + " (with 75 Defence)", "Members now have the Magic level required to wear " + "" + "ragefire boots" + "" + " (with 75 Defence)."); + case 88: + return newstruct cs2func_script_996_struct(78, 13864, "Members: Zuriel's hood" + "
" + " (with level 78 Defence)", "Members now have the Magic level required to wear " + "" + "Zuriel's hood" + "" + ". (They also need level 78 Defence.)"); + case 89: + return newstruct cs2func_script_996_struct(78, 13858, "Members: Zuriel's robe top" + "
" + " (with level 78 Defence)", "Members now have the Magic level required to wear " + "" + "Zuriel's robe top" + "" + ". (They also need level 78 Defence.)"); + case 90: + return newstruct cs2func_script_996_struct(78, 13861, "Members: Zuriel's robe bottom" + "
" + " (with level 78 Defence)", "Members now have the Magic level required to wear " + "" + "Zuriel's robe bottom" + "" + ". (They also need level 78 Defence.)"); + case 91: + return newstruct cs2func_script_996_struct(80, 20159, "Members: Virtus mask" + "
" + " (with 80 Defence and Constitution)", "Members can now wear " + "" + "virtus masks" + "" + ". (They also need level 80 Defence and Constitution.)"); + case 92: + return newstruct cs2func_script_996_struct(80, 20163, "Members: Virtus robe top" + "
" + " (with 80 Defence and Constitution)", "Members can now wear " + "" + "virtus robe tops" + "" + ". (They also need level 80 Defence and Constitution.)"); + case 93: + return newstruct cs2func_script_996_struct(80, 20167, "Members: Virtus robe legs" + "
" + " (with 80 Defence and Constitution)", "Members can now wear " + "" + "virtus robe legs" + "" + ". (They also need level 80 Defence and Constitution.)"); + } + break; + case 5: + switch (arg1) { + case 0: + return newstruct cs2func_script_996_struct(1, 1379, "Staff", "You can now wield " + "" + "staves" + "" + "."); + case 1: + return newstruct cs2func_script_996_struct(1, 15598, "Caitlin's staff" + "
" + " (after The Blood Pact)", "You can now wield " + "" + "Caitlin's staff" + "" + " (after The Blood Pact)."); + case 2: + return newstruct cs2func_script_996_struct(1, 1389, "Magic staff", "You can now wield " + "" + "staves of magic" + "" + "."); + case 3: + return newstruct cs2func_script_996_struct(1, 1381, "Staff of air", "You can now wield " + "" + "staves of air" + "" + "."); + case 4: + return newstruct cs2func_script_996_struct(1, 1385, "Staff of earth", "You can now wield " + "" + "staves of earth" + "" + "."); + case 5: + return newstruct cs2func_script_996_struct(1, 1387, "Staff of fire", "You can now wield " + "" + "staves of fires" + "" + "."); + case 6: + return newstruct cs2func_script_996_struct(1, 1383, "Staff of water", "You can now wield " + "" + "staves of water" + "" + "."); + case 7: + return newstruct cs2func_script_996_struct(1, 21490, "Skeletal staves", "You can now wield " + "" + "skeletal staves" + "" + "."); + case 8: + return newstruct cs2func_script_996_struct(20, 13941, "Members: Corrupt Zuriel's staff" + "
" + " (with level 20 Attack)", "Members now have the Magic level required to use " + "" + "Corrupt Zuriel's staff" + "" + ". (They also need level 20 Attack.)"); + case 9: + return newstruct cs2func_script_996_struct(30, 1397, "Members: Air battlestaff" + "
" + " (with level 30 Attack)", "Members now have the Magic level required to use " + "" + "air battlestaves" + "" + ". (They also need level 30 Attack.)"); + case 10: + return newstruct cs2func_script_996_struct(30, 1399, "Members: Earth battlestaff" + "
" + " (with level 30 Attack)", "Members now have the Magic level required to use " + "" + "earth battlestaves" + "" + ". (They also need level 30 Attack.)"); + case 11: + return newstruct cs2func_script_996_struct(30, 1393, "Members: Fire battlestaff" + "
" + " (with level 30 Attack)", "Members now have the Magic level required to use " + "" + "fire battlestaves" + "" + ". (They also need level 30 Attack.)"); + case 12: + return newstruct cs2func_script_996_struct(30, 1395, "Members: Water battlestaff" + "
" + " (with level 30 Attack)", "Members now have the Magic level required to use " + "" + "water battlestaves" + "" + ". (They also need level 30 Attack.)"); + case 13: + return newstruct cs2func_script_996_struct(30, 3053, "Members: Lava battlestaff" + "
" + " (with level 30 Attack)", "Members now have the Magic level required to use " + "" + "lava battlestaves" + "" + ". (They also need level 30 Attack.)"); + case 14: + return newstruct cs2func_script_996_struct(30, 6562, "Members: Mud battlestaff" + "
" + " (with level 30 Attack)", "Members now have the Magic level required to use " + "" + "mud battlestaves" + "" + ". (They also need level 30 Attack.)"); + case 15: + return newstruct cs2func_script_996_struct(30, 11736, "Members: Steam battlestaff" + "
" + " (with level 30 Attack)", "Members now have the Magic level required to use " + "" + "steam battlestaves" + "" + ". (They also need level 30 Attack.)"); + case 16: + return newstruct cs2func_script_996_struct(30, 21502, "Members: Skeletal battlestaves" + "
" + " (with level 30 Attack)", "Members now have the Magic level required to use " + "" + "skeletal battlestaves" + "" + ". (They also need level 30 Attack.)"); + case 17: + return newstruct cs2func_script_996_struct(30, 21536, "Members: Sceptre of the gods" + "
" + " (with level 30 Attack)", "Members now have the Magic level required to use " + "" + "the sceptre of the gods" + "" + ". (They also need level 30 Attack.)"); + case 18: + return newstruct cs2func_script_996_struct(40, 1405, "Members: Mystic air staff" + "
" + " (with level 40 Attack)", "Members now have the Magic level required to use " + "" + "mystic air staves" + "" + ". (They also need level 40 Attack.)"); + case 19: + return newstruct cs2func_script_996_struct(40, 1407, "Members: Mystic earth staff" + "
" + " (with level 40 Attack)", "Members now have the Magic level required to use " + "" + "mystic earth staves" + "" + ". (They also need level 40 Attack.)"); + case 20: + return newstruct cs2func_script_996_struct(40, 1401, "Members: Mystic fire staff" + "
" + " (with level 40 Attack)", "Members now have the Magic level required to use " + "" + "mystic fire staves" + "" + ". (They also need level 40 Attack.)"); + case 21: + return newstruct cs2func_script_996_struct(40, 1403, "Members: Mystic water staff" + "
" + " (with level 40 Attack)", "Members now have the Magic level required to use " + "" + "mystic water staves" + "" + ". (They also need level 40 Attack.)"); + case 22: + return newstruct cs2func_script_996_struct(40, 3054, "Members: Mystic lava staff" + "
" + " (with level 40 Attack)", "Members now have the Magic level required to use " + "" + "mystic lava staves" + "" + ". (They also need level 40 Attack.)"); + case 23: + return newstruct cs2func_script_996_struct(40, 6563, "Members: Mystic mud staff" + "
" + " (with level 40 Attack)", "Members now have the Magic level required to use " + "" + "mystic mud staves" + "" + ". (They also need level 40 Attack.)"); + case 24: + return newstruct cs2func_script_996_struct(40, 11738, "Members: Mystic steam staff" + "
" + " (with level 40 Attack)", "Members now have the Magic level required to use " + "" + "mystic steam staves" + "" + ". (They also need level 40 Attack.)"); + case 25: + return newstruct cs2func_script_996_struct(40, 19323, "Members: Dragon staff" + "
" + " (with 40 Attack, 60 Prayer and 20 Defence)", "Members now have the Magic level required to wield " + "" + "dragon staves" + "" + ". (They also need level 40 Attack, level 60 Prayer and level 20 Defence.)"); + case 26: + return newstruct cs2func_script_996_struct(40, 19325, "Members: Penguin staff" + "
" + " (with 40 Attack, 60 Prayer and 20 Defence)", "Members now have the Magic level required to wield " + "" + "penguin staves" + "" + ". (They also need level 40 Attack, level 60 Prayer and level 20 Defence.)"); + case 27: + return newstruct cs2func_script_996_struct(40, 19327, "Members: Bat staff" + "
" + " (with 40 Attack, 60 Prayer and 20 Defence)", "Members now have the Magic level required to wield " + "" + "bat staves" + "" + ". (They also need level 40 Attack, level 60 Prayer and level 20 Defence.)"); + case 28: + return newstruct cs2func_script_996_struct(40, 19329, "Members: Wolf staff" + "
" + " (with 40 Attack, 60 Prayer and 20 Defence)", "Members now have the Magic level required to wield " + "" + "wolf staves" + "" + ". (They also need level 40 Attack, level 60 Prayer and level 20 Defence.)"); + case 29: + return newstruct cs2func_script_996_struct(40, 19331, "Members: Cat staff" + "
" + " (with 40 Attack, 60 Prayer and 20 Defence)", "Members now have the Magic level required to wield " + "" + "cat staves" + "" + ". (They also need level 40 Attack, level 60 Prayer and level 20 Defence.)"); + case 30: + return newstruct cs2func_script_996_struct(40, 14117, "Members: Sacred clay staff", "Members can now wield " + "" + "sacred clay staves" + "" + "."); + case 31: + return newstruct cs2func_script_996_struct(40, 21498, "Members: Necromancer staves" + "
" + " (with level 40 Attack)", "Members now have the Magic level required to use " + "" + "necromancer staves" + "" + ". (They also need level 40 Attack.)"); + case 32: + return newstruct cs2func_script_996_struct(42, 8841, "Members: Void knight mace", "Members now have the Magic level required to wield " + "" + "Void knight maces" + "" + "."); + case 33: + return newstruct cs2func_script_996_struct(45, 18342, "Law staff" + "
" + " (with 40 Attack and 45 Dungeoneering)", "You can now use " + "" + "law staves" + "" + ". (You also need level 40 Attack and level 45 Dungeoneering.)"); + case 34: + return newstruct cs2func_script_996_struct(45, 18371, "Gravite staff" + "
" + " (with 45 Dungeoneering)", "You can now wield " + "" + "gravite staves" + "" + ". (You also need level 45 Dungeoneering.)"); + case 35: + return newstruct cs2func_script_996_struct(50, 4170, "Members: Slayer's staff" + "
" + " (with level 55 Slayer)", "Members now have the Magic level required to use " + "" + "Slayer staves" + "" + ", magic weapons used for killing turoth and kurask. (They also need level 55 Slayer.)"); + case 36: + return newstruct cs2func_script_996_struct(50, 1409, "Members: Iban's Staff" + "
" + " (after Underground Pass and with 50 Attack)", "Members now have the Magic level required to use " + "" + "Iban's Staff" + "" + " (after Underground Pass and with 50 Attack)."); + case 37: + return newstruct cs2func_script_996_struct(50, 4675, "Members: Ancient Staff" + "
" + " (after Desert Treasure, with 50 Attack)", "Members now have the Magic level required to use the " + "" + "Ancient Staff" + "" + " (after Desert Treasure and with 50 Attack)."); + case 38: + return newstruct cs2func_script_996_struct(53, 18341, "Nature staff" + "
" + " (with 40 Attack and 53 Dungeoneering)", "You can now use " + "" + "nature staves" + "" + ". (You also need level 40 Attack and level 53 Dungeoneering.)"); + case 39: + return newstruct cs2func_script_996_struct(60, 2415, "Members: Saradomin staff", "Members can now use " + "" + "Saradomin staves" + "" + "."); + case 40: + return newstruct cs2func_script_996_struct(60, 2416, "Members: Guthix staff", "Members can now use the " + "" + "Guthix staves" + "" + "."); + case 41: + return newstruct cs2func_script_996_struct(60, 2417, "Members: Zamorak staff", "Members can now use the " + "" + "Zamorak staves" + "" + "."); + case 42: + return newstruct cs2func_script_996_struct(60, 6526, "Members: Toktz-Mej-Tal" + "
" + " (with level 60 Attack)", "Members now have the Magic level required to use " + "" + "Toktz-Mej-Tal" + "" + ". (They also need level 60 Attack.)"); + case 43: + return newstruct cs2func_script_996_struct(70, 15438, "Members: Penance Trident", "Members now have the Magic level required to use the " + "" + "Penance Trident" + "" + "."); + case 44: + return newstruct cs2func_script_996_struct(70, 15485, "Members: Penance Master Trident" + "
" + " (with level 70 Attack)", "Members now have the Magic level required to use the " + "" + "Penance Master Trident" + "" + ". (They also need level 70 Attack.)"); + case 45: + return newstruct cs2func_script_996_struct(70, 4710, "Members: Ahrim's staff" + "
" + " (with level 70 Attack)", "Members now have the Magic level required to use " + "" + "Ahrim's staff" + "" + ". (They also need level 70 Attack.)"); + case 46: + return newstruct cs2func_script_996_struct(70, 21744, "Members: Akrisae's war mace" + "
" + " (after Ritual of the Mahjarrat and with level 70 Attack and level 70 Prayer)", "Members now have the Magic level required to wield " + "" + "Akrisae's war mace" + "" + " (after Ritual of the Mahjarrat with level 70 Defence and 70 Prayer.)"); + case 47: + return newstruct cs2func_script_996_struct(70, 21580, "Members: Blisterwood staff (after The Branches of Darkmeyer)", "Members now have the Magic level required to use " + "" + "blisterwood staves" + "" + " (after The Branches of Darkmeyer.)"); + case 48: + return newstruct cs2func_script_996_struct(75, 15486, "Members: Staff of Light (with 75 Attack)", "Members can now wield the " + "" + "Staff of Light" + "" + " (with 75 Attack)."); + case 49: + return newstruct cs2func_script_996_struct(77, 21777, "Members: Armadyl battlestaff" + "
" + " (with level 40 Attack)", "Members now have the Magic level required to use " + "" + "Armadyl battlestaves" + "" + ". (They also need level 40 Attack.)"); + case 50: + return newstruct cs2func_script_996_struct(78, 13867, "Members: Zuriel's staff" + "
" + " (with level 78 Attack)", "Members now have the Magic level required to use " + "" + "Zuriel's staff" + "" + ". (They also need level 78 Attack.)"); + case 51: + return newstruct cs2func_script_996_struct(80, 18355, "Members: Chaotic staff" + "
" + " (with 80 Dungeoneering)", "Members can now wield " + "" + "chaotic staves" + "" + ". (They also need level 80 Dungeoneering.)"); + } + break; + case 6: + switch (arg1) { + case 0: + return newstruct cs2func_script_996_struct(35, 19671, " Magical blastbox" + "
" + " (with 30 Dungeoneering and 30 Runecrafting)", "You can now use " + "" + "magical blastboxes" + "" + ". (You also need level 30 Dungeoneering and 30 Runecrafting.)"); + case 1: + return newstruct cs2func_script_996_struct(45, 6908, "Members: Beginner wand", "Members can now use " + "" + "beginner wands" + "" + "."); + case 2: + return newstruct cs2func_script_996_struct(48, 18346, "Tome of frost" + "
" + " (with 48 Dungeoneering)", "You can now use " + "" + "tomes of frost" + "" + ". (You also need level 48 Dungeoneering.)"); + case 3: + return newstruct cs2func_script_996_struct(50, 6910, "Members: Apprentice wand", "Members can now use " + "" + "apprentice wands" + "" + "."); + case 4: + return newstruct cs2func_script_996_struct(55, 6912, "Members: Teacher wand", "Members can now use " + "" + "teacher wands" + "" + "."); + case 5: + return newstruct cs2func_script_996_struct(60, 6914, "Members: Master wand", "Members can now use " + "" + "master wands" + "" + "."); + case 6: + return newstruct cs2func_script_996_struct(60, 6889, "Members: Mage's book", "Members can now use " + "" + "mages' books" + "" + "."); + case 7: + return newstruct cs2func_script_996_struct(70, 19889, "Members: Celestial surgebox" + "
" + " (with 70 Dungeoneering and 70 Runecrafting)", "Members can now use " + "" + "celestial surgeboxes" + "" + ". (They also need level 70 Dungeoneering and level 70 Runecrafting.)"); + } + break; + case 7: + switch (arg1) { + case 0: + return newstruct cs2func_script_996_struct(30, 10149, "Members: Swamp lizard" + "
" + " (with level 30 Attack and 30 Ranged)", "Members now have the Magic level required to wield " + "" + "swamp lizards" + "" + ". (They also need level 30 Attack and level 30 Ranged.)"); + case 1: + return newstruct cs2func_script_996_struct(50, 10146, "Members: Orange salamander" + "
" + " (with level 50 Attack and 50 Ranged)", "Members now have the Magic level required to wield " + "" + "orange salamanders" + "" + ". (They also need level 50 Attack and 50 Ranged.)"); + case 2: + return newstruct cs2func_script_996_struct(60, 10147, "Members: Red salamander" + "
" + " (with level 60 Attack and 60 Ranged)", "Members now have the Magic level required to wield " + "" + "red salamanders" + "" + ". (They also need level 60 Attack and 60 Ranged.)"); + case 3: + return newstruct cs2func_script_996_struct(70, 10148, "Members: Black salamander" + "
" + " (with level 70 Attack and 70 Ranged)", "Members now have the Magic level required to wield " + "" + "black salamanders" + "" + ". (They also need level 70 Attack and 70 Ranged.)"); + } + break; + case 8: + switch (arg1) { + case 0: + return newstruct cs2func_script_996_struct(1, 14377, "Members: Stealing Creation - class 1 staff", "Members can now wield " + "" + "class 1 staves" + "" + " in Stealing Creation."); + case 1: + return newstruct cs2func_script_996_struct(1, 14337, "Members: Stealing Creation - class 1 hat", "Members can now wear " + "" + "class 1 hats" + "" + " in Stealing Creation."); + case 2: + return newstruct cs2func_script_996_struct(1, 14317, "Members: Stealing Creation - class 1 robe top", "Members can now wear " + "" + "class 1 robe tops" + "" + " in Stealing Creation."); + case 3: + return newstruct cs2func_script_996_struct(1, 14327, "Members: Stealing Creation - class 1 robe bottom", "Members can now wear " + "" + "class 1 robe bottoms" + "" + " in Stealing Creation."); + case 4: + return newstruct cs2func_script_996_struct(20, 14379, "Members: Stealing Creation - class 2 staff", "Members can now wield " + "" + "class 2 staves" + "" + " in Stealing Creation."); + case 5: + return newstruct cs2func_script_996_struct(20, 14339, "Members: Stealing Creation - class 2 hat", "Members can now wear " + "" + "class 2 hats" + "" + " in Stealing Creation."); + case 6: + return newstruct cs2func_script_996_struct(20, 14319, "Members: Stealing Creation - class 2 robe top", "Members can now wear " + "" + "class 2 robe tops" + "" + " in Stealing Creation."); + case 7: + return newstruct cs2func_script_996_struct(20, 14329, "Members: Stealing Creation - class 2 robe bottom", "Members can now wear " + "" + "class 2 robe bottoms" + "" + " in Stealing Creation."); + case 8: + return newstruct cs2func_script_996_struct(40, 14381, "Members: Stealing Creation - class 3 staff", "Members can now wield " + "" + "class 3 staves" + "" + " in Stealing Creation."); + case 9: + return newstruct cs2func_script_996_struct(40, 14341, "Members: Stealing Creation - class 3 hat", "Members can now wear " + "" + "class 3 hats" + "" + " in Stealing Creation."); + case 10: + return newstruct cs2func_script_996_struct(40, 14321, "Members: Stealing Creation - class 3 robe top", "Members can now wear " + "" + "class 3 robe tops" + "" + " in Stealing Creation."); + case 11: + return newstruct cs2func_script_996_struct(40, 14331, "Members: Stealing Creation - class 3 robe bottom", "Members can now wear " + "" + "class 3 robe bottoms" + "" + " in Stealing Creation."); + case 12: + return newstruct cs2func_script_996_struct(60, 14383, "Members: Stealing Creation - class 4 staff", "Members can now wield " + "" + "class 4 staves" + "" + " in Stealing Creation."); + case 13: + return newstruct cs2func_script_996_struct(60, 14343, "Members: Stealing Creation - class 4 hat", "Members can now wear " + "" + "class 4 hats" + "" + " in Stealing Creation."); + case 14: + return newstruct cs2func_script_996_struct(60, 14323, "Members: Stealing Creation - class 4 robe top", "Members can now wear " + "" + "class 4 robe tops" + "" + " in Stealing Creation."); + case 15: + return newstruct cs2func_script_996_struct(60, 14333, "Members: Stealing Creation - class 4 robe bottom", "Members can now wear " + "" + "class 4 robe bottoms" + "" + " in Stealing Creation."); + case 16: + return newstruct cs2func_script_996_struct(80, 14385, "Members: Stealing Creation - class 5 staff", "Members can now wield " + "" + "class 5 staves" + "" + " in Stealing Creation."); + case 17: + return newstruct cs2func_script_996_struct(80, 14345, "Members: Stealing Creation - class 5 hat", "Members can now wear " + "" + "class 5 hats" + "" + " in Stealing Creation."); + case 18: + return newstruct cs2func_script_996_struct(80, 14325, "Members: Stealing Creation - class 5 robe top", "Members can now wear " + "" + "class 5 robe tops" + "" + " in Stealing Creation."); + case 19: + return newstruct cs2func_script_996_struct(80, 14335, "Members: Stealing Creation - class 5 robe bottom", "Members can now wear " + "" + "class 5 robe bottoms" + "" + " in Stealing Creation."); + case 20: + return newstruct cs2func_script_996_struct(85, 21537, "Members: Battle-mage helm" + "
" + " (with 85 Defence and 85 Strength)", "Members now have the magic level require to wear " + "" + "Battle-mage helms" + "" + ". They also need level 85 Defence and level 85 Strength."); + case 21: + return newstruct cs2func_script_996_struct(85, 21539, "Members: Battle-mage robe" + "
" + " (with 85 Defence and 85 Strength)", "Members now have the magic level require to wear " + "" + "Battle-mage robes" + "" + ". They also need level 85 Defence and level 85 Strength."); + case 22: + return newstruct cs2func_script_996_struct(85, 21541, "Members: Battle-mage legs" + "
" + " (with 85 Defence and 85 Strength)", "Members now have the magic level require to wear " + "" + "Battle-mage legs" + "" + ". They also need level 85 Defence and level 85 Strength."); + case 23: + return newstruct cs2func_script_996_struct(85, 21543, "Members: Battle-mage gloves" + "
" + " (with 85 Defence and 85 Strength)", "Members now have the magic level require to wear " + "" + "Battle-mage gloves" + "" + ". They also need level 85 Defence and level 85 Strength."); + case 24: + return newstruct cs2func_script_996_struct(85, 21545, "Members: Battle-mage boots" + "
" + " (with 85 Defence and 85 Strength)", "Members now have the magic level require to wear " + "" + "Battle-mage boots" + "" + ". They also need level 85 Defence and level 85 Strength."); + case 25: + return newstruct cs2func_script_996_struct(85, 21547, "Members: Trickster hood" + "
" + " (with 85 Defence and 85 Ranged)", "Members now have the magic level require to wear " + "" + "Trickster hoods" + "" + ". They also need level 85 Defence and level 85 Ranged"); + case 26: + return newstruct cs2func_script_996_struct(85, 21549, "Members: Trickster robe" + "
" + " (with 85 Defence and 85 Ranged)", "Members now have the magic level require to wear " + "" + "Trickster robes" + "" + ". They also need level 85 Defence and level 85 Ranged"); + case 27: + return newstruct cs2func_script_996_struct(85, 21551, "Members: Trickster legs" + "
" + " (with 85 Defence and 85 Ranged)", "Members now have the magic level require to wear " + "" + "Trickster legs" + "" + ". They also need level 85 Defence and level 85 Ranged"); + case 28: + return newstruct cs2func_script_996_struct(85, 21553, "Members: Trickster gloves" + "
" + " (with 85 Defence and 85 Ranged)", "Members now have the magic level require to wear " + "" + "Trickster gloves" + "" + ". They also need level 85 Defence and level 85 Ranged"); + case 29: + return newstruct cs2func_script_996_struct(85, 21555, "Members: Trickster boots" + "
" + " (with 85 Defence and 85 Ranged)", "Members now have the magic level require to wear " + "" + "Trickster boots" + "" + ". They also need level 85 Defence and level 85 Ranged"); + } + break; + case 9: + switch (arg1) { + case 0: + return newstruct cs2func_script_996_struct(-1, 15707, "Dungeoneering skill tasks" + "
" + "As your Magic level increases, you will be able to attempt higher-level magic tasks within Daemonheim. You will also be more likely to succeed when attempting magic tasks within Daemonheim.", ""); + case 1: + return newstruct cs2func_script_996_struct(1, 16977, "Basic staves (all tiers)", "You can now wield " + "" + "basic staves" + "" + " within Daemonheim."); + case 2: + return newstruct cs2func_script_996_struct(1, 16997, "Water staff", "You can now wield " + "" + "water staves" + "" + " within Daemonheim."); + case 3: + return newstruct cs2func_script_996_struct(1, 16735, "Salve hood (Tier 1)" + "
" + " (with 1 Defence)", "You can now wear " + "" + "salve hoods" + "" + " within Daemonheim. (You also need level 1 Defence.)"); + case 4: + return newstruct cs2func_script_996_struct(1, 17217, "Salve robe top (Tier 1)" + "
" + " (with 1 Defence)", "You can now wear " + "" + "salve robe tops" + "" + " within Daemonheim. (You also need level 1 Defence.)"); + case 5: + return newstruct cs2func_script_996_struct(1, 16845, "Salve robe bottom (Tier 1)" + "
" + " (with 1 Defence)", "You can now wear " + "" + "salve robe bottoms" + "" + " within Daemonheim. (You also need level 1 Defence.)"); + case 6: + return newstruct cs2func_script_996_struct(1, 17151, "Salve gloves (Tier 1)" + "
" + " (with 1 Defence)", "You can now wear " + "" + "salve gloves" + "" + " within Daemonheim. (You also need level 1 Defence.)"); + case 7: + return newstruct cs2func_script_996_struct(1, 16911, "Salve boots (Tier 1)" + "
" + " (with 1 Defence)", "You can now wear " + "" + "salve boots" + "" + " within Daemonheim. (You also need level 1 Defence.)"); + case 8: + return newstruct cs2func_script_996_struct(10, 17001, "Earth staff", "You can now wield " + "" + "earth staves" + "" + " within Daemonheim."); + case 9: + return newstruct cs2func_script_996_struct(10, 16737, "Wildercress hood (Tier 2)" + "
" + " (with 10 Defence)", "You can now wear " + "" + "wildercress hoods" + "" + " within Daemonheim. (You also need level 10 Defence.)"); + case 10: + return newstruct cs2func_script_996_struct(10, 17219, "Wildercress robe top (Tier 2)" + "
" + " (with 10 Defence)", "You can now wear " + "" + "wildercress robe tops" + "" + " within Daemonheim. (You also need level 10 Defence.)"); + case 11: + return newstruct cs2func_script_996_struct(10, 16847, "Wildercress robe bottom (Tier 2)" + "
" + " (with 10 Defence)", "You can now wear " + "" + "wildercress robe bottoms" + "" + " within Daemonheim. (You also need level 10 Defence.)"); + case 12: + return newstruct cs2func_script_996_struct(10, 17153, "Wildercress gloves (Tier 2)" + "
" + " (with 10 Defence)", "You can now wear " + "" + "wildercress gloves" + "" + " within Daemonheim. (You also need level 10 Defence.)"); + case 13: + return newstruct cs2func_script_996_struct(10, 16913, "Wildercress boots (Tier 2)" + "
" + " (with 10 Defence)", "You can now wear " + "" + "wildercress boots" + "" + " within Daemonheim. (You also need level 10 Defence.)"); + case 14: + return newstruct cs2func_script_996_struct(20, 17005, "Fire staff", "You can now wield " + "" + "fire staves" + "" + " within Daemonheim."); + case 15: + return newstruct cs2func_script_996_struct(20, 16739, "Blightleaf hood (Tier 3)" + "
" + " (with 20 Defence)", "You can now wear " + "" + "blightleaf hoods" + "" + " within Daemonheim. (You also need level 20 Defence.)"); + case 16: + return newstruct cs2func_script_996_struct(20, 17221, "Blightleaf robe top (Tier 3)" + "
" + " (with 20 Defence)", "You can now wear " + "" + "blightleaf robe tops" + "" + " within Daemonheim. (You also need level 20 Defence.)"); + case 17: + return newstruct cs2func_script_996_struct(20, 16849, "Blightleaf robe bottom (Tier 3)" + "
" + " (with 20 Defence)", "You can now wear " + "" + "blightleaf robe bottoms" + "" + " within Daemonheim. (You also need level 20 Defence.)"); + case 18: + return newstruct cs2func_script_996_struct(20, 17155, "Blightleaf gloves (Tier 3)" + "
" + " (with 20 Defence)", "You can now wear " + "" + "blightleaf gloves" + "" + " within Daemonheim. (You also need level 20 Defence.)"); + case 19: + return newstruct cs2func_script_996_struct(20, 16915, "Blightleaf boots (Tier 3)" + "
" + " (with 20 Defence)", "You can now wear " + "" + "blightleaf boots" + "" + " within Daemonheim. (You also need level 20 Defence.)"); + case 20: + return newstruct cs2func_script_996_struct(30, 17009, "Air staff", "You can now wield " + "" + "air staves" + "" + " within Daemonheim."); + case 21: + return newstruct cs2func_script_996_struct(30, 16741, "Roseblood hood (Tier 4)" + "
" + " (with 30 Defence)", "You can now wear " + "" + "roseblood hoods" + "" + " within Daemonheim. (You also need level 30 Defence.)"); + case 22: + return newstruct cs2func_script_996_struct(30, 17223, "Roseblood robe top (Tier 4)" + "
" + " (with 30 Defence)", "You can now wear " + "" + "roseblood robe tops" + "" + " within Daemonheim. (You also need level 30 Defence.)"); + case 23: + return newstruct cs2func_script_996_struct(30, 16851, "Roseblood robe bottom (Tier 4)" + "
" + " (with 30 Defence)", "You can now wear " + "" + "roseblood robe bottoms" + "" + " within Daemonheim. (You also need level 30 Defence.)"); + case 24: + return newstruct cs2func_script_996_struct(30, 17157, "Roseblood gloves (Tier 4)" + "
" + " (with 30 Defence)", "You can now wear " + "" + "roseblood gloves" + "" + " within Daemonheim. (You also need level 30 Defence.)"); + case 25: + return newstruct cs2func_script_996_struct(30, 16917, "Roseblood boots (Tier 4)" + "
" + " (with 30 Defence)", "You can now wear " + "" + "roseblood boots" + "" + " within Daemonheim. (You also need level 30 Defence.)"); + case 26: + return newstruct cs2func_script_996_struct(32, 18637, "Spell: Create Gatestone", "You can now cast " + "" + "Create Gatestone" + "" + " within Daemonheim."); + case 27: + return newstruct cs2func_script_996_struct(32, 18638, "Spell: Gatestone Teleport", "You can now cast " + "" + "Gatestone Teleport" + "" + " within Daemonheim."); + case 28: + return newstruct cs2func_script_996_struct(33, 17273, "Members: Flameburst defender" + "
" + " (with 33 Defence)", "Members can now wield " + "" + "flameburst defenders" + "" + " within Daemonheim. (They also need level 33 Defence.)"); + case 29: + return newstruct cs2func_script_996_struct(36, 17275, "Members: Frostbite dagger" + "
" + " (with 36 Attack)", "Members can now wield " + "" + "frostbite daggers" + "" + " within Daemonheim. (They also need level 36 Attack.)"); + case 30: + return newstruct cs2func_script_996_struct(40, 17013, "Catalytic staff", "You can now wield " + "" + "catalytic staves" + "" + " within Daemonheim."); + case 31: + return newstruct cs2func_script_996_struct(40, 16743, "Bryll hood (Tier 5)" + "
" + " (with 40 Defence)", "You can now wear " + "" + "bryll hoods" + "" + " within Daemonheim. (You also need level 40 Defence.)"); + case 32: + return newstruct cs2func_script_996_struct(40, 17225, "Bryll robe top (Tier 5)" + "
" + " (with 40 Defence)", "You can now wear " + "" + "bryll robe tops" + "" + " within Daemonheim. (You also need level 40 Defence.)"); + case 33: + return newstruct cs2func_script_996_struct(40, 16853, "Bryll robe bottom (Tier 5)" + "
" + " (with 40 Defence)", "You can now wear " + "" + "bryll robe bottoms" + "" + " within Daemonheim. (You also need level 40 Defence.)"); + case 34: + return newstruct cs2func_script_996_struct(40, 17159, "Bryll gloves (Tier 5)" + "
" + " (with 40 Defence)", "You can now wear " + "" + "bryll gloves" + "" + " within Daemonheim. (You also need level 40 Defence.)"); + case 35: + return newstruct cs2func_script_996_struct(40, 16919, "Bryll boots (Tier 5)" + "
" + " (with 40 Defence)", "You can now wear " + "" + "bryll boots" + "" + " within Daemonheim. (You also need level 40 Defence.)"); + case 36: + return newstruct cs2func_script_996_struct(50, 16999, "Members: Empowered water staff", "Members can now wield " + "" + "empowered water staves" + "" + " within Daemonheim."); + case 37: + return newstruct cs2func_script_996_struct(50, 16745, "Members: Duskweed hood (Tier 6)" + "
" + " (with 50 Defence)", "Members can now wear " + "" + "duskweed hoods" + "" + " within Daemonheim. (They also need level 50 Defence.)"); + case 38: + return newstruct cs2func_script_996_struct(50, 17227, "Members: Duskweed robe top (Tier 6)" + "
" + " (with 50 Defence)", "Members can now wear " + "" + "duskweed robe tops" + "" + " within Daemonheim. (They also need level 50 Defence.)"); + case 39: + return newstruct cs2func_script_996_struct(50, 16855, "Members: Duskweed robe bottom (Tier 6)" + "
" + " (with 50 Defence)", "Members can now wear " + "" + "duskweed robe bottoms" + "" + " within Daemonheim. (They also need level 50 Defence.)"); + case 40: + return newstruct cs2func_script_996_struct(50, 17161, "Members: Duskweed gloves (Tier 6)" + "
" + " (with 50 Defence)", "Members can now wear " + "" + "duskweed gloves" + "" + " within Daemonheim. (They also need level 50 Defence.)"); + case 41: + return newstruct cs2func_script_996_struct(50, 16921, "Members: Duskweed boots (Tier 6)" + "
" + " (with 50 Defence)", "Members can now wear " + "" + "duskweed boots" + "" + " within Daemonheim. (They also need level 50 Defence.)"); + case 42: + return newstruct cs2func_script_996_struct(60, 17003, "Members: Empowered earth staff", "Members can now wield " + "" + "empowered earth staves" + "" + " within Daemonheim."); + case 43: + return newstruct cs2func_script_996_struct(60, 16747, "Members: Soulbell hood (Tier 7)" + "
" + " (with 60 Defence)", "Members can now wear " + "" + "soulbell hoods" + "" + " within Daemonheim. (You also need level 60 Defence)."); + case 44: + return newstruct cs2func_script_996_struct(60, 17229, "Members: Soulbell robe top (Tier 7)" + "
" + " (with 60 Defence)", "Members can now wear " + "" + "soulbell robe tops" + "" + " within Daemonheim. (They also need level 60 Defence.)"); + case 45: + return newstruct cs2func_script_996_struct(60, 16857, "Members: Soulbell robe bottom (Tier 7)" + "
" + " (with 60 Defence)", "Members can now wear " + "" + "soulbell robe bottoms" + "" + " within Daemonheim. (They also need level 60 Defence.)"); + case 46: + return newstruct cs2func_script_996_struct(60, 17163, "Members: Soulbell gloves (Tier 7)" + "
" + " (with 60 Defence)", "Members can now wear " + "" + "soulbell gloves" + "" + " within Daemonheim. (They also need level 60 Defence.)"); + case 47: + return newstruct cs2func_script_996_struct(60, 16923, "Members: Soulbell boots (Tier 7)" + "
" + " (with 60 Defence)", "Members can now wear " + "" + "soulbell boots" + "" + " within Daemonheim. (They also need level 60 Defence.)"); + case 48: + return newstruct cs2func_script_996_struct(68, 17275, "Members: Hailstorm dagger" + "
" + " (with 68 Attack)", "Members can now wield " + "" + "hailstorm daggers" + "" + " within Daemonheim. (They also need level 68 Attack.)"); + case 49: + return newstruct cs2func_script_996_struct(68, 17293, "Members: Doomcore staff" + "
" + " (with 68 Attack)", "Members can now wield " + "" + "doomcore staves" + "" + " within Daemonheim. (They also need level 68 Attack.)"); + case 50: + return newstruct cs2func_script_996_struct(70, 17007, "Members: Empowered fire staff", "Members can now wield " + "" + "empowered fire staves" + "" + " within Daemonheim."); + case 51: + return newstruct cs2func_script_996_struct(70, 16749, "Members: Ectohood (Tier 8)" + "
" + " (with 70 Defence)", "Members can now wear " + "" + "ectohoods" + "" + " within Daemonheim. (They also need level 70 Defence.)"); + case 52: + return newstruct cs2func_script_996_struct(70, 17231, "Members: Ectorobe top (Tier 8)" + "
" + " (with 70 Defence)", "Members can now wear " + "" + "ectorobe tops" + "" + " within Daemonheim. (They also need level 70 Defence.)"); + case 53: + return newstruct cs2func_script_996_struct(70, 16859, "Members: Ectorobe bottom (Tier 8)" + "
" + " (with 70 Defence)", "Members can now wear " + "" + "ectorobe bottoms" + "" + " within Daemonheim. (They also need level 70 Defence.)"); + case 54: + return newstruct cs2func_script_996_struct(70, 17165, "Members: Ectogloves (Tier 8)" + "
" + " (with 70 Defence)", "Members can now wear " + "" + "ectogloves" + "" + " within Daemonheim. (They also need level 70 Defence.)"); + case 55: + return newstruct cs2func_script_996_struct(70, 16925, "Members: Ectoboots (Tier 8)" + "
" + " (with 70 Defence)", "Members can now wear " + "" + "ectoboots" + "" + " within Daemonheim. (They also need level 70 Defence.)"); + case 56: + return newstruct cs2func_script_996_struct(80, 17011, "Members: Empowered air staff", "Members can now wield " + "" + "empowered air staves" + "" + " within Daemonheim."); + case 57: + return newstruct cs2func_script_996_struct(80, 16751, "Members: Runic hood (Tier 9)" + "
" + " (with 80 Defence)", "Members can now wear " + "" + "runic hoods" + "" + " within Daemonheim. (They also need level 80 Defence.)"); + case 58: + return newstruct cs2func_script_996_struct(80, 17233, "Members: Runic robe top (Tier 9)" + "
" + " (with 80 Defence)", "Members can now wear " + "" + "runic robe tops" + "" + " within Daemonheim. (They also need level 80 Defence.)"); + case 59: + return newstruct cs2func_script_996_struct(80, 16861, "Members: Runic robe bottom (Tier 9)" + "
" + " (with 80 Defence)", "Members can now wear " + "" + "runic robe bottoms" + "" + " within Daemonheim. (They also need level 80 Defence.)"); + case 60: + return newstruct cs2func_script_996_struct(80, 17167, "Members: Runic gloves (Tier 9)" + "
" + " (with 80 Defence)", "Members can now wear " + "" + "runic gloves" + "" + " within Daemonheim. (They also need level 80 Defence.)"); + case 61: + return newstruct cs2func_script_996_struct(80, 16927, "Members: Runic boots (Tier 9)" + "
" + " (with 80 Defence)", "Members can now wear " + "" + "runic boots" + "" + " within Daemonheim. (They also need level 80 Defence.)"); + case 62: + return newstruct cs2func_script_996_struct(83, 17293, "Members: Doomcore staff", "Members can now wield " + "" + "doomcore staves" + "" + " within Daemonheim."); + case 63: + return newstruct cs2func_script_996_struct(90, 17015, "Members: Empowered catalytic staff", "Members can now wield " + "" + "empowered catalytic staves" + "" + " within Daemonheim."); + case 64: + return newstruct cs2func_script_996_struct(90, 16753, "Members: Spiritbloom hood (Tier 10)" + "
" + " (with 90 Defence)", "Members can now wear " + "" + "spiritbloom hoods" + "" + " within Daemonheim. (They also need level 90 Defence.)"); + case 65: + return newstruct cs2func_script_996_struct(90, 17235, "Members: Spiritbloom robe top (Tier 10)" + "
" + " (with 90 Defence)", "Members can now wear " + "" + "spiritbloom robe tops" + "" + " within Daemonheim. (They also need level 90 Defence.)"); + case 66: + return newstruct cs2func_script_996_struct(90, 16863, "Members: Spiritbloom robe bottom (Tier 10)" + "
" + " (with 90 Defence)", "Members can now wear " + "" + "spiritbloom robe bottoms" + "" + " within Daemonheim. (They also need level 90 Defence.)"); + case 67: + return newstruct cs2func_script_996_struct(90, 17169, "Members: Spiritbloom gloves (Tier 10)" + "
" + " (with 90 Defence)", "Members can now wear " + "" + "spiritbloom gloves" + "" + " within Daemonheim. (They also need level 90 Defence.)"); + case 68: + return newstruct cs2func_script_996_struct(90, 16929, "Members: Spiritbloom boots (Tier 10)" + "
" + " (with 90 Defence)", "Members can now wear " + "" + "spiritbloom boots" + "" + " within Daemonheim. (They also need level 90 Defence.)"); + case 69: + return newstruct cs2func_script_996_struct(99, 17015, "Members: Celestial catalytic staff", "Members can now wield " + "" + "celestial catalytic staves" + "" + " within Daemonheim."); + case 70: + return newstruct cs2func_script_996_struct(99, 16755, "Members: Celestial hood (Tier 11)" + "
" + " (with 99 Defence)", "Members can now wear " + "" + "celestial hoods" + "" + " within Daemonheim. (They also need level 99 Defence.)"); + case 71: + return newstruct cs2func_script_996_struct(99, 17237, "Members: Celestial robe top (Tier 11)" + "
" + " (with 99 Defence)", "Members can now wear " + "" + "celestial robe tops" + "" + " within Daemonheim. (They also need level 99 Defence.)"); + case 72: + return newstruct cs2func_script_996_struct(99, 16865, "Members: Celestial robe bottom (Tier 11)" + "
" + " (with 99 Defence)", "Members can now wear " + "" + "celestial robe bottoms" + "" + " within Daemonheim. (They also need level 99 Defence.)"); + case 73: + return newstruct cs2func_script_996_struct(99, 17171, "Members: Celestial gloves (Tier 11)" + "
" + " (with 99 Defence)", "Members can now wear " + "" + "celestial gloves" + "" + " within Daemonheim. (They also need level 99 Defence.)"); + case 74: + return newstruct cs2func_script_996_struct(99, 16931, "Members: Celestial boots (Tier 11)" + "
" + " (with 99 Defence)", "Members can now wear " + "" + "celestial boots" + "" + " within Daemonheim. (They also need level 99 Defence.)"); + } + break; + case 10: + SWITCH (arg1) { + case 0: + GOTO flow_299 + case 1: + GOTO flow_300 + case 2: + GOTO flow_301 + case 3: + GOTO flow_302 + case 4: + GOTO flow_303 + } + break; + flow_299: + return newstruct cs2func_script_996_struct(1, 1907, "Wizard's Mind Bomb" + "
" + " will temporarily increase your Magic level by 2 levels.", "" + "Wizard's Mind Bomb" + "" + " will now temporarily increase your Magic level by " + "" + "2 levels" + "" + "."); + flow_300: + return newstruct cs2func_script_996_struct(50, 1907, "Wizard's Mind Bomb" + "
" + " will temporarily increase your Magic level by 3 levels.", "" + "Wizard's Mind Bomb" + "" + " will now temporarily increase your Magic level by " + "" + "3 levels" + "" + "."); + flow_301: + return newstruct cs2func_script_996_struct(66, 4675, "Members: Magic Guild", "Members can now enter the " + "" + "Wizard's Guild" + "" + "."); + flow_302: + return newstruct cs2func_script_996_struct(70, 20704, "Members: access to the Livid Farm (with 60 Agility, 60 Crafting, 60 Farming, 50 Construction and Lunar Diplomacy)", "Members can access the " + "" + "Livid Farm" + "" + " (with 60 Farming, 60 Agility, 60 Crafting, 50 Construction and Lunar Diplomacy)."); + flow_303: + return newstruct cs2func_script_996_struct(99, 9762, "Skill mastery", "" + "Congratulations! You are now a master of " + "" + "Magic" + "" + ". Members can visit the " + "" + "robe store" + "" + " in the " + "" + "Wizards' Guild" + "" + ". They have something special that is only available to true masters of the " + "" + "Magic" + "" + " skill!"); + } + return newstruct cs2func_script_996_struct(0, -1, "", ""); +} diff --git a/dumps/scripts/997.cs2 b/dumps/scripts/997.cs2 new file mode 100644 index 0000000..42dacb9 --- /dev/null +++ b/dumps/scripts/997.cs2 @@ -0,0 +1,21 @@ +cs2func_script_997_struct(1,1,0) script_997(int arg0) { + switch (arg0) { + case 0: + return newstruct cs2func_script_997_struct(0, "Techniques"); + case 1: + return newstruct cs2func_script_997_struct(0, "Catches"); + case 2: + return newstruct cs2func_script_997_struct(1, "Barbarian"); + case 3: + return newstruct cs2func_script_997_struct(1, "Multiple Catch"); + case 4: + return newstruct cs2func_script_997_struct(0, "Other"); + case 5: + return newstruct cs2func_script_997_struct(1, "Minigames"); + case 6: + return newstruct cs2func_script_997_struct(0, "Dungeoneering"); + case 7: + return newstruct cs2func_script_997_struct(0, "Milestones"); + } + return newstruct cs2func_script_997_struct(-1, ""); +} diff --git a/dumps/scripts/998.cs2 b/dumps/scripts/998.cs2 new file mode 100644 index 0000000..98b6122 --- /dev/null +++ b/dumps/scripts/998.cs2 @@ -0,0 +1,212 @@ +cs2func_script_998_struct(2,2,0) script_998(int arg0,int arg1) { + switch (arg0) { + flow_1: + case 0: + switch (arg1) { + case 0: + return newstruct cs2func_script_998_struct(1, 303, "Small net", "You can now fish with a " + "" + "small net" + "" + "."); + case 1: + return newstruct cs2func_script_998_struct(1, 13431, "Crayfish cage", "You can now fish with a " + "" + "crayfish cage" + "" + "."); + case 2: + return newstruct cs2func_script_998_struct(5, 307, "Bait fishing", "You can now fish with " + "" + "fishing rods" + "" + " and bait" + "" + "."); + case 3: + return newstruct cs2func_script_998_struct(16, 305, "Members: Big net", "Members can now fish with " + "" + "big nets" + "" + "."); + case 4: + return newstruct cs2func_script_998_struct(20, 309, "Fly fishing rod", "You can now fish with " + "" + "fly fishing rods" + "" + " and " + "" + "feathers" + "" + "."); + case 5: + return newstruct cs2func_script_998_struct(35, 311, "Harpoon", "You can now fish with " + "" + "harpoons" + "" + "."); + case 6: + return newstruct cs2func_script_998_struct(40, 301, "Lobster pot", "You can now fish with " + "" + "lobster pots" + "" + "."); + case 7: + return newstruct cs2func_script_998_struct(40, 14109, "Members: Sacred clay harpoon", "Members can now use " + "" + "sacred clay harpoons" + "" + "."); + case 8: + return newstruct cs2func_script_998_struct(40, 14101, "Members: Volatile harpoon", "Members can now use " + "" + "volatile harpoons" + "" + "."); + case 9: + return newstruct cs2func_script_998_struct(48, 11323, "Members: Heavy rod" + "
" + " (with 15 Agility and 15 Strength)", "Members who are versed in the art of barbarian fishing now have the Fishing level required to fish with " + "" + "heavy rods" + "" + ". (They also need level 15 Agility and level 15 Strength.)"); + case 10: + return newstruct cs2func_script_998_struct(65, 3157, "Members: Vessel fishing" + "
" + " (after starting Tai Bwo Wannai Trio)", "Members now have the Fishing level required to use " + "" + "karambwan vessels" + "" + " to fish for " + "" + "karambwan" + "" + " (after starting Tai Bwo Wannai Trio)."); + case 11: + return newstruct cs2func_script_998_struct(65, 12860, "Swordfish gloves", "You can now wear " + "" + "swordfish gloves" + "" + "."); + case 12: + return newstruct cs2func_script_998_struct(70, 20891, "Members: Small cast net (after completing Deadliest Catch)", "You can now fish with " + "" + "small cast nets" + "" + " (after completing Deadliest Catch)."); + case 13: + return newstruct cs2func_script_998_struct(70, 20892, "Members: Big cast net (after completing Deadliest Catch)", "Members can now fish with " + "" + "big cast nets" + "" + " (after completing Deadliest Catch)."); + case 14: + return newstruct cs2func_script_998_struct(90, 12861, "Members: Shark gloves", "Members can now wear " + "" + "shark gloves" + "" + "."); + } + break; + case 1: + switch (arg1) { + case 0: + return newstruct cs2func_script_998_struct(1, 317, "Shrimp - Net fishing", "You can now catch " + "" + "shrimp" + "" + " with a net."); + case 1: + return newstruct cs2func_script_998_struct(1, 13435, "Crayfish - Crayfish cage", "You can now catch " + "" + "crayfish" + "" + " with a crayfish cage."); + case 2: + return newstruct cs2func_script_998_struct(5, 327, "Sardine - Sea bait fishing", "You can now catch " + "" + "sardines" + "" + " with a fishing rod."); + case 3: + return newstruct cs2func_script_998_struct(5, 3150, "Members: Karambwanji - Net fishing", "Members can now catch " + "" + "karabwanji" + "" + " with a net."); + case 4: + return newstruct cs2func_script_998_struct(10, 345, "Herring - Sea bait fishing", "You can now catch " + "" + "herring" + "" + " with a fishing rod."); + case 5: + return newstruct cs2func_script_998_struct(15, 321, "Anchovies - Net fishing", "You can now catch " + "" + "anchovies" + "" + " with a net."); + case 6: + return newstruct cs2func_script_998_struct(16, 353, "Members: Mackerel - Big net fishing", "Members can now catch " + "" + "mackerel" + "" + " with a big net."); + case 7: + return newstruct cs2func_script_998_struct(16, 407, "Members: Oyster - Big net fishing", "Members can now catch " + "" + "oysters" + "" + " with a big net."); + case 8: + return newstruct cs2func_script_998_struct(16, 405, "Members: Casket - Big net fishing", "Members can now catch " + "" + "caskets" + "" + " with a big net."); + case 9: + return newstruct cs2func_script_998_struct(16, 401, "Members: Seaweed - Big net fishing", "Members can now catch " + "" + "seaweed" + "" + " with a big net."); + case 10: + return newstruct cs2func_script_998_struct(20, 335, "Trout - Fly-fishing", "You can now catch " + "" + "trout" + "" + " with a fly-fishing rod."); + case 11: + return newstruct cs2func_script_998_struct(23, 341, "Members: Cod - Big net fishing", "Members can now catch " + "" + "cod" + "" + " with a big net."); + case 12: + return newstruct cs2func_script_998_struct(25, 349, "Pike - River bait fishing", "You can now catch " + "" + "pike" + "" + " with a fishing rod."); + case 13: + return newstruct cs2func_script_998_struct(28, 3379, "Members: Slimy eel - River bait fishing", "Members can now catch " + "" + "slimy eels" + "" + " with a fishing rod."); + case 14: + return newstruct cs2func_script_998_struct(30, 331, "Salmon - Fly-fishing", "You can now catch " + "" + "salmon" + "" + " with a fly-fishing rod."); + case 15: + return newstruct cs2func_script_998_struct(33, 5004, "Members: Giant frogspawn - Net fishing", "Members can now catch " + "" + "giant frogspawn" + "" + " with a net."); + case 16: + return newstruct cs2func_script_998_struct(35, 359, "Tuna - Harpoon fishing", "You can now catch " + "" + "tuna" + "" + " with a harpoon."); + case 17: + return newstruct cs2func_script_998_struct(38, 10138, "Members: Rainbow fish - Stripy fly-fishing", "Members can now catch " + "" + "rainbow fish" + "" + " with a fly-fishing rod."); + case 18: + return newstruct cs2func_script_998_struct(38, 5001, "Members: Cave eel - River bait fishing", "Members can now catch " + "" + "cave eels" + "" + " with a fishing rod."); + case 19: + return newstruct cs2func_script_998_struct(40, 377, "Lobster - Lobster pot fishing", "You can now catch " + "" + "lobsters" + "" + " with a lobster pot."); + case 20: + return newstruct cs2func_script_998_struct(46, 363, "Members: Bass - Big net fishing", "Members can now catch " + "" + "bass" + "" + " with a big net."); + case 21: + return newstruct cs2func_script_998_struct(50, 371, "Swordfish - Harpoon fishing", "You can now catch " + "" + "swordfish" + "" + " with a harpoon."); + case 22: + return newstruct cs2func_script_998_struct(53, 2148, "Members: Lava eel - Bait fishing (oily fishing rod)", "Members can now catch " + "" + "lava eels" + "" + " with an oily fishing rod."); + case 23: + return newstruct cs2func_script_998_struct(62, 7944, "Members: Monkfish - Net fishing", "Members can now catch " + "" + "monkfish" + "" + " with a net."); + case 24: + return newstruct cs2func_script_998_struct(65, 3142, "Members: Karambwan - Vessel fishing", "Members can now catch " + "" + "karambwan" + "" + " with a karambwan vessel in Karamja."); + case 25: + return newstruct cs2func_script_998_struct(76, 383, "Members: Shark - Harpoon fishing", "Members can now catch " + "" + "sharks" + "" + " with a harpoon."); + case 26: + return newstruct cs2func_script_998_struct(79, 395, "Members: Sea turtle - Fishing Trawler", "Members can now catch " + "" + "sea turtles" + "" + " in Fishing Trawler."); + case 27: + return newstruct cs2func_script_998_struct(81, 389, "Members: Manta ray - Fishing Trawler", "Members can now catch " + "" + "manta rays" + "" + " in Fishing Trawler."); + case 28: + return newstruct cs2func_script_998_struct(85, 15264, "Members: Cavefish - Cave bait fishing", "Members can now catch " + "" + "cavefish" + "" + " with a fishing rod."); + case 29: + return newstruct cs2func_script_998_struct(90, 15270, "Members: Rocktail - Living minerals cave bait fishing", "Members can now catch " + "" + "rocktails" + "" + " with a fishing rod."); + case 30: + return newstruct cs2func_script_998_struct(95, 21520, "Members: Tiger shark - Fishing Trawler", "Members can now catch " + "" + "tiger sharks" + "" + " in Fishing Trawler."); + } + break; + case 2: + switch (arg1) { + case 0: + return newstruct cs2func_script_998_struct(-1, 7620, "To start fishing like a barbarian, talk to Otto Godblessed when you have at least level 48 Fishing, level 15 Agility and level 15 Strength.", ""); + case 1: + return newstruct cs2func_script_998_struct(48, 11328, "Members: Leaping trout" + "
" + " (with 15 Strength and 15 Agility)", "Members who are versed in the art of barbarian fishing now have the Fishing level required to catch " + "" + "leaping trout" + "" + " with a heavy rod. (They also need level 15 Agility and level 15 Strength.)"); + case 2: + return newstruct cs2func_script_998_struct(55, 359, "Members: Tuna" + "
" + " (with 35 Strength)", "Members who are versed in the art of barbarian fishing now have the Fishing level required to catch " + "" + "tuna" + "" + " without a harpoon. (They also need level 35 Strength.)"); + case 3: + return newstruct cs2func_script_998_struct(55, 359, "Members: Possibility of catching two tuna in one fishing attempt" + "
" + " (with 35 Strength and 35 Agility)", "Members who are versed in the art of barbarian fishing now have the Fishing level required to potentially catch two " + "" + "tuna" + "" + " in one attempt without a harpoon. (They also need level 35 Strength and 35 Agility.)"); + case 4: + return newstruct cs2func_script_998_struct(58, 11330, "Members: Leaping salmon" + "
" + " (with 30 Strength and 30 Agility)", "Members who are versed in the art of barbarian fishing now have the Fishing level required to catch " + "" + "leaping salmon" + "" + " with a heavy rod. (They also need level 30 Agility and level 30 Strength.)"); + case 5: + return newstruct cs2func_script_998_struct(70, 371, "Members: Swordfish" + "
" + " (with 50 Strength)", "Members who are versed in the art of barbarian fishing now have the Fishing level required to catch " + "" + "swordfish" + "" + " without a harpoon. (They also need level 50 Strength.)"); + case 6: + return newstruct cs2func_script_998_struct(70, 371, "Members: Possibility of catching two swordfish in one fishing attempt" + "
" + " (with 50 Strength and 50 Agility)", "Members who are versed in the art of barbarian fishing now have the Fishing level required to catch two " + "" + "swordfish" + "" + " without a harpoon. (They also need level 50 Strength and 50 Agility.)"); + case 7: + return newstruct cs2func_script_998_struct(70, 11332, "Members: Leaping sturgeon" + "
" + " (with 45 Strength and 45 Agility)", "Members who are versed in the art of barbarian fishing now have the Fishing level required to catch " + "" + "leaping sturgeon" + "" + " with a heavy rod. (They also need level 45 Agility and level 45 Strength.)"); + case 8: + return newstruct cs2func_script_998_struct(96, 383, "Members: Shark" + "
" + " (with 76 Strength)", "Members who are versed in the art of barbarian fishing now have the Fishing level required to catch " + "" + "sharks" + "" + " without a harpoon. (They also need level 76 Strength.)"); + case 9: + return newstruct cs2func_script_998_struct(96, 383, "Members: Possibility of catching two sharks in one fishing attempt" + "
" + " (with 76 Strength and 76 Agility)", "Members who are versed in the art of barbarian fishing now have the Fishing level required to potentially catch two " + "" + "sharks" + "" + " in one attempt without a harpoon. (They also need level 76 Strength and 76 Agility.)"); + } + break; + case 3: + switch (arg1) { + case 0: + return newstruct cs2func_script_998_struct(35, 359, "Possibility of catching two tuna in one fishing attempt" + "
" + " (with 35 Agility)", "You now have the Fishing level required to potentially catch two " + "" + "tuna" + "" + " in one fishing attempt. (You also need level 35 Agility.)"); + case 1: + return newstruct cs2func_script_998_struct(50, 371, "Possibility of catching two swordfish in one fishing attempt" + "
" + " (with 50 Agility)", "You now have the Fishing level required to potentially catch two " + "" + "swordfish" + "" + " in one fishing attempt. (You also need level 50 Agility.)"); + case 2: + return newstruct cs2func_script_998_struct(76, 383, "Possibility of catching two sharks in one fishing attempt" + "
" + " (with 76 Agility)", "You now have the Fishing level required to potentially catch two " + "" + "sharks" + "" + " in one fishing attempt. (You also need level 76 Agility.)"); + } + break; + case 4: + switch (arg1) { + case 0: + return newstruct cs2func_script_998_struct(91, 18778, "Members: Starved ancient effigies", "Members can now investigate " + "" + "starved ancient effigies" + "" + " using their knowledge of Fishing."); + case 1: + return newstruct cs2func_script_998_struct(93, 18779, "Members: Nourished ancient effigies", "Members can now investigate " + "" + "nourished ancient effigies" + "" + " using their knowledge of Fishing."); + case 2: + return newstruct cs2func_script_998_struct(95, 18780, "Members: Sated ancient effigies", "Members can now investigate " + "" + "sated ancient effigies" + "" + " using their knowledge of Fishing."); + case 3: + return newstruct cs2func_script_998_struct(97, 18781, "Members: Gorged ancient effigies", "Members can now investigate " + "" + "gorged ancient effigies" + "" + " using their knowledge of Fishing."); + } + break; + case 5: + switch (arg1) { + case 0: + return newstruct cs2func_script_998_struct(1, 14142, "Members: Stealing Creation - class 1 harpoon", "Members can now use " + "" + "class 1 harpoons" + "" + " in Stealing Creation."); + case 1: + return newstruct cs2func_script_998_struct(20, 14184, "Members: Stealing Creation - catch class 2 sacred clay", "Members can now catch " + "" + "class 2 sacred clay" + "" + " in Stealing Creation."); + case 2: + return newstruct cs2func_script_998_struct(20, 14144, "Members: Stealing Creation - class 2 harpoon", "Members can now use " + "" + "class 2 harpoons" + "" + " in Stealing Creation."); + case 3: + return newstruct cs2func_script_998_struct(40, 14186, "Members: Stealing Creation - catch class 3 sacred clay", "Members can now catch " + "" + "class 3 sacred clay" + "" + " in Stealing Creation."); + case 4: + return newstruct cs2func_script_998_struct(40, 14146, "Members: Stealing Creation - class 3 harpoon", "Members can now use " + "" + "class 3 harpoons" + "" + " in Stealing Creation."); + case 5: + return newstruct cs2func_script_998_struct(60, 14188, "Members: Stealing Creation - catch class 4 sacred clay", "Members can now catch " + "" + "class 4 sacred clay" + "" + " in Stealing Creation."); + case 6: + return newstruct cs2func_script_998_struct(60, 14148, "Members: Stealing Creation - class 4 harpoon", "Members can now use " + "" + "class 4 harpoons" + "" + " in Stealing Creation."); + case 7: + return newstruct cs2func_script_998_struct(80, 14190, "Members: Stealing Creation - catch class 5 sacred clay", "Members can now catch " + "" + "class 5 sacred clay" + "" + " in Stealing Creation."); + case 8: + return newstruct cs2func_script_998_struct(80, 14150, "Members: Stealing Creation - class 5 harpoon", "Members can now use " + "" + "class 5 harpoons" + "" + " in Stealing Creation."); + } + break; + case 6: + switch (arg1) { + case 0: + return newstruct cs2func_script_998_struct(-1, 15707, "Dungeoneering skill tasks" + "
" + "As your Fishing level increases, you will be able to attempt higher-level fishing tasks within Daemonheim. You will also be more likely to succeed when attempting fishing tasks within Daemonheim.", ""); + case 1: + return newstruct cs2func_script_998_struct(1, 17797, "Heim crab (Tier 1)", "You can now catch " + "" + "heim crabs" + "" + " within Daemonheim."); + case 2: + return newstruct cs2func_script_998_struct(10, 17799, "Red-eye (Tier 2)", "You can now catch " + "" + "red-eye" + "" + " within Daemonheim."); + case 3: + return newstruct cs2func_script_998_struct(20, 17801, "Dusk eel (Tier 3)", "You can now catch " + "" + "dusk eels" + "" + " within Daemonheim."); + case 4: + return newstruct cs2func_script_998_struct(30, 17803, "Giant flatfish (Tier 4)", "You can now catch " + "" + "giant flatfish" + "" + " within Daemonheim."); + case 5: + return newstruct cs2func_script_998_struct(40, 17805, "Short-finned eel (Tier 5)", "You can now catch " + "" + "short-finned eels" + "" + " within Daemonheim."); + case 6: + return newstruct cs2func_script_998_struct(50, 17807, "Members: Web snipper (Tier 6)", "Members can now catch " + "" + "web snippers" + "" + " within Daemonheim."); + case 7: + return newstruct cs2func_script_998_struct(60, 17809, "Members: Bouldabass (Tier 7)", "Members can now catch " + "" + "bouldabass" + "" + " within Daemonheim."); + case 8: + return newstruct cs2func_script_998_struct(70, 17811, "Members: Salve eel (Tier 8)", "Members can now catch " + "" + "salve eels" + "" + " within Daemonheim."); + case 9: + return newstruct cs2func_script_998_struct(80, 17813, "Members: Blue crab (Tier 9)", "Members can now catch " + "" + "blue crabs" + "" + " within Daemonheim."); + case 10: + return newstruct cs2func_script_998_struct(90, 17815, "Members: Cave moray (Tier 10)", "Members can now catch " + "" + "cave morays" + "" + " within Daemonheim."); + } + break; + case 7: + SWITCH (arg1) { + case 0: + GOTO flow_99 + case 1: + GOTO flow_100 + } + break; + flow_99: + return newstruct cs2func_script_998_struct(68, 383, "Members: Fishing Guild", "Members can now enter the " + "" + "Fishing Guild" + "" + "."); + flow_100: + return newstruct cs2func_script_998_struct(99, 9798, "Skill mastery", "" + "Congratulations! You are now a master of " + "" + "Fishing" + "" + ". Members can visit the " + "" + "Master Fisherman" + "" + " at the " + "" + "Fishing Guild" + "" + ". He has something special that is only available to true masters of the " + "" + "Fishing" + "" + " skill!"); + } + return newstruct cs2func_script_998_struct(0, -1, "", ""); +} diff --git a/dumps/scripts/999.cs2 b/dumps/scripts/999.cs2 new file mode 100644 index 0000000..c1dd8b9 --- /dev/null +++ b/dumps/scripts/999.cs2 @@ -0,0 +1,31 @@ +cs2func_script_999_struct(1,1,0) script_999(int arg0) { + switch (arg0) { + case 0: + return newstruct cs2func_script_999_struct(1, "Weaving"); + case 1: + return newstruct cs2func_script_999_struct(0, "Armour"); + case 2: + return newstruct cs2func_script_999_struct(0, "Spinning"); + case 3: + return newstruct cs2func_script_999_struct(0, "Pottery"); + case 4: + return newstruct cs2func_script_999_struct(1, "Glass"); + case 5: + return newstruct cs2func_script_999_struct(0, "Jewellery"); + case 6: + return newstruct cs2func_script_999_struct(1, "Weaponry"); + case 7: + return newstruct cs2func_script_999_struct(1, "Pyre ships"); + case 8: + return newstruct cs2func_script_999_struct(1, "Objects"); + case 9: + return newstruct cs2func_script_999_struct(0, "Other"); + case 10: + return newstruct cs2func_script_999_struct(1, "Minigames"); + case 11: + return newstruct cs2func_script_999_struct(0, "Dungeoneering"); + case 12: + return newstruct cs2func_script_999_struct(0, "Milestones"); + } + return newstruct cs2func_script_999_struct(-1, ""); +} diff --git a/dumps/scripts/cs2mapping.txt b/dumps/scripts/cs2mapping.txt new file mode 100644 index 0000000..e0f5265 --- /dev/null +++ b/dumps/scripts/cs2mapping.txt @@ -0,0 +1,1472 @@ +Script 0 - [0,0,null,0]: null +Script 1 - [0,0,null,0]: null +Script 2 - [0,0,null,0]: null +Script 3 - [0,0,null,0]: null +Script 4 - [0,0,null,0]: null +Script 5 - [0,0,null,0]: null +Script 6 - [0,0,null,0]: null +Script 7 - [0,0,null,0]: null +Script 8 - [0,0,null,0]: null +Script 9 - [0,0,null,0]: null +Script 10 - [0,0,null,0]: null +Script 11 - [0,0,null,0]: null +Script 12 - [0,0,null,0]: null +Script 13 - [0,0,null,0]: null +Script 14 - [0,0,null,0]: null +Script 15 - [0,0,null,0]: null +Script 16 - [0,0,null,0]: null +Script 17 - [0,0,null,0]: null +Script 18 - [0,0,null,0]: null +Script 19 - [0,0,null,0]: null +Script 20 - [0,0,null,0]: null +Script 21 - [0,0,null,0]: null +Script 22 - [0,0,null,0]: null +Script 23 - [0,0,null,0]: null +Script 24 - [0,0,null,0]: null +Script 25 - [0,0,null,0]: null +Script 26 - [0,0,null,0]: null +Script 27 - [0,0,null,0]: null +Script 28 - [0,0,null,0]: null +Script 29 - [0,0,null,0]: null +Script 30 - [0,0,null,0]: null +Script 31 - [0,0,null,0]: null +Script 32 - [0,0,null,0]: null +Script 33 - [0,0,null,0]: null +Script 34 - [0,0,null,0]: null +Script 35 - [0,0,null,0]: null +Script 36 - [0,0,null,0]: null +Script 37 - [0,0,null,0]: null +Script 38 - [0,0,null,0]: null +Script 39 - [0,0,null,0]: null +Script 40 - [0,0,null,0]: null +Script 41 - [0,0,null,0]: null +Script 42 - [0,0,null,0]: null +Script 43 - [0,0,null,0]: null +Script 44 - [0,0,null,0]: null +Script 45 - [0,0,null,0]: null +Script 46 - [0,0,null,0]: null +Script 47 - [0,0,null,0]: null +Script 48 - [0,0,null,0]: null +Script 49 - [0,0,null,0]: null +Script 50 - [0,0,null,0]: null +Script 51 - [0,0,null,0]: null +Script 52 - [0,0,null,0]: null +Script 53 - [0,0,null,0]: null +Script 54 - [0,0,null,0]: null +Script 55 - [0,0,null,0]: null +Script 56 - [0,0,null,0]: null +Script 57 - [0,0,null,0]: null +Script 58 - [0,0,null,0]: null +Script 59 - [0,0,null,0]: null +Script 60 - [0,0,null,0]: null +Script 61 - [0,0,null,0]: null +Script 62 - [0,0,null,0]: null +Script 63 - [0,0,null,0]: null +Script 64 - [0,0,null,0]: null +Script 65 - [0,0,null,0]: null +Script 66 - [0,0,null,0]: null +Script 67 - [0,0,null,0]: null +Script 68 - [0,0,null,0]: null +Script 69 - [0,0,null,0]: null +Script 70 - [0,0,null,0]: null +Script 71 - [0,0,null,0]: null +Script 72 - [0,0,null,0]: null +Script 73 - [0,0,null,0]: null +Script 74 - [0,0,null,0]: null +Script 75 - [0,0,null,0]: null +Script 76 - [0,0,null,0]: null +Script 77 - [0,0,null,0]: null +Script 78 - [0,0,null,0]: null +Script 79 - [0,0,null,0]: null +Script 80 - [0,0,null,0]: null +Script 81 - [0,0,null,0]: null +Script 82 - [0,0,null,0]: null +Script 83 - [0,0,null,0]: null +Script 84 - [0,0,null,0]: null +Script 85 - [0,0,null,0]: null +Script 86 - [0,0,null,0]: null +Script 87 - [0,0,null,0]: null +Script 88 - [0,0,null,0]: null +Script 89 - [0,0,null,0]: null +Script 90 - [0,0,null,0]: null +Script 91 - [0,0,null,0]: null +Script 92 - [0,0,null,0]: null +Script 93 - [0,0,null,0]: null +Script 94 - [0,0,null,0]: null +Script 95 - [0,0,null,0]: null +Script 96 - [0,0,null,0]: null +Script 97 - [0,0,null,0]: null +Script 98 - [0,0,null,0]: null +Script 99 - [0,0,null,0]: null +Script 100 - [0,0,null,0]: null +Script 101 - [0,0,null,0]: null +Script 102 - [0,0,null,0]: null +Script 103 - [0,0,null,0]: null +Script 104 - [0,0,null,0]: null +Script 105 - [0,0,null,0]: null +Script 106 - [0,0,null,0]: null +Script 107 - [0,0,null,0]: null +Script 108 - [0,0,null,0]: null +Script 109 - [0,0,null,0]: null +Script 110 - [0,0,null,0]: null +Script 111 - [0,0,null,0]: null +Script 112 - [0,0,null,0]: null +Script 113 - [0,0,null,0]: null +Script 114 - [0,0,null,0]: null +Script 115 - [0,0,null,0]: null +Script 116 - [0,0,null,0]: null +Script 117 - [0,0,null,0]: null +Script 118 - [0,0,null,0]: null +Script 119 - [0,0,null,0]: null +Script 120 - [0,0,null,0]: null +Script 121 - [0,0,null,0]: null +Script 122 - [0,0,null,0]: null +Script 123 - [0,0,null,0]: null +Script 124 - [0,0,null,0]: null +Script 125 - [0,0,null,0]: null +Script 126 - [0,0,null,0]: null +Script 127 - [0,0,null,0]: null +Script 128 - [0,0,null,0]: null +Script 129 - [0,0,null,0]: null +Script 130 - [0,0,null,0]: null +Script 131 - [0,0,null,0]: null +Script 132 - [0,0,null,0]: null +Script 133 - [0,0,null,0]: null +Script 134 - [0,0,null,0]: null +Script 135 - [0,0,null,0]: null +Script 136 - [0,0,null,0]: null +Script 137 - [0,0,null,0]: null +Script 138 - [0,0,null,0]: null +Script 139 - [0,0,null,0]: null +Script 140 - [0,0,null,0]: null +Script 141 - [0,0,null,0]: null +Script 142 - [0,0,null,0]: null +Script 143 - [0,0,null,0]: null +Script 144 - [0,0,null,0]: null +Script 145 - [0,0,null,0]: null +Script 146 - [0,0,null,0]: null +Script 147 - [0,0,null,0]: null +Script 148 - [0,0,null,0]: null +Script 149 - [0,0,null,0]: null +Script 150 - [0,0,null,0]: null +Script 151 - [0,0,null,0]: null +Script 152 - [0,0,null,0]: null +Script 153 - [0,0,null,0]: null +Script 154 - [0,0,null,0]: null +Script 155 - [0,0,null,0]: null +Script 156 - [0,0,null,0]: null +Script 157 - [0,0,null,0]: null +Script 158 - [0,0,null,0]: null +Script 159 - [0,0,null,0]: null +Script 160 - [0,0,null,0]: null +Script 161 - [0,0,null,0]: null +Script 162 - [0,0,null,0]: null +Script 163 - [0,0,null,0]: null +Script 164 - [0,0,null,0]: null +Script 165 - [0,0,null,0]: null +Script 166 - [0,0,null,0]: null +Script 167 - [0,0,null,0]: null +Script 168 - [0,0,null,0]: null +Script 169 - [0,0,null,0]: null +Script 170 - [0,0,null,0]: null +Script 171 - [0,0,null,0]: null +Script 172 - [0,0,null,0]: null +Script 173 - [0,0,null,0]: null +Script 174 - [0,0,null,0]: null +Script 175 - [0,0,null,0]: null +Script 176 - [0,0,null,0]: null +Script 177 - [0,0,null,0]: null +Script 178 - [0,0,null,0]: null +Script 179 - [0,0,null,0]: null +Script 180 - [0,0,null,0]: null +Script 181 - [0,0,null,0]: null +Script 182 - [0,0,null,0]: null +Script 183 - [0,0,null,0]: null +Script 184 - [0,0,null,0]: null +Script 185 - [0,0,null,0]: null +Script 186 - [0,0,null,0]: null +Script 187 - [0,0,null,0]: null +Script 188 - [0,0,null,0]: null +Script 189 - [0,0,null,0]: null +Script 190 - [0,0,null,0]: null +Script 191 - [0,0,null,0]: null +Script 192 - [0,0,null,0]: null +Script 193 - [0,0,null,0]: null +Script 194 - [0,0,null,0]: null +Script 195 - [0,0,null,0]: null +Script 196 - [0,0,null,0]: null +Script 197 - [0,0,null,0]: null +Script 198 - [0,0,null,0]: null +Script 199 - [0,0,null,0]: null +Script 200 - [0,0,null,0]: null +Script 201 - [0,0,null,0]: null +Script 202 - [0,0,null,0]: null +Script 203 - [0,0,null,0]: null +Script 204 - [0,0,null,0]: null +Script 205 - [0,0,null,0]: null +Script 206 - [0,0,null,0]: null +Script 207 - [0,0,null,0]: null + f11=17956908, 12=17956909, 13=17956910, 14=17956911, 15=17956912, 17=17956914, 16=17956913, 19=17956916, 18=17956915, 21=17956918, 20=17956917, 23=17956920, 22=17956919, 25=17956922, 24=17956921, 27=17956924, 26=17956923, 29=17956926, 28=17956925, 31=17956928, 30=17956927, 34=17956931, 35=17956932, 32=17956929, 33=17956930, 38=17956935, 39=17956936, 36=17956933, 37=17956934, 42=17956939, 43=17956940, 40=17956937, 41=17956938, 46=17956943, 47=17956944, 44=17956941, 45=17956942, 51=17956948, 50=17956947, 49=17956946, 48=17956945, 55=17956952, 54=17956951, 53=17956950, 52=17956949, 59=17956956, 58=1 7956955, 57=17956954, 56=17956953, 63=17956960, 62=17956959, 61=17956958, 60=17956957, 68=17956965, 69=17956966, 70=17956967, 71=17956968, 64=17956961, 65=17956962, 66=17956963, 67=17956964, 76=17956973, 77=17956974, 78=17956975, 79=17956976, 72=17956969, 73=17956970, 74=17956971, 75=17956972, 85=17956982, 84=17956981, 87=17956984, 86=17956983, 81=17956978, 80=17956977, 83=17956980, 82=17956979, 93=17956990, 92=17956989, 95=17956992, 94=17956991, 89=17956986, 88=17956985, 91=17956988, 90=17956987, 102=17956999, 103=17957000, 100=17956997, 101=17956998, 98=17956995, 99=17956996, 96=17956993, 97=17956994, 110=17957007, 111=17957008, 108=17957005, 109=17957006, 106=17957003, 107=17957004, 104=17957001, 105=17957002, 119=17957016, 118=17957015, 117=17957014, 116=17957013, 115=17957012, 114=17957011, 113=17957010, 112=17957009} +Script 210 - [0,0,null,0]: null +Script 211 - [0,0,null,0]: null +Script 212 - [0,0,null,0]: null +Script 213 - [0,0,null,0]: null +Script 214 - [0,0,null,0]: null +Script 215 - [0,0,null,0]: null +Script 216 - [0,0,null,0]: null +Script 217 - [0,0,null,0]: null +Script 218 - [0,0,null,0]: null +Script 219 - [0,0,null,0]: null +Script 220 - [0,0,null,0]: null +Script 221 - [0,0,null,0]: null +Script 222 - [0,0,null,0]: null +Script 223 - [0,0,null,0]: null +Script 224 - [0,0,null,0]: null +Script 225 - [0,0,null,0]: null +Script 226 - [0,0,null,0]: null +Script 227 - [0,0,null,0]: null +Script 228 - [0,0,null,0]: null +Script 229 - [0,0,null,0]: null +Script 230 - [0,0,null,0]: null +Script 231 - [0,0,null,0]: null +Script 232 - [0,0,null,0]: null +Script 233 - [0,0,null,0]: null +Script 234 - [0,0,null,0]: null +Script 235 - [0,0,null,0]: null +Script 236 - [0,0,null,0]: null +Script 237 - [0,0,null,0]: null +Script 238 - [0,0,null,0]: null +Script 239 - [0,0,null,0]: null +Script 240 - [0,0,null,0]: null +Script 241 - [0,0,null,0]: null +Script 242 - [0,0,null,0]: null +Script 243 - [0,0,null,0]: null +Script 244 - [0,0,null,0]: null +Script 245 - [0,0,null,0]: null +Script 246 - [0,0,null,0]: null +Script 247 - [0,0,null,0]: null +Script 248 - [0,0,null,0]: null +Script 249 - [0,0,null,0]: null +Script 250 - [0,0,null,0]: null +Script 251 - [0,0,null,0]: null +Script 252 - [0,0,null,0]: null +Script 253 - [0,0,null,0]: null +Script 254 - [0,0,null,0]: null +Script 255 - [0,0,null,0]: null +Script 256 - [0,0,null,0]: null +Script 257 - [0,0,null,0]: null +Script 258 - [0,0,null,0]: null +Script 259 - [0,0,null,0]: null +Script 260 - [0,0,null,0]: null +Script 261 - [0,0,null,0]: null +Script 262 - [0,0,null,0]: null +Script 263 - [0,0,null,0]: null +Script 264 - [0,0,null,0]: null +Script 265 - [0,0,null,0]: null +Script 266 - [0,0,null,0]: null +Script 267 - [0,0,null,0]: null +Script 268 - [0,0,null,0]: null +Script 269 - [0,0,null,0]: null +Script 270 - [0,0,null,0]: null +Script 271 - [0,0,null,0]: null +Script 272 - [0,0,null,0]: null +Script 273 - [0,0,null,0]: null +Script 274 - [0,0,null,0]: null +Script 275 - [0,0,null,0]: null +Script 276 - [0,0,null,0]: null +Script 277 - [0,0,null,0]: null +Script 278 - [0,0,null,0]: null +Script 279 - [0,0,null,0]: null +Script 280 - [0,0,null,0]: null +Script 281 - [0,0,null,0]: null +Script 282 - [0,0,null,0]: null +Script 283 - [0,0,null,0]: null +Script 284 - [0,0,null,0]: null +Script 285 - [0,0,null,0]: null +Script 286 - [0,0,null,0]: null +Script 287 - [0,0,null,0]: null +Script 288 - [0,0,null,0]: null +Script 289 - [0,0,null,0]: null +Script 290 - [0,0,null,0]: null +Script 291 - [0,0,null,0]: null +Script 292 - [0,0,null,0]: null +Script 293 - [0,0,null,0]: null +Script 294 - [0,0,null,0]: null +Script 295 - [0,0,null,0]: null +Script 296 - [0,0,null,0]: null +Script 297 - [0,0,null,0]: null +Script 298 - [0,0,null,0]: null +Script 299 - [0,0,null,0]: null +Script 300 - [0,0,null,0]: null +Script 301 - [0,0,null,0]: null +Script 302 - [0,0,null,0]: null +Script 303 - [0,0,null,0]: null +Script 304 - [0,0,null,0]: null +Script 305 - [0,0,null,0]: null +Script 306 - [0,0,null,0]: null +Script 307 - [0,0,null,0]: null +Script 308 - [0,0,null,0]: null +Script 309 - [0,0,null,0]: null +Script 310 - [0,0,null,0]: null +Script 311 - [0,0,null,0]: null +Script 312 - [0,0,null,0]: null +Script 313 - [0,0,null,0]: null +Script 314 - [0,0,null,0]: null +Script 315 - [0,0,null,0]: null +Script 316 - [0,0,null,0]: null +Script 317 - [0,0,null,0]: null +Script 318 - [0,0,null,0]: null +Script 319 - [0,0,null,0]: null +Script 320 - [0,0,null,0]: null +Script 321 - [0,0,null,0]: null +Script 322 - [0,0,null,0]: null +Script 323 - [0,0,null,0]: null +Script 324 - [0,0,null,0]: null +Script 325 - [0,0,null,0]: null +Script 326 - [0,0,null,0]: null +Script 327 - [0,0,null,0]: null +Script 328 - [0,0,null,0]: null +Script 329 - [0,0,null,0]: null +Script 330 - [0,0,null,0]: null +Script 331 - [0,0,null,0]: null +Script 332 - [0,0,null,0]: null +Script 333 - [0,0,null,0]: null +Script 334 - [0,0,null,0]: null +Script 335 - [0,0,null,0]: null +Script 336 - [0,0,null,0]: null +Script 337 - [0,0,null,0]: null +Script 338 - [0,0,null,0]: null +Script 339 - [0,0,null,0]: null +Script 340 - [0,0,null,0]: null +Script 341 - [0,0,null,0]: null +Script 342 - [0,0,null,0]: null +Script 343 - [0,0,null,0]: null +Script 344 - [0,0,null,0]: null +Script 345 - [0,0,null,0]: null +Script 346 - [0,0,null,0]: null +Script 347 - [0,0,null,0]: null +Script 348 - [0,0,null,0]: null +Script 349 - [0,0,null,0]: null +Script 350 - [0,0,null,0]: null +Script 351 - [0,0,null,0]: null +Script 352 - [0,0,null,0]: null +Script 353 - [0,0,null,0]: null +Script 354 - [0,0,null,0]: null +Script 355 - [0,0,null,0]: null +Script 356 - [0,0,null,0]: null +Script 357 - [0,0,null,0]: null +Script 358 - [0,0,null,0]: null +Script 359 - [0,0,null,0]: null +Script 360 - [0,0,null,0]: null +Script 361 - [0,0,null,0]: null +Script 362 - [0,0,null,0]: null +Script 363 - [0,0,null,0]: null +Script 364 - [0,0,null,0]: null +Script 365 - [0,0,null,0]: null +Script 366 - [0,0,null,0]: null +Script 367 - [0,0,null,0]: null +Script 368 - [0,0,null,0]: null +Script 369 - [0,0,null,0]: null +Script 370 - [0,0,null,0]: null +Script 371 - [0,0,null,0]: null +Script 372 - [0,0,null,0]: null +Script 373 - [0,0,null,0]: null +Script 374 - [0,0,null,0]: null +Script 375 - [0,0,null,0]: null +Script 376 - [0,0,null,0]: null +Script 377 - [0,0,null,0]: null +Script 378 - [0,0,null,0]: null +Script 379 - [0,0,null,0]: null +Script 380 - [0,0,null,0]: null +Script 381 - [0,0,null,0]: null +Script 382 - [0,0,null,0]: null +Script 383 - [0,0,null,0]: null +Script 384 - [0,0,null,0]: null +Script 385 - [0,0,null,0]: null +Script 386 - [0,0,null,0]: null +Script 387 - [0,0,null,0]: null +Script 388 - [0,0,null,0]: null +Script 389 - [0,0,null,0]: null +Script 390 - [0,0,null,0]: null +Script 391 - [0,0,null,0]: null +Script 392 - [0,0,null,0]: null +Script 393 - [0,0,null,0]: null +Script 394 - [0,0,null,0]: null +Script 395 - [0,0,null,0]: null +Script 396 - [0,0,null,0]: null +Script 397 - [0,0,null,0]: null +Script 398 - [0,0,null,0]: null +Script 399 - [0,0,null,0]: null +Script 400 - [0,0,null,0]: null +Script 401 - [0,0,null,0]: null +Script 402 - [0,0,null,0]: null +Script 403 - [0,0,null,0]: null +Script 404 - [0,0,null,0]: null +Script 405 - [0,0,null,0]: null +Script 406 - [0,0,null,0]: null +Script 407 - [0,0,null,0]: null +Script 408 - [0,0,null,0]: null +Script 409 - [0,0,null,0]: null +Script 410 - [0,0,null,0]: null +Script 411 - [0,0,null,0]: null +Script 412 - [0,0,null,0]: null +Script 413 - [0,0,null,0]: null +Script 414 - [0,0,null,0]: null +Script 415 - [0,0,null,0]: null +Script 416 - [0,0,null,0]: null +Script 417 - [0,0,null,0]: null +Script 418 - [0,0,null,0]: null +Script 419 - [0,0,null,0]: null +Script 420 - [0,0,null,0]: null +Script 421 - [0,0,null,0]: null +Script 422 - [0,0,null,0]: null +Script 423 - [0,0,null,0]: null +Script 424 - [0,0,null,0]: null +Script 425 - [0,0,null,0]: null +Script 426 - [0,0,null,0]: null +Script 427 - [0,0,null,0]: null +Script 428 - [0,0,null,0]: null +Script 429 - [0,0,null,0]: null +Script 430 - [0,0,null,0]: null +Script 431 - [0,0,null,0]: null +Script 432 - [0,0,null,0]: null +Script 433 - [0,0,null,0]: null +Script 434 - [0,0,null,0]: null +Script 435 - [0,0,null,0]: null +Script 436 - [0,0,null,0]: null +Script 437 - [0,0,null,0]: null +Script 438 - [0,0,null,0]: null +Script 439 - [0,0,null,0]: null +Script 440 - [0,0,null,0]: null +Script 441 - [0,0,null,0]: null +Script 442 - [0,0,null,0]: null +Script 443 - [0,0,null,0]: null +Script 444 - [0,0,null,0]: null +Script 445 - [0,0,null,0]: null +Script 446 - [0,0,null,0]: null +Script 447 - [0,0,null,0]: null +Script 448 - [0,0,null,0]: null +Script 449 - [0,0,null,0]: null +Script 450 - [0,0,null,0]: null +Script 451 - [0,0,null,0]: null +Script 452 - [0,0,null,0]: null +Script 453 - [0,0,null,0]: null +Script 454 - [0,0,null,0]: null +Script 455 - [0,0,null,0]: null +Script 456 - [0,0,null,0]: null +Script 457 - [0,0,null,0]: null +Script 458 - [0,0,null,0]: null +Script 459 - [0,0,null,0]: null +Script 460 - [0,0,null,0]: null +Script 461 - [0,0,null,0]: null +Script 462 - [0,0,null,0]: null +Script 463 - [0,0,null,0]: null +Script 464 - [0,0,null,0]: null +Script 465 - [0,0,null,0]: null +Script 466 - [0,0,null,0]: null +Script 467 - [0,0,null,0]: null +Script 468 - [0,0,null,0]: null +Script 469 - [0,0,null,0]: null +Script 470 - [0,0,null,0]: null +Script 471 - [0,0,null,0]: null +Script 472 - [0,0,null,0]: null +Script 473 - [0,0,null,0]: null +Script 474 - [0,0,null,0]: null +Script 475 - [0,0,null,0]: null +Script 476 - [0,0,null,0]: null +Script 477 - [0,0,null,0]: null +Script 478 - [0,0,null,0]: null +Script 479 - [0,0,null,0]: null +Script 480 - [0,0,null,0]: null +Script 481 - [0,0,null,0]: null +Script 482 - [0,0,null,0]: null +Script 483 - [0,0,null,0]: null +Script 484 - [0,0,null,0]: null +Script 485 - [0,0,null,0]: null +Script 486 - [0,0,null,0]: null +Script 487 - [0,0,null,0]: null +Script 488 - [0,0,null,0]: null +Script 489 - [0,0,null,0]: null +Script 490 - [0,0,null,0]: null +Script 491 - [0,0,null,0]: null +Script 492 - [0,0,null,0]: null +Script 493 - [0,0,null,0]: null +Script 494 - [0,0,null,0]: null +Script 495 - [0,0,null,0]: null +Script 496 - [0,0,null,0]: null +Script 497 - [0,0,null,0]: null +Script 498 - [0,0,null,0]: null +Script 499 - [0,0,null,0]: null +Script 500 - [0,0,null,0]: null +Script 501 - [0,0,null,0]: null +Script 502 - [0,0,null,0]: null +Script 503 - [0,0,null,0]: null +Script 504 - [73,115,zzz,0]: {17956878=Black Knights' Fortress, 17956879=Cook's Assistant, 17956881=Doric's Quest, 17956880=Demon Slayer, 17956883=Ernest the Chicken, 17956882=Dragon Slayer, 17956885=Imp Catcher, 17956884=Goblin Diplomacy, 17956887=Pirate's Treasure, 17956886=Knight's Sword, The, 17956889=Restless Ghost, The, 17956888=Prince Ali Rescue, 17956891=Rune Mysteries, 17956890=Romeo & Juliet, 17956893=Shield of Arrav, 17956892=Sheep Shearer, 17956895=Witch's Potion, 17956894=Vampire Slayer, 17956898=Between a Rock..., 17956899=Big Chompy Bird Hunting, 17956897=Animal Magnetism, 17956902=Clock Tower, 17956903=Contact!, 17956900=Biohazard, 17956901=Cabin Fever, 17956906=Darkness of Hallowvale, 17956907=Death to the Dorgeshuun, 17956904=Zogre Flesh Eaters, 17956905=Creature of Fenkenstrain, 17956910=Devious Minds, 17956911=Dig Site, The, 17956908=Death Plateau, 17956909=Desert Treasure, 17956915=Eagles' Peak, 17956914=Eadgar's Ruse, 17956913=Dwarf Cannon, 17956912=Druidic Ritual, 17956919=Enlightened Journey, 17956918=Enakhra's Lament, 17956917=Elemental Workshop II, 17956916=Elemental Workshop I, 17956923=Family Crest, 17956922=Fairytale II - Cure a Queen, 17956921=Fairytale I - Growing Pains, 17956920=Eyes of Glouphrie, The, 17956927=Forgettable Tale..., 17956926=Fishing Contest, 17956925=Fight Arena, 17956924=Feud, The, 17956932=Ghosts Ahoy, 17956933=Giant Dwarf, The, 17956934=Golem, The, 17956935=Grand Tree, The, 17956928=Fremennik Trials, The, 17956929=Waterfall Quest, 17956930=Garden of Tranquillity, 17956931=Gertrude's Cat, 17956940=Holy Grail, 17956941=Horror from the Deep, 17956942=Icthlarin's Little Helper, 17956943=In Aid of the Myreque, 17956936=Hand in the Sand, The, 17956937=Haunted Mine, 17956938=Hazeel Cult, 17956939=Heroes' Quest, 17956949=Lunar Diplomacy, 17956948=Lost Tribe, The, 17956951=Merlin's Crystal, 17956950=Making History, 17956945=Jungle Potion, 17956944=In Search of the Myreque, 17956947=Lost City, 17956946=Legends' Quest, 17956957=Murder Mystery, 17956956=Mourning's Ends Part II, 17956959=Nature Spirit, 17956958=My Arm's Big Adventure, 17956953=Monk's Friend, 17956952=Monkey Madness, 17956955=Mourning's Ends Part I, 17956954=Mountain Daughter, 17956966=Recipe for Disaster, 17956967=Recruitment Drive, 17956964=Rag and Bone Man, 17956965=Ratcatchers, 17956962=Plague City, 17956963=Priest in Peril, 17956960=Observatory Quest, 17956961=One Small Favour, 17956974=Slug Menace, The, 17956975=Shades of Mort'ton, 17956972=Scorpion Catcher, 17956973=Sea Slug, 17956970=Royal Trouble, 17956971=Rum Deal, 17956968=Regicide, 17956969=Roving Elves, 17956983=Tail of Two Cats, A, 17956982=Tai Bwo Wannai Trio, 17956981=Swan Song, 17956980=Spirits of the Elid, 17956979=Soul's Bane, A, 17956978=Shilo Village, 17956977=Sheep Herder, 17956976=Shadow of the Storm, 17956991=Troll Romance, 17956990=Tribal Totem, 17956989=Tree Gnome Village, 17956988=Witch's House, 17956987=Tourist Trap, The, 17956986=Throne of Miscellania, 17956985=Temple of Ikov, 17956984=Tears of Guthix, 17957001=Olaf's Quest, 17957000=What Lies Below, 17957003=Dream Mentor, 17957002=Another Slice of H.A.M., 17957005=King's Ransom, 17957004=Grim Tales, 17957007=Back to my Roots, 17957006=Path of Glouphrie, The, 17956993=Underground Pass, 17956992=Troll Stronghold, 17956995=Watchtower, 17956994=Wanted!, 17956997=Fremennik Isles, The, 17956996=Cold War, 17956999=Great Brain Robbery, The, 17956998=Tower of Life, 17957016=TokTz-Ket-Dill, 17957008=Land of the Goblins, 17957009=Dealing with Scabaras, 17957010=Wolf Whistle, 17957011=As a First Resort..., 17957012=Catapult Construction, 17957013=Kennith's Concerns, 17957014=Legacy of Seergaze, 17957015=Perils of Ice Mountain} +Script 505 - [0,0,null,0]: null +Script 506 - [0,0,null,0]: null +Script 507 - [0,0,null,0]: null +Script 508 - [0,0,null,0]: null +Script 509 - [0,0,null,0]: null +Script 510 - [0,0,null,0]: null +Script 511 - [0,0,null,0]: null +Script 512 - [0,0,null,0]: null +Script 513 - [0,0,null,0]: null +Script 514 - [0,0,null,0]: null +Script 515 - [0,0,null,0]: null +Script 516 - [0,0,null,0]: null +Script 517 - [0,0,null,0]: null +Script 518 - [0,0,null,0]: null +Script 519 - [0,0,null,0]: null +Script 520 - [0,0,null,0]: null +Script 521 - [0,0,null,0]: null +Script 522 - [0,0,null,0]: null +Script 523 - [0,0,null,0]: null +Script 524 - [0,0,null,0]: null +Script 525 - [0,0,null,0]: null +Script 526 - [0,0,null,0]: null +Script 527 - [0,0,null,0]: null +Script 528 - [0,0,null,0]: null +Script 529 - [0,0,null,0]: null +Script 530 - [0,0,null,0]: null +Script 531 - [0,0,null,0]: null +Script 532 - [0,0,null,0]: null +Script 533 - [0,0,null,0]: null +Script 534 - [0,0,null,0]: null +Script 535 - [0,0,null,0]: null +Script 536 - [0,0,null,0]: null +Script 537 - [0,0,null,0]: null +Script 538 - [0,0,null,0]: null +Script 539 - [0,0,null,0]: null +Script 540 - [0,0,null,0]: null +Script 541 - [0,0,null,0]: null +Script 542 - [0,0,null,0]: null +Script 543 - [0,0,null,0]: null +Script 544 - [0,0,null,0]: null +Script 545 - [0,0,null,0]: null +Script 546 - [0,0,null,0]: null +Script 547 - [0,0,null,0]: null +Script 548 - [0,0,null,0]: null +Script 549 - [0,0,null,0]: null +Script 550 - [0,0,null,0]: null +Script 551 - [0,0,null,0]: null +Script 552 - [0,0,null,0]: null +Script 553 - [0,0,null,0]: null +Script 554 - [0,0,null,0]: null +Script 555 - [0,0,null,0]: null +Script 556 - [0,0,null,0]: null +Script 557 - [0,0,null,0]: null +Script 558 - [0,0,null,0]: null +Script 559 - [0,0,null,0]: null +Script 560 - [0,0,null,0]: null +Script 561 - [0,0,null,0]: null +Script 562 - [0,0,null,0]: null +Script 563 - [0,0,null,0]: null +Script 564 - [0,0,null,0]: null +Script 565 - [0,0,null,0]: null +Script 566 - [0,0,null,0]: null +Script 567 - [0,0,null,0]: null +Script 568 - [0,0,null,0]: null +Script 569 - [0,0,null,0]: null +Script 570 - [0,0,null,0]: null +Script 571 - [0,0,null,0]: null +Script 572 - [0,0,null,0]: null +Script 573 - [0,0,null,0]: null +Script 574 - [0,0,null,0]: null +Script 575 - [0,0,null,0]: null +Script 576 - [0,0,null,0]: null +Script 577 - [0,0,null,0]: null +Script 578 - [0,0,null,0]: null +Script 579 - [105,73,null,-1]: {0=8978436, 1=8978437, 2=8978438, 3=8978439, 4=8978440, 5=8978441, 6=8978442, 7=8978443, 8=8978444, 9=8978445, 10=8978446, 11=8978447, 12=8978448, 13=8978449, 14=8978450, 15=8978451, 17=8978453, 16=8978452, 19=8978455, 18=8978454, 21=8978457, 20=8978456, 23=8978459, 22=8978458, 25=8978461, 24=8978460, 27=8978463, 26=8978462, 29=8978465, 28=8978464, 31=8978467, 30=8978466, 34=8978470, 35=8978471, 32=8978468, 33=8978469, 38=8978474, 39=8978475, 36=8978472, 37=8978473, 42=8978478, 43=8978479, 40=8978476, 41=8978477, 46=8978482, 47=8978483, 44=8978480, 45=8978481, 51=8978487, 50=8978486, 49=8978485, 48=8978484, 55=8978491, 54=8978490, 53=8978489, 52=8978488, 59=8978495, 58=8978494, 57=8978493, 56=8978492, 63=8978499, 62=8978498, 61=8978497, 60=8978496, 68=8978504, 69=8978505, 70=8978506, 71=8978507, 64=8978500, 65=8978501, 66=8978502, 67=8978503, 76=8978512, 77=8978513, 78=8978514, 79=8978515, 72=8978508, 73=8978509, 74=8978510, 75=8978511, 85=8978521, 84=8978520, 87=8978523, 86=8978522, 81=8978517, 80=8978516, 83=8978519, 82=8978518, 93=8978529, 92=8978528, 95=8978531, 94=8978530, 89=8978525, 88=8978524, 91=8978527, 90=8978526, 98=8978534, 99=8978535, 96=8978532, 97=8978533} +Script 580 - [105,73,null,-1]: {0=35913812, 1=35913811, 2=35913810, 3=35913809, 4=35913808} +Script 581 - [0,0,null,0]: null +Script 582 - [0,0,null,0]: null +Script 583 - [0,0,null,0]: null +Script 584 - [0,0,null,0]: null +Script 585 - [0,0,null,0]: null +Script 586 - [0,0,null,0]: null +Script 587 - [0,0,null,0]: null +Script 588 - [0,0,null,0]: null +Script 589 - [0,0,null,0]: null +Script 590 - [0,0,null,0]: null +Script 591 - [0,0,null,0]: null +Script 592 - [0,0,null,0]: null +Script 593 - [0,0,null,0]: null +Script 594 - [0,0,null,0]: null +Script 595 - [0,0,null,0]: null +Script 596 - [0,0,null,0]: null +Script 597 - [0,0,null,0]: null +Script 598 - [0,0,null,0]: null +Script 599 - [0,0,null,0]: null +Script 600 - [0,0,null,0]: null +Script 601 - [0,0,null,0]: null +Script 602 - [0,0,null,0]: null +Script 603 - [0,0,null,0]: null +Script 604 - [0,0,null,0]: null +Script 605 - [0,0,null,0]: null +Script 606 - [0,0,null,0]: null +Script 607 - [0,0,null,0]: null +Script 608 - [0,0,null,0]: null +Script 609 - [0,0,null,0]: null +Script 610 - [0,0,null,0]: null +Script 611 - [0,0,null,0]: null +Script 612 - [0,0,null,0]: null +Script 613 - [0,0,null,0]: null +Script 614 - [0,0,null,0]: null +Script 615 - [0,0,null,0]: null +Script 616 - [111,105,null,0]: {7806=1, 7807=1, 8871=1, 4075=1, 1842=1, 5510=1, 7808=1, 5511=1, 7809=1, 10024=1, 431=1, 5509=1, 4657=1, 5514=1, 9067=1, 5515=1, 10023=1, 5512=1, 5513=1, 8949=1, 8950=1, 9433=1} +Script 617 - [0,0,null,0]: null +Script 618 - [0,0,null,0]: null +Script 619 - [0,0,null,0]: null +Script 620 - [0,0,null,0]: null +Script 621 - [0,0,null,0]: null +Script 622 - [0,0,null,0]: null +Script 623 - [0,0,null,0]: null +Script 624 - [0,0,null,0]: null +Script 625 - [0,0,null,0]: null +Script 626 - [0,0,null,0]: null +Script 627 - [0,0,null,0]: null +Script 628 - [0,0,null,0]: null +Script 629 - [0,0,null,0]: null +Script 630 - [0,0,null,0]: null +Script 631 - [0,0,null,0]: null +Script 632 - [0,0,null,0]: null +Script 633 - [0,0,null,0]: null +Script 634 - [0,0,null,0]: null +Script 635 - [0,0,null,0]: null +Script 636 - [0,0,null,0]: null +Script 637 - [0,0,null,0]: null +Script 638 - [0,0,null,0]: null +Script 639 - [0,0,null,0]: null +Script 640 - [0,0,null,0]: null +Script 641 - [0,0,null,0]: null +Script 642 - [0,0,null,0]: null +Script 643 - [0,0,null,0]: null +Script 644 - [0,0,null,0]: null +Script 645 - [0,0,null,0]: null +Script 646 - [0,0,null,0]: null +Script 647 - [0,0,null,0]: null +Script 648 - [0,0,null,0]: null +Script 649 - [0,0,null,0]: null +Script 650 - [0,0,null,0]: null +Script 651 - [0,0,null,0]: null +Script 652 - [0,0,null,0]: null +Script 653 - [0,0,null,0]: null +Script 654 - [0,0,null,0]: null +Script 655 - [0,0,null,0]: null +Script 656 - [0,0,null,0]: null +Script 657 - [0,0,null,0]: null +Script 658 - [0,0,null,0]: null +Script 659 - [0,0,null,0]: null +Script 660 - [0,0,null,0]: null +Script 661 - [0,0,null,0]: null +Script 662 - [0,0,null,0]: null +Script 663 - [0,0,null,0]: null +Script 664 - [0,0,null,0]: null +Script 665 - [0,0,null,0]: null +Script 666 - [0,0,null,0]: null +Script 667 - [0,0,null,0]: null +Script 668 - [0,0,null,0]: null +Script 669 - [0,0,null,0]: null +Script 670 - [0,0,null,0]: null +Script 671 - [0,0,null,0]: null +Script 672 - [0,0,null,0]: null +Script 673 - [0,0,null,0]: null +Script 674 - [0,0,null,0]: null +Script 675 - [0,0,null,0]: null +Script 676 - [0,0,null,0]: null +Script 677 - [0,0,null,0]: null +Script 678 - [0,0,null,0]: null +Script 679 - [0,0,null,0]: null +Script 680 - [83,115,this skill,0]: {0=Attack, 1=Defence, 2=Strength, 3=Hitpoints, 4=Ranged, 5=Prayer, 6=Magic, 7=Cooking, 8=Woodcutting, 9=Fletching, 10=Fishing, 11=Firemaking, 12=Crafting, 13=Smithing, 14=Mining, 15=Herblore, 17=Thieving, 16=Agility, 19=Farming, 18=Slayer, 21=Hunter, 20=Runecraft, 23=Summoning, 22=Construction} +Script 681 - [0,0,null,0]: null +Script 682 - [0,0,null,0]: null +Script 683 - [105,73,null,-1]: {0=35913731, 1=35913734, 2=35913737, 3=35913741, 4=35913745, 5=35913749, 6=35913753} +Script 684 - [105,73,null,-1]: {2=35913739, 3=35913743, 4=35913747, 5=35913751, 6=35913755} +Script 685 - [0,0,null,0]: null +Script 686 - [0,0,null,0]: null +Script 687 - [0,0,null,0]: null +Script 688 - [105,73,null,37617683]: {1=38207534, 2=38207540, 3=38207537, 4=38207536, 5=38207539, 6=38207538, 7=38207551, 8=38207550, 9=38207546, 10=38207547, 11=38207541, 12=38207549, 13=38207535, 14=38207542, 15=38207543, 17=38207548, 16=38207544, 19=38207552, 18=38207553, 21=38207558, 20=38207545, 23=38207554, 25=38207556, 24=38207555, 27=38207559, 26=38207557, 29=38207561, 28=38207560} +Script 689 - [0,0,null,0]: null +Script 690 - [0,0,null,0]: null +Script 691 - [0,0,null,0]: null +Script 692 - [0,0,null,0]: null +Script 693 - [0,0,null,0]: null +Script 694 - [0,0,null,0]: null +Script 695 - [0,0,null,0]: null +Script 696 - [0,0,null,0]: null +Script 697 - [0,0,null,0]: null +Script 698 - [0,0,null,0]: null +Script 699 - [0,0,null,0]: null +Script 700 - [0,0,null,0]: null +Script 701 - [0,0,null,0]: null +Script 702 - [0,0,null,0]: null +Script 703 - [0,0,null,0]: null +Script 704 - [0,0,null,0]: null +Script 705 - [0,0,null,0]: null +Script 706 - [0,0,null,0]: null +Script 707 - [0,0,null,0]: null +Script 708 - [0,0,null,0]: null +Script 709 - [0,0,null,0]: null +Script 710 - [0,0,null,0]: null +Script 711 - [0,0,null,0]: null +Script 712 - [0,0,null,0]: null +Script 713 - [0,0,null,0]: null +Script 714 - [0,0,null,0]: null +Script 715 - [0,0,null,0]: null +Script 716 - [105,105,null,0]: {2=83, 3=174, 4=276, 5=388, 6=512, 7=650, 8=801, 9=969, 10=1154, 11=1358, 12=1584, 13=1833, 14=2107, 15=2411, 17=3115, 16=2746, 19=3973, 18=3523, 21=5018, 20=4470, 23=6291, 22=5624, 25=7842, 24=7028, 27=9730, 26=8740, 29=12031, 28=10824, 31=14833, 30=13363, 34=20224, 35=22406, 32=16456, 33=18247, 38=30408, 39=33648, 36=24815, 37=27473, 42=45529, 43=50339, 40=37224, 41=41171, 46=67983, 47=75127, 44=55649, 45=61512, 51=111945, 50=101333, 49=91721, 48=83014, 55=166636, 54=150872, 53=136594, 52=123660, 59=247886, 58=224466, 57=203254, 56=184040, 63=368599, 62=333804, 61=302288, 60=273742, 68=605032, 69=668051, 70=737627, 71=814445, 64=407015, 65=449428, 66=496254, 67=547953, 76=1336443, 77=1475581, 78=1629200, 79=1798808, 72=899257, 73=992895, 74=1096278, 75=1210421, 85=3258594, 84=2951373, 87=3972294, 86=3597792, 81=2192818, 80=1986068, 83=2673114, 82=2421087, 93=7195629, 92=6517253, 95=8771558, 94=7944614, 89=4842295, 88=4385776, 91=5902831, 90=5346332, 98=11805606, 99=13034431, 96=9684577, 97=10692629} +Script 717 - [0,0,null,0]: null +Script 718 - [0,0,null,0]: null +Script 719 - [0,0,null,0]: null +Script 720 - [0,0,null,0]: null +Script 721 - [0,0,null,0]: null +Script 722 - [0,0,null,0]: null +Script 723 - [0,0,null,0]: null +Script 724 - [0,0,null,0]: null +Script 725 - [0,0,null,0]: null +Script 726 - [0,0,null,0]: null +Script 727 - [105,79,null,11760]: {1=1931, 2=954, 3=1265, 4=1925, 5=590, 6=2347, 7=1061, 8=839, 9=882, 10=329, 11=2327, 12=2309, 13=2142} +Script 728 - [105,79,null,11760]: {1=1205, 2=1203, 3=1207, 4=1209, 5=1211, 6=1213, 7=1321, 8=1323, 9=1325} +Script 729 - [105,79,null,11760]: {4=1823, 1=2309, 2=1891, 3=1901} +Script 730 - [105,79,null,11760]: {1=1755, 2=1592, 3=1597, 4=1595, 5=1733, 6=1734, 7=1599, 8=2976, 9=5523, 10=11065} +Script 731 - [105,79,null,11760]: {1=1931, 2=2169, 3=175} +Script 732 - [105,79,null,11760]: {1=4684, 2=1833, 3=1835, 4=1837, 5=950, 6=1734, 7=1733} +Script 733 - [105,79,null,11760]: {1=8794, 2=8790, 3=4819, 4=4820, 5=1539} +Script 734 - [105,79,null,11760]: {4=8788, 1=3420, 2=8786, 3=8784} +Script 735 - [105,79,null,11760]: {1=8417, 2=8419, 3=8421, 4=8423, 5=8425, 6=8427, 7=8429, 8=8431, 9=8433, 10=8435, 11=8437, 12=8439, 13=8441, 14=8443, 15=8445, 17=8449, 16=8447, 19=8453, 18=8451, 21=8457, 20=8455, 23=8461, 22=8459} +Script 736 - [105,79,null,11760]: {1=1931, 2=1935, 3=1735, 4=1925, 5=590, 6=1755, 7=2347, 8=3424, 9=227, 10=1933, 11=3678} +Script 737 - [105,79,null,11760]: {1=3211, 2=3420, 3=8837, 4=1941, 5=960} +Script 738 - [105,79,null,11760]: {1=303, 2=307, 3=309, 4=311, 5=301, 6=313, 7=314, 8=305, 9=327} +Script 739 - [105,79,null,11760]: {1=1965, 2=1942, 3=1957, 4=1982, 5=1550} +Script 740 - [105,79,null,11760]: {1=303, 2=307, 3=309, 4=311, 5=301, 6=313, 7=314, 8=305, 9=327} +Script 741 - [105,79,null,11760]: {1=1965, 2=1942, 3=1957, 4=1982, 5=1550} +Script 742 - [105,79,null,11760]: {4=353, 1=1351, 2=590, 3=3363} +Script 743 - [105,79,null,11760]: {1=1931, 2=1935, 3=1735, 4=1925, 5=1923, 6=1887, 7=590, 8=1755, 9=2347} +Script 744 - [105,79,null,11760]: {1=3767, 2=3769, 3=3771, 4=3773, 5=3775, 6=3793, 7=3795, 8=5050, 9=5052, 10=5038, 11=5040, 12=5044, 13=5046, 14=5026, 15=5028, 17=5034, 16=5032} +Script 745 - [105,79,null,11760]: {4=1978, 1=1917, 2=5763, 3=1993} +Script 746 - [105,79,null,11760]: {8=1927, 1=2309, 2=1985, 3=1965, 4=1942, 5=1957, 6=1933, 7=1973} +Script 747 - [105,79,null,11760]: {1=1931, 2=1935, 3=1735, 4=1925, 5=590, 6=1755, 7=2347, 8=952, 9=946} +Script 748 - [105,79,null,11760]: {1=1734, 2=1733, 3=1759, 4=1763, 5=1765, 6=1767, 7=1769, 8=1771, 9=1773} +Script 749 - [105,79,null,11760]: {1=884, 2=886, 3=888, 4=890, 5=892, 6=877, 7=843, 8=845, 9=837, 10=849, 11=847} +Script 750 - [105,79,null,11760]: {1=2309, 2=379, 3=1993, 4=1985, 5=1891} +Script 751 - [105,79,null,11760]: {1=9640, 2=9642, 3=9644, 4=9634, 5=9636, 6=9638} +Script 752 - [105,79,null,11760]: {1=1931, 2=1935, 3=1735, 4=590, 5=2309, 6=3190, 7=3192, 8=3194, 9=3196, 10=3198, 11=3200, 12=3202} +Script 753 - [105,79,null,11760]: {1=1931, 2=1935, 3=1735, 4=590, 5=2309, 6=3190, 7=3192, 8=3194, 9=3196, 10=3198, 11=3200, 12=3202, 13=3204} +Script 754 - [105,79,null,11760]: {1=954, 2=1523, 3=1755, 4=946, 5=5560, 6=864, 7=863, 8=865, 9=3095, 10=3096, 11=3097} +Script 755 - [105,79,null,11760]: {1=954, 2=1523, 3=1755, 4=946, 5=5560, 6=864, 7=863, 8=865, 9=3095, 10=3096, 11=3097, 12=9777} +Script 756 - [105,79,null,11760]: {1=954, 2=1523, 3=1755, 4=946, 5=5560, 6=864, 7=863, 8=865, 9=3095, 10=3096, 11=3097, 12=9778} +Script 757 - [105,79,null,11760]: {1=4315, 2=4335, 3=4355, 4=4375, 5=4395} +Script 758 - [105,79,null,11760]: {1=4317, 2=4337, 3=4357, 4=4377, 5=4397} +Script 759 - [105,79,null,11760]: {1=4319, 2=4339, 3=4359, 4=4379, 5=4399} +Script 760 - [105,79,null,11760]: {1=4321, 2=4341, 3=4361, 4=4381, 5=4401} +Script 761 - [105,79,null,11760]: {1=4323, 2=4343, 3=4363, 4=4383, 5=4403} +Script 762 - [105,79,null,11760]: {1=4325, 2=4345, 3=4365, 4=4385, 5=4405} +Script 763 - [105,79,null,11760]: {1=4327, 2=4347, 3=4367, 4=4387, 5=4407} +Script 764 - [105,79,null,11760]: {1=4329, 2=4349, 3=4369, 4=4389, 5=4409} +Script 765 - [105,79,null,11760]: {1=4331, 2=4351, 3=4371, 4=4391, 5=4411} +Script 766 - [105,79,null,11760]: {1=4333, 2=4353, 3=4373, 4=4393, 5=4413} +Script 767 - [105,79,null,11760]: {1=9068, 2=9069, 3=9070, 4=9071, 5=9072, 6=9073, 7=9074, 8=1733, 9=1734} +Script 768 - [105,79,null,11760]: {1=556, 2=555, 3=557, 4=554, 5=558, 6=559, 7=562, 8=561, 9=560, 10=563, 11=565, 12=566, 13=1387, 14=1383, 15=1381, 17=9078, 16=1385} +Script 769 - [105,79,null,11760]: {1=556, 2=555, 3=557, 4=554, 5=558, 6=559, 7=562, 8=561, 9=560, 10=563, 11=565, 12=566, 13=9075, 14=1387, 15=1383, 17=1385, 16=1381, 18=9078} +Script 770 - [105,79,null,11760]: {1=1931, 2=1935, 3=1735, 4=1925, 5=1923, 6=1887, 7=590, 8=1755, 9=2347, 10=9003} +Script 771 - [105,79,null,11760]: {1=2518} +Script 772 - [105,79,null,11760]: {1=1931, 2=1935, 3=1735, 4=1925, 5=1923, 6=1887, 7=590, 8=1755, 9=2347, 10=550, 11=9003, 12=954, 13=946, 14=1963, 15=1785, 17=307, 16=301, 19=9629, 18=1941, 21=1025, 20=3226} +Script 773 - [105,79,null,11760]: {1=1931, 2=1935, 3=1735, 4=1925, 5=1923, 6=1887, 7=590, 8=1755, 9=2347} +Script 774 - [105,79,null,11760]: {1=1093, 2=1079, 3=1113, 4=1099, 5=1065, 6=1193, 7=1151} +Script 775 - [105,79,null,11760]: {2=1973, 1=6794} +Script 776 - [105,79,null,11760]: {1=2309, 2=1891, 3=1901} +Script 777 - [105,79,null,11760]: {1=1755, 2=1592, 3=1597, 4=1733, 5=1734, 6=1759} +Script 778 - [105,79,null,11760]: {1=1714} +Script 779 - [105,79,null,11760]: {1=5048, 2=5036, 3=5042, 4=5024, 5=5030, 6=950} +Script 780 - [105,79,null,11760]: {1=1337, 2=1335, 3=1339, 4=1341, 5=1343, 6=1345} +Script 781 - [105,79,null,11760]: {1=1365, 2=1369, 3=1285, 4=1287, 5=1325, 6=1297, 7=1303, 8=853, 9=851, 10=888, 11=890} +Script 782 - [105,79,null,11760]: {1=1105, 2=1109, 3=1107, 4=1111, 5=1141, 6=1143, 7=1145, 8=1177, 9=1195} +Script 783 - [105,79,null,11760]: {1=1935, 2=1925, 3=590, 4=1755, 5=2347, 6=36, 7=596, 8=973, 9=1059, 10=229, 11=233, 12=954} +Script 784 - [105,79,null,11760]: {1=1265, 2=1269, 3=1273, 4=1271, 5=1275} +Script 785 - [105,79,null,11760]: {1=5050, 2=5052, 3=5038, 4=5040, 5=5044, 6=5046, 7=5026, 8=5028, 9=5032, 10=5034} +Script 786 - [105,79,null,11760]: {8=560, 1=554, 2=555, 3=556, 4=557, 5=558, 6=559, 7=562} +Script 787 - [105,79,null,11760]: {8=565, 1=554, 2=555, 3=556, 4=557, 5=558, 6=562, 7=560} +Script 788 - [105,79,null,11760]: {1=4844, 2=2878, 3=946} +Script 789 - [105,79,null,11760]: {1=554, 2=555, 3=556, 4=557, 5=558, 6=559, 7=561, 8=562, 9=563, 10=564, 11=560} +Script 790 - [105,79,null,11760]: {1=2415, 2=2416, 3=2417} +Script 791 - [105,79,null,11760]: {1=1931, 2=1935, 3=1735, 4=1925, 5=590, 6=1755, 7=2347, 8=946, 9=1980} +Script 792 - [105,79,null,11760]: {1=1905, 2=1907, 3=1913} +Script 793 - [105,79,null,11760]: {1=1321, 2=1323, 3=1325, 4=1329, 5=2347} +Script 794 - [105,79,null,11760]: {4=2003, 1=1917, 2=7157, 3=1993} +Script 795 - [105,79,null,11760]: {1=317, 2=327, 3=345, 4=353, 5=341, 6=321} +Script 796 - [105,79,null,11760]: {1=7114, 2=7110, 3=7112, 4=7116, 5=7122, 6=7124, 7=7126, 8=7128, 9=7130, 10=7132, 11=7134, 12=7136, 13=7138} +Script 797 - [105,79,null,11760]: {1=8952, 2=8959, 3=8991, 4=8953, 5=8960, 6=8992, 7=8954, 8=8961, 9=8993, 10=8955, 11=8962, 12=8994, 13=8956, 14=8963, 15=8995, 17=8964, 16=8957, 19=8958, 18=8996, 21=8997, 20=8965, 23=8967, 22=8966, 25=8969, 24=8968, 27=8971, 26=8970, 29=8940, 28=8988, 30=8941} +Script 798 - [105,79,null,11760]: {1=347, 2=339, 3=361, 4=379, 5=373, 6=3144} +Script 799 - [105,79,null,11760]: {1=333, 2=365, 3=2289, 4=6705, 5=2003} +Script 800 - [105,79,null,11760]: {1=1363, 2=1365, 3=1369, 4=1277, 5=1279, 6=1281, 7=1283, 8=1285, 9=1287, 10=1291, 11=1293, 12=1295, 13=1297, 14=1299, 15=1301, 17=1203, 16=1205, 19=1217, 18=1207, 21=1211, 20=1209, 23=1420, 22=1422, 25=1428, 24=1424, 27=1307, 26=1430, 29=1311, 28=1309, 31=1315, 30=1313, 34=1101, 35=1105, 32=1317, 33=1103, 38=1141, 36=1139, 37=1137} +Script 801 - [105,79,null,11760]: {1=115, 2=121, 3=133} +Script 802 - [105,79,null,11760]: {1=6341, 2=6343, 3=6345, 4=6349, 5=6347, 6=6313, 7=6315, 8=6317, 9=6351, 10=6353, 11=6355, 12=6357, 13=6359, 14=6361, 15=6363, 17=6367, 16=6365, 19=6371, 18=6369, 21=6375, 20=6373, 23=6379, 22=6377} +Script 803 - [105,79,null,11760]: {1=2084, 2=2092, 3=2048, 4=2054, 5=2064, 6=2074, 7=2080} +Script 804 - [105,79,null,11760]: {1=10010, 2=10012, 3=10025, 4=10150, 5=10006, 6=10008, 7=10029, 8=596, 9=10031} +Script 805 - [105,79,null,11760]: {1=10010, 2=10012, 3=10025, 4=10150, 5=10006, 6=10008, 7=10029, 8=596, 9=10031} +Script 806 - [105,79,null,11760]: {1=596, 2=5014, 3=590} +Script 807 - [105,79,null,11760]: {1=10954, 2=10956, 3=10958} +Script 808 - [105,79,null,11760]: {8=1785, 1=596, 2=590, 3=1931, 4=1935, 5=1923, 6=1887, 7=954} +Script 809 - [105,79,null,11760]: null +Script 810 - [105,79,null,11760]: {4=9668, 1=5574, 2=5576, 3=5575} +Script 811 - [105,79,null,11760]: {1=5574, 2=5576, 3=5575, 4=9668, 5=9672, 6=9676, 7=9674, 8=9678, 9=9666, 10=9670} +Script 812 - [105,79,null,11760]: {2=3157, 1=3142} +Script 813 - [105,79,null,11760]: {1=3170, 2=3171, 3=3172, 4=3173, 5=3174, 6=3175, 7=3188} +Script 814 - [105,79,null,11760]: {1=6408, 2=6412, 3=6418, 4=6416, 5=4600} +Script 815 - [105,79,null,11760]: {1=6410, 2=6414, 3=6420, 4=6416, 5=4600} +Script 816 - [105,79,null,11760]: {8=6406, 1=6392, 2=6394, 3=6396, 4=6398, 5=6400, 6=6402, 7=6404} +Script 817 - [105,79,null,11760]: {1=6382, 2=6384, 3=6386, 4=6388, 5=6390} +Script 818 - [105,79,null,11760]: {4=557, 1=554, 2=555, 3=556} +Script 819 - [105,79,null,11760]: {1=561, 2=563, 3=562, 4=560, 5=558, 6=559, 7=565, 8=564, 9=566} +Script 820 - [0,0,null,0]: null +Script 821 - [105,79,null,11760]: {1=1265, 2=1351, 3=1349, 4=1353, 5=1363, 6=1365, 7=1369} +Script 822 - [105,79,null,11760]: {1=1277, 2=1279, 3=1281, 4=1283, 5=1285, 6=1287, 7=1291, 8=1293, 9=1295, 10=1297, 11=1299, 12=1301, 13=1205, 14=1203, 15=1207, 17=1209, 16=1217, 18=1211} +Script 823 - [105,79,null,11760]: {1=882, 2=884, 3=886, 4=888, 5=890, 6=877, 7=841, 8=839, 9=843, 10=845, 11=849, 12=847, 13=853, 14=851, 15=837} +Script 824 - [105,79,null,11760]: {1=886, 2=888, 3=890, 4=843, 5=845, 6=849, 7=847, 8=853, 9=851} +Script 825 - [105,79,null,11760]: {1=1379, 2=1389, 3=1381, 4=1383, 5=1385, 6=1387} +Script 826 - [105,79,null,11760]: {4=1329, 1=1321, 2=1323, 3=1325} +Script 827 - [105,79,null,11760]: {1=1422, 2=1420, 3=1424, 4=1428, 5=1430} +Script 828 - [105,79,null,11760]: {1=1375, 2=1363, 3=1365, 4=1367, 5=1369, 6=1371} +Script 829 - [105,79,null,11760]: {2=1215, 1=1305} +Script 830 - [105,79,null,11760]: {1=1307, 2=1309, 3=1311, 4=1313, 5=1315, 6=1317} +Script 831 - [105,79,null,11760]: {2=1434, 1=1377} +Script 832 - [105,79,null,11760]: {1=877, 2=882, 3=884, 4=39, 5=40, 6=41, 7=42, 8=43, 9=44, 10=841, 11=839, 12=837, 13=843, 14=845, 15=1133, 16=1097} +Script 833 - [105,79,null,11760]: {1=877, 2=882, 3=884, 4=39, 5=40, 6=41, 7=42, 8=43, 9=44, 10=841, 11=839, 12=837, 13=843, 14=845, 15=1133, 17=9783, 16=1097} +Script 834 - [105,79,null,11760]: {1=877, 2=882, 3=884, 4=39, 5=40, 6=41, 7=42, 8=43, 9=44, 10=841, 11=839, 12=837, 13=843, 14=845, 15=1133, 17=9784, 16=1097} +Script 835 - [105,79,null,11760]: {1=1379, 2=1389, 3=1381, 4=1383, 5=1385, 6=1387} +Script 836 - [105,79,null,11760]: {1=882, 2=877, 3=841, 4=839, 5=837, 6=39, 7=40, 8=41, 9=42, 10=1349, 11=1353, 12=1363, 13=1365, 14=1369, 15=1307, 17=1311, 16=1309, 19=1315, 18=1313, 20=1317} +Script 837 - [105,79,null,11760]: {1=1265, 2=1267, 3=1269, 4=1273, 5=1271, 6=1275} +Script 838 - [105,79,null,11760]: {1=6, 2=8, 3=10, 4=12, 5=5, 6=4} +Script 839 - [105,79,null,11760]: {1=52, 2=39, 3=40, 4=41, 5=42, 6=43, 7=44, 8=882, 9=884, 10=886, 11=888, 12=890, 13=892, 14=841, 15=843, 17=839, 16=849, 19=847, 18=845} +Script 840 - [105,79,null,11760]: {1=825, 2=826, 3=827, 4=828, 5=829, 6=830, 7=800, 8=801, 9=802, 10=803, 11=804, 12=805} +Script 841 - [105,79,null,11760]: {8=560, 1=554, 2=555, 3=556, 4=557, 5=558, 6=559, 7=562} +Script 842 - [105,79,null,11760]: {1=554, 2=555, 3=556, 4=557, 5=558, 6=559, 7=562, 8=560, 9=9765} +Script 843 - [105,79,null,11760]: {1=554, 2=555, 3=556, 4=557, 5=558, 6=559, 7=562, 8=560, 9=9766} +Script 844 - [105,79,null,11760]: {1=554, 2=555, 3=556, 4=557, 5=558, 6=559, 7=562, 8=560, 9=221, 10=579, 11=1017} +Script 845 - [105,79,null,11760]: {1=556, 2=555, 3=557, 4=554, 5=558, 6=559, 7=562, 8=561, 9=560, 10=563, 11=565, 12=566, 13=1387, 14=1383, 15=1381, 16=1385} +Script 846 - [105,79,null,11760]: {1=4089, 2=4091, 3=4093, 4=4095, 5=4097} +Script 847 - [105,79,null,11760]: {1=4089, 2=4091, 3=4093, 4=4095, 5=4097, 6=9762} +Script 848 - [105,79,null,11760]: {1=4089, 2=4091, 3=4093, 4=4095, 5=4097, 6=9763} +Script 849 - [105,79,null,11760]: {1=1103, 2=1101, 3=1105, 4=1109, 5=1117, 6=1115, 7=1119, 8=1125, 9=1121, 10=1067, 11=1133, 12=1097} +Script 850 - [105,79,null,11760]: {1=1139, 2=1137, 3=1141, 4=1143, 5=1145, 6=1155, 7=1153, 8=1157, 9=1159, 10=1161} +Script 851 - [105,79,null,11760]: {1=1075, 2=1067, 3=1069, 4=1077, 5=1071, 6=1073} +Script 852 - [105,79,null,11760]: {8=1181, 1=1171, 2=1173, 3=1189, 4=1175, 5=1191, 6=1177, 7=1193} +Script 853 - [105,79,null,11760]: {1=1087, 2=1081, 3=1083, 4=1089, 5=1085, 6=1091} +Script 854 - [105,79,null,11760]: {1=1103, 2=1101, 3=1105, 4=1107, 5=1109, 6=1111} +Script 855 - [105,79,null,11760]: {1=1093, 2=1079, 3=1432, 4=1113, 5=1303, 6=1289, 7=1099, 8=1065, 9=1169} +Script 856 - [105,79,null,11760]: {2=1135, 1=1127} +Script 857 - [105,79,null,11760]: {1=1117, 2=1115, 3=1119, 4=1125, 5=1121} +Script 858 - [105,79,null,11760]: {8=1063, 1=1129, 2=1131, 3=1133, 4=1095, 5=1097, 6=1169, 7=1167} +Script 859 - [105,79,null,11760]: {1=1129, 2=1131, 3=1133, 4=1095, 5=1097, 6=1169, 7=1167, 8=1063, 9=9756} +Script 860 - [105,79,null,11760]: {1=1129, 2=1131, 3=1133, 4=1095, 5=1097, 6=1169, 7=1167, 8=1063, 9=9757} +Script 861 - [105,79,null,11760]: {1=1931, 2=1935, 3=1735, 4=1925, 5=1923, 6=1887, 7=590, 8=1755, 9=2347, 10=550, 11=9003} +Script 862 - [105,79,null,11760]: {1=1931, 2=1935, 3=1735, 4=1925, 5=1923, 6=1887, 7=590, 8=1755, 9=2347, 10=550, 11=9003} +Script 863 - [105,79,null,11760]: {1=1931, 2=1935, 3=1735, 4=1925, 5=1923, 6=1887, 7=590, 8=1755, 9=2347, 10=550, 11=9003} +Script 864 - [105,79,null,11760]: {1=1931, 2=1935, 3=1735, 4=1925, 5=1923, 6=1887, 7=590, 8=1755, 9=2347, 10=550, 11=9003} +Script 865 - [105,79,null,11760]: {4=1123, 1=1021, 2=1165, 3=1077} +Script 866 - [105,79,null,11760]: {1=1931, 2=1935, 3=1735, 4=1925, 5=590, 6=1755, 7=2347} +Script 867 - [105,79,null,11760]: {1=1931, 2=1935, 3=1735, 4=1925, 5=1923, 6=1887, 7=590, 8=1755, 9=2347, 10=550, 11=9003} +Script 868 - [105,79,null,11760]: {1=1931, 2=1935, 3=1735, 4=1925, 5=1923, 6=1887, 7=590, 8=1755, 9=2347, 10=550, 11=9003} +Script 869 - [105,79,null,11760]: {1=1931, 2=1935, 3=1735, 4=1925, 5=1923, 6=1887, 7=590, 8=1755, 9=2347} +Script 870 - [105,79,null,11760]: {1=1931, 2=1935, 3=1735, 4=1925, 5=1923, 6=1887, 7=590, 8=1755, 9=2347, 10=550, 11=9003} +Script 871 - [105,79,null,11760]: {1=1931, 2=1935, 3=590, 4=1755, 5=2347, 6=1265, 7=1351} +Script 872 - [105,79,null,11760]: {1=1925, 2=1265, 3=1923, 4=1887, 5=590, 6=1755, 7=2347, 8=954, 9=1931, 10=946} +Script 873 - [105,79,null,11760]: {1=227, 2=1265, 3=1349, 4=2142, 5=590, 6=1759, 7=882, 8=954, 9=970, 10=946} +Script 874 - [105,79,null,11760]: {1=1265, 2=1931, 3=1935, 4=1735, 5=1925, 6=590, 7=1755, 8=2347, 9=954, 10=1933, 11=583, 12=1941, 13=946} +Script 875 - [105,79,null,11760]: {1=1931, 2=1265, 3=1935, 4=1735, 5=1925, 6=590, 7=1755, 8=2347, 9=882, 10=2142} +Script 876 - [105,79,null,11760]: {1=590, 2=36, 3=596, 4=1931, 5=954, 6=1129, 7=1059, 8=1061, 9=2142, 10=2309, 11=229, 12=227, 13=233, 14=175, 15=970, 17=946, 16=973, 19=975, 18=2347, 21=952, 20=1755, 23=1265, 22=1351, 24=1349} +Script 877 - [105,79,null,11760]: {1=590, 2=229, 3=233, 4=1931, 5=1351, 6=1265, 7=1349, 8=1129, 9=1059, 10=1061, 11=2142, 12=2309, 13=952, 14=36, 15=596, 17=2347, 16=1755, 19=973, 18=970, 21=975, 20=227, 22=954} +Script 878 - [105,79,null,11760]: {1=1931, 2=1935, 3=946, 4=1925, 5=590, 6=1755, 7=2347} +Script 879 - [105,79,null,11760]: {4=886, 1=373, 2=2323, 3=121} +Script 880 - [105,79,null,11760]: {1=646, 2=648, 3=650, 4=652, 5=654, 6=656, 7=658, 8=660, 9=662, 10=664, 11=636, 12=638, 13=640, 14=642, 15=644, 17=628, 16=626, 19=632, 18=630, 20=634} +Script 881 - [105,79,null,11760]: {1=882, 2=877, 3=841, 4=839, 5=837, 6=39, 7=40, 8=41, 9=42, 10=1349, 11=1353, 12=1363, 13=1365, 14=1369, 15=1307, 17=1311, 16=1309, 19=1315, 18=1313, 20=1317} +Script 882 - [105,79,null,11760]: null +Script 883 - [105,79,null,11760]: null +Script 884 - [105,79,null,11760]: {8=327, 1=303, 2=307, 3=309, 4=311, 5=301, 6=313, 7=314} +Script 885 - [105,79,null,11760]: {1=2283} +Script 886 - [105,79,null,11760]: {1=303, 2=307, 3=311, 4=301, 5=313, 6=305} +Script 887 - [105,79,null,11760]: {4=1973, 1=2309, 2=1891, 3=1901} +Script 888 - [105,79,null,11760]: {4=1973, 1=2309, 2=1891, 3=1901} +Script 889 - [105,79,null,11760]: {2=314, 1=313} +Script 890 - [105,79,null,11760]: {1=2313, 2=1887, 3=1923, 4=1942, 5=590, 6=1935, 7=1931, 8=1973, 9=1933, 10=1980} +Script 891 - [105,79,null,11760]: {1=1978} +Script 892 - [105,79,null,11760]: {1=2007, 2=946, 3=1550} +Script 893 - [105,79,null,11760]: {1=1933, 2=2132, 3=2138, 4=1965, 5=2309, 6=1973, 7=1985, 8=1982, 9=1942} +Script 894 - [105,79,null,11760]: {4=314, 1=307, 2=309, 3=313} +Script 895 - [105,79,null,11760]: {1=1917, 2=431, 3=1993} +Script 896 - [105,79,null,11760]: {1=1635, 2=1637, 3=1639, 4=1641, 5=1643, 6=1654, 7=1656, 8=1658, 9=1660, 10=1662, 11=1692, 12=1694, 13=1696, 14=1698, 15=1700} +Script 897 - [105,79,null,11760]: {1=1641} +Script 898 - [105,79,null,11760]: {1=1718, 2=1727, 3=1729, 4=1725, 5=1731} +Script 899 - [105,79,null,11760]: {1=1714} +Script 900 - [105,79,null,11760]: {1=1005, 2=1129, 3=1059, 4=1061, 5=1757, 6=1013, 7=1015, 8=1011, 9=1007, 10=950, 11=428, 12=426} +Script 901 - [105,79,null,11760]: {2=1265, 1=2347} +Script 902 - [105,79,null,11760]: {1=1755, 2=1592, 3=1597, 4=1595, 5=1733, 6=1734, 7=1599, 8=2976, 9=5523, 10=9434, 11=11065} +Script 903 - [105,79,null,11760]: {8=5523, 1=1755, 2=1592, 3=1597, 4=1595, 5=1733, 6=1734, 7=1599} +Script 904 - [105,79,null,11760]: {1=1755, 2=1592, 3=1597, 4=1595, 5=1733, 6=1734, 7=1599, 8=2976, 9=5523, 10=9434, 11=11065} +Script 905 - [105,79,null,11760]: {8=5523, 1=1755, 2=1592, 3=1597, 4=1595, 5=1733, 6=1734, 7=1599} +Script 906 - [105,79,null,11760]: {1=229, 2=233, 3=221} +Script 907 - [105,79,null,11760]: {1=36} +Script 908 - [105,79,null,11760]: {1=229, 2=233, 3=221} +Script 909 - [105,79,null,11760]: {1=579, 2=1023, 3=958, 4=948, 5=1733, 6=1734, 7=1059, 8=1061, 9=428, 10=426, 11=1757, 12=1013, 13=1015, 14=1011, 15=1007, 16=1025} +Script 910 - [105,79,null,11760]: {1=229, 2=233, 3=221} +Script 911 - [105,79,null,11760]: {2=958, 1=948} +Script 912 - [105,79,null,11760]: {1=1823, 2=1831, 3=1937, 4=1921, 5=1929, 6=946, 7=2347} +Script 913 - [105,79,null,11760]: {1=1823, 2=1831, 3=1937, 4=1921, 5=1929, 6=946, 7=1833, 8=1835, 9=1837, 10=314, 11=2347, 12=1925, 13=1923, 14=1935, 15=1854, 16=954} +Script 914 - [105,79,null,11760]: {1=299, 2=1590, 3=1542, 4=2368, 5=1052} +Script 915 - [105,79,null,11760]: {1=2520, 2=2522, 3=2524, 4=2526, 5=4613, 6=12844} +Script 916 - [105,79,null,11760]: {1=5341, 2=5343, 3=5329, 4=952, 5=5325, 6=5331, 7=5354, 8=6032, 9=5418, 10=5376, 11=6036, 12=12622} +Script 917 - [105,79,null,11760]: {1=5341, 2=5343, 3=5329, 4=952, 5=5325, 6=5331, 7=5354, 8=6032, 9=5418, 10=5376, 11=6036, 12=12622} +Script 918 - [105,79,null,11760]: {1=5341, 2=5343, 3=5329, 4=952, 5=5325, 6=5331, 7=5354, 8=6032, 9=5418, 10=5376, 11=6036, 12=12622} +Script 919 - [105,79,null,11760]: {1=5341, 2=5343, 3=5329, 4=952, 5=5325, 6=5331, 7=5354, 8=6032, 9=5418, 10=5376, 11=6036, 12=12622} +Script 920 - [105,79,null,11760]: {1=5318, 2=5319, 3=5324, 4=5305, 5=5306, 6=5097, 7=5096, 8=5307, 9=5308, 10=5309} +Script 921 - [118,105,null,0]: {343=1, 204=1, 139=1, 70=1, 138=1, 3=1, 279=1, 4=1, 65=1, 13=1, 17=1, 256=1, 18=1, 83=1, 23=1, 456=1, 159=1, 455=1, 145=1, 24=1, 264=1, 214=1, 391=1, 148=1, 389=1, 31=1, 211=1, 34=1, 441=1, 442=1, 38=1, 235=1, 174=1, 513=1, 233=1, 383=1, 160=1, 41=1, 227=1, 47=1, 254=1, 255=1, 416=1, 57=1, 536=1, 62=1, 301=1, 61=1} +Script 922 - [105,79,null,11760]: null +Script 923 - [0,0,null,0]: null +Script 924 - [111,105,null,0]: {1038=1, 1057=1, 981=1, 1048=1, 1959=1, 1050=1, 1053=1, 1055=1, 1989=1, 1040=1, 962=1, 1042=1, 1961=1, 1044=1, 1046=1} +Script 925 - [105,79,null,11760]: {1=303, 2=311, 3=2309, 4=1931, 5=1927, 6=1733, 7=1734, 8=1917, 9=1785, 10=946} +Script 926 - [105,79,null,11760]: {1=4740} +Script 927 - [105,79,null,11760]: {1=1931, 2=1925, 3=1735, 4=1935, 5=590, 6=1755, 7=2347} +Script 928 - [105,79,null,11760]: {1=5341, 2=5343, 3=5329, 4=952, 5=5325, 6=5331, 7=6032, 8=6036, 9=2026, 10=1480} +Script 929 - [105,79,null,11760]: {2=6625, 1=6615} +Script 930 - [105,79,null,11760]: {4=6605, 1=6615, 2=6625, 3=6591} +Script 931 - [105,79,null,11760]: {1=6615, 2=6625, 3=6627, 4=6621, 5=6631, 6=6591, 7=6605} +Script 932 - [105,79,null,11760]: {1=6615, 2=6625, 3=6627, 4=6621, 5=6631, 6=6591, 7=6605, 8=6601, 9=6603, 10=6607} +Script 933 - [105,79,null,11760]: {1=6615, 2=6625, 3=6627, 4=6621, 5=6631, 6=6623, 7=6633, 8=6617, 9=6619, 10=6629, 11=6591, 12=6605, 13=6601, 14=6603, 15=6607} +Script 934 - [105,79,null,11760]: {1=6615, 2=6625, 3=6627, 4=6621, 5=6631, 6=6623, 7=6633, 8=6617, 9=6619, 10=6629, 11=6591, 12=6605, 13=6601, 14=6603, 15=6607, 17=6589, 16=6613, 19=6587, 18=6611, 21=6599, 20=6609} +Script 935 - [105,79,null,11760]: {1=946, 2=2347, 3=1734, 4=1733, 5=4819, 6=1351, 7=1759} +Script 936 - [105,79,null,11760]: {2=341, 1=331} +Script 937 - [105,79,null,11760]: {2=339, 1=329} +Script 938 - [105,79,null,11760]: {8=1121, 1=1109, 2=1143, 3=1159, 4=1181, 5=1197, 6=1071, 7=1085} +Script 939 - [105,79,null,11760]: {1=1299, 2=1343, 3=1369, 4=3099, 5=1315} +Script 940 - [105,79,null,11760]: {2=438, 1=436} +Script 941 - [105,79,null,11760]: {1=10818, 2=10816, 3=10814} +Script 942 - [105,79,null,11760]: {1=1993, 2=1935, 3=7919} +Script 943 - [105,79,null,11760]: {4=1935, 1=1993, 2=7810, 3=7919} +Script 944 - [105,79,null,11760]: {2=1935, 1=1993} +Script 945 - [105,79,null,11760]: {1=825, 2=826, 3=827, 4=828, 5=829, 6=830, 7=39, 8=40, 9=41, 10=42, 11=43, 12=44} +Script 946 - [105,79,null,11760]: {8=560, 1=554, 2=555, 3=556, 4=557, 5=558, 6=559, 7=562} +Script 947 - [105,79,null,11760]: {1=1931, 2=1935, 3=1735, 4=1925, 5=1923, 6=1887, 7=590, 8=1755, 9=2347, 10=1351, 11=7934} +Script 948 - [105,79,null,11760]: {1=954, 2=2347, 3=1755, 4=946, 5=952, 6=590, 7=36, 8=273, 9=233, 10=1931, 11=1925, 12=1929, 13=1935, 14=1937, 15=229, 17=2019, 16=227, 19=2015, 18=2021, 21=2017, 20=1915, 23=1913, 22=1909, 24=1907} +Script 949 - [105,79,null,11760]: {1=5018, 2=5016, 3=8872, 4=8880, 5=8882} +Script 950 - [105,79,null,11760]: {1=9440, 2=9442, 3=9444, 4=9446, 5=9448, 6=9420, 7=9423, 8=9425, 9=9427} +Script 951 - [105,79,null,11760]: {1=9440, 2=9442, 3=9444, 4=9446, 5=9448, 6=9450, 7=9420, 8=9423, 9=9425, 10=9427, 11=9429} +Script 952 - [105,79,null,11760]: {1=2518} +Script 953 - [105,79,null,11760]: {1=3775, 2=3773, 3=3767, 4=3769, 5=3771, 6=3793, 7=3795, 8=3797, 9=3799, 10=3791, 11=3765, 12=3763, 13=3761, 14=3759, 15=3777, 17=3781, 16=3779, 19=3785, 18=3783, 21=3789, 20=3787} +Script 954 - [105,79,null,11760]: {1=1917, 2=3803, 3=3801} +Script 955 - [105,79,null,11760]: {1=1337, 2=1335, 3=1339, 4=1341, 5=1343, 6=1345, 7=3749, 8=3751, 9=3753, 10=3755} +Script 956 - [105,79,null,11760]: {1=590, 2=954, 3=233, 4=1931, 5=2142, 6=2309, 7=952, 8=36, 9=1755, 10=2347, 11=229, 12=227, 13=1925, 14=1929, 15=1944, 17=1965, 16=1942} +Script 957 - [105,79,null,11760]: {1=303, 2=307, 3=309, 4=311, 5=301, 6=313, 7=314, 8=305, 9=317, 10=327} +Script 958 - [105,79,null,11760]: {2=958, 1=948} +Script 959 - [105,79,null,11760]: {1=314, 2=884, 3=886, 4=40, 5=41} +Script 960 - [105,79,null,11760]: {1=4684, 2=1833, 3=1835, 4=950, 5=1734, 6=1733} +Script 961 - [105,79,null,11760]: {1=1931, 2=1935, 3=1825, 4=1833, 5=1837, 6=1925, 7=4593, 8=4591, 9=970, 10=946, 11=590, 12=1265, 13=2138} +Script 962 - [105,79,null,11760]: {1=1931, 2=1935, 3=1825, 4=1833, 5=1837, 6=1925, 7=4593, 8=4591, 9=1985, 10=2120, 11=1982, 12=1937, 13=1921, 14=1929} +Script 963 - [105,79,null,11760]: {1=1917, 2=2017, 3=1993, 4=2015, 5=2021, 6=1915} +Script 964 - [105,79,null,11760]: {1=7162} +Script 965 - [105,79,null,11760]: {1=2028, 2=2030, 3=2032, 4=2034, 5=2036, 6=2038, 7=2040} +Script 966 - [105,79,null,11760]: {1=2227, 2=2219, 3=2221, 4=2225, 5=2223, 6=2233, 7=2231, 8=2235, 9=2229, 10=2237, 11=2243, 12=2239, 13=2241} +Script 967 - [105,79,null,11760]: {1=4155, 2=4156, 3=4158, 4=4160, 5=4161, 6=4162, 7=4164, 8=4166, 9=4168, 10=4170, 11=4551, 12=6664, 13=6696, 14=6720, 15=7051, 17=7421, 16=7159, 19=8923, 18=7432, 20=10952} +Script 968 - [105,79,null,11760]: {4=2136, 1=2132, 2=2138, 3=2134} +Script 969 - [105,79,null,11760]: {1=2894, 2=2896, 3=2898, 4=2900, 5=2902, 6=2904, 7=2906, 8=2908, 9=2910, 10=2912, 11=2914, 12=2916, 13=2918, 14=2920, 15=2922, 17=2926, 16=2924, 19=2930, 18=2928, 21=2934, 20=2932, 23=2938, 22=2936, 25=2942, 24=2940, 27=1019, 26=1007, 29=1023, 28=1021, 30=1027} +Script 970 - [105,79,null,11760]: {1=1733, 2=1734, 3=1931, 4=1925, 5=1935, 6=590, 7=1755, 8=2347, 9=3377, 10=946} +Script 971 - [105,79,null,11760]: {8=4023, 1=554, 2=555, 3=556, 4=557, 5=563, 6=4008, 7=4006} +Script 972 - [105,79,null,11760]: {4=1329, 1=1321, 2=1323, 3=1325} +Script 973 - [105,79,null,11760]: {1=1321, 2=1323, 3=1325, 4=1329, 5=4587} +Script 974 - [105,79,null,11760]: {4=4014, 1=4012, 2=1963, 3=4016} +Script 975 - [105,79,null,11760]: {8=11065, 1=1755, 2=1592, 3=1597, 4=4020, 5=1733, 6=1734, 7=1759} +Script 976 - [105,79,null,11760]: {1=1931, 2=1935, 3=954, 4=1925, 5=590, 6=2347} +Script 977 - [105,79,null,11760]: {1=1823, 2=1831, 3=1937, 4=1921, 5=1929, 6=1935, 7=1923, 8=1925, 9=1837, 10=1833, 11=1835, 12=946} +Script 978 - [105,79,null,11760]: {1=4627} +Script 979 - [105,79,null,11760]: {1=1969, 2=2023, 3=660, 4=1215, 5=550, 6=583, 7=1941, 8=273, 9=970, 10=975, 11=1599, 12=2976, 13=1823, 14=1837, 15=1854, 17=3377, 16=2524, 19=1909, 18=2894, 21=3801, 20=3787, 23=3424, 22=3678, 25=5, 24=3420} +Script 980 - [105,79,null,11760]: {8=6568, 1=6522, 2=6523, 3=6524, 4=6525, 5=6526, 6=6527, 7=6528} +Script 981 - [105,79,null,11760]: null +Script 982 - [105,79,null,11760]: {8=560, 1=554, 2=555, 3=556, 4=557, 5=558, 6=559, 7=562} +Script 983 - [0,0,null,0]: null +Script 984 - [111,105,null,9999]: {9075=330, 566=615, 565=825, 564=348, 563=567, 562=210, 561=558, 560=465, 558=26, 559=24, 556=26, 557=26, 554=26, 555=26} +Script 985 - [0,0,null,0]: null +Script 986 - [0,0,null,0]: null +Script 987 - [111,105,null,9999]: {562=9, 560=18} +Script 988 - [0,0,null,0]: null +Script 989 - [0,0,null,0]: null +Script 990 - [0,0,null,0]: null +Script 991 - [0,0,null,0]: null +Script 992 - [0,0,null,0]: null +Script 993 - [0,0,null,0]: null +Script 994 - [0,0,null,0]: null +Script 995 - [0,0,null,0]: null +Script 996 - [0,0,null,0]: null +Script 997 - [0,0,null,0]: null +Script 998 - [0,0,null,0]: null +Script 999 - [0,0,null,0]: null +Script 1000 - [0,0,null,0]: null +Script 1001 - [0,0,null,0]: null +Script 1002 - [0,0,null,0]: null +Script 1003 - [0,0,null,0]: null +Script 1004 - [0,0,null,0]: null +Script 1005 - [0,0,null,0]: null +Script 1006 - [0,0,null,0]: null +Script 1007 - [0,0,null,0]: null +Script 1008 - [0,0,null,0]: null +Script 1009 - [0,0,null,0]: null +Script 1010 - [0,0,null,0]: null +Script 1011 - [0,0,null,0]: null +Script 1012 - [0,0,null,0]: null +Script 1013 - [0,0,null,0]: null +Script 1014 - [0,0,null,0]: null +Script 1015 - [0,0,null,0]: null +Script 1016 - [0,0,null,0]: null +Script 1017 - [0,0,null,0]: null +Script 1018 - [0,0,null,0]: null +Script 1019 - [0,0,null,0]: null +Script 1020 - [0,0,null,0]: null +Script 1021 - [0,0,null,0]: null +Script 1022 - [0,0,null,0]: null +Script 1023 - [0,0,null,0]: null +Script 1024 - [0,0,null,0]: null +Script 1025 - [0,0,null,0]: null +Script 1026 - [0,0,null,0]: null +Script 1027 - [0,0,null,0]: null +Script 1028 - [0,0,null,0]: null +Script 1029 - [0,0,null,0]: null +Script 1030 - [0,0,null,0]: null +Script 1031 - [0,0,null,0]: null +Script 1032 - [0,0,null,0]: null +Script 1033 - [0,0,null,0]: null +Script 1034 - [0,0,null,0]: null +Script 1035 - [0,0,null,0]: null +Script 1036 - [0,0,null,0]: null +Script 1037 - [0,0,null,0]: null +Script 1038 - [0,0,null,0]: null +Script 1039 - [0,0,null,0]: null +Script 1040 - [0,0,null,0]: null +Script 1041 - [0,0,null,0]: null +Script 1042 - [0,0,null,0]: null +Script 1043 - [0,0,null,0]: null +Script 1044 - [0,0,null,0]: null +Script 1045 - [0,0,null,0]: null +Script 1046 - [0,0,null,0]: null +Script 1047 - [0,0,null,0]: null +Script 1048 - [0,0,null,0]: null +Script 1049 - [0,0,null,0]: null +Script 1050 - [0,0,null,0]: null +Script 1051 - [0,0,null,0]: null +Script 1052 - [0,0,null,0]: null +Script 1053 - [0,0,null,0]: null +Script 1054 - [0,0,null,0]: null +Script 1055 - [0,0,null,0]: null +Script 1056 - [0,0,null,0]: null +Script 1057 - [0,0,null,0]: null +Script 1058 - [0,0,null,0]: null +Script 1059 - [0,0,null,0]: null +Script 1060 - [0,0,null,0]: null +Script 1061 - [73,105,null,0]: {28180512=1, 12582928=1, 12582940=1, 12582937=1, 12582917=1, 12582915=1, 12582925=1, 12582921=1, 28180481=1, 28180482=1, 28180483=1, 28180484=1, 12582963=1, 28180485=1, 28180486=1, 12582961=1, 28180487=1, 28180488=1, 28180489=1, 28180490=1, 12582973=1, 28180491=1, 28180492=1, 28180493=1, 28180495=1, 12582951=1, 12582948=1, 12582946=1, 12582947=1, 28180503=1, 28180502=1, 28180505=1, 12582958=1, 28180507=1, 28180506=1, 28180509=1, 12582952=1, 28180510=1} +Script 1062 - [0,0,null,0]: null +Script 1063 - [0,0,null,0]: null +Script 1064 - [0,0,null,0]: null +Script 1065 - [0,0,null,0]: null +Script 1066 - [0,0,null,0]: null +Script 1067 - [0,0,null,0]: null +Script 1068 - [0,0,null,0]: null +Script 1069 - [0,0,null,0]: null +Script 1070 - [0,0,null,0]: null +Script 1071 - [0,0,null,0]: null +Script 1072 - [0,0,null,0]: null +Script 1073 - [105,73,null,-1]: {0=6881298, 1=6881314, 2=6881330, 3=6881349, 4=6881368, 5=6881387} +Script 1074 - [105,73,null,-1]: {0=6881313, 1=6881329, 2=6881345, 3=6881364, 4=6881383, 5=6881402} +Script 1075 - [105,73,null,-1]: {0=6881312, 1=6881328, 2=6881344, 3=6881363, 4=6881382, 5=6881401} +Script 1076 - [105,73,null,-1]: {0=6881299, 1=6881315, 2=6881331, 3=6881350, 4=6881369, 5=6881388} +Script 1077 - [105,73,null,-1]: {4=6881384, 5=6881403, 2=6881346, 3=6881365} +Script 1078 - [105,118,null,-1]: {0=517, 1=518, 2=519, 3=520, 4=521, 5=522} +Script 1079 - [105,118,null,-1]: {0=523, 1=524, 2=525, 3=526, 4=527, 5=528} +Script 1080 - [105,73,null,-1]: {0=7143442, 1=7143447, 2=7143452, 3=7143460, 4=7143468, 5=7143476} +Script 1081 - [105,73,null,-1]: {0=7143444, 1=7143449, 2=7143454, 3=7143462, 4=7143470, 5=7143478} +Script 1082 - [105,73,null,-1]: {4=7143471, 5=7143479, 2=7143455, 3=7143463} +Script 1083 - [105,73,null,-1]: {0=6946834, 1=6946848, 2=6946862, 3=6946879, 4=6946896, 5=6946913} +Script 1084 - [105,73,null,-1]: {0=6946835, 1=6946849, 2=6946863, 3=6946880, 4=6946897, 5=6946914} +Script 1085 - [105,73,null,-1]: {4=6946910, 5=6946927, 2=6946876, 3=6946893} +Script 1086 - [0,0,null,0]: null +Script 1087 - [105,79,null,11760]: {1=11814, 2=11816, 3=11818, 4=11820, 5=11822, 6=11824, 7=11826, 8=11828, 9=11830, 10=11832, 11=11834, 12=11836, 13=11838, 14=11840, 15=11842, 17=11846, 16=11844, 19=11850, 18=11848, 21=11854, 20=11852, 23=11858, 22=11856, 25=11862, 24=11860, 27=11866, 26=11864, 29=11870, 28=11868, 31=11960, 30=11872, 34=11876, 35=11878, 32=11962, 33=11874, 38=11884, 39=11886, 36=11880, 37=11882, 42=11892, 43=11894, 40=11888, 41=11890, 46=11900, 47=11902, 44=11896, 45=11898, 51=11910, 50=11908, 49=11906, 48=11904, 55=11918, 54=11916, 53=11914, 52=11912, 59=11926, 58=11924, 57=11922, 56=11920, 63=11934, 62=11932, 61=11930, 60=11928, 68=11944, 69=11946, 70=11967, 64=11936, 65=11938, 66=11940, 67=11942} +Script 1088 - [79,115,shop_dummy,0]: {11836=This item set is made up of adamant full helm, platebody, skirt and kiteshield., 11838=This item set is made up of rune full helm, platebody, legs and kiteshield., 11832=This item set is made up of mithril full helm, platebody, skirt and kiteshield., 11834=This item set is made up of adamant full helm, platebody, legs and kiteshield., 11828=This item set is made up of black full helm, platebody, skirt and kiteshield., 11967=This item set is made up of cannon base, stand, barrels and furnace., 11830=This item set is made up of mithril full helm, platebody, legs and kiteshield., 11960=This item set is made up of hat, top, bottoms, gloves and boots., 11824=This item set is made up of steel full helm, platebody, skirt and kiteshield., 11962=This item set is made up of hat, top, bottoms, gloves and boots., 11826=This item set is made up of black full helm, platebody, legs and kiteshield., 11820=This item set is made up of iron full helm, platebody, skirt and kiteshield., 11940=This item set is made up of full helm, platebody, skirt and kiteshield., 11822=This item set is made up of steel full helm, platebody, legs and kiteshield., 11942=This item set is made up of helm, platebody, legs, boots and gloves., 11816=This item set is made up of bronze full helm, platebody, skirt and kiteshield., 11936=This item set is made up of full helm, platebody, skirt and kiteshield., 11818=This item set is made up of iron full helm, platebody, legs and kiteshield., 11938=This item set is made up of full helm, platebody, legs and kiteshield., 11814=This item set is made up of bronze full helm, platebody, legs and kiteshield., 11944=This item set is made up of helm, body, chaps, boots and gloves., 11946=This item set is made up of helm, top, bottoms, boots and gloves., 11926=This item set is made up of full helm, platebody, legs and shield., 11924=This item set is made up of body, chaps, bracers and coif., 11922=This item set is made up of body, chaps, bracers and coif., 11920=This item set is made up of body, chaps, bracers and coif., 11934=This item set is made up of full helm, platebody, skirt and kiteshield., 11932=This item set is made up of full helm, platebody, skirt and kiteshield., 11930=This item set is made up of full helm, platebody, legs and kiteshield., 11928=This item set is made up of full helm, platebody, legs and kiteshield., 11910=This item set is made up of body and chaps., 11908=This item set is made up of body and chaps., 11906=This item set is made up of hat, robetop and bottoms., 11904=This item set is made up of hat, robetop and bottoms., 11918=This item set is made up of body and chaps., 11916=This item set is made up of body and chaps., 11914=This item set is made up of body and chaps., 11912=This item set is made up of body and chaps., 11896=This item set is made up of full helm, platebody, skirt and kiteshield., 11898=This item set is made up of full helm, platebody, legs and kiteshield., 11900=This item set is made up of full helm, platebody, skirt and kiteshield., 11902=This item set is made up of hat, robetop and bottoms., 11888=This item set is made up of full helm, platebody, skirt and kiteshield., 11890=This item set is made up of full helm, platebody, legs and kiteshield., 11892=This item set is made up of full helm, platebody, skirt and kiteshield., 11894=This item set is made up of full helm, platebody, legs and kiteshield., 11880=This item set is made up of full helm, platebody, skirt and kiteshield., 11882=This item set is made up of full helm, platebody, legs and kiteshield., 11884=This item set is made up of full helm, platebody, skirt and kiteshield., 11886=This item set is made up of full helm, platebody, legs and kiteshield., 11872=This item set is made up of hat, top, bottoms, gloves and boots., 11874=This item set is made up of hat, top, bottoms, gloves and boots., 11876=This item set is made up of helm, body, boots, gauntlets and legs., 11878=This item set is made up of full helm, platebody, legs and kiteshield., 11866=This item set is made up of body, chaps and vambraces., 11864=This item set is made up of body, chaps and vambraces., 11870=This item set is made up of body, chaps and vambraces., 11868=This item set is made up of body, chaps and vambraces., 11858=This item set is made up of helm, body, legs and shield., 11856=This item set is made up of Verac's helm, brassard, plateskirt and flail., 11862=This item set is made up of body, legs, amulet and hat., 11860=This item set is made up of coif, body, chaps and vambraces., 11850=This item set is made up of Guthan's helm, body, chainskirt and spear., 11848=This item set is made up of Dharok's helm, body, legs and greataxe., 11854=This item set is made up of Torag's helm, body, legs and hammers., 11852=This item set is made up of Karil's coif, leather top, leather skirt and crossbow., 11842=This item set is made up of dragon med helm, chainbody, legs., 11840=This item set is made up of rune full helm, platebody, skirt and kiteshield., 11846=This item set is made up of Ahrim's hood, robetop, robeskirt and staff., 11844=This item set is made up of dragon med helm, chainbody, skirt.} +Script 1089 - [111,115,shop_dummy,0]: {11836=This item set is made up of adamant full helm, platebody, skirt and kiteshield., 11838=This item set is made up of rune full helm, platebody, legs and kiteshield., 11832=This item set is made up of mithril full helm, platebody, skirt and kiteshield., 11834=This item set is made up of adamant full helm, platebody, legs and kiteshield., 11828=This item set is made up of black full helm, platebody, skirt and kiteshield., 11967=This item set is made up of cannon base, stand, barrels and furnace., 11830=This item set is made up of mithril full helm, platebody, legs and kiteshield., 11960=This item set is made up of hat, top, bottoms, gloves and boots., 11824=This item set is made up of steel full helm, platebody, skirt and kiteshield., 11962=This item set is made up of hat, top, bottoms, gloves and boots., 11826=This item set is made up of black full helm, platebody, legs and kiteshield., 11820=This item set is made up of iron full helm, platebody, skirt and kiteshield., 11940=This item set is made up of full helm, platebody, skirt and kiteshield., 11822=This item set is made up of steel full helm, platebody, legs and kiteshield., 11942=This item set is made up of helm, platebody, legs, boots and gloves., 11816=This item set is made up of bronze full helm, platebody, skirt and kiteshield., 11936=This item set is made up of full helm, platebody, skirt and kiteshield., 11818=This item set is made up of iron full helm, platebody, legs and kiteshield., 11938=This item set is made up of full helm, platebody, legs and kiteshield., 11814=This item set is made up of bronze full helm, platebody, legs and kiteshield., 11944=This item set is made up of helm, body, chaps, boots and gloves., 11946=This item set is made up of helm, top, bottoms, boots and gloves., 11926=This item set is made up of full helm, platebody, legs and shield., 11924=This item set is made up of body, chaps, bracers and coif., 11922=This item set is made up of body, chaps, bracers and coif., 11920=This item set is made up of body, chaps, bracers and coif., 11934=This item set is made up of full helm, platebody, skirt and kiteshield., 11932=This item set is made up of full helm, platebody, skirt and kiteshield., 11930=This item set is made up of full helm, platebody, legs and kiteshield., 11928=This item set is made up of full helm, platebody, legs and kiteshield., 11910=This item set is made up of body and chaps., 11908=This item set is made up of body and chaps., 11906=This item set is made up of hat, robetop and bottoms., 11904=This item set is made up of hat, robetop and bottoms., 11918=This item set is made up of body and chaps., 11916=This item set is made up of body and chaps., 11914=This item set is made up of body and chaps., 11912=This item set is made up of body and chaps., 11896=This item set is made up of full helm, platebody, skirt and kiteshield., 11898=This item set is made up of full helm, platebody, legs and kiteshield., 11900=This item set is made up of full helm, platebody, skirt and kiteshield., 11902=This item set is made up of hat, robetop and bottoms., 11888=This item set is made up of full helm, platebody, skirt and kiteshield., 11890=This item set is made up of full helm, platebody, legs and kiteshield., 11892=This item set is made up of full helm, platebody, skirt and kiteshield., 11894=This item set is made up of full helm, platebody, legs and kiteshield., 11880=This item set is made up of full helm, platebody, skirt and kiteshield., 11882=This item set is made up of full helm, platebody, legs and kiteshield., 11884=This item set is made up of full helm, platebody, skirt and kiteshield., 11886=This item set is made up of full helm, platebody, legs and kiteshield., 11872=This item set is made up of hat, top, bottoms, gloves and boots., 11874=This item set is made up of hat, top, bottoms, gloves and boots., 11876=This item set is made up of helm, body, greaves, gauntlets and legs, 11878=This item set is made up of full helm, platebody, legs and kiteshield., 11866=This item set is made up of body, chaps and vambraces., 11864=This item set is made up of body, chaps and vambraces., 11870=This item set is made up of body, chaps and vambraces., 11868=This item set is made up of body, chaps and vambraces., 11858=This item set is made up of helm, body, legs and shield., 11856=This item set is made up of Verac's helm, brassard, plateskirt and flail., 11862=This item set is made up of body, legs, amulet and hat., 11860=This item set is made up of coif, body, chaps and vambraces., 11850=This item set is made up of Guthan's helm, body, chainskirt and spear, 11848=This item set is made up of Dharok's helm, body, legs and greataxe, 11854=This item set is made up of Torag's helm, body, legs and hammers., 11852=This item set is made up of Karil's coif, leather top, leather skirt and crossbow., 11842=This item set is made up of dragon med helm, chainbody, legs., 11840=This item set is made up of rune full helm, platebody, skirt and kiteshield., 11846=This item set is made up of Ahrim's hood, robetop, robeskirt and staff., 11844=This item set is made up of dragon med helm, chainbody, skirt.} +Script 1090 - [0,0,null,0]: null +Script 1091 - [0,0,null,0]: null +Script 1092 - [0,0,null,0]: null +Script 1093 - [0,0,null,0]: null +Script 1094 - [0,0,null,0]: null +Script 1095 - [0,0,null,0]: null +Script 1096 - [0,0,null,0]: null +Script 1097 - [0,0,null,0]: null +Script 1098 - [105,110,null,6565]: {1=6568, 2=6571, 3=6574, 4=6577, 5=6580, 6=6583, 7=6586, 8=6589, 9=6592, 10=6595, 11=6598, 12=6601} +Script 1099 - [105,115,,0]: {0=Memorial plaque, 1=Flag, 2=Small gravestone, 3=Ornate gravestone, 4=Font of Life, 5=Stele, 6=Symbol of Saradomin, 7=Symbol of Zamorak, 8=Symbol of Guthix, 9=Symbol of Bandos, 10=Symbol of Armadyl, 11=Ancient symbol, 12=Angel of Death} +Script 1100 - [105,115,,0]: {0=A simple plaque, bearing the name of the deceased.

(Everyone has this by default.), 1=A dignified little flag flutters in the breeze., 2=A simple little gravestone., 3=An ornately carved gravestone., 4=An elaborate font. As water collects in the bowl, it symbolises new life and hope., 5=A monolithic memorial stone bearing a selection of emblems., 6=The four-pointed star is universally recognised as the symbol of Saradomin., 7=This serpentine sigil represents the ruthless Zamorak., 8=Favoured by humans of a mystical or druidic inclination., 9=Followers of Bandos are now scarce, but this symbol is still used by those who remember that violent god., 10=Armadyl's love of winged creatures is represented by this elegant symbol. Little else is remembered of him., 11=Adventurers often request this symbol, although its origin and meaning have become obscure in the centuries since the god wars., 12=The ultimate marker for a grave, this statue evokes intimations of mortality in all who are faced with it.} +Script 1101 - [105,105,null,-1]: {0=0, 1=50, 2=500, 3=5000, 4=50000, 5=50000, 6=50000, 7=50000, 8=50000, 9=50000, 10=50000, 11=50000, 12=500000} +Script 1102 - [0,0,null,0]: null +Script 1103 - [0,0,null,0]: null +Script 1104 - [0,0,null,0]: null +Script 1105 - [0,0,null,0]: null +Script 1106 - [0,0,null,0]: null +Script 1107 - [0,0,null,0]: null +Script 1108 - [0,0,null,0]: null +Script 1109 - [0,0,null,0]: null +Script 1110 - [0,0,null,0]: null +Script 1111 - [0,0,null,0]: null +Script 1112 - [0,0,null,0]: null +Script 1113 - [0,0,null,0]: null +Script 1114 - [0,0,null,0]: null +Script 1115 - [0,0,null,0]: null +Script 1116 - [0,0,null,0]: null +Script 1117 - [0,0,null,0]: null +Script 1118 - [0,0,null,0]: null +Script 1119 - [0,0,null,0]: null +Script 1120 - [0,0,null,0]: null +Script 1121 - [0,0,null,0]: null +Script 1122 - [0,0,null,0]: null +Script 1123 - [0,0,null,0]: null +Script 1124 - [0,0,null,0]: null +Script 1125 - [105,75,null,0]: {1=1, 2=2, 3=3, 4=4, 5=5, 6=6, 7=7, 8=8, 9=91, 10=92, 11=93, 12=94, 13=95, 14=96, 15=97} +Script 1126 - [105,75,null,45]: {1=46, 2=47, 3=48, 4=49, 5=50, 6=51, 7=52, 8=53, 9=54, 10=135, 11=136, 12=137, 13=138, 14=139, 15=140, 17=142, 16=141, 19=144, 18=143, 21=146, 20=145} +Script 1127 - [105,75,null,10]: {1=11, 2=12, 3=13, 4=14, 5=15, 6=16, 7=17, 8=98, 9=99, 10=100, 11=101, 12=102, 13=103, 14=104} +Script 1128 - [105,75,null,18]: {1=19, 2=20, 3=21, 4=22, 5=23, 6=24, 7=25, 8=111, 9=112, 10=113, 11=114, 12=115, 13=116} +Script 1129 - [105,75,null,56]: {1=57, 2=58, 3=59, 4=60, 5=153, 6=154, 7=155, 8=156, 9=157, 10=158} +Script 1130 - [105,75,null,26]: {1=27, 2=28, 3=29, 4=30, 5=31, 6=105, 7=106, 8=107, 9=108, 10=109, 11=110} +Script 1131 - [105,75,null,61]: {1=62, 2=63, 3=64, 4=65, 5=147, 6=148, 7=149, 8=150, 9=151, 10=152} +Script 1132 - [105,75,null,33]: {1=34, 2=84, 3=117, 4=118, 5=119, 6=120, 7=121, 8=122, 9=123, 10=124, 11=125, 12=126} +Script 1133 - [105,75,null,67]: {1=68, 2=127, 3=159, 4=160, 5=161, 6=162, 7=163, 8=164, 9=165, 10=166, 11=167, 12=168} +Script 1134 - [105,75,null,36]: {1=37, 2=38, 3=39, 4=40, 5=85, 6=86, 7=87, 8=88, 9=89, 10=90} +Script 1135 - [105,75,null,70]: {1=71, 2=72, 3=73, 4=74, 5=75, 6=76, 7=77, 8=128, 9=129, 10=130, 11=131, 12=132, 13=133, 14=134} +Script 1136 - [105,75,null,42]: {1=43} +Script 1137 - [105,75,null,79]: {1=80} +Script 1138 - [0,0,null,0]: null +Script 1139 - [0,0,null,0]: null +Script 1140 - [0,0,null,0]: null +Script 1141 - [0,0,null,0]: null +Script 1142 - [0,0,null,0]: null +Script 1143 - [0,0,null,0]: null +Script 1144 - [0,0,null,0]: null +Script 1145 - [0,0,null,0]: null +Script 1146 - [0,0,null,0]: null +Script 1147 - [0,0,null,0]: null +Script 1148 - [0,0,null,0]: null +Script 1149 - [0,0,null,0]: null +Script 1150 - [0,0,null,0]: null +Script 1151 - [105,109,null,-1]: {1=31039, 2=31035, 3=31042, 4=31050, 5=31051, 6=31029, 7=31032, 8=31043, 9=31031, 10=31049, 11=31060, 12=31033} +Script 1152 - [105,109,null,-1]: {1=31036, 2=31046, 3=31056, 4=31027, 5=31026, 6=31045, 7=31048, 8=31058, 9=31028, 10=31041, 11=31044, 12=31057} +Script 1153 - [105,73,null,-1]: {1=17629192, 2=17629193, 3=17629194, 4=17629195, 5=17629196, 6=17629197, 7=17629198, 8=17629199, 9=17629200, 10=17629201, 11=17629202, 12=17629203, 13=17629204, 14=17629205, 15=17629206, 17=17629208, 16=17629207, 19=17629210, 18=17629209, 21=17629212, 20=17629211, 23=17629214, 22=17629213, 25=17629216, 24=17629215, 27=17629218, 26=17629217, 29=17629220, 28=17629219, 31=17629222, 30=17629221, 34=17629225, 35=17629226, 32=17629223, 33=17629224, 36=17629227} +Script 1154 - [105,73,null,-1]: {0=17629186, 1=17629187, 2=17629188} +Script 1155 - [105,109,null,-1]: {0=31054, 1=31038, 2=31055} +Script 1156 - [105,105,null,0]: {0=80, 1=75, 2=60, 3=50} +Script 1157 - [105,105,null,0]: {0=10, 1=10, 2=10, 3=10} +Script 1158 - [105,105,null,0]: {0=95, 1=85, 2=75, 3=60} +Script 1159 - [105,105,null,0]: {0=10, 1=10, 2=15, 3=15} +Script 1160 - [105,105,null,0]: {0=70, 1=65, 2=55, 3=45} +Script 1161 - [105,105,null,0]: {0=10, 1=10, 2=10, 3=5} +Script 1162 - [105,105,null,0]: {0=1, 1=35, 2=70, 3=105} +Script 1163 - [0,0,null,0]: null +Script 1164 - [0,0,null,0]: null +Script 1165 - [0,0,null,0]: null +Script 1166 - [0,0,null,0]: null +Script 1167 - [0,0,null,0]: null +Script 1168 - [0,0,null,0]: null +Script 1169 - [0,0,null,0]: null +Script 1170 - [0,0,null,0]: null +Script 1171 - [0,0,null,0]: null +Script 1172 - [0,0,null,0]: null +Script 1173 - [0,0,null,0]: null +Script 1174 - [0,0,null,0]: null +Script 1175 - [0,0,null,0]: null +Script 1176 - [0,0,null,0]: null +Script 1177 - [0,0,null,0]: null +Script 1178 - [0,0,null,0]: null +Script 1179 - [0,0,null,0]: null +Script 1180 - [0,0,null,0]: null +Script 1181 - [0,0,null,0]: null +Script 1182 - [105,111,null,526]: {1=12047, 2=12043, 3=12059, 4=12019, 5=12009, 6=12778, 7=12049, 8=12055, 9=12808, 10=12067, 11=12063, 12=12091, 13=12800, 14=12053, 15=12065, 17=12818, 16=12021, 19=12798, 18=12780, 21=12087, 20=12814, 23=12051, 22=12071, 25=12097, 24=12095, 27=12101, 26=12099, 29=12105, 28=12103, 31=12816, 30=12107, 34=12007, 35=12035, 32=12041, 33=12061, 38=12812, 39=12784, 36=12027, 37=12531, 42=12085, 43=12037, 40=12810, 41=12023, 46=12123, 47=12031, 44=12015, 45=12045, 51=12057, 50=12820, 49=12033, 48=12029, 55=12782, 54=12011, 53=12069, 52=12792, 59=12804, 58=12802, 57=12013, 56=12794, 63=12788, 62=12017, 61=12025, 60=12806, 68=12079, 69=12081, 70=12083, 71=12039, 64=12776, 65=12073, 66=12075, 67=12077, 76=12093, 77=12790, 72=12786, 73=12089, 74=12796, 75=12822} +Script 1183 - [105,111,null,526]: {1=12231, 2=12225, 3=12236, 4=12255, 5=12226, 6=12286, 7=12256, 8=12240, 9=12290, 10=12245, 11=12241, 12=12237, 13=12276, 14=12227, 15=12246, 17=12282, 16=12232, 19=12283, 18=12284, 21=12243, 20=12285, 23=12229, 22=12228, 25=12266, 24=12266, 27=12266, 26=12266, 29=12266, 28=12266, 31=12288, 30=12266, 34=12238, 35=12258, 32=12235, 33=12259, 38=12274, 39=12289, 36=12257, 37=12233, 42=12239, 43=12234, 40=12275, 41=12267, 46=12252, 47=12253, 44=12254, 45=12265, 51=12249, 50=12244, 49=12230, 48=12262, 55=12291, 54=12247, 53=12242, 52=12279, 59=12273, 58=12271, 57=12269, 56=12261, 63=12277, 62=12260, 61=12263, 60=12272, 68=12264, 69=12264, 70=12264, 71=12250, 64=12270, 65=12264, 66=12264, 67=12264, 76=12251, 77=12278, 72=12280, 73=12268, 74=12281, 75=12287} +Script 1184 - [105,111,null,526]: {1=12377, 2=12293, 3=12353, 4=12359, 5=12355, 6=12409, 7=12381, 8=12357, 9=12415, 10=12351, 11=12327, 12=12313, 13=12395, 14=12375, 15=12321, 17=12407, 16=12303, 19=12407, 18=12407, 21=12301, 20=12407, 23=12371, 22=12335, 25=12311, 24=12311, 27=12311, 26=12311, 29=12311, 28=12311, 31=12411, 30=12311, 34=12345, 35=12299, 32=12337, 33=12347, 38=12391, 39=12419, 36=12325, 37=12363, 42=12317, 43=12297, 40=12393, 41=12329, 46=12367, 47=12369, 44=12361, 45=12365, 51=12349, 50=12333, 49=12319, 48=12309, 55=12417, 54=12339, 53=12331, 52=12401, 59=12389, 58=12389, 57=12385, 56=12343, 63=12397, 62=12295, 61=12323, 60=12389, 68=12341, 69=12341, 70=12341, 71=12373, 64=12387, 65=12341, 66=12341, 67=12341, 76=12383, 77=12399, 72=12405, 73=12379, 74=12403, 75=12413} +Script 1185 - [111,105,null,0]: {12079=66, 12798=34, 12796=93, 12077=56, 12075=46, 12794=77, 12073=36, 12792=73, 12790=99, 12071=41, 12788=83, 12069=74, 12786=89, 12067=23, 12784=57, 12065=32, 12782=76, 12095=43, 12093=96, 12780=34, 12778=17, 12091=28, 12089=92, 12776=85, 12087=40, 12085=61, 12083=86, 12081=76, 12531=56, 12045=64, 12047=1, 12041=47, 12043=4, 12037=62, 12039=88, 12033=69, 12035=54, 12061=49, 12063=25, 12057=71, 12059=10, 12053=31, 12055=19, 12049=18, 12051=42, 12017=83, 12806=79, 12804=79, 12019=13, 12802=79, 12021=33, 12023=58, 12800=29, 12025=80, 12814=34, 12812=57, 12027=55, 12029=68, 12810=57, 12031=67, 12808=22, 12822=95, 12820=70, 12818=34, 12007=52, 12816=46, 12009=16, 12011=75, 12013=78, 12015=63, 12105=43, 12107=43, 12097=43, 12099=43, 12101=43, 12103=43, 12123=66} +Script 1186 - [111,115,You may not check this pouch for its ingredients.,0]: {12079=This pouch requires 1 mithril bar, 1 blue charm and 152 spirit shards., 12798=This pouch requires 1 torcher charm, 1 blue charm and 74 spirit shards., 12796=This pouch requires 1 abyssal charm, 1 green charm and 113 spirit shards., 12077=This pouch requires 1 steel bar, 1 blue charm and 141 spirit shards., 12075=This pouch requires 1 iron bar, 1 blue charm and 125 spirit shards., 12794=This pouch requires 1 talon beast charm, 1 crimson charm and 174 spirit shards., 12073=This pouch requires 1 bronze bar, 1 blue charm and 102 spirit shards., 12792=This pouch requires 1 obsidian charm, 1 blue charm and 195 spirit shards., 12790=This pouch requires 1 steel platebody, 1 crimson charm and 178 spirit shards., 12071=This pouch requires 1 clean guam leaf, 1 green charm and 78 spirit shards., 12788=This pouch requires 1 obsidian charm, 1 blue charm and 219 spirit shards., 12069=This pouch requires one 500g block of granite, 1 crimson charm and 166 spirit shards., 12786=This pouch requires 1 water talisman, 1 blue charm and 222 spirit shards., 12067=This pouch requires 1 raw rat meat, 1 blue charm and 75 spirit shards., 12784=This pouch requires 1 perfect larupia fur, 1 blue charm and 155 spirit shards., 12065=This pouch requires 1 honeycomb, 1 crimson charm and 84 spirit shards., 12782=This pouch requires 1 ruby harvest butterfly, 1 green charm and 141 spirit shards., 12095=This pouch requires 1 cockatrice egg, 1 green charm and 88 spirit shards., 12093=This pouch requires 1 yak hide, 1 crimson charm and 211 spirit shards., 12780=This pouch requires 1 spinner charm, 1 blue charm and 74 spirit shards., 12778=This pouch requires 1 mosquito proboscis, 1 gold charm and 1 spirit shard., 12091=This pouch requires 1 bucket of compost, 1 green charm and 47 spirit shards., 12089=This pouch requires 1 raw rabbit, 1 wolf bones, 1 crimson charm and 203 spirit shards., 12776=This pouch requires 1 swamp lizard, 1 crimson charm and 150 spirit shards., 12087=This pouch requires 1 marigold, 1 gold charm and 11 spirit shards., 12085=This pouch requires 1 pile of goat horn dust, 1 crimson charm and 141 spirit shards., 12083=This pouch requires 1 runite bar, 1 blue charm and 1 spirit shard., 12081=This pouch requires 1 adamantite bar, 1 blue charm and 144 spirit shards., 12531=This pouch requires 1 harpoon, 1 green charm and 109 spirit shards., 12045=This pouch requires 1 bagged plant 1, 1 crimson charm and 128 spirit shards., 12047=This pouch requires 1 set of wolf bones, 1 gold charm and 7 spirit shards., 12041=This pouch requires 1 gold ring, 1 green charm and 88 spirit shards., 12043=This pouch requires 1 raw chicken, 1 gold charm and 8 spirit shards., 12037=This pouch requires 1 abyssal charm, 1 green charm and 119 spirit shards., 12039=This pouch requires 1 unicorn horn, 1 green charm and 140 spirit shards., 12033=This pouch requires 1 banana, 1 green charm and 130 spirit shards., 12035=This pouch requires 1 abyssal charm, 1 green charm and 106 spirit shards., 12061=This pouch requires 1 raw beef, 1 crimson charm and 117 spirit shards., 12063=This pouch requires 1 potato cactus, 1 blue charm and 51 spirit shards., 12057=This pouch requires 1 polar kebbit fur, 1 gold charm and 14 spirit shards., 12059=This pouch requires 1 spider carcass, 1 gold charm and 8 spirit shards., 12053=This pouch requires 1 vampire dust, 1 crimson charm and 81 spirit shards., 12055=This pouch requires 1 pair of bronze claws, 1 crimson charm and 57 spirit shards., 12049=This pouch requires 1 bucket of sand, 1 green charm and 45 spirit shards., 12051=This pouch requires 1 carved evil turnip, 1 crimson charm and 104 spirit shards., 12017=This pouch requires 1 dagannoth hide, 1 crimson charm and 1 spirit shard., 12806=This pouch requires 1 air talisman, 1 water talisman, 1 blue charm and 198 spirit shards., 12804=This pouch requires 1 earth talisman, 1 blue charm and 202 spirit shards., 12019=This pouch requires 1 uncooked thin snail, 1 gold charm and 9 spirit shards., 12802=This pouch requires 1 fire talisman, 1 blue charm and 198 spirit shards., 12021=This pouch requires 1 willow log, 1 green charm and 72 spirit shards., 12023=This pouch requires 1 empty fishbowl, 1 blue charm and 144 spirit shards., 12800=This pouch requires 1 chinchompa, 1 blue charm and 84 spirit shards., 12025=This pouch requires 1 water orb, 1 green charm and 128 spirit shards., 12814=This pouch requires 1 shifter charm, 1 blue charm and 74 spirit shards., 12812=This pouch requires 1 perfect kyatt fur, 1 blue charm and 153 spirit shards., 12027=This pouch requires 1 jug of water, 1 blue charm and 151 spirit shards., 12029=This pouch requires 1 raw shark, 1 green charm and 110 spirit shards., 12810=This pouch requires 1 perfect graahk fur, 1 blue charm and 154 spirit shards., 12031=This pouch requires 1 tortoise shell, 1 gold charm and 1 spirit shard., 12808=This pouch requires 1 obsidian charm, 1 crimson charm and 64 spirit shards., 12822=This pouch requires 1 iron platebody, 1 crimson charm and 198 spirit shards., 12820=This pouch requires 1 pot of flour, 1 crimson charm and 79 spirit shards., 12818=This pouch requires 1 ravager charm, 1 green charm and 74 spirit shards., 12007=This pouch requires 1 raw bird meat, 1 gold charm and 12 spirit shards., 12816=This pouch requires 1 tinderbox, 1 crimson charm and 111 spirit shards., 12009=This pouch requires 1 iron ore, 1 gold charm and 7 spirit shards., 12011=This pouch requires 1 bunch of red flowers, 1 crimson charm and 168 spirit shards., 12013=This pouch requires 1 willow branch, 1 green charm and 124 spirit shards., 12015=This pouch requires 1 snake hide, 1 crimson charm and 116 spirit shards., 12105=This pouch requires 1 coraxatrice egg, 1 green charm and 88 spirit shards., 12107=This pouch requires 1 vulatrice egg, 1 green charm and 88 spirit shards., 12292=This pouch is not yet available., 12097=This pouch requires 1 guthatrice egg, 1 green charm and 88 spirit shards., 12099=This pouch requires 1 saratrice egg, 1 green charm and 88 spirit shards., 12101=This pouch requires 1 zamatrice egg, 1 green charm and 88 spirit shards., 12103=This pouch requires 1 pengatrice egg, 1 green charm and 88 spirit shards., 12123=This pouch requires 1 swamp toad, 1 gold charm and 11 spirit shards.} +Script 1187 - [111,115,Familiar,0]: {12017=Spirit dagannoth pouch, 12806=Ice titan pouch, 12804=Moss titan pouch, 12019=Thorny snail pouch, 12802=Fire titan pouch, 12021=Beaver pouch, 12023=Karamthulhu overlord pouch, 12800=Giant chinchompa pouch, 12025=Hydra pouch, 12814=Void shifter pouch, 12812=Spirit kyatt pouch, 12027=Spirit jelly pouch, 12029=Bunyip pouch, 12810=Spirit graahk pouch, 12031=War tortoise pouch, 12808=Spirit Tz-Kih pouch, 12822=Iron titan pouch, 12820=Ravenous locust pouch, 12818=Void ravager pouch, 12007=Spirit terrorbird pouch, 12816=Pyrelord pouch, 12830=Famine scroll, 12009=Granite crab pouch, 12831=Deadly Claw scroll, 12828=Iron Within scroll, 12011=Praying mantis pouch, 12829=Immense Heat scroll, 12826=Volcanic Strength scroll, 12013=Giant ent pouch, 12827=Essence Shipment scroll, 12824=Titan's Constitution scroll, 12015=Spirit cobra pouch, 12825=Steel of Legends scroll, 12837=Ebon Thunder scroll, 12836=Ambush scroll, 12839=Fireball Assault scroll, 12838=Pester scroll, 12833=Boil scroll, 12832=Swamp Plague scroll, 12835=Goad scroll, 12292=Reserved, 12834=Explode scroll, 12841=Inferno scroll, 12840=Rending scroll, 12079=Mithril minotaur pouch, 12798=Void torcher pouch, 12796=Abyssal titan pouch, 12077=Steel minotaur pouch, 12075=Iron minotaur pouch, 12794=Talon beast pouch, 12073=Bronze minotaur pouch, 12792=Obsidian golem pouch, 12790=Steel titan pouch, 12071=Macaw pouch, 12788=Lava titan pouch, 12069=Granite lobster pouch, 12786=Geyser titan pouch, 12067=Albino rat pouch, 12784=Spirit larupia pouch, 12065=Honey badger pouch, 12782=Forge regent pouch, 12095=Spirit cockatrice pouch, 12093=Pack yak pouch, 12780=Void spinner pouch, 12778=Spirit mosquito pouch, 12091=Compost mound pouch, 12089=Wolpertinger pouch, 12776=Swamp titan pouch, 12533=Stony Shell scroll, 12087=Bull ant pouch, 12085=Smoke devil pouch, 12083=Rune minotaur pouch, 12081=Adamant minotaur pouch, 12531=Ibis pouch, 12045=Stranger plant pouch, 12047=Spirit wolf pouch, 12041=Magpie pouch, 12043=Dreadfowl pouch, 12037=Abyssal lurker pouch, 12039=Unicorn stallion pouch, 12033=Fruit bat pouch, 12035=Abyssal parasite pouch, 12061=Bloated leech pouch, 12063=Spirit kalphite pouch, 12057=Arctic bear pouch, 12059=Spirit spider pouch, 12053=Vampire bat pouch, 12055=Spirit scorpion pouch, 12049=Desert wyrm pouch, 12051=Evil turnip pouch, 12456=Spike Shot scroll, 12457=Acorn Missile scroll, 12458=Petrifying Gaze scroll, 12459=Slime Spray scroll, 12460=Electric Lash scroll, 12461=Bronze Bull Rush scroll, 12462=Iron Bull Rush scroll, 12463=Steel Bull Rush scroll, 12448=Evil Flames scroll, 12449=Crushing Claw scroll, 12450=Mantis Strike scroll, 12451=Arctic Blast scroll, 12452=Toad Bark scroll, 12453=Dissolve scroll, 12454=Abyssal Drain scroll, 12455=Doomsphere Device scroll, 12465=Adamant Bull Rush scroll, 12464=Mithril Bull Rush scroll, 12467=Poisonous Blast scroll, 12466=Rune Bull Rush scroll, 12468=Dust Cloud scroll, 12426=Thieving Fingers scroll, 12427=Abyssal Stealth scroll, 12105=Spirit coraxatrice pouch, 12424=Fish Rain scroll, 12425=Howl scroll, 12107=Spirit vulatrice pouch, 12430=Cheese Feast scroll, 12431=Unburden scroll, 12428=Egg Spawn scroll, 12429=Multichop scroll, 12097=Spirit guthatrice pouch, 12099=Spirit saratrice pouch, 12422=Herbcall scroll, 12423=Fruitfall scroll, 12101=Spirit zamatrice pouch, 12421=Reserved, 12103=Spirit pengatrice pouch, 12443=Call to Arms scroll, 12442=Regrowth scroll, 12441=Tireless Run scroll, 12123=Barker toad pouch, 12440=Generate Compost scroll, 12447=Vampire Touch scroll, 12446=Sandstorm scroll, 12445=Dreadfowl Strike scroll, 12444=Blood Drain scroll, 12435=Winter Storage scroll, 12434=Healing Aura scroll, 12433=Insane Ferocity scroll, 12432=Venom Shot scroll, 12439=Testudo scroll, 12438=Swallow Whole scroll, 12437=Magic Focus scroll, 12436=Ophidian Incubation scroll} +Script 1188 - [105,111,null,526]: {1=12425, 2=12445, 3=12428, 4=12459, 5=12533, 6=12838, 7=12460, 8=12432, 9=12839, 10=12430, 11=12446, 12=12440, 13=12834, 14=12447, 15=12433, 17=12443, 16=12429, 19=12443, 18=12443, 21=12431, 20=12443, 23=12448, 22=12422, 25=12458, 24=12458, 27=12458, 26=12458, 29=12458, 28=12458, 31=12829, 30=12458, 34=12441, 35=12454, 32=12426, 33=12444, 38=12836, 39=12840, 36=12453, 37=12424, 42=12468, 43=12427, 40=12835, 41=12455, 46=12452, 47=12439, 44=12436, 45=12467, 51=12451, 50=12830, 49=12423, 48=12438, 55=12841, 54=12450, 53=12449, 52=12826, 59=12824, 58=12824, 57=12457, 56=12831, 63=12837, 62=12456, 61=12442, 60=12824, 68=12464, 69=12465, 70=12466, 71=12434, 64=12832, 65=12461, 66=12462, 67=12463, 76=12435, 77=12825, 72=12833, 73=12437, 74=12827, 75=12828} +Script 1189 - [111,105,null,0]: {12089=1, 12047=1} +Script 1190 - [111,105,null,0]: {12123=1, 12019=1, 12047=1, 12057=1, 12778=1, 12007=1, 12059=1, 12043=1, 12087=1, 12009=1, 12031=1} +Script 1191 - [111,105,null,0]: {12037=1, 12796=1, 12035=1} +Script 1192 - [111,105,null,0]: {12043=1} +Script 1193 - [111,105,null,0]: {12059=1} +Script 1194 - [111,105,null,0]: {12105=1, 12796=1, 12107=1, 12041=1, 12021=1, 12025=1, 12037=1, 12097=1, 12071=1, 12039=1, 12099=1, 12033=1, 12029=1, 12101=1, 12035=1, 12103=1, 12782=1, 12095=1, 12818=1, 12091=1, 12013=1, 12049=1, 12531=1} +Script 1195 - [111,105,null,0]: {12009=1} +Script 1196 - [111,105,null,0]: {12049=1} +Script 1197 - [111,105,null,0]: {12063=1} +Script 1198 - [111,105,null,0]: {12053=1} +Script 1199 - [111,105,null,0]: {12065=1} +Script 1200 - [111,105,null,0]: {12051=1} +Script 1201 - [111,105,null,0]: {12041=1} +Script 1202 - [111,105,null,0]: {12013=1} +Script 1203 - [111,105,null,0]: {12033=1} +Script 1204 - [111,105,null,0]: {12069=1} +Script 1205 - [111,105,null,0]: {12782=1} +Script 1206 - [111,105,null,0]: {12039=1} +Script 1207 - [111,105,null,0]: {12093=1} +Script 1208 - [111,105,null,0]: {12031=1} +Script 1209 - [111,105,null,0]: {12015=1} +Script 1210 - [111,105,null,0]: {12079=1, 12806=1, 12798=1, 12077=1, 12804=1, 12075=1, 12802=1, 12073=1, 12792=1, 12023=1, 12800=1, 12814=1, 12788=1, 12812=1, 12027=1, 12786=1, 12810=1, 12067=1, 12784=1, 12780=1, 12063=1, 12083=1, 12081=1} +Script 1211 - [111,105,null,0]: {12023=1} +Script 1212 - [111,105,null,0]: {12089=1} +Script 1213 - [0,0,null,0]: null +Script 1214 - [111,105,null,0]: {12776=150, 12794=50} +Script 1215 - [111,105,null,0]: {12794=1} +Script 1216 - [111,105,null,0]: {12091=1} +Script 1217 - [111,105,null,0]: {12019=1} +Script 1218 - [111,105,null,0]: {12017=1, 12045=1, 12794=1, 12790=1, 12069=1, 12065=1, 12808=1, 12822=1, 12061=1, 12093=1, 12820=1, 12089=1, 12776=1, 12816=1, 12053=1, 12011=1, 12085=1, 12055=1, 12015=1, 12051=1} +Script 1219 - [111,105,null,0]: {12095=1} +Script 1220 - [111,105,null,0]: {12097=1} +Script 1221 - [111,105,null,0]: {12099=1} +Script 1222 - [111,105,null,0]: {12101=1} +Script 1223 - [111,105,null,0]: {12103=1} +Script 1224 - [111,105,null,0]: {12105=1} +Script 1225 - [111,105,null,0]: {12107=1} +Script 1226 - [111,105,null,0]: {12806=1, 12786=1} +Script 1227 - [111,105,null,0]: null +Script 1228 - [111,105,null,0]: {12029=1} +Script 1229 - [111,105,null,0]: {12812=1} +Script 1230 - [111,105,null,0]: {12810=1} +Script 1231 - [111,105,null,0]: {12077=1} +Script 1232 - [111,105,null,0]: {12788=1, 12792=1, 12808=1} +Script 1233 - [111,105,null,0]: {12818=1} +Script 1234 - [111,105,null,0]: {12814=1} +Script 1235 - [111,105,null,0]: {12780=1} +Script 1236 - [111,105,null,0]: {12798=1} +Script 1237 - [111,105,null,0]: {12814=1} +Script 1238 - [111,105,null,0]: {12778=1} +Script 1239 - [111,105,null,0]: {12784=1} +Script 1240 - [111,105,null,0]: {12075=1} +Script 1241 - [111,105,null,0]: {12055=1} +Script 1242 - [111,105,null,0]: {12067=1} +Script 1243 - [111,105,null,0]: {12087=1} +Script 1244 - [111,105,null,0]: {12820=1} +Script 1245 - [111,105,null,0]: {12021=1} +Script 1246 - [111,105,null,0]: {12816=1} +Script 1247 - [111,105,null,0]: {12061=1} +Script 1248 - [111,105,null,0]: null +Script 1249 - [111,105,null,0]: {12071=1} +Script 1250 - [111,105,null,0]: {12800=1} +Script 1251 - [111,105,null,0]: {12007=1} +Script 1252 - [111,105,null,0]: {12027=1} +Script 1253 - [111,105,null,0]: {12531=1} +Script 1254 - [111,105,null,0]: {12085=1} +Script 1255 - [111,105,null,0]: {12045=1} +Script 1256 - [111,105,null,0]: {12057=1} +Script 1257 - [111,105,null,0]: {12011=1} +Script 1258 - [111,105,null,0]: {12806=1} +Script 1259 - [111,105,null,0]: {12804=1} +Script 1260 - [111,105,null,0]: {12802=1} +Script 1261 - [111,105,null,0]: {12025=1} +Script 1262 - [111,105,null,0]: {12017=1} +Script 1263 - [111,105,null,0]: {12776=1} +Script 1264 - [111,105,null,0]: {12073=1} +Script 1265 - [111,105,null,0]: {12079=1} +Script 1266 - [111,105,null,0]: {12081=1} +Script 1267 - [111,105,null,0]: {12083=1} +Script 1268 - [111,105,null,0]: {12822=1} +Script 1269 - [111,105,null,0]: {12790=1} +Script 1270 - [111,105,null,0]: {12079=152, 12798=74, 12796=113, 12077=141, 12075=125, 12794=174, 12073=102, 12792=195, 12790=178, 12071=78, 12788=219, 12069=166, 12786=222, 12067=75, 12784=155, 12065=84, 12782=141, 12095=88, 12093=211, 12780=74, 12778=1, 12091=47, 12089=203, 12776=150, 12087=11, 12085=141, 12083=1, 12081=144, 12531=109, 12045=128, 12047=7, 12041=88, 12043=8, 12037=119, 12039=140, 12033=130, 12035=106, 12061=117, 12063=51, 12057=14, 12059=8, 12053=81, 12055=57, 12049=45, 12051=104, 12017=1, 12806=198, 12804=202, 12019=9, 12802=198, 12021=72, 12023=144, 12800=84, 12025=128, 12814=74, 12812=153, 12027=151, 12029=110, 12810=154, 12031=1, 12808=64, 12822=198, 12820=79, 12818=74, 12007=12, 12816=111, 12009=7, 12011=168, 12013=124, 12015=116, 12105=88, 12107=88, 12097=88, 12099=88, 12101=88, 12103=88, 12123=11} +Script 1271 - [0,0,null,0]: null +Script 1272 - [0,0,null,0]: null +Script 1273 - [0,0,null,0]: null +Script 1274 - [0,0,null,0]: null +Script 1275 - [105,65,null,8374]: {1=4844, 2=6824, 3=8378, 4=8374, 5=5665, 6=8476, 7=6552, 8=7639, 9=8383, 10=4844, 11=8394, 12=8397, 13=8418, 14=8412, 15=8402, 17=8420, 16=8406, 19=8485, 18=8433, 21=8430, 20=8425, 23=8454, 22=8464, 25=8442, 24=8458, 27=8444, 26=8437, 29=8488, 28=8450, 31=8387, 30=8474, 34=8469, 32=8480, 33=8493} +Script 1276 - [105,65,null,8373]: {1=4846, 2=8, 3=8376, 4=8373, 5=5661, 6=8477, 7=6551, 8=7637, 9=8381, 10=8390, 11=8392, 12=8396, 13=8416, 14=8413, 15=8399, 17=8421, 16=8404, 19=8483, 18=8431, 21=8429, 20=8423, 23=8452, 22=8463, 25=8440, 24=8456, 27=8445, 26=8436, 29=8487, 28=8448, 31=8385, 30=8473, 34=8467, 32=8482, 33=8491} +Script 1277 - [105,111,null,526]: {1=12047, 2=12043, 3=12059, 4=12019, 5=12009, 6=12778, 7=12049, 8=12055, 9=12808, 10=12067, 11=12063, 12=12091, 13=12800, 14=12053, 15=12065, 17=12818, 16=12021, 19=12798, 18=12780, 21=12087, 20=12814, 23=12051, 22=12071, 25=12097, 24=12095, 27=12101, 26=12099, 29=12105, 28=12103, 31=12816, 30=12107, 34=12007, 35=12035, 32=12041, 33=12061, 38=12812, 39=12784, 36=12027, 37=12531, 42=12085, 43=12037, 40=12810, 41=12023, 46=12123, 47=12031, 44=12015, 45=12045, 51=12057, 50=12820, 49=12033, 48=12029, 55=12782, 54=12011, 53=12069, 52=12792, 59=12804, 58=12802, 57=12013, 56=12794, 63=12788, 62=12017, 61=12025, 60=12806, 68=12079, 69=12081, 70=12083, 71=12039, 64=12776, 65=12073, 66=12075, 67=12077, 76=12093, 77=12790, 72=12786, 73=12089, 74=12796, 75=12822} +Script 1278 - [105,115,Animal,0]: {1=Spirit wolf, 2=Dreadfowl, 3=Desert wyrm, 4=Spirit spider, 5=Thorny snail, 6=Granite crab, 7=Spirit scorpion, 8=Spirit Tz-Kih, 9=Albino rat, 10=Spirit kalphite, 11=Compost mound, 12=Ravenous locust, 13=Vampire bat, 14=Honey badger, 15=Beaver, 17=Void spinner, 16=Void ravager, 19=Void torcher, 18=Void shifter, 21=Bull ant, 20=Mosquito, 23=Evil turnip, 22=Macaw, 25=Spirit guthatrice, 24=Spirit cockatrice, 27=Spirit zamatrice, 26=Spirit saratrice, 29=Spirit coraxatrice, 28=Spirit pengatrice, 30=Spirit vulatrice, 34=Bloated leech, 35=Giant chinchompa, 32=Pyrelord, 33=Magpie, 38=Spirit jelly, 39=Ibis, 36=Spirit terrorbird, 37=Abyssal parasite, 42=Spirit graahk, 43=Karamthulhu overlord, 40=Spirit kyatt, 41=Spirit larupia, 46=Spirit cobra, 47=Stranger plant, 44=Smoke devil, 45=Abyssal lurker, 51=Fruit bat, 50=Bunyip, 49=War tortoise, 48=Barker toad, 55=Praying mantis, 54=Obsidian golem, 53=Arctic bear, 52=Granite lobster, 59=Fire titan, 58=Giant ent, 57=Talon beast, 56=Forge regent, 63=Spirit dagannoth, 62=Hydra, 61=Moss titan, 60=Ice titan, 68=Steel minotaur, 69=Mithril minotaur, 70=Adamant minotaur, 71=Rune minotaur, 64=Lava titan, 65=Swamp titan, 66=Bronze minotaur, 67=Iron minotaur, 76=Iron titan, 77=Pack yak, 78=Steel titan, 72=Unicorn stallion, 73=Geyser titan, 74=Wolpertinger, 75=Abyssal titan} +Script 1279 - [110,115,Animal,0]: {6813=Bunyip, 6815=War tortoise, 6809=Karamthulhu overlord, 6808=Beaver, 6811=Hydra, 6804=Spirit dagannoth, 6806=Thorny snail, 6800=Giant ent, 6802=Spirit cobra, 6796=Granite crab, 6798=Praying mantis, 6794=Spirit terrorbird, 6847=Albino rat, 6845=Honey badger, 6843=Bloated leech, 7377=Pyrelord, 6841=Spirit spider, 6839=Arctic bear, 6837=Spirit scorpion, 6835=Vampire bat, 6833=Evil turnip, 7365=Spirit kyatt, 6831=Desert wyrm, 7367=Void shifter, 6829=Spirit wolf, 6827=Stranger plant, 7361=Spirit Tz-Kih, 6824=Magpie, 7363=Spirit graahk, 6825=Dreadfowl, 6822=Unicorn stallion, 7372=Ravenous locust, 6820=Abyssal lurker, 7375=Iron titan, 6818=Abyssal parasite, 7370=Void ravager, 6817=Fruit bat, 6873=Pack yak, 7347=Talon beast, 7345=Obsidian golem, 6875=Spirit cockatrice, 6877=Spirit guthatrice, 7351=Void torcher, 7349=Abyssal titan, 6879=Spirit saratrice, 7355=Fire titan, 6865=Smoke devil, 7353=Giant chinchompa, 6867=Bull ant, 6869=Wolpertinger, 7359=Ice titan, 6991=Ibis, 7357=Moss titan, 6871=Compost mound, 6994=Spirit kalphite, 6857=Steel minotaur, 7331=Spirit mosquito, 6992=Spirit jelly, 6859=Mithril minotaur, 7329=Swamp titan, 6861=Adamant minotaur, 7335=Forge regent, 6863=Rune minotaur, 7333=Void spinner, 7339=Geyser titan, 6849=Granite lobster, 7337=Spirit larupia, 6851=Macaw, 7343=Steel titan, 6853=Bronze minotaur, 6855=Iron minotaur, 7341=Lava titan, 6889=Barker toad, 6883=Spirit pengatrice, 6881=Spirit zamatrice, 6887=Spirit vulatrice, 6885=Spirit coraxatrice} +Script 1280 - [0,0,null,0]: null +Script 1281 - [0,0,null,0]: null +Script 1282 - [110,73,null,43384878]: {6813=43384984, 6815=43384948, 6809=43384966, 6808=43384920, 6811=43384976, 6804=43384978, 6806=43384950, 6800=43384970, 6802=43384946, 6796=43384906, 6798=43384926, 6794=43384960, 6847=43384934, 6845=43384936, 6843=43384962, 7377=43385016, 6841=43384914, 6839=43384940, 6837=43384932, 6835=43384902, 6833=43384908, 7365=43385000, 6831=43384952, 7367=43384988, 6829=43384898, 6827=43384972, 7361=43385010, 6824=43384912, 7363=43384998, 6825=43384900, 6822=43384944, 7372=43384928, 6820=43384918, 7375=43385014, 6818=43384956, 7370=43384988, 6817=43384910, 6873=43384942, 7347=43384974, 7345=43385004, 6875=43384958, 6877=43384958, 7351=43384988, 7349=43385006, 6879=43384958, 7355=43384990, 6865=43384964, 7353=43384996, 6867=43384922, 6869=43384982, 7359=43384990, 6991=43384916, 7357=43384990, 6871=43384968, 6994=43384930, 6857=43384980, 7331=43385008, 6992=43384954, 6859=43384980, 7329=43384986, 6861=43384980, 7335=43385018, 6863=43384980, 7333=43384988, 7339=43384992, 6849=43384924, 7337=43385012, 6851=43384904, 7343=43384994, 6853=43384980, 6855=43384980, 7341=43385002, 6889=43384938, 6883=43384958, 6881=43384958, 6887=43384958, 6885=43384958} +Script 1283 - [111,111,null,526]: {12079=12464, 12798=12443, 12796=12827, 12077=12463, 12075=12462, 12794=12831, 12073=12461, 12792=12826, 12790=12825, 12071=12422, 12788=12837, 12069=12449, 12786=12833, 12067=12430, 12784=12840, 12065=12433, 12782=12841, 12095=12458, 12093=12435, 12780=12443, 12778=12838, 12091=12440, 12089=12437, 12776=12832, 12087=12431, 12085=12468, 12083=12466, 12081=12465, 12531=12424, 12045=12467, 12047=12425, 12041=12426, 12043=12445, 12037=12427, 12039=12434, 12033=12423, 12035=12454, 12061=12444, 12063=12446, 12057=12451, 12059=12428, 12053=12447, 12055=12432, 12049=12460, 12051=12448, 12017=12456, 12806=12824, 12804=12824, 12019=12459, 12802=12824, 12021=12429, 12023=12455, 12800=12834, 12025=12442, 12814=12443, 12812=12836, 12027=12453, 12029=12438, 12810=12835, 12031=12439, 12808=12839, 12822=12828, 12820=12830, 12818=12443, 12007=12441, 12816=12829, 12009=12533, 12011=12450, 12013=12457, 12015=12436, 12105=12458, 12107=12458, 12097=12458, 12099=12458, 12101=12458, 12103=12458, 12123=12452} +Script 1284 - [0,0,null,0]: null +Script 1285 - [0,0,null,0]: null +Script 1286 - [105,79,null,11760]: {1=12130, 2=12125, 3=12127} +Script 1287 - [105,79,null,11760]: {4=12207, 1=12155, 2=12183, 3=12204} +Script 1288 - [0,0,null,0]: null +Script 1289 - [0,0,null,0]: null +Script 1290 - [0,0,null,0]: null +Script 1291 - [0,0,null,0]: null +Script 1292 - [0,0,null,0]: null +Script 1293 - [0,0,null,0]: null +Script 1294 - [0,0,null,0]: null +Script 1295 - [0,0,null,0]: null +Script 1296 - [0,0,null,0]: null +Script 1297 - [0,0,null,0]: null +Script 1298 - [0,0,null,0]: null +Script 1299 - [0,0,null,0]: null +Script 1300 - [0,0,null,0]: null +Script 1301 - [0,0,null,0]: null +Script 1302 - [0,0,null,0]: null +Script 1303 - [0,0,null,0]: null +Script 1304 - [0,0,null,0]: null +Script 1305 - [0,0,null,0]: null +Script 1306 - [0,0,null,0]: null +Script 1307 - [0,0,null,0]: null +Script 1308 - [0,0,null,0]: null +Script 1309 - [0,0,null,0]: null +Script 1310 - [0,0,null,0]: null +Script 1311 - [0,0,null,0]: null +Script 1312 - [0,0,null,0]: null +Script 1313 - [0,0,null,0]: null +Script 1314 - [0,0,null,0]: null +Script 1315 - [0,0,null,0]: null +Script 1316 - [0,0,null,0]: null +Script 1317 - [111,105,null,0]: {12123=1} +Script 1318 - [0,0,null,0]: null +Script 1319 - [0,0,null,0]: null +Script 1320 - [111,110,null,6988]: {12079=6859, 12798=7351, 12796=7349, 12077=6857, 12075=6855, 12794=7347, 12073=6853, 12792=7345, 12790=7343, 12071=6851, 12788=7341, 12069=6849, 12786=7339, 12067=6847, 12784=7337, 12065=6845, 12782=7335, 12095=6875, 12093=6873, 12780=7333, 12778=7331, 12091=6871, 12089=6869, 12776=7329, 12087=6867, 12085=6865, 12083=6863, 12081=6861, 12531=6991, 12045=6827, 12047=6829, 12041=6824, 12043=6825, 12037=6820, 12039=6822, 12033=6817, 12035=6818, 12061=6843, 12063=6994, 12057=6839, 12059=6841, 12053=6835, 12055=6837, 12049=6831, 12051=6833, 12017=6804, 12806=7359, 12804=7357, 12019=6806, 12802=7355, 12021=6808, 12023=6809, 12800=7353, 12025=6811, 12814=7367, 12812=7365, 12027=6992, 12029=6813, 12810=7363, 12031=6815, 12808=7361, 12822=7375, 12820=7372, 12818=7370, 12007=6794, 12816=7377, 12009=6796, 12011=6798, 12013=6800, 12015=6802, 12105=6885, 12107=6887, 12097=6877, 12099=6879, 12101=6881, 12103=6883, 12123=6889} +Script 1321 - [105,79,null,11760]: {1=2134, 2=2132, 3=2136, 4=2138, 5=3226, 6=9978, 7=2876, 8=2142, 9=2140, 10=3228} +Script 1322 - [0,0,null,0]: null +Script 1323 - [0,0,null,0]: null +Script 1324 - [0,0,null,0]: null +Script 1325 - [0,0,null,0]: null +Script 1326 - [0,0,null,0]: null +Script 1327 - [105,79,null,11760]: {1=590, 2=2866, 3=2878, 4=314, 5=1351, 6=954, 7=1931, 8=1925, 9=2347, 10=946, 11=12561, 12=12563, 13=12565} +Script 1328 - [0,0,null,0]: null +Script 1329 - [0,0,null,0]: null +Script 1330 - [0,0,null,0]: null +Script 1331 - [0,0,null,0]: null +Script 1332 - [0,0,null,0]: null +Script 1333 - [0,0,null,0]: null +Script 1334 - [0,0,null,0]: null +Script 1335 - [0,0,null,0]: null +Script 1336 - [0,0,null,0]: null +Script 1337 - [0,0,null,0]: null +Script 1338 - [0,0,null,0]: null +Script 1339 - [0,0,null,0]: null +Script 1340 - [0,0,null,0]: null +Script 1341 - [0,0,null,0]: null +Script 1342 - [0,0,null,0]: null +Script 1343 - [0,0,null,0]: null +Script 1344 - [0,0,null,0]: null +Script 1345 - [105,115, ,0]: {0=Adventure, 1=Al Kharid, 2=Alone, 3=Ambient Jungle, 4=Arabian, 5=Arabian2, 6=Arabian3, 7=Arabique, 8=Army of Darkness, 9=Arrival, 10=Attack1, 11=Attack2, 12=Attack3, 13=Attack4, 14=Attack5, 15=Attack6, 17=Autumn Voyage, 16=Attention, 19=Ballad of Enchantment, 18=Background, 21=Beyond, 20=Baroque, 23=Book of Spells, 22=Big Chords, 25=Cave Background, 24=Camelot, 27=Chain of Command, 26=Cavern, 29=Crystal Sword, 28=Crystal Cave, 31=Dark, 30=Dangerous, 34=Doorways, 35=Dream, 32=Deep Wildy, 33=Desert Voyage, 38=Emotion, 39=Emperor, 36=Dunjun, 37=Egypt, 42=Expedition, 43=Faerie, 40=Expanse, 41=Expecting, 46=Fishing, 47=Flute Salad, 44=Fanfare, 45=Fanfare3, 51=Gnome King, 50=Garden, 49=Gaol, 48=Forever, 55=Goblin Village, 54=Gnome Village2, 53=Gnome Village, 52=Dwarf Theme, 59=High Seas, 58=Harmony, 57=Greatness, 56=Gnomeball, 63=Inspiration, 62=In the Manor, 61=Iban, 60=Horizon, 68=Jungly2, 69=Jungly3, 70=Knightly, 71=Lasting, 64=Intrepid, 65=Jolly-R, 66=Jungle Island, 67=Jungly1, 76=Long Way Home, 77=Lullaby, 78=Mage Arena, 79=Magic Dance, 72=Legion, 73=Lightness, 74=Lightwalk, 75=Long Ago, 85=Miracle Dance, 84=Miles Away, 87=Moody, 86=Monarch Waltz, 81=March, 80=Magical Journey, 83=Mellow, 82=Medieval, 93=Parade, 92=Overture, 95=Regal, 94=Quest, 89=Newbie Melody, 88=Neverland, 91=Oriental, 90=Nightfall, 102=Scape Cave, 103=Scape Original, 100=Rune Essence, 101=Sad Meadow, 98=Riverside, 99=Royale, 96=Reggae, 97=Reggae2, 110=Shine, 111=Soundscape, 108=Serenade, 109=Serene, 106=Sea Shanty, 107=Sea Shanty2, 104=Scape Sad, 105=Scape Wild, 119=Talking Forest, 118=Still Night, 117=Start, 116=Starlight, 115=Spookyjungle, 114=Spooky, 113=Splendour, 112=Spirit, 127=Tribal Background, 126=Tree Spirits, 125=Trawler Minor, 124=Trawler, 123=Theme, 122=The Tower, 121=The Shadow, 120=The Desert, 137=Vision, 136=Venture, 139=Voyage, 138=Voodoo Cult, 141=Waterfall, 140=Wander, 143=Wilderness2, 142=Wilderness, 129=Tribal2, 128=Tribal, 131=Troubled, 130=Trinity, 133=Unknown Land, 132=Underground, 135=Upcoming, 134=Underground Pass, 152=Scape Scared, 153=Scape Santa, 154=Land of Snow, 155=Shaping Up, 156=Exam Conditions, 157=Roots and Flutes, 158=Incarceration, 159=Scape Soft, 144=Wilderness3, 145=Witching, 146=Wonder, 147=Wonderous, 148=Workshop, 149=Lonesome, 150=Scape Main, 151=Ground Scape, 171=Nomad, 170=Undercurrent, 169=Landlubber, 168=Venture2, 175=Close Quarters, 174=Heart and Mind, 173=Cellar Song, 172=Zealot, 163=Tomorrow, 162=Fanfare2, 161=Yesteryear, 160=Shining, 167=Harmony2, 166=Wild Isle, 165=Ice Melody, 164=Duel Arena, 186=Cursed, 187=Understanding, 184=Mausoleum, 185=Forbidden, 190=Kingdom, 191=Hermit, 188=Principality, 189=Tremble, 178=Chompy Hunt, 179=Twilight, 176=Escape, 177=Grumpy, 182=Village, 183=Bone Dance, 180=Morytania, 181=Dead Quiet, 205=Meridian, 204=Lost Soul, 207=Overpass, 206=Woodland, 201=Aztec, 200=Artistry, 203=Forest, 202=Elven Mist, 197=Natural, 196=Time Out, 199=Waterlogged, 198=Grotto, 193=Stagnant, 192=La Mort, 195=Stratosphere, 194=Breeze, 220=Exposed, 221=Well of Voyage, 222=Haunted Mine, 223=Righteousness, 216=Bone Dry, 217=Competition, 218=Spooky2, 219=Everywhere, 212=Insect Queen, 213=Mad Eadgar, 214=Bandit Camp, 215=Sunburn, 208=Contest, 209=Sojourn, 210=Crystal Castle, 211=Marzipan, 239=Monkey Madness, 238=Technology, 237=Warrior, 236=Frostbite, 235=Legend, 234=Stranded, 233=Borderland, 232=Saga, 231=Rellekka, 230=Deadlands, 229=Lair, 228=Shadowland, 227=Etcetera, 226=Miscellania, 225=Chamber, 224=Deep Down, 254=Hell's Bells, 255=The Navigator, 252=Goblin Game, 253=Out of the Deep, 250=Stillness, 251=Lighthouse, 248=Melodrama, 249=Ready For Battle, 246=Find My Way, 247=Castlewars, 244=Suspicious, 245=Showdown, 242=Island Life, 243=Temple, 240=Anywhere, 241=Marooned, 275=Dynasty, 274=Barking Mad, 273=Fruits de Mer, 272=Monster Melee, 279=Settlement, 278=The Other Side, 277=Phasmatys, 276=Shipwrecked, 283=Sarcophagus, 282=Scarab, 281=Dragontooth Island, 280=Cave of Beasts, 287=Pathways, 286=Karamja Jam, 285=7th Realm, 284=Down Below, 258=Complication, 259=Down to Earth, 256=Wildwood, 257=Barbarianism, 262=Pirates of Peril, 263=Dangerous Road, 260=Courage, 261=Superstition, 266=Tiptoe, 267=The Terrible Tower, 264=Romancing the Crone, 265=Faithless, 270=Body Parts, 271=Fenkenstrain's Refrain, 268=Masquerade, 269=The Slayer, 305=Bish Bash Bosh, 304=Cave of the Goblins, 307=Path of Peril, 306=Zogre Dance, 309=Tale of Keldagrim, 308=Wayward, 311=Tears of Guthix, 310=Land of the Dwarves, 313=The Rogues' Den, 312=Romper Chomper, 315=The Lost Melody, 314=The Far Side, 317=Into the Abyss, 316=Evil Bob's Island, 319=The Power of Tears, 318=The Quiz Master, 288=Eagle Peak, 289=Time to Mine, 290=In Between, 291=Claustrophobia, 292=Far Away, 293=Fight or Flight, 294=Temple of Light, 295=The Golem, 296=Forgotten, 297=Throne of the Demon, 298=Dance of the Undead, 299=Dangerous Way, 300=City of the Dead, 301=Hypnotized, 302=Sphinx, 303=Mirage, 343=Jungle Troubles, 342=The Cellar Dwellers, 341=Dead Can Dance, 340=Wild Side, 339=TzHaar!, 338=Brew Hoo Hoo, 337=Strange Place, 336=Frogland, 351=Aye Car Rum Ba, 350=Homescape, 349=Rat Hunt, 348=Sarim's Vermin, 347=Bubble and Squeak, 346=The Noble Rodent, 345=Rat a Tat Tat, 344=Catch Me If You Can, 326=Forgettable Melody, 327=Right On Track, 324=The Chosen, 325=Have a Blast, 322=The Lost Tribe, 323=Corporal Punishment, 321=Pheasant Peasant, 334=Fire and Brimstone, 335=In the Pits, 332=The Genie, 333=Desert Heat, 330=The Desolate Isle, 331=Spirits of Elid, 328=Over To Nardah, 329=The Monsters Below, 373=Mind Over Matter, 372=Roll the Bones, 374=Golden Touch, 369=Woe of the Wyvern, 368=Victory is Mine, 371=Diango's Little Helpers, 370=In the Brine, 381=Lament, 380=Last Stand, 383=Scarabaeoidea, 382=Poles Apart, 377=Scape Hunter, 376=The Enchanter, 379=Cabin Fever, 378=Making Waves, 356=Land Down Under, 357=Meddling Kids, 358=Corridors of Power, 359=Slither and Thither, 352=Blistering Barnacles, 353=Distant Land, 354=Fangs For the Memory, 355=Pharaoh's Tomb, 364=Grip of the Talon, 365=Dagannoth Dawn, 366=Xenophobe, 367=Title Fight, 360=In the Clink, 361=Mudskipper Melody, 362=Subterranea, 363=Incantation, 410=Trouble Brewing, 411=Head to Head, 408=The Depths, 409=Distillery Hilarity, 414=Back to Life, 415=Labyrinth, 412=Pinball Wizard, 413=Beetle Juice, 402=Tomb Raider, 403=No Way Out, 400=Null and Void, 401=Pest Control, 406=Funny Bunnies, 407=Assault and Battery, 404=Method of Madness, 405=Fear and Loathing, 395=Chickened Out, 394=Davy Jones's Locker, 393=The Mad Mole, 392=Storm Brew, 399=Chef Surprize, 398=Too Many Cooks..., 397=Mastermindless, 396=Hot 'n' Bothered, 387=Dogs of War, 386=Joy of the Hunt, 385=Home Sweet Home, 384=Jungle Hunt, 391=Wrath and Ruin, 390=Dance of Death, 389=Malady, 388=Food For Thought, 440=Volcanic Vikings, 441=Island of the Trolls, 442=Pirates of Penance, 443=Brimstail's Scales, 444=My Arm's Journey, 445=Slug a Bug Ball, 446=Prime Time, 447=Rising Damp, 432=The Last Shanty, 433=Night of the Vampyre, 434=We are the Fairies, 435=Dimension X, 436=All's Fairy in Love and War, 437=Major Miner, 438=Jester Minute, 439=Norse Code, 425=On the Wing, 424=Life's a Beach!, 427=The Mollusc Menace, 426=Little Cave of Horrors, 429=H.A.M. Fisted, 428=The Galleon, 431=Sigmund's Showdown, 430=Lament of Meiyerditch, 417=Everlasting Fire, 416=Safety in Numbers, 419=Dreamstate, 418=Waking Dream, 421=Isle of Everywhere, 420=The Lunar Isle, 423=Warriors' Guild, 422=Way of the Enchanter, 478=Ham and Seek, 479=Venomous, 476=Ham Attack, 477=Slice of Silent Movie, 474=Impetuous, 475=Easter Jig, 472=Slice of Station, 473=Barb Wire, 470=Espionage, 471=Undead Dungeon, 468=Creature Cruelty, 469=Alternative Root, 466=Have an Ice Day, 467=Zombiism, 464=Garden of Winter, 465=Garden of Autumn, 463=Garden of Spring, 462=Garden of Summer, 461=Jungle Bells, 460=Sea Shanty XMAS, 459=Jungle Island XMAS, 458=Looking Back, 457=High Spirits, 456=Roc and Roll, 455=Floating Free, 454=Dorgeshuun Deep, 453=Dorgeshuun City, 452=Mutant Medley, 451=Magic Magic Magic, 450=Work Work Work, 449=Ogre the Top, 448=Where Eagles Lair, 508=Dusk in Yu'biusk, 509=Grimly Fiendish, 510=Tune from the Dune, 511=Spa Bizarre, 504=Animal Apogee, 505=Temple of Tribes, 506=Catacombs and Tombs, 507=Zanik's Theme, 500=Terrorbird Tussle, 501=Altar Ego, 502=Bolrie's Diary, 503=Healin' Feelin', 496=The Longramble Scramble, 497=Waste Defaced, 498=Knightmare, 499=Lore and Order, 493=Armadyl Alliance, 492=Bandos Battalion, 495=Storeroom Shuffle, 494=Armageddon, 489=Melzar's Maze, 488=On the Up, 491=Strength of Saradomin, 490=Zamorak Zoo, 485=Everlasting, 484=Illusive, 487=Down and Out, 486=Untouchable, 481=Fe Fi Fo Fum, 480=Mouse Trap, 483=Inadequacy, 482=School's Out, 550= , 551= , 548= , 549= , 546= , 547= , 544= , 545= , 558=Icy Trouble Ahead, 559=Icy a Worried Gnome, 556=Jungle Community, 557= , 554= , 555=The Trade Parade, 552= , 553= , 567= , 566= , 565= , 564= , 563= , 562= , 561= , 560= , 575= , 574= , 573= , 572= , 571= , 570= , 569= , 568= , 516=Charmin' Farmin', 517=Bounty Hunter Level 1, 518=Bounty Hunter Level 2, 519=Bounty Hunter Level 3, 512=Copris Lunaris, 513=Narnode's Theme, 514=Tournament!, 515=Clan Wars, 524= , 525= , 526= , 527= , 521=Creepy, 522=A New Menace, 523= , 533=Brain Battle, 532= , 535= , 534= , 529= , 528= , 531= , 530= , 541= , 540= , 543= , 542= , 537= , 536=Surok's Theme, 539= , 538= , 576= , 577=Distant Land, 578=Castle Wars, 579=Pest Control, 580=Competition, 581=Poles Apart, 582=Far Away, 583=Hell's Bells, 584=Bloodbath, 585=The Route of All Evil, 586=The Route of the Problem, 587=The Wrong Path, 588=The Columbarium, 589=The Terrible Tunnels, 590=The Terrible Caverns, 591=Dillo-gence is Key, 593=TokTz-Ket-Ek-Mack, 592=Arma Gonna Get You, 595=Bittersweet Bunny, 601=Conspiracy: Part 2, 600=Conspiracy: Part 1, 603=Guthix's Hunter, 602=Scape Summon, 604=Waiting for the Hunt} +Script 1346 - [105,105,null,255]: {0=3, 1=8, 2=0, 3=10, 4=8, 5=8, 6=8, 7=33, 8=1, 9=14, 10=32, 11=32, 12=32, 13=32, 14=32, 15=32, 17=4, 16=14, 19=18, 18=14, 21=35, 20=18, 23=4, 22=17, 25=35, 24=19, 27=33, 26=33, 29=1, 28=23, 31=1, 30=1, 34=1, 35=4, 32=1, 33=8, 38=12, 39=14, 36=0, 37=8, 42=33, 43=23, 40=3, 41=17, 46=19, 47=4, 44=14, 45=15, 51=12, 50=3, 49=16, 48=3, 55=0, 54=12, 53=12, 52=0, 59=15, 58=4, 57=3, 56=12, 63=1, 62=17, 61=0, 60=14, 68=10, 69=10, 70=18, 71=19, 64=33, 65=15, 66=10, 67=10, 76=14, 77=19, 78=1, 79=17, 72=7, 73=1, 74=19, 75=17, 85=0, 84=14, 87=18, 86=19, 81=18, 80=19, 83=20, 82=3, 93=3, 92=19, 95=1, 94=0, 89=4, 88=12, 91=33, 90=14, 102=33, 103=0, 100=23, 101=18, 98=11, 99=33, 96=10, 97=10, 110=3, 111=33, 108=17, 109=0, 106=15, 107=15, 104=1, 105=1, 119=19, 118=3, 117=4, 116=22, 115=10, 114=5, 113=14, 112=3, 127=10, 126=12, 125=15, 124=15, 123=19, 122=18, 121=0, 120=8, 137=4, 136=3, 139=20, 138=0, 141=20, 140=14, 143=1, 142=1, 129=10, 128=10, 131=1, 130=18, 133=4, 132=33, 135=18, 134=33, 152=0, 153=27, 154=27, 155=0, 156=0, 157=10, 158=0, 159=14, 144=1, 145=1, 146=1, 147=18, 148=14, 149=33, 150=0, 151=0, 171=8, 170=1, 169=15, 168=3, 175=1, 174=0, 173=33, 172=0, 163=14, 162=15, 161=4, 160=1, 167=4, 166=1, 165=13, 164=0, 186=33, 187=0, 184=25, 185=1, 190=13, 191=13, 188=14, 189=13, 178=16, 179=0, 176=33, 177=16, 182=25, 183=16, 180=25, 181=25, 205=11, 204=31, 207=11, 206=11, 201=8, 200=0, 203=11, 202=11, 197=25, 196=0, 199=25, 198=33, 193=25, 192=0, 195=0, 194=11, 220=31, 221=31, 222=0, 223=0, 216=8, 217=0, 218=5, 219=11, 212=0, 213=0, 214=8, 215=8, 208=13, 209=13, 210=11, 211=35, 239=10, 238=0, 237=33, 236=30, 235=7, 234=30, 233=7, 232=7, 231=7, 230=25, 229=33, 228=25, 227=9, 226=9, 225=33, 224=33, 254=30, 255=7, 252=34, 253=0, 250=33, 251=0, 248=17, 249=32, 246=33, 247=0, 244=0, 245=0, 242=10, 243=33, 240=10, 241=10, 275=8, 274=0, 273=15, 272=0, 279=7, 278=25, 277=25, 276=15, 283=8, 282=8, 281=15, 280=0, 287=33, 286=10, 285=33, 284=33, 258=0, 259=0, 256=1, 257=7, 262=15, 263=33, 260=33, 261=33, 266=33, 267=25, 264=30, 265=1, 270=25, 271=25, 268=33, 269=33, 305=0, 304=34, 307=33, 306=16, 309=35, 308=33, 311=0, 310=35, 313=0, 312=16, 315=34, 314=0, 317=24, 316=0, 319=0, 318=0, 288=21, 289=35, 290=0, 291=0, 292=11, 293=33, 294=23, 295=8, 296=0, 297=0, 298=25, 299=25, 300=8, 301=0, 302=8, 303=8, 343=10, 342=0, 341=1, 340=1, 339=36, 338=0, 337=0, 336=0, 351=15, 350=0, 349=0, 348=0, 347=0, 346=0, 345=0, 344=0, 326=35, 327=35, 324=0, 325=35, 322=34, 323=0, 321=0, 334=36, 335=36, 332=0, 333=8, 330=9, 331=8, 328=8, 329=0, 373=0, 372=0, 374=0, 369=0, 368=0, 371=27, 370=15, 381=0, 380=0, 383=0, 382=30, 377=0, 376=0, 379=15, 378=21, 356=0, 357=0, 358=0, 359=0, 352=15, 353=25, 354=0, 355=0, 364=0, 365=0, 366=0, 367=0, 360=0, 361=15, 362=0, 363=33, 410=15, 411=0, 408=0, 409=15, 414=8, 415=33, 412=0, 413=0, 402=8, 403=0, 400=0, 401=0, 406=26, 407=0, 404=0, 405=0, 395=0, 394=15, 393=0, 392=0, 399=0, 398=0, 397=0, 396=8, 387=33, 386=21, 385=37, 384=21, 391=0, 390=0, 389=0, 388=0, 440=38, 441=13, 442=0, 443=0, 444=15, 445=0, 446=0, 447=0, 432=15, 433=25, 434=23, 435=0, 436=23, 437=0, 438=0, 439=38, 425=21, 424=15, 427=0, 426=0, 429=0, 428=15, 431=0, 430=25, 417=1, 416=33, 419=9, 418=9, 421=9, 420=9, 423=0, 422=9, 478=0, 479=1, 477=0, 474=0, 475=26, 472=0, 473=0, 470=0, 471=0, 468=0, 469=33, 466=22, 467=0, 464=0, 465=0, 463=0, 462=0, 461=27, 460=27, 459=27, 458=0, 457=28, 456=0, 455=0, 454=34, 453=0, 452=0, 451=0, 450=0, 449=13, 448=0, 508=0, 509=0, 510=0, 511=0, 504=0, 505=0, 506=0, 507=0, 500=0, 501=0, 502=0, 503=0, 496=31, 497=31, 498=0, 499=0, 493=0, 492=0, 495=0, 494=0, 489=0, 488=0, 491=0, 490=0, 485=0, 484=0, 487=0, 486=0, 481=0, 480=0, 483=0, 482=0, 550=0, 551=0, 548=0, 549=0, 546=0, 547=0, 544=0, 545=0, 558=0, 559=0, 556=10, 557=0, 554=0, 555=3, 552=0, 553=0, 567=0, 566=0, 565=0, 564=0, 563=0, 562=0, 561=0, 560=0, 575=0, 574=0, 573=0, 572=0, 571=0, 570=0, 569=0, 568=0, 516=0, 517=0, 518=0, 519=0, 512=0, 513=12, 514=0, 515=0, 524=0, 525=0, 526=0, 527=0, 520=0, 521=0, 522=0, 523=0, 533=0, 532=0, 535=0, 534=0, 529=0, 528=0, 531=10, 530=0, 541=0, 540=0, 543=0, 542=0, 537=0, 536=0, 539=0, 538=0, 576=0, 577=0, 578=0, 579=0, 580=0, 581=0, 582=0, 583=0, 584=0, 585=33, 586=33, 587=0, 588=0, 589=0, 590=33, 591=0, 593=0, 592=0, 595=0, 594=15, 597=0, 596=15, 599=0, 598=0, 601=0, 600=0, 603=0, 602=0, 604=0} +Script 1347 - [105,115, ,0]: {0=adventure, 1=al kharid, 2=alone, 3=ambient jungle, 4=arabian, 5=arabian2, 6=arabian3, 7=arabique, 8=army of darkness, 9=arrival, 10=attack1, 11=attack2, 12=attack3, 13=attack4, 14=attack5, 15=attack6, 17=autumn voyage, 16=attention, 19=ballad of enchantment, 18=background, 21=beyond, 20=baroque, 23=book of spells, 22=big chords, 25=cave background, 24=camelot, 27=chain of command, 26=cavern, 29=crystal sword, 28=crystal cave, 31=dark, 30=dangerous, 34=doorways, 35=dream, 32=deep wildy, 33=desert voyage, 38=emotion, 39=emperor, 36=dunjun, 37=egypt, 42=expedition, 43=faerie, 40=expanse, 41=expecting, 46=fishing, 47=flute salad, 44=fanfare, 45=fanfare3, 51=gnome king, 50=garden, 49=gaol, 48=forever, 55=goblin village, 54=gnome village2, 53=gnome village, 52=dwarf theme, 59=high seas, 58=harmony, 57=greatness, 56=gnomeball, 63=inspiration, 62=in the manor, 61=iban, 60=horizon, 68=jungly2, 69=jungly3, 70=knightly, 71=lasting, 64=intrepid, 65=jolly-r, 66=jungle island, 67=jungly1, 76=long way home, 77=lullaby, 78=mage arena, 79=magic dance, 72=legion, 73=lightness, 74=lightwalk, 75=long ago, 85=miracle dance, 84=miles away, 87=moody, 86=monarch waltz, 81=march, 80=magical journey, 83=mellow, 82=medieval, 93=parade, 92=overture, 95=regal, 94=quest, 89=newbie melody, 88=neverland, 91=oriental, 90=nightfall, 102=scape cave, 103=Scape original, 100=rune essence, 101=sad meadow, 98=riverside, 99=royale, 96=reggae, 97=reggae2, 110=shine, 111=soundscape, 108=serenade, 109=serene, 106=sea shanty, 107=sea shanty2, 104=scape sad, 105=scape wild, 119=talking forest, 118=still night, 117=start, 116=starlight, 115=spookyjungle, 114=spooky, 113=splendour, 112=spirit, 127=tribal background, 126=tree spirits, 125=trawler minor, 124=trawler, 123=theme, 122=tower, 121=shadow, 120=desert, 137=vision, 136=venture, 139=voyage, 138=voodoo cult, 141=waterfall, 140=wander, 143=wilderness2, 142=wilderness, 129=tribal2, 128=tribal, 131=troubled, 130=trinity, 133=unknown land, 132=underground, 135=upcoming, 134=Underground Pass, 152=scape scared, 153=scape santa, 154=land of snow, 155=shaping up, 156=exam conditions, 157=roots and flutes, 158=incarceration, 159=scape soft, 144=wilderness3, 145=witching, 146=wonder, 147=wonderous, 148=workshop, 149=lonesome, 150=scape main, 151=ground scape, 171=nomad, 170=undercurrent, 169=landlubber, 168=venture2, 175=close quarters, 174=heart and mind, 173=cellar song, 172=zealot, 163=tomorrow, 162=fanfare2, 161=yesteryear, 160=shining, 167=harmony2, 166=wild isle, 165=ice melody, 164=duel arena, 186=cursed, 187=understanding, 184=mausoleum, 185=forbidden, 190=kingdom, 191=hermit, 188=principality, 189=tremble, 178=chompy hunt, 179=twilight, 176=escape, 177=grumpy, 182=village, 183=bone dance, 180=morytania, 181=dead quiet, 205=meridian, 204=lost soul, 207=overpass, 206=woodland, 201=aztec, 200=artistry, 203=forest, 202=elven mist, 197=natural, 196=time out, 199=waterlogged, 198=grotto, 193=stagnant, 192=la mort, 195=stratosphere, 194=breeze, 220=exposed, 221=well of voyage, 222=haunted mine, 223=righteousness, 216=bone dry, 217=competition, 218=spooky2, 219=everywhere, 212=insect queen, 213=mad eadgar, 214=bandit camp, 215=sunburn, 208=contest, 209=sojourn, 210=crystal castle, 211=marzipan, 239=monkey madness, 238=technology, 237=warrior, 236=frostbite, 235=legend, 234=stranded, 233=borderland, 232=saga, 231=rellekka, 230=deadlands, 229=lair, 228=shadowland, 227=etcetera, 226=miscellania, 225=chamber, 224=deep down, 254=hell's bells, 255=navigator the, 252=goblin game, 253=out of the deep, 250=stillness, 251=lighthouse, 248=melodrama, 249=ready for battle, 246=find my way, 247=castlewars, 244=suspicious, 245=showdown, 242=island life, 243=temple, 240=anywhere, 241=marooned, 275=dynasty, 274=barking mad, 273=fruits de mer, 272=monster melee, 279=settlement, 278=other side, 277=phasmatys, 276=shipwrecked, 283=sarcophagus, 282=scarab, 281=dragontooth island, 280=cave of beasts, 287=pathways, 286=karamja jam, 285=7th realm, 284=down below, 258=complication, 259=down to earth, 256=wildwood, 257=barbarianism, 262=pirates of peril, 263=dangerous road, 260=courage, 261=superstition, 266=tiptoe, 267=terrible tower, 264=romancing the crone, 265=faithless, 270=body parts, 271=fenkenstrain's refrain, 268=masquerade, 269=slayer the, 305=bish bash bosh, 304=cave of the goblins, 307=path of peril, 306=zogre dance, 309=tale of keldagrim, 308=wayward, 311=tears of guthix, 310=land of the dwarves, 313=rogues' den, 312=romper chomper, 315=lost melody, 314=far side, 317=into the abyss, 316=evil bob's island, 319=power of tears, 318=quiz master, 288=eagle peak, 289=time to mine, 290=in between, 291=claustrophobia, 292=far away, 293=fight or flight, 294=temple of light, 295=golem the, 296=forgotten, 297=throne of the demon, 298=dance of the undead, 299=dangerous way, 300=city of the dead, 301=hypnotized, 302=sphinx, 303=mirage, 343=jungle troubles, 342=cellar dwellers, 341=dead can dance, 340=wild side, 339=tzhaar!, 338=brew hoo hoo, 337=strange place, 336=frogland, 351=aye car rum ba, 350=homescape, 349=rat hunt, 348=sarim's vermin, 347=bubble and squeak, 346=noble rodent, 345=rat a tat tat, 344=catch me if you can, 326=forgettable melody, 327=right on track, 324=chosen, 325=have a blast, 322=lost tribe, 323=corporal punishment, 321=pheasant peasant, 334=fire and brimstone, 335=in the pits, 332=genie, 333=desert heat, 330=desolate isle, 331=spirits of elid, 328=over to nardah, 329=monsters below, 373=mind over matter, 372=roll the bones, 374=golden touch, 369=woe of the wyvern, 368=victory is mine, 371=diango's little helpers, 370=in the brine, 381=lament, 380=last stand, 383=scarabaeoidea, 382=poles apart, 377=scape hunter, 376=enchanter, 379=cabin fever, 378=making waves, 356=land down under, 357=meddling kids, 358=corridors of power, 359=slither and thither, 352=blistering barnacles, 353=distant land, 354=fangs for the memory, 355=pharaoh's tomb, 364=grip of the talon, 365=dagannoth dawn, 366=xenophobe, 367=title fight, 360=in the clink, 361=mudskipper melody, 362=subterranea, 363=incantation, 410=trouble brewing, 411=head to head, 408=depths the, 409=distillery hilarity, 414=back to life, 415=labyrinth, 412=pinball wizard, 413=beetle juice, 402=tomb raider, 403=no way out, 400=null and void, 401=pest control, 406=funny bunnies, 407=assault and battery, 404=method of madness, 405=fear and loathing, 395=chickened out, 394=davy jones's locker, 393=mad mole, 392=storm brew, 399=chef surprize, 398=too many cooks..., 397=mastermindless, 396=hot 'n' bothered, 387=dogs of war, 386=joy of the hunt, 385=home sweet home, 384=jungle hunt, 391=wrath and ruin, 390=dance of death, 389=malady, 388=food for thought, 440=volcanic vikings, 441=island of the trolls, 442=pirates of penance, 443=brimstail's scales, 444=my arm's journey, 445=slug a bug ball, 446=prime time, 447=rising damp, 432=last shanty the, 433=night of the vampyre, 434=we are the fairies, 435=dimension x, 436=all's fairy in love and war, 437=major miner, 438=jester minute, 439=norse code, 425=on the wing, 424=life's a beach!, 427=mollusc menace, 426=little cave of horrors, 429=h.a.m. fisted, 428=galleon, 431=sigmund's showdown, 430=lament of meiyerditch, 417=everlasting fire, 416=safety in numbers, 419=dreamstate, 418=waking dream, 421=isle of everywhere, 420=lunar isle, 423=warriors' guild, 422=way of the enchanter, 478=h.a.m. and seek, 479=venomous, 476=h.a.m. attack, 477=slice of silent movie, 474=impetuous, 475=easter jig, 472=slice of station, 473=barb wire, 470=espionage, 471=undead dungeon, 468=creature cruelty, 469=alternative root, 466=have an ice day, 467=zombiism, 464=garden of winter, 465=garden of autumn, 463=garden of spring, 462=garden of summer, 461=jungle bells, 460=sea shanty xmas, 459=jungle island xmas, 458=looking back, 457=high spirits, 456=roc and roll, 455=floating free, 454=dorgeshuun deep, 453=dorgeshuun city, 452=mutant medley, 451=magic magic magic, 450=work work work, 449=ogre the top, 448=where eagles lair, 508=dusk in yu'biusk, 509=grimly fiendish, 510=tune from the dune, 511=spa bizarre, 504=animal apogee, 505=temple of tribes, 506=catacombs and tombs, 507=zanik's theme, 500=terrorbird tussle, 501=altar ego, 502=bolrie's diary, 503=healin' feelin', 496=longramble scramble, 497=waste defaced, 498=knightmare, 499=lore and order, 493=armadyl alliance, 492=bandos battalion, 495=storeroom shuffle, 494=armageddon, 489=melzar's maze, 488=on the up, 491=strength of saradomin, 490=zamorak zoo, 485=everlasting, 484=illusive, 487=down and out, 486=untouchable, 481=fe fi fo fum, 480=mouse trap, 483=inadequacy, 482=school's out, 550=zzzzzzzzzzzzz, 551=zzzzzzzzzzzzz, 548=zzzzzzzzzzzzz, 549=zzzzzzzzzzzzz, 546=zzzzzzzzzzzzz, 547=zzzzzzzzzzzzz, 544=zzzzzzzzzzzzz, 545=zzzzzzzzzzzzz, 558=icy trouble ahead, 559=icy a worried gnome, 556=jungle community, 557=zzzzzzzzzzzzz, 554=zzzzzzzzzzzzz, 555=trade parade, 552=zzzzzzzzzzzzz, 553=zzzzzzzzzzzzz, 567=zzzzzzzzzzzzz, 566=zzzzzzzzzzzzz, 565=zzzzzzzzzzzzz, 564=zzzzzzzzzzzzz, 563=zzzzzzzzzzzzz, 562=zzzzzzzzzzzzz, 561=zzzzzzzzzzzzz, 560=zzzzzzzzzzzzz, 575=zzzzzzzzzzzzz, 574=zzzzzzzzzzzzz, 573=zzzzzzzzzzzzz, 572=zzzzzzzzzzzzz, 571=zzzzzzzzzzzzz, 570=zzzzzzzzzzzzz, 569=zzzzzzzzzzzzz, 568=zzzzzzzzzzzzz, 516=charmin' farmin', 517=bounty hunter level 1, 518=bounty hunter level 2, 519=bounty hunter level 3, 512=copris lunaris, 513=narnode's theme, 514=tournament!, 515=clan wars, 524=zzzzzzzzzzzzz, 525=zzzzzzzzzzzzz, 526=zzzzzzzzzzzzz, 527=zzzzzzzzzzzzz, 521=creepy, 522=a new menace, 523=zzzzzzzzzzzzz, 533=brain battle, 532=zzzzzzzzzzzzz, 535=zzzzzzzzzzzzz, 534=zzzzzzzzzzzzz, 529=zzzzzzzzzzzzz, 528=zzzzzzzzzzzzz, 531=zzzzzzzzzzzzz, 530=zzzzzzzzzzzzz, 541=zzzzzzzzzzzzz, 540=zzzzzzzzzzzzz, 543=zzzzzzzzzzzzz, 542=zzzzzzzzzzzzz, 537=zzzzzzzzzzzzz, 536=surok's theme, 539=zzzzzzzzzzzzz, 538=zzzzzzzzzzzzz, 576=zzzzzzzzzzzzz, 577=zzzzzzzzzzzzz, 578=zzzzzzzzzzzzz, 579=zzzzzzzzzzzzz, 580=zzzzzzzzzzzzz, 581=zzzzzzzzzzzzz, 582=zzzzzzzzzzzzz, 583=zzzzzzzzzzzzz, 584=bloodbath, 585=route of all evil, 586=route of the problem, 587=wrong path, 588=columbarium, 589=terrible tunnels, 590=terrible caverns, 591=dillo-gence is key, 593=toktz-ket-ek-mack, 592=arma gonna get you, 595=bittersweet bunny, 601=conspiracy: part 2, 600=conspiracy: part 1, 603=guthix's hunter, 602=scape summon, 604=waiting for the hunt} +Script 1348 - [0,0,null,0]: null +Script 1349 - [105,115,default info,0]: {0=at Varrock Palace., 1=at Al Kharid., 2=at the Clock Tower Dungeon., 3=at Shilo Village., 4=in the Kharidian Desert., 5=at Al Kharid mine., 6=at the desert entrance to the Kalphite Lair., 7=at the hellhounds in Taverley Dungeon., 8=at the Dark Warrior's Fortress., 9=at the gem trader in Falador., 10=at the Battlefield north of Tree Gnome Village., 11=at Elvarg's lair or during Grand Tree Quest., 12=to the north of the Lava Maze., 13=at the Fight Arena., 14=at the King Black Dragon., 15=at Gu'Tanoth Ogre Enclave., 17=at Lumbridge farm., 16=at the coastline below Rimmington., 19=at the Monastery., 18=on Entrana., 21=at the ice dungeon under Wolf Mountain., 20=in Ardougne., 23=at Lumbridge Swamp., 22=to the west of Yanille., 25=at the Dwarven Mine., 24=at Camelot Castle., 27=during Temple of Ikov., 26=at Yanille Agility Dungeon., 29=at the Wilderness, north of Varrock., 28=at Zanaris market., 31=in the south-east of the Wilderness., 30=to the north of Edgeville., 34=to the north of the Grand Exchange., 35=on the path between Lumbridge and Draynor., 32=in the north-west of the Wilderness., 33=around the Desert Mining Camp., 38=in the Tree Gnome Village maze., 39=in Melzar's Maze., 36=in Taverley Dungeon., 37=at Shantay Pass., 42=in the caverns below the Observatory., 43=at Zanaris., 40=at the stone circle in Varrock., 41=at the unholy altar north of the Observatory., 46=at Catherby beach., 47=at the Lumbridge windmill area., 44=at Falador Castle., 45=at Port Khazard., 51=at the Tree Gnome Stronghold., 50=at Varrock city centre., 49=to the north of the Bandit Camp in the Wilderness., 48=at Edgeville., 55=at Goblin Village., 54=to the south-west of the Tree Gnome Stronghold., 53=at the Tree Gnome Stronghold's Agility Training Area., 52=at the Dwarven Mine., 59=at Brimhaven., 58=at Lumbridge Castle., 57=at the Champions' Guild., 56=at the Gnome Ball Field., 63=at the area north of the Black Knights' Fortress., 62=at the ogre island, west of Yanille., 61=at Iban's lair in the Underground Pass., 60=in Taverley., 68=to the north-west of Brimhaven., 69=at Tai Bwo Wannai Village., 70=at Ardougne Castle., 71=at Hemenster., 64=in the Underground Pass caverns., 65=at the north dock of Brimhaven., 66=on Karamja., 67=at Cairn Isle., 76=at Rimmington., 77=at the area south-west of Rellekka., 78=at the Mage Arena., 79=in the east of Yanille., 72=at the Barbarian Outpost., 73=to the north of Edgeville., 74=at Keep Le Faye., 75=at the Fishing Platform., 85=at the Mind Altar., 84=at the Crafting Guild., 87=at the entrance to the Underground Pass., 86=at the Sinclair Mansion., 81=at King Lathas's Combat Training Camp., 80=at the Sorcerer's Tower., 83=at the Fishing Guild., 82=to the west of the Dig Site., 93=at the Jolly Boar Inn., 92=at Seers' Village., 95=at the Rogues' Castle., 94=at the Fire Altar., 89=on Tutorial Island., 88=to the south of Tree Gnome Village., 91=in the Waterfall Dungeon, East of Shilo Village., 90=to the north of Rimmington., 102=during the Lumbridge Tutorial and in Varrock Sewers., 103=automatically., 100=at the rune essence mine., 101=at West Ardougne., 98=to the west of Tyras Camp., 99=at the Black Knight base in Taverley Dungeon., 96=to the south-east of the Kharazi Jungle., 97=to the east of Karamja Jungle., 110=at the Duel Arena hospital., 111=at the Feldip Hills glider area., 108=at the Observatory., 109=at the Air Altar., 106=at Karamja port., 107=at Port Sarim., 104=at the Demonic Ruins in the Wilderness., 105=in the Wilderness., 119=at McGrubor's Wood., 118=at the Mining area south-east of Varrock., 117=at Draynor Village., 116=at the Asgarnian Ice Dungeon north of Mudskipper Point., 115=to the north-east of Karamja., 114=at Draynor Manor., 113=at the Heroes' Guild., 112=at the Cooks' Guild., 127=in the south-east Kharazi Jungle., 126=to the west of the Tree Gnome Stronghold., 125=during the Fishing Trawler minigame., 124=during the Fishing Trawler minigame., 123=at the Coal Trucks., 122=to the north-west of Ardougne., 121=on Crandor., 120=to the west of the Kharidian Desert., 137=at the Wizards' Tower., 136=at the Dig Site., 139=at the top of Baxtorian Falls., 138=at the cave under the Kharazi Jungle., 141=at Baxtorian Falls., 140=at the farm area south of Falador., 143=to the south of the Lava Maze in the Wilderness., 142=in the Wilderness., 129=at the gnome glider on Karamja., 128=to the east of Tai Bwo Wannai Village., 131=to the west of the Bandit Camp in the Wilderness., 130=at the Legends' Guild., 133=at Draynor Market., 132=at the dramen tree in Entrana Dungeon., 135=at the tower of the Necromancer., 134=during Underground Pass., 152=automatically., 153=automatically., 154=during or after the Christmas 2007 holiday event., 155=during As a First Resort..., 156=at the Stronghold of Player Safety., 157=during Back to my Roots., 158=at the Stronghold of Player Safety., 159=to the north of Falador., 144=to the west of Bounty Hunter in the Wilderness., 145=on the east side of the Wilderness., 146=to the north-west of the Black Knights' Fortress., 147=near the Legends' Guild., 148=at the Mining Guild in Falador., 149=at the Desert Mining Camp., 150=automatically., 151=automatically., 171=to the east of the Bedabin Camp., 170=in the south-east of the Wilderness., 169=to the west of Brimhaven., 168=during Dig Site., 175=at the entrance to Bounty Hunter in the Wilderness., 174=at the Body Altar., 173=at the bank vault west of Varrock., 172=at the Water Altar., 163=at the coastline south of Port Sarim., 162=at the Shipyard on Karamja., 161=to the east of Lumbridge Swamp., 160=at the Bone Yard in the Wilderness., 167=in Lumbridge Castle's basement., 166=to the south of Red Dragon Isle in the Wilderness., 165=at White Wolf Mountain., 164=at the Duel Arena., 186=during Underground Pass., 187=at the Nature Altar., 184=under Paterdomus., 185=to the north of the Lumber Yard., 190=on the way to Death Plateau., 191=at the hermit's cave north-west of Burthorpe., 188=at Burthorpe's training ground., 189=during Death Plateau., 178=at the chompy hunt area near Rantz the ogre., 179=during Elemental Workshop., 176=at the perfect gold mine under Ardougne., 177=at the swamp toad pond in the Feldip Hills., 182=at Canifis in Morytania., 183=to the west of Mort'ton., 180=to the east of Paterdomus., 181=to the north of the Mort Myre area., 205=at the area around Tyras Camp in Isafdar., 204=at the Poison Waste in south Isafdar., 207=at Arandar, east of Tirannwn., 206=at the Elf Camp in Tirannwn., 201=at the Brimhaven Agility Arena., 200=during the Mime random event., 203=to the south-east of Isafdar., 202=at the exit of the Underground Pass., 197=at the nature spirit's island in Mort Myre Swamp., 196=during the Maze random event., 199=to the south of Canifis., 198=at the nature spirit's grotto in Mort Myre Swamp., 193=at the Hollows in the Mort Myre Swamp., 192=at the Death Altar., 195=at the Cosmic Altar., 194=at Isafdar near the Underground Pass., 220=to the south of Tyras Camp in Isafdar., 221=in the passage between Iban's Temple and Isafdar., 222=at the boss area of the Haunted Mine., 223=at the Law Altar., 216=in the smoky well near Pollnivneach., 217=at Burthorpe Games Room., 218=at the entrance to the Haunted Mine., 219=to the south-west of Prifddinas., 212=at the Kalphite Queen., 213=at Eadgar's cave atop Trollheim., 214=at the Bandit Camp in the Kharidian Desert., 215=in the desert north of Jaldraocht Pyramid., 208=in Trollheim., 209=at the troll champion arena., 210=to the south-east of Prifddinas., 211=at the Trollheim cave., 239=on Ape Atoll., 238=at the gnome glider hanger., 237=during Fremennik Trials., 236=at the Ice Path north of Trollheim., 235=to the south-east of Rellekka., 234=at the gate to the Ice Path, north of Trollheim., 233=to the east of Rellekka., 232=to the south of Rellekka., 231=at Rellekka., 230=at the Haunted Woods of Morytania., 229=at the shade catacombs below Mort'ton., 228=to the east of Mort'ton., 227=on Etceteria., 226=on Miscellania., 225=on the middle floor of the Haunted Mine., 224=on the bottom floor of the Haunted Mine., 254=during the Troll Romance quest., 255=during Fremennik Trials., 252=at the goblin cave near the Fishing Guild., 253=at the dagannoth cave under the Lighthouse., 250=at the Myreque area under Mort Myre., 251=at the Lighthouse., 248=during the Castle Wars minigame., 249=during the Castle Wars minigame., 246=at the gnome tunnel in Monkey Madness., 247=during the Castle Wars minigame., 244=during Monkey Madness., 245=during the boss fight in Monkey Madness., 242=at the southern part of Ape Atoll., 243=on Ape Atoll., 240=at Marim's main gate., 241=on Crash Island during Monkey Madness., 275=at the town of Pollnivneach., 274=at the Werewolf Agility Course., 273=at the Fishing Platform., 272=at the H.A.M. cave., 279=at the Mountain Camp., 278=at Port Phasmatys., 277=at the pool of ectoplasm underneath the Ectofuntus., 276=at the shipwreck on the north coast of Morytania., 283=inside Jaldraocht, the pyramid visited in Desert Treasure., 282=at Jaldraocht, the pyramid visited in Desert Treasure., 281=on Dragontooth Island., 280=during Mountain Daughter., 287=at Brimhaven Dungeon's entrance., 286=at the dragon area of Brimhaven Dungeon., 285=at Brimhaven Dungeon., 284=at the dungeon below Draynor Village., 258=at the Chaos Altar., 259=at the Earth Altar., 256=to the south of Bounty Hunter., 257=at Barbarian Village., 262=at the Pirates' Hideout in the Wilderness., 263=at the caves below Crandor., 260=at Taverley Dungeon., 261=at the cave below the Kharazi Jungle., 266=at Draynor Manor's cellar., 267=at the Slayer Tower., 264=during the Troll Romance quest., 265=at the Chaos Temple in the Wilderness., 270=at the dungeon south-east of Fenkenstrain's Castle., 271=at Fenkenstrain's Castle., 268=on the west side of the Fremennik Slayer Dungeon., 269=on the east side of the Fremennik Slayer Dungeon., 305=during As a First Resort..., 304=at the caves beneath Lumbridge Swamp., 307=in Damis's Shadow Dungeon., 306=at the zogre area., 309=on the east side of Keldagrim., 308=at the zogre dungeon., 311=during Tears of Guthix., 310=on the west side of Keldagrim., 313=at the Rogues' Den., 312=at the ogre area south of Castle Wars., 315=at the Dorgesh-Kaan mine., 314=at the Rogues' Den training area., 317=in abyssal space., 316=during the Evil Bob random event., 319=during the Tears of Guthix quest., 318=during the Quiz Master random event., 288=during Eagles' Peak., 289=during Between a Rock..., 290=during Between a Rock..., 291=during Between a Rock..., 292=at Lletya., 293=at the slave mine under West Ardougne., 294=during Mourning's Ends Part II., 295=at the Ruins of Uzer., 296=during the Golem., 297=during Shadow of the Storm., 298=at the Barrows., 299=beneath the Barrows., 300=at Sophanem., 301=during Icthlarin's Little Helper., 302=to the north of Sophanem., 303=during Icthlarin's Little Helper., 343=in the jungle of north-east Karamja., 342=during the Hazeel Cult., 341=to the east of Bounty Hunter., 340=to the north of the Lava Maze in the Wilderness., 339=in the TzHaar Fight Cave minigame., 338=at Port Phasmatys brewery., 337=during the Tale of Two Cats., 336=during the Frog random event., 351=on Braindeath Island., 350=automatically., 349=during Rat Catchers., 348=at Port Sarim Rat Pits., 347=at the Keldagrim Rat Pits., 346=during Rat Catchers., 345=at the Varrock Rat Pits., 344=at the Ardougne Rat Pits., 326=during Forgettable Tale..., 327=during Forgettable Tale..., 324=during Recruitment Drive., 325=during the Blast Furnace minigame., 322=at the goblin mines under Lumbridge., 323=during the Drill Demon random event., 321=during the Freaky Forester random event., 334=in the TzHaar Fight Pit minigame., 335=in TzHaar., 332=at the genie's cave west of Nardah., 333=in the desert north of Nardah., 330=on Waterbirth Island., 331=during the Spirits of Elid., 328=at Nardah., 329=in Waterbirth Island Dungeon., 373=at the Mage Training Arena's Telekinetic Theatre., 372=at the Mage Training Arena's Creature Graveyard., 374=at the Mage Training Arena's Alchemists' Playground., 369=at the Asgarnian Ice Dungeon's wyvern area., 368=at the Champion's Challenge arena., 371=at Diango's Christmas workshop., 370=on Mos Le'Harmless., 381=during Enakhra's Lament., 380=during Swan Song., 383=during Dealing with Scabaras., 382=at the Trollweiss and Rellekka Hunter area., 377=automatically., 376=at the Mage Training Arena's Enchanting Chamber., 379=during Cabin Fever., 378=during Swan Song., 356=during Royal Trouble., 357=during Royal Trouble., 358=during Royal Trouble., 359=at the sea snake cave in Royal Trouble., 352=on Braindeath Island's mountain., 353=at Burgh de Rott., 354=during In Aid of the Myreque., 355=at the Agility Pyramid., 364=during Shadow of the Storm., 365=in Waterbirth Island Dungeon., 366=in Waterbirth Island Dungeon., 367=at the Champion's Challenge underground area., 360=during the Prison Pete random event., 361=at Mudskipper Point., 362=in Waterbirth Island Dungeon., 363=during Shadow of the Storm., 410=during the Trouble Brewing minigame., 411=during the Evil Twin random event., 408=during Contact!, 409=at Trouble Brewing's distillery., 414=during Contact!, 415=during Contact!, 412=during the Pinball random event., 413=during Contact!, 402=during the Pyramid Plunder minigame., 403=at the hopelessness room of Tolna's rift area., 400=at the Pest Control minigame landing area., 401=during the Pest Control minigame., 406=during or after the Easter 2006 holiday event., 407=during the Barbarian Assault minigame., 404=at the confusion room of Tolna's rift area., 405=at the fear room of Tolna's rift area., 395=at the Evil Chicken's lair., 394=during Recipe for Disaster., 393=at Falador Mole Lair., 392=at the killerwatt plane., 399=during Recipe for Disaster., 398=during Recipe for Disaster., 397=during Recipe for Disaster., 396=during As a First Resort..., 387=at the Vault of War in the Stronghold of Security., 386=at the Feldip Hunter area cave., 385=at your player-owned house., 384=at the Feldip Hunter area., 391=at the anger room of Tolna's rift., 390=at the Sepulchre of Death in the Stronghold of Security., 389=at the Pit of Pestilence in the Stronghold of Security., 388=at the Catacomb of Famine in the Stronghold of Security., 440=during Fremennik Isles., 441=during Fremennik Isles., 442=during the Barbarian Assault minigame., 443=at Brimstail's cave., 444=during My Arm's Big Adventure., 445=during the Slug Menace Quest., 446=during Elemental Workshop II., 447=during Olaf's Quest., 432=during the Darkness of Hallowvale., 433=during the Darkness of Hallowvale., 434=on the cosmic entity plane during Fairy Tale Part II., 435=on the gorak plane in Fairy Tale Part II., 436=at the fairy resistance hideout in Fairy Tale Part II., 437=during Fremennik Isles., 438=during Fremennik Isles., 439=during Fremennik Isles., 425=during Fairy Tale Part II., 424=at the coastal area of Mos Le'Harmless., 427=during Slug Menace., 426=in the cave horror dungeon beneath Mos Le'Harmless., 429=during Death to the Dorgeshuun., 428=during Lunar Diplomacy., 431=during Death to the Dorgeshuun., 430=during the Darkness of Hallowvale., 417=in the north-east corner of the Wilderness., 416=at the Stronghold of Player Safety., 419=during your dream in Lunar Diplomacy., 418=during your dream in Lunar Diplomacy., 421=on the east coast of Lunar Isle., 420=at Lunar Isle., 423=at the Warriors' Guild., 422=in the dungeon beneath Lunar Isle., 478=during Another Slice of H.A.M.., 479=at the Scorpion Pit in the Wilderness., 476=during Another Slice of H.A.M.., 477=during Another Slice of H.A.M.., 474=during the Impetuous Impulses minigame., 475=during or after the Easter 2007 holiday event., 472=during Another Slice of H.A.M.., 473=while learning barbarian skills., 470=during Cold War., 471=in Tarn's Lair., 468=during Tower of Life., 469=during What Lies Below., 466=during Cold War., 467=during Great Brain Robbery., 464=during the Sorceress's Garden minigame., 465=during the Sorceress's Garden minigame., 463=during the Sorceress's Garden minigame., 462=during the Sorceress's Garden minigame., 461=during or after the Christmas 2006 holiday event., 460=during or after the Christmas 2006 holiday event., 459=during or after the Christmas 2006 holiday event., 458=at Varrock Museum., 457=during or after the Halloween 2006 holiday event., 456=during My Arm's Big Adventure., 455=during An Enlightened Journey., 454=at the Dorgesh-Kaan caves., 453=at Dorgesh-Kaan., 452=during Tower of Life., 451=during Tower of Life., 450=during Tower of Life., 449=during Fremennik Isles., 448=during Eagles' Peak., 508=during Land of the Goblins., 509=during the Halloween 2007 holiday event., 510=during Dealing with Scabaras., 511=during As a First Resort..., 504=during Wolf Whistle., 505=during Land of the Goblins., 506=during Land of the Goblins., 507=during Land of the Goblins., 500=during Path of Glouphrie., 501=at Ourania Altar., 502=during Path of Glouphrie., 503=during Path of Glouphrie., 496=during Path of Glouphrie., 497=during Path of Glouphrie., 498=at the Black Knights' Fortress., 499=during King's Ransom., 493=in the God Wars Dungeon., 492=in the God Wars Dungeon., 495=during Path of Glouphrie., 494=in the God Wars Dungeon., 489=during Dragon Slayer., 488=during Dream Mentor., 491=in the God Wars Dungeon., 490=in the God Wars Dungeon., 485=during Dream Mentor., 484=during Dream Mentor., 487=during Dream Mentor., 486=during Dream Mentor., 481=during Grim Tales., 480=during Grim Tales., 483=during Dream Mentor., 482=during the Pattern Recognition random event., 550=not unlockable!, 551=not unlockable!, 548=not unlockable!, 549=not unlockable!, 546=not unlockable!, 547=not unlockable!, 544=not unlockable!, 545=not unlockable!, 558=during the Perils of Ice Mountain., 559=during the Perils of Ice Mountain., 556=to the north of Tai Bwo Wannai Village., 557=not unlockable!, 554=not unlockable!, 555=at the Grand Exchange., 552=not unlockable!, 553=not unlockable!, 567=not unlockable!, 566=not unlockable!, 565=not unlockable!, 564=not unlockable!, 563=not unlockable!, 562=not unlockable!, 561=not unlockable!, 560=not unlockable!, 575=not unlockable!, 574=not unlockable!, 573=not unlockable!, 572=not unlockable!, 571=not unlockable!, 570=not unlockable!, 569=not unlockable!, 568=not unlockable!, 516=during the Vinesweeper minigame., 517=while playing Bounty Hunter., 518=while playing Bounty Hunter., 519=while playing Bounty Hunter., 512=during Dealing with Scabaras., 513=beneath the Grand Tree., 514=during a Duel Arena Tournament., 515=during the Clan Wars minigame., 524=not unlockable!, 525=not unlockable!, 526=not unlockable!, 527=not unlockable!, 521=during Kennith's Concerns., 522=during Kennith's Concerns., 523=automatically., 533=on completion of Great Brain Robbery., 532=not unlockable!, 535=not unlockable!, 534=not unlockable!, 529=not unlockable!, 528=not unlockable!, 531=not unlockable!, 530=not unlockable!, 541=not unlockable!, 540=not unlockable!, 543=not unlockable!, 542=not unlockable!, 537=not unlockable!, 536=on completion of What Lies Below., 539=not unlockable!, 538=not unlockable!, 576=not unlockable!, 577=not unlockable!, 578=not unlockable!, 579=not unlockable!, 580=not unlockable!, 581=not unlockable!, 582=not unlockable!, 583=not unlockable!, 584=at the Blood Altar., 585=in the Chaos Tunnels., 586=in the Chaos Tunnels., 587=in the Chaos Tunnels., 588=during Myreque Part IV., 589=during Myreque Part IV., 590=during Myreque Part IV., 591=during TokTz-Ket-Dill., 593=during TokTz-Ket-Dill., 592=during TokTz-Ket-Dill., 595=during or after the Easter 2008 holiday event., 601=during Myreque Part IV., 600=during Myreque Part IV., 603=during the Fist of Guthix minigame., 602=automatically., 604=in the Fist of Guthix minigame waiting room.} +Script 1350 - [105,105,null,0]: {550=1, 551=1, 548=1, 549=1, 546=1, 547=1, 544=1, 545=1, 557=1, 554=1, 552=1, 553=1, 567=1, 566=1, 565=1, 564=1, 563=1, 562=1, 561=1, 560=1, 575=1, 574=1, 573=1, 572=1, 571=1, 570=1, 569=1, 568=1, 524=1, 525=1, 526=1, 527=1, 523=1, 532=1, 535=1, 534=1, 529=1, 528=1, 531=1, 530=1, 541=1, 540=1, 543=1, 542=1, 537=1, 539=1, 538=1, 320=1, 576=1, 577=1, 578=1, 375=1, 579=1, 580=1, 581=1, 582=1, 583=1} +Script 1351 - [105,77,null,147]: {0=177, 1=50, 2=102, 3=90, 4=36, 5=123, 6=124, 7=19, 8=160, 9=186, 10=24, 11=25, 12=26, 13=27, 14=28, 15=29, 17=2, 16=180, 19=152, 18=324, 21=100, 20=99, 23=64, 22=83, 25=325, 24=104, 27=63, 26=68, 29=169, 28=181, 31=326, 30=182, 34=56, 35=327, 32=37, 33=174, 38=148, 39=138, 36=173, 37=69, 42=153, 43=118, 40=106, 41=41, 46=119, 47=163, 44=72, 45=167, 51=22, 50=125, 49=159, 48=98, 55=313, 54=101, 53=33, 52=310, 59=55, 58=76, 57=116, 56=112, 63=96, 62=188, 61=1, 60=18, 68=115, 69=117, 70=191, 71=60, 64=95, 65=6, 66=172, 67=114, 76=12, 77=20, 78=13, 79=185, 72=66, 73=113, 74=74, 75=161, 85=65, 84=107, 87=10, 86=21, 81=328, 80=184, 83=193, 82=157, 93=93, 92=7, 95=329, 94=158, 89=62, 88=155, 91=103, 90=127, 102=144, 103=400, 100=57, 101=5, 98=91, 99=53, 96=78, 97=89, 110=122, 111=80, 108=110, 109=52, 106=92, 107=35, 104=331, 105=332, 119=140, 118=111, 117=151, 116=108, 115=129, 114=333, 113=77, 112=175, 127=162, 126=130, 125=51, 124=38, 123=109, 122=133, 121=170, 120=79, 137=85, 136=75, 139=32, 138=30, 141=82, 140=49, 143=42, 142=435, 129=94, 128=165, 131=183, 130=192, 133=3, 132=179, 135=70, 134=323, 152=321, 153=547, 154=189, 155=468, 156=492, 157=429, 158=494, 159=54, 144=43, 145=14, 146=34, 147=81, 148=15, 149=168, 150=16, 151=466, 171=58, 170=176, 169=164, 168=45, 175=67, 174=190, 173=330, 172=146, 163=105, 162=166, 161=145, 160=120, 167=46, 166=449, 165=87, 164=47, 186=59, 187=131, 184=156, 185=121, 190=9, 191=97, 188=149, 189=187, 178=71, 179=88, 176=17, 177=128, 182=61, 183=154, 180=48, 181=84, 205=254, 204=253, 207=256, 206=255, 201=248, 200=247, 203=251, 202=252, 197=245, 196=242, 199=244, 198=246, 193=241, 192=134, 195=243, 194=132, 220=270, 221=271, 222=277, 223=262, 216=266, 217=269, 218=11, 219=268, 212=260, 213=264, 214=263, 215=267, 208=258, 209=257, 210=259, 211=261, 239=303, 238=296, 237=295, 236=294, 235=293, 234=292, 233=291, 232=290, 231=289, 230=288, 229=287, 228=286, 227=285, 226=284, 225=282, 224=278, 254=4, 255=316, 252=346, 253=322, 250=319, 251=320, 248=317, 249=318, 246=312, 247=314, 244=308, 245=311, 242=306, 243=307, 240=305, 241=304, 275=351, 274=345, 273=347, 272=343, 279=356, 278=355, 277=354, 276=353, 283=359, 282=352, 281=358, 280=357, 287=364, 286=362, 285=363, 284=361, 258=142, 259=143, 256=8, 257=141, 262=334, 263=336, 260=178, 261=265, 266=338, 267=339, 264=335, 265=337, 270=342, 271=344, 268=340, 269=341, 305=474, 304=389, 307=393, 306=392, 309=395, 308=394, 311=397, 310=396, 313=402, 312=390, 315=407, 314=403, 317=412, 316=411, 319=398, 318=413, 288=366, 289=369, 290=370, 291=373, 292=372, 293=375, 294=376, 295=377, 296=378, 297=379, 298=380, 299=381, 300=383, 301=384, 302=387, 303=388, 343=479, 342=478, 341=476, 340=475, 339=473, 338=471, 337=470, 336=409, 351=497, 350=621, 349=491, 348=490, 347=489, 346=485, 345=482, 344=481, 326=436, 327=44, 324=425, 325=434, 322=420, 323=418, 321=419, 334=463, 335=469, 332=464, 333=465, 330=461, 331=462, 328=447, 329=448, 373=534, 372=533, 374=535, 369=529, 368=528, 371=532, 370=530, 381=542, 380=546, 383=455, 382=548, 377=207, 376=541, 379=545, 378=544, 356=506, 357=508, 358=509, 359=510, 352=498, 353=501, 354=504, 355=505, 364=520, 365=198, 366=524, 367=525, 360=511, 361=515, 362=517, 363=519, 410=611, 411=612, 408=606, 409=610, 414=616, 415=213, 412=614, 413=615, 402=591, 403=594, 400=587, 401=588, 406=603, 407=604, 404=600, 405=602, 395=575, 394=576, 393=573, 392=568, 399=583, 398=582, 397=577, 396=477, 387=537, 386=460, 385=454, 384=453, 391=565, 390=560, 389=559, 388=558, 440=225, 441=220, 442=211, 443=194, 444=203, 445=201, 446=202, 447=274, 432=643, 433=646, 434=126, 435=86, 436=73, 437=222, 438=221, 439=223, 425=633, 424=631, 427=200, 426=632, 429=638, 428=630, 431=640, 430=197, 417=586, 416=493, 419=623, 418=622, 421=627, 420=625, 423=634, 422=626, 478=276, 479=450, 476=279, 477=281, 474=349, 475=273, 472=275, 473=367, 470=216, 471=214, 468=234, 469=272, 466=217, 467=238, 464=231, 465=228, 463=229, 462=230, 461=209, 460=210, 459=208, 458=309, 457=205, 456=204, 455=206, 454=249, 453=240, 452=236, 451=235, 450=237, 449=224, 448=620, 508=433, 509=432, 510=451, 511=472, 504=456, 505=440, 506=439, 507=437, 500=417, 501=428, 502=427, 503=416, 496=414, 497=426, 498=374, 499=382, 493=404, 492=386, 495=421, 494=399, 489=365, 488=302, 491=408, 490=391, 485=283, 484=298, 487=301, 486=300, 481=23, 480=150, 483=299, 482=371, 550=430, 551=422, 548=368, 549=458, 546=480, 547=232, 544=212, 545=297, 558=523, 559=522, 556=483, 557=495, 554=446, 555=496, 552=423, 553=424, 567=174, 566=288, 565=260, 564=332, 563=79, 562=40, 561=39, 560=385, 575=33, 574=172, 573=241, 572=529, 571=347, 570=548, 569=165, 568=573, 516=487, 517=444, 518=443, 519=445, 512=452, 513=348, 514=441, 515=442, 524=350, 525=360, 526=195, 527=219, 521=499, 522=500, 523=147, 533=239, 532=574, 535=226, 534=406, 529=227, 528=218, 531=431, 530=196, 541=405, 540=410, 543=199, 542=484, 537=233, 536=250, 539=315, 538=215, 576=24, 577=501, 578=314, 579=588, 580=269, 581=548, 582=372, 583=4, 584=512, 585=459, 586=467, 587=488, 588=514, 589=518, 590=521, 591=527, 593=531, 592=526, 595=502, 601=516, 600=513, 603=507, 602=457, 604=503} +Script 1352 - [0,0,null,0]: null +Script 1353 - [0,0,null,0]: null +Script 1354 - [105,73,null,44630126]: {0=44630034, 1=44630035, 2=44630036, 3=44630037, 4=44630038, 5=44630039, 6=44630040, 7=44630041, 8=44630042, 9=44630043} +Script 1355 - [105,73,null,44630126]: {0=44630044, 1=44630045, 2=44630046, 3=44630047, 4=44630048, 5=44630049, 6=44630050, 7=44630051, 8=44630052, 9=44630053} +Script 1356 - [105,73,null,44630126]: {0=44630064, 1=44630065, 2=44630066, 3=44630067, 4=44630068, 5=44630069, 6=44630070, 7=44630071, 8=44630072, 9=44630073} +Script 1357 - [105,73,null,44630126]: {0=44630054, 1=44630055, 2=44630056, 3=44630057, 4=44630058, 5=44630059, 6=44630060, 7=44630061, 8=44630062, 9=44630063} +Script 1358 - [105,73,null,44630126]: {0=44761112, 1=44761113, 2=44761114, 3=44761115, 4=44761116, 5=44761117, 6=44761118, 7=44761119, 8=44761120, 9=44761121} +Script 1359 - [105,73,null,44630127]: {0=44630078, 1=44630083, 2=44630088, 3=44630093, 4=44630098, 5=44630103, 6=44630108, 7=44630113, 8=44630118, 9=44630123} +Script 1360 - [105,73,null,44630127]: {0=44630079, 1=44630084, 2=44630089, 3=44630094, 4=44630099, 5=44630104, 6=44630109, 7=44630114, 8=44630119, 9=44630124} +Script 1361 - [105,73,null,44630127]: {0=44630077, 1=44630082, 2=44630087, 3=44630092, 4=44630097, 5=44630102, 6=44630107, 7=44630112, 8=44630117, 9=44630122} +Script 1362 - [105,73,null,44630127]: {0=44630076, 1=44630081, 2=44630086, 3=44630091, 4=44630096, 5=44630101, 6=44630106, 7=44630111, 8=44630116, 9=44630121} +Script 1363 - [0,0,null,0]: null +Script 1364 - [0,0,null,0]: null +Script 1365 - [0,0,null,0]: null +Script 1366 - [0,0,null,0]: null +Script 1367 - [0,0,null,0]: null +Script 1368 - [0,0,null,0]: null +Script 1369 - [105,105,null,1]: {1=13, 2=13, 3=13, 4=13, 5=13, 6=13, 7=13, 8=13, 9=14, 10=15, 11=15, 12=16, 13=16, 14=16, 15=16, 17=19, 16=17, 19=22, 18=20, 21=26, 20=25, 23=30, 22=28, 25=35, 24=32, 27=40, 26=37, 29=47, 28=45, 31=55, 30=50, 34=70, 35=75, 32=60, 33=65, 38=90, 39=95, 36=80, 37=85} +Script 1370 - [0,0,null,0]: null +Script 1371 - [0,0,null,0]: null +Script 1372 - [0,0,null,0]: null +Script 1373 - [0,0,null,0]: null +Script 1374 - [0,0,null,0]: null +Script 1375 - [0,0,null,0]: null +Script 1376 - [0,0,null,0]: null +Script 1377 - [0,0,null,0]: null +Script 1378 - [0,0,null,0]: null +Script 1379 - [0,0,null,0]: null +Script 1380 - [0,0,null,0]: null +Script 1381 - [0,0,null,0]: null +Script 1382 - [0,0,null,0]: null +Script 1383 - [0,0,null,0]: null +Script 1384 - [0,0,null,0]: null +Script 1385 - [0,0,null,0]: null +Script 1386 - [0,0,null,0]: null +Script 1387 - [0,0,null,0]: null +Script 1388 - [0,0,null,0]: null +Script 1389 - [0,0,null,0]: null +Script 1390 - [0,0,null,0]: null +Script 1391 - [0,0,null,0]: null +Script 1392 - [0,0,null,0]: null +Script 1393 - [0,0,null,0]: null +Script 1394 - [0,0,null,0]: null +Script 1395 - [0,0,null,0]: null +Script 1396 - [0,0,null,0]: null +Script 1397 - [0,0,null,0]: null +Script 1398 - [0,0,null,0]: null +Script 1399 - [0,0,null,0]: null +Script 1400 - [0,0,null,0]: null +Script 1401 - [0,0,null,0]: null +Script 1402 - [0,0,null,0]: null +Script 1403 - [0,0,null,0]: null +Script 1404 - [0,0,null,0]: null +Script 1405 - [0,0,null,0]: null +Script 1406 - [0,0,null,0]: null +Script 1407 - [0,0,null,0]: null +Script 1408 - [0,0,null,0]: null +Script 1409 - [0,0,null,0]: null +Script 1410 - [0,0,null,0]: null +Script 1411 - [0,0,null,0]: null +Script 1412 - [0,0,null,0]: null +Script 1413 - [0,0,null,0]: null +Script 1414 - [0,0,null,0]: null +Script 1415 - [0,0,null,0]: null +Script 1416 - [0,0,null,0]: null +Script 1417 - [0,0,null,0]: null +Script 1418 - [0,0,null,0]: null +Script 1419 - [0,0,null,0]: null +Script 1420 - [0,0,null,0]: null +Script 1421 - [0,0,null,0]: null +Script 1422 - [105,105,null,0]: {50=6, 70=14, 80=4, 60=11, 45=10} +Script 1423 - [0,0,null,0]: null +Script 1424 - [0,0,null,0]: null +Script 1425 - [0,0,null,0]: null +Script 1426 - [0,0,null,0]: null +Script 1427 - [0,0,null,0]: null +Script 1428 - [0,0,null,0]: null +Script 1429 - [0,0,null,0]: null +Script 1430 - [0,0,null,0]: null +Script 1431 - [0,0,null,0]: null +Script 1432 - [0,0,null,0]: null +Script 1433 - [105,79,null,11760]: {1=1931, 2=1929, 3=1937, 4=2313, 5=1887, 6=590, 7=1735, 8=1951, 9=1969, 10=1949} +Script 1434 - [0,0,null,0]: null +Script 1435 - [0,0,null,0]: null +Script 1436 - [0,0,null,0]: null +Script 1437 - [0,0,null,0]: null +Script 1438 - [0,0,null,0]: null +Script 1439 - [0,0,null,0]: null +Script 1440 - [0,0,null,0]: null +Script 1441 - [0,0,null,0]: null +Script 1442 - [105,73,null,-1]: {0=47513626, 1=47513646, 2=47513647, 3=47513652, 4=47513640, 5=47513641, 6=47513648, 7=47513658, 8=47513664, 9=47513659, 10=47513660, 11=47513642, 12=47513649, 13=47513650, 14=47513661, 15=47513643, 17=47513662, 16=47513644, 19=47513634, 18=47513651, 21=47513635, 20=47513663, 23=47513628, 22=47513645, 25=47513636, 24=47513629, 27=47513630, 26=47513637, 29=47513665, 28=47513631, 31=47513667, 30=47513666, 34=47513632, 35=47513633, 32=47513668, 33=47513669, 38=47513653, 39=47513654, 36=47513638, 37=47513639, 42=47513657, 40=47513655, 41=47513656} +Script 1443 - [105,73,null,-1]: {0=47579257, 1=47579293, 2=47579301, 3=47579279, 4=47579285, 5=47579292, 6=47579299, 7=47579276, 8=47579277, 9=47579284, 10=47579275, 11=47579300, 12=47579288, 13=47579278, 14=47579296, 15=47579304, 17=47579283, 16=47579302, 19=47579280, 18=47579291, 21=47579272, 20=47579281, 23=47579282, 22=47579263, 25=47579303, 24=47579312, 27=47579289, 26=47579310, 29=47579317, 28=47579271, 31=47579297, 30=47579298, 34=47579319, 35=47579262, 32=47579290, 33=47579306, 38=47579305, 39=47579320, 36=47579261, 37=47579270, 42=47579265, 43=47579318, 40=47579269, 41=47579264, 46=47579307, 47=47579274, 44=47579311, 45=47579309, 51=47579266, 50=47579273, 49=47579322, 48=47579321, 55=47579315, 54=47579314, 53=47579313, 52=47579316, 59=47579260, 58=47579268, 57=47579267, 56=47579308, 60=47579259} +Script 1444 - [0,0,null,0]: null +Script 1445 - [0,0,null,0]: null +Script 1446 - [0,0,null,0]: null +Script 1447 - [0,0,null,0]: null +Script 1448 - [0,0,null,0]: null +Script 1449 - [0,0,null,0]: null +Script 1450 - [0,0,null,0]: null +Script 1451 - [0,0,null,0]: null +Script 1452 - [0,0,null,0]: null +Script 1453 - [0,0,null,0]: null +Script 1454 - [0,0,null,0]: null +Script 1455 - [0,0,null,0]: null +Script 1456 - [0,0,null,0]: null +Script 1457 - [0,0,null,0]: null +Script 1458 - [0,0,null,0]: null +Script 1459 - [0,0,null,0]: null +Script 1460 - [0,0,null,0]: null +Script 1461 - [0,0,null,0]: null +Script 1462 - [0,0,null,0]: null +Script 1463 - [0,0,null,0]: null +Script 1464 - [0,0,null,0]: null +Script 1465 - [0,0,null,0]: null +Script 1466 - [73,115,,0]: {48168986=A L P, 48168987=A L Q, 48168984=A K R, 48168985=A K S, 48168990=B I P, 48168991=B I Q, 48168988=A L R, 48168989=A L S, 48168978=A J P, 48168979=A J Q, 48168976=A I R, 48168977=A I S, 48168982=A K P, 48168983=A K Q, 48168980=A J R, 48168981=A J S, 48169037=D L S, 48169036=D L R, 48169035=D L Q, 48168975=A I Q, 48169034=D L P, 48168974=A I P, 48169033=D K S, 48169032=D K R, 48169031=D K Q, 48169030=D K P, 48169029=D J S, 48169028=D J R, 48169027=D J Q, 48169026=D J P, 48169025=D I S, 48169024=D I R, 48169016=C K R, 48169017=C K S, 48169018=C L P, 48169019=C L Q, 48169020=C L R, 48169021=C L S, 48169022=D I P, 48169023=D I Q, 48169008=C I R, 48169009=C I S, 48169010=C J P, 48169011=C J Q, 48169012=C J R, 48169013=C J S, 48169014=C K P, 48169015=C K Q, 48169001=B K S, 48169000=B K R, 48169003=B L Q, 48169002=B L P, 48169005=B L S, 48169004=B L R, 48169007=C I Q, 48169006=C I P, 48168993=B I S, 48168992=B I R, 48168995=B J Q, 48168994=B J P, 48168997=B J S, 48168996=B J R, 48168999=B K Q, 48168998=B K P} +Script 1467 - [105,73,null,-1]: {0=48168974, 1=48168977, 2=48168976, 3=48168975, 4=48168986, 5=48168989, 6=48168988, 7=48168987, 8=48168982, 9=48168985, 10=48168984, 11=48168983, 12=48168978, 13=48168981, 14=48168980, 15=48168979, 17=48169025, 16=48169022, 19=48169023, 18=48169024, 21=48169037, 20=48169034, 23=48169035, 22=48169036, 25=48169033, 24=48169030, 27=48169031, 26=48169032, 29=48169029, 28=48169026, 31=48169027, 30=48169028, 34=48169008, 35=48169007, 32=48169006, 33=48169009, 38=48169020, 39=48169019, 36=48169018, 37=48169021, 42=48169016, 43=48169015, 40=48169014, 41=48169017, 46=48169012, 47=48169011, 44=48169010, 45=48169013, 51=48168991, 50=48168992, 49=48168993, 48=48168990, 55=48169003, 54=48169004, 53=48169005, 52=48169002, 59=48168999, 58=48169000, 57=48169001, 56=48168998, 63=48168995, 62=48168996, 61=48168997, 60=48168994, 64=48169038} +Script 1468 - [0,0,null,0]: null +Script 1469 - [0,0,null,0]: null +Script 1470 - [0,0,null,0]: null +Script 1471 - [0,0,null,0]: null +Script 1472 - [0,0,null,0]: null diff --git a/make-release.py b/make-release.py new file mode 100755 index 0000000..bae99d2 --- /dev/null +++ b/make-release.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python3 + +import subprocess +import datetime +import os + + +WEB_REPO = '../2009scape.github.io' +NEWS_DIR = 'updates/_posts' +LOG_DELIMITER = ';;;;;' +DEBUG = False + + +class Tag: + def __init__(self, tag_name, last_tag): + self.tag_name = tag_name + self.last_tag = last_tag + + +def make_tag() -> Tag: + tag_name = datetime.datetime.now().strftime('%b-%d-%Y') + print('new release tag:', tag_name) + last_tag = subprocess.check_output(['git', 'describe', '--tags', '--abbrev=0']).decode('utf8').strip() + print('last release tag:', last_tag) + if not DEBUG: + subprocess.run(['git', 'tag', tag_name]) + return Tag(tag_name, last_tag) + + +def get_changelog_html(tag: Tag) -> str: + if DEBUG: + log_period = f'{tag.last_tag}..HEAD' + else: + log_period = f'{tag.last_tag}..{tag.tag_name}' + changelog = subprocess.check_output(['git', 'log', log_period, f'--format=%B{LOG_DELIMITER}']).decode('utf8').split(LOG_DELIMITER) + changelog_html = ''.join(['- ' + change.strip().replace('\n', '
\n') + '\n' for change in changelog if change.strip()]) + changelog_html = f'\n{changelog_html}' + print('generated changelog:', changelog_html, sep='\n') + return changelog_html + + +def make_news_post(tag: Tag) -> None: + changelog_html = get_changelog_html(tag) + os.chdir(os.path.join(WEB_REPO, NEWS_DIR)) + current_date = datetime.datetime.now().strftime('%Y-%m-%d') + news_filename = f'{current_date}-More-changes-in-Gielinor.md' + print('news filename:', news_filename) + news_post = news_template(current_date, changelog_html) + if DEBUG: + print('generated news post:', news_post) + else: + if news_filename in os.listdir(): + raise FileExistsError(news_filename) + with open(news_filename, 'wt') as news_handle: + news_handle.write(news_post) + + +def news_template(current_date: str, changelog: str) -> str: + return f'''--- +title: More changes in Gielinor +tags: news +layout: newspost +date: {current_date} 00:00:00 +0000 +authors: ryannathans +excerpt: "There have been some more changes in Gielinor..." +modtype: "Lead Developer" +avatar: avatar8fa9.gif +--- +Greetings Explorers + +There have been some more changes in Gielinor: + +{changelog} +''' + + +def main() -> None: + tag = make_tag() + make_news_post(tag) + + +if __name__ == '__main__': + main() diff --git a/run b/run new file mode 100755 index 0000000..e1c4fdc --- /dev/null +++ b/run @@ -0,0 +1,171 @@ +#!/usr/bin/env bash +SCRIPT_DIR=$(cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P) +LOG_DIR=$SCRIPT_DIR/logs +BUILD_DIR=$SCRIPT_DIR/builddir +GS_SRC=$SCRIPT_DIR/Server +MS_SRC=$SCRIPT_DIR/Management-Server + +FORCE_REBUILD=0 +REFRESH_BUILD=1 + +GAMESERVER_ONLY=1 + +GS_EXEC="cd $GS_SRC && java -Dnashorn.args=--no-deprecation-warning -jar $BUILD_DIR/server.jar" +MS_EXEC="cd $MS_SRC && java -Dnashorn.args=--no-deprecation-warning -jar $BUILD_DIR/ms.jar" + +# 0: parallel +# 1: fancy tmux +# 2: tests only +RUN_MODE=0 + +help() +{ + echo "Usage: $0 [-h] [-q] [-r] [-t] [-x] [-g] [-e ] [-o ]" + echo " -h: Display this message." + echo " -q: Don't perform the incremental build." + echo " -r: Force clean rebuild." + echo " -t: Only run tests, not the JARs." + echo " -x: Run in a fancy tmux session." + echo " -g: Build + run only the game server (no management server)." + echo " -e: Write STDERR to 'logs/filename' as well as the terminal."; + echo " -o: Write STDOUT to 'logs/filename' as well as the terminal." +} + +error() +{ + echo "$1"; + exit 1; +} + +rebuild_project() +{ + if [ $GAMESERVER_ONLY ]; then + $SCRIPT_DIR/build -qgcg + else + $SCRIPT_DIR/build -qmgcmg + fi +} + +refresh_project() +{ + if [ $GAMESERVER_ONLY ]; then + $SCRIPT_DIR/build -qg + else + $SCRIPT_DIR/build -qmg + fi +} + +verify_binaries_exist() +{ + if ! [ $GAMESERVER_ONLY ]; then + if [ ! -f $SCRIPT_DIR/builddir/ms.jar ]; then + error "Management server binary does not exist."; + fi + fi + + if [ ! -f $SCRIPT_DIR/build/server.jar ]; then + error "Game server binary does not exist."; + fi +} + +run_server_parallel() +{ + if ! [ -x "$(command -v java)" ]; then + error "Java is not installed." + fi + + echo "Running in parallel. All logs redirected to proper files." + + if [ $GAMESERVER_ONLY ]; then + sh -c "$GS_EXEC" & wait + else + sh -c "$MS_EXEC > $LOG_DIR/ms_stdout.log 2> $LOG_DIR/ms_stderr.log & $GS_EXEC" & wait + fi +} + +run_server_tmux() +{ + if ! [ -x "$(command -v tmux)" ]; then + error "tmux is not installed. Install tmux or don't use this option." + fi + + if [ $GAMESERVER_ONLY ]; then + tmux new-session "$GS_EXEC" + else + tmux new-session "$MS_EXEC" \; \ + split-window -h "$GS_EXEC" + fi +} + +run_server_tests() +{ + cd "$GS_SRC" || error "Could not change to GameServer source directory." + sh mvnw test +} + +while getopts ":ghqrtxe:o:" arg; do + case $arg in + h) + help + exit 0 + ;; + q) + REFRESH_BUILD=0 + ;; + r) + FORCE_REBUILD=1 + ;; + t) + RUN_MODE=2 + ;; + o) + GS_EXEC="$GS_EXEC > >(tee $LOG_DIR/${OPTARG})" + ;; + e) + GS_EXEC="$GS_EXEC 2> >(tee $LOG_DIR/${OPTARG})" + ;; + x) + RUN_MODE=1 + ;; + g) + GAMESERVER_ONLY=0 + ;; + *) + error "Argument -$arg is not a known or valid argument." + ;; + esac +done + +if [ ! -d $LOG_DIR ]; then + mkdir -p $LOG_DIR +fi + +if [ ! -d $GS_SRC/target ]; then + rebuild_project || error "Failed to perform a clean build." +else + if [ $FORCE_REBUILD -eq 1 ]; then + rebuild_project || error "Failed to perform a clean build." + else + if [ $REFRESH_BUILD -eq 1 ]; then + refresh_project || error "Failed to perform an incremental build." + fi + fi +fi; + +cd "$SCRIPT_DIR/builddir" || error "Failed to navigate to the build directory." + +case $RUN_MODE in + 0) + # The trap will allow the script to kill the background + # Java instances upon exiting. + trap "trap - SIGTERM && kill -- -$$" SIGINT SIGTERM EXIT + + run_server_parallel + ;; + 1) + run_server_tmux + ;; + 2) + run_server_tests + ;; +esac diff --git a/run-ms.bat b/run-ms.bat new file mode 100644 index 0000000..494ccb6 --- /dev/null +++ b/run-ms.bat @@ -0,0 +1,8 @@ +@echo off +cd Management-Server + +if NOT exist DoNotCreateThisFile.txt ( + .\mvnw.cmd package -DskipTests + xcopy /Y target\*-with-dependencies.jar ms.jar* + java -jar ms.jar +) \ No newline at end of file diff --git a/run-server.bat b/run-server.bat new file mode 100644 index 0000000..871c0d2 --- /dev/null +++ b/run-server.bat @@ -0,0 +1,14 @@ +@echo off +cd Server + +if NOT exist hasRan.txt ( + .\mvnw.cmd clean + copy NUL hasRan.txt + .\mvnw.cmd package -DskipTests + xcopy /Y target\*-with-dependencies.jar server.jar* + java -jar server.jar +) ELSE ( + .\mvnw.cmd package -DskipTests + xcopy /Y target\*-with-dependencies.jar server.jar* + java -jar server.jar +) \ No newline at end of file